diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/asm/atomic.h linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/atomic.h
--- linux-libre-3.10-gnu/arch/alpha/include/asm/atomic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/atomic.h	2013-08-25 20:43:22.000000000 -0400
@@ -186,17 +186,24 @@ static __inline__ long atomic64_sub_retu
  */
 static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
 {
-	int c, old;
-	c = atomic_read(v);
-	for (;;) {
-		if (unlikely(c == (u)))
-			break;
-		old = atomic_cmpxchg((v), c, c + (a));
-		if (likely(old == c))
-			break;
-		c = old;
-	}
-	return c;
+	int c, new, old;
+	smp_mb();
+	__asm__ __volatile__(
+	"1:	ldl_l	%[old],%[mem]\n"
+	"	cmpeq	%[old],%[u],%[c]\n"
+	"	addl	%[old],%[a],%[new]\n"
+	"	bne	%[c],2f\n"
+	"	stl_c	%[new],%[mem]\n"
+	"	beq	%[new],3f\n"
+	"2:\n"
+	".subsection 2\n"
+	"3:	br	1b\n"
+	".previous"
+	: [old] "=&r"(old), [new] "=&r"(new), [c] "=&r"(c)
+	: [mem] "m"(*v), [a] "rI"(a), [u] "rI"((long)u)
+	: "memory");
+	smp_mb();
+	return old;
 }
 
 
@@ -207,21 +214,56 @@ static __inline__ int __atomic_add_unles
  * @u: ...unless v is equal to u.
  *
  * Atomically adds @a to @v, so long as it was not @u.
- * Returns the old value of @v.
+ * Returns true iff @v was not @u.
  */
 static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
 {
-	long c, old;
-	c = atomic64_read(v);
-	for (;;) {
-		if (unlikely(c == (u)))
-			break;
-		old = atomic64_cmpxchg((v), c, c + (a));
-		if (likely(old == c))
-			break;
-		c = old;
-	}
-	return c != (u);
+	long c, tmp;
+	smp_mb();
+	__asm__ __volatile__(
+	"1:	ldq_l	%[tmp],%[mem]\n"
+	"	cmpeq	%[tmp],%[u],%[c]\n"
+	"	addq	%[tmp],%[a],%[tmp]\n"
+	"	bne	%[c],2f\n"
+	"	stq_c	%[tmp],%[mem]\n"
+	"	beq	%[tmp],3f\n"
+	"2:\n"
+	".subsection 2\n"
+	"3:	br	1b\n"
+	".previous"
+	: [tmp] "=&r"(tmp), [c] "=&r"(c)
+	: [mem] "m"(*v), [a] "rI"(a), [u] "rI"(u)
+	: "memory");
+	smp_mb();
+	return !c;
+}
+
+/*
+ * atomic64_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic_t
+ *
+ * The function returns the old value of *v minus 1, even if
+ * the atomic variable, v, was not decremented.
+ */
+static inline long atomic64_dec_if_positive(atomic64_t *v)
+{
+	long old, tmp;
+	smp_mb();
+	__asm__ __volatile__(
+	"1:	ldq_l	%[old],%[mem]\n"
+	"	subq	%[old],1,%[tmp]\n"
+	"	ble	%[old],2f\n"
+	"	stq_c	%[tmp],%[mem]\n"
+	"	beq	%[tmp],3f\n"
+	"2:\n"
+	".subsection 2\n"
+	"3:	br	1b\n"
+	".previous"
+	: [old] "=&r"(old), [tmp] "=&r"(tmp)
+	: [mem] "m"(*v)
+	: "memory");
+	smp_mb();
+	return old - 1;
 }
 
 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/asm/mmzone.h linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/mmzone.h
--- linux-libre-3.10-gnu/arch/alpha/include/asm/mmzone.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/mmzone.h	2013-08-25 20:43:22.000000000 -0400
@@ -71,8 +71,6 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p,
 
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 
-#define VALID_PAGE(page)	(((page) - mem_map) < max_mapnr)
-
 #define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> 32))
 #define pgd_page(pgd)		(pfn_to_page(pgd_val(pgd) >> 32))
 #define pte_pfn(pte)		(pte_val(pte) >> 32)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/asm/param.h linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/param.h
--- linux-libre-3.10-gnu/arch/alpha/include/asm/param.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/param.h	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,9 @@
 
 #include <uapi/asm/param.h>
 
-#define HZ		CONFIG_HZ
-#define USER_HZ		HZ
-# define CLOCKS_PER_SEC	HZ	/* frequency at which times() counts */
+# undef HZ
+# define HZ		CONFIG_HZ
+# define USER_HZ	1024
+# define CLOCKS_PER_SEC	USER_HZ	/* frequency at which times() counts */
+
 #endif /* _ASM_ALPHA_PARAM_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/alpha/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -354,9 +354,6 @@ extern inline pte_t mk_swap_pte(unsigned
 #define kern_addr_valid(addr)	(1)
 #endif
 
-#define io_remap_pfn_range(vma, start, pfn, size, prot)	\
-		remap_pfn_range(vma, start, pfn, size, prot)
-
 #define pte_ERROR(e) \
 	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
 #define pmd_ERROR(e) \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/asm/spinlock.h linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/spinlock.h
--- linux-libre-3.10-gnu/arch/alpha/include/asm/spinlock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/spinlock.h	2013-08-25 20:43:22.000000000 -0400
@@ -168,8 +168,4 @@ static inline void arch_write_unlock(arc
 #define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
 #define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
 
-#define arch_spin_relax(lock)	cpu_relax()
-#define arch_read_relax(lock)	cpu_relax()
-#define arch_write_relax(lock)	cpu_relax()
-
 #endif /* _ALPHA_SPINLOCK_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/asm/unistd.h linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/unistd.h
--- linux-libre-3.10-gnu/arch/alpha/include/asm/unistd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/asm/unistd.h	2013-08-25 20:43:22.000000000 -0400
@@ -3,8 +3,7 @@
 
 #include <uapi/asm/unistd.h>
 
-
-#define NR_SYSCALLS			506
+#define NR_SYSCALLS			508
 
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_STAT64
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/uapi/asm/fcntl.h linux-libre-3.11-rc7-gnu/arch/alpha/include/uapi/asm/fcntl.h
--- linux-libre-3.10-gnu/arch/alpha/include/uapi/asm/fcntl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/uapi/asm/fcntl.h	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,7 @@
 #define O_SYNC		(__O_SYNC|O_DSYNC)
 
 #define O_PATH		040000000
+#define __O_TMPFILE	0100000000
 
 #define F_GETLK		7
 #define F_SETLK		8
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/uapi/asm/param.h linux-libre-3.11-rc7-gnu/arch/alpha/include/uapi/asm/param.h
--- linux-libre-3.10-gnu/arch/alpha/include/uapi/asm/param.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/uapi/asm/param.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,13 +1,7 @@
 #ifndef _UAPI_ASM_ALPHA_PARAM_H
 #define _UAPI_ASM_ALPHA_PARAM_H
 
-/* ??? Gross.  I don't want to parameterize this, and supposedly the
-   hardware ignores reprogramming.  We also need userland buy-in to the 
-   change in HZ, since this is visible in the wait4 resources etc.  */
-
-#ifndef __KERNEL__
 #define HZ		1024
-#endif
 
 #define EXEC_PAGESIZE	8192
 
@@ -17,5 +11,4 @@
 
 #define MAXHOSTNAMELEN	64	/* max length of hostname */
 
-
 #endif /* _UAPI_ASM_ALPHA_PARAM_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/alpha/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/alpha/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -81,4 +81,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL			46
+
 #endif /* _UAPI_ASM_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/include/uapi/asm/unistd.h linux-libre-3.11-rc7-gnu/arch/alpha/include/uapi/asm/unistd.h
--- linux-libre-3.10-gnu/arch/alpha/include/uapi/asm/unistd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/include/uapi/asm/unistd.h	2013-08-25 20:43:22.000000000 -0400
@@ -467,5 +467,7 @@
 #define __NR_sendmmsg			503
 #define __NR_process_vm_readv		504
 #define __NR_process_vm_writev		505
+#define __NR_kcmp			506
+#define __NR_finit_module		507
 
 #endif /* _UAPI_ALPHA_UNISTD_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/Kconfig linux-libre-3.11-rc7-gnu/arch/alpha/Kconfig
--- linux-libre-3.10-gnu/arch/alpha/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@ config ALPHA
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_STRNCPY_FROM_USER
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/console.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/console.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/console.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/console.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,7 +61,9 @@ locate_and_init_vga(void *(*sel_func)(vo
 
 	/* Set the VGA hose and init the new console. */
 	pci_vga_hose = hose;
-	take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1);
+	console_lock();
+	do_take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1);
+	console_unlock();
 }
 
 void __init
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/entry.S linux-libre-3.11-rc7-gnu/arch/alpha/kernel/entry.S
--- linux-libre-3.10-gnu/arch/alpha/kernel/entry.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/entry.S	2013-08-25 20:43:22.000000000 -0400
@@ -12,11 +12,32 @@
 
 	.text
 	.set noat
+	.cfi_sections	.debug_frame
 
 /* Stack offsets.  */
 #define SP_OFF			184
 #define SWITCH_STACK_SIZE	320
 
+.macro	CFI_START_OSF_FRAME	func
+	.align	4
+	.globl	\func
+	.type	\func,@function
+\func:
+	.cfi_startproc simple
+	.cfi_return_column 64
+	.cfi_def_cfa	$sp, 48
+	.cfi_rel_offset	64, 8
+	.cfi_rel_offset	$gp, 16
+	.cfi_rel_offset	$16, 24
+	.cfi_rel_offset	$17, 32
+	.cfi_rel_offset	$18, 40
+.endm
+
+.macro	CFI_END_OSF_FRAME	func
+	.cfi_endproc
+	.size	\func, . - \func
+.endm
+
 /*
  * This defines the normal kernel pt-regs layout.
  *
@@ -27,100 +48,158 @@
  * the palcode-provided values are available to the signal handler.
  */
 
-#define SAVE_ALL			\
-	subq	$sp, SP_OFF, $sp;	\
-	stq	$0, 0($sp);		\
-	stq	$1, 8($sp);		\
-	stq	$2, 16($sp);		\
-	stq	$3, 24($sp);		\
-	stq	$4, 32($sp);		\
-	stq	$28, 144($sp);		\
-	lda	$2, alpha_mv;		\
-	stq	$5, 40($sp);		\
-	stq	$6, 48($sp);		\
-	stq	$7, 56($sp);		\
-	stq	$8, 64($sp);		\
-	stq	$19, 72($sp);		\
-	stq	$20, 80($sp);		\
-	stq	$21, 88($sp);		\
-	ldq	$2, HAE_CACHE($2);	\
-	stq	$22, 96($sp);		\
-	stq	$23, 104($sp);		\
-	stq	$24, 112($sp);		\
-	stq	$25, 120($sp);		\
-	stq	$26, 128($sp);		\
-	stq	$27, 136($sp);		\
-	stq	$2, 152($sp);		\
-	stq	$16, 160($sp);		\
-	stq	$17, 168($sp);		\
+.macro	SAVE_ALL
+	subq	$sp, SP_OFF, $sp
+	.cfi_adjust_cfa_offset	SP_OFF
+	stq	$0, 0($sp)
+	stq	$1, 8($sp)
+	stq	$2, 16($sp)
+	stq	$3, 24($sp)
+	stq	$4, 32($sp)
+	stq	$28, 144($sp)
+	.cfi_rel_offset	$0, 0
+	.cfi_rel_offset $1, 8
+	.cfi_rel_offset	$2, 16
+	.cfi_rel_offset	$3, 24
+	.cfi_rel_offset	$4, 32
+	.cfi_rel_offset	$28, 144
+	lda	$2, alpha_mv
+	stq	$5, 40($sp)
+	stq	$6, 48($sp)
+	stq	$7, 56($sp)
+	stq	$8, 64($sp)
+	stq	$19, 72($sp)
+	stq	$20, 80($sp)
+	stq	$21, 88($sp)
+	ldq	$2, HAE_CACHE($2)
+	stq	$22, 96($sp)
+	stq	$23, 104($sp)
+	stq	$24, 112($sp)
+	stq	$25, 120($sp)
+	stq	$26, 128($sp)
+	stq	$27, 136($sp)
+	stq	$2, 152($sp)
+	stq	$16, 160($sp)
+	stq	$17, 168($sp)
 	stq	$18, 176($sp)
+	.cfi_rel_offset	$5, 40
+	.cfi_rel_offset	$6, 48
+	.cfi_rel_offset	$7, 56
+	.cfi_rel_offset	$8, 64
+	.cfi_rel_offset $19, 72
+	.cfi_rel_offset	$20, 80
+	.cfi_rel_offset	$21, 88
+	.cfi_rel_offset $22, 96
+	.cfi_rel_offset	$23, 104
+	.cfi_rel_offset	$24, 112
+	.cfi_rel_offset	$25, 120
+	.cfi_rel_offset	$26, 128
+	.cfi_rel_offset	$27, 136
+.endm
 
-#define RESTORE_ALL			\
-	lda	$19, alpha_mv;		\
-	ldq	$0, 0($sp);		\
-	ldq	$1, 8($sp);		\
-	ldq	$2, 16($sp);		\
-	ldq	$3, 24($sp);		\
-	ldq	$21, 152($sp);		\
-	ldq	$20, HAE_CACHE($19);	\
-	ldq	$4, 32($sp);		\
-	ldq	$5, 40($sp);		\
-	ldq	$6, 48($sp);		\
-	ldq	$7, 56($sp);		\
-	subq	$20, $21, $20;		\
-	ldq	$8, 64($sp);		\
-	beq	$20, 99f;		\
-	ldq	$20, HAE_REG($19);	\
-	stq	$21, HAE_CACHE($19);	\
-	stq	$21, 0($20);		\
-99:;					\
-	ldq	$19, 72($sp);		\
-	ldq	$20, 80($sp);		\
-	ldq	$21, 88($sp);		\
-	ldq	$22, 96($sp);		\
-	ldq	$23, 104($sp);		\
-	ldq	$24, 112($sp);		\
-	ldq	$25, 120($sp);		\
-	ldq	$26, 128($sp);		\
-	ldq	$27, 136($sp);		\
-	ldq	$28, 144($sp);		\
+.macro	RESTORE_ALL
+	lda	$19, alpha_mv
+	ldq	$0, 0($sp)
+	ldq	$1, 8($sp)
+	ldq	$2, 16($sp)
+	ldq	$3, 24($sp)
+	ldq	$21, 152($sp)
+	ldq	$20, HAE_CACHE($19)
+	ldq	$4, 32($sp)
+	ldq	$5, 40($sp)
+	ldq	$6, 48($sp)
+	ldq	$7, 56($sp)
+	subq	$20, $21, $20
+	ldq	$8, 64($sp)
+	beq	$20, 99f
+	ldq	$20, HAE_REG($19)
+	stq	$21, HAE_CACHE($19)
+	stq	$21, 0($20)
+99:	ldq	$19, 72($sp)
+	ldq	$20, 80($sp)
+	ldq	$21, 88($sp)
+	ldq	$22, 96($sp)
+	ldq	$23, 104($sp)
+	ldq	$24, 112($sp)
+	ldq	$25, 120($sp)
+	ldq	$26, 128($sp)
+	ldq	$27, 136($sp)
+	ldq	$28, 144($sp)
 	addq	$sp, SP_OFF, $sp
+	.cfi_restore	$0
+	.cfi_restore	$1
+	.cfi_restore	$2
+	.cfi_restore	$3
+	.cfi_restore	$4
+	.cfi_restore	$5
+	.cfi_restore	$6
+	.cfi_restore	$7
+	.cfi_restore	$8
+	.cfi_restore	$19
+	.cfi_restore	$20
+	.cfi_restore	$21
+	.cfi_restore	$22
+	.cfi_restore	$23
+	.cfi_restore	$24
+	.cfi_restore	$25
+	.cfi_restore	$26
+	.cfi_restore	$27
+	.cfi_restore	$28
+	.cfi_adjust_cfa_offset	-SP_OFF
+.endm
+
+.macro	DO_SWITCH_STACK
+	bsr	$1, do_switch_stack
+	.cfi_adjust_cfa_offset	SWITCH_STACK_SIZE
+	.cfi_rel_offset	$9, 0
+	.cfi_rel_offset	$10, 8
+	.cfi_rel_offset	$11, 16
+	.cfi_rel_offset	$12, 24
+	.cfi_rel_offset	$13, 32
+	.cfi_rel_offset	$14, 40
+	.cfi_rel_offset	$15, 48
+	/* We don't really care about the FP registers for debugging.  */
+.endm
+
+.macro	UNDO_SWITCH_STACK
+	bsr	$1, undo_switch_stack
+	.cfi_restore	$9
+	.cfi_restore	$10
+	.cfi_restore	$11
+	.cfi_restore	$12
+	.cfi_restore	$13
+	.cfi_restore	$14
+	.cfi_restore	$15
+	.cfi_adjust_cfa_offset	-SWITCH_STACK_SIZE
+.endm
 
 /*
  * Non-syscall kernel entry points.
  */
 
-	.align	4
-	.globl	entInt
-	.ent	entInt
-entInt:
+CFI_START_OSF_FRAME entInt
 	SAVE_ALL
 	lda	$8, 0x3fff
 	lda	$26, ret_from_sys_call
 	bic	$sp, $8, $8
 	mov	$sp, $19
 	jsr	$31, do_entInt
-.end entInt
+CFI_END_OSF_FRAME entInt
 
-	.align	4
-	.globl	entArith
-	.ent	entArith
-entArith:
+CFI_START_OSF_FRAME entArith
 	SAVE_ALL
 	lda	$8, 0x3fff
 	lda	$26, ret_from_sys_call
 	bic	$sp, $8, $8
 	mov	$sp, $18
 	jsr	$31, do_entArith
-.end entArith
+CFI_END_OSF_FRAME entArith
 
-	.align	4
-	.globl	entMM
-	.ent	entMM
-entMM:
+CFI_START_OSF_FRAME entMM
 	SAVE_ALL
 /* save $9 - $15 so the inline exception code can manipulate them.  */
 	subq	$sp, 56, $sp
+	.cfi_adjust_cfa_offset	56
 	stq	$9, 0($sp)
 	stq	$10, 8($sp)
 	stq	$11, 16($sp)
@@ -128,6 +207,13 @@ entMM:
 	stq	$13, 32($sp)
 	stq	$14, 40($sp)
 	stq	$15, 48($sp)
+	.cfi_rel_offset	$9, 0
+	.cfi_rel_offset	$10, 8
+	.cfi_rel_offset	$11, 16
+	.cfi_rel_offset	$12, 24
+	.cfi_rel_offset	$13, 32
+	.cfi_rel_offset	$14, 40
+	.cfi_rel_offset	$15, 48
 	addq	$sp, 56, $19
 /* handle the fault */
 	lda	$8, 0x3fff
@@ -142,28 +228,33 @@ entMM:
 	ldq	$14, 40($sp)
 	ldq	$15, 48($sp)
 	addq	$sp, 56, $sp
+	.cfi_restore	$9
+	.cfi_restore	$10
+	.cfi_restore	$11
+	.cfi_restore	$12
+	.cfi_restore	$13
+	.cfi_restore	$14
+	.cfi_restore	$15
+	.cfi_adjust_cfa_offset	-56
 /* finish up the syscall as normal.  */
 	br	ret_from_sys_call
-.end entMM
+CFI_END_OSF_FRAME entMM
 
-	.align	4
-	.globl	entIF
-	.ent	entIF
-entIF:
+CFI_START_OSF_FRAME entIF
 	SAVE_ALL
 	lda	$8, 0x3fff
 	lda	$26, ret_from_sys_call
 	bic	$sp, $8, $8
 	mov	$sp, $17
 	jsr	$31, do_entIF
-.end entIF
+CFI_END_OSF_FRAME entIF
 
-	.align	4
-	.globl	entUna
-	.ent	entUna
-entUna:
+CFI_START_OSF_FRAME entUna
 	lda	$sp, -256($sp)
+	.cfi_adjust_cfa_offset	256
 	stq	$0, 0($sp)
+	.cfi_rel_offset	$0, 0
+	.cfi_remember_state
 	ldq	$0, 256($sp)	/* get PS */
 	stq	$1, 8($sp)
 	stq	$2, 16($sp)
@@ -195,6 +286,32 @@ entUna:
 	stq	$28, 224($sp)
 	mov	$sp, $19
 	stq	$gp, 232($sp)
+	.cfi_rel_offset	$1, 1*8
+	.cfi_rel_offset	$2, 2*8
+	.cfi_rel_offset	$3, 3*8
+	.cfi_rel_offset	$4, 4*8
+	.cfi_rel_offset	$5, 5*8
+	.cfi_rel_offset	$6, 6*8
+	.cfi_rel_offset	$7, 7*8
+	.cfi_rel_offset	$8, 8*8
+	.cfi_rel_offset	$9, 9*8
+	.cfi_rel_offset	$10, 10*8
+	.cfi_rel_offset	$11, 11*8
+	.cfi_rel_offset	$12, 12*8
+	.cfi_rel_offset	$13, 13*8
+	.cfi_rel_offset	$14, 14*8
+	.cfi_rel_offset	$15, 15*8
+	.cfi_rel_offset	$19, 19*8
+	.cfi_rel_offset	$20, 20*8
+	.cfi_rel_offset	$21, 21*8
+	.cfi_rel_offset	$22, 22*8
+	.cfi_rel_offset	$23, 23*8
+	.cfi_rel_offset	$24, 24*8
+	.cfi_rel_offset	$25, 25*8
+	.cfi_rel_offset	$26, 26*8
+	.cfi_rel_offset	$27, 27*8
+	.cfi_rel_offset	$28, 28*8
+	.cfi_rel_offset	$29, 29*8
 	lda	$8, 0x3fff
 	stq	$31, 248($sp)
 	bic	$sp, $8, $8
@@ -228,16 +345,45 @@ entUna:
 	ldq	$28, 224($sp)
 	ldq	$gp, 232($sp)
 	lda	$sp, 256($sp)
+	.cfi_restore	$1
+	.cfi_restore	$2
+	.cfi_restore	$3
+	.cfi_restore	$4
+	.cfi_restore	$5
+	.cfi_restore	$6
+	.cfi_restore	$7
+	.cfi_restore	$8
+	.cfi_restore	$9
+	.cfi_restore	$10
+	.cfi_restore	$11
+	.cfi_restore	$12
+	.cfi_restore	$13
+	.cfi_restore	$14
+	.cfi_restore	$15
+	.cfi_restore	$19
+	.cfi_restore	$20
+	.cfi_restore	$21
+	.cfi_restore	$22
+	.cfi_restore	$23
+	.cfi_restore	$24
+	.cfi_restore	$25
+	.cfi_restore	$26
+	.cfi_restore	$27
+	.cfi_restore	$28
+	.cfi_restore	$29
+	.cfi_adjust_cfa_offset	-256
 	call_pal PAL_rti
-.end entUna
 
 	.align	4
-	.ent	entUnaUser
 entUnaUser:
+	.cfi_restore_state
 	ldq	$0, 0($sp)	/* restore original $0 */
 	lda	$sp, 256($sp)	/* pop entUna's stack frame */
+	.cfi_restore	$0
+	.cfi_adjust_cfa_offset	-256
 	SAVE_ALL		/* setup normal kernel stack */
 	lda	$sp, -56($sp)
+	.cfi_adjust_cfa_offset	56
 	stq	$9, 0($sp)
 	stq	$10, 8($sp)
 	stq	$11, 16($sp)
@@ -245,6 +391,13 @@ entUnaUser:
 	stq	$13, 32($sp)
 	stq	$14, 40($sp)
 	stq	$15, 48($sp)
+	.cfi_rel_offset	$9, 0
+	.cfi_rel_offset	$10, 8
+	.cfi_rel_offset	$11, 16
+	.cfi_rel_offset	$12, 24
+	.cfi_rel_offset	$13, 32
+	.cfi_rel_offset	$14, 40
+	.cfi_rel_offset	$15, 48
 	lda	$8, 0x3fff
 	addq	$sp, 56, $19
 	bic	$sp, $8, $8
@@ -257,20 +410,25 @@ entUnaUser:
 	ldq	$14, 40($sp)
 	ldq	$15, 48($sp)
 	lda	$sp, 56($sp)
+	.cfi_restore	$9
+	.cfi_restore	$10
+	.cfi_restore	$11
+	.cfi_restore	$12
+	.cfi_restore	$13
+	.cfi_restore	$14
+	.cfi_restore	$15
+	.cfi_adjust_cfa_offset	-56
 	br	ret_from_sys_call
-.end entUnaUser
+CFI_END_OSF_FRAME entUna
 
-	.align	4
-	.globl	entDbg
-	.ent	entDbg
-entDbg:
+CFI_START_OSF_FRAME entDbg
 	SAVE_ALL
 	lda	$8, 0x3fff
 	lda	$26, ret_from_sys_call
 	bic	$sp, $8, $8
 	mov	$sp, $16
 	jsr	$31, do_entDbg
-.end entDbg
+CFI_END_OSF_FRAME entDbg
 
 /*
  * The system call entry point is special.  Most importantly, it looks
@@ -285,8 +443,12 @@ entDbg:
 
 	.align	4
 	.globl	entSys
-	.globl	ret_from_sys_call
-	.ent	entSys
+	.type	entSys, @function
+	.cfi_startproc simple
+	.cfi_return_column 64
+	.cfi_def_cfa	$sp, 48
+	.cfi_rel_offset	64, 8
+	.cfi_rel_offset	$gp, 16
 entSys:
 	SAVE_ALL
 	lda	$8, 0x3fff
@@ -300,6 +462,9 @@ entSys:
 	stq	$17, SP_OFF+32($sp)
 	s8addq	$0, $5, $5
 	stq	$18, SP_OFF+40($sp)
+	.cfi_rel_offset	$16, SP_OFF+24
+	.cfi_rel_offset	$17, SP_OFF+32
+	.cfi_rel_offset	$18, SP_OFF+40
 	blbs	$3, strace
 	beq	$4, 1f
 	ldq	$27, 0($5)
@@ -310,6 +475,7 @@ entSys:
 	stq	$31, 72($sp)		/* a3=0 => no error */
 
 	.align	4
+	.globl	ret_from_sys_call
 ret_from_sys_call:
 	cmovne	$26, 0, $18		/* $18 = 0 => non-restartable */
 	ldq	$0, SP_OFF($sp)
@@ -324,10 +490,12 @@ ret_to_user:
 	and	$17, _TIF_WORK_MASK, $2
 	bne	$2, work_pending
 restore_all:
+	.cfi_remember_state
 	RESTORE_ALL
 	call_pal PAL_rti
 
 ret_to_kernel:
+	.cfi_restore_state
 	lda	$16, 7
 	call_pal PAL_swpipl
 	br restore_all
@@ -356,7 +524,6 @@ $ret_success:
 	stq	$0, 0($sp)
 	stq	$31, 72($sp)	/* a3=0 => no error */
 	br	ret_from_sys_call
-.end entSys
 
 /*
  * Do all cleanup when returning from all interrupts and system calls.
@@ -370,7 +537,7 @@ $ret_success:
  */
 
 	.align	4
-	.ent	work_pending
+	.type	work_pending, @function
 work_pending:
 	and	$17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2
 	bne	$2, $work_notifysig
@@ -387,23 +554,22 @@ $work_resched:
 
 $work_notifysig:
 	mov	$sp, $16
-	bsr	$1, do_switch_stack
+	DO_SWITCH_STACK
 	jsr	$26, do_work_pending
-	bsr	$1, undo_switch_stack
+	UNDO_SWITCH_STACK
 	br	restore_all
-.end work_pending
 
 /*
  * PTRACE syscall handler
  */
 
 	.align	4
-	.ent	strace
+	.type	strace, @function
 strace:
 	/* set up signal stack, call syscall_trace */
-	bsr	$1, do_switch_stack
+	DO_SWITCH_STACK
 	jsr	$26, syscall_trace_enter /* returns the syscall number */
-	bsr	$1, undo_switch_stack
+	UNDO_SWITCH_STACK
 
 	/* get the arguments back.. */
 	ldq	$16, SP_OFF+24($sp)
@@ -431,9 +597,9 @@ ret_from_straced:
 $strace_success:
 	stq	$0, 0($sp)		/* save return value */
 
-	bsr	$1, do_switch_stack
+	DO_SWITCH_STACK
 	jsr	$26, syscall_trace_leave
-	bsr	$1, undo_switch_stack
+	UNDO_SWITCH_STACK
 	br	$31, ret_from_sys_call
 
 	.align	3
@@ -447,26 +613,31 @@ $strace_error:
 	stq	$0, 0($sp)
 	stq	$1, 72($sp)	/* a3 for return */
 
-	bsr	$1, do_switch_stack
+	DO_SWITCH_STACK
 	mov	$18, $9		/* save old syscall number */
 	mov	$19, $10	/* save old a3 */
 	jsr	$26, syscall_trace_leave
 	mov	$9, $18
 	mov	$10, $19
-	bsr	$1, undo_switch_stack
+	UNDO_SWITCH_STACK
 
 	mov	$31, $26	/* tell "ret_from_sys_call" we can restart */
 	br	ret_from_sys_call
-.end strace
+CFI_END_OSF_FRAME entSys
 
 /*
  * Save and restore the switch stack -- aka the balance of the user context.
  */
 
 	.align	4
-	.ent	do_switch_stack
+	.type	do_switch_stack, @function
+	.cfi_startproc simple
+	.cfi_return_column 64
+	.cfi_def_cfa $sp, 0
+	.cfi_register 64, $1
 do_switch_stack:
 	lda	$sp, -SWITCH_STACK_SIZE($sp)
+	.cfi_adjust_cfa_offset	SWITCH_STACK_SIZE
 	stq	$9, 0($sp)
 	stq	$10, 8($sp)
 	stq	$11, 16($sp)
@@ -510,10 +681,14 @@ do_switch_stack:
 	stt	$f0, 312($sp)	# save fpcr in slot of $f31
 	ldt	$f0, 64($sp)	# dont let "do_switch_stack" change fp state.
 	ret	$31, ($1), 1
-.end do_switch_stack
+	.cfi_endproc
+	.size	do_switch_stack, .-do_switch_stack
 
 	.align	4
-	.ent	undo_switch_stack
+	.type	undo_switch_stack, @function
+	.cfi_startproc simple
+	.cfi_def_cfa $sp, 0
+	.cfi_register 64, $1
 undo_switch_stack:
 	ldq	$9, 0($sp)
 	ldq	$10, 8($sp)
@@ -558,7 +733,8 @@ undo_switch_stack:
 	ldt	$f30, 304($sp)
 	lda	$sp, SWITCH_STACK_SIZE($sp)
 	ret	$31, ($1), 1
-.end undo_switch_stack
+	.cfi_endproc
+	.size	undo_switch_stack, .-undo_switch_stack
 
 /*
  * The meat of the context switch code.
@@ -566,17 +742,18 @@ undo_switch_stack:
 
 	.align	4
 	.globl	alpha_switch_to
-	.ent	alpha_switch_to
+	.type	alpha_switch_to, @function
+	.cfi_startproc
 alpha_switch_to:
-	.prologue 0
-	bsr	$1, do_switch_stack
+	DO_SWITCH_STACK
 	call_pal PAL_swpctx
 	lda	$8, 0x3fff
-	bsr	$1, undo_switch_stack
+	UNDO_SWITCH_STACK
 	bic	$sp, $8, $8
 	mov	$17, $0
 	ret
-.end alpha_switch_to
+	.cfi_endproc
+	.size	alpha_switch_to, .-alpha_switch_to
 
 /*
  * New processes begin life here.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/irq_alpha.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/irq_alpha.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/irq_alpha.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/irq_alpha.c	2013-08-25 20:43:22.000000000 -0400
@@ -236,7 +236,7 @@ void __init
 init_rtc_irq(void)
 {
 	irq_set_chip_and_handler_name(RTC_IRQ, &dummy_irq_chip,
-				      handle_simple_irq, "RTC");
+				      handle_percpu_irq, "RTC");
 	setup_irq(RTC_IRQ, &timer_irqaction);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/osf_sys.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/osf_sys.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/osf_sys.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/osf_sys.c	2013-08-25 20:43:22.000000000 -0400
@@ -96,6 +96,7 @@ struct osf_dirent {
 };
 
 struct osf_dirent_callback {
+	struct dir_context ctx;
 	struct osf_dirent __user *dirent;
 	long __user *basep;
 	unsigned int count;
@@ -146,17 +147,17 @@ SYSCALL_DEFINE4(osf_getdirentries, unsig
 {
 	int error;
 	struct fd arg = fdget(fd);
-	struct osf_dirent_callback buf;
+	struct osf_dirent_callback buf = {
+		.ctx.actor = osf_filldir,
+		.dirent = dirent,
+		.basep = basep,
+		.count = count
+	};
 
 	if (!arg.file)
 		return -EBADF;
 
-	buf.dirent = dirent;
-	buf.basep = basep;
-	buf.count = count;
-	buf.error = 0;
-
-	error = vfs_readdir(arg.file, osf_filldir, &buf);
+	error = iterate_dir(arg.file, &buf.ctx);
 	if (error >= 0)
 		error = buf.error;
 	if (count != buf.count)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/pci-sysfs.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/pci-sysfs.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/pci-sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/pci-sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,6 @@ static int hose_mmap_page_range(struct p
 		base = sparse ? hose->sparse_io_base : hose->dense_io_base;
 
 	vma->vm_pgoff += base >> PAGE_SHIFT;
-	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 
 	return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
 				  vma->vm_end - vma->vm_start,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/process.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/process.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -117,7 +117,9 @@ common_shutdown_1(void *generic_ptr)
 		if (in_interrupt())
 			irq_exit();
 		/* This has the effect of resetting the VGA video origin.  */
-		take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
+		console_lock();
+		do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
+		console_unlock();
 #endif
 		pci_restore_srm_config();
 		set_hae(srm_hae);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/smp.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,7 +116,7 @@ wait_boot_cpu_to_stop(int cpuid)
 /*
  * Where secondaries begin a life of C.
  */
-void __cpuinit
+void
 smp_callin(void)
 {
 	int cpuid = hard_smp_processor_id();
@@ -194,7 +194,7 @@ wait_for_txrdy (unsigned long cpumask)
  * Send a message to a secondary's console.  "START" is one such
  * interesting message.  ;-)
  */
-static void __cpuinit
+static void
 send_secondary_console_msg(char *str, int cpuid)
 {
 	struct percpu_struct *cpu;
@@ -264,9 +264,10 @@ recv_secondary_console_msg(void)
 		if (cnt <= 0 || cnt >= 80)
 			strcpy(buf, "<<< BOGUS MSG >>>");
 		else {
-			cp1 = (char *) &cpu->ipc_buffer[11];
+			cp1 = (char *) &cpu->ipc_buffer[1];
 			cp2 = buf;
-			strcpy(cp2, cp1);
+			memcpy(cp2, cp1, cnt);
+			cp2[cnt] = '\0';
 			
 			while ((cp2 = strchr(cp2, '\r')) != 0) {
 				*cp2 = ' ';
@@ -285,7 +286,7 @@ recv_secondary_console_msg(void)
 /*
  * Convince the console to have a secondary cpu begin execution.
  */
-static int __cpuinit
+static int
 secondary_cpu_start(int cpuid, struct task_struct *idle)
 {
 	struct percpu_struct *cpu;
@@ -356,7 +357,7 @@ secondary_cpu_start(int cpuid, struct ta
 /*
  * Bring one cpu online.
  */
-static int __cpuinit
+static int
 smp_boot_one_cpu(int cpuid, struct task_struct *idle)
 {
 	unsigned long timeout;
@@ -472,7 +473,7 @@ smp_prepare_boot_cpu(void)
 {
 }
 
-int __cpuinit
+int
 __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	smp_boot_one_cpu(cpu, tidle);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/sys_dp264.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/sys_dp264.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/sys_dp264.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/sys_dp264.c	2013-08-25 20:43:22.000000000 -0400
@@ -190,9 +190,6 @@ static struct irq_chip clipper_irq_type
 static void
 dp264_device_interrupt(unsigned long vector)
 {
-#if 1
-	printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n");
-#else
 	unsigned long pld;
 	unsigned int i;
 
@@ -210,12 +207,7 @@ dp264_device_interrupt(unsigned long vec
 			isa_device_interrupt(vector);
 		else
 			handle_irq(16 + i);
-#if 0
-		TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
-		tmp = TSUNAMI_cchip->dir0.csr;
-#endif
 	}
-#endif
 }
 
 static void 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/sys_marvel.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/sys_marvel.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/sys_marvel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/sys_marvel.c	2013-08-25 20:43:22.000000000 -0400
@@ -317,8 +317,9 @@ marvel_init_irq(void)
 }
 
 static int 
-marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+marvel_map_irq(const struct pci_dev *cdev, u8 slot, u8 pin)
 {
+	struct pci_dev *dev = (struct pci_dev *)cdev;
 	struct pci_controller *hose = dev->sysdata;
 	struct io7_port *io7_port = hose->sysdata;
 	struct io7 *io7 = io7_port->io7;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/sys_nautilus.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/sys_nautilus.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/sys_nautilus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/sys_nautilus.c	2013-08-25 20:43:22.000000000 -0400
@@ -238,8 +238,8 @@ nautilus_init_pci(void)
 	if (pci_mem < memtop)
 		memtop = pci_mem;
 	if (memtop > alpha_mv.min_mem_address) {
-		free_reserved_area((unsigned long)__va(alpha_mv.min_mem_address),
-				   (unsigned long)__va(memtop), 0, NULL);
+		free_reserved_area(__va(alpha_mv.min_mem_address),
+				   __va(memtop), -1, NULL);
 		printk("nautilus_init_pci: %ldk freed\n",
 			(memtop - alpha_mv.min_mem_address) >> 10);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/systbls.S linux-libre-3.11-rc7-gnu/arch/alpha/kernel/systbls.S
--- linux-libre-3.10-gnu/arch/alpha/kernel/systbls.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/systbls.S	2013-08-25 20:43:22.000000000 -0400
@@ -524,6 +524,8 @@ sys_call_table:
 	.quad sys_sendmmsg
 	.quad sys_process_vm_readv
 	.quad sys_process_vm_writev		/* 505 */
+	.quad sys_kcmp
+	.quad sys_finit_module
 
 	.size sys_call_table, . - sys_call_table
 	.type sys_call_table, @object
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/time.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/time.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -105,9 +105,7 @@ void arch_irq_work_raise(void)
 
 static inline __u32 rpcc(void)
 {
-    __u32 result;
-    asm volatile ("rpcc %0" : "=r"(result));
-    return result;
+	return __builtin_alpha_rpcc();
 }
 
 int update_persistent_clock(struct timespec now)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/alpha/kernel/traps.c
--- linux-libre-3.10-gnu/arch/alpha/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,7 @@
 
 static int opDEC_fix;
 
-static void __cpuinit
+static void
 opDEC_check(void)
 {
 	__asm__ __volatile__ (
@@ -66,8 +66,8 @@ dik_show_regs(struct pt_regs *regs, unsi
 {
 	printk("pc = [<%016lx>]  ra = [<%016lx>]  ps = %04lx    %s\n",
 	       regs->pc, regs->r26, regs->ps, print_tainted());
-	print_symbol("pc is at %s\n", regs->pc);
-	print_symbol("ra is at %s\n", regs->r26 );
+	printk("pc is at %pSR\n", (void *)regs->pc);
+	printk("ra is at %pSR\n", (void *)regs->r26);
 	printk("v0 = %016lx  t0 = %016lx  t1 = %016lx\n",
 	       regs->r0, regs->r1, regs->r2);
 	printk("t2 = %016lx  t3 = %016lx  t4 = %016lx\n",
@@ -132,9 +132,7 @@ dik_show_trace(unsigned long *sp)
 			continue;
 		if (tmp >= (unsigned long) &_etext)
 			continue;
-		printk("[<%lx>]", tmp);
-		print_symbol(" %s", tmp);
-		printk("\n");
+		printk("[<%lx>] %pSR\n", tmp, (void *)tmp);
 		if (i > 40) {
 			printk(" ...");
 			break;
@@ -1059,7 +1057,7 @@ give_sigbus:
 	return;
 }
 
-void __cpuinit
+void
 trap_init(void)
 {
 	/* Tell PAL-code what global pointer we want in the kernel.  */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/mm/init.c linux-libre-3.11-rc7-gnu/arch/alpha/mm/init.c
--- linux-libre-3.10-gnu/arch/alpha/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -276,56 +276,25 @@ srm_paging_stop (void)
 }
 #endif
 
-#ifndef CONFIG_DISCONTIGMEM
-static void __init
-printk_memory_info(void)
-{
-	unsigned long codesize, reservedpages, datasize, initsize, tmp;
-	extern int page_is_ram(unsigned long) __init;
-
-	/* printk all informations */
-	reservedpages = 0;
-	for (tmp = 0; tmp < max_low_pfn; tmp++)
-		/*
-		 * Only count reserved RAM pages
-		 */
-		if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
-			reservedpages++;
-
-	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_data;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
-	printk("Memory: %luk/%luk available (%luk kernel code, %luk reserved, %luk data, %luk init)\n",
-	       nr_free_pages() << (PAGE_SHIFT-10),
-	       max_mapnr << (PAGE_SHIFT-10),
-	       codesize >> 10,
-	       reservedpages << (PAGE_SHIFT-10),
-	       datasize >> 10,
-	       initsize >> 10);
-}
-
 void __init
 mem_init(void)
 {
-	max_mapnr = num_physpages = max_low_pfn;
-	totalram_pages += free_all_bootmem();
+	set_max_mapnr(max_low_pfn);
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
-
-	printk_memory_info();
+	free_all_bootmem();
+	mem_init_print_info(NULL);
 }
-#endif /* CONFIG_DISCONTIGMEM */
 
 void
 free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void
 free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/alpha/mm/numa.c linux-libre-3.11-rc7-gnu/arch/alpha/mm/numa.c
--- linux-libre-3.10-gnu/arch/alpha/mm/numa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/alpha/mm/numa.c	2013-08-25 20:43:22.000000000 -0400
@@ -129,8 +129,6 @@ setup_memory_node(int nid, void *kernel_
 	if (node_max_pfn > max_low_pfn)
 		max_pfn = max_low_pfn = node_max_pfn;
 
-	num_physpages += node_max_pfn - node_min_pfn;
-
 #if 0 /* we'll try this one again in a little while */
 	/* Cute trick to make sure our local node data is on local memory */
 	node_data[nid] = (pg_data_t *)(__va(node_min_pfn << PAGE_SHIFT));
@@ -321,41 +319,3 @@ void __init paging_init(void)
 	/* Initialize the kernel's ZERO_PGE. */
 	memset((void *)ZERO_PGE, 0, PAGE_SIZE);
 }
-
-void __init mem_init(void)
-{
-	unsigned long codesize, reservedpages, datasize, initsize, pfn;
-	extern int page_is_ram(unsigned long) __init;
-	unsigned long nid, i;
-	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
-
-	reservedpages = 0;
-	for_each_online_node(nid) {
-		/*
-		 * This will free up the bootmem, ie, slot 0 memory
-		 */
-		totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
-
-		pfn = NODE_DATA(nid)->node_start_pfn;
-		for (i = 0; i < node_spanned_pages(nid); i++, pfn++)
-			if (page_is_ram(pfn) &&
-			    PageReserved(nid_page_nr(nid, i)))
-				reservedpages++;
-	}
-
-	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_data;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
-	printk("Memory: %luk/%luk available (%luk kernel code, %luk reserved, "
-	       "%luk data, %luk init)\n",
-	       nr_free_pages() << (PAGE_SHIFT-10),
-	       num_physpages << (PAGE_SHIFT-10),
-	       codesize >> 10,
-	       reservedpages << (PAGE_SHIFT-10),
-	       datasize >> 10,
-	       initsize >> 10);
-#if 0
-	mem_stress();
-#endif
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb100.dtsi linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb100.dtsi
--- linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb100.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb100.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -21,10 +21,6 @@
 
 /include/ "abilis_tb10x.dtsi"
 
-/* interrupt specifiers
- * --------------------
- * 0: rising, 1: low, 2: high, 3: falling,
- */
 
 / {
 	clock-frequency		= <500000000>;	/* 500 MHZ */
@@ -173,7 +169,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF140000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -185,7 +181,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF141000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -197,7 +193,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF142000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -209,7 +205,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF143000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -221,7 +217,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF144000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -233,7 +229,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF145000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -245,7 +241,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF146000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -257,7 +253,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF147000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -269,7 +265,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF148000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -281,7 +277,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF149000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -293,7 +289,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF14A000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -305,7 +301,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF14B000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -317,7 +313,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF14C000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -329,7 +325,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF14D000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb100_dvk.dts linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb100_dvk.dts
--- linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb100_dvk.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb100_dvk.dts	2013-08-25 20:43:22.000000000 -0400
@@ -45,19 +45,19 @@
 		};
 
 		i2c0: i2c@FF120000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 		i2c1: i2c@FF121000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 		i2c2: i2c@FF122000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 		i2c3: i2c@FF123000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 		i2c4: i2c@FF124000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 
 		leds {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb101.dtsi linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb101.dtsi
--- linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb101.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb101.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -21,10 +21,6 @@
 
 /include/ "abilis_tb10x.dtsi"
 
-/* interrupt specifiers
- * --------------------
- * 0: rising, 1: low, 2: high, 3: falling,
- */
 
 / {
 	clock-frequency		= <500000000>;	/* 500 MHZ */
@@ -182,7 +178,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF140000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -194,7 +190,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF141000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -206,7 +202,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF142000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -218,7 +214,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF143000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -230,7 +226,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF144000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -242,7 +238,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF145000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -254,7 +250,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF146000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -266,7 +262,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF147000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -278,7 +274,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF148000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -290,7 +286,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF149000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -302,7 +298,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF14A000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -314,7 +310,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF14B000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -326,7 +322,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF14C000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
@@ -338,7 +334,7 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <27 1>;
+			interrupts = <27 2>;
 			reg = <0xFF14D000 0x1000>;
 			gpio-controller;
 			#gpio-cells = <1>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb101_dvk.dts linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb101_dvk.dts
--- linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb101_dvk.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb101_dvk.dts	2013-08-25 20:43:22.000000000 -0400
@@ -45,19 +45,19 @@
 		};
 
 		i2c0: i2c@FF120000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 		i2c1: i2c@FF121000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 		i2c2: i2c@FF122000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 		i2c3: i2c@FF123000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 		i2c4: i2c@FF124000 {
-			sda-hold-time = <432>;
+			i2c-sda-hold-time-ns = <432>;
 		};
 
 		leds {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb10x.dtsi linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb10x.dtsi
--- linux-libre-3.10-gnu/arch/arc/boot/dts/abilis_tb10x.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/abilis_tb10x.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -19,10 +19,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-/* interrupt specifiers
- * --------------------
- * 0: rising, 1: low, 2: high, 3: falling,
- */
 
 / {
 	compatible		= "abilis,arc-tb10x";
@@ -78,7 +74,7 @@
 			#interrupt-cells = <1>;
 		};
 		tb10x_ictl: pic@fe002000 {
-			compatible = "abilis,tb10x_ictl";
+			compatible = "abilis,tb10x-ictl";
 			reg = <0xFE002000 0x20>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
@@ -91,7 +87,7 @@
 			compatible = "snps,dw-apb-uart";
 			reg = <0xFF100000 0x100>;
 			clock-frequency = <166666666>;
-			interrupts = <25 1>;
+			interrupts = <25 8>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
 			interrupt-parent = <&tb10x_ictl>;
@@ -100,7 +96,7 @@
 			compatible = "snps,dwmac-3.70a","snps,dwmac";
 			reg = <0xFE100000 0x1058>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <6 1>;
+			interrupts = <6 8>;
 			interrupt-names = "macirq";
 			clocks = <&ahb_clk>;
 			clock-names = "stmmaceth";
@@ -109,7 +105,7 @@
 			compatible = "snps,dma-spear1340";
 			reg = <0xFE000000 0x400>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <14 1>;
+			interrupts = <14 8>;
 			dma-channels = <6>;
 			dma-requests = <0>;
 			dma-masters = <1>;
@@ -128,7 +124,7 @@
 			compatible = "snps,designware-i2c";
 			reg = <0xFF120000 0x1000>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <12 1>;
+			interrupts = <12 8>;
 			clocks = <&ahb_clk>;
 		};
 		i2c1: i2c@FF121000 {
@@ -137,7 +133,7 @@
 			compatible = "snps,designware-i2c";
 			reg = <0xFF121000 0x1000>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <12 1>;
+			interrupts = <12 8>;
 			clocks = <&ahb_clk>;
 		};
 		i2c2: i2c@FF122000 {
@@ -146,7 +142,7 @@
 			compatible = "snps,designware-i2c";
 			reg = <0xFF122000 0x1000>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <12 1>;
+			interrupts = <12 8>;
 			clocks = <&ahb_clk>;
 		};
 		i2c3: i2c@FF123000 {
@@ -155,7 +151,7 @@
 			compatible = "snps,designware-i2c";
 			reg = <0xFF123000 0x1000>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <12 1>;
+			interrupts = <12 8>;
 			clocks = <&ahb_clk>;
 		};
 		i2c4: i2c@FF124000 {
@@ -164,7 +160,7 @@
 			compatible = "snps,designware-i2c";
 			reg = <0xFF124000 0x1000>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <12 1>;
+			interrupts = <12 8>;
 			clocks = <&ahb_clk>;
 		};
 
@@ -176,7 +172,7 @@
 			num-cs = <1>;
 			reg = <0xFE010000 0x20>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <26 1>;
+			interrupts = <26 8>;
 			clocks = <&ahb_clk>;
 		};
 		spi1: spi@0xFE011000 {
@@ -187,7 +183,7 @@
 			num-cs = <2>;
 			reg = <0xFE011000 0x20>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <10 1>;
+			interrupts = <10 8>;
 			clocks = <&ahb_clk>;
 		};
 
@@ -195,7 +191,7 @@
 			compatible = "abilis,tb100-tsm";
 			reg = <0xff316000 0x400>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <17 1>;
+			interrupts = <17 8>;
 			output-clkdiv = <4>;
 			global-packet-delay = <0x21>;
 			port-packet-delay = <0>;
@@ -213,7 +209,7 @@
 					"cpuctrl",
 					"a6it_int_force";
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <20 1>, <19 1>;
+			interrupts = <20 2>, <19 2>;
 			interrupt-names = "cmd_irq", "event_irq";
 		};
 		tb10x_mdsc0: tb10x-mdscr@FF300000 {
@@ -239,7 +235,7 @@
 			compatible = "abilis,tb100-wfb";
 			reg = <0xff319000 0x1000>;
 			interrupt-parent = <&tb10x_ictl>;
-			interrupts = <16 1>;
+			interrupts = <16 8>;
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/boot/dts/angel4.dts linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/angel4.dts
--- linux-libre-3.10-gnu/arch/arc/boot/dts/angel4.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/boot/dts/angel4.dts	2013-08-25 20:43:22.000000000 -0400
@@ -51,5 +51,21 @@
 			current-speed = <115200>;
 			status = "okay";
 		};
+
+		ethernet@c0fc2000 {
+			compatible = "snps,arc-emac";
+			reg = <0xc0fc2000 0x3c>;
+			interrupts = <6>;
+			mac-address = [ 00 11 22 33 44 55 ];
+			clock-frequency = <80000000>;
+			max-speed = <100>;
+			phy = <&phy0>;
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+			phy0: ethernet-phy@0 {
+				reg = <1>;
+			};
+		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/configs/fpga_defconfig linux-libre-3.11-rc7-gnu/arch/arc/configs/fpga_defconfig
--- linux-libre-3.10-gnu/arch/arc/configs/fpga_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/configs/fpga_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-elf32-"
+CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
@@ -38,6 +38,9 @@ CONFIG_INET=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 # CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+CONFIG_ARC_EMAC=y
+CONFIG_LXT_PHY=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/configs/nsimosci_defconfig linux-libre-3.11-rc7-gnu/arch/arc/configs/nsimosci_defconfig
--- linux-libre-3.10-gnu/arch/arc/configs/nsimosci_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/configs/nsimosci_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-elf32-"
+CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/configs/tb10x_defconfig linux-libre-3.11-rc7-gnu/arch/arc/configs/tb10x_defconfig
--- linux-libre-3.10-gnu/arch/arc/configs/tb10x_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/configs/tb10x_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-CONFIG_CROSS_COMPILE="arc-elf32-"
+CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_DEFAULT_HOSTNAME="tb10x"
 CONFIG_SYSVIPC=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/arcregs.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/arcregs.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/arcregs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/arcregs.h	2013-08-25 20:43:22.000000000 -0400
@@ -20,7 +20,6 @@
 #define ARC_REG_PERIBASE_BCR	0x69
 #define ARC_REG_FP_BCR		0x6B	/* Single-Precision FPU */
 #define ARC_REG_DPFP_BCR	0x6C	/* Dbl Precision FPU */
-#define ARC_REG_MMU_BCR		0x6f
 #define ARC_REG_DCCM_BCR	0x74	/* DCCM Present + SZ */
 #define ARC_REG_TIMERS_BCR	0x75
 #define ARC_REG_ICCM_BCR	0x78
@@ -34,22 +33,12 @@
 #define ARC_REG_D_UNCACH_BCR	0x6A
 
 /* status32 Bits Positions */
-#define STATUS_H_BIT		0	/* CPU Halted */
-#define STATUS_E1_BIT		1	/* Int 1 enable */
-#define STATUS_E2_BIT		2	/* Int 2 enable */
-#define STATUS_A1_BIT		3	/* Int 1 active */
-#define STATUS_A2_BIT		4	/* Int 2 active */
 #define STATUS_AE_BIT		5	/* Exception active */
 #define STATUS_DE_BIT		6	/* PC is in delay slot */
 #define STATUS_U_BIT		7	/* User/Kernel mode */
 #define STATUS_L_BIT		12	/* Loop inhibit */
 
 /* These masks correspond to the status word(STATUS_32) bits */
-#define STATUS_H_MASK		(1<<STATUS_H_BIT)
-#define STATUS_E1_MASK		(1<<STATUS_E1_BIT)
-#define STATUS_E2_MASK		(1<<STATUS_E2_BIT)
-#define STATUS_A1_MASK		(1<<STATUS_A1_BIT)
-#define STATUS_A2_MASK		(1<<STATUS_A2_BIT)
 #define STATUS_AE_MASK		(1<<STATUS_AE_BIT)
 #define STATUS_DE_MASK		(1<<STATUS_DE_BIT)
 #define STATUS_U_MASK		(1<<STATUS_U_BIT)
@@ -71,6 +60,7 @@
 #define ECR_V_ITLB_MISS			0x21
 #define ECR_V_DTLB_MISS			0x22
 #define ECR_V_PROTV			0x23
+#define ECR_V_TRAP			0x25
 
 /* Protection Violation Exception Cause Code Values */
 #define ECR_C_PROTV_INST_FETCH		0x00
@@ -79,94 +69,23 @@
 #define ECR_C_PROTV_XCHG		0x03
 #define ECR_C_PROTV_MISALIG_DATA	0x04
 
+#define ECR_C_BIT_PROTV_MISALIG_DATA	10
+
+/* Machine Check Cause Code Values */
+#define ECR_C_MCHK_DUP_TLB		0x01
+
 /* DTLB Miss Exception Cause Code Values */
 #define ECR_C_BIT_DTLB_LD_MISS		8
 #define ECR_C_BIT_DTLB_ST_MISS		9
 
+/* Dummy ECR values for Interrupts */
+#define event_IRQ1		0x0031abcd
+#define event_IRQ2		0x0032abcd
 
 /* Auxiliary registers */
 #define AUX_IDENTITY		4
 #define AUX_INTR_VEC_BASE	0x25
-#define AUX_IRQ_LEV		0x200	/* IRQ Priority: L1 or L2 */
-#define AUX_IRQ_HINT		0x201	/* For generating Soft Interrupts */
-#define AUX_IRQ_LV12		0x43	/* interrupt level register */
-
-#define AUX_IENABLE		0x40c
-#define AUX_ITRIGGER		0x40d
-#define AUX_IPULSE		0x415
-
-/* Timer related Aux registers */
-#define ARC_REG_TIMER0_LIMIT	0x23	/* timer 0 limit */
-#define ARC_REG_TIMER0_CTRL	0x22	/* timer 0 control */
-#define ARC_REG_TIMER0_CNT	0x21	/* timer 0 count */
-#define ARC_REG_TIMER1_LIMIT	0x102	/* timer 1 limit */
-#define ARC_REG_TIMER1_CTRL	0x101	/* timer 1 control */
-#define ARC_REG_TIMER1_CNT	0x100	/* timer 1 count */
-
-#define TIMER_CTRL_IE		(1 << 0) /* Interupt when Count reachs limit */
-#define TIMER_CTRL_NH		(1 << 1) /* Count only when CPU NOT halted */
-
-/* MMU Management regs */
-#define ARC_REG_TLBPD0		0x405
-#define ARC_REG_TLBPD1		0x406
-#define ARC_REG_TLBINDEX	0x407
-#define ARC_REG_TLBCOMMAND	0x408
-#define ARC_REG_PID		0x409
-#define ARC_REG_SCRATCH_DATA0	0x418
-
-/* Bits in MMU PID register */
-#define MMU_ENABLE		(1 << 31)	/* Enable MMU for process */
-
-/* Error code if probe fails */
-#define TLB_LKUP_ERR		0x80000000
 
-/* TLB Commands */
-#define TLBWrite    0x1
-#define TLBRead     0x2
-#define TLBGetIndex 0x3
-#define TLBProbe    0x4
-
-#if (CONFIG_ARC_MMU_VER >= 2)
-#define TLBWriteNI  0x5		/* write JTLB without inv uTLBs */
-#define TLBIVUTLB   0x6		/* explicitly inv uTLBs */
-#else
-#undef TLBWriteNI		/* These cmds don't exist on older MMU */
-#undef TLBIVUTLB
-#endif
-
-/* Instruction cache related Auxiliary registers */
-#define ARC_REG_IC_BCR		0x77	/* Build Config reg */
-#define ARC_REG_IC_IVIC		0x10
-#define ARC_REG_IC_CTRL		0x11
-#define ARC_REG_IC_IVIL		0x19
-#if (CONFIG_ARC_MMU_VER > 2)
-#define ARC_REG_IC_PTAG		0x1E
-#endif
-
-/* Bit val in IC_CTRL */
-#define IC_CTRL_CACHE_DISABLE   0x1
-
-/* Data cache related Auxiliary registers */
-#define ARC_REG_DC_BCR		0x72
-#define ARC_REG_DC_IVDC		0x47
-#define ARC_REG_DC_CTRL		0x48
-#define ARC_REG_DC_IVDL		0x4A
-#define ARC_REG_DC_FLSH		0x4B
-#define ARC_REG_DC_FLDL		0x4C
-#if (CONFIG_ARC_MMU_VER > 2)
-#define ARC_REG_DC_PTAG		0x5C
-#endif
-
-/* Bit val in DC_CTRL */
-#define DC_CTRL_INV_MODE_FLUSH  0x40
-#define DC_CTRL_FLUSH_STATUS    0x100
-
-/* MMU Management regs */
-#define ARC_REG_PID		0x409
-#define ARC_REG_SCRATCH_DATA0	0x418
-
-/* Bits in MMU PID register */
-#define MMU_ENABLE		(1 << 31)	/* Enable MMU for process */
 
 /*
  * Floating Pt Registers
@@ -293,24 +212,6 @@ struct bcr_identity {
 #endif
 };
 
-struct bcr_mmu_1_2 {
-#ifdef CONFIG_CPU_BIG_ENDIAN
-	unsigned int ver:8, ways:4, sets:4, u_itlb:8, u_dtlb:8;
-#else
-	unsigned int u_dtlb:8, u_itlb:8, sets:4, ways:4, ver:8;
-#endif
-};
-
-struct bcr_mmu_3 {
-#ifdef CONFIG_CPU_BIG_ENDIAN
-	unsigned int ver:8, ways:4, sets:4, osm:1, reserv:3, pg_sz:4,
-		     u_itlb:4, u_dtlb:4;
-#else
-	unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, reserv:3, osm:1, sets:4,
-		     ways:4, ver:8;
-#endif
-};
-
 #define EXTN_SWAP_VALID     0x1
 #define EXTN_NORM_VALID     0x2
 #define EXTN_MINMAX_VALID   0x2
@@ -343,14 +244,6 @@ struct bcr_extn_xymem {
 #endif
 };
 
-struct bcr_cache {
-#ifdef CONFIG_CPU_BIG_ENDIAN
-	unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
-#else
-	unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
-#endif
-};
-
 struct bcr_perip {
 #ifdef CONFIG_CPU_BIG_ENDIAN
 	unsigned int start:8, pad2:8, sz:8, pad:8;
@@ -403,7 +296,7 @@ struct cpuinfo_arc_mmu {
 };
 
 struct cpuinfo_arc_cache {
-	unsigned int has_aliasing, sz, line_len, assoc, ver;
+	unsigned int sz, line_len, assoc, ver;
 };
 
 struct cpuinfo_arc_ccm {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/bug.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/bug.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/bug.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/bug.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,9 +18,8 @@ struct task_struct;
 void show_regs(struct pt_regs *regs);
 void show_stacktrace(struct task_struct *tsk, struct pt_regs *regs);
 void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
-			    unsigned long address, unsigned long cause_reg);
-void die(const char *str, struct pt_regs *regs, unsigned long address,
-	 unsigned long cause_reg);
+			    unsigned long address);
+void die(const char *str, struct pt_regs *regs, unsigned long address);
 
 #define BUG()	do {				\
 	dump_stack();					\
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/cacheflush.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/cacheflush.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/cacheflush.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/cacheflush.h	2013-08-25 20:43:22.000000000 -0400
@@ -81,16 +81,19 @@ void flush_anon_page(struct vm_area_stru
 #endif	/* CONFIG_ARC_CACHE_VIPT_ALIASING */
 
 /*
+ * A new pagecache page has PG_arch_1 clear - thus dcache dirty by default
+ * This works around some PIO based drivers which don't call flush_dcache_page
+ * to record that they dirtied the dcache
+ */
+#define PG_dc_clean	PG_arch_1
+
+/*
  * Simple wrapper over config option
  * Bootup code ensures that hardware matches kernel configuration
  */
 static inline int cache_is_vipt_aliasing(void)
 {
-#ifdef CONFIG_ARC_CACHE_VIPT_ALIASING
-	return 1;
-#else
-	return 0;
-#endif
+	return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
 }
 
 #define CACHE_COLOR(addr)	(((unsigned long)(addr) >> (PAGE_SHIFT)) & 1)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/cache.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/cache.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/cache.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/cache.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,21 +18,19 @@
 
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
-#define ARC_ICACHE_WAYS	2
-#define ARC_DCACHE_WAYS	4
-
-/* Helpers */
+/* For a rare case where customers have differently config I/D */
 #define ARC_ICACHE_LINE_LEN	L1_CACHE_BYTES
 #define ARC_DCACHE_LINE_LEN	L1_CACHE_BYTES
 
 #define ICACHE_LINE_MASK	(~(ARC_ICACHE_LINE_LEN - 1))
 #define DCACHE_LINE_MASK	(~(ARC_DCACHE_LINE_LEN - 1))
 
-#if ARC_ICACHE_LINE_LEN != ARC_DCACHE_LINE_LEN
-#error "Need to fix some code as I/D cache lines not same"
-#else
-#define is_not_cache_aligned(p)	((unsigned long)p & (~DCACHE_LINE_MASK))
-#endif
+/*
+ * ARC700 doesn't cache any access in top 256M.
+ * Ideal for wiring memory mapped peripherals as we don't need to do
+ * explicit uncached accesses (LD.di/ST.di) hence more portable drivers
+ */
+#define ARC_UNCACHED_ADDR_SPACE	0xc0000000
 
 #ifndef __ASSEMBLY__
 
@@ -57,16 +55,10 @@
 
 #define ARCH_DMA_MINALIGN      L1_CACHE_BYTES
 
-/*
- * ARC700 doesn't cache any access in top 256M.
- * Ideal for wiring memory mapped peripherals as we don't need to do
- * explicit uncached accesses (LD.di/ST.di) hence more portable drivers
- */
-#define ARC_UNCACHED_ADDR_SPACE	0xc0000000
-
 extern void arc_cache_init(void);
 extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len);
 extern void __init read_decode_cache_bcr(void);
-#endif
+
+#endif	/* !__ASSEMBLY__ */
 
 #endif /* _ASM_CACHE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/defines.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/defines.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/defines.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/defines.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ARC_ASM_DEFINES_H__
-#define __ARC_ASM_DEFINES_H__
-
-#if defined(CONFIG_ARC_MMU_V1)
-#define CONFIG_ARC_MMU_VER 1
-#elif defined(CONFIG_ARC_MMU_V2)
-#define CONFIG_ARC_MMU_VER 2
-#elif defined(CONFIG_ARC_MMU_V3)
-#define CONFIG_ARC_MMU_VER 3
-#endif
-
-#ifdef CONFIG_ARC_HAS_LLSC
-#define __CONFIG_ARC_HAS_LLSC_VAL 1
-#else
-#define __CONFIG_ARC_HAS_LLSC_VAL 0
-#endif
-
-#ifdef CONFIG_ARC_HAS_SWAPE
-#define __CONFIG_ARC_HAS_SWAPE_VAL 1
-#else
-#define __CONFIG_ARC_HAS_SWAPE_VAL 0
-#endif
-
-#ifdef CONFIG_ARC_HAS_RTSC
-#define __CONFIG_ARC_HAS_RTSC_VAL 1
-#else
-#define __CONFIG_ARC_HAS_RTSC_VAL 0
-#endif
-
-#ifdef CONFIG_ARC_MMU_SASID
-#define __CONFIG_ARC_MMU_SASID_VAL 1
-#else
-#define __CONFIG_ARC_MMU_SASID_VAL 0
-#endif
-
-#ifdef CONFIG_ARC_HAS_ICACHE
-#define __CONFIG_ARC_HAS_ICACHE	1
-#else
-#define __CONFIG_ARC_HAS_ICACHE	0
-#endif
-
-#ifdef CONFIG_ARC_HAS_DCACHE
-#define __CONFIG_ARC_HAS_DCACHE	1
-#else
-#define __CONFIG_ARC_HAS_DCACHE	0
-#endif
-
-#endif /* __ARC_ASM_DEFINES_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/entry.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/entry.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/entry.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/entry.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,6 +38,7 @@
 #include <asm/ptrace.h>
 #include <asm/processor.h>	/* For VMALLOC_START */
 #include <asm/thread_info.h>	/* For THREAD_SIZE */
+#include <asm/mmu.h>
 
 /* Note on the LD/ST addr modes with addr reg wback
  *
@@ -50,194 +51,177 @@
  *      Eff Addr for load = [reg2]
  */
 
+.macro PUSH reg
+	st.a	\reg, [sp, -4]
+.endm
+
+.macro PUSHAX aux
+	lr	r9, [\aux]
+	PUSH	r9
+.endm
+
+.macro POP reg
+	ld.ab	\reg, [sp, 4]
+.endm
+
+.macro POPAX aux
+	POP	r9
+	sr	r9, [\aux]
+.endm
+
 /*--------------------------------------------------------------
- * Save caller saved registers (scratch registers) ( r0 - r12 )
- * Registers are pushed / popped in the order defined in struct ptregs
- * in asm/ptrace.h
+ * Helpers to save/restore Scratch Regs:
+ * used by Interrupt/Exception Prologue/Epilogue
  *-------------------------------------------------------------*/
-.macro  SAVE_CALLER_SAVED
-	st.a    r0, [sp, -4]
-	st.a    r1, [sp, -4]
-	st.a    r2, [sp, -4]
-	st.a    r3, [sp, -4]
-	st.a    r4, [sp, -4]
-	st.a    r5, [sp, -4]
-	st.a    r6, [sp, -4]
-	st.a    r7, [sp, -4]
-	st.a    r8, [sp, -4]
-	st.a    r9, [sp, -4]
-	st.a    r10, [sp, -4]
-	st.a    r11, [sp, -4]
-	st.a    r12, [sp, -4]
+.macro  SAVE_R0_TO_R12
+	PUSH	r0
+	PUSH	r1
+	PUSH	r2
+	PUSH	r3
+	PUSH	r4
+	PUSH	r5
+	PUSH	r6
+	PUSH	r7
+	PUSH	r8
+	PUSH	r9
+	PUSH	r10
+	PUSH	r11
+	PUSH	r12
+.endm
+
+.macro RESTORE_R12_TO_R0
+	POP	r12
+	POP	r11
+	POP	r10
+	POP	r9
+	POP	r8
+	POP	r7
+	POP	r6
+	POP	r5
+	POP	r4
+	POP	r3
+	POP	r2
+	POP	r1
+	POP	r0
+
+#ifdef CONFIG_ARC_CURR_IN_REG
+	ld	r25, [sp, 12]
+#endif
 .endm
 
 /*--------------------------------------------------------------
- * Restore caller saved registers (scratch registers)
+ * Helpers to save/restore callee-saved regs:
+ * used by several macros below
  *-------------------------------------------------------------*/
-.macro RESTORE_CALLER_SAVED
-	ld.ab   r12, [sp, 4]
-	ld.ab   r11, [sp, 4]
-	ld.ab   r10, [sp, 4]
-	ld.ab   r9, [sp, 4]
-	ld.ab   r8, [sp, 4]
-	ld.ab   r7, [sp, 4]
-	ld.ab   r6, [sp, 4]
-	ld.ab   r5, [sp, 4]
-	ld.ab   r4, [sp, 4]
-	ld.ab   r3, [sp, 4]
-	ld.ab   r2, [sp, 4]
-	ld.ab   r1, [sp, 4]
-	ld.ab   r0, [sp, 4]
+.macro SAVE_R13_TO_R24
+	PUSH	r13
+	PUSH	r14
+	PUSH	r15
+	PUSH	r16
+	PUSH	r17
+	PUSH	r18
+	PUSH	r19
+	PUSH	r20
+	PUSH	r21
+	PUSH	r22
+	PUSH	r23
+	PUSH	r24
+.endm
+
+.macro RESTORE_R24_TO_R13
+	POP	r24
+	POP	r23
+	POP	r22
+	POP	r21
+	POP	r20
+	POP	r19
+	POP	r18
+	POP	r17
+	POP	r16
+	POP	r15
+	POP	r14
+	POP	r13
 .endm
 
+#define OFF_USER_R25_FROM_R24	(SZ_CALLEE_REGS + SZ_PT_REGS - 8)/4
 
 /*--------------------------------------------------------------
- * Save callee saved registers (non scratch registers) ( r13 - r25 )
- *  on kernel stack.
- * User mode callee regs need to be saved in case of
- *    -fork and friends for replicating from parent to child
- *    -before going into do_signal( ) for ptrace/core-dump
- * Special case handling is required for r25 in case it is used by kernel
- *  for caching task ptr. Low level exception/ISR save user mode r25
- *  into task->thread.user_r25. So it needs to be retrieved from there and
- *  saved into kernel stack with rest of callee reg-file
+ * Collect User Mode callee regs as struct callee_regs - needed by
+ * fork/do_signal/unaligned-access-emulation.
+ * (By default only scratch regs are saved on entry to kernel)
+ *
+ * Special handling for r25 if used for caching Task Pointer.
+ * It would have been saved in task->thread.user_r25 already, but to keep
+ * the interface same it is copied into regular r25 placeholder in
+ * struct callee_regs.
  *-------------------------------------------------------------*/
 .macro SAVE_CALLEE_SAVED_USER
-	st.a    r13, [sp, -4]
-	st.a    r14, [sp, -4]
-	st.a    r15, [sp, -4]
-	st.a    r16, [sp, -4]
-	st.a    r17, [sp, -4]
-	st.a    r18, [sp, -4]
-	st.a    r19, [sp, -4]
-	st.a    r20, [sp, -4]
-	st.a    r21, [sp, -4]
-	st.a    r22, [sp, -4]
-	st.a    r23, [sp, -4]
-	st.a    r24, [sp, -4]
+
+	SAVE_R13_TO_R24
 
 #ifdef CONFIG_ARC_CURR_IN_REG
 	; Retrieve orig r25 and save it on stack
-	ld      r12, [r25, TASK_THREAD + THREAD_USER_R25]
+	ld.as   r12, [sp, OFF_USER_R25_FROM_R24]
 	st.a    r12, [sp, -4]
 #else
-	st.a    r25, [sp, -4]
+	PUSH	r25
 #endif
 
-	/* move up by 1 word to "create" callee_regs->"stack_place_holder" */
-	sub sp, sp, 4
 .endm
 
 /*--------------------------------------------------------------
- * Save callee saved registers (non scratch registers) ( r13 - r25 )
- * kernel mode callee regs needed to be saved in case of context switch
- * If r25 is used for caching task pointer then that need not be saved
- * as it can be re-created from current task global
+ * Save kernel Mode callee regs at the time of Contect Switch.
+ *
+ * Special handling for r25 if used for caching Task Pointer.
+ * Kernel simply skips saving it since it will be loaded with
+ * incoming task pointer anyways
  *-------------------------------------------------------------*/
 .macro SAVE_CALLEE_SAVED_KERNEL
-	st.a    r13, [sp, -4]
-	st.a    r14, [sp, -4]
-	st.a    r15, [sp, -4]
-	st.a    r16, [sp, -4]
-	st.a    r17, [sp, -4]
-	st.a    r18, [sp, -4]
-	st.a    r19, [sp, -4]
-	st.a    r20, [sp, -4]
-	st.a    r21, [sp, -4]
-	st.a    r22, [sp, -4]
-	st.a    r23, [sp, -4]
-	st.a    r24, [sp, -4]
+
+	SAVE_R13_TO_R24
+
 #ifdef CONFIG_ARC_CURR_IN_REG
-	sub     sp, sp, 8
-#else
-	st.a    r25, [sp, -4]
 	sub     sp, sp, 4
+#else
+	PUSH	r25
 #endif
 .endm
 
 /*--------------------------------------------------------------
- * RESTORE_CALLEE_SAVED_KERNEL:
- * Loads callee (non scratch) Reg File by popping from Kernel mode stack.
- *  This is reverse of SAVE_CALLEE_SAVED,
- *
- * NOTE:
- * Ideally this shd only be called in switch_to for loading
- *  switched-IN task's CALLEE Reg File.
- *  For all other cases RESTORE_CALLEE_SAVED_FAST must be used
- *  which simply pops the stack w/o touching regs.
+ * Opposite of SAVE_CALLEE_SAVED_KERNEL
  *-------------------------------------------------------------*/
 .macro RESTORE_CALLEE_SAVED_KERNEL
 
-
 #ifdef CONFIG_ARC_CURR_IN_REG
-	add     sp, sp, 8  /* skip callee_reg gutter and user r25 placeholder */
+	add     sp, sp, 4  /* skip usual r25 placeholder */
 #else
-	add     sp, sp, 4   /* skip "callee_regs->stack_place_holder" */
-	ld.ab   r25, [sp, 4]
+	POP	r25
 #endif
-
-	ld.ab   r24, [sp, 4]
-	ld.ab   r23, [sp, 4]
-	ld.ab   r22, [sp, 4]
-	ld.ab   r21, [sp, 4]
-	ld.ab   r20, [sp, 4]
-	ld.ab   r19, [sp, 4]
-	ld.ab   r18, [sp, 4]
-	ld.ab   r17, [sp, 4]
-	ld.ab   r16, [sp, 4]
-	ld.ab   r15, [sp, 4]
-	ld.ab   r14, [sp, 4]
-	ld.ab   r13, [sp, 4]
-
+	RESTORE_R24_TO_R13
 .endm
 
 /*--------------------------------------------------------------
- * RESTORE_CALLEE_SAVED_USER:
- * This is called after do_signal where tracer might have changed callee regs
- * thus we need to restore the reg file.
- * Special case handling is required for r25 in case it is used by kernel
- *  for caching task ptr. Ptrace would have modified on-kernel-stack value of
- *  r25, which needs to be shoved back into task->thread.user_r25 where from
- *  Low level exception/ISR return code will retrieve to populate with rest of
- *  callee reg-file.
+ * Opposite of SAVE_CALLEE_SAVED_USER
+ *
+ * ptrace tracer or unaligned-access fixup might have changed a user mode
+ * callee reg which is saved back to usual r25 storage location
  *-------------------------------------------------------------*/
 .macro RESTORE_CALLEE_SAVED_USER
 
-	add     sp, sp, 4   /* skip "callee_regs->stack_place_holder" */
-
 #ifdef CONFIG_ARC_CURR_IN_REG
 	ld.ab   r12, [sp, 4]
-	st      r12, [r25, TASK_THREAD + THREAD_USER_R25]
+	st.as   r12, [sp, OFF_USER_R25_FROM_R24]
 #else
-	ld.ab   r25, [sp, 4]
+	POP	r25
 #endif
-
-	ld.ab   r24, [sp, 4]
-	ld.ab   r23, [sp, 4]
-	ld.ab   r22, [sp, 4]
-	ld.ab   r21, [sp, 4]
-	ld.ab   r20, [sp, 4]
-	ld.ab   r19, [sp, 4]
-	ld.ab   r18, [sp, 4]
-	ld.ab   r17, [sp, 4]
-	ld.ab   r16, [sp, 4]
-	ld.ab   r15, [sp, 4]
-	ld.ab   r14, [sp, 4]
-	ld.ab   r13, [sp, 4]
+	RESTORE_R24_TO_R13
 .endm
 
 /*--------------------------------------------------------------
  * Super FAST Restore callee saved regs by simply re-adjusting SP
  *-------------------------------------------------------------*/
 .macro DISCARD_CALLEE_SAVED_USER
-	add     sp, sp, 14 * 4
-.endm
-
-/*--------------------------------------------------------------
- * Restore User mode r25 saved in task_struct->thread.user_r25
- *-------------------------------------------------------------*/
-.macro RESTORE_USER_R25
-	ld  r25, [r25, TASK_THREAD + THREAD_USER_R25]
+	add     sp, sp, SZ_CALLEE_REGS
 .endm
 
 /*-------------------------------------------------------------
@@ -252,7 +236,7 @@
 	ld  \out, [\tsk, TASK_THREAD_INFO]
 
 	/* Go to end of page where stack begins (grows upwards) */
-	add2 \out, \out, (THREAD_SIZE - 4)/4   /* one word GUTTER */
+	add2 \out, \out, (THREAD_SIZE)/4
 
 .endm
 
@@ -305,33 +289,28 @@
 	 * safe-keeping not really needed, but it keeps the epilogue code
 	 * (SP restore) simpler/uniform.
 	 */
-	b.d	77f
-
-	st.a	sp, [sp, -12]	; Make room for orig_r0 and orig_r8
+	b.d	66f
+	mov	r9, sp
 
 88: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */
 
 	GET_CURR_TASK_ON_CPU   r9
 
-#ifdef CONFIG_ARC_CURR_IN_REG
-
-	/* If current task pointer cached in r25, time to
-	 *  -safekeep USER r25 in task->thread_struct->user_r25
-	 *  -load r25 with current task ptr
-	 */
-	st.as	r25, [r9, (TASK_THREAD + THREAD_USER_R25)/4]
-	mov	r25, r9
-#endif
-
 	/* With current tsk in r9, get it's kernel mode stack base */
 	GET_TSK_STACK_BASE  r9, r9
 
-#ifdef PT_REGS_CANARY
-	st	0xabcdabcd, [r9, 0]
+66:
+#ifdef CONFIG_ARC_CURR_IN_REG
+	/*
+	 * Treat r25 as scratch reg, save it on stack first
+	 * Load it with current task pointer
+	 */
+	st	r25, [r9, -4]
+	GET_CURR_TASK_ON_CPU   r25
 #endif
 
 	/* Save Pre Intr/Exception User SP on kernel stack */
-	st.a    sp, [r9, -12]	; Make room for orig_r0 and orig_r8
+	st.a    sp, [r9, -16]	; Make room for orig_r0, ECR, user_r25
 
 	/* CAUTION:
 	 * SP should be set at the very end when we are done with everything
@@ -342,7 +321,7 @@
 	/* set SP to point to kernel mode stack */
 	mov sp, r9
 
-77: /* ----- Stack Switched to kernel Mode, Now save REG FILE ----- */
+	/* ----- Stack Switched to kernel Mode, Now save REG FILE ----- */
 
 .endm
 
@@ -369,7 +348,7 @@
  * @reg [OUT] &thread_info of "current"
  */
 .macro GET_CURR_THR_INFO_FROM_SP  reg
-	and \reg, sp, ~(THREAD_SIZE - 1)
+	bic \reg, sp, (THREAD_SIZE - 1)
 .endm
 
 /*
@@ -413,62 +392,25 @@
  * Note that syscalls are implemented via TRAP which is also a exception
  * from CPU's point of view
  *-------------------------------------------------------------*/
-.macro SAVE_ALL_EXCEPTION   marker
+.macro SAVE_ALL_SYS
 
-	st      \marker, [sp, 8]	/* orig_r8 */
+	lr	r9, [ecr]
+	st      r9, [sp, 8]    /* ECR */
 	st      r0, [sp, 4]    /* orig_r0, needed only for sys calls */
 
 	/* Restore r9 used to code the early prologue */
 	EXCPN_PROLOG_RESTORE_REG  r9
 
-	SAVE_CALLER_SAVED
-	st.a    r26, [sp, -4]   /* gp */
-	st.a    fp, [sp, -4]
-	st.a    blink, [sp, -4]
-	lr	r9, [eret]
-	st.a    r9, [sp, -4]
-	lr	r9, [erstatus]
-	st.a    r9, [sp, -4]
-	st.a    lp_count, [sp, -4]
-	lr	r9, [lp_end]
-	st.a    r9, [sp, -4]
-	lr	r9, [lp_start]
-	st.a    r9, [sp, -4]
-	lr	r9, [erbta]
-	st.a    r9, [sp, -4]
-
-#ifdef PT_REGS_CANARY
-	mov   r9, 0xdeadbeef
-	st    r9, [sp, -4]
-#endif
-
-	/* move up by 1 word to "create" pt_regs->"stack_place_holder" */
-	sub sp, sp, 4
-.endm
-
-/*--------------------------------------------------------------
- * Save scratch regs for exceptions
- *-------------------------------------------------------------*/
-.macro SAVE_ALL_SYS
-	SAVE_ALL_EXCEPTION  orig_r8_IS_EXCPN
-.endm
-
-/*--------------------------------------------------------------
- * Save scratch regs for sys calls
- *-------------------------------------------------------------*/
-.macro SAVE_ALL_TRAP
-	/*
-	 * Setup pt_regs->orig_r8.
-	 * Encode syscall number (r8) in upper short word of event type (r9)
-	 * N.B. #1: This is already endian safe (see ptrace.h)
-	 *      #2: Only r9 can be used as scratch as it is already clobbered
-	 *          and it's contents are no longer needed by the latter part
-	 *          of exception prologue
-	 */
-	lsl  r9, r8, 16
-	or   r9, r9, orig_r8_IS_SCALL
-
-	SAVE_ALL_EXCEPTION  r9
+	SAVE_R0_TO_R12
+	PUSH	gp
+	PUSH	fp
+	PUSH	blink
+	PUSHAX	eret
+	PUSHAX	erstatus
+	PUSH	lp_count
+	PUSHAX	lp_end
+	PUSHAX	lp_start
+	PUSHAX	erbta
 .endm
 
 /*--------------------------------------------------------------
@@ -483,28 +425,22 @@
  * by hardware and that is not good.
  *-------------------------------------------------------------*/
 .macro RESTORE_ALL_SYS
+	POPAX	erbta
+	POPAX	lp_start
+	POPAX	lp_end
 
-	add sp, sp, 4       /* hop over unused "pt_regs->stack_place_holder" */
+	POP	r9
+	mov	lp_count, r9	;LD to lp_count is not allowed
 
-	ld.ab   r9, [sp, 4]
-	sr	r9, [erbta]
-	ld.ab   r9, [sp, 4]
-	sr	r9, [lp_start]
-	ld.ab   r9, [sp, 4]
-	sr	r9, [lp_end]
-	ld.ab   r9, [sp, 4]
-	mov	lp_count, r9
-	ld.ab   r9, [sp, 4]
-	sr	r9, [erstatus]
-	ld.ab   r9, [sp, 4]
-	sr	r9, [eret]
-	ld.ab   blink, [sp, 4]
-	ld.ab   fp, [sp, 4]
-	ld.ab   r26, [sp, 4]    /* gp */
-	RESTORE_CALLER_SAVED
+	POPAX	erstatus
+	POPAX	eret
+	POP	blink
+	POP	fp
+	POP	gp
+	RESTORE_R12_TO_R0
 
 	ld  sp, [sp] /* restore original sp */
-	/* orig_r0 and orig_r8 skipped automatically */
+	/* orig_r0, ECR, user_r25 skipped automatically */
 .endm
 
 
@@ -513,9 +449,7 @@
  *-------------------------------------------------------------*/
 .macro SAVE_ALL_INT1
 
-	/* restore original r9 , saved in int1_saved_reg
-	* It will be saved on stack in macro: SAVE_CALLER_SAVED
-	*/
+	/* restore original r9 to be saved as part of reg-file */
 #ifdef CONFIG_SMP
 	lr  r9, [ARC_REG_SCRATCH_DATA0]
 #else
@@ -523,29 +457,19 @@
 #endif
 
 	/* now we are ready to save the remaining context :) */
-	st      orig_r8_IS_IRQ1, [sp, 8]    /* Event Type */
+	st      event_IRQ1, [sp, 8]    /* Dummy ECR */
 	st      0, [sp, 4]    /* orig_r0 , N/A for IRQ */
-	SAVE_CALLER_SAVED
-	st.a    r26, [sp, -4]   /* gp */
-	st.a    fp, [sp, -4]
-	st.a    blink, [sp, -4]
-	st.a    ilink1, [sp, -4]
-	lr	r9, [status32_l1]
-	st.a    r9, [sp, -4]
-	st.a    lp_count, [sp, -4]
-	lr	r9, [lp_end]
-	st.a    r9, [sp, -4]
-	lr	r9, [lp_start]
-	st.a    r9, [sp, -4]
-	lr	r9, [bta_l1]
-	st.a    r9, [sp, -4]
 
-#ifdef PT_REGS_CANARY
-	mov   r9, 0xdeadbee1
-	st    r9, [sp, -4]
-#endif
-	/* move up by 1 word to "create" pt_regs->"stack_place_holder" */
-	sub sp, sp, 4
+	SAVE_R0_TO_R12
+	PUSH	gp
+	PUSH	fp
+	PUSH	blink
+	PUSH	ilink1
+	PUSHAX	status32_l1
+	PUSH	lp_count
+	PUSHAX	lp_end
+	PUSHAX	lp_start
+	PUSHAX	bta_l1
 .endm
 
 .macro SAVE_ALL_INT2
@@ -558,30 +482,19 @@
 	ld  r9, [@int2_saved_reg]
 
 	/* now we are ready to save the remaining context :) */
-	st      orig_r8_IS_IRQ2, [sp, 8]    /* Event Type */
+	st      event_IRQ2, [sp, 8]    /* Dummy ECR */
 	st      0, [sp, 4]    /* orig_r0 , N/A for IRQ */
-	SAVE_CALLER_SAVED
-	st.a    r26, [sp, -4]   /* gp */
-	st.a    fp, [sp, -4]
-	st.a    blink, [sp, -4]
-	st.a    ilink2, [sp, -4]
-	lr	r9, [status32_l2]
-	st.a    r9, [sp, -4]
-	st.a    lp_count, [sp, -4]
-	lr	r9, [lp_end]
-	st.a    r9, [sp, -4]
-	lr	r9, [lp_start]
-	st.a    r9, [sp, -4]
-	lr	r9, [bta_l2]
-	st.a    r9, [sp, -4]
 
-#ifdef PT_REGS_CANARY
-	mov   r9, 0xdeadbee2
-	st    r9, [sp, -4]
-#endif
-
-	/* move up by 1 word to "create" pt_regs->"stack_place_holder" */
-	sub sp, sp, 4
+	SAVE_R0_TO_R12
+	PUSH	gp
+	PUSH	fp
+	PUSH	blink
+	PUSH	ilink2
+	PUSHAX	status32_l2
+	PUSH	lp_count
+	PUSHAX	lp_end
+	PUSHAX	lp_start
+	PUSHAX	bta_l2
 .endm
 
 /*--------------------------------------------------------------
@@ -595,52 +508,41 @@
  *-------------------------------------------------------------*/
 
 .macro RESTORE_ALL_INT1
-	add sp, sp, 4       /* hop over unused "pt_regs->stack_place_holder" */
+	POPAX	bta_l1
+	POPAX	lp_start
+	POPAX	lp_end
 
-	ld.ab   r9, [sp, 4] /* Actual reg file */
-	sr	r9, [bta_l1]
-	ld.ab   r9, [sp, 4]
-	sr	r9, [lp_start]
-	ld.ab   r9, [sp, 4]
-	sr	r9, [lp_end]
-	ld.ab   r9, [sp, 4]
-	mov	lp_count, r9
-	ld.ab   r9, [sp, 4]
-	sr	r9, [status32_l1]
-	ld.ab   r9, [sp, 4]
-	mov	ilink1, r9
-	ld.ab   blink, [sp, 4]
-	ld.ab   fp, [sp, 4]
-	ld.ab   r26, [sp, 4]    /* gp */
-	RESTORE_CALLER_SAVED
+	POP	r9
+	mov	lp_count, r9	;LD to lp_count is not allowed
+
+	POPAX	status32_l1
+	POP	ilink1
+	POP	blink
+	POP	fp
+	POP	gp
+	RESTORE_R12_TO_R0
 
 	ld  sp, [sp] /* restore original sp */
-	/* orig_r0 and orig_r8 skipped automatically */
+	/* orig_r0, ECR, user_r25 skipped automatically */
 .endm
 
 .macro RESTORE_ALL_INT2
-	add sp, sp, 4       /* hop over unused "pt_regs->stack_place_holder" */
+	POPAX	bta_l2
+	POPAX	lp_start
+	POPAX	lp_end
 
-	ld.ab   r9, [sp, 4]
-	sr	r9, [bta_l2]
-	ld.ab   r9, [sp, 4]
-	sr	r9, [lp_start]
-	ld.ab   r9, [sp, 4]
-	sr	r9, [lp_end]
-	ld.ab   r9, [sp, 4]
-	mov	lp_count, r9
-	ld.ab   r9, [sp, 4]
-	sr	r9, [status32_l2]
-	ld.ab   r9, [sp, 4]
-	mov	ilink2, r9
-	ld.ab   blink, [sp, 4]
-	ld.ab   fp, [sp, 4]
-	ld.ab   r26, [sp, 4]    /* gp */
-	RESTORE_CALLER_SAVED
+	POP	r9
+	mov	lp_count, r9	;LD to lp_count is not allowed
 
-	ld  sp, [sp] /* restore original sp */
-	/* orig_r0 and orig_r8 skipped automatically */
+	POPAX	status32_l2
+	POP	ilink2
+	POP	blink
+	POP	fp
+	POP	gp
+	RESTORE_R12_TO_R0
 
+	ld  sp, [sp] /* restore original sp */
+	/* orig_r0, ECR, user_r25 skipped automatically */
 .endm
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/irqflags.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/irqflags.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/irqflags.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/irqflags.h	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,26 @@
 
 #include <asm/arcregs.h>
 
+/* status32 Reg bits related to Interrupt Handling */
+#define STATUS_E1_BIT		1	/* Int 1 enable */
+#define STATUS_E2_BIT		2	/* Int 2 enable */
+#define STATUS_A1_BIT		3	/* Int 1 active */
+#define STATUS_A2_BIT		4	/* Int 2 active */
+
+#define STATUS_E1_MASK		(1<<STATUS_E1_BIT)
+#define STATUS_E2_MASK		(1<<STATUS_E2_BIT)
+#define STATUS_A1_MASK		(1<<STATUS_A1_BIT)
+#define STATUS_A2_MASK		(1<<STATUS_A2_BIT)
+
+/* Other Interrupt Handling related Aux regs */
+#define AUX_IRQ_LEV		0x200	/* IRQ Priority: L1 or L2 */
+#define AUX_IRQ_HINT		0x201	/* For generating Soft Interrupts */
+#define AUX_IRQ_LV12		0x43	/* interrupt level register */
+
+#define AUX_IENABLE		0x40c
+#define AUX_ITRIGGER		0x40d
+#define AUX_IPULSE		0x415
+
 #ifndef __ASSEMBLY__
 
 /******************************************************************
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/irq.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/irq.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/irq.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/irq.h	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,6 @@
 extern void __init arc_init_IRQ(void);
 extern int __init get_hw_config_num_irq(void);
 
-void __cpuinit arc_local_timer_setup(unsigned int cpu);
+void arc_local_timer_setup(unsigned int cpu);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/kgdb.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/kgdb.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/kgdb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/kgdb.h	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,7 @@ static inline void arch_kgdb_breakpoint(
 	__asm__ __volatile__ ("trap_s	0x4\n");
 }
 
-extern void kgdb_trap(struct pt_regs *regs, int param);
+extern void kgdb_trap(struct pt_regs *regs);
 
 enum arc700_linux_regnums {
 	_R0		= 0,
@@ -53,7 +53,7 @@ enum arc700_linux_regnums {
 };
 
 #else
-#define kgdb_trap(regs, param)
+#define kgdb_trap(regs)
 #endif
 
 #endif	/* __ARC_KGDB_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/kprobes.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/kprobes.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/kprobes.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/kprobes.h	2013-08-25 20:43:22.000000000 -0400
@@ -50,11 +50,9 @@ struct kprobe_ctlblk {
 
 int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause);
 void kretprobe_trampoline(void);
-void trap_is_kprobe(unsigned long cause, unsigned long address,
-			   struct pt_regs *regs);
+void trap_is_kprobe(unsigned long address, struct pt_regs *regs);
 #else
-static void trap_is_kprobe(unsigned long cause, unsigned long address,
-			   struct pt_regs *regs)
+static void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
 {
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/mmu.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/mmu.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/mmu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/mmu.h	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,40 @@
 #ifndef _ASM_ARC_MMU_H
 #define _ASM_ARC_MMU_H
 
+#if defined(CONFIG_ARC_MMU_V1)
+#define CONFIG_ARC_MMU_VER 1
+#elif defined(CONFIG_ARC_MMU_V2)
+#define CONFIG_ARC_MMU_VER 2
+#elif defined(CONFIG_ARC_MMU_V3)
+#define CONFIG_ARC_MMU_VER 3
+#endif
+
+/* MMU Management regs */
+#define ARC_REG_MMU_BCR		0x06f
+#define ARC_REG_TLBPD0		0x405
+#define ARC_REG_TLBPD1		0x406
+#define ARC_REG_TLBINDEX	0x407
+#define ARC_REG_TLBCOMMAND	0x408
+#define ARC_REG_PID		0x409
+#define ARC_REG_SCRATCH_DATA0	0x418
+
+/* Bits in MMU PID register */
+#define MMU_ENABLE		(1 << 31)	/* Enable MMU for process */
+
+/* Error code if probe fails */
+#define TLB_LKUP_ERR		0x80000000
+
+/* TLB Commands */
+#define TLBWrite    0x1
+#define TLBRead     0x2
+#define TLBGetIndex 0x3
+#define TLBProbe    0x4
+
+#if (CONFIG_ARC_MMU_VER >= 2)
+#define TLBWriteNI  0x5		/* write JTLB without inv uTLBs */
+#define TLBIVUTLB   0x6		/* explicitly inv uTLBs */
+#endif
+
 #ifndef __ASSEMBLY__
 
 typedef struct {
@@ -18,6 +52,16 @@ typedef struct {
 #endif
 } mm_context_t;
 
+#ifdef CONFIG_ARC_DBG_TLB_PARANOIA
+void tlb_paranoid_check(unsigned int pid_sw, unsigned long address);
+#else
+#define tlb_paranoid_check(a, b)
 #endif
 
+void arc_mmu_init(void);
+extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
+void __init read_decode_mmu_bcr(void);
+
+#endif	/* !__ASSEMBLY__ */
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/page.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/page.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/page.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/page.h	2013-08-25 20:43:22.000000000 -0400
@@ -96,13 +96,8 @@ typedef unsigned long pgtable_t;
 
 #define virt_addr_valid(kaddr)  pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-/* Default Permissions for page, used in mmap.c */
-#ifdef CONFIG_ARC_STACK_NONEXEC
+/* Default Permissions for stack/heaps pages (Non Executable) */
 #define VM_DATA_DEFAULT_FLAGS   (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE)
-#else
-#define VM_DATA_DEFAULT_FLAGS   (VM_READ | VM_WRITE | VM_EXEC | \
-				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-#endif
 
 #define WANT_PAGE_VIRTUAL   1
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -135,6 +135,12 @@
 /* ioremap */
 #define PAGE_KERNEL_NO_CACHE __pgprot(_K_PAGE_PERMS)
 
+/* Masks for actual TLB "PD"s */
+#define PTE_BITS_IN_PD0	(_PAGE_GLOBAL | _PAGE_PRESENT)
+#define PTE_BITS_IN_PD1	(PAGE_MASK | _PAGE_CACHEABLE | \
+			 _PAGE_U_EXECUTE | _PAGE_U_WRITE | _PAGE_U_READ | \
+			 _PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ)
+
 /**************************************************************************
  * Mapping of vm_flags (Generic VM) to PTE flags (arch specific)
  *
@@ -394,9 +400,6 @@ void update_mmu_cache(struct vm_area_str
  * remap a physical page `pfn' of size `size' with page protection `prot'
  * into virtual address `from'
  */
-#define io_remap_pfn_range(vma, from, pfn, size, prot) \
-			remap_pfn_range(vma, from, pfn, size, prot)
-
 #include <asm-generic/pgtable.h>
 
 /* to cope with aliasing VIPT cache */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/processor.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/processor.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/processor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/processor.h	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,7 @@
 #ifndef __ASSEMBLY__
 
 #include <asm/arcregs.h>	/* for STATUS_E1_MASK et all */
+#include <asm/ptrace.h>
 
 /* Arch specific stuff which needs to be saved per task.
  * However these items are not so important so as to earn a place in
@@ -28,10 +29,6 @@ struct thread_struct {
 	unsigned long ksp;	/* kernel mode stack pointer */
 	unsigned long callee_reg;	/* pointer to callee regs */
 	unsigned long fault_address;	/* dbls as brkpt holder as well */
-	unsigned long cause_code;	/* Exception Cause Code (ECR) */
-#ifdef CONFIG_ARC_CURR_IN_REG
-	unsigned long user_r25;
-#endif
 #ifdef CONFIG_ARC_FPU_SAVE_RESTORE
 	struct arc_fpu fpu;
 #endif
@@ -50,7 +47,7 @@ struct task_struct;
 unsigned long thread_saved_pc(struct task_struct *t);
 
 #define task_pt_regs(p) \
-	((struct pt_regs *)(THREAD_SIZE - 4 + (void *)task_stack_page(p)) - 1)
+	((struct pt_regs *)(THREAD_SIZE + (void *)task_stack_page(p)) - 1)
 
 /* Free all resources held by a thread. */
 #define release_thread(thread) do { } while (0)
@@ -75,11 +72,15 @@ unsigned long thread_saved_pc(struct tas
 
 /*
  * Where abouts of Task's sp, fp, blink when it was last seen in kernel mode.
- * These can't be derived from pt_regs as that would give correp user-mode val
+ * Look in process.c for details of kernel stack layout
  */
 #define KSTK_ESP(tsk)   (tsk->thread.ksp)
-#define KSTK_BLINK(tsk) (*((unsigned int *)((KSTK_ESP(tsk)) + (13+1+1)*4)))
-#define KSTK_FP(tsk)    (*((unsigned int *)((KSTK_ESP(tsk)) + (13+1)*4)))
+
+#define KSTK_REG(tsk, off)	(*((unsigned int *)(KSTK_ESP(tsk) + \
+					sizeof(struct callee_regs) + off)))
+
+#define KSTK_BLINK(tsk) KSTK_REG(tsk, 4)
+#define KSTK_FP(tsk)    KSTK_REG(tsk, 0)
 
 /*
  * Do necessary setup to start up a newly executed thread.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/ptrace.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/ptrace.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/ptrace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/ptrace.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,12 +17,6 @@
 /* THE pt_regs: Defines how regs are saved during entry into kernel */
 
 struct pt_regs {
-	/*
-	 * 1 word gutter after reg-file has been saved
-	 * Technically not needed, Since SP always points to a "full" location
-	 * (vs. "empty"). But pt_regs is shared with tools....
-	 */
-	long res;
 
 	/* Real registers */
 	long bta;	/* bta_l1, bta_l2, erbta */
@@ -50,22 +44,32 @@ struct pt_regs {
 	long sp;	/* user/kernel sp depending on where we came from  */
 	long orig_r0;
 
-	/*to distinguish bet excp, syscall, irq */
+	/*
+	 * To distinguish bet excp, syscall, irq
+	 * For traps and exceptions, Exception Cause Register.
+	 * 	ECR: <00> <VV> <CC> <PP>
+	 * 	Last word used by Linux for extra state mgmt (syscall-restart)
+	 * For interrupts, use artificial ECR values to note current prio-level
+	 */
 	union {
+		struct {
 #ifdef CONFIG_CPU_BIG_ENDIAN
-		/* so that assembly code is same for LE/BE */
-		unsigned long orig_r8:16, event:16;
+			unsigned long state:8, ecr_vec:8,
+				      ecr_cause:8, ecr_param:8;
 #else
-		unsigned long event:16, orig_r8:16;
+			unsigned long ecr_param:8, ecr_cause:8,
+				      ecr_vec:8, state:8;
 #endif
-		long orig_r8_word;
+		};
+		unsigned long event;
 	};
+
+	long user_r25;
 };
 
 /* Callee saved registers - need to be saved only when you are scheduled out */
 
 struct callee_regs {
-	long res;	/* Again this is not needed */
 	long r25;
 	long r24;
 	long r23;
@@ -99,18 +103,20 @@ struct callee_regs {
 /* return 1 if PC in delay slot */
 #define delay_mode(regs) ((regs->status32 & STATUS_DE_MASK) == STATUS_DE_MASK)
 
-#define in_syscall(regs)    (regs->event & orig_r8_IS_SCALL)
-#define in_brkpt_trap(regs) (regs->event & orig_r8_IS_BRKPT)
+#define in_syscall(regs)    ((regs->ecr_vec == ECR_V_TRAP) && !regs->ecr_param)
+#define in_brkpt_trap(regs) ((regs->ecr_vec == ECR_V_TRAP) && regs->ecr_param)
 
-#define syscall_wont_restart(regs) (regs->event |= orig_r8_IS_SCALL_RESTARTED)
-#define syscall_restartable(regs) !(regs->event &  orig_r8_IS_SCALL_RESTARTED)
+#define STATE_SCALL_RESTARTED	0x01
+
+#define syscall_wont_restart(reg) (reg->state |= STATE_SCALL_RESTARTED)
+#define syscall_restartable(reg) !(reg->state &  STATE_SCALL_RESTARTED)
 
 #define current_pt_regs()					\
 ({								\
 	/* open-coded current_thread_info() */			\
 	register unsigned long sp asm ("sp");			\
 	unsigned long pg_start = (sp & ~(THREAD_SIZE - 1));	\
-	(struct pt_regs *)(pg_start + THREAD_SIZE - 4) - 1;	\
+	(struct pt_regs *)(pg_start + THREAD_SIZE) - 1;	\
 })
 
 static inline long regs_return_value(struct pt_regs *regs)
@@ -120,11 +126,4 @@ static inline long regs_return_value(str
 
 #endif /* !__ASSEMBLY__ */
 
-#define orig_r8_IS_SCALL		0x0001
-#define orig_r8_IS_SCALL_RESTARTED	0x0002
-#define orig_r8_IS_BRKPT		0x0004
-#define orig_r8_IS_EXCPN		0x0008
-#define orig_r8_IS_IRQ1			0x0010
-#define orig_r8_IS_IRQ2			0x0020
-
 #endif /* __ASM_PTRACE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/syscall.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/syscall.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/syscall.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/syscall.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,7 @@ static inline long
 syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
 {
 	if (user_mode(regs) && in_syscall(regs))
-		return regs->orig_r8;
+		return regs->r8;
 	else
 		return -1;
 }
@@ -26,8 +26,7 @@ syscall_get_nr(struct task_struct *task,
 static inline void
 syscall_rollback(struct task_struct *task, struct pt_regs *regs)
 {
-	/* XXX: I can't fathom how pt_regs->r8 will be clobbered ? */
-	regs->r8 = regs->orig_r8;
+	regs->r0 = regs->orig_r0;
 }
 
 static inline long
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/tlb.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/tlb.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/tlb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/tlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -9,18 +9,6 @@
 #ifndef _ASM_ARC_TLB_H
 #define _ASM_ARC_TLB_H
 
-#ifdef __KERNEL__
-
-#include <asm/pgtable.h>
-
-/* Masks for actual TLB "PD"s */
-#define PTE_BITS_IN_PD0	(_PAGE_GLOBAL | _PAGE_PRESENT)
-#define PTE_BITS_IN_PD1	(PAGE_MASK | _PAGE_CACHEABLE | \
-			 _PAGE_U_EXECUTE | _PAGE_U_WRITE | _PAGE_U_READ | \
-			 _PAGE_K_EXECUTE | _PAGE_K_WRITE | _PAGE_K_READ)
-
-#ifndef __ASSEMBLY__
-
 #define tlb_flush(tlb)				\
 do {						\
 	if (tlb->fullmm)			\
@@ -56,18 +44,4 @@ do {									\
 #include <linux/pagemap.h>
 #include <asm-generic/tlb.h>
 
-#ifdef CONFIG_ARC_DBG_TLB_PARANOIA
-void tlb_paranoid_check(unsigned int pid_sw, unsigned long address);
-#else
-#define tlb_paranoid_check(a, b)
-#endif
-
-void arc_mmu_init(void);
-extern char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len);
-void __init read_decode_mmu_bcr(void);
-
-#endif	/* __ASSEMBLY__ */
-
-#endif	/* __KERNEL__ */
-
 #endif /* _ASM_ARC_TLB_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/tlb-mmu1.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/tlb-mmu1.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/tlb-mmu1.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/tlb-mmu1.h	2013-08-25 20:43:22.000000000 -0400
@@ -9,9 +9,9 @@
 #ifndef __ASM_TLB_MMU_V1_H__
 #define __ASM_TLB_MMU_V1_H__
 
-#if defined(__ASSEMBLY__) && defined(CONFIG_ARC_MMU_VER == 1)
+#include <asm/mmu.h>
 
-#include <asm/tlb.h>
+#if defined(__ASSEMBLY__) && (CONFIG_ARC_MMU_VER == 1)
 
 .macro TLB_WRITE_HEURISTICS
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/asm/unaligned.h linux-libre-3.11-rc7-gnu/arch/arc/include/asm/unaligned.h
--- linux-libre-3.10-gnu/arch/arc/include/asm/unaligned.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/asm/unaligned.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,11 @@
 
 #ifdef CONFIG_ARC_MISALIGN_ACCESS
 int misaligned_fixup(unsigned long address, struct pt_regs *regs,
-		     unsigned long cause, struct callee_regs *cregs);
+		     struct callee_regs *cregs);
 #else
 static inline int
 misaligned_fixup(unsigned long address, struct pt_regs *regs,
-		 unsigned long cause, struct callee_regs *cregs)
+		 struct callee_regs *cregs)
 {
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/include/uapi/asm/ptrace.h linux-libre-3.11-rc7-gnu/arch/arc/include/uapi/asm/ptrace.h
--- linux-libre-3.10-gnu/arch/arc/include/uapi/asm/ptrace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/include/uapi/asm/ptrace.h	2013-08-25 20:43:22.000000000 -0400
@@ -20,28 +20,31 @@
  *
  * This is to decouple pt_regs from user-space ABI, to be able to change it
  * w/o affecting the ABI.
- * Although the layout (initial padding) is similar to pt_regs to have some
- * optimizations when copying pt_regs to/from user_regs_struct.
+ *
+ * The intermediate pad,pad2 are relics of initial layout based on pt_regs
+ * for optimizations when copying pt_regs to/from user_regs_struct.
+ * We no longer need them, but can't be changed as they are part of ABI now.
  *
  * Also, sigcontext only care about the scratch regs as that is what we really
- * save/restore for signal handling.
+ * save/restore for signal handling. However gdb also uses the same struct
+ * hence callee regs need to be in there too.
 */
 struct user_regs_struct {
 
+	long pad;
 	struct {
-		long pad;
 		long bta, lp_start, lp_end, lp_count;
 		long status32, ret, blink, fp, gp;
 		long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0;
 		long sp;
 	} scratch;
+	long pad2;
 	struct {
-		long pad;
 		long r25, r24, r23, r22, r21, r20;
 		long r19, r18, r17, r16, r15, r14, r13;
 	} callee;
 	long efa;	/* break pt addr, for break points in delay slots */
-	long stop_pc;	/* give dbg stop_pc directly after checking orig_r8 */
+	long stop_pc;	/* give dbg stop_pc after ensuring brkpt trap */
 };
 #endif /* !__ASSEMBLY__ */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/Kconfig linux-libre-3.11-rc7-gnu/arch/arc/Kconfig
--- linux-libre-3.10-gnu/arch/arc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -34,6 +34,7 @@ config ARC
 	select OF
 	select OF_EARLY_FLATTREE
 	select PERF_USE_VMALLOC
+	select HAVE_DEBUG_STACKOVERFLOW
 
 config SCHED_OMIT_FRAME_POINTER
 	def_bool y
@@ -184,6 +185,7 @@ config ARC_CACHE_PAGES
 
 config ARC_CACHE_VIPT_ALIASING
 	bool "Support VIPT Aliasing D$"
+	depends on ARC_HAS_DCACHE
 	default n
 
 endif	#ARC_CACHE
@@ -361,13 +363,6 @@ config ARC_MISALIGN_ACCESS
 	  Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide
 	  potential bugs in code
 
-config ARC_STACK_NONEXEC
-	bool "Make stack non-executable"
-	default n
-	help
-	  To disable the execute permissions of stack/heap of processes
-	  which are enabled by default.
-
 config HZ
 	int "Timer Frequency"
 	default 100
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/arc/Kconfig.debug
--- linux-libre-3.10-gnu/arch/arc/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -15,13 +15,6 @@ config EARLY_PRINTK
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash.
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-	help
-	  This option will cause messages to be printed if free stack space
-	  drops below a certain limit.
-
 config 16KSTACKS
 	bool "Use 16Kb for kernel stacks instead of 8Kb"
 	help
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/asm-offsets.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/asm-offsets.c
--- linux-libre-3.10-gnu/arch/arc/kernel/asm-offsets.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/asm-offsets.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,9 +24,6 @@ int main(void)
 
 	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
 	DEFINE(THREAD_CALLEE_REG, offsetof(struct thread_struct, callee_reg));
-#ifdef CONFIG_ARC_CURR_IN_REG
-	DEFINE(THREAD_USER_R25, offsetof(struct thread_struct, user_r25));
-#endif
 	DEFINE(THREAD_FAULT_ADDR,
 	       offsetof(struct thread_struct, fault_address));
 
@@ -49,7 +46,7 @@ int main(void)
 	BLANK();
 
 	DEFINE(PT_status32, offsetof(struct pt_regs, status32));
-	DEFINE(PT_orig_r8, offsetof(struct pt_regs, orig_r8_word));
+	DEFINE(PT_event, offsetof(struct pt_regs, event));
 	DEFINE(PT_sp, offsetof(struct pt_regs, sp));
 	DEFINE(PT_r0, offsetof(struct pt_regs, r0));
 	DEFINE(PT_r1, offsetof(struct pt_regs, r1));
@@ -60,5 +57,7 @@ int main(void)
 	DEFINE(PT_r6, offsetof(struct pt_regs, r6));
 	DEFINE(PT_r7, offsetof(struct pt_regs, r7));
 
+	DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs));
+	DEFINE(SZ_PT_REGS, sizeof(struct pt_regs));
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/ctx_sw.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/ctx_sw.c
--- linux-libre-3.10-gnu/arch/arc/kernel/ctx_sw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/ctx_sw.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,10 +23,6 @@ __switch_to(struct task_struct *prev_tas
 	unsigned int tmp;
 	unsigned int prev = (unsigned int)prev_task;
 	unsigned int next = (unsigned int)next_task;
-	int num_words_to_skip = 1;
-#ifdef CONFIG_ARC_CURR_IN_REG
-	num_words_to_skip++;
-#endif
 
 	__asm__ __volatile__(
 		/* FP/BLINK save generated by gcc (standard function prologue */
@@ -44,8 +40,9 @@ __switch_to(struct task_struct *prev_tas
 		"st.a    r24, [sp, -4]   \n\t"
 #ifndef CONFIG_ARC_CURR_IN_REG
 		"st.a    r25, [sp, -4]   \n\t"
+#else
+		"sub     sp, sp, 4      \n\t"	/* usual r25 placeholder */
 #endif
-		"sub     sp, sp, %4      \n\t"	/* create gutter at top */
 
 		/* set ksp of outgoing task in tsk->thread.ksp */
 		"st.as   sp, [%3, %1]    \n\t"
@@ -76,10 +73,10 @@ __switch_to(struct task_struct *prev_tas
 
 		/* start loading it's CALLEE reg file */
 
-		"add    sp, sp, %4     \n\t"	/* skip gutter at top */
-
 #ifndef CONFIG_ARC_CURR_IN_REG
 		"ld.ab   r25, [sp, 4]   \n\t"
+#else
+		"add    sp, sp, 4       \n\t"
 #endif
 		"ld.ab   r24, [sp, 4]   \n\t"
 		"ld.ab   r23, [sp, 4]   \n\t"
@@ -100,8 +97,7 @@ __switch_to(struct task_struct *prev_tas
 		/* FP/BLINK restore generated by gcc (standard func epilogue */
 
 		: "=r"(tmp)
-		: "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev),
-		  "n"(num_words_to_skip * 4)
+		: "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev)
 		: "blink"
 	);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/entry.S linux-libre-3.11-rc7-gnu/arch/arc/kernel/entry.S
--- linux-libre-3.10-gnu/arch/arc/kernel/entry.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/entry.S	2013-08-25 20:43:22.000000000 -0400
@@ -142,7 +142,7 @@ VECTOR   reserved                ; Reser
 .endr
 
 #include <linux/linkage.h>   /* ARC_{EXTRY,EXIT} */
-#include <asm/entry.h>       /* SAVE_ALL_{INT1,INT2,TRAP...} */
+#include <asm/entry.h>       /* SAVE_ALL_{INT1,INT2,SYS...} */
 #include <asm/errno.h>
 #include <asm/arcregs.h>
 #include <asm/irqflags.h>
@@ -274,10 +274,8 @@ ARC_ENTRY instr_service
 	SWITCH_TO_KERNEL_STK
 	SAVE_ALL_SYS
 
-	lr  r0, [ecr]
-	lr  r1, [efa]
-
-	mov r2, sp
+	lr  r0, [efa]
+	mov r1, sp
 
 	FAKE_RET_FROM_EXCPN r9
 
@@ -298,9 +296,8 @@ ARC_ENTRY mem_service
 	SWITCH_TO_KERNEL_STK
 	SAVE_ALL_SYS
 
-	lr  r0, [ecr]
-	lr  r1, [efa]
-	mov r2, sp
+	lr  r0, [efa]
+	mov r1, sp
 	bl  do_memory_error
 	b   ret_from_exception
 ARC_EXIT mem_service
@@ -317,11 +314,14 @@ ARC_ENTRY EV_MachineCheck
 	SWITCH_TO_KERNEL_STK
 	SAVE_ALL_SYS
 
-	lr  r0, [ecr]
-	lr  r1, [efa]
-	mov r2, sp
+	lr  r2, [ecr]
+	lr  r0, [efa]
+	mov r1, sp
+
+	lsr  	r3, r2, 8
+	bmsk 	r3, r3, 7
+	brne    r3, ECR_C_MCHK_DUP_TLB, 1f
 
-	brne    r0, 0x200100, 1f
 	bl      do_tlb_overlap_fault
 	b       ret_from_exception
 
@@ -355,8 +355,8 @@ ARC_ENTRY EV_TLBProtV
 	;  ecr and efa were not saved in case an Intr sneaks in
 	;  after fake rtie
 	;
-	lr  r3, [ecr]
-	lr  r4, [efa]
+	lr  r2, [ecr]
+	lr  r1, [efa]	; Faulting Data address
 
 	; --------(4) Return from CPU Exception Mode ---------
 	;  Fake a rtie, but rtie to next label
@@ -368,31 +368,25 @@ ARC_ENTRY EV_TLBProtV
 	;------ (5) Type of Protection Violation? ----------
 	;
 	; ProtV Hardware Exception is triggered for Access Faults of 2 types
-	;   -Access Violaton (WRITE to READ ONLY Page) - for linux COW
-	;   -Unaligned Access (READ/WRITE on odd boundary)
+	;   -Access Violaton	: 00_23_(00|01|02|03)_00
+	;			         x  r  w  r+w
+	;   -Unaligned Access	: 00_23_04_00
 	;
-	cmp r3, 0x230400    ; Misaligned data access ?
-	beq 4f
+	bbit1 r2, ECR_C_BIT_PROTV_MISALIG_DATA, 4f
 
 	;========= (6a) Access Violation Processing ========
-	cmp r3, 0x230100
-	mov r1, 0x0              ; if LD exception ? write = 0
-	mov.ne r1, 0x1           ; else write = 1
-
-	mov r2, r4              ; faulting address
 	mov r0, sp              ; pt_regs
 	bl  do_page_fault
 	b   ret_from_exception
 
 	;========== (6b) Non aligned access ============
 4:
-	mov r0, r3              ; cause code
-	mov r1, r4              ; faulting address
-	mov r2, sp              ; pt_regs
+	mov r0, r1
+	mov r1, sp              ; pt_regs
 
 #ifdef  CONFIG_ARC_MISALIGN_ACCESS
 	SAVE_CALLEE_SAVED_USER
-	mov r3, sp              ; callee_regs
+	mov r2, sp              ; callee_regs
 
 	bl  do_misaligned_access
 
@@ -419,9 +413,8 @@ ARC_ENTRY EV_PrivilegeV
 	SWITCH_TO_KERNEL_STK
 	SAVE_ALL_SYS
 
-	lr  r0, [ecr]
-	lr  r1, [efa]
-	mov r2, sp
+	lr  r0, [efa]
+	mov r1, sp
 
 	FAKE_RET_FROM_EXCPN r9
 
@@ -440,9 +433,8 @@ ARC_ENTRY EV_Extension
 	SWITCH_TO_KERNEL_STK
 	SAVE_ALL_SYS
 
-	lr  r0, [ecr]
-	lr  r1, [efa]
-	mov r2, sp
+	lr  r0, [efa]
+	mov r1, sp
 	bl  do_extension_fault
 	b   ret_from_exception
 ARC_EXIT EV_Extension
@@ -498,11 +490,8 @@ tracesys_exit:
 trap_with_param:
 
 	; stop_pc info by gdb needs this info
-	stw orig_r8_IS_BRKPT, [sp, PT_orig_r8]
-
-	mov r0, r12
-	lr  r1, [efa]
-	mov r2, sp
+	lr  r0, [efa]
+	mov r1, sp
 
 	; Now that we have read EFA, its safe to do "fake" rtie
 	;   and get out of CPU exception mode
@@ -544,11 +533,11 @@ ARC_ENTRY EV_Trap
 	lr  r9, [erstatus]
 
 	SWITCH_TO_KERNEL_STK
-	SAVE_ALL_TRAP
+	SAVE_ALL_SYS
 
 	;------- (4) What caused the Trap --------------
 	lr     r12, [ecr]
-	and.f  0, r12, ECR_PARAM_MASK
+	bmsk.f 0, r12, 7
 	bnz    trap_with_param
 
 	; ======= (5a) Trap is due to System Call ========
@@ -589,11 +578,7 @@ ARC_ENTRY ret_from_exception
 	; Pre-{IRQ,Trap,Exception} K/U mode from pt_regs->status32
 	ld  r8, [sp, PT_status32]   ; returning to User/Kernel Mode
 
-#ifdef CONFIG_PREEMPT
 	bbit0  r8, STATUS_U_BIT, resume_kernel_mode
-#else
-	bbit0  r8, STATUS_U_BIT, restore_regs
-#endif
 
 	; Before returning to User mode check-for-and-complete any pending work
 	; such as rescheduling/signal-delivery etc.
@@ -653,10 +638,10 @@ resume_user_mode_begin:
 	b      resume_user_mode_begin	; unconditionally back to U mode ret chks
 					; for single exit point from this block
 
-#ifdef CONFIG_PREEMPT
-
 resume_kernel_mode:
 
+#ifdef CONFIG_PREEMPT
+
 	; Can't preempt if preemption disabled
 	GET_CURR_THR_INFO_FROM_SP   r10
 	ld  r8, [r10, THREAD_INFO_PREEMPT_COUNT]
@@ -687,17 +672,6 @@ restore_regs :
 	; XXX can this be optimised out
 	IRQ_DISABLE_SAVE    r9, r10	;@r10 has prisitine (pre-disable) copy
 
-#ifdef CONFIG_ARC_CURR_IN_REG
-	; Restore User R25
-	; Earlier this used to be only for returning to user mode
-	; However with 2 levels of IRQ this can also happen even if
-	; in kernel mode
-	ld r9, [sp, PT_sp]
-	brhs r9, VMALLOC_START, 8f
-	RESTORE_USER_R25
-8:
-#endif
-
 	; Restore REG File. In case multiple Events outstanding,
 	; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None
 	; Note that we use realtime STATUS32 (not pt_regs->status32) to
@@ -714,28 +688,33 @@ not_exception:
 
 #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
 
+	; Level 2 interrupt return Path - from hardware standpoint
 	bbit0  r10, STATUS_A2_BIT, not_level2_interrupt
 
 	;------------------------------------------------------------------
+	; However the context returning might not have taken L2 intr itself
+	; e.g. Task'A' user-code -> L2 intr -> schedule -> 'B' user-code ret
+	; Special considerations needed for the context which took L2 intr
+
+	ld   r9, [sp, PT_event]        ; Ensure this is L2 intr context
+	brne r9, event_IRQ2, 149f
+
+	;------------------------------------------------------------------
 	; if L2 IRQ interrupted a L1 ISR,  we'd disbaled preemption earlier
 	; so that sched doesnt move to new task, causing L1 to be delayed
 	; undeterministically. Now that we've achieved that, lets reset
 	; things to what they were, before returning from L2 context
 	;----------------------------------------------------------------
 
-	ldw  r9, [sp, PT_orig_r8]      ; get orig_r8 to make sure it is
-	brne r9, orig_r8_IS_IRQ2, 149f ; infact a L2 ISR ret path
-
 	ld r9, [sp, PT_status32]       ; get statu32_l2 (saved in pt_regs)
 	bbit0 r9, STATUS_A1_BIT, 149f  ; L1 not active when L2 IRQ, so normal
 
-	; A1 is set in status32_l2
 	; decrement thread_info->preempt_count (re-enable preemption)
 	GET_CURR_THR_INFO_FROM_SP   r10
 	ld      r9, [r10, THREAD_INFO_PREEMPT_COUNT]
 
 	; paranoid check, given A1 was active when A2 happened, preempt count
-	; must not be 0 beccause we would have incremented it.
+	; must not be 0 because we would have incremented it.
 	; If this does happen we simply HALT as it means a BUG !!!
 	cmp     r9, 0
 	bnz     2f
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/head.S linux-libre-3.11-rc7-gnu/arch/arc/kernel/head.S
--- linux-libre-3.10-gnu/arch/arc/kernel/head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/head.S	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,8 @@ stext:
 	; Don't clobber r0-r4 yet. It might have bootloader provided info
 	;-------------------------------------------------------------------
 
+	sr	@_int_vec_base_lds, [AUX_INTR_VEC_BASE]
+
 #ifdef CONFIG_SMP
 	; Only Boot (Master) proceeds. Others wait in platform dependent way
 	;	IDENTITY Reg [ 3  2  1  0 ]
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/irq.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/irq.c
--- linux-libre-3.10-gnu/arch/arc/kernel/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,25 +28,17 @@
  * -Disable all IRQs (on CPU side)
  * -Optionally, setup the High priority Interrupts as Level 2 IRQs
  */
-void __cpuinit arc_init_IRQ(void)
+void arc_init_IRQ(void)
 {
 	int level_mask = 0;
 
-	write_aux_reg(AUX_INTR_VEC_BASE, _int_vec_base_lds);
-
 	/* Disable all IRQs: enable them as devices request */
 	write_aux_reg(AUX_IENABLE, 0);
 
        /* setup any high priority Interrupts (Level2 in ARCompact jargon) */
-#ifdef CONFIG_ARC_IRQ3_LV2
-	level_mask |= (1 << 3);
-#endif
-#ifdef CONFIG_ARC_IRQ5_LV2
-	level_mask |= (1 << 5);
-#endif
-#ifdef CONFIG_ARC_IRQ6_LV2
-	level_mask |= (1 << 6);
-#endif
+	level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3;
+	level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5;
+	level_mask |= IS_ENABLED(CONFIG_ARC_IRQ6_LV2) << 6;
 
 	if (level_mask) {
 		pr_info("Level-2 interrupts bitset %x\n", level_mask);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/kgdb.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/kgdb.c
--- linux-libre-3.10-gnu/arch/arc/kernel/kgdb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/kgdb.c	2013-08-25 20:43:22.000000000 -0400
@@ -169,7 +169,7 @@ int kgdb_arch_init(void)
 	return 0;
 }
 
-void kgdb_trap(struct pt_regs *regs, int param)
+void kgdb_trap(struct pt_regs *regs)
 {
 	/* trap_s 3 is used for breakpoints that overwrite existing
 	 * instructions, while trap_s 4 is used for compiled breakpoints.
@@ -181,7 +181,7 @@ void kgdb_trap(struct pt_regs *regs, int
 	 * with trap_s 4 (compiled) breakpoints, continuation needs to
 	 * start after the breakpoint.
 	 */
-	if (param == 3)
+	if (regs->ecr_param == 3)
 		instruction_pointer(regs) -= BREAK_INSTR_SIZE;
 
 	kgdb_handle_exception(1, SIGTRAP, 0, regs);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/kprobes.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/kprobes.c
--- linux-libre-3.10-gnu/arch/arc/kernel/kprobes.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/kprobes.c	2013-08-25 20:43:22.000000000 -0400
@@ -517,8 +517,7 @@ int __kprobes arch_trampoline_kprobe(str
 	return 0;
 }
 
-void trap_is_kprobe(unsigned long cause, unsigned long address,
-		    struct pt_regs *regs)
+void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
 {
-	notify_die(DIE_TRAP, "kprobe_trap", regs, address, cause, SIGTRAP);
+	notify_die(DIE_TRAP, "kprobe_trap", regs, address, 0, SIGTRAP);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/process.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/process.c
--- linux-libre-3.10-gnu/arch/arc/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,10 +55,8 @@ asmlinkage void ret_from_fork(void);
  * |     ...        |
  * |    unused      |
  * |                |
- * ------------------  <==== top of Stack (thread.ksp)
- * |   UNUSED 1 word|
  * ------------------
- * |     r25        |
+ * |     r25        |   <==== top of Stack (thread.ksp)
  * ~                ~
  * |    --to--      |   (CALLEE Regs of user mode)
  * |     r13        |
@@ -76,7 +74,10 @@ asmlinkage void ret_from_fork(void);
  * |    --to--      |   (scratch Regs of user mode)
  * |     r0         |
  * ------------------
- * |   UNUSED 1 word|
+ * |      SP        |
+ * |    orig_r0     |
+ * |    event/ECR   |
+ * |    user_r25    |
  * ------------------  <===== END of PAGE
  */
 int copy_thread(unsigned long clone_flags,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/ptrace.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/ptrace.c
--- linux-libre-3.10-gnu/arch/arc/kernel/ptrace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/ptrace.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,7 +40,15 @@ static int genregs_get(struct task_struc
 			offsetof(struct user_regs_struct, LOC), \
 			offsetof(struct user_regs_struct, LOC) + 4);
 
+#define REG_O_ZERO(LOC)		\
+	if (!ret)		\
+		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, \
+			offsetof(struct user_regs_struct, LOC), \
+			offsetof(struct user_regs_struct, LOC) + 4);
+
+	REG_O_ZERO(pad);
 	REG_O_CHUNK(scratch, callee, ptregs);
+	REG_O_ZERO(pad2);
 	REG_O_CHUNK(callee, efa, cregs);
 	REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address);
 
@@ -88,8 +96,10 @@ static int genregs_set(struct task_struc
 			offsetof(struct user_regs_struct, LOC), \
 			offsetof(struct user_regs_struct, LOC) + 4);
 
-	/* TBD: disallow updates to STATUS32, orig_r8 etc*/
-	REG_IN_CHUNK(scratch, callee, ptregs);	/* pt_regs[bta..orig_r8] */
+	REG_IGNORE_ONE(pad);
+	/* TBD: disallow updates to STATUS32 etc*/
+	REG_IN_CHUNK(scratch, pad2, ptregs);	/* pt_regs[bta..sp] */
+	REG_IGNORE_ONE(pad2);
 	REG_IN_CHUNK(callee, efa, cregs);	/* callee_regs[r25..r13] */
 	REG_IGNORE_ONE(efa);			/* efa update invalid */
 	REG_IN_ONE(stop_pc, &ptregs->ret);	/* stop_pc: PC update */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/setup.c
--- linux-libre-3.10-gnu/arch/arc/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,14 +31,14 @@
 int running_on_hw = 1;	/* vs. on ISS */
 
 char __initdata command_line[COMMAND_LINE_SIZE];
-struct machine_desc *machine_desc __cpuinitdata;
+struct machine_desc *machine_desc;
 
 struct task_struct *_current_task[NR_CPUS];	/* For stack switching */
 
 struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
 
 
-void __cpuinit read_arc_build_cfg_regs(void)
+void read_arc_build_cfg_regs(void)
 {
 	struct bcr_perip uncached_space;
 	struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
@@ -182,7 +182,7 @@ char *arc_extn_mumbojumbo(int cpu_id, ch
 	FIX_PTR(cpu);
 #define IS_AVAIL1(var, str)	((var) ? str : "")
 #define IS_AVAIL2(var, str)	((var == 0x2) ? str : "")
-#define IS_USED(var)		((var) ? "(in-use)" : "(not used)")
+#define IS_USED(cfg)		(IS_ENABLED(cfg) ? "(in-use)" : "(not used)")
 
 	n += scnprintf(buf + n, len - n,
 		       "Extn [700-Base]\t: %s %s %s %s %s %s\n",
@@ -202,9 +202,9 @@ char *arc_extn_mumbojumbo(int cpu_id, ch
 	if (cpu->core.family == 0x34) {
 		n += scnprintf(buf + n, len - n,
 		"Extn [700-4.10]\t: LLOCK/SCOND %s, SWAPE %s, RTSC %s\n",
-			       IS_USED(__CONFIG_ARC_HAS_LLSC_VAL),
-			       IS_USED(__CONFIG_ARC_HAS_SWAPE_VAL),
-			       IS_USED(__CONFIG_ARC_HAS_RTSC_VAL));
+			       IS_USED(CONFIG_ARC_HAS_LLSC),
+			       IS_USED(CONFIG_ARC_HAS_SWAPE),
+			       IS_USED(CONFIG_ARC_HAS_RTSC));
 	}
 
 	n += scnprintf(buf + n, len - n, "Extn [CCM]\t: %s",
@@ -237,7 +237,7 @@ char *arc_extn_mumbojumbo(int cpu_id, ch
 	return buf;
 }
 
-void __cpuinit arc_chk_ccms(void)
+void arc_chk_ccms(void)
 {
 #if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM)
 	struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
@@ -272,7 +272,7 @@ void __cpuinit arc_chk_ccms(void)
  * hardware has dedicated regs which need to be saved/restored on ctx-sw
  * (Single Precision uses core regs), thus kernel is kind of oblivious to it
  */
-void __cpuinit arc_chk_fpu(void)
+void arc_chk_fpu(void)
 {
 	struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
 
@@ -293,7 +293,7 @@ void __cpuinit arc_chk_fpu(void)
  *    such as only for boot CPU etc
  */
 
-void __cpuinit setup_processor(void)
+void setup_processor(void)
 {
 	char str[512];
 	int cpu_id = smp_processor_id();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/smp.c
--- linux-libre-3.10-gnu/arch/arc/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -117,7 +117,7 @@ const char *arc_platform_smp_cpuinfo(voi
  * Called from asm stub in head.S
  * "current"/R25 already setup by low level boot code
  */
-void __cpuinit start_kernel_secondary(void)
+void start_kernel_secondary(void)
 {
 	struct mm_struct *mm = &init_mm;
 	unsigned int cpu = smp_processor_id();
@@ -154,7 +154,7 @@ void __cpuinit start_kernel_secondary(vo
  *
  * Essential requirements being where to run from (PC) and stack (SP)
 */
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
+int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long wait_till;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/stacktrace.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/stacktrace.c
--- linux-libre-3.10-gnu/arch/arc/kernel/stacktrace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/stacktrace.c	2013-08-25 20:43:22.000000000 -0400
@@ -79,7 +79,7 @@ static void seed_unwind_frame_info(struc
 		 * assembly code
 		 */
 		frame_info->regs.r27 = 0;
-		frame_info->regs.r28 += 64;
+		frame_info->regs.r28 += 60;
 		frame_info->call_frame = 0;
 
 	} else {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/time.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/time.c
--- linux-libre-3.10-gnu/arch/arc/kernel/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,13 +44,24 @@
 #include <asm/clk.h>
 #include <asm/mach_desc.h>
 
+/* Timer related Aux registers */
+#define ARC_REG_TIMER0_LIMIT	0x23	/* timer 0 limit */
+#define ARC_REG_TIMER0_CTRL	0x22	/* timer 0 control */
+#define ARC_REG_TIMER0_CNT	0x21	/* timer 0 count */
+#define ARC_REG_TIMER1_LIMIT	0x102	/* timer 1 limit */
+#define ARC_REG_TIMER1_CTRL	0x101	/* timer 1 control */
+#define ARC_REG_TIMER1_CNT	0x100	/* timer 1 count */
+
+#define TIMER_CTRL_IE		(1 << 0) /* Interupt when Count reachs limit */
+#define TIMER_CTRL_NH		(1 << 1) /* Count only when CPU NOT halted */
+
 #define ARC_TIMER_MAX	0xFFFFFFFF
 
 /********** Clock Source Device *********/
 
 #ifdef CONFIG_ARC_HAS_RTSC
 
-int __cpuinit arc_counter_setup(void)
+int arc_counter_setup(void)
 {
 	/* RTSC insn taps into cpu clk, needs no setup */
 
@@ -105,7 +116,7 @@ static bool is_usable_as_clocksource(voi
 /*
  * set 32bit TIMER1 to keep counting monotonically and wraparound
  */
-int __cpuinit arc_counter_setup(void)
+int arc_counter_setup(void)
 {
 	write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX);
 	write_aux_reg(ARC_REG_TIMER1_CNT, 0);
@@ -212,7 +223,7 @@ static struct irqaction arc_timer_irq =
  * Setup the local event timer for @cpu
  * N.B. weak so that some exotic ARC SoCs can completely override it
  */
-void __attribute__((weak)) __cpuinit arc_local_timer_setup(unsigned int cpu)
+void __attribute__((weak)) arc_local_timer_setup(unsigned int cpu)
 {
 	struct clock_event_device *clk = &per_cpu(arc_clockevent_device, cpu);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/traps.c
--- linux-libre-3.10-gnu/arch/arc/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,10 +28,9 @@ void __init trap_init(void)
 	return;
 }
 
-void die(const char *str, struct pt_regs *regs, unsigned long address,
-	 unsigned long cause_reg)
+void die(const char *str, struct pt_regs *regs, unsigned long address)
 {
-	show_kernel_fault_diag(str, regs, address, cause_reg);
+	show_kernel_fault_diag(str, regs, address);
 
 	/* DEAD END */
 	__asm__("flag 1");
@@ -42,14 +41,13 @@ void die(const char *str, struct pt_regs
  *  -for user faults enqueues requested signal
  *  -for kernel, chk if due to copy_(to|from)_user, otherwise die()
  */
-static noinline int handle_exception(unsigned long cause, char *str,
-				     struct pt_regs *regs, siginfo_t *info)
+static noinline int
+handle_exception(const char *str, struct pt_regs *regs, siginfo_t *info)
 {
 	if (user_mode(regs)) {
 		struct task_struct *tsk = current;
 
 		tsk->thread.fault_address = (__force unsigned int)info->si_addr;
-		tsk->thread.cause_code = cause;
 
 		force_sig_info(info->si_signo, info, tsk);
 
@@ -58,14 +56,14 @@ static noinline int handle_exception(uns
 		if (fixup_exception(regs))
 			return 0;
 
-		die(str, regs, (unsigned long)info->si_addr, cause);
+		die(str, regs, (unsigned long)info->si_addr);
 	}
 
 	return 1;
 }
 
 #define DO_ERROR_INFO(signr, str, name, sicode) \
-int name(unsigned long cause, unsigned long address, struct pt_regs *regs) \
+int name(unsigned long address, struct pt_regs *regs) \
 {						\
 	siginfo_t info = {			\
 		.si_signo = signr,		\
@@ -73,7 +71,7 @@ int name(unsigned long cause, unsigned l
 		.si_code  = sicode,		\
 		.si_addr = (void __user *)address,	\
 	};					\
-	return handle_exception(cause, str, regs, &info);\
+	return handle_exception(str, regs, &info);\
 }
 
 /*
@@ -90,11 +88,11 @@ DO_ERROR_INFO(SIGBUS, "Misaligned Access
 /*
  * Entry Point for Misaligned Data access Exception, for emulating in software
  */
-int do_misaligned_access(unsigned long cause, unsigned long address,
-			 struct pt_regs *regs, struct callee_regs *cregs)
+int do_misaligned_access(unsigned long address, struct pt_regs *regs,
+			 struct callee_regs *cregs)
 {
-	if (misaligned_fixup(address, regs, cause, cregs) != 0)
-		return do_misaligned_error(cause, address, regs);
+	if (misaligned_fixup(address, regs, cregs) != 0)
+		return do_misaligned_error(address, regs);
 
 	return 0;
 }
@@ -104,10 +102,9 @@ int do_misaligned_access(unsigned long c
  * Entry point for miscll errors such as Nested Exceptions
  *  -Duplicate TLB entry is handled seperately though
  */
-void do_machine_check_fault(unsigned long cause, unsigned long address,
-			    struct pt_regs *regs)
+void do_machine_check_fault(unsigned long address, struct pt_regs *regs)
 {
-	die("Machine Check Exception", regs, address, cause);
+	die("Machine Check Exception", regs, address);
 }
 
 
@@ -120,23 +117,22 @@ void do_machine_check_fault(unsigned lon
  *  -1 used for software breakpointing (gdb)
  *  -2 used by kprobes
  */
-void do_non_swi_trap(unsigned long cause, unsigned long address,
-			struct pt_regs *regs)
+void do_non_swi_trap(unsigned long address, struct pt_regs *regs)
 {
-	unsigned int param = cause & 0xff;
+	unsigned int param = regs->ecr_param;
 
 	switch (param) {
 	case 1:
-		trap_is_brkpt(cause, address, regs);
+		trap_is_brkpt(address, regs);
 		break;
 
 	case 2:
-		trap_is_kprobe(param, address, regs);
+		trap_is_kprobe(address, regs);
 		break;
 
 	case 3:
 	case 4:
-		kgdb_trap(regs, param);
+		kgdb_trap(regs);
 		break;
 
 	default:
@@ -149,14 +145,14 @@ void do_non_swi_trap(unsigned long cause
  *  -For a corner case, ARC kprobes implementation resorts to using
  *   this exception, hence the check
  */
-void do_insterror_or_kprobe(unsigned long cause,
-				       unsigned long address,
-				       struct pt_regs *regs)
+void do_insterror_or_kprobe(unsigned long address, struct pt_regs *regs)
 {
+	int rc;
+
 	/* Check if this exception is caused by kprobes */
-	if (notify_die(DIE_IERR, "kprobe_ierr", regs, address,
-		       cause, SIGILL) == NOTIFY_STOP)
+	rc = notify_die(DIE_IERR, "kprobe_ierr", regs, address, 0, SIGILL);
+	if (rc == NOTIFY_STOP)
 		return;
 
-	insterror_is_error(cause, address, regs);
+	insterror_is_error(address, regs);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/troubleshoot.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/troubleshoot.c
--- linux-libre-3.10-gnu/arch/arc/kernel/troubleshoot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/troubleshoot.c	2013-08-25 20:43:22.000000000 -0400
@@ -101,7 +101,7 @@ static void show_faulting_vma(unsigned l
 		if (file) {
 			struct path *path = &file->f_path;
 			nm = d_path(path, buf, PAGE_SIZE - 1);
-			inode = vma->vm_file->f_path.dentry->d_inode;
+			inode = file_inode(vma->vm_file);
 			dev = inode->i_sb->s_dev;
 			ino = inode->i_ino;
 		}
@@ -117,23 +117,22 @@ static void show_faulting_vma(unsigned l
 
 static void show_ecr_verbose(struct pt_regs *regs)
 {
-	unsigned int vec, cause_code, cause_reg;
+	unsigned int vec, cause_code;
 	unsigned long address;
 
-	cause_reg = current->thread.cause_code;
-	pr_info("\n[ECR   ]: 0x%08x => ", cause_reg);
+	pr_info("\n[ECR   ]: 0x%08lx => ", regs->event);
 
 	/* For Data fault, this is data address not instruction addr */
 	address = current->thread.fault_address;
 
-	vec = cause_reg >> 16;
-	cause_code = (cause_reg >> 8) & 0xFF;
+	vec = regs->ecr_vec;
+	cause_code = regs->ecr_cause;
 
 	/* For DTLB Miss or ProtV, display the memory involved too */
 	if (vec == ECR_V_DTLB_MISS) {
-		pr_cont("Invalid %s 0x%08lx by insn @ 0x%08lx\n",
-		       (cause_code == 0x01) ? "Read From" :
-		       ((cause_code == 0x02) ? "Write to" : "EX"),
+		pr_cont("Invalid %s @ 0x%08lx by insn @ 0x%08lx\n",
+		       (cause_code == 0x01) ? "Read" :
+		       ((cause_code == 0x02) ? "Write" : "EX"),
 		       address, regs->ret);
 	} else if (vec == ECR_V_ITLB_MISS) {
 		pr_cont("Insn could not be fetched\n");
@@ -144,14 +143,12 @@ static void show_ecr_verbose(struct pt_r
 	} else if (vec == ECR_V_PROTV) {
 		if (cause_code == ECR_C_PROTV_INST_FETCH)
 			pr_cont("Execute from Non-exec Page\n");
-		else if (cause_code == ECR_C_PROTV_LOAD)
-			pr_cont("Read from Non-readable Page\n");
-		else if (cause_code == ECR_C_PROTV_STORE)
-			pr_cont("Write to Non-writable Page\n");
-		else if (cause_code == ECR_C_PROTV_XCHG)
-			pr_cont("Data exchange protection violation\n");
 		else if (cause_code == ECR_C_PROTV_MISALIG_DATA)
 			pr_cont("Misaligned r/w from 0x%08lx\n", address);
+		else
+			pr_cont("%s access not allowed on page\n",
+				(cause_code == 0x01) ? "Read" :
+				((cause_code == 0x02) ? "Write" : "EX"));
 	} else if (vec == ECR_V_INSN_ERR) {
 		pr_cont("Illegal Insn\n");
 	} else {
@@ -176,8 +173,7 @@ void show_regs(struct pt_regs *regs)
 	print_task_path_n_nm(tsk, buf);
 	show_regs_print_info(KERN_INFO);
 
-	if (current->thread.cause_code)
-		show_ecr_verbose(regs);
+	show_ecr_verbose(regs);
 
 	pr_info("[EFA   ]: 0x%08lx\n[BLINK ]: %pS\n[ERET  ]: %pS\n",
 		current->thread.fault_address,
@@ -213,10 +209,9 @@ void show_regs(struct pt_regs *regs)
 }
 
 void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
-			    unsigned long address, unsigned long cause_reg)
+			    unsigned long address)
 {
 	current->thread.fault_address = address;
-	current->thread.cause_code = cause_reg;
 
 	/* Caller and Callee regs */
 	show_regs(regs);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/unaligned.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/unaligned.c
--- linux-libre-3.10-gnu/arch/arc/kernel/unaligned.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/unaligned.c	2013-08-25 20:43:22.000000000 -0400
@@ -187,7 +187,7 @@ fault:	state->fault = 1;
  * Returns 0 if successfully handled, 1 if some error happened
  */
 int misaligned_fixup(unsigned long address, struct pt_regs *regs,
-		     unsigned long cause, struct callee_regs *cregs)
+		     struct callee_regs *cregs)
 {
 	struct disasm_state state;
 	char buf[TASK_COMM_LEN];
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/unwind.c linux-libre-3.11-rc7-gnu/arch/arc/kernel/unwind.c
--- linux-libre-3.10-gnu/arch/arc/kernel/unwind.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/unwind.c	2013-08-25 20:43:22.000000000 -0400
@@ -289,6 +289,8 @@ static void __init setup_unwind_table(st
 			 * instead of the initial loc addr
 			 * return;
 			 */
+			WARN(1, "unwinder: FDE->initial_location NULL %p\n",
+				(const u8 *)(fde + 1) + *fde);
 		}
 		++n;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/kernel/vmlinux.lds.S linux-libre-3.11-rc7-gnu/arch/arc/kernel/vmlinux.lds.S
--- linux-libre-3.10-gnu/arch/arc/kernel/vmlinux.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/kernel/vmlinux.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -125,6 +125,11 @@ SECTIONS
 		*(.debug_frame)
 		__end_unwind = .;
 	}
+	/*
+	 * gcc 4.8 generates this for -fasynchonous-unwind-tables,
+	 * while we still use the .debug_frame based unwinder
+	 */
+	/DISCARD/ : {	*(.eh_frame) }
 #else
 	/DISCARD/ : {	*(.debug_frame) }
 #endif
@@ -142,15 +147,18 @@ SECTIONS
 		*(.arcextmap.*)
 	}
 
+#ifndef CONFIG_DEBUG_INFO
 	/* open-coded because we need .debug_frame seperately for unwinding */
-	.debug_aranges 0 : { *(.debug_aranges) }
-	.debug_pubnames 0 : { *(.debug_pubnames) }
-	.debug_info 0 : { *(.debug_info) }
-	.debug_abbrev 0 : { *(.debug_abbrev) }
-	.debug_line 0 : { *(.debug_line) }
-	.debug_str 0 : { *(.debug_str) }
-	.debug_loc 0 : { *(.debug_loc) }
-	.debug_macinfo 0 : { *(.debug_macinfo) }
+	/DISCARD/ : { *(.debug_aranges) }
+	/DISCARD/ : { *(.debug_pubnames) }
+	/DISCARD/ : { *(.debug_info) }
+	/DISCARD/ : { *(.debug_abbrev) }
+	/DISCARD/ : { *(.debug_line) }
+	/DISCARD/ : { *(.debug_str) }
+	/DISCARD/ : { *(.debug_loc) }
+	/DISCARD/ : { *(.debug_macinfo) }
+	/DISCARD/ : { *(.debug_ranges) }
+#endif
 
 #ifdef CONFIG_ARC_HAS_DCCM
 	. = CONFIG_ARC_DCCM_BASE;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/lib/strchr-700.S linux-libre-3.11-rc7-gnu/arch/arc/lib/strchr-700.S
--- linux-libre-3.10-gnu/arch/arc/lib/strchr-700.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/lib/strchr-700.S	2013-08-25 20:43:22.000000000 -0400
@@ -39,9 +39,18 @@ ARC_ENTRY strchr
 	ld.a	r2,[r0,4]
 	sub	r12,r6,r7
 	bic	r12,r12,r6
+#ifdef __LITTLE_ENDIAN__
 	and	r7,r12,r4
 	breq	r7,0,.Loop ; For speed, we want this branch to be unaligned.
 	b	.Lfound_char ; Likewise this one.
+#else
+	and	r12,r12,r4
+	breq	r12,0,.Loop ; For speed, we want this branch to be unaligned.
+	lsr_s	r12,r12,7
+	bic 	r2,r7,r6
+	b.d	.Lfound_char_b
+	and_s	r2,r2,r12
+#endif
 ; /* We require this code address to be unaligned for speed...  */
 .Laligned:
 	ld_s	r2,[r0]
@@ -95,6 +104,7 @@ ARC_ENTRY strchr
 	lsr	r7,r7,7
 
 	bic	r2,r7,r6
+.Lfound_char_b:
 	norm	r2,r2
 	sub_s	r0,r0,4
 	asr_s	r2,r2,3
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/Makefile linux-libre-3.11-rc7-gnu/arch/arc/Makefile
--- linux-libre-3.10-gnu/arch/arc/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -9,25 +9,27 @@
 UTS_MACHINE := arc
 
 ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := arc-elf32-
+CROSS_COMPILE := arc-linux-uclibc-
 endif
 
 KBUILD_DEFCONFIG := fpga_defconfig
 
 cflags-y	+= -mA7 -fno-common -pipe -fno-builtin -D__linux__
 
-LINUXINCLUDE	+=  -include ${src}/arch/arc/include/asm/defines.h
-
 ifdef CONFIG_ARC_CURR_IN_REG
 # For a global register defintion, make sure it gets passed to every file
 # We had a customer reported bug where some code built in kernel was NOT using
 # any kernel headers, and missing the r25 global register
-# Can't do unconditionally (like above) because of recursive include issues
+# Can't do unconditionally because of recursive include issues
 # due to <linux/thread_info.h>
 LINUXINCLUDE	+=  -include ${src}/arch/arc/include/asm/current.h
 endif
 
-atleast_gcc44 :=  $(call cc-ifversion, -gt, 0402, y)
+upto_gcc42    :=  $(call cc-ifversion, -le, 0402, y)
+upto_gcc44    :=  $(call cc-ifversion, -le, 0404, y)
+atleast_gcc44 :=  $(call cc-ifversion, -ge, 0404, y)
+atleast_gcc48 :=  $(call cc-ifversion, -ge, 0408, y)
+
 cflags-$(atleast_gcc44)			+= -fsection-anchors
 
 cflags-$(CONFIG_ARC_HAS_LLSC)		+= -mlock
@@ -35,6 +37,11 @@ cflags-$(CONFIG_ARC_HAS_SWAPE)		+= -mswa
 cflags-$(CONFIG_ARC_HAS_RTSC)		+= -mrtsc
 cflags-$(CONFIG_ARC_DW2_UNWIND)		+= -fasynchronous-unwind-tables
 
+# By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok
+ifeq ($(atleast_gcc48),y)
+cflags-$(CONFIG_ARC_DW2_UNWIND)		+= -gdwarf-2
+endif
+
 ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE
 # Generic build system uses -O2, we want -O3
 cflags-y  += -O3
@@ -48,11 +55,10 @@ cflags-$(disable_small_data)		+= -mno-sd
 cflags-$(CONFIG_CPU_BIG_ENDIAN)		+= -mbig-endian
 ldflags-$(CONFIG_CPU_BIG_ENDIAN)	+= -EB
 
-# STAR 9000518362:
+# STAR 9000518362: (fixed with binutils shipping with gcc 4.8)
 # arc-linux-uclibc-ld (buildroot) or arceb-elf32-ld (EZChip) don't accept
-# --build-id w/o "-marclinux".
-# Default arc-elf32-ld is OK
-ldflags-y				+= -marclinux
+# --build-id w/o "-marclinux". Default arc-elf32-ld is OK
+ldflags-$(upto_gcc44)			+= -marclinux
 
 ARC_LIBGCC				:= -mA7
 cflags-$(CONFIG_ARC_HAS_HW_MPY)		+= -multcost=16
@@ -66,8 +72,8 @@ ifndef CONFIG_ARC_HAS_HW_MPY
 # With gcc 4.4.7, -mno-mpy is enough to make any other related adjustments,
 # e.g. increased cost of MPY. With gcc 4.2.1 this had to be explicitly hinted
 
-	ARC_LIBGCC		:= -marc600
-	ifneq ($(atleast_gcc44),y)
+	ifeq ($(upto_gcc42),y)
+		ARC_LIBGCC	:= -marc600
 		cflags-y	+= -multcost=30
 	endif
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/mm/cache_arc700.c linux-libre-3.11-rc7-gnu/arch/arc/mm/cache_arc700.c
--- linux-libre-3.10-gnu/arch/arc/mm/cache_arc700.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/mm/cache_arc700.c	2013-08-25 20:43:22.000000000 -0400
@@ -73,6 +73,33 @@
 #include <asm/cachectl.h>
 #include <asm/setup.h>
 
+/* Instruction cache related Auxiliary registers */
+#define ARC_REG_IC_BCR		0x77	/* Build Config reg */
+#define ARC_REG_IC_IVIC		0x10
+#define ARC_REG_IC_CTRL		0x11
+#define ARC_REG_IC_IVIL		0x19
+#if (CONFIG_ARC_MMU_VER > 2)
+#define ARC_REG_IC_PTAG		0x1E
+#endif
+
+/* Bit val in IC_CTRL */
+#define IC_CTRL_CACHE_DISABLE   0x1
+
+/* Data cache related Auxiliary registers */
+#define ARC_REG_DC_BCR		0x72	/* Build Config reg */
+#define ARC_REG_DC_IVDC		0x47
+#define ARC_REG_DC_CTRL		0x48
+#define ARC_REG_DC_IVDL		0x4A
+#define ARC_REG_DC_FLSH		0x4B
+#define ARC_REG_DC_FLDL		0x4C
+#if (CONFIG_ARC_MMU_VER > 2)
+#define ARC_REG_DC_PTAG		0x5C
+#endif
+
+/* Bit val in DC_CTRL */
+#define DC_CTRL_INV_MODE_FLUSH  0x40
+#define DC_CTRL_FLUSH_STATUS    0x100
+
 char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len)
 {
 	int n = 0;
@@ -89,8 +116,10 @@ char *arc_cache_mumbojumbo(int cpu_id, c
 			enb ?  "" : "DISABLED (kernel-build)");		\
 }
 
-	PR_CACHE(&cpuinfo_arc700[c].icache, __CONFIG_ARC_HAS_ICACHE, "I-Cache");
-	PR_CACHE(&cpuinfo_arc700[c].dcache, __CONFIG_ARC_HAS_DCACHE, "D-Cache");
+	PR_CACHE(&cpuinfo_arc700[c].icache, IS_ENABLED(CONFIG_ARC_HAS_ICACHE),
+			"I-Cache");
+	PR_CACHE(&cpuinfo_arc700[c].dcache, IS_ENABLED(CONFIG_ARC_HAS_DCACHE),
+			"D-Cache");
 
 	return buf;
 }
@@ -100,17 +129,23 @@ char *arc_cache_mumbojumbo(int cpu_id, c
  * the cpuinfo structure for later use.
  * No Validation done here, simply read/convert the BCRs
  */
-void __cpuinit read_decode_cache_bcr(void)
+void read_decode_cache_bcr(void)
 {
-	struct bcr_cache ibcr, dbcr;
 	struct cpuinfo_arc_cache *p_ic, *p_dc;
 	unsigned int cpu = smp_processor_id();
+	struct bcr_cache {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+		unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
+#else
+		unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
+#endif
+	} ibcr, dbcr;
 
 	p_ic = &cpuinfo_arc700[cpu].icache;
 	READ_BCR(ARC_REG_IC_BCR, ibcr);
 
-	if (ibcr.config == 0x3)
-		p_ic->assoc = 2;
+	BUG_ON(ibcr.config != 3);
+	p_ic->assoc = 2;		/* Fixed to 2w set assoc */
 	p_ic->line_len = 8 << ibcr.line_len;
 	p_ic->sz = 0x200 << ibcr.sz;
 	p_ic->ver = ibcr.ver;
@@ -118,8 +153,8 @@ void __cpuinit read_decode_cache_bcr(voi
 	p_dc = &cpuinfo_arc700[cpu].dcache;
 	READ_BCR(ARC_REG_DC_BCR, dbcr);
 
-	if (dbcr.config == 0x2)
-		p_dc->assoc = 4;
+	BUG_ON(dbcr.config != 2);
+	p_dc->assoc = 4;		/* Fixed to 4w set assoc */
 	p_dc->line_len = 16 << dbcr.line_len;
 	p_dc->sz = 0x200 << dbcr.sz;
 	p_dc->ver = dbcr.ver;
@@ -132,14 +167,12 @@ void __cpuinit read_decode_cache_bcr(voi
  * 3. Enable the Caches, setup default flush mode for D-Cache
  * 3. Calculate the SHMLBA used by user space
  */
-void __cpuinit arc_cache_init(void)
+void arc_cache_init(void)
 {
-	unsigned int temp;
 	unsigned int cpu = smp_processor_id();
 	struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache;
 	struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache;
-	int way_pg_ratio = way_pg_ratio;
-	int dcache_does_alias;
+	unsigned int dcache_does_alias, temp;
 	char str[256];
 
 	printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
@@ -149,20 +182,11 @@ void __cpuinit arc_cache_init(void)
 
 #ifdef CONFIG_ARC_HAS_ICACHE
 	/* 1. Confirm some of I-cache params which Linux assumes */
-	if ((ic->assoc != ARC_ICACHE_WAYS) ||
-	    (ic->line_len != ARC_ICACHE_LINE_LEN)) {
+	if (ic->line_len != ARC_ICACHE_LINE_LEN)
 		panic("Cache H/W doesn't match kernel Config");
-	}
-#if (CONFIG_ARC_MMU_VER > 2)
-	if (ic->ver != 3) {
-		if (running_on_hw)
-			panic("Cache ver doesn't match MMU ver\n");
-
-		/* For ISS - suggest the toggles to use */
-		pr_err("Use -prop=icache_version=3,-prop=dcache_version=3\n");
 
-	}
-#endif
+	if (ic->ver != CONFIG_ARC_MMU_VER)
+		panic("Cache ver doesn't match MMU ver\n");
 #endif
 
 	/* Enable/disable I-Cache */
@@ -181,14 +205,12 @@ chk_dc:
 		return;
 
 #ifdef CONFIG_ARC_HAS_DCACHE
-	if ((dc->assoc != ARC_DCACHE_WAYS) ||
-	    (dc->line_len != ARC_DCACHE_LINE_LEN)) {
+	if (dc->line_len != ARC_DCACHE_LINE_LEN)
 		panic("Cache H/W doesn't match kernel Config");
-	}
-
-	dcache_does_alias = (dc->sz / ARC_DCACHE_WAYS) > PAGE_SIZE;
 
 	/* check for D-Cache aliasing */
+	dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
+
 	if (dcache_does_alias && !cache_is_vipt_aliasing())
 		panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
 	else if (!dcache_does_alias && cache_is_vipt_aliasing())
@@ -239,11 +261,9 @@ static inline void wait_for_flush(void)
  */
 static inline void __dc_entire_op(const int cacheop)
 {
-	unsigned long flags, tmp = tmp;
+	unsigned int tmp = tmp;
 	int aux;
 
-	local_irq_save(flags);
-
 	if (cacheop == OP_FLUSH_N_INV) {
 		/* Dcache provides 2 cmd: FLUSH or INV
 		 * INV inturn has sub-modes: DISCARD or FLUSH-BEFORE
@@ -267,8 +287,6 @@ static inline void __dc_entire_op(const
 	/* Switch back the DISCARD ONLY Invalidate mode */
 	if (cacheop == OP_FLUSH_N_INV)
 		write_aux_reg(ARC_REG_DC_CTRL, tmp & ~DC_CTRL_INV_MODE_FLUSH);
-
-	local_irq_restore(flags);
 }
 
 /*
@@ -459,8 +477,15 @@ static void __ic_line_inv_vaddr(unsigned
 	local_irq_restore(flags);
 }
 
+static inline void __ic_entire_inv(void)
+{
+	write_aux_reg(ARC_REG_IC_IVIC, 1);
+	read_aux_reg(ARC_REG_IC_CTRL);	/* blocks */
+}
+
 #else
 
+#define __ic_entire_inv()
 #define __ic_line_inv_vaddr(pstart, vstart, sz)
 
 #endif /* CONFIG_ARC_HAS_ICACHE */
@@ -487,7 +512,7 @@ void flush_dcache_page(struct page *page
 	struct address_space *mapping;
 
 	if (!cache_is_vipt_aliasing()) {
-		set_bit(PG_arch_1, &page->flags);
+		clear_bit(PG_dc_clean, &page->flags);
 		return;
 	}
 
@@ -501,7 +526,7 @@ void flush_dcache_page(struct page *page
 	 * Make a note that K-mapping is dirty
 	 */
 	if (!mapping_mapped(mapping)) {
-		set_bit(PG_arch_1, &page->flags);
+		clear_bit(PG_dc_clean, &page->flags);
 	} else if (page_mapped(page)) {
 
 		/* kernel reading from page with U-mapping */
@@ -629,26 +654,13 @@ void ___flush_dcache_page(unsigned long
 	__dc_line_op(paddr, vaddr & PAGE_MASK, PAGE_SIZE, OP_FLUSH_N_INV);
 }
 
-void flush_icache_all(void)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	write_aux_reg(ARC_REG_IC_IVIC, 1);
-
-	/* lr will not complete till the icache inv operation is not over */
-	read_aux_reg(ARC_REG_IC_CTRL);
-	local_irq_restore(flags);
-}
-
 noinline void flush_cache_all(void)
 {
 	unsigned long flags;
 
 	local_irq_save(flags);
 
-	flush_icache_all();
+	__ic_entire_inv();
 	__dc_entire_op(OP_FLUSH_N_INV);
 
 	local_irq_restore(flags);
@@ -667,7 +679,12 @@ void flush_cache_page(struct vm_area_str
 {
 	unsigned int paddr = pfn << PAGE_SHIFT;
 
-	__sync_icache_dcache(paddr, u_vaddr, PAGE_SIZE);
+	u_vaddr &= PAGE_MASK;
+
+	___flush_dcache_page(paddr, u_vaddr);
+
+	if (vma->vm_flags & VM_EXEC)
+		__inv_icache_page(paddr, u_vaddr);
 }
 
 void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
@@ -717,7 +734,7 @@ void copy_user_highpage(struct page *to,
 	 * non copied user pages (e.g. read faults which wire in pagecache page
 	 * directly).
 	 */
-	set_bit(PG_arch_1, &to->flags);
+	clear_bit(PG_dc_clean, &to->flags);
 
 	/*
 	 * if SRC was already usermapped and non-congruent to kernel mapping
@@ -725,15 +742,16 @@ void copy_user_highpage(struct page *to,
 	 */
 	if (clean_src_k_mappings) {
 		__flush_dcache_page(kfrom, kfrom);
+		set_bit(PG_dc_clean, &from->flags);
 	} else {
-		set_bit(PG_arch_1, &from->flags);
+		clear_bit(PG_dc_clean, &from->flags);
 	}
 }
 
 void clear_user_page(void *to, unsigned long u_vaddr, struct page *page)
 {
 	clear_page(to);
-	set_bit(PG_arch_1, &page->flags);
+	clear_bit(PG_dc_clean, &page->flags);
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/mm/fault.c linux-libre-3.11-rc7-gnu/arch/arc/mm/fault.c
--- linux-libre-3.10-gnu/arch/arc/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/uaccess.h>
 #include <linux/kdebug.h>
 #include <asm/pgalloc.h>
+#include <asm/mmu.h>
 
 static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address)
 {
@@ -51,14 +52,14 @@ bad_area:
 	return 1;
 }
 
-void do_page_fault(struct pt_regs *regs, int write, unsigned long address,
-		   unsigned long cause_code)
+void do_page_fault(struct pt_regs *regs, unsigned long address)
 {
 	struct vm_area_struct *vma = NULL;
 	struct task_struct *tsk = current;
 	struct mm_struct *mm = tsk->mm;
 	siginfo_t info;
 	int fault, ret;
+	int write = regs->ecr_cause & ECR_C_PROTV_STORE;  /* ST/EX */
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
 				(write ? FAULT_FLAG_WRITE : 0);
 
@@ -109,7 +110,8 @@ good_area:
 
 	/* Handle protection violation, execute on heap or stack */
 
-	if (cause_code == ((ECR_V_PROTV << 16) | ECR_C_PROTV_INST_FETCH))
+	if ((regs->ecr_vec == ECR_V_PROTV) &&
+	    (regs->ecr_cause == ECR_C_PROTV_INST_FETCH))
 		goto bad_area;
 
 	if (write) {
@@ -176,7 +178,6 @@ bad_area_nosemaphore:
 	/* User mode accesses just cause a SIGSEGV */
 	if (user_mode(regs)) {
 		tsk->thread.fault_address = address;
-		tsk->thread.cause_code = cause_code;
 		info.si_signo = SIGSEGV;
 		info.si_errno = 0;
 		/* info.si_code has been set above */
@@ -197,7 +198,7 @@ no_context:
 	if (fixup_exception(regs))
 		return;
 
-	die("Oops", regs, address, cause_code);
+	die("Oops", regs, address);
 
 out_of_memory:
 	if (is_global_init(tsk)) {
@@ -206,8 +207,10 @@ out_of_memory:
 	}
 	up_read(&mm->mmap_sem);
 
-	if (user_mode(regs))
-		do_group_exit(SIGKILL);	/* This will never return */
+	if (user_mode(regs)) {
+		pagefault_out_of_memory();
+		return;
+	}
 
 	goto no_context;
 
@@ -218,7 +221,6 @@ do_sigbus:
 		goto no_context;
 
 	tsk->thread.fault_address = address;
-	tsk->thread.cause_code = cause_code;
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRERR;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/mm/init.c linux-libre-3.11-rc7-gnu/arch/arc/mm/init.c
--- linux-libre-3.10-gnu/arch/arc/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,7 +74,7 @@ void __init setup_arch_memory(void)
 	/* Last usable page of low mem (no HIGHMEM yet for ARC port) */
 	max_low_pfn = max_pfn = PFN_DOWN(end_mem);
 
-	max_mapnr = num_physpages = max_low_pfn - min_low_pfn;
+	max_mapnr = max_low_pfn - min_low_pfn;
 
 	/*------------- reserve kernel image -----------------------*/
 	memblock_reserve(CONFIG_LINUX_LINK_BASE,
@@ -84,7 +84,7 @@ void __init setup_arch_memory(void)
 
 	/*-------------- node setup --------------------------------*/
 	memset(zones_size, 0, sizeof(zones_size));
-	zones_size[ZONE_NORMAL] = num_physpages;
+	zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
 
 	/*
 	 * We can't use the helper free_area_init(zones[]) because it uses
@@ -106,39 +106,9 @@ void __init setup_arch_memory(void)
  */
 void __init mem_init(void)
 {
-	int codesize, datasize, initsize, reserved_pages, free_pages;
-	int tmp;
-
 	high_memory = (void *)(CONFIG_LINUX_LINK_BASE + arc_mem_sz);
-
-	totalram_pages = free_all_bootmem();
-
-	/* count all reserved pages [kernel code/data/mem_map..] */
-	reserved_pages = 0;
-	for (tmp = 0; tmp < max_mapnr; tmp++)
-		if (PageReserved(mem_map + tmp))
-			reserved_pages++;
-
-	/* XXX: nr_free_pages() is equivalent */
-	free_pages = max_mapnr - reserved_pages;
-
-	/*
-	 * For the purpose of display below, split the "reserve mem"
-	 * kernel code/data is already shown explicitly,
-	 * Show any other reservations (mem_map[ ] et al)
-	 */
-	reserved_pages -= (((unsigned int)_end - CONFIG_LINUX_LINK_BASE) >>
-								PAGE_SHIFT);
-
-	codesize = _etext - _text;
-	datasize = _end - _etext;
-	initsize = __init_end - __init_begin;
-
-	pr_info("Memory Available: %dM / %ldM (%dK code, %dK data, %dK init, %dK reserv)\n",
-		PAGES_TO_MB(free_pages),
-		TO_MB(arc_mem_sz),
-		TO_KB(codesize), TO_KB(datasize), TO_KB(initsize),
-		PAGES_TO_KB(reserved_pages));
+	free_all_bootmem();
+	mem_init_print_info(NULL);
 }
 
 /*
@@ -146,13 +116,13 @@ void __init mem_init(void)
  */
 void __init_refok free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/mm/tlb.c linux-libre-3.11-rc7-gnu/arch/arc/mm/tlb.c
--- linux-libre-3.10-gnu/arch/arc/mm/tlb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/mm/tlb.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,7 +55,7 @@
 #include <asm/arcregs.h>
 #include <asm/setup.h>
 #include <asm/mmu_context.h>
-#include <asm/tlb.h>
+#include <asm/mmu.h>
 
 /*			Need for ARC MMU v2
  *
@@ -97,6 +97,7 @@
  * J-TLB entry got evicted/replaced.
  */
 
+
 /* A copy of the ASID from the PID reg is kept in asid_cache */
 int asid_cache = FIRST_ASID;
 
@@ -432,9 +433,14 @@ void update_mmu_cache(struct vm_area_str
 {
 	unsigned long vaddr = vaddr_unaligned & PAGE_MASK;
 	unsigned long paddr = pte_val(*ptep) & PAGE_MASK;
+	struct page *page = pfn_to_page(pte_pfn(*ptep));
 
 	create_tlb(vma, vaddr, ptep);
 
+	if (page == ZERO_PAGE(0)) {
+		return;
+	}
+
 	/*
 	 * Exec page : Independent of aliasing/page-color considerations,
 	 *	       since icache doesn't snoop dcache on ARC, any dirty
@@ -446,9 +452,8 @@ void update_mmu_cache(struct vm_area_str
 	 */
 	if ((vma->vm_flags & VM_EXEC) ||
 	     addr_not_cache_congruent(paddr, vaddr)) {
-		struct page *page = pfn_to_page(pte_pfn(*ptep));
 
-		int dirty = test_and_clear_bit(PG_arch_1, &page->flags);
+		int dirty = !test_and_set_bit(PG_dc_clean, &page->flags);
 		if (dirty) {
 			/* wback + inv dcache lines */
 			__flush_dcache_page(paddr, paddr);
@@ -464,12 +469,27 @@ void update_mmu_cache(struct vm_area_str
  * the cpuinfo structure for later use.
  * No Validation is done here, simply read/convert the BCRs
  */
-void __cpuinit read_decode_mmu_bcr(void)
+void read_decode_mmu_bcr(void)
 {
-	unsigned int tmp;
-	struct bcr_mmu_1_2 *mmu2;	/* encoded MMU2 attr */
-	struct bcr_mmu_3 *mmu3;		/* encoded MMU3 attr */
 	struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
+	unsigned int tmp;
+	struct bcr_mmu_1_2 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+		unsigned int ver:8, ways:4, sets:4, u_itlb:8, u_dtlb:8;
+#else
+		unsigned int u_dtlb:8, u_itlb:8, sets:4, ways:4, ver:8;
+#endif
+	} *mmu2;
+
+	struct bcr_mmu_3 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	unsigned int ver:8, ways:4, sets:4, osm:1, reserv:3, pg_sz:4,
+		     u_itlb:4, u_dtlb:4;
+#else
+	unsigned int u_dtlb:4, u_itlb:4, pg_sz:4, reserv:3, osm:1, sets:4,
+		     ways:4, ver:8;
+#endif
+	} *mmu3;
 
 	tmp = read_aux_reg(ARC_REG_MMU_BCR);
 	mmu->ver = (tmp >> 24);
@@ -505,12 +525,12 @@ char *arc_mmu_mumbojumbo(int cpu_id, cha
 		       "J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n",
 		       p_mmu->num_tlb, p_mmu->sets, p_mmu->ways,
 		       p_mmu->u_dtlb, p_mmu->u_itlb,
-		       __CONFIG_ARC_MMU_SASID_VAL ? "SASID" : "");
+		       IS_ENABLED(CONFIG_ARC_MMU_SASID) ? "SASID" : "");
 
 	return buf;
 }
 
-void __cpuinit arc_mmu_init(void)
+void arc_mmu_init(void)
 {
 	char str[256];
 	struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/mm/tlbex.S linux-libre-3.11-rc7-gnu/arch/arc/mm/tlbex.S
--- linux-libre-3.10-gnu/arch/arc/mm/tlbex.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/mm/tlbex.S	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,7 @@
 
 #include <linux/linkage.h>
 #include <asm/entry.h>
-#include <asm/tlb.h>
+#include <asm/mmu.h>
 #include <asm/pgtable.h>
 #include <asm/arcregs.h>
 #include <asm/cache.h>
@@ -147,9 +147,9 @@ ex_saved_reg1:
 #ifdef CONFIG_ARC_DBG_TLB_MISS_COUNT
 	and.f 0, r0, _PAGE_PRESENT
 	bz   1f
-	ld   r2, [num_pte_not_present]
-	add  r2, r2, 1
-	st   r2, [num_pte_not_present]
+	ld   r3, [num_pte_not_present]
+	add  r3, r3, 1
+	st   r3, [num_pte_not_present]
 1:
 #endif
 
@@ -271,22 +271,22 @@ ARC_ENTRY EV_TLBMissI
 #endif
 
 	;----------------------------------------------------------------
-	; Get the PTE corresponding to V-addr accessed
+	; Get the PTE corresponding to V-addr accessed, r2 is setup with EFA
 	LOAD_FAULT_PTE
 
 	;----------------------------------------------------------------
 	; VERIFY_PTE: Check if PTE permissions approp for executing code
 	cmp_s   r2, VMALLOC_START
-	mov.lo  r2, (_PAGE_PRESENT | _PAGE_U_READ | _PAGE_U_EXECUTE)
-	mov.hs  r2, (_PAGE_PRESENT | _PAGE_K_READ | _PAGE_K_EXECUTE)
+	mov.lo  r2, (_PAGE_PRESENT | _PAGE_U_EXECUTE)
+	mov.hs  r2, (_PAGE_PRESENT | _PAGE_K_EXECUTE)
 
 	and     r3, r0, r2  ; Mask out NON Flag bits from PTE
 	xor.f   r3, r3, r2  ; check ( ( pte & flags_test ) == flags_test )
 	bnz     do_slow_path_pf
 
 	; Let Linux VM know that the page was accessed
-	or      r0, r0, (_PAGE_PRESENT | _PAGE_ACCESSED)  ; set Accessed Bit
-	st_s    r0, [r1]                                  ; Write back PTE
+	or      r0, r0, _PAGE_ACCESSED  ; set Accessed Bit
+	st_s    r0, [r1]                ; Write back PTE
 
 	CONV_PTE_TO_TLB
 	COMMIT_ENTRY_TO_MMU
@@ -311,7 +311,7 @@ ARC_ENTRY EV_TLBMissD
 
 	;----------------------------------------------------------------
 	; Get the PTE corresponding to V-addr accessed
-	; If PTE exists, it will setup, r0 = PTE, r1 = Ptr to PTE
+	; If PTE exists, it will setup, r0 = PTE, r1 = Ptr to PTE, r2 = EFA
 	LOAD_FAULT_PTE
 
 	;----------------------------------------------------------------
@@ -345,7 +345,7 @@ ARC_ENTRY EV_TLBMissD
 	;----------------------------------------------------------------
 	; UPDATE_PTE: Let Linux VM know that page was accessed/dirty
 	lr      r3, [ecr]
-	or      r0, r0, (_PAGE_PRESENT | _PAGE_ACCESSED) ; Accessed bit always
+	or      r0, r0, _PAGE_ACCESSED        ; Accessed bit always
 	btst_s  r3,  ECR_C_BIT_DTLB_ST_MISS   ; See if it was a Write Access ?
 	or.nz   r0, r0, _PAGE_MODIFIED        ; if Write, set Dirty bit as well
 	st_s    r0, [r1]                      ; Write back PTE
@@ -381,18 +381,7 @@ do_slow_path_pf:
 
 	; ------- setup args for Linux Page fault Hanlder ---------
 	mov_s r0, sp
-	lr  r2, [efa]
-	lr  r3, [ecr]
-
-	; Both st and ex imply WRITE access of some sort, hence do_page_fault( )
-	; invoked with write=1 for DTLB-st/ex Miss and write=0 for ITLB miss or
-	; DTLB-ld Miss
-	; DTLB Miss Cause code is ld = 0x01 , st = 0x02, ex = 0x03
-	; Following code uses that fact that st/ex have one bit in common
-
-	btst_s r3,  ECR_C_BIT_DTLB_ST_MISS
-	mov.z  r1, 0
-	mov.nz r1, 1
+	lr  r1, [efa]
 
 	; We don't want exceptions to be disabled while the fault is handled.
 	; Now that we have saved the context we return from exception hence
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/plat-arcfpga/include/plat/irq.h linux-libre-3.11-rc7-gnu/arch/arc/plat-arcfpga/include/plat/irq.h
--- linux-libre-3.10-gnu/arch/arc/plat-arcfpga/include/plat/irq.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/plat-arcfpga/include/plat/irq.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,8 +16,6 @@
 #define UART1_IRQ	10
 #define UART2_IRQ	11
 
-#define VMAC_IRQ	6
-
 #define IDE_IRQ		13
 #define PCI_IRQ		14
 #define PS2_IRQ		15
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/plat-arcfpga/include/plat/memmap.h linux-libre-3.11-rc7-gnu/arch/arc/plat-arcfpga/include/plat/memmap.h
--- linux-libre-3.10-gnu/arch/arc/plat-arcfpga/include/plat/memmap.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/plat-arcfpga/include/plat/memmap.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,8 +15,6 @@
 #define UART0_BASE              0xC0FC1000
 #define UART1_BASE              0xC0FC1100
 
-#define VMAC_REG_BASEADDR       0xC0FC2000
-
 #define IDE_CONTROLLER_BASE     0xC0FC9000
 
 #define AHB_PCI_HOST_BRG_BASE   0xC0FD0000
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/plat-arcfpga/platform.c linux-libre-3.11-rc7-gnu/arch/arc/plat-arcfpga/platform.c
--- linux-libre-3.10-gnu/arch/arc/plat-arcfpga/platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/plat-arcfpga/platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -77,6 +77,7 @@ static void __init setup_bvci_lat_unit(v
 
 /*----------------------- Platform Devices -----------------------------*/
 
+#if IS_ENABLED(CONFIG_SERIAL_ARC)
 static unsigned long arc_uart_info[] = {
 	0,	/* uart->is_emulated (runtime @running_on_hw) */
 	0,	/* uart->port.uartclk */
@@ -115,7 +116,7 @@ static struct platform_device arc_uart0_
 static struct platform_device *fpga_early_devs[] __initdata = {
 	&arc_uart0_dev,
 };
-#endif
+#endif	/* CONFIG_SERIAL_ARC_CONSOLE */
 
 static void arc_fpga_serial_init(void)
 {
@@ -152,8 +153,13 @@ static void arc_fpga_serial_init(void)
 	 * otherwise the early console never gets a chance to run.
 	 */
 	add_preferred_console("ttyARC", 0, "115200");
-#endif
+#endif	/* CONFIG_SERIAL_ARC_CONSOLE */
+}
+#else	/* !IS_ENABLED(CONFIG_SERIAL_ARC) */
+static void arc_fpga_serial_init(void)
+{
 }
+#endif
 
 static void __init plat_fpga_early_init(void)
 {
@@ -169,7 +175,7 @@ static void __init plat_fpga_early_init(
 }
 
 static struct of_dev_auxdata plat_auxdata_lookup[] __initdata = {
-#if defined(CONFIG_SERIAL_ARC) || defined(CONFIG_SERIAL_ARC_MODULE)
+#if IS_ENABLED(CONFIG_SERIAL_ARC)
 	OF_DEV_AUXDATA("snps,arc-uart", UART0_BASE, "arc-uart", arc_uart_info),
 #endif
 	{}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arc/plat-tb10x/Kconfig linux-libre-3.11-rc7-gnu/arch/arc/plat-tb10x/Kconfig
--- linux-libre-3.10-gnu/arch/arc/plat-tb10x/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arc/plat-tb10x/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@ menuconfig ARC_PLAT_TB10X
 	select PINCTRL
 	select PINMUX
 	select ARCH_REQUIRE_GPIOLIB
+	select TB10X_IRQC
 	help
 	  Support for platforms based on the TB10x home media gateway SOC by
 	  Abilis Systems. TB10x is based on the ARC700 CPU architecture.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/compressed/atags_to_fdt.c linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/atags_to_fdt.c
--- linux-libre-3.10-gnu/arch/arm/boot/compressed/atags_to_fdt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/atags_to_fdt.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,6 +53,17 @@ static const void *getprop(const void *f
 	return fdt_getprop(fdt, offset, property, len);
 }
 
+static uint32_t get_cell_size(const void *fdt)
+{
+	int len;
+	uint32_t cell_size = 1;
+	const uint32_t *size_len =  getprop(fdt, "/", "#size-cells", &len);
+
+	if (size_len)
+		cell_size = fdt32_to_cpu(*size_len);
+	return cell_size;
+}
+
 static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
 {
 	char cmdline[COMMAND_LINE_SIZE];
@@ -95,9 +106,11 @@ static void merge_fdt_bootargs(void *fdt
 int atags_to_fdt(void *atag_list, void *fdt, int total_space)
 {
 	struct tag *atag = atag_list;
-	uint32_t mem_reg_property[2 * NR_BANKS];
+	/* In the case of 64 bits memory size, need to reserve 2 cells for
+	 * address and size for each bank */
+	uint32_t mem_reg_property[2 * 2 * NR_BANKS];
 	int memcount = 0;
-	int ret;
+	int ret, memsize;
 
 	/* make sure we've got an aligned pointer */
 	if ((u32)atag_list & 0x3)
@@ -137,8 +150,25 @@ int atags_to_fdt(void *atag_list, void *
 				continue;
 			if (!atag->u.mem.size)
 				continue;
-			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
-			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
+			memsize = get_cell_size(fdt);
+
+			if (memsize == 2) {
+				/* if memsize is 2, that means that
+				 * each data needs 2 cells of 32 bits,
+				 * so the data are 64 bits */
+				uint64_t *mem_reg_prop64 =
+					(uint64_t *)mem_reg_property;
+				mem_reg_prop64[memcount++] =
+					cpu_to_fdt64(atag->u.mem.start);
+				mem_reg_prop64[memcount++] =
+					cpu_to_fdt64(atag->u.mem.size);
+			} else {
+				mem_reg_property[memcount++] =
+					cpu_to_fdt32(atag->u.mem.start);
+				mem_reg_property[memcount++] =
+					cpu_to_fdt32(atag->u.mem.size);
+			}
+
 		} else if (atag->hdr.tag == ATAG_INITRD2) {
 			uint32_t initrd_start, initrd_size;
 			initrd_start = atag->u.initrd.start;
@@ -150,8 +180,10 @@ int atags_to_fdt(void *atag_list, void *
 		}
 	}
 
-	if (memcount)
-		setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount);
+	if (memcount) {
+		setprop(fdt, "/memory", "reg", mem_reg_property,
+			4 * memcount * memsize);
+	}
 
 	return fdt_pack(fdt);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/compressed/decompress.c linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/decompress.c
--- linux-libre-3.10-gnu/arch/arm/boot/compressed/decompress.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/decompress.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,6 +51,10 @@ extern char * strstr(const char * s1, co
 #include "../../../../lib/decompress_unxz.c"
 #endif
 
+#ifdef CONFIG_KERNEL_LZ4
+#include "../../../../lib/decompress_unlz4.c"
+#endif
+
 int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
 {
 	return decompress(input, len, NULL, NULL, output, NULL, error);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/compressed/.gitignore linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/.gitignore
--- linux-libre-3.10-gnu/arch/arm/boot/compressed/.gitignore	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/.gitignore	2013-08-25 20:43:22.000000000 -0400
@@ -6,6 +6,7 @@ piggy.gzip
 piggy.lzo
 piggy.lzma
 piggy.xzkern
+piggy.lz4
 vmlinux
 vmlinux.lds
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/compressed/head.S linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/head.S
--- linux-libre-3.10-gnu/arch/arm/boot/compressed/head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/head.S	2013-08-25 20:43:22.000000000 -0400
@@ -142,7 +142,6 @@ start:
 		mov	r7, r1			@ save architecture ID
 		mov	r8, r2			@ save atags pointer
 
-#ifndef __ARM_ARCH_2__
 		/*
 		 * Booting from Angel - need to enter SVC mode and disable
 		 * FIQs/IRQs (numeric definitions from angel arm.h source).
@@ -158,10 +157,6 @@ not_angel:
 		safe_svcmode_maskall r0
 		msr	spsr_cxsf, r9		@ Save the CPU boot mode in
 						@ SPSR
-#else
-		teqp	pc, #0x0c000003		@ turn off interrupts
-#endif
-
 		/*
 		 * Note that some cache flushing and other stuff may
 		 * be needed here - is there an Angel SWI call for this?
@@ -183,7 +178,19 @@ not_angel:
 		ldr	r4, =zreladdr
 #endif
 
-		bl	cache_on
+		/*
+		 * Set up a page table only if it won't overwrite ourself.
+		 * That means r4 < pc && r4 - 16k page directory > &_end.
+		 * Given that r4 > &_end is most unfrequent, we add a rough
+		 * additional 1MB of room for a possible appended DTB.
+		 */
+		mov	r0, pc
+		cmp	r0, r4
+		ldrcc	r0, LC0+32
+		addcc	r0, r0, pc
+		cmpcc	r4, r0
+		orrcc	r4, r4, #1		@ remember we skipped cache_on
+		blcs	cache_on
 
 restart:	adr	r0, LC0
 		ldmia	r0, {r1, r2, r3, r6, r10, r11, r12}
@@ -229,7 +236,7 @@ restart:	adr	r0, LC0
  *   r0  = delta
  *   r2  = BSS start
  *   r3  = BSS end
- *   r4  = final kernel address
+ *   r4  = final kernel address (possibly with LSB set)
  *   r5  = appended dtb size (still unknown)
  *   r6  = _edata
  *   r7  = architecture ID
@@ -277,6 +284,7 @@ restart:	adr	r0, LC0
 		 */
 		cmp	r0, #1
 		sub	r0, r4, #TEXT_OFFSET
+		bic	r0, r0, #1
 		add	r0, r0, #0x100
 		mov	r1, r6
 		sub	r2, sp, r6
@@ -323,12 +331,13 @@ dtb_check_done:
 
 /*
  * Check to see if we will overwrite ourselves.
- *   r4  = final kernel address
+ *   r4  = final kernel address (possibly with LSB set)
  *   r9  = size of decompressed image
  *   r10 = end of this image, including  bss/stack/malloc space if non XIP
  * We basically want:
  *   r4 - 16k page directory >= r10 -> OK
  *   r4 + image length <= address of wont_overwrite -> OK
+ * Note: the possible LSB in r4 is harmless here.
  */
 		add	r10, r10, #16384
 		cmp	r4, r10
@@ -390,7 +399,8 @@ dtb_check_done:
 		add	sp, sp, r6
 #endif
 
-		bl	cache_clean_flush
+		tst	r4, #1
+		bleq	cache_clean_flush
 
 		adr	r0, BSYM(restart)
 		add	r0, r0, r6
@@ -402,7 +412,7 @@ wont_overwrite:
  *   r0  = delta
  *   r2  = BSS start
  *   r3  = BSS end
- *   r4  = kernel execution address
+ *   r4  = kernel execution address (possibly with LSB set)
  *   r5  = appended dtb size (0 if not present)
  *   r7  = architecture ID
  *   r8  = atags pointer
@@ -465,6 +475,15 @@ not_relocated:	mov	r0, #0
 		cmp	r2, r3
 		blo	1b
 
+		/*
+		 * Did we skip the cache setup earlier?
+		 * That is indicated by the LSB in r4.
+		 * Do it now if so.
+		 */
+		tst	r4, #1
+		bic	r4, r4, #1
+		blne	cache_on
+
 /*
  * The C runtime environment should now be setup sufficiently.
  * Set up some pointers, and start decompressing.
@@ -513,6 +532,7 @@ LC0:		.word	LC0			@ r1
 		.word	_got_start		@ r11
 		.word	_got_end		@ ip
 		.word	.L_user_stack_end	@ sp
+		.word	_end - restart + 16384 + 1024*1024
 		.size	LC0, . - LC0
 
 #ifdef CONFIG_ARCH_RPC
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/compressed/head-shmobile.S linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/head-shmobile.S
--- linux-libre-3.10-gnu/arch/arm/boot/compressed/head-shmobile.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/head-shmobile.S	2013-08-25 20:43:22.000000000 -0400
@@ -46,7 +46,7 @@ __image_start:
 __image_end:
 	.long	_got_end
 __load_base:
-	.long	CONFIG_MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
+	.long	MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
 __loaded:
 	.long	__continue
 	.align
@@ -55,26 +55,9 @@ __tmp_stack:
 __continue:
 #endif /* CONFIG_ZBOOT_ROM_MMC || CONFIG_ZBOOT_ROM_SH_MOBILE_SDHI */
 
-	b	1f
-__atags:@ tag #1
-	.long	12			@ tag->hdr.size = tag_size(tag_core);
-	.long	0x54410001		@ tag->hdr.tag = ATAG_CORE;
-	.long   0			@ tag->u.core.flags = 0;
-	.long	0			@ tag->u.core.pagesize = 0;
-	.long	0			@ tag->u.core.rootdev = 0;
-	@ tag #2
-	.long	8			@ tag->hdr.size = tag_size(tag_mem32);
-	.long	0x54410002		@ tag->hdr.tag = ATAG_MEM;
-	.long	CONFIG_MEMORY_SIZE	@ tag->u.mem.size = CONFIG_MEMORY_SIZE;
-	.long	CONFIG_MEMORY_START	@ @ tag->u.mem.start = CONFIG_MEMORY_START;
-	@ tag #3
-	.long	0			@ tag->hdr.size = 0
-	.long	0			@ tag->hdr.tag = ATAG_NONE;
-1:
-
 	/* Set board ID necessary for boot */
 	ldr	r7, 1f				@ Set machine type register
-	adr	r8, __atags			@ Set atag register
+	mov	r8, #0				@ pass null pointer as atag
 	b	2f
 
 1 :	.long MACH_TYPE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/compressed/Makefile linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/Makefile
--- linux-libre-3.10-gnu/arch/arm/boot/compressed/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@ OBJS	+= misc.o decompress.o
 ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
 OBJS	+= debug.o
 endif
-FONTC	= $(srctree)/drivers/video/console/font_acorn_8x8.c
+FONTC	= $(srctree)/lib/fonts/font_acorn_8x8.c
 
 # string library code (-Os is enforced to keep it much smaller)
 OBJS		+= string.o
@@ -91,6 +91,7 @@ suffix_$(CONFIG_KERNEL_GZIP) = gzip
 suffix_$(CONFIG_KERNEL_LZO)  = lzo
 suffix_$(CONFIG_KERNEL_LZMA) = lzma
 suffix_$(CONFIG_KERNEL_XZ)   = xzkern
+suffix_$(CONFIG_KERNEL_LZ4)  = lz4
 
 # Borrowed libfdt files for the ATAG compatibility mode
 
@@ -115,7 +116,7 @@ targets       := vmlinux vmlinux.lds \
 		 font.o font.c head.o misc.o $(OBJS)
 
 # Make sure files are removed during clean
-extra-y       += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \
+extra-y       += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern piggy.lz4 \
 		 lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) \
 		 hyp-stub.S
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/compressed/piggy.lz4.S linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/piggy.lz4.S
--- linux-libre-3.10-gnu/arch/arm/boot/compressed/piggy.lz4.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/compressed/piggy.lz4.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,6 @@
+	.section .piggydata,#alloc
+	.globl	input_data
+input_data:
+	.incbin	"arch/arm/boot/compressed/piggy.lz4"
+	.globl	input_data_end
+input_data_end:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/aks-cdu.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/aks-cdu.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/aks-cdu.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/aks-cdu.dts	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,7 @@
 
 /dts-v1/;
 
-/include/ "ge863-pro3.dtsi"
+#include "ge863-pro3.dtsi"
 
 / {
 	chosen {
@@ -46,7 +46,7 @@
 			};
 
 			usb1: gadget@fffa4000 {
-				atmel,vbus-gpio = <&pioC 15 0>;
+				atmel,vbus-gpio = <&pioC 15 GPIO_ACTIVE_HIGH>;
 				status = "okay";
 			};
 		};
@@ -90,23 +90,23 @@
 		compatible = "gpio-leds";
 
 		red {
-			gpios = <&pioC 10 0>;
+			gpios = <&pioC 10 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "none";
 		};
 
 		green {
-			gpios = <&pioA 5 1>;
+			gpios = <&pioA 5 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "none";
 			default-state = "on";
 		};
 
 		yellow {
-			gpios = <&pioB 20 1>;
+			gpios = <&pioB 20 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "none";
 		};
 
 		blue {
-			gpios = <&pioB 21 1>;
+			gpios = <&pioB 21 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "none";
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/am335x-bone.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am335x-bone.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/am335x-bone.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am335x-bone.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "am33xx.dtsi"
+#include "am33xx.dtsi"
 
 / {
 	model = "TI AM335x BeagleBone";
@@ -26,24 +26,104 @@
 
 	am33xx_pinmux: pinmux@44e10800 {
 		pinctrl-names = "default";
-		pinctrl-0 = <&user_leds_s0>;
+		pinctrl-0 = <&clkout2_pin>;
 
 		user_leds_s0: user_leds_s0 {
 			pinctrl-single,pins = <
-				0x54 0x7	/* gpmc_a5.gpio1_21, OUTPUT | MODE7 */
-				0x58 0x17	/* gpmc_a6.gpio1_22, OUTPUT_PULLUP | MODE7 */
-				0x5c 0x7	/* gpmc_a7.gpio1_23, OUTPUT | MODE7 */
-				0x60 0x17	/* gpmc_a8.gpio1_24, OUTPUT_PULLUP | MODE7 */
+				0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a5.gpio1_21 */
+				0x58 (PIN_OUTPUT_PULLUP | MUX_MODE7)	/* gpmc_a6.gpio1_22 */
+				0x5c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a7.gpio1_23 */
+				0x60 (PIN_OUTPUT_PULLUP | MUX_MODE7)	/* gpmc_a8.gpio1_24 */
+			>;
+		};
+
+		i2c0_pins: pinmux_i2c0_pins {
+			pinctrl-single,pins = <
+				0x188 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_sda.i2c0_sda */
+				0x18c (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
+			>;
+		};
+
+		uart0_pins: pinmux_uart0_pins {
+			pinctrl-single,pins = <
+				0x170 (PIN_INPUT_PULLUP | MUX_MODE0)	/* uart0_rxd.uart0_rxd */
+				0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* uart0_txd.uart0_txd */
+			>;
+		};
+
+		clkout2_pin: pinmux_clkout2_pin {
+			pinctrl-single,pins = <
+				0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)	/* xdma_event_intr1.clkout2 */
+			>;
+		};
+
+		cpsw_default: cpsw_default {
+			pinctrl-single,pins = <
+				/* Slave 1 */
+				0x110 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxerr.mii1_rxerr */
+				0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txen.mii1_txen */
+				0x118 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxdv.mii1_rxdv */
+				0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd3.mii1_txd3 */
+				0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd2.mii1_txd2 */
+				0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd1.mii1_txd1 */
+				0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mii1_txd0.mii1_txd0 */
+				0x12c (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_txclk.mii1_txclk */
+				0x130 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxclk.mii1_rxclk */
+				0x134 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd3.mii1_rxd3 */
+				0x138 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd2.mii1_rxd2 */
+				0x13c (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd1.mii1_rxd1 */
+				0x140 (PIN_INPUT_PULLUP | MUX_MODE0)	/* mii1_rxd0.mii1_rxd0 */
+			>;
+		};
+
+		cpsw_sleep: cpsw_sleep {
+			pinctrl-single,pins = <
+				/* Slave 1 reset value */
+				0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			>;
+		};
+
+		davinci_mdio_default: davinci_mdio_default {
+			pinctrl-single,pins = <
+				/* MDIO */
+				0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data.mdio_data */
+				0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk.mdio_clk */
+			>;
+		};
+
+		davinci_mdio_sleep: davinci_mdio_sleep {
+			pinctrl-single,pins = <
+				/* MDIO reset value */
+				0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
 			>;
 		};
 	};
 
 	ocp {
-		uart1: serial@44e09000 {
+		uart0: serial@44e09000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_pins>;
+
 			status = "okay";
 		};
 
 		i2c0: i2c@44e0b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins>;
+
 			status = "okay";
 			clock-frequency = <400000>;
 
@@ -55,31 +135,34 @@
 	};
 
 	leds {
+		pinctrl-names = "default";
+		pinctrl-0 = <&user_leds_s0>;
+
 		compatible = "gpio-leds";
 
 		led@2 {
 			label = "beaglebone:green:heartbeat";
-			gpios = <&gpio1 21 0>;
+			gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 			default-state = "off";
 		};
 
 		led@3 {
 			label = "beaglebone:green:mmc0";
-			gpios = <&gpio1 22 0>;
+			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "mmc0";
 			default-state = "off";
 		};
 
 		led@4 {
 			label = "beaglebone:green:usr2";
-			gpios = <&gpio1 23 0>;
+			gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
 
 		led@5 {
 			label = "beaglebone:green:usr3";
-			gpios = <&gpio1 24 0>;
+			gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
 	};
@@ -131,8 +214,23 @@
 
 &cpsw_emac0 {
 	phy_id = <&davinci_mdio>, <0>;
+	phy-mode = "mii";
 };
 
 &cpsw_emac1 {
 	phy_id = <&davinci_mdio>, <1>;
+	phy-mode = "mii";
+};
+
+&mac {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&cpsw_default>;
+	pinctrl-1 = <&cpsw_sleep>;
+
+};
+
+&davinci_mdio {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&davinci_mdio_default>;
+	pinctrl-1 = <&davinci_mdio_sleep>;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/am335x-evm.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am335x-evm.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/am335x-evm.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am335x-evm.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "am33xx.dtsi"
+#include "am33xx.dtsi"
 
 / {
 	model = "TI AM335x EVM";
@@ -26,32 +26,143 @@
 
 	am33xx_pinmux: pinmux@44e10800 {
 		pinctrl-names = "default";
-		pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0>;
+		pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0 &clkout2_pin>;
 
 		matrix_keypad_s0: matrix_keypad_s0 {
 			pinctrl-single,pins = <
-				0x54 0x7	/* gpmc_a5.gpio1_21, OUTPUT | MODE7 */
-				0x58 0x7	/* gpmc_a6.gpio1_22, OUTPUT | MODE7 */
-				0x64 0x27	/* gpmc_a9.gpio1_25, INPUT | MODE7 */
-				0x68 0x27	/* gpmc_a10.gpio1_26, INPUT | MODE7 */
-				0x6c 0x27	/* gpmc_a11.gpio1_27, INPUT | MODE7 */
+				0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a5.gpio1_21 */
+				0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a6.gpio1_22 */
+				0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a9.gpio1_25 */
+				0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a10.gpio1_26 */
+				0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_a11.gpio1_27 */
 			>;
 		};
 
 		volume_keys_s0: volume_keys_s0 {
 			pinctrl-single,pins = <
-				0x150 0x27	/* spi0_sclk.gpio0_2, INPUT | MODE7 */
-				0x154 0x27	/* spi0_d0.gpio0_3, INPUT | MODE7 */
+				0x150 (PIN_INPUT_PULLDOWN | MUX_MODE7)	/* spi0_sclk.gpio0_2 */
+				0x154 (PIN_INPUT_PULLDOWN | MUX_MODE7)	/* spi0_d0.gpio0_3 */
+			>;
+		};
+
+		i2c0_pins: pinmux_i2c0_pins {
+			pinctrl-single,pins = <
+				0x188 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_sda.i2c0_sda */
+				0x18c (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
+			>;
+		};
+
+		i2c1_pins: pinmux_i2c1_pins {
+			pinctrl-single,pins = <
+				0x158 (PIN_INPUT_PULLUP | MUX_MODE2)	/* spi0_d1.i2c1_sda */
+				0x15c (PIN_INPUT_PULLUP | MUX_MODE2)	/* spi0_cs0.i2c1_scl */
+			>;
+		};
+
+		uart0_pins: pinmux_uart0_pins {
+			pinctrl-single,pins = <
+				0x170 (PIN_INPUT_PULLUP | MUX_MODE0)	/* uart0_rxd.uart0_rxd */
+				0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* uart0_txd.uart0_txd */
+			>;
+		};
+
+		clkout2_pin: pinmux_clkout2_pin {
+			pinctrl-single,pins = <
+				0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)	/* xdma_event_intr1.clkout2 */
+			>;
+		};
+
+		nandflash_pins_s0: nandflash_pins_s0 {
+			pinctrl-single,pins = <
+				0x0 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad0.gpmc_ad0 */
+				0x4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad1.gpmc_ad1 */
+				0x8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad2.gpmc_ad2 */
+				0xc (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad3.gpmc_ad3 */
+				0x10 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad4.gpmc_ad4 */
+				0x14 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad5.gpmc_ad5 */
+				0x18 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad6.gpmc_ad6 */
+				0x1c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad7.gpmc_ad7 */
+				0x70 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_wait0.gpmc_wait0 */
+				0x74 (PIN_INPUT_PULLUP | MUX_MODE7)	/* gpmc_wpn.gpio0_30 */
+				0x7c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_csn0.gpmc_csn0  */
+				0x90 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_advn_ale.gpmc_advn_ale */
+				0x94 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_oen_ren.gpmc_oen_ren */
+				0x98 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_wen.gpmc_wen */
+				0x9c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_be0n_cle.gpmc_be0n_cle */
+			>;
+		};
+
+		ecap0_pins: backlight_pins {
+			pinctrl-single,pins = <
+				0x164 0x0	/* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */
+			>;
+		};
+
+		cpsw_default: cpsw_default {
+			pinctrl-single,pins = <
+				/* Slave 1 */
+				0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txen.rgmii1_tctl */
+				0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxdv.rgmii1_rctl */
+				0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd3.rgmii1_td3 */
+				0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd2.rgmii1_td2 */
+				0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd1.rgmii1_td1 */
+				0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd0.rgmii1_td0 */
+				0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txclk.rgmii1_tclk */
+				0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxclk.rgmii1_rclk */
+				0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd3.rgmii1_rd3 */
+				0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd2.rgmii1_rd2 */
+				0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd1.rgmii1_rd1 */
+				0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd0.rgmii1_rd0 */
+			>;
+		};
+
+		cpsw_sleep: cpsw_sleep {
+			pinctrl-single,pins = <
+				/* Slave 1 reset value */
+				0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			>;
+		};
+
+		davinci_mdio_default: davinci_mdio_default {
+			pinctrl-single,pins = <
+				/* MDIO */
+				0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data.mdio_data */
+				0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk.mdio_clk */
+			>;
+		};
+
+		davinci_mdio_sleep: davinci_mdio_sleep {
+			pinctrl-single,pins = <
+				/* MDIO reset value */
+				0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
 			>;
 		};
 	};
 
 	ocp {
-		uart1: serial@44e09000 {
+		uart0: serial@44e09000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_pins>;
+
 			status = "okay";
 		};
 
 		i2c0: i2c@44e0b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins>;
+
 			status = "okay";
 			clock-frequency = <400000>;
 
@@ -61,6 +172,9 @@
 		};
 
 		i2c1: i2c@4802a000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c1_pins>;
+
 			status = "okay";
 			clock-frequency = <100000>;
 
@@ -102,6 +216,101 @@
 				reg = <0x48>;
 			};
 		};
+
+		elm: elm@48080000 {
+			status = "okay";
+		};
+
+		epwmss0: epwmss@48300000 {
+			status = "okay";
+
+			ecap0: ecap@48300100 {
+				status = "okay";
+				pinctrl-names = "default";
+				pinctrl-0 = <&ecap0_pins>;
+			};
+		};
+
+		gpmc: gpmc@50000000 {
+			status = "okay";
+			pinctrl-names = "default";
+			pinctrl-0 = <&nandflash_pins_s0>;
+			ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+			nand@0,0 {
+				reg = <0 0 0>; /* CS0, offset 0 */
+				nand-bus-width = <8>;
+				ti,nand-ecc-opt = "bch8";
+				gpmc,device-nand = "true";
+				gpmc,device-width = <1>;
+				gpmc,sync-clk-ps = <0>;
+				gpmc,cs-on-ns = <0>;
+				gpmc,cs-rd-off-ns = <44>;
+				gpmc,cs-wr-off-ns = <44>;
+				gpmc,adv-on-ns = <6>;
+				gpmc,adv-rd-off-ns = <34>;
+				gpmc,adv-wr-off-ns = <44>;
+				gpmc,we-on-ns = <0>;
+				gpmc,we-off-ns = <40>;
+				gpmc,oe-on-ns = <0>;
+				gpmc,oe-off-ns = <54>;
+				gpmc,access-ns = <64>;
+				gpmc,rd-cycle-ns = <82>;
+				gpmc,wr-cycle-ns = <82>;
+				gpmc,wait-on-read = "true";
+				gpmc,wait-on-write = "true";
+				gpmc,bus-turnaround-ns = <0>;
+				gpmc,cycle2cycle-delay-ns = <0>;
+				gpmc,clk-activation-ns = <0>;
+				gpmc,wait-monitoring-ns = <0>;
+				gpmc,wr-access-ns = <40>;
+				gpmc,wr-data-mux-bus-ns = <0>;
+
+				#address-cells = <1>;
+				#size-cells = <1>;
+				elm_id = <&elm>;
+
+				/* MTD partition table */
+				partition@0 {
+					label = "SPL1";
+					reg = <0x00000000 0x000020000>;
+				};
+
+				partition@1 {
+					label = "SPL2";
+					reg = <0x00020000 0x00020000>;
+				};
+
+				partition@2 {
+					label = "SPL3";
+					reg = <0x00040000 0x00020000>;
+				};
+
+				partition@3 {
+					label = "SPL4";
+					reg = <0x00060000 0x00020000>;
+				};
+
+				partition@4 {
+					label = "U-boot";
+					reg = <0x00080000 0x001e0000>;
+				};
+
+				partition@5 {
+					label = "environment";
+					reg = <0x00260000 0x00020000>;
+				};
+
+				partition@6 {
+					label = "Kernel";
+					reg = <0x00280000 0x00500000>;
+				};
+
+				partition@7 {
+					label = "File-System";
+					reg = <0x00780000 0x0F880000>;
+				};
+			};
+		};
 	};
 
 	vbat: fixedregulator@0 {
@@ -123,12 +332,12 @@
 		debounce-delay-ms = <5>;
 		col-scan-delay-us = <2>;
 
-		row-gpios = <&gpio1 25 0	/* Bank1, pin25 */
-			     &gpio1 26 0	/* Bank1, pin26 */
-			     &gpio1 27 0>;	/* Bank1, pin27 */
+		row-gpios = <&gpio1 25 GPIO_ACTIVE_HIGH		/* Bank1, pin25 */
+			     &gpio1 26 GPIO_ACTIVE_HIGH		/* Bank1, pin26 */
+			     &gpio1 27 GPIO_ACTIVE_HIGH>;	/* Bank1, pin27 */
 
-		col-gpios = <&gpio1 21 0	/* Bank1, pin21 */
-			     &gpio1 22 0>;	/* Bank1, pin22 */
+		col-gpios = <&gpio1 21 GPIO_ACTIVE_HIGH		/* Bank1, pin21 */
+			     &gpio1 22 GPIO_ACTIVE_HIGH>;	/* Bank1, pin22 */
 
 		linux,keymap = <0x0000008b	/* MENU */
 				0x0100009e	/* BACK */
@@ -147,20 +356,27 @@
 		switch@9 {
 			label = "volume-up";
 			linux,code = <115>;
-			gpios = <&gpio0 2 1>;
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
 			gpio-key,wakeup;
 		};
 
 		switch@10 {
 			label = "volume-down";
 			linux,code = <114>;
-			gpios = <&gpio0 3 1>;
+			gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
 			gpio-key,wakeup;
 		};
 	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&ecap0 0 50000 0>;
+		brightness-levels = <0 51 53 56 62 75 101 152 255>;
+		default-brightness-level = <8>;
+	};
 };
 
-/include/ "tps65910.dtsi"
+#include "tps65910.dtsi"
 
 &tps {
 	vcc1-supply = <&vbat>;
@@ -237,10 +453,38 @@
 	};
 };
 
+&mac {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&cpsw_default>;
+	pinctrl-1 = <&cpsw_sleep>;
+};
+
+&davinci_mdio {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&davinci_mdio_default>;
+	pinctrl-1 = <&davinci_mdio_sleep>;
+};
+
 &cpsw_emac0 {
 	phy_id = <&davinci_mdio>, <0>;
+	phy-mode = "rgmii-txid";
 };
 
 &cpsw_emac1 {
 	phy_id = <&davinci_mdio>, <1>;
+	phy-mode = "rgmii-txid";
+};
+
+&tscadc {
+	status = "okay";
+	tsc {
+		ti,wires = <4>;
+		ti,x-plate-resistance = <200>;
+		ti,coordiante-readouts = <5>;
+		ti,wire-config = <0x00 0x11 0x22 0x33>;
+	};
+
+	adc {
+		ti,adc-channels = <4 5 6 7>;
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/am335x-evmsk.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am335x-evmsk.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/am335x-evmsk.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am335x-evmsk.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 
 /dts-v1/;
 
-/include/ "am33xx.dtsi"
+#include "am33xx.dtsi"
 
 / {
 	model = "TI AM335x EVM-SK";
@@ -32,33 +32,145 @@
 
 	am33xx_pinmux: pinmux@44e10800 {
 		pinctrl-names = "default";
-		pinctrl-0 = <&user_leds_s0 &gpio_keys_s0>;
+		pinctrl-0 = <&gpio_keys_s0 &clkout2_pin>;
 
 		user_leds_s0: user_leds_s0 {
 			pinctrl-single,pins = <
-				0x10 0x7	/* gpmc_ad4.gpio1_4, OUTPUT | MODE7 */
-				0x14 0x7	/* gpmc_ad5.gpio1_5, OUTPUT | MODE7 */
-				0x18 0x7	/* gpmc_ad6.gpio1_6, OUTPUT | MODE7 */
-				0x1c 0x7	/* gpmc_ad7.gpio1_7, OUTPUT | MODE7 */
+				0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad4.gpio1_4 */
+				0x14 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad5.gpio1_5 */
+				0x18 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad6.gpio1_6 */
+				0x1c (PIN_OUTPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ad7.gpio1_7 */
 			>;
 		};
 
 		gpio_keys_s0: gpio_keys_s0 {
 			pinctrl-single,pins = <
-				0x94 0x27	/* gpmc_oen_ren.gpio2_3, INPUT | MODE7 */
-				0x90 0x27	/* gpmc_advn_ale.gpio2_2, INPUT | MODE7 */
-				0x70 0x27	/* gpmc_wait0.gpio0_30, INPUT | MODE7 */
-				0x9c 0x27	/* gpmc_ben0_cle.gpio2_5, INPUT | MODE7 */
+				0x94 (PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_oen_ren.gpio2_3 */
+				0x90 (PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_advn_ale.gpio2_2 */
+				0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_wait0.gpio0_30 */
+				0x9c (PIN_INPUT_PULLDOWN | MUX_MODE7)	/* gpmc_ben0_cle.gpio2_5 */
+			>;
+		};
+
+		i2c0_pins: pinmux_i2c0_pins {
+			pinctrl-single,pins = <
+				0x188 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_sda.i2c0_sda */
+				0x18c (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c0_scl.i2c0_scl */
+			>;
+		};
+
+		uart0_pins: pinmux_uart0_pins {
+			pinctrl-single,pins = <
+				0x170 (PIN_INPUT_PULLUP | MUX_MODE0)	/* uart0_rxd.uart0_rxd */
+				0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)		/* uart0_txd.uart0_txd */
+			>;
+		};
+
+		clkout2_pin: pinmux_clkout2_pin {
+			pinctrl-single,pins = <
+				0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3)		/* xdma_event_intr1.clkout2 */
+			>;
+		};
+
+		ecap2_pins: backlight_pins {
+			pinctrl-single,pins = <
+				0x19c 0x4	/* mcasp0_ahclkr.ecap2_in_pwm2_out MODE4 */
+			>;
+		};
+
+		cpsw_default: cpsw_default {
+			pinctrl-single,pins = <
+				/* Slave 1 */
+				0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txen.rgmii1_tctl */
+				0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxdv.rgmii1_rctl */
+				0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd3.rgmii1_td3 */
+				0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd2.rgmii1_td2 */
+				0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd1.rgmii1_td1 */
+				0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txd0.rgmii1_td0 */
+				0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* mii1_txclk.rgmii1_tclk */
+				0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxclk.rgmii1_rclk */
+				0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd3.rgmii1_rd3 */
+				0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd2.rgmii1_rd2 */
+				0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd1.rgmii1_rd1 */
+				0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* mii1_rxd0.rgmii1_rd0 */
+
+				/* Slave 2 */
+				0x40 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a0.rgmii2_tctl */
+				0x44 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a1.rgmii2_rctl */
+				0x48 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a2.rgmii2_td3 */
+				0x4c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a3.rgmii2_td2 */
+				0x50 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a4.rgmii2_td1 */
+				0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a5.rgmii2_td0 */
+				0x58 (PIN_OUTPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a6.rgmii2_tclk */
+				0x5c (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a7.rgmii2_rclk */
+				0x60 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a8.rgmii2_rd3 */
+				0x64 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a9.rgmii2_rd2 */
+				0x68 (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a10.rgmii2_rd1 */
+				0x6c (PIN_INPUT_PULLDOWN | MUX_MODE2)	/* gpmc_a11.rgmii2_rd0 */
+			>;
+		};
+
+		cpsw_sleep: cpsw_sleep {
+			pinctrl-single,pins = <
+				/* Slave 1 reset value */
+				0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+
+				/* Slave 2 reset value*/
+				0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7)
+			>;
+		};
+
+		davinci_mdio_default: davinci_mdio_default {
+			pinctrl-single,pins = <
+				/* MDIO */
+				0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)	/* mdio_data.mdio_data */
+				0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0)			/* mdio_clk.mdio_clk */
+			>;
+		};
+
+		davinci_mdio_sleep: davinci_mdio_sleep {
+			pinctrl-single,pins = <
+				/* MDIO reset value */
+				0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7)
+				0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
 			>;
 		};
 	};
 
 	ocp {
-		uart1: serial@44e09000 {
+		uart0: serial@44e09000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_pins>;
+
 			status = "okay";
 		};
 
 		i2c0: i2c@44e0b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins>;
+
 			status = "okay";
 			clock-frequency = <400000>;
 
@@ -94,6 +206,16 @@
 				st,max-limit-z = <750>;
 			};
 		};
+
+		epwmss2: epwmss@48304000 {
+			status = "okay";
+
+			ecap2: ecap@48304100 {
+				status = "okay";
+				pinctrl-names = "default";
+				pinctrl-0 = <&ecap2_pins>;
+			};
+		};
 	};
 
 	vbat: fixedregulator@0 {
@@ -111,30 +233,33 @@
 	};
 
 	leds {
+		pinctrl-names = "default";
+		pinctrl-0 = <&user_leds_s0>;
+
 		compatible = "gpio-leds";
 
 		led@1 {
 			label = "evmsk:green:usr0";
-			gpios = <&gpio1 4 0>;
+			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
 
 		led@2 {
 			label = "evmsk:green:usr1";
-			gpios = <&gpio1 5 0>;
+			gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
 		};
 
 		led@3 {
 			label = "evmsk:green:mmc0";
-			gpios = <&gpio1 6 0>;
+			gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "mmc0";
 			default-state = "off";
 		};
 
 		led@4 {
 			label = "evmsk:green:heartbeat";
-			gpios = <&gpio1 7 0>;
+			gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 			default-state = "off";
 		};
@@ -148,31 +273,38 @@
 		switch@1 {
 			label = "button0";
 			linux,code = <0x100>;
-			gpios = <&gpio2 3 0>;
+			gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
 		};
 
 		switch@2 {
 			label = "button1";
 			linux,code = <0x101>;
-			gpios = <&gpio2 2 0>;
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
 		};
 
 		switch@3 {
 			label = "button2";
 			linux,code = <0x102>;
-			gpios = <&gpio0 30 0>;
+			gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
 			gpio-key,wakeup;
 		};
 
 		switch@4 {
 			label = "button3";
 			linux,code = <0x103>;
-			gpios = <&gpio2 5 0>;
+			gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
 		};
 	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&ecap2 0 50000 1>;
+		brightness-levels = <0 58 61 66 75 90 125 170 255>;
+		default-brightness-level = <8>;
+	};
 };
 
-/include/ "tps65910.dtsi"
+#include "tps65910.dtsi"
 
 &tps {
 	vcc1-supply = <&vbat>;
@@ -248,3 +380,25 @@
 		};
 	};
 };
+
+&mac {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&cpsw_default>;
+	pinctrl-1 = <&cpsw_sleep>;
+};
+
+&davinci_mdio {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&davinci_mdio_default>;
+	pinctrl-1 = <&davinci_mdio_sleep>;
+};
+
+&cpsw_emac0 {
+	phy_id = <&davinci_mdio>, <0>;
+	phy-mode = "rgmii-txid";
+};
+
+&cpsw_emac1 {
+	phy_id = <&davinci_mdio>, <1>;
+	phy-mode = "rgmii-txid";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/am33xx.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am33xx.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/am33xx.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am33xx.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,26 +8,33 @@
  * kind, whether express or implied.
  */
 
-/include/ "skeleton.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/am33xx.h>
+
+#include "skeleton.dtsi"
 
 / {
 	compatible = "ti,am33xx";
 	interrupt-parent = <&intc>;
 
 	aliases {
-		serial0 = &uart1;
-		serial1 = &uart2;
-		serial2 = &uart3;
-		serial3 = &uart4;
-		serial4 = &uart5;
-		serial5 = &uart6;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		serial5 = &uart5;
 		d_can0 = &dcan0;
 		d_can1 = &dcan1;
 	};
 
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 		cpu@0 {
 			compatible = "arm,cortex-a8";
+			device_type = "cpu";
+			reg = <0>;
 
 			/*
 			 * To consider voltage drop between PMIC and SoC,
@@ -133,7 +140,7 @@
 			interrupts = <62>;
 		};
 
-		uart1: serial@44e09000 {
+		uart0: serial@44e09000 {
 			compatible = "ti,omap3-uart";
 			ti,hwmods = "uart1";
 			clock-frequency = <48000000>;
@@ -142,7 +149,7 @@
 			status = "disabled";
 		};
 
-		uart2: serial@48022000 {
+		uart1: serial@48022000 {
 			compatible = "ti,omap3-uart";
 			ti,hwmods = "uart2";
 			clock-frequency = <48000000>;
@@ -151,7 +158,7 @@
 			status = "disabled";
 		};
 
-		uart3: serial@48024000 {
+		uart2: serial@48024000 {
 			compatible = "ti,omap3-uart";
 			ti,hwmods = "uart3";
 			clock-frequency = <48000000>;
@@ -160,7 +167,7 @@
 			status = "disabled";
 		};
 
-		uart4: serial@481a6000 {
+		uart3: serial@481a6000 {
 			compatible = "ti,omap3-uart";
 			ti,hwmods = "uart4";
 			clock-frequency = <48000000>;
@@ -169,7 +176,7 @@
 			status = "disabled";
 		};
 
-		uart5: serial@481a8000 {
+		uart4: serial@481a8000 {
 			compatible = "ti,omap3-uart";
 			ti,hwmods = "uart5";
 			clock-frequency = <48000000>;
@@ -178,7 +185,7 @@
 			status = "disabled";
 		};
 
-		uart6: serial@481aa000 {
+		uart5: serial@481aa000 {
 			compatible = "ti,omap3-uart";
 			ti,hwmods = "uart6";
 			clock-frequency = <48000000>;
@@ -343,6 +350,90 @@
 			ti,hwmods = "usb_otg_hs";
 		};
 
+		epwmss0: epwmss@48300000 {
+			compatible = "ti,am33xx-pwmss";
+			reg = <0x48300000 0x10>;
+			ti,hwmods = "epwmss0";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			status = "disabled";
+			ranges = <0x48300100 0x48300100 0x80   /* ECAP */
+				  0x48300180 0x48300180 0x80   /* EQEP */
+				  0x48300200 0x48300200 0x80>; /* EHRPWM */
+
+			ecap0: ecap@48300100 {
+				compatible = "ti,am33xx-ecap";
+				#pwm-cells = <3>;
+				reg = <0x48300100 0x80>;
+				ti,hwmods = "ecap0";
+				status = "disabled";
+			};
+
+			ehrpwm0: ehrpwm@48300200 {
+				compatible = "ti,am33xx-ehrpwm";
+				#pwm-cells = <3>;
+				reg = <0x48300200 0x80>;
+				ti,hwmods = "ehrpwm0";
+				status = "disabled";
+			};
+		};
+
+		epwmss1: epwmss@48302000 {
+			compatible = "ti,am33xx-pwmss";
+			reg = <0x48302000 0x10>;
+			ti,hwmods = "epwmss1";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			status = "disabled";
+			ranges = <0x48302100 0x48302100 0x80   /* ECAP */
+				  0x48302180 0x48302180 0x80   /* EQEP */
+				  0x48302200 0x48302200 0x80>; /* EHRPWM */
+
+			ecap1: ecap@48302100 {
+				compatible = "ti,am33xx-ecap";
+				#pwm-cells = <3>;
+				reg = <0x48302100 0x80>;
+				ti,hwmods = "ecap1";
+				status = "disabled";
+			};
+
+			ehrpwm1: ehrpwm@48302200 {
+				compatible = "ti,am33xx-ehrpwm";
+				#pwm-cells = <3>;
+				reg = <0x48302200 0x80>;
+				ti,hwmods = "ehrpwm1";
+				status = "disabled";
+			};
+		};
+
+		epwmss2: epwmss@48304000 {
+			compatible = "ti,am33xx-pwmss";
+			reg = <0x48304000 0x10>;
+			ti,hwmods = "epwmss2";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			status = "disabled";
+			ranges = <0x48304100 0x48304100 0x80   /* ECAP */
+				  0x48304180 0x48304180 0x80   /* EQEP */
+				  0x48304200 0x48304200 0x80>; /* EHRPWM */
+
+			ecap2: ecap@48304100 {
+				compatible = "ti,am33xx-ecap";
+				#pwm-cells = <3>;
+				reg = <0x48304100 0x80>;
+				ti,hwmods = "ecap2";
+				status = "disabled";
+			};
+
+			ehrpwm2: ehrpwm@48304200 {
+				compatible = "ti,am33xx-ehrpwm";
+				#pwm-cells = <3>;
+				reg = <0x48304200 0x80>;
+				ti,hwmods = "ehrpwm2";
+				status = "disabled";
+			};
+		};
+
 		mac: ethernet@4a100000 {
 			compatible = "ti,cpsw";
 			ti,hwmods = "cpgmac0";
@@ -394,7 +485,6 @@
 			compatible = "ti,am3352-ocmcram";
 			reg = <0x40300000 0x10000>;
 			ti,hwmods = "ocmcram";
-			ti,no_idle_on_suspend;
 		};
 
 		wkup_m3: wkup_m3@44d00000 {
@@ -404,6 +494,31 @@
 			ti,hwmods = "wkup_m3";
 		};
 
+		elm: elm@48080000 {
+			compatible = "ti,am3352-elm";
+			reg = <0x48080000 0x2000>;
+			interrupts = <4>;
+			ti,hwmods = "elm";
+			status = "disabled";
+		};
+
+		tscadc: tscadc@44e0d000 {
+			compatible = "ti,am3359-tscadc";
+			reg = <0x44e0d000 0x1000>;
+			interrupt-parent = <&intc>;
+			interrupts = <16>;
+			ti,hwmods = "adc_tsc";
+			status = "disabled";
+
+			tsc {
+				compatible = "ti,am3359-tsc";
+			};
+			am335x_adc: adc {
+				#io-channel-cells = <1>;
+				compatible = "ti,am3359-adc";
+			};
+		};
+
 		gpmc: gpmc@50000000 {
 			compatible = "ti,am3352-gpmc";
 			ti,hwmods = "gpmc";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/am3517-evm.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am3517-evm.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/am3517-evm.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am3517-evm.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap34xx.dtsi"
+#include "omap34xx.dtsi"
 
 / {
 	model = "TI AM3517 EVM (AM3517/05)";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/am3517_mt_ventoux.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am3517_mt_ventoux.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/am3517_mt_ventoux.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am3517_mt_ventoux.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap34xx.dtsi"
+#include "omap34xx.dtsi"
 
 / {
 	model = "TeeJet Mt.Ventoux";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/am4372.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am4372.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/am4372.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am4372.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,68 @@
+/*
+ * Device Tree Source for AM4372 SoC
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "ti,am4372", "ti,am43";
+	interrupt-parent = <&gic>;
+
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	cpus {
+		cpu@0 {
+			compatible = "arm,cortex-a9";
+		};
+	};
+
+	gic: interrupt-controller@48241000 {
+		compatible = "arm,cortex-a9-gic";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		reg = <0x48241000 0x1000>,
+		      <0x48240100 0x0100>;
+	};
+
+	ocp {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		uart0: serial@44e09000 {
+			compatible = "ti,am4372-uart","ti,omap2-uart";
+			reg = <0x44e09000 0x2000>;
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		timer1: timer@44e31000 {
+			compatible = "ti,am4372-timer-1ms","ti,am335x-timer-1ms";
+			reg = <0x44e31000 0x400>;
+			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+			ti,timer-alwon;
+		};
+
+		timer2: timer@48040000  {
+			compatible = "ti,am4372-timer","ti,am335x-timer";
+			reg = <0x48040000  0x400>;
+			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		counter32k: counter@44e86000 {
+			compatible = "ti,am4372-counter32k","ti,omap-counter32k";
+			reg = <0x44e86000 0x40>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/am43x-epos-evm.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am43x-epos-evm.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/am43x-epos-evm.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/am43x-epos-evm.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* AM43x EPOS EVM */
+
+/dts-v1/;
+
+#include "am4372.dtsi"
+
+/ {
+	model = "TI AM43x EPOS EVM";
+	compatible = "ti,am43x-epos-evm","ti,am4372","ti,am43";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/animeo_ip.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/animeo_ip.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/animeo_ip.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/animeo_ip.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 
 /dts-v1/;
-/include/ "at91sam9260.dtsi"
+#include "at91sam9260.dtsi"
 
 / {
 	model = "Somfy Animeo IP";
@@ -123,7 +123,7 @@
 
 		usb0: ohci@00500000 {
 			num-ports = <2>;
-			atmel,vbus-gpio = <&pioB 15 1>;
+			atmel,vbus-gpio = <&pioB 15 GPIO_ACTIVE_LOW>;
 			status = "okay";
 		};
 	};
@@ -133,23 +133,23 @@
 
 		power_green {
 			label = "power_green";
-			gpios = <&pioC 17 0>;
+			gpios = <&pioC 17 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 
 		power_red {
 			label = "power_red";
-			gpios = <&pioA 2 0>;
+			gpios = <&pioA 2 GPIO_ACTIVE_HIGH>;
 		};
 
 		tx_green {
 			label = "tx_green";
-			gpios = <&pioC 19 0>;
+			gpios = <&pioC 19 GPIO_ACTIVE_HIGH>;
 		};
 
 		tx_red {
 			label = "tx_red";
-			gpios = <&pioC 18 0>;
+			gpios = <&pioC 18 GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -160,21 +160,21 @@
 
 		keyswitch_in {
 			label = "keyswitch_in";
-			gpios = <&pioB 1 0>;
+			gpios = <&pioB 1 GPIO_ACTIVE_HIGH>;
 			linux,code = <28>;
 			gpio-key,wakeup;
 		};
 
 		error_in {
 			label = "error_in";
-			gpios = <&pioB 2 0>;
+			gpios = <&pioB 2 GPIO_ACTIVE_HIGH>;
 			linux,code = <29>;
 			gpio-key,wakeup;
 		};
 
 		btn {
 			label = "btn";
-			gpios = <&pioC 23 0>;
+			gpios = <&pioC 23 GPIO_ACTIVE_HIGH>;
 			linux,code = <31>;
 			gpio-key,wakeup;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370-db.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370-db.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370-db.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370-db.dts	2013-08-25 20:43:22.000000000 -0400
@@ -74,6 +74,7 @@
 				 */
 				status = "disabled";
 				/* No CD or WP GPIOs */
+				broken-cd;
 			};
 
 			usb@50000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -180,10 +180,6 @@
 
 				bus-range = <0x00 0xff>;
 
-				reg = <0x40000 0x2000>, <0x80000 0x2000>;
-
-				reg-names = "pcie0.0", "pcie1.0";
-
 				ranges = <0x82000000 0 0x40000 0x40000 0 0x00002000   /* Port 0.0 registers */
 					0x82000000 0 0x80000 0x80000 0 0x00002000   /* Port 1.0 registers */
 					0x82000000 0 0xe0000000 0xe0000000 0 0x08000000   /* non-prefetchable memory */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370-mirabox.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370-mirabox.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370-mirabox.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370-mirabox.dts	2013-08-25 20:43:22.000000000 -0400
@@ -99,6 +99,7 @@
 				 * No CD or WP GPIOs: SDIO interface used for
 				 * Wifi/Bluetooth chip
 				 */
+				 broken-cd;
 			};
 
 			usb@50000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370-rd.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370-rd.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370-rd.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370-rd.dts	2013-08-25 20:43:22.000000000 -0400
@@ -64,6 +64,7 @@
 				pinctrl-names = "default";
 				status = "okay";
 				/* No CD or WP GPIOs */
+				broken-cd;
 			};
 
 			usb@50000 {
@@ -84,6 +85,22 @@
 					gpios = <&gpio0 6 1>;
 				};
 			};
+
+			pcie-controller {
+				status = "okay";
+
+				/* Internal mini-PCIe connector */
+				pcie@1,0 {
+					/* Port 0, Lane 0 */
+					status = "okay";
+				};
+
+				/* Internal mini-PCIe connector */
+				pcie@2,0 {
+					/* Port 1, Lane 0 */
+					status = "okay";
+				};
+			};
 		};
 	};
  };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370-xp.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370-xp.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-370-xp.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-370-xp.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -22,9 +22,18 @@
 	model = "Marvell Armada 370 and XP SoC";
 	compatible = "marvell,armada-370-xp";
 
+	aliases {
+		eth0 = &eth0;
+		eth1 = &eth1;
+	};
+
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 		cpu@0 {
 			compatible = "marvell,sheeva-v7";
+			device_type = "cpu";
+			reg = <0>;
 		};
 	};
 
@@ -80,7 +89,7 @@
 
 			sata@a0000 {
 				compatible = "marvell,orion-sata";
-				reg = <0xa0000 0x2400>;
+				reg = <0xa0000 0x5000>;
 				interrupts = <55>;
 				clocks = <&gateclk 15>, <&gateclk 30>;
 				clock-names = "0", "1";
@@ -94,17 +103,17 @@
 				reg = <0x72004 0x4>;
 			};
 
-			ethernet@70000 {
+			eth0: ethernet@70000 {
 				compatible = "marvell,armada-370-neta";
-				reg = <0x70000 0x2500>;
+				reg = <0x70000 0x4000>;
 				interrupts = <8>;
 				clocks = <&gateclk 4>;
 				status = "disabled";
 			};
 
-			ethernet@74000 {
+			eth1: ethernet@74000 {
 				compatible = "marvell,armada-370-neta";
-				reg = <0x74000 0x2500>;
+				reg = <0x74000 0x4000>;
 				interrupts = <10>;
 				clocks = <&gateclk 3>;
 				status = "disabled";
@@ -143,6 +152,10 @@
 				reg = <0xd4000 0x200>;
 				interrupts = <54>;
 				clocks = <&gateclk 17>;
+				bus-width = <4>;
+				cap-sdio-irq;
+				cap-sd-highspeed;
+				cap-mmc-highspeed;
 				status = "disabled";
 			};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-db.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-db.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-db.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-db.dts	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,10 @@
 	};
 
 	soc {
+		ranges = <0          0 0xd0000000 0x100000	/* Internal registers 1MiB */
+			  0xe0000000 0 0xe0000000 0x8100000     /* PCIe */
+			  0xf0000000 0 0xf0000000 0x1000000>;	/* Device Bus, NOR 16MiB   */
+
 		internal-regs {
 			serial@12000 {
 				clock-frequency = <250000000>;
@@ -97,6 +101,7 @@
 				pinctrl-names = "default";
 				status = "okay";
 				/* No CD or WP GPIOs */
+				broken-cd;
 			};
 
 			usb@50000 {
@@ -155,6 +160,35 @@
 					status = "okay";
 				};
 			};
+
+			devbus-bootcs@10400 {
+				status = "okay";
+				ranges = <0 0xf0000000 0x1000000>;
+
+				/* Device Bus parameters are required */
+
+				/* Read parameters */
+				devbus,bus-width    = <8>;
+				devbus,turn-off-ps  = <60000>;
+				devbus,badr-skew-ps = <0>;
+				devbus,acc-first-ps = <124000>;
+				devbus,acc-next-ps  = <248000>;
+				devbus,rd-setup-ps  = <0>;
+				devbus,rd-hold-ps   = <0>;
+
+				/* Write parameters */
+				devbus,sync-enable = <0>;
+				devbus,wr-high-ps  = <60000>;
+				devbus,wr-low-ps   = <60000>;
+				devbus,ale-wr-ps   = <60000>;
+
+				/* NOR 16 MiB */
+				nor@0 {
+					compatible = "cfi-flash";
+					reg = <0 0x1000000>;
+					bank-width = <2>;
+				};
+			};
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,10 @@
 	model = "Marvell Armada XP family SoC";
 	compatible = "marvell,armadaxp", "marvell,armada-370-xp";
 
+	aliases {
+		eth2 = &eth2;
+	};
+
 	soc {
 		internal-regs {
 			L2: l2-cache {
@@ -86,9 +90,9 @@
 				reg = <0x18200 0x500>;
 			};
 
-			ethernet@30000 {
+			eth2: ethernet@30000 {
 				compatible = "marvell,armada-370-neta";
-				reg = <0x30000 0x2500>;
+				reg = <0x30000 0x4000>;
 				interrupts = <12>;
 				clocks = <&gateclk 2>;
 				status = "disabled";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-gp.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-gp.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-gp.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-gp.dts	2013-08-25 20:43:22.000000000 -0400
@@ -105,6 +105,16 @@
 				phy-mode = "rgmii-id";
 			};
 
+			/* Front-side USB slot */
+			usb@50000 {
+				status = "okay";
+			};
+
+			/* Back-side USB slot */
+			usb@51000 {
+				status = "okay";
+			};
+
 			spi0: spi@10600 {
 				status = "okay";
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-mv78260.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-mv78260.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-mv78260.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-mv78260.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -92,7 +92,7 @@
 
 			ethernet@34000 {
 				compatible = "marvell,armada-370-neta";
-				reg = <0x34000 0x2500>;
+				reg = <0x34000 0x4000>;
 				interrupts = <14>;
 				clocks = <&gateclk 1>;
 				status = "disabled";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-mv78460.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-mv78460.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-mv78460.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-mv78460.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,7 @@
 		gpio0 = &gpio0;
 		gpio1 = &gpio1;
 		gpio2 = &gpio2;
+		eth3 = &eth3;
 	};
 
 
@@ -105,9 +106,9 @@
 				interrupts = <91>;
 			};
 
-			ethernet@34000 {
+			eth3: ethernet@34000 {
 				compatible = "marvell,armada-370-neta";
-				reg = <0x34000 0x2500>;
+				reg = <0x34000 0x4000>;
 				interrupts = <14>;
 				clocks = <&gateclk 1>;
 				status = "disabled";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts	2013-08-25 20:43:22.000000000 -0400
@@ -138,13 +138,22 @@
 				nr-ports = <2>;
 				status = "okay";
 			};
+
+			/* Front side USB 0 */
 			usb@50000 {
 				status = "okay";
 			};
+
+			/* Front side USB 1 */
 			usb@51000 {
 				status = "okay";
 			};
 
+			/* USB interface in the mini-PCIe connector */
+			usb@52000 {
+				status = "okay";
+			};
+
 			devbus-bootcs@10400 {
 				status = "okay";
 				ranges = <0 0xf0000000 0x8000000>; /* @addr 0xf000000, size 0x8000000 */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91-ariag25.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91-ariag25.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91-ariag25.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91-ariag25.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9g25.dtsi"
+#include "at91sam9g25.dtsi"
 
 / {
 	model = "Acme Systems Aria G25";
@@ -21,6 +21,7 @@
 		serial3 = &usart2;
 		serial4 = &usart3;
 		serial5 = &uart0;
+		serial6 = &uart1;
 	};
 
 	chosen {
@@ -112,13 +113,17 @@
 				status = "okay";
 			};
 
+			/*
+			 * UART0/1 pins are marked as GPIO on
+			 * Aria documentation.
+			 * Change to "okay" if you need additional serial ports
+			 */
 			uart0: serial@f8040000 {
-				compatible = "atmel,at91sam9260-usart";
-				reg = <0xf8040000 0x200>;
-				interrupts = <15 4 5>;
-				pinctrl-names = "default";
-				pinctrl-0 = <&pinctrl_uart0>;
-				status = "okay";
+				status = "disabled";
+			};
+
+			uart1: serial@f8044000 {
+				status = "disabled";
 			};
 
 			adc0: adc@f804c000 {
@@ -138,6 +143,10 @@
 					};
 				};
 			};
+
+			rtc@fffffeb0 {
+				status = "okay";
+			};
 		};
 
 		usb0: ohci@00600000 {
@@ -156,7 +165,7 @@
 		/* little green LED in middle of Aria G25 module */
 		aria_led {
 			label = "aria_led";
-			gpios = <&pioB 8 0>; /* PB8 */
+			gpios = <&pioB 8 GPIO_ACTIVE_HIGH>; /* PB8 */
 			linux,default-trigger = "heartbeat";
 		};
 
@@ -164,7 +173,7 @@
 
 	onewire@0 {
 		compatible = "w1-gpio";
-		gpios = <&pioA 21 1>;
+		gpios = <&pioA 21 GPIO_ACTIVE_LOW>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_w1_0>;
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91-foxg20.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91-foxg20.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91-foxg20.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91-foxg20.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,157 @@
+/*
+ * at91-foxg20.dts - Device Tree file for Acme Systems FoxG20 board
+ *
+ * Based on DT files for at91sam9g20ek evaluation board (AT91SAM9G20 SoC)
+ *
+ * Copyright (C) 2013 Douglas Gilbert <dgilbert@interlog.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "at91sam9g20.dtsi"
+
+/ {
+	model = "Acme Systems FoxG20";
+	compatible = "acme,foxg20", "atmel,at91sam9g20", "atmel,at91sam9";
+
+	chosen {
+		bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait";
+	};
+
+	memory {
+		reg = <0x20000000 0x4000000>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		main_clock: clock@0 {
+			compatible = "atmel,osc", "fixed-clock";
+			clock-frequency = <18432000>;
+		};
+	};
+
+	ahb {
+		apb {
+			usb1: gadget@fffa4000 {
+				atmel,vbus-gpio = <&pioC 6 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+			};
+
+			mmc0: mmc@fffa8000 {
+				pinctrl-0 = <
+					&pinctrl_mmc0_clk
+					&pinctrl_mmc0_slot1_cmd_dat0
+					&pinctrl_mmc0_slot1_dat1_3>;
+				status = "okay";
+
+				slot@1 {
+					reg = <1>;
+					bus-width = <4>;
+				};
+			};
+
+			usart0: serial@fffb0000 {
+				pinctrl-0 =
+					<&pinctrl_usart0
+					 &pinctrl_usart0_rts
+					 &pinctrl_usart0_cts
+					>;
+				status = "okay";
+			};
+
+			usart1: serial@fffb4000 {
+				status = "okay";
+			};
+
+			usart2: serial@fffb8000 {
+				status = "okay";
+			};
+
+			macb0: ethernet@fffc4000 {
+				phy-mode = "rmii";
+				status = "okay";
+			};
+
+			usart3: serial@fffd0000 {
+				status = "okay";
+			};
+
+			uart0: serial@fffd4000 {
+				status = "okay";
+			};
+
+			uart1: serial@fffd8000 {
+				status = "okay";
+			};
+
+			dbgu: serial@fffff200 {
+				status = "okay";
+			};
+
+			pinctrl@fffff400 {
+				board {
+					pinctrl_pck0_as_mck: pck0_as_mck {
+						atmel,pins =
+							<AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+				};
+
+				mmc0_slot1 {
+					pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+						atmel,pins =
+							<AT91_PIOC 9 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;	/* CD pin */
+					};
+				};
+
+				i2c0 {
+					pinctrl_i2c0: i2c0-0 {
+						atmel,pins =
+							<AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_MULTI_DRIVE	/* TWD (SDA), open drain */
+							 AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_MULTI_DRIVE>;	/* TWCK (SCL), open drain */
+					};
+				};
+			};
+
+			watchdog@fffffd40 {
+				status = "okay";
+			};
+		};
+
+		usb0: ohci@00500000 {
+			num-ports = <2>;
+			status = "okay";
+		};
+	};
+
+	i2c@0 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2c0>;
+		i2c-gpio,delay-us = <5>;	/* ~85 kHz */
+		status = "okay";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		/* red LED marked "PC7" near mini USB (device) receptacle */
+		user_led {
+			label = "user_led";
+			gpios = <&pioC 7 GPIO_ACTIVE_HIGH>;	/* PC7 */
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+
+		btn {
+			label = "Button";
+			gpios = <&pioC 4 GPIO_ACTIVE_LOW>;
+			linux,code = <0x103>;
+			gpio-key,wakeup;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91rm9200.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91rm9200.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91rm9200.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91rm9200.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,10 @@
  * Licensed under GPLv2 or later.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Atmel AT91RM9200 family SoC";
@@ -35,8 +38,12 @@
 		ssc2 = &ssc2;
 	};
 	cpus {
-		cpu@0 {
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
 			compatible = "arm,arm920t";
+			device_type = "cpu";
 		};
 	};
 
@@ -77,25 +84,29 @@
 			st: timer@fffffd00 {
 				compatible = "atmel,at91rm9200-st";
 				reg = <0xfffffd00 0x100>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 			};
 
 			tcb0: timer@fffa0000 {
 				compatible = "atmel,at91rm9200-tcb";
 				reg = <0xfffa0000 0x100>;
-				interrupts = <17 4 0 18 4 0 19 4 0>;
+				interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0
+					      18 IRQ_TYPE_LEVEL_HIGH 0
+					      19 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			tcb1: timer@fffa4000 {
 				compatible = "atmel,at91rm9200-tcb";
 				reg = <0xfffa4000 0x100>;
-				interrupts = <20 4 0 21 4 0 22 4 0>;
+				interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0
+					      21 IRQ_TYPE_LEVEL_HIGH 0
+					      22 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			i2c0: i2c@fffb8000 {
 				compatible = "atmel,at91rm9200-i2c";
 				reg = <0xfffb8000 0x4000>;
-				interrupts = <12 4 6>;
+				interrupts = <12 IRQ_TYPE_LEVEL_HIGH 6>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_twi>;
 				#address-cells = <1>;
@@ -106,7 +117,7 @@
 			mmc0: mmc@fffb4000 {
 				compatible = "atmel,hsmci";
 				reg = <0xfffb4000 0x4000>;
-				interrupts = <10 4 0>;
+				interrupts = <10 IRQ_TYPE_LEVEL_HIGH 0>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
@@ -115,7 +126,7 @@
 			ssc0: ssc@fffd0000 {
 				compatible = "atmel,at91rm9200-ssc";
 				reg = <0xfffd0000 0x4000>;
-				interrupts = <14 4 5>;
+				interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
 				status = "disable";
@@ -124,7 +135,7 @@
 			ssc1: ssc@fffd4000 {
 				compatible = "atmel,at91rm9200-ssc";
 				reg = <0xfffd4000 0x4000>;
-				interrupts = <15 4 5>;
+				interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
 				status = "disable";
@@ -133,7 +144,7 @@
 			ssc2: ssc@fffd8000 {
 				compatible = "atmel,at91rm9200-ssc";
 				reg = <0xfffd8000 0x4000>;
-				interrupts = <16 4 5>;
+				interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc2_tx &pinctrl_ssc2_rx>;
 				status = "disable";
@@ -142,7 +153,7 @@
 			macb0: ethernet@fffbc000 {
 				compatible = "cdns,at91rm9200-emac", "cdns,emac";
 				reg = <0xfffbc000 0x4000>;
-				interrupts = <24 4 3>;
+				interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>;
 				phy-mode = "rmii";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_macb_rmii>;
@@ -167,234 +178,319 @@
 				dbgu {
 					pinctrl_dbgu: dbgu-0 {
 						atmel,pins =
-							<0 30 0x1 0x0	/* PA30 periph A */
-							 0 31 0x1 0x1>;	/* PA31 periph with pullup */
+							<AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA30 periph A */
+							 AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA31 periph with pullup */
 					};
 				};
 
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<0 17 0x1 0x0	/* PA17 periph A */
-							 0 18 0x1 0x0>;	/* PA18 periph A */
+							<AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA17 periph A */
+							 AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA18 periph A */
 					};
 
 					pinctrl_uart0_rts: uart0_rts-0 {
 						atmel,pins =
-							<0 20 0x1 0x0>;	/* PA20 periph A */
+							<AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA20 periph A */
 					};
 
 					pinctrl_uart0_cts: uart0_cts-0 {
 						atmel,pins =
-							<0 21 0x1 0x0>;	/* PA21 periph A */
+							<AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA21 periph A */
 					};
 				};
 
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<1 20 0x1 0x1	/* PB20 periph A with pullup */
-							 1 21 0x1 0x0>;	/* PB21 periph A */
+							<AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB20 periph A with pullup */
+							 AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB21 periph A */
 					};
 
 					pinctrl_uart1_rts: uart1_rts-0 {
 						atmel,pins =
-							<1 24 0x1 0x0>;	/* PB24 periph A */
+							<AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB24 periph A */
 					};
 
 					pinctrl_uart1_cts: uart1_cts-0 {
 						atmel,pins =
-							<1 26 0x1 0x0>;	/* PB26 periph A */
+							<AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB26 periph A */
 					};
 
 					pinctrl_uart1_dtr_dsr: uart1_dtr_dsr-0 {
 						atmel,pins =
-							<1 19 0x1 0x0	/* PB19 periph A */
-							 1 25 0x1 0x0>;	/* PB25 periph A */
+							<AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB19 periph A */
+							 AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB25 periph A */
 					};
 
 					pinctrl_uart1_dcd: uart1_dcd-0 {
 						atmel,pins =
-							<1 23 0x1 0x0>;	/* PB23 periph A */
+							<AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB23 periph A */
 					};
 
 					pinctrl_uart1_ri: uart1_ri-0 {
 						atmel,pins =
-							<1 18 0x1 0x0>;	/* PB18 periph A */
+							<AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB18 periph A */
 					};
 				};
 
 				uart2 {
 					pinctrl_uart2: uart2-0 {
 						atmel,pins =
-							<0 22 0x1 0x0	/* PA22 periph A */
-							 0 23 0x1 0x1>;	/* PA23 periph A with pullup */
+							<AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA22 periph A */
+							 AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA23 periph A with pullup */
 					};
 
 					pinctrl_uart2_rts: uart2_rts-0 {
 						atmel,pins =
-							<0 30 0x2 0x0>;	/* PA30 periph B */
+							<AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA30 periph B */
 					};
 
 					pinctrl_uart2_cts: uart2_cts-0 {
 						atmel,pins =
-							<0 31 0x2 0x0>;	/* PA31 periph B */
+							<AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA31 periph B */
 					};
 				};
 
 				uart3 {
 					pinctrl_uart3: uart3-0 {
 						atmel,pins =
-							<0 5 0x2 0x1	/* PA5 periph B with pullup */
-							 0 6 0x2 0x0>;	/* PA6 periph B */
+							<AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA5 periph B with pullup */
+							 AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA6 periph B */
 					};
 
 					pinctrl_uart3_rts: uart3_rts-0 {
 						atmel,pins =
-							<1 0 0x2 0x0>;	/* PB0 periph B */
+							<AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB0 periph B */
 					};
 
 					pinctrl_uart3_cts: uart3_cts-0 {
 						atmel,pins =
-							<1 1 0x2 0x0>;	/* PB1 periph B */
+							<AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB1 periph B */
 					};
 				};
 
 				nand {
 					pinctrl_nand: nand-0 {
 						atmel,pins =
-							<2 2 0x0 0x1	/* PC2 gpio RDY pin pull_up */
-							 1 1 0x0 0x1>;	/* PB1 gpio CD pin pull_up */
+							<AT91_PIOC 2 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP	/* PC2 gpio RDY pin pull_up */
+							 AT91_PIOB 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;	/* PB1 gpio CD pin pull_up */
 					};
 				};
 
 				macb {
 					pinctrl_macb_rmii: macb_rmii-0 {
 						atmel,pins =
-							<0 7 0x1 0x0	/* PA7 periph A */
-							 0 8 0x1 0x0	/* PA8 periph A */
-							 0 9 0x1 0x0	/* PA9 periph A */
-							 0 10 0x1 0x0	/* PA10 periph A */
-							 0 11 0x1 0x0	/* PA11 periph A */
-							 0 12 0x1 0x0	/* PA12 periph A */
-							 0 13 0x1 0x0	/* PA13 periph A */
-							 0 14 0x1 0x0	/* PA14 periph A */
-							 0 15 0x1 0x0	/* PA15 periph A */
-							 0 16 0x1 0x0>;	/* PA16 periph A */
+							<AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA7 periph A */
+							 AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA8 periph A */
+							 AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA9 periph A */
+							 AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA10 periph A */
+							 AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA11 periph A */
+							 AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA12 periph A */
+							 AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA13 periph A */
+							 AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA14 periph A */
+							 AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA15 periph A */
+							 AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA16 periph A */
 					};
 
 					pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
 						atmel,pins =
-							<1 12 0x2 0x0	/* PB12 periph B */
-							 1 13 0x2 0x0	/* PB13 periph B */
-							 1 14 0x2 0x0	/* PB14 periph B */
-							 1 15 0x2 0x0	/* PB15 periph B */
-							 1 16 0x2 0x0	/* PB16 periph B */
-							 1 17 0x2 0x0	/* PB17 periph B */
-							 1 18 0x2 0x0	/* PB18 periph B */
-							 1 19 0x2 0x0>;	/* PB19 periph B */
+							<AT91_PIOB 12 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB12 periph B */
+							 AT91_PIOB 13 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB13 periph B */
+							 AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB14 periph B */
+							 AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB15 periph B */
+							 AT91_PIOB 16 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB16 periph B */
+							 AT91_PIOB 17 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB17 periph B */
+							 AT91_PIOB 18 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB18 periph B */
+							 AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB19 periph B */
 					};
 				};
 
 				mmc0 {
 					pinctrl_mmc0_clk: mmc0_clk-0 {
 						atmel,pins =
-							<0 27 0x1 0x0>;	/* PA27 periph A */
+							<AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA27 periph A */
 					};
 
 					pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
 						atmel,pins =
-							<0 28 0x1 0x1	/* PA28 periph A with pullup */
-							 0 29 0x1 0x1>;	/* PA29 periph A with pullup */
+							<AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA28 periph A with pullup */
+							 AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA29 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
 						atmel,pins =
-							<1 3 0x2 0x1	/* PB3 periph B with pullup */
-							 1 4 0x2 0x1	/* PB4 periph B with pullup */
-							 1 5 0x2 0x1>;	/* PB5 periph B with pullup */
+							<AT91_PIOB 3 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PB3 periph B with pullup */
+							 AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PB4 periph B with pullup */
+							 AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PB5 periph B with pullup */
 					};
 
 					pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
 						atmel,pins =
-							<0 8 0x2 0x1	/* PA8 periph B with pullup */
-							 0 9 0x2 0x1>;	/* PA9 periph B with pullup */
+							<AT91_PIOA 8 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA8 periph B with pullup */
+							 AT91_PIOA 9 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PA9 periph B with pullup */
 					};
 
 					pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
 						atmel,pins =
-							<0 10 0x2 0x1	/* PA10 periph B with pullup */
-							 0 11 0x2 0x1	/* PA11 periph B with pullup */
-							 0 12 0x2 0x1>;	/* PA12 periph B with pullup */
+							<AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA10 periph B with pullup */
+							 AT91_PIOA 11 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA11 periph B with pullup */
+							 AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PA12 periph B with pullup */
 					};
 				};
 
 				ssc0 {
 					pinctrl_ssc0_tx: ssc0_tx-0 {
 						atmel,pins =
-							<1 0 0x1 0x0	/* PB0 periph A */
-							 1 1 0x1 0x0	/* PB1 periph A */
-							 1 2 0x1 0x0>;	/* PB2 periph A */
+							<AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB0 periph A */
+							 AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB1 periph A */
+							 AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB2 periph A */
 					};
 
 					pinctrl_ssc0_rx: ssc0_rx-0 {
 						atmel,pins =
-							<1 3 0x1 0x0	/* PB3 periph A */
-							 1 4 0x1 0x0	/* PB4 periph A */
-							 1 5 0x1 0x0>;	/* PB5 periph A */
+							<AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB3 periph A */
+							 AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB4 periph A */
+							 AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB5 periph A */
 					};
 				};
 
 				ssc1 {
 					pinctrl_ssc1_tx: ssc1_tx-0 {
 						atmel,pins =
-							<1 6 0x1 0x0	/* PB6 periph A */
-							 1 7 0x1 0x0	/* PB7 periph A */
-							 1 8 0x1 0x0>;	/* PB8 periph A */
+							<AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB6 periph A */
+							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB7 periph A */
+							 AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB8 periph A */
 					};
 
 					pinctrl_ssc1_rx: ssc1_rx-0 {
 						atmel,pins =
-							<1 9 0x1 0x0	/* PB9 periph A */
-							 1 10 0x1 0x0	/* PB10 periph A */
-							 1 11 0x1 0x0>;	/* PB11 periph A */
+							<AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB9 periph A */
+							 AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB10 periph A */
+							 AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB11 periph A */
 					};
 				};
 
 				ssc2 {
 					pinctrl_ssc2_tx: ssc2_tx-0 {
 						atmel,pins =
-							<1 12 0x1 0x0	/* PB12 periph A */
-							 1 13 0x1 0x0	/* PB13 periph A */
-							 1 14 0x1 0x0>;	/* PB14 periph A */
+							<AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB12 periph A */
+							 AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB13 periph A */
+							 AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB14 periph A */
 					};
 
 					pinctrl_ssc2_rx: ssc2_rx-0 {
 						atmel,pins =
-							<1 15 0x1 0x0	/* PB15 periph A */
-							 1 16 0x1 0x0	/* PB16 periph A */
-							 1 17 0x1 0x0>;	/* PB17 periph A */
+							<AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB15 periph A */
+							 AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB16 periph A */
+							 AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB17 periph A */
 					};
 				};
 
 				twi {
 					pinctrl_twi: twi-0 {
 						atmel,pins =
-							<0 25 0x1 0x2	/* PA25 periph A with multi drive */
-							 0 26 0x1 0x2>;	/* PA26 periph A with multi drive */
+							<AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_MULTI_DRIVE	/* PA25 periph A with multi drive */
+							 AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_MULTI_DRIVE>;	/* PA26 periph A with multi drive */
 					};
 
 					pinctrl_twi_gpio: twi_gpio-0 {
 						atmel,pins =
-							<0 25 0x0 0x2	/* PA25 GPIO with multi drive */
-							 0 26 0x0 0x2>;	/* PA26 GPIO with multi drive */
+							<AT91_PIOA 25 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE	/* PA25 GPIO with multi drive */
+							 AT91_PIOA 26 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;	/* PA26 GPIO with multi drive */
+					};
+				};
+
+				tcb0 {
+					pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+						atmel,pins = <AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+						atmel,pins = <AT91_PIOA 14 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+						atmel,pins = <AT91_PIOA 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+						atmel,pins = <AT91_PIOA 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+						atmel,pins = <AT91_PIOA 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+						atmel,pins = <AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+						atmel,pins = <AT91_PIOA 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+						atmel,pins = <AT91_PIOA 20 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+						atmel,pins = <AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+				};
+
+				tcb1 {
+					pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+						atmel,pins = <AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+						atmel,pins = <AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+						atmel,pins = <AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+						atmel,pins = <AT91_PIOB 6 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+						atmel,pins = <AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+						atmel,pins = <AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+						atmel,pins = <AT91_PIOB 7 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+						atmel,pins = <AT91_PIOB 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+						atmel,pins = <AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+				};
+
+				spi0 {
+					pinctrl_spi0: spi0-0 {
+						atmel,pins =
+							<AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA0 periph A SPI0_MISO pin */
+							 AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA1 periph A SPI0_MOSI pin */
+							 AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA2 periph A SPI0_SPCK pin */
 					};
 				};
 
 				pioA: gpio@fffff400 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff400 0x200>;
-					interrupts = <2 4 1>;
+					interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -404,7 +500,7 @@
 				pioB: gpio@fffff600 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff600 0x200>;
-					interrupts = <3 4 1>;
+					interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -414,7 +510,7 @@
 				pioC: gpio@fffff800 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff800 0x200>;
-					interrupts = <4 4 1>;
+					interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -424,7 +520,7 @@
 				pioD: gpio@fffffa00 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffffa00 0x200>;
-					interrupts = <5 4 1>;
+					interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -435,7 +531,7 @@
 			dbgu: serial@fffff200 {
 				compatible = "atmel,at91rm9200-usart";
 				reg = <0xfffff200 0x200>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_dbgu>;
 				status = "disabled";
@@ -444,7 +540,7 @@
 			usart0: serial@fffc0000 {
 				compatible = "atmel,at91rm9200-usart";
 				reg = <0xfffc0000 0x200>;
-				interrupts = <6 4 5>;
+				interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -455,7 +551,7 @@
 			usart1: serial@fffc4000 {
 				compatible = "atmel,at91rm9200-usart";
 				reg = <0xfffc4000 0x200>;
-				interrupts = <7 4 5>;
+				interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -466,7 +562,7 @@
 			usart2: serial@fffc8000 {
 				compatible = "atmel,at91rm9200-usart";
 				reg = <0xfffc8000 0x200>;
-				interrupts = <8 4 5>;
+				interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -477,7 +573,7 @@
 			usart3: serial@fffcc000 {
 				compatible = "atmel,at91rm9200-usart";
 				reg = <0xfffcc000 0x200>;
-				interrupts = <23 4 5>;
+				interrupts = <23 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -488,7 +584,18 @@
 			usb1: gadget@fffb0000 {
 				compatible = "atmel,at91rm9200-udc";
 				reg = <0xfffb0000 0x4000>;
-				interrupts = <11 4 2>;
+				interrupts = <11 IRQ_TYPE_LEVEL_HIGH 2>;
+				status = "disabled";
+			};
+
+			spi0: spi@fffe0000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "atmel,at91rm9200-spi";
+				reg = <0xfffe0000 0x200>;
+				interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_spi0>;
 				status = "disabled";
 			};
 		};
@@ -503,9 +610,9 @@
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_nand>;
 			nand-ecc-mode = "soft";
-			gpios = <&pioC 2 0
+			gpios = <&pioC 2 GPIO_ACTIVE_HIGH
 				 0
-				 &pioB 1 0
+				 &pioB 1 GPIO_ACTIVE_HIGH
 				>;
 			status = "disabled";
 		};
@@ -513,15 +620,15 @@
 		usb0: ohci@00300000 {
 			compatible = "atmel,at91rm9200-ohci", "usb-ohci";
 			reg = <0x00300000 0x100000>;
-			interrupts = <23 4 2>;
+			interrupts = <23 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 	};
 
 	i2c@0 {
 		compatible = "i2c-gpio";
-		gpios = <&pioA 25 0 /* sda */
-			 &pioA 26 0 /* scl */
+		gpios = <&pioA 25 GPIO_ACTIVE_HIGH /* sda */
+			 &pioA 26 GPIO_ACTIVE_HIGH /* scl */
 			>;
 		i2c-gpio,sda-open-drain;
 		i2c-gpio,scl-open-drain;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91rm9200ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91rm9200ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91rm9200ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91rm9200ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2 only
  */
 /dts-v1/;
-/include/ "at91rm9200.dtsi"
+#include "at91rm9200.dtsi"
 
 / {
 	model = "Atmel AT91RM9200 evaluation kit";
@@ -50,8 +50,18 @@
 			};
 
 			usb1: gadget@fffb0000 {
-				atmel,vbus-gpio = <&pioD 4 0>;
+				atmel,vbus-gpio = <&pioD 4 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+			};
+
+			spi0: spi@fffe0000 {
 				status = "okay";
+				cs-gpios = <&pioA 3 0>, <0>, <0>, <0>;
+				mtd_dataflash@0 {
+					compatible = "atmel,at45", "atmel,dataflash";
+					spi-max-frequency = <15000000>;
+					reg = <0>;
+				};
 			};
 		};
 
@@ -66,19 +76,19 @@
 
 		ds2 {
 			label = "green";
-			gpios = <&pioB 0 0x1>;
+			gpios = <&pioB 0 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "mmc0";
 		};
 
 		ds4 {
 			label = "yellow";
-			gpios = <&pioB 1 0x1>;
+			gpios = <&pioB 1 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
 		};
 
 		ds6 {
 			label = "red";
-			gpios = <&pioB 2 0x1>;
+			gpios = <&pioB 2 GPIO_ACTIVE_LOW>;
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9260.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9260.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9260.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9260.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,10 @@
  * Licensed under GPLv2 or later.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Atmel AT91SAM9260 family SoC";
@@ -32,8 +35,12 @@
 		ssc0 = &ssc0;
 	};
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
@@ -84,19 +91,23 @@
 			pit: timer@fffffd30 {
 				compatible = "atmel,at91sam9260-pit";
 				reg = <0xfffffd30 0xf>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 			};
 
 			tcb0: timer@fffa0000 {
 				compatible = "atmel,at91rm9200-tcb";
 				reg = <0xfffa0000 0x100>;
-				interrupts = <17 4 0 18 4 0 19 4 0>;
+				interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0
+					      18 IRQ_TYPE_LEVEL_HIGH 0
+					      19 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			tcb1: timer@fffdc000 {
 				compatible = "atmel,at91rm9200-tcb";
 				reg = <0xfffdc000 0x100>;
-				interrupts = <26 4 0 27 4 0 28 4 0>;
+				interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0
+					      27 IRQ_TYPE_LEVEL_HIGH 0
+					      28 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			pinctrl@fffff400 {
@@ -116,234 +127,318 @@
 				dbgu {
 					pinctrl_dbgu: dbgu-0 {
 						atmel,pins =
-							<1 14 0x1 0x0	/* PB14 periph A */
-							 1 15 0x1 0x1>;	/* PB15 periph with pullup */
+							<AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB14 periph A */
+							 AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PB15 periph with pullup */
 					};
 				};
 
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<1 4 0x1 0x0	/* PB4 periph A */
-							 1 5 0x1 0x0>;	/* PB5 periph A */
+							<AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB4 periph A */
+							 AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB5 periph A */
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
 						atmel,pins =
-							<1 26 0x1 0x0>;	/* PB26 periph A */
+							<AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB26 periph A */
 					};
 
 					pinctrl_usart0_cts: usart0_cts-0 {
 						atmel,pins =
-							<1 27 0x1 0x0>;	/* PB27 periph A */
+							<AT91_PIOB 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB27 periph A */
 					};
 
 					pinctrl_usart0_dtr_dsr: usart0_dtr_dsr-0 {
 						atmel,pins =
-							<1 24 0x1 0x0	/* PB24 periph A */
-							 1 22 0x1 0x0>;	/* PB22 periph A */
+							<AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB24 periph A */
+							 AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB22 periph A */
 					};
 
 					pinctrl_usart0_dcd: usart0_dcd-0 {
 						atmel,pins =
-							<1 23 0x1 0x0>;	/* PB23 periph A */
+							<AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB23 periph A */
 					};
 
 					pinctrl_usart0_ri: usart0_ri-0 {
 						atmel,pins =
-							<1 25 0x1 0x0>;	/* PB25 periph A */
+							<AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB25 periph A */
 					};
 				};
 
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<1 6 0x1 0x1	/* PB6 periph A with pullup */
-							 1 7 0x1 0x0>;	/* PB7 periph A */
+							<AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB6 periph A with pullup */
+							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB7 periph A */
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
 						atmel,pins =
-							<1 28 0x1 0x0>;	/* PB28 periph A */
+							<AT91_PIOB 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB28 periph A */
 					};
 
 					pinctrl_usart1_cts: usart1_cts-0 {
 						atmel,pins =
-							<1 29 0x1 0x0>;	/* PB29 periph A */
+							<AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB29 periph A */
 					};
 				};
 
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<1 8 0x1 0x1	/* PB8 periph A with pullup */
-							 1 9 0x1 0x0>;	/* PB9 periph A */
+							<AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB8 periph A with pullup */
+							 AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB9 periph A */
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
 						atmel,pins =
-							<0 4 0x1 0x0>;	/* PA4 periph A */
+							<AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA4 periph A */
 					};
 
 					pinctrl_usart2_cts: usart2_cts-0 {
 						atmel,pins =
-							<0 5 0x1 0x0>;	/* PA5 periph A */
+							<AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA5 periph A */
 					};
 				};
 
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<1 10 0x1 0x1	/* PB10 periph A with pullup */
-							 1 11 0x1 0x0>;	/* PB11 periph A */
+							<AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB10 periph A with pullup */
+							 AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB11 periph A */
 					};
 
 					pinctrl_usart3_rts: usart3_rts-0 {
 						atmel,pins =
-							<2 8 0x2 0x0>;	/* PC8 periph B */
+							<AT91_PIOB 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC8 periph B */
 					};
 
 					pinctrl_usart3_cts: usart3_cts-0 {
 						atmel,pins =
-							<2 10 0x2 0x0>;	/* PC10 periph B */
+							<AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC10 periph B */
 					};
 				};
 
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<0 31 0x2 0x1	/* PA31 periph B with pullup */
-							 0 30 0x2 0x0>;	/* PA30 periph B */
+							<AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA31 periph B with pullup */
+							 AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA30 periph B */
 					};
 				};
 
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<1 12 0x1 0x1	/* PB12 periph A with pullup */
-							 1 13 0x1 0x0>;	/* PB13 periph A */
+							<AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB12 periph A with pullup */
+							 AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB13 periph A */
 					};
 				};
 
 				nand {
 					pinctrl_nand: nand-0 {
 						atmel,pins =
-							<2 13 0x0 0x1	/* PC13 gpio RDY pin pull_up */
-							 2 14 0x0 0x1>;	/* PC14 gpio enable pin pull_up */
+							<AT91_PIOC 13 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP	/* PC13 gpio RDY pin pull_up */
+							 AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;	/* PC14 gpio enable pin pull_up */
 					};
 				};
 
 				macb {
 					pinctrl_macb_rmii: macb_rmii-0 {
 						atmel,pins =
-							<0 12 0x1 0x0	/* PA12 periph A */
-							 0 13 0x1 0x0	/* PA13 periph A */
-							 0 14 0x1 0x0	/* PA14 periph A */
-							 0 15 0x1 0x0	/* PA15 periph A */
-							 0 16 0x1 0x0	/* PA16 periph A */
-							 0 17 0x1 0x0	/* PA17 periph A */
-							 0 18 0x1 0x0	/* PA18 periph A */
-							 0 19 0x1 0x0	/* PA19 periph A */
-							 0 20 0x1 0x0	/* PA20 periph A */
-							 0 21 0x1 0x0>;	/* PA21 periph A */
+							<AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA12 periph A */
+							 AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA13 periph A */
+							 AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA14 periph A */
+							 AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA15 periph A */
+							 AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA16 periph A */
+							 AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA17 periph A */
+							 AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA18 periph A */
+							 AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA19 periph A */
+							 AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA20 periph A */
+							 AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA21 periph A */
 					};
 
 					pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
 						atmel,pins =
-							<0 22 0x2 0x0	/* PA22 periph B */
-							 0 23 0x2 0x0	/* PA23 periph B */
-							 0 24 0x2 0x0	/* PA24 periph B */
-							 0 25 0x2 0x0	/* PA25 periph B */
-							 0 26 0x2 0x0	/* PA26 periph B */
-							 0 27 0x2 0x0	/* PA27 periph B */
-							 0 28 0x2 0x0	/* PA28 periph B */
-							 0 29 0x2 0x0>;	/* PA29 periph B */
+							<AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA22 periph B */
+							 AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA23 periph B */
+							 AT91_PIOA 24 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA24 periph B */
+							 AT91_PIOA 25 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA25 periph B */
+							 AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA26 periph B */
+							 AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA27 periph B */
+							 AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA28 periph B */
+							 AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA29 periph B */
 					};
 
 					pinctrl_macb_rmii_mii_alt: macb_rmii_mii-1 {
 						atmel,pins =
-							<0 10 0x2 0x0	/* PA10 periph B */
-							 0 11 0x2 0x0	/* PA11 periph B */
-							 0 22 0x2 0x0	/* PA22 periph B */
-							 0 25 0x2 0x0	/* PA25 periph B */
-							 0 26 0x2 0x0	/* PA26 periph B */
-							 0 27 0x2 0x0	/* PA27 periph B */
-							 0 28 0x2 0x0	/* PA28 periph B */
-							 0 29 0x2 0x0>;	/* PA29 periph B */
+							<AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA10 periph B */
+							 AT91_PIOA 11 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA11 periph B */
+							 AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA22 periph B */
+							 AT91_PIOA 25 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA25 periph B */
+							 AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA26 periph B */
+							 AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA27 periph B */
+							 AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA28 periph B */
+							 AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA29 periph B */
 					};
 				};
 
 				mmc0 {
 					pinctrl_mmc0_clk: mmc0_clk-0 {
 						atmel,pins =
-							<0 8 0x1 0x0>;	/* PA8 periph A */
+							<AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA8 periph A */
 					};
 
 					pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
 						atmel,pins =
-							<0 7 0x1 0x1	/* PA7 periph A with pullup */
-							 0 6 0x1 0x1>;	/* PA6 periph A with pullup */
+							<AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA7 periph A with pullup */
+							 AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA6 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
 						atmel,pins =
-							<0 9 0x1 0x1	/* PA9 periph A with pullup */
-							 0 10 0x1 0x1	/* PA10 periph A with pullup */
-							 0 11 0x1 0x1>;	/* PA11 periph A with pullup */
+							<AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA9 periph A with pullup */
+							 AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA10 periph A with pullup */
+							 AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA11 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
 						atmel,pins =
-							<0 1 0x2 0x1	/* PA1 periph B with pullup */
-							 0 0 0x2 0x1>;	/* PA0 periph B with pullup */
+							<AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA1 periph B with pullup */
+							 AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PA0 periph B with pullup */
 					};
 
 					pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
 						atmel,pins =
-							<0 5 0x2 0x1	/* PA5 periph B with pullup */
-							 0 4 0x2 0x1	/* PA4 periph B with pullup */
-							 0 3 0x2 0x1>;	/* PA3 periph B with pullup */
+							<AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA5 periph B with pullup */
+							 AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA4 periph B with pullup */
+							 AT91_PIOA 3 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PA3 periph B with pullup */
 					};
 				};
 
 				ssc0 {
 					pinctrl_ssc0_tx: ssc0_tx-0 {
 						atmel,pins =
-							<1 16 0x1 0x0	/* PB16 periph A */
-							 1 17 0x1 0x0	/* PB17 periph A */
-							 1 18 0x1 0x0>;	/* PB18 periph A */
+							<AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB16 periph A */
+							 AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB17 periph A */
+							 AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB18 periph A */
 					};
 
 					pinctrl_ssc0_rx: ssc0_rx-0 {
 						atmel,pins =
-							<1 19 0x1 0x0	/* PB19 periph A */
-							 1 20 0x1 0x0	/* PB20 periph A */
-							 1 21 0x1 0x0>;	/* PB21 periph A */
+							<AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB19 periph A */
+							 AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB20 periph A */
+							 AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB21 periph A */
 					};
 				};
 
 				spi0 {
 					pinctrl_spi0: spi0-0 {
 						atmel,pins =
-							<0 0 0x1 0x0	/* PA0 periph A SPI0_MISO pin */
-							 0 1 0x1 0x0	/* PA1 periph A SPI0_MOSI pin */
-							 0 2 0x1 0x0>;	/* PA2 periph A SPI0_SPCK pin */
+							<AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA0 periph A SPI0_MISO pin */
+							 AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA1 periph A SPI0_MOSI pin */
+							 AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA2 periph A SPI0_SPCK pin */
 					};
 				};
 
 				spi1 {
 					pinctrl_spi1: spi1-0 {
 						atmel,pins =
-							<1 0 0x1 0x0	/* PB0 periph A SPI1_MISO pin */
-							 1 1 0x1 0x0	/* PB1 periph A SPI1_MOSI pin */
-							 1 2 0x1 0x0>;	/* PB2 periph A SPI1_SPCK pin */
+							<AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB0 periph A SPI1_MISO pin */
+							 AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB1 periph A SPI1_MOSI pin */
+							 AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB2 periph A SPI1_SPCK pin */
+					};
+				};
+
+				i2c_gpio0 {
+					pinctrl_i2c_gpio0: i2c_gpio0-0 {
+						atmel,pins =
+							<AT91_PIOA 23 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE
+							 AT91_PIOA 24 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+					};
+				};
+
+				tcb0 {
+					pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+						atmel,pins = <AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+						atmel,pins = <AT91_PIOB 6 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+						atmel,pins = <AT91_PIOB 7 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+						atmel,pins = <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+						atmel,pins = <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+						atmel,pins = <AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+						atmel,pins = <AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+						atmel,pins = <AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+						atmel,pins = <AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+				};
+
+				tcb1 {
+					pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+						atmel,pins = <AT91_PIOB 16 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+						atmel,pins = <AT91_PIOB 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+						atmel,pins = <AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+						atmel,pins = <AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+						atmel,pins = <AT91_PIOB 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+						atmel,pins = <AT91_PIOB 3 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+						atmel,pins = <AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+						atmel,pins = <AT91_PIOB 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+						atmel,pins = <AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
 					};
 				};
 
 				pioA: gpio@fffff400 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff400 0x200>;
-					interrupts = <2 4 1>;
+					interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -353,7 +448,7 @@
 				pioB: gpio@fffff600 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff600 0x200>;
-					interrupts = <3 4 1>;
+					interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -363,7 +458,7 @@
 				pioC: gpio@fffff800 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff800 0x200>;
-					interrupts = <4 4 1>;
+					interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -374,7 +469,7 @@
 			dbgu: serial@fffff200 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfffff200 0x200>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_dbgu>;
 				status = "disabled";
@@ -383,7 +478,7 @@
 			usart0: serial@fffb0000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfffb0000 0x200>;
-				interrupts = <6 4 5>;
+				interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -394,7 +489,7 @@
 			usart1: serial@fffb4000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfffb4000 0x200>;
-				interrupts = <7 4 5>;
+				interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -405,7 +500,7 @@
 			usart2: serial@fffb8000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfffb8000 0x200>;
-				interrupts = <8 4 5>;
+				interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -416,7 +511,7 @@
 			usart3: serial@fffd0000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfffd0000 0x200>;
-				interrupts = <23 4 5>;
+				interrupts = <23 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -427,7 +522,7 @@
 			uart0: serial@fffd4000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfffd4000 0x200>;
-				interrupts = <24 4 5>;
+				interrupts = <24 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -438,7 +533,7 @@
 			uart1: serial@fffd8000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfffd8000 0x200>;
-				interrupts = <25 4 5>;
+				interrupts = <25 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -449,7 +544,7 @@
 			macb0: ethernet@fffc4000 {
 				compatible = "cdns,at32ap7000-macb", "cdns,macb";
 				reg = <0xfffc4000 0x100>;
-				interrupts = <21 4 3>;
+				interrupts = <21 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_macb_rmii>;
 				status = "disabled";
@@ -458,14 +553,14 @@
 			usb1: gadget@fffa4000 {
 				compatible = "atmel,at91rm9200-udc";
 				reg = <0xfffa4000 0x4000>;
-				interrupts = <10 4 2>;
+				interrupts = <10 IRQ_TYPE_LEVEL_HIGH 2>;
 				status = "disabled";
 			};
 
 			i2c0: i2c@fffac000 {
 				compatible = "atmel,at91sam9260-i2c";
 				reg = <0xfffac000 0x100>;
-				interrupts = <11 4 6>;
+				interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
@@ -474,7 +569,7 @@
 			mmc0: mmc@fffa8000 {
 				compatible = "atmel,hsmci";
 				reg = <0xfffa8000 0x600>;
-				interrupts = <9 4 0>;
+				interrupts = <9 IRQ_TYPE_LEVEL_HIGH 0>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
@@ -483,7 +578,7 @@
 			ssc0: ssc@fffbc000 {
 				compatible = "atmel,at91rm9200-ssc";
 				reg = <0xfffbc000 0x4000>;
-				interrupts = <14 4 5>;
+				interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
 				status = "disabled";
@@ -494,7 +589,7 @@
 				#size-cells = <0>;
 				compatible = "atmel,at91rm9200-spi";
 				reg = <0xfffc8000 0x200>;
-				interrupts = <12 4 3>;
+				interrupts = <12 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi0>;
 				status = "disabled";
@@ -505,7 +600,7 @@
 				#size-cells = <0>;
 				compatible = "atmel,at91rm9200-spi";
 				reg = <0xfffcc000 0x200>;
-				interrupts = <13 4 3>;
+				interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi1>;
 				status = "disabled";
@@ -514,7 +609,7 @@
 			adc0: adc@fffe0000 {
 				compatible = "atmel,at91sam9260-adc";
 				reg = <0xfffe0000 0x100>;
-				interrupts = <5 4 0>;
+				interrupts = <5 IRQ_TYPE_LEVEL_HIGH 0>;
 				atmel,adc-use-external-triggers;
 				atmel,adc-channels-used = <0xf>;
 				atmel,adc-vref = <3300>;
@@ -567,8 +662,8 @@
 			atmel,nand-cmd-offset = <22>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_nand>;
-			gpios = <&pioC 13 0
-				 &pioC 14 0
+			gpios = <&pioC 13 GPIO_ACTIVE_HIGH
+				 &pioC 14 GPIO_ACTIVE_HIGH
 				 0
 				>;
 			status = "disabled";
@@ -577,21 +672,23 @@
 		usb0: ohci@00500000 {
 			compatible = "atmel,at91rm9200-ohci", "usb-ohci";
 			reg = <0x00500000 0x100000>;
-			interrupts = <20 4 2>;
+			interrupts = <20 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 	};
 
 	i2c@0 {
 		compatible = "i2c-gpio";
-		gpios = <&pioA 23 0 /* sda */
-			 &pioA 24 0 /* scl */
+		gpios = <&pioA 23 GPIO_ACTIVE_HIGH /* sda */
+			 &pioA 24 GPIO_ACTIVE_HIGH /* scl */
 			>;
 		i2c-gpio,sda-open-drain;
 		i2c-gpio,scl-open-drain;
 		i2c-gpio,delay-us = <2>;	/* ~100 kHz */
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2c_gpio0>;
 		status = "disabled";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9263.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9263.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9263.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9263.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,10 @@
  * Licensed under GPLv2 only.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Atmel AT91SAM9263 family SoC";
@@ -29,8 +32,12 @@
 		ssc1 = &ssc1;
 	};
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
@@ -72,13 +79,13 @@
 			pit: timer@fffffd30 {
 				compatible = "atmel,at91sam9260-pit";
 				reg = <0xfffffd30 0xf>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 			};
 
 			tcb0: timer@fff7c000 {
 				compatible = "atmel,at91rm9200-tcb";
 				reg = <0xfff7c000 0x100>;
-				interrupts = <19 4 0>;
+				interrupts = <19 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			rstc@fffffd00 {
@@ -110,221 +117,259 @@
 				dbgu {
 					pinctrl_dbgu: dbgu-0 {
 						atmel,pins =
-							<2 30 0x1 0x0	/* PC30 periph A */
-							 2 31 0x1 0x1>;	/* PC31 periph with pullup */
+							<AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC30 periph A */
+							 AT91_PIOC 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PC31 periph with pullup */
 					};
 				};
 
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<0 26 0x1 0x1	/* PA26 periph A with pullup */
-							 0 27 0x1 0x0>;	/* PA27 periph A */
+							<AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA26 periph A with pullup */
+							 AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA27 periph A */
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
 						atmel,pins =
-							<0 28 0x1 0x0>;	/* PA28 periph A */
+							<AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA28 periph A */
 					};
 
 					pinctrl_usart0_cts: usart0_cts-0 {
 						atmel,pins =
-							<0 29 0x1 0x0>;	/* PA29 periph A */
+							<AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA29 periph A */
 					};
 				};
 
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<3 0 0x1 0x1	/* PD0 periph A with pullup */
-							 3 1 0x1 0x0>;	/* PD1 periph A */
+							<AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD0 periph A with pullup */
+							 AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD1 periph A */
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
 						atmel,pins =
-							<3 7 0x2 0x0>;	/* PD7 periph B */
+							<AT91_PIOD 7 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PD7 periph B */
 					};
 
 					pinctrl_usart1_cts: usart1_cts-0 {
 						atmel,pins =
-							<3 8 0x2 0x0>;	/* PD8 periph B */
+							<AT91_PIOD 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PD8 periph B */
 					};
 				};
 
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<3 2 0x1 0x1	/* PD2 periph A with pullup */
-							 3 3 0x1 0x0>;	/* PD3 periph A */
+							<AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD2 periph A with pullup */
+							 AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD3 periph A */
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
 						atmel,pins =
-							<3 5 0x2 0x0>;	/* PD5 periph B */
+							<AT91_PIOD 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PD5 periph B */
 					};
 
 					pinctrl_usart2_cts: usart2_cts-0 {
 						atmel,pins =
-							<4 6 0x2 0x0>;	/* PD6 periph B */
+							<AT91_PIOD 6 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PD6 periph B */
 					};
 				};
 
 				nand {
 					pinctrl_nand: nand-0 {
 						atmel,pins =
-							<0 22 0x0 0x1	/* PA22 gpio RDY pin pull_up*/
-							 3 15 0x0 0x1>;	/* PD15 gpio enable pin pull_up */
+							<AT91_PIOA 22 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP	/* PA22 gpio RDY pin pull_up*/
+							 AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;	/* PD15 gpio enable pin pull_up */
 					};
 				};
 
 				macb {
 					pinctrl_macb_rmii: macb_rmii-0 {
 						atmel,pins =
-							<2 25 0x2 0x0	/* PC25 periph B */
-							 4 21 0x1 0x0	/* PE21 periph A */
-							 4 23 0x1 0x0	/* PE23 periph A */
-							 4 24 0x1 0x0	/* PE24 periph A */
-							 4 25 0x1 0x0	/* PE25 periph A */
-							 4 26 0x1 0x0	/* PE26 periph A */
-							 4 27 0x1 0x0	/* PE27 periph A */
-							 4 28 0x1 0x0	/* PE28 periph A */
-							 4 29 0x1 0x0	/* PE29 periph A */
-							 4 30 0x1 0x0>;	/* PE30 periph A */
+							<AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC25 periph B */
+							 AT91_PIOE 21 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PE21 periph A */
+							 AT91_PIOE 23 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PE23 periph A */
+							 AT91_PIOE 24 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PE24 periph A */
+							 AT91_PIOE 25 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PE25 periph A */
+							 AT91_PIOE 26 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PE26 periph A */
+							 AT91_PIOE 27 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PE27 periph A */
+							 AT91_PIOE 28 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PE28 periph A */
+							 AT91_PIOE 29 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PE29 periph A */
+							 AT91_PIOE 30 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PE30 periph A */
 					};
 
 					pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
 						atmel,pins =
-							<2 20 0x2 0x0	/* PC20 periph B */
-							 2 21 0x2 0x0	/* PC21 periph B */
-							 2 22 0x2 0x0	/* PC22 periph B */
-							 2 23 0x2 0x0	/* PC23 periph B */
-							 2 24 0x2 0x0	/* PC24 periph B */
-							 2 25 0x2 0x0	/* PC25 periph B */
-							 2 27 0x2 0x0	/* PC27 periph B */
-							 4 22 0x2 0x0>;	/* PE22 periph B */
+							<AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC20 periph B */
+							 AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC21 periph B */
+							 AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC22 periph B */
+							 AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC23 periph B */
+							 AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC24 periph B */
+							 AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC25 periph B */
+							 AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC27 periph B */
+							 AT91_PIOE 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PE22 periph B */
 					};
 				};
 
 				mmc0 {
 					pinctrl_mmc0_clk: mmc0_clk-0 {
 						atmel,pins =
-							<0 12 0x1 0x0>;	/* PA12 periph A */
+							<AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA12 periph A */
 					};
 
 					pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
 						atmel,pins =
-							<0 1 0x1 0x1	/* PA1 periph A with pullup */
-							 0 0 0x1 0x1>;	/* PA0 periph A with pullup */
+							<AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA1 periph A with pullup */
+							 AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA0 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
 						atmel,pins =
-							<0 3 0x1 0x1	/* PA3 periph A with pullup */
-							 0 4 0x1 0x1	/* PA4 periph A with pullup */
-							 0 5 0x1 0x1>;	/* PA5 periph A with pullup */
+							<AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA3 periph A with pullup */
+							 AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA4 periph A with pullup */
+							 AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA5 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
 						atmel,pins =
-							<0 16 0x1 0x1	/* PA16 periph A with pullup */
-							 0 17 0x1 0x1>;	/* PA17 periph A with pullup */
+							<AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA16 periph A with pullup */
+							 AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA17 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
 						atmel,pins =
-							<0 18 0x1 0x1	/* PA18 periph A with pullup */
-							 0 19 0x1 0x1	/* PA19 periph A with pullup */
-							 0 20 0x1 0x1>;	/* PA20 periph A with pullup */
+							<AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA18 periph A with pullup */
+							 AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA19 periph A with pullup */
+							 AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA20 periph A with pullup */
 					};
 				};
 
 				mmc1 {
 					pinctrl_mmc1_clk: mmc1_clk-0 {
 						atmel,pins =
-							<0 6 0x1 0x0>;	/* PA6 periph A */
+							<AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA6 periph A */
 					};
 
 					pinctrl_mmc1_slot0_cmd_dat0: mmc1_slot0_cmd_dat0-0 {
 						atmel,pins =
-							<0 7 0x1 0x1	/* PA7 periph A with pullup */
-							 0 8 0x1 0x1>;	/* PA8 periph A with pullup */
+							<AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA7 periph A with pullup */
+							 AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA8 periph A with pullup */
 					};
 
 					pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
 						atmel,pins =
-							<0 9 0x1 0x1	/* PA9 periph A with pullup */
-							 0 10 0x1 0x1	/* PA10 periph A with pullup */
-							 0 11 0x1 0x1>;	/* PA11 periph A with pullup */
+							<AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA9 periph A with pullup */
+							 AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA10 periph A with pullup */
+							 AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA11 periph A with pullup */
 					};
 
 					pinctrl_mmc1_slot1_cmd_dat0: mmc1_slot1_cmd_dat0-0 {
 						atmel,pins =
-							<0 21 0x1 0x1	/* PA21 periph A with pullup */
-							 0 22 0x1 0x1>;	/* PA22 periph A with pullup */
+							<AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA21 periph A with pullup */
+							 AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA22 periph A with pullup */
 					};
 
 					pinctrl_mmc1_slot1_dat1_3: mmc1_slot1_dat1_3-0 {
 						atmel,pins =
-							<0 23 0x1 0x1	/* PA23 periph A with pullup */
-							 0 24 0x1 0x1	/* PA24 periph A with pullup */
-							 0 25 0x1 0x1>;	/* PA25 periph A with pullup */
+							<AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA23 periph A with pullup */
+							 AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA24 periph A with pullup */
+							 AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA25 periph A with pullup */
 					};
 				};
 
 				ssc0 {
 					pinctrl_ssc0_tx: ssc0_tx-0 {
 						atmel,pins =
-							<1 0 0x2 0x0	/* PB0 periph B */
-							 1 1 0x2 0x0	/* PB1 periph B */
-							 1 2 0x2 0x0>;	/* PB2 periph B */
+							<AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB0 periph B */
+							 AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB1 periph B */
+							 AT91_PIOB 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB2 periph B */
 					};
 
 					pinctrl_ssc0_rx: ssc0_rx-0 {
 						atmel,pins =
-							<1 3 0x2 0x0	/* PB3 periph B */
-							 1 4 0x2 0x0	/* PB4 periph B */
-							 1 5 0x2 0x0>;	/* PB5 periph B */
+							<AT91_PIOB 3 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB3 periph B */
+							 AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB4 periph B */
+							 AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB5 periph B */
 					};
 				};
 
 				ssc1 {
 					pinctrl_ssc1_tx: ssc1_tx-0 {
 						atmel,pins =
-							<1 6 0x1 0x0	/* PB6 periph A */
-							 1 7 0x1 0x0	/* PB7 periph A */
-							 1 8 0x1 0x0>;	/* PB8 periph A */
+							<AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB6 periph A */
+							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB7 periph A */
+							 AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB8 periph A */
 					};
 
 					pinctrl_ssc1_rx: ssc1_rx-0 {
 						atmel,pins =
-							<1 9 0x1 0x0	/* PB9 periph A */
-							 1 10 0x1 0x0	/* PB10 periph A */
-							 1 11 0x1 0x0>;	/* PB11 periph A */
+							<AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB9 periph A */
+							 AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB10 periph A */
+							 AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB11 periph A */
 					};
 				};
 
 				spi0 {
 					pinctrl_spi0: spi0-0 {
 						atmel,pins =
-							<0 0 0x2 0x0	/* PA0 periph B SPI0_MISO pin */
-							 0 1 0x2 0x0	/* PA1 periph B SPI0_MOSI pin */
-							 0 2 0x2 0x0>;	/* PA2 periph B SPI0_SPCK pin */
+							<AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA0 periph B SPI0_MISO pin */
+							 AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA1 periph B SPI0_MOSI pin */
+							 AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA2 periph B SPI0_SPCK pin */
 					};
 				};
 
 				spi1 {
 					pinctrl_spi1: spi1-0 {
 						atmel,pins =
-							<1 12 0x1 0x0	/* PB12 periph A SPI1_MISO pin */
-							 1 13 0x1 0x0	/* PB13 periph A SPI1_MOSI pin */
-							 1 14 0x1 0x0>;	/* PB14 periph A SPI1_SPCK pin */
+							<AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB12 periph A SPI1_MISO pin */
+							 AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB13 periph A SPI1_MOSI pin */
+							 AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB14 periph A SPI1_SPCK pin */
+					};
+				};
+
+				tcb0 {
+					pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+						atmel,pins = <AT91_PIOB 28 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+						atmel,pins = <AT91_PIOC 28 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+						atmel,pins = <AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+						atmel,pins = <AT91_PIOE 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+						atmel,pins = <AT91_PIOE 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+						atmel,pins = <AT91_PIOB 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+						atmel,pins = <AT91_PIOE 19 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+						atmel,pins = <AT91_PIOE 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+						atmel,pins = <AT91_PIOB 18 AT91_PERIPH_B AT91_PINCTRL_NONE>;
 					};
 				};
 
 				pioA: gpio@fffff200 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff200 0x200>;
-					interrupts = <2 4 1>;
+					interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -334,7 +379,7 @@
 				pioB: gpio@fffff400 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff400 0x200>;
-					interrupts = <3 4 1>;
+					interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -344,7 +389,7 @@
 				pioC: gpio@fffff600 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff600 0x200>;
-					interrupts = <4 4 1>;
+					interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -354,7 +399,7 @@
 				pioD: gpio@fffff800 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff800 0x200>;
-					interrupts = <4 4 1>;
+					interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -364,7 +409,7 @@
 				pioE: gpio@fffffa00 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffffa00 0x200>;
-					interrupts = <4 4 1>;
+					interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -375,7 +420,7 @@
 			dbgu: serial@ffffee00 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xffffee00 0x200>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_dbgu>;
 				status = "disabled";
@@ -384,7 +429,7 @@
 			usart0: serial@fff8c000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfff8c000 0x200>;
-				interrupts = <7 4 5>;
+				interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -395,7 +440,7 @@
 			usart1: serial@fff90000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfff90000 0x200>;
-				interrupts = <8 4 5>;
+				interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -406,7 +451,7 @@
 			usart2: serial@fff94000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfff94000 0x200>;
-				interrupts = <9 4 5>;
+				interrupts = <9 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -417,7 +462,7 @@
 			ssc0: ssc@fff98000 {
 				compatible = "atmel,at91rm9200-ssc";
 				reg = <0xfff98000 0x4000>;
-				interrupts = <16 4 5>;
+				interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
 				status = "disabled";
@@ -426,7 +471,7 @@
 			ssc1: ssc@fff9c000 {
 				compatible = "atmel,at91rm9200-ssc";
 				reg = <0xfff9c000 0x4000>;
-				interrupts = <17 4 5>;
+				interrupts = <17 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
 				status = "disabled";
@@ -435,7 +480,7 @@
 			macb0: ethernet@fffbc000 {
 				compatible = "cdns,at32ap7000-macb", "cdns,macb";
 				reg = <0xfffbc000 0x100>;
-				interrupts = <21 4 3>;
+				interrupts = <21 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_macb_rmii>;
 				status = "disabled";
@@ -444,14 +489,14 @@
 			usb1: gadget@fff78000 {
 				compatible = "atmel,at91rm9200-udc";
 				reg = <0xfff78000 0x4000>;
-				interrupts = <24 4 2>;
+				interrupts = <24 IRQ_TYPE_LEVEL_HIGH 2>;
 				status = "disabled";
 			};
 
 			i2c0: i2c@fff88000 {
 				compatible = "atmel,at91sam9263-i2c";
 				reg = <0xfff88000 0x100>;
-				interrupts = <13 4 6>;
+				interrupts = <13 IRQ_TYPE_LEVEL_HIGH 6>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
@@ -460,7 +505,7 @@
 			mmc0: mmc@fff80000 {
 				compatible = "atmel,hsmci";
 				reg = <0xfff80000 0x600>;
-				interrupts = <10 4 0>;
+				interrupts = <10 IRQ_TYPE_LEVEL_HIGH 0>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
@@ -469,7 +514,7 @@
 			mmc1: mmc@fff84000 {
 				compatible = "atmel,hsmci";
 				reg = <0xfff84000 0x600>;
-				interrupts = <11 4 0>;
+				interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
@@ -486,7 +531,7 @@
 				#size-cells = <0>;
 				compatible = "atmel,at91rm9200-spi";
 				reg = <0xfffa4000 0x200>;
-				interrupts = <14 4 3>;
+				interrupts = <14 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi0>;
 				status = "disabled";
@@ -497,7 +542,7 @@
 				#size-cells = <0>;
 				compatible = "atmel,at91rm9200-spi";
 				reg = <0xfffa8000 0x200>;
-				interrupts = <15 4 3>;
+				interrupts = <15 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi1>;
 				status = "disabled";
@@ -515,8 +560,8 @@
 			atmel,nand-cmd-offset = <22>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_nand>;
-			gpios = <&pioA 22 0
-				 &pioD 15 0
+			gpios = <&pioA 22 GPIO_ACTIVE_HIGH
+				 &pioD 15 GPIO_ACTIVE_HIGH
 				 0
 				>;
 			status = "disabled";
@@ -525,15 +570,15 @@
 		usb0: ohci@00a00000 {
 			compatible = "atmel,at91rm9200-ohci", "usb-ohci";
 			reg = <0x00a00000 0x100000>;
-			interrupts = <29 4 2>;
+			interrupts = <29 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 	};
 
 	i2c@0 {
 		compatible = "i2c-gpio";
-		gpios = <&pioB 4 0 /* sda */
-			 &pioB 5 0 /* scl */
+		gpios = <&pioB 4 GPIO_ACTIVE_HIGH /* sda */
+			 &pioB 5 GPIO_ACTIVE_HIGH /* scl */
 			>;
 		i2c-gpio,sda-open-drain;
 		i2c-gpio,scl-open-drain;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9263ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9263ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9263ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9263ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2 only
  */
 /dts-v1/;
-/include/ "at91sam9263.dtsi"
+#include "at91sam9263.dtsi"
 
 / {
 	model = "Atmel at91sam9263ek";
@@ -51,7 +51,7 @@
 			};
 
 			usb1: gadget@fff78000 {
-				atmel,vbus-gpio = <&pioA 25 0>;
+				atmel,vbus-gpio = <&pioA 25 GPIO_ACTIVE_HIGH>;
 				status = "okay";
 			};
 
@@ -65,8 +65,8 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioE 18 0>;
-					wp-gpios = <&pioE 19 0>;
+					cd-gpios = <&pioE 18 GPIO_ACTIVE_HIGH>;
+					wp-gpios = <&pioE 19 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -74,8 +74,8 @@
 				mmc0 {
 					pinctrl_board_mmc0: mmc0-board {
 						atmel,pins =
-							<5 18 0x0 0x5	/* PE18 gpio CD pin pull up and deglitch */
-							 5 19 0x0 0x1>;	/* PE19 gpio WP pin pull up */
+							<AT91_PIOE 18 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH 	/* PE18 gpio CD pin pull up and deglitch */
+							 AT91_PIOE 19 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;	/* PE19 gpio WP pin pull up */
 					};
 				};
 			};
@@ -89,6 +89,10 @@
 					reg = <0>;
 				};
 			};
+
+			watchdog@fffffd40 {
+				status = "okay";
+			};
 		};
 
 		nand0: nand@40000000 {
@@ -141,8 +145,8 @@
 		usb0: ohci@00a00000 {
 			num-ports = <2>;
 			status = "okay";
-			atmel,vbus-gpio = <&pioA 24 0
-					   &pioA 21 0
+			atmel,vbus-gpio = <&pioA 24 GPIO_ACTIVE_HIGH
+					   &pioA 21 GPIO_ACTIVE_HIGH
 					  >;
 		};
 	};
@@ -152,13 +156,13 @@
 
 		d3 {
 			label = "d3";
-			gpios = <&pioB 7 0>;
+			gpios = <&pioB 7 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 
 		d2 {
 			label = "d2";
-			gpios = <&pioC 29 1>;
+			gpios = <&pioC 29 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "nand-disk";
 		};
 	};
@@ -168,14 +172,14 @@
 
 		left_click {
 			label = "left_click";
-			gpios = <&pioC 5 1>;
+			gpios = <&pioC 5 GPIO_ACTIVE_LOW>;
 			linux,code = <272>;
 			gpio-key,wakeup;
 		};
 
 		right_click {
 			label = "right_click";
-			gpios = <&pioC 4 1>;
+			gpios = <&pioC 4 GPIO_ACTIVE_LOW>;
 			linux,code = <273>;
 			gpio-key,wakeup;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g15.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g15.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g15.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g15.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 
-/include/ "at91sam9x5.dtsi"
+#include "at91sam9x5.dtsi"
 
 / {
 	model = "Atmel AT91SAM9G15 SoC";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g15ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g15ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g15ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g15ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9g15.dtsi"
-/include/ "at91sam9x5ek.dtsi"
+#include "at91sam9g15.dtsi"
+#include "at91sam9x5ek.dtsi"
 
 / {
 	model = "Atmel AT91SAM9G15-EK";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g20.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g20.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g20.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g20.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 
-/include/ "at91sam9260.dtsi"
+#include "at91sam9260.dtsi"
 
 / {
 	model = "Atmel AT91SAM9G20 family SoC";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 /dts-v1/;
-/include/ "at91sam9g20ek_common.dtsi"
+#include "at91sam9g20ek_common.dtsi"
 
 / {
 	model = "Atmel at91sam9g20ek 2 mmc";
@@ -23,7 +23,7 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioC 2 0>;
+					cd-gpios = <&pioC 2 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -31,7 +31,7 @@
 				mmc0_slot0 {
 					pinctrl_board_mmc0_slot0: mmc0_slot0-board {
 						atmel,pins =
-							<2 2 0x0 0x5>;	/* PC2 gpio CD pin pull up and deglitch */
+							<AT91_PIOC 2 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;	/* PC2 gpio CD pin pull up and deglitch */
 					};
 				};
 			};
@@ -43,13 +43,13 @@
 
 		ds1 {
 			label = "ds1";
-			gpios = <&pioB 9 0>;
+			gpios = <&pioB 9 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 
 		ds5 {
 			label = "ds5";
-			gpios = <&pioB 8 1>;
+			gpios = <&pioB 8 GPIO_ACTIVE_LOW>;
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g20ek_common.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g20ek_common.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g20ek_common.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * Licensed under GPLv2.
  */
-/include/ "at91sam9g20.dtsi"
+#include "at91sam9g20.dtsi"
 
 / {
 
@@ -34,10 +34,17 @@
 				board {
 					pinctrl_pck0_as_mck: pck0_as_mck {
 						atmel,pins =
-							<2 1 0x2 0x0>;	/* PC1 periph B */
+							<AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC1 periph B */
 					};
 
 				};
+
+				mmc0_slot1 {
+					pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+						atmel,pins =
+							<AT91_PIOC 9 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;	/* PC9 gpio CD pin pull up and deglitch */
+					};
+				};
 			};
 
 			dbgu: serial@fffff200 {
@@ -65,7 +72,7 @@
 			};
 
 			usb1: gadget@fffa4000 {
-				atmel,vbus-gpio = <&pioC 5 0>;
+				atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
 				status = "okay";
 			};
 
@@ -79,16 +86,7 @@
 				slot@1 {
 					reg = <1>;
 					bus-width = <4>;
-					cd-gpios = <&pioC 9 0>;
-				};
-			};
-
-			pinctrl@fffff400 {
-				mmc0_slot1 {
-					pinctrl_board_mmc0_slot1: mmc0_slot1-board {
-						atmel,pins =
-							<2 9 0x0 0x5>;	/* PC9 gpio CD pin pull up and deglitch */
-					};
+					cd-gpios = <&pioC 9 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -106,6 +104,10 @@
 					reg = <1>;
 				};
 			};
+
+			watchdog@fffffd40 {
+				status = "okay";
+			};
 		};
 
 		nand0: nand@40000000 {
@@ -180,14 +182,14 @@
 
 		btn3 {
 			label = "Button 3";
-			gpios = <&pioA 30 1>;
+			gpios = <&pioA 30 GPIO_ACTIVE_LOW>;
 			linux,code = <0x103>;
 			gpio-key,wakeup;
 		};
 
 		btn4 {
 			label = "Button 4";
-			gpios = <&pioA 31 1>;
+			gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
 			linux,code = <0x104>;
 			gpio-key,wakeup;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g20ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g20ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g20ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g20ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 /dts-v1/;
-/include/ "at91sam9g20ek_common.dtsi"
+#include "at91sam9g20ek_common.dtsi"
 
 / {
 	model = "Atmel at91sam9g20ek";
@@ -17,13 +17,13 @@
 
 		ds1 {
 			label = "ds1";
-			gpios = <&pioA 9 0>;
+			gpios = <&pioA 9 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 
 		ds5 {
 			label = "ds5";
-			gpios = <&pioA 6 1>;
+			gpios = <&pioA 6 GPIO_ACTIVE_LOW>;
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g25.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g25.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g25.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g25.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 
-/include/ "at91sam9x5.dtsi"
+#include "at91sam9x5.dtsi"
 
 / {
 	model = "Atmel AT91SAM9G25 SoC";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g25ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g25ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g25ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g25ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9g25.dtsi"
-/include/ "at91sam9x5ek.dtsi"
+#include "at91sam9g25.dtsi"
+#include "at91sam9x5ek.dtsi"
 
 / {
 	model = "Atmel AT91SAM9G25-EK";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g35.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g35.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g35.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g35.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 
-/include/ "at91sam9x5.dtsi"
+#include "at91sam9x5.dtsi"
 
 / {
 	model = "Atmel AT91SAM9G35 SoC";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g35ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g35ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g35ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g35ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9g35.dtsi"
-/include/ "at91sam9x5ek.dtsi"
+#include "at91sam9g35.dtsi"
+#include "at91sam9x5ek.dtsi"
 
 / {
 	model = "Atmel AT91SAM9G35-EK";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g45.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g45.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9g45.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9g45.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,11 @@
  * Licensed under GPLv2 or later.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Atmel AT91SAM9G45 family SoC";
@@ -35,8 +39,12 @@
 		ssc1 = &ssc1;
 	};
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
@@ -83,7 +91,7 @@
 			pit: timer@fffffd30 {
 				compatible = "atmel,at91sam9260-pit";
 				reg = <0xfffffd30 0xf>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 			};
 
 
@@ -95,19 +103,19 @@
 			tcb0: timer@fff7c000 {
 				compatible = "atmel,at91rm9200-tcb";
 				reg = <0xfff7c000 0x100>;
-				interrupts = <18 4 0>;
+				interrupts = <18 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			tcb1: timer@fffd4000 {
 				compatible = "atmel,at91rm9200-tcb";
 				reg = <0xfffd4000 0x100>;
-				interrupts = <18 4 0>;
+				interrupts = <18 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			dma: dma-controller@ffffec00 {
 				compatible = "atmel,at91sam9g45-dma";
 				reg = <0xffffec00 0x200>;
-				interrupts = <21 4 0>;
+				interrupts = <21 IRQ_TYPE_LEVEL_HIGH 0>;
 				#dma-cells = <2>;
 			};
 
@@ -130,221 +138,297 @@
 				dbgu {
 					pinctrl_dbgu: dbgu-0 {
 						atmel,pins =
-							<1 12 0x1 0x0	/* PB12 periph A */
-							 1 13 0x1 0x0>;	/* PB13 periph A */
+							<AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB12 periph A */
+							 AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB13 periph A */
 					};
 				};
 
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<1 19 0x1 0x1	/* PB19 periph A with pullup */
-							 1 18 0x1 0x0>;	/* PB18 periph A */
+							<AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB19 periph A with pullup */
+							 AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB18 periph A */
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
 						atmel,pins =
-							<1 17 0x2 0x0>;	/* PB17 periph B */
+							<AT91_PIOB 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB17 periph B */
 					};
 
 					pinctrl_usart0_cts: usart0_cts-0 {
 						atmel,pins =
-							<1 15 0x2 0x0>;	/* PB15 periph B */
+							<AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB15 periph B */
 					};
 				};
 
 				uart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<1 4 0x1 0x1	/* PB4 periph A with pullup */
-							 1 5 0x1 0x0>;	/* PB5 periph A */
+							<AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB4 periph A with pullup */
+							 AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB5 periph A */
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
 						atmel,pins =
-							<3 16 0x1 0x0>;	/* PD16 periph A */
+							<AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD16 periph A */
 					};
 
 					pinctrl_usart1_cts: usart1_cts-0 {
 						atmel,pins =
-							<3 17 0x1 0x0>;	/* PD17 periph A */
+							<AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD17 periph A */
 					};
 				};
 
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<1 6 0x1 0x1	/* PB6 periph A with pullup */
-							 1 7 0x1 0x0>;	/* PB7 periph A */
+							<AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB6 periph A with pullup */
+							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB7 periph A */
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
 						atmel,pins =
-							<2 9 0x2 0x0>;	/* PC9 periph B */
+							<AT91_PIOC 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC9 periph B */
 					};
 
 					pinctrl_usart2_cts: usart2_cts-0 {
 						atmel,pins =
-							<2 11 0x2 0x0>;	/* PC11 periph B */
+							<AT91_PIOC 11 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC11 periph B */
 					};
 				};
 
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<1 8 0x1 0x1	/* PB9 periph A with pullup */
-							 1 9 0x1 0x0>;	/* PB8 periph A */
+							<AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB9 periph A with pullup */
+							 AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB8 periph A */
 					};
 
 					pinctrl_usart3_rts: usart3_rts-0 {
 						atmel,pins =
-							<0 23 0x2 0x0>;	/* PA23 periph B */
+							<AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA23 periph B */
 					};
 
 					pinctrl_usart3_cts: usart3_cts-0 {
 						atmel,pins =
-							<0 24 0x2 0x0>;	/* PA24 periph B */
+							<AT91_PIOA 24 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA24 periph B */
 					};
 				};
 
 				nand {
 					pinctrl_nand: nand-0 {
 						atmel,pins =
-							<2 8 0x0 0x1	/* PC8 gpio RDY pin pull_up*/
-							 2 14 0x0 0x1>;	/* PC14 gpio enable pin pull_up */
+							<AT91_PIOC 8 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP	/* PC8 gpio RDY pin pull_up*/
+							 AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;	/* PC14 gpio enable pin pull_up */
 					};
 				};
 
 				macb {
 					pinctrl_macb_rmii: macb_rmii-0 {
 						atmel,pins =
-							<0 10 0x1 0x0	/* PA10 periph A */
-							 0 11 0x1 0x0	/* PA11 periph A */
-							 0 12 0x1 0x0	/* PA12 periph A */
-							 0 13 0x1 0x0	/* PA13 periph A */
-							 0 14 0x1 0x0	/* PA14 periph A */
-							 0 15 0x1 0x0	/* PA15 periph A */
-							 0 16 0x1 0x0	/* PA16 periph A */
-							 0 17 0x1 0x0	/* PA17 periph A */
-							 0 18 0x1 0x0	/* PA18 periph A */
-							 0 19 0x1 0x0>;	/* PA19 periph A */
+							<AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA10 periph A */
+							 AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA11 periph A */
+							 AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA12 periph A */
+							 AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA13 periph A */
+							 AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA14 periph A */
+							 AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA15 periph A */
+							 AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA16 periph A */
+							 AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA17 periph A */
+							 AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA18 periph A */
+							 AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA19 periph A */
 					};
 
 					pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
 						atmel,pins =
-							<0 6 0x2 0x0	/* PA6 periph B */
-							 0 7 0x2 0x0	/* PA7 periph B */
-							 0 8 0x2 0x0	/* PA8 periph B */
-							 0 9 0x2 0x0	/* PA9 periph B */
-							 0 27 0x2 0x0	/* PA27 periph B */
-							 0 28 0x2 0x0	/* PA28 periph B */
-							 0 29 0x2 0x0	/* PA29 periph B */
-							 0 30 0x2 0x0>;	/* PA30 periph B */
+							<AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA6 periph B */
+							 AT91_PIOA 7 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA7 periph B */
+							 AT91_PIOA 8 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA8 periph B */
+							 AT91_PIOA 9 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA9 periph B */
+							 AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA27 periph B */
+							 AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA28 periph B */
+							 AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA29 periph B */
+							 AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA30 periph B */
 					};
 				};
 
 				mmc0 {
 					pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
 						atmel,pins =
-							<0 0 0x1 0x0	/* PA0 periph A */
-							 0 1 0x1 0x1	/* PA1 periph A with pullup */
-							 0 2 0x1 0x1>;	/* PA2 periph A with pullup */
+							<AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA0 periph A */
+							 AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA1 periph A with pullup */
+							 AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA2 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
 						atmel,pins =
-							<0 3 0x1 0x1	/* PA3 periph A with pullup */
-							 0 4 0x1 0x1	/* PA4 periph A with pullup */
-							 0 5 0x1 0x1>;	/* PA5 periph A with pullup */
+							<AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA3 periph A with pullup */
+							 AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA4 periph A with pullup */
+							 AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA5 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 {
 						atmel,pins =
-							<0 6 0x1 0x1	/* PA6 periph A with pullup */
-							 0 7 0x1 0x1	/* PA7 periph A with pullup */
-							 0 8 0x1 0x1	/* PA8 periph A with pullup */
-							 0 9 0x1 0x1>;	/* PA9 periph A with pullup */
+							<AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA6 periph A with pullup */
+							 AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA7 periph A with pullup */
+							 AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA8 periph A with pullup */
+							 AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA9 periph A with pullup */
 					};
 				};
 
 				mmc1 {
 					pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 {
 						atmel,pins =
-							<0 31 0x1 0x0	/* PA31 periph A */
-							 0 22 0x1 0x1	/* PA22 periph A with pullup */
-							 0 23 0x1 0x1>;	/* PA23 periph A with pullup */
+							<AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA31 periph A */
+							 AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA22 periph A with pullup */
+							 AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA23 periph A with pullup */
 					};
 
 					pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
 						atmel,pins =
-							<0 24 0x1 0x1	/* PA24 periph A with pullup */
-							 0 25 0x1 0x1	/* PA25 periph A with pullup */
-							 0 26 0x1 0x1>;	/* PA26 periph A with pullup */
+							<AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA24 periph A with pullup */
+							 AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA25 periph A with pullup */
+							 AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA26 periph A with pullup */
 					};
 
 					pinctrl_mmc1_slot0_dat4_7: mmc1_slot0_dat4_7-0 {
 						atmel,pins =
-							<0 27 0x1 0x1	/* PA27 periph A with pullup */
-							 0 28 0x1 0x1	/* PA28 periph A with pullup */
-							 0 29 0x1 0x1	/* PA29 periph A with pullup */
-							 0 20 0x1 0x1>;	/* PA30 periph A with pullup */
+							<AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA27 periph A with pullup */
+							 AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA28 periph A with pullup */
+							 AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA29 periph A with pullup */
+							 AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA30 periph A with pullup */
 					};
 				};
 
 				ssc0 {
 					pinctrl_ssc0_tx: ssc0_tx-0 {
 						atmel,pins =
-							<3 0 0x1 0x0	/* PD0 periph A */
-							 3 1 0x1 0x0	/* PD1 periph A */
-							 3 2 0x1 0x0>;	/* PD2 periph A */
+							<AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD0 periph A */
+							 AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD1 periph A */
+							 AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD2 periph A */
 					};
 
 					pinctrl_ssc0_rx: ssc0_rx-0 {
 						atmel,pins =
-							<3 3 0x1 0x0	/* PD3 periph A */
-							 3 4 0x1 0x0	/* PD4 periph A */
-							 3 5 0x1 0x0>;	/* PD5 periph A */
+							<AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD3 periph A */
+							 AT91_PIOD 4 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD4 periph A */
+							 AT91_PIOD 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD5 periph A */
 					};
 				};
 
 				ssc1 {
 					pinctrl_ssc1_tx: ssc1_tx-0 {
 						atmel,pins =
-							<3 10 0x1 0x0	/* PD10 periph A */
-							 3 11 0x1 0x0	/* PD11 periph A */
-							 3 12 0x1 0x0>;	/* PD12 periph A */
+							<AT91_PIOD 10 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD10 periph A */
+							 AT91_PIOD 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD11 periph A */
+							 AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD12 periph A */
 					};
 
 					pinctrl_ssc1_rx: ssc1_rx-0 {
 						atmel,pins =
-							<3 13 0x1 0x0	/* PD13 periph A */
-							 3 14 0x1 0x0	/* PD14 periph A */
-							 3 15 0x1 0x0>;	/* PD15 periph A */
+							<AT91_PIOD 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD13 periph A */
+							 AT91_PIOD 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD14 periph A */
+							 AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD15 periph A */
 					};
 				};
 
 				spi0 {
 					pinctrl_spi0: spi0-0 {
 						atmel,pins =
-							<1 0 0x1 0x0	/* PB0 periph A SPI0_MISO pin */
-							 1 1 0x1 0x0	/* PB1 periph A SPI0_MOSI pin */
-							 1 2 0x1 0x0>;	/* PB2 periph A SPI0_SPCK pin */
+							<AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB0 periph A SPI0_MISO pin */
+							 AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB1 periph A SPI0_MOSI pin */
+							 AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB2 periph A SPI0_SPCK pin */
 					};
 				};
 
 				spi1 {
 					pinctrl_spi1: spi1-0 {
 						atmel,pins =
-							<1 14 0x1 0x0	/* PB14 periph A SPI1_MISO pin */
-							 1 15 0x1 0x0	/* PB15 periph A SPI1_MOSI pin */
-							 1 16 0x1 0x0>;	/* PB16 periph A SPI1_SPCK pin */
+							<AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB14 periph A SPI1_MISO pin */
+							 AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB15 periph A SPI1_MOSI pin */
+							 AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB16 periph A SPI1_SPCK pin */
+					};
+				};
+
+				tcb0 {
+					pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+						atmel,pins = <AT91_PIOD 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+						atmel,pins = <AT91_PIOD 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+						atmel,pins = <AT91_PIOC 10 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+						atmel,pins = <AT91_PIOD 20 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+						atmel,pins = <AT91_PIOD 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+						atmel,pins = <AT91_PIOD 22 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+						atmel,pins = <AT91_PIOD 30 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+						atmel,pins = <AT91_PIOD 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+						atmel,pins = <AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+				};
+
+				tcb1 {
+					pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+						atmel,pins = <AT91_PIOA 0 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+						atmel,pins = <AT91_PIOA 3 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+						atmel,pins = <AT91_PIOD 9 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+						atmel,pins = <AT91_PIOA 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+						atmel,pins = <AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+						atmel,pins = <AT91_PIOD 7 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+						atmel,pins = <AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+						atmel,pins = <AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+						atmel,pins = <AT91_PIOD 8 AT91_PERIPH_B AT91_PINCTRL_NONE>;
 					};
 				};
 
 				pioA: gpio@fffff200 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff200 0x200>;
-					interrupts = <2 4 1>;
+					interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -354,7 +438,7 @@
 				pioB: gpio@fffff400 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff400 0x200>;
-					interrupts = <3 4 1>;
+					interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -364,7 +448,7 @@
 				pioC: gpio@fffff600 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff600 0x200>;
-					interrupts = <4 4 1>;
+					interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -374,7 +458,7 @@
 				pioD: gpio@fffff800 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffff800 0x200>;
-					interrupts = <5 4 1>;
+					interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -384,7 +468,7 @@
 				pioE: gpio@fffffa00 {
 					compatible = "atmel,at91rm9200-gpio";
 					reg = <0xfffffa00 0x200>;
-					interrupts = <5 4 1>;
+					interrupts = <5 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -395,7 +479,7 @@
 			dbgu: serial@ffffee00 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xffffee00 0x200>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_dbgu>;
 				status = "disabled";
@@ -404,7 +488,7 @@
 			usart0: serial@fff8c000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfff8c000 0x200>;
-				interrupts = <7 4 5>;
+				interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -415,7 +499,7 @@
 			usart1: serial@fff90000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfff90000 0x200>;
-				interrupts = <8 4 5>;
+				interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -426,7 +510,7 @@
 			usart2: serial@fff94000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfff94000 0x200>;
-				interrupts = <9 4 5>;
+				interrupts = <9 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -437,7 +521,7 @@
 			usart3: serial@fff98000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfff98000 0x200>;
-				interrupts = <10 4 5>;
+				interrupts = <10 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,use-dma-rx;
 				atmel,use-dma-tx;
 				pinctrl-names = "default";
@@ -448,7 +532,7 @@
 			macb0: ethernet@fffbc000 {
 				compatible = "cdns,at32ap7000-macb", "cdns,macb";
 				reg = <0xfffbc000 0x100>;
-				interrupts = <25 4 3>;
+				interrupts = <25 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_macb_rmii>;
 				status = "disabled";
@@ -457,7 +541,7 @@
 			i2c0: i2c@fff84000 {
 				compatible = "atmel,at91sam9g10-i2c";
 				reg = <0xfff84000 0x100>;
-				interrupts = <12 4 6>;
+				interrupts = <12 IRQ_TYPE_LEVEL_HIGH 6>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
@@ -466,7 +550,7 @@
 			i2c1: i2c@fff88000 {
 				compatible = "atmel,at91sam9g10-i2c";
 				reg = <0xfff88000 0x100>;
-				interrupts = <13 4 6>;
+				interrupts = <13 IRQ_TYPE_LEVEL_HIGH 6>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
@@ -475,7 +559,7 @@
 			ssc0: ssc@fff9c000 {
 				compatible = "atmel,at91sam9g45-ssc";
 				reg = <0xfff9c000 0x4000>;
-				interrupts = <16 4 5>;
+				interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
 				status = "disabled";
@@ -484,7 +568,7 @@
 			ssc1: ssc@fffa0000 {
 				compatible = "atmel,at91sam9g45-ssc";
 				reg = <0xfffa0000 0x4000>;
-				interrupts = <17 4 5>;
+				interrupts = <17 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
 				status = "disabled";
@@ -493,7 +577,7 @@
 			adc0: adc@fffb0000 {
 				compatible = "atmel,at91sam9260-adc";
 				reg = <0xfffb0000 0x100>;
-				interrupts = <20 4 0>;
+				interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
 				atmel,adc-use-external-triggers;
 				atmel,adc-channels-used = <0xff>;
 				atmel,adc-vref = <3300>;
@@ -533,8 +617,8 @@
 			mmc0: mmc@fff80000 {
 				compatible = "atmel,hsmci";
 				reg = <0xfff80000 0x600>;
-				interrupts = <11 4 0>;
-				dmas = <&dma 1 0>;
+				interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma 1 AT91_DMA_CFG_PER_ID(0)>;
 				dma-names = "rxtx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -544,8 +628,8 @@
 			mmc1: mmc@fffd0000 {
 				compatible = "atmel,hsmci";
 				reg = <0xfffd0000 0x600>;
-				interrupts = <29 4 0>;
-				dmas = <&dma 1 13>;
+				interrupts = <29 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma 1 AT91_DMA_CFG_PER_ID(13)>;
 				dma-names = "rxtx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -579,6 +663,68 @@
 				pinctrl-0 = <&pinctrl_spi1>;
 				status = "disabled";
 			};
+
+			usb2: gadget@fff78000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "atmel,at91sam9rl-udc";
+				reg = <0x00600000 0x80000
+				       0xfff78000 0x400>;
+				interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
+				status = "disabled";
+
+				ep0 {
+					reg = <0>;
+					atmel,fifo-size = <64>;
+					atmel,nb-banks = <1>;
+				};
+
+				ep1 {
+					reg = <1>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep2 {
+					reg = <2>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep3 {
+					reg = <3>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep4 {
+					reg = <4>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep5 {
+					reg = <5>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep6 {
+					reg = <6>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+			};
 		};
 
 		nand0: nand@40000000 {
@@ -592,8 +738,8 @@
 			atmel,nand-cmd-offset = <22>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_nand>;
-			gpios = <&pioC 8 0
-				 &pioC 14 0
+			gpios = <&pioC 8 GPIO_ACTIVE_HIGH
+				 &pioC 14 GPIO_ACTIVE_HIGH
 				 0
 				>;
 			status = "disabled";
@@ -602,22 +748,22 @@
 		usb0: ohci@00700000 {
 			compatible = "atmel,at91rm9200-ohci", "usb-ohci";
 			reg = <0x00700000 0x100000>;
-			interrupts = <22 4 2>;
+			interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 
 		usb1: ehci@00800000 {
 			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
 			reg = <0x00800000 0x100000>;
-			interrupts = <22 4 2>;
+			interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 	};
 
 	i2c@0 {
 		compatible = "i2c-gpio";
-		gpios = <&pioA 20 0 /* sda */
-			 &pioA 21 0 /* scl */
+		gpios = <&pioA 20 GPIO_ACTIVE_HIGH /* sda */
+			 &pioA 21 GPIO_ACTIVE_HIGH /* scl */
 			>;
 		i2c-gpio,sda-open-drain;
 		i2c-gpio,scl-open-drain;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9m10g45ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9m10g45ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9m10g45ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9m10g45ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9g45.dtsi"
+#include "at91sam9g45.dtsi"
 
 / {
 	model = "Atmel AT91SAM9M10G45-EK";
@@ -59,6 +59,10 @@
 				status = "okay";
 			};
 
+			watchdog@fffffd40 {
+				status = "okay";
+			};
+
 			mmc0: mmc@fff80000 {
 				pinctrl-0 = <
 					&pinctrl_board_mmc0
@@ -68,7 +72,7 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioD 10 0>;
+					cd-gpios = <&pioD 10 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -81,8 +85,8 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioD 11 0>;
-					wp-gpios = <&pioD 29 0>;
+					cd-gpios = <&pioD 11 GPIO_ACTIVE_HIGH>;
+					wp-gpios = <&pioD 29 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -90,15 +94,15 @@
 				mmc0 {
 					pinctrl_board_mmc0: mmc0-board {
 						atmel,pins =
-							<3 10 0x0 0x5>;	/* PD10 gpio CD pin pull up and deglitch */
+							<AT91_PIOD 10 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;	/* PD10 gpio CD pin pull up and deglitch */
 					};
 				};
 
 				mmc1 {
 					pinctrl_board_mmc1: mmc1-board {
 						atmel,pins =
-							<3 11 0x0 0x5	/* PD11 gpio CD pin pull up and deglitch */
-							 3 29 0x0 0x1>;	/* PD29 gpio WP pin pull up */
+							<AT91_PIOD 11 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH	/* PD11 gpio CD pin pull up and deglitch */
+							 AT91_PIOD 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;	/* PD29 gpio WP pin pull up */
 					};
 				};
 			};
@@ -112,6 +116,11 @@
 					reg = <0>;
 				};
 			};
+
+			usb2: gadget@fff78000 {
+				atmel,vbus-gpio = <&pioB 19 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+			};
 		};
 
 		nand0: nand@40000000 {
@@ -139,8 +148,8 @@
 		usb0: ohci@00700000 {
 			status = "okay";
 			num-ports = <2>;
-			atmel,vbus-gpio = <&pioD 1 1
-					   &pioD 3 1>;
+			atmel,vbus-gpio = <&pioD 1 GPIO_ACTIVE_LOW
+					   &pioD 3 GPIO_ACTIVE_LOW>;
 		};
 
 		usb1: ehci@00800000 {
@@ -153,19 +162,19 @@
 
 		d8 {
 			label = "d8";
-			gpios = <&pioD 30 0>;
+			gpios = <&pioD 30 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 
 		d6 {
 			label = "d6";
-			gpios = <&pioD 0 1>;
+			gpios = <&pioD 0 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "nand-disk";
 		};
 
 		d7 {
 			label = "d7";
-			gpios = <&pioD 31 1>;
+			gpios = <&pioD 31 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "mmc0";
 		};
 	};
@@ -175,45 +184,45 @@
 
 		left_click {
 			label = "left_click";
-			gpios = <&pioB 6 1>;
+			gpios = <&pioB 6 GPIO_ACTIVE_LOW>;
 			linux,code = <272>;
 			gpio-key,wakeup;
 		};
 
 		right_click {
 			label = "right_click";
-			gpios = <&pioB 7 1>;
+			gpios = <&pioB 7 GPIO_ACTIVE_LOW>;
 			linux,code = <273>;
 			gpio-key,wakeup;
 		};
 
 		left {
 			label = "Joystick Left";
-			gpios = <&pioB 14 1>;
+			gpios = <&pioB 14 GPIO_ACTIVE_LOW>;
 			linux,code = <105>;
 		};
 
 		right {
 			label = "Joystick Right";
-			gpios = <&pioB 15 1>;
+			gpios = <&pioB 15 GPIO_ACTIVE_LOW>;
 			linux,code = <106>;
 		};
 
 		up {
 			label = "Joystick Up";
-			gpios = <&pioB 16 1>;
+			gpios = <&pioB 16 GPIO_ACTIVE_LOW>;
 			linux,code = <103>;
 		};
 
 		down {
 			label = "Joystick Down";
-			gpios = <&pioB 17 1>;
+			gpios = <&pioB 17 GPIO_ACTIVE_LOW>;
 			linux,code = <108>;
 		};
 
 		enter {
 			label = "Joystick Press";
-			gpios = <&pioB 18 1>;
+			gpios = <&pioB 18 GPIO_ACTIVE_LOW>;
 			linux,code = <28>;
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9n12.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9n12.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9n12.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9n12.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,11 @@
  * Licensed under GPLv2 or later.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Atmel AT91SAM9N12 SoC";
@@ -31,8 +35,12 @@
 		ssc0 = &ssc0;
 	};
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
@@ -78,7 +86,7 @@
 			pit: timer@fffffe30 {
 				compatible = "atmel,at91sam9260-pit";
 				reg = <0xfffffe30 0xf>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 			};
 
 			shdwc@fffffe10 {
@@ -89,8 +97,8 @@
 			mmc0: mmc@f0008000 {
 				compatible = "atmel,hsmci";
 				reg = <0xf0008000 0x600>;
-				interrupts = <12 4 0>;
-				dmas = <&dma 1 0>;
+				interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma 1 AT91_DMA_CFG_PER_ID(0)>;
 				dma-names = "rxtx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -100,19 +108,19 @@
 			tcb0: timer@f8008000 {
 				compatible = "atmel,at91sam9x5-tcb";
 				reg = <0xf8008000 0x100>;
-				interrupts = <17 4 0>;
+				interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			tcb1: timer@f800c000 {
 				compatible = "atmel,at91sam9x5-tcb";
 				reg = <0xf800c000 0x100>;
-				interrupts = <17 4 0>;
+				interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			dma: dma-controller@ffffec00 {
 				compatible = "atmel,at91sam9g45-dma";
 				reg = <0xffffec00 0x200>;
-				interrupts = <20 4 0>;
+				interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
 				#dma-cells = <2>;
 			};
 
@@ -134,159 +142,235 @@
 				dbgu {
 					pinctrl_dbgu: dbgu-0 {
 						atmel,pins =
-							<0 9 0x1 0x0	/* PA9 periph A */
-							 0 10 0x1 0x1>;	/* PA10 periph with pullup */
+							<AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA9 periph A */
+							 AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA10 periph with pullup */
 					};
 				};
 
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<0 1 0x1 0x1	/* PA1 periph A with pullup */
-							 0 0 0x1 0x0>;	/* PA0 periph A */
+							<AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA1 periph A with pullup */
+							 AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA0 periph A */
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
 						atmel,pins =
-							<0 2 0x1 0x0>;	/* PA2 periph A */
+							<AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA2 periph A */
 					};
 
 					pinctrl_usart0_cts: usart0_cts-0 {
 						atmel,pins =
-							<0 3 0x1 0x0>;	/* PA3 periph A */
+							<AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA3 periph A */
 					};
 				};
 
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<0 6 0x1 0x1	/* PA6 periph A with pullup */
-							 0 5 0x1 0x0>;	/* PA5 periph A */
+							<AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA6 periph A with pullup */
+							 AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA5 periph A */
 					};
 				};
 
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<0 8 0x1 0x1	/* PA8 periph A with pullup */
-							 0 7 0x1 0x0>;	/* PA7 periph A */
+							<AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA8 periph A with pullup */
+							 AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA7 periph A */
 					};
 
 					pinctrl_usart2_rts: usart2_rts-0 {
 						atmel,pins =
-							<1 0 0x2 0x0>;	/* PB0 periph B */
+							<AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB0 periph B */
 					};
 
 					pinctrl_usart2_cts: usart2_cts-0 {
 						atmel,pins =
-							<1 1 0x2 0x0>;	/* PB1 periph B */
+							<AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB1 periph B */
 					};
 				};
 
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<2 23 0x2 0x1	/* PC23 periph B with pullup */
-							 2 22 0x2 0x0>;	/* PC22 periph B */
+							<AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PC23 periph B with pullup */
+							 AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC22 periph B */
 					};
 
 					pinctrl_usart3_rts: usart3_rts-0 {
 						atmel,pins =
-							<2 24 0x2 0x0>;	/* PC24 periph B */
+							<AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC24 periph B */
 					};
 
 					pinctrl_usart3_cts: usart3_cts-0 {
 						atmel,pins =
-							<2 25 0x2 0x0>;	/* PC25 periph B */
+							<AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC25 periph B */
 					};
 				};
 
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<2 9 0x3 0x1	/* PC9 periph C with pullup */
-							 2 8 0x3 0x0>;	/* PC8 periph C */
+							<AT91_PIOC 9 AT91_PERIPH_C AT91_PINCTRL_PULL_UP	/* PC9 periph C with pullup */
+							 AT91_PIOC 8 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PC8 periph C */
 					};
 				};
 
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<2 16 0x3 0x1	/* PC17 periph C with pullup */
-							 2 17 0x3 0x0>;	/* PC16 periph C */
+							<AT91_PIOC 16 AT91_PERIPH_C AT91_PINCTRL_PULL_UP	/* PC17 periph C with pullup */
+							 AT91_PIOC 17 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PC16 periph C */
 					};
 				};
 
 				nand {
 					pinctrl_nand: nand-0 {
 						atmel,pins =
-							<3 5 0x0 0x1	/* PD5 gpio RDY pin pull_up*/
-							 3 4 0x0 0x1>;	/* PD4 gpio enable pin pull_up */
+							<AT91_PIOD 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP	/* PD5 gpio RDY pin pull_up*/
+							 AT91_PIOD 4 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;	/* PD4 gpio enable pin pull_up */
 					};
 				};
 
 				mmc0 {
 					pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
 						atmel,pins =
-							<0 17 0x1 0x0	/* PA17 periph A */
-							 0 16 0x1 0x1	/* PA16 periph A with pullup */
-							 0 15 0x1 0x1>;	/* PA15 periph A with pullup */
+							<AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA17 periph A */
+							 AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA16 periph A with pullup */
+							 AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA15 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
 						atmel,pins =
-							<0 18 0x1 0x1	/* PA18 periph A with pullup */
-							 0 19 0x1 0x1	/* PA19 periph A with pullup */
-							 0 20 0x1 0x1>;	/* PA20 periph A with pullup */
+							<AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA18 periph A with pullup */
+							 AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA19 periph A with pullup */
+							 AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA20 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 {
 						atmel,pins =
-							<0 11 0x2 0x1	/* PA11 periph B with pullup */
-							 0 12 0x2 0x1	/* PA12 periph B with pullup */
-							 0 13 0x2 0x1	/* PA13 periph B with pullup */
-							 0 14 0x2 0x1>;	/* PA14 periph B with pullup */
+							<AT91_PIOA 11 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA11 periph B with pullup */
+							 AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA12 periph B with pullup */
+							 AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA13 periph B with pullup */
+							 AT91_PIOA 14 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PA14 periph B with pullup */
 					};
 				};
 
 				ssc0 {
 					pinctrl_ssc0_tx: ssc0_tx-0 {
 						atmel,pins =
-							<0 24 0x2 0x0	/* PA24 periph B */
-							 0 25 0x2 0x0	/* PA25 periph B */
-							 0 26 0x2 0x0>;	/* PA26 periph B */
+							<AT91_PIOA 24 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA24 periph B */
+							 AT91_PIOA 25 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA25 periph B */
+							 AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA26 periph B */
 					};
 
 					pinctrl_ssc0_rx: ssc0_rx-0 {
 						atmel,pins =
-							<0 27 0x2 0x0	/* PA27 periph B */
-							 0 28 0x2 0x0	/* PA28 periph B */
-							 0 29 0x2 0x0>;	/* PA29 periph B */
+							<AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA27 periph B */
+							 AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA28 periph B */
+							 AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA29 periph B */
 					};
 				};
 
 				spi0 {
 					pinctrl_spi0: spi0-0 {
 						atmel,pins =
-							<0 11 0x1 0x0	/* PA11 periph A SPI0_MISO pin */
-							 0 12 0x1 0x0	/* PA12 periph A SPI0_MOSI pin */
-							 0 13 0x1 0x0>;	/* PA13 periph A SPI0_SPCK pin */
+							<AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA11 periph A SPI0_MISO pin */
+							 AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA12 periph A SPI0_MOSI pin */
+							 AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA13 periph A SPI0_SPCK pin */
 					};
 				};
 
 				spi1 {
 					pinctrl_spi1: spi1-0 {
 						atmel,pins =
-							<0 21 0x2 0x0	/* PA21 periph B SPI1_MISO pin */
-							 0 22 0x2 0x0	/* PA22 periph B SPI1_MOSI pin */
-							 0 23 0x2 0x0>;	/* PA23 periph B SPI1_SPCK pin */
+							<AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA21 periph B SPI1_MISO pin */
+							 AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA22 periph B SPI1_MOSI pin */
+							 AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA23 periph B SPI1_SPCK pin */
+					};
+				};
+
+				tcb0 {
+					pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+						atmel,pins = <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+						atmel,pins = <AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+						atmel,pins = <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+						atmel,pins = <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+						atmel,pins = <AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+						atmel,pins = <AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+						atmel,pins = <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+						atmel,pins = <AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+						atmel,pins = <AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+				};
+
+				tcb1 {
+					pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+						atmel,pins = <AT91_PIOC 4 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+						atmel,pins = <AT91_PIOC 7 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+						atmel,pins = <AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+						atmel,pins = <AT91_PIOC 2 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+						atmel,pins = <AT91_PIOC 5 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+						atmel,pins = <AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+						atmel,pins = <AT91_PIOC 3 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+						atmel,pins = <AT91_PIOC 6 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+						atmel,pins = <AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE>;
 					};
 				};
 
 				pioA: gpio@fffff400 {
 					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
 					reg = <0xfffff400 0x200>;
-					interrupts = <2 4 1>;
+					interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -296,7 +380,7 @@
 				pioB: gpio@fffff600 {
 					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
 					reg = <0xfffff600 0x200>;
-					interrupts = <2 4 1>;
+					interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -306,7 +390,7 @@
 				pioC: gpio@fffff800 {
 					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
 					reg = <0xfffff800 0x200>;
-					interrupts = <3 4 1>;
+					interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -316,7 +400,7 @@
 				pioD: gpio@fffffa00 {
 					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
 					reg = <0xfffffa00 0x200>;
-					interrupts = <3 4 1>;
+					interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -327,7 +411,7 @@
 			dbgu: serial@fffff200 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfffff200 0x200>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_dbgu>;
 				status = "disabled";
@@ -336,7 +420,7 @@
 			ssc0: ssc@f0010000 {
 				compatible = "atmel,at91sam9g45-ssc";
 				reg = <0xf0010000 0x4000>;
-				interrupts = <28 4 5>;
+				interrupts = <28 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
 				status = "disabled";
@@ -345,7 +429,7 @@
 			usart0: serial@f801c000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf801c000 0x4000>;
-				interrupts = <5 4 5>;
+				interrupts = <5 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart0>;
 				status = "disabled";
@@ -354,7 +438,7 @@
 			usart1: serial@f8020000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf8020000 0x4000>;
-				interrupts = <6 4 5>;
+				interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart1>;
 				status = "disabled";
@@ -363,7 +447,7 @@
 			usart2: serial@f8024000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf8024000 0x4000>;
-				interrupts = <7 4 5>;
+				interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart2>;
 				status = "disabled";
@@ -372,7 +456,7 @@
 			usart3: serial@f8028000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf8028000 0x4000>;
-				interrupts = <8 4 5>;
+				interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart3>;
 				status = "disabled";
@@ -381,9 +465,9 @@
 			i2c0: i2c@f8010000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf8010000 0x100>;
-				interrupts = <9 4 6>;
-				dmas = <&dma 1 13>,
-				       <&dma 1 14>;
+				interrupts = <9 IRQ_TYPE_LEVEL_HIGH 6>;
+				dmas = <&dma 1 AT91_DMA_CFG_PER_ID(13)>,
+				       <&dma 1 AT91_DMA_CFG_PER_ID(14)>;
 				dma-names = "tx", "rx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -393,9 +477,9 @@
 			i2c1: i2c@f8014000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf8014000 0x100>;
-				interrupts = <10 4 6>;
-				dmas = <&dma 1 15>,
-				       <&dma 1 16>;
+				interrupts = <10 IRQ_TYPE_LEVEL_HIGH 6>;
+				dmas = <&dma 1 AT91_DMA_CFG_PER_ID(15)>,
+				       <&dma 1 AT91_DMA_CFG_PER_ID(16)>;
 				dma-names = "tx", "rx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -407,7 +491,10 @@
 				#size-cells = <0>;
 				compatible = "atmel,at91rm9200-spi";
 				reg = <0xf0000000 0x100>;
-				interrupts = <13 4 3>;
+				interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+				dmas = <&dma 1 AT91_DMA_CFG_PER_ID(1)>,
+				       <&dma 1 AT91_DMA_CFG_PER_ID(2)>;
+				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi0>;
 				status = "disabled";
@@ -418,11 +505,20 @@
 				#size-cells = <0>;
 				compatible = "atmel,at91rm9200-spi";
 				reg = <0xf0004000 0x100>;
-				interrupts = <14 4 3>;
+				interrupts = <14 IRQ_TYPE_LEVEL_HIGH 3>;
+				dmas = <&dma 1 AT91_DMA_CFG_PER_ID(3)>,
+				       <&dma 1 AT91_DMA_CFG_PER_ID(4)>;
+				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi1>;
 				status = "disabled";
 			};
+
+			watchdog@fffffe40 {
+				compatible = "atmel,at91sam9260-wdt";
+				reg = <0xfffffe40 0x10>;
+				status = "disabled";
+			};
 		};
 
 		nand0: nand@40000000 {
@@ -439,8 +535,8 @@
 			atmel,nand-cmd-offset = <22>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_nand>;
-			gpios = <&pioD 5 0
-				 &pioD 4 0
+			gpios = <&pioD 5 GPIO_ACTIVE_HIGH
+				 &pioD 4 GPIO_ACTIVE_HIGH
 				 0
 				>;
 			status = "disabled";
@@ -449,15 +545,15 @@
 		usb0: ohci@00500000 {
 			compatible = "atmel,at91rm9200-ohci", "usb-ohci";
 			reg = <0x00500000 0x00100000>;
-			interrupts = <22 4 2>;
+			interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 	};
 
 	i2c@0 {
 		compatible = "i2c-gpio";
-		gpios = <&pioA 30 0 /* sda */
-			 &pioA 31 0 /* scl */
+		gpios = <&pioA 30 GPIO_ACTIVE_HIGH /* sda */
+			 &pioA 31 GPIO_ACTIVE_HIGH /* scl */
 			>;
 		i2c-gpio,sda-open-drain;
 		i2c-gpio,scl-open-drain;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9n12ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9n12ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9n12ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9n12ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,18 +7,18 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9n12.dtsi"
+#include "at91sam9n12.dtsi"
 
 / {
 	model = "Atmel AT91SAM9N12-EK";
 	compatible = "atmel,at91sam9n12ek", "atmel,at91sam9n12", "atmel,at91sam9";
 
 	chosen {
-		bootargs = "mem=128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2";
+		bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2";
 	};
 
 	memory {
-		reg = <0x20000000 0x10000000>;
+		reg = <0x20000000 0x8000000>;
 	};
 
 	clocks {
@@ -55,7 +55,7 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioA 7 0>;
+					cd-gpios = <&pioA 7 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -63,7 +63,7 @@
 				mmc0 {
 					pinctrl_board_mmc0: mmc0-board {
 						atmel,pins =
-							<0 7 0x0 0x5>;	/* PA7 gpio CD pin pull up and deglitch */
+							<AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;	/* PA7 gpio CD pin pull up and deglitch */
 					};
 				};
 			};
@@ -77,6 +77,10 @@
 					reg = <0>;
 				};
 			};
+
+			watchdog@fffffe40 {
+				status = "okay";
+			};
 		};
 
 		nand0: nand@40000000 {
@@ -95,19 +99,19 @@
 
 		d8 {
 			label = "d8";
-			gpios = <&pioB 4 1>;
+			gpios = <&pioB 4 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "mmc0";
 		};
 
 		d9 {
 			label = "d6";
-			gpios = <&pioB 5 1>;
+			gpios = <&pioB 5 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "nand-disk";
 		};
 
 		d10 {
 			label = "d7";
-			gpios = <&pioB 6 0>;
+			gpios = <&pioB 6 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 	};
@@ -117,7 +121,7 @@
 
 		enter {
 			label = "Enter";
-			gpios = <&pioB 4 1>;
+			gpios = <&pioB 4 GPIO_ACTIVE_LOW>;
 			linux,code = <28>;
 			gpio-key,wakeup;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x25.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x25.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x25.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x25.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 
-/include/ "at91sam9x5.dtsi"
+#include "at91sam9x5.dtsi"
 
 / {
 	model = "Atmel AT91SAM9X25 SoC";
@@ -26,16 +26,16 @@
 				macb1 {
 					pinctrl_macb1_rmii: macb1_rmii-0 {
 						atmel,pins =
-							<2 16 0x2 0x0	/* PC16 periph B */
-							 2 18 0x2 0x0	/* PC18 periph B */
-							 2 19 0x2 0x0	/* PC19 periph B */
-							 2 20 0x2 0x0	/* PC20 periph B */
-							 2 21 0x2 0x0	/* PC21 periph B */
-							 2 27 0x2 0x0	/* PC27 periph B */
-							 2 28 0x2 0x0	/* PC28 periph B */
-							 2 29 0x2 0x0	/* PC29 periph B */
-							 2 30 0x2 0x0	/* PC30 periph B */
-							 2 31 0x2 0x0>;	/* PC31 periph B */
+							<AT91_PIOC 16 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC16 periph B */
+							 AT91_PIOC 18 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC18 periph B */
+							 AT91_PIOC 19 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC19 periph B */
+							 AT91_PIOC 20 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC20 periph B */
+							 AT91_PIOC 21 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC21 periph B */
+							 AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC27 periph B */
+							 AT91_PIOC 28 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC28 periph B */
+							 AT91_PIOC 29 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC29 periph B */
+							 AT91_PIOC 30 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC30 periph B */
+							 AT91_PIOC 31 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC31 periph B */
 					};
 				};
 			};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x25ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x25ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x25ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x25ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9x25.dtsi"
-/include/ "at91sam9x5ek.dtsi"
+#include "at91sam9x25.dtsi"
+#include "at91sam9x5ek.dtsi"
 
 / {
 	model = "Atmel AT91SAM9X25-EK";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x35.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x35.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x35.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x35.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 
-/include/ "at91sam9x5.dtsi"
+#include "at91sam9x5.dtsi"
 
 / {
 	model = "Atmel AT91SAM9X35 SoC";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x35ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x35ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x35ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x35ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9x35.dtsi"
-/include/ "at91sam9x5ek.dtsi"
+#include "at91sam9x35.dtsi"
+#include "at91sam9x5ek.dtsi"
 
 / {
 	model = "Atmel AT91SAM9X35-EK";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x5cm.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x5cm.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x5cm.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x5cm.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,7 @@
 			pinctrl@fffff400 {
 				1wire_cm {
 					pinctrl_1wire_cm: 1wire_cm-0 {
-						atmel,pins = <1 18 0x0 0x2>; /* PB18 multidrive, conflicts with led */
+						atmel,pins = <AT91_PIOB 18 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>; /* PB18 multidrive, conflicts with led */
 					};
 				};
 			};
@@ -75,19 +75,19 @@
 
 		pb18 {
 			label = "pb18";
-			gpios = <&pioB 18 1>;
+			gpios = <&pioB 18 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
 		};
 
 		pd21 {
 			label = "pd21";
-			gpios = <&pioD 21 0>;
+			gpios = <&pioD 21 GPIO_ACTIVE_HIGH>;
 		};
 	};
 
 	1wire_cm {
 		compatible = "w1-gpio";
-		gpios = <&pioB 18 0>;
+		gpios = <&pioB 18 GPIO_ACTIVE_HIGH>;
 		linux,open-drain;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_1wire_cm>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x5.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x5.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x5.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x5.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,11 @@
  * Licensed under GPLv2 or later.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Atmel AT91SAM9x5 family SoC";
@@ -33,8 +37,12 @@
 		ssc0 = &ssc0;
 	};
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
@@ -85,32 +93,32 @@
 			pit: timer@fffffe30 {
 				compatible = "atmel,at91sam9260-pit";
 				reg = <0xfffffe30 0xf>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 			};
 
 			tcb0: timer@f8008000 {
 				compatible = "atmel,at91sam9x5-tcb";
 				reg = <0xf8008000 0x100>;
-				interrupts = <17 4 0>;
+				interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			tcb1: timer@f800c000 {
 				compatible = "atmel,at91sam9x5-tcb";
 				reg = <0xf800c000 0x100>;
-				interrupts = <17 4 0>;
+				interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			dma0: dma-controller@ffffec00 {
 				compatible = "atmel,at91sam9g45-dma";
 				reg = <0xffffec00 0x200>;
-				interrupts = <20 4 0>;
+				interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
 				#dma-cells = <2>;
 			};
 
 			dma1: dma-controller@ffffee00 {
 				compatible = "atmel,at91sam9g45-dma";
 				reg = <0xffffee00 0x200>;
-				interrupts = <21 4 0>;
+				interrupts = <21 IRQ_TYPE_LEVEL_HIGH 0>;
 				#dma-cells = <2>;
 			};
 
@@ -124,297 +132,373 @@
 				dbgu {
 					pinctrl_dbgu: dbgu-0 {
 						atmel,pins =
-							<0 9 0x1 0x0	/* PA9 periph A */
-							 0 10 0x1 0x1>;	/* PA10 periph A with pullup */
+							<AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA9 periph A */
+							 AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA10 periph A with pullup */
 					};
 				};
 
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<0 0 0x1 0x1	/* PA0 periph A with pullup */
-							 0 1 0x1 0x0>;	/* PA1 periph A */
+							<AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA0 periph A with pullup */
+							 AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA1 periph A */
 					};
 
 					pinctrl_usart0_rts: usart0_rts-0 {
 						atmel,pins =
-							<0 2 0x1 0x0>;	/* PA2 periph A */
+							<AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA2 periph A */
 					};
 
 					pinctrl_usart0_cts: usart0_cts-0 {
 						atmel,pins =
-							<0 3 0x1 0x0>;	/* PA3 periph A */
+							<AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA3 periph A */
 					};
 
 					pinctrl_usart0_sck: usart0_sck-0 {
 						atmel,pins =
-							<0 4 0x1 0x0>;	/* PA4 periph A */
+							<AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA4 periph A */
 					};
 				};
 
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<0 5 0x1 0x1	/* PA5 periph A with pullup */
-							 0 6 0x1 0x0>;	/* PA6 periph A */
+							<AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA5 periph A with pullup */
+							 AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA6 periph A */
 					};
 
 					pinctrl_usart1_rts: usart1_rts-0 {
 						atmel,pins =
-							<2 27 0x3 0x0>;	/* PC27 periph C */
+							<AT91_PIOC 27 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PC27 periph C */
 					};
 
 					pinctrl_usart1_cts: usart1_cts-0 {
 						atmel,pins =
-							<2 28 0x3 0x0>;	/* PC28 periph C */
+							<AT91_PIOC 28 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PC28 periph C */
 					};
 
 					pinctrl_usart1_sck: usart1_sck-0 {
 						atmel,pins =
-							<2 28 0x3 0x0>;	/* PC29 periph C */
+							<AT91_PIOC 28 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PC29 periph C */
 					};
 				};
 
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<0 7 0x1 0x1	/* PA7 periph A with pullup */
-							 0 8 0x1 0x0>;	/* PA8 periph A */
+							<AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA7 periph A with pullup */
+							 AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA8 periph A */
 					};
 
 					pinctrl_uart2_rts: uart2_rts-0 {
 						atmel,pins =
-							<1 0 0x2 0x0>;	/* PB0 periph B */
+							<AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB0 periph B */
 					};
 
 					pinctrl_uart2_cts: uart2_cts-0 {
 						atmel,pins =
-							<1 1 0x2 0x0>;	/* PB1 periph B */
+							<AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB1 periph B */
 					};
 
 					pinctrl_usart2_sck: usart2_sck-0 {
 						atmel,pins =
-							<1 2 0x2 0x0>;	/* PB2 periph B */
+							<AT91_PIOB 2 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB2 periph B */
 					};
 				};
 
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<2 22 0x2 0x1	/* PC22 periph B with pullup */
-							 2 23 0x2 0x0>;	/* PC23 periph B */
+							<AT91_PIOC 22 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PC22 periph B with pullup */
+							 AT91_PIOC 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC23 periph B */
 					};
 
 					pinctrl_usart3_rts: usart3_rts-0 {
 						atmel,pins =
-							<2 24 0x2 0x0>;	/* PC24 periph B */
+							<AT91_PIOC 24 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC24 periph B */
 					};
 
 					pinctrl_usart3_cts: usart3_cts-0 {
 						atmel,pins =
-							<2 25 0x2 0x0>;	/* PC25 periph B */
+							<AT91_PIOC 25 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC25 periph B */
 					};
 
 					pinctrl_usart3_sck: usart3_sck-0 {
 						atmel,pins =
-							<2 26 0x2 0x0>;	/* PC26 periph B */
+							<AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC26 periph B */
 					};
 				};
 
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<2 8 0x3 0x0	/* PC8 periph C */
-							 2 9 0x3 0x1>;	/* PC9 periph C with pullup */
+							<AT91_PIOC 8 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC8 periph C */
+							 AT91_PIOC 9 AT91_PERIPH_C AT91_PINCTRL_PULL_UP>;	/* PC9 periph C with pullup */
 					};
 				};
 
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<2 16 0x3 0x0	/* PC16 periph C */
-							 2 17 0x3 0x1>;	/* PC17 periph C with pullup */
+							<AT91_PIOC 16 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC16 periph C */
+							 AT91_PIOC 17 AT91_PERIPH_C AT91_PINCTRL_PULL_UP>;	/* PC17 periph C with pullup */
 					};
 				};
 
 				nand {
 					pinctrl_nand: nand-0 {
 						atmel,pins =
-							<3 0 0x1 0x0	/* PD0 periph A Read Enable */
-							 3 1 0x1 0x0	/* PD1 periph A Write Enable */
-							 3 2 0x1 0x0	/* PD2 periph A Address Latch Enable */
-							 3 3 0x1 0x0	/* PD3 periph A Command Latch Enable */
-							 3 4 0x0 0x1	/* PD4 gpio Chip Enable pin pull_up */
-							 3 5 0x0 0x1	/* PD5 gpio RDY/BUSY pin pull_up */
-							 3 6 0x1 0x0	/* PD6 periph A Data bit 0 */
-							 3 7 0x1 0x0	/* PD7 periph A Data bit 1 */
-							 3 8 0x1 0x0	/* PD8 periph A Data bit 2 */
-							 3 9 0x1 0x0	/* PD9 periph A Data bit 3 */
-							 3 10 0x1 0x0	/* PD10 periph A Data bit 4 */
-							 3 11 0x1 0x0	/* PD11 periph A Data bit 5 */
-							 3 12 0x1 0x0	/* PD12 periph A Data bit 6 */
-							 3 13 0x1 0x0>;	/* PD13 periph A Data bit 7 */
+							<AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD0 periph A Read Enable */
+							 AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD1 periph A Write Enable */
+							 AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD2 periph A Address Latch Enable */
+							 AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD3 periph A Command Latch Enable */
+							 AT91_PIOD 4 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP	/* PD4 gpio Chip Enable pin pull_up */
+							 AT91_PIOD 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP	/* PD5 gpio RDY/BUSY pin pull_up */
+							 AT91_PIOD 6 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD6 periph A Data bit 0 */
+							 AT91_PIOD 7 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD7 periph A Data bit 1 */
+							 AT91_PIOD 8 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD8 periph A Data bit 2 */
+							 AT91_PIOD 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD9 periph A Data bit 3 */
+							 AT91_PIOD 10 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD10 periph A Data bit 4 */
+							 AT91_PIOD 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD11 periph A Data bit 5 */
+							 AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD12 periph A Data bit 6 */
+							 AT91_PIOD 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD13 periph A Data bit 7 */
 					};
 
 					pinctrl_nand_16bits: nand_16bits-0 {
 						atmel,pins =
-							<3 14 0x1 0x0	/* PD14 periph A Data bit 8 */
-							 3 15 0x1 0x0	/* PD15 periph A Data bit 9 */
-							 3 16 0x1 0x0	/* PD16 periph A Data bit 10 */
-							 3 17 0x1 0x0	/* PD17 periph A Data bit 11 */
-							 3 18 0x1 0x0	/* PD18 periph A Data bit 12 */
-							 3 19 0x1 0x0	/* PD19 periph A Data bit 13 */
-							 3 20 0x1 0x0	/* PD20 periph A Data bit 14 */
-							 3 21 0x1 0x0>;	/* PD21 periph A Data bit 15 */
+							<AT91_PIOD 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD14 periph A Data bit 8 */
+							 AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD15 periph A Data bit 9 */
+							 AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD16 periph A Data bit 10 */
+							 AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD17 periph A Data bit 11 */
+							 AT91_PIOD 18 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD18 periph A Data bit 12 */
+							 AT91_PIOD 19 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD19 periph A Data bit 13 */
+							 AT91_PIOD 20 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD20 periph A Data bit 14 */
+							 AT91_PIOD 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD21 periph A Data bit 15 */
 					};
 				};
 
 				macb0 {
 					pinctrl_macb0_rmii: macb0_rmii-0 {
 						atmel,pins =
-							<1 0 0x1 0x0	/* PB0 periph A */
-							 1 1 0x1 0x0	/* PB1 periph A */
-							 1 2 0x1 0x0	/* PB2 periph A */
-							 1 3 0x1 0x0	/* PB3 periph A */
-							 1 4 0x1 0x0	/* PB4 periph A */
-							 1 5 0x1 0x0	/* PB5 periph A */
-							 1 6 0x1 0x0	/* PB6 periph A */
-							 1 7 0x1 0x0	/* PB7 periph A */
-							 1 9 0x1 0x0	/* PB9 periph A */
-							 1 10 0x1 0x0>;	/* PB10 periph A */
+							<AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB0 periph A */
+							 AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB1 periph A */
+							 AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB2 periph A */
+							 AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB3 periph A */
+							 AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB4 periph A */
+							 AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB5 periph A */
+							 AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB6 periph A */
+							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB7 periph A */
+							 AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB9 periph A */
+							 AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB10 periph A */
 					};
 
 					pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 {
 						atmel,pins =
-							<1 8 0x1 0x0	/* PB8 periph A */
-							 1 11 0x1 0x0	/* PB11 periph A */
-							 1 12 0x1 0x0	/* PB12 periph A */
-							 1 13 0x1 0x0	/* PB13 periph A */
-							 1 14 0x1 0x0	/* PB14 periph A */
-							 1 15 0x1 0x0	/* PB15 periph A */
-							 1 16 0x1 0x0	/* PB16 periph A */
-							 1 17 0x1 0x0>;	/* PB17 periph A */
+							<AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB8 periph A */
+							 AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB11 periph A */
+							 AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB12 periph A */
+							 AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB13 periph A */
+							 AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB14 periph A */
+							 AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB15 periph A */
+							 AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB16 periph A */
+							 AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB17 periph A */
 					};
 				};
 
 				mmc0 {
 					pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
 						atmel,pins =
-							<0 17 0x1 0x0	/* PA17 periph A */
-							 0 16 0x1 0x1	/* PA16 periph A with pullup */
-							 0 15 0x1 0x1>;	/* PA15 periph A with pullup */
+							<AT91_PIOA 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA17 periph A */
+							 AT91_PIOA 16 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA16 periph A with pullup */
+							 AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA15 periph A with pullup */
 					};
 
 					pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
 						atmel,pins =
-							<0 18 0x1 0x1	/* PA18 periph A with pullup */
-							 0 19 0x1 0x1	/* PA19 periph A with pullup */
-							 0 20 0x1 0x1>;	/* PA20 periph A with pullup */
+							<AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA18 periph A with pullup */
+							 AT91_PIOA 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PA19 periph A with pullup */
+							 AT91_PIOA 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PA20 periph A with pullup */
 					};
 				};
 
 				mmc1 {
 					pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 {
 						atmel,pins =
-							<0 13 0x2 0x0	/* PA13 periph B */
-							 0 12 0x2 0x1	/* PA12 periph B with pullup */
-							 0 11 0x2 0x1>;	/* PA11 periph B with pullup */
+							<AT91_PIOA 13 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA13 periph B */
+							 AT91_PIOA 12 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA12 periph B with pullup */
+							 AT91_PIOA 11 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PA11 periph B with pullup */
 					};
 
 					pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
 						atmel,pins =
-							<0 2 0x2 0x1	/* PA2 periph B with pullup */
-							 0 3 0x2 0x1	/* PA3 periph B with pullup */
-							 0 4 0x2 0x1>;	/* PA4 periph B with pullup */
+							<AT91_PIOA 2 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA2 periph B with pullup */
+							 AT91_PIOA 3 AT91_PERIPH_B AT91_PINCTRL_PULL_UP	/* PA3 periph B with pullup */
+							 AT91_PIOA 4 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PA4 periph B with pullup */
 					};
 				};
 
 				ssc0 {
 					pinctrl_ssc0_tx: ssc0_tx-0 {
 						atmel,pins =
-							<0 24 0x2 0x0	/* PA24 periph B */
-							 0 25 0x2 0x0	/* PA25 periph B */
-							 0 26 0x2 0x0>;	/* PA26 periph B */
+							<AT91_PIOA 24 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA24 periph B */
+							 AT91_PIOA 25 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA25 periph B */
+							 AT91_PIOA 26 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA26 periph B */
 					};
 
 					pinctrl_ssc0_rx: ssc0_rx-0 {
 						atmel,pins =
-							<0 27 0x2 0x0	/* PA27 periph B */
-							 0 28 0x2 0x0	/* PA28 periph B */
-							 0 29 0x2 0x0>;	/* PA29 periph B */
+							<AT91_PIOA 27 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA27 periph B */
+							 AT91_PIOA 28 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA28 periph B */
+							 AT91_PIOA 29 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA29 periph B */
 					};
 				};
 
 				spi0 {
 					pinctrl_spi0: spi0-0 {
 						atmel,pins =
-							<0 11 0x1 0x0	/* PA11 periph A SPI0_MISO pin */
-							 0 12 0x1 0x0	/* PA12 periph A SPI0_MOSI pin */
-							 0 13 0x1 0x0>;	/* PA13 periph A SPI0_SPCK pin */
+							<AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA11 periph A SPI0_MISO pin */
+							 AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA12 periph A SPI0_MOSI pin */
+							 AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA13 periph A SPI0_SPCK pin */
 					};
 				};
 
 				spi1 {
 					pinctrl_spi1: spi1-0 {
 						atmel,pins =
-							<0 21 0x2 0x0	/* PA21 periph B SPI1_MISO pin */
-							 0 22 0x2 0x0	/* PA22 periph B SPI1_MOSI pin */
-							 0 23 0x2 0x0>;	/* PA23 periph B SPI1_SPCK pin */
+							<AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA21 periph B SPI1_MISO pin */
+							 AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA22 periph B SPI1_MOSI pin */
+							 AT91_PIOA 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PA23 periph B SPI1_SPCK pin */
 					};
 				};
 
 				i2c0 {
 					pinctrl_i2c0: i2c0-0 {
 						atmel,pins =
-							<0 30 0x1 0x0	/* PA30 periph A I2C0 data */
-							 0 31 0x1 0x0>;	/* PA31 periph A I2C0 clock */
+							<AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA30 periph A I2C0 data */
+							 AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA31 periph A I2C0 clock */
 					};
 				};
 
 				i2c1 {
 					pinctrl_i2c1: i2c1-0 {
 						atmel,pins =
-							<2 0 0x3 0x0	/* PC0 periph C I2C1 data */
-							 2 1 0x3 0x0>;	/* PC1 periph C I2C1 clock */
+							<AT91_PIOC 0 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC0 periph C I2C1 data */
+							 AT91_PIOC 1 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PC1 periph C I2C1 clock */
 					};
 				};
 
 				i2c2 {
 					pinctrl_i2c2: i2c2-0 {
 						atmel,pins =
-							<1 4 0x2 0x0	/* PB4 periph B I2C2 data */
-							 1 5 0x2 0x0>;	/* PB5 periph B I2C2 clock */
+							<AT91_PIOB 4 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB4 periph B I2C2 data */
+							 AT91_PIOB 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB5 periph B I2C2 clock */
 					};
 				};
 
 				i2c_gpio0 {
 					pinctrl_i2c_gpio0: i2c_gpio0-0 {
 						atmel,pins =
-							<0 30 0x0 0x2	/* PA30 gpio multidrive I2C0 data */
-							 0 31 0x0 0x2>;	/* PA31 gpio multidrive I2C0 clock */
+							<AT91_PIOA 30 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE	/* PA30 gpio multidrive I2C0 data */
+							 AT91_PIOA 31 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;	/* PA31 gpio multidrive I2C0 clock */
 					};
 				};
 
 				i2c_gpio1 {
 					pinctrl_i2c_gpio1: i2c_gpio1-0 {
 						atmel,pins =
-							<2 0 0x0 0x2	/* PC0 gpio multidrive I2C1 data */
-							 2 1 0x0 0x2>;	/* PC1 gpio multidrive I2C1 clock */
+							<AT91_PIOC 0 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE	/* PC0 gpio multidrive I2C1 data */
+							 AT91_PIOC 1 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;	/* PC1 gpio multidrive I2C1 clock */
 					};
 				};
 
 				i2c_gpio2 {
 					pinctrl_i2c_gpio2: i2c_gpio2-0 {
 						atmel,pins =
-							<1 4 0x0 0x2	/* PB4 gpio multidrive I2C2 data */
-							 1 5 0x0 0x2>;	/* PB5 gpio multidrive I2C2 clock */
+							<AT91_PIOB 4 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE	/* PB4 gpio multidrive I2C2 data */
+							 AT91_PIOB 5 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;	/* PB5 gpio multidrive I2C2 clock */
+					};
+				};
+
+				tcb0 {
+					pinctrl_tcb0_tclk0: tcb0_tclk0-0 {
+						atmel,pins = <AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk1: tcb0_tclk1-0 {
+						atmel,pins = <AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tclk2: tcb0_tclk2-0 {
+						atmel,pins = <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa0: tcb0_tioa0-0 {
+						atmel,pins = <AT91_PIOA 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa1: tcb0_tioa1-0 {
+						atmel,pins = <AT91_PIOA 22 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tioa2: tcb0_tioa2-0 {
+						atmel,pins = <AT91_PIOA 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob0: tcb0_tiob0-0 {
+						atmel,pins = <AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob1: tcb0_tiob1-0 {
+						atmel,pins = <AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb0_tiob2: tcb0_tiob2-0 {
+						atmel,pins = <AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+					};
+				};
+
+				tcb1 {
+					pinctrl_tcb1_tclk0: tcb1_tclk0-0 {
+						atmel,pins = <AT91_PIOC 4 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk1: tcb1_tclk1-0 {
+						atmel,pins = <AT91_PIOC 7 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tclk2: tcb1_tclk2-0 {
+						atmel,pins = <AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa0: tcb1_tioa0-0 {
+						atmel,pins = <AT91_PIOC 2 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa1: tcb1_tioa1-0 {
+						atmel,pins = <AT91_PIOC 5 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tioa2: tcb1_tioa2-0 {
+						atmel,pins = <AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob0: tcb1_tiob0-0 {
+						atmel,pins = <AT91_PIOC 3 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob1: tcb1_tiob1-0 {
+						atmel,pins = <AT91_PIOC 6 AT91_PERIPH_C AT91_PINCTRL_NONE>;
+					};
+
+					pinctrl_tcb1_tiob2: tcb1_tiob2-0 {
+						atmel,pins = <AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE>;
 					};
 				};
 
 				pioA: gpio@fffff400 {
 					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
 					reg = <0xfffff400 0x200>;
-					interrupts = <2 4 1>;
+					interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -424,7 +508,7 @@
 				pioB: gpio@fffff600 {
 					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
 					reg = <0xfffff600 0x200>;
-					interrupts = <2 4 1>;
+					interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					#gpio-lines = <19>;
@@ -435,7 +519,7 @@
 				pioC: gpio@fffff800 {
 					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
 					reg = <0xfffff800 0x200>;
-					interrupts = <3 4 1>;
+					interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					interrupt-controller;
@@ -445,7 +529,7 @@
 				pioD: gpio@fffffa00 {
 					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
 					reg = <0xfffffa00 0x200>;
-					interrupts = <3 4 1>;
+					interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
 					#gpio-cells = <2>;
 					gpio-controller;
 					#gpio-lines = <22>;
@@ -457,7 +541,7 @@
 			ssc0: ssc@f0010000 {
 				compatible = "atmel,at91sam9g45-ssc";
 				reg = <0xf0010000 0x4000>;
-				interrupts = <28 4 5>;
+				interrupts = <28 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
 				status = "disabled";
@@ -466,8 +550,8 @@
 			mmc0: mmc@f0008000 {
 				compatible = "atmel,hsmci";
 				reg = <0xf0008000 0x600>;
-				interrupts = <12 4 0>;
-				dmas = <&dma0 1 0>;
+				interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(0)>;
 				dma-names = "rxtx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -477,8 +561,8 @@
 			mmc1: mmc@f000c000 {
 				compatible = "atmel,hsmci";
 				reg = <0xf000c000 0x600>;
-				interrupts = <26 4 0>;
-				dmas = <&dma1 1 0>;
+				interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(0)>;
 				dma-names = "rxtx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -488,7 +572,7 @@
 			dbgu: serial@fffff200 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xfffff200 0x200>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_dbgu>;
 				status = "disabled";
@@ -497,7 +581,7 @@
 			usart0: serial@f801c000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf801c000 0x200>;
-				interrupts = <5 4 5>;
+				interrupts = <5 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart0>;
 				status = "disabled";
@@ -506,7 +590,7 @@
 			usart1: serial@f8020000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf8020000 0x200>;
-				interrupts = <6 4 5>;
+				interrupts = <6 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart1>;
 				status = "disabled";
@@ -515,7 +599,7 @@
 			usart2: serial@f8024000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf8024000 0x200>;
-				interrupts = <7 4 5>;
+				interrupts = <7 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart2>;
 				status = "disabled";
@@ -524,7 +608,7 @@
 			macb0: ethernet@f802c000 {
 				compatible = "cdns,at32ap7000-macb", "cdns,macb";
 				reg = <0xf802c000 0x100>;
-				interrupts = <24 4 3>;
+				interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_macb0_rmii>;
 				status = "disabled";
@@ -533,16 +617,16 @@
 			macb1: ethernet@f8030000 {
 				compatible = "cdns,at32ap7000-macb", "cdns,macb";
 				reg = <0xf8030000 0x100>;
-				interrupts = <27 4 3>;
+				interrupts = <27 IRQ_TYPE_LEVEL_HIGH 3>;
 				status = "disabled";
 			};
 
 			i2c0: i2c@f8010000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf8010000 0x100>;
-				interrupts = <9 4 6>;
-				dmas = <&dma0 1 7>,
-				       <&dma0 1 8>;
+				interrupts = <9 IRQ_TYPE_LEVEL_HIGH 6>;
+				dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(7)>,
+				       <&dma0 1 AT91_DMA_CFG_PER_ID(8)>;
 				dma-names = "tx", "rx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -554,9 +638,9 @@
 			i2c1: i2c@f8014000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf8014000 0x100>;
-				interrupts = <10 4 6>;
-				dmas = <&dma1 1 5>,
-				       <&dma1 1 6>;
+				interrupts = <10 IRQ_TYPE_LEVEL_HIGH 6>;
+				dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(5)>,
+				       <&dma1 1 AT91_DMA_CFG_PER_ID(6)>;
 				dma-names = "tx", "rx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -568,9 +652,9 @@
 			i2c2: i2c@f8018000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf8018000 0x100>;
-				interrupts = <11 4 6>;
-				dmas = <&dma0 1 9>,
-				       <&dma0 1 10>;
+				interrupts = <11 IRQ_TYPE_LEVEL_HIGH 6>;
+				dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(9)>,
+				       <&dma0 1 AT91_DMA_CFG_PER_ID(10)>;
 				dma-names = "tx", "rx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -579,10 +663,28 @@
 				status = "disabled";
 			};
 
+			uart0: serial@f8040000 {
+				compatible = "atmel,at91sam9260-usart";
+				reg = <0xf8040000 0x200>;
+				interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_uart0>;
+				status = "disabled";
+			};
+
+			uart1: serial@f8044000 {
+				compatible = "atmel,at91sam9260-usart";
+				reg = <0xf8044000 0x200>;
+				interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_uart1>;
+				status = "disabled";
+			};
+
 			adc0: adc@f804c000 {
 				compatible = "atmel,at91sam9260-adc";
 				reg = <0xf804c000 0x100>;
-				interrupts = <19 4 0>;
+				interrupts = <19 IRQ_TYPE_LEVEL_HIGH 0>;
 				atmel,adc-use-external;
 				atmel,adc-channels-used = <0xffff>;
 				atmel,adc-vref = <3300>;
@@ -625,7 +727,10 @@
 				#size-cells = <0>;
 				compatible = "atmel,at91rm9200-spi";
 				reg = <0xf0000000 0x100>;
-				interrupts = <13 4 3>;
+				interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
+				dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(1)>,
+				       <&dma0 1 AT91_DMA_CFG_PER_ID(2)>;
+				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi0>;
 				status = "disabled";
@@ -636,16 +741,87 @@
 				#size-cells = <0>;
 				compatible = "atmel,at91rm9200-spi";
 				reg = <0xf0004000 0x100>;
-				interrupts = <14 4 3>;
+				interrupts = <14 IRQ_TYPE_LEVEL_HIGH 3>;
+				dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(1)>,
+				       <&dma1 1 AT91_DMA_CFG_PER_ID(2)>;
+				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi1>;
 				status = "disabled";
 			};
 
+			usb2: gadget@f803c000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "atmel,at91sam9rl-udc";
+				reg = <0x00500000 0x80000
+				       0xf803c000 0x400>;
+				interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>;
+				status = "disabled";
+
+				ep0 {
+					reg = <0>;
+					atmel,fifo-size = <64>;
+					atmel,nb-banks = <1>;
+				};
+
+				ep1 {
+					reg = <1>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep2 {
+					reg = <2>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <2>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep3 {
+					reg = <3>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep4 {
+					reg = <4>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+				};
+
+				ep5 {
+					reg = <5>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+
+				ep6 {
+					reg = <6>;
+					atmel,fifo-size = <1024>;
+					atmel,nb-banks = <3>;
+					atmel,can-dma;
+					atmel,can-isoc;
+				};
+			};
+
+			watchdog@fffffe40 {
+				compatible = "atmel,at91sam9260-wdt";
+				reg = <0xfffffe40 0x10>;
+				status = "disabled";
+			};
+
 			rtc@fffffeb0 {
-				compatible = "atmel,at91rm9200-rtc";
+				compatible = "atmel,at91sam9x5-rtc";
 				reg = <0xfffffeb0 0x40>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				status = "disabled";
 			};
 		};
@@ -664,8 +840,8 @@
 			atmel,nand-cmd-offset = <22>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_nand>;
-			gpios = <&pioD 5 0
-				 &pioD 4 0
+			gpios = <&pioD 5 GPIO_ACTIVE_HIGH
+				 &pioD 4 GPIO_ACTIVE_HIGH
 				 0
 				>;
 			status = "disabled";
@@ -674,22 +850,22 @@
 		usb0: ohci@00600000 {
 			compatible = "atmel,at91rm9200-ohci", "usb-ohci";
 			reg = <0x00600000 0x100000>;
-			interrupts = <22 4 2>;
+			interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 
 		usb1: ehci@00700000 {
 			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
 			reg = <0x00700000 0x100000>;
-			interrupts = <22 4 2>;
+			interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 	};
 
 	i2c@0 {
 		compatible = "i2c-gpio";
-		gpios = <&pioA 30 0 /* sda */
-			 &pioA 31 0 /* scl */
+		gpios = <&pioA 30 GPIO_ACTIVE_HIGH /* sda */
+			 &pioA 31 GPIO_ACTIVE_HIGH /* scl */
 			>;
 		i2c-gpio,sda-open-drain;
 		i2c-gpio,scl-open-drain;
@@ -703,8 +879,8 @@
 
 	i2c@1 {
 		compatible = "i2c-gpio";
-		gpios = <&pioC 0 0 /* sda */
-			 &pioC 1 0 /* scl */
+		gpios = <&pioC 0 GPIO_ACTIVE_HIGH /* sda */
+			 &pioC 1 GPIO_ACTIVE_HIGH /* scl */
 			>;
 		i2c-gpio,sda-open-drain;
 		i2c-gpio,scl-open-drain;
@@ -718,8 +894,8 @@
 
 	i2c@2 {
 		compatible = "i2c-gpio";
-		gpios = <&pioB 4 0 /* sda */
-			 &pioB 5 0 /* scl */
+		gpios = <&pioB 4 GPIO_ACTIVE_HIGH /* sda */
+			 &pioB 5 GPIO_ACTIVE_HIGH /* scl */
 			>;
 		i2c-gpio,sda-open-drain;
 		i2c-gpio,scl-open-drain;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x5ek.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x5ek.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/at91sam9x5ek.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/at91sam9x5ek.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  *
  * Licensed under GPLv2 or later.
  */
-/include/ "at91sam9x5cm.dtsi"
+#include "at91sam9x5cm.dtsi"
 
 / {
 	model = "Atmel AT91SAM9X5-EK";
@@ -27,7 +27,7 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioD 15 0>;
+					cd-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -40,7 +40,7 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioD 14 0>;
+					cd-gpios = <&pioD 14 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -52,6 +52,11 @@
 				status = "okay";
 			};
 
+			usb2: gadget@f803c000 {
+				atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+			};
+
 			i2c0: i2c@f8010000 {
 				status = "okay";
 			};
@@ -60,14 +65,14 @@
 				mmc0 {
 					pinctrl_board_mmc0: mmc0-board {
 						atmel,pins =
-							<3 15 0x0 0x5>;	/* PD15 gpio CD pin pull up and deglitch */
+							<AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;	/* PD15 gpio CD pin pull up and deglitch */
 					};
 				};
 
 				mmc1 {
 					pinctrl_board_mmc1: mmc1-board {
 						atmel,pins =
-							<3 14 0x0 0x5>;	/* PD14 gpio CD pin pull up and deglitch */
+							<AT91_PIOD 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;	/* PD14 gpio CD pin pull up and deglitch */
 					};
 				};
 			};
@@ -81,13 +86,18 @@
 					reg = <0>;
 				};
 			};
+
+			watchdog@fffffe40 {
+				status = "okay";
+			};
 		};
 
 		usb0: ohci@00600000 {
 			status = "okay";
-			num-ports = <2>;
-			atmel,vbus-gpio = <&pioD 19 1
-					   &pioD 20 1
+			num-ports = <3>;
+			atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW *//* Activate to have access to port A */
+					   &pioD 19 GPIO_ACTIVE_LOW
+					   &pioD 20 GPIO_ACTIVE_LOW
 					  >;
 		};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/atlas6.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/atlas6.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/atlas6.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/atlas6.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -485,6 +485,12 @@
                                                 sirf,function = "usp0";
                                         };
                                 };
+				usp0_uart_nostreamctrl_pins_a: usp0@1 {
+                                        usp0 {
+                                                sirf,pins = "usp0_uart_nostreamctrl_grp";
+                                                sirf,function = "usp0_uart_nostreamctrl";
+                                        };
+                                };
                                 usp1_pins_a: usp1@0 {
                                         usp1 {
                                                 sirf,pins = "usp1grp";
@@ -515,16 +521,16 @@
                                                 sirf,function = "pulse_count";
                                         };
                                 };
-                                cko0_rst_pins_a: cko0_rst@0 {
-                                        cko0_rst {
-                                                sirf,pins = "cko0_rstgrp";
-                                                sirf,function = "cko0_rst";
+                                cko0_pins_a: cko0@0 {
+                                        cko0 {
+                                                sirf,pins = "cko0grp";
+                                                sirf,function = "cko0";
                                         };
                                 };
-                                cko1_rst_pins_a: cko1_rst@0 {
-                                        cko1_rst {
-                                                sirf,pins = "cko1_rstgrp";
-                                                sirf,function = "cko1_rst";
+                                cko1_pins_a: cko1@0 {
+                                        cko1 {
+                                                sirf,pins = "cko1grp";
+                                                sirf,function = "cko1";
                                         };
                                 };
 			};
@@ -613,7 +619,7 @@
 		};
 
 		rtc-iobg {
-			compatible = "sirf,prima2-rtciobg", "sirf-prima2-rtciobg-bus";
+			compatible = "sirf,prima2-rtciobg", "sirf-prima2-rtciobg-bus", "simple-bus";
 			#address-cells = <1>;
 			#size-cells = <1>;
 			reg = <0x80030000 0x10000>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/bcm11351-brt.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/bcm11351-brt.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/bcm11351-brt.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/bcm11351-brt.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 
 /dts-v1/;
 
-/include/ "bcm11351.dtsi"
+#include "bcm11351.dtsi"
 
 / {
 	model = "BCM11351 BRT board";
@@ -27,4 +27,21 @@
 		status = "okay";
 	};
 
+	sdio0: sdio@0x3f180000 {
+		max-frequency = <48000000>;
+		status = "okay";
+	};
+
+	sdio1: sdio@0x3f190000 {
+		non-removable;
+		max-frequency = <48000000>;
+		status = "okay";
+	};
+
+	sdio3: sdio@0x3f1b0000 {
+		max-frequency = <48000000>;
+		status = "okay";
+	};
+
+
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/bcm11351.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/bcm11351.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/bcm11351.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/bcm11351.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,10 @@
  * GNU General Public License for more details.
  */
 
-/include/ "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "skeleton.dtsi"
 
 / {
 	model = "BCM11351 SoC";
@@ -33,7 +36,7 @@
 
 	smc@0x3404c000 {
 		compatible = "bcm,bcm11351-smc", "bcm,kona-smc";
-		reg = <0x3404c000 0x400>; //1 KiB in SRAM
+		reg = <0x3404c000 0x400>; /* 1 KiB in SRAM */
 	};
 
 	uart@3e000000 {
@@ -41,23 +44,51 @@
 		status = "disabled";
 		reg = <0x3e000000 0x1000>;
 		clock-frequency = <13000000>;
-		interrupts = <0x0 67 0x4>;
+		interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
 		reg-shift = <2>;
 		reg-io-width = <4>;
 	};
 
 	L2: l2-cache {
-		    compatible = "arm,pl310-cache";
-		    reg = <0x3ff20000 0x1000>;
-		    cache-unified;
-		    cache-level = <2>;
+		compatible = "bcm,bcm11351-a2-pl310-cache";
+		reg = <0x3ff20000 0x1000>;
+		cache-unified;
+		cache-level = <2>;
 	};
 
 	timer@35006000 {
 		compatible = "bcm,kona-timer";
 		reg = <0x35006000 0x1000>;
-		interrupts = <0x0 7 0x4>;
+		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
 		clock-frequency = <32768>;
 	};
 
+	sdio0: sdio@0x3f180000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f180000 0x10000>;
+		interrupts = <0x0 77 0x4>;
+		status = "disabled";
+	};
+
+	sdio1: sdio@0x3f190000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f190000 0x10000>;
+		interrupts = <0x0 76 0x4>;
+		status = "disabled";
+	};
+
+	sdio2: sdio@0x3f1a0000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f1a0000 0x10000>;
+		interrupts = <0x0 74 0x4>;
+		status = "disabled";
+	};
+
+	sdio3: sdio@0x3f1b0000 {
+		compatible = "bcm,kona-sdhci";
+		reg = <0x3f1b0000 0x10000>;
+		interrupts = <0x0 73 0x4>;
+		status = "disabled";
+	};
+
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/bcm2835-rpi-b.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/bcm2835-rpi-b.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/bcm2835-rpi-b.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/bcm2835-rpi-b.dts	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,17 @@
 	memory {
 		reg = <0 0x10000000>;
 	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		act {
+			label = "ACT";
+			gpios = <&gpio 16 1>;
+			default-state = "keep";
+			linux,default-trigger = "heartbeat";
+		};
+	};
 };
 
 &gpio {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/ccu8540.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ccu8540.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/ccu8540.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ccu8540.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013 ST-Ericsson AB
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "dbx5x0.dtsi"
+
+/ {
+	model = "ST-Ericsson U8540 platform with Device Tree";
+	compatible = "st-ericsson,ccu8540", "st-ericsson,u8540";
+
+	memory@0 {
+		reg = <0x20000000 0x1f000000>, <0xc0000000 0x3f000000>;
+	};
+
+	soc {
+		prcmu@80157000 {
+			reg = <0x80157000 0x2000>, <0x801b0000 0x8000>, <0x801b8000 0x3000>;
+			reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm";
+		};
+
+		uart@80120000 {
+			status = "okay";
+		};
+
+		uart@80121000 {
+			status = "okay";
+		};
+
+		uart@80007000 {
+			status = "okay";
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/ccu9540.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ccu9540.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/ccu9540.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ccu9540.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "dbx5x0.dtsi"
+#include "dbx5x0.dtsi"
 
 / {
 	model = "ST-Ericsson CCU9540 platform with Device Tree";
@@ -20,7 +20,7 @@
 		reg = <0x00000000 0x20000000>;
 	};
 
-	soc-u9500 {
+	soc {
 		uart@80120000 {
 			status = "okay";
 		};
@@ -52,7 +52,7 @@
 		// WLAN SDIO channel
 		sdi1_per2@80118000 {
 			arm,primecell-periphid = <0x10480180>;
-			max-frequency = <50000000>;
+			max-frequency = <100000000>;
 			bus-width = <4>;
 
 			status = "okay";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/cros5250-common.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/cros5250-common.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/cros5250-common.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/cros5250-common.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -190,7 +190,7 @@
 		samsung,i2c-max-bus-freq = <66000>;
 
 		hdmiddc@50 {
-			compatible = "samsung,exynos5-hdmiddc";
+			compatible = "samsung,exynos4210-hdmiddc";
 			reg = <0x50>;
 		};
 	};
@@ -224,7 +224,7 @@
 		samsung,i2c-max-bus-freq = <378000>;
 
 		hdmiphy@38 {
-			compatible = "samsung,exynos5-hdmiphy";
+			compatible = "samsung,exynos4212-hdmiphy";
 			reg = <0x38>;
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/da850.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/da850.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/da850.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/da850.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
 	arm {
@@ -37,7 +37,7 @@
 			#size-cells = <0>;
 			pinctrl-single,bit-per-mux;
 			pinctrl-single,register-width = <32>;
-			pinctrl-single,function-mask = <0xffffffff>;
+			pinctrl-single,function-mask = <0xf>;
 			status = "disabled";
 
 			nand_cs3_pins: pinmux_nand_pins {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/da850-enbw-cmc.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/da850-enbw-cmc.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/da850-enbw-cmc.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/da850-enbw-cmc.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@
  * option) any later version.
  */
 /dts-v1/;
-/include/ "da850.dtsi"
+#include "da850.dtsi"
 
 / {
 	compatible = "enbw,cmc", "ti,da850";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/da850-evm.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/da850-evm.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/da850-evm.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/da850-evm.dts	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
  * Free Software Foundation, version 2.
  */
 /dts-v1/;
-/include/ "da850.dtsi"
+#include "da850.dtsi"
 
 / {
 	compatible = "ti,da850-evm", "ti,da850";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/dbx5x0.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/dbx5x0.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/dbx5x0.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/dbx5x0.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -9,10 +9,11 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-/include/ "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "skeleton.dtsi"
 
 / {
-	soc-u9500 {
+	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "stericsson,db8500";
@@ -31,33 +32,33 @@
 		L2: l2-cache {
 			compatible = "arm,pl310-cache";
 			reg = <0xa0412000 0x1000>;
-			interrupts = <0 13 4>;
+			interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>;
 			cache-unified;
 			cache-level = <2>;
 		};
 
 		pmu {
 			compatible = "arm,cortex-a9-pmu";
-			interrupts = <0 7 0x4>;
+			interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
 		timer@a0410600 {
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = <0xa0410600 0x20>;
-			interrupts = <1 13 0x304>;
+			interrupts = <1 13 0x304>; /* IRQ level high per-CPU */
 		};
 
 		rtc@80154000 {
 			compatible = "arm,rtc-pl031", "arm,primecell";
 			reg = <0x80154000 0x1000>;
-			interrupts = <0 18 0x4>;
+			interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
 		gpio0: gpio@8012e000 {
 			compatible = "stericsson,db8500-gpio",
 				"st,nomadik-gpio";
 			reg =  <0x8012e000 0x80>;
-			interrupts = <0 119 0x4>;
+			interrupts = <0 119 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			st,supports-sleepmode;
@@ -70,7 +71,7 @@
 			compatible = "stericsson,db8500-gpio",
 				"st,nomadik-gpio";
 			reg =  <0x8012e080 0x80>;
-			interrupts = <0 120 0x4>;
+			interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			st,supports-sleepmode;
@@ -83,7 +84,7 @@
 			compatible = "stericsson,db8500-gpio",
 				"st,nomadik-gpio";
 			reg =  <0x8000e000 0x80>;
-			interrupts = <0 121 0x4>;
+			interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			st,supports-sleepmode;
@@ -96,7 +97,7 @@
 			compatible = "stericsson,db8500-gpio",
 				"st,nomadik-gpio";
 			reg =  <0x8000e080 0x80>;
-			interrupts = <0 122 0x4>;
+			interrupts = <0 122 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			st,supports-sleepmode;
@@ -109,7 +110,7 @@
 			compatible = "stericsson,db8500-gpio",
 				"st,nomadik-gpio";
 			reg =  <0x8000e100 0x80>;
-			interrupts = <0 123 0x4>;
+			interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			st,supports-sleepmode;
@@ -122,7 +123,7 @@
 			compatible = "stericsson,db8500-gpio",
 				"st,nomadik-gpio";
 			reg =  <0x8000e180 0x80>;
-			interrupts = <0 124 0x4>;
+			interrupts = <0 124 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			st,supports-sleepmode;
@@ -135,7 +136,7 @@
 			compatible = "stericsson,db8500-gpio",
 				"st,nomadik-gpio";
 			reg =  <0x8011e000 0x80>;
-			interrupts = <0 125 0x4>;
+			interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			st,supports-sleepmode;
@@ -148,7 +149,7 @@
 			compatible = "stericsson,db8500-gpio",
 				"st,nomadik-gpio";
 			reg =  <0x8011e080 0x80>;
-			interrupts = <0 126 0x4>;
+			interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			st,supports-sleepmode;
@@ -161,7 +162,7 @@
 			compatible = "stericsson,db8500-gpio",
 				"st,nomadik-gpio";
 			reg =  <0xa03fe000 0x80>;
-			interrupts = <0 127 0x4>;
+			interrupts = <0 127 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-controller;
 			#interrupt-cells = <2>;
 			st,supports-sleepmode;
@@ -171,29 +172,61 @@
 		};
 
 		pinctrl {
-			compatible = "stericsson,nmk-pinctrl";
+			compatible = "stericsson,db8500-pinctrl";
 			prcm = <&prcmu>;
 		};
 
-		usb@a03e0000 {
+		usb_per5@a03e0000 {
 			compatible = "stericsson,db8500-musb",
 				"mentor,musb";
 			reg = <0xa03e0000 0x10000>;
-			interrupts = <0 23 0x4>;
+			interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "mc";
+
+			dr_mode = "otg";
+
+			dmas = <&dma 38 0 0x2>, /* Logical - DevToMem */
+			       <&dma 38 0 0x0>, /* Logical - MemToDev */
+			       <&dma 37 0 0x2>, /* Logical - DevToMem */
+			       <&dma 37 0 0x0>, /* Logical - MemToDev */
+			       <&dma 36 0 0x2>, /* Logical - DevToMem */
+			       <&dma 36 0 0x0>, /* Logical - MemToDev */
+			       <&dma 19 0 0x2>, /* Logical - DevToMem */
+			       <&dma 19 0 0x0>, /* Logical - MemToDev */
+			       <&dma 18 0 0x2>, /* Logical - DevToMem */
+			       <&dma 18 0 0x0>, /* Logical - MemToDev */
+			       <&dma 17 0 0x2>, /* Logical - DevToMem */
+			       <&dma 17 0 0x0>, /* Logical - MemToDev */
+			       <&dma 16 0 0x2>, /* Logical - DevToMem */
+			       <&dma 16 0 0x0>, /* Logical - MemToDev */
+			       <&dma 39 0 0x2>, /* Logical - DevToMem */
+			       <&dma 39 0 0x0>; /* Logical - MemToDev */
+
+			dma-names = "iep_1_9",  "oep_1_9",
+				    "iep_2_10", "oep_2_10",
+				    "iep_3_11", "oep_3_11",
+				    "iep_4_12", "oep_4_12",
+				    "iep_5_13", "oep_5_13",
+				    "iep_6_14", "oep_6_14",
+				    "iep_7_15", "oep_7_15",
+				    "iep_8",    "oep_8";
 		};
 
-		dma-controller@801C0000 {
-			compatible = "stericsson,db8500-dma40",
-					"stericsson,dma40";
+		dma: dma-controller@801C0000 {
+			compatible = "stericsson,db8500-dma40", "stericsson,dma40";
 			reg = <0x801C0000 0x1000 0x40010000 0x800>;
-			interrupts = <0 25 0x4>;
+			reg-names = "base", "lcpa";
+			interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
+
+			#dma-cells = <3>;
+			memcpy-channels = <56 57 58 59 60>;
 		};
 
 		prcmu: prcmu@80157000 {
 			compatible = "stericsson,db8500-prcmu";
 			reg = <0x80157000 0x2000>, <0x801b0000 0x8000>, <0x801b8000 0x1000>;
 			reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm";
-			interrupts = <0 47 0x4>;
+			interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			interrupt-controller;
@@ -208,7 +241,8 @@
 			thermal@801573c0 {
 				compatible = "stericsson,db8500-thermal";
 				reg = <0x801573c0 0x40>;
-				interrupts = <21 0x4>, <22 0x4>;
+				interrupts = <21 IRQ_TYPE_LEVEL_HIGH>,
+					     <22 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-names = "IRQ_HOTMON_LOW", "IRQ_HOTMON_HIGH";
 				status = "disabled";
 			 };
@@ -322,21 +356,26 @@
 			ab8500 {
 				compatible = "stericsson,ab8500";
 				interrupt-parent = <&intc>;
-				interrupts = <0 40 0x4>;
+				interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-controller;
 				#interrupt-cells = <2>;
 
+				ab8500_gpio: ab8500-gpio {
+					gpio-controller;
+					#gpio-cells = <2>;
+				};
+
 				ab8500-rtc {
 					compatible = "stericsson,ab8500-rtc";
-					interrupts = <17 0x4
-					              18 0x4>;
+					interrupts = <17 IRQ_TYPE_LEVEL_HIGH
+						      18 IRQ_TYPE_LEVEL_HIGH>;
 					interrupt-names = "60S", "ALARM";
 				};
 
 				ab8500-gpadc {
 					compatible = "stericsson,ab8500-gpadc";
-					interrupts = <32 0x4
-						      39 0x4>;
+					interrupts = <32 IRQ_TYPE_LEVEL_HIGH
+						      39 IRQ_TYPE_LEVEL_HIGH>;
 					interrupt-names = "HW_CONV_END", "SW_CONV_END";
 					vddadc-supply = <&ab8500_ldo_tvout_reg>;
 				};
@@ -369,13 +408,13 @@
 
 				ab8500_usb {
 					compatible = "stericsson,ab8500-usb";
-					interrupts = < 90 0x4
-						       96 0x4
-						       14 0x4
-						       15 0x4
-						       79 0x4
-						       74 0x4
-						       75 0x4>;
+					interrupts = < 90 IRQ_TYPE_LEVEL_HIGH
+						       96 IRQ_TYPE_LEVEL_HIGH
+						       14 IRQ_TYPE_LEVEL_HIGH
+						       15 IRQ_TYPE_LEVEL_HIGH
+						       79 IRQ_TYPE_LEVEL_HIGH
+						       74 IRQ_TYPE_LEVEL_HIGH
+						       75 IRQ_TYPE_LEVEL_HIGH>;
 					interrupt-names = "ID_WAKEUP_R",
 							  "ID_WAKEUP_F",
 							  "VBUS_DET_F",
@@ -383,15 +422,15 @@
 							  "USB_LINK_STATUS",
 							  "USB_ADP_PROBE_PLUG",
 							  "USB_ADP_PROBE_UNPLUG";
-					vddulpivio18-supply = <&ab8500_ldo_initcore_reg>;
+					vddulpivio18-supply = <&ab8500_ldo_intcore_reg>;
 					v-ape-supply = <&db8500_vape_reg>;
 					musb_1v8-supply = <&db8500_vsmps2_reg>;
 				};
 
 				ab8500-ponkey {
 					compatible = "stericsson,ab8500-poweron-key";
-					interrupts = <6 0x4
-						      7 0x4>;
+					interrupts = <6 IRQ_TYPE_LEVEL_HIGH
+						      7 IRQ_TYPE_LEVEL_HIGH>;
 					interrupt-names = "ONKEY_DBF", "ONKEY_DBR";
 				};
 
@@ -410,6 +449,11 @@
 				codec: ab8500-codec {
 					compatible = "stericsson,ab8500-codec";
 
+					V-AUD-supply = <&ab8500_ldo_audio_reg>;
+					V-AMIC1-supply = <&ab8500_ldo_anamic1_reg>;
+					V-AMIC2-supply = <&ab8500_ldo_anamic2_reg>;
+					V-DMIC-supply = <&ab8500_ldo_dmic_reg>;
+
 					stericsson,earpeice-cmv = <950>; /* Units in mV. */
 				};
 
@@ -441,8 +485,8 @@
 					};
 
 					// supply for v-intcore12; VINTCORE12 LDO
-					ab8500_ldo_initcore_reg: ab8500_ldo_initcore {
-						regulator-compatible = "ab8500_ldo_initcore";
+					ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
+						regulator-compatible = "ab8500_ldo_intcore";
 					};
 
 					// supply for tvout; gpadc; TVOUT LDO
@@ -460,14 +504,14 @@
 						regulator-compatible = "ab8500_ldo_audio";
 					};
 
-					// supply for v-anamic1 VAMic1-LDO
+					// supply for v-anamic1 VAMIC1 LDO
 					ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
 						regulator-compatible = "ab8500_ldo_anamic1";
 					};
 
 					// supply for v-amic2; VAMIC2 LDO; reuse constants for AMIC1
-					ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 {
-						regulator-compatible = "ab8500_ldo_amamic2";
+					ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
+						regulator-compatible = "ab8500_ldo_anamic2";
 					};
 
 					// supply for v-dmic; VDMIC LDO
@@ -486,7 +530,7 @@
 		i2c@80004000 {
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x80004000 0x1000>;
-			interrupts = <0 21 0x4>;
+			interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>;
 			arm,primecell-periphid = <0x180024>;
 
 			#address-cells = <1>;
@@ -499,7 +543,7 @@
 		i2c@80122000 {
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x80122000 0x1000>;
-			interrupts = <0 22 0x4>;
+			interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
 			arm,primecell-periphid = <0x180024>;
 
 			#address-cells = <1>;
@@ -512,7 +556,7 @@
 		i2c@80128000 {
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x80128000 0x1000>;
-			interrupts = <0 55 0x4>;
+			interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
 			arm,primecell-periphid = <0x180024>;
 
 			#address-cells = <1>;
@@ -525,7 +569,7 @@
 		i2c@80110000 {
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x80110000 0x1000>;
-			interrupts = <0 12 0x4>;
+			interrupts = <0 12 IRQ_TYPE_LEVEL_HIGH>;
 			arm,primecell-periphid = <0x180024>;
 
 			#address-cells = <1>;
@@ -538,7 +582,7 @@
 		i2c@8012a000 {
 			compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
 			reg = <0x8012a000 0x1000>;
-			interrupts = <0 51 0x4>;
+			interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
 			arm,primecell-periphid = <0x180024>;
 
 			#address-cells = <1>;
@@ -551,82 +595,114 @@
 		ssp@80002000 {
 			compatible = "arm,pl022", "arm,primecell";
 			reg = <0x80002000 0x1000>;
-			interrupts = <0 14 0x4>;
+			interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			status = "disabled";
-
-			// Add one of these for each child device
-			cs-gpios = <&gpio0 31 0x4 &gpio4 14 0x4 &gpio4 16 0x4
-				    &gpio6 22 0x4 &gpio7 0 0x4>;
-
 		};
 
 		uart@80120000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x80120000 0x1000>;
-			interrupts = <0 11 0x4>;
+			interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+
+			dmas = <&dma 13 0 0x2>, /* Logical - DevToMem */
+			       <&dma 13 0 0x0>; /* Logical - MemToDev */
+			dma-names = "rx", "tx";
+
 			status = "disabled";
 		};
+
 		uart@80121000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x80121000 0x1000>;
-			interrupts = <0 19 0x4>;
+			interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
+
+			dmas = <&dma 12 0 0x2>, /* Logical - DevToMem */
+			       <&dma 12 0 0x0>; /* Logical - MemToDev */
+			dma-names = "rx", "tx";
+
 			status = "disabled";
 		};
+
 		uart@80007000 {
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x80007000 0x1000>;
-			interrupts = <0 26 0x4>;
+			interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
+
+			dmas = <&dma 11 0 0x2>, /* Logical - DevToMem */
+			       <&dma 11 0 0x0>; /* Logical - MemToDev */
+			dma-names = "rx", "tx";
+
 			status = "disabled";
 		};
 
 		sdi0_per1@80126000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80126000 0x1000>;
-			interrupts = <0 60 0x4>;
+			interrupts = <0 60 IRQ_TYPE_LEVEL_HIGH>;
+
+			dmas = <&dma 29 0 0x2>, /* Logical - DevToMem */
+			       <&dma 29 0 0x0>; /* Logical - MemToDev */
+			dma-names = "rx", "tx";
+
 			status = "disabled";
 		};
 
 		sdi1_per2@80118000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80118000 0x1000>;
-			interrupts = <0 50 0x4>;
+			interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
+
+			dmas = <&dma 32 0 0x2>, /* Logical - DevToMem */
+			       <&dma 32 0 0x0>; /* Logical - MemToDev */
+			dma-names = "rx", "tx";
+
 			status = "disabled";
 		};
 
 		sdi2_per3@80005000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80005000 0x1000>;
-			interrupts = <0 41 0x4>;
+			interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>;
+
+			dmas = <&dma 28 0 0x2>, /* Logical - DevToMem */
+			       <&dma 28 0 0x0>; /* Logical - MemToDev */
+			dma-names = "rx", "tx";
+
 			status = "disabled";
 		};
 
 		sdi3_per2@80119000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80119000 0x1000>;
-			interrupts = <0 59 0x4>;
+			interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
 		};
 
 		sdi4_per2@80114000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80114000 0x1000>;
-			interrupts = <0 99 0x4>;
+			interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>;
+
+			dmas = <&dma 42 0 0x2>, /* Logical - DevToMem */
+			       <&dma 42 0 0x0>; /* Logical - MemToDev */
+			dma-names = "rx", "tx";
+
 			status = "disabled";
 		};
 
 		sdi5_per3@80008000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80008000 0x1000>;
-			interrupts = <0 100 0x4>;
+			interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
 		};
 
 		msp0: msp@80123000 {
 			compatible = "stericsson,ux500-msp-i2s";
 			reg = <0x80123000 0x1000>;
-			interrupts = <0 31 0x4>;
+			interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
 			v-ape-supply = <&db8500_vape_reg>;
 			status = "disabled";
 		};
@@ -634,7 +710,7 @@
 		msp1: msp@80124000 {
 			compatible = "stericsson,ux500-msp-i2s";
 			reg = <0x80124000 0x1000>;
-			interrupts = <0 62 0x4>;
+			interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>;
 			v-ape-supply = <&db8500_vape_reg>;
 			status = "disabled";
 		};
@@ -643,7 +719,7 @@
 		msp2: msp@80117000 {
 			compatible = "stericsson,ux500-msp-i2s";
 			reg = <0x80117000 0x1000>;
-			interrupts = <0 98 0x4>;
+			interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
 			v-ape-supply = <&db8500_vape_reg>;
 			status = "disabled";
 		};
@@ -651,7 +727,7 @@
 		msp3: msp@80125000 {
 			compatible = "stericsson,ux500-msp-i2s";
 			reg = <0x80125000 0x1000>;
-			interrupts = <0 62 0x4>;
+			interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>;
 			v-ape-supply = <&db8500_vape_reg>;
 			status = "disabled";
 		};
@@ -686,5 +762,20 @@
 
 			status = "disabled";
 		};
+
+		cryp@a03cb000 {
+			compatible = "stericsson,ux500-cryp";
+			reg = <0xa03cb000 0x1000>;
+			interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
+
+			v-ape-supply = <&db8500_vape_reg>;
+		};
+
+		hash@a03c2000 {
+			compatible = "stericsson,ux500-hash";
+			reg = <0xa03c2000 0x1000>;
+
+			v-ape-supply = <&db8500_vape_reg>;
+		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/dove-cubox.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/dove-cubox.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/dove-cubox.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/dove-cubox.dts	2013-08-25 20:43:22.000000000 -0400
@@ -44,11 +44,60 @@
 			gpio = <&gpio0 1 0>;
 		};
 	};
+
+	clocks {
+		/* 25MHz reference crystal */
+		ref25: oscillator {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <25000000>;
+		};
+	};
 };
 
 &uart0 { status = "okay"; };
 &sata0 { status = "okay"; };
-&i2c0 { status = "okay"; };
+
+&i2c0 {
+	status = "okay";
+	clock-frequency = <100000>;
+
+	si5351: clock-generator {
+		compatible = "silabs,si5351a-msop";
+		reg = <0x60>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#clock-cells = <1>;
+
+		/* connect xtal input to 25MHz reference */
+		clocks = <&ref25>;
+
+		/* connect xtal input as source of pll0 and pll1 */
+		silabs,pll-source = <0 0>, <1 0>;
+
+		clkout0 {
+			reg = <0>;
+			silabs,drive-strength = <8>;
+			silabs,multisynth-source = <0>;
+			silabs,clock-source = <0>;
+			silabs,pll-master;
+		};
+
+		clkout1 {
+			reg = <1>;
+			silabs,drive-strength = <8>;
+			silabs,multisynth-source = <1>;
+			silabs,clock-source = <0>;
+			silabs,pll-master;
+		};
+
+		clkout2 {
+			reg = <2>;
+			silabs,multisynth-source = <1>;
+			silabs,clock-source = <0>;
+		};
+	};
+};
 
 &sdio0 {
 	status = "okay";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/ecx-common.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ecx-common.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/ecx-common.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ecx-common.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -33,6 +33,8 @@
 			calxeda,port-phys = <&combophy5 0 &combophy0 0
 					     &combophy0 1 &combophy0 2
 					     &combophy0 3>;
+			calxeda,sgpio-gpio =<&gpioh 5 1 &gpioh 6 1 &gpioh 7 1>;
+			calxeda,led-order = <4 0 1 2 3>;
 		};
 
 		sdhci@ffe0e000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/ethernut5.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ethernut5.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/ethernut5.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ethernut5.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 /dts-v1/;
-/include/ "at91sam9260.dtsi"
+#include "at91sam9260.dtsi"
 
 / {
 	model = "Ethernut 5";
@@ -40,7 +40,7 @@
 			};
 
 			usb1: gadget@fffa4000 {
-				atmel,vbus-gpio = <&pioC 5 0>;
+				atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
 				status = "okay";
 			};
 		};
@@ -52,7 +52,7 @@
 			status = "okay";
 
 			gpios = <0
-				 &pioC 14 0
+				 &pioC 14 GPIO_ACTIVE_HIGH
 				 0
 				>;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/evk-pro3.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/evk-pro3.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/evk-pro3.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/evk-pro3.dts	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,7 @@
 
 /dts-v1/;
 
-/include/ "ge863-pro3.dtsi"
+#include "ge863-pro3.dtsi"
 
 / {
 	model = "Telit EVK-PRO3 for Telit GE863-PRO3";
@@ -31,7 +31,7 @@
 			};
 
 			usb1: gadget@fffa4000 {
-				atmel,vbus-gpio = <&pioC 5 0>;
+				atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
 				status = "okay";
 			};
 
@@ -50,4 +50,4 @@
 		status = "okay";
 	};
 
-};
\ No newline at end of file
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -19,8 +19,8 @@
  * published by the Free Software Foundation.
 */
 
-/include/ "exynos4.dtsi"
-/include/ "exynos4210-pinctrl.dtsi"
+#include "exynos4.dtsi"
+#include "exynos4210-pinctrl.dtsi"
 
 / {
 	compatible = "samsung,exynos4210";
@@ -112,12 +112,17 @@
 		interrupt-parent = <&combiner>;
 		reg = <0x100C0000 0x100>;
 		interrupts = <2 4>;
+		clocks = <&clock 383>;
+		clock-names = "tmu_apbif";
+		status = "disabled";
 	};
 
 	g2d@12800000 {
 		compatible = "samsung,s5pv210-g2d";
 		reg = <0x12800000 0x1000>;
 		interrupts = <0 89 0>;
+		clocks = <&clock 177>, <&clock 277>;
+		clock-names = "sclk_fimg2d", "fimg2d";
 		status = "disabled";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-origen.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-origen.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-origen.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-origen.dts	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos4210.dtsi"
+#include "exynos4210.dtsi"
 
 / {
 	model = "Insignal Origen evaluation board based on Exynos4210";
@@ -41,6 +41,10 @@
 		enable-active-high;
 	};
 
+	tmu@100C0000 {
+		status = "okay";
+	};
+
 	sdhci@12530000 {
 		bus-width = <4>;
 		pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;
@@ -83,6 +87,150 @@
 		status = "okay";
 	};
 
+	i2c@13860000 {
+		status = "okay";
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <20000>;
+		pinctrl-0 = <&i2c0_bus>;
+		pinctrl-names = "default";
+
+		max8997_pmic@66 {
+			compatible = "maxim,max8997-pmic";
+			reg = <0x66>;
+			interrupt-parent = <&gpx0>;
+			interrupts = <4 0>, <3 0>;
+
+			max8997,pmic-buck1-dvs-voltage = <1350000>;
+			max8997,pmic-buck2-dvs-voltage = <1100000>;
+			max8997,pmic-buck5-dvs-voltage = <1200000>;
+
+			regulators {
+				ldo1_reg: LDO1 {
+					regulator-name = "VDD_ABB_3.3V";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+				};
+
+				ldo2_reg: LDO2 {
+					regulator-name = "VDD_ALIVE_1.1V";
+					regulator-min-microvolt = <1100000>;
+					regulator-max-microvolt = <1100000>;
+					regulator-always-on;
+				};
+
+				ldo3_reg: LDO3 {
+					regulator-name = "VMIPI_1.1V";
+					regulator-min-microvolt = <1100000>;
+					regulator-max-microvolt = <1100000>;
+				};
+
+				ldo4_reg: LDO4 {
+					regulator-name = "VDD_RTC_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt	= <1800000>;
+					regulator-always-on;
+				};
+
+				ldo6_reg: LDO6 {
+					regulator-name = "VMIPI_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt	= <1800000>;
+					regulator-always-on;
+				};
+
+				ldo7_reg: LDO7 {
+					regulator-name = "VDD_AUD_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt	= <1800000>;
+				};
+
+				ldo8_reg: LDO8 {
+					regulator-name = "VADC_3.3V";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt	= <3300000>;
+				};
+
+				ldo9_reg: LDO9 {
+					regulator-name = "DVDD_SWB_2.8V";
+					regulator-min-microvolt = <2800000>;
+					regulator-max-microvolt	= <2800000>;
+					regulator-always-on;
+				};
+
+				ldo10_reg: LDO10 {
+					regulator-name = "VDD_PLL_1.1V";
+					regulator-min-microvolt = <1100000>;
+					regulator-max-microvolt	= <1100000>;
+					regulator-always-on;
+				};
+
+				ldo11_reg: LDO11 {
+					regulator-name = "VDD_AUD_3V";
+					regulator-min-microvolt = <3000000>;
+					regulator-max-microvolt	= <3000000>;
+				};
+
+				ldo14_reg: LDO14 {
+					regulator-name = "AVDD18_SWB_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt	= <1800000>;
+					regulator-always-on;
+				};
+
+				ldo17_reg: LDO17 {
+					regulator-name = "VDD_SWB_3.3V";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt	= <3300000>;
+					regulator-always-on;
+				};
+
+				ldo21_reg: LDO21 {
+					regulator-name = "VDD_MIF_1.2V";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt	= <1200000>;
+					regulator-always-on;
+				};
+
+				buck1_reg: BUCK1 {
+					regulator-name = "VDD_ARM_1.2V";
+					regulator-min-microvolt = <950000>;
+					regulator-max-microvolt	= <1350000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				buck2_reg: BUCK2 {
+					regulator-name = "VDD_INT_1.1V";
+					regulator-min-microvolt = <900000>;
+					regulator-max-microvolt	= <1100000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				buck3_reg: BUCK3 {
+					regulator-name = "VDD_G3D_1.1V";
+					regulator-min-microvolt = <900000>;
+					regulator-max-microvolt = <1100000>;
+				};
+
+				buck5_reg: BUCK5 {
+					regulator-name = "VDDQ_M1M2_1.2V";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					regulator-always-on;
+				};
+
+				buck7_reg: BUCK7 {
+					regulator-name = "VDD_LCD_3.3V";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-boot-on;
+					regulator-always-on;
+				};
+			};
+		};
+	};
+
 	gpio_keys {
 		compatible = "gpio-keys";
 		#address-cells = <1>;
@@ -143,4 +291,25 @@
 			clock-frequency = <24000000>;
 		};
 	};
+
+	fimd@11c00000 {
+		pinctrl-0 = <&lcd_en &lcd_clk &lcd_data24 &pwm0_out>;
+		pinctrl-names = "default";
+		status = "okay";
+	};
+
+	display-timings {
+		native-mode = <&timing0>;
+		timing0: timing {
+			clock-frequency = <50000>;
+			hactive = <1024>;
+			vactive = <600>;
+			hfront-porch = <64>;
+			hback-porch = <16>;
+			hsync-len = <48>;
+			vback-porch = <64>;
+			vfront-porch = <16>;
+			vsync-len = <3>;
+		};
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-pinctrl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-pinctrl.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-pinctrl.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -330,6 +330,95 @@
 			samsung,pin-pud = <3>;
 			samsung,pin-drv = <0>;
 		};
+
+		pwm0_out: pwm0-out {
+			samsung,pins = "gpd0-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pwm1_out: pwm1-out {
+			samsung,pins = "gpd0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pwm2_out: pwm2-out {
+			samsung,pins = "gpd0-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pwm3_out: pwm3-out {
+			samsung,pins = "gpd0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_ctrl: lcd-ctrl {
+			samsung,pins = "gpd0-0", "gpd0-1";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_sync: lcd-sync {
+			samsung,pins = "gpf0-0", "gpf0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_en: lcd-en {
+			samsung,pins = "gpe3-4";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_clk: lcd-clk {
+			samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_data16: lcd-data-width16 {
+			samsung,pins = "gpf0-7", "gpf1-0", "gpf1-1", "gpf1-2",
+					"gpf1-3", "gpf1-6", "gpf1-7", "gpf2-0",
+					"gpf2-1", "gpf2-2", "gpf2-3", "gpf2-7",
+					"gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_data18: lcd-data-width18 {
+			samsung,pins = "gpf0-6", "gpf0-7", "gpf1-0", "gpf1-1",
+					"gpf1-2", "gpf1-3", "gpf1-6", "gpf1-7",
+					"gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+					"gpf2-6", "gpf2-7", "gpf3-0", "gpf3-1",
+					"gpf3-2", "gpf3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_data24: lcd-data-width24 {
+			samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
+					"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
+					"gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
+					"gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+					"gpf2-4", "gpf2-5", "gpf2-6", "gpf2-7",
+					"gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
 	};
 
 	pinctrl@11000000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-smdkv310.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-smdkv310.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-smdkv310.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-smdkv310.dts	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos4210.dtsi"
+#include "exynos4210.dtsi"
 
 / {
 	model = "Samsung smdkv310 evaluation board based on Exynos4210";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-trats.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-trats.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-trats.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-trats.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos4210.dtsi"
+#include "exynos4210.dtsi"
 
 / {
 	model = "Samsung Trats based on Exynos4210";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-universal_c210.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-universal_c210.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4210-universal_c210.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4210-universal_c210.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos4210.dtsi"
+#include "exynos4210.dtsi"
 
 / {
 	model = "Samsung Universal C210 based on Exynos4210 rev0";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4212.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4212.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4212.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4212.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,7 @@
  * published by the Free Software Foundation.
 */
 
-/include/ "exynos4x12.dtsi"
+#include "exynos4x12.dtsi"
 
 / {
 	compatible = "samsung,exynos4212";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4412.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4412.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4412.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4412.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,7 @@
  * published by the Free Software Foundation.
 */
 
-/include/ "exynos4x12.dtsi"
+#include "exynos4x12.dtsi"
 
 / {
 	compatible = "samsung,exynos4412";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4412-odroidx.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4412-odroidx.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4412-odroidx.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4412-odroidx.dts	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos4412.dtsi"
+#include "exynos4412.dtsi"
 
 / {
 	model = "Hardkernel ODROID-X board based on Exynos4412";
@@ -43,6 +43,7 @@
 		#size-cells = <0>;
 		pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
 		pinctrl-names = "default";
+		vmmc-supply = <&ldo20_reg &buck8_reg>;
 		status = "okay";
 
 		num-slots = <1>;
@@ -78,6 +79,7 @@
 		bus-width = <4>;
 		pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
 		pinctrl-names = "default";
+		vmmc-supply = <&ldo4_reg &ldo21_reg>;
 		status = "okay";
 	};
 
@@ -108,4 +110,199 @@
 			clock-frequency = <24000000>;
 		};
 	};
+
+	i2c@13860000 {
+		pinctrl-0 = <&i2c0_bus>;
+		pinctrl-names = "default";
+		status = "okay";
+
+		max77686: pmic@09 {
+			compatible = "maxim,max77686";
+			reg = <0x09>;
+
+			voltage-regulators {
+				ldo1_reg: LDO1 {
+					regulator-name = "VDD_ALIVE_1.0V";
+					regulator-min-microvolt = <1000000>;
+					regulator-max-microvolt = <1000000>;
+					regulator-always-on;
+				};
+
+				ldo2_reg: LDO2 {
+					regulator-name = "VDDQ_M1_2_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+				};
+
+				ldo3_reg: LDO3 {
+					regulator-name = "VDDQ_EXT_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+				};
+
+				ldo4_reg: LDO4 {
+					regulator-name = "VDDQ_MMC2_2.8V";
+					regulator-min-microvolt = <2800000>;
+					regulator-max-microvolt = <2800000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo5_reg: LDO5 {
+					regulator-name = "VDDQ_MMC1_3_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo6_reg: LDO6 {
+					regulator-name = "VDD10_MPLL_1.0V";
+					regulator-min-microvolt = <1000000>;
+					regulator-max-microvolt = <1000000>;
+					regulator-always-on;
+				};
+
+				ldo7_reg: LDO7 {
+					regulator-name = "VDD10_XPLL_1.0V";
+					regulator-min-microvolt = <1000000>;
+					regulator-max-microvolt = <1000000>;
+					regulator-always-on;
+				};
+
+				ldo11_reg: LDO11 {
+					regulator-name = "VDD18_ABB1_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+				};
+
+				ldo12_reg: LDO12 {
+					regulator-name = "VDD33_USB_3.3V";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo13_reg: LDO13 {
+					regulator-name = "VDDQ_C2C_W_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo14_reg: LDO14 {
+					regulator-name = "VDD18_ABB0_2_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo15_reg: LDO15 {
+					regulator-name = "VDD10_HSIC_1.0V";
+					regulator-min-microvolt = <1000000>;
+					regulator-max-microvolt = <1000000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo16_reg: LDO16 {
+					regulator-name = "VDD18_HSIC_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo20_reg: LDO20 {
+					regulator-name = "LDO20_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-boot-on;
+				};
+
+				ldo21_reg: LDO21 {
+					regulator-name = "LDO21_3.3V";
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo25_reg: LDO25 {
+					regulator-name = "VDDQ_LCD_1.8V";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				buck1_reg: BUCK1 {
+					regulator-name = "vdd_mif";
+					regulator-min-microvolt = <1000000>;
+					regulator-max-microvolt = <1000000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				buck2_reg: BUCK2 {
+					regulator-name = "vdd_arm";
+					regulator-min-microvolt = <900000>;
+					regulator-max-microvolt = <1300000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				buck3_reg: BUCK3 {
+					regulator-name = "vdd_int";
+					regulator-min-microvolt = <1000000>;
+					regulator-max-microvolt = <1000000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				buck4_reg: BUCK4 {
+					regulator-name = "vdd_g3d";
+					regulator-min-microvolt = <900000>;
+					regulator-max-microvolt = <1100000>;
+					regulator-microvolt-offset = <50000>;
+				};
+
+				buck5_reg: BUCK5 {
+					regulator-name = "VDDQ_CKEM1_2_1.2V";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				buck6_reg: BUCK6 {
+					regulator-name = "BUCK6_1.35V";
+					regulator-min-microvolt = <1350000>;
+					regulator-max-microvolt = <1350000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				buck7_reg: BUCK7 {
+					regulator-name = "BUCK7_2.0V";
+					regulator-min-microvolt = <2000000>;
+					regulator-max-microvolt = <2000000>;
+					regulator-always-on;
+				};
+
+				buck8_reg: BUCK8 {
+					regulator-name = "BUCK8_2.8V";
+					regulator-min-microvolt = <2800000>;
+					regulator-max-microvolt = <2800000>;
+					regulator-always-on;
+				};
+			};
+		};
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4412-origen.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4412-origen.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4412-origen.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4412-origen.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos4412.dtsi"
+#include "exynos4412.dtsi"
 
 / {
 	model = "Insignal Origen evaluation board based on Exynos4412";
@@ -36,6 +36,72 @@
 		enable-active-high;
 	};
 
+	pinctrl@11000000 {
+		keypad_rows: keypad-rows {
+			samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		keypad_cols: keypad-cols {
+			samsung,pins = "gpx1-0", "gpx1-1";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+	keypad@100A0000 {
+		samsung,keypad-num-rows = <3>;
+		samsung,keypad-num-columns = <2>;
+		linux,keypad-no-autorepeat;
+		linux,keypad-wakeup;
+		pinctrl-0 = <&keypad_rows &keypad_cols>;
+		pinctrl-names = "default";
+		status = "okay";
+
+		key_home {
+			keypad,row = <0>;
+			keypad,column = <0>;
+			linux,code = <102>;
+		};
+
+		key_down {
+			keypad,row = <0>;
+			keypad,column = <1>;
+			linux,code = <108>;
+		};
+
+		key_up {
+			keypad,row = <1>;
+			keypad,column = <0>;
+			linux,code = <103>;
+		};
+
+		key_menu {
+			keypad,row = <1>;
+			keypad,column = <1>;
+			linux,code = <139>;
+		};
+
+		key_back {
+			keypad,row = <2>;
+			keypad,column = <0>;
+			linux,code = <158>;
+		};
+
+		key_enter {
+			keypad,row = <2>;
+			keypad,column = <1>;
+			linux,code = <28>;
+		};
+	};
+
+	g2d@10800000 {
+		status = "okay";
+	};
+
 	sdhci@12530000 {
 		bus-width = <4>;
 		pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4412-smdk4412.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4412-smdk4412.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4412-smdk4412.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4412-smdk4412.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos4412.dtsi"
+#include "exynos4412.dtsi"
 
 / {
 	model = "Samsung SMDK evaluation board based on Exynos4412";
@@ -31,8 +31,91 @@
 		status = "okay";
 	};
 
-	g2d@10800000 {
+	pinctrl@11000000 {
+		keypad_rows: keypad-rows {
+			samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		keypad_cols: keypad-cols {
+			samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3",
+				       "gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+	keypad@100A0000 {
+		samsung,keypad-num-rows = <3>;
+		samsung,keypad-num-columns = <8>;
+		linux,keypad-no-autorepeat;
+		linux,keypad-wakeup;
+		pinctrl-0 = <&keypad_rows &keypad_cols>;
+		pinctrl-names = "default";
 		status = "okay";
+
+		key_1 {
+			keypad,row = <1>;
+			keypad,column = <3>;
+			linux,code = <2>;
+		};
+
+		key_2 {
+			keypad,row = <1>;
+			keypad,column = <4>;
+			linux,code = <3>;
+		};
+
+		key_3 {
+			keypad,row = <1>;
+			keypad,column = <5>;
+			linux,code = <4>;
+		};
+
+		key_4 {
+			keypad,row = <1>;
+			keypad,column = <6>;
+			linux,code = <5>;
+		};
+
+		key_5 {
+			keypad,row = <1>;
+			keypad,column = <7>;
+			linux,code = <6>;
+		};
+
+		key_A {
+			keypad,row = <2>;
+			keypad,column = <6>;
+			linux,code = <30>;
+		};
+
+		key_B {
+			keypad,row = <2>;
+			keypad,column = <7>;
+			linux,code = <48>;
+		};
+
+		key_C {
+			keypad,row = <0>;
+			keypad,column = <5>;
+			linux,code = <46>;
+		};
+
+		key_D {
+			keypad,row = <2>;
+			keypad,column = <5>;
+			linux,code = <32>;
+		};
+
+		key_E {
+			keypad,row = <0>;
+			keypad,column = <7>;
+			linux,code = <18>;
+		};
 	};
 
 	sdhci@12530000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -19,7 +19,7 @@
  * published by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
 	interrupt-parent = <&gic>;
@@ -160,6 +160,8 @@
 		reg = <0x13400000 0x10000>;
 		interrupts = <0 94 0>;
 		samsung,power-domain = <&pd_mfc>;
+		clocks = <&clock 170>, <&clock 273>;
+		clock-names = "sclk_mfc", "mfc";
 		status = "disabled";
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4x12.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4x12.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4x12.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4x12.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -17,8 +17,8 @@
  * published by the Free Software Foundation.
 */
 
-/include/ "exynos4.dtsi"
-/include/ "exynos4x12-pinctrl.dtsi"
+#include "exynos4.dtsi"
+#include "exynos4x12-pinctrl.dtsi"
 
 / {
 	aliases {
@@ -28,14 +28,6 @@
 		pinctrl3 = &pinctrl_3;
 	};
 
-	combiner:interrupt-controller@10440000 {
-		interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
-			     <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
-			     <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
-			     <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
-			     <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
-	};
-
 	clock: clock-controller@0x10030000 {
 		compatible = "samsung,exynos4412-clock";
 		reg = <0x10030000 0x20000>;
@@ -77,6 +69,8 @@
 		compatible = "samsung,exynos4212-g2d";
 		reg = <0x10800000 0x1000>;
 		interrupts = <0 89 0>;
+		clocks = <&clock 177>, <&clock 277>;
+		clock-names = "sclk_fimg2d", "fimg2d";
 		status = "disabled";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -778,62 +778,6 @@
 			samsung,pin-drv = <3>;
 		};
 
-		keypad_col0: keypad-col0 {
-			samsung,pins = "gpl2-0";
-			samsung,pin-function = <3>;
-			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
-		};
-
-		keypad_col1: keypad-col1 {
-			samsung,pins = "gpl2-1";
-			samsung,pin-function = <3>;
-			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
-		};
-
-		keypad_col2: keypad-col2 {
-			samsung,pins = "gpl2-2";
-			samsung,pin-function = <3>;
-			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
-		};
-
-		keypad_col3: keypad-col3 {
-			samsung,pins = "gpl2-3";
-			samsung,pin-function = <3>;
-			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
-		};
-
-		keypad_col4: keypad-col4 {
-			samsung,pins = "gpl2-4";
-			samsung,pin-function = <3>;
-			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
-		};
-
-		keypad_col5: keypad-col5 {
-			samsung,pins = "gpl2-5";
-			samsung,pin-function = <3>;
-			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
-		};
-
-		keypad_col6: keypad-col6 {
-			samsung,pins = "gpl2-6";
-			samsung,pin-function = <3>;
-			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
-		};
-
-		keypad_col7: keypad-col7 {
-			samsung,pins = "gpl2-7";
-			samsung,pin-function = <3>;
-			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
-		};
-
 		cam_port_b: cam-port-b {
 			samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
 					"gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250-arndale.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250-arndale.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250-arndale.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250-arndale.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos5250.dtsi"
+#include "exynos5250.dtsi"
 
 / {
 	model = "Insignal Arndale evaluation board based on EXYNOS5250";
@@ -449,4 +449,35 @@
 			clock-frequency = <24000000>;
 		};
 	};
+
+	dp-controller {
+		samsung,color-space = <0>;
+		samsung,dynamic-range = <0>;
+		samsung,ycbcr-coeff = <0>;
+		samsung,color-depth = <1>;
+		samsung,link-rate = <0x0a>;
+		samsung,lane-count = <4>;
+	};
+
+	fimd: fimd@14400000 {
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: timing@0 {
+				/* 2560x1600 DP panel */
+				clock-frequency = <50000>;
+				hactive = <2560>;
+				vactive = <1600>;
+				hfront-porch = <48>;
+				hback-porch = <80>;
+				hsync-len = <32>;
+				vback-porch = <16>;
+				vfront-porch = <8>;
+				vsync-len = <6>;
+			};
+		};
+	};
+
+	rtc {
+		status = "okay";
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -17,12 +17,13 @@
  * published by the Free Software Foundation.
 */
 
-/include/ "skeleton.dtsi"
-/include/ "exynos5250-pinctrl.dtsi"
+#include "exynos5.dtsi"
+#include "exynos5250-pinctrl.dtsi"
+
+#include <dt-bindings/clk/exynos-audss-clk.h>
 
 / {
 	compatible = "samsung,exynos5250";
-	interrupt-parent = <&gic>;
 
 	aliases {
 		spi0 = &spi_0;
@@ -51,9 +52,20 @@
 		pinctrl3 = &pinctrl_3;
 	};
 
-	chipid@10000000 {
-		compatible = "samsung,exynos4210-chipid";
-		reg = <0x10000000 0x100>;
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0>;
+		};
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <1>;
+		};
 	};
 
 	pd_gsc: gsc-power-domain@0x10044000 {
@@ -72,15 +84,10 @@
 		#clock-cells = <1>;
 	};
 
-	gic:interrupt-controller@10481000 {
-		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
-		#interrupt-cells = <3>;
-		interrupt-controller;
-		reg = <0x10481000 0x1000>,
-		      <0x10482000 0x1000>,
-		      <0x10484000 0x2000>,
-		      <0x10486000 0x2000>;
-		interrupts = <1 9 0xf04>;
+	clock_audss: audss-clock-controller@3810000 {
+		compatible = "samsung,exynos5250-audss-clock";
+		reg = <0x03810000 0x0C>;
+		#clock-cells = <1>;
 	};
 
 	timer {
@@ -91,22 +98,6 @@
 			     <1 10 0xf08>;
 	};
 
-	combiner:interrupt-controller@10440000 {
-		compatible = "samsung,exynos4210-combiner";
-		#interrupt-cells = <2>;
-		interrupt-controller;
-		samsung,combiner-nr = <32>;
-		reg = <0x10440000 0x1000>;
-		interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
-			     <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
-			     <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
-			     <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
-			     <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
-			     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
-			     <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
-			     <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
-	};
-
 	mct@101C0000 {
 		compatible = "samsung,exynos4210-mct";
 		reg = <0x101C0000 0x800>;
@@ -168,9 +159,6 @@
 	};
 
 	watchdog {
-		compatible = "samsung,s3c2410-wdt";
-		reg = <0x101D0000 0x100>;
-		interrupts = <0 42 0>;
 		clocks = <&clock 336>;
 		clock-names = "watchdog";
 	};
@@ -183,12 +171,8 @@
 	};
 
 	rtc {
-		compatible = "samsung,s3c6410-rtc";
-		reg = <0x101E0000 0x100>;
-		interrupts = <0 43 0>, <0 44 0>;
 		clocks = <&clock 337>;
 		clock-names = "rtc";
-		status = "disabled";
 	};
 
 	tmu@10060000 {
@@ -200,33 +184,21 @@
 	};
 
 	serial@12C00000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x12C00000 0x100>;
-		interrupts = <0 51 0>;
 		clocks = <&clock 289>, <&clock 146>;
 		clock-names = "uart", "clk_uart_baud0";
 	};
 
 	serial@12C10000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x12C10000 0x100>;
-		interrupts = <0 52 0>;
 		clocks = <&clock 290>, <&clock 147>;
 		clock-names = "uart", "clk_uart_baud0";
 	};
 
 	serial@12C20000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x12C20000 0x100>;
-		interrupts = <0 53 0>;
 		clocks = <&clock 291>, <&clock 148>;
 		clock-names = "uart", "clk_uart_baud0";
 	};
 
 	serial@12C30000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x12C30000 0x100>;
-		interrupts = <0 54 0>;
 		clocks = <&clock 292>, <&clock 149>;
 		clock-names = "uart", "clk_uart_baud0";
 	};
@@ -405,31 +377,19 @@
 	};
 
 	dwmmc_0: dwmmc0@12200000 {
-		compatible = "samsung,exynos5250-dw-mshc";
 		reg = <0x12200000 0x1000>;
-		interrupts = <0 75 0>;
-		#address-cells = <1>;
-		#size-cells = <0>;
 		clocks = <&clock 280>, <&clock 139>;
 		clock-names = "biu", "ciu";
 	};
 
 	dwmmc_1: dwmmc1@12210000 {
-		compatible = "samsung,exynos5250-dw-mshc";
 		reg = <0x12210000 0x1000>;
-		interrupts = <0 76 0>;
-		#address-cells = <1>;
-		#size-cells = <0>;
 		clocks = <&clock 281>, <&clock 140>;
 		clock-names = "biu", "ciu";
 	};
 
 	dwmmc_2: dwmmc2@12220000 {
-		compatible = "samsung,exynos5250-dw-mshc";
 		reg = <0x12220000 0x1000>;
-		interrupts = <0 77 0>;
-		#address-cells = <1>;
-		#size-cells = <0>;
 		clocks = <&clock 282>, <&clock 141>;
 		clock-names = "biu", "ciu";
 	};
@@ -451,6 +411,10 @@
 			&pdma0 9
 			&pdma0 8>;
 		dma-names = "tx", "rx", "tx-sec";
+		clocks = <&clock_audss EXYNOS_I2S_BUS>,
+			<&clock_audss EXYNOS_I2S_BUS>,
+			<&clock_audss EXYNOS_SCLK_I2S>;
+		clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
 		samsung,supports-6ch;
 		samsung,supports-rstclr;
 		samsung,supports-secdai;
@@ -465,6 +429,8 @@
 		dmas = <&pdma1 12
 			&pdma1 11>;
 		dma-names = "tx", "rx";
+		clocks = <&clock 307>, <&clock 157>;
+		clock-names = "iis", "i2s_opclk0";
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2s1_bus>;
 	};
@@ -475,10 +441,42 @@
 		dmas = <&pdma0 12
 			&pdma0 11>;
 		dma-names = "tx", "rx";
+		clocks = <&clock 308>, <&clock 158>;
+		clock-names = "iis", "i2s_opclk0";
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2s2_bus>;
 	};
 
+	usb@12000000 {
+		compatible = "samsung,exynos5250-dwusb3";
+		clocks = <&clock 286>;
+		clock-names = "usbdrd30";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		dwc3 {
+			compatible = "synopsys,dwc3";
+			reg = <0x12000000 0x10000>;
+			interrupts = <0 72 0>;
+			usb-phy = <&usb2_phy &usb3_phy>;
+		};
+	};
+
+	usb3_phy: usbphy@12100000 {
+		compatible = "samsung,exynos5250-usb3phy";
+		reg = <0x12100000 0x100>;
+		clocks = <&clock 1>, <&clock 286>;
+		clock-names = "ext_xtal", "usbdrd30";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		usbphy-sys {
+			reg = <0x10040704 0x8>;
+		};
+	};
+
 	usb@12110000 {
 		compatible = "samsung,exynos4210-ehci";
 		reg = <0x12110000 0x100>;
@@ -497,7 +495,7 @@
 		clock-names = "usbhost";
 	};
 
-	usbphy@12130000 {
+	usb2_phy: usbphy@12130000 {
 		compatible = "samsung,exynos5250-usb2phy";
 		reg = <0x12130000 0x100>;
 		clocks = <&clock 1>, <&clock 285>;
@@ -601,7 +599,7 @@
 	};
 
 	hdmi {
-		compatible = "samsung,exynos5-hdmi";
+		compatible = "samsung,exynos4212-hdmi";
 		reg = <0x14530000 0x70000>;
 		interrupts = <0 95 0>;
 		clocks = <&clock 333>, <&clock 136>, <&clock 137>,
@@ -611,7 +609,7 @@
 	};
 
 	mixer {
-		compatible = "samsung,exynos5-mixer";
+		compatible = "samsung,exynos5250-mixer";
 		reg = <0x14450000 0x10000>;
 		interrupts = <0 94 0>;
 	};
@@ -621,6 +619,8 @@
 		reg = <0x145b0000 0x1000>;
 		interrupts = <10 3>;
 		interrupt-parent = <&combiner>;
+		clocks = <&clock 342>;
+		clock-names = "dp";
 		#address-cells = <1>;
 		#size-cells = <0>;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250-pinctrl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250-pinctrl.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250-pinctrl.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -553,6 +553,13 @@
 			samsung,pin-pud = <0>;
 			samaung,pin-drv = <0>;
 		};
+
+		dp_hpd: dp_hpd {
+			samsung,pins = "gpx0-7";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samaung,pin-drv = <0>;
+		};
 	};
 
 	pinctrl@13400000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250-smdk5250.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250-smdk5250.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250-smdk5250.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250-smdk5250.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@
 */
 
 /dts-v1/;
-/include/ "exynos5250.dtsi"
+#include "exynos5250.dtsi"
 
 / {
 	model = "SAMSUNG SMDK5250 board based on EXYNOS5250";
@@ -37,6 +37,30 @@
 		};
 	};
 
+	vdd:fixed-regulator@0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd-supply";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+	};
+
+	dbvdd:fixed-regulator@1 {
+		compatible = "regulator-fixed";
+		regulator-name = "dbvdd-supply";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	spkvdd:fixed-regulator@2 {
+		compatible = "regulator-fixed";
+		regulator-name = "spkvdd-supply";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
 	i2c@12C70000 {
 		samsung,i2c-sda-delay = <100>;
 		samsung,i2c-max-bus-freq = <20000>;
@@ -47,8 +71,17 @@
 		};
 
 		wm8994: wm8994@1a {
-			 compatible = "wlf,wm8994";
-			 reg = <0x1a>;
+			compatible = "wlf,wm8994";
+			reg = <0x1a>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			AVDD2-supply = <&vdd>;
+			CPVDD-supply = <&vdd>;
+			DBVDD-supply = <&dbvdd>;
+			SPKVDD1-supply = <&spkvdd>;
+			SPKVDD2-supply = <&spkvdd>;
 		};
 	};
 
@@ -72,7 +105,7 @@
 		samsung,i2c-max-bus-freq = <66000>;
 
 		hdmiddc@50 {
-			compatible = "samsung,exynos5-hdmiddc";
+			compatible = "samsung,exynos4210-hdmiddc";
 			reg = <0x50>;
 		};
 	};
@@ -102,7 +135,7 @@
 		samsung,i2c-max-bus-freq = <66000>;
 
 		hdmiphy@38 {
-			compatible = "samsung,exynos5-hdmiphy";
+			compatible = "samsung,exynos4212-hdmiphy";
 			reg = <0x38>;
 		};
 	};
@@ -224,6 +257,9 @@
 		samsung,color-depth = <1>;
 		samsung,link-rate = <0x0a>;
 		samsung,lane-count = <4>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&dp_hpd>;
 	};
 
 	display-timings {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250-snow.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250-snow.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5250-snow.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5250-snow.dts	2013-08-25 20:43:22.000000000 -0400
@@ -9,8 +9,8 @@
 */
 
 /dts-v1/;
-/include/ "exynos5250.dtsi"
-/include/ "cros5250-common.dtsi"
+#include "exynos5250.dtsi"
+#include "cros5250-common.dtsi"
 
 / {
 	model = "Google Snow";
@@ -171,6 +171,10 @@
 		};
 	};
 
+	rtc {
+		status = "okay";
+	};
+
 	/*
 	 * On Snow we've got SIP WiFi and so can keep drive strengths low to
 	 * reduce EMI.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5420.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5420.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5420.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5420.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,148 @@
+/*
+ * SAMSUNG EXYNOS5420 SoC device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * SAMSUNG EXYNOS54200 SoC device nodes are listed in this file.
+ * EXYNOS5420 based board files can include this file and provide
+ * values for board specfic bindings.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "exynos5.dtsi"
+/include/ "exynos5420-pinctrl.dtsi"
+/ {
+	compatible = "samsung,exynos5420";
+
+	aliases {
+		pinctrl0 = &pinctrl_0;
+		pinctrl1 = &pinctrl_1;
+		pinctrl2 = &pinctrl_2;
+		pinctrl3 = &pinctrl_3;
+		pinctrl4 = &pinctrl_4;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x0>;
+			clock-frequency = <1800000000>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x1>;
+			clock-frequency = <1800000000>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x2>;
+			clock-frequency = <1800000000>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x3>;
+			clock-frequency = <1800000000>;
+		};
+	};
+
+	clock: clock-controller@0x10010000 {
+		compatible = "samsung,exynos5420-clock";
+		reg = <0x10010000 0x30000>;
+		#clock-cells = <1>;
+	};
+
+	mct@101C0000 {
+		compatible = "samsung,exynos4210-mct";
+		reg = <0x101C0000 0x800>;
+		interrupt-controller;
+		#interrups-cells = <1>;
+		interrupt-parent = <&mct_map>;
+		interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>;
+		clocks = <&clock 1>, <&clock 315>;
+		clock-names = "fin_pll", "mct";
+
+		mct_map: mct-map {
+			#interrupt-cells = <1>;
+			#address-cells = <0>;
+			#size-cells = <0>;
+			interrupt-map = <0 &combiner 23 3>,
+					<1 &combiner 23 4>,
+					<2 &combiner 25 2>,
+					<3 &combiner 25 3>,
+					<4 &gic 0 120 0>,
+					<5 &gic 0 121 0>,
+					<6 &gic 0 122 0>,
+					<7 &gic 0 123 0>;
+		};
+	};
+
+	pinctrl_0: pinctrl@13400000 {
+		compatible = "samsung,exynos5420-pinctrl";
+		reg = <0x13400000 0x1000>;
+		interrupts = <0 45 0>;
+
+		wakeup-interrupt-controller {
+			compatible = "samsung,exynos4210-wakeup-eint";
+			interrupt-parent = <&gic>;
+			interrupts = <0 32 0>;
+		};
+	};
+
+	pinctrl_1: pinctrl@13410000 {
+		compatible = "samsung,exynos5420-pinctrl";
+		reg = <0x13410000 0x1000>;
+		interrupts = <0 78 0>;
+	};
+
+	pinctrl_2: pinctrl@14000000 {
+		compatible = "samsung,exynos5420-pinctrl";
+		reg = <0x14000000 0x1000>;
+		interrupts = <0 46 0>;
+	};
+
+	pinctrl_3: pinctrl@14010000 {
+		compatible = "samsung,exynos5420-pinctrl";
+		reg = <0x14010000 0x1000>;
+		interrupts = <0 50 0>;
+	};
+
+	pinctrl_4: pinctrl@03860000 {
+		compatible = "samsung,exynos5420-pinctrl";
+		reg = <0x03860000 0x1000>;
+		interrupts = <0 47 0>;
+	};
+
+	serial@12C00000 {
+		clocks = <&clock 257>, <&clock 128>;
+		clock-names = "uart", "clk_uart_baud0";
+	};
+
+	serial@12C10000 {
+		clocks = <&clock 258>, <&clock 129>;
+		clock-names = "uart", "clk_uart_baud0";
+	};
+
+	serial@12C20000 {
+		clocks = <&clock 259>, <&clock 130>;
+		clock-names = "uart", "clk_uart_baud0";
+	};
+
+	serial@12C30000 {
+		clocks = <&clock 260>, <&clock 131>;
+		clock-names = "uart", "clk_uart_baud0";
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5420-pinctrl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5420-pinctrl.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5420-pinctrl.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,680 @@
+/*
+ * Samsung's Exynos5420 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos5420 SoC pin-mux and pin-config options are listed as device
+ * tree nodes are listed in this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/ {
+	pinctrl@13400000 {
+		gpy7: gpy7 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpx0: gpx0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			interrupt-parent = <&combiner>;
+			#interrupt-cells = <2>;
+			interrupts = <23 0>, <24 0>, <25 0>, <25 1>,
+				     <26 0>, <26 1>, <27 0>, <27 1>;
+		};
+
+		gpx1: gpx1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			interrupt-parent = <&combiner>;
+			#interrupt-cells = <2>;
+			interrupts = <28 0>, <28 1>, <29 0>, <29 1>,
+				     <30 0>, <30 1>, <31 0>, <31 1>;
+		};
+
+		gpx2: gpx2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpx3: gpx3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pinctrl@13410000 {
+		gpc0: gpc0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc1: gpc1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc2: gpc2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc3: gpc3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc4: gpc4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpd1: gpd1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpy0: gpy0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy1: gpy1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy2: gpy2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy3: gpy3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy4: gpy4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy5: gpy5 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy6: gpy6 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		sd0_clk: sd0-clk {
+			samsung,pins = "gpc0-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_cmd: sd0-cmd {
+			samsung,pins = "gpc0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_cd: sd0-cd {
+			samsung,pins = "gpc0-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_bus1: sd0-bus-width1 {
+			samsung,pins = "gpc0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_bus4: sd0-bus-width4 {
+			samsung,pins = "gpc0-4", "gpc0-5", "gpc0-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_bus8: sd0-bus-width8 {
+			samsung,pins = "gpc3-0", "gpc3-1", "gpc3-2", "gpc3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_clk: sd1-clk {
+			samsung,pins = "gpc1-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_cmd: sd1-cmd {
+			samsung,pins = "gpc1-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_cd: sd1-cd {
+			samsung,pins = "gpc1-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_int: sd1-int {
+			samsung,pins = "gpd1-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		sd1_bus1: sd1-bus-width1 {
+			samsung,pins = "gpc1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_bus4: sd1-bus-width4 {
+			samsung,pins = "gpc1-4", "gpc1-5", "gpc1-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_bus8: sd1-bus-width8 {
+			samsung,pins = "gpd1-4", "gpd1-5", "gpd1-6", "gpd1-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_clk: sd2-clk {
+			samsung,pins = "gpc2-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_cmd: sd2-cmd {
+			samsung,pins = "gpc2-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_cd: sd2-cd {
+			samsung,pins = "gpc2-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_bus1: sd2-bus-width1 {
+			samsung,pins = "gpc2-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_bus4: sd2-bus-width4 {
+			samsung,pins = "gpc2-4", "gpc2-5", "gpc2-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+	};
+
+	pinctrl@14000000 {
+		gpe0: gpe0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpe1: gpe1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf0: gpf0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf1: gpf1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpg0: gpg0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpg1: gpg1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpg2: gpg2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpj4: gpj4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		cam_gpio_a: cam-gpio-a {
+			samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
+				       "gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
+				       "gpe1-0", "gpe1-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		cam_gpio_b: cam-gpio-b {
+			samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
+				       "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		cam_i2c2_bus: cam-i2c2-bus {
+			samsung,pins = "gpf0-4", "gpf0-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+		cam_spi1_bus: cam-spi1-bus {
+			samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		cam_i2c1_bus: cam-i2c1-bus {
+			samsung,pins = "gpf0-2", "gpf0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		cam_i2c0_bus: cam-i2c0-bus {
+			samsung,pins = "gpf0-0", "gpf0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		cam_spi0_bus: cam-spi0-bus {
+			samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		cam_bayrgb_bus: cam-bayrgb-bus {
+			samsung,pins = "gpg0-0", "gpg0-1", "gpg0-2", "gpg0-3",
+				       "gpg0-4", "gpg0-5", "gpg0-6", "gpg0-7",
+				       "gpg1-0", "gpg1-1", "gpg1-2", "gpg1-3",
+				       "gpg1-4", "gpg1-5", "gpg1-6", "gpg1-7",
+				       "gpg2-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+	pinctrl@14010000 {
+		gpa0: gpa0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpa1: gpa1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpa2: gpa2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb0: gpb0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb1: gpb1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb2: gpb2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb3: gpb3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb4: gpb4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gph0: gph0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		uart0_data: uart0-data {
+			samsung,pins = "gpa0-0", "gpa0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart0_fctl: uart0-fctl {
+			samsung,pins = "gpa0-2", "gpa0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart1_data: uart1-data {
+			samsung,pins = "gpa0-4", "gpa0-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart1_fctl: uart1-fctl {
+			samsung,pins = "gpa0-6", "gpa0-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c2_bus: i2c2-bus {
+			samsung,pins = "gpa0-6", "gpa0-7";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart2_data: uart2-data {
+			samsung,pins = "gpa1-0", "gpa1-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart2_fctl: uart2-fctl {
+			samsung,pins = "gpa1-2", "gpa1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c3_bus: i2c3-bus {
+			samsung,pins = "gpa1-2", "gpa1-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart3_data: uart3-data {
+			samsung,pins = "gpa1-4", "gpa1-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi0_bus: spi0-bus {
+			samsung,pins = "gpa2-0", "gpa2-1", "gpa2-2", "gpa2-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi1_bus: spi1-bus {
+			samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c4_hs_bus: i2c4-hs-bus {
+			samsung,pins = "gpa2-0", "gpa2-1";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c5_hs_bus: i2c5-hs-bus {
+			samsung,pins = "gpa2-2", "gpa2-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2s1_bus: i2s1-bus {
+			samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+					"gpb0-4";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pcm1_bus: pcm1-bus {
+			samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+					"gpb0-4";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2s2_bus: i2s2-bus {
+			samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
+					"gpb1-4";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pcm2_bus: pcm2-bus {
+			samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
+					"gpb1-4";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		spdif_bus: spdif-bus {
+			samsung,pins = "gpb1-0", "gpb1-1";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi2_bus: spi2-bus {
+			samsung,pins = "gpb1-1", "gpb1-3", "gpb1-4";
+			samsung,pin-function = <5>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c6_hs_bus: i2c6-hs-bus {
+			samsung,pins = "gpb1-3", "gpb1-4";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c7_hs_bus: i2c7-hs-bus {
+			samsung,pins = "gpb2-2", "gpb2-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c0_bus: i2c0-bus {
+			samsung,pins = "gpb3-0", "gpb3-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c1_bus: i2c1-bus {
+			samsung,pins = "gpb3-2", "gpb3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c8_hs_bus: i2c8-hs-bus {
+			samsung,pins = "gpb3-4", "gpb3-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c9_hs_bus: i2c9-hs-bus {
+			samsung,pins = "gpb3-6", "gpb3-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c10_hs_bus: i2c10-hs-bus {
+			samsung,pins = "gpb4-0", "gpb4-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+	pinctrl@03860000 {
+		gpz: gpz {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		i2s0_bus: i2s0-bus {
+			samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+					"gpz-4", "gpz-5", "gpz-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5420-smdk5420.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5420-smdk5420.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5420-smdk5420.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5420-smdk5420.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,33 @@
+/*
+ * SAMSUNG SMDK5420 board device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/dts-v1/;
+#include "exynos5420.dtsi"
+
+/ {
+	model = "Samsung SMDK5420 board based on EXYNOS5420";
+	compatible = "samsung,smdk5420", "samsung,exynos5420";
+
+	memory {
+		reg = <0x20000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttySAC2,115200 init=/linuxrc";
+	};
+
+	fixed-rate-clocks {
+		oscclk {
+			compatible = "samsung,exynos5420-oscclk";
+			clock-frequency = <24000000>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5440.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5440.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5440.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5440.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -9,13 +9,17 @@
  * published by the Free Software Foundation.
 */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
 	compatible = "samsung,exynos5440";
 
 	interrupt-parent = <&gic>;
 
+	aliases {
+		spi0 = &spi_0;
+	};
+
 	clock: clock-controller@0x160000 {
 		compatible = "samsung,exynos5440-clock";
 		reg = <0x160000 0x1000>;
@@ -38,18 +42,22 @@
 		#size-cells = <0>;
 
 		cpu@0 {
+			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <0>;
 		};
 		cpu@1 {
+			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <1>;
 		};
 		cpu@2 {
+			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <2>;
 		};
 		cpu@3 {
+			device_type = "cpu";
 			compatible = "arm,cortex-a15";
 			reg = <3>;
 		};
@@ -79,8 +87,13 @@
 		interrupts = <0 57 0>;
 		operating-points = <
 				/* KHz	  uV */
+				1500000 1100000
+				1400000 1075000
+				1300000 1050000
 				1200000 1025000
+				1100000 1000000
 				1000000 975000
+				900000  950000
 				800000  925000
 		>;
 	};
@@ -101,19 +114,19 @@
 		clock-names = "uart", "clk_uart_baud0";
 	};
 
-	spi {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0xD0000 0x1000>;
+	spi_0: spi@D0000 {
+		compatible = "samsung,exynos5440-spi";
+		reg = <0xD0000 0x100>;
 		interrupts = <0 4 0>;
-		tx-dma-channel = <&pdma0 5>; /* preliminary */
-		rx-dma-channel = <&pdma0 4>; /* preliminary */
 		#address-cells = <1>;
 		#size-cells = <0>;
+		samsung,spi-src-clk = <0>;
+		num-cs = <1>;
 		clocks = <&clock 21>, <&clock 16>;
 		clock-names = "spi", "spi_busclk0";
 	};
 
-	pinctrl {
+	pin_ctrl: pinctrl {
 		compatible = "samsung,exynos5440-pinctrl";
 		reg = <0xE0000 0x1000>;
 		interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>,
@@ -184,28 +197,6 @@
 		compatible = "arm,amba-bus";
 		interrupt-parent = <&gic>;
 		ranges;
-
-		pdma0: pdma@00121000 {
-			compatible = "arm,pl330", "arm,primecell";
-			reg = <0x121000 0x1000>;
-			interrupts = <0 46 0>;
-			clocks = <&clock 8>;
-			clock-names = "apb_pclk";
-			#dma-cells = <1>;
-			#dma-channels = <8>;
-			#dma-requests = <32>;
-		};
-
-		pdma1: pdma@00120000 {
-			compatible = "arm,pl330", "arm,primecell";
-			reg = <0x120000 0x1000>;
-			interrupts = <0 47 0>;
-			clocks = <&clock 8>;
-			clock-names = "apb_pclk";
-			#dma-cells = <1>;
-			#dma-channels = <8>;
-			#dma-requests = <32>;
-		};
 	};
 
 	rtc {
@@ -214,6 +205,67 @@
 		interrupts = <0 17 0>, <0 16 0>;
 		clocks = <&clock 21>;
 		clock-names = "rtc";
-		status = "disabled";
+	};
+
+	sata@210000 {
+		compatible = "snps,exynos5440-ahci";
+		reg = <0x210000 0x10000>;
+		interrupts = <0 30 0>;
+		clocks = <&clock 23>;
+		clock-names = "sata";
+	};
+
+	ohci@220000 {
+		compatible = "samsung,exynos5440-ohci";
+		reg = <0x220000 0x1000>;
+		interrupts = <0 29 0>;
+		clocks = <&clock 24>;
+		clock-names = "usbhost";
+	};
+
+	ehci@221000 {
+		compatible = "samsung,exynos5440-ehci";
+		reg = <0x221000 0x1000>;
+		interrupts = <0 29 0>;
+		clocks = <&clock 24>;
+		clock-names = "usbhost";
+	};
+
+	pcie@290000 {
+		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+		reg = <0x290000 0x1000
+			0x270000 0x1000
+			0x271000 0x40>;
+		interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
+		clocks = <&clock 28>, <&clock 27>;
+		clock-names = "pcie", "pcie_bus";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000   /* configuration space */
+			  0x81000000 0 0	  0x40001000 0 0x00010000   /* downstream I/O */
+			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0x0 0 &gic 53>;
+	};
+
+	pcie@2a0000 {
+		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+		reg = <0x2a0000 0x1000
+			0x272000 0x1000
+			0x271040 0x40>;
+		interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
+		clocks = <&clock 29>, <&clock 27>;
+		clock-names = "pcie", "pcie_bus";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000   /* configuration space */
+			  0x81000000 0 0	  0x60001000 0 0x00010000   /* downstream I/O */
+			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0x0 0 &gic 56>;
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5440-sd5v1.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5440-sd5v1.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5440-sd5v1.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5440-sd5v1.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,14 +10,14 @@
 */
 
 /dts-v1/;
-/include/ "exynos5440.dtsi"
+#include "exynos5440.dtsi"
 
 / {
 	model = "SAMSUNG SD5v1 board based on EXYNOS5440";
 	compatible = "samsung,sd5v1", "samsung,exynos5440";
 
 	chosen {
-		bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 console=ttySAC0,115200";
+		bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
 	};
 
 	fixed-rate-clocks {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5440-ssdk5440.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5440-ssdk5440.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5440-ssdk5440.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5440-ssdk5440.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,18 +10,53 @@
 */
 
 /dts-v1/;
-/include/ "exynos5440.dtsi"
+#include "exynos5440.dtsi"
 
 / {
 	model = "SAMSUNG SSDK5440 board based on EXYNOS5440";
 	compatible = "samsung,ssdk5440", "samsung,exynos5440";
 
 	chosen {
-		bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 console=ttySAC0,115200";
+		bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 mem=6144M@0x100000000 console=ttySAC0,115200";
 	};
 
-	spi {
-		status = "disabled";
+	spi_0: spi@D0000 {
+
+		flash: w25q128@0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "winbond,w25q128";
+			spi-max-frequency = <15625000>;
+			reg = <0>;
+			controller-data {
+				samsung,spi-feedback-delay = <0>;
+			};
+
+			partition@00000 {
+				label = "BootLoader";
+				reg = <0x60000 0x80000>;
+				read-only;
+			};
+
+			partition@e0000 {
+				label = "Recovery-Kernel";
+				reg = <0xe0000 0x300000>;
+				read-only;
+			};
+
+			partition@3e0000 {
+				label = "CRAM-FS";
+				reg = <0x3e0000 0x700000>;
+				read-only;
+			};
+
+			partition@ae0000 {
+				label = "User-Data";
+				reg = <0xae0000 0x520000>;
+			};
+
+		};
+
 	};
 
 	fixed-rate-clocks {
@@ -30,4 +65,12 @@
 			clock-frequency = <50000000>;
 		};
 	};
+
+	pcie@290000 {
+		reset-gpio = <&pin_ctrl 5 0>;
+	};
+
+	pcie@2a0000 {
+		reset-gpio = <&pin_ctrl 22 0>;
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/exynos5.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/exynos5.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,111 @@
+/*
+ * Samsung's Exynos5 SoC series common device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos5 SoC series device nodes are listed in this file. Particular
+ * SoCs from Exynos5 series can include this file and provide values for SoCs
+ * specfic bindings.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+	interrupt-parent = <&gic>;
+
+	chipid@10000000 {
+		compatible = "samsung,exynos4210-chipid";
+		reg = <0x10000000 0x100>;
+	};
+
+	combiner:interrupt-controller@10440000 {
+		compatible = "samsung,exynos4210-combiner";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		samsung,combiner-nr = <32>;
+		reg = <0x10440000 0x1000>;
+		interrupts =	<0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+				<0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+				<0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+				<0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+				<0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+				<0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>,
+				<0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+				<0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+	};
+
+	gic:interrupt-controller@10481000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg =	<0x10481000 0x1000>,
+			<0x10482000 0x1000>,
+			<0x10484000 0x2000>,
+			<0x10486000 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	dwmmc_0: dwmmc0@12200000 {
+		compatible = "samsung,exynos5250-dw-mshc";
+		interrupts = <0 75 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	dwmmc_1: dwmmc1@12210000 {
+		compatible = "samsung,exynos5250-dw-mshc";
+		interrupts = <0 76 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	dwmmc_2: dwmmc2@12220000 {
+		compatible = "samsung,exynos5250-dw-mshc";
+		interrupts = <0 77 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	serial@12C00000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x12C00000 0x100>;
+		interrupts = <0 51 0>;
+	};
+
+	serial@12C10000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x12C10000 0x100>;
+		interrupts = <0 52 0>;
+	};
+
+	serial@12C20000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x12C20000 0x100>;
+		interrupts = <0 53 0>;
+	};
+
+	serial@12C30000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x12C30000 0x100>;
+		interrupts = <0 54 0>;
+	};
+
+	rtc {
+		compatible = "samsung,s3c6410-rtc";
+		reg = <0x101E0000 0x100>;
+		interrupts = <0 43 0>, <0 44 0>;
+		status = "disabled";
+	};
+
+	watchdog {
+		compatible = "samsung,s3c2410-wdt";
+		reg = <0x101D0000 0x100>;
+		interrupts = <0 42 0>;
+		status = "disabled";
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/ge863-pro3.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ge863-pro3.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/ge863-pro3.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ge863-pro3.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  * Licensed under GPLv2 or later.
  */
 
-/include/ "at91sam9260.dtsi"
+#include "at91sam9260.dtsi"
 
 / {
 	clocks {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/href.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/href.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/href.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/href.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,8 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-/include/ "dbx5x0.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "dbx5x0.dtsi"
 
 / {
 	memory {
@@ -27,7 +28,7 @@
 		};
 	};
 
-	soc-u9500 {
+	soc {
 		uart@80120000 {
 			status = "okay";
 		};
@@ -45,14 +46,14 @@
 				compatible = "tc3589x";
 				reg = <0x42>;
 				interrupt-parent = <&gpio6>;
-				interrupts = <25 0x1>;
+				interrupts = <25 IRQ_TYPE_EDGE_RISING>;
 
 				interrupt-controller;
 				#interrupt-cells = <2>;
 
 				tc3589x_gpio: tc3589x_gpio {
 					compatible = "tc3589x-gpio";
-					interrupts = <0 0x1>;
+					interrupts = <0 IRQ_TYPE_EDGE_RISING>;
 
 					interrupt-controller;
 					#interrupt-cells = <2>;
@@ -63,17 +64,43 @@
 		};
 
 		i2c@80128000 {
-			lp5521@0x33 {
-				compatible = "lp5521";
+			lp5521@33 {
+				compatible = "national,lp5521";
 				reg = <0x33>;
+				label = "lp5521_pri";
+				clock-mode = /bits/ 8 <2>;
+				chan0 {
+					led-cur = /bits/ 8 <0x2f>;
+					max-cur = /bits/ 8 <0x5f>;
+				};
+				chan1 {
+					led-cur = /bits/ 8 <0x2f>;
+					max-cur = /bits/ 8 <0x5f>;
+				};
+				chan2 {
+					led-cur = /bits/ 8 <0x2f>;
+					max-cur = /bits/ 8 <0x5f>;
+				};
 			};
-
-			lp5521@0x34 {
-				compatible = "lp5521";
+			lp5521@34 {
+				compatible = "national,lp5521";
 				reg = <0x34>;
+				label = "lp5521_sec";
+				clock-mode = /bits/ 8 <2>;
+				chan0 {
+					led-cur = /bits/ 8 <0x2f>;
+					max-cur = /bits/ 8 <0x5f>;
+				};
+				chan1 {
+					led-cur = /bits/ 8 <0x2f>;
+					max-cur = /bits/ 8 <0x5f>;
+				};
+				chan2 {
+					led-cur = /bits/ 8 <0x2f>;
+					max-cur = /bits/ 8 <0x5f>;
+				};
 			};
-
-			bh1780@0x29 {
+			bh1780@29 {
 				compatible = "rohm,bh1780gli";
 				reg = <0x33>;
 			};
@@ -82,7 +109,7 @@
 		// External Micro SD slot
 		sdi0_per1@80126000 {
 			arm,primecell-periphid = <0x10480180>;
-			max-frequency = <50000000>;
+			max-frequency = <100000000>;
 			bus-width = <4>;
 			mmc-cap-sd-highspeed;
 			mmc-cap-mmc-highspeed;
@@ -97,7 +124,7 @@
 		// WLAN SDIO channel
 		sdi1_per2@80118000 {
 			arm,primecell-periphid = <0x10480180>;
-			max-frequency = <50000000>;
+			max-frequency = <100000000>;
 			bus-width = <4>;
 
 			status = "okay";
@@ -106,7 +133,7 @@
 		// PoP:ed eMMC
 		sdi2_per3@80005000 {
 			arm,primecell-periphid = <0x10480180>;
-			max-frequency = <50000000>;
+			max-frequency = <100000000>;
 			bus-width = <8>;
 			mmc-cap-mmc-highspeed;
 
@@ -116,7 +143,7 @@
 		// On-board eMMC
 		sdi4_per2@80114000 {
 			arm,primecell-periphid = <0x10480180>;
-		        max-frequency = <50000000>;
+		        max-frequency = <100000000>;
 			bus-width = <8>;
 			mmc-cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux2_reg>;
@@ -236,7 +263,7 @@
 						regulator-name = "V-MMC-SD";
 					};
 
-					ab8500_ldo_initcore_reg: ab8500_ldo_initcore {
+					ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
 						regulator-name = "V-INTCORE";
 					};
 
@@ -256,7 +283,7 @@
 						regulator-name = "V-AMIC1";
 					};
 
-					ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 {
+					ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
 						regulator-name = "V-AMIC2";
 					};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/hrefprev60.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/hrefprev60.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/hrefprev60.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/hrefprev60.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,9 +10,9 @@
  */
 
 /dts-v1/;
-/include/ "dbx5x0.dtsi"
-/include/ "href.dtsi"
-/include/ "stuib.dtsi"
+#include "dbx5x0.dtsi"
+#include "href.dtsi"
+#include "stuib.dtsi"
 
 / {
 	model = "ST-Ericsson HREF (pre-v60) platform with Device Tree";
@@ -24,7 +24,7 @@
 		};
 	};
 
-	soc-u9500 {
+	soc {
 		prcmu@80157000 {
 			ab8500@5 {
 				ab8500-gpio {
@@ -41,7 +41,7 @@
 		};
 
 		i2c@80110000 {
-			bu21013_tp@0x5c {
+			bu21013_tp@5c {
 				reset-gpio = <&tc3589x_gpio 13 0x4>;
 			};
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/hrefv60plus.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/hrefv60plus.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/hrefv60plus.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/hrefv60plus.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,9 +10,9 @@
  */
 
 /dts-v1/;
-/include/ "dbx5x0.dtsi"
-/include/ "href.dtsi"
-/include/ "stuib.dtsi"
+#include "dbx5x0.dtsi"
+#include "href.dtsi"
+#include "stuib.dtsi"
 
 / {
 	model = "ST-Ericsson HREF (v60+) platform with Device Tree";
@@ -24,7 +24,7 @@
 		};
 	};
 
-	soc-u9500 {
+	soc {
 		i2c@80110000 {
 			bu21013_tp@0x5c {
 				reset-gpio = <&gpio4 15 0x4>;
@@ -34,7 +34,7 @@
 		// External Micro SD slot
 		sdi0_per1@80126000 {
 			arm,primecell-periphid = <0x10480180>;
-			max-frequency = <50000000>;
+			max-frequency = <100000000>;
 			bus-width = <4>;
 			mmc-cap-sd-highspeed;
 			mmc-cap-mmc-highspeed;
@@ -48,7 +48,7 @@
 		// WLAN SDIO channel
 		sdi1_per2@80118000 {
 			arm,primecell-periphid = <0x10480180>;
-			max-frequency = <50000000>;
+			max-frequency = <100000000>;
 			bus-width = <4>;
 
 			status = "okay";
@@ -57,7 +57,7 @@
 		// PoP:ed eMMC
 		sdi2_per3@80005000 {
 			arm,primecell-periphid = <0x10480180>;
-			max-frequency = <50000000>;
+			max-frequency = <100000000>;
 			bus-width = <8>;
 			mmc-cap-mmc-highspeed;
 
@@ -67,7 +67,7 @@
 		// On-board eMMC
 		sdi4_per2@80114000 {
 			arm,primecell-periphid = <0x10480180>;
-		        max-frequency = <50000000>;
+		        max-frequency = <100000000>;
 			bus-width = <8>;
 			mmc-cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux2_reg>;
@@ -172,7 +172,7 @@
 						regulator-name = "V-MMC-SD";
 					};
 
-					ab8500_ldo_initcore_reg: ab8500_ldo_initcore {
+					ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
 						regulator-name = "V-INTCORE";
 					};
 
@@ -192,7 +192,7 @@
 						regulator-name = "V-AMIC1";
 					};
 
-					ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 {
+					ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
 						regulator-name = "V-AMIC2";
 					};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx23.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx23.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx23.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx23.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -23,8 +23,12 @@
 	};
 
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx27.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx27.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx27.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx27.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,9 @@
 		gpio3 = &gpio4;
 		gpio4 = &gpio5;
 		gpio5 = &gpio6;
+		spi0 = &cspi1;
+		spi1 = &cspi2;
+		spi2 = &cspi3;
 	};
 
 	avic: avic-interrupt-controller@e0000000 {
@@ -58,6 +61,16 @@
 			reg = <0x10000000 0x20000>;
 			ranges;
 
+			dma: dma@10001000 {
+				compatible = "fsl,imx27-dma";
+				reg = <0x10001000 0x1000>;
+				interrupts = <32>;
+				clocks = <&clks 50>, <&clks 70>;
+				clock-names = "ipg", "ahb";
+				#dma-cells = <1>;
+				#dma-channels = <16>;
+			};
+
 			wdog: wdog@10002000 {
 				compatible = "fsl,imx27-wdt", "fsl,imx21-wdt";
 				reg = <0x10002000 0x1000>;
@@ -89,6 +102,14 @@
 				clock-names = "ipg", "per";
 			};
 
+			pwm0: pwm@10006000 {
+				compatible = "fsl,imx27-pwm";
+				reg = <0x10006000 0x1000>;
+				interrupts = <23>;
+				clocks = <&clks 34>, <&clks 61>;
+				clock-names = "ipg", "per";
+			};
+
 			uart1: serial@1000a000 {
 				compatible = "fsl,imx27-uart", "fsl,imx21-uart";
 				reg = <0x1000a000 0x1000>;
@@ -157,6 +178,28 @@
 				status = "disabled";
 			};
 
+			sdhci1: sdhci@10013000 {
+				compatible = "fsl,imx27-mmc", "fsl,imx21-mmc";
+				reg = <0x10013000 0x1000>;
+				interrupts = <11>;
+				clocks = <&clks 30>, <&clks 60>;
+				clock-names = "ipg", "per";
+				dmas = <&dma 7>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
+			sdhci2: sdhci@10014000 {
+				compatible = "fsl,imx27-mmc", "fsl,imx21-mmc";
+				reg = <0x10014000 0x1000>;
+				interrupts = <10>;
+				clocks = <&clks 29>, <&clks 60>;
+				clock-names = "ipg", "per";
+				dmas = <&dma 6>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
 			gpio1: gpio@10015000 {
 				compatible = "fsl,imx27-gpio", "fsl,imx21-gpio";
 				reg = <0x10015000 0x100>;
@@ -272,6 +315,17 @@
 				status = "disabled";
 			};
 
+			sdhci3: sdhci@1001e000 {
+				compatible = "fsl,imx27-mmc", "fsl,imx21-mmc";
+				reg = <0x1001e000 0x1000>;
+				interrupts = <9>;
+				clocks = <&clks 28>, <&clks 60>;
+				clock-names = "ipg", "per";
+				dmas = <&dma 36>;
+				dma-names = "rx-tx";
+				status = "disabled";
+			};
+
 			gpt6: timer@1001f000 {
 				compatible = "fsl,imx27-gpt", "fsl,imx1-gpt";
 				reg = <0x1001f000 0x1000>;
@@ -288,6 +342,21 @@
 			reg = <0x10020000 0x20000>;
 			ranges;
 
+			coda: coda@10023000 {
+				compatible = "fsl,imx27-vpu";
+				reg = <0x10023000 0x0200>;
+				interrupts = <53>;
+				clocks = <&clks 57>, <&clks 66>;
+				clock-names = "per", "ahb";
+				iram = <&iram>;
+			};
+
+			clks: ccm@10027000{
+				compatible = "fsl,imx27-ccm";
+				reg = <0x10027000 0x1000>;
+				#clock-cells = <1>;
+			};
+
 			fec: ethernet@1002b000 {
 				compatible = "fsl,imx27-fec";
 				reg = <0x1002b000 0x4000>;
@@ -296,19 +365,16 @@
 				clock-names = "ipg", "ahb", "ptp";
 				status = "disabled";
 			};
-
-			clks: ccm@10027000{
-				compatible = "fsl,imx27-ccm";
-				reg = <0x10027000 0x1000>;
-				#clock-cells = <1>;
-			};
 		};
 
+		iram: iram@ffff4c00 {
+			compatible = "mmio-sram";
+			reg = <0xffff4c00 0xb400>;
+		};
 
 		nfc: nand@d8000000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
-
 			compatible = "fsl,imx27-nand";
 			reg = <0xd8000000 0x1000>;
 			interrupts = <29>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx27-phytec-phycore.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx27-phytec-phycore.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx27-phytec-phycore.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx27-phytec-phycore.dts	1969-12-31 19:00:00.000000000 -0500
@@ -1,79 +0,0 @@
-/*
- * Copyright 2012 Sascha Hauer, Pengutronix
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-/dts-v1/;
-#include "imx27.dtsi"
-
-/ {
-	model = "Phytec pcm038";
-	compatible = "phytec,imx27-pcm038", "fsl,imx27";
-
-	memory {
-		reg = <0x0 0x0>;
-	};
-
-	soc {
-		aipi@10000000 { /* aipi1 */
-			serial@1000a000 {
-				fsl,uart-has-rtscts;
-				status = "okay";
-			};
-
-			serial@1000b000 {
-				fsl,uart-has-rtscts;
-				status = "okay";
-			};
-
-			serial@1000c000 {
-				fsl,uart-has-rtscts;
-				status = "okay";
-			};
-
-			i2c@1001d000 {
-				clock-frequency = <400000>;
-				status = "okay";
-				at24@52 {
-					compatible = "at,24c32";
-					pagesize = <32>;
-					reg = <0x52>;
-				};
-				pcf8563@51 {
-					compatible = "nxp,pcf8563";
-					reg = <0x51>;
-				};
-				lm75@4a {
-					compatible = "national,lm75";
-					reg = <0x4a>;
-				};
-			};
-		};
-
-		aipi@10020000 { /* aipi2 */
-			ethernet@1002b000 {
-				status = "okay";
-			};
-		};
-	};
-
-	nor_flash@c0000000 {
-		compatible = "cfi-flash";
-		bank-width = <2>;
-		reg = <0xc0000000 0x02000000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-	};
-};
-
-&nfc {
-	nand-bus-width = <8>;
-	nand-ecc-mode = "hw";
-	status = "okay";
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "imx27-phytec-phycore-som.dts"
+
+/ {
+	model = "Phytec pcm970";
+	compatible = "phytec,imx27-pcm970", "phytec,imx27-pcm038", "fsl,imx27";
+};
+
+&cspi1 {
+	fsl,spi-num-chipselects = <2>;
+	cs-gpios = <&gpio4 28 0>, <&gpio4 27 0>;
+};
+
+&sdhci2 {
+	bus-width = <4>;
+	cd-gpios = <&gpio3 29 0>;
+	wp-gpios = <&gpio3 28 0>;
+	vmmc-supply = <&vmmc1_reg>;
+	status = "okay";
+};
+
+&uart1 {
+	fsl,uart-has-rtscts;
+};
+
+&uart2 {
+	fsl,uart-has-rtscts;
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx27-phytec-phycore-som.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx27-phytec-phycore-som.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx27-phytec-phycore-som.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx27-phytec-phycore-som.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx27.dtsi"
+
+/ {
+	model = "Phytec pcm038";
+	compatible = "phytec,imx27-pcm038", "fsl,imx27";
+
+	memory {
+		reg = <0x0 0x0>;
+	};
+
+	soc {
+		aipi@10000000 { /* aipi1 */
+			serial@1000a000 {
+				status = "okay";
+			};
+
+			i2c@1001d000 {
+				clock-frequency = <400000>;
+				status = "okay";
+				at24@52 {
+					compatible = "at,24c32";
+					pagesize = <32>;
+					reg = <0x52>;
+				};
+				pcf8563@51 {
+					compatible = "nxp,pcf8563";
+					reg = <0x51>;
+				};
+				lm75@4a {
+					compatible = "national,lm75";
+					reg = <0x4a>;
+				};
+			};
+		};
+
+		aipi@10020000 { /* aipi2 */
+			ethernet@1002b000 {
+				phy-reset-gpios = <&gpio3 30 0>;
+				status = "okay";
+			};
+		};
+	};
+
+	nor_flash@c0000000 {
+		compatible = "cfi-flash";
+		bank-width = <2>;
+		reg = <0xc0000000 0x02000000>;
+		linux,mtd-name = "physmap-flash.0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+	};
+};
+
+&cspi1 {
+	fsl,spi-num-chipselects = <1>;
+	cs-gpios = <&gpio4 28 0>;
+	status = "okay";
+
+	pmic: mc13783@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "fsl,mc13783";
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <23 0x4>;
+		fsl,mc13xxx-uses-adc;
+		fsl,mc13xxx-uses-rtc;
+
+		regulators {
+			sw1a_reg: sw1a {
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			sw1b_reg: sw1b {
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			sw2a_reg: sw2a {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			sw2b_reg: sw2b {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			sw3_reg: sw3 {
+				regulator-min-microvolt = <5000000>;
+				regulator-max-microvolt = <5000000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vaudio_reg: vaudio {
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			violo_reg: violo {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			viohi_reg: viohi {
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vgen_reg: vgen {
+				regulator-min-microvolt = <1500000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vcam_reg: vcam {
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+			};
+
+			vrf1_reg: vrf1 {
+				regulator-min-microvolt = <2775000>;
+				regulator-max-microvolt = <2775000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vrf2_reg: vrf2 {
+				regulator-min-microvolt = <2775000>;
+				regulator-max-microvolt = <2775000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			vmmc1_reg: vmmc1 {
+				regulator-min-microvolt = <1600000>;
+				regulator-max-microvolt = <3000000>;
+			};
+
+			gpo1_reg: gpo1 { };
+
+			pwgt1spi_reg: pwgt1spi {
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&nfc {
+	nand-bus-width = <8>;
+	nand-ecc-mode = "hw";
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-apf28dev.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-apf28dev.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-apf28dev.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-apf28dev.dts	2013-08-25 20:43:22.000000000 -0400
@@ -103,6 +103,7 @@
 
 		apbx@80040000 {
 			lradc@80050000 {
+				fsl,lradc-touchscreen-wires = <4>;
 				status = "okay";
 			};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-apx4devkit.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-apx4devkit.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-apx4devkit.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-apx4devkit.dts	2013-08-25 20:43:22.000000000 -0400
@@ -147,7 +147,7 @@
 					reg = <0x0a>;
 					VDDA-supply = <&reg_3p3v>;
 					VDDIO-supply = <&reg_3p3v>;
-
+					clocks = <&saif0>;
 				};
 
 				pcf8563: rtc@51 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-cfa10036.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-cfa10036.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-cfa10036.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-cfa10036.dts	2013-08-25 20:43:22.000000000 -0400
@@ -45,6 +45,17 @@
 					fsl,voltage = <1>;
 					fsl,pull-up = <0>;
 				};
+
+				usb0_otg_cfa10036: otg-10036@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x0142 /* MX28_PAD_GPMI_READY0__USB0_ID */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
 			};
 
 			ssp0: ssp@80010000 {
@@ -58,12 +69,6 @@
 		};
 
 		apbx@80040000 {
-			pwm: pwm@80064000 {
-				pinctrl-names = "default";
-				pinctrl-0 = <&pwm4_pins_a>;
-				status = "okay";
-			};
-
 			duart: serial@80074000 {
 				pinctrl-names = "default";
 				pinctrl-0 = <&duart_pins_b>;
@@ -73,15 +78,30 @@
 			i2c0: i2c@80058000 {
 				pinctrl-names = "default";
 				pinctrl-0 = <&i2c0_pins_b>;
+				clock-frequency = <400000>;
 				status = "okay";
 
-				ssd1307: oled@3c {
-					compatible = "solomon,ssd1307fb-i2c";
+				ssd1306: oled@3c {
+					compatible = "solomon,ssd1306fb-i2c";
 					reg = <0x3c>;
-					pwms = <&pwm 4 3000>;
 					reset-gpios = <&gpio2 7 0>;
+					solomon,height = <32>;
+					solomon,width = <128>;
+					solomon,page-offset = <0>;
 				};
 			};
+
+			usbphy0: usbphy@8007c000 {
+				status = "okay";
+			};
+		};
+	};
+
+	ahb@80080000 {
+		usb0: usb@80080000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&usb0_otg_cfa10036>;
+			status = "okay";
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-cfa10049.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-cfa10049.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-cfa10049.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-cfa10049.dts	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,7 @@
 						0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */
 						0x1173 /* MX28_PAD_LCD_D22__GPIO_1_23 */
 						0x2153 /* MX28_PAD_SSP2_D5__GPIO_2_21 */
-						0x3173 /* MX28_PAD_LCD_RESET__GPIO_3_23 */
+						0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */
 					>;
 					fsl,drive-strength = <0>;
 					fsl,voltage = <1>;
@@ -166,8 +166,8 @@
 
 		apbx@80040000 {
 			pwm: pwm@80064000 {
-				pinctrl-names = "default", "default";
-				pinctrl-1 = <&pwm3_pins_b>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&pwm3_pins_b>;
 				status = "okay";
 			};
 
@@ -265,7 +265,7 @@
 		gpio-sck = <&gpio2 16 0>;
 		gpio-mosi = <&gpio2 17 0>;
 		gpio-miso = <&gpio2 18 0>;
-		cs-gpios = <&gpio3 23 0>;
+		cs-gpios = <&gpio3 5 0>;
 		num-chipselects = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-cfa10055.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-cfa10055.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-cfa10055.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-cfa10055.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2013 Crystalfontz America, Inc.
+ * 				  Free Electrons
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * The CFA-10055 is an expansion board for the CFA-10036 module and
+ * CFA-10037, thus we need to include the CFA-10037 DTS.
+ */
+/include/ "imx28-cfa10037.dts"
+
+/ {
+	model = "Crystalfontz CFA-10055 Board";
+	compatible = "crystalfontz,cfa10055", "crystalfontz,cfa10037", "crystalfontz,cfa10036", "fsl,imx28";
+
+	apb@80000000 {
+		apbh@80000000 {
+			pinctrl@80018000 {
+				pinctrl-names = "default", "default";
+				pinctrl-1 = <&hog_pins_cfa10055
+					&hog_pins_cfa10055_pullup>;
+
+				hog_pins_cfa10055: hog-10055@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
+				hog_pins_cfa10055_pullup: hog-10055-pullup@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <1>;
+				};
+
+				spi2_pins_cfa10055: spi2-cfa10055@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x2103 /* MX28_PAD_SSP2_SCK__GPIO_2_16 */
+						0x2113 /* MX28_PAD_SSP2_CMD__GPIO_2_17 */
+						0x2123 /* MX28_PAD_SSP2_D0__GPIO_2_18 */
+					>;
+					fsl,drive-strength = <1>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <1>;
+				};
+
+				lcdif_18bit_pins_cfa10055: lcdif-18bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
+						0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
+						0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
+						0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
+						0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
+						0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
+						0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
+						0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
+						0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
+						0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
+						0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
+						0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
+						0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
+						0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
+						0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
+						0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
+						0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */
+						0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
+				lcdif_pins_cfa10055: lcdif-evk@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
+						0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
+						0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
+						0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+			};
+
+			lcdif@80030000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&lcdif_18bit_pins_cfa10055
+					     &lcdif_pins_cfa10055>;
+				display = <&display>;
+				status = "okay";
+
+				display: display {
+					bits-per-pixel = <32>;
+					bus-width = <18>;
+
+					display-timings {
+						native-mode = <&timing0>;
+						timing0: timing0 {
+							clock-frequency = <9216000>;
+							hactive = <320>;
+							vactive = <480>;
+							hback-porch = <2>;
+							hfront-porch = <2>;
+							vback-porch = <2>;
+							vfront-porch = <2>;
+							hsync-len = <15>;
+							vsync-len = <15>;
+							hsync-active = <0>;
+							vsync-active = <0>;
+							de-active = <1>;
+							pixelclk-active = <1>;
+						};
+					};
+				};
+			};
+		};
+
+		apbx@80040000 {
+			lradc@80050000 {
+				fsl,lradc-touchscreen-wires = <4>;
+				status = "okay";
+			};
+
+			pwm: pwm@80064000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pwm3_pins_b>;
+				status = "okay";
+			};
+		};
+	};
+
+	spi2 {
+		compatible = "spi-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi2_pins_cfa10055>;
+		status = "okay";
+		gpio-sck = <&gpio2 16 0>;
+		gpio-mosi = <&gpio2 17 0>;
+		gpio-miso = <&gpio2 18 0>;
+		cs-gpios = <&gpio3 5 0>;
+		num-chipselects = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		hx8357: hx8357@0 {
+			compatible = "himax,hx8357b", "himax,hx8357";
+			reg = <0>;
+			spi-max-frequency = <100000>;
+			spi-cpol;
+			spi-cpha;
+			gpios-reset = <&gpio3 30 0>;
+		};
+	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 3 5000000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-cfa10057.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-cfa10057.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-cfa10057.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-cfa10057.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2013 Crystalfontz America, Inc.
+ * Copyright 2012 Free Electrons
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * The CFA-10057 is an expansion board for the CFA-10036 module, thus we
+ * need to include the CFA-10036 DTS.
+ */
+/include/ "imx28-cfa10036.dts"
+
+/ {
+	model = "Crystalfontz CFA-10057 Board";
+	compatible = "crystalfontz,cfa10057", "crystalfontz,cfa10036", "fsl,imx28";
+
+	apb@80000000 {
+		apbh@80000000 {
+			pinctrl@80018000 {
+				pinctrl-names = "default", "default";
+				pinctrl-1 = <&hog_pins_cfa10057
+					&hog_pins_cfa10057_pullup>;
+
+				hog_pins_cfa10057: hog-10057@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */
+						0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
+				hog_pins_cfa10057_pullup: hog-10057-pullup@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x2133 /* MX28_PAD_SSP2_D3__GPIO_2_19 */
+						0x3183 /* MX28_PAD_I2C0_SCL__GPIO_3_24 */
+						0x3193 /* MX28_PAD_I2C0_SDA__GPIO_3_25 */
+						0x31a3 /* MX28_PAD_SAIF_SDATA0__GPIO_3_26 */
+						0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <1>;
+				};
+
+				lcdif_18bit_pins_cfa10057: lcdif-18bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
+						0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
+						0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
+						0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
+						0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
+						0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
+						0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
+						0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
+						0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
+						0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
+						0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
+						0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
+						0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
+						0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
+						0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
+						0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
+						0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */
+						0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
+				lcdif_pins_cfa10057: lcdif-evk@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
+						0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
+						0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
+						0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+			};
+
+			lcdif@80030000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&lcdif_18bit_pins_cfa10057
+					     &lcdif_pins_cfa10057>;
+				display = <&display>;
+				status = "okay";
+
+				display: display {
+					bits-per-pixel = <32>;
+					bus-width = <18>;
+
+					display-timings {
+						native-mode = <&timing0>;
+						timing0: timing0 {
+							clock-frequency = <30000000>;
+							hactive = <480>;
+							vactive = <800>;
+							hfront-porch = <12>;
+							hback-porch = <2>;
+							vfront-porch = <5>;
+							vback-porch = <3>;
+							hsync-len = <2>;
+							vsync-len = <2>;
+							hsync-active = <0>;
+							vsync-active = <0>;
+							de-active = <1>;
+							pixelclk-active = <1>;
+						};
+					};
+				};
+			};
+		};
+
+		apbx@80040000 {
+			lradc@80050000 {
+				fsl,lradc-touchscreen-wires = <4>;
+				status = "okay";
+			};
+
+			pwm: pwm@80064000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pwm3_pins_b>;
+				status = "okay";
+			};
+
+			i2c1: i2c@8005a000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&i2c1_pins_a>;
+				status = "okay";
+			};
+
+			usbphy1: usbphy@8007e000 {
+				status = "okay";
+			};
+		};
+	};
+
+	ahb@80080000 {
+		usb1: usb@80090000 {
+			vbus-supply = <&reg_usb1_vbus>;
+			pinctrl-0 = <&usbphy1_pins_a>;
+			pinctrl-names = "default";
+			status = "okay";
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+
+		reg_usb1_vbus: usb1_vbus {
+			compatible = "regulator-fixed";
+			regulator-name = "usb1_vbus";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio0 7 1>;
+		};
+	};
+
+	ahb@80080000 {
+		mac0: ethernet@800f0000 {
+			phy-mode = "rmii";
+			pinctrl-names = "default";
+			pinctrl-0 = <&mac0_pins_a>;
+			phy-reset-gpios = <&gpio2 21 0>;
+			phy-reset-duration = <100>;
+			status = "okay";
+		};
+	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 3 5000000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <7>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx28.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx28.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -32,8 +32,12 @@
 	};
 
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
@@ -330,6 +334,17 @@
 					fsl,pull-up = <0>;
 				};
 
+				auart2_2pins_b: auart2-2pins@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						0x3080 /* MX28_PAD_AUART2_RX__AUART2_RX */
+						0x3090 /* MX28_PAD_AUART2_TX__AUART2_TX */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
 				auart3_pins_a: auart3@0 {
 					reg = <0>;
 					fsl,pinmux-ids = <
@@ -354,6 +369,28 @@
 					fsl,pull-up = <0>;
 				};
 
+				auart3_2pins_b: auart3-2pins@1 {
+					reg = <1>;
+					fsl,pinmux-ids = <
+						0x30c0 /* MX28_PAD_AUART3_RX__AUART3_RX */
+						0x30d0 /* MX28_PAD_AUART3_TX__AUART3_TX */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
+				auart4_2pins_a: auart4@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x2181 /* MX28_PAD_SSP3_SCK__AUART4_TX */
+						0x2191 /* MX28_PAD_SSP3_MOSI__AUART4_RX */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
 				mac0_pins_a: mac0@0 {
 					reg = <0>;
 					fsl,pinmux-ids = <
@@ -669,7 +706,7 @@
 			};
 
 			digctl@8001c000 {
-				compatible = "fsl,imx28-digctl";
+				compatible = "fsl,imx28-digctl", "fsl,imx23-digctl";
 				reg = <0x8001c000 0x2000>;
 				interrupts = <89>;
 				status = "disabled";
@@ -699,7 +736,7 @@
 			dcp@80028000 {
 				reg = <0x80028000 0x2000>;
 				interrupts = <52 53 54>;
-				status = "disabled";
+				compatible = "fsl-dcp";
 			};
 
 			pxp@8002a000 {
@@ -800,6 +837,7 @@
 				compatible = "fsl,imx28-saif";
 				reg = <0x80042000 0x2000>;
 				interrupts = <59 80>;
+				#clock-cells = <0>;
 				clocks = <&clks 53>;
 				dmas = <&dma_apbx 4>;
 				dma-names = "rx-tx";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-evk.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-evk.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-evk.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-evk.dts	2013-08-25 20:43:22.000000000 -0400
@@ -155,12 +155,14 @@
 			can0: can@80032000 {
 				pinctrl-names = "default";
 				pinctrl-0 = <&can0_pins_a>;
+				xceiver-supply = <&reg_can_3v3>;
 				status = "okay";
 			};
 
 			can1: can@80034000 {
 				pinctrl-names = "default";
 				pinctrl-0 = <&can1_pins_a>;
+				xceiver-supply = <&reg_can_3v3>;
 				status = "okay";
 			};
 		};
@@ -193,7 +195,7 @@
 					reg = <0x0a>;
 					VDDA-supply = <&reg_3p3v>;
 					VDDIO-supply = <&reg_3p3v>;
-
+					clocks = <&saif0>;
 				};
 
 				at24@51 {
@@ -319,6 +321,16 @@
 			gpio = <&gpio3 30 0>;
 			enable-active-high;
 		};
+
+		reg_can_3v3: can-3v3 {
+			compatible = "regulator-fixed";
+			regulator-name = "can-3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio2 13 0>;
+			enable-active-high;
+		};
+
 	};
 
 	sound {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-m28evk.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-m28evk.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx28-m28evk.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx28-m28evk.dts	2013-08-25 20:43:22.000000000 -0400
@@ -184,7 +184,7 @@
 					reg = <0x0a>;
 					VDDA-supply = <&reg_3p3v>;
 					VDDIO-supply = <&reg_3p3v>;
-
+					clocks = <&saif0>;
 				};
 
 				eeprom: eeprom@51 {
@@ -220,7 +220,19 @@
 
 			auart0: serial@8006a000 {
 				pinctrl-names = "default";
-				pinctrl-0 = <&auart0_2pins_a>;
+				pinctrl-0 = <&auart0_pins_a>;
+				status = "okay";
+			};
+
+			auart1: serial@8006c000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&auart1_pins_a>;
+				status = "okay";
+			};
+
+			auart2: serial@8006e000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&auart2_2pins_b>;
 				status = "okay";
 			};
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx51-apf51.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx51-apf51.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx51-apf51.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx51-apf51.dts	2013-08-25 20:43:22.000000000 -0400
@@ -45,6 +45,13 @@
 	status = "okay";
 };
 
+&nfc {
+	nand-bus-width = <8>;
+	nand-ecc-mode = "hw";
+	nand-on-flash-bbt;
+	status = "okay";
+};
+
 &uart3 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart3_2>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx51-babbage.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx51-babbage.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx51-babbage.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx51-babbage.dts	2013-08-25 20:43:22.000000000 -0400
@@ -61,6 +61,16 @@
 		mux-int-port = <2>;
 		mux-ext-port = <3>;
 	};
+
+	clocks {
+		clk_26M: codec_clock {
+			compatible = "fixed-clock";
+			reg=<0>;
+			#clock-cells = <0>;
+			clock-frequency = <26000000>;
+			gpios = <&gpio4 26 1>;
+		};
+	};
 };
 
 &esdhc1 {
@@ -229,6 +239,7 @@
 				MX51_PAD_EIM_A27__GPIO2_21   0x5
 				MX51_PAD_CSPI1_SS0__GPIO4_24 0x85
 				MX51_PAD_CSPI1_SS1__GPIO4_25 0x85
+				MX51_PAD_CSPI1_RDY__GPIO4_26 0x80000000
 			>;
 		};
 	};
@@ -255,7 +266,7 @@
 	sgtl5000: codec@0a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
-		clock-frequency = <26000000>;
+		clocks = <&clk_26M>;
 		VDDA-supply = <&vdig_reg>;
 		VDDIO-supply = <&vvideo_reg>;
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx51.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx51.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx51.dtsi	2013-07-01 10:32:35.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx51.dtsi	2013-08-31 17:52:02.000000000 -0400
@@ -175,10 +175,20 @@
 				};
 			};
 
+			usbphy0: usbphy@0 {
+				compatible = "usb-nop-xceiv";
+				clocks = <&clks 124>;
+				clock-names = "main_clk";
+				status = "okay";
+			};
+
 			usbotg: usb@73f80000 {
 				compatible = "fsl,imx51-usb", "fsl,imx27-usb";
 				reg = <0x73f80000 0x0200>;
 				interrupts = <18>;
+				clocks = <&clks 108>;
+				fsl,usbmisc = <&usbmisc 0>;
+				fsl,usbphy = <&usbphy0>;
 				status = "disabled";
 			};
 
@@ -186,6 +196,8 @@
 				compatible = "fsl,imx51-usb", "fsl,imx27-usb";
 				reg = <0x73f80200 0x0200>;
 				interrupts = <14>;
+				clocks = <&clks 108>;
+				fsl,usbmisc = <&usbmisc 1>;
 				status = "disabled";
 			};
 
@@ -193,6 +205,8 @@
 				compatible = "fsl,imx51-usb", "fsl,imx27-usb";
 				reg = <0x73f80400 0x0200>;
 				interrupts = <16>;
+				clocks = <&clks 108>;
+				fsl,usbmisc = <&usbmisc 2>;
 				status = "disabled";
 			};
 
@@ -200,9 +214,18 @@
 				compatible = "fsl,imx51-usb", "fsl,imx27-usb";
 				reg = <0x73f80600 0x0200>;
 				interrupts = <17>;
+				clocks = <&clks 108>;
+				fsl,usbmisc = <&usbmisc 3>;
 				status = "disabled";
 			};
 
+			usbmisc: usbmisc@73f80800 {
+				#index-cells = <1>;
+				compatible = "fsl,imx51-usbmisc";
+				reg = <0x73f80800 0x200>;
+				clocks = <&clks 108>;
+			};
+
 			gpio1: gpio@73f84000 {
 				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f84000 0x4000>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx53.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx53.dtsi	2013-07-01 10:32:37.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53.dtsi	2013-08-31 17:52:04.000000000 -0400
@@ -27,6 +27,9 @@
 		gpio4 = &gpio5;
 		gpio5 = &gpio6;
 		gpio6 = &gpio7;
+		i2c0 = &i2c1;
+		i2c1 = &i2c2;
+		i2c2 = &i2c3;
 	};
 
 	tzic: tz-interrupt-controller@0fffc000 {
@@ -163,10 +166,27 @@
 				};
 			};
 
+			usbphy0: usbphy@0 {
+				compatible = "usb-nop-xceiv";
+				clocks = <&clks 124>;
+				clock-names = "main_clk";
+				status = "okay";
+			};
+
+			usbphy1: usbphy@1 {
+				compatible = "usb-nop-xceiv";
+				clocks = <&clks 125>;
+				clock-names = "main_clk";
+				status = "okay";
+			};
+
 			usbotg: usb@53f80000 {
 				compatible = "fsl,imx53-usb", "fsl,imx27-usb";
 				reg = <0x53f80000 0x0200>;
 				interrupts = <18>;
+				clocks = <&clks 108>;
+				fsl,usbmisc = <&usbmisc 0>;
+				fsl,usbphy = <&usbphy0>;
 				status = "disabled";
 			};
 
@@ -174,6 +194,9 @@
 				compatible = "fsl,imx53-usb", "fsl,imx27-usb";
 				reg = <0x53f80200 0x0200>;
 				interrupts = <14>;
+				clocks = <&clks 108>;
+				fsl,usbmisc = <&usbmisc 1>;
+				fsl,usbphy = <&usbphy1>;
 				status = "disabled";
 			};
 
@@ -181,6 +204,8 @@
 				compatible = "fsl,imx53-usb", "fsl,imx27-usb";
 				reg = <0x53f80400 0x0200>;
 				interrupts = <16>;
+				clocks = <&clks 108>;
+				fsl,usbmisc = <&usbmisc 2>;
 				status = "disabled";
 			};
 
@@ -188,9 +213,18 @@
 				compatible = "fsl,imx53-usb", "fsl,imx27-usb";
 				reg = <0x53f80600 0x0200>;
 				interrupts = <17>;
+				clocks = <&clks 108>;
+				fsl,usbmisc = <&usbmisc 3>;
 				status = "disabled";
 			};
 
+			usbmisc: usbmisc@53f80800 {
+				#index-cells = <1>;
+				compatible = "fsl,imx53-usbmisc";
+				reg = <0x53f80800 0x200>;
+				clocks = <&clks 108>;
+			};
+
 			gpio1: gpio@53f84000 {
 				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f84000 0x4000>;
@@ -267,6 +301,24 @@
 							MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD  0x80000000
 						>;
 					};
+
+					pinctrl_audmux_2: audmuxgrp-2 {
+						fsl,pins = <
+							MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC	0x80000000
+							MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD	0x80000000
+							MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS	0x80000000
+							MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD	0x80000000
+						>;
+					};
+
+					pinctrl_audmux_3: audmuxgrp-3 {
+						fsl,pins = <
+							MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC	0x80000000
+							MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD	0x80000000
+							MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS	0x80000000
+							MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD	0x80000000
+						>;
+					};
 				};
 
 				fec {
@@ -284,6 +336,29 @@
 							MX53_PAD_FEC_TXD0__FEC_TDATA_0   0x80000000
 						>;
 					};
+
+					pinctrl_fec_2: fecgrp-2 {
+						fsl,pins = <
+							MX53_PAD_FEC_MDC__FEC_MDC	 0x80000000
+							MX53_PAD_FEC_MDIO__FEC_MDIO	 0x80000000
+							MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
+							MX53_PAD_FEC_RX_ER__FEC_RX_ER    0x80000000
+							MX53_PAD_FEC_CRS_DV__FEC_RX_DV   0x80000000
+							MX53_PAD_FEC_RXD1__FEC_RDATA_1   0x80000000
+							MX53_PAD_FEC_RXD0__FEC_RDATA_0   0x80000000
+							MX53_PAD_FEC_TX_EN__FEC_TX_EN    0x80000000
+							MX53_PAD_FEC_TXD1__FEC_TDATA_1   0x80000000
+							MX53_PAD_FEC_TXD0__FEC_TDATA_0   0x80000000
+							MX53_PAD_KEY_ROW1__FEC_COL	 0x80000000
+							MX53_PAD_KEY_COL3__FEC_CRS	 0x80000000
+							MX53_PAD_KEY_COL2__FEC_RDATA_2	 0x80000000
+							MX53_PAD_KEY_COL0__FEC_RDATA_3	 0x80000000
+							MX53_PAD_KEY_COL1__FEC_RX_CLK	 0x80000000
+							MX53_PAD_KEY_ROW2__FEC_TDATA_2	 0x80000000
+							MX53_PAD_GPIO_19__FEC_TDATA_3	 0x80000000
+							MX53_PAD_KEY_ROW0__FEC_TX_ER	 0x80000000
+						>;
+					};
 				};
 
 				csi {
@@ -312,6 +387,22 @@
 							MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK   0x1d5
 						>;
 					};
+
+					pinctrl_csi_2: csigrp-2 {
+						fsl,pins = <
+							MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC	0x1d5
+							MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC	0x1d5
+							MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK	0x1d5
+							MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19	0x1d5
+							MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18	0x1d5
+							MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17	0x1d5
+							MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16	0x1d5
+							MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15	0x1d5
+							MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14	0x1d5
+							MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13	0x1d5
+							MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12	0x1d5
+						>;
+					};
 				};
 
 				cspi {
@@ -322,6 +413,14 @@
 							MX53_PAD_SD1_CLK__CSPI_SCLK   0x1d5
 						>;
 					};
+
+					pinctrl_cspi_2: cspigrp-2 {
+						fsl,pins = <
+							MX53_PAD_EIM_D22__CSPI_MISO 0x1d5
+							MX53_PAD_EIM_D28__CSPI_MOSI 0x1d5
+							MX53_PAD_EIM_D21__CSPI_SCLK 0x1d5
+						>;
+					};
 				};
 
 				ecspi1 {
@@ -332,6 +431,27 @@
 							MX53_PAD_EIM_D18__ECSPI1_MOSI 0x80000000
 						>;
 					};
+
+					pinctrl_ecspi1_2: ecspi1grp-2 {
+						fsl,pins = <
+							MX53_PAD_GPIO_19__ECSPI1_RDY	0x80000000
+							MX53_PAD_EIM_EB2__ECSPI1_SS0	0x80000000
+							MX53_PAD_EIM_D16__ECSPI1_SCLK	0x80000000
+							MX53_PAD_EIM_D17__ECSPI1_MISO	0x80000000
+							MX53_PAD_EIM_D18__ECSPI1_MOSI	0x80000000
+							MX53_PAD_EIM_D19__ECSPI1_SS1	0x80000000
+						>;
+					};
+				};
+
+				ecspi2 {
+					pinctrl_ecspi2_1: ecspi2grp-1 {
+						fsl,pins = <
+							MX53_PAD_EIM_OE__ECSPI2_MISO  0x80000000
+							MX53_PAD_EIM_CS1__ECSPI2_MOSI 0x80000000
+							MX53_PAD_EIM_CS0__ECSPI2_SCLK 0x80000000
+						>;
+					};
 				};
 
 				esdhc1 {
@@ -406,6 +526,13 @@
 							MX53_PAD_KEY_ROW2__CAN1_RXCAN 0x80000000
 						>;
 					};
+
+					pinctrl_can1_3: can1grp-3 {
+						fsl,pins = <
+							MX53_PAD_GPIO_7__CAN1_TXCAN	0x80000000
+							MX53_PAD_GPIO_8__CAN1_RXCAN	0x80000000
+						>;
+					};
 				};
 
 				can2 {
@@ -424,6 +551,13 @@
 							MX53_PAD_CSI0_DAT9__I2C1_SCL 0xc0000000
 						>;
 					};
+
+					pinctrl_i2c1_2: i2c1grp-2 {
+						fsl,pins = <
+							MX53_PAD_EIM_D21__I2C1_SCL	0xc0000000
+							MX53_PAD_EIM_D28__I2C1_SDA	0xc0000000
+						>;
+					};
 				};
 
 				i2c2 {
@@ -433,6 +567,13 @@
 							MX53_PAD_KEY_COL3__I2C2_SCL 0xc0000000
 						>;
 					};
+
+					pinctrl_i2c2_2: i2c2grp-2 {
+						fsl,pins = <
+							MX53_PAD_EIM_D16__I2C2_SDA	0xc0000000
+							MX53_PAD_EIM_EB2__I2C2_SCL	0xc0000000
+						>;
+					};
 				};
 
 				i2c3 {
@@ -444,6 +585,119 @@
 					};
 				};
 
+				ipu_disp0 {
+					pinctrl_ipu_disp0_1: ipudisp0grp-1 {
+						fsl,pins = <
+						MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK	0x5
+						MX53_PAD_DI0_PIN15__IPU_DI0_PIN15		0x5
+						MX53_PAD_DI0_PIN2__IPU_DI0_PIN2		0x5
+						MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 		0x5
+						MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0		0x5
+						MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1		0x5
+						MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2		0x5
+						MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3		0x5
+						MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4		0x5
+						MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5		0x5
+						MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6		0x5
+						MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7		0x5
+						MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8		0x5
+						MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9		0x5
+						MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10		0x5
+						MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11		0x5
+						MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12		0x5
+						MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13		0x5
+						MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14		0x5
+						MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15		0x5
+						MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16		0x5
+						MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17		0x5
+						MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18		0x5
+						MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19		0x5
+						MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20		0x5
+						MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21		0x5
+						MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22		0x5
+						MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23		0x5
+						>;
+					};
+				};
+
+				ipu_disp1 {
+					pinctrl_ipu_disp1_1: ipudisp1grp-1 {
+						fsl,pins = <
+							MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0	0x5
+							MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1	0x5
+							MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2	0x5
+							MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3	0x5
+							MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4	0x5
+							MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5	0x5
+							MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6	0x5
+							MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7	0x5
+							MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8	0x5
+							MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9	0x5
+							MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10	0x5
+							MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11	0x5
+							MX53_PAD_EIM_A17__IPU_DISP1_DAT_12	0x5
+							MX53_PAD_EIM_A18__IPU_DISP1_DAT_13	0x5
+							MX53_PAD_EIM_A19__IPU_DISP1_DAT_14	0x5
+							MX53_PAD_EIM_A20__IPU_DISP1_DAT_15	0x5
+							MX53_PAD_EIM_A21__IPU_DISP1_DAT_16	0x5
+							MX53_PAD_EIM_A22__IPU_DISP1_DAT_17	0x5
+							MX53_PAD_EIM_A23__IPU_DISP1_DAT_18	0x5
+							MX53_PAD_EIM_A24__IPU_DISP1_DAT_19	0x5
+							MX53_PAD_EIM_D31__IPU_DISP1_DAT_20	0x5
+							MX53_PAD_EIM_D30__IPU_DISP1_DAT_21	0x5
+							MX53_PAD_EIM_D26__IPU_DISP1_DAT_22	0x5
+							MX53_PAD_EIM_D27__IPU_DISP1_DAT_23	0x5
+							MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK	0x5
+							MX53_PAD_EIM_DA13__IPU_DI1_D0_CS	0x5
+							MX53_PAD_EIM_DA14__IPU_DI1_D1_CS	0x5
+							MX53_PAD_EIM_DA15__IPU_DI1_PIN1		0x5
+							MX53_PAD_EIM_DA11__IPU_DI1_PIN2		0x5
+							MX53_PAD_EIM_DA12__IPU_DI1_PIN3		0x5
+							MX53_PAD_EIM_A25__IPU_DI1_PIN12		0x5
+							MX53_PAD_EIM_DA10__IPU_DI1_PIN15	0x5
+						>;
+					};
+				};
+
+				ipu_disp2 {
+					pinctrl_ipu_disp2_1: ipudisp2grp-1 {
+						fsl,pins = <
+							MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0	0x80000000
+							MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1	0x80000000
+							MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2	0x80000000
+							MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3	0x80000000
+							MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK	0x80000000
+							MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0	0x80000000
+							MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1	0x80000000
+							MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2	0x80000000
+							MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3	0x80000000
+							MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK	0x80000000
+						>;
+					};
+				};
+
+				nand {
+					pinctrl_nand_1: nandgrp-1 {
+						fsl,pins = <
+							MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B	0x4
+							MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B	0x4
+							MX53_PAD_NANDF_CLE__EMI_NANDF_CLE	0x4
+							MX53_PAD_NANDF_ALE__EMI_NANDF_ALE	0x4
+							MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B	0xe0
+							MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0	0xe0
+							MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0	0x4
+							MX53_PAD_PATA_DATA0__EMI_NANDF_D_0	0xa4
+							MX53_PAD_PATA_DATA1__EMI_NANDF_D_1	0xa4
+							MX53_PAD_PATA_DATA2__EMI_NANDF_D_2	0xa4
+							MX53_PAD_PATA_DATA3__EMI_NANDF_D_3	0xa4
+							MX53_PAD_PATA_DATA4__EMI_NANDF_D_4	0xa4
+							MX53_PAD_PATA_DATA5__EMI_NANDF_D_5	0xa4
+							MX53_PAD_PATA_DATA6__EMI_NANDF_D_6	0xa4
+							MX53_PAD_PATA_DATA7__EMI_NANDF_D_7	0xa4
+						>;
+					};
+				};
+
 				owire {
 					pinctrl_owire_1: owiregrp-1 {
 						fsl,pins = <
@@ -452,18 +706,41 @@
 					};
 				};
 
+				pwm1 {
+					pinctrl_pwm1_1: pwm1grp-1 {
+						fsl,pins = <
+							MX53_PAD_DISP0_DAT8__PWM1_PWMO	0x5
+						>;
+					};
+				};
+
+				pwm2 {
+					pinctrl_pwm2_1: pwm2grp-1 {
+						fsl,pins = <
+							MX53_PAD_GPIO_1__PWM2_PWMO	0x80000000
+						>;
+					};
+				};
+
 				uart1 {
 					pinctrl_uart1_1: uart1grp-1 {
 						fsl,pins = <
-							MX53_PAD_CSI0_DAT10__UART1_TXD_MUX 0x1c5
-							MX53_PAD_CSI0_DAT11__UART1_RXD_MUX 0x1c5
+							MX53_PAD_CSI0_DAT10__UART1_TXD_MUX 0x1e4
+							MX53_PAD_CSI0_DAT11__UART1_RXD_MUX 0x1e4
 						>;
 					};
 
 					pinctrl_uart1_2: uart1grp-2 {
 						fsl,pins = <
-							MX53_PAD_PATA_DIOW__UART1_TXD_MUX  0x1c5
-							MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1c5
+							MX53_PAD_PATA_DIOW__UART1_TXD_MUX  0x1e4
+							MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1e4
+						>;
+					};
+
+					pinctrl_uart1_3: uart1grp-3 {
+						fsl,pins = <
+							MX53_PAD_PATA_RESET_B__UART1_CTS 0x1c5
+							MX53_PAD_PATA_IORDY__UART1_RTS	 0x1c5
 						>;
 					};
 				};
@@ -471,8 +748,17 @@
 				uart2 {
 					pinctrl_uart2_1: uart2grp-1 {
 						fsl,pins = <
-							MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x1c5
-							MX53_PAD_PATA_DMARQ__UART2_TXD_MUX     0x1c5
+							MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX 0x1e4
+							MX53_PAD_PATA_DMARQ__UART2_TXD_MUX     0x1e4
+						>;
+					};
+
+					pinctrl_uart2_2: uart2grp-2 {
+						fsl,pins = <
+							MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX	0x1c5
+							MX53_PAD_PATA_DMARQ__UART2_TXD_MUX	0x1c5
+							MX53_PAD_PATA_DIOR__UART2_RTS		0x1c5
+							MX53_PAD_PATA_INTRQ__UART2_CTS		0x1c5
 						>;
 					};
 				};
@@ -480,17 +766,17 @@
 				uart3 {
 					pinctrl_uart3_1: uart3grp-1 {
 						fsl,pins = <
-							MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1c5
-							MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1c5
-							MX53_PAD_PATA_DA_1__UART3_CTS	  0x1c5
-							MX53_PAD_PATA_DA_2__UART3_RTS	  0x1c5
+							MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
+							MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
+							MX53_PAD_PATA_DA_1__UART3_CTS	  0x1e4
+							MX53_PAD_PATA_DA_2__UART3_RTS	  0x1e4
 						>;
 					};
 
 					pinctrl_uart3_2: uart3grp-2 {
 						fsl,pins = <
-							MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1c5
-							MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1c5
+							MX53_PAD_PATA_CS_0__UART3_TXD_MUX 0x1e4
+							MX53_PAD_PATA_CS_1__UART3_RXD_MUX 0x1e4
 						>;
 					};
 
@@ -499,8 +785,8 @@
 				uart4 {
 					pinctrl_uart4_1: uart4grp-1 {
 						fsl,pins = <
-							MX53_PAD_KEY_COL0__UART4_TXD_MUX 0x1c5
-							MX53_PAD_KEY_ROW0__UART4_RXD_MUX 0x1c5
+							MX53_PAD_KEY_COL0__UART4_TXD_MUX 0x1e4
+							MX53_PAD_KEY_ROW0__UART4_RXD_MUX 0x1e4
 						>;
 					};
 				};
@@ -508,12 +794,11 @@
 				uart5 {
 					pinctrl_uart5_1: uart5grp-1 {
 						fsl,pins = <
-							MX53_PAD_KEY_COL1__UART5_TXD_MUX 0x1c5
-							MX53_PAD_KEY_ROW1__UART5_RXD_MUX 0x1c5
+							MX53_PAD_KEY_COL1__UART5_TXD_MUX 0x1e4
+							MX53_PAD_KEY_ROW1__UART5_RXD_MUX 0x1e4
 						>;
 					};
 				};
-
 			};
 
 			gpr: iomuxc-gpr@53fa8000 {
@@ -781,6 +1066,16 @@
 				clock-names = "ipg", "ahb", "ptp";
 				status = "disabled";
 			};
+
+			tve: tve@63ff0000 {
+				compatible = "fsl,imx53-tve";
+				reg = <0x63ff0000 0x1000>;
+				interrupts = <92>;
+				clocks = <&clks 69>, <&clks 116>;
+				clock-names = "tve", "di_sel";
+				crtcs = <&ipu 1>;
+				status = "disabled";
+			};
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-m53evk.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-m53evk.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-m53evk.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-m53evk.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2013 Marek Vasut <marex@denx.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx53.dtsi"
+
+/ {
+	model = "DENX M53EVK";
+	compatible = "denx,imx53-m53evk", "fsl,imx53";
+
+	memory {
+		reg = <0x70000000 0x20000000>;
+	};
+
+	soc {
+		display@di1 {
+			compatible = "fsl,imx-parallel-display";
+			crtcs = <&ipu 1>;
+			interface-pix-fmt = "bgr666";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_ipu_disp2_1>;
+
+			display-timings {
+				800x480p60 {
+					native-mode;
+					clock-frequency = <31500000>;
+					hactive = <800>;
+					vactive = <480>;
+					hfront-porch = <40>;
+					hback-porch = <88>;
+					hsync-len = <128>;
+					vback-porch = <33>;
+					vfront-porch = <9>;
+					vsync-len = <3>;
+					vsync-active = <1>;
+				};
+			};
+		};
+	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 3000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pin_gpio>;
+
+		user1 {
+			label = "user1";
+			gpios = <&gpio2 8 0>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		user2 {
+			label = "user2";
+			gpios = <&gpio2 9 0>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+
+		reg_3p2v: 3p2v {
+			compatible = "regulator-fixed";
+			regulator-name = "3P2V";
+			regulator-min-microvolt = <3200000>;
+			regulator-max-microvolt = <3200000>;
+			regulator-always-on;
+		};
+	};
+
+	sound {
+		compatible = "fsl,imx53-m53evk-sgtl5000",
+			     "fsl,imx-audio-sgtl5000";
+		model = "imx53-m53evk-sgtl5000";
+		ssi-controller = <&ssi2>;
+		audio-codec = <&sgtl5000>;
+		audio-routing =
+			"MIC_IN", "Mic Jack",
+			"Mic Jack", "Mic Bias",
+			"LINE_IN", "Line In Jack",
+			"Headphone Jack", "HP_OUT",
+			"Ext Spk", "LINE_OUT";
+		mux-int-port = <2>;
+		mux-ext-port = <4>;
+	};
+};
+
+&audmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux_2>;
+	status = "okay";
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can1_3>;
+	status = "okay";
+};
+
+&can2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can2_1>;
+	status = "okay";
+};
+
+&esdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_esdhc1_1>;
+	cd-gpios = <&gpio1 1 0>;
+	wp-gpios = <&gpio1 9 0>;
+	status = "okay";
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec_1>;
+	phy-mode = "rmii";
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1_2>;
+	status = "okay";
+
+	sgtl5000: codec@0a {
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		VDDA-supply = <&reg_3p2v>;
+		VDDIO-supply = <&reg_3p2v>;
+		clocks = <&clks 150>;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2_2>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	stmpe610@41 {
+		compatible = "st,stmpe610";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x41>;
+		id = <0>;
+		blocks = <0x5>;
+		interrupts = <6 0x0>;
+		interrupt-parent = <&gpio7>;
+		irq-trigger = <0x1>;
+
+		stmpe_touchscreen {
+			compatible = "stmpe,ts";
+			reg = <0>;
+			ts,sample-time = <4>;
+			ts,mod-12b = <1>;
+			ts,ref-sel = <0>;
+			ts,adc-freq = <1>;
+			ts,ave-ctrl = <3>;
+			ts,touch-det-delay = <3>;
+			ts,settling = <4>;
+			ts,fraction-z = <7>;
+			ts,i-drive = <1>;
+		};
+	};
+
+	eeprom: eeprom@50 {
+		compatible = "atmel,24c128";
+		reg = <0x50>;
+		pagesize = <32>;
+	};
+
+	rtc: rtc@68 {
+		compatible = "stm,m41t62";
+		reg = <0x68>;
+	};
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3_1>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
+	hog {
+		pinctrl_hog: hoggrp {
+			fsl,pins = <
+				MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK	0x80000000
+				MX53_PAD_EIM_EB3__GPIO2_31		0x80000000
+				MX53_PAD_PATA_DA_0__GPIO7_6		0x80000000
+				MX53_PAD_DISP0_DAT8__PWM1_PWMO		0x5
+
+			>;
+		};
+
+		led_pin_gpio: led_gpio@0 {
+			fsl,pins = <
+				MX53_PAD_PATA_DATA8__GPIO2_8		0x80000000
+				MX53_PAD_PATA_DATA9__GPIO2_9		0x80000000
+			>;
+		};
+	};
+};
+
+&nfc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nand_1>;
+	nand-bus-width = <8>;
+	nand-ecc-mode = "hw";
+	status = "okay";
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1_1>;
+	status = "okay";
+};
+
+&ssi2 {
+	fsl,mode = "i2s-slave";
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1_2>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2_1>;
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3_1>;
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-mba53.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-mba53.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-mba53.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-mba53.dts	2013-08-25 20:43:22.000000000 -0400
@@ -16,27 +16,81 @@
 / {
 	model = "TQ MBa53 starter kit";
 	compatible = "tq,mba53", "tq,tqma53", "fsl,imx53";
+
+	reg_backlight: fixed@0 {
+		compatible = "regulator-fixed";
+		regulator-name = "lcd-supply";
+		gpio = <&gpio2 5 0>;
+		startup-delay-us = <5000>;
+		enable-active-low;
+	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm2 0 50000>;
+		brightness-levels = <0 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100>;
+		default-brightness-level = <10>;
+		enable-gpios = <&gpio7 7 0>;
+		power-supply = <&reg_backlight>;
+	};
+
+	disp1: display@disp1 {
+		compatible = "fsl,imx-parallel-display";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_disp1_1>;
+		crtcs = <&ipu 1>;
+		interface-pix-fmt = "rgb24";
+		status = "disabled";
+	};
+
+	reg_3p2v: 3p2v {
+		compatible = "regulator-fixed";
+		regulator-name = "3P2V";
+		regulator-min-microvolt = <3200000>;
+		regulator-max-microvolt = <3200000>;
+		regulator-always-on;
+	};
+
+	sound {
+		compatible = "tq,imx53-mba53-sgtl5000",
+			     "fsl,imx-audio-sgtl5000";
+		model = "imx53-mba53-sgtl5000";
+		ssi-controller = <&ssi2>;
+		audio-codec = <&codec>;
+		audio-routing =
+			"MIC_IN", "Mic Jack",
+			"Mic Jack", "Mic Bias",
+			"Headphone Jack", "HP_OUT";
+		mux-int-port = <2>;
+		mux-ext-port = <5>;
+	};
+};
+
+&ldb {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lvds1_1>;
+	status = "disabled";
 };
 
 &iomuxc {
 	lvds1 {
 		pinctrl_lvds1_1: lvds1-grp1 {
 			fsl,pins = <
-				MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 0x10000
-				MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 0x10000
-				MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 0x10000
-				MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 0x10000
-				MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 0x10000
+				MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 0x80000000
+				MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 0x80000000
+				MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 0x80000000
+				MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 0x80000000
+				MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 0x80000000
 			>;
 		};
 
 		pinctrl_lvds1_2: lvds1-grp2 {
 			fsl,pins = <
-				MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 0x10000
-				MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 0x10000
-				MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK 0x10000
-				MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 0x10000
-				MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 0x10000
+				MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 0x80000000
+				MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 0x80000000
+				MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK 0x80000000
+				MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 0x80000000
+				MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 0x80000000
 			>;
 		};
 	};
@@ -44,33 +98,44 @@
 	disp1 {
 		pinctrl_disp1_1: disp1-grp1 {
 			fsl,pins = <
-				MX53_PAD_EIM_DA10__IPU_DI1_PIN15   0x10000 /* DISP1_DRDY */
-				MX53_PAD_EIM_D23__IPU_DI1_PIN2     0x10000 /* DISP1_HSYNC */
-				MX53_PAD_EIM_EB3__IPU_DI1_PIN3     0x10000 /* DISP1_VSYNC */
-				MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 0x10000
-				MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 0x10000
-				MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 0x10000
-				MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 0x10000
-				MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 0x10000
-				MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 0x10000
-				MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 0x10000
-				MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 0x10000
-				MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 0x10000
-				MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 0x10000
-				MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 0x10000
-				MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 0x10000
-				MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 0x10000
-				MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 0x10000
-				MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9  0x10000
-				MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8  0x10000
-				MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7  0x10000
-				MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6  0x10000
-				MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5  0x10000
-				MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4  0x10000
-				MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3  0x10000
-				MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2  0x10000
-				MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1  0x10000
-				MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0  0x10000
+				MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK 0x80000000 /* DISP1_CLK */
+				MX53_PAD_EIM_DA10__IPU_DI1_PIN15   0x80000000 /* DISP1_DRDY */
+				MX53_PAD_EIM_D23__IPU_DI1_PIN2     0x80000000 /* DISP1_HSYNC */
+				MX53_PAD_EIM_EB3__IPU_DI1_PIN3     0x80000000 /* DISP1_VSYNC */
+				MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 0x80000000
+				MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 0x80000000
+				MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 0x80000000
+				MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 0x80000000
+				MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 0x80000000
+				MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 0x80000000
+				MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 0x80000000
+				MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 0x80000000
+				MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 0x80000000
+				MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 0x80000000
+				MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 0x80000000
+				MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 0x80000000
+				MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 0x80000000
+				MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 0x80000000
+				MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9  0x80000000
+				MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8  0x80000000
+				MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7  0x80000000
+				MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6  0x80000000
+				MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5  0x80000000
+				MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4  0x80000000
+				MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3  0x80000000
+				MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2  0x80000000
+				MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1  0x80000000
+				MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0  0x80000000
+			>;
+		};
+	};
+
+	tve {
+		pinctrl_vga_sync_1: vgasync-grp1 {
+			fsl,pins = <
+				/* VGA_VSYNC, HSYNC with max drive strength */
+				MX53_PAD_EIM_CS1__IPU_DI1_PIN6	   0xe6
+				MX53_PAD_EIM_DA15__IPU_DI1_PIN4	   0xe6
 			>;
 		};
 	};
@@ -80,16 +145,27 @@
 	status = "okay";
 };
 
+&audmux {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux_1>;
+};
+
 &i2c2 {
 	codec: sgtl5000@a {
 		compatible = "fsl,sgtl5000";
 		reg = <0x0a>;
+		clocks = <&clks 150>;
+		VDDA-supply = <&reg_3p2v>;
+		VDDIO-supply = <&reg_3p2v>;
 	};
 
 	expander: pca9554@20 {
 		compatible = "pca9554";
 		reg = <0x20>;
 		interrupts = <109>;
+		#gpio-cells = <2>;
+		gpio-controller;
 	};
 
 	sensor2: lm75@49 {
@@ -99,6 +175,7 @@
 };
 
 &fec {
+	phy-reset-gpios = <&gpio7 6 0>;
 	status = "okay";
 };
 
@@ -114,10 +191,24 @@
 	status = "okay";
 };
 
+&usbotg {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbh1 {
+	status = "okay";
+};
+
 &uart1 {
 	status = "okay";
 };
 
+&ssi2 {
+	fsl,mode = "i2s-slave";
+	status = "okay";
+};
+
 &uart2 {
 	status = "okay";
 };
@@ -133,3 +224,13 @@
 &i2c3 {
 	status = "okay";
 };
+
+&tve {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_vga_sync_1>;
+	ddc = <&i2c3>;
+	fsl,tve-mode = "vga";
+	fsl,hsync-pin = <4>;
+	fsl,vsync-pin = <6>;
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-qsb.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-qsb.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-qsb.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-qsb.dts	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,33 @@
 		reg = <0x70000000 0x40000000>;
 	};
 
+	display@di0 {
+		compatible = "fsl,imx-parallel-display";
+		crtcs = <&ipu 0>;
+		interface-pix-fmt = "rgb565";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu_disp0_1>;
+		status = "disabled";
+		display-timings {
+			claawvga {
+				native-mode;
+				clock-frequency = <27000000>;
+				hactive = <800>;
+				vactive = <480>;
+				hback-porch = <40>;
+				hfront-porch = <60>;
+				vback-porch = <10>;
+				vfront-porch = <10>;
+				hsync-len = <20>;
+				vsync-len = <10>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				de-active = <1>;
+				pixelclk-active = <0>;
+			};
+		};
+	};
+
 	gpio-keys {
 		compatible = "gpio-keys";
 
@@ -147,6 +174,7 @@
 		reg = <0x0a>;
 		VDDA-supply = <&reg_3p2v>;
 		VDDIO-supply = <&reg_3p2v>;
+		clocks = <&clks 150>;
 	};
 };
 
@@ -268,3 +296,11 @@
 	phy-reset-gpios = <&gpio7 6 0>;
 	status = "okay";
 };
+
+&usbh1 {
+       status = "okay";
+};
+
+&usbotg {
+       status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-tqma53.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-tqma53.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-tqma53.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-tqma53.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -35,7 +35,9 @@
 
 &esdhc2 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_esdhc2_1>;
+	pinctrl-0 = <&pinctrl_esdhc2_1>,
+		    <&pinctrl_tqma53_esdhc2_2>;
+	vmmc-supply = <&reg_3p3v>;
 	wp-gpios = <&gpio1 2 0>;
 	cd-gpios = <&gpio1 4 0>;
 	status = "disabled";
@@ -69,14 +71,22 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_hog>;
 
+	esdhc2_2 {
+		pinctrl_tqma53_esdhc2_2: esdhc2-tqma53-grp2 {
+			fsl,pins = <
+				MX53_PAD_GPIO_4__GPIO1_4	0x80000000 /* SD2_CD */
+				MX53_PAD_GPIO_2__GPIO1_2	0x80000000 /* SD2_WP */
+			>;
+		};
+	};
+
 	i2s {
 		pinctrl_i2s_1: i2s-grp1 {
 			fsl,pins = <
-				 MX53_PAD_GPIO_19__GPIO4_5           0x10000 /* I2S_MCLK */
-				 MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC  0x10000 /* I2S_SCLK */
-				 MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD  0x10000 /* I2S_DOUT */
-				 MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x10000 /* I2S_LRCLK */
-				 MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD  0x10000 /* I2S_DIN */
+				 MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC  0x80000000 /* I2S_SCLK */
+				 MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD  0x80000000 /* I2S_DOUT */
+				 MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000 /* I2S_LRCLK */
+				 MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD  0x80000000 /* I2S_DIN */
 			>;
 		};
 	};
@@ -84,16 +94,17 @@
 	hog {
 		pinctrl_hog: hoggrp {
 			fsl,pins = <
-				 MX53_PAD_EIM_CS1__IPU_DI1_PIN6  0x10000 /* VSYNC */
-				 MX53_PAD_EIM_DA15__IPU_DI1_PIN4 0x10000 /* HSYNC */
-				 MX53_PAD_PATA_DA_1__GPIO7_7     0x10000 /* LCD_BLT_EN */
-				 MX53_PAD_PATA_DA_2__GPIO7_8     0x10000 /* LCD_RESET */
-				 MX53_PAD_PATA_DATA5__GPIO2_5    0x10000 /* LCD_POWER */
-				 MX53_PAD_PATA_DATA6__GPIO2_6    0x10000 /* PMIC_INT */
-				 MX53_PAD_PATA_DATA14__GPIO2_14  0x10000 /* CSI_RST */
-				 MX53_PAD_PATA_DATA15__GPIO2_15  0x10000 /* CSI_PWDN */
-				 MX53_PAD_GPIO_0__GPIO1_0        0x10000 /* SYSTEM_DOWN */
-				 MX53_PAD_GPIO_3__GPIO1_3        0x10000
+				 MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000 /* SSI_MCLK */
+				 MX53_PAD_PATA_DA_1__GPIO7_7     0x80000000 /* LCD_BLT_EN */
+				 MX53_PAD_PATA_DA_2__GPIO7_8     0x80000000 /* LCD_RESET */
+				 MX53_PAD_PATA_DATA5__GPIO2_5    0x80000000 /* LCD_POWER */
+				 MX53_PAD_PATA_DATA6__GPIO2_6    0x80000000 /* PMIC_INT */
+				 MX53_PAD_PATA_DATA14__GPIO2_14  0x80000000 /* CSI_RST */
+				 MX53_PAD_PATA_DATA15__GPIO2_15  0x80000000 /* CSI_PWDN */
+				 MX53_PAD_GPIO_19__GPIO4_5 	 0x80000000 /* #SYSTEM_DOWN */
+				 MX53_PAD_GPIO_3__GPIO1_3        0x80000000
+				 MX53_PAD_PATA_DA_0__GPIO7_6	 0x80000000 /* #PHY_RESET */
+				 MX53_PAD_GPIO_1__PWM2_PWMO	 0x80000000 /* LCD_CONTRAST */
 			>;
 		};
 	};
@@ -149,7 +160,7 @@
 		reg = <0x8>;
 		fsl,mc13xxx-uses-rtc;
 		interrupt-parent = <&gpio2>;
-		interrupts = <6 8>; /* PDATA_DATA6, low active */
+		interrupts = <6 4>; /* PATA_DATA6, active high */
 	};
 
 	sensor1: lm75@48 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-tx53.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-tx53.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx53-tx53.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx53-tx53.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "imx53.dtsi"
+
+/ {
+	model = "Ka-Ro TX53";
+	compatible = "karo,tx53", "fsl,imx53";
+
+	memory {
+		reg = <0x70000000 0x40000000>; /* Up to 1GiB */
+	};
+
+	regulators {
+		compatible = "simple-bus";
+
+		reg_3p3v: 3p3v {
+			compatible = "regulator-fixed";
+			regulator-name = "3P3V";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+	};
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can1_2>;
+	status = "disabled";
+};
+
+&can2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can2_1>;
+	status = "disabled";
+};
+
+&ecspi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1_2>;
+	status = "disabled";
+};
+
+&esdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_esdhc1_2>;
+	status = "disabled";
+};
+
+&esdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_esdhc2_1>;
+	status = "disabled";
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec_1>;
+	phy-mode = "rmii";
+	status = "disabled";
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3_2>;
+	status = "disabled";
+};
+
+&owire {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_owire_1>;
+	status = "disabled";
+};
+
+&pwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm2_1>;
+	status = "disabled";
+};
+
+&ssi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux_1>;
+	status = "disabled";
+};
+
+&ssi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux_2>;
+	status = "disabled";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1_2>,
+		    <&pinctrl_uart1_3>;
+	fsl,uart-has-rtscts;
+	status = "disabled";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2_2>;
+	fsl,uart-has-rtscts;
+	status = "disabled";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3_1>;
+	fsl,uart-has-rtscts;
+	status = "disabled";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6dl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6dl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6dl.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6dl.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -18,12 +18,14 @@
 
 		cpu@0 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			reg = <0>;
 			next-level-cache = <&L2>;
 		};
 
 		cpu@1 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			reg = <1>;
 			next-level-cache = <&L2>;
 		};
@@ -35,6 +37,27 @@
 				compatible = "fsl,imx6dl-iomuxc";
 				reg = <0x020e0000 0x4000>;
 
+				audmux {
+					pinctrl_audmux_2: audmux-2 {
+						fsl,pins = <
+							MX6DL_PAD_CSI0_DAT7__AUD3_RXD  0x80000000
+							MX6DL_PAD_CSI0_DAT4__AUD3_TXC  0x80000000
+							MX6DL_PAD_CSI0_DAT5__AUD3_TXD  0x80000000
+							MX6DL_PAD_CSI0_DAT6__AUD3_TXFS 0x80000000
+						>;
+					};
+				};
+
+				ecspi1 {
+					pinctrl_ecspi1_1: ecspi1grp-1 {
+						fsl,pins = <
+							MX6DL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+							MX6DL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+							MX6DL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+						>;
+					};
+				};
+
 				enet {
 					pinctrl_enet_1: enetgrp-1 {
 						fsl,pins = <
@@ -78,6 +101,39 @@
 					};
 				};
 
+				gpmi-nand {
+					pinctrl_gpmi_nand_1: gpmi-nand-1 {
+						fsl,pins = <
+							MX6DL_PAD_NANDF_CLE__NAND_CLE     0xb0b1
+							MX6DL_PAD_NANDF_ALE__NAND_ALE     0xb0b1
+							MX6DL_PAD_NANDF_WP_B__NAND_WP_B   0xb0b1
+							MX6DL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+							MX6DL_PAD_NANDF_CS0__NAND_CE0_B   0xb0b1
+							MX6DL_PAD_NANDF_CS1__NAND_CE1_B   0xb0b1
+							MX6DL_PAD_SD4_CMD__NAND_RE_B      0xb0b1
+							MX6DL_PAD_SD4_CLK__NAND_WE_B      0xb0b1
+							MX6DL_PAD_NANDF_D0__NAND_DATA00   0xb0b1
+							MX6DL_PAD_NANDF_D1__NAND_DATA01   0xb0b1
+							MX6DL_PAD_NANDF_D2__NAND_DATA02   0xb0b1
+							MX6DL_PAD_NANDF_D3__NAND_DATA03   0xb0b1
+							MX6DL_PAD_NANDF_D4__NAND_DATA04   0xb0b1
+							MX6DL_PAD_NANDF_D5__NAND_DATA05   0xb0b1
+							MX6DL_PAD_NANDF_D6__NAND_DATA06   0xb0b1
+							MX6DL_PAD_NANDF_D7__NAND_DATA07   0xb0b1
+							MX6DL_PAD_SD4_DAT0__NAND_DQS      0x00b1
+						>;
+					};
+				};
+
+				i2c1 {
+					pinctrl_i2c1_2: i2c1grp-2 {
+						fsl,pins = <
+							MX6DL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+							MX6DL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+						>;
+					};
+				};
+
 				uart1 {
 					pinctrl_uart1_1: uart1grp-1 {
 						fsl,pins = <
@@ -149,6 +205,64 @@
 					};
 				};
 
+				weim {
+					pinctrl_weim_cs0_1: weim_cs0grp-1 {
+						fsl,pins = <
+							MX6DL_PAD_EIM_CS0__EIM_CS0_B   0xb0b1
+						>;
+					};
+
+					pinctrl_weim_nor_1: weim_norgrp-1 {
+						fsl,pins = <
+							MX6DL_PAD_EIM_OE__EIM_OE_B     0xb0b1
+							MX6DL_PAD_EIM_RW__EIM_RW       0xb0b1
+							MX6DL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
+							/* data */
+							MX6DL_PAD_EIM_D16__EIM_DATA16 0x1b0b0
+							MX6DL_PAD_EIM_D17__EIM_DATA17 0x1b0b0
+							MX6DL_PAD_EIM_D18__EIM_DATA18 0x1b0b0
+							MX6DL_PAD_EIM_D19__EIM_DATA19 0x1b0b0
+							MX6DL_PAD_EIM_D20__EIM_DATA20 0x1b0b0
+							MX6DL_PAD_EIM_D21__EIM_DATA21 0x1b0b0
+							MX6DL_PAD_EIM_D22__EIM_DATA22 0x1b0b0
+							MX6DL_PAD_EIM_D23__EIM_DATA23 0x1b0b0
+							MX6DL_PAD_EIM_D24__EIM_DATA24 0x1b0b0
+							MX6DL_PAD_EIM_D25__EIM_DATA25 0x1b0b0
+							MX6DL_PAD_EIM_D26__EIM_DATA26 0x1b0b0
+							MX6DL_PAD_EIM_D27__EIM_DATA27 0x1b0b0
+							MX6DL_PAD_EIM_D28__EIM_DATA28 0x1b0b0
+							MX6DL_PAD_EIM_D29__EIM_DATA29 0x1b0b0
+							MX6DL_PAD_EIM_D30__EIM_DATA30 0x1b0b0
+							MX6DL_PAD_EIM_D31__EIM_DATA31 0x1b0b0
+							/* address */
+							MX6DL_PAD_EIM_A23__EIM_ADDR23 0xb0b1
+							MX6DL_PAD_EIM_A22__EIM_ADDR22 0xb0b1
+							MX6DL_PAD_EIM_A21__EIM_ADDR21 0xb0b1
+							MX6DL_PAD_EIM_A20__EIM_ADDR20 0xb0b1
+							MX6DL_PAD_EIM_A19__EIM_ADDR19 0xb0b1
+							MX6DL_PAD_EIM_A18__EIM_ADDR18 0xb0b1
+							MX6DL_PAD_EIM_A17__EIM_ADDR17 0xb0b1
+							MX6DL_PAD_EIM_A16__EIM_ADDR16 0xb0b1
+							MX6DL_PAD_EIM_DA15__EIM_AD15  0xb0b1
+							MX6DL_PAD_EIM_DA14__EIM_AD14  0xb0b1
+							MX6DL_PAD_EIM_DA13__EIM_AD13  0xb0b1
+							MX6DL_PAD_EIM_DA12__EIM_AD12  0xb0b1
+							MX6DL_PAD_EIM_DA11__EIM_AD11  0xb0b1
+							MX6DL_PAD_EIM_DA10__EIM_AD10  0xb0b1
+							MX6DL_PAD_EIM_DA9__EIM_AD09   0xb0b1
+							MX6DL_PAD_EIM_DA8__EIM_AD08   0xb0b1
+							MX6DL_PAD_EIM_DA7__EIM_AD07   0xb0b1
+							MX6DL_PAD_EIM_DA6__EIM_AD06   0xb0b1
+							MX6DL_PAD_EIM_DA5__EIM_AD05   0xb0b1
+							MX6DL_PAD_EIM_DA4__EIM_AD04   0xb0b1
+							MX6DL_PAD_EIM_DA3__EIM_AD03   0xb0b1
+							MX6DL_PAD_EIM_DA2__EIM_AD02   0xb0b1
+							MX6DL_PAD_EIM_DA1__EIM_AD01   0xb0b1
+							MX6DL_PAD_EIM_DA0__EIM_AD00   0xb0b1
+						>;
+					};
+
+				};
 
 			};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6dl-sabreauto.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6dl-sabreauto.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6dl-sabreauto.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6dl-sabreauto.dts	2013-08-25 20:43:22.000000000 -0400
@@ -28,4 +28,12 @@
 			>;
 		};
 	};
+
+	ecspi1 {
+		pinctrl_ecspi1_sabreauto: ecspi1-sabreauto {
+			fsl,pins = <
+				MX6DL_PAD_EIM_D19__GPIO3_IO19  0x80000000
+			>;
+		};
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6dl-sabresd.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6dl-sabresd.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6dl-sabresd.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6dl-sabresd.dts	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,7 @@
 				MX6DL_PAD_NANDF_D1__GPIO2_IO01 0x80000000
 				MX6DL_PAD_NANDF_D2__GPIO2_IO02 0x80000000
 				MX6DL_PAD_NANDF_D3__GPIO2_IO03 0x80000000
+				MX6DL_PAD_GPIO_0__CCM_CLKO1    0x130b0
 			>;
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6qdl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6qdl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6qdl.dtsi	2013-07-01 10:32:39.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6qdl.dtsi	2013-08-31 17:52:06.000000000 -0400
@@ -106,6 +106,8 @@
 			interrupts = <0 92 0x04>;
 			cache-unified;
 			cache-level = <2>;
+			arm,tag-latency = <4 2 3>;
+			arm,data-latency = <4 2 3>;
 		};
 
 		pmu {
@@ -638,7 +640,7 @@
 				status = "disabled";
 			};
 
-			usbmisc: usbmisc: usbmisc@02184800 {
+			usbmisc: usbmisc@02184800 {
 				#index-cells = <1>;
 				compatible = "fsl,imx6q-usbmisc";
 				reg = <0x02184800 0x200>;
@@ -742,9 +744,11 @@
 				reg = <0x021b4000 0x4000>;
 			};
 
-			weim@021b8000 {
+			weim: weim@021b8000 {
+				compatible = "fsl,imx6q-weim";
 				reg = <0x021b8000 0x4000>;
 				interrupts = <0 14 0x04>;
+				clocks = <&clks 196>;
 			};
 
 			ocotp@021bc000 {
@@ -752,11 +756,6 @@
 				reg = <0x021bc000 0x4000>;
 			};
 
-			ocotp@021c0000 {
-				reg = <0x021c0000 0x4000>;
-				interrupts = <0 21 0x04>;
-			};
-
 			tzasc@021d0000 { /* TZASC1 */
 				reg = <0x021d0000 0x4000>;
 				interrupts = <0 108 0x04>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,22 @@
 	};
 };
 
+&ecspi1 {
+	fsl,spi-num-chipselects = <1>;
+	cs-gpios = <&gpio3 19 0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_sabreauto>;
+	status = "disabled"; /* pin conflict with WEIM NOR */
+
+	flash: m25p80@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "st,m25p32";
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+	};
+};
+
 &fec {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_enet_2>;
@@ -23,6 +39,12 @@
 	status = "okay";
 };
 
+&gpmi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpmi_nand_1>;
+	status = "okay";
+};
+
 &uart4 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart4_1>;
@@ -36,3 +58,22 @@
 	wp-gpios = <&gpio1 13 0>;
 	status = "okay";
 };
+
+&weim {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_weim_nor_1 &pinctrl_weim_cs0_1>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+	ranges = <0 0 0x08000000 0x08000000>;
+	status = "disabled"; /* pin conflict with SPI NOR */
+
+	nor@0,0 {
+		compatible = "cfi-flash";
+		reg = <0 0 0x02000000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		bank-width = <2>;
+		fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
+				0x0000c000 0x1404a38e 0x00000000>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6qdl-sabresd.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6qdl-sabresd.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6qdl-sabresd.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,13 @@
 			gpio = <&gpio3 22 0>;
 			enable-active-high;
 		};
+
+		reg_audio: wm8962_supply {
+			compatible = "regulator-fixed";
+			regulator-name = "wm8962-supply";
+			gpio = <&gpio4 10 0>;
+			enable-active-high;
+		};
 	};
 
 	gpio-keys {
@@ -43,6 +50,31 @@
 			linux,code = <114>; /* KEY_VOLUMEDOWN */
 		};
 	};
+
+	sound {
+		compatible = "fsl,imx6q-sabresd-wm8962",
+			   "fsl,imx-audio-wm8962";
+		model = "wm8962-audio";
+		ssi-controller = <&ssi2>;
+		audio-codec = <&codec>;
+		audio-routing =
+			"Headphone Jack", "HPOUTL",
+			"Headphone Jack", "HPOUTR",
+			"Ext Spk", "SPKOUTL",
+			"Ext Spk", "SPKOUTR",
+			"MICBIAS", "AMIC",
+			"IN3R", "MICBIAS",
+			"DMIC", "MICBIAS",
+			"DMICDAT", "DMIC";
+		mux-int-port = <2>;
+		mux-ext-port = <3>;
+	};
+};
+
+&audmux {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux_2>;
+	status = "okay";
 };
 
 &fec {
@@ -52,6 +84,40 @@
 	status = "okay";
 };
 
+&i2c1 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1_2>;
+	status = "okay";
+
+	codec: wm8962@1a {
+		compatible = "wlf,wm8962";
+		reg = <0x1a>;
+		clocks = <&clks 169>;
+		DCVDD-supply = <&reg_audio>;
+		DBVDD-supply = <&reg_audio>;
+		AVDD-supply = <&reg_audio>;
+		CPVDD-supply = <&reg_audio>;
+		MICVDD-supply = <&reg_audio>;
+		PLLVDD-supply = <&reg_audio>;
+		SPKVDD1-supply = <&reg_audio>;
+		SPKVDD2-supply = <&reg_audio>;
+		gpio-cfg = <
+			0x0000 /* 0:Default */
+			0x0000 /* 1:Default */
+			0x0013 /* 2:FN_DMICCLK */
+			0x0000 /* 3:Default */
+			0x8014 /* 4:FN_DMICCDAT */
+			0x0000 /* 5:Default */
+		>;
+       };
+};
+
+&ssi2 {
+	fsl,mode = "i2s-slave";
+	status = "okay";
+};
+
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1_1>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
 
 		cpu@0 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			reg = <0>;
 			next-level-cache = <&L2>;
 			operating-points = <
@@ -39,18 +40,21 @@
 
 		cpu@1 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			reg = <1>;
 			next-level-cache = <&L2>;
 		};
 
 		cpu@2 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			reg = <2>;
 			next-level-cache = <&L2>;
 		};
 
 		cpu@3 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			reg = <3>;
 			next-level-cache = <&L2>;
 		};
@@ -157,6 +161,27 @@
 							MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
 						>;
 					};
+
+					pinctrl_enet_3: enetgrp-3 {
+						fsl,pins = <
+							MX6Q_PAD_ENET_MDIO__ENET_MDIO       0x1b0b0
+							MX6Q_PAD_ENET_MDC__ENET_MDC         0x1b0b0
+							MX6Q_PAD_RGMII_TXC__RGMII_TXC       0x1b0b0
+							MX6Q_PAD_RGMII_TD0__RGMII_TD0       0x1b0b0
+							MX6Q_PAD_RGMII_TD1__RGMII_TD1       0x1b0b0
+							MX6Q_PAD_RGMII_TD2__RGMII_TD2       0x1b0b0
+							MX6Q_PAD_RGMII_TD3__RGMII_TD3       0x1b0b0
+							MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+							MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK  0x1b0b0
+							MX6Q_PAD_RGMII_RXC__RGMII_RXC       0x1b0b0
+							MX6Q_PAD_RGMII_RD0__RGMII_RD0       0x1b0b0
+							MX6Q_PAD_RGMII_RD1__RGMII_RD1       0x1b0b0
+							MX6Q_PAD_RGMII_RD2__RGMII_RD2       0x1b0b0
+							MX6Q_PAD_RGMII_RD3__RGMII_RD3       0x1b0b0
+							MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+							MX6Q_PAD_ENET_TX_EN__ENET_TX_EN     0x1b0b0
+						>;
+					};
 				};
 
 				gpmi-nand {
@@ -168,8 +193,6 @@
 							MX6Q_PAD_NANDF_RB0__NAND_READY_B 0xb000
 							MX6Q_PAD_NANDF_CS0__NAND_CE0_B   0xb0b1
 							MX6Q_PAD_NANDF_CS1__NAND_CE1_B   0xb0b1
-							MX6Q_PAD_NANDF_CS2__NAND_CE2_B   0xb0b1
-							MX6Q_PAD_NANDF_CS3__NAND_CE3_B   0xb0b1
 							MX6Q_PAD_SD4_CMD__NAND_RE_B      0xb0b1
 							MX6Q_PAD_SD4_CLK__NAND_WE_B      0xb0b1
 							MX6Q_PAD_NANDF_D0__NAND_DATA00   0xb0b1
@@ -192,6 +215,13 @@
 							MX6Q_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
 						>;
 					};
+
+					pinctrl_i2c1_2: i2c1grp-2 {
+						fsl,pins = <
+							MX6Q_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
+							MX6Q_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
+						>;
+					};
 				};
 
 				i2c2 {
@@ -268,6 +298,17 @@
 							MX6Q_PAD_NANDF_D7__SD2_DATA7 0x17059
 						>;
 					};
+
+					pinctrl_usdhc2_2: usdhc2grp-2 {
+						fsl,pins = <
+							MX6Q_PAD_SD2_CMD__SD2_CMD    0x17059
+							MX6Q_PAD_SD2_CLK__SD2_CLK    0x10059
+							MX6Q_PAD_SD2_DAT0__SD2_DATA0 0x17059
+							MX6Q_PAD_SD2_DAT1__SD2_DATA1 0x17059
+							MX6Q_PAD_SD2_DAT2__SD2_DATA2 0x17059
+							MX6Q_PAD_SD2_DAT3__SD2_DATA3 0x17059
+						>;
+					};
 				};
 
 				usdhc3 {
@@ -325,6 +366,65 @@
 						>;
 					};
 				};
+
+				weim {
+					pinctrl_weim_cs0_1: weim_cs0grp-1 {
+						fsl,pins = <
+							MX6Q_PAD_EIM_CS0__EIM_CS0_B   0xb0b1
+						>;
+					};
+
+					pinctrl_weim_nor_1: weimnorgrp-1 {
+						fsl,pins = <
+							MX6Q_PAD_EIM_OE__EIM_OE_B     0xb0b1
+							MX6Q_PAD_EIM_RW__EIM_RW       0xb0b1
+							MX6Q_PAD_EIM_WAIT__EIM_WAIT_B 0xb060
+							/* data */
+							MX6Q_PAD_EIM_D16__EIM_DATA16 0x1b0b0
+							MX6Q_PAD_EIM_D17__EIM_DATA17 0x1b0b0
+							MX6Q_PAD_EIM_D18__EIM_DATA18 0x1b0b0
+							MX6Q_PAD_EIM_D19__EIM_DATA19 0x1b0b0
+							MX6Q_PAD_EIM_D20__EIM_DATA20 0x1b0b0
+							MX6Q_PAD_EIM_D21__EIM_DATA21 0x1b0b0
+							MX6Q_PAD_EIM_D22__EIM_DATA22 0x1b0b0
+							MX6Q_PAD_EIM_D23__EIM_DATA23 0x1b0b0
+							MX6Q_PAD_EIM_D24__EIM_DATA24 0x1b0b0
+							MX6Q_PAD_EIM_D25__EIM_DATA25 0x1b0b0
+							MX6Q_PAD_EIM_D26__EIM_DATA26 0x1b0b0
+							MX6Q_PAD_EIM_D27__EIM_DATA27 0x1b0b0
+							MX6Q_PAD_EIM_D28__EIM_DATA28 0x1b0b0
+							MX6Q_PAD_EIM_D29__EIM_DATA29 0x1b0b0
+							MX6Q_PAD_EIM_D30__EIM_DATA30 0x1b0b0
+							MX6Q_PAD_EIM_D31__EIM_DATA31 0x1b0b0
+							/* address */
+							MX6Q_PAD_EIM_A23__EIM_ADDR23 0xb0b1
+							MX6Q_PAD_EIM_A22__EIM_ADDR22 0xb0b1
+							MX6Q_PAD_EIM_A21__EIM_ADDR21 0xb0b1
+							MX6Q_PAD_EIM_A20__EIM_ADDR20 0xb0b1
+							MX6Q_PAD_EIM_A19__EIM_ADDR19 0xb0b1
+							MX6Q_PAD_EIM_A18__EIM_ADDR18 0xb0b1
+							MX6Q_PAD_EIM_A17__EIM_ADDR17 0xb0b1
+							MX6Q_PAD_EIM_A16__EIM_ADDR16 0xb0b1
+							MX6Q_PAD_EIM_DA15__EIM_AD15  0xb0b1
+							MX6Q_PAD_EIM_DA14__EIM_AD14  0xb0b1
+							MX6Q_PAD_EIM_DA13__EIM_AD13  0xb0b1
+							MX6Q_PAD_EIM_DA12__EIM_AD12  0xb0b1
+							MX6Q_PAD_EIM_DA11__EIM_AD11  0xb0b1
+							MX6Q_PAD_EIM_DA10__EIM_AD10  0xb0b1
+							MX6Q_PAD_EIM_DA9__EIM_AD09   0xb0b1
+							MX6Q_PAD_EIM_DA8__EIM_AD08   0xb0b1
+							MX6Q_PAD_EIM_DA7__EIM_AD07   0xb0b1
+							MX6Q_PAD_EIM_DA6__EIM_AD06   0xb0b1
+							MX6Q_PAD_EIM_DA5__EIM_AD05   0xb0b1
+							MX6Q_PAD_EIM_DA4__EIM_AD04   0xb0b1
+							MX6Q_PAD_EIM_DA3__EIM_AD03   0xb0b1
+							MX6Q_PAD_EIM_DA2__EIM_AD02   0xb0b1
+							MX6Q_PAD_EIM_DA1__EIM_AD01   0xb0b1
+							MX6Q_PAD_EIM_DA0__EIM_AD00   0xb0b1
+						>;
+					};
+
+				};
 			};
 		};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q-phytec-pbab01.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q-phytec-pbab01.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q-phytec-pbab01.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q-phytec-pbab01.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q-phytec-pfla02.dtsi"
+
+/ {
+	model = "Phytec phyFLEX-i.MX6 Quad Carrier-Board";
+	compatible = "phytec,imx6q-pbab01", "phytec,imx6q-pfla02", "fsl,imx6q";
+};
+
+&fec {
+	status = "okay";
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&usdhc2 {
+	status = "okay";
+};
+
+&usdhc3 {
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2013 Christian Hemp, Phytec Messtechnik GmbH
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "imx6q.dtsi"
+
+/ {
+	model = "Phytec phyFLEX-i.MX6 Ouad";
+	compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
+
+	memory {
+		reg = <0x10000000 0x80000000>;
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
+	hog {
+		pinctrl_hog: hoggrp {
+			fsl,pins = <
+				MX6Q_PAD_EIM_D23__GPIO3_IO23    0x80000000
+			>;
+		};
+	};
+
+	pfla02 {
+		pinctrl_usdhc3_pfla02: usdhc3grp-pfla02 {
+			fsl,pins = <
+				MX6Q_PAD_ENET_RXD0__GPIO1_IO27  0x80000000
+				MX6Q_PAD_ENET_TXD1__GPIO1_IO29  0x80000000
+			>;
+		};
+	};
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet_3>;
+	phy-mode = "rgmii";
+	phy-reset-gpios = <&gpio3 23 0>;
+	status = "disabled";
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4_1>;
+	status = "disabled";
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2_2>;
+	cd-gpios = <&gpio1 4 0>;
+	wp-gpios = <&gpio1 2 0>;
+	status = "disabled";
+};
+
+&usdhc3 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_usdhc3_2
+		     &pinctrl_usdhc3_pfla02>;
+        cd-gpios = <&gpio1 27 0>;
+        wp-gpios = <&gpio1 29 0>;
+        status = "disabled";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q-sabreauto.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q-sabreauto.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q-sabreauto.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q-sabreauto.dts	2013-08-25 20:43:22.000000000 -0400
@@ -32,4 +32,12 @@
 			>;
 		};
 	};
+
+	ecspi1 {
+		pinctrl_ecspi1_sabreauto: ecspi1-sabreauto {
+			fsl,pins = <
+				MX6Q_PAD_EIM_D19__GPIO3_IO19  0x80000000
+			>;
+		};
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q-sabresd.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q-sabresd.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6q-sabresd.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6q-sabresd.dts	2013-08-25 20:43:22.000000000 -0400
@@ -33,6 +33,7 @@
 				MX6Q_PAD_NANDF_D1__GPIO2_IO01 0x80000000
 				MX6Q_PAD_NANDF_D2__GPIO2_IO02 0x80000000
 				MX6Q_PAD_NANDF_D3__GPIO2_IO03 0x80000000
+				MX6Q_PAD_GPIO_0__CCM_CLKO1    0x130b0
 			>;
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6sl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6sl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6sl.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6sl.dtsi	2013-08-31 17:52:09.000000000 -0400
@@ -0,0 +1,779 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include "skeleton.dtsi"
+#include "imx6sl-pinfunc.h"
+#include <dt-bindings/clock/imx6sl-clock.h>
+
+/ {
+	aliases {
+		serial0 = &uart1;
+		serial1 = &uart2;
+		serial2 = &uart3;
+		serial3 = &uart4;
+		serial4 = &uart5;
+		gpio0 = &gpio1;
+		gpio1 = &gpio2;
+		gpio2 = &gpio3;
+		gpio3 = &gpio4;
+		gpio4 = &gpio5;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "arm,cortex-a9";
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	intc: interrupt-controller@00a01000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-controller;
+		reg = <0x00a01000 0x1000>,
+		      <0x00a00100 0x100>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ckil {
+			compatible = "fixed-clock";
+			clock-frequency = <32768>;
+		};
+
+		osc {
+			compatible = "fixed-clock";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		interrupt-parent = <&intc>;
+		ranges;
+
+		L2: l2-cache@00a02000 {
+			compatible = "arm,pl310-cache";
+			reg = <0x00a02000 0x1000>;
+			interrupts = <0 92 0x04>;
+			cache-unified;
+			cache-level = <2>;
+			arm,tag-latency = <4 2 3>;
+			arm,data-latency = <4 2 3>;
+		};
+
+		pmu {
+			compatible = "arm,cortex-a9-pmu";
+			interrupts = <0 94 0x04>;
+		};
+
+		aips1: aips-bus@02000000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x02000000 0x100000>;
+			ranges;
+
+			spba: spba-bus@02000000 {
+				compatible = "fsl,spba-bus", "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x02000000 0x40000>;
+				ranges;
+
+				spdif: spdif@02004000 {
+					reg = <0x02004000 0x4000>;
+					interrupts = <0 52 0x04>;
+				};
+
+				ecspi1: ecspi@02008000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+					reg = <0x02008000 0x4000>;
+					interrupts = <0 31 0x04>;
+					clocks = <&clks IMX6SL_CLK_ECSPI1>,
+						 <&clks IMX6SL_CLK_ECSPI1>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				ecspi2: ecspi@0200c000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+					reg = <0x0200c000 0x4000>;
+					interrupts = <0 32 0x04>;
+					clocks = <&clks IMX6SL_CLK_ECSPI2>,
+						 <&clks IMX6SL_CLK_ECSPI2>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				ecspi3: ecspi@02010000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+					reg = <0x02010000 0x4000>;
+					interrupts = <0 33 0x04>;
+					clocks = <&clks IMX6SL_CLK_ECSPI3>,
+						 <&clks IMX6SL_CLK_ECSPI3>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				ecspi4: ecspi@02014000 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					compatible = "fsl,imx6sl-ecspi", "fsl,imx51-ecspi";
+					reg = <0x02014000 0x4000>;
+					interrupts = <0 34 0x04>;
+					clocks = <&clks IMX6SL_CLK_ECSPI4>,
+						 <&clks IMX6SL_CLK_ECSPI4>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				uart5: serial@02018000 {
+					compatible = "fsl,imx6sl-uart", "fsl,imx21-uart";
+					reg = <0x02018000 0x4000>;
+					interrupts = <0 30 0x04>;
+					clocks = <&clks IMX6SL_CLK_UART>,
+						 <&clks IMX6SL_CLK_UART_SERIAL>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				uart1: serial@02020000 {
+					compatible = "fsl,imx6sl-uart", "fsl,imx21-uart";
+					reg = <0x02020000 0x4000>;
+					interrupts = <0 26 0x04>;
+					clocks = <&clks IMX6SL_CLK_UART>,
+						 <&clks IMX6SL_CLK_UART_SERIAL>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				uart2: serial@02024000 {
+					compatible = "fsl,imx6sl-uart", "fsl,imx21-uart";
+					reg = <0x02024000 0x4000>;
+					interrupts = <0 27 0x04>;
+					clocks = <&clks IMX6SL_CLK_UART>,
+						 <&clks IMX6SL_CLK_UART_SERIAL>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				ssi1: ssi@02028000 {
+					compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+					reg = <0x02028000 0x4000>;
+					interrupts = <0 46 0x04>;
+					clocks = <&clks IMX6SL_CLK_SSI1>;
+					fsl,fifo-depth = <15>;
+					status = "disabled";
+				};
+
+				ssi2: ssi@0202c000 {
+					compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+					reg = <0x0202c000 0x4000>;
+					interrupts = <0 47 0x04>;
+					clocks = <&clks IMX6SL_CLK_SSI2>;
+					fsl,fifo-depth = <15>;
+					status = "disabled";
+				};
+
+				ssi3: ssi@02030000 {
+					compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+					reg = <0x02030000 0x4000>;
+					interrupts = <0 48 0x04>;
+					clocks = <&clks IMX6SL_CLK_SSI3>;
+					fsl,fifo-depth = <15>;
+					status = "disabled";
+				};
+
+				uart3: serial@02034000 {
+					compatible = "fsl,imx6sl-uart", "fsl,imx21-uart";
+					reg = <0x02034000 0x4000>;
+					interrupts = <0 28 0x04>;
+					clocks = <&clks IMX6SL_CLK_UART>,
+						 <&clks IMX6SL_CLK_UART_SERIAL>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+
+				uart4: serial@02038000 {
+					compatible = "fsl,imx6sl-uart", "fsl,imx21-uart";
+					reg = <0x02038000 0x4000>;
+					interrupts = <0 29 0x04>;
+					clocks = <&clks IMX6SL_CLK_UART>,
+						 <&clks IMX6SL_CLK_UART_SERIAL>;
+					clock-names = "ipg", "per";
+					status = "disabled";
+				};
+			};
+
+			pwm1: pwm@02080000 {
+				#pwm-cells = <2>;
+				compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
+				reg = <0x02080000 0x4000>;
+				interrupts = <0 83 0x04>;
+				clocks = <&clks IMX6SL_CLK_PWM1>,
+					 <&clks IMX6SL_CLK_PWM1>;
+				clock-names = "ipg", "per";
+			};
+
+			pwm2: pwm@02084000 {
+				#pwm-cells = <2>;
+				compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
+				reg = <0x02084000 0x4000>;
+				interrupts = <0 84 0x04>;
+				clocks = <&clks IMX6SL_CLK_PWM2>,
+					 <&clks IMX6SL_CLK_PWM2>;
+				clock-names = "ipg", "per";
+			};
+
+			pwm3: pwm@02088000 {
+				#pwm-cells = <2>;
+				compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
+				reg = <0x02088000 0x4000>;
+				interrupts = <0 85 0x04>;
+				clocks = <&clks IMX6SL_CLK_PWM3>,
+					 <&clks IMX6SL_CLK_PWM3>;
+				clock-names = "ipg", "per";
+			};
+
+			pwm4: pwm@0208c000 {
+				#pwm-cells = <2>;
+				compatible = "fsl,imx6sl-pwm", "fsl,imx27-pwm";
+				reg = <0x0208c000 0x4000>;
+				interrupts = <0 86 0x04>;
+				clocks = <&clks IMX6SL_CLK_PWM4>,
+					 <&clks IMX6SL_CLK_PWM4>;
+				clock-names = "ipg", "per";
+			};
+
+			gpt: gpt@02098000 {
+				compatible = "fsl,imx6sl-gpt";
+				reg = <0x02098000 0x4000>;
+				interrupts = <0 55 0x04>;
+				clocks = <&clks IMX6SL_CLK_GPT>,
+					 <&clks IMX6SL_CLK_GPT_SERIAL>;
+				clock-names = "ipg", "per";
+			};
+
+			gpio1: gpio@0209c000 {
+				compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+				reg = <0x0209c000 0x4000>;
+				interrupts = <0 66 0x04 0 67 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio2: gpio@020a0000 {
+				compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+				reg = <0x020a0000 0x4000>;
+				interrupts = <0 68 0x04 0 69 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio3: gpio@020a4000 {
+				compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+				reg = <0x020a4000 0x4000>;
+				interrupts = <0 70 0x04 0 71 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio4: gpio@020a8000 {
+				compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+				reg = <0x020a8000 0x4000>;
+				interrupts = <0 72 0x04 0 73 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio5: gpio@020ac000 {
+				compatible = "fsl,imx6sl-gpio", "fsl,imx35-gpio";
+				reg = <0x020ac000 0x4000>;
+				interrupts = <0 74 0x04 0 75 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			kpp: kpp@020b8000 {
+				reg = <0x020b8000 0x4000>;
+				interrupts = <0 82 0x04>;
+			};
+
+			wdog1: wdog@020bc000 {
+				compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
+				reg = <0x020bc000 0x4000>;
+				interrupts = <0 80 0x04>;
+				clocks = <&clks IMX6SL_CLK_DUMMY>;
+			};
+
+			wdog2: wdog@020c0000 {
+				compatible = "fsl,imx6sl-wdt", "fsl,imx21-wdt";
+				reg = <0x020c0000 0x4000>;
+				interrupts = <0 81 0x04>;
+				clocks = <&clks IMX6SL_CLK_DUMMY>;
+				status = "disabled";
+			};
+
+			clks: ccm@020c4000 {
+				compatible = "fsl,imx6sl-ccm";
+				reg = <0x020c4000 0x4000>;
+				interrupts = <0 87 0x04 0 88 0x04>;
+				#clock-cells = <1>;
+			};
+
+			anatop: anatop@020c8000 {
+				compatible = "fsl,imx6sl-anatop", "syscon", "simple-bus";
+				reg = <0x020c8000 0x1000>;
+				interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
+
+				regulator-1p1@110 {
+					compatible = "fsl,anatop-regulator";
+					regulator-name = "vdd1p1";
+					regulator-min-microvolt = <800000>;
+					regulator-max-microvolt = <1375000>;
+					regulator-always-on;
+					anatop-reg-offset = <0x110>;
+					anatop-vol-bit-shift = <8>;
+					anatop-vol-bit-width = <5>;
+					anatop-min-bit-val = <4>;
+					anatop-min-voltage = <800000>;
+					anatop-max-voltage = <1375000>;
+				};
+
+				regulator-3p0@120 {
+					compatible = "fsl,anatop-regulator";
+					regulator-name = "vdd3p0";
+					regulator-min-microvolt = <2800000>;
+					regulator-max-microvolt = <3150000>;
+					regulator-always-on;
+					anatop-reg-offset = <0x120>;
+					anatop-vol-bit-shift = <8>;
+					anatop-vol-bit-width = <5>;
+					anatop-min-bit-val = <0>;
+					anatop-min-voltage = <2625000>;
+					anatop-max-voltage = <3400000>;
+				};
+
+				regulator-2p5@130 {
+					compatible = "fsl,anatop-regulator";
+					regulator-name = "vdd2p5";
+					regulator-min-microvolt = <2100000>;
+					regulator-max-microvolt = <2850000>;
+					regulator-always-on;
+					anatop-reg-offset = <0x130>;
+					anatop-vol-bit-shift = <8>;
+					anatop-vol-bit-width = <5>;
+					anatop-min-bit-val = <0>;
+					anatop-min-voltage = <2100000>;
+					anatop-max-voltage = <2850000>;
+				};
+
+				reg_arm: regulator-vddcore@140 {
+					compatible = "fsl,anatop-regulator";
+					regulator-name = "cpu";
+					regulator-min-microvolt = <725000>;
+					regulator-max-microvolt = <1450000>;
+					regulator-always-on;
+					anatop-reg-offset = <0x140>;
+					anatop-vol-bit-shift = <0>;
+					anatop-vol-bit-width = <5>;
+					anatop-delay-reg-offset = <0x170>;
+					anatop-delay-bit-shift = <24>;
+					anatop-delay-bit-width = <2>;
+					anatop-min-bit-val = <1>;
+					anatop-min-voltage = <725000>;
+					anatop-max-voltage = <1450000>;
+				};
+
+				reg_pu: regulator-vddpu@140 {
+					compatible = "fsl,anatop-regulator";
+					regulator-name = "vddpu";
+					regulator-min-microvolt = <725000>;
+					regulator-max-microvolt = <1450000>;
+					regulator-always-on;
+					anatop-reg-offset = <0x140>;
+					anatop-vol-bit-shift = <9>;
+					anatop-vol-bit-width = <5>;
+					anatop-delay-reg-offset = <0x170>;
+					anatop-delay-bit-shift = <26>;
+					anatop-delay-bit-width = <2>;
+					anatop-min-bit-val = <1>;
+					anatop-min-voltage = <725000>;
+					anatop-max-voltage = <1450000>;
+				};
+
+				reg_soc: regulator-vddsoc@140 {
+					compatible = "fsl,anatop-regulator";
+					regulator-name = "vddsoc";
+					regulator-min-microvolt = <725000>;
+					regulator-max-microvolt = <1450000>;
+					regulator-always-on;
+					anatop-reg-offset = <0x140>;
+					anatop-vol-bit-shift = <18>;
+					anatop-vol-bit-width = <5>;
+					anatop-delay-reg-offset = <0x170>;
+					anatop-delay-bit-shift = <28>;
+					anatop-delay-bit-width = <2>;
+					anatop-min-bit-val = <1>;
+					anatop-min-voltage = <725000>;
+					anatop-max-voltage = <1450000>;
+				};
+			};
+
+			usbphy1: usbphy@020c9000 {
+				compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
+				reg = <0x020c9000 0x1000>;
+				interrupts = <0 44 0x04>;
+				clocks = <&clks IMX6SL_CLK_USBPHY1>;
+			};
+
+			usbphy2: usbphy@020ca000 {
+				compatible = "fsl,imx6sl-usbphy", "fsl,imx23-usbphy";
+				reg = <0x020ca000 0x1000>;
+				interrupts = <0 45 0x04>;
+				clocks = <&clks IMX6SL_CLK_USBPHY2>;
+			};
+
+			snvs@020cc000 {
+				compatible = "fsl,sec-v4.0-mon", "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x020cc000 0x4000>;
+
+				snvs-rtc-lp@34 {
+					compatible = "fsl,sec-v4.0-mon-rtc-lp";
+					reg = <0x34 0x58>;
+					interrupts = <0 19 0x04 0 20 0x04>;
+				};
+			};
+
+			epit1: epit@020d0000 {
+				reg = <0x020d0000 0x4000>;
+				interrupts = <0 56 0x04>;
+			};
+
+			epit2: epit@020d4000 {
+				reg = <0x020d4000 0x4000>;
+				interrupts = <0 57 0x04>;
+			};
+
+			src: src@020d8000 {
+				compatible = "fsl,imx6sl-src", "fsl,imx51-src";
+				reg = <0x020d8000 0x4000>;
+				interrupts = <0 91 0x04 0 96 0x04>;
+				#reset-cells = <1>;
+			};
+
+			gpc: gpc@020dc000 {
+				compatible = "fsl,imx6sl-gpc", "fsl,imx6q-gpc";
+				reg = <0x020dc000 0x4000>;
+				interrupts = <0 89 0x04>;
+			};
+
+			iomuxc: iomuxc@020e0000 {
+				compatible = "fsl,imx6sl-iomuxc";
+				reg = <0x020e0000 0x4000>;
+
+				fec {
+					pinctrl_fec_1: fecgrp-1 {
+						fsl,pins = <
+							MX6SL_PAD_FEC_MDC__FEC_MDC         0x1b0b0
+							MX6SL_PAD_FEC_MDIO__FEC_MDIO       0x1b0b0
+							MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV    0x1b0b0
+							MX6SL_PAD_FEC_RXD0__FEC_RX_DATA0   0x1b0b0
+							MX6SL_PAD_FEC_RXD1__FEC_RX_DATA1   0x1b0b0
+							MX6SL_PAD_FEC_TX_EN__FEC_TX_EN     0x1b0b0
+							MX6SL_PAD_FEC_TXD0__FEC_TX_DATA0   0x1b0b0
+							MX6SL_PAD_FEC_TXD1__FEC_TX_DATA1   0x1b0b0
+							MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT 0x4001b0a8
+						>;
+					};
+				};
+
+				uart1 {
+					pinctrl_uart1_1: uart1grp-1 {
+						fsl,pins = <
+							MX6SL_PAD_UART1_RXD__UART1_RX_DATA 0x1b0b1
+							MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
+						>;
+					};
+				};
+
+				usdhc1 {
+					pinctrl_usdhc1_1: usdhc1grp-1 {
+						fsl,pins = <
+							MX6SL_PAD_SD1_CMD__SD1_CMD    0x17059
+							MX6SL_PAD_SD1_CLK__SD1_CLK    0x10059
+							MX6SL_PAD_SD1_DAT0__SD1_DATA0 0x17059
+							MX6SL_PAD_SD1_DAT1__SD1_DATA1 0x17059
+							MX6SL_PAD_SD1_DAT2__SD1_DATA2 0x17059
+							MX6SL_PAD_SD1_DAT3__SD1_DATA3 0x17059
+							MX6SL_PAD_SD1_DAT4__SD1_DATA4 0x17059
+							MX6SL_PAD_SD1_DAT5__SD1_DATA5 0x17059
+							MX6SL_PAD_SD1_DAT6__SD1_DATA6 0x17059
+							MX6SL_PAD_SD1_DAT7__SD1_DATA7 0x17059
+						>;
+					};
+				};
+
+				usdhc2 {
+					pinctrl_usdhc2_1: usdhc2grp-1 {
+						fsl,pins = <
+							MX6SL_PAD_SD2_CMD__SD2_CMD    0x17059
+							MX6SL_PAD_SD2_CLK__SD2_CLK    0x10059
+							MX6SL_PAD_SD2_DAT0__SD2_DATA0 0x17059
+							MX6SL_PAD_SD2_DAT1__SD2_DATA1 0x17059
+							MX6SL_PAD_SD2_DAT2__SD2_DATA2 0x17059
+							MX6SL_PAD_SD2_DAT3__SD2_DATA3 0x17059
+						>;
+					};
+				};
+
+				usdhc3 {
+					pinctrl_usdhc3_1: usdhc3grp-1 {
+						fsl,pins = <
+							MX6SL_PAD_SD3_CMD__SD3_CMD    0x17059
+							MX6SL_PAD_SD3_CLK__SD3_CLK    0x10059
+							MX6SL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+							MX6SL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+							MX6SL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+							MX6SL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+						>;
+					};
+				};
+			};
+
+			csi: csi@020e4000 {
+				reg = <0x020e4000 0x4000>;
+				interrupts = <0 7 0x04>;
+			};
+
+			spdc: spdc@020e8000 {
+				reg = <0x020e8000 0x4000>;
+				interrupts = <0 6 0x04>;
+			};
+
+			sdma: sdma@020ec000 {
+				compatible = "fsl,imx6sl-sdma", "fsl,imx35-sdma";
+				reg = <0x020ec000 0x4000>;
+				interrupts = <0 2 0x04>;
+				clocks = <&clks IMX6SL_CLK_SDMA>,
+					 <&clks IMX6SL_CLK_SDMA>;
+				clock-names = "ipg", "ahb";
+				fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
+			};
+
+			pxp: pxp@020f0000 {
+				reg = <0x020f0000 0x4000>;
+				interrupts = <0 98 0x04>;
+			};
+
+			epdc: epdc@020f4000 {
+				reg = <0x020f4000 0x4000>;
+				interrupts = <0 97 0x04>;
+			};
+
+			lcdif: lcdif@020f8000 {
+				reg = <0x020f8000 0x4000>;
+				interrupts = <0 39 0x04>;
+			};
+
+			dcp: dcp@020fc000 {
+				reg = <0x020fc000 0x4000>;
+				interrupts = <0 99 0x04>;
+			};
+		};
+
+		aips2: aips-bus@02100000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x02100000 0x100000>;
+			ranges;
+
+			usbotg1: usb@02184000 {
+				compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
+				reg = <0x02184000 0x200>;
+				interrupts = <0 43 0x04>;
+				clocks = <&clks IMX6SL_CLK_USBOH3>;
+				fsl,usbphy = <&usbphy1>;
+				fsl,usbmisc = <&usbmisc 0>;
+				status = "disabled";
+			};
+
+			usbotg2: usb@02184200 {
+				compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
+				reg = <0x02184200 0x200>;
+				interrupts = <0 40 0x04>;
+				clocks = <&clks IMX6SL_CLK_USBOH3>;
+				fsl,usbphy = <&usbphy2>;
+				fsl,usbmisc = <&usbmisc 1>;
+				status = "disabled";
+			};
+
+			usbh: usb@02184400 {
+				compatible = "fsl,imx6sl-usb", "fsl,imx27-usb";
+				reg = <0x02184400 0x200>;
+				interrupts = <0 42 0x04>;
+				clocks = <&clks IMX6SL_CLK_USBOH3>;
+				fsl,usbmisc = <&usbmisc 2>;
+				status = "disabled";
+			};
+
+			usbmisc: usbmisc@02184800 {
+				#index-cells = <1>;
+				compatible = "fsl,imx6sl-usbmisc", "fsl,imx6q-usbmisc";
+				reg = <0x02184800 0x200>;
+				clocks = <&clks IMX6SL_CLK_USBOH3>;
+			};
+
+			fec: ethernet@02188000 {
+				compatible = "fsl,imx6sl-fec", "fsl,imx25-fec";
+				reg = <0x02188000 0x4000>;
+				interrupts = <0 114 0x04>;
+				clocks = <&clks IMX6SL_CLK_ENET_REF>,
+					 <&clks IMX6SL_CLK_ENET_REF>;
+				clock-names = "ipg", "ahb";
+				status = "disabled";
+			};
+
+			usdhc1: usdhc@02190000 {
+				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+				reg = <0x02190000 0x4000>;
+				interrupts = <0 22 0x04>;
+				clocks = <&clks IMX6SL_CLK_USDHC1>,
+					 <&clks IMX6SL_CLK_USDHC1>,
+					 <&clks IMX6SL_CLK_USDHC1>;
+				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
+				status = "disabled";
+			};
+
+			usdhc2: usdhc@02194000 {
+				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+				reg = <0x02194000 0x4000>;
+				interrupts = <0 23 0x04>;
+				clocks = <&clks IMX6SL_CLK_USDHC2>,
+					 <&clks IMX6SL_CLK_USDHC2>,
+					 <&clks IMX6SL_CLK_USDHC2>;
+				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
+				status = "disabled";
+			};
+
+			usdhc3: usdhc@02198000 {
+				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+				reg = <0x02198000 0x4000>;
+				interrupts = <0 24 0x04>;
+				clocks = <&clks IMX6SL_CLK_USDHC3>,
+					 <&clks IMX6SL_CLK_USDHC3>,
+					 <&clks IMX6SL_CLK_USDHC3>;
+				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
+				status = "disabled";
+			};
+
+			usdhc4: usdhc@0219c000 {
+				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+				reg = <0x0219c000 0x4000>;
+				interrupts = <0 25 0x04>;
+				clocks = <&clks IMX6SL_CLK_USDHC4>,
+					 <&clks IMX6SL_CLK_USDHC4>,
+					 <&clks IMX6SL_CLK_USDHC4>;
+				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@021a0000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
+				reg = <0x021a0000 0x4000>;
+				interrupts = <0 36 0x04>;
+				clocks = <&clks IMX6SL_CLK_I2C1>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@021a4000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
+				reg = <0x021a4000 0x4000>;
+				interrupts = <0 37 0x04>;
+				clocks = <&clks IMX6SL_CLK_I2C2>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@021a8000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx6sl-i2c", "fsl,imx21-i2c";
+				reg = <0x021a8000 0x4000>;
+				interrupts = <0 38 0x04>;
+				clocks = <&clks IMX6SL_CLK_I2C3>;
+				status = "disabled";
+			};
+
+			mmdc: mmdc@021b0000 {
+				compatible = "fsl,imx6sl-mmdc", "fsl,imx6q-mmdc";
+				reg = <0x021b0000 0x4000>;
+			};
+
+			rngb: rngb@021b4000 {
+				reg = <0x021b4000 0x4000>;
+				interrupts = <0 5 0x04>;
+			};
+
+			weim: weim@021b8000 {
+				reg = <0x021b8000 0x4000>;
+				interrupts = <0 14 0x04>;
+			};
+
+			ocotp: ocotp@021bc000 {
+				compatible = "fsl,imx6sl-ocotp";
+				reg = <0x021bc000 0x4000>;
+			};
+
+			audmux: audmux@021d8000 {
+				compatible = "fsl,imx6sl-audmux", "fsl,imx31-audmux";
+				reg = <0x021d8000 0x4000>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/imx6sl-evk.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6sl-evk.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/imx6sl-evk.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/imx6sl-evk.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "imx6sl.dtsi"
+
+/ {
+	model = "Freescale i.MX6 SoloLite EVK Board";
+	compatible = "fsl,imx6sl-evk", "fsl,imx6sl";
+
+	memory {
+		reg = <0x80000000 0x40000000>;
+	};
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec_1>;
+	phy-mode = "rmii";
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
+	hog {
+		pinctrl_hog: hoggrp {
+			fsl,pins = <
+				MX6SL_PAD_KEY_ROW7__GPIO4_IO07    0x17059
+				MX6SL_PAD_KEY_COL7__GPIO4_IO06    0x17059
+				MX6SL_PAD_SD2_DAT7__GPIO5_IO00    0x17059
+				MX6SL_PAD_SD2_DAT6__GPIO4_IO29    0x17059
+				MX6SL_PAD_REF_CLK_32K__GPIO3_IO22 0x17059
+			>;
+		};
+	};
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1_1>;
+	status = "okay";
+};
+
+&usdhc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc1_1>;
+	bus-width = <8>;
+	cd-gpios = <&gpio4 7 0>;
+	wp-gpios = <&gpio4 6 0>;
+	status = "okay";
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2_1>;
+	cd-gpios = <&gpio5 0 0>;
+	wp-gpios = <&gpio4 29 0>;
+	status = "okay";
+};
+
+&usdhc3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc3_1>;
+	cd-gpios = <&gpio3 22 0>;
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/integratorap.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/integratorap.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/integratorap.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/integratorap.dts	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,47 @@
 		valid-mask = <0x003fffff>;
 	};
 
+	pci: pciv3@62000000 {
+		compatible = "v3,v360epc-pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0x62000000 0x10000>;
+		interrupt-parent = <&pic>;
+		interrupts = <17>; /* Bus error IRQ */
+		ranges = <0x00000000 0 0x61000000 /* config space */
+			0x61000000 0 0x00100000 /* 16 MiB @ 61000000 */
+			0x01000000 0 0x0 /* I/O space */
+			0x60000000 0 0x00100000 /* 16 MiB @ 60000000 */
+			0x02000000 0 0x00000000 /* non-prefectable memory */
+			0x40000000 0 0x10000000 /* 256 MiB @ 40000000 */
+			0x42000000 0 0x10000000 /* prefetchable memory */
+			0x50000000 0 0x10000000>; /* 256 MiB @ 50000000 */
+		interrupt-map-mask = <0xf800 0 0 0x7>;
+		interrupt-map = <
+		/* IDSEL 9 */
+		0x4800 0 0 1 &pic 13 /* INT A on slot 9 is irq 13 */
+		0x4800 0 0 2 &pic 14 /* INT B on slot 9 is irq 14 */
+		0x4800 0 0 3 &pic 15 /* INT C on slot 9 is irq 15 */
+		0x4800 0 0 4 &pic 16 /* INT D on slot 9 is irq 16 */
+		/* IDSEL 10 */
+		0x5000 0 0 1 &pic 14 /* INT A on slot 10 is irq 14 */
+		0x5000 0 0 2 &pic 15 /* INT B on slot 10 is irq 15 */
+		0x5000 0 0 3 &pic 16 /* INT C on slot 10 is irq 16 */
+		0x5000 0 0 4 &pic 13 /* INT D on slot 10 is irq 13 */
+		/* IDSEL 11 */
+		0x5800 0 0 1 &pic 15 /* INT A on slot 11 is irq 15 */
+		0x5800 0 0 2 &pic 16 /* INT B on slot 11 is irq 16 */
+		0x5800 0 0 3 &pic 13 /* INT C on slot 11 is irq 13 */
+		0x5800 0 0 4 &pic 14 /* INT D on slot 11 is irq 14 */
+		/* IDSEL 12 */
+		0x6000 0 0 1 &pic 16 /* INT A on slot 12 is irq 16 */
+		0x6000 0 0 2 &pic 13 /* INT B on slot 12 is irq 13 */
+		0x6000 0 0 3 &pic 14 /* INT C on slot 12 is irq 14 */
+		0x6000 0 0 4 &pic 15 /* INT D on slot 12 is irq 15 */
+		>;
+	};
+
 	fpga {
 		/*
 		 * The Integator/AP predates the idea to have magic numbers
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/keystone.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/keystone.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/keystone.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/keystone.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2013 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "Texas Instruments Keystone 2 SoC";
+	compatible =  "ti,keystone-evm";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&gic>;
+
+	aliases {
+		serial0	= &uart0;
+	};
+
+	memory {
+		reg = <0x00000000 0x80000000 0x00000000 0x40000000>;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		interrupt-parent = <&gic>;
+
+		cpu@0 {
+			compatible = "arm,cortex-a15";
+			device_type = "cpu";
+			reg = <0>;
+		};
+
+		cpu@1 {
+			compatible = "arm,cortex-a15";
+			device_type = "cpu";
+			reg = <1>;
+		};
+
+		cpu@2 {
+			compatible = "arm,cortex-a15";
+			device_type = "cpu";
+			reg = <2>;
+		};
+
+		cpu@3 {
+			compatible = "arm,cortex-a15";
+			device_type = "cpu";
+			reg = <3>;
+		};
+	};
+
+	gic: interrupt-controller {
+		compatible = "arm,cortex-a15-gic";
+		#interrupt-cells = <3>;
+		#size-cells = <0>;
+		#address-cells = <1>;
+		interrupt-controller;
+		reg = <0x0 0x02561000 0x0 0x1000>,
+		      <0x0 0x02562000 0x0 0x2000>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <1 13 0xf08>,
+			     <1 14 0xf08>,
+			     <1 11 0xf08>,
+			     <1 10 0x308>;
+	};
+
+	pmu {
+		compatible = "arm,cortex-a15-pmu";
+		interrupts = <0 20 0xf01>,
+			     <0 21 0xf01>,
+			     <0 22 0xf01>,
+			     <0 23 0xf01>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "ti,keystone","simple-bus";
+		interrupt-parent = <&gic>;
+		ranges = <0x0 0x0 0x0 0xc0000000>;
+
+		rstctrl: reset-controller {
+			compatible = "ti,keystone-reset";
+			reg = <0x023100e8 4>;	/* pll reset control reg */
+		};
+
+		uart0: serial@02530c00 {
+			compatible = "ns16550a";
+			current-speed = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			reg = <0x02530c00 0x100>;
+			clock-frequency = <133120000>;
+			interrupts = <0 277 0xf01>;
+		};
+
+		uart1:	serial@02531000 {
+			compatible = "ns16550a";
+			current-speed = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			reg = <0x02531000 0x100>;
+			clock-frequency = <133120000>;
+			interrupts = <0 280 0xf01>;
+		};
+
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-6281.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-6281.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-6281.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-6281.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -40,5 +40,64 @@
 				marvell,function = "sdio";
 			};
 		};
+
+		pcie-controller {
+			compatible = "marvell,kirkwood-pcie";
+			status = "disabled";
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			bus-range = <0x00 0xff>;
+
+			ranges = <0x82000000 0 0x00040000 0x00040000 0 0x00002000   /* Port 0.0 registers */
+				  0x82000000 0 0xe0000000 0xe0000000 0 0x08000000   /* non-prefetchable memory */
+			          0x81000000 0 0          0xe8000000 0 0x00100000>; /* downstream I/O */
+
+			pcie@1,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>;
+				reg = <0x0800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &intc 9>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gate_clk 2>;
+				status = "disabled";
+			};
+		};
+
+		rtc@10300 {
+			compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
+			reg = <0x10300 0x20>;
+			interrupts = <53>;
+			clocks = <&gate_clk 7>;
+		};
+
+		sata@80000 {
+			compatible = "marvell,orion-sata";
+			reg = <0x80000 0x5000>;
+			interrupts = <21>;
+			clocks = <&gate_clk 14>, <&gate_clk 15>;
+			clock-names = "0", "1";
+			status = "disabled";
+		};
+
+		mvsdio@90000 {
+			compatible = "marvell,orion-sdio";
+			reg = <0x90000 0x200>;
+			interrupts = <28>;
+			clocks = <&gate_clk 4>;
+			bus-width = <4>;
+			cap-sdio-irq;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			status = "disabled";
+		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-6282.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-6282.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-6282.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-6282.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -49,6 +49,34 @@
 			};
 		};
 
+		rtc@10300 {
+			compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
+			reg = <0x10300 0x20>;
+			interrupts = <53>;
+			clocks = <&gate_clk 7>;
+		};
+
+		sata@80000 {
+			compatible = "marvell,orion-sata";
+			reg = <0x80000 0x5000>;
+			interrupts = <21>;
+			clocks = <&gate_clk 14>, <&gate_clk 15>;
+			clock-names = "0", "1";
+			status = "disabled";
+		};
+
+		mvsdio@90000 {
+			compatible = "marvell,orion-sdio";
+			reg = <0x90000 0x200>;
+			interrupts = <28>;
+			clocks = <&gate_clk 4>;
+			bus-width = <4>;
+			cap-sdio-irq;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			status = "disabled";
+		};
+
 		thermal@10078 {
 			compatible = "marvell,kirkwood-thermal";
 			reg = <0x10078 0x4>;
@@ -65,5 +93,53 @@
 			clocks = <&gate_clk 7>;
 			status = "disabled";
 		};
+
+		pcie-controller {
+			compatible = "marvell,kirkwood-pcie";
+			status = "disabled";
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			bus-range = <0x00 0xff>;
+
+			ranges = <0x82000000 0 0x00040000 0x00040000 0 0x00002000   /* Port 0.0 registers */
+			          0x82000000 0 0x00044000 0x00044000 0 0x00002000   /* Port 1.0 registers */
+				  0x82000000 0 0xe0000000 0xe0000000 0 0x08000000   /* non-prefetchable memory */
+			          0x81000000 0 0          0xe8000000 0 0x00100000>; /* downstream I/O */
+
+			pcie@1,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>;
+				reg = <0x0800 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &intc 9>;
+				marvell,pcie-port = <0>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gate_clk 2>;
+				status = "disabled";
+			};
+
+			pcie@2,0 {
+				device_type = "pci";
+				assigned-addresses = <0x82001000 0 0x00044000 0 0x2000>;
+				reg = <0x1000 0 0 0 0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+				ranges;
+				interrupt-map-mask = <0 0 0 0>;
+				interrupt-map = <0 0 0 0 &intc 10>;
+				marvell,pcie-port = <1>;
+				marvell,pcie-lane = <0>;
+				clocks = <&gate_clk 18>;
+				status = "disabled";
+			};
+		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-cloudbox.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-cloudbox.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-cloudbox.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-cloudbox.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,10 +18,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-			pinctrl-0 = < &pmx_spi &pmx_uart0
-					&pmx_cloudbox_sata0 >;
-			pinctrl-names = "default";
-
 			pmx_cloudbox_sata0: pmx-cloudbox-sata0 {
 				marvell,pins = "mpp15";
 				marvell,function = "sata0";
@@ -29,16 +25,22 @@
 		};
 
 		serial@12000 {
+			pinctrl-0 = <&pmx_uart0>;
+			pinctrl-names = "default";
 			clock-frequency = <166666667>;
 			status = "okay";
 		};
 
 		sata@80000 {
+			pinctrl-0 = <&pmx_cloudbox_sata0>;
+			pinctrl-names = "default";
 			status = "okay";
 			nr-ports = <1>;
 		};
 
 		spi@10600 {
+			pinctrl-0 = <&pmx_spi>;
+			pinctrl-names = "default";
 			status = "okay";
 
 			flash@0 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-db-88f6281.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-db-88f6281.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-db-88f6281.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-db-88f6281.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,30 @@
+/*
+ * Marvell DB-88F6281-BP Development Board Setup
+ *
+ * Saeed Bishara <saeed@marvell.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+/include/ "kirkwood-db.dtsi"
+/include/ "kirkwood-6281.dtsi"
+
+/ {
+	model = "Marvell DB-88F6281-BP Development Board";
+	compatible = "marvell,db-88f6281-bp", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	ocp@f1000000 {
+		pcie-controller {
+			status = "okay";
+
+			pcie@1,0 {
+				status = "okay";
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-db-88f6282.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-db-88f6282.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-db-88f6282.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-db-88f6282.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,34 @@
+/*
+ * Marvell DB-88F6282-BP Development Board Setup
+ *
+ * Saeed Bishara <saeed@marvell.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+/include/ "kirkwood-db.dtsi"
+/include/ "kirkwood-6282.dtsi"
+
+/ {
+	model = "Marvell DB-88F6282-BP Development Board";
+	compatible = "marvell,db-88f6282-bp", "marvell,kirkwood-88f6282", "marvell,kirkwood";
+
+	ocp@f1000000 {
+		pcie-controller {
+			status = "okay";
+
+			pcie@1,0 {
+				status = "okay";
+			};
+
+			pcie@2,0 {
+				status = "okay";
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-db.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-db.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-db.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-db.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,89 @@
+/*
+ * Marvell DB-{88F6281,88F6282}-BP Development Board Setup
+ *
+ * Saeed Bishara <saeed@marvell.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * This file contains the definitions that are common between the 6281
+ * and 6282 variants of the Marvell Kirkwood Development Board.
+ */
+
+/include/ "kirkwood.dtsi"
+
+/ {
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>; /* 512 MB */
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8 earlyprintk";
+	};
+
+	ocp@f1000000 {
+		pinctrl@10000 {
+			pmx_sdio_gpios: pmx-sdio-gpios {
+				marvell,pins = "mpp37", "mpp38";
+				marvell,function = "gpio";
+			};
+		};
+
+		serial@12000 {
+			pinctrl-0 = <&pmx_uart0>;
+			pinctrl-names = "default";
+			clock-frequency = <200000000>;
+			status = "ok";
+		};
+
+		nand@3000000 {
+			pinctrl-0 = <&pmx_nand>;
+			pinctrl-names = "default";
+			chip-delay = <25>;
+			status = "okay";
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x100000>;
+			};
+
+			partition@100000 {
+				label = "uImage";
+				reg = <0x100000 0x400000>;
+			};
+
+			partition@500000 {
+				label = "root";
+				reg = <0x500000 0x1fb00000>;
+			};
+		};
+
+		sata@80000 {
+			nr-ports = <2>;
+			status = "okay";
+		};
+
+		ehci@50000 {
+			status = "okay";
+		};
+
+		mvsdio@90000 {
+			pinctrl-0 = <&pmx_sdio_gpios>;
+			pinctrl-names = "default";
+			wp-gpios = <&gpio1 5 0>;
+			cd-gpios = <&gpio1 6 0>;
+			status = "okay";
+		};
+
+		pcie-controller {
+			status = "okay";
+
+			pcie@1,0 {
+				status = "okay";
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dns320.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dns320.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dns320.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dns320.dts	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,11 @@
 
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_power &pmx_led_red_usb_320
+			     &pmx_led_red_left_hdd &pmx_led_red_right_hdd
+			     &pmx_led_white_usb>;
+		pinctrl-names = "default";
+
 		blue-power {
 			label = "dns320:blue:power";
 			gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */
@@ -46,6 +51,8 @@
 		};
 
 		serial@12100 {
+			pinctrl-0 = <&pmx_uart1>;
+			pinctrl-names = "default";
 			status = "okay";
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dns325.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dns325.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dns325.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dns325.dts	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,11 @@
 
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_power &pmx_led_red_usb_325
+			     &pmx_led_red_left_hdd &pmx_led_red_right_hdd
+			     &pmx_led_white_usb>;
+		pinctrl-names = "default";
+
 		white-power {
 			label = "dns325:white:power";
 			gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dnskw.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dnskw.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dnskw.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dnskw.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,10 @@
 		compatible = "gpio-keys";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_button_power &pmx_button_unmount
+			     &pmx_button_reset>;
+		pinctrl-names = "default";
+
 		button@1 {
 			label = "Power button";
 			linux,code = <116>;
@@ -29,6 +33,8 @@
 	gpio_fan {
 		/* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */
 		compatible = "gpio-fan";
+		pinctrl-0 = <&pmx_fan_high_speed &pmx_fan_low_speed>;
+		pinctrl-names = "default";
 		gpios = <&gpio1 14 1
 			 &gpio1 13 1>;
 		gpio-fan,speed-map = <0    0
@@ -38,27 +44,17 @@
 
 	gpio_poweroff {
 		compatible = "gpio-poweroff";
+		pinctrl-0 = <&pmx_power_off>;
+		pinctrl-names = "default";
 		gpios = <&gpio1 4 0>;
 	};
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
 
-			pinctrl-0 = < &pmx_nand &pmx_uart1
-				      &pmx_sata0 &pmx_sata1
-				      &pmx_led_power
-				      &pmx_led_red_right_hdd
-				      &pmx_led_red_left_hdd
-				      &pmx_led_red_usb_325
-				      &pmx_button_power
-				      &pmx_led_red_usb_320
-				      &pmx_power_off &pmx_power_back_on
-				      &pmx_power_sata0 &pmx_power_sata1
-				      &pmx_present_sata0 &pmx_present_sata1
-				      &pmx_led_white_usb &pmx_fan_tacho
-				      &pmx_fan_high_speed &pmx_fan_low_speed
-				      &pmx_button_unmount &pmx_button_reset
-				      &pmx_temp_alarm >;
+			pinctrl-0 = <&pmx_power_back_on &pmx_present_sata0
+				     &pmx_present_sata1 &pmx_fan_tacho
+				     &pmx_temp_alarm>;
 			pinctrl-names = "default";
 
 			pmx_sata0: pmx-sata0 {
@@ -147,11 +143,15 @@
 			};
 		};
 		sata@80000 {
+			pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+			pinctrl-names = "default";
 			status = "okay";
 			nr-ports = <2>;
 		};
 
 		nand@3000000 {
+			pinctrl-0 = <&pmx_nand>;
+			pinctrl-names = "default";
 			status = "okay";
 			chip-delay = <35>;
 
@@ -192,6 +192,8 @@
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_power_sata0 &pmx_power_sata1>;
+		pinctrl-names = "default";
 
 		sata0_power: regulator@1 {
 			compatible = "regulator-fixed";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dockstar.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dockstar.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dockstar.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dockstar.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,11 +18,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_usb_power_enable
-				      &pmx_led_green &pmx_led_orange >;
-			pinctrl-names = "default";
-
 			pmx_usb_power_enable: pmx-usb-power-enable {
 				marvell,pins = "mpp29";
 				marvell,function = "gpio";
@@ -62,6 +57,8 @@
 	};
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_green &pmx_led_orange>;
+		pinctrl-names = "default";
 
 		health {
 			label = "status:green:health";
@@ -77,6 +74,8 @@
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_usb_power_enable>;
+		pinctrl-names = "default";
 
 		usb_power: regulator@1 {
 			compatible = "regulator-fixed";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dreamplug.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dreamplug.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-dreamplug.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-dreamplug.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,12 +18,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_spi
-				      &pmx_led_bluetooth &pmx_led_wifi
-				      &pmx_led_wifi_ap >;
-			pinctrl-names = "default";
-
 			pmx_led_bluetooth: pmx-led-bluetooth {
 				marvell,pins = "mpp47";
 				marvell,function = "gpio";
@@ -43,6 +37,8 @@
 
 		spi@10600 {
 			status = "okay";
+			pinctrl-0 = <&pmx_spi>;
+			pinctrl-names = "default";
 
 			m25p40@0 {
 				#address-cells = <1>;
@@ -79,11 +75,15 @@
 			pinctrl-names = "default";
 			status = "okay";
 			/* No CD or WP GPIOs */
+			broken-cd;
 		};
 	};
 
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_bluetooth &pmx_led_wifi
+			     &pmx_led_wifi_ap >;
+		pinctrl-names = "default";
 
 		bluetooth {
 			label = "dreamplug:blue:bluetooth";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -4,6 +4,18 @@
 	compatible = "marvell,kirkwood";
 	interrupt-parent = <&intc>;
 
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "marvell,feroceon";
+			clocks = <&core_clk 1>, <&core_clk 3>, <&gate_clk 11>;
+			clock-names = "cpu_clk", "ddrclk", "powersave";
+		};
+	};
+
 	aliases {
 	       gpio0 = &gpio0;
 	       gpio1 = &gpio1;
@@ -18,7 +30,9 @@
 
 	ocp@f1000000 {
 		compatible = "simple-bus";
-		ranges = <0x00000000 0xf1000000 0x4000000
+		ranges = <0x00000000 0xf1000000 0x0100000
+		          0xe0000000 0xe0000000 0x8100000 /* PCIE */
+		          0xf4000000 0xf4000000 0x0000400
 		          0xf5000000 0xf5000000 0x0000400>;
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -71,13 +85,6 @@
 			status = "disabled";
 		};
 
-		rtc@10300 {
-			compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
-			reg = <0x10300 0x20>;
-			interrupts = <53>;
-			clocks = <&gate_clk 7>;
-		};
-
 		spi@10600 {
 			compatible = "marvell,orion-spi";
 			#address-cells = <1>;
@@ -151,15 +158,6 @@
 			status = "okay";
 		};
 
-		sata@80000 {
-			compatible = "marvell,orion-sata";
-			reg = <0x80000 0x5000>;
-			interrupts = <21>;
-			clocks = <&gate_clk 14>, <&gate_clk 15>;
-			clock-names = "0", "1";
-			status = "disabled";
-		};
-
 		nand@3000000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -167,7 +165,7 @@
 			ale = <1>;
 			bank-width = <1>;
 			compatible = "marvell,orion-nand";
-			reg = <0x3000000 0x400>;
+			reg = <0xf4000000 0x400>;
 			chip-delay = <25>;
 			/* set partition map and/or chip-delay in board dts */
 			clocks = <&gate_clk 7>;
@@ -194,13 +192,5 @@
 			clocks = <&gate_clk 17>;
 			status = "okay";
 		};
-
-		mvsdio@90000 {
-			compatible = "marvell,orion-sdio";
-			reg = <0x90000 0x200>;
-			interrupts = <28>;
-			clocks = <&gate_clk 4>;
-			status = "disabled";
-		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-goflexnet.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-goflexnet.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-goflexnet.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-goflexnet.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,15 +18,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_usb_power_enable &pmx_led_orange
-				      &pmx_led_left_cap_0 &pmx_led_left_cap_1
-				      &pmx_led_left_cap_2 &pmx_led_left_cap_3
-				      &pmx_led_right_cap_0 &pmx_led_right_cap_1
-				      &pmx_led_right_cap_2 &pmx_led_right_cap_3
-				    >;
-			pinctrl-names = "default";
-
 			pmx_usb_power_enable: pmx-usb-power-enable {
 				marvell,pins = "mpp29";
 				marvell,function = "gpio";
@@ -109,6 +100,13 @@
 	};
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = < &pmx_led_orange
+			      &pmx_led_left_cap_0 &pmx_led_left_cap_1
+			      &pmx_led_left_cap_2 &pmx_led_left_cap_3
+			      &pmx_led_right_cap_0 &pmx_led_right_cap_1
+			      &pmx_led_right_cap_2 &pmx_led_right_cap_3
+			    >;
+		pinctrl-names = "default";
 
 		health {
 			label = "status:green:health";
@@ -156,6 +154,8 @@
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_usb_power_enable>;
+		pinctrl-names = "default";
 
 		usb_power: regulator@1 {
 			compatible = "regulator-fixed";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,11 +18,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_led_health_r &pmx_led_health_g
-				      &pmx_led_wmode_r &pmx_led_wmode_g >;
-			pinctrl-names = "default";
-
 			pmx_led_health_r: pmx-led-health-r {
 				marvell,pins = "mpp46";
 				marvell,function = "gpio";
@@ -72,11 +67,16 @@
 
 		mvsdio@90000 {
 			status = "okay";
+			/* No CD or WP GPIOs */
+			broken-cd;
 		};
 	};
 
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = < &pmx_led_health_r &pmx_led_health_g
+			      &pmx_led_wmode_r &pmx_led_wmode_g >;
+		pinctrl-names = "default";
 
 		health-r {
 			label = "guruplug:red:health";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ib62x0.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ib62x0.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ib62x0.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ib62x0.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,13 +18,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_nand
-				      &pmx_led_os_red &pmx_power_off
-				      &pmx_led_os_green &pmx_led_usb_transfer
-				      &pmx_button_reset &pmx_button_usb_copy >;
-			pinctrl-names = "default";
-
 			pmx_led_os_red: pmx-led-os-red {
 				marvell,pins = "mpp22";
 				marvell,function = "gpio";
@@ -61,6 +54,8 @@
 
 		nand@3000000 {
 			status = "okay";
+			pinctrl-0 = <&pmx_nand>;
+			pinctrl-names = "default";
 
 			partition@0 {
 				label = "u-boot";
@@ -84,6 +79,9 @@
 		compatible = "gpio-keys";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_button_reset &pmx_button_usb_copy>;
+		pinctrl-names = "default";
+
 		button@1 {
 			label = "USB Copy";
 			linux,code = <133>;
@@ -97,6 +95,9 @@
 	};
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_os_red &pmx_led_os_green
+			     &pmx_led_usb_transfer>;
+		pinctrl-names = "default";
 
 		green-os {
 			label = "ib62x0:green:os";
@@ -114,6 +115,8 @@
 	};
 	gpio_poweroff {
 		compatible = "gpio-poweroff";
+		pinctrl-0 = <&pmx_power_off>;
+		pinctrl-names = "default";
 		gpios = <&gpio0 24 0>;
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-iconnect.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-iconnect.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-iconnect.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-iconnect.dts	2013-08-25 20:43:22.000000000 -0400
@@ -20,51 +20,43 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_gpio_12 &pmx_gpio_35
-				      &pmx_gpio_41 &pmx_gpio_42
-				      &pmx_gpio_43 &pmx_gpio_44
-				      &pmx_gpio_45 &pmx_gpio_46
-				      &pmx_gpio_47 &pmx_gpio_48 >;
-			pinctrl-names = "default";
-
-			pmx_gpio_12: pmx-gpio-12 {
+			pmx_button_reset: pmx-button-reset {
 				marvell,pins = "mpp12";
 				marvell,function = "gpio";
 			};
-			pmx_gpio_35: pmx-gpio-35 {
+			pmx_button_otb: pmx-button-otb {
 				marvell,pins = "mpp35";
 				marvell,function = "gpio";
 			};
-			pmx_gpio_41: pmx-gpio-41 {
+			pmx_led_level: pmx-led-level {
 				marvell,pins = "mpp41";
 				marvell,function = "gpio";
 			};
-			pmx_gpio_42: pmx-gpio-42 {
+			pmx_led_power_blue: pmx-led-power-blue {
 				marvell,pins = "mpp42";
 				marvell,function = "gpio";
 			};
-			pmx_gpio_43: pmx-gpio-43 {
+			pmx_led_power_red: pmx-power-red {
 				marvell,pins = "mpp43";
 				marvell,function = "gpio";
 			};
-			pmx_gpio_44: pmx-gpio-44 {
+			pmx_led_usb1: pmx-led-usb1 {
 				marvell,pins = "mpp44";
 				marvell,function = "gpio";
 			};
-			pmx_gpio_45: pmx-gpio-45 {
+			pmx_led_usb2: pmx-led-usb2 {
 				marvell,pins = "mpp45";
 				marvell,function = "gpio";
 			};
-			pmx_gpio_46: pmx-gpio-46 {
+			pmx_led_usb3: pmx-led-usb3 {
 				marvell,pins = "mpp46";
 				marvell,function = "gpio";
 			};
-			pmx_gpio_47: pmx-gpio-47 {
+			pmx_led_usb4: pmx-led-usb4 {
 				marvell,pins = "mpp47";
 				marvell,function = "gpio";
 			};
-			pmx_gpio_48: pmx-gpio-48 {
+			pmx_led_otb: pmx-led-otb {
 				marvell,pins = "mpp48";
 				marvell,function = "gpio";
 			};
@@ -109,10 +101,23 @@
 				reg = <0x980000 0x1f400000>;
 			};
 		};
+
+		pcie-controller {
+			status = "okay";
+
+			pcie@1,0 {
+				status = "okay";
+			};
+		};
 	};
 
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = < &pmx_led_level &pmx_led_power_blue
+			      &pmx_led_power_red &pmx_led_usb1
+			      &pmx_led_usb2 &pmx_led_usb3
+			      &pmx_led_usb4 &pmx_led_otb >;
+		pinctrl-names = "default";
 
 		led-level {
 			label = "led_level";
@@ -154,6 +159,9 @@
 		compatible = "gpio-keys";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = < &pmx_button_reset &pmx_button_otb >;
+		pinctrl-names = "default";
+
 		button@1 {
 			label = "OTB Button";
 			linux,code = <133>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,12 +18,7 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_button_reset &pmx_button_power
-				      &pmx_led_backup &pmx_led_power
-				      &pmx_button_otb &pmx_led_rebuild
-				      &pmx_led_health
-				      &pmx_led_sata_brt_ctrl_1
+			pinctrl-0 = < &pmx_led_sata_brt_ctrl_1
 				      &pmx_led_sata_brt_ctrl_2
 				      &pmx_led_backup_brt_ctrl_1
 				      &pmx_led_backup_brt_ctrl_2
@@ -151,6 +146,9 @@
 	};
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = < &pmx_led_backup &pmx_led_power
+			      &pmx_led_rebuild &pmx_led_health >;
+		pinctrl-names = "default";
 
 		power_led {
 			label = "status:white:power_led";
@@ -174,6 +172,11 @@
 		compatible = "gpio-keys";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_button_reset &pmx_button_power
+			     &pmx_button_otb>;
+		pinctrl-names = "default";
+
+
 		Power {
 			label = "Power Button";
 			linux,code = <116>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-is2.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-is2.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-is2.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-is2.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,8 @@
 
 	ocp@f1000000 {
 		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0>;
+			pinctrl-names = "default";
 			status = "okay";
 			nr-ports = <1>;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-km_kirkwood.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-km_kirkwood.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-km_kirkwood.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,9 +18,7 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_nand &pmx_i2c_gpio_sda
-				&pmx_i2c_gpio_scl >;
+			pinctrl-0 = < &pmx_i2c_gpio_sda &pmx_i2c_gpio_scl >;
 			pinctrl-names = "default";
 
 			pmx_i2c_gpio_sda: pmx-gpio-sda {
@@ -38,8 +36,17 @@
 		};
 
 		nand@3000000 {
+			pinctrl-0 = <&pmx_nand>;
+			pinctrl-names = "default";
 			status = "ok";
 			chip-delay = <25>;
 		};
 	};
+
+	i2c@0 {
+		compatible = "i2c-gpio";
+		gpios = < &gpio0 8 0		/* sda */
+			&gpio0 9 0 >;		/* scl */
+		i2c-gpio,delay-us = <2>;	/* ~100 kHz */
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-lsxl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-lsxl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-lsxl.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-lsxl.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,16 +8,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_power_hdd &pmx_usb_vbus
-				      &pmx_fan_low &pmx_fan_high
-				      &pmx_led_function_red &pmx_led_alarm
-				      &pmx_led_info &pmx_led_power
-				      &pmx_fan_lock &pmx_button_function
-				      &pmx_power_switch &pmx_power_auto_switch
-				      &pmx_led_function_blue >;
-			pinctrl-names = "default";
-
 			pmx_power_hdd: pmx-power-hdd {
 				marvell,pins = "mpp10";
 				marvell,function = "gpo";
@@ -112,6 +102,10 @@
 		compatible = "gpio-keys";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_button_function &pmx_power_switch
+			     &pmx_power_auto_switch>;
+		pinctrl-names = "default";
+
 		button@1 {
 			label = "Function Button";
 			linux,code = <357>;
@@ -133,6 +127,10 @@
 
 	gpio_leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm
+			     &pmx_led_info &pmx_led_power
+			     &pmx_led_function_blue>;
+		pinctrl-names = "default";
 
 		led@1 {
 			label = "lsxl:blue:func";
@@ -163,6 +161,8 @@
 
 	gpio_fan {
 		compatible = "gpio-fan";
+		pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>;
+		pinctrl-names = "default";
 		gpios = <&gpio0 19 1
 		         &gpio0 18 1>;
 		gpio-fan,speed-map = <0    3
@@ -172,10 +172,16 @@
 		alarm-gpios = <&gpio1 8 0>;
 	};
 
+	restart_poweroff {
+		compatible = "restart-poweroff";
+	};
+
 	regulators {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_power_hdd &pmx_usb_vbus>;
+		pinctrl-names = "default";
 
 		usb_power: regulator@1 {
 			compatible = "regulator-fixed";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-mplcec4.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-mplcec4.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-mplcec4.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-mplcec4.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,16 +18,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_nand &pmx_uart0
-				      &pmx_led_health
-				      &pmx_sata0 &pmx_sata1
-				      &pmx_led_user1o
-				      &pmx_led_user1g &pmx_led_user0o
-				      &pmx_led_user0g &pmx_led_misc
-				    >;
-			pinctrl-names = "default";
-
 			pmx_led_health: pmx-led-health {
 				marvell,pins = "mpp7";
 				marvell,function = "gpo";
@@ -91,9 +81,13 @@
 
                 serial@12000 {
                         status = "ok";
+                        pinctrl-0 = <&pmx_uart0>;
+                        pinctrl-names = "default";
                 };
 
                 nand@3000000 {
+                        pinctrl-0 = <&pmx_nand>;
+                        pinctrl-names = "default";
                         status = "okay";
 
                         partition@0 {
@@ -127,22 +121,37 @@
 		};
 
 		sata@80000 {
+			pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+			pinctrl-names = "default";
 			nr-ports = <2>;
 			status = "okay";
-
 		};
 
 		mvsdio@90000 {
 			pinctrl-0 = <&pmx_sdio &pmx_sdio_cd>;
 			pinctrl-names = "default";
 			status = "okay";
-			cd-gpios = <&gpio1 15 0>;
+			cd-gpios = <&gpio1 15 1>;
 			/* No WP GPIO */
 		};
+
+		pcie-controller {
+			status = "okay";
+
+			pcie@1,0 {
+				status = "okay";
+			};
+		};
 	};
 
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = < &pmx_led_health
+			      &pmx_led_user1o
+			      &pmx_led_user1g &pmx_led_user0o
+			      &pmx_led_user0g &pmx_led_misc
+			    >;
+		pinctrl-names = "default";
 
 		health {
 			label = "status:green:health";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,18 +18,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-
-			pinctrl-0 = < &pmx_uart0
-				      &pmx_button_power
-				      &pmx_button_backup
-				      &pmx_button_reset
-				      &pmx_led_blue_power
-				      &pmx_led_blue_activity
-				      &pmx_led_blue_disk1
-				      &pmx_led_blue_disk2
-				      &pmx_led_blue_backup >;
-			pinctrl-names = "default";
-
 			pmx_button_power: pmx-button-power {
 				marvell,pins = "mpp47";
 				marvell,function = "gpio";
@@ -74,6 +62,8 @@
 		};
 
 		serial@12000 {
+			pinctrl-0 = <&pmx_uart0>;
+			pinctrl-names = "default";
 			status = "okay";
 		};
 
@@ -111,10 +101,22 @@
 			status = "okay";
 			nr-ports = <2>;
 		};
+
+		pcie-controller {
+			status = "okay";
+
+			pcie@1,0 {
+				status = "okay";
+			};
+		};
 	};
 
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = < &pmx_led_blue_power &pmx_led_blue_activity
+			      &pmx_led_blue_disk1 &pmx_led_blue_disk2
+			      &pmx_led_blue_backup >;
+		pinctrl-names = "default";
 
 		power_led {
 			label = "status:blue:power_led";
@@ -143,6 +145,10 @@
 		compatible = "gpio-keys";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_button_power &pmx_button_backup
+			     &pmx_button_reset>;
+		pinctrl-names = "default";
+
 		button@1 {
 			label = "Power Button";
 			linux,code = <116>;     /* KEY_POWER */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2-common.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2-common.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2-common.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2-common.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,10 +8,6 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-			pinctrl-0 = < &pmx_spi &pmx_twsi0 &pmx_uart0
-					&pmx_ns2_sata0 &pmx_ns2_sata1>;
-			pinctrl-names = "default";
-
 			pmx_ns2_sata0: pmx-ns2-sata0 {
 				marvell,pins = "mpp21";
 				marvell,function = "sata0";
@@ -23,10 +19,14 @@
 		};
 
 		serial@12000 {
+			pinctrl-0 = <&pmx_uart0>;
+			pinctrl-names = "default";
 			status = "okay";
 		};
 
 		spi@10600 {
+			pinctrl-0 = <&pmx_spi>;
+			pinctrl-names = "default";
 			status = "okay";
 
 			flash@0 {
@@ -45,6 +45,8 @@
 		};
 
 		i2c@11000 {
+			pinctrl-0 = <&pmx_twsi0>;
+			pinctrl-names = "default";
 			status = "okay";
 
 			eeprom@50 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,8 @@
 
 	ocp@f1000000 {
 		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0>;
+			pinctrl-names = "default";
 			status = "okay";
 			nr-ports = <1>;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2lite.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2lite.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2lite.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2lite.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,8 @@
 
 	ocp@f1000000 {
 		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0>;
+			pinctrl-names = "default";
 			status = "okay";
 			nr-ports = <1>;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2max.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2max.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2max.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2max.dts	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,8 @@
 
 	ocp@f1000000 {
 		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0 &pmx_ns2_sata1>;
+			pinctrl-names = "default";
 			status = "okay";
 			nr-ports = <2>;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2mini.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2mini.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ns2mini.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ns2mini.dts	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,8 @@
 
 	ocp@f1000000 {
 		sata@80000 {
+			pinctrl-0 = <&pmx_ns2_sata0>;
+			pinctrl-names = "default";
 			status = "okay";
 			nr-ports = <1>;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-nsa310.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-nsa310.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-nsa310.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-nsa310.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	model = "ZyXEL NSA310";
@@ -17,22 +18,7 @@
 
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
-			pinctrl-0 = < &pmx_led_esata_green
-				      &pmx_led_esata_red
-				      &pmx_led_usb_green
-				      &pmx_led_usb_red
-				      &pmx_usb_power_off
-				      &pmx_led_sys_green
-				      &pmx_led_sys_red
-				      &pmx_btn_reset
-				      &pmx_btn_copy
-				      &pmx_led_copy_green
-				      &pmx_led_copy_red
-				      &pmx_led_hdd_green
-				      &pmx_led_hdd_red
-				      &pmx_unknown
-				      &pmx_btn_power
-				      &pmx_pwr_off >;
+			pinctrl-0 = <&pmx_unknown>;
 			pinctrl-names = "default";
 
 			pmx_led_esata_green: pmx-led-esata-green {
@@ -176,12 +162,22 @@
 				reg = <0x5040000 0x2fc0000>;
 			};
 		};
+
+		pcie-controller {
+			status = "okay";
+
+			pcie@1,0 {
+				status = "okay";
+			};
+		};
 	};
 
 	gpio_keys {
 		compatible = "gpio-keys";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_btn_reset &pmx_btn_copy &pmx_btn_power>;
+		pinctrl-names = "default";
 
 		button@1 {
 			label = "Power Button";
@@ -202,6 +198,12 @@
 
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_esata_green &pmx_led_esata_red
+			     &pmx_led_usb_green &pmx_led_usb_red
+			     &pmx_led_sys_green &pmx_led_sys_red
+			     &pmx_led_copy_green &pmx_led_copy_red
+			     &pmx_led_hdd_green &pmx_led_hdd_red>;
+		pinctrl-names = "default";
 
 		green-sys {
 			label = "nsa310:green:sys";
@@ -247,6 +249,8 @@
 
 	gpio_poweroff {
 		compatible = "gpio-poweroff";
+		pinctrl-0 = <&pmx_pwr_off>;
+		pinctrl-names = "default";
 		gpios = <&gpio1 16 0>;
 	};
 
@@ -254,6 +258,8 @@
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_usb_power_off>;
+		pinctrl-names = "default";
 
 		usb0_power_off: regulator@1 {
 			compatible = "regulator-fixed";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-openblocks_a6.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-openblocks_a6.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-openblocks_a6.dts	2013-08-25 20:43:22.000000000 -0400
@@ -19,15 +19,21 @@
 	ocp@f1000000 {
 		serial@12000 {
 			status = "ok";
+			pinctrl-0 = <&pmx_uart0>;
+			pinctrl-names = "default";
 		};
 
 		serial@12100 {
 			status = "ok";
+			pinctrl-0 = <&pmx_uart1>;
+			pinctrl-names = "default";
 		};
 
 		nand@3000000 {
 			chip-delay = <25>;
 			status = "okay";
+			pinctrl-0 = <&pmx_nand>;
+			pinctrl-names = "default";
 
 			partition@0 {
 				label = "uboot";
@@ -67,6 +73,8 @@
 
 		i2c@11100 {
 			status = "okay";
+			pinctrl-0 = <&pmx_twsi1>;
+			pinctrl-names = "default";
 
 			s35390a: s35390a@30 {
 				compatible = "s35390a";
@@ -75,16 +83,7 @@
 		};
 
 		pinctrl: pinctrl@10000 {
-			pinctrl-0 = < &pmx_nand &pmx_uart0
-				&pmx_uart1 &pmx_twsi1
-				&pmx_dip_sw0 &pmx_dip_sw1
-				&pmx_dip_sw2 &pmx_dip_sw3
-				&pmx_gpio_0 &pmx_gpio_1
-				&pmx_gpio_2 &pmx_gpio_3
-				&pmx_gpio_4 &pmx_gpio_5
-				&pmx_gpio_6 &pmx_gpio_7
-				&pmx_led_red &pmx_led_green
-				&pmx_led_yellow >;
+			pinctrl-0 = <&pmx_dip_switches &pmx_gpio_header>;
 			pinctrl-names = "default";
 
 			pmx_uart0: pmx-uart0 {
@@ -104,63 +103,14 @@
 				marvell,function = "sysrst";
 			};
 
-			pmx_dip_sw0: pmx-dip-sw0 {
-				marvell,pins = "mpp20";
-				marvell,function = "gpio";
-			};
-
-			pmx_dip_sw1: pmx-dip-sw1 {
-				marvell,pins = "mpp21";
-				marvell,function = "gpio";
-			};
-
-			pmx_dip_sw2: pmx-dip-sw2 {
-				marvell,pins = "mpp22";
-				marvell,function = "gpio";
-			};
-
-			pmx_dip_sw3: pmx-dip-sw3 {
-				marvell,pins = "mpp23";
-				marvell,function = "gpio";
-			};
-
-			pmx_gpio_0: pmx-gpio-0 {
-				marvell,pins = "mpp24";
-				marvell,function = "gpio";
-			};
-
-			pmx_gpio_1: pmx-gpio-1 {
-				marvell,pins = "mpp25";
-				marvell,function = "gpio";
-			};
-
-			pmx_gpio_2: pmx-gpio-2 {
-				marvell,pins = "mpp26";
-				marvell,function = "gpio";
-			};
-
-			pmx_gpio_3: pmx-gpio-3 {
-				marvell,pins = "mpp27";
-				marvell,function = "gpio";
-			};
-
-			pmx_gpio_4: pmx-gpio-4 {
-				marvell,pins = "mpp28";
-				marvell,function = "gpio";
-			};
-
-			pmx_gpio_5: pmx-gpio-5 {
-				marvell,pins = "mpp29";
-				marvell,function = "gpio";
-			};
-
-			pmx_gpio_6: pmx-gpio-6 {
-				marvell,pins = "mpp30";
+			pmx_dip_switches: pmx-dip-switches {
+				marvell,pins = "mpp20", "mpp21", "mpp22", "mpp23";
 				marvell,function = "gpio";
 			};
 
-			pmx_gpio_7: pmx-gpio-7 {
-				marvell,pins = "mpp31";
+			pmx_gpio_header: pmx-gpio-header {
+				marvell,pins = "mpp24", "mpp25", "mpp26", "mpp27",
+					       "mpp28", "mpp29", "mpp30", "mpp31";
 				marvell,function = "gpio";
 			};
 
@@ -174,18 +124,8 @@
 				marvell,function = "gpio";
 			};
 
-			pmx_led_red: pmx-led-red {
-				marvell,pins = "mpp41";
-				marvell,function = "gpio";
-			};
-
-			pmx_led_green: pmx-led-green {
-				marvell,pins = "mpp42";
-				marvell,function = "gpio";
-			};
-
-			pmx_led_yellow: pmx-led-yellow {
-				marvell,pins = "mpp43";
+			pmx_leds: pmx-leds {
+				marvell,pins = "mpp41", "mpp42", "mpp43";
 				marvell,function = "gpio";
 			};
 		};
@@ -193,6 +133,8 @@
 
 	gpio-leds {
 		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_leds>;
+		pinctrl-names = "default";
 
 		led-red {
 			label = "obsa6:red:stat";
@@ -209,4 +151,18 @@
 			gpios = <&gpio1 11 1>;
 		};
         };
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		pinctrl-0 = <&pmx_gpio_init>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		button@1 {
+			label = "Init Button";
+			linux,code = <116>;
+			gpios = <&gpio1 6 0>;
+		};
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * kirkwood-sheevaplug-common.dts - Common parts for Sheevaplugs
+ *
+ * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
+ *
+ * Licensed under GPLv2
+ */
+
+/include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
+
+/ {
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8 earlyprintk";
+	};
+
+	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pmx_usb_power_enable: pmx-usb-power-enable {
+				marvell,pins = "mpp29";
+				marvell,function = "gpio";
+			};
+			pmx_led_red: pmx-led-red {
+				marvell,pins = "mpp46";
+				marvell,function = "gpio";
+			};
+			pmx_led_blue: pmx-led-blue {
+				marvell,pins = "mpp49";
+				marvell,function = "gpio";
+			};
+			pmx_sdio_cd: pmx-sdio-cd {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+			pmx_sdio_wp: pmx-sdio-wp {
+				marvell,pins = "mpp47";
+				marvell,function = "gpio";
+			};
+		};
+		serial@12000 {
+			pinctrl-0 = <&pmx_uart0>;
+			pinctrl-names = "default";
+			status = "okay";
+		};
+
+		nand@3000000 {
+			pinctrl-0 = <&pmx_nand>;
+			pinctrl-names = "default";
+			status = "okay";
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0000000 0x100000>;
+			};
+
+			partition@100000 {
+				label = "uImage";
+				reg = <0x0100000 0x400000>;
+			};
+
+			partition@500000 {
+				label = "root";
+				reg = <0x0500000 0x1fb00000>;
+			};
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_usb_power_enable>;
+		pinctrl-names = "default";
+
+		usb_power: regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "USB Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 29 0>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-sheevaplug.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-sheevaplug.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-sheevaplug.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-sheevaplug.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ * kirkwood-sheevaplug-esata.dts - Device tree file for Sheevaplug
+ *
+ * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
+ *
+ * Licensed under GPLv2
+ */
+
+/dts-v1/;
+
+/include/ "kirkwood-sheevaplug-common.dtsi"
+
+/ {
+	model = "Globalscale Technologies SheevaPlug";
+	compatible = "globalscale,sheevaplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	ocp@f1000000 {
+		mvsdio@90000 {
+			pinctrl-0 = <&pmx_sdio>;
+			pinctrl-names = "default";
+			status = "okay";
+			/* No CD or WP GPIOs */
+			broken-cd;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_blue &pmx_led_red>;
+		pinctrl-names = "default";
+
+		health {
+			label = "sheevaplug:blue:health";
+			gpios = <&gpio1 17 1>;
+			linux,default-trigger = "default-on";
+		};
+
+		misc {
+			label = "sheevaplug:red:misc";
+			gpios = <&gpio1 14 1>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ * kirkwood-sheevaplug-esata.dts - Device tree file for eSATA Sheevaplug
+ *
+ * Copyright (C) 2013 Simon Baatz <gmbnomis@gmail.com>
+ *
+ * Licensed under GPLv2
+ */
+
+/dts-v1/;
+
+/include/ "kirkwood-sheevaplug-common.dtsi"
+
+/ {
+	model = "Globalscale Technologies eSATA SheevaPlug";
+	compatible = "globalscale,sheevaplug-esata-rev13", "globalscale,sheevaplug-esata", "globalscale,sheevaplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+	ocp@f1000000 {
+		sata@80000 {
+			status = "okay";
+			nr-ports = <2>;
+		};
+
+		mvsdio@90000 {
+			pinctrl-0 = <&pmx_sdio &pmx_sdio_cd &pmx_sdio_wp>;
+			pinctrl-names = "default";
+			status = "okay";
+			cd-gpios = <&gpio1 12 1>;
+			wp-gpios = <&gpio1 15 0>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_blue>;
+		pinctrl-names = "default";
+
+		health {
+			label = "sheevaplug:blue:health";
+			gpios = <&gpio1 17 1>;
+			linux,default-trigger = "default-on";
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-topkick.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-topkick.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-topkick.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-topkick.dts	2013-08-25 20:43:22.000000000 -0400
@@ -19,18 +19,6 @@
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
 			/*
-			 * GPIO LED layout
-			 *
-			 *       /-SYS_LED(2)
-			 *       |
-			 *       |   /-DISK_LED
-			 *       |   |
-			 *       |   |   /-WLAN_LED(2)
-			 *       |   |   |
-			 * [SW] [*] [*] [*]
-			 */
-
-			/*
 			 * Switch positions
 			 *
 			 *     /-SW_LEFT(2)
@@ -41,19 +29,8 @@
 			 *     |   |   |
 			 * PS [L] [I] [R] LEDS
 			 */
-			pinctrl-0 = < &pmx_led_disk_yellow
-				      &pmx_sata0_pwr_enable
-				      &pmx_led_sys_red
-				      &pmx_led_sys_blue
-				      &pmx_led_wifi_green
-				      &pmx_sw_left
-				      &pmx_sw_right
-				      &pmx_sw_idle
-				      &pmx_sw_left2
-				      &pmx_led_wifi_yellow
-				      &pmx_uart0
-				      &pmx_nand
-				      &pmx_twsi0 >;
+			pinctrl-0 = <&pmx_sw_left &pmx_sw_right
+				     &pmx_sw_idle &pmx_sw_left2>;
 			pinctrl-names = "default";
 
 			pmx_led_disk_yellow: pmx-led-disk-yellow {
@@ -109,10 +86,14 @@
 
 		serial@12000 {
 			status = "ok";
+			pinctrl-0 = <&pmx_uart0>;
+			pinctrl-names = "default";
 		};
 
 		nand@3000000 {
 			status = "okay";
+			pinctrl-0 = <&pmx_nand>;
+			pinctrl-names = "default";
 
 			partition@0 {
 				label = "u-boot";
@@ -147,6 +128,8 @@
 
 		i2c@11000 {
 			status = "ok";
+			pinctrl-0 = <&pmx_twsi0>;
+			pinctrl-names = "default";
 		};
 
 		mvsdio@90000 {
@@ -154,11 +137,28 @@
 			pinctrl-names = "default";
 			status = "okay";
 			/* No CD or WP GPIOs */
+			broken-cd;
 		};
 	};
 
 	gpio-leds {
+		/*
+		 * GPIO LED layout
+		 *
+		 *       /-SYS_LED(2)
+		 *       |
+		 *       |   /-DISK_LED
+		 *       |   |
+		 *       |   |   /-WLAN_LED(2)
+		 *       |   |   |
+		 * [SW] [*] [*] [*]
+		 */
+
 		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_disk_yellow &pmx_led_sys_red
+			     &pmx_led_sys_blue &pmx_led_wifi_green
+			     &pmx_led_wifi_yellow>;
+		pinctrl-names = "default";
 
 		disk {
 			label = "topkick:yellow:disk";
@@ -187,6 +187,8 @@
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_sata0_pwr_enable>;
+		pinctrl-names = "default";
 
 		sata0_power: regulator@1 {
 			compatible = "regulator-fixed";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ts219-6281.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ts219-6281.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ts219-6281.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ts219-6281.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,16 +1,14 @@
 /dts-v1/;
 
-/include/ "kirkwood-ts219.dtsi"
+/include/ "kirkwood.dtsi"
 /include/ "kirkwood-6281.dtsi"
+/include/ "kirkwood-ts219.dtsi"
 
 / {
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
 
-			pinctrl-0 = < &pmx_uart0 &pmx_uart1 &pmx_spi
-				      &pmx_twsi0 &pmx_sata0 &pmx_sata1
-				      &pmx_ram_size &pmx_reset_button
-				      &pmx_USB_copy_button &pmx_board_id>;
+			pinctrl-0 = <&pmx_ram_size &pmx_board_id>;
 			pinctrl-names = "default";
 
 			pmx_ram_size: pmx-ram-size {
@@ -38,6 +36,9 @@
 		compatible = "gpio-keys";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
+		pinctrl-names = "default";
+
 		button@1 {
 			label = "USB Copy";
 			linux,code = <133>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ts219-6282.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ts219-6282.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ts219-6282.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ts219-6282.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,16 +1,14 @@
 /dts-v1/;
 
-/include/ "kirkwood-ts219.dtsi"
+/include/ "kirkwood.dtsi"
 /include/ "kirkwood-6282.dtsi"
+/include/ "kirkwood-ts219.dtsi"
 
 / {
 	ocp@f1000000 {
 		pinctrl: pinctrl@10000 {
 
-			pinctrl-0 = < &pmx_uart0 &pmx_uart1 &pmx_spi
-				      &pmx_twsi0 &pmx_sata0 &pmx_sata1
-				      &pmx_ram_size &pmx_reset_button
-				      &pmx_USB_copy_button &pmx_board_id>;
+			pinctrl-0 = <&pmx_ram_size &pmx_board_id>;
 			pinctrl-names = "default";
 
 			pmx_ram_size: pmx-ram-size {
@@ -32,12 +30,23 @@
 				marvell,function = "gpio";
 			};
 		};
+		pcie-controller {
+			status = "okay";
+
+			pcie@2,0 {
+				status = "okay";
+			};
+		};
+
 	};
 
 	gpio_keys {
 		compatible = "gpio-keys";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-0 = <&pmx_reset_button &pmx_USB_copy_button>;
+		pinctrl-names = "default";
+
 		button@1 {
 			label = "USB Copy";
 			linux,code = <133>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ts219.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ts219.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kirkwood-ts219.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kirkwood-ts219.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,3 @@
-/include/ "kirkwood.dtsi"
-
 / {
 	model = "QNAP TS219 family";
 	compatible = "qnap,ts219", "marvell,kirkwood";
@@ -17,6 +15,8 @@
 		i2c@11000 {
 			status = "okay";
 			clock-frequency = <400000>;
+			pinctrl-0 = <&pmx_twsi0>;
+			pinctrl-names = "default";
 
 			s35390a: s35390a@30 {
 				compatible = "s35390a";
@@ -26,13 +26,24 @@
 		serial@12000 {
 			clock-frequency = <200000000>;
 			status = "okay";
+			pinctrl-0 = <&pmx_uart0>;
+			pinctrl-names = "default";
 		};
 		serial@12100 {
 			clock-frequency = <200000000>;
 			status = "okay";
+			pinctrl-0 = <&pmx_uart1>;
+			pinctrl-names = "default";
+		};
+		poweroff@12100 {
+			compatible = "qnap,power-off";
+			reg = <0x12000 0x100>;
+			clocks = <&gate_clk 7>;
 		};
 		spi@10600 {
 			status = "okay";
+			pinctrl-0 = <&pmx_spi>;
+			pinctrl-names = "default";
 
 			m25p128@0 {
 				#address-cells = <1>;
@@ -71,8 +82,17 @@
 			};
 		};
 		sata@80000 {
+			pinctrl-0 = <&pmx_sata0 &pmx_sata1>;
+			pinctrl-names = "default";
 			status = "okay";
 			nr-ports = <2>;
 		};
+		pcie-controller {
+			status = "okay";
+
+			pcie@1,0 {
+				status = "okay";
+			};
+		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/kizbox.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kizbox.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/kizbox.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/kizbox.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 /dts-v1/;
-/include/ "at91sam9g20.dtsi"
+#include "at91sam9g20.dtsi"
 
 / {
 
@@ -94,26 +94,26 @@
 
 		led1g {
 			label = "led1:green";
-			gpios = <&pioB 0 1>;
+			gpios = <&pioB 0 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "none";
 		};
 
 		led1r {
 			label = "led1:red";
-			gpios = <&pioB 1 1>;
+			gpios = <&pioB 1 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "none";
 		};
 
 		led2g {
 			label = "led2:green";
-			gpios = <&pioB 2 1>;
+			gpios = <&pioB 2 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "none";
 			default-state = "on";
 		};
 
 		led2r {
 			label = "led2:red";
-			gpios = <&pioB 3 1>;
+			gpios = <&pioB 3 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "none";
 		};
 	};
@@ -125,16 +125,16 @@
 
 		reset {
 			label = "reset";
-			gpios = <&pioB 30 1>;
+			gpios = <&pioB 30 GPIO_ACTIVE_LOW>;
 			linux,code = <0x100>;
 			gpio-key,wakeup;
 		};
 
 		mode {
 			label = "mode";
-			gpios = <&pioB 31 1>;
+			gpios = <&pioB 31 GPIO_ACTIVE_LOW>;
 			linux,code = <0x101>;
 			gpio-key,wakeup;
 		};
 	};
-};
\ No newline at end of file
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/lpc32xx.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/lpc32xx.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/lpc32xx.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/lpc32xx.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -18,8 +18,12 @@
 	interrupt-parent = <&mic>;
 
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/Makefile linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/Makefile
--- linux-libre-3.10-gnu/arch/arm/boot/dts/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,13 @@ dtb-$(CONFIG_ARCH_AT91) += at91sam9263ek
 dtb-$(CONFIG_ARCH_AT91) += tny_a9263.dtb
 dtb-$(CONFIG_ARCH_AT91) += usb_a9263.dtb
 # sam9g20
+dtb-$(CONFIG_ARCH_AT91) += at91-foxg20.dtb
 dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek.dtb
 dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek_2mmc.dtb
 dtb-$(CONFIG_ARCH_AT91) += kizbox.dtb
 dtb-$(CONFIG_ARCH_AT91) += tny_a9g20.dtb
 dtb-$(CONFIG_ARCH_AT91) += usb_a9g20.dtb
+dtb-$(CONFIG_ARCH_AT91) += usb_a9g20_lpw.dtb
 # sam9g45
 dtb-$(CONFIG_ARCH_AT91) += at91sam9m10g45ek.dtb
 dtb-$(CONFIG_ARCH_AT91) += pm9g45.dtb
@@ -57,6 +59,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-
 	exynos5440-sd5v1.dtb \
 	exynos5250-smdk5250.dtb \
 	exynos5250-snow.dtb \
+	exynos5420-smdk5420.dtb \
 	exynos5440-ssdk5440.dtb
 dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
 	ecx-2000.dtb
@@ -64,6 +67,8 @@ dtb-$(CONFIG_ARCH_INTEGRATOR) += integra
 	integratorcp.dtb
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \
+	kirkwood-db-88f6281.dtb \
+	kirkwood-db-88f6282.dtb \
 	kirkwood-dns320.dtb \
 	kirkwood-dns325.dtb \
 	kirkwood-dockstar.dtb \
@@ -84,6 +89,8 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-
 	kirkwood-ns2max.dtb \
 	kirkwood-ns2mini.dtb \
 	kirkwood-nsa310.dtb \
+	kirkwood-sheevaplug.dtb \
+	kirkwood-sheevaplug-esata.dtb \
 	kirkwood-topkick.dtb \
 	kirkwood-ts219-6281.dtb \
 	kirkwood-ts219-6282.dtb \
@@ -103,13 +110,15 @@ dtb-$(CONFIG_ARCH_MXC) += \
 	imx27-apf27.dtb \
 	imx27-apf27dev.dtb \
 	imx27-pdk.dtb \
-	imx27-phytec-phycore.dtb \
+	imx27-phytec-phycore-som.dtb \
+	imx27-phytec-phycore-rdk.dtb \
 	imx31-bug.dtb \
 	imx51-apf51.dtb \
 	imx51-apf51dev.dtb \
 	imx51-babbage.dtb \
 	imx53-ard.dtb \
 	imx53-evk.dtb \
+	imx53-m53evk.dtb \
 	imx53-mba53.dtb \
 	imx53-qsb.dtb \
 	imx53-smd.dtb \
@@ -117,10 +126,13 @@ dtb-$(CONFIG_ARCH_MXC) += \
 	imx6dl-sabresd.dtb \
 	imx6dl-wandboard.dtb \
 	imx6q-arm2.dtb \
+	imx6q-phytec-pbab01.dtb \
 	imx6q-sabreauto.dtb \
 	imx6q-sabrelite.dtb \
 	imx6q-sabresd.dtb \
-	imx6q-sbc6x.dtb
+	imx6q-sbc6x.dtb \
+	imx6sl-evk.dtb \
+	vf610-twr.dtb
 dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
 	imx23-olinuxino.dtb \
 	imx23-stmp378x_devb.dtb \
@@ -130,11 +142,16 @@ dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb
 	imx28-cfa10036.dtb \
 	imx28-cfa10037.dtb \
 	imx28-cfa10049.dtb \
+	imx28-cfa10055.dtb \
+	imx28-cfa10057.dtb \
 	imx28-evk.dtb \
 	imx28-m28evk.dtb \
 	imx28-sps1.dtb \
 	imx28-tx28.dtb
 dtb-$(CONFIG_ARCH_NOMADIK) += ste-nomadik-s8815.dtb
+dtb-$(CONFIG_ARCH_NSPIRE) += nspire-cx.dtb \
+	nspire-tp.dtb \
+	nspire-clp.dtb
 dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
 	omap3430-sdp.dtb \
 	omap3-beagle.dtb \
@@ -149,19 +166,26 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420
 	omap4-panda-es.dtb \
 	omap4-var-som.dtb \
 	omap4-sdp.dtb \
-	omap5-evm.dtb \
+	omap4-sdp-es23plus.dtb \
+	omap5-uevm.dtb \
 	am335x-evm.dtb \
 	am335x-evmsk.dtb \
-	am335x-bone.dtb
+	am335x-bone.dtb \
+	am3517-evm.dtb \
+	am3517_mt_ventoux.dtb \
+	am43x-epos-evm.dtb
 dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
 dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
 dtb-$(CONFIG_ARCH_U8500) += snowball.dtb \
 	hrefprev60.dtb \
 	hrefv60plus.dtb \
+	ccu8540.dtb \
 	ccu9540.dtb
+dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb
 dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
 	r8a7740-armadillo800eva.dtb \
 	r8a7778-bockw.dtb \
+	r8a7740-armadillo800eva-reference.dtb \
 	r8a7779-marzen-reference.dtb \
 	r8a7790-lager.dtb \
 	sh73a0-kzm9g.dtb \
@@ -177,10 +201,15 @@ dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-e
 	spear320-evb.dtb \
 	spear320-hmi.dtb
 dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb
+dtb-$(CONFIG_ARCH_STI)+= stih415-b2000.dtb \
+	stih416-b2000.dtb \
+	stih415-b2020.dtb \
+	stih416-b2020.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += \
 	sun4i-a10-cubieboard.dtb \
 	sun4i-a10-mini-xplus.dtb \
 	sun4i-a10-hackberry.dtb \
+	sun5i-a10s-olinuxino-micro.dtb \
 	sun5i-a13-olinuxino.dtb
 dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
 	tegra20-iris-512.dtb \
@@ -199,6 +228,7 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harm
 	tegra114-pluto.dtb
 dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \
 	versatile-pb.dtb
+dtb-$(CONFIG_ARCH_U300) += ste-u300.dtb
 dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
 	vexpress-v2p-ca9.dtb \
 	vexpress-v2p-ca15-tc1.dtb \
@@ -207,8 +237,11 @@ dtb-$(CONFIG_ARCH_VIRT) += xenvm-4.2.dtb
 dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
 	wm8505-ref.dtb \
 	wm8650-mid.dtb \
+	wm8750-apc8750.dtb \
 	wm8850-w70v2.dtb
-dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb
+dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \
+	zynq-zc706.dtb \
+	zynq-zed.dtb
 
 targets += dtbs
 targets += $(dtb-y)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/mpa1600.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/mpa1600.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/mpa1600.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/mpa1600.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2 only
  */
 /dts-v1/;
-/include/ "at91rm9200.dtsi"
+#include "at91rm9200.dtsi"
 
 / {
 	model = "Phontech MPA 1600";
@@ -62,7 +62,7 @@
 
 		monitor_mute {
 			label = "Monitor mute";
-			gpios = <&pioC 1 1>;
+			gpios = <&pioC 1 GPIO_ACTIVE_LOW>;
 			linux,code = <113>;
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/msm8660-surf.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/msm8660-surf.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/msm8660-surf.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/msm8660-surf.dts	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,7 @@
 		      < 0x02081000 0x1000 >;
 	};
 
-	timer@2000004 {
+	timer@2000000 {
 		compatible = "qcom,scss-timer", "qcom,msm-timer";
 		interrupts = <1 0 0x301>,
 			     <1 1 0x301>,
@@ -26,7 +26,18 @@
 		cpu-offset = <0x40000>;
 	};
 
-	serial@19c400000 {
+	msmgpio: gpio@800000 {
+		compatible = "qcom,msm-gpio";
+		reg = <0x00800000 0x1000>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		ngpio = <173>;
+		interrupts = <0 32 0x4>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	serial@19c40000 {
 		compatible = "qcom,msm-hsuart", "qcom,msm-uart";
 		reg = <0x19c40000 0x1000>,
 		      <0x19c00000 0x1000>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/msm8960-cdp.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/msm8960-cdp.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/msm8960-cdp.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/msm8960-cdp.dts	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,18 @@
 		cpu-offset = <0x80000>;
 	};
 
-	serial@19c400000 {
+	msmgpio: gpio@800000 {
+		compatible = "qcom,msm-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+		ngpio = <150>;
+		interrupts = <0 32 0x4>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		reg = <0x800000 0x4000>;
+	};
+
+	serial@16440000 {
 		compatible = "qcom,msm-hsuart", "qcom,msm-uart";
 		reg = <0x16440000 0x1000>,
 		      <0x16400000 0x1000>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/nspire-classic.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire-classic.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/nspire-classic.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire-classic.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+ *  linux/arch/arm/boot/nspire-classic.dts
+ *
+ *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/include/ "nspire.dtsi"
+
+&lcd {
+	lcd-type = "classic";
+};
+
+&fast_timer {
+	/* compatible = "lsi,zevio-timer"; */
+	reg = <0x90010000 0x1000>, <0x900A0010 0x8>;
+};
+
+&uart {
+	compatible = "ns16550";
+	reg-shift = <2>;
+	reg-io-width = <4>;
+	clocks = <&apb_pclk>;
+	no-loopback-test;
+};
+
+&timer0 {
+	/* compatible = "lsi,zevio-timer"; */
+	reg = <0x900C0000 0x1000>, <0x900A0018 0x8>;
+};
+
+&timer1 {
+	compatible = "lsi,zevio-timer";
+	reg = <0x900D0000 0x1000>, <0x900A0020 0x8>;
+};
+
+&keypad {
+	active-low;
+
+};
+
+&base_clk {
+	compatible = "lsi,nspire-classic-clock";
+};
+
+&ahb_clk {
+	compatible = "lsi,nspire-classic-ahb-divider";
+};
+
+/ {
+	memory {
+		device_type = "memory";
+		reg = <0x10000000 0x2000000>; /* 32 MB */
+	};
+
+	ahb {
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		intc: interrupt-controller@DC000000 {
+			compatible = "lsi,zevio-intc";
+			interrupt-controller;
+			reg = <0xDC000000 0x1000>;
+			#interrupt-cells = <1>;
+		};
+	};
+	chosen {
+		bootargs = "debug earlyprintk console=tty0 console=ttyS0,115200n8 root=/dev/ram0";
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/nspire-clp.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire-clp.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/nspire-clp.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire-clp.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ *  linux/arch/arm/boot/nspire-clp.dts
+ *
+ *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+
+/include/ "nspire-classic.dtsi"
+
+&keypad {
+	linux,keymap = <
+	0x0000001c 	0x0001001c 	0x00020039
+	0x0004002c 	0x00050034 	0x00060015
+	0x0007000b 	0x0008002d 	0x01000033
+	0x0101004e 	0x01020011 	0x01030004
+	0x0104002f 	0x01050003 	0x01060016
+	0x01070002 	0x01080014 	0x02000062
+	0x0201000c 	0x0202001f 	0x02030007
+	0x02040013 	0x02050006 	0x02060010
+	0x02070005 	0x02080019 	0x03000027
+	0x03010037 	0x03020018 	0x0303000a
+	0x03040031 	0x03050009 	0x03060032
+	0x03070008 	0x03080026 	0x04000028
+	0x04010035 	0x04020025 	0x04040024
+	0x04060017 	0x04080023 	0x05000028
+	0x05020022 	0x0503001b 	0x05040021
+	0x0505001a 	0x05060012 	0x0507006f
+	0x05080020 	0x0509002a 	0x0601001c
+	0x0602002e 	0x06030068 	0x06040030
+	0x0605006d 	0x0606001e 	0x06070001
+	0x0608002b 	0x0609000f 	0x07000067
+	0x0702006a 	0x0704006c 	0x07060069
+	0x0707000e 	0x0708001d 	0x070a000d
+	>;
+};
+
+/ {
+	model = "TI-NSPIRE Clickpad";
+	compatible = "ti,nspire-clp";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/nspire-cx.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire-cx.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/nspire-cx.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire-cx.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,112 @@
+/*
+ *  linux/arch/arm/boot/nspire-cx.dts
+ *
+ *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+
+/include/ "nspire.dtsi"
+
+&lcd {
+	lcd-type = "cx";
+};
+
+&fast_timer {
+	/* compatible = "arm,sp804", "arm,primecell"; */
+};
+
+&uart {
+	compatible = "arm,pl011", "arm,primecell";
+
+	clocks = <&uart_clk>, <&apb_pclk>;
+	clock-names = "uart_clk", "apb_pclk";
+};
+
+&timer0 {
+	compatible = "arm,sp804", "arm,primecell";
+};
+
+&timer1 {
+	compatible = "arm,sp804", "arm,primecell";
+};
+
+&base_clk {
+	compatible = "lsi,nspire-cx-clock";
+};
+
+&ahb_clk {
+	compatible = "lsi,nspire-cx-ahb-divider";
+};
+
+&keypad {
+	linux,keymap = <
+	0x0000001c 	0x0001001c 	0x00040039
+	0x0005002c 	0x00060015 	0x0007000b
+	0x0008000f 	0x0100002d 	0x01010011
+	0x0102002f 	0x01030004 	0x01040016
+	0x01050014 	0x0106001f 	0x01070002
+	0x010a006a 	0x02000013 	0x02010010
+	0x02020019 	0x02030007 	0x02040018
+	0x02050031 	0x02060032 	0x02070005
+	0x02080028 	0x0209006c 	0x03000026
+	0x03010025 	0x03020024 	0x0303000a
+	0x03040017 	0x03050023 	0x03060022
+	0x03070008 	0x03080035 	0x03090069
+	0x04000021 	0x04010012 	0x04020020
+	0x0404002e 	0x04050030 	0x0406001e
+	0x0407000d 	0x04080037 	0x04090067
+	0x05010038 	0x0502000c 	0x0503001b
+	0x05040034 	0x0505001a 	0x05060006
+	0x05080027 	0x0509000e 	0x050a006f
+	0x0600002b 	0x0602004e 	0x06030068
+	0x06040003 	0x0605006d 	0x06060009
+	0x06070001 	0x0609000f 	0x0708002a
+	0x0709001d 	0x070a0033 	>;
+};
+
+/ {
+	model = "TI-NSPIRE CX";
+	compatible = "ti,nspire-cx";
+
+	memory {
+		device_type = "memory";
+		reg = <0x10000000 0x4000000>; /* 64 MB */
+	};
+
+	uart_clk: uart_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <12000000>;
+	};
+
+	ahb {
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		intc: interrupt-controller@DC000000 {
+			compatible = "arm,pl190-vic";
+			interrupt-controller;
+			reg = <0xDC000000 0x1000>;
+			#interrupt-cells = <1>;
+		};
+
+		apb@90000000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			i2c@90050000 {
+				compatible = "snps,designware-i2c";
+				reg = <0x90050000 0x1000>;
+				interrupts = <20>;
+			};
+		};
+	};
+	chosen {
+		bootargs = "debug earlyprintk console=tty0 console=ttyAMA0,115200n8 root=/dev/ram0";
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/nspire.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/nspire.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,175 @@
+/*
+ *  linux/arch/arm/boot/nspire.dtsi
+ *
+ *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	interrupt-parent = <&intc>;
+
+	cpus {
+		cpu@0 {
+			compatible = "arm,arm926ejs";
+		};
+	};
+
+	bootrom: bootrom@00000000 {
+		reg = <0x00000000 0x80000>;
+	};
+
+	sram: sram@A4000000 {
+		device = "memory";
+		reg = <0xA4000000 0x20000>;
+	};
+
+	timer_clk: timer_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <32768>;
+	};
+
+	base_clk: base_clk {
+		#clock-cells = <0>;
+		reg = <0x900B0024 0x4>;
+	};
+
+	ahb_clk: ahb_clk {
+		#clock-cells = <0>;
+		reg = <0x900B0024 0x4>;
+		clocks = <&base_clk>;
+	};
+
+	apb_pclk: apb_pclk {
+		#clock-cells = <0>;
+		compatible = "fixed-factor-clock";
+		clock-div = <2>;
+		clock-mult = <1>;
+		clocks = <&ahb_clk>;
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		spi: spi@A9000000 {
+			reg = <0xA9000000 0x1000>;
+		};
+
+		usb0: usb@B0000000 {
+			reg = <0xB0000000 0x1000>;
+			interrupts = <8>;
+		};
+
+		usb1: usb@B4000000 {
+			reg = <0xB4000000 0x1000>;
+			interrupts = <9>;
+			status = "disabled";
+		};
+
+		lcd: lcd@C0000000 {
+			compatible = "arm,pl111", "arm,primecell";
+			reg = <0xC0000000 0x1000>;
+			interrupts = <21>;
+
+			clocks = <&apb_pclk>;
+			clock-names = "apb_pclk";
+		};
+
+		adc: adc@C4000000 {
+			reg = <0xC4000000 0x1000>;
+			interrupts = <11>;
+		};
+
+		tdes: crypto@C8010000 {
+			reg = <0xC8010000 0x1000>;
+		};
+
+		sha256: crypto@CC000000 {
+			reg = <0xCC000000 0x1000>;
+		};
+
+		apb@90000000 {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			clock-ranges;
+			ranges;
+
+			gpio: gpio@90000000 {
+				reg = <0x90000000 0x1000>;
+				interrupts = <7>;
+			};
+
+			fast_timer: timer@90010000 {
+				reg = <0x90010000 0x1000>;
+				interrupts = <17>;
+			};
+
+			uart: serial@90020000 {
+				reg = <0x90020000 0x1000>;
+				interrupts = <1>;
+			};
+
+			timer0: timer@900C0000 {
+				reg = <0x900C0000 0x1000>;
+
+				clocks = <&timer_clk>;
+			};
+
+			timer1: timer@900D0000 {
+				reg = <0x900D0000 0x1000>;
+				interrupts = <19>;
+
+				clocks = <&timer_clk>;
+			};
+
+			watchdog: watchdog@90060000 {
+				compatible = "arm,amba-primecell";
+				reg = <0x90060000 0x1000>;
+				interrupts = <3>;
+			};
+
+			rtc: rtc@90090000 {
+				reg = <0x90090000 0x1000>;
+				interrupts = <4>;
+			};
+
+			misc: misc@900A0000 {
+				reg = <0x900A0000 0x1000>;
+			};
+
+			pwr: pwr@900B0000 {
+				reg = <0x900B0000 0x1000>;
+				interrupts = <15>;
+			};
+
+			keypad: input@900E0000 {
+				compatible = "ti,nspire-keypad";
+				reg = <0x900E0000 0x1000>;
+				interrupts = <16>;
+
+				scan-interval = <1000>;
+				row-delay = <200>;
+
+				clocks = <&apb_pclk>;
+			};
+
+			contrast: contrast@900F0000 {
+				reg = <0x900F0000 0x1000>;
+			};
+
+			led: led@90110000 {
+				reg = <0x90110000 0x1000>;
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/nspire-tp.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire-tp.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/nspire-tp.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/nspire-tp.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ *  linux/arch/arm/boot/nspire-tp.dts
+ *
+ *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+/dts-v1/;
+
+/include/ "nspire-classic.dtsi"
+
+&keypad {
+	linux,keymap = <
+	0x0000001c 	0x0001001c 	0x00040039
+	0x0005002c 	0x00060015 	0x0007000b
+	0x0008000f 	0x0100002d 	0x01010011
+	0x0102002f 	0x01030004 	0x01040016
+	0x01050014 	0x0106001f 	0x01070002
+	0x010a006a 	0x02000013 	0x02010010
+	0x02020019 	0x02030007 	0x02040018
+	0x02050031 	0x02060032 	0x02070005
+	0x02080028 	0x0209006c 	0x03000026
+	0x03010025 	0x03020024 	0x0303000a
+	0x03040017 	0x03050023 	0x03060022
+	0x03070008 	0x03080035 	0x03090069
+	0x04000021 	0x04010012 	0x04020020
+	0x0404002e 	0x04050030 	0x0406001e
+	0x0407000d 	0x04080037 	0x04090067
+	0x05010038 	0x0502000c 	0x0503001b
+	0x05040034 	0x0505001a 	0x05060006
+	0x05080027 	0x0509000e 	0x050a006f
+	0x0600002b 	0x0602004e 	0x06030068
+	0x06040003 	0x0605006d 	0x06060009
+	0x06070001 	0x0609000f 	0x0708002a
+	0x0709001d 	0x070a0033 	>;
+};
+
+/ {
+	model = "TI-NSPIRE Touchpad";
+	compatible = "ti,nspire-tp";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap2420.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap2420.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap2420.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap2420.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
  * kind, whether express or implied.
  */
 
-/include/ "omap2.dtsi"
+#include "omap2.dtsi"
 
 / {
 	compatible = "ti,omap2420", "ti,omap2";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap2420-h4.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap2420-h4.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap2420-h4.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap2420-h4.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap2420.dtsi"
+#include "omap2420.dtsi"
 
 / {
 	model = "TI OMAP2420 H4 board";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap2430.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap2430.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap2430.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap2430.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
  * kind, whether express or implied.
  */
 
-/include/ "omap2.dtsi"
+#include "omap2.dtsi"
 
 / {
 	compatible = "ti,omap2430", "ti,omap2";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap2.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap2.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap2.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap2.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,10 @@
  * kind, whether express or implied.
  */
 
-/include/ "skeleton.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/omap.h>
+
+#include "skeleton.dtsi"
 
 / {
 	compatible = "ti,omap2430", "ti,omap2420", "ti,omap2";
@@ -21,8 +24,12 @@
 	};
 
 	cpus {
-		cpu@0 {
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
 			compatible = "arm,arm1136jf-s";
+			device_type = "cpu";
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3430-sdp.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3430-sdp.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3430-sdp.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3430-sdp.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap34xx.dtsi"
+#include "omap34xx.dtsi"
 
 / {
 	model = "TI OMAP3430 SDP";
@@ -28,7 +28,8 @@
 	};
 };
 
-/include/ "twl4030.dtsi"
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
 
 &mmc1 {
 	vmmc-supply = <&vmmc1>;
@@ -105,7 +106,6 @@
 		nand-bus-width = <8>;
 
 		ti,nand-ecc-opt = "sw";
-		gpmc,device-nand;
 		gpmc,cs-on-ns = <0>;
 		gpmc,cs-rd-off-ns = <36>;
 		gpmc,cs-wr-off-ns = <36>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap34xx.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap34xx.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap34xx.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap34xx.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
  * kind, whether express or implied.
  */
 
-/include/ "omap3.dtsi"
+#include "omap3.dtsi"
 
 / {
 	cpus {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap36xx.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap36xx.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap36xx.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap36xx.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
  * kind, whether express or implied.
  */
 
-/include/ "omap3.dtsi"
+#include "omap3.dtsi"
 
 / {
 	aliases {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-beagle.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-beagle.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-beagle.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-beagle.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap34xx.dtsi"
+#include "omap34xx.dtsi"
 
 / {
 	model = "TI OMAP3 BeagleBoard";
@@ -28,18 +28,18 @@
 		compatible = "gpio-leds";
 		pmu_stat {
 			label = "beagleboard::pmu_stat";
-			gpios = <&twl_gpio 19 0>; /* LEDB */
+			gpios = <&twl_gpio 19 GPIO_ACTIVE_HIGH>; /* LEDB */
 		};
 
 		heartbeat {
 			label = "beagleboard::usr0";
-			gpios = <&gpio5 22 0>; /* 150 -> D6 LED */
+			gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; /* 150 -> D6 LED */
 			linux,default-trigger = "heartbeat";
 		};
 
 		mmc {
 			label = "beagleboard::usr1";
-			gpios = <&gpio5 21 0>; /* 149 -> D7 LED */
+			gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>; /* 149 -> D7 LED */
 			linux,default-trigger = "mmc0";
 		};
 	};
@@ -71,6 +71,26 @@
 		reset-supply = <&hsusb2_reset>;
 		vcc-supply = <&hsusb2_power>;
 	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+
+		user {
+			label = "user";
+			gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+			linux,code = <0x114>;
+			gpio-key,wakeup;
+		};
+
+	};
+};
+
+&omap3_pmx_wkup {
+	gpio1_pins: pinmux_gpio1_pins {
+		pinctrl-single,pins = <
+			0x14 (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot5.gpio_7 */
+		>;
+	};
 };
 
 &omap3_pmx_core {
@@ -81,18 +101,25 @@
 
 	hsusbb2_pins: pinmux_hsusbb2_pins {
 		pinctrl-single,pins = <
-			0x5c0 0x3  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_clk OUTPUT */
-			0x5c2 0x3  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_stp OUTPUT */
-			0x5c4 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dir INPUT | PULLDOWN */
-			0x5c6 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_nxt INPUT | PULLDOWN */
-			0x5c8 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat0 INPUT | PULLDOWN */
-			0x5cA 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat1 INPUT | PULLDOWN */
-			0x1a4 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat2 INPUT | PULLDOWN */
-			0x1a6 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat3 INPUT | PULLDOWN */
-			0x1a8 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat4 INPUT | PULLDOWN */
-			0x1aa 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat5 INPUT | PULLDOWN */
-			0x1ac 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat6 INPUT | PULLDOWN */
-			0x1ae 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat7 INPUT | PULLDOWN */
+			0x5c0 (PIN_OUTPUT | MUX_MODE3)		/* usbb2_ulpitll_clk.usbb1_ulpiphy_clk */
+			0x5c2 (PIN_OUTPUT | MUX_MODE3)		/* usbb2_ulpitll_clk.usbb1_ulpiphy_stp */
+			0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_dir */
+			0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_nxt */
+			0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_dat0 */
+			0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_dat1 */
+			0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_dat2 */
+			0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_dat3 */
+			0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_dat4 */
+			0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_dat5 */
+			0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_dat6 */
+			0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* usbb2_ulpitll_clk.usbb1_ulpiphy_dat7 */
+		>;
+	};
+
+	uart3_pins: pinmux_uart3_pins {
+		pinctrl-single,pins = <
+			0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+			0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
 		>;
 	};
 };
@@ -107,7 +134,8 @@
 	};
 };
 
-/include/ "twl4030.dtsi"
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
 
 &mmc1 {
 	vmmc-supply = <&vmmc1>;
@@ -142,3 +170,13 @@
 	 */
 	ti,pulldowns = <0x03a1c4>;
 };
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+};
+
+&gpio1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio1_pins>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-beagle-xm.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-beagle-xm.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-beagle-xm.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-beagle-xm.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap36xx.dtsi"
+#include "omap36xx.dtsi"
 
 / {
 	model = "TI OMAP3 BeagleBoard xM";
@@ -29,13 +29,13 @@
 
 		heartbeat {
 			label = "beagleboard::usr0";
-			gpios = <&gpio5 22 0>; /* 150 -> D6 LED */
+			gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; /* 150 -> D6 LED */
 			linux,default-trigger = "heartbeat";
 		};
 
 		mmc {
 			label = "beagleboard::usr1";
-			gpios = <&gpio5 21 0>; /* 149 -> D7 LED */
+			gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>; /* 149 -> D7 LED */
 			linux,default-trigger = "mmc0";
 		};
 	};
@@ -57,6 +57,26 @@
 		ti,mcbsp = <&mcbsp2>;
 		ti,codec = <&twl_audio>;
 	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+
+		user {
+			label = "user";
+			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+			linux,code = <0x114>;
+			gpio-key,wakeup;
+		};
+
+	};
+};
+
+&omap3_pmx_wkup {
+	gpio1_pins: pinmux_gpio1_pins {
+		pinctrl-single,pins = <
+			0x0e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE4) /* sys_boot2.gpio_4 */
+		>;
+	};
 };
 
 &i2c1 {
@@ -75,7 +95,8 @@
 	};
 };
 
-/include/ "twl4030.dtsi"
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
 
 &i2c2 {
 	clock-frequency = <400000>;
@@ -126,3 +147,22 @@
 	mode = <3>;
 	power = <50>;
 };
+
+&omap3_pmx_core {
+	uart3_pins: pinmux_uart3_pins {
+		pinctrl-single,pins = <
+			0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+			0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */
+		>;
+	};
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+};
+
+&gpio1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio1_pins>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-devkit8000.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-devkit8000.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-devkit8000.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-devkit8000.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap34xx.dtsi"
+#include "omap34xx.dtsi"
 / {
 	model = "TimLL OMAP3 Devkit8000";
 	compatible = "timll,omap3-devkit8000", "ti,omap3";
@@ -22,21 +22,21 @@
 
 		heartbeat {
 			label = "devkit8000::led1";
-			gpios = <&gpio6 26 0>;	/* 186 -> LED1 */
+			gpios = <&gpio6 26 GPIO_ACTIVE_HIGH>;	/* 186 -> LED1 */
 			default-state = "on";
 			linux,default-trigger = "heartbeat";
 		};
 
 		mmc {
 			label = "devkit8000::led2";
-			gpios = <&gpio6 3 0>;	/* 163 -> LED2 */
+			gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>;	/* 163 -> LED2 */
 			default-state = "on";
 			linux,default-trigger = "none";
 		};
 
 		usr {
 			label = "devkit8000::led3";
-			gpios = <&gpio6 4 0>;	/* 164 -> LED3 */
+			gpios = <&gpio6 4 GPIO_ACTIVE_HIGH>;	/* 164 -> LED3 */
 			default-state = "on";
 			linux,default-trigger = "usr";
                 };
@@ -80,7 +80,8 @@
 	status = "disabled";
 };
 
-/include/ "twl4030.dtsi"
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
 
 &mmc1 {
 	vmmc-supply = <&vmmc1>;
@@ -123,20 +124,21 @@
 		reg = <0 0 0>; /* CS0, offset 0 */
 		nand-bus-width = <16>;
 
-		gpmc,sync-clk = <0>;
-		gpmc,cs-on = <0>;
-		gpmc,cs-rd-off = <44>;
-		gpmc,cs-wr-off = <44>;
-		gpmc,adv-on = <6>;
-		gpmc,adv-rd-off = <34>;
-		gpmc,adv-wr-off = <44>;
-		gpmc,we-off = <40>;
-		gpmc,oe-off = <54>;
-		gpmc,access = <64>;
-		gpmc,rd-cycle = <82>;
-		gpmc,wr-cycle = <82>;
-		gpmc,wr-access = <40>;
-		gpmc,wr-data-mux-bus = <0>;
+		gpmc,device-nand;
+		gpmc,sync-clki-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <44>;
+		gpmc,cs-wr-off-ns = <44>;
+		gpmc,adv-on-ns = <6>;
+		gpmc,adv-rd-off-ns = <34>;
+		gpmc,adv-wr-off-ns = <44>;
+		gpmc,we-off-ns = <40>;
+		gpmc,oe-off-ns = <54>;
+		gpmc,access-ns = <64>;
+		gpmc,rd-cycle-ns = <82>;
+		gpmc,wr-cycle-ns = <82>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,11 @@
  * kind, whether express or implied.
  */
 
-/include/ "skeleton.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/omap.h>
+
+#include "skeleton.dtsi"
 
 / {
 	compatible = "ti,omap3430", "ti,omap3";
@@ -21,8 +25,13 @@
 	};
 
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
 		cpu@0 {
 			compatible = "arm,cortex-a8";
+			device_type = "cpu";
+			reg = <0x0>;
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-evm.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-evm.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-evm.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-evm.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap34xx.dtsi"
+#include "omap34xx.dtsi"
 
 / {
 	model = "TI OMAP3 EVM (OMAP3530, AM/DM37x)";
@@ -28,7 +28,7 @@
 		compatible = "gpio-leds";
 		ledb {
 			label = "omap3evm::ledb";
-			gpios = <&twl_gpio 19 0>; /* LEDB */
+			gpios = <&twl_gpio 19 GPIO_ACTIVE_HIGH>; /* LEDB */
 			linux,default-trigger = "default-on";
 		};
 	};
@@ -44,7 +44,8 @@
 	};
 };
 
-/include/ "twl4030.dtsi"
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
 
 &i2c2 {
 	clock-frequency = <400000>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-igep0020.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-igep0020.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-igep0020.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-igep0020.dts	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,7 @@
  * published by the Free Software Foundation.
  */
 
-/include/ "omap3-igep.dtsi"
+#include "omap3-igep.dtsi"
 
 / {
 	model = "IGEPv2";
@@ -19,27 +19,39 @@
 		compatible = "gpio-leds";
 		boot {
 			 label = "omap3:green:boot";
-			 gpios = <&gpio1 26 0>;
+			 gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
 			 default-state = "on";
 		};
 
 		user0 {
 			 label = "omap3:red:user0";
-			 gpios = <&gpio1 27 0>;
+			 gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
 			 default-state = "off";
 		};
 
 		user1 {
 			 label = "omap3:red:user1";
-			 gpios = <&gpio1 28 0>;
+			 gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
 			 default-state = "off";
 		};
 
 		user2 {
 			label = "omap3:green:user1";
-			gpios = <&twl_gpio 19 1>;
+			gpios = <&twl_gpio 19 GPIO_ACTIVE_LOW>;
 		};
 	};
+
+	vddvario: regulator-vddvario {
+		  compatible = "regulator-fixed";
+		  regulator-name = "vddvario";
+		  regulator-always-on;
+	};
+
+	vdd33a: regulator-vdd33a {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd33a";
+		regulator-always-on;
+	};
 };
 
 &i2c3 {
@@ -54,3 +66,92 @@
 		reg = <0x50>;
 	};
 };
+
+&gpmc {
+	ranges = <0 0 0x00000000 0x20000000>,
+		 <5 0 0x2c000000 0x01000000>;
+
+	nand@0,0 {
+		linux,mtd-name= "micron,mt29c4g96maz";
+		reg = <0 0 0>;
+		nand-bus-width = <16>;
+		ti,nand-ecc-opt = "bch8";
+
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <44>;
+		gpmc,cs-wr-off-ns = <44>;
+		gpmc,adv-on-ns = <6>;
+		gpmc,adv-rd-off-ns = <34>;
+		gpmc,adv-wr-off-ns = <44>;
+		gpmc,we-off-ns = <40>;
+		gpmc,oe-off-ns = <54>;
+		gpmc,access-ns = <64>;
+		gpmc,rd-cycle-ns = <82>;
+		gpmc,wr-cycle-ns = <82>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "SPL";
+			reg = <0 0x100000>;
+		};
+		partition@0x80000 {
+			label = "U-Boot";
+			reg = <0x100000 0x180000>;
+		};
+		partition@0x1c0000 {
+			label = "Environment";
+			reg = <0x280000 0x100000>;
+		};
+		partition@0x280000 {
+			label = "Kernel";
+			reg = <0x380000 0x300000>;
+		};
+		partition@0x780000 {
+			label = "Filesystem";
+			reg = <0x680000 0x1f980000>;
+		};
+	};
+
+	ethernet@5,0 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&smsc911x_pins>;
+		compatible = "smsc,lan9221", "smsc,lan9115";
+		reg = <5 0 0xff>;
+		bank-width = <2>;
+
+		gpmc,mux-add-data;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <186>;
+		gpmc,cs-wr-off-ns = <186>;
+		gpmc,adv-on-ns = <12>;
+		gpmc,adv-rd-off-ns = <48>;
+		gpmc,adv-wr-off-ns = <48>;
+		gpmc,oe-on-ns = <54>;
+		gpmc,oe-off-ns = <168>;
+		gpmc,we-on-ns = <54>;
+		gpmc,we-off-ns = <168>;
+		gpmc,rd-cycle-ns = <186>;
+		gpmc,wr-cycle-ns = <186>;
+		gpmc,access-ns = <114>;
+		gpmc,page-burst-access-ns = <6>;
+		gpmc,bus-turnaround-ns = <12>;
+		gpmc,cycle2cycle-delay-ns = <18>;
+		gpmc,wr-data-mux-bus-ns = <90>;
+		gpmc,wr-access-ns = <186>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
+
+		interrupt-parent = <&gpio6>;
+		interrupts = <16 8>;
+		vmmc-supply = <&vddvario>;
+		vmmc_aux-supply = <&vdd33a>;
+		reg-io-width = <4>;
+
+		smsc,save-mac-address;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-igep0030.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-igep0030.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-igep0030.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-igep0030.dts	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,7 @@
  * published by the Free Software Foundation.
  */
 
-/include/ "omap3-igep.dtsi"
+#include "omap3-igep.dtsi"
 
 / {
 	model = "IGEP COM Module";
@@ -19,26 +19,76 @@
 		compatible = "gpio-leds";
 		boot {
 			 label = "omap3:green:boot";
-			 gpios = <&twl_gpio 13 1>;
+			 gpios = <&twl_gpio 13 GPIO_ACTIVE_LOW>;
 			 default-state = "on";
 		};
 
 		user0 {
 			 label = "omap3:red:user0";
-			 gpios = <&twl_gpio 18 1>; /* LEDA */
+			 gpios = <&twl_gpio 18 GPIO_ACTIVE_LOW>; /* LEDA */
 			 default-state = "off";
 		};
 
 		user1 {
 			 label = "omap3:green:user1";
-			 gpios = <&twl_gpio 19 1>; /* LEDB */
+			 gpios = <&twl_gpio 19 GPIO_ACTIVE_LOW>; /* LEDB */
 			 default-state = "off";
 		};
 
 		user2 {
 			 label = "omap3:red:user1";
-			 gpios = <&gpio1 16 1>;
+			 gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
 			 default-state = "off";
 		};
 	};
 };
+
+&gpmc {
+	ranges = <0 0 0x00000000 0x20000000>;
+
+	nand@0,0 {
+		linux,mtd-name= "micron,mt29c4g96maz";
+		reg = <0 0 0>;
+		nand-bus-width = <16>;
+		ti,nand-ecc-opt = "bch8";
+
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <44>;
+		gpmc,cs-wr-off-ns = <44>;
+		gpmc,adv-on-ns = <6>;
+		gpmc,adv-rd-off-ns = <34>;
+		gpmc,adv-wr-off-ns = <44>;
+		gpmc,we-off-ns = <40>;
+		gpmc,oe-off-ns = <54>;
+		gpmc,access-ns = <64>;
+		gpmc,rd-cycle-ns = <82>;
+		gpmc,wr-cycle-ns = <82>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "SPL";
+			reg = <0 0x100000>;
+		};
+		partition@0x80000 {
+			label = "U-Boot";
+			reg = <0x100000 0x180000>;
+		};
+		partition@0x1c0000 {
+			label = "Environment";
+			reg = <0x280000 0x100000>;
+		};
+		partition@0x280000 {
+			label = "Kernel";
+			reg = <0x380000 0x300000>;
+		};
+		partition@0x780000 {
+			label = "Filesystem";
+			reg = <0x680000 0x1f980000>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-igep.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-igep.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-igep.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-igep.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@
  */
 /dts-v1/;
 
-/include/ "omap34xx.dtsi"
+#include "omap34xx.dtsi"
 
 / {
 	memory {
@@ -29,37 +29,43 @@
 &omap3_pmx_core {
 	uart1_pins: pinmux_uart1_pins {
 		pinctrl-single,pins = <
-			0x152 0x100	/* uart1_rx.uart1_rx INPUT | MODE0 */
-			0x14c 0		/* uart1_tx.uart1_tx OUTPUT | MODE0 */
+			0x152 (PIN_INPUT | MUX_MODE0)		/* uart1_rx.uart1_rx */
+			0x14c (PIN_OUTPUT |MUX_MODE0)		/* uart1_tx.uart1_tx */
 		>;
 	};
 
 	uart2_pins: pinmux_uart2_pins {
 		pinctrl-single,pins = <
-			0x14a 0x100	/* uart2_rx.uart2_rx INPUT | MODE0 */
-			0x148 0		/* uart2_tx.uart2_tx OUTPUT | MODE0 */
+			0x14a (PIN_INPUT | MUX_MODE0)		/* uart2_rx.uart2_rx */
+			0x148 (PIN_OUTPUT | MUX_MODE0)		/* uart2_tx.uart2_tx */
 		>;
 	};
 
 	uart3_pins: pinmux_uart3_pins {
 		pinctrl-single,pins = <
-			0x16e 0x100	/* uart3_rx.uart3_rx INPUT | MODE0 */
-			0x170 0		/* uart3_tx.uart3_tx OUTPUT | MODE0 */
+			0x16e (PIN_INPUT | MUX_MODE0)		/* uart3_rx.uart3_rx */
+			0x170 (PIN_OUTPUT | MUX_MODE0)		/* uart3_tx.uart3_tx */
 		>;
 	};
 
 	mmc1_pins: pinmux_mmc1_pins {
 		pinctrl-single,pins = <
-			0x114 0x0118    /* sdmmc1_clk.sdmmc1_clk INPUT PULLUP | MODE 0 */
-			0x116 0x0118    /* sdmmc1_cmd.sdmmc1_cmd INPUT PULLUP | MODE 0 */
-			0x118 0x0118 	/* sdmmc1_dat0.sdmmc1_dat0 INPUT PULLUP | MODE 0 */
-			0x11a 0x0118	/* sdmmc1_dat1.sdmmc1_dat1 INPUT PULLUP | MODE 0 */
-			0x11c 0x0118	/* sdmmc1_dat2.sdmmc1_dat2 INPUT PULLUP | MODE 0 */
-			0x11e 0x0118	/* sdmmc1_dat3.sdmmc1_dat3 INPUT PULLUP | MODE 0 */
-			0x120 0x0100	/* sdmmc1_dat4.sdmmc1_dat4 INPUT | MODE 0 */
-			0x122 0x0100	/* sdmmc1_dat5.sdmmc1_dat5 INPUT | MODE 0 */
-			0x124 0x0100	/* sdmmc1_dat6.sdmmc1_dat6 INPUT | MODE 0 */
-			0x126 0x0100	/* sdmmc1_dat7.sdmmc1_dat7 INPUT | MODE 0 */
+			0x114 (PIN_INPUT_PULLUP | MUX_MODE0)	/* sdmmc1_clk.sdmmc1_clk */
+			0x116 (PIN_INPUT_PULLUP | MUX_MODE0)	/* sdmmc1_cmd.sdmmc1_cmd */
+			0x118 (PIN_INPUT_PULLUP | MUX_MODE0) 	/* sdmmc1_dat0.sdmmc1_dat0 */
+			0x11a (PIN_INPUT_PULLUP | MUX_MODE0)	/* sdmmc1_dat1.sdmmc1_dat1 */
+			0x11c (PIN_INPUT_PULLUP | MUX_MODE0)	/* sdmmc1_dat2.sdmmc1_dat2 */
+			0x11e (PIN_INPUT_PULLUP | MUX_MODE0)	/* sdmmc1_dat3.sdmmc1_dat3 */
+			0x120 (PIN_INPUT | MUX_MODE0)		/* sdmmc1_dat4.sdmmc1_dat4 */
+			0x122 (PIN_INPUT | MUX_MODE0)		/* sdmmc1_dat5.sdmmc1_dat5 */
+			0x124 (PIN_INPUT | MUX_MODE0)		/* sdmmc1_dat6.sdmmc1_dat6 */
+			0x126 (PIN_INPUT | MUX_MODE0)		/* sdmmc1_dat7.sdmmc1_dat7 */
+		>;
+	};
+
+	smsc911x_pins: pinmux_smsc911x_pins {
+		pinctrl-single,pins = <
+			0x1a2 (PIN_INPUT | MUX_MODE4)		/* mcspi1_cs2.gpio_176 */
 		>;
 	};
 };
@@ -80,7 +86,8 @@
 	};
 };
 
-/include/ "twl4030.dtsi"
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
 
 &i2c2 {
 	clock-frequency = <400000>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-overo.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-overo.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-overo.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-overo.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,7 @@
  */
 /dts-v1/;
 
-/include/ "omap34xx.dtsi"
+#include "omap34xx.dtsi"
 
 / {
 	pwmleds {
@@ -21,6 +21,7 @@
 			label = "overo:blue:COM";
 			pwms = <&twl_pwmled 1 7812500>;
 			max-brightness = <127>;
+			linux,default-trigger = "mmc0";
 		};
 	};
 
@@ -49,7 +50,8 @@
 	};
 };
 
-/include/ "twl4030.dtsi"
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
 
 /* i2c2 pins are used for gpio */
 &i2c2 {
@@ -77,3 +79,17 @@
 	mode = <3>;
 	power = <50>;
 };
+
+&omap3_pmx_core {
+	uart3_pins: pinmux_uart3_pins {
+		pinctrl-single,pins = <
+			0x16e (PIN_INPUT | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */
+			0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */
+		>;
+	};
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-tobi.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-tobi.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap3-tobi.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap3-tobi.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@
  * Tobi expansion board is manufactured by Gumstix Inc.
  */
 
-/include/ "omap3-overo.dtsi"
+#include "omap3-overo.dtsi"
 
 / {
 	model = "TI OMAP3 Gumstix Overo on Tobi";
@@ -20,10 +20,58 @@
 		compatible = "gpio-leds";
 		heartbeat {
 			label = "overo:red:gpio21";
-			gpios = <&gpio1 21 0>;
+			gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
 		};
 	};
+
+	vddvario: regulator-vddvario {
+		  compatible = "regulator-fixed";
+		  regulator-name = "vddvario";
+		  regulator-always-on;
+	};
+
+	vdd33a: regulator-vdd33a {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd33a";
+		regulator-always-on;
+	};
+};
+
+&gpmc {
+	ranges = <5 0 0x2c000000 0x1000000>;	/* CS5 */
+
+	ethernet@5,0 {
+		compatible = "smsc,lan9221", "smsc,lan9115";
+		reg = <5 0 0xff>;
+		bank-width = <2>;
+
+		gpmc,mux-add-data;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <42>;
+		gpmc,cs-wr-off-ns = <36>;
+		gpmc,adv-on-ns = <6>;
+		gpmc,adv-rd-off-ns = <12>;
+		gpmc,adv-wr-off-ns = <12>;
+		gpmc,oe-on-ns = <0>;
+		gpmc,oe-off-ns = <42>;
+		gpmc,we-on-ns = <0>;
+		gpmc,we-off-ns = <36>;
+		gpmc,rd-cycle-ns = <60>;
+		gpmc,wr-cycle-ns = <54>;
+		gpmc,access-ns = <36>;
+		gpmc,page-burst-access-ns = <0>;
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <0>;
+		gpmc,wr-data-mux-bus-ns = <18>;
+		gpmc,wr-access-ns = <42>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
+
+		interrupt-parent = <&gpio6>;
+		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
+		reg-io-width = <4>;
+	};
 };
 
 &i2c3 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap443x.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap443x.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap443x.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap443x.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
  * kind, whether express or implied.
  */
 
-/include/ "omap4.dtsi"
+#include "omap4.dtsi"
 
 / {
 	cpus {
@@ -24,4 +24,10 @@
 			clock-latency = <300000>; /* From legacy driver */
 		};
 	};
+
+	bandgap {
+		reg = <0x4a002260 0x4
+		       0x4a00232C 0x4>;
+		compatible = "ti,omap4430-bandgap";
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap4460.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4460.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap4460.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4460.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  * version 2.  This program is licensed "as is" without any warranty of any
  * kind, whether express or implied.
  */
-/include/ "omap4.dtsi"
+#include "omap4.dtsi"
 
 / {
 	cpus {
@@ -25,8 +25,17 @@
 
 	pmu {
 		compatible = "arm,cortex-a9-pmu";
-		interrupts = <0 54 0x4>,
-			     <0 55 0x4>;
+		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
 		ti,hwmods = "debugss";
 	};
+
+	bandgap {
+		reg = <0x4a002260 0x4
+		       0x4a00232C 0x4
+		       0x4a002378 0x18>;
+		compatible = "ti,omap4460-bandgap";
+		interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; /* talert */
+		gpios = <&gpio3 22 0>; /* tshut */
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap4.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap4.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,15 +6,11 @@
  * published by the Free Software Foundation.
  */
 
-/*
- * Carveout for multimedia usecases
- * It should be the last 48MB of the first 512MB memory part
- * In theory, it should not even exist. That zone should be reserved
- * dynamically during the .reserve callback.
- */
-/memreserve/ 0x9d000000 0x03000000;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/omap.h>
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
 	compatible = "ti,omap4430", "ti,omap4";
@@ -28,13 +24,20 @@
 	};
 
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
 		cpu@0 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			next-level-cache = <&L2>;
+			reg = <0x0>;
 		};
 		cpu@1 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			next-level-cache = <&L2>;
+			reg = <0x1>;
 		};
 	};
 
@@ -56,7 +59,7 @@
 	local-timer@0x48240600 {
 		compatible = "arm,cortex-a9-twd-timer";
 		reg = <0x48240600 0x20>;
-		interrupts = <1 13 0x304>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
 	/*
@@ -97,8 +100,8 @@
 		reg = <0x44000000 0x1000>,
 		      <0x44800000 0x2000>,
 		      <0x45000000 0x1000>;
-		interrupts = <0 9 0x4>,
-			     <0 10 0x4>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
 
 		counter32k: counter@4a304000 {
 			compatible = "ti,omap-counter32k";
@@ -126,10 +129,10 @@
 		sdma: dma-controller@4a056000 {
 			compatible = "ti,omap4430-sdma";
 			reg = <0x4a056000 0x1000>;
-			interrupts = <0 12 0x4>,
-				     <0 13 0x4>,
-				     <0 14 0x4>,
-				     <0 15 0x4>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
 			#dma-cells = <1>;
 			#dma-channels = <32>;
 			#dma-requests = <127>;
@@ -138,7 +141,7 @@
 		gpio1: gpio@4a310000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x4a310000 0x200>;
-			interrupts = <0 29 0x4>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio1";
 			ti,gpio-always-on;
 			gpio-controller;
@@ -150,7 +153,7 @@
 		gpio2: gpio@48055000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x48055000 0x200>;
-			interrupts = <0 30 0x4>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio2";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -161,7 +164,7 @@
 		gpio3: gpio@48057000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x48057000 0x200>;
-			interrupts = <0 31 0x4>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio3";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -172,7 +175,7 @@
 		gpio4: gpio@48059000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x48059000 0x200>;
-			interrupts = <0 32 0x4>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio4";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -183,7 +186,7 @@
 		gpio5: gpio@4805b000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x4805b000 0x200>;
-			interrupts = <0 33 0x4>;
+			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio5";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -194,7 +197,7 @@
 		gpio6: gpio@4805d000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x4805d000 0x200>;
-			interrupts = <0 34 0x4>;
+			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio6";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -207,7 +210,7 @@
 			reg = <0x50000000 0x1000>;
 			#address-cells = <2>;
 			#size-cells = <1>;
-			interrupts = <0 20 0x4>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 			gpmc,num-cs = <8>;
 			gpmc,num-waitpins = <4>;
 			ti,hwmods = "gpmc";
@@ -216,7 +219,7 @@
 		uart1: serial@4806a000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x4806a000 0x100>;
-			interrupts = <0 72 0x4>;
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart1";
 			clock-frequency = <48000000>;
 		};
@@ -224,7 +227,7 @@
 		uart2: serial@4806c000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x4806c000 0x100>;
-			interrupts = <0 73 0x4>;
+			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart2";
 			clock-frequency = <48000000>;
 		};
@@ -232,7 +235,7 @@
 		uart3: serial@48020000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x48020000 0x100>;
-			interrupts = <0 74 0x4>;
+			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart3";
 			clock-frequency = <48000000>;
 		};
@@ -240,7 +243,7 @@
 		uart4: serial@4806e000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x4806e000 0x100>;
-			interrupts = <0 70 0x4>;
+			interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart4";
 			clock-frequency = <48000000>;
 		};
@@ -248,7 +251,7 @@
 		i2c1: i2c@48070000 {
 			compatible = "ti,omap4-i2c";
 			reg = <0x48070000 0x100>;
-			interrupts = <0 56 0x4>;
+			interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "i2c1";
@@ -257,7 +260,7 @@
 		i2c2: i2c@48072000 {
 			compatible = "ti,omap4-i2c";
 			reg = <0x48072000 0x100>;
-			interrupts = <0 57 0x4>;
+			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "i2c2";
@@ -266,7 +269,7 @@
 		i2c3: i2c@48060000 {
 			compatible = "ti,omap4-i2c";
 			reg = <0x48060000 0x100>;
-			interrupts = <0 61 0x4>;
+			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "i2c3";
@@ -275,7 +278,7 @@
 		i2c4: i2c@48350000 {
 			compatible = "ti,omap4-i2c";
 			reg = <0x48350000 0x100>;
-			interrupts = <0 62 0x4>;
+			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "i2c4";
@@ -284,7 +287,7 @@
 		mcspi1: spi@48098000 {
 			compatible = "ti,omap4-mcspi";
 			reg = <0x48098000 0x200>;
-			interrupts = <0 65 0x4>;
+			interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "mcspi1";
@@ -304,7 +307,7 @@
 		mcspi2: spi@4809a000 {
 			compatible = "ti,omap4-mcspi";
 			reg = <0x4809a000 0x200>;
-			interrupts = <0 66 0x4>;
+			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "mcspi2";
@@ -319,7 +322,7 @@
 		mcspi3: spi@480b8000 {
 			compatible = "ti,omap4-mcspi";
 			reg = <0x480b8000 0x200>;
-			interrupts = <0 91 0x4>;
+			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "mcspi3";
@@ -331,7 +334,7 @@
 		mcspi4: spi@480ba000 {
 			compatible = "ti,omap4-mcspi";
 			reg = <0x480ba000 0x200>;
-			interrupts = <0 48 0x4>;
+			interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "mcspi4";
@@ -343,7 +346,7 @@
 		mmc1: mmc@4809c000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x4809c000 0x400>;
-			interrupts = <0 83 0x4>;
+			interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc1";
 			ti,dual-volt;
 			ti,needs-special-reset;
@@ -354,7 +357,7 @@
 		mmc2: mmc@480b4000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x480b4000 0x400>;
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc2";
 			ti,needs-special-reset;
 			dmas = <&sdma 47>, <&sdma 48>;
@@ -364,7 +367,7 @@
 		mmc3: mmc@480ad000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x480ad000 0x400>;
-			interrupts = <0 94 0x4>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc3";
 			ti,needs-special-reset;
 			dmas = <&sdma 77>, <&sdma 78>;
@@ -374,7 +377,7 @@
 		mmc4: mmc@480d1000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x480d1000 0x400>;
-			interrupts = <0 96 0x4>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc4";
 			ti,needs-special-reset;
 			dmas = <&sdma 57>, <&sdma 58>;
@@ -384,7 +387,7 @@
 		mmc5: mmc@480d5000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x480d5000 0x400>;
-			interrupts = <0 59 0x4>;
+			interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc5";
 			ti,needs-special-reset;
 			dmas = <&sdma 59>, <&sdma 60>;
@@ -394,7 +397,7 @@
 		wdt2: wdt@4a314000 {
 			compatible = "ti,omap4-wdt", "ti,omap3-wdt";
 			reg = <0x4a314000 0x80>;
-			interrupts = <0 80 0x4>;
+			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "wd_timer2";
 		};
 
@@ -403,7 +406,7 @@
 			reg = <0x40132000 0x7f>, /* MPU private access */
 			      <0x49032000 0x7f>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 112 0x4>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mcpdm";
 			dmas = <&sdma 65>,
 			       <&sdma 66>;
@@ -415,7 +418,7 @@
 			reg = <0x4012e000 0x7f>, /* MPU private access */
 			      <0x4902e000 0x7f>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 114 0x4>;
+			interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "dmic";
 			dmas = <&sdma 67>;
 			dma-names = "up_link";
@@ -426,7 +429,7 @@
 			reg = <0x40122000 0xff>, /* MPU private access */
 			      <0x49022000 0xff>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 17 0x4>;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "common";
 			ti,buffer-size = <128>;
 			ti,hwmods = "mcbsp1";
@@ -440,7 +443,7 @@
 			reg = <0x40124000 0xff>, /* MPU private access */
 			      <0x49024000 0xff>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 22 0x4>;
+			interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "common";
 			ti,buffer-size = <128>;
 			ti,hwmods = "mcbsp2";
@@ -454,7 +457,7 @@
 			reg = <0x40126000 0xff>, /* MPU private access */
 			      <0x49026000 0xff>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 23 0x4>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "common";
 			ti,buffer-size = <128>;
 			ti,hwmods = "mcbsp3";
@@ -467,7 +470,7 @@
 			compatible = "ti,omap4-mcbsp";
 			reg = <0x48096000 0xff>; /* L4 Interconnect */
 			reg-names = "mpu";
-			interrupts = <0 16 0x4>;
+			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "common";
 			ti,buffer-size = <128>;
 			ti,hwmods = "mcbsp4";
@@ -479,7 +482,7 @@
 		keypad: keypad@4a31c000 {
 			compatible = "ti,omap4-keypad";
 			reg = <0x4a31c000 0x80>;
-			interrupts = <0 120 0x4>;
+			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
 			reg-names = "mpu";
 			ti,hwmods = "kbd";
 		};
@@ -487,7 +490,7 @@
 		emif1: emif@4c000000 {
 			compatible = "ti,emif-4d";
 			reg = <0x4c000000 0x100>;
-			interrupts = <0 110 0x4>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "emif1";
 			phy-type = <1>;
 			hw-caps-read-idle-ctrl;
@@ -498,7 +501,7 @@
 		emif2: emif@4d000000 {
 			compatible = "ti,emif-4d";
 			reg = <0x4d000000 0x100>;
-			interrupts = <0 111 0x4>;
+			interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "emif2";
 			phy-type = <1>;
 			hw-caps-read-idle-ctrl;
@@ -523,7 +526,7 @@
 		timer1: timer@4a318000 {
 			compatible = "ti,omap3430-timer";
 			reg = <0x4a318000 0x80>;
-			interrupts = <0 37 0x4>;
+			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer1";
 			ti,timer-alwon;
 		};
@@ -531,21 +534,21 @@
 		timer2: timer@48032000 {
 			compatible = "ti,omap3430-timer";
 			reg = <0x48032000 0x80>;
-			interrupts = <0 38 0x4>;
+			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer2";
 		};
 
 		timer3: timer@48034000 {
 			compatible = "ti,omap4430-timer";
 			reg = <0x48034000 0x80>;
-			interrupts = <0 39 0x4>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer3";
 		};
 
 		timer4: timer@48036000 {
 			compatible = "ti,omap4430-timer";
 			reg = <0x48036000 0x80>;
-			interrupts = <0 40 0x4>;
+			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer4";
 		};
 
@@ -553,7 +556,7 @@
 			compatible = "ti,omap4430-timer";
 			reg = <0x40138000 0x80>,
 			      <0x49038000 0x80>;
-			interrupts = <0 41 0x4>;
+			interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer5";
 			ti,timer-dsp;
 		};
@@ -562,7 +565,7 @@
 			compatible = "ti,omap4430-timer";
 			reg = <0x4013a000 0x80>,
 			      <0x4903a000 0x80>;
-			interrupts = <0 42 0x4>;
+			interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer6";
 			ti,timer-dsp;
 		};
@@ -571,7 +574,7 @@
 			compatible = "ti,omap4430-timer";
 			reg = <0x4013c000 0x80>,
 			      <0x4903c000 0x80>;
-			interrupts = <0 43 0x4>;
+			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer7";
 			ti,timer-dsp;
 		};
@@ -580,7 +583,7 @@
 			compatible = "ti,omap4430-timer";
 			reg = <0x4013e000 0x80>,
 			      <0x4903e000 0x80>;
-			interrupts = <0 44 0x4>;
+			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer8";
 			ti,timer-pwm;
 			ti,timer-dsp;
@@ -589,7 +592,7 @@
 		timer9: timer@4803e000 {
 			compatible = "ti,omap4430-timer";
 			reg = <0x4803e000 0x80>;
-			interrupts = <0 45 0x4>;
+			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer9";
 			ti,timer-pwm;
 		};
@@ -597,7 +600,7 @@
 		timer10: timer@48086000 {
 			compatible = "ti,omap3430-timer";
 			reg = <0x48086000 0x80>;
-			interrupts = <0 46 0x4>;
+			interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer10";
 			ti,timer-pwm;
 		};
@@ -605,7 +608,7 @@
 		timer11: timer@48088000 {
 			compatible = "ti,omap4430-timer";
 			reg = <0x48088000 0x80>;
-			interrupts = <0 47 0x4>;
+			interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer11";
 			ti,timer-pwm;
 		};
@@ -613,7 +616,7 @@
 		usbhstll: usbhstll@4a062000 {
 			compatible = "ti,usbhs-tll";
 			reg = <0x4a062000 0x1000>;
-			interrupts = <0 78 0x4>;
+			interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "usb_tll_hs";
 		};
 
@@ -629,14 +632,14 @@
 				compatible = "ti,ohci-omap3", "usb-ohci";
 				reg = <0x4a064800 0x400>;
 				interrupt-parent = <&gic>;
-				interrupts = <0 76 0x4>;
+				interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
 			};
 
 			usbhsehci: ehci@4a064c00 {
 				compatible = "ti,ehci-omap", "usb-ehci";
 				reg = <0x4a064c00 0x400>;
 				interrupt-parent = <&gic>;
-				interrupts = <0 77 0x4>;
+				interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
 			};
 		};
 
@@ -651,7 +654,7 @@
 		usb_otg_hs: usb_otg_hs@4a0ab000 {
 			compatible = "ti,omap4-musb";
 			reg = <0x4a0ab000 0x7ff>;
-			interrupts = <0 92 0x4>, <0 93 0x4>;
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "mc", "dma";
 			ti,hwmods = "usb_otg_hs";
 			usb-phy = <&usb2_phy>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-panda-a4.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-panda-a4.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-panda-a4.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-panda-a4.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,14 +7,14 @@
  */
 /dts-v1/;
 
-/include/ "omap443x.dtsi"
-/include/ "omap4-panda-common.dtsi"
+#include "omap443x.dtsi"
+#include "omap4-panda-common.dtsi"
 
 /* Pandaboard Rev A4+ have external pullups on SCL & SDA */
 &dss_hdmi_pins {
 	pinctrl-single,pins = <
-		0x5a 0x118	/* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */
-		0x5c 0x100	/* hdmi_scl.hdmi_scl INPUT | MODE 0 */
-		0x5e 0x100	/* hdmi_sda.hdmi_sda INPUT | MODE 0 */
+		0x5a (PIN_INPUT_PULLUP | MUX_MODE0)	/* hdmi_cec.hdmi_cec */
+		0x5c (PIN_INPUT | MUX_MODE0)		/* hdmi_scl.hdmi_scl */
+		0x5e (PIN_INPUT | MUX_MODE0)		/* hdmi_sda.hdmi_sda */
 		>;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-panda-common.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-panda-common.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-panda-common.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-panda-common.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-/include/ "elpida_ecb240abacn.dtsi"
+#include "elpida_ecb240abacn.dtsi"
 
 / {
 	model = "TI OMAP4 PandaBoard";
@@ -16,17 +16,22 @@
 		reg = <0x80000000 0x40000000>; /* 1 GB */
 	};
 
-	leds {
+	leds: leds {
 		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <
+			&led_wkgpio_pins
+		>;
+
 		heartbeat {
 			label = "pandaboard::status1";
-			gpios = <&gpio1 7 0>;
+			gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 
 		mmc {
 			label = "pandaboard::status2";
-			gpios = <&gpio1 8 0>;
+			gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "mmc0";
 		};
 	};
@@ -54,6 +59,54 @@
 			"AFML", "Line In",
 			"AFMR", "Line In";
 	};
+
+	/*
+	 * Temp hack: Need to be replaced with the proper gpio-controlled
+	 * reset driver as soon it will be merged.
+	 * http://thread.gmane.org/gmane.linux.drivers.devicetree/36830
+	 */
+	/* HS USB Port 1 RESET */
+	hsusb1_reset: hsusb1_reset_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "hsusb1_reset";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio2 30 0>;	/* gpio_62 */
+		startup-delay-us = <70000>;
+		enable-active-high;
+	};
+
+	/* HS USB Port 1 Power */
+	hsusb1_power: hsusb1_power_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "hsusb1_vbus";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio1 1 0>;	/* gpio_1 */
+		startup-delay-us = <70000>;
+		enable-active-high;
+		/*
+		 * boot-on is required along with always-on as the
+		 * regulator framework doesn't enable the regulator
+		 * if boot-on is not there.
+		 */
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	/* HS USB Host PHY on PORT 1 */
+	hsusb1_phy: hsusb1_phy {
+		compatible = "usb-nop-xceiv";
+		reset-supply = <&hsusb1_reset>;
+		vcc-supply = <&hsusb1_power>;
+	/**
+	 * FIXME:
+	 * put the right clock phandle here when available
+	 *	clocks = <&auxclk3>;
+	 *	clock-names = "main_clk";
+	 */
+		clock-frequency = <19200000>;
+	};
 };
 
 &omap4_pmx_wkup {
@@ -64,7 +117,7 @@
 
 	twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
 		pinctrl-single,pins = <
-			0x14 0x2        /* fref_clk0_out.sys_drm_msecure OUTPUT | MODE2 */
+			0x14 (PIN_OUTPUT | MUX_MODE2)		/* fref_clk0_out.sys_drm_msecure */
 		>;
 	};
 };
@@ -78,81 +131,108 @@
 			&mcbsp1_pins
 			&dss_hdmi_pins
 			&tpd12s015_pins
+			&hsusbb1_pins
 	>;
 
 	twl6030_pins: pinmux_twl6030_pins {
 		pinctrl-single,pins = <
-			0x15e 0x4118	/* sys_nirq1.sys_nirq1 OMAP_WAKEUP_EN | INPUT_PULLUP | MODE0 */
+			0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0)	/* sys_nirq1.sys_nirq1 */
 		>;
 	};
 
 	twl6040_pins: pinmux_twl6040_pins {
 		pinctrl-single,pins = <
-			0xe0 0x3	/* hdq_sio.gpio_127 OUTPUT | MODE3 */
-			0x160 0x100	/* sys_nirq2.sys_nirq2 INPUT | MODE0 */
+			0xe0 (PIN_OUTPUT | MUX_MODE3)	/* hdq_sio.gpio_127 */
+			0x160 (PIN_INPUT | MUX_MODE0)	/* sys_nirq2.sys_nirq2 */
 		>;
 	};
 
 	mcpdm_pins: pinmux_mcpdm_pins {
 		pinctrl-single,pins = <
-			0xc6 0x108	/* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
-			0xc8 0x108	/* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
-			0xca 0x118	/* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
-			0xcc 0x108	/* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
-			0xce 0x108	/* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+			0xc6 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_pdm_ul_data.abe_pdm_ul_data */
+			0xc8 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_pdm_dl_data.abe_pdm_dl_data */
+			0xca (PIN_INPUT_PULLUP   | MUX_MODE0)	/* abe_pdm_frame.abe_pdm_frame */
+			0xcc (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_pdm_lb_clk.abe_pdm_lb_clk */
+			0xce (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_clks.abe_clks */
 		>;
 	};
 
 	mcbsp1_pins: pinmux_mcbsp1_pins {
 		pinctrl-single,pins = <
-			0xbe 0x100	/* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
-			0xc0 0x108	/* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
-			0xc2 0x8		/* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
-			0xc4 0x100	/* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
+			0xbe (PIN_INPUT | MUX_MODE0)		/* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
+			0xc0 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_mcbsp1_dr.abe_mcbsp1_dr */
+			0xc2 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* abe_mcbsp1_dx.abe_mcbsp1_dx */
+			0xc4 (PIN_INPUT | MUX_MODE0)		/* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
 		>;
 	};
 
 	dss_hdmi_pins: pinmux_dss_hdmi_pins {
 		pinctrl-single,pins = <
-			0x5a 0x118	/* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */
-			0x5c 0x118	/* hdmi_scl.hdmi_scl INPUT PULLUP | MODE 0 */
-			0x5e 0x118	/* hdmi_sda.hdmi_sda INPUT PULLUP | MODE 0 */
+			0x5a (PIN_INPUT_PULLUP | MUX_MODE0)	/* hdmi_cec.hdmi_cec */
+			0x5c (PIN_INPUT_PULLUP | MUX_MODE0)	/* hdmi_scl.hdmi_scl */
+			0x5e (PIN_INPUT_PULLUP | MUX_MODE0)	/* hdmi_sda.hdmi_sda */
 		>;
 	};
 
 	tpd12s015_pins: pinmux_tpd12s015_pins {
 		pinctrl-single,pins = <
-			0x22 0x3	/* gpmc_a17.gpio_41 OUTPUT | MODE3 */
-			0x48 0x3	/* gpmc_nbe1.gpio_60 OUTPUT | MODE3 */
-			0x58 0x10b	/* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */
+			0x22 (PIN_OUTPUT | MUX_MODE3)		/* gpmc_a17.gpio_41 */
+			0x48 (PIN_OUTPUT | MUX_MODE3)		/* gpmc_nbe1.gpio_60 */
+			0x58 (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* hdmi_hpd.gpio_63 */
+		>;
+	};
+
+	hsusbb1_pins: pinmux_hsusbb1_pins {
+		pinctrl-single,pins = <
+			0x82 (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */
+			0x84 (PIN_OUTPUT | MUX_MODE4)		/* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */
+			0x86 (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_dir.usbb1_ulpiphy_dir */
+			0x88 (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_nxt.usbb1_ulpiphy_nxt */
+			0x8a (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_dat0.usbb1_ulpiphy_dat0 */
+			0x8c (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_dat1.usbb1_ulpiphy_dat1 */
+			0x8e (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_dat2.usbb1_ulpiphy_dat2 */
+			0x90 (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_dat3.usbb1_ulpiphy_dat3 */
+			0x92 (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_dat4.usbb1_ulpiphy_dat4 */
+			0x94 (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_dat5.usbb1_ulpiphy_dat5 */
+			0x96 (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_dat6.usbb1_ulpiphy_dat6 */
+			0x98 (PIN_INPUT_PULLDOWN | MUX_MODE4)	/* usbb1_ulpitll_dat7.usbb1_ulpiphy_dat7 */
 		>;
 	};
 
 	i2c1_pins: pinmux_i2c1_pins {
 		pinctrl-single,pins = <
-			0xe2 0x118        /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */
-			0xe4 0x118        /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */
+			0xe2 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c1_scl */
+			0xe4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c1_sda */
 		>;
 	};
 
 	i2c2_pins: pinmux_i2c2_pins {
 		pinctrl-single,pins = <
-			0xe6 0x118        /* i2c2_scl PULLUP | INPUTENABLE | MODE0 */
-			0xe8 0x118        /* i2c2_sda PULLUP | INPUTENABLE | MODE0 */
+			0xe6 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c2_scl */
+			0xe8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c2_sda */
 		>;
 	};
 
 	i2c3_pins: pinmux_i2c3_pins {
 		pinctrl-single,pins = <
-			0xea 0x118        /* i2c3_scl PULLUP | INPUTENABLE | MODE0 */
-			0xec 0x118     /* i2c3_sda PULLUP | INPUTENABLE | MODE0 */
+			0xea (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c3_scl */
+			0xec (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c3_sda */
 		>;
 	};
 
 	i2c4_pins: pinmux_i2c4_pins {
 		pinctrl-single,pins = <
-			0xee 0x118        /* i2c4_scl PULLUP | INPUTENABLE | MODE0 */
-			0xf0 0x118     /* i2c4_sda PULLUP | INPUTENABLE | MODE0 */
+			0xee (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c4_scl */
+			0xf0 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c4_sda */
+		>;
+	};
+};
+
+&omap4_pmx_wkup {
+	led_wkgpio_pins: pinmux_leds_wkpins {
+		pinctrl-single,pins = <
+			0x1a (PIN_OUTPUT | MUX_MODE3)	/* gpio_wk7 */
+			0x1c (PIN_OUTPUT | MUX_MODE3)	/* gpio_wk8 */
 		>;
 	};
 };
@@ -165,18 +245,18 @@
 
 	twl: twl@48 {
 		reg = <0x48>;
-		/* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
-		interrupts = <0 7 4>; /* IRQ_SYS_1N cascaded to gic */
+		/* IRQ# = 7 */
+		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
 		interrupt-parent = <&gic>;
 	};
 
 	twl6040: twl@4b {
 		compatible = "ti,twl6040";
 		reg = <0x4b>;
-		/* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
-		interrupts = <0 119 4>; /* IRQ_SYS_2N cascaded to gic */
+		/* IRQ# = 119 */
+		interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
 		interrupt-parent = <&gic>;
-		ti,audpwron-gpio = <&gpio4 31 0>;  /* gpio line 127 */
+		ti,audpwron-gpio = <&gpio4 31 GPIO_ACTIVE_HIGH>;  /* gpio line 127 */
 
 		vio-supply = <&v1v8>;
 		v2v1-supply = <&v2v1>;
@@ -184,7 +264,7 @@
 	};
 };
 
-/include/ "twl6030.dtsi"
+#include "twl6030.dtsi"
 
 &i2c2 {
 	pinctrl-names = "default";
@@ -269,3 +349,11 @@
 	mode = <3>;
 	power = <50>;
 };
+
+&usbhshost {
+	port1-mode = "ehci-phy";
+};
+
+&usbhsehci {
+	phys = <&hsusb1_phy>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-panda.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-panda.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-panda.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-panda.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,5 +7,5 @@
  */
 /dts-v1/;
 
-/include/ "omap443x.dtsi"
-/include/ "omap4-panda-common.dtsi"
+#include "omap443x.dtsi"
+#include "omap4-panda-common.dtsi"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-panda-es.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-panda-es.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-panda-es.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-panda-es.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  */
 /dts-v1/;
 
-/include/ "omap4460.dtsi"
-/include/ "omap4-panda-common.dtsi"
+#include "omap4460.dtsi"
+#include "omap4-panda-common.dtsi"
 
 /* Audio routing is differnet between PandaBoard4430 and PandaBoardES */
 &sound {
@@ -29,8 +29,36 @@
 /* PandaboardES has external pullups on SCL & SDA */
 &dss_hdmi_pins {
 	pinctrl-single,pins = <
-		0x5a 0x118	/* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */
-		0x5c 0x100	/* hdmi_scl.hdmi_scl INPUT | MODE 0 */
-		0x5e 0x100	/* hdmi_sda.hdmi_sda INPUT | MODE 0 */
+		0x5a (PIN_INPUT_PULLUP | MUX_MODE0)	/* hdmi_cec.hdmi_cec */
+		0x5c (PIN_INPUT | MUX_MODE0)		/* hdmi_scl.hdmi_scl */
+		0x5e (PIN_INPUT | MUX_MODE0)		/* hdmi_sda.hdmi_sda */
 		>;
 };
+
+&omap4_pmx_core {
+	led_gpio_pins: gpio_led_pmx {
+		pinctrl-single,pins = <
+			0xb6 (PIN_OUTPUT | MUX_MODE3)	/* gpio_110 */
+		>;
+	};
+};
+
+&led_wkgpio_pins {
+	pinctrl-single,pins = <
+		0x1c (PIN_OUTPUT | MUX_MODE3)	/* gpio_wk8 */
+	>;
+};
+
+&leds {
+	pinctrl-0 = <
+		&led_gpio_pins
+		&led_wkgpio_pins
+	>;
+
+	heartbeat {
+		gpios = <&gpio4 14 GPIO_ACTIVE_HIGH>;
+	};
+	mmc {
+		gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-sdp.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-sdp.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-sdp.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-sdp.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  */
 /dts-v1/;
 
-/include/ "omap443x.dtsi"
-/include/ "elpida_ecb240abacn.dtsi"
+#include "omap443x.dtsi"
+#include "elpida_ecb240abacn.dtsi"
 
 / {
 	model = "TI OMAP4 SDP board";
@@ -41,42 +41,42 @@
 		compatible = "gpio-leds";
 		debug0 {
 			label = "omap4:green:debug0";
-			gpios = <&gpio2 29 0>; /* 61 */
+			gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>; /* 61 */
 		};
 
 		debug1 {
 			label = "omap4:green:debug1";
-			gpios = <&gpio1 30 0>; /* 30 */
+			gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>; /* 30 */
 		};
 
 		debug2 {
 			label = "omap4:green:debug2";
-			gpios = <&gpio1 7 0>; /* 7 */
+			gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; /* 7 */
 		};
 
 		debug3 {
 			label = "omap4:green:debug3";
-			gpios = <&gpio1 8 0>; /* 8 */
+			gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; /* 8 */
 		};
 
 		debug4 {
 			label = "omap4:green:debug4";
-			gpios = <&gpio2 18 0>; /* 50 */
+			gpios = <&gpio2 18 GPIO_ACTIVE_HIGH>; /* 50 */
 		};
 
 		user1 {
 			label = "omap4:blue:user";
-			gpios = <&gpio6 9 0>; /* 169 */
+			gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>; /* 169 */
 		};
 
 		user2 {
 			label = "omap4:red:user";
-			gpios = <&gpio6 10 0>; /* 170 */
+			gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>; /* 170 */
 		};
 
 		user3 {
 			label = "omap4:green:user";
-			gpios = <&gpio5 11 0>; /* 139 */
+			gpios = <&gpio5 11 GPIO_ACTIVE_HIGH>; /* 139 */
 		};
 	};
 
@@ -150,7 +150,7 @@
 
 	twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
 		pinctrl-single,pins = <
-			0x14 0x2        /* fref_clk0_out.sys_drm_msecure OUTPUT | MODE2 */
+			0x14 (PIN_OUTPUT | MUX_MODE2)		/* fref_clk0_out.sys_drm_msecure */
 		>;
 	};
 };
@@ -170,129 +170,129 @@
 
 	uart2_pins: pinmux_uart2_pins {
 		pinctrl-single,pins = <
-			0xd8 0x118	/* uart2_cts.uart2_cts INPUT_PULLUP | MODE0 */
-			0xda 0		/* uart2_rts.uart2_rts OUTPUT | MODE0 */
-			0xdc 0x118	/* uart2_rx.uart2_rx INPUT_PULLUP | MODE0 */
-			0xde 0		/* uart2_tx.uart2_tx OUTPUT | MODE0 */
+			0xd8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* uart2_cts.uart2_cts */
+			0xda (PIN_OUTPUT | MUX_MODE0)		/* uart2_rts.uart2_rts */
+			0xdc (PIN_INPUT_PULLUP | MUX_MODE0)	/* uart2_rx.uart2_rx */
+			0xde (PIN_OUTPUT | MUX_MODE0)		/* uart2_tx.uart2_tx */
 		>;
 	};
 
 	uart3_pins: pinmux_uart3_pins {
 		pinctrl-single,pins = <
-			0x100 0x118	/* uart3_cts_rctx.uart3_cts_rctx INPUT_PULLUP | MODE0 */
-			0x102 0		/* uart3_rts_sd.uart3_rts_sd OUTPUT | MODE0 */
-			0x104 0x100	/* uart3_rx_irrx.uart3_rx_irrx INPUT | MODE0 */
-			0x106 0		/* uart3_tx_irtx.uart3_tx_irtx OUTPUT | MODE0 */
+			0x100 (PIN_INPUT_PULLUP | MUX_MODE0)	/* uart3_cts_rctx.uart3_cts_rctx */
+			0x102 (PIN_OUTPUT | MUX_MODE0)		/* uart3_rts_sd.uart3_rts_sd */
+			0x104 (PIN_INPUT | MUX_MODE0)		/* uart3_rx_irrx.uart3_rx_irrx */
+			0x106 (PIN_OUTPUT | MUX_MODE0)		/* uart3_tx_irtx.uart3_tx_irtx */
 		>;
 	};
 
 	uart4_pins: pinmux_uart4_pins {
 		pinctrl-single,pins = <
-			0x11c 0x100	/* uart4_rx.uart4_rx INPUT | MODE0 */
-			0x11e 0		/* uart4_tx.uart4_tx OUTPUT | MODE0 */
+			0x11c (PIN_INPUT | MUX_MODE0)		/* uart4_rx.uart4_rx */
+			0x11e (PIN_OUTPUT | MUX_MODE0)		/* uart4_tx.uart4_tx */
 		>;
 	};
 
 	twl6030_pins: pinmux_twl6030_pins {
 		pinctrl-single,pins = <
-			0x15e 0x4118	/* sys_nirq1.sys_nirq1 OMAP_WAKEUP_EN | INPUT_PULLUP | MODE0 */
+			0x15e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0)	/* sys_nirq1.sys_nirq1 */
 		>;
 	};
 
 	twl6040_pins: pinmux_twl6040_pins {
 		pinctrl-single,pins = <
-			0xe0 0x3	/* hdq_sio.gpio_127 OUTPUT | MODE3 */
-			0x160 0x100	/* sys_nirq2.sys_nirq2 INPUT | MODE0 */
+			0xe0 (PIN_OUTPUT | MUX_MODE3)		/* hdq_sio.gpio_127 */
+			0x160 (PIN_INPUT | MUX_MODE0)		/* sys_nirq2.sys_nirq2 */
 		>;
 	};
 
 	mcpdm_pins: pinmux_mcpdm_pins {
 		pinctrl-single,pins = <
-			0xc6 0x108	/* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
-			0xc8 0x108	/* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
-			0xca 0x118	/* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
-			0xcc 0x108	/* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
-			0xce 0x108	/* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+			0xc6 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_pdm_ul_data.abe_pdm_ul_data */
+			0xc8 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_pdm_dl_data.abe_pdm_dl_data */
+			0xca (PIN_INPUT_PULLUP | MUX_MODE0)	/* abe_pdm_frame.abe_pdm_frame */
+			0xcc (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_pdm_lb_clk.abe_pdm_lb_clk */
+			0xce (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_clks.abe_clks */
 		>;
 	};
 
 	dmic_pins: pinmux_dmic_pins {
 		pinctrl-single,pins = <
-			0xd0 0		/* abe_dmic_clk1.abe_dmic_clk1 OUTPUT | MODE0 */
-			0xd2 0x100	/* abe_dmic_din1.abe_dmic_din1 INPUT | MODE0 */
-			0xd4 0x100	/* abe_dmic_din2.abe_dmic_din2 INPUT | MODE0 */
-			0xd6 0x100	/* abe_dmic_din3.abe_dmic_din3 INPUT | MODE0 */
+			0xd0 (PIN_OUTPUT | MUX_MODE0)		/* abe_dmic_clk1.abe_dmic_clk1 */
+			0xd2 (PIN_INPUT | MUX_MODE0)		/* abe_dmic_din1.abe_dmic_din1 */
+			0xd4 (PIN_INPUT | MUX_MODE0)		/* abe_dmic_din2.abe_dmic_din2 */
+			0xd6 (PIN_INPUT | MUX_MODE0)		/* abe_dmic_din3.abe_dmic_din3 */
 		>;
 	};
 
 	mcbsp1_pins: pinmux_mcbsp1_pins {
 		pinctrl-single,pins = <
-			0xbe 0x100	/* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
-			0xc0 0x108	/* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
-			0xc2 0x8	/* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
-			0xc4 0x100	/* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
+			0xbe (PIN_INPUT | MUX_MODE0)		/* abe_mcbsp1_clkx.abe_mcbsp1_clkx */
+			0xc0 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_mcbsp1_dr.abe_mcbsp1_dr */
+			0xc2 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* abe_mcbsp1_dx.abe_mcbsp1_dx */
+			0xc4 (PIN_INPUT | MUX_MODE0)		/* abe_mcbsp1_fsx.abe_mcbsp1_fsx */
 		>;
 	};
 
 	mcbsp2_pins: pinmux_mcbsp2_pins {
 		pinctrl-single,pins = <
-			0xb6 0x100	/* abe_mcbsp2_clkx.abe_mcbsp2_clkx INPUT | MODE0 */
-			0xb8 0x108	/* abe_mcbsp2_dr.abe_mcbsp2_dr INPUT PULLDOWN | MODE0 */
-			0xba 0x8	/* abe_mcbsp2_dx.abe_mcbsp2_dx OUTPUT PULLDOWN | MODE0 */
-			0xbc 0x100	/* abe_mcbsp2_fsx.abe_mcbsp2_fsx INPUT | MODE0 */
+			0xb6 (PIN_INPUT | MUX_MODE0)		/* abe_mcbsp2_clkx.abe_mcbsp2_clkx */
+			0xb8 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_mcbsp2_dr.abe_mcbsp2_dr */
+			0xba (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* abe_mcbsp2_dx.abe_mcbsp2_dx */
+			0xbc (PIN_INPUT | MUX_MODE0)		/* abe_mcbsp2_fsx.abe_mcbsp2_fsx */
 		>;
 	};
 
 	mcspi1_pins: pinmux_mcspi1_pins {
 		pinctrl-single,pins = <
-			0xf2 0x100	/*  mcspi1_clk.mcspi1_clk INPUT | MODE0 */
-			0xf4 0x100	/*  mcspi1_somi.mcspi1_somi INPUT | MODE0 */
-			0xf6 0x100	/*  mcspi1_simo.mcspi1_simo INPUT | MODE0 */
-			0xf8 0x100	/*  mcspi1_cs0.mcspi1_cs0 INPUT | MODE0*/
+			0xf2 (PIN_INPUT | MUX_MODE0)		/*  mcspi1_clk.mcspi1_clk */
+			0xf4 (PIN_INPUT | MUX_MODE0)		/*  mcspi1_somi.mcspi1_somi */
+			0xf6 (PIN_INPUT | MUX_MODE0)		/*  mcspi1_simo.mcspi1_simo */
+			0xf8 (PIN_INPUT | MUX_MODE0)		/*  mcspi1_cs0.mcspi1_cs0 */
 		>;
 	};
 
 	dss_hdmi_pins: pinmux_dss_hdmi_pins {
 		pinctrl-single,pins = <
-			0x5a 0x118	/* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */
-			0x5c 0x118	/* hdmi_scl.hdmi_scl INPUT PULLUP | MODE 0 */
-			0x5e 0x118	/* hdmi_sda.hdmi_sda INPUT PULLUP | MODE 0 */
+			0x5a (PIN_INPUT_PULLUP | MUX_MODE0)	/* hdmi_cec.hdmi_cec */
+			0x5c (PIN_INPUT_PULLUP | MUX_MODE0)	/* hdmi_scl.hdmi_scl */
+			0x5e (PIN_INPUT_PULLUP | MUX_MODE0)	/* hdmi_sda.hdmi_sda */
 		>;
 	};
 
 	tpd12s015_pins: pinmux_tpd12s015_pins {
 		pinctrl-single,pins = <
-			0x22 0x3	/* gpmc_a17.gpio_41 OUTPUT | MODE3 */
-			0x48 0x3	/* gpmc_nbe1.gpio_60 OUTPUT | MODE3 */
-			0x58 0x10b	/* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */
+			0x22 (PIN_OUTPUT | MUX_MODE3)		/* gpmc_a17.gpio_41 */
+			0x48 (PIN_OUTPUT | MUX_MODE3)		/* gpmc_nbe1.gpio_60 */
+			0x58 (PIN_INPUT_PULLDOWN | MUX_MODE3)	/* hdmi_hpd.gpio_63 */
 		>;
 	};
 
 	i2c1_pins: pinmux_i2c1_pins {
 		pinctrl-single,pins = <
-			0xe2 0x118        /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */
-			0xe4 0x118       /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */
+			0xe2 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c1_scl */
+			0xe4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c1_sda */
 		>;
 	};
 
 	i2c2_pins: pinmux_i2c2_pins {
 		pinctrl-single,pins = <
-                        0xe6 0x118        /* i2c2_scl PULLUP | INPUTENABLE | MODE0 */
-                        0xe8 0x118        /* i2c2_sda PULLUP | INPUTENABLE | MODE0 */
+			0xe6 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c2_scl */
+			0xe8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c2_sda */
 		>;
 	};
 
 	i2c3_pins: pinmux_i2c3_pins {
 		pinctrl-single,pins = <
-			0xea 0x118        /* i2c3_scl PULLUP | INPUTENABLE | MODE0 */
-			0xec 0x118     /* i2c3_sda PULLUP | INPUTENABLE | MODE0 */
+			0xea (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c3_scl */
+			0xec (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c3_sda */
 		>;
 	};
 
 	i2c4_pins: pinmux_i2c4_pins {
 		pinctrl-single,pins = <
-			0xee 0x118        /* i2c4_scl PULLUP | INPUTENABLE | MODE0 */
-			0xf0 0x118     /* i2c4_sda PULLUP | INPUTENABLE | MODE0 */
+			0xee (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c4_scl */
+			0xf0 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c4_sda */
 		>;
 	};
 };
@@ -306,7 +306,7 @@
 	twl: twl@48 {
 		reg = <0x48>;
 		/* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
-		interrupts = <0 7 4>; /* IRQ_SYS_1N cascaded to gic */
+		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
 		interrupt-parent = <&gic>;
 	};
 
@@ -314,7 +314,7 @@
 		compatible = "ti,twl6040";
 		reg = <0x4b>;
 		/* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
-		interrupts = <0 119 4>; /* IRQ_SYS_2N cascaded to gic */
+		interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_2N cascaded to gic */
 		interrupt-parent = <&gic>;
 		ti,audpwron-gpio = <&gpio4 31 0>;  /* gpio line 127 */
 
@@ -336,7 +336,7 @@
 	};
 };
 
-/include/ "twl6030.dtsi"
+#include "twl6030.dtsi"
 
 &i2c2 {
 	pinctrl-names = "default";
@@ -395,7 +395,7 @@
 		spi-max-frequency = <24000000>;
 		reg = <0>;
 		interrupt-parent = <&gpio2>;
-		interrupts = <2 8>; /* gpio line 34, low triggered */
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>; /* gpio line 34 */
 		vdd-supply = <&vdd_eth>;
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-sdp-es23plus.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-sdp-es23plus.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-sdp-es23plus.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-sdp-es23plus.dts	2013-08-25 20:43:22.000000000 -0400
@@ -5,13 +5,13 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-/include/ "omap4-sdp.dts"
+#include "omap4-sdp.dts"
 
 /* SDP boards with 4430 ES2.3+ or 4460 have external pullups on SCL & SDA */
 &dss_hdmi_pins {
 	pinctrl-single,pins = <
-		0x5a 0x118	/* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */
-		0x5c 0x100	/* hdmi_scl.hdmi_scl INPUT | MODE 0 */
-		0x5e 0x100	/* hdmi_sda.hdmi_sda INPUT | MODE 0 */
+		0x5a (PIN_INPUT_PULLUP | MUX_MODE0)	/* hdmi_cec.hdmi_cec */
+		0x5c (PIN_INPUT | MUX_MODE0)		/* hdmi_scl.hdmi_scl */
+		0x5e (PIN_INPUT | MUX_MODE0)		/* hdmi_sda.hdmi_sda */
 		>;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-var-som.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-var-som.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap4-var-som.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap4-var-som.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap443x.dtsi"
+#include "omap443x.dtsi"
 
 / {
 	model = "Variscite OMAP4 SOM";
@@ -34,12 +34,12 @@
 	twl: twl@48 {
 		reg = <0x48>;
 		/* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
-		interrupts = <0 7 4>; /* IRQ_SYS_1N cascaded to gic */
+		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
 		interrupt-parent = <&gic>;
 	};
 };
 
-/include/ "twl6030.dtsi"
+#include "twl6030.dtsi"
 
 &i2c2 {
 	clock-frequency = <400000>;
@@ -68,7 +68,7 @@
 		spi-max-frequency = <24000000>;
 		reg = <0>;
 		interrupt-parent = <&gpio6>;
-		interrupts = <11 8>; /* gpio line 171, low triggered */
+		interrupts = <11 IRQ_TYPE_LEVEL_LOW>; /* gpio line 171 */
 		vdd-supply = <&vdd_eth>;
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap5.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap5.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap5.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap5.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -7,15 +7,11 @@
  * Based on "omap4.dtsi"
  */
 
-/*
- * Carveout for multimedia usecases
- * It should be the last 48MB of the first 512MB memory part
- * In theory, it should not even exist. That zone should be reserved
- * dynamically during the .reserve callback.
- */
-/memreserve/ 0x9d000000 0x03000000;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/omap.h>
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
 
 / {
 	#address-cells = <1>;
@@ -34,21 +30,28 @@
 	};
 
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
 		cpu@0 {
+			device_type = "cpu";
 			compatible = "arm,cortex-a15";
+			reg = <0x0>;
 		};
 		cpu@1 {
+			device_type = "cpu";
 			compatible = "arm,cortex-a15";
+			reg = <0x1>;
 		};
 	};
 
 	timer {
 		compatible = "arm,armv7-timer";
-		/* PPI secure/nonsecure IRQ, active low level-sensitive */
-		interrupts = <1 13 0x308>,
-			     <1 14 0x308>,
-			     <1 11 0x308>,
-			     <1 10 0x308>;
+		/* PPI secure/nonsecure IRQ */
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_LOW)>;
 		clock-frequency = <6144000>;
 	};
 
@@ -90,8 +93,8 @@
 		reg = <0x44000000 0x2000>,
 		      <0x44800000 0x3000>,
 		      <0x45000000 0x4000>;
-		interrupts = <0 9 0x4>,
-			     <0 10 0x4>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
 
 		counter32k: counter@4ae04000 {
 			compatible = "ti,omap-counter32k";
@@ -119,10 +122,10 @@
 		sdma: dma-controller@4a056000 {
 			compatible = "ti,omap4430-sdma";
 			reg = <0x4a056000 0x1000>;
-			interrupts = <0 12 0x4>,
-				     <0 13 0x4>,
-				     <0 14 0x4>,
-				     <0 15 0x4>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
 			#dma-cells = <1>;
 			#dma-channels = <32>;
 			#dma-requests = <127>;
@@ -131,7 +134,7 @@
 		gpio1: gpio@4ae10000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x4ae10000 0x200>;
-			interrupts = <0 29 0x4>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio1";
 			ti,gpio-always-on;
 			gpio-controller;
@@ -143,7 +146,7 @@
 		gpio2: gpio@48055000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x48055000 0x200>;
-			interrupts = <0 30 0x4>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio2";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -154,7 +157,7 @@
 		gpio3: gpio@48057000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x48057000 0x200>;
-			interrupts = <0 31 0x4>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio3";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -165,7 +168,7 @@
 		gpio4: gpio@48059000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x48059000 0x200>;
-			interrupts = <0 32 0x4>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio4";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -176,7 +179,7 @@
 		gpio5: gpio@4805b000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x4805b000 0x200>;
-			interrupts = <0 33 0x4>;
+			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio5";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -187,7 +190,7 @@
 		gpio6: gpio@4805d000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x4805d000 0x200>;
-			interrupts = <0 34 0x4>;
+			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio6";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -198,7 +201,7 @@
 		gpio7: gpio@48051000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x48051000 0x200>;
-			interrupts = <0 35 0x4>;
+			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio7";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -209,7 +212,7 @@
 		gpio8: gpio@48053000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x48053000 0x200>;
-			interrupts = <0 121 0x4>;
+			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "gpio8";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -222,7 +225,7 @@
 			reg = <0x50000000 0x1000>;
 			#address-cells = <2>;
 			#size-cells = <1>;
-			interrupts = <0 20 0x4>;
+			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 			gpmc,num-cs = <8>;
 			gpmc,num-waitpins = <4>;
 			ti,hwmods = "gpmc";
@@ -231,7 +234,7 @@
 		i2c1: i2c@48070000 {
 			compatible = "ti,omap4-i2c";
 			reg = <0x48070000 0x100>;
-			interrupts = <0 56 0x4>;
+			interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "i2c1";
@@ -240,7 +243,7 @@
 		i2c2: i2c@48072000 {
 			compatible = "ti,omap4-i2c";
 			reg = <0x48072000 0x100>;
-			interrupts = <0 57 0x4>;
+			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "i2c2";
@@ -249,7 +252,7 @@
 		i2c3: i2c@48060000 {
 			compatible = "ti,omap4-i2c";
 			reg = <0x48060000 0x100>;
-			interrupts = <0 61 0x4>;
+			interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "i2c3";
@@ -258,7 +261,7 @@
 		i2c4: i2c@4807a000 {
 			compatible = "ti,omap4-i2c";
 			reg = <0x4807a000 0x100>;
-			interrupts = <0 62 0x4>;
+			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "i2c4";
@@ -267,7 +270,7 @@
 		i2c5: i2c@4807c000 {
 			compatible = "ti,omap4-i2c";
 			reg = <0x4807c000 0x100>;
-			interrupts = <0 60 0x4>;
+			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "i2c5";
@@ -276,7 +279,7 @@
 		mcspi1: spi@48098000 {
 			compatible = "ti,omap4-mcspi";
 			reg = <0x48098000 0x200>;
-			interrupts = <0 65 0x4>;
+			interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "mcspi1";
@@ -296,7 +299,7 @@
 		mcspi2: spi@4809a000 {
 			compatible = "ti,omap4-mcspi";
 			reg = <0x4809a000 0x200>;
-			interrupts = <0 66 0x4>;
+			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "mcspi2";
@@ -311,7 +314,7 @@
 		mcspi3: spi@480b8000 {
 			compatible = "ti,omap4-mcspi";
 			reg = <0x480b8000 0x200>;
-			interrupts = <0 91 0x4>;
+			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "mcspi3";
@@ -323,7 +326,7 @@
 		mcspi4: spi@480ba000 {
 			compatible = "ti,omap4-mcspi";
 			reg = <0x480ba000 0x200>;
-			interrupts = <0 48 0x4>;
+			interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			ti,hwmods = "mcspi4";
@@ -335,7 +338,7 @@
 		uart1: serial@4806a000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x4806a000 0x100>;
-			interrupts = <0 72 0x4>;
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart1";
 			clock-frequency = <48000000>;
 		};
@@ -343,7 +346,7 @@
 		uart2: serial@4806c000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x4806c000 0x100>;
-			interrupts = <0 73 0x4>;
+			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart2";
 			clock-frequency = <48000000>;
 		};
@@ -351,7 +354,7 @@
 		uart3: serial@48020000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x48020000 0x100>;
-			interrupts = <0 74 0x4>;
+			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart3";
 			clock-frequency = <48000000>;
 		};
@@ -359,7 +362,7 @@
 		uart4: serial@4806e000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x4806e000 0x100>;
-			interrupts = <0 70 0x4>;
+			interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart4";
 			clock-frequency = <48000000>;
 		};
@@ -367,7 +370,7 @@
 		uart5: serial@48066000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x48066000 0x100>;
-			interrupts = <0 105 0x4>;
+			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart5";
 			clock-frequency = <48000000>;
 		};
@@ -375,7 +378,7 @@
 		uart6: serial@48068000 {
 			compatible = "ti,omap4-uart";
 			reg = <0x48068000 0x100>;
-			interrupts = <0 106 0x4>;
+			interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "uart6";
 			clock-frequency = <48000000>;
 		};
@@ -383,7 +386,7 @@
 		mmc1: mmc@4809c000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x4809c000 0x400>;
-			interrupts = <0 83 0x4>;
+			interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc1";
 			ti,dual-volt;
 			ti,needs-special-reset;
@@ -394,7 +397,7 @@
 		mmc2: mmc@480b4000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x480b4000 0x400>;
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc2";
 			ti,needs-special-reset;
 			dmas = <&sdma 47>, <&sdma 48>;
@@ -404,7 +407,7 @@
 		mmc3: mmc@480ad000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x480ad000 0x400>;
-			interrupts = <0 94 0x4>;
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc3";
 			ti,needs-special-reset;
 			dmas = <&sdma 77>, <&sdma 78>;
@@ -414,7 +417,7 @@
 		mmc4: mmc@480d1000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x480d1000 0x400>;
-			interrupts = <0 96 0x4>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc4";
 			ti,needs-special-reset;
 			dmas = <&sdma 57>, <&sdma 58>;
@@ -424,7 +427,7 @@
 		mmc5: mmc@480d5000 {
 			compatible = "ti,omap4-hsmmc";
 			reg = <0x480d5000 0x400>;
-			interrupts = <0 59 0x4>;
+			interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc5";
 			ti,needs-special-reset;
 			dmas = <&sdma 59>, <&sdma 60>;
@@ -442,7 +445,7 @@
 			reg = <0x40132000 0x7f>, /* MPU private access */
 			      <0x49032000 0x7f>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 112 0x4>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mcpdm";
 			dmas = <&sdma 65>,
 			       <&sdma 66>;
@@ -454,7 +457,7 @@
 			reg = <0x4012e000 0x7f>, /* MPU private access */
 			      <0x4902e000 0x7f>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 114 0x4>;
+			interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "dmic";
 			dmas = <&sdma 67>;
 			dma-names = "up_link";
@@ -465,7 +468,7 @@
 			reg = <0x40122000 0xff>, /* MPU private access */
 			      <0x49022000 0xff>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 17 0x4>;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "common";
 			ti,buffer-size = <128>;
 			ti,hwmods = "mcbsp1";
@@ -479,7 +482,7 @@
 			reg = <0x40124000 0xff>, /* MPU private access */
 			      <0x49024000 0xff>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 22 0x4>;
+			interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "common";
 			ti,buffer-size = <128>;
 			ti,hwmods = "mcbsp2";
@@ -493,7 +496,7 @@
 			reg = <0x40126000 0xff>, /* MPU private access */
 			      <0x49026000 0xff>; /* L3 Interconnect */
 			reg-names = "mpu", "dma";
-			interrupts = <0 23 0x4>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "common";
 			ti,buffer-size = <128>;
 			ti,hwmods = "mcbsp3";
@@ -505,7 +508,7 @@
 		timer1: timer@4ae18000 {
 			compatible = "ti,omap5430-timer";
 			reg = <0x4ae18000 0x80>;
-			interrupts = <0 37 0x4>;
+			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer1";
 			ti,timer-alwon;
 		};
@@ -513,21 +516,21 @@
 		timer2: timer@48032000 {
 			compatible = "ti,omap5430-timer";
 			reg = <0x48032000 0x80>;
-			interrupts = <0 38 0x4>;
+			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer2";
 		};
 
 		timer3: timer@48034000 {
 			compatible = "ti,omap5430-timer";
 			reg = <0x48034000 0x80>;
-			interrupts = <0 39 0x4>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer3";
 		};
 
 		timer4: timer@48036000 {
 			compatible = "ti,omap5430-timer";
 			reg = <0x48036000 0x80>;
-			interrupts = <0 40 0x4>;
+			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer4";
 		};
 
@@ -535,7 +538,7 @@
 			compatible = "ti,omap5430-timer";
 			reg = <0x40138000 0x80>,
 			      <0x49038000 0x80>;
-			interrupts = <0 41 0x4>;
+			interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer5";
 			ti,timer-dsp;
 			ti,timer-pwm;
@@ -545,7 +548,7 @@
 			compatible = "ti,omap5430-timer";
 			reg = <0x4013a000 0x80>,
 			      <0x4903a000 0x80>;
-			interrupts = <0 42 0x4>;
+			interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer6";
 			ti,timer-dsp;
 			ti,timer-pwm;
@@ -555,7 +558,7 @@
 			compatible = "ti,omap5430-timer";
 			reg = <0x4013c000 0x80>,
 			      <0x4903c000 0x80>;
-			interrupts = <0 43 0x4>;
+			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer7";
 			ti,timer-dsp;
 		};
@@ -564,7 +567,7 @@
 			compatible = "ti,omap5430-timer";
 			reg = <0x4013e000 0x80>,
 			      <0x4903e000 0x80>;
-			interrupts = <0 44 0x4>;
+			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer8";
 			ti,timer-dsp;
 			ti,timer-pwm;
@@ -573,7 +576,7 @@
 		timer9: timer@4803e000 {
 			compatible = "ti,omap5430-timer";
 			reg = <0x4803e000 0x80>;
-			interrupts = <0 45 0x4>;
+			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer9";
 			ti,timer-pwm;
 		};
@@ -581,7 +584,7 @@
 		timer10: timer@48086000 {
 			compatible = "ti,omap5430-timer";
 			reg = <0x48086000 0x80>;
-			interrupts = <0 46 0x4>;
+			interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer10";
 			ti,timer-pwm;
 		};
@@ -589,7 +592,7 @@
 		timer11: timer@48088000 {
 			compatible = "ti,omap5430-timer";
 			reg = <0x48088000 0x80>;
-			interrupts = <0 47 0x4>;
+			interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "timer11";
 			ti,timer-pwm;
 		};
@@ -597,7 +600,7 @@
 		wdt2: wdt@4ae14000 {
 			compatible = "ti,omap5-wdt", "ti,omap3-wdt";
 			reg = <0x4ae14000 0x80>;
-			interrupts = <0 80 0x4>;
+			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "wd_timer2";
 		};
 
@@ -606,7 +609,7 @@
 			ti,hwmods	= "emif1";
 			phy-type	= <2>; /* DDR PHY type: Intelli PHY */
 			reg = <0x4c000000 0x400>;
-			interrupts = <0 110 0x4>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
 			hw-caps-read-idle-ctrl;
 			hw-caps-ll-interface;
 			hw-caps-temp-alert;
@@ -617,7 +620,7 @@
 			ti,hwmods	= "emif2";
 			phy-type	= <2>; /* DDR PHY type: Intelli PHY */
 			reg = <0x4d000000 0x400>;
-			interrupts = <0 111 0x4>;
+			interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
 			hw-caps-read-idle-ctrl;
 			hw-caps-ll-interface;
 			hw-caps-temp-alert;
@@ -635,7 +638,7 @@
 			compatible = "ti,dwc3";
 			ti,hwmods = "usb_otg_ss";
 			reg = <0x4a020000 0x1000>;
-			interrupts = <0 93 4>;
+			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			utmi-mode = <2>;
@@ -643,7 +646,7 @@
 			dwc3@4a030000 {
 				compatible = "synopsys,dwc3";
 				reg = <0x4a030000 0x1000>;
-				interrupts = <0 92 4>;
+				interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
 				usb-phy = <&usb2_phy>, <&usb3_phy>;
 				tx-fifo-resize;
 			};
@@ -670,5 +673,44 @@
 				ctrl-module = <&omap_control_usb>;
 			};
 		};
+
+		usbhstll: usbhstll@4a062000 {
+			compatible = "ti,usbhs-tll";
+			reg = <0x4a062000 0x1000>;
+			interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+			ti,hwmods = "usb_tll_hs";
+		};
+
+		usbhshost: usbhshost@4a064000 {
+			compatible = "ti,usbhs-host";
+			reg = <0x4a064000 0x800>;
+			ti,hwmods = "usb_host_hs";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			usbhsohci: ohci@4a064800 {
+				compatible = "ti,ohci-omap3", "usb-ohci";
+				reg = <0x4a064800 0x400>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+			usbhsehci: ehci@4a064c00 {
+				compatible = "ti,ehci-omap", "usb-ehci";
+				reg = <0x4a064c00 0x400>;
+				interrupt-parent = <&gic>;
+				interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
+
+		bandgap@4a0021e0 {
+			reg = <0x4a0021e0 0xc
+			       0x4a00232c 0xc
+			       0x4a002380 0x2c
+			       0x4a0023C0 0x3c>;
+			interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+			compatible = "ti,omap5430-bandgap";
+		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap5-evm.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap5-evm.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap5-evm.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap5-evm.dts	1969-12-31 19:00:00.000000000 -0500
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-/dts-v1/;
-
-/include/ "omap5.dtsi"
-/include/ "samsung_k3pe0e000b.dtsi"
-
-/ {
-	model = "TI OMAP5 EVM board";
-	compatible = "ti,omap5-evm", "ti,omap5";
-
-	memory {
-		device_type = "memory";
-		reg = <0x80000000 0x7F000000>; /* 2032 MB */
-	};
-
-	vmmcsd_fixed: fixedregulator-mmcsd {
-		compatible = "regulator-fixed";
-		regulator-name = "vmmcsd_fixed";
-		regulator-min-microvolt = <3000000>;
-		regulator-max-microvolt = <3000000>;
-	};
-
-};
-
-&omap5_pmx_core {
-	pinctrl-names = "default";
-	pinctrl-0 = <
-			&twl6040_pins
-			&mcpdm_pins
-			&dmic_pins
-			&mcbsp1_pins
-			&mcbsp2_pins
-	>;
-
-	twl6040_pins: pinmux_twl6040_pins {
-		pinctrl-single,pins = <
-			0x18a 0x6	/* perslimbus2_clock.gpio5_145 OUTPUT | MODE6 */
-		>;
-	};
-
-	mcpdm_pins: pinmux_mcpdm_pins {
-		pinctrl-single,pins = <
-			0x142 0x108	/* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
-			0x15c 0x108	/* abemcpdm_ul_data.abemcpdm_ul_data INPUT PULLDOWN | MODE0 */
-			0x15e 0x108	/* abemcpdm_dl_data.abemcpdm_dl_data INPUT PULLDOWN | MODE0 */
-			0x160 0x118	/* abemcpdm_frame.abemcpdm_frame INPUT PULLUP | MODE0 */
-			0x162 0x108	/* abemcpdm_lb_clk.abemcpdm_lb_clk INPUT PULLDOWN | MODE0 */
-		>;
-	};
-
-	dmic_pins: pinmux_dmic_pins {
-		pinctrl-single,pins = <
-			0x144 0x100	/* abedmic_din1.abedmic_din1 INPUT | MODE0 */
-			0x146 0x100	/* abedmic_din2.abedmic_din2 INPUT | MODE0 */
-			0x148 0x100	/* abedmic_din3.abedmic_din3 INPUT | MODE0 */
-			0x14a 0		/* abedmic_clk1.abedmic_clk1 OUTPUT | MODE0 */
-		>;
-	};
-
-	mcbsp1_pins: pinmux_mcbsp1_pins {
-		pinctrl-single,pins = <
-			0x14c 0x101	/* abedmic_clk2.abemcbsp1_fsx INPUT | MODE1 */
-			0x14e 0x9	/* abedmic_clk3.abemcbsp1_dx OUTPUT PULLDOWN | MODE1 */
-			0x150 0x101	/* abeslimbus1_clock.abemcbsp1_clkx INPUT | MODE0 */
-			0x152 0x109	/* abeslimbus1_data.abemcbsp1_dr INPUT PULLDOWN | MODE1 */
-		>;
-	};
-
-	mcbsp2_pins: pinmux_mcbsp2_pins {
-		pinctrl-single,pins = <
-			0x154 0x108	/* abemcbsp2_dr.abemcbsp2_dr INPUT PULLDOWN | MODE0 */
-			0x156 0x8	/* abemcbsp2_dx.abemcbsp2_dx OUTPUT PULLDOWN | MODE0 */
-			0x158 0x100	/* abemcbsp2_fsx.abemcbsp2_fsx INPUT | MODE0 */
-			0x15a 0x100	/* abemcbsp2_clkx.abemcbsp2_clkx INPUT | MODE0 */
-		>;
-	};
-
-        i2c1_pins: pinmux_i2c1_pins {
-                pinctrl-single,pins = <
-                        0x1b2 0x118        /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */
-                        0x1b4 0x118        /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */
-                >;
-        };
-
-	i2c2_pins: pinmux_i2c2_pins {
-		pinctrl-single,pins = <
-			0x178 0x100        /* i2c2_scl INPUTENABLE | MODE0 */
-			0x17a 0x100        /* i2c2_sda INPUTENABLE | MODE0 */
-		>;
-	};
-
-	i2c3_pins: pinmux_i2c3_pins {
-		pinctrl-single,pins = <
-			0x13a 0x100        /* i2c3_scl INPUTENABLE | MODE0 */
-			0x13c 0x100     /* i2c3_sda INPUTENABLE | MODE0 */
-		>;
-	};
-
-	i2c4_pins: pinmux_i2c4_pins {
-		pinctrl-single,pins = <
-			0xb8 0x100        /* i2c4_scl INPUTENABLE | MODE0 */
-			0xba 0x100     /* i2c4_sda INPUTENABLE | MODE0 */
-		>;
-	};
-
-	i2c5_pins: pinmux_i2c5_pins {
-		pinctrl-single,pins = <
-			0x184 0x100        /* i2c5_scl INPUTENABLE | MODE0 */
-			0x186 0x100     /* i2c5_sda INPUTENABLE | MODE0 */
-		>;
-	};
-
-	mcspi2_pins: pinmux_mcspi2_pins {
-		pinctrl-single,pins = <
-			0xbc 0x100	/*  MCSPI2_CLK INPUTENABLE | MODE0 */
-			0xbe 0x100	/*  MCSPI2_SIMO INPUTENABLE | MODE0 */
-			0xc0 0x118	/*  MCSPI2_SOMI PULLUP | INPUTENABLE | MODE0*/
-			0xc2 0x0	/*  MCSPI2_CS MODE0*/
-		>;
-	};
-
-	mcspi3_pins: pinmux_mcspi3_pins {
-		pinctrl-single,pins = <
-			0x78 0x101	/*  MCSPI2_SOMI INPUTENABLE | MODE1 */
-			0x7a 0x101	/*  MCSPI2_CS INPUTENABLE | MODE1 */
-			0x7c 0x101	/*  MCSPI2_SIMO INPUTENABLE | MODE1 */
-			0x7e 0x101	/*  MCSPI2_CLK INPUTENABLE | MODE1 */
-		>;
-	};
-
-	mcspi4_pins: pinmux_mcspi4_pins {
-		pinctrl-single,pins = <
-			0x164 0x101	/*  MCSPI2_CLK INPUTENABLE | MODE1 */
-			0x168 0x101	/*  MCSPI2_SIMO INPUTENABLE | MODE1 */
-			0x16a 0x101	/*  MCSPI2_SOMI INPUTENABLE | MODE1 */
-			0x16c 0x101	/*  MCSPI2_CS INPUTENABLE | MODE1 */
-		>;
-	};
-};
-
-&mmc1 {
-	vmmc-supply = <&vmmcsd_fixed>;
-	bus-width = <4>;
-};
-
-&mmc2 {
-	vmmc-supply = <&vmmcsd_fixed>;
-	bus-width = <8>;
-	ti,non-removable;
-};
-
-&mmc3 {
-	bus-width = <4>;
-	ti,non-removable;
-};
-
-&mmc4 {
-	status = "disabled";
-};
-
-&mmc5 {
-	status = "disabled";
-};
-
-&i2c1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c1_pins>;
-
-	clock-frequency = <400000>;
-};
-
-&i2c2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c2_pins>;
-
-	clock-frequency = <400000>;
-
-	/* Pressure Sensor */
-	bmp085@77 {
-		compatible = "bosch,bmp085";
-		reg = <0x77>;
-	};
-};
-
-&i2c3 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c3_pins>;
-
-	clock-frequency = <400000>;
-};
-
-&i2c4 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c4_pins>;
-
-	clock-frequency = <400000>;
-
-	/* Temperature Sensor */
-	tmp102@48{
-		compatible = "ti,tmp102";
-		reg = <0x48>;
-	};
-};
-
-&i2c5 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c5_pins>;
-
-	clock-frequency = <400000>;
-};
-
-&keypad {
-	keypad,num-rows = <8>;
-	keypad,num-columns = <8>;
-	linux,keymap = <0x02020073	/* VOLUP */
-			0x02030072	/* VOLDOWM */
-			0x020400e7	/* SEND */
-			0x02050066	/* HOME */
-			0x0206006b	/* END */
-			0x020700d9>;	/* SEARCH */
-	linux,input-no-autorepeat;
-};
-
-&mcbsp3 {
-	status = "disabled";
-};
-
-&emif1 {
-	cs1-used;
-	device-handle = <&samsung_K3PE0E000B>;
-};
-
-&emif2 {
-	cs1-used;
-	device-handle = <&samsung_K3PE0E000B>;
-};
-
-&mcspi1 {
-
-};
-
-&mcspi2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcspi2_pins>;
-};
-
-&mcspi3 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcspi3_pins>;
-};
-
-&mcspi4 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mcspi4_pins>;
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/omap5-uevm.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap5-uevm.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/omap5-uevm.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/omap5-uevm.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,505 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "omap5.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	model = "TI OMAP5 uEVM board";
+	compatible = "ti,omap5-uevm", "ti,omap5";
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x7F000000>; /* 2032 MB */
+	};
+
+	vmmcsd_fixed: fixedregulator-mmcsd {
+		compatible = "regulator-fixed";
+		regulator-name = "vmmcsd_fixed";
+		regulator-min-microvolt = <3000000>;
+		regulator-max-microvolt = <3000000>;
+	};
+
+	/* HS USB Port 2 RESET */
+	hsusb2_reset: hsusb2_reset_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "hsusb2_reset";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>; /* gpio3_80 HUB_NRESET */
+		startup-delay-us = <70000>;
+		enable-active-high;
+	};
+
+	/* HS USB Host PHY on PORT 2 */
+	hsusb2_phy: hsusb2_phy {
+		compatible = "usb-nop-xceiv";
+		reset-supply = <&hsusb2_reset>;
+	/**
+	  * FIXME
+	  * Put the right clock phandle here when available
+	  *	clocks = <&auxclk1>;
+	  *	clock-names = "main_clk";
+	  */
+		clock-frequency = <19200000>;
+	};
+
+	/* HS USB Port 3 RESET */
+	hsusb3_reset: hsusb3_reset_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "hsusb3_reset";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>; /* gpio3_79 ETH_NRESET */
+		startup-delay-us = <70000>;
+		enable-active-high;
+	};
+
+	/* HS USB Host PHY on PORT 3 */
+	hsusb3_phy: hsusb3_phy {
+		compatible = "usb-nop-xceiv";
+		reset-supply = <&hsusb3_reset>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		led@1 {
+			label = "omap5:blue:usr1";
+			gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>; /* gpio5_153 D1 LED */
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
+		};
+	};
+};
+
+&omap5_pmx_core {
+	pinctrl-names = "default";
+	pinctrl-0 = <
+			&twl6040_pins
+			&mcpdm_pins
+			&dmic_pins
+			&mcbsp1_pins
+			&mcbsp2_pins
+			&usbhost_pins
+			&led_gpio_pins
+	>;
+
+	twl6040_pins: pinmux_twl6040_pins {
+		pinctrl-single,pins = <
+			0x18a (PIN_OUTPUT | MUX_MODE6)	/* perslimbus2_clock.gpio5_145 */
+		>;
+	};
+
+	mcpdm_pins: pinmux_mcpdm_pins {
+		pinctrl-single,pins = <
+			0x142 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abe_clks.abe_clks */
+			0x15c (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abemcpdm_ul_data.abemcpdm_ul_data */
+			0x15e (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abemcpdm_dl_data.abemcpdm_dl_data */
+			0x160 (PIN_INPUT_PULLUP | MUX_MODE0)	/* abemcpdm_frame.abemcpdm_frame */
+			0x162 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abemcpdm_lb_clk.abemcpdm_lb_clk */
+		>;
+	};
+
+	dmic_pins: pinmux_dmic_pins {
+		pinctrl-single,pins = <
+			0x144 (PIN_INPUT | MUX_MODE0)		/* abedmic_din1.abedmic_din1 */
+			0x146 (PIN_INPUT | MUX_MODE0)		/* abedmic_din2.abedmic_din2 */
+			0x148 (PIN_INPUT | MUX_MODE0)		/* abedmic_din3.abedmic_din3 */
+			0x14a (PIN_OUTPUT | MUX_MODE0)		/* abedmic_clk1.abedmic_clk1 */
+		>;
+	};
+
+	mcbsp1_pins: pinmux_mcbsp1_pins {
+		pinctrl-single,pins = <
+			0x14c (PIN_INPUT | MUX_MODE1)		/* abedmic_clk2.abemcbsp1_fsx */
+			0x14e (PIN_OUTPUT_PULLDOWN | MUX_MODE1)	/* abedmic_clk3.abemcbsp1_dx */
+			0x150 (PIN_INPUT | MUX_MODE1)		/* abeslimbus1_clock.abemcbsp1_clkx */
+			0x152 (PIN_INPUT_PULLDOWN | MUX_MODE1)	/* abeslimbus1_data.abemcbsp1_dr */
+		>;
+	};
+
+	mcbsp2_pins: pinmux_mcbsp2_pins {
+		pinctrl-single,pins = <
+			0x154 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* abemcbsp2_dr.abemcbsp2_dr */
+			0x156 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* abemcbsp2_dx.abemcbsp2_dx */
+			0x158 (PIN_INPUT | MUX_MODE0)		/* abemcbsp2_fsx.abemcbsp2_fsx */
+			0x15a (PIN_INPUT | MUX_MODE0)		/* abemcbsp2_clkx.abemcbsp2_clkx */
+		>;
+	};
+
+	i2c1_pins: pinmux_i2c1_pins {
+		pinctrl-single,pins = <
+			0x1b2 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c1_scl */
+			0x1b4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* i2c1_sda */
+		>;
+	};
+
+	i2c5_pins: pinmux_i2c5_pins {
+		pinctrl-single,pins = <
+			0x184 (PIN_INPUT | MUX_MODE0)		/* i2c5_scl */
+			0x186 (PIN_INPUT | MUX_MODE0)		/* i2c5_sda */
+		>;
+	};
+
+	mcspi2_pins: pinmux_mcspi2_pins {
+		pinctrl-single,pins = <
+			0xbc (PIN_INPUT | MUX_MODE0)		/*  mcspi2_clk */
+			0xbe (PIN_INPUT | MUX_MODE0)		/*  mcspi2_simo */
+			0xc0 (PIN_INPUT_PULLUP | MUX_MODE0)	/*  mcspi2_somi */
+			0xc2 (PIN_OUTPUT | MUX_MODE0)		/*  mcspi2_cs */
+		>;
+	};
+
+	mcspi3_pins: pinmux_mcspi3_pins {
+		pinctrl-single,pins = <
+			0x78 (PIN_INPUT | MUX_MODE1)		/*  mcspi2_somi */
+			0x7a (PIN_INPUT | MUX_MODE1)		/*  mcspi2_cs */
+			0x7c (PIN_INPUT | MUX_MODE1)		/*  mcspi2_simo */
+			0x7e (PIN_INPUT | MUX_MODE1)		/*  mcspi2_clk */
+		>;
+	};
+
+	mcspi4_pins: pinmux_mcspi4_pins {
+		pinctrl-single,pins = <
+			0x164 (PIN_INPUT | MUX_MODE1)		/*  mcspi2_clk */
+			0x168 (PIN_INPUT | MUX_MODE1)		/*  mcspi2_simo */
+			0x16a (PIN_INPUT | MUX_MODE1)		/*  mcspi2_somi */
+			0x16c (PIN_INPUT | MUX_MODE1)		/*  mcspi2_cs */
+		>;
+	};
+
+	usbhost_pins: pinmux_usbhost_pins {
+		pinctrl-single,pins = <
+			0x84 (PIN_INPUT | MUX_MODE0) /* usbb2_hsic_strobe */
+			0x86 (PIN_INPUT | MUX_MODE0) /* usbb2_hsic_data */
+
+			0x19e (PIN_INPUT | MUX_MODE0) /* usbb3_hsic_strobe */
+			0x1a0 (PIN_INPUT | MUX_MODE0) /* usbb3_hsic_data */
+
+			0x70 (PIN_OUTPUT | MUX_MODE6) /* gpio3_80 HUB_NRESET */
+			0x6e (PIN_OUTPUT | MUX_MODE6) /* gpio3_79 ETH_NRESET */
+		>;
+	};
+
+	led_gpio_pins: pinmux_led_gpio_pins {
+		pinctrl-single,pins = <
+			0x196 (PIN_OUTPUT | MUX_MODE6) /* uart3_cts_rctx.gpio5_153 */
+		>;
+	};
+
+	uart1_pins: pinmux_uart1_pins {
+		pinctrl-single,pins = <
+			0x60 (PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_cts */
+			0x62 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_tx.uart1_cts */
+			0x64 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rx.uart1_rts */
+			0x66 (PIN_OUTPUT | MUX_MODE0) /* uart1_rx.uart1_rts */
+		>;
+	};
+
+	uart3_pins: pinmux_uart3_pins {
+		pinctrl-single,pins = <
+			0x19a (PIN_OUTPUT | MUX_MODE0) /* uart3_rts_irsd.uart3_tx_irtx */
+			0x19c (PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_rx_irrx.uart3_usbb3_hsic */
+		>;
+	};
+
+	uart5_pins: pinmux_uart5_pins {
+		pinctrl-single,pins = <
+			0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_rx.uart5_rx */
+			0x172 (PIN_OUTPUT | MUX_MODE0) /* uart5_tx.uart5_tx */
+			0x174 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart5_cts.uart5_rts */
+			0x176 (PIN_OUTPUT | MUX_MODE0) /* uart5_cts.uart5_rts */
+		>;
+	};
+
+};
+
+&omap5_pmx_wkup {
+	pinctrl-names = "default";
+	pinctrl-0 = <
+			&usbhost_wkup_pins
+	>;
+
+	usbhost_wkup_pins: pinmux_usbhost_wkup_pins {
+		pinctrl-single,pins = <
+			0x1A (PIN_OUTPUT | MUX_MODE0) /* fref_clk1_out, USB hub clk */
+		>;
+	};
+};
+
+&mmc1 {
+	vmmc-supply = <&ldo9_reg>;
+	bus-width = <4>;
+};
+
+&mmc2 {
+	vmmc-supply = <&vmmcsd_fixed>;
+	bus-width = <8>;
+	ti,non-removable;
+};
+
+&mmc3 {
+	bus-width = <4>;
+	ti,non-removable;
+};
+
+&mmc4 {
+	status = "disabled";
+};
+
+&mmc5 {
+	status = "disabled";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+
+	clock-frequency = <400000>;
+
+	palmas: palmas@48 {
+		compatible = "ti,palmas";
+		interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* IRQ_SYS_1N */
+		interrupt-parent = <&gic>;
+		reg = <0x48>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		palmas_pmic {
+			compatible = "ti,palmas-pmic";
+			interrupt-parent = <&palmas>;
+			interrupts = <14 IRQ_TYPE_NONE>;
+			interrupt-name = "short-irq";
+
+			ti,ldo6-vibrator;
+
+			regulators {
+				smps123_reg: smps123 {
+					/* VDD_OPP_MPU */
+					regulator-name = "smps123";
+					regulator-min-microvolt = < 600000>;
+					regulator-max-microvolt = <1500000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				smps45_reg: smps45 {
+					/* VDD_OPP_MM */
+					regulator-name = "smps45";
+					regulator-min-microvolt = < 600000>;
+					regulator-max-microvolt = <1310000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				smps6_reg: smps6 {
+					/* VDD_DDR3 - over VDD_SMPS6 */
+					regulator-name = "smps6";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				smps7_reg: smps7 {
+					/* VDDS_1v8_OMAP over VDDS_1v8_MAIN */
+					regulator-name = "smps7";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				smps8_reg: smps8 {
+					/* VDD_OPP_CORE */
+					regulator-name = "smps8";
+					regulator-min-microvolt = < 600000>;
+					regulator-max-microvolt = <1310000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				smps9_reg: smps9 {
+					/* VDDA_2v1_AUD over VDD_2v1 */
+					regulator-name = "smps9";
+					regulator-min-microvolt = <2100000>;
+					regulator-max-microvolt = <2100000>;
+					ti,smps-range = <0x80>;
+				};
+
+				smps10_reg: smps10 {
+					/* VBUS_5V_OTG */
+					regulator-name = "smps10";
+					regulator-min-microvolt = <5000000>;
+					regulator-max-microvolt = <5000000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo1_reg: ldo1 {
+					/* VDDAPHY_CAM: vdda_csiport */
+					regulator-name = "ldo1";
+					regulator-min-microvolt = <1500000>;
+					regulator-max-microvolt = <1800000>;
+				};
+
+				ldo2_reg: ldo2 {
+					/* VCC_2V8_DISP: Does not go anywhere */
+					regulator-name = "ldo2";
+					regulator-min-microvolt = <2800000>;
+					regulator-max-microvolt = <2800000>;
+					/* Unused */
+					status = "disabled";
+				};
+
+				ldo3_reg: ldo3 {
+					/* VDDAPHY_MDM: vdda_lli */
+					regulator-name = "ldo3";
+					regulator-min-microvolt = <1500000>;
+					regulator-max-microvolt = <1500000>;
+					regulator-boot-on;
+					/* Only if Modem is used */
+					status = "disabled";
+				};
+
+				ldo4_reg: ldo4 {
+					/* VDDAPHY_DISP: vdda_dsiport/hdmi */
+					regulator-name = "ldo4";
+					regulator-min-microvolt = <1500000>;
+					regulator-max-microvolt = <1800000>;
+				};
+
+				ldo5_reg: ldo5 {
+					/* VDDA_1V8_PHY: usb/sata/hdmi.. */
+					regulator-name = "ldo5";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo6_reg: ldo6 {
+					/* VDDS_1V2_WKUP: hsic/ldo_emu_wkup */
+					regulator-name = "ldo6";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldo7_reg: ldo7 {
+					/* VDD_VPP: vpp1 */
+					regulator-name = "ldo7";
+					regulator-min-microvolt = <2000000>;
+					regulator-max-microvolt = <2000000>;
+					/* Only for efuse reprograming! */
+					status = "disabled";
+				};
+
+				ldo8_reg: ldo8 {
+					/* VDD_3v0: Does not go anywhere */
+					regulator-name = "ldo8";
+					regulator-min-microvolt = <3000000>;
+					regulator-max-microvolt = <3000000>;
+					regulator-boot-on;
+					/* Unused */
+					status = "disabled";
+				};
+
+				ldo9_reg: ldo9 {
+					/* VCC_DV_SDIO: vdds_sdcard */
+					regulator-name = "ldo9";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <3000000>;
+					regulator-boot-on;
+				};
+
+				ldoln_reg: ldoln {
+					/* VDDA_1v8_REF: vdds_osc/mm_l4per.. */
+					regulator-name = "ldoln";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				ldousb_reg: ldousb {
+					/* VDDA_3V_USB: VDDA_USBHS33 */
+					regulator-name = "ldousb";
+					regulator-min-microvolt = <3250000>;
+					regulator-max-microvolt = <3250000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+
+				regen3_reg: regen3 {
+					/* REGEN3 controls LDO9 supply to card */
+					regulator-name = "regen3";
+					regulator-always-on;
+					regulator-boot-on;
+				};
+			};
+		};
+	};
+};
+
+&i2c5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c5_pins>;
+
+	clock-frequency = <400000>;
+};
+
+&mcbsp3 {
+	status = "disabled";
+};
+
+&usbhshost {
+	port2-mode = "ehci-hsic";
+	port3-mode = "ehci-hsic";
+};
+
+&usbhsehci {
+	phys = <0 &hsusb2_phy &hsusb3_phy>;
+};
+
+&mcspi1 {
+
+};
+
+&mcspi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcspi2_pins>;
+};
+
+&mcspi3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcspi3_pins>;
+};
+
+&mcspi4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mcspi4_pins>;
+};
+
+&uart1 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&uart1_pins>;
+};
+
+&uart3 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&uart3_pins>;
+};
+
+&uart5 {
+        pinctrl-names = "default";
+        pinctrl-0 = <&uart5_pins>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/picoxcell-pc3x2.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/picoxcell-pc3x2.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/picoxcell-pc3x2.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/picoxcell-pc3x2.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -18,13 +18,13 @@
 	#size-cells = <1>;
 
 	cpus {
-		#address-cells = <1>;
+		#address-cells = <0>;
 		#size-cells = <0>;
 
-		cpu@0 {
-			compatible = "arm,1176jz-s";
+		cpu {
+			compatible = "arm,arm1176jz-s";
+			device_type = "cpu";
 			clock-frequency = <400000000>;
-			reg = <0>;
 			d-cache-line-size = <32>;
 			d-cache-size = <32768>;
 			i-cache-line-size = <32>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/picoxcell-pc3x3.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/picoxcell-pc3x3.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/picoxcell-pc3x3.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/picoxcell-pc3x3.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -18,13 +18,13 @@
 	#size-cells = <1>;
 
 	cpus {
-		#address-cells = <1>;
+		#address-cells = <0>;
 		#size-cells = <0>;
 
-		cpu@0 {
-			compatible = "arm,1176jz-s";
+		cpu {
+			compatible = "arm,arm1176jz-s";
+			device_type = "cpu";
 			cpu-clock = <&arm_clk>, "cpu";
-			reg = <0>;
 			d-cache-line-size = <32>;
 			d-cache-size = <32768>;
 			i-cache-line-size = <32>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/pm9g45.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/pm9g45.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/pm9g45.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/pm9g45.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2.
  */
 /dts-v1/;
-/include/ "at91sam9g45.dtsi"
+#include "at91sam9g45.dtsi"
 
 / {
 	model = "Ronetix pm9g45";
@@ -42,15 +42,15 @@
 				board {
 					pinctrl_board_nand: nand0-board {
 						atmel,pins =
-							<3 3 0x0 0x1	/* PD3 gpio RDY pin pull_up*/
-							 2 14 0x0 0x1>;	/* PC14 gpio enable pin pull_up */
+							<AT91_PIOD 3 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP	/* PD3 gpio RDY pin pull_up*/
+							 AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;	/* PC14 gpio enable pin pull_up */
 					};
 				};
 
 				mmc {
 					pinctrl_board_mmc: mmc0-board {
 						atmel,pins =
-							<3 6 0x0 0x5>;	/* PD6 gpio CD pin pull_up and deglitch */
+							<AT91_PIOD 6 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;	/* PD6 gpio CD pin pull_up and deglitch */
 					};
 				};
 			};
@@ -64,7 +64,7 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioD 6 0>;
+					cd-gpios = <&pioD 6 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -81,8 +81,8 @@
 			nand-on-flash-bbt;
 			pinctrl-0 = <&pinctrl_board_nand>;
 
-			gpios = <&pioD 3 0
-				 &pioC 14 0
+			gpios = <&pioD 3 GPIO_ACTIVE_HIGH
+				 &pioC 14 GPIO_ACTIVE_HIGH
 				 0
 				>;
 
@@ -134,13 +134,13 @@
 
 		led0 {
 			label = "led0";
-			gpios = <&pioD 0 1>;
+			gpios = <&pioD 0 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "nand-disk";
 		};
 
 		led1 {
 			label = "led1";
-			gpios = <&pioD 31 0>;
+			gpios = <&pioD 31 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 	};
@@ -152,13 +152,13 @@
 
 		right {
 			label = "SW4";
-			gpios = <&pioE 7 1>;
+			gpios = <&pioE 7 GPIO_ACTIVE_LOW>;
 			linux,code = <106>;
 		};
 
 		up {
 			label = "SW3";
-			gpios = <&pioE 8 1>;
+			gpios = <&pioE 8 GPIO_ACTIVE_LOW>;
 			linux,code = <103>;
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/prima2.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/prima2.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/prima2.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/prima2.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,8 @@
 		#size-cells = <0>;
 
 		cpu@0 {
+			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			reg = <0x0>;
 			d-cache-line-size = <32>;
 			i-cache-line-size = <32>;
@@ -513,16 +515,16 @@
                                                 sirf,function = "pulse_count";
                                         };
                                 };
-                                cko0_rst_pins_a: cko0_rst@0 {
-                                        cko0_rst {
-                                                sirf,pins = "cko0_rstgrp";
-                                                sirf,function = "cko0_rst";
+                                cko0_pins_a: cko0@0 {
+                                        cko0 {
+                                                sirf,pins = "cko0grp";
+                                                sirf,function = "cko0";
                                         };
                                 };
-                                cko1_rst_pins_a: cko1_rst@0 {
-                                        cko1_rst {
-                                                sirf,pins = "cko1_rstgrp";
-                                                sirf,function = "cko1_rst";
+                                cko1_pins_a: cko1@0 {
+                                        cko1 {
+                                                sirf,pins = "cko1grp";
+                                                sirf,function = "cko1";
                                         };
                                 };
 			};
@@ -608,7 +610,7 @@
 		};
 
 		rtc-iobg {
-			compatible = "sirf,prima2-rtciobg", "sirf-prima2-rtciobg-bus";
+			compatible = "sirf,prima2-rtciobg", "sirf-prima2-rtciobg-bus", "simple-bus";
 			#address-cells = <1>;
 			#size-cells = <1>;
 			reg = <0x80030000 0x10000>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/pxa2xx.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/pxa2xx.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/pxa2xx.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/pxa2xx.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -23,8 +23,11 @@
 	};
 
 	cpus {
-		cpu@0 {
-			compatible = "arm,xscale";
+		#address-cells = <0>;
+		#size-cells = <0>;
+		cpu {
+			compatible = "marvell,xscale";
+			device_type = "cpu";
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/r8a73a4.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a73a4.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/r8a73a4.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a73a4.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -37,12 +37,6 @@
 			<0 0xf1004000 0 0x2000>,
 			<0 0xf1006000 0 0x2000>;
 		interrupts = <1 9 0xf04>;
-
-		gic-cpuif@4 {
-			compatible = "arm,gic-cpuif";
-			cpuif-id = <4>;
-			cpu = <&cpu0>;
-		};
 	};
 
 	timer {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * Reference Device Tree Source for the armadillo 800 eva board
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+/include/ "r8a7740.dtsi"
+
+/ {
+	model = "armadillo 800 eva reference";
+	compatible = "renesas,armadillo800eva-reference", "renesas,r8a7740";
+
+	chosen {
+		bootargs = "console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096 rw";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x40000000 0x20000000>;
+	};
+
+	reg_3p3v: regulator@0 {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+};
+
+&i2c0 {
+	touchscreen: st1232@55 {
+		compatible = "sitronix,st1232";
+		reg = <0x55>;
+		interrupt-parent = <&irqpin1>;
+		interrupts = <2 0>; /* IRQ10: hwirq 2 on irqpin1 */
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/r8a7740.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a7740.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/r8a7740.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a7740.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -14,8 +14,129 @@
 	compatible = "renesas,r8a7740";
 
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 		cpu@0 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
+			reg = <0x0>;
 		};
 	};
+
+	gic: interrupt-controller@c2800000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <1>;
+		interrupt-controller;
+		reg = <0xc2800000 0x1000>,
+		      <0xc2000000 0x1000>;
+	};
+
+	/* irqpin0: IRQ0 - IRQ7 */
+	irqpin0: irqpin@e6900000 {
+		compatible = "renesas,intc-irqpin";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xe6900000 4>,
+			<0xe6900010 4>,
+			<0xe6900020 1>,
+			<0xe6900040 1>,
+			<0xe6900060 1>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4>;
+	};
+
+	/* irqpin1: IRQ8 - IRQ15 */
+	irqpin1: irqpin@e6900004 {
+		compatible = "renesas,intc-irqpin";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xe6900004 4>,
+			<0xe6900014 4>,
+			<0xe6900024 1>,
+			<0xe6900044 1>,
+			<0xe6900064 1>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4>;
+	};
+
+	/* irqpin2: IRQ16 - IRQ23 */
+	irqpin2: irqpin@e6900008 {
+		compatible = "renesas,intc-irqpin";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xe6900008 4>,
+			<0xe6900018 4>,
+			<0xe6900028 1>,
+			<0xe6900048 1>,
+			<0xe6900068 1>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4>;
+	};
+
+	/* irqpin3: IRQ24 - IRQ31 */
+	irqpin3: irqpin@e690000c {
+		compatible = "renesas,intc-irqpin";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xe690000c 4>,
+			<0xe690001c 4>,
+			<0xe690002c 1>,
+			<0xe690004c 1>,
+			<0xe690006c 1>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4
+			      0 149 0x4>;
+	};
+
+	i2c0: i2c@fff20000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "renesas,rmobile-iic";
+		reg = <0xfff20000 0x425>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 201 0x4
+			      0 202 0x4
+			      0 203 0x4
+			      0 204 0x4>;
+	};
+
+	i2c1: i2c@e6c20000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "renesas,rmobile-iic";
+		reg = <0xe6c20000 0x425>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 70 0x4
+			      0 71 0x4
+			      0 72 0x4
+			      0 73 0x4>;
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/r8a7779.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a7779.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/r8a7779.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a7779.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -48,6 +48,23 @@
                       <0xf0000100 0x100>;
         };
 
+	irqpin0: irqpin@fe780010 {
+		compatible = "renesas,intc-irqpin";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xfe78001c 4>,
+			<0xfe780010 4>,
+			<0xfe780024 4>,
+			<0xfe780044 4>,
+			<0xfe780064 4>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 27 0x4
+				0 28 0x4
+				0 29 0x4
+				0 30 0x4>;
+		sense-bitfield-width = <2>;
+	};
+
 	i2c0: i2c@0xffc70000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/r8a7790.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a7790.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/r8a7790.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/r8a7790.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -36,12 +36,6 @@
 			<0 0xf1004000 0 0x2000>,
 			<0 0xf1006000 0 0x2000>;
 		interrupts = <1 9 0xf04>;
-
-		gic-cpuif@4 {
-			compatible = "arm,gic-cpuif";
-			cpuif-id = <4>;
-			cpu = <&cpu0>;
-		};
 	};
 
 	timer {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/rk3066a-clocks.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/rk3066a-clocks.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/rk3066a-clocks.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/rk3066a-clocks.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/ {
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		/*
+		 * This is a dummy clock, to be used as placeholder on
+		 * other mux clocks when a specific parent clock is not
+		 * yet implemented. It should be dropped when the driver
+		 * is complete.
+		 */
+		dummy: dummy {
+			compatible = "fixed-clock";
+			clock-frequency = <0>;
+			#clock-cells = <0>;
+		};
+
+		xin24m: xin24m {
+			compatible = "fixed-clock";
+			clock-frequency = <24000000>;
+			#clock-cells = <0>;
+		};
+
+		dummy48m: dummy48m {
+			compatible = "fixed-clock";
+			clock-frequency = <48000000>;
+			#clock-cells = <0>;
+		};
+
+		dummy150m: dummy150m {
+			compatible = "fixed-clock";
+			clock-frequency = <150000000>;
+			#clock-cells = <0>;
+		};
+
+		clk_gates0: gate-clk@200000d0 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d0 0x4>;
+			clocks = <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>;
+
+			clock-output-names =
+				"gate_core_periph", "gate_cpu_gpll",
+				"gate_ddrphy", "gate_aclk_cpu",
+				"gate_hclk_cpu", "gate_pclk_cpu",
+				"gate_atclk_cpu", "gate_i2s0",
+				"gate_i2s0_frac", "gate_i2s1",
+				"gate_i2s1_frac", "gate_i2s2",
+				"gate_i2s2_frac", "gate_spdif",
+				"gate_spdif_frac", "gate_testclk";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates1: gate-clk@200000d4 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d4 0x4>;
+			clocks = <&xin24m>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&dummy>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>;
+
+			clock-output-names =
+				"gate_timer0", "gate_timer1",
+				"gate_timer2", "gate_jtag",
+				"gate_aclk_lcdc1_src", "gate_otgphy0",
+				"gate_otgphy1", "gate_ddr_gpll",
+				"gate_uart0", "gate_frac_uart0",
+				"gate_uart1", "gate_frac_uart1",
+				"gate_uart2", "gate_frac_uart2",
+				"gate_uart3", "gate_frac_uart3";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates2: gate-clk@200000d8 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d8 0x4>;
+			clocks = <&clk_gates2 1>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&clk_gates2 3>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy48m>,
+				 <&dummy>, <&dummy48m>,
+				 <&dummy>, <&dummy>;
+
+			clock-output-names =
+				"gate_periph_src", "gate_aclk_periph",
+				"gate_hclk_periph", "gate_pclk_periph",
+				"gate_smc", "gate_mac",
+				"gate_hsadc", "gate_hsadc_frac",
+				"gate_saradc", "gate_spi0",
+				"gate_spi1", "gate_mmc0",
+				"gate_mac_lbtest", "gate_mmc1",
+				"gate_emmc", "gate_tsadc";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates3: gate-clk@200000dc {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000dc 0x4>;
+			clocks = <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>;
+
+			clock-output-names =
+				"gate_aclk_lcdc0_src", "gate_dclk_lcdc0",
+				"gate_dclk_lcdc1", "gate_pclkin_cif0",
+				"gate_pclkin_cif1", "reserved",
+				"reserved", "gate_cif0_out",
+				"gate_cif1_out", "gate_aclk_vepu",
+				"gate_hclk_vepu", "gate_aclk_vdpu",
+				"gate_hclk_vdpu", "gate_gpu_src",
+				"reserved", "gate_xin27m";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates4: gate-clk@200000e0 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000e0 0x4>;
+			clocks = <&clk_gates2 2>, <&clk_gates2 3>,
+				 <&clk_gates2 1>, <&clk_gates2 1>,
+				 <&clk_gates2 1>, <&clk_gates2 2>,
+				 <&clk_gates2 2>, <&clk_gates2 2>,
+				 <&clk_gates0 4>, <&clk_gates0 4>,
+				 <&clk_gates0 3>, <&clk_gates0 3>,
+				 <&clk_gates0 3>, <&clk_gates2 3>,
+				 <&clk_gates0 4>;
+
+			clock-output-names =
+				"gate_hclk_peri_axi_matrix", "gate_pclk_peri_axi_matrix",
+				"gate_aclk_cpu_peri", "gate_aclk_peri_axi_matrix",
+				"gate_aclk_pei_niu", "gate_hclk_usb_peri",
+				"gate_hclk_peri_ahb_arbi", "gate_hclk_emem_peri",
+				"gate_hclk_cpubus", "gate_hclk_ahb2apb",
+				"gate_aclk_strc_sys", "gate_aclk_l2mem_con",
+				"gate_aclk_intmem", "gate_pclk_tsadc",
+				"gate_hclk_hdmi";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates5: gate-clk@200000e4 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000e4 0x4>;
+			clocks = <&clk_gates0 3>, <&clk_gates2 1>,
+				 <&clk_gates0 5>, <&clk_gates0 5>,
+				 <&clk_gates0 5>, <&clk_gates0 5>,
+				 <&clk_gates0 4>, <&clk_gates0 5>,
+				 <&clk_gates2 1>, <&clk_gates2 2>,
+				 <&clk_gates2 2>, <&clk_gates2 2>,
+				 <&clk_gates2 2>, <&clk_gates4 5>,
+				 <&clk_gates4 5>, <&dummy>;
+
+			clock-output-names =
+				"gate_aclk_dmac1", "gate_aclk_dmac2",
+				"gate_pclk_efuse", "gate_pclk_tzpc",
+				"gate_pclk_grf", "gate_pclk_pmu",
+				"gate_hclk_rom", "gate_pclk_ddrupctl",
+				"gate_aclk_smc", "gate_hclk_nandc",
+				"gate_hclk_mmc0", "gate_hclk_mmc1",
+				"gate_hclk_emmc", "gate_hclk_otg0",
+				"gate_hclk_otg1", "gate_aclk_gpu";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates6: gate-clk@200000e8 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000e8 0x4>;
+			clocks = <&clk_gates3 0>, <&clk_gates0 4>,
+				 <&clk_gates0 4>, <&clk_gates1 4>,
+				 <&clk_gates0 4>, <&clk_gates3 0>,
+				 <&clk_gates0 4>, <&clk_gates1 4>,
+				 <&clk_gates3 0>, <&clk_gates0 4>,
+				 <&clk_gates0 4>, <&clk_gates1 4>,
+				 <&clk_gates0 4>, <&clk_gates3 0>,
+				 <&dummy>, <&dummy>;
+
+			clock-output-names =
+				"gate_aclk_lcdc0", "gate_hclk_lcdc0",
+				"gate_hclk_lcdc1", "gate_aclk_lcdc1",
+				"gate_hclk_cif0", "gate_aclk_cif0",
+				"gate_hclk_cif1", "gate_aclk_cif1",
+				"gate_aclk_ipp", "gate_hclk_ipp",
+				"gate_hclk_rga", "gate_aclk_rga",
+				"gate_hclk_vio_bus", "gate_aclk_vio0",
+				"gate_aclk_vcodec", "gate_shclk_vio_h2h";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates7: gate-clk@200000ec {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000ec 0x4>;
+			clocks = <&clk_gates2 2>, <&clk_gates0 4>,
+				 <&clk_gates0 4>, <&clk_gates0 4>,
+				 <&clk_gates0 4>, <&clk_gates2 2>,
+				 <&clk_gates2 2>, <&clk_gates0 5>,
+				 <&clk_gates0 5>, <&clk_gates0 5>,
+				 <&clk_gates0 5>, <&clk_gates2 3>,
+				 <&clk_gates2 3>, <&clk_gates2 3>,
+				 <&clk_gates2 3>, <&clk_gates2 3>;
+
+			clock-output-names =
+				"gate_hclk_emac", "gate_hclk_spdif",
+				"gate_hclk_i2s0_2ch", "gate_hclk_i2s1_2ch",
+				"gate_hclk_i2s_8ch", "gate_hclk_hsadc",
+				"gate_hclk_pidf", "gate_pclk_timer0",
+				"gate_pclk_timer1", "gate_pclk_timer2",
+				"gate_pclk_pwm01", "gate_pclk_pwm23",
+				"gate_pclk_spi0", "gate_pclk_spi1",
+				"gate_pclk_saradc", "gate_pclk_wdt";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates8: gate-clk@200000f0 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000f0 0x4>;
+			clocks = <&clk_gates0 5>, <&clk_gates0 5>,
+				 <&clk_gates2 3>, <&clk_gates2 3>,
+				 <&clk_gates0 5>, <&clk_gates0 5>,
+				 <&clk_gates2 3>, <&clk_gates2 3>,
+				 <&clk_gates2 3>, <&clk_gates0 5>,
+				 <&clk_gates0 5>, <&clk_gates0 5>,
+				 <&clk_gates2 3>, <&clk_gates2 3>,
+				 <&dummy>, <&clk_gates0 5>;
+
+			clock-output-names =
+				"gate_pclk_uart0", "gate_pclk_uart1",
+				"gate_pclk_uart2", "gate_pclk_uart3",
+				"gate_pclk_i2c0", "gate_pclk_i2c1",
+				"gate_pclk_i2c2", "gate_pclk_i2c3",
+				"gate_pclk_i2c4", "gate_pclk_gpio0",
+				"gate_pclk_gpio1", "gate_pclk_gpio2",
+				"gate_pclk_gpio3", "gate_pclk_gpio4",
+				"reserved", "gate_pclk_gpio6";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates9: gate-clk@200000f4 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000f4 0x4>;
+			clocks = <&dummy>, <&clk_gates0 5>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&clk_gates1 4>,
+				 <&clk_gates0 5>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>;
+
+			clock-output-names =
+				"gate_clk_core_dbg", "gate_pclk_dbg",
+				"gate_clk_trace", "gate_atclk",
+				"gate_clk_l2c", "gate_aclk_vio1",
+				"gate_pclk_publ", "gate_aclk_intmem0",
+				"gate_aclk_intmem1", "gate_aclk_intmem2",
+				"gate_aclk_intmem3";
+
+			#clock-cells = <1>;
+		};
+	};
+
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/rk3066a.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/rk3066a.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/rk3066a.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/rk3066a.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "skeleton.dtsi"
+#include "rk3066a-clocks.dtsi"
+
+/ {
+	compatible = "rockchip,rk3066a";
+	interrupt-parent = <&gic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			next-level-cache = <&L2>;
+			reg = <0x0>;
+		};
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			next-level-cache = <&L2>;
+			reg = <0x1>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges;
+
+		gic: interrupt-controller@1013d000 {
+			compatible = "arm,cortex-a9-gic";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x1013d000 0x1000>,
+			      <0x1013c100 0x0100>;
+		};
+
+		L2: l2-cache-controller@10138000 {
+			compatible = "arm,pl310-cache";
+			reg = <0x10138000 0x1000>;
+			cache-unified;
+			cache-level = <2>;
+		};
+
+		local-timer@1013c600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x1013c600 0x20>;
+			interrupts = <GIC_PPI 13 0x304>;
+			clocks = <&dummy150m>;
+		};
+
+		timer@20038000 {
+			compatible = "snps,dw-apb-timer-osc";
+			reg = <0x20038000 0x100>;
+			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk_gates1 0>, <&clk_gates7 7>;
+			clock-names = "timer", "pclk";
+		};
+
+		timer@2003a000 {
+			compatible = "snps,dw-apb-timer-osc";
+			reg = <0x2003a000 0x100>;
+			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk_gates1 1>, <&clk_gates7 8>;
+			clock-names = "timer", "pclk";
+		};
+
+		timer@2000e000 {
+			compatible = "snps,dw-apb-timer-osc";
+			reg = <0x2000e000 0x100>;
+			interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk_gates1 2>, <&clk_gates7 9>;
+			clock-names = "timer", "pclk";
+		};
+
+		pinctrl@20008000 {
+			compatible = "rockchip,rk3066a-pinctrl";
+			reg = <0x20008000 0x150>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			gpio0: gpio0@20034000 {
+				compatible = "rockchip,gpio-bank";
+				reg = <0x20034000 0x100>;
+				interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk_gates8 9>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio1: gpio1@2003c000 {
+				compatible = "rockchip,gpio-bank";
+				reg = <0x2003c000 0x100>;
+				interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk_gates8 10>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio2: gpio2@2003e000 {
+				compatible = "rockchip,gpio-bank";
+				reg = <0x2003e000 0x100>;
+				interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk_gates8 11>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio3: gpio3@20080000 {
+				compatible = "rockchip,gpio-bank";
+				reg = <0x20080000 0x100>;
+				interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk_gates8 12>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio4: gpio4@20084000 {
+				compatible = "rockchip,gpio-bank";
+				reg = <0x20084000 0x100>;
+				interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk_gates8 13>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio6: gpio6@2000a000 {
+				compatible = "rockchip,gpio-bank";
+				reg = <0x2000a000 0x100>;
+				interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clk_gates8 15>;
+
+				gpio-controller;
+				#gpio-cells = <2>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			pcfg_pull_default: pcfg_pull_default {
+				bias-pull-pin-default;
+			};
+
+			pcfg_pull_none: pcfg_pull_none {
+				bias-disable;
+			};
+
+			uart0 {
+				uart0_xfer: uart0-xfer {
+					rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				uart0_cts: uart0-cts {
+					rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				uart0_rts: uart0-rts {
+					rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+			};
+
+			uart1 {
+				uart1_xfer: uart1-xfer {
+					rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				uart1_cts: uart1-cts {
+					rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				uart1_rts: uart1-rts {
+					rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+			};
+
+			uart2 {
+				uart2_xfer: uart2-xfer {
+					rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+				/* no rts / cts for uart2 */
+			};
+
+			uart3 {
+				uart3_xfer: uart3-xfer {
+					rockchip,pins = <RK_GPIO3 27 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO3 28 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				uart3_cts: uart3-cts {
+					rockchip,pins = <RK_GPIO3 29 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				uart3_rts: uart3-rts {
+					rockchip,pins = <RK_GPIO3 30 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+			};
+
+			sd0 {
+				sd0_clk: sd0-clk {
+					rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd0_cmd: sd0-cmd {
+					rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd0_cd: sd0-cd {
+					rockchip,pins = <RK_GPIO3 14 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd0_wp: sd0-wp {
+					rockchip,pins = <RK_GPIO3 15 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd0_bus1: sd0-bus-width1 {
+					rockchip,pins = <RK_GPIO3 10 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd0_bus4: sd0-bus-width4 {
+					rockchip,pins = <RK_GPIO3 10 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO3 11 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO3 12 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO3 13 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+			};
+
+			sd1 {
+				sd1_clk: sd1-clk {
+					rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd1_cmd: sd1-cmd {
+					rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd1_cd: sd1-cd {
+					rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd1_wp: sd1-wp {
+					rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd1_bus1: sd1-bus-width1 {
+					rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+
+				sd1_bus4: sd1-bus-width4 {
+					rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_default>,
+							<RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_default>;
+					rockchip,config = <&pcfg_pull_default>;
+				};
+			};
+		};
+
+		uart0: serial@10124000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x10124000 0x400>;
+			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <1>;
+			clocks = <&clk_gates1 8>;
+			status = "disabled";
+		};
+
+		uart1: serial@10126000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x10126000 0x400>;
+			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <1>;
+			clocks = <&clk_gates1 10>;
+			status = "disabled";
+		};
+
+		uart2: serial@20064000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x20064000 0x400>;
+			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <1>;
+			clocks = <&clk_gates1 12>;
+			status = "disabled";
+		};
+
+		uart3: serial@20068000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x20068000 0x400>;
+			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <1>;
+			clocks = <&clk_gates1 14>;
+			status = "disabled";
+		};
+
+		dwmmc@10214000 {
+			compatible = "rockchip,rk2928-dw-mshc";
+			reg = <0x10214000 0x1000>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			clocks = <&clk_gates5 10>, <&clk_gates2 11>;
+			clock-names = "biu", "ciu";
+
+			status = "disabled";
+		};
+
+		dwmmc@10218000 {
+			compatible = "rockchip,rk2928-dw-mshc";
+			reg = <0x10218000 0x1000>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			clocks = <&clk_gates5 11>, <&clk_gates2 13>;
+			clock-names = "biu", "ciu";
+
+			status = "disabled";
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/s3c2416.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/s3c2416.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/s3c2416.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/s3c2416.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,79 @@
+/*
+ * Samsung's S3C2416 SoC device tree source
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "s3c24xx.dtsi"
+#include "s3c2416-pinctrl.dtsi"
+
+/ {
+	model = "Samsung S3C2416 SoC";
+	compatible = "samsung,s3c2416";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ejs";
+		};
+	};
+
+	interrupt-controller@4a000000 {
+		compatible = "samsung,s3c2416-irq";
+	};
+
+	pinctrl@56000000 {
+		compatible = "samsung,s3c2416-pinctrl";
+	};
+
+	serial@50000000 {
+		compatible = "samsung,s3c2440-uart";
+	};
+
+	serial@50004000 {
+		compatible = "samsung,s3c2440-uart";
+	};
+
+	serial@50008000 {
+		compatible = "samsung,s3c2440-uart";
+	};
+
+	serial@5000C000 {
+		compatible = "samsung,s3c2440-uart";
+		reg = <0x5000C000 0x4000>;
+		interrupts = <1 18 24 4>, <1 18 25 4>;
+		status = "disabled";
+	};
+
+	sdhci@4AC00000 {
+		compatible = "samsung,s3c6410-sdhci";
+		reg = <0x4AC00000 0x100>;
+		interrupts = <0 0 21 3>;
+		status = "disabled";
+	};
+
+	sdhci@4A800000 {
+		compatible = "samsung,s3c6410-sdhci";
+		reg = <0x4A800000 0x100>;
+		interrupts = <0 0 20 3>;
+		status = "disabled";
+	};
+
+	watchdog@53000000 {
+		interrupts = <1 9 27 3>;
+	};
+
+	rtc@57000000 {
+		compatible = "samsung,s3c2416-rtc";
+	};
+
+	i2c@54000000 {
+		compatible = "samsung,s3c2440-i2c";
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/s3c2416-pinctrl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/s3c2416-pinctrl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/s3c2416-pinctrl.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/s3c2416-pinctrl.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,173 @@
+/*
+ * Samsung S3C2416 pinctrl settings
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+&pinctrl_0 {
+	/*
+	 * Pin banks
+	 */
+
+	gpa: gpa {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpb: gpb {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpc: gpc {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpd: gpd {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpe: gpe {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpf: gpf {
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg: gpg {
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gph: gph {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpj: gpj {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpk: gpk {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpl: gpl {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpm: gpm {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	/*
+	 * Pin groups
+	 */
+
+	uart0_data: uart0-data {
+		samsung,pins = "gph-0", "gph-1";
+		samsung,pin-function = <2>;
+	};
+
+	uart0_fctl: uart0-fctl {
+		samsung,pins = "gph-8", "gph-9";
+		samsung,pin-function = <2>;
+	};
+
+	uart1_data: uart1-data {
+		samsung,pins = "gph-2", "gph-3";
+		samsung,pin-function = <2>;
+	};
+
+	uart1_fctl: uart1-fctl {
+		samsung,pins = "gph-10", "gph-11";
+		samsung,pin-function = <2>;
+	};
+
+	uart2_data: uart2-data {
+		samsung,pins = "gph-4", "gph-5";
+		samsung,pin-function = <2>;
+	};
+
+	uart2_fctl: uart2-fctl {
+		samsung,pins = "gph-6", "gph-7";
+		samsung,pin-function = <2>;
+	};
+
+	uart3_data: uart3-data {
+		samsung,pins = "gph-6", "gph-7";
+		samsung,pin-function = <2>;
+	};
+
+	extuart_clk: extuart-clk {
+		samsung,pins = "gph-12";
+		samsung,pin-function = <2>;
+	};
+
+	i2c0_bus: i2c0-bus {
+		samsung,pins = "gpe-14", "gpe-15";
+		samsung,pin-function = <2>;
+	};
+
+	spi0_bus: spi0-bus {
+		samsung,pins = "gpe-11", "gpe-12", "gpe-13";
+		samsung,pin-function = <2>;
+	};
+
+	sd0_clk: sd0-clk {
+		samsung,pins = "gpe-5";
+		samsung,pin-function = <2>;
+	};
+
+	sd0_cmd: sd0-cmd {
+		samsung,pins = "gpe-6";
+		samsung,pin-function = <2>;
+	};
+
+	sd0_bus1: sd0-bus1 {
+		samsung,pins = "gpe-7";
+		samsung,pin-function = <2>;
+	};
+
+	sd0_bus4: sd0-bus4 {
+		samsung,pins = "gpe-8", "gpe-9", "gpe-10";
+		samsung,pin-function = <2>;
+	};
+
+	sd1_cmd: sd1-cmd {
+		samsung,pins = "gpl-8";
+		samsung,pin-function = <2>;
+	};
+
+	sd1_clk: sd1-clk {
+		samsung,pins = "gpl-9";
+		samsung,pin-function = <2>;
+	};
+
+	sd1_bus1: sd1-bus1 {
+		samsung,pins = "gpl-0";
+		samsung,pin-function = <2>;
+	};
+
+	sd1_bus4: sd1-bus4 {
+		samsung,pins = "gpl-1", "gpl-2", "gpl-3";
+		samsung,pin-function = <2>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/s3c2416-smdk2416.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/s3c2416-smdk2416.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/s3c2416-smdk2416.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/s3c2416-smdk2416.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,72 @@
+/*
+ * SAMSUNG SMDK2416 board device tree source
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include "s3c2416.dtsi"
+
+/ {
+	model = "SMDK2416";
+	compatible = "samsung,s3c2416";
+
+	memory {
+		reg =  <0x30000000 0x4000000>;
+	};
+
+	serial@50000000 {
+		status = "okay";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_data>, <&uart0_fctl>;
+	};
+
+	serial@50004000 {
+		status = "okay";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart1_data>, <&uart1_fctl>;
+	};
+
+	serial@50008000 {
+		status = "okay";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2_data>;
+	};
+
+	serial@5000C000 {
+		status = "okay";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart3_data>;
+	};
+
+	watchdog@53000000 {
+		status = "okay";
+	};
+
+	rtc@57000000 {
+		status = "okay";
+	};
+
+	sdhci@4AC00000 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&sd0_clk>, <&sd0_cmd>,
+				<&sd0_bus1>, <&sd0_bus4>;
+		bus-width = <4>;
+		cd-gpios = <&gpf 1 0>;
+		cd-inverted;
+		status = "okay";
+	};
+
+	sdhci@4A800000 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&sd1_clk>, <&sd1_cmd>,
+				<&sd1_bus1>, <&sd1_bus4>;
+		bus-width = <4>;
+		broken-cd;
+		status = "okay";
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/s3c24xx.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/s3c24xx.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/s3c24xx.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/s3c24xx.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * Samsung's S3C24XX family device tree source
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "samsung,s3c24xx";
+	interrupt-parent = <&intc>;
+
+	aliases {
+		pinctrl0 = &pinctrl_0;
+	};
+
+	intc:interrupt-controller@4a000000 {
+		compatible = "samsung,s3c2410-irq";
+		reg = <0x4a000000 0x100>;
+		interrupt-controller;
+		#interrupt-cells = <4>;
+	};
+
+	pinctrl_0: pinctrl@56000000 {
+		reg = <0x56000000 0x1000>;
+
+		wakeup-interrupt-controller {
+			compatible = "samsung,s3c2410-wakeup-eint";
+			interrupts = <0 0 0 3>,
+				     <0 0 1 3>,
+				     <0 0 2 3>,
+				     <0 0 3 3>,
+				     <0 0 4 4>,
+				     <0 0 5 4>;
+		};
+	};
+
+	timer@51000000 {
+		compatible = "samsung,s3c2410-pwm";
+		reg = <0x51000000 0x1000>;
+		interrupts = <0 0 10 3>, <0 0 11 3>, <0 0 12 3>, <0 0 13 3>, <0 0 14 3>;
+		#pwm-cells = <4>;
+	};
+
+	serial@50000000 {
+		compatible = "samsung,s3c2410-uart";
+		reg = <0x50000000 0x4000>;
+		interrupts = <1 28 0 4>, <1 28 1 4>;
+		status = "disabled";
+	};
+
+	serial@50004000 {
+		compatible = "samsung,s3c2410-uart";
+		reg = <0x50004000 0x4000>;
+		interrupts = <1 23 3 4>, <1 23 4 4>;
+		status = "disabled";
+	};
+
+	serial@50008000 {
+		compatible = "samsung,s3c2410-uart";
+		reg = <0x50008000 0x4000>;
+		interrupts = <1 15 6 4>, <1 15 7 4>;
+		status = "disabled";
+	};
+
+	watchdog@53000000 {
+		compatible = "samsung,s3c2410-wdt";
+		reg = <0x53000000 0x100>;
+		interrupts = <0 0 9 3>;
+		status = "disabled";
+	};
+
+	rtc@57000000 {
+		compatible = "samsung,s3c2410-rtc";
+		reg = <0x57000000 0x100>;
+		interrupts = <0 0 30 3>, <0 0 8 3>;
+		status = "disabled";
+	};
+
+	i2c@54000000 {
+		compatible = "samsung,s3c2410-i2c";
+		reg = <0x54000000 0x100>;
+		interrupts = <0 0 27 3>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d31ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d31ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d31ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d31ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "sama5d3xmb.dtsi"
-/include/ "sama5d3xdm.dtsi"
+#include "sama5d3xmb.dtsi"
+#include "sama5d3xdm.dtsi"
 
 / {
 	model = "Atmel SAMA5D31-EK";
@@ -41,7 +41,7 @@
 	leds {
 		d3 {
 			label = "d3";
-			gpios = <&pioE 24 0>;
+			gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d33ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d33ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d33ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d33ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "sama5d3xmb.dtsi"
-/include/ "sama5d3xdm.dtsi"
+#include "sama5d3xmb.dtsi"
+#include "sama5d3xdm.dtsi"
 
 / {
 	model = "Atmel SAMA5D33-EK";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d34ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d34ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d34ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d34ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,8 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "sama5d3xmb.dtsi"
-/include/ "sama5d3xdm.dtsi"
+#include "sama5d3xmb.dtsi"
+#include "sama5d3xdm.dtsi"
 
 / {
 	model = "Atmel SAMA5D34-EK";
@@ -51,7 +51,7 @@
 	leds {
 		d3 {
 			label = "d3";
-			gpios = <&pioE 24 0>;
+			gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d35ek.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d35ek.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d35ek.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d35ek.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "sama5d3xmb.dtsi"
+#include "sama5d3xmb.dtsi"
 
 / {
 	model = "Atmel SAMA5D35-EK";
@@ -48,7 +48,7 @@
 
 		pb_user1 {
 			label = "pb_user1";
-			gpios = <&pioE 27 0>;
+			gpios = <&pioE 27 GPIO_ACTIVE_HIGH>;
 			linux,code = <0x100>;
 			gpio-key,wakeup;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d3.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d3.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d3.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d3.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,11 @@
  * Licensed under GPLv2 or later.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Atmel SAMA5D3 family SoC";
@@ -35,8 +39,12 @@
 		ssc1 = &ssc1;
 	};
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 		cpu@0 {
+			device_type = "cpu";
 			compatible = "arm,cortex-a5";
+			reg = <0x0>;
 		};
 	};
 
@@ -59,8 +67,8 @@
 			mmc0: mmc@f0000000 {
 				compatible = "atmel,hsmci";
 				reg = <0xf0000000 0x600>;
-				interrupts = <21 4 0>;
-				dmas = <&dma0 2 0>;
+				interrupts = <21 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(0)>;
 				dma-names = "rxtx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7>;
@@ -72,9 +80,12 @@
 			spi0: spi@f0004000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "atmel,at91sam9x5-spi";
+				compatible = "atmel,at91rm9200-spi";
 				reg = <0xf0004000 0x100>;
-				interrupts = <24 4 3>;
+				interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>;
+				dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(1)>,
+				       <&dma0 2 AT91_DMA_CFG_PER_ID(2)>;
+				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi0>;
 				status = "disabled";
@@ -83,7 +94,7 @@
 			ssc0: ssc@f0008000 {
 				compatible = "atmel,at91sam9g45-ssc";
 				reg = <0xf0008000 0x4000>;
-				interrupts = <38 4 4>;
+				interrupts = <38 IRQ_TYPE_LEVEL_HIGH 4>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>;
 				status = "disabled";
@@ -92,7 +103,7 @@
 			can0: can@f000c000 {
 				compatible = "atmel,at91sam9x5-can";
 				reg = <0xf000c000 0x300>;
-				interrupts = <40 4 3>;
+				interrupts = <40 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_can0_rx_tx>;
 				status = "disabled";
@@ -101,15 +112,15 @@
 			tcb0: timer@f0010000 {
 				compatible = "atmel,at91sam9x5-tcb";
 				reg = <0xf0010000 0x100>;
-				interrupts = <26 4 0>;
+				interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			i2c0: i2c@f0014000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf0014000 0x4000>;
-				interrupts = <18 4 6>;
-				dmas = <&dma0 2 7>,
-				       <&dma0 2 8>;
+				interrupts = <18 IRQ_TYPE_LEVEL_HIGH 6>;
+				dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(7)>,
+				       <&dma0 2 AT91_DMA_CFG_PER_ID(8)>;
 				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_i2c0>;
@@ -121,9 +132,9 @@
 			i2c1: i2c@f0018000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf0018000 0x4000>;
-				interrupts = <19 4 6>;
-				dmas = <&dma0 2 9>,
-				       <&dma0 2 10>;
+				interrupts = <19 IRQ_TYPE_LEVEL_HIGH 6>;
+				dmas = <&dma0 2 AT91_DMA_CFG_PER_ID(9)>,
+				       <&dma0 2 AT91_DMA_CFG_PER_ID(10)>;
 				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_i2c1>;
@@ -135,7 +146,7 @@
 			usart0: serial@f001c000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf001c000 0x100>;
-				interrupts = <12 4 5>;
+				interrupts = <12 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart0>;
 				status = "disabled";
@@ -144,7 +155,7 @@
 			usart1: serial@f0020000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf0020000 0x100>;
-				interrupts = <13 4 5>;
+				interrupts = <13 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart1>;
 				status = "disabled";
@@ -153,7 +164,7 @@
 			macb0: ethernet@f0028000 {
 				compatible = "cdns,pc302-gem", "cdns,gem";
 				reg = <0xf0028000 0x100>;
-				interrupts = <34 4 3>;
+				interrupts = <34 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_macb0_data_rgmii &pinctrl_macb0_signal_rgmii>;
 				status = "disabled";
@@ -162,15 +173,15 @@
 			isi: isi@f0034000 {
 				compatible = "atmel,at91sam9g45-isi";
 				reg = <0xf0034000 0x4000>;
-				interrupts = <37 4 5>;
+				interrupts = <37 IRQ_TYPE_LEVEL_HIGH 5>;
 				status = "disabled";
 			};
 
 			mmc1: mmc@f8000000 {
 				compatible = "atmel,hsmci";
 				reg = <0xf8000000 0x600>;
-				interrupts = <22 4 0>;
-				dmas = <&dma1 2 0>;
+				interrupts = <22 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(0)>;
 				dma-names = "rxtx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>;
@@ -182,8 +193,8 @@
 			mmc2: mmc@f8004000 {
 				compatible = "atmel,hsmci";
 				reg = <0xf8004000 0x600>;
-				interrupts = <23 4 0>;
-				dmas = <&dma1 2 1>;
+				interrupts = <23 IRQ_TYPE_LEVEL_HIGH 0>;
+				dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(1)>;
 				dma-names = "rxtx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>;
@@ -195,9 +206,12 @@
 			spi1: spi@f8008000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "atmel,at91sam9x5-spi";
+				compatible = "atmel,at91rm9200-spi";
 				reg = <0xf8008000 0x100>;
-				interrupts = <25 4 3>;
+				interrupts = <25 IRQ_TYPE_LEVEL_HIGH 3>;
+				dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(15)>,
+				       <&dma1 2 AT91_DMA_CFG_PER_ID(16)>;
+				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_spi1>;
 				status = "disabled";
@@ -206,7 +220,7 @@
 			ssc1: ssc@f800c000 {
 				compatible = "atmel,at91sam9g45-ssc";
 				reg = <0xf800c000 0x4000>;
-				interrupts = <39 4 4>;
+				interrupts = <39 IRQ_TYPE_LEVEL_HIGH 4>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>;
 				status = "disabled";
@@ -215,7 +229,7 @@
 			can1: can@f8010000 {
 				compatible = "atmel,at91sam9x5-can";
 				reg = <0xf8010000 0x300>;
-				interrupts = <41 4 3>;
+				interrupts = <41 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_can1_rx_tx>;
 			};
@@ -223,13 +237,13 @@
 			tcb1: timer@f8014000 {
 				compatible = "atmel,at91sam9x5-tcb";
 				reg = <0xf8014000 0x100>;
-				interrupts = <27 4 0>;
+				interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			adc0: adc@f8018000 {
 				compatible = "atmel,at91sam9260-adc";
 				reg = <0xf8018000 0x100>;
-				interrupts = <29 4 5>;
+				interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <
 					&pinctrl_adc0_adtrg
@@ -283,7 +297,7 @@
 			tsadcc: tsadcc@f8018000 {
 				compatible = "atmel,at91sam9x5-tsadcc";
 				reg = <0xf8018000 0x4000>;
-				interrupts = <29 4 5>;
+				interrupts = <29 IRQ_TYPE_LEVEL_HIGH 5>;
 				atmel,tsadcc_clock = <300000>;
 				atmel,filtering_average = <0x03>;
 				atmel,pendet_debounce = <0x08>;
@@ -295,9 +309,9 @@
 			i2c2: i2c@f801c000 {
 				compatible = "atmel,at91sam9x5-i2c";
 				reg = <0xf801c000 0x4000>;
-				interrupts = <20 4 6>;
-				dmas = <&dma1 2 11>,
-				       <&dma1 2 12>;
+				interrupts = <20 IRQ_TYPE_LEVEL_HIGH 6>;
+				dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(11)>,
+				       <&dma1 2 AT91_DMA_CFG_PER_ID(12)>;
 				dma-names = "tx", "rx";
 				#address-cells = <1>;
 				#size-cells = <0>;
@@ -307,7 +321,7 @@
 			usart2: serial@f8020000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf8020000 0x100>;
-				interrupts = <14 4 5>;
+				interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart2>;
 				status = "disabled";
@@ -316,7 +330,7 @@
 			usart3: serial@f8024000 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xf8024000 0x100>;
-				interrupts = <15 4 5>;
+				interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_usart3>;
 				status = "disabled";
@@ -325,7 +339,7 @@
 			macb1: ethernet@f802c000 {
 				compatible = "cdns,at32ap7000-macb", "cdns,macb";
 				reg = <0xf802c000 0x100>;
-				interrupts = <35 4 3>;
+				interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_macb1_rmii>;
 				status = "disabled";
@@ -334,7 +348,7 @@
 			sha@f8034000 {
 				compatible = "atmel,sam9g46-sha";
 				reg = <0xf8034000 0x100>;
-				interrupts = <42 4 0>;
+				interrupts = <42 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			aes@f8038000 {
@@ -346,20 +360,20 @@
 			tdes@f803c000 {
 				compatible = "atmel,sam9g46-tdes";
 				reg = <0xf803c000 0x100>;
-				interrupts = <44 4 0>;
+				interrupts = <44 IRQ_TYPE_LEVEL_HIGH 0>;
 			};
 
 			dma0: dma-controller@ffffe600 {
 				compatible = "atmel,at91sam9g45-dma";
 				reg = <0xffffe600 0x200>;
-				interrupts = <30 4 0>;
+				interrupts = <30 IRQ_TYPE_LEVEL_HIGH 0>;
 				#dma-cells = <2>;
 			};
 
 			dma1: dma-controller@ffffe800 {
 				compatible = "atmel,at91sam9g45-dma";
 				reg = <0xffffe800 0x200>;
-				interrupts = <31 4 0>;
+				interrupts = <31 IRQ_TYPE_LEVEL_HIGH 0>;
 				#dma-cells = <2>;
 			};
 
@@ -371,7 +385,7 @@
 			dbgu: serial@ffffee00 {
 				compatible = "atmel,at91sam9260-usart";
 				reg = <0xffffee00 0x200>;
-				interrupts = <2 4 7>;
+				interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>;
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_dbgu>;
 				status = "disabled";
@@ -403,202 +417,202 @@
 				adc0 {
 					pinctrl_adc0_adtrg: adc0_adtrg {
 						atmel,pins =
-							<3 19 0x1 0x0>;	/* PD19 periph A ADTRG */
+							<AT91_PIOD 19 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD19 periph A ADTRG */
 					};
 					pinctrl_adc0_ad0: adc0_ad0 {
 						atmel,pins =
-							<3 20 0x1 0x0>;	/* PD20 periph A AD0 */
+							<AT91_PIOD 20 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD20 periph A AD0 */
 					};
 					pinctrl_adc0_ad1: adc0_ad1 {
 						atmel,pins =
-							<3 21 0x1 0x0>;	/* PD21 periph A AD1 */
+							<AT91_PIOD 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD21 periph A AD1 */
 					};
 					pinctrl_adc0_ad2: adc0_ad2 {
 						atmel,pins =
-							<3 22 0x1 0x0>;	/* PD22 periph A AD2 */
+							<AT91_PIOD 22 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD22 periph A AD2 */
 					};
 					pinctrl_adc0_ad3: adc0_ad3 {
 						atmel,pins =
-							<3 23 0x1 0x0>;	/* PD23 periph A AD3 */
+							<AT91_PIOD 23 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD23 periph A AD3 */
 					};
 					pinctrl_adc0_ad4: adc0_ad4 {
 						atmel,pins =
-							<3 24 0x1 0x0>;	/* PD24 periph A AD4 */
+							<AT91_PIOD 24 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD24 periph A AD4 */
 					};
 					pinctrl_adc0_ad5: adc0_ad5 {
 						atmel,pins =
-							<3 25 0x1 0x0>;	/* PD25 periph A AD5 */
+							<AT91_PIOD 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD25 periph A AD5 */
 					};
 					pinctrl_adc0_ad6: adc0_ad6 {
 						atmel,pins =
-							<3 26 0x1 0x0>;	/* PD26 periph A AD6 */
+							<AT91_PIOD 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD26 periph A AD6 */
 					};
 					pinctrl_adc0_ad7: adc0_ad7 {
 						atmel,pins =
-							<3 27 0x1 0x0>;	/* PD27 periph A AD7 */
+							<AT91_PIOD 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD27 periph A AD7 */
 					};
 					pinctrl_adc0_ad8: adc0_ad8 {
 						atmel,pins =
-							<3 28 0x1 0x0>;	/* PD28 periph A AD8 */
+							<AT91_PIOD 28 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD28 periph A AD8 */
 					};
 					pinctrl_adc0_ad9: adc0_ad9 {
 						atmel,pins =
-							<3 29 0x1 0x0>;	/* PD29 periph A AD9 */
+							<AT91_PIOD 29 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD29 periph A AD9 */
 					};
 					pinctrl_adc0_ad10: adc0_ad10 {
 						atmel,pins =
-							<3 30 0x1 0x0>;	/* PD30 periph A AD10, conflicts with PCK0 */
+							<AT91_PIOD 30 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD30 periph A AD10, conflicts with PCK0 */
 					};
 					pinctrl_adc0_ad11: adc0_ad11 {
 						atmel,pins =
-							<3 31 0x1 0x0>;	/* PD31 periph A AD11, conflicts with PCK1 */
+							<AT91_PIOD 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD31 periph A AD11, conflicts with PCK1 */
 					};
 				};
 
 				can0 {
 					pinctrl_can0_rx_tx: can0_rx_tx {
 						atmel,pins =
-							<3 14 0x3 0x0	/* PD14 periph C RX, conflicts with SCK0, SPI0_NPCS1 */
-							 3 15 0x3 0x0>;	/* PD15 periph C TX, conflicts with CTS0, SPI0_NPCS2 */
+							<AT91_PIOD 14 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PD14 periph C RX, conflicts with SCK0, SPI0_NPCS1 */
+							 AT91_PIOD 15 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PD15 periph C TX, conflicts with CTS0, SPI0_NPCS2 */
 					};
 				};
 
 				can1 {
 					pinctrl_can1_rx_tx: can1_rx_tx {
 						atmel,pins =
-							<1 14 0x2 0x0	/* PB14 periph B RX, conflicts with GCRS */
-							 1 15 0x2 0x0>;	/* PB15 periph B TX, conflicts with GCOL */
+							<AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB14 periph B RX, conflicts with GCRS */
+							 AT91_PIOB 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB15 periph B TX, conflicts with GCOL */
 					};
 				};
 
 				dbgu {
 					pinctrl_dbgu: dbgu-0 {
 						atmel,pins =
-							<1 30 0x1 0x0	/* PB30 periph A */
-							 1 31 0x1 0x1>;	/* PB31 periph A with pullup */
+							<AT91_PIOB 30 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB30 periph A */
+							 AT91_PIOB 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PB31 periph A with pullup */
 					};
 				};
 
 				i2c0 {
 					pinctrl_i2c0: i2c0-0 {
 						atmel,pins =
-							<0 30 0x1 0x0	/* PA30 periph A TWD0 pin, conflicts with URXD1, ISI_VSYNC */
-							 0 31 0x1 0x0>;	/* PA31 periph A TWCK0 pin, conflicts with UTXD1, ISI_HSYNC */
+							<AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA30 periph A TWD0 pin, conflicts with URXD1, ISI_VSYNC */
+							 AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PA31 periph A TWCK0 pin, conflicts with UTXD1, ISI_HSYNC */
 					};
 				};
 
 				i2c1 {
 					pinctrl_i2c1: i2c1-0 {
 						atmel,pins =
-							<2 26 0x2 0x0	/* PC26 periph B TWD1 pin, conflicts with SPI1_NPCS1, ISI_D11 */
-							 2 27 0x2 0x0>;	/* PC27 periph B TWCK1 pin, conflicts with SPI1_NPCS2, ISI_D10 */
+							<AT91_PIOC 26 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PC26 periph B TWD1 pin, conflicts with SPI1_NPCS1, ISI_D11 */
+							 AT91_PIOC 27 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PC27 periph B TWCK1 pin, conflicts with SPI1_NPCS2, ISI_D10 */
 					};
 				};
 
 				isi {
 					pinctrl_isi: isi-0 {
 						atmel,pins =
-							<0 16 0x3 0x0	/* PA16 periph C ISI_D0, conflicts with LCDDAT16 */
-							 0 17 0x3 0x0	/* PA17 periph C ISI_D1, conflicts with LCDDAT17 */
-							 0 18 0x3 0x0	/* PA18 periph C ISI_D2, conflicts with LCDDAT18, TWD2 */
-							 0 19 0x3 0x0	/* PA19 periph C ISI_D3, conflicts with LCDDAT19, TWCK2 */
-							 0 20 0x3 0x0	/* PA20 periph C ISI_D4, conflicts with LCDDAT20, PWMH0 */
-							 0 21 0x3 0x0	/* PA21 periph C ISI_D5, conflicts with LCDDAT21, PWML0 */
-							 0 22 0x3 0x0	/* PA22 periph C ISI_D6, conflicts with LCDDAT22, PWMH1 */
-							 0 23 0x3 0x0	/* PA23 periph C ISI_D7, conflicts with LCDDAT23, PWML1 */
-							 2 30 0x3 0x0	/* PC30 periph C ISI_PCK, conflicts with UTXD0 */
-							 0 31 0x3 0x0	/* PA31 periph C ISI_HSYNC, conflicts with TWCK0, UTXD1 */
-							 0 30 0x3 0x0	/* PA30 periph C ISI_VSYNC, conflicts with TWD0, URXD1 */
-							 2 29 0x3 0x0	/* PC29 periph C ISI_PD8, conflicts with URXD0, PWMFI2 */
-							 2 28 0x3 0x0>;	/* PC28 periph C ISI_PD9, conflicts with SPI1_NPCS3, PWMFI0 */
+							<AT91_PIOA 16 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA16 periph C ISI_D0, conflicts with LCDDAT16 */
+							 AT91_PIOA 17 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA17 periph C ISI_D1, conflicts with LCDDAT17 */
+							 AT91_PIOA 18 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA18 periph C ISI_D2, conflicts with LCDDAT18, TWD2 */
+							 AT91_PIOA 19 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA19 periph C ISI_D3, conflicts with LCDDAT19, TWCK2 */
+							 AT91_PIOA 20 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA20 periph C ISI_D4, conflicts with LCDDAT20, PWMH0 */
+							 AT91_PIOA 21 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA21 periph C ISI_D5, conflicts with LCDDAT21, PWML0 */
+							 AT91_PIOA 22 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA22 periph C ISI_D6, conflicts with LCDDAT22, PWMH1 */
+							 AT91_PIOA 23 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA23 periph C ISI_D7, conflicts with LCDDAT23, PWML1 */
+							 AT91_PIOC 30 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC30 periph C ISI_PCK, conflicts with UTXD0 */
+							 AT91_PIOA 31 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA31 periph C ISI_HSYNC, conflicts with TWCK0, UTXD1 */
+							 AT91_PIOA 30 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PA30 periph C ISI_VSYNC, conflicts with TWD0, URXD1 */
+							 AT91_PIOC 29 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC29 periph C ISI_PD8, conflicts with URXD0, PWMFI2 */
+							 AT91_PIOC 28 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PC28 periph C ISI_PD9, conflicts with SPI1_NPCS3, PWMFI0 */
 					};
 					pinctrl_isi_pck_as_mck: isi_pck_as_mck-0 {
 						atmel,pins =
-							<3 31 0x2 0x0>;	/* PD31 periph B ISI_MCK */
+							<AT91_PIOD 31 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PD31 periph B ISI_MCK */
 					};
 				};
 
 				lcd {
 					pinctrl_lcd: lcd-0 {
 						atmel,pins =
-							<0 24 0x1 0x0	/* PA24 periph A LCDPWM */
-							 0 26 0x1 0x0	/* PA26 periph A LCDVSYNC */
-							 0 27 0x1 0x0	/* PA27 periph A LCDHSYNC */
-							 0 25 0x1 0x0	/* PA25 periph A LCDDISP */
-							 0 29 0x1 0x0	/* PA29 periph A LCDDEN */
-							 0 28 0x1 0x0	/* PA28 periph A LCDPCK */
-							 0 0 0x1 0x0	/* PA0 periph A LCDD0 pin */
-							 0 1 0x1 0x0	/* PA1 periph A LCDD1 pin */
-							 0 2 0x1 0x0	/* PA2 periph A LCDD2 pin */
-							 0 3 0x1 0x0	/* PA3 periph A LCDD3 pin */
-							 0 4 0x1 0x0	/* PA4 periph A LCDD4 pin */
-							 0 5 0x1 0x0	/* PA5 periph A LCDD5 pin */
-							 0 6 0x1 0x0	/* PA6 periph A LCDD6 pin */
-							 0 7 0x1 0x0	/* PA7 periph A LCDD7 pin */
-							 0 8 0x1 0x0	/* PA8 periph A LCDD8 pin */
-							 0 9 0x1 0x0	/* PA9 periph A LCDD9 pin */
-							 0 10 0x1 0x0	/* PA10 periph A LCDD10 pin */
-							 0 11 0x1 0x0	/* PA11 periph A LCDD11 pin */
-							 0 12 0x1 0x0	/* PA12 periph A LCDD12 pin */
-							 0 13 0x1 0x0	/* PA13 periph A LCDD13 pin */
-							 0 14 0x1 0x0	/* PA14 periph A LCDD14 pin */
-							 0 15 0x1 0x0	/* PA15 periph A LCDD15 pin */
-							 2 14 0x3 0x0	/* PC14 periph C LCDD16 pin */
-							 2 13 0x3 0x0	/* PC13 periph C LCDD17 pin */
-							 2 12 0x3 0x0	/* PC12 periph C LCDD18 pin */
-							 2 11 0x3 0x0	/* PC11 periph C LCDD19 pin */
-							 2 10 0x3 0x0	/* PC10 periph C LCDD20 pin */
-							 2 15 0x3 0x0	/* PC15 periph C LCDD21 pin */
-							 4 27 0x3 0x0	/* PE27 periph C LCDD22 pin */
-							 4 28 0x3 0x0>;	/* PE28 periph C LCDD23 pin */
+							<AT91_PIOA 24 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA24 periph A LCDPWM */
+							 AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA26 periph A LCDVSYNC */
+							 AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA27 periph A LCDHSYNC */
+							 AT91_PIOA 25 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA25 periph A LCDDISP */
+							 AT91_PIOA 29 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA29 periph A LCDDEN */
+							 AT91_PIOA 28 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA28 periph A LCDPCK */
+							 AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA0 periph A LCDD0 pin */
+							 AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA1 periph A LCDD1 pin */
+							 AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA2 periph A LCDD2 pin */
+							 AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA3 periph A LCDD3 pin */
+							 AT91_PIOA 4 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA4 periph A LCDD4 pin */
+							 AT91_PIOA 5 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA5 periph A LCDD5 pin */
+							 AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA6 periph A LCDD6 pin */
+							 AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA7 periph A LCDD7 pin */
+							 AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA8 periph A LCDD8 pin */
+							 AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA9 periph A LCDD9 pin */
+							 AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA10 periph A LCDD10 pin */
+							 AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA11 periph A LCDD11 pin */
+							 AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA12 periph A LCDD12 pin */
+							 AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA13 periph A LCDD13 pin */
+							 AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA14 periph A LCDD14 pin */
+							 AT91_PIOA 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PA15 periph A LCDD15 pin */
+							 AT91_PIOC 14 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC14 periph C LCDD16 pin */
+							 AT91_PIOC 13 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC13 periph C LCDD17 pin */
+							 AT91_PIOC 12 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC12 periph C LCDD18 pin */
+							 AT91_PIOC 11 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC11 periph C LCDD19 pin */
+							 AT91_PIOC 10 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC10 periph C LCDD20 pin */
+							 AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PC15 periph C LCDD21 pin */
+							 AT91_PIOE 27 AT91_PERIPH_C AT91_PINCTRL_NONE	/* PE27 periph C LCDD22 pin */
+							 AT91_PIOE 28 AT91_PERIPH_C AT91_PINCTRL_NONE>;	/* PE28 periph C LCDD23 pin */
 					};
 				};
 
 				macb0 {
 					pinctrl_macb0_data_rgmii: macb0_data_rgmii {
 						atmel,pins =
-							<1 0 0x1 0x0	/* PB0 periph A GTX0, conflicts with PWMH0 */
-							 1 1 0x1 0x0	/* PB1 periph A GTX1, conflicts with PWML0 */
-							 1 2 0x1 0x0	/* PB2 periph A GTX2, conflicts with TK1 */
-							 1 3 0x1 0x0	/* PB3 periph A GTX3, conflicts with TF1 */
-							 1 4 0x1 0x0	/* PB4 periph A GRX0, conflicts with PWMH1 */
-							 1 5 0x1 0x0	/* PB5 periph A GRX1, conflicts with PWML1 */
-							 1 6 0x1 0x0	/* PB6 periph A GRX2, conflicts with TD1 */
-							 1 7 0x1 0x0>;	/* PB7 periph A GRX3, conflicts with RK1 */
+							<AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB0 periph A GTX0, conflicts with PWMH0 */
+							 AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB1 periph A GTX1, conflicts with PWML0 */
+							 AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB2 periph A GTX2, conflicts with TK1 */
+							 AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB3 periph A GTX3, conflicts with TF1 */
+							 AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB4 periph A GRX0, conflicts with PWMH1 */
+							 AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB5 periph A GRX1, conflicts with PWML1 */
+							 AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB6 periph A GRX2, conflicts with TD1 */
+							 AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB7 periph A GRX3, conflicts with RK1 */
 					};
 					pinctrl_macb0_data_gmii: macb0_data_gmii {
 						atmel,pins =
-							<1 19 0x2 0x0	/* PB19 periph B GTX4, conflicts with MCI1_CDA */
-							 1 20 0x2 0x0	/* PB20 periph B GTX5, conflicts with MCI1_DA0 */
-							 1 21 0x2 0x0	/* PB21 periph B GTX6, conflicts with MCI1_DA1 */
-							 1 22 0x2 0x0	/* PB22 periph B GTX7, conflicts with MCI1_DA2 */
-							 1 23 0x2 0x0	/* PB23 periph B GRX4, conflicts with MCI1_DA3 */
-							 1 24 0x2 0x0	/* PB24 periph B GRX5, conflicts with MCI1_CK */
-							 1 25 0x2 0x0	/* PB25 periph B GRX6, conflicts with SCK1 */
-							 1 26 0x2 0x0>;	/* PB26 periph B GRX7, conflicts with CTS1 */
+							<AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB19 periph B GTX4, conflicts with MCI1_CDA */
+							 AT91_PIOB 20 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB20 periph B GTX5, conflicts with MCI1_DA0 */
+							 AT91_PIOB 21 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB21 periph B GTX6, conflicts with MCI1_DA1 */
+							 AT91_PIOB 22 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB22 periph B GTX7, conflicts with MCI1_DA2 */
+							 AT91_PIOB 23 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB23 periph B GRX4, conflicts with MCI1_DA3 */
+							 AT91_PIOB 24 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB24 periph B GRX5, conflicts with MCI1_CK */
+							 AT91_PIOB 25 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB25 periph B GRX6, conflicts with SCK1 */
+							 AT91_PIOB 26 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB26 periph B GRX7, conflicts with CTS1 */
 					};
 					pinctrl_macb0_signal_rgmii: macb0_signal_rgmii {
 						atmel,pins =
-							<1 8 0x1 0x0	/* PB8 periph A GTXCK, conflicts with PWMH2 */
-							 1 9 0x1 0x0	/* PB9 periph A GTXEN, conflicts with PWML2 */
-							 1 11 0x1 0x0	/* PB11 periph A GRXCK, conflicts with RD1 */
-							 1 13 0x1 0x0	/* PB13 periph A GRXER, conflicts with PWML3 */
-							 1 16 0x1 0x0	/* PB16 periph A GMDC */
-							 1 17 0x1 0x0	/* PB17 periph A GMDIO */
-							 1 18 0x1 0x0>;	/* PB18 periph A G125CK */
+							<AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB8 periph A GTXCK, conflicts with PWMH2 */
+							 AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB9 periph A GTXEN, conflicts with PWML2 */
+							 AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB11 periph A GRXCK, conflicts with RD1 */
+							 AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB13 periph A GRXER, conflicts with PWML3 */
+							 AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB16 periph A GMDC */
+							 AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB17 periph A GMDIO */
+							 AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB18 periph A G125CK */
 					};
 					pinctrl_macb0_signal_gmii: macb0_signal_gmii {
 						atmel,pins =
-							<1 9 0x1 0x0	/* PB9 periph A GTXEN, conflicts with PWML2 */
-							 1 10 0x1 0x0	/* PB10 periph A GTXER, conflicts with RF1 */
-							 1 11 0x1 0x0	/* PB11 periph A GRXCK, conflicts with RD1 */
-							 1 12 0x1 0x0	/* PB12 periph A GRXDV, conflicts with PWMH3 */
-							 1 13 0x1 0x0	/* PB13 periph A GRXER, conflicts with PWML3 */
-							 1 14 0x1 0x0	/* PB14 periph A GCRS, conflicts with CANRX1 */
-							 1 15 0x1 0x0	/* PB15 periph A GCOL, conflicts with CANTX1 */
-							 1 16 0x1 0x0	/* PB16 periph A GMDC */
-							 1 17 0x1 0x0	/* PB17 periph A GMDIO */
-							 1 27 0x2 0x0>;	/* PB27 periph B G125CKO */
+							<AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB9 periph A GTXEN, conflicts with PWML2 */
+							 AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB10 periph A GTXER, conflicts with RF1 */
+							 AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB11 periph A GRXCK, conflicts with RD1 */
+							 AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB12 periph A GRXDV, conflicts with PWMH3 */
+							 AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB13 periph A GRXER, conflicts with PWML3 */
+							 AT91_PIOB 14 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB14 periph A GCRS, conflicts with CANRX1 */
+							 AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB15 periph A GCOL, conflicts with CANTX1 */
+							 AT91_PIOB 16 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB16 periph A GMDC */
+							 AT91_PIOB 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB17 periph A GMDIO */
+							 AT91_PIOB 27 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB27 periph B G125CKO */
 					};
 
 				};
@@ -606,252 +620,251 @@
 				macb1 {
 					pinctrl_macb1_rmii: macb1_rmii-0 {
 						atmel,pins =
-							<2 0 0x1 0x0	/* PC0 periph A ETX0, conflicts with TIOA3 */
-							 2 1 0x1 0x0	/* PC1 periph A ETX1, conflicts with TIOB3 */
-							 2 2 0x1 0x0	/* PC2 periph A ERX0, conflicts with TCLK3 */
-							 2 3 0x1 0x0	/* PC3 periph A ERX1, conflicts with TIOA4 */
-							 2 4 0x1 0x0	/* PC4 periph A ETXEN, conflicts with TIOB4 */
-							 2 5 0x1 0x0	/* PC5 periph A ECRSDV,conflicts with TCLK4 */
-							 2 6 0x1 0x0	/* PC6 periph A ERXER, conflicts with TIOA5 */
-							 2 7 0x1 0x0	/* PC7 periph A EREFCK, conflicts with TIOB5 */
-							 2 8 0x1 0x0	/* PC8 periph A EMDC, conflicts with TCLK5 */
-							 2 9 0x1 0x0>;	/* PC9 periph A EMDIO  */
+							<AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC0 periph A ETX0, conflicts with TIOA3 */
+							 AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC1 periph A ETX1, conflicts with TIOB3 */
+							 AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC2 periph A ERX0, conflicts with TCLK3 */
+							 AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC3 periph A ERX1, conflicts with TIOA4 */
+							 AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC4 periph A ETXEN, conflicts with TIOB4 */
+							 AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC5 periph A ECRSDV,conflicts with TCLK4 */
+							 AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC6 periph A ERXER, conflicts with TIOA5 */
+							 AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC7 periph A EREFCK, conflicts with TIOB5 */
+							 AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC8 periph A EMDC, conflicts with TCLK5 */
+							 AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PC9 periph A EMDIO  */
 					};
 				};
 
 				mmc0 {
 					pinctrl_mmc0_clk_cmd_dat0: mmc0_clk_cmd_dat0 {
 						atmel,pins =
-							<3 9 0x1 0x0	/* PD9 periph A MCI0_CK */
-							 3 0 0x1 0x1	/* PD0 periph A MCI0_CDA with pullup */
-							 3 1 0x1 0x1>;	/* PD1 periph A MCI0_DA0 with pullup */
+							<AT91_PIOD 9 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD9 periph A MCI0_CK */
+							 AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD0 periph A MCI0_CDA with pullup */
+							 AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PD1 periph A MCI0_DA0 with pullup */
 					};
 					pinctrl_mmc0_dat1_3: mmc0_dat1_3 {
 						atmel,pins =
-							<3 2 0x1 0x1	/* PD2 periph A MCI0_DA1 with pullup */
-							 3 3 0x1 0x1	/* PD3 periph A MCI0_DA2 with pullup */
-							 3 4 0x1 0x1>;	/* PD4 periph A MCI0_DA3 with pullup */
+							<AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD2 periph A MCI0_DA1 with pullup */
+							 AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD3 periph A MCI0_DA2 with pullup */
+							 AT91_PIOD 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PD4 periph A MCI0_DA3 with pullup */
 					};
 					pinctrl_mmc0_dat4_7: mmc0_dat4_7 {
 						atmel,pins =
-							<3 5 0x1 0x1	/* PD5 periph A MCI0_DA4 with pullup, conflicts with TIOA0, PWMH2 */
-							 3 6 0x1 0x1	/* PD6 periph A MCI0_DA5 with pullup, conflicts with TIOB0, PWML2 */
-							 3 7 0x1 0x1	/* PD7 periph A MCI0_DA6 with pullup, conlicts with TCLK0, PWMH3 */
-							 3 8 0x1 0x1>;	/* PD8 periph A MCI0_DA7 with pullup, conflicts with PWML3 */
+							<AT91_PIOD 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD5 periph A MCI0_DA4 with pullup, conflicts with TIOA0, PWMH2 */
+							 AT91_PIOD 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD6 periph A MCI0_DA5 with pullup, conflicts with TIOB0, PWML2 */
+							 AT91_PIOD 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PD7 periph A MCI0_DA6 with pullup, conlicts with TCLK0, PWMH3 */
+							 AT91_PIOD 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PD8 periph A MCI0_DA7 with pullup, conflicts with PWML3 */
 					};
 				};
 
 				mmc1 {
 					pinctrl_mmc1_clk_cmd_dat0: mmc1_clk_cmd_dat0 {
 						atmel,pins =
-							<1 24 0x1 0x0	/* PB24 periph A MCI1_CK, conflicts with GRX5 */
-							 1 19 0x1 0x1	/* PB19 periph A MCI1_CDA with pullup, conflicts with GTX4 */
-							 1 20 0x1 0x1>;	/* PB20 periph A MCI1_DA0 with pullup, conflicts with GTX5 */
+							<AT91_PIOB 24 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB24 periph A MCI1_CK, conflicts with GRX5 */
+							 AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB19 periph A MCI1_CDA with pullup, conflicts with GTX4 */
+							 AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PB20 periph A MCI1_DA0 with pullup, conflicts with GTX5 */
 					};
 					pinctrl_mmc1_dat1_3: mmc1_dat1_3 {
 						atmel,pins =
-							<1 21 0x1 0x1	/* PB21 periph A MCI1_DA1 with pullup, conflicts with GTX6 */
-							 1 22 0x1 0x1	/* PB22 periph A MCI1_DA2 with pullup, conflicts with GTX7 */
-							 1 23 0x1 0x1>;	/* PB23 periph A MCI1_DA3 with pullup, conflicts with GRX4 */
+							<AT91_PIOB 21 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB21 periph A MCI1_DA1 with pullup, conflicts with GTX6 */
+							 AT91_PIOB 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PB22 periph A MCI1_DA2 with pullup, conflicts with GTX7 */
+							 AT91_PIOB 23 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PB23 periph A MCI1_DA3 with pullup, conflicts with GRX4 */
 					};
 				};
 
 				mmc2 {
 					pinctrl_mmc2_clk_cmd_dat0: mmc2_clk_cmd_dat0 {
 						atmel,pins =
-							<2 15 0x1 0x0	/* PC15 periph A MCI2_CK, conflicts with PCK2 */
-							 2 10 0x1 0x1	/* PC10 periph A MCI2_CDA with pullup */
-							 2 11 0x1 0x1>;	/* PC11 periph A MCI2_DA0 with pullup */
+							<AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC15 periph A MCI2_CK, conflicts with PCK2 */
+							 AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PC10 periph A MCI2_CDA with pullup */
+							 AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PC11 periph A MCI2_DA0 with pullup */
 					};
 					pinctrl_mmc2_dat1_3: mmc2_dat1_3 {
 						atmel,pins =
-							<2 12 0x1 0x0	/* PC12 periph A MCI2_DA1 with pullup, conflicts with TIOA1 */
-							 2 13 0x1 0x0	/* PC13 periph A MCI2_DA2 with pullup, conflicts with TIOB1 */
-							 2 14 0x1 0x0>;	/* PC14 periph A MCI2_DA3 with pullup, conflicts with TCLK1 */
+							<AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC12 periph A MCI2_DA1 with pullup, conflicts with TIOA1 */
+							 AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC13 periph A MCI2_DA2 with pullup, conflicts with TIOB1 */
+							 AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PC14 periph A MCI2_DA3 with pullup, conflicts with TCLK1 */
 					};
 				};
 
 				nand0 {
 					pinctrl_nand0_ale_cle: nand0_ale_cle-0 {
 						atmel,pins =
-							<4 21 0x1 0x1	/* PE21 periph A with pullup */
-							 4 22 0x1 0x1>;	/* PE22 periph A with pullup */
+							<AT91_PIOE 21 AT91_PERIPH_A AT91_PINCTRL_PULL_UP	/* PE21 periph A with pullup */
+							 AT91_PIOE 22 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PE22 periph A with pullup */
 					};
 				};
 
-				pioA: gpio@fffff200 {
-					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
-					reg = <0xfffff200 0x100>;
-					interrupts = <6 4 1>;
-					#gpio-cells = <2>;
-					gpio-controller;
-					interrupt-controller;
-					#interrupt-cells = <2>;
-				};
-
-				pioB: gpio@fffff400 {
-					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
-					reg = <0xfffff400 0x100>;
-					interrupts = <7 4 1>;
-					#gpio-cells = <2>;
-					gpio-controller;
-					interrupt-controller;
-					#interrupt-cells = <2>;
-				};
-
-				pioC: gpio@fffff600 {
-					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
-					reg = <0xfffff600 0x100>;
-					interrupts = <8 4 1>;
-					#gpio-cells = <2>;
-					gpio-controller;
-					interrupt-controller;
-					#interrupt-cells = <2>;
-				};
-
-				pioD: gpio@fffff800 {
-					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
-					reg = <0xfffff800 0x100>;
-					interrupts = <9 4 1>;
-					#gpio-cells = <2>;
-					gpio-controller;
-					interrupt-controller;
-					#interrupt-cells = <2>;
-				};
-
-				pioE: gpio@fffffa00 {
-					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
-					reg = <0xfffffa00 0x100>;
-					interrupts = <10 4 1>;
-					#gpio-cells = <2>;
-					gpio-controller;
-					interrupt-controller;
-					#interrupt-cells = <2>;
-				};
-
 				spi0 {
 					pinctrl_spi0: spi0-0 {
 						atmel,pins =
-							<3 10 0x1 0x0	/* PD10 periph A SPI0_MISO pin */
-							 3 11 0x1 0x0	/* PD11 periph A SPI0_MOSI pin */
-							 3 12 0x1 0x0	/* PD12 periph A SPI0_SPCK pin */
-							 3 13 0x0 0x0>;	/* PD13 GPIO SPI0_NPCS0 pin */
+							<AT91_PIOD 10 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD10 periph A SPI0_MISO pin */
+							 AT91_PIOD 11 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD11 periph A SPI0_MOSI pin */
+							 AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD12 periph A SPI0_SPCK pin */
 					};
 				};
 
 				spi1 {
 					pinctrl_spi1: spi1-0 {
 						atmel,pins =
-							<2 22 0x1 0x0	/* PC22 periph A SPI1_MISO pin */
-							 2 23 0x1 0x0	/* PC23 periph A SPI1_MOSI pin */
-							 2 24 0x1 0x0	/* PC24 periph A SPI1_SPCK pin */
-							 2 25 0x0 0x0>;	/* PC25 GPIO SPI1_NPCS0 pin */
+							<AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC22 periph A SPI1_MISO pin */
+							 AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC23 periph A SPI1_MOSI pin */
+							 AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PC24 periph A SPI1_SPCK pin */
 					};
 				};
 
 				ssc0 {
 					pinctrl_ssc0_tx: ssc0_tx {
 						atmel,pins =
-							<2 16 0x1 0x0	/* PC16 periph A TK0 */
-							 2 17 0x1 0x0	/* PC17 periph A TF0 */
-							 2 18 0x1 0x0>;	/* PC18 periph A TD0 */
+							<AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC16 periph A TK0 */
+							 AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC17 periph A TF0 */
+							 AT91_PIOC 18 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PC18 periph A TD0 */
 					};
 
 					pinctrl_ssc0_rx: ssc0_rx {
 						atmel,pins =
-							<2 19 0x1 0x0	/* PC19 periph A RK0 */
-							 2 20 0x1 0x0	/* PC20 periph A RF0 */
-							 2 21 0x1 0x0>;	/* PC21 periph A RD0 */
+							<AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC19 periph A RK0 */
+							 AT91_PIOC 20 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC20 periph A RF0 */
+							 AT91_PIOC 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PC21 periph A RD0 */
 					};
 				};
 
 				ssc1 {
 					pinctrl_ssc1_tx: ssc1_tx {
 						atmel,pins =
-							<1 2 0x2 0x0	/* PB2 periph B TK1, conflicts with GTX2 */
-							 1 3 0x2 0x0	/* PB3 periph B TF1, conflicts with GTX3 */
-							 1 6 0x2 0x0>;	/* PB6 periph B TD1, conflicts with TD1 */
+							<AT91_PIOB 2 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB2 periph B TK1, conflicts with GTX2 */
+							 AT91_PIOB 3 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB3 periph B TF1, conflicts with GTX3 */
+							 AT91_PIOB 6 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB6 periph B TD1, conflicts with TD1 */
 					};
 
 					pinctrl_ssc1_rx: ssc1_rx {
 						atmel,pins =
-							<1 7 0x2 0x0	/* PB7 periph B RK1, conflicts with EREFCK */
-							 1 10 0x2 0x0	/* PB10 periph B RF1, conflicts with GTXER */
-							 1 11 0x2 0x0>;	/* PB11 periph B RD1, conflicts with GRXCK */
+							<AT91_PIOB 7 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB7 periph B RK1, conflicts with EREFCK */
+							 AT91_PIOB 10 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PB10 periph B RF1, conflicts with GTXER */
+							 AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PB11 periph B RD1, conflicts with GRXCK */
 					};
 				};
 
 				uart0 {
 					pinctrl_uart0: uart0-0 {
 						atmel,pins =
-							<2 29 0x1 0x0	/* PC29 periph A, conflicts with PWMFI2, ISI_D8 */
-							 2 30 0x1 0x1>;	/* PC30 periph A with pullup, conflicts with ISI_PCK */
+							<AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PC29 periph A, conflicts with PWMFI2, ISI_D8 */
+							 AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PC30 periph A with pullup, conflicts with ISI_PCK */
 					};
 				};
 
 				uart1 {
 					pinctrl_uart1: uart1-0 {
 						atmel,pins =
-							<0 30 0x2 0x0	/* PA30 periph B, conflicts with TWD0, ISI_VSYNC */
-							 0 31 0x2 0x1>;	/* PA31 periph B with pullup, conflicts with TWCK0, ISI_HSYNC */
+							<AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PA30 periph B, conflicts with TWD0, ISI_VSYNC */
+							 AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PA31 periph B with pullup, conflicts with TWCK0, ISI_HSYNC */
 					};
 				};
 
 				usart0 {
 					pinctrl_usart0: usart0-0 {
 						atmel,pins =
-							<3 17 0x1 0x0	/* PD17 periph A */
-							 3 18 0x1 0x1>;	/* PD18 periph A with pullup */
+							<AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD17 periph A */
+							 AT91_PIOD 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PD18 periph A with pullup */
 					};
 
 					pinctrl_usart0_rts_cts: usart0_rts_cts-0 {
 						atmel,pins =
-							<3 15 0x1 0x0	/* PD15 periph A, conflicts with SPI0_NPCS2, CANTX0 */
-							 3 16 0x1 0x0>;	/* PD16 periph A, conflicts with SPI0_NPCS3, PWMFI3 */
+							<AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PD15 periph A, conflicts with SPI0_NPCS2, CANTX0 */
+							 AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PD16 periph A, conflicts with SPI0_NPCS3, PWMFI3 */
 					};
 				};
 
 				usart1 {
 					pinctrl_usart1: usart1-0 {
 						atmel,pins =
-							<1 28 0x1 0x0	/* PB28 periph A */
-							 1 29 0x1 0x1>;	/* PB29 periph A with pullup */
+							<AT91_PIOB 28 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB28 periph A */
+							 AT91_PIOB 29 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;	/* PB29 periph A with pullup */
 					};
 
 					pinctrl_usart1_rts_cts: usart1_rts_cts-0 {
 						atmel,pins =
-							<1 26 0x1 0x0	/* PB26 periph A, conflicts with GRX7 */
-							 1 27 0x1 0x0>;	/* PB27 periph A, conflicts with G125CKO */
+							<AT91_PIOB 26 AT91_PERIPH_A AT91_PINCTRL_NONE	/* PB26 periph A, conflicts with GRX7 */
+							 AT91_PIOB 27 AT91_PERIPH_A AT91_PINCTRL_NONE>;	/* PB27 periph A, conflicts with G125CKO */
 					};
 				};
 
 				usart2 {
 					pinctrl_usart2: usart2-0 {
 						atmel,pins =
-							<4 25 0x2 0x0	/* PE25 periph B, conflicts with A25 */
-							 4 26 0x2 0x1>;	/* PE26 periph B with pullup, conflicts NCS0 */
+							<AT91_PIOE 25 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PE25 periph B, conflicts with A25 */
+							 AT91_PIOE 26 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PE26 periph B with pullup, conflicts NCS0 */
 					};
 
 					pinctrl_usart2_rts_cts: usart2_rts_cts-0 {
 						atmel,pins =
-							<4 23 0x2 0x0	/* PE23 periph B, conflicts with A23 */
-							 4 24 0x2 0x0>;	/* PE24 periph B, conflicts with A24 */
+							<AT91_PIOE 23 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PE23 periph B, conflicts with A23 */
+							 AT91_PIOE 24 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PE24 periph B, conflicts with A24 */
 					};
 				};
 
 				usart3 {
 					pinctrl_usart3: usart3-0 {
 						atmel,pins =
-							<4 18 0x2 0x0	/* PE18 periph B, conflicts with A18 */
-							 4 19 0x2 0x1>;	/* PE19 periph B with pullup, conflicts with A19 */
+							<AT91_PIOE 18 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PE18 periph B, conflicts with A18 */
+							 AT91_PIOE 19 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;	/* PE19 periph B with pullup, conflicts with A19 */
 					};
 
 					pinctrl_usart3_rts_cts: usart3_rts_cts-0 {
 						atmel,pins =
-							<4 16 0x2 0x0	/* PE16 periph B, conflicts with A16 */
-							 4 17 0x2 0x0>;	/* PE17 periph B, conflicts with A17 */
+							<AT91_PIOE 16 AT91_PERIPH_B AT91_PINCTRL_NONE	/* PE16 periph B, conflicts with A16 */
+							 AT91_PIOE 17 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PE17 periph B, conflicts with A17 */
 					};
 				};
+
+
+				pioA: gpio@fffff200 {
+					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+					reg = <0xfffff200 0x100>;
+					interrupts = <6 IRQ_TYPE_LEVEL_HIGH 1>;
+					#gpio-cells = <2>;
+					gpio-controller;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
+
+				pioB: gpio@fffff400 {
+					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+					reg = <0xfffff400 0x100>;
+					interrupts = <7 IRQ_TYPE_LEVEL_HIGH 1>;
+					#gpio-cells = <2>;
+					gpio-controller;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
+
+				pioC: gpio@fffff600 {
+					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+					reg = <0xfffff600 0x100>;
+					interrupts = <8 IRQ_TYPE_LEVEL_HIGH 1>;
+					#gpio-cells = <2>;
+					gpio-controller;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
+
+				pioD: gpio@fffff800 {
+					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+					reg = <0xfffff800 0x100>;
+					interrupts = <9 IRQ_TYPE_LEVEL_HIGH 1>;
+					#gpio-cells = <2>;
+					gpio-controller;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
+
+				pioE: gpio@fffffa00 {
+					compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+					reg = <0xfffffa00 0x100>;
+					interrupts = <10 IRQ_TYPE_LEVEL_HIGH 1>;
+					#gpio-cells = <2>;
+					gpio-controller;
+					interrupt-controller;
+					#interrupt-cells = <2>;
+				};
 			};
 
 			pmc: pmc@fffffc00 {
@@ -867,7 +880,7 @@
 			pit: timer@fffffe30 {
 				compatible = "atmel,at91sam9260-pit";
 				reg = <0xfffffe30 0xf>;
-				interrupts = <3 4 5>;
+				interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>;
 			};
 
 			watchdog@fffffe40 {
@@ -879,7 +892,7 @@
 			rtc@fffffeb0 {
 				compatible = "atmel,at91rm9200-rtc";
 				reg = <0xfffffeb0 0x30>;
-				interrupts = <1 4 7>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 			};
 		};
 
@@ -889,7 +902,7 @@
 			compatible = "atmel,at91sam9rl-udc";
 			reg = <0x00500000 0x100000
 			       0xf8030000 0x4000>;
-			interrupts = <33 4 2>;
+			interrupts = <33 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 
 			ep0 {
@@ -1001,14 +1014,14 @@
 		usb1: ohci@00600000 {
 			compatible = "atmel,at91rm9200-ohci", "usb-ohci";
 			reg = <0x00600000 0x100000>;
-			interrupts = <32 4 2>;
+			interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 
 		usb2: ehci@00700000 {
 			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
 			reg = <0x00700000 0x100000>;
-			interrupts = <32 4 2>;
+			interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>;
 			status = "disabled";
 		};
 
@@ -1024,7 +1037,7 @@
 				0xffffc000 0x00000070	/* NFC HSMC regs */
 				0x00200000 0x00100000	/* NFC SRAM banks */
 				>;
-			interrupts = <5 4 6>;
+			interrupts = <5 IRQ_TYPE_LEVEL_HIGH 6>;
 			atmel,nand-addr-offset = <21>;
 			atmel,nand-cmd-offset = <22>;
 			pinctrl-names = "default";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d3xcm.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d3xcm.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d3xcm.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d3xcm.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  *
  * Licensed under GPLv2 or later.
  */
-/include/ "sama5d3.dtsi"
+#include "sama5d3.dtsi"
 
 / {
 	compatible = "atmel,samad3xcm", "atmel,sama5d3", "atmel,sama5";
@@ -89,7 +89,7 @@
 
 		d2 {
 			label = "d2";
-			gpios = <&pioE 25 1>;	/* PE25, conflicts with A25, RXD2 */
+			gpios = <&pioE 25 GPIO_ACTIVE_LOW>;	/* PE25, conflicts with A25, RXD2 */
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d3xdm.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d3xdm.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d3xdm.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d3xdm.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,7 @@
 				board {
 					pinctrl_qt1070_irq: qt1070_irq {
 						atmel,pins =
-							<4 31 0x0 0x5>; /* PE31 GPIO with pull up deglith */
+							<AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE31 GPIO with pull up deglith */
 					};
 				};
 			};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d3xmb.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d3xmb.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sama5d3xmb.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sama5d3xmb.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  *
  * Licensed under GPLv2 or later.
  */
-/include/ "sama5d3xcm.dtsi"
+#include "sama5d3xcm.dtsi"
 
 / {
 	compatible = "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d3", "atmel,sama5";
@@ -20,7 +20,7 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioD 17 0>;
+					cd-gpios = <&pioD 17 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -62,7 +62,7 @@
 				slot@0 {
 					reg = <0>;
 					bus-width = <4>;
-					cd-gpios = <&pioD 18 0>;
+					cd-gpios = <&pioD 18 GPIO_ACTIVE_HIGH>;
 				};
 			};
 
@@ -87,32 +87,32 @@
 				board {
 					pinctrl_mmc0_cd: mmc0_cd {
 						atmel,pins =
-							<3 17 0x0 0x5>; /* PD17 GPIO with pullup deglitch */
+							<AT91_PIOD 17 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD17 GPIO with pullup deglitch */
 					};
 
 					pinctrl_mmc1_cd: mmc1_cd {
 						atmel,pins =
-							<3 18 0x0 0x5>; /* PD18 GPIO with pullup deglitch */
+							<AT91_PIOD 18 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PD18 GPIO with pullup deglitch */
 					};
 
 					pinctrl_pck0_as_audio_mck: pck0_as_audio_mck {
 						atmel,pins =
-							<3 30 0x2 0x0>;	/* PD30 periph B */
+							<AT91_PIOD 30 AT91_PERIPH_B AT91_PINCTRL_NONE>;	/* PD30 periph B */
 					};
 
 					pinctrl_isi_reset: isi_reset-0 {
 						atmel,pins =
-							<4 24 0x0 0x0>;   /* PE24 gpio */
+							<AT91_PIOE 24 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;   /* PE24 gpio */
 					};
 
 					pinctrl_isi_power: isi_power-0 {
 						atmel,pins =
-							<4 29 0x0 0x0>; /* PE29 gpio */
+							<AT91_PIOE 29 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; /* PE29 gpio */
 					};
 
 					pinctrl_usba_vbus: usba_vbus {
 						atmel,pins =
-							<3 29 0x0 0x4>; /* PD29 GPIO with deglitch */
+							<AT91_PIOD 29 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PD29 GPIO with deglitch */
 					};
 				};
 			};
@@ -127,7 +127,7 @@
 		};
 
 		usb0: gadget@00500000 {
-			atmel,vbus-gpio = <&pioD 29 0>;
+			atmel,vbus-gpio = <&pioD 29 GPIO_ACTIVE_HIGH>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_usba_vbus>;
 			status = "okay";
@@ -135,9 +135,9 @@
 
 		usb1: ohci@00600000 {
 			num-ports = <3>;
-			atmel,vbus-gpio = <&pioD 25 0
-					   &pioD 26 1
-					   &pioD 27 1
+			atmel,vbus-gpio = <&pioD 25 GPIO_ACTIVE_HIGH
+					   &pioD 26 GPIO_ACTIVE_LOW
+					   &pioD 27 GPIO_ACTIVE_LOW
 					  >;
 			status = "okay";
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sh7372.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sh7372.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sh7372.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sh7372.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -14,8 +14,13 @@
 	compatible = "renesas,sh7372";
 
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
 		cpu@0 {
 			compatible = "arm,cortex-a8";
+			device_type = "cpu";
+			reg = <0x0>;
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sh73a0.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sh73a0.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sh73a0.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sh73a0.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -119,7 +119,7 @@
 			      0 32 0x4>;
 	};
 
-	i2c0: i2c@0xe6820000 {
+	i2c0: i2c@e6820000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "renesas,rmobile-iic";
@@ -131,7 +131,7 @@
 			      0 170 0x4>;
 	};
 
-	i2c1: i2c@0xe6822000 {
+	i2c1: i2c@e6822000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "renesas,rmobile-iic";
@@ -143,7 +143,7 @@
 			      0 54 0x4>;
 	};
 
-	i2c2: i2c@0xe6824000 {
+	i2c2: i2c@e6824000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "renesas,rmobile-iic";
@@ -155,7 +155,7 @@
 			      0 174 0x4>;
 	};
 
-	i2c3: i2c@0xe6826000 {
+	i2c3: i2c@e6826000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "renesas,rmobile-iic";
@@ -167,7 +167,7 @@
 			      0 186 0x4>;
 	};
 
-	i2c4: i2c@0xe6828000 {
+	i2c4: i2c@e6828000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "renesas,rmobile-iic";
@@ -179,7 +179,7 @@
 			      0 190 0x4>;
 	};
 
-	mmcif: mmcif@0x10010000 {
+	mmcif: mmcif@e6bd0000 {
 		compatible = "renesas,sh-mmcif";
 		reg = <0xe6bd0000 0x100>;
 		interrupt-parent = <&gic>;
@@ -189,7 +189,7 @@
 		status = "disabled";
 	};
 
-	sdhi0: sdhi@0xee100000 {
+	sdhi0: sdhi@ee100000 {
 		compatible = "renesas,r8a7740-sdhi";
 		reg = <0xee100000 0x100>;
 		interrupt-parent = <&gic>;
@@ -201,7 +201,7 @@
 	};
 
 	/* SDHI1 and SDHI2 have no CD pins, no need for CD IRQ */
-	sdhi1: sdhi@0xee120000 {
+	sdhi1: sdhi@ee120000 {
 		compatible = "renesas,r8a7740-sdhi";
 		reg = <0xee120000 0x100>;
 		interrupt-parent = <&gic>;
@@ -212,7 +212,7 @@
 		status = "disabled";
 	};
 
-	sdhi2: sdhi@0xee140000 {
+	sdhi2: sdhi@ee140000 {
 		compatible = "renesas,r8a7740-sdhi";
 		reg = <0xee140000 0x100>;
 		interrupt-parent = <&gic>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,19 @@
 	model = "KZM-A9-GT";
 	compatible = "renesas,kzm9g-reference", "renesas,sh73a0";
 
+	cpus {
+		cpu@0 {
+			cpu0-supply = <&vdd_dvfs>;
+			operating-points = <
+				/* kHz  uV */
+				1196000 1315000
+				 598000 1175000
+				 398667 1065000
+			>;
+			voltage-tolerance = <1>; /* 1% */
+		};
+	};
+
 	chosen {
 		bootargs = "console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel earlyprintk=sh-sci.4,115200";
 	};
@@ -59,6 +72,79 @@
 	};
 };
 
+&i2c0 {
+	as3711@40 {
+		compatible = "ams,as3711";
+		reg = <0x40>;
+
+		regulators {
+			vdd_dvfs: sd1 {
+				regulator-name = "1.315V CPU";
+				regulator-min-microvolt = <1050000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+			sd2 {
+				regulator-name = "1.8V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+			sd4 {
+				regulator-name = "1.215V";
+				regulator-min-microvolt = <1215000>;
+				regulator-max-microvolt = <1235000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+			ldo2 {
+				regulator-name = "2.8V CPU";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+			ldo3 {
+				regulator-name = "3.0V CPU";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+			ldo4 {
+				regulator-name = "2.8V";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+			ldo5 {
+				regulator-name = "2.8V #2";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+			ldo7 {
+				regulator-name = "1.15V CPU";
+				regulator-min-microvolt = <1150000>;
+				regulator-max-microvolt = <1150000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+			ldo8 {
+				regulator-name = "1.15V CPU #2";
+				regulator-min-microvolt = <1150000>;
+				regulator-max-microvolt = <1150000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
 &mmcif {
 	bus-width = <8>;
 	vmmc-supply = <&reg_1p8v>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/snowball.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/snowball.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/snowball.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/snowball.dts	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@
  */
 
 /dts-v1/;
-/include/ "dbx5x0.dtsi"
+#include "dbx5x0.dtsi"
 
 / {
 	model = "Calao Systems Snowball platform with device tree";
@@ -22,12 +22,13 @@
 
 	en_3v3_reg: en_3v3 {
 		compatible = "regulator-fixed";
-                regulator-name = "en-3v3-fixed-supply";
-                regulator-min-microvolt = <3300000>;
-                regulator-max-microvolt = <3300000>;
-                gpios = <&gpio0 26  0x4>; // 26
-                startup-delay-us = <5000>;
-                enable-active-high;
+		regulator-name = "en-3v3-fixed-supply";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		/* AB8500 GPIOs start from 1 - offset 25 is GPIO26. */
+		gpio = <&ab8500_gpio 25 0x4>;
+		startup-delay-us = <5000>;
+		enable-active-high;
 	};
 
 	gpio_keys {
@@ -82,7 +83,7 @@
 		};
 	};
 
-	soc-u9500 {
+	soc {
 
 		sound {
 			compatible = "stericsson,snd-soc-mop500";
@@ -99,40 +100,13 @@
 			status = "okay";
 		};
 
-		prcmu@80157000 {
-			thermal@801573c0 {
-				num-trips = <4>;
-
-				trip0-temp = <70000>;
-				trip0-type = "active";
-				trip0-cdev-num = <1>;
-				trip0-cdev-name0 = "thermal-cpufreq-0";
-
-				trip1-temp = <75000>;
-				trip1-type = "active";
-				trip1-cdev-num = <1>;
-				trip1-cdev-name0 = "thermal-cpufreq-0";
-
-				trip2-temp = <80000>;
-				trip2-type = "active";
-				trip2-cdev-num = <1>;
-				trip2-cdev-name0 = "thermal-cpufreq-0";
-
-				trip3-temp = <85000>;
-				trip3-type = "critical";
-				trip3-cdev-num = <0>;
-
-				status = "okay";
-			 };
-		};
-
 		external-bus@50000000 {
 			status = "okay";
 
 			ethernet@0 {
 				compatible = "smsc,lan9115";
 				reg = <0 0x10000>;
-				interrupts = <12 0x1>;
+				interrupts = <12 IRQ_TYPE_EDGE_RISING>;
 				interrupt-parent = <&gpio4>;
 				vdd33a-supply = <&en_3v3_reg>;
 				vddvario-supply = <&db8500_vape_reg>;
@@ -146,13 +120,21 @@
 			};
 		};
 
+		vmmci: regulator-gpio {
+			gpios = <&gpio6 25 0x4>;
+			enable-gpio = <&gpio7 4 0x4>;
+
+			status = "okay";
+		};
+
 		// External Micro SD slot
 		sdi0_per1@80126000 {
 			arm,primecell-periphid = <0x10480180>;
-			max-frequency = <50000000>;
+			max-frequency = <100000000>;
 			bus-width = <4>;
 			mmc-cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
+			vqmmc-supply = <&vmmci>;
 
 			cd-gpios  = <&gpio6 26 0x4>; // 218
 			cd-inverted;
@@ -163,7 +145,7 @@
 		// On-board eMMC
 		sdi4_per2@80114000 {
 			arm,primecell-periphid = <0x10480180>;
-		        max-frequency = <50000000>;
+		        max-frequency = <100000000>;
 			bus-width = <8>;
 			mmc-cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux2_reg>;
@@ -197,15 +179,15 @@
 		};
 
 		i2c@80128000 {
-			lp5521@0x33 {
+			lp5521@33 {
 				// compatible = "lp5521";
 				reg = <0x33>;
 			};
-			lp5521@0x34 {
+			lp5521@34 {
 				// compatible = "lp5521";
 				reg = <0x34>;
 			};
-			bh1780@0x29 {
+			bh1780@29 {
 				// compatible = "rohm,bh1780gli";
 				reg = <0x33>;
 			};
@@ -298,6 +280,31 @@
 				};
 			};
 
+			thermal@801573c0 {
+				num-trips = <4>;
+
+				trip0-temp = <70000>;
+				trip0-type = "active";
+				trip0-cdev-num = <1>;
+				trip0-cdev-name0 = "thermal-cpufreq-0";
+
+				trip1-temp = <75000>;
+				trip1-type = "active";
+				trip1-cdev-num = <1>;
+				trip1-cdev-name0 = "thermal-cpufreq-0";
+
+				trip2-temp = <80000>;
+				trip2-type = "active";
+				trip2-cdev-num = <1>;
+				trip2-cdev-name0 = "thermal-cpufreq-0";
+
+				trip3-temp = <85000>;
+				trip3-type = "critical";
+				trip3-cdev-num = <0>;
+
+				status = "okay";
+			};
+
 			ab8500 {
 				ab8500-gpio {
 					compatible = "stericsson,ab8500-gpio";
@@ -316,7 +323,7 @@
 						regulator-name = "V-MMC-SD";
 					};
 
-					ab8500_ldo_initcore_reg: ab8500_ldo_initcore {
+					ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
 						regulator-name = "V-INTCORE";
 					};
 
@@ -336,7 +343,7 @@
 						regulator-name = "V-AMIC1";
 					};
 
-					ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 {
+					ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
 						regulator-name = "V-AMIC2";
 					};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/socfpga_cyclone5.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/socfpga_cyclone5.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/socfpga_cyclone5.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/socfpga_cyclone5.dts	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,13 @@
 		reg = <0x0 0x40000000>; /* 1GB */
 	};
 
+	aliases {
+		/* this allow the ethaddr uboot environmnet variable contents
+		 * to be added to the gmac1 device tree blob.
+		 */
+		ethernet0 = &gmac1;
+	};
+
 	soc {
 		clkmgr@ffd04000 {
 			clocks {
@@ -41,6 +48,12 @@
 			};
 		};
 
+		ethernet@ff702000 {
+			phy-mode = "rgmii";
+			phy-addr = <0xffffffff>; /* probe for phy addr */
+			status = "okay";
+		};
+
 		timer0@ffc08000 {
 			clock-frequency = <100000000>;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/socfpga.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/socfpga.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/socfpga.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/socfpga.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,7 @@
 
 	aliases {
 		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
 		serial0 = &uart0;
 		serial1 = &uart1;
 		timer0 = &timer0;
@@ -94,6 +95,12 @@
 						compatible = "fixed-clock";
 					};
 
+					f2s_periph_ref_clk: f2s_periph_ref_clk {
+						#clock-cells = <0>;
+						compatible = "fixed-clock";
+						clock-frequency = <10000000>;
+					};
+
 					main_pll: main_pll {
 						#address-cells = <1>;
 						#size-cells = <0>;
@@ -235,16 +242,222 @@
 							reg = <0xD4>;
 						};
 					};
+
+				mpu_periph_clk: mpu_periph_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&mpuclk>;
+					fixed-divider = <4>;
+					};
+
+				mpu_l2_ram_clk: mpu_l2_ram_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&mpuclk>;
+					fixed-divider = <2>;
+					};
+
+				l4_main_clk: l4_main_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&mainclk>;
+					clk-gate = <0x60 0>;
+					};
+
+				l3_main_clk: l3_main_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&mainclk>;
+					};
+
+				l3_mp_clk: l3_mp_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&mainclk>;
+					div-reg = <0x64 0 2>;
+					clk-gate = <0x60 1>;
+					};
+
+				l3_sp_clk: l3_sp_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&mainclk>;
+					div-reg = <0x64 2 2>;
+				};
+
+				l4_mp_clk: l4_mp_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&mainclk>, <&per_base_clk>;
+					div-reg = <0x64 4 3>;
+					clk-gate = <0x60 2>;
+					};
+
+				l4_sp_clk: l4_sp_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&mainclk>, <&per_base_clk>;
+					div-reg = <0x64 7 3>;
+					clk-gate = <0x60 3>;
+					};
+
+				dbg_at_clk: dbg_at_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&dbg_base_clk>;
+					div-reg = <0x68 0 2>;
+					clk-gate = <0x60 4>;
+					};
+
+				dbg_clk: dbg_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&dbg_base_clk>;
+					div-reg = <0x68 2 2>;
+					clk-gate = <0x60 5>;
+					};
+
+				dbg_trace_clk: dbg_trace_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&dbg_base_clk>;
+					div-reg = <0x6C 0 3>;
+					clk-gate = <0x60 6>;
+					};
+
+				dbg_timer_clk: dbg_timer_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&dbg_base_clk>;
+					clk-gate = <0x60 7>;
+					};
+
+				cfg_clk: cfg_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&cfg_s2f_usr0_clk>;
+					clk-gate = <0x60 8>;
+					};
+
+				s2f_user0_clk: s2f_user0_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&cfg_s2f_usr0_clk>;
+					clk-gate = <0x60 9>;
+					};
+
+				emac_0_clk: emac_0_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&emac0_clk>;
+					clk-gate = <0xa0 0>;
+					};
+
+				emac_1_clk: emac_1_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&emac1_clk>;
+					clk-gate = <0xa0 1>;
+					};
+
+				usb_mp_clk: usb_mp_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&per_base_clk>;
+					clk-gate = <0xa0 2>;
+					div-reg = <0xa4 0 3>;
+					};
+
+				spi_m_clk: spi_m_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&per_base_clk>;
+					clk-gate = <0xa0 3>;
+					div-reg = <0xa4 3 3>;
+					};
+
+				can0_clk: can0_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&per_base_clk>;
+					clk-gate = <0xa0 4>;
+					div-reg = <0xa4 6 3>;
+					};
+
+				can1_clk: can1_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&per_base_clk>;
+					clk-gate = <0xa0 5>;
+					div-reg = <0xa4 9 3>;
+					};
+
+				gpio_db_clk: gpio_db_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&per_base_clk>;
+					clk-gate = <0xa0 6>;
+					div-reg = <0xa8 0 24>;
+					};
+
+				s2f_user1_clk: s2f_user1_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&s2f_usr1_clk>;
+					clk-gate = <0xa0 7>;
+					};
+
+				sdmmc_clk: sdmmc_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+					clk-gate = <0xa0 8>;
+					};
+
+				nand_x_clk: nand_x_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+					clk-gate = <0xa0 9>;
+					};
+
+				nand_clk: nand_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&f2s_periph_ref_clk>, <&main_nand_sdmmc_clk>, <&per_nand_mmc_clk>;
+					clk-gate = <0xa0 10>;
+					fixed-divider = <4>;
+					};
+
+				qspi_clk: qspi_clk {
+					#clock-cells = <0>;
+					compatible = "altr,socfpga-gate-clk";
+					clocks = <&f2s_periph_ref_clk>, <&main_qspi_clk>, <&per_qspi_clk>;
+					clk-gate = <0xa0 11>;
+					};
 				};
 			};
 
-		gmac0: stmmac@ff700000 {
+		gmac0: ethernet@ff700000 {
 			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
 			reg = <0xff700000 0x2000>;
 			interrupts = <0 115 4>;
 			interrupt-names = "macirq";
 			mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
-			phy-mode = "gmii";
+			clocks = <&emac0_clk>;
+			clock-names = "stmmaceth";
+			status = "disabled";
+		};
+
+		gmac1: ethernet@ff702000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
+			reg = <0xff702000 0x2000>;
+			interrupts = <0 120 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
+			clocks = <&emac1_clk>;
+			clock-names = "stmmaceth";
+			status = "disabled";
 		};
 
 		L2: l2-cache@fffef000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/socfpga_vt.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/socfpga_vt.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/socfpga_vt.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/socfpga_vt.dts	2013-08-25 20:43:22.000000000 -0400
@@ -41,6 +41,11 @@
 			};
 		};
 
+		ethernet@ff700000 {
+			phy-mode = "gmii";
+			status = "okay";
+		};
+
 		timer0@ffc08000 {
 			clock-frequency = <7000000>;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/spear13xx.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/spear13xx.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/spear13xx.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/spear13xx.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -22,12 +22,14 @@
 
 		cpu@0 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			reg = <0>;
 			next-level-cache = <&L2>;
 		};
 
 		cpu@1 {
 			compatible = "arm,cortex-a9";
+			device_type = "cpu";
 			reg = <1>;
 			next-level-cache = <&L2>;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/spear3xx.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/spear3xx.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/spear3xx.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/spear3xx.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -17,8 +17,12 @@
 	interrupt-parent = <&vic>;
 
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/spear600.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/spear600.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/spear600.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/spear600.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -15,8 +15,12 @@
 	compatible = "st,spear600";
 
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			compatible = "arm,arm926ej-s";
+			device_type = "cpu";
 		};
 	};
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/ste-nomadik-s8815.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ste-nomadik-s8815.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/ste-nomadik-s8815.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ste-nomadik-s8815.dts	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,49 @@
 		};
 	};
 
+	src@101e0000 {
+		/* These chrystal drivers are not used on this board */
+		disable-sxtalo;
+		disable-mxtalo;
+	};
+
+	pinctrl {
+		/* Hog CD pins */
+		pinctrl-names = "default";
+		pinctrl-0 = <&cd_default_mode>;
+
+		mmcsd-cd {
+			cd_default_mode: cd_default {
+				cd_default_cfg1 {
+					/* CD input GPIO */
+					ste,pins = "GPIO111_H21";
+					ste,input = <0>;
+				};
+				cd_default_cfg2 {
+					/* CD GPIO biasing */
+					ste,pins = "GPIO112_J21";
+					ste,output = <0>;
+				};
+			};
+		};
+		user-led {
+			user_led_default_mode: user_led_default {
+				user_led_default_cfg {
+					ste,pins = "GPIO2_C5";
+					ste,output = <1>;
+				};
+			};
+		};
+		user-button {
+			user_button_default_mode: user_button_default {
+				user_button_default_cfg {
+					ste,pins = "GPIO3_A4";
+					ste,input = <0>;
+				};
+			};
+		};
+	};
+
 	/* Custom board node with GPIO pins to active etc */
 	usb-s8815 {
 		/* The S8815 is using this very GPIO pin for the SMSC91x IRQs */
@@ -33,4 +76,30 @@
 			gpios = <&gpio3 16 0x1>;
 		};
 	};
+
+	/* The user LED on the board is set up to be used for heartbeat */
+	leds {
+		compatible = "gpio-leds";
+		user-led {
+			label = "user_led";
+			gpios = <&gpio0 2 0x1>;
+			default-state = "off";
+			linux,default-trigger = "heartbeat";
+			pinctrl-names = "default";
+			pinctrl-0 = <&user_led_default_mode>;
+		};
+	};
+
+	/* User key mapped in as "escape" */
+	gpio-keys {
+		compatible = "gpio-keys";
+		user-button {
+			label = "user_button";
+			gpios = <&gpio0 3 0x1>;
+			linux,code = <1>; /* KEY_ESC */
+			gpio-key,wakeup;
+			pinctrl-names = "default";
+			pinctrl-0 = <&user_button_default_mode>;
+		};
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -21,18 +21,23 @@
 		cache-level = <2>;
 	};
 
-	mtu0 {
+	mtu0: mtu@101e2000 {
 		/* Nomadik system timer */
+		compatible = "st,nomadik-mtu";
 		reg = <0x101e2000 0x1000>;
 		interrupt-parent = <&vica>;
 		interrupts = <4>;
+		clocks = <&timclk>, <&pclk>;
+		clock-names = "timclk", "apb_pclk";
 	};
 
-	mtu1 {
+	mtu1: mtu@101e3000 {
 		/* Secondary timer */
 		reg = <0x101e3000 0x1000>;
 		interrupt-parent = <&vica>;
 		interrupts = <5>;
+		clocks = <&timclk>, <&pclk>;
+		clock-names = "timclk", "apb_pclk";
 	};
 
 	gpio0: gpio@101e4000 {
@@ -45,6 +50,7 @@
 		gpio-controller;
 		#gpio-cells = <2>;
 		gpio-bank = <0>;
+		clocks = <&pclk>;
 	};
 
 	gpio1: gpio@101e5000 {
@@ -57,6 +63,7 @@
 		gpio-controller;
 		#gpio-cells = <2>;
 		gpio-bank = <1>;
+		clocks = <&pclk>;
 	};
 
 	gpio2: gpio@101e6000 {
@@ -69,6 +76,7 @@
 		gpio-controller;
 		#gpio-cells = <2>;
 		gpio-bank = <2>;
+		clocks = <&pclk>;
 	};
 
 	gpio3: gpio@101e7000 {
@@ -81,10 +89,544 @@
 		gpio-controller;
 		#gpio-cells = <2>;
 		gpio-bank = <3>;
+		clocks = <&pclk>;
 	};
 
 	pinctrl {
-		compatible = "stericsson,nmk-pinctrl-stn8815";
+		compatible = "stericsson,stn8815-pinctrl";
+		/* Pin configurations */
+		uart0 {
+			uart0_default_mux: uart0_mux {
+				u0_default_mux {
+					ste,function = "u0";
+					ste,pins = "u0_a_1";
+				};
+			};
+		};
+		uart1 {
+			uart1_default_mux: uart1_mux {
+				u1_default_mux {
+					ste,function = "u1";
+					ste,pins = "u1_a_1";
+				};
+			};
+		};
+		mmcsd {
+			mmcsd_default_mux: mmcsd_mux {
+				mmcsd_default_mux {
+					ste,function = "mmcsd";
+					ste,pins = "mmcsd_a_1";
+				};
+			};
+			mmcsd_default_mode: mmcsd_default {
+				mmcsd_default_cfg1 {
+					/* MCCLK */
+					ste,pins = "GPIO8_B10";
+					ste,output = <0>;
+				};
+				mmcsd_default_cfg2 {
+					/* MCCMDDIR, MCDAT0DIR, MCDAT31DIR */
+					ste,pins = "GPIO10_C11", "GPIO15_A12",
+					"GPIO16_C13";
+					ste,output = <1>;
+				};
+				mmcsd_default_cfg3 {
+					/* MCCMD, MCDAT3-0, MCMSFBCLK */
+					ste,pins = "GPIO9_A10", "GPIO11_B11",
+					"GPIO12_A11", "GPIO13_C12",
+					"GPIO14_B12", "GPIO24_C15";
+					ste,input = <1>;
+				};
+			};
+		};
+		i2c0 {
+			i2c0_default_mode: i2c0_default {
+				i2c0_default_cfg {
+					ste,pins = "GPIO62_D3", "GPIO63_D2";
+					ste,input = <1>;
+				};
+			};
+		};
+		i2c1 {
+			i2c1_default_mode: i2c1_default {
+				i2c1_default_cfg {
+					ste,pins = "GPIO53_L4", "GPIO54_L3";
+					ste,input = <1>;
+				};
+			};
+		};
+		i2c2 {
+			i2c2_default_mode: i2c2_default {
+				i2c2_default_cfg {
+					ste,pins = "GPIO73_C21", "GPIO74_C20";
+					ste,input = <1>;
+				};
+			};
+		};
+	};
+
+	src: src@101e0000 {
+		compatible = "stericsson,nomadik-src";
+		reg = <0x101e0000 0x1000>;
+		disable-sxtalo;
+		disable-mxtalo;
+
+		/*
+		 * MXTAL "Main Chrystal" is a chrystal oscillator @19.2 MHz
+		 * that is parent of TIMCLK, PLL1 and PLL2
+		 */
+		mxtal: mxtal@19.2M {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <19200000>;
+		};
+
+		/*
+		 * The 2.4 MHz TIMCLK reference clock is active at
+		 * boot time, this is actually the MXTALCLK @19.2 MHz
+		 * divided by 8. This clock is used by the timers and
+		 * watchdog. See page 105 ff.
+		 */
+		timclk: timclk@2.4M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <8>;
+			clock-mult = <1>;
+			clocks = <&mxtal>;
+		};
+
+		/* PLL1 is locked to MXTALI and variable from 20.4 to 334 MHz */
+		pll1: pll1@0 {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-pll-clock";
+			pll-id = <1>;
+			clocks = <&mxtal>;
+		};
+
+		/* HCLK divides the PLL1 with 1,2,3 or 4 */
+		hclk: hclk@0 {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-hclk-clock";
+			clocks = <&pll1>;
+		};
+		/* The PCLK domain uses HCLK right off */
+		pclk: pclk@0 {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <1>;
+			clock-mult = <1>;
+			clocks = <&hclk>;
+		};
+
+		/* PLL2 is usually 864 MHz and divided into a few fixed rates */
+		pll2: pll2@0 {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-pll-clock";
+			pll-id = <2>;
+			clocks = <&mxtal>;
+		};
+		clk216: clk216@216M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <4>;
+			clock-mult = <1>;
+			clocks = <&pll2>;
+		};
+		clk108: clk108@108M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <2>;
+			clock-mult = <1>;
+			clocks = <&clk216>;
+		};
+		clk72: clk72@72M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			/* The data sheet does not say how this is derived */
+			clock-div = <12>;
+			clock-mult = <1>;
+			clocks = <&pll2>;
+		};
+		clk48: clk48@48M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			/* The data sheet does not say how this is derived */
+			clock-div = <18>;
+			clock-mult = <1>;
+			clocks = <&pll2>;
+		};
+		clk27: clk27@27M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <4>;
+			clock-mult = <1>;
+			clocks = <&clk108>;
+		};
+
+		/* This apparently exists as well */
+		ulpiclk: ulpiclk@60M {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <60000000>;
+		};
+
+		/*
+		 * IP AMBA bus clocks, driving the bus side of the
+		 * peripheral clocking, clock gates.
+		 */
+
+		hclkdma0: hclkdma0@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <0>;
+			clocks = <&hclk>;
+		};
+		hclksmc: hclksmc@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <1>;
+			clocks = <&hclk>;
+		};
+		hclksdram: hclksdram@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <2>;
+			clocks = <&hclk>;
+		};
+		hclkdma1: hclkdma1@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <3>;
+			clocks = <&hclk>;
+		};
+		hclkclcd: hclkclcd@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <4>;
+			clocks = <&hclk>;
+		};
+		pclkirda: pclkirda@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <5>;
+			clocks = <&pclk>;
+		};
+		pclkssp: pclkssp@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <6>;
+			clocks = <&pclk>;
+		};
+		pclkuart0: pclkuart0@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <7>;
+			clocks = <&pclk>;
+		};
+		pclksdi: pclksdi@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <8>;
+			clocks = <&pclk>;
+		};
+		pclki2c0: pclki2c0@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <9>;
+			clocks = <&pclk>;
+		};
+		pclki2c1: pclki2c1@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <10>;
+			clocks = <&pclk>;
+		};
+		pclkuart1: pclkuart1@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <11>;
+			clocks = <&pclk>;
+		};
+		pclkmsp0: pclkmsp0@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <12>;
+			clocks = <&pclk>;
+		};
+		hclkusb: hclkusb@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <13>;
+			clocks = <&hclk>;
+		};
+		hclkdif: hclkdif@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <14>;
+			clocks = <&hclk>;
+		};
+		hclksaa: hclksaa@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <15>;
+			clocks = <&hclk>;
+		};
+		hclksva: hclksva@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <16>;
+			clocks = <&hclk>;
+		};
+		pclkhsi: pclkhsi@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <17>;
+			clocks = <&pclk>;
+		};
+		pclkxti: pclkxti@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <18>;
+			clocks = <&pclk>;
+		};
+		pclkuart2: pclkuart2@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <19>;
+			clocks = <&pclk>;
+		};
+		pclkmsp1: pclkmsp1@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <20>;
+			clocks = <&pclk>;
+		};
+		pclkmsp2: pclkmsp2@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <21>;
+			clocks = <&pclk>;
+		};
+		pclkowm: pclkowm@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <22>;
+			clocks = <&pclk>;
+		};
+		hclkhpi: hclkhpi@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <23>;
+			clocks = <&hclk>;
+		};
+		pclkske: pclkske@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <24>;
+			clocks = <&pclk>;
+		};
+		pclkhsem: pclkhsem@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <25>;
+			clocks = <&pclk>;
+		};
+		hclk3d: hclk3d@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <26>;
+			clocks = <&hclk>;
+		};
+		hclkhash: hclkhash@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <27>;
+			clocks = <&hclk>;
+		};
+		hclkcryp: hclkcryp@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <28>;
+			clocks = <&hclk>;
+		};
+		pclkmshc: pclkmshc@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <29>;
+			clocks = <&pclk>;
+		};
+		hclkusbm: hclkusbm@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <30>;
+			clocks = <&hclk>;
+		};
+		hclkrng: hclkrng@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <31>;
+			clocks = <&hclk>;
+		};
+
+		/* IP kernel clocks */
+		clcdclk: clcdclk@0 {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <36>;
+			clocks = <&clk72 &clk48>;
+		};
+		irdaclk: irdaclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <37>;
+			clocks = <&clk48>;
+		};
+		sspiclk: sspiclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <38>;
+			clocks = <&clk48>;
+		};
+		uart0clk: uart0clk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <39>;
+			clocks = <&clk48>;
+		};
+		sdiclk: sdiclk@48M {
+			/* Also called MCCLK in some documents */
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <40>;
+			clocks = <&clk48>;
+		};
+		i2c0clk: i2c0clk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <41>;
+			clocks = <&clk48>;
+		};
+		i2c1clk: i2c1clk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <42>;
+			clocks = <&clk48>;
+		};
+		uart1clk: uart1clk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <43>;
+			clocks = <&clk48>;
+		};
+		mspclk0: mspclk0@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <44>;
+			clocks = <&clk48>;
+		};
+		usbclk: usbclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <45>;
+			clocks = <&clk48>; /* 48 MHz not ULPI */
+		};
+		difclk: difclk@72M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <46>;
+			clocks = <&clk72>;
+		};
+		ipi2cclk: ipi2cclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <47>;
+			clocks = <&clk48>; /* Guess */
+		};
+		ipbmcclk: ipbmcclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <48>;
+			clocks = <&clk48>; /* Guess */
+		};
+		hsiclkrx: hsiclkrx@216M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <49>;
+			clocks = <&clk216>;
+		};
+		hsiclktx: hsiclktx@108M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <50>;
+			clocks = <&clk108>;
+		};
+		uart2clk: uart2clk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <51>;
+			clocks = <&clk48>;
+		};
+		mspclk1: mspclk1@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <52>;
+			clocks = <&clk48>;
+		};
+		mspclk2: mspclk2@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <53>;
+			clocks = <&clk48>;
+		};
+		owmclk: owmclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <54>;
+			clocks = <&clk48>; /* Guess */
+		};
+		skeclk: skeclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <56>;
+			clocks = <&clk48>; /* Guess */
+		};
+		x3dclk: x3dclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <58>;
+			clocks = <&clk48>; /* Guess */
+		};
+		pclkmsp3: pclkmsp3@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <59>;
+			clocks = <&pclk>;
+		};
+		mspclk3: mspclk3@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <60>;
+			clocks = <&clk48>;
+		};
+		mshcclk: mshcclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <61>;
+			clocks = <&clk48>; /* Guess */
+		};
+		usbmclk: usbmclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <62>;
+			/* Stated as "48 MHz not ULPI clock" */
+			clocks = <&clk48>;
+		};
+		rngcclk: rngcclk@48M {
+			#clock-cells = <0>;
+			compatible = "st,nomadik-src-clock";
+			clock-id = <63>;
+			clocks = <&clk48>; /* Guess */
+		};
 	};
 
 	/* A NAND flash of 128 MiB */
@@ -97,6 +639,7 @@
 			<0x41000000 0x2000>,	/* NAND Base ADDR */
 			<0x40800000 0x2000>;	/* NAND Base CMD */
 		reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
+		clocks = <&hclksmc>;
 		status = "okay";
 
 		partition@0 {
@@ -144,6 +687,8 @@
 			<&gpio1 30 0>; /* scl */
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c0_default_mode>;
 
 		stw4811@2d {
 			   compatible = "st,stw4811";
@@ -158,6 +703,8 @@
 			<&gpio1 21 0>; /* scl */
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c1_default_mode>;
 
 		camera@2d {
 			   compatible = "st,camera";
@@ -180,6 +727,9 @@
 			<&gpio2 9 0>; /* scl */
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c2_default_mode>;
+
 		stw4811@2d {
 			   compatible = "st,stw4811-usb";
 			   reg = <0x2d>;
@@ -211,6 +761,10 @@
 			reg = <0x101fd000 0x1000>;
 			interrupt-parent = <&vica>;
 			interrupts = <12>;
+			clocks = <&uart0clk>, <&pclkuart0>;
+			clock-names = "uartclk", "apb_pclk";
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_default_mux>;
 		};
 
 		uart1: uart@101fb000 {
@@ -218,6 +772,10 @@
 			reg = <0x101fb000 0x1000>;
 			interrupt-parent = <&vica>;
 			interrupts = <17>;
+			clocks = <&uart1clk>, <&pclkuart1>;
+			clock-names = "uartclk", "apb_pclk";
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart1_default_mux>;
 		};
 
 		uart2: uart@101f2000 {
@@ -225,17 +783,23 @@
 			reg = <0x101f2000 0x1000>;
 			interrupt-parent = <&vica>;
 			interrupts = <28>;
+			clocks = <&uart2clk>, <&pclkuart2>;
+			clock-names = "uartclk", "apb_pclk";
 			status = "disabled";
 		};
 
 		rng: rng@101b0000 {
 			compatible = "arm,primecell";
 			reg = <0x101b0000 0x1000>;
+			clocks = <&rngcclk>, <&hclkrng>;
+			clock-names = "rng", "apb_pclk";
 		};
 
 		rtc: rtc@101e8000 {
 			compatible = "arm,pl031", "arm,primecell";
 			reg = <0x101e8000 0x1000>;
+			clocks = <&pclk>;
+			clock-names = "apb_pclk";
 			interrupt-parent = <&vica>;
 			interrupts = <10>;
 		};
@@ -243,6 +807,8 @@
 		mmcsd: sdi@101f6000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x101f6000 0x1000>;
+			clocks = <&sdiclk>, <&pclksdi>;
+			clock-names = "mclk", "apb_pclk";
 			interrupt-parent = <&vica>;
 			interrupts = <22>;
 			max-frequency = <48000000>;
@@ -251,6 +817,8 @@
 			mmc-cap-sd-highspeed;
 			cd-gpios = <&gpio3 15 0x1>;
 			cd-inverted;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmcsd_default_mux>, <&mmcsd_default_mode>;
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/ste-u300.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ste-u300.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/ste-u300.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/ste-u300.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,473 @@
+/*
+ * Device Tree for the ST-Ericsson U300 Machine and SoC
+ */
+
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "ST-Ericsson U300";
+	compatible = "stericsson,u300";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	chosen {
+		bootargs = "root=/dev/ram0 console=ttyAMA0,115200n8 earlyprintk";
+	};
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+        };
+
+	memory {
+		reg = <0x48000000 0x03c00000>;
+	};
+
+	s365 {
+		compatible = "stericsson,s365";
+		vana15-supply = <&ab3100_ldo_d_reg>;
+		syscon = <&syscon>;
+	};
+
+	syscon: syscon@c0011000 {
+		compatible = "stericsson,u300-syscon", "syscon";
+		reg = <0xc0011000 0x1000>;
+		clk32: app_32_clk@32k {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <32768>;
+		};
+		pll13: pll13@13M {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <13000000>;
+		};
+		/* Slow bridge clocks under PLL13 */
+		slow_clk: slow_clk@13M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <0>; /* Slow */
+			clock-id = <0>;
+			clocks = <&pll13>;
+		};
+		uart0_clk: uart0_clk@13M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <0>; /* Slow */
+			clock-id = <1>;
+			clocks = <&slow_clk>;
+		};
+		gpio_clk: gpio_clk@13M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <0>; /* Slow */
+			clock-id = <4>;
+			clocks = <&slow_clk>;
+		};
+		rtc_clk: rtc_clk@13M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <0>; /* Slow */
+			clock-id = <6>;
+			clocks = <&slow_clk>;
+		};
+		apptimer_clk: app_tmr_clk@13M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <0>; /* Slow */
+			clock-id = <7>;
+			clocks = <&slow_clk>;
+		};
+		acc_tmr_clk@13M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <0>; /* Slow */
+			clock-id = <8>;
+			clocks = <&slow_clk>;
+		};
+		pll208: pll208@208M {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <208000000>;
+		};
+		app208: app_208_clk@208M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <1>;
+			clock-mult = <1>;
+			clocks = <&pll208>;
+		};
+		cpu_clk@208M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <2>; /* Rest */
+			clock-id = <3>;
+			clocks = <&app208>;
+		};
+		app104: app_104_clk@104M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <2>;
+			clock-mult = <1>;
+			clocks = <&pll208>;
+		};
+		semi_clk@104M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <2>; /* Rest */
+			clock-id = <9>;
+			clocks = <&app104>;
+		};
+		app52: app_52_clk@52M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <4>;
+			clock-mult = <1>;
+			clocks = <&pll208>;
+		};
+		/* AHB subsystem clocks */
+		ahb_clk: ahb_subsys_clk@52M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <2>; /* Rest */
+			clock-id = <10>;
+			clocks = <&app52>;
+		};
+		intcon_clk@52M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <2>; /* Rest */
+			clock-id = <12>;
+			clocks = <&ahb_clk>;
+		};
+		emif_clk@52M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <2>; /* Rest */
+			clock-id = <5>;
+			clocks = <&ahb_clk>;
+		};
+		dmac_clk: dmac_clk@52M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <2>; /* Rest */
+			clock-id = <4>;
+			clocks = <&app52>;
+		};
+		fsmc_clk: fsmc_clk@52M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <2>; /* Rest */
+			clock-id = <6>;
+			clocks = <&app52>;
+		};
+		xgam_clk: xgam_clk@52M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <2>; /* Rest */
+			clock-id = <8>;
+			clocks = <&app52>;
+		};
+		app26: app_26_clk@26M {
+			#clock-cells = <0>;
+			compatible = "fixed-factor-clock";
+			clock-div = <2>;
+			clock-mult = <1>;
+			clocks = <&app52>;
+		};
+		/* Fast bridge  clocks */
+		fast_clk: fast_clk@26M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <1>; /* Fast */
+			clock-id = <0>;
+			clocks = <&app26>;
+		};
+		i2c0_clk: i2c0_clk@26M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <1>; /* Fast */
+			clock-id = <1>;
+			clocks = <&fast_clk>;
+		};
+		i2c1_clk: i2c1_clk@26M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <1>; /* Fast */
+			clock-id = <2>;
+			clocks = <&fast_clk>;
+		};
+		mmc_pclk: mmc_p_clk@26M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <1>; /* Fast */
+			clock-id = <5>;
+			clocks = <&fast_clk>;
+		};
+		mmc_mclk: mmc_mclk {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-mclk";
+			clocks = <&mmc_pclk>;
+		};
+		spi_clk: spi_p_clk@26M {
+			#clock-cells = <0>;
+			compatible = "stericsson,u300-syscon-clk";
+			clock-type = <1>; /* Fast */
+			clock-id = <6>;
+			clocks = <&fast_clk>;
+		};
+	};
+
+	timer: timer@c0014000 {
+		compatible = "stericsson,u300-apptimer";
+		reg = <0xc0014000 0x1000>;
+		interrupt-parent = <&vica>;
+		interrupts = <24 25 26 27>;
+		clocks = <&apptimer_clk>;
+	};
+
+	gpio: gpio@c0016000 {
+		compatible = "stericsson,gpio-coh901";
+		reg = <0xc0016000 0x1000>;
+		interrupt-parent = <&vicb>;
+		interrupts = <0 1 2 18 21 22 23>;
+		clocks = <&gpio_clk>;
+		interrupt-names = "gpio0", "gpio1", "gpio2", "gpio3",
+				"gpio4", "gpio5", "gpio6";
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	pinctrl: pinctrl@c0011000 {
+		compatible = "stericsson,pinctrl-u300";
+		reg = <0xc0011000 0x1000>;
+	};
+
+	watchdog: watchdog@c0012000 {
+		compatible = "stericsson,coh901327";
+		reg = <0xc0012000 0x1000>;
+		interrupt-parent = <&vicb>;
+		interrupts = <3>;
+		clocks = <&clk32>;
+	};
+
+	rtc: rtc@c0017000 {
+		compatible = "stericsson,coh901331";
+		reg = <0xc0017000 0x1000>;
+		interrupt-parent = <&vicb>;
+		interrupts = <10>;
+		clocks = <&rtc_clk>;
+	};
+
+	dmac: dma-controller@c00020000 {
+		compatible = "stericsson,coh901318";
+		reg = <0xc0020000 0x1000>;
+		interrupt-parent = <&vica>;
+		interrupts = <2>;
+		#dma-cells = <1>;
+		dma-channels = <40>;
+		clocks = <&dmac_clk>;
+	};
+
+	/* A NAND flash of 128 MiB */
+	fsmc: flash@40000000 {
+		compatible = "stericsson,fsmc-nand";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x9f800000 0x1000>,	/* FSMC Register*/
+			<0x80000000 0x4000>,	/* NAND Base DATA */
+			<0x80020000 0x4000>,	/* NAND Base ADDR */
+			<0x80010000 0x4000>;	/* NAND Base CMD */
+		reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
+		nand-skip-bbtscan;
+		clocks = <&fsmc_clk>;
+
+		partition@0 {
+		label = "boot records";
+			reg = <0x0 0x20000>;
+		};
+		partition@20000 {
+			label = "free";
+			reg = <0x20000 0x7e0000>;
+		};
+		partition@800000 {
+			label = "platform";
+			reg = <0x800000 0xf800000>;
+		};
+	};
+
+	i2c0: i2c@c0004000 {
+		compatible = "st,ddci2c";
+		reg = <0xc0004000 0x1000>;
+		interrupt-parent = <&vicb>;
+		interrupts = <8>;
+		clocks = <&i2c0_clk>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		ab3100: ab3100@0x48 {
+			compatible = "stericsson,ab3100";
+			reg = <0x48>;
+			interrupt-parent = <&vica>;
+			interrupts = <0>; /* EXT0 IRQ */
+			ab3100-regulators {
+				compatible = "stericsson,ab3100-regulators";
+				ab3100_ldo_a_reg: ab3100_ldo_a {
+					regulator-compatible = "ab3100_ldo_a";
+					startup-delay-us = <200>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+				ab3100_ldo_c_reg: ab3100_ldo_c {
+					regulator-compatible = "ab3100_ldo_c";
+					startup-delay-us = <200>;
+				};
+				ab3100_ldo_d_reg: ab3100_ldo_d {
+					regulator-compatible = "ab3100_ldo_d";
+					startup-delay-us = <200>;
+				};
+				ab3100_ldo_e_reg: ab3100_ldo_e {
+					regulator-compatible = "ab3100_ldo_e";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					startup-delay-us = <200>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+				ab3100_ldo_f_reg: ab3100_ldo_f {
+					regulator-compatible = "ab3100_ldo_f";
+					regulator-min-microvolt = <2500000>;
+					regulator-max-microvolt = <2500000>;
+					startup-delay-us = <600>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+				ab3100_ldo_g_reg: ab3100_ldo_g {
+					regulator-compatible = "ab3100_ldo_g";
+					regulator-min-microvolt = <1500000>;
+					regulator-max-microvolt = <2850000>;
+					startup-delay-us = <400>;
+				};
+				ab3100_ldo_h_reg: ab3100_ldo_h {
+					regulator-compatible = "ab3100_ldo_h";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <2750000>;
+					startup-delay-us = <200>;
+				};
+				ab3100_ldo_k_reg: ab3100_ldo_k {
+					regulator-compatible = "ab3100_ldo_k";
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <2750000>;
+					startup-delay-us = <200>;
+				};
+				ab3100_ext_reg: ab3100_ext {
+					regulator-compatible = "ab3100_ext";
+				};
+				ab3100_buck_reg: ab3100_buck {
+					regulator-compatible = "ab3100_buck";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1800000>;
+					startup-delay-us = <1000>;
+					regulator-always-on;
+					regulator-boot-on;
+				};
+			};
+		};
+	};
+
+	i2c1: i2c@c0005000 {
+		compatible = "st,ddci2c";
+		reg = <0xc0005000 0x1000>;
+		interrupt-parent = <&vicb>;
+		interrupts = <9>;
+		clocks = <&i2c1_clk>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		fwcam0: fwcam@0x10 {
+			reg = <0x10>;
+		};
+		fwcam1: fwcam@0x5d {
+			reg = <0x5d>;
+		};
+	};
+
+	amba {
+		compatible = "arm,amba-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		vica: interrupt-controller@a0001000 {
+			compatible = "arm,versatile-vic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			reg = <0xa0001000 0x20>;
+		};
+
+		vicb: interrupt-controller@a0002000 {
+			compatible = "arm,versatile-vic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			reg = <0xa0002000 0x20>;
+		};
+
+		uart0: serial@c0013000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xc0013000 0x1000>;
+			interrupt-parent = <&vica>;
+			interrupts = <22>;
+			clocks = <&uart0_clk>, <&uart0_clk>;
+			clock-names = "apb_pclk", "uart0_clk";
+			dmas = <&dmac 17 &dmac 18>;
+			dma-names = "tx", "rx";
+		};
+
+		uart1: serial@c0007000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0xc0007000 0x1000>;
+			interrupt-parent = <&vicb>;
+			interrupts = <20>;
+			dmas = <&dmac 38 &dmac 39>;
+			dma-names = "tx", "rx";
+		};
+
+		mmcsd: mmcsd@c0001000 {
+			compatible = "arm,pl18x", "arm,primecell";
+			reg = <0xc0001000 0x1000>;
+			interrupt-parent = <&vicb>;
+			interrupts = <6 7>;
+			clocks = <&mmc_pclk>, <&mmc_mclk>;
+			clock-names = "apb_pclk", "mclk";
+			max-frequency = <24000000>;
+			bus-width = <4>; // SD-card slot
+			mmc-cap-mmc-highspeed;
+			mmc-cap-sd-highspeed;
+			cd-gpios = <&gpio 12 0x4>;
+			cd-inverted;
+			vmmc-supply = <&ab3100_ldo_g_reg>;
+			dmas = <&dmac 14>;
+			dma-names = "rx";
+		};
+
+		spi: ssp@c0006000 {
+			compatible = "arm,pl022", "arm,primecell";
+			reg = <0xc0006000 0x1000>;
+			interrupt-parent = <&vica>;
+			interrupts = <23>;
+			clocks = <&spi_clk>, <&spi_clk>;
+			clock-names = "apb_pclk", "spi_clk";
+			dmas = <&dmac 27 &dmac 28>;
+			dma-names = "tx", "rx";
+			num-cs = <3>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			spi-dummy@1 {
+				compatible = "arm,pl022-dummy";
+				reg = <1>;
+				spi-max-frequency = <20000000>;
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih415-b2000.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415-b2000.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih415-b2000.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415-b2000.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2000.dtsi"
+/ {
+	model = "STiH415 B2000 Board";
+	compatible = "st,stih415", "st,stih415-b2000";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih415-b2020.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415-b2020.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih415-b2020.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415-b2020.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih415.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+	model = "STiH415 B2020 Board";
+	compatible = "st,stih415", "st,stih415-b2020";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih415-clock.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415-clock.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih415-clock.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415-clock.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/ {
+	clocks {
+		/*
+		 * Fixed 30MHz oscillator input to SoC
+		 */
+		CLK_SYSIN: CLK_SYSIN {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <30000000>;
+		};
+
+		/*
+		 * ARM Peripheral clock for timers
+		 */
+		arm_periph_clk: arm_periph_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <500000000>;
+		};
+
+		/*
+		 * Bootloader initialized system infrastructure clock for
+		 * serial devices.
+		 */
+		CLKS_ICN_REG_0: CLKS_ICN_REG_0 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih415.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih415.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih41x.dtsi"
+#include "stih415-clock.dtsi"
+#include "stih415-pinctrl.dtsi"
+/ {
+
+	L2: cache-controller {
+		compatible = "arm,pl310-cache";
+		reg = <0xfffe2000 0x1000>;
+		arm,data-latency = <3 2 2>;
+		arm,tag-latency = <1 1 1>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&intc>;
+		ranges;
+		compatible	= "simple-bus";
+
+		syscfg_sbc: sbc-syscfg@fe600000{
+			compatible      = "st,stih415-sbc-syscfg", "syscon";
+			reg		= <0xfe600000 0xb4>;
+		};
+
+		syscfg_front: front-syscfg@fee10000{
+			compatible      = "st,stih415-front-syscfg", "syscon";
+			reg		= <0xfee10000 0x194>;
+		};
+
+		syscfg_rear: rear-syscfg@fe830000{
+			compatible      = "st,stih415-rear-syscfg", "syscon";
+			reg		= <0xfe830000 0x190>;
+		};
+
+		/* MPE syscfgs */
+		syscfg_left: left-syscfg@fd690000{
+			compatible      = "st,stih415-left-syscfg", "syscon";
+			reg		= <0xfd690000 0x78>;
+		};
+
+		syscfg_right: right-syscfg@fd320000{
+			compatible      = "st,stih415-right-syscfg", "syscon";
+			reg		= <0xfd320000 0x180>;
+		};
+
+		syscfg_system: system-syscfg@fdde0000  {
+			compatible      = "st,stih415-system-syscfg", "syscon";
+			reg		= <0xfdde0000 0x15c>;
+		};
+
+		syscfg_lpm: lpm-syscfg@fe4b5100{
+			compatible      = "st,stih415-lpm-syscfg", "syscon";
+			reg		= <0xfe4b5100 0x08>;
+		};
+
+		serial2: serial@fed32000 {
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfed32000 0x2c>;
+			interrupts	= <0 197 0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_serial2>;
+			clocks		= <&CLKS_ICN_REG_0>;
+		};
+
+		/* SBC comms block ASCs in SASG1 */
+		sbc_serial1: serial@fe531000 {
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfe531000 0x2c>;
+			interrupts	= <0 210 0>;
+			clocks		= <&CLK_SYSIN>;
+			pinctrl-names 	= "default";
+			pinctrl-0	= <&pinctrl_sbc_serial1>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih415-pinctrl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415-pinctrl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih415-pinctrl.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih415-pinctrl.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "st-pincfg.h"
+/ {
+
+	aliases {
+		gpio0	= &PIO0;
+		gpio1	= &PIO1;
+		gpio2	= &PIO2;
+		gpio3	= &PIO3;
+		gpio4	= &PIO4;
+		gpio5	= &PIO5;
+		gpio6	= &PIO6;
+		gpio7	= &PIO7;
+		gpio8	= &PIO8;
+		gpio9	= &PIO9;
+		gpio10	= &PIO10;
+		gpio11	= &PIO11;
+		gpio12	= &PIO12;
+		gpio13	= &PIO13;
+		gpio14	= &PIO14;
+		gpio15	= &PIO15;
+		gpio16	= &PIO16;
+		gpio17	= &PIO17;
+		gpio18	= &PIO18;
+		gpio19	= &PIO100;
+		gpio20	= &PIO101;
+		gpio21	= &PIO102;
+		gpio22	= &PIO103;
+		gpio23	= &PIO104;
+		gpio24	= &PIO105;
+		gpio25	= &PIO106;
+		gpio26	= &PIO107;
+	};
+
+	soc {
+		pin-controller-sbc {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-sbc-pinctrl";
+			st,syscfg	= <&syscfg_sbc>;
+			ranges 		= <0 0xfe610000 0x5000>;
+
+			PIO0: gpio@fe610000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO0";
+			};
+			PIO1: gpio@fe611000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO1";
+			};
+			PIO2: gpio@fe612000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO2";
+			};
+			PIO3: gpio@fe613000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x3000 0x100>;
+				st,bank-name	= "PIO3";
+			};
+			PIO4: gpio@fe614000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x4000 0x100>;
+				st,bank-name	= "PIO4";
+			};
+
+			sbc_serial1 {
+				pinctrl_sbc_serial1:sbc_serial1 {
+					st,pins {
+						tx	= <&PIO2 6 ALT3 OUT>;
+						rx	= <&PIO2 7 ALT3 IN>;
+					};
+				};
+			};
+		};
+
+		pin-controller-front {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-front-pinctrl";
+			st,syscfg	= <&syscfg_front>;
+			ranges		= <0 0xfee00000 0x8000>;
+
+			PIO5: gpio@fee00000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO5";
+			};
+			PIO6: gpio@fee01000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO6";
+			};
+			PIO7: gpio@fee02000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO7";
+			};
+			PIO8: gpio@fee03000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x3000 0x100>;
+				st,bank-name	= "PIO8";
+			};
+			PIO9: gpio@fee04000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x4000 0x100>;
+				st,bank-name	= "PIO9";
+			};
+			PIO10: gpio@fee05000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x5000 0x100>;
+				st,bank-name	= "PIO10";
+			};
+			PIO11: gpio@fee06000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x6000 0x100>;
+				st,bank-name	= "PIO11";
+			};
+			PIO12: gpio@fee07000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x7000 0x100>;
+				st,bank-name	= "PIO12";
+			};
+		};
+
+		pin-controller-rear {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-rear-pinctrl";
+			st,syscfg	= <&syscfg_rear>;
+			ranges		= <0 0xfe820000 0x8000>;
+
+			PIO13: gpio@fe820000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO13";
+			};
+			PIO14: gpio@fe821000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO14";
+			};
+			PIO15: gpio@fe822000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO15";
+			};
+			PIO16: gpio@fe823000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x3000 0x100>;
+				st,bank-name	= "PIO16";
+			};
+			PIO17: gpio@fe824000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x4000 0x100>;
+				st,bank-name	= "PIO17";
+			};
+			PIO18: gpio@fe825000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x5000 0x100>;
+				st,bank-name	= "PIO18";
+			};
+
+			serial2 {
+				pinctrl_serial2: serial2-0 {
+					st,pins {
+						tx	= <&PIO17 4 ALT2 OUT>;
+						rx	= <&PIO17 5 ALT2 IN>;
+					};
+				};
+			};
+		};
+
+		pin-controller-left {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-left-pinctrl";
+			st,syscfg	= <&syscfg_left>;
+			ranges		= <0 0xfd6b0000 0x3000>;
+
+			PIO100: gpio@fd6b0000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO100";
+			};
+			PIO101: gpio@fd6b1000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO101";
+			};
+			PIO102: gpio@fd6b2000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO102";
+			};
+		};
+
+		pin-controller-right {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih415-right-pinctrl";
+			st,syscfg	= <&syscfg_right>;
+			ranges		= <0 0xfd330000 0x5000>;
+
+			PIO103: gpio@fd330000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO103";
+			};
+			PIO104: gpio@fd331000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO104";
+			};
+			PIO105: gpio@fd332000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO105";
+			};
+			PIO106: gpio@fd333000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x3000 0x100>;
+				st,bank-name	= "PIO106";
+			};
+			PIO107: gpio@fd334000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x4000 0x100>;
+				st,bank-name	= "PIO107";
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih416-b2000.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416-b2000.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih416-b2000.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416-b2000.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2000.dtsi"
+
+/ {
+	compatible = "st,stih416", "st,stih416-b2000";
+	model = "STiH416 B2000";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih416-b2020.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416-b2020.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih416-b2020.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416-b2020.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/dts-v1/;
+#include "stih416.dtsi"
+#include "stih41x-b2020.dtsi"
+/ {
+	model = "STiH416 B2020";
+	compatible = "st,stih416", "st,stih416-b2020";
+
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih416-clock.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416-clock.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih416-clock.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416-clock.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics R&D Limited
+ * <stlinux-devel@stlinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/ {
+	clocks {
+		/*
+		 * Fixed 30MHz oscillator inputs to SoC
+		 */
+		CLK_SYSIN: CLK_SYSIN {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <30000000>;
+			clock-output-names = "CLK_SYSIN";
+		};
+
+		/*
+		 * ARM Peripheral clock for timers
+		 */
+		arm_periph_clk: arm_periph_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <600000000>;
+		};
+
+		/*
+		 * Bootloader initialized system infrastructure clock for
+		 * serial devices.
+		 */
+		CLK_S_ICN_REG_0: clockgenA0@4 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+			clock-output-names = "CLK_S_ICN_REG_0";
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih416.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih416.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2012 STMicroelectronics Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "stih41x.dtsi"
+#include "stih416-clock.dtsi"
+#include "stih416-pinctrl.dtsi"
+/ {
+	L2: cache-controller {
+		compatible = "arm,pl310-cache";
+		reg = <0xfffe2000 0x1000>;
+		arm,data-latency = <3 3 3>;
+		arm,tag-latency = <2 2 2>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&intc>;
+		ranges;
+		compatible	= "simple-bus";
+
+		syscfg_sbc:sbc-syscfg@fe600000{
+			compatible	= "st,stih416-sbc-syscfg", "syscon";
+			reg		= <0xfe600000 0x1000>;
+		};
+
+		syscfg_front:front-syscfg@fee10000{
+			compatible	= "st,stih416-front-syscfg", "syscon";
+			reg		= <0xfee10000 0x1000>;
+		};
+
+		syscfg_rear:rear-syscfg@fe830000{
+			compatible	= "st,stih416-rear-syscfg", "syscon";
+			reg		= <0xfe830000 0x1000>;
+		};
+
+		/* MPE */
+		syscfg_fvdp_fe:fvdp-fe-syscfg@fddf0000{
+			compatible	= "st,stih416-fvdp-fe-syscfg", "syscon";
+			reg		= <0xfddf0000 0x1000>;
+		};
+
+		syscfg_fvdp_lite:fvdp-lite-syscfg@fd6a0000{
+			compatible	= "st,stih416-fvdp-lite-syscfg", "syscon";
+			reg		= <0xfd6a0000 0x1000>;
+		};
+
+		syscfg_cpu:cpu-syscfg@fdde0000{
+			compatible	= "st,stih416-cpu-syscfg", "syscon";
+			reg		= <0xfdde0000 0x1000>;
+		};
+
+		syscfg_compo:compo-syscfg@fd320000{
+			compatible	= "st,stih416-compo-syscfg", "syscon";
+			reg		= <0xfd320000 0x1000>;
+		};
+
+		syscfg_transport:transport-syscfg@fd690000{
+			compatible	= "st,stih416-transport-syscfg", "syscon";
+			reg		= <0xfd690000 0x1000>;
+		};
+
+		syscfg_lpm:lpm-syscfg@fe4b5100{
+			compatible	= "st,stih416-lpm-syscfg", "syscon";
+			reg		= <0xfe4b5100 0x8>;
+		};
+
+		serial2: serial@fed32000{
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfed32000 0x2c>;
+			interrupts	= <0 197 0>;
+			clocks          = <&CLK_S_ICN_REG_0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_serial2 &pinctrl_serial2_oe>;
+		};
+
+		/* SBC_UART1 */
+		sbc_serial1: serial@fe531000 {
+			compatible	= "st,asc";
+			status 		= "disabled";
+			reg		= <0xfe531000 0x2c>;
+			interrupts	= <0 210 0>;
+			pinctrl-names 	= "default";
+			pinctrl-0 	= <&pinctrl_sbc_serial1>;
+			clocks          = <&CLK_SYSIN>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih416-pinctrl.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416-pinctrl.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih416-pinctrl.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih416-pinctrl.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,303 @@
+
+/*
+ * Copyright (C) 2013 STMicroelectronics Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#include "st-pincfg.h"
+/ {
+
+	aliases {
+		gpio0	= &PIO0;
+		gpio1	= &PIO1;
+		gpio2	= &PIO2;
+		gpio3	= &PIO3;
+		gpio4	= &PIO4;
+		gpio5	= &PIO40;
+		gpio6	= &PIO5;
+		gpio7	= &PIO6;
+		gpio8	= &PIO7;
+		gpio9	= &PIO8;
+		gpio10	= &PIO9;
+		gpio11	= &PIO10;
+		gpio12	= &PIO11;
+		gpio13	= &PIO12;
+		gpio14	= &PIO30;
+		gpio15	= &PIO31;
+		gpio16	= &PIO13;
+		gpio17	= &PIO14;
+		gpio18	= &PIO15;
+		gpio19	= &PIO16;
+		gpio20	= &PIO17;
+		gpio21	= &PIO18;
+		gpio22	= &PIO100;
+		gpio23	= &PIO101;
+		gpio24	= &PIO102;
+		gpio25	= &PIO103;
+		gpio26	= &PIO104;
+		gpio27	= &PIO105;
+		gpio28	= &PIO106;
+		gpio29	= &PIO107;
+	};
+
+	soc {
+		pin-controller-sbc {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-sbc-pinctrl";
+			st,syscfg	= <&syscfg_sbc>;
+			ranges		= <0 0xfe610000 0x6000>;
+
+			PIO0: gpio@fe610000 {
+				gpio-controller;
+				#gpio-cells = <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO0";
+			};
+			PIO1: gpio@fe611000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO1";
+			};
+			PIO2: gpio@fe612000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO2";
+			};
+			PIO3: gpio@fe613000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x3000 0x100>;
+				st,bank-name	= "PIO3";
+			};
+			PIO4: gpio@fe614000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x4000 0x100>;
+				st,bank-name	= "PIO4";
+			};
+			PIO40: gpio@fe615000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x5000 0x100>;
+				st,bank-name	= "PIO40";
+				st,retime-pin-mask = <0x7f>;
+			};
+
+			sbc_serial1 {
+				pinctrl_sbc_serial1: sbc_serial1 {
+					st,pins {
+						tx	= <&PIO2 6 ALT3 OUT>;
+						rx	= <&PIO2 7 ALT3 IN>;
+					};
+				};
+			};
+		};
+
+		pin-controller-front {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-front-pinctrl";
+			st,syscfg	= <&syscfg_front>;
+			ranges		= <0 0xfee00000 0x10000>;
+
+			PIO5: gpio@fee00000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO5";
+			};
+			PIO6: gpio@fee01000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO6";
+			};
+			PIO7: gpio@fee02000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO7";
+			};
+			PIO8: gpio@fee03000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x3000 0x100>;
+				st,bank-name	= "PIO8";
+			};
+			PIO9: gpio@fee04000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x4000 0x100>;
+				st,bank-name	= "PIO9";
+			};
+			PIO10: gpio@fee05000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x5000 0x100>;
+				st,bank-name	= "PIO10";
+			};
+			PIO11: gpio@fee06000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x6000 0x100>;
+				st,bank-name	= "PIO11";
+			};
+			PIO12: gpio@fee07000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x7000 0x100>;
+				st,bank-name	= "PIO12";
+			};
+			PIO30: gpio@fee08000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x8000 0x100>;
+				st,bank-name	= "PIO30";
+			};
+			PIO31: gpio@fee09000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x9000 0x100>;
+				st,bank-name	= "PIO31";
+			};
+
+			serial2-oe {
+				pinctrl_serial2_oe: serial2-1 {
+					st,pins {
+						output-enable	= <&PIO11 3 ALT2 OUT>;
+					};
+				};
+			};
+
+		};
+
+		pin-controller-rear {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-rear-pinctrl";
+			st,syscfg	= <&syscfg_rear>;
+			ranges 		= <0 0xfe820000 0x6000>;
+
+			PIO13: gpio@fe820000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO13";
+			};
+			PIO14: gpio@fe821000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO14";
+			};
+			PIO15: gpio@fe822000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO15";
+			};
+			PIO16: gpio@fe823000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x3000 0x100>;
+				st,bank-name	= "PIO16";
+			};
+			PIO17: gpio@fe824000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x4000 0x100>;
+				st,bank-name	= "PIO17";
+			};
+			PIO18: gpio@fe825000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x5000 0x100>;
+				st,bank-name	= "PIO18";
+				st,retime-pin-mask = <0xf>;
+			};
+
+			serial2 {
+				pinctrl_serial2: serial2-0 {
+					st,pins {
+						tx	= <&PIO17 4 ALT2 OUT>;
+						rx	= <&PIO17 5 ALT2 IN>;
+					};
+				};
+			};
+		};
+
+		pin-controller-fvdp-fe {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-fvdp-fe-pinctrl";
+			st,syscfg	= <&syscfg_fvdp_fe>;
+			ranges		= <0 0xfd6b0000 0x3000>;
+
+			PIO100: gpio@fd6b0000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO100";
+			};
+			PIO101: gpio@fd6b1000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO101";
+			};
+			PIO102: gpio@fd6b2000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO102";
+			};
+		};
+
+		pin-controller-fvdp-lite {
+			#address-cells	= <1>;
+			#size-cells	= <1>;
+			compatible	= "st,stih416-fvdp-lite-pinctrl";
+			st,syscfg		= <&syscfg_fvdp_lite>;
+			ranges			= <0 0xfd330000 0x5000>;
+
+			PIO103: gpio@fd330000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0 0x100>;
+				st,bank-name	= "PIO103";
+			};
+			PIO104: gpio@fd331000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x1000 0x100>;
+				st,bank-name	= "PIO104";
+			};
+			PIO105: gpio@fd332000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x2000 0x100>;
+				st,bank-name	= "PIO105";
+			};
+			PIO106: gpio@fd333000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x3000 0x100>;
+				st,bank-name	= "PIO106";
+			};
+
+			PIO107: gpio@fd334000 {
+				gpio-controller;
+				#gpio-cells	= <1>;
+				reg		= <0x4000 0x100>;
+				st,bank-name	= "PIO107";
+				st,retime-pin-mask = <0xf>;
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih41x-b2000.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih41x-b2000.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih41x-b2000.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih41x-b2000.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+
+	memory{
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyAS0,115200";
+		linux,stdout-path = &serial2;
+	};
+
+	aliases {
+		ttyAS0 = &serial2;
+	};
+
+	soc {
+		serial2: serial@fed32000 {
+			status = "okay";
+		};
+
+		leds {
+			compatible	= "gpio-leds";
+			fp_led {
+				#gpio-cells = <1>;
+				label	= "Front Panel LED";
+				gpios	= <&PIO105 7>;
+				linux,default-trigger	= "heartbeat";
+			};
+		};
+
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih41x-b2020.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih41x-b2020.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih41x-b2020.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih41x-b2020.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+/ {
+	memory{
+		device_type = "memory";
+		reg = <0x40000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyAS0,115200";
+		linux,stdout-path = &sbc_serial1;
+	};
+
+	aliases {
+		ttyAS0 = &sbc_serial1;
+	};
+	soc {
+		sbc_serial1: serial@fe531000 {
+			status = "okay";
+		};
+
+		leds {
+			compatible	= "gpio-leds";
+			red {
+				#gpio-cells = <1>;
+				label	= "Front Panel LED";
+				gpios	= <&PIO4 1>;
+				linux,default-trigger	= "heartbeat";
+			};
+			green {
+				gpios	= <&PIO4 7>;
+				default-state = "off";
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stih41x.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih41x.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stih41x.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stih41x.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,40 @@
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+		};
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+		};
+	};
+
+	intc: interrupt-controller@fffe1000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0xfffe1000 0x1000>,
+		      <0xfffe0100 0x100>;
+	};
+
+	scu@fffe0000 {
+		compatible = "arm,cortex-a9-scu";
+		reg = <0xfffe0000 0x1000>;
+	};
+
+	timer@fffe0200 {
+		interrupt-parent = <&intc>;
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0xfffe0200 0x100>;
+		interrupts = <1 11 0x04>;
+		clocks = <&arm_periph_clk>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/st-pincfg.h linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/st-pincfg.h
--- linux-libre-3.10-gnu/arch/arm/boot/dts/st-pincfg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/st-pincfg.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,71 @@
+#ifndef _ST_PINCFG_H_
+#define _ST_PINCFG_H_
+
+/* Alternate functions */
+#define ALT1	1
+#define ALT2	2
+#define ALT3	3
+#define ALT4	4
+#define ALT5	5
+#define ALT6	6
+#define ALT7	7
+
+/* Output enable */
+#define OE			(1 << 27)
+/* Pull Up */
+#define PU			(1 << 26)
+/* Open Drain */
+#define OD			(1 << 26)
+#define RT			(1 << 23)
+#define INVERTCLK		(1 << 22)
+#define CLKNOTDATA		(1 << 21)
+#define DOUBLE_EDGE		(1 << 20)
+#define CLK_A			(0 << 18)
+#define CLK_B			(1 << 18)
+#define CLK_C			(2 << 18)
+#define CLK_D			(3 << 18)
+
+/* User-frendly defines for Pin Direction */
+		/* oe = 0, pu = 0, od = 0 */
+#define IN			(0)
+		/* oe = 0, pu = 1, od = 0 */
+#define IN_PU			(PU)
+		/* oe = 1, pu = 0, od = 0 */
+#define OUT			(OE)
+		/* oe = 1, pu = 0, od = 1 */
+#define BIDIR			(OE | OD)
+		/* oe = 1, pu = 1, od = 1 */
+#define BIDIR_PU		(OE | PU | OD)
+
+/* RETIME_TYPE */
+/*
+ * B Mode
+ * Bypass retime with optional delay parameter
+ */
+#define BYPASS		(0)
+/*
+ * R0, R1, R0D, R1D modes
+ * single-edge data non inverted clock, retime data with clk
+ */
+#define SE_NICLK_IO	(RT)
+/*
+ * RIV0, RIV1, RIV0D, RIV1D modes
+ * single-edge data inverted clock, retime data with clk
+ */
+#define SE_ICLK_IO	(RT | INVERTCLK)
+/*
+ * R0E, R1E, R0ED, R1ED modes
+ * double-edge data, retime data with clk
+ */
+#define DE_IO		(RT | DOUBLE_EDGE)
+/*
+ * CIV0, CIV1 modes with inverted clock
+ * Retiming the clk pins will park clock & reduce the noise within the core.
+ */
+#define ICLK		(RT | CLKNOTDATA | INVERTCLK)
+/*
+ * CLK0, CLK1 modes with non-inverted clock
+ * Retiming the clk pins will park clock & reduce the noise within the core.
+ */
+#define NICLK		(RT | CLKNOTDATA)
+#endif /* _ST_PINCFG_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/stuib.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stuib.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/stuib.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/stuib.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -9,13 +9,15 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
+#include <dt-bindings/interrupt-controller/irq.h>
+
 / {
-	soc-u9500 {
+	soc {
 		i2c@80004000 {
 			stmpe1601: stmpe1601@40 {
 				compatible = "st,stmpe1601";
 				reg = <0x40>;
-				interrupts = <26 0x2>;
+				interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
 				interrupt-parent = <&gpio6>;
 				interrupt-controller;
 
@@ -52,26 +54,26 @@
 		};
 
 		i2c@80110000 {
-			bu21013_tp@0x5c {
-				compatible = "rhom,bu21013_tp";
+			bu21013_tp@5c {
+				compatible = "rohm,bu21013_tp";
 				reg = <0x5c>;
 				touch-gpio = <&gpio2 20 0x4>;
 				avdd-supply = <&ab8500_ldo_aux1_reg>;
 
-				rhom,touch-max-x = <384>;
-				rhom,touch-max-y = <704>;
-				rhom,flip-y;
+				rohm,touch-max-x = <384>;
+				rohm,touch-max-y = <704>;
+				rohm,flip-y;
 			};
 
-			bu21013_tp@0x5d {
-				compatible = "rhom,bu21013_tp";
+			bu21013_tp@5d {
+				compatible = "rohm,bu21013_tp";
 				reg = <0x5d>;
 				touch-gpio = <&gpio2 20 0x4>;
 				avdd-supply = <&ab8500_ldo_aux1_reg>;
 
-				rhom,touch-max-x = <384>;
-				rhom,touch-max-y = <704>;
-				rhom,flip-y;
+				rohm,touch-max-x = <384>;
+				rohm,touch-max-y = <704>;
+				rohm,flip-y;
 			};
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sun4i-a10-cubieboard.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sun4i-a10-cubieboard.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun4i-a10-cubieboard.dts	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,21 @@
 	};
 
 	soc@01c20000 {
+		emac: ethernet@01c0b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&emac_pins_a>;
+			phy = <&phy1>;
+			status = "okay";
+		};
+
+		mdio@01c0b080 {
+			status = "okay";
+
+			phy1: ethernet-phy@1 {
+				reg = <1>;
+			};
+		};
+
 		pinctrl@01c20800 {
 			led_pins_cubieboard: led_pins@0 {
 				allwinner,pins = "PH20", "PH21";
@@ -41,6 +56,18 @@
 			pinctrl-0 = <&uart0_pins_a>;
 			status = "okay";
 		};
+
+		i2c0: i2c@01c2ac00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins_a>;
+			status = "okay";
+		};
+
+		i2c1: i2c@01c2b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c1_pins_a>;
+			status = "okay";
+		};
 	};
 
 	leds {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sun4i-a10.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun4i-a10.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sun4i-a10.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun4i-a10.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -16,8 +16,12 @@
 	interrupt-parent = <&intc>;
 
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 		cpu@0 {
+			device_type = "cpu";
 			compatible = "arm,cortex-a8";
+			reg = <0x0>;
 		};
 	};
 
@@ -163,6 +167,22 @@
 		reg = <0x01c20000 0x300000>;
 		ranges;
 
+		emac: ethernet@01c0b000 {
+			compatible = "allwinner,sun4i-emac";
+			reg = <0x01c0b000 0x1000>;
+			interrupts = <55>;
+			clocks = <&ahb_gates 17>;
+			status = "disabled";
+		};
+
+		mdio@01c0b080 {
+			compatible = "allwinner,sun4i-mdio";
+			reg = <0x01c0b080 0x14>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
 		intc: interrupt-controller@01c20400 {
 			compatible = "allwinner,sun4i-ic";
 			reg = <0x01c20400 0x400>;
@@ -173,8 +193,10 @@
 		pio: pinctrl@01c20800 {
 			compatible = "allwinner,sun4i-a10-pinctrl";
 			reg = <0x01c20800 0x400>;
+			interrupts = <28>;
 			clocks = <&apb0_gates 5>;
 			gpio-controller;
+			interrupt-controller;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			#gpio-cells = <3>;
@@ -199,6 +221,38 @@
 				allwinner,drive = <0>;
 				allwinner,pull = <0>;
 			};
+
+			i2c0_pins_a: i2c0@0 {
+				allwinner,pins = "PB0", "PB1";
+				allwinner,function = "i2c0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			i2c1_pins_a: i2c1@0 {
+				allwinner,pins = "PB18", "PB19";
+				allwinner,function = "i2c1";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			i2c2_pins_a: i2c2@0 {
+				allwinner,pins = "PB20", "PB21";
+				allwinner,function = "i2c2";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			emac_pins_a: emac0@0 {
+				allwinner,pins = "PA0", "PA1", "PA2",
+						"PA3", "PA4", "PA5", "PA6",
+						"PA7", "PA8", "PA9", "PA10",
+						"PA11", "PA12", "PA13", "PA14",
+						"PA15", "PA16";
+				allwinner,function = "emac";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
 		};
 
 		timer@01c20c00 {
@@ -292,5 +346,32 @@
 			clocks = <&apb1_gates 23>;
 			status = "disabled";
 		};
+
+		i2c0: i2c@01c2ac00 {
+			compatible = "allwinner,sun4i-i2c";
+			reg = <0x01c2ac00 0x400>;
+			interrupts = <7>;
+			clocks = <&apb1_gates 0>;
+			clock-frequency = <100000>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@01c2b000 {
+			compatible = "allwinner,sun4i-i2c";
+			reg = <0x01c2b000 0x400>;
+			interrupts = <8>;
+			clocks = <&apb1_gates 1>;
+			clock-frequency = <100000>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@01c2b400 {
+			compatible = "allwinner,sun4i-i2c";
+			reg = <0x01c2b400 0x400>;
+			interrupts = <9>;
+			clocks = <&apb1_gates 2>;
+			clock-frequency = <100000>;
+			status = "disabled";
+		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sun4i-a10-hackberry.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun4i-a10-hackberry.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sun4i-a10-hackberry.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun4i-a10-hackberry.dts	2013-08-25 20:43:22.000000000 -0400
@@ -23,10 +23,51 @@
 	};
 
 	soc@01c20000 {
+		emac: ethernet@01c0b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&emac_pins_a>;
+			phy = <&phy0>;
+			status = "okay";
+		};
+
+		mdio@01c0b080 {
+			phy-supply = <&reg_emac_3v3>;
+			status = "okay";
+
+			phy0: ethernet-phy@0 {
+				reg = <0>;
+			};
+		};
+
+		pio: pinctrl@01c20800 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&hackberry_hogs>;
+
+			hackberry_hogs: hogs@0 {
+				allwinner,pins = "PH19";
+				allwinner,function = "gpio_out";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+		};
+
 		uart0: serial@01c28000 {
 			pinctrl-names = "default";
 			pinctrl-0 = <&uart0_pins_a>;
 			status = "okay";
 		};
 	};
+
+	regulators {
+		compatible = "simple-bus";
+
+		reg_emac_3v3: emac-3v3 {
+			compatible = "regulator-fixed";
+			regulator-name = "emac-3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			enable-active-high;
+			gpio = <&pio 7 19 0>;
+		};
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sun5i-a10s.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun5i-a10s.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sun5i-a10s.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun5i-a10s.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	interrupt-parent = <&intc>;
+
+	cpus {
+		cpu@0 {
+			compatible = "arm,cortex-a8";
+		};
+	};
+
+	memory {
+		reg = <0x40000000 0x20000000>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		/*
+		 * This is a dummy clock, to be used as placeholder on
+		 * other mux clocks when a specific parent clock is not
+		 * yet implemented. It should be dropped when the driver
+		 * is complete.
+		 */
+		dummy: dummy {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <0>;
+		};
+
+		osc24M: osc24M@01c20050 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-osc-clk";
+			reg = <0x01c20050 0x4>;
+			clock-frequency = <24000000>;
+		};
+
+		osc32k: osc32k {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <32768>;
+		};
+
+		pll1: pll1@01c20000 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-pll1-clk";
+			reg = <0x01c20000 0x4>;
+			clocks = <&osc24M>;
+		};
+
+		/* dummy is 200M */
+		cpu: cpu@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-cpu-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
+		};
+
+		axi: axi@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-axi-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&cpu>;
+		};
+
+		axi_gates: axi_gates@01c2005c {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-axi-gates-clk";
+			reg = <0x01c2005c 0x4>;
+			clocks = <&axi>;
+			clock-output-names = "axi_dram";
+		};
+
+		ahb: ahb@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-ahb-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&axi>;
+		};
+
+		ahb_gates: ahb_gates@01c20060 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-ahb-gates-clk";
+			reg = <0x01c20060 0x8>;
+			clocks = <&ahb>;
+			clock-output-names = "ahb_usb0", "ahb_ehci0",
+				"ahb_ohci0", "ahb_ehci1", "ahb_ohci1", "ahb_ss",
+				"ahb_dma", "ahb_bist", "ahb_mmc0", "ahb_mmc1",
+				"ahb_mmc2", "ahb_mmc3", "ahb_ms", "ahb_nand",
+				"ahb_sdram", "ahb_ace",	"ahb_emac", "ahb_ts",
+				"ahb_spi0", "ahb_spi1", "ahb_spi2", "ahb_spi3",
+				"ahb_pata", "ahb_sata", "ahb_gps", "ahb_ve",
+				"ahb_tvd", "ahb_tve0", "ahb_tve1", "ahb_lcd0",
+				"ahb_lcd1", "ahb_csi0", "ahb_csi1", "ahb_hdmi",
+				"ahb_de_be0", "ahb_de_be1", "ahb_de_fe0",
+				"ahb_de_fe1", "ahb_mp", "ahb_mali400";
+		};
+
+		apb0: apb0@01c20054 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-apb0-clk";
+			reg = <0x01c20054 0x4>;
+			clocks = <&ahb>;
+		};
+
+		apb0_gates: apb0_gates@01c20068 {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-apb0-gates-clk";
+			reg = <0x01c20068 0x4>;
+			clocks = <&apb0>;
+			clock-output-names = "apb0_codec", "apb0_spdif",
+				"apb0_ac97", "apb0_iis", "apb0_pio", "apb0_ir0",
+				"apb0_ir1", "apb0_keypad";
+		};
+
+		/* dummy is pll62 */
+		apb1_mux: apb1_mux@01c20058 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-apb1-mux-clk";
+			reg = <0x01c20058 0x4>;
+			clocks = <&osc24M>, <&dummy>, <&osc32k>;
+		};
+
+		apb1: apb1@01c20058 {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-apb1-clk";
+			reg = <0x01c20058 0x4>;
+			clocks = <&apb1_mux>;
+		};
+
+		apb1_gates: apb1_gates@01c2006c {
+			#clock-cells = <1>;
+			compatible = "allwinner,sun4i-apb1-gates-clk";
+			reg = <0x01c2006c 0x4>;
+			clocks = <&apb1>;
+			clock-output-names = "apb1_i2c0", "apb1_i2c1",
+				"apb1_i2c2", "apb1_can", "apb1_scr",
+				"apb1_ps20", "apb1_ps21", "apb1_uart0",
+				"apb1_uart1", "apb1_uart2", "apb1_uart3",
+				"apb1_uart4", "apb1_uart5", "apb1_uart6",
+				"apb1_uart7";
+		};
+	};
+
+	soc@01c20000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x01c20000 0x300000>;
+		ranges;
+
+		emac: ethernet@01c0b000 {
+			compatible = "allwinner,sun4i-emac";
+			reg = <0x01c0b000 0x1000>;
+			interrupts = <55>;
+			clocks = <&ahb_gates 17>;
+			status = "disabled";
+		};
+
+		mdio@01c0b080 {
+			compatible = "allwinner,sun4i-mdio";
+			reg = <0x01c0b080 0x14>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		intc: interrupt-controller@01c20400 {
+			compatible = "allwinner,sun4i-ic";
+			reg = <0x01c20400 0x400>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		pio: pinctrl@01c20800 {
+			compatible = "allwinner,sun5i-a10s-pinctrl";
+			reg = <0x01c20800 0x400>;
+			interrupts = <28>;
+			clocks = <&apb0_gates 5>;
+			gpio-controller;
+			interrupt-controller;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			#gpio-cells = <3>;
+
+			uart0_pins_a: uart0@0 {
+				allwinner,pins = "PB19", "PB20";
+				allwinner,function = "uart0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			uart2_pins_a: uart2@0 {
+				allwinner,pins = "PC18", "PC19";
+				allwinner,function = "uart2";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			uart3_pins_a: uart3@0 {
+				allwinner,pins = "PG9", "PG10";
+				allwinner,function = "uart3";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			emac_pins_a: emac0@0 {
+				allwinner,pins = "PA0", "PA1", "PA2",
+						"PA3", "PA4", "PA5", "PA6",
+						"PA7", "PA8", "PA9", "PA10",
+						"PA11", "PA12", "PA13", "PA14",
+						"PA15", "PA16";
+				allwinner,function = "emac";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+		};
+
+		timer@01c20c00 {
+			compatible = "allwinner,sun4i-timer";
+			reg = <0x01c20c00 0x90>;
+			interrupts = <22>;
+			clocks = <&osc24M>;
+		};
+
+		wdt: watchdog@01c20c90 {
+			compatible = "allwinner,sun4i-wdt";
+			reg = <0x01c20c90 0x10>;
+		};
+
+		uart0: serial@01c28000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28000 0x400>;
+			interrupts = <1>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 16>;
+			status = "disabled";
+		};
+
+		uart1: serial@01c28400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28400 0x400>;
+			interrupts = <2>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 17>;
+			status = "disabled";
+		};
+
+		uart2: serial@01c28800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28800 0x400>;
+			interrupts = <3>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 18>;
+			status = "disabled";
+		};
+
+		uart3: serial@01c28c00 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01c28c00 0x400>;
+			interrupts = <4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&apb1_gates 19>;
+			status = "disabled";
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2013 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "sun5i-a10s.dtsi"
+
+/ {
+	model = "Olimex A10s-Olinuxino Micro";
+	compatible = "olimex,a10s-olinuxino-micro", "allwinner,sun5i-a10s";
+
+	soc@01c20000 {
+		emac: ethernet@01c0b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&emac_pins_a>;
+			phy = <&phy1>;
+			status = "okay";
+		};
+
+		mdio@01c0b080 {
+			status = "okay";
+
+			phy1: ethernet-phy@1 {
+				reg = <1>;
+			};
+		};
+
+		pinctrl@01c20800 {
+			led_pins_olinuxino: led_pins@0 {
+				allwinner,pins = "PE3";
+				allwinner,function = "gpio_out";
+				allwinner,drive = <1>;
+				allwinner,pull = <0>;
+			};
+		};
+
+		uart0: serial@01c28000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_pins_a>;
+			status = "okay";
+		};
+
+		uart2: serial@01c28800 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart2_pins_a>;
+			status = "okay";
+		};
+
+		uart3: serial@01c28c00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart3_pins_a>;
+			status = "okay";
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_olinuxino>;
+
+		green {
+			label = "a10s-olinuxino-micro:green:usr";
+			gpios = <&pio 4 3 0>;
+			default-state = "on";
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sun5i-a13.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun5i-a13.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sun5i-a13.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun5i-a13.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -17,8 +17,12 @@
 	interrupt-parent = <&intc>;
 
 	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
 		cpu@0 {
+			device_type = "cpu";
 			compatible = "arm,cortex-a8";
+			reg = <0x0>;
 		};
 	};
 
@@ -95,20 +99,15 @@
 
 		ahb_gates: ahb_gates@01c20060 {
 			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-ahb-gates-clk";
+			compatible = "allwinner,sun5i-a13-ahb-gates-clk";
 			reg = <0x01c20060 0x8>;
 			clocks = <&ahb>;
-			clock-output-names = "ahb_usb0", "ahb_ehci0",
-				"ahb_ohci0", "ahb_ehci1", "ahb_ohci1", "ahb_ss",
-				"ahb_dma", "ahb_bist", "ahb_mmc0", "ahb_mmc1",
-				"ahb_mmc2", "ahb_mmc3", "ahb_ms", "ahb_nand",
-				"ahb_sdram", "ahb_ace",	"ahb_emac", "ahb_ts",
-				"ahb_spi0", "ahb_spi1", "ahb_spi2", "ahb_spi3",
-				"ahb_pata", "ahb_sata", "ahb_gps", "ahb_ve",
-				"ahb_tvd", "ahb_tve0", "ahb_tve1", "ahb_lcd0",
-				"ahb_lcd1", "ahb_csi0", "ahb_csi1", "ahb_hdmi",
-				"ahb_de_be0", "ahb_de_be1", "ahb_de_fe0",
-				"ahb_de_fe1", "ahb_mp", "ahb_mali400";
+			clock-output-names = "ahb_usbotg", "ahb_ehci", "ahb_ohci",
+				"ahb_ss", "ahb_dma", "ahb_bist", "ahb_mmc0",
+				"ahb_mmc1", "ahb_mmc2", "ahb_nand", "ahb_sdram",
+				"ahb_spi0", "ahb_spi1", "ahb_spi2", "ahb_stimer",
+				"ahb_ve", "ahb_lcd", "ahb_csi", "ahb_de_be",
+				"ahb_de_fe", "ahb_iep", "ahb_mali400";
 		};
 
 		apb0: apb0@01c20054 {
@@ -120,15 +119,13 @@
 
 		apb0_gates: apb0_gates@01c20068 {
 			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-apb0-gates-clk";
+			compatible = "allwinner,sun5i-a13-apb0-gates-clk";
 			reg = <0x01c20068 0x4>;
 			clocks = <&apb0>;
-			clock-output-names = "apb0_codec", "apb0_spdif",
-				"apb0_ac97", "apb0_iis", "apb0_pio", "apb0_ir0",
-				"apb0_ir1", "apb0_keypad";
+			clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir";
 		};
 
-		/* dummy is pll62 */
+		/* dummy is pll6 */
 		apb1_mux: apb1_mux@01c20058 {
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-apb1-mux-clk";
@@ -145,15 +142,11 @@
 
 		apb1_gates: apb1_gates@01c2006c {
 			#clock-cells = <1>;
-			compatible = "allwinner,sun4i-apb1-gates-clk";
+			compatible = "allwinner,sun5i-a13-apb1-gates-clk";
 			reg = <0x01c2006c 0x4>;
 			clocks = <&apb1>;
 			clock-output-names = "apb1_i2c0", "apb1_i2c1",
-				"apb1_i2c2", "apb1_can", "apb1_scr",
-				"apb1_ps20", "apb1_ps21", "apb1_uart0",
-				"apb1_uart1", "apb1_uart2", "apb1_uart3",
-				"apb1_uart4", "apb1_uart5", "apb1_uart6",
-				"apb1_uart7";
+				"apb1_i2c2", "apb1_uart1", "apb1_uart3";
 		};
 	};
 
@@ -174,8 +167,10 @@
 		pio: pinctrl@01c20800 {
 			compatible = "allwinner,sun5i-a13-pinctrl";
 			reg = <0x01c20800 0x400>;
+			interrupts = <28>;
 			clocks = <&apb0_gates 5>;
 			gpio-controller;
+			interrupt-controller;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			#gpio-cells = <3>;
@@ -193,6 +188,27 @@
 				allwinner,drive = <0>;
 				allwinner,pull = <0>;
 			};
+
+			i2c0_pins_a: i2c0@0 {
+				allwinner,pins = "PB0", "PB1";
+				allwinner,function = "i2c0";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			i2c1_pins_a: i2c1@0 {
+				allwinner,pins = "PB15", "PB16";
+				allwinner,function = "i2c1";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
+
+			i2c2_pins_a: i2c2@0 {
+				allwinner,pins = "PB17", "PB18";
+				allwinner,function = "i2c2";
+				allwinner,drive = <0>;
+				allwinner,pull = <0>;
+			};
 		};
 
 		timer@01c20c00 {
@@ -226,5 +242,32 @@
 			clocks = <&apb1_gates 19>;
 			status = "disabled";
 		};
+
+		i2c0: i2c@01c2ac00 {
+			compatible = "allwinner,sun4i-i2c";
+			reg = <0x01c2ac00 0x400>;
+			interrupts = <7>;
+			clocks = <&apb1_gates 0>;
+			clock-frequency = <100000>;
+			status = "disabled";
+		};
+
+		i2c1: i2c@01c2b000 {
+			compatible = "allwinner,sun4i-i2c";
+			reg = <0x01c2b000 0x400>;
+			interrupts = <8>;
+			clocks = <&apb1_gates 1>;
+			clock-frequency = <100000>;
+			status = "disabled";
+		};
+
+		i2c2: i2c@01c2b400 {
+			compatible = "allwinner,sun4i-i2c";
+			reg = <0x01c2b400 0x400>;
+			interrupts = <9>;
+			clocks = <&apb1_gates 2>;
+			clock-frequency = <100000>;
+			status = "disabled";
+		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/sun5i-a13-olinuxino.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/sun5i-a13-olinuxino.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/sun5i-a13-olinuxino.dts	2013-08-25 20:43:22.000000000 -0400
@@ -37,6 +37,24 @@
 			pinctrl-0 = <&uart1_pins_b>;
 			status = "okay";
 		};
+
+		i2c0: i2c@01c2ac00 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins_a>;
+			status = "okay";
+		};
+
+		i2c1: i2c@01c2b000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c1_pins_a>;
+			status = "okay";
+		};
+
+		i2c2: i2c@01c2b400 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c2_pins_a>;
+			status = "okay";
+		};
 	};
 
 	leds {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra114-dalmore.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra114-dalmore.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra114-dalmore.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra114-dalmore.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra114.dtsi"
+#include "tegra114.dtsi"
 
 / {
 	model = "NVIDIA Tegra114 Dalmore evaluation board";
@@ -727,6 +727,16 @@
 			battery-name = "battery";
 			sbs,i2c-retry-count = <2>;
 			sbs,poll-retry-count = <100>;
+			power-supplies = <&charger>;
+		};
+
+		rt5640: rt5640 {
+			compatible = "realtek,rt5640";
+			reg = <0x1c>;
+			interrupt-parent = <&gpio>;
+			interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
+			realtek,ldo1-en-gpios =
+				<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -748,7 +758,7 @@
 			compatible = "ti,tps65090";
 			reg = <0x48>;
 			interrupt-parent = <&gpio>;
-			interrupts = <72 0x04>; /* gpio PJ0 */
+			interrupts = <TEGRA_GPIO(J, 0) IRQ_TYPE_LEVEL_HIGH>;
 
 			vsys1-supply = <&vdd_ac_bat_reg>;
 			vsys2-supply = <&vdd_ac_bat_reg>;
@@ -763,6 +773,11 @@
 			vsys-l1-supply = <&vdd_ac_bat_reg>;
 			vsys-l2-supply = <&vdd_ac_bat_reg>;
 
+			charger: charger {
+				compatible = "ti,tps65090-charger";
+				ti,enable-low-current-chrg;
+			};
+
 			regulators {
 				tps65090_dcdc1_reg: dcdc1 {
 					regulator-name = "vdd-sys-5v0";
@@ -823,12 +838,28 @@
 		};
 	};
 
+	spi@7000da00 {
+		status = "okay";
+		spi-max-frequency = <25000000>;
+		spi-flash@0 {
+			compatible = "winbond,w25q32dw";
+			reg = <0>;
+			spi-max-frequency = <20000000>;
+		};
+	};
+
 	pmc {
 		nvidia,invert-interrupt;
 	};
 
+	ahub {
+		i2s@70080400 {
+			status = "okay";
+		};
+	};
+
 	sdhci@78000400 {
-		cd-gpios = <&gpio 170 1>; /* gpio PV2 */
+		cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
 		bus-width = <4>;
 		status = "okay";
 	};
@@ -873,7 +904,7 @@
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
 			enable-active-high;
-			gpio = <&gpio 61 0>; /* GPIO PH5 */
+			gpio = <&gpio TEGRA_GPIO(H, 5) GPIO_ACTIVE_HIGH>;
 		};
 
 		lcd_bl_en_reg: regulator@2 {
@@ -883,7 +914,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 58 0>; /* GPIO PH2 */
+			gpio = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
 		};
 
 		usb1_vbus_reg: regulator@3 {
@@ -893,7 +924,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 108 0>; /* GPIO PN4 */
+			gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
 			gpio-open-drain;
 			vin-supply = <&tps65090_dcdc1_reg>;
 		};
@@ -905,7 +936,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 86 0>; /* GPIO PK6 */
+			gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
 			gpio-open-drain;
 			vin-supply = <&tps65090_dcdc1_reg>;
 		};
@@ -917,8 +948,32 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 81 0>; /* GPIO PK1 */
+			gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&tps65090_dcdc1_reg>;
 		};
 	};
+
+	sound {
+		compatible = "nvidia,tegra-audio-rt5640-dalmore",
+			     "nvidia,tegra-audio-rt5640";
+		nvidia,model = "NVIDIA Tegra Dalmore";
+
+		nvidia,audio-routing =
+			"Headphones", "HPOR",
+			"Headphones", "HPOL",
+			"Speakers", "SPORP",
+			"Speakers", "SPORN",
+			"Speakers", "SPOLP",
+			"Speakers", "SPOLN";
+
+		nvidia,i2s-controller = <&tegra_i2s1>;
+		nvidia,audio-codec = <&rt5640>;
+
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_HIGH>;
+
+		clocks = <&tegra_car TEGRA114_CLK_PLL_A>,
+			 <&tegra_car TEGRA114_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA114_CLK_EXTERN1>;
+		clock-names = "pll_a", "pll_a_out0", "mclk";
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra114.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra114.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra114.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra114.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,8 @@
-/include/ "skeleton.dtsi"
+#include <dt-bindings/clock/tegra114-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
 
 / {
 	compatible = "nvidia,tegra114";
@@ -19,19 +23,20 @@
 		      <0x50042000 0x1000>,
 		      <0x50044000 0x2000>,
 		      <0x50046000 0x2000>;
-		interrupts = <1 9 0xf04>;
+		interrupts = <GIC_PPI 9
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
 	timer@60005000 {
 		compatible = "nvidia,tegra114-timer", "nvidia,tegra20-timer";
 		reg = <0x60005000 0x400>;
-		interrupts = <0 0 0x04
-			      0 1 0x04
-			      0 41 0x04
-			      0 42 0x04
-			      0 121 0x04
-			      0 122 0x04>;
-		clocks = <&tegra_car 5>;
+		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA114_CLK_TIMER>;
 	};
 
 	tegra_car: clock {
@@ -43,39 +48,39 @@
 	apbdma: dma {
 		compatible = "nvidia,tegra114-apbdma";
 		reg = <0x6000a000 0x1400>;
-		interrupts = <0 104 0x04
-			      0 105 0x04
-			      0 106 0x04
-			      0 107 0x04
-			      0 108 0x04
-			      0 109 0x04
-			      0 110 0x04
-			      0 111 0x04
-			      0 112 0x04
-			      0 113 0x04
-			      0 114 0x04
-			      0 115 0x04
-			      0 116 0x04
-			      0 117 0x04
-			      0 118 0x04
-			      0 119 0x04
-			      0 128 0x04
-			      0 129 0x04
-			      0 130 0x04
-			      0 131 0x04
-			      0 132 0x04
-			      0 133 0x04
-			      0 134 0x04
-			      0 135 0x04
-			      0 136 0x04
-			      0 137 0x04
-			      0 138 0x04
-			      0 139 0x04
-			      0 140 0x04
-			      0 141 0x04
-			      0 142 0x04
-			      0 143 0x04>;
-		clocks = <&tegra_car 34>;
+		interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA114_CLK_APBDMA>;
 	};
 
 	ahb: ahb {
@@ -86,14 +91,14 @@
 	gpio: gpio {
 		compatible = "nvidia,tegra114-gpio", "nvidia,tegra30-gpio";
 		reg = <0x6000d000 0x1000>;
-		interrupts = <0 32 0x04
-			      0 33 0x04
-			      0 34 0x04
-			      0 35 0x04
-			      0 55 0x04
-			      0 87 0x04
-			      0 89 0x04
-			      0 125 0x04>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
 		#gpio-cells = <2>;
 		gpio-controller;
 		#interrupt-cells = <2>;
@@ -118,57 +123,57 @@
 		compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
 		reg = <0x70006000 0x40>;
 		reg-shift = <2>;
-		interrupts = <0 36 0x04>;
+		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 8>;
 		status = "disabled";
-		clocks = <&tegra_car 6>;
+		clocks = <&tegra_car TEGRA114_CLK_UARTA>;
 	};
 
 	uartb: serial@70006040 {
 		compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
 		reg = <0x70006040 0x40>;
 		reg-shift = <2>;
-		interrupts = <0 37 0x04>;
+		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 9>;
 		status = "disabled";
-		clocks = <&tegra_car 192>;
+		clocks = <&tegra_car TEGRA114_CLK_UARTB>;
 	};
 
 	uartc: serial@70006200 {
 		compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
 		reg = <0x70006200 0x100>;
 		reg-shift = <2>;
-		interrupts = <0 46 0x04>;
+		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 10>;
 		status = "disabled";
-		clocks = <&tegra_car 55>;
+		clocks = <&tegra_car TEGRA114_CLK_UARTC>;
 	};
 
 	uartd: serial@70006300 {
 		compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
 		reg = <0x70006300 0x100>;
 		reg-shift = <2>;
-		interrupts = <0 90 0x04>;
+		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 19>;
 		status = "disabled";
-		clocks = <&tegra_car 65>;
+		clocks = <&tegra_car TEGRA114_CLK_UARTD>;
 	};
 
 	pwm: pwm {
 		compatible = "nvidia,tegra114-pwm", "nvidia,tegra20-pwm";
 		reg = <0x7000a000 0x100>;
 		#pwm-cells = <2>;
-		clocks = <&tegra_car 17>;
+		clocks = <&tegra_car TEGRA114_CLK_PWM>;
 		status = "disabled";
 	};
 
 	i2c@7000c000 {
 		compatible = "nvidia,tegra114-i2c";
 		reg = <0x7000c000 0x100>;
-		interrupts = <0 38 0x04>;
+		interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 12>;
+		clocks = <&tegra_car TEGRA114_CLK_I2C1>;
 		clock-names = "div-clk";
 		status = "disabled";
 	};
@@ -176,10 +181,10 @@
 	i2c@7000c400 {
 		compatible = "nvidia,tegra114-i2c";
 		reg = <0x7000c400 0x100>;
-		interrupts = <0 84 0x04>;
+		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 54>;
+		clocks = <&tegra_car TEGRA114_CLK_I2C2>;
 		clock-names = "div-clk";
 		status = "disabled";
 	};
@@ -187,10 +192,10 @@
 	i2c@7000c500 {
 		compatible = "nvidia,tegra114-i2c";
 		reg = <0x7000c500 0x100>;
-		interrupts = <0 92 0x04>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 67>;
+		clocks = <&tegra_car TEGRA114_CLK_I2C3>;
 		clock-names = "div-clk";
 		status = "disabled";
 	};
@@ -198,10 +203,10 @@
 	i2c@7000c700 {
 		compatible = "nvidia,tegra114-i2c";
 		reg = <0x7000c700 0x100>;
-		interrupts = <0 120 0x04>;
+		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 103>;
+		clocks = <&tegra_car TEGRA114_CLK_I2C4>;
 		clock-names = "div-clk";
 		status = "disabled";
 	};
@@ -209,10 +214,10 @@
 	i2c@7000d000 {
 		compatible = "nvidia,tegra114-i2c";
 		reg = <0x7000d000 0x100>;
-		interrupts = <0 53 0x04>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 47>;
+		clocks = <&tegra_car TEGRA114_CLK_I2C5>;
 		clock-names = "div-clk";
 		status = "disabled";
 	};
@@ -220,11 +225,11 @@
 	spi@7000d400 {
 		compatible = "nvidia,tegra114-spi";
 		reg = <0x7000d400 0x200>;
-		interrupts = <0 59 0x04>;
+		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 15>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 41>;
+		clocks = <&tegra_car TEGRA114_CLK_SBC1>;
 		clock-names = "spi";
 		status = "disabled";
 	};
@@ -232,11 +237,11 @@
 	spi@7000d600 {
 		compatible = "nvidia,tegra114-spi";
 		reg = <0x7000d600 0x200>;
-		interrupts = <0 82 0x04>;
+		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 16>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 44>;
+		clocks = <&tegra_car TEGRA114_CLK_SBC2>;
 		clock-names = "spi";
 		status = "disabled";
 	};
@@ -244,11 +249,11 @@
 	spi@7000d800 {
 		compatible = "nvidia,tegra114-spi";
 		reg = <0x7000d800 0x200>;
-		interrupts = <0 83 0x04>;
+		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 17>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 46>;
+		clocks = <&tegra_car TEGRA114_CLK_SBC3>;
 		clock-names = "spi";
 		status = "disabled";
 	};
@@ -256,11 +261,11 @@
 	spi@7000da00 {
 		compatible = "nvidia,tegra114-spi";
 		reg = <0x7000da00 0x200>;
-		interrupts = <0 93 0x04>;
+		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 18>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 68>;
+		clocks = <&tegra_car TEGRA114_CLK_SBC4>;
 		clock-names = "spi";
 		status = "disabled";
 	};
@@ -268,11 +273,11 @@
 	spi@7000dc00 {
 		compatible = "nvidia,tegra114-spi";
 		reg = <0x7000dc00 0x200>;
-		interrupts = <0 94 0x04>;
+		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 27>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 104>;
+		clocks = <&tegra_car TEGRA114_CLK_SBC5>;
 		clock-names = "spi";
 		status = "disabled";
 	};
@@ -280,11 +285,11 @@
 	spi@7000de00 {
 		compatible = "nvidia,tegra114-spi";
 		reg = <0x7000de00 0x200>;
-		interrupts = <0 79 0x04>;
+		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 28>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 105>;
+		clocks = <&tegra_car TEGRA114_CLK_SBC6>;
 		clock-names = "spi";
 		status = "disabled";
 	};
@@ -292,22 +297,22 @@
 	rtc {
 		compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc";
 		reg = <0x7000e000 0x100>;
-		interrupts = <0 2 0x04>;
-		clocks = <&tegra_car 4>;
+		interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA114_CLK_RTC>;
 	};
 
 	kbc {
 		compatible = "nvidia,tegra114-kbc";
 		reg = <0x7000e200 0x100>;
-		interrupts = <0 85 0x04>;
-		clocks = <&tegra_car 36>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA114_CLK_KBC>;
 		status = "disabled";
 	};
 
 	pmc {
 		compatible = "nvidia,tegra114-pmc";
 		reg = <0x7000e400 0x400>;
-		clocks = <&tegra_car 261>, <&clk32k_in>;
+		clocks = <&tegra_car TEGRA114_CLK_PCLK>, <&clk32k_in>;
 		clock-names = "pclk", "clk32k_in";
 	};
 
@@ -322,35 +327,106 @@
 		nvidia,ahb = <&ahb>;
 	};
 
+	ahub {
+		compatible = "nvidia,tegra114-ahub";
+		reg = <0x70080000 0x200>,
+		      <0x70080200 0x100>,
+		      <0x70081000 0x200>;
+		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+		nvidia,dma-request-selector = <&apbdma 1>, <&apbdma 2>,
+			<&apbdma 3>, <&apbdma 4>, <&apbdma 6>, <&apbdma 7>,
+			<&apbdma 12>, <&apbdma 13>, <&apbdma 14>,
+			<&apbdma 29>;
+		clocks = <&tegra_car TEGRA114_CLK_D_AUDIO>,
+			 <&tegra_car TEGRA114_CLK_APBIF>,
+			 <&tegra_car TEGRA114_CLK_I2S0>,
+			 <&tegra_car TEGRA114_CLK_I2S1>,
+			 <&tegra_car TEGRA114_CLK_I2S2>,
+			 <&tegra_car TEGRA114_CLK_I2S3>,
+			 <&tegra_car TEGRA114_CLK_I2S4>,
+			 <&tegra_car TEGRA114_CLK_DAM0>,
+			 <&tegra_car TEGRA114_CLK_DAM1>,
+			 <&tegra_car TEGRA114_CLK_DAM2>,
+			 <&tegra_car TEGRA114_CLK_SPDIF_IN>,
+			 <&tegra_car TEGRA114_CLK_AMX>,
+			 <&tegra_car TEGRA114_CLK_ADX>;
+		clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
+			      "i2s3", "i2s4", "dam0", "dam1", "dam2",
+			      "spdif_in", "amx", "adx";
+		ranges;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		tegra_i2s0: i2s@70080300 {
+			compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+			reg = <0x70080300 0x100>;
+			nvidia,ahub-cif-ids = <4 4>;
+			clocks = <&tegra_car TEGRA114_CLK_I2S0>;
+			status = "disabled";
+		};
+
+		tegra_i2s1: i2s@70080400 {
+			compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+			reg = <0x70080400 0x100>;
+			nvidia,ahub-cif-ids = <5 5>;
+			clocks = <&tegra_car TEGRA114_CLK_I2S1>;
+			status = "disabled";
+		};
+
+		tegra_i2s2: i2s@70080500 {
+			compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+			reg = <0x70080500 0x100>;
+			nvidia,ahub-cif-ids = <6 6>;
+			clocks = <&tegra_car TEGRA114_CLK_I2S2>;
+			status = "disabled";
+		};
+
+		tegra_i2s3: i2s@70080600 {
+			compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+			reg = <0x70080600 0x100>;
+			nvidia,ahub-cif-ids = <7 7>;
+			clocks = <&tegra_car TEGRA114_CLK_I2S3>;
+			status = "disabled";
+		};
+
+		tegra_i2s4: i2s@70080700 {
+			compatible = "nvidia,tegra114-i2s", "nvidia,tegra30-i2s";
+			reg = <0x70080700 0x100>;
+			nvidia,ahub-cif-ids = <8 8>;
+			clocks = <&tegra_car TEGRA114_CLK_I2S4>;
+			status = "disabled";
+		};
+	};
+
 	sdhci@78000000 {
 		compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
 		reg = <0x78000000 0x200>;
-		interrupts = <0 14 0x04>;
-		clocks = <&tegra_car 14>;
+		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA114_CLK_SDMMC1>;
 		status = "disable";
 	};
 
 	sdhci@78000200 {
 		compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
 		reg = <0x78000200 0x200>;
-		interrupts = <0 15 0x04>;
-		clocks = <&tegra_car 9>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA114_CLK_SDMMC2>;
 		status = "disable";
 	};
 
 	sdhci@78000400 {
 		compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
 		reg = <0x78000400 0x200>;
-		interrupts = <0 19 0x04>;
-		clocks = <&tegra_car 69>;
+		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA114_CLK_SDMMC3>;
 		status = "disable";
 	};
 
 	sdhci@78000600 {
 		compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
 		reg = <0x78000600 0x200>;
-		interrupts = <0 31 0x04>;
-		clocks = <&tegra_car 15>;
+		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA114_CLK_SDMMC4>;
 		status = "disable";
 	};
 
@@ -385,9 +461,14 @@
 
 	timer {
 		compatible = "arm,armv7-timer";
-		interrupts = <1 13 0xf08>,
-			     <1 14 0xf08>,
-			     <1 11 0xf08>,
-			     <1 10 0xf08>;
+		interrupts =
+			<GIC_PPI 13
+				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			<GIC_PPI 14
+				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			<GIC_PPI 11
+				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			<GIC_PPI 10
+				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra114-pluto.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra114-pluto.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra114-pluto.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra114-pluto.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra114.dtsi"
+#include "tegra114.dtsi"
 
 / {
 	model = "NVIDIA Tegra114 Pluto evaluation board";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-colibri-512.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-colibri-512.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-colibri-512.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-colibri-512.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-/include/ "tegra20.dtsi"
+#include "tegra20.dtsi"
 
 / {
 	model = "Toradex Colibri T20 512MB";
@@ -14,7 +14,8 @@
 			pll-supply = <&hdmi_pll_reg>;
 
 			nvidia,ddc-i2c-bus = <&i2c_ddc>;
-			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+			nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+				GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -217,7 +218,7 @@
 		pmic: tps6586x@34 {
 			compatible = "ti,tps6586x";
 			reg = <0x34>;
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 
 			ti,system-power-controller;
 
@@ -443,17 +444,26 @@
 
 	ac97: ac97 {
 		status = "okay";
-		nvidia,codec-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
-		nvidia,codec-sync-gpio = <&gpio 120 0>; /* gpio PP0 */
+		nvidia,codec-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+			GPIO_ACTIVE_HIGH>;
+		nvidia,codec-sync-gpio = <&gpio TEGRA_GPIO(P, 0)
+			GPIO_ACTIVE_HIGH>;
 	};
 
 	usb@c5004000 {
 		status = "okay";
-		nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+			GPIO_ACTIVE_LOW>;
+	};
+
+	usb-phy@c5004000 {
+		status = "okay";
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+			GPIO_ACTIVE_LOW>;
 	};
 
 	sdhci@c8000600 {
-		cd-gpios = <&gpio 23 1>; /* gpio PC7 */
+		cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
 	};
 
 	clocks {
@@ -483,7 +493,9 @@
 
 		nvidia,ac97-controller = <&ac97>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+			 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 
@@ -510,7 +522,7 @@
 			enable-active-high;
 			regulator-boot-on;
 			regulator-always-on;
-			gpio = <&gpio 217 0>;
+			gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
 		};
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,8 @@
-/include/ "skeleton.dtsi"
+#include <dt-bindings/clock/tegra20-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
 
 / {
 	compatible = "nvidia,tegra20";
@@ -15,9 +19,9 @@
 	host1x {
 		compatible = "nvidia,tegra20-host1x", "simple-bus";
 		reg = <0x50000000 0x00024000>;
-		interrupts = <0 65 0x04   /* mpcore syncpt */
-			      0 67 0x04>; /* mpcore general */
-		clocks = <&tegra_car 28>;
+		interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+			     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+		clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -27,49 +31,50 @@
 		mpe {
 			compatible = "nvidia,tegra20-mpe";
 			reg = <0x54040000 0x00040000>;
-			interrupts = <0 68 0x04>;
-			clocks = <&tegra_car 60>;
+			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA20_CLK_MPE>;
 		};
 
 		vi {
 			compatible = "nvidia,tegra20-vi";
 			reg = <0x54080000 0x00040000>;
-			interrupts = <0 69 0x04>;
-			clocks = <&tegra_car 100>;
+			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA20_CLK_VI>;
 		};
 
 		epp {
 			compatible = "nvidia,tegra20-epp";
 			reg = <0x540c0000 0x00040000>;
-			interrupts = <0 70 0x04>;
-			clocks = <&tegra_car 19>;
+			interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA20_CLK_EPP>;
 		};
 
 		isp {
 			compatible = "nvidia,tegra20-isp";
 			reg = <0x54100000 0x00040000>;
-			interrupts = <0 71 0x04>;
-			clocks = <&tegra_car 23>;
+			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA20_CLK_ISP>;
 		};
 
 		gr2d {
 			compatible = "nvidia,tegra20-gr2d";
 			reg = <0x54140000 0x00040000>;
-			interrupts = <0 72 0x04>;
-			clocks = <&tegra_car 21>;
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA20_CLK_GR2D>;
 		};
 
 		gr3d {
 			compatible = "nvidia,tegra20-gr3d";
 			reg = <0x54180000 0x00040000>;
-			clocks = <&tegra_car 24>;
+			clocks = <&tegra_car TEGRA20_CLK_GR3D>;
 		};
 
 		dc@54200000 {
 			compatible = "nvidia,tegra20-dc";
 			reg = <0x54200000 0x00040000>;
-			interrupts = <0 73 0x04>;
-			clocks = <&tegra_car 27>, <&tegra_car 121>;
+			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA20_CLK_DISP1>,
+				 <&tegra_car TEGRA20_CLK_PLL_P>;
 			clock-names = "disp1", "parent";
 
 			rgb {
@@ -80,8 +85,9 @@
 		dc@54240000 {
 			compatible = "nvidia,tegra20-dc";
 			reg = <0x54240000 0x00040000>;
-			interrupts = <0 74 0x04>;
-			clocks = <&tegra_car 26>, <&tegra_car 121>;
+			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA20_CLK_DISP2>,
+				 <&tegra_car TEGRA20_CLK_PLL_P>;
 			clock-names = "disp2", "parent";
 
 			rgb {
@@ -92,8 +98,9 @@
 		hdmi {
 			compatible = "nvidia,tegra20-hdmi";
 			reg = <0x54280000 0x00040000>;
-			interrupts = <0 75 0x04>;
-			clocks = <&tegra_car 51>, <&tegra_car 117>;
+			interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA20_CLK_HDMI>,
+				 <&tegra_car TEGRA20_CLK_PLL_D_OUT0>;
 			clock-names = "hdmi", "parent";
 			status = "disabled";
 		};
@@ -101,15 +108,15 @@
 		tvo {
 			compatible = "nvidia,tegra20-tvo";
 			reg = <0x542c0000 0x00040000>;
-			interrupts = <0 76 0x04>;
-			clocks = <&tegra_car 102>;
+			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA20_CLK_TVO>;
 			status = "disabled";
 		};
 
 		dsi {
 			compatible = "nvidia,tegra20-dsi";
 			reg = <0x54300000 0x00040000>;
-			clocks = <&tegra_car 48>;
+			clocks = <&tegra_car TEGRA20_CLK_DSI>;
 			status = "disabled";
 		};
 	};
@@ -117,8 +124,9 @@
 	timer@50004600 {
 		compatible = "arm,cortex-a9-twd-timer";
 		reg = <0x50040600 0x20>;
-		interrupts = <1 13 0x304>;
-		clocks = <&tegra_car 132>;
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+		clocks = <&tegra_car TEGRA20_CLK_TWD>;
 	};
 
 	intc: interrupt-controller {
@@ -141,11 +149,11 @@
 	timer@60005000 {
 		compatible = "nvidia,tegra20-timer";
 		reg = <0x60005000 0x60>;
-		interrupts = <0 0 0x04
-			      0 1 0x04
-			      0 41 0x04
-			      0 42 0x04>;
-		clocks = <&tegra_car 5>;
+		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA20_CLK_TIMER>;
 	};
 
 	tegra_car: clock {
@@ -157,23 +165,23 @@
 	apbdma: dma {
 		compatible = "nvidia,tegra20-apbdma";
 		reg = <0x6000a000 0x1200>;
-		interrupts = <0 104 0x04
-			      0 105 0x04
-			      0 106 0x04
-			      0 107 0x04
-			      0 108 0x04
-			      0 109 0x04
-			      0 110 0x04
-			      0 111 0x04
-			      0 112 0x04
-			      0 113 0x04
-			      0 114 0x04
-			      0 115 0x04
-			      0 116 0x04
-			      0 117 0x04
-			      0 118 0x04
-			      0 119 0x04>;
-		clocks = <&tegra_car 34>;
+		interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA20_CLK_APBDMA>;
 	};
 
 	ahb {
@@ -184,13 +192,13 @@
 	gpio: gpio {
 		compatible = "nvidia,tegra20-gpio";
 		reg = <0x6000d000 0x1000>;
-		interrupts = <0 32 0x04
-			      0 33 0x04
-			      0 34 0x04
-			      0 35 0x04
-			      0 55 0x04
-			      0 87 0x04
-			      0 89 0x04>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
 		#gpio-cells = <2>;
 		gpio-controller;
 		#interrupt-cells = <2>;
@@ -213,27 +221,27 @@
 	tegra_ac97: ac97 {
 		compatible = "nvidia,tegra20-ac97";
 		reg = <0x70002000 0x200>;
-		interrupts = <0 81 0x04>;
+		interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 12>;
-		clocks = <&tegra_car 3>;
+		clocks = <&tegra_car TEGRA20_CLK_AC97>;
 		status = "disabled";
 	};
 
 	tegra_i2s1: i2s@70002800 {
 		compatible = "nvidia,tegra20-i2s";
 		reg = <0x70002800 0x200>;
-		interrupts = <0 13 0x04>;
+		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 2>;
-		clocks = <&tegra_car 11>;
+		clocks = <&tegra_car TEGRA20_CLK_I2S1>;
 		status = "disabled";
 	};
 
 	tegra_i2s2: i2s@70002a00 {
 		compatible = "nvidia,tegra20-i2s";
 		reg = <0x70002a00 0x200>;
-		interrupts = <0 3 0x04>;
+		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 1>;
-		clocks = <&tegra_car 18>;
+		clocks = <&tegra_car TEGRA20_CLK_I2S2>;
 		status = "disabled";
 	};
 
@@ -248,9 +256,9 @@
 		compatible = "nvidia,tegra20-uart";
 		reg = <0x70006000 0x40>;
 		reg-shift = <2>;
-		interrupts = <0 36 0x04>;
+		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 8>;
-		clocks = <&tegra_car 6>;
+		clocks = <&tegra_car TEGRA20_CLK_UARTA>;
 		status = "disabled";
 	};
 
@@ -258,9 +266,9 @@
 		compatible = "nvidia,tegra20-uart";
 		reg = <0x70006040 0x40>;
 		reg-shift = <2>;
-		interrupts = <0 37 0x04>;
+		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 9>;
-		clocks = <&tegra_car 96>;
+		clocks = <&tegra_car TEGRA20_CLK_UARTB>;
 		status = "disabled";
 	};
 
@@ -268,9 +276,9 @@
 		compatible = "nvidia,tegra20-uart";
 		reg = <0x70006200 0x100>;
 		reg-shift = <2>;
-		interrupts = <0 46 0x04>;
+		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 10>;
-		clocks = <&tegra_car 55>;
+		clocks = <&tegra_car TEGRA20_CLK_UARTC>;
 		status = "disabled";
 	};
 
@@ -278,9 +286,9 @@
 		compatible = "nvidia,tegra20-uart";
 		reg = <0x70006300 0x100>;
 		reg-shift = <2>;
-		interrupts = <0 90 0x04>;
+		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 19>;
-		clocks = <&tegra_car 65>;
+		clocks = <&tegra_car TEGRA20_CLK_UARTD>;
 		status = "disabled";
 	};
 
@@ -288,9 +296,9 @@
 		compatible = "nvidia,tegra20-uart";
 		reg = <0x70006400 0x100>;
 		reg-shift = <2>;
-		interrupts = <0 91 0x04>;
+		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 20>;
-		clocks = <&tegra_car 66>;
+		clocks = <&tegra_car TEGRA20_CLK_UARTE>;
 		status = "disabled";
 	};
 
@@ -298,24 +306,25 @@
 		compatible = "nvidia,tegra20-pwm";
 		reg = <0x7000a000 0x100>;
 		#pwm-cells = <2>;
-		clocks = <&tegra_car 17>;
+		clocks = <&tegra_car TEGRA20_CLK_PWM>;
 		status = "disabled";
 	};
 
 	rtc {
 		compatible = "nvidia,tegra20-rtc";
 		reg = <0x7000e000 0x100>;
-		interrupts = <0 2 0x04>;
-		clocks = <&tegra_car 4>;
+		interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA20_CLK_RTC>;
 	};
 
 	i2c@7000c000 {
 		compatible = "nvidia,tegra20-i2c";
 		reg = <0x7000c000 0x100>;
-		interrupts = <0 38 0x04>;
+		interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 12>, <&tegra_car 124>;
+		clocks = <&tegra_car TEGRA20_CLK_I2C1>,
+			 <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 		status = "disabled";
 	};
@@ -323,21 +332,22 @@
 	spi@7000c380 {
 		compatible = "nvidia,tegra20-sflash";
 		reg = <0x7000c380 0x80>;
-		interrupts = <0 39 0x04>;
+		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 11>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 43>;
+		clocks = <&tegra_car TEGRA20_CLK_SPI>;
 		status = "disabled";
 	};
 
 	i2c@7000c400 {
 		compatible = "nvidia,tegra20-i2c";
 		reg = <0x7000c400 0x100>;
-		interrupts = <0 84 0x04>;
+		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 54>, <&tegra_car 124>;
+		clocks = <&tegra_car TEGRA20_CLK_I2C2>,
+			 <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 		status = "disabled";
 	};
@@ -345,10 +355,11 @@
 	i2c@7000c500 {
 		compatible = "nvidia,tegra20-i2c";
 		reg = <0x7000c500 0x100>;
-		interrupts = <0 92 0x04>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 67>, <&tegra_car 124>;
+		clocks = <&tegra_car TEGRA20_CLK_I2C3>,
+			 <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 		status = "disabled";
 	};
@@ -356,10 +367,11 @@
 	i2c@7000d000 {
 		compatible = "nvidia,tegra20-i2c-dvc";
 		reg = <0x7000d000 0x200>;
-		interrupts = <0 53 0x04>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 47>, <&tegra_car 124>;
+		clocks = <&tegra_car TEGRA20_CLK_DVC>,
+			 <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 		status = "disabled";
 	};
@@ -367,59 +379,59 @@
 	spi@7000d400 {
 		compatible = "nvidia,tegra20-slink";
 		reg = <0x7000d400 0x200>;
-		interrupts = <0 59 0x04>;
+		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 15>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 41>;
+		clocks = <&tegra_car TEGRA20_CLK_SBC1>;
 		status = "disabled";
 	};
 
 	spi@7000d600 {
 		compatible = "nvidia,tegra20-slink";
 		reg = <0x7000d600 0x200>;
-		interrupts = <0 82 0x04>;
+		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 16>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 44>;
+		clocks = <&tegra_car TEGRA20_CLK_SBC2>;
 		status = "disabled";
 	};
 
 	spi@7000d800 {
 		compatible = "nvidia,tegra20-slink";
 		reg = <0x7000d800 0x200>;
-		interrupts = <0 83 0x04>;
+		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 17>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 46>;
+		clocks = <&tegra_car TEGRA20_CLK_SBC3>;
 		status = "disabled";
 	};
 
 	spi@7000da00 {
 		compatible = "nvidia,tegra20-slink";
 		reg = <0x7000da00 0x200>;
-		interrupts = <0 93 0x04>;
+		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 18>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 68>;
+		clocks = <&tegra_car TEGRA20_CLK_SBC4>;
 		status = "disabled";
 	};
 
 	kbc {
 		compatible = "nvidia,tegra20-kbc";
 		reg = <0x7000e200 0x100>;
-		interrupts = <0 85 0x04>;
-		clocks = <&tegra_car 36>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA20_CLK_KBC>;
 		status = "disabled";
 	};
 
 	pmc {
 		compatible = "nvidia,tegra20-pmc";
 		reg = <0x7000e400 0x400>;
-		clocks = <&tegra_car 110>, <&clk32k_in>;
+		clocks = <&tegra_car TEGRA20_CLK_PCLK>, <&clk32k_in>;
 		clock-names = "pclk", "clk32k_in";
 	};
 
@@ -427,7 +439,7 @@
 		compatible = "nvidia,tegra20-mc";
 		reg = <0x7000f000 0x024
 		       0x7000f03c 0x3c4>;
-		interrupts = <0 77 0x04>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
 	iommu {
@@ -446,89 +458,114 @@
 	usb@c5000000 {
 		compatible = "nvidia,tegra20-ehci", "usb-ehci";
 		reg = <0xc5000000 0x4000>;
-		interrupts = <0 20 0x04>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 		phy_type = "utmi";
 		nvidia,has-legacy-mode;
-		clocks = <&tegra_car 22>;
+		clocks = <&tegra_car TEGRA20_CLK_USBD>;
 		nvidia,needs-double-reset;
 		nvidia,phy = <&phy1>;
 		status = "disabled";
 	};
 
-	phy1: usb-phy@c5000400 {
+	phy1: usb-phy@c5000000 {
 		compatible = "nvidia,tegra20-usb-phy";
-		reg = <0xc5000400 0x3c00>;
+		reg = <0xc5000000 0x4000 0xc5000000 0x4000>;
 		phy_type = "utmi";
+		clocks = <&tegra_car TEGRA20_CLK_USBD>,
+			 <&tegra_car TEGRA20_CLK_PLL_U>,
+			 <&tegra_car TEGRA20_CLK_CLK_M>,
+			 <&tegra_car TEGRA20_CLK_USBD>;
+		clock-names = "reg", "pll_u", "timer", "utmi-pads";
 		nvidia,has-legacy-mode;
-		clocks = <&tegra_car 22>, <&tegra_car 127>;
-		clock-names = "phy", "pll_u";
+		hssync_start_delay = <9>;
+		idle_wait_delay = <17>;
+		elastic_limit = <16>;
+		term_range_adj = <6>;
+		xcvr_setup = <9>;
+		xcvr_lsfslew = <1>;
+		xcvr_lsrslew = <1>;
+		status = "disabled";
 	};
 
 	usb@c5004000 {
 		compatible = "nvidia,tegra20-ehci", "usb-ehci";
 		reg = <0xc5004000 0x4000>;
-		interrupts = <0 21 0x04>;
+		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
 		phy_type = "ulpi";
-		clocks = <&tegra_car 58>;
+		clocks = <&tegra_car TEGRA20_CLK_USB2>;
 		nvidia,phy = <&phy2>;
 		status = "disabled";
 	};
 
-	phy2: usb-phy@c5004400 {
+	phy2: usb-phy@c5004000 {
 		compatible = "nvidia,tegra20-usb-phy";
-		reg = <0xc5004400 0x3c00>;
+		reg = <0xc5004000 0x4000>;
 		phy_type = "ulpi";
-		clocks = <&tegra_car 93>, <&tegra_car 127>;
-		clock-names = "phy", "pll_u";
+		clocks = <&tegra_car TEGRA20_CLK_USB2>,
+			 <&tegra_car TEGRA20_CLK_PLL_U>,
+			 <&tegra_car TEGRA20_CLK_CDEV2>;
+		clock-names = "reg", "pll_u", "ulpi-link";
+		status = "disabled";
 	};
 
 	usb@c5008000 {
 		compatible = "nvidia,tegra20-ehci", "usb-ehci";
 		reg = <0xc5008000 0x4000>;
-		interrupts = <0 97 0x04>;
+		interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
 		phy_type = "utmi";
-		clocks = <&tegra_car 59>;
+		clocks = <&tegra_car TEGRA20_CLK_USB3>;
 		nvidia,phy = <&phy3>;
 		status = "disabled";
 	};
 
-	phy3: usb-phy@c5008400 {
+	phy3: usb-phy@c5008000 {
 		compatible = "nvidia,tegra20-usb-phy";
-		reg = <0xc5008400 0x3c00>;
+		reg = <0xc5008000 0x4000 0xc5000000 0x4000>;
 		phy_type = "utmi";
-		clocks = <&tegra_car 22>, <&tegra_car 127>;
-		clock-names = "phy", "pll_u";
+		clocks = <&tegra_car TEGRA20_CLK_USB3>,
+			 <&tegra_car TEGRA20_CLK_PLL_U>,
+			 <&tegra_car TEGRA20_CLK_CLK_M>,
+			 <&tegra_car TEGRA20_CLK_USBD>;
+		clock-names = "reg", "pll_u", "timer", "utmi-pads";
+		hssync_start_delay = <9>;
+		idle_wait_delay = <17>;
+		elastic_limit = <16>;
+		term_range_adj = <6>;
+		xcvr_setup = <9>;
+		xcvr_lsfslew = <2>;
+		xcvr_lsrslew = <2>;
+		status = "disabled";
 	};
 
 	sdhci@c8000000 {
 		compatible = "nvidia,tegra20-sdhci";
 		reg = <0xc8000000 0x200>;
-		interrupts = <0 14 0x04>;
-		clocks = <&tegra_car 14>;
+		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA20_CLK_SDMMC1>;
 		status = "disabled";
 	};
 
 	sdhci@c8000200 {
 		compatible = "nvidia,tegra20-sdhci";
 		reg = <0xc8000200 0x200>;
-		interrupts = <0 15 0x04>;
-		clocks = <&tegra_car 9>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA20_CLK_SDMMC2>;
 		status = "disabled";
 	};
 
 	sdhci@c8000400 {
 		compatible = "nvidia,tegra20-sdhci";
 		reg = <0xc8000400 0x200>;
-		interrupts = <0 19 0x04>;
-		clocks = <&tegra_car 69>;
+		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA20_CLK_SDMMC3>;
 		status = "disabled";
 	};
 
 	sdhci@c8000600 {
 		compatible = "nvidia,tegra20-sdhci";
 		reg = <0xc8000600 0x200>;
-		interrupts = <0 31 0x04>;
-		clocks = <&tegra_car 15>;
+		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA20_CLK_SDMMC4>;
 		status = "disabled";
 	};
 
@@ -551,7 +588,7 @@
 
 	pmu {
 		compatible = "arm,cortex-a9-pmu";
-		interrupts = <0 56 0x04
-			      0 57 0x04>;
+		interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-harmony.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-harmony.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-harmony.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-harmony.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20.dtsi"
+#include "tegra20.dtsi"
 
 / {
 	model = "NVIDIA Tegra20 Harmony evaluation board";
@@ -18,7 +18,8 @@
 			pll-supply = <&hdmi_pll_reg>;
 
 			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
-			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+			nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+				GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -262,7 +263,7 @@
 			compatible = "wlf,wm8903";
 			reg = <0x1a>;
 			interrupt-parent = <&gpio>;
-			interrupts = <187 0x04>;
+			interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -290,7 +291,7 @@
 		pmic: tps6586x@34 {
 			compatible = "ti,tps6586x";
 			reg = <0x34>;
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 
 			ti,system-power-controller;
 
@@ -428,32 +429,43 @@
 		status = "okay";
 	};
 
+	usb-phy@c5000000 {
+		status = "okay";
+	};
+
 	usb@c5004000 {
 		status = "okay";
-		nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+			GPIO_ACTIVE_LOW>;
+	};
+
+	usb-phy@c5004000 {
+		status = "okay";
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+			GPIO_ACTIVE_LOW>;
 	};
 
 	usb@c5008000 {
 		status = "okay";
 	};
 
-	usb-phy@c5004400 {
-		nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+	usb-phy@c5008000 {
+		status = "okay";
 	};
 
 	sdhci@c8000200 {
 		status = "okay";
-		cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-		wp-gpios = <&gpio 57 0>; /* gpio PH1 */
-		power-gpios = <&gpio 155 0>; /* gpio PT3 */
+		cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+		power-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 	};
 
 	sdhci@c8000600 {
 		status = "okay";
-		cd-gpios = <&gpio 58 1>; /* gpio PH2 */
-		wp-gpios = <&gpio 59 0>; /* gpio PH3 */
-		power-gpios = <&gpio 70 0>; /* gpio PI6 */
+		cd-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
+		power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
 		bus-width = <8>;
 	};
 
@@ -475,7 +487,7 @@
 
 		power {
 			label = "Power";
-			gpios = <&gpio 170 1>; /* gpio PV2, active low */
+			gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
 			linux,code = <116>; /* KEY_POWER */
 			gpio-key,wakeup;
 		};
@@ -618,7 +630,7 @@
 			regulator-name = "vdd_1v5";
 			regulator-min-microvolt = <1500000>;
 			regulator-max-microvolt = <1500000>;
-			gpio = <&pmic 0 0>;
+			gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
 		};
 
 		regulator@2 {
@@ -627,7 +639,7 @@
 			regulator-name = "vdd_1v2";
 			regulator-min-microvolt = <1200000>;
 			regulator-max-microvolt = <1200000>;
-			gpio = <&pmic 1 0>;
+			gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
 			enable-active-high;
 		};
 
@@ -637,7 +649,7 @@
 			regulator-name = "vdd_1v05";
 			regulator-min-microvolt = <1050000>;
 			regulator-max-microvolt = <1050000>;
-			gpio = <&pmic 2 0>;
+			gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
 			enable-active-high;
 			/* Hack until board-harmony-pcie.c is removed */
 			status = "disabled";
@@ -649,7 +661,7 @@
 			regulator-name = "vdd_pnl";
 			regulator-min-microvolt = <2800000>;
 			regulator-max-microvolt = <2800000>;
-			gpio = <&gpio 22 0>; /* gpio PC6 */
+			gpio = <&gpio TEGRA_GPIO(C, 6) GPIO_ACTIVE_HIGH>;
 			enable-active-high;
 		};
 
@@ -659,7 +671,7 @@
 			regulator-name = "vdd_bl";
 			regulator-min-microvolt = <2800000>;
 			regulator-max-microvolt = <2800000>;
-			gpio = <&gpio 176 0>; /* gpio PW0 */
+			gpio = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>;
 			enable-active-high;
 		};
 	};
@@ -682,12 +694,17 @@
 		nvidia,i2s-controller = <&tegra_i2s1>;
 		nvidia,audio-codec = <&wm8903>;
 
-		nvidia,spkr-en-gpios = <&wm8903 2 0>;
-		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
-		nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
-		nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+		nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2)
+			GPIO_ACTIVE_HIGH>;
+		nvidia,int-mic-en-gpios = <&gpio TEGRA_GPIO(X, 0)
+			GPIO_ACTIVE_HIGH>;
+		nvidia,ext-mic-en-gpios = <&gpio TEGRA_GPIO(X, 1)
+			GPIO_ACTIVE_HIGH>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+			 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-iris-512.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-iris-512.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-iris-512.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-iris-512.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20-colibri-512.dtsi"
+#include "tegra20-colibri-512.dtsi"
 
 / {
 	model = "Toradex Colibri T20 512MB on Iris";
@@ -38,13 +38,20 @@
 
 	usb@c5000000 {
 		status = "okay";
-		dr_mode = "otg";
+	};
+
+	usb-phy@c5000000 {
+		status = "okay";
 	};
 
 	usb@c5008000 {
 		status = "okay";
 	};
 
+	usb-phy@c5008000 {
+		status = "okay";
+	};
+
 	serial@70006000 {
 		status = "okay";
 	};
@@ -73,7 +80,7 @@
 			regulator-max-microvolt = <5000000>;
 			regulator-boot-on;
 			regulator-always-on;
-			gpio = <&gpio 178 0>;
+			gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
 		};
 
 		vcc_sd_reg: regulator@1 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-medcom-wide.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-medcom-wide.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-medcom-wide.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-medcom-wide.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20-tamonten.dtsi"
+#include "tegra20-tamonten.dtsi"
 
 / {
 	model = "Avionic Design Medcom-Wide board";
@@ -15,7 +15,7 @@
 			compatible = "wlf,wm8903";
 			reg = <0x1a>;
 			interrupt-parent = <&gpio>;
-			interrupts = <187 0x04>;
+			interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -56,10 +56,12 @@
 		nvidia,i2s-controller = <&tegra_i2s1>;
 		nvidia,audio-codec = <&wm8903>;
 
-		nvidia,spkr-en-gpios = <&wm8903 2 0>;
-		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+		nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+			 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-paz00.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-paz00.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-paz00.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-paz00.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20.dtsi"
+#include "tegra20.dtsi"
 
 / {
 	model = "Toshiba AC100 / Dynabook AZ";
@@ -18,7 +18,8 @@
 			pll-supply = <&hdmi_pll_reg>;
 
 			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
-			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+			nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+				GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -270,13 +271,14 @@
 	nvec {
 		compatible = "nvidia,nvec";
 		reg = <0x7000c500 0x100>;
-		interrupts = <0 92 0x04>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clock-frequency = <80000>;
-		request-gpios = <&gpio 170 0>; /* gpio PV2 */
+		request-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
 		slave-addr = <138>;
-		clocks = <&tegra_car 67>, <&tegra_car 124>;
+		clocks = <&tegra_car TEGRA20_CLK_I2C3>,
+		       	 <&tegra_car TEGRA20_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 	};
 
@@ -287,7 +289,7 @@
 		pmic: tps6586x@34 {
 			compatible = "ti,tps6586x";
 			reg = <0x34>;
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 
 			#gpio-cells = <2>;
 			gpio-controller;
@@ -427,24 +429,35 @@
 		status = "okay";
 	};
 
+	usb-phy@c5000000 {
+		status = "okay";
+	};
+
 	usb@c5004000 {
 		status = "okay";
-		nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+			GPIO_ACTIVE_LOW>;
+	};
+
+	usb-phy@c5004000 {
+		status = "okay";
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+			GPIO_ACTIVE_LOW>;
 	};
 
 	usb@c5008000 {
 		status = "okay";
 	};
 
-	usb-phy@c5004400 {
-		nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
+	usb-phy@c5008000 {
+		status = "okay";
 	};
 
 	sdhci@c8000000 {
 		status = "okay";
-		cd-gpios = <&gpio 173 1>; /* gpio PV5 */
-		wp-gpios = <&gpio 57 0>;  /* gpio PH1 */
-		power-gpios = <&gpio 169 0>; /* gpio PV1 */
+		cd-gpios = <&gpio TEGRA_GPIO(V, 5) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+		power-gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 	};
 
@@ -472,7 +485,7 @@
 
 		power {
 			label = "Power";
-			gpios = <&gpio 79 1>; /* gpio PJ7, active low */
+			gpios = <&gpio TEGRA_GPIO(J, 7) GPIO_ACTIVE_LOW>;
 			linux,code = <116>; /* KEY_POWER */
 			gpio-key,wakeup;
 		};
@@ -483,7 +496,7 @@
 
 		wifi {
 			label = "wifi-led";
-			gpios = <&gpio 24 0>; /* gpio PD0 */
+			gpios = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "rfkill0";
 		};
 	};
@@ -520,9 +533,12 @@
 
 		nvidia,audio-codec = <&alc5632>;
 		nvidia,i2s-controller = <&tegra_i2s1>;
-		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2)
+			GPIO_ACTIVE_HIGH>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+		       	 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-plutux.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-plutux.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-plutux.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-plutux.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20-tamonten.dtsi"
+#include "tegra20-tamonten.dtsi"
 
 / {
 	model = "Avionic Design Plutux board";
@@ -17,7 +17,7 @@
 			compatible = "wlf,wm8903";
 			reg = <0x1a>;
 			interrupt-parent = <&gpio>;
-			interrupts = <187 0x04>;
+			interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -50,10 +50,12 @@
 		nvidia,i2s-controller = <&tegra_i2s1>;
 		nvidia,audio-codec = <&wm8903>;
 
-		nvidia,spkr-en-gpios = <&wm8903 2 0>;
-		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+		nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+			 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-seaboard.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-seaboard.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-seaboard.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-seaboard.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20.dtsi"
+#include "tegra20.dtsi"
 
 / {
 	model = "NVIDIA Seaboard";
@@ -18,7 +18,8 @@
 			pll-supply = <&hdmi_pll_reg>;
 
 			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
-			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+			nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+				GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -313,7 +314,7 @@
 			compatible = "wlf,wm8903";
 			reg = <0x1a>;
 			interrupt-parent = <&gpio>;
-			interrupts = <187 0x04>;
+			interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -328,14 +329,14 @@
 			compatible = "isil,isl29018";
 			reg = <0x44>;
 			interrupt-parent = <&gpio>;
-			interrupts = <202 0x04>; /* GPIO PZ2 */
+			interrupts = <TEGRA_GPIO(Z, 2) IRQ_TYPE_LEVEL_HIGH>;
 		};
 
 		gyrometer@68 {
 			compatible = "invn,mpu3050";
 			reg = <0x68>;
 			interrupt-parent = <&gpio>;
-			interrupts = <204 0x04>; /* gpio PZ4 */
+			interrupts = <TEGRA_GPIO(Z, 4) IRQ_TYPE_LEVEL_HIGH>;
 		};
 	};
 
@@ -388,7 +389,7 @@
 		pmic: tps6586x@34 {
 			compatible = "ti,tps6586x";
 			reg = <0x34>;
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 
 			ti,system-power-controller;
 
@@ -511,7 +512,7 @@
 			compatible = "ak,ak8975";
 			reg = <0xc>;
 			interrupt-parent = <&gpio>;
-			interrupts = <109 0x04>; /* gpio PN5 */
+			interrupts = <TEGRA_GPIO(N, 5) IRQ_TYPE_LEVEL_HIGH>;
 		};
 	};
 
@@ -565,35 +566,48 @@
 
 	usb@c5000000 {
 		status = "okay";
-		nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
+		nvidia,vbus-gpio = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
+		dr_mode = "otg";
+	};
+
+	usb-phy@c5000000 {
+		status = "okay";
+		vbus-supply = <&vbus_reg>;
 		dr_mode = "otg";
 	};
 
 	usb@c5004000 {
 		status = "okay";
-		nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+			GPIO_ACTIVE_LOW>;
+	};
+
+	usb-phy@c5004000 {
+		status = "okay";
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+			GPIO_ACTIVE_LOW>;
 	};
 
 	usb@c5008000 {
 		status = "okay";
 	};
 
-	usb-phy@c5004400 {
-		nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+	usb-phy@c5008000 {
+		status = "okay";
 	};
 
 	sdhci@c8000000 {
 		status = "okay";
-		power-gpios = <&gpio 86 0>; /* gpio PK6 */
+		power-gpios = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 		keep-power-in-suspend;
 	};
 
 	sdhci@c8000400 {
 		status = "okay";
-		cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-		wp-gpios = <&gpio 57 0>; /* gpio PH1 */
-		power-gpios = <&gpio 70 0>; /* gpio PI6 */
+		cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+		power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 	};
 
@@ -621,14 +635,14 @@
 
 		power {
 			label = "Power";
-			gpios = <&gpio 170 1>; /* gpio PV2, active low */
+			gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
 			linux,code = <116>; /* KEY_POWER */
 			gpio-key,wakeup;
 		};
 
 		lid {
 			label = "Lid";
-			gpios = <&gpio 23 0>; /* gpio PC7 */
+			gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_HIGH>;
 			linux,input-type = <5>; /* EV_SW */
 			linux,code = <0>; /* SW_LID */
 			debounce-interval = <1>;
@@ -795,7 +809,7 @@
 			regulator-name = "vdd_1v5";
 			regulator-min-microvolt = <1500000>;
 			regulator-max-microvolt = <1500000>;
-			gpio = <&pmic 0 0>;
+			gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
 		};
 
 		regulator@2 {
@@ -804,8 +818,20 @@
 			regulator-name = "vdd_1v2";
 			regulator-min-microvolt = <1200000>;
 			regulator-max-microvolt = <1200000>;
-			gpio = <&pmic 1 0>;
+			gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+		};
+
+		vbus_reg: regulator@3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+			regulator-name = "vdd_vbus_wup1";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
 			enable-active-high;
+			gpio = <&gpio 24 0>; /* PD0 */
+			regulator-always-on;
+			regulator-boot-on;
 		};
 	};
 
@@ -827,10 +853,12 @@
 		nvidia,i2s-controller = <&tegra_i2s1>;
 		nvidia,audio-codec = <&wm8903>;
 
-		nvidia,spkr-en-gpios = <&wm8903 2 0>;
-		nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
+		nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(X, 1) GPIO_ACTIVE_HIGH>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+			 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-tamonten.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-tamonten.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-tamonten.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-tamonten.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-/include/ "tegra20.dtsi"
+#include "tegra20.dtsi"
 
 / {
 	model = "Avionic Design Tamonten SOM";
@@ -14,7 +14,8 @@
 			pll-supply = <&hdmi_pll_reg>;
 
 			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
-			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+			nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+				GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -321,7 +322,7 @@
 		pmic: tps6586x@34 {
 			compatible = "ti,tps6586x";
 			reg = <0x34>;
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 
 			ti,system-power-controller;
 
@@ -470,9 +471,13 @@
 		status = "okay";
 	};
 
+	usb-phy@c5008000 {
+		status = "okay";
+	};
+
 	sdhci@c8000600 {
-		cd-gpios = <&gpio 58 1>; /* gpio PH2 */
-		wp-gpios = <&gpio 59 0>; /* gpio PH3 */
+		cd-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 		status = "okay";
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-tec.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-tec.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-tec.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-tec.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20-tamonten.dtsi"
+#include "tegra20-tamonten.dtsi"
 
 / {
 	model = "Avionic Design Tamonten Evaluation Carrier";
@@ -17,7 +17,7 @@
 			compatible = "wlf,wm8903";
 			reg = <0x1a>;
 			interrupt-parent = <&gpio>;
-			interrupts = <187 0x04>;
+			interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -50,10 +50,13 @@
 		nvidia,i2s-controller = <&tegra_i2s1>;
 		nvidia,audio-codec = <&wm8903>;
 
-		nvidia,spkr-en-gpios = <&wm8903 2 0>;
-		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+		nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2)
+			GPIO_ACTIVE_HIGH>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+			 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-trimslice.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-trimslice.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-trimslice.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-trimslice.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20.dtsi"
+#include "tegra20.dtsi"
 
 / {
 	model = "Compulab TrimSlice board";
@@ -18,7 +18,8 @@
 			pll-supply = <&hdmi_pll_reg>;
 
 			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
-			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+			nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+				GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -311,20 +312,32 @@
 
 	usb@c5000000 {
 		status = "okay";
-		nvidia,vbus-gpio = <&gpio 170 0>; /* gpio PV2 */
+		nvidia,vbus-gpio = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+	};
+
+	usb-phy@c5000000 {
+		status = "okay";
+		vbus-supply = <&vbus_reg>;
 	};
 
 	usb@c5004000 {
 		status = "okay";
-		nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+			GPIO_ACTIVE_LOW>;
+	};
+
+	usb-phy@c5004000 {
+		status = "okay";
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+			GPIO_ACTIVE_LOW>;
 	};
 
 	usb@c5008000 {
 		status = "okay";
 	};
 
-	usb-phy@c5004400 {
-		nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
+	usb-phy@c5008000 {
+		status = "okay";
 	};
 
 	sdhci@c8000000 {
@@ -334,8 +347,8 @@
 
 	sdhci@c8000600 {
 		status = "okay";
-		cd-gpios = <&gpio 121 1>; /* gpio PP1 */
-		wp-gpios = <&gpio 122 0>; /* gpio PP2 */
+		cd-gpios = <&gpio TEGRA_GPIO(P, 1) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 	};
 
@@ -357,7 +370,7 @@
 
 		power {
 			label = "Power";
-			gpios = <&gpio 190 1>; /* gpio PX6, active low */
+			gpios = <&gpio TEGRA_GPIO(X, 6) GPIO_ACTIVE_LOW>;
 			linux,code = <116>; /* KEY_POWER */
 			gpio-key,wakeup;
 		};
@@ -365,7 +378,7 @@
 
 	poweroff {
 		compatible = "gpio-poweroff";
-		gpios = <&gpio 191 1>; /* gpio PX7, active low */
+		gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_LOW>;
 	};
 
 	regulators {
@@ -390,6 +403,18 @@
 			regulator-max-microvolt = <1800000>;
 			regulator-always-on;
 		};
+
+		vbus_reg: regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "usb1_vbus";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			gpio = <&gpio 170 0>; /* PV2 */
+			regulator-always-on;
+			regulator-boot-on;
+		};
 	};
 
 	sound {
@@ -397,7 +422,9 @@
 		nvidia,i2s-controller = <&tegra_i2s1>;
 		nvidia,audio-codec = <&codec>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+			 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-ventana.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-ventana.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-ventana.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-ventana.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20.dtsi"
+#include "tegra20.dtsi"
 
 / {
 	model = "NVIDIA Tegra20 Ventana evaluation board";
@@ -18,7 +18,8 @@
 			pll-supply = <&hdmi_pll_reg>;
 
 			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
-			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+			nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+				GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -310,7 +311,7 @@
 			compatible = "wlf,wm8903";
 			reg = <0x1a>;
 			interrupt-parent = <&gpio>;
-			interrupts = <187 0x04>;
+			interrupts = <TEGRA_GPIO(X, 3) IRQ_TYPE_LEVEL_HIGH>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -325,7 +326,7 @@
 			compatible = "isil,isl29018";
 			reg = <0x44>;
 			interrupt-parent = <&gpio>;
-			interrupts = <202 0x04>; /*gpio PZ2 */
+			interrupts = <TEGRA_GPIO(Z, 2) IRQ_TYPE_LEVEL_HIGH>;
 		};
 	};
 
@@ -371,7 +372,7 @@
 		pmic: tps6586x@34 {
 			compatible = "ti,tps6586x";
 			reg = <0x34>;
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 
 			ti,system-power-controller;
 
@@ -505,31 +506,42 @@
 		status = "okay";
 	};
 
+	usb-phy@c5000000 {
+		status = "okay";
+	};
+
 	usb@c5004000 {
 		status = "okay";
-		nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+			GPIO_ACTIVE_LOW>;
+	};
+
+	usb-phy@c5004000 {
+		status = "okay";
+		nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+			GPIO_ACTIVE_LOW>;
 	};
 
 	usb@c5008000 {
 		status = "okay";
 	};
 
-	usb-phy@c5004400 {
-		nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+	usb-phy@c5008000 {
+		status = "okay";
 	};
 
 	sdhci@c8000000 {
 		status = "okay";
-		power-gpios = <&gpio 86 0>; /* gpio PK6 */
+		power-gpios = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 		keep-power-in-suspend;
 	};
 
 	sdhci@c8000400 {
 		status = "okay";
-		cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-		wp-gpios = <&gpio 57 0>; /* gpio PH1 */
-		power-gpios = <&gpio 70 0>; /* gpio PI6 */
+		cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+		power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 	};
 
@@ -557,7 +569,7 @@
 
 		power {
 			label = "Power";
-			gpios = <&gpio 170 1>; /* gpio PV2, active low */
+			gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
 			linux,code = <116>; /* KEY_POWER */
 			gpio-key,wakeup;
 		};
@@ -583,7 +595,7 @@
 			regulator-name = "vdd_1v5";
 			regulator-min-microvolt = <1500000>;
 			regulator-max-microvolt = <1500000>;
-			gpio = <&pmic 0 0>;
+			gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
 		};
 
 		regulator@2 {
@@ -592,7 +604,7 @@
 			regulator-name = "vdd_1v2";
 			regulator-min-microvolt = <1200000>;
 			regulator-max-microvolt = <1200000>;
-			gpio = <&pmic 1 0>;
+			gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
 			enable-active-high;
 		};
 
@@ -602,7 +614,7 @@
 			regulator-name = "vdd_pnl";
 			regulator-min-microvolt = <2800000>;
 			regulator-max-microvolt = <2800000>;
-			gpio = <&gpio 22 0>; /* gpio PC6 */
+			gpio = <&gpio TEGRA_GPIO(C, 6) GPIO_ACTIVE_HIGH>;
 			enable-active-high;
 		};
 
@@ -612,7 +624,7 @@
 			regulator-name = "vdd_bl";
 			regulator-min-microvolt = <2800000>;
 			regulator-max-microvolt = <2800000>;
-			gpio = <&gpio 176 0>; /* gpio PW0 */
+			gpio = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>;
 			enable-active-high;
 		};
 	};
@@ -635,12 +647,16 @@
 		nvidia,i2s-controller = <&tegra_i2s1>;
 		nvidia,audio-codec = <&wm8903>;
 
-		nvidia,spkr-en-gpios = <&wm8903 2 0>;
-		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
-		nvidia,int-mic-en-gpios = <&gpio 184 0>; /* gpio PX0 */
-		nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+		nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
+		nvidia,int-mic-en-gpios = <&gpio TEGRA_GPIO(X, 0)
+			GPIO_ACTIVE_HIGH>;
+		nvidia,ext-mic-en-gpios = <&gpio TEGRA_GPIO(X, 1)
+			GPIO_ACTIVE_HIGH>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+			 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-whistler.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-whistler.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra20-whistler.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra20-whistler.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra20.dtsi"
+#include "tegra20.dtsi"
 
 / {
 	model = "NVIDIA Tegra20 Whistler evaluation board";
@@ -18,7 +18,8 @@
 			pll-supply = <&hdmi_pll_reg>;
 
 			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
-			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+			nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+				GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -281,7 +282,7 @@
 		max8907@3c {
 			compatible = "maxim,max8907";
 			reg = <0x3c>;
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 
 			maxim,system-power-controller;
 
@@ -508,18 +509,28 @@
 
 	usb@c5000000 {
 		status = "okay";
-		nvidia,vbus-gpio = <&tca6416 0 0>; /* GPIO_PMU0 */
+		nvidia,vbus-gpio = <&tca6416 0 GPIO_ACTIVE_HIGH>;
+	};
+
+	usb-phy@c5000000 {
+		status = "okay";
+		vbus-supply = <&vbus1_reg>;
 	};
 
 	usb@c5008000 {
 		status = "okay";
-		nvidia,vbus-gpio = <&tca6416 1 0>; /* GPIO_PMU1 */
+		nvidia,vbus-gpio = <&tca6416 1 GPIO_ACTIVE_HIGH>;
+	};
+
+	usb-phy@c5008000 {
+		status = "okay";
+		vbus-supply = <&vbus3_reg>;
 	};
 
 	sdhci@c8000400 {
 		status = "okay";
-		cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-		wp-gpios = <&gpio 173 0>; /* gpio PV5 */
+		cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(V, 5) GPIO_ACTIVE_HIGH>;
 		bus-width = <8>;
 	};
 
@@ -568,6 +579,30 @@
 			regulator-max-microvolt = <5000000>;
 			regulator-always-on;
 		};
+
+		vbus1_reg: regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "vbus1";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			gpio = <&tca6416 0 0>; /* GPIO_PMU0 */
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		vbus3_reg: regulator@3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+			regulator-name = "vbus3";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			gpio = <&tca6416 1 0>; /* GPIO_PMU1 */
+			regulator-always-on;
+			regulator-boot-on;
+		};
 	};
 
 	sound {
@@ -584,7 +619,9 @@
 		nvidia,i2s-controller = <&tegra_i2s1>;
 		nvidia,audio-codec = <&codec>;
 
-		clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+		clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+			 <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA20_CLK_CDEV1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30-beaver.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30-beaver.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30-beaver.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30-beaver.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,13 +1,13 @@
 /dts-v1/;
 
-/include/ "tegra30.dtsi"
+#include "tegra30.dtsi"
 
 / {
 	model = "NVIDIA Tegra30 Beaver evaluation board";
 	compatible = "nvidia,beaver", "nvidia,tegra30";
 
 	memory {
-		reg = <0x80000000 0x80000000>;
+		reg = <0x80000000 0x7ff00000>;
 	};
 
 	pinmux {
@@ -116,6 +116,15 @@
 		status = "okay";
 		clock-frequency = <100000>;
 
+		rt5640: rt5640 {
+			compatible = "realtek,rt5640";
+			reg = <0x1c>;
+			interrupt-parent = <&gpio>;
+			interrupts = <TEGRA_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
+			realtek,ldo1-en-gpios =
+				<&gpio TEGRA_GPIO(X, 2) GPIO_ACTIVE_HIGH>;
+		};
+
 		tps62361 {
 			compatible = "ti,tps62361";
 			reg = <0x60>;
@@ -133,7 +142,7 @@
 			compatible = "ti,tps65911";
 			reg = <0x2d>;
 
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 			#interrupt-cells = <2>;
 			interrupt-controller;
 
@@ -264,9 +273,9 @@
 
 	sdhci@78000000 {
 		status = "okay";
-		cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-		wp-gpios = <&gpio 155 0>; /* gpio PT3 */
-		power-gpios = <&gpio 31 0>; /* gpio PD7 */
+		cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
+		power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 	};
 
@@ -312,7 +321,7 @@
 			regulator-boot-on;
 			regulator-always-on;
 			enable-active-high;
-			gpio = <&pmic 0 0>; /* PMIC TPS65911 GPIO0 */
+			gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
 		};
 
 		ddr_reg: regulator@2 {
@@ -324,7 +333,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&pmic 7 0>; /* PMIC TPS65911 GPIO7 */
+			gpio = <&pmic 7 GPIO_ACTIVE_HIGH>;
 			vin-supply = <&vdd_5v_in_reg>;
 		};
 
@@ -337,7 +346,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&gpio 30 0>; /* gpio PD6 */
+			gpio = <&gpio TEGRA_GPIO(D, 6) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&vdd_5v_in_reg>;
 		};
 
@@ -348,7 +357,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 68 0>; /* GPIO PI4 */
+			gpio = <&gpio TEGRA_GPIO(I, 4) GPIO_ACTIVE_HIGH>;
 			gpio-open-drain;
 			vin-supply = <&vdd_5v_in_reg>;
 		};
@@ -360,7 +369,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 63 0>; /* GPIO PH7 */
+			gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_HIGH>;
 			gpio-open-drain;
 			vin-supply = <&vdd_5v_in_reg>;
 		};
@@ -374,7 +383,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&pmic 6 0>; /* PMIC TPS65911 GPIO6 */
+			gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
 			vin-supply = <&vdd_5v_in_reg>;
 		};
 
@@ -387,8 +396,41 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&gpio 95 0>; /* gpio PL7 */
+			gpio = <&gpio TEGRA_GPIO(L, 7) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&sys_3v3_reg>;
 		};
 	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		gpled1 {
+			label = "LED1"; /* CR5A1 (blue) */
+			gpios = <&gpio TEGRA_GPIO(L, 1) GPIO_ACTIVE_HIGH>;
+		};
+		gpled2 {
+			label = "LED2"; /* CR4A2 (green) */
+			gpios = <&gpio TEGRA_GPIO(L, 0) GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	sound {
+		compatible = "nvidia,tegra-audio-rt5640-beaver",
+			     "nvidia,tegra-audio-rt5640";
+		nvidia,model = "NVIDIA Tegra Beaver";
+
+		nvidia,audio-routing =
+			"Headphones", "HPOR",
+			"Headphones", "HPOL";
+
+		nvidia,i2s-controller = <&tegra_i2s1>;
+		nvidia,audio-codec = <&rt5640>;
+
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
+
+		clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
+			 <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA30_CLK_EXTERN1>;
+		clock-names = "pll_a", "pll_a_out0", "mclk";
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30-cardhu-a02.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30-cardhu-a02.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30-cardhu-a02.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30-cardhu-a02.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra30-cardhu.dtsi"
+#include "tegra30-cardhu.dtsi"
 
 /* This dts file support the cardhu A02 version of board */
 
@@ -22,7 +22,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&pmic 6 0>;
+			gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
 		};
 
 		sys_3v3_reg: regulator@101 {
@@ -34,7 +34,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&pmic 7 0>;
+			gpio = <&pmic 7 GPIO_ACTIVE_HIGH>;
 		};
 
 		usb1_vbus_reg: regulator@102 {
@@ -44,7 +44,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 68 0>; /* GPIO PI4 */
+			gpio = <&gpio TEGRA_GPIO(I, 4) GPIO_ACTIVE_HIGH>;
 			gpio-open-drain;
 			vin-supply = <&vdd_5v0_reg>;
 		};
@@ -56,7 +56,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 63 0>; /* GPIO PH7 */
+			gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_HIGH>;
 			gpio-open-drain;
 			vin-supply = <&vdd_5v0_reg>;
 		};
@@ -68,7 +68,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&pmic 2 0>;
+			gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
 		};
 
 		vdd_bl_reg: regulator@105 {
@@ -80,13 +80,13 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&gpio 83 0>; /* GPIO PK3 */
+			gpio = <&gpio TEGRA_GPIO(K, 3) GPIO_ACTIVE_HIGH>;
 		};
 	};
 
 	sdhci@78000400 {
 		status = "okay";
-		power-gpios = <&gpio 28 0>; /* gpio PD4 */
+		power-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 		keep-power-in-suspend;
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30-cardhu-a04.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30-cardhu-a04.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30-cardhu-a04.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30-cardhu-a04.dts	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "tegra30-cardhu.dtsi"
+#include "tegra30-cardhu.dtsi"
 
 /* This dts file support the cardhu A04 and later versions of board */
 
@@ -22,7 +22,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&pmic 7 0>;
+			gpio = <&pmic 7 GPIO_ACTIVE_HIGH>;
 		};
 
 		sys_3v3_reg: regulator@101 {
@@ -34,7 +34,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&pmic 6 0>;
+			gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
 		};
 
 		usb1_vbus_reg: regulator@102 {
@@ -44,7 +44,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 238 0>; /* GPIO PDD6 */
+			gpio = <&gpio TEGRA_GPIO(DD, 6) GPIO_ACTIVE_HIGH>;
 			gpio-open-drain;
 			vin-supply = <&vdd_5v0_reg>;
 		};
@@ -56,7 +56,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 236 0>; /* GPIO PDD4 */
+			gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>;
 			gpio-open-drain;
 			vin-supply = <&vdd_5v0_reg>;
 		};
@@ -68,7 +68,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&pmic 8 0>;
+			gpio = <&pmic 8 GPIO_ACTIVE_HIGH>;
 		};
 
 		vdd_bl_reg: regulator@105 {
@@ -80,7 +80,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&gpio 234 0>; /* GPIO PDD2 */
+			gpio = <&gpio TEGRA_GPIO(DD, 2) GPIO_ACTIVE_HIGH>;
 		};
 
 		vdd_bl2_reg: regulator@106 {
@@ -92,13 +92,13 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&gpio 232 0>; /* GPIO PDD0 */
+			gpio = <&gpio TEGRA_GPIO(DD, 0) GPIO_ACTIVE_HIGH>;
 		};
 	};
 
 	sdhci@78000400 {
 		status = "okay";
-		power-gpios = <&gpio 27 0>; /* gpio PD3 */
+		power-gpios = <&gpio TEGRA_GPIO(D, 3) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 		keep-power-in-suspend;
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30-cardhu.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30-cardhu.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30-cardhu.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30-cardhu.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-/include/ "tegra30.dtsi"
+#include "tegra30.dtsi"
 
 /**
  * This file contains common DT entry for all fab version of Cardhu.
@@ -146,7 +146,7 @@
 			compatible = "isil,isl29028";
 			reg = <0x44>;
 			interrupt-parent = <&gpio>;
-			interrupts = <88 0x04>; /*gpio PL0 */
+			interrupts = <TEGRA_GPIO(L, 0) IRQ_TYPE_LEVEL_HIGH>;
 		};
 	};
 
@@ -163,7 +163,7 @@
 			compatible = "wlf,wm8903";
 			reg = <0x1a>;
 			interrupt-parent = <&gpio>;
-			interrupts = <179 0x04>; /* gpio PW3 */
+			interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_HIGH>;
 
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -190,7 +190,7 @@
 			compatible = "ti,tps65911";
 			reg = <0x2d>;
 
-			interrupts = <0 86 0x4>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
 			#interrupt-cells = <2>;
 			interrupt-controller;
 
@@ -318,9 +318,9 @@
 
 	sdhci@78000000 {
 		status = "okay";
-		cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-		wp-gpios = <&gpio 155 0>; /* gpio PT3 */
-		power-gpios = <&gpio 31 0>; /* gpio PD7 */
+		cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+		wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
+		power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>;
 		bus-width = <4>;
 	};
 
@@ -364,7 +364,7 @@
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
 			enable-active-high;
-			gpio = <&gpio 220 0>; /* gpio PBB4 */
+			gpio = <&gpio TEGRA_GPIO(BB, 4) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&vio_reg>;
 		};
 
@@ -377,7 +377,7 @@
 			regulator-boot-on;
 			regulator-always-on;
 			enable-active-high;
-			gpio = <&pmic 0 0>; /* PMIC TPS65911 GPIO0 */
+			gpio = <&pmic 0 GPIO_ACTIVE_HIGH>;
 		};
 
 		emmc_3v3_reg: regulator@3 {
@@ -389,7 +389,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&gpio 25 0>; /* gpio PD1 */
+			gpio = <&gpio TEGRA_GPIO(D, 1) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&sys_3v3_reg>;
 		};
 
@@ -400,7 +400,7 @@
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			enable-active-high;
-			gpio = <&gpio 30 0>; /* gpio PD6 */
+			gpio = <&gpio TEGRA_GPIO(D, 6) GPIO_ACTIVE_HIGH>;
 		};
 
 		pex_hvdd_3v3_reg: regulator@5 {
@@ -410,7 +410,7 @@
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			enable-active-high;
-			gpio = <&gpio 95 0>; /* gpio PL7 */
+			gpio = <&gpio TEGRA_GPIO(L, 7) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&sys_3v3_reg>;
 		};
 
@@ -421,7 +421,7 @@
 			regulator-min-microvolt = <2800000>;
 			regulator-max-microvolt = <2800000>;
 			enable-active-high;
-			gpio = <&gpio 142 0>; /* gpio PR6 */
+			gpio = <&gpio TEGRA_GPIO(R, 6) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&sys_3v3_reg>;
 		};
 
@@ -432,7 +432,7 @@
 			regulator-min-microvolt = <2800000>;
 			regulator-max-microvolt = <2800000>;
 			enable-active-high;
-			gpio = <&gpio 143 0>; /* gpio PR7 */
+			gpio = <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&sys_3v3_reg>;
 		};
 
@@ -443,7 +443,7 @@
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			enable-active-high;
-			gpio = <&gpio 144 0>; /* gpio PS0 */
+			gpio = <&gpio TEGRA_GPIO(S, 0) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&sys_3v3_reg>;
 		};
 
@@ -456,7 +456,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&gpio 24 0>; /* gpio PD0 */
+			gpio = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&sys_3v3_reg>;
 		};
 
@@ -467,7 +467,7 @@
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			enable-active-high;
-			gpio = <&gpio 94 0>; /* gpio PL6 */
+			gpio = <&gpio TEGRA_GPIO(L, 6) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&sys_3v3_reg>;
 		};
 
@@ -480,7 +480,7 @@
 			regulator-always-on;
 			regulator-boot-on;
 			enable-active-high;
-			gpio = <&gpio 92 0>; /* gpio PL4 */
+			gpio = <&gpio TEGRA_GPIO(L, 4) GPIO_ACTIVE_HIGH>;
 			vin-supply = <&sys_3v3_reg>;
 		};
 
@@ -491,7 +491,7 @@
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
 			enable-active-high;
-			gpio = <&gpio 152 0>; /* GPIO PT0 */
+			gpio = <&gpio TEGRA_GPIO(T, 0) GPIO_ACTIVE_HIGH>;
 			gpio-open-drain;
 			vin-supply = <&vdd_5v0_reg>;
 		};
@@ -515,10 +515,13 @@
 		nvidia,i2s-controller = <&tegra_i2s1>;
 		nvidia,audio-codec = <&wm8903>;
 
-		nvidia,spkr-en-gpios = <&wm8903 2 0>;
-		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+		nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>;
+		nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2)
+			GPIO_ACTIVE_HIGH>;
 
-		clocks = <&tegra_car 184>, <&tegra_car 185>, <&tegra_car 120>;
+		clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
+			 <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+			 <&tegra_car TEGRA30_CLK_EXTERN1>;
 		clock-names = "pll_a", "pll_a_out0", "mclk";
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tegra30.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tegra30.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,8 @@
-/include/ "skeleton.dtsi"
+#include <dt-bindings/clock/tegra30-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "skeleton.dtsi"
 
 / {
 	compatible = "nvidia,tegra30";
@@ -15,9 +19,9 @@
 	host1x {
 		compatible = "nvidia,tegra30-host1x", "simple-bus";
 		reg = <0x50000000 0x00024000>;
-		interrupts = <0 65 0x04   /* mpcore syncpt */
-			      0 67 0x04>; /* mpcore general */
-		clocks = <&tegra_car 28>;
+		interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
+			     <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
+		clocks = <&tegra_car TEGRA30_CLK_HOST1X>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -27,36 +31,36 @@
 		mpe {
 			compatible = "nvidia,tegra30-mpe";
 			reg = <0x54040000 0x00040000>;
-			interrupts = <0 68 0x04>;
-			clocks = <&tegra_car 60>;
+			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA30_CLK_MPE>;
 		};
 
 		vi {
 			compatible = "nvidia,tegra30-vi";
 			reg = <0x54080000 0x00040000>;
-			interrupts = <0 69 0x04>;
-			clocks = <&tegra_car 164>;
+			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA30_CLK_VI>;
 		};
 
 		epp {
 			compatible = "nvidia,tegra30-epp";
 			reg = <0x540c0000 0x00040000>;
-			interrupts = <0 70 0x04>;
-			clocks = <&tegra_car 19>;
+			interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA30_CLK_EPP>;
 		};
 
 		isp {
 			compatible = "nvidia,tegra30-isp";
 			reg = <0x54100000 0x00040000>;
-			interrupts = <0 71 0x04>;
-			clocks = <&tegra_car 23>;
+			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA30_CLK_ISP>;
 		};
 
 		gr2d {
 			compatible = "nvidia,tegra30-gr2d";
 			reg = <0x54140000 0x00040000>;
-			interrupts = <0 72 0x04>;
-			clocks = <&tegra_car 21>;
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA30_CLK_GR2D>;
 		};
 
 		gr3d {
@@ -69,8 +73,9 @@
 		dc@54200000 {
 			compatible = "nvidia,tegra30-dc";
 			reg = <0x54200000 0x00040000>;
-			interrupts = <0 73 0x04>;
-			clocks = <&tegra_car 27>, <&tegra_car 179>;
+			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA30_CLK_DISP1>,
+				 <&tegra_car TEGRA30_CLK_PLL_P>;
 			clock-names = "disp1", "parent";
 
 			rgb {
@@ -81,8 +86,9 @@
 		dc@54240000 {
 			compatible = "nvidia,tegra30-dc";
 			reg = <0x54240000 0x00040000>;
-			interrupts = <0 74 0x04>;
-			clocks = <&tegra_car 26>, <&tegra_car 179>;
+			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA30_CLK_DISP2>,
+				 <&tegra_car TEGRA30_CLK_PLL_P>;
 			clock-names = "disp2", "parent";
 
 			rgb {
@@ -93,8 +99,9 @@
 		hdmi {
 			compatible = "nvidia,tegra30-hdmi";
 			reg = <0x54280000 0x00040000>;
-			interrupts = <0 75 0x04>;
-			clocks = <&tegra_car 51>, <&tegra_car 189>;
+			interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA30_CLK_HDMI>,
+				 <&tegra_car TEGRA30_CLK_PLL_D2_OUT0>;
 			clock-names = "hdmi", "parent";
 			status = "disabled";
 		};
@@ -102,15 +109,15 @@
 		tvo {
 			compatible = "nvidia,tegra30-tvo";
 			reg = <0x542c0000 0x00040000>;
-			interrupts = <0 76 0x04>;
-			clocks = <&tegra_car 169>;
+			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&tegra_car TEGRA30_CLK_TVO>;
 			status = "disabled";
 		};
 
 		dsi {
 			compatible = "nvidia,tegra30-dsi";
 			reg = <0x54300000 0x00040000>;
-			clocks = <&tegra_car 48>;
+			clocks = <&tegra_car TEGRA30_CLK_DSIA>;
 			status = "disabled";
 		};
 	};
@@ -118,8 +125,9 @@
 	timer@50004600 {
 		compatible = "arm,cortex-a9-twd-timer";
 		reg = <0x50040600 0x20>;
-		interrupts = <1 13 0xf04>;
-		clocks = <&tegra_car 214>;
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		clocks = <&tegra_car TEGRA30_CLK_TWD>;
 	};
 
 	intc: interrupt-controller {
@@ -142,13 +150,13 @@
 	timer@60005000 {
 		compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
 		reg = <0x60005000 0x400>;
-		interrupts = <0 0 0x04
-			      0 1 0x04
-			      0 41 0x04
-			      0 42 0x04
-			      0 121 0x04
-			      0 122 0x04>;
-		clocks = <&tegra_car 5>;
+		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA30_CLK_TIMER>;
 	};
 
 	tegra_car: clock {
@@ -160,39 +168,39 @@
 	apbdma: dma {
 		compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
 		reg = <0x6000a000 0x1400>;
-		interrupts = <0 104 0x04
-			      0 105 0x04
-			      0 106 0x04
-			      0 107 0x04
-			      0 108 0x04
-			      0 109 0x04
-			      0 110 0x04
-			      0 111 0x04
-			      0 112 0x04
-			      0 113 0x04
-			      0 114 0x04
-			      0 115 0x04
-			      0 116 0x04
-			      0 117 0x04
-			      0 118 0x04
-			      0 119 0x04
-			      0 128 0x04
-			      0 129 0x04
-			      0 130 0x04
-			      0 131 0x04
-			      0 132 0x04
-			      0 133 0x04
-			      0 134 0x04
-			      0 135 0x04
-			      0 136 0x04
-			      0 137 0x04
-			      0 138 0x04
-			      0 139 0x04
-			      0 140 0x04
-			      0 141 0x04
-			      0 142 0x04
-			      0 143 0x04>;
-		clocks = <&tegra_car 34>;
+		interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA30_CLK_APBDMA>;
 	};
 
 	ahb: ahb {
@@ -203,14 +211,14 @@
 	gpio: gpio {
 		compatible = "nvidia,tegra30-gpio";
 		reg = <0x6000d000 0x1000>;
-		interrupts = <0 32 0x04
-			      0 33 0x04
-			      0 34 0x04
-			      0 35 0x04
-			      0 55 0x04
-			      0 87 0x04
-			      0 89 0x04
-			      0 125 0x04>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
 		#gpio-cells = <2>;
 		gpio-controller;
 		#interrupt-cells = <2>;
@@ -235,9 +243,9 @@
 		compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
 		reg = <0x70006000 0x40>;
 		reg-shift = <2>;
-		interrupts = <0 36 0x04>;
+		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 8>;
-		clocks = <&tegra_car 6>;
+		clocks = <&tegra_car TEGRA30_CLK_UARTA>;
 		status = "disabled";
 	};
 
@@ -245,9 +253,9 @@
 		compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
 		reg = <0x70006040 0x40>;
 		reg-shift = <2>;
-		interrupts = <0 37 0x04>;
+		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 9>;
-		clocks = <&tegra_car 160>;
+		clocks = <&tegra_car TEGRA30_CLK_UARTB>;
 		status = "disabled";
 	};
 
@@ -255,9 +263,9 @@
 		compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
 		reg = <0x70006200 0x100>;
 		reg-shift = <2>;
-		interrupts = <0 46 0x04>;
+		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 10>;
-		clocks = <&tegra_car 55>;
+		clocks = <&tegra_car TEGRA30_CLK_UARTC>;
 		status = "disabled";
 	};
 
@@ -265,9 +273,9 @@
 		compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
 		reg = <0x70006300 0x100>;
 		reg-shift = <2>;
-		interrupts = <0 90 0x04>;
+		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 19>;
-		clocks = <&tegra_car 65>;
+		clocks = <&tegra_car TEGRA30_CLK_UARTD>;
 		status = "disabled";
 	};
 
@@ -275,9 +283,9 @@
 		compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
 		reg = <0x70006400 0x100>;
 		reg-shift = <2>;
-		interrupts = <0 91 0x04>;
+		interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 20>;
-		clocks = <&tegra_car 66>;
+		clocks = <&tegra_car TEGRA30_CLK_UARTE>;
 		status = "disabled";
 	};
 
@@ -285,24 +293,25 @@
 		compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm";
 		reg = <0x7000a000 0x100>;
 		#pwm-cells = <2>;
-		clocks = <&tegra_car 17>;
+		clocks = <&tegra_car TEGRA30_CLK_PWM>;
 		status = "disabled";
 	};
 
 	rtc {
 		compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
 		reg = <0x7000e000 0x100>;
-		interrupts = <0 2 0x04>;
-		clocks = <&tegra_car 4>;
+		interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA30_CLK_RTC>;
 	};
 
 	i2c@7000c000 {
 		compatible =  "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
 		reg = <0x7000c000 0x100>;
-		interrupts = <0 38 0x04>;
+		interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 12>, <&tegra_car 182>;
+		clocks = <&tegra_car TEGRA30_CLK_I2C1>,
+			 <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 		status = "disabled";
 	};
@@ -310,10 +319,11 @@
 	i2c@7000c400 {
 		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
 		reg = <0x7000c400 0x100>;
-		interrupts = <0 84 0x04>;
+		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 54>, <&tegra_car 182>;
+		clocks = <&tegra_car TEGRA30_CLK_I2C2>,
+			 <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 		status = "disabled";
 	};
@@ -321,10 +331,11 @@
 	i2c@7000c500 {
 		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
 		reg = <0x7000c500 0x100>;
-		interrupts = <0 92 0x04>;
+		interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 67>, <&tegra_car 182>;
+		clocks = <&tegra_car TEGRA30_CLK_I2C3>,
+			 <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 		status = "disabled";
 	};
@@ -332,10 +343,11 @@
 	i2c@7000c700 {
 		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
 		reg = <0x7000c700 0x100>;
-		interrupts = <0 120 0x04>;
+		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 103>, <&tegra_car 182>;
+		clocks = <&tegra_car TEGRA30_CLK_I2C4>,
+			 <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 		status = "disabled";
 	};
@@ -343,10 +355,11 @@
 	i2c@7000d000 {
 		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
 		reg = <0x7000d000 0x100>;
-		interrupts = <0 53 0x04>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 47>, <&tegra_car 182>;
+		clocks = <&tegra_car TEGRA30_CLK_I2C5>,
+			 <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
 		clock-names = "div-clk", "fast-clk";
 		status = "disabled";
 	};
@@ -354,81 +367,81 @@
 	spi@7000d400 {
 		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
 		reg = <0x7000d400 0x200>;
-		interrupts = <0 59 0x04>;
+		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 15>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 41>;
+		clocks = <&tegra_car TEGRA30_CLK_SBC1>;
 		status = "disabled";
 	};
 
 	spi@7000d600 {
 		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
 		reg = <0x7000d600 0x200>;
-		interrupts = <0 82 0x04>;
+		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 16>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 44>;
+		clocks = <&tegra_car TEGRA30_CLK_SBC2>;
 		status = "disabled";
 	};
 
 	spi@7000d800 {
 		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
 		reg = <0x7000d800 0x200>;
-		interrupts = <0 83 0x04>;
+		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 17>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 46>;
+		clocks = <&tegra_car TEGRA30_CLK_SBC3>;
 		status = "disabled";
 	};
 
 	spi@7000da00 {
 		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
 		reg = <0x7000da00 0x200>;
-		interrupts = <0 93 0x04>;
+		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 18>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 68>;
+		clocks = <&tegra_car TEGRA30_CLK_SBC4>;
 		status = "disabled";
 	};
 
 	spi@7000dc00 {
 		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
 		reg = <0x7000dc00 0x200>;
-		interrupts = <0 94 0x04>;
+		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 27>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 104>;
+		clocks = <&tegra_car TEGRA30_CLK_SBC5>;
 		status = "disabled";
 	};
 
 	spi@7000de00 {
 		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
 		reg = <0x7000de00 0x200>;
-		interrupts = <0 79 0x04>;
+		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 28>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-		clocks = <&tegra_car 105>;
+		clocks = <&tegra_car TEGRA30_CLK_SBC6>;
 		status = "disabled";
 	};
 
 	kbc {
 		compatible = "nvidia,tegra30-kbc", "nvidia,tegra20-kbc";
 		reg = <0x7000e200 0x100>;
-		interrupts = <0 85 0x04>;
-		clocks = <&tegra_car 36>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA30_CLK_KBC>;
 		status = "disabled";
 	};
 
 	pmc {
 		compatible = "nvidia,tegra30-pmc";
 		reg = <0x7000e400 0x400>;
-		clocks = <&tegra_car 218>, <&clk32k_in>;
+		clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>;
 		clock-names = "pclk", "clk32k_in";
 	};
 
@@ -438,7 +451,7 @@
 		       0x7000f03c 0x1b4
 		       0x7000f200 0x028
 		       0x7000f284 0x17c>;
-		interrupts = <0 77 0x04>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
 	iommu {
@@ -455,12 +468,19 @@
 		compatible = "nvidia,tegra30-ahub";
 		reg = <0x70080000 0x200
 		       0x70080200 0x100>;
-		interrupts = <0 103 0x04>;
+		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
 		nvidia,dma-request-selector = <&apbdma 1>;
-		clocks = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>,
-			 <&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>,
-			 <&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>,
-			 <&tegra_car 110>, <&tegra_car 162>;
+		clocks = <&tegra_car TEGRA30_CLK_D_AUDIO>,
+			 <&tegra_car TEGRA30_CLK_APBIF>,
+			 <&tegra_car TEGRA30_CLK_I2S0>,
+			 <&tegra_car TEGRA30_CLK_I2S1>,
+			 <&tegra_car TEGRA30_CLK_I2S2>,
+			 <&tegra_car TEGRA30_CLK_I2S3>,
+			 <&tegra_car TEGRA30_CLK_I2S4>,
+			 <&tegra_car TEGRA30_CLK_DAM0>,
+			 <&tegra_car TEGRA30_CLK_DAM1>,
+			 <&tegra_car TEGRA30_CLK_DAM2>,
+			 <&tegra_car TEGRA30_CLK_SPDIF_IN>;
 		clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
 			      "i2s3", "i2s4", "dam0", "dam1", "dam2",
 			      "spdif_in";
@@ -472,7 +492,7 @@
 			compatible = "nvidia,tegra30-i2s";
 			reg = <0x70080300 0x100>;
 			nvidia,ahub-cif-ids = <4 4>;
-			clocks = <&tegra_car 30>;
+			clocks = <&tegra_car TEGRA30_CLK_I2S0>;
 			status = "disabled";
 		};
 
@@ -480,7 +500,7 @@
 			compatible = "nvidia,tegra30-i2s";
 			reg = <0x70080400 0x100>;
 			nvidia,ahub-cif-ids = <5 5>;
-			clocks = <&tegra_car 11>;
+			clocks = <&tegra_car TEGRA30_CLK_I2S1>;
 			status = "disabled";
 		};
 
@@ -488,7 +508,7 @@
 			compatible = "nvidia,tegra30-i2s";
 			reg = <0x70080500 0x100>;
 			nvidia,ahub-cif-ids = <6 6>;
-			clocks = <&tegra_car 18>;
+			clocks = <&tegra_car TEGRA30_CLK_I2S2>;
 			status = "disabled";
 		};
 
@@ -496,7 +516,7 @@
 			compatible = "nvidia,tegra30-i2s";
 			reg = <0x70080600 0x100>;
 			nvidia,ahub-cif-ids = <7 7>;
-			clocks = <&tegra_car 101>;
+			clocks = <&tegra_car TEGRA30_CLK_I2S3>;
 			status = "disabled";
 		};
 
@@ -504,7 +524,7 @@
 			compatible = "nvidia,tegra30-i2s";
 			reg = <0x70080700 0x100>;
 			nvidia,ahub-cif-ids = <8 8>;
-			clocks = <&tegra_car 102>;
+			clocks = <&tegra_car TEGRA30_CLK_I2S4>;
 			status = "disabled";
 		};
 	};
@@ -512,32 +532,32 @@
 	sdhci@78000000 {
 		compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
 		reg = <0x78000000 0x200>;
-		interrupts = <0 14 0x04>;
-		clocks = <&tegra_car 14>;
+		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA30_CLK_SDMMC1>;
 		status = "disabled";
 	};
 
 	sdhci@78000200 {
 		compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
 		reg = <0x78000200 0x200>;
-		interrupts = <0 15 0x04>;
-		clocks = <&tegra_car 9>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA30_CLK_SDMMC2>;
 		status = "disabled";
 	};
 
 	sdhci@78000400 {
 		compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
 		reg = <0x78000400 0x200>;
-		interrupts = <0 19 0x04>;
-		clocks = <&tegra_car 69>;
+		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA30_CLK_SDMMC3>;
 		status = "disabled";
 	};
 
 	sdhci@78000600 {
 		compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
 		reg = <0x78000600 0x200>;
-		interrupts = <0 31 0x04>;
-		clocks = <&tegra_car 15>;
+		interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&tegra_car TEGRA30_CLK_SDMMC4>;
 		status = "disabled";
 	};
 
@@ -572,9 +592,9 @@
 
 	pmu {
 		compatible = "arm,cortex-a9-pmu";
-		interrupts = <0 144 0x04
-			      0 145 0x04
-			      0 146 0x04
-			      0 147 0x04>;
+		interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tny_a9260.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tny_a9260.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tny_a9260.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tny_a9260.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,8 +6,8 @@
  * Licensed under GPLv2.
  */
 /dts-v1/;
-/include/ "at91sam9260.dtsi"
-/include/ "tny_a9260_common.dtsi"
+#include "at91sam9260.dtsi"
+#include "tny_a9260_common.dtsi"
 
 / {
 	model = "Calao TNY A9260";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tny_a9263.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tny_a9263.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tny_a9263.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tny_a9263.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2 only
  */
 /dts-v1/;
-/include/ "at91sam9263.dtsi"
+#include "at91sam9263.dtsi"
 
 / {
 	model = "Calao TNY A9263";
@@ -38,7 +38,7 @@
 			};
 
 			usb1: gadget@fff78000 {
-				atmel,vbus-gpio = <&pioB 11 0>;
+				atmel,vbus-gpio = <&pioB 11 GPIO_ACTIVE_HIGH>;
 				status = "okay";
 			};
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/tny_a9g20.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tny_a9g20.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/tny_a9g20.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/tny_a9g20.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,8 +6,8 @@
  * Licensed under GPLv2.
  */
 /dts-v1/;
-/include/ "at91sam9g20.dtsi"
-/include/ "tny_a9260_common.dtsi"
+#include "at91sam9g20.dtsi"
+#include "tny_a9260_common.dtsi"
 
 / {
 	model = "Calao TNY A9G20";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/twl4030.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/twl4030.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/twl4030.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/twl4030.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -47,6 +47,12 @@
 		regulator-max-microvolt = <3150000>;
 	};
 
+	vmmc2: regulator-vmmc2 {
+		compatible = "ti,twl4030-vmmc2";
+		regulator-min-microvolt = <1850000>;
+		regulator-max-microvolt = <3150000>;
+	};
+
 	vusb1v5: regulator-vusb1v5 {
 		compatible = "ti,twl4030-vusb1v5";
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/twl4030_omap3.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/twl4030_omap3.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/twl4030_omap3.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/twl4030_omap3.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2013 Linaro, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+&twl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&twl4030_pins>;
+};
+
+&omap3_pmx_core {
+	/*
+	 * On most OMAP3 platforms, the twl4030 IRQ line is connected
+	 * to the SYS_NIRQ line on OMAP.  Therefore, configure the
+	 * defaults for the SYS_NIRQ pin here.
+	 */
+	twl4030_pins: pinmux_twl4030_pins {
+		pinctrl-single,pins = <
+			0x1b0 (PIN_INPUT_PULLUP | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* sys_nirq.sys_nirq */
+		>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9260_common.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9260_common.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9260_common.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9260_common.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,7 @@
 			};
 
 			usb1: gadget@fffa4000 {
-				atmel,vbus-gpio = <&pioC 5 0>;
+				atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
 				status = "okay";
 			};
 		};
@@ -93,7 +93,7 @@
 
 		user_led {
 			label = "user_led";
-			gpios = <&pioB 21 1>;
+			gpios = <&pioB 21 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
 		};
 	};
@@ -105,7 +105,7 @@
 
 		user_pb {
 			label = "user_pb";
-			gpios = <&pioB 10 1>;
+			gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
 			linux,code = <28>;
 			gpio-key,wakeup;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9260.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9260.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9260.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9260.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,8 +6,8 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9260.dtsi"
-/include/ "usb_a9260_common.dtsi"
+#include "at91sam9260.dtsi"
+#include "usb_a9260_common.dtsi"
 
 / {
 	model = "Calao USB A9260";
@@ -20,4 +20,13 @@
 	memory {
 		reg = <0x20000000 0x4000000>;
 	};
+
+	ahb {
+		apb {
+			shdwc@fffffd10 {
+				atmel,wakeup-counter = <10>;
+				atmel,wakeup-rtt-timer;
+			};
+		};
+	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9263.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9263.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9263.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9263.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  * Licensed under GPLv2 only
  */
 /dts-v1/;
-/include/ "at91sam9263.dtsi"
+#include "at91sam9263.dtsi"
 
 / {
 	model = "Calao USB A9263";
@@ -43,10 +43,24 @@
 			};
 
 			usb1: gadget@fff78000 {
-				atmel,vbus-gpio = <&pioB 11 0>;
+				atmel,vbus-gpio = <&pioB 11 GPIO_ACTIVE_HIGH>;
 				status = "okay";
 			};
 
+			spi0: spi@fffa4000 {
+				cs-gpios = <&pioB 15 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+				mtd_dataflash@0 {
+					compatible = "atmel,at45", "atmel,dataflash";
+					reg = <0>;
+					spi-max-frequency = <15000000>;
+				};
+			};
+
+			shdwc@fffffd10 {
+				atmel,wakeup-counter = <10>;
+				atmel,wakeup-rtt-timer;
+			};
 		};
 
 		nand0: nand@40000000 {
@@ -107,7 +121,7 @@
 
 		user_led {
 			label = "user_led";
-			gpios = <&pioB 21 0>;
+			gpios = <&pioB 21 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
 	};
@@ -119,7 +133,7 @@
 
 		user_pb {
 			label = "user_pb";
-			gpios = <&pioB 10 1>;
+			gpios = <&pioB 10 GPIO_ACTIVE_LOW>;
 			linux,code = <28>;
 			gpio-key,wakeup;
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9g20_common.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9g20_common.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9g20_common.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9g20_common.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,27 @@
+/*
+ * usb_a9g20.dts - Device Tree file for Caloa USB A9G20 board
+ *
+ *  Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include "at91sam9g20.dtsi"
+#include "usb_a9260_common.dtsi"
+
+/ {
+	chosen {
+		bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
+	};
+
+	memory {
+		reg = <0x20000000 0x4000000>;
+	};
+
+	i2c@0 {
+		rv3029c2@56 {
+			compatible = "rv3029c2";
+			reg = <0x56>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9g20-dab-mmx.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -28,39 +28,39 @@
 
 		user_led1 {
 			label = "user_led1";
-			gpios = <&pioB 20 1>;
+			gpios = <&pioB 20 GPIO_ACTIVE_LOW>;
 		};
 
 /*
 * led already used by mother board but active as high
 *		user_led2 {
 *			label = "user_led2";
-*			gpios = <&pioB 21 1>;
+*			gpios = <&pioB 21 GPIO_ACTIVE_LOW>;
 *		};
 */
 		user_led3 {
 			label = "user_led3";
-			gpios = <&pioB 22 1>;
+			gpios = <&pioB 22 GPIO_ACTIVE_LOW>;
 		};
 
 		user_led4 {
 			label = "user_led4";
-			gpios = <&pioB 23 1>;
+			gpios = <&pioB 23 GPIO_ACTIVE_LOW>;
 		};
 
 		red {
 			label = "red";
-			gpios = <&pioB 24 1>;
+			gpios = <&pioB 24 GPIO_ACTIVE_LOW>;
 		};
 
 		orange {
 			label = "orange";
-			gpios = <&pioB 30 1>;
+			gpios = <&pioB 30 GPIO_ACTIVE_LOW>;
 		};
 
 		green {
 			label = "green";
-			gpios = <&pioB 31 1>;
+			gpios = <&pioB 31 GPIO_ACTIVE_LOW>;
 		};
 	};
 
@@ -71,25 +71,25 @@
 
 		user_pb1 {
 			label = "user_pb1";
-			gpios = <&pioB 25 1>;
+			gpios = <&pioB 25 GPIO_ACTIVE_LOW>;
 			linux,code = <0x100>;
 		};
 
 		user_pb2 {
 			label = "user_pb2";
-			gpios = <&pioB 13 1>;
+			gpios = <&pioB 13 GPIO_ACTIVE_LOW>;
 			linux,code = <0x101>;
 		};
 
 		user_pb3 {
 			label = "user_pb3";
-			gpios = <&pioA 26 1>;
+			gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
 			linux,code = <0x102>;
 		};
 
 		user_pb4 {
 			label = "user_pb4";
-			gpios = <&pioC 9 1>;
+			gpios = <&pioC 9 GPIO_ACTIVE_LOW>;
 			linux,code = <0x103>;
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9g20.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9g20.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9g20.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9g20.dts	2013-08-25 20:43:22.000000000 -0400
@@ -6,25 +6,9 @@
  * Licensed under GPLv2 or later.
  */
 /dts-v1/;
-/include/ "at91sam9g20.dtsi"
-/include/ "usb_a9260_common.dtsi"
+#include "usb_a9g20_common.dtsi"
 
 / {
 	model = "Calao USB A9G20";
 	compatible = "calao,usb-a9g20", "atmel,at91sam9g20", "atmel,at91sam9";
-
-	chosen {
-		bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs";
-	};
-
-	memory {
-		reg = <0x20000000 0x4000000>;
-	};
-
-	i2c@0 {
-		rv3029c2@56 {
-			compatible = "rv3029c2";
-			reg = <0x56>;
-		};
-	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9g20_lpw.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9g20_lpw.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/usb_a9g20_lpw.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/usb_a9g20_lpw.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ * usb_a9g20_lpw.dts - Device Tree file for Caloa USB A9G20 Low Power board
+ *
+ *  Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "usb_a9g20_common.dtsi"
+
+/ {
+	model = "Calao USB A9G20 Low Power";
+	compatible = "calao,usb-a9g20-lpw", "calao,usb-a9g20", "atmel,at91sam9g20", "atmel,at91sam9";
+
+	ahb {
+		apb {
+			spi1: spi@fffcc000 {
+				cs-gpios = <&pioB 3 GPIO_ACTIVE_HIGH>;
+				status = "okay";
+				mmc-slot@0 {
+					compatible = "mmc-spi-slot";
+					reg = <0>;
+					voltage-ranges = <3200 3400>;
+					spi-max-frequency = <25000000>;
+					interrupt-parent = <&pioC>;
+					interrupts = <4 IRQ_TYPE_EDGE_BOTH>;
+				};
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/vf610.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vf610.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/vf610.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vf610.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,464 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "skeleton.dtsi"
+#include "vf610-pinfunc.h"
+#include <dt-bindings/clock/vf610-clock.h>
+
+/ {
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		serial5 = &uart5;
+		gpio0 = &gpio1;
+		gpio1 = &gpio2;
+		gpio2 = &gpio3;
+		gpio3 = &gpio4;
+		gpio4 = &gpio5;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "arm,cortex-a5";
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sxosc {
+			compatible = "fixed-clock";
+			clock-frequency = <32768>;
+		};
+
+		fxosc {
+			compatible = "fixed-clock";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		interrupt-parent = <&intc>;
+		ranges;
+
+		aips0: aips-bus@40000000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			interrupt-parent = <&intc>;
+			reg = <0x40000000 0x70000>;
+			ranges;
+
+			intc: interrupt-controller@40002000 {
+				compatible = "arm,cortex-a9-gic";
+				#interrupt-cells = <3>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				interrupt-controller;
+				reg = <0x40003000 0x1000>,
+				      <0x40002100 0x100>;
+			};
+
+			L2: l2-cache@40006000 {
+				compatible = "arm,pl310-cache";
+				reg = <0x40006000 0x1000>;
+				cache-unified;
+				cache-level = <2>;
+				arm,data-latency = <1 1 1>;
+				arm,tag-latency = <2 2 2>;
+			};
+
+			uart0: serial@40027000 {
+				compatible = "fsl,vf610-lpuart";
+				reg = <0x40027000 0x1000>;
+				interrupts = <0 61 0x00>;
+				clocks = <&clks VF610_CLK_UART0>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			uart1: serial@40028000 {
+				compatible = "fsl,vf610-lpuart";
+				reg = <0x40028000 0x1000>;
+				interrupts = <0 62 0x04>;
+				clocks = <&clks VF610_CLK_UART1>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			uart2: serial@40029000 {
+				compatible = "fsl,vf610-lpuart";
+				reg = <0x40029000 0x1000>;
+				interrupts = <0 63 0x04>;
+				clocks = <&clks VF610_CLK_UART2>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			uart3: serial@4002a000 {
+				compatible = "fsl,vf610-lpuart";
+				reg = <0x4002a000 0x1000>;
+				interrupts = <0 64 0x04>;
+				clocks = <&clks VF610_CLK_UART3>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			sai2: sai@40031000 {
+				compatible = "fsl,vf610-sai";
+				reg = <0x40031000 0x1000>;
+				interrupts = <0 86 0x04>;
+				clocks = <&clks VF610_CLK_SAI2>;
+				clock-names = "sai";
+				status = "disabled";
+			};
+
+			pit: pit@40037000 {
+				compatible = "fsl,vf610-pit";
+				reg = <0x40037000 0x1000>;
+				interrupts = <0 39 0x04>;
+				clocks = <&clks VF610_CLK_PIT>;
+				clock-names = "pit";
+			};
+
+			wdog@4003e000 {
+				compatible = "fsl,vf610-wdt", "fsl,imx21-wdt";
+				reg = <0x4003e000 0x1000>;
+				clocks = <&clks VF610_CLK_WDT>;
+				clock-names = "wdog";
+			};
+
+			qspi0: quadspi@40044000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,vf610-qspi";
+				reg = <0x40044000 0x1000>;
+				interrupts = <0 24 0x04>;
+				clocks = <&clks VF610_CLK_QSPI0_EN>,
+					<&clks VF610_CLK_QSPI0>;
+				clock-names = "qspi_en", "qspi";
+				status = "disabled";
+			};
+
+			iomuxc: iomuxc@40048000 {
+				compatible = "fsl,vf610-iomuxc";
+				reg = <0x40048000 0x1000>;
+				#gpio-range-cells = <3>;
+
+				/* functions and groups pins */
+
+				dcu0 {
+					pinctrl_dcu0_1: dcu0grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTB8__GPIO_30		0x42
+						VF610_PAD_PTE0__DCU0_HSYNC	0x42
+						VF610_PAD_PTE1__DCU0_VSYNC	0x42
+						VF610_PAD_PTE2__DCU0_PCLK	0x42
+						VF610_PAD_PTE4__DCU0_DE		0x42
+						VF610_PAD_PTE5__DCU0_R0		0x42
+						VF610_PAD_PTE6__DCU0_R1		0x42
+						VF610_PAD_PTE7__DCU0_R2		0x42
+						VF610_PAD_PTE8__DCU0_R3		0x42
+						VF610_PAD_PTE9__DCU0_R4		0x42
+						VF610_PAD_PTE10__DCU0_R5	0x42
+						VF610_PAD_PTE11__DCU0_R6	0x42
+						VF610_PAD_PTE12__DCU0_R7	0x42
+						VF610_PAD_PTE13__DCU0_G0	0x42
+						VF610_PAD_PTE14__DCU0_G1	0x42
+						VF610_PAD_PTE15__DCU0_G2	0x42
+						VF610_PAD_PTE16__DCU0_G3	0x42
+						VF610_PAD_PTE17__DCU0_G4	0x42
+						VF610_PAD_PTE18__DCU0_G5	0x42
+						VF610_PAD_PTE19__DCU0_G6	0x42
+						VF610_PAD_PTE20__DCU0_G7	0x42
+						VF610_PAD_PTE21__DCU0_B0	0x42
+						VF610_PAD_PTE22__DCU0_B1	0x42
+						VF610_PAD_PTE23__DCU0_B2	0x42
+						VF610_PAD_PTE24__DCU0_B3	0x42
+						VF610_PAD_PTE25__DCU0_B4	0x42
+						VF610_PAD_PTE26__DCU0_B5	0x42
+						VF610_PAD_PTE27__DCU0_B6	0x42
+						VF610_PAD_PTE28__DCU0_B7	0x42
+						>;
+					};
+				};
+
+				dspi0 {
+					pinctrl_dspi0_1: dspi0grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTB19__DSPI0_CS0	0x1182
+						VF610_PAD_PTB20__DSPI0_SIN	0x1181
+						VF610_PAD_PTB21__DSPI0_SOUT	0x1182
+						VF610_PAD_PTB22__DSPI0_SCK	0x1182
+						>;
+					};
+				};
+
+				esdhc1 {
+					pinctrl_esdhc1_1: esdhc1grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTA24__ESDHC1_CLK	0x31ef
+						VF610_PAD_PTA25__ESDHC1_CMD	0x31ef
+						VF610_PAD_PTA26__ESDHC1_DAT0	0x31ef
+						VF610_PAD_PTA27__ESDHC1_DAT1	0x31ef
+						VF610_PAD_PTA28__ESDHC1_DATA2	0x31ef
+						VF610_PAD_PTA29__ESDHC1_DAT3	0x31ef
+						VF610_PAD_PTA7__GPIO_134	0x219d
+						>;
+					};
+				};
+
+				fec0 {
+					pinctrl_fec0_1: fec0grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTA6__RMII_CLKIN	0x30d1
+						VF610_PAD_PTC0__ENET_RMII0_MDC	0x30d3
+						VF610_PAD_PTC1__ENET_RMII0_MDIO	0x30d1
+						VF610_PAD_PTC2__ENET_RMII0_CRS	0x30d1
+						VF610_PAD_PTC3__ENET_RMII0_RXD1	0x30d1
+						VF610_PAD_PTC4__ENET_RMII0_RXD0	0x30d1
+						VF610_PAD_PTC5__ENET_RMII0_RXER	0x30d1
+						VF610_PAD_PTC6__ENET_RMII0_TXD1	0x30d2
+						VF610_PAD_PTC7__ENET_RMII0_TXD0	0x30d2
+						VF610_PAD_PTC8__ENET_RMII0_TXEN	0x30d2
+						>;
+					};
+				};
+
+				fec1 {
+					pinctrl_fec1_1: fec1grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTC9__ENET_RMII1_MDC		0x30d2
+						VF610_PAD_PTC10__ENET_RMII1_MDIO	0x30d3
+						VF610_PAD_PTC11__ENET_RMII1_CRS		0x30d1
+						VF610_PAD_PTC12__ENET_RMII_RXD1		0x30d1
+						VF610_PAD_PTC13__ENET_RMII1_RXD0	0x30d1
+						VF610_PAD_PTC14__ENET_RMII1_RXER	0x30d1
+						VF610_PAD_PTC15__ENET_RMII1_TXD1	0x30d2
+						VF610_PAD_PTC16__ENET_RMII1_TXD0	0x30d2
+						VF610_PAD_PTC17__ENET_RMII1_TXEN	0x30d2
+						>;
+					};
+				};
+
+				i2c0 {
+					pinctrl_i2c0_1: i2c0grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTB14__I2C0_SCL	0x30d3
+						VF610_PAD_PTB15__I2C0_SDA	0x30d3
+						>;
+					};
+				};
+
+				pwm0 {
+					pinctrl_pwm0_1: pwm0grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTB0__FTM0_CH0	0x1582
+						VF610_PAD_PTB1__FTM0_CH1	0x1582
+						VF610_PAD_PTB2__FTM0_CH2	0x1582
+						VF610_PAD_PTB3__FTM0_CH3	0x1582
+						VF610_PAD_PTB6__FTM0_CH6	0x1582
+						VF610_PAD_PTB7__FTM0_CH7	0x1582
+						>;
+					};
+				};
+
+				qspi0 {
+					pinctrl_qspi0_1: qspi0grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTD0__QSPI0_A_QSCK	0x307b
+						VF610_PAD_PTD1__QSPI0_A_CS0	0x307f
+						VF610_PAD_PTD2__QSPI0_A_DATA3	0x3073
+						VF610_PAD_PTD3__QSPI0_A_DATA2	0x3073
+						VF610_PAD_PTD4__QSPI0_A_DATA1	0x3073
+						VF610_PAD_PTD5__QSPI0_A_DATA0	0x307b
+						VF610_PAD_PTD7__QSPI0_B_QSCK	0x307b
+						VF610_PAD_PTD8__QSPI0_B_CS0	0x307f
+						VF610_PAD_PTD9__QSPI0_B_DATA3	0x3073
+						VF610_PAD_PTD10__QSPI0_B_DATA2	0x3073
+						VF610_PAD_PTD11__QSPI0_B_DATA1	0x3073
+						VF610_PAD_PTD12__QSPI0_B_DATA0	0x307b
+						>;
+					};
+				};
+
+				sai2 {
+					pinctrl_sai2_1: sai2grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTA16__SAI2_TX_BCLK	0x02ed
+						VF610_PAD_PTA18__SAI2_TX_DATA	0x02ee
+						VF610_PAD_PTA19__SAI2_TX_SYNC	0x02ed
+						VF610_PAD_PTA21__SAI2_RX_BCLK	0x02ed
+						VF610_PAD_PTA22__SAI2_RX_DATA	0x02ed
+						VF610_PAD_PTA23__SAI2_RX_SYNC	0x02ed
+						VF610_PAD_PTB18__EXT_AUDIO_MCLK	0x02ed
+						>;
+					};
+				};
+
+				uart1 {
+					pinctrl_uart1_1: uart1grp_1 {
+						fsl,pins = <
+						VF610_PAD_PTB4__UART1_TX	0x21a2
+						VF610_PAD_PTB5__UART1_RX	0x21a1
+						>;
+					};
+				};
+
+				usbvbus {
+					pinctrl_usbvbus_1: usbvbusgrp_1 {
+						fsl,pins = <
+						VF610_PAD_PTA24__USB1_VBUS_EN	0x219c
+						VF610_PAD_PTA16__USB0_VBUS_EN	0x219c
+						>;
+					};
+				};
+
+			};
+
+			gpio1: gpio@40049000 {
+				compatible = "fsl,vf610-gpio";
+				reg = <0x40049000 0x1000 0x400ff000 0x40>;
+				interrupts = <0 107 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				gpio-ranges = <&iomuxc 0 0 32>;
+			};
+
+			gpio2: gpio@4004a000 {
+				compatible = "fsl,vf610-gpio";
+				reg = <0x4004a000 0x1000 0x400ff040 0x40>;
+				interrupts = <0 108 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				gpio-ranges = <&iomuxc 0 32 32>;
+			};
+
+			gpio3: gpio@4004b000 {
+				compatible = "fsl,vf610-gpio";
+				reg = <0x4004b000 0x1000 0x400ff080 0x40>;
+				interrupts = <0 109 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				gpio-ranges = <&iomuxc 0 64 32>;
+			};
+
+			gpio4: gpio@4004c000 {
+				compatible = "fsl,vf610-gpio";
+				reg = <0x4004c000 0x1000 0x400ff0c0 0x40>;
+				interrupts = <0 110 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				gpio-ranges = <&iomuxc 0 96 32>;
+			};
+
+			gpio5: gpio@4004d000 {
+				compatible = "fsl,vf610-gpio";
+				reg = <0x4004d000 0x1000 0x400ff100 0x40>;
+				interrupts = <0 111 0x04>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				gpio-ranges = <&iomuxc 0 128 7>;
+			};
+
+			anatop@40050000 {
+				compatible = "fsl,vf610-anatop";
+				reg = <0x40050000 0x1000>;
+			};
+
+			i2c0: i2c@40066000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,vf610-i2c";
+				reg = <0x40066000 0x1000>;
+				interrupts =<0 71 0x04>;
+				clocks = <&clks VF610_CLK_I2C0>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			clks: ccm@4006b000 {
+				compatible = "fsl,vf610-ccm";
+				reg = <0x4006b000 0x1000>;
+				#clock-cells = <1>;
+			};
+		};
+
+		aips1: aips-bus@40080000 {
+			compatible = "fsl,aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x40080000 0x80000>;
+			ranges;
+
+			uart4: serial@400a9000 {
+				compatible = "fsl,vf610-lpuart";
+				reg = <0x400a9000 0x1000>;
+				interrupts = <0 65 0x04>;
+				clocks = <&clks VF610_CLK_UART4>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			uart5: serial@400aa000 {
+				compatible = "fsl,vf610-lpuart";
+				reg = <0x400aa000 0x1000>;
+				interrupts = <0 66 0x04>;
+				clocks = <&clks VF610_CLK_UART5>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			fec0: ethernet@400d0000 {
+				compatible = "fsl,mvf600-fec";
+				reg = <0x400d0000 0x1000>;
+				interrupts = <0 78 0x04>;
+				clocks = <&clks VF610_CLK_ENET0>,
+					<&clks VF610_CLK_ENET0>,
+					<&clks VF610_CLK_ENET>;
+				clock-names = "ipg", "ahb", "ptp";
+				status = "disabled";
+			};
+
+			fec1: ethernet@400d1000 {
+				compatible = "fsl,mvf600-fec";
+				reg = <0x400d1000 0x1000>;
+				interrupts = <0 79 0x04>;
+				clocks = <&clks VF610_CLK_ENET1>,
+					<&clks VF610_CLK_ENET1>,
+					<&clks VF610_CLK_ENET>;
+				clock-names = "ipg", "ahb", "ptp";
+				status = "disabled";
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/vf610-pinfunc.h linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vf610-pinfunc.h
--- linux-libre-3.10-gnu/arch/arm/boot/dts/vf610-pinfunc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vf610-pinfunc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,810 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_VF610_PINFUNC_H
+#define __DTS_VF610_PINFUNC_H
+
+/*
+ * The pin function ID for VF610 is a tuple of:
+ * <mux_reg input_reg mux_mode input_val>
+ */
+
+#define ALT0	0x0
+#define ALT1	0x1
+#define ALT2	0x2
+#define ALT3	0x3
+#define ALT4	0x4
+#define ALT5	0x5
+#define ALT6	0x6
+#define ALT7	0x7
+
+
+#define VF610_PAD_PTA6__GPIO_0			0x000 0x000 ALT0 0x0
+#define VF610_PAD_PTA6__RMII_CLKOUT		0x000 0x000 ALT1 0x0
+#define VF610_PAD_PTA6__RMII_CLKIN		0x000 0x2F0 ALT2 0x0
+#define VF610_PAD_PTA6__DCU1_TCON11		0x000 0x000 ALT4 0x0
+#define VF610_PAD_PTA6__DCU1_R2			0x000 0x000 ALT7 0x0
+#define VF610_PAD_PTA8__GPIO_1			0x004 0x000 ALT0 0x0
+#define VF610_PAD_PTA8__TCLK			0x004 0x000 ALT1 0x0
+#define VF610_PAD_PTA8__DCU0_R0			0x004 0x000 ALT4 0x0
+#define VF610_PAD_PTA8__MLB_CLK			0x004 0x354 ALT7 0x0
+#define VF610_PAD_PTA9__GPIO_2			0x008 0x000 ALT0 0x0
+#define VF610_PAD_PTA9__TDI			0x008 0x000 ALT1 0x0
+#define VF610_PAD_PTA9__RMII_CLKOUT		0x008 0x000 ALT2 0x0
+#define VF610_PAD_PTA9__RMII_CLKIN		0x008 0x2F0 ALT3 0x1
+#define VF610_PAD_PTA9__DCU0_R1			0x008 0x000 ALT4 0x0
+#define VF610_PAD_PTA9__WDOG_B			0x008 0x000 ALT6 0x0
+#define VF610_PAD_PTA10__GPIO_3			0x00C 0x000 ALT0 0x0
+#define VF610_PAD_PTA10__TDO			0x00C 0x000 ALT1 0x0
+#define VF610_PAD_PTA10__EXT_AUDIO_MCLK		0x00C 0x2EC ALT2 0x0
+#define VF610_PAD_PTA10__DCU0_G0		0x00C 0x000 ALT4 0x0
+#define VF610_PAD_PTA10__ENET_TS_CLKIN		0x00C 0x2F4 ALT6 0x0
+#define VF610_PAD_PTA10__MLB_SIGNAL		0x00C 0x35C ALT7 0x0
+#define VF610_PAD_PTA11__GPIO_4			0x010 0x000 ALT0 0x0
+#define VF610_PAD_PTA11__TMS			0x010 0x000 ALT1 0x0
+#define VF610_PAD_PTA11__DCU0_G1		0x010 0x000 ALT4 0x0
+#define VF610_PAD_PTA11__MLB_DATA		0x010 0x358 ALT7 0x0
+#define VF610_PAD_PTA12__GPIO_5			0x014 0x000 ALT0 0x0
+#define VF610_PAD_PTA12__TRACECK		0x014 0x000 ALT1 0x0
+#define VF610_PAD_PTA12__EXT_AUDIO_MCLK		0x014 0x2EC ALT2 0x1
+#define VF610_PAD_PTA12__VIU_DATA13		0x014 0x000 ALT6 0x0
+#define VF610_PAD_PTA12__I2C0_SCL		0x014 0x33C ALT7 0x0
+#define VF610_PAD_PTA16__GPIO_6			0x018 0x000 ALT0 0x0
+#define VF610_PAD_PTA16__TRACED0		0x018 0x000 ALT1 0x0
+#define VF610_PAD_PTA16__USB0_VBUS_EN		0x018 0x000 ALT2 0x0
+#define VF610_PAD_PTA16__ADC1_SE0		0x018 0x000 ALT3 0x0
+#define VF610_PAD_PTA16__LCD29			0x018 0x000 ALT4 0x0
+#define VF610_PAD_PTA16__SAI2_TX_BCLK		0x018 0x370 ALT5 0x0
+#define VF610_PAD_PTA16__VIU_DATA14		0x018 0x000 ALT6 0x0
+#define VF610_PAD_PTA16__I2C0_SDA		0x018 0x340 ALT7 0x0
+#define VF610_PAD_PTA17__GPIO_7			0x01C 0x000 ALT0 0x0
+#define VF610_PAD_PTA17__TRACED1		0x01C 0x000 ALT1 0x0
+#define VF610_PAD_PTA17__USB0_VBUS_OC		0x01C 0x000 ALT2 0x0
+#define VF610_PAD_PTA17__ADC1_SE1		0x01C 0x000 ALT3 0x0
+#define VF610_PAD_PTA17__LCD30			0x01C 0x000 ALT4 0x0
+#define VF610_PAD_PTA17__USB0_SOF_PULSE		0x01C 0x000 ALT5 0x0
+#define VF610_PAD_PTA17__VIU_DATA15		0x01C 0x000 ALT6 0x0
+#define VF610_PAD_PTA17__I2C1_SCL		0x01C 0x344 ALT7 0x0
+#define VF610_PAD_PTA18__GPIO_8			0x020 0x000 ALT0 0x0
+#define VF610_PAD_PTA18__TRACED2		0x020 0x000 ALT1 0x0
+#define VF610_PAD_PTA18__ADC0_SE0		0x020 0x000 ALT2 0x0
+#define VF610_PAD_PTA18__FTM1_QD_PHA		0x020 0x334 ALT3 0x0
+#define VF610_PAD_PTA18__LCD31			0x020 0x000 ALT4 0x0
+#define VF610_PAD_PTA18__SAI2_TX_DATA		0x020 0x000 ALT5 0x0
+#define VF610_PAD_PTA18__VIU_DATA16		0x020 0x000 ALT6 0x0
+#define VF610_PAD_PTA18__I2C1_SDA		0x020 0x348 ALT7 0x0
+#define VF610_PAD_PTA19__GPIO_9			0x024 0x000 ALT0 0x0
+#define VF610_PAD_PTA19__TRACED3		0x024 0x000 ALT1 0x0
+#define VF610_PAD_PTA19__ADC0_SE1		0x024 0x000 ALT2 0x0
+#define VF610_PAD_PTA19__FTM1_QD_PHB		0x024 0x338 ALT3 0x0
+#define VF610_PAD_PTA19__LCD32			0x024 0x000 ALT4 0x0
+#define VF610_PAD_PTA19__SAI2_TX_SYNC		0x024 0x000 ALT5 0x0
+#define VF610_PAD_PTA19__VIU_DATA17		0x024 0x000 ALT6 0x0
+#define VF610_PAD_PTA19__QSPI1_A_QSCK		0x024 0x374 ALT7 0x0
+#define VF610_PAD_PTA20__GPIO_10		0x028 0x000 ALT0 0x0
+#define VF610_PAD_PTA20__TRACED4		0x028 0x000 ALT1 0x0
+#define VF610_PAD_PTA20__LCD33			0x028 0x000 ALT4 0x0
+#define VF610_PAD_PTA20__UART3_TX		0x028 0x394 ALT6 0x0
+#define VF610_PAD_PTA20__DCU1_HSYNC		0x028 0x000 ALT7 0x0
+#define VF610_PAD_PTA21__GPIO_11		0x02C 0x000 ALT0 0x0
+#define VF610_PAD_PTA21__TRACED5		0x02C 0x000 ALT1 0x0
+#define VF610_PAD_PTA21__SAI2_RX_BCLK		0x02C 0x364 ALT5 0x0
+#define VF610_PAD_PTA21__UART3_RX		0x02C 0x390 ALT6 0x0
+#define VF610_PAD_PTA21__DCU1_VSYNC		0x02C 0x000 ALT7 0x0
+#define VF610_PAD_PTA22__GPIO_12		0x030 0x000 ALT0 0x0
+#define VF610_PAD_PTA22__TRACED6		0x030 0x000 ALT1 0x0
+#define VF610_PAD_PTA22__SAI2_RX_DATA		0x030 0x368 ALT5 0x0
+#define VF610_PAD_PTA22__I2C2_SCL		0x030 0x34C ALT6 0x0
+#define VF610_PAD_PTA22__DCU1_TAG		0x030 0x000 ALT7 0x0
+#define VF610_PAD_PTA23__GPIO_13		0x034 0x000 ALT0 0x0
+#define VF610_PAD_PTA23__TRACED7		0x034 0x000 ALT1 0x0
+#define VF610_PAD_PTA23__SAI2_RX_SYNC		0x034 0x36C ALT5 0x0
+#define VF610_PAD_PTA23__I2C2_SDA		0x034 0x350 ALT6 0x0
+#define VF610_PAD_PTA23__DCU1_DE		0x034 0x000 ALT7 0x0
+#define VF610_PAD_PTA24__GPIO_14		0x038 0x000 ALT0 0x0
+#define VF610_PAD_PTA24__TRACED8		0x038 0x000 ALT1 0x0
+#define VF610_PAD_PTA24__USB1_VBUS_EN		0x038 0x000 ALT2 0x0
+#define VF610_PAD_PTA24__ESDHC1_CLK		0x038 0x000 ALT5 0x0
+#define VF610_PAD_PTA24__DCU1_TCON4		0x038 0x000 ALT6 0x0
+#define VF610_PAD_PTA24__DDR_TEST_PAD_CTRL	0x038 0x000 ALT7 0x0
+#define VF610_PAD_PTA25__GPIO_15		0x03C 0x000 ALT0 0x0
+#define VF610_PAD_PTA25__TRACED9		0x03C 0x000 ALT1 0x0
+#define VF610_PAD_PTA25__USB1_VBUS_OC		0x03C 0x000 ALT2 0x0
+#define VF610_PAD_PTA25__ESDHC1_CMD		0x03C 0x000 ALT5 0x0
+#define VF610_PAD_PTA25__DCU1_TCON5		0x03C 0x000 ALT6 0x0
+#define VF610_PAD_PTA26__GPIO_16		0x040 0x000 ALT0 0x0
+#define VF610_PAD_PTA26__TRACED10		0x040 0x000 ALT1 0x0
+#define VF610_PAD_PTA26__SAI3_TX_BCLK		0x040 0x000 ALT2 0x0
+#define VF610_PAD_PTA26__ESDHC1_DAT0		0x040 0x000 ALT5 0x0
+#define VF610_PAD_PTA26__DCU1_TCON6		0x040 0x000 ALT6 0x0
+#define VF610_PAD_PTA27__GPIO_17		0x044 0x000 ALT0 0x0
+#define VF610_PAD_PTA27__TRACED11		0x044 0x000 ALT1 0x0
+#define VF610_PAD_PTA27__SAI3_RX_BCLK		0x044 0x000 ALT2 0x0
+#define VF610_PAD_PTA27__ESDHC1_DAT1		0x044 0x000 ALT5 0x0
+#define VF610_PAD_PTA27__DCU1_TCON7		0x044 0x000 ALT6 0x0
+#define VF610_PAD_PTA28__GPIO_18		0x048 0x000 ALT0 0x0
+#define VF610_PAD_PTA28__TRACED12		0x048 0x000 ALT1 0x0
+#define VF610_PAD_PTA28__SAI3_RX_DATA		0x048 0x000 ALT2 0x0
+#define VF610_PAD_PTA28__ENET1_1588_TMR0	0x048 0x000 ALT3 0x0
+#define VF610_PAD_PTA28__UART4_TX		0x048 0x000 ALT4 0x0
+#define VF610_PAD_PTA28__ESDHC1_DATA2		0x048 0x000 ALT5 0x0
+#define VF610_PAD_PTA28__DCU1_TCON8		0x048 0x000 ALT6 0x0
+#define VF610_PAD_PTA29__GPIO_19		0x04C 0x000 ALT0 0x0
+#define VF610_PAD_PTA29__TRACED13		0x04C 0x000 ALT1 0x0
+#define VF610_PAD_PTA29__SAI3_TX_DATA		0x04C 0x000 ALT2 0x0
+#define VF610_PAD_PTA29__ENET1_1588_TMR1	0x04C 0x000 ALT3 0x0
+#define VF610_PAD_PTA29__UART4_RX		0x04C 0x000 ALT4 0x0
+#define VF610_PAD_PTA29__ESDHC1_DAT3		0x04C 0x000 ALT5 0x0
+#define VF610_PAD_PTA29__DCU1_TCON9		0x04C 0x000 ALT6 0x0
+#define VF610_PAD_PTA30__GPIO_20		0x050 0x000 ALT0 0x0
+#define VF610_PAD_PTA30__TRACED14		0x050 0x000 ALT1 0x0
+#define VF610_PAD_PTA30__SAI3_RX_SYNC		0x050 0x000 ALT2 0x0
+#define VF610_PAD_PTA30__ENET1_1588_TMR2	0x050 0x000 ALT3 0x0
+#define VF610_PAD_PTA30__UART4_RTS		0x050 0x000 ALT4 0x0
+#define VF610_PAD_PTA30__I2C3_SCL		0x050 0x000 ALT5 0x0
+#define VF610_PAD_PTA30__UART3_TX		0x050 0x394 ALT7 0x1
+#define VF610_PAD_PTA31__GPIO_21		0x054 0x000 ALT0 0x0
+#define VF610_PAD_PTA31__TRACED15		0x054 0x000 ALT1 0x0
+#define VF610_PAD_PTA31__SAI3_TX_SYNC		0x054 0x000 ALT2 0x0
+#define VF610_PAD_PTA31__ENET1_1588_TMR3	0x054 0x000 ALT3 0x0
+#define VF610_PAD_PTA31__UART4_CTS		0x054 0x000 ALT4 0x0
+#define VF610_PAD_PTA31__I2C3_SDA		0x054 0x000 ALT5 0x0
+#define VF610_PAD_PTA31__UART3_RX		0x054 0x390 ALT7 0x1
+#define VF610_PAD_PTB0__GPIO_22			0x058 0x000 ALT0 0x0
+#define VF610_PAD_PTB0__FTM0_CH0		0x058 0x000 ALT1 0x0
+#define VF610_PAD_PTB0__ADC0_SE2		0x058 0x000 ALT2 0x0
+#define VF610_PAD_PTB0__TRACE_CTL		0x058 0x000 ALT3 0x0
+#define VF610_PAD_PTB0__LCD34			0x058 0x000 ALT4 0x0
+#define VF610_PAD_PTB0__SAI2_RX_BCLK		0x058 0x364 ALT5 0x1
+#define VF610_PAD_PTB0__VIU_DATA18		0x058 0x000 ALT6 0x0
+#define VF610_PAD_PTB0__QSPI1_A_QPCS0		0x058 0x000 ALT7 0x0
+#define VF610_PAD_PTB1__GPIO_23			0x05C 0x000 ALT0 0x0
+#define VF610_PAD_PTB1__FTM0_CH1		0x05C 0x000 ALT1 0x0
+#define VF610_PAD_PTB1__ADC0_SE3		0x05C 0x000 ALT2 0x0
+#define VF610_PAD_PTB1__SRC_RCON30		0x05C 0x000 ALT3 0x0
+#define VF610_PAD_PTB1__LCD35			0x05C 0x000 ALT4 0x0
+#define VF610_PAD_PTB1__SAI2_RX_DATA		0x05C 0x368 ALT5 0x1
+#define VF610_PAD_PTB1__VIU_DATA19		0x05C 0x000 ALT6 0x0
+#define VF610_PAD_PTB1__QSPI1_A_DATA3		0x05C 0x000 ALT7 0x0
+#define VF610_PAD_PTB2__GPIO_24			0x060 0x000 ALT0 0x0
+#define VF610_PAD_PTB2__FTM0_CH2		0x060 0x000 ALT1 0x0
+#define VF610_PAD_PTB2__ADC1_SE2		0x060 0x000 ALT2 0x0
+#define VF610_PAD_PTB2__SRC_RCON31		0x060 0x000 ALT3 0x0
+#define VF610_PAD_PTB2__LCD36			0x060 0x000 ALT4 0x0
+#define VF610_PAD_PTB2__SAI2_RX_SYNC		0x060 0x36C ALT5 0x1
+#define VF610_PAD_PTB2__VIDEO_IN0_DATA20	0x060 0x000 ALT6 0x0
+#define VF610_PAD_PTB2__QSPI1_A_DATA2		0x060 0x000 ALT7 0x0
+#define VF610_PAD_PTB3__GPIO_25			0x064 0x000 ALT0 0x0
+#define VF610_PAD_PTB3__FTM0_CH3		0x064 0x000 ALT1 0x0
+#define VF610_PAD_PTB3__ADC1_SE3		0x064 0x000 ALT2 0x0
+#define VF610_PAD_PTB3__PDB_EXTRIG		0x064 0x000 ALT3 0x0
+#define VF610_PAD_PTB3__LCD37			0x064 0x000 ALT4 0x0
+#define VF610_PAD_PTB3__VIU_DATA21		0x064 0x000 ALT6 0x0
+#define VF610_PAD_PTB3__QSPI1_A_DATA1		0x064 0x000 ALT7 0x0
+#define VF610_PAD_PTB4__GPIO_26			0x068 0x000 ALT0 0x0
+#define VF610_PAD_PTB4__FTM0_CH4		0x068 0x000 ALT1 0x0
+#define VF610_PAD_PTB4__UART1_TX		0x068 0x380 ALT2 0x0
+#define VF610_PAD_PTB4__ADC0_SE4		0x068 0x000 ALT3 0x0
+#define VF610_PAD_PTB4__LCD38			0x068 0x000 ALT4 0x0
+#define VF610_PAD_PTB4__VIU_FID			0x068 0x3A8 ALT5 0x0
+#define VF610_PAD_PTB4__VIU_DATA22		0x068 0x000 ALT6 0x0
+#define VF610_PAD_PTB4__QSPI1_A_DATA0		0x068 0x000 ALT7 0x0
+#define VF610_PAD_PTB5__GPIO_27			0x06C 0x000 ALT0 0x0
+#define VF610_PAD_PTB5__FTM0_CH5		0x06C 0x000 ALT1 0x0
+#define VF610_PAD_PTB5__UART1_RX		0x06C 0x37C ALT2 0x0
+#define VF610_PAD_PTB5__ADC1_SE4		0x06C 0x000 ALT3 0x0
+#define VF610_PAD_PTB5__LCD39			0x06C 0x000 ALT4 0x0
+#define VF610_PAD_PTB5__VIU_DE			0x06C 0x3A4 ALT5 0x0
+#define VF610_PAD_PTB5__QSPI1_A_DQS		0x06C 0x000 ALT7 0x0
+#define VF610_PAD_PTB6__GPIO_28			0x070 0x000 ALT0 0x0
+#define VF610_PAD_PTB6__FTM0_CH6		0x070 0x000 ALT1 0x0
+#define VF610_PAD_PTB6__UART1_RTS		0x070 0x000 ALT2 0x0
+#define VF610_PAD_PTB6__QSPI0_QPCS1_A		0x070 0x000 ALT3 0x0
+#define VF610_PAD_PTB6__LCD_LCD40		0x070 0x000 ALT4 0x0
+#define VF610_PAD_PTB6__FB_CLKOUT		0x070 0x000 ALT5 0x0
+#define VF610_PAD_PTB6__VIU_HSYNC		0x070 0x000 ALT6 0x0
+#define VF610_PAD_PTB6__UART2_TX		0x070 0x38C ALT7 0x0
+#define VF610_PAD_PTB7__GPIO_29			0x074 0x000 ALT0 0x0
+#define VF610_PAD_PTB7__FTM0_CH7		0x074 0x000 ALT1 0x0
+#define VF610_PAD_PTB7__UART1_CTS		0x074 0x378 ALT2 0x0
+#define VF610_PAD_PTB7__QSPI0_B_QPCS1		0x074 0x000 ALT3 0x0
+#define VF610_PAD_PTB7__LCD41			0x074 0x000 ALT4 0x0
+#define VF610_PAD_PTB7__VIU_VSYNC		0x074 0x000 ALT6 0x0
+#define VF610_PAD_PTB7__UART2_RX		0x074 0x388 ALT7 0x0
+#define VF610_PAD_PTB8__GPIO_30			0x078 0x000 ALT0 0x0
+#define VF610_PAD_PTB8__FTM1_CH0		0x078 0x32C ALT1 0x0
+#define VF610_PAD_PTB8__FTM1_QD_PHA		0x078 0x334 ALT3 0x1
+#define VF610_PAD_PTB8__VIU_DE			0x078 0x3A4 ALT5 0x1
+#define VF610_PAD_PTB8__DCU1_R6			0x078 0x000 ALT7 0x0
+#define VF610_PAD_PTB9__GPIO_31			0x07C 0x000 ALT0 0x0
+#define VF610_PAD_PTB9__FTM1_CH1		0x07C 0x330 ALT1 0x0
+#define VF610_PAD_PTB9__FTM1_QD_PHB		0x07C 0x338 ALT3 0x1
+#define VF610_PAD_PTB9__DCU1_R7			0x07C 0x000 ALT7 0x0
+#define VF610_PAD_PTB10__GPIO_32		0x080 0x000 ALT0 0x0
+#define VF610_PAD_PTB10__UART0_TX		0x080 0x000 ALT1 0x0
+#define VF610_PAD_PTB10__DCU0_TCON4		0x080 0x000 ALT4 0x0
+#define VF610_PAD_PTB10__VIU_DE			0x080 0x3A4 ALT5 0x2
+#define VF610_PAD_PTB10__CKO1			0x080 0x000 ALT6 0x0
+#define VF610_PAD_PTB10__ENET_TS_CLKIN		0x080 0x2F4 ALT7 0x1
+#define VF610_PAD_PTB11__GPIO_33		0x084 0x000 ALT0 0x0
+#define VF610_PAD_PTB11__UART0_RX		0x084 0x000 ALT1 0x0
+#define VF610_PAD_PTB11__DCU0_TCON5		0x084 0x000 ALT4 0x0
+#define VF610_PAD_PTB11__SNVS_ALARM_OUT_B	0x084 0x000 ALT5 0x0
+#define VF610_PAD_PTB11__CKO2			0x084 0x000 ALT6 0x0
+#define VF610_PAD_PTB11_ENET0_1588_TMR0		0x084 0x304 ALT7 0x0
+#define VF610_PAD_PTB12__GPIO_34		0x088 0x000 ALT0 0x0
+#define VF610_PAD_PTB12__UART0_RTS		0x088 0x000 ALT1 0x0
+#define VF610_PAD_PTB12__DSPI0_CS5		0x088 0x000 ALT3 0x0
+#define VF610_PAD_PTB12__DCU0_TCON6		0x088 0x000 ALT4 0x0
+#define VF610_PAD_PTB12__FB_AD1			0x088 0x000 ALT5 0x0
+#define VF610_PAD_PTB12__NMI			0x088 0x000 ALT6 0x0
+#define VF610_PAD_PTB12__ENET0_1588_TMR1	0x088 0x308 ALT7 0x0
+#define VF610_PAD_PTB13__GPIO_35		0x08C 0x000 ALT0 0x0
+#define VF610_PAD_PTB13__UART0_CTS		0x08C 0x000 ALT1 0x0
+#define VF610_PAD_PTB13__DSPI0_CS4		0x08C 0x000 ALT3 0x0
+#define VF610_PAD_PTB13__DCU0_TCON7		0x08C 0x000 ALT4 0x0
+#define VF610_PAD_PTB13__FB_AD0			0x08C 0x000 ALT5 0x0
+#define VF610_PAD_PTB13__TRACE_CTL		0x08C 0x000 ALT6 0x0
+#define VF610_PAD_PTB14__GPIO_36		0x090 0x000 ALT0 0x0
+#define VF610_PAD_PTB14__CAN0_RX		0x090 0x000 ALT1 0x0
+#define VF610_PAD_PTB14__I2C0_SCL		0x090 0x33C ALT2 0x1
+#define VF610_PAD_PTB14__DCU0_TCON8		0x090 0x000 ALT4 0x0
+#define VF610_PAD_PTB14__DCU1_PCLK		0x090 0x000 ALT7 0x0
+#define VF610_PAD_PTB15__GPIO_37		0x094 0x000 ALT0 0x0
+#define VF610_PAD_PTB15__CAN0_TX		0x094 0x000 ALT1 0x0
+#define VF610_PAD_PTB15__I2C0_SDA		0x094 0x340 ALT2 0x1
+#define VF610_PAD_PTB15__DCU0_TCON9		0x094 0x000 ALT4 0x0
+#define VF610_PAD_PTB15__VIU_PIX_CLK		0x094 0x3AC ALT7 0x0
+#define VF610_PAD_PTB16__GPIO_38		0x098 0x000 ALT0 0x0
+#define VF610_PAD_PTB16__CAN1_RX		0x098 0x000 ALT1 0x0
+#define VF610_PAD_PTB16__I2C1_SCL		0x098 0x344 ALT2 0x1
+#define VF610_PAD_PTB16__DCU0_TCON10		0x098 0x000 ALT4 0x0
+#define VF610_PAD_PTB17__GPIO_39		0x09C 0x000 ALT0 0x0
+#define VF610_PAD_PTB17__CAN1_TX		0x09C 0x000 ALT1 0x0
+#define VF610_PAD_PTB17__I2C1_SDA		0x09C 0x348 ALT2 0x1
+#define VF610_PAD_PTB17__DCU0_TCON11		0x09C 0x000 ALT4 0x0
+#define VF610_PAD_PTB18__GPIO_40		0x0A0 0x000 ALT0 0x0
+#define VF610_PAD_PTB18__DSPI0_CS1		0x0A0 0x000 ALT1 0x0
+#define VF610_PAD_PTB18__EXT_AUDIO_MCLK		0x0A0 0x2EC ALT2 0x2
+#define VF610_PAD_PTB18__VIU_DATA9		0x0A0 0x000 ALT6 0x0
+#define VF610_PAD_PTB19__GPIO_41		0x0A4 0x000 ALT0 0x0
+#define VF610_PAD_PTB19__DSPI0_CS0		0x0A4 0x000 ALT1 0x0
+#define VF610_PAD_PTB19__VIU_DATA10		0x0A4 0x000 ALT6 0x0
+#define VF610_PAD_PTB20__GPIO_42		0x0A8 0x000 ALT0 0x0
+#define VF610_PAD_PTB20__DSPI0_SIN		0x0A8 0x000 ALT1 0x0
+#define VF610_PAD_PTB20__LCD42			0x0A8 0x000 ALT4 0x0
+#define VF610_PAD_PTB20__VIU_DATA11		0x0A8 0x000 ALT6 0x0
+#define VF610_PAD_PTB21__GPIO_43		0x0AC 0x000 ALT0 0x0
+#define VF610_PAD_PTB21__DSPI0_SOUT		0x0AC 0x000 ALT1 0x0
+#define VF610_PAD_PTB21__LCD43			0x0AC 0x000 ALT4 0x0
+#define VF610_PAD_PTB21__VIU_DATA12		0x0AC 0x000 ALT6 0x0
+#define VF610_PAD_PTB21__DCU1_PCLK		0x0AC 0x000 ALT7 0x0
+#define VF610_PAD_PTB22__GPIO_44		0x0B0 0x000 ALT0 0x0
+#define VF610_PAD_PTB22__DSPI0_SCK		0x0B0 0x000 ALT1 0x0
+#define VF610_PAD_PTB22__VLCD			0x0B0 0x000 ALT4 0x0
+#define VF610_PAD_PTB22__VIU_FID		0x0B0 0x3A8 ALT5 0x1
+#define VF610_PAD_PTC0__GPIO_45			0x0B4 0x000 ALT0 0x0
+#define VF610_PAD_PTC0__ENET_RMII0_MDC		0x0B4 0x000 ALT1 0x0
+#define VF610_PAD_PTC0__FTM1_CH0		0x0B4 0x32C ALT2 0x1
+#define VF610_PAD_PTC0__DSPI0_CS3		0x0B4 0x000 ALT3 0x0
+#define VF610_PAD_PTC0__ESAI_SCKT		0x0B4 0x310 ALT4 0x0
+#define VF610_PAD_PTC0__ESDHC0_CLK		0x0B4 0x000 ALT5 0x0
+#define VF610_PAD_PTC0__VIU_DATA0		0x0B4 0x000 ALT6 0x0
+#define VF610_PAD_PTC0__SRC_RCON18		0x0B4 0x398 ALT7 0x0
+#define VF610_PAD_PTC1__GPIO_46			0x0B8 0x000 ALT0 0x0
+#define VF610_PAD_PTC1__ENET_RMII0_MDIO		0x0B8 0x000 ALT1 0x0
+#define VF610_PAD_PTC1__FTM1_CH1		0x0B8 0x330 ALT2 0x1
+#define VF610_PAD_PTC1__DSPI0_CS2		0x0B8 0x000 ALT3 0x0
+#define VF610_PAD_PTC1__ESAI_FST		0x0B8 0x30C ALT4 0x0
+#define VF610_PAD_PTC1__ESDHC0_CMD		0x0B8 0x000 ALT5 0x0
+#define VF610_PAD_PTC1__VIU_DATA1		0x0B8 0x000 ALT6 0x0
+#define VF610_PAD_PTC1__SRC_RCON19		0x0B8 0x39C ALT7 0x0
+#define VF610_PAD_PTC2__GPIO_47			0x0BC 0x000 ALT0 0x0
+#define VF610_PAD_PTC2__ENET_RMII0_CRS		0x0BC 0x000 ALT1 0x0
+#define VF610_PAD_PTC2__UART1_TX		0x0BC 0x380 ALT2 0x1
+#define VF610_PAD_PTC2__ESAI_SDO0		0x0BC 0x314 ALT4 0x0
+#define VF610_PAD_PTC2__ESDHC0_DAT0		0x0BC 0x000 ALT5 0x0
+#define VF610_PAD_PTC2__VIU_DATA2		0x0BC 0x000 ALT6 0x0
+#define VF610_PAD_PTC2__SRC_RCON20		0x0BC 0x3A0 ALT7 0x0
+#define VF610_PAD_PTC3__GPIO_48			0x0C0 0x000 ALT0 0x0
+#define VF610_PAD_PTC3__ENET_RMII0_RXD1		0x0C0 0x000 ALT1 0x0
+#define VF610_PAD_PTC3__UART1_RX		0x0C0 0x37C ALT2 0x1
+#define VF610_PAD_PTC3__ESAI_SDO1		0x0C0 0x318 ALT4 0x0
+#define VF610_PAD_PTC3__ESDHC0_DAT1		0x0C0 0x000 ALT5 0x0
+#define VF610_PAD_PTC3__VIU_DATA3		0x0C0 0x000 ALT6 0x0
+#define VF610_PAD_PTC3__DCU0_R0			0x0C0 0x000 ALT7 0x0
+#define VF610_PAD_PTC4__GPIO_49			0x0C4 0x000 ALT0 0x0
+#define VF610_PAD_PTC4__ENET_RMII0_RXD0		0x0C4 0x000 ALT1 0x0
+#define VF610_PAD_PTC4__UART1_RTS		0x0C4 0x000 ALT2 0x0
+#define VF610_PAD_PTC4__DSPI1_CS1		0x0C4 0x000 ALT3 0x0
+#define VF610_PAD_PTC4__ESAI_SDO2		0x0C4 0x31C ALT4 0x0
+#define VF610_PAD_PTC4__ESDHC0_DAT2		0x0C4 0x000 ALT5 0x0
+#define VF610_PAD_PTC4__VIU_DATA4		0x0C4 0x000 ALT6 0x0
+#define VF610_PAD_PTC4__DCU0_R1			0x0C4 0x000 ALT7 0x0
+#define VF610_PAD_PTC5__GPIO_50			0x0C8 0x000 ALT0 0x0
+#define VF610_PAD_PTC5__ENET_RMII0_RXER		0x0C8 0x000 ALT1 0x0
+#define VF610_PAD_PTC5__UART1_CTS		0x0C8 0x378 ALT2 0x1
+#define VF610_PAD_PTC5__DSPI1_CS0		0x0C8 0x300 ALT3 0x0
+#define VF610_PAD_PTC5__ESAI_SDO3		0x0C8 0x320 ALT4 0x0
+#define VF610_PAD_PTC5__ESDHC0_DAT3		0x0C8 0x000 ALT5 0x0
+#define VF610_PAD_PTC5__VIU_DATA5		0x0C8 0x000 ALT6 0x0
+#define VF610_PAD_PTC5__DCU0_G0			0x0C8 0x000 ALT7 0x0
+#define VF610_PAD_PTC6__GPIO_51			0x0CC 0x000 ALT0 0x0
+#define VF610_PAD_PTC6__ENET_RMII0_TXD1		0x0CC 0x000 ALT1 0x0
+#define VF610_PAD_PTC6__DSPI1_SIN		0x0CC 0x2FC ALT3 0x0
+#define VF610_PAD_PTC6__ESAI_SDI0		0x0CC 0x328 ALT4 0x0
+#define VF610_PAD_PTC6__ESDHC0_WP		0x0CC 0x000 ALT5 0x0
+#define VF610_PAD_PTC6__VIU_DATA6		0x0CC 0x000 ALT6 0x0
+#define VF610_PAD_PTC6__DCU0_G1			0x0CC 0x000 ALT7 0x0
+#define VF610_PAD_PTC7__GPIO_52			0x0D0 0x000 ALT0 0x0
+#define VF610_PAD_PTC7__ENET_RMII0_TXD0		0x0D0 0x000 ALT1 0x0
+#define VF610_PAD_PTC7__DSPI1_SOUT		0x0D0 0x000 ALT3 0x0
+#define VF610_PAD_PTC7__ESAI_SDI1		0x0D0 0x324 ALT4 0x0
+#define VF610_PAD_PTC7__VIU_DATA7		0x0D0 0x000 ALT6 0x0
+#define VF610_PAD_PTC7__DCU0_B0			0x0D0 0x000 ALT7 0x0
+#define VF610_PAD_PTC8__GPIO_53			0x0D4 0x000 ALT0 0x0
+#define VF610_PAD_PTC8__ENET_RMII0_TXEN		0x0D4 0x000 ALT1 0x0
+#define VF610_PAD_PTC8__DSPI1_SCK		0x0D4 0x2F8 ALT3 0x0
+#define VF610_PAD_PTC8__VIU_DATA8		0x0D4 0x000 ALT6 0x0
+#define VF610_PAD_PTC8__DCU0_B1			0x0D4 0x000 ALT7 0x0
+#define VF610_PAD_PTC9__GPIO_54			0x0D8 0x000 ALT0 0x0
+#define VF610_PAD_PTC9__ENET_RMII1_MDC		0x0D8 0x000 ALT1 0x0
+#define VF610_PAD_PTC9__ESAI_SCKT		0x0D8 0x310 ALT3 0x1
+#define VF610_PAD_PTC9__MLB_CLK			0x0D8 0x354 ALT6 0x1
+#define VF610_PAD_PTC9__DEBUG_OUT0		0x0D8 0x000 ALT7 0x0
+#define VF610_PAD_PTC10__GPIO_55		0x0DC 0x000 ALT0 0x0
+#define VF610_PAD_PTC10__ENET_RMII1_MDIO	0x0DC 0x000 ALT1 0x0
+#define VF610_PAD_PTC10__ESAI_FST		0x0DC 0x30C ALT3 0x1
+#define VF610_PAD_PTC10__MLB_SIGNAL		0x0DC 0x35C ALT6 0x1
+#define VF610_PAD_PTC10__DEBUG_OUT1		0x0DC 0x000 ALT7 0x0
+#define VF610_PAD_PTC11__GPIO_56		0x0E0 0x000 ALT0 0x0
+#define VF610_PAD_PTC11__ENET_RMII1_CRS		0x0E0 0x000 ALT1 0x0
+#define VF610_PAD_PTC11__ESAI_SDO0		0x0E0 0x314 ALT3 0x1
+#define VF610_PAD_PTC11__MLB_DATA		0x0E0 0x358 ALT6 0x1
+#define VF610_PAD_PTC11__DEBUG_OUT		0x0E0 0x000 ALT7 0x0
+#define VF610_PAD_PTC12__GPIO_57		0x0E4 0x000 ALT0 0x0
+#define VF610_PAD_PTC12__ENET_RMII_RXD1		0x0E4 0x000 ALT1 0x0
+#define VF610_PAD_PTC12__ESAI_SDO1		0x0E4 0x318 ALT3 0x1
+#define VF610_PAD_PTC12__SAI2_TX_BCLK		0x0E4 0x370 ALT5 0x1
+#define VF610_PAD_PTC12__DEBUG_OUT3		0x0E4 0x000 ALT7 0x0
+#define VF610_PAD_PTC13__GPIO_58		0x0E8 0x000 ALT0 0x0
+#define VF610_PAD_PTC13__ENET_RMII1_RXD0	0x0E8 0x000 ALT1 0x0
+#define VF610_PAD_PTC13__ESAI_SDO2		0x0E8 0x31C ALT3 0x1
+#define VF610_PAD_PTC13__SAI2_RX_BCLK		0x0E8 0x364 ALT5 0x2
+#define VF610_PAD_PTC13__DEBUG_OUT4		0x0E8 0x000 ALT7 0x0
+#define VF610_PAD_PTC14__GPIO_59		0x0EC 0x000 ALT0 0x0
+#define VF610_PAD_PTC14__ENET_RMII1_RXER	0x0EC 0x000 ALT1 0x0
+#define VF610_PAD_PTC14__ESAI_SDO3		0x0EC 0x320 ALT3 0x1
+#define VF610_PAD_PTC14__UART5_TX		0x0EC 0x000 ALT4 0x0
+#define VF610_PAD_PTC14__SAI2_RX_DATA		0x0EC 0x368 ALT5 0x2
+#define VF610_PAD_PTC14__ADC0_SE6		0x0EC 0x000 ALT6 0x0
+#define VF610_PAD_PTC14__DEBUG_OUT5		0x0EC 0x000 ALT7 0x0
+#define VF610_PAD_PTC15__GPIO_60		0x0F0 0x000 ALT0 0x0
+#define VF610_PAD_PTC15__ENET_RMII1_TXD1	0x0F0 0x000 ALT1 0x0
+#define VF610_PAD_PTC15__ESAI_SDI0		0x0F0 0x328 ALT3 0x1
+#define VF610_PAD_PTC15__UART5_RX		0x0F0 0x000 ALT4 0x0
+#define VF610_PAD_PTC15__SAI2_TX_DATA		0x0F0 0x000 ALT5 0x0
+#define VF610_PAD_PTC15__ADC0_SE7		0x0F0 0x000 ALT6 0x0
+#define VF610_PAD_PTC15__DEBUG_OUT6		0x0F0 0x000 ALT7 0x0
+#define VF610_PAD_PTC16__GPIO_61		0x0F4 0x000 ALT0 0x0
+#define VF610_PAD_PTC16__ENET_RMII1_TXD0	0x0F4 0x000 ALT1 0x0
+#define VF610_PAD_PTC16__ESAI_SDI1		0x0F4 0x324 ALT3 0x1
+#define VF610_PAD_PTC16__UART5_RTS		0x0F4 0x000 ALT4 0x0
+#define VF610_PAD_PTC16__SAI2_RX_SYNC		0x0F4 0x36C ALT5 0x2
+#define VF610_PAD_PTC16__ADC1_SE6		0x0F4 0x000 ALT6 0x0
+#define VF610_PAD_PTC16__DEBUG_OUT7		0x0F4 0x000 ALT7 0x0
+#define VF610_PAD_PTC17__GPIO_62		0x0F8 0x000 ALT0 0x0
+#define VF610_PAD_PTC17__ENET_RMII1_TXEN	0x0F8 0x000 ALT1 0x0
+#define VF610_PAD_PTC17__ADC1_SE7		0x0F8 0x000 ALT3 0x0
+#define VF610_PAD_PTC17__UART5_CTS		0x0F8 0x000 ALT4 0x0
+#define VF610_PAD_PTC17__SAI2_TX_SYNC		0x0F8 0x374 ALT5 0x1
+#define VF610_PAD_PTC17__USB1_SOF_PULSE		0x0F8 0x000 ALT6 0x0
+#define VF610_PAD_PTC17__DEBUG_OUT8		0x0F8 0x000 ALT7 0x0
+#define VF610_PAD_PTD31__GPIO_63		0x0FC 0x000 ALT0 0x0
+#define VF610_PAD_PTD31__FB_AD31		0x0FC 0x000 ALT1 0x0
+#define VF610_PAD_PTD31__NF_IO15		0x0FC 0x000 ALT2 0x0
+#define VF610_PAD_PTD31__FTM3_CH0		0x0FC 0x000 ALT4 0x0
+#define VF610_PAD_PTD31__DSPI2_CS1		0x0FC 0x000 ALT5 0x0
+#define VF610_PAD_PTD31__DEBUG_OUT9		0x0FC 0x000 ALT7 0x0
+#define VF610_PAD_PTD30__GPIO_64		0x100 0x000 ALT0 0x0
+#define VF610_PAD_PTD30__FB_AD30		0x100 0x000 ALT1 0x0
+#define VF610_PAD_PTD30__NF_IO14		0x100 0x000 ALT2 0x0
+#define VF610_PAD_PTD30__FTM3_CH1		0x100 0x000 ALT4 0x0
+#define VF610_PAD_PTD30__DSPI2_CS0		0x100 0x000 ALT5 0x0
+#define VF610_PAD_PTD30__DEBUG_OUT10		0x100 0x000 ALT7 0x0
+#define VF610_PAD_PTD29__GPIO_65		0x104 0x000 ALT0 0x0
+#define VF610_PAD_PTD29__FB_AD29		0x104 0x000 ALT1 0x0
+#define VF610_PAD_PTD29__NF_IO13		0x104 0x000 ALT2 0x0
+#define VF610_PAD_PTD29__FTM3_CH2		0x104 0x000 ALT4 0x0
+#define VF610_PAD_PTD29__DSPI2_SIN		0x104 0x000 ALT5 0x0
+#define VF610_PAD_PTD29__DEBUG_OUT11		0x104 0x000 ALT7 0x0
+#define VF610_PAD_PTD28__GPIO_66	 	0x108 0x000 ALT0 0x0
+#define VF610_PAD_PTD28__FB_AD28		0x108 0x000 ALT1 0x0
+#define VF610_PAD_PTD28__NF_IO12		0x108 0x000 ALT2 0x0
+#define VF610_PAD_PTD28__I2C2_SCL		0x108 0x34C ALT3 0x1
+#define VF610_PAD_PTD28__FTM3_CH3		0x108 0x000 ALT4 0x0
+#define VF610_PAD_PTD28__DSPI2_SOUT		0x108 0x000 ALT5 0x0
+#define VF610_PAD_PTD28__DEBUG_OUT12		0x108 0x000 ALT7 0x0
+#define VF610_PAD_PTD27__GPIO_67		0x10C 0x000 ALT0 0x0
+#define VF610_PAD_PTD27__FB_AD27		0x10C 0x000 ALT1 0x0
+#define VF610_PAD_PTD27__NF_IO11		0x10C 0x000 ALT2 0x0
+#define VF610_PAD_PTD27__I2C2_SDA		0x10C 0x350 ALT3 0x1
+#define VF610_PAD_PTD27__FTM3_CH4		0x10C 0x000 ALT4 0x0
+#define VF610_PAD_PTD27__DSPI2_SCK		0x10C 0x000 ALT5 0x0
+#define VF610_PAD_PTD27__DEBUG_OUT13		0x10C 0x000 ALT7 0x0
+#define VF610_PAD_PTD26__GPIO_68		0x110 0x000 ALT0 0x0
+#define VF610_PAD_PTD26__FB_AD26		0x110 0x000 ALT1 0x0
+#define VF610_PAD_PTD26__NF_IO10		0x110 0x000 ALT2 0x0
+#define VF610_PAD_PTD26__FTM3_CH5		0x110 0x000 ALT4 0x0
+#define VF610_PAD_PTD26__ESDHC1_WP		0x110 0x000 ALT5 0x0
+#define VF610_PAD_PTD26__DEBUG_OUT14		0x110 0x000 ALT7 0x0
+#define VF610_PAD_PTD25__GPIO_69		0x114 0x000 ALT0 0x0
+#define VF610_PAD_PTD25__FB_AD25		0x114 0x000 ALT1 0x0
+#define VF610_PAD_PTD25__NF_IO9			0x114 0x000 ALT2 0x0
+#define VF610_PAD_PTD25__FTM3_CH6		0x114 0x000 ALT4 0x0
+#define VF610_PAD_PTD25__DEBUG_OUT15		0x114 0x000 ALT7 0x0
+#define VF610_PAD_PTD24__GPIO_70		0x118 0x000 ALT0 0x0
+#define VF610_PAD_PTD24__FB_AD24		0x118 0x000 ALT1 0x0
+#define VF610_PAD_PTD24__NF_IO8			0x118 0x000 ALT2 0x0
+#define VF610_PAD_PTD24__FTM3_CH7		0x118 0x000 ALT4 0x0
+#define VF610_PAD_PTD24__DEBUG_OUT16		0x118 0x000 ALT7 0x0
+#define VF610_PAD_PTD23__GPIO_71		0x11C 0x000 ALT0 0x0
+#define VF610_PAD_PTD23__FB_AD23		0x11C 0x000 ALT1 0x0
+#define VF610_PAD_PTD23__NF_IO7			0x11C 0x000 ALT2 0x0
+#define VF610_PAD_PTD23__FTM2_CH0		0x11C 0x000 ALT3 0x0
+#define VF610_PAD_PTD23__ENET0_1588_TMR0	0x11C 0x304 ALT4 0x1
+#define VF610_PAD_PTD23__ESDHC0_DAT4		0x11C 0x000 ALT5 0x0
+#define VF610_PAD_PTD23__UART2_TX		0x11C 0x38C ALT6 0x1
+#define VF610_PAD_PTD23__DCU1_R3		0x11C 0x000 ALT7 0x0
+#define VF610_PAD_PTD22__GPIO_72		0x120 0x000 ALT0 0x0
+#define VF610_PAD_PTD22__FB_AD22		0x120 0x000 ALT1 0x0
+#define VF610_PAD_PTD22__NF_IO6			0x120 0x000 ALT2 0x0
+#define VF610_PAD_PTD22__FTM2_CH1		0x120 0x000 ALT3 0x0
+#define VF610_PAD_PTD22__ENET0_1588_TMR1	0x120 0x308 ALT4 0x1
+#define VF610_PAD_PTD22__ESDHC0_DAT5		0x120 0x000 ALT5 0x0
+#define VF610_PAD_PTD22__UART2_RX		0x120 0x388 ALT6 0x1
+#define VF610_PAD_PTD22__DCU1_R4		0x120 0x000 ALT7 0x0
+#define VF610_PAD_PTD21__GPIO_73		0x124 0x000 ALT0 0x0
+#define VF610_PAD_PTD21__FB_AD21		0x124 0x000 ALT1 0x0
+#define VF610_PAD_PTD21__NF_IO5			0x124 0x000 ALT2 0x0
+#define VF610_PAD_PTD21__ENET0_1588_TMR2	0x124 0x000 ALT4 0x0
+#define VF610_PAD_PTD21__ESDHC0_DAT6		0x124 0x000 ALT5 0x0
+#define VF610_PAD_PTD21__UART2_RTS		0x124 0x000 ALT6 0x0
+#define VF610_PAD_PTD21__DCU1_R5		0x124 0x000 ALT7 0x0
+#define VF610_PAD_PTD20__GPIO_74		0x128 0x000 ALT0 0x0
+#define VF610_PAD_PTD20__FB_AD20		0x128 0x000 ALT1 0x0
+#define VF610_PAD_PTD20__NF_IO4			0x128 0x000 ALT2 0x0
+#define VF610_PAD_PTD20__ENET0_1588_TMR3	0x128 0x000 ALT4 0x0
+#define VF610_PAD_PTD20__ESDHC0_DAT7		0x128 0x000 ALT5 0x0
+#define VF610_PAD_PTD20__UART2_CTS		0x128 0x384 ALT6 0x0
+#define VF610_PAD_PTD20__DCU1_R0		0x128 0x000 ALT7 0x0
+#define VF610_PAD_PTD19__GPIO_75		0x12C 0x000 ALT0 0x0
+#define VF610_PAD_PTD19__FB_AD19		0x12C 0x000 ALT1 0x0
+#define VF610_PAD_PTD19__NF_IO3			0x12C 0x000 ALT2 0x0
+#define VF610_PAD_PTD19__ESAI_SCKR		0x12C 0x000 ALT3 0x0
+#define VF610_PAD_PTD19__I2C0_SCL		0x12C 0x33C ALT4 0x2
+#define VF610_PAD_PTD19__FTM2_QD_PHA		0x12C 0x000 ALT5 0x0
+#define VF610_PAD_PTD19__DCU1_R1		0x12C 0x000 ALT7 0x0
+#define VF610_PAD_PTD18__GPIO_76		0x130 0x000 ALT0 0x0
+#define VF610_PAD_PTD18__FB_AD18		0x130 0x000 ALT1 0x0
+#define VF610_PAD_PTD18__NF_IO2			0x130 0x000 ALT2 0x0
+#define VF610_PAD_PTD18__ESAI_FSR		0x130 0x000 ALT3 0x0
+#define VF610_PAD_PTD18__I2C0_SDA		0x130 0x340 ALT4 0x2
+#define VF610_PAD_PTD18__FTM2_QD_PHB		0x130 0x000 ALT5 0x0
+#define VF610_PAD_PTD18__DCU1_G0		0x130 0x000 ALT7 0x0
+#define VF610_PAD_PTD17__GPIO_77		0x134 0x000 ALT0 0x0
+#define VF610_PAD_PTD17__FB_AD17		0x134 0x000 ALT1 0x0
+#define VF610_PAD_PTD17__NF_IO1			0x134 0x000 ALT2 0x0
+#define VF610_PAD_PTD17__ESAI_HCKR		0x134 0x000 ALT3 0x0
+#define VF610_PAD_PTD17__I2C1_SCL		0x134 0x344 ALT4 0x2
+#define VF610_PAD_PTD17__DCU1_G1		0x134 0x000 ALT7 0x0
+#define VF610_PAD_PTD16__GPIO_78		0x138 0x000 ALT0 0x0
+#define VF610_PAD_PTD16__FB_AD16		0x138 0x000 ALT1 0x0
+#define VF610_PAD_PTD16__NF_IO0			0x138 0x000 ALT2 0x0
+#define VF610_PAD_PTD16__ESAI_HCKT		0x138 0x000 ALT3 0x0
+#define VF610_PAD_PTD16__I2C1_SDA		0x138 0x348 ALT4 0x2
+#define VF610_PAD_PTD16__DCU1_G2		0x138 0x000 ALT7 0x0
+#define VF610_PAD_PTD0__GPIO_79			0x13C 0x000 ALT0 0x0
+#define VF610_PAD_PTD0__QSPI0_A_QSCK		0x13C 0x000 ALT1 0x0
+#define VF610_PAD_PTD0__UART2_TX		0x13C 0x38C ALT2 0x2
+#define VF610_PAD_PTD0__FB_AD15			0x13C 0x000 ALT4 0x0
+#define VF610_PAD_PTD0__SPDIF_EXTCLK		0x13C 0x000 ALT5 0x0
+#define VF610_PAD_PTD0__DEBUG_OUT17		0x13C 0x000 ALT7 0x0
+#define VF610_PAD_PTD1__GPIO_80			0x140 0x000 ALT0 0x0
+#define VF610_PAD_PTD1__QSPI0_A_CS0		0x140 0x000 ALT1 0x0
+#define VF610_PAD_PTD1__UART2_RX		0x140 0x388 ALT2 0x2
+#define VF610_PAD_PTD1__FB_AD14			0x140 0x000 ALT4 0x0
+#define VF610_PAD_PTD1__SPDIF_IN1		0x140 0x000 ALT5 0x0
+#define VF610_PAD_PTD1__DEBUG_OUT18		0x140 0x000 ALT7 0x0
+#define VF610_PAD_PTD2__GPIO_81			0x144 0x000 ALT0 0x0
+#define VF610_PAD_PTD2__QSPI0_A_DATA3		0x144 0x000 ALT1 0x0
+#define VF610_PAD_PTD2__UART2_RTS		0x144 0x000 ALT2 0x0
+#define VF610_PAD_PTD2__DSPI1_CS3		0x144 0x000 ALT3 0x0
+#define VF610_PAD_PTD2__FB_AD13			0x144 0x000 ALT4 0x0
+#define VF610_PAD_PTD2__SPDIF_OUT1		0x144 0x000 ALT5 0x0
+#define VF610_PAD_PTD2__DEBUG_OUT19		0x144 0x000 ALT7 0x0
+#define VF610_PAD_PTD3__GPIO_82			0x148 0x000 ALT0 0x0
+#define VF610_PAD_PTD3__QSPI0_A_DATA2		0x148 0x000 ALT1 0x0
+#define VF610_PAD_PTD3__UART2_CTS		0x148 0x384 ALT2 0x1
+#define VF610_PAD_PTD3__DSPI1_CS2		0x148 0x000 ALT3 0x0
+#define VF610_PAD_PTD3__FB_AD12			0x148 0x000 ALT4 0x0
+#define VF610_PAD_PTD3__SPDIF_PLOCK		0x148 0x000 ALT5 0x0
+#define VF610_PAD_PTD3__DEBUG_OUT20		0x148 0x000 ALT7 0x0
+#define VF610_PAD_PTD4__GPIO_83			0x14C 0x000 ALT0 0x0
+#define VF610_PAD_PTD4__QSPI0_A_DATA1		0x14C 0x000 ALT1 0x0
+#define VF610_PAD_PTD4__DSPI1_CS1		0x14C 0x000 ALT3 0x0
+#define VF610_PAD_PTD4__FB_AD11			0x14C 0x000 ALT4 0x0
+#define VF610_PAD_PTD4__SPDIF_SRCLK		0x14C 0x000 ALT5 0x0
+#define VF610_PAD_PTD4__DEBUG_OUT21		0x14C 0x000 ALT7 0x0
+#define VF610_PAD_PTD5__GPIO_84			0x150 0x000 ALT0 0x0
+#define VF610_PAD_PTD5__QSPI0_A_DATA0		0x150 0x000 ALT1 0x0
+#define VF610_PAD_PTD5__DSPI1_CS0		0x150 0x300 ALT3 0x1
+#define VF610_PAD_PTD5__FB_AD10			0x150 0x000 ALT4 0x0
+#define VF610_PAD_PTD5__DEBUG_OUT22		0x150 0x000 ALT7 0x0
+#define VF610_PAD_PTD6__GPIO_85			0x154 0x000 ALT0 0x0
+#define VF610_PAD_PTD6__QSPI1_A_DQS		0x154 0x000 ALT1 0x0
+#define VF610_PAD_PTD6__DSPI1_SIN		0x154 0x2FC ALT3 0x1
+#define VF610_PAD_PTD6__FB_AD9			0x154 0x000 ALT4 0x0
+#define VF610_PAD_PTD6__DEBUG_OUT23		0x154 0x000 ALT7 0x0
+#define VF610_PAD_PTD7__GPIO_86			0x158 0x000 ALT0 0x0
+#define VF610_PAD_PTD7__QSPI0_B_QSCK		0x158 0x000 ALT1 0x0
+#define VF610_PAD_PTD7__DSPI1_SOUT		0x158 0x000 ALT3 0x0
+#define VF610_PAD_PTD7__FB_AD8			0x158 0x000 ALT4 0x0
+#define VF610_PAD_PTD7__DEBUG_OUT24		0x158 0x000 ALT7 0x0
+#define VF610_PAD_PTD8__GPIO_87			0x15C 0x000 ALT0 0x0
+#define VF610_PAD_PTD8__QSPI0_B_CS0		0x15C 0x000 ALT1 0x0
+#define VF610_PAD_PTD8__FB_CLKOUT		0x15C 0x000 ALT2 0x0
+#define VF610_PAD_PTD8__DSPI1_SCK		0x15C 0x2F8 ALT3 0x1
+#define VF610_PAD_PTD8__FB_AD7			0x15C 0x000 ALT4 0x0
+#define VF610_PAD_PTD8__DEBUG_OUT25		0x15C 0x000 ALT7 0x0
+#define VF610_PAD_PTD9__GPIO_88			0x160 0x000 ALT0 0x0
+#define VF610_PAD_PTD9__QSPI0_B_DATA3		0x160 0x000 ALT1 0x0
+#define VF610_PAD_PTD9__DSPI3_CS1		0x160 0x000 ALT2 0x0
+#define VF610_PAD_PTD9__FB_AD6			0x160 0x000 ALT4 0x0
+#define VF610_PAD_PTD9__SAI1_TX_SYNC		0x160 0x360 ALT6 0x0
+#define VF610_PAD_PTD9__DCU1_B0			0x160 0x000 ALT7 0x0
+#define VF610_PAD_PTD10__GPIO_89		0x164 0x000 ALT0 0x0
+#define VF610_PAD_PTD10__QSPI0_B_DATA2		0x164 0x000 ALT1 0x0
+#define VF610_PAD_PTD10__DSPI3_CS0		0x164 0x000 ALT2 0x0
+#define VF610_PAD_PTD10__FB_AD5			0x164 0x000 ALT4 0x0
+#define VF610_PAD_PTD10__DCU1_B1		0x164 0x000 ALT7 0x0
+#define VF610_PAD_PTD11__GPIO_90		0x168 0x000 ALT0 0x0
+#define VF610_PAD_PTD11__QSPI0_B_DATA1		0x168 0x000 ALT1 0x0
+#define VF610_PAD_PTD11__DSPI3_SIN		0x168 0x000 ALT2 0x0
+#define VF610_PAD_PTD11__FB_AD4			0x168 0x000 ALT4 0x0
+#define VF610_PAD_PTD11__DEBUG_OUT26		0x168 0x000 ALT7 0x0
+#define VF610_PAD_PTD12__GPIO_91		0x16C 0x000 ALT0 0x0
+#define VF610_PAD_PTD12__QSPI0_B_DATA0		0x16C 0x000 ALT1 0x0
+#define VF610_PAD_PTD12__DSPI3_SOUT		0x16C 0x000 ALT2 0x0
+#define VF610_PAD_PTD12__FB_AD3			0x16C 0x000 ALT4 0x0
+#define VF610_PAD_PTD12__DEBUG_OUT27		0x16C 0x000 ALT7 0x0
+#define VF610_PAD_PTD13__GPIO_92		0x170 0x000 ALT0 0x0
+#define VF610_PAD_PTD13__QSPI0_B_DQS		0x170 0x000 ALT1 0x0
+#define VF610_PAD_PTD13__DSPI3_SCK		0x170 0x000 ALT2 0x0
+#define VF610_PAD_PTD13__FB_AD2			0x170 0x000 ALT4 0x0
+#define VF610_PAD_PTD13__DEBUG_OUT28		0x170 0x000 ALT7 0x0
+#define VF610_PAD_PTB23__GPIO_93		0x174 0x000 ALT0 0x0
+#define VF610_PAD_PTB23__SAI0_TX_BCLK		0x174 0x000 ALT1 0x0
+#define VF610_PAD_PTB23__UART1_TX		0x174 0x380 ALT2 0x2
+#define VF610_PAD_PTB23__SRC_RCON18		0x174 0x398 ALT3 0x1
+#define VF610_PAD_PTB23__FB_MUXED_ALE		0x174 0x000 ALT4 0x0
+#define VF610_PAD_PTB23__FB_TS_B		0x174 0x000 ALT5 0x0
+#define VF610_PAD_PTB23__UART3_RTS		0x174 0x000 ALT6 0x0
+#define VF610_PAD_PTB23__DCU1_G3		0x174 0x000 ALT7 0x0
+#define VF610_PAD_PTB24__GPIO_94		0x178 0x000 ALT0 0x0
+#define VF610_PAD_PTB24__SAI0_RX_BCLK		0x178 0x000 ALT1 0x0
+#define VF610_PAD_PTB24__UART1_RX		0x178 0x37C ALT2 0x2
+#define VF610_PAD_PTB24__SRC_RCON19		0x178 0x39C ALT3 0x1
+#define VF610_PAD_PTB24__FB_MUXED_TSIZ0		0x178 0x000 ALT4 0x0
+#define VF610_PAD_PTB24__NF_WE_B		0x178 0x000 ALT5 0x0
+#define VF610_PAD_PTB24__UART3_CTS		0x178 0x000 ALT6 0x0
+#define VF610_PAD_PTB24__DCU1_G4		0x178 0x000 ALT7 0x0
+#define VF610_PAD_PTB25__GPIO_95		0x17C 0x000 ALT0 0x0
+#define VF610_PAD_PTB25__SAI0_RX_DATA		0x17C 0x000 ALT1 0x0
+#define VF610_PAD_PTB25__UART1_RTS		0x17C 0x000 ALT2 0x0
+#define VF610_PAD_PTB25__SRC_RCON20		0x17C 0x3A0 ALT3 0x1
+#define VF610_PAD_PTB25__FB_CS1_B		0x17C 0x000 ALT4 0x0
+#define VF610_PAD_PTB25__NF_CE0_B		0x17C 0x000 ALT5 0x0
+#define VF610_PAD_PTB25__DCU1_G5		0x17C 0x000 ALT7 0x0
+#define VF610_PAD_PTB26__GPIO_96		0x180 0x000 ALT0 0x0
+#define VF610_PAD_PTB26__SAI0_TX_DATA		0x180 0x000 ALT1 0x0
+#define VF610_PAD_PTB26__UART1_CTS		0x180 0x378 ALT2 0x2
+#define VF610_PAD_PTB26__SRC_RCON21		0x180 0x000 ALT3 0x0
+#define VF610_PAD_PTB26__FB_CS0_B		0x180 0x000 ALT4 0x0
+#define VF610_PAD_PTB26__NF_CE1_B		0x180 0x000 ALT5 0x0
+#define VF610_PAD_PTB26__DCU1_G6		0x180 0x000 ALT7 0x0
+#define VF610_PAD_PTB27__GPIO_97		0x184 0x000 ALT0 0x0
+#define VF610_PAD_PTB27__SAI0_RX_SYNC		0x184 0x000 ALT1 0x0
+#define VF610_PAD_PTB27__SRC_RCON22		0x184 0x000 ALT3 0x0
+#define VF610_PAD_PTB27__FB_OE_B		0x184 0x000 ALT4 0x0
+#define VF610_PAD_PTB27__FB_MUXED_TBST_B	0x184 0x000 ALT5 0x0
+#define VF610_PAD_PTB27__NF_RE_B		0x184 0x000 ALT6 0x0
+#define VF610_PAD_PTB27__DCU1_G7		0x184 0x000 ALT7 0x0
+#define VF610_PAD_PTB28__GPIO_98		0x188 0x000 ALT0 0x0
+#define VF610_PAD_PTB28__SAI0_TX_SYNC		0x188 0x000 ALT1 0x0
+#define VF610_PAD_PTB28__SRC_RCON23		0x188 0x000 ALT3 0x0
+#define VF610_PAD_PTB28__FB_RW_B		0x188 0x000 ALT4 0x0
+#define VF610_PAD_PTB28__DCU1_B6		0x188 0x000 ALT7 0x0
+#define VF610_PAD_PTC26__GPIO_99		0x18C 0x000 ALT0 0x0
+#define VF610_PAD_PTC26__SAI1_TX_BCLK		0x18C 0x000 ALT1 0x0
+#define VF610_PAD_PTC26__DSPI0_CS5		0x18C 0x000 ALT2 0x0
+#define VF610_PAD_PTC26__SRC_RCON24		0x18C 0x000 ALT3 0x0
+#define VF610_PAD_PTC26__FB_TA_B		0x18C 0x000 ALT4 0x0
+#define VF610_PAD_PTC26__NF_RB_B		0x18C 0x000 ALT5 0x0
+#define VF610_PAD_PTC26__DCU1_B7		0x18C 0x000 ALT7 0x0
+#define VF610_PAD_PTC27__GPIO_100		0x190 0x000 ALT0 0x0
+#define VF610_PAD_PTC27__SAI1_RX_BCLK		0x190 0x000 ALT1 0x0
+#define VF610_PAD_PTC27__DSPI0_CS4		0x190 0x000 ALT2 0x0
+#define VF610_PAD_PTC27__SRC_RCON25		0x190 0x000 ALT3 0x0
+#define VF610_PAD_PTC27__FB_BE3_B		0x190 0x000 ALT4 0x0
+#define VF610_PAD_PTC27__FB_CS3_B		0x190 0x000 ALT5 0x0
+#define VF610_PAD_PTC27__NF_ALE			0x190 0x000 ALT6 0x0
+#define VF610_PAD_PTC27__DCU1_B2		0x190 0x000 ALT7 0x0
+#define VF610_PAD_PTC28__GPIO_101		0x194 0x000 ALT0 0x0
+#define VF610_PAD_PTC28__SAI1_RX_DATA		0x194 0x000 ALT1 0x0
+#define VF610_PAD_PTC28__DSPI0_CS3		0x194 0x000 ALT2 0x0
+#define VF610_PAD_PTC28__SRC_RCON26		0x194 0x000 ALT3 0x0
+#define VF610_PAD_PTC28__FB_BE2_B		0x194 0x000 ALT4 0x0
+#define VF610_PAD_PTC28__FB_CS2_B		0x194 0x000 ALT5 0x0
+#define VF610_PAD_PTC28__NF_CLE			0x194 0x000 ALT6 0x0
+#define VF610_PAD_PTC28__DCU1_B3		0x194 0x000 ALT7 0x0
+#define VF610_PAD_PTC29__GPIO_102		0x198 0x000 ALT0 0x0
+#define VF610_PAD_PTC29__SAI1_TX_DATA		0x198 0x000 ALT1 0x0
+#define VF610_PAD_PTC29__DSPI0_CS2		0x198 0x000 ALT2 0x0
+#define VF610_PAD_PTC29__SRC_RCON27		0x198 0x000 ALT3 0x0
+#define VF610_PAD_PTC29__FB_BE1_B		0x198 0x000 ALT4 0x0
+#define VF610_PAD_PTC29__FB_MUXED_TSIZE1	0x198 0x000 ALT5 0x0
+#define VF610_PAD_PTC29__DCU1_B4		0x198 0x000 ALT7 0x0
+#define VF610_PAD_PTC30__GPIO_103		0x19C 0x000 ALT0 0x0
+#define VF610_PAD_PTC30__SAI1_RX_SYNC		0x19C 0x000 ALT1 0x0
+#define VF610_PAD_PTC30__DSPI1_CS2		0x19C 0x000 ALT2 0x0
+#define VF610_PAD_PTC30__SRC_RCON28		0x19C 0x000 ALT3 0x0
+#define VF610_PAD_PTC30__FB_MUXED_BE0_B		0x19C 0x000 ALT4 0x0
+#define VF610_PAD_PTC30__FB_TSIZ0		0x19C 0x000 ALT5 0x0
+#define VF610_PAD_PTC30__ADC0_SE5		0x19C 0x000 ALT6 0x0
+#define VF610_PAD_PTC30__DCU1_B5		0x19C 0x000 ALT7 0x0
+#define VF610_PAD_PTC31__GPIO_104		0x1A0 0x000 ALT0 0x0
+#define VF610_PAD_PTC31__SAI1_TX_SYNC		0x1A0 0x360 ALT1 0x1
+#define VF610_PAD_PTC31__SRC_RCON29		0x1A0 0x000 ALT3 0x0
+#define VF610_PAD_PTC31__ADC1_SE5		0x1A0 0x000 ALT6 0x0
+#define VF610_PAD_PTC31__DCU1_B6		0x1A0 0x000 ALT7 0x0
+#define VF610_PAD_PTE0__GPIO_105		0x1A4 0x000 ALT0 0x0
+#define VF610_PAD_PTE0__DCU0_HSYNC		0x1A4 0x000 ALT1 0x0
+#define VF610_PAD_PTE0__SRC_BMODE1		0x1A4 0x000 ALT2 0x0
+#define VF610_PAD_PTE0__LCD0			0x1A4 0x000 ALT4 0x0
+#define VF610_PAD_PTE0__DEBUG_OUT29		0x1A4 0x000 ALT7 0x0
+#define VF610_PAD_PTE1__GPIO_106		0x1A8 0x000 ALT0 0x0
+#define VF610_PAD_PTE1__DCU0_VSYNC		0x1A8 0x000 ALT1 0x0
+#define VF610_PAD_PTE1__SRC_BMODE0		0x1A8 0x000 ALT2 0x0
+#define VF610_PAD_PTE1__LCD1			0x1A8 0x000 ALT4 0x0
+#define VF610_PAD_PTE1__DEBUG_OUT30		0x1A8 0x000 ALT7 0x0
+#define VF610_PAD_PTE2__GPIO_107		0x1AC 0x000 ALT0 0x0
+#define VF610_PAD_PTE2__DCU0_PCLK		0x1AC 0x000 ALT1 0x0
+#define VF610_PAD_PTE2__LCD2			0x1AC 0x000 ALT4 0x0
+#define VF610_PAD_PTE2__DEBUG_OUT31		0x1AC 0x000 ALT7 0x0
+#define VF610_PAD_PTE3__GPIO_108		0x1B0 0x000 ALT0 0x0
+#define VF610_PAD_PTE3__DCU0_TAG		0x1B0 0x000 ALT1 0x0
+#define VF610_PAD_PTE3__LCD3			0x1B0 0x000 ALT4 0x0
+#define VF610_PAD_PTE3__DEBUG_OUT32		0x1B0 0x000 ALT7 0x0
+#define VF610_PAD_PTE4__GPIO_109		0x1B4 0x000 ALT0 0x0
+#define VF610_PAD_PTE4__DCU0_DE			0x1B4 0x000 ALT1 0x0
+#define VF610_PAD_PTE4__LCD4			0x1B4 0x000 ALT4 0x0
+#define VF610_PAD_PTE4__DEBUG_OUT33		0x1B4 0x000 ALT7 0x0
+#define VF610_PAD_PTE5__GPIO_110		0x1B8 0x000 ALT0 0x0
+#define VF610_PAD_PTE5__DCU0_R0			0x1B8 0x000 ALT1 0x0
+#define VF610_PAD_PTE5__LCD5			0x1B8 0x000 ALT4 0x0
+#define VF610_PAD_PTE5__DEBUG_OUT34		0x1B8 0x000 ALT7 0x0
+#define VF610_PAD_PTE6__GPIO_111		0x1BC 0x000 ALT0 0x0
+#define VF610_PAD_PTE6__DCU0_R1			0x1BC 0x000 ALT1 0x0
+#define VF610_PAD_PTE6__LCD6			0x1BC 0x000 ALT4 0x0
+#define VF610_PAD_PTE6__DEBUG_OUT35		0x1BC 0x000 ALT7 0x0
+#define VF610_PAD_PTE7__GPIO_112		0x1C0 0x000 ALT0 0x0
+#define VF610_PAD_PTE7__DCU0_R2			0x1C0 0x000 ALT1 0x0
+#define VF610_PAD_PTE7__SRC_RCON0		0x1C0 0x000 ALT3 0x0
+#define VF610_PAD_PTE7__LCD7			0x1C0 0x000 ALT4 0x0
+#define VF610_PAD_PTE7__DEBUG_OUT36		0x1C0 0x000 ALT7 0x0
+#define VF610_PAD_PTE8__GPIO_113		0x1C4 0x000 ALT0 0x0
+#define VF610_PAD_PTE8__DCU0_R3			0x1C4 0x000 ALT1 0x0
+#define VF610_PAD_PTE8__SRC_RCON1		0x1C4 0x000 ALT3 0x0
+#define VF610_PAD_PTE8__LCD8			0x1C4 0x000 ALT4 0x0
+#define VF610_PAD_PTE8__DEBUG_OUT37		0x1C4 0x000 ALT7 0x0
+#define VF610_PAD_PTE9__GPIO_114		0x1C8 0x000 ALT0 0x0
+#define VF610_PAD_PTE9__DCU0_R4			0x1C8 0x000 ALT1 0x0
+#define VF610_PAD_PTE9__SRC_RCON2		0x1C8 0x000 ALT3 0x0
+#define VF610_PAD_PTE9__LCD9			0x1C8 0x000 ALT4 0x0
+#define VF610_PAD_PTE9__DEBUG_OUT38		0x1C8 0x000 ALT7 0x0
+#define VF610_PAD_PTE10__GPIO_115		0x1CC 0x000 ALT0 0x0
+#define VF610_PAD_PTE10__DCU0_R5		0x1CC 0x000 ALT1 0x0
+#define VF610_PAD_PTE10__SRC_RCON3		0x1CC 0x000 ALT3 0x0
+#define VF610_PAD_PTE10__LCD10			0x1CC 0x000 ALT4 0x0
+#define VF610_PAD_PTE10__DEBUG_OUT39		0x1CC 0x000 ALT7 0x0
+#define VF610_PAD_PTE11__GPIO_116		0x1D0 0x000 ALT0 0x0
+#define VF610_PAD_PTE11__DCU0_R6		0x1D0 0x000 ALT1 0x0
+#define VF610_PAD_PTE11__SRC_RCON4		0x1D0 0x000 ALT3 0x0
+#define VF610_PAD_PTE11__LCD11			0x1D0 0x000 ALT4 0x0
+#define VF610_PAD_PTE11__DEBUG_OUT40		0x1D0 0x000 ALT7 0x0
+#define VF610_PAD_PTE12__GPIO_117		0x1D4 0x000 ALT0 0x0
+#define VF610_PAD_PTE12__DCU0_R7		0x1D4 0x000 ALT1 0x0
+#define VF610_PAD_PTE12__DSPI1_CS3		0x1D4 0x000 ALT2 0x0
+#define VF610_PAD_PTE12__SRC_RCON5		0x1D4 0x000 ALT3 0x0
+#define VF610_PAD_PTE12__LCD12			0x1D4 0x000 ALT4 0x0
+#define VF610_PAD_PTE12__LPT_ALT0		0x1D4 0x000 ALT7 0x0
+#define VF610_PAD_PTE13__GPIO_118		0x1D8 0x000 ALT0 0x0
+#define VF610_PAD_PTE13__DCU0_G0		0x1D8 0x000 ALT1 0x0
+#define VF610_PAD_PTE13__LCD13			0x1D8 0x000 ALT4 0x0
+#define VF610_PAD_PTE13__DEBUG_OUT41		0x1D8 0x000 ALT7 0x0
+#define VF610_PAD_PTE14__GPIO_119		0x1DC 0x000 ALT0 0x0
+#define VF610_PAD_PTE14__DCU0_G1		0x1DC 0x000 ALT1 0x0
+#define VF610_PAD_PTE14__LCD14			0x1DC 0x000 ALT4 0x0
+#define VF610_PAD_PTE14__DEBUG_OUT42		0x1DC 0x000 ALT7 0x0
+#define VF610_PAD_PTE15__GPIO_120		0x1E0 0x000 ALT0 0x0
+#define VF610_PAD_PTE15__DCU0_G2		0x1E0 0x000 ALT1 0x0
+#define VF610_PAD_PTE15__SRC_RCON6		0x1E0 0x000 ALT3 0x0
+#define VF610_PAD_PTE15__LCD15			0x1E0 0x000 ALT4 0x0
+#define VF610_PAD_PTE15__DEBUG_OUT43		0x1E0 0x000 ALT7 0x0
+#define VF610_PAD_PTE16__GPIO_121		0x1E4 0x000 ALT0 0x0
+#define VF610_PAD_PTE16__DCU0_G3		0x1E4 0x000 ALT1 0x0
+#define VF610_PAD_PTE16__SRC_RCON7		0x1E4 0x000 ALT3 0x0
+#define VF610_PAD_PTE16__LCD16			0x1E4 0x000 ALT4 0x0
+#define VF610_PAD_PTE17__GPIO_122		0x1E8 0x000 ALT0 0x0
+#define VF610_PAD_PTE17__DCU0_G4		0x1E8 0x000 ALT1 0x0
+#define VF610_PAD_PTE17__SRC_RCON8		0x1E8 0x000 ALT3 0x0
+#define VF610_PAD_PTE17__LCD17			0x1E8 0x000 ALT4 0x0
+#define VF610_PAD_PTE18__GPIO_123		0x1EC 0x000 ALT0 0x0
+#define VF610_PAD_PTE18__DCU0_G5		0x1EC 0x000 ALT1 0x0
+#define VF610_PAD_PTE18__SRC_RCON9		0x1EC 0x000 ALT3 0x0
+#define VF610_PAD_PTE18__LCD18			0x1EC 0x000 ALT4 0x0
+#define VF610_PAD_PTE19__GPIO_124		0x1F0 0x000 ALT0 0x0
+#define VF610_PAD_PTE19__DCU0_G6		0x1F0 0x000 ALT1 0x0
+#define VF610_PAD_PTE19__SRC_RCON10		0x1F0 0x000 ALT3 0x0
+#define VF610_PAD_PTE19__LCD19			0x1F0 0x000 ALT4 0x0
+#define VF610_PAD_PTE19__I2C0_SCL		0x1F0 0x33C ALT5 0x3
+#define VF610_PAD_PTE20__GPIO_125		0x1F4 0x000 ALT0 0x0
+#define VF610_PAD_PTE20__DCU0_G7		0x1F4 0x000 ALT1 0x0
+#define VF610_PAD_PTE20__SRC_RCON11		0x1F4 0x000 ALT3 0x0
+#define VF610_PAD_PTE20__LCD20			0x1F4 0x000 ALT4 0x0
+#define VF610_PAD_PTE20__I2C0_SDA		0x1F4 0x340 ALT5 0x3
+#define VF610_PAD_PTE20__EWM_IN			0x1F4 0x000 ALT7 0x0
+#define VF610_PAD_PTE21__GPIO_126		0x1F8 0x000 ALT0 0x0
+#define VF610_PAD_PTE21__DCU0_B0		0x1F8 0x000 ALT1 0x0
+#define VF610_PAD_PTE21__LCD21			0x1F8 0x000 ALT4 0x0
+#define VF610_PAD_PTE22__GPIO_127		0x1FC 0x000 ALT0 0x0
+#define VF610_PAD_PTE22__DCU0_B1		0x1FC 0x000 ALT1 0x0
+#define VF610_PAD_PTE22__LCD22			0x1FC 0x000 ALT4 0x0
+#define VF610_PAD_PTE23__GPIO_128		0x200 0x000 ALT0 0x0
+#define VF610_PAD_PTE23__DCU0_B2		0x200 0x000 ALT1 0x0
+#define VF610_PAD_PTE23__SRC_RCON12		0x200 0x000 ALT3 0x0
+#define VF610_PAD_PTE23__LCD23			0x200 0x000 ALT4 0x0
+#define VF610_PAD_PTE24__GPIO_129		0x204 0x000 ALT0 0x0
+#define VF610_PAD_PTE24__DCU0_B3		0x204 0x000 ALT1 0x0
+#define VF610_PAD_PTE24__SRC_RCON13		0x204 0x000 ALT3 0x0
+#define VF610_PAD_PTE24__LCD24			0x204 0x000 ALT4 0x0
+#define VF610_PAD_PTE25__GPIO_130		0x208 0x000 ALT0 0x0
+#define VF610_PAD_PTE25__DCU0_B4		0x208 0x000 ALT1 0x0
+#define VF610_PAD_PTE25__SRC_RCON14		0x208 0x000 ALT3 0x0
+#define VF610_PAD_PTE25__LCD25			0x208 0x000 ALT4 0x0
+#define VF610_PAD_PTE26__GPIO_131		0x20C 0x000 ALT0 0x0
+#define VF610_PAD_PTE26__DCU0_B5		0x20C 0x000 ALT1 0x0
+#define VF610_PAD_PTE26__SRC_RCON15		0x20C 0x000 ALT3 0x0
+#define VF610_PAD_PTE26__LCD26			0x20C 0x000 ALT4 0x0
+#define VF610_PAD_PTE27__GPIO_132		0x210 0x000 ALT0 0x0
+#define VF610_PAD_PTE27__DCU0_B6		0x210 0x000 ALT1 0x0
+#define VF610_PAD_PTE27__SRC_RCON16		0x210 0x000 ALT3 0x0
+#define VF610_PAD_PTE27__LCD27			0x210 0x000 ALT4 0x0
+#define VF610_PAD_PTE27__I2C1_SCL		0x210 0x344 ALT5 0x3
+#define VF610_PAD_PTE28__GPIO_133		0x214 0x000 ALT0 0x0
+#define VF610_PAD_PTE28__DCU0_B7		0x214 0x000 ALT1 0x0
+#define VF610_PAD_PTE28__SRC_RCON17		0x214 0x000 ALT3 0x0
+#define VF610_PAD_PTE28__LCD28			0x214 0x000 ALT4 0x0
+#define VF610_PAD_PTE28__I2C1_SDA		0x214 0x348 ALT5 0x3
+#define VF610_PAD_PTE28__EWM_OUT		0x214 0x000 ALT7 0x0
+#define VF610_PAD_PTA7__GPIO_134		0x218 0x000 ALT0 0x0
+#define VF610_PAD_PTA7__VIU_PIX_CLK		0x218 0x3AC ALT1 0x1
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/vf610-twr.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vf610-twr.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/vf610-twr.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vf610-twr.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/dts-v1/;
+#include "vf610.dtsi"
+
+/ {
+	model = "VF610 Tower Board";
+	compatible = "fsl,vf610-twr", "fsl,vf610";
+
+	chosen {
+		bootargs = "console=ttyLP1,115200";
+	};
+
+	memory {
+		reg = <0x80000000 0x8000000>;
+	};
+
+	clocks {
+		audio_ext {
+			compatible = "fixed-clock";
+			clock-frequency = <24576000>;
+		};
+
+		enet_ext {
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+	};
+
+};
+
+&fec0 {
+	phy-mode = "rmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec0_1>;
+	status = "okay";
+};
+
+&fec1 {
+	phy-mode = "rmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_fec1_1>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1_1>;
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/vt8500-bv07.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vt8500-bv07.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/vt8500-bv07.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vt8500-bv07.dts	2013-08-25 20:43:22.000000000 -0400
@@ -30,3 +30,7 @@
 		};
 	};
 };
+
+&uart0 {
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/vt8500.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vt8500.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/vt8500.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/vt8500.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,23 @@
 / {
 	compatible = "via,vt8500";
 
+	cpus {
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			device_type = "cpu";
+			compatible = "arm,arm926ej-s";
+		};
+	};
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -111,32 +128,36 @@
 			reg = <0xd8050400 0x100>;
 		};
 
-		uart@d8200000 {
+		uart0: serial@d8200000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd8200000 0x1040>;
 			interrupts = <32>;
 			clocks = <&clkuart0>;
+			status = "disabled";
 		};
 
-		uart@d82b0000 {
+		uart1: serial@d82b0000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd82b0000 0x1040>;
 			interrupts = <33>;
 			clocks = <&clkuart1>;
+			status = "disabled";
 		};
 
-		uart@d8210000 {
+		uart2: serial@d8210000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd8210000 0x1040>;
 			interrupts = <47>;
 			clocks = <&clkuart2>;
+			status = "disabled";
 		};
 
-		uart@d82c0000 {
+		uart3: serial@d82c0000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd82c0000 0x1040>;
 			interrupts = <50>;
 			clocks = <&clkuart3>;
+			status = "disabled";
 		};
 
 		rtc@d8100000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/wm8505.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8505.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/wm8505.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8505.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -12,11 +12,24 @@
 	compatible = "wm,wm8505";
 
 	cpus {
-		cpu@0 {
-			compatible = "arm,arm926ejs";
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			device_type = "cpu";
+			compatible = "arm,arm926ej-s";
 		};
 	};
 
+ 	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		serial5 = &uart5;
+ 	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -68,6 +81,13 @@
 					clock-frequency = <25000000>;
 				};
 
+				plla: plla {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x200>;
+				};
+
 				pllb: pllb {
 					#clock-cells = <0>;
 					compatible = "via,vt8500-pll-clock";
@@ -75,6 +95,48 @@
 					reg = <0x204>;
 				};
 
+				pllc: pllc {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x208>;
+				};
+
+				plld: plld {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x20c>;
+				};
+
+				clkarm: arm {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&plla>;
+					divisor-reg = <0x300>;
+				};
+
+				clkahb: ahb {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x304>;
+				};
+
+				clkapb: apb {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x350>;
+				};
+
+				clkddr: ddr {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&plld>;
+					divisor-reg = <0x310>;
+				};
+
 				clkuart0: uart0 {
 					#clock-cells = <0>;
 					compatible = "via,vt8500-device-clock";
@@ -163,46 +225,52 @@
 			reg = <0xd8050400 0x100>;
 		};
 
-		uart@d8200000 {
+		uart0: serial@d8200000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd8200000 0x1040>;
 			interrupts = <32>;
 			clocks = <&clkuart0>;
+			status = "disabled";
 		};
 
-		uart@d82b0000 {
+		uart1: serial@d82b0000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd82b0000 0x1040>;
 			interrupts = <33>;
 			clocks = <&clkuart1>;
+			status = "disabled";
 		};
 
-		uart@d8210000 {
+		uart2: serial@d8210000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd8210000 0x1040>;
 			interrupts = <47>;
 			clocks = <&clkuart2>;
+			status = "disabled";
 		};
 
-		uart@d82c0000 {
+		uart3: serial@d82c0000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd82c0000 0x1040>;
 			interrupts = <50>;
 			clocks = <&clkuart3>;
+			status = "disabled";
 		};
 
-		uart@d8370000 {
+		uart4: serial@d8370000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd8370000 0x1040>;
 			interrupts = <31>;
 			clocks = <&clkuart4>;
+			status = "disabled";
 		};
 
-		uart@d8380000 {
+		uart5: serial@d8380000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd8380000 0x1040>;
 			interrupts = <30>;
 			clocks = <&clkuart5>;
+			status = "disabled";
 		};
 
 		rtc@d8100000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/wm8505-ref.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8505-ref.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/wm8505-ref.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8505-ref.dts	2013-08-25 20:43:22.000000000 -0400
@@ -30,3 +30,7 @@
 		};
 	};
 };
+
+&uart0 {
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/wm8650.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8650.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/wm8650.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8650.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,21 @@
 / {
 	compatible = "wm,wm8650";
 
+	cpus {
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			device_type = "cpu";
+			compatible = "arm,arm926ej-s";
+		};
+	};
+
+ 	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -77,6 +92,55 @@
 					reg = <0x204>;
 				};
 
+				pllc: pllc {
+					#clock-cells = <0>;
+					compatible = "wm,wm8650-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x208>;
+				};
+
+				plld: plld {
+					#clock-cells = <0>;
+					compatible = "wm,wm8650-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x20c>;
+				};
+
+				plle: plle {
+					#clock-cells = <0>;
+					compatible = "wm,wm8650-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x210>;
+				};
+
+				clkarm: arm {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&plla>;
+					divisor-reg = <0x300>;
+				};
+
+				clkahb: ahb {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x304>;
+				};
+
+				clkapb: apb {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x320>;
+				};
+
+				clkddr: ddr {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&plld>;
+					divisor-reg = <0x310>;
+				};
+
 				clkuart0: uart0 {
  					#clock-cells = <0>;
  					compatible = "via,vt8500-device-clock";
@@ -93,14 +157,7 @@
 					enable-bit = <2>;
 				};
 
-				arm: arm {
-					#clock-cells = <0>;
-					compatible = "via,vt8500-device-clock";
-					clocks = <&plla>;
-					divisor-reg = <0x300>;
-				};
-
-				sdhc: sdhc {
+				clksdhc: sdhc {
 					#clock-cells = <0>;
 					compatible = "via,vt8500-device-clock";
 					clocks = <&pllb>;
@@ -140,18 +197,20 @@
 			reg = <0xd8050400 0x100>;
 		};
 
-		uart@d8200000 {
+		uart0: serial@d8200000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd8200000 0x1040>;
 			interrupts = <32>;
 			clocks = <&clkuart0>;
+			status = "disabled";
 		};
 
-		uart@d82b0000 {
+		uart1: serial@d82b0000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd82b0000 0x1040>;
 			interrupts = <33>;
 			clocks = <&clkuart1>;
+			status = "disabled";
 		};
 
 		rtc@d8100000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/wm8650-mid.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8650-mid.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/wm8650-mid.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8650-mid.dts	2013-08-25 20:43:22.000000000 -0400
@@ -32,3 +32,6 @@
 	};
 };
 
+&uart0 {
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/wm8750-apc8750.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8750-apc8750.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/wm8750-apc8750.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8750-apc8750.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,30 @@
+/*
+ * wm8750-apc8750.dts
+ *  - Device tree file for VIA APC8750
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/dts-v1/;
+/include/ "wm8750.dtsi"
+
+/ {
+	model = "VIA APC8750";
+};
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c>;
+
+	i2c: i2c {
+		wm,pins = <168 169 170 171>;
+		wm,function = <2>;	/* alt */
+		wm,pull = <2>;	/* pull-up */
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/wm8750.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8750.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/wm8750.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8750.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,347 @@
+/*
+ * wm8750.dtsi - Device tree file for Wondermedia WM8750 SoC
+ *
+ * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * Licensed under GPLv2 or later
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "wm,wm8750";
+
+	cpus {
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			device_type = "cpu";
+			compatible = "arm,arm1176ej-s";
+		};
+	};
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		serial5 = &uart5;
+		i2c0 = &i2c_0;
+		i2c1 = &i2c_1;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges;
+		interrupt-parent = <&intc0>;
+
+		intc0: interrupt-controller@d8140000 {
+			compatible = "via,vt8500-intc";
+			interrupt-controller;
+			reg = <0xd8140000 0x10000>;
+			#interrupt-cells = <1>;
+		};
+
+		/* Secondary IC cascaded to intc0 */
+		intc1: interrupt-controller@d8150000 {
+			compatible = "via,vt8500-intc";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			reg = <0xD8150000 0x10000>;
+			interrupts = <56 57 58 59 60 61 62 63>;
+		};
+
+		pinctrl: pinctrl@d8110000 {
+			compatible = "wm,wm8750-pinctrl";
+			reg = <0xd8110000 0x10000>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		pmc@d8130000 {
+			compatible = "via,vt8500-pmc";
+			reg = <0xd8130000 0x1000>;
+
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ref24: ref24M {
+					#clock-cells = <0>;
+					compatible = "fixed-clock";
+					clock-frequency = <24000000>;
+				};
+
+				ref25: ref25M {
+					#clock-cells = <0>;
+					compatible = "fixed-clock";
+					clock-frequency = <25000000>;
+				};
+
+				plla: plla {
+					#clock-cells = <0>;
+					compatible = "wm,wm8750-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x200>;
+				};
+
+				pllb: pllb {
+					#clock-cells = <0>;
+					compatible = "wm,wm8750-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x204>;
+				};
+
+				pllc: pllc {
+					#clock-cells = <0>;
+					compatible = "wm,wm8750-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x208>;
+				};
+
+				plld: plld {
+					#clock-cells = <0>;
+					compatible = "wm,wm8750-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x20C>;
+				};
+
+				plle: plle {
+					#clock-cells = <0>;
+					compatible = "wm,wm8750-pll-clock";
+					clocks = <&ref25>;
+					reg = <0x210>;
+				};
+
+				clkarm: arm {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&plla>;
+					divisor-reg = <0x300>;
+				};
+
+				clkahb: ahb {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x304>;
+				};
+
+				clkapb: apb {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x320>;
+				};
+
+				clkddr: ddr {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&plld>;
+					divisor-reg = <0x310>;
+				};
+
+				clkuart0: uart0 {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&ref24>;
+					enable-reg = <0x254>;
+					enable-bit = <24>;
+				};
+
+				clkuart1: uart1 {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&ref24>;
+					enable-reg = <0x254>;
+					enable-bit = <25>;
+				};
+
+                                clkuart2: uart2 {
+                                        #clock-cells = <0>;
+                                        compatible = "via,vt8500-device-clock";
+                                        clocks = <&ref24>;
+                                        enable-reg = <0x254>;
+                                        enable-bit = <26>;
+                                };
+
+                                clkuart3: uart3 {
+                                        #clock-cells = <0>;
+                                        compatible = "via,vt8500-device-clock";
+                                        clocks = <&ref24>;
+                                        enable-reg = <0x254>;
+                                        enable-bit = <27>;
+                                };
+
+                                clkuart4: uart4 {
+                                        #clock-cells = <0>;
+                                        compatible = "via,vt8500-device-clock";
+                                        clocks = <&ref24>;
+                                        enable-reg = <0x254>;
+                                        enable-bit = <28>;
+                                };
+
+                                clkuart5: uart5 {
+                                        #clock-cells = <0>;
+                                        compatible = "via,vt8500-device-clock";
+                                        clocks = <&ref24>;
+                                        enable-reg = <0x254>;
+                                        enable-bit = <29>;
+                                };
+
+				clkpwm: pwm {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x350>;
+					enable-reg = <0x250>;
+					enable-bit = <17>;
+				};
+
+				clksdhc: sdhc {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x330>;
+					divisor-mask = <0x3f>;
+					enable-reg = <0x250>;
+					enable-bit = <0>;
+				};
+
+				clki2c0: i2c0clk {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x3A0>;
+					enable-reg = <0x250>;
+					enable-bit = <8>;
+				};
+
+				clki2c1: i2c1clk {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x3A4>;
+					enable-reg = <0x250>;
+					enable-bit = <9>;
+				};
+			};
+		};
+
+		pwm: pwm@d8220000 {
+			#pwm-cells = <3>;
+			compatible = "via,vt8500-pwm";
+			reg = <0xd8220000 0x100>;
+			clocks = <&clkpwm>;
+		};
+
+		timer@d8130100 {
+			compatible = "via,vt8500-timer";
+			reg = <0xd8130100 0x28>;
+			interrupts = <36>;
+		};
+
+		ehci@d8007900 {
+			compatible = "via,vt8500-ehci";
+			reg = <0xd8007900 0x200>;
+			interrupts = <26>;
+		};
+
+		uhci@d8007b00 {
+			compatible = "platform-uhci";
+			reg = <0xd8007b00 0x200>;
+			interrupts = <26>;
+		};
+
+		uhci@d8008d00 {
+			compatible = "platform-uhci";
+			reg = <0xd8008d00 0x200>;
+			interrupts = <26>;
+		};
+
+		uart0: serial@d8200000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd8200000 0x1040>;
+			interrupts = <32>;
+			clocks = <&clkuart0>;
+			status = "disabled";
+		};
+
+		uart1: serial@d82b0000 {
+			compatible = "via,vt8500-uart";
+			reg = <0xd82b0000 0x1040>;
+			interrupts = <33>;
+			clocks = <&clkuart1>;
+			status = "disabled";
+		};
+
+                uart2: serial@d8210000 {
+                        compatible = "via,vt8500-uart";
+                        reg = <0xd8210000 0x1040>;
+                        interrupts = <47>;
+                        clocks = <&clkuart2>;
+			status = "disabled";
+                };
+
+                uart3: serial@d82c0000 {
+                        compatible = "via,vt8500-uart";
+                        reg = <0xd82c0000 0x1040>;
+                        interrupts = <50>;
+                        clocks = <&clkuart3>;
+			status = "disabled";
+                };
+
+                uart4: serial@d8370000 {
+                        compatible = "via,vt8500-uart";
+                        reg = <0xd8370000 0x1040>;
+                        interrupts = <30>;
+                        clocks = <&clkuart4>;
+			status = "disabled";
+                };
+
+                uart5: serial@d8380000 {
+                        compatible = "via,vt8500-uart";
+                        reg = <0xd8380000 0x1040>;
+                        interrupts = <43>;
+                        clocks = <&clkuart5>;
+			status = "disabled";
+                };
+
+		rtc@d8100000 {
+			compatible = "via,vt8500-rtc";
+			reg = <0xd8100000 0x10000>;
+			interrupts = <48>;
+		};
+
+		sdhc@d800a000 {
+			compatible = "wm,wm8505-sdhc";
+			reg = <0xd800a000 0x1000>;
+			interrupts = <20 21>;
+			clocks = <&clksdhc>;
+			bus-width = <4>;
+			sdon-inverted;
+		};
+
+		i2c_0: i2c@d8280000 {
+			compatible = "wm,wm8505-i2c";
+			reg = <0xd8280000 0x1000>;
+			interrupts = <19>;
+			clocks = <&clki2c0>;
+			clock-frequency = <400000>;
+		};
+
+		i2c_1: i2c@d8320000 {
+			compatible = "wm,wm8505-i2c";
+			reg = <0xd8320000 0x1000>;
+			interrupts = <18>;
+			clocks = <&clki2c1>;
+			clock-frequency = <400000>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/wm8850.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8850.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/wm8850.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8850.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,17 @@
 / {
 	compatible = "wm,wm8850";
 
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x0>;
+		};
+	};
+
 	aliases {
 		serial0 = &uart0;
 		serial1 = &uart1;
@@ -72,18 +83,81 @@
 
 				plla: plla {
 					#clock-cells = <0>;
-					compatible = "wm,wm8750-pll-clock";
-					clocks = <&ref25>;
+					compatible = "wm,wm8850-pll-clock";
+					clocks = <&ref24>;
 					reg = <0x200>;
 				};
 
 				pllb: pllb {
 					#clock-cells = <0>;
-					compatible = "wm,wm8750-pll-clock";
-					clocks = <&ref25>;
+					compatible = "wm,wm8850-pll-clock";
+					clocks = <&ref24>;
 					reg = <0x204>;
 				};
 
+				pllc: pllc {
+					#clock-cells = <0>;
+					compatible = "wm,wm8850-pll-clock";
+					clocks = <&ref24>;
+					reg = <0x208>;
+				};
+
+				plld: plld {
+					#clock-cells = <0>;
+					compatible = "wm,wm8850-pll-clock";
+					clocks = <&ref24>;
+					reg = <0x20c>;
+				};
+
+				plle: plle {
+					#clock-cells = <0>;
+					compatible = "wm,wm8850-pll-clock";
+					clocks = <&ref24>;
+					reg = <0x210>;
+				};
+
+				pllf: pllf {
+					#clock-cells = <0>;
+					compatible = "wm,wm8850-pll-clock";
+					clocks = <&ref24>;
+					reg = <0x214>;
+				};
+
+				pllg: pllg {
+					#clock-cells = <0>;
+					compatible = "wm,wm8850-pll-clock";
+					clocks = <&ref24>;
+					reg = <0x218>;
+				};
+
+				clkarm: arm {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&plla>;
+					divisor-reg = <0x300>;
+				};
+
+				clkahb: ahb {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x304>;
+				};
+
+				clkapb: apb {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&pllb>;
+					divisor-reg = <0x320>;
+				};
+
+				clkddr: ddr {
+					#clock-cells = <0>;
+					compatible = "via,vt8500-device-clock";
+					clocks = <&plld>;
+					divisor-reg = <0x310>;
+				};
+
 				clkuart0: uart0 {
 					#clock-cells = <0>;
 					compatible = "via,vt8500-device-clock";
@@ -178,32 +252,36 @@
 			interrupts = <26>;
 		};
 
-		uart0: uart@d8200000 {
+		uart0: serial@d8200000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd8200000 0x1040>;
 			interrupts = <32>;
 			clocks = <&clkuart0>;
+			status = "disabled";
 		};
 
-		uart1: uart@d82b0000 {
+		uart1: serial@d82b0000 {
 			compatible = "via,vt8500-uart";
 			reg = <0xd82b0000 0x1040>;
 			interrupts = <33>;
 			clocks = <&clkuart1>;
+			status = "disabled";
 		};
 
-                uart2: uart@d8210000 {
+                uart2: serial@d8210000 {
                         compatible = "via,vt8500-uart";
                         reg = <0xd8210000 0x1040>;
                         interrupts = <47>;
                         clocks = <&clkuart2>;
+			status = "disabled";
                 };
 
-                uart3: uart@d82c0000 {
+                uart3: serial@d82c0000 {
                         compatible = "via,vt8500-uart";
                         reg = <0xd82c0000 0x1040>;
                         interrupts = <50>;
                         clocks = <&clkuart3>;
+			status = "disabled";
                 };
 
 		rtc@d8100000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/wm8850-w70v2.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8850-w70v2.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/wm8850-w70v2.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/wm8850-w70v2.dts	2013-08-25 20:43:22.000000000 -0400
@@ -41,3 +41,7 @@
 		};
 	};
 };
+
+&uart0 {
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/zynq-7000.dtsi linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/zynq-7000.dtsi
--- linux-libre-3.10-gnu/arch/arm/boot/dts/zynq-7000.dtsi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/zynq-7000.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -49,16 +49,20 @@
 
 		uart0: uart@e0000000 {
 			compatible = "xlnx,xuartps";
+			status = "disabled";
+			clocks = <&clkc 23>, <&clkc 40>;
+			clock-names = "ref_clk", "aper_clk";
 			reg = <0xE0000000 0x1000>;
 			interrupts = <0 27 4>;
-			clocks = <&uart_clk 0>;
 		};
 
 		uart1: uart@e0001000 {
 			compatible = "xlnx,xuartps";
+			status = "disabled";
+			clocks = <&clkc 24>, <&clkc 41>;
+			clock-names = "ref_clk", "aper_clk";
 			reg = <0xE0001000 0x1000>;
 			interrupts = <0 50 4>;
-			clocks = <&uart_clk 1>;
 		};
 
 		slcr: slcr@f8000000 {
@@ -69,50 +73,21 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 
-				ps_clk: ps_clk {
-					#clock-cells = <0>;
-					compatible = "fixed-clock";
-					/* clock-frequency set in board-specific file */
-					clock-output-names = "ps_clk";
-				};
-				armpll: armpll {
-					#clock-cells = <0>;
-					compatible = "xlnx,zynq-pll";
-					clocks = <&ps_clk>;
-					reg = <0x100 0x110>;
-					clock-output-names = "armpll";
-				};
-				ddrpll: ddrpll {
-					#clock-cells = <0>;
-					compatible = "xlnx,zynq-pll";
-					clocks = <&ps_clk>;
-					reg = <0x104 0x114>;
-					clock-output-names = "ddrpll";
-				};
-				iopll: iopll {
-					#clock-cells = <0>;
-					compatible = "xlnx,zynq-pll";
-					clocks = <&ps_clk>;
-					reg = <0x108 0x118>;
-					clock-output-names = "iopll";
-				};
-				uart_clk: uart_clk {
-					#clock-cells = <1>;
-					compatible = "xlnx,zynq-periph-clock";
-					clocks = <&iopll &armpll &ddrpll>;
-					reg = <0x154>;
-					clock-output-names = "uart0_ref_clk",
-							     "uart1_ref_clk";
-				};
-				cpu_clk: cpu_clk {
+				clkc: clkc {
 					#clock-cells = <1>;
-					compatible = "xlnx,zynq-cpu-clock";
-					clocks = <&iopll &armpll &ddrpll>;
-					reg = <0x120 0x1C4>;
-					clock-output-names = "cpu_6x4x",
-							     "cpu_3x2x",
-							     "cpu_2x",
-							     "cpu_1x";
+					compatible = "xlnx,ps7-clkc";
+					ps-clk-frequency = <33333333>;
+					clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
+							"cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
+							"dci", "lqspi", "smc", "pcap", "gem0", "gem1",
+							"fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
+							"sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
+							"dma", "usb0_aper", "usb1_aper", "gem0_aper",
+							"gem1_aper", "sdio0_aper", "sdio1_aper",
+							"spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
+							"i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
+							"gpio_aper", "lqspi_aper", "smc_aper", "swdt",
+							"dbg_trc", "dbg_apb";
 				};
 			};
 		};
@@ -121,9 +96,8 @@
 			interrupt-parent = <&intc>;
 			interrupts = < 0 10 4 0 11 4 0 12 4 >;
 			compatible = "cdns,ttc";
+			clocks = <&clkc 6>;
 			reg = <0xF8001000 0x1000>;
-			clocks = <&cpu_clk 3>;
-			clock-names = "cpu_1x";
 			clock-ranges;
 		};
 
@@ -131,9 +105,8 @@
 			interrupt-parent = <&intc>;
 			interrupts = < 0 37 4 0 38 4 0 39 4 >;
 			compatible = "cdns,ttc";
+			clocks = <&clkc 6>;
 			reg = <0xF8002000 0x1000>;
-			clocks = <&cpu_clk 3>;
-			clock-names = "cpu_1x";
 			clock-ranges;
 		};
 		scutimer: scutimer@f8f00600 {
@@ -141,7 +114,7 @@
 			interrupts = < 1 13 0x301 >;
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = < 0xf8f00600 0x20 >;
-			clocks = <&cpu_clk 1>;
+			clocks = <&clkc 4>;
 		} ;
 	};
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/zynq-zc702.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/zynq-zc702.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/zynq-zc702.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/zynq-zc702.dts	2013-08-25 20:43:22.000000000 -0400
@@ -24,11 +24,11 @@
 	};
 
 	chosen {
-		bootargs = "console=ttyPS1,115200 earlyprintk";
+		bootargs = "console=ttyPS0,115200 earlyprintk";
 	};
 
 };
 
-&ps_clk {
-	clock-frequency = <33333330>;
+&uart1 {
+	status = "okay";
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/zynq-zc706.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/zynq-zc706.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/zynq-zc706.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/zynq-zc706.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2011 Xilinx
+ *  Copyright (C) 2012 National Instruments Corp.
+ *  Copyright (C) 2013 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+	model = "Zynq ZC706 Development Board";
+	compatible = "xlnx,zynq-zc706", "xlnx,zynq-7000";
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x40000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyPS0,115200 earlyprintk";
+	};
+
+};
+
+&uart1 {
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/boot/dts/zynq-zed.dts linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/zynq-zed.dts
--- linux-libre-3.10-gnu/arch/arm/boot/dts/zynq-zed.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/boot/dts/zynq-zed.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2011 Xilinx
+ *  Copyright (C) 2012 National Instruments Corp.
+ *  Copyright (C) 2013 Xilinx
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+	model = "Zynq Zed Development Board";
+	compatible = "xlnx,zynq-7000";
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x20000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyPS0,115200 earlyprintk";
+	};
+
+};
+
+&uart1 {
+	status = "okay";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/common/edma.c linux-libre-3.11-rc7-gnu/arch/arm/common/edma.c
--- linux-libre-3.10-gnu/arch/arm/common/edma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/common/edma.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1766 @@
+/*
+ * EDMA3 support for DaVinci
+ *
+ * Copyright (C) 2006-2009 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/edma.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/platform_data/edma.h>
+
+/* Offsets matching "struct edmacc_param" */
+#define PARM_OPT		0x00
+#define PARM_SRC		0x04
+#define PARM_A_B_CNT		0x08
+#define PARM_DST		0x0c
+#define PARM_SRC_DST_BIDX	0x10
+#define PARM_LINK_BCNTRLD	0x14
+#define PARM_SRC_DST_CIDX	0x18
+#define PARM_CCNT		0x1c
+
+#define PARM_SIZE		0x20
+
+/* Offsets for EDMA CC global channel registers and their shadows */
+#define SH_ER		0x00	/* 64 bits */
+#define SH_ECR		0x08	/* 64 bits */
+#define SH_ESR		0x10	/* 64 bits */
+#define SH_CER		0x18	/* 64 bits */
+#define SH_EER		0x20	/* 64 bits */
+#define SH_EECR		0x28	/* 64 bits */
+#define SH_EESR		0x30	/* 64 bits */
+#define SH_SER		0x38	/* 64 bits */
+#define SH_SECR		0x40	/* 64 bits */
+#define SH_IER		0x50	/* 64 bits */
+#define SH_IECR		0x58	/* 64 bits */
+#define SH_IESR		0x60	/* 64 bits */
+#define SH_IPR		0x68	/* 64 bits */
+#define SH_ICR		0x70	/* 64 bits */
+#define SH_IEVAL	0x78
+#define SH_QER		0x80
+#define SH_QEER		0x84
+#define SH_QEECR	0x88
+#define SH_QEESR	0x8c
+#define SH_QSER		0x90
+#define SH_QSECR	0x94
+#define SH_SIZE		0x200
+
+/* Offsets for EDMA CC global registers */
+#define EDMA_REV	0x0000
+#define EDMA_CCCFG	0x0004
+#define EDMA_QCHMAP	0x0200	/* 8 registers */
+#define EDMA_DMAQNUM	0x0240	/* 8 registers (4 on OMAP-L1xx) */
+#define EDMA_QDMAQNUM	0x0260
+#define EDMA_QUETCMAP	0x0280
+#define EDMA_QUEPRI	0x0284
+#define EDMA_EMR	0x0300	/* 64 bits */
+#define EDMA_EMCR	0x0308	/* 64 bits */
+#define EDMA_QEMR	0x0310
+#define EDMA_QEMCR	0x0314
+#define EDMA_CCERR	0x0318
+#define EDMA_CCERRCLR	0x031c
+#define EDMA_EEVAL	0x0320
+#define EDMA_DRAE	0x0340	/* 4 x 64 bits*/
+#define EDMA_QRAE	0x0380	/* 4 registers */
+#define EDMA_QUEEVTENTRY	0x0400	/* 2 x 16 registers */
+#define EDMA_QSTAT	0x0600	/* 2 registers */
+#define EDMA_QWMTHRA	0x0620
+#define EDMA_QWMTHRB	0x0624
+#define EDMA_CCSTAT	0x0640
+
+#define EDMA_M		0x1000	/* global channel registers */
+#define EDMA_ECR	0x1008
+#define EDMA_ECRH	0x100C
+#define EDMA_SHADOW0	0x2000	/* 4 regions shadowing global channels */
+#define EDMA_PARM	0x4000	/* 128 param entries */
+
+#define PARM_OFFSET(param_no)	(EDMA_PARM + ((param_no) << 5))
+
+#define EDMA_DCHMAP	0x0100  /* 64 registers */
+#define CHMAP_EXIST	BIT(24)
+
+#define EDMA_MAX_DMACH           64
+#define EDMA_MAX_PARAMENTRY     512
+
+/*****************************************************************************/
+
+static void __iomem *edmacc_regs_base[EDMA_MAX_CC];
+
+static inline unsigned int edma_read(unsigned ctlr, int offset)
+{
+	return (unsigned int)__raw_readl(edmacc_regs_base[ctlr] + offset);
+}
+
+static inline void edma_write(unsigned ctlr, int offset, int val)
+{
+	__raw_writel(val, edmacc_regs_base[ctlr] + offset);
+}
+static inline void edma_modify(unsigned ctlr, int offset, unsigned and,
+		unsigned or)
+{
+	unsigned val = edma_read(ctlr, offset);
+	val &= and;
+	val |= or;
+	edma_write(ctlr, offset, val);
+}
+static inline void edma_and(unsigned ctlr, int offset, unsigned and)
+{
+	unsigned val = edma_read(ctlr, offset);
+	val &= and;
+	edma_write(ctlr, offset, val);
+}
+static inline void edma_or(unsigned ctlr, int offset, unsigned or)
+{
+	unsigned val = edma_read(ctlr, offset);
+	val |= or;
+	edma_write(ctlr, offset, val);
+}
+static inline unsigned int edma_read_array(unsigned ctlr, int offset, int i)
+{
+	return edma_read(ctlr, offset + (i << 2));
+}
+static inline void edma_write_array(unsigned ctlr, int offset, int i,
+		unsigned val)
+{
+	edma_write(ctlr, offset + (i << 2), val);
+}
+static inline void edma_modify_array(unsigned ctlr, int offset, int i,
+		unsigned and, unsigned or)
+{
+	edma_modify(ctlr, offset + (i << 2), and, or);
+}
+static inline void edma_or_array(unsigned ctlr, int offset, int i, unsigned or)
+{
+	edma_or(ctlr, offset + (i << 2), or);
+}
+static inline void edma_or_array2(unsigned ctlr, int offset, int i, int j,
+		unsigned or)
+{
+	edma_or(ctlr, offset + ((i*2 + j) << 2), or);
+}
+static inline void edma_write_array2(unsigned ctlr, int offset, int i, int j,
+		unsigned val)
+{
+	edma_write(ctlr, offset + ((i*2 + j) << 2), val);
+}
+static inline unsigned int edma_shadow0_read(unsigned ctlr, int offset)
+{
+	return edma_read(ctlr, EDMA_SHADOW0 + offset);
+}
+static inline unsigned int edma_shadow0_read_array(unsigned ctlr, int offset,
+		int i)
+{
+	return edma_read(ctlr, EDMA_SHADOW0 + offset + (i << 2));
+}
+static inline void edma_shadow0_write(unsigned ctlr, int offset, unsigned val)
+{
+	edma_write(ctlr, EDMA_SHADOW0 + offset, val);
+}
+static inline void edma_shadow0_write_array(unsigned ctlr, int offset, int i,
+		unsigned val)
+{
+	edma_write(ctlr, EDMA_SHADOW0 + offset + (i << 2), val);
+}
+static inline unsigned int edma_parm_read(unsigned ctlr, int offset,
+		int param_no)
+{
+	return edma_read(ctlr, EDMA_PARM + offset + (param_no << 5));
+}
+static inline void edma_parm_write(unsigned ctlr, int offset, int param_no,
+		unsigned val)
+{
+	edma_write(ctlr, EDMA_PARM + offset + (param_no << 5), val);
+}
+static inline void edma_parm_modify(unsigned ctlr, int offset, int param_no,
+		unsigned and, unsigned or)
+{
+	edma_modify(ctlr, EDMA_PARM + offset + (param_no << 5), and, or);
+}
+static inline void edma_parm_and(unsigned ctlr, int offset, int param_no,
+		unsigned and)
+{
+	edma_and(ctlr, EDMA_PARM + offset + (param_no << 5), and);
+}
+static inline void edma_parm_or(unsigned ctlr, int offset, int param_no,
+		unsigned or)
+{
+	edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or);
+}
+
+static inline void set_bits(int offset, int len, unsigned long *p)
+{
+	for (; len > 0; len--)
+		set_bit(offset + (len - 1), p);
+}
+
+static inline void clear_bits(int offset, int len, unsigned long *p)
+{
+	for (; len > 0; len--)
+		clear_bit(offset + (len - 1), p);
+}
+
+/*****************************************************************************/
+
+/* actual number of DMA channels and slots on this silicon */
+struct edma {
+	/* how many dma resources of each type */
+	unsigned	num_channels;
+	unsigned	num_region;
+	unsigned	num_slots;
+	unsigned	num_tc;
+	unsigned	num_cc;
+	enum dma_event_q 	default_queue;
+
+	/* list of channels with no even trigger; terminated by "-1" */
+	const s8	*noevent;
+
+	/* The edma_inuse bit for each PaRAM slot is clear unless the
+	 * channel is in use ... by ARM or DSP, for QDMA, or whatever.
+	 */
+	DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
+
+	/* The edma_unused bit for each channel is clear unless
+	 * it is not being used on this platform. It uses a bit
+	 * of SOC-specific initialization code.
+	 */
+	DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH);
+
+	unsigned	irq_res_start;
+	unsigned	irq_res_end;
+
+	struct dma_interrupt_data {
+		void (*callback)(unsigned channel, unsigned short ch_status,
+				void *data);
+		void *data;
+	} intr_data[EDMA_MAX_DMACH];
+};
+
+static struct edma *edma_cc[EDMA_MAX_CC];
+static int arch_num_cc;
+
+/* dummy param set used to (re)initialize parameter RAM slots */
+static const struct edmacc_param dummy_paramset = {
+	.link_bcntrld = 0xffff,
+	.ccnt = 1,
+};
+
+/*****************************************************************************/
+
+static void map_dmach_queue(unsigned ctlr, unsigned ch_no,
+		enum dma_event_q queue_no)
+{
+	int bit = (ch_no & 0x7) * 4;
+
+	/* default to low priority queue */
+	if (queue_no == EVENTQ_DEFAULT)
+		queue_no = edma_cc[ctlr]->default_queue;
+
+	queue_no &= 7;
+	edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3),
+			~(0x7 << bit), queue_no << bit);
+}
+
+static void __init map_queue_tc(unsigned ctlr, int queue_no, int tc_no)
+{
+	int bit = queue_no * 4;
+	edma_modify(ctlr, EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit));
+}
+
+static void __init assign_priority_to_queue(unsigned ctlr, int queue_no,
+		int priority)
+{
+	int bit = queue_no * 4;
+	edma_modify(ctlr, EDMA_QUEPRI, ~(0x7 << bit),
+			((priority & 0x7) << bit));
+}
+
+/**
+ * map_dmach_param - Maps channel number to param entry number
+ *
+ * This maps the dma channel number to param entry numberter. In
+ * other words using the DMA channel mapping registers a param entry
+ * can be mapped to any channel
+ *
+ * Callers are responsible for ensuring the channel mapping logic is
+ * included in that particular EDMA variant (Eg : dm646x)
+ *
+ */
+static void __init map_dmach_param(unsigned ctlr)
+{
+	int i;
+	for (i = 0; i < EDMA_MAX_DMACH; i++)
+		edma_write_array(ctlr, EDMA_DCHMAP , i , (i << 5));
+}
+
+static inline void
+setup_dma_interrupt(unsigned lch,
+	void (*callback)(unsigned channel, u16 ch_status, void *data),
+	void *data)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(lch);
+	lch = EDMA_CHAN_SLOT(lch);
+
+	if (!callback)
+		edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5,
+				BIT(lch & 0x1f));
+
+	edma_cc[ctlr]->intr_data[lch].callback = callback;
+	edma_cc[ctlr]->intr_data[lch].data = data;
+
+	if (callback) {
+		edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5,
+				BIT(lch & 0x1f));
+		edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5,
+				BIT(lch & 0x1f));
+	}
+}
+
+static int irq2ctlr(int irq)
+{
+	if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end)
+		return 0;
+	else if (irq >= edma_cc[1]->irq_res_start &&
+		irq <= edma_cc[1]->irq_res_end)
+		return 1;
+
+	return -1;
+}
+
+/******************************************************************************
+ *
+ * DMA interrupt handler
+ *
+ *****************************************************************************/
+static irqreturn_t dma_irq_handler(int irq, void *data)
+{
+	int ctlr;
+	u32 sh_ier;
+	u32 sh_ipr;
+	u32 bank;
+
+	ctlr = irq2ctlr(irq);
+	if (ctlr < 0)
+		return IRQ_NONE;
+
+	dev_dbg(data, "dma_irq_handler\n");
+
+	sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0);
+	if (!sh_ipr) {
+		sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 1);
+		if (!sh_ipr)
+			return IRQ_NONE;
+		sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 1);
+		bank = 1;
+	} else {
+		sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 0);
+		bank = 0;
+	}
+
+	do {
+		u32 slot;
+		u32 channel;
+
+		dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr);
+
+		slot = __ffs(sh_ipr);
+		sh_ipr &= ~(BIT(slot));
+
+		if (sh_ier & BIT(slot)) {
+			channel = (bank << 5) | slot;
+			/* Clear the corresponding IPR bits */
+			edma_shadow0_write_array(ctlr, SH_ICR, bank,
+					BIT(slot));
+			if (edma_cc[ctlr]->intr_data[channel].callback)
+				edma_cc[ctlr]->intr_data[channel].callback(
+					channel, DMA_COMPLETE,
+					edma_cc[ctlr]->intr_data[channel].data);
+		}
+	} while (sh_ipr);
+
+	edma_shadow0_write(ctlr, SH_IEVAL, 1);
+	return IRQ_HANDLED;
+}
+
+/******************************************************************************
+ *
+ * DMA error interrupt handler
+ *
+ *****************************************************************************/
+static irqreturn_t dma_ccerr_handler(int irq, void *data)
+{
+	int i;
+	int ctlr;
+	unsigned int cnt = 0;
+
+	ctlr = irq2ctlr(irq);
+	if (ctlr < 0)
+		return IRQ_NONE;
+
+	dev_dbg(data, "dma_ccerr_handler\n");
+
+	if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
+	    (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
+	    (edma_read(ctlr, EDMA_QEMR) == 0) &&
+	    (edma_read(ctlr, EDMA_CCERR) == 0))
+		return IRQ_NONE;
+
+	while (1) {
+		int j = -1;
+		if (edma_read_array(ctlr, EDMA_EMR, 0))
+			j = 0;
+		else if (edma_read_array(ctlr, EDMA_EMR, 1))
+			j = 1;
+		if (j >= 0) {
+			dev_dbg(data, "EMR%d %08x\n", j,
+					edma_read_array(ctlr, EDMA_EMR, j));
+			for (i = 0; i < 32; i++) {
+				int k = (j << 5) + i;
+				if (edma_read_array(ctlr, EDMA_EMR, j) &
+							BIT(i)) {
+					/* Clear the corresponding EMR bits */
+					edma_write_array(ctlr, EDMA_EMCR, j,
+							BIT(i));
+					/* Clear any SER */
+					edma_shadow0_write_array(ctlr, SH_SECR,
+								j, BIT(i));
+					if (edma_cc[ctlr]->intr_data[k].
+								callback) {
+						edma_cc[ctlr]->intr_data[k].
+						callback(k,
+						DMA_CC_ERROR,
+						edma_cc[ctlr]->intr_data
+						[k].data);
+					}
+				}
+			}
+		} else if (edma_read(ctlr, EDMA_QEMR)) {
+			dev_dbg(data, "QEMR %02x\n",
+				edma_read(ctlr, EDMA_QEMR));
+			for (i = 0; i < 8; i++) {
+				if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) {
+					/* Clear the corresponding IPR bits */
+					edma_write(ctlr, EDMA_QEMCR, BIT(i));
+					edma_shadow0_write(ctlr, SH_QSECR,
+								BIT(i));
+
+					/* NOTE:  not reported!! */
+				}
+			}
+		} else if (edma_read(ctlr, EDMA_CCERR)) {
+			dev_dbg(data, "CCERR %08x\n",
+				edma_read(ctlr, EDMA_CCERR));
+			/* FIXME:  CCERR.BIT(16) ignored!  much better
+			 * to just write CCERRCLR with CCERR value...
+			 */
+			for (i = 0; i < 8; i++) {
+				if (edma_read(ctlr, EDMA_CCERR) & BIT(i)) {
+					/* Clear the corresponding IPR bits */
+					edma_write(ctlr, EDMA_CCERRCLR, BIT(i));
+
+					/* NOTE:  not reported!! */
+				}
+			}
+		}
+		if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
+		    (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
+		    (edma_read(ctlr, EDMA_QEMR) == 0) &&
+		    (edma_read(ctlr, EDMA_CCERR) == 0))
+			break;
+		cnt++;
+		if (cnt > 10)
+			break;
+	}
+	edma_write(ctlr, EDMA_EEVAL, 1);
+	return IRQ_HANDLED;
+}
+
+static int reserve_contiguous_slots(int ctlr, unsigned int id,
+				     unsigned int num_slots,
+				     unsigned int start_slot)
+{
+	int i, j;
+	unsigned int count = num_slots;
+	int stop_slot = start_slot;
+	DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY);
+
+	for (i = start_slot; i < edma_cc[ctlr]->num_slots; ++i) {
+		j = EDMA_CHAN_SLOT(i);
+		if (!test_and_set_bit(j, edma_cc[ctlr]->edma_inuse)) {
+			/* Record our current beginning slot */
+			if (count == num_slots)
+				stop_slot = i;
+
+			count--;
+			set_bit(j, tmp_inuse);
+
+			if (count == 0)
+				break;
+		} else {
+			clear_bit(j, tmp_inuse);
+
+			if (id == EDMA_CONT_PARAMS_FIXED_EXACT) {
+				stop_slot = i;
+				break;
+			} else {
+				count = num_slots;
+			}
+		}
+	}
+
+	/*
+	 * We have to clear any bits that we set
+	 * if we run out parameter RAM slots, i.e we do find a set
+	 * of contiguous parameter RAM slots but do not find the exact number
+	 * requested as we may reach the total number of parameter RAM slots
+	 */
+	if (i == edma_cc[ctlr]->num_slots)
+		stop_slot = i;
+
+	j = start_slot;
+	for_each_set_bit_from(j, tmp_inuse, stop_slot)
+		clear_bit(j, edma_cc[ctlr]->edma_inuse);
+
+	if (count)
+		return -EBUSY;
+
+	for (j = i - num_slots + 1; j <= i; ++j)
+		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j),
+			&dummy_paramset, PARM_SIZE);
+
+	return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
+}
+
+static int prepare_unused_channel_list(struct device *dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	int i, ctlr;
+
+	for (i = 0; i < pdev->num_resources; i++) {
+		if ((pdev->resource[i].flags & IORESOURCE_DMA) &&
+				(int)pdev->resource[i].start >= 0) {
+			ctlr = EDMA_CTLR(pdev->resource[i].start);
+			clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
+					edma_cc[ctlr]->edma_unused);
+		}
+	}
+
+	return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+static bool unused_chan_list_done;
+
+/* Resource alloc/free:  dma channels, parameter RAM slots */
+
+/**
+ * edma_alloc_channel - allocate DMA channel and paired parameter RAM
+ * @channel: specific channel to allocate; negative for "any unmapped channel"
+ * @callback: optional; to be issued on DMA completion or errors
+ * @data: passed to callback
+ * @eventq_no: an EVENTQ_* constant, used to choose which Transfer
+ *	Controller (TC) executes requests using this channel.  Use
+ *	EVENTQ_DEFAULT unless you really need a high priority queue.
+ *
+ * This allocates a DMA channel and its associated parameter RAM slot.
+ * The parameter RAM is initialized to hold a dummy transfer.
+ *
+ * Normal use is to pass a specific channel number as @channel, to make
+ * use of hardware events mapped to that channel.  When the channel will
+ * be used only for software triggering or event chaining, channels not
+ * mapped to hardware events (or mapped to unused events) are preferable.
+ *
+ * DMA transfers start from a channel using edma_start(), or by
+ * chaining.  When the transfer described in that channel's parameter RAM
+ * slot completes, that slot's data may be reloaded through a link.
+ *
+ * DMA errors are only reported to the @callback associated with the
+ * channel driving that transfer, but transfer completion callbacks can
+ * be sent to another channel under control of the TCC field in
+ * the option word of the transfer's parameter RAM set.  Drivers must not
+ * use DMA transfer completion callbacks for channels they did not allocate.
+ * (The same applies to TCC codes used in transfer chaining.)
+ *
+ * Returns the number of the channel, else negative errno.
+ */
+int edma_alloc_channel(int channel,
+		void (*callback)(unsigned channel, u16 ch_status, void *data),
+		void *data,
+		enum dma_event_q eventq_no)
+{
+	unsigned i, done = 0, ctlr = 0;
+	int ret = 0;
+
+	if (!unused_chan_list_done) {
+		/*
+		 * Scan all the platform devices to find out the EDMA channels
+		 * used and clear them in the unused list, making the rest
+		 * available for ARM usage.
+		 */
+		ret = bus_for_each_dev(&platform_bus_type, NULL, NULL,
+				prepare_unused_channel_list);
+		if (ret < 0)
+			return ret;
+
+		unused_chan_list_done = true;
+	}
+
+	if (channel >= 0) {
+		ctlr = EDMA_CTLR(channel);
+		channel = EDMA_CHAN_SLOT(channel);
+	}
+
+	if (channel < 0) {
+		for (i = 0; i < arch_num_cc; i++) {
+			channel = 0;
+			for (;;) {
+				channel = find_next_bit(edma_cc[i]->edma_unused,
+						edma_cc[i]->num_channels,
+						channel);
+				if (channel == edma_cc[i]->num_channels)
+					break;
+				if (!test_and_set_bit(channel,
+						edma_cc[i]->edma_inuse)) {
+					done = 1;
+					ctlr = i;
+					break;
+				}
+				channel++;
+			}
+			if (done)
+				break;
+		}
+		if (!done)
+			return -ENOMEM;
+	} else if (channel >= edma_cc[ctlr]->num_channels) {
+		return -EINVAL;
+	} else if (test_and_set_bit(channel, edma_cc[ctlr]->edma_inuse)) {
+		return -EBUSY;
+	}
+
+	/* ensure access through shadow region 0 */
+	edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f));
+
+	/* ensure no events are pending */
+	edma_stop(EDMA_CTLR_CHAN(ctlr, channel));
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
+			&dummy_paramset, PARM_SIZE);
+
+	if (callback)
+		setup_dma_interrupt(EDMA_CTLR_CHAN(ctlr, channel),
+					callback, data);
+
+	map_dmach_queue(ctlr, channel, eventq_no);
+
+	return EDMA_CTLR_CHAN(ctlr, channel);
+}
+EXPORT_SYMBOL(edma_alloc_channel);
+
+
+/**
+ * edma_free_channel - deallocate DMA channel
+ * @channel: dma channel returned from edma_alloc_channel()
+ *
+ * This deallocates the DMA channel and associated parameter RAM slot
+ * allocated by edma_alloc_channel().
+ *
+ * Callers are responsible for ensuring the channel is inactive, and
+ * will not be reactivated by linking, chaining, or software calls to
+ * edma_start().
+ */
+void edma_free_channel(unsigned channel)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel >= edma_cc[ctlr]->num_channels)
+		return;
+
+	setup_dma_interrupt(channel, NULL, NULL);
+	/* REVISIT should probably take out of shadow region 0 */
+
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
+			&dummy_paramset, PARM_SIZE);
+	clear_bit(channel, edma_cc[ctlr]->edma_inuse);
+}
+EXPORT_SYMBOL(edma_free_channel);
+
+/**
+ * edma_alloc_slot - allocate DMA parameter RAM
+ * @slot: specific slot to allocate; negative for "any unused slot"
+ *
+ * This allocates a parameter RAM slot, initializing it to hold a
+ * dummy transfer.  Slots allocated using this routine have not been
+ * mapped to a hardware DMA channel, and will normally be used by
+ * linking to them from a slot associated with a DMA channel.
+ *
+ * Normal use is to pass EDMA_SLOT_ANY as the @slot, but specific
+ * slots may be allocated on behalf of DSP firmware.
+ *
+ * Returns the number of the slot, else negative errno.
+ */
+int edma_alloc_slot(unsigned ctlr, int slot)
+{
+	if (!edma_cc[ctlr])
+		return -EINVAL;
+
+	if (slot >= 0)
+		slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < 0) {
+		slot = edma_cc[ctlr]->num_channels;
+		for (;;) {
+			slot = find_next_zero_bit(edma_cc[ctlr]->edma_inuse,
+					edma_cc[ctlr]->num_slots, slot);
+			if (slot == edma_cc[ctlr]->num_slots)
+				return -ENOMEM;
+			if (!test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse))
+				break;
+		}
+	} else if (slot < edma_cc[ctlr]->num_channels ||
+			slot >= edma_cc[ctlr]->num_slots) {
+		return -EINVAL;
+	} else if (test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) {
+		return -EBUSY;
+	}
+
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+			&dummy_paramset, PARM_SIZE);
+
+	return EDMA_CTLR_CHAN(ctlr, slot);
+}
+EXPORT_SYMBOL(edma_alloc_slot);
+
+/**
+ * edma_free_slot - deallocate DMA parameter RAM
+ * @slot: parameter RAM slot returned from edma_alloc_slot()
+ *
+ * This deallocates the parameter RAM slot allocated by edma_alloc_slot().
+ * Callers are responsible for ensuring the slot is inactive, and will
+ * not be activated.
+ */
+void edma_free_slot(unsigned slot)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_cc[ctlr]->num_channels ||
+		slot >= edma_cc[ctlr]->num_slots)
+		return;
+
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+			&dummy_paramset, PARM_SIZE);
+	clear_bit(slot, edma_cc[ctlr]->edma_inuse);
+}
+EXPORT_SYMBOL(edma_free_slot);
+
+
+/**
+ * edma_alloc_cont_slots- alloc contiguous parameter RAM slots
+ * The API will return the starting point of a set of
+ * contiguous parameter RAM slots that have been requested
+ *
+ * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
+ * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
+ * @count: number of contiguous Paramter RAM slots
+ * @slot  - the start value of Parameter RAM slot that should be passed if id
+ * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
+ *
+ * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of
+ * contiguous Parameter RAM slots from parameter RAM 64 in the case of
+ * DaVinci SOCs and 32 in the case of DA8xx SOCs.
+ *
+ * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a
+ * set of contiguous parameter RAM slots from the "slot" that is passed as an
+ * argument to the API.
+ *
+ * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries
+ * starts looking for a set of contiguous parameter RAMs from the "slot"
+ * that is passed as an argument to the API. On failure the API will try to
+ * find a set of contiguous Parameter RAM slots from the remaining Parameter
+ * RAM slots
+ */
+int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
+{
+	/*
+	 * The start slot requested should be greater than
+	 * the number of channels and lesser than the total number
+	 * of slots
+	 */
+	if ((id != EDMA_CONT_PARAMS_ANY) &&
+		(slot < edma_cc[ctlr]->num_channels ||
+		slot >= edma_cc[ctlr]->num_slots))
+		return -EINVAL;
+
+	/*
+	 * The number of parameter RAM slots requested cannot be less than 1
+	 * and cannot be more than the number of slots minus the number of
+	 * channels
+	 */
+	if (count < 1 || count >
+		(edma_cc[ctlr]->num_slots - edma_cc[ctlr]->num_channels))
+		return -EINVAL;
+
+	switch (id) {
+	case EDMA_CONT_PARAMS_ANY:
+		return reserve_contiguous_slots(ctlr, id, count,
+						 edma_cc[ctlr]->num_channels);
+	case EDMA_CONT_PARAMS_FIXED_EXACT:
+	case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
+		return reserve_contiguous_slots(ctlr, id, count, slot);
+	default:
+		return -EINVAL;
+	}
+
+}
+EXPORT_SYMBOL(edma_alloc_cont_slots);
+
+/**
+ * edma_free_cont_slots - deallocate DMA parameter RAM slots
+ * @slot: first parameter RAM of a set of parameter RAM slots to be freed
+ * @count: the number of contiguous parameter RAM slots to be freed
+ *
+ * This deallocates the parameter RAM slots allocated by
+ * edma_alloc_cont_slots.
+ * Callers/applications need to keep track of sets of contiguous
+ * parameter RAM slots that have been allocated using the edma_alloc_cont_slots
+ * API.
+ * Callers are responsible for ensuring the slots are inactive, and will
+ * not be activated.
+ */
+int edma_free_cont_slots(unsigned slot, int count)
+{
+	unsigned ctlr, slot_to_free;
+	int i;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_cc[ctlr]->num_channels ||
+		slot >= edma_cc[ctlr]->num_slots ||
+		count < 1)
+		return -EINVAL;
+
+	for (i = slot; i < slot + count; ++i) {
+		ctlr = EDMA_CTLR(i);
+		slot_to_free = EDMA_CHAN_SLOT(i);
+
+		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free),
+			&dummy_paramset, PARM_SIZE);
+		clear_bit(slot_to_free, edma_cc[ctlr]->edma_inuse);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(edma_free_cont_slots);
+
+/*-----------------------------------------------------------------------*/
+
+/* Parameter RAM operations (i) -- read/write partial slots */
+
+/**
+ * edma_set_src - set initial DMA source address in parameter RAM slot
+ * @slot: parameter RAM slot being configured
+ * @src_port: physical address of source (memory, controller FIFO, etc)
+ * @addressMode: INCR, except in very rare cases
+ * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
+ *	width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the source address is modified during the DMA transfer
+ * according to edma_set_src_index().
+ */
+void edma_set_src(unsigned slot, dma_addr_t src_port,
+				enum address_mode mode, enum fifo_width width)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_cc[ctlr]->num_slots) {
+		unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
+
+		if (mode) {
+			/* set SAM and program FWID */
+			i = (i & ~(EDMA_FWID)) | (SAM | ((width & 0x7) << 8));
+		} else {
+			/* clear SAM */
+			i &= ~SAM;
+		}
+		edma_parm_write(ctlr, PARM_OPT, slot, i);
+
+		/* set the source port address
+		   in source register of param structure */
+		edma_parm_write(ctlr, PARM_SRC, slot, src_port);
+	}
+}
+EXPORT_SYMBOL(edma_set_src);
+
+/**
+ * edma_set_dest - set initial DMA destination address in parameter RAM slot
+ * @slot: parameter RAM slot being configured
+ * @dest_port: physical address of destination (memory, controller FIFO, etc)
+ * @addressMode: INCR, except in very rare cases
+ * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
+ *	width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the destination address is modified during the DMA transfer
+ * according to edma_set_dest_index().
+ */
+void edma_set_dest(unsigned slot, dma_addr_t dest_port,
+				 enum address_mode mode, enum fifo_width width)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_cc[ctlr]->num_slots) {
+		unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
+
+		if (mode) {
+			/* set DAM and program FWID */
+			i = (i & ~(EDMA_FWID)) | (DAM | ((width & 0x7) << 8));
+		} else {
+			/* clear DAM */
+			i &= ~DAM;
+		}
+		edma_parm_write(ctlr, PARM_OPT, slot, i);
+		/* set the destination port address
+		   in dest register of param structure */
+		edma_parm_write(ctlr, PARM_DST, slot, dest_port);
+	}
+}
+EXPORT_SYMBOL(edma_set_dest);
+
+/**
+ * edma_get_position - returns the current transfer points
+ * @slot: parameter RAM slot being examined
+ * @src: pointer to source port position
+ * @dst: pointer to destination port position
+ *
+ * Returns current source and destination addresses for a particular
+ * parameter RAM slot.  Its channel should not be active when this is called.
+ */
+void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst)
+{
+	struct edmacc_param temp;
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	edma_read_slot(EDMA_CTLR_CHAN(ctlr, slot), &temp);
+	if (src != NULL)
+		*src = temp.src;
+	if (dst != NULL)
+		*dst = temp.dst;
+}
+EXPORT_SYMBOL(edma_get_position);
+
+/**
+ * edma_set_src_index - configure DMA source address indexing
+ * @slot: parameter RAM slot being configured
+ * @src_bidx: byte offset between source arrays in a frame
+ * @src_cidx: byte offset between source frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_cc[ctlr]->num_slots) {
+		edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
+				0xffff0000, src_bidx);
+		edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
+				0xffff0000, src_cidx);
+	}
+}
+EXPORT_SYMBOL(edma_set_src_index);
+
+/**
+ * edma_set_dest_index - configure DMA destination address indexing
+ * @slot: parameter RAM slot being configured
+ * @dest_bidx: byte offset between destination arrays in a frame
+ * @dest_cidx: byte offset between destination frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_cc[ctlr]->num_slots) {
+		edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
+				0x0000ffff, dest_bidx << 16);
+		edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
+				0x0000ffff, dest_cidx << 16);
+	}
+}
+EXPORT_SYMBOL(edma_set_dest_index);
+
+/**
+ * edma_set_transfer_params - configure DMA transfer parameters
+ * @slot: parameter RAM slot being configured
+ * @acnt: how many bytes per array (at least one)
+ * @bcnt: how many arrays per frame (at least one)
+ * @ccnt: how many frames per block (at least one)
+ * @bcnt_rld: used only for A-Synchronized transfers; this specifies
+ *	the value to reload into bcnt when it decrements to zero
+ * @sync_mode: ASYNC or ABSYNC
+ *
+ * See the EDMA3 documentation to understand how to configure and link
+ * transfers using the fields in PaRAM slots.  If you are not doing it
+ * all at once with edma_write_slot(), you will use this routine
+ * plus two calls each for source and destination, setting the initial
+ * address and saying how to index that address.
+ *
+ * An example of an A-Synchronized transfer is a serial link using a
+ * single word shift register.  In that case, @acnt would be equal to
+ * that word size; the serial controller issues a DMA synchronization
+ * event to transfer each word, and memory access by the DMA transfer
+ * controller will be word-at-a-time.
+ *
+ * An example of an AB-Synchronized transfer is a device using a FIFO.
+ * In that case, @acnt equals the FIFO width and @bcnt equals its depth.
+ * The controller with the FIFO issues DMA synchronization events when
+ * the FIFO threshold is reached, and the DMA transfer controller will
+ * transfer one frame to (or from) the FIFO.  It will probably use
+ * efficient burst modes to access memory.
+ */
+void edma_set_transfer_params(unsigned slot,
+		u16 acnt, u16 bcnt, u16 ccnt,
+		u16 bcnt_rld, enum sync_dimension sync_mode)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_cc[ctlr]->num_slots) {
+		edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot,
+				0x0000ffff, bcnt_rld << 16);
+		if (sync_mode == ASYNC)
+			edma_parm_and(ctlr, PARM_OPT, slot, ~SYNCDIM);
+		else
+			edma_parm_or(ctlr, PARM_OPT, slot, SYNCDIM);
+		/* Set the acount, bcount, ccount registers */
+		edma_parm_write(ctlr, PARM_A_B_CNT, slot, (bcnt << 16) | acnt);
+		edma_parm_write(ctlr, PARM_CCNT, slot, ccnt);
+	}
+}
+EXPORT_SYMBOL(edma_set_transfer_params);
+
+/**
+ * edma_link - link one parameter RAM slot to another
+ * @from: parameter RAM slot originating the link
+ * @to: parameter RAM slot which is the link target
+ *
+ * The originating slot should not be part of any active DMA transfer.
+ */
+void edma_link(unsigned from, unsigned to)
+{
+	unsigned ctlr_from, ctlr_to;
+
+	ctlr_from = EDMA_CTLR(from);
+	from = EDMA_CHAN_SLOT(from);
+	ctlr_to = EDMA_CTLR(to);
+	to = EDMA_CHAN_SLOT(to);
+
+	if (from >= edma_cc[ctlr_from]->num_slots)
+		return;
+	if (to >= edma_cc[ctlr_to]->num_slots)
+		return;
+	edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000,
+				PARM_OFFSET(to));
+}
+EXPORT_SYMBOL(edma_link);
+
+/**
+ * edma_unlink - cut link from one parameter RAM slot
+ * @from: parameter RAM slot originating the link
+ *
+ * The originating slot should not be part of any active DMA transfer.
+ * Its link is set to 0xffff.
+ */
+void edma_unlink(unsigned from)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(from);
+	from = EDMA_CHAN_SLOT(from);
+
+	if (from >= edma_cc[ctlr]->num_slots)
+		return;
+	edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff);
+}
+EXPORT_SYMBOL(edma_unlink);
+
+/*-----------------------------------------------------------------------*/
+
+/* Parameter RAM operations (ii) -- read/write whole parameter sets */
+
+/**
+ * edma_write_slot - write parameter RAM data for slot
+ * @slot: number of parameter RAM slot being modified
+ * @param: data to be written into parameter RAM slot
+ *
+ * Use this to assign all parameters of a transfer at once.  This
+ * allows more efficient setup of transfers than issuing multiple
+ * calls to set up those parameters in small pieces, and provides
+ * complete control over all transfer options.
+ */
+void edma_write_slot(unsigned slot, const struct edmacc_param *param)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot >= edma_cc[ctlr]->num_slots)
+		return;
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param,
+			PARM_SIZE);
+}
+EXPORT_SYMBOL(edma_write_slot);
+
+/**
+ * edma_read_slot - read parameter RAM data from slot
+ * @slot: number of parameter RAM slot being copied
+ * @param: where to store copy of parameter RAM data
+ *
+ * Use this to read data from a parameter RAM slot, perhaps to
+ * save them as a template for later reuse.
+ */
+void edma_read_slot(unsigned slot, struct edmacc_param *param)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot >= edma_cc[ctlr]->num_slots)
+		return;
+	memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+			PARM_SIZE);
+}
+EXPORT_SYMBOL(edma_read_slot);
+
+/*-----------------------------------------------------------------------*/
+
+/* Various EDMA channel control operations */
+
+/**
+ * edma_pause - pause dma on a channel
+ * @channel: on which edma_start() has been called
+ *
+ * This temporarily disables EDMA hardware events on the specified channel,
+ * preventing them from triggering new transfers on its behalf
+ */
+void edma_pause(unsigned channel)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_cc[ctlr]->num_channels) {
+		unsigned int mask = BIT(channel & 0x1f);
+
+		edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask);
+	}
+}
+EXPORT_SYMBOL(edma_pause);
+
+/**
+ * edma_resume - resumes dma on a paused channel
+ * @channel: on which edma_pause() has been called
+ *
+ * This re-enables EDMA hardware events on the specified channel.
+ */
+void edma_resume(unsigned channel)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_cc[ctlr]->num_channels) {
+		unsigned int mask = BIT(channel & 0x1f);
+
+		edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask);
+	}
+}
+EXPORT_SYMBOL(edma_resume);
+
+/**
+ * edma_start - start dma on a channel
+ * @channel: channel being activated
+ *
+ * Channels with event associations will be triggered by their hardware
+ * events, and channels without such associations will be triggered by
+ * software.  (At this writing there is no interface for using software
+ * triggers except with channels that don't support hardware triggers.)
+ *
+ * Returns zero on success, else negative errno.
+ */
+int edma_start(unsigned channel)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_cc[ctlr]->num_channels) {
+		int j = channel >> 5;
+		unsigned int mask = BIT(channel & 0x1f);
+
+		/* EDMA channels without event association */
+		if (test_bit(channel, edma_cc[ctlr]->edma_unused)) {
+			pr_debug("EDMA: ESR%d %08x\n", j,
+				edma_shadow0_read_array(ctlr, SH_ESR, j));
+			edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
+			return 0;
+		}
+
+		/* EDMA channel with event association */
+		pr_debug("EDMA: ER%d %08x\n", j,
+			edma_shadow0_read_array(ctlr, SH_ER, j));
+		/* Clear any pending event or error */
+		edma_write_array(ctlr, EDMA_ECR, j, mask);
+		edma_write_array(ctlr, EDMA_EMCR, j, mask);
+		/* Clear any SER */
+		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+		edma_shadow0_write_array(ctlr, SH_EESR, j, mask);
+		pr_debug("EDMA: EER%d %08x\n", j,
+			edma_shadow0_read_array(ctlr, SH_EER, j));
+		return 0;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(edma_start);
+
+/**
+ * edma_stop - stops dma on the channel passed
+ * @channel: channel being deactivated
+ *
+ * When @lch is a channel, any active transfer is paused and
+ * all pending hardware events are cleared.  The current transfer
+ * may not be resumed, and the channel's Parameter RAM should be
+ * reinitialized before being reused.
+ */
+void edma_stop(unsigned channel)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_cc[ctlr]->num_channels) {
+		int j = channel >> 5;
+		unsigned int mask = BIT(channel & 0x1f);
+
+		edma_shadow0_write_array(ctlr, SH_EECR, j, mask);
+		edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
+		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+		edma_write_array(ctlr, EDMA_EMCR, j, mask);
+
+		pr_debug("EDMA: EER%d %08x\n", j,
+				edma_shadow0_read_array(ctlr, SH_EER, j));
+
+		/* REVISIT:  consider guarding against inappropriate event
+		 * chaining by overwriting with dummy_paramset.
+		 */
+	}
+}
+EXPORT_SYMBOL(edma_stop);
+
+/******************************************************************************
+ *
+ * It cleans ParamEntry qand bring back EDMA to initial state if media has
+ * been removed before EDMA has finished.It is usedful for removable media.
+ * Arguments:
+ *      ch_no     - channel no
+ *
+ * Return: zero on success, or corresponding error no on failure
+ *
+ * FIXME this should not be needed ... edma_stop() should suffice.
+ *
+ *****************************************************************************/
+
+void edma_clean_channel(unsigned channel)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_cc[ctlr]->num_channels) {
+		int j = (channel >> 5);
+		unsigned int mask = BIT(channel & 0x1f);
+
+		pr_debug("EDMA: EMR%d %08x\n", j,
+				edma_read_array(ctlr, EDMA_EMR, j));
+		edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
+		/* Clear the corresponding EMR bits */
+		edma_write_array(ctlr, EDMA_EMCR, j, mask);
+		/* Clear any SER */
+		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+		edma_write(ctlr, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0));
+	}
+}
+EXPORT_SYMBOL(edma_clean_channel);
+
+/*
+ * edma_clear_event - clear an outstanding event on the DMA channel
+ * Arguments:
+ *	channel - channel number
+ */
+void edma_clear_event(unsigned channel)
+{
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel >= edma_cc[ctlr]->num_channels)
+		return;
+	if (channel < 32)
+		edma_write(ctlr, EDMA_ECR, BIT(channel));
+	else
+		edma_write(ctlr, EDMA_ECRH, BIT(channel - 32));
+}
+EXPORT_SYMBOL(edma_clear_event);
+
+#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DMADEVICES)
+
+static int edma_of_read_u32_to_s16_array(const struct device_node *np,
+					 const char *propname, s16 *out_values,
+					 size_t sz)
+{
+	int ret;
+
+	ret = of_property_read_u16_array(np, propname, out_values, sz);
+	if (ret)
+		return ret;
+
+	/* Terminate it */
+	*out_values++ = -1;
+	*out_values++ = -1;
+
+	return 0;
+}
+
+static int edma_xbar_event_map(struct device *dev,
+			       struct device_node *node,
+			       struct edma_soc_info *pdata, int len)
+{
+	int ret, i;
+	struct resource res;
+	void __iomem *xbar;
+	const s16 (*xbar_chans)[2];
+	u32 shift, offset, mux;
+
+	xbar_chans = devm_kzalloc(dev,
+				  len/sizeof(s16) + 2*sizeof(s16),
+				  GFP_KERNEL);
+	if (!xbar_chans)
+		return -ENOMEM;
+
+	ret = of_address_to_resource(node, 1, &res);
+	if (ret)
+		return -EIO;
+
+	xbar = devm_ioremap(dev, res.start, resource_size(&res));
+	if (!xbar)
+		return -ENOMEM;
+
+	ret = edma_of_read_u32_to_s16_array(node,
+					    "ti,edma-xbar-event-map",
+					    (s16 *)xbar_chans,
+					    len/sizeof(u32));
+	if (ret)
+		return -EIO;
+
+	for (i = 0; xbar_chans[i][0] != -1; i++) {
+		shift = (xbar_chans[i][1] & 0x03) << 3;
+		offset = xbar_chans[i][1] & 0xfffffffc;
+		mux = readl(xbar + offset);
+		mux &= ~(0xff << shift);
+		mux |= xbar_chans[i][0] << shift;
+		writel(mux, (xbar + offset));
+	}
+
+	pdata->xbar_chans = xbar_chans;
+
+	return 0;
+}
+
+static int edma_of_parse_dt(struct device *dev,
+			    struct device_node *node,
+			    struct edma_soc_info *pdata)
+{
+	int ret = 0, i;
+	u32 value;
+	struct property *prop;
+	size_t sz;
+	struct edma_rsv_info *rsv_info;
+	s8 (*queue_tc_map)[2], (*queue_priority_map)[2];
+
+	memset(pdata, 0, sizeof(struct edma_soc_info));
+
+	ret = of_property_read_u32(node, "dma-channels", &value);
+	if (ret < 0)
+		return ret;
+	pdata->n_channel = value;
+
+	ret = of_property_read_u32(node, "ti,edma-regions", &value);
+	if (ret < 0)
+		return ret;
+	pdata->n_region = value;
+
+	ret = of_property_read_u32(node, "ti,edma-slots", &value);
+	if (ret < 0)
+		return ret;
+	pdata->n_slot = value;
+
+	pdata->n_cc = 1;
+
+	rsv_info = devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL);
+	if (!rsv_info)
+		return -ENOMEM;
+	pdata->rsv = rsv_info;
+
+	queue_tc_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL);
+	if (!queue_tc_map)
+		return -ENOMEM;
+
+	for (i = 0; i < 3; i++) {
+		queue_tc_map[i][0] = i;
+		queue_tc_map[i][1] = i;
+	}
+	queue_tc_map[i][0] = -1;
+	queue_tc_map[i][1] = -1;
+
+	pdata->queue_tc_mapping = queue_tc_map;
+
+	queue_priority_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL);
+	if (!queue_priority_map)
+		return -ENOMEM;
+
+	for (i = 0; i < 3; i++) {
+		queue_priority_map[i][0] = i;
+		queue_priority_map[i][1] = i;
+	}
+	queue_priority_map[i][0] = -1;
+	queue_priority_map[i][1] = -1;
+
+	pdata->queue_priority_mapping = queue_priority_map;
+
+	pdata->default_queue = 0;
+
+	prop = of_find_property(node, "ti,edma-xbar-event-map", &sz);
+	if (prop)
+		ret = edma_xbar_event_map(dev, node, pdata, sz);
+
+	return ret;
+}
+
+static struct of_dma_filter_info edma_filter_info = {
+	.filter_fn = edma_filter_fn,
+};
+
+static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
+						      struct device_node *node)
+{
+	struct edma_soc_info *info;
+	int ret;
+
+	info = devm_kzalloc(dev, sizeof(struct edma_soc_info), GFP_KERNEL);
+	if (!info)
+		return ERR_PTR(-ENOMEM);
+
+	ret = edma_of_parse_dt(dev, node, info);
+	if (ret)
+		return ERR_PTR(ret);
+
+	dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
+	of_dma_controller_register(dev->of_node, of_dma_simple_xlate,
+				   &edma_filter_info);
+
+	return info;
+}
+#else
+static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
+						      struct device_node *node)
+{
+	return ERR_PTR(-ENOSYS);
+}
+#endif
+
+static int edma_probe(struct platform_device *pdev)
+{
+	struct edma_soc_info	**info = pdev->dev.platform_data;
+	struct edma_soc_info    *ninfo[EDMA_MAX_CC] = {NULL};
+	s8		(*queue_priority_mapping)[2];
+	s8		(*queue_tc_mapping)[2];
+	int			i, j, off, ln, found = 0;
+	int			status = -1;
+	const s16		(*rsv_chans)[2];
+	const s16		(*rsv_slots)[2];
+	const s16		(*xbar_chans)[2];
+	int			irq[EDMA_MAX_CC] = {0, 0};
+	int			err_irq[EDMA_MAX_CC] = {0, 0};
+	struct resource		*r[EDMA_MAX_CC] = {NULL};
+	struct resource		res[EDMA_MAX_CC];
+	char			res_name[10];
+	char			irq_name[10];
+	struct device_node	*node = pdev->dev.of_node;
+	struct device		*dev = &pdev->dev;
+	int			ret;
+
+	if (node) {
+		/* Check if this is a second instance registered */
+		if (arch_num_cc) {
+			dev_err(dev, "only one EDMA instance is supported via DT\n");
+			return -ENODEV;
+		}
+
+		ninfo[0] = edma_setup_info_from_dt(dev, node);
+		if (IS_ERR(ninfo[0])) {
+			dev_err(dev, "failed to get DT data\n");
+			return PTR_ERR(ninfo[0]);
+		}
+
+		info = ninfo;
+	}
+
+	if (!info)
+		return -ENODEV;
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync() failed\n");
+		return ret;
+	}
+
+	for (j = 0; j < EDMA_MAX_CC; j++) {
+		if (!info[j]) {
+			if (!found)
+				return -ENODEV;
+			break;
+		}
+		if (node) {
+			ret = of_address_to_resource(node, j, &res[j]);
+			if (!ret)
+				r[j] = &res[j];
+		} else {
+			sprintf(res_name, "edma_cc%d", j);
+			r[j] = platform_get_resource_byname(pdev,
+						IORESOURCE_MEM,
+						res_name);
+		}
+		if (!r[j]) {
+			if (found)
+				break;
+			else
+				return -ENODEV;
+		} else {
+			found = 1;
+		}
+
+		edmacc_regs_base[j] = devm_ioremap_resource(&pdev->dev, r[j]);
+		if (IS_ERR(edmacc_regs_base[j]))
+			return PTR_ERR(edmacc_regs_base[j]);
+
+		edma_cc[j] = devm_kzalloc(&pdev->dev, sizeof(struct edma),
+					  GFP_KERNEL);
+		if (!edma_cc[j])
+			return -ENOMEM;
+
+		edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel,
+							EDMA_MAX_DMACH);
+		edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot,
+							EDMA_MAX_PARAMENTRY);
+		edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc,
+							EDMA_MAX_CC);
+
+		edma_cc[j]->default_queue = info[j]->default_queue;
+
+		dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n",
+			edmacc_regs_base[j]);
+
+		for (i = 0; i < edma_cc[j]->num_slots; i++)
+			memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
+					&dummy_paramset, PARM_SIZE);
+
+		/* Mark all channels as unused */
+		memset(edma_cc[j]->edma_unused, 0xff,
+			sizeof(edma_cc[j]->edma_unused));
+
+		if (info[j]->rsv) {
+
+			/* Clear the reserved channels in unused list */
+			rsv_chans = info[j]->rsv->rsv_chans;
+			if (rsv_chans) {
+				for (i = 0; rsv_chans[i][0] != -1; i++) {
+					off = rsv_chans[i][0];
+					ln = rsv_chans[i][1];
+					clear_bits(off, ln,
+						  edma_cc[j]->edma_unused);
+				}
+			}
+
+			/* Set the reserved slots in inuse list */
+			rsv_slots = info[j]->rsv->rsv_slots;
+			if (rsv_slots) {
+				for (i = 0; rsv_slots[i][0] != -1; i++) {
+					off = rsv_slots[i][0];
+					ln = rsv_slots[i][1];
+					set_bits(off, ln,
+						edma_cc[j]->edma_inuse);
+				}
+			}
+		}
+
+		/* Clear the xbar mapped channels in unused list */
+		xbar_chans = info[j]->xbar_chans;
+		if (xbar_chans) {
+			for (i = 0; xbar_chans[i][1] != -1; i++) {
+				off = xbar_chans[i][1];
+				clear_bits(off, 1,
+					   edma_cc[j]->edma_unused);
+			}
+		}
+
+		if (node) {
+			irq[j] = irq_of_parse_and_map(node, 0);
+		} else {
+			sprintf(irq_name, "edma%d", j);
+			irq[j] = platform_get_irq_byname(pdev, irq_name);
+		}
+		edma_cc[j]->irq_res_start = irq[j];
+		status = devm_request_irq(&pdev->dev, irq[j],
+					  dma_irq_handler, 0, "edma",
+					  &pdev->dev);
+		if (status < 0) {
+			dev_dbg(&pdev->dev,
+				"devm_request_irq %d failed --> %d\n",
+				irq[j], status);
+			return status;
+		}
+
+		if (node) {
+			err_irq[j] = irq_of_parse_and_map(node, 2);
+		} else {
+			sprintf(irq_name, "edma%d_err", j);
+			err_irq[j] = platform_get_irq_byname(pdev, irq_name);
+		}
+		edma_cc[j]->irq_res_end = err_irq[j];
+		status = devm_request_irq(&pdev->dev, err_irq[j],
+					  dma_ccerr_handler, 0,
+					  "edma_error", &pdev->dev);
+		if (status < 0) {
+			dev_dbg(&pdev->dev,
+				"devm_request_irq %d failed --> %d\n",
+				err_irq[j], status);
+			return status;
+		}
+
+		for (i = 0; i < edma_cc[j]->num_channels; i++)
+			map_dmach_queue(j, i, info[j]->default_queue);
+
+		queue_tc_mapping = info[j]->queue_tc_mapping;
+		queue_priority_mapping = info[j]->queue_priority_mapping;
+
+		/* Event queue to TC mapping */
+		for (i = 0; queue_tc_mapping[i][0] != -1; i++)
+			map_queue_tc(j, queue_tc_mapping[i][0],
+					queue_tc_mapping[i][1]);
+
+		/* Event queue priority mapping */
+		for (i = 0; queue_priority_mapping[i][0] != -1; i++)
+			assign_priority_to_queue(j,
+						queue_priority_mapping[i][0],
+						queue_priority_mapping[i][1]);
+
+		/* Map the channel to param entry if channel mapping logic
+		 * exist
+		 */
+		if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
+			map_dmach_param(j);
+
+		for (i = 0; i < info[j]->n_region; i++) {
+			edma_write_array2(j, EDMA_DRAE, i, 0, 0x0);
+			edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
+			edma_write_array(j, EDMA_QRAE, i, 0x0);
+		}
+		arch_num_cc++;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id edma_of_ids[] = {
+	{ .compatible = "ti,edma3", },
+	{}
+};
+
+static struct platform_driver edma_driver = {
+	.driver = {
+		.name	= "edma",
+		.of_match_table = edma_of_ids,
+	},
+	.probe = edma_probe,
+};
+
+static int __init edma_init(void)
+{
+	return platform_driver_probe(&edma_driver, edma_probe);
+}
+arch_initcall(edma_init);
+
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/common/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/common/Kconfig
--- linux-libre-3.10-gnu/arch/arm/common/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/common/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -17,3 +17,6 @@ config SHARP_PARAM
 
 config SHARP_SCOOP
 	bool
+
+config TI_PRIV_EDMA
+	bool
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/common/Makefile linux-libre-3.11-rc7-gnu/arch/arm/common/Makefile
--- linux-libre-3.10-gnu/arch/arm/common/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/common/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -16,3 +16,4 @@ obj-$(CONFIG_ARM_TIMER_SP804)	+= timer-s
 obj-$(CONFIG_MCPM)		+= mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
 AFLAGS_mcpm_head.o		:= -march=armv7-a
 AFLAGS_vlock.o			:= -march=armv7-a
+obj-$(CONFIG_TI_PRIV_EDMA)	+= edma.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/common/mcpm_head.S linux-libre-3.11-rc7-gnu/arch/arm/common/mcpm_head.S
--- linux-libre-3.10-gnu/arch/arm/common/mcpm_head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/common/mcpm_head.S	2013-08-25 20:43:22.000000000 -0400
@@ -32,11 +32,11 @@
 1901:	adr	r0, 1902b
 	bl	printascii
 	mov	r0, r9
-	bl	printhex8
+	bl	printhex2
 	adr	r0, 1903b
 	bl	printascii
 	mov	r0, r10
-	bl	printhex8
+	bl	printhex2
 	adr	r0, 1904b
 	bl	printascii
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/common/mcpm_platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/common/mcpm_platsmp.c
--- linux-libre-3.10-gnu/arch/arm/common/mcpm_platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/common/mcpm_platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,11 +19,7 @@
 #include <asm/smp.h>
 #include <asm/smp_plat.h>
 
-static void __init simple_smp_init_cpus(void)
-{
-}
-
-static int __cpuinit mcpm_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int mcpm_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned int mpidr, pcpu, pcluster, ret;
 	extern void secondary_startup(void);
@@ -44,7 +40,7 @@ static int __cpuinit mcpm_boot_secondary
 	return 0;
 }
 
-static void __cpuinit mcpm_secondary_init(unsigned int cpu)
+static void mcpm_secondary_init(unsigned int cpu)
 {
 	mcpm_cpu_powered_up();
 }
@@ -74,7 +70,6 @@ static void mcpm_cpu_die(unsigned int cp
 #endif
 
 static struct smp_operations __initdata mcpm_smp_ops = {
-	.smp_init_cpus		= simple_smp_init_cpus,
 	.smp_boot_secondary	= mcpm_boot_secondary,
 	.smp_secondary_init	= mcpm_secondary_init,
 #ifdef CONFIG_HOTPLUG_CPU
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/common/timer-sp.c linux-libre-3.11-rc7-gnu/arch/arm/common/timer-sp.c
--- linux-libre-3.10-gnu/arch/arm/common/timer-sp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/common/timer-sp.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,8 +28,8 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/sched_clock.h>
 
-#include <asm/sched_clock.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/timer-sp.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/ap4evb_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/ap4evb_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/ap4evb_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/ap4evb_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
-CONFIG_ARCH_SH7372=y
-CONFIG_MACH_AP4EVB=y
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=sh-sci.0,115200"
-CONFIG_KEXEC=y
-CONFIG_PM=y
-# CONFIG_SUSPEND is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_NAND=y
-# CONFIG_BLK_DEV is not set
-# CONFIG_MISC_DEVICES is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=8
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-# CONFIG_MISC_FILESYSTEMS is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DETECT_SOFTLOCKUP is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_FTRACE is not set
-# CONFIG_CRC32 is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/armadillo800eva_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/armadillo800eva_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/armadillo800eva_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/armadillo800eva_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -86,7 +86,7 @@ CONFIG_TOUCHSCREEN_ST1232=y
 # CONFIG_SERIO is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+CONFIG_SERIAL_SH_SCI_NR_UARTS=9
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/at91_dt_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/at91_dt_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/at91_dt_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/at91_dt_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
@@ -25,8 +24,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 CONFIG_AT91_TIMER_HZ=128
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
 CONFIG_UACCESS_WITH_MEMCPY=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
@@ -42,6 +39,9 @@ CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
@@ -51,7 +51,8 @@ CONFIG_IPV6=y
 # CONFIG_INET6_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET6_XFRM_MODE_BEET is not set
 CONFIG_IPV6_SIT_6RD=y
-# CONFIG_WIRELESS is not set
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -72,7 +73,6 @@ CONFIG_BLK_DEV_RAM_COUNT=4
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_ATMEL_PWM=y
 CONFIG_ATMEL_TCLIB=y
-CONFIG_EEPROM_93CX6=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
@@ -81,7 +81,6 @@ CONFIG_NETDEVICES=y
 CONFIG_MII=y
 CONFIG_MACB=y
 # CONFIG_NET_VENDOR_BROADCOM is not set
-# CONFIG_NET_VENDOR_CHELSIO is not set
 # CONFIG_NET_VENDOR_FARADAY is not set
 # CONFIG_NET_VENDOR_INTEL is not set
 # CONFIG_NET_VENDOR_MARVELL is not set
@@ -92,7 +91,23 @@ CONFIG_MACB=y
 # CONFIG_NET_VENDOR_STMICRO is not set
 CONFIG_DAVICOM_PHY=y
 CONFIG_MICREL_PHY=y
-# CONFIG_WLAN is not set
+CONFIG_RTL8187=m
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_LIBERTAS_SPI=m
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_RT2800USB_RT53XX=y
+CONFIG_RT2800USB_RT55XX=y
+CONFIG_RT2800USB_UNKNOWN=y
+CONFIG_RTLWIFI=m
+# CONFIG_RTLWIFI_DEBUG is not set
+CONFIG_RTL8192CU=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_USB=m
 CONFIG_INPUT_POLLDEV=y
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
@@ -112,13 +127,11 @@ CONFIG_I2C=y
 CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
-CONFIG_PINCTRL_AT91=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_AT91SAM9X_WATCHDOG=y
 CONFIG_SSB=m
 CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_ATMEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
@@ -132,11 +145,8 @@ CONFIG_FONT_8x8=y
 CONFIG_FONT_ACORN_8x8=y
 CONFIG_FONT_MINI_4x6=y
 CONFIG_LOGO=y
-# CONFIG_HID_SUPPORT is not set
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_ACM=y
@@ -146,16 +156,12 @@ CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_FTDI_SIO=y
 CONFIG_USB_SERIAL_PL2303=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_AT91=m
-CONFIG_USB_ATMEL_USBA=m
-CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_CDC_COMPOSITE=m
-CONFIG_USB_G_ACM_MS=m
-CONFIG_USB_G_MULTI=m
-CONFIG_USB_G_MULTI_CDC=y
+CONFIG_USB_AT91=y
+CONFIG_USB_ATMEL_USBA=y
+CONFIG_USB_G_SERIAL=y
 CONFIG_MMC=y
 CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_SPI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
@@ -164,20 +170,23 @@ CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_GPIO=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RV3029C2=y
 CONFIG_RTC_DRV_AT91RM9200=y
 CONFIG_RTC_DRV_AT91SAM9=y
 CONFIG_DMADEVICES=y
 # CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXT2_FS=y
+CONFIG_EXT4_FS=y
 CONFIG_FANOTIFY=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_850=y
 CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_FS=y
 # CONFIG_SCHED_DEBUG is not set
@@ -192,7 +201,7 @@ CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
 # CONFIG_CRYPTO_HW is not set
-CONFIG_CRC_CCITT=m
-CONFIG_CRC_ITU_T=m
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
 CONFIG_CRC7=m
 CONFIG_AVERAGE=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/at91rm9200_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/at91rm9200_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/at91rm9200_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/at91rm9200_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,10 +1,12 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_USER_NS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_MODULES=y
 CONFIG_MODULE_FORCE_LOAD=y
@@ -16,7 +18,6 @@ CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_ARCH_AT91=y
 CONFIG_ARCH_AT91RM9200=y
 CONFIG_MACH_ONEARM=y
-CONFIG_ARCH_AT91RM9200DK=y
 CONFIG_MACH_AT91RM9200EK=y
 CONFIG_MACH_CSB337=y
 CONFIG_MACH_CSB637=y
@@ -35,49 +36,37 @@ CONFIG_AT91_TIMER_HZ=100
 # CONFIG_ARM_THUMB is not set
 CONFIG_PCCARD=y
 CONFIG_AT91_CF=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
 CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
+# CONFIG_COMPACTION is not set
 CONFIG_ZBOOT_ROM_TEXT=0x10000000
 CONFIG_ZBOOT_ROM_BSS=0x20040000
 CONFIG_KEXEC=y
+CONFIG_AUTO_ZRELADDR=y
 CONFIG_FPE_NWFPE=y
 CONFIG_BINFMT_MISC=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-CONFIG_NET_IPIP=m
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
 CONFIG_IPV6_ROUTE_INFO=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_BT=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_AFS_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
@@ -94,55 +83,21 @@ CONFIG_MTD_NAND_PLATFORM=y
 CONFIG_MTD_UBI=y
 CONFIG_MTD_UBI_GLUEBI=y
 CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
-CONFIG_TUN=m
+CONFIG_MII=y
 CONFIG_ARM_AT91_ETHER=y
-CONFIG_PHYLIB=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_SMSC_PHY=y
 CONFIG_MICREL_PHY=y
-CONFIG_PPP=y
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_MPPE=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=y
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_DM9601=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_LEGACY_PTY_COUNT=32
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_HW_RANDOM=y
@@ -151,38 +106,8 @@ CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
-CONFIG_SPI_BITBANG=y
 CONFIG_GPIO_SYSFS=y
-CONFIG_HWMON=m
-CONFIG_SENSORS_ADM1021=m
-CONFIG_SENSORS_ADM1025=m
-CONFIG_SENSORS_ADM1026=m
-CONFIG_SENSORS_ADM1029=m
-CONFIG_SENSORS_ADM1031=m
-CONFIG_SENSORS_ADM9240=m
-CONFIG_SENSORS_DS1621=m
-CONFIG_SENSORS_GL518SM=m
-CONFIG_SENSORS_GL520SM=m
-CONFIG_SENSORS_IT87=m
-CONFIG_SENSORS_LM63=m
-CONFIG_SENSORS_LM73=m
-CONFIG_SENSORS_LM75=m
-CONFIG_SENSORS_LM77=m
-CONFIG_SENSORS_LM78=m
-CONFIG_SENSORS_LM80=m
-CONFIG_SENSORS_LM83=m
-CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_LM87=m
-CONFIG_SENSORS_LM90=m
-CONFIG_SENSORS_LM92=m
-CONFIG_SENSORS_MAX1619=m
-CONFIG_SENSORS_PCF8591=m
-CONFIG_SENSORS_SMSC47B397=m
-CONFIG_SENSORS_W83781D=m
-CONFIG_SENSORS_W83791D=m
-CONFIG_SENSORS_W83792D=m
-CONFIG_SENSORS_W83793=m
-CONFIG_SENSORS_W83L785TS=m
+# CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_AT91RM9200_WATCHDOG=y
@@ -194,43 +119,14 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_BACKLIGHT_GENERIC is not set
-CONFIG_DISPLAY_SUPPORT=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FONTS=y
-CONFIG_FONT_MINI_4x6=y
 CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
 CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=y
-CONFIG_USB_SERIAL_KEYSPAN=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_MCT_U232=y
-CONFIG_USB_SERIAL_PL2303=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_AT91=y
+CONFIG_USB_G_SERIAL=y
 CONFIG_MMC=y
 CONFIG_MMC_ATMELMCI=y
 CONFIG_NEW_LEDS=y
@@ -240,84 +136,27 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_RTC_CLASS=y
-# CONFIG_RTC_HCTOSYS is not set
-CONFIG_RTC_DRV_DS1307=y
-CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_AT91RM9200=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_REISERFS_FS=y
+CONFIG_EXT4_FS=y
 CONFIG_AUTOFS4_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
-CONFIG_NTFS_FS=m
 CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_CRAMFS=y
-CONFIG_MINIX_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_CIFS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_PARTITION=y
 CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
+CONFIG_NLS_CODEPAGE_850=y
 CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
 CONFIG_CRYPTO_PCBC=y
 CONFIG_CRYPTO_SHA1=y
+CONFIG_XZ_DEC_ARMTHUMB=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/at91sam9260_9g20_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9260_9g20_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/at91sam9260_9g20_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9260_9g20_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,155 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_MACH_AT91SAM9260EK=y
+CONFIG_MACH_CAM60=y
+CONFIG_MACH_SAM9_L9260=y
+CONFIG_MACH_AFEB9260=y
+CONFIG_MACH_QIL_A9260=y
+CONFIG_MACH_CPU9260=y
+CONFIG_MACH_FLEXIBITY=y
+CONFIG_MACH_AT91SAM9G20EK=y
+CONFIG_MACH_AT91SAM9G20EK_2MMC=y
+CONFIG_MACH_CPU9G20=y
+CONFIG_MACH_ACMENETUSFOXG20=y
+CONFIG_MACH_PORTUXG20=y
+CONFIG_MACH_STAMP9G20=y
+CONFIG_MACH_PCONTROL_G20=y
+CONFIG_MACH_GSIA18S=y
+CONFIG_MACH_SNAPPER_9260=y
+CONFIG_MACH_AT91SAM9_DT=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_SLOW_CLOCK=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_MISC_DEVICES=y
+CONFIG_EEPROM_AT25=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_AT91=y
+CONFIG_USB_G_SERIAL=y
+CONFIG_MMC=y
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_SPI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RV3029C2=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT4_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_LL=y
+CONFIG_AT91_DEBUG_LL_DBGU0=y
+CONFIG_EARLY_PRINTK=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/at91sam9260_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9260_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/at91sam9260_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9260_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,91 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9260=y
-CONFIG_ARCH_AT91SAM9260_SAM9XE=y
-CONFIG_MACH_AT91SAM9260EK=y
-CONFIG_MACH_CAM60=y
-CONFIG_MACH_SAM9_L9260=y
-CONFIG_MACH_AFEB9260=y
-CONFIG_MACH_USB_A9260=y
-CONFIG_MACH_QIL_A9260=y
-CONFIG_MACH_CPU9260=y
-CONFIG_MACH_FLEXIBITY=y
-CONFIG_MACH_SNAPPER_9260=y
-CONFIG_MACH_AT91SAM9_DT=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91SAM9X_WATCHDOG=y
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DEBUG=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_MASS_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/at91sam9261_9g10_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9261_9g10_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/at91sam9261_9g10_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9261_9g10_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,149 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9261=y
+CONFIG_MACH_AT91SAM9261EK=y
+CONFIG_MACH_AT91SAM9G10EK=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_SSC=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_DM9000=y
+CONFIG_USB_ZD1201=m
+CONFIG_RTL8187=m
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_LIBERTAS_SPI=m
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_ZD1211RW=m
+CONFIG_INPUT_POLLDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ATMEL=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_ATMEL_LCDC=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_AT73C213=y
+CONFIG_SND_USB_AUDIO=m
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_AT91=y
+CONFIG_USB_G_SERIAL=y
+CONFIG_MMC=y
+CONFIG_MMC_ATMELMCI=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_CRC_CCITT=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/at91sam9261_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9261_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/at91sam9261_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9261_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,158 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_KERNEL_LZMA=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_NAMESPACES=y
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9261=y
-CONFIG_MACH_AT91SAM9261EK=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_VFP=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_CFG80211=y
-CONFIG_LIB80211=y
-CONFIG_MAC80211=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_GLUEBI=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_MISC_DEVICES=y
-CONFIG_ATMEL_TCLIB=y
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_DM9000=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_USB_ZD1201=m
-CONFIG_RTL8187=m
-CONFIG_LIBERTAS=m
-CONFIG_LIBERTAS_USB=m
-CONFIG_LIBERTAS_SDIO=m
-CONFIG_LIBERTAS_SPI=m
-CONFIG_RT2X00=m
-CONFIG_RT2500USB=m
-CONFIG_RT73USB=m
-CONFIG_ZD1211RW=m
-CONFIG_INPUT_POLLDEV=m
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91SAM9X_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_ATMEL=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_ATMEL_LCDC=y
-# CONFIG_BACKLIGHT_GENERIC is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
-CONFIG_LOGO=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SEQUENCER=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PROCFS is not set
-# CONFIG_SND_DRIVERS is not set
-# CONFIG_SND_ARM is not set
-CONFIG_SND_AT73C213=y
-CONFIG_SND_USB_AUDIO=m
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_MASS_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_MMC=y
-CONFIG_MMC_ATMELMCI=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_UBIFS_FS=y
-CONFIG_UBIFS_FS_ADVANCED_COMPR=y
-CONFIG_SQUASHFS=y
-CONFIG_SQUASHFS_LZO=y
-CONFIG_SQUASHFS_XZ=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-CONFIG_FTRACE=y
-CONFIG_CRC_CCITT=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/at91sam9263_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9263_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/at91sam9263_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9263_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,4 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_KERNEL_LZMA=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_IKCONFIG=y
@@ -17,7 +15,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_AT91=y
 CONFIG_ARCH_AT91SAM9263=y
 CONFIG_MACH_AT91SAM9263EK=y
-CONFIG_MACH_USB_A9263=y
 CONFIG_MTD_AT91_DATAFLASH_CARD=y
 # CONFIG_ARM_THUMB is not set
 CONFIG_AEABI=y
@@ -48,9 +45,11 @@ CONFIG_IP_PIMSM_V2=y
 # CONFIG_INET_LRO is not set
 # CONFIG_INET_DIAG is not set
 CONFIG_IPV6=y
+# CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -65,7 +64,6 @@ CONFIG_MTD_UBI_GLUEBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_MISC_DEVICES=y
 CONFIG_ATMEL_PWM=y
 CONFIG_ATMEL_TCLIB=y
 CONFIG_SCSI=y
@@ -73,23 +71,18 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
 CONFIG_NETDEVICES=y
 CONFIG_MII=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
 CONFIG_MACB=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_USB_ZD1201=m
+CONFIG_SMSC_PHY=y
+# CONFIG_WLAN is not set
 CONFIG_INPUT_POLLDEV=m
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+# CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=y
-CONFIG_LEGACY_PTY_COUNT=4
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_HW_RANDOM=y
@@ -98,6 +91,7 @@ CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
+CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
@@ -107,9 +101,9 @@ CONFIG_FB_ATMEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_ATMEL_LCDC=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
 CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
@@ -124,16 +118,12 @@ CONFIG_SND_ATMEL_AC97C=y
 # CONFIG_SND_SPI is not set
 CONFIG_SND_USB_AUDIO=m
 CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
 CONFIG_USB_MON=y
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_MASS_STORAGE=m
-CONFIG_USB_G_SERIAL=m
+CONFIG_USB_ATMEL_USBA=y
+CONFIG_USB_G_SERIAL=y
 CONFIG_MMC=y
 CONFIG_SDIO_UART=m
 CONFIG_MMC_ATMELMCI=m
@@ -145,22 +135,18 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_FUSE_FS=m
+CONFIG_EXT4_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
 CONFIG_UBIFS_FS=y
 CONFIG_UBIFS_FS_ADVANCED_COMPR=y
-CONFIG_CRAMFS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_850=y
 CONFIG_NLS_ISO8859_1=y
-CONFIG_FTRACE=y
+CONFIG_NLS_UTF8=y
 CONFIG_DEBUG_USER=y
 CONFIG_XZ_DEC=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/at91sam9g20_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9g20_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/at91sam9g20_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9g20_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,127 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9G20=y
-CONFIG_MACH_AT91SAM9G20EK=y
-CONFIG_MACH_AT91SAM9G20EK_2MMC=y
-CONFIG_MACH_CPU9G20=y
-CONFIG_MACH_ACMENETUSFOXG20=y
-CONFIG_MACH_PORTUXG20=y
-CONFIG_MACH_STAMP9G20=y
-CONFIG_MACH_PCONTROL_G20=y
-CONFIG_MACH_GSIA18S=y
-CONFIG_MACH_USB_A9G20=y
-CONFIG_MACH_SNAPPER_9260=y
-CONFIG_MACH_AT91SAM9_DT=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_NETDEVICES=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_LEGACY_PTY_COUNT=16
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_GPIO=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-CONFIG_SPI_SPIDEV=y
-# CONFIG_HWMON is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SEQUENCER=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_VERBOSE_PROCFS is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_MASS_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_MMC=y
-CONFIG_MMC_ATMELMCI=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_RV3029C2=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/at91sam9g45_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9g45_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/at91sam9g45_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/at91sam9g45_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
@@ -23,8 +22,6 @@ CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
 CONFIG_AT91_SLOW_CLOCK=y
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
 CONFIG_UACCESS_WITH_MEMCPY=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
@@ -36,6 +33,9 @@ CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
@@ -45,9 +45,6 @@ CONFIG_IPV6=y
 # CONFIG_INET6_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET6_XFRM_MODE_BEET is not set
 CONFIG_IPV6_SIT_6RD=y
-CONFIG_CFG80211=y
-CONFIG_LIB80211=y
-CONFIG_MAC80211=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -61,13 +58,14 @@ CONFIG_MTD_DATAFLASH=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ATMEL=y
 CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=4
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_MISC_DEVICES=y
 CONFIG_ATMEL_PWM=y
 CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_SSC=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
@@ -76,67 +74,40 @@ CONFIG_NETDEVICES=y
 CONFIG_MII=y
 CONFIG_MACB=y
 CONFIG_DAVICOM_PHY=y
-CONFIG_LIBERTAS_THINFIRM=m
-CONFIG_LIBERTAS_THINFIRM_USB=m
-CONFIG_AT76C50X_USB=m
-CONFIG_USB_ZD1201=m
-CONFIG_RTL8187=m
-CONFIG_ATH_COMMON=m
-CONFIG_ATH9K=m
-CONFIG_CARL9170=m
-CONFIG_B43=m
-CONFIG_B43_PHY_N=y
-CONFIG_LIBERTAS=m
-CONFIG_LIBERTAS_USB=m
-CONFIG_LIBERTAS_SDIO=m
-CONFIG_LIBERTAS_SPI=m
-CONFIG_RT2X00=m
-CONFIG_RT2500USB=m
-CONFIG_RT73USB=m
-CONFIG_RT2800USB=m
-CONFIG_RT2800USB_RT53XX=y
-CONFIG_RT2800USB_UNKNOWN=y
-CONFIG_RTL8192CU=m
-CONFIG_WL1251=m
-CONFIG_WL1251_SDIO=m
-CONFIG_WL12XX_MENU=m
-CONFIG_WL12XX=m
-CONFIG_WL12XX_SDIO=m
-CONFIG_ZD1211RW=m
-CONFIG_MWIFIEX=m
-CONFIG_MWIFIEX_SDIO=m
-CONFIG_INPUT_POLLDEV=m
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=272
+# CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_JOYDEV=y
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_QT1070=m
-CONFIG_KEYBOARD_QT2160=m
+CONFIG_KEYBOARD_QT1070=y
+CONFIG_KEYBOARD_QT2160=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=m
 CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
 # CONFIG_SERIO is not set
-CONFIG_LEGACY_PTY_COUNT=4
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_HW_RANDOM=y
 CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
 # CONFIG_HWMON is not set
 CONFIG_FB=y
 CONFIG_FB_ATMEL=y
-CONFIG_FB_UDL=m
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
-# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_ATMEL_LCDC=y
+CONFIG_BACKLIGHT_ATMEL_PWM=y
 # CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
+CONFIG_LOGO=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SEQUENCER=y
@@ -148,33 +119,25 @@ CONFIG_SND_PCM_OSS=y
 # CONFIG_SND_ARM is not set
 CONFIG_SND_ATMEL_AC97C=y
 # CONFIG_SND_SPI is not set
-CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB is not set
 # CONFIG_USB_HID is not set
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_ACM=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_ATMEL_USBA=m
-CONFIG_USB_ZERO=m
-CONFIG_USB_AUDIO=m
-CONFIG_USB_ETH=m
-CONFIG_USB_ETH_EEM=y
-CONFIG_USB_MASS_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_USB_CDC_COMPOSITE=m
-CONFIG_USB_G_MULTI=m
+CONFIG_USB_ATMEL_USBA=y
+CONFIG_USB_G_MULTI=y
 CONFIG_USB_G_MULTI_CDC=y
 CONFIG_MMC=y
 # CONFIG_MMC_BLOCK_BOUNCE is not set
-CONFIG_SDIO_UART=m
 CONFIG_MMC_ATMELMCI=y
-CONFIG_LEDS_ATMEL_PWM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_GPIO=y
@@ -184,17 +147,14 @@ CONFIG_DMADEVICES=y
 CONFIG_AT_HDMAC=y
 CONFIG_DMATEST=m
 # CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXT2_FS=y
+CONFIG_EXT4_FS=y
 CONFIG_FANOTIFY=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_CRAMFS=m
-CONFIG_SQUASHFS=m
-CONFIG_SQUASHFS_EMBEDDED=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_850=y
 CONFIG_NLS_ISO8859_1=y
@@ -203,6 +163,8 @@ CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
 CONFIG_CRYPTO_ECB=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_USER_API_HASH=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/bcm2835_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/bcm2835_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/bcm2835_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/bcm2835_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -55,14 +55,11 @@ CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
-# CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_TTY_PRINTK=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_BCM2835=y
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_BCM2835=y
@@ -70,11 +67,27 @@ CONFIG_SPI=y
 CONFIG_SPI_BCM2835=y
 CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_SIMPLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
 # CONFIG_USB_SUPPORT is not set
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=y
+CONFIG_LEDS_TRIGGER_CAMERA=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/bcm_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/bcm_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/bcm_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/bcm_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -78,6 +78,13 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_BCM_KONA=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGERS=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/bockw_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/bockw_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/bockw_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/bockw_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,7 @@ CONFIG_CMDLINE="console=ttySC0,115200 ig
 CONFIG_CMDLINE_FORCE=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_UNIX=y
 CONFIG_INET=y
@@ -48,6 +49,14 @@ CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_M25P80=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
@@ -71,7 +80,23 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_HWMON is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_I2C=y
+CONFIG_I2C_RCAR=y
+CONFIG_SPI=y
+CONFIG_SPI_SH_HSPI=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_RCAR_PHY=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHI=y
+CONFIG_MMC_SH_MMCIF=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RX8581=y
 CONFIG_UIO=y
 CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_IOMMU_SUPPORT is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/bonito_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/bonito_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/bonito_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/bonito_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,72 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE=y
-CONFIG_ARCH_R8A7740=y
-CONFIG_MACH_BONITO=y
-# CONFIG_SH_TIMER_TMU is not set
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_FORCE_MAX_ZONEORDER=12
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttySC5,115200 earlyprintk=sh-sci.5,115200 ignore_loglevel"
-CONFIG_KEXEC=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_SUSPEND is not set
-CONFIG_PM_RUNTIME=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_ARM_INTEGRATOR=y
-CONFIG_MTD_BLOCK2MTD=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=9
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_SH_MOBILE=y
-CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
-# CONFIG_MFD_SUPPORT is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_UIO=y
-CONFIG_UIO_PDRV=y
-CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY_USER is not set
-CONFIG_TMPFS=y
-# CONFIG_MISC_FILESYSTEMS is not set
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_ARM_UNWIND is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/clps711x_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/clps711x_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/clps711x_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/clps711x_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -31,21 +31,18 @@ CONFIG_EP7211_DONGLE=y
 # CONFIG_WIRELESS is not set
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_CFI_STAA=y
-CONFIG_MTD_AUTCPU12=y
 CONFIG_MTD_PLATRAM=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_GPIO=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
-# CONFIG_NET_VENDOR_CHELSIO is not set
 CONFIG_CS89x0=y
 CONFIG_CS89x0_PLATFORM=y
 # CONFIG_NET_VENDOR_FARADAY is not set
@@ -63,7 +60,11 @@ CONFIG_CS89x0_PLATFORM=y
 # CONFIG_VT is not set
 CONFIG_SERIAL_CLPS711X_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
+CONFIG_SPI_CLPS711X=y
+CONFIG_GPIO_CLPS711X=y
 CONFIG_GPIO_GENERIC_PLATFORM=y
 # CONFIG_HWMON is not set
 CONFIG_FB=y
@@ -87,4 +88,3 @@ CONFIG_DEBUG_LL=y
 CONFIG_EARLY_PRINTK=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
-# CONFIG_CRC32 is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/da8xx_omapl_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/da8xx_omapl_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/da8xx_omapl_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/da8xx_omapl_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -102,6 +102,8 @@ CONFIG_SND_SOC=m
 CONFIG_SND_DAVINCI_SOC=m
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_DMADEVICES=y
+CONFIG_TI_EDMA=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_XFS_FS=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/davinci_all_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/davinci_all_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/davinci_all_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/davinci_all_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -162,6 +162,8 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
 CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_TI_EDMA=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_XFS_FS=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/exynos_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/exynos_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/exynos_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/exynos_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -50,6 +50,7 @@ CONFIG_USB_USBNET=y
 CONFIG_USB_NET_SMSC75XX=y
 CONFIG_USB_NET_SMSC95XX=y
 CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_CROS_EC=y
 # CONFIG_MOUSE_PS2 is not set
 CONFIG_MOUSE_CYAPA=y
@@ -104,6 +105,8 @@ CONFIG_MMC_SDHCI_S3C=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_EXYNOS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_S3C=y
 CONFIG_COMMON_CLK_MAX77686=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/imx_v6_v7_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/imx_v6_v7_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/imx_v6_v7_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/imx_v6_v7_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -37,6 +37,8 @@ CONFIG_MACH_IMX51_DT=y
 CONFIG_MACH_EUKREA_CPUIMX51SD=y
 CONFIG_SOC_IMX53=y
 CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_SOC_VF610=y
 CONFIG_MXC_PWM=y
 CONFIG_SMP=y
 CONFIG_VMSPLIT_2G=y
@@ -47,6 +49,7 @@ CONFIG_CMDLINE="noinitrd console=ttymxc0
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_BINFMT_MISC=m
+CONFIG_PM_RUNTIME=y
 CONFIG_PM_DEBUG=y
 CONFIG_PM_TEST_SUSPEND=y
 CONFIG_NET=y
@@ -170,6 +173,7 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_L4F00242T03=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
 CONFIG_FONTS=y
@@ -182,6 +186,7 @@ CONFIG_SND_SOC=y
 CONFIG_SND_IMX_SOC=y
 CONFIG_SND_SOC_PHYCORE_AC97=y
 CONFIG_SND_SOC_EUKREA_TLV320=y
+CONFIG_SND_SOC_IMX_WM8962=y
 CONFIG_SND_SOC_IMX_SGTL5000=y
 CONFIG_SND_SOC_IMX_MC13783=y
 CONFIG_USB=y
@@ -208,10 +213,15 @@ CONFIG_IMX_SDMA=y
 CONFIG_MXS_DMA=y
 CONFIG_STAGING=y
 CONFIG_DRM_IMX=y
+CONFIG_DRM_IMX_TVE=y
+CONFIG_DRM_IMX_FB_HELPER=y
+CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
 CONFIG_DRM_IMX_IPUV3_CORE=y
 CONFIG_DRM_IMX_IPUV3=y
 CONFIG_COMMON_CLK_DEBUG=y
 # CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_IMX=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/keystone_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/keystone_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/keystone_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/keystone_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,157 @@
+# CONFIG_SWAP is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_BASE_FULL is not set
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_ARCH_KEYSTONE=y
+CONFIG_ARM_LPAE=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE_DEMUX=y
+CONFIG_NET_IPGRE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_INET_AH=y
+CONFIG_INET_IPCOMP=y
+CONFIG_IPV6=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_CPU=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_ULOG=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_CLUSTERIP=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP_SCTP=y
+CONFIG_VLAN_8021Q=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_CMA=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_UBI=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_EEPROM_AT24=y
+CONFIG_NETDEVICES=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_SPIDEV=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_DMADEVICES=y
+CONFIG_COMMON_CLK_DEBUG=y
+CONFIG_MEMORY=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_UBIFS_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/kirkwood_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/kirkwood_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/kirkwood_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/kirkwood_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -31,6 +30,7 @@ CONFIG_MACH_T5325=y
 CONFIG_MACH_TS219=y
 CONFIG_MACH_TS41X=y
 CONFIG_MACH_CLOUDBOX_DT=y
+CONFIG_MACH_DB88F628X_BP_DT=y
 CONFIG_MACH_DLINK_KIRKWOOD_DT=y
 CONFIG_MACH_DOCKSTAR_DT=y
 CONFIG_MACH_DREAMPLUG_DT=y
@@ -50,14 +50,19 @@ CONFIG_MACH_NETSPACE_V2_DT=y
 CONFIG_MACH_NSA310_DT=y
 CONFIG_MACH_OPENBLOCKS_A6_DT=y
 CONFIG_MACH_READYNAS_DT=y
+CONFIG_MACH_SHEEVAPLUG_DT=y
 CONFIG_MACH_TOPKICK_DT=y
 CONFIG_MACH_TS219_DT=y
 # CONFIG_CPU_FEROCEON_OLD_ID is not set
+CONFIG_PCI_MVEBU=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -68,14 +73,12 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IPV6 is not set
-CONFIG_NET_DSA=y
 CONFIG_NET_PKTGEN=m
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_JEDECPROBE=y
@@ -140,6 +143,7 @@ CONFIG_HID_TOPSEED=y
 CONFIG_HID_THRUSTMASTER=y
 CONFIG_HID_ZEROPLUS=y
 CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_PRINTER=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/kzm9g_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/kzm9g_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/kzm9g_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/kzm9g_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -84,9 +84,12 @@ CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_SH_MOBILE=y
 CONFIG_GPIO_PCF857X=y
 # CONFIG_HWMON is not set
+CONFIG_MFD_AS3711=y
 CONFIG_REGULATOR=y
+CONFIG_REGULATOR_AS3711=y
 CONFIG_FB=y
 CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_BACKLIGHT_AS3711=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 CONFIG_FB_SH_MOBILE_MERAM=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/multi_v7_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/multi_v7_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/multi_v7_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/multi_v7_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,83 +1,171 @@
-CONFIG_EXPERIMENTAL=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_ARCH_MVEBU=y
 CONFIG_MACH_ARMADA_370=y
-CONFIG_ARCH_SIRF=y
 CONFIG_MACH_ARMADA_XP=y
+CONFIG_ARCH_BCM=y
+CONFIG_GPIO_PCA953X=y
 CONFIG_ARCH_HIGHBANK=y
+CONFIG_ARCH_KEYSTONE=y
+CONFIG_ARCH_MXC=y
+CONFIG_MACH_IMX51_DT=y
+CONFIG_SOC_IMX53=y
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_SOC_VF610=y
+CONFIG_ARCH_OMAP3=y
+CONFIG_ARCH_OMAP4=y
+CONFIG_SOC_OMAP5=y
+CONFIG_SOC_AM33XX=y
+CONFIG_SOC_AM43XX=y
+CONFIG_ARCH_ROCKCHIP=y
 CONFIG_ARCH_SOCFPGA=y
-CONFIG_ARCH_SUNXI=y
-CONFIG_ARCH_WM8850=y
-# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
-CONFIG_ARCH_ZYNQ=y
-CONFIG_ARM_ERRATA_754322=y
 CONFIG_PLAT_SPEAR=y
 CONFIG_ARCH_SPEAR13XX=y
 CONFIG_MACH_SPEAR1310=y
 CONFIG_MACH_SPEAR1340=y
+CONFIG_ARCH_STI=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_SIRF=y
+CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TEGRA_2x_SOC=y
+CONFIG_ARCH_TEGRA_3x_SOC=y
+CONFIG_ARCH_TEGRA_114_SOC=y
+CONFIG_TEGRA_PCI=y
+CONFIG_TEGRA_EMC_SCALING_ENABLE=y
+CONFIG_ARCH_U8500=y
+CONFIG_MACH_SNOWBALL=y
+CONFIG_MACH_UX500_DT=y
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_ARCH_VEXPRESS_CA9X4=y
+CONFIG_ARCH_VIRT=y
+CONFIG_ARCH_WM8850=y
+CONFIG_ARCH_ZYNQ=y
 CONFIG_SMP=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_AEABI=y
-CONFIG_HIGHMEM=y
 CONFIG_HIGHPTE=y
 CONFIG_ARM_APPENDED_DTB=y
-CONFIG_VFP=y
-CONFIG_NEON=y
 CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_OMAP_OCP2SCP=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
 CONFIG_SATA_HIGHBANK=y
 CONFIG_SATA_MV=y
-CONFIG_SATA_AHCI_PLATFORM=y
 CONFIG_NETDEVICES=y
+CONFIG_SUN4I_EMAC=y
 CONFIG_NET_CALXEDA_XGMAC=y
+CONFIG_KS8851=y
 CONFIG_SMSC911X=y
 CONFIG_STMMAC_ETH=y
+CONFIG_MDIO_SUN4I=y
+CONFIG_KEYBOARD_SPEAR=y
 CONFIG_SERIO_AMBAKMI=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_DW=y
-CONFIG_KEYBOARD_SPEAR=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_SIRFSOC=y
 CONFIG_SERIAL_SIRFSOC_CONSOLE=y
+CONFIG_SERIAL_TEGRA=y
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
 CONFIG_SERIAL_VT8500=y
 CONFIG_SERIAL_VT8500_CONSOLE=y
-CONFIG_IPMI_HANDLER=y
-CONFIG_IPMI_SI=y
-CONFIG_I2C=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
 CONFIG_I2C_DESIGNWARE_PLATFORM=y
 CONFIG_I2C_SIRF=y
+CONFIG_I2C_TEGRA=y
 CONFIG_SPI=y
+CONFIG_SPI_OMAP24XX=y
 CONFIG_SPI_PL022=y
 CONFIG_SPI_SIRF=y
-CONFIG_GPIO_PL061=y
-CONFIG_FB=y
+CONFIG_SPI_TEGRA114=y
+CONFIG_SPI_TEGRA20_SLINK=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_TWL4030=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_AB8500=y
+CONFIG_REGULATOR_TPS51632=y
+CONFIG_REGULATOR_TPS62360=y
+CONFIG_REGULATOR_TWL4030=y
+CONFIG_REGULATOR_VEXPRESS=y
+CONFIG_DRM=y
+CONFIG_TEGRA_HOST1X=y
+CONFIG_DRM_TEGRA=y
 CONFIG_FB_ARMCLCD=y
 CONFIG_FB_WM8505=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FB_SIMPLE=y
 CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_TEGRA=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
 CONFIG_USB_ISP1760_HCD=y
 CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_AB8500_USB=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_OMAP_USB2=y
+CONFIG_OMAP_USB3=y
+CONFIG_SAMSUNG_USB2PHY=y
+CONFIG_SAMSUNG_USB3PHY=y
+CONFIG_USB_GPIO_VBUS=y
+CONFIG_USB_ISP1301=y
+CONFIG_USB_MXS_PHY=y
 CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_TEGRA=y
 CONFIG_MMC_SDHCI_SPEAR=y
-CONFIG_MMC_WMT=y
+CONFIG_MMC_OMAP=y
+CONFIG_MMC_OMAP_HS=y
 CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
 CONFIG_EDAC_HIGHBANK_MC=y
 CONFIG_EDAC_HIGHBANK_L2=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_TWL4030=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_RTC_DRV_VT8500=y
-CONFIG_PWM=y
-CONFIG_PWM_VT8500=y
+CONFIG_RTC_DRV_TEGRA=y
 CONFIG_DMADEVICES=y
-CONFIG_PL330_DMA=y
-CONFIG_SIRF_DMA=y
 CONFIG_DW_DMAC=y
+CONFIG_TEGRA20_APB_DMA=y
+CONFIG_STE_DMA40=y
+CONFIG_SIRF_DMA=y
+CONFIG_TI_EDMA=y
+CONFIG_PL330_DMA=y
+CONFIG_IMX_SDMA=y
+CONFIG_IMX_DMA=y
+CONFIG_MXS_DMA=y
+CONFIG_DMA_OMAP=y
+CONFIG_PWM=y
+CONFIG_PWM_VT8500=y
+CONFIG_EXT4_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOCKUP_DETECTOR=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/mvebu_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/mvebu_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/mvebu_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/mvebu_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,8 @@ CONFIG_MACH_ARMADA_370=y
 CONFIG_MACH_ARMADA_XP=y
 # CONFIG_CACHE_L2X0 is not set
 # CONFIG_SWP_EMULATE is not set
+CONFIG_PCI=y
+CONFIG_PCI_MVEBU=y
 CONFIG_SMP=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
@@ -60,6 +62,8 @@ CONFIG_USB_SUPPORT=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_XHCI_HCD=y
 CONFIG_MMC=y
 CONFIG_MMC_MVSDIO=y
 CONFIG_NEW_LEDS=y
@@ -96,5 +100,3 @@ CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
-CONFIG_EARLY_PRINTK=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/nhk8815_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/nhk8815_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/nhk8815_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/nhk8815_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,8 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -48,7 +50,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_NAND_ECC_SMC=y
 CONFIG_MTD_NAND=y
@@ -81,6 +82,7 @@ CONFIG_PPP_SYNC_TTY=m
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_SERIO is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -93,9 +95,16 @@ CONFIG_I2C_GPIO=y
 CONFIG_I2C_NOMADIK=y
 CONFIG_DEBUG_GPIO=y
 # CONFIG_HWMON is not set
+CONFIG_REGULATOR=y
 CONFIG_MMC=y
-CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_DMADEVICES=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/omap1_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/omap1_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/omap1_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/omap1_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,8 @@ CONFIG_ARCH_OMAP=y
 CONFIG_ARCH_OMAP1=y
 CONFIG_OMAP_RESET_CLOCKS=y
 # CONFIG_OMAP_MUX is not set
-CONFIG_OMAP_MBOX_FWK=y
+CONFIG_MAILBOX=y
+CONFIG_OMAP1_MBOX=y
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_DM_TIMER=y
 CONFIG_ARCH_OMAP730=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/omap2plus_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/omap2plus_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/omap2plus_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/omap2plus_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,10 @@ CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_MULTI_V6=y
 CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_ARCH_OMAP2=y
+CONFIG_ARCH_OMAP3=y
+CONFIG_ARCH_OMAP4=y
+CONFIG_SOC_AM33XX=y
 CONFIG_OMAP_RESET_CLOCKS=y
 CONFIG_OMAP_MUX_DEBUG=y
 CONFIG_ARCH_VEXPRESS_CA9X4=y
@@ -34,6 +38,8 @@ CONFIG_NR_CPUS=2
 CONFIG_LEDS=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
 CONFIG_KEXEC=y
 CONFIG_FPE_NWFPE=y
@@ -152,6 +158,13 @@ CONFIG_W1=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_SENSORS_LM75=m
 CONFIG_WATCHDOG=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_FAIR_SHARE=y
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_CPU_THERMAL=y
 CONFIG_OMAP_WATCHDOG=y
 CONFIG_TWL4030_WATCHDOG=y
 CONFIG_MFD_TPS65217=y
@@ -210,6 +223,8 @@ CONFIG_USB_WDM=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_LIBUSUAL=y
 CONFIG_USB_TEST=y
+CONFIG_USB_PHY=y
+CONFIG_NOP_USB_XCEIV=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DEBUG=y
 CONFIG_USB_GADGET_DEBUG_FILES=y
@@ -236,7 +251,13 @@ CONFIG_RTC_DRV_TWL92330=y
 CONFIG_RTC_DRV_TWL4030=y
 CONFIG_RTC_DRV_OMAP=y
 CONFIG_DMADEVICES=y
+CONFIG_TI_EDMA=y
 CONFIG_DMA_OMAP=y
+CONFIG_TI_SOC_THERMAL=y
+CONFIG_TI_THERMAL=y
+CONFIG_OMAP4_THERMAL=y
+CONFIG_OMAP5_THERMAL=y
+CONFIG_DRA752_THERMAL=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
@@ -284,3 +305,4 @@ CONFIG_SOC_OMAP5=y
 CONFIG_TI_DAVINCI_MDIO=y
 CONFIG_TI_DAVINCI_CPDMA=y
 CONFIG_TI_CPSW=y
+CONFIG_AT803X_PHY=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/sama5_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/sama5_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/sama5_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/sama5_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,9 @@ CONFIG_AEABI=y
 CONFIG_UACCESS_WITH_MEMCPY=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
 CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
+CONFIG_KEXEC=y
 CONFIG_AUTO_ZRELADDR=y
 CONFIG_VFP=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
@@ -39,6 +41,9 @@ CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
@@ -68,6 +73,8 @@ CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ATMEL=y
 CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=4
@@ -95,7 +102,19 @@ CONFIG_MACB=y
 # CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_MICREL_PHY=y
-# CONFIG_WLAN is not set
+CONFIG_LIBERTAS_THINFIRM=m
+CONFIG_LIBERTAS_THINFIRM_USB=m
+CONFIG_RTL8187=m
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_RT2800USB=m
+CONFIG_RT2800USB_RT53XX=y
+CONFIG_RT2800USB_RT55XX=y
+CONFIG_RT2800USB_UNKNOWN=y
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_USB=m
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
@@ -133,9 +152,13 @@ CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_ACM=y
 CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_PL2303=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_AT91=y
-CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_ATMEL_USBA=y
+CONFIG_USB_G_SERIAL=y
 CONFIG_MMC=y
 # CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_ATMELMCI=y
@@ -151,18 +174,18 @@ CONFIG_DMADEVICES=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_IIO=y
 CONFIG_AT91_ADC=y
-CONFIG_EXT2_FS=y
+CONFIG_EXT4_FS=y
 CONFIG_FANOTIFY=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
 CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
 CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_850=y
 CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_FS=y
 # CONFIG_SCHED_DEBUG is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/spear13xx_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/spear13xx_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/spear13xx_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/spear13xx_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -61,7 +61,6 @@ CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PL061=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
-CONFIG_MPCORE_WATCHDOG=y
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB=y
 # CONFIG_USB_DEVICE_CLASS is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/tegra_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/tegra_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/tegra_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/tegra_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -21,8 +21,8 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_TEGRA=y
 CONFIG_GPIO_PCA953X=y
+CONFIG_ARCH_TEGRA=y
 CONFIG_ARCH_TEGRA_2x_SOC=y
 CONFIG_ARCH_TEGRA_3x_SOC=y
 CONFIG_ARCH_TEGRA_114_SOC=y
@@ -36,7 +36,6 @@ CONFIG_HIGHMEM=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_KEXEC=y
-CONFIG_AUTO_ZRELADDR=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
@@ -81,7 +80,6 @@ CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 CONFIG_CMA=y
 CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_M25P80=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
@@ -105,8 +103,8 @@ CONFIG_BRCMFMAC=m
 CONFIG_RT2X00=y
 CONFIG_RT2800USB=m
 CONFIG_INPUT_EVDEV=y
-CONFIG_KEYBOARD_TEGRA=y
 CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_TEGRA=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MPU3050=y
 # CONFIG_LEGACY_PTYS is not set
@@ -121,6 +119,7 @@ CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PINCTRL=y
 CONFIG_I2C_TEGRA=y
 CONFIG_SPI=y
+CONFIG_SPI_TEGRA114=y
 CONFIG_SPI_TEGRA20_SFLASH=y
 CONFIG_SPI_TEGRA20_SLINK=y
 CONFIG_GPIO_PCA953X_IRQ=y
@@ -129,14 +128,15 @@ CONFIG_GPIO_TPS6586X=y
 CONFIG_GPIO_TPS65910=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_BATTERY_SBS=y
+CONFIG_CHARGER_TPS65090=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_SENSORS_LM90=y
-CONFIG_MFD_TPS6586X=y
-CONFIG_MFD_TPS65910=y
 CONFIG_MFD_MAX8907=y
-CONFIG_MFD_TPS65090=y
 CONFIG_MFD_PALMAS=y
+CONFIG_MFD_TPS65090=y
+CONFIG_MFD_TPS6586X=y
+CONFIG_MFD_TPS65910=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
@@ -171,6 +171,7 @@ CONFIG_SND=y
 # CONFIG_SND_USB is not set
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_TEGRA=y
+CONFIG_SND_SOC_TEGRA_RT5640=y
 CONFIG_SND_SOC_TEGRA_WM8753=y
 CONFIG_SND_SOC_TEGRA_WM8903=y
 CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
@@ -190,7 +191,13 @@ CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=y
+CONFIG_LEDS_TRIGGER_CAMERA=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_MAX8907=y
 CONFIG_RTC_DRV_PALMAS=y
@@ -203,7 +210,6 @@ CONFIG_TEGRA20_APB_DMA=y
 CONFIG_STAGING=y
 CONFIG_SENSORS_ISL29018=y
 CONFIG_SENSORS_ISL29028=y
-CONFIG_AK8975=y
 CONFIG_MFD_NVEC=y
 CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
@@ -213,6 +219,7 @@ CONFIG_TEGRA_IOMMU_GART=y
 CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_MEMORY=y
 CONFIG_IIO=y
+CONFIG_AK8975=y
 CONFIG_PWM=y
 CONFIG_PWM_TEGRA=y
 CONFIG_EXT2_FS=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/u300_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/u300_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/u300_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/u300_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,8 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_EXPERT=y
 # CONFIG_AIO is not set
@@ -11,12 +12,9 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_CFQ is not set
+# CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_U300=y
-CONFIG_MACH_U300=y
-CONFIG_MACH_U300_BS335=y
 CONFIG_MACH_U300_SPIDUMMY=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -44,14 +42,15 @@ CONFIG_I2C=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_FB=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 # CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_MMC=y
-CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_ARMMMCI=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_HCTOSYS is not set
@@ -70,4 +69,3 @@ CONFIG_DEBUG_FS=y
 CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_PREEMPT is not set
 CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/configs/u8500_defconfig linux-libre-3.11-rc7-gnu/arch/arm/configs/u8500_defconfig
--- linux-libre-3.10-gnu/arch/arm/configs/u8500_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/configs/u8500_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,8 @@
-CONFIG_EXPERIMENTAL=y
+CONFIG_HIGHMEM=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_MODULES=y
@@ -9,10 +11,7 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_U8500=y
 CONFIG_MACH_HREFV60=y
 CONFIG_MACH_SNOWBALL=y
-CONFIG_MACH_U5500=y
 CONFIG_MACH_UX500_DT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_PREEMPT=y
@@ -20,6 +19,7 @@ CONFIG_AEABI=y
 CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8"
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_PM_RUNTIME=y
@@ -36,7 +36,6 @@ CONFIG_CAIF=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=65536
-CONFIG_AB8500_PWM=y
 CONFIG_SENSORS_BH1780=y
 CONFIG_NETDEVICES=y
 CONFIG_SMSC911X=y
@@ -60,35 +59,39 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_NOMADIK=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_GPIO_STMPE=y
 CONFIG_GPIO_TC3589X=y
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_AB8500_BM is not set
-# CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL is not set
 CONFIG_THERMAL=y
 CONFIG_CPU_THERMAL=y
+CONFIG_WATCHDOG=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_TC3589X=y
-CONFIG_AB5500_CORE=y
-CONFIG_AB8500_CORE=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_AB8500=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB_GADGET=y
+CONFIG_REGULATOR_AB8500=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_UX500=y
+CONFIG_SND_SOC_UX500_MACH_MOP500=y
+CONFIG_USB=y
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_UX500=y
+CONFIG_USB_PHY=y
 CONFIG_AB8500_USB=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_ETH=m
 CONFIG_MMC=y
-CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
 CONFIG_MMC_ARMMMCI=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_LM3530=y
-CONFIG_LEDS_LP5521=y
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_LP5521=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
@@ -108,7 +111,6 @@ CONFIG_EXT4_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_CONFIGFS_FS=m
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
@@ -122,3 +124,7 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_DEV_UX500=y
+CONFIG_CRYPTO_DEV_UX500_CRYP=y
+CONFIG_CRYPTO_DEV_UX500_HASH=y
+CONFIG_CRYPTO_DEV_UX500_DEBUG=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/a.out-core.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/a.out-core.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/a.out-core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/a.out-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/* a.out coredump register dumper
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#ifndef _ASM_A_OUT_CORE_H
-#define _ASM_A_OUT_CORE_H
-
-#ifdef __KERNEL__
-
-#include <linux/user.h>
-#include <linux/elfcore.h>
-
-/*
- * fill in the user structure for an a.out core dump
- */
-static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
-{
-	struct task_struct *tsk = current;
-
-	dump->magic = CMAGIC;
-	dump->start_code = tsk->mm->start_code;
-	dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
-
-	dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
-	dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	dump->u_ssize = 0;
-
-	memset(dump->u_debugreg, 0, sizeof(dump->u_debugreg));
-
-	if (dump->start_stack < 0x04000000)
-		dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
-
-	dump->regs = *regs;
-	dump->u_fpvalid = dump_fpu (regs, &dump->u_fp);
-}
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_A_OUT_CORE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/arch_timer.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/arch_timer.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/arch_timer.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/arch_timer.h	2013-08-25 20:43:22.000000000 -0400
@@ -80,15 +80,6 @@ static inline u32 arch_timer_get_cntfrq(
 	return val;
 }
 
-static inline u64 arch_counter_get_cntpct(void)
-{
-	u64 cval;
-
-	isb();
-	asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
-	return cval;
-}
-
 static inline u64 arch_counter_get_cntvct(void)
 {
 	u64 cval;
@@ -98,7 +89,7 @@ static inline u64 arch_counter_get_cntvc
 	return cval;
 }
 
-static inline void __cpuinit arch_counter_set_user_access(void)
+static inline void arch_counter_set_user_access(void)
 {
 	u32 cntkctl;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/assembler.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/assembler.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/assembler.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/assembler.h	2013-08-25 20:43:22.000000000 -0400
@@ -136,7 +136,11 @@
  * assumes FIQs are enabled, and that the processor is in SVC mode.
  */
 	.macro	save_and_disable_irqs, oldcpsr
+#ifdef CONFIG_CPU_V7M
+	mrs	\oldcpsr, primask
+#else
 	mrs	\oldcpsr, cpsr
+#endif
 	disable_irq
 	.endm
 
@@ -150,7 +154,11 @@
  * guarantee that this will preserve the flags.
  */
 	.macro	restore_irqs_notrace, oldcpsr
+#ifdef CONFIG_CPU_V7M
+	msr	primask, \oldcpsr
+#else
 	msr	cpsr_c, \oldcpsr
+#endif
 	.endm
 
 	.macro restore_irqs, oldcpsr
@@ -229,7 +237,14 @@
 #endif
 	.endm
 
-#ifdef CONFIG_THUMB2_KERNEL
+#if defined(CONFIG_CPU_V7M)
+	/*
+	 * setmode is used to assert to be in svc mode during boot. For v7-M
+	 * this is done in __v7m_setup, so setmode can be empty here.
+	 */
+	.macro	setmode, mode, reg
+	.endm
+#elif defined(CONFIG_THUMB2_KERNEL)
 	.macro	setmode, mode, reg
 	mov	\reg, #\mode
 	msr	cpsr_c, \reg
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/cp15.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/cp15.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/cp15.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/cp15.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,11 @@
 #define CR_RR	(1 << 14)	/* Round Robin cache replacement	*/
 #define CR_L4	(1 << 15)	/* LDR pc can set T bit			*/
 #define CR_DT	(1 << 16)
+#ifdef CONFIG_MMU
+#define CR_HA	(1 << 17)	/* Hardware management of Access Flag   */
+#else
+#define CR_BR	(1 << 17)	/* MPU Background region enable (PMSA)  */
+#endif
 #define CR_IT	(1 << 18)
 #define CR_ST	(1 << 19)
 #define CR_FI	(1 << 21)	/* Fast interrupt (lower latency mode)	*/
@@ -61,6 +66,20 @@ static inline void set_cr(unsigned int v
 	isb();
 }
 
+static inline unsigned int get_auxcr(void)
+{
+	unsigned int val;
+	asm("mrc p15, 0, %0, c1, c0, 1	@ get AUXCR" : "=r" (val));
+	return val;
+}
+
+static inline void set_auxcr(unsigned int val)
+{
+	asm volatile("mcr p15, 0, %0, c1, c0, 1	@ set AUXCR"
+	  : : "r" (val));
+	isb();
+}
+
 #ifndef CONFIG_SMP
 extern void adjust_cr(unsigned long mask, unsigned long set);
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/cputype.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/cputype.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/cputype.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/cputype.h	2013-08-25 20:43:22.000000000 -0400
@@ -8,8 +8,25 @@
 #define CPUID_CACHETYPE	1
 #define CPUID_TCM	2
 #define CPUID_TLBTYPE	3
+#define CPUID_MPUIR	4
 #define CPUID_MPIDR	5
 
+#ifdef CONFIG_CPU_V7M
+#define CPUID_EXT_PFR0	0x40
+#define CPUID_EXT_PFR1	0x44
+#define CPUID_EXT_DFR0	0x48
+#define CPUID_EXT_AFR0	0x4c
+#define CPUID_EXT_MMFR0	0x50
+#define CPUID_EXT_MMFR1	0x54
+#define CPUID_EXT_MMFR2	0x58
+#define CPUID_EXT_MMFR3	0x5c
+#define CPUID_EXT_ISAR0	0x60
+#define CPUID_EXT_ISAR1	0x64
+#define CPUID_EXT_ISAR2	0x68
+#define CPUID_EXT_ISAR3	0x6c
+#define CPUID_EXT_ISAR4	0x70
+#define CPUID_EXT_ISAR5	0x74
+#else
 #define CPUID_EXT_PFR0	"c1, 0"
 #define CPUID_EXT_PFR1	"c1, 1"
 #define CPUID_EXT_DFR0	"c1, 2"
@@ -24,6 +41,7 @@
 #define CPUID_EXT_ISAR3	"c2, 3"
 #define CPUID_EXT_ISAR4	"c2, 4"
 #define CPUID_EXT_ISAR5	"c2, 5"
+#endif
 
 #define MPIDR_SMP_BITMASK (0x3 << 30)
 #define MPIDR_SMP_VALUE (0x2 << 30)
@@ -71,17 +89,38 @@ extern unsigned int processor_id;
 		__val;							\
 	})
 
+/*
+ * The memory clobber prevents gcc 4.5 from reordering the mrc before
+ * any is_smp() tests, which can cause undefined instruction aborts on
+ * ARM1136 r0 due to the missing extended CP15 registers.
+ */
 #define read_cpuid_ext(ext_reg)						\
 	({								\
 		unsigned int __val;					\
 		asm("mrc	p15, 0, %0, c0, " ext_reg		\
 		    : "=r" (__val)					\
 		    :							\
-		    : "cc");						\
+		    : "memory");					\
 		__val;							\
 	})
 
-#else /* ifdef CONFIG_CPU_CP15 */
+#elif defined(CONFIG_CPU_V7M)
+
+#include <asm/io.h>
+#include <asm/v7m.h>
+
+#define read_cpuid(reg)							\
+	({								\
+		WARN_ON_ONCE(1);					\
+		0;							\
+	})
+
+static inline unsigned int __attribute_const__ read_cpuid_ext(unsigned offset)
+{
+	return readl(BASEADDR_V7M_SCB + offset);
+}
+
+#else /* ifdef CONFIG_CPU_CP15 / elif defined (CONFIG_CPU_V7M) */
 
 /*
  * read_cpuid and read_cpuid_ext should only ever be called on machines that
@@ -108,7 +147,14 @@ static inline unsigned int __attribute_c
 	return read_cpuid(CPUID_ID);
 }
 
-#else /* ifdef CONFIG_CPU_CP15 */
+#elif defined(CONFIG_CPU_V7M)
+
+static inline unsigned int __attribute_const__ read_cpuid_id(void)
+{
+	return readl(BASEADDR_V7M_SCB + V7M_SCB_CPUID);
+}
+
+#else /* ifdef CONFIG_CPU_CP15 / elif defined(CONFIG_CPU_V7M) */
 
 static inline unsigned int __attribute_const__ read_cpuid_id(void)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/div64.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/div64.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/div64.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/div64.h	2013-08-25 20:43:22.000000000 -0400
@@ -46,7 +46,7 @@
 	__rem;							\
 })
 
-#if __GNUC__ < 4
+#if __GNUC__ < 4 || !defined(CONFIG_AEABI)
 
 /*
  * gcc versions earlier than 4.0 are simply too problematic for the
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/elf.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/elf.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/elf.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/elf.h	2013-08-25 20:43:22.000000000 -0400
@@ -130,4 +130,10 @@ struct mm_struct;
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
+#ifdef CONFIG_MMU
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+int arch_setup_additional_pages(struct linux_binprm *, int);
+#endif
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/glue-cache.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/glue-cache.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/glue-cache.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/glue-cache.h	2013-08-25 20:43:22.000000000 -0400
@@ -117,10 +117,37 @@
 # endif
 #endif
 
+#if defined(CONFIG_CPU_V7M)
+# ifdef _CACHE
+#  define MULTI_CACHE 1
+# else
+#  define _CACHE nop
+# endif
+#endif
+
 #if !defined(_CACHE) && !defined(MULTI_CACHE)
 #error Unknown cache maintenance model
 #endif
 
+#ifndef __ASSEMBLER__
+extern inline void nop_flush_icache_all(void) { }
+extern inline void nop_flush_kern_cache_all(void) { }
+extern inline void nop_flush_kern_cache_louis(void) { }
+extern inline void nop_flush_user_cache_all(void) { }
+extern inline void nop_flush_user_cache_range(unsigned long a,
+		unsigned long b, unsigned int c) { }
+
+extern inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { }
+extern inline int nop_coherent_user_range(unsigned long a,
+		unsigned long b) { return 0; }
+extern inline void nop_flush_kern_dcache_area(void *a, size_t s) { }
+
+extern inline void nop_dma_flush_range(const void *a, const void *b) { }
+
+extern inline void nop_dma_map_area(const void *s, size_t l, int f) { }
+extern inline void nop_dma_unmap_area(const void *s, size_t l, int f) { }
+#endif
+
 #ifndef MULTI_CACHE
 #define __cpuc_flush_icache_all		__glue(_CACHE,_flush_icache_all)
 #define __cpuc_flush_kern_all		__glue(_CACHE,_flush_kern_cache_all)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/glue-df.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/glue-df.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/glue-df.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/glue-df.h	2013-08-25 20:43:22.000000000 -0400
@@ -95,6 +95,14 @@
 # endif
 #endif
 
+#ifdef CONFIG_CPU_ABRT_NOMMU
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER nommu_early_abort
+# endif
+#endif
+
 #ifndef CPU_DABORT_HANDLER
 #error Unknown data abort handler type
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/glue-proc.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/glue-proc.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/glue-proc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/glue-proc.h	2013-08-25 20:43:22.000000000 -0400
@@ -230,6 +230,15 @@
 # endif
 #endif
 
+#ifdef CONFIG_CPU_V7M
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_v7m
+# endif
+#endif
+
 #ifdef CONFIG_CPU_PJ4B
 # ifdef CPU_NAME
 #  undef  MULTI_CPU
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/hardware/iop3xx.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/hardware/iop3xx.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/hardware/iop3xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/hardware/iop3xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -223,11 +223,12 @@ extern int iop3xx_get_init_atu(void);
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
+#include <linux/reboot.h>
 
 void iop3xx_map_io(void);
 void iop_init_cp6_handler(void);
 void iop_init_time(unsigned long tickrate);
-void iop3xx_restart(char, const char *);
+void iop3xx_restart(enum reboot_mode, const char *);
 
 static inline u32 read_tmr0(void)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/hardware/pci_v3.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/hardware/pci_v3.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/hardware/pci_v3.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/hardware/pci_v3.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,186 +0,0 @@
-/*
- *  arch/arm/include/asm/hardware/pci_v3.h
- *
- *  Internal header file PCI V3 chip
- *
- *  Copyright (C) ARM Limited
- *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef ASM_ARM_HARDWARE_PCI_V3_H
-#define ASM_ARM_HARDWARE_PCI_V3_H
-
-/* -------------------------------------------------------------------------------
- *  V3 Local Bus to PCI Bridge definitions
- * -------------------------------------------------------------------------------
- *  Registers (these are taken from page 129 of the EPC User's Manual Rev 1.04
- *  All V3 register names are prefaced by V3_ to avoid clashing with any other
- *  PCI definitions.  Their names match the user's manual.
- * 
- *  I'm assuming that I20 is disabled.
- * 
- */
-#define V3_PCI_VENDOR                   0x00000000
-#define V3_PCI_DEVICE                   0x00000002
-#define V3_PCI_CMD                      0x00000004
-#define V3_PCI_STAT                     0x00000006
-#define V3_PCI_CC_REV                   0x00000008
-#define V3_PCI_HDR_CFG                  0x0000000C
-#define V3_PCI_IO_BASE                  0x00000010
-#define V3_PCI_BASE0                    0x00000014
-#define V3_PCI_BASE1                    0x00000018
-#define V3_PCI_SUB_VENDOR               0x0000002C
-#define V3_PCI_SUB_ID                   0x0000002E
-#define V3_PCI_ROM                      0x00000030
-#define V3_PCI_BPARAM                   0x0000003C
-#define V3_PCI_MAP0                     0x00000040
-#define V3_PCI_MAP1                     0x00000044
-#define V3_PCI_INT_STAT                 0x00000048
-#define V3_PCI_INT_CFG                  0x0000004C 
-#define V3_LB_BASE0                     0x00000054
-#define V3_LB_BASE1                     0x00000058
-#define V3_LB_MAP0                      0x0000005E
-#define V3_LB_MAP1                      0x00000062
-#define V3_LB_BASE2                     0x00000064
-#define V3_LB_MAP2                      0x00000066
-#define V3_LB_SIZE                      0x00000068
-#define V3_LB_IO_BASE                   0x0000006E
-#define V3_FIFO_CFG                     0x00000070
-#define V3_FIFO_PRIORITY                0x00000072
-#define V3_FIFO_STAT                    0x00000074
-#define V3_LB_ISTAT                     0x00000076
-#define V3_LB_IMASK                     0x00000077
-#define V3_SYSTEM                       0x00000078
-#define V3_LB_CFG                       0x0000007A
-#define V3_PCI_CFG                      0x0000007C
-#define V3_DMA_PCI_ADR0                 0x00000080
-#define V3_DMA_PCI_ADR1                 0x00000090
-#define V3_DMA_LOCAL_ADR0               0x00000084
-#define V3_DMA_LOCAL_ADR1               0x00000094
-#define V3_DMA_LENGTH0                  0x00000088
-#define V3_DMA_LENGTH1                  0x00000098
-#define V3_DMA_CSR0                     0x0000008B
-#define V3_DMA_CSR1                     0x0000009B
-#define V3_DMA_CTLB_ADR0                0x0000008C
-#define V3_DMA_CTLB_ADR1                0x0000009C
-#define V3_DMA_DELAY                    0x000000E0
-#define V3_MAIL_DATA                    0x000000C0
-#define V3_PCI_MAIL_IEWR                0x000000D0
-#define V3_PCI_MAIL_IERD                0x000000D2
-#define V3_LB_MAIL_IEWR                 0x000000D4
-#define V3_LB_MAIL_IERD                 0x000000D6
-#define V3_MAIL_WR_STAT                 0x000000D8
-#define V3_MAIL_RD_STAT                 0x000000DA
-#define V3_QBA_MAP                      0x000000DC
-
-/*  PCI COMMAND REGISTER bits
- */
-#define V3_COMMAND_M_FBB_EN             (1 << 9)
-#define V3_COMMAND_M_SERR_EN            (1 << 8)
-#define V3_COMMAND_M_PAR_EN             (1 << 6)
-#define V3_COMMAND_M_MASTER_EN          (1 << 2)
-#define V3_COMMAND_M_MEM_EN             (1 << 1)
-#define V3_COMMAND_M_IO_EN              (1 << 0)
-
-/*  SYSTEM REGISTER bits
- */
-#define V3_SYSTEM_M_RST_OUT             (1 << 15)
-#define V3_SYSTEM_M_LOCK                (1 << 14)
-
-/*  PCI_CFG bits
- */
-#define V3_PCI_CFG_M_I2O_EN		(1 << 15)
-#define V3_PCI_CFG_M_IO_REG_DIS		(1 << 14)
-#define V3_PCI_CFG_M_IO_DIS		(1 << 13)
-#define V3_PCI_CFG_M_EN3V		(1 << 12)
-#define V3_PCI_CFG_M_RETRY_EN           (1 << 10)
-#define V3_PCI_CFG_M_AD_LOW1            (1 << 9)
-#define V3_PCI_CFG_M_AD_LOW0            (1 << 8)
-
-/*  PCI_BASE register bits (PCI -> Local Bus)
- */
-#define V3_PCI_BASE_M_ADR_BASE          0xFFF00000
-#define V3_PCI_BASE_M_ADR_BASEL         0x000FFF00
-#define V3_PCI_BASE_M_PREFETCH          (1 << 3)
-#define V3_PCI_BASE_M_TYPE              (3 << 1)
-#define V3_PCI_BASE_M_IO                (1 << 0)
-
-/*  PCI MAP register bits (PCI -> Local bus)
- */
-#define V3_PCI_MAP_M_MAP_ADR            0xFFF00000
-#define V3_PCI_MAP_M_RD_POST_INH        (1 << 15)
-#define V3_PCI_MAP_M_ROM_SIZE           (3 << 10)
-#define V3_PCI_MAP_M_SWAP               (3 << 8)
-#define V3_PCI_MAP_M_ADR_SIZE           0x000000F0
-#define V3_PCI_MAP_M_REG_EN             (1 << 1)
-#define V3_PCI_MAP_M_ENABLE             (1 << 0)
-
-/*
- *  LB_BASE0,1 register bits (Local bus -> PCI)
- */
-#define V3_LB_BASE_ADR_BASE		0xfff00000
-#define V3_LB_BASE_SWAP			(3 << 8)
-#define V3_LB_BASE_ADR_SIZE		(15 << 4)
-#define V3_LB_BASE_PREFETCH		(1 << 3)
-#define V3_LB_BASE_ENABLE		(1 << 0)
-
-#define V3_LB_BASE_ADR_SIZE_1MB		(0 << 4)
-#define V3_LB_BASE_ADR_SIZE_2MB		(1 << 4)
-#define V3_LB_BASE_ADR_SIZE_4MB		(2 << 4)
-#define V3_LB_BASE_ADR_SIZE_8MB		(3 << 4)
-#define V3_LB_BASE_ADR_SIZE_16MB	(4 << 4)
-#define V3_LB_BASE_ADR_SIZE_32MB	(5 << 4)
-#define V3_LB_BASE_ADR_SIZE_64MB	(6 << 4)
-#define V3_LB_BASE_ADR_SIZE_128MB	(7 << 4)
-#define V3_LB_BASE_ADR_SIZE_256MB	(8 << 4)
-#define V3_LB_BASE_ADR_SIZE_512MB	(9 << 4)
-#define V3_LB_BASE_ADR_SIZE_1GB		(10 << 4)
-#define V3_LB_BASE_ADR_SIZE_2GB		(11 << 4)
-
-#define v3_addr_to_lb_base(a)	((a) & V3_LB_BASE_ADR_BASE)
-
-/*
- *  LB_MAP0,1 register bits (Local bus -> PCI)
- */
-#define V3_LB_MAP_MAP_ADR		0xfff0
-#define V3_LB_MAP_TYPE			(7 << 1)
-#define V3_LB_MAP_AD_LOW_EN		(1 << 0)
-
-#define V3_LB_MAP_TYPE_IACK		(0 << 1)
-#define V3_LB_MAP_TYPE_IO		(1 << 1)
-#define V3_LB_MAP_TYPE_MEM		(3 << 1)
-#define V3_LB_MAP_TYPE_CONFIG		(5 << 1)
-#define V3_LB_MAP_TYPE_MEM_MULTIPLE	(6 << 1)
-
-#define v3_addr_to_lb_map(a)	(((a) >> 16) & V3_LB_MAP_MAP_ADR)
-
-/*
- *  LB_BASE2 register bits (Local bus -> PCI IO)
- */
-#define V3_LB_BASE2_ADR_BASE		0xff00
-#define V3_LB_BASE2_SWAP		(3 << 6)
-#define V3_LB_BASE2_ENABLE		(1 << 0)
-
-#define v3_addr_to_lb_base2(a)	(((a) >> 16) & V3_LB_BASE2_ADR_BASE)
-
-/*
- *  LB_MAP2 register bits (Local bus -> PCI IO)
- */
-#define V3_LB_MAP2_MAP_ADR		0xff00
-
-#define v3_addr_to_lb_map2(a)	(((a) >> 16) & V3_LB_MAP2_MAP_ADR)
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/hugetlb-3level.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/hugetlb-3level.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/hugetlb-3level.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/hugetlb-3level.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/include/asm/hugetlb-3level.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_ARM_HUGETLB_3LEVEL_H
+#define _ASM_ARM_HUGETLB_3LEVEL_H
+
+
+/*
+ * If our huge pte is non-zero then mark the valid bit.
+ * This allows pte_present(huge_ptep_get(ptep)) to return true for non-zero
+ * ptes.
+ * (The valid bit is automatically cleared by set_pte_at for PROT_NONE ptes).
+ */
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+	pte_t retval = *ptep;
+	if (pte_val(retval))
+		pte_val(retval) |= L_PTE_VALID;
+	return retval;
+}
+
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+				   pte_t *ptep, pte_t pte)
+{
+	set_pte_at(mm, addr, ptep, pte);
+}
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+					 unsigned long addr, pte_t *ptep)
+{
+	ptep_clear_flush(vma, addr, ptep);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+					   unsigned long addr, pte_t *ptep)
+{
+	ptep_set_wrprotect(mm, addr, ptep);
+}
+
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+					    unsigned long addr, pte_t *ptep)
+{
+	return ptep_get_and_clear(mm, addr, ptep);
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+					     unsigned long addr, pte_t *ptep,
+					     pte_t pte, int dirty)
+{
+	return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+}
+
+#endif /* _ASM_ARM_HUGETLB_3LEVEL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/hugetlb.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/hugetlb.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/hugetlb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/hugetlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/include/asm/hugetlb.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_ARM_HUGETLB_H
+#define _ASM_ARM_HUGETLB_H
+
+#include <asm/page.h>
+#include <asm-generic/hugetlb.h>
+
+#include <asm/hugetlb-3level.h>
+
+static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
+					  unsigned long addr, unsigned long end,
+					  unsigned long floor,
+					  unsigned long ceiling)
+{
+	free_pgd_range(tlb, addr, end, floor, ceiling);
+}
+
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+					 unsigned long addr, unsigned long len)
+{
+	return 0;
+}
+
+static inline int prepare_hugepage_range(struct file *file,
+					 unsigned long addr, unsigned long len)
+{
+	struct hstate *h = hstate_file(file);
+	if (len & ~huge_page_mask(h))
+		return -EINVAL;
+	if (addr & ~huge_page_mask(h))
+		return -EINVAL;
+	return 0;
+}
+
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+}
+
+static inline int huge_pte_none(pte_t pte)
+{
+	return pte_none(pte);
+}
+
+static inline pte_t huge_pte_wrprotect(pte_t pte)
+{
+	return pte_wrprotect(pte);
+}
+
+static inline int arch_prepare_hugepage(struct page *page)
+{
+	return 0;
+}
+
+static inline void arch_release_hugepage(struct page *page)
+{
+}
+
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+	clear_bit(PG_dcache_clean, &page->flags);
+}
+
+#endif /* _ASM_ARM_HUGETLB_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/io.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/io.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/io.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/io.h	2013-08-25 20:43:22.000000000 -0400
@@ -130,16 +130,16 @@ static inline u32 __raw_readl(const vola
  */
 extern void __iomem *__arm_ioremap_pfn_caller(unsigned long, unsigned long,
 	size_t, unsigned int, void *);
-extern void __iomem *__arm_ioremap_caller(unsigned long, size_t, unsigned int,
+extern void __iomem *__arm_ioremap_caller(phys_addr_t, size_t, unsigned int,
 	void *);
 
 extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
-extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int);
-extern void __iomem *__arm_ioremap_exec(unsigned long, size_t, bool cached);
+extern void __iomem *__arm_ioremap(phys_addr_t, size_t, unsigned int);
+extern void __iomem *__arm_ioremap_exec(phys_addr_t, size_t, bool cached);
 extern void __iounmap(volatile void __iomem *addr);
 extern void __arm_iounmap(volatile void __iomem *addr);
 
-extern void __iomem * (*arch_ioremap_caller)(unsigned long, size_t,
+extern void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t,
 	unsigned int, void *);
 extern void (*arch_iounmap)(volatile void __iomem *);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/irqflags.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/irqflags.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/irqflags.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/irqflags.h	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,16 @@
 /*
  * CPU interrupt mask handling.
  */
+#ifdef CONFIG_CPU_V7M
+#define IRQMASK_REG_NAME_R "primask"
+#define IRQMASK_REG_NAME_W "primask"
+#define IRQMASK_I_BIT	1
+#else
+#define IRQMASK_REG_NAME_R "cpsr"
+#define IRQMASK_REG_NAME_W "cpsr_c"
+#define IRQMASK_I_BIT	PSR_I_BIT
+#endif
+
 #if __LINUX_ARM_ARCH__ >= 6
 
 static inline unsigned long arch_local_irq_save(void)
@@ -15,7 +25,7 @@ static inline unsigned long arch_local_i
 	unsigned long flags;
 
 	asm volatile(
-		"	mrs	%0, cpsr	@ arch_local_irq_save\n"
+		"	mrs	%0, " IRQMASK_REG_NAME_R "	@ arch_local_irq_save\n"
 		"	cpsid	i"
 		: "=r" (flags) : : "memory", "cc");
 	return flags;
@@ -129,7 +139,7 @@ static inline unsigned long arch_local_s
 {
 	unsigned long flags;
 	asm volatile(
-		"	mrs	%0, cpsr	@ local_save_flags"
+		"	mrs	%0, " IRQMASK_REG_NAME_R "	@ local_save_flags"
 		: "=r" (flags) : : "memory", "cc");
 	return flags;
 }
@@ -140,7 +150,7 @@ static inline unsigned long arch_local_s
 static inline void arch_local_irq_restore(unsigned long flags)
 {
 	asm volatile(
-		"	msr	cpsr_c, %0	@ local_irq_restore"
+		"	msr	" IRQMASK_REG_NAME_W ", %0	@ local_irq_restore"
 		:
 		: "r" (flags)
 		: "memory", "cc");
@@ -148,8 +158,8 @@ static inline void arch_local_irq_restor
 
 static inline int arch_irqs_disabled_flags(unsigned long flags)
 {
-	return flags & PSR_I_BIT;
+	return flags & IRQMASK_I_BIT;
 }
 
-#endif
-#endif
+#endif /* ifdef __KERNEL__ */
+#endif /* ifndef __ASM_ARM_IRQFLAGS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/kvm_arch_timer.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_arch_timer.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/kvm_arch_timer.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_arch_timer.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Ltd.
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __ASM_ARM_KVM_ARCH_TIMER_H
-#define __ASM_ARM_KVM_ARCH_TIMER_H
-
-#include <linux/clocksource.h>
-#include <linux/hrtimer.h>
-#include <linux/workqueue.h>
-
-struct arch_timer_kvm {
-#ifdef CONFIG_KVM_ARM_TIMER
-	/* Is the timer enabled */
-	bool			enabled;
-
-	/* Virtual offset */
-	cycle_t			cntvoff;
-#endif
-};
-
-struct arch_timer_cpu {
-#ifdef CONFIG_KVM_ARM_TIMER
-	/* Registers: control register, timer value */
-	u32				cntv_ctl;	/* Saved/restored */
-	cycle_t				cntv_cval;	/* Saved/restored */
-
-	/*
-	 * Anything that is not used directly from assembly code goes
-	 * here.
-	 */
-
-	/* Background timer used when the guest is not running */
-	struct hrtimer			timer;
-
-	/* Work queued with the above timer expires */
-	struct work_struct		expired;
-
-	/* Background timer active */
-	bool				armed;
-
-	/* Timer IRQ */
-	const struct kvm_irq_level	*irq;
-#endif
-};
-
-#ifdef CONFIG_KVM_ARM_TIMER
-int kvm_timer_hyp_init(void);
-int kvm_timer_init(struct kvm *kvm);
-void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
-void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu);
-void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
-void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu);
-#else
-static inline int kvm_timer_hyp_init(void)
-{
-	return 0;
-};
-
-static inline int kvm_timer_init(struct kvm *kvm)
-{
-	return 0;
-}
-
-static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {}
-static inline void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) {}
-static inline void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) {}
-static inline void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) {}
-#endif
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/kvm_arm.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_arm.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/kvm_arm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_arm.h	2013-08-25 20:43:22.000000000 -0400
@@ -135,7 +135,6 @@
 #define KVM_PHYS_MASK	(KVM_PHYS_SIZE - 1ULL)
 #define PTRS_PER_S2_PGD	(1ULL << (KVM_PHYS_SHIFT - 30))
 #define S2_PGD_ORDER	get_order(PTRS_PER_S2_PGD * sizeof(pgd_t))
-#define S2_PGD_SIZE	(1 << S2_PGD_ORDER)
 
 /* Virtualization Translation Control Register (VTCR) bits */
 #define VTCR_SH0	(3 << 12)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/kvm_asm.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_asm.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/kvm_asm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_asm.h	2013-08-25 20:43:22.000000000 -0400
@@ -37,16 +37,18 @@
 #define c5_AIFSR	15	/* Auxilary Instrunction Fault Status R */
 #define c6_DFAR		16	/* Data Fault Address Register */
 #define c6_IFAR		17	/* Instruction Fault Address Register */
-#define c9_L2CTLR	18	/* Cortex A15 L2 Control Register */
-#define c10_PRRR	19	/* Primary Region Remap Register */
-#define c10_NMRR	20	/* Normal Memory Remap Register */
-#define c12_VBAR	21	/* Vector Base Address Register */
-#define c13_CID		22	/* Context ID Register */
-#define c13_TID_URW	23	/* Thread ID, User R/W */
-#define c13_TID_URO	24	/* Thread ID, User R/O */
-#define c13_TID_PRIV	25	/* Thread ID, Privileged */
-#define c14_CNTKCTL	26	/* Timer Control Register (PL1) */
-#define NR_CP15_REGS	27	/* Number of regs (incl. invalid) */
+#define c7_PAR		18	/* Physical Address Register */
+#define c7_PAR_high	19	/* PAR top 32 bits */
+#define c9_L2CTLR	20	/* Cortex A15 L2 Control Register */
+#define c10_PRRR	21	/* Primary Region Remap Register */
+#define c10_NMRR	22	/* Normal Memory Remap Register */
+#define c12_VBAR	23	/* Vector Base Address Register */
+#define c13_CID		24	/* Context ID Register */
+#define c13_TID_URW	25	/* Thread ID, User R/W */
+#define c13_TID_URO	26	/* Thread ID, User R/O */
+#define c13_TID_PRIV	27	/* Thread ID, Privileged */
+#define c14_CNTKCTL	28	/* Timer Control Register (PL1) */
+#define NR_CP15_REGS	29	/* Number of regs (incl. invalid) */
 
 #define ARM_EXCEPTION_RESET	  0
 #define ARM_EXCEPTION_UNDEFINED   1
@@ -72,8 +74,6 @@ extern char __kvm_hyp_vector[];
 extern char __kvm_hyp_code_start[];
 extern char __kvm_hyp_code_end[];
 
-extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
-
 extern void __kvm_flush_vm_context(void);
 extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/kvm_emulate.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_emulate.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/kvm_emulate.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_emulate.h	2013-08-25 20:43:22.000000000 -0400
@@ -65,11 +65,6 @@ static inline bool vcpu_mode_priv(struct
 	return cpsr_mode > USR_MODE;;
 }
 
-static inline bool kvm_vcpu_reg_is_pc(struct kvm_vcpu *vcpu, int reg)
-{
-	return reg == 15;
-}
-
 static inline u32 kvm_vcpu_get_hsr(struct kvm_vcpu *vcpu)
 {
 	return vcpu->arch.fault.hsr;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/kvm_host.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_host.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/kvm_host.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_host.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,9 +23,14 @@
 #include <asm/kvm_asm.h>
 #include <asm/kvm_mmio.h>
 #include <asm/fpstate.h>
-#include <asm/kvm_arch_timer.h>
+#include <kvm/arm_arch_timer.h>
 
+#if defined(CONFIG_KVM_ARM_MAX_VCPUS)
 #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS
+#else
+#define KVM_MAX_VCPUS 0
+#endif
+
 #define KVM_USER_MEM_SLOTS 32
 #define KVM_PRIVATE_MEM_SLOTS 4
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
@@ -38,7 +43,7 @@
 #define KVM_NR_PAGE_SIZES	1
 #define KVM_PAGES_PER_HPAGE(x)	(1UL<<31)
 
-#include <asm/kvm_vgic.h>
+#include <kvm/arm_vgic.h>
 
 struct kvm_vcpu;
 u32 *kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode);
@@ -190,8 +195,8 @@ int kvm_arm_coproc_set_reg(struct kvm_vc
 int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
 		int exception_index);
 
-static inline void __cpu_init_hyp_mode(unsigned long long boot_pgd_ptr,
-				       unsigned long long pgd_ptr,
+static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
+				       phys_addr_t pgd_ptr,
 				       unsigned long hyp_stack_ptr,
 				       unsigned long vector_ptr)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/kvm_vgic.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_vgic.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/kvm_vgic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/kvm_vgic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Ltd.
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __ASM_ARM_KVM_VGIC_H
-#define __ASM_ARM_KVM_VGIC_H
-
-#include <linux/kernel.h>
-#include <linux/kvm.h>
-#include <linux/irqreturn.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/irqchip/arm-gic.h>
-
-#define VGIC_NR_IRQS		128
-#define VGIC_NR_SGIS		16
-#define VGIC_NR_PPIS		16
-#define VGIC_NR_PRIVATE_IRQS	(VGIC_NR_SGIS + VGIC_NR_PPIS)
-#define VGIC_NR_SHARED_IRQS	(VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS)
-#define VGIC_MAX_CPUS		KVM_MAX_VCPUS
-#define VGIC_MAX_LRS		(1 << 6)
-
-/* Sanity checks... */
-#if (VGIC_MAX_CPUS > 8)
-#error	Invalid number of CPU interfaces
-#endif
-
-#if (VGIC_NR_IRQS & 31)
-#error "VGIC_NR_IRQS must be a multiple of 32"
-#endif
-
-#if (VGIC_NR_IRQS > 1024)
-#error "VGIC_NR_IRQS must be <= 1024"
-#endif
-
-/*
- * The GIC distributor registers describing interrupts have two parts:
- * - 32 per-CPU interrupts (SGI + PPI)
- * - a bunch of shared interrupts (SPI)
- */
-struct vgic_bitmap {
-	union {
-		u32 reg[VGIC_NR_PRIVATE_IRQS / 32];
-		DECLARE_BITMAP(reg_ul, VGIC_NR_PRIVATE_IRQS);
-	} percpu[VGIC_MAX_CPUS];
-	union {
-		u32 reg[VGIC_NR_SHARED_IRQS / 32];
-		DECLARE_BITMAP(reg_ul, VGIC_NR_SHARED_IRQS);
-	} shared;
-};
-
-struct vgic_bytemap {
-	u32 percpu[VGIC_MAX_CPUS][VGIC_NR_PRIVATE_IRQS / 4];
-	u32 shared[VGIC_NR_SHARED_IRQS  / 4];
-};
-
-struct vgic_dist {
-#ifdef CONFIG_KVM_ARM_VGIC
-	spinlock_t		lock;
-	bool			ready;
-
-	/* Virtual control interface mapping */
-	void __iomem		*vctrl_base;
-
-	/* Distributor and vcpu interface mapping in the guest */
-	phys_addr_t		vgic_dist_base;
-	phys_addr_t		vgic_cpu_base;
-
-	/* Distributor enabled */
-	u32			enabled;
-
-	/* Interrupt enabled (one bit per IRQ) */
-	struct vgic_bitmap	irq_enabled;
-
-	/* Interrupt 'pin' level */
-	struct vgic_bitmap	irq_state;
-
-	/* Level-triggered interrupt in progress */
-	struct vgic_bitmap	irq_active;
-
-	/* Interrupt priority. Not used yet. */
-	struct vgic_bytemap	irq_priority;
-
-	/* Level/edge triggered */
-	struct vgic_bitmap	irq_cfg;
-
-	/* Source CPU per SGI and target CPU */
-	u8			irq_sgi_sources[VGIC_MAX_CPUS][VGIC_NR_SGIS];
-
-	/* Target CPU for each IRQ */
-	u8			irq_spi_cpu[VGIC_NR_SHARED_IRQS];
-	struct vgic_bitmap	irq_spi_target[VGIC_MAX_CPUS];
-
-	/* Bitmap indicating which CPU has something pending */
-	unsigned long		irq_pending_on_cpu;
-#endif
-};
-
-struct vgic_cpu {
-#ifdef CONFIG_KVM_ARM_VGIC
-	/* per IRQ to LR mapping */
-	u8		vgic_irq_lr_map[VGIC_NR_IRQS];
-
-	/* Pending interrupts on this VCPU */
-	DECLARE_BITMAP(	pending_percpu, VGIC_NR_PRIVATE_IRQS);
-	DECLARE_BITMAP(	pending_shared, VGIC_NR_SHARED_IRQS);
-
-	/* Bitmap of used/free list registers */
-	DECLARE_BITMAP(	lr_used, VGIC_MAX_LRS);
-
-	/* Number of list registers on this CPU */
-	int		nr_lr;
-
-	/* CPU vif control registers for world switch */
-	u32		vgic_hcr;
-	u32		vgic_vmcr;
-	u32		vgic_misr;	/* Saved only */
-	u32		vgic_eisr[2];	/* Saved only */
-	u32		vgic_elrsr[2];	/* Saved only */
-	u32		vgic_apr;
-	u32		vgic_lr[VGIC_MAX_LRS];
-#endif
-};
-
-#define LR_EMPTY	0xff
-
-struct kvm;
-struct kvm_vcpu;
-struct kvm_run;
-struct kvm_exit_mmio;
-
-#ifdef CONFIG_KVM_ARM_VGIC
-int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr);
-int kvm_vgic_hyp_init(void);
-int kvm_vgic_init(struct kvm *kvm);
-int kvm_vgic_create(struct kvm *kvm);
-int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu);
-void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
-void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
-int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
-			bool level);
-int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
-bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
-		      struct kvm_exit_mmio *mmio);
-
-#define irqchip_in_kernel(k)	(!!((k)->arch.vgic.vctrl_base))
-#define vgic_initialized(k)	((k)->arch.vgic.ready)
-
-#else
-static inline int kvm_vgic_hyp_init(void)
-{
-	return 0;
-}
-
-static inline int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr)
-{
-	return 0;
-}
-
-static inline int kvm_vgic_init(struct kvm *kvm)
-{
-	return 0;
-}
-
-static inline int kvm_vgic_create(struct kvm *kvm)
-{
-	return 0;
-}
-
-static inline int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
-{
-	return 0;
-}
-
-static inline void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) {}
-static inline void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) {}
-
-static inline int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid,
-				      unsigned int irq_num, bool level)
-{
-	return 0;
-}
-
-static inline int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
-{
-	return 0;
-}
-
-static inline bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
-				    struct kvm_exit_mmio *mmio)
-{
-	return false;
-}
-
-static inline int irqchip_in_kernel(struct kvm *kvm)
-{
-	return 0;
-}
-
-static inline bool vgic_initialized(struct kvm *kvm)
-{
-	return true;
-}
-#endif
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/mach/arch.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mach/arch.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/mach/arch.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mach/arch.h	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,10 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/types.h>
+
 #ifndef __ASSEMBLY__
+#include <linux/reboot.h>
 
 struct tag;
 struct meminfo;
@@ -16,8 +19,10 @@ struct pt_regs;
 struct smp_operations;
 #ifdef CONFIG_SMP
 #define smp_ops(ops) (&(ops))
+#define smp_init_ops(ops) (&(ops))
 #else
 #define smp_ops(ops) (struct smp_operations *)NULL
+#define smp_init_ops(ops) (bool (*)(void))NULL
 #endif
 
 struct machine_desc {
@@ -39,8 +44,9 @@ struct machine_desc {
 	unsigned char		reserve_lp0 :1;	/* never has lp0	*/
 	unsigned char		reserve_lp1 :1;	/* never has lp1	*/
 	unsigned char		reserve_lp2 :1;	/* never has lp2	*/
-	char			restart_mode;	/* default restart mode	*/
+	enum reboot_mode	reboot_mode;	/* default restart mode	*/
 	struct smp_operations	*smp;		/* SMP operations	*/
+	bool			(*smp_init)(void);
 	void			(*fixup)(struct tag *, char **,
 					 struct meminfo *);
 	void			(*reserve)(void);/* reserve mem blocks	*/
@@ -53,7 +59,7 @@ struct machine_desc {
 #ifdef CONFIG_MULTI_IRQ_HANDLER
 	void			(*handle_irq)(struct pt_regs *);
 #endif
-	void			(*restart)(char, const char *);
+	void			(*restart)(enum reboot_mode, const char *);
 };
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/mach/pci.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mach/pci.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/mach/pci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mach/pci.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,7 @@
 struct pci_sys_data;
 struct pci_ops;
 struct pci_bus;
+struct device;
 
 struct hw_pci {
 #ifdef CONFIG_PCI_DOMAINS
@@ -68,7 +69,16 @@ struct pci_sys_data {
 /*
  * Call this with your hw_pci struct to initialise the PCI system.
  */
-void pci_common_init(struct hw_pci *);
+void pci_common_init_dev(struct device *, struct hw_pci *);
+
+/*
+ * Compatibility wrapper for older platforms that do not care about
+ * passing the parent device.
+ */
+static inline void pci_common_init(struct hw_pci *hw)
+{
+	pci_common_init_dev(NULL, hw);
+}
 
 /*
  * Setup early fixed I/O mapping.
@@ -96,9 +106,4 @@ extern struct pci_ops via82c505_ops;
 extern int via82c505_setup(int nr, struct pci_sys_data *);
 extern void via82c505_init(void *sysdata);
 
-extern struct pci_ops pci_v3_ops;
-extern int pci_v3_setup(int nr, struct pci_sys_data *);
-extern void pci_v3_preinit(void);
-extern void pci_v3_postinit(void);
-
 #endif /* __ASM_MACH_PCI_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/memory.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/memory.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/memory.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/memory.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,8 @@
 #include <linux/types.h>
 #include <linux/sizes.h>
 
+#include <asm/cache.h>
+
 #ifdef CONFIG_NEED_MACH_MEMORY_H
 #include <mach/memory.h>
 #endif
@@ -141,6 +143,20 @@
 #define page_to_phys(page)	(__pfn_to_phys(page_to_pfn(page)))
 #define phys_to_page(phys)	(pfn_to_page(__phys_to_pfn(phys)))
 
+/*
+ * Minimum guaranted alignment in pgd_alloc().  The page table pointers passed
+ * around in head.S and proc-*.S are shifted by this amount, in order to
+ * leave spare high bits for systems with physical address extension.  This
+ * does not fully accomodate the 40-bit addressing capability of ARM LPAE, but
+ * gives us about 38-bits or so.
+ */
+#ifdef CONFIG_ARM_LPAE
+#define ARCH_PGD_SHIFT		L1_CACHE_SHIFT
+#else
+#define ARCH_PGD_SHIFT		0
+#endif
+#define ARCH_PGD_MASK		((1 << ARCH_PGD_SHIFT) - 1)
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -207,7 +223,7 @@ static inline unsigned long __phys_to_vi
  * direct-mapped view.  We assume this is the first page
  * of RAM in the mem_map as well.
  */
-#define PHYS_PFN_OFFSET	(PHYS_OFFSET >> PAGE_SHIFT)
+#define PHYS_PFN_OFFSET	((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))
 
 /*
  * These are *only* valid on the kernel direct mapped RAM memory.
@@ -260,12 +276,6 @@ static inline __deprecated void *bus_to_
 /*
  * Conversion between a struct page and a physical address.
  *
- * Note: when converting an unknown physical address to a
- * struct page, the resulting pointer must be validated
- * using VALID_PAGE().  It must return an invalid struct page
- * for any physical address not corresponding to a system
- * RAM address.
- *
  *  page_to_pfn(page)	convert a struct page * to a PFN number
  *  pfn_to_page(pfn)	convert a _valid_ PFN number to struct page *
  *
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/mmu_context.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mmu_context.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/mmu_context.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mmu_context.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
 #include <asm/proc-fns.h>
+#include <asm/smp_plat.h>
 #include <asm-generic/mm_hooks.h>
 
 void __check_vmalloc_seq(struct mm_struct *mm);
@@ -27,7 +28,15 @@ void __check_vmalloc_seq(struct mm_struc
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
 #define init_new_context(tsk,mm)	({ atomic64_set(&mm->context.id, 0); 0; })
 
-DECLARE_PER_CPU(atomic64_t, active_asids);
+#ifdef CONFIG_ARM_ERRATA_798181
+void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
+			     cpumask_t *mask);
+#else  /* !CONFIG_ARM_ERRATA_798181 */
+static inline void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
+					   cpumask_t *mask)
+{
+}
+#endif /* CONFIG_ARM_ERRATA_798181 */
 
 #else	/* !CONFIG_CPU_HAS_ASID */
 
@@ -47,7 +56,7 @@ static inline void check_and_switch_cont
 		 * on non-ASID CPUs, the old mm will remain valid until the
 		 * finish_arch_post_lock_switch() call.
 		 */
-		set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM);
+		mm->context.switch_pending = 1;
 	else
 		cpu_switch_mm(mm->pgd, mm);
 }
@@ -56,9 +65,21 @@ static inline void check_and_switch_cont
 	finish_arch_post_lock_switch
 static inline void finish_arch_post_lock_switch(void)
 {
-	if (test_and_clear_thread_flag(TIF_SWITCH_MM)) {
-		struct mm_struct *mm = current->mm;
-		cpu_switch_mm(mm->pgd, mm);
+	struct mm_struct *mm = current->mm;
+
+	if (mm && mm->context.switch_pending) {
+		/*
+		 * Preemption must be disabled during cpu_switch_mm() as we
+		 * have some stateful cache flush implementations. Check
+		 * switch_pending again in case we were preempted and the
+		 * switch to this mm was already done.
+		 */
+		preempt_disable();
+		if (mm->context.switch_pending) {
+			mm->context.switch_pending = 0;
+			cpu_switch_mm(mm->pgd, mm);
+		}
+		preempt_enable_no_resched();
 	}
 }
 
@@ -98,12 +119,16 @@ switch_mm(struct mm_struct *prev, struct
 #ifdef CONFIG_MMU
 	unsigned int cpu = smp_processor_id();
 
-#ifdef CONFIG_SMP
-	/* check for possible thread migration */
-	if (!cpumask_empty(mm_cpumask(next)) &&
+	/*
+	 * __sync_icache_dcache doesn't broadcast the I-cache invalidation,
+	 * so check for possible thread migration and invalidate the I-cache
+	 * if we're new to this CPU.
+	 */
+	if (cache_ops_need_broadcast() &&
+	    !cpumask_empty(mm_cpumask(next)) &&
 	    !cpumask_test_cpu(cpu, mm_cpumask(next)))
 		__flush_icache_all();
-#endif
+
 	if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
 		check_and_switch_context(next, tsk);
 		if (cache_is_vivt())
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/mmu.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mmu.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/mmu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mmu.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,8 +6,11 @@
 typedef struct {
 #ifdef CONFIG_CPU_HAS_ASID
 	atomic64_t	id;
+#else
+	int		switch_pending;
 #endif
 	unsigned int	vmalloc_seq;
+	unsigned long	sigpage;
 } mm_context_t;
 
 #ifdef CONFIG_CPU_HAS_ASID
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/mpu.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mpu.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/mpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/mpu.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,76 @@
+#ifndef __ARM_MPU_H
+#define __ARM_MPU_H
+
+#ifdef CONFIG_ARM_MPU
+
+/* MPUIR layout */
+#define MPUIR_nU		1
+#define MPUIR_DREGION		8
+#define MPUIR_IREGION		16
+#define MPUIR_DREGION_SZMASK	(0xFF << MPUIR_DREGION)
+#define MPUIR_IREGION_SZMASK	(0xFF << MPUIR_IREGION)
+
+/* ID_MMFR0 data relevant to MPU */
+#define MMFR0_PMSA		(0xF << 4)
+#define MMFR0_PMSAv7		(3 << 4)
+
+/* MPU D/I Size Register fields */
+#define MPU_RSR_SZ		1
+#define MPU_RSR_EN		0
+
+/* The D/I RSR value for an enabled region spanning the whole of memory */
+#define MPU_RSR_ALL_MEM		63
+
+/* Individual bits in the DR/IR ACR */
+#define MPU_ACR_XN		(1 << 12)
+#define MPU_ACR_SHARED		(1 << 2)
+
+/* C, B and TEX[2:0] bits only have semantic meanings when grouped */
+#define MPU_RGN_CACHEABLE	0xB
+#define MPU_RGN_SHARED_CACHEABLE (MPU_RGN_CACHEABLE | MPU_ACR_SHARED)
+#define MPU_RGN_STRONGLY_ORDERED 0
+
+/* Main region should only be shared for SMP */
+#ifdef CONFIG_SMP
+#define MPU_RGN_NORMAL		(MPU_RGN_CACHEABLE | MPU_ACR_SHARED)
+#else
+#define MPU_RGN_NORMAL		MPU_RGN_CACHEABLE
+#endif
+
+/* Access permission bits of ACR (only define those that we use)*/
+#define MPU_AP_PL1RW_PL0RW	(0x3 << 8)
+#define MPU_AP_PL1RW_PL0R0	(0x2 << 8)
+#define MPU_AP_PL1RW_PL0NA	(0x1 << 8)
+
+/* For minimal static MPU region configurations */
+#define MPU_PROBE_REGION	0
+#define MPU_BG_REGION		1
+#define MPU_RAM_REGION		2
+#define MPU_VECTORS_REGION	3
+
+/* Maximum number of regions Linux is interested in */
+#define MPU_MAX_REGIONS		16
+
+#define MPU_DATA_SIDE		0
+#define MPU_INSTR_SIDE		1
+
+#ifndef __ASSEMBLY__
+
+struct mpu_rgn {
+	/* Assume same attributes for d/i-side  */
+	u32 drbar;
+	u32 drsr;
+	u32 dracr;
+};
+
+struct mpu_rgn_info {
+	u32 mpuir;
+	struct mpu_rgn rgns[MPU_MAX_REGIONS];
+};
+extern struct mpu_rgn_info mpu_rgn_info;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_ARM_MPU */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/page.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/page.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/page.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/page.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT		12
 #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK		(~(PAGE_SIZE-1))
+#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))
 
 #ifndef __ASSEMBLY__
 
@@ -142,7 +142,9 @@ extern void __cpu_copy_user_highpage(str
 #define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, const void *from);
 
+#ifdef CONFIG_KUSER_HELPERS
 #define __HAVE_ARCH_GATE_AREA 1
+#endif
 
 #ifdef CONFIG_ARM_LPAE
 #include <asm/pgtable-3level-types.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/pgtable-3level.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/pgtable-3level.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/pgtable-3level.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/pgtable-3level.h	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,7 @@
 #define PTRS_PER_PMD		512
 #define PTRS_PER_PGD		4
 
-#define PTE_HWTABLE_PTRS	(PTRS_PER_PTE)
+#define PTE_HWTABLE_PTRS	(0)
 #define PTE_HWTABLE_OFF		(0)
 #define PTE_HWTABLE_SIZE	(PTRS_PER_PTE * sizeof(u64))
 
@@ -48,20 +48,28 @@
 #define PMD_SHIFT		21
 
 #define PMD_SIZE		(1UL << PMD_SHIFT)
-#define PMD_MASK		(~(PMD_SIZE-1))
+#define PMD_MASK		(~((1 << PMD_SHIFT) - 1))
 #define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
-#define PGDIR_MASK		(~(PGDIR_SIZE-1))
+#define PGDIR_MASK		(~((1 << PGDIR_SHIFT) - 1))
 
 /*
  * section address mask and size definitions.
  */
 #define SECTION_SHIFT		21
 #define SECTION_SIZE		(1UL << SECTION_SHIFT)
-#define SECTION_MASK		(~(SECTION_SIZE-1))
+#define SECTION_MASK		(~((1 << SECTION_SHIFT) - 1))
 
 #define USER_PTRS_PER_PGD	(PAGE_OFFSET / PGDIR_SIZE)
 
 /*
+ * Hugetlb definitions.
+ */
+#define HPAGE_SHIFT		PMD_SHIFT
+#define HPAGE_SIZE		(_AC(1, UL) << HPAGE_SHIFT)
+#define HPAGE_MASK		(~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
+
+/*
  * "Linux" PTE definitions for LPAE.
  *
  * These bits overlap with the hardware bits but the naming is preserved for
@@ -79,6 +87,11 @@
 #define L_PTE_SPECIAL		(_AT(pteval_t, 1) << 56)	/* unused */
 #define L_PTE_NONE		(_AT(pteval_t, 1) << 57)	/* PROT_NONE */
 
+#define PMD_SECT_VALID		(_AT(pmdval_t, 1) << 0)
+#define PMD_SECT_DIRTY		(_AT(pmdval_t, 1) << 55)
+#define PMD_SECT_SPLITTING	(_AT(pmdval_t, 1) << 56)
+#define PMD_SECT_NONE		(_AT(pmdval_t, 1) << 57)
+
 /*
  * To be used in assembly code with the upper page attributes.
  */
@@ -166,8 +179,83 @@ static inline pmd_t *pmd_offset(pud_t *p
 		clean_pmd_entry(pmdp);	\
 	} while (0)
 
+/*
+ * For 3 levels of paging the PTE_EXT_NG bit will be set for user address ptes
+ * that are written to a page table but not for ptes created with mk_pte.
+ *
+ * In hugetlb_no_page, a new huge pte (new_pte) is generated and passed to
+ * hugetlb_cow, where it is compared with an entry in a page table.
+ * This comparison test fails erroneously leading ultimately to a memory leak.
+ *
+ * To correct this behaviour, we mask off PTE_EXT_NG for any pte that is
+ * present before running the comparison.
+ */
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(pte_a,pte_b)	((pte_present(pte_a) ? pte_val(pte_a) & ~PTE_EXT_NG	\
+					: pte_val(pte_a))				\
+				== (pte_present(pte_b) ? pte_val(pte_b) & ~PTE_EXT_NG	\
+					: pte_val(pte_b)))
+
 #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext)))
 
+#define pte_huge(pte)		(pte_val(pte) && !(pte_val(pte) & PTE_TABLE_BIT))
+#define pte_mkhuge(pte)		(__pte(pte_val(pte) & ~PTE_TABLE_BIT))
+
+#define pmd_young(pmd)		(pmd_val(pmd) & PMD_SECT_AF)
+
+#define __HAVE_ARCH_PMD_WRITE
+#define pmd_write(pmd)		(!(pmd_val(pmd) & PMD_SECT_RDONLY))
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define pmd_trans_huge(pmd)	(pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
+#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
+#endif
+
+#define PMD_BIT_FUNC(fn,op) \
+static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
+
+PMD_BIT_FUNC(wrprotect,	|= PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkold,	&= ~PMD_SECT_AF);
+PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
+PMD_BIT_FUNC(mkwrite,   &= ~PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkdirty,   |= PMD_SECT_DIRTY);
+PMD_BIT_FUNC(mkyoung,   |= PMD_SECT_AF);
+
+#define pmd_mkhuge(pmd)		(__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
+
+#define pmd_pfn(pmd)		(((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
+#define pfn_pmd(pfn,prot)	(__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+#define mk_pmd(page,prot)	pfn_pmd(page_to_pfn(page),prot)
+
+/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
+#define pmd_mknotpresent(pmd)	(__pmd(0))
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+	const pmdval_t mask = PMD_SECT_USER | PMD_SECT_XN | PMD_SECT_RDONLY |
+				PMD_SECT_VALID | PMD_SECT_NONE;
+	pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
+	return pmd;
+}
+
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+			      pmd_t *pmdp, pmd_t pmd)
+{
+	BUG_ON(addr >= TASK_SIZE);
+
+	/* create a faulting entry if PROT_NONE protected */
+	if (pmd_val(pmd) & PMD_SECT_NONE)
+		pmd_val(pmd) &= ~PMD_SECT_VALID;
+
+	*pmdp = __pmd(pmd_val(pmd) | PMD_SECT_nG);
+	flush_pmd_entry(pmdp);
+}
+
+static inline int has_transparent_hugepage(void)
+{
+	return 1;
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_PGTABLE_3LEVEL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/pgtable-3level-hwdef.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/pgtable-3level-hwdef.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/pgtable-3level-hwdef.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/pgtable-3level-hwdef.h	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,7 @@
 #define PMD_TYPE_FAULT		(_AT(pmdval_t, 0) << 0)
 #define PMD_TYPE_TABLE		(_AT(pmdval_t, 3) << 0)
 #define PMD_TYPE_SECT		(_AT(pmdval_t, 1) << 0)
+#define PMD_TABLE_BIT		(_AT(pmdval_t, 1) << 1)
 #define PMD_BIT4		(_AT(pmdval_t, 0))
 #define PMD_DOMAIN(x)		(_AT(pmdval_t, 0))
 #define PMD_APTABLE_SHIFT	(61)
@@ -41,6 +42,8 @@
  */
 #define PMD_SECT_BUFFERABLE	(_AT(pmdval_t, 1) << 2)
 #define PMD_SECT_CACHEABLE	(_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_USER		(_AT(pmdval_t, 1) << 6)		/* AP[1] */
+#define PMD_SECT_RDONLY		(_AT(pmdval_t, 1) << 7)		/* AP[2] */
 #define PMD_SECT_S		(_AT(pmdval_t, 3) << 8)
 #define PMD_SECT_AF		(_AT(pmdval_t, 1) << 10)
 #define PMD_SECT_nG		(_AT(pmdval_t, 1) << 11)
@@ -66,6 +69,7 @@
 #define PTE_TYPE_MASK		(_AT(pteval_t, 3) << 0)
 #define PTE_TYPE_FAULT		(_AT(pteval_t, 0) << 0)
 #define PTE_TYPE_PAGE		(_AT(pteval_t, 3) << 0)
+#define PTE_TABLE_BIT		(_AT(pteval_t, 1) << 1)
 #define PTE_BUFFERABLE		(_AT(pteval_t, 1) << 2)		/* AttrIndx[0] */
 #define PTE_CACHEABLE		(_AT(pteval_t, 1) << 3)		/* AttrIndx[1] */
 #define PTE_EXT_SHARED		(_AT(pteval_t, 3) << 8)		/* SH[1:0], inner shareable */
@@ -79,4 +83,24 @@
 #define PHYS_MASK_SHIFT		(40)
 #define PHYS_MASK		((1ULL << PHYS_MASK_SHIFT) - 1)
 
+/*
+ * TTBR0/TTBR1 split (PAGE_OFFSET):
+ *   0x40000000: T0SZ = 2, T1SZ = 0 (not used)
+ *   0x80000000: T0SZ = 0, T1SZ = 1
+ *   0xc0000000: T0SZ = 0, T1SZ = 2
+ *
+ * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise
+ * booting secondary CPUs would end up using TTBR1 for the identity
+ * mapping set up in TTBR0.
+ */
+#if defined CONFIG_VMSPLIT_2G
+#define TTBR1_OFFSET	16			/* skip two L1 entries */
+#elif defined CONFIG_VMSPLIT_3G
+#define TTBR1_OFFSET	(4096 * (1 + 3))	/* only L2, skip pgd + 3*pmd */
+#else
+#define TTBR1_OFFSET	0
+#endif
+
+#define TTBR1_SIZE	(((PAGE_OFFSET >> 30) - 1) << 16)
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,9 @@
 #include <asm/memory.h>
 #include <asm/pgtable-hwdef.h>
 
+
+#include <asm/tlbflush.h>
+
 #ifdef CONFIG_ARM_LPAE
 #include <asm/pgtable-3level.h>
 #else
@@ -318,13 +321,6 @@ static inline pte_t pte_modify(pte_t pte
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
 
-/*
- * remap a physical page `pfn' of size `size' with page protection `prot'
- * into virtual address `from'
- */
-#define io_remap_pfn_range(vma,from,pfn,size,prot) \
-		remap_pfn_range(vma, from, pfn, size, prot)
-
 #define pgtable_cache_init() do { } while (0)
 
 #endif /* !__ASSEMBLY__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/pgtable-nommu.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/pgtable-nommu.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/pgtable-nommu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/pgtable-nommu.h	2013-08-25 20:43:22.000000000 -0400
@@ -79,8 +79,6 @@ extern unsigned int kobjsize(const void
  * No page table caches to initialise.
  */
 #define pgtable_cache_init()	do { } while (0)
-#define io_remap_pfn_range	remap_pfn_range
-
 
 /*
  * All 32bit addresses are effectively valid for vmalloc...
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/processor.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/processor.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/processor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/processor.h	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,6 @@ struct thread_struct {
 
 #define start_thread(regs,pc,sp)					\
 ({									\
-	unsigned long *stack = (unsigned long *)sp;			\
 	memset(regs->uregs, 0, sizeof(regs->uregs));			\
 	if (current->personality & ADDR_LIMIT_32BIT)			\
 		regs->ARM_cpsr = USR_MODE;				\
@@ -65,9 +64,6 @@ struct thread_struct {
 	regs->ARM_cpsr |= PSR_ENDSTATE;					\
 	regs->ARM_pc = pc & ~1;		/* pc */			\
 	regs->ARM_sp = sp;		/* sp */			\
-	regs->ARM_r2 = stack[2];	/* r2 (envp) */			\
-	regs->ARM_r1 = stack[1];	/* r1 (argv) */			\
-	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\
 	nommu_start_thread(regs);					\
 })
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/proc-fns.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/proc-fns.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/proc-fns.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/proc-fns.h	2013-08-25 20:43:22.000000000 -0400
@@ -60,7 +60,7 @@ extern struct processor {
 	/*
 	 * Set the page table
 	 */
-	void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
+	void (*switch_mm)(phys_addr_t pgd_phys, struct mm_struct *mm);
 	/*
 	 * Set a possibly extended PTE.  Non-extended PTEs should
 	 * ignore 'ext'.
@@ -82,7 +82,7 @@ extern void cpu_proc_init(void);
 extern void cpu_proc_fin(void);
 extern int cpu_do_idle(void);
 extern void cpu_dcache_clean_area(void *, int);
-extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+extern void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
 #ifdef CONFIG_ARM_LPAE
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
 #else
@@ -116,13 +116,25 @@ extern void cpu_resume(void);
 #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
 
 #ifdef CONFIG_ARM_LPAE
+
+#define cpu_get_ttbr(nr)					\
+	({							\
+		u64 ttbr;					\
+		__asm__("mrrc	p15, " #nr ", %Q0, %R0, c2"	\
+			: "=r" (ttbr));				\
+		ttbr;						\
+	})
+
+#define cpu_set_ttbr(nr, val)					\
+	do {							\
+		u64 ttbr = val;					\
+		__asm__("mcrr	p15, " #nr ", %Q0, %R0, c2"	\
+			: : "r" (ttbr));			\
+	} while (0)
+
 #define cpu_get_pgd()	\
 	({						\
-		unsigned long pg, pg2;			\
-		__asm__("mrrc	p15, 0, %0, %1, c2"	\
-			: "=r" (pg), "=r" (pg2)		\
-			:				\
-			: "cc");			\
+		u64 pg = cpu_get_ttbr(0);		\
 		pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1);	\
 		(pgd_t *)phys_to_virt(pg);		\
 	})
@@ -137,6 +149,10 @@ extern void cpu_resume(void);
 	})
 #endif
 
+#else	/*!CONFIG_MMU */
+
+#define cpu_switch_mm(pgd,mm)	{ }
+
 #endif
 
 #endif /* __ASSEMBLY__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/psci.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/psci.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/psci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/psci.h	2013-08-25 20:43:22.000000000 -0400
@@ -32,5 +32,14 @@ struct psci_operations {
 };
 
 extern struct psci_operations psci_ops;
+extern struct smp_operations psci_smp_ops;
+
+#ifdef CONFIG_ARM_PSCI
+void psci_init(void);
+bool psci_smp_available(void);
+#else
+static inline void psci_init(void) { }
+static inline bool psci_smp_available(void) { return false; }
+#endif
 
 #endif /* __ASM_ARM_PSCI_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/ptrace.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/ptrace.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/ptrace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/ptrace.h	2013-08-25 20:43:22.000000000 -0400
@@ -45,6 +45,7 @@ struct pt_regs {
  */
 static inline int valid_user_regs(struct pt_regs *regs)
 {
+#ifndef CONFIG_CPU_V7M
 	unsigned long mode = regs->ARM_cpsr & MODE_MASK;
 
 	/*
@@ -67,6 +68,9 @@ static inline int valid_user_regs(struct
 		regs->ARM_cpsr |= USR_MODE;
 
 	return 0;
+#else /* ifndef CONFIG_CPU_V7M */
+	return 1;
+#endif
 }
 
 static inline long regs_return_value(struct pt_regs *regs)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/sched_clock.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/sched_clock.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/sched_clock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/sched_clock.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,16 +1,4 @@
-/*
- * sched_clock.h: support for extending counters to full 64-bit ns counter
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+/* You shouldn't include this file. Use linux/sched_clock.h instead.
+ * Temporary file until all asm/sched_clock.h users are gone
  */
-#ifndef ASM_SCHED_CLOCK
-#define ASM_SCHED_CLOCK
-
-extern void sched_clock_postinit(void);
-extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate);
-
-extern unsigned long long (*sched_clock_func)(void);
-
-#endif
+#include <linux/sched_clock.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/smp.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/smp.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/smp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/smp.h	2013-08-25 20:43:22.000000000 -0400
@@ -65,7 +65,10 @@ asmlinkage void secondary_start_kernel(v
  * Initial data for bringing up a secondary CPU.
  */
 struct secondary_data {
-	unsigned long pgdir;
+	union {
+		unsigned long mpu_rgn_szr;
+		unsigned long pgdir;
+	};
 	unsigned long swapper_pg_dir;
 	void *stack;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/smp_plat.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/smp_plat.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/smp_plat.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/smp_plat.h	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,9 @@ static inline bool is_smp(void)
 }
 
 /* all SMP configurations have the extended CPUID registers */
+#ifndef CONFIG_MMU
+#define tlb_ops_need_broadcast()	0
+#else
 static inline int tlb_ops_need_broadcast(void)
 {
 	if (!is_smp())
@@ -33,6 +36,7 @@ static inline int tlb_ops_need_broadcast
 
 	return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
 }
+#endif
 
 #if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
 #define cache_ops_need_broadcast()	0
@@ -66,4 +70,25 @@ static inline int get_logical_index(u32
 	return -EINVAL;
 }
 
+/*
+ * NOTE ! Assembly code relies on the following
+ * structure memory layout in order to carry out load
+ * multiple from its base address. For more
+ * information check arch/arm/kernel/sleep.S
+ */
+struct mpidr_hash {
+	u32	mask; /* used by sleep.S */
+	u32	shift_aff[3]; /* used by sleep.S */
+	u32	bits;
+};
+
+extern struct mpidr_hash mpidr_hash;
+
+static inline u32 mpidr_hash_size(void)
+{
+	return 1 << mpidr_hash.bits;
+}
+
+extern int platform_can_cpu_hotplug(void);
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/smp_scu.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/smp_scu.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/smp_scu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/smp_scu.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,10 +23,21 @@ static inline unsigned long scu_a9_get_b
 	return pa;
 }
 
+#ifdef CONFIG_HAVE_ARM_SCU
 unsigned int scu_get_core_count(void __iomem *);
 int scu_power_mode(void __iomem *, unsigned int);
+#else
+static inline unsigned int scu_get_core_count(void __iomem *scu_base)
+{
+	return 0;
+}
+static inline int scu_power_mode(void __iomem *scu_base, unsigned int mode)
+{
+	return -EINVAL;
+}
+#endif
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) && defined(CONFIG_HAVE_ARM_SCU)
 void scu_enable(void __iomem *scu_base);
 #else
 static inline void scu_enable(void __iomem *scu_base) {}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/spinlock.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/spinlock.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/spinlock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/spinlock.h	2013-08-25 20:43:22.000000000 -0400
@@ -97,19 +97,22 @@ static inline void arch_spin_lock(arch_s
 
 static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
-	unsigned long tmp;
+	unsigned long contended, res;
 	u32 slock;
 
-	__asm__ __volatile__(
-"	ldrex	%0, [%2]\n"
-"	subs	%1, %0, %0, ror #16\n"
-"	addeq	%0, %0, %3\n"
-"	strexeq	%1, %0, [%2]"
-	: "=&r" (slock), "=&r" (tmp)
-	: "r" (&lock->slock), "I" (1 << TICKET_SHIFT)
-	: "cc");
+	do {
+		__asm__ __volatile__(
+		"	ldrex	%0, [%3]\n"
+		"	mov	%2, #0\n"
+		"	subs	%1, %0, %0, ror #16\n"
+		"	addeq	%0, %0, %4\n"
+		"	strexeq	%2, %0, [%3]"
+		: "=&r" (slock), "=&r" (contended), "=&r" (res)
+		: "r" (&lock->slock), "I" (1 << TICKET_SHIFT)
+		: "cc");
+	} while (res);
 
-	if (tmp == 0) {
+	if (!contended) {
 		smp_mb();
 		return 1;
 	} else {
@@ -165,17 +168,20 @@ static inline void arch_write_lock(arch_
 
 static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
-	unsigned long tmp;
+	unsigned long contended, res;
 
-	__asm__ __volatile__(
-"	ldrex	%0, [%1]\n"
-"	teq	%0, #0\n"
-"	strexeq	%0, %2, [%1]"
-	: "=&r" (tmp)
-	: "r" (&rw->lock), "r" (0x80000000)
-	: "cc");
+	do {
+		__asm__ __volatile__(
+		"	ldrex	%0, [%2]\n"
+		"	mov	%1, #0\n"
+		"	teq	%0, #0\n"
+		"	strexeq	%1, %3, [%2]"
+		: "=&r" (contended), "=&r" (res)
+		: "r" (&rw->lock), "r" (0x80000000)
+		: "cc");
+	} while (res);
 
-	if (tmp == 0) {
+	if (!contended) {
 		smp_mb();
 		return 1;
 	} else {
@@ -251,18 +257,26 @@ static inline void arch_read_unlock(arch
 
 static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
-	unsigned long tmp, tmp2 = 1;
+	unsigned long contended, res;
 
-	__asm__ __volatile__(
-"	ldrex	%0, [%2]\n"
-"	adds	%0, %0, #1\n"
-"	strexpl	%1, %0, [%2]\n"
-	: "=&r" (tmp), "+r" (tmp2)
-	: "r" (&rw->lock)
-	: "cc");
+	do {
+		__asm__ __volatile__(
+		"	ldrex	%0, [%2]\n"
+		"	mov	%1, #0\n"
+		"	adds	%0, %0, #1\n"
+		"	strexpl	%1, %0, [%2]"
+		: "=&r" (contended), "=&r" (res)
+		: "r" (&rw->lock)
+		: "cc");
+	} while (res);
 
-	smp_mb();
-	return tmp2 == 0;
+	/* If the lock is negative, then it is already held for write. */
+	if (contended < 0x80000000) {
+		smp_mb();
+		return 1;
+	} else {
+		return 0;
+	}
 }
 
 /* read_can_lock - would read_trylock() succeed? */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/suspend.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/suspend.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/suspend.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/suspend.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,11 @@
 #ifndef __ASM_ARM_SUSPEND_H
 #define __ASM_ARM_SUSPEND_H
 
+struct sleep_save_sp {
+	u32 *save_ptr_stash;
+	u32 save_ptr_stash_phys;
+};
+
 extern void cpu_resume(void);
 extern int cpu_suspend(unsigned long, int (*)(unsigned long));
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/system_info.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/system_info.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/system_info.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/system_info.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,7 @@
 #define CPU_ARCH_ARMv5TEJ	7
 #define CPU_ARCH_ARMv6		8
 #define CPU_ARCH_ARMv7		9
+#define CPU_ARCH_ARMv7M		10
 
 #ifndef __ASSEMBLY__
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/system_misc.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/system_misc.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/system_misc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/system_misc.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,11 +6,12 @@
 #include <linux/compiler.h>
 #include <linux/linkage.h>
 #include <linux/irqflags.h>
+#include <linux/reboot.h>
 
 extern void cpu_init(void);
 
 void soft_restart(unsigned long);
-extern void (*arm_pm_restart)(char str, const char *cmd);
+extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
 extern void (*arm_pm_idle)(void);
 
 #define UDBG_UNDEFINED	(1 << 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/thread_info.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/thread_info.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/thread_info.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/thread_info.h	2013-08-25 20:43:22.000000000 -0400
@@ -58,7 +58,7 @@ struct thread_info {
 	struct cpu_context_save	cpu_context;	/* cpu context */
 	__u32			syscall;	/* syscall number */
 	__u8			used_cp[16];	/* thread used copro */
-	unsigned long		tp_value;
+	unsigned long		tp_value[2];	/* TLS registers */
 #ifdef CONFIG_CRUNCH
 	struct crunch_state	crunchstate;
 #endif
@@ -156,7 +156,6 @@ extern int vfp_restore_user_hwstate(stru
 #define TIF_USING_IWMMXT	17
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	20
-#define TIF_SWITCH_MM		22	/* deferred switch_mm */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/tlbflush.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/tlbflush.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/tlbflush.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/tlbflush.h	2013-08-25 20:43:22.000000000 -0400
@@ -443,7 +443,18 @@ static inline void local_flush_bp_all(vo
 		isb();
 }
 
+#include <asm/cputype.h>
 #ifdef CONFIG_ARM_ERRATA_798181
+static inline int erratum_a15_798181(void)
+{
+	unsigned int midr = read_cpuid_id();
+
+	/* Cortex-A15 r0p0..r3p2 affected */
+	if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2)
+		return 0;
+	return 1;
+}
+
 static inline void dummy_flush_tlb_a15_erratum(void)
 {
 	/*
@@ -453,6 +464,11 @@ static inline void dummy_flush_tlb_a15_e
 	dsb();
 }
 #else
+static inline int erratum_a15_798181(void)
+{
+	return 0;
+}
+
 static inline void dummy_flush_tlb_a15_erratum(void)
 {
 }
@@ -535,8 +551,33 @@ static inline void update_mmu_cache(stru
 }
 #endif
 
+#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
+
 #endif
 
-#endif /* CONFIG_MMU */
+#elif defined(CONFIG_SMP)	/* !CONFIG_MMU */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/mm_types.h>
+
+static inline void local_flush_tlb_all(void)									{ }
+static inline void local_flush_tlb_mm(struct mm_struct *mm)							{ }
+static inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)			{ }
+static inline void local_flush_tlb_kernel_page(unsigned long kaddr)						{ }
+static inline void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)	{ }
+static inline void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)				{ }
+static inline void local_flush_bp_all(void)									{ }
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr);
+extern void flush_tlb_kernel_page(unsigned long kaddr);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+extern void flush_bp_all(void);
+#endif	/* __ASSEMBLY__ */
+
+#endif
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/tlb.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/tlb.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/tlb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/tlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -43,6 +43,7 @@ struct mmu_gather {
 	struct mm_struct	*mm;
 	unsigned int		fullmm;
 	struct vm_area_struct	*vma;
+	unsigned long		start, end;
 	unsigned long		range_start;
 	unsigned long		range_end;
 	unsigned int		nr;
@@ -107,10 +108,12 @@ static inline void tlb_flush_mmu(struct
 }
 
 static inline void
-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
 {
 	tlb->mm = mm;
-	tlb->fullmm = fullmm;
+	tlb->fullmm = !(start | (end+1));
+	tlb->start = start;
+	tlb->end = end;
 	tlb->vma = NULL;
 	tlb->max = ARRAY_SIZE(tlb->local);
 	tlb->pages = tlb->local;
@@ -204,6 +207,12 @@ static inline void __pmd_free_tlb(struct
 #endif
 }
 
+static inline void
+tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr)
+{
+	tlb_add_flush(tlb, addr);
+}
+
 #define pte_free_tlb(tlb, ptep, addr)	__pte_free_tlb(tlb, ptep, addr)
 #define pmd_free_tlb(tlb, pmdp, addr)	__pmd_free_tlb(tlb, pmdp, addr)
 #define pud_free_tlb(tlb, pudp, addr)	pud_free((tlb)->mm, pudp)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/tls.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/tls.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/tls.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/tls.h	2013-08-25 20:43:22.000000000 -0400
@@ -2,27 +2,30 @@
 #define __ASMARM_TLS_H
 
 #ifdef __ASSEMBLY__
-	.macro set_tls_none, tp, tmp1, tmp2
+#include <asm/asm-offsets.h>
+	.macro switch_tls_none, base, tp, tpuser, tmp1, tmp2
 	.endm
 
-	.macro set_tls_v6k, tp, tmp1, tmp2
+	.macro switch_tls_v6k, base, tp, tpuser, tmp1, tmp2
+	mrc	p15, 0, \tmp2, c13, c0, 2	@ get the user r/w register
 	mcr	p15, 0, \tp, c13, c0, 3		@ set TLS register
-	mov	\tmp1, #0
-	mcr	p15, 0, \tmp1, c13, c0, 2	@ clear user r/w TLS register
+	mcr	p15, 0, \tpuser, c13, c0, 2	@ and the user r/w register
+	str	\tmp2, [\base, #TI_TP_VALUE + 4] @ save it
 	.endm
 
-	.macro set_tls_v6, tp, tmp1, tmp2
+	.macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2
 	ldr	\tmp1, =elf_hwcap
 	ldr	\tmp1, [\tmp1, #0]
 	mov	\tmp2, #0xffff0fff
 	tst	\tmp1, #HWCAP_TLS		@ hardware TLS available?
-	mcrne	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
-	movne	\tmp1, #0
-	mcrne	p15, 0, \tmp1, c13, c0, 2	@ clear user r/w TLS register
 	streq	\tp, [\tmp2, #-15]		@ set TLS value at 0xffff0ff0
+	mrcne	p15, 0, \tmp2, c13, c0, 2	@ get the user r/w register
+	mcrne	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
+	mcrne	p15, 0, \tpuser, c13, c0, 2	@ set user r/w register
+	strne	\tmp2, [\base, #TI_TP_VALUE + 4] @ save it
 	.endm
 
-	.macro set_tls_software, tp, tmp1, tmp2
+	.macro switch_tls_software, base, tp, tpuser, tmp1, tmp2
 	mov	\tmp1, #0xffff0fff
 	str	\tp, [\tmp1, #-15]		@ set TLS value at 0xffff0ff0
 	.endm
@@ -31,19 +34,30 @@
 #ifdef CONFIG_TLS_REG_EMUL
 #define tls_emu		1
 #define has_tls_reg		1
-#define set_tls		set_tls_none
+#define switch_tls	switch_tls_none
 #elif defined(CONFIG_CPU_V6)
 #define tls_emu		0
 #define has_tls_reg		(elf_hwcap & HWCAP_TLS)
-#define set_tls		set_tls_v6
+#define switch_tls	switch_tls_v6
 #elif defined(CONFIG_CPU_32v6K)
 #define tls_emu		0
 #define has_tls_reg		1
-#define set_tls		set_tls_v6k
+#define switch_tls	switch_tls_v6k
 #else
 #define tls_emu		0
 #define has_tls_reg		0
-#define set_tls		set_tls_software
+#define switch_tls	switch_tls_software
 #endif
 
+#ifndef __ASSEMBLY__
+static inline unsigned long get_tpuser(void)
+{
+	unsigned long reg = 0;
+
+	if (has_tls_reg && !tls_emu)
+		__asm__("mrc p15, 0, %0, c13, c0, 2" : "=r" (reg));
+
+	return reg;
+}
+#endif
 #endif	/* __ASMARM_TLS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/v7m.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/v7m.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/v7m.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/v7m.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * Common defines for v7m cpus
+ */
+#define V7M_SCS_ICTR			IOMEM(0xe000e004)
+#define V7M_SCS_ICTR_INTLINESNUM_MASK		0x0000000f
+
+#define BASEADDR_V7M_SCB		IOMEM(0xe000ed00)
+
+#define V7M_SCB_CPUID			0x00
+
+#define V7M_SCB_ICSR			0x04
+#define V7M_SCB_ICSR_PENDSVSET			(1 << 28)
+#define V7M_SCB_ICSR_PENDSVCLR			(1 << 27)
+#define V7M_SCB_ICSR_RETTOBASE			(1 << 11)
+
+#define V7M_SCB_VTOR			0x08
+
+#define V7M_SCB_SCR			0x10
+#define V7M_SCB_SCR_SLEEPDEEP			(1 << 2)
+
+#define V7M_SCB_CCR			0x14
+#define V7M_SCB_CCR_STKALIGN			(1 << 9)
+
+#define V7M_SCB_SHPR2			0x1c
+#define V7M_SCB_SHPR3			0x20
+
+#define V7M_SCB_SHCSR			0x24
+#define V7M_SCB_SHCSR_USGFAULTENA		(1 << 18)
+#define V7M_SCB_SHCSR_BUSFAULTENA		(1 << 17)
+#define V7M_SCB_SHCSR_MEMFAULTENA		(1 << 16)
+
+#define V7M_xPSR_FRAMEPTRALIGN			0x00000200
+#define V7M_xPSR_EXCEPTIONNO			0x000001ff
+
+/*
+ * When branching to an address that has bits [31:28] == 0xf an exception return
+ * occurs. Bits [27:5] are reserved (SBOP). If the processor implements the FP
+ * extension Bit [4] defines if the exception frame has space allocated for FP
+ * state information, SBOP otherwise. Bit [3] defines the mode that is returned
+ * to (0 -> handler mode; 1 -> thread mode). Bit [2] defines which sp is used
+ * (0 -> msp; 1 -> psp). Bits [1:0] are fixed to 0b01.
+ */
+#define EXC_RET_STACK_MASK			0x00000004
+#define EXC_RET_THREADMODE_PROCESSSTACK		0xfffffffd
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/virt.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/virt.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/virt.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/virt.h	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,7 @@
 #define BOOT_CPU_MODE_MISMATCH	PSR_N_BIT
 
 #ifndef __ASSEMBLY__
+#include <asm/cacheflush.h>
 
 #ifdef CONFIG_ARM_VIRT_EXT
 /*
@@ -41,10 +42,21 @@
  */
 extern int __boot_cpu_mode;
 
+static inline void sync_boot_mode(void)
+{
+	/*
+	 * As secondaries write to __boot_cpu_mode with caches disabled, we
+	 * must flush the corresponding cache entries to ensure the visibility
+	 * of their writes.
+	 */
+	sync_cache_r(&__boot_cpu_mode);
+}
+
 void __hyp_set_vectors(unsigned long phys_vector_base);
 unsigned long __hyp_get_vectors(void);
 #else
 #define __boot_cpu_mode	(SVC_MODE)
+#define sync_boot_mode()
 #endif
 
 #ifndef ZIMAGE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/xen/hypercall.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/xen/hypercall.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/xen/hypercall.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/xen/hypercall.h	2013-08-25 20:43:22.000000000 -0400
@@ -47,6 +47,7 @@ unsigned long HYPERVISOR_hvm_op(int op,
 int HYPERVISOR_memory_op(unsigned int cmd, void *arg);
 int HYPERVISOR_physdev_op(int cmd, void *arg);
 int HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args);
+int HYPERVISOR_tmem_op(void *arg);
 
 static inline void
 MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/asm/xen/page.h linux-libre-3.11-rc7-gnu/arch/arm/include/asm/xen/page.h
--- linux-libre-3.10-gnu/arch/arm/include/asm/xen/page.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/asm/xen/page.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,6 @@
 #ifndef _ASM_ARM_XEN_PAGE_H
 #define _ASM_ARM_XEN_PAGE_H
 
-#include <asm/mach/map.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
@@ -88,6 +87,6 @@ static inline bool set_phys_to_machine(u
 	return __set_phys_to_machine(pfn, mfn);
 }
 
-#define xen_remap(cookie, size) __arm_ioremap((cookie), (size), MT_MEMORY);
+#define xen_remap(cookie, size) ioremap_cached((cookie), (size));
 
 #endif /* _ASM_ARM_XEN_PAGE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/debug/imx-uart.h linux-libre-3.11-rc7-gnu/arch/arm/include/debug/imx-uart.h
--- linux-libre-3.10-gnu/arch/arm/include/debug/imx-uart.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/debug/imx-uart.h	2013-08-25 20:43:22.000000000 -0400
@@ -65,6 +65,14 @@
 #define IMX6Q_UART_BASE_ADDR(n)	IMX6Q_UART##n##_BASE_ADDR
 #define IMX6Q_UART_BASE(n)	IMX6Q_UART_BASE_ADDR(n)
 
+#define IMX6SL_UART1_BASE_ADDR	0x02020000
+#define IMX6SL_UART2_BASE_ADDR	0x02024000
+#define IMX6SL_UART3_BASE_ADDR	0x02034000
+#define IMX6SL_UART4_BASE_ADDR	0x02038000
+#define IMX6SL_UART5_BASE_ADDR	0x02018000
+#define IMX6SL_UART_BASE_ADDR(n) IMX6SL_UART##n##_BASE_ADDR
+#define IMX6SL_UART_BASE(n)	IMX6SL_UART_BASE_ADDR(n)
+
 #define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT)
 
 #ifdef CONFIG_DEBUG_IMX1_UART
@@ -83,6 +91,8 @@
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX53)
 #elif defined(CONFIG_DEBUG_IMX6Q_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX6Q)
+#elif defined(CONFIG_DEBUG_IMX6SL_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX6SL)
 #endif
 
 #endif /* __DEBUG_IMX_UART_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/debug/keystone.S linux-libre-3.11-rc7-gnu/arch/arm/include/debug/keystone.S
--- linux-libre-3.10-gnu/arch/arm/include/debug/keystone.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/debug/keystone.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ * Early serial debug output macro for Keystone SOCs
+ *
+ * Copyright 2013 Texas Instruments, Inc.
+ *	Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Based on RMKs low level debug code.
+ *  Copyright (C) 1994-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_reg.h>
+
+#define UART_SHIFT 2
+#if defined(CONFIG_DEBUG_KEYSTONE_UART0)
+#define UART_PHYS		0x02530c00
+#define UART_VIRT		0xfeb30c00
+#elif defined(CONFIG_DEBUG_KEYSTONE_UART1)
+#define UART_PHYS		0x02531000
+#define UART_VIRT		0xfeb31000
+#endif
+
+	.macro	addruart, rp, rv, tmp
+	ldr	\rv, =UART_VIRT			@ physical base address
+	ldr	\rp, =UART_PHYS			@ virtual base address
+	.endm
+
+	.macro	senduart,rd,rx
+	str	\rd, [\rx, #UART_TX << UART_SHIFT]
+	.endm
+
+	.macro	busyuart,rd,rx
+1002:	ldr	\rd, [\rx, #UART_LSR << UART_SHIFT]
+	and	\rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+	teq	\rd, #UART_LSR_TEMT | UART_LSR_THRE
+	bne	1002b
+	.endm
+
+	.macro	waituart,rd,rx
+	.endm
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/debug/mvebu.S linux-libre-3.11-rc7-gnu/arch/arm/include/debug/mvebu.S
--- linux-libre-3.10-gnu/arch/arm/include/debug/mvebu.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/debug/mvebu.S	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,12 @@
  * published by the Free Software Foundation.
 */
 
+#ifdef CONFIG_DEBUG_MVEBU_UART_ALTERNATE
+#define ARMADA_370_XP_REGS_PHYS_BASE	0xf1000000
+#else
 #define ARMADA_370_XP_REGS_PHYS_BASE	0xd0000000
+#endif
+
 #define ARMADA_370_XP_REGS_VIRT_BASE	0xfec00000
 
 	.macro	addruart, rp, rv, tmp
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/debug/nspire.S linux-libre-3.11-rc7-gnu/arch/arm/include/debug/nspire.S
--- linux-libre-3.10-gnu/arch/arm/include/debug/nspire.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/debug/nspire.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ *	linux/arch/arm/include/debug/nspire.S
+ *
+ *	Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define NSPIRE_EARLY_UART_PHYS_BASE	   0x90020000
+#define NSPIRE_EARLY_UART_VIRT_BASE	   0xfee20000
+
+.macro	addruart, rp, rv, tmp
+	ldr \rp, =(NSPIRE_EARLY_UART_PHYS_BASE)		@ physical base address
+	ldr \rv, =(NSPIRE_EARLY_UART_VIRT_BASE)		@ virtual base address
+.endm
+
+
+#ifdef CONFIG_DEBUG_NSPIRE_CX_UART
+#include <asm/hardware/debug-pl01x.S>
+#endif
+
+#ifdef CONFIG_DEBUG_NSPIRE_CLASSIC_UART
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/debug/rockchip.S linux-libre-3.11-rc7-gnu/arch/arm/include/debug/rockchip.S
--- linux-libre-3.10-gnu/arch/arm/include/debug/rockchip.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/debug/rockchip.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * Early serial output macro for Rockchip SoCs
+ *
+ * Copyright (C) 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#if defined(CONFIG_DEBUG_RK29_UART0)
+#define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20060000
+#define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed60000
+#elif defined(CONFIG_DEBUG_RK29_UART1)
+#define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20064000
+#define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed64000
+#elif defined(CONFIG_DEBUG_RK29_UART2)
+#define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20068000
+#define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed68000
+#elif defined(CONFIG_DEBUG_RK3X_UART0)
+#define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x10124000
+#define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfeb24000
+#elif defined(CONFIG_DEBUG_RK3X_UART1)
+#define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x10126000
+#define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfeb26000
+#elif defined(CONFIG_DEBUG_RK3X_UART2)
+#define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20064000
+#define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed64000
+#elif defined(CONFIG_DEBUG_RK3X_UART3)
+#define ROCKCHIP_UART_DEBUG_PHYS_BASE 0x20068000
+#define ROCKCHIP_UART_DEBUG_VIRT_BASE 0xfed68000
+#endif
+
+	.macro	addruart, rp, rv, tmp
+	ldr	\rp, =ROCKCHIP_UART_DEBUG_PHYS_BASE
+	ldr	\rv, =ROCKCHIP_UART_DEBUG_VIRT_BASE
+	.endm
+
+#define UART_SHIFT	2
+#include <asm/hardware/debug-8250.S>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/debug/sti.S linux-libre-3.11-rc7-gnu/arch/arm/include/debug/sti.S
--- linux-libre-3.10-gnu/arch/arm/include/debug/sti.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/debug/sti.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/include/debug/sti.S
+ *
+ * Debugging macro include header
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define STIH41X_COMMS_BASE              0xfed00000
+#define STIH41X_ASC2_BASE               (STIH41X_COMMS_BASE+0x32000)
+
+#define STIH41X_SBC_LPM_BASE            0xfe400000
+#define STIH41X_SBC_COMMS_BASE          (STIH41X_SBC_LPM_BASE + 0x100000)
+#define STIH41X_SBC_ASC1_BASE           (STIH41X_SBC_COMMS_BASE + 0x31000)
+
+
+#define VIRT_ADDRESS(x)		(x - 0x1000000)
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_ASC2)
+#define DEBUG_LL_UART_BASE	STIH41X_ASC2_BASE
+#endif
+
+#if IS_ENABLED(CONFIG_STIH41X_DEBUG_SBC_ASC1)
+#define DEBUG_LL_UART_BASE	STIH41X_SBC_ASC1_BASE
+#endif
+
+#ifndef DEBUG_LL_UART_BASE
+#error "DEBUG UART is not Configured"
+#endif
+
+#define ASC_TX_BUF_OFF  0x04
+#define ASC_CTRL_OFF    0x0c
+#define ASC_STA_OFF     0x14
+
+#define ASC_STA_TX_FULL         (1<<9)
+#define ASC_STA_TX_EMPTY        (1<<1)
+
+
+		.macro	addruart, rp, rv, tmp
+		ldr	\rp,      =DEBUG_LL_UART_BASE	@ physical base
+		ldr	\rv,      =VIRT_ADDRESS(DEBUG_LL_UART_BASE) @ virt base
+		.endm
+
+                .macro  senduart,rd,rx
+                strb    \rd, [\rx, #ASC_TX_BUF_OFF]
+                .endm
+
+                .macro  waituart,rd,rx
+1001:           ldr     \rd, [\rx, #ASC_STA_OFF]
+                tst     \rd, #ASC_STA_TX_FULL
+                bne     1001b
+                .endm
+
+                .macro  busyuart,rd,rx
+1001:           ldr     \rd, [\rx, #ASC_STA_OFF]
+                tst     \rd, #ASC_STA_TX_EMPTY
+                beq     1001b
+                .endm
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/debug/u300.S linux-libre-3.11-rc7-gnu/arch/arm/include/debug/u300.S
--- linux-libre-3.10-gnu/arch/arm/include/debug/u300.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/debug/u300.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2006-2013 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Debugging macro include header.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#define U300_SLOW_PER_PHYS_BASE		0xc0010000
+#define U300_SLOW_PER_VIRT_BASE		0xff000000
+
+	.macro	addruart, rp, rv, tmp
+	/* If we move the address using MMU, use this. */
+	ldr	\rp,	  = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address
+	ldr	\rv,	  = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address
+	orr	\rp, \rp, #0x00003000
+	orr	\rv, \rv, #0x00003000
+	.endm
+
+#include <asm/hardware/debug-pl01x.S>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/debug/vexpress.S linux-libre-3.11-rc7-gnu/arch/arm/include/debug/vexpress.S
--- linux-libre-3.10-gnu/arch/arm/include/debug/vexpress.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/debug/vexpress.S	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,8 @@
 #define DEBUG_LL_PHYS_BASE_RS1		0x1c000000
 #define DEBUG_LL_UART_OFFSET_RS1	0x00090000
 
+#define DEBUG_LL_UART_PHYS_CRX		0xb0090000
+
 #define DEBUG_LL_VIRT_BASE		0xf8000000
 
 #if defined(CONFIG_DEBUG_VEXPRESS_UART0_DETECT)
@@ -66,6 +68,14 @@
 		.endm
 
 #include <asm/hardware/debug-pl01x.S>
+
+#elif defined(CONFIG_DEBUG_VEXPRESS_UART0_CRX)
+
+		.macro	addruart,rp,tmp,tmp2
+		ldr	\rp, =DEBUG_LL_UART_PHYS_CRX
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
 
 #else /* CONFIG_DEBUG_LL_UART_NONE */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/uapi/asm/a.out.h linux-libre-3.11-rc7-gnu/arch/arm/include/uapi/asm/a.out.h
--- linux-libre-3.10-gnu/arch/arm/include/uapi/asm/a.out.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/uapi/asm/a.out.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-#ifndef __ARM_A_OUT_H__
-#define __ARM_A_OUT_H__
-
-#include <linux/personality.h>
-#include <linux/types.h>
-
-struct exec
-{
-  __u32 a_info;		/* Use macros N_MAGIC, etc for access */
-  __u32 a_text;		/* length of text, in bytes */
-  __u32 a_data;		/* length of data, in bytes */
-  __u32 a_bss;		/* length of uninitialized data area for file, in bytes */
-  __u32 a_syms;		/* length of symbol table data in file, in bytes */
-  __u32 a_entry;	/* start address */
-  __u32 a_trsize;	/* length of relocation info for text, in bytes */
-  __u32 a_drsize;	/* length of relocation info for data, in bytes */
-};
-
-/*
- * This is always the same
- */
-#define N_TXTADDR(a)	(0x00008000)
-
-#define N_TRSIZE(a)	((a).a_trsize)
-#define N_DRSIZE(a)	((a).a_drsize)
-#define N_SYMSIZE(a)	((a).a_syms)
-
-#define M_ARM 103
-
-#ifndef LIBRARY_START_TEXT
-#define LIBRARY_START_TEXT	(0x00c00000)
-#endif
-
-#endif /* __A_OUT_GNU_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/uapi/asm/hwcap.h linux-libre-3.11-rc7-gnu/arch/arm/include/uapi/asm/hwcap.h
--- linux-libre-3.10-gnu/arch/arm/include/uapi/asm/hwcap.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/uapi/asm/hwcap.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,6 @@
 #define HWCAP_IDIVT	(1 << 18)
 #define HWCAP_VFPD32	(1 << 19)	/* set if VFP has 32 regs (not 16) */
 #define HWCAP_IDIV	(HWCAP_IDIVA | HWCAP_IDIVT)
-
+#define HWCAP_LPAE	(1 << 20)
 
 #endif /* _UAPI__ASMARM_HWCAP_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/uapi/asm/Kbuild linux-libre-3.11-rc7-gnu/arch/arm/include/uapi/asm/Kbuild
--- linux-libre-3.10-gnu/arch/arm/include/uapi/asm/Kbuild	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/uapi/asm/Kbuild	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,6 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
-header-y += a.out.h
 header-y += byteorder.h
 header-y += fcntl.h
 header-y += hwcap.h
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/include/uapi/asm/ptrace.h linux-libre-3.11-rc7-gnu/arch/arm/include/uapi/asm/ptrace.h
--- linux-libre-3.10-gnu/arch/arm/include/uapi/asm/ptrace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/include/uapi/asm/ptrace.h	2013-08-25 20:43:22.000000000 -0400
@@ -34,28 +34,47 @@
 
 /*
  * PSR bits
+ * Note on V7M there is no mode contained in the PSR
  */
 #define USR26_MODE	0x00000000
 #define FIQ26_MODE	0x00000001
 #define IRQ26_MODE	0x00000002
 #define SVC26_MODE	0x00000003
+#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M)
+/*
+ * Use 0 here to get code right that creates a userspace
+ * or kernel space thread.
+ */
+#define USR_MODE	0x00000000
+#define SVC_MODE	0x00000000
+#else
 #define USR_MODE	0x00000010
+#define SVC_MODE	0x00000013
+#endif
 #define FIQ_MODE	0x00000011
 #define IRQ_MODE	0x00000012
-#define SVC_MODE	0x00000013
 #define ABT_MODE	0x00000017
 #define HYP_MODE	0x0000001a
 #define UND_MODE	0x0000001b
 #define SYSTEM_MODE	0x0000001f
 #define MODE32_BIT	0x00000010
 #define MODE_MASK	0x0000001f
-#define PSR_T_BIT	0x00000020
-#define PSR_F_BIT	0x00000040
-#define PSR_I_BIT	0x00000080
-#define PSR_A_BIT	0x00000100
-#define PSR_E_BIT	0x00000200
-#define PSR_J_BIT	0x01000000
-#define PSR_Q_BIT	0x08000000
+
+#define V4_PSR_T_BIT	0x00000020	/* >= V4T, but not V7M */
+#define V7M_PSR_T_BIT	0x01000000
+#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M)
+#define PSR_T_BIT	V7M_PSR_T_BIT
+#else
+/* for compatibility */
+#define PSR_T_BIT	V4_PSR_T_BIT
+#endif
+
+#define PSR_F_BIT	0x00000040	/* >= V4, but not V7M */
+#define PSR_I_BIT	0x00000080	/* >= V4, but not V7M */
+#define PSR_A_BIT	0x00000100	/* >= V6, but not V7M */
+#define PSR_E_BIT	0x00000200	/* >= V6, but not V7M */
+#define PSR_J_BIT	0x01000000	/* >= V5J, but not V7M */
+#define PSR_Q_BIT	0x08000000	/* >= V5E, including V7M */
 #define PSR_V_BIT	0x10000000
 #define PSR_C_BIT	0x20000000
 #define PSR_Z_BIT	0x40000000
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/Kconfig
--- linux-libre-3.10-gnu/arch/arm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -9,17 +9,17 @@ config ARM
 	select BUILDTIME_EXTABLE_SORT if MMU
 	select CPU_PM if (SUSPEND || CPU_IDLE)
 	select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU
-	select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
+	select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI)
 	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
 	select GENERIC_PCI_IOMAP
+	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select HARDIRQS_SW_RESEND
-	select HAVE_AOUT
 	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_SECCOMP_FILTER
@@ -40,6 +40,7 @@ config ARM
 	select HAVE_IDE if PCI || ISA || PCMCIA
 	select HAVE_IRQ_TIME_ACCOUNTING
 	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_LZ4
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_XZ
@@ -175,6 +176,9 @@ config ARCH_HAS_CPUFREQ
 	  and that the relevant menu configurations are displayed for
 	  it.
 
+config ARCH_HAS_BANDGAP
+	bool
+
 config GENERIC_HWEIGHT
 	bool
 	default y
@@ -213,7 +217,8 @@ config VECTORS_BASE
 	default DRAM_BASE if REMAP_VECTORS_TO_RAM
 	default 0x00000000
 	help
-	  The base address of exception vectors.
+	  The base address of exception vectors.  This must be two pages
+	  in size.
 
 config ARM_PATCH_PHYS_VIRT
 	bool "Patch physical to virtual translations at runtime" if EMBEDDED
@@ -366,11 +371,12 @@ config ARCH_CLPS711X
 	select ARCH_REQUIRE_GPIOLIB
 	select AUTO_ZRELADDR
 	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
 	select COMMON_CLK
 	select CPU_ARM720T
 	select GENERIC_CLOCKEVENTS
+	select MFD_SYSCON
 	select MULTI_IRQ_HANDLER
-	select NEED_MACH_MEMORY_H
 	select SPARSE_IRQ
 	help
 	  Support for Cirrus Logic 711x/721x/731x based boards.
@@ -502,6 +508,7 @@ config ARCH_DOVE
 
 config ARCH_KIRKWOOD
 	bool "Marvell Kirkwood"
+	select ARCH_HAS_CPUFREQ
 	select ARCH_REQUIRE_GPIOLIB
 	select CPU_FEROCEON
 	select GENERIC_CLOCKEVENTS
@@ -623,8 +630,8 @@ config ARCH_MSM
 	bool "Qualcomm MSM"
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
+	select COMMON_CLK
 	select GENERIC_CLOCKEVENTS
-	select HAVE_CLK
 	help
 	  Support for Qualcomm MSM/QSD based systems.  This runs on the
 	  apps processor of the MSM/QSD and depends on a shared memory
@@ -634,6 +641,7 @@ config ARCH_MSM
 
 config ARCH_SHMOBILE
 	bool "Renesas SH-Mobile / R-Mobile"
+	select ARM_PATCH_PHYS_VIRT
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU if SMP
@@ -643,9 +651,8 @@ config ARCH_SHMOBILE
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
 	select MULTI_IRQ_HANDLER
-	select NEED_MACH_MEMORY_H
 	select NO_IOPORT
-	select PINCTRL if ARCH_WANT_OPTIONAL_GPIOLIB
+	select PINCTRL
 	select PM_GENERIC_DOMAINS if PM
 	select SPARSE_IRQ
 	help
@@ -695,6 +702,7 @@ config ARCH_S3C24XX
 	select CLKDEV_LOOKUP
 	select CLKSRC_MMIO
 	select GENERIC_CLOCKEVENTS
+	select GPIO_SAMSUNG
 	select HAVE_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -702,6 +710,7 @@ config ARCH_S3C24XX
 	select MULTI_IRQ_HANDLER
 	select NEED_MACH_GPIO_H
 	select NEED_MACH_IO_H
+	select SAMSUNG_ATAGS
 	help
 	  Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443
 	  and S3C2450 SoCs based systems, such as the Simtec Electronics BAST
@@ -717,6 +726,7 @@ config ARCH_S3C64XX
 	select CLKSRC_MMIO
 	select CPU_V6
 	select GENERIC_CLOCKEVENTS
+	select GPIO_SAMSUNG
 	select HAVE_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -726,9 +736,11 @@ config ARCH_S3C64XX
 	select PLAT_SAMSUNG
 	select S3C_DEV_NAND
 	select S3C_GPIO_TRACK
+	select SAMSUNG_ATAGS
 	select SAMSUNG_CLKSRC
 	select SAMSUNG_GPIOLIB_4BIT
 	select SAMSUNG_IRQ_VIC_TIMER
+	select SAMSUNG_WDT_RESET
 	select USB_ARCH_HAS_OHCI
 	help
 	  Samsung S3C64XX series based systems
@@ -739,11 +751,14 @@ config ARCH_S5P64X0
 	select CLKSRC_MMIO
 	select CPU_V6
 	select GENERIC_CLOCKEVENTS
+	select GPIO_SAMSUNG
 	select HAVE_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
 	select NEED_MACH_GPIO_H
+	select SAMSUNG_WDT_RESET
+	select SAMSUNG_ATAGS
 	help
 	  Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
 	  SMDK6450.
@@ -755,11 +770,14 @@ config ARCH_S5PC100
 	select CLKSRC_MMIO
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
+	select GPIO_SAMSUNG
 	select HAVE_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
 	select NEED_MACH_GPIO_H
+	select SAMSUNG_WDT_RESET
+	select SAMSUNG_ATAGS
 	help
 	  Samsung S5PC100 series based systems
 
@@ -772,12 +790,14 @@ config ARCH_S5PV210
 	select CLKSRC_MMIO
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
+	select GPIO_SAMSUNG
 	select HAVE_CLK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
 	select NEED_MACH_GPIO_H
 	select NEED_MACH_MEMORY_H
+	select SAMSUNG_ATAGS
 	help
 	  Samsung S5PV210/S5PC110 series based systems
 
@@ -785,7 +805,9 @@ config ARCH_EXYNOS
 	bool "Samsung EXYNOS"
 	select ARCH_HAS_CPUFREQ
 	select ARCH_HAS_HOLES_MEMORYMODEL
+	select ARCH_REQUIRE_GPIOLIB
 	select ARCH_SPARSEMEM_ENABLE
+	select ARM_GIC
 	select CLKDEV_LOOKUP
 	select COMMON_CLK
 	select CPU_V7
@@ -794,8 +816,9 @@ config ARCH_EXYNOS
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select HAVE_S3C_RTC if RTC_CLASS
-	select NEED_MACH_GPIO_H
 	select NEED_MACH_MEMORY_H
+	select SPARSE_IRQ
+	select USE_OF
 	help
 	  Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5)
 
@@ -813,23 +836,6 @@ config ARCH_SHARK
 	  Support for the StrongARM based Digital DNARD machine, also known
 	  as "Shark" (<http://www.shark-linux.de/shark.html>).
 
-config ARCH_U300
-	bool "ST-Ericsson U300 Series"
-	depends on MMU
-	select ARCH_REQUIRE_GPIOLIB
-	select ARM_AMBA
-	select ARM_PATCH_PHYS_VIRT
-	select ARM_VIC
-	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
-	select COMMON_CLK
-	select CPU_ARM926T
-	select GENERIC_CLOCKEVENTS
-	select HAVE_TCM
-	select SPARSE_IRQ
-	help
-	  Support for ST-Ericsson U300 series mobile platforms.
-
 config ARCH_DAVINCI
 	bool "TI DaVinci"
 	select ARCH_HAS_HOLES_MEMORYMODEL
@@ -840,6 +846,7 @@ config ARCH_DAVINCI
 	select GENERIC_IRQ_CHIP
 	select HAVE_IDE
 	select NEED_MACH_GPIO_H
+	select TI_PRIV_EDMA
 	select USE_OF
 	select ZONE_DMA
 	help
@@ -871,20 +878,21 @@ menu "Multiple platform selection"
 
 comment "CPU Core family selection"
 
-config ARCH_MULTI_V4
-	bool "ARMv4 based platforms (FA526, StrongARM)"
-	depends on !ARCH_MULTI_V6_V7
-	select ARCH_MULTI_V4_V5
-
 config ARCH_MULTI_V4T
 	bool "ARMv4T based platforms (ARM720T, ARM920T, ...)"
 	depends on !ARCH_MULTI_V6_V7
 	select ARCH_MULTI_V4_V5
+	select CPU_ARM920T if !(CPU_ARM7TDMI || CPU_ARM720T || \
+		CPU_ARM740T || CPU_ARM9TDMI || CPU_ARM922T || \
+		CPU_ARM925T || CPU_ARM940T)
 
 config ARCH_MULTI_V5
 	bool "ARMv5 based platforms (ARM926T, XSCALE, PJ1, ...)"
 	depends on !ARCH_MULTI_V6_V7
 	select ARCH_MULTI_V4_V5
+	select CPU_ARM926T if (!CPU_ARM946E || CPU_ARM1020 || \
+		CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \
+		CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_FEROCEON)
 
 config ARCH_MULTI_V4_V5
 	bool
@@ -948,6 +956,8 @@ source "arch/arm/mach-iop13xx/Kconfig"
 
 source "arch/arm/mach-ixp4xx/Kconfig"
 
+source "arch/arm/mach-keystone/Kconfig"
+
 source "arch/arm/mach-kirkwood/Kconfig"
 
 source "arch/arm/mach-ks8695/Kconfig"
@@ -964,6 +974,8 @@ source "arch/arm/mach-netx/Kconfig"
 
 source "arch/arm/mach-nomadik/Kconfig"
 
+source "arch/arm/mach-nspire/Kconfig"
+
 source "arch/arm/plat-omap/Kconfig"
 
 source "arch/arm/mach-omap1/Kconfig"
@@ -981,6 +993,8 @@ source "arch/arm/mach-mmp/Kconfig"
 
 source "arch/arm/mach-realview/Kconfig"
 
+source "arch/arm/mach-rockchip/Kconfig"
+
 source "arch/arm/mach-sa1100/Kconfig"
 
 source "arch/arm/plat-samsung/Kconfig"
@@ -989,6 +1003,8 @@ source "arch/arm/mach-socfpga/Kconfig"
 
 source "arch/arm/mach-spear/Kconfig"
 
+source "arch/arm/mach-sti/Kconfig"
+
 source "arch/arm/mach-s3c24xx/Kconfig"
 
 if ARCH_S3C64XX
@@ -1300,7 +1316,7 @@ config ARM_ERRATA_754327
 
 config ARM_ERRATA_364296
 	bool "ARM errata: Possible cache data corruption with hit-under-miss enabled"
-	depends on CPU_V6 && !SMP
+	depends on CPU_V6
 	help
 	  This options enables the workaround for the 364296 ARM1136
 	  r0p2 erratum (possible cache data corruption with
@@ -1417,6 +1433,7 @@ config PCI_HOST_ITE8152
 	select DMABOUNCE
 
 source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pcmcia/Kconfig"
 
@@ -1438,7 +1455,7 @@ config SMP
 	depends on CPU_V6K || CPU_V7
 	depends on GENERIC_CLOCKEVENTS
 	depends on HAVE_SMP
-	depends on MMU
+	depends on MMU || ARM_MPU
 	select USE_GENERIC_SMP_HELPERS
 	help
 	  This enables support for systems with more than one CPU. If you have
@@ -1459,7 +1476,7 @@ config SMP
 
 config SMP_ON_UP
 	bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
-	depends on SMP && !XIP_KERNEL
+	depends on SMP && !XIP_KERNEL && MMU
 	default y
 	help
 	  SMP kernels contain instructions which fail on non-SMP processors.
@@ -1552,7 +1569,7 @@ config NR_CPUS
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
-	depends on SMP && HOTPLUG
+	depends on SMP
 	help
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
@@ -1583,7 +1600,7 @@ config LOCAL_TIMERS
 config ARCH_NR_GPIO
 	int
 	default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
-	default 512 if SOC_OMAP5
+	default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5
 	default 392 if ARCH_U8500
 	default 352 if ARCH_VT8500
 	default 288 if ARCH_SUNXI
@@ -1609,7 +1626,7 @@ config SCHED_HRTICK
 
 config THUMB2_KERNEL
 	bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY
-	depends on CPU_V7 && !CPU_V6 && !CPU_V6K
+	depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K
 	default y if CPU_THUMBONLY
 	select AEABI
 	select ARM_ASM_UNIFIED
@@ -1731,6 +1748,14 @@ config HW_PERF_EVENTS
 	  Enable hardware performance counter support for perf events. If
 	  disabled, perf events will use software events only.
 
+config SYS_SUPPORTS_HUGETLBFS
+       def_bool y
+       depends on ARM_LPAE
+
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
+       def_bool y
+       depends on ARM_LPAE
+
 source "mm/Kconfig"
 
 config FORCE_MAX_ZONEORDER
@@ -2064,7 +2089,7 @@ config CRASH_DUMP
 
 config AUTO_ZRELADDR
 	bool "Auto calculation of the decompressed kernel image address"
-	depends on !ZBOOT_ROM && !ARCH_U300
+	depends on !ZBOOT_ROM
 	help
 	  ZRELADDR is the physical address where the decompressed kernel
 	  image will be placed. If AUTO_ZRELADDR is selected, the address
@@ -2078,53 +2103,6 @@ menu "CPU Power Management"
 
 if ARCH_HAS_CPUFREQ
 source "drivers/cpufreq/Kconfig"
-
-config CPU_FREQ_S3C
-	bool
-	help
-	  Internal configuration node for common cpufreq on Samsung SoC
-
-config CPU_FREQ_S3C24XX
-	bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
-	depends on ARCH_S3C24XX && CPU_FREQ
-	select CPU_FREQ_S3C
-	help
-	  This enables the CPUfreq driver for the Samsung S3C24XX family
-	  of CPUs.
-
-	  For details, take a look at <file:Documentation/cpu-freq>.
-
-	  If in doubt, say N.
-
-config CPU_FREQ_S3C24XX_PLL
-	bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
-	depends on CPU_FREQ_S3C24XX
-	help
-	  Compile in support for changing the PLL frequency from the
-	  S3C24XX series CPUfreq driver. The PLL takes time to settle
-	  after a frequency change, so by default it is not enabled.
-
-	  This also means that the PLL tables for the selected CPU(s) will
-	  be built which may increase the size of the kernel image.
-
-config CPU_FREQ_S3C24XX_DEBUG
-	bool "Debug CPUfreq Samsung driver core"
-	depends on CPU_FREQ_S3C24XX
-	help
-	  Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
-
-config CPU_FREQ_S3C24XX_IODEBUG
-	bool "Debug CPUfreq Samsung driver IO timing"
-	depends on CPU_FREQ_S3C24XX
-	help
-	  Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
-
-config CPU_FREQ_S3C24XX_DEBUGFS
-	bool "Export debugfs for CPUFreq"
-	depends on CPU_FREQ_S3C24XX && DEBUG_FS
-	help
-	  Export status information via debugfs.
-
 endif
 
 source "drivers/cpuidle/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/arm/Kconfig.debug
--- linux-libre-3.10-gnu/arch/arm/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -251,6 +251,27 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX6Q/DL.
 
+	config DEBUG_IMX6SL_UART
+		bool "i.MX6SL Debug UART"
+		depends on SOC_IMX6SL
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on i.MX6SL.
+
+	config DEBUG_KEYSTONE_UART0
+		bool "Kernel low-level debugging on KEYSTONE2 using UART0"
+		depends on ARCH_KEYSTONE
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to UART0 serial port on KEYSTONE2 devices.
+
+	config DEBUG_KEYSTONE_UART1
+		bool "Kernel low-level debugging on KEYSTONE2 using UART1"
+		depends on ARCH_KEYSTONE
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to UART1 serial port on KEYSTONE2 devices.
+
 	config DEBUG_MMP_UART2
 		bool "Kernel low-level debugging message via MMP UART2"
 		depends on ARCH_MMP
@@ -303,12 +324,37 @@ choice
 		  their output to the serial port on MSM 8960 devices.
 
 	config DEBUG_MVEBU_UART
-		bool "Kernel low-level debugging messages via MVEBU UART"
+		bool "Kernel low-level debugging messages via MVEBU UART (old bootloaders)"
+		depends on ARCH_MVEBU
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on MVEBU based platforms.
+
+		  This option should be used with the old bootloaders
+		  that left the internal registers mapped at
+		  0xd0000000. As of today, this is the case on
+		  platforms such as the Globalscale Mirabox or the
+		  Plathome OpenBlocks AX3, when using the original
+		  bootloader.
+
+		  If the wrong DEBUG_MVEBU_UART* option is selected,
+		  when u-boot hands over to the kernel, the system
+		  silently crashes, with no serial output at all.
+
+	config DEBUG_MVEBU_UART_ALTERNATE
+		bool "Kernel low-level debugging messages via MVEBU UART (new bootloaders)"
 		depends on ARCH_MVEBU
 		help
 		  Say Y here if you want kernel low-level debugging support
 		  on MVEBU based platforms.
 
+		  This option should be used with the new bootloaders
+		  that remap the internal registers at 0xf1000000.
+
+		  If the wrong DEBUG_MVEBU_UART* option is selected,
+		  when u-boot hands over to the kernel, the system
+		  silently crashes, with no serial output at all.
+
 	config DEBUG_NOMADIK_UART
 		bool "Kernel low-level debugging messages via NOMADIK UART"
 		depends on ARCH_NOMADIK
@@ -316,6 +362,20 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on NOMADIK based platforms.
 
+	config DEBUG_NSPIRE_CLASSIC_UART
+		bool "Kernel low-level debugging via TI-NSPIRE 8250 UART"
+		depends on ARCH_NSPIRE
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on TI-NSPIRE classic models.
+
+	config DEBUG_NSPIRE_CX_UART
+		bool "Kernel low-level debugging via TI-NSPIRE PL011 UART"
+		depends on ARCH_NSPIRE
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on TI-NSPIRE CX models.
+
 	config DEBUG_OMAP2PLUS_UART
 		bool "Kernel low-level debugging messages via OMAP2PLUS UART"
 		depends on ARCH_OMAP2PLUS
@@ -353,6 +413,13 @@ choice
 		  their output to the standard serial port on the RealView
 		  PB1176 platform.
 
+	config DEBUG_ROCKCHIP_UART
+		bool "Kernel low-level debugging messages via Rockchip UART"
+		depends on ARCH_ROCKCHIP
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on Rockchip based platforms.
+
 	config DEBUG_S3C_UART0
 		depends on PLAT_SAMSUNG
 		select DEBUG_EXYNOS_UART if ARCH_EXYNOS
@@ -443,6 +510,23 @@ choice
 		  Say Y here if you want the debug print routines to direct
 		  their output to the uart1 port on SiRFmarco devices.
 
+	config DEBUG_STI_UART
+		depends on ARCH_STI
+		bool "Use StiH415/416 ASC for low-level debug"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on StiH415/416 based platforms like B2000, B2020.
+		  It support UART2 and SBC_UART1.
+
+		  If unsure, say N.
+
+	config DEBUG_U300_UART
+		bool "Kernel low-level debugging messages via U300 UART0"
+		depends on ARCH_U300
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the uart port on U300 devices.
+
 	config DEBUG_UX500_UART
 		depends on ARCH_U8500
 		bool "Use Ux500 UART for low-level debug"
@@ -476,6 +560,13 @@ choice
 		  of the tiles using the RS1 memory map, including all new A-class
 		  core tiles, FPGA-based SMMs and software models.
 
+	config DEBUG_VEXPRESS_UART0_CRX
+		bool "Use PL011 UART0 at 0xb0090000 (Cortex-R compliant tiles)"
+		depends on ARCH_VEXPRESS && !MMU
+		help
+		  This option selects UART0 at 0xb0090000. This is appropriate for
+		  Cortex-R series tiles and SMMs, such as Cortex-R5 and Cortex-R7
+
 	config DEBUG_VT8500_UART0
 		bool "Use UART0 on VIA/Wondermedia SoCs"
 		depends on ARCH_VT8500
@@ -532,7 +623,8 @@ config DEBUG_IMX_UART_PORT
 						DEBUG_IMX35_UART || \
 						DEBUG_IMX51_UART || \
 						DEBUG_IMX53_UART || \
-						DEBUG_IMX6Q_UART
+						DEBUG_IMX6Q_UART || \
+						DEBUG_IMX6SL_UART
 	default 1
 	depends on ARCH_MXC
 	help
@@ -589,6 +681,32 @@ endchoice
 
 choice
 	prompt "Low-level debug console UART"
+	depends on DEBUG_ROCKCHIP_UART
+
+	config DEBUG_RK29_UART0
+		bool "RK29 UART0"
+
+	config DEBUG_RK29_UART1
+		bool "RK29 UART1"
+
+	config DEBUG_RK29_UART2
+		bool "RK29 UART2"
+
+	config DEBUG_RK3X_UART0
+		bool "RK3X UART0"
+
+	config DEBUG_RK3X_UART1
+		bool "RK3X UART1"
+
+	config DEBUG_RK3X_UART2
+		bool "RK3X UART2"
+
+	config DEBUG_RK3X_UART3
+		bool "RK3X UART3"
+endchoice
+
+choice
+	prompt "Low-level debug console UART"
 	depends on DEBUG_LL && DEBUG_TEGRA_UART
 
 	config TEGRA_DEBUG_UART_AUTO_ODMDATA
@@ -617,6 +735,30 @@ choice
 
 endchoice
 
+choice
+	prompt "Low-level debug console UART"
+	depends on DEBUG_LL && DEBUG_STI_UART
+
+	config STIH41X_DEBUG_ASC2
+		bool "ASC2 UART"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on STiH415/416 based platforms like b2000, which has
+		  default UART wired up to ASC2.
+
+		  If unsure, say N.
+
+	config STIH41X_DEBUG_SBC_ASC1
+		bool "SBC ASC1 UART"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on STiH415/416 based platforms like b2020. which has
+		  default UART wired up to SBC ASC1.
+
+		  If unsure, say N.
+
+endchoice
+
 config DEBUG_LL_INCLUDE
 	string
 	default "debug/bcm2835.S" if DEBUG_BCM2835
@@ -631,30 +773,50 @@ config DEBUG_LL_INCLUDE
 				 DEBUG_IMX35_UART || \
 				 DEBUG_IMX51_UART || \
 				 DEBUG_IMX53_UART ||\
-				 DEBUG_IMX6Q_UART
-	default "debug/mvebu.S" if DEBUG_MVEBU_UART
+				 DEBUG_IMX6Q_UART || \
+				 DEBUG_IMX6SL_UART
+	default "debug/keystone.S" if DEBUG_KEYSTONE_UART0 || \
+				      DEBUG_KEYSTONE_UART1
+	default "debug/mvebu.S" if DEBUG_MVEBU_UART || \
+				   DEBUG_MVEBU_UART_ALTERNATE
 	default "debug/mxs.S" if DEBUG_IMX23_UART || DEBUG_IMX28_UART
 	default "debug/nomadik.S" if DEBUG_NOMADIK_UART
+	default "debug/nspire.S" if 	DEBUG_NSPIRE_CX_UART || \
+					DEBUG_NSPIRE_CLASSIC_UART
 	default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
 	default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART
 	default "debug/pxa.S" if DEBUG_PXA_UART1 || DEBUG_MMP_UART2 || \
 				 DEBUG_MMP_UART3
+	default "debug/rockchip.S" if DEBUG_ROCKCHIP_UART
 	default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
 	default "debug/socfpga.S" if DEBUG_SOCFPGA_UART
+	default "debug/sti.S" if DEBUG_STI_UART
 	default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1
 	default "debug/tegra.S" if DEBUG_TEGRA_UART
+	default "debug/u300.S" if DEBUG_U300_UART
 	default "debug/ux500.S" if DEBUG_UX500_UART
 	default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \
-		DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1
+		DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 || \
+		DEBUG_VEXPRESS_UART0_CRX
 	default "debug/vt8500.S" if DEBUG_VT8500_UART0
 	default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
 	default "mach/debug-macro.S"
 
 config DEBUG_UNCOMPRESS
 	bool
-	default y if ARCH_MULTIPLATFORM && DEBUG_LL && \
-		     !DEBUG_OMAP2PLUS_UART && \
+	depends on ARCH_MULTIPLATFORM
+	default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
 		     !DEBUG_TEGRA_UART
+	help
+	  This option influences the normal decompressor output for
+	  multiplatform kernels.  Normally, multiplatform kernels disable
+	  decompressor output because it is not possible to know where to
+	  send the decompressor output.
+
+	  When this option is set, the selected DEBUG_LL output method
+	  will be re-used for normal decompressor output on multiplatform
+	  kernels.
+	  
 
 config UNCOMPRESS_INCLUDE
 	string
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/Kconfig-nommu linux-libre-3.11-rc7-gnu/arch/arm/Kconfig-nommu
--- linux-libre-3.10-gnu/arch/arm/Kconfig-nommu	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/Kconfig-nommu	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,7 @@ config FLASH_SIZE
 config PROCESSOR_ID
 	hex 'Hard wire the processor ID'
 	default 0x00007700
-	depends on !CPU_CP15
+	depends on !(CPU_CP15 || CPU_V7M)
 	help
 	  If processor has no CP15 register, this processor ID is
 	  used instead of the auto-probing which utilizes the register.
@@ -50,3 +50,15 @@ config REMAP_VECTORS_TO_RAM
 	  Otherwise, say 'y' here.  In this case, the kernel will require
 	  external support to redirect the hardware exception vectors to
 	  the writable versions located at DRAM_BASE.
+
+config ARM_MPU
+       bool 'Use the ARM v7 PMSA Compliant MPU'
+       depends on CPU_V7
+       default y
+       help
+         Some ARM systems without an MMU have instead a Memory Protection
+         Unit (MPU) that defines the type and permissions for regions of
+         memory.
+
+         If your CPU has an MPU then you should choose 'y' here unless you
+         know that you do not want to use the MPU.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/arch_timer.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/arch_timer.c
--- linux-libre-3.10-gnu/arch/arm/kernel/arch_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/arch_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,9 +11,9 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/sched_clock.h>
 
 #include <asm/delay.h>
-#include <asm/sched_clock.h>
 
 #include <clocksource/arm_arch_timer.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/asm-offsets.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/asm-offsets.c
--- linux-libre-3.10-gnu/arch/arm/kernel/asm-offsets.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/asm-offsets.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,7 @@
 #include <asm/thread_info.h>
 #include <asm/memory.h>
 #include <asm/procinfo.h>
+#include <asm/suspend.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <linux/kbuild.h>
 
@@ -145,6 +146,11 @@ int main(void)
 #ifdef MULTI_CACHE
   DEFINE(CACHE_FLUSH_KERN_ALL,	offsetof(struct cpu_cache_fns, flush_kern_all));
 #endif
+#ifdef CONFIG_ARM_CPU_SUSPEND
+  DEFINE(SLEEP_SAVE_SP_SZ,	sizeof(struct sleep_save_sp));
+  DEFINE(SLEEP_SAVE_SP_PHYS,	offsetof(struct sleep_save_sp, save_ptr_stash_phys));
+  DEFINE(SLEEP_SAVE_SP_VIRT,	offsetof(struct sleep_save_sp, save_ptr_stash));
+#endif
   BLANK();
   DEFINE(DMA_BIDIRECTIONAL,	DMA_BIDIRECTIONAL);
   DEFINE(DMA_TO_DEVICE,		DMA_TO_DEVICE);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/bios32.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/bios32.c
--- linux-libre-3.10-gnu/arch/arm/kernel/bios32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/bios32.c	2013-08-25 20:43:22.000000000 -0400
@@ -445,7 +445,8 @@ static int pcibios_init_resources(int bu
 	return 0;
 }
 
-static void pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
+static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
+			    struct list_head *head)
 {
 	struct pci_sys_data *sys = NULL;
 	int ret;
@@ -480,7 +481,7 @@ static void pcibios_init_hw(struct hw_pc
 			if (hw->scan)
 				sys->bus = hw->scan(nr, sys);
 			else
-				sys->bus = pci_scan_root_bus(NULL, sys->busnr,
+				sys->bus = pci_scan_root_bus(parent, sys->busnr,
 						hw->ops, sys, &sys->resources);
 
 			if (!sys->bus)
@@ -497,7 +498,7 @@ static void pcibios_init_hw(struct hw_pc
 	}
 }
 
-void pci_common_init(struct hw_pci *hw)
+void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
 {
 	struct pci_sys_data *sys;
 	LIST_HEAD(head);
@@ -505,7 +506,7 @@ void pci_common_init(struct hw_pci *hw)
 	pci_add_flags(PCI_REASSIGN_ALL_RSRC);
 	if (hw->preinit)
 		hw->preinit();
-	pcibios_init_hw(hw, &head);
+	pcibios_init_hw(parent, hw, &head);
 	if (hw->postinit)
 		hw->postinit();
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/entry-armv.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/entry-armv.S
--- linux-libre-3.10-gnu/arch/arm/kernel/entry-armv.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/entry-armv.S	2013-08-25 20:43:22.000000000 -0400
@@ -357,7 +357,8 @@ ENDPROC(__pabt_svc)
 	.endm
 
 	.macro	kuser_cmpxchg_check
-#if !defined(CONFIG_CPU_32v6K) && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \
+    !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
 #ifndef CONFIG_MMU
 #warning "NPTL on non MMU needs fixing"
 #else
@@ -685,15 +686,16 @@ ENTRY(__switch_to)
  UNWIND(.fnstart	)
  UNWIND(.cantunwind	)
 	add	ip, r1, #TI_CPU_SAVE
-	ldr	r3, [r2, #TI_TP_VALUE]
  ARM(	stmia	ip!, {r4 - sl, fp, sp, lr} )	@ Store most regs on stack
  THUMB(	stmia	ip!, {r4 - sl, fp}	   )	@ Store most regs on stack
  THUMB(	str	sp, [ip], #4		   )
  THUMB(	str	lr, [ip], #4		   )
+	ldr	r4, [r2, #TI_TP_VALUE]
+	ldr	r5, [r2, #TI_TP_VALUE + 4]
 #ifdef CONFIG_CPU_USE_DOMAINS
 	ldr	r6, [r2, #TI_CPU_DOMAIN]
 #endif
-	set_tls	r3, r4, r5
+	switch_tls r1, r4, r5, r3, r7
 #if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
 	ldr	r7, [r2, #TI_TASK]
 	ldr	r8, =__stack_chk_guard
@@ -741,6 +743,18 @@ ENDPROC(__switch_to)
 #endif
 	.endm
 
+	.macro	kuser_pad, sym, size
+	.if	(. - \sym) & 3
+	.rept	4 - (. - \sym) & 3
+	.byte	0
+	.endr
+	.endif
+	.rept	(\size - (. - \sym)) / 4
+	.word	0xe7fddef1
+	.endr
+	.endm
+
+#ifdef CONFIG_KUSER_HELPERS
 	.align	5
 	.globl	__kuser_helper_start
 __kuser_helper_start:
@@ -831,18 +845,13 @@ kuser_cmpxchg64_fixup:
 #error "incoherent kernel configuration"
 #endif
 
-	/* pad to next slot */
-	.rept	(16 - (. - __kuser_cmpxchg64)/4)
-	.word	0
-	.endr
-
-	.align	5
+	kuser_pad __kuser_cmpxchg64, 64
 
 __kuser_memory_barrier:				@ 0xffff0fa0
 	smp_dmb	arm
 	usr_ret	lr
 
-	.align	5
+	kuser_pad __kuser_memory_barrier, 32
 
 __kuser_cmpxchg:				@ 0xffff0fc0
 
@@ -915,13 +924,14 @@ kuser_cmpxchg32_fixup:
 
 #endif
 
-	.align	5
+	kuser_pad __kuser_cmpxchg, 32
 
 __kuser_get_tls:				@ 0xffff0fe0
 	ldr	r0, [pc, #(16 - 8)]	@ read TLS, set in kuser_get_tls_init
 	usr_ret	lr
 	mrc	p15, 0, r0, c13, c0, 3	@ 0xffff0fe8 hardware TLS code
-	.rep	4
+	kuser_pad __kuser_get_tls, 16
+	.rep	3
 	.word	0			@ 0xffff0ff0 software TLS value, then
 	.endr				@ pad up to __kuser_helper_version
 
@@ -931,14 +941,16 @@ __kuser_helper_version:				@ 0xffff0ffc
 	.globl	__kuser_helper_end
 __kuser_helper_end:
 
+#endif
+
  THUMB(	.thumb	)
 
 /*
  * Vector stubs.
  *
- * This code is copied to 0xffff0200 so we can use branches in the
- * vectors, rather than ldr's.  Note that this code must not
- * exceed 0x300 bytes.
+ * This code is copied to 0xffff1000 so we can use branches in the
+ * vectors, rather than ldr's.  Note that this code must not exceed
+ * a page size.
  *
  * Common stub entry macro:
  *   Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
@@ -985,8 +997,17 @@ ENDPROC(vector_\name)
 1:
 	.endm
 
-	.globl	__stubs_start
+	.section .stubs, "ax", %progbits
 __stubs_start:
+	@ This must be the first word
+	.word	vector_swi
+
+vector_rst:
+ ARM(	swi	SYS_ERROR0	)
+ THUMB(	svc	#0		)
+ THUMB(	nop			)
+	b	vector_und
+
 /*
  * Interrupt dispatcher
  */
@@ -1081,6 +1102,16 @@ __stubs_start:
 	.align	5
 
 /*=============================================================================
+ * Address exception handler
+ *-----------------------------------------------------------------------------
+ * These aren't too critical.
+ * (they're not supposed to happen, and won't happen in 32-bit data mode).
+ */
+
+vector_addrexcptn:
+	b	vector_addrexcptn
+
+/*=============================================================================
  * Undefined FIQs
  *-----------------------------------------------------------------------------
  * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
@@ -1093,45 +1124,19 @@ __stubs_start:
 vector_fiq:
 	subs	pc, lr, #4
 
-/*=============================================================================
- * Address exception handler
- *-----------------------------------------------------------------------------
- * These aren't too critical.
- * (they're not supposed to happen, and won't happen in 32-bit data mode).
- */
-
-vector_addrexcptn:
-	b	vector_addrexcptn
-
-/*
- * We group all the following data together to optimise
- * for CPUs with separate I & D caches.
- */
-	.align	5
-
-.LCvswi:
-	.word	vector_swi
-
-	.globl	__stubs_end
-__stubs_end:
-
-	.equ	stubs_offset, __vectors_start + 0x200 - __stubs_start
+	.globl	vector_fiq_offset
+	.equ	vector_fiq_offset, vector_fiq
 
-	.globl	__vectors_start
+	.section .vectors, "ax", %progbits
 __vectors_start:
- ARM(	swi	SYS_ERROR0	)
- THUMB(	svc	#0		)
- THUMB(	nop			)
-	W(b)	vector_und + stubs_offset
-	W(ldr)	pc, .LCvswi + stubs_offset
-	W(b)	vector_pabt + stubs_offset
-	W(b)	vector_dabt + stubs_offset
-	W(b)	vector_addrexcptn + stubs_offset
-	W(b)	vector_irq + stubs_offset
-	W(b)	vector_fiq + stubs_offset
-
-	.globl	__vectors_end
-__vectors_end:
+	W(b)	vector_rst
+	W(b)	vector_und
+	W(ldr)	pc, __vectors_start + 0x1000
+	W(b)	vector_pabt
+	W(b)	vector_dabt
+	W(b)	vector_addrexcptn
+	W(b)	vector_irq
+	W(b)	vector_fiq
 
 	.data
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/entry-common.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/entry-common.S
--- linux-libre-3.10-gnu/arch/arm/kernel/entry-common.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/entry-common.S	2013-08-25 20:43:22.000000000 -0400
@@ -350,6 +350,9 @@ ENDPROC(ftrace_stub)
 
 	.align	5
 ENTRY(vector_swi)
+#ifdef CONFIG_CPU_V7M
+	v7m_exception_entry
+#else
 	sub	sp, sp, #S_FRAME_SIZE
 	stmia	sp, {r0 - r12}			@ Calling r0 - r12
  ARM(	add	r8, sp, #S_PC		)
@@ -360,8 +363,19 @@ ENTRY(vector_swi)
 	str	lr, [sp, #S_PC]			@ Save calling PC
 	str	r8, [sp, #S_PSR]		@ Save CPSR
 	str	r0, [sp, #S_OLD_R0]		@ Save OLD_R0
+#endif
 	zero_fp
 
+#ifdef CONFIG_ALIGNMENT_TRAP
+	ldr	ip, __cr_alignment
+	ldr	ip, [ip]
+	mcr	p15, 0, ip, c1, c0		@ update control register
+#endif
+
+	enable_irq
+	ct_user_exit
+	get_thread_info tsk
+
 	/*
 	 * Get the system call number.
 	 */
@@ -375,9 +389,9 @@ ENTRY(vector_swi)
 #ifdef CONFIG_ARM_THUMB
 	tst	r8, #PSR_T_BIT
 	movne	r10, #0				@ no thumb OABI emulation
-	ldreq	r10, [lr, #-4]			@ get SWI instruction
+ USER(	ldreq	r10, [lr, #-4]		)	@ get SWI instruction
 #else
-	ldr	r10, [lr, #-4]			@ get SWI instruction
+ USER(	ldr	r10, [lr, #-4]		)	@ get SWI instruction
 #endif
 #ifdef CONFIG_CPU_ENDIAN_BE8
 	rev	r10, r10			@ little endian instruction
@@ -392,22 +406,13 @@ ENTRY(vector_swi)
 	/* Legacy ABI only, possibly thumb mode. */
 	tst	r8, #PSR_T_BIT			@ this is SPSR from save_user_regs
 	addne	scno, r7, #__NR_SYSCALL_BASE	@ put OS number in
-	ldreq	scno, [lr, #-4]
+ USER(	ldreq	scno, [lr, #-4]		)
 
 #else
 	/* Legacy ABI only. */
-	ldr	scno, [lr, #-4]			@ get SWI instruction
-#endif
-
-#ifdef CONFIG_ALIGNMENT_TRAP
-	ldr	ip, __cr_alignment
-	ldr	ip, [ip]
-	mcr	p15, 0, ip, c1, c0		@ update control register
+ USER(	ldr	scno, [lr, #-4]		)	@ get SWI instruction
 #endif
-	enable_irq
-	ct_user_exit
 
-	get_thread_info tsk
 	adr	tbl, sys_call_table		@ load syscall table pointer
 
 #if defined(CONFIG_OABI_COMPAT)
@@ -442,6 +447,21 @@ local_restart:
 	eor	r0, scno, #__NR_SYSCALL_BASE	@ put OS number back
 	bcs	arm_syscall	
 	b	sys_ni_syscall			@ not private func
+
+#if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI)
+	/*
+	 * We failed to handle a fault trying to access the page
+	 * containing the swi instruction, but we're not really in a
+	 * position to return -EFAULT. Instead, return back to the
+	 * instruction and re-enter the user fault handling path trying
+	 * to page it in. This will likely result in sending SEGV to the
+	 * current task.
+	 */
+9001:
+	sub	lr, lr, #4
+	str	lr, [sp, #S_PC]
+	b	ret_fast_syscall
+#endif
 ENDPROC(vector_swi)
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/entry-header.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/entry-header.S
--- linux-libre-3.10-gnu/arch/arm/kernel/entry-header.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/entry-header.S	2013-08-25 20:43:22.000000000 -0400
@@ -5,6 +5,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/errno.h>
 #include <asm/thread_info.h>
+#include <asm/v7m.h>
 
 @ Bad Abort numbers
 @ -----------------
@@ -44,6 +45,116 @@
 #endif
 	.endm
 
+#ifdef CONFIG_CPU_V7M
+/*
+ * ARMv7-M exception entry/exit macros.
+ *
+ * xPSR, ReturnAddress(), LR (R14), R12, R3, R2, R1, and R0 are
+ * automatically saved on the current stack (32 words) before
+ * switching to the exception stack (SP_main).
+ *
+ * If exception is taken while in user mode, SP_main is
+ * empty. Otherwise, SP_main is aligned to 64 bit automatically
+ * (CCR.STKALIGN set).
+ *
+ * Linux assumes that the interrupts are disabled when entering an
+ * exception handler and it may BUG if this is not the case. Interrupts
+ * are disabled during entry and reenabled in the exit macro.
+ *
+ * v7m_exception_slow_exit is used when returning from SVC or PendSV.
+ * When returning to kernel mode, we don't return from exception.
+ */
+	.macro	v7m_exception_entry
+	@ determine the location of the registers saved by the core during
+	@ exception entry. Depending on the mode the cpu was in when the
+	@ exception happend that is either on the main or the process stack.
+	@ Bit 2 of EXC_RETURN stored in the lr register specifies which stack
+	@ was used.
+	tst	lr, #EXC_RET_STACK_MASK
+	mrsne	r12, psp
+	moveq	r12, sp
+
+	@ we cannot rely on r0-r3 and r12 matching the value saved in the
+	@ exception frame because of tail-chaining. So these have to be
+	@ reloaded.
+	ldmia	r12!, {r0-r3}
+
+	@ Linux expects to have irqs off. Do it here before taking stack space
+	cpsid	i
+
+	sub	sp, #S_FRAME_SIZE-S_IP
+	stmdb	sp!, {r0-r11}
+
+	@ load saved r12, lr, return address and xPSR.
+	@ r0-r7 are used for signals and never touched from now on. Clobbering
+	@ r8-r12 is OK.
+	mov	r9, r12
+	ldmia	r9!, {r8, r10-r12}
+
+	@ calculate the original stack pointer value.
+	@ r9 currently points to the memory location just above the auto saved
+	@ xPSR.
+	@ The cpu might automatically 8-byte align the stack. Bit 9
+	@ of the saved xPSR specifies if stack aligning took place. In this case
+	@ another 32-bit value is included in the stack.
+
+	tst	r12, V7M_xPSR_FRAMEPTRALIGN
+	addne	r9, r9, #4
+
+	@ store saved r12 using str to have a register to hold the base for stm
+	str	r8, [sp, #S_IP]
+	add	r8, sp, #S_SP
+	@ store r13-r15, xPSR
+	stmia	r8!, {r9-r12}
+	@ store old_r0
+	str	r0, [r8]
+	.endm
+
+        /*
+	 * PENDSV and SVCALL are configured to have the same exception
+	 * priorities. As a kernel thread runs at SVCALL execution priority it
+	 * can never be preempted and so we will never have to return to a
+	 * kernel thread here.
+         */
+	.macro	v7m_exception_slow_exit ret_r0
+	cpsid	i
+	ldr	lr, =EXC_RET_THREADMODE_PROCESSSTACK
+
+	@ read original r12, sp, lr, pc and xPSR
+	add	r12, sp, #S_IP
+	ldmia	r12, {r1-r5}
+
+	@ an exception frame is always 8-byte aligned. To tell the hardware if
+	@ the sp to be restored is aligned or not set bit 9 of the saved xPSR
+	@ accordingly.
+	tst	r2, #4
+	subne	r2, r2, #4
+	orrne	r5, V7M_xPSR_FRAMEPTRALIGN
+	biceq	r5, V7M_xPSR_FRAMEPTRALIGN
+
+	@ write basic exception frame
+	stmdb	r2!, {r1, r3-r5}
+	ldmia	sp, {r1, r3-r5}
+	.if	\ret_r0
+	stmdb	r2!, {r0, r3-r5}
+	.else
+	stmdb	r2!, {r1, r3-r5}
+	.endif
+
+	@ restore process sp
+	msr	psp, r2
+
+	@ restore original r4-r11
+	ldmia	sp!, {r0-r11}
+
+	@ restore main sp
+	add	sp, sp, #S_FRAME_SIZE-S_IP
+
+	cpsie	i
+	bx	lr
+	.endm
+#endif	/* CONFIG_CPU_V7M */
+
 	@
 	@ Store/load the USER SP and LR registers by switching to the SYS
 	@ mode. Useful in Thumb-2 mode where "stm/ldm rd, {sp, lr}^" is not
@@ -165,6 +276,18 @@
 	rfeia	sp!
 	.endm
 
+#ifdef CONFIG_CPU_V7M
+	/*
+	 * Note we don't need to do clrex here as clearing the local monitor is
+	 * part of each exception entry and exit sequence.
+	 */
+	.macro	restore_user_regs, fast = 0, offset = 0
+	.if	\offset
+	add	sp, #\offset
+	.endif
+	v7m_exception_slow_exit ret_r0 = \fast
+	.endm
+#else	/* ifdef CONFIG_CPU_V7M */
 	.macro	restore_user_regs, fast = 0, offset = 0
 	clrex					@ clear the exclusive monitor
 	mov	r2, sp
@@ -181,6 +304,7 @@
 	add	sp, sp, #S_FRAME_SIZE - S_SP
 	movs	pc, lr				@ return & move spsr_svc into cpsr
 	.endm
+#endif	/* ifdef CONFIG_CPU_V7M / else */
 
 	.macro	get_thread_info, rd
 	mov	\rd, sp
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/entry-v7m.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/entry-v7m.S
--- linux-libre-3.10-gnu/arch/arm/kernel/entry-v7m.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/entry-v7m.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,143 @@
+/*
+ * linux/arch/arm/kernel/entry-v7m.S
+ *
+ * Copyright (C) 2008 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Low-level vector interface routines for the ARMv7-M architecture
+ */
+#include <asm/memory.h>
+#include <asm/glue.h>
+#include <asm/thread_notify.h>
+#include <asm/v7m.h>
+
+#include <mach/entry-macro.S>
+
+#include "entry-header.S"
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+#error "CONFIG_TRACE_IRQFLAGS not supported on the current ARMv7M implementation"
+#endif
+
+__invalid_entry:
+	v7m_exception_entry
+	adr	r0, strerr
+	mrs	r1, ipsr
+	mov	r2, lr
+	bl	printk
+	mov	r0, sp
+	bl	show_regs
+1:	b	1b
+ENDPROC(__invalid_entry)
+
+strerr:	.asciz	"\nUnhandled exception: IPSR = %08lx LR = %08lx\n"
+
+	.align	2
+__irq_entry:
+	v7m_exception_entry
+
+	@
+	@ Invoke the IRQ handler
+	@
+	mrs	r0, ipsr
+	ldr	r1, =V7M_xPSR_EXCEPTIONNO
+	and	r0, r1
+	sub	r0, #16
+	mov	r1, sp
+	stmdb	sp!, {lr}
+	@ routine called with r0 = irq number, r1 = struct pt_regs *
+	bl	nvic_handle_irq
+
+	pop	{lr}
+	@
+	@ Check for any pending work if returning to user
+	@
+	ldr	r1, =BASEADDR_V7M_SCB
+	ldr	r0, [r1, V7M_SCB_ICSR]
+	tst	r0, V7M_SCB_ICSR_RETTOBASE
+	beq	2f
+
+	get_thread_info tsk
+	ldr	r2, [tsk, #TI_FLAGS]
+	tst	r2, #_TIF_WORK_MASK
+	beq	2f			@ no work pending
+	mov	r0, #V7M_SCB_ICSR_PENDSVSET
+	str	r0, [r1, V7M_SCB_ICSR]	@ raise PendSV
+
+2:
+	@ registers r0-r3 and r12 are automatically restored on exception
+	@ return. r4-r7 were not clobbered in v7m_exception_entry so for
+	@ correctness they don't need to be restored. So only r8-r11 must be
+	@ restored here. The easiest way to do so is to restore r0-r7, too.
+	ldmia	sp!, {r0-r11}
+	add	sp, #S_FRAME_SIZE-S_IP
+	cpsie	i
+	bx	lr
+ENDPROC(__irq_entry)
+
+__pendsv_entry:
+	v7m_exception_entry
+
+	ldr	r1, =BASEADDR_V7M_SCB
+	mov	r0, #V7M_SCB_ICSR_PENDSVCLR
+	str	r0, [r1, V7M_SCB_ICSR]	@ clear PendSV
+
+	@ execute the pending work, including reschedule
+	get_thread_info tsk
+	mov	why, #0
+	b	ret_to_user
+ENDPROC(__pendsv_entry)
+
+/*
+ * Register switch for ARMv7-M processors.
+ * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
+ * previous and next are guaranteed not to be the same.
+ */
+ENTRY(__switch_to)
+	.fnstart
+	.cantunwind
+	add	ip, r1, #TI_CPU_SAVE
+	stmia	ip!, {r4 - r11}		@ Store most regs on stack
+	str	sp, [ip], #4
+	str	lr, [ip], #4
+	mov	r5, r0
+	add	r4, r2, #TI_CPU_SAVE
+	ldr	r0, =thread_notify_head
+	mov	r1, #THREAD_NOTIFY_SWITCH
+	bl	atomic_notifier_call_chain
+	mov	ip, r4
+	mov	r0, r5
+	ldmia	ip!, {r4 - r11}		@ Load all regs saved previously
+	ldr	sp, [ip]
+	ldr	pc, [ip, #4]!
+	.fnend
+ENDPROC(__switch_to)
+
+	.data
+	.align	8
+/*
+ * Vector table (64 words => 256 bytes natural alignment)
+ */
+ENTRY(vector_table)
+	.long	0			@ 0 - Reset stack pointer
+	.long	__invalid_entry		@ 1 - Reset
+	.long	__invalid_entry		@ 2 - NMI
+	.long	__invalid_entry		@ 3 - HardFault
+	.long	__invalid_entry		@ 4 - MemManage
+	.long	__invalid_entry		@ 5 - BusFault
+	.long	__invalid_entry		@ 6 - UsageFault
+	.long	__invalid_entry		@ 7 - Reserved
+	.long	__invalid_entry		@ 8 - Reserved
+	.long	__invalid_entry		@ 9 - Reserved
+	.long	__invalid_entry		@ 10 - Reserved
+	.long	vector_swi		@ 11 - SVCall
+	.long	__invalid_entry		@ 12 - Debug Monitor
+	.long	__invalid_entry		@ 13 - Reserved
+	.long	__pendsv_entry		@ 14 - PendSV
+	.long	__invalid_entry		@ 15 - SysTick
+	.rept	64 - 16
+	.long	__irq_entry		@ 16..64 - External Interrupts
+	.endr
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/fiq.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/fiq.c
--- linux-libre-3.10-gnu/arch/arm/kernel/fiq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/fiq.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,6 +47,11 @@
 #include <asm/irq.h>
 #include <asm/traps.h>
 
+#define FIQ_OFFSET ({					\
+		extern void *vector_fiq_offset;		\
+		(unsigned)&vector_fiq_offset;		\
+	})
+
 static unsigned long no_fiq_insn;
 
 /* Default reacquire function
@@ -79,14 +84,14 @@ int show_fiq_list(struct seq_file *p, in
 
 void set_fiq_handler(void *start, unsigned int length)
 {
-#if defined(CONFIG_CPU_USE_DOMAINS)
-	memcpy((void *)0xffff001c, start, length);
-#else
-	memcpy(vectors_page + 0x1c, start, length);
-#endif
-	flush_icache_range(0xffff001c, 0xffff001c + length);
-	if (!vectors_high())
-		flush_icache_range(0x1c, 0x1c + length);
+	void *base = vectors_page;
+	unsigned offset = FIQ_OFFSET;
+
+	memcpy(base + offset, start, length);
+	if (!cache_is_vipt_nonaliasing())
+		flush_icache_range((unsigned long)base + offset, offset +
+				   length);
+	flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length);
 }
 
 int claim_fiq(struct fiq_handler *f)
@@ -144,6 +149,7 @@ EXPORT_SYMBOL(disable_fiq);
 
 void __init init_FIQ(int start)
 {
-	no_fiq_insn = *(unsigned long *)0xffff001c;
+	unsigned offset = FIQ_OFFSET;
+	no_fiq_insn = *(unsigned long *)(0xffff0000 + offset);
 	fiq_start = start;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/head-common.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/head-common.S
--- linux-libre-3.10-gnu/arch/arm/kernel/head-common.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/head-common.S	2013-08-25 20:43:22.000000000 -0400
@@ -133,6 +133,9 @@ ENTRY(lookup_processor_type)
 	ldmfd	sp!, {r4 - r6, r9, pc}
 ENDPROC(lookup_processor_type)
 
+	__FINIT
+	.text
+
 /*
  * Read processor ID register (CP#15, CR0), and look up in the linker-built
  * supported processor list.  Note that we can't use the absolute addresses
@@ -146,7 +149,6 @@ ENDPROC(lookup_processor_type)
  *	r5 = proc_info pointer in physical address space
  *	r9 = cpuid (preserved)
  */
-	__CPUINIT
 __lookup_processor_type:
 	adr	r3, __lookup_processor_type_data
 	ldmia	r3, {r4 - r6}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/head-nommu.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/head-nommu.S
--- linux-libre-3.10-gnu/arch/arm/kernel/head-nommu.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/head-nommu.S	2013-08-25 20:43:22.000000000 -0400
@@ -17,8 +17,12 @@
 #include <asm/assembler.h>
 #include <asm/ptrace.h>
 #include <asm/asm-offsets.h>
+#include <asm/memory.h>
 #include <asm/cp15.h>
 #include <asm/thread_info.h>
+#include <asm/v7m.h>
+#include <asm/mpu.h>
+#include <asm/page.h>
 
 /*
  * Kernel startup entry point.
@@ -50,21 +54,86 @@ ENTRY(stext)
 
 	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
 						@ and irqs disabled
-#ifndef CONFIG_CPU_CP15
-	ldr	r9, =CONFIG_PROCESSOR_ID
-#else
+#if defined(CONFIG_CPU_CP15)
 	mrc	p15, 0, r9, c0, c0		@ get processor id
+#elif defined(CONFIG_CPU_V7M)
+	ldr	r9, =BASEADDR_V7M_SCB
+	ldr	r9, [r9, V7M_SCB_CPUID]
+#else
+	ldr	r9, =CONFIG_PROCESSOR_ID
 #endif
 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
 	movs	r10, r5				@ invalid processor (r5=0)?
 	beq	__error_p				@ yes, error 'p'
 
-	adr	lr, BSYM(__after_proc_init)	@ return (PIC) address
+#ifdef CONFIG_ARM_MPU
+	/* Calculate the size of a region covering just the kernel */
+	ldr	r5, =PHYS_OFFSET		@ Region start: PHYS_OFFSET
+	ldr     r6, =(_end)			@ Cover whole kernel
+	sub	r6, r6, r5			@ Minimum size of region to map
+	clz	r6, r6				@ Region size must be 2^N...
+	rsb	r6, r6, #31			@ ...so round up region size
+	lsl	r6, r6, #MPU_RSR_SZ		@ Put size in right field
+	orr	r6, r6, #(1 << MPU_RSR_EN)	@ Set region enabled bit
+	bl	__setup_mpu
+#endif
+	ldr	r13, =__mmap_switched		@ address to jump to after
+						@ initialising sctlr
+	adr	lr, BSYM(1f)			@ return (PIC) address
  ARM(	add	pc, r10, #PROCINFO_INITFUNC	)
  THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
  THUMB(	mov	pc, r12				)
+ 1:	b	__after_proc_init
 ENDPROC(stext)
 
+#ifdef CONFIG_SMP
+	.text
+ENTRY(secondary_startup)
+	/*
+	 * Common entry point for secondary CPUs.
+	 *
+	 * Ensure that we're in SVC mode, and IRQs are disabled.  Lookup
+	 * the processor type - there is no need to check the machine type
+	 * as it has already been validated by the primary processor.
+	 */
+	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
+#ifndef CONFIG_CPU_CP15
+	ldr	r9, =CONFIG_PROCESSOR_ID
+#else
+	mrc	p15, 0, r9, c0, c0		@ get processor id
+#endif
+	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
+	movs	r10, r5				@ invalid processor?
+	beq	__error_p			@ yes, error 'p'
+
+	adr	r4, __secondary_data
+	ldmia	r4, {r7, r12}
+
+#ifdef CONFIG_ARM_MPU
+	/* Use MPU region info supplied by __cpu_up */
+	ldr	r6, [r7]			@ get secondary_data.mpu_szr
+	bl      __setup_mpu			@ Initialize the MPU
+#endif
+
+	adr	lr, BSYM(__after_proc_init)	@ return address
+	mov	r13, r12			@ __secondary_switched address
+ ARM(	add	pc, r10, #PROCINFO_INITFUNC	)
+ THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
+ THUMB(	mov	pc, r12				)
+ENDPROC(secondary_startup)
+
+ENTRY(__secondary_switched)
+	ldr	sp, [r7, #8]			@ set up the stack pointer
+	mov	fp, #0
+	b	secondary_start_kernel
+ENDPROC(__secondary_switched)
+
+	.type	__secondary_data, %object
+__secondary_data:
+	.long	secondary_data
+	.long	__secondary_switched
+#endif /* CONFIG_SMP */
+
 /*
  * Set the Control Register and Read the process ID.
  */
@@ -95,10 +164,97 @@ __after_proc_init:
 #endif
 	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
 #endif /* CONFIG_CPU_CP15 */
-
-	b	__mmap_switched			@ clear the BSS and jump
-						@ to start_kernel
+	mov	pc, r13
 ENDPROC(__after_proc_init)
 	.ltorg
 
+#ifdef CONFIG_ARM_MPU
+
+
+/* Set which MPU region should be programmed */
+.macro set_region_nr tmp, rgnr
+	mov	\tmp, \rgnr			@ Use static region numbers
+	mcr	p15, 0, \tmp, c6, c2, 0		@ Write RGNR
+.endm
+
+/* Setup a single MPU region, either D or I side (D-side for unified) */
+.macro setup_region bar, acr, sr, side = MPU_DATA_SIDE
+	mcr	p15, 0, \bar, c6, c1, (0 + \side)	@ I/DRBAR
+	mcr	p15, 0, \acr, c6, c1, (4 + \side)	@ I/DRACR
+	mcr	p15, 0, \sr, c6, c1, (2 + \side)		@ I/DRSR
+.endm
+
+/*
+ * Setup the MPU and initial MPU Regions. We create the following regions:
+ * Region 0: Use this for probing the MPU details, so leave disabled.
+ * Region 1: Background region - covers the whole of RAM as strongly ordered
+ * Region 2: Normal, Shared, cacheable for RAM. From PHYS_OFFSET, size from r6
+ * Region 3: Normal, shared, inaccessible from PL0 to protect the vectors page
+ *
+ * r6: Value to be written to DRSR (and IRSR if required) for MPU_RAM_REGION
+*/
+
+ENTRY(__setup_mpu)
+
+	/* Probe for v7 PMSA compliance */
+	mrc	p15, 0, r0, c0, c1, 4		@ Read ID_MMFR0
+	and	r0, r0, #(MMFR0_PMSA)		@ PMSA field
+	teq	r0, #(MMFR0_PMSAv7)		@ PMSA v7
+	bne	__error_p			@ Fail: ARM_MPU on NOT v7 PMSA
+
+	/* Determine whether the D/I-side memory map is unified. We set the
+	 * flags here and continue to use them for the rest of this function */
+	mrc	p15, 0, r0, c0, c0, 4		@ MPUIR
+	ands	r5, r0, #MPUIR_DREGION_SZMASK	@ 0 size d region => No MPU
+	beq	__error_p			@ Fail: ARM_MPU and no MPU
+	tst	r0, #MPUIR_nU			@ MPUIR_nU = 0 for unified
+
+	/* Setup second region first to free up r6 */
+	set_region_nr r0, #MPU_RAM_REGION
+	isb
+	/* Full access from PL0, PL1, shared for CONFIG_SMP, cacheable */
+	ldr	r0, =PHYS_OFFSET		@ RAM starts at PHYS_OFFSET
+	ldr	r5,=(MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL)
+
+	setup_region r0, r5, r6, MPU_DATA_SIDE	@ PHYS_OFFSET, shared, enabled
+	beq	1f				@ Memory-map not unified
+	setup_region r0, r5, r6, MPU_INSTR_SIDE @ PHYS_OFFSET, shared, enabled
+1:	isb
+
+	/* First/background region */
+	set_region_nr r0, #MPU_BG_REGION
+	isb
+	/* Execute Never,  strongly ordered, inaccessible to PL0, rw PL1  */
+	mov	r0, #0				@ BG region starts at 0x0
+	ldr	r5,=(MPU_ACR_XN | MPU_RGN_STRONGLY_ORDERED | MPU_AP_PL1RW_PL0NA)
+	mov	r6, #MPU_RSR_ALL_MEM		@ 4GB region, enabled
+
+	setup_region r0, r5, r6, MPU_DATA_SIDE	@ 0x0, BG region, enabled
+	beq	2f				@ Memory-map not unified
+	setup_region r0, r5, r6, MPU_INSTR_SIDE @ 0x0, BG region, enabled
+2:	isb
+
+	/* Vectors region */
+	set_region_nr r0, #MPU_VECTORS_REGION
+	isb
+	/* Shared, inaccessible to PL0, rw PL1 */
+	mov	r0, #CONFIG_VECTORS_BASE	@ Cover from VECTORS_BASE
+	ldr	r5,=(MPU_AP_PL1RW_PL0NA | MPU_RGN_NORMAL)
+	/* Writing N to bits 5:1 (RSR_SZ) --> region size 2^N+1 */
+	mov	r6, #(((PAGE_SHIFT - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN)
+
+	setup_region r0, r5, r6, MPU_DATA_SIDE	@ VECTORS_BASE, PL0 NA, enabled
+	beq	3f				@ Memory-map not unified
+	setup_region r0, r5, r6, MPU_INSTR_SIDE	@ VECTORS_BASE, PL0 NA, enabled
+3:	isb
+
+	/* Enable the MPU */
+	mrc	p15, 0, r0, c1, c0, 0		@ Read SCTLR
+	bic     r0, r0, #CR_BR			@ Disable the 'default mem-map'
+	orr	r0, r0, #CR_M			@ Set SCTRL.M (MPU on)
+	mcr	p15, 0, r0, c1, c0, 0		@ Enable MPU
+	isb
+	mov pc,lr
+ENDPROC(__setup_mpu)
+#endif
 #include "head-common.S"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/head.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/head.S
--- linux-libre-3.10-gnu/arch/arm/kernel/head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/head.S	2013-08-25 20:43:22.000000000 -0400
@@ -156,7 +156,7 @@ ENDPROC(stext)
  *
  * Returns:
  *  r0, r3, r5-r7 corrupted
- *  r4 = physical page table address
+ *  r4 = page table (see ARCH_PGD_SHIFT in asm/memory.h)
  */
 __create_page_tables:
 	pgtbl	r4, r8				@ page table address
@@ -331,6 +331,7 @@ __create_page_tables:
 #endif
 #ifdef CONFIG_ARM_LPAE
 	sub	r4, r4, #0x1000		@ point to the PGD table
+	mov	r4, r4, lsr #ARCH_PGD_SHIFT
 #endif
 	mov	pc, lr
 ENDPROC(__create_page_tables)
@@ -342,7 +343,7 @@ __turn_mmu_on_loc:
 	.long	__turn_mmu_on_end
 
 #if defined(CONFIG_SMP)
-	__CPUINIT
+	.text
 ENTRY(secondary_startup)
 	/*
 	 * Common entry point for secondary CPUs.
@@ -408,7 +409,7 @@ __secondary_data:
  *  r0  = cp#15 control register
  *  r1  = machine ID
  *  r2  = atags or dtb pointer
- *  r4  = page table pointer
+ *  r4  = page table (see ARCH_PGD_SHIFT in asm/memory.h)
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
  */
@@ -427,10 +428,7 @@ __enable_mmu:
 #ifdef CONFIG_CPU_ICACHE_DISABLE
 	bic	r0, r0, #CR_I
 #endif
-#ifdef CONFIG_ARM_LPAE
-	mov	r5, #0
-	mcrr	p15, 0, r4, r5, c2		@ load TTBR0
-#else
+#ifndef CONFIG_ARM_LPAE
 	mov	r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 		      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/hw_breakpoint.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/hw_breakpoint.c
--- linux-libre-3.10-gnu/arch/arm/kernel/hw_breakpoint.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/hw_breakpoint.c	2013-08-25 20:43:22.000000000 -0400
@@ -1020,7 +1020,7 @@ out_mdbgen:
 		cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
 }
 
-static int __cpuinit dbg_reset_notify(struct notifier_block *self,
+static int dbg_reset_notify(struct notifier_block *self,
 				      unsigned long action, void *cpu)
 {
 	if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE)
@@ -1029,7 +1029,7 @@ static int __cpuinit dbg_reset_notify(st
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata dbg_reset_nb = {
+static struct notifier_block dbg_reset_nb = {
 	.notifier_call = dbg_reset_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/hyp-stub.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/hyp-stub.S
--- linux-libre-3.10-gnu/arch/arm/kernel/hyp-stub.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/hyp-stub.S	2013-08-25 20:43:22.000000000 -0400
@@ -56,8 +56,8 @@ ENTRY(__boot_cpu_mode)
 	ldr	\reg3, [\reg2]
 	ldr	\reg1, [\reg2, \reg3]
 	cmp	\mode, \reg1		@ matches primary CPU boot mode?
-	orrne	r7, r7, #BOOT_CPU_MODE_MISMATCH
-	strne	r7, [r5, r6]		@ record what happened and give up
+	orrne	\reg1, \reg1, #BOOT_CPU_MODE_MISMATCH
+	strne	\reg1, [\reg2, \reg3]	@ record what happened and give up
 	.endm
 
 #else	/* ZIMAGE */
@@ -153,6 +153,13 @@ THUMB(	orr	r7, #(1 << 30)	)	@ HSCTLR.TE
 	mrc	p15, 4, r7, c14, c1, 0	@ CNTHCTL
 	orr	r7, r7, #3		@ PL1PCEN | PL1PCTEN
 	mcr	p15, 4, r7, c14, c1, 0	@ CNTHCTL
+	mov	r7, #0
+	mcrr	p15, 4, r7, r7, c14	@ CNTVOFF
+
+	@ Disable virtual timer in case it was counting
+	mrc	p15, 0, r7, c14, c3, 1	@ CNTV_CTL
+	bic	r7, #1			@ Clear ENABLE
+	mcr	p15, 0, r7, c14, c3, 1	@ CNTV_CTL
 1:
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/machine_kexec.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/machine_kexec.c
--- linux-libre-3.10-gnu/arch/arm/kernel/machine_kexec.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/machine_kexec.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 #include <asm/mach-types.h>
+#include <asm/smp_plat.h>
 #include <asm/system_misc.h>
 
 extern const unsigned char relocate_new_kernel[];
@@ -39,6 +40,14 @@ int machine_kexec_prepare(struct kimage
 	int i, err;
 
 	/*
+	 * Validate that if the current HW supports SMP, then the SW supports
+	 * and implements CPU hotplug for the current HW. If not, we won't be
+	 * able to kexec reliably, so fail the prepare operation.
+	 */
+	if (num_possible_cpus() > 1 && !platform_can_cpu_hotplug())
+		return -EINVAL;
+
+	/*
 	 * No segment at default ATAGs address. try to locate
 	 * a dtb using magic.
 	 */
@@ -73,6 +82,7 @@ void machine_crash_nonpanic_core(void *u
 	crash_save_cpu(&regs, smp_processor_id());
 	flush_cache_all();
 
+	set_cpu_online(smp_processor_id(), false);
 	atomic_dec(&waiting_for_crash_ipi);
 	while (1)
 		cpu_relax();
@@ -134,10 +144,13 @@ void machine_kexec(struct kimage *image)
 	unsigned long reboot_code_buffer_phys;
 	void *reboot_code_buffer;
 
-	if (num_online_cpus() > 1) {
-		pr_err("kexec: error: multiple CPUs still online\n");
-		return;
-	}
+	/*
+	 * This can only happen if machine_shutdown() failed to disable some
+	 * CPU, and that can only happen if the checks in
+	 * machine_kexec_prepare() were not correct. If this fails, we can't
+	 * reliably kexec anyway, so BUG_ON is appropriate.
+	 */
+	BUG_ON(num_online_cpus() > 1);
 
 	page_list = image->head & PAGE_MASK;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/Makefile linux-libre-3.11-rc7-gnu/arch/arm/kernel/Makefile
--- linux-libre-3.10-gnu/arch/arm/kernel/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -15,14 +15,20 @@ CFLAGS_REMOVE_return_address.o = -pg
 
 # Object file lists.
 
-obj-y		:= elf.o entry-armv.o entry-common.o irq.o opcodes.o \
-		   process.o ptrace.o return_address.o sched_clock.o \
+obj-y		:= elf.o entry-common.o irq.o opcodes.o \
+		   process.o ptrace.o return_address.o \
 		   setup.o signal.o stacktrace.o sys_arm.o time.o traps.o
 
 obj-$(CONFIG_ATAGS)		+= atags_parse.o
 obj-$(CONFIG_ATAGS_PROC)	+= atags_proc.o
 obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o
 
+ifeq ($(CONFIG_CPU_V7M),y)
+obj-y		+= entry-v7m.o
+else
+obj-y		+= entry-armv.o
+endif
+
 obj-$(CONFIG_OC_ETM)		+= etm.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
@@ -32,7 +38,10 @@ obj-$(CONFIG_ARTHUR)		+= arthur.o
 obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
 obj-$(CONFIG_PCI)		+= bios32.o isa.o
 obj-$(CONFIG_ARM_CPU_SUSPEND)	+= sleep.o suspend.o
-obj-$(CONFIG_SMP)		+= smp.o smp_tlb.o
+obj-$(CONFIG_SMP)		+= smp.o
+ifdef CONFIG_MMU
+obj-$(CONFIG_SMP)		+= smp_tlb.o
+endif
 obj-$(CONFIG_HAVE_ARM_SCU)	+= smp_scu.o
 obj-$(CONFIG_HAVE_ARM_TWD)	+= smp_twd.o
 obj-$(CONFIG_ARM_ARCH_TIMER)	+= arch_timer.o
@@ -82,6 +91,9 @@ obj-$(CONFIG_DEBUG_LL)	+= debug.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 obj-$(CONFIG_ARM_VIRT_EXT)	+= hyp-stub.o
-obj-$(CONFIG_ARM_PSCI)		+= psci.o
+ifeq ($(CONFIG_ARM_PSCI),y)
+obj-y				+= psci.o
+obj-$(CONFIG_SMP)		+= psci_smp.o
+endif
 
 extra-y := $(head-y) vmlinux.lds
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/module.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/module.c
--- linux-libre-3.10-gnu/arch/arm/kernel/module.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/module.c	2013-08-25 20:43:22.000000000 -0400
@@ -288,24 +288,16 @@ int module_finalize(const Elf32_Ehdr *hd
 
 		if (strcmp(".ARM.exidx.init.text", secname) == 0)
 			maps[ARM_SEC_INIT].unw_sec = s;
-		else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
-			maps[ARM_SEC_DEVINIT].unw_sec = s;
 		else if (strcmp(".ARM.exidx", secname) == 0)
 			maps[ARM_SEC_CORE].unw_sec = s;
 		else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
 			maps[ARM_SEC_EXIT].unw_sec = s;
-		else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
-			maps[ARM_SEC_DEVEXIT].unw_sec = s;
 		else if (strcmp(".init.text", secname) == 0)
 			maps[ARM_SEC_INIT].txt_sec = s;
-		else if (strcmp(".devinit.text", secname) == 0)
-			maps[ARM_SEC_DEVINIT].txt_sec = s;
 		else if (strcmp(".text", secname) == 0)
 			maps[ARM_SEC_CORE].txt_sec = s;
 		else if (strcmp(".exit.text", secname) == 0)
 			maps[ARM_SEC_EXIT].txt_sec = s;
-		else if (strcmp(".devexit.text", secname) == 0)
-			maps[ARM_SEC_DEVEXIT].txt_sec = s;
 	}
 
 	for (i = 0; i < ARM_SEC_MAX; i++)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/perf_event.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/perf_event.c
--- linux-libre-3.10-gnu/arch/arm/kernel/perf_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/perf_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,7 +53,12 @@ armpmu_map_cache_event(const unsigned (*
 static int
 armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
 {
-	int mapping = (*event_map)[config];
+	int mapping;
+
+	if (config >= PERF_COUNT_HW_MAX)
+		return -EINVAL;
+
+	mapping = (*event_map)[config];
 	return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
 }
 
@@ -253,6 +258,9 @@ validate_event(struct pmu_hw_events *hw_
 	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
 	struct pmu *leader_pmu = event->group_leader->pmu;
 
+	if (is_software_event(event))
+		return 1;
+
 	if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
 		return 1;
 
@@ -569,6 +577,7 @@ perf_callchain_user(struct perf_callchai
 		return;
 	}
 
+	perf_callchain_store(entry, regs->ARM_pc);
 	tail = (struct frame_tail __user *)regs->ARM_fp - 1;
 
 	while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/perf_event_cpu.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/perf_event_cpu.c
--- linux-libre-3.10-gnu/arch/arm/kernel/perf_event_cpu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/perf_event_cpu.c	2013-08-25 20:43:22.000000000 -0400
@@ -157,8 +157,8 @@ static void cpu_pmu_init(struct arm_pmu
  * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
  * junk values out of them.
  */
-static int __cpuinit cpu_pmu_notify(struct notifier_block *b,
-				    unsigned long action, void *hcpu)
+static int cpu_pmu_notify(struct notifier_block *b, unsigned long action,
+			  void *hcpu)
 {
 	if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
 		return NOTIFY_DONE;
@@ -171,7 +171,7 @@ static int __cpuinit cpu_pmu_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata cpu_pmu_hotplug_notifier = {
+static struct notifier_block cpu_pmu_hotplug_notifier = {
 	.notifier_call = cpu_pmu_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/process.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/process.c
--- linux-libre-3.10-gnu/arch/arm/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/hw_breakpoint.h>
 #include <linux/cpuidle.h>
 #include <linux/leds.h>
+#include <linux/reboot.h>
 
 #include <asm/cacheflush.h>
 #include <asm/idmap.h>
@@ -39,6 +40,7 @@
 #include <asm/thread_notify.h>
 #include <asm/stacktrace.h>
 #include <asm/mach/time.h>
+#include <asm/tls.h>
 
 #ifdef CONFIG_CC_STACKPROTECTOR
 #include <linux/stackprotector.h>
@@ -112,7 +114,7 @@ void soft_restart(unsigned long addr)
 	BUG();
 }
 
-static void null_restart(char mode, const char *cmd)
+static void null_restart(enum reboot_mode reboot_mode, const char *cmd)
 {
 }
 
@@ -122,7 +124,7 @@ static void null_restart(char mode, cons
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
-void (*arm_pm_restart)(char str, const char *cmd) = null_restart;
+void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd) = null_restart;
 EXPORT_SYMBOL_GPL(arm_pm_restart);
 
 /*
@@ -174,16 +176,6 @@ void arch_cpu_idle(void)
 		default_idle();
 }
 
-static char reboot_mode = 'h';
-
-int __init reboot_setup(char *str)
-{
-	reboot_mode = str[0];
-	return 1;
-}
-
-__setup("reboot=", reboot_setup);
-
 /*
  * Called by kexec, immediately prior to machine_kexec().
  *
@@ -205,6 +197,7 @@ void machine_shutdown(void)
  */
 void machine_halt(void)
 {
+	local_irq_disable();
 	smp_send_stop();
 
 	local_irq_disable();
@@ -219,6 +212,7 @@ void machine_halt(void)
  */
 void machine_power_off(void)
 {
+	local_irq_disable();
 	smp_send_stop();
 
 	if (pm_power_off)
@@ -238,6 +232,7 @@ void machine_power_off(void)
  */
 void machine_restart(char *cmd)
 {
+	local_irq_disable();
 	smp_send_stop();
 
 	arm_pm_restart(reboot_mode, cmd);
@@ -374,7 +369,8 @@ copy_thread(unsigned long clone_flags, u
 	clear_ptrace_hw_breakpoint(p);
 
 	if (clone_flags & CLONE_SETTLS)
-		thread->tp_value = childregs->ARM_r3;
+		thread->tp_value[0] = childregs->ARM_r3;
+	thread->tp_value[1] = get_tpuser();
 
 	thread_notify(THREAD_NOTIFY_COPY, thread);
 
@@ -433,10 +429,11 @@ unsigned long arch_randomize_brk(struct
 }
 
 #ifdef CONFIG_MMU
+#ifdef CONFIG_KUSER_HELPERS
 /*
  * The vectors page is always readable from user space for the
- * atomic helpers and the signal restart code. Insert it into the
- * gate_vma so that it is visible through ptrace and /proc/<pid>/mem.
+ * atomic helpers. Insert it into the gate_vma so that it is visible
+ * through ptrace and /proc/<pid>/mem.
  */
 static struct vm_area_struct gate_vma = {
 	.vm_start	= 0xffff0000,
@@ -465,9 +462,48 @@ int in_gate_area_no_mm(unsigned long add
 {
 	return in_gate_area(NULL, addr);
 }
+#define is_gate_vma(vma)	((vma) == &gate_vma)
+#else
+#define is_gate_vma(vma)	0
+#endif
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
-	return (vma == &gate_vma) ? "[vectors]" : NULL;
+	return is_gate_vma(vma) ? "[vectors]" :
+		(vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage) ?
+		 "[sigpage]" : NULL;
+}
+
+static struct page *signal_page;
+extern struct page *get_signal_page(void);
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long addr;
+	int ret;
+
+	if (!signal_page)
+		signal_page = get_signal_page();
+	if (!signal_page)
+		return -ENOMEM;
+
+	down_write(&mm->mmap_sem);
+	addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+	if (IS_ERR_VALUE(addr)) {
+		ret = addr;
+		goto up_fail;
+	}
+
+	ret = install_special_mapping(mm, addr, PAGE_SIZE,
+		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+		&signal_page);
+
+	if (ret == 0)
+		mm->context.sigpage = addr;
+
+ up_fail:
+	up_write(&mm->mmap_sem);
+	return ret;
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/psci.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/psci.c
--- linux-libre-3.10-gnu/arch/arm/kernel/psci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/psci.c	2013-08-25 20:43:22.000000000 -0400
@@ -158,7 +158,7 @@ static const struct of_device_id psci_of
 	{},
 };
 
-static int __init psci_init(void)
+void __init psci_init(void)
 {
 	struct device_node *np;
 	const char *method;
@@ -166,7 +166,7 @@ static int __init psci_init(void)
 
 	np = of_find_matching_node(NULL, psci_of_match);
 	if (!np)
-		return 0;
+		return;
 
 	pr_info("probing function IDs from device-tree\n");
 
@@ -206,6 +206,5 @@ static int __init psci_init(void)
 
 out_put_node:
 	of_node_put(np);
-	return 0;
+	return;
 }
-early_initcall(psci_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/psci_smp.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/psci_smp.c
--- linux-libre-3.10-gnu/arch/arm/kernel/psci_smp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/psci_smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,83 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/irqchip/arm-gic.h>
+#include <linux/smp.h>
+#include <linux/of.h>
+
+#include <asm/psci.h>
+#include <asm/smp_plat.h>
+
+/*
+ * psci_smp assumes that the following is true about PSCI:
+ *
+ * cpu_suspend   Suspend the execution on a CPU
+ * @state        we don't currently describe affinity levels, so just pass 0.
+ * @entry_point  the first instruction to be executed on return
+ * returns 0  success, < 0 on failure
+ *
+ * cpu_off       Power down a CPU
+ * @state        we don't currently describe affinity levels, so just pass 0.
+ * no return on successful call
+ *
+ * cpu_on        Power up a CPU
+ * @cpuid        cpuid of target CPU, as from MPIDR
+ * @entry_point  the first instruction to be executed on return
+ * returns 0  success, < 0 on failure
+ *
+ * migrate       Migrate the context to a different CPU
+ * @cpuid        cpuid of target CPU, as from MPIDR
+ * returns 0  success, < 0 on failure
+ *
+ */
+
+extern void secondary_startup(void);
+
+static int psci_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	if (psci_ops.cpu_on)
+		return psci_ops.cpu_on(cpu_logical_map(cpu),
+				       __pa(secondary_startup));
+	return -ENODEV;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void __ref psci_cpu_die(unsigned int cpu)
+{
+       const struct psci_power_state ps = {
+               .type = PSCI_POWER_STATE_TYPE_POWER_DOWN,
+       };
+
+       if (psci_ops.cpu_off)
+               psci_ops.cpu_off(ps);
+
+       /* We should never return */
+       panic("psci: cpu %d failed to shutdown\n", cpu);
+}
+#endif
+
+bool __init psci_smp_available(void)
+{
+	/* is cpu_on available at least? */
+	return (psci_ops.cpu_on != NULL);
+}
+
+struct smp_operations __initdata psci_smp_ops = {
+	.smp_boot_secondary	= psci_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_die		= psci_cpu_die,
+#endif
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/ptrace.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/ptrace.c
--- linux-libre-3.10-gnu/arch/arm/kernel/ptrace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/ptrace.c	2013-08-25 20:43:22.000000000 -0400
@@ -849,7 +849,7 @@ long arch_ptrace(struct task_struct *chi
 #endif
 
 		case PTRACE_GET_THREAD_AREA:
-			ret = put_user(task_thread_info(child)->tp_value,
+			ret = put_user(task_thread_info(child)->tp_value[0],
 				       datap);
 			break;
 
@@ -886,20 +886,12 @@ long arch_ptrace(struct task_struct *chi
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 		case PTRACE_GETHBPREGS:
-			if (ptrace_get_breakpoints(child) < 0)
-				return -ESRCH;
-
 			ret = ptrace_gethbpregs(child, addr,
 						(unsigned long __user *)data);
-			ptrace_put_breakpoints(child);
 			break;
 		case PTRACE_SETHBPREGS:
-			if (ptrace_get_breakpoints(child) < 0)
-				return -ESRCH;
-
 			ret = ptrace_sethbpregs(child, addr,
 						(unsigned long __user *)data);
-			ptrace_put_breakpoints(child);
 			break;
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/sched_clock.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/sched_clock.c
--- linux-libre-3.10-gnu/arch/arm/kernel/sched_clock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/sched_clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,217 +0,0 @@
-/*
- * sched_clock.c: support for extending counters to full 64-bit ns counter
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/clocksource.h>
-#include <linux/init.h>
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/moduleparam.h>
-#include <linux/sched.h>
-#include <linux/syscore_ops.h>
-#include <linux/timer.h>
-
-#include <asm/sched_clock.h>
-
-struct clock_data {
-	u64 epoch_ns;
-	u32 epoch_cyc;
-	u32 epoch_cyc_copy;
-	unsigned long rate;
-	u32 mult;
-	u32 shift;
-	bool suspended;
-	bool needs_suspend;
-};
-
-static void sched_clock_poll(unsigned long wrap_ticks);
-static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
-static int irqtime = -1;
-
-core_param(irqtime, irqtime, int, 0400);
-
-static struct clock_data cd = {
-	.mult	= NSEC_PER_SEC / HZ,
-};
-
-static u32 __read_mostly sched_clock_mask = 0xffffffff;
-
-static u32 notrace jiffy_sched_clock_read(void)
-{
-	return (u32)(jiffies - INITIAL_JIFFIES);
-}
-
-static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read;
-
-static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift)
-{
-	return (cyc * mult) >> shift;
-}
-
-static unsigned long long notrace cyc_to_sched_clock(u32 cyc, u32 mask)
-{
-	u64 epoch_ns;
-	u32 epoch_cyc;
-
-	if (cd.suspended)
-		return cd.epoch_ns;
-
-	/*
-	 * Load the epoch_cyc and epoch_ns atomically.  We do this by
-	 * ensuring that we always write epoch_cyc, epoch_ns and
-	 * epoch_cyc_copy in strict order, and read them in strict order.
-	 * If epoch_cyc and epoch_cyc_copy are not equal, then we're in
-	 * the middle of an update, and we should repeat the load.
-	 */
-	do {
-		epoch_cyc = cd.epoch_cyc;
-		smp_rmb();
-		epoch_ns = cd.epoch_ns;
-		smp_rmb();
-	} while (epoch_cyc != cd.epoch_cyc_copy);
-
-	return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, cd.mult, cd.shift);
-}
-
-/*
- * Atomically update the sched_clock epoch.
- */
-static void notrace update_sched_clock(void)
-{
-	unsigned long flags;
-	u32 cyc;
-	u64 ns;
-
-	cyc = read_sched_clock();
-	ns = cd.epoch_ns +
-		cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask,
-			  cd.mult, cd.shift);
-	/*
-	 * Write epoch_cyc and epoch_ns in a way that the update is
-	 * detectable in cyc_to_fixed_sched_clock().
-	 */
-	raw_local_irq_save(flags);
-	cd.epoch_cyc_copy = cyc;
-	smp_wmb();
-	cd.epoch_ns = ns;
-	smp_wmb();
-	cd.epoch_cyc = cyc;
-	raw_local_irq_restore(flags);
-}
-
-static void sched_clock_poll(unsigned long wrap_ticks)
-{
-	mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks));
-	update_sched_clock();
-}
-
-void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
-{
-	unsigned long r, w;
-	u64 res, wrap;
-	char r_unit;
-
-	if (cd.rate > rate)
-		return;
-
-	BUG_ON(bits > 32);
-	WARN_ON(!irqs_disabled());
-	read_sched_clock = read;
-	sched_clock_mask = (1 << bits) - 1;
-	cd.rate = rate;
-
-	/* calculate the mult/shift to convert counter ticks to ns. */
-	clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 0);
-
-	r = rate;
-	if (r >= 4000000) {
-		r /= 1000000;
-		r_unit = 'M';
-	} else if (r >= 1000) {
-		r /= 1000;
-		r_unit = 'k';
-	} else
-		r_unit = ' ';
-
-	/* calculate how many ns until we wrap */
-	wrap = cyc_to_ns((1ULL << bits) - 1, cd.mult, cd.shift);
-	do_div(wrap, NSEC_PER_MSEC);
-	w = wrap;
-
-	/* calculate the ns resolution of this counter */
-	res = cyc_to_ns(1ULL, cd.mult, cd.shift);
-	pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n",
-		bits, r, r_unit, res, w);
-
-	/*
-	 * Start the timer to keep sched_clock() properly updated and
-	 * sets the initial epoch.
-	 */
-	sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
-	update_sched_clock();
-
-	/*
-	 * Ensure that sched_clock() starts off at 0ns
-	 */
-	cd.epoch_ns = 0;
-
-	/* Enable IRQ time accounting if we have a fast enough sched_clock */
-	if (irqtime > 0 || (irqtime == -1 && rate >= 1000000))
-		enable_sched_clock_irqtime();
-
-	pr_debug("Registered %pF as sched_clock source\n", read);
-}
-
-static unsigned long long notrace sched_clock_32(void)
-{
-	u32 cyc = read_sched_clock();
-	return cyc_to_sched_clock(cyc, sched_clock_mask);
-}
-
-unsigned long long __read_mostly (*sched_clock_func)(void) = sched_clock_32;
-
-unsigned long long notrace sched_clock(void)
-{
-	return sched_clock_func();
-}
-
-void __init sched_clock_postinit(void)
-{
-	/*
-	 * If no sched_clock function has been provided at that point,
-	 * make it the final one one.
-	 */
-	if (read_sched_clock == jiffy_sched_clock_read)
-		setup_sched_clock(jiffy_sched_clock_read, 32, HZ);
-
-	sched_clock_poll(sched_clock_timer.data);
-}
-
-static int sched_clock_suspend(void)
-{
-	sched_clock_poll(sched_clock_timer.data);
-	cd.suspended = true;
-	return 0;
-}
-
-static void sched_clock_resume(void)
-{
-	cd.epoch_cyc = read_sched_clock();
-	cd.epoch_cyc_copy = cd.epoch_cyc;
-	cd.suspended = false;
-}
-
-static struct syscore_ops sched_clock_ops = {
-	.suspend = sched_clock_suspend,
-	.resume = sched_clock_resume,
-};
-
-static int __init sched_clock_syscore_init(void)
-{
-	register_syscore_ops(&sched_clock_ops);
-	return 0;
-}
-device_initcall(sched_clock_syscore_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/setup.c
--- linux-libre-3.10-gnu/arch/arm/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,6 +37,7 @@
 #include <asm/cputype.h>
 #include <asm/elf.h>
 #include <asm/procinfo.h>
+#include <asm/psci.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp_plat.h>
@@ -73,7 +74,7 @@ __setup("fpe=", fpe_setup);
 
 extern void paging_init(struct machine_desc *desc);
 extern void sanity_check_meminfo(void);
-extern void reboot_setup(char *str);
+extern enum reboot_mode reboot_mode;
 extern void setup_dma_zone(struct machine_desc *desc);
 
 unsigned int processor_id;
@@ -128,7 +129,9 @@ struct stack {
 	u32 und[3];
 } ____cacheline_aligned;
 
+#ifndef CONFIG_CPU_V7M
 static struct stack stacks[NR_CPUS];
+#endif
 
 char elf_platform[ELF_PLATFORM_SIZE];
 EXPORT_SYMBOL(elf_platform);
@@ -207,7 +210,7 @@ static const char *proc_arch[] = {
 	"5TEJ",
 	"6TEJ",
 	"7",
-	"?(11)",
+	"7M",
 	"?(12)",
 	"?(13)",
 	"?(14)",
@@ -216,6 +219,12 @@ static const char *proc_arch[] = {
 	"?(17)",
 };
 
+#ifdef CONFIG_CPU_V7M
+static int __get_cpu_architecture(void)
+{
+	return CPU_ARCH_ARMv7M;
+}
+#else
 static int __get_cpu_architecture(void)
 {
 	int cpu_arch;
@@ -248,6 +257,7 @@ static int __get_cpu_architecture(void)
 
 	return cpu_arch;
 }
+#endif
 
 int __pure cpu_architecture(void)
 {
@@ -293,7 +303,9 @@ static void __init cacheid_init(void)
 {
 	unsigned int arch = cpu_architecture();
 
-	if (arch >= CPU_ARCH_ARMv6) {
+	if (arch == CPU_ARCH_ARMv7M) {
+		cacheid = 0;
+	} else if (arch >= CPU_ARCH_ARMv6) {
 		unsigned int cachetype = read_cpuid_cachetype();
 		if ((cachetype & (7 << 29)) == 4 << 29) {
 			/* ARMv7 register format */
@@ -355,7 +367,7 @@ void __init early_print(const char *str,
 
 static void __init cpuid_init_hwcaps(void)
 {
-	unsigned int divide_instrs;
+	unsigned int divide_instrs, vmsa;
 
 	if (cpu_architecture() < CPU_ARCH_ARMv7)
 		return;
@@ -368,6 +380,11 @@ static void __init cpuid_init_hwcaps(voi
 	case 1:
 		elf_hwcap |= HWCAP_IDIVT;
 	}
+
+	/* LPAE implies atomic ldrd/strd instructions */
+	vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0;
+	if (vmsa >= 5)
+		elf_hwcap |= HWCAP_LPAE;
 }
 
 static void __init feat_v6_fixup(void)
@@ -392,6 +409,7 @@ static void __init feat_v6_fixup(void)
  */
 void notrace cpu_init(void)
 {
+#ifndef CONFIG_CPU_V7M
 	unsigned int cpu = smp_processor_id();
 	struct stack *stk = &stacks[cpu];
 
@@ -442,6 +460,7 @@ void notrace cpu_init(void)
 	      "I" (offsetof(struct stack, und[0])),
 	      PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
 	    : "r14");
+#endif
 }
 
 u32 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID };
@@ -456,9 +475,82 @@ void __init smp_setup_processor_id(void)
 	for (i = 1; i < nr_cpu_ids; ++i)
 		cpu_logical_map(i) = i == cpu ? 0 : i;
 
+	/*
+	 * clear __my_cpu_offset on boot CPU to avoid hang caused by
+	 * using percpu variable early, for example, lockdep will
+	 * access percpu variable inside lock_release
+	 */
+	set_my_cpu_offset(0);
+
 	printk(KERN_INFO "Booting Linux on physical CPU 0x%x\n", mpidr);
 }
 
+struct mpidr_hash mpidr_hash;
+#ifdef CONFIG_SMP
+/**
+ * smp_build_mpidr_hash - Pre-compute shifts required at each affinity
+ *			  level in order to build a linear index from an
+ *			  MPIDR value. Resulting algorithm is a collision
+ *			  free hash carried out through shifting and ORing
+ */
+static void __init smp_build_mpidr_hash(void)
+{
+	u32 i, affinity;
+	u32 fs[3], bits[3], ls, mask = 0;
+	/*
+	 * Pre-scan the list of MPIDRS and filter out bits that do
+	 * not contribute to affinity levels, ie they never toggle.
+	 */
+	for_each_possible_cpu(i)
+		mask |= (cpu_logical_map(i) ^ cpu_logical_map(0));
+	pr_debug("mask of set bits 0x%x\n", mask);
+	/*
+	 * Find and stash the last and first bit set at all affinity levels to
+	 * check how many bits are required to represent them.
+	 */
+	for (i = 0; i < 3; i++) {
+		affinity = MPIDR_AFFINITY_LEVEL(mask, i);
+		/*
+		 * Find the MSB bit and LSB bits position
+		 * to determine how many bits are required
+		 * to express the affinity level.
+		 */
+		ls = fls(affinity);
+		fs[i] = affinity ? ffs(affinity) - 1 : 0;
+		bits[i] = ls - fs[i];
+	}
+	/*
+	 * An index can be created from the MPIDR by isolating the
+	 * significant bits at each affinity level and by shifting
+	 * them in order to compress the 24 bits values space to a
+	 * compressed set of values. This is equivalent to hashing
+	 * the MPIDR through shifting and ORing. It is a collision free
+	 * hash though not minimal since some levels might contain a number
+	 * of CPUs that is not an exact power of 2 and their bit
+	 * representation might contain holes, eg MPIDR[7:0] = {0x2, 0x80}.
+	 */
+	mpidr_hash.shift_aff[0] = fs[0];
+	mpidr_hash.shift_aff[1] = MPIDR_LEVEL_BITS + fs[1] - bits[0];
+	mpidr_hash.shift_aff[2] = 2*MPIDR_LEVEL_BITS + fs[2] -
+						(bits[1] + bits[0]);
+	mpidr_hash.mask = mask;
+	mpidr_hash.bits = bits[2] + bits[1] + bits[0];
+	pr_debug("MPIDR hash: aff0[%u] aff1[%u] aff2[%u] mask[0x%x] bits[%u]\n",
+				mpidr_hash.shift_aff[0],
+				mpidr_hash.shift_aff[1],
+				mpidr_hash.shift_aff[2],
+				mpidr_hash.mask,
+				mpidr_hash.bits);
+	/*
+	 * 4x is an arbitrary value used to warn on a hash table much bigger
+	 * than expected on most systems.
+	 */
+	if (mpidr_hash_size() > 4 * num_possible_cpus())
+		pr_warn("Large number of MPIDR hash buckets detected\n");
+	sync_cache_w(&mpidr_hash);
+}
+#endif
+
 static void __init setup_processor(void)
 {
 	struct proc_info_list *list;
@@ -744,6 +836,8 @@ static int __init meminfo_cmp(const void
 void __init hyp_mode_check(void)
 {
 #ifdef CONFIG_ARM_VIRT_EXT
+	sync_boot_mode();
+
 	if (is_hyp_mode_available()) {
 		pr_info("CPU: All CPU(s) started in HYP mode.\n");
 		pr_info("CPU: Virtualization extensions available.\n");
@@ -769,8 +863,8 @@ void __init setup_arch(char **cmdline_p)
 
 	setup_dma_zone(mdesc);
 
-	if (mdesc->restart_mode)
-		reboot_setup(&mdesc->restart_mode);
+	if (mdesc->reboot_mode != REBOOT_HARD)
+		reboot_mode = mdesc->reboot_mode;
 
 	init_mm.start_code = (unsigned long) _text;
 	init_mm.end_code   = (unsigned long) _etext;
@@ -796,10 +890,17 @@ void __init setup_arch(char **cmdline_p)
 	unflatten_device_tree();
 
 	arm_dt_init_cpu_maps();
+	psci_init();
 #ifdef CONFIG_SMP
 	if (is_smp()) {
-		smp_set_ops(mdesc->smp);
+		if (!mdesc->smp_init || !mdesc->smp_init()) {
+			if (psci_smp_available())
+				smp_set_ops(&psci_smp_ops);
+			else if (mdesc->smp)
+				smp_set_ops(mdesc->smp);
+		}
 		smp_init_cpus();
+		smp_build_mpidr_hash();
 	}
 #endif
 
@@ -872,6 +973,8 @@ static const char *hwcap_str[] = {
 	"vfpv4",
 	"idiva",
 	"idivt",
+	"vfpd32",
+	"lpae",
 	NULL
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/signal.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/signal.c
--- linux-libre-3.10-gnu/arch/arm/kernel/signal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/signal.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/errno.h>
+#include <linux/random.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
 #include <linux/uaccess.h>
@@ -15,12 +16,11 @@
 
 #include <asm/elf.h>
 #include <asm/cacheflush.h>
+#include <asm/traps.h>
 #include <asm/ucontext.h>
 #include <asm/unistd.h>
 #include <asm/vfp.h>
 
-#include "signal.h"
-
 /*
  * For ARM syscalls, we encode the syscall number into the instruction.
  */
@@ -40,11 +40,13 @@
 #define SWI_THUMB_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
 #define SWI_THUMB_RT_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
 
-const unsigned long sigreturn_codes[7] = {
+static const unsigned long sigreturn_codes[7] = {
 	MOV_R7_NR_SIGRETURN,    SWI_SYS_SIGRETURN,    SWI_THUMB_SIGRETURN,
 	MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
 };
 
+static unsigned long signal_return_offset;
+
 #ifdef CONFIG_CRUNCH
 static int preserve_crunch_context(struct crunch_sigframe __user *frame)
 {
@@ -392,17 +394,28 @@ setup_return(struct pt_regs *regs, struc
 		if (ksig->ka.sa.sa_flags & SA_SIGINFO)
 			idx += 3;
 
+		/*
+		 * Put the sigreturn code on the stack no matter which return
+		 * mechanism we use in order to remain ABI compliant
+		 */
 		if (__put_user(sigreturn_codes[idx],   rc) ||
 		    __put_user(sigreturn_codes[idx+1], rc+1))
 			return 1;
 
+#ifdef CONFIG_MMU
 		if (cpsr & MODE32_BIT) {
+			struct mm_struct *mm = current->mm;
+
 			/*
-			 * 32-bit code can use the new high-page
-			 * signal return code support.
+			 * 32-bit code can use the signal return page
+			 * except when the MPU has protected the vectors
+			 * page from PL0
 			 */
-			retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
-		} else {
+			retcode = mm->context.sigpage + signal_return_offset +
+				  (idx << 2) + thumb;
+		} else
+#endif
+		{
 			/*
 			 * Ensure that the instruction cache sees
 			 * the return code written onto the stack.
@@ -603,3 +616,33 @@ do_work_pending(struct pt_regs *regs, un
 	} while (thread_flags & _TIF_WORK_MASK);
 	return 0;
 }
+
+struct page *get_signal_page(void)
+{
+	unsigned long ptr;
+	unsigned offset;
+	struct page *page;
+	void *addr;
+
+	page = alloc_pages(GFP_KERNEL, 0);
+
+	if (!page)
+		return NULL;
+
+	addr = page_address(page);
+
+	/* Give the signal return code some randomness */
+	offset = 0x200 + (get_random_int() & 0x7fc);
+	signal_return_offset = offset;
+
+	/*
+	 * Copy signal return handlers into the vector page, and
+	 * set sigreturn to be a pointer to these.
+	 */
+	memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
+
+	ptr = (unsigned long)addr + offset;
+	flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
+
+	return page;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/signal.h linux-libre-3.11-rc7-gnu/arch/arm/kernel/signal.h
--- linux-libre-3.10-gnu/arch/arm/kernel/signal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/signal.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-/*
- *  linux/arch/arm/kernel/signal.h
- *
- *  Copyright (C) 2005-2009 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#define KERN_SIGRETURN_CODE	(CONFIG_VECTORS_BASE + 0x00000500)
-
-extern const unsigned long sigreturn_codes[7];
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/sleep.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/sleep.S
--- linux-libre-3.10-gnu/arch/arm/kernel/sleep.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/sleep.S	2013-08-25 20:43:22.000000000 -0400
@@ -7,6 +7,49 @@
 	.text
 
 /*
+ * Implementation of MPIDR hash algorithm through shifting
+ * and OR'ing.
+ *
+ * @dst: register containing hash result
+ * @rs0: register containing affinity level 0 bit shift
+ * @rs1: register containing affinity level 1 bit shift
+ * @rs2: register containing affinity level 2 bit shift
+ * @mpidr: register containing MPIDR value
+ * @mask: register containing MPIDR mask
+ *
+ * Pseudo C-code:
+ *
+ *u32 dst;
+ *
+ *compute_mpidr_hash(u32 rs0, u32 rs1, u32 rs2, u32 mpidr, u32 mask) {
+ *	u32 aff0, aff1, aff2;
+ *	u32 mpidr_masked = mpidr & mask;
+ *	aff0 = mpidr_masked & 0xff;
+ *	aff1 = mpidr_masked & 0xff00;
+ *	aff2 = mpidr_masked & 0xff0000;
+ *	dst = (aff0 >> rs0 | aff1 >> rs1 | aff2 >> rs2);
+ *}
+ * Input registers: rs0, rs1, rs2, mpidr, mask
+ * Output register: dst
+ * Note: input and output registers must be disjoint register sets
+         (eg: a macro instance with mpidr = r1 and dst = r1 is invalid)
+ */
+	.macro compute_mpidr_hash dst, rs0, rs1, rs2, mpidr, mask
+	and	\mpidr, \mpidr, \mask			@ mask out MPIDR bits
+	and	\dst, \mpidr, #0xff			@ mask=aff0
+ ARM(	mov	\dst, \dst, lsr \rs0		)	@ dst=aff0>>rs0
+ THUMB(	lsr	\dst, \dst, \rs0		)
+	and	\mask, \mpidr, #0xff00			@ mask = aff1
+ ARM(	orr	\dst, \dst, \mask, lsr \rs1	)	@ dst|=(aff1>>rs1)
+ THUMB(	lsr	\mask, \mask, \rs1		)
+ THUMB(	orr	\dst, \dst, \mask		)
+	and	\mask, \mpidr, #0xff0000		@ mask = aff2
+ ARM(	orr	\dst, \dst, \mask, lsr \rs2	)	@ dst|=(aff2>>rs2)
+ THUMB(	lsr	\mask, \mask, \rs2		)
+ THUMB(	orr	\dst, \dst, \mask		)
+	.endm
+
+/*
  * Save CPU state for a suspend.  This saves the CPU general purpose
  * registers, and allocates space on the kernel stack to save the CPU
  * specific registers and some other data for resume.
@@ -29,12 +72,18 @@ ENTRY(__cpu_suspend)
 	mov	r1, r4			@ size of save block
 	mov	r2, r5			@ virtual SP
 	ldr	r3, =sleep_save_sp
-#ifdef CONFIG_SMP
-	ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
-	ALT_UP(mov lr, #0)
-	and	lr, lr, #15
+	ldr	r3, [r3, #SLEEP_SAVE_SP_VIRT]
+	ALT_SMP(mrc p15, 0, r9, c0, c0, 5)
+        ALT_UP_B(1f)
+	ldr	r8, =mpidr_hash
+	/*
+	 * This ldmia relies on the memory layout of the mpidr_hash
+	 * struct mpidr_hash.
+	 */
+	ldmia	r8, {r4-r7}	@ r4 = mpidr mask (r5,r6,r7) = l[0,1,2] shifts
+	compute_mpidr_hash	lr, r5, r6, r7, r9, r4
 	add	r3, r3, lr, lsl #2
-#endif
+1:
 	bl	__cpu_suspend_save
 	adr	lr, BSYM(cpu_suspend_abort)
 	ldmfd	sp!, {r0, pc}		@ call suspend fn
@@ -81,15 +130,23 @@ ENDPROC(cpu_resume_after_mmu)
 	.data
 	.align
 ENTRY(cpu_resume)
-#ifdef CONFIG_SMP
-	adr	r0, sleep_save_sp
-	ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
-	ALT_UP(mov r1, #0)
-	and	r1, r1, #15
-	ldr	r0, [r0, r1, lsl #2]	@ stack phys addr
-#else
-	ldr	r0, sleep_save_sp	@ stack phys addr
-#endif
+	mov	r1, #0
+	ALT_SMP(mrc p15, 0, r0, c0, c0, 5)
+	ALT_UP_B(1f)
+	adr	r2, mpidr_hash_ptr
+	ldr	r3, [r2]
+	add	r2, r2, r3		@ r2 = struct mpidr_hash phys address
+	/*
+	 * This ldmia relies on the memory layout of the mpidr_hash
+	 * struct mpidr_hash.
+	 */
+	ldmia	r2, { r3-r6 }	@ r3 = mpidr mask (r4,r5,r6) = l[0,1,2] shifts
+	compute_mpidr_hash	r1, r4, r5, r6, r0, r3
+1:
+	adr	r0, _sleep_save_sp
+	ldr	r0, [r0, #SLEEP_SAVE_SP_PHYS]
+	ldr	r0, [r0, r1, lsl #2]
+
 	setmode	PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1  @ set SVC, irqs off
 	@ load phys pgd, stack, resume fn
   ARM(	ldmia	r0!, {r1, sp, pc}	)
@@ -98,7 +155,11 @@ THUMB(	mov	sp, r2			)
 THUMB(	bx	r3			)
 ENDPROC(cpu_resume)
 
-sleep_save_sp:
-	.rept	CONFIG_NR_CPUS
-	.long	0				@ preserve stack phys ptr here
-	.endr
+	.align 2
+mpidr_hash_ptr:
+	.long	mpidr_hash - .			@ mpidr_hash struct offset
+
+	.type	sleep_save_sp, #object
+ENTRY(sleep_save_sp)
+_sleep_save_sp:
+	.space	SLEEP_SAVE_SP_SZ		@ struct sleep_save_sp
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/smp.c
--- linux-libre-3.10-gnu/arch/arm/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,6 +45,7 @@
 #include <asm/smp_plat.h>
 #include <asm/virt.h>
 #include <asm/mach/arch.h>
+#include <asm/mpu.h>
 
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
@@ -57,7 +58,7 @@ struct secondary_data secondary_data;
  * control for which core is the next to come out of the secondary
  * boot "holding pen"
  */
-volatile int __cpuinitdata pen_release = -1;
+volatile int pen_release = -1;
 
 enum ipi_msg_type {
 	IPI_WAKEUP,
@@ -78,7 +79,14 @@ void __init smp_set_ops(struct smp_opera
 		smp_ops = *ops;
 };
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
+static unsigned long get_arch_pgd(pgd_t *pgd)
+{
+	phys_addr_t pgdir = virt_to_phys(pgd);
+	BUG_ON(pgdir & ARCH_PGD_MASK);
+	return pgdir >> ARCH_PGD_SHIFT;
+}
+
+int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	int ret;
 
@@ -87,8 +95,14 @@ int __cpuinit __cpu_up(unsigned int cpu,
 	 * its stack and the page tables.
 	 */
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
-	secondary_data.pgdir = virt_to_phys(idmap_pgd);
-	secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir);
+#ifdef CONFIG_ARM_MPU
+	secondary_data.mpu_rgn_szr = mpu_rgn_info.rgns[MPU_RAM_REGION].drsr;
+#endif
+
+#ifdef CONFIG_MMU
+	secondary_data.pgdir = get_arch_pgd(idmap_pgd);
+	secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir);
+#endif
 	__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
 	outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
 
@@ -112,9 +126,8 @@ int __cpuinit __cpu_up(unsigned int cpu,
 		pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
 	}
 
-	secondary_data.stack = NULL;
-	secondary_data.pgdir = 0;
 
+	memset(&secondary_data, 0, sizeof(secondary_data));
 	return ret;
 }
 
@@ -125,13 +138,23 @@ void __init smp_init_cpus(void)
 		smp_ops.smp_init_cpus();
 }
 
-int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+int boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	if (smp_ops.smp_boot_secondary)
 		return smp_ops.smp_boot_secondary(cpu, idle);
 	return -ENOSYS;
 }
 
+int platform_can_cpu_hotplug(void)
+{
+#ifdef CONFIG_HOTPLUG_CPU
+	if (smp_ops.cpu_kill)
+		return 1;
+#endif
+
+	return 0;
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 static void percpu_timer_stop(void);
 
@@ -157,7 +180,7 @@ static int platform_cpu_disable(unsigned
 /*
  * __cpu_disable runs on the processor to be shutdown.
  */
-int __cpuinit __cpu_disable(void)
+int __cpu_disable(void)
 {
 	unsigned int cpu = smp_processor_id();
 	int ret;
@@ -203,7 +226,7 @@ static DECLARE_COMPLETION(cpu_died);
  * called on the thread which is asking for a CPU to be shutdown -
  * waits until shutdown has completed, or it is timed out.
  */
-void __cpuinit __cpu_die(unsigned int cpu)
+void __cpu_die(unsigned int cpu)
 {
 	if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
 		pr_err("CPU%u: cpu didn't die\n", cpu);
@@ -293,7 +316,7 @@ void __ref cpu_die(void)
  * Called by both boot and secondaries to move global data into
  * per-processor storage.
  */
-static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
+static void smp_store_cpu_info(unsigned int cpuid)
 {
 	struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
 
@@ -309,7 +332,7 @@ static void percpu_timer_setup(void);
  * This is the secondary CPU boot entry.  We're using this CPUs
  * idle thread stack, but a set of temporary page tables.
  */
-asmlinkage void __cpuinit secondary_start_kernel(void)
+asmlinkage void secondary_start_kernel(void)
 {
 	struct mm_struct *mm = &init_mm;
 	unsigned int cpu;
@@ -508,7 +531,7 @@ static void broadcast_timer_set_mode(enu
 {
 }
 
-static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
+static void broadcast_timer_setup(struct clock_event_device *evt)
 {
 	evt->name	= "dummy_timer";
 	evt->features	= CLOCK_EVT_FEAT_ONESHOT |
@@ -537,7 +560,7 @@ int local_timer_register(struct local_ti
 }
 #endif
 
-static void __cpuinit percpu_timer_setup(void)
+static void percpu_timer_setup(void)
 {
 	unsigned int cpu = smp_processor_id();
 	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/smp_tlb.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/smp_tlb.c
--- linux-libre-3.10-gnu/arch/arm/kernel/smp_tlb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/smp_tlb.c	2013-08-25 20:43:22.000000000 -0400
@@ -70,23 +70,6 @@ static inline void ipi_flush_bp_all(void
 	local_flush_bp_all();
 }
 
-#ifdef CONFIG_ARM_ERRATA_798181
-static int erratum_a15_798181(void)
-{
-	unsigned int midr = read_cpuid_id();
-
-	/* Cortex-A15 r0p0..r3p2 affected */
-	if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2)
-		return 0;
-	return 1;
-}
-#else
-static int erratum_a15_798181(void)
-{
-	return 0;
-}
-#endif
-
 static void ipi_flush_tlb_a15_erratum(void *arg)
 {
 	dmb();
@@ -103,7 +86,7 @@ static void broadcast_tlb_a15_erratum(vo
 
 static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm)
 {
-	int cpu, this_cpu;
+	int this_cpu;
 	cpumask_t mask = { CPU_BITS_NONE };
 
 	if (!erratum_a15_798181())
@@ -111,21 +94,7 @@ static void broadcast_tlb_mm_a15_erratum
 
 	dummy_flush_tlb_a15_erratum();
 	this_cpu = get_cpu();
-	for_each_online_cpu(cpu) {
-		if (cpu == this_cpu)
-			continue;
-		/*
-		 * We only need to send an IPI if the other CPUs are running
-		 * the same ASID as the one being invalidated. There is no
-		 * need for locking around the active_asids check since the
-		 * switch_mm() function has at least one dmb() (as required by
-		 * this workaround) in case a context switch happens on
-		 * another CPU after the condition below.
-		 */
-		if (atomic64_read(&mm->context.id) ==
-		    atomic64_read(&per_cpu(active_asids, cpu)))
-			cpumask_set_cpu(cpu, &mask);
-	}
+	a15_erratum_get_cpumask(this_cpu, mm, &mask);
 	smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1);
 	put_cpu();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/smp_twd.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/smp_twd.c
--- linux-libre-3.10-gnu/arch/arm/kernel/smp_twd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/smp_twd.c	2013-08-25 20:43:22.000000000 -0400
@@ -120,7 +120,7 @@ static int twd_rate_change(struct notifi
 	 * changing cpu.
 	 */
 	if (flags == POST_RATE_CHANGE)
-		smp_call_function(twd_update_frequency,
+		on_each_cpu(twd_update_frequency,
 				  (void *)&cnd->new_rate, 1);
 
 	return NOTIFY_OK;
@@ -187,7 +187,7 @@ core_initcall(twd_cpufreq_init);
 
 #endif
 
-static void __cpuinit twd_calibrate_rate(void)
+static void twd_calibrate_rate(void)
 {
 	unsigned long count;
 	u64 waitjiffies;
@@ -265,7 +265,7 @@ static void twd_get_clock(struct device_
 /*
  * Setup the local clock events for a CPU.
  */
-static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
+static int twd_timer_setup(struct clock_event_device *clk)
 {
 	struct clock_event_device **this_cpu_clk;
 	int cpu = smp_processor_id();
@@ -308,7 +308,7 @@ static int __cpuinit twd_timer_setup(str
 	return 0;
 }
 
-static struct local_timer_ops twd_lt_ops __cpuinitdata = {
+static struct local_timer_ops twd_lt_ops = {
 	.setup	= twd_timer_setup,
 	.stop	= twd_timer_stop,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/suspend.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/suspend.c
--- linux-libre-3.10-gnu/arch/arm/kernel/suspend.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/suspend.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,15 +1,54 @@
 #include <linux/init.h>
+#include <linux/slab.h>
 
+#include <asm/cacheflush.h>
 #include <asm/idmap.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/memory.h>
+#include <asm/smp_plat.h>
 #include <asm/suspend.h>
 #include <asm/tlbflush.h>
 
 extern int __cpu_suspend(unsigned long, int (*)(unsigned long));
 extern void cpu_resume_mmu(void);
 
+#ifdef CONFIG_MMU
+/*
+ * Hide the first two arguments to __cpu_suspend - these are an implementation
+ * detail which platform code shouldn't have to know about.
+ */
+int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+	struct mm_struct *mm = current->active_mm;
+	int ret;
+
+	if (!idmap_pgd)
+		return -EINVAL;
+
+	/*
+	 * Provide a temporary page table with an identity mapping for
+	 * the MMU-enable code, required for resuming.  On successful
+	 * resume (indicated by a zero return code), we need to switch
+	 * back to the correct page tables.
+	 */
+	ret = __cpu_suspend(arg, fn);
+	if (ret == 0) {
+		cpu_switch_mm(mm->pgd, mm);
+		local_flush_bp_all();
+		local_flush_tlb_all();
+	}
+
+	return ret;
+}
+#else
+int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+{
+	return __cpu_suspend(arg, fn);
+}
+#define	idmap_pgd	NULL
+#endif
+
 /*
  * This is called by __cpu_suspend() to save the state, and do whatever
  * flushing is required to ensure that when the CPU goes to sleep we have
@@ -47,30 +86,19 @@ void __cpu_suspend_save(u32 *ptr, u32 pt
 			  virt_to_phys(save_ptr) + sizeof(*save_ptr));
 }
 
-/*
- * Hide the first two arguments to __cpu_suspend - these are an implementation
- * detail which platform code shouldn't have to know about.
- */
-int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
-{
-	struct mm_struct *mm = current->active_mm;
-	int ret;
-
-	if (!idmap_pgd)
-		return -EINVAL;
+extern struct sleep_save_sp sleep_save_sp;
 
-	/*
-	 * Provide a temporary page table with an identity mapping for
-	 * the MMU-enable code, required for resuming.  On successful
-	 * resume (indicated by a zero return code), we need to switch
-	 * back to the correct page tables.
-	 */
-	ret = __cpu_suspend(arg, fn);
-	if (ret == 0) {
-		cpu_switch_mm(mm->pgd, mm);
-		local_flush_bp_all();
-		local_flush_tlb_all();
-	}
+static int cpu_suspend_alloc_sp(void)
+{
+	void *ctx_ptr;
+	/* ctx_ptr is an array of physical addresses */
+	ctx_ptr = kcalloc(mpidr_hash_size(), sizeof(u32), GFP_KERNEL);
 
-	return ret;
+	if (WARN_ON(!ctx_ptr))
+		return -ENOMEM;
+	sleep_save_sp.save_ptr_stash = ctx_ptr;
+	sleep_save_sp.save_ptr_stash_phys = virt_to_phys(ctx_ptr);
+	sync_cache_w(&sleep_save_sp);
+	return 0;
 }
+early_initcall(cpu_suspend_alloc_sp);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/time.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/time.c
--- linux-libre-3.10-gnu/arch/arm/kernel/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,9 +24,9 @@
 #include <linux/timer.h>
 #include <linux/clocksource.h>
 #include <linux/irq.h>
+#include <linux/sched_clock.h>
 
 #include <asm/thread_info.h>
-#include <asm/sched_clock.h>
 #include <asm/stacktrace.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
@@ -120,6 +120,4 @@ void __init time_init(void)
 		machine_desc->init_time();
 	else
 		clocksource_of_init();
-
-	sched_clock_postinit();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/arm/kernel/traps.c
--- linux-libre-3.10-gnu/arch/arm/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,8 +35,6 @@
 #include <asm/tls.h>
 #include <asm/system_misc.h>
 
-#include "signal.h"
-
 static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
 
 void *vectors_page;
@@ -581,7 +579,7 @@ asmlinkage int arm_syscall(int no, struc
 		return regs->ARM_r0;
 
 	case NR(set_tls):
-		thread->tp_value = regs->ARM_r0;
+		thread->tp_value[0] = regs->ARM_r0;
 		if (tls_emu)
 			return 0;
 		if (has_tls_reg) {
@@ -699,7 +697,7 @@ static int get_tp_trap(struct pt_regs *r
 	int reg = (instr >> 12) & 15;
 	if (reg == 15)
 		return 1;
-	regs->uregs[reg] = current_thread_info()->tp_value;
+	regs->uregs[reg] = current_thread_info()->tp_value[0];
 	regs->ARM_pc += 4;
 	return 0;
 }
@@ -800,47 +798,63 @@ void __init trap_init(void)
 	return;
 }
 
-static void __init kuser_get_tls_init(unsigned long vectors)
+#ifdef CONFIG_KUSER_HELPERS
+static void __init kuser_init(void *vectors)
 {
+	extern char __kuser_helper_start[], __kuser_helper_end[];
+	int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+
+	memcpy(vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
+
 	/*
 	 * vectors + 0xfe0 = __kuser_get_tls
 	 * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
 	 */
 	if (tls_emu || has_tls_reg)
-		memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4);
+		memcpy(vectors + 0xfe0, vectors + 0xfe8, 4);
 }
+#else
+static void __init kuser_init(void *vectors)
+{
+}
+#endif
 
 void __init early_trap_init(void *vectors_base)
 {
+#ifndef CONFIG_CPU_V7M
 	unsigned long vectors = (unsigned long)vectors_base;
 	extern char __stubs_start[], __stubs_end[];
 	extern char __vectors_start[], __vectors_end[];
-	extern char __kuser_helper_start[], __kuser_helper_end[];
-	int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+	unsigned i;
 
 	vectors_page = vectors_base;
 
 	/*
+	 * Poison the vectors page with an undefined instruction.  This
+	 * instruction is chosen to be undefined for both ARM and Thumb
+	 * ISAs.  The Thumb version is an undefined instruction with a
+	 * branch back to the undefined instruction.
+	 */
+	for (i = 0; i < PAGE_SIZE / sizeof(u32); i++)
+		((u32 *)vectors_base)[i] = 0xe7fddef1;
+
+	/*
 	 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
 	 * into the vector page, mapped at 0xffff0000, and ensure these
 	 * are visible to the instruction stream.
 	 */
 	memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
-	memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
-	memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
+	memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
 
-	/*
-	 * Do processor specific fixups for the kuser helpers
-	 */
-	kuser_get_tls_init(vectors);
+	kuser_init(vectors_base);
 
+	flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
+	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+#else /* ifndef CONFIG_CPU_V7M */
 	/*
-	 * Copy signal return handlers into the vector page, and
-	 * set sigreturn to be a pointer to these.
+	 * on V7-M there is no need to copy the vector table to a dedicated
+	 * memory area. The address is configurable and so a table in the kernel
+	 * image can be used.
 	 */
-	memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
-	       sigreturn_codes, sizeof(sigreturn_codes));
-
-	flush_icache_range(vectors, vectors + PAGE_SIZE);
-	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+#endif
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kernel/vmlinux.lds.S linux-libre-3.11-rc7-gnu/arch/arm/kernel/vmlinux.lds.S
--- linux-libre-3.10-gnu/arch/arm/kernel/vmlinux.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kernel/vmlinux.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -70,10 +70,6 @@ SECTIONS
 		ARM_EXIT_DISCARD(EXIT_TEXT)
 		ARM_EXIT_DISCARD(EXIT_DATA)
 		EXIT_CALL
-#ifndef CONFIG_HOTPLUG
-		*(.ARM.exidx.devexit.text)
-		*(.ARM.extab.devexit.text)
-#endif
 #ifndef CONFIG_MMU
 		*(.fixup)
 		*(__ex_table)
@@ -152,6 +148,23 @@ SECTIONS
 	. = ALIGN(PAGE_SIZE);
 	__init_begin = .;
 #endif
+	/*
+	 * The vectors and stubs are relocatable code, and the
+	 * only thing that matters is their relative offsets
+	 */
+	__vectors_start = .;
+	.vectors 0 : AT(__vectors_start) {
+		*(.vectors)
+	}
+	. = __vectors_start + SIZEOF(.vectors);
+	__vectors_end = .;
+
+	__stubs_start = .;
+	.stubs 0x1000 : AT(__stubs_start) {
+		*(.stubs)
+	}
+	. = __stubs_start + SIZEOF(.stubs);
+	__stubs_end = .;
 
 	INIT_TEXT_SECTION(8)
 	.exit.text : {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/arch_timer.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/arch_timer.c
--- linux-libre-3.10-gnu/arch/arm/kvm/arch_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/arch_timer.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Ltd.
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/cpu.h>
-#include <linux/of_irq.h>
-#include <linux/kvm.h>
-#include <linux/kvm_host.h>
-#include <linux/interrupt.h>
-
-#include <clocksource/arm_arch_timer.h>
-#include <asm/arch_timer.h>
-
-#include <asm/kvm_vgic.h>
-#include <asm/kvm_arch_timer.h>
-
-static struct timecounter *timecounter;
-static struct workqueue_struct *wqueue;
-static struct kvm_irq_level timer_irq = {
-	.level	= 1,
-};
-
-static cycle_t kvm_phys_timer_read(void)
-{
-	return timecounter->cc->read(timecounter->cc);
-}
-
-static bool timer_is_armed(struct arch_timer_cpu *timer)
-{
-	return timer->armed;
-}
-
-/* timer_arm: as in "arm the timer", not as in ARM the company */
-static void timer_arm(struct arch_timer_cpu *timer, u64 ns)
-{
-	timer->armed = true;
-	hrtimer_start(&timer->timer, ktime_add_ns(ktime_get(), ns),
-		      HRTIMER_MODE_ABS);
-}
-
-static void timer_disarm(struct arch_timer_cpu *timer)
-{
-	if (timer_is_armed(timer)) {
-		hrtimer_cancel(&timer->timer);
-		cancel_work_sync(&timer->expired);
-		timer->armed = false;
-	}
-}
-
-static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu)
-{
-	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
-
-	timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK;
-	kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
-			    vcpu->arch.timer_cpu.irq->irq,
-			    vcpu->arch.timer_cpu.irq->level);
-}
-
-static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
-{
-	struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id;
-
-	/*
-	 * We disable the timer in the world switch and let it be
-	 * handled by kvm_timer_sync_hwstate(). Getting a timer
-	 * interrupt at this point is a sure sign of some major
-	 * breakage.
-	 */
-	pr_warn("Unexpected interrupt %d on vcpu %p\n", irq, vcpu);
-	return IRQ_HANDLED;
-}
-
-static void kvm_timer_inject_irq_work(struct work_struct *work)
-{
-	struct kvm_vcpu *vcpu;
-
-	vcpu = container_of(work, struct kvm_vcpu, arch.timer_cpu.expired);
-	vcpu->arch.timer_cpu.armed = false;
-	kvm_timer_inject_irq(vcpu);
-}
-
-static enum hrtimer_restart kvm_timer_expire(struct hrtimer *hrt)
-{
-	struct arch_timer_cpu *timer;
-	timer = container_of(hrt, struct arch_timer_cpu, timer);
-	queue_work(wqueue, &timer->expired);
-	return HRTIMER_NORESTART;
-}
-
-/**
- * kvm_timer_flush_hwstate - prepare to move the virt timer to the cpu
- * @vcpu: The vcpu pointer
- *
- * Disarm any pending soft timers, since the world-switch code will write the
- * virtual timer state back to the physical CPU.
- */
-void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
-{
-	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
-
-	/*
-	 * We're about to run this vcpu again, so there is no need to
-	 * keep the background timer running, as we're about to
-	 * populate the CPU timer again.
-	 */
-	timer_disarm(timer);
-}
-
-/**
- * kvm_timer_sync_hwstate - sync timer state from cpu
- * @vcpu: The vcpu pointer
- *
- * Check if the virtual timer was armed and either schedule a corresponding
- * soft timer or inject directly if already expired.
- */
-void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
-{
-	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
-	cycle_t cval, now;
-	u64 ns;
-
-	if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) ||
-		!(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE))
-		return;
-
-	cval = timer->cntv_cval;
-	now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
-
-	BUG_ON(timer_is_armed(timer));
-
-	if (cval <= now) {
-		/*
-		 * Timer has already expired while we were not
-		 * looking. Inject the interrupt and carry on.
-		 */
-		kvm_timer_inject_irq(vcpu);
-		return;
-	}
-
-	ns = cyclecounter_cyc2ns(timecounter->cc, cval - now);
-	timer_arm(timer, ns);
-}
-
-void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
-{
-	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
-
-	INIT_WORK(&timer->expired, kvm_timer_inject_irq_work);
-	hrtimer_init(&timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-	timer->timer.function = kvm_timer_expire;
-	timer->irq = &timer_irq;
-}
-
-static void kvm_timer_init_interrupt(void *info)
-{
-	enable_percpu_irq(timer_irq.irq, 0);
-}
-
-
-static int kvm_timer_cpu_notify(struct notifier_block *self,
-				unsigned long action, void *cpu)
-{
-	switch (action) {
-	case CPU_STARTING:
-	case CPU_STARTING_FROZEN:
-		kvm_timer_init_interrupt(NULL);
-		break;
-	case CPU_DYING:
-	case CPU_DYING_FROZEN:
-		disable_percpu_irq(timer_irq.irq);
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block kvm_timer_cpu_nb = {
-	.notifier_call = kvm_timer_cpu_notify,
-};
-
-static const struct of_device_id arch_timer_of_match[] = {
-	{ .compatible	= "arm,armv7-timer",	},
-	{},
-};
-
-int kvm_timer_hyp_init(void)
-{
-	struct device_node *np;
-	unsigned int ppi;
-	int err;
-
-	timecounter = arch_timer_get_timecounter();
-	if (!timecounter)
-		return -ENODEV;
-
-	np = of_find_matching_node(NULL, arch_timer_of_match);
-	if (!np) {
-		kvm_err("kvm_arch_timer: can't find DT node\n");
-		return -ENODEV;
-	}
-
-	ppi = irq_of_parse_and_map(np, 2);
-	if (!ppi) {
-		kvm_err("kvm_arch_timer: no virtual timer interrupt\n");
-		err = -EINVAL;
-		goto out;
-	}
-
-	err = request_percpu_irq(ppi, kvm_arch_timer_handler,
-				 "kvm guest timer", kvm_get_running_vcpus());
-	if (err) {
-		kvm_err("kvm_arch_timer: can't request interrupt %d (%d)\n",
-			ppi, err);
-		goto out;
-	}
-
-	timer_irq.irq = ppi;
-
-	err = register_cpu_notifier(&kvm_timer_cpu_nb);
-	if (err) {
-		kvm_err("Cannot register timer CPU notifier\n");
-		goto out_free;
-	}
-
-	wqueue = create_singlethread_workqueue("kvm_arch_timer");
-	if (!wqueue) {
-		err = -ENOMEM;
-		goto out_free;
-	}
-
-	kvm_info("%s IRQ%d\n", np->name, ppi);
-	on_each_cpu(kvm_timer_init_interrupt, NULL, 1);
-
-	goto out;
-out_free:
-	free_percpu_irq(ppi, kvm_get_running_vcpus());
-out:
-	of_node_put(np);
-	return err;
-}
-
-void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
-{
-	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
-
-	timer_disarm(timer);
-}
-
-int kvm_timer_init(struct kvm *kvm)
-{
-	if (timecounter && wqueue) {
-		kvm->arch.timer.cntvoff = kvm_phys_timer_read();
-		kvm->arch.timer.enabled = 1;
-	}
-
-	return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/arm.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/arm.c
--- linux-libre-3.10-gnu/arch/arm/kvm/arm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/arm.c	2013-08-25 20:43:22.000000000 -0400
@@ -800,8 +800,8 @@ long kvm_arch_vm_ioctl(struct file *filp
 
 static void cpu_init_hyp_mode(void *dummy)
 {
-	unsigned long long boot_pgd_ptr;
-	unsigned long long pgd_ptr;
+	phys_addr_t boot_pgd_ptr;
+	phys_addr_t pgd_ptr;
 	unsigned long hyp_stack_ptr;
 	unsigned long stack_page;
 	unsigned long vector_ptr;
@@ -809,8 +809,8 @@ static void cpu_init_hyp_mode(void *dumm
 	/* Switch from the HYP stub to our own HYP init vector */
 	__hyp_set_vectors(kvm_get_idmap_vector());
 
-	boot_pgd_ptr = (unsigned long long)kvm_mmu_get_boot_httbr();
-	pgd_ptr = (unsigned long long)kvm_mmu_get_httbr();
+	boot_pgd_ptr = kvm_mmu_get_boot_httbr();
+	pgd_ptr = kvm_mmu_get_httbr();
 	stack_page = __get_cpu_var(kvm_arm_hyp_stack_page);
 	hyp_stack_ptr = stack_page + PAGE_SIZE;
 	vector_ptr = (unsigned long)__kvm_hyp_vector;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/coproc_a15.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/coproc_a15.c
--- linux-libre-3.10-gnu/arch/arm/kvm/coproc_a15.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/coproc_a15.c	2013-08-25 20:43:22.000000000 -0400
@@ -114,7 +114,11 @@ static bool access_l2ectlr(struct kvm_vc
 
 /*
  * A15-specific CP15 registers.
- * Important: Must be sorted ascending by CRn, CRM, Op1, Op2
+ * CRn denotes the primary register number, but is copied to the CRm in the
+ * user space API for 64-bit register access in line with the terminology used
+ * in the ARM ARM.
+ * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
+ *            registers preceding 32-bit ones.
  */
 static const struct coproc_reg a15_regs[] = {
 	/* MPIDR: we use VMPIDR for guest access. */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/coproc.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/coproc.c
--- linux-libre-3.10-gnu/arch/arm/kvm/coproc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/coproc.c	2013-08-25 20:43:22.000000000 -0400
@@ -146,7 +146,11 @@ static bool pm_fake(struct kvm_vcpu *vcp
 #define access_pmintenclr pm_fake
 
 /* Architected CP15 registers.
- * Important: Must be sorted ascending by CRn, CRM, Op1, Op2
+ * CRn denotes the primary register number, but is copied to the CRm in the
+ * user space API for 64-bit register access in line with the terminology used
+ * in the ARM ARM.
+ * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
+ *            registers preceding 32-bit ones.
  */
 static const struct coproc_reg cp15_regs[] = {
 	/* CSSELR: swapped by interrupt.S. */
@@ -154,8 +158,8 @@ static const struct coproc_reg cp15_regs
 			NULL, reset_unknown, c0_CSSELR },
 
 	/* TTBR0/TTBR1: swapped by interrupt.S. */
-	{ CRm( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 },
-	{ CRm( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 },
+	{ CRm64( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 },
+	{ CRm64( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 },
 
 	/* TTBCR: swapped by interrupt.S. */
 	{ CRn( 2), CRm( 0), Op1( 0), Op2( 2), is32,
@@ -180,6 +184,10 @@ static const struct coproc_reg cp15_regs
 			NULL, reset_unknown, c6_DFAR },
 	{ CRn( 6), CRm( 0), Op1( 0), Op2( 2), is32,
 			NULL, reset_unknown, c6_IFAR },
+
+	/* PAR swapped by interrupt.S */
+	{ CRm64( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR },
+
 	/*
 	 * DC{C,I,CI}SW operations:
 	 */
@@ -395,12 +403,13 @@ static bool index_to_params(u64 id, stru
 			      | KVM_REG_ARM_OPC1_MASK))
 			return false;
 		params->is_64bit = true;
-		params->CRm = ((id & KVM_REG_ARM_CRM_MASK)
+		/* CRm to CRn: see cp15_to_index for details */
+		params->CRn = ((id & KVM_REG_ARM_CRM_MASK)
 			       >> KVM_REG_ARM_CRM_SHIFT);
 		params->Op1 = ((id & KVM_REG_ARM_OPC1_MASK)
 			       >> KVM_REG_ARM_OPC1_SHIFT);
 		params->Op2 = 0;
-		params->CRn = 0;
+		params->CRm = 0;
 		return true;
 	default:
 		return false;
@@ -894,7 +903,14 @@ static u64 cp15_to_index(const struct co
 	if (reg->is_64) {
 		val |= KVM_REG_SIZE_U64;
 		val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT);
-		val |= (reg->CRm << KVM_REG_ARM_CRM_SHIFT);
+		/*
+		 * CRn always denotes the primary coproc. reg. nr. for the
+		 * in-kernel representation, but the user space API uses the
+		 * CRm for the encoding, because it is modelled after the
+		 * MRRC/MCRR instructions: see the ARM ARM rev. c page
+		 * B3-1445
+		 */
+		val |= (reg->CRn << KVM_REG_ARM_CRM_SHIFT);
 	} else {
 		val |= KVM_REG_SIZE_U32;
 		val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/coproc.h linux-libre-3.11-rc7-gnu/arch/arm/kvm/coproc.h
--- linux-libre-3.10-gnu/arch/arm/kvm/coproc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/coproc.h	2013-08-25 20:43:22.000000000 -0400
@@ -135,6 +135,8 @@ static inline int cmp_reg(const struct c
 		return -1;
 	if (i1->CRn != i2->CRn)
 		return i1->CRn - i2->CRn;
+	if (i1->is_64 != i2->is_64)
+		return i2->is_64 - i1->is_64;
 	if (i1->CRm != i2->CRm)
 		return i1->CRm - i2->CRm;
 	if (i1->Op1 != i2->Op1)
@@ -145,6 +147,7 @@ static inline int cmp_reg(const struct c
 
 #define CRn(_x)		.CRn = _x
 #define CRm(_x) 	.CRm = _x
+#define CRm64(_x)       .CRn = _x, .CRm = 0
 #define Op1(_x) 	.Op1 = _x
 #define Op2(_x) 	.Op2 = _x
 #define is64		.is_64 = true
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/handle_exit.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/handle_exit.c
--- linux-libre-3.10-gnu/arch/arm/kvm/handle_exit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/handle_exit.c	2013-08-25 20:43:22.000000000 -0400
@@ -52,9 +52,6 @@ static int handle_hvc(struct kvm_vcpu *v
 
 static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
-	if (kvm_psci_call(vcpu))
-		return 1;
-
 	kvm_inject_undefined(vcpu);
 	return 1;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/interrupts_head.S linux-libre-3.11-rc7-gnu/arch/arm/kvm/interrupts_head.S
--- linux-libre-3.10-gnu/arch/arm/kvm/interrupts_head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/interrupts_head.S	2013-08-25 20:43:22.000000000 -0400
@@ -302,11 +302,14 @@ vcpu	.req	r0		@ vcpu pointer always in r
 	.endif
 
 	mrc	p15, 0, r2, c14, c1, 0	@ CNTKCTL
+	mrrc	p15, 0, r4, r5, c7	@ PAR
 
 	.if \store_to_vcpu == 0
-	push	{r2}
+	push	{r2,r4-r5}
 	.else
 	str	r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
+	add	r12, vcpu, #CP15_OFFSET(c7_PAR)
+	strd	r4, r5, [r12]
 	.endif
 .endm
 
@@ -319,12 +322,15 @@ vcpu	.req	r0		@ vcpu pointer always in r
  */
 .macro write_cp15_state read_from_vcpu
 	.if \read_from_vcpu == 0
-	pop	{r2}
+	pop	{r2,r4-r5}
 	.else
 	ldr	r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)]
+	add	r12, vcpu, #CP15_OFFSET(c7_PAR)
+	ldrd	r4, r5, [r12]
 	.endif
 
 	mcr	p15, 0, r2, c14, c1, 0	@ CNTKCTL
+	mcrr	p15, 0, r4, r5, c7	@ PAR
 
 	.if \read_from_vcpu == 0
 	pop	{r2-r12}
@@ -497,6 +503,10 @@ vcpu	.req	r0		@ vcpu pointer always in r
 	add	r5, vcpu, r4
 	strd	r2, r3, [r5]
 
+	@ Ensure host CNTVCT == CNTPCT
+	mov	r2, #0
+	mcrr	p15, 4, r2, r2, c14	@ CNTVOFF
+
 1:
 #endif
 	@ Allow physical timer/counter access for the host
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/interrupts.S linux-libre-3.11-rc7-gnu/arch/arm/kvm/interrupts.S
--- linux-libre-3.10-gnu/arch/arm/kvm/interrupts.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/interrupts.S	2013-08-25 20:43:22.000000000 -0400
@@ -49,6 +49,7 @@ __kvm_hyp_code_start:
 ENTRY(__kvm_tlb_flush_vmid_ipa)
 	push	{r2, r3}
 
+	dsb	ishst
 	add	r0, r0, #KVM_VTTBR
 	ldrd	r2, r3, [r0]
 	mcrr	p15, 6, r2, r3, c2	@ Write VTTBR
@@ -291,6 +292,7 @@ THUMB(	orr	r2, r2, #PSR_T_BIT	)
 	ldr	r2, =BSYM(panic)
 	msr	ELR_hyp, r2
 	ldr	r0, =\panic_str
+	clrex				@ Clear exclusive monitor
 	eret
 .endm
 
@@ -414,6 +416,10 @@ guest_trap:
 	mrcne	p15, 4, r2, c6, c0, 4	@ HPFAR
 	bne	3f
 
+	/* Preserve PAR */
+	mrrc	p15, 0, r0, r1, c7	@ PAR
+	push	{r0, r1}
+
 	/* Resolve IPA using the xFAR */
 	mcr	p15, 0, r2, c7, c8, 0	@ ATS1CPR
 	isb
@@ -424,13 +430,20 @@ guest_trap:
 	lsl	r2, r2, #4
 	orr	r2, r2, r1, lsl #24
 
+	/* Restore PAR */
+	pop	{r0, r1}
+	mcrr	p15, 0, r0, r1, c7	@ PAR
+
 3:	load_vcpu			@ Load VCPU pointer to r0
 	str	r2, [r0, #VCPU_HPFAR]
 
 1:	mov	r1, #ARM_EXCEPTION_HVC
 	b	__kvm_vcpu_return
 
-4:	pop	{r0, r1, r2}		@ Failed translation, return to guest
+4:	pop	{r0, r1}		@ Failed translation, return to guest
+	mcrr	p15, 0, r0, r1, c7	@ PAR
+	clrex
+	pop	{r0, r1, r2}
 	eret
 
 /*
@@ -456,6 +469,7 @@ switch_to_guest_vfp:
 
 	pop	{r3-r7}
 	pop	{r0-r2}
+	clrex
 	eret
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/kvm/Kconfig
--- linux-libre-3.10-gnu/arch/arm/kvm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -41,9 +41,9 @@ config KVM_ARM_HOST
 	  Provides host support for ARM processors.
 
 config KVM_ARM_MAX_VCPUS
-	int "Number maximum supported virtual CPUs per VM" if KVM_ARM_HOST
-	default 4 if KVM_ARM_HOST
-	default 0
+	int "Number maximum supported virtual CPUs per VM"
+	depends on KVM_ARM_HOST
+	default 4
 	help
 	  Static number of max supported virtual CPUs per VM.
 
@@ -67,6 +67,4 @@ config KVM_ARM_TIMER
 	---help---
 	  Adds support for the Architected Timers in virtual machines
 
-source drivers/virtio/Kconfig
-
 endif # VIRTUALIZATION
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/Makefile linux-libre-3.11-rc7-gnu/arch/arm/kvm/Makefile
--- linux-libre-3.10-gnu/arch/arm/kvm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,11 @@ CFLAGS_mmu.o := -I.
 AFLAGS_init.o := -Wa,-march=armv7-a$(plus_virt)
 AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt)
 
-kvm-arm-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
+KVM := ../../../virt/kvm
+kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o
 
 obj-y += kvm-arm.o init.o interrupts.o
 obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
 obj-y += coproc.o coproc_a15.o mmio.o psci.o perf.o
-obj-$(CONFIG_KVM_ARM_VGIC) += vgic.o
-obj-$(CONFIG_KVM_ARM_TIMER) += arch_timer.o
+obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o
+obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/mmio.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/mmio.c
--- linux-libre-3.10-gnu/arch/arm/kvm/mmio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/mmio.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,7 +63,8 @@ int kvm_handle_mmio_return(struct kvm_vc
 static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		      struct kvm_exit_mmio *mmio)
 {
-	unsigned long rt, len;
+	unsigned long rt;
+	int len;
 	bool is_write, sign_extend;
 
 	if (kvm_vcpu_dabt_isextabt(vcpu)) {
@@ -86,12 +87,6 @@ static int decode_hsr(struct kvm_vcpu *v
 	sign_extend = kvm_vcpu_dabt_issext(vcpu);
 	rt = kvm_vcpu_dabt_get_rd(vcpu);
 
-	if (kvm_vcpu_reg_is_pc(vcpu, rt)) {
-		/* IO memory trying to read/write pc */
-		kvm_inject_pabt(vcpu, kvm_vcpu_get_hfar(vcpu));
-		return 1;
-	}
-
 	mmio->is_write = is_write;
 	mmio->phys_addr = fault_ipa;
 	mmio->len = len;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/mmu.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/mmu.c
--- linux-libre-3.10-gnu/arch/arm/kvm/mmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/mmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -85,6 +85,12 @@ static void *mmu_memory_cache_alloc(stru
 	return p;
 }
 
+static bool page_empty(void *ptr)
+{
+	struct page *ptr_page = virt_to_page(ptr);
+	return page_count(ptr_page) == 1;
+}
+
 static void clear_pud_entry(struct kvm *kvm, pud_t *pud, phys_addr_t addr)
 {
 	pmd_t *pmd_table = pmd_offset(pud, 0);
@@ -103,12 +109,6 @@ static void clear_pmd_entry(struct kvm *
 	put_page(virt_to_page(pmd));
 }
 
-static bool pmd_empty(pmd_t *pmd)
-{
-	struct page *pmd_page = virt_to_page(pmd);
-	return page_count(pmd_page) == 1;
-}
-
 static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr)
 {
 	if (pte_present(*pte)) {
@@ -118,12 +118,6 @@ static void clear_pte_entry(struct kvm *
 	}
 }
 
-static bool pte_empty(pte_t *pte)
-{
-	struct page *pte_page = virt_to_page(pte);
-	return page_count(pte_page) == 1;
-}
-
 static void unmap_range(struct kvm *kvm, pgd_t *pgdp,
 			unsigned long long start, u64 size)
 {
@@ -132,37 +126,37 @@ static void unmap_range(struct kvm *kvm,
 	pmd_t *pmd;
 	pte_t *pte;
 	unsigned long long addr = start, end = start + size;
-	u64 range;
+	u64 next;
 
 	while (addr < end) {
 		pgd = pgdp + pgd_index(addr);
 		pud = pud_offset(pgd, addr);
 		if (pud_none(*pud)) {
-			addr += PUD_SIZE;
+			addr = pud_addr_end(addr, end);
 			continue;
 		}
 
 		pmd = pmd_offset(pud, addr);
 		if (pmd_none(*pmd)) {
-			addr += PMD_SIZE;
+			addr = pmd_addr_end(addr, end);
 			continue;
 		}
 
 		pte = pte_offset_kernel(pmd, addr);
 		clear_pte_entry(kvm, pte, addr);
-		range = PAGE_SIZE;
+		next = addr + PAGE_SIZE;
 
 		/* If we emptied the pte, walk back up the ladder */
-		if (pte_empty(pte)) {
+		if (page_empty(pte)) {
 			clear_pmd_entry(kvm, pmd, addr);
-			range = PMD_SIZE;
-			if (pmd_empty(pmd)) {
+			next = pmd_addr_end(addr, end);
+			if (page_empty(pmd) && !page_empty(pud)) {
 				clear_pud_entry(kvm, pud, addr);
-				range = PUD_SIZE;
+				next = pud_addr_end(addr, end);
 			}
 		}
 
-		addr += range;
+		addr = next;
 	}
 }
 
@@ -382,9 +376,6 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm
 	if (!pgd)
 		return -ENOMEM;
 
-	/* stage-2 pgd must be aligned to its size */
-	VM_BUG_ON((unsigned long)pgd & (S2_PGD_SIZE - 1));
-
 	memset(pgd, 0, PTRS_PER_S2_PGD * sizeof(pgd_t));
 	kvm_clean_pgd(pgd);
 	kvm->arch.pgd = pgd;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/psci.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/psci.c
--- linux-libre-3.10-gnu/arch/arm/kvm/psci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/psci.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,7 +75,7 @@ static unsigned long kvm_psci_vcpu_on(st
  * kvm_psci_call - handle PSCI call if r0 value is in range
  * @vcpu: Pointer to the VCPU struct
  *
- * Handle PSCI calls from guests through traps from HVC or SMC instructions.
+ * Handle PSCI calls from guests through traps from HVC instructions.
  * The calling convention is similar to SMC calls to the secure world where
  * the function number is placed in r0 and this function returns true if the
  * function number specified in r0 is withing the PSCI range, and false
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/reset.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/reset.c
--- linux-libre-3.10-gnu/arch/arm/kvm/reset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/reset.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,8 @@
 #include <asm/kvm_arm.h>
 #include <asm/kvm_coproc.h>
 
+#include <kvm/arm_arch_timer.h>
+
 /******************************************************************************
  * Cortex-A15 Reset Values
  */
@@ -37,6 +39,11 @@ static struct kvm_regs a15_regs_reset =
 	.usr_regs.ARM_cpsr = SVC_MODE | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT,
 };
 
+static const struct kvm_irq_level a15_vtimer_irq = {
+	.irq = 27,
+	.level = 1,
+};
+
 
 /*******************************************************************************
  * Exported reset function
@@ -52,6 +59,7 @@ static struct kvm_regs a15_regs_reset =
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 {
 	struct kvm_regs *cpu_reset;
+	const struct kvm_irq_level *cpu_vtimer_irq;
 
 	switch (vcpu->arch.target) {
 	case KVM_ARM_TARGET_CORTEX_A15:
@@ -59,6 +67,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu
 			return -EINVAL;
 		cpu_reset = &a15_regs_reset;
 		vcpu->arch.midr = read_cpuid_id();
+		cpu_vtimer_irq = &a15_vtimer_irq;
 		break;
 	default:
 		return -ENODEV;
@@ -70,5 +79,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu
 	/* Reset CP15 registers */
 	kvm_reset_coprocs(vcpu);
 
+	/* Reset arch_timer context */
+	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
+
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/kvm/vgic.c linux-libre-3.11-rc7-gnu/arch/arm/kvm/vgic.c
--- linux-libre-3.10-gnu/arch/arm/kvm/vgic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/kvm/vgic.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1499 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Ltd.
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/cpu.h>
-#include <linux/kvm.h>
-#include <linux/kvm_host.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-
-#include <linux/irqchip/arm-gic.h>
-
-#include <asm/kvm_emulate.h>
-#include <asm/kvm_arm.h>
-#include <asm/kvm_mmu.h>
-
-/*
- * How the whole thing works (courtesy of Christoffer Dall):
- *
- * - At any time, the dist->irq_pending_on_cpu is the oracle that knows if
- *   something is pending
- * - VGIC pending interrupts are stored on the vgic.irq_state vgic
- *   bitmap (this bitmap is updated by both user land ioctls and guest
- *   mmio ops, and other in-kernel peripherals such as the
- *   arch. timers) and indicate the 'wire' state.
- * - Every time the bitmap changes, the irq_pending_on_cpu oracle is
- *   recalculated
- * - To calculate the oracle, we need info for each cpu from
- *   compute_pending_for_cpu, which considers:
- *   - PPI: dist->irq_state & dist->irq_enable
- *   - SPI: dist->irq_state & dist->irq_enable & dist->irq_spi_target
- *   - irq_spi_target is a 'formatted' version of the GICD_ICFGR
- *     registers, stored on each vcpu. We only keep one bit of
- *     information per interrupt, making sure that only one vcpu can
- *     accept the interrupt.
- * - The same is true when injecting an interrupt, except that we only
- *   consider a single interrupt at a time. The irq_spi_cpu array
- *   contains the target CPU for each SPI.
- *
- * The handling of level interrupts adds some extra complexity. We
- * need to track when the interrupt has been EOIed, so we can sample
- * the 'line' again. This is achieved as such:
- *
- * - When a level interrupt is moved onto a vcpu, the corresponding
- *   bit in irq_active is set. As long as this bit is set, the line
- *   will be ignored for further interrupts. The interrupt is injected
- *   into the vcpu with the GICH_LR_EOI bit set (generate a
- *   maintenance interrupt on EOI).
- * - When the interrupt is EOIed, the maintenance interrupt fires,
- *   and clears the corresponding bit in irq_active. This allow the
- *   interrupt line to be sampled again.
- */
-
-#define VGIC_ADDR_UNDEF		(-1)
-#define IS_VGIC_ADDR_UNDEF(_x)  ((_x) == VGIC_ADDR_UNDEF)
-
-/* Physical address of vgic virtual cpu interface */
-static phys_addr_t vgic_vcpu_base;
-
-/* Virtual control interface base address */
-static void __iomem *vgic_vctrl_base;
-
-static struct device_node *vgic_node;
-
-#define ACCESS_READ_VALUE	(1 << 0)
-#define ACCESS_READ_RAZ		(0 << 0)
-#define ACCESS_READ_MASK(x)	((x) & (1 << 0))
-#define ACCESS_WRITE_IGNORED	(0 << 1)
-#define ACCESS_WRITE_SETBIT	(1 << 1)
-#define ACCESS_WRITE_CLEARBIT	(2 << 1)
-#define ACCESS_WRITE_VALUE	(3 << 1)
-#define ACCESS_WRITE_MASK(x)	((x) & (3 << 1))
-
-static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
-static void vgic_update_state(struct kvm *kvm);
-static void vgic_kick_vcpus(struct kvm *kvm);
-static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg);
-static u32 vgic_nr_lr;
-
-static unsigned int vgic_maint_irq;
-
-static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x,
-				int cpuid, u32 offset)
-{
-	offset >>= 2;
-	if (!offset)
-		return x->percpu[cpuid].reg;
-	else
-		return x->shared.reg + offset - 1;
-}
-
-static int vgic_bitmap_get_irq_val(struct vgic_bitmap *x,
-				   int cpuid, int irq)
-{
-	if (irq < VGIC_NR_PRIVATE_IRQS)
-		return test_bit(irq, x->percpu[cpuid].reg_ul);
-
-	return test_bit(irq - VGIC_NR_PRIVATE_IRQS, x->shared.reg_ul);
-}
-
-static void vgic_bitmap_set_irq_val(struct vgic_bitmap *x, int cpuid,
-				    int irq, int val)
-{
-	unsigned long *reg;
-
-	if (irq < VGIC_NR_PRIVATE_IRQS) {
-		reg = x->percpu[cpuid].reg_ul;
-	} else {
-		reg =  x->shared.reg_ul;
-		irq -= VGIC_NR_PRIVATE_IRQS;
-	}
-
-	if (val)
-		set_bit(irq, reg);
-	else
-		clear_bit(irq, reg);
-}
-
-static unsigned long *vgic_bitmap_get_cpu_map(struct vgic_bitmap *x, int cpuid)
-{
-	if (unlikely(cpuid >= VGIC_MAX_CPUS))
-		return NULL;
-	return x->percpu[cpuid].reg_ul;
-}
-
-static unsigned long *vgic_bitmap_get_shared_map(struct vgic_bitmap *x)
-{
-	return x->shared.reg_ul;
-}
-
-static u32 *vgic_bytemap_get_reg(struct vgic_bytemap *x, int cpuid, u32 offset)
-{
-	offset >>= 2;
-	BUG_ON(offset > (VGIC_NR_IRQS / 4));
-	if (offset < 4)
-		return x->percpu[cpuid] + offset;
-	else
-		return x->shared + offset - 8;
-}
-
-#define VGIC_CFG_LEVEL	0
-#define VGIC_CFG_EDGE	1
-
-static bool vgic_irq_is_edge(struct kvm_vcpu *vcpu, int irq)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-	int irq_val;
-
-	irq_val = vgic_bitmap_get_irq_val(&dist->irq_cfg, vcpu->vcpu_id, irq);
-	return irq_val == VGIC_CFG_EDGE;
-}
-
-static int vgic_irq_is_enabled(struct kvm_vcpu *vcpu, int irq)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	return vgic_bitmap_get_irq_val(&dist->irq_enabled, vcpu->vcpu_id, irq);
-}
-
-static int vgic_irq_is_active(struct kvm_vcpu *vcpu, int irq)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	return vgic_bitmap_get_irq_val(&dist->irq_active, vcpu->vcpu_id, irq);
-}
-
-static void vgic_irq_set_active(struct kvm_vcpu *vcpu, int irq)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	vgic_bitmap_set_irq_val(&dist->irq_active, vcpu->vcpu_id, irq, 1);
-}
-
-static void vgic_irq_clear_active(struct kvm_vcpu *vcpu, int irq)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	vgic_bitmap_set_irq_val(&dist->irq_active, vcpu->vcpu_id, irq, 0);
-}
-
-static int vgic_dist_irq_is_pending(struct kvm_vcpu *vcpu, int irq)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	return vgic_bitmap_get_irq_val(&dist->irq_state, vcpu->vcpu_id, irq);
-}
-
-static void vgic_dist_irq_set(struct kvm_vcpu *vcpu, int irq)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	vgic_bitmap_set_irq_val(&dist->irq_state, vcpu->vcpu_id, irq, 1);
-}
-
-static void vgic_dist_irq_clear(struct kvm_vcpu *vcpu, int irq)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	vgic_bitmap_set_irq_val(&dist->irq_state, vcpu->vcpu_id, irq, 0);
-}
-
-static void vgic_cpu_irq_set(struct kvm_vcpu *vcpu, int irq)
-{
-	if (irq < VGIC_NR_PRIVATE_IRQS)
-		set_bit(irq, vcpu->arch.vgic_cpu.pending_percpu);
-	else
-		set_bit(irq - VGIC_NR_PRIVATE_IRQS,
-			vcpu->arch.vgic_cpu.pending_shared);
-}
-
-static void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq)
-{
-	if (irq < VGIC_NR_PRIVATE_IRQS)
-		clear_bit(irq, vcpu->arch.vgic_cpu.pending_percpu);
-	else
-		clear_bit(irq - VGIC_NR_PRIVATE_IRQS,
-			  vcpu->arch.vgic_cpu.pending_shared);
-}
-
-static u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask)
-{
-	return *((u32 *)mmio->data) & mask;
-}
-
-static void mmio_data_write(struct kvm_exit_mmio *mmio, u32 mask, u32 value)
-{
-	*((u32 *)mmio->data) = value & mask;
-}
-
-/**
- * vgic_reg_access - access vgic register
- * @mmio:   pointer to the data describing the mmio access
- * @reg:    pointer to the virtual backing of vgic distributor data
- * @offset: least significant 2 bits used for word offset
- * @mode:   ACCESS_ mode (see defines above)
- *
- * Helper to make vgic register access easier using one of the access
- * modes defined for vgic register access
- * (read,raz,write-ignored,setbit,clearbit,write)
- */
-static void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
-			    phys_addr_t offset, int mode)
-{
-	int word_offset = (offset & 3) * 8;
-	u32 mask = (1UL << (mmio->len * 8)) - 1;
-	u32 regval;
-
-	/*
-	 * Any alignment fault should have been delivered to the guest
-	 * directly (ARM ARM B3.12.7 "Prioritization of aborts").
-	 */
-
-	if (reg) {
-		regval = *reg;
-	} else {
-		BUG_ON(mode != (ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED));
-		regval = 0;
-	}
-
-	if (mmio->is_write) {
-		u32 data = mmio_data_read(mmio, mask) << word_offset;
-		switch (ACCESS_WRITE_MASK(mode)) {
-		case ACCESS_WRITE_IGNORED:
-			return;
-
-		case ACCESS_WRITE_SETBIT:
-			regval |= data;
-			break;
-
-		case ACCESS_WRITE_CLEARBIT:
-			regval &= ~data;
-			break;
-
-		case ACCESS_WRITE_VALUE:
-			regval = (regval & ~(mask << word_offset)) | data;
-			break;
-		}
-		*reg = regval;
-	} else {
-		switch (ACCESS_READ_MASK(mode)) {
-		case ACCESS_READ_RAZ:
-			regval = 0;
-			/* fall through */
-
-		case ACCESS_READ_VALUE:
-			mmio_data_write(mmio, mask, regval >> word_offset);
-		}
-	}
-}
-
-static bool handle_mmio_misc(struct kvm_vcpu *vcpu,
-			     struct kvm_exit_mmio *mmio, phys_addr_t offset)
-{
-	u32 reg;
-	u32 word_offset = offset & 3;
-
-	switch (offset & ~3) {
-	case 0:			/* CTLR */
-		reg = vcpu->kvm->arch.vgic.enabled;
-		vgic_reg_access(mmio, &reg, word_offset,
-				ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
-		if (mmio->is_write) {
-			vcpu->kvm->arch.vgic.enabled = reg & 1;
-			vgic_update_state(vcpu->kvm);
-			return true;
-		}
-		break;
-
-	case 4:			/* TYPER */
-		reg  = (atomic_read(&vcpu->kvm->online_vcpus) - 1) << 5;
-		reg |= (VGIC_NR_IRQS >> 5) - 1;
-		vgic_reg_access(mmio, &reg, word_offset,
-				ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
-		break;
-
-	case 8:			/* IIDR */
-		reg = 0x4B00043B;
-		vgic_reg_access(mmio, &reg, word_offset,
-				ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
-		break;
-	}
-
-	return false;
-}
-
-static bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu,
-			       struct kvm_exit_mmio *mmio, phys_addr_t offset)
-{
-	vgic_reg_access(mmio, NULL, offset,
-			ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
-	return false;
-}
-
-static bool handle_mmio_set_enable_reg(struct kvm_vcpu *vcpu,
-				       struct kvm_exit_mmio *mmio,
-				       phys_addr_t offset)
-{
-	u32 *reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_enabled,
-				       vcpu->vcpu_id, offset);
-	vgic_reg_access(mmio, reg, offset,
-			ACCESS_READ_VALUE | ACCESS_WRITE_SETBIT);
-	if (mmio->is_write) {
-		vgic_update_state(vcpu->kvm);
-		return true;
-	}
-
-	return false;
-}
-
-static bool handle_mmio_clear_enable_reg(struct kvm_vcpu *vcpu,
-					 struct kvm_exit_mmio *mmio,
-					 phys_addr_t offset)
-{
-	u32 *reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_enabled,
-				       vcpu->vcpu_id, offset);
-	vgic_reg_access(mmio, reg, offset,
-			ACCESS_READ_VALUE | ACCESS_WRITE_CLEARBIT);
-	if (mmio->is_write) {
-		if (offset < 4) /* Force SGI enabled */
-			*reg |= 0xffff;
-		vgic_retire_disabled_irqs(vcpu);
-		vgic_update_state(vcpu->kvm);
-		return true;
-	}
-
-	return false;
-}
-
-static bool handle_mmio_set_pending_reg(struct kvm_vcpu *vcpu,
-					struct kvm_exit_mmio *mmio,
-					phys_addr_t offset)
-{
-	u32 *reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_state,
-				       vcpu->vcpu_id, offset);
-	vgic_reg_access(mmio, reg, offset,
-			ACCESS_READ_VALUE | ACCESS_WRITE_SETBIT);
-	if (mmio->is_write) {
-		vgic_update_state(vcpu->kvm);
-		return true;
-	}
-
-	return false;
-}
-
-static bool handle_mmio_clear_pending_reg(struct kvm_vcpu *vcpu,
-					  struct kvm_exit_mmio *mmio,
-					  phys_addr_t offset)
-{
-	u32 *reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_state,
-				       vcpu->vcpu_id, offset);
-	vgic_reg_access(mmio, reg, offset,
-			ACCESS_READ_VALUE | ACCESS_WRITE_CLEARBIT);
-	if (mmio->is_write) {
-		vgic_update_state(vcpu->kvm);
-		return true;
-	}
-
-	return false;
-}
-
-static bool handle_mmio_priority_reg(struct kvm_vcpu *vcpu,
-				     struct kvm_exit_mmio *mmio,
-				     phys_addr_t offset)
-{
-	u32 *reg = vgic_bytemap_get_reg(&vcpu->kvm->arch.vgic.irq_priority,
-					vcpu->vcpu_id, offset);
-	vgic_reg_access(mmio, reg, offset,
-			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
-	return false;
-}
-
-#define GICD_ITARGETSR_SIZE	32
-#define GICD_CPUTARGETS_BITS	8
-#define GICD_IRQS_PER_ITARGETSR	(GICD_ITARGETSR_SIZE / GICD_CPUTARGETS_BITS)
-static u32 vgic_get_target_reg(struct kvm *kvm, int irq)
-{
-	struct vgic_dist *dist = &kvm->arch.vgic;
-	struct kvm_vcpu *vcpu;
-	int i, c;
-	unsigned long *bmap;
-	u32 val = 0;
-
-	irq -= VGIC_NR_PRIVATE_IRQS;
-
-	kvm_for_each_vcpu(c, vcpu, kvm) {
-		bmap = vgic_bitmap_get_shared_map(&dist->irq_spi_target[c]);
-		for (i = 0; i < GICD_IRQS_PER_ITARGETSR; i++)
-			if (test_bit(irq + i, bmap))
-				val |= 1 << (c + i * 8);
-	}
-
-	return val;
-}
-
-static void vgic_set_target_reg(struct kvm *kvm, u32 val, int irq)
-{
-	struct vgic_dist *dist = &kvm->arch.vgic;
-	struct kvm_vcpu *vcpu;
-	int i, c;
-	unsigned long *bmap;
-	u32 target;
-
-	irq -= VGIC_NR_PRIVATE_IRQS;
-
-	/*
-	 * Pick the LSB in each byte. This ensures we target exactly
-	 * one vcpu per IRQ. If the byte is null, assume we target
-	 * CPU0.
-	 */
-	for (i = 0; i < GICD_IRQS_PER_ITARGETSR; i++) {
-		int shift = i * GICD_CPUTARGETS_BITS;
-		target = ffs((val >> shift) & 0xffU);
-		target = target ? (target - 1) : 0;
-		dist->irq_spi_cpu[irq + i] = target;
-		kvm_for_each_vcpu(c, vcpu, kvm) {
-			bmap = vgic_bitmap_get_shared_map(&dist->irq_spi_target[c]);
-			if (c == target)
-				set_bit(irq + i, bmap);
-			else
-				clear_bit(irq + i, bmap);
-		}
-	}
-}
-
-static bool handle_mmio_target_reg(struct kvm_vcpu *vcpu,
-				   struct kvm_exit_mmio *mmio,
-				   phys_addr_t offset)
-{
-	u32 reg;
-
-	/* We treat the banked interrupts targets as read-only */
-	if (offset < 32) {
-		u32 roreg = 1 << vcpu->vcpu_id;
-		roreg |= roreg << 8;
-		roreg |= roreg << 16;
-
-		vgic_reg_access(mmio, &roreg, offset,
-				ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
-		return false;
-	}
-
-	reg = vgic_get_target_reg(vcpu->kvm, offset & ~3U);
-	vgic_reg_access(mmio, &reg, offset,
-			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
-	if (mmio->is_write) {
-		vgic_set_target_reg(vcpu->kvm, reg, offset & ~3U);
-		vgic_update_state(vcpu->kvm);
-		return true;
-	}
-
-	return false;
-}
-
-static u32 vgic_cfg_expand(u16 val)
-{
-	u32 res = 0;
-	int i;
-
-	/*
-	 * Turn a 16bit value like abcd...mnop into a 32bit word
-	 * a0b0c0d0...m0n0o0p0, which is what the HW cfg register is.
-	 */
-	for (i = 0; i < 16; i++)
-		res |= ((val >> i) & VGIC_CFG_EDGE) << (2 * i + 1);
-
-	return res;
-}
-
-static u16 vgic_cfg_compress(u32 val)
-{
-	u16 res = 0;
-	int i;
-
-	/*
-	 * Turn a 32bit word a0b0c0d0...m0n0o0p0 into 16bit value like
-	 * abcd...mnop which is what we really care about.
-	 */
-	for (i = 0; i < 16; i++)
-		res |= ((val >> (i * 2 + 1)) & VGIC_CFG_EDGE) << i;
-
-	return res;
-}
-
-/*
- * The distributor uses 2 bits per IRQ for the CFG register, but the
- * LSB is always 0. As such, we only keep the upper bit, and use the
- * two above functions to compress/expand the bits
- */
-static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu,
-				struct kvm_exit_mmio *mmio, phys_addr_t offset)
-{
-	u32 val;
-	u32 *reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_cfg,
-				       vcpu->vcpu_id, offset >> 1);
-	if (offset & 2)
-		val = *reg >> 16;
-	else
-		val = *reg & 0xffff;
-
-	val = vgic_cfg_expand(val);
-	vgic_reg_access(mmio, &val, offset,
-			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
-	if (mmio->is_write) {
-		if (offset < 4) {
-			*reg = ~0U; /* Force PPIs/SGIs to 1 */
-			return false;
-		}
-
-		val = vgic_cfg_compress(val);
-		if (offset & 2) {
-			*reg &= 0xffff;
-			*reg |= val << 16;
-		} else {
-			*reg &= 0xffff << 16;
-			*reg |= val;
-		}
-	}
-
-	return false;
-}
-
-static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu,
-				struct kvm_exit_mmio *mmio, phys_addr_t offset)
-{
-	u32 reg;
-	vgic_reg_access(mmio, &reg, offset,
-			ACCESS_READ_RAZ | ACCESS_WRITE_VALUE);
-	if (mmio->is_write) {
-		vgic_dispatch_sgi(vcpu, reg);
-		vgic_update_state(vcpu->kvm);
-		return true;
-	}
-
-	return false;
-}
-
-/*
- * I would have liked to use the kvm_bus_io_*() API instead, but it
- * cannot cope with banked registers (only the VM pointer is passed
- * around, and we need the vcpu). One of these days, someone please
- * fix it!
- */
-struct mmio_range {
-	phys_addr_t base;
-	unsigned long len;
-	bool (*handle_mmio)(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
-			    phys_addr_t offset);
-};
-
-static const struct mmio_range vgic_ranges[] = {
-	{
-		.base		= GIC_DIST_CTRL,
-		.len		= 12,
-		.handle_mmio	= handle_mmio_misc,
-	},
-	{
-		.base		= GIC_DIST_IGROUP,
-		.len		= VGIC_NR_IRQS / 8,
-		.handle_mmio	= handle_mmio_raz_wi,
-	},
-	{
-		.base		= GIC_DIST_ENABLE_SET,
-		.len		= VGIC_NR_IRQS / 8,
-		.handle_mmio	= handle_mmio_set_enable_reg,
-	},
-	{
-		.base		= GIC_DIST_ENABLE_CLEAR,
-		.len		= VGIC_NR_IRQS / 8,
-		.handle_mmio	= handle_mmio_clear_enable_reg,
-	},
-	{
-		.base		= GIC_DIST_PENDING_SET,
-		.len		= VGIC_NR_IRQS / 8,
-		.handle_mmio	= handle_mmio_set_pending_reg,
-	},
-	{
-		.base		= GIC_DIST_PENDING_CLEAR,
-		.len		= VGIC_NR_IRQS / 8,
-		.handle_mmio	= handle_mmio_clear_pending_reg,
-	},
-	{
-		.base		= GIC_DIST_ACTIVE_SET,
-		.len		= VGIC_NR_IRQS / 8,
-		.handle_mmio	= handle_mmio_raz_wi,
-	},
-	{
-		.base		= GIC_DIST_ACTIVE_CLEAR,
-		.len		= VGIC_NR_IRQS / 8,
-		.handle_mmio	= handle_mmio_raz_wi,
-	},
-	{
-		.base		= GIC_DIST_PRI,
-		.len		= VGIC_NR_IRQS,
-		.handle_mmio	= handle_mmio_priority_reg,
-	},
-	{
-		.base		= GIC_DIST_TARGET,
-		.len		= VGIC_NR_IRQS,
-		.handle_mmio	= handle_mmio_target_reg,
-	},
-	{
-		.base		= GIC_DIST_CONFIG,
-		.len		= VGIC_NR_IRQS / 4,
-		.handle_mmio	= handle_mmio_cfg_reg,
-	},
-	{
-		.base		= GIC_DIST_SOFTINT,
-		.len		= 4,
-		.handle_mmio	= handle_mmio_sgi_reg,
-	},
-	{}
-};
-
-static const
-struct mmio_range *find_matching_range(const struct mmio_range *ranges,
-				       struct kvm_exit_mmio *mmio,
-				       phys_addr_t base)
-{
-	const struct mmio_range *r = ranges;
-	phys_addr_t addr = mmio->phys_addr - base;
-
-	while (r->len) {
-		if (addr >= r->base &&
-		    (addr + mmio->len) <= (r->base + r->len))
-			return r;
-		r++;
-	}
-
-	return NULL;
-}
-
-/**
- * vgic_handle_mmio - handle an in-kernel MMIO access
- * @vcpu:	pointer to the vcpu performing the access
- * @run:	pointer to the kvm_run structure
- * @mmio:	pointer to the data describing the access
- *
- * returns true if the MMIO access has been performed in kernel space,
- * and false if it needs to be emulated in user space.
- */
-bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
-		      struct kvm_exit_mmio *mmio)
-{
-	const struct mmio_range *range;
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-	unsigned long base = dist->vgic_dist_base;
-	bool updated_state;
-	unsigned long offset;
-
-	if (!irqchip_in_kernel(vcpu->kvm) ||
-	    mmio->phys_addr < base ||
-	    (mmio->phys_addr + mmio->len) > (base + KVM_VGIC_V2_DIST_SIZE))
-		return false;
-
-	/* We don't support ldrd / strd or ldm / stm to the emulated vgic */
-	if (mmio->len > 4) {
-		kvm_inject_dabt(vcpu, mmio->phys_addr);
-		return true;
-	}
-
-	range = find_matching_range(vgic_ranges, mmio, base);
-	if (unlikely(!range || !range->handle_mmio)) {
-		pr_warn("Unhandled access %d %08llx %d\n",
-			mmio->is_write, mmio->phys_addr, mmio->len);
-		return false;
-	}
-
-	spin_lock(&vcpu->kvm->arch.vgic.lock);
-	offset = mmio->phys_addr - range->base - base;
-	updated_state = range->handle_mmio(vcpu, mmio, offset);
-	spin_unlock(&vcpu->kvm->arch.vgic.lock);
-	kvm_prepare_mmio(run, mmio);
-	kvm_handle_mmio_return(vcpu, run);
-
-	if (updated_state)
-		vgic_kick_vcpus(vcpu->kvm);
-
-	return true;
-}
-
-static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg)
-{
-	struct kvm *kvm = vcpu->kvm;
-	struct vgic_dist *dist = &kvm->arch.vgic;
-	int nrcpus = atomic_read(&kvm->online_vcpus);
-	u8 target_cpus;
-	int sgi, mode, c, vcpu_id;
-
-	vcpu_id = vcpu->vcpu_id;
-
-	sgi = reg & 0xf;
-	target_cpus = (reg >> 16) & 0xff;
-	mode = (reg >> 24) & 3;
-
-	switch (mode) {
-	case 0:
-		if (!target_cpus)
-			return;
-
-	case 1:
-		target_cpus = ((1 << nrcpus) - 1) & ~(1 << vcpu_id) & 0xff;
-		break;
-
-	case 2:
-		target_cpus = 1 << vcpu_id;
-		break;
-	}
-
-	kvm_for_each_vcpu(c, vcpu, kvm) {
-		if (target_cpus & 1) {
-			/* Flag the SGI as pending */
-			vgic_dist_irq_set(vcpu, sgi);
-			dist->irq_sgi_sources[c][sgi] |= 1 << vcpu_id;
-			kvm_debug("SGI%d from CPU%d to CPU%d\n", sgi, vcpu_id, c);
-		}
-
-		target_cpus >>= 1;
-	}
-}
-
-static int compute_pending_for_cpu(struct kvm_vcpu *vcpu)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-	unsigned long *pending, *enabled, *pend_percpu, *pend_shared;
-	unsigned long pending_private, pending_shared;
-	int vcpu_id;
-
-	vcpu_id = vcpu->vcpu_id;
-	pend_percpu = vcpu->arch.vgic_cpu.pending_percpu;
-	pend_shared = vcpu->arch.vgic_cpu.pending_shared;
-
-	pending = vgic_bitmap_get_cpu_map(&dist->irq_state, vcpu_id);
-	enabled = vgic_bitmap_get_cpu_map(&dist->irq_enabled, vcpu_id);
-	bitmap_and(pend_percpu, pending, enabled, VGIC_NR_PRIVATE_IRQS);
-
-	pending = vgic_bitmap_get_shared_map(&dist->irq_state);
-	enabled = vgic_bitmap_get_shared_map(&dist->irq_enabled);
-	bitmap_and(pend_shared, pending, enabled, VGIC_NR_SHARED_IRQS);
-	bitmap_and(pend_shared, pend_shared,
-		   vgic_bitmap_get_shared_map(&dist->irq_spi_target[vcpu_id]),
-		   VGIC_NR_SHARED_IRQS);
-
-	pending_private = find_first_bit(pend_percpu, VGIC_NR_PRIVATE_IRQS);
-	pending_shared = find_first_bit(pend_shared, VGIC_NR_SHARED_IRQS);
-	return (pending_private < VGIC_NR_PRIVATE_IRQS ||
-		pending_shared < VGIC_NR_SHARED_IRQS);
-}
-
-/*
- * Update the interrupt state and determine which CPUs have pending
- * interrupts. Must be called with distributor lock held.
- */
-static void vgic_update_state(struct kvm *kvm)
-{
-	struct vgic_dist *dist = &kvm->arch.vgic;
-	struct kvm_vcpu *vcpu;
-	int c;
-
-	if (!dist->enabled) {
-		set_bit(0, &dist->irq_pending_on_cpu);
-		return;
-	}
-
-	kvm_for_each_vcpu(c, vcpu, kvm) {
-		if (compute_pending_for_cpu(vcpu)) {
-			pr_debug("CPU%d has pending interrupts\n", c);
-			set_bit(c, &dist->irq_pending_on_cpu);
-		}
-	}
-}
-
-#define LR_CPUID(lr)	\
-	(((lr) & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT)
-#define MK_LR_PEND(src, irq)	\
-	(GICH_LR_PENDING_BIT | ((src) << GICH_LR_PHYSID_CPUID_SHIFT) | (irq))
-
-/*
- * An interrupt may have been disabled after being made pending on the
- * CPU interface (the classic case is a timer running while we're
- * rebooting the guest - the interrupt would kick as soon as the CPU
- * interface gets enabled, with deadly consequences).
- *
- * The solution is to examine already active LRs, and check the
- * interrupt is still enabled. If not, just retire it.
- */
-static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
-{
-	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-	int lr;
-
-	for_each_set_bit(lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
-		int irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID;
-
-		if (!vgic_irq_is_enabled(vcpu, irq)) {
-			vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
-			clear_bit(lr, vgic_cpu->lr_used);
-			vgic_cpu->vgic_lr[lr] &= ~GICH_LR_STATE;
-			if (vgic_irq_is_active(vcpu, irq))
-				vgic_irq_clear_active(vcpu, irq);
-		}
-	}
-}
-
-/*
- * Queue an interrupt to a CPU virtual interface. Return true on success,
- * or false if it wasn't possible to queue it.
- */
-static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
-{
-	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-	int lr;
-
-	/* Sanitize the input... */
-	BUG_ON(sgi_source_id & ~7);
-	BUG_ON(sgi_source_id && irq >= VGIC_NR_SGIS);
-	BUG_ON(irq >= VGIC_NR_IRQS);
-
-	kvm_debug("Queue IRQ%d\n", irq);
-
-	lr = vgic_cpu->vgic_irq_lr_map[irq];
-
-	/* Do we have an active interrupt for the same CPUID? */
-	if (lr != LR_EMPTY &&
-	    (LR_CPUID(vgic_cpu->vgic_lr[lr]) == sgi_source_id)) {
-		kvm_debug("LR%d piggyback for IRQ%d %x\n",
-			  lr, irq, vgic_cpu->vgic_lr[lr]);
-		BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
-		vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT;
-		return true;
-	}
-
-	/* Try to use another LR for this interrupt */
-	lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used,
-			       vgic_cpu->nr_lr);
-	if (lr >= vgic_cpu->nr_lr)
-		return false;
-
-	kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id);
-	vgic_cpu->vgic_lr[lr] = MK_LR_PEND(sgi_source_id, irq);
-	vgic_cpu->vgic_irq_lr_map[irq] = lr;
-	set_bit(lr, vgic_cpu->lr_used);
-
-	if (!vgic_irq_is_edge(vcpu, irq))
-		vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI;
-
-	return true;
-}
-
-static bool vgic_queue_sgi(struct kvm_vcpu *vcpu, int irq)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-	unsigned long sources;
-	int vcpu_id = vcpu->vcpu_id;
-	int c;
-
-	sources = dist->irq_sgi_sources[vcpu_id][irq];
-
-	for_each_set_bit(c, &sources, VGIC_MAX_CPUS) {
-		if (vgic_queue_irq(vcpu, c, irq))
-			clear_bit(c, &sources);
-	}
-
-	dist->irq_sgi_sources[vcpu_id][irq] = sources;
-
-	/*
-	 * If the sources bitmap has been cleared it means that we
-	 * could queue all the SGIs onto link registers (see the
-	 * clear_bit above), and therefore we are done with them in
-	 * our emulated gic and can get rid of them.
-	 */
-	if (!sources) {
-		vgic_dist_irq_clear(vcpu, irq);
-		vgic_cpu_irq_clear(vcpu, irq);
-		return true;
-	}
-
-	return false;
-}
-
-static bool vgic_queue_hwirq(struct kvm_vcpu *vcpu, int irq)
-{
-	if (vgic_irq_is_active(vcpu, irq))
-		return true; /* level interrupt, already queued */
-
-	if (vgic_queue_irq(vcpu, 0, irq)) {
-		if (vgic_irq_is_edge(vcpu, irq)) {
-			vgic_dist_irq_clear(vcpu, irq);
-			vgic_cpu_irq_clear(vcpu, irq);
-		} else {
-			vgic_irq_set_active(vcpu, irq);
-		}
-
-		return true;
-	}
-
-	return false;
-}
-
-/*
- * Fill the list registers with pending interrupts before running the
- * guest.
- */
-static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
-{
-	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-	int i, vcpu_id;
-	int overflow = 0;
-
-	vcpu_id = vcpu->vcpu_id;
-
-	/*
-	 * We may not have any pending interrupt, or the interrupts
-	 * may have been serviced from another vcpu. In all cases,
-	 * move along.
-	 */
-	if (!kvm_vgic_vcpu_pending_irq(vcpu)) {
-		pr_debug("CPU%d has no pending interrupt\n", vcpu_id);
-		goto epilog;
-	}
-
-	/* SGIs */
-	for_each_set_bit(i, vgic_cpu->pending_percpu, VGIC_NR_SGIS) {
-		if (!vgic_queue_sgi(vcpu, i))
-			overflow = 1;
-	}
-
-	/* PPIs */
-	for_each_set_bit_from(i, vgic_cpu->pending_percpu, VGIC_NR_PRIVATE_IRQS) {
-		if (!vgic_queue_hwirq(vcpu, i))
-			overflow = 1;
-	}
-
-	/* SPIs */
-	for_each_set_bit(i, vgic_cpu->pending_shared, VGIC_NR_SHARED_IRQS) {
-		if (!vgic_queue_hwirq(vcpu, i + VGIC_NR_PRIVATE_IRQS))
-			overflow = 1;
-	}
-
-epilog:
-	if (overflow) {
-		vgic_cpu->vgic_hcr |= GICH_HCR_UIE;
-	} else {
-		vgic_cpu->vgic_hcr &= ~GICH_HCR_UIE;
-		/*
-		 * We're about to run this VCPU, and we've consumed
-		 * everything the distributor had in store for
-		 * us. Claim we don't have anything pending. We'll
-		 * adjust that if needed while exiting.
-		 */
-		clear_bit(vcpu_id, &dist->irq_pending_on_cpu);
-	}
-}
-
-static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
-{
-	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-	bool level_pending = false;
-
-	kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr);
-
-	if (vgic_cpu->vgic_misr & GICH_MISR_EOI) {
-		/*
-		 * Some level interrupts have been EOIed. Clear their
-		 * active bit.
-		 */
-		int lr, irq;
-
-		for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_eisr,
-				 vgic_cpu->nr_lr) {
-			irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID;
-
-			vgic_irq_clear_active(vcpu, irq);
-			vgic_cpu->vgic_lr[lr] &= ~GICH_LR_EOI;
-
-			/* Any additional pending interrupt? */
-			if (vgic_dist_irq_is_pending(vcpu, irq)) {
-				vgic_cpu_irq_set(vcpu, irq);
-				level_pending = true;
-			} else {
-				vgic_cpu_irq_clear(vcpu, irq);
-			}
-
-			/*
-			 * Despite being EOIed, the LR may not have
-			 * been marked as empty.
-			 */
-			set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr);
-			vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT;
-		}
-	}
-
-	if (vgic_cpu->vgic_misr & GICH_MISR_U)
-		vgic_cpu->vgic_hcr &= ~GICH_HCR_UIE;
-
-	return level_pending;
-}
-
-/*
- * Sync back the VGIC state after a guest run. The distributor lock is
- * needed so we don't get preempted in the middle of the state processing.
- */
-static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
-{
-	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-	int lr, pending;
-	bool level_pending;
-
-	level_pending = vgic_process_maintenance(vcpu);
-
-	/* Clear mappings for empty LRs */
-	for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr,
-			 vgic_cpu->nr_lr) {
-		int irq;
-
-		if (!test_and_clear_bit(lr, vgic_cpu->lr_used))
-			continue;
-
-		irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID;
-
-		BUG_ON(irq >= VGIC_NR_IRQS);
-		vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
-	}
-
-	/* Check if we still have something up our sleeve... */
-	pending = find_first_zero_bit((unsigned long *)vgic_cpu->vgic_elrsr,
-				      vgic_cpu->nr_lr);
-	if (level_pending || pending < vgic_cpu->nr_lr)
-		set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu);
-}
-
-void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	if (!irqchip_in_kernel(vcpu->kvm))
-		return;
-
-	spin_lock(&dist->lock);
-	__kvm_vgic_flush_hwstate(vcpu);
-	spin_unlock(&dist->lock);
-}
-
-void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	if (!irqchip_in_kernel(vcpu->kvm))
-		return;
-
-	spin_lock(&dist->lock);
-	__kvm_vgic_sync_hwstate(vcpu);
-	spin_unlock(&dist->lock);
-}
-
-int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
-{
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-
-	if (!irqchip_in_kernel(vcpu->kvm))
-		return 0;
-
-	return test_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu);
-}
-
-static void vgic_kick_vcpus(struct kvm *kvm)
-{
-	struct kvm_vcpu *vcpu;
-	int c;
-
-	/*
-	 * We've injected an interrupt, time to find out who deserves
-	 * a good kick...
-	 */
-	kvm_for_each_vcpu(c, vcpu, kvm) {
-		if (kvm_vgic_vcpu_pending_irq(vcpu))
-			kvm_vcpu_kick(vcpu);
-	}
-}
-
-static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
-{
-	int is_edge = vgic_irq_is_edge(vcpu, irq);
-	int state = vgic_dist_irq_is_pending(vcpu, irq);
-
-	/*
-	 * Only inject an interrupt if:
-	 * - edge triggered and we have a rising edge
-	 * - level triggered and we change level
-	 */
-	if (is_edge)
-		return level > state;
-	else
-		return level != state;
-}
-
-static bool vgic_update_irq_state(struct kvm *kvm, int cpuid,
-				  unsigned int irq_num, bool level)
-{
-	struct vgic_dist *dist = &kvm->arch.vgic;
-	struct kvm_vcpu *vcpu;
-	int is_edge, is_level;
-	int enabled;
-	bool ret = true;
-
-	spin_lock(&dist->lock);
-
-	vcpu = kvm_get_vcpu(kvm, cpuid);
-	is_edge = vgic_irq_is_edge(vcpu, irq_num);
-	is_level = !is_edge;
-
-	if (!vgic_validate_injection(vcpu, irq_num, level)) {
-		ret = false;
-		goto out;
-	}
-
-	if (irq_num >= VGIC_NR_PRIVATE_IRQS) {
-		cpuid = dist->irq_spi_cpu[irq_num - VGIC_NR_PRIVATE_IRQS];
-		vcpu = kvm_get_vcpu(kvm, cpuid);
-	}
-
-	kvm_debug("Inject IRQ%d level %d CPU%d\n", irq_num, level, cpuid);
-
-	if (level)
-		vgic_dist_irq_set(vcpu, irq_num);
-	else
-		vgic_dist_irq_clear(vcpu, irq_num);
-
-	enabled = vgic_irq_is_enabled(vcpu, irq_num);
-
-	if (!enabled) {
-		ret = false;
-		goto out;
-	}
-
-	if (is_level && vgic_irq_is_active(vcpu, irq_num)) {
-		/*
-		 * Level interrupt in progress, will be picked up
-		 * when EOId.
-		 */
-		ret = false;
-		goto out;
-	}
-
-	if (level) {
-		vgic_cpu_irq_set(vcpu, irq_num);
-		set_bit(cpuid, &dist->irq_pending_on_cpu);
-	}
-
-out:
-	spin_unlock(&dist->lock);
-
-	return ret;
-}
-
-/**
- * kvm_vgic_inject_irq - Inject an IRQ from a device to the vgic
- * @kvm:     The VM structure pointer
- * @cpuid:   The CPU for PPIs
- * @irq_num: The IRQ number that is assigned to the device
- * @level:   Edge-triggered:  true:  to trigger the interrupt
- *			      false: to ignore the call
- *	     Level-sensitive  true:  activates an interrupt
- *			      false: deactivates an interrupt
- *
- * The GIC is not concerned with devices being active-LOW or active-HIGH for
- * level-sensitive interrupts.  You can think of the level parameter as 1
- * being HIGH and 0 being LOW and all devices being active-HIGH.
- */
-int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
-			bool level)
-{
-	if (vgic_update_irq_state(kvm, cpuid, irq_num, level))
-		vgic_kick_vcpus(kvm);
-
-	return 0;
-}
-
-static irqreturn_t vgic_maintenance_handler(int irq, void *data)
-{
-	/*
-	 * We cannot rely on the vgic maintenance interrupt to be
-	 * delivered synchronously. This means we can only use it to
-	 * exit the VM, and we perform the handling of EOIed
-	 * interrupts on the exit path (see vgic_process_maintenance).
-	 */
-	return IRQ_HANDLED;
-}
-
-int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
-{
-	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
-	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-	int i;
-
-	if (!irqchip_in_kernel(vcpu->kvm))
-		return 0;
-
-	if (vcpu->vcpu_id >= VGIC_MAX_CPUS)
-		return -EBUSY;
-
-	for (i = 0; i < VGIC_NR_IRQS; i++) {
-		if (i < VGIC_NR_PPIS)
-			vgic_bitmap_set_irq_val(&dist->irq_enabled,
-						vcpu->vcpu_id, i, 1);
-		if (i < VGIC_NR_PRIVATE_IRQS)
-			vgic_bitmap_set_irq_val(&dist->irq_cfg,
-						vcpu->vcpu_id, i, VGIC_CFG_EDGE);
-
-		vgic_cpu->vgic_irq_lr_map[i] = LR_EMPTY;
-	}
-
-	/*
-	 * By forcing VMCR to zero, the GIC will restore the binary
-	 * points to their reset values. Anything else resets to zero
-	 * anyway.
-	 */
-	vgic_cpu->vgic_vmcr = 0;
-
-	vgic_cpu->nr_lr = vgic_nr_lr;
-	vgic_cpu->vgic_hcr = GICH_HCR_EN; /* Get the show on the road... */
-
-	return 0;
-}
-
-static void vgic_init_maintenance_interrupt(void *info)
-{
-	enable_percpu_irq(vgic_maint_irq, 0);
-}
-
-static int vgic_cpu_notify(struct notifier_block *self,
-			   unsigned long action, void *cpu)
-{
-	switch (action) {
-	case CPU_STARTING:
-	case CPU_STARTING_FROZEN:
-		vgic_init_maintenance_interrupt(NULL);
-		break;
-	case CPU_DYING:
-	case CPU_DYING_FROZEN:
-		disable_percpu_irq(vgic_maint_irq);
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block vgic_cpu_nb = {
-	.notifier_call = vgic_cpu_notify,
-};
-
-int kvm_vgic_hyp_init(void)
-{
-	int ret;
-	struct resource vctrl_res;
-	struct resource vcpu_res;
-
-	vgic_node = of_find_compatible_node(NULL, NULL, "arm,cortex-a15-gic");
-	if (!vgic_node) {
-		kvm_err("error: no compatible vgic node in DT\n");
-		return -ENODEV;
-	}
-
-	vgic_maint_irq = irq_of_parse_and_map(vgic_node, 0);
-	if (!vgic_maint_irq) {
-		kvm_err("error getting vgic maintenance irq from DT\n");
-		ret = -ENXIO;
-		goto out;
-	}
-
-	ret = request_percpu_irq(vgic_maint_irq, vgic_maintenance_handler,
-				 "vgic", kvm_get_running_vcpus());
-	if (ret) {
-		kvm_err("Cannot register interrupt %d\n", vgic_maint_irq);
-		goto out;
-	}
-
-	ret = register_cpu_notifier(&vgic_cpu_nb);
-	if (ret) {
-		kvm_err("Cannot register vgic CPU notifier\n");
-		goto out_free_irq;
-	}
-
-	ret = of_address_to_resource(vgic_node, 2, &vctrl_res);
-	if (ret) {
-		kvm_err("Cannot obtain VCTRL resource\n");
-		goto out_free_irq;
-	}
-
-	vgic_vctrl_base = of_iomap(vgic_node, 2);
-	if (!vgic_vctrl_base) {
-		kvm_err("Cannot ioremap VCTRL\n");
-		ret = -ENOMEM;
-		goto out_free_irq;
-	}
-
-	vgic_nr_lr = readl_relaxed(vgic_vctrl_base + GICH_VTR);
-	vgic_nr_lr = (vgic_nr_lr & 0x3f) + 1;
-
-	ret = create_hyp_io_mappings(vgic_vctrl_base,
-				     vgic_vctrl_base + resource_size(&vctrl_res),
-				     vctrl_res.start);
-	if (ret) {
-		kvm_err("Cannot map VCTRL into hyp\n");
-		goto out_unmap;
-	}
-
-	kvm_info("%s@%llx IRQ%d\n", vgic_node->name,
-		 vctrl_res.start, vgic_maint_irq);
-	on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1);
-
-	if (of_address_to_resource(vgic_node, 3, &vcpu_res)) {
-		kvm_err("Cannot obtain VCPU resource\n");
-		ret = -ENXIO;
-		goto out_unmap;
-	}
-	vgic_vcpu_base = vcpu_res.start;
-
-	goto out;
-
-out_unmap:
-	iounmap(vgic_vctrl_base);
-out_free_irq:
-	free_percpu_irq(vgic_maint_irq, kvm_get_running_vcpus());
-out:
-	of_node_put(vgic_node);
-	return ret;
-}
-
-int kvm_vgic_init(struct kvm *kvm)
-{
-	int ret = 0, i;
-
-	mutex_lock(&kvm->lock);
-
-	if (vgic_initialized(kvm))
-		goto out;
-
-	if (IS_VGIC_ADDR_UNDEF(kvm->arch.vgic.vgic_dist_base) ||
-	    IS_VGIC_ADDR_UNDEF(kvm->arch.vgic.vgic_cpu_base)) {
-		kvm_err("Need to set vgic cpu and dist addresses first\n");
-		ret = -ENXIO;
-		goto out;
-	}
-
-	ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base,
-				    vgic_vcpu_base, KVM_VGIC_V2_CPU_SIZE);
-	if (ret) {
-		kvm_err("Unable to remap VGIC CPU to VCPU\n");
-		goto out;
-	}
-
-	for (i = VGIC_NR_PRIVATE_IRQS; i < VGIC_NR_IRQS; i += 4)
-		vgic_set_target_reg(kvm, 0, i);
-
-	kvm_timer_init(kvm);
-	kvm->arch.vgic.ready = true;
-out:
-	mutex_unlock(&kvm->lock);
-	return ret;
-}
-
-int kvm_vgic_create(struct kvm *kvm)
-{
-	int ret = 0;
-
-	mutex_lock(&kvm->lock);
-
-	if (atomic_read(&kvm->online_vcpus) || kvm->arch.vgic.vctrl_base) {
-		ret = -EEXIST;
-		goto out;
-	}
-
-	spin_lock_init(&kvm->arch.vgic.lock);
-	kvm->arch.vgic.vctrl_base = vgic_vctrl_base;
-	kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
-	kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
-
-out:
-	mutex_unlock(&kvm->lock);
-	return ret;
-}
-
-static bool vgic_ioaddr_overlap(struct kvm *kvm)
-{
-	phys_addr_t dist = kvm->arch.vgic.vgic_dist_base;
-	phys_addr_t cpu = kvm->arch.vgic.vgic_cpu_base;
-
-	if (IS_VGIC_ADDR_UNDEF(dist) || IS_VGIC_ADDR_UNDEF(cpu))
-		return 0;
-	if ((dist <= cpu && dist + KVM_VGIC_V2_DIST_SIZE > cpu) ||
-	    (cpu <= dist && cpu + KVM_VGIC_V2_CPU_SIZE > dist))
-		return -EBUSY;
-	return 0;
-}
-
-static int vgic_ioaddr_assign(struct kvm *kvm, phys_addr_t *ioaddr,
-			      phys_addr_t addr, phys_addr_t size)
-{
-	int ret;
-
-	if (!IS_VGIC_ADDR_UNDEF(*ioaddr))
-		return -EEXIST;
-	if (addr + size < addr)
-		return -EINVAL;
-
-	ret = vgic_ioaddr_overlap(kvm);
-	if (ret)
-		return ret;
-	*ioaddr = addr;
-	return ret;
-}
-
-int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr)
-{
-	int r = 0;
-	struct vgic_dist *vgic = &kvm->arch.vgic;
-
-	if (addr & ~KVM_PHYS_MASK)
-		return -E2BIG;
-
-	if (addr & (SZ_4K - 1))
-		return -EINVAL;
-
-	mutex_lock(&kvm->lock);
-	switch (type) {
-	case KVM_VGIC_V2_ADDR_TYPE_DIST:
-		r = vgic_ioaddr_assign(kvm, &vgic->vgic_dist_base,
-				       addr, KVM_VGIC_V2_DIST_SIZE);
-		break;
-	case KVM_VGIC_V2_ADDR_TYPE_CPU:
-		r = vgic_ioaddr_assign(kvm, &vgic->vgic_cpu_base,
-				       addr, KVM_VGIC_V2_CPU_SIZE);
-		break;
-	default:
-		r = -ENODEV;
-	}
-
-	mutex_unlock(&kvm->lock);
-	return r;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/lib/delay.c linux-libre-3.11-rc7-gnu/arch/arm/lib/delay.c
--- linux-libre-3.10-gnu/arch/arm/lib/delay.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/lib/delay.c	2013-08-25 20:43:22.000000000 -0400
@@ -86,7 +86,7 @@ void __init register_current_timer_delay
 	}
 }
 
-unsigned long __cpuinit calibrate_delay_is_known(void)
+unsigned long calibrate_delay_is_known(void)
 {
 	delay_calibrated = true;
 	return lpj_fine;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/at91rm9200.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91rm9200.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/at91rm9200.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91rm9200.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/reboot.h>
 
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
@@ -304,7 +305,7 @@ static void at91rm9200_idle(void)
 	at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
 }
 
-static void at91rm9200_restart(char mode, const char *cmd)
+static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
 {
 	/*
 	 * Perform a hardware reset with the use of the Watchdog timer.
@@ -332,10 +333,6 @@ static void __init at91rm9200_initialize
 {
 	arm_pm_idle = at91rm9200_idle;
 	arm_pm_restart = at91rm9200_restart;
-	at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1)
-			| (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3)
-			| (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5)
-			| (1 << AT91RM9200_ID_IRQ6);
 
 	/* Initialize GPIO subsystem */
 	at91_gpio_init(at91rm9200_gpio,
@@ -388,6 +385,10 @@ static unsigned int at91rm9200_default_i
 AT91_SOC_START(at91rm9200)
 	.map_io = at91rm9200_map_io,
 	.default_irq_priority = at91rm9200_default_irq_priority,
+	.extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1)
+		    | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3)
+		    | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5)
+		    | (1 << AT91RM9200_ID_IRQ6),
 	.ioremap_registers = at91rm9200_ioremap_registers,
 	.register_clocks = at91rm9200_register_clocks,
 	.init = at91rm9200_initialize,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9260.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9260.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9260.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9260.c	2013-08-25 20:43:22.000000000 -0400
@@ -348,8 +348,6 @@ static void __init at91sam9260_initializ
 {
 	arm_pm_idle = at91sam9_idle;
 	arm_pm_restart = at91sam9_alt_restart;
-	at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
-			| (1 << AT91SAM9260_ID_IRQ2);
 
 	/* Register GPIO subsystem */
 	at91_gpio_init(at91sam9260_gpio, 3);
@@ -400,6 +398,8 @@ static unsigned int at91sam9260_default_
 AT91_SOC_START(at91sam9260)
 	.map_io = at91sam9260_map_io,
 	.default_irq_priority = at91sam9260_default_irq_priority,
+	.extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
+		    | (1 << AT91SAM9260_ID_IRQ2),
 	.ioremap_registers = at91sam9260_ioremap_registers,
 	.register_clocks = at91sam9260_register_clocks,
 	.init = at91sam9260_initialize,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9261.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9261.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9261.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9261.c	2013-08-25 20:43:22.000000000 -0400
@@ -290,8 +290,6 @@ static void __init at91sam9261_initializ
 {
 	arm_pm_idle = at91sam9_idle;
 	arm_pm_restart = at91sam9_alt_restart;
-	at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
-			| (1 << AT91SAM9261_ID_IRQ2);
 
 	/* Register GPIO subsystem */
 	at91_gpio_init(at91sam9261_gpio, 3);
@@ -342,6 +340,8 @@ static unsigned int at91sam9261_default_
 AT91_SOC_START(at91sam9261)
 	.map_io = at91sam9261_map_io,
 	.default_irq_priority = at91sam9261_default_irq_priority,
+	.extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
+		    | (1 << AT91SAM9261_ID_IRQ2),
 	.ioremap_registers = at91sam9261_ioremap_registers,
 	.register_clocks = at91sam9261_register_clocks,
 	.init = at91sam9261_initialize,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9263.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9263.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9263.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9263.c	2013-08-25 20:43:22.000000000 -0400
@@ -327,7 +327,6 @@ static void __init at91sam9263_initializ
 {
 	arm_pm_idle = at91sam9_idle;
 	arm_pm_restart = at91sam9_alt_restart;
-	at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
 
 	/* Register GPIO subsystem */
 	at91_gpio_init(at91sam9263_gpio, 5);
@@ -378,6 +377,7 @@ static unsigned int at91sam9263_default_
 AT91_SOC_START(at91sam9263)
 	.map_io = at91sam9263_map_io,
 	.default_irq_priority = at91sam9263_default_irq_priority,
+	.extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1),
 	.ioremap_registers = at91sam9263_ioremap_registers,
 	.register_clocks = at91sam9263_register_clocks,
 	.init = at91sam9263_initialize,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9g45.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9g45.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9g45.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9g45.c	2013-08-25 20:43:22.000000000 -0400
@@ -266,6 +266,8 @@ static struct clk_lookup periph_clocks_l
 	CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk),
+	CLKDEV_CON_DEV_ID("hclk", "600000.gadget", &utmi_clk),
+	CLKDEV_CON_DEV_ID("pclk", "600000.gadget", &udphs_clk),
 	/* fake hclk clock */
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk),
@@ -374,7 +376,6 @@ static void __init at91sam9g45_initializ
 {
 	arm_pm_idle = at91sam9_idle;
 	arm_pm_restart = at91sam9g45_restart;
-	at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
 
 	/* Register GPIO subsystem */
 	at91_gpio_init(at91sam9g45_gpio, 5);
@@ -425,6 +426,7 @@ static unsigned int at91sam9g45_default_
 AT91_SOC_START(at91sam9g45)
 	.map_io = at91sam9g45_map_io,
 	.default_irq_priority = at91sam9g45_default_irq_priority,
+	.extern_irq = (1 << AT91SAM9G45_ID_IRQ0),
 	.ioremap_registers = at91sam9g45_ioremap_registers,
 	.register_clocks = at91sam9g45_register_clocks,
 	.init = at91sam9g45_initialize,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9rl.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9rl.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9rl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9rl.c	2013-08-25 20:43:22.000000000 -0400
@@ -293,7 +293,6 @@ static void __init at91sam9rl_initialize
 {
 	arm_pm_idle = at91sam9_idle;
 	arm_pm_restart = at91sam9_alt_restart;
-	at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);
 
 	/* Register GPIO subsystem */
 	at91_gpio_init(at91sam9rl_gpio, 4);
@@ -344,6 +343,7 @@ static unsigned int at91sam9rl_default_i
 AT91_SOC_START(at91sam9rl)
 	.map_io = at91sam9rl_map_io,
 	.default_irq_priority = at91sam9rl_default_irq_priority,
+	.extern_irq = (1 << AT91SAM9RL_ID_IRQ0),
 	.ioremap_registers = at91sam9rl_ioremap_registers,
 	.register_clocks = at91sam9rl_register_clocks,
 	.init = at91sam9rl_initialize,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9x5.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9x5.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/at91sam9x5.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91sam9x5.c	2013-08-25 20:43:22.000000000 -0400
@@ -227,6 +227,8 @@ static struct clk_lookup periph_clocks_l
 	CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk),
 	CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk),
 	CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
+	CLKDEV_CON_DEV_ID("usart", "f8040000.serial", &uart0_clk),
+	CLKDEV_CON_DEV_ID("usart", "f8044000.serial", &uart1_clk),
 	CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk),
 	CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
 	CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc0_clk),
@@ -249,6 +251,8 @@ static struct clk_lookup periph_clocks_l
 	CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk),
+	CLKDEV_CON_DEV_ID("hclk", "500000.gadget", &utmi_clk),
+	CLKDEV_CON_DEV_ID("pclk", "500000.gadget", &udphs_clk),
 };
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/at91x40.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91x40.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/at91x40.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/at91x40.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,8 +55,6 @@ static void at91x40_idle(void)
 void __init at91x40_initialize(unsigned long main_clock)
 {
 	arm_pm_idle = at91x40_idle;
-	at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1)
-			| (1 << AT91X40_ID_IRQ2);
 }
 
 /*
@@ -86,9 +84,10 @@ static unsigned int at91x40_default_irq_
 
 void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS])
 {
+	u32  extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1)
+			| (1 << AT91X40_ID_IRQ2);
 	if (!priority)
 		priority = at91x40_default_irq_priority;
 
-	at91_aic_init(priority, at91_extern_irq);
+	at91_aic_init(priority, extern_irq);
 }
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/board-dt-sama5.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/board-dt-sama5.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/board-dt-sama5.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/board-dt-sama5.c	2013-08-25 20:43:22.000000000 -0400
@@ -62,7 +62,8 @@ static int ksz9021rn_phy_fixup(struct ph
 
 static void __init sama5_dt_device_init(void)
 {
-	if (of_machine_is_compatible("atmel,sama5d3xcm"))
+	if (of_machine_is_compatible("atmel,sama5d3xcm") &&
+	    IS_ENABLED(CONFIG_PHYLIB))
 		phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
 			ksz9021rn_phy_fixup);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/board-rm9200dk.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/board-rm9200dk.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/board-rm9200dk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/board-rm9200dk.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,228 +0,0 @@
-/*
- * linux/arch/arm/mach-at91/board-rm9200dk.c
- *
- *  Copyright (C) 2005 SAN People
- *
- *  Epson S1D framebuffer glue code is:
- *     Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/at91rm9200_mc.h>
-#include <mach/at91_ramc.h>
-
-#include "at91_aic.h"
-#include "board.h"
-#include "generic.h"
-
-
-static void __init dk_init_early(void)
-{
-	/* Initialize processor: 18.432 MHz crystal */
-	at91_initialize(18432000);
-}
-
-static struct macb_platform_data __initdata dk_eth_data = {
-	.phy_irq_pin	= AT91_PIN_PC4,
-	.is_rmii	= 1,
-};
-
-static struct at91_usbh_data __initdata dk_usbh_data = {
-	.ports		= 2,
-	.vbus_pin	= {-EINVAL, -EINVAL},
-	.overcurrent_pin= {-EINVAL, -EINVAL},
-};
-
-static struct at91_udc_data __initdata dk_udc_data = {
-	.vbus_pin	= AT91_PIN_PD4,
-	.pullup_pin	= AT91_PIN_PD5,
-};
-
-static struct at91_cf_data __initdata dk_cf_data = {
-	.irq_pin	= -EINVAL,
-	.det_pin	= AT91_PIN_PB0,
-	.vcc_pin	= -EINVAL,
-	.rst_pin	= AT91_PIN_PC5,
-};
-
-#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
-static struct mci_platform_data __initdata dk_mci0_data = {
-	.slot[0] = {
-		.bus_width	= 4,
-		.detect_pin	= -EINVAL,
-		.wp_pin		= -EINVAL,
-	},
-};
-#endif
-
-static struct spi_board_info dk_spi_devices[] = {
-	{	/* DataFlash chip */
-		.modalias	= "mtd_dataflash",
-		.chip_select	= 0,
-		.max_speed_hz	= 15 * 1000 * 1000,
-	},
-	{	/* UR6HCPS2-SP40 PS2-to-SPI adapter */
-		.modalias	= "ur6hcps2",
-		.chip_select	= 1,
-		.max_speed_hz	= 250 *  1000,
-	},
-	{	/* TLV1504 ADC, 4 channels, 10 bits; one is a temp sensor */
-		.modalias	= "tlv1504",
-		.chip_select	= 2,
-		.max_speed_hz	= 20 * 1000 * 1000,
-	},
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-	{	/* DataFlash card */
-		.modalias	= "mtd_dataflash",
-		.chip_select	= 3,
-		.max_speed_hz	= 15 * 1000 * 1000,
-	}
-#endif
-};
-
-static struct i2c_board_info __initdata dk_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("ics1523", 0x26),
-	},
-	{
-		I2C_BOARD_INFO("x9429", 0x28),
-	},
-	{
-		I2C_BOARD_INFO("24c1024", 0x50),
-	}
-};
-
-static struct mtd_partition __initdata dk_nand_partition[] = {
-	{
-		.name	= "NAND Partition 1",
-		.offset	= 0,
-		.size	= MTDPART_SIZ_FULL,
-	},
-};
-
-static struct atmel_nand_data __initdata dk_nand_data = {
-	.ale		= 22,
-	.cle		= 21,
-	.det_pin	= AT91_PIN_PB1,
-	.rdy_pin	= AT91_PIN_PC2,
-	.enable_pin	= -EINVAL,
-	.ecc_mode	= NAND_ECC_SOFT,
-	.on_flash_bbt	= 1,
-	.parts		= dk_nand_partition,
-	.num_parts	= ARRAY_SIZE(dk_nand_partition),
-};
-
-#define DK_FLASH_BASE	AT91_CHIPSELECT_0
-#define DK_FLASH_SIZE	SZ_2M
-
-static struct physmap_flash_data dk_flash_data = {
-	.width		= 2,
-};
-
-static struct resource dk_flash_resource = {
-	.start		= DK_FLASH_BASE,
-	.end		= DK_FLASH_BASE + DK_FLASH_SIZE - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device dk_flash = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-				.platform_data	= &dk_flash_data,
-			},
-	.resource	= &dk_flash_resource,
-	.num_resources	= 1,
-};
-
-static struct gpio_led dk_leds[] = {
-	{
-		.name			= "led0",
-		.gpio			= AT91_PIN_PB2,
-		.active_low		= 1,
-		.default_trigger	= "heartbeat",
-	}
-};
-
-static void __init dk_board_init(void)
-{
-	/* Serial */
-	/* DBGU on ttyS0. (Rx & Tx only) */
-	at91_register_uart(0, 0, 0);
-
-	/* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
-	at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
-			   | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
-			   | ATMEL_UART_RI);
-	at91_add_device_serial();
-	/* Ethernet */
-	at91_add_device_eth(&dk_eth_data);
-	/* USB Host */
-	at91_add_device_usbh(&dk_usbh_data);
-	/* USB Device */
-	at91_add_device_udc(&dk_udc_data);
-	at91_set_multi_drive(dk_udc_data.pullup_pin, 1);	/* pullup_pin is connected to reset */
-	/* Compact Flash */
-	at91_add_device_cf(&dk_cf_data);
-	/* I2C */
-	at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));
-	/* SPI */
-	at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices));
-#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-	/* DataFlash card */
-	at91_set_gpio_output(AT91_PIN_PB7, 0);
-#else
-	/* MMC */
-	at91_set_gpio_output(AT91_PIN_PB7, 1);	/* this MMC card slot can optionally use SPI signaling (CS3). */
-	at91_add_device_mci(0, &dk_mci0_data);
-#endif
-	/* NAND */
-	at91_add_device_nand(&dk_nand_data);
-	/* NOR Flash */
-	platform_device_register(&dk_flash);
-	/* LEDs */
-	at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));
-	/* VGA */
-//	dk_add_device_video();
-}
-
-MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
-	/* Maintainer: SAN People/Atmel */
-	.init_time	= at91rm9200_timer_init,
-	.map_io		= at91_map_io,
-	.handle_irq	= at91_aic_handle_irq,
-	.init_early	= dk_init_early,
-	.init_irq	= at91_init_irq_default,
-	.init_machine	= dk_board_init,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/board-sam9261ek.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/board-sam9261ek.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/board-sam9261ek.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/board-sam9261ek.c	2013-08-25 20:43:22.000000000 -0400
@@ -264,11 +264,7 @@ static void __init ek_add_device_ts(void
  */
 static struct at73c213_board_info at73c213_data = {
 	.ssc_id		= 1,
-#if defined(CONFIG_MACH_AT91SAM9261EK)
-	.shortname	= "AT91SAM9261-EK external DAC",
-#else
-	.shortname	= "AT91SAM9G10-EK external DAC",
-#endif
+	.shortname	= "AT91SAM9261/9G10-EK external DAC",
 };
 
 #if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
@@ -412,9 +408,6 @@ static struct atmel_lcdfb_info __initdat
 	.default_monspecs		= &at91fb_default_stn_monspecs,
 	.atmel_lcdfb_power_control	= at91_lcdc_stn_power_control,
 	.guard_time			= 1,
-#if defined(CONFIG_MACH_AT91SAM9G10EK)
-	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
-#endif
 };
 
 #else
@@ -468,9 +461,6 @@ static struct atmel_lcdfb_info __initdat
 	.default_monspecs		= &at91fb_default_tft_monspecs,
 	.atmel_lcdfb_power_control	= at91_lcdc_tft_power_control,
 	.guard_time			= 1,
-#if defined(CONFIG_MACH_AT91SAM9G10EK)
-	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
-#endif
 };
 #endif
 
@@ -574,6 +564,10 @@ static void __init ek_board_init(void)
 	/* DBGU on ttyS0. (Rx & Tx only) */
 	at91_register_uart(0, 0, 0);
 	at91_add_device_serial();
+
+	if (cpu_is_at91sam9g10())
+		ek_lcdc_data.lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB;
+
 	/* USB Host */
 	at91_add_device_usbh(&ek_usbh_data);
 	/* USB Device */
@@ -606,11 +600,17 @@ static void __init ek_board_init(void)
 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
 }
 
-#if defined(CONFIG_MACH_AT91SAM9261EK)
 MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
-#else
+	/* Maintainer: Atmel */
+	.init_time	= at91sam926x_pit_init,
+	.map_io		= at91_map_io,
+	.handle_irq	= at91_aic_handle_irq,
+	.init_early	= ek_init_early,
+	.init_irq	= at91_init_irq_default,
+	.init_machine	= ek_board_init,
+MACHINE_END
+
 MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
-#endif
 	/* Maintainer: Atmel */
 	.init_time	= at91sam926x_pit_init,
 	.map_io		= at91_map_io,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/board-usb-a926x.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/board-usb-a926x.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/board-usb-a926x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/board-usb-a926x.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,384 +0,0 @@
-/*
- * linux/arch/arm/mach-at91/board-usb-a926x.c
- *
- *  Copyright (C) 2005 SAN People
- *  Copyright (C) 2007 Atmel Corporation.
- *  Copyright (C) 2007 Calao-systems
- *  Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/gpio_keys.h>
-#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/spi/mmc_spi.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/at91sam9_smc.h>
-
-#include "at91_aic.h"
-#include "at91_shdwc.h"
-#include "board.h"
-#include "sam9_smc.h"
-#include "generic.h"
-
-
-static void __init ek_init_early(void)
-{
-	/* Initialize processor: 12.00 MHz crystal */
-	at91_initialize(12000000);
-}
-
-/*
- * USB Host port
- */
-static struct at91_usbh_data __initdata ek_usbh_data = {
-	.ports		= 2,
-	.vbus_pin	= {-EINVAL, -EINVAL},
-	.overcurrent_pin= {-EINVAL, -EINVAL},
-};
-
-/*
- * USB Device port
- */
-static struct at91_udc_data __initdata ek_udc_data = {
-	.vbus_pin	= AT91_PIN_PB11,
-	.pullup_pin	= -EINVAL,		/* pull-up driven by UDC */
-};
-
-static void __init ek_add_device_udc(void)
-{
-	if (machine_is_usb_a9260() || machine_is_usb_a9g20())
-		ek_udc_data.vbus_pin = AT91_PIN_PC5;
-
-	at91_add_device_udc(&ek_udc_data);
-}
-
-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
-#define MMC_SPI_CARD_DETECT_INT AT91_PIN_PC4
-static int at91_mmc_spi_init(struct device *dev,
-	irqreturn_t (*detect_int)(int, void *), void *data)
-{
-	/* Configure Interrupt pin as input, no pull-up */
-	at91_set_gpio_input(MMC_SPI_CARD_DETECT_INT, 0);
-	return request_irq(gpio_to_irq(MMC_SPI_CARD_DETECT_INT), detect_int,
-		IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-		"mmc-spi-detect", data);
-}
-
-static void at91_mmc_spi_exit(struct device *dev, void *data)
-{
-	free_irq(gpio_to_irq(MMC_SPI_CARD_DETECT_INT), data);
-}
-
-static struct mmc_spi_platform_data at91_mmc_spi_pdata = {
-	.init = at91_mmc_spi_init,
-	.exit = at91_mmc_spi_exit,
-	.detect_delay = 100, /* msecs */
-};
-#endif
-
-/*
- * SPI devices.
- */
-static struct spi_board_info usb_a9263_spi_devices[] = {
-	{	/* DataFlash chip */
-		.modalias	= "mtd_dataflash",
-		.chip_select	= 0,
-		.max_speed_hz	= 15 * 1000 * 1000,
-		.bus_num	= 0,
-	}
-};
-
-static struct spi_board_info usb_a9g20_spi_devices[] = {
-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
-	{
-		.modalias = "mmc_spi",
-		.max_speed_hz = 20000000,	/* max spi clock (SCK) speed in HZ */
-		.bus_num = 1,
-		.chip_select = 0,
-		.platform_data = &at91_mmc_spi_pdata,
-		.mode = SPI_MODE_3,
-	},
-#endif
-};
-
-static void __init ek_add_device_spi(void)
-{
-	if (machine_is_usb_a9263())
-		at91_add_device_spi(usb_a9263_spi_devices, ARRAY_SIZE(usb_a9263_spi_devices));
-	else if (machine_is_usb_a9g20())
-		at91_add_device_spi(usb_a9g20_spi_devices, ARRAY_SIZE(usb_a9g20_spi_devices));
-}
-
-/*
- * MACB Ethernet device
- */
-static struct macb_platform_data __initdata ek_macb_data = {
-	.phy_irq_pin	= AT91_PIN_PE31,
-	.is_rmii	= 1,
-};
-
-static void __init ek_add_device_eth(void)
-{
-	if (machine_is_usb_a9260() || machine_is_usb_a9g20())
-		ek_macb_data.phy_irq_pin = AT91_PIN_PA31;
-
-	at91_add_device_eth(&ek_macb_data);
-}
-
-/*
- * NAND flash
- */
-static struct mtd_partition __initdata ek_nand_partition[] = {
-	{
-		.name	= "barebox",
-		.offset	= 0,
-		.size	= 3 * SZ_128K,
-	}, {
-		.name	= "bareboxenv",
-		.offset	= MTDPART_OFS_NXTBLK,
-		.size	= SZ_128K,
-	}, {
-		.name	= "bareboxenv2",
-		.offset	= MTDPART_OFS_NXTBLK,
-		.size	= SZ_128K,
-	}, {
-		.name	= "oftree",
-		.offset	= MTDPART_OFS_NXTBLK,
-		.size	= SZ_128K,
-	}, {
-		.name	= "kernel",
-		.offset	= MTDPART_OFS_NXTBLK,
-		.size	= 4 * SZ_1M,
-	}, {
-		.name	= "rootfs",
-		.offset	= MTDPART_OFS_NXTBLK,
-		.size	= 120 * SZ_1M,
-	}, {
-		.name	= "data",
-		.offset	= MTDPART_OFS_NXTBLK,
-		.size	= MTDPART_SIZ_FULL,
-	}
-};
-
-static struct atmel_nand_data __initdata ek_nand_data = {
-	.ale		= 21,
-	.cle		= 22,
-	.det_pin	= -EINVAL,
-	.rdy_pin	= AT91_PIN_PA22,
-	.enable_pin	= AT91_PIN_PD15,
-	.ecc_mode	= NAND_ECC_SOFT,
-	.on_flash_bbt	= 1,
-	.parts		= ek_nand_partition,
-	.num_parts	= ARRAY_SIZE(ek_nand_partition),
-};
-
-static struct sam9_smc_config __initdata usb_a9260_nand_smc_config = {
-	.ncs_read_setup		= 0,
-	.nrd_setup		= 1,
-	.ncs_write_setup	= 0,
-	.nwe_setup		= 1,
-
-	.ncs_read_pulse		= 3,
-	.nrd_pulse		= 3,
-	.ncs_write_pulse	= 3,
-	.nwe_pulse		= 3,
-
-	.read_cycle		= 5,
-	.write_cycle		= 5,
-
-	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
-	.tdf_cycles		= 2,
-};
-
-static struct sam9_smc_config __initdata usb_a9g20_nand_smc_config = {
-	.ncs_read_setup		= 0,
-	.nrd_setup		= 2,
-	.ncs_write_setup	= 0,
-	.nwe_setup		= 2,
-
-	.ncs_read_pulse		= 4,
-	.nrd_pulse		= 4,
-	.ncs_write_pulse	= 4,
-	.nwe_pulse		= 4,
-
-	.read_cycle		= 7,
-	.write_cycle		= 7,
-
-	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
-	.tdf_cycles		= 3,
-};
-
-static void __init ek_add_device_nand(void)
-{
-	if (machine_is_usb_a9260() || machine_is_usb_a9g20()) {
-		ek_nand_data.rdy_pin	= AT91_PIN_PC13;
-		ek_nand_data.enable_pin	= AT91_PIN_PC14;
-	}
-
-	/* configure chip-select 3 (NAND) */
-	if (machine_is_usb_a9g20())
-		sam9_smc_configure(0, 3, &usb_a9g20_nand_smc_config);
-	else
-		sam9_smc_configure(0, 3, &usb_a9260_nand_smc_config);
-
-	at91_add_device_nand(&ek_nand_data);
-}
-
-
-/*
- * GPIO Buttons
- */
-#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
-static struct gpio_keys_button ek_buttons[] = {
-	{	/* USER PUSH BUTTON */
-		.code		= KEY_ENTER,
-		.gpio		= AT91_PIN_PB10,
-		.active_low	= 1,
-		.desc		= "user_pb",
-		.wakeup		= 1,
-	}
-};
-
-static struct gpio_keys_platform_data ek_button_data = {
-	.buttons	= ek_buttons,
-	.nbuttons	= ARRAY_SIZE(ek_buttons),
-};
-
-static struct platform_device ek_button_device = {
-	.name		= "gpio-keys",
-	.id		= -1,
-	.num_resources	= 0,
-	.dev		= {
-		.platform_data	= &ek_button_data,
-	}
-};
-
-static void __init ek_add_device_buttons(void)
-{
-	at91_set_GPIO_periph(AT91_PIN_PB10, 1);	/* user push button, pull up enabled */
-	at91_set_deglitch(AT91_PIN_PB10, 1);
-
-	platform_device_register(&ek_button_device);
-}
-#else
-static void __init ek_add_device_buttons(void) {}
-#endif
-
-/*
- * LEDs
- */
-static struct gpio_led ek_leds[] = {
-	{	/* user_led (green) */
-		.name			= "user_led",
-		.gpio			= AT91_PIN_PB21,
-		.active_low		= 1,
-		.default_trigger	= "heartbeat",
-	}
-};
-
-static struct i2c_board_info __initdata ek_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("rv3029c2", 0x56),
-	},
-};
-
-static void __init ek_add_device_leds(void)
-{
-	if (machine_is_usb_a9260() || machine_is_usb_a9g20())
-		ek_leds[0].active_low = 0;
-
-	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
-}
-
-static void __init ek_board_init(void)
-{
-	/* Serial */
-	/* DBGU on ttyS0. (Rx & Tx only) */
-	at91_register_uart(0, 0, 0);
-	at91_add_device_serial();
-	/* USB Host */
-	at91_add_device_usbh(&ek_usbh_data);
-	/* USB Device */
-	ek_add_device_udc();
-	/* SPI */
-	ek_add_device_spi();
-	/* Ethernet */
-	ek_add_device_eth();
-	/* NAND */
-	ek_add_device_nand();
-	/* Push Buttons */
-	ek_add_device_buttons();
-	/* LEDs */
-	ek_add_device_leds();
-
-	if (machine_is_usb_a9g20()) {
-		/* I2C */
-		at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
-	} else {
-		/* I2C */
-		at91_add_device_i2c(NULL, 0);
-		/* shutdown controller, wakeup button (5 msec low) */
-		at91_shdwc_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10)
-				| AT91_SHDW_WKMODE0_LOW
-				| AT91_SHDW_RTTWKEN);
-	}
-}
-
-MACHINE_START(USB_A9263, "CALAO USB_A9263")
-	/* Maintainer: calao-systems */
-	.init_time	= at91sam926x_pit_init,
-	.map_io		= at91_map_io,
-	.handle_irq	= at91_aic_handle_irq,
-	.init_early	= ek_init_early,
-	.init_irq	= at91_init_irq_default,
-	.init_machine	= ek_board_init,
-MACHINE_END
-
-MACHINE_START(USB_A9260, "CALAO USB_A9260")
-	/* Maintainer: calao-systems */
-	.init_time	= at91sam926x_pit_init,
-	.map_io		= at91_map_io,
-	.handle_irq	= at91_aic_handle_irq,
-	.init_early	= ek_init_early,
-	.init_irq	= at91_init_irq_default,
-	.init_machine	= ek_board_init,
-MACHINE_END
-
-MACHINE_START(USB_A9G20, "CALAO USB_A92G0")
-	/* Maintainer: Jean-Christophe PLAGNIOL-VILLARD */
-	.init_time	= at91sam926x_pit_init,
-	.map_io		= at91_map_io,
-	.handle_irq	= at91_aic_handle_irq,
-	.init_early	= ek_init_early,
-	.init_irq	= at91_init_irq_default,
-	.init_machine	= ek_board_init,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/clock.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/clock.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/clock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/clock.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,7 +75,7 @@ EXPORT_SYMBOL_GPL(at91_pmc_base);
 #define cpu_has_pllb()		(!(cpu_is_at91sam9rl() \
 				|| cpu_is_at91sam9g45() \
 				|| cpu_is_at91sam9x5() \
-				|| cpu_is_at91sam9n12()))
+				|| cpu_is_sama5d3()))
 
 #define cpu_has_upll()		(cpu_is_at91sam9g45() \
 				|| cpu_is_at91sam9x5() \
@@ -489,7 +489,7 @@ static int at91_clk_show(struct seq_file
 		seq_printf(s, "UCKR = %8x\n", uckr);
 	}
 	seq_printf(s, "MCKR = %8x\n", at91_pmc_read(AT91_PMC_MCKR));
-	if (cpu_has_upll())
+	if (cpu_has_upll() || cpu_is_at91sam9n12())
 		seq_printf(s, "USB  = %8x\n", at91_pmc_read(AT91_PMC_USB));
 	seq_printf(s, "SR   = %8x\n", sr);
 
@@ -614,6 +614,8 @@ static u32 __init at91_usb_rate(struct c
 {
 	if (pll == &pllb && (reg & AT91_PMC_USB96M))
 		return freq / 2;
+	else if (pll == &utmi_clk || cpu_is_at91sam9n12())
+		return freq / (1 + ((reg & AT91_PMC_OHCIUSBDIV) >> 8));
 	else
 		return freq;
 }
@@ -683,6 +685,8 @@ static struct clk *const standard_pmc_cl
 /* PLLB generated USB full speed clock init */
 static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
 {
+	unsigned int reg;
+
 	/*
 	 * USB clock init:  choose 48 MHz PLLB value,
 	 * disable 48MHz clock during usb peripheral suspend.
@@ -691,22 +695,35 @@ static void __init at91_pllb_usbfs_clock
 	 */
 	uhpck.parent = &pllb;
 
-	at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
+	reg = at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2);
 	pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
 	if (cpu_is_at91rm9200()) {
+		reg = at91_pllb_usb_init |= AT91_PMC_USB96M;
 		uhpck.pmc_mask = AT91RM9200_PMC_UHP;
 		udpck.pmc_mask = AT91RM9200_PMC_UDP;
 		at91_pmc_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
 	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
 		   cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
 		   cpu_is_at91sam9g10()) {
+		reg = at91_pllb_usb_init |= AT91_PMC_USB96M;
+		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
+		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
+	} else if (cpu_is_at91sam9n12()) {
+		/* Divider for USB clock is in USB clock register for 9n12 */
+		reg = AT91_PMC_USBS_PLLB;
+
+		/* For PLLB output 96M, set usb divider 2 (USBDIV + 1) */
+		reg |= AT91_PMC_OHCIUSBDIV_2;
+		at91_pmc_write(AT91_PMC_USB, reg);
+
+		/* Still setup masks */
 		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
 		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
 	}
 	at91_pmc_write(AT91_CKGR_PLLBR, 0);
 
-	udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
-	uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+	udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, reg);
+	uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, reg);
 }
 
 /* UPLL generated USB full speed clock init */
@@ -725,8 +742,7 @@ static void __init at91_upll_usbfs_clock
 	/* Now set uhpck values */
 	uhpck.parent = &utmi_clk;
 	uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
-	uhpck.rate_hz = utmi_clk.rate_hz;
-	uhpck.rate_hz /= 1 + ((at91_pmc_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
+	uhpck.rate_hz = at91_usb_rate(&utmi_clk, utmi_clk.rate_hz, usbr);
 }
 
 static int __init at91_pmc_init(unsigned long main_clock)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/cpuidle.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/cpuidle.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/cpuidle.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/cpuidle.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,7 +51,7 @@ static struct cpuidle_driver at91_idle_d
 	.states[1]		= {
 		.enter			= at91_enter_idle,
 		.exit_latency		= 10,
-		.target_residency	= 100000,
+		.target_residency	= 10000,
 		.flags			= CPUIDLE_FLAG_TIME_VALID,
 		.name			= "RAM_SR",
 		.desc			= "WFI and DDR Self Refresh",
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/generic.h linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/generic.h
--- linux-libre-3.10-gnu/arch/arm/mach-at91/generic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/generic.h	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,7 @@
 
 #include <linux/clkdev.h>
 #include <linux/of.h>
+#include <linux/reboot.h>
 
  /* Map io */
 extern void __init at91_map_io(void);
@@ -60,8 +61,8 @@ extern void at91sam9_idle(void);
 
 /* reset */
 extern void at91_ioremap_rstc(u32 base_addr);
-extern void at91sam9_alt_restart(char, const char *);
-extern void at91sam9g45_restart(char, const char *);
+extern void at91sam9_alt_restart(enum reboot_mode, const char *);
+extern void at91sam9g45_restart(enum reboot_mode, const char *);
 
 /* shutdown */
 extern void at91_ioremap_shdwc(u32 base_addr);
@@ -85,4 +86,4 @@ extern void __init at91_gpio_irq_setup(v
 extern int  __init at91_gpio_of_irq_setup(struct device_node *node,
 					  struct device_node *parent);
 
-extern int at91_extern_irq;
+extern u32 at91_get_extern_irq(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/include/mach/at91_pmc.h linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/include/mach/at91_pmc.h
--- linux-libre-3.10-gnu/arch/arm/mach-at91/include/mach/at91_pmc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/include/mach/at91_pmc.h	2013-08-25 20:43:22.000000000 -0400
@@ -130,7 +130,10 @@ extern void __iomem *at91_pmc_base;
 #define		AT91_PMC_USBS		(0x1 <<  0)		/* USB OHCI Input clock selection */
 #define			AT91_PMC_USBS_PLLA		(0 << 0)
 #define			AT91_PMC_USBS_UPLL		(1 << 0)
+#define			AT91_PMC_USBS_PLLB		(1 << 0)	/* [AT91SAMN12 only] */
 #define		AT91_PMC_OHCIUSBDIV	(0xF <<  8)		/* Divider for USB OHCI Clock */
+#define			AT91_PMC_OHCIUSBDIV_1	(0x0 <<  8)
+#define			AT91_PMC_OHCIUSBDIV_2	(0x1 <<  8)
 
 #define	AT91_PMC_SMD		0x3c			/* Soft Modem Clock Register [some SAM9 only] */
 #define		AT91_PMC_SMDS		(0x1  <<  0)		/* SMD input clock selection */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/irq.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/irq.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -232,7 +232,14 @@ static void __maybe_unused at91_aic5_eoi
 	at91_aic_write(AT91_AIC5_EOICR, 0);
 }
 
-unsigned long *at91_extern_irq;
+static unsigned long *at91_extern_irq;
+
+u32 at91_get_extern_irq(void)
+{
+	if (!at91_extern_irq)
+		return 0;
+	return *at91_extern_irq;
+}
 
 #define is_extern_irq(hwirq) test_bit(hwirq, at91_extern_irq)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-at91/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -163,6 +163,7 @@ config MACH_SAMA5_DT
 	bool "Atmel SAMA5 Evaluation Kits with device-tree support"
 	depends on SOC_SAMA5
 	select USE_OF
+	select PHYLIB if NETDEVICES
 	help
 	  Select this if you want to experiment device-tree with
 	  an Atmel Evaluation Kit.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/Kconfig.non_dt linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/Kconfig.non_dt
--- linux-libre-3.10-gnu/arch/arm/mach-at91/Kconfig.non_dt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/Kconfig.non_dt	2013-08-25 20:43:22.000000000 -0400
@@ -14,15 +14,11 @@ config ARCH_AT91RM9200
 	select SOC_AT91RM9200
 
 config ARCH_AT91SAM9260
-	bool "AT91SAM9260 or AT91SAM9XE"
+	bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20"
 	select SOC_AT91SAM9260
 
 config ARCH_AT91SAM9261
-	bool "AT91SAM9261"
-	select SOC_AT91SAM9261
-
-config ARCH_AT91SAM9G10
-	bool "AT91SAM9G10"
+	bool "AT91SAM9261 or AT91SAM9G10"
 	select SOC_AT91SAM9261
 
 config ARCH_AT91SAM9263
@@ -33,10 +29,6 @@ config ARCH_AT91SAM9RL
 	bool "AT91SAM9RL"
 	select SOC_AT91SAM9RL
 
-config ARCH_AT91SAM9G20
-	bool "AT91SAM9G20"
-	select SOC_AT91SAM9260
-
 config ARCH_AT91SAM9G45
 	bool "AT91SAM9G45"
 	select SOC_AT91SAM9G45
@@ -50,6 +42,14 @@ config ARCH_AT91X40
 
 endchoice
 
+config ARCH_AT91SAM9G20
+	bool
+	select ARCH_AT91SAM9260
+
+config ARCH_AT91SAM9G10
+	bool
+	select ARCH_AT91SAM9261
+
 # ----------------------------------------------------------
 
 if ARCH_AT91RM9200
@@ -62,13 +62,6 @@ config MACH_ONEARM
 	  Select this if you are using Ajeco's 1ARM Single Board Computer.
 	  <http://www.ajeco.fi/>
 
-config ARCH_AT91RM9200DK
-	bool "Atmel AT91RM9200-DK Development board"
-	select HAVE_AT91_DATAFLASH_CARD
-	help
-	  Select this if you are using Atmel's AT91RM9200-DK Development board.
-	  (Discontinued)
-
 config MACH_AT91RM9200EK
 	bool "Atmel AT91RM9200-EK Evaluation Kit"
 	select HAVE_AT91_DATAFLASH_CARD
@@ -183,12 +176,6 @@ config MACH_AFEB9260
 	  <svn://194.85.238.22/home/users/george/svn/arm9eb>
 	  <http://groups.google.com/group/arm9fpga-evolution-board>
 
-config MACH_USB_A9260
-	bool "CALAO USB-A9260"
-	help
-	  Select this if you are using a Calao Systems USB-A9260.
-	  <http://www.calao-systems.com>
-
 config MACH_QIL_A9260
 	bool "CALAO QIL-A9260 board"
 	help
@@ -207,76 +194,6 @@ config MACH_FLEXIBITY
 	  Select this if you are using Flexibity Connect board
 	  <http://www.flexibity.com>
 
-endif
-
-# ----------------------------------------------------------
-
-if ARCH_AT91SAM9261
-
-comment "AT91SAM9261 Board Type"
-
-config MACH_AT91SAM9261EK
-	bool "Atmel AT91SAM9261-EK Evaluation Kit"
-	select HAVE_AT91_DATAFLASH_CARD
-	help
-	  Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit.
-	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820>
-
-endif
-
-# ----------------------------------------------------------
-
-if ARCH_AT91SAM9G10
-
-comment "AT91SAM9G10 Board Type"
-
-config MACH_AT91SAM9G10EK
-	bool "Atmel AT91SAM9G10-EK Evaluation Kit"
-	select HAVE_AT91_DATAFLASH_CARD
-	help
-	  Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit.
-	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588>
-
-endif
-
-# ----------------------------------------------------------
-
-if ARCH_AT91SAM9263
-
-comment "AT91SAM9263 Board Type"
-
-config MACH_AT91SAM9263EK
-	bool "Atmel AT91SAM9263-EK Evaluation Kit"
-	select HAVE_AT91_DATAFLASH_CARD
-	help
-	  Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit.
-	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057>
-
-config MACH_USB_A9263
-	bool "CALAO USB-A9263"
-	help
-	  Select this if you are using a Calao Systems USB-A9263.
-	  <http://www.calao-systems.com>
-
-endif
-
-# ----------------------------------------------------------
-
-if ARCH_AT91SAM9RL
-
-comment "AT91SAM9RL Board Type"
-
-config MACH_AT91SAM9RLEK
-	bool "Atmel AT91SAM9RL-EK Evaluation Kit"
-	help
-	  Select this if you are using Atmel's AT91SAM9RL-EK Evaluation Kit.
-
-endif
-
-# ----------------------------------------------------------
-
-if ARCH_AT91SAM9G20
-
 comment "AT91SAM9G20 Board Type"
 
 config MACH_AT91SAM9G20EK
@@ -334,24 +251,64 @@ config MACH_GSIA18S
 	  produced by GeoSIG Ltd company. This is an internet accelerograph.
 	  <http://www.geosig.com>
 
-config MACH_USB_A9G20
-	bool "CALAO USB-A9G20"
-	depends on ARCH_AT91SAM9G20
+config MACH_SNAPPER_9260
+	bool "Bluewater Systems Snapper 9260/9G20 module"
 	help
-	  Select this if you are using a Calao Systems USB-A9G20.
-	  <http://www.calao-systems.com>
+	  Select this if you are using the Bluewater Systems Snapper 9260 or
+	  Snapper 9G20 modules.
+	  <http://www.bluewatersys.com/>
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9261
+
+comment "AT91SAM9261 Board Type"
+
+config MACH_AT91SAM9261EK
+	bool "Atmel AT91SAM9261-EK Evaluation Kit"
+	select HAVE_AT91_DATAFLASH_CARD
+	help
+	  Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit.
+	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820>
+
+comment "AT91SAM9G10 Board Type"
+
+config MACH_AT91SAM9G10EK
+	bool "Atmel AT91SAM9G10-EK Evaluation Kit"
+	select HAVE_AT91_DATAFLASH_CARD
+	help
+	  Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit.
+	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588>
 
 endif
 
-if (ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
-comment "AT91SAM9260/AT91SAM9G20 boards"
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9263
+
+comment "AT91SAM9263 Board Type"
+
+config MACH_AT91SAM9263EK
+	bool "Atmel AT91SAM9263-EK Evaluation Kit"
+	select HAVE_AT91_DATAFLASH_CARD
+	help
+	  Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit.
+	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057>
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9RL
+
+comment "AT91SAM9RL Board Type"
+
+config MACH_AT91SAM9RLEK
+	bool "Atmel AT91SAM9RL-EK Evaluation Kit"
+	help
+	  Select this if you are using Atmel's AT91SAM9RL-EK Evaluation Kit.
 
-config MACH_SNAPPER_9260
-        bool "Bluewater Systems Snapper 9260/9G20 module"
-        help
-          Select this if you are using the Bluewater Systems Snapper 9260 or
-          Snapper 9G20 modules.
-          <http://www.bluewatersys.com/>
 endif
 
 # ----------------------------------------------------------
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-at91/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -27,16 +27,13 @@ obj-$(CONFIG_SOC_SAMA5D3)	+= sama5d3.o
 obj-$(CONFIG_ARCH_AT91RM9200)	+= at91rm9200_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9260)	+= at91sam9260_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9261)	+= at91sam9261_devices.o
-obj-$(CONFIG_ARCH_AT91SAM9G10)	+= at91sam9261_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9RL)	+= at91sam9rl_devices.o
-obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9G45)	+= at91sam9g45_devices.o
 obj-$(CONFIG_ARCH_AT91X40)	+= at91x40.o at91x40_time.o
 
 # AT91RM9200 board-specific support
 obj-$(CONFIG_MACH_ONEARM)	+= board-1arm.o
-obj-$(CONFIG_ARCH_AT91RM9200DK)	+= board-rm9200dk.o
 obj-$(CONFIG_MACH_AT91RM9200EK)	+= board-rm9200ek.o
 obj-$(CONFIG_MACH_CSB337)	+= board-csb337.o
 obj-$(CONFIG_MACH_CSB637)	+= board-csb637.o
@@ -55,7 +52,6 @@ obj-$(CONFIG_MACH_RSI_EWS)	+= board-rsi-
 obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
 obj-$(CONFIG_MACH_CAM60)	+= board-cam60.o
 obj-$(CONFIG_MACH_SAM9_L9260)	+= board-sam9-l9260.o
-obj-$(CONFIG_MACH_USB_A9260)	+= board-usb-a926x.o
 obj-$(CONFIG_MACH_QIL_A9260)	+= board-qil-a9260.o
 obj-$(CONFIG_MACH_AFEB9260)	+= board-afeb-9260v1.o
 obj-$(CONFIG_MACH_CPU9260)	+= board-cpu9krea.o
@@ -67,7 +63,6 @@ obj-$(CONFIG_MACH_AT91SAM9G10EK) += boar
 
 # AT91SAM9263 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
-obj-$(CONFIG_MACH_USB_A9263)	+= board-usb-a926x.o
 
 # AT91SAM9RL board-specific support
 obj-$(CONFIG_MACH_AT91SAM9RLEK)	+= board-sam9rlek.o
@@ -80,7 +75,6 @@ obj-$(CONFIG_MACH_STAMP9G20)	+= board-st
 obj-$(CONFIG_MACH_PORTUXG20)	+= board-stamp9g20.o
 obj-$(CONFIG_MACH_PCONTROL_G20)	+= board-pcontrol-g20.o board-stamp9g20.o
 obj-$(CONFIG_MACH_GSIA18S)	+= board-gsia18s.o board-stamp9g20.o
-obj-$(CONFIG_MACH_USB_A9G20)	+= board-usb-a926x.o
 
 # AT91SAM9260/AT91SAM9G20 board-specific support
 obj-$(CONFIG_MACH_SNAPPER_9260)	+= board-snapper9260.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/pm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/pm.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -212,7 +212,7 @@ static int at91_pm_enter(suspend_state_t
 			(at91_pmc_read(AT91_PMC_PCSR)
 					| (1 << AT91_ID_FIQ)
 					| (1 << AT91_ID_SYS)
-					| (at91_extern_irq))
+					| (at91_get_extern_irq()))
 				& at91_aic_read(AT91_AIC_IMR),
 			state);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/setup.c linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/setup.c
--- linux-libre-3.10-gnu/arch/arm/mach-at91/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,7 +48,7 @@ void __init at91_init_irq_default(void)
 void __init at91_init_interrupts(unsigned int *priority)
 {
 	/* Initialize the AIC interrupt controller */
-	at91_aic_init(priority, at91_extern_irq);
+	at91_aic_init(priority, at91_boot_soc.extern_irq);
 
 	/* Enable GPIO interrupts */
 	at91_gpio_irq_setup();
@@ -80,7 +80,7 @@ void __init at91_init_sram(int bank, uns
 
 	desc->pfn = __phys_to_pfn(base);
 	desc->length = length;
-	desc->type = MT_DEVICE;
+	desc->type = MT_MEMORY_NONCACHED;
 
 	pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n",
 		base, length, desc->virtual);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-at91/soc.h linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/soc.h
--- linux-libre-3.10-gnu/arch/arm/mach-at91/soc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-at91/soc.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,6 +6,7 @@
 
 struct at91_init_soc {
 	int builtin;
+	u32 extern_irq;
 	unsigned int *default_irq_priority;
 	void (*map_io)(void);
 	void (*ioremap_registers)(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-bcm/board_bcm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-bcm/board_bcm.c
--- linux-libre-3.10-gnu/arch/arm/mach-bcm/board_bcm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-bcm/board_bcm.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <linux/irqchip.h>
 #include <linux/clocksource.h>
 
 #include <asm/mach/arch.h>
@@ -54,7 +53,6 @@ static void __init board_init(void)
 static const char * const bcm11351_dt_compat[] = { "bcm,bcm11351", NULL, };
 
 DT_MACHINE_START(BCM11351_DT, "Broadcom Application Processor")
-	.init_irq = irqchip_init,
 	.init_time = clocksource_of_init,
 	.init_machine = board_init,
 	.dt_compat = bcm11351_dt_compat,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-bcm2835/bcm2835.c linux-libre-3.11-rc7-gnu/arch/arm/mach-bcm2835/bcm2835.c
--- linux-libre-3.10-gnu/arch/arm/mach-bcm2835/bcm2835.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-bcm2835/bcm2835.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,7 +53,7 @@ static void bcm2835_setup_restart(void)
 	WARN(!wdt_regs, "failed to remap watchdog regs");
 }
 
-static void bcm2835_restart(char mode, const char *cmd)
+static void bcm2835_restart(enum reboot_mode mode, const char *cmd)
 {
 	u32 val;
 
@@ -91,7 +91,7 @@ static void bcm2835_power_off(void)
 	writel_relaxed(val, wdt_regs + PM_RSTS);
 
 	/* Continue with normal reset mechanism */
-	bcm2835_restart(0, "");
+	bcm2835_restart(REBOOT_HARD, "");
 }
 
 static struct map_desc io_map __initdata = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-autcpu12.c linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-autcpu12.c
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-autcpu12.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-autcpu12.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,8 @@
 #include <linux/gpio.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand-gpio.h>
 #include <linux/platform_device.h>
@@ -40,38 +42,49 @@
 #include <asm/page.h>
 
 #include <asm/mach/map.h>
-#include <mach/autcpu12.h>
 
 #include "common.h"
+#include "devices.h"
 
-#define AUTCPU12_CS8900_BASE	(CS2_PHYS_BASE + 0x300)
-#define AUTCPU12_CS8900_IRQ	(IRQ_EINT3)
+/* NOR flash */
+#define AUTCPU12_FLASH_BASE	(CS0_PHYS_BASE)
+
+/* Board specific hardware definitions */
+#define AUTCPU12_CHAR_LCD_BASE	(CS1_PHYS_BASE + 0x00000000)
+#define AUTCPU12_CSAUX1_BASE	(CS1_PHYS_BASE + 0x04000000)
+#define AUTCPU12_CAN_BASE	(CS1_PHYS_BASE + 0x08000000)
+#define AUTCPU12_TOUCH_BASE	(CS1_PHYS_BASE + 0x0a000000)
+#define AUTCPU12_IO_BASE	(CS1_PHYS_BASE + 0x0c000000)
+#define AUTCPU12_LPT_BASE	(CS1_PHYS_BASE + 0x0e000000)
+
+/* NVRAM */
+#define AUTCPU12_NVRAM_BASE	(CS1_PHYS_BASE + 0x02000000)
 
+/* SmartMedia flash */
 #define AUTCPU12_SMC_BASE	(CS1_PHYS_BASE + 0x06000000)
 #define AUTCPU12_SMC_SEL_BASE	(AUTCPU12_SMC_BASE + 0x10)
 
+/* Ethernet */
+#define AUTCPU12_CS8900_BASE	(CS2_PHYS_BASE + 0x300)
+#define AUTCPU12_CS8900_IRQ	(IRQ_EINT3)
+
+/* NAND flash */
 #define AUTCPU12_MMGPIO_BASE	(CLPS711X_NR_GPIO)
 #define AUTCPU12_SMC_NCE	(AUTCPU12_MMGPIO_BASE + 0) /* Bit 0 */
 #define AUTCPU12_SMC_RDY	CLPS711X_GPIO(1, 2)
 #define AUTCPU12_SMC_ALE	CLPS711X_GPIO(1, 3)
 #define AUTCPU12_SMC_CLE	CLPS711X_GPIO(1, 3)
 
+/* LCD contrast digital potentiometer */
+#define AUTCPU12_DPOT_CS	CLPS711X_GPIO(4, 0)
+#define AUTCPU12_DPOT_CLK	CLPS711X_GPIO(4, 1)
+#define AUTCPU12_DPOT_UD	CLPS711X_GPIO(4, 2)
+
 static struct resource autcpu12_cs8900_resource[] __initdata = {
 	DEFINE_RES_MEM(AUTCPU12_CS8900_BASE, SZ_1K),
 	DEFINE_RES_IRQ(AUTCPU12_CS8900_IRQ),
 };
 
-static struct resource autcpu12_nvram_resource[] __initdata = {
-	DEFINE_RES_MEM_NAMED(AUTCPU12_PHYS_NVRAM, SZ_128K, "SRAM"),
-};
-
-static struct platform_device autcpu12_nvram_pdev __initdata = {
-	.name		= "autcpu12_nvram",
-	.id		= -1,
-	.resource	= autcpu12_nvram_resource,
-	.num_resources	= ARRAY_SIZE(autcpu12_nvram_resource),
-};
-
 static struct resource autcpu12_nand_resource[] __initdata = {
 	DEFINE_RES_MEM(AUTCPU12_SMC_BASE, SZ_16),
 };
@@ -147,17 +160,106 @@ static struct platform_device autcpu12_m
 	},
 };
 
+static const struct gpio autcpu12_gpios[] __initconst = {
+	{ AUTCPU12_DPOT_CS,	GPIOF_OUT_INIT_HIGH,	"DPOT CS" },
+	{ AUTCPU12_DPOT_CLK,	GPIOF_OUT_INIT_LOW,	"DPOT CLK" },
+	{ AUTCPU12_DPOT_UD,	GPIOF_OUT_INIT_LOW,	"DPOT UD" },
+};
+
+static struct mtd_partition autcpu12_flash_partitions[] = {
+	{
+		.name	= "NOR.0",
+		.offset	= 0,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data autcpu12_flash_pdata = {
+	.width		= 4,
+	.parts		= autcpu12_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(autcpu12_flash_partitions),
+};
+
+static struct resource autcpu12_flash_resources[] __initdata = {
+	DEFINE_RES_MEM(AUTCPU12_FLASH_BASE, SZ_8M),
+};
+
+static struct platform_device autcpu12_flash_pdev __initdata = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.resource	= autcpu12_flash_resources,
+	.num_resources	= ARRAY_SIZE(autcpu12_flash_resources),
+	.dev		= {
+		.platform_data	= &autcpu12_flash_pdata,
+	},
+};
+
+static struct resource autcpu12_nvram_resource[] __initdata = {
+	DEFINE_RES_MEM(AUTCPU12_NVRAM_BASE, 0),
+};
+
+static struct platdata_mtd_ram autcpu12_nvram_pdata = {
+	.bankwidth	= 4,
+};
+
+static struct platform_device autcpu12_nvram_pdev __initdata = {
+	.name		= "mtd-ram",
+	.id		= 0,
+	.resource	= autcpu12_nvram_resource,
+	.num_resources	= ARRAY_SIZE(autcpu12_nvram_resource),
+	.dev		= {
+		.platform_data	= &autcpu12_nvram_pdata,
+	},
+};
+
+static void __init autcpu12_nvram_init(void)
+{
+	void __iomem *nvram;
+	unsigned int save[2];
+	resource_size_t nvram_size = SZ_128K;
+
+	/*
+	 * Check for 32K/128K
+	 * Read ofs 0K
+	 * Read ofs 64K
+	 * Write complement to ofs 64K
+	 * Read and check result on ofs 0K
+	 * Restore contents
+	 */
+	nvram = ioremap(autcpu12_nvram_resource[0].start, SZ_128K);
+	if (nvram) {
+		save[0] = readl(nvram + 0);
+		save[1] = readl(nvram + SZ_64K);
+		writel(~save[0], nvram + SZ_64K);
+		if (readl(nvram + 0) != save[0]) {
+			writel(save[0], nvram + 0);
+			nvram_size = SZ_32K;
+		} else
+			writel(save[1], nvram + SZ_64K);
+		iounmap(nvram);
+
+		autcpu12_nvram_resource[0].end =
+			autcpu12_nvram_resource[0].start + nvram_size - 1;
+		platform_device_register(&autcpu12_nvram_pdev);
+	} else
+		pr_err("Failed to remap NVRAM resource\n");
+}
+
 static void __init autcpu12_init(void)
 {
+	clps711x_devices_init();
+	platform_device_register(&autcpu12_flash_pdev);
 	platform_device_register_simple("video-clps711x", 0, NULL, 0);
 	platform_device_register_simple("cs89x0", 0, autcpu12_cs8900_resource,
 					ARRAY_SIZE(autcpu12_cs8900_resource));
 	platform_device_register(&autcpu12_mmgpio_pdev);
-	platform_device_register(&autcpu12_nvram_pdev);
+	autcpu12_nvram_init();
 }
 
 static void __init autcpu12_init_late(void)
 {
+	gpio_request_array(autcpu12_gpios, ARRAY_SIZE(autcpu12_gpios));
+
 	if (IS_ENABLED(MTD_NAND_GPIO) && IS_ENABLED(GPIO_GENERIC_PLATFORM)) {
 		/* We are need both drivers to handle NAND */
 		platform_device_register(&autcpu12_nand_pdev);
@@ -169,6 +271,7 @@ MACHINE_START(AUTCPU12, "autronix autcpu
 	.atag_offset	= 0x20000,
 	.nr_irqs	= CLPS711X_NR_IRQS,
 	.map_io		= clps711x_map_io,
+	.init_early	= clps711x_init_early,
 	.init_irq	= clps711x_init_irq,
 	.init_time	= clps711x_timer_init,
 	.init_machine	= autcpu12_init,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-cdb89712.c linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-cdb89712.c
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-cdb89712.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-cdb89712.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
+#include "devices.h"
 
 #define CDB89712_CS8900_BASE	(CS2_PHYS_BASE + 0x300)
 #define CDB89712_CS8900_IRQ	(IRQ_EINT3)
@@ -127,6 +128,7 @@ static struct platform_device cdb89712_s
 
 static void __init cdb89712_init(void)
 {
+	clps711x_devices_init();
 	platform_device_register(&cdb89712_flash_pdev);
 	platform_device_register(&cdb89712_bootrom_pdev);
 	platform_device_register(&cdb89712_sram_pdev);
@@ -139,6 +141,7 @@ MACHINE_START(CDB89712, "Cirrus-CDB89712
 	.atag_offset	= 0x100,
 	.nr_irqs	= CLPS711X_NR_IRQS,
 	.map_io		= clps711x_map_io,
+	.init_early	= clps711x_init_early,
 	.init_irq	= clps711x_init_irq,
 	.init_time	= clps711x_timer_init,
 	.init_machine	= cdb89712_init,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-clep7312.c linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-clep7312.c
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-clep7312.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-clep7312.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,7 @@ MACHINE_START(CLEP7212, "Cirrus Logic 72
 	.nr_irqs	= CLPS711X_NR_IRQS,
 	.fixup		= fixup_clep7312,
 	.map_io		= clps711x_map_io,
+	.init_early	= clps711x_init_early,
 	.init_irq	= clps711x_init_irq,
 	.init_time	= clps711x_timer_init,
 	.handle_irq	= clps711x_handle_irq,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-edb7211.c linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-edb7211.c
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-edb7211.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-edb7211.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/memblock.h>
 #include <linux/types.h>
+#include <linux/i2c-gpio.h>
 #include <linux/interrupt.h>
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
@@ -29,6 +30,7 @@
 #include <mach/hardware.h>
 
 #include "common.h"
+#include "devices.h"
 
 #define VIDEORAM_SIZE		SZ_128K
 
@@ -36,11 +38,24 @@
 #define EDB7211_LCDEN		CLPS711X_GPIO(3, 2)
 #define EDB7211_LCDBL		CLPS711X_GPIO(3, 3)
 
+#define EDB7211_I2C_SDA		CLPS711X_GPIO(3, 4)
+#define EDB7211_I2C_SCL		CLPS711X_GPIO(3, 5)
+
 #define EDB7211_FLASH0_BASE	(CS0_PHYS_BASE)
 #define EDB7211_FLASH1_BASE	(CS1_PHYS_BASE)
+
 #define EDB7211_CS8900_BASE	(CS2_PHYS_BASE + 0x300)
 #define EDB7211_CS8900_IRQ	(IRQ_EINT3)
 
+/* The extra 8 lines of the keyboard matrix */
+#define EDB7211_EXTKBD_BASE	(CS3_PHYS_BASE)
+
+static struct i2c_gpio_platform_data edb7211_i2c_pdata __initdata = {
+	.sda_pin	= EDB7211_I2C_SDA,
+	.scl_pin	= EDB7211_I2C_SCL,
+	.scl_is_output_only = 1,
+};
+
 static struct resource edb7211_cs8900_resource[] __initdata = {
 	DEFINE_RES_MEM(EDB7211_CS8900_BASE, SZ_1K),
 	DEFINE_RES_IRQ(EDB7211_CS8900_IRQ),
@@ -94,13 +109,14 @@ static struct plat_lcd_data edb7211_lcd_
 
 static void edb7211_lcd_backlight_set_intensity(int intensity)
 {
-	gpio_set_value(EDB7211_LCDBL, intensity);
+	gpio_set_value(EDB7211_LCDBL, !!intensity);
+	clps_writel((clps_readl(PMPCON) & 0xf0ff) | (intensity << 8), PMPCON);
 }
 
 static struct generic_bl_info edb7211_lcd_backlight_pdata = {
 	.name			= "lcd-backlight.0",
 	.default_intensity	= 0x01,
-	.max_intensity		= 0x01,
+	.max_intensity		= 0x0f,
 	.set_bl_intensity	= edb7211_lcd_backlight_set_intensity,
 };
 
@@ -112,8 +128,8 @@ static struct gpio edb7211_gpios[] __ini
 
 static struct map_desc edb7211_io_desc[] __initdata = {
 	{	/* Memory-mapped extra keyboard row */
-		.virtual	= IO_ADDRESS(EP7211_PHYS_EXTKBD),
-		.pfn		= __phys_to_pfn(EP7211_PHYS_EXTKBD),
+		.virtual	= IO_ADDRESS(EDB7211_EXTKBD_BASE),
+		.pfn		= __phys_to_pfn(EDB7211_EXTKBD_BASE),
 		.length		= SZ_1M,
 		.type		= MT_DEVICE,
 	},
@@ -151,6 +167,11 @@ fixup_edb7211(struct tag *tags, char **c
 
 static void __init edb7211_init(void)
 {
+	clps711x_devices_init();
+}
+
+static void __init edb7211_init_late(void)
+{
 	gpio_request_array(edb7211_gpios, ARRAY_SIZE(edb7211_gpios));
 
 	platform_device_register(&edb7211_flash_pdev);
@@ -163,6 +184,9 @@ static void __init edb7211_init(void)
 	platform_device_register_simple("video-clps711x", 0, NULL, 0);
 	platform_device_register_simple("cs89x0", 0, edb7211_cs8900_resource,
 					ARRAY_SIZE(edb7211_cs8900_resource));
+	platform_device_register_data(&platform_bus, "i2c-gpio", 0,
+				      &edb7211_i2c_pdata,
+				      sizeof(edb7211_i2c_pdata));
 }
 
 MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
@@ -172,9 +196,11 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP72
 	.fixup		= fixup_edb7211,
 	.reserve	= edb7211_reserve,
 	.map_io		= edb7211_map_io,
+	.init_early	= clps711x_init_early,
 	.init_irq	= clps711x_init_irq,
 	.init_time	= clps711x_timer_init,
 	.init_machine	= edb7211_init,
+	.init_late	= edb7211_init_late,
 	.handle_irq	= clps711x_handle_irq,
 	.restart	= clps711x_restart,
 MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-fortunet.c linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-fortunet.c
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-fortunet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-fortunet.c	2013-08-25 20:43:22.000000000 -0400
@@ -77,6 +77,7 @@ MACHINE_START(FORTUNET, "ARM-FortuNet")
 	.nr_irqs	= CLPS711X_NR_IRQS,
 	.fixup		= fortunet_fixup,
 	.map_io		= clps711x_map_io,
+	.init_early	= clps711x_init_early,
 	.init_irq	= clps711x_init_irq,
 	.init_time	= clps711x_timer_init,
 	.handle_irq	= clps711x_handle_irq,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-p720t.c linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-p720t.c
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/board-p720t.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/board-p720t.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,10 +23,12 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 #include <linux/slab.h>
 #include <linux/leds.h>
 #include <linux/sizes.h>
 #include <linux/backlight.h>
+#include <linux/basic_mmio_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand-gpio.h>
@@ -38,11 +40,11 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <mach/syspld.h>
 
 #include <video/platform_lcd.h>
 
 #include "common.h"
+#include "devices.h"
 
 #define P720T_USERLED		CLPS711X_GPIO(3, 0)
 #define P720T_NAND_CLE		CLPS711X_GPIO(4, 0)
@@ -51,6 +53,178 @@
 
 #define P720T_NAND_BASE		(CLPS711X_SDRAM1_BASE)
 
+#define P720T_MMGPIO_BASE	(CLPS711X_NR_GPIO)
+
+#define SYSPLD_PHYS_BASE	IOMEM(CS1_PHYS_BASE)
+
+#define PLD_INT			(SYSPLD_PHYS_BASE + 0x000000)
+#define PLD_INT_MMGPIO_BASE	(P720T_MMGPIO_BASE + 0)
+#define PLD_INT_PENIRQ		(PLD_INT_MMGPIO_BASE + 5)
+#define PLD_INT_UCB_IRQ		(PLD_INT_MMGPIO_BASE + 1)
+#define PLD_INT_KBD_ATN		(PLD_INT_MMGPIO_BASE + 0) /* EINT1 */
+
+#define PLD_PWR			(SYSPLD_PHYS_BASE + 0x000004)
+#define PLD_PWR_MMGPIO_BASE	(P720T_MMGPIO_BASE + 8)
+#define PLD_PWR_EXT		(PLD_PWR_MMGPIO_BASE + 5)
+#define PLD_PWR_MODE		(PLD_PWR_MMGPIO_BASE + 4) /* 1 = PWM, 0 = PFM */
+#define PLD_S4_ON		(PLD_PWR_MMGPIO_BASE + 3) /* LCD bias voltage enable */
+#define PLD_S3_ON		(PLD_PWR_MMGPIO_BASE + 2) /* LCD backlight enable */
+#define PLD_S2_ON		(PLD_PWR_MMGPIO_BASE + 1) /* LCD 3V3 supply enable */
+#define PLD_S1_ON		(PLD_PWR_MMGPIO_BASE + 0) /* LCD 3V supply enable */
+
+#define PLD_KBD			(SYSPLD_PHYS_BASE + 0x000008)
+#define PLD_KBD_MMGPIO_BASE	(P720T_MMGPIO_BASE + 16)
+#define PLD_KBD_WAKE		(PLD_KBD_MMGPIO_BASE + 1)
+#define PLD_KBD_EN		(PLD_KBD_MMGPIO_BASE + 0)
+
+#define PLD_SPI			(SYSPLD_PHYS_BASE + 0x00000c)
+#define PLD_SPI_MMGPIO_BASE	(P720T_MMGPIO_BASE + 24)
+#define PLD_SPI_EN		(PLD_SPI_MMGPIO_BASE + 0)
+
+#define PLD_IO			(SYSPLD_PHYS_BASE + 0x000010)
+#define PLD_IO_MMGPIO_BASE	(P720T_MMGPIO_BASE + 32)
+#define PLD_IO_BOOTSEL		(PLD_IO_MMGPIO_BASE + 6) /* Boot sel switch */
+#define PLD_IO_USER		(PLD_IO_MMGPIO_BASE + 5) /* User defined switch */
+#define PLD_IO_LED3		(PLD_IO_MMGPIO_BASE + 4)
+#define PLD_IO_LED2		(PLD_IO_MMGPIO_BASE + 3)
+#define PLD_IO_LED1		(PLD_IO_MMGPIO_BASE + 2)
+#define PLD_IO_LED0		(PLD_IO_MMGPIO_BASE + 1)
+#define PLD_IO_LEDEN		(PLD_IO_MMGPIO_BASE + 0)
+
+#define PLD_IRDA		(SYSPLD_PHYS_BASE + 0x000014)
+#define PLD_IRDA_MMGPIO_BASE	(P720T_MMGPIO_BASE + 40)
+#define PLD_IRDA_EN		(PLD_IRDA_MMGPIO_BASE + 0)
+
+#define PLD_COM2		(SYSPLD_PHYS_BASE + 0x000018)
+#define PLD_COM2_MMGPIO_BASE	(P720T_MMGPIO_BASE + 48)
+#define PLD_COM2_EN		(PLD_COM2_MMGPIO_BASE + 0)
+
+#define PLD_COM1		(SYSPLD_PHYS_BASE + 0x00001c)
+#define PLD_COM1_MMGPIO_BASE	(P720T_MMGPIO_BASE + 56)
+#define PLD_COM1_EN		(PLD_COM1_MMGPIO_BASE + 0)
+
+#define PLD_AUD			(SYSPLD_PHYS_BASE + 0x000020)
+#define PLD_AUD_MMGPIO_BASE	(P720T_MMGPIO_BASE + 64)
+#define PLD_AUD_DIV1		(PLD_AUD_MMGPIO_BASE + 6)
+#define PLD_AUD_DIV0		(PLD_AUD_MMGPIO_BASE + 5)
+#define PLD_AUD_CLK_SEL1	(PLD_AUD_MMGPIO_BASE + 4)
+#define PLD_AUD_CLK_SEL0	(PLD_AUD_MMGPIO_BASE + 3)
+#define PLD_AUD_MIC_PWR		(PLD_AUD_MMGPIO_BASE + 2)
+#define PLD_AUD_MIC_GAIN	(PLD_AUD_MMGPIO_BASE + 1)
+#define PLD_AUD_CODEC_EN	(PLD_AUD_MMGPIO_BASE + 0)
+
+#define PLD_CF			(SYSPLD_PHYS_BASE + 0x000024)
+#define PLD_CF_MMGPIO_BASE	(P720T_MMGPIO_BASE + 72)
+#define PLD_CF2_SLEEP		(PLD_CF_MMGPIO_BASE + 5)
+#define PLD_CF1_SLEEP		(PLD_CF_MMGPIO_BASE + 4)
+#define PLD_CF2_nPDREQ		(PLD_CF_MMGPIO_BASE + 3)
+#define PLD_CF1_nPDREQ		(PLD_CF_MMGPIO_BASE + 2)
+#define PLD_CF2_nIRQ		(PLD_CF_MMGPIO_BASE + 1)
+#define PLD_CF1_nIRQ		(PLD_CF_MMGPIO_BASE + 0)
+
+#define PLD_SDC			(SYSPLD_PHYS_BASE + 0x000028)
+#define PLD_SDC_MMGPIO_BASE	(P720T_MMGPIO_BASE + 80)
+#define PLD_SDC_INT_EN		(PLD_SDC_MMGPIO_BASE + 2)
+#define PLD_SDC_WP		(PLD_SDC_MMGPIO_BASE + 1)
+#define PLD_SDC_CD		(PLD_SDC_MMGPIO_BASE + 0)
+
+#define PLD_CODEC		(SYSPLD_PHYS_BASE + 0x400000)
+#define PLD_CODEC_MMGPIO_BASE	(P720T_MMGPIO_BASE + 88)
+#define PLD_CODEC_IRQ3		(PLD_CODEC_MMGPIO_BASE + 4)
+#define PLD_CODEC_IRQ2		(PLD_CODEC_MMGPIO_BASE + 3)
+#define PLD_CODEC_IRQ1		(PLD_CODEC_MMGPIO_BASE + 2)
+#define PLD_CODEC_EN		(PLD_CODEC_MMGPIO_BASE + 0)
+
+#define PLD_BRITE		(SYSPLD_PHYS_BASE + 0x400004)
+#define PLD_BRITE_MMGPIO_BASE	(P720T_MMGPIO_BASE + 96)
+#define PLD_BRITE_UP		(PLD_BRITE_MMGPIO_BASE + 1)
+#define PLD_BRITE_DN		(PLD_BRITE_MMGPIO_BASE + 0)
+
+#define PLD_LCDEN		(SYSPLD_PHYS_BASE + 0x400008)
+#define PLD_LCDEN_MMGPIO_BASE	(P720T_MMGPIO_BASE + 104)
+#define PLD_LCDEN_EN		(PLD_LCDEN_MMGPIO_BASE + 0)
+
+#define PLD_TCH			(SYSPLD_PHYS_BASE + 0x400010)
+#define PLD_TCH_MMGPIO_BASE	(P720T_MMGPIO_BASE + 112)
+#define PLD_TCH_PENIRQ		(PLD_TCH_MMGPIO_BASE + 1)
+#define PLD_TCH_EN		(PLD_TCH_MMGPIO_BASE + 0)
+
+#define PLD_GPIO		(SYSPLD_PHYS_BASE + 0x400014)
+#define PLD_GPIO_MMGPIO_BASE	(P720T_MMGPIO_BASE + 120)
+#define PLD_GPIO2		(PLD_GPIO_MMGPIO_BASE + 2)
+#define PLD_GPIO1		(PLD_GPIO_MMGPIO_BASE + 1)
+#define PLD_GPIO0		(PLD_GPIO_MMGPIO_BASE + 0)
+
+static struct gpio p720t_gpios[] __initconst = {
+	{ PLD_S1_ON,	GPIOF_OUT_INIT_LOW,	"PLD_S1_ON" },
+	{ PLD_S2_ON,	GPIOF_OUT_INIT_LOW,	"PLD_S2_ON" },
+	{ PLD_S3_ON,	GPIOF_OUT_INIT_LOW,	"PLD_S3_ON" },
+	{ PLD_S4_ON,	GPIOF_OUT_INIT_LOW,	"PLD_S4_ON" },
+	{ PLD_KBD_EN,	GPIOF_OUT_INIT_LOW,	"PLD_KBD_EN" },
+	{ PLD_SPI_EN,	GPIOF_OUT_INIT_LOW,	"PLD_SPI_EN" },
+	{ PLD_IO_USER,	GPIOF_OUT_INIT_LOW,	"PLD_IO_USER" },
+	{ PLD_IO_LED0,	GPIOF_OUT_INIT_LOW,	"PLD_IO_LED0" },
+	{ PLD_IO_LED1,	GPIOF_OUT_INIT_LOW,	"PLD_IO_LED1" },
+	{ PLD_IO_LED2,	GPIOF_OUT_INIT_LOW,	"PLD_IO_LED2" },
+	{ PLD_IO_LED3,	GPIOF_OUT_INIT_LOW,	"PLD_IO_LED3" },
+	{ PLD_IO_LEDEN,	GPIOF_OUT_INIT_LOW,	"PLD_IO_LEDEN" },
+	{ PLD_IRDA_EN,	GPIOF_OUT_INIT_LOW,	"PLD_IRDA_EN" },
+	{ PLD_COM1_EN,	GPIOF_OUT_INIT_HIGH,	"PLD_COM1_EN" },
+	{ PLD_COM2_EN,	GPIOF_OUT_INIT_HIGH,	"PLD_COM2_EN" },
+	{ PLD_CODEC_EN,	GPIOF_OUT_INIT_LOW,	"PLD_CODEC_EN" },
+	{ PLD_LCDEN_EN,	GPIOF_OUT_INIT_LOW,	"PLD_LCDEN_EN" },
+	{ PLD_TCH_EN,	GPIOF_OUT_INIT_LOW,	"PLD_TCH_EN" },
+	{ P720T_USERLED,GPIOF_OUT_INIT_LOW,	"USER_LED" },
+};
+
+static struct resource p720t_mmgpio_resource[] __initdata = {
+	DEFINE_RES_MEM_NAMED(0, 4, "dat"),
+};
+
+static struct bgpio_pdata p720t_mmgpio_pdata = {
+	.ngpio	= 8,
+};
+
+static struct platform_device p720t_mmgpio __initdata = {
+	.name		= "basic-mmio-gpio",
+	.id		= -1,
+	.resource	= p720t_mmgpio_resource,
+	.num_resources	= ARRAY_SIZE(p720t_mmgpio_resource),
+	.dev		= {
+		.platform_data	= &p720t_mmgpio_pdata,
+	},
+};
+
+static void __init p720t_mmgpio_init(void __iomem *addrbase, int gpiobase)
+{
+	p720t_mmgpio_resource[0].start = (unsigned long)addrbase;
+	p720t_mmgpio_pdata.base = gpiobase;
+
+	platform_device_register(&p720t_mmgpio);
+}
+
+static struct {
+	void __iomem	*addrbase;
+	int		gpiobase;
+} mmgpios[] __initconst = {
+	{ PLD_INT,	PLD_INT_MMGPIO_BASE },
+	{ PLD_PWR,	PLD_PWR_MMGPIO_BASE },
+	{ PLD_KBD,	PLD_KBD_MMGPIO_BASE },
+	{ PLD_SPI,	PLD_SPI_MMGPIO_BASE },
+	{ PLD_IO,	PLD_IO_MMGPIO_BASE },
+	{ PLD_IRDA,	PLD_IRDA_MMGPIO_BASE },
+	{ PLD_COM2,	PLD_COM2_MMGPIO_BASE },
+	{ PLD_COM1,	PLD_COM1_MMGPIO_BASE },
+	{ PLD_AUD,	PLD_AUD_MMGPIO_BASE },
+	{ PLD_CF,	PLD_CF_MMGPIO_BASE },
+	{ PLD_SDC,	PLD_SDC_MMGPIO_BASE },
+	{ PLD_CODEC,	PLD_CODEC_MMGPIO_BASE },
+	{ PLD_BRITE,	PLD_BRITE_MMGPIO_BASE },
+	{ PLD_LCDEN,	PLD_LCDEN_MMGPIO_BASE },
+	{ PLD_TCH,	PLD_TCH_MMGPIO_BASE },
+	{ PLD_GPIO,	PLD_GPIO_MMGPIO_BASE },
+};
+
 static struct resource p720t_nand_resource[] __initdata = {
 	DEFINE_RES_MEM(P720T_NAND_BASE, SZ_4),
 };
@@ -92,11 +266,15 @@ static struct platform_device p720t_nand
 static void p720t_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
 {
 	if (power) {
-		PLD_LCDEN = PLD_LCDEN_EN;
-		PLD_PWR |= PLD_S4_ON | PLD_S2_ON | PLD_S1_ON;
+		gpio_set_value(PLD_LCDEN_EN, 1);
+		gpio_set_value(PLD_S1_ON, 1);
+		gpio_set_value(PLD_S2_ON, 1);
+		gpio_set_value(PLD_S4_ON, 1);
 	} else {
-		PLD_PWR &= ~(PLD_S4_ON | PLD_S2_ON | PLD_S1_ON);
-		PLD_LCDEN = 0;
+		gpio_set_value(PLD_S1_ON, 0);
+		gpio_set_value(PLD_S2_ON, 0);
+		gpio_set_value(PLD_S4_ON, 0);
+		gpio_set_value(PLD_LCDEN_EN, 0);
 	}
 }
 
@@ -106,10 +284,7 @@ static struct plat_lcd_data p720t_lcd_po
 
 static void p720t_lcd_backlight_set_intensity(int intensity)
 {
-	if (intensity)
-		PLD_PWR |= PLD_S3_ON;
-	else
-		PLD_PWR = 0;
+	gpio_set_value(PLD_S3_ON, intensity);
 }
 
 static struct generic_bl_info p720t_lcd_backlight_pdata = {
@@ -119,19 +294,6 @@ static struct generic_bl_info p720t_lcd_
 	.set_bl_intensity	= p720t_lcd_backlight_set_intensity,
 };
 
-/*
- * Map the P720T system PLD. It occupies two address spaces:
- * 0x10000000 and 0x10400000. We map both regions as one.
- */
-static struct map_desc p720t_io_desc[] __initdata = {
-	{
-		.virtual	= SYSPLD_VIRT_BASE,
-		.pfn		= __phys_to_pfn(SYSPLD_PHYS_BASE),
-		.length		= SZ_8M,
-		.type		= MT_DEVICE,
-	},
-};
-
 static void __init
 fixup_p720t(struct tag *tag, char **cmdline, struct meminfo *mi)
 {
@@ -157,33 +319,6 @@ fixup_p720t(struct tag *tag, char **cmdl
 	}
 }
 
-static void __init p720t_map_io(void)
-{
-	clps711x_map_io();
-	iotable_init(p720t_io_desc, ARRAY_SIZE(p720t_io_desc));
-}
-
-static void __init p720t_init_early(void)
-{
-	/*
-	 * Power down as much as possible in case we don't
-	 * have the drivers loaded.
-	 */
-	PLD_LCDEN = 0;
-	PLD_PWR  &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
-
-	PLD_KBD   = 0;
-	PLD_IO    = 0;
-	PLD_IRDA  = 0;
-	PLD_CODEC = 0;
-	PLD_TCH   = 0;
-	PLD_SPI   = 0;
-	if (!IS_ENABLED(CONFIG_DEBUG_LL)) {
-		PLD_COM2 = 0;
-		PLD_COM1 = 0;
-	}
-}
-
 static struct gpio_led p720t_gpio_leds[] = {
 	{
 		.name			= "User LED",
@@ -199,7 +334,20 @@ static struct gpio_led_platform_data p72
 
 static void __init p720t_init(void)
 {
+	int i;
+
+	clps711x_devices_init();
+
+	for (i = 0; i < ARRAY_SIZE(mmgpios); i++)
+		p720t_mmgpio_init(mmgpios[i].addrbase, mmgpios[i].gpiobase);
+
 	platform_device_register(&p720t_nand_pdev);
+}
+
+static void __init p720t_init_late(void)
+{
+	WARN_ON(gpio_request_array(p720t_gpios, ARRAY_SIZE(p720t_gpios)));
+
 	platform_device_register_data(&platform_bus, "platform-lcd", 0,
 				      &p720t_lcd_power_pdata,
 				      sizeof(p720t_lcd_power_pdata));
@@ -207,10 +355,6 @@ static void __init p720t_init(void)
 				      &p720t_lcd_backlight_pdata,
 				      sizeof(p720t_lcd_backlight_pdata));
 	platform_device_register_simple("video-clps711x", 0, NULL, 0);
-}
-
-static void __init p720t_init_late(void)
-{
 	platform_device_register_data(&platform_bus, "leds-gpio", 0,
 				      &p720t_gpio_led_pdata,
 				      sizeof(p720t_gpio_led_pdata));
@@ -221,8 +365,8 @@ MACHINE_START(P720T, "ARM-Prospector720T
 	.atag_offset	= 0x100,
 	.nr_irqs	= CLPS711X_NR_IRQS,
 	.fixup		= fixup_p720t,
-	.map_io		= p720t_map_io,
-	.init_early	= p720t_init_early,
+	.map_io		= clps711x_map_io,
+	.init_early	= clps711x_init_early,
 	.init_irq	= clps711x_init_irq,
 	.init_time	= clps711x_timer_init,
 	.init_machine	= p720t_init,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,12 +27,14 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clockchips.h>
+#include <linux/clocksource.h>
 #include <linux/clk-provider.h>
 
 #include <asm/exception.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
+#include <asm/sched_clock.h>
 #include <asm/system_misc.h>
 
 #include <mach/hardware.h>
@@ -213,7 +215,7 @@ void __init clps711x_init_irq(void)
 	}
 }
 
-inline u32 fls16(u32 x)
+static inline u32 fls16(u32 x)
 {
 	u32 r = 15;
 
@@ -237,27 +239,52 @@ inline u32 fls16(u32 x)
 
 asmlinkage void __exception_irq_entry clps711x_handle_irq(struct pt_regs *regs)
 {
-	u32 irqstat;
-	void __iomem *base = CLPS711X_VIRT_BASE;
+	do {
+		u32 irqstat;
+		void __iomem *base = CLPS711X_VIRT_BASE;
 
-	irqstat = readl_relaxed(base + INTSR1) & readl_relaxed(base + INTMR1);
-	if (irqstat) {
-		handle_IRQ(fls16(irqstat), regs);
-		return;
-	}
+		irqstat = readw_relaxed(base + INTSR1) &
+			  readw_relaxed(base + INTMR1);
+		if (irqstat)
+			handle_IRQ(fls16(irqstat), regs);
 
-	irqstat = readl_relaxed(base + INTSR2) & readl_relaxed(base + INTMR2);
-	if (likely(irqstat))
-		handle_IRQ(fls16(irqstat) + 16, regs);
+		irqstat = readw_relaxed(base + INTSR2) &
+			  readw_relaxed(base + INTMR2);
+		if (irqstat) {
+			handle_IRQ(fls16(irqstat) + 16, regs);
+			continue;
+		}
+
+		break;
+	} while (1);
+}
+
+static u32 notrace clps711x_sched_clock_read(void)
+{
+	return ~readw_relaxed(CLPS711X_VIRT_BASE + TC1D);
 }
 
 static void clps711x_clockevent_set_mode(enum clock_event_mode mode,
 					 struct clock_event_device *evt)
 {
+	disable_irq(IRQ_TC2OI);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		enable_irq(IRQ_TC2OI);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* Not supported */
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_RESUME:
+		/* Left event sources disabled, no more interrupts appear */
+		break;
+	}
 }
 
 static struct clock_event_device clockevent_clps711x = {
-	.name		= "CLPS711x Clockevents",
+	.name		= "clps711x-clockevent",
 	.rating		= 300,
 	.features	= CLOCK_EVT_FEAT_PERIODIC,
 	.set_mode	= clps711x_clockevent_set_mode,
@@ -271,8 +298,8 @@ static irqreturn_t clps711x_timer_interr
 }
 
 static struct irqaction clps711x_timer_irq = {
-	.name		= "CLPS711x Timer Tick",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.name		= "clps711x-timer",
+	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
 	.handler	= clps711x_timer_interrupt,
 };
 
@@ -301,6 +328,7 @@ void __init clps711x_timer_init(void)
 		cpu = ext;
 		bus = cpu;
 		spi = 135400;
+		pll = 0;
 	} else {
 		cpu = pll;
 		if (cpu >= 36864000)
@@ -319,9 +347,9 @@ void __init clps711x_timer_init(void)
 		else
 			timh = 541440;
 	} else
-		timh = cpu / 144;
+		timh = DIV_ROUND_CLOSEST(cpu, 144);
 
-	timl = timh / 256;
+	timl = DIV_ROUND_CLOSEST(timh, 256);
 
 	/* All clocks are fixed */
 	add_fixed_clk(clk_pll, "pll", pll);
@@ -334,18 +362,29 @@ void __init clps711x_timer_init(void)
 
 	pr_info("CPU frequency set at %i Hz.\n", cpu);
 
+	/* Start Timer1 in free running mode (Low frequency) */
+	tmp = clps_readl(SYSCON1) & ~(SYSCON1_TC1S | SYSCON1_TC1M);
+	clps_writel(tmp, SYSCON1);
+
+	setup_sched_clock(clps711x_sched_clock_read, 16, timl);
+
+	clocksource_mmio_init(CLPS711X_VIRT_BASE + TC1D,
+			      "clps711x_clocksource", timl, 300, 16,
+			      clocksource_mmio_readw_down);
+
+	/* Set Timer2 prescaler */
 	clps_writew(DIV_ROUND_CLOSEST(timh, HZ), TC2D);
 
-	tmp = clps_readl(SYSCON1);
-	tmp |= SYSCON1_TC2S | SYSCON1_TC2M;
+	/* Start Timer2 in prescale mode (High frequency)*/
+	tmp = clps_readl(SYSCON1) | SYSCON1_TC2M | SYSCON1_TC2S;
 	clps_writel(tmp, SYSCON1);
 
-	clockevents_config_and_register(&clockevent_clps711x, timh, 1, 0xffff);
+	clockevents_config_and_register(&clockevent_clps711x, timh, 0, 0);
 
 	setup_irq(IRQ_TC2OI, &clps711x_timer_irq);
 }
 
-void clps711x_restart(char mode, const char *cmd)
+void clps711x_restart(enum reboot_mode mode, const char *cmd)
 {
 	soft_restart(0);
 }
@@ -353,15 +392,11 @@ void clps711x_restart(char mode, const c
 static void clps711x_idle(void)
 {
 	clps_writel(1, HALT);
-	__asm__ __volatile__(
-	"mov    r0, r0\n\
-	mov     r0, r0");
+	asm("mov r0, r0");
+	asm("mov r0, r0");
 }
 
-static int __init clps711x_idle_init(void)
+void __init clps711x_init_early(void)
 {
 	arm_pm_idle = clps711x_idle;
-	return 0;
 }
-
-arch_initcall(clps711x_idle_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -4,6 +4,8 @@
  * Common bits.
  */
 
+#include <linux/reboot.h>
+
 #define CLPS711X_NR_IRQS	(33)
 #define CLPS711X_NR_GPIO	(4 * 8 + 3)
 #define CLPS711X_GPIO(prt, bit)	((prt) * 8 + (bit))
@@ -12,4 +14,5 @@ extern void clps711x_map_io(void);
 extern void clps711x_init_irq(void);
 extern void clps711x_timer_init(void);
 extern void clps711x_handle_irq(struct pt_regs *regs);
-extern void clps711x_restart(char mode, const char *cmd);
+extern void clps711x_restart(enum reboot_mode mode, const char *cmd);
+extern void clps711x_init_early(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/devices.c linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/devices.c
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/devices.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/devices.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,68 @@
+/*
+ *  CLPS711X common devices definitions
+ *
+ *  Author: Alexander Shiyan <shc_work@mail.ru>, 2013
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/sizes.h>
+
+#include <mach/hardware.h>
+
+static const phys_addr_t clps711x_gpios[][2] __initconst = {
+	{ PADR, PADDR },
+	{ PBDR, PBDDR },
+	{ PCDR, PCDDR },
+	{ PDDR, PDDDR },
+	{ PEDR, PEDDR },
+};
+
+static void __init clps711x_add_gpio(void)
+{
+	unsigned i;
+	struct resource gpio_res[2];
+
+	memset(gpio_res, 0, sizeof(gpio_res));
+
+	gpio_res[0].flags = IORESOURCE_MEM;
+	gpio_res[1].flags = IORESOURCE_MEM;
+
+	for (i = 0; i < ARRAY_SIZE(clps711x_gpios); i++) {
+		gpio_res[0].start = CLPS711X_PHYS_BASE + clps711x_gpios[i][0];
+		gpio_res[0].end = gpio_res[0].start;
+		gpio_res[1].start = CLPS711X_PHYS_BASE + clps711x_gpios[i][1];
+		gpio_res[1].end = gpio_res[1].start;
+
+		platform_device_register_simple("clps711x-gpio", i,
+						gpio_res, ARRAY_SIZE(gpio_res));
+	}
+}
+
+const struct resource clps711x_syscon_res[] __initconst = {
+	/* SYSCON1, SYSFLG1 */
+	DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON1, SZ_128),
+	/* SYSCON2, SYSFLG2 */
+	DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON2, SZ_128),
+	/* SYSCON3 */
+	DEFINE_RES_MEM(CLPS711X_PHYS_BASE + SYSCON3, SZ_64),
+};
+
+static void __init clps711x_add_syscon(void)
+{
+	unsigned i;
+
+	for (i = 0; i < ARRAY_SIZE(clps711x_syscon_res); i++)
+		platform_device_register_simple("clps711x-syscon", i + 1,
+						&clps711x_syscon_res[i], 1);
+}
+
+void __init clps711x_devices_init(void)
+{
+	clps711x_add_gpio();
+	clps711x_add_syscon();
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/devices.h linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/devices.h
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/devices.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/devices.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,12 @@
+/*
+ *  CLPS711X common devices definitions
+ *
+ *  Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+void clps711x_devices_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/autcpu12.h linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/autcpu12.h
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/autcpu12.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/autcpu12.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,59 +0,0 @@
-/*
- * AUTCPU12 specific defines
- *
- * (c) 2001 Thomas Gleixner, autronix automation <gleixner@autronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_AUTCPU12_H
-#define __ASM_ARCH_AUTCPU12_H
-
-/*
- * The flash bank is wired to chip select 0
- */
-#define AUTCPU12_PHYS_FLASH		CS0_PHYS_BASE		/* physical */
-
-/* offset for device specific information structure */
-#define AUTCPU12_LCDINFO_OFFS		(0x00010000)	
-
-/* Videomemory in the internal SRAM (CS 6) */
-#define AUTCPU12_PHYS_VIDEO		CS6_PHYS_BASE
-
-/*
-* All special IO's are tied to CS1
-*/
-#define AUTCPU12_PHYS_CHAR_LCD         	CS1_PHYS_BASE +0x00000000  /* physical */
-
-#define AUTCPU12_PHYS_NVRAM            	CS1_PHYS_BASE +0x02000000  /* physical */
-
-#define AUTCPU12_PHYS_CSAUX1           	CS1_PHYS_BASE +0x04000000  /* physical */
-
-#define AUTCPU12_PHYS_CAN              	CS1_PHYS_BASE +0x08000000  /* physical */
-
-#define AUTCPU12_PHYS_TOUCH            	CS1_PHYS_BASE +0x0A000000  /* physical */
-
-#define AUTCPU12_PHYS_IO               	CS1_PHYS_BASE +0x0C000000  /* physical */
-
-#define AUTCPU12_PHYS_LPT              	CS1_PHYS_BASE +0x0E000000  /* physical */
-
-/*
-* defines for lcd contrast 
-*/
-#define AUTCPU12_DPOT_PORT_OFFSET	PEDR
-#define	AUTCPU12_DPOT_CS		(1<<0)
-#define AUTCPU12_DPOT_CLK    		(1<<1)
-#define	AUTCPU12_DPOT_UD		(1<<2)
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/clps711x.h linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/clps711x.h
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/clps711x.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/clps711x.h	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,8 @@
 #ifndef __MACH_CLPS711X_H
 #define __MACH_CLPS711X_H
 
+#include <linux/mfd/syscon/clps711x.h>
+
 #define CLPS711X_PHYS_BASE	(0x80000000)
 
 #define PADR		(0x0000)
@@ -96,83 +98,9 @@
 #define RANDID2		(0x2708)
 #define RANDID3		(0x270c)
 
-/* common bits: SYSCON1 / SYSCON2 */
-#define SYSCON_UARTEN		(1 << 8)
-
-#define SYSCON1_KBDSCAN(x)	((x) & 15)
-#define SYSCON1_KBDSCANMASK	(15)
-#define SYSCON1_TC1M		(1 << 4)
-#define SYSCON1_TC1S		(1 << 5)
-#define SYSCON1_TC2M		(1 << 6)
-#define SYSCON1_TC2S		(1 << 7)
-#define SYSCON1_UART1EN		SYSCON_UARTEN
-#define SYSCON1_BZTOG		(1 << 9)
-#define SYSCON1_BZMOD		(1 << 10)
-#define SYSCON1_DBGEN		(1 << 11)
-#define SYSCON1_LCDEN		(1 << 12)
-#define SYSCON1_CDENTX		(1 << 13)
-#define SYSCON1_CDENRX		(1 << 14)
-#define SYSCON1_SIREN		(1 << 15)
-#define SYSCON1_ADCKSEL(x)	(((x) & 3) << 16)
-#define SYSCON1_ADCKSEL_MASK	(3 << 16)
-#define SYSCON1_EXCKEN		(1 << 18)
-#define SYSCON1_WAKEDIS		(1 << 19)
-#define SYSCON1_IRTXM		(1 << 20)
-
-/* common bits: SYSFLG1 / SYSFLG2 */
-#define SYSFLG_UBUSY		(1 << 11)
-#define SYSFLG_URXFE		(1 << 22)
-#define SYSFLG_UTXFF		(1 << 23)
-
-#define SYSFLG1_MCDR		(1 << 0)
-#define SYSFLG1_DCDET		(1 << 1)
-#define SYSFLG1_WUDR		(1 << 2)
-#define SYSFLG1_WUON		(1 << 3)
-#define SYSFLG1_CTS		(1 << 8)
-#define SYSFLG1_DSR		(1 << 9)
-#define SYSFLG1_DCD		(1 << 10)
-#define SYSFLG1_UBUSY		SYSFLG_UBUSY
-#define SYSFLG1_NBFLG		(1 << 12)
-#define SYSFLG1_RSTFLG		(1 << 13)
-#define SYSFLG1_PFFLG		(1 << 14)
-#define SYSFLG1_CLDFLG		(1 << 15)
-#define SYSFLG1_URXFE		SYSFLG_URXFE
-#define SYSFLG1_UTXFF		SYSFLG_UTXFF
-#define SYSFLG1_CRXFE		(1 << 24)
-#define SYSFLG1_CTXFF		(1 << 25)
-#define SYSFLG1_SSIBUSY		(1 << 26)
-#define SYSFLG1_ID		(1 << 29)
-#define SYSFLG1_VERID(x)	(((x) >> 30) & 3)
-#define SYSFLG1_VERID_MASK	(3 << 30)
-
-#define SYSFLG2_SSRXOF		(1 << 0)
-#define SYSFLG2_RESVAL		(1 << 1)
-#define SYSFLG2_RESFRM		(1 << 2)
-#define SYSFLG2_SS2RXFE		(1 << 3)
-#define SYSFLG2_SS2TXFF		(1 << 4)
-#define SYSFLG2_SS2TXUF		(1 << 5)
-#define SYSFLG2_CKMODE		(1 << 6)
-#define SYSFLG2_UBUSY		SYSFLG_UBUSY
-#define SYSFLG2_URXFE		SYSFLG_URXFE
-#define SYSFLG2_UTXFF		SYSFLG_UTXFF
-
 #define LCDCON_GSEN		(1 << 30)
 #define LCDCON_GSMD		(1 << 31)
 
-#define SYSCON2_SERSEL		(1 << 0)
-#define SYSCON2_KBD6		(1 << 1)
-#define SYSCON2_DRAMZ		(1 << 2)
-#define SYSCON2_KBWEN		(1 << 3)
-#define SYSCON2_SS2TXEN		(1 << 4)
-#define SYSCON2_PCCARD1		(1 << 5)
-#define SYSCON2_PCCARD2		(1 << 6)
-#define SYSCON2_SS2RXEN		(1 << 7)
-#define SYSCON2_UART2EN		SYSCON_UARTEN
-#define SYSCON2_SS2MAEN		(1 << 9)
-#define SYSCON2_OSTB		(1 << 12)
-#define SYSCON2_CLKENSL		(1 << 13)
-#define SYSCON2_BUZFREQ		(1 << 14)
-
 /* common bits: UARTDR1 / UARTDR2 */
 #define UARTDR_FRMERR		(1 << 8)
 #define UARTDR_PARERR		(1 << 9)
@@ -228,18 +156,6 @@
 #define DAI64FS_MCLK256EN	(1 << 3)
 #define DAI64FS_LOOPBACK	(1 << 5)
 
-#define SYSCON3_ADCCON		(1 << 0)
-#define SYSCON3_CLKCTL0		(1 << 1)
-#define SYSCON3_CLKCTL1		(1 << 2)
-#define SYSCON3_DAISEL		(1 << 3)
-#define SYSCON3_ADCCKNSEN	(1 << 4)
-#define SYSCON3_VERSN(x)	(((x) >> 5) & 7)
-#define SYSCON3_VERSN_MASK	(7 << 5)
-#define SYSCON3_FASTWAKE	(1 << 8)
-#define SYSCON3_DAIEN		(1 << 9)
-#define SYSCON3_128FS		SYSCON3_DAIEN
-#define SYSCON3_ENPD67		(1 << 10)
-
 #define SDCONF_ACTIVE		(1 << 10)
 #define SDCONF_CLKCTL		(1 << 9)
 #define SDCONF_WIDTH_4		(0 << 7)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/hardware.h linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/hardware.h
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/hardware.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/hardware.h	2013-08-25 20:43:22.000000000 -0400
@@ -70,11 +70,4 @@
 #define CLPS711X_SDRAM0_BASE	(0xc0000000)
 #define CLPS711X_SDRAM1_BASE	(0xd0000000)
 
-#if defined (CONFIG_ARCH_EDB7211)
-
-/* The extra 8 lines of the keyboard matrix are wired to chip select 3 */
-#define EP7211_PHYS_EXTKBD	CS3_PHYS_BASE
-
-#endif /* CONFIG_ARCH_EDB7211 */
-
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/memory.h linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/memory.h
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/memory.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/*
- *  arch/arm/mach-clps711x/include/mach/memory.h
- *
- *  Copyright (C) 1999 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-/*
- * Physical DRAM offset.
- */
-#define PLAT_PHYS_OFFSET	UL(0xc0000000)
-
-/*
- * The PS7211 allows up to 256MB max per DRAM bank, but the EDB7211
- * uses only one of the two banks (bank #1).  However, even within
- * bank #1, memory is discontiguous.
- *
- * The EDB7211 has two 8MB DRAM areas with 8MB of empty space between
- * them, so we use 24 for the node max shift to get 16MB node sizes.
- */
-
-#define SECTION_SIZE_BITS	24
-#define MAX_PHYSMEM_BITS	32
-
-#endif
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/syspld.h linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/syspld.h
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/include/mach/syspld.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/include/mach/syspld.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,116 +0,0 @@
-/*
- *  arch/arm/mach-clps711x/include/mach/syspld.h
- *
- *  System Control PLD register definitions.
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSPLD_H
-#define __ASM_ARCH_SYSPLD_H
-
-#define SYSPLD_PHYS_BASE	(0x10000000)
-#define SYSPLD_VIRT_BASE	IO_ADDRESS(SYSPLD_PHYS_BASE)
-
-#define SYSPLD_REG(type, off)	(*(volatile type *)(SYSPLD_VIRT_BASE + (off)))
-
-#define PLD_INT		SYSPLD_REG(u32, 0x000000)
-#define PLD_INT_PENIRQ		(1 << 5)
-#define PLD_INT_UCB_IRQ		(1 << 1)
-#define PLD_INT_KBD_ATN		(1 << 0)	/* EINT1 */
-
-#define PLD_PWR		SYSPLD_REG(u32, 0x000004)
-#define PLD_PWR_EXT		(1 << 5)
-#define PLD_PWR_MODE		(1 << 4)	/* 1 = PWM, 0 = PFM */
-#define PLD_S4_ON		(1 << 3)	/* LCD bias voltage enable */
-#define PLD_S3_ON		(1 << 2)	/* LCD backlight enable */
-#define PLD_S2_ON		(1 << 1)	/* LCD 3V3 supply enable */
-#define PLD_S1_ON		(1 << 0)	/* LCD 3V supply enable */
-
-#define PLD_KBD		SYSPLD_REG(u32, 0x000008)
-#define PLD_KBD_WAKE		(1 << 1)
-#define PLD_KBD_EN		(1 << 0)
-
-#define PLD_SPI		SYSPLD_REG(u32, 0x00000c)
-#define PLD_SPI_EN		(1 << 0)
-
-#define PLD_IO		SYSPLD_REG(u32, 0x000010)
-#define PLD_IO_BOOTSEL		(1 << 6)	/* boot sel switch */
-#define PLD_IO_USER		(1 << 5)	/* user defined switch */
-#define PLD_IO_LED3		(1 << 4)
-#define PLD_IO_LED2		(1 << 3)
-#define PLD_IO_LED1		(1 << 2)
-#define PLD_IO_LED0		(1 << 1)
-#define PLD_IO_LEDEN		(1 << 0)
-
-#define PLD_IRDA	SYSPLD_REG(u32, 0x000014)
-#define PLD_IRDA_EN		(1 << 0)
-
-#define PLD_COM2	SYSPLD_REG(u32, 0x000018)
-#define PLD_COM2_EN		(1 << 0)
-
-#define PLD_COM1	SYSPLD_REG(u32, 0x00001c)
-#define PLD_COM1_EN		(1 << 0)
-
-#define PLD_AUD		SYSPLD_REG(u32, 0x000020)
-#define PLD_AUD_DIV1		(1 << 6)
-#define PLD_AUD_DIV0		(1 << 5)
-#define PLD_AUD_CLK_SEL1	(1 << 4)
-#define PLD_AUD_CLK_SEL0	(1 << 3)
-#define PLD_AUD_MIC_PWR		(1 << 2)
-#define PLD_AUD_MIC_GAIN	(1 << 1)
-#define PLD_AUD_CODEC_EN	(1 << 0)
-
-#define PLD_CF		SYSPLD_REG(u32, 0x000024)
-#define PLD_CF2_SLEEP		(1 << 5)
-#define PLD_CF1_SLEEP		(1 << 4)
-#define PLD_CF2_nPDREQ		(1 << 3)
-#define PLD_CF1_nPDREQ		(1 << 2)
-#define PLD_CF2_nIRQ		(1 << 1)
-#define PLD_CF1_nIRQ		(1 << 0)
-
-#define PLD_SDC		SYSPLD_REG(u32, 0x000028)
-#define PLD_SDC_INT_EN		(1 << 2)
-#define PLD_SDC_WP		(1 << 1)
-#define PLD_SDC_CD		(1 << 0)
-
-#define PLD_FPGA	SYSPLD_REG(u32, 0x00002c)
-
-#define PLD_CODEC	SYSPLD_REG(u32, 0x400000)
-#define PLD_CODEC_IRQ3		(1 << 4)
-#define PLD_CODEC_IRQ2		(1 << 3)
-#define PLD_CODEC_IRQ1		(1 << 2)
-#define PLD_CODEC_EN		(1 << 0)
-
-#define PLD_BRITE	SYSPLD_REG(u32, 0x400004)
-#define PLD_BRITE_UP		(1 << 1)
-#define PLD_BRITE_DN		(1 << 0)
-
-#define PLD_LCDEN	SYSPLD_REG(u32, 0x400008)
-#define PLD_LCDEN_EN		(1 << 0)
-
-#define PLD_ID		SYSPLD_REG(u32, 0x40000c)
-
-#define PLD_TCH		SYSPLD_REG(u32, 0x400010)
-#define PLD_TCH_PENIRQ		(1 << 1)
-#define PLD_TCH_EN		(1 << 0)
-
-#define PLD_GPIO	SYSPLD_REG(u32, 0x400014)
-#define PLD_GPIO2		(1 << 2)
-#define PLD_GPIO1		(1 << 1)
-#define PLD_GPIO0		(1 << 0)
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,8 +22,7 @@ config ARCH_CLEP7312
 
 config ARCH_EDB7211
 	bool "EDB7211"
-	select ARCH_SELECT_MEMORY_MODEL
-	select ARCH_SPARSEMEM_ENABLE
+	select ARCH_HAS_HOLES_MEMORYMODEL
 	help
 	  Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
 	  evaluation board.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-clps711x/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-clps711x/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-clps711x/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -4,10 +4,7 @@
 
 # Object file lists.
 
-obj-y			:= common.o
-obj-m			:=
-obj-n			:=
-obj-			:=
+obj-y				:= common.o devices.o
 
 obj-$(CONFIG_ARCH_AUTCPU12)	+= board-autcpu12.o
 obj-$(CONFIG_ARCH_CDB89712)	+= board-cdb89712.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-cns3xxx/core.h linux-libre-3.11-rc7-gnu/arch/arm/mach-cns3xxx/core.h
--- linux-libre-3.10-gnu/arch/arm/mach-cns3xxx/core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-cns3xxx/core.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,8 @@
 #ifndef __CNS3XXX_CORE_H
 #define __CNS3XXX_CORE_H
 
+#include <linux/reboot.h>
+
 extern void cns3xxx_timer_init(void);
 
 #ifdef CONFIG_CACHE_L2X0
@@ -22,6 +24,6 @@ static inline void cns3xxx_l2x0_init(voi
 void __init cns3xxx_map_io(void);
 void __init cns3xxx_init_irq(void);
 void cns3xxx_power_off(void);
-void cns3xxx_restart(char, const char *);
+void cns3xxx_restart(enum reboot_mode, const char *);
 
 #endif /* __CNS3XXX_CORE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-cns3xxx/pm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-cns3xxx/pm.c
--- linux-libre-3.10-gnu/arch/arm/mach-cns3xxx/pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-cns3xxx/pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -89,7 +89,7 @@ void cns3xxx_pwr_soft_rst(unsigned int b
 }
 EXPORT_SYMBOL(cns3xxx_pwr_soft_rst);
 
-void cns3xxx_restart(char mode, const char *cmd)
+void cns3xxx_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * To reset, we hit the on-board reset register
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/board-da850-evm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-da850-evm.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/board-da850-evm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-da850-evm.c	2013-08-25 20:43:22.000000000 -0400
@@ -985,7 +985,6 @@ static struct regulator_init_data tps650
 static struct touchscreen_init_data tps6507x_touchscreen_data = {
 	.poll_period =  30,	/* ms between touch samples */
 	.min_pressure = 0x30,	/* minimum pressure to trigger touch */
-	.vref = 0,		/* turn off vref when not using A/D */
 	.vendor = 0,		/* /sys/class/input/input?/id/vendor */
 	.product = 65070,	/* /sys/class/input/input?/id/product */
 	.version = 0x100,	/* /sys/class/input/input?/id/version */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/board-dm355-leopard.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-dm355-leopard.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/board-dm355-leopard.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-dm355-leopard.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,6 +75,7 @@ static struct davinci_nand_pdata davinci
 	.parts			= davinci_nand_partitions,
 	.nr_parts		= ARRAY_SIZE(davinci_nand_partitions),
 	.ecc_mode		= NAND_ECC_HW_SYNDROME,
+	.ecc_bits		= 4,
 	.bbt_options		= NAND_BBT_USE_FLASH,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/board-dm365-evm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-dm365-evm.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/board-dm365-evm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-dm365-evm.c	2013-08-25 20:43:22.000000000 -0400
@@ -505,11 +505,10 @@ static struct vpbe_output dm365evm_vpbe_
 /*
  * Amplifiers on the board
  */
-struct ths7303_platform_data ths7303_pdata = {
+static struct ths7303_platform_data ths7303_pdata = {
 	.ch_1 = 3,
 	.ch_2 = 3,
 	.ch_3 = 3,
-	.init_enable = 1,
 };
 
 static struct amp_config_info vpbe_amp = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/board-dm644x-evm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-dm644x-evm.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/board-dm644x-evm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-dm644x-evm.c	2013-08-25 20:43:22.000000000 -0400
@@ -153,6 +153,7 @@ static struct davinci_nand_pdata davinci
 	.parts		= davinci_evm_nandflash_partition,
 	.nr_parts	= ARRAY_SIZE(davinci_evm_nandflash_partition),
 	.ecc_mode	= NAND_ECC_HW,
+	.ecc_bits	= 1,
 	.bbt_options	= NAND_BBT_USE_FLASH,
 	.timing		= &davinci_evm_nandflash_timing,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/board-dm646x-evm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-dm646x-evm.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/board-dm646x-evm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-dm646x-evm.c	2013-08-25 20:43:22.000000000 -0400
@@ -90,6 +90,7 @@ static struct davinci_nand_pdata davinci
 	.parts			= davinci_nand_partitions,
 	.nr_parts		= ARRAY_SIZE(davinci_nand_partitions),
 	.ecc_mode		= NAND_ECC_HW,
+	.ecc_bits		= 1,
 	.options		= 0,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/board-neuros-osd2.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-neuros-osd2.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/board-neuros-osd2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-neuros-osd2.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,6 +88,7 @@ static struct davinci_nand_pdata davinci
 	.parts		= davinci_ntosd2_nandflash_partition,
 	.nr_parts	= ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
 	.ecc_mode	= NAND_ECC_HW,
+	.ecc_bits	= 1,
 	.bbt_options	= NAND_BBT_USE_FLASH,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/board-sffsdr.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-sffsdr.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/board-sffsdr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-sffsdr.c	2013-08-25 20:43:22.000000000 -0400
@@ -151,7 +151,6 @@ static __init void davinci_sffsdr_init(v
 }
 
 MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
-	/* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */
 	.atag_offset  = 0x100,
 	.map_io	      = davinci_sffsdr_map_io,
 	.init_irq     = davinci_irq_init,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/board-tnetv107x-evm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-tnetv107x-evm.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/board-tnetv107x-evm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/board-tnetv107x-evm.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,12 +26,12 @@
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
+#include <linux/platform_data/edma.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
 #include <mach/irqs.h>
-#include <mach/edma.h>
 #include <mach/mux.h>
 #include <mach/cp_intc.h>
 #include <mach/tnetv107x.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/da850.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/da850.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/da850.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/da850.c	2013-08-25 20:43:22.000000000 -0400
@@ -1004,7 +1004,7 @@ static const struct da850_opp da850_opp_
 
 #define OPP(freq) 		\
 	{				\
-		.index = (unsigned int) &da850_opp_##freq,	\
+		.driver_data = (unsigned int) &da850_opp_##freq,	\
 		.frequency = freq * 1000, \
 	}
 
@@ -1016,7 +1016,7 @@ static struct cpufreq_frequency_table da
 	OPP(200),
 	OPP(96),
 	{
-		.index		= 0,
+		.driver_data		= 0,
 		.frequency	= CPUFREQ_TABLE_END,
 	},
 };
@@ -1044,7 +1044,7 @@ static int da850_set_voltage(unsigned in
 	if (!cvdd)
 		return -ENODEV;
 
-	opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
+	opp = (struct da850_opp *) cpufreq_info.freq_table[index].driver_data;
 
 	return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
 }
@@ -1125,7 +1125,7 @@ static int da850_set_pll0rate(struct clk
 	struct pll_data *pll = clk->pll_data;
 	int ret;
 
-	opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
+	opp = (struct da850_opp *) cpufreq_info.freq_table[index].driver_data;
 	prediv = opp->prediv;
 	mult = opp->mult;
 	postdiv = opp->postdiv;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/davinci.h linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/davinci.h
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/davinci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/davinci.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,9 +23,9 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/platform_data/davinci_asp.h>
+#include <linux/platform_data/edma.h>
 #include <linux/platform_data/keyscan-davinci.h>
 #include <mach/hardware.h>
-#include <mach/edma.h>
 
 #include <media/davinci/vpfe_capture.h>
 #include <media/davinci/vpif_types.h>
@@ -77,32 +77,32 @@ void davinci_map_sysmod(void);
 #define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000
 
 /* DM355 function declarations */
-void __init dm355_init(void);
+void dm355_init(void);
 void dm355_init_spi0(unsigned chipselect_mask,
 		const struct spi_board_info *info, unsigned len);
-void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
+void dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
 int dm355_init_video(struct vpfe_config *, struct vpbe_config *);
 
 /* DM365 function declarations */
-void __init dm365_init(void);
-void __init dm365_init_asp(struct snd_platform_data *pdata);
-void __init dm365_init_vc(struct snd_platform_data *pdata);
-void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
-void __init dm365_init_rtc(void);
+void dm365_init(void);
+void dm365_init_asp(struct snd_platform_data *pdata);
+void dm365_init_vc(struct snd_platform_data *pdata);
+void dm365_init_ks(struct davinci_ks_platform_data *pdata);
+void dm365_init_rtc(void);
 void dm365_init_spi0(unsigned chipselect_mask,
 			const struct spi_board_info *info, unsigned len);
 int dm365_init_video(struct vpfe_config *, struct vpbe_config *);
 
 /* DM644x function declarations */
-void __init dm644x_init(void);
-void __init dm644x_init_asp(struct snd_platform_data *pdata);
-int __init dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
+void dm644x_init(void);
+void dm644x_init_asp(struct snd_platform_data *pdata);
+int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
 
 /* DM646x function declarations */
-void __init dm646x_init(void);
-void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
-void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
-int __init dm646x_init_edma(struct edma_rsv_info *rsv);
+void dm646x_init(void);
+void dm646x_init_mcasp0(struct snd_platform_data *pdata);
+void dm646x_init_mcasp1(struct snd_platform_data *pdata);
+int dm646x_init_edma(struct edma_rsv_info *rsv);
 void dm646x_video_init(void);
 void dm646x_setup_vpif(struct vpif_display_config *,
 		       struct vpif_capture_config *);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/devices.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/devices.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/devices.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/devices.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,15 +13,17 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/reboot.h>
 
 #include <mach/hardware.h>
 #include <linux/platform_data/i2c-davinci.h>
 #include <mach/irqs.h>
 #include <mach/cputype.h>
 #include <mach/mux.h>
-#include <mach/edma.h>
 #include <linux/platform_data/mmc-davinci.h>
 #include <mach/time.h>
+#include <linux/platform_data/edma.h>
+
 
 #include "davinci.h"
 #include "clock.h"
@@ -34,6 +36,9 @@
 #define DM365_MMCSD0_BASE	     0x01D11000
 #define DM365_MMCSD1_BASE	     0x01D00000
 
+#define DAVINCI_DMA_MMCRXEVT	26
+#define DAVINCI_DMA_MMCTXEVT	27
+
 void __iomem  *davinci_sysmod_base;
 
 void davinci_map_sysmod(void)
@@ -303,7 +308,7 @@ struct platform_device davinci_wdt_devic
 	.resource	= wdt_resources,
 };
 
-void davinci_restart(char mode, const char *cmd)
+void davinci_restart(enum reboot_mode mode, const char *cmd)
 {
 	davinci_watchdog_reset(&davinci_wdt_device);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/devices-da8xx.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/devices-da8xx.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/devices-da8xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/devices-da8xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/serial_8250.h>
 #include <linux/ahci_platform.h>
 #include <linux/clk.h>
+#include <linux/reboot.h>
 
 #include <mach/cputype.h>
 #include <mach/common.h>
@@ -105,27 +106,27 @@ struct platform_device da8xx_serial_devi
 	},
 };
 
-static const s8 da8xx_queue_tc_mapping[][2] = {
+static s8 da8xx_queue_tc_mapping[][2] = {
 	/* {event queue no, TC no} */
 	{0, 0},
 	{1, 1},
 	{-1, -1}
 };
 
-static const s8 da8xx_queue_priority_mapping[][2] = {
+static s8 da8xx_queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 3},
 	{1, 7},
 	{-1, -1}
 };
 
-static const s8 da850_queue_tc_mapping[][2] = {
+static s8 da850_queue_tc_mapping[][2] = {
 	/* {event queue no, TC no} */
 	{0, 0},
 	{-1, -1}
 };
 
-static const s8 da850_queue_priority_mapping[][2] = {
+static s8 da850_queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 3},
 	{-1, -1}
@@ -366,7 +367,7 @@ static struct platform_device da8xx_wdt_
 	.resource	= da8xx_watchdog_resources,
 };
 
-void da8xx_restart(char mode, const char *cmd)
+void da8xx_restart(enum reboot_mode mode, const char *cmd)
 {
 	struct device *dev;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/devices-tnetv107x.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/devices-tnetv107x.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/devices-tnetv107x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/devices-tnetv107x.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,10 +18,10 @@
 #include <linux/dma-mapping.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
+#include <linux/platform_data/edma.h>
 
 #include <mach/common.h>
 #include <mach/irqs.h>
-#include <mach/edma.h>
 #include <mach/tnetv107x.h>
 
 #include "clock.h"
@@ -58,14 +58,14 @@
 #define TNETV107X_DMACH_SDIO1_RX		28
 #define TNETV107X_DMACH_SDIO1_TX		29
 
-static const s8 edma_tc_mapping[][2] = {
+static s8 edma_tc_mapping[][2] = {
 	/* event queue no	TC no	*/
 	{	 0,		 0	},
 	{	 1,		 1	},
 	{	-1,		-1	}
 };
 
-static const s8 edma_priority_mapping[][2] = {
+static s8 edma_priority_mapping[][2] = {
 	/* event queue no	Prio	*/
 	{	 0,		 3	},
 	{	 1,		 7	},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/dm355.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dm355.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/dm355.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dm355.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,7 +19,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/cputype.h>
-#include <mach/edma.h>
 #include <mach/psc.h>
 #include <mach/mux.h>
 #include <mach/irqs.h>
@@ -28,6 +27,7 @@
 #include <mach/common.h>
 #include <linux/platform_data/spi-davinci.h>
 #include <mach/gpio-davinci.h>
+#include <linux/platform_data/edma.h>
 
 #include "davinci.h"
 #include "clock.h"
@@ -569,7 +569,7 @@ static u8 dm355_default_priorities[DAVIN
 
 /*----------------------------------------------------------------------*/
 
-static const s8
+static s8
 queue_tc_mapping[][2] = {
 	/* {event queue no, TC no} */
 	{0, 0},
@@ -577,7 +577,7 @@ queue_tc_mapping[][2] = {
 	{-1, -1},
 };
 
-static const s8
+static s8
 queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 3},
@@ -860,7 +860,7 @@ static struct platform_device dm355_vpbe
 	},
 };
 
-struct venc_platform_data dm355_venc_pdata = {
+static struct venc_platform_data dm355_venc_pdata = {
 	.setup_pinmux	= dm355_vpbe_setup_pinmux,
 	.setup_clock	= dm355_venc_setup_clock,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/dm365.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dm365.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/dm365.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dm365.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,11 +18,11 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/spi/spi.h>
+#include <linux/platform_data/edma.h>
 
 #include <asm/mach/map.h>
 
 #include <mach/cputype.h>
-#include <mach/edma.h>
 #include <mach/psc.h>
 #include <mach/mux.h>
 #include <mach/irqs.h>
@@ -826,7 +826,7 @@ static u8 dm365_default_priorities[DAVIN
 };
 
 /* Four Transfer Controllers on DM365 */
-static const s8
+static s8
 dm365_queue_tc_mapping[][2] = {
 	/* {event queue no, TC no} */
 	{0, 0},
@@ -836,7 +836,7 @@ dm365_queue_tc_mapping[][2] = {
 	{-1, -1},
 };
 
-static const s8
+static s8
 dm365_queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 7},
@@ -1349,7 +1349,7 @@ static struct platform_device dm365_vpbe
 	},
 };
 
-struct venc_platform_data dm365_venc_pdata = {
+static struct venc_platform_data dm365_venc_pdata = {
 	.setup_pinmux	= dm365_vpbe_setup_pinmux,
 	.setup_clock	= dm365_venc_setup_clock,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/dm644x.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dm644x.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/dm644x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dm644x.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,11 +12,11 @@
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/edma.h>
 
 #include <asm/mach/map.h>
 
 #include <mach/cputype.h>
-#include <mach/edma.h>
 #include <mach/irqs.h>
 #include <mach/psc.h>
 #include <mach/mux.h>
@@ -497,7 +497,7 @@ static u8 dm644x_default_priorities[DAVI
 
 /*----------------------------------------------------------------------*/
 
-static const s8
+static s8
 queue_tc_mapping[][2] = {
 	/* {event queue no, TC no} */
 	{0, 0},
@@ -505,7 +505,7 @@ queue_tc_mapping[][2] = {
 	{-1, -1},
 };
 
-static const s8
+static s8
 queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 3},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/dm646x.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dm646x.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/dm646x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dm646x.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,11 +13,11 @@
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/edma.h>
 
 #include <asm/mach/map.h>
 
 #include <mach/cputype.h>
-#include <mach/edma.h>
 #include <mach/irqs.h>
 #include <mach/psc.h>
 #include <mach/mux.h>
@@ -531,7 +531,7 @@ static u8 dm646x_default_priorities[DAVI
 /*----------------------------------------------------------------------*/
 
 /* Four Transfer Controllers on DM646x */
-static const s8
+static s8
 dm646x_queue_tc_mapping[][2] = {
 	/* {event queue no, TC no} */
 	{0, 0},
@@ -541,7 +541,7 @@ dm646x_queue_tc_mapping[][2] = {
 	{-1, -1},
 };
 
-static const s8
+static s8
 dm646x_queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 4},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/dma.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dma.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/dma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1591 +0,0 @@
-/*
- * EDMA3 support for DaVinci
- *
- * Copyright (C) 2006-2009 Texas Instruments.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <mach/edma.h>
-
-/* Offsets matching "struct edmacc_param" */
-#define PARM_OPT		0x00
-#define PARM_SRC		0x04
-#define PARM_A_B_CNT		0x08
-#define PARM_DST		0x0c
-#define PARM_SRC_DST_BIDX	0x10
-#define PARM_LINK_BCNTRLD	0x14
-#define PARM_SRC_DST_CIDX	0x18
-#define PARM_CCNT		0x1c
-
-#define PARM_SIZE		0x20
-
-/* Offsets for EDMA CC global channel registers and their shadows */
-#define SH_ER		0x00	/* 64 bits */
-#define SH_ECR		0x08	/* 64 bits */
-#define SH_ESR		0x10	/* 64 bits */
-#define SH_CER		0x18	/* 64 bits */
-#define SH_EER		0x20	/* 64 bits */
-#define SH_EECR		0x28	/* 64 bits */
-#define SH_EESR		0x30	/* 64 bits */
-#define SH_SER		0x38	/* 64 bits */
-#define SH_SECR		0x40	/* 64 bits */
-#define SH_IER		0x50	/* 64 bits */
-#define SH_IECR		0x58	/* 64 bits */
-#define SH_IESR		0x60	/* 64 bits */
-#define SH_IPR		0x68	/* 64 bits */
-#define SH_ICR		0x70	/* 64 bits */
-#define SH_IEVAL	0x78
-#define SH_QER		0x80
-#define SH_QEER		0x84
-#define SH_QEECR	0x88
-#define SH_QEESR	0x8c
-#define SH_QSER		0x90
-#define SH_QSECR	0x94
-#define SH_SIZE		0x200
-
-/* Offsets for EDMA CC global registers */
-#define EDMA_REV	0x0000
-#define EDMA_CCCFG	0x0004
-#define EDMA_QCHMAP	0x0200	/* 8 registers */
-#define EDMA_DMAQNUM	0x0240	/* 8 registers (4 on OMAP-L1xx) */
-#define EDMA_QDMAQNUM	0x0260
-#define EDMA_QUETCMAP	0x0280
-#define EDMA_QUEPRI	0x0284
-#define EDMA_EMR	0x0300	/* 64 bits */
-#define EDMA_EMCR	0x0308	/* 64 bits */
-#define EDMA_QEMR	0x0310
-#define EDMA_QEMCR	0x0314
-#define EDMA_CCERR	0x0318
-#define EDMA_CCERRCLR	0x031c
-#define EDMA_EEVAL	0x0320
-#define EDMA_DRAE	0x0340	/* 4 x 64 bits*/
-#define EDMA_QRAE	0x0380	/* 4 registers */
-#define EDMA_QUEEVTENTRY	0x0400	/* 2 x 16 registers */
-#define EDMA_QSTAT	0x0600	/* 2 registers */
-#define EDMA_QWMTHRA	0x0620
-#define EDMA_QWMTHRB	0x0624
-#define EDMA_CCSTAT	0x0640
-
-#define EDMA_M		0x1000	/* global channel registers */
-#define EDMA_ECR	0x1008
-#define EDMA_ECRH	0x100C
-#define EDMA_SHADOW0	0x2000	/* 4 regions shadowing global channels */
-#define EDMA_PARM	0x4000	/* 128 param entries */
-
-#define PARM_OFFSET(param_no)	(EDMA_PARM + ((param_no) << 5))
-
-#define EDMA_DCHMAP	0x0100  /* 64 registers */
-#define CHMAP_EXIST	BIT(24)
-
-#define EDMA_MAX_DMACH           64
-#define EDMA_MAX_PARAMENTRY     512
-
-/*****************************************************************************/
-
-static void __iomem *edmacc_regs_base[EDMA_MAX_CC];
-
-static inline unsigned int edma_read(unsigned ctlr, int offset)
-{
-	return (unsigned int)__raw_readl(edmacc_regs_base[ctlr] + offset);
-}
-
-static inline void edma_write(unsigned ctlr, int offset, int val)
-{
-	__raw_writel(val, edmacc_regs_base[ctlr] + offset);
-}
-static inline void edma_modify(unsigned ctlr, int offset, unsigned and,
-		unsigned or)
-{
-	unsigned val = edma_read(ctlr, offset);
-	val &= and;
-	val |= or;
-	edma_write(ctlr, offset, val);
-}
-static inline void edma_and(unsigned ctlr, int offset, unsigned and)
-{
-	unsigned val = edma_read(ctlr, offset);
-	val &= and;
-	edma_write(ctlr, offset, val);
-}
-static inline void edma_or(unsigned ctlr, int offset, unsigned or)
-{
-	unsigned val = edma_read(ctlr, offset);
-	val |= or;
-	edma_write(ctlr, offset, val);
-}
-static inline unsigned int edma_read_array(unsigned ctlr, int offset, int i)
-{
-	return edma_read(ctlr, offset + (i << 2));
-}
-static inline void edma_write_array(unsigned ctlr, int offset, int i,
-		unsigned val)
-{
-	edma_write(ctlr, offset + (i << 2), val);
-}
-static inline void edma_modify_array(unsigned ctlr, int offset, int i,
-		unsigned and, unsigned or)
-{
-	edma_modify(ctlr, offset + (i << 2), and, or);
-}
-static inline void edma_or_array(unsigned ctlr, int offset, int i, unsigned or)
-{
-	edma_or(ctlr, offset + (i << 2), or);
-}
-static inline void edma_or_array2(unsigned ctlr, int offset, int i, int j,
-		unsigned or)
-{
-	edma_or(ctlr, offset + ((i*2 + j) << 2), or);
-}
-static inline void edma_write_array2(unsigned ctlr, int offset, int i, int j,
-		unsigned val)
-{
-	edma_write(ctlr, offset + ((i*2 + j) << 2), val);
-}
-static inline unsigned int edma_shadow0_read(unsigned ctlr, int offset)
-{
-	return edma_read(ctlr, EDMA_SHADOW0 + offset);
-}
-static inline unsigned int edma_shadow0_read_array(unsigned ctlr, int offset,
-		int i)
-{
-	return edma_read(ctlr, EDMA_SHADOW0 + offset + (i << 2));
-}
-static inline void edma_shadow0_write(unsigned ctlr, int offset, unsigned val)
-{
-	edma_write(ctlr, EDMA_SHADOW0 + offset, val);
-}
-static inline void edma_shadow0_write_array(unsigned ctlr, int offset, int i,
-		unsigned val)
-{
-	edma_write(ctlr, EDMA_SHADOW0 + offset + (i << 2), val);
-}
-static inline unsigned int edma_parm_read(unsigned ctlr, int offset,
-		int param_no)
-{
-	return edma_read(ctlr, EDMA_PARM + offset + (param_no << 5));
-}
-static inline void edma_parm_write(unsigned ctlr, int offset, int param_no,
-		unsigned val)
-{
-	edma_write(ctlr, EDMA_PARM + offset + (param_no << 5), val);
-}
-static inline void edma_parm_modify(unsigned ctlr, int offset, int param_no,
-		unsigned and, unsigned or)
-{
-	edma_modify(ctlr, EDMA_PARM + offset + (param_no << 5), and, or);
-}
-static inline void edma_parm_and(unsigned ctlr, int offset, int param_no,
-		unsigned and)
-{
-	edma_and(ctlr, EDMA_PARM + offset + (param_no << 5), and);
-}
-static inline void edma_parm_or(unsigned ctlr, int offset, int param_no,
-		unsigned or)
-{
-	edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or);
-}
-
-static inline void set_bits(int offset, int len, unsigned long *p)
-{
-	for (; len > 0; len--)
-		set_bit(offset + (len - 1), p);
-}
-
-static inline void clear_bits(int offset, int len, unsigned long *p)
-{
-	for (; len > 0; len--)
-		clear_bit(offset + (len - 1), p);
-}
-
-/*****************************************************************************/
-
-/* actual number of DMA channels and slots on this silicon */
-struct edma {
-	/* how many dma resources of each type */
-	unsigned	num_channels;
-	unsigned	num_region;
-	unsigned	num_slots;
-	unsigned	num_tc;
-	unsigned	num_cc;
-	enum dma_event_q 	default_queue;
-
-	/* list of channels with no even trigger; terminated by "-1" */
-	const s8	*noevent;
-
-	/* The edma_inuse bit for each PaRAM slot is clear unless the
-	 * channel is in use ... by ARM or DSP, for QDMA, or whatever.
-	 */
-	DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
-
-	/* The edma_unused bit for each channel is clear unless
-	 * it is not being used on this platform. It uses a bit
-	 * of SOC-specific initialization code.
-	 */
-	DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH);
-
-	unsigned	irq_res_start;
-	unsigned	irq_res_end;
-
-	struct dma_interrupt_data {
-		void (*callback)(unsigned channel, unsigned short ch_status,
-				void *data);
-		void *data;
-	} intr_data[EDMA_MAX_DMACH];
-};
-
-static struct edma *edma_cc[EDMA_MAX_CC];
-static int arch_num_cc;
-
-/* dummy param set used to (re)initialize parameter RAM slots */
-static const struct edmacc_param dummy_paramset = {
-	.link_bcntrld = 0xffff,
-	.ccnt = 1,
-};
-
-/*****************************************************************************/
-
-static void map_dmach_queue(unsigned ctlr, unsigned ch_no,
-		enum dma_event_q queue_no)
-{
-	int bit = (ch_no & 0x7) * 4;
-
-	/* default to low priority queue */
-	if (queue_no == EVENTQ_DEFAULT)
-		queue_no = edma_cc[ctlr]->default_queue;
-
-	queue_no &= 7;
-	edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3),
-			~(0x7 << bit), queue_no << bit);
-}
-
-static void __init map_queue_tc(unsigned ctlr, int queue_no, int tc_no)
-{
-	int bit = queue_no * 4;
-	edma_modify(ctlr, EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit));
-}
-
-static void __init assign_priority_to_queue(unsigned ctlr, int queue_no,
-		int priority)
-{
-	int bit = queue_no * 4;
-	edma_modify(ctlr, EDMA_QUEPRI, ~(0x7 << bit),
-			((priority & 0x7) << bit));
-}
-
-/**
- * map_dmach_param - Maps channel number to param entry number
- *
- * This maps the dma channel number to param entry numberter. In
- * other words using the DMA channel mapping registers a param entry
- * can be mapped to any channel
- *
- * Callers are responsible for ensuring the channel mapping logic is
- * included in that particular EDMA variant (Eg : dm646x)
- *
- */
-static void __init map_dmach_param(unsigned ctlr)
-{
-	int i;
-	for (i = 0; i < EDMA_MAX_DMACH; i++)
-		edma_write_array(ctlr, EDMA_DCHMAP , i , (i << 5));
-}
-
-static inline void
-setup_dma_interrupt(unsigned lch,
-	void (*callback)(unsigned channel, u16 ch_status, void *data),
-	void *data)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(lch);
-	lch = EDMA_CHAN_SLOT(lch);
-
-	if (!callback)
-		edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5,
-				BIT(lch & 0x1f));
-
-	edma_cc[ctlr]->intr_data[lch].callback = callback;
-	edma_cc[ctlr]->intr_data[lch].data = data;
-
-	if (callback) {
-		edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5,
-				BIT(lch & 0x1f));
-		edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5,
-				BIT(lch & 0x1f));
-	}
-}
-
-static int irq2ctlr(int irq)
-{
-	if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end)
-		return 0;
-	else if (irq >= edma_cc[1]->irq_res_start &&
-		irq <= edma_cc[1]->irq_res_end)
-		return 1;
-
-	return -1;
-}
-
-/******************************************************************************
- *
- * DMA interrupt handler
- *
- *****************************************************************************/
-static irqreturn_t dma_irq_handler(int irq, void *data)
-{
-	int ctlr;
-	u32 sh_ier;
-	u32 sh_ipr;
-	u32 bank;
-
-	ctlr = irq2ctlr(irq);
-	if (ctlr < 0)
-		return IRQ_NONE;
-
-	dev_dbg(data, "dma_irq_handler\n");
-
-	sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0);
-	if (!sh_ipr) {
-		sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 1);
-		if (!sh_ipr)
-			return IRQ_NONE;
-		sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 1);
-		bank = 1;
-	} else {
-		sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 0);
-		bank = 0;
-	}
-
-	do {
-		u32 slot;
-		u32 channel;
-
-		dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr);
-
-		slot = __ffs(sh_ipr);
-		sh_ipr &= ~(BIT(slot));
-
-		if (sh_ier & BIT(slot)) {
-			channel = (bank << 5) | slot;
-			/* Clear the corresponding IPR bits */
-			edma_shadow0_write_array(ctlr, SH_ICR, bank,
-					BIT(slot));
-			if (edma_cc[ctlr]->intr_data[channel].callback)
-				edma_cc[ctlr]->intr_data[channel].callback(
-					channel, DMA_COMPLETE,
-					edma_cc[ctlr]->intr_data[channel].data);
-		}
-	} while (sh_ipr);
-
-	edma_shadow0_write(ctlr, SH_IEVAL, 1);
-	return IRQ_HANDLED;
-}
-
-/******************************************************************************
- *
- * DMA error interrupt handler
- *
- *****************************************************************************/
-static irqreturn_t dma_ccerr_handler(int irq, void *data)
-{
-	int i;
-	int ctlr;
-	unsigned int cnt = 0;
-
-	ctlr = irq2ctlr(irq);
-	if (ctlr < 0)
-		return IRQ_NONE;
-
-	dev_dbg(data, "dma_ccerr_handler\n");
-
-	if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
-	    (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
-	    (edma_read(ctlr, EDMA_QEMR) == 0) &&
-	    (edma_read(ctlr, EDMA_CCERR) == 0))
-		return IRQ_NONE;
-
-	while (1) {
-		int j = -1;
-		if (edma_read_array(ctlr, EDMA_EMR, 0))
-			j = 0;
-		else if (edma_read_array(ctlr, EDMA_EMR, 1))
-			j = 1;
-		if (j >= 0) {
-			dev_dbg(data, "EMR%d %08x\n", j,
-					edma_read_array(ctlr, EDMA_EMR, j));
-			for (i = 0; i < 32; i++) {
-				int k = (j << 5) + i;
-				if (edma_read_array(ctlr, EDMA_EMR, j) &
-							BIT(i)) {
-					/* Clear the corresponding EMR bits */
-					edma_write_array(ctlr, EDMA_EMCR, j,
-							BIT(i));
-					/* Clear any SER */
-					edma_shadow0_write_array(ctlr, SH_SECR,
-								j, BIT(i));
-					if (edma_cc[ctlr]->intr_data[k].
-								callback) {
-						edma_cc[ctlr]->intr_data[k].
-						callback(k,
-						DMA_CC_ERROR,
-						edma_cc[ctlr]->intr_data
-						[k].data);
-					}
-				}
-			}
-		} else if (edma_read(ctlr, EDMA_QEMR)) {
-			dev_dbg(data, "QEMR %02x\n",
-				edma_read(ctlr, EDMA_QEMR));
-			for (i = 0; i < 8; i++) {
-				if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) {
-					/* Clear the corresponding IPR bits */
-					edma_write(ctlr, EDMA_QEMCR, BIT(i));
-					edma_shadow0_write(ctlr, SH_QSECR,
-								BIT(i));
-
-					/* NOTE:  not reported!! */
-				}
-			}
-		} else if (edma_read(ctlr, EDMA_CCERR)) {
-			dev_dbg(data, "CCERR %08x\n",
-				edma_read(ctlr, EDMA_CCERR));
-			/* FIXME:  CCERR.BIT(16) ignored!  much better
-			 * to just write CCERRCLR with CCERR value...
-			 */
-			for (i = 0; i < 8; i++) {
-				if (edma_read(ctlr, EDMA_CCERR) & BIT(i)) {
-					/* Clear the corresponding IPR bits */
-					edma_write(ctlr, EDMA_CCERRCLR, BIT(i));
-
-					/* NOTE:  not reported!! */
-				}
-			}
-		}
-		if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
-		    (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
-		    (edma_read(ctlr, EDMA_QEMR) == 0) &&
-		    (edma_read(ctlr, EDMA_CCERR) == 0))
-			break;
-		cnt++;
-		if (cnt > 10)
-			break;
-	}
-	edma_write(ctlr, EDMA_EEVAL, 1);
-	return IRQ_HANDLED;
-}
-
-/******************************************************************************
- *
- * Transfer controller error interrupt handlers
- *
- *****************************************************************************/
-
-#define tc_errs_handled	false	/* disabled as long as they're NOPs */
-
-static irqreturn_t dma_tc0err_handler(int irq, void *data)
-{
-	dev_dbg(data, "dma_tc0err_handler\n");
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t dma_tc1err_handler(int irq, void *data)
-{
-	dev_dbg(data, "dma_tc1err_handler\n");
-	return IRQ_HANDLED;
-}
-
-static int reserve_contiguous_slots(int ctlr, unsigned int id,
-				     unsigned int num_slots,
-				     unsigned int start_slot)
-{
-	int i, j;
-	unsigned int count = num_slots;
-	int stop_slot = start_slot;
-	DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY);
-
-	for (i = start_slot; i < edma_cc[ctlr]->num_slots; ++i) {
-		j = EDMA_CHAN_SLOT(i);
-		if (!test_and_set_bit(j, edma_cc[ctlr]->edma_inuse)) {
-			/* Record our current beginning slot */
-			if (count == num_slots)
-				stop_slot = i;
-
-			count--;
-			set_bit(j, tmp_inuse);
-
-			if (count == 0)
-				break;
-		} else {
-			clear_bit(j, tmp_inuse);
-
-			if (id == EDMA_CONT_PARAMS_FIXED_EXACT) {
-				stop_slot = i;
-				break;
-			} else {
-				count = num_slots;
-			}
-		}
-	}
-
-	/*
-	 * We have to clear any bits that we set
-	 * if we run out parameter RAM slots, i.e we do find a set
-	 * of contiguous parameter RAM slots but do not find the exact number
-	 * requested as we may reach the total number of parameter RAM slots
-	 */
-	if (i == edma_cc[ctlr]->num_slots)
-		stop_slot = i;
-
-	j = start_slot;
-	for_each_set_bit_from(j, tmp_inuse, stop_slot)
-		clear_bit(j, edma_cc[ctlr]->edma_inuse);
-
-	if (count)
-		return -EBUSY;
-
-	for (j = i - num_slots + 1; j <= i; ++j)
-		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j),
-			&dummy_paramset, PARM_SIZE);
-
-	return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
-}
-
-static int prepare_unused_channel_list(struct device *dev, void *data)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	int i, ctlr;
-
-	for (i = 0; i < pdev->num_resources; i++) {
-		if ((pdev->resource[i].flags & IORESOURCE_DMA) &&
-				(int)pdev->resource[i].start >= 0) {
-			ctlr = EDMA_CTLR(pdev->resource[i].start);
-			clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
-					edma_cc[ctlr]->edma_unused);
-		}
-	}
-
-	return 0;
-}
-
-/*-----------------------------------------------------------------------*/
-
-static bool unused_chan_list_done;
-
-/* Resource alloc/free:  dma channels, parameter RAM slots */
-
-/**
- * edma_alloc_channel - allocate DMA channel and paired parameter RAM
- * @channel: specific channel to allocate; negative for "any unmapped channel"
- * @callback: optional; to be issued on DMA completion or errors
- * @data: passed to callback
- * @eventq_no: an EVENTQ_* constant, used to choose which Transfer
- *	Controller (TC) executes requests using this channel.  Use
- *	EVENTQ_DEFAULT unless you really need a high priority queue.
- *
- * This allocates a DMA channel and its associated parameter RAM slot.
- * The parameter RAM is initialized to hold a dummy transfer.
- *
- * Normal use is to pass a specific channel number as @channel, to make
- * use of hardware events mapped to that channel.  When the channel will
- * be used only for software triggering or event chaining, channels not
- * mapped to hardware events (or mapped to unused events) are preferable.
- *
- * DMA transfers start from a channel using edma_start(), or by
- * chaining.  When the transfer described in that channel's parameter RAM
- * slot completes, that slot's data may be reloaded through a link.
- *
- * DMA errors are only reported to the @callback associated with the
- * channel driving that transfer, but transfer completion callbacks can
- * be sent to another channel under control of the TCC field in
- * the option word of the transfer's parameter RAM set.  Drivers must not
- * use DMA transfer completion callbacks for channels they did not allocate.
- * (The same applies to TCC codes used in transfer chaining.)
- *
- * Returns the number of the channel, else negative errno.
- */
-int edma_alloc_channel(int channel,
-		void (*callback)(unsigned channel, u16 ch_status, void *data),
-		void *data,
-		enum dma_event_q eventq_no)
-{
-	unsigned i, done = 0, ctlr = 0;
-	int ret = 0;
-
-	if (!unused_chan_list_done) {
-		/*
-		 * Scan all the platform devices to find out the EDMA channels
-		 * used and clear them in the unused list, making the rest
-		 * available for ARM usage.
-		 */
-		ret = bus_for_each_dev(&platform_bus_type, NULL, NULL,
-				prepare_unused_channel_list);
-		if (ret < 0)
-			return ret;
-
-		unused_chan_list_done = true;
-	}
-
-	if (channel >= 0) {
-		ctlr = EDMA_CTLR(channel);
-		channel = EDMA_CHAN_SLOT(channel);
-	}
-
-	if (channel < 0) {
-		for (i = 0; i < arch_num_cc; i++) {
-			channel = 0;
-			for (;;) {
-				channel = find_next_bit(edma_cc[i]->edma_unused,
-						edma_cc[i]->num_channels,
-						channel);
-				if (channel == edma_cc[i]->num_channels)
-					break;
-				if (!test_and_set_bit(channel,
-						edma_cc[i]->edma_inuse)) {
-					done = 1;
-					ctlr = i;
-					break;
-				}
-				channel++;
-			}
-			if (done)
-				break;
-		}
-		if (!done)
-			return -ENOMEM;
-	} else if (channel >= edma_cc[ctlr]->num_channels) {
-		return -EINVAL;
-	} else if (test_and_set_bit(channel, edma_cc[ctlr]->edma_inuse)) {
-		return -EBUSY;
-	}
-
-	/* ensure access through shadow region 0 */
-	edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f));
-
-	/* ensure no events are pending */
-	edma_stop(EDMA_CTLR_CHAN(ctlr, channel));
-	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
-			&dummy_paramset, PARM_SIZE);
-
-	if (callback)
-		setup_dma_interrupt(EDMA_CTLR_CHAN(ctlr, channel),
-					callback, data);
-
-	map_dmach_queue(ctlr, channel, eventq_no);
-
-	return EDMA_CTLR_CHAN(ctlr, channel);
-}
-EXPORT_SYMBOL(edma_alloc_channel);
-
-
-/**
- * edma_free_channel - deallocate DMA channel
- * @channel: dma channel returned from edma_alloc_channel()
- *
- * This deallocates the DMA channel and associated parameter RAM slot
- * allocated by edma_alloc_channel().
- *
- * Callers are responsible for ensuring the channel is inactive, and
- * will not be reactivated by linking, chaining, or software calls to
- * edma_start().
- */
-void edma_free_channel(unsigned channel)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(channel);
-	channel = EDMA_CHAN_SLOT(channel);
-
-	if (channel >= edma_cc[ctlr]->num_channels)
-		return;
-
-	setup_dma_interrupt(channel, NULL, NULL);
-	/* REVISIT should probably take out of shadow region 0 */
-
-	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
-			&dummy_paramset, PARM_SIZE);
-	clear_bit(channel, edma_cc[ctlr]->edma_inuse);
-}
-EXPORT_SYMBOL(edma_free_channel);
-
-/**
- * edma_alloc_slot - allocate DMA parameter RAM
- * @slot: specific slot to allocate; negative for "any unused slot"
- *
- * This allocates a parameter RAM slot, initializing it to hold a
- * dummy transfer.  Slots allocated using this routine have not been
- * mapped to a hardware DMA channel, and will normally be used by
- * linking to them from a slot associated with a DMA channel.
- *
- * Normal use is to pass EDMA_SLOT_ANY as the @slot, but specific
- * slots may be allocated on behalf of DSP firmware.
- *
- * Returns the number of the slot, else negative errno.
- */
-int edma_alloc_slot(unsigned ctlr, int slot)
-{
-	if (!edma_cc[ctlr])
-		return -EINVAL;
-
-	if (slot >= 0)
-		slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot < 0) {
-		slot = edma_cc[ctlr]->num_channels;
-		for (;;) {
-			slot = find_next_zero_bit(edma_cc[ctlr]->edma_inuse,
-					edma_cc[ctlr]->num_slots, slot);
-			if (slot == edma_cc[ctlr]->num_slots)
-				return -ENOMEM;
-			if (!test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse))
-				break;
-		}
-	} else if (slot < edma_cc[ctlr]->num_channels ||
-			slot >= edma_cc[ctlr]->num_slots) {
-		return -EINVAL;
-	} else if (test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) {
-		return -EBUSY;
-	}
-
-	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
-			&dummy_paramset, PARM_SIZE);
-
-	return EDMA_CTLR_CHAN(ctlr, slot);
-}
-EXPORT_SYMBOL(edma_alloc_slot);
-
-/**
- * edma_free_slot - deallocate DMA parameter RAM
- * @slot: parameter RAM slot returned from edma_alloc_slot()
- *
- * This deallocates the parameter RAM slot allocated by edma_alloc_slot().
- * Callers are responsible for ensuring the slot is inactive, and will
- * not be activated.
- */
-void edma_free_slot(unsigned slot)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot < edma_cc[ctlr]->num_channels ||
-		slot >= edma_cc[ctlr]->num_slots)
-		return;
-
-	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
-			&dummy_paramset, PARM_SIZE);
-	clear_bit(slot, edma_cc[ctlr]->edma_inuse);
-}
-EXPORT_SYMBOL(edma_free_slot);
-
-
-/**
- * edma_alloc_cont_slots- alloc contiguous parameter RAM slots
- * The API will return the starting point of a set of
- * contiguous parameter RAM slots that have been requested
- *
- * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
- * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
- * @count: number of contiguous Paramter RAM slots
- * @slot  - the start value of Parameter RAM slot that should be passed if id
- * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
- *
- * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of
- * contiguous Parameter RAM slots from parameter RAM 64 in the case of
- * DaVinci SOCs and 32 in the case of DA8xx SOCs.
- *
- * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a
- * set of contiguous parameter RAM slots from the "slot" that is passed as an
- * argument to the API.
- *
- * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries
- * starts looking for a set of contiguous parameter RAMs from the "slot"
- * that is passed as an argument to the API. On failure the API will try to
- * find a set of contiguous Parameter RAM slots from the remaining Parameter
- * RAM slots
- */
-int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
-{
-	/*
-	 * The start slot requested should be greater than
-	 * the number of channels and lesser than the total number
-	 * of slots
-	 */
-	if ((id != EDMA_CONT_PARAMS_ANY) &&
-		(slot < edma_cc[ctlr]->num_channels ||
-		slot >= edma_cc[ctlr]->num_slots))
-		return -EINVAL;
-
-	/*
-	 * The number of parameter RAM slots requested cannot be less than 1
-	 * and cannot be more than the number of slots minus the number of
-	 * channels
-	 */
-	if (count < 1 || count >
-		(edma_cc[ctlr]->num_slots - edma_cc[ctlr]->num_channels))
-		return -EINVAL;
-
-	switch (id) {
-	case EDMA_CONT_PARAMS_ANY:
-		return reserve_contiguous_slots(ctlr, id, count,
-						 edma_cc[ctlr]->num_channels);
-	case EDMA_CONT_PARAMS_FIXED_EXACT:
-	case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
-		return reserve_contiguous_slots(ctlr, id, count, slot);
-	default:
-		return -EINVAL;
-	}
-
-}
-EXPORT_SYMBOL(edma_alloc_cont_slots);
-
-/**
- * edma_free_cont_slots - deallocate DMA parameter RAM slots
- * @slot: first parameter RAM of a set of parameter RAM slots to be freed
- * @count: the number of contiguous parameter RAM slots to be freed
- *
- * This deallocates the parameter RAM slots allocated by
- * edma_alloc_cont_slots.
- * Callers/applications need to keep track of sets of contiguous
- * parameter RAM slots that have been allocated using the edma_alloc_cont_slots
- * API.
- * Callers are responsible for ensuring the slots are inactive, and will
- * not be activated.
- */
-int edma_free_cont_slots(unsigned slot, int count)
-{
-	unsigned ctlr, slot_to_free;
-	int i;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot < edma_cc[ctlr]->num_channels ||
-		slot >= edma_cc[ctlr]->num_slots ||
-		count < 1)
-		return -EINVAL;
-
-	for (i = slot; i < slot + count; ++i) {
-		ctlr = EDMA_CTLR(i);
-		slot_to_free = EDMA_CHAN_SLOT(i);
-
-		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free),
-			&dummy_paramset, PARM_SIZE);
-		clear_bit(slot_to_free, edma_cc[ctlr]->edma_inuse);
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(edma_free_cont_slots);
-
-/*-----------------------------------------------------------------------*/
-
-/* Parameter RAM operations (i) -- read/write partial slots */
-
-/**
- * edma_set_src - set initial DMA source address in parameter RAM slot
- * @slot: parameter RAM slot being configured
- * @src_port: physical address of source (memory, controller FIFO, etc)
- * @addressMode: INCR, except in very rare cases
- * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
- *	width to use when addressing the fifo (e.g. W8BIT, W32BIT)
- *
- * Note that the source address is modified during the DMA transfer
- * according to edma_set_src_index().
- */
-void edma_set_src(unsigned slot, dma_addr_t src_port,
-				enum address_mode mode, enum fifo_width width)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot < edma_cc[ctlr]->num_slots) {
-		unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
-
-		if (mode) {
-			/* set SAM and program FWID */
-			i = (i & ~(EDMA_FWID)) | (SAM | ((width & 0x7) << 8));
-		} else {
-			/* clear SAM */
-			i &= ~SAM;
-		}
-		edma_parm_write(ctlr, PARM_OPT, slot, i);
-
-		/* set the source port address
-		   in source register of param structure */
-		edma_parm_write(ctlr, PARM_SRC, slot, src_port);
-	}
-}
-EXPORT_SYMBOL(edma_set_src);
-
-/**
- * edma_set_dest - set initial DMA destination address in parameter RAM slot
- * @slot: parameter RAM slot being configured
- * @dest_port: physical address of destination (memory, controller FIFO, etc)
- * @addressMode: INCR, except in very rare cases
- * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
- *	width to use when addressing the fifo (e.g. W8BIT, W32BIT)
- *
- * Note that the destination address is modified during the DMA transfer
- * according to edma_set_dest_index().
- */
-void edma_set_dest(unsigned slot, dma_addr_t dest_port,
-				 enum address_mode mode, enum fifo_width width)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot < edma_cc[ctlr]->num_slots) {
-		unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
-
-		if (mode) {
-			/* set DAM and program FWID */
-			i = (i & ~(EDMA_FWID)) | (DAM | ((width & 0x7) << 8));
-		} else {
-			/* clear DAM */
-			i &= ~DAM;
-		}
-		edma_parm_write(ctlr, PARM_OPT, slot, i);
-		/* set the destination port address
-		   in dest register of param structure */
-		edma_parm_write(ctlr, PARM_DST, slot, dest_port);
-	}
-}
-EXPORT_SYMBOL(edma_set_dest);
-
-/**
- * edma_get_position - returns the current transfer points
- * @slot: parameter RAM slot being examined
- * @src: pointer to source port position
- * @dst: pointer to destination port position
- *
- * Returns current source and destination addresses for a particular
- * parameter RAM slot.  Its channel should not be active when this is called.
- */
-void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst)
-{
-	struct edmacc_param temp;
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	edma_read_slot(EDMA_CTLR_CHAN(ctlr, slot), &temp);
-	if (src != NULL)
-		*src = temp.src;
-	if (dst != NULL)
-		*dst = temp.dst;
-}
-EXPORT_SYMBOL(edma_get_position);
-
-/**
- * edma_set_src_index - configure DMA source address indexing
- * @slot: parameter RAM slot being configured
- * @src_bidx: byte offset between source arrays in a frame
- * @src_cidx: byte offset between source frames in a block
- *
- * Offsets are specified to support either contiguous or discontiguous
- * memory transfers, or repeated access to a hardware register, as needed.
- * When accessing hardware registers, both offsets are normally zero.
- */
-void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot < edma_cc[ctlr]->num_slots) {
-		edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
-				0xffff0000, src_bidx);
-		edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
-				0xffff0000, src_cidx);
-	}
-}
-EXPORT_SYMBOL(edma_set_src_index);
-
-/**
- * edma_set_dest_index - configure DMA destination address indexing
- * @slot: parameter RAM slot being configured
- * @dest_bidx: byte offset between destination arrays in a frame
- * @dest_cidx: byte offset between destination frames in a block
- *
- * Offsets are specified to support either contiguous or discontiguous
- * memory transfers, or repeated access to a hardware register, as needed.
- * When accessing hardware registers, both offsets are normally zero.
- */
-void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot < edma_cc[ctlr]->num_slots) {
-		edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
-				0x0000ffff, dest_bidx << 16);
-		edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
-				0x0000ffff, dest_cidx << 16);
-	}
-}
-EXPORT_SYMBOL(edma_set_dest_index);
-
-/**
- * edma_set_transfer_params - configure DMA transfer parameters
- * @slot: parameter RAM slot being configured
- * @acnt: how many bytes per array (at least one)
- * @bcnt: how many arrays per frame (at least one)
- * @ccnt: how many frames per block (at least one)
- * @bcnt_rld: used only for A-Synchronized transfers; this specifies
- *	the value to reload into bcnt when it decrements to zero
- * @sync_mode: ASYNC or ABSYNC
- *
- * See the EDMA3 documentation to understand how to configure and link
- * transfers using the fields in PaRAM slots.  If you are not doing it
- * all at once with edma_write_slot(), you will use this routine
- * plus two calls each for source and destination, setting the initial
- * address and saying how to index that address.
- *
- * An example of an A-Synchronized transfer is a serial link using a
- * single word shift register.  In that case, @acnt would be equal to
- * that word size; the serial controller issues a DMA synchronization
- * event to transfer each word, and memory access by the DMA transfer
- * controller will be word-at-a-time.
- *
- * An example of an AB-Synchronized transfer is a device using a FIFO.
- * In that case, @acnt equals the FIFO width and @bcnt equals its depth.
- * The controller with the FIFO issues DMA synchronization events when
- * the FIFO threshold is reached, and the DMA transfer controller will
- * transfer one frame to (or from) the FIFO.  It will probably use
- * efficient burst modes to access memory.
- */
-void edma_set_transfer_params(unsigned slot,
-		u16 acnt, u16 bcnt, u16 ccnt,
-		u16 bcnt_rld, enum sync_dimension sync_mode)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot < edma_cc[ctlr]->num_slots) {
-		edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot,
-				0x0000ffff, bcnt_rld << 16);
-		if (sync_mode == ASYNC)
-			edma_parm_and(ctlr, PARM_OPT, slot, ~SYNCDIM);
-		else
-			edma_parm_or(ctlr, PARM_OPT, slot, SYNCDIM);
-		/* Set the acount, bcount, ccount registers */
-		edma_parm_write(ctlr, PARM_A_B_CNT, slot, (bcnt << 16) | acnt);
-		edma_parm_write(ctlr, PARM_CCNT, slot, ccnt);
-	}
-}
-EXPORT_SYMBOL(edma_set_transfer_params);
-
-/**
- * edma_link - link one parameter RAM slot to another
- * @from: parameter RAM slot originating the link
- * @to: parameter RAM slot which is the link target
- *
- * The originating slot should not be part of any active DMA transfer.
- */
-void edma_link(unsigned from, unsigned to)
-{
-	unsigned ctlr_from, ctlr_to;
-
-	ctlr_from = EDMA_CTLR(from);
-	from = EDMA_CHAN_SLOT(from);
-	ctlr_to = EDMA_CTLR(to);
-	to = EDMA_CHAN_SLOT(to);
-
-	if (from >= edma_cc[ctlr_from]->num_slots)
-		return;
-	if (to >= edma_cc[ctlr_to]->num_slots)
-		return;
-	edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000,
-				PARM_OFFSET(to));
-}
-EXPORT_SYMBOL(edma_link);
-
-/**
- * edma_unlink - cut link from one parameter RAM slot
- * @from: parameter RAM slot originating the link
- *
- * The originating slot should not be part of any active DMA transfer.
- * Its link is set to 0xffff.
- */
-void edma_unlink(unsigned from)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(from);
-	from = EDMA_CHAN_SLOT(from);
-
-	if (from >= edma_cc[ctlr]->num_slots)
-		return;
-	edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff);
-}
-EXPORT_SYMBOL(edma_unlink);
-
-/*-----------------------------------------------------------------------*/
-
-/* Parameter RAM operations (ii) -- read/write whole parameter sets */
-
-/**
- * edma_write_slot - write parameter RAM data for slot
- * @slot: number of parameter RAM slot being modified
- * @param: data to be written into parameter RAM slot
- *
- * Use this to assign all parameters of a transfer at once.  This
- * allows more efficient setup of transfers than issuing multiple
- * calls to set up those parameters in small pieces, and provides
- * complete control over all transfer options.
- */
-void edma_write_slot(unsigned slot, const struct edmacc_param *param)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot >= edma_cc[ctlr]->num_slots)
-		return;
-	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param,
-			PARM_SIZE);
-}
-EXPORT_SYMBOL(edma_write_slot);
-
-/**
- * edma_read_slot - read parameter RAM data from slot
- * @slot: number of parameter RAM slot being copied
- * @param: where to store copy of parameter RAM data
- *
- * Use this to read data from a parameter RAM slot, perhaps to
- * save them as a template for later reuse.
- */
-void edma_read_slot(unsigned slot, struct edmacc_param *param)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(slot);
-	slot = EDMA_CHAN_SLOT(slot);
-
-	if (slot >= edma_cc[ctlr]->num_slots)
-		return;
-	memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
-			PARM_SIZE);
-}
-EXPORT_SYMBOL(edma_read_slot);
-
-/*-----------------------------------------------------------------------*/
-
-/* Various EDMA channel control operations */
-
-/**
- * edma_pause - pause dma on a channel
- * @channel: on which edma_start() has been called
- *
- * This temporarily disables EDMA hardware events on the specified channel,
- * preventing them from triggering new transfers on its behalf
- */
-void edma_pause(unsigned channel)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(channel);
-	channel = EDMA_CHAN_SLOT(channel);
-
-	if (channel < edma_cc[ctlr]->num_channels) {
-		unsigned int mask = BIT(channel & 0x1f);
-
-		edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask);
-	}
-}
-EXPORT_SYMBOL(edma_pause);
-
-/**
- * edma_resume - resumes dma on a paused channel
- * @channel: on which edma_pause() has been called
- *
- * This re-enables EDMA hardware events on the specified channel.
- */
-void edma_resume(unsigned channel)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(channel);
-	channel = EDMA_CHAN_SLOT(channel);
-
-	if (channel < edma_cc[ctlr]->num_channels) {
-		unsigned int mask = BIT(channel & 0x1f);
-
-		edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask);
-	}
-}
-EXPORT_SYMBOL(edma_resume);
-
-/**
- * edma_start - start dma on a channel
- * @channel: channel being activated
- *
- * Channels with event associations will be triggered by their hardware
- * events, and channels without such associations will be triggered by
- * software.  (At this writing there is no interface for using software
- * triggers except with channels that don't support hardware triggers.)
- *
- * Returns zero on success, else negative errno.
- */
-int edma_start(unsigned channel)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(channel);
-	channel = EDMA_CHAN_SLOT(channel);
-
-	if (channel < edma_cc[ctlr]->num_channels) {
-		int j = channel >> 5;
-		unsigned int mask = BIT(channel & 0x1f);
-
-		/* EDMA channels without event association */
-		if (test_bit(channel, edma_cc[ctlr]->edma_unused)) {
-			pr_debug("EDMA: ESR%d %08x\n", j,
-				edma_shadow0_read_array(ctlr, SH_ESR, j));
-			edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
-			return 0;
-		}
-
-		/* EDMA channel with event association */
-		pr_debug("EDMA: ER%d %08x\n", j,
-			edma_shadow0_read_array(ctlr, SH_ER, j));
-		/* Clear any pending event or error */
-		edma_write_array(ctlr, EDMA_ECR, j, mask);
-		edma_write_array(ctlr, EDMA_EMCR, j, mask);
-		/* Clear any SER */
-		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
-		edma_shadow0_write_array(ctlr, SH_EESR, j, mask);
-		pr_debug("EDMA: EER%d %08x\n", j,
-			edma_shadow0_read_array(ctlr, SH_EER, j));
-		return 0;
-	}
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(edma_start);
-
-/**
- * edma_stop - stops dma on the channel passed
- * @channel: channel being deactivated
- *
- * When @lch is a channel, any active transfer is paused and
- * all pending hardware events are cleared.  The current transfer
- * may not be resumed, and the channel's Parameter RAM should be
- * reinitialized before being reused.
- */
-void edma_stop(unsigned channel)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(channel);
-	channel = EDMA_CHAN_SLOT(channel);
-
-	if (channel < edma_cc[ctlr]->num_channels) {
-		int j = channel >> 5;
-		unsigned int mask = BIT(channel & 0x1f);
-
-		edma_shadow0_write_array(ctlr, SH_EECR, j, mask);
-		edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
-		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
-		edma_write_array(ctlr, EDMA_EMCR, j, mask);
-
-		pr_debug("EDMA: EER%d %08x\n", j,
-				edma_shadow0_read_array(ctlr, SH_EER, j));
-
-		/* REVISIT:  consider guarding against inappropriate event
-		 * chaining by overwriting with dummy_paramset.
-		 */
-	}
-}
-EXPORT_SYMBOL(edma_stop);
-
-/******************************************************************************
- *
- * It cleans ParamEntry qand bring back EDMA to initial state if media has
- * been removed before EDMA has finished.It is usedful for removable media.
- * Arguments:
- *      ch_no     - channel no
- *
- * Return: zero on success, or corresponding error no on failure
- *
- * FIXME this should not be needed ... edma_stop() should suffice.
- *
- *****************************************************************************/
-
-void edma_clean_channel(unsigned channel)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(channel);
-	channel = EDMA_CHAN_SLOT(channel);
-
-	if (channel < edma_cc[ctlr]->num_channels) {
-		int j = (channel >> 5);
-		unsigned int mask = BIT(channel & 0x1f);
-
-		pr_debug("EDMA: EMR%d %08x\n", j,
-				edma_read_array(ctlr, EDMA_EMR, j));
-		edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
-		/* Clear the corresponding EMR bits */
-		edma_write_array(ctlr, EDMA_EMCR, j, mask);
-		/* Clear any SER */
-		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
-		edma_write(ctlr, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0));
-	}
-}
-EXPORT_SYMBOL(edma_clean_channel);
-
-/*
- * edma_clear_event - clear an outstanding event on the DMA channel
- * Arguments:
- *	channel - channel number
- */
-void edma_clear_event(unsigned channel)
-{
-	unsigned ctlr;
-
-	ctlr = EDMA_CTLR(channel);
-	channel = EDMA_CHAN_SLOT(channel);
-
-	if (channel >= edma_cc[ctlr]->num_channels)
-		return;
-	if (channel < 32)
-		edma_write(ctlr, EDMA_ECR, BIT(channel));
-	else
-		edma_write(ctlr, EDMA_ECRH, BIT(channel - 32));
-}
-EXPORT_SYMBOL(edma_clear_event);
-
-/*-----------------------------------------------------------------------*/
-
-static int __init edma_probe(struct platform_device *pdev)
-{
-	struct edma_soc_info	**info = pdev->dev.platform_data;
-	const s8		(*queue_priority_mapping)[2];
-	const s8		(*queue_tc_mapping)[2];
-	int			i, j, off, ln, found = 0;
-	int			status = -1;
-	const s16		(*rsv_chans)[2];
-	const s16		(*rsv_slots)[2];
-	int			irq[EDMA_MAX_CC] = {0, 0};
-	int			err_irq[EDMA_MAX_CC] = {0, 0};
-	struct resource		*r[EDMA_MAX_CC] = {NULL};
-	resource_size_t		len[EDMA_MAX_CC];
-	char			res_name[10];
-	char			irq_name[10];
-
-	if (!info)
-		return -ENODEV;
-
-	for (j = 0; j < EDMA_MAX_CC; j++) {
-		sprintf(res_name, "edma_cc%d", j);
-		r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-						res_name);
-		if (!r[j] || !info[j]) {
-			if (found)
-				break;
-			else
-				return -ENODEV;
-		} else {
-			found = 1;
-		}
-
-		len[j] = resource_size(r[j]);
-
-		r[j] = request_mem_region(r[j]->start, len[j],
-			dev_name(&pdev->dev));
-		if (!r[j]) {
-			status = -EBUSY;
-			goto fail1;
-		}
-
-		edmacc_regs_base[j] = ioremap(r[j]->start, len[j]);
-		if (!edmacc_regs_base[j]) {
-			status = -EBUSY;
-			goto fail1;
-		}
-
-		edma_cc[j] = kzalloc(sizeof(struct edma), GFP_KERNEL);
-		if (!edma_cc[j]) {
-			status = -ENOMEM;
-			goto fail1;
-		}
-
-		edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel,
-							EDMA_MAX_DMACH);
-		edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot,
-							EDMA_MAX_PARAMENTRY);
-		edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc,
-							EDMA_MAX_CC);
-
-		edma_cc[j]->default_queue = info[j]->default_queue;
-
-		dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n",
-			edmacc_regs_base[j]);
-
-		for (i = 0; i < edma_cc[j]->num_slots; i++)
-			memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
-					&dummy_paramset, PARM_SIZE);
-
-		/* Mark all channels as unused */
-		memset(edma_cc[j]->edma_unused, 0xff,
-			sizeof(edma_cc[j]->edma_unused));
-
-		if (info[j]->rsv) {
-
-			/* Clear the reserved channels in unused list */
-			rsv_chans = info[j]->rsv->rsv_chans;
-			if (rsv_chans) {
-				for (i = 0; rsv_chans[i][0] != -1; i++) {
-					off = rsv_chans[i][0];
-					ln = rsv_chans[i][1];
-					clear_bits(off, ln,
-						edma_cc[j]->edma_unused);
-				}
-			}
-
-			/* Set the reserved slots in inuse list */
-			rsv_slots = info[j]->rsv->rsv_slots;
-			if (rsv_slots) {
-				for (i = 0; rsv_slots[i][0] != -1; i++) {
-					off = rsv_slots[i][0];
-					ln = rsv_slots[i][1];
-					set_bits(off, ln,
-						edma_cc[j]->edma_inuse);
-				}
-			}
-		}
-
-		sprintf(irq_name, "edma%d", j);
-		irq[j] = platform_get_irq_byname(pdev, irq_name);
-		edma_cc[j]->irq_res_start = irq[j];
-		status = request_irq(irq[j], dma_irq_handler, 0, "edma",
-					&pdev->dev);
-		if (status < 0) {
-			dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
-				irq[j], status);
-			goto fail;
-		}
-
-		sprintf(irq_name, "edma%d_err", j);
-		err_irq[j] = platform_get_irq_byname(pdev, irq_name);
-		edma_cc[j]->irq_res_end = err_irq[j];
-		status = request_irq(err_irq[j], dma_ccerr_handler, 0,
-					"edma_error", &pdev->dev);
-		if (status < 0) {
-			dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
-				err_irq[j], status);
-			goto fail;
-		}
-
-		for (i = 0; i < edma_cc[j]->num_channels; i++)
-			map_dmach_queue(j, i, info[j]->default_queue);
-
-		queue_tc_mapping = info[j]->queue_tc_mapping;
-		queue_priority_mapping = info[j]->queue_priority_mapping;
-
-		/* Event queue to TC mapping */
-		for (i = 0; queue_tc_mapping[i][0] != -1; i++)
-			map_queue_tc(j, queue_tc_mapping[i][0],
-					queue_tc_mapping[i][1]);
-
-		/* Event queue priority mapping */
-		for (i = 0; queue_priority_mapping[i][0] != -1; i++)
-			assign_priority_to_queue(j,
-						queue_priority_mapping[i][0],
-						queue_priority_mapping[i][1]);
-
-		/* Map the channel to param entry if channel mapping logic
-		 * exist
-		 */
-		if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
-			map_dmach_param(j);
-
-		for (i = 0; i < info[j]->n_region; i++) {
-			edma_write_array2(j, EDMA_DRAE, i, 0, 0x0);
-			edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
-			edma_write_array(j, EDMA_QRAE, i, 0x0);
-		}
-		arch_num_cc++;
-	}
-
-	if (tc_errs_handled) {
-		status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0,
-					"edma_tc0", &pdev->dev);
-		if (status < 0) {
-			dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
-				IRQ_TCERRINT0, status);
-			return status;
-		}
-		status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0,
-					"edma_tc1", &pdev->dev);
-		if (status < 0) {
-			dev_dbg(&pdev->dev, "request_irq %d --> %d\n",
-				IRQ_TCERRINT, status);
-			return status;
-		}
-	}
-
-	return 0;
-
-fail:
-	for (i = 0; i < EDMA_MAX_CC; i++) {
-		if (err_irq[i])
-			free_irq(err_irq[i], &pdev->dev);
-		if (irq[i])
-			free_irq(irq[i], &pdev->dev);
-	}
-fail1:
-	for (i = 0; i < EDMA_MAX_CC; i++) {
-		if (r[i])
-			release_mem_region(r[i]->start, len[i]);
-		if (edmacc_regs_base[i])
-			iounmap(edmacc_regs_base[i]);
-		kfree(edma_cc[i]);
-	}
-	return status;
-}
-
-
-static struct platform_driver edma_driver = {
-	.driver.name	= "edma",
-};
-
-static int __init edma_init(void)
-{
-	return platform_driver_probe(&edma_driver, edma_probe);
-}
-arch_initcall(edma_init);
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
+#include <linux/reboot.h>
 
 extern void davinci_timer_init(void);
 
@@ -81,7 +82,7 @@ extern struct davinci_soc_info davinci_s
 
 extern void davinci_common_init(struct davinci_soc_info *soc_info);
 extern void davinci_init_ide(void);
-void davinci_restart(char mode, const char *cmd);
+void davinci_restart(enum reboot_mode mode, const char *cmd);
 void davinci_init_late(void);
 
 #ifdef CONFIG_DAVINCI_RESET_CLOCKS
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/cp_intc.h linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/cp_intc.h
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/cp_intc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/cp_intc.h	2013-08-25 20:43:22.000000000 -0400
@@ -51,7 +51,7 @@
 #define CP_INTC_HOST_PRIO_VECTOR(n)	(0x1600 + (n << 2))
 #define CP_INTC_VECTOR_ADDR(n)		(0x2000 + (n << 2))
 
-void __init cp_intc_init(void);
-int __init cp_intc_of_init(struct device_node *, struct device_node *);
+void cp_intc_init(void);
+int cp_intc_of_init(struct device_node *, struct device_node *);
 
 #endif	/* __ASM_HARDWARE_CP_INTC_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/da8xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/da8xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/da8xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/da8xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,12 @@
 #include <linux/davinci_emac.h>
 #include <linux/spi/spi.h>
 #include <linux/platform_data/davinci_asp.h>
+#include <linux/reboot.h>
 #include <linux/videodev2.h>
 
 #include <mach/serial.h>
-#include <mach/edma.h>
 #include <mach/pm.h>
+#include <linux/platform_data/edma.h>
 #include <linux/platform_data/i2c-davinci.h>
 #include <linux/platform_data/mmc-davinci.h>
 #include <linux/platform_data/usb-davinci.h>
@@ -79,8 +80,8 @@ extern unsigned int da850_max_speed;
 #define DA8XX_SHARED_RAM_BASE	0x80000000
 #define DA8XX_ARM_RAM_BASE	0xffff0000
 
-void __init da830_init(void);
-void __init da850_init(void);
+void da830_init(void);
+void da850_init(void);
 
 int da830_register_edma(struct edma_rsv_info *rsv);
 int da850_register_edma(struct edma_rsv_info *rsv[2]);
@@ -94,19 +95,19 @@ int da8xx_register_uio_pruss(void);
 int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
 int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
 int da850_register_mmcsd1(struct davinci_mmc_config *config);
-void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
+void da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
 int da8xx_register_rtc(void);
 int da850_register_cpufreq(char *async_clk);
 int da8xx_register_cpuidle(void);
-void __iomem * __init da8xx_get_mem_ctlr(void);
+void __iomem *da8xx_get_mem_ctlr(void);
 int da850_register_pm(struct platform_device *pdev);
-int __init da850_register_sata(unsigned long refclkpn);
-int __init da850_register_vpif(void);
-int __init da850_register_vpif_display
+int da850_register_sata(unsigned long refclkpn);
+int da850_register_vpif(void);
+int da850_register_vpif_display
 			(struct vpif_display_config *display_config);
-int __init da850_register_vpif_capture
+int da850_register_vpif_capture
 			(struct vpif_capture_config *capture_config);
-void da8xx_restart(char mode, const char *cmd);
+void da8xx_restart(enum reboot_mode mode, const char *cmd);
 void da8xx_rproc_reserve_cma(void);
 int da8xx_register_rproc(void);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/edma.h linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/edma.h
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/edma.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/edma.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,267 +0,0 @@
-/*
- *  TI DAVINCI dma definitions
- *
- *  Copyright (C) 2006-2009 Texas Instruments.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/*
- * This EDMA3 programming framework exposes two basic kinds of resource:
- *
- *  Channel	Triggers transfers, usually from a hardware event but
- *		also manually or by "chaining" from DMA completions.
- *		Each channel is coupled to a Parameter RAM (PaRAM) slot.
- *
- *  Slot	Each PaRAM slot holds a DMA transfer descriptor (PaRAM
- *		"set"), source and destination addresses, a link to a
- *		next PaRAM slot (if any), options for the transfer, and
- *		instructions for updating those addresses.  There are
- *		more than twice as many slots as event channels.
- *
- * Each PaRAM set describes a sequence of transfers, either for one large
- * buffer or for several discontiguous smaller buffers.  An EDMA transfer
- * is driven only from a channel, which performs the transfers specified
- * in its PaRAM slot until there are no more transfers.  When that last
- * transfer completes, the "link" field may be used to reload the channel's
- * PaRAM slot with a new transfer descriptor.
- *
- * The EDMA Channel Controller (CC) maps requests from channels into physical
- * Transfer Controller (TC) requests when the channel triggers (by hardware
- * or software events, or by chaining).  The two physical DMA channels provided
- * by the TCs are thus shared by many logical channels.
- *
- * DaVinci hardware also has a "QDMA" mechanism which is not currently
- * supported through this interface.  (DSP firmware uses it though.)
- */
-
-#ifndef EDMA_H_
-#define EDMA_H_
-
-/* PaRAM slots are laid out like this */
-struct edmacc_param {
-	unsigned int opt;
-	unsigned int src;
-	unsigned int a_b_cnt;
-	unsigned int dst;
-	unsigned int src_dst_bidx;
-	unsigned int link_bcntrld;
-	unsigned int src_dst_cidx;
-	unsigned int ccnt;
-};
-
-#define CCINT0_INTERRUPT     16
-#define CCERRINT_INTERRUPT   17
-#define TCERRINT0_INTERRUPT   18
-#define TCERRINT1_INTERRUPT   19
-
-/* fields in edmacc_param.opt */
-#define SAM		BIT(0)
-#define DAM		BIT(1)
-#define SYNCDIM		BIT(2)
-#define STATIC		BIT(3)
-#define EDMA_FWID	(0x07 << 8)
-#define TCCMODE		BIT(11)
-#define EDMA_TCC(t)	((t) << 12)
-#define TCINTEN		BIT(20)
-#define ITCINTEN	BIT(21)
-#define TCCHEN		BIT(22)
-#define ITCCHEN		BIT(23)
-
-#define TRWORD (0x7<<2)
-#define PAENTRY (0x1ff<<5)
-
-/* Drivers should avoid using these symbolic names for dm644x
- * channels, and use platform_device IORESOURCE_DMA resources
- * instead.  (Other DaVinci chips have different peripherals
- * and thus have different DMA channel mappings.)
- */
-#define DAVINCI_DMA_MCBSP_TX              2
-#define DAVINCI_DMA_MCBSP_RX              3
-#define DAVINCI_DMA_VPSS_HIST             4
-#define DAVINCI_DMA_VPSS_H3A              5
-#define DAVINCI_DMA_VPSS_PRVU             6
-#define DAVINCI_DMA_VPSS_RSZ              7
-#define DAVINCI_DMA_IMCOP_IMXINT          8
-#define DAVINCI_DMA_IMCOP_VLCDINT         9
-#define DAVINCI_DMA_IMCO_PASQINT         10
-#define DAVINCI_DMA_IMCOP_DSQINT         11
-#define DAVINCI_DMA_SPI_SPIX             16
-#define DAVINCI_DMA_SPI_SPIR             17
-#define DAVINCI_DMA_UART0_URXEVT0        18
-#define DAVINCI_DMA_UART0_UTXEVT0        19
-#define DAVINCI_DMA_UART1_URXEVT1        20
-#define DAVINCI_DMA_UART1_UTXEVT1        21
-#define DAVINCI_DMA_UART2_URXEVT2        22
-#define DAVINCI_DMA_UART2_UTXEVT2        23
-#define DAVINCI_DMA_MEMSTK_MSEVT         24
-#define DAVINCI_DMA_MMCRXEVT             26
-#define DAVINCI_DMA_MMCTXEVT             27
-#define DAVINCI_DMA_I2C_ICREVT           28
-#define DAVINCI_DMA_I2C_ICXEVT           29
-#define DAVINCI_DMA_GPIO_GPINT0          32
-#define DAVINCI_DMA_GPIO_GPINT1          33
-#define DAVINCI_DMA_GPIO_GPINT2          34
-#define DAVINCI_DMA_GPIO_GPINT3          35
-#define DAVINCI_DMA_GPIO_GPINT4          36
-#define DAVINCI_DMA_GPIO_GPINT5          37
-#define DAVINCI_DMA_GPIO_GPINT6          38
-#define DAVINCI_DMA_GPIO_GPINT7          39
-#define DAVINCI_DMA_GPIO_GPBNKINT0       40
-#define DAVINCI_DMA_GPIO_GPBNKINT1       41
-#define DAVINCI_DMA_GPIO_GPBNKINT2       42
-#define DAVINCI_DMA_GPIO_GPBNKINT3       43
-#define DAVINCI_DMA_GPIO_GPBNKINT4       44
-#define DAVINCI_DMA_TIMER0_TINT0         48
-#define DAVINCI_DMA_TIMER1_TINT1         49
-#define DAVINCI_DMA_TIMER2_TINT2         50
-#define DAVINCI_DMA_TIMER3_TINT3         51
-#define DAVINCI_DMA_PWM0                 52
-#define DAVINCI_DMA_PWM1                 53
-#define DAVINCI_DMA_PWM2                 54
-
-/* DA830 specific EDMA3 information */
-#define EDMA_DA830_NUM_DMACH		32
-#define EDMA_DA830_NUM_TCC		32
-#define EDMA_DA830_NUM_PARAMENTRY	128
-#define EDMA_DA830_NUM_EVQUE		2
-#define EDMA_DA830_NUM_TC		2
-#define EDMA_DA830_CHMAP_EXIST		0
-#define EDMA_DA830_NUM_REGIONS		4
-#define DA830_DMACH2EVENT_MAP0		0x000FC03Fu
-#define DA830_DMACH2EVENT_MAP1		0x00000000u
-#define DA830_EDMA_ARM_OWN		0x30FFCCFFu
-
-/*ch_status paramater of callback function possible values*/
-#define DMA_COMPLETE 1
-#define DMA_CC_ERROR 2
-#define DMA_TC1_ERROR 3
-#define DMA_TC2_ERROR 4
-
-enum address_mode {
-	INCR = 0,
-	FIFO = 1
-};
-
-enum fifo_width {
-	W8BIT = 0,
-	W16BIT = 1,
-	W32BIT = 2,
-	W64BIT = 3,
-	W128BIT = 4,
-	W256BIT = 5
-};
-
-enum dma_event_q {
-	EVENTQ_0 = 0,
-	EVENTQ_1 = 1,
-	EVENTQ_2 = 2,
-	EVENTQ_3 = 3,
-	EVENTQ_DEFAULT = -1
-};
-
-enum sync_dimension {
-	ASYNC = 0,
-	ABSYNC = 1
-};
-
-#define EDMA_CTLR_CHAN(ctlr, chan)	(((ctlr) << 16) | (chan))
-#define EDMA_CTLR(i)			((i) >> 16)
-#define EDMA_CHAN_SLOT(i)		((i) & 0xffff)
-
-#define EDMA_CHANNEL_ANY		-1	/* for edma_alloc_channel() */
-#define EDMA_SLOT_ANY			-1	/* for edma_alloc_slot() */
-#define EDMA_CONT_PARAMS_ANY		 1001
-#define EDMA_CONT_PARAMS_FIXED_EXACT	 1002
-#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
-
-#define EDMA_MAX_CC               2
-
-/* alloc/free DMA channels and their dedicated parameter RAM slots */
-int edma_alloc_channel(int channel,
-	void (*callback)(unsigned channel, u16 ch_status, void *data),
-	void *data, enum dma_event_q);
-void edma_free_channel(unsigned channel);
-
-/* alloc/free parameter RAM slots */
-int edma_alloc_slot(unsigned ctlr, int slot);
-void edma_free_slot(unsigned slot);
-
-/* alloc/free a set of contiguous parameter RAM slots */
-int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count);
-int edma_free_cont_slots(unsigned slot, int count);
-
-/* calls that operate on part of a parameter RAM slot */
-void edma_set_src(unsigned slot, dma_addr_t src_port,
-				enum address_mode mode, enum fifo_width);
-void edma_set_dest(unsigned slot, dma_addr_t dest_port,
-				 enum address_mode mode, enum fifo_width);
-void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst);
-void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx);
-void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx);
-void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt,
-		u16 bcnt_rld, enum sync_dimension sync_mode);
-void edma_link(unsigned from, unsigned to);
-void edma_unlink(unsigned from);
-
-/* calls that operate on an entire parameter RAM slot */
-void edma_write_slot(unsigned slot, const struct edmacc_param *params);
-void edma_read_slot(unsigned slot, struct edmacc_param *params);
-
-/* channel control operations */
-int edma_start(unsigned channel);
-void edma_stop(unsigned channel);
-void edma_clean_channel(unsigned channel);
-void edma_clear_event(unsigned channel);
-void edma_pause(unsigned channel);
-void edma_resume(unsigned channel);
-
-struct edma_rsv_info {
-
-	const s16	(*rsv_chans)[2];
-	const s16	(*rsv_slots)[2];
-};
-
-/* platform_data for EDMA driver */
-struct edma_soc_info {
-
-	/* how many dma resources of each type */
-	unsigned	n_channel;
-	unsigned	n_region;
-	unsigned	n_slot;
-	unsigned	n_tc;
-	unsigned	n_cc;
-	/*
-	 * Default queue is expected to be a low-priority queue.
-	 * This way, long transfers on the default queue started
-	 * by the codec engine will not cause audio defects.
-	 */
-	enum dma_event_q	default_queue;
-
-	/* Resource reservation for other cores */
-	struct edma_rsv_info	*rsv;
-
-	const s8	(*queue_tc_mapping)[2];
-	const s8	(*queue_priority_mapping)[2];
-};
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/tnetv107x.h linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/tnetv107x.h
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/include/mach/tnetv107x.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/include/mach/tnetv107x.h	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/serial_8250.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/mfd/ti_ssp.h>
+#include <linux/reboot.h>
 
 #include <linux/platform_data/mmc-davinci.h>
 #include <linux/platform_data/mtd-davinci.h>
@@ -51,10 +52,10 @@ struct tnetv107x_device_info {
 extern struct platform_device tnetv107x_wdt_device;
 extern struct platform_device tnetv107x_serial_device;
 
-extern void __init tnetv107x_init(void);
-extern void __init tnetv107x_devices_init(struct tnetv107x_device_info *);
-extern void __init tnetv107x_irq_init(void);
-void tnetv107x_restart(char mode, const char *cmd);
+extern void tnetv107x_init(void);
+extern void tnetv107x_devices_init(struct tnetv107x_device_info *);
+extern void tnetv107x_irq_init(void);
+void tnetv107x_restart(enum reboot_mode mode, const char *cmd);
 
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -40,6 +40,7 @@ config ARCH_DAVINCI_DA850
 	bool "DA850/OMAP-L138/AM18x based system"
 	select ARCH_DAVINCI_DA8XX
 	select ARCH_HAS_CPUFREQ
+	select CPU_FREQ_TABLE
 	select CP_INTC
 
 config ARCH_DAVINCI_DA8XX
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,7 @@
 
 # Common objects
 obj-y 			:= time.o clock.o serial.o psc.o \
-			   dma.o usb.o common.o sram.o aemif.o
+			   usb.o common.o sram.o aemif.o
 
 obj-$(CONFIG_DAVINCI_MUX)		+= mux.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/time.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/time.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,8 +18,8 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/sched_clock.h>
 
-#include <asm/sched_clock.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-davinci/tnetv107x.c linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/tnetv107x.c
--- linux-libre-3.10-gnu/arch/arm/mach-davinci/tnetv107x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-davinci/tnetv107x.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 
 #include <asm/mach/map.h>
 
@@ -730,7 +731,7 @@ static void tnetv107x_watchdog_reset(str
 	__raw_writel(1, &regs->kick);
 }
 
-void tnetv107x_restart(char mode, const char *cmd)
+void tnetv107x_restart(enum reboot_mode mode, const char *cmd)
 {
 	tnetv107x_watchdog_reset(&tnetv107x_wdt_device);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-dove/board-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/board-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-dove/board-dt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/board-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,6 @@
 
 #include <linux/init.h>
 #include <linux/clk-provider.h>
-#include <linux/clk/mvebu.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/platform_data/usb-ehci-orion.h>
@@ -49,7 +48,7 @@ static void __init dove_legacy_clk_init(
 
 static void __init dove_of_clk_init(void)
 {
-	mvebu_clocks_init();
+	of_clk_init(NULL);
 	dove_legacy_clk_init();
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-dove/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-dove/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,6 @@
  */
 
 #include <linux/clk-provider.h>
-#include <linux/clk/mvebu.h>
 #include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/of.h>
@@ -382,7 +381,7 @@ void __init dove_init(void)
 	dove_xor1_init();
 }
 
-void dove_restart(char mode, const char *cmd)
+void dove_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * Enable soft reset to assert RSTOUTn.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-dove/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-dove/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,8 @@
 #ifndef __ARCH_DOVE_COMMON_H
 #define __ARCH_DOVE_COMMON_H
 
+#include <linux/reboot.h>
+
 struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
 
@@ -42,6 +44,6 @@ void dove_spi1_init(void);
 void dove_i2c_init(void);
 void dove_sdio0_init(void);
 void dove_sdio1_init(void);
-void dove_restart(char, const char *);
+void dove_restart(enum reboot_mode, const char *);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-dove/include/mach/bridge-regs.h linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/include/mach/bridge-regs.h
--- linux-libre-3.10-gnu/arch/arm/mach-dove/include/mach/bridge-regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/include/mach/bridge-regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,7 @@
 #define SYSTEM_SOFT_RESET	(BRIDGE_VIRT_BASE + 0x010c)
 #define  SOFT_RESET		0x00000001
 
+#define BRIDGE_CAUSE		(BRIDGE_VIRT_BASE + 0x0110)
 #define  BRIDGE_INT_TIMER1_CLR	(~0x0004)
 
 #define IRQ_VIRT_BASE		(BRIDGE_VIRT_BASE + 0x0200)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-dove/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-dove/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-dove/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,8 +22,7 @@ config MACH_CM_A510
 
 config MACH_DOVE_DT
 	bool "Marvell Dove Flattened Device Tree"
-	select MVEBU_CLK_CORE
-	select MVEBU_CLK_GATING
+	select DOVE_CLK
 	select REGULATOR
 	select REGULATOR_FIXED_VOLTAGE
 	select USE_OF
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ebsa110/core.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ebsa110/core.c
--- linux-libre-3.10-gnu/arch/arm/mach-ebsa110/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ebsa110/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,7 +116,7 @@ static void __init ebsa110_map_io(void)
 	iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc));
 }
 
-static void __iomem *ebsa110_ioremap_caller(unsigned long cookie, size_t size,
+static void __iomem *ebsa110_ioremap_caller(phys_addr_t cookie, size_t size,
 					    unsigned int flags, void *caller)
 {
 	return (void __iomem *)cookie;
@@ -311,7 +311,7 @@ static int __init ebsa110_init(void)
 
 arch_initcall(ebsa110_init);
 
-static void ebsa110_restart(char mode, const char *cmd)
+static void ebsa110_restart(enum reboot_mode mode, const char *cmd)
 {
 	soft_restart(0x80000000);
 }
@@ -321,7 +321,6 @@ MACHINE_START(EBSA110, "EBSA110")
 	.atag_offset	= 0x400,
 	.reserve_lp0	= 1,
 	.reserve_lp2	= 1,
-	.restart_mode	= 's',
 	.map_io		= ebsa110_map_io,
 	.init_early	= ebsa110_init_early,
 	.init_irq	= ebsa110_init_irq,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ep93xx/core.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ep93xx/core.c
--- linux-libre-3.10-gnu/arch/arm/mach-ep93xx/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ep93xx/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/spi/spi.h>
 #include <linux/export.h>
 #include <linux/irqchip/arm-vic.h>
+#include <linux/reboot.h>
 
 #include <mach/hardware.h>
 #include <linux/platform_data/video-ep93xx.h>
@@ -921,7 +922,7 @@ void __init ep93xx_init_devices(void)
 	gpio_led_register_device(-1, &ep93xx_led_data);
 }
 
-void ep93xx_restart(char mode, const char *cmd)
+void ep93xx_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * Set then clear the SWRST bit to initiate a software reset
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ep93xx/include/mach/platform.h linux-libre-3.11-rc7-gnu/arch/arm/mach-ep93xx/include/mach/platform.h
--- linux-libre-3.10-gnu/arch/arm/mach-ep93xx/include/mach/platform.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ep93xx/include/mach/platform.h	2013-08-25 20:43:22.000000000 -0400
@@ -4,6 +4,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/reboot.h>
+
 struct i2c_gpio_platform_data;
 struct i2c_board_info;
 struct spi_board_info;
@@ -55,7 +57,7 @@ void ep93xx_ide_release_gpio(struct plat
 void ep93xx_init_devices(void);
 extern void ep93xx_timer_init(void);
 
-void ep93xx_restart(char, const char *);
+void ep93xx_restart(enum reboot_mode, const char *);
 void ep93xx_init_late(void);
 
 #ifdef CONFIG_CRUNCH
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,20 +40,9 @@
 
 #include <mach/regs-irq.h>
 #include <mach/regs-pmu.h>
-#include <mach/regs-gpio.h>
-#include <mach/irqs.h>
 
 #include <plat/cpu.h>
-#include <plat/devs.h>
 #include <plat/pm.h>
-#include <plat/sdhci.h>
-#include <plat/gpio-cfg.h>
-#include <plat/adc-core.h>
-#include <plat/fb-core.h>
-#include <plat/fimc-core.h>
-#include <plat/iic-core.h>
-#include <plat/tv-core.h>
-#include <plat/spi-core.h>
 #include <plat/regs-serial.h>
 
 #include "common.h"
@@ -64,36 +53,30 @@ static const char name_exynos4210[] = "E
 static const char name_exynos4212[] = "EXYNOS4212";
 static const char name_exynos4412[] = "EXYNOS4412";
 static const char name_exynos5250[] = "EXYNOS5250";
+static const char name_exynos5420[] = "EXYNOS5420";
 static const char name_exynos5440[] = "EXYNOS5440";
 
 static void exynos4_map_io(void);
 static void exynos5_map_io(void);
-static void exynos5440_map_io(void);
-static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 static int exynos_init(void);
 
-unsigned long xxti_f = 0, xusbxti_f = 0;
-
 static struct cpu_table cpu_ids[] __initdata = {
 	{
 		.idcode		= EXYNOS4210_CPU_ID,
 		.idmask		= EXYNOS4_CPU_MASK,
 		.map_io		= exynos4_map_io,
-		.init_uarts	= exynos4_init_uarts,
 		.init		= exynos_init,
 		.name		= name_exynos4210,
 	}, {
 		.idcode		= EXYNOS4212_CPU_ID,
 		.idmask		= EXYNOS4_CPU_MASK,
 		.map_io		= exynos4_map_io,
-		.init_uarts	= exynos4_init_uarts,
 		.init		= exynos_init,
 		.name		= name_exynos4212,
 	}, {
 		.idcode		= EXYNOS4412_CPU_ID,
 		.idmask		= EXYNOS4_CPU_MASK,
 		.map_io		= exynos4_map_io,
-		.init_uarts	= exynos4_init_uarts,
 		.init		= exynos_init,
 		.name		= name_exynos4412,
 	}, {
@@ -103,9 +86,14 @@ static struct cpu_table cpu_ids[] __init
 		.init		= exynos_init,
 		.name		= name_exynos5250,
 	}, {
+		.idcode		= EXYNOS5420_SOC_ID,
+		.idmask		= EXYNOS5_SOC_MASK,
+		.map_io		= exynos5_map_io,
+		.init		= exynos_init,
+		.name		= name_exynos5420,
+	}, {
 		.idcode		= EXYNOS5440_SOC_ID,
 		.idmask		= EXYNOS5_SOC_MASK,
-		.map_io		= exynos5440_map_io,
 		.init		= exynos_init,
 		.name		= name_exynos5440,
 	},
@@ -113,15 +101,6 @@ static struct cpu_table cpu_ids[] __init
 
 /* Initial IO mappings */
 
-static struct map_desc exynos_iodesc[] __initdata = {
-	{
-		.virtual	= (unsigned long)S5P_VA_CHIPID,
-		.pfn		= __phys_to_pfn(EXYNOS_PA_CHIPID),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE,
-	},
-};
-
 static struct map_desc exynos4_iodesc[] __initdata = {
 	{
 		.virtual	= (unsigned long)S3C_VA_SYS,
@@ -169,11 +148,6 @@ static struct map_desc exynos4_iodesc[]
 		.length		= SZ_64K,
 		.type		= MT_DEVICE,
 	}, {
-		.virtual	= (unsigned long)S3C_VA_UART,
-		.pfn		= __phys_to_pfn(EXYNOS4_PA_UART),
-		.length		= SZ_512K,
-		.type		= MT_DEVICE,
-	}, {
 		.virtual	= (unsigned long)S5P_VA_CMU,
 		.pfn		= __phys_to_pfn(EXYNOS4_PA_CMU),
 		.length		= SZ_128K,
@@ -287,45 +261,24 @@ static struct map_desc exynos5_iodesc[]
 		.pfn		= __phys_to_pfn(EXYNOS5_PA_PMU),
 		.length		= SZ_64K,
 		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)S3C_VA_UART,
-		.pfn		= __phys_to_pfn(EXYNOS5_PA_UART),
-		.length		= SZ_512K,
-		.type		= MT_DEVICE,
 	},
 };
 
-static struct map_desc exynos5440_iodesc0[] __initdata = {
-	{
-		.virtual	= (unsigned long)S3C_VA_UART,
-		.pfn		= __phys_to_pfn(EXYNOS5440_PA_UART0),
-		.length		= SZ_512K,
-		.type		= MT_DEVICE,
-	},
-};
-
-static struct samsung_pwm_variant exynos4_pwm_variant = {
-	.bits		= 32,
-	.div_base	= 0,
-	.has_tint_cstat	= true,
-	.tclk_mask	= 0,
-};
-
-void exynos4_restart(char mode, const char *cmd)
+void exynos4_restart(enum reboot_mode mode, const char *cmd)
 {
 	__raw_writel(0x1, S5P_SWRESET);
 }
 
-void exynos5_restart(char mode, const char *cmd)
+void exynos5_restart(enum reboot_mode mode, const char *cmd)
 {
 	struct device_node *np;
 	u32 val;
 	void __iomem *addr;
 
-	if (of_machine_is_compatible("samsung,exynos5250")) {
-		val = 0x1;
-		addr = EXYNOS_SWRESET;
-	} else if (of_machine_is_compatible("samsung,exynos5440")) {
+	val = 0x1;
+	addr = EXYNOS_SWRESET;
+
+	if (of_machine_is_compatible("samsung,exynos5440")) {
 		u32 status;
 		np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
 
@@ -336,9 +289,6 @@ void exynos5_restart(char mode, const ch
 		val = __raw_readl(addr);
 
 		val = (val & 0xffff0000) | (status & 0xffff);
-	} else {
-		pr_err("%s: cannot support non-DT\n", __func__);
-		return;
 	}
 
 	__raw_writel(val, addr);
@@ -353,8 +303,7 @@ void __init exynos_init_late(void)
 	exynos_pm_late_initcall();
 }
 
-#ifdef CONFIG_OF
-int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
+static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
 					int depth, void *data)
 {
 	struct map_desc iodesc;
@@ -376,7 +325,6 @@ int __init exynos_fdt_map_chipid(unsigne
 	iotable_init(&iodesc, 1);
 	return 1;
 }
-#endif
 
 /*
  * exynos_map_io
@@ -384,19 +332,11 @@ int __init exynos_fdt_map_chipid(unsigne
  * register the standard cpu IO areas
  */
 
-void __init exynos_init_io(struct map_desc *mach_desc, int size)
+void __init exynos_init_io(void)
 {
 	debug_ll_io_init();
 
-#ifdef CONFIG_OF
-	if (initial_boot_params)
-		of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
-	else
-#endif
-		iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc));
-
-	if (mach_desc)
-		iotable_init(mach_desc, size);
+	of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
 
 	/* detect cpu id and rev. */
 	s5p_init_cpu(S5P_VA_CHIPID);
@@ -417,34 +357,6 @@ static void __init exynos4_map_io(void)
 		iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
 	if (soc_is_exynos4212() || soc_is_exynos4412())
 		iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
-
-	/* initialize device information early */
-	exynos4_default_sdhci0();
-	exynos4_default_sdhci1();
-	exynos4_default_sdhci2();
-	exynos4_default_sdhci3();
-
-	s3c_adc_setname("samsung-adc-v3");
-
-	s3c_fimc_setname(0, "exynos4-fimc");
-	s3c_fimc_setname(1, "exynos4-fimc");
-	s3c_fimc_setname(2, "exynos4-fimc");
-	s3c_fimc_setname(3, "exynos4-fimc");
-
-	s3c_sdhci_setname(0, "exynos4-sdhci");
-	s3c_sdhci_setname(1, "exynos4-sdhci");
-	s3c_sdhci_setname(2, "exynos4-sdhci");
-	s3c_sdhci_setname(3, "exynos4-sdhci");
-
-	/* The I2C bus controllers are directly compatible with s3c2440 */
-	s3c_i2c0_setname("s3c2440-i2c");
-	s3c_i2c1_setname("s3c2440-i2c");
-	s3c_i2c2_setname("s3c2440-i2c");
-
-	s5p_fb_setname(0, "exynos4-fb");
-	s5p_hdmi_setname("exynos4-hdmi");
-
-	s3c64xx_spi_setname("exynos4210-spi");
 }
 
 static void __init exynos5_map_io(void)
@@ -455,86 +367,10 @@ static void __init exynos5_map_io(void)
 		iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
 }
 
-static void __init exynos5440_map_io(void)
-{
-	iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0));
-}
-
-void __init exynos_set_timer_source(u8 channels)
-{
-	exynos4_pwm_variant.output_mask = BIT(SAMSUNG_PWM_NUM) - 1;
-	exynos4_pwm_variant.output_mask &= ~channels;
-}
-
 void __init exynos_init_time(void)
 {
-	unsigned int timer_irqs[SAMSUNG_PWM_NUM] = {
-		EXYNOS4_IRQ_TIMER0_VIC, EXYNOS4_IRQ_TIMER1_VIC,
-		EXYNOS4_IRQ_TIMER2_VIC, EXYNOS4_IRQ_TIMER3_VIC,
-		EXYNOS4_IRQ_TIMER4_VIC,
-	};
-
-	if (of_have_populated_dt()) {
-#ifdef CONFIG_OF
-		of_clk_init(NULL);
-		clocksource_of_init();
-#endif
-	} else {
-		/* todo: remove after migrating legacy E4 platforms to dt */
-#ifdef CONFIG_ARCH_EXYNOS4
-		exynos4_clk_init(NULL, !soc_is_exynos4210(), S5P_VA_CMU, readl(S5P_VA_CHIPID + 8) & 1);
-		exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
-#endif
-#ifdef CONFIG_CLKSRC_SAMSUNG_PWM
-		if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
-			samsung_pwm_clocksource_init(S3C_VA_TIMER,
-					timer_irqs, &exynos4_pwm_variant);
-		else
-#endif
-			mct_init(S5P_VA_SYSTIMER, EXYNOS4_IRQ_MCT_G0,
-					EXYNOS4_IRQ_MCT_L0, EXYNOS4_IRQ_MCT_L1);
-	}
-}
-
-static unsigned int max_combiner_nr(void)
-{
-	if (soc_is_exynos5250())
-		return EXYNOS5_MAX_COMBINER_NR;
-	else if (soc_is_exynos4412())
-		return EXYNOS4412_MAX_COMBINER_NR;
-	else if (soc_is_exynos4212())
-		return EXYNOS4212_MAX_COMBINER_NR;
-	else
-		return EXYNOS4210_MAX_COMBINER_NR;
-}
-
-
-void __init exynos4_init_irq(void)
-{
-	unsigned int gic_bank_offset;
-
-	gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
-
-	if (!of_have_populated_dt())
-		gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
-#ifdef CONFIG_OF
-	else
-		irqchip_init();
-#endif
-
-	if (!of_have_populated_dt())
-		combiner_init(S5P_VA_COMBINER_BASE, NULL,
-			      max_combiner_nr(), COMBINER_IRQ(0, 0));
-
-	gic_arch_extn.irq_set_wake = s3c_irq_wake;
-}
-
-void __init exynos5_init_irq(void)
-{
-#ifdef CONFIG_OF
-	irqchip_init();
-#endif
-	gic_arch_extn.irq_set_wake = s3c_irq_wake;
+	of_clk_init(NULL);
+	clocksource_of_init();
 }
 
 struct bus_type exynos_subsys = {
@@ -552,59 +388,19 @@ static int __init exynos_core_init(void)
 }
 core_initcall(exynos_core_init);
 
-#ifdef CONFIG_CACHE_L2X0
 static int __init exynos4_l2x0_cache_init(void)
 {
 	int ret;
 
-	if (soc_is_exynos5250() || soc_is_exynos5440())
-		return 0;
-
 	ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
-	if (!ret) {
-		l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
-		clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
-		return 0;
-	}
-
-	if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) {
-		l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC;
-		/* TAG, Data Latency Control: 2 cycles */
-		l2x0_saved_regs.tag_latency = 0x110;
-
-		if (soc_is_exynos4212() || soc_is_exynos4412())
-			l2x0_saved_regs.data_latency = 0x120;
-		else
-			l2x0_saved_regs.data_latency = 0x110;
-
-		l2x0_saved_regs.prefetch_ctrl = 0x30000007;
-		l2x0_saved_regs.pwr_ctrl =
-			(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN);
-
-		l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
-
-		__raw_writel(l2x0_saved_regs.tag_latency,
-				S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
-		__raw_writel(l2x0_saved_regs.data_latency,
-				S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
-
-		/* L2X0 Prefetch Control */
-		__raw_writel(l2x0_saved_regs.prefetch_ctrl,
-				S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
-
-		/* L2X0 Power Control */
-		__raw_writel(l2x0_saved_regs.pwr_ctrl,
-				S5P_VA_L2CC + L2X0_POWER_CTRL);
-
-		clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
-		clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs));
-	}
+	if (ret)
+		return ret;
 
-	l2x0_init(S5P_VA_L2CC, L2_AUX_VAL, L2_AUX_MASK);
+	l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
+	clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
 	return 0;
 }
 early_initcall(exynos4_l2x0_cache_init);
-#endif
 
 static int __init exynos_init(void)
 {
@@ -612,350 +408,3 @@ static int __init exynos_init(void)
 
 	return device_register(&exynos4_dev);
 }
-
-/* uart registration process */
-
-static void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
-{
-	struct s3c2410_uartcfg *tcfg = cfg;
-	u32 ucnt;
-
-	for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
-		tcfg->has_fracval = 1;
-
-	s3c24xx_init_uartdevs("exynos4210-uart", exynos4_uart_resources, cfg, no);
-}
-
-static void __iomem *exynos_eint_base;
-
-static DEFINE_SPINLOCK(eint_lock);
-
-static unsigned int eint0_15_data[16];
-
-static inline int exynos4_irq_to_gpio(unsigned int irq)
-{
-	if (irq < IRQ_EINT(0))
-		return -EINVAL;
-
-	irq -= IRQ_EINT(0);
-	if (irq < 8)
-		return EXYNOS4_GPX0(irq);
-
-	irq -= 8;
-	if (irq < 8)
-		return EXYNOS4_GPX1(irq);
-
-	irq -= 8;
-	if (irq < 8)
-		return EXYNOS4_GPX2(irq);
-
-	irq -= 8;
-	if (irq < 8)
-		return EXYNOS4_GPX3(irq);
-
-	return -EINVAL;
-}
-
-static inline int exynos5_irq_to_gpio(unsigned int irq)
-{
-	if (irq < IRQ_EINT(0))
-		return -EINVAL;
-
-	irq -= IRQ_EINT(0);
-	if (irq < 8)
-		return EXYNOS5_GPX0(irq);
-
-	irq -= 8;
-	if (irq < 8)
-		return EXYNOS5_GPX1(irq);
-
-	irq -= 8;
-	if (irq < 8)
-		return EXYNOS5_GPX2(irq);
-
-	irq -= 8;
-	if (irq < 8)
-		return EXYNOS5_GPX3(irq);
-
-	return -EINVAL;
-}
-
-static unsigned int exynos4_eint0_15_src_int[16] = {
-	EXYNOS4_IRQ_EINT0,
-	EXYNOS4_IRQ_EINT1,
-	EXYNOS4_IRQ_EINT2,
-	EXYNOS4_IRQ_EINT3,
-	EXYNOS4_IRQ_EINT4,
-	EXYNOS4_IRQ_EINT5,
-	EXYNOS4_IRQ_EINT6,
-	EXYNOS4_IRQ_EINT7,
-	EXYNOS4_IRQ_EINT8,
-	EXYNOS4_IRQ_EINT9,
-	EXYNOS4_IRQ_EINT10,
-	EXYNOS4_IRQ_EINT11,
-	EXYNOS4_IRQ_EINT12,
-	EXYNOS4_IRQ_EINT13,
-	EXYNOS4_IRQ_EINT14,
-	EXYNOS4_IRQ_EINT15,
-};
-
-static unsigned int exynos5_eint0_15_src_int[16] = {
-	EXYNOS5_IRQ_EINT0,
-	EXYNOS5_IRQ_EINT1,
-	EXYNOS5_IRQ_EINT2,
-	EXYNOS5_IRQ_EINT3,
-	EXYNOS5_IRQ_EINT4,
-	EXYNOS5_IRQ_EINT5,
-	EXYNOS5_IRQ_EINT6,
-	EXYNOS5_IRQ_EINT7,
-	EXYNOS5_IRQ_EINT8,
-	EXYNOS5_IRQ_EINT9,
-	EXYNOS5_IRQ_EINT10,
-	EXYNOS5_IRQ_EINT11,
-	EXYNOS5_IRQ_EINT12,
-	EXYNOS5_IRQ_EINT13,
-	EXYNOS5_IRQ_EINT14,
-	EXYNOS5_IRQ_EINT15,
-};
-static inline void exynos_irq_eint_mask(struct irq_data *data)
-{
-	u32 mask;
-
-	spin_lock(&eint_lock);
-	mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq));
-	mask |= EINT_OFFSET_BIT(data->irq);
-	__raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq));
-	spin_unlock(&eint_lock);
-}
-
-static void exynos_irq_eint_unmask(struct irq_data *data)
-{
-	u32 mask;
-
-	spin_lock(&eint_lock);
-	mask = __raw_readl(EINT_MASK(exynos_eint_base, data->irq));
-	mask &= ~(EINT_OFFSET_BIT(data->irq));
-	__raw_writel(mask, EINT_MASK(exynos_eint_base, data->irq));
-	spin_unlock(&eint_lock);
-}
-
-static inline void exynos_irq_eint_ack(struct irq_data *data)
-{
-	__raw_writel(EINT_OFFSET_BIT(data->irq),
-		     EINT_PEND(exynos_eint_base, data->irq));
-}
-
-static void exynos_irq_eint_maskack(struct irq_data *data)
-{
-	exynos_irq_eint_mask(data);
-	exynos_irq_eint_ack(data);
-}
-
-static int exynos_irq_eint_set_type(struct irq_data *data, unsigned int type)
-{
-	int offs = EINT_OFFSET(data->irq);
-	int shift;
-	u32 ctrl, mask;
-	u32 newvalue = 0;
-
-	switch (type) {
-	case IRQ_TYPE_EDGE_RISING:
-		newvalue = S5P_IRQ_TYPE_EDGE_RISING;
-		break;
-
-	case IRQ_TYPE_EDGE_FALLING:
-		newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
-		break;
-
-	case IRQ_TYPE_EDGE_BOTH:
-		newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
-		break;
-
-	case IRQ_TYPE_LEVEL_LOW:
-		newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
-		break;
-
-	case IRQ_TYPE_LEVEL_HIGH:
-		newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
-		break;
-
-	default:
-		printk(KERN_ERR "No such irq type %d", type);
-		return -EINVAL;
-	}
-
-	shift = (offs & 0x7) * 4;
-	mask = 0x7 << shift;
-
-	spin_lock(&eint_lock);
-	ctrl = __raw_readl(EINT_CON(exynos_eint_base, data->irq));
-	ctrl &= ~mask;
-	ctrl |= newvalue << shift;
-	__raw_writel(ctrl, EINT_CON(exynos_eint_base, data->irq));
-	spin_unlock(&eint_lock);
-
-	if (soc_is_exynos5250())
-		s3c_gpio_cfgpin(exynos5_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf));
-	else
-		s3c_gpio_cfgpin(exynos4_irq_to_gpio(data->irq), S3C_GPIO_SFN(0xf));
-
-	return 0;
-}
-
-static struct irq_chip exynos_irq_eint = {
-	.name		= "exynos-eint",
-	.irq_mask	= exynos_irq_eint_mask,
-	.irq_unmask	= exynos_irq_eint_unmask,
-	.irq_mask_ack	= exynos_irq_eint_maskack,
-	.irq_ack	= exynos_irq_eint_ack,
-	.irq_set_type	= exynos_irq_eint_set_type,
-#ifdef CONFIG_PM
-	.irq_set_wake	= s3c_irqext_wake,
-#endif
-};
-
-/*
- * exynos4_irq_demux_eint
- *
- * This function demuxes the IRQ from from EINTs 16 to 31.
- * It is designed to be inlined into the specific handler
- * s5p_irq_demux_eintX_Y.
- *
- * Each EINT pend/mask registers handle eight of them.
- */
-static inline void exynos_irq_demux_eint(unsigned int start)
-{
-	unsigned int irq;
-
-	u32 status = __raw_readl(EINT_PEND(exynos_eint_base, start));
-	u32 mask = __raw_readl(EINT_MASK(exynos_eint_base, start));
-
-	status &= ~mask;
-	status &= 0xff;
-
-	while (status) {
-		irq = fls(status) - 1;
-		generic_handle_irq(irq + start);
-		status &= ~(1 << irq);
-	}
-}
-
-static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
-{
-	struct irq_chip *chip = irq_get_chip(irq);
-	chained_irq_enter(chip, desc);
-	exynos_irq_demux_eint(IRQ_EINT(16));
-	exynos_irq_demux_eint(IRQ_EINT(24));
-	chained_irq_exit(chip, desc);
-}
-
-static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
-{
-	u32 *irq_data = irq_get_handler_data(irq);
-	struct irq_chip *chip = irq_get_chip(irq);
-
-	chained_irq_enter(chip, desc);
-	generic_handle_irq(*irq_data);
-	chained_irq_exit(chip, desc);
-}
-
-static int __init exynos_init_irq_eint(void)
-{
-	int irq;
-
-#ifdef CONFIG_PINCTRL_SAMSUNG
-	/*
-	 * The Samsung pinctrl driver provides an integrated gpio/pinmux/pinconf
-	 * functionality along with support for external gpio and wakeup
-	 * interrupts. If the samsung pinctrl driver is enabled and includes
-	 * the wakeup interrupt support, then the setting up external wakeup
-	 * interrupts here can be skipped. This check here is temporary to
-	 * allow exynos4 platforms that do not use Samsung pinctrl driver to
-	 * co-exist with platforms that do. When all of the Samsung Exynos4
-	 * platforms switch over to using the pinctrl driver, the wakeup
-	 * interrupt support code here can be completely removed.
-	 */
-	static const struct of_device_id exynos_pinctrl_ids[] = {
-		{ .compatible = "samsung,exynos4210-pinctrl", },
-		{ .compatible = "samsung,exynos4x12-pinctrl", },
-		{ .compatible = "samsung,exynos5250-pinctrl", },
-	};
-	struct device_node *pctrl_np, *wkup_np;
-	const char *wkup_compat = "samsung,exynos4210-wakeup-eint";
-
-	for_each_matching_node(pctrl_np, exynos_pinctrl_ids) {
-		if (of_device_is_available(pctrl_np)) {
-			wkup_np = of_find_compatible_node(pctrl_np, NULL,
-							wkup_compat);
-			if (wkup_np)
-				return -ENODEV;
-		}
-	}
-#endif
-	if (soc_is_exynos5440())
-		return 0;
-
-	if (soc_is_exynos5250())
-		exynos_eint_base = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
-	else
-		exynos_eint_base = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
-
-	if (exynos_eint_base == NULL) {
-		pr_err("unable to ioremap for EINT base address\n");
-		return -ENOMEM;
-	}
-
-	for (irq = 0 ; irq <= 31 ; irq++) {
-		irq_set_chip_and_handler(IRQ_EINT(irq), &exynos_irq_eint,
-					 handle_level_irq);
-		set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
-	}
-
-	irq_set_chained_handler(EXYNOS_IRQ_EINT16_31, exynos_irq_demux_eint16_31);
-
-	for (irq = 0 ; irq <= 15 ; irq++) {
-		eint0_15_data[irq] = IRQ_EINT(irq);
-
-		if (soc_is_exynos5250()) {
-			irq_set_handler_data(exynos5_eint0_15_src_int[irq],
-					     &eint0_15_data[irq]);
-			irq_set_chained_handler(exynos5_eint0_15_src_int[irq],
-						exynos_irq_eint0_15);
-		} else {
-			irq_set_handler_data(exynos4_eint0_15_src_int[irq],
-					     &eint0_15_data[irq]);
-			irq_set_chained_handler(exynos4_eint0_15_src_int[irq],
-						exynos_irq_eint0_15);
-		}
-	}
-
-	return 0;
-}
-arch_initcall(exynos_init_irq_eint);
-
-static struct resource exynos4_pmu_resource[] = {
-	DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU),
-	DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU1),
-#if defined(CONFIG_SOC_EXYNOS4412)
-	DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU2),
-	DEFINE_RES_IRQ(EXYNOS4_IRQ_PMU_CPU3),
-#endif
-};
-
-static struct platform_device exynos4_device_pmu = {
-	.name		= "arm-pmu",
-	.num_resources	= ARRAY_SIZE(exynos4_pmu_resource),
-	.resource	= exynos4_pmu_resource,
-};
-
-static int __init exynos_armpmu_init(void)
-{
-	if (!of_have_populated_dt()) {
-		if (soc_is_exynos4210() || soc_is_exynos4212())
-			exynos4_device_pmu.num_resources = 2;
-		platform_device_register(&exynos4_device_pmu);
-	}
-
-	return 0;
-}
-arch_initcall(exynos_armpmu_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,7 @@
 #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H
 #define __ARCH_ARM_MACH_EXYNOS_COMMON_H
 
+#include <linux/reboot.h>
 #include <linux/of.h>
 
 void mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1);
@@ -19,11 +20,9 @@ void exynos_init_time(void);
 extern unsigned long xxti_f, xusbxti_f;
 
 struct map_desc;
-void exynos_init_io(struct map_desc *mach_desc, int size);
-void exynos4_init_irq(void);
-void exynos5_init_irq(void);
-void exynos4_restart(char mode, const char *cmd);
-void exynos5_restart(char mode, const char *cmd);
+void exynos_init_io(void);
+void exynos4_restart(enum reboot_mode mode, const char *cmd);
+void exynos5_restart(enum reboot_mode mode, const char *cmd);
 void exynos_init_late(void);
 
 /* ToDo: remove these after migrating legacy exynos4 platforms to dt */
@@ -98,6 +97,5 @@ struct exynos_pmu_conf {
 };
 
 extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
-extern void s3c_cpu_resume(void);
 
 #endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/cpuidle.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/cpuidle.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/cpuidle.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/cpuidle.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,7 @@
 #include <mach/regs-pmu.h>
 
 #include <plat/cpu.h>
+#include <plat/pm.h>
 
 #include "common.h"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/dev-ahci.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dev-ahci.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/dev-ahci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dev-ahci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,255 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-ahci.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS4 - AHCI support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/ahci_platform.h>
-
-#include <plat/cpu.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-#include <mach/regs-pmu.h>
-
-/* PHY Control Register */
-#define SATA_CTRL0		0x0
-/* PHY Link Control Register */
-#define SATA_CTRL1		0x4
-/* PHY Status Register */
-#define SATA_PHY_STATUS		0x8
-
-#define SATA_CTRL0_RX_DATA_VALID(x)	(x << 27)
-#define SATA_CTRL0_SPEED_MODE		(1 << 26)
-#define SATA_CTRL0_M_PHY_CAL		(1 << 19)
-#define SATA_CTRL0_PHY_CMU_RST_N	(1 << 10)
-#define SATA_CTRL0_M_PHY_LN_RST_N	(1 << 9)
-#define SATA_CTRL0_PHY_POR_N		(1 << 8)
-
-#define SATA_CTRL1_RST_PMALIVE_N	(1 << 8)
-#define SATA_CTRL1_RST_RXOOB_N		(1 << 7)
-#define SATA_CTRL1_RST_RX_N		(1 << 6)
-#define SATA_CTRL1_RST_TX_N		(1 << 5)
-
-#define SATA_PHY_STATUS_CMU_OK		(1 << 18)
-#define SATA_PHY_STATUS_LANE_OK		(1 << 16)
-
-#define LANE0		0x200
-#define COM_LANE	0xA00
-
-#define HOST_PORTS_IMPL	0xC
-#define SCLK_SATA_FREQ	(67 * MHZ)
-
-static void __iomem *phy_base, *phy_ctrl;
-
-struct phy_reg {
-	u8	reg;
-	u8	val;
-};
-
-/* SATA PHY setup */
-static const struct phy_reg exynos4_sataphy_cmu[] = {
-	{ 0x00, 0x06 }, { 0x02, 0x80 }, { 0x22, 0xa0 }, { 0x23, 0x42 },
-	{ 0x2e, 0x04 }, { 0x2f, 0x50 }, { 0x30, 0x70 }, { 0x31, 0x02 },
-	{ 0x32, 0x25 }, { 0x33, 0x40 }, { 0x34, 0x01 }, { 0x35, 0x40 },
-	{ 0x61, 0x2e }, { 0x63, 0x5e }, { 0x65, 0x42 }, { 0x66, 0xd1 },
-	{ 0x67, 0x20 }, { 0x68, 0x28 }, { 0x69, 0x78 }, { 0x6a, 0x04 },
-	{ 0x6b, 0xc8 }, { 0x6c, 0x06 },
-};
-
-static const struct phy_reg exynos4_sataphy_lane[] = {
-	{ 0x00, 0x02 }, { 0x05, 0x10 }, { 0x06, 0x84 }, { 0x07, 0x04 },
-	{ 0x08, 0xe0 }, { 0x10, 0x23 }, { 0x13, 0x05 }, { 0x14, 0x30 },
-	{ 0x15, 0x00 }, { 0x17, 0x70 }, { 0x18, 0xf2 }, { 0x19, 0x1e },
-	{ 0x1a, 0x18 }, { 0x1b, 0x0d }, { 0x1c, 0x08 }, { 0x50, 0x60 },
-	{ 0x51, 0x0f },
-};
-
-static const struct phy_reg exynos4_sataphy_comlane[] = {
-	{ 0x01, 0x20 }, { 0x03, 0x40 }, { 0x04, 0x3c }, { 0x05, 0x7d },
-	{ 0x06, 0x1d }, { 0x07, 0xcf }, { 0x08, 0x05 }, { 0x09, 0x63 },
-	{ 0x0a, 0x29 }, { 0x0b, 0xc4 }, { 0x0c, 0x01 }, { 0x0d, 0x03 },
-	{ 0x0e, 0x28 }, { 0x0f, 0x98 }, { 0x10, 0x19 }, { 0x13, 0x80 },
-	{ 0x14, 0xf0 }, { 0x15, 0xd0 }, { 0x39, 0xa0 }, { 0x3a, 0xa0 },
-	{ 0x3b, 0xa0 }, { 0x3c, 0xa0 }, { 0x3d, 0xa0 }, { 0x3e, 0xa0 },
-	{ 0x3f, 0xa0 }, { 0x40, 0x42 }, { 0x42, 0x80 }, { 0x43, 0x58 },
-	{ 0x45, 0x44 }, { 0x46, 0x5c }, { 0x47, 0x86 }, { 0x48, 0x8d },
-	{ 0x49, 0xd0 }, { 0x4a, 0x09 }, { 0x4b, 0x90 }, { 0x4c, 0x07 },
-	{ 0x4d, 0x40 }, { 0x51, 0x20 }, { 0x52, 0x32 }, { 0x7f, 0xd8 },
-	{ 0x80, 0x1a }, { 0x81, 0xff }, { 0x82, 0x11 }, { 0x83, 0x00 },
-	{ 0x87, 0xf0 }, { 0x87, 0xff }, { 0x87, 0xff }, { 0x87, 0xff },
-	{ 0x87, 0xff }, { 0x8c, 0x1c }, { 0x8d, 0xc2 }, { 0x8e, 0xc3 },
-	{ 0x8f, 0x3f }, { 0x90, 0x0a }, { 0x96, 0xf8 },
-};
-
-static int wait_for_phy_ready(void __iomem *reg, unsigned long bit)
-{
-	unsigned long timeout;
-
-	/* wait for maximum of 3 sec */
-	timeout = jiffies + msecs_to_jiffies(3000);
-	while (!(__raw_readl(reg) & bit)) {
-		if (time_after(jiffies, timeout))
-			return -1;
-		cpu_relax();
-	}
-	return 0;
-}
-
-static int ahci_phy_init(void __iomem *mmio)
-{
-	int i, ctrl0;
-
-	for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_cmu); i++)
-		__raw_writeb(exynos4_sataphy_cmu[i].val,
-		phy_base + (exynos4_sataphy_cmu[i].reg * 4));
-
-	for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_lane); i++)
-		__raw_writeb(exynos4_sataphy_lane[i].val,
-		phy_base + (LANE0 + exynos4_sataphy_lane[i].reg) * 4);
-
-	for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_comlane); i++)
-		__raw_writeb(exynos4_sataphy_comlane[i].val,
-		phy_base + (COM_LANE + exynos4_sataphy_comlane[i].reg) * 4);
-
-	__raw_writeb(0x07, phy_base);
-
-	ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
-	ctrl0 |= SATA_CTRL0_PHY_CMU_RST_N;
-	__raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
-
-	if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
-				SATA_PHY_STATUS_CMU_OK) < 0) {
-		printk(KERN_ERR "PHY CMU not ready\n");
-		return -EBUSY;
-	}
-
-	__raw_writeb(0x03, phy_base + (COM_LANE * 4));
-
-	ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
-	ctrl0 |= SATA_CTRL0_M_PHY_LN_RST_N;
-	__raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
-
-	if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
-				SATA_PHY_STATUS_LANE_OK) < 0) {
-		printk(KERN_ERR "PHY LANE not ready\n");
-		return -EBUSY;
-	}
-
-	ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
-	ctrl0 |= SATA_CTRL0_M_PHY_CAL;
-	__raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
-
-	return 0;
-}
-
-static int exynos4_ahci_init(struct device *dev, void __iomem *mmio)
-{
-	struct clk *clk_sata, *clk_sataphy, *clk_sclk_sata;
-	int val, ret;
-
-	phy_base = ioremap(EXYNOS4_PA_SATAPHY, SZ_64K);
-	if (!phy_base) {
-		dev_err(dev, "failed to allocate memory for SATA PHY\n");
-		return -ENOMEM;
-	}
-
-	phy_ctrl = ioremap(EXYNOS4_PA_SATAPHY_CTRL, SZ_16);
-	if (!phy_ctrl) {
-		dev_err(dev, "failed to allocate memory for SATA PHY CTRL\n");
-		ret = -ENOMEM;
-		goto err1;
-	}
-
-	clk_sata = clk_get(dev, "sata");
-	if (IS_ERR(clk_sata)) {
-		dev_err(dev, "failed to get sata clock\n");
-		ret = PTR_ERR(clk_sata);
-		clk_sata = NULL;
-		goto err2;
-
-	}
-	clk_enable(clk_sata);
-
-	clk_sataphy = clk_get(dev, "sataphy");
-	if (IS_ERR(clk_sataphy)) {
-		dev_err(dev, "failed to get sataphy clock\n");
-		ret = PTR_ERR(clk_sataphy);
-		clk_sataphy = NULL;
-		goto err3;
-	}
-	clk_enable(clk_sataphy);
-
-	clk_sclk_sata = clk_get(dev, "sclk_sata");
-	if (IS_ERR(clk_sclk_sata)) {
-		dev_err(dev, "failed to get sclk_sata\n");
-		ret = PTR_ERR(clk_sclk_sata);
-		clk_sclk_sata = NULL;
-		goto err4;
-	}
-	clk_enable(clk_sclk_sata);
-	clk_set_rate(clk_sclk_sata, SCLK_SATA_FREQ);
-
-	__raw_writel(S5P_PMU_SATA_PHY_CONTROL_EN, S5P_PMU_SATA_PHY_CONTROL);
-
-	/* Enable PHY link control */
-	val = SATA_CTRL1_RST_PMALIVE_N | SATA_CTRL1_RST_RXOOB_N |
-			SATA_CTRL1_RST_RX_N | SATA_CTRL1_RST_TX_N;
-	__raw_writel(val, phy_ctrl + SATA_CTRL1);
-
-	/* Set communication speed as 3Gbps and enable PHY power */
-	val = SATA_CTRL0_RX_DATA_VALID(3) | SATA_CTRL0_SPEED_MODE |
-			SATA_CTRL0_PHY_POR_N;
-	__raw_writel(val, phy_ctrl + SATA_CTRL0);
-
-	/* Port0 is available */
-	__raw_writel(0x1, mmio + HOST_PORTS_IMPL);
-
-	return ahci_phy_init(mmio);
-
-err4:
-	clk_disable(clk_sataphy);
-	clk_put(clk_sataphy);
-err3:
-	clk_disable(clk_sata);
-	clk_put(clk_sata);
-err2:
-	iounmap(phy_ctrl);
-err1:
-	iounmap(phy_base);
-
-	return ret;
-}
-
-static struct ahci_platform_data exynos4_ahci_pdata = {
-	.init = exynos4_ahci_init,
-};
-
-static struct resource exynos4_ahci_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_SATA, SZ_64K),
-	[1] = DEFINE_RES_IRQ(EXYNOS4_IRQ_SATA),
-};
-
-static u64 exynos4_ahci_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_ahci = {
-	.name		= "ahci",
-	.id		= -1,
-	.resource	= exynos4_ahci_resource,
-	.num_resources	= ARRAY_SIZE(exynos4_ahci_resource),
-	.dev		= {
-		.platform_data		= &exynos4_ahci_pdata,
-		.dma_mask		= &exynos4_ahci_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/dev-audio.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dev-audio.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/dev-audio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dev-audio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,254 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-audio.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- *	Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <linux/platform_data/asoc-s3c.h>
-
-#include <plat/gpio-cfg.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-#include <mach/irqs.h>
-
-#define EXYNOS4_AUDSS_INT_MEM	(0x03000000)
-
-static int exynos4_cfg_i2s(struct platform_device *pdev)
-{
-	/* configure GPIO for i2s port */
-	switch (pdev->id) {
-	case 0:
-		s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 7, S3C_GPIO_SFN(2));
-		break;
-	case 1:
-		s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(2));
-		break;
-	case 2:
-		s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(4));
-		break;
-	default:
-		printk(KERN_ERR "Invalid Device %d\n", pdev->id);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static struct s3c_audio_pdata i2sv5_pdata = {
-	.cfg_gpio = exynos4_cfg_i2s,
-	.type = {
-		.i2s = {
-			.quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
-					 | QUIRK_NEED_RSTCLR,
-			.idma_addr = EXYNOS4_AUDSS_INT_MEM,
-		},
-	},
-};
-
-static struct resource exynos4_i2s0_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_I2S0, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_I2S0_TX),
-	[2] = DEFINE_RES_DMA(DMACH_I2S0_RX),
-	[3] = DEFINE_RES_DMA(DMACH_I2S0S_TX),
-};
-
-struct platform_device exynos4_device_i2s0 = {
-	.name = "samsung-i2s",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(exynos4_i2s0_resource),
-	.resource = exynos4_i2s0_resource,
-	.dev = {
-		.platform_data = &i2sv5_pdata,
-	},
-};
-
-static struct s3c_audio_pdata i2sv3_pdata = {
-	.cfg_gpio = exynos4_cfg_i2s,
-	.type = {
-		.i2s = {
-			.quirks = QUIRK_NO_MUXPSR,
-		},
-	},
-};
-
-static struct resource exynos4_i2s1_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_I2S1, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_I2S1_TX),
-	[2] = DEFINE_RES_DMA(DMACH_I2S1_RX),
-};
-
-struct platform_device exynos4_device_i2s1 = {
-	.name = "samsung-i2s",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(exynos4_i2s1_resource),
-	.resource = exynos4_i2s1_resource,
-	.dev = {
-		.platform_data = &i2sv3_pdata,
-	},
-};
-
-static struct resource exynos4_i2s2_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_I2S2, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_I2S2_TX),
-	[2] = DEFINE_RES_DMA(DMACH_I2S2_RX),
-};
-
-struct platform_device exynos4_device_i2s2 = {
-	.name = "samsung-i2s",
-	.id = 2,
-	.num_resources = ARRAY_SIZE(exynos4_i2s2_resource),
-	.resource = exynos4_i2s2_resource,
-	.dev = {
-		.platform_data = &i2sv3_pdata,
-	},
-};
-
-/* PCM Controller platform_devices */
-
-static int exynos4_pcm_cfg_gpio(struct platform_device *pdev)
-{
-	switch (pdev->id) {
-	case 0:
-		s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 5, S3C_GPIO_SFN(3));
-		break;
-	case 1:
-		s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(3));
-		break;
-	case 2:
-		s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(3));
-		break;
-	default:
-		printk(KERN_DEBUG "Invalid PCM Controller number!");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static struct s3c_audio_pdata s3c_pcm_pdata = {
-	.cfg_gpio = exynos4_pcm_cfg_gpio,
-};
-
-static struct resource exynos4_pcm0_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_PCM0, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_PCM0_TX),
-	[2] = DEFINE_RES_DMA(DMACH_PCM0_RX),
-};
-
-struct platform_device exynos4_device_pcm0 = {
-	.name = "samsung-pcm",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(exynos4_pcm0_resource),
-	.resource = exynos4_pcm0_resource,
-	.dev = {
-		.platform_data = &s3c_pcm_pdata,
-	},
-};
-
-static struct resource exynos4_pcm1_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_PCM1, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_PCM1_TX),
-	[2] = DEFINE_RES_DMA(DMACH_PCM1_RX),
-};
-
-struct platform_device exynos4_device_pcm1 = {
-	.name = "samsung-pcm",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(exynos4_pcm1_resource),
-	.resource = exynos4_pcm1_resource,
-	.dev = {
-		.platform_data = &s3c_pcm_pdata,
-	},
-};
-
-static struct resource exynos4_pcm2_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_PCM2, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_PCM2_TX),
-	[2] = DEFINE_RES_DMA(DMACH_PCM2_RX),
-};
-
-struct platform_device exynos4_device_pcm2 = {
-	.name = "samsung-pcm",
-	.id = 2,
-	.num_resources = ARRAY_SIZE(exynos4_pcm2_resource),
-	.resource = exynos4_pcm2_resource,
-	.dev = {
-		.platform_data = &s3c_pcm_pdata,
-	},
-};
-
-/* AC97 Controller platform devices */
-
-static int exynos4_ac97_cfg_gpio(struct platform_device *pdev)
-{
-	return s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(4));
-}
-
-static struct resource exynos4_ac97_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_AC97, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_AC97_PCMOUT),
-	[2] = DEFINE_RES_DMA(DMACH_AC97_PCMIN),
-	[3] = DEFINE_RES_DMA(DMACH_AC97_MICIN),
-	[4] = DEFINE_RES_IRQ(EXYNOS4_IRQ_AC97),
-};
-
-static struct s3c_audio_pdata s3c_ac97_pdata = {
-	.cfg_gpio = exynos4_ac97_cfg_gpio,
-};
-
-static u64 exynos4_ac97_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_ac97 = {
-	.name = "samsung-ac97",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(exynos4_ac97_resource),
-	.resource = exynos4_ac97_resource,
-	.dev = {
-		.platform_data = &s3c_ac97_pdata,
-		.dma_mask = &exynos4_ac97_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
-
-/* S/PDIF Controller platform_device */
-
-static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
-{
-	s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
-
-	return 0;
-}
-
-static struct resource exynos4_spdif_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_SPDIF, SZ_256),
-	[1] = DEFINE_RES_DMA(DMACH_SPDIF),
-};
-
-static struct s3c_audio_pdata samsung_spdif_pdata = {
-	.cfg_gpio = exynos4_spdif_cfg_gpio,
-};
-
-static u64 exynos4_spdif_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_spdif = {
-	.name = "samsung-spdif",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(exynos4_spdif_resource),
-	.resource = exynos4_spdif_resource,
-	.dev = {
-		.platform_data = &samsung_spdif_pdata,
-		.dma_mask = &exynos4_spdif_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/dev-ohci.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dev-ohci.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/dev-ohci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dev-ohci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/* linux/arch/arm/mach-exynos/dev-ohci.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS - OHCI support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/usb-ohci-exynos.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-#include <plat/usb-phy.h>
-
-static struct resource exynos4_ohci_resource[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_OHCI, SZ_256),
-	[1] = DEFINE_RES_IRQ(IRQ_USB_HOST),
-};
-
-static u64 exynos4_ohci_dma_mask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_ohci = {
-	.name		= "exynos-ohci",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(exynos4_ohci_resource),
-	.resource	= exynos4_ohci_resource,
-	.dev		= {
-		.dma_mask		= &exynos4_ohci_dma_mask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	}
-};
-
-void __init exynos4_ohci_set_platdata(struct exynos4_ohci_platdata *pd)
-{
-	struct exynos4_ohci_platdata *npd;
-
-	npd = s3c_set_platdata(pd, sizeof(struct exynos4_ohci_platdata),
-			&exynos4_device_ohci);
-
-	if (!npd->phy_init)
-		npd->phy_init = s5p_usb_phy_init;
-	if (!npd->phy_exit)
-		npd->phy_exit = s5p_usb_phy_exit;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/dev-uart.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dev-uart.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/dev-uart.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dev-uart.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * Base EXYNOS UART resource and device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/irqs.h>
-
-#include <plat/devs.h>
-
-#define EXYNOS_UART_RESOURCE(_series, _nr)	\
-static struct resource exynos##_series##_uart##_nr##_resource[] = {	\
-	[0] = DEFINE_RES_MEM(EXYNOS##_series##_PA_UART##_nr, EXYNOS##_series##_SZ_UART),	\
-	[1] = DEFINE_RES_IRQ(EXYNOS##_series##_IRQ_UART##_nr),	\
-};
-
-EXYNOS_UART_RESOURCE(4, 0)
-EXYNOS_UART_RESOURCE(4, 1)
-EXYNOS_UART_RESOURCE(4, 2)
-EXYNOS_UART_RESOURCE(4, 3)
-
-struct s3c24xx_uart_resources exynos4_uart_resources[] __initdata = {
-	[0] = {
-		.resources	= exynos4_uart0_resource,
-		.nr_resources	= ARRAY_SIZE(exynos4_uart0_resource),
-	},
-	[1] = {
-		.resources	= exynos4_uart1_resource,
-		.nr_resources	= ARRAY_SIZE(exynos4_uart1_resource),
-	},
-	[2] = {
-		.resources	= exynos4_uart2_resource,
-		.nr_resources	= ARRAY_SIZE(exynos4_uart2_resource),
-	},
-	[3] = {
-		.resources	= exynos4_uart3_resource,
-		.nr_resources	= ARRAY_SIZE(exynos4_uart3_resource),
-	},
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/dma.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dma.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/dma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,322 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dma.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *	Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/pl330.h>
-#include <linux/of.h>
-
-#include <asm/irq.h>
-#include <plat/devs.h>
-#include <plat/irqs.h>
-#include <plat/cpu.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/dma.h>
-
-static u8 exynos4210_pdma0_peri[] = {
-	DMACH_PCM0_RX,
-	DMACH_PCM0_TX,
-	DMACH_PCM2_RX,
-	DMACH_PCM2_TX,
-	DMACH_MSM_REQ0,
-	DMACH_MSM_REQ2,
-	DMACH_SPI0_RX,
-	DMACH_SPI0_TX,
-	DMACH_SPI2_RX,
-	DMACH_SPI2_TX,
-	DMACH_I2S0S_TX,
-	DMACH_I2S0_RX,
-	DMACH_I2S0_TX,
-	DMACH_I2S2_RX,
-	DMACH_I2S2_TX,
-	DMACH_UART0_RX,
-	DMACH_UART0_TX,
-	DMACH_UART2_RX,
-	DMACH_UART2_TX,
-	DMACH_UART4_RX,
-	DMACH_UART4_TX,
-	DMACH_SLIMBUS0_RX,
-	DMACH_SLIMBUS0_TX,
-	DMACH_SLIMBUS2_RX,
-	DMACH_SLIMBUS2_TX,
-	DMACH_SLIMBUS4_RX,
-	DMACH_SLIMBUS4_TX,
-	DMACH_AC97_MICIN,
-	DMACH_AC97_PCMIN,
-	DMACH_AC97_PCMOUT,
-};
-
-static u8 exynos4212_pdma0_peri[] = {
-	DMACH_PCM0_RX,
-	DMACH_PCM0_TX,
-	DMACH_PCM2_RX,
-	DMACH_PCM2_TX,
-	DMACH_MIPI_HSI0,
-	DMACH_MIPI_HSI1,
-	DMACH_SPI0_RX,
-	DMACH_SPI0_TX,
-	DMACH_SPI2_RX,
-	DMACH_SPI2_TX,
-	DMACH_I2S0S_TX,
-	DMACH_I2S0_RX,
-	DMACH_I2S0_TX,
-	DMACH_I2S2_RX,
-	DMACH_I2S2_TX,
-	DMACH_UART0_RX,
-	DMACH_UART0_TX,
-	DMACH_UART2_RX,
-	DMACH_UART2_TX,
-	DMACH_UART4_RX,
-	DMACH_UART4_TX,
-	DMACH_SLIMBUS0_RX,
-	DMACH_SLIMBUS0_TX,
-	DMACH_SLIMBUS2_RX,
-	DMACH_SLIMBUS2_TX,
-	DMACH_SLIMBUS4_RX,
-	DMACH_SLIMBUS4_TX,
-	DMACH_AC97_MICIN,
-	DMACH_AC97_PCMIN,
-	DMACH_AC97_PCMOUT,
-	DMACH_MIPI_HSI4,
-	DMACH_MIPI_HSI5,
-};
-
-static u8 exynos5250_pdma0_peri[] = {
-	DMACH_PCM0_RX,
-	DMACH_PCM0_TX,
-	DMACH_PCM2_RX,
-	DMACH_PCM2_TX,
-	DMACH_SPI0_RX,
-	DMACH_SPI0_TX,
-	DMACH_SPI2_RX,
-	DMACH_SPI2_TX,
-	DMACH_I2S0S_TX,
-	DMACH_I2S0_RX,
-	DMACH_I2S0_TX,
-	DMACH_I2S2_RX,
-	DMACH_I2S2_TX,
-	DMACH_UART0_RX,
-	DMACH_UART0_TX,
-	DMACH_UART2_RX,
-	DMACH_UART2_TX,
-	DMACH_UART4_RX,
-	DMACH_UART4_TX,
-	DMACH_SLIMBUS0_RX,
-	DMACH_SLIMBUS0_TX,
-	DMACH_SLIMBUS2_RX,
-	DMACH_SLIMBUS2_TX,
-	DMACH_SLIMBUS4_RX,
-	DMACH_SLIMBUS4_TX,
-	DMACH_AC97_MICIN,
-	DMACH_AC97_PCMIN,
-	DMACH_AC97_PCMOUT,
-	DMACH_MIPI_HSI0,
-	DMACH_MIPI_HSI2,
-	DMACH_MIPI_HSI4,
-	DMACH_MIPI_HSI6,
-};
-
-static struct dma_pl330_platdata exynos_pdma0_pdata;
-
-static AMBA_AHB_DEVICE(exynos_pdma0, "dma-pl330.0", 0x00041330,
-	EXYNOS4_PA_PDMA0, {EXYNOS4_IRQ_PDMA0}, &exynos_pdma0_pdata);
-
-static u8 exynos4210_pdma1_peri[] = {
-	DMACH_PCM0_RX,
-	DMACH_PCM0_TX,
-	DMACH_PCM1_RX,
-	DMACH_PCM1_TX,
-	DMACH_MSM_REQ1,
-	DMACH_MSM_REQ3,
-	DMACH_SPI1_RX,
-	DMACH_SPI1_TX,
-	DMACH_I2S0S_TX,
-	DMACH_I2S0_RX,
-	DMACH_I2S0_TX,
-	DMACH_I2S1_RX,
-	DMACH_I2S1_TX,
-	DMACH_UART0_RX,
-	DMACH_UART0_TX,
-	DMACH_UART1_RX,
-	DMACH_UART1_TX,
-	DMACH_UART3_RX,
-	DMACH_UART3_TX,
-	DMACH_SLIMBUS1_RX,
-	DMACH_SLIMBUS1_TX,
-	DMACH_SLIMBUS3_RX,
-	DMACH_SLIMBUS3_TX,
-	DMACH_SLIMBUS5_RX,
-	DMACH_SLIMBUS5_TX,
-};
-
-static u8 exynos4212_pdma1_peri[] = {
-	DMACH_PCM0_RX,
-	DMACH_PCM0_TX,
-	DMACH_PCM1_RX,
-	DMACH_PCM1_TX,
-	DMACH_MIPI_HSI2,
-	DMACH_MIPI_HSI3,
-	DMACH_SPI1_RX,
-	DMACH_SPI1_TX,
-	DMACH_I2S0S_TX,
-	DMACH_I2S0_RX,
-	DMACH_I2S0_TX,
-	DMACH_I2S1_RX,
-	DMACH_I2S1_TX,
-	DMACH_UART0_RX,
-	DMACH_UART0_TX,
-	DMACH_UART1_RX,
-	DMACH_UART1_TX,
-	DMACH_UART3_RX,
-	DMACH_UART3_TX,
-	DMACH_SLIMBUS1_RX,
-	DMACH_SLIMBUS1_TX,
-	DMACH_SLIMBUS3_RX,
-	DMACH_SLIMBUS3_TX,
-	DMACH_SLIMBUS5_RX,
-	DMACH_SLIMBUS5_TX,
-	DMACH_SLIMBUS0AUX_RX,
-	DMACH_SLIMBUS0AUX_TX,
-	DMACH_SPDIF,
-	DMACH_MIPI_HSI6,
-	DMACH_MIPI_HSI7,
-};
-
-static u8 exynos5250_pdma1_peri[] = {
-	DMACH_PCM0_RX,
-	DMACH_PCM0_TX,
-	DMACH_PCM1_RX,
-	DMACH_PCM1_TX,
-	DMACH_SPI1_RX,
-	DMACH_SPI1_TX,
-	DMACH_PWM,
-	DMACH_SPDIF,
-	DMACH_I2S0S_TX,
-	DMACH_I2S0_RX,
-	DMACH_I2S0_TX,
-	DMACH_I2S1_RX,
-	DMACH_I2S1_TX,
-	DMACH_UART0_RX,
-	DMACH_UART0_TX,
-	DMACH_UART1_RX,
-	DMACH_UART1_TX,
-	DMACH_UART3_RX,
-	DMACH_UART3_TX,
-	DMACH_SLIMBUS1_RX,
-	DMACH_SLIMBUS1_TX,
-	DMACH_SLIMBUS3_RX,
-	DMACH_SLIMBUS3_TX,
-	DMACH_SLIMBUS5_RX,
-	DMACH_SLIMBUS5_TX,
-	DMACH_SLIMBUS0AUX_RX,
-	DMACH_SLIMBUS0AUX_TX,
-	DMACH_DISP1,
-	DMACH_MIPI_HSI1,
-	DMACH_MIPI_HSI3,
-	DMACH_MIPI_HSI5,
-	DMACH_MIPI_HSI7,
-};
-
-static struct dma_pl330_platdata exynos_pdma1_pdata;
-
-static AMBA_AHB_DEVICE(exynos_pdma1,  "dma-pl330.1", 0x00041330,
-	EXYNOS4_PA_PDMA1, {EXYNOS4_IRQ_PDMA1}, &exynos_pdma1_pdata);
-
-static u8 mdma_peri[] = {
-	DMACH_MTOM_0,
-	DMACH_MTOM_1,
-	DMACH_MTOM_2,
-	DMACH_MTOM_3,
-	DMACH_MTOM_4,
-	DMACH_MTOM_5,
-	DMACH_MTOM_6,
-	DMACH_MTOM_7,
-};
-
-static struct dma_pl330_platdata exynos_mdma1_pdata = {
-	.nr_valid_peri = ARRAY_SIZE(mdma_peri),
-	.peri_id = mdma_peri,
-};
-
-static AMBA_AHB_DEVICE(exynos_mdma1,  "dma-pl330.2", 0x00041330,
-	EXYNOS4_PA_MDMA1, {EXYNOS4_IRQ_MDMA1}, &exynos_mdma1_pdata);
-
-static int __init exynos_dma_init(void)
-{
-	if (of_have_populated_dt())
-		return 0;
-
-	if (soc_is_exynos4210()) {
-		exynos_pdma0_pdata.nr_valid_peri =
-			ARRAY_SIZE(exynos4210_pdma0_peri);
-		exynos_pdma0_pdata.peri_id = exynos4210_pdma0_peri;
-		exynos_pdma1_pdata.nr_valid_peri =
-			ARRAY_SIZE(exynos4210_pdma1_peri);
-		exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
-
-		if (samsung_rev() == EXYNOS4210_REV_0)
-			exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1;
-	} else if (soc_is_exynos4212() || soc_is_exynos4412()) {
-		exynos_pdma0_pdata.nr_valid_peri =
-			ARRAY_SIZE(exynos4212_pdma0_peri);
-		exynos_pdma0_pdata.peri_id = exynos4212_pdma0_peri;
-		exynos_pdma1_pdata.nr_valid_peri =
-			ARRAY_SIZE(exynos4212_pdma1_peri);
-		exynos_pdma1_pdata.peri_id = exynos4212_pdma1_peri;
-	} else if (soc_is_exynos5250()) {
-		exynos_pdma0_pdata.nr_valid_peri =
-			ARRAY_SIZE(exynos5250_pdma0_peri);
-		exynos_pdma0_pdata.peri_id = exynos5250_pdma0_peri;
-		exynos_pdma1_pdata.nr_valid_peri =
-			ARRAY_SIZE(exynos5250_pdma1_peri);
-		exynos_pdma1_pdata.peri_id = exynos5250_pdma1_peri;
-
-		exynos_pdma0_device.res.start = EXYNOS5_PA_PDMA0;
-		exynos_pdma0_device.res.end = EXYNOS5_PA_PDMA0 + SZ_4K;
-		exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_PDMA0;
-		exynos_pdma1_device.res.start = EXYNOS5_PA_PDMA1;
-		exynos_pdma1_device.res.end = EXYNOS5_PA_PDMA1 + SZ_4K;
-		exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_PDMA1;
-		exynos_mdma1_device.res.start = EXYNOS5_PA_MDMA1;
-		exynos_mdma1_device.res.end = EXYNOS5_PA_MDMA1 + SZ_4K;
-		exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_MDMA1;
-	}
-
-	dma_cap_set(DMA_SLAVE, exynos_pdma0_pdata.cap_mask);
-	dma_cap_set(DMA_CYCLIC, exynos_pdma0_pdata.cap_mask);
-	dma_cap_set(DMA_PRIVATE, exynos_pdma0_pdata.cap_mask);
-	amba_device_register(&exynos_pdma0_device, &iomem_resource);
-
-	dma_cap_set(DMA_SLAVE, exynos_pdma1_pdata.cap_mask);
-	dma_cap_set(DMA_CYCLIC, exynos_pdma1_pdata.cap_mask);
-	dma_cap_set(DMA_PRIVATE, exynos_pdma1_pdata.cap_mask);
-	amba_device_register(&exynos_pdma1_device, &iomem_resource);
-
-	dma_cap_set(DMA_MEMCPY, exynos_mdma1_pdata.cap_mask);
-	amba_device_register(&exynos_mdma1_device, &iomem_resource);
-
-	return 0;
-}
-arch_initcall(exynos_dma_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/firmware.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/firmware.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/firmware.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/firmware.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,20 +48,18 @@ static const struct firmware_ops exynos_
 
 void __init exynos_firmware_init(void)
 {
-	if (of_have_populated_dt()) {
-		struct device_node *nd;
-		const __be32 *addr;
+	struct device_node *nd;
+	const __be32 *addr;
 
-		nd = of_find_compatible_node(NULL, NULL,
-						"samsung,secure-firmware");
-		if (!nd)
-			return;
+	nd = of_find_compatible_node(NULL, NULL,
+					"samsung,secure-firmware");
+	if (!nd)
+		return;
 
-		addr = of_get_address(nd, 0, NULL, NULL);
-		if (!addr) {
-			pr_err("%s: No address specified.\n", __func__);
-			return;
-		}
+	addr = of_get_address(nd, 0, NULL, NULL);
+	if (!addr) {
+		pr_err("%s: No address specified.\n", __func__);
+		return;
 	}
 
 	pr_info("Running under secure firmware.\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/headsmp.S
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/headsmp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -13,8 +13,6 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-	__CPUINIT
-
 /*
  * exynos4 specific entry point for secondary CPUs.  This provides
  * a "holding pen" into which all secondary cores are held until we're
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/gpio.h linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/gpio.h
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/gpio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,289 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS - GPIO lib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_H
-#define __ASM_ARCH_GPIO_H __FILE__
-
-/* Macro for EXYNOS GPIO numbering */
-
-#define EXYNOS_GPIO_NEXT(__gpio) \
-	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
-
-/* EXYNOS4 GPIO bank sizes */
-
-#define EXYNOS4_GPIO_A0_NR	(8)
-#define EXYNOS4_GPIO_A1_NR	(6)
-#define EXYNOS4_GPIO_B_NR	(8)
-#define EXYNOS4_GPIO_C0_NR	(5)
-#define EXYNOS4_GPIO_C1_NR	(5)
-#define EXYNOS4_GPIO_D0_NR	(4)
-#define EXYNOS4_GPIO_D1_NR	(4)
-#define EXYNOS4_GPIO_E0_NR	(5)
-#define EXYNOS4_GPIO_E1_NR	(8)
-#define EXYNOS4_GPIO_E2_NR	(6)
-#define EXYNOS4_GPIO_E3_NR	(8)
-#define EXYNOS4_GPIO_E4_NR	(8)
-#define EXYNOS4_GPIO_F0_NR	(8)
-#define EXYNOS4_GPIO_F1_NR	(8)
-#define EXYNOS4_GPIO_F2_NR	(8)
-#define EXYNOS4_GPIO_F3_NR	(6)
-#define EXYNOS4_GPIO_J0_NR	(8)
-#define EXYNOS4_GPIO_J1_NR	(5)
-#define EXYNOS4_GPIO_K0_NR	(7)
-#define EXYNOS4_GPIO_K1_NR	(7)
-#define EXYNOS4_GPIO_K2_NR	(7)
-#define EXYNOS4_GPIO_K3_NR	(7)
-#define EXYNOS4_GPIO_L0_NR	(8)
-#define EXYNOS4_GPIO_L1_NR	(3)
-#define EXYNOS4_GPIO_L2_NR	(8)
-#define EXYNOS4_GPIO_X0_NR	(8)
-#define EXYNOS4_GPIO_X1_NR	(8)
-#define EXYNOS4_GPIO_X2_NR	(8)
-#define EXYNOS4_GPIO_X3_NR	(8)
-#define EXYNOS4_GPIO_Y0_NR	(6)
-#define EXYNOS4_GPIO_Y1_NR	(4)
-#define EXYNOS4_GPIO_Y2_NR	(6)
-#define EXYNOS4_GPIO_Y3_NR	(8)
-#define EXYNOS4_GPIO_Y4_NR	(8)
-#define EXYNOS4_GPIO_Y5_NR	(8)
-#define EXYNOS4_GPIO_Y6_NR	(8)
-#define EXYNOS4_GPIO_Z_NR	(7)
-
-/* EXYNOS4 GPIO bank numbers */
-
-enum exynos4_gpio_number {
-	EXYNOS4_GPIO_A0_START	= 0,
-	EXYNOS4_GPIO_A1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A0),
-	EXYNOS4_GPIO_B_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_A1),
-	EXYNOS4_GPIO_C0_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_B),
-	EXYNOS4_GPIO_C1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C0),
-	EXYNOS4_GPIO_D0_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_C1),
-	EXYNOS4_GPIO_D1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D0),
-	EXYNOS4_GPIO_E0_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_D1),
-	EXYNOS4_GPIO_E1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E0),
-	EXYNOS4_GPIO_E2_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E1),
-	EXYNOS4_GPIO_E3_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E2),
-	EXYNOS4_GPIO_E4_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E3),
-	EXYNOS4_GPIO_F0_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_E4),
-	EXYNOS4_GPIO_F1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F0),
-	EXYNOS4_GPIO_F2_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F1),
-	EXYNOS4_GPIO_F3_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F2),
-	EXYNOS4_GPIO_J0_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_F3),
-	EXYNOS4_GPIO_J1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J0),
-	EXYNOS4_GPIO_K0_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_J1),
-	EXYNOS4_GPIO_K1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K0),
-	EXYNOS4_GPIO_K2_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K1),
-	EXYNOS4_GPIO_K3_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K2),
-	EXYNOS4_GPIO_L0_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_K3),
-	EXYNOS4_GPIO_L1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L0),
-	EXYNOS4_GPIO_L2_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L1),
-	EXYNOS4_GPIO_X0_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_L2),
-	EXYNOS4_GPIO_X1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X0),
-	EXYNOS4_GPIO_X2_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X1),
-	EXYNOS4_GPIO_X3_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X2),
-	EXYNOS4_GPIO_Y0_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_X3),
-	EXYNOS4_GPIO_Y1_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y0),
-	EXYNOS4_GPIO_Y2_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y1),
-	EXYNOS4_GPIO_Y3_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y2),
-	EXYNOS4_GPIO_Y4_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y3),
-	EXYNOS4_GPIO_Y5_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y4),
-	EXYNOS4_GPIO_Y6_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y5),
-	EXYNOS4_GPIO_Z_START	= EXYNOS_GPIO_NEXT(EXYNOS4_GPIO_Y6),
-};
-
-/* EXYNOS4 GPIO number definitions */
-
-#define EXYNOS4_GPA0(_nr)	(EXYNOS4_GPIO_A0_START + (_nr))
-#define EXYNOS4_GPA1(_nr)	(EXYNOS4_GPIO_A1_START + (_nr))
-#define EXYNOS4_GPB(_nr)	(EXYNOS4_GPIO_B_START + (_nr))
-#define EXYNOS4_GPC0(_nr)	(EXYNOS4_GPIO_C0_START + (_nr))
-#define EXYNOS4_GPC1(_nr)	(EXYNOS4_GPIO_C1_START + (_nr))
-#define EXYNOS4_GPD0(_nr)	(EXYNOS4_GPIO_D0_START + (_nr))
-#define EXYNOS4_GPD1(_nr)	(EXYNOS4_GPIO_D1_START + (_nr))
-#define EXYNOS4_GPE0(_nr)	(EXYNOS4_GPIO_E0_START + (_nr))
-#define EXYNOS4_GPE1(_nr)	(EXYNOS4_GPIO_E1_START + (_nr))
-#define EXYNOS4_GPE2(_nr)	(EXYNOS4_GPIO_E2_START + (_nr))
-#define EXYNOS4_GPE3(_nr)	(EXYNOS4_GPIO_E3_START + (_nr))
-#define EXYNOS4_GPE4(_nr)	(EXYNOS4_GPIO_E4_START + (_nr))
-#define EXYNOS4_GPF0(_nr)	(EXYNOS4_GPIO_F0_START + (_nr))
-#define EXYNOS4_GPF1(_nr)	(EXYNOS4_GPIO_F1_START + (_nr))
-#define EXYNOS4_GPF2(_nr)	(EXYNOS4_GPIO_F2_START + (_nr))
-#define EXYNOS4_GPF3(_nr)	(EXYNOS4_GPIO_F3_START + (_nr))
-#define EXYNOS4_GPJ0(_nr)	(EXYNOS4_GPIO_J0_START + (_nr))
-#define EXYNOS4_GPJ1(_nr)	(EXYNOS4_GPIO_J1_START + (_nr))
-#define EXYNOS4_GPK0(_nr)	(EXYNOS4_GPIO_K0_START + (_nr))
-#define EXYNOS4_GPK1(_nr)	(EXYNOS4_GPIO_K1_START + (_nr))
-#define EXYNOS4_GPK2(_nr)	(EXYNOS4_GPIO_K2_START + (_nr))
-#define EXYNOS4_GPK3(_nr)	(EXYNOS4_GPIO_K3_START + (_nr))
-#define EXYNOS4_GPL0(_nr)	(EXYNOS4_GPIO_L0_START + (_nr))
-#define EXYNOS4_GPL1(_nr)	(EXYNOS4_GPIO_L1_START + (_nr))
-#define EXYNOS4_GPL2(_nr)	(EXYNOS4_GPIO_L2_START + (_nr))
-#define EXYNOS4_GPX0(_nr)	(EXYNOS4_GPIO_X0_START + (_nr))
-#define EXYNOS4_GPX1(_nr)	(EXYNOS4_GPIO_X1_START + (_nr))
-#define EXYNOS4_GPX2(_nr)	(EXYNOS4_GPIO_X2_START + (_nr))
-#define EXYNOS4_GPX3(_nr)	(EXYNOS4_GPIO_X3_START + (_nr))
-#define EXYNOS4_GPY0(_nr)	(EXYNOS4_GPIO_Y0_START + (_nr))
-#define EXYNOS4_GPY1(_nr)	(EXYNOS4_GPIO_Y1_START + (_nr))
-#define EXYNOS4_GPY2(_nr)	(EXYNOS4_GPIO_Y2_START + (_nr))
-#define EXYNOS4_GPY3(_nr)	(EXYNOS4_GPIO_Y3_START + (_nr))
-#define EXYNOS4_GPY4(_nr)	(EXYNOS4_GPIO_Y4_START + (_nr))
-#define EXYNOS4_GPY5(_nr)	(EXYNOS4_GPIO_Y5_START + (_nr))
-#define EXYNOS4_GPY6(_nr)	(EXYNOS4_GPIO_Y6_START + (_nr))
-#define EXYNOS4_GPZ(_nr)	(EXYNOS4_GPIO_Z_START + (_nr))
-
-/* the end of the EXYNOS4 specific gpios */
-
-#define EXYNOS4_GPIO_END	(EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1)
-
-/* EXYNOS5 GPIO bank sizes */
-
-#define EXYNOS5_GPIO_A0_NR	(8)
-#define EXYNOS5_GPIO_A1_NR	(6)
-#define EXYNOS5_GPIO_A2_NR	(8)
-#define EXYNOS5_GPIO_B0_NR	(5)
-#define EXYNOS5_GPIO_B1_NR	(5)
-#define EXYNOS5_GPIO_B2_NR	(4)
-#define EXYNOS5_GPIO_B3_NR	(4)
-#define EXYNOS5_GPIO_C0_NR	(7)
-#define EXYNOS5_GPIO_C1_NR	(4)
-#define EXYNOS5_GPIO_C2_NR	(7)
-#define EXYNOS5_GPIO_C3_NR	(7)
-#define EXYNOS5_GPIO_C4_NR	(7)
-#define EXYNOS5_GPIO_D0_NR	(4)
-#define EXYNOS5_GPIO_D1_NR	(8)
-#define EXYNOS5_GPIO_Y0_NR	(6)
-#define EXYNOS5_GPIO_Y1_NR	(4)
-#define EXYNOS5_GPIO_Y2_NR	(6)
-#define EXYNOS5_GPIO_Y3_NR	(8)
-#define EXYNOS5_GPIO_Y4_NR	(8)
-#define EXYNOS5_GPIO_Y5_NR	(8)
-#define EXYNOS5_GPIO_Y6_NR	(8)
-#define EXYNOS5_GPIO_X0_NR	(8)
-#define EXYNOS5_GPIO_X1_NR	(8)
-#define EXYNOS5_GPIO_X2_NR	(8)
-#define EXYNOS5_GPIO_X3_NR	(8)
-#define EXYNOS5_GPIO_E0_NR	(8)
-#define EXYNOS5_GPIO_E1_NR	(2)
-#define EXYNOS5_GPIO_F0_NR	(4)
-#define EXYNOS5_GPIO_F1_NR	(4)
-#define EXYNOS5_GPIO_G0_NR	(8)
-#define EXYNOS5_GPIO_G1_NR	(8)
-#define EXYNOS5_GPIO_G2_NR	(2)
-#define EXYNOS5_GPIO_H0_NR	(4)
-#define EXYNOS5_GPIO_H1_NR	(8)
-#define EXYNOS5_GPIO_V0_NR	(8)
-#define EXYNOS5_GPIO_V1_NR	(8)
-#define EXYNOS5_GPIO_V2_NR	(8)
-#define EXYNOS5_GPIO_V3_NR	(8)
-#define EXYNOS5_GPIO_V4_NR	(2)
-#define EXYNOS5_GPIO_Z_NR	(7)
-
-/* EXYNOS5 GPIO bank numbers */
-
-enum exynos5_gpio_number {
-	EXYNOS5_GPIO_A0_START		= 0,
-	EXYNOS5_GPIO_A1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A0),
-	EXYNOS5_GPIO_A2_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A1),
-	EXYNOS5_GPIO_B0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_A2),
-	EXYNOS5_GPIO_B1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B0),
-	EXYNOS5_GPIO_B2_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B1),
-	EXYNOS5_GPIO_B3_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B2),
-	EXYNOS5_GPIO_C0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_B3),
-	EXYNOS5_GPIO_C1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0),
-	EXYNOS5_GPIO_C2_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1),
-	EXYNOS5_GPIO_C3_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2),
-	EXYNOS5_GPIO_C4_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3),
-	EXYNOS5_GPIO_D0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C4),
-	EXYNOS5_GPIO_D1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0),
-	EXYNOS5_GPIO_Y0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1),
-	EXYNOS5_GPIO_Y1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0),
-	EXYNOS5_GPIO_Y2_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y1),
-	EXYNOS5_GPIO_Y3_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y2),
-	EXYNOS5_GPIO_Y4_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y3),
-	EXYNOS5_GPIO_Y5_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y4),
-	EXYNOS5_GPIO_Y6_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y5),
-	EXYNOS5_GPIO_X0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y6),
-	EXYNOS5_GPIO_X1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X0),
-	EXYNOS5_GPIO_X2_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X1),
-	EXYNOS5_GPIO_X3_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X2),
-	EXYNOS5_GPIO_E0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_X3),
-	EXYNOS5_GPIO_E1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E0),
-	EXYNOS5_GPIO_F0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_E1),
-	EXYNOS5_GPIO_F1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F0),
-	EXYNOS5_GPIO_G0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_F1),
-	EXYNOS5_GPIO_G1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G0),
-	EXYNOS5_GPIO_G2_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G1),
-	EXYNOS5_GPIO_H0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_G2),
-	EXYNOS5_GPIO_H1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H0),
-	EXYNOS5_GPIO_V0_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_H1),
-	EXYNOS5_GPIO_V1_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V0),
-	EXYNOS5_GPIO_V2_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V1),
-	EXYNOS5_GPIO_V3_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V2),
-	EXYNOS5_GPIO_V4_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V3),
-	EXYNOS5_GPIO_Z_START		= EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_V4),
-};
-
-/* EXYNOS5 GPIO number definitions */
-
-#define EXYNOS5_GPA0(_nr)	(EXYNOS5_GPIO_A0_START + (_nr))
-#define EXYNOS5_GPA1(_nr)	(EXYNOS5_GPIO_A1_START + (_nr))
-#define EXYNOS5_GPA2(_nr)	(EXYNOS5_GPIO_A2_START + (_nr))
-#define EXYNOS5_GPB0(_nr)	(EXYNOS5_GPIO_B0_START + (_nr))
-#define EXYNOS5_GPB1(_nr)	(EXYNOS5_GPIO_B1_START + (_nr))
-#define EXYNOS5_GPB2(_nr)	(EXYNOS5_GPIO_B2_START + (_nr))
-#define EXYNOS5_GPB3(_nr)	(EXYNOS5_GPIO_B3_START + (_nr))
-#define EXYNOS5_GPC0(_nr)	(EXYNOS5_GPIO_C0_START + (_nr))
-#define EXYNOS5_GPC1(_nr)	(EXYNOS5_GPIO_C1_START + (_nr))
-#define EXYNOS5_GPC2(_nr)	(EXYNOS5_GPIO_C2_START + (_nr))
-#define EXYNOS5_GPC3(_nr)	(EXYNOS5_GPIO_C3_START + (_nr))
-#define EXYNOS5_GPC4(_nr)	(EXYNOS5_GPIO_C4_START + (_nr))
-#define EXYNOS5_GPD0(_nr)	(EXYNOS5_GPIO_D0_START + (_nr))
-#define EXYNOS5_GPD1(_nr)	(EXYNOS5_GPIO_D1_START + (_nr))
-#define EXYNOS5_GPY0(_nr)	(EXYNOS5_GPIO_Y0_START + (_nr))
-#define EXYNOS5_GPY1(_nr)	(EXYNOS5_GPIO_Y1_START + (_nr))
-#define EXYNOS5_GPY2(_nr)	(EXYNOS5_GPIO_Y2_START + (_nr))
-#define EXYNOS5_GPY3(_nr)	(EXYNOS5_GPIO_Y3_START + (_nr))
-#define EXYNOS5_GPY4(_nr)	(EXYNOS5_GPIO_Y4_START + (_nr))
-#define EXYNOS5_GPY5(_nr)	(EXYNOS5_GPIO_Y5_START + (_nr))
-#define EXYNOS5_GPY6(_nr)	(EXYNOS5_GPIO_Y6_START + (_nr))
-#define EXYNOS5_GPX0(_nr)	(EXYNOS5_GPIO_X0_START + (_nr))
-#define EXYNOS5_GPX1(_nr)	(EXYNOS5_GPIO_X1_START + (_nr))
-#define EXYNOS5_GPX2(_nr)	(EXYNOS5_GPIO_X2_START + (_nr))
-#define EXYNOS5_GPX3(_nr)	(EXYNOS5_GPIO_X3_START + (_nr))
-#define EXYNOS5_GPE0(_nr)	(EXYNOS5_GPIO_E0_START + (_nr))
-#define EXYNOS5_GPE1(_nr)	(EXYNOS5_GPIO_E1_START + (_nr))
-#define EXYNOS5_GPF0(_nr)	(EXYNOS5_GPIO_F0_START + (_nr))
-#define EXYNOS5_GPF1(_nr)	(EXYNOS5_GPIO_F1_START + (_nr))
-#define EXYNOS5_GPG0(_nr)	(EXYNOS5_GPIO_G0_START + (_nr))
-#define EXYNOS5_GPG1(_nr)	(EXYNOS5_GPIO_G1_START + (_nr))
-#define EXYNOS5_GPG2(_nr)	(EXYNOS5_GPIO_G2_START + (_nr))
-#define EXYNOS5_GPH0(_nr)	(EXYNOS5_GPIO_H0_START + (_nr))
-#define EXYNOS5_GPH1(_nr)	(EXYNOS5_GPIO_H1_START + (_nr))
-#define EXYNOS5_GPV0(_nr)	(EXYNOS5_GPIO_V0_START + (_nr))
-#define EXYNOS5_GPV1(_nr)	(EXYNOS5_GPIO_V1_START + (_nr))
-#define EXYNOS5_GPV2(_nr)	(EXYNOS5_GPIO_V2_START + (_nr))
-#define EXYNOS5_GPV3(_nr)	(EXYNOS5_GPIO_V3_START + (_nr))
-#define EXYNOS5_GPV4(_nr)	(EXYNOS5_GPIO_V4_START + (_nr))
-#define EXYNOS5_GPZ(_nr)	(EXYNOS5_GPIO_Z_START + (_nr))
-
-/* the end of the EXYNOS5 specific gpios */
-
-#define EXYNOS5_GPIO_END	(EXYNOS5_GPZ(EXYNOS5_GPIO_Z_NR) + 1)
-
-/* actually, EXYNOS5_GPIO_END is bigger than EXYNOS4 */
-
-#define S3C_GPIO_END		(EXYNOS5_GPIO_END)
-
-/* define the number of gpios */
-
-#define ARCH_NR_GPIOS		(CONFIG_SAMSUNG_GPIO_EXTRA + S3C_GPIO_END)
-
-#endif /* __ASM_ARCH_GPIO_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/irqs.h linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/irqs.h
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/irqs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,476 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS - IRQ definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H __FILE__
-
-#include <plat/irqs.h>
-
-/* PPI: Private Peripheral Interrupt */
-
-#define IRQ_PPI(x)			(x + 16)
-
-/* SPI: Shared Peripheral Interrupt */
-
-#define IRQ_SPI(x)			(x + 32)
-
-/* COMBINER */
-
-#define MAX_IRQ_IN_COMBINER		8
-#define COMBINER_GROUP(x)		((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128))
-#define COMBINER_IRQ(x, y)		(COMBINER_GROUP(x) + y)
-
-/* For EXYNOS4 and EXYNOS5 */
-
-#define EXYNOS_IRQ_EINT16_31		IRQ_SPI(32)
-
-/* For EXYNOS4 SoCs */
-
-#define EXYNOS4_IRQ_EINT0		IRQ_SPI(16)
-#define EXYNOS4_IRQ_EINT1		IRQ_SPI(17)
-#define EXYNOS4_IRQ_EINT2		IRQ_SPI(18)
-#define EXYNOS4_IRQ_EINT3		IRQ_SPI(19)
-#define EXYNOS4_IRQ_EINT4		IRQ_SPI(20)
-#define EXYNOS4_IRQ_EINT5		IRQ_SPI(21)
-#define EXYNOS4_IRQ_EINT6		IRQ_SPI(22)
-#define EXYNOS4_IRQ_EINT7		IRQ_SPI(23)
-#define EXYNOS4_IRQ_EINT8		IRQ_SPI(24)
-#define EXYNOS4_IRQ_EINT9		IRQ_SPI(25)
-#define EXYNOS4_IRQ_EINT10		IRQ_SPI(26)
-#define EXYNOS4_IRQ_EINT11		IRQ_SPI(27)
-#define EXYNOS4_IRQ_EINT12		IRQ_SPI(28)
-#define EXYNOS4_IRQ_EINT13		IRQ_SPI(29)
-#define EXYNOS4_IRQ_EINT14		IRQ_SPI(30)
-#define EXYNOS4_IRQ_EINT15		IRQ_SPI(31)
-
-#define EXYNOS4_IRQ_MDMA0		IRQ_SPI(33)
-#define EXYNOS4_IRQ_MDMA1		IRQ_SPI(34)
-#define EXYNOS4_IRQ_PDMA0		IRQ_SPI(35)
-#define EXYNOS4_IRQ_PDMA1		IRQ_SPI(36)
-#define EXYNOS4_IRQ_TIMER0_VIC		IRQ_SPI(37)
-#define EXYNOS4_IRQ_TIMER1_VIC		IRQ_SPI(38)
-#define EXYNOS4_IRQ_TIMER2_VIC		IRQ_SPI(39)
-#define EXYNOS4_IRQ_TIMER3_VIC		IRQ_SPI(40)
-#define EXYNOS4_IRQ_TIMER4_VIC		IRQ_SPI(41)
-#define EXYNOS4_IRQ_MCT_L0		IRQ_SPI(42)
-#define EXYNOS4_IRQ_WDT			IRQ_SPI(43)
-#define EXYNOS4_IRQ_RTC_ALARM		IRQ_SPI(44)
-#define EXYNOS4_IRQ_RTC_TIC		IRQ_SPI(45)
-#define EXYNOS4_IRQ_GPIO_XB		IRQ_SPI(46)
-#define EXYNOS4_IRQ_GPIO_XA		IRQ_SPI(47)
-#define EXYNOS4_IRQ_MCT_L1		IRQ_SPI(48)
-
-#define EXYNOS4_IRQ_UART0		IRQ_SPI(52)
-#define EXYNOS4_IRQ_UART1		IRQ_SPI(53)
-#define EXYNOS4_IRQ_UART2		IRQ_SPI(54)
-#define EXYNOS4_IRQ_UART3		IRQ_SPI(55)
-#define EXYNOS4_IRQ_UART4		IRQ_SPI(56)
-#define EXYNOS4_IRQ_MCT_G0		IRQ_SPI(57)
-#define EXYNOS4_IRQ_IIC			IRQ_SPI(58)
-#define EXYNOS4_IRQ_IIC1		IRQ_SPI(59)
-#define EXYNOS4_IRQ_IIC2		IRQ_SPI(60)
-#define EXYNOS4_IRQ_IIC3		IRQ_SPI(61)
-#define EXYNOS4_IRQ_IIC4		IRQ_SPI(62)
-#define EXYNOS4_IRQ_IIC5		IRQ_SPI(63)
-#define EXYNOS4_IRQ_IIC6		IRQ_SPI(64)
-#define EXYNOS4_IRQ_IIC7		IRQ_SPI(65)
-#define EXYNOS4_IRQ_SPI0		IRQ_SPI(66)
-#define EXYNOS4_IRQ_SPI1		IRQ_SPI(67)
-#define EXYNOS4_IRQ_SPI2		IRQ_SPI(68)
-
-#define EXYNOS4_IRQ_USB_HOST		IRQ_SPI(70)
-#define EXYNOS4_IRQ_USB_HSOTG		IRQ_SPI(71)
-#define EXYNOS4_IRQ_MODEM_IF		IRQ_SPI(72)
-#define EXYNOS4_IRQ_HSMMC0		IRQ_SPI(73)
-#define EXYNOS4_IRQ_HSMMC1		IRQ_SPI(74)
-#define EXYNOS4_IRQ_HSMMC2		IRQ_SPI(75)
-#define EXYNOS4_IRQ_HSMMC3		IRQ_SPI(76)
-#define EXYNOS4_IRQ_DWMCI		IRQ_SPI(77)
-
-#define EXYNOS4_IRQ_MIPI_CSIS0		IRQ_SPI(78)
-#define EXYNOS4_IRQ_MIPI_CSIS1		IRQ_SPI(80)
-
-#define EXYNOS4_IRQ_ONENAND_AUDI	IRQ_SPI(82)
-#define EXYNOS4_IRQ_ROTATOR		IRQ_SPI(83)
-#define EXYNOS4_IRQ_FIMC0		IRQ_SPI(84)
-#define EXYNOS4_IRQ_FIMC1		IRQ_SPI(85)
-#define EXYNOS4_IRQ_FIMC2		IRQ_SPI(86)
-#define EXYNOS4_IRQ_FIMC3		IRQ_SPI(87)
-#define EXYNOS4_IRQ_JPEG		IRQ_SPI(88)
-#define EXYNOS4_IRQ_2D			IRQ_SPI(89)
-#define EXYNOS4_IRQ_PCIE		IRQ_SPI(90)
-
-#define EXYNOS4_IRQ_MIXER		IRQ_SPI(91)
-#define EXYNOS4_IRQ_HDMI		IRQ_SPI(92)
-#define EXYNOS4_IRQ_IIC_HDMIPHY		IRQ_SPI(93)
-#define EXYNOS4_IRQ_MFC			IRQ_SPI(94)
-#define EXYNOS4_IRQ_SDO			IRQ_SPI(95)
-
-#define EXYNOS4_IRQ_AUDIO_SS		IRQ_SPI(96)
-#define EXYNOS4_IRQ_I2S0		IRQ_SPI(97)
-#define EXYNOS4_IRQ_I2S1		IRQ_SPI(98)
-#define EXYNOS4_IRQ_I2S2		IRQ_SPI(99)
-#define EXYNOS4_IRQ_AC97		IRQ_SPI(100)
-
-#define EXYNOS4_IRQ_SPDIF		IRQ_SPI(104)
-#define EXYNOS4_IRQ_ADC0		IRQ_SPI(105)
-#define EXYNOS4_IRQ_PEN0		IRQ_SPI(106)
-#define EXYNOS4_IRQ_ADC1		IRQ_SPI(107)
-#define EXYNOS4_IRQ_PEN1		IRQ_SPI(108)
-#define EXYNOS4_IRQ_KEYPAD		IRQ_SPI(109)
-#define EXYNOS4_IRQ_POWER_PMU		IRQ_SPI(110)
-#define EXYNOS4_IRQ_GPS			IRQ_SPI(111)
-#define EXYNOS4_IRQ_INTFEEDCTRL_SSS	IRQ_SPI(112)
-#define EXYNOS4_IRQ_SLIMBUS		IRQ_SPI(113)
-
-#define EXYNOS4_IRQ_TSI			IRQ_SPI(115)
-#define EXYNOS4_IRQ_SATA		IRQ_SPI(116)
-
-#define EXYNOS4_IRQ_PMU			COMBINER_IRQ(2, 2)
-#define EXYNOS4_IRQ_PMU_CPU1		COMBINER_IRQ(3, 2)
-#define EXYNOS4_IRQ_PMU_CPU2		COMBINER_IRQ(18, 2)
-#define EXYNOS4_IRQ_PMU_CPU3		COMBINER_IRQ(19, 2)
-
-#define EXYNOS4_IRQ_TMU_TRIG0		COMBINER_IRQ(2, 4)
-#define EXYNOS4_IRQ_TMU_TRIG1		COMBINER_IRQ(3, 4)
-
-#define EXYNOS4_IRQ_SYSMMU_MDMA0_0	COMBINER_IRQ(4, 0)
-#define EXYNOS4_IRQ_SYSMMU_SSS_0	COMBINER_IRQ(4, 1)
-#define EXYNOS4_IRQ_SYSMMU_FIMC0_0	COMBINER_IRQ(4, 2)
-#define EXYNOS4_IRQ_SYSMMU_FIMC1_0	COMBINER_IRQ(4, 3)
-#define EXYNOS4_IRQ_SYSMMU_FIMC2_0	COMBINER_IRQ(4, 4)
-#define EXYNOS4_IRQ_SYSMMU_FIMC3_0	COMBINER_IRQ(4, 5)
-#define EXYNOS4_IRQ_SYSMMU_JPEG_0	COMBINER_IRQ(4, 6)
-#define EXYNOS4_IRQ_SYSMMU_2D_0		COMBINER_IRQ(4, 7)
-
-#define EXYNOS4_IRQ_SYSMMU_ROTATOR_0	COMBINER_IRQ(5, 0)
-#define EXYNOS4_IRQ_SYSMMU_MDMA1_0	COMBINER_IRQ(5, 1)
-#define EXYNOS4_IRQ_SYSMMU_LCD0_M0_0	COMBINER_IRQ(5, 2)
-#define EXYNOS4_IRQ_SYSMMU_LCD1_M1_0	COMBINER_IRQ(5, 3)
-#define EXYNOS4_IRQ_SYSMMU_TV_M0_0	COMBINER_IRQ(5, 4)
-#define EXYNOS4_IRQ_SYSMMU_MFC_M0_0	COMBINER_IRQ(5, 5)
-#define EXYNOS4_IRQ_SYSMMU_MFC_M1_0	COMBINER_IRQ(5, 6)
-#define EXYNOS4_IRQ_SYSMMU_PCIE_0	COMBINER_IRQ(5, 7)
-
-#define EXYNOS4_IRQ_SYSMMU_FIMC_LITE0_0	COMBINER_IRQ(16, 0)
-#define EXYNOS4_IRQ_SYSMMU_FIMC_LITE1_0	COMBINER_IRQ(16, 1)
-#define EXYNOS4_IRQ_SYSMMU_FIMC_ISP_0	COMBINER_IRQ(16, 2)
-#define EXYNOS4_IRQ_SYSMMU_FIMC_DRC_0	COMBINER_IRQ(16, 3)
-#define EXYNOS4_IRQ_SYSMMU_FIMC_FD_0	COMBINER_IRQ(16, 4)
-#define EXYNOS4_IRQ_SYSMMU_FIMC_CX_0	COMBINER_IRQ(16, 5)
-
-#define EXYNOS4_IRQ_FIMD0_FIFO		COMBINER_IRQ(11, 0)
-#define EXYNOS4_IRQ_FIMD0_VSYNC		COMBINER_IRQ(11, 1)
-#define EXYNOS4_IRQ_FIMD0_SYSTEM	COMBINER_IRQ(11, 2)
-
-#define EXYNOS4210_MAX_COMBINER_NR	16
-#define EXYNOS4212_MAX_COMBINER_NR	18
-#define EXYNOS4412_MAX_COMBINER_NR	20
-#define EXYNOS4_MAX_COMBINER_NR		EXYNOS4412_MAX_COMBINER_NR
-
-#define EXYNOS4_IRQ_GPIO1_NR_GROUPS	16
-#define EXYNOS4_IRQ_GPIO2_NR_GROUPS	9
-
-/*
- * For Compatibility:
- * the default is for EXYNOS4, and
- * for exynos5, should be re-mapped at function
- */
-
-#define IRQ_TIMER0_VIC			EXYNOS4_IRQ_TIMER0_VIC
-#define IRQ_TIMER1_VIC			EXYNOS4_IRQ_TIMER1_VIC
-#define IRQ_TIMER2_VIC			EXYNOS4_IRQ_TIMER2_VIC
-#define IRQ_TIMER3_VIC			EXYNOS4_IRQ_TIMER3_VIC
-#define IRQ_TIMER4_VIC			EXYNOS4_IRQ_TIMER4_VIC
-
-#define IRQ_WDT				EXYNOS4_IRQ_WDT
-#define IRQ_RTC_ALARM			EXYNOS4_IRQ_RTC_ALARM
-#define IRQ_RTC_TIC			EXYNOS4_IRQ_RTC_TIC
-#define IRQ_GPIO_XB			EXYNOS4_IRQ_GPIO_XB
-#define IRQ_GPIO_XA			EXYNOS4_IRQ_GPIO_XA
-
-#define IRQ_IIC				EXYNOS4_IRQ_IIC
-#define IRQ_IIC1			EXYNOS4_IRQ_IIC1
-#define IRQ_IIC3			EXYNOS4_IRQ_IIC3
-#define IRQ_IIC5			EXYNOS4_IRQ_IIC5
-#define IRQ_IIC6			EXYNOS4_IRQ_IIC6
-#define IRQ_IIC7			EXYNOS4_IRQ_IIC7
-
-#define IRQ_SPI0			EXYNOS4_IRQ_SPI0
-#define IRQ_SPI1			EXYNOS4_IRQ_SPI1
-#define IRQ_SPI2			EXYNOS4_IRQ_SPI2
-
-#define IRQ_USB_HOST			EXYNOS4_IRQ_USB_HOST
-#define IRQ_OTG				EXYNOS4_IRQ_USB_HSOTG
-
-#define IRQ_HSMMC0			EXYNOS4_IRQ_HSMMC0
-#define IRQ_HSMMC1			EXYNOS4_IRQ_HSMMC1
-#define IRQ_HSMMC2			EXYNOS4_IRQ_HSMMC2
-#define IRQ_HSMMC3			EXYNOS4_IRQ_HSMMC3
-
-#define IRQ_MIPI_CSIS0			EXYNOS4_IRQ_MIPI_CSIS0
-
-#define IRQ_ONENAND_AUDI		EXYNOS4_IRQ_ONENAND_AUDI
-
-#define IRQ_FIMC0			EXYNOS4_IRQ_FIMC0
-#define IRQ_FIMC1			EXYNOS4_IRQ_FIMC1
-#define IRQ_FIMC2			EXYNOS4_IRQ_FIMC2
-#define IRQ_FIMC3			EXYNOS4_IRQ_FIMC3
-#define IRQ_JPEG			EXYNOS4_IRQ_JPEG
-#define IRQ_2D				EXYNOS4_IRQ_2D
-
-#define IRQ_MIXER			EXYNOS4_IRQ_MIXER
-#define IRQ_HDMI			EXYNOS4_IRQ_HDMI
-#define IRQ_IIC_HDMIPHY			EXYNOS4_IRQ_IIC_HDMIPHY
-#define IRQ_MFC				EXYNOS4_IRQ_MFC
-#define IRQ_SDO				EXYNOS4_IRQ_SDO
-
-#define IRQ_I2S0			EXYNOS4_IRQ_I2S0
-
-#define IRQ_ADC				EXYNOS4_IRQ_ADC0
-#define IRQ_TC				EXYNOS4_IRQ_PEN0
-
-#define IRQ_KEYPAD			EXYNOS4_IRQ_KEYPAD
-
-#define IRQ_FIMD0_FIFO			EXYNOS4_IRQ_FIMD0_FIFO
-#define IRQ_FIMD0_VSYNC			EXYNOS4_IRQ_FIMD0_VSYNC
-#define IRQ_FIMD0_SYSTEM		EXYNOS4_IRQ_FIMD0_SYSTEM
-
-#define IRQ_GPIO1_NR_GROUPS		EXYNOS4_IRQ_GPIO1_NR_GROUPS
-#define IRQ_GPIO2_NR_GROUPS		EXYNOS4_IRQ_GPIO2_NR_GROUPS
-
-/* For EXYNOS5 SoCs */
-
-#define EXYNOS5_IRQ_MDMA0		IRQ_SPI(33)
-#define EXYNOS5_IRQ_PDMA0		IRQ_SPI(34)
-#define EXYNOS5_IRQ_PDMA1		IRQ_SPI(35)
-#define EXYNOS5_IRQ_TIMER0_VIC		IRQ_SPI(36)
-#define EXYNOS5_IRQ_TIMER1_VIC		IRQ_SPI(37)
-#define EXYNOS5_IRQ_TIMER2_VIC		IRQ_SPI(38)
-#define EXYNOS5_IRQ_TIMER3_VIC		IRQ_SPI(39)
-#define EXYNOS5_IRQ_TIMER4_VIC		IRQ_SPI(40)
-#define EXYNOS5_IRQ_RTIC		IRQ_SPI(41)
-#define EXYNOS5_IRQ_WDT			IRQ_SPI(42)
-#define EXYNOS5_IRQ_RTC_ALARM		IRQ_SPI(43)
-#define EXYNOS5_IRQ_RTC_TIC		IRQ_SPI(44)
-#define EXYNOS5_IRQ_GPIO_XB		IRQ_SPI(45)
-#define EXYNOS5_IRQ_GPIO_XA		IRQ_SPI(46)
-#define EXYNOS5_IRQ_GPIO		IRQ_SPI(47)
-#define EXYNOS5_IRQ_IEM_IEC		IRQ_SPI(48)
-#define EXYNOS5_IRQ_IEM_APC		IRQ_SPI(49)
-#define EXYNOS5_IRQ_GPIO_C2C		IRQ_SPI(50)
-#define EXYNOS5_IRQ_IIC			IRQ_SPI(56)
-#define EXYNOS5_IRQ_IIC1		IRQ_SPI(57)
-#define EXYNOS5_IRQ_IIC2		IRQ_SPI(58)
-#define EXYNOS5_IRQ_IIC3		IRQ_SPI(59)
-#define EXYNOS5_IRQ_IIC4		IRQ_SPI(60)
-#define EXYNOS5_IRQ_IIC5		IRQ_SPI(61)
-#define EXYNOS5_IRQ_IIC6		IRQ_SPI(62)
-#define EXYNOS5_IRQ_IIC7		IRQ_SPI(63)
-#define EXYNOS5_IRQ_IIC_HDMIPHY		IRQ_SPI(64)
-#define EXYNOS5_IRQ_TMU			IRQ_SPI(65)
-#define EXYNOS5_IRQ_FIQ_0		IRQ_SPI(66)
-#define EXYNOS5_IRQ_FIQ_1		IRQ_SPI(67)
-#define EXYNOS5_IRQ_SPI0		IRQ_SPI(68)
-#define EXYNOS5_IRQ_SPI1		IRQ_SPI(69)
-#define EXYNOS5_IRQ_SPI2		IRQ_SPI(70)
-#define EXYNOS5_IRQ_USB_HOST		IRQ_SPI(71)
-#define EXYNOS5_IRQ_USB3_DRD		IRQ_SPI(72)
-#define EXYNOS5_IRQ_MIPI_HSI		IRQ_SPI(73)
-#define EXYNOS5_IRQ_USB_HSOTG		IRQ_SPI(74)
-#define EXYNOS5_IRQ_HSMMC0		IRQ_SPI(75)
-#define EXYNOS5_IRQ_HSMMC1		IRQ_SPI(76)
-#define EXYNOS5_IRQ_HSMMC2		IRQ_SPI(77)
-#define EXYNOS5_IRQ_HSMMC3		IRQ_SPI(78)
-#define EXYNOS5_IRQ_MIPICSI0		IRQ_SPI(79)
-#define EXYNOS5_IRQ_MIPICSI1		IRQ_SPI(80)
-#define EXYNOS5_IRQ_EFNFCON_DMA_ABORT	IRQ_SPI(81)
-#define EXYNOS5_IRQ_MIPIDSI0		IRQ_SPI(82)
-#define EXYNOS5_IRQ_WDT_IOP		IRQ_SPI(83)
-#define EXYNOS5_IRQ_ROTATOR		IRQ_SPI(84)
-#define EXYNOS5_IRQ_GSC0		IRQ_SPI(85)
-#define EXYNOS5_IRQ_GSC1		IRQ_SPI(86)
-#define EXYNOS5_IRQ_GSC2		IRQ_SPI(87)
-#define EXYNOS5_IRQ_GSC3		IRQ_SPI(88)
-#define EXYNOS5_IRQ_JPEG		IRQ_SPI(89)
-#define EXYNOS5_IRQ_EFNFCON_DMA		IRQ_SPI(90)
-#define EXYNOS5_IRQ_2D			IRQ_SPI(91)
-#define EXYNOS5_IRQ_EFNFCON_0		IRQ_SPI(92)
-#define EXYNOS5_IRQ_EFNFCON_1		IRQ_SPI(93)
-#define EXYNOS5_IRQ_MIXER		IRQ_SPI(94)
-#define EXYNOS5_IRQ_HDMI		IRQ_SPI(95)
-#define EXYNOS5_IRQ_MFC			IRQ_SPI(96)
-#define EXYNOS5_IRQ_AUDIO_SS		IRQ_SPI(97)
-#define EXYNOS5_IRQ_I2S0		IRQ_SPI(98)
-#define EXYNOS5_IRQ_I2S1		IRQ_SPI(99)
-#define EXYNOS5_IRQ_I2S2		IRQ_SPI(100)
-#define EXYNOS5_IRQ_AC97		IRQ_SPI(101)
-#define EXYNOS5_IRQ_PCM0		IRQ_SPI(102)
-#define EXYNOS5_IRQ_PCM1		IRQ_SPI(103)
-#define EXYNOS5_IRQ_PCM2		IRQ_SPI(104)
-#define EXYNOS5_IRQ_SPDIF		IRQ_SPI(105)
-#define EXYNOS5_IRQ_ADC0		IRQ_SPI(106)
-#define EXYNOS5_IRQ_ADC1		IRQ_SPI(107)
-#define EXYNOS5_IRQ_SATA_PHY		IRQ_SPI(108)
-#define EXYNOS5_IRQ_SATA_PMEMREQ	IRQ_SPI(109)
-#define EXYNOS5_IRQ_CAM_C		IRQ_SPI(110)
-#define EXYNOS5_IRQ_EAGLE_PMU		IRQ_SPI(111)
-#define EXYNOS5_IRQ_INTFEEDCTRL_SSS	IRQ_SPI(112)
-#define EXYNOS5_IRQ_DP1_INTP1		IRQ_SPI(113)
-#define EXYNOS5_IRQ_CEC			IRQ_SPI(114)
-#define EXYNOS5_IRQ_SATA		IRQ_SPI(115)
-
-#define EXYNOS5_IRQ_MMC44		IRQ_SPI(123)
-#define EXYNOS5_IRQ_MDMA1		IRQ_SPI(124)
-#define EXYNOS5_IRQ_FIMC_LITE0		IRQ_SPI(125)
-#define EXYNOS5_IRQ_FIMC_LITE1		IRQ_SPI(126)
-#define EXYNOS5_IRQ_RP_TIMER		IRQ_SPI(127)
-
-/* EXYNOS5440 */
-
-#define EXYNOS5440_IRQ_UART0		IRQ_SPI(2)
-#define EXYNOS5440_IRQ_UART1		IRQ_SPI(3)
-
-#define EXYNOS5_IRQ_PMU			COMBINER_IRQ(1, 2)
-
-#define EXYNOS5_IRQ_SYSMMU_GSC0_0	COMBINER_IRQ(2, 0)
-#define EXYNOS5_IRQ_SYSMMU_GSC0_1	COMBINER_IRQ(2, 1)
-#define EXYNOS5_IRQ_SYSMMU_GSC1_0	COMBINER_IRQ(2, 2)
-#define EXYNOS5_IRQ_SYSMMU_GSC1_1	COMBINER_IRQ(2, 3)
-#define EXYNOS5_IRQ_SYSMMU_GSC2_0	COMBINER_IRQ(2, 4)
-#define EXYNOS5_IRQ_SYSMMU_GSC2_1	COMBINER_IRQ(2, 5)
-#define EXYNOS5_IRQ_SYSMMU_GSC3_0	COMBINER_IRQ(2, 6)
-#define EXYNOS5_IRQ_SYSMMU_GSC3_1	COMBINER_IRQ(2, 7)
-
-#define EXYNOS5_IRQ_SYSMMU_LITE2_0	COMBINER_IRQ(3, 0)
-#define EXYNOS5_IRQ_SYSMMU_LITE2_1	COMBINER_IRQ(3, 1)
-#define EXYNOS5_IRQ_SYSMMU_FIMD1_0	COMBINER_IRQ(3, 2)
-#define EXYNOS5_IRQ_SYSMMU_FIMD1_1	COMBINER_IRQ(3, 3)
-#define EXYNOS5_IRQ_SYSMMU_LITE0_0	COMBINER_IRQ(3, 4)
-#define EXYNOS5_IRQ_SYSMMU_LITE0_1	COMBINER_IRQ(3, 5)
-#define EXYNOS5_IRQ_SYSMMU_SCALERPISP_0	COMBINER_IRQ(3, 6)
-#define EXYNOS5_IRQ_SYSMMU_SCALERPISP_1	COMBINER_IRQ(3, 7)
-
-#define EXYNOS5_IRQ_SYSMMU_ROTATOR_0	COMBINER_IRQ(4, 0)
-#define EXYNOS5_IRQ_SYSMMU_ROTATOR_1	COMBINER_IRQ(4, 1)
-#define EXYNOS5_IRQ_SYSMMU_JPEG_0	COMBINER_IRQ(4, 2)
-#define EXYNOS5_IRQ_SYSMMU_JPEG_1	COMBINER_IRQ(4, 3)
-
-#define EXYNOS5_IRQ_SYSMMU_FD_0		COMBINER_IRQ(5, 0)
-#define EXYNOS5_IRQ_SYSMMU_FD_1		COMBINER_IRQ(5, 1)
-#define EXYNOS5_IRQ_SYSMMU_SCALERCISP_0	COMBINER_IRQ(5, 2)
-#define EXYNOS5_IRQ_SYSMMU_SCALERCISP_1	COMBINER_IRQ(5, 3)
-#define EXYNOS5_IRQ_SYSMMU_MCUISP_0	COMBINER_IRQ(5, 4)
-#define EXYNOS5_IRQ_SYSMMU_MCUISP_1	COMBINER_IRQ(5, 5)
-#define EXYNOS5_IRQ_SYSMMU_3DNR_0	COMBINER_IRQ(5, 6)
-#define EXYNOS5_IRQ_SYSMMU_3DNR_1	COMBINER_IRQ(5, 7)
-
-#define EXYNOS5_IRQ_SYSMMU_ARM_0	COMBINER_IRQ(6, 0)
-#define EXYNOS5_IRQ_SYSMMU_ARM_1	COMBINER_IRQ(6, 1)
-#define EXYNOS5_IRQ_SYSMMU_MFC_R_0	COMBINER_IRQ(6, 2)
-#define EXYNOS5_IRQ_SYSMMU_MFC_R_1	COMBINER_IRQ(6, 3)
-#define EXYNOS5_IRQ_SYSMMU_RTIC_0	COMBINER_IRQ(6, 4)
-#define EXYNOS5_IRQ_SYSMMU_RTIC_1	COMBINER_IRQ(6, 5)
-#define EXYNOS5_IRQ_SYSMMU_SSS_0	COMBINER_IRQ(6, 6)
-#define EXYNOS5_IRQ_SYSMMU_SSS_1	COMBINER_IRQ(6, 7)
-
-#define EXYNOS5_IRQ_SYSMMU_MDMA0_0	COMBINER_IRQ(7, 0)
-#define EXYNOS5_IRQ_SYSMMU_MDMA0_1	COMBINER_IRQ(7, 1)
-#define EXYNOS5_IRQ_SYSMMU_MDMA1_0	COMBINER_IRQ(7, 2)
-#define EXYNOS5_IRQ_SYSMMU_MDMA1_1	COMBINER_IRQ(7, 3)
-#define EXYNOS5_IRQ_SYSMMU_TV_0		COMBINER_IRQ(7, 4)
-#define EXYNOS5_IRQ_SYSMMU_TV_1		COMBINER_IRQ(7, 5)
-
-#define EXYNOS5_IRQ_SYSMMU_MFC_L_0	COMBINER_IRQ(8, 5)
-#define EXYNOS5_IRQ_SYSMMU_MFC_L_1	COMBINER_IRQ(8, 6)
-
-#define EXYNOS5_IRQ_SYSMMU_DIS1_0	COMBINER_IRQ(9, 4)
-#define EXYNOS5_IRQ_SYSMMU_DIS1_1	COMBINER_IRQ(9, 5)
-
-#define EXYNOS5_IRQ_DP			COMBINER_IRQ(10, 3)
-#define EXYNOS5_IRQ_SYSMMU_DIS0_0	COMBINER_IRQ(10, 4)
-#define EXYNOS5_IRQ_SYSMMU_DIS0_1	COMBINER_IRQ(10, 5)
-#define EXYNOS5_IRQ_SYSMMU_ISP_0	COMBINER_IRQ(10, 6)
-#define EXYNOS5_IRQ_SYSMMU_ISP_1	COMBINER_IRQ(10, 7)
-
-#define EXYNOS5_IRQ_SYSMMU_ODC_0	COMBINER_IRQ(11, 0)
-#define EXYNOS5_IRQ_SYSMMU_ODC_1	COMBINER_IRQ(11, 1)
-#define EXYNOS5_IRQ_SYSMMU_DRC_0	COMBINER_IRQ(11, 6)
-#define EXYNOS5_IRQ_SYSMMU_DRC_1	COMBINER_IRQ(11, 7)
-
-#define EXYNOS5_IRQ_MDMA1_ABORT		COMBINER_IRQ(13, 1)
-
-#define EXYNOS5_IRQ_MDMA0_ABORT		COMBINER_IRQ(15, 3)
-
-#define EXYNOS5_IRQ_FIMD1_FIFO		COMBINER_IRQ(18, 4)
-#define EXYNOS5_IRQ_FIMD1_VSYNC		COMBINER_IRQ(18, 5)
-#define EXYNOS5_IRQ_FIMD1_SYSTEM	COMBINER_IRQ(18, 6)
-
-#define EXYNOS5_IRQ_ARMIOP_GIC		COMBINER_IRQ(19, 0)
-#define EXYNOS5_IRQ_ARMISP_GIC		COMBINER_IRQ(19, 1)
-#define EXYNOS5_IRQ_IOP_GIC		COMBINER_IRQ(19, 3)
-#define EXYNOS5_IRQ_ISP_GIC		COMBINER_IRQ(19, 4)
-
-#define EXYNOS5_IRQ_PMU_CPU1		COMBINER_IRQ(22, 4)
-
-#define EXYNOS5_IRQ_EINT0		COMBINER_IRQ(23, 0)
-
-#define EXYNOS5_IRQ_EINT1		COMBINER_IRQ(24, 0)
-#define EXYNOS5_IRQ_SYSMMU_LITE1_0	COMBINER_IRQ(24, 1)
-#define EXYNOS5_IRQ_SYSMMU_LITE1_1	COMBINER_IRQ(24, 2)
-#define EXYNOS5_IRQ_SYSMMU_2D_0		COMBINER_IRQ(24, 5)
-#define EXYNOS5_IRQ_SYSMMU_2D_1		COMBINER_IRQ(24, 6)
-
-#define EXYNOS5_IRQ_EINT2		COMBINER_IRQ(25, 0)
-#define EXYNOS5_IRQ_EINT3		COMBINER_IRQ(25, 1)
-
-#define EXYNOS5_IRQ_EINT4		COMBINER_IRQ(26, 0)
-#define EXYNOS5_IRQ_EINT5		COMBINER_IRQ(26, 1)
-
-#define EXYNOS5_IRQ_EINT6		COMBINER_IRQ(27, 0)
-#define EXYNOS5_IRQ_EINT7		COMBINER_IRQ(27, 1)
-
-#define EXYNOS5_IRQ_EINT8		COMBINER_IRQ(28, 0)
-#define EXYNOS5_IRQ_EINT9		COMBINER_IRQ(28, 1)
-
-#define EXYNOS5_IRQ_EINT10		COMBINER_IRQ(29, 0)
-#define EXYNOS5_IRQ_EINT11		COMBINER_IRQ(29, 1)
-
-#define EXYNOS5_IRQ_EINT12		COMBINER_IRQ(30, 0)
-#define EXYNOS5_IRQ_EINT13		COMBINER_IRQ(30, 1)
-
-#define EXYNOS5_IRQ_EINT14		COMBINER_IRQ(31, 0)
-#define EXYNOS5_IRQ_EINT15		COMBINER_IRQ(31, 1)
-
-#define EXYNOS5_MAX_COMBINER_NR		32
-
-#define EXYNOS5_IRQ_GPIO1_NR_GROUPS	14
-#define EXYNOS5_IRQ_GPIO2_NR_GROUPS	9
-#define EXYNOS5_IRQ_GPIO3_NR_GROUPS	5
-#define EXYNOS5_IRQ_GPIO4_NR_GROUPS	1
-
-#define MAX_COMBINER_NR			(EXYNOS4_MAX_COMBINER_NR > EXYNOS5_MAX_COMBINER_NR ? \
-					EXYNOS4_MAX_COMBINER_NR : EXYNOS5_MAX_COMBINER_NR)
-
-#define S5P_EINT_BASE1			COMBINER_IRQ(MAX_COMBINER_NR, 0)
-#define S5P_EINT_BASE2			(S5P_EINT_BASE1 + 16)
-#define S5P_GPIOINT_BASE		(S5P_EINT_BASE1 + 32)
-#define IRQ_GPIO_END			(S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
-#define IRQ_TIMER_BASE			(IRQ_GPIO_END + 64)
-
-/* Set the default NR_IRQS */
-#define EXYNOS_NR_IRQS			(IRQ_TIMER_BASE + IRQ_TIMER_COUNT)
-
-#ifndef CONFIG_SPARSE_IRQ
-#define NR_IRQS				EXYNOS_NR_IRQS
-#endif
-
-#endif /* __ASM_ARCH_IRQS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/map.h linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/map.h
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/map.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/map.h	2013-08-25 20:43:22.000000000 -0400
@@ -30,31 +30,6 @@
 #define EXYNOS4x12_PA_SYSRAM_NS		0x0204F000
 #define EXYNOS5250_PA_SYSRAM_NS		0x0204F000
 
-#define EXYNOS4_PA_FIMC0		0x11800000
-#define EXYNOS4_PA_FIMC1		0x11810000
-#define EXYNOS4_PA_FIMC2		0x11820000
-#define EXYNOS4_PA_FIMC3		0x11830000
-
-#define EXYNOS4_PA_JPEG			0x11840000
-
-/* x = 0...1 */
-#define EXYNOS4_PA_FIMC_LITE(x)		(0x12390000 + ((x) * 0x10000))
-
-#define EXYNOS4_PA_G2D			0x12800000
-
-#define EXYNOS4_PA_I2S0			0x03830000
-#define EXYNOS4_PA_I2S1			0xE3100000
-#define EXYNOS4_PA_I2S2			0xE2A00000
-
-#define EXYNOS4_PA_PCM0			0x03840000
-#define EXYNOS4_PA_PCM1			0x13980000
-#define EXYNOS4_PA_PCM2			0x13990000
-
-#define EXYNOS4_PA_SROM_BANK(x)		(0x04000000 + ((x) * 0x01000000))
-
-#define EXYNOS4_PA_ONENAND		0x0C000000
-#define EXYNOS4_PA_ONENAND_DMA		0x0C600000
-
 #define EXYNOS_PA_CHIPID		0x10000000
 
 #define EXYNOS4_PA_SYSCON		0x10010000
@@ -71,10 +46,6 @@
 #define EXYNOS4_PA_WATCHDOG		0x10060000
 #define EXYNOS5_PA_WATCHDOG		0x101D0000
 
-#define EXYNOS4_PA_RTC			0x10070000
-
-#define EXYNOS4_PA_KEYPAD		0x100A0000
-
 #define EXYNOS4_PA_DMC0			0x10400000
 #define EXYNOS4_PA_DMC1			0x10410000
 
@@ -87,207 +58,22 @@
 #define EXYNOS5_PA_GIC_DIST		0x10481000
 
 #define EXYNOS4_PA_COREPERI		0x10500000
-#define EXYNOS4_PA_TWD			0x10500600
 #define EXYNOS4_PA_L2CC			0x10502000
 
-#define EXYNOS4_PA_TMU			0x100C0000
-
-#define EXYNOS4_PA_MDMA0		0x10810000
-#define EXYNOS4_PA_MDMA1		0x12850000
-#define EXYNOS4_PA_S_MDMA1		0x12840000
-#define EXYNOS4_PA_PDMA0		0x12680000
-#define EXYNOS4_PA_PDMA1		0x12690000
-#define EXYNOS5_PA_MDMA0		0x10800000
-#define EXYNOS5_PA_MDMA1		0x11C10000
-#define EXYNOS5_PA_PDMA0		0x121A0000
-#define EXYNOS5_PA_PDMA1		0x121B0000
-
-#define EXYNOS4_PA_SYSMMU_MDMA		0x10A40000
-#define EXYNOS4_PA_SYSMMU_2D_ACP	0x10A40000
-#define EXYNOS4_PA_SYSMMU_SSS		0x10A50000
-#define EXYNOS4_PA_SYSMMU_FIMC0		0x11A20000
-#define EXYNOS4_PA_SYSMMU_FIMC1		0x11A30000
-#define EXYNOS4_PA_SYSMMU_FIMC2		0x11A40000
-#define EXYNOS4_PA_SYSMMU_FIMC3		0x11A50000
-#define EXYNOS4_PA_SYSMMU_JPEG		0x11A60000
-#define EXYNOS4_PA_SYSMMU_FIMD0		0x11E20000
-#define EXYNOS4_PA_SYSMMU_FIMD1		0x12220000
-#define EXYNOS4_PA_SYSMMU_FIMC_ISP	0x12260000
-#define EXYNOS4_PA_SYSMMU_FIMC_DRC	0x12270000
-#define EXYNOS4_PA_SYSMMU_FIMC_FD	0x122A0000
-#define EXYNOS4_PA_SYSMMU_ISPCPU	0x122B0000
-#define EXYNOS4_PA_SYSMMU_FIMC_LITE0	0x123B0000
-#define EXYNOS4_PA_SYSMMU_FIMC_LITE1	0x123C0000
-#define EXYNOS4_PA_SYSMMU_PCIe		0x12620000
-#define EXYNOS4_PA_SYSMMU_G2D		0x12A20000
-#define EXYNOS4_PA_SYSMMU_ROTATOR	0x12A30000
-#define EXYNOS4_PA_SYSMMU_MDMA2		0x12A40000
-#define EXYNOS4_PA_SYSMMU_TV		0x12E20000
-#define EXYNOS4_PA_SYSMMU_MFC_L		0x13620000
-#define EXYNOS4_PA_SYSMMU_MFC_R		0x13630000
-
-#define EXYNOS5_PA_GSC0			0x13E00000
-#define EXYNOS5_PA_GSC1			0x13E10000
-#define EXYNOS5_PA_GSC2			0x13E20000
-#define EXYNOS5_PA_GSC3			0x13E30000
-
-#define EXYNOS5_PA_SYSMMU_MDMA1		0x10A40000
-#define EXYNOS5_PA_SYSMMU_SSS		0x10A50000
-#define EXYNOS5_PA_SYSMMU_2D		0x10A60000
-#define EXYNOS5_PA_SYSMMU_MFC_L		0x11200000
-#define EXYNOS5_PA_SYSMMU_MFC_R		0x11210000
-#define EXYNOS5_PA_SYSMMU_ROTATOR	0x11D40000
-#define EXYNOS5_PA_SYSMMU_MDMA2		0x11D50000
-#define EXYNOS5_PA_SYSMMU_JPEG		0x11F20000
-#define EXYNOS5_PA_SYSMMU_IOP		0x12360000
-#define EXYNOS5_PA_SYSMMU_RTIC		0x12370000
-#define EXYNOS5_PA_SYSMMU_ISP		0x13260000
-#define EXYNOS5_PA_SYSMMU_DRC		0x12370000
-#define EXYNOS5_PA_SYSMMU_SCALERC	0x13280000
-#define EXYNOS5_PA_SYSMMU_SCALERP	0x13290000
-#define EXYNOS5_PA_SYSMMU_FD		0x132A0000
-#define EXYNOS5_PA_SYSMMU_ISPCPU	0x132B0000
-#define EXYNOS5_PA_SYSMMU_ODC		0x132C0000
-#define EXYNOS5_PA_SYSMMU_DIS0		0x132D0000
-#define EXYNOS5_PA_SYSMMU_DIS1		0x132E0000
-#define EXYNOS5_PA_SYSMMU_3DNR		0x132F0000
-#define EXYNOS5_PA_SYSMMU_LITE0		0x13C40000
-#define EXYNOS5_PA_SYSMMU_LITE1		0x13C50000
-#define EXYNOS5_PA_SYSMMU_GSC0		0x13E80000
-#define EXYNOS5_PA_SYSMMU_GSC1		0x13E90000
-#define EXYNOS5_PA_SYSMMU_GSC2		0x13EA0000
-#define EXYNOS5_PA_SYSMMU_GSC3		0x13EB0000
-#define EXYNOS5_PA_SYSMMU_FIMD1		0x14640000
-#define EXYNOS5_PA_SYSMMU_TV		0x14650000
-
-#define EXYNOS4_PA_SPI0			0x13920000
-#define EXYNOS4_PA_SPI1			0x13930000
-#define EXYNOS4_PA_SPI2			0x13940000
-#define EXYNOS5_PA_SPI0			0x12D20000
-#define EXYNOS5_PA_SPI1			0x12D30000
-#define EXYNOS5_PA_SPI2			0x12D40000
-
-#define EXYNOS4_PA_GPIO1		0x11400000
-#define EXYNOS4_PA_GPIO2		0x11000000
-#define EXYNOS4_PA_GPIO3		0x03860000
-#define EXYNOS5_PA_GPIO1		0x11400000
-#define EXYNOS5_PA_GPIO2		0x13400000
-#define EXYNOS5_PA_GPIO3		0x10D10000
-#define EXYNOS5_PA_GPIO4		0x03860000
-
-#define EXYNOS4_PA_MIPI_CSIS0		0x11880000
-#define EXYNOS4_PA_MIPI_CSIS1		0x11890000
-
-#define EXYNOS4_PA_FIMD0		0x11C00000
-
-#define EXYNOS4_PA_HSMMC(x)		(0x12510000 + ((x) * 0x10000))
-#define EXYNOS4_PA_DWMCI		0x12550000
-#define EXYNOS5_PA_DWMCI0		0x12200000
-#define EXYNOS5_PA_DWMCI1		0x12210000
-#define EXYNOS5_PA_DWMCI2		0x12220000
-#define EXYNOS5_PA_DWMCI3		0x12230000
-
-#define EXYNOS4_PA_HSOTG		0x12480000
-#define EXYNOS4_PA_USB_HSPHY		0x125B0000
-
-#define EXYNOS4_PA_SATA			0x12560000
-#define EXYNOS4_PA_SATAPHY		0x125D0000
-#define EXYNOS4_PA_SATAPHY_CTRL		0x126B0000
-
 #define EXYNOS4_PA_SROMC		0x12570000
 #define EXYNOS5_PA_SROMC		0x12250000
 
-#define EXYNOS4_PA_EHCI			0x12580000
-#define EXYNOS4_PA_OHCI			0x12590000
 #define EXYNOS4_PA_HSPHY		0x125B0000
-#define EXYNOS4_PA_MFC			0x13400000
 
 #define EXYNOS4_PA_UART			0x13800000
 #define EXYNOS5_PA_UART			0x12C00000
 
-#define EXYNOS4_PA_VP			0x12C00000
-#define EXYNOS4_PA_MIXER		0x12C10000
-#define EXYNOS4_PA_SDO			0x12C20000
-#define EXYNOS4_PA_HDMI			0x12D00000
-#define EXYNOS4_PA_IIC_HDMIPHY		0x138E0000
-
-#define EXYNOS4_PA_IIC(x)		(0x13860000 + ((x) * 0x10000))
-#define EXYNOS5_PA_IIC(x)		(0x12C60000 + ((x) * 0x10000))
-
-#define EXYNOS4_PA_ADC			0x13910000
-#define EXYNOS4_PA_ADC1			0x13911000
-
-#define EXYNOS4_PA_AC97			0x139A0000
-
-#define EXYNOS4_PA_SPDIF		0x139B0000
-
 #define EXYNOS4_PA_TIMER		0x139D0000
 #define EXYNOS5_PA_TIMER		0x12DD0000
 
-#define EXYNOS4_PA_SDRAM		0x40000000
-#define EXYNOS5_PA_SDRAM		0x40000000
-
-/* Compatibiltiy Defines */
-
-#define S3C_PA_HSMMC0			EXYNOS4_PA_HSMMC(0)
-#define S3C_PA_HSMMC1			EXYNOS4_PA_HSMMC(1)
-#define S3C_PA_HSMMC2			EXYNOS4_PA_HSMMC(2)
-#define S3C_PA_HSMMC3			EXYNOS4_PA_HSMMC(3)
-#define S3C_PA_IIC			EXYNOS4_PA_IIC(0)
-#define S3C_PA_IIC1			EXYNOS4_PA_IIC(1)
-#define S3C_PA_IIC2			EXYNOS4_PA_IIC(2)
-#define S3C_PA_IIC3			EXYNOS4_PA_IIC(3)
-#define S3C_PA_IIC4			EXYNOS4_PA_IIC(4)
-#define S3C_PA_IIC5			EXYNOS4_PA_IIC(5)
-#define S3C_PA_IIC6			EXYNOS4_PA_IIC(6)
-#define S3C_PA_IIC7			EXYNOS4_PA_IIC(7)
-#define S3C_PA_RTC			EXYNOS4_PA_RTC
-#define S3C_PA_WDT			EXYNOS4_PA_WATCHDOG
-#define S3C_PA_SPI0			EXYNOS4_PA_SPI0
-#define S3C_PA_SPI1			EXYNOS4_PA_SPI1
-#define S3C_PA_SPI2			EXYNOS4_PA_SPI2
-#define S3C_PA_USB_HSOTG		EXYNOS4_PA_HSOTG
-
-#define S5P_PA_EHCI			EXYNOS4_PA_EHCI
-#define S5P_PA_FIMC0			EXYNOS4_PA_FIMC0
-#define S5P_PA_FIMC1			EXYNOS4_PA_FIMC1
-#define S5P_PA_FIMC2			EXYNOS4_PA_FIMC2
-#define S5P_PA_FIMC3			EXYNOS4_PA_FIMC3
-#define S5P_PA_JPEG			EXYNOS4_PA_JPEG
-#define S5P_PA_G2D			EXYNOS4_PA_G2D
-#define S5P_PA_FIMD0			EXYNOS4_PA_FIMD0
-#define S5P_PA_HDMI			EXYNOS4_PA_HDMI
-#define S5P_PA_IIC_HDMIPHY		EXYNOS4_PA_IIC_HDMIPHY
-#define S5P_PA_MFC			EXYNOS4_PA_MFC
-#define S5P_PA_MIPI_CSIS0		EXYNOS4_PA_MIPI_CSIS0
-#define S5P_PA_MIPI_CSIS1		EXYNOS4_PA_MIPI_CSIS1
-#define S5P_PA_MIXER			EXYNOS4_PA_MIXER
-#define S5P_PA_ONENAND			EXYNOS4_PA_ONENAND
-#define S5P_PA_ONENAND_DMA		EXYNOS4_PA_ONENAND_DMA
-#define S5P_PA_SDO			EXYNOS4_PA_SDO
-#define S5P_PA_SDRAM			EXYNOS4_PA_SDRAM
-#define S5P_PA_VP			EXYNOS4_PA_VP
-
-#define SAMSUNG_PA_ADC			EXYNOS4_PA_ADC
-#define SAMSUNG_PA_ADC1			EXYNOS4_PA_ADC1
-#define SAMSUNG_PA_KEYPAD		EXYNOS4_PA_KEYPAD
-
 /* Compatibility UART */
 
-#define EXYNOS4_PA_UART0		0x13800000
-#define EXYNOS4_PA_UART1		0x13810000
-#define EXYNOS4_PA_UART2		0x13820000
-#define EXYNOS4_PA_UART3		0x13830000
-#define EXYNOS4_SZ_UART			SZ_256
-
-#define EXYNOS5_PA_UART0		0x12C00000
-#define EXYNOS5_PA_UART1		0x12C10000
-#define EXYNOS5_PA_UART2		0x12C20000
-#define EXYNOS5_PA_UART3		0x12C30000
-
 #define EXYNOS5440_PA_UART0		0x000B0000
-#define EXYNOS5440_PA_UART1		0x000C0000
-#define EXYNOS5440_SZ_UART		SZ_256
 
 #define S3C_VA_UARTx(x)			(S3C_VA_UART + ((x) * S3C_UART_OFFSET))
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/memory.h linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/memory.h
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/memory.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/memory.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,8 +15,13 @@
 
 #define PLAT_PHYS_OFFSET		UL(0x40000000)
 
+#ifndef CONFIG_ARM_LPAE
 /* Maximum of 256MiB in one bank */
 #define MAX_PHYSMEM_BITS	32
 #define SECTION_SIZE_BITS	28
+#else
+#define MAX_PHYSMEM_BITS	36
+#define SECTION_SIZE_BITS	31
+#endif
 
 #endif /* __ASM_ARCH_MEMORY_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/pm-core.h linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/pm-core.h
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/pm-core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/pm-core.h	2013-08-25 20:43:22.000000000 -0400
@@ -34,12 +34,7 @@ static inline void s3c_pm_debug_init_uar
 
 static inline void s3c_pm_arch_prepare_irqs(void)
 {
-	u32 eintmask = s3c_irqwake_eintmask;
-
-	if (of_have_populated_dt())
-		eintmask = exynos_get_eint_wake_mask();
-
-	__raw_writel(eintmask, S5P_EINT_WAKEUP_MASK);
+	__raw_writel(exynos_get_eint_wake_mask(), S5P_EINT_WAKEUP_MASK);
 	__raw_writel(s3c_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
 }
 
@@ -69,4 +64,9 @@ static inline void samsung_pm_saved_gpio
 	/* nothing here yet */
 }
 
+/* Compatibility definitions to make plat-samsung/pm.c compile */
+#define IRQ_EINT_BIT(x)		1
+#define s3c_irqwake_intallow	0
+#define s3c_irqwake_eintallow	0
+
 #endif /* __ASM_ARCH_PM_CORE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/regs-gpio.h linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/regs-gpio.h
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/regs-gpio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/regs-gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-gpio.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS4 - GPIO (including EINT) register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_GPIO_H
-#define __ASM_ARCH_REGS_GPIO_H __FILE__
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-
-#define EINT_REG_NR(x)			(EINT_OFFSET(x) >> 3)
-#define EINT_CON(b, x)			(b + 0xE00 + (EINT_REG_NR(x) * 4))
-#define EINT_FLTCON(b, x)		(b + 0xE80 + (EINT_REG_NR(x) * 4))
-#define EINT_MASK(b, x)			(b + 0xF00 + (EINT_REG_NR(x) * 4))
-#define EINT_PEND(b, x)			(b + 0xF40 + (EINT_REG_NR(x) * 4))
-
-#define EINT_OFFSET_BIT(x)		(1 << (EINT_OFFSET(x) & 0x7))
-
-/* compatibility for plat-s5p/irq-pm.c */
-#define EXYNOS4_EINT40CON		(S5P_VA_GPIO2 + 0xE00)
-#define S5P_EINT_CON(x)			(EXYNOS4_EINT40CON + ((x) * 0x4))
-
-#define EXYNOS4_EINT40FLTCON0		(S5P_VA_GPIO2 + 0xE80)
-#define S5P_EINT_FLTCON(x)		(EXYNOS4_EINT40FLTCON0 + ((x) * 0x4))
-
-#define EXYNOS4_EINT40MASK		(S5P_VA_GPIO2 + 0xF00)
-#define S5P_EINT_MASK(x)		(EXYNOS4_EINT40MASK + ((x) * 0x4))
-
-#define EXYNOS4_EINT40PEND		(S5P_VA_GPIO2 + 0xF40)
-#define S5P_EINT_PEND(x)		(EXYNOS4_EINT40PEND + ((x) * 0x4))
-
-#endif /* __ASM_ARCH_REGS_GPIO_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/regs-usb-phy.h linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/regs-usb-phy.h
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/regs-usb-phy.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/regs-usb-phy.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifndef __PLAT_S5P_REGS_USB_PHY_H
-#define __PLAT_S5P_REGS_USB_PHY_H
-
-#define EXYNOS4_HSOTG_PHYREG(x)		((x) + S3C_VA_USB_HSPHY)
-
-#define EXYNOS4_PHYPWR			EXYNOS4_HSOTG_PHYREG(0x00)
-#define PHY1_HSIC_NORMAL_MASK		(0xf << 9)
-#define PHY1_HSIC1_SLEEP		(1 << 12)
-#define PHY1_HSIC1_FORCE_SUSPEND	(1 << 11)
-#define PHY1_HSIC0_SLEEP		(1 << 10)
-#define PHY1_HSIC0_FORCE_SUSPEND	(1 << 9)
-
-#define PHY1_STD_NORMAL_MASK		(0x7 << 6)
-#define PHY1_STD_SLEEP			(1 << 8)
-#define PHY1_STD_ANALOG_POWERDOWN	(1 << 7)
-#define PHY1_STD_FORCE_SUSPEND		(1 << 6)
-
-#define PHY0_NORMAL_MASK		(0x39 << 0)
-#define PHY0_SLEEP			(1 << 5)
-#define PHY0_OTG_DISABLE		(1 << 4)
-#define PHY0_ANALOG_POWERDOWN		(1 << 3)
-#define PHY0_FORCE_SUSPEND		(1 << 0)
-
-#define EXYNOS4_PHYCLK			EXYNOS4_HSOTG_PHYREG(0x04)
-#define PHY1_COMMON_ON_N		(1 << 7)
-#define PHY0_COMMON_ON_N		(1 << 4)
-#define PHY0_ID_PULLUP			(1 << 2)
-
-#define EXYNOS4_CLKSEL_SHIFT		(0)
-
-#define EXYNOS4210_CLKSEL_MASK		(0x3 << 0)
-#define EXYNOS4210_CLKSEL_48M		(0x0 << 0)
-#define EXYNOS4210_CLKSEL_12M		(0x2 << 0)
-#define EXYNOS4210_CLKSEL_24M		(0x3 << 0)
-
-#define EXYNOS4X12_CLKSEL_MASK		(0x7 << 0)
-#define EXYNOS4X12_CLKSEL_9600K		(0x0 << 0)
-#define EXYNOS4X12_CLKSEL_10M		(0x1 << 0)
-#define EXYNOS4X12_CLKSEL_12M		(0x2 << 0)
-#define EXYNOS4X12_CLKSEL_19200K	(0x3 << 0)
-#define EXYNOS4X12_CLKSEL_20M		(0x4 << 0)
-#define EXYNOS4X12_CLKSEL_24M		(0x5 << 0)
-
-#define EXYNOS4_RSTCON			EXYNOS4_HSOTG_PHYREG(0x08)
-#define HOST_LINK_PORT_SWRST_MASK	(0xf << 6)
-#define HOST_LINK_PORT2_SWRST		(1 << 9)
-#define HOST_LINK_PORT1_SWRST		(1 << 8)
-#define HOST_LINK_PORT0_SWRST		(1 << 7)
-#define HOST_LINK_ALL_SWRST		(1 << 6)
-
-#define PHY1_SWRST_MASK			(0x7 << 3)
-#define PHY1_HSIC_SWRST			(1 << 5)
-#define PHY1_STD_SWRST			(1 << 4)
-#define PHY1_ALL_SWRST			(1 << 3)
-
-#define PHY0_SWRST_MASK			(0x7 << 0)
-#define PHY0_PHYLINK_SWRST		(1 << 2)
-#define PHY0_HLINK_SWRST		(1 << 1)
-#define PHY0_SWRST			(1 << 0)
-
-#define EXYNOS4_PHY1CON			EXYNOS4_HSOTG_PHYREG(0x34)
-#define FPENABLEN			(1 << 0)
-
-#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/uncompress.h linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/uncompress.h
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/include/mach/uncompress.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/include/mach/uncompress.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,9 +15,6 @@
 #include <asm/mach-types.h>
 
 #include <mach/map.h>
-
-volatile u8 *uart_base;
-
 #include <plat/uncompress.h>
 
 static unsigned int __raw_readl(unsigned int ptr)
@@ -31,13 +28,12 @@ static void arch_detect_cpu(void)
 
 	/*
 	 * product_id is bits 31:12
-	 *    bits 23:20 describe the exynosX family
-	 *
+	 * bits 23:20 describe the exynosX family
+	 * bits 27:24 describe the exynosX family in exynos5420
 	 */
 	chip_id >>= 20;
-	chip_id &= 0xf;
 
-	if (chip_id == 0x5)
+	if ((chip_id & 0x0f) == 0x5 || (chip_id & 0xf0) == 0x50)
 		uart_base = (volatile u8 *)EXYNOS5_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
 	else
 		uart_base = (volatile u8 *)EXYNOS4_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -14,9 +14,11 @@ menu "SAMSUNG EXYNOS SoCs Support"
 config ARCH_EXYNOS4
 	bool "SAMSUNG EXYNOS4"
 	default y
+	select GIC_NON_BANKED
 	select HAVE_ARM_SCU if SMP
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
+	select PINCTRL
 	help
 	  Samsung EXYNOS4 SoCs based systems
 
@@ -24,6 +26,7 @@ config ARCH_EXYNOS5
 	bool "SAMSUNG EXYNOS5"
 	select HAVE_ARM_SCU if SMP
 	select HAVE_SMP
+	select PINCTRL
 	help
 	  Samsung EXYNOS5 (Cortex-A15) SoC based systems
 
@@ -34,7 +37,8 @@ config CPU_EXYNOS4210
 	default y
 	depends on ARCH_EXYNOS4
 	select ARM_CPU_SUSPEND if PM
-	select PM_GENERIC_DOMAINS
+	select PINCTRL_EXYNOS
+	select PM_GENERIC_DOMAINS if PM
 	select S5P_PM if PM
 	select S5P_SLEEP if PM
 	select SAMSUNG_DMADEV
@@ -45,6 +49,7 @@ config SOC_EXYNOS4212
 	bool "SAMSUNG EXYNOS4212"
 	default y
 	depends on ARCH_EXYNOS4
+	select PINCTRL_EXYNOS
 	select S5P_PM if PM
 	select S5P_SLEEP if PM
 	select SAMSUNG_DMADEV
@@ -55,6 +60,7 @@ config SOC_EXYNOS4412
 	bool "SAMSUNG EXYNOS4412"
 	default y
 	depends on ARCH_EXYNOS4
+	select PINCTRL_EXYNOS
 	select SAMSUNG_DMADEV
 	help
 	  Enable EXYNOS4412 SoC support
@@ -63,6 +69,7 @@ config SOC_EXYNOS5250
 	bool "SAMSUNG EXYNOS5250"
 	default y
 	depends on ARCH_EXYNOS5
+	select PINCTRL_EXYNOS
 	select PM_GENERIC_DOMAINS if PM
 	select S5P_PM if PM
 	select S5P_SLEEP if PM
@@ -71,352 +78,43 @@ config SOC_EXYNOS5250
 	help
 	  Enable EXYNOS5250 SoC support
 
+config SOC_EXYNOS5420
+	bool "SAMSUNG EXYNOS5420"
+	default y
+	depends on ARCH_EXYNOS5
+	select PM_GENERIC_DOMAINS if PM
+	select S5P_PM if PM
+	select S5P_SLEEP if PM
+	help
+	  Enable EXYNOS5420 SoC support
+
 config SOC_EXYNOS5440
 	bool "SAMSUNG EXYNOS5440"
 	default y
 	depends on ARCH_EXYNOS5
+	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
 	select ARCH_HAS_OPP
-	select ARM_ARCH_TIMER
+	select HAVE_ARM_ARCH_TIMER
 	select AUTO_ZRELADDR
-	select PINCTRL
+	select MIGHT_HAVE_PCI
+	select PCI_DOMAINS if PCI
 	select PINCTRL_EXYNOS5440
 	select PM_OPP
 	help
 	  Enable EXYNOS5440 SoC support
 
-config EXYNOS_ATAGS
-	bool "ATAGS based boot for EXYNOS (deprecated)"
-	depends on !ARCH_MULTIPLATFORM
-	depends on ATAGS
-	default y
-	help
-	  The EXYNOS platform is moving towards being completely probed
-	  through device tree. This enables support for board files using
-	  the traditional ATAGS boot format.
-	  Note that this option is not available for multiplatform builds.
-
-if EXYNOS_ATAGS
-
-config EXYNOS_DEV_DMA
-	bool
-	help
-	  Compile in amba device definitions for DMA controller
-
-config EXYNOS4_DEV_AHCI
-	bool
-	help
-	  Compile in platform device definitions for AHCI
-
-config EXYNOS4_SETUP_FIMD0
-	bool
-	help
-	  Common setup code for FIMD0.
-
-config EXYNOS4_DEV_USB_OHCI
-	bool
-	help
-	  Compile in platform device definition for USB OHCI
-
-config EXYNOS4_SETUP_I2C1
-	bool
-	help
-	  Common setup code for i2c bus 1.
-
-config EXYNOS4_SETUP_I2C2
-	bool
-	help
-	  Common setup code for i2c bus 2.
-
-config EXYNOS4_SETUP_I2C3
-	bool
-	help
-	  Common setup code for i2c bus 3.
-
-config EXYNOS4_SETUP_I2C4
-	bool
-	help
-	  Common setup code for i2c bus 4.
-
-config EXYNOS4_SETUP_I2C5
-	bool
-	help
-	  Common setup code for i2c bus 5.
-
-config EXYNOS4_SETUP_I2C6
-	bool
-	help
-	  Common setup code for i2c bus 6.
-
-config EXYNOS4_SETUP_I2C7
-	bool
-	help
-	  Common setup code for i2c bus 7.
-
-config EXYNOS4_SETUP_KEYPAD
-	bool
-	help
-	  Common setup code for keypad.
-
-config EXYNOS4_SETUP_SDHCI
-	bool
-	select EXYNOS4_SETUP_SDHCI_GPIO
-	help
-	  Internal helper functions for EXYNOS4 based SDHCI systems.
-
-config EXYNOS4_SETUP_SDHCI_GPIO
-	bool
-	help
-	  Common setup code for SDHCI gpio.
-
-config EXYNOS4_SETUP_FIMC
-	bool
-	help
-	  Common setup code for the camera interfaces.
-
-config EXYNOS4_SETUP_USB_PHY
-	bool
-	help
-	  Common setup code for USB PHY controller
-
-config EXYNOS_SETUP_SPI
-	bool
-	help
-	  Common setup code for SPI GPIO configurations.
-
-# machine support
-
-if ARCH_EXYNOS4
-
-comment "EXYNOS4210 Boards"
-
-config MACH_SMDKC210
-	bool "SMDKC210"
-	select MACH_SMDKV310
-	help
-	  Machine support for Samsung SMDKC210
-
-config MACH_SMDKV310
-	bool "SMDKV310"
-	select CPU_EXYNOS4210
-	select EXYNOS4_DEV_AHCI
-	select EXYNOS4_DEV_USB_OHCI
-	select EXYNOS4_SETUP_FIMD0
-	select EXYNOS4_SETUP_I2C1
-	select EXYNOS4_SETUP_KEYPAD
-	select EXYNOS4_SETUP_SDHCI
-	select EXYNOS4_SETUP_USB_PHY
-	select EXYNOS_DEV_DMA
-	select EXYNOS_DEV_SYSMMU
-	select S3C24XX_PWM
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC1
-	select S3C_DEV_HSMMC2
-	select S3C_DEV_HSMMC3
-	select S3C_DEV_I2C1
-	select S3C_DEV_RTC
-	select S3C_DEV_USB_HSOTG
-	select S3C_DEV_WDT
-	select S5P_DEV_FIMC0
-	select S5P_DEV_FIMC1
-	select S5P_DEV_FIMC2
-	select S5P_DEV_FIMC3
-	select S5P_DEV_FIMD0
-	select S5P_DEV_G2D
-	select S5P_DEV_I2C_HDMIPHY
-	select S5P_DEV_JPEG
-	select S5P_DEV_MFC
-	select S5P_DEV_TV
-	select S5P_DEV_USB_EHCI
-	select SAMSUNG_DEV_BACKLIGHT
-	select SAMSUNG_DEV_KEYPAD
-	select SAMSUNG_DEV_PWM
-	help
-	  Machine support for Samsung SMDKV310
-
-config MACH_ARMLEX4210
-	bool "ARMLEX4210"
-	select CPU_EXYNOS4210
-	select EXYNOS4_DEV_AHCI
-	select EXYNOS4_SETUP_SDHCI
-	select EXYNOS_DEV_DMA
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC2
-	select S3C_DEV_HSMMC3
-	select S3C_DEV_RTC
-	select S3C_DEV_WDT
-	help
-	  Machine support for Samsung ARMLEX4210 based on EXYNOS4210
-
-config MACH_UNIVERSAL_C210
-	bool "Mobile UNIVERSAL_C210 Board"
-	select CLKSRC_MMIO
-	select CLKSRC_SAMSUNG_PWM
-	select CPU_EXYNOS4210
-	select EXYNOS4_SETUP_FIMC
-	select EXYNOS4_SETUP_FIMD0
-	select EXYNOS4_SETUP_I2C1
-	select EXYNOS4_SETUP_I2C3
-	select EXYNOS4_SETUP_I2C5
-	select EXYNOS4_SETUP_SDHCI
-	select EXYNOS4_SETUP_USB_PHY
-	select EXYNOS_DEV_DMA
-	select EXYNOS_DEV_SYSMMU
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC2
-	select S3C_DEV_HSMMC3
-	select S3C_DEV_I2C1
-	select S3C_DEV_I2C3
-	select S3C_DEV_I2C5
-	select S3C_DEV_USB_HSOTG
-	select S5P_DEV_CSIS0
-	select S5P_DEV_FIMC0
-	select S5P_DEV_FIMC1
-	select S5P_DEV_FIMC2
-	select S5P_DEV_FIMC3
-	select S5P_DEV_FIMD0
-	select S5P_DEV_G2D
-	select S5P_DEV_I2C_HDMIPHY
-	select S5P_DEV_JPEG
-	select S5P_DEV_MFC
-	select S5P_DEV_ONENAND
-	select S5P_DEV_TV
-	select S5P_GPIO_INT
-	select S5P_SETUP_MIPIPHY
-	help
-	  Machine support for Samsung Mobile Universal S5PC210 Reference
-	  Board.
-
-config MACH_NURI
-	bool "Mobile NURI Board"
-	select CPU_EXYNOS4210
-	select EXYNOS4_SETUP_FIMC
-	select EXYNOS4_SETUP_FIMD0
-	select EXYNOS4_SETUP_I2C1
-	select EXYNOS4_SETUP_I2C3
-	select EXYNOS4_SETUP_I2C5
-	select EXYNOS4_SETUP_I2C6
-	select EXYNOS4_SETUP_SDHCI
-	select EXYNOS4_SETUP_USB_PHY
-	select EXYNOS_DEV_DMA
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC2
-	select S3C_DEV_HSMMC3
-	select S3C_DEV_I2C1
-	select S3C_DEV_I2C3
-	select S3C_DEV_I2C5
-	select S3C_DEV_I2C6
-	select S3C_DEV_RTC
-	select S3C_DEV_USB_HSOTG
-	select S3C_DEV_WDT
-	select S5P_DEV_CSIS0
-	select S5P_DEV_FIMC0
-	select S5P_DEV_FIMC1
-	select S5P_DEV_FIMC2
-	select S5P_DEV_FIMC3
-	select S5P_DEV_FIMD0
-	select S5P_DEV_G2D
-	select S5P_DEV_JPEG
-	select S5P_DEV_MFC
-	select S5P_DEV_USB_EHCI
-	select S5P_GPIO_INT
-	select S5P_SETUP_MIPIPHY
-	select SAMSUNG_DEV_ADC
-	select SAMSUNG_DEV_PWM
-	help
-	  Machine support for Samsung Mobile NURI Board.
-
-config MACH_ORIGEN
-	bool "ORIGEN"
-	select CPU_EXYNOS4210
-	select EXYNOS4_DEV_USB_OHCI
-	select EXYNOS4_SETUP_FIMD0
-	select EXYNOS4_SETUP_SDHCI
-	select EXYNOS4_SETUP_USB_PHY
-	select EXYNOS_DEV_DMA
-	select EXYNOS_DEV_SYSMMU
-	select S3C24XX_PWM
-	select S3C_DEV_HSMMC
-	select S3C_DEV_HSMMC2
-	select S3C_DEV_RTC
-	select S3C_DEV_USB_HSOTG
-	select S3C_DEV_WDT
-	select S5P_DEV_FIMC0
-	select S5P_DEV_FIMC1
-	select S5P_DEV_FIMC2
-	select S5P_DEV_FIMC3
-	select S5P_DEV_FIMD0
-	select S5P_DEV_G2D
-	select S5P_DEV_I2C_HDMIPHY
-	select S5P_DEV_JPEG
-	select S5P_DEV_MFC
-	select S5P_DEV_TV
-	select S5P_DEV_USB_EHCI
-	select SAMSUNG_DEV_BACKLIGHT
-	select SAMSUNG_DEV_PWM
-	help
-	  Machine support for ORIGEN based on Samsung EXYNOS4210
-
-comment "EXYNOS4212 Boards"
-
-config MACH_SMDK4212
-	bool "SMDK4212"
-	select EXYNOS4_SETUP_FIMD0
-	select EXYNOS4_SETUP_I2C1
-	select EXYNOS4_SETUP_I2C3
-	select EXYNOS4_SETUP_I2C7
-	select EXYNOS4_SETUP_KEYPAD
-	select EXYNOS4_SETUP_SDHCI
-	select EXYNOS4_SETUP_USB_PHY
-	select EXYNOS_DEV_DMA
-	select EXYNOS_DEV_SYSMMU
-	select S3C24XX_PWM
-	select S3C_DEV_HSMMC2
-	select S3C_DEV_HSMMC3
-	select S3C_DEV_I2C1
-	select S3C_DEV_I2C3
-	select S3C_DEV_I2C7
-	select S3C_DEV_RTC
-	select S3C_DEV_USB_HSOTG
-	select S3C_DEV_WDT
-	select S5P_DEV_FIMC0
-	select S5P_DEV_FIMC1
-	select S5P_DEV_FIMC2
-	select S5P_DEV_FIMC3
-	select S5P_DEV_FIMD0
-	select S5P_DEV_MFC
-	select SAMSUNG_DEV_BACKLIGHT
-	select SAMSUNG_DEV_KEYPAD
-	select SAMSUNG_DEV_PWM
-	select SOC_EXYNOS4212
-	help
-	  Machine support for Samsung SMDK4212
-
-comment "EXYNOS4412 Boards"
-
-config MACH_SMDK4412
-	bool "SMDK4412"
-	select MACH_SMDK4212
-	select SOC_EXYNOS4412
-	help
-	  Machine support for Samsung SMDK4412
-endif
-
-endif
-
 comment "Flattened Device Tree based board for EXYNOS SoCs"
 
 config MACH_EXYNOS4_DT
 	bool "Samsung Exynos4 Machine using device tree"
+	default y
 	depends on ARCH_EXYNOS4
 	select ARM_AMBA
 	select CLKSRC_OF
 	select CLKSRC_SAMSUNG_PWM if CPU_EXYNOS4210
 	select CPU_EXYNOS4210
 	select KEYBOARD_SAMSUNG if INPUT_KEYBOARD
-	select PINCTRL
-	select PINCTRL_EXYNOS
 	select S5P_DEV_MFC
-	select USE_OF
 	help
 	  Machine support for Samsung Exynos4 machine with device tree enabled.
 	  Select this if a fdt blob is available for the Exynos4 SoC based board.
@@ -429,28 +127,11 @@ config MACH_EXYNOS5_DT
 	depends on ARCH_EXYNOS5
 	select ARM_AMBA
 	select CLKSRC_OF
-	select USE_OF
+	select USB_ARCH_HAS_XHCI
 	help
 	  Machine support for Samsung EXYNOS5 machine with device tree enabled.
 	  Select this if a fdt blob is available for the EXYNOS5 SoC based board.
 
-if ARCH_EXYNOS4
-
-comment "Configuration for HSMMC 8-bit bus width"
-
-config EXYNOS4_SDHCI_CH0_8BIT
-	bool "Channel 0 with 8-bit bus"
-	help
-	  Support HSMMC Channel 0 8-bit bus.
-	  If selected, Channel 1 is disabled.
-
-config EXYNOS4_SDHCI_CH2_8BIT
-	bool "Channel 2 with 8-bit bus"
-	help
-	  Support HSMMC Channel 2 8-bit bus.
-	  If selected, Channel 3 is disabled.
-endif
-
 endmenu
 
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-armlex4210.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-armlex4210.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-armlex4210.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-armlex4210.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,207 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-armlex4210.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/smsc911x.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/gpio-cfg.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-srom.h>
-#include <plat/sdhci.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include "common.h"
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define ARMLEX4210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
-				 S3C2410_UCON_RXILEVEL |	\
-				 S3C2410_UCON_TXIRQMODE |	\
-				 S3C2410_UCON_RXIRQMODE |	\
-				 S3C2410_UCON_RXFIFO_TOI |	\
-				 S3C2443_UCON_RXERR_IRQEN)
-
-#define ARMLEX4210_ULCON_DEFAULT	S3C2410_LCON_CS8
-
-#define ARMLEX4210_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
-				 S5PV210_UFCON_TXTRIG4 |	\
-				 S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg armlex4210_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport		= 0,
-		.flags		= 0,
-		.ucon		= ARMLEX4210_UCON_DEFAULT,
-		.ulcon		= ARMLEX4210_ULCON_DEFAULT,
-		.ufcon		= ARMLEX4210_UFCON_DEFAULT,
-	},
-	[1] = {
-		.hwport		= 1,
-		.flags		= 0,
-		.ucon		= ARMLEX4210_UCON_DEFAULT,
-		.ulcon		= ARMLEX4210_ULCON_DEFAULT,
-		.ufcon		= ARMLEX4210_UFCON_DEFAULT,
-	},
-	[2] = {
-		.hwport		= 2,
-		.flags		= 0,
-		.ucon		= ARMLEX4210_UCON_DEFAULT,
-		.ulcon		= ARMLEX4210_ULCON_DEFAULT,
-		.ufcon		= ARMLEX4210_UFCON_DEFAULT,
-	},
-	[3] = {
-		.hwport		= 3,
-		.flags		= 0,
-		.ucon		= ARMLEX4210_UCON_DEFAULT,
-		.ulcon		= ARMLEX4210_ULCON_DEFAULT,
-		.ufcon		= ARMLEX4210_UFCON_DEFAULT,
-	},
-};
-
-static struct s3c_sdhci_platdata armlex4210_hsmmc0_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_PERMANENT,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
-	.max_width		= 8,
-	.host_caps		= MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata armlex4210_hsmmc2_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_GPIO,
-	.ext_cd_gpio		= EXYNOS4_GPX2(5),
-	.ext_cd_gpio_invert	= 1,
-	.max_width		= 4,
-};
-
-static struct s3c_sdhci_platdata armlex4210_hsmmc3_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_PERMANENT,
-	.max_width		= 4,
-};
-
-static void __init armlex4210_sdhci_init(void)
-{
-	s3c_sdhci0_set_platdata(&armlex4210_hsmmc0_pdata);
-	s3c_sdhci2_set_platdata(&armlex4210_hsmmc2_pdata);
-	s3c_sdhci3_set_platdata(&armlex4210_hsmmc3_pdata);
-}
-
-static void __init armlex4210_wlan_init(void)
-{
-	/* enable */
-	s3c_gpio_cfgpin(EXYNOS4_GPX2(0), S3C_GPIO_SFN(0xf));
-	s3c_gpio_setpull(EXYNOS4_GPX2(0), S3C_GPIO_PULL_UP);
-
-	/* reset */
-	s3c_gpio_cfgpin(EXYNOS4_GPX1(6), S3C_GPIO_SFN(0xf));
-	s3c_gpio_setpull(EXYNOS4_GPX1(6), S3C_GPIO_PULL_UP);
-
-	/* wakeup */
-	s3c_gpio_cfgpin(EXYNOS4_GPX1(5), S3C_GPIO_SFN(0xf));
-	s3c_gpio_setpull(EXYNOS4_GPX1(5), S3C_GPIO_PULL_UP);
-}
-
-static struct resource armlex4210_smsc911x_resources[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_SROM_BANK(3), SZ_64K),
-	[1] = DEFINE_RES_NAMED(IRQ_EINT(27), 1, NULL, IORESOURCE_IRQ \
-					| IRQF_TRIGGER_HIGH),
-};
-
-static struct smsc911x_platform_config smsc9215_config = {
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
-	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
-	.flags		= SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-	.mac		= {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
-};
-
-static struct platform_device armlex4210_smsc911x = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(armlex4210_smsc911x_resources),
-	.resource	= armlex4210_smsc911x_resources,
-	.dev		= {
-		.platform_data	= &smsc9215_config,
-	},
-};
-
-static struct platform_device *armlex4210_devices[] __initdata = {
-	&s3c_device_hsmmc0,
-	&s3c_device_hsmmc2,
-	&s3c_device_hsmmc3,
-	&s3c_device_rtc,
-	&s3c_device_wdt,
-	&armlex4210_smsc911x,
-	&exynos4_device_ahci,
-};
-
-static void __init armlex4210_smsc911x_init(void)
-{
-	u32 cs1;
-
-	/* configure nCS1 width to 16 bits */
-	cs1 = __raw_readl(S5P_SROM_BW) &
-		~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
-	cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
-		(0 << S5P_SROM_BW__WAITENABLE__SHIFT) |
-		(1 << S5P_SROM_BW__ADDRMODE__SHIFT) |
-		(1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
-		S5P_SROM_BW__NCS1__SHIFT;
-	__raw_writel(cs1, S5P_SROM_BW);
-
-	/* set timing for nCS1 suitable for ethernet chip */
-	__raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
-		     (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
-		     (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
-		     (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
-		     (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
-		     (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
-		     (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
-}
-
-static void __init armlex4210_map_io(void)
-{
-	exynos_init_io(NULL, 0);
-	s3c24xx_init_uarts(armlex4210_uartcfgs,
-			   ARRAY_SIZE(armlex4210_uartcfgs));
-}
-
-static void __init armlex4210_machine_init(void)
-{
-	armlex4210_smsc911x_init();
-
-	armlex4210_sdhci_init();
-
-	armlex4210_wlan_init();
-
-	platform_add_devices(armlex4210_devices,
-			     ARRAY_SIZE(armlex4210_devices));
-}
-
-MACHINE_START(ARMLEX4210, "ARMLEX4210")
-	/* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(exynos_smp_ops),
-	.init_irq	= exynos4_init_irq,
-	.map_io		= armlex4210_map_io,
-	.init_machine	= armlex4210_machine_init,
-	.init_late	= exynos_init_late,
-	.init_time	= exynos_init_time,
-	.restart	= exynos4_restart,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-exynos4-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-exynos4-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-exynos4-dt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-exynos4-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,11 +23,6 @@
 
 #include "common.h"
 
-static void __init exynos4_dt_map_io(void)
-{
-	exynos_init_io(NULL, 0);
-}
-
 static void __init exynos4_dt_machine_init(void)
 {
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
@@ -55,8 +50,7 @@ static void __init exynos4_reserve(void)
 DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
 	/* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
 	.smp		= smp_ops(exynos_smp_ops),
-	.init_irq	= exynos4_init_irq,
-	.map_io		= exynos4_dt_map_io,
+	.map_io		= exynos_init_io,
 	.init_early	= exynos_firmware_init,
 	.init_machine	= exynos4_dt_machine_init,
 	.init_late	= exynos_init_late,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-exynos5-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-exynos5-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-exynos5-dt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-exynos5-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,11 +23,6 @@
 
 #include "common.h"
 
-static void __init exynos5_dt_map_io(void)
-{
-	exynos_init_io(NULL, 0);
-}
-
 static void __init exynos5_dt_machine_init(void)
 {
 	struct device_node *i2c_np;
@@ -57,6 +52,7 @@ static void __init exynos5_dt_machine_in
 
 static char const *exynos5_dt_compat[] __initdata = {
 	"samsung,exynos5250",
+	"samsung,exynos5420",
 	"samsung,exynos5440",
 	NULL
 };
@@ -76,9 +72,8 @@ static void __init exynos5_reserve(void)
 
 DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
 	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-	.init_irq	= exynos5_init_irq,
 	.smp		= smp_ops(exynos_smp_ops),
-	.map_io		= exynos5_dt_map_io,
+	.map_io		= exynos_init_io,
 	.init_machine	= exynos5_dt_machine_init,
 	.init_late	= exynos_init_late,
 	.init_time	= exynos_init_time,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-nuri.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-nuri.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-nuri.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-nuri.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1388 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/mach-nuri.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/i2c/atmel_mxt_ts.h>
-#include <linux/i2c-gpio.h>
-#include <linux/gpio_keys.h>
-#include <linux/gpio.h>
-#include <linux/power/max8903_charger.h>
-#include <linux/power/max17042_battery.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/mfd/max8997.h>
-#include <linux/mfd/max8997-private.h>
-#include <linux/mmc/host.h>
-#include <linux/fb.h>
-#include <linux/pwm_backlight.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <linux/platform_data/mipi-csis.h>
-#include <linux/platform_data/s3c-hsotg.h>
-#include <linux/platform_data/usb-ehci-s5p.h>
-#include <drm/exynos_drm.h>
-
-#include <video/platform_lcd.h>
-#include <video/samsung_fimd.h>
-#include <media/m5mols.h>
-#include <media/s5k6aa.h>
-#include <media/s5p_fimc.h>
-#include <media/v4l2-mediabus.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <plat/adc.h>
-#include <plat/regs-serial.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/fb.h>
-#include <plat/sdhci.h>
-#include <plat/clock.h>
-#include <plat/gpio-cfg.h>
-#include <plat/mfc.h>
-#include <plat/fimc-core.h>
-#include <plat/camport.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include "common.h"
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define NURI_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
-				 S3C2410_UCON_RXILEVEL |	\
-				 S3C2410_UCON_TXIRQMODE |	\
-				 S3C2410_UCON_RXIRQMODE |	\
-				 S3C2410_UCON_RXFIFO_TOI |	\
-				 S3C2443_UCON_RXERR_IRQEN)
-
-#define NURI_ULCON_DEFAULT	S3C2410_LCON_CS8
-
-#define NURI_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
-				 S5PV210_UFCON_TXTRIG256 |	\
-				 S5PV210_UFCON_RXTRIG256)
-
-enum fixed_regulator_id {
-	FIXED_REG_ID_MMC = 0,
-	FIXED_REG_ID_MAX8903,
-	FIXED_REG_ID_CAM_A28V,
-	FIXED_REG_ID_CAM_12V,
-	FIXED_REG_ID_CAM_VT_15V,
-};
-
-static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
-	{
-		.hwport		= 0,
-		.ucon		= NURI_UCON_DEFAULT,
-		.ulcon		= NURI_ULCON_DEFAULT,
-		.ufcon		= NURI_UFCON_DEFAULT,
-	},
-	{
-		.hwport		= 1,
-		.ucon		= NURI_UCON_DEFAULT,
-		.ulcon		= NURI_ULCON_DEFAULT,
-		.ufcon		= NURI_UFCON_DEFAULT,
-	},
-	{
-		.hwport		= 2,
-		.ucon		= NURI_UCON_DEFAULT,
-		.ulcon		= NURI_ULCON_DEFAULT,
-		.ufcon		= NURI_UFCON_DEFAULT,
-	},
-	{
-		.hwport		= 3,
-		.ucon		= NURI_UCON_DEFAULT,
-		.ulcon		= NURI_ULCON_DEFAULT,
-		.ufcon		= NURI_UFCON_DEFAULT,
-	},
-};
-
-/* eMMC */
-static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = {
-	.max_width		= 8,
-	.host_caps		= (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
-				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-				MMC_CAP_ERASE),
-	.cd_type		= S3C_SDHCI_CD_PERMANENT,
-};
-
-static struct regulator_consumer_supply emmc_supplies[] = {
-	REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.0"),
-	REGULATOR_SUPPLY("vmmc", "dw_mmc"),
-};
-
-static struct regulator_init_data emmc_fixed_voltage_init_data = {
-	.constraints		= {
-		.name		= "VMEM_VDD_2.8V",
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(emmc_supplies),
-	.consumer_supplies	= emmc_supplies,
-};
-
-static struct fixed_voltage_config emmc_fixed_voltage_config = {
-	.supply_name		= "MASSMEMORY_EN (inverted)",
-	.microvolts		= 2800000,
-	.gpio			= EXYNOS4_GPL1(1),
-	.enable_high		= false,
-	.init_data		= &emmc_fixed_voltage_init_data,
-};
-
-static struct platform_device emmc_fixed_voltage = {
-	.name			= "reg-fixed-voltage",
-	.id			= FIXED_REG_ID_MMC,
-	.dev			= {
-		.platform_data	= &emmc_fixed_voltage_config,
-	},
-};
-
-/* SD */
-static struct s3c_sdhci_platdata nuri_hsmmc2_data __initdata = {
-	.max_width		= 4,
-	.host_caps		= MMC_CAP_4_BIT_DATA |
-				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
-	.ext_cd_gpio		= EXYNOS4_GPX3(3),	/* XEINT_27 */
-	.ext_cd_gpio_invert	= 1,
-	.cd_type		= S3C_SDHCI_CD_GPIO,
-};
-
-/* WLAN */
-static struct s3c_sdhci_platdata nuri_hsmmc3_data __initdata = {
-	.max_width		= 4,
-	.host_caps		= MMC_CAP_4_BIT_DATA |
-				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
-	.cd_type		= S3C_SDHCI_CD_EXTERNAL,
-};
-
-static void __init nuri_sdhci_init(void)
-{
-	s3c_sdhci0_set_platdata(&nuri_hsmmc0_data);
-	s3c_sdhci2_set_platdata(&nuri_hsmmc2_data);
-	s3c_sdhci3_set_platdata(&nuri_hsmmc3_data);
-}
-
-/* GPIO KEYS */
-static struct gpio_keys_button nuri_gpio_keys_tables[] = {
-	{
-		.code			= KEY_VOLUMEUP,
-		.gpio			= EXYNOS4_GPX2(0),	/* XEINT16 */
-		.desc			= "gpio-keys: KEY_VOLUMEUP",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_VOLUMEDOWN,
-		.gpio			= EXYNOS4_GPX2(1),	/* XEINT17 */
-		.desc			= "gpio-keys: KEY_VOLUMEDOWN",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_POWER,
-		.gpio			= EXYNOS4_GPX2(7),	/* XEINT23 */
-		.desc			= "gpio-keys: KEY_POWER",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.wakeup			= 1,
-		.debounce_interval	= 1,
-	},
-};
-
-static struct gpio_keys_platform_data nuri_gpio_keys_data = {
-	.buttons		= nuri_gpio_keys_tables,
-	.nbuttons		= ARRAY_SIZE(nuri_gpio_keys_tables),
-};
-
-static struct platform_device nuri_gpio_keys = {
-	.name			= "gpio-keys",
-	.dev			= {
-		.platform_data	= &nuri_gpio_keys_data,
-	},
-};
-
-#ifdef CONFIG_DRM_EXYNOS
-static struct exynos_drm_fimd_pdata drm_fimd_pdata = {
-	.panel = {
-		.timing	= {
-			.xres		= 1024,
-			.yres		= 600,
-			.hsync_len	= 40,
-			.left_margin	= 79,
-			.right_margin	= 200,
-			.vsync_len	= 10,
-			.upper_margin	= 10,
-			.lower_margin	= 11,
-			.refresh	= 60,
-		},
-	},
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
-			  VIDCON0_CLKSEL_LCD,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-	.default_win	= 3,
-	.bpp		= 32,
-};
-
-#else
-/* Frame Buffer */
-static struct s3c_fb_pd_win nuri_fb_win0 = {
-	.max_bpp	= 24,
-	.default_bpp	= 16,
-	.xres		= 1024,
-	.yres		= 600,
-	.virtual_x	= 1024,
-	.virtual_y	= 2 * 600,
-};
-
-static struct fb_videomode nuri_lcd_timing = {
-	.left_margin	= 64,
-	.right_margin	= 16,
-	.upper_margin	= 64,
-	.lower_margin	= 1,
-	.hsync_len	= 48,
-	.vsync_len	= 3,
-	.xres		= 1024,
-	.yres		= 600,
-	.refresh	= 60,
-};
-
-static struct s3c_fb_platdata nuri_fb_pdata __initdata = {
-	.win[0]		= &nuri_fb_win0,
-	.vtiming	= &nuri_lcd_timing,
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
-			  VIDCON0_CLKSEL_LCD,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
-};
-#endif
-
-static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power)
-{
-	int gpio = EXYNOS4_GPE1(5);
-
-	gpio_request(gpio, "LVDS_nSHDN");
-	gpio_direction_output(gpio, power);
-	gpio_free(gpio);
-}
-
-static int nuri_bl_init(struct device *dev)
-{
-	return gpio_request_one(EXYNOS4_GPE2(3), GPIOF_OUT_INIT_LOW,
-				"LCD_LD0_EN");
-}
-
-static int nuri_bl_notify(struct device *dev, int brightness)
-{
-	if (brightness < 1)
-		brightness = 0;
-
-	gpio_set_value(EXYNOS4_GPE2(3), 1);
-
-	return brightness;
-}
-
-static void nuri_bl_exit(struct device *dev)
-{
-	gpio_free(EXYNOS4_GPE2(3));
-}
-
-/* nuri pwm backlight */
-static struct platform_pwm_backlight_data nuri_backlight_data = {
-	.pwm_id			= 0,
-	.pwm_period_ns		= 30000,
-	.max_brightness		= 100,
-	.dft_brightness		= 50,
-	.init			= nuri_bl_init,
-	.notify			= nuri_bl_notify,
-	.exit			= nuri_bl_exit,
-};
-
-static struct platform_device nuri_backlight_device = {
-	.name			= "pwm-backlight",
-	.id			= -1,
-	.dev			= {
-		.parent		= &s3c_device_timer[0].dev,
-		.platform_data	= &nuri_backlight_data,
-	},
-};
-
-static struct plat_lcd_data nuri_lcd_platform_data = {
-	.set_power		= nuri_lcd_power_on,
-};
-
-static struct platform_device nuri_lcd_device = {
-	.name			= "platform-lcd",
-	.id			= -1,
-	.dev			= {
-		.platform_data	= &nuri_lcd_platform_data,
-	},
-};
-
-/* I2C1 */
-static struct i2c_board_info i2c1_devs[] __initdata = {
-	/* Gyro, To be updated */
-};
-
-/* TSP */
-static struct mxt_platform_data mxt_platform_data = {
-	.x_line			= 18,
-	.y_line			= 11,
-	.x_size			= 1024,
-	.y_size			= 600,
-	.blen			= 0x1,
-	.threshold		= 0x28,
-	.voltage		= 2800000,		/* 2.8V */
-	.orient			= MXT_DIAGONAL_COUNTER,
-	.irqflags		= IRQF_TRIGGER_FALLING,
-};
-
-static struct s3c2410_platform_i2c i2c3_data __initdata = {
-	.flags		= 0,
-	.bus_num	= 3,
-	.slave_addr	= 0x10,
-	.frequency	= 400 * 1000,
-	.sda_delay	= 100,
-};
-
-static struct i2c_board_info i2c3_devs[] __initdata = {
-	{
-		I2C_BOARD_INFO("atmel_mxt_ts", 0x4a),
-		.platform_data	= &mxt_platform_data,
-		.irq		= IRQ_EINT(4),
-	},
-};
-
-static void __init nuri_tsp_init(void)
-{
-	int gpio;
-
-	/* TOUCH_INT: XEINT_4 */
-	gpio = EXYNOS4_GPX0(4);
-	gpio_request(gpio, "TOUCH_INT");
-	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-	s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-}
-
-static struct regulator_consumer_supply __initdata max8997_ldo1_[] = {
-	REGULATOR_SUPPLY("vdd", "s5p-adc"), /* Used by CPU's ADC drv */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo3_[] = {
-	REGULATOR_SUPPLY("vusb_d", "s3c-hsotg"), /* USB */
-	REGULATOR_SUPPLY("vddcore", "s5p-mipi-csis.0"), /* MIPI */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo4_[] = {
-	REGULATOR_SUPPLY("vddio", "s5p-mipi-csis.0"), /* MIPI */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo5_[] = {
-	REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */
-};
-static struct regulator_consumer_supply nuri_max8997_ldo6_consumer[] = {
-	REGULATOR_SUPPLY("vdd_reg", "6-003c"), /* S5K6AA camera */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo7_[] = {
-	REGULATOR_SUPPLY("dig_18", "0-001f"), /* HCD803 */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo8_[] = {
-	REGULATOR_SUPPLY("vusb_a", "s3c-hsotg"), /* USB */
-	REGULATOR_SUPPLY("vdac", NULL), /* Used by CPU */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo11_[] = {
-	REGULATOR_SUPPLY("vcc", "platform-lcd"), /* U804 LVDS */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo12_[] = {
-	REGULATOR_SUPPLY("vddio", "6-003c"), /* HDC802 */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo13_[] = {
-	REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.2"), /* TFLASH */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo14_[] = {
-	REGULATOR_SUPPLY("inmotor", "max8997-haptic"),
-};
-static struct regulator_consumer_supply __initdata max8997_ldo15_[] = {
-	REGULATOR_SUPPLY("avdd", "3-004a"), /* Touch Screen */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo16_[] = {
-	REGULATOR_SUPPLY("d_sensor", "0-001f"), /* HDC803 */
-};
-static struct regulator_consumer_supply __initdata max8997_ldo18_[] = {
-	REGULATOR_SUPPLY("vdd", "3-004a"), /* Touch Screen */
-};
-static struct regulator_consumer_supply __initdata max8997_buck1_[] = {
-	REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */
-};
-static struct regulator_consumer_supply __initdata max8997_buck2_[] = {
-	REGULATOR_SUPPLY("vdd_int", "exynos4210-busfreq.0"), /* CPUFREQ */
-};
-static struct regulator_consumer_supply __initdata max8997_buck3_[] = {
-	REGULATOR_SUPPLY("vdd", "mali_dev.0"), /* G3D of Exynos 4 */
-};
-static struct regulator_consumer_supply __initdata max8997_buck4_[] = {
-	REGULATOR_SUPPLY("core", "0-001f"), /* HDC803 */
-};
-static struct regulator_consumer_supply __initdata max8997_buck6_[] = {
-	REGULATOR_SUPPLY("dig_28", "0-001f"), /* pin "7" of HDC803 */
-};
-static struct regulator_consumer_supply __initdata max8997_esafeout1_[] = {
-	REGULATOR_SUPPLY("usb_vbus", NULL), /* CPU's USB OTG */
-};
-static struct regulator_consumer_supply __initdata max8997_esafeout2_[] = {
-	REGULATOR_SUPPLY("usb_vbus", "modemctl"), /* VBUS of Modem */
-};
-
-static struct regulator_consumer_supply __initdata max8997_charger_[] = {
-	REGULATOR_SUPPLY("vinchg1", "charger-manager.0"),
-};
-static struct regulator_consumer_supply __initdata max8997_chg_toff_[] = {
-	REGULATOR_SUPPLY("vinchg_stop", NULL), /* for jack interrupt handlers */
-};
-
-static struct regulator_consumer_supply __initdata max8997_32khz_ap_[] = {
-	REGULATOR_SUPPLY("gps_clk", "bcm4751"),
-	REGULATOR_SUPPLY("bt_clk", "bcm4330-b1"),
-	REGULATOR_SUPPLY("wifi_clk", "bcm433-b1"),
-};
-
-static struct regulator_init_data __initdata max8997_ldo1_data = {
-	.constraints	= {
-		.name		= "VADC_3.3V_C210",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo1_),
-	.consumer_supplies	= max8997_ldo1_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo2_data = {
-	.constraints	= {
-		.name		= "VALIVE_1.1V_C210",
-		.min_uV		= 1100000,
-		.max_uV		= 1100000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_ldo3_data = {
-	.constraints	= {
-		.name		= "VUSB_1.1V_C210",
-		.min_uV		= 1100000,
-		.max_uV		= 1100000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo3_),
-	.consumer_supplies	= max8997_ldo3_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo4_data = {
-	.constraints	= {
-		.name		= "VMIPI_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo4_),
-	.consumer_supplies	= max8997_ldo4_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo5_data = {
-	.constraints	= {
-		.name		= "VHSIC_1.2V_C210",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo5_),
-	.consumer_supplies	= max8997_ldo5_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo6_data = {
-	.constraints	= {
-		.name		= "VCC_1.8V_PDA",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo6_consumer),
-	.consumer_supplies	= nuri_max8997_ldo6_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_ldo7_data = {
-	.constraints	= {
-		.name		= "CAM_ISP_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo7_),
-	.consumer_supplies	= max8997_ldo7_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo8_data = {
-	.constraints	= {
-		.name		= "VUSB+VDAC_3.3V_C210",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo8_),
-	.consumer_supplies	= max8997_ldo8_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo9_data = {
-	.constraints	= {
-		.name		= "VCC_2.8V_PDA",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_ldo10_data = {
-	.constraints	= {
-		.name		= "VPLL_1.1V_C210",
-		.min_uV		= 1100000,
-		.max_uV		= 1100000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_ldo11_data = {
-	.constraints	= {
-		.name		= "LVDS_VDD3.3V",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.boot_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo11_),
-	.consumer_supplies	= max8997_ldo11_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo12_data = {
-	.constraints	= {
-		.name		= "VT_CAM_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo12_),
-	.consumer_supplies	= max8997_ldo12_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo13_data = {
-	.constraints	= {
-		.name		= "VTF_2.8V",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo13_),
-	.consumer_supplies	= max8997_ldo13_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo14_data = {
-	.constraints	= {
-		.name		= "VCC_3.0V_MOTOR",
-		.min_uV		= 3000000,
-		.max_uV		= 3000000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo14_),
-	.consumer_supplies	= max8997_ldo14_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo15_data = {
-	.constraints	= {
-		.name		= "VTOUCH_ADVV2.8V",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo15_),
-	.consumer_supplies	= max8997_ldo15_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo16_data = {
-	.constraints	= {
-		.name		= "CAM_SENSOR_IO_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo16_),
-	.consumer_supplies	= max8997_ldo16_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo18_data = {
-	.constraints	= {
-		.name		= "VTOUCH_VDD2.8V",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_ldo18_),
-	.consumer_supplies	= max8997_ldo18_,
-};
-
-static struct regulator_init_data __initdata max8997_ldo21_data = {
-	.constraints	= {
-		.name		= "VDDQ_M1M2_1.2V",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_buck1_data = {
-	.constraints	= {
-		.name		= "VARM_1.2V_C210",
-		.min_uV		= 900000,
-		.max_uV		= 1350000,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
-		.always_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(max8997_buck1_),
-	.consumer_supplies = max8997_buck1_,
-};
-
-static struct regulator_init_data __initdata max8997_buck2_data = {
-	.constraints	= {
-		.name		= "VINT_1.1V_C210",
-		.min_uV		= 900000,
-		.max_uV		= 1200000,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
-		.always_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(max8997_buck2_),
-	.consumer_supplies = max8997_buck2_,
-};
-
-static struct regulator_init_data __initdata max8997_buck3_data = {
-	.constraints	= {
-		.name		= "VG3D_1.1V_C210",
-		.min_uV		= 900000,
-		.max_uV		= 1100000,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
-				  REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(max8997_buck3_),
-	.consumer_supplies = max8997_buck3_,
-};
-
-static struct regulator_init_data __initdata max8997_buck4_data = {
-	.constraints	= {
-		.name		= "CAM_ISP_CORE_1.2V",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(max8997_buck4_),
-	.consumer_supplies = max8997_buck4_,
-};
-
-static struct regulator_init_data __initdata max8997_buck5_data = {
-	.constraints	= {
-		.name		= "VMEM_1.2V_C210",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_buck6_data = {
-	.constraints	= {
-		.name		= "CAM_AF_2.8V",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(max8997_buck6_),
-	.consumer_supplies = max8997_buck6_,
-};
-
-static struct regulator_init_data __initdata max8997_buck7_data = {
-	.constraints	= {
-		.name		= "VCC_SUB_2.0V",
-		.min_uV		= 2000000,
-		.max_uV		= 2000000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_32khz_ap_data = {
-	.constraints	= {
-		.name		= "32KHz AP",
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(max8997_32khz_ap_),
-	.consumer_supplies = max8997_32khz_ap_,
-};
-
-static struct regulator_init_data __initdata max8997_32khz_cp_data = {
-	.constraints	= {
-		.name		= "32KHz CP",
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_vichg_data = {
-	.constraints	= {
-		.name		= "VICHG",
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_esafeout1_data = {
-	.constraints	= {
-		.name		= "SAFEOUT1",
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.always_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_esafeout1_),
-	.consumer_supplies	= max8997_esafeout1_,
-};
-
-static struct regulator_init_data __initdata max8997_esafeout2_data = {
-	.constraints	= {
-		.name		= "SAFEOUT2",
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_esafeout2_),
-	.consumer_supplies	= max8997_esafeout2_,
-};
-
-static struct regulator_init_data __initdata max8997_charger_cv_data = {
-	.constraints	= {
-		.name		= "CHARGER_CV",
-		.min_uV		= 4200000,
-		.max_uV		= 4200000,
-		.apply_uV	= 1,
-	},
-};
-
-static struct regulator_init_data __initdata max8997_charger_data = {
-	.constraints	= {
-		.name		= "CHARGER",
-		.min_uA		= 200000,
-		.max_uA		= 950000,
-		.boot_on	= 1,
-		.valid_ops_mask = REGULATOR_CHANGE_STATUS |
-				REGULATOR_CHANGE_CURRENT,
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_charger_),
-	.consumer_supplies	= max8997_charger_,
-};
-
-static struct regulator_init_data __initdata max8997_charger_topoff_data = {
-	.constraints	= {
-		.name		= "CHARGER TOPOFF",
-		.min_uA		= 50000,
-		.max_uA		= 200000,
-		.valid_ops_mask = REGULATOR_CHANGE_CURRENT,
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(max8997_chg_toff_),
-	.consumer_supplies	= max8997_chg_toff_,
-};
-
-static struct max8997_regulator_data __initdata nuri_max8997_regulators[] = {
-	{ MAX8997_LDO1, &max8997_ldo1_data },
-	{ MAX8997_LDO2, &max8997_ldo2_data },
-	{ MAX8997_LDO3, &max8997_ldo3_data },
-	{ MAX8997_LDO4, &max8997_ldo4_data },
-	{ MAX8997_LDO5, &max8997_ldo5_data },
-	{ MAX8997_LDO6, &max8997_ldo6_data },
-	{ MAX8997_LDO7, &max8997_ldo7_data },
-	{ MAX8997_LDO8, &max8997_ldo8_data },
-	{ MAX8997_LDO9, &max8997_ldo9_data },
-	{ MAX8997_LDO10, &max8997_ldo10_data },
-	{ MAX8997_LDO11, &max8997_ldo11_data },
-	{ MAX8997_LDO12, &max8997_ldo12_data },
-	{ MAX8997_LDO13, &max8997_ldo13_data },
-	{ MAX8997_LDO14, &max8997_ldo14_data },
-	{ MAX8997_LDO15, &max8997_ldo15_data },
-	{ MAX8997_LDO16, &max8997_ldo16_data },
-
-	{ MAX8997_LDO18, &max8997_ldo18_data },
-	{ MAX8997_LDO21, &max8997_ldo21_data },
-
-	{ MAX8997_BUCK1, &max8997_buck1_data },
-	{ MAX8997_BUCK2, &max8997_buck2_data },
-	{ MAX8997_BUCK3, &max8997_buck3_data },
-	{ MAX8997_BUCK4, &max8997_buck4_data },
-	{ MAX8997_BUCK5, &max8997_buck5_data },
-	{ MAX8997_BUCK6, &max8997_buck6_data },
-	{ MAX8997_BUCK7, &max8997_buck7_data },
-
-	{ MAX8997_EN32KHZ_AP, &max8997_32khz_ap_data },
-	{ MAX8997_EN32KHZ_CP, &max8997_32khz_cp_data },
-
-	{ MAX8997_ENVICHG, &max8997_vichg_data },
-	{ MAX8997_ESAFEOUT1, &max8997_esafeout1_data },
-	{ MAX8997_ESAFEOUT2, &max8997_esafeout2_data },
-	{ MAX8997_CHARGER_CV, &max8997_charger_cv_data },
-	{ MAX8997_CHARGER, &max8997_charger_data },
-	{ MAX8997_CHARGER_TOPOFF, &max8997_charger_topoff_data },
-};
-
-static struct max8997_platform_data __initdata nuri_max8997_pdata = {
-	.wakeup			= 1,
-
-	.num_regulators		= ARRAY_SIZE(nuri_max8997_regulators),
-	.regulators		= nuri_max8997_regulators,
-
-	.buck125_gpios = { EXYNOS4_GPX0(5), EXYNOS4_GPX0(6), EXYNOS4_GPL0(0) },
-
-	.buck1_voltage[0] = 1350000, /* 1.35V */
-	.buck1_voltage[1] = 1300000, /* 1.3V */
-	.buck1_voltage[2] = 1250000, /* 1.25V */
-	.buck1_voltage[3] = 1200000, /* 1.2V */
-	.buck1_voltage[4] = 1150000, /* 1.15V */
-	.buck1_voltage[5] = 1100000, /* 1.1V */
-	.buck1_voltage[6] = 1000000, /* 1.0V */
-	.buck1_voltage[7] = 950000, /* 0.95V */
-
-	.buck2_voltage[0] = 1100000, /* 1.1V */
-	.buck2_voltage[1] = 1000000, /* 1.0V */
-	.buck2_voltage[2] = 950000, /* 0.95V */
-	.buck2_voltage[3] = 900000, /* 0.9V */
-	.buck2_voltage[4] = 1100000, /* 1.1V */
-	.buck2_voltage[5] = 1000000, /* 1.0V */
-	.buck2_voltage[6] = 950000, /* 0.95V */
-	.buck2_voltage[7] = 900000, /* 0.9V */
-
-	.buck5_voltage[0] = 1200000, /* 1.2V */
-	.buck5_voltage[1] = 1200000, /* 1.2V */
-	.buck5_voltage[2] = 1200000, /* 1.2V */
-	.buck5_voltage[3] = 1200000, /* 1.2V */
-	.buck5_voltage[4] = 1200000, /* 1.2V */
-	.buck5_voltage[5] = 1200000, /* 1.2V */
-	.buck5_voltage[6] = 1200000, /* 1.2V */
-	.buck5_voltage[7] = 1200000, /* 1.2V */
-};
-
-/* GPIO I2C 5 (PMIC) */
-enum { I2C5_MAX8997 };
-static struct i2c_board_info i2c5_devs[] __initdata = {
-	[I2C5_MAX8997] = {
-		I2C_BOARD_INFO("max8997", 0xCC >> 1),
-		.platform_data	= &nuri_max8997_pdata,
-	},
-};
-
-static struct max17042_platform_data nuri_battery_platform_data = {
-};
-
-/* GPIO I2C 9 (Fuel Gauge) */
-static struct i2c_gpio_platform_data i2c9_gpio_data = {
-	.sda_pin		= EXYNOS4_GPY4(0),      /* XM0ADDR_8 */
-	.scl_pin		= EXYNOS4_GPY4(1),      /* XM0ADDR_9 */
-};
-static struct platform_device i2c9_gpio = {
-	.name			= "i2c-gpio",
-	.id			= 9,
-	.dev			= {
-		.platform_data	= &i2c9_gpio_data,
-	},
-};
-enum { I2C9_MAX17042};
-static struct i2c_board_info i2c9_devs[] __initdata = {
-	[I2C9_MAX17042] = {
-		I2C_BOARD_INFO("max17042", 0x36),
-		.platform_data = &nuri_battery_platform_data,
-	},
-};
-
-/* MAX8903 Secondary Charger */
-static struct regulator_consumer_supply supplies_max8903[] = {
-	REGULATOR_SUPPLY("vinchg2", "charger-manager.0"),
-};
-
-static struct regulator_init_data max8903_charger_en_data = {
-	.constraints = {
-		.name		= "VOUT_CHARGER",
-		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
-		.boot_on	= 1,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(supplies_max8903),
-	.consumer_supplies = supplies_max8903,
-};
-
-static struct fixed_voltage_config max8903_charger_en = {
-	.supply_name = "VOUT_CHARGER",
-	.microvolts = 5000000, /* Assume 5VDC */
-	.gpio = EXYNOS4_GPY4(5), /* TA_EN negaged */
-	.enable_high = 0, /* Enable = Low */
-	.enabled_at_boot = 1,
-	.init_data = &max8903_charger_en_data,
-};
-
-static struct platform_device max8903_fixed_reg_dev = {
-	.name = "reg-fixed-voltage",
-	.id = FIXED_REG_ID_MAX8903,
-	.dev = { .platform_data	= &max8903_charger_en },
-};
-
-static struct max8903_pdata nuri_max8903 = {
-	/*
-	 * cen: don't control with the driver, let it be
-	 * controlled by regulator above
-	 */
-	.dok = EXYNOS4_GPX1(4), /* TA_nCONNECTED */
-	/* uok, usus: not connected */
-	.chg = EXYNOS4_GPE2(0), /* TA_nCHG */
-	/* flt: vcc_1.8V_pda */
-	.dcm = EXYNOS4_GPL0(1), /* CURR_ADJ */
-
-	.dc_valid = true,
-	.usb_valid = false, /* USB is not wired to MAX8903 */
-};
-
-static struct platform_device nuri_max8903_device = {
-	.name			= "max8903-charger",
-	.dev			= {
-		.platform_data	= &nuri_max8903,
-	},
-};
-
-static void __init nuri_power_init(void)
-{
-	int gpio;
-	int ta_en = 0;
-
-	gpio = EXYNOS4_GPX0(7);
-	gpio_request(gpio, "AP_PMIC_IRQ");
-	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-	s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-
-	gpio = EXYNOS4_GPX2(3);
-	gpio_request(gpio, "FUEL_ALERT");
-	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-	s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-
-	gpio = nuri_max8903.dok;
-	gpio_request(gpio, "TA_nCONNECTED");
-	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-	s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-	ta_en = gpio_get_value(gpio) ? 0 : 1;
-
-	gpio = nuri_max8903.chg;
-	gpio_request(gpio, "TA_nCHG");
-	gpio_direction_input(gpio);
-
-	gpio = nuri_max8903.dcm;
-	gpio_request(gpio, "CURR_ADJ");
-	gpio_direction_output(gpio, ta_en);
-}
-
-/* USB EHCI */
-static struct s5p_ehci_platdata nuri_ehci_pdata;
-
-static void __init nuri_ehci_init(void)
-{
-	struct s5p_ehci_platdata *pdata = &nuri_ehci_pdata;
-
-	s5p_ehci_set_platdata(pdata);
-}
-
-/* USB OTG */
-static struct s3c_hsotg_plat nuri_hsotg_pdata;
-
-/* CAMERA */
-static struct regulator_consumer_supply cam_vt_cam15_supply =
-	REGULATOR_SUPPLY("vdd_core", "6-003c");
-
-static struct regulator_init_data cam_vt_cam15_reg_init_data = {
-	.constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
-	.num_consumer_supplies = 1,
-	.consumer_supplies = &cam_vt_cam15_supply,
-};
-
-static struct fixed_voltage_config cam_vt_cam15_fixed_voltage_cfg = {
-	.supply_name	= "VT_CAM_1.5V",
-	.microvolts	= 1500000,
-	.gpio		= EXYNOS4_GPE2(2), /* VT_CAM_1.5V_EN */
-	.enable_high	= 1,
-	.init_data	= &cam_vt_cam15_reg_init_data,
-};
-
-static struct platform_device cam_vt_cam15_fixed_rdev = {
-	.name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_15V,
-	.dev = { .platform_data	= &cam_vt_cam15_fixed_voltage_cfg },
-};
-
-static struct regulator_consumer_supply cam_vdda_supply[] = {
-	REGULATOR_SUPPLY("vdda", "6-003c"),
-	REGULATOR_SUPPLY("a_sensor", "0-001f"),
-};
-
-static struct regulator_init_data cam_vdda_reg_init_data = {
-	.constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
-	.num_consumer_supplies = ARRAY_SIZE(cam_vdda_supply),
-	.consumer_supplies = cam_vdda_supply,
-};
-
-static struct fixed_voltage_config cam_vdda_fixed_voltage_cfg = {
-	.supply_name	= "CAM_IO_EN",
-	.microvolts	= 2800000,
-	.gpio		= EXYNOS4_GPE2(1), /* CAM_IO_EN */
-	.enable_high	= 1,
-	.init_data	= &cam_vdda_reg_init_data,
-};
-
-static struct platform_device cam_vdda_fixed_rdev = {
-	.name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_A28V,
-	.dev = { .platform_data	= &cam_vdda_fixed_voltage_cfg },
-};
-
-static struct regulator_consumer_supply camera_8m_12v_supply =
-	REGULATOR_SUPPLY("dig_12", "0-001f");
-
-static struct regulator_init_data cam_8m_12v_reg_init_data = {
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &camera_8m_12v_supply,
-	.constraints = {
-		.valid_ops_mask = REGULATOR_CHANGE_STATUS
-	},
-};
-
-static struct fixed_voltage_config cam_8m_12v_fixed_voltage_cfg = {
-	.supply_name	= "8M_1.2V",
-	.microvolts	= 1200000,
-	.gpio		= EXYNOS4_GPE2(5), /* 8M_1.2V_EN */
-	.enable_high	= 1,
-	.init_data	= &cam_8m_12v_reg_init_data,
-};
-
-static struct platform_device cam_8m_12v_fixed_rdev = {
-	.name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_12V,
-	.dev = { .platform_data = &cam_8m_12v_fixed_voltage_cfg },
-};
-
-static struct s5p_platform_mipi_csis mipi_csis_platdata = {
-	.clk_rate	= 166000000UL,
-	.lanes		= 2,
-	.hs_settle	= 12,
-};
-
-#define GPIO_CAM_MEGA_RST	EXYNOS4_GPY3(7) /* ISP_RESET */
-#define GPIO_CAM_8M_ISP_INT	EXYNOS4_GPL2(5)
-#define GPIO_CAM_VT_NSTBY	EXYNOS4_GPL2(0)
-#define GPIO_CAM_VT_NRST	EXYNOS4_GPL2(1)
-
-static struct s5k6aa_platform_data s5k6aa_pldata = {
-	.mclk_frequency	= 24000000UL,
-	.gpio_reset	= { GPIO_CAM_VT_NRST, 0 },
-	.gpio_stby	= { GPIO_CAM_VT_NSTBY, 0 },
-	.bus_type	= V4L2_MBUS_PARALLEL,
-	.horiz_flip	= 1,
-};
-
-static struct i2c_board_info s5k6aa_board_info = {
-	I2C_BOARD_INFO("S5K6AA", 0x3c),
-	.platform_data = &s5k6aa_pldata,
-};
-
-static struct m5mols_platform_data m5mols_platdata = {
-	.gpio_reset = GPIO_CAM_MEGA_RST,
-};
-
-static struct i2c_board_info m5mols_board_info = {
-	I2C_BOARD_INFO("M5MOLS", 0x1F),
-	.platform_data	= &m5mols_platdata,
-};
-
-static struct fimc_source_info nuri_camera_sensors[] = {
-	{
-		.flags		= V4L2_MBUS_PCLK_SAMPLE_RISING |
-				  V4L2_MBUS_VSYNC_ACTIVE_LOW,
-		.fimc_bus_type	= FIMC_BUS_TYPE_ITU_601,
-		.board_info	= &s5k6aa_board_info,
-		.clk_frequency	= 24000000UL,
-		.i2c_bus_num	= 6,
-	}, {
-		.flags		= V4L2_MBUS_PCLK_SAMPLE_FALLING |
-				  V4L2_MBUS_VSYNC_ACTIVE_LOW,
-		.fimc_bus_type	= FIMC_BUS_TYPE_MIPI_CSI2,
-		.board_info	= &m5mols_board_info,
-		.clk_frequency	= 24000000UL,
-	},
-};
-
-static struct s5p_platform_fimc fimc_md_platdata = {
-	.source_info	= nuri_camera_sensors,
-	.num_clients	= ARRAY_SIZE(nuri_camera_sensors),
-};
-
-static struct gpio nuri_camera_gpios[] = {
-	{ GPIO_CAM_VT_NSTBY,	GPIOF_OUT_INIT_LOW, "CAM_VGA_NSTBY" },
-	{ GPIO_CAM_VT_NRST,	GPIOF_OUT_INIT_LOW, "CAM_VGA_NRST"  },
-	{ GPIO_CAM_8M_ISP_INT,	GPIOF_IN,           "8M_ISP_INT"  },
-	{ GPIO_CAM_MEGA_RST,	GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" },
-};
-
-static void __init nuri_camera_init(void)
-{
-	s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
-			 &s5p_device_mipi_csis0);
-	s3c_set_platdata(&fimc_md_platdata,  sizeof(fimc_md_platdata),
-			 &s5p_device_fimc_md);
-
-	if (gpio_request_array(nuri_camera_gpios,
-			       ARRAY_SIZE(nuri_camera_gpios))) {
-		pr_err("%s: GPIO request failed\n", __func__);
-		return;
-	}
-
-	m5mols_board_info.irq = s5p_register_gpio_interrupt(GPIO_CAM_8M_ISP_INT);
-	if (m5mols_board_info.irq >= 0)
-		s3c_gpio_cfgpin(GPIO_CAM_8M_ISP_INT, S3C_GPIO_SFN(0xF));
-	else
-		pr_err("%s: Failed to configure 8M_ISP_INT GPIO\n", __func__);
-
-	/* Free GPIOs controlled directly by the sensor drivers. */
-	gpio_free(GPIO_CAM_VT_NRST);
-	gpio_free(GPIO_CAM_VT_NSTBY);
-	gpio_free(GPIO_CAM_MEGA_RST);
-
-	if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A)) {
-		pr_err("%s: Camera port A setup failed\n", __func__);
-		return;
-	}
-	/* Increase drive strength of the sensor clock output */
-	s5p_gpio_set_drvstr(EXYNOS4_GPJ1(3), S5P_GPIO_DRVSTR_LV4);
-}
-
-static struct s3c2410_platform_i2c nuri_i2c6_platdata __initdata = {
-	.frequency	= 400000U,
-	.sda_delay	= 200,
-	.bus_num	= 6,
-};
-
-static struct s3c2410_platform_i2c nuri_i2c0_platdata __initdata = {
-	.frequency	= 400000U,
-	.sda_delay	= 200,
-};
-
-/* DEVFREQ controlling memory/bus */
-static struct platform_device exynos4_bus_devfreq = {
-	.name			= "exynos4210-busfreq",
-};
-
-static struct platform_device *nuri_devices[] __initdata = {
-	/* Samsung Platform Devices */
-	&s3c_device_i2c5, /* PMIC should initialize first */
-	&s3c_device_i2c0,
-	&s3c_device_i2c6,
-	&emmc_fixed_voltage,
-	&s5p_device_mipi_csis0,
-	&s5p_device_fimc0,
-	&s5p_device_fimc1,
-	&s5p_device_fimc2,
-	&s5p_device_fimc3,
-	&s5p_device_fimd0,
-	&s3c_device_hsmmc0,
-	&s3c_device_hsmmc2,
-	&s3c_device_hsmmc3,
-	&s3c_device_wdt,
-	&s3c_device_timer[0],
-	&s5p_device_ehci,
-	&s3c_device_i2c3,
-	&i2c9_gpio,
-	&s3c_device_adc,
-	&s5p_device_g2d,
-	&s5p_device_jpeg,
-	&s3c_device_rtc,
-	&s5p_device_mfc,
-	&s5p_device_mfc_l,
-	&s5p_device_mfc_r,
-	&s5p_device_fimc_md,
-	&s3c_device_usb_hsotg,
-
-	/* NURI Devices */
-	&nuri_gpio_keys,
-	&nuri_lcd_device,
-	&nuri_backlight_device,
-	&max8903_fixed_reg_dev,
-	&nuri_max8903_device,
-	&cam_vt_cam15_fixed_rdev,
-	&cam_vdda_fixed_rdev,
-	&cam_8m_12v_fixed_rdev,
-	&exynos4_bus_devfreq,
-};
-
-static void __init nuri_map_io(void)
-{
-	exynos_init_io(NULL, 0);
-	s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
-	xxti_f = 0;
-	xusbxti_f = 24000000;
-}
-
-static void __init nuri_reserve(void)
-{
-	s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
-}
-
-static void __init nuri_machine_init(void)
-{
-	nuri_sdhci_init();
-	nuri_tsp_init();
-	nuri_power_init();
-
-	s3c_i2c0_set_platdata(&nuri_i2c0_platdata);
-	i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
-	s3c_i2c3_set_platdata(&i2c3_data);
-	i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
-	s3c_i2c5_set_platdata(NULL);
-	i2c5_devs[I2C5_MAX8997].irq = gpio_to_irq(EXYNOS4_GPX0(7));
-	i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
-	i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3));
-	i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs));
-	s3c_i2c6_set_platdata(&nuri_i2c6_platdata);
-
-#ifdef CONFIG_DRM_EXYNOS
-	s5p_device_fimd0.dev.platform_data = &drm_fimd_pdata;
-	exynos4_fimd0_gpio_setup_24bpp();
-#else
-	s5p_fimd0_set_platdata(&nuri_fb_pdata);
-#endif
-
-	nuri_camera_init();
-
-	nuri_ehci_init();
-	s3c_hsotg_set_platdata(&nuri_hsotg_pdata);
-
-	/* Last */
-	platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
-}
-
-MACHINE_START(NURI, "NURI")
-	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(exynos_smp_ops),
-	.init_irq	= exynos4_init_irq,
-	.map_io		= nuri_map_io,
-	.init_machine	= nuri_machine_init,
-	.init_late	= exynos_init_late,
-	.init_time	= exynos_init_time,
-	.reserve        = &nuri_reserve,
-	.restart	= exynos4_restart,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-origen.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-origen.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-origen.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-origen.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,823 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-origen.c
- *
- * Copyright (c) 2011 Insignal Co., Ltd.
- *		http://www.insignal.co.kr/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/serial_core.h>
-#include <linux/leds.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/input.h>
-#include <linux/pwm.h>
-#include <linux/pwm_backlight.h>
-#include <linux/gpio_keys.h>
-#include <linux/i2c.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/max8997.h>
-#include <linux/lcd.h>
-#include <linux/rfkill-gpio.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <linux/platform_data/s3c-hsotg.h>
-#include <linux/platform_data/usb-ehci-s5p.h>
-#include <linux/platform_data/usb-ohci-exynos.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <video/platform_lcd.h>
-#include <video/samsung_fimd.h>
-
-#include <plat/regs-serial.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/sdhci.h>
-#include <plat/clock.h>
-#include <plat/gpio-cfg.h>
-#include <plat/backlight.h>
-#include <plat/fb.h>
-#include <plat/mfc.h>
-#include <plat/hdmi.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-
-#include <drm/exynos_drm.h>
-#include "common.h"
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define ORIGEN_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
-				 S3C2410_UCON_RXILEVEL |	\
-				 S3C2410_UCON_TXIRQMODE |	\
-				 S3C2410_UCON_RXIRQMODE |	\
-				 S3C2410_UCON_RXFIFO_TOI |	\
-				 S3C2443_UCON_RXERR_IRQEN)
-
-#define ORIGEN_ULCON_DEFAULT	S3C2410_LCON_CS8
-
-#define ORIGEN_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
-				 S5PV210_UFCON_TXTRIG4 |	\
-				 S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg origen_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport		= 0,
-		.flags		= 0,
-		.ucon		= ORIGEN_UCON_DEFAULT,
-		.ulcon		= ORIGEN_ULCON_DEFAULT,
-		.ufcon		= ORIGEN_UFCON_DEFAULT,
-	},
-	[1] = {
-		.hwport		= 1,
-		.flags		= 0,
-		.ucon		= ORIGEN_UCON_DEFAULT,
-		.ulcon		= ORIGEN_ULCON_DEFAULT,
-		.ufcon		= ORIGEN_UFCON_DEFAULT,
-	},
-	[2] = {
-		.hwport		= 2,
-		.flags		= 0,
-		.ucon		= ORIGEN_UCON_DEFAULT,
-		.ulcon		= ORIGEN_ULCON_DEFAULT,
-		.ufcon		= ORIGEN_UFCON_DEFAULT,
-	},
-	[3] = {
-		.hwport		= 3,
-		.flags		= 0,
-		.ucon		= ORIGEN_UCON_DEFAULT,
-		.ulcon		= ORIGEN_ULCON_DEFAULT,
-		.ufcon		= ORIGEN_UFCON_DEFAULT,
-	},
-};
-
-static struct regulator_consumer_supply __initdata ldo3_consumer[] = {
-	REGULATOR_SUPPLY("vddcore", "s5p-mipi-csis.0"), /* MIPI */
-	REGULATOR_SUPPLY("vdd", "exynos4-hdmi"), /* HDMI */
-	REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"), /* HDMI */
-	REGULATOR_SUPPLY("vusb_a", "s3c-hsotg"), /* OTG */
-};
-static struct regulator_consumer_supply __initdata ldo6_consumer[] = {
-	REGULATOR_SUPPLY("vddio", "s5p-mipi-csis.0"), /* MIPI */
-};
-static struct regulator_consumer_supply __initdata ldo7_consumer[] = {
-	REGULATOR_SUPPLY("avdd", "alc5625"), /* Realtek ALC5625 */
-};
-static struct regulator_consumer_supply __initdata ldo8_consumer[] = {
-	REGULATOR_SUPPLY("vdd", "s5p-adc"), /* ADC */
-	REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"), /* HDMI */
-	REGULATOR_SUPPLY("vusb_d", "s3c-hsotg"), /* OTG */
-};
-static struct regulator_consumer_supply __initdata ldo9_consumer[] = {
-	REGULATOR_SUPPLY("dvdd", "swb-a31"), /* AR6003 WLAN & CSR 8810 BT */
-};
-static struct regulator_consumer_supply __initdata ldo11_consumer[] = {
-	REGULATOR_SUPPLY("dvdd", "alc5625"), /* Realtek ALC5625 */
-};
-static struct regulator_consumer_supply __initdata ldo14_consumer[] = {
-	REGULATOR_SUPPLY("avdd18", "swb-a31"), /* AR6003 WLAN & CSR 8810 BT */
-};
-static struct regulator_consumer_supply __initdata ldo17_consumer[] = {
-	REGULATOR_SUPPLY("vdd33", "swb-a31"), /* AR6003 WLAN & CSR 8810 BT */
-};
-static struct regulator_consumer_supply __initdata buck1_consumer[] = {
-	REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */
-};
-static struct regulator_consumer_supply __initdata buck2_consumer[] = {
-	REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */
-};
-static struct regulator_consumer_supply __initdata buck3_consumer[] = {
-	REGULATOR_SUPPLY("vdd_g3d", "mali_drm"), /* G3D */
-};
-static struct regulator_consumer_supply __initdata buck7_consumer[] = {
-	REGULATOR_SUPPLY("vcc", "platform-lcd"), /* LCD */
-};
-
-static struct regulator_init_data __initdata max8997_ldo1_data = {
-	.constraints	= {
-		.name		= "VDD_ABB_3.3V",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_ldo2_data	= {
-	.constraints	= {
-		.name		= "VDD_ALIVE_1.1V",
-		.min_uV		= 1100000,
-		.max_uV		= 1100000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_ldo3_data = {
-	.constraints	= {
-		.name		= "VMIPI_1.1V",
-		.min_uV		= 1100000,
-		.max_uV		= 1100000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(ldo3_consumer),
-	.consumer_supplies	= ldo3_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_ldo4_data = {
-	.constraints	= {
-		.name		= "VDD_RTC_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_ldo6_data = {
-	.constraints	= {
-		.name		= "VMIPI_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(ldo6_consumer),
-	.consumer_supplies	= ldo6_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_ldo7_data = {
-	.constraints	= {
-		.name		= "VDD_AUD_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(ldo7_consumer),
-	.consumer_supplies	= ldo7_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_ldo8_data = {
-	.constraints	= {
-		.name		= "VADC_3.3V",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(ldo8_consumer),
-	.consumer_supplies	= ldo8_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_ldo9_data = {
-	.constraints	= {
-		.name		= "DVDD_SWB_2.8V",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(ldo9_consumer),
-	.consumer_supplies	= ldo9_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_ldo10_data = {
-	.constraints	= {
-		.name		= "VDD_PLL_1.1V",
-		.min_uV		= 1100000,
-		.max_uV		= 1100000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_ldo11_data = {
-	.constraints	= {
-		.name		= "VDD_AUD_3V",
-		.min_uV		= 3000000,
-		.max_uV		= 3000000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(ldo11_consumer),
-	.consumer_supplies	= ldo11_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_ldo14_data = {
-	.constraints	= {
-		.name		= "AVDD18_SWB_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(ldo14_consumer),
-	.consumer_supplies	= ldo14_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_ldo17_data = {
-	.constraints	= {
-		.name		= "VDD_SWB_3.3V",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(ldo17_consumer),
-	.consumer_supplies	= ldo17_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_ldo21_data = {
-	.constraints	= {
-		.name		= "VDD_MIF_1.2V",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_buck1_data = {
-	.constraints	= {
-		.name		= "VDD_ARM_1.2V",
-		.min_uV		= 950000,
-		.max_uV		= 1350000,
-		.always_on	= 1,
-		.boot_on	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(buck1_consumer),
-	.consumer_supplies	= buck1_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_buck2_data = {
-	.constraints	= {
-		.name		= "VDD_INT_1.1V",
-		.min_uV		= 900000,
-		.max_uV		= 1100000,
-		.always_on	= 1,
-		.boot_on	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(buck2_consumer),
-	.consumer_supplies	= buck2_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_buck3_data = {
-	.constraints	= {
-		.name		= "VDD_G3D_1.1V",
-		.min_uV		= 900000,
-		.max_uV		= 1100000,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
-					REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(buck3_consumer),
-	.consumer_supplies	= buck3_consumer,
-};
-
-static struct regulator_init_data __initdata max8997_buck5_data = {
-	.constraints	= {
-		.name		= "VDDQ_M1M2_1.2V",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data __initdata max8997_buck7_data = {
-	.constraints	= {
-		.name		= "VDD_LCD_3.3V",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.boot_on	= 1,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(buck7_consumer),
-	.consumer_supplies	= buck7_consumer,
-};
-
-static struct max8997_regulator_data __initdata origen_max8997_regulators[] = {
-	{ MAX8997_LDO1,		&max8997_ldo1_data },
-	{ MAX8997_LDO2,		&max8997_ldo2_data },
-	{ MAX8997_LDO3,		&max8997_ldo3_data },
-	{ MAX8997_LDO4,		&max8997_ldo4_data },
-	{ MAX8997_LDO6,		&max8997_ldo6_data },
-	{ MAX8997_LDO7,		&max8997_ldo7_data },
-	{ MAX8997_LDO8,		&max8997_ldo8_data },
-	{ MAX8997_LDO9,		&max8997_ldo9_data },
-	{ MAX8997_LDO10,	&max8997_ldo10_data },
-	{ MAX8997_LDO11,	&max8997_ldo11_data },
-	{ MAX8997_LDO14,	&max8997_ldo14_data },
-	{ MAX8997_LDO17,	&max8997_ldo17_data },
-	{ MAX8997_LDO21,	&max8997_ldo21_data },
-	{ MAX8997_BUCK1,	&max8997_buck1_data },
-	{ MAX8997_BUCK2,	&max8997_buck2_data },
-	{ MAX8997_BUCK3,	&max8997_buck3_data },
-	{ MAX8997_BUCK5,	&max8997_buck5_data },
-	{ MAX8997_BUCK7,	&max8997_buck7_data },
-};
-
-static struct max8997_platform_data __initdata origen_max8997_pdata = {
-	.num_regulators = ARRAY_SIZE(origen_max8997_regulators),
-	.regulators	= origen_max8997_regulators,
-
-	.wakeup	= true,
-	.buck1_gpiodvs	= false,
-	.buck2_gpiodvs	= false,
-	.buck5_gpiodvs	= false,
-
-	.ignore_gpiodvs_side_effect = true,
-	.buck125_default_idx = 0x0,
-
-	.buck125_gpios[0]	= EXYNOS4_GPX0(0),
-	.buck125_gpios[1]	= EXYNOS4_GPX0(1),
-	.buck125_gpios[2]	= EXYNOS4_GPX0(2),
-
-	.buck1_voltage[0]	= 1350000,
-	.buck1_voltage[1]	= 1300000,
-	.buck1_voltage[2]	= 1250000,
-	.buck1_voltage[3]	= 1200000,
-	.buck1_voltage[4]	= 1150000,
-	.buck1_voltage[5]	= 1100000,
-	.buck1_voltage[6]	= 1000000,
-	.buck1_voltage[7]	= 950000,
-
-	.buck2_voltage[0]	= 1100000,
-	.buck2_voltage[1]	= 1100000,
-	.buck2_voltage[2]	= 1100000,
-	.buck2_voltage[3]	= 1100000,
-	.buck2_voltage[4]	= 1000000,
-	.buck2_voltage[5]	= 1000000,
-	.buck2_voltage[6]	= 1000000,
-	.buck2_voltage[7]	= 1000000,
-
-	.buck5_voltage[0]	= 1200000,
-	.buck5_voltage[1]	= 1200000,
-	.buck5_voltage[2]	= 1200000,
-	.buck5_voltage[3]	= 1200000,
-	.buck5_voltage[4]	= 1200000,
-	.buck5_voltage[5]	= 1200000,
-	.buck5_voltage[6]	= 1200000,
-	.buck5_voltage[7]	= 1200000,
-};
-
-/* I2C0 */
-static struct i2c_board_info i2c0_devs[] __initdata = {
-	{
-		I2C_BOARD_INFO("max8997", (0xCC >> 1)),
-		.platform_data	= &origen_max8997_pdata,
-		.irq		= IRQ_EINT(4),
-	},
-};
-
-static struct s3c_sdhci_platdata origen_hsmmc0_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-};
-
-static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-};
-
-/* USB EHCI */
-static struct s5p_ehci_platdata origen_ehci_pdata;
-
-static void __init origen_ehci_init(void)
-{
-	struct s5p_ehci_platdata *pdata = &origen_ehci_pdata;
-
-	s5p_ehci_set_platdata(pdata);
-}
-
-/* USB OHCI */
-static struct exynos4_ohci_platdata origen_ohci_pdata;
-
-static void __init origen_ohci_init(void)
-{
-	struct exynos4_ohci_platdata *pdata = &origen_ohci_pdata;
-
-	exynos4_ohci_set_platdata(pdata);
-}
-
-/* USB OTG */
-static struct s3c_hsotg_plat origen_hsotg_pdata;
-
-static struct gpio_led origen_gpio_leds[] = {
-	{
-		.name			= "origen::status1",
-		.default_trigger	= "heartbeat",
-		.gpio			= EXYNOS4_GPX1(3),
-		.active_low		= 1,
-	},
-	{
-		.name			= "origen::status2",
-		.default_trigger	= "mmc0",
-		.gpio			= EXYNOS4_GPX1(4),
-		.active_low		= 1,
-	},
-};
-
-static struct gpio_led_platform_data origen_gpio_led_info = {
-	.leds		= origen_gpio_leds,
-	.num_leds	= ARRAY_SIZE(origen_gpio_leds),
-};
-
-static struct platform_device origen_leds_gpio = {
-	.name	= "leds-gpio",
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &origen_gpio_led_info,
-	},
-};
-
-static struct gpio_keys_button origen_gpio_keys_table[] = {
-	{
-		.code			= KEY_MENU,
-		.gpio			= EXYNOS4_GPX1(5),
-		.desc			= "gpio-keys: KEY_MENU",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.wakeup			= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_HOME,
-		.gpio			= EXYNOS4_GPX1(6),
-		.desc			= "gpio-keys: KEY_HOME",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.wakeup			= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_BACK,
-		.gpio			= EXYNOS4_GPX1(7),
-		.desc			= "gpio-keys: KEY_BACK",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.wakeup			= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_UP,
-		.gpio			= EXYNOS4_GPX2(0),
-		.desc			= "gpio-keys: KEY_UP",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.wakeup			= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_DOWN,
-		.gpio			= EXYNOS4_GPX2(1),
-		.desc			= "gpio-keys: KEY_DOWN",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.wakeup			= 1,
-		.debounce_interval	= 1,
-	},
-};
-
-static struct gpio_keys_platform_data origen_gpio_keys_data = {
-	.buttons	= origen_gpio_keys_table,
-	.nbuttons	= ARRAY_SIZE(origen_gpio_keys_table),
-};
-
-static struct platform_device origen_device_gpiokeys = {
-	.name		= "gpio-keys",
-	.dev		= {
-		.platform_data	= &origen_gpio_keys_data,
-	},
-};
-
-static void lcd_hv070wsa_set_power(struct plat_lcd_data *pd, unsigned int power)
-{
-	int ret;
-
-	if (power)
-		ret = gpio_request_one(EXYNOS4_GPE3(4),
-					GPIOF_OUT_INIT_HIGH, "GPE3_4");
-	else
-		ret = gpio_request_one(EXYNOS4_GPE3(4),
-					GPIOF_OUT_INIT_LOW, "GPE3_4");
-
-	gpio_free(EXYNOS4_GPE3(4));
-
-	if (ret)
-		pr_err("failed to request gpio for LCD power: %d\n", ret);
-}
-
-static struct plat_lcd_data origen_lcd_hv070wsa_data = {
-	.set_power = lcd_hv070wsa_set_power,
-};
-
-static struct platform_device origen_lcd_hv070wsa = {
-	.name			= "platform-lcd",
-	.dev.parent		= &s5p_device_fimd0.dev,
-	.dev.platform_data	= &origen_lcd_hv070wsa_data,
-};
-
-static struct pwm_lookup origen_pwm_lookup[] = {
-	PWM_LOOKUP("s3c24xx-pwm.0", 0, "pwm-backlight.0", NULL),
-};
-
-#ifdef CONFIG_DRM_EXYNOS_FIMD
-static struct exynos_drm_fimd_pdata drm_fimd_pdata = {
-	.panel	= {
-		.timing	= {
-			.left_margin	= 64,
-			.right_margin	= 16,
-			.upper_margin	= 64,
-			.lower_margin	= 16,
-			.hsync_len	= 48,
-			.vsync_len	= 3,
-			.xres		= 1024,
-			.yres		= 600,
-		},
-	},
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC |
-				VIDCON1_INV_VCLK,
-	.default_win	= 0,
-	.bpp		= 32,
-};
-#else
-static struct s3c_fb_pd_win origen_fb_win0 = {
-	.xres			= 1024,
-	.yres			= 600,
-	.max_bpp		= 32,
-	.default_bpp		= 24,
-	.virtual_x		= 1024,
-	.virtual_y		= 2 * 600,
-};
-
-static struct fb_videomode origen_lcd_timing = {
-	.left_margin	= 64,
-	.right_margin	= 16,
-	.upper_margin	= 64,
-	.lower_margin	= 16,
-	.hsync_len	= 48,
-	.vsync_len	= 3,
-	.xres		= 1024,
-	.yres		= 600,
-};
-
-static struct s3c_fb_platdata origen_lcd_pdata __initdata = {
-	.win[0]		= &origen_fb_win0,
-	.vtiming	= &origen_lcd_timing,
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC |
-				VIDCON1_INV_VCLK,
-	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
-};
-#endif
-
-/* Bluetooth rfkill gpio platform data */
-static struct rfkill_gpio_platform_data origen_bt_pdata = {
-	.reset_gpio	= EXYNOS4_GPX2(2),
-	.shutdown_gpio	= -1,
-	.type		= RFKILL_TYPE_BLUETOOTH,
-	.name		= "origen-bt",
-};
-
-/* Bluetooth Platform device */
-static struct platform_device origen_device_bluetooth = {
-	.name		= "rfkill_gpio",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &origen_bt_pdata,
-	},
-};
-
-static struct platform_device *origen_devices[] __initdata = {
-	&s3c_device_hsmmc2,
-	&s3c_device_hsmmc0,
-	&s3c_device_i2c0,
-	&s3c_device_rtc,
-	&s3c_device_usb_hsotg,
-	&s3c_device_wdt,
-	&s5p_device_ehci,
-	&s5p_device_fimc0,
-	&s5p_device_fimc1,
-	&s5p_device_fimc2,
-	&s5p_device_fimc3,
-	&s5p_device_fimc_md,
-	&s5p_device_fimd0,
-	&s5p_device_g2d,
-	&s5p_device_hdmi,
-	&s5p_device_i2c_hdmiphy,
-	&s5p_device_jpeg,
-	&s5p_device_mfc,
-	&s5p_device_mfc_l,
-	&s5p_device_mfc_r,
-	&s5p_device_mixer,
-	&exynos4_device_ohci,
-	&origen_device_gpiokeys,
-	&origen_lcd_hv070wsa,
-	&origen_leds_gpio,
-	&origen_device_bluetooth,
-};
-
-/* LCD Backlight data */
-static struct samsung_bl_gpio_info origen_bl_gpio_info = {
-	.no		= EXYNOS4_GPD0(0),
-	.func		= S3C_GPIO_SFN(2),
-};
-
-static struct platform_pwm_backlight_data origen_bl_data = {
-	.pwm_id		= 0,
-	.pwm_period_ns	= 1000,
-};
-
-static void __init origen_bt_setup(void)
-{
-	gpio_request(EXYNOS4_GPA0(0), "GPIO BT_UART");
-	/* 4 UART Pins configuration */
-	s3c_gpio_cfgrange_nopull(EXYNOS4_GPA0(0), 4, S3C_GPIO_SFN(2));
-	/* Setup BT Reset, this gpio will be requesed by rfkill-gpio */
-	s3c_gpio_cfgpin(EXYNOS4_GPX2(2), S3C_GPIO_OUTPUT);
-	s3c_gpio_setpull(EXYNOS4_GPX2(2), S3C_GPIO_PULL_NONE);
-}
-
-/* I2C module and id for HDMIPHY */
-static struct i2c_board_info hdmiphy_info = {
-	I2C_BOARD_INFO("hdmiphy-exynos4210", 0x38),
-};
-
-static void s5p_tv_setup(void)
-{
-	/* Direct HPD to HDMI chip */
-	gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
-	s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
-	s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
-}
-
-static void __init origen_map_io(void)
-{
-	exynos_init_io(NULL, 0);
-	s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
-	xxti_f = 0;
-	xusbxti_f = 24000000;
-}
-
-static void __init origen_power_init(void)
-{
-	gpio_request(EXYNOS4_GPX0(4), "PMIC_IRQ");
-	s3c_gpio_cfgpin(EXYNOS4_GPX0(4), S3C_GPIO_SFN(0xf));
-	s3c_gpio_setpull(EXYNOS4_GPX0(4), S3C_GPIO_PULL_NONE);
-}
-
-static void __init origen_reserve(void)
-{
-	s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
-}
-
-static void __init origen_machine_init(void)
-{
-	origen_power_init();
-
-	s3c_i2c0_set_platdata(NULL);
-	i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
-
-	/*
-	 * Since sdhci instance 2 can contain a bootable media,
-	 * sdhci instance 0 is registered after instance 2.
-	 */
-	s3c_sdhci2_set_platdata(&origen_hsmmc2_pdata);
-	s3c_sdhci0_set_platdata(&origen_hsmmc0_pdata);
-
-	origen_ehci_init();
-	origen_ohci_init();
-	s3c_hsotg_set_platdata(&origen_hsotg_pdata);
-
-	s5p_tv_setup();
-	s5p_i2c_hdmiphy_set_platdata(NULL);
-	s5p_hdmi_set_platdata(&hdmiphy_info, NULL, 0);
-
-#ifdef CONFIG_DRM_EXYNOS_FIMD
-	s5p_device_fimd0.dev.platform_data = &drm_fimd_pdata;
-	exynos4_fimd0_gpio_setup_24bpp();
-#else
-	s5p_fimd0_set_platdata(&origen_lcd_pdata);
-#endif
-
-	platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
-
-	pwm_add_table(origen_pwm_lookup, ARRAY_SIZE(origen_pwm_lookup));
-	samsung_bl_set(&origen_bl_gpio_info, &origen_bl_data);
-
-	origen_bt_setup();
-}
-
-MACHINE_START(ORIGEN, "ORIGEN")
-	/* Maintainer: JeongHyeon Kim <jhkim@insignal.co.kr> */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(exynos_smp_ops),
-	.init_irq	= exynos4_init_irq,
-	.map_io		= origen_map_io,
-	.init_machine	= origen_machine_init,
-	.init_late	= exynos_init_late,
-	.init_time	= exynos_init_time,
-	.reserve	= &origen_reserve,
-	.restart	= exynos4_restart,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-smdk4x12.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-smdk4x12.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-smdk4x12.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-smdk4x12.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,396 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/mach-smdk4x12.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gpio.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/lcd.h>
-#include <linux/mfd/max8997.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/pwm.h>
-#include <linux/pwm_backlight.h>
-#include <linux/regulator/machine.h>
-#include <linux/serial_core.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <linux/platform_data/s3c-hsotg.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <video/samsung_fimd.h>
-#include <plat/backlight.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/fb.h>
-#include <plat/gpio-cfg.h>
-#include <plat/keypad.h>
-#include <plat/mfc.h>
-#include <plat/regs-serial.h>
-#include <plat/sdhci.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <drm/exynos_drm.h>
-#include "common.h"
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define SMDK4X12_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
-				 S3C2410_UCON_RXILEVEL |	\
-				 S3C2410_UCON_TXIRQMODE |	\
-				 S3C2410_UCON_RXIRQMODE |	\
-				 S3C2410_UCON_RXFIFO_TOI |	\
-				 S3C2443_UCON_RXERR_IRQEN)
-
-#define SMDK4X12_ULCON_DEFAULT	S3C2410_LCON_CS8
-
-#define SMDK4X12_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
-				 S5PV210_UFCON_TXTRIG4 |	\
-				 S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg smdk4x12_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport		= 0,
-		.flags		= 0,
-		.ucon		= SMDK4X12_UCON_DEFAULT,
-		.ulcon		= SMDK4X12_ULCON_DEFAULT,
-		.ufcon		= SMDK4X12_UFCON_DEFAULT,
-	},
-	[1] = {
-		.hwport		= 1,
-		.flags		= 0,
-		.ucon		= SMDK4X12_UCON_DEFAULT,
-		.ulcon		= SMDK4X12_ULCON_DEFAULT,
-		.ufcon		= SMDK4X12_UFCON_DEFAULT,
-	},
-	[2] = {
-		.hwport		= 2,
-		.flags		= 0,
-		.ucon		= SMDK4X12_UCON_DEFAULT,
-		.ulcon		= SMDK4X12_ULCON_DEFAULT,
-		.ufcon		= SMDK4X12_UFCON_DEFAULT,
-	},
-	[3] = {
-		.hwport		= 3,
-		.flags		= 0,
-		.ucon		= SMDK4X12_UCON_DEFAULT,
-		.ulcon		= SMDK4X12_ULCON_DEFAULT,
-		.ufcon		= SMDK4X12_UFCON_DEFAULT,
-	},
-};
-
-static struct s3c_sdhci_platdata smdk4x12_hsmmc2_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
-	.max_width		= 8,
-	.host_caps		= MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdk4x12_hsmmc3_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-};
-
-static struct regulator_consumer_supply max8997_buck1 =
-	REGULATOR_SUPPLY("vdd_arm", NULL);
-
-static struct regulator_consumer_supply max8997_buck2 =
-	REGULATOR_SUPPLY("vdd_int", NULL);
-
-static struct regulator_consumer_supply max8997_buck3 =
-	REGULATOR_SUPPLY("vdd_g3d", NULL);
-
-static struct regulator_init_data max8997_buck1_data = {
-	.constraints	= {
-		.name		= "VDD_ARM_SMDK4X12",
-		.min_uV		= 925000,
-		.max_uV		= 1350000,
-		.always_on	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &max8997_buck1,
-};
-
-static struct regulator_init_data max8997_buck2_data = {
-	.constraints	= {
-		.name		= "VDD_INT_SMDK4X12",
-		.min_uV		= 950000,
-		.max_uV		= 1150000,
-		.always_on	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &max8997_buck2,
-};
-
-static struct regulator_init_data max8997_buck3_data = {
-	.constraints	= {
-		.name		= "VDD_G3D_SMDK4X12",
-		.min_uV		= 950000,
-		.max_uV		= 1150000,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
-				  REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &max8997_buck3,
-};
-
-static struct max8997_regulator_data smdk4x12_max8997_regulators[] = {
-	{ MAX8997_BUCK1, &max8997_buck1_data },
-	{ MAX8997_BUCK2, &max8997_buck2_data },
-	{ MAX8997_BUCK3, &max8997_buck3_data },
-};
-
-static struct max8997_platform_data smdk4x12_max8997_pdata = {
-	.num_regulators	= ARRAY_SIZE(smdk4x12_max8997_regulators),
-	.regulators	= smdk4x12_max8997_regulators,
-
-	.buck1_voltage[0] = 1100000,	/* 1.1V */
-	.buck1_voltage[1] = 1100000,	/* 1.1V */
-	.buck1_voltage[2] = 1100000,	/* 1.1V */
-	.buck1_voltage[3] = 1100000,	/* 1.1V */
-	.buck1_voltage[4] = 1100000,	/* 1.1V */
-	.buck1_voltage[5] = 1100000,	/* 1.1V */
-	.buck1_voltage[6] = 1000000,	/* 1.0V */
-	.buck1_voltage[7] = 950000,	/* 0.95V */
-
-	.buck2_voltage[0] = 1100000,	/* 1.1V */
-	.buck2_voltage[1] = 1000000,	/* 1.0V */
-	.buck2_voltage[2] = 950000,	/* 0.95V */
-	.buck2_voltage[3] = 900000,	/* 0.9V */
-	.buck2_voltage[4] = 1100000,	/* 1.1V */
-	.buck2_voltage[5] = 1000000,	/* 1.0V */
-	.buck2_voltage[6] = 950000,	/* 0.95V */
-	.buck2_voltage[7] = 900000,	/* 0.9V */
-
-	.buck5_voltage[0] = 1100000,	/* 1.1V */
-	.buck5_voltage[1] = 1100000,	/* 1.1V */
-	.buck5_voltage[2] = 1100000,	/* 1.1V */
-	.buck5_voltage[3] = 1100000,	/* 1.1V */
-	.buck5_voltage[4] = 1100000,	/* 1.1V */
-	.buck5_voltage[5] = 1100000,	/* 1.1V */
-	.buck5_voltage[6] = 1100000,	/* 1.1V */
-	.buck5_voltage[7] = 1100000,	/* 1.1V */
-};
-
-static struct i2c_board_info smdk4x12_i2c_devs0[] __initdata = {
-	{
-		I2C_BOARD_INFO("max8997", 0x66),
-		.platform_data	= &smdk4x12_max8997_pdata,
-	}
-};
-
-static struct i2c_board_info smdk4x12_i2c_devs1[] __initdata = {
-	{ I2C_BOARD_INFO("wm8994", 0x1a), }
-};
-
-static struct i2c_board_info smdk4x12_i2c_devs3[] __initdata = {
-	/* nothing here yet */
-};
-
-static struct i2c_board_info smdk4x12_i2c_devs7[] __initdata = {
-	/* nothing here yet */
-};
-
-static struct samsung_bl_gpio_info smdk4x12_bl_gpio_info = {
-	.no = EXYNOS4_GPD0(1),
-	.func = S3C_GPIO_SFN(2),
-};
-
-static struct platform_pwm_backlight_data smdk4x12_bl_data = {
-	.pwm_id = 1,
-	.pwm_period_ns  = 1000,
-};
-
-static struct pwm_lookup smdk4x12_pwm_lookup[] = {
-	PWM_LOOKUP("s3c24xx-pwm.1", 0, "pwm-backlight.0", NULL),
-};
-
-static uint32_t smdk4x12_keymap[] __initdata = {
-	/* KEY(row, col, keycode) */
-	KEY(1, 3, KEY_1), KEY(1, 4, KEY_2), KEY(1, 5, KEY_3),
-	KEY(1, 6, KEY_4), KEY(1, 7, KEY_5),
-	KEY(2, 5, KEY_D), KEY(2, 6, KEY_A), KEY(2, 7, KEY_B),
-	KEY(0, 7, KEY_E), KEY(0, 5, KEY_C)
-};
-
-static struct matrix_keymap_data smdk4x12_keymap_data __initdata = {
-	.keymap		= smdk4x12_keymap,
-	.keymap_size	= ARRAY_SIZE(smdk4x12_keymap),
-};
-
-static struct samsung_keypad_platdata smdk4x12_keypad_data __initdata = {
-	.keymap_data	= &smdk4x12_keymap_data,
-	.rows		= 3,
-	.cols		= 8,
-};
-
-#ifdef CONFIG_DRM_EXYNOS_FIMD
-static struct exynos_drm_fimd_pdata drm_fimd_pdata = {
-	.panel	= {
-		.timing	= {
-			.left_margin	= 8,
-			.right_margin	= 8,
-			.upper_margin	= 6,
-			.lower_margin	= 6,
-			.hsync_len	= 6,
-			.vsync_len	= 4,
-			.xres		= 480,
-			.yres		= 800,
-		},
-	},
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-	.default_win	= 0,
-	.bpp		= 32,
-};
-#else
-static struct s3c_fb_pd_win smdk4x12_fb_win0 = {
-	.xres		= 480,
-	.yres		= 800,
-	.virtual_x	= 480,
-	.virtual_y	= 800 * 2,
-	.max_bpp	= 32,
-	.default_bpp	= 24,
-};
-
-static struct fb_videomode smdk4x12_lcd_timing = {
-	.left_margin	= 8,
-	.right_margin	= 8,
-	.upper_margin	= 6,
-	.lower_margin	= 6,
-	.hsync_len	= 6,
-	.vsync_len	= 4,
-	.xres		= 480,
-	.yres		= 800,
-};
-
-static struct s3c_fb_platdata smdk4x12_lcd_pdata __initdata = {
-	.win[0]		= &smdk4x12_fb_win0,
-	.vtiming	= &smdk4x12_lcd_timing,
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
-};
-#endif
-
-/* USB OTG */
-static struct s3c_hsotg_plat smdk4x12_hsotg_pdata;
-
-static struct platform_device *smdk4x12_devices[] __initdata = {
-	&s3c_device_hsmmc2,
-	&s3c_device_hsmmc3,
-	&s3c_device_i2c0,
-	&s3c_device_i2c1,
-	&s3c_device_i2c3,
-	&s3c_device_i2c7,
-	&s3c_device_rtc,
-	&s3c_device_usb_hsotg,
-	&s3c_device_wdt,
-	&s5p_device_fimc0,
-	&s5p_device_fimc1,
-	&s5p_device_fimc2,
-	&s5p_device_fimc3,
-	&s5p_device_fimc_md,
-	&s5p_device_fimd0,
-	&s5p_device_mfc,
-	&s5p_device_mfc_l,
-	&s5p_device_mfc_r,
-	&samsung_device_keypad,
-};
-
-static void __init smdk4x12_map_io(void)
-{
-	exynos_init_io(NULL, 0);
-	s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs));
-}
-
-static void __init smdk4x12_reserve(void)
-{
-	s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
-}
-
-static void __init smdk4x12_machine_init(void)
-{
-	s3c_i2c0_set_platdata(NULL);
-	i2c_register_board_info(0, smdk4x12_i2c_devs0,
-				ARRAY_SIZE(smdk4x12_i2c_devs0));
-
-	s3c_i2c1_set_platdata(NULL);
-	i2c_register_board_info(1, smdk4x12_i2c_devs1,
-				ARRAY_SIZE(smdk4x12_i2c_devs1));
-
-	s3c_i2c3_set_platdata(NULL);
-	i2c_register_board_info(3, smdk4x12_i2c_devs3,
-				ARRAY_SIZE(smdk4x12_i2c_devs3));
-
-	s3c_i2c7_set_platdata(NULL);
-	i2c_register_board_info(7, smdk4x12_i2c_devs7,
-				ARRAY_SIZE(smdk4x12_i2c_devs7));
-
-	samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data);
-	pwm_add_table(smdk4x12_pwm_lookup, ARRAY_SIZE(smdk4x12_pwm_lookup));
-
-	samsung_keypad_set_platdata(&smdk4x12_keypad_data);
-
-	s3c_sdhci2_set_platdata(&smdk4x12_hsmmc2_pdata);
-	s3c_sdhci3_set_platdata(&smdk4x12_hsmmc3_pdata);
-
-	s3c_hsotg_set_platdata(&smdk4x12_hsotg_pdata);
-
-#ifdef CONFIG_DRM_EXYNOS_FIMD
-	s5p_device_fimd0.dev.platform_data = &drm_fimd_pdata;
-	exynos4_fimd0_gpio_setup_24bpp();
-#else
-	s5p_fimd0_set_platdata(&smdk4x12_lcd_pdata);
-#endif
-
-	platform_add_devices(smdk4x12_devices, ARRAY_SIZE(smdk4x12_devices));
-}
-
-MACHINE_START(SMDK4212, "SMDK4212")
-	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(exynos_smp_ops),
-	.init_irq	= exynos4_init_irq,
-	.map_io		= smdk4x12_map_io,
-	.init_machine	= smdk4x12_machine_init,
-	.init_time	= exynos_init_time,
-	.restart	= exynos4_restart,
-	.reserve	= &smdk4x12_reserve,
-MACHINE_END
-
-MACHINE_START(SMDK4412, "SMDK4412")
-	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-	/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(exynos_smp_ops),
-	.init_irq	= exynos4_init_irq,
-	.map_io		= smdk4x12_map_io,
-	.init_machine	= smdk4x12_machine_init,
-	.init_late	= exynos_init_late,
-	.init_time	= exynos_init_time,
-	.restart	= exynos4_restart,
-	.reserve	= &smdk4x12_reserve,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-smdkv310.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-smdkv310.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-smdkv310.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-smdkv310.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,444 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-smdkv310.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/serial_core.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/lcd.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/smsc911x.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-#include <linux/pwm.h>
-#include <linux/pwm_backlight.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <linux/platform_data/s3c-hsotg.h>
-#include <linux/platform_data/usb-ehci-s5p.h>
-#include <linux/platform_data/usb-ohci-exynos.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <video/platform_lcd.h>
-#include <video/samsung_fimd.h>
-#include <plat/regs-serial.h>
-#include <plat/regs-srom.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/fb.h>
-#include <plat/keypad.h>
-#include <plat/sdhci.h>
-#include <plat/gpio-cfg.h>
-#include <plat/backlight.h>
-#include <plat/mfc.h>
-#include <plat/clock.h>
-#include <plat/hdmi.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <drm/exynos_drm.h>
-#include "common.h"
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define SMDKV310_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
-				 S3C2410_UCON_RXILEVEL |	\
-				 S3C2410_UCON_TXIRQMODE |	\
-				 S3C2410_UCON_RXIRQMODE |	\
-				 S3C2410_UCON_RXFIFO_TOI |	\
-				 S3C2443_UCON_RXERR_IRQEN)
-
-#define SMDKV310_ULCON_DEFAULT	S3C2410_LCON_CS8
-
-#define SMDKV310_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
-				 S5PV210_UFCON_TXTRIG4 |	\
-				 S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport		= 0,
-		.flags		= 0,
-		.ucon		= SMDKV310_UCON_DEFAULT,
-		.ulcon		= SMDKV310_ULCON_DEFAULT,
-		.ufcon		= SMDKV310_UFCON_DEFAULT,
-	},
-	[1] = {
-		.hwport		= 1,
-		.flags		= 0,
-		.ucon		= SMDKV310_UCON_DEFAULT,
-		.ulcon		= SMDKV310_ULCON_DEFAULT,
-		.ufcon		= SMDKV310_UFCON_DEFAULT,
-	},
-	[2] = {
-		.hwport		= 2,
-		.flags		= 0,
-		.ucon		= SMDKV310_UCON_DEFAULT,
-		.ulcon		= SMDKV310_ULCON_DEFAULT,
-		.ufcon		= SMDKV310_UFCON_DEFAULT,
-	},
-	[3] = {
-		.hwport		= 3,
-		.flags		= 0,
-		.ucon		= SMDKV310_UCON_DEFAULT,
-		.ulcon		= SMDKV310_ULCON_DEFAULT,
-		.ufcon		= SMDKV310_UFCON_DEFAULT,
-	},
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
-	.max_width		= 8,
-	.host_caps		= MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_GPIO,
-	.ext_cd_gpio		= EXYNOS4_GPK0(2),
-	.ext_cd_gpio_invert	= 1,
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
-	.max_width		= 8,
-	.host_caps		= MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_GPIO,
-	.ext_cd_gpio		= EXYNOS4_GPK2(2),
-	.ext_cd_gpio_invert	= 1,
-};
-
-static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
-				   unsigned int power)
-{
-	if (power) {
-#if !defined(CONFIG_BACKLIGHT_PWM)
-		gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
-		gpio_free(EXYNOS4_GPD0(1));
-#endif
-		/* fire nRESET on power up */
-		gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
-		mdelay(100);
-
-		gpio_set_value(EXYNOS4_GPX0(6), 0);
-		mdelay(10);
-
-		gpio_set_value(EXYNOS4_GPX0(6), 1);
-		mdelay(10);
-
-		gpio_free(EXYNOS4_GPX0(6));
-	} else {
-#if !defined(CONFIG_BACKLIGHT_PWM)
-		gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
-		gpio_free(EXYNOS4_GPD0(1));
-#endif
-	}
-}
-
-static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
-	.set_power		= lcd_lte480wv_set_power,
-};
-
-static struct platform_device smdkv310_lcd_lte480wv = {
-	.name			= "platform-lcd",
-	.dev.parent		= &s5p_device_fimd0.dev,
-	.dev.platform_data	= &smdkv310_lcd_lte480wv_data,
-};
-
-#ifdef CONFIG_DRM_EXYNOS_FIMD
-static struct exynos_drm_fimd_pdata drm_fimd_pdata = {
-	.panel	= {
-		.timing	= {
-			.left_margin	= 13,
-			.right_margin	= 8,
-			.upper_margin	= 7,
-			.lower_margin	= 5,
-			.hsync_len	= 3,
-			.vsync_len	= 1,
-			.xres		= 800,
-			.yres		= 480,
-		},
-	},
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-	.default_win	= 0,
-	.bpp		= 32,
-};
-#else
-static struct s3c_fb_pd_win smdkv310_fb_win0 = {
-	.max_bpp	= 32,
-	.default_bpp	= 24,
-	.xres		= 800,
-	.yres		= 480,
-};
-
-static struct fb_videomode smdkv310_lcd_timing = {
-	.left_margin	= 13,
-	.right_margin	= 8,
-	.upper_margin	= 7,
-	.lower_margin	= 5,
-	.hsync_len	= 3,
-	.vsync_len	= 1,
-	.xres		= 800,
-	.yres		= 480,
-};
-
-static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
-	.win[0]		= &smdkv310_fb_win0,
-	.vtiming	= &smdkv310_lcd_timing,
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
-	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
-};
-#endif
-
-static struct resource smdkv310_smsc911x_resources[] = {
-	[0] = DEFINE_RES_MEM(EXYNOS4_PA_SROM_BANK(1), SZ_64K),
-	[1] = DEFINE_RES_NAMED(IRQ_EINT(5), 1, NULL, IORESOURCE_IRQ \
-						| IRQF_TRIGGER_LOW),
-};
-
-static struct smsc911x_platform_config smsc9215_config = {
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
-	.flags		= SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-	.mac		= {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
-};
-
-static struct platform_device smdkv310_smsc911x = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(smdkv310_smsc911x_resources),
-	.resource	= smdkv310_smsc911x_resources,
-	.dev		= {
-		.platform_data	= &smsc9215_config,
-	},
-};
-
-static uint32_t smdkv310_keymap[] __initdata = {
-	/* KEY(row, col, keycode) */
-	KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
-	KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
-	KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
-	KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
-};
-
-static struct matrix_keymap_data smdkv310_keymap_data __initdata = {
-	.keymap		= smdkv310_keymap,
-	.keymap_size	= ARRAY_SIZE(smdkv310_keymap),
-};
-
-static struct samsung_keypad_platdata smdkv310_keypad_data __initdata = {
-	.keymap_data	= &smdkv310_keymap_data,
-	.rows		= 2,
-	.cols		= 8,
-};
-
-static struct i2c_board_info i2c_devs1[] __initdata = {
-	{I2C_BOARD_INFO("wm8994", 0x1a),},
-};
-
-/* USB EHCI */
-static struct s5p_ehci_platdata smdkv310_ehci_pdata;
-
-static void __init smdkv310_ehci_init(void)
-{
-	struct s5p_ehci_platdata *pdata = &smdkv310_ehci_pdata;
-
-	s5p_ehci_set_platdata(pdata);
-}
-
-/* USB OHCI */
-static struct exynos4_ohci_platdata smdkv310_ohci_pdata;
-
-static void __init smdkv310_ohci_init(void)
-{
-	struct exynos4_ohci_platdata *pdata = &smdkv310_ohci_pdata;
-
-	exynos4_ohci_set_platdata(pdata);
-}
-
-/* USB OTG */
-static struct s3c_hsotg_plat smdkv310_hsotg_pdata;
-
-/* Audio device */
-static struct platform_device smdkv310_device_audio = {
-	.name = "smdk-audio",
-	.id = -1,
-};
-
-static struct platform_device *smdkv310_devices[] __initdata = {
-	&s3c_device_hsmmc0,
-	&s3c_device_hsmmc1,
-	&s3c_device_hsmmc2,
-	&s3c_device_hsmmc3,
-	&s3c_device_i2c1,
-	&s5p_device_i2c_hdmiphy,
-	&s3c_device_rtc,
-	&s3c_device_usb_hsotg,
-	&s3c_device_wdt,
-	&s5p_device_ehci,
-	&s5p_device_fimc0,
-	&s5p_device_fimc1,
-	&s5p_device_fimc2,
-	&s5p_device_fimc3,
-	&s5p_device_fimc_md,
-	&s5p_device_g2d,
-	&s5p_device_jpeg,
-	&exynos4_device_ac97,
-	&exynos4_device_i2s0,
-	&exynos4_device_ohci,
-	&samsung_device_keypad,
-	&s5p_device_mfc,
-	&s5p_device_mfc_l,
-	&s5p_device_mfc_r,
-	&exynos4_device_spdif,
-	&samsung_asoc_idma,
-	&s5p_device_fimd0,
-	&smdkv310_device_audio,
-	&smdkv310_lcd_lte480wv,
-	&smdkv310_smsc911x,
-	&exynos4_device_ahci,
-	&s5p_device_hdmi,
-	&s5p_device_mixer,
-};
-
-static void __init smdkv310_smsc911x_init(void)
-{
-	u32 cs1;
-
-	/* configure nCS1 width to 16 bits */
-	cs1 = __raw_readl(S5P_SROM_BW) &
-		~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
-	cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
-		(1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
-		(1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
-		S5P_SROM_BW__NCS1__SHIFT;
-	__raw_writel(cs1, S5P_SROM_BW);
-
-	/* set timing for nCS1 suitable for ethernet chip */
-	__raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
-		     (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
-		     (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
-		     (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
-		     (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
-		     (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
-		     (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
-}
-
-/* LCD Backlight data */
-static struct samsung_bl_gpio_info smdkv310_bl_gpio_info = {
-	.no = EXYNOS4_GPD0(1),
-	.func = S3C_GPIO_SFN(2),
-};
-
-static struct platform_pwm_backlight_data smdkv310_bl_data = {
-	.pwm_id = 1,
-	.pwm_period_ns  = 1000,
-};
-
-/* I2C module and id for HDMIPHY */
-static struct i2c_board_info hdmiphy_info = {
-	I2C_BOARD_INFO("hdmiphy-exynos4210", 0x38),
-};
-
-static struct pwm_lookup smdkv310_pwm_lookup[] = {
-	PWM_LOOKUP("s3c24xx-pwm.1", 0, "pwm-backlight.0", NULL),
-};
-
-static void s5p_tv_setup(void)
-{
-	/* direct HPD to HDMI chip */
-	WARN_ON(gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug"));
-	s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
-	s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
-}
-
-static void __init smdkv310_map_io(void)
-{
-	exynos_init_io(NULL, 0);
-	s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
-	xxti_f = 12000000;
-	xusbxti_f = 24000000;
-}
-
-static void __init smdkv310_reserve(void)
-{
-	s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
-}
-
-static void __init smdkv310_machine_init(void)
-{
-	s3c_i2c1_set_platdata(NULL);
-	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
-
-	smdkv310_smsc911x_init();
-
-	s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
-	s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
-	s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
-	s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
-
-	s5p_tv_setup();
-	s5p_i2c_hdmiphy_set_platdata(NULL);
-	s5p_hdmi_set_platdata(&hdmiphy_info, NULL, 0);
-
-	samsung_keypad_set_platdata(&smdkv310_keypad_data);
-
-	samsung_bl_set(&smdkv310_bl_gpio_info, &smdkv310_bl_data);
-	pwm_add_table(smdkv310_pwm_lookup, ARRAY_SIZE(smdkv310_pwm_lookup));
-
-#ifdef CONFIG_DRM_EXYNOS_FIMD
-	s5p_device_fimd0.dev.platform_data = &drm_fimd_pdata;
-	exynos4_fimd0_gpio_setup_24bpp();
-#else
-	s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
-#endif
-
-	smdkv310_ehci_init();
-	smdkv310_ohci_init();
-	s3c_hsotg_set_platdata(&smdkv310_hsotg_pdata);
-
-	platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
-}
-
-MACHINE_START(SMDKV310, "SMDKV310")
-	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-	/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(exynos_smp_ops),
-	.init_irq	= exynos4_init_irq,
-	.map_io		= smdkv310_map_io,
-	.init_machine	= smdkv310_machine_init,
-	.init_time	= exynos_init_time,
-	.reserve	= &smdkv310_reserve,
-	.restart	= exynos4_restart,
-MACHINE_END
-
-MACHINE_START(SMDKC210, "SMDKC210")
-	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(exynos_smp_ops),
-	.init_irq	= exynos4_init_irq,
-	.map_io		= smdkv310_map_io,
-	.init_machine	= smdkv310_machine_init,
-	.init_late	= exynos_init_late,
-	.init_time	= exynos_init_time,
-	.reserve	= &smdkv310_reserve,
-	.restart	= exynos4_restart,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-universal_c210.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-universal_c210.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/mach-universal_c210.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/mach-universal_c210.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1159 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-universal_c210.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/gpio_keys.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/mfd/max8998.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/max8952.h>
-#include <linux/mmc/host.h>
-#include <linux/i2c-gpio.h>
-#include <linux/i2c/mcs.h>
-#include <linux/i2c/atmel_mxt_ts.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <linux/platform_data/mipi-csis.h>
-#include <linux/platform_data/s3c-hsotg.h>
-#include <drm/exynos_drm.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <video/samsung_fimd.h>
-#include <plat/regs-serial.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/gpio-cfg.h>
-#include <plat/fb.h>
-#include <plat/mfc.h>
-#include <plat/sdhci.h>
-#include <plat/fimc-core.h>
-#include <plat/camport.h>
-
-#include <mach/map.h>
-
-#include <media/v4l2-mediabus.h>
-#include <media/s5p_fimc.h>
-#include <media/m5mols.h>
-#include <media/s5k6aa.h>
-
-#include "common.h"
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define UNIVERSAL_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
-				 S3C2410_UCON_RXILEVEL |	\
-				 S3C2410_UCON_TXIRQMODE |	\
-				 S3C2410_UCON_RXIRQMODE |	\
-				 S3C2410_UCON_RXFIFO_TOI |	\
-				 S3C2443_UCON_RXERR_IRQEN)
-
-#define UNIVERSAL_ULCON_DEFAULT	S3C2410_LCON_CS8
-
-#define UNIVERSAL_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
-				 S5PV210_UFCON_TXTRIG256 |	\
-				 S5PV210_UFCON_RXTRIG256)
-
-static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport		= 0,
-		.ucon		= UNIVERSAL_UCON_DEFAULT,
-		.ulcon		= UNIVERSAL_ULCON_DEFAULT,
-		.ufcon		= UNIVERSAL_UFCON_DEFAULT,
-	},
-	[1] = {
-		.hwport		= 1,
-		.ucon		= UNIVERSAL_UCON_DEFAULT,
-		.ulcon		= UNIVERSAL_ULCON_DEFAULT,
-		.ufcon		= UNIVERSAL_UFCON_DEFAULT,
-	},
-	[2] = {
-		.hwport		= 2,
-		.ucon		= UNIVERSAL_UCON_DEFAULT,
-		.ulcon		= UNIVERSAL_ULCON_DEFAULT,
-		.ufcon		= UNIVERSAL_UFCON_DEFAULT,
-	},
-	[3] = {
-		.hwport		= 3,
-		.ucon		= UNIVERSAL_UCON_DEFAULT,
-		.ulcon		= UNIVERSAL_ULCON_DEFAULT,
-		.ufcon		= UNIVERSAL_UFCON_DEFAULT,
-	},
-};
-
-static struct regulator_consumer_supply max8952_consumer =
-	REGULATOR_SUPPLY("vdd_arm", NULL);
-
-static struct regulator_init_data universal_max8952_reg_data = {
-	.constraints	= {
-		.name		= "VARM_1.2V",
-		.min_uV		= 770000,
-		.max_uV		= 1400000,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
-		.always_on	= 1,
-		.boot_on	= 1,
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &max8952_consumer,
-};
-
-static struct max8952_platform_data universal_max8952_pdata __initdata = {
-	.gpio_vid0	= EXYNOS4_GPX0(3),
-	.gpio_vid1	= EXYNOS4_GPX0(4),
-	.gpio_en	= -1, /* Not controllable, set "Always High" */
-	.default_mode	= 0, /* vid0 = 0, vid1 = 0 */
-	.dvs_mode	= { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */
-	.sync_freq	= 0, /* default: fastest */
-	.ramp_speed	= 0, /* default: fastest */
-	.reg_data	= &universal_max8952_reg_data,
-};
-
-static struct regulator_consumer_supply lp3974_buck1_consumer =
-	REGULATOR_SUPPLY("vdd_int", NULL);
-
-static struct regulator_consumer_supply lp3974_buck2_consumer =
-	REGULATOR_SUPPLY("vddg3d", NULL);
-
-static struct regulator_consumer_supply lp3974_buck3_consumer[] = {
-	REGULATOR_SUPPLY("vdet", "s5p-sdo"),
-	REGULATOR_SUPPLY("vdd_reg", "0-003c"),
-};
-
-static struct regulator_init_data lp3974_buck1_data = {
-	.constraints	= {
-		.name		= "VINT_1.1V",
-		.min_uV		= 750000,
-		.max_uV		= 1500000,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
-			REGULATOR_CHANGE_STATUS,
-		.boot_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = 1,
-	.consumer_supplies = &lp3974_buck1_consumer,
-};
-
-static struct regulator_init_data lp3974_buck2_data = {
-	.constraints	= {
-		.name		= "VG3D_1.1V",
-		.min_uV		= 750000,
-		.max_uV		= 1500000,
-		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE |
-			REGULATOR_CHANGE_STATUS,
-		.boot_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = 1,
-	.consumer_supplies = &lp3974_buck2_consumer,
-};
-
-static struct regulator_init_data lp3974_buck3_data = {
-	.constraints	= {
-		.name		= "VCC_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(lp3974_buck3_consumer),
-	.consumer_supplies = lp3974_buck3_consumer,
-};
-
-static struct regulator_init_data lp3974_buck4_data = {
-	.constraints	= {
-		.name		= "VMEM_1.2V",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.apply_uV	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data lp3974_ldo2_data = {
-	.constraints	= {
-		.name		= "VALIVE_1.2V",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-};
-
-static struct regulator_consumer_supply lp3974_ldo3_consumer[] = {
-	REGULATOR_SUPPLY("vusb_a", "s3c-hsotg"),
-	REGULATOR_SUPPLY("vdd", "exynos4-hdmi"),
-	REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"),
-	REGULATOR_SUPPLY("vddcore", "s5p-mipi-csis.0"),
-};
-
-static struct regulator_init_data lp3974_ldo3_data = {
-	.constraints	= {
-		.name		= "VUSB+MIPI_1.1V",
-		.min_uV		= 1100000,
-		.max_uV		= 1100000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(lp3974_ldo3_consumer),
-	.consumer_supplies = lp3974_ldo3_consumer,
-};
-
-static struct regulator_consumer_supply lp3974_ldo4_consumer[] = {
-	REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"),
-};
-
-static struct regulator_init_data lp3974_ldo4_data = {
-	.constraints	= {
-		.name		= "VADC_3.3V",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(lp3974_ldo4_consumer),
-	.consumer_supplies = lp3974_ldo4_consumer,
-};
-
-static struct regulator_init_data lp3974_ldo5_data = {
-	.constraints	= {
-		.name		= "VTF_2.8V",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data lp3974_ldo6_data = {
-	.constraints	= {
-		.name		= "LDO6",
-		.min_uV		= 2000000,
-		.max_uV		= 2000000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_consumer_supply lp3974_ldo7_consumer[] = {
-	REGULATOR_SUPPLY("vddio", "s5p-mipi-csis.0"),
-};
-
-static struct regulator_init_data lp3974_ldo7_data = {
-	.constraints	= {
-		.name		= "VLCD+VMIPI_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(lp3974_ldo7_consumer),
-	.consumer_supplies	= lp3974_ldo7_consumer,
-};
-
-static struct regulator_consumer_supply lp3974_ldo8_consumer[] = {
-	REGULATOR_SUPPLY("vusb_d", "s3c-hsotg"),
-	REGULATOR_SUPPLY("vdd33a_dac", "s5p-sdo"),
-};
-
-static struct regulator_init_data lp3974_ldo8_data = {
-	.constraints	= {
-		.name		= "VUSB+VDAC_3.3V",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies = ARRAY_SIZE(lp3974_ldo8_consumer),
-	.consumer_supplies = lp3974_ldo8_consumer,
-};
-
-static struct regulator_consumer_supply lp3974_ldo9_consumer =
-	REGULATOR_SUPPLY("vddio", "0-003c");
-
-static struct regulator_init_data lp3974_ldo9_data = {
-	.constraints	= {
-		.name		= "VCC_2.8V",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.apply_uV	= 1,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &lp3974_ldo9_consumer,
-};
-
-static struct regulator_init_data lp3974_ldo10_data = {
-	.constraints	= {
-		.name		= "VPLL_1.1V",
-		.min_uV		= 1100000,
-		.max_uV		= 1100000,
-		.boot_on	= 1,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_consumer_supply lp3974_ldo11_consumer =
-	REGULATOR_SUPPLY("dig_28", "0-001f");
-
-static struct regulator_init_data lp3974_ldo11_data = {
-	.constraints	= {
-		.name		= "CAM_AF_3.3V",
-		.min_uV		= 3300000,
-		.max_uV		= 3300000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &lp3974_ldo11_consumer,
-};
-
-static struct regulator_init_data lp3974_ldo12_data = {
-	.constraints	= {
-		.name		= "PS_2.8V",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data lp3974_ldo13_data = {
-	.constraints	= {
-		.name		= "VHIC_1.2V",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_consumer_supply lp3974_ldo14_consumer =
-	REGULATOR_SUPPLY("dig_18", "0-001f");
-
-static struct regulator_init_data lp3974_ldo14_data = {
-	.constraints	= {
-		.name		= "CAM_I_HOST_1.8V",
-		.min_uV		= 1800000,
-		.max_uV		= 1800000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &lp3974_ldo14_consumer,
-};
-
-
-static struct regulator_consumer_supply lp3974_ldo15_consumer =
-	REGULATOR_SUPPLY("dig_12", "0-001f");
-
-static struct regulator_init_data lp3974_ldo15_data = {
-	.constraints	= {
-		.name		= "CAM_S_DIG+FM33_CORE_1.2V",
-		.min_uV		= 1200000,
-		.max_uV		= 1200000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &lp3974_ldo15_consumer,
-};
-
-static struct regulator_consumer_supply lp3974_ldo16_consumer[] = {
-	REGULATOR_SUPPLY("vdda", "0-003c"),
-	REGULATOR_SUPPLY("a_sensor", "0-001f"),
-};
-
-static struct regulator_init_data lp3974_ldo16_data = {
-	.constraints	= {
-		.name		= "CAM_S_ANA_2.8V",
-		.min_uV		= 2800000,
-		.max_uV		= 2800000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(lp3974_ldo16_consumer),
-	.consumer_supplies	= lp3974_ldo16_consumer,
-};
-
-static struct regulator_init_data lp3974_ldo17_data = {
-	.constraints	= {
-		.name		= "VCC_3.0V_LCD",
-		.min_uV		= 3000000,
-		.max_uV		= 3000000,
-		.apply_uV	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.boot_on	= 1,
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data lp3974_32khz_ap_data = {
-	.constraints	= {
-		.name		= "32KHz AP",
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data lp3974_32khz_cp_data = {
-	.constraints	= {
-		.name		= "32KHz CP",
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data lp3974_vichg_data = {
-	.constraints	= {
-		.name		= "VICHG",
-		.state_mem	= {
-			.disabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data lp3974_esafeout1_data = {
-	.constraints	= {
-		.name		= "SAFEOUT1",
-		.min_uV		= 4800000,
-		.max_uV		= 4800000,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.always_on	= 1,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-};
-
-static struct regulator_init_data lp3974_esafeout2_data = {
-	.constraints	= {
-		.name		= "SAFEOUT2",
-		.boot_on	= 1,
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-		.state_mem	= {
-			.enabled	= 1,
-		},
-	},
-};
-
-static struct max8998_regulator_data lp3974_regulators[] = {
-	{ MAX8998_LDO2,  &lp3974_ldo2_data },
-	{ MAX8998_LDO3,  &lp3974_ldo3_data },
-	{ MAX8998_LDO4,  &lp3974_ldo4_data },
-	{ MAX8998_LDO5,  &lp3974_ldo5_data },
-	{ MAX8998_LDO6,  &lp3974_ldo6_data },
-	{ MAX8998_LDO7,  &lp3974_ldo7_data },
-	{ MAX8998_LDO8,  &lp3974_ldo8_data },
-	{ MAX8998_LDO9,  &lp3974_ldo9_data },
-	{ MAX8998_LDO10, &lp3974_ldo10_data },
-	{ MAX8998_LDO11, &lp3974_ldo11_data },
-	{ MAX8998_LDO12, &lp3974_ldo12_data },
-	{ MAX8998_LDO13, &lp3974_ldo13_data },
-	{ MAX8998_LDO14, &lp3974_ldo14_data },
-	{ MAX8998_LDO15, &lp3974_ldo15_data },
-	{ MAX8998_LDO16, &lp3974_ldo16_data },
-	{ MAX8998_LDO17, &lp3974_ldo17_data },
-	{ MAX8998_BUCK1, &lp3974_buck1_data },
-	{ MAX8998_BUCK2, &lp3974_buck2_data },
-	{ MAX8998_BUCK3, &lp3974_buck3_data },
-	{ MAX8998_BUCK4, &lp3974_buck4_data },
-	{ MAX8998_EN32KHZ_AP, &lp3974_32khz_ap_data },
-	{ MAX8998_EN32KHZ_CP, &lp3974_32khz_cp_data },
-	{ MAX8998_ENVICHG, &lp3974_vichg_data },
-	{ MAX8998_ESAFEOUT1, &lp3974_esafeout1_data },
-	{ MAX8998_ESAFEOUT2, &lp3974_esafeout2_data },
-};
-
-static struct max8998_platform_data universal_lp3974_pdata = {
-	.num_regulators		= ARRAY_SIZE(lp3974_regulators),
-	.regulators		= lp3974_regulators,
-	.buck1_voltage1		= 1100000,	/* INT */
-	.buck1_voltage2		= 1000000,
-	.buck1_voltage3		= 1100000,
-	.buck1_voltage4		= 1000000,
-	.buck1_set1		= EXYNOS4_GPX0(5),
-	.buck1_set2		= EXYNOS4_GPX0(6),
-	.buck2_voltage1		= 1200000,	/* G3D */
-	.buck2_voltage2		= 1100000,
-	.buck1_default_idx	= 0,
-	.buck2_set3		= EXYNOS4_GPE2(0),
-	.buck2_default_idx	= 0,
-	.wakeup			= true,
-};
-
-
-enum fixed_regulator_id {
-	FIXED_REG_ID_MMC0,
-	FIXED_REG_ID_HDMI_5V,
-	FIXED_REG_ID_CAM_S_IF,
-	FIXED_REG_ID_CAM_I_CORE,
-	FIXED_REG_ID_CAM_VT_DIO,
-};
-
-static struct regulator_consumer_supply hdmi_fixed_consumer =
-	REGULATOR_SUPPLY("hdmi-en", "exynos4-hdmi");
-
-static struct regulator_init_data hdmi_fixed_voltage_init_data = {
-	.constraints		= {
-		.name		= "HDMI_5V",
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &hdmi_fixed_consumer,
-};
-
-static struct fixed_voltage_config hdmi_fixed_voltage_config = {
-	.supply_name		= "HDMI_EN1",
-	.microvolts		= 5000000,
-	.gpio			= EXYNOS4_GPE0(1),
-	.enable_high		= true,
-	.init_data		= &hdmi_fixed_voltage_init_data,
-};
-
-static struct platform_device hdmi_fixed_voltage = {
-	.name			= "reg-fixed-voltage",
-	.id			= FIXED_REG_ID_HDMI_5V,
-	.dev			= {
-		.platform_data	= &hdmi_fixed_voltage_config,
-	},
-};
-
-/* GPIO I2C 5 (PMIC) */
-static struct i2c_board_info i2c5_devs[] __initdata = {
-	{
-		I2C_BOARD_INFO("max8952", 0xC0 >> 1),
-		.platform_data	= &universal_max8952_pdata,
-	}, {
-		I2C_BOARD_INFO("lp3974", 0xCC >> 1),
-		.platform_data	= &universal_lp3974_pdata,
-	},
-};
-
-/* I2C3 (TSP) */
-static struct mxt_platform_data qt602240_platform_data = {
-	.x_line		= 19,
-	.y_line		= 11,
-	.x_size		= 800,
-	.y_size		= 480,
-	.blen		= 0x11,
-	.threshold	= 0x28,
-	.voltage	= 2800000,		/* 2.8V */
-	.orient		= MXT_DIAGONAL,
-	.irqflags	= IRQF_TRIGGER_FALLING,
-};
-
-static struct i2c_board_info i2c3_devs[] __initdata = {
-	{
-		I2C_BOARD_INFO("qt602240_ts", 0x4a),
-		.platform_data = &qt602240_platform_data,
-	},
-};
-
-static void __init universal_tsp_init(void)
-{
-	int gpio;
-
-	/* TSP_LDO_ON: XMDMADDR_11 */
-	gpio = EXYNOS4_GPE2(3);
-	gpio_request_one(gpio, GPIOF_OUT_INIT_HIGH, "TSP_LDO_ON");
-	gpio_export(gpio, 0);
-
-	/* TSP_INT: XMDMADDR_7 */
-	gpio = EXYNOS4_GPE1(7);
-	gpio_request(gpio, "TSP_INT");
-
-	s5p_register_gpio_interrupt(gpio);
-	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-	s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-	i2c3_devs[0].irq = gpio_to_irq(gpio);
-}
-
-
-/* GPIO I2C 12 (3 Touchkey) */
-static uint32_t touchkey_keymap[] = {
-	/* MCS_KEY_MAP(value, keycode) */
-	MCS_KEY_MAP(0, KEY_MENU),		/* KEY_SEND */
-	MCS_KEY_MAP(1, KEY_BACK),		/* KEY_END */
-};
-
-static struct mcs_platform_data touchkey_data = {
-	.keymap		= touchkey_keymap,
-	.keymap_size	= ARRAY_SIZE(touchkey_keymap),
-	.key_maxval	= 2,
-};
-
-/* GPIO I2C 3_TOUCH 2.8V */
-#define I2C_GPIO_BUS_12		12
-static struct i2c_gpio_platform_data i2c_gpio12_data = {
-	.sda_pin	= EXYNOS4_GPE4(0),	/* XMDMDATA_8 */
-	.scl_pin	= EXYNOS4_GPE4(1),	/* XMDMDATA_9 */
-};
-
-static struct platform_device i2c_gpio12 = {
-	.name		= "i2c-gpio",
-	.id		= I2C_GPIO_BUS_12,
-	.dev		= {
-		.platform_data	= &i2c_gpio12_data,
-	},
-};
-
-static struct i2c_board_info i2c_gpio12_devs[] __initdata = {
-	{
-		I2C_BOARD_INFO("mcs5080_touchkey", 0x20),
-		.platform_data = &touchkey_data,
-	},
-};
-
-static void __init universal_touchkey_init(void)
-{
-	int gpio;
-
-	gpio = EXYNOS4_GPE3(7);			/* XMDMDATA_7 */
-	gpio_request(gpio, "3_TOUCH_INT");
-	s5p_register_gpio_interrupt(gpio);
-	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
-	i2c_gpio12_devs[0].irq = gpio_to_irq(gpio);
-
-	gpio = EXYNOS4_GPE3(3);			/* XMDMDATA_3 */
-	gpio_request_one(gpio, GPIOF_OUT_INIT_HIGH, "3_TOUCH_EN");
-}
-
-static struct s3c2410_platform_i2c universal_i2c0_platdata __initdata = {
-	.frequency	= 300 * 1000,
-	.sda_delay	= 200,
-};
-
-/* GPIO KEYS */
-static struct gpio_keys_button universal_gpio_keys_tables[] = {
-	{
-		.code			= KEY_VOLUMEUP,
-		.gpio			= EXYNOS4_GPX2(0),	/* XEINT16 */
-		.desc			= "gpio-keys: KEY_VOLUMEUP",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_VOLUMEDOWN,
-		.gpio			= EXYNOS4_GPX2(1),	/* XEINT17 */
-		.desc			= "gpio-keys: KEY_VOLUMEDOWN",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_CONFIG,
-		.gpio			= EXYNOS4_GPX2(2),	/* XEINT18 */
-		.desc			= "gpio-keys: KEY_CONFIG",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_CAMERA,
-		.gpio			= EXYNOS4_GPX2(3),	/* XEINT19 */
-		.desc			= "gpio-keys: KEY_CAMERA",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.debounce_interval	= 1,
-	}, {
-		.code			= KEY_OK,
-		.gpio			= EXYNOS4_GPX3(5),	/* XEINT29 */
-		.desc			= "gpio-keys: KEY_OK",
-		.type			= EV_KEY,
-		.active_low		= 1,
-		.debounce_interval	= 1,
-	},
-};
-
-static struct gpio_keys_platform_data universal_gpio_keys_data = {
-	.buttons	= universal_gpio_keys_tables,
-	.nbuttons	= ARRAY_SIZE(universal_gpio_keys_tables),
-};
-
-static struct platform_device universal_gpio_keys = {
-	.name			= "gpio-keys",
-	.dev			= {
-		.platform_data	= &universal_gpio_keys_data,
-	},
-};
-
-/* eMMC */
-static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
-	.max_width		= 8,
-	.host_caps		= (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
-				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-	.cd_type		= S3C_SDHCI_CD_PERMANENT,
-};
-
-static struct regulator_consumer_supply mmc0_supplies[] = {
-	REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.0"),
-};
-
-static struct regulator_init_data mmc0_fixed_voltage_init_data = {
-	.constraints		= {
-		.name		= "VMEM_VDD_2.8V",
-		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(mmc0_supplies),
-	.consumer_supplies	= mmc0_supplies,
-};
-
-static struct fixed_voltage_config mmc0_fixed_voltage_config = {
-	.supply_name		= "MASSMEMORY_EN",
-	.microvolts		= 2800000,
-	.gpio			= EXYNOS4_GPE1(3),
-	.enable_high		= true,
-	.init_data		= &mmc0_fixed_voltage_init_data,
-};
-
-static struct platform_device mmc0_fixed_voltage = {
-	.name			= "reg-fixed-voltage",
-	.id			= FIXED_REG_ID_MMC0,
-	.dev			= {
-		.platform_data	= &mmc0_fixed_voltage_config,
-	},
-};
-
-/* SD */
-static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = {
-	.max_width		= 4,
-	.host_caps		= MMC_CAP_4_BIT_DATA |
-				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
-	.ext_cd_gpio		= EXYNOS4_GPX3(4),      /* XEINT_28 */
-	.ext_cd_gpio_invert	= 1,
-	.cd_type		= S3C_SDHCI_CD_GPIO,
-};
-
-/* WiFi */
-static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = {
-	.max_width		= 4,
-	.host_caps		= MMC_CAP_4_BIT_DATA |
-				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
-	.cd_type		= S3C_SDHCI_CD_EXTERNAL,
-};
-
-static void __init universal_sdhci_init(void)
-{
-	s3c_sdhci0_set_platdata(&universal_hsmmc0_data);
-	s3c_sdhci2_set_platdata(&universal_hsmmc2_data);
-	s3c_sdhci3_set_platdata(&universal_hsmmc3_data);
-}
-
-/* I2C1 */
-static struct i2c_board_info i2c1_devs[] __initdata = {
-	/* Gyro, To be updated */
-};
-
-#ifdef CONFIG_DRM_EXYNOS
-static struct exynos_drm_fimd_pdata drm_fimd_pdata = {
-	.panel = {
-		.timing	= {
-			.left_margin	= 16,
-			.right_margin	= 16,
-			.upper_margin	= 2,
-			.lower_margin	= 28,
-			.hsync_len	= 2,
-			.vsync_len	= 1,
-			.xres		= 480,
-			.yres		= 800,
-			.refresh	= 55,
-		},
-	},
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
-			  VIDCON0_CLKSEL_LCD,
-	.vidcon1	= VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
-			  | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-	.default_win	= 3,
-	.bpp		= 32,
-};
-#else
-/* Frame Buffer */
-static struct s3c_fb_pd_win universal_fb_win0 = {
-	.max_bpp	= 32,
-	.default_bpp	= 16,
-	.xres		= 480,
-	.yres		= 800,
-	.virtual_x	= 480,
-	.virtual_y	= 2 * 800,
-};
-
-static struct fb_videomode universal_lcd_timing = {
-	.left_margin	= 16,
-	.right_margin	= 16,
-	.upper_margin	= 2,
-	.lower_margin	= 28,
-	.hsync_len	= 2,
-	.vsync_len	= 1,
-	.xres		= 480,
-	.yres		= 800,
-	.refresh	= 55,
-};
-
-static struct s3c_fb_platdata universal_lcd_pdata __initdata = {
-	.win[0]		= &universal_fb_win0,
-	.vtiming	= &universal_lcd_timing,
-	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
-			  VIDCON0_CLKSEL_LCD,
-	.vidcon1	= VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
-			  | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
-	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
-};
-#endif
-
-static struct regulator_consumer_supply cam_vt_dio_supply =
-	REGULATOR_SUPPLY("vdd_core", "0-003c");
-
-static struct regulator_init_data cam_vt_dio_reg_init_data = {
-	.constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
-	.num_consumer_supplies = 1,
-	.consumer_supplies = &cam_vt_dio_supply,
-};
-
-static struct fixed_voltage_config cam_vt_dio_fixed_voltage_cfg = {
-	.supply_name	= "CAM_VT_D_IO",
-	.microvolts	= 2800000,
-	.gpio		= EXYNOS4_GPE2(1), /* CAM_PWR_EN2 */
-	.enable_high	= 1,
-	.init_data	= &cam_vt_dio_reg_init_data,
-};
-
-static struct platform_device cam_vt_dio_fixed_reg_dev = {
-	.name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_DIO,
-	.dev = { .platform_data	= &cam_vt_dio_fixed_voltage_cfg },
-};
-
-static struct regulator_consumer_supply cam_i_core_supply =
-	REGULATOR_SUPPLY("core", "0-001f");
-
-static struct regulator_init_data cam_i_core_reg_init_data = {
-	.constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
-	.num_consumer_supplies = 1,
-	.consumer_supplies = &cam_i_core_supply,
-};
-
-static struct fixed_voltage_config cam_i_core_fixed_voltage_cfg = {
-	.supply_name	= "CAM_I_CORE_1.2V",
-	.microvolts	= 1200000,
-	.gpio		= EXYNOS4_GPE2(2),	/* CAM_8M_CORE_EN */
-	.enable_high	= 1,
-	.init_data	= &cam_i_core_reg_init_data,
-};
-
-static struct platform_device cam_i_core_fixed_reg_dev = {
-	.name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_I_CORE,
-	.dev = { .platform_data	= &cam_i_core_fixed_voltage_cfg },
-};
-
-static struct regulator_consumer_supply cam_s_if_supply =
-	REGULATOR_SUPPLY("d_sensor", "0-001f");
-
-static struct regulator_init_data cam_s_if_reg_init_data = {
-	.constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
-	.num_consumer_supplies = 1,
-	.consumer_supplies = &cam_s_if_supply,
-};
-
-static struct fixed_voltage_config cam_s_if_fixed_voltage_cfg = {
-	.supply_name	= "CAM_S_IF_1.8V",
-	.microvolts	= 1800000,
-	.gpio		= EXYNOS4_GPE3(0),	/* CAM_PWR_EN1 */
-	.enable_high	= 1,
-	.init_data	= &cam_s_if_reg_init_data,
-};
-
-static struct platform_device cam_s_if_fixed_reg_dev = {
-	.name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_S_IF,
-	.dev = { .platform_data	= &cam_s_if_fixed_voltage_cfg },
-};
-
-static struct s5p_platform_mipi_csis mipi_csis_platdata = {
-	.clk_rate	= 166000000UL,
-	.lanes		= 2,
-	.hs_settle	= 12,
-};
-
-#define GPIO_CAM_LEVEL_EN(n)	EXYNOS4_GPE4(n + 3)
-#define GPIO_CAM_8M_ISP_INT	EXYNOS4_GPX1(5)	/* XEINT_13 */
-#define GPIO_CAM_MEGA_nRST	EXYNOS4_GPE2(5)
-#define GPIO_CAM_VGA_NRST	EXYNOS4_GPE4(7)
-#define GPIO_CAM_VGA_NSTBY	EXYNOS4_GPE4(6)
-
-static int s5k6aa_set_power(int on)
-{
-	gpio_set_value(GPIO_CAM_LEVEL_EN(2), !!on);
-	return 0;
-}
-
-static struct s5k6aa_platform_data s5k6aa_platdata = {
-	.mclk_frequency	= 21600000UL,
-	.gpio_reset	= { GPIO_CAM_VGA_NRST, 0 },
-	.gpio_stby	= { GPIO_CAM_VGA_NSTBY, 0 },
-	.bus_type	= V4L2_MBUS_PARALLEL,
-	.horiz_flip	= 1,
-	.set_power	= s5k6aa_set_power,
-};
-
-static struct i2c_board_info s5k6aa_board_info = {
-	I2C_BOARD_INFO("S5K6AA", 0x3C),
-	.platform_data = &s5k6aa_platdata,
-};
-
-static int m5mols_set_power(struct device *dev, int on)
-{
-	gpio_set_value(GPIO_CAM_LEVEL_EN(1), !on);
-	gpio_set_value(GPIO_CAM_LEVEL_EN(2), !!on);
-	return 0;
-}
-
-static struct m5mols_platform_data m5mols_platdata = {
-	.gpio_reset	= GPIO_CAM_MEGA_nRST,
-	.reset_polarity	= 0,
-	.set_power	= m5mols_set_power,
-};
-
-static struct i2c_board_info m5mols_board_info = {
-	I2C_BOARD_INFO("M5MOLS", 0x1F),
-	.platform_data = &m5mols_platdata,
-};
-
-static struct fimc_source_info universal_camera_sensors[] = {
-	{
-		.mux_id		= 0,
-		.flags		= V4L2_MBUS_PCLK_SAMPLE_FALLING |
-				  V4L2_MBUS_VSYNC_ACTIVE_LOW,
-		.fimc_bus_type	= FIMC_BUS_TYPE_ITU_601,
-		.board_info	= &s5k6aa_board_info,
-		.i2c_bus_num	= 0,
-		.clk_frequency	= 24000000UL,
-	}, {
-		.mux_id		= 0,
-		.flags		= V4L2_MBUS_PCLK_SAMPLE_FALLING |
-				  V4L2_MBUS_VSYNC_ACTIVE_LOW,
-		.fimc_bus_type	= FIMC_BUS_TYPE_MIPI_CSI2,
-		.board_info	= &m5mols_board_info,
-		.i2c_bus_num	= 0,
-		.clk_frequency	= 24000000UL,
-	},
-};
-
-static struct s5p_platform_fimc fimc_md_platdata = {
-	.source_info	= universal_camera_sensors,
-	.num_clients	= ARRAY_SIZE(universal_camera_sensors),
-};
-
-static struct gpio universal_camera_gpios[] = {
-	{ GPIO_CAM_LEVEL_EN(1),	GPIOF_OUT_INIT_HIGH, "CAM_LVL_EN1" },
-	{ GPIO_CAM_LEVEL_EN(2),	GPIOF_OUT_INIT_LOW,  "CAM_LVL_EN2" },
-	{ GPIO_CAM_8M_ISP_INT,	GPIOF_IN,            "8M_ISP_INT"  },
-	{ GPIO_CAM_MEGA_nRST,	GPIOF_OUT_INIT_LOW,  "CAM_8M_NRST" },
-	{ GPIO_CAM_VGA_NRST,	GPIOF_OUT_INIT_LOW,  "CAM_VGA_NRST"  },
-	{ GPIO_CAM_VGA_NSTBY,	GPIOF_OUT_INIT_LOW,  "CAM_VGA_NSTBY" },
-};
-
-/* USB OTG */
-static struct s3c_hsotg_plat universal_hsotg_pdata;
-
-static void __init universal_camera_init(void)
-{
-	s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
-			 &s5p_device_mipi_csis0);
-	s3c_set_platdata(&fimc_md_platdata,  sizeof(fimc_md_platdata),
-			 &s5p_device_fimc_md);
-
-	if (gpio_request_array(universal_camera_gpios,
-			       ARRAY_SIZE(universal_camera_gpios))) {
-		pr_err("%s: GPIO request failed\n", __func__);
-		return;
-	}
-
-	if (!s3c_gpio_cfgpin(GPIO_CAM_8M_ISP_INT, S3C_GPIO_SFN(0xf)))
-		m5mols_board_info.irq = gpio_to_irq(GPIO_CAM_8M_ISP_INT);
-	else
-		pr_err("Failed to configure 8M_ISP_INT GPIO\n");
-
-	/* Free GPIOs controlled directly by the sensor drivers. */
-	gpio_free(GPIO_CAM_MEGA_nRST);
-	gpio_free(GPIO_CAM_8M_ISP_INT);
-	gpio_free(GPIO_CAM_VGA_NRST);
-	gpio_free(GPIO_CAM_VGA_NSTBY);
-
-	if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A))
-		pr_err("Camera port A setup failed\n");
-}
-
-static struct platform_device *universal_devices[] __initdata = {
-	/* Samsung Platform Devices */
-	&s5p_device_mipi_csis0,
-	&s5p_device_fimc0,
-	&s5p_device_fimc1,
-	&s5p_device_fimc2,
-	&s5p_device_fimc3,
-	&s5p_device_g2d,
-	&mmc0_fixed_voltage,
-	&s3c_device_hsmmc0,
-	&s3c_device_hsmmc2,
-	&s3c_device_hsmmc3,
-	&s3c_device_i2c0,
-	&s3c_device_i2c3,
-	&s3c_device_i2c5,
-	&s5p_device_i2c_hdmiphy,
-	&hdmi_fixed_voltage,
-	&s5p_device_hdmi,
-	&s5p_device_sdo,
-	&s5p_device_mixer,
-
-	/* Universal Devices */
-	&i2c_gpio12,
-	&universal_gpio_keys,
-	&s5p_device_onenand,
-	&s5p_device_fimd0,
-	&s5p_device_jpeg,
-	&s3c_device_usb_hsotg,
-	&s5p_device_mfc,
-	&s5p_device_mfc_l,
-	&s5p_device_mfc_r,
-	&cam_vt_dio_fixed_reg_dev,
-	&cam_i_core_fixed_reg_dev,
-	&cam_s_if_fixed_reg_dev,
-	&s5p_device_fimc_md,
-};
-
-static void __init universal_map_io(void)
-{
-	exynos_init_io(NULL, 0);
-	s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
-	exynos_set_timer_source(BIT(2) | BIT(4));
-	xxti_f = 0;
-	xusbxti_f = 24000000;
-}
-
-static void s5p_tv_setup(void)
-{
-	/* direct HPD to HDMI chip */
-	gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
-	s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
-	s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
-}
-
-static void __init universal_reserve(void)
-{
-	s5p_mfc_reserve_mem(0x43000000, 8 << 20, 0x51000000, 8 << 20);
-}
-
-static void __init universal_machine_init(void)
-{
-	universal_sdhci_init();
-	s5p_tv_setup();
-
-	s3c_i2c0_set_platdata(&universal_i2c0_platdata);
-	i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
-
-	universal_tsp_init();
-	s3c_i2c3_set_platdata(NULL);
-	i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
-
-	s3c_i2c5_set_platdata(NULL);
-	s5p_i2c_hdmiphy_set_platdata(NULL);
-	i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
-
-#ifdef CONFIG_DRM_EXYNOS
-	s5p_device_fimd0.dev.platform_data = &drm_fimd_pdata;
-	exynos4_fimd0_gpio_setup_24bpp();
-#else
-	s5p_fimd0_set_platdata(&universal_lcd_pdata);
-#endif
-
-	universal_touchkey_init();
-	i2c_register_board_info(I2C_GPIO_BUS_12, i2c_gpio12_devs,
-			ARRAY_SIZE(i2c_gpio12_devs));
-
-	s3c_hsotg_set_platdata(&universal_hsotg_pdata);
-	universal_camera_init();
-
-	/* Last */
-	platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
-}
-
-MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
-	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(exynos_smp_ops),
-	.init_irq	= exynos4_init_irq,
-	.map_io		= universal_map_io,
-	.init_machine	= universal_machine_init,
-	.init_late	= exynos_init_late,
-	.init_time	= exynos_init_time,
-	.reserve        = &universal_reserve,
-	.restart	= exynos4_restart,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -14,7 +14,7 @@ obj-				:=
 
 obj-$(CONFIG_ARCH_EXYNOS)	+= common.o
 
-obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_S5P_PM)		+= pm.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
@@ -32,38 +32,5 @@ AFLAGS_exynos-smc.o		:=-Wa,-march=armv7-
 
 # machine support
 
-obj-$(CONFIG_MACH_SMDKC210)		+= mach-smdkv310.o
-obj-$(CONFIG_MACH_SMDKV310)		+= mach-smdkv310.o
-obj-$(CONFIG_MACH_ARMLEX4210)		+= mach-armlex4210.o
-obj-$(CONFIG_MACH_UNIVERSAL_C210)	+= mach-universal_c210.o
-obj-$(CONFIG_MACH_NURI)			+= mach-nuri.o
-obj-$(CONFIG_MACH_ORIGEN)		+= mach-origen.o
-
-obj-$(CONFIG_MACH_SMDK4212)		+= mach-smdk4x12.o
-obj-$(CONFIG_MACH_SMDK4412)		+= mach-smdk4x12.o
-
 obj-$(CONFIG_MACH_EXYNOS4_DT)		+= mach-exynos4-dt.o
 obj-$(CONFIG_MACH_EXYNOS5_DT)		+= mach-exynos5-dt.o
-
-# device support
-
-obj-y					+= dev-uart.o
-obj-$(CONFIG_ARCH_EXYNOS4)		+= dev-audio.o
-obj-$(CONFIG_EXYNOS4_DEV_AHCI)		+= dev-ahci.o
-obj-$(CONFIG_EXYNOS_DEV_DMA)		+= dma.o
-obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI)	+= dev-ohci.o
-
-obj-$(CONFIG_ARCH_EXYNOS)		+= setup-i2c0.o
-obj-$(CONFIG_EXYNOS4_SETUP_FIMC)	+= setup-fimc.o
-obj-$(CONFIG_EXYNOS4_SETUP_FIMD0)	+= setup-fimd0.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C1)	+= setup-i2c1.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C2)	+= setup-i2c2.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C3)	+= setup-i2c3.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C4)	+= setup-i2c4.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C5)	+= setup-i2c5.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C6)	+= setup-i2c6.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C7)	+= setup-i2c7.o
-obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD)	+= setup-keypad.o
-obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
-obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY)	+= setup-usb-phy.o
-obj-$(CONFIG_EXYNOS_SETUP_SPI)		+= setup-spi.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,6 +50,8 @@ static inline void __iomem *cpu_boot_reg
 	boot_reg = cpu_boot_reg_base();
 	if (soc_is_exynos4412())
 		boot_reg += 4*cpu;
+	else if (soc_is_exynos5420())
+		boot_reg += 4;
 	return boot_reg;
 }
 
@@ -73,7 +75,7 @@ static void __iomem *scu_base_addr(void)
 
 static DEFINE_SPINLOCK(boot_lock);
 
-static void __cpuinit exynos_secondary_init(unsigned int cpu)
+static void exynos_secondary_init(unsigned int cpu)
 {
 	/*
 	 * let the primary processor know we're out of the
@@ -88,7 +90,7 @@ static void __cpuinit exynos_secondary_i
 	spin_unlock(&boot_lock);
 }
 
-static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
 	unsigned long phys_cpu = cpu_logical_map(cpu);
@@ -180,10 +182,14 @@ static void __init exynos_smp_init_cpus(
 	void __iomem *scu_base = scu_base_addr();
 	unsigned int i, ncores;
 
-	if (soc_is_exynos5250())
-		ncores = 2;
-	else
+	if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
 		ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+	else
+		/*
+		 * CPU Nodes are passed thru DT and set_cpu_possible
+		 * is set by "arm_dt_init_cpu_maps".
+		 */
+		return;
 
 	/* sanity check */
 	if (ncores > nr_cpu_ids) {
@@ -200,7 +206,7 @@ static void __init exynos_smp_prepare_cp
 {
 	int i;
 
-	if (!(soc_is_exynos5250() || soc_is_exynos5440()))
+	if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
 		scu_enable(scu_base_addr());
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/pm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/pm.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,6 @@
 #include <plat/regs-srom.h>
 
 #include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-pmu.h>
 #include <mach/pm-core.h>
@@ -218,6 +217,9 @@ static __init int exynos_pm_drvinit(void
 	struct clk *pll_base;
 	unsigned int tmp;
 
+	if (soc_is_exynos5440())
+		return 0;
+
 	s3c_pm_init();
 
 	/* All wakeup disable */
@@ -341,6 +343,9 @@ static struct syscore_ops exynos_pm_sysc
 
 static __init int exynos_pm_syscore_init(void)
 {
+	if (soc_is_exynos5440())
+		return 0;
+
 	register_syscore_ops(&exynos_pm_syscore_ops);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/pm_domains.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/pm_domains.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/pm_domains.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/pm_domains.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,17 +74,6 @@ static int exynos_pd_power_off(struct ge
 	return exynos_pd_power(domain, false);
 }
 
-#define EXYNOS_GPD(PD, BASE, NAME)			\
-static struct exynos_pm_domain PD = {			\
-	.base = (void __iomem *)BASE,			\
-	.name = NAME,					\
-	.pd = {						\
-		.power_off = exynos_pd_power_off,	\
-		.power_on = exynos_pd_power_on,	\
-	},						\
-}
-
-#ifdef CONFIG_OF
 static void exynos_add_device_to_domain(struct exynos_pm_domain *pd,
 					 struct device *dev)
 {
@@ -157,7 +146,7 @@ static struct notifier_block platform_nb
 	.notifier_call = exynos_pm_notifier_call,
 };
 
-static __init int exynos_pm_dt_parse_domains(void)
+static __init int exynos4_pm_init_power_domain(void)
 {
 	struct platform_device *pdev;
 	struct device_node *np;
@@ -193,94 +182,6 @@ static __init int exynos_pm_dt_parse_dom
 
 	return 0;
 }
-#else
-static __init int exynos_pm_dt_parse_domains(void)
-{
-	return 0;
-}
-#endif /* CONFIG_OF */
-
-static __init __maybe_unused void exynos_pm_add_dev_to_genpd(struct platform_device *pdev,
-						struct exynos_pm_domain *pd)
-{
-	if (pdev->dev.bus) {
-		if (!pm_genpd_add_device(&pd->pd, &pdev->dev))
-			pm_genpd_dev_need_restore(&pdev->dev, true);
-		else
-			pr_info("%s: error in adding %s device to %s power"
-				"domain\n", __func__, dev_name(&pdev->dev),
-				pd->name);
-	}
-}
-
-EXYNOS_GPD(exynos4_pd_mfc, S5P_PMU_MFC_CONF, "pd-mfc");
-EXYNOS_GPD(exynos4_pd_g3d, S5P_PMU_G3D_CONF, "pd-g3d");
-EXYNOS_GPD(exynos4_pd_lcd0, S5P_PMU_LCD0_CONF, "pd-lcd0");
-EXYNOS_GPD(exynos4_pd_lcd1, S5P_PMU_LCD1_CONF, "pd-lcd1");
-EXYNOS_GPD(exynos4_pd_tv, S5P_PMU_TV_CONF, "pd-tv");
-EXYNOS_GPD(exynos4_pd_cam, S5P_PMU_CAM_CONF, "pd-cam");
-EXYNOS_GPD(exynos4_pd_gps, S5P_PMU_GPS_CONF, "pd-gps");
-
-static struct exynos_pm_domain *exynos4_pm_domains[] = {
-	&exynos4_pd_mfc,
-	&exynos4_pd_g3d,
-	&exynos4_pd_lcd0,
-	&exynos4_pd_lcd1,
-	&exynos4_pd_tv,
-	&exynos4_pd_cam,
-	&exynos4_pd_gps,
-};
-
-static __init int exynos4_pm_init_power_domain(void)
-{
-	int idx;
-
-	if (of_have_populated_dt())
-		return exynos_pm_dt_parse_domains();
-
-	for (idx = 0; idx < ARRAY_SIZE(exynos4_pm_domains); idx++) {
-		struct exynos_pm_domain *pd = exynos4_pm_domains[idx];
-		int on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN;
-
-		pm_genpd_init(&pd->pd, NULL, !on);
-	}
-
-#ifdef CONFIG_S5P_DEV_FIMD0
-	exynos_pm_add_dev_to_genpd(&s5p_device_fimd0, &exynos4_pd_lcd0);
-#endif
-#ifdef CONFIG_S5P_DEV_TV
-	exynos_pm_add_dev_to_genpd(&s5p_device_hdmi, &exynos4_pd_tv);
-	exynos_pm_add_dev_to_genpd(&s5p_device_mixer, &exynos4_pd_tv);
-#endif
-#ifdef CONFIG_S5P_DEV_MFC
-	exynos_pm_add_dev_to_genpd(&s5p_device_mfc, &exynos4_pd_mfc);
-#endif
-#ifdef CONFIG_S5P_DEV_FIMC0
-	exynos_pm_add_dev_to_genpd(&s5p_device_fimc0, &exynos4_pd_cam);
-#endif
-#ifdef CONFIG_S5P_DEV_FIMC1
-	exynos_pm_add_dev_to_genpd(&s5p_device_fimc1, &exynos4_pd_cam);
-#endif
-#ifdef CONFIG_S5P_DEV_FIMC2
-	exynos_pm_add_dev_to_genpd(&s5p_device_fimc2, &exynos4_pd_cam);
-#endif
-#ifdef CONFIG_S5P_DEV_FIMC3
-	exynos_pm_add_dev_to_genpd(&s5p_device_fimc3, &exynos4_pd_cam);
-#endif
-#ifdef CONFIG_S5P_DEV_CSIS0
-	exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis0, &exynos4_pd_cam);
-#endif
-#ifdef CONFIG_S5P_DEV_CSIS1
-	exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis1, &exynos4_pd_cam);
-#endif
-#ifdef CONFIG_S5P_DEV_G2D
-	exynos_pm_add_dev_to_genpd(&s5p_device_g2d, &exynos4_pd_lcd0);
-#endif
-#ifdef CONFIG_S5P_DEV_JPEG
-	exynos_pm_add_dev_to_genpd(&s5p_device_jpeg, &exynos4_pd_cam);
-#endif
-	return 0;
-}
 arch_initcall(exynos4_pm_init_power_domain);
 
 int __init exynos_pm_late_initcall(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-fimc.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-fimc.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-fimc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-fimc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- *
- * Exynos4 camera interface GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/gpio.h>
-#include <plat/gpio-cfg.h>
-#include <plat/camport.h>
-
-int exynos4_fimc_setup_gpio(enum s5p_camport_id id)
-{
-	u32 gpio8, gpio5;
-	u32 sfn;
-	int ret;
-
-	switch (id) {
-	case S5P_CAMPORT_A:
-		gpio8 = EXYNOS4_GPJ0(0); /* PCLK, VSYNC, HREF, DATA[0:4] */
-		gpio5 = EXYNOS4_GPJ1(0); /* DATA[5:7], CLKOUT, FIELD */
-		sfn = S3C_GPIO_SFN(2);
-		break;
-
-	case S5P_CAMPORT_B:
-		gpio8 = EXYNOS4_GPE0(0); /* DATA[0:7] */
-		gpio5 = EXYNOS4_GPE1(0); /* PCLK, VSYNC, HREF, CLKOUT, FIELD */
-		sfn = S3C_GPIO_SFN(3);
-		break;
-
-	default:
-		WARN(1, "Wrong camport id: %d\n", id);
-		return -EINVAL;
-	}
-
-	ret = s3c_gpio_cfgall_range(gpio8, 8, sfn, S3C_GPIO_PULL_UP);
-	if (ret)
-		return ret;
-
-	return s3c_gpio_cfgall_range(gpio5, 5, sfn, S3C_GPIO_PULL_UP);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-fimd0.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-fimd0.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-fimd0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-fimd0.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/* linux/arch/arm/mach-exynos4/setup-fimd0.c
- *
- * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Base Exynos4 FIMD 0 configuration
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/fb.h>
-#include <linux/gpio.h>
-
-#include <video/samsung_fimd.h>
-#include <plat/gpio-cfg.h>
-
-#include <mach/map.h>
-
-void exynos4_fimd0_gpio_setup_24bpp(void)
-{
-	unsigned int reg;
-
-	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2));
-	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2));
-	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2));
-	s3c_gpio_cfgrange_nopull(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2));
-
-	/*
-	 * Set DISPLAY_CONTROL register for Display path selection.
-	 *
-	 * DISPLAY_CONTROL[1:0]
-	 * ---------------------
-	 *  00 | MIE
-	 *  01 | MDINE
-	 *  10 | FIMD : selected
-	 *  11 | FIMD
-	 */
-	reg = __raw_readl(S3C_VA_SYS + 0x0210);
-	reg |= (1 << 1);
-	__raw_writel(reg, S3C_VA_SYS + 0x0210);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c0.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c0.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c0.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2009-2012 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * I2C0 GPIO configuration.
- *
- * Based on plat-s3c64xx/setup-i2c0.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/gpio-cfg.h>
-#include <plat/cpu.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
-	if (soc_is_exynos5250() || soc_is_exynos5440())
-		/* will be implemented with gpio function */
-		return;
-
-	s3c_gpio_cfgall_range(EXYNOS4_GPD1(0), 2,
-			      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c1.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c1.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c1.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c1.c
- *
- * Copyright (C) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C1 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c1_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgall_range(EXYNOS4_GPD1(2), 2,
-			      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c2.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c2.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c2.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c2.c
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *
- * I2C2 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c2_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgall_range(EXYNOS4_GPA0(6), 2,
-			      S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c3.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c3.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c3.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c3.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C3 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c3_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgall_range(EXYNOS4_GPA1(2), 2,
-			      S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c4.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c4.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c4.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c4.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c4.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C4 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c4_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
-			      S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c5.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c5.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c5.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c5.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c5.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C5 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c5_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
-			      S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c6.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c6.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c6.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c6.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c6.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C6 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c6_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgall_range(EXYNOS4_GPC1(3), 2,
-			      S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c7.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c7.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-i2c7.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-i2c7.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c7.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *
- * I2C7 GPIO configuration.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c7_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgall_range(EXYNOS4_GPD0(2), 2,
-			      S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-keypad.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-keypad.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-keypad.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/* linux/arch/arm/mach-exynos4/setup-keypad.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * GPIO configuration for Exynos4 KeyPad device
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/gpio.h>
-#include <plat/gpio-cfg.h>
-
-void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
-{
-	/* Keypads can be of various combinations, Just making sure */
-
-	if (rows > 8) {
-		/* Set all the necessary GPX2 pins: KP_ROW[0~7] */
-		s3c_gpio_cfgall_range(EXYNOS4_GPX2(0), 8, S3C_GPIO_SFN(3),
-					S3C_GPIO_PULL_UP);
-
-		/* Set all the necessary GPX3 pins: KP_ROW[8~] */
-		s3c_gpio_cfgall_range(EXYNOS4_GPX3(0), (rows - 8),
-					 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-	} else {
-		/* Set all the necessary GPX2 pins: KP_ROW[x] */
-		s3c_gpio_cfgall_range(EXYNOS4_GPX2(0), rows, S3C_GPIO_SFN(3),
-					S3C_GPIO_PULL_UP);
-	}
-
-	/* Set all the necessary GPX1 pins to special-function 3: KP_COL[x] */
-	s3c_gpio_cfgrange_nopull(EXYNOS4_GPX1(0), cols, S3C_GPIO_SFN(3));
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-sdhci-gpio.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-sdhci-gpio.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-sdhci-gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-sdhci-gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,152 +0,0 @@
-/* linux/arch/arm/mach-exynos4/setup-sdhci-gpio.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS4 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/card.h>
-
-#include <mach/gpio.h>
-#include <plat/gpio-cfg.h>
-#include <plat/sdhci.h>
-
-void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPK0[0:1] pins to special-function 2 */
-	for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-
-	switch (width) {
-	case 8:
-		for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
-			/* Data pin GPK1[3:6] to special-function 3 */
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-			s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-		}
-	case 4:
-		for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) {
-			/* Data pin GPK0[3:6] to special-function 2 */
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-			s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-		}
-	default:
-		break;
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_cfgpin(EXYNOS4_GPK0(2), S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(EXYNOS4_GPK0(2), S3C_GPIO_PULL_UP);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-}
-
-void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPK1[0:1] pins to special-function 2 */
-	for (gpio = EXYNOS4_GPK1(0); gpio < EXYNOS4_GPK1(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-
-	for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
-		/* Data pin GPK1[3:6] to special-function 2 */
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_cfgpin(EXYNOS4_GPK1(2), S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(EXYNOS4_GPK1(2), S3C_GPIO_PULL_UP);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-}
-
-void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPK2[0:1] pins to special-function 2 */
-	for (gpio = EXYNOS4_GPK2(0); gpio < EXYNOS4_GPK2(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-
-	switch (width) {
-	case 8:
-		for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
-			/* Data pin GPK3[3:6] to special-function 3 */
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-			s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-		}
-	case 4:
-		for (gpio = EXYNOS4_GPK2(3); gpio <= EXYNOS4_GPK2(6); gpio++) {
-			/* Data pin GPK2[3:6] to special-function 2 */
-			s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-			s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-			s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-		}
-	default:
-		break;
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_cfgpin(EXYNOS4_GPK2(2), S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(EXYNOS4_GPK2(2), S3C_GPIO_PULL_UP);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-}
-
-void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
-{
-	struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
-	unsigned int gpio;
-
-	/* Set all the necessary GPK3[0:1] pins to special-function 2 */
-	for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) {
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-
-	for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
-		/* Data pin GPK3[3:6] to special-function 2 */
-		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-
-	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
-		s3c_gpio_cfgpin(EXYNOS4_GPK3(2), S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(EXYNOS4_GPK3(2), S3C_GPIO_PULL_UP);
-		s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
-	}
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-spi.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-spi.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-spi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/* linux/arch/arm/mach-exynos4/setup-spi.c
- *
- * Copyright (C) 2011 Samsung Electronics Ltd.
- *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/gpio.h>
-#include <plat/gpio-cfg.h>
-
-#ifdef CONFIG_S3C64XX_DEV_SPI0
-int s3c64xx_spi0_cfg_gpio(void)
-{
-	s3c_gpio_cfgpin(EXYNOS4_GPB(0), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(EXYNOS4_GPB(0), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
-			      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_S3C64XX_DEV_SPI1
-int s3c64xx_spi1_cfg_gpio(void)
-{
-	s3c_gpio_cfgpin(EXYNOS4_GPB(4), S3C_GPIO_SFN(2));
-	s3c_gpio_setpull(EXYNOS4_GPB(4), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
-			      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_S3C64XX_DEV_SPI2
-int s3c64xx_spi2_cfg_gpio(void)
-{
-	s3c_gpio_cfgpin(EXYNOS4_GPC1(1), S3C_GPIO_SFN(5));
-	s3c_gpio_setpull(EXYNOS4_GPC1(1), S3C_GPIO_PULL_UP);
-	s3c_gpio_cfgall_range(EXYNOS4_GPC1(3), 2,
-			      S3C_GPIO_SFN(5), S3C_GPIO_PULL_UP);
-	return 0;
-}
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-usb-phy.c linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-usb-phy.c
--- linux-libre-3.10-gnu/arch/arm/mach-exynos/setup-usb-phy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-exynos/setup-usb-phy.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <mach/regs-pmu.h>
-#include <mach/regs-usb-phy.h>
-#include <plat/cpu.h>
-#include <plat/usb-phy.h>
-
-static atomic_t host_usage;
-
-static int exynos4_usb_host_phy_is_on(void)
-{
-	return (readl(EXYNOS4_PHYPWR) & PHY1_STD_ANALOG_POWERDOWN) ? 0 : 1;
-}
-
-static void exynos4210_usb_phy_clkset(struct platform_device *pdev)
-{
-	struct clk *xusbxti_clk;
-	u32 phyclk;
-
-	xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
-	if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
-		if (soc_is_exynos4210()) {
-			/* set clock frequency for PLL */
-			phyclk = readl(EXYNOS4_PHYCLK) & ~EXYNOS4210_CLKSEL_MASK;
-
-			switch (clk_get_rate(xusbxti_clk)) {
-			case 12 * MHZ:
-				phyclk |= EXYNOS4210_CLKSEL_12M;
-				break;
-			case 48 * MHZ:
-				phyclk |= EXYNOS4210_CLKSEL_48M;
-				break;
-			default:
-			case 24 * MHZ:
-				phyclk |= EXYNOS4210_CLKSEL_24M;
-				break;
-			}
-			writel(phyclk, EXYNOS4_PHYCLK);
-		} else if (soc_is_exynos4212() || soc_is_exynos4412()) {
-			/* set clock frequency for PLL */
-			phyclk = readl(EXYNOS4_PHYCLK) & ~EXYNOS4X12_CLKSEL_MASK;
-
-			switch (clk_get_rate(xusbxti_clk)) {
-			case 9600 * KHZ:
-				phyclk |= EXYNOS4X12_CLKSEL_9600K;
-				break;
-			case 10 * MHZ:
-				phyclk |= EXYNOS4X12_CLKSEL_10M;
-				break;
-			case 12 * MHZ:
-				phyclk |= EXYNOS4X12_CLKSEL_12M;
-				break;
-			case 19200 * KHZ:
-				phyclk |= EXYNOS4X12_CLKSEL_19200K;
-				break;
-			case 20 * MHZ:
-				phyclk |= EXYNOS4X12_CLKSEL_20M;
-				break;
-			default:
-			case 24 * MHZ:
-				/* default reference clock */
-				phyclk |= EXYNOS4X12_CLKSEL_24M;
-				break;
-			}
-			writel(phyclk, EXYNOS4_PHYCLK);
-		}
-		clk_put(xusbxti_clk);
-	}
-}
-
-static int exynos4210_usb_phy0_init(struct platform_device *pdev)
-{
-	u32 rstcon;
-
-	writel(readl(S5P_USBDEVICE_PHY_CONTROL) | S5P_USBDEVICE_PHY_ENABLE,
-			S5P_USBDEVICE_PHY_CONTROL);
-
-	exynos4210_usb_phy_clkset(pdev);
-
-	/* set to normal PHY0 */
-	writel((readl(EXYNOS4_PHYPWR) & ~PHY0_NORMAL_MASK), EXYNOS4_PHYPWR);
-
-	/* reset PHY0 and Link */
-	rstcon = readl(EXYNOS4_RSTCON) | PHY0_SWRST_MASK;
-	writel(rstcon, EXYNOS4_RSTCON);
-	udelay(10);
-
-	rstcon &= ~PHY0_SWRST_MASK;
-	writel(rstcon, EXYNOS4_RSTCON);
-
-	return 0;
-}
-
-static int exynos4210_usb_phy0_exit(struct platform_device *pdev)
-{
-	writel((readl(EXYNOS4_PHYPWR) | PHY0_ANALOG_POWERDOWN |
-				PHY0_OTG_DISABLE), EXYNOS4_PHYPWR);
-
-	writel(readl(S5P_USBDEVICE_PHY_CONTROL) & ~S5P_USBDEVICE_PHY_ENABLE,
-			S5P_USBDEVICE_PHY_CONTROL);
-
-	return 0;
-}
-
-static int exynos4210_usb_phy1_init(struct platform_device *pdev)
-{
-	struct clk *otg_clk;
-	u32 rstcon;
-	int err;
-
-	atomic_inc(&host_usage);
-
-	otg_clk = clk_get(&pdev->dev, "otg");
-	if (IS_ERR(otg_clk)) {
-		dev_err(&pdev->dev, "Failed to get otg clock\n");
-		return PTR_ERR(otg_clk);
-	}
-
-	err = clk_enable(otg_clk);
-	if (err) {
-		clk_put(otg_clk);
-		return err;
-	}
-
-	if (exynos4_usb_host_phy_is_on())
-		return 0;
-
-	writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
-			S5P_USBHOST_PHY_CONTROL);
-
-	exynos4210_usb_phy_clkset(pdev);
-
-	/* floating prevention logic: disable */
-	writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
-
-	/* set to normal HSIC 0 and 1 of PHY1 */
-	writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK),
-			EXYNOS4_PHYPWR);
-
-	/* set to normal standard USB of PHY1 */
-	writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR);
-
-	/* reset all ports of both PHY and Link */
-	rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK |
-		PHY1_SWRST_MASK;
-	writel(rstcon, EXYNOS4_RSTCON);
-	udelay(10);
-
-	rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
-	writel(rstcon, EXYNOS4_RSTCON);
-	udelay(80);
-
-	clk_disable(otg_clk);
-	clk_put(otg_clk);
-
-	return 0;
-}
-
-static int exynos4210_usb_phy1_exit(struct platform_device *pdev)
-{
-	struct clk *otg_clk;
-	int err;
-
-	if (atomic_dec_return(&host_usage) > 0)
-		return 0;
-
-	otg_clk = clk_get(&pdev->dev, "otg");
-	if (IS_ERR(otg_clk)) {
-		dev_err(&pdev->dev, "Failed to get otg clock\n");
-		return PTR_ERR(otg_clk);
-	}
-
-	err = clk_enable(otg_clk);
-	if (err) {
-		clk_put(otg_clk);
-		return err;
-	}
-
-	writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN),
-			EXYNOS4_PHYPWR);
-
-	writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE,
-			S5P_USBHOST_PHY_CONTROL);
-
-	clk_disable(otg_clk);
-	clk_put(otg_clk);
-
-	return 0;
-}
-
-int s5p_usb_phy_init(struct platform_device *pdev, int type)
-{
-	if (type == USB_PHY_TYPE_DEVICE)
-		return exynos4210_usb_phy0_init(pdev);
-	else if (type == USB_PHY_TYPE_HOST)
-		return exynos4210_usb_phy1_init(pdev);
-
-	return -EINVAL;
-}
-
-int s5p_usb_phy_exit(struct platform_device *pdev, int type)
-{
-	if (type == USB_PHY_TYPE_DEVICE)
-		return exynos4210_usb_phy0_exit(pdev);
-	else if (type == USB_PHY_TYPE_HOST)
-		return exynos4210_usb_phy1_exit(pdev);
-
-	return -EINVAL;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-footbridge/cats-hw.c linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/cats-hw.c
--- linux-libre-3.10-gnu/arch/arm/mach-footbridge/cats-hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/cats-hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -86,7 +86,7 @@ fixup_cats(struct tag *tags, char **cmdl
 MACHINE_START(CATS, "Chalice-CATS")
 	/* Maintainer: Philip Blundell */
 	.atag_offset	= 0x100,
-	.restart_mode	= 's',
+	.reboot_mode	= REBOOT_SOFT,
 	.fixup		= fixup_cats,
 	.map_io		= footbridge_map_io,
 	.init_irq	= footbridge_init_irq,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-footbridge/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-footbridge/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -198,9 +198,9 @@ void __init footbridge_map_io(void)
 	}
 }
 
-void footbridge_restart(char mode, const char *cmd)
+void footbridge_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's') {
+	if (mode == REBOOT_SOFT) {
 		/* Jump into the ROM */
 		soft_restart(0x41000000);
 	} else {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-footbridge/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-footbridge/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,3 +1,4 @@
+#include <linux/reboot.h>
 
 extern void footbridge_timer_init(void);
 extern void isa_timer_init(void);
@@ -8,4 +9,4 @@ extern void footbridge_map_io(void);
 extern void footbridge_init_irq(void);
 
 extern void isa_init_irq(unsigned int irq);
-extern void footbridge_restart(char, const char *);
+extern void footbridge_restart(enum reboot_mode, const char *);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-footbridge/dc21285.c linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/dc21285.c
--- linux-libre-3.10-gnu/arch/arm/mach-footbridge/dc21285.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/dc21285.c	2013-08-25 20:43:22.000000000 -0400
@@ -276,8 +276,6 @@ int __init dc21285_setup(int nr, struct
 
 	sys->mem_offset  = DC21285_PCI_MEM;
 
-	pci_ioremap_io(0, DC21285_PCI_IO);
-
 	pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset);
 	pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-footbridge/netwinder-hw.c linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/netwinder-hw.c
--- linux-libre-3.10-gnu/arch/arm/mach-footbridge/netwinder-hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-footbridge/netwinder-hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -634,9 +634,9 @@ fixup_netwinder(struct tag *tags, char *
 #endif
 }
 
-static void netwinder_restart(char mode, const char *cmd)
+static void netwinder_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's') {
+	if (mode == REBOOT_SOFT) {
 		/* Jump into the ROM */
 		soft_restart(0x41000000);
 	} else {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-highbank/core.h linux-libre-3.11-rc7-gnu/arch/arm/mach-highbank/core.h
--- linux-libre-3.10-gnu/arch/arm/mach-highbank/core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-highbank/core.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,8 +1,10 @@
 #ifndef __HIGHBANK_CORE_H
 #define __HIGHBANK_CORE_H
 
+#include <linux/reboot.h>
+
 extern void highbank_set_cpu_jump(int cpu, void *jump_addr);
-extern void highbank_restart(char, const char *);
+extern void highbank_restart(enum reboot_mode, const char *);
 extern void __iomem *scu_base_addr;
 
 #ifdef CONFIG_PM_SLEEP
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-highbank/highbank.c linux-libre-3.11-rc7-gnu/arch/arm/mach-highbank/highbank.c
--- linux-libre-3.10-gnu/arch/arm/mach-highbank/highbank.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-highbank/highbank.c	2013-08-25 20:43:22.000000000 -0400
@@ -115,6 +115,7 @@ static int highbank_platform_notifier(st
 {
 	struct resource *res;
 	int reg = -1;
+	u32 val;
 	struct device *dev = __dev;
 
 	if (event != BUS_NOTIFY_ADD_DEVICE)
@@ -141,10 +142,10 @@ static int highbank_platform_notifier(st
 		return NOTIFY_DONE;
 
 	if (of_property_read_bool(dev->of_node, "dma-coherent")) {
-		writel(0xff31, sregs_base + reg);
+		val = readl(sregs_base + reg);
+		writel(val | 0xff01, sregs_base + reg);
 		set_dma_ops(dev, &arm_coherent_dma_ops);
-	} else
-		writel(0, sregs_base + reg);
+	}
 
 	return NOTIFY_OK;
 }
@@ -176,7 +177,6 @@ static const char *highbank_match[] __in
 
 DT_MACHINE_START(HIGHBANK, "Highbank")
 	.smp		= smp_ops(highbank_smp_ops),
-	.map_io		= debug_ll_io_init,
 	.init_irq	= highbank_init_irq,
 	.init_time	= highbank_timer_init,
 	.init_machine	= highbank_init,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-highbank/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-highbank/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-highbank/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-highbank/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
 
 extern void secondary_startup(void);
 
-static int __cpuinit highbank_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int highbank_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	highbank_set_cpu_jump(cpu, secondary_startup);
 	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-highbank/system.c linux-libre-3.11-rc7-gnu/arch/arm/mach-highbank/system.c
--- linux-libre-3.10-gnu/arch/arm/mach-highbank/system.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-highbank/system.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,13 +15,14 @@
  */
 #include <linux/io.h>
 #include <asm/proc-fns.h>
+#include <linux/reboot.h>
 
 #include "core.h"
 #include "sysregs.h"
 
-void highbank_restart(char mode, const char *cmd)
+void highbank_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 'h')
+	if (mode == REBOOT_HARD)
 		highbank_set_pwr_hard_reset();
 	else
 		highbank_set_pwr_soft_reset();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/clk.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/clk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,39 @@
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include "clk.h"
 
 DEFINE_SPINLOCK(imx_ccm_lock);
+
+static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
+{
+	struct of_phandle_args phandle;
+	struct clk *clk = ERR_PTR(-ENODEV);
+	char *path;
+
+	path = kasprintf(GFP_KERNEL, "/clocks/%s", name);
+	if (!path)
+		return ERR_PTR(-ENOMEM);
+
+	phandle.np = of_find_node_by_path(path);
+	kfree(path);
+
+	if (phandle.np) {
+		clk = of_clk_get_from_provider(&phandle);
+		of_node_put(phandle.np);
+	}
+	return clk;
+}
+
+struct clk * __init imx_obtain_fixed_clock(
+			const char *name, unsigned long rate)
+{
+	struct clk *clk;
+
+	clk = imx_obtain_fixed_clock_from_dt(name);
+	if (IS_ERR(clk))
+		clk = imx_clk_fixed(name, rate);
+	return clk;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/clk.h linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk.h
--- linux-libre-3.10-gnu/arch/arm/mach-imx/clk.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,6 @@ enum imx_pllv3_type {
 	IMX_PLLV3_USB,
 	IMX_PLLV3_AV,
 	IMX_PLLV3_ENET,
-	IMX_PLLV3_MLB,
 };
 
 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
@@ -29,6 +28,9 @@ struct clk *clk_register_gate2(struct de
 		void __iomem *reg, u8 bit_idx,
 		u8 clk_gate_flags, spinlock_t *lock);
 
+struct clk * imx_obtain_fixed_clock(
+			const char *name, unsigned long rate);
+
 static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
 		void __iomem *reg, u8 shift)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/clk-imx51-imx53.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-imx51-imx53.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/clk-imx51-imx53.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-imx51-imx53.c	2013-08-25 20:43:22.000000000 -0400
@@ -73,6 +73,12 @@ static const char *mx53_cko2_sel[] = {
 	"tve_sel", "lp_apm",
 	"uart_root", "dummy"/* spdif0_clk_root */,
 	"dummy", "dummy", };
+static const char *mx51_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", };
+static const char *mx53_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", "pll4_sw", };
+static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", };
+static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", };
+static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", };
+
 
 enum imx5_clks {
 	dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
@@ -110,7 +116,9 @@ enum imx5_clks {
 	owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate,
 	cko1_sel, cko1_podf, cko1,
 	cko2_sel, cko2_podf, cko2,
-	srtc_gate, pata_gate,
+	srtc_gate, pata_gate, sata_gate, spdif_xtal_sel, spdif0_sel,
+	spdif1_sel, spdif0_pred, spdif0_podf, spdif1_pred, spdif1_podf,
+	spdif0_com_s, spdif1_com_sel, spdif0_gate, spdif1_gate, spdif_ipg_gate,
 	clk_max
 };
 
@@ -123,11 +131,13 @@ static void __init mx5_clocks_common_ini
 {
 	int i;
 
+	of_clk_init(NULL);
+
 	clk[dummy] = imx_clk_fixed("dummy", 0);
-	clk[ckil] = imx_clk_fixed("ckil", rate_ckil);
-	clk[osc] = imx_clk_fixed("osc", rate_osc);
-	clk[ckih1] = imx_clk_fixed("ckih1", rate_ckih1);
-	clk[ckih2] = imx_clk_fixed("ckih2", rate_ckih2);
+	clk[ckil] = imx_obtain_fixed_clock("ckil", rate_ckil);
+	clk[osc] = imx_obtain_fixed_clock("osc", rate_osc);
+	clk[ckih1] = imx_obtain_fixed_clock("ckih1", rate_ckih1);
+	clk[ckih2] = imx_obtain_fixed_clock("ckih2", rate_ckih2);
 
 	clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
 				lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
@@ -267,6 +277,13 @@ static void __init mx5_clocks_common_ini
 	clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
 	clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
 	clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
+	clk[spdif0_sel] = imx_clk_mux("spdif0_sel", MXC_CCM_CSCMR2, 0, 2, spdif_sel, ARRAY_SIZE(spdif_sel));
+	clk[spdif0_pred] = imx_clk_divider("spdif0_pred", "spdif0_sel", MXC_CCM_CDCDR, 25, 3);
+	clk[spdif0_podf] = imx_clk_divider("spdif0_podf", "spdif0_pred", MXC_CCM_CDCDR, 19, 6);
+	clk[spdif0_com_s] = imx_clk_mux_flags("spdif0_com_sel", MXC_CCM_CSCMR2, 4, 1,
+				spdif0_com_sel, ARRAY_SIZE(spdif0_com_sel), CLK_SET_RATE_PARENT);
+	clk[spdif0_gate] = imx_clk_gate2("spdif0_gate", "spdif0_com_sel", MXC_CCM_CCGR5, 26);
+	clk[spdif_ipg_gate] = imx_clk_gate2("spdif_ipg_gate", "ipg", MXC_CCM_CCGR5, 30);
 
 	for (i = 0; i < ARRAY_SIZE(clk); i++)
 		if (IS_ERR(clk[i]))
@@ -310,8 +327,6 @@ static void __init mx5_clocks_common_ini
 	clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
 	clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
 	clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2");
-	clk_register_clkdev(clk[ssi_ext1_gate], "ssi_ext1", NULL);
-	clk_register_clkdev(clk[ssi_ext2_gate], "ssi_ext2", NULL);
 	clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
 	clk_register_clkdev(clk[cpu_podf], NULL, "cpufreq-cpu0.0");
 	clk_register_clkdev(clk[iim_gate], "iim", NULL);
@@ -378,6 +393,15 @@ int __init mx51_clocks_init(unsigned lon
 	clk[mipi_hsc2_gate] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8);
 	clk[mipi_esc_gate] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10);
 	clk[mipi_hsp_gate] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12);
+	clk[spdif_xtal_sel] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
+				mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel));
+	clk[spdif1_sel] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2,
+				spdif_sel, ARRAY_SIZE(spdif_sel));
+	clk[spdif1_pred] = imx_clk_divider("spdif1_podf", "spdif1_sel", MXC_CCM_CDCDR, 16, 3);
+	clk[spdif1_podf] = imx_clk_divider("spdif1_podf", "spdif1_pred", MXC_CCM_CDCDR, 9, 6);
+	clk[spdif1_com_sel] = imx_clk_mux("spdif1_com_sel", MXC_CCM_CSCMR2, 5, 1,
+				mx51_spdif1_com_sel, ARRAY_SIZE(mx51_spdif1_com_sel));
+	clk[spdif1_gate] = imx_clk_gate2("spdif1_gate", "spdif1_com_sel", MXC_CCM_CCGR5, 28);
 
 	for (i = 0; i < ARRAY_SIZE(clk); i++)
 		if (IS_ERR(clk[i]))
@@ -485,6 +509,7 @@ int __init mx53_clocks_init(unsigned lon
 	clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8);
 	clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
 	clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
+	clk[sata_gate] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2);
 
 	clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
 				mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
@@ -495,6 +520,8 @@ int __init mx53_clocks_init(unsigned lon
 				mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
 	clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
 	clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
+	clk[spdif_xtal_sel] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
+				mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel));
 
 	for (i = 0; i < ARRAY_SIZE(clk); i++)
 		if (IS_ERR(clk[i]))
@@ -542,42 +569,12 @@ int __init mx53_clocks_init(unsigned lon
 	return 0;
 }
 
-#ifdef CONFIG_OF
-static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
-				   unsigned long *ckih1, unsigned long *ckih2)
-{
-	struct device_node *np;
-
-	/* retrieve the freqency of fixed clocks from device tree */
-	for_each_compatible_node(np, NULL, "fixed-clock") {
-		u32 rate;
-		if (of_property_read_u32(np, "clock-frequency", &rate))
-			continue;
-
-		if (of_device_is_compatible(np, "fsl,imx-ckil"))
-			*ckil = rate;
-		else if (of_device_is_compatible(np, "fsl,imx-osc"))
-			*osc = rate;
-		else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
-			*ckih1 = rate;
-		else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
-			*ckih2 = rate;
-	}
-}
-
 int __init mx51_clocks_init_dt(void)
 {
-	unsigned long ckil, osc, ckih1, ckih2;
-
-	clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
-	return mx51_clocks_init(ckil, osc, ckih1, ckih2);
+	return mx51_clocks_init(0, 0, 0, 0);
 }
 
 int __init mx53_clocks_init_dt(void)
 {
-	unsigned long ckil, osc, ckih1, ckih2;
-
-	clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
-	return mx53_clocks_init(ckil, osc, ckih1, ckih2);
+	return mx53_clocks_init(0, 0, 0, 0);
 }
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/clk-imx6q.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-imx6q.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/clk-imx6q.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-imx6q.c	2013-08-25 20:43:22.000000000 -0400
@@ -199,7 +199,8 @@ static const char *pcie_axi_sels[]	= { "
 static const char *ssi_sels[]		= { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", };
 static const char *usdhc_sels[]	= { "pll2_pfd2_396m", "pll2_pfd0_352m", };
 static const char *enfc_sels[]	= { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
-static const char *emi_sels[]		= { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *emi_sels[]		= { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", };
+static const char *emi_slow_sels[]      = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
 static const char *vdo_axi_sels[]	= { "axi", "ahb", };
 static const char *vpu_axi_sels[]	= { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
 static const char *cko1_sels[]	= { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div",
@@ -238,7 +239,7 @@ enum mx6q_clks {
 	pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
 	ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
 	sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
-	usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, clk_max
+	usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow, clk_max
 };
 
 static struct clk *clk[clk_max];
@@ -270,27 +271,16 @@ static struct clk_div_table video_div_ta
 	{ }
 };
 
-int __init mx6q_clocks_init(void)
+static void __init imx6q_clocks_init(struct device_node *ccm_node)
 {
 	struct device_node *np;
 	void __iomem *base;
 	int i, irq;
 
 	clk[dummy] = imx_clk_fixed("dummy", 0);
-
-	/* retrieve the freqency of fixed clocks from device tree */
-	for_each_compatible_node(np, NULL, "fixed-clock") {
-		u32 rate;
-		if (of_property_read_u32(np, "clock-frequency", &rate))
-			continue;
-
-		if (of_device_is_compatible(np, "fsl,imx-ckil"))
-			clk[ckil] = imx_clk_fixed("ckil", rate);
-		else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
-			clk[ckih] = imx_clk_fixed("ckih", rate);
-		else if (of_device_is_compatible(np, "fsl,imx-osc"))
-			clk[osc] = imx_clk_fixed("osc", rate);
-	}
+	clk[ckil] = imx_obtain_fixed_clock("ckil", 0);
+	clk[ckih] = imx_obtain_fixed_clock("ckih1", 0);
+	clk[osc] = imx_obtain_fixed_clock("osc", 0);
 
 	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
 	base = of_iomap(np, 0);
@@ -312,7 +302,6 @@ int __init mx6q_clocks_init(void)
 	clk[pll5_video]    = imx_clk_pllv3(IMX_PLLV3_AV,	"pll5_video",	"osc", base + 0xa0, 0x7f);
 	clk[pll6_enet]     = imx_clk_pllv3(IMX_PLLV3_ENET,	"pll6_enet",	"osc", base + 0xe0, 0x3);
 	clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
-	clk[pll8_mlb]      = imx_clk_pllv3(IMX_PLLV3_MLB,	"pll8_mlb",	"osc", base + 0xd0, 0x0);
 
 	/*
 	 * Bit 20 is the reserved and read-only bit, we do this only for:
@@ -360,7 +349,7 @@ int __init mx6q_clocks_init(void)
 	clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
 	clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
+	np = ccm_node;
 	base = of_iomap(np, 0);
 	WARN_ON(!base);
 	ccm_base = base;
@@ -404,7 +393,7 @@ int __init mx6q_clocks_init(void)
 	clk[usdhc4_sel]       = imx_clk_mux("usdhc4_sel",       base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
 	clk[enfc_sel]         = imx_clk_mux("enfc_sel",         base + 0x2c, 16, 2, enfc_sels,         ARRAY_SIZE(enfc_sels));
 	clk[emi_sel]          = imx_clk_mux("emi_sel",          base + 0x1c, 27, 2, emi_sels,          ARRAY_SIZE(emi_sels));
-	clk[emi_slow_sel]     = imx_clk_mux("emi_slow_sel",     base + 0x1c, 29, 2, emi_sels,          ARRAY_SIZE(emi_sels));
+	clk[emi_slow_sel]     = imx_clk_mux("emi_slow_sel",     base + 0x1c, 29, 2, emi_slow_sels,     ARRAY_SIZE(emi_slow_sels));
 	clk[vdo_axi_sel]      = imx_clk_mux("vdo_axi_sel",      base + 0x18, 11, 1, vdo_axi_sels,      ARRAY_SIZE(vdo_axi_sels));
 	clk[vpu_axi_sel]      = imx_clk_mux("vpu_axi_sel",      base + 0x18, 14, 2, vpu_axi_sels,      ARRAY_SIZE(vpu_axi_sels));
 	clk[cko1_sel]         = imx_clk_mux("cko1_sel",         base + 0x60, 0,  4, cko1_sels,         ARRAY_SIZE(cko1_sels));
@@ -481,7 +470,14 @@ int __init mx6q_clocks_init(void)
 	clk[esai]         = imx_clk_gate2("esai",          "esai_podf",         base + 0x6c, 16);
 	clk[gpt_ipg]      = imx_clk_gate2("gpt_ipg",       "ipg",               base + 0x6c, 20);
 	clk[gpt_ipg_per]  = imx_clk_gate2("gpt_ipg_per",   "ipg_per",           base + 0x6c, 22);
-	clk[gpu2d_core]   = imx_clk_gate2("gpu2d_core",    "gpu2d_core_podf",   base + 0x6c, 24);
+	if (cpu_is_imx6dl())
+		/*
+		 * The multiplexer and divider of imx6q clock gpu3d_shader get
+		 * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl.
+		 */
+		clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu3d_shader", base + 0x6c, 24);
+	else
+		clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
 	clk[gpu3d_core]   = imx_clk_gate2("gpu3d_core",    "gpu3d_core_podf",   base + 0x6c, 26);
 	clk[hdmi_iahb]    = imx_clk_gate2("hdmi_iahb",     "ahb",               base + 0x70, 0);
 	clk[hdmi_isfr]    = imx_clk_gate2("hdmi_isfr",     "pll3_pfd1_540m",    base + 0x70, 4);
@@ -499,7 +495,14 @@ int __init mx6q_clocks_init(void)
 	clk[ldb_di1]      = imx_clk_gate2("ldb_di1",       "ldb_di1_podf",      base + 0x74, 14);
 	clk[ipu2_di1]     = imx_clk_gate2("ipu2_di1",      "ipu2_di1_sel",      base + 0x74, 10);
 	clk[hsi_tx]       = imx_clk_gate2("hsi_tx",        "hsi_tx_podf",       base + 0x74, 16);
-	clk[mlb]          = imx_clk_gate2("mlb",           "axi",               base + 0x74, 18);
+	if (cpu_is_imx6dl())
+		/*
+		 * The multiplexer and divider of the imx6q clock gpu2d get
+		 * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl.
+		 */
+		clk[mlb] = imx_clk_gate2("mlb",            "gpu2d_core_podf",   base + 0x74, 18);
+	else
+		clk[mlb] = imx_clk_gate2("mlb",            "axi",               base + 0x74, 18);
 	clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi",  "mmdc_ch0_axi_podf", base + 0x74, 20);
 	clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi",  "mmdc_ch1_axi_podf", base + 0x74, 22);
 	clk[ocram]        = imx_clk_gate2("ocram",         "ahb",               base + 0x74, 28);
@@ -528,6 +531,7 @@ int __init mx6q_clocks_init(void)
 	clk[usdhc2]       = imx_clk_gate2("usdhc2",        "usdhc2_podf",       base + 0x80, 4);
 	clk[usdhc3]       = imx_clk_gate2("usdhc3",        "usdhc3_podf",       base + 0x80, 6);
 	clk[usdhc4]       = imx_clk_gate2("usdhc4",        "usdhc4_podf",       base + 0x80, 8);
+	clk[eim_slow]     = imx_clk_gate2("eim_slow",      "emi_slow_podf",     base + 0x80, 10);
 	clk[vdo_axi]      = imx_clk_gate2("vdo_axi",       "vdo_axi_sel",       base + 0x80, 12);
 	clk[vpu_axi]      = imx_clk_gate2("vpu_axi",       "vpu_axi_podf",      base + 0x80, 14);
 	clk[cko1]         = imx_clk_gate("cko1",           "cko1_podf",         base + 0x60, 7);
@@ -547,6 +551,8 @@ int __init mx6q_clocks_init(void)
 	clk_register_clkdev(clk[ahb], "ahb", NULL);
 	clk_register_clkdev(clk[cko1], "cko1", NULL);
 	clk_register_clkdev(clk[arm], NULL, "cpu0");
+	clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
+	clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
 
 	if (imx6q_revision() != IMX_CHIP_REVISION_1_0) {
 		clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
@@ -576,6 +582,5 @@ int __init mx6q_clocks_init(void)
 	WARN_ON(!base);
 	irq = irq_of_parse_and_map(np, 0);
 	mxc_timer_init(base, irq);
-
-	return 0;
 }
+CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/clk-imx6sl.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-imx6sl.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/clk-imx6sl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-imx6sl.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <dt-bindings/clock/imx6sl-clock.h>
+
+#include "clk.h"
+#include "common.h"
+
+static const char const *step_sels[]		= { "osc", "pll2_pfd2", };
+static const char const *pll1_sw_sels[]		= { "pll1_sys", "step", };
+static const char const *ocram_alt_sels[]	= { "pll2_pfd2", "pll3_pfd1", };
+static const char const *ocram_sels[]		= { "periph", "ocram_alt_sels", };
+static const char const *pre_periph_sels[]	= { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
+static const char const *periph_clk2_sels[]	= { "pll3_usb_otg", "osc", "osc", "dummy", };
+static const char const *periph2_clk2_sels[]	= { "pll3_usb_otg", "pll2_bus", };
+static const char const *periph_sels[]		= { "pre_periph_sel", "periph_clk2_podf", };
+static const char const *periph2_sels[]		= { "pre_periph2_sel", "periph2_clk2_podf", };
+static const char const *csi_lcdif_sels[]	= { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
+static const char const *usdhc_sels[]		= { "pll2_pfd2", "pll2_pfd0", };
+static const char const *ssi_sels[]		= { "pll3_pfd2", "pll3_pfd3", "pll4_post_div", "dummy", };
+static const char const *perclk_sels[]		= { "ipg", "osc", };
+static const char const *epdc_pxp_sels[]	= { "mmdc", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd1", };
+static const char const *gpu2d_ovg_sels[]	= { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", };
+static const char const *gpu2d_sels[]		= { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", };
+static const char const *lcdif_pix_sels[]	= { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", };
+static const char const *epdc_pix_sels[]	= { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
+static const char const *audio_sels[]		= { "pll4_post_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
+static const char const *ecspi_sels[]		= { "pll3_60m", "osc", };
+static const char const *uart_sels[]		= { "pll3_80m", "osc", };
+
+static struct clk_div_table clk_enet_ref_table[] = {
+	{ .val = 0, .div = 20, },
+	{ .val = 1, .div = 10, },
+	{ .val = 2, .div = 5, },
+	{ .val = 3, .div = 4, },
+	{ }
+};
+
+static struct clk_div_table post_div_table[] = {
+	{ .val = 2, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 0, .div = 4, },
+	{ }
+};
+
+static struct clk_div_table video_div_table[] = {
+	{ .val = 0, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 2, .div = 1, },
+	{ .val = 3, .div = 4, },
+	{ }
+};
+
+static struct clk *clks[IMX6SL_CLK_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static void __init imx6sl_clocks_init(struct device_node *ccm_node)
+{
+	struct device_node *np;
+	void __iomem *base;
+	int irq;
+	int i;
+
+	clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+	clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
+	clks[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+
+	/*                                             type               name            parent  base         div_mask */
+	clks[IMX6SL_CLK_PLL1_SYS]      = imx_clk_pllv3(IMX_PLLV3_SYS,	  "pll1_sys",	   "osc", base,        0x7f);
+	clks[IMX6SL_CLK_PLL2_BUS]      = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus",	   "osc", base + 0x30, 0x1);
+	clks[IMX6SL_CLK_PLL3_USB_OTG]  = imx_clk_pllv3(IMX_PLLV3_USB,	  "pll3_usb_otg",  "osc", base + 0x10, 0x3);
+	clks[IMX6SL_CLK_PLL4_AUDIO]    = imx_clk_pllv3(IMX_PLLV3_AV,	  "pll4_audio",	   "osc", base + 0x70, 0x7f);
+	clks[IMX6SL_CLK_PLL5_VIDEO]    = imx_clk_pllv3(IMX_PLLV3_AV,	  "pll5_video",	   "osc", base + 0xa0, 0x7f);
+	clks[IMX6SL_CLK_PLL6_ENET]     = imx_clk_pllv3(IMX_PLLV3_ENET,	  "pll6_enet",	   "osc", base + 0xe0, 0x3);
+	clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB,     "pll7_usb_host", "osc", base + 0x20, 0x3);
+
+	/*
+	 * usbphy1 and usbphy2 are implemented as dummy gates using reserve
+	 * bit 20.  They are used by phy driver to keep the refcount of
+	 * parent PLL correct. usbphy1_gate and usbphy2_gate only needs to be
+	 * turned on during boot, and software will not need to control it
+	 * anymore after that.
+	 */
+	clks[IMX6SL_CLK_USBPHY1]      = imx_clk_gate("usbphy1",      "pll3_usb_otg",  base + 0x10, 20);
+	clks[IMX6SL_CLK_USBPHY2]      = imx_clk_gate("usbphy2",      "pll7_usb_host", base + 0x20, 20);
+	clks[IMX6SL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy",         base + 0x10, 6);
+	clks[IMX6SL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy",         base + 0x20, 6);
+
+	/*                                                           dev   name              parent_name      flags                reg        shift width div: flags, div_table lock */
+	clks[IMX6SL_CLK_PLL4_POST_DIV]  = clk_register_divider_table(NULL, "pll4_post_div",  "pll4_audio",    CLK_SET_RATE_PARENT, base + 0x70,  19, 2,   0, post_div_table, &imx_ccm_lock);
+	clks[IMX6SL_CLK_PLL5_POST_DIV]  = clk_register_divider_table(NULL, "pll5_post_div",  "pll5_video",    CLK_SET_RATE_PARENT, base + 0xa0,  19, 2,   0, post_div_table, &imx_ccm_lock);
+	clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2,   0, video_div_table, &imx_ccm_lock);
+	clks[IMX6SL_CLK_ENET_REF]       = clk_register_divider_table(NULL, "enet_ref",       "pll6_enet",     0,                   base + 0xe0,  0,  2,   0, clk_enet_ref_table, &imx_ccm_lock);
+
+	/*                                       name         parent_name     reg           idx */
+	clks[IMX6SL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0", "pll2_bus",     base + 0x100, 0);
+	clks[IMX6SL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus",     base + 0x100, 1);
+	clks[IMX6SL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus",     base + 0x100, 2);
+	clks[IMX6SL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0", "pll3_usb_otg", base + 0xf0,  0);
+	clks[IMX6SL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", base + 0xf0,  1);
+	clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0,  2);
+	clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0,  3);
+
+	/*                                                name         parent_name     mult div */
+	clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2",      1, 2);
+	clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg",   1, 4);
+	clks[IMX6SL_CLK_PLL3_80M]  = imx_clk_fixed_factor("pll3_80m",  "pll3_usb_otg",   1, 6);
+	clks[IMX6SL_CLK_PLL3_60M]  = imx_clk_fixed_factor("pll3_60m",  "pll3_usb_otg",   1, 8);
+
+	np = ccm_node;
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+
+	/*                                              name                reg       shift width parent_names     num_parents */
+	clks[IMX6SL_CLK_STEP]             = imx_clk_mux("step",             base + 0xc,  8,  1, step_sels,         ARRAY_SIZE(step_sels));
+	clks[IMX6SL_CLK_PLL1_SW]          = imx_clk_mux("pll1_sw",          base + 0xc,  2,  1, pll1_sw_sels,      ARRAY_SIZE(pll1_sw_sels));
+	clks[IMX6SL_CLK_OCRAM_ALT_SEL]    = imx_clk_mux("ocram_alt_sel",    base + 0x14, 7,  1, ocram_alt_sels,    ARRAY_SIZE(ocram_alt_sels));
+	clks[IMX6SL_CLK_OCRAM_SEL]        = imx_clk_mux("ocram_sel",        base + 0x14, 6,  1, ocram_sels,        ARRAY_SIZE(ocram_sels));
+	clks[IMX6SL_CLK_PRE_PERIPH2_SEL]  = imx_clk_mux("pre_periph2_sel",  base + 0x18, 21, 2, pre_periph_sels,   ARRAY_SIZE(pre_periph_sels));
+	clks[IMX6SL_CLK_PRE_PERIPH_SEL]   = imx_clk_mux("pre_periph_sel",   base + 0x18, 18, 2, pre_periph_sels,   ARRAY_SIZE(pre_periph_sels));
+	clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
+	clks[IMX6SL_CLK_PERIPH_CLK2_SEL]  = imx_clk_mux("periph_clk2_sel",  base + 0x18, 12, 2, periph_clk2_sels,  ARRAY_SIZE(periph_clk2_sels));
+	clks[IMX6SL_CLK_CSI_SEL]          = imx_clk_mux("csi_sel",          base + 0x3c, 9,  2, csi_lcdif_sels,    ARRAY_SIZE(csi_lcdif_sels));
+	clks[IMX6SL_CLK_LCDIF_AXI_SEL]    = imx_clk_mux("lcdif_axi_sel",    base + 0x3c, 14, 2, csi_lcdif_sels,    ARRAY_SIZE(csi_lcdif_sels));
+	clks[IMX6SL_CLK_USDHC1_SEL]       = imx_clk_mux("usdhc1_sel",       base + 0x1c, 16, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SL_CLK_USDHC2_SEL]       = imx_clk_mux("usdhc2_sel",       base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SL_CLK_USDHC3_SEL]       = imx_clk_mux("usdhc3_sel",       base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SL_CLK_USDHC4_SEL]       = imx_clk_mux("usdhc4_sel",       base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
+	clks[IMX6SL_CLK_SSI1_SEL]         = imx_clk_mux("ssi1_sel",         base + 0x1c, 10, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
+	clks[IMX6SL_CLK_SSI2_SEL]         = imx_clk_mux("ssi2_sel",         base + 0x1c, 12, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
+	clks[IMX6SL_CLK_SSI3_SEL]         = imx_clk_mux("ssi3_sel",         base + 0x1c, 14, 2, ssi_sels,          ARRAY_SIZE(ssi_sels));
+	clks[IMX6SL_CLK_PERCLK_SEL]       = imx_clk_mux("perclk_sel",       base + 0x1c, 6,  1, perclk_sels,       ARRAY_SIZE(perclk_sels));
+	clks[IMX6SL_CLK_PXP_AXI_SEL]      = imx_clk_mux("pxp_axi_sel",      base + 0x34, 6,  3, epdc_pxp_sels,     ARRAY_SIZE(epdc_pxp_sels));
+	clks[IMX6SL_CLK_EPDC_AXI_SEL]     = imx_clk_mux("epdc_axi_sel",     base + 0x34, 15, 3, epdc_pxp_sels,     ARRAY_SIZE(epdc_pxp_sels));
+	clks[IMX6SL_CLK_GPU2D_OVG_SEL]    = imx_clk_mux("gpu2d_ovg_sel",    base + 0x18, 4,  2, gpu2d_ovg_sels,    ARRAY_SIZE(gpu2d_ovg_sels));
+	clks[IMX6SL_CLK_GPU2D_SEL]        = imx_clk_mux("gpu2d_sel",        base + 0x18, 8,  2, gpu2d_sels,        ARRAY_SIZE(gpu2d_sels));
+	clks[IMX6SL_CLK_LCDIF_PIX_SEL]    = imx_clk_mux("lcdif_pix_sel",    base + 0x38, 6,  3, lcdif_pix_sels,    ARRAY_SIZE(lcdif_pix_sels));
+	clks[IMX6SL_CLK_EPDC_PIX_SEL]     = imx_clk_mux("epdc_pix_sel",     base + 0x38, 15, 3, epdc_pix_sels,     ARRAY_SIZE(epdc_pix_sels));
+	clks[IMX6SL_CLK_SPDIF0_SEL]       = imx_clk_mux("spdif0_sel",       base + 0x30, 20, 2, audio_sels,        ARRAY_SIZE(audio_sels));
+	clks[IMX6SL_CLK_SPDIF1_SEL]       = imx_clk_mux("spdif1_sel",       base + 0x30, 7,  2, audio_sels,        ARRAY_SIZE(audio_sels));
+	clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels,        ARRAY_SIZE(audio_sels));
+	clks[IMX6SL_CLK_ECSPI_SEL]        = imx_clk_mux("ecspi_sel",        base + 0x38, 18, 1, ecspi_sels,        ARRAY_SIZE(ecspi_sels));
+	clks[IMX6SL_CLK_UART_SEL]         = imx_clk_mux("uart_sel",         base + 0x24, 6,  1, uart_sels,         ARRAY_SIZE(uart_sels));
+
+	/*                                          name       reg        shift width busy: reg, shift parent_names  num_parents */
+	clks[IMX6SL_CLK_PERIPH]  = imx_clk_busy_mux("periph",  base + 0x14, 25,  1,   base + 0x48, 5,  periph_sels,  ARRAY_SIZE(periph_sels));
+	clks[IMX6SL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26,  1,   base + 0x48, 3,  periph2_sels, ARRAY_SIZE(periph2_sels));
+
+	/*                                                   name                 parent_name          reg       shift width */
+	clks[IMX6SL_CLK_OCRAM_PODF]        = imx_clk_divider("ocram_podf",        "ocram_sel",         base + 0x14, 16, 3);
+	clks[IMX6SL_CLK_PERIPH_CLK2_PODF]  = imx_clk_divider("periph_clk2_podf",  "periph_clk2_sel",   base + 0x14, 27, 3);
+	clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel",  base + 0x14, 0,  3);
+	clks[IMX6SL_CLK_IPG]               = imx_clk_divider("ipg",               "ahb",               base + 0x14, 8,  2);
+	clks[IMX6SL_CLK_CSI_PODF]          = imx_clk_divider("csi_podf",          "csi_sel",           base + 0x3c, 11, 3);
+	clks[IMX6SL_CLK_LCDIF_AXI_PODF]    = imx_clk_divider("lcdif_axi_podf",    "lcdif_axi_sel",     base + 0x3c, 16, 3);
+	clks[IMX6SL_CLK_USDHC1_PODF]       = imx_clk_divider("usdhc1_podf",       "usdhc1_sel",        base + 0x24, 11, 3);
+	clks[IMX6SL_CLK_USDHC2_PODF]       = imx_clk_divider("usdhc2_podf",       "usdhc2_sel",        base + 0x24, 16, 3);
+	clks[IMX6SL_CLK_USDHC3_PODF]       = imx_clk_divider("usdhc3_podf",       "usdhc3_sel",        base + 0x24, 19, 3);
+	clks[IMX6SL_CLK_USDHC4_PODF]       = imx_clk_divider("usdhc4_podf",       "usdhc4_sel",        base + 0x24, 22, 3);
+	clks[IMX6SL_CLK_SSI1_PRED]         = imx_clk_divider("ssi1_pred",         "ssi1_sel",          base + 0x28, 6,  3);
+	clks[IMX6SL_CLK_SSI1_PODF]         = imx_clk_divider("ssi1_podf",         "ssi1_pred",         base + 0x28, 0,  6);
+	clks[IMX6SL_CLK_SSI2_PRED]         = imx_clk_divider("ssi2_pred",         "ssi2_sel",          base + 0x2c, 6,  3);
+	clks[IMX6SL_CLK_SSI2_PODF]         = imx_clk_divider("ssi2_podf",         "ssi2_pred",         base + 0x2c, 0,  6);
+	clks[IMX6SL_CLK_SSI3_PRED]         = imx_clk_divider("ssi3_pred",         "ssi3_sel",          base + 0x28, 22, 3);
+	clks[IMX6SL_CLK_SSI3_PODF]         = imx_clk_divider("ssi3_podf",         "ssi3_pred",         base + 0x28, 16, 6);
+	clks[IMX6SL_CLK_PERCLK]            = imx_clk_divider("perclk",            "perclk_sel",        base + 0x1c, 0,  6);
+	clks[IMX6SL_CLK_PXP_AXI_PODF]      = imx_clk_divider("pxp_axi_podf",      "pxp_axi_sel",       base + 0x34, 3,  3);
+	clks[IMX6SL_CLK_EPDC_AXI_PODF]     = imx_clk_divider("epdc_axi_podf",     "epdc_axi_sel",      base + 0x34, 12, 3);
+	clks[IMX6SL_CLK_GPU2D_OVG_PODF]    = imx_clk_divider("gpu2d_ovg_podf",    "gpu2d_ovg_sel",     base + 0x18, 26, 3);
+	clks[IMX6SL_CLK_GPU2D_PODF]        = imx_clk_divider("gpu2d_podf",        "gpu2d_sel",         base + 0x18, 29, 3);
+	clks[IMX6SL_CLK_LCDIF_PIX_PRED]    = imx_clk_divider("lcdif_pix_pred",    "lcdif_pix_sel",     base + 0x38, 3,  3);
+	clks[IMX6SL_CLK_EPDC_PIX_PRED]     = imx_clk_divider("epdc_pix_pred",     "epdc_pix_sel",      base + 0x38, 12, 3);
+	clks[IMX6SL_CLK_LCDIF_PIX_PODF]    = imx_clk_divider("lcdif_pix_podf",    "lcdif_pix_pred",    base + 0x1c, 20, 3);
+	clks[IMX6SL_CLK_EPDC_PIX_PODF]     = imx_clk_divider("epdc_pix_podf",     "epdc_pix_pred",     base + 0x18, 23, 3);
+	clks[IMX6SL_CLK_SPDIF0_PRED]       = imx_clk_divider("spdif0_pred",       "spdif0_sel",        base + 0x30, 25, 3);
+	clks[IMX6SL_CLK_SPDIF0_PODF]       = imx_clk_divider("spdif0_podf",       "spdif0_pred",       base + 0x30, 22, 3);
+	clks[IMX6SL_CLK_SPDIF1_PRED]       = imx_clk_divider("spdif1_pred",       "spdif1_sel",        base + 0x30, 12, 3);
+	clks[IMX6SL_CLK_SPDIF1_PODF]       = imx_clk_divider("spdif1_podf",       "spdif1_pred",       base + 0x30, 9,  3);
+	clks[IMX6SL_CLK_EXTERN_AUDIO_PRED] = imx_clk_divider("extern_audio_pred", "extern_audio_sel",  base + 0x28, 9,  3);
+	clks[IMX6SL_CLK_EXTERN_AUDIO_PODF] = imx_clk_divider("extern_audio_podf", "extern_audio_pred", base + 0x28, 25, 3);
+	clks[IMX6SL_CLK_ECSPI_ROOT]        = imx_clk_divider("ecspi_root",        "ecspi_sel",         base + 0x38, 19, 6);
+	clks[IMX6SL_CLK_UART_ROOT]         = imx_clk_divider("uart_root",         "uart_sel",          base + 0x24, 0,  6);
+
+	/*                                                name         parent_name reg       shift width busy: reg, shift */
+	clks[IMX6SL_CLK_AHB]       = imx_clk_busy_divider("ahb",       "periph",  base + 0x14, 10, 3,    base + 0x48, 1);
+	clks[IMX6SL_CLK_MMDC_ROOT] = imx_clk_busy_divider("mmdc",      "periph2", base + 0x14, 3,  3,    base + 0x48, 2);
+	clks[IMX6SL_CLK_ARM]       = imx_clk_busy_divider("arm",       "pll1_sw", base + 0x10, 0,  3,    base + 0x48, 16);
+
+	/*                                            name            parent_name          reg         shift */
+	clks[IMX6SL_CLK_ECSPI1]       = imx_clk_gate2("ecspi1",       "ecspi_root",        base + 0x6c, 0);
+	clks[IMX6SL_CLK_ECSPI2]       = imx_clk_gate2("ecspi2",       "ecspi_root",        base + 0x6c, 2);
+	clks[IMX6SL_CLK_ECSPI3]       = imx_clk_gate2("ecspi3",       "ecspi_root",        base + 0x6c, 4);
+	clks[IMX6SL_CLK_ECSPI4]       = imx_clk_gate2("ecspi4",       "ecspi_root",        base + 0x6c, 6);
+	clks[IMX6SL_CLK_EPIT1]        = imx_clk_gate2("epit1",        "perclk",            base + 0x6c, 12);
+	clks[IMX6SL_CLK_EPIT2]        = imx_clk_gate2("epit2",        "perclk",            base + 0x6c, 14);
+	clks[IMX6SL_CLK_EXTERN_AUDIO] = imx_clk_gate2("extern_audio", "extern_audio_podf", base + 0x6c, 16);
+	clks[IMX6SL_CLK_GPT]          = imx_clk_gate2("gpt",          "perclk",            base + 0x6c, 20);
+	clks[IMX6SL_CLK_GPT_SERIAL]   = imx_clk_gate2("gpt_serial",   "perclk",            base + 0x6c, 22);
+	clks[IMX6SL_CLK_GPU2D_OVG]    = imx_clk_gate2("gpu2d_ovg",    "gpu2d_ovg_podf",    base + 0x6c, 26);
+	clks[IMX6SL_CLK_I2C1]         = imx_clk_gate2("i2c1",         "perclk",            base + 0x70, 6);
+	clks[IMX6SL_CLK_I2C2]         = imx_clk_gate2("i2c2",         "perclk",            base + 0x70, 8);
+	clks[IMX6SL_CLK_I2C3]         = imx_clk_gate2("i2c3",         "perclk",            base + 0x70, 10);
+	clks[IMX6SL_CLK_OCOTP]        = imx_clk_gate2("ocotp",        "ipg",               base + 0x70, 12);
+	clks[IMX6SL_CLK_CSI]          = imx_clk_gate2("csi",          "csi_podf",          base + 0x74, 0);
+	clks[IMX6SL_CLK_PXP_AXI]      = imx_clk_gate2("pxp_axi",      "pxp_axi_podf",      base + 0x74, 2);
+	clks[IMX6SL_CLK_EPDC_AXI]     = imx_clk_gate2("epdc_axi",     "epdc_axi_podf",     base + 0x74, 4);
+	clks[IMX6SL_CLK_LCDIF_AXI]    = imx_clk_gate2("lcdif_axi",    "lcdif_axi_podf",    base + 0x74, 6);
+	clks[IMX6SL_CLK_LCDIF_PIX]    = imx_clk_gate2("lcdif_pix",    "lcdif_pix_podf",    base + 0x74, 8);
+	clks[IMX6SL_CLK_EPDC_PIX]     = imx_clk_gate2("epdc_pix",     "epdc_pix_podf",     base + 0x74, 10);
+	clks[IMX6SL_CLK_OCRAM]        = imx_clk_gate2("ocram",        "ocram_podf",        base + 0x74, 28);
+	clks[IMX6SL_CLK_PWM1]         = imx_clk_gate2("pwm1",         "perclk",            base + 0x78, 16);
+	clks[IMX6SL_CLK_PWM2]         = imx_clk_gate2("pwm2",         "perclk",            base + 0x78, 18);
+	clks[IMX6SL_CLK_PWM3]         = imx_clk_gate2("pwm3",         "perclk",            base + 0x78, 20);
+	clks[IMX6SL_CLK_PWM4]         = imx_clk_gate2("pwm4",         "perclk",            base + 0x78, 22);
+	clks[IMX6SL_CLK_SDMA]         = imx_clk_gate2("sdma",         "ipg",               base + 0x7c, 6);
+	clks[IMX6SL_CLK_SPDIF]        = imx_clk_gate2("spdif",        "spdif0_podf",       base + 0x7c, 14);
+	clks[IMX6SL_CLK_SSI1]         = imx_clk_gate2("ssi1",         "ssi1_podf",         base + 0x7c, 18);
+	clks[IMX6SL_CLK_SSI2]         = imx_clk_gate2("ssi2",         "ssi2_podf",         base + 0x7c, 20);
+	clks[IMX6SL_CLK_SSI3]         = imx_clk_gate2("ssi3",         "ssi3_podf",         base + 0x7c, 22);
+	clks[IMX6SL_CLK_UART]         = imx_clk_gate2("uart",         "ipg",               base + 0x7c, 24);
+	clks[IMX6SL_CLK_UART_SERIAL]  = imx_clk_gate2("uart_serial",  "uart_root",         base + 0x7c, 26);
+	clks[IMX6SL_CLK_USBOH3]       = imx_clk_gate2("usboh3",       "ipg",               base + 0x80, 0);
+	clks[IMX6SL_CLK_USDHC1]       = imx_clk_gate2("usdhc1",       "usdhc1_podf",       base + 0x80, 2);
+	clks[IMX6SL_CLK_USDHC2]       = imx_clk_gate2("usdhc2",       "usdhc2_podf",       base + 0x80, 4);
+	clks[IMX6SL_CLK_USDHC3]       = imx_clk_gate2("usdhc3",       "usdhc3_podf",       base + 0x80, 6);
+	clks[IMX6SL_CLK_USDHC4]       = imx_clk_gate2("usdhc4",       "usdhc4_podf",       base + 0x80, 8);
+
+	for (i = 0; i < ARRAY_SIZE(clks); i++)
+		if (IS_ERR(clks[i]))
+			pr_err("i.MX6SL clk %d: register failed with %ld\n",
+				i, PTR_ERR(clks[i]));
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+	clk_register_clkdev(clks[IMX6SL_CLK_GPT], "ipg", "imx-gpt.0");
+	clk_register_clkdev(clks[IMX6SL_CLK_GPT_SERIAL], "per", "imx-gpt.0");
+
+	if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
+		clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
+		clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
+	}
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpt");
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+	irq = irq_of_parse_and_map(np, 0);
+	mxc_timer_init(base, irq);
+}
+CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/clk-pllv3.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-pllv3.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/clk-pllv3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-pllv3.c	2013-08-25 20:43:22.000000000 -0400
@@ -296,13 +296,6 @@ static const struct clk_ops clk_pllv3_en
 	.recalc_rate	= clk_pllv3_enet_recalc_rate,
 };
 
-static const struct clk_ops clk_pllv3_mlb_ops = {
-	.prepare	= clk_pllv3_prepare,
-	.unprepare	= clk_pllv3_unprepare,
-	.enable		= clk_pllv3_enable,
-	.disable	= clk_pllv3_disable,
-};
-
 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
 			  const char *parent_name, void __iomem *base,
 			  u32 div_mask)
@@ -330,9 +323,6 @@ struct clk *imx_clk_pllv3(enum imx_pllv3
 	case IMX_PLLV3_ENET:
 		ops = &clk_pllv3_enet_ops;
 		break;
-	case IMX_PLLV3_MLB:
-		ops = &clk_pllv3_mlb_ops;
-		break;
 	default:
 		ops = &clk_pllv3_ops;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/clk-vf610.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-vf610.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/clk-vf610.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/clk-vf610.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2012-2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <dt-bindings/clock/vf610-clock.h>
+
+#include "clk.h"
+
+#define CCM_CCR			(ccm_base + 0x00)
+#define CCM_CSR			(ccm_base + 0x04)
+#define CCM_CCSR		(ccm_base + 0x08)
+#define CCM_CACRR		(ccm_base + 0x0c)
+#define CCM_CSCMR1		(ccm_base + 0x10)
+#define CCM_CSCDR1		(ccm_base + 0x14)
+#define CCM_CSCDR2		(ccm_base + 0x18)
+#define CCM_CSCDR3		(ccm_base + 0x1c)
+#define CCM_CSCMR2		(ccm_base + 0x20)
+#define CCM_CSCDR4		(ccm_base + 0x24)
+#define CCM_CLPCR		(ccm_base + 0x2c)
+#define CCM_CISR		(ccm_base + 0x30)
+#define CCM_CIMR		(ccm_base + 0x34)
+#define CCM_CGPR		(ccm_base + 0x3c)
+#define CCM_CCGR0		(ccm_base + 0x40)
+#define CCM_CCGR1		(ccm_base + 0x44)
+#define CCM_CCGR2		(ccm_base + 0x48)
+#define CCM_CCGR3		(ccm_base + 0x4c)
+#define CCM_CCGR4		(ccm_base + 0x50)
+#define CCM_CCGR5		(ccm_base + 0x54)
+#define CCM_CCGR6		(ccm_base + 0x58)
+#define CCM_CCGR7		(ccm_base + 0x5c)
+#define CCM_CCGR8		(ccm_base + 0x60)
+#define CCM_CCGR9		(ccm_base + 0x64)
+#define CCM_CCGR10		(ccm_base + 0x68)
+#define CCM_CCGR11		(ccm_base + 0x6c)
+#define CCM_CMEOR0		(ccm_base + 0x70)
+#define CCM_CMEOR1		(ccm_base + 0x74)
+#define CCM_CMEOR2		(ccm_base + 0x78)
+#define CCM_CMEOR3		(ccm_base + 0x7c)
+#define CCM_CMEOR4		(ccm_base + 0x80)
+#define CCM_CMEOR5		(ccm_base + 0x84)
+#define CCM_CPPDSR		(ccm_base + 0x88)
+#define CCM_CCOWR		(ccm_base + 0x8c)
+#define CCM_CCPGR0		(ccm_base + 0x90)
+#define CCM_CCPGR1		(ccm_base + 0x94)
+#define CCM_CCPGR2		(ccm_base + 0x98)
+#define CCM_CCPGR3		(ccm_base + 0x9c)
+
+#define CCM_CCGRx_CGn(n)	((n) * 2)
+
+#define PFD_PLL1_BASE		(anatop_base + 0x2b0)
+#define PFD_PLL2_BASE		(anatop_base + 0x100)
+#define PFD_PLL3_BASE		(anatop_base + 0xf0)
+
+static void __iomem *anatop_base;
+static void __iomem *ccm_base;
+
+/* sources for multiplexer clocks, this is used multiple times */
+static const char const *fast_sels[]	= { "firc", "fxosc", };
+static const char const *slow_sels[]	= { "sirc_32k", "sxosc", };
+static const char const *pll1_sels[]	= { "pll1_main", "pll1_pfd1", "pll1_pfd2", "pll1_pfd3", "pll1_pfd4", };
+static const char const *pll2_sels[]	= { "pll2_main", "pll2_pfd1", "pll2_pfd2", "pll2_pfd3", "pll2_pfd4", };
+static const char const *sys_sels[]	= { "fast_clk_sel", "slow_clk_sel", "pll2_pfd_sel", "pll2_main", "pll1_pfd_sel", "pll3_main", };
+static const char const *ddr_sels[]	= { "pll2_pfd2", "sys_sel", };
+static const char const *rmii_sels[]	= { "enet_ext", "audio_ext", "enet_50m", "enet_25m", };
+static const char const *enet_ts_sels[]	= { "enet_ext", "fxosc", "audio_ext", "usb", "enet_ts", "enet_25m", "enet_50m", };
+static const char const *esai_sels[]	= { "audio_ext", "mlb", "spdif_rx", "pll4_main_div", };
+static const char const *sai_sels[]	= { "audio_ext", "mlb", "spdif_rx", "pll4_main_div", };
+static const char const *nfc_sels[]	= { "platform_bus", "pll1_pfd1", "pll3_pfd1", "pll3_pfd3", };
+static const char const *qspi_sels[]	= { "pll3_main", "pll3_pfd4", "pll2_pfd4", "pll1_pfd4", };
+static const char const *esdhc_sels[]	= { "pll3_main", "pll3_pfd3", "pll1_pfd3", "platform_bus", };
+static const char const *dcu_sels[]	= { "pll1_pfd2", "pll3_main", };
+static const char const *gpu_sels[]	= { "pll2_pfd2", "pll3_pfd2", };
+static const char const *vadc_sels[]	= { "pll6_main_div", "pll3_main_div", "pll3_main", };
+/* FTM counter clock source, not module clock */
+static const char const *ftm_ext_sels[]	= {"sirc_128k", "sxosc", "fxosc_half", "audio_ext", };
+static const char const *ftm_fix_sels[]	= { "sxosc", "ipg_bus", };
+
+static struct clk_div_table pll4_main_div_table[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 6 },
+	{ .val = 3, .div = 8 },
+	{ .val = 4, .div = 10 },
+	{ .val = 5, .div = 12 },
+	{ .val = 6, .div = 14 },
+	{ .val = 7, .div = 16 },
+	{ }
+};
+
+static struct clk *clk[VF610_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static void __init vf610_clocks_init(struct device_node *ccm_node)
+{
+	struct device_node *np;
+
+	clk[VF610_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+	clk[VF610_CLK_SIRC_128K] = imx_clk_fixed("sirc_128k", 128000);
+	clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000);
+	clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000);
+
+	clk[VF610_CLK_SXOSC] = imx_obtain_fixed_clock("sxosc", 0);
+	clk[VF610_CLK_FXOSC] = imx_obtain_fixed_clock("fxosc", 0);
+	clk[VF610_CLK_AUDIO_EXT] = imx_obtain_fixed_clock("audio_ext", 0);
+	clk[VF610_CLK_ENET_EXT] = imx_obtain_fixed_clock("enet_ext", 0);
+
+	clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2);
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,vf610-anatop");
+	anatop_base = of_iomap(np, 0);
+	BUG_ON(!anatop_base);
+
+	np = ccm_node;
+	ccm_base = of_iomap(np, 0);
+	BUG_ON(!ccm_base);
+
+	clk[VF610_CLK_SLOW_CLK_SEL] = imx_clk_mux("slow_clk_sel", CCM_CCSR, 4, 1, slow_sels, ARRAY_SIZE(slow_sels));
+	clk[VF610_CLK_FASK_CLK_SEL] = imx_clk_mux("fast_clk_sel", CCM_CCSR, 5, 1, fast_sels, ARRAY_SIZE(fast_sels));
+
+	clk[VF610_CLK_PLL1_MAIN] = imx_clk_fixed_factor("pll1_main", "fast_clk_sel", 22, 1);
+	clk[VF610_CLK_PLL1_PFD1] = imx_clk_pfd("pll1_pfd1", "pll1_main", PFD_PLL1_BASE, 0);
+	clk[VF610_CLK_PLL1_PFD2] = imx_clk_pfd("pll1_pfd2", "pll1_main", PFD_PLL1_BASE, 1);
+	clk[VF610_CLK_PLL1_PFD3] = imx_clk_pfd("pll1_pfd3", "pll1_main", PFD_PLL1_BASE, 2);
+	clk[VF610_CLK_PLL1_PFD4] = imx_clk_pfd("pll1_pfd4", "pll1_main", PFD_PLL1_BASE, 3);
+
+	clk[VF610_CLK_PLL2_MAIN] = imx_clk_fixed_factor("pll2_main", "fast_clk_sel", 22, 1);
+	clk[VF610_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_main", PFD_PLL2_BASE, 0);
+	clk[VF610_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_main", PFD_PLL2_BASE, 1);
+	clk[VF610_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3", "pll2_main", PFD_PLL2_BASE, 2);
+	clk[VF610_CLK_PLL2_PFD4] = imx_clk_pfd("pll2_pfd4", "pll2_main", PFD_PLL2_BASE, 3);
+
+	clk[VF610_CLK_PLL3_MAIN] = imx_clk_fixed_factor("pll3_main", "fast_clk_sel", 20, 1);
+	clk[VF610_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_main", PFD_PLL3_BASE, 0);
+	clk[VF610_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_main", PFD_PLL3_BASE, 1);
+	clk[VF610_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_main", PFD_PLL3_BASE, 2);
+	clk[VF610_CLK_PLL3_PFD4] = imx_clk_pfd("pll3_pfd4", "pll3_main", PFD_PLL3_BASE, 3);
+
+	clk[VF610_CLK_PLL4_MAIN] = imx_clk_fixed_factor("pll4_main", "fast_clk_sel", 25, 1);
+	/* Enet pll: fixed 50Mhz */
+	clk[VF610_CLK_PLL5_MAIN] = imx_clk_fixed_factor("pll5_main", "fast_clk_sel", 125, 6);
+	/* pll6: default 960Mhz */
+	clk[VF610_CLK_PLL6_MAIN] = imx_clk_fixed_factor("pll6_main", "fast_clk_sel", 40, 1);
+	clk[VF610_CLK_PLL1_PFD_SEL] = imx_clk_mux("pll1_pfd_sel", CCM_CCSR, 16, 3, pll1_sels, 5);
+	clk[VF610_CLK_PLL2_PFD_SEL] = imx_clk_mux("pll2_pfd_sel", CCM_CCSR, 19, 3, pll2_sels, 5);
+	clk[VF610_CLK_SYS_SEL] = imx_clk_mux("sys_sel", CCM_CCSR, 0, 3, sys_sels, ARRAY_SIZE(sys_sels));
+	clk[VF610_CLK_DDR_SEL] = imx_clk_mux("ddr_sel", CCM_CCSR, 6, 1, ddr_sels, ARRAY_SIZE(ddr_sels));
+	clk[VF610_CLK_SYS_BUS] = imx_clk_divider("sys_bus", "sys_sel", CCM_CACRR, 0, 3);
+	clk[VF610_CLK_PLATFORM_BUS] = imx_clk_divider("platform_bus", "sys_bus", CCM_CACRR, 3, 3);
+	clk[VF610_CLK_IPG_BUS] = imx_clk_divider("ipg_bus", "platform_bus", CCM_CACRR, 11, 2);
+
+	clk[VF610_CLK_PLL3_MAIN_DIV] = imx_clk_divider("pll3_main_div", "pll3_main", CCM_CACRR, 20, 1);
+	clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_main_div", "pll4_main", 0, CCM_CACRR, 6, 3, 0, pll4_main_div_table, &imx_ccm_lock);
+	clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_main_div", "pll6_main", CCM_CACRR, 21, 1);
+
+	clk[VF610_CLK_USBC0] = imx_clk_gate2("usbc0", "pll3_main", CCM_CCGR1, CCM_CCGRx_CGn(4));
+	clk[VF610_CLK_USBC1] = imx_clk_gate2("usbc1", "pll3_main", CCM_CCGR7, CCM_CCGRx_CGn(4));
+
+	clk[VF610_CLK_QSPI0_SEL] = imx_clk_mux("qspi0_sel", CCM_CSCMR1, 22, 2, qspi_sels, 4);
+	clk[VF610_CLK_QSPI0_EN] = imx_clk_gate("qspi0_en", "qspi0_sel", CCM_CSCDR3, 4);
+	clk[VF610_CLK_QSPI0_X4_DIV] = imx_clk_divider("qspi0_x4", "qspi0_en", CCM_CSCDR3, 0, 2);
+	clk[VF610_CLK_QSPI0_X2_DIV] = imx_clk_divider("qspi0_x2", "qspi0_x4", CCM_CSCDR3, 2, 1);
+	clk[VF610_CLK_QSPI0_X1_DIV] = imx_clk_divider("qspi0_x1", "qspi0_x2", CCM_CSCDR3, 3, 1);
+	clk[VF610_CLK_QSPI0] = imx_clk_gate2("qspi0", "qspi0_x1", CCM_CCGR2, CCM_CCGRx_CGn(4));
+
+	clk[VF610_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", CCM_CSCMR1, 24, 2, qspi_sels, 4);
+	clk[VF610_CLK_QSPI1_EN] = imx_clk_gate("qspi1_en", "qspi1_sel", CCM_CSCDR3, 12);
+	clk[VF610_CLK_QSPI1_X4_DIV] = imx_clk_divider("qspi1_x4", "qspi1_en", CCM_CSCDR3, 8, 2);
+	clk[VF610_CLK_QSPI1_X2_DIV] = imx_clk_divider("qspi1_x2", "qspi1_x4", CCM_CSCDR3, 10, 1);
+	clk[VF610_CLK_QSPI1_X1_DIV] = imx_clk_divider("qspi1_x1", "qspi1_x2", CCM_CSCDR3, 11, 1);
+	clk[VF610_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_x1", CCM_CCGR8, CCM_CCGRx_CGn(4));
+
+	clk[VF610_CLK_ENET_50M] = imx_clk_fixed_factor("enet_50m", "pll5_main", 1, 10);
+	clk[VF610_CLK_ENET_25M] = imx_clk_fixed_factor("enet_25m", "pll5_main", 1, 20);
+	clk[VF610_CLK_ENET_SEL] = imx_clk_mux("enet_sel", CCM_CSCMR2, 4, 2, rmii_sels, 4);
+	clk[VF610_CLK_ENET_TS_SEL] = imx_clk_mux("enet_ts_sel", CCM_CSCMR2, 0, 3, enet_ts_sels, 7);
+	clk[VF610_CLK_ENET] = imx_clk_gate("enet", "enet_sel", CCM_CSCDR1, 24);
+	clk[VF610_CLK_ENET_TS] = imx_clk_gate("enet_ts", "enet_ts_sel", CCM_CSCDR1, 23);
+	clk[VF610_CLK_ENET0] = imx_clk_gate2("enet0", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(0));
+	clk[VF610_CLK_ENET1] = imx_clk_gate2("enet1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(1));
+
+	clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7));
+
+	clk[VF610_CLK_UART0] = imx_clk_gate2("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7));
+	clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8));
+	clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9));
+	clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10));
+
+	clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6));
+	clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7));
+
+	clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12));
+	clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13));
+	clk[VF610_CLK_DSPI2] = imx_clk_gate2("dspi2", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(12));
+	clk[VF610_CLK_DSPI3] = imx_clk_gate2("dspi3", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(13));
+
+	clk[VF610_CLK_WDT] = imx_clk_gate2("wdt", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(14));
+
+	clk[VF610_CLK_ESDHC0_SEL] = imx_clk_mux("esdhc0_sel", CCM_CSCMR1, 16, 2, esdhc_sels, 4);
+	clk[VF610_CLK_ESDHC0_EN] = imx_clk_gate("esdhc0_en", "esdhc0_sel", CCM_CSCDR2, 28);
+	clk[VF610_CLK_ESDHC0_DIV] = imx_clk_divider("esdhc0_div", "esdhc0_en", CCM_CSCDR2, 16, 4);
+	clk[VF610_CLK_ESDHC0] = imx_clk_gate2("eshc0", "esdhc0_div", CCM_CCGR7, CCM_CCGRx_CGn(1));
+
+	clk[VF610_CLK_ESDHC1_SEL] = imx_clk_mux("esdhc1_sel", CCM_CSCMR1, 18, 2, esdhc_sels, 4);
+	clk[VF610_CLK_ESDHC1_EN] = imx_clk_gate("esdhc1_en", "esdhc1_sel", CCM_CSCDR2, 29);
+	clk[VF610_CLK_ESDHC1_DIV] = imx_clk_divider("esdhc1_div", "esdhc1_en", CCM_CSCDR2, 20, 4);
+	clk[VF610_CLK_ESDHC1] = imx_clk_gate2("eshc1", "esdhc1_div", CCM_CCGR7, CCM_CCGRx_CGn(2));
+
+	/*
+	 * ftm_ext_clk and ftm_fix_clk are FTM timer counter's
+	 * selectable clock sources, both use a common enable bit
+	 * in CCM_CSCDR1, selecting "dummy" clock as parent of
+	 * "ftm0_ext_fix" make it serve only for enable/disable.
+	 */
+	clk[VF610_CLK_FTM0_EXT_SEL] = imx_clk_mux("ftm0_ext_sel", CCM_CSCMR2, 6, 2, ftm_ext_sels, 4);
+	clk[VF610_CLK_FTM0_FIX_SEL] = imx_clk_mux("ftm0_fix_sel", CCM_CSCMR2, 14, 1, ftm_fix_sels, 2);
+	clk[VF610_CLK_FTM0_EXT_FIX_EN] = imx_clk_gate("ftm0_ext_fix_en", "dummy", CCM_CSCDR1, 25);
+	clk[VF610_CLK_FTM1_EXT_SEL] = imx_clk_mux("ftm1_ext_sel", CCM_CSCMR2, 8, 2, ftm_ext_sels, 4);
+	clk[VF610_CLK_FTM1_FIX_SEL] = imx_clk_mux("ftm1_fix_sel", CCM_CSCMR2, 15, 1, ftm_fix_sels, 2);
+	clk[VF610_CLK_FTM1_EXT_FIX_EN] = imx_clk_gate("ftm1_ext_fix_en", "dummy", CCM_CSCDR1, 26);
+	clk[VF610_CLK_FTM2_EXT_SEL] = imx_clk_mux("ftm2_ext_sel", CCM_CSCMR2, 10, 2, ftm_ext_sels, 4);
+	clk[VF610_CLK_FTM2_FIX_SEL] = imx_clk_mux("ftm2_fix_sel", CCM_CSCMR2, 16, 1, ftm_fix_sels, 2);
+	clk[VF610_CLK_FTM2_EXT_FIX_EN] = imx_clk_gate("ftm2_ext_fix_en", "dummy", CCM_CSCDR1, 27);
+	clk[VF610_CLK_FTM3_EXT_SEL] = imx_clk_mux("ftm3_ext_sel", CCM_CSCMR2, 12, 2, ftm_ext_sels, 4);
+	clk[VF610_CLK_FTM3_FIX_SEL] = imx_clk_mux("ftm3_fix_sel", CCM_CSCMR2, 17, 1, ftm_fix_sels, 2);
+	clk[VF610_CLK_FTM3_EXT_FIX_EN] = imx_clk_gate("ftm3_ext_fix_en", "dummy", CCM_CSCDR1, 28);
+
+	/* ftm(n)_clk are FTM module operation clock */
+	clk[VF610_CLK_FTM0] = imx_clk_gate2("ftm0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(8));
+	clk[VF610_CLK_FTM1] = imx_clk_gate2("ftm1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(9));
+	clk[VF610_CLK_FTM2] = imx_clk_gate2("ftm2", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(8));
+	clk[VF610_CLK_FTM3] = imx_clk_gate2("ftm3", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(9));
+
+	clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2);
+	clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19);
+	clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3);
+	clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, CCM_CCGRx_CGn(8));
+	clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2);
+	clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23);
+	clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3);
+	clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, CCM_CCGRx_CGn(8));
+
+	clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4);
+	clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30);
+	clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", CCM_CSCDR2, 24, 4);
+	clk[VF610_CLK_ESAI] = imx_clk_gate2("esai", "esai_div", CCM_CCGR4, CCM_CCGRx_CGn(2));
+
+	clk[VF610_CLK_SAI0_SEL] = imx_clk_mux("sai0_sel", CCM_CSCMR1, 0, 2, sai_sels, 4);
+	clk[VF610_CLK_SAI0_EN] = imx_clk_gate("sai0_en", "sai0_sel", CCM_CSCDR1, 16);
+	clk[VF610_CLK_SAI0_DIV] = imx_clk_divider("sai0_div", "sai0_en", CCM_CSCDR1, 0, 4);
+	clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "sai0_div", CCM_CCGR0, CCM_CCGRx_CGn(15));
+
+	clk[VF610_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", CCM_CSCMR1, 2, 2, sai_sels, 4);
+	clk[VF610_CLK_SAI1_EN] = imx_clk_gate("sai1_en", "sai1_sel", CCM_CSCDR1, 17);
+	clk[VF610_CLK_SAI1_DIV] = imx_clk_divider("sai1_div", "sai1_en", CCM_CSCDR1, 4, 4);
+	clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "sai1_div", CCM_CCGR1, CCM_CCGRx_CGn(0));
+
+	clk[VF610_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", CCM_CSCMR1, 4, 2, sai_sels, 4);
+	clk[VF610_CLK_SAI2_EN] = imx_clk_gate("sai2_en", "sai2_sel", CCM_CSCDR1, 18);
+	clk[VF610_CLK_SAI2_DIV] = imx_clk_divider("sai2_div", "sai2_en", CCM_CSCDR1, 8, 4);
+	clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "sai2_div", CCM_CCGR1, CCM_CCGRx_CGn(1));
+
+	clk[VF610_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", CCM_CSCMR1, 6, 2, sai_sels, 4);
+	clk[VF610_CLK_SAI3_EN] = imx_clk_gate("sai3_en", "sai3_sel", CCM_CSCDR1, 19);
+	clk[VF610_CLK_SAI3_DIV] = imx_clk_divider("sai3_div", "sai3_en", CCM_CSCDR1, 12, 4);
+	clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "sai3_div", CCM_CCGR1, CCM_CCGRx_CGn(2));
+
+	clk[VF610_CLK_NFC_SEL] = imx_clk_mux("nfc_sel", CCM_CSCMR1, 12, 2, nfc_sels, 4);
+	clk[VF610_CLK_NFC_EN] = imx_clk_gate("nfc_en", "nfc_sel", CCM_CSCDR2, 9);
+	clk[VF610_CLK_NFC_PRE_DIV] = imx_clk_divider("nfc_pre_div", "nfc_en", CCM_CSCDR3, 13, 3);
+	clk[VF610_CLK_NFC_FRAC_DIV] = imx_clk_divider("nfc_frac_div", "nfc_pre_div", CCM_CSCDR2, 4, 4);
+	clk[VF610_CLK_NFC] = imx_clk_gate2("nfc", "nfc_frac_div", CCM_CCGR10, CCM_CCGRx_CGn(0));
+
+	clk[VF610_CLK_GPU_SEL] = imx_clk_mux("gpu_sel", CCM_CSCMR1, 14, 1, gpu_sels, 2);
+	clk[VF610_CLK_GPU_EN] = imx_clk_gate("gpu_en", "gpu_sel", CCM_CSCDR2, 10);
+	clk[VF610_CLK_GPU2D] = imx_clk_gate2("gpu", "gpu_en", CCM_CCGR8, CCM_CCGRx_CGn(15));
+
+	clk[VF610_CLK_VADC_SEL] = imx_clk_mux("vadc_sel", CCM_CSCMR1, 8, 2, vadc_sels, 3);
+	clk[VF610_CLK_VADC_EN] = imx_clk_gate("vadc_en", "vadc_sel", CCM_CSCDR1, 22);
+	clk[VF610_CLK_VADC_DIV] = imx_clk_divider("vadc_div", "vadc_en", CCM_CSCDR1, 20, 2);
+	clk[VF610_CLK_VADC_DIV_HALF] = imx_clk_fixed_factor("vadc_div_half", "vadc_div", 1, 2);
+	clk[VF610_CLK_VADC] = imx_clk_gate2("vadc", "vadc_div", CCM_CCGR8, CCM_CCGRx_CGn(7));
+
+	clk[VF610_CLK_ADC0] = imx_clk_gate2("adc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(11));
+	clk[VF610_CLK_ADC1] = imx_clk_gate2("adc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(11));
+	clk[VF610_CLK_DAC0] = imx_clk_gate2("dac0", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(12));
+	clk[VF610_CLK_DAC1] = imx_clk_gate2("dac1", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(13));
+
+	clk[VF610_CLK_ASRC] = imx_clk_gate2("asrc", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(1));
+
+	clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(0));
+	clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(4));
+
+	clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]);
+	clk_set_rate(clk[VF610_CLK_QSPI0_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_SEL]) / 2);
+	clk_set_rate(clk[VF610_CLK_QSPI0_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X4_DIV]) / 2);
+	clk_set_rate(clk[VF610_CLK_QSPI0_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X2_DIV]) / 2);
+
+	clk_set_parent(clk[VF610_CLK_QSPI1_SEL], clk[VF610_CLK_PLL1_PFD4]);
+	clk_set_rate(clk[VF610_CLK_QSPI1_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_SEL]) / 2);
+	clk_set_rate(clk[VF610_CLK_QSPI1_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X4_DIV]) / 2);
+	clk_set_rate(clk[VF610_CLK_QSPI1_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X2_DIV]) / 2);
+
+	clk_set_parent(clk[VF610_CLK_SAI0_SEL], clk[VF610_CLK_AUDIO_EXT]);
+	clk_set_parent(clk[VF610_CLK_SAI1_SEL], clk[VF610_CLK_AUDIO_EXT]);
+	clk_set_parent(clk[VF610_CLK_SAI2_SEL], clk[VF610_CLK_AUDIO_EXT]);
+	clk_set_parent(clk[VF610_CLK_SAI3_SEL], clk[VF610_CLK_AUDIO_EXT]);
+
+	/* Add the clocks to provider list */
+	clk_data.clks = clk;
+	clk_data.clk_num = ARRAY_SIZE(clk);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+CLK_OF_DECLARE(vf610, "fsl,vf610-ccm", vf610_clocks_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-imx/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,8 @@
 #ifndef __ASM_ARCH_MXC_COMMON_H__
 #define __ASM_ARCH_MXC_COMMON_H__
 
+#include <linux/reboot.h>
+
 struct platform_device;
 struct pt_regs;
 struct clk;
@@ -68,12 +70,12 @@ extern int mx27_clocks_init_dt(void);
 extern int mx31_clocks_init_dt(void);
 extern int mx51_clocks_init_dt(void);
 extern int mx53_clocks_init_dt(void);
-extern int mx6q_clocks_init(void);
 extern struct platform_device *mxc_register_gpio(char *name, int id,
 	resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
 extern void mxc_set_cpu_type(unsigned int type);
-extern void mxc_restart(char, const char *);
+extern void mxc_restart(enum reboot_mode, const char *);
 extern void mxc_arch_reset_init(void __iomem *);
+extern void mxc_arch_reset_init_dt(void);
 extern int mx53_revision(void);
 extern int imx6q_revision(void);
 extern int mx53_display_revision(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/devices/devices-common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices/devices-common.h
--- linux-libre-3.10-gnu/arch/arm/mach-imx/devices/devices-common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices/devices-common.h	2013-08-25 20:43:22.000000000 -0400
@@ -50,7 +50,6 @@ struct platform_device *__init imx_add_f
 		const struct imx_fec_data *data,
 		const struct fec_platform_data *pdata);
 
-#include <linux/can/platform/flexcan.h>
 struct imx_flexcan_data {
 	int id;
 	resource_size_t iobase;
@@ -58,8 +57,7 @@ struct imx_flexcan_data {
 	resource_size_t irq;
 };
 struct platform_device *__init imx_add_flexcan(
-		const struct imx_flexcan_data *data,
-		const struct flexcan_platform_data *pdata);
+		const struct imx_flexcan_data *data);
 
 #include <linux/fsl_devices.h>
 struct imx_fsl_usb2_udc_data {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/devices/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-imx/devices/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,6 @@ config IMX_HAVE_PLATFORM_FEC
 
 config IMX_HAVE_PLATFORM_FLEXCAN
 	bool
-	select HAVE_CAN_FLEXCAN if CAN
 
 config IMX_HAVE_PLATFORM_FSL_USB2_UDC
 	bool
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/devices/platform-flexcan.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices/platform-flexcan.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/devices/platform-flexcan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices/platform-flexcan.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,8 +38,7 @@ const struct imx_flexcan_data imx35_flex
 #endif /* ifdef CONFIG_SOC_IMX35 */
 
 struct platform_device *__init imx_add_flexcan(
-		const struct imx_flexcan_data *data,
-		const struct flexcan_platform_data *pdata)
+		const struct imx_flexcan_data *data)
 {
 	struct resource res[] = {
 		{
@@ -54,5 +53,5 @@ struct platform_device *__init imx_add_f
 	};
 
 	return imx_add_platform_device("flexcan", data->id,
-			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+			res, ARRAY_SIZE(res), NULL, 0);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/devices-imx25.h linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices-imx25.h
--- linux-libre-3.10-gnu/arch/arm/mach-imx/devices-imx25.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices-imx25.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,10 +13,10 @@ extern const struct imx_fec_data imx25_f
 	imx_add_fec(&imx25_fec_data, pdata)
 
 extern const struct imx_flexcan_data imx25_flexcan_data[];
-#define imx25_add_flexcan(id, pdata)	\
-	imx_add_flexcan(&imx25_flexcan_data[id], pdata)
-#define imx25_add_flexcan0(pdata)	imx25_add_flexcan(0, pdata)
-#define imx25_add_flexcan1(pdata)	imx25_add_flexcan(1, pdata)
+#define imx25_add_flexcan(id)	\
+	imx_add_flexcan(&imx25_flexcan_data[id])
+#define imx25_add_flexcan0()		imx25_add_flexcan(0)
+#define imx25_add_flexcan1()		imx25_add_flexcan(1)
 
 extern const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data;
 #define imx25_add_fsl_usb2_udc(pdata)	\
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/devices-imx35.h linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices-imx35.h
--- linux-libre-3.10-gnu/arch/arm/mach-imx/devices-imx35.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/devices-imx35.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,10 +17,10 @@ extern const struct imx_fsl_usb2_udc_dat
 	imx_add_fsl_usb2_udc(&imx35_fsl_usb2_udc_data, pdata)
 
 extern const struct imx_flexcan_data imx35_flexcan_data[];
-#define imx35_add_flexcan(id, pdata)	\
-	imx_add_flexcan(&imx35_flexcan_data[id], pdata)
-#define imx35_add_flexcan0(pdata)	imx35_add_flexcan(0, pdata)
-#define imx35_add_flexcan1(pdata)	imx35_add_flexcan(1, pdata)
+#define imx35_add_flexcan(id)	\
+	imx_add_flexcan(&imx35_flexcan_data[id])
+#define imx35_add_flexcan0()		imx35_add_flexcan(0)
+#define imx35_add_flexcan1()		imx35_add_flexcan(1)
 
 extern const struct imx_imx2_wdt_data imx35_imx2_wdt_data;
 #define imx35_add_imx2_wdt()       \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c	2013-08-25 20:43:22.000000000 -0400
@@ -279,7 +279,7 @@ void __init eukrea_mbimxsd25_baseboard_i
 	imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata);
 	imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
 
-	imx25_add_flexcan1(NULL);
+	imx25_add_flexcan1();
 	imx25_add_sdhci_esdhc_imx(0, &sd1_pdata);
 
 	gpio_request(GPIO_LED1, "LED1");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c	2013-08-25 20:43:22.000000000 -0400
@@ -287,7 +287,7 @@ void __init eukrea_mbimxsd35_baseboard_i
 
 	imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
 
-	imx35_add_flexcan1(NULL);
+	imx35_add_flexcan1();
 	imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
 
 	gpio_request(GPIO_LED1, "LED1");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/hardware.h linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/hardware.h
--- linux-libre-3.10-gnu/arch/arm/mach-imx/hardware.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/hardware.h	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #ifndef __ASM_ARCH_MXC_HARDWARE_H__
 #define __ASM_ARCH_MXC_HARDWARE_H__
 
+#include <asm/io.h>
 #include <asm/sizes.h>
 
 #define addr_in_module(addr, mod) \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/imx25-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/imx25-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/imx25-dt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/imx25-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,8 @@
 
 static void __init imx25_dt_init(void)
 {
+	mxc_arch_reset_init_dt();
+
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/imx27-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/imx27-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/imx27-dt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/imx27-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,8 @@ static void __init imx27_dt_init(void)
 {
 	struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
 
+	mxc_arch_reset_init_dt();
+
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 
 	platform_device_register_full(&devinfo);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/imx31-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/imx31-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/imx31-dt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/imx31-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,8 @@
 
 static void __init imx31_dt_init(void)
 {
+	mxc_arch_reset_init_dt();
+
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/imx51-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/imx51-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/imx51-dt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/imx51-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,8 @@ static void __init imx51_dt_init(void)
 {
 	struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
 
+	mxc_arch_reset_init_dt();
+
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 	platform_device_register_full(&devinfo);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/irq-common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/irq-common.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/irq-common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/irq-common.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/module.h>
 #include <linux/irq.h>
+#include <linux/platform_data/asoc-imx-ssi.h>
 
 #include "irq-common.h"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-imx/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -56,9 +56,6 @@ config MXC_USE_EPIT
 	  uses the same clocks as the GPT. Anyway, on some systems the GPT
 	  may be in use for other purposes.
 
-config MXC_ULPI
-	bool
-
 config ARCH_HAS_RNGA
 	bool
 
@@ -111,7 +108,6 @@ config SOC_IMX25
 	select ARCH_MXC_IOMUX_V3
 	select COMMON_CLK
 	select CPU_ARM926T
-	select HAVE_CAN_FLEXCAN if CAN
 	select MXC_AVIC
 
 config SOC_IMX27
@@ -137,7 +133,6 @@ config SOC_IMX35
 	select ARCH_MXC_IOMUX_V3
 	select COMMON_CLK
 	select CPU_V6K
-	select HAVE_CAN_FLEXCAN if CAN
 	select HAVE_EPIT
 	select MXC_AVIC
 	select SMP_ON_UP if SMP
@@ -176,6 +171,7 @@ config ARCH_MX1ADS
 config MACH_SCB9328
 	bool "Synertronixx scb9328"
 	select IMX_HAVE_PLATFORM_IMX_UART
+	select SOC_IMX1
 	help
 	  Say Y here if you are using a Synertronixx scb9328 board
 
@@ -233,7 +229,7 @@ config MACH_EUKREA_CPUIMX25SD
 	select IMX_HAVE_PLATFORM_MXC_EHCI
 	select IMX_HAVE_PLATFORM_MXC_NAND
 	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX25
 
 choice
@@ -284,7 +280,7 @@ config MACH_PCM038
 	select IMX_HAVE_PLATFORM_MXC_NAND
 	select IMX_HAVE_PLATFORM_MXC_W1
 	select IMX_HAVE_PLATFORM_SPI_IMX
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX27
 	help
 	  Include support for phyCORE-i.MX27 (aka pcm038) platform. This
@@ -314,7 +310,7 @@ config MACH_CPUIMX27
 	select IMX_HAVE_PLATFORM_MXC_EHCI
 	select IMX_HAVE_PLATFORM_MXC_NAND
 	select IMX_HAVE_PLATFORM_MXC_W1
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX27
 	help
 	  Include support for Eukrea CPUIMX27 platform. This includes
@@ -369,7 +365,7 @@ config MACH_MX27_3DS
 	select IMX_HAVE_PLATFORM_MXC_MMC
 	select IMX_HAVE_PLATFORM_SPI_IMX
 	select MXC_DEBUG_BOARD
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX27
 	help
 	  Include support for MX27PDK platform. This includes specific
@@ -414,7 +410,7 @@ config MACH_PCA100
 	select IMX_HAVE_PLATFORM_MXC_NAND
 	select IMX_HAVE_PLATFORM_MXC_W1
 	select IMX_HAVE_PLATFORM_SPI_IMX
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX27
 	help
 	  Include support for phyCARD-s (aka pca100) platform. This
@@ -481,7 +477,7 @@ config MACH_MX31LILLY
 	select IMX_HAVE_PLATFORM_MXC_EHCI
 	select IMX_HAVE_PLATFORM_MXC_MMC
 	select IMX_HAVE_PLATFORM_SPI_IMX
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX31
 	help
 	  Include support for mx31 based LILLY1131 modules. This includes
@@ -497,7 +493,7 @@ config MACH_MX31LITE
 	select IMX_HAVE_PLATFORM_MXC_RTC
 	select IMX_HAVE_PLATFORM_SPI_IMX
 	select LEDS_GPIO_REGISTER
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX31
 	help
 	  Include support for MX31 LITEKIT platform. This includes specific
@@ -514,7 +510,7 @@ config MACH_PCM037
 	select IMX_HAVE_PLATFORM_MXC_MMC
 	select IMX_HAVE_PLATFORM_MXC_NAND
 	select IMX_HAVE_PLATFORM_MXC_W1
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX31
 	help
 	  Include support for Phytec pcm037 platform. This includes
@@ -544,7 +540,7 @@ config MACH_MX31_3DS
 	select IMX_HAVE_PLATFORM_MXC_NAND
 	select IMX_HAVE_PLATFORM_SPI_IMX
 	select MXC_DEBUG_BOARD
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX31
 	help
 	  Include support for MX31PDK (3DS) platform. This includes specific
@@ -571,7 +567,7 @@ config MACH_MX31MOBOARD
 	select IMX_HAVE_PLATFORM_MXC_MMC
 	select IMX_HAVE_PLATFORM_SPI_IMX
 	select LEDS_GPIO_REGISTER
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX31
 	help
 	  Include support for mx31moboard platform. This includes specific
@@ -595,7 +591,7 @@ config MACH_ARMADILLO5X0
 	select IMX_HAVE_PLATFORM_MXC_EHCI
 	select IMX_HAVE_PLATFORM_MXC_MMC
 	select IMX_HAVE_PLATFORM_MXC_NAND
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX31
 	help
 	  Include support for Atmark Armadillo-500 platform. This includes
@@ -639,7 +635,7 @@ config MACH_PCM043
 	select IMX_HAVE_PLATFORM_MXC_EHCI
 	select IMX_HAVE_PLATFORM_MXC_NAND
 	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX35
 	help
 	  Include support for Phytec pcm043 platform. This includes
@@ -673,7 +669,7 @@ config MACH_EUKREA_CPUIMX35SD
 	select IMX_HAVE_PLATFORM_MXC_EHCI
 	select IMX_HAVE_PLATFORM_MXC_NAND
 	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
-	select MXC_ULPI if USB_ULPI
+	select USB_ULPI_VIEWPORT if USB_ULPI
 	select SOC_IMX35
 	help
 	  Include support for Eukrea CPUIMX35 platform. This includes
@@ -776,7 +772,6 @@ comment "Device tree only"
 
 config	SOC_IMX53
 	bool "i.MX53 support"
-	select HAVE_CAN_FLEXCAN if CAN
 	select HAVE_IMX_SRC
 	select IMX_HAVE_PLATFORM_IMX2_WDT
 	select PINCTRL
@@ -799,7 +794,6 @@ config SOC_IMX6Q
 	select CPU_V7
 	select HAVE_ARM_SCU if SMP
 	select HAVE_ARM_TWD if LOCAL_TIMERS
-	select HAVE_CAN_FLEXCAN if CAN
 	select HAVE_IMX_ANATOP
 	select HAVE_IMX_GPC
 	select HAVE_IMX_MMDC
@@ -816,6 +810,41 @@ config SOC_IMX6Q
 	help
 	  This enables support for Freescale i.MX6 Quad processor.
 
+config SOC_IMX6SL
+	bool "i.MX6 SoloLite support"
+	select ARM_ERRATA_754322
+	select ARM_ERRATA_775420
+	select ARM_GIC
+	select CPU_V7
+	select HAVE_IMX_ANATOP
+	select HAVE_IMX_GPC
+	select HAVE_IMX_MMDC
+	select HAVE_IMX_SRC
+	select MFD_SYSCON
+	select PINCTRL
+	select PINCTRL_IMX6SL
+	select PL310_ERRATA_588369 if CACHE_PL310
+	select PL310_ERRATA_727915 if CACHE_PL310
+	select PL310_ERRATA_769419 if CACHE_PL310
+
+	help
+	  This enables support for Freescale i.MX6 SoloLite processor.
+
+config SOC_VF610
+	bool "Vybrid Family VF610 support"
+	select CPU_V7
+	select ARM_GIC
+	select CLKSRC_OF
+	select PINCTRL
+	select PINCTRL_VF610
+	select VF_PIT_TIMER
+	select PL310_ERRATA_588369 if CACHE_PL310
+	select PL310_ERRATA_727915 if CACHE_PL310
+	select PL310_ERRATA_769419 if CACHE_PL310
+
+	help
+	  This enable support for Freescale Vybrid VF610 processor.
+
 endif
 
 source "arch/arm/mach-imx/devices/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mach-imx53.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-imx53.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mach-imx53.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-imx53.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,25 +21,12 @@
 #include <asm/mach/time.h>
 
 #include "common.h"
+#include "hardware.h"
 #include "mx53.h"
 
-static void __init imx53_qsb_init(void)
-{
-	struct clk *clk;
-
-	clk = clk_get_sys(NULL, "ssi_ext1");
-	if (IS_ERR(clk)) {
-		pr_err("failed to get clk ssi_ext1\n");
-		return;
-	}
-
-	clk_register_clkdev(clk, NULL, "0-000a");
-}
-
 static void __init imx53_dt_init(void)
 {
-	if (of_machine_is_compatible("fsl,imx53-qsb"))
-		imx53_qsb_init();
+	mxc_arch_reset_init_dt();
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mach-imx6q.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-imx6q.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mach-imx6q.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-imx6q.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/clocksource.h>
 #include <linux/cpu.h>
@@ -26,6 +27,7 @@
 #include <linux/of_platform.h>
 #include <linux/opp.h>
 #include <linux/phy.h>
+#include <linux/reboot.h>
 #include <linux/regmap.h>
 #include <linux/micrel_phy.h>
 #include <linux/mfd/syscon.h>
@@ -66,7 +68,7 @@ static void __init imx6q_init_revision(v
 	mxc_set_cpu_type(rev >> 16 & 0xff);
 }
 
-static void imx6q_restart(char mode, const char *cmd)
+static void imx6q_restart(enum reboot_mode mode, const char *cmd)
 {
 	struct device_node *np;
 	void __iomem *wdog_base;
@@ -145,6 +147,45 @@ static void __init imx6q_sabrelite_init(
 	imx6q_sabrelite_cko1_setup();
 }
 
+static void __init imx6q_sabresd_cko1_setup(void)
+{
+	struct clk *cko1_sel, *pll4, *pll4_post, *cko1;
+	unsigned long rate;
+
+	cko1_sel = clk_get_sys(NULL, "cko1_sel");
+	pll4 = clk_get_sys(NULL, "pll4_audio");
+	pll4_post = clk_get_sys(NULL, "pll4_post_div");
+	cko1 = clk_get_sys(NULL, "cko1");
+	if (IS_ERR(cko1_sel) || IS_ERR(pll4)
+			|| IS_ERR(pll4_post) || IS_ERR(cko1)) {
+		pr_err("cko1 setup failed!\n");
+		goto put_clk;
+	}
+	/*
+	 * Setting pll4 at 768MHz (24MHz * 32)
+	 * So its child clock can get 24MHz easily
+	 */
+	clk_set_rate(pll4, 768000000);
+
+	clk_set_parent(cko1_sel, pll4_post);
+	rate = clk_round_rate(cko1, 24000000);
+	clk_set_rate(cko1, rate);
+put_clk:
+	if (!IS_ERR(cko1_sel))
+		clk_put(cko1_sel);
+	if (!IS_ERR(pll4_post))
+		clk_put(pll4_post);
+	if (!IS_ERR(pll4))
+		clk_put(pll4);
+	if (!IS_ERR(cko1))
+		clk_put(cko1);
+}
+
+static void __init imx6q_sabresd_init(void)
+{
+	imx6q_sabresd_cko1_setup();
+}
+
 static void __init imx6q_1588_init(void)
 {
 	struct regmap *gpr;
@@ -165,6 +206,9 @@ static void __init imx6q_init_machine(vo
 {
 	if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
 		imx6q_sabrelite_init();
+	else if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
+			of_machine_is_compatible("fsl,imx6dl-sabresd"))
+		imx6q_sabresd_init();
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 
@@ -253,10 +297,44 @@ static void __init imx6q_map_io(void)
 	imx_scu_map_io();
 }
 
+#ifdef CONFIG_CACHE_L2X0
+static void __init imx6q_init_l2cache(void)
+{
+	void __iomem *l2x0_base;
+	struct device_node *np;
+	unsigned int val;
+
+	np = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
+	if (!np)
+		goto out;
+
+	l2x0_base = of_iomap(np, 0);
+	if (!l2x0_base) {
+		of_node_put(np);
+		goto out;
+	}
+
+	/* Configure the L2 PREFETCH and POWER registers */
+	val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
+	val |= 0x70800000;
+	writel_relaxed(val, l2x0_base + L2X0_PREFETCH_CTRL);
+	val = L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
+	writel_relaxed(val, l2x0_base + L2X0_POWER_CTRL);
+
+	iounmap(l2x0_base);
+	of_node_put(np);
+
+out:
+	l2x0_of_init(0, ~0UL);
+}
+#else
+static inline void imx6q_init_l2cache(void) {}
+#endif
+
 static void __init imx6q_init_irq(void)
 {
 	imx6q_init_revision();
-	l2x0_of_init(0, ~0UL);
+	imx6q_init_l2cache();
 	imx_src_init();
 	imx_gpc_init();
 	irqchip_init();
@@ -264,7 +342,7 @@ static void __init imx6q_init_irq(void)
 
 static void __init imx6q_timer_init(void)
 {
-	mx6q_clocks_init();
+	of_clk_init(NULL);
 	clocksource_of_init();
 	imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
 			      imx6q_revision());
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mach-imx6sl.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-imx6sl.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mach-imx6sl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-imx6sl.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/irqchip.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+
+static void __init imx6sl_init_machine(void)
+{
+	mxc_arch_reset_init_dt();
+
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static void __init imx6sl_init_irq(void)
+{
+	l2x0_of_init(0, ~0UL);
+	imx_src_init();
+	imx_gpc_init();
+	irqchip_init();
+}
+
+static void __init imx6sl_timer_init(void)
+{
+	of_clk_init(NULL);
+}
+
+static const char *imx6sl_dt_compat[] __initdata = {
+	"fsl,imx6sl",
+	NULL,
+};
+
+DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)")
+	.map_io		= debug_ll_io_init,
+	.init_irq	= imx6sl_init_irq,
+	.init_time	= imx6sl_timer_init,
+	.init_machine	= imx6sl_init_machine,
+	.dt_compat	= imx6sl_dt_compat,
+	.restart	= mxc_restart,
+MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mach-mx25_3ds.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-mx25_3ds.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mach-mx25_3ds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-mx25_3ds.c	2013-08-25 20:43:22.000000000 -0400
@@ -249,7 +249,7 @@ static void __init mx25pdk_init(void)
 	imx25_add_imx_i2c0(&mx25_3ds_i2c0_data);
 
 	gpio_request_one(MX25PDK_CAN_PWDN, GPIOF_OUT_INIT_LOW, "can-pwdn");
-	imx25_add_flexcan0(NULL);
+	imx25_add_flexcan0();
 }
 
 static void __init mx25pdk_timer_init(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mach-mx31moboard.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-mx31moboard.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mach-mx31moboard.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-mx31moboard.c	2013-08-25 20:43:22.000000000 -0400
@@ -268,10 +268,11 @@ static struct mc13xxx_led_platform_data
 static struct mc13xxx_leds_platform_data moboard_leds = {
 	.num_leds = ARRAY_SIZE(moboard_led),
 	.led = moboard_led,
-	.flags = MC13783_LED_SLEWLIMTC,
-	.abmode = MC13783_LED_AB_DISABLED,
-	.tc1_period = MC13783_LED_PERIOD_10MS,
-	.tc2_period = MC13783_LED_PERIOD_10MS,
+	.led_control[0]	= MC13783_LED_C0_ENABLE | MC13783_LED_C0_ABMODE(0),
+	.led_control[1]	= MC13783_LED_C1_SLEWLIM,
+	.led_control[2]	= MC13783_LED_C2_SLEWLIM,
+	.led_control[3]	= MC13783_LED_C3_PERIOD(0),
+	.led_control[4]	= MC13783_LED_C3_PERIOD(0),
 };
 
 static struct mc13xxx_buttons_platform_data moboard_buttons = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mach-pca100.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-pca100.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mach-pca100.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-pca100.c	2013-08-25 20:43:22.000000000 -0400
@@ -398,8 +398,8 @@ static void __init pca100_init(void)
 		imx27_add_fsl_usb2_udc(&otg_device_pdata);
 	}
 
-	usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
-				ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+	usbh2_pdata.otg = imx_otg_ulpi_create(
+			ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
 
 	if (usbh2_pdata.otg)
 		imx27_add_mxc_ehci_hs(2, &usbh2_pdata);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mach-pcm043.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-pcm043.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mach-pcm043.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-pcm043.c	2013-08-25 20:43:22.000000000 -0400
@@ -385,7 +385,7 @@ static void __init pcm043_init(void)
 	if (!otg_mode_host)
 		imx35_add_fsl_usb2_udc(&otg_device_pdata);
 
-	imx35_add_flexcan1(NULL);
+	imx35_add_flexcan1();
 	imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mach-vf610.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-vf610.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mach-vf610.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mach-vf610.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012-2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/of_platform.h>
+#include <linux/clocksource.h>
+#include <linux/irqchip.h>
+#include <linux/clk-provider.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "common.h"
+
+static void __init vf610_init_machine(void)
+{
+	mxc_arch_reset_init_dt();
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static void __init vf610_init_irq(void)
+{
+	l2x0_of_init(0, ~0UL);
+	irqchip_init();
+}
+
+static void __init vf610_init_time(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+}
+
+static const char *vf610_dt_compat[] __initdata = {
+	"fsl,vf610",
+	NULL,
+};
+
+DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)")
+	.init_irq	= vf610_init_irq,
+	.init_time	= vf610_init_time,
+	.init_machine   = vf610_init_machine,
+	.dt_compat	= vf610_dt_compat,
+	.restart	= mxc_restart,
+MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-imx/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,6 @@ obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux
 obj-$(CONFIG_MXC_TZIC) += tzic.o
 obj-$(CONFIG_MXC_AVIC) += avic.o
 
-obj-$(CONFIG_MXC_ULPI) += ulpi.o
 obj-$(CONFIG_MXC_USE_EPIT) += epit.o
 obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
 
@@ -98,6 +97,7 @@ AFLAGS_headsmp.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SMP) += headsmp.o platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
+obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
 
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
@@ -111,4 +111,6 @@ obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEB
 obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
 obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
 
+obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o
+
 obj-y += devices/
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx1.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx1.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx1.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,6 @@ void __init mx1_map_io(void)
 void __init imx1_init_early(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX1);
-	mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
 	imx_iomuxv1_init(MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR),
 			MX1_NUM_GPIO_PORT);
 }
@@ -51,6 +50,7 @@ void __init mx1_init_irq(void)
 
 void __init imx1_soc_init(void)
 {
+	mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
 	mxc_device_init();
 
 	mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx21.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx21.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx21.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx21.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,7 +66,6 @@ void __init mx21_map_io(void)
 void __init imx21_init_early(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX21);
-	mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
 	imx_iomuxv1_init(MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR),
 			MX21_NUM_GPIO_PORT);
 }
@@ -82,6 +81,7 @@ static const struct resource imx21_audmu
 
 void __init imx21_soc_init(void)
 {
+	mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
 	mxc_device_init();
 
 	mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx25.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx25.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx25.c	2013-07-01 10:32:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx25.c	2013-08-31 17:51:56.000000000 -0400
@@ -54,7 +54,6 @@ void __init imx25_init_early(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX25);
 	mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR));
-	mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
 }
 
 void __init mx25_init_irq(void)
@@ -89,6 +88,7 @@ static const struct resource imx25_audmu
 
 void __init imx25_soc_init(void)
 {
+	mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
 	mxc_device_init();
 
 	/* i.mx25 has the i.mx35 type gpio */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx27.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx27.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx27.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx27.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,7 +66,6 @@ void __init mx27_map_io(void)
 void __init imx27_init_early(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX27);
-	mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
 	imx_iomuxv1_init(MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR),
 			MX27_NUM_GPIO_PORT);
 }
@@ -82,6 +81,7 @@ static const struct resource imx27_audmu
 
 void __init imx27_soc_init(void)
 {
+	mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
 	mxc_device_init();
 
 	/* i.mx27 has the i.mx21 type gpio */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx3.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx3.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx3.c	2013-07-01 10:32:31.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx3.c	2013-08-31 17:51:58.000000000 -0400
@@ -65,7 +65,7 @@ static void imx3_idle(void)
 		: "=r" (reg));
 }
 
-static void __iomem *imx3_ioremap_caller(unsigned long phys_addr, size_t size,
+static void __iomem *imx3_ioremap_caller(phys_addr_t phys_addr, size_t size,
 					 unsigned int mtype, void *caller)
 {
 	if (mtype == MT_DEVICE) {
@@ -138,7 +138,6 @@ void __init mx31_map_io(void)
 void __init imx31_init_early(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX31);
-	mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
 	arch_ioremap_caller = imx3_ioremap_caller;
 	arm_pm_idle = imx3_idle;
 	mx3_ccm_base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
@@ -174,6 +173,7 @@ void __init imx31_soc_init(void)
 
 	imx3_init_l2x0();
 
+	mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
 	mxc_device_init();
 
 	mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
@@ -216,7 +216,6 @@ void __init imx35_init_early(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX35);
 	mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
-	mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
 	arm_pm_idle = imx3_idle;
 	arch_ioremap_caller = imx3_ioremap_caller;
 	mx3_ccm_base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
@@ -272,6 +271,7 @@ void __init imx35_soc_init(void)
 
 	imx3_init_l2x0();
 
+	mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
 	mxc_device_init();
 
 	mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx5.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx5.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mm-imx5.c	2013-07-01 10:32:33.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mm-imx5.c	2013-08-31 17:52:00.000000000 -0400
@@ -83,7 +83,6 @@ void __init imx51_init_early(void)
 	imx51_ipu_mipi_setup();
 	mxc_set_cpu_type(MXC_CPU_MX51);
 	mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
-	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
 	imx_src_init();
 }
 
@@ -91,7 +90,6 @@ void __init imx53_init_early(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX53);
 	mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
-	mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
 	imx_src_init();
 }
 
@@ -129,6 +127,7 @@ static const struct resource imx51_audmu
 
 void __init imx51_soc_init(void)
 {
+	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
 	mxc_device_init();
 
 	/* i.mx51 has the i.mx35 type gpio */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/mx27.h linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mx27.h
--- linux-libre-3.10-gnu/arch/arm/mach-imx/mx27.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/mx27.h	2013-08-25 20:43:22.000000000 -0400
@@ -135,7 +135,7 @@
 #define MX27_INT_GPT4		(NR_IRQS_LEGACY + 4)
 #define MX27_INT_RTIC		(NR_IRQS_LEGACY + 5)
 #define MX27_INT_CSPI3		(NR_IRQS_LEGACY + 6)
-#define MX27_INT_SDHC		(NR_IRQS_LEGACY + 7)
+#define MX27_INT_MSHC		(NR_IRQS_LEGACY + 7)
 #define MX27_INT_GPIO		(NR_IRQS_LEGACY + 8)
 #define MX27_INT_SDHC3		(NR_IRQS_LEGACY + 9)
 #define MX27_INT_SDHC2		(NR_IRQS_LEGACY + 10)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,7 +53,7 @@ void imx_scu_standby_enable(void)
 	writel_relaxed(val, scu_base);
 }
 
-static int __cpuinit imx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int imx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	imx_set_cpu_jump(cpu, v7_secondary_startup);
 	imx_enable_cpu(cpu, true);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/system.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/system.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/system.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/system.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,8 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <asm/system_misc.h>
 #include <asm/proc-fns.h>
@@ -30,24 +32,22 @@
 #include "hardware.h"
 
 static void __iomem *wdog_base;
+static struct clk *wdog_clk;
 
 /*
  * Reset the system. It is called by machine_restart().
  */
-void mxc_restart(char mode, const char *cmd)
+void mxc_restart(enum reboot_mode mode, const char *cmd)
 {
 	unsigned int wcr_enable;
 
-	if (cpu_is_mx1()) {
-		wcr_enable = (1 << 0);
-	} else {
-		struct clk *clk;
+	if (wdog_clk)
+		clk_enable(wdog_clk);
 
-		clk = clk_get_sys("imx2-wdt.0", NULL);
-		if (!IS_ERR(clk))
-			clk_prepare_enable(clk);
+	if (cpu_is_mx1())
+		wcr_enable = (1 << 0);
+	else
 		wcr_enable = (1 << 2);
-	}
 
 	/* Assert SRS signal */
 	__raw_writew(wcr_enable, wdog_base);
@@ -55,7 +55,7 @@ void mxc_restart(char mode, const char *
 	/* wait for reset to assert... */
 	mdelay(500);
 
-	printk(KERN_ERR "Watchdog reset failed to assert reset\n");
+	pr_err("%s: Watchdog reset failed to assert reset\n", __func__);
 
 	/* delay to allow the serial port to show the message */
 	mdelay(50);
@@ -64,7 +64,34 @@ void mxc_restart(char mode, const char *
 	soft_restart(0);
 }
 
-void mxc_arch_reset_init(void __iomem *base)
+void __init mxc_arch_reset_init(void __iomem *base)
 {
 	wdog_base = base;
+
+	wdog_clk = clk_get_sys("imx2-wdt.0", NULL);
+	if (IS_ERR(wdog_clk)) {
+		pr_warn("%s: failed to get wdog clock\n", __func__);
+		wdog_clk = NULL;
+		return;
+	}
+
+	clk_prepare(wdog_clk);
+}
+
+void __init mxc_arch_reset_init_dt(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx21-wdt");
+	wdog_base = of_iomap(np, 0);
+	WARN_ON(!wdog_base);
+
+	wdog_clk = of_clk_get(np, 0);
+	if (IS_ERR(wdog_clk)) {
+		pr_warn("%s: failed to get wdog clock\n", __func__);
+		wdog_clk = NULL;
+		return;
+	}
+
+	clk_prepare(wdog_clk);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/time.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/time.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,8 +26,8 @@
 #include <linux/clockchips.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/sched_clock.h>
 
-#include <asm/sched_clock.h>
 #include <asm/mach/time.h>
 
 #include "common.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/ulpi.c linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/ulpi.c
--- linux-libre-3.10-gnu/arch/arm/mach-imx/ulpi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/ulpi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,118 +0,0 @@
-/*
- * Copyright 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- * Copyright 2009 Daniel Mack <daniel@caiaq.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA  02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/ulpi.h>
-
-#include "ulpi.h"
-
-/* ULPIVIEW register bits */
-#define ULPIVW_WU		(1 << 31)	/* Wakeup */
-#define ULPIVW_RUN		(1 << 30)	/* read/write run */
-#define ULPIVW_WRITE		(1 << 29)	/* 0 = read  1 = write */
-#define ULPIVW_SS		(1 << 27)	/* SyncState */
-#define ULPIVW_PORT_MASK	0x07	/* Port field */
-#define ULPIVW_PORT_SHIFT	24
-#define ULPIVW_ADDR_MASK	0xff	/* data address field */
-#define ULPIVW_ADDR_SHIFT	16
-#define ULPIVW_RDATA_MASK	0xff	/* read data field */
-#define ULPIVW_RDATA_SHIFT	8
-#define ULPIVW_WDATA_MASK	0xff	/* write data field */
-#define ULPIVW_WDATA_SHIFT	0
-
-static int ulpi_poll(void __iomem *view, u32 bit)
-{
-	int timeout = 10000;
-
-	while (timeout--) {
-		u32 data = __raw_readl(view);
-
-		if (!(data & bit))
-			return 0;
-
-		cpu_relax();
-	};
-
-	printk(KERN_WARNING "timeout polling for ULPI device\n");
-
-	return -ETIMEDOUT;
-}
-
-static int ulpi_read(struct usb_phy *otg, u32 reg)
-{
-	int ret;
-	void __iomem *view = otg->io_priv;
-
-	/* make sure interface is running */
-	if (!(__raw_readl(view) & ULPIVW_SS)) {
-		__raw_writel(ULPIVW_WU, view);
-
-		/* wait for wakeup */
-		ret = ulpi_poll(view, ULPIVW_WU);
-		if (ret)
-			return ret;
-	}
-
-	/* read the register */
-	__raw_writel((ULPIVW_RUN | (reg << ULPIVW_ADDR_SHIFT)), view);
-
-	/* wait for completion */
-	ret = ulpi_poll(view, ULPIVW_RUN);
-	if (ret)
-		return ret;
-
-	return (__raw_readl(view) >> ULPIVW_RDATA_SHIFT) & ULPIVW_RDATA_MASK;
-}
-
-static int ulpi_write(struct usb_phy *otg, u32 val, u32 reg)
-{
-	int ret;
-	void __iomem *view = otg->io_priv;
-
-	/* make sure the interface is running */
-	if (!(__raw_readl(view) & ULPIVW_SS)) {
-		__raw_writel(ULPIVW_WU, view);
-		/* wait for wakeup */
-		ret = ulpi_poll(view, ULPIVW_WU);
-		if (ret)
-			return ret;
-	}
-
-	__raw_writel((ULPIVW_RUN | ULPIVW_WRITE |
-		      (reg << ULPIVW_ADDR_SHIFT) |
-		      ((val & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)), view);
-
-	/* wait for completion */
-	return ulpi_poll(view, ULPIVW_RUN);
-}
-
-struct usb_phy_io_ops mxc_ulpi_access_ops = {
-	.read	= ulpi_read,
-	.write	= ulpi_write,
-};
-EXPORT_SYMBOL_GPL(mxc_ulpi_access_ops);
-
-struct usb_phy *imx_otg_ulpi_create(unsigned int flags)
-{
-	return otg_ulpi_create(&mxc_ulpi_access_ops, flags);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-imx/ulpi.h linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/ulpi.h
--- linux-libre-3.10-gnu/arch/arm/mach-imx/ulpi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-imx/ulpi.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,8 +1,13 @@
 #ifndef __MACH_ULPI_H
 #define __MACH_ULPI_H
 
-#ifdef CONFIG_USB_ULPI
-struct usb_phy *imx_otg_ulpi_create(unsigned int flags);
+#include <linux/usb/ulpi.h>
+
+#ifdef CONFIG_USB_ULPI_VIEWPORT
+static inline struct usb_phy *imx_otg_ulpi_create(unsigned int flags)
+{
+	return otg_ulpi_create(&ulpi_viewport_access_ops, flags);
+}
 #else
 static inline struct usb_phy *imx_otg_ulpi_create(unsigned int flags)
 {
@@ -10,7 +15,5 @@ static inline struct usb_phy *imx_otg_ul
 }
 #endif
 
-extern struct usb_phy_io_ops mxc_ulpi_access_ops;
-
 #endif /* __MACH_ULPI_H */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-integrator/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-integrator/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,8 @@
+#include <linux/reboot.h>
 #include <linux/amba/serial.h>
 extern struct amba_pl010_data ap_uart_data;
 void integrator_init_early(void);
 int integrator_init(bool is_cp);
 void integrator_reserve(void);
-void integrator_restart(char, const char *);
+void integrator_restart(enum reboot_mode, const char *);
 void integrator_init_sysfs(struct device *parent, u32 id);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-integrator/core.c linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/core.c
--- linux-libre-3.10-gnu/arch/arm/mach-integrator/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -124,7 +124,7 @@ void __init integrator_reserve(void)
 /*
  * To reset, we hit the on-board reset register in the system FPGA
  */
-void integrator_restart(char mode, const char *cmd)
+void integrator_restart(enum reboot_mode mode, const char *cmd)
 {
 	cm_control(CM_CTRL_RESET, CM_CTRL_RESET);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-integrator/include/mach/platform.h linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/include/mach/platform.h
--- linux-libre-3.10-gnu/arch/arm/mach-integrator/include/mach/platform.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/include/mach/platform.h	2013-08-25 20:43:22.000000000 -0400
@@ -305,29 +305,6 @@
 /* KMI definitions are now in include/asm-arm/hardware/amba_kmi.h -- rmk */
 
 /* ------------------------------------------------------------------------
- *  Where in the memory map does PCI live?
- * ------------------------------------------------------------------------
- *  This represents a fairly liberal usage of address space.  Even though
- *  the V3 only has two windows (therefore we need to map stuff on the fly),
- *  we maintain the same addresses, even if they're not mapped.
- *
- */
-#define PHYS_PCI_MEM_BASE               0x40000000   /* 512M to xxx */
-/*  unused 256M from A0000000-AFFFFFFF might be used for I2O ???
- */
-#define PHYS_PCI_IO_BASE                0x60000000   /* 16M to xxx */
-/*  unused (128-16)M from B1000000-B7FFFFFF
- */
-#define PHYS_PCI_CONFIG_BASE            0x61000000   /* 16M to xxx */
-/*  unused ((128-16)M - 64K) from XXX
- */
-#define PHYS_PCI_V3_BASE                0x62000000
-
-#define PCI_MEMORY_VADDR		IOMEM(0xe8000000)
-#define PCI_CONFIG_VADDR		IOMEM(0xec000000)
-#define PCI_V3_VADDR			IOMEM(0xed000000)
-
-/* ------------------------------------------------------------------------
  *  Integrator Interrupt Controllers
  * ------------------------------------------------------------------------
  *
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-integrator/integrator_ap.c linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/integrator_ap.c
--- linux-libre-3.10-gnu/arch/arm/mach-integrator/integrator_ap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/integrator_ap.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,7 +41,7 @@
 #include <linux/stat.h>
 #include <linux/sys_soc.h>
 #include <linux/termios.h>
-#include <video/vga.h>
+#include <linux/sched_clock.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
@@ -49,7 +49,6 @@
 #include <asm/setup.h>
 #include <asm/param.h>		/* HZ */
 #include <asm/mach-types.h>
-#include <asm/sched_clock.h>
 
 #include <mach/lm.h>
 #include <mach/irqs.h>
@@ -57,10 +56,10 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
-#include <asm/mach/pci.h>
 #include <asm/mach/time.h>
 
 #include "common.h"
+#include "pci_v3.h"
 
 /* Base address to the AP system controller */
 void __iomem *ap_syscon_base;
@@ -78,10 +77,6 @@ void __iomem *ap_syscon_base;
 
 /*
  * Logical      Physical
- * e8000000	40000000	PCI memory		PHYS_PCI_MEM_BASE	(max 512M)
- * ec000000	61000000	PCI config space	PHYS_PCI_CONFIG_BASE	(max 16M)
- * ed000000	62000000	PCI V3 regs		PHYS_PCI_V3_BASE	(max 64k)
- * fee00000	60000000	PCI IO			PHYS_PCI_IO_BASE	(max 16M)
  * ef000000			Cache flush
  * f1000000	10000000	Core module registers
  * f1100000	11000000	System controller registers
@@ -130,29 +125,13 @@ static struct map_desc ap_io_desc[] __in
 		.pfn		= __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
-	}, {
-		.virtual	= (unsigned long)PCI_MEMORY_VADDR,
-		.pfn		= __phys_to_pfn(PHYS_PCI_MEM_BASE),
-		.length		= SZ_16M,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= (unsigned long)PCI_CONFIG_VADDR,
-		.pfn		= __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
-		.length		= SZ_16M,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= (unsigned long)PCI_V3_VADDR,
-		.pfn		= __phys_to_pfn(PHYS_PCI_V3_BASE),
-		.length		= SZ_64K,
-		.type		= MT_DEVICE
 	}
 };
 
 static void __init ap_map_io(void)
 {
 	iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
-	vga_base = (unsigned long)PCI_MEMORY_VADDR;
-	pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
+	pci_v3_early_init();
 }
 
 #ifdef CONFIG_PM
@@ -615,6 +594,11 @@ static void __init ap_map_io_atag(void)
  * for eventual deletion.
  */
 
+static struct platform_device pci_v3_device = {
+	.name		= "pci-v3",
+	.id		= 0,
+};
+
 static struct resource cfi_flash_resource = {
 	.start		= INTEGRATOR_FLASH_BASE,
 	.end		= INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
@@ -672,6 +656,7 @@ static void __init ap_init(void)
 	unsigned long sc_dec;
 	int i;
 
+	platform_device_register(&pci_v3_device);
 	platform_device_register(&cfi_flash_device);
 
 	ap_syscon_base = __io_address(INTEGRATOR_SC_BASE);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-integrator/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-integrator/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -8,5 +8,5 @@ obj-y					:= core.o lm.o leds.o
 obj-$(CONFIG_ARCH_INTEGRATOR_AP)	+= integrator_ap.o
 obj-$(CONFIG_ARCH_INTEGRATOR_CP)	+= integrator_cp.o
 
-obj-$(CONFIG_PCI)			+= pci_v3.o pci.o
+obj-$(CONFIG_PCI)			+= pci_v3.o
 obj-$(CONFIG_INTEGRATOR_IMPD1)		+= impd1.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-integrator/pci.c linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/pci.c
--- linux-libre-3.10-gnu/arch/arm/mach-integrator/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/pci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,113 +0,0 @@
-/*
- *  linux/arch/arm/mach-integrator/pci-integrator.c
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *
- *  PCI functions for Integrator
- */
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-
-#include <mach/irqs.h>
-
-/* 
- * A small note about bridges and interrupts.  The DECchip 21050 (and
- * later) adheres to the PCI-PCI bridge specification.  This says that
- * the interrupts on the other side of a bridge are swizzled in the
- * following manner:
- *
- * Dev    Interrupt   Interrupt 
- *        Pin on      Pin on 
- *        Device      Connector
- *
- *   4    A           A
- *        B           B
- *        C           C
- *        D           D
- * 
- *   5    A           B
- *        B           C
- *        C           D
- *        D           A
- *
- *   6    A           C
- *        B           D
- *        C           A
- *        D           B
- *
- *   7    A           D
- *        B           A
- *        C           B
- *        D           C
- *
- * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
- * Thus, each swizzle is ((pin-1) + (device#-4)) % 4
- */
-
-/*
- * This routine handles multiple bridges.
- */
-static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp)
-{
-	if (*pinp == 0)
-		*pinp = 1;
-
-	return pci_common_swizzle(dev, pinp);
-}
-
-static int irq_tab[4] __initdata = {
-	IRQ_AP_PCIINT0,	IRQ_AP_PCIINT1,	IRQ_AP_PCIINT2,	IRQ_AP_PCIINT3
-};
-
-/*
- * map the specified device/slot/pin to an IRQ.  This works out such
- * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
- */
-static int __init integrator_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	int intnr = ((slot - 9) + (pin - 1)) & 3;
-
-	return irq_tab[intnr];
-}
-
-extern void pci_v3_init(void *);
-
-static struct hw_pci integrator_pci __initdata = {
-	.swizzle		= integrator_swizzle,
-	.map_irq		= integrator_map_irq,
-	.setup			= pci_v3_setup,
-	.nr_controllers		= 1,
-	.ops			= &pci_v3_ops,
-	.preinit		= pci_v3_preinit,
-	.postinit		= pci_v3_postinit,
-};
-
-static int __init integrator_pci_init(void)
-{
-	if (machine_is_integrator())
-		pci_common_init(&integrator_pci);
-	return 0;
-}
-
-subsys_initcall(integrator_pci_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-integrator/pci_v3.c linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/pci_v3.c
--- linux-libre-3.10-gnu/arch/arm/mach-integrator/pci_v3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/pci_v3.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,16 +27,199 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <video/vga.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
 #include <mach/irqs.h>
 
+#include <asm/mach/map.h>
 #include <asm/signal.h>
 #include <asm/mach/pci.h>
 #include <asm/irq_regs.h>
 
-#include <asm/hardware/pci_v3.h>
+#include "pci_v3.h"
+
+/*
+ * Where in the memory map does PCI live?
+ *
+ * This represents a fairly liberal usage of address space.  Even though
+ * the V3 only has two windows (therefore we need to map stuff on the fly),
+ * we maintain the same addresses, even if they're not mapped.
+ */
+#define PHYS_PCI_MEM_BASE               0x40000000 /* 256M */
+#define PHYS_PCI_PRE_BASE               0x50000000 /* 256M */
+#define PHYS_PCI_IO_BASE                0x60000000 /* 16M */
+#define PHYS_PCI_CONFIG_BASE            0x61000000 /* 16M */
+#define PHYS_PCI_V3_BASE                0x62000000 /* 64K */
+
+#define PCI_MEMORY_VADDR               IOMEM(0xe8000000)
+#define PCI_CONFIG_VADDR               IOMEM(0xec000000)
+
+/*
+ * V3 Local Bus to PCI Bridge definitions
+ *
+ * Registers (these are taken from page 129 of the EPC User's Manual Rev 1.04
+ * All V3 register names are prefaced by V3_ to avoid clashing with any other
+ * PCI definitions.  Their names match the user's manual.
+ *
+ * I'm assuming that I20 is disabled.
+ *
+ */
+#define V3_PCI_VENDOR                   0x00000000
+#define V3_PCI_DEVICE                   0x00000002
+#define V3_PCI_CMD                      0x00000004
+#define V3_PCI_STAT                     0x00000006
+#define V3_PCI_CC_REV                   0x00000008
+#define V3_PCI_HDR_CFG                  0x0000000C
+#define V3_PCI_IO_BASE                  0x00000010
+#define V3_PCI_BASE0                    0x00000014
+#define V3_PCI_BASE1                    0x00000018
+#define V3_PCI_SUB_VENDOR               0x0000002C
+#define V3_PCI_SUB_ID                   0x0000002E
+#define V3_PCI_ROM                      0x00000030
+#define V3_PCI_BPARAM                   0x0000003C
+#define V3_PCI_MAP0                     0x00000040
+#define V3_PCI_MAP1                     0x00000044
+#define V3_PCI_INT_STAT                 0x00000048
+#define V3_PCI_INT_CFG                  0x0000004C
+#define V3_LB_BASE0                     0x00000054
+#define V3_LB_BASE1                     0x00000058
+#define V3_LB_MAP0                      0x0000005E
+#define V3_LB_MAP1                      0x00000062
+#define V3_LB_BASE2                     0x00000064
+#define V3_LB_MAP2                      0x00000066
+#define V3_LB_SIZE                      0x00000068
+#define V3_LB_IO_BASE                   0x0000006E
+#define V3_FIFO_CFG                     0x00000070
+#define V3_FIFO_PRIORITY                0x00000072
+#define V3_FIFO_STAT                    0x00000074
+#define V3_LB_ISTAT                     0x00000076
+#define V3_LB_IMASK                     0x00000077
+#define V3_SYSTEM                       0x00000078
+#define V3_LB_CFG                       0x0000007A
+#define V3_PCI_CFG                      0x0000007C
+#define V3_DMA_PCI_ADR0                 0x00000080
+#define V3_DMA_PCI_ADR1                 0x00000090
+#define V3_DMA_LOCAL_ADR0               0x00000084
+#define V3_DMA_LOCAL_ADR1               0x00000094
+#define V3_DMA_LENGTH0                  0x00000088
+#define V3_DMA_LENGTH1                  0x00000098
+#define V3_DMA_CSR0                     0x0000008B
+#define V3_DMA_CSR1                     0x0000009B
+#define V3_DMA_CTLB_ADR0                0x0000008C
+#define V3_DMA_CTLB_ADR1                0x0000009C
+#define V3_DMA_DELAY                    0x000000E0
+#define V3_MAIL_DATA                    0x000000C0
+#define V3_PCI_MAIL_IEWR                0x000000D0
+#define V3_PCI_MAIL_IERD                0x000000D2
+#define V3_LB_MAIL_IEWR                 0x000000D4
+#define V3_LB_MAIL_IERD                 0x000000D6
+#define V3_MAIL_WR_STAT                 0x000000D8
+#define V3_MAIL_RD_STAT                 0x000000DA
+#define V3_QBA_MAP                      0x000000DC
+
+/*  PCI COMMAND REGISTER bits
+ */
+#define V3_COMMAND_M_FBB_EN             (1 << 9)
+#define V3_COMMAND_M_SERR_EN            (1 << 8)
+#define V3_COMMAND_M_PAR_EN             (1 << 6)
+#define V3_COMMAND_M_MASTER_EN          (1 << 2)
+#define V3_COMMAND_M_MEM_EN             (1 << 1)
+#define V3_COMMAND_M_IO_EN              (1 << 0)
+
+/*  SYSTEM REGISTER bits
+ */
+#define V3_SYSTEM_M_RST_OUT             (1 << 15)
+#define V3_SYSTEM_M_LOCK                (1 << 14)
+
+/*  PCI_CFG bits
+ */
+#define V3_PCI_CFG_M_I2O_EN		(1 << 15)
+#define V3_PCI_CFG_M_IO_REG_DIS		(1 << 14)
+#define V3_PCI_CFG_M_IO_DIS		(1 << 13)
+#define V3_PCI_CFG_M_EN3V		(1 << 12)
+#define V3_PCI_CFG_M_RETRY_EN           (1 << 10)
+#define V3_PCI_CFG_M_AD_LOW1            (1 << 9)
+#define V3_PCI_CFG_M_AD_LOW0            (1 << 8)
+
+/*  PCI_BASE register bits (PCI -> Local Bus)
+ */
+#define V3_PCI_BASE_M_ADR_BASE          0xFFF00000
+#define V3_PCI_BASE_M_ADR_BASEL         0x000FFF00
+#define V3_PCI_BASE_M_PREFETCH          (1 << 3)
+#define V3_PCI_BASE_M_TYPE              (3 << 1)
+#define V3_PCI_BASE_M_IO                (1 << 0)
+
+/*  PCI MAP register bits (PCI -> Local bus)
+ */
+#define V3_PCI_MAP_M_MAP_ADR            0xFFF00000
+#define V3_PCI_MAP_M_RD_POST_INH        (1 << 15)
+#define V3_PCI_MAP_M_ROM_SIZE           (3 << 10)
+#define V3_PCI_MAP_M_SWAP               (3 << 8)
+#define V3_PCI_MAP_M_ADR_SIZE           0x000000F0
+#define V3_PCI_MAP_M_REG_EN             (1 << 1)
+#define V3_PCI_MAP_M_ENABLE             (1 << 0)
+
+/*
+ *  LB_BASE0,1 register bits (Local bus -> PCI)
+ */
+#define V3_LB_BASE_ADR_BASE		0xfff00000
+#define V3_LB_BASE_SWAP			(3 << 8)
+#define V3_LB_BASE_ADR_SIZE		(15 << 4)
+#define V3_LB_BASE_PREFETCH		(1 << 3)
+#define V3_LB_BASE_ENABLE		(1 << 0)
+
+#define V3_LB_BASE_ADR_SIZE_1MB		(0 << 4)
+#define V3_LB_BASE_ADR_SIZE_2MB		(1 << 4)
+#define V3_LB_BASE_ADR_SIZE_4MB		(2 << 4)
+#define V3_LB_BASE_ADR_SIZE_8MB		(3 << 4)
+#define V3_LB_BASE_ADR_SIZE_16MB	(4 << 4)
+#define V3_LB_BASE_ADR_SIZE_32MB	(5 << 4)
+#define V3_LB_BASE_ADR_SIZE_64MB	(6 << 4)
+#define V3_LB_BASE_ADR_SIZE_128MB	(7 << 4)
+#define V3_LB_BASE_ADR_SIZE_256MB	(8 << 4)
+#define V3_LB_BASE_ADR_SIZE_512MB	(9 << 4)
+#define V3_LB_BASE_ADR_SIZE_1GB		(10 << 4)
+#define V3_LB_BASE_ADR_SIZE_2GB		(11 << 4)
+
+#define v3_addr_to_lb_base(a)	((a) & V3_LB_BASE_ADR_BASE)
+
+/*
+ *  LB_MAP0,1 register bits (Local bus -> PCI)
+ */
+#define V3_LB_MAP_MAP_ADR		0xfff0
+#define V3_LB_MAP_TYPE			(7 << 1)
+#define V3_LB_MAP_AD_LOW_EN		(1 << 0)
+
+#define V3_LB_MAP_TYPE_IACK		(0 << 1)
+#define V3_LB_MAP_TYPE_IO		(1 << 1)
+#define V3_LB_MAP_TYPE_MEM		(3 << 1)
+#define V3_LB_MAP_TYPE_CONFIG		(5 << 1)
+#define V3_LB_MAP_TYPE_MEM_MULTIPLE	(6 << 1)
+
+#define v3_addr_to_lb_map(a)	(((a) >> 16) & V3_LB_MAP_MAP_ADR)
+
+/*
+ *  LB_BASE2 register bits (Local bus -> PCI IO)
+ */
+#define V3_LB_BASE2_ADR_BASE		0xff00
+#define V3_LB_BASE2_SWAP		(3 << 6)
+#define V3_LB_BASE2_ENABLE		(1 << 0)
+
+#define v3_addr_to_lb_base2(a)	(((a) >> 16) & V3_LB_BASE2_ADR_BASE)
+
+/*
+ *  LB_MAP2 register bits (Local bus -> PCI IO)
+ */
+#define V3_LB_MAP2_MAP_ADR		0xff00
+
+#define v3_addr_to_lb_map2(a)	(((a) >> 16) & V3_LB_MAP2_MAP_ADR)
 
 /*
  * The V3 PCI interface chip in Integrator provides several windows from
@@ -101,15 +284,28 @@
  * the mappings into PCI memory.
  */
 
+/* Filled in by probe */
+static void __iomem *pci_v3_base;
+/* CPU side memory ranges */
+static struct resource conf_mem; /* FIXME: remap this instead of static map */
+static struct resource io_mem;
+static struct resource non_mem;
+static struct resource pre_mem;
+/* PCI side memory ranges */
+static u64 non_mem_pci;
+static u64 non_mem_pci_sz;
+static u64 pre_mem_pci;
+static u64 pre_mem_pci_sz;
+
 // V3 access routines
-#define v3_writeb(o,v) __raw_writeb(v, PCI_V3_VADDR + (unsigned int)(o))
-#define v3_readb(o)    (__raw_readb(PCI_V3_VADDR + (unsigned int)(o)))
+#define v3_writeb(o,v) __raw_writeb(v, pci_v3_base + (unsigned int)(o))
+#define v3_readb(o)    (__raw_readb(pci_v3_base + (unsigned int)(o)))
 
-#define v3_writew(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o))
-#define v3_readw(o)    (__raw_readw(PCI_V3_VADDR + (unsigned int)(o)))
+#define v3_writew(o,v) __raw_writew(v, pci_v3_base + (unsigned int)(o))
+#define v3_readw(o)    (__raw_readw(pci_v3_base + (unsigned int)(o)))
 
-#define v3_writel(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o))
-#define v3_readl(o)    (__raw_readl(PCI_V3_VADDR + (unsigned int)(o)))
+#define v3_writel(o,v) __raw_writel(v, pci_v3_base + (unsigned int)(o))
+#define v3_readl(o)    (__raw_readl(pci_v3_base + (unsigned int)(o)))
 
 /*============================================================================
  *
@@ -165,19 +361,6 @@
  */
 static DEFINE_RAW_SPINLOCK(v3_lock);
 
-#define PCI_BUS_NONMEM_START	0x00000000
-#define PCI_BUS_NONMEM_SIZE	SZ_256M
-
-#define PCI_BUS_PREMEM_START	PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE
-#define PCI_BUS_PREMEM_SIZE	SZ_256M
-
-#if PCI_BUS_NONMEM_START & 0x000fffff
-#error PCI_BUS_NONMEM_START must be megabyte aligned
-#endif
-#if PCI_BUS_PREMEM_START & 0x000fffff
-#error PCI_BUS_PREMEM_START must be megabyte aligned
-#endif
-
 #undef V3_LB_BASE_PREFETCH
 #define V3_LB_BASE_PREFETCH 0
 
@@ -243,13 +426,13 @@ static void __iomem *v3_open_config_wind
 	 * prefetchable), this frees up base1 for re-use by
 	 * configuration memory
 	 */
-	v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+	v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(non_mem.start) |
 			V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE);
 
 	/*
 	 * Set up base1/map1 to point into configuration space.
 	 */
-	v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_CONFIG_BASE) |
+	v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(conf_mem.start) |
 			V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE);
 	v3_writew(V3_LB_MAP1, mapaddress);
 
@@ -261,16 +444,16 @@ static void v3_close_config_window(void)
 	/*
 	 * Reassign base1 for use by prefetchable PCI memory
 	 */
-	v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+	v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(pre_mem.start) |
 			V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
 			V3_LB_BASE_ENABLE);
-	v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+	v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(pre_mem_pci) |
 			V3_LB_MAP_TYPE_MEM_MULTIPLE);
 
 	/*
 	 * And shrink base0 back to a 256M window (NOTE: MAP0 already correct)
 	 */
-	v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+	v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(non_mem.start) |
 			V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
 }
 
@@ -337,25 +520,11 @@ static int v3_write_config(struct pci_bu
 	return PCIBIOS_SUCCESSFUL;
 }
 
-struct pci_ops pci_v3_ops = {
+static struct pci_ops pci_v3_ops = {
 	.read	= v3_read_config,
 	.write	= v3_write_config,
 };
 
-static struct resource non_mem = {
-	.name	= "PCI non-prefetchable",
-	.start	= PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START,
-	.end	= PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct resource pre_mem = {
-	.name	= "PCI prefetchable",
-	.start	= PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START,
-	.end	= PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
-	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
-};
-
 static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
 {
 	if (request_resource(&iomem_resource, &non_mem)) {
@@ -471,7 +640,7 @@ static irqreturn_t v3_irq(int dummy, voi
 	return IRQ_HANDLED;
 }
 
-int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
+static int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
 {
 	int ret = 0;
 
@@ -479,7 +648,7 @@ int __init pci_v3_setup(int nr, struct p
 		return -EINVAL;
 
 	if (nr == 0) {
-		sys->mem_offset = PHYS_PCI_MEM_BASE;
+		sys->mem_offset = non_mem.start;
 		ret = pci_v3_setup_resources(sys);
 	}
 
@@ -490,18 +659,10 @@ int __init pci_v3_setup(int nr, struct p
  * V3_LB_BASE? - local bus address
  * V3_LB_MAP?  - pci bus address
  */
-void __init pci_v3_preinit(void)
+static void __init pci_v3_preinit(void)
 {
 	unsigned long flags;
 	unsigned int temp;
-	int ret;
-
-	/* Remap the Integrator system controller */
-	ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
-	if (!ap_syscon_base) {
-		pr_err("unable to remap the AP syscon for PCIv3\n");
-		return;
-	}
 
 	pcibios_min_mem = 0x00100000;
 
@@ -525,25 +686,25 @@ void __init pci_v3_preinit(void)
 	 * Setup window 0 - PCI non-prefetchable memory
 	 *  Local: 0x40000000 Bus: 0x00000000 Size: 256MB
 	 */
-	v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+	v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(non_mem.start) |
 			V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
-	v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(PCI_BUS_NONMEM_START) |
+	v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(non_mem_pci) |
 			V3_LB_MAP_TYPE_MEM);
 
 	/*
 	 * Setup window 1 - PCI prefetchable memory
 	 *  Local: 0x50000000 Bus: 0x10000000 Size: 256MB
 	 */
-	v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+	v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(pre_mem.start) |
 			V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
 			V3_LB_BASE_ENABLE);
-	v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+	v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(pre_mem_pci) |
 			V3_LB_MAP_TYPE_MEM_MULTIPLE);
 
 	/*
 	 * Setup window 2 - PCI IO
 	 */
-	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(PHYS_PCI_IO_BASE) |
+	v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) |
 			V3_LB_BASE_ENABLE);
 	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
 
@@ -578,18 +739,10 @@ void __init pci_v3_preinit(void)
 	v3_writeb(V3_LB_IMASK, 0x28);
 	__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
 
-	/*
-	 * Grab the PCI error interrupt.
-	 */
-	ret = request_irq(IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
-	if (ret)
-		printk(KERN_ERR "PCI: unable to grab PCI error "
-		       "interrupt: %d\n", ret);
-
 	raw_spin_unlock_irqrestore(&v3_lock, flags);
 }
 
-void __init pci_v3_postinit(void)
+static void __init pci_v3_postinit(void)
 {
 	unsigned int pci_cmd;
 
@@ -608,5 +761,284 @@ void __init pci_v3_postinit(void)
 		       "interrupt: %d\n", ret);
 #endif
 
-	register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
+	register_isa_ports(non_mem.start, io_mem.start, 0);
+}
+
+/*
+ * A small note about bridges and interrupts.  The DECchip 21050 (and
+ * later) adheres to the PCI-PCI bridge specification.  This says that
+ * the interrupts on the other side of a bridge are swizzled in the
+ * following manner:
+ *
+ * Dev    Interrupt   Interrupt
+ *        Pin on      Pin on
+ *        Device      Connector
+ *
+ *   4    A           A
+ *        B           B
+ *        C           C
+ *        D           D
+ *
+ *   5    A           B
+ *        B           C
+ *        C           D
+ *        D           A
+ *
+ *   6    A           C
+ *        B           D
+ *        C           A
+ *        D           B
+ *
+ *   7    A           D
+ *        B           A
+ *        C           B
+ *        D           C
+ *
+ * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
+ * Thus, each swizzle is ((pin-1) + (device#-4)) % 4
+ */
+
+/*
+ * This routine handles multiple bridges.
+ */
+static u8 __init pci_v3_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	if (*pinp == 0)
+		*pinp = 1;
+
+	return pci_common_swizzle(dev, pinp);
+}
+
+static int irq_tab[4] __initdata = {
+	IRQ_AP_PCIINT0,	IRQ_AP_PCIINT1,	IRQ_AP_PCIINT2,	IRQ_AP_PCIINT3
+};
+
+/*
+ * map the specified device/slot/pin to an IRQ.  This works out such
+ * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
+ */
+static int __init pci_v3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int intnr = ((slot - 9) + (pin - 1)) & 3;
+
+	return irq_tab[intnr];
+}
+
+static struct hw_pci pci_v3 __initdata = {
+	.swizzle		= pci_v3_swizzle,
+	.setup			= pci_v3_setup,
+	.nr_controllers		= 1,
+	.ops			= &pci_v3_ops,
+	.preinit		= pci_v3_preinit,
+	.postinit		= pci_v3_postinit,
+};
+
+#ifdef CONFIG_OF
+
+static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct of_irq oirq;
+	int ret;
+
+	ret = of_irq_map_pci(dev, &oirq);
+	if (ret) {
+		dev_err(&dev->dev, "of_irq_map_pci() %d\n", ret);
+		/* Proper return code 0 == NO_IRQ */
+		return 0;
+	}
+
+	return irq_create_of_mapping(oirq.controller, oirq.specifier,
+				     oirq.size);
+}
+
+static int __init pci_v3_dtprobe(struct platform_device *pdev,
+				struct device_node *np)
+{
+	struct of_pci_range_parser parser;
+	struct of_pci_range range;
+	struct resource *res;
+	int irq, ret;
+
+	if (of_pci_range_parser_init(&parser, np))
+		return -EINVAL;
+
+	/* Get base for bridge registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "unable to obtain PCIv3 base\n");
+		return -ENODEV;
+	}
+	pci_v3_base = devm_ioremap(&pdev->dev, res->start,
+				   resource_size(res));
+	if (!pci_v3_base) {
+		dev_err(&pdev->dev, "unable to remap PCIv3 base\n");
+		return -ENODEV;
+	}
+
+	/* Get and request error IRQ resource */
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0) {
+		dev_err(&pdev->dev, "unable to obtain PCIv3 error IRQ\n");
+		return -ENODEV;
+	}
+	ret = devm_request_irq(&pdev->dev, irq, v3_irq, 0,
+			"PCIv3 error", NULL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "unable to request PCIv3 error IRQ %d (%d)\n", irq, ret);
+		return ret;
+	}
+
+	for_each_of_pci_range(&parser, &range) {
+		if (!range.flags) {
+			of_pci_range_to_resource(&range, np, &conf_mem);
+			conf_mem.name = "PCIv3 config";
+		}
+		if (range.flags & IORESOURCE_IO) {
+			of_pci_range_to_resource(&range, np, &io_mem);
+			io_mem.name = "PCIv3 I/O";
+		}
+		if ((range.flags & IORESOURCE_MEM) &&
+			!(range.flags & IORESOURCE_PREFETCH)) {
+			non_mem_pci = range.pci_addr;
+			non_mem_pci_sz = range.size;
+			of_pci_range_to_resource(&range, np, &non_mem);
+			non_mem.name = "PCIv3 non-prefetched mem";
+		}
+		if ((range.flags & IORESOURCE_MEM) &&
+			(range.flags & IORESOURCE_PREFETCH)) {
+			pre_mem_pci = range.pci_addr;
+			pre_mem_pci_sz = range.size;
+			of_pci_range_to_resource(&range, np, &pre_mem);
+			pre_mem.name = "PCIv3 prefetched mem";
+		}
+	}
+
+	if (!conf_mem.start || !io_mem.start ||
+	    !non_mem.start || !pre_mem.start) {
+		dev_err(&pdev->dev, "missing ranges in device node\n");
+		return -EINVAL;
+	}
+
+	pci_v3.map_irq = pci_v3_map_irq_dt;
+	pci_common_init_dev(&pdev->dev, &pci_v3);
+
+	return 0;
+}
+
+#else
+
+static inline int pci_v3_dtprobe(struct platform_device *pdev,
+				  struct device_node *np)
+{
+	return -EINVAL;
+}
+
+#endif
+
+static int __init pci_v3_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	/* Remap the Integrator system controller */
+	ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
+	if (!ap_syscon_base) {
+		dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n");
+		return -ENODEV;
+	}
+
+	/* Device tree probe path */
+	if (np)
+		return pci_v3_dtprobe(pdev, np);
+
+	pci_v3_base = devm_ioremap(&pdev->dev, PHYS_PCI_V3_BASE, SZ_64K);
+	if (!pci_v3_base) {
+		dev_err(&pdev->dev, "unable to remap PCIv3 base\n");
+		return -ENODEV;
+	}
+
+	ret = devm_request_irq(&pdev->dev, IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to grab PCI error interrupt: %d\n",
+			ret);
+		return -ENODEV;
+	}
+
+	conf_mem.name = "PCIv3 config";
+	conf_mem.start = PHYS_PCI_CONFIG_BASE;
+	conf_mem.end = PHYS_PCI_CONFIG_BASE + SZ_16M - 1;
+	conf_mem.flags = IORESOURCE_MEM;
+
+	io_mem.name = "PCIv3 I/O";
+	io_mem.start = PHYS_PCI_IO_BASE;
+	io_mem.end = PHYS_PCI_IO_BASE + SZ_16M - 1;
+	io_mem.flags = IORESOURCE_MEM;
+
+	non_mem_pci = 0x00000000;
+	non_mem_pci_sz = SZ_256M;
+	non_mem.name = "PCIv3 non-prefetched mem";
+	non_mem.start = PHYS_PCI_MEM_BASE;
+	non_mem.end = PHYS_PCI_MEM_BASE + SZ_256M - 1;
+	non_mem.flags = IORESOURCE_MEM;
+
+	pre_mem_pci = 0x10000000;
+	pre_mem_pci_sz = SZ_256M;
+	pre_mem.name = "PCIv3 prefetched mem";
+	pre_mem.start = PHYS_PCI_PRE_BASE + SZ_256M;
+	pre_mem.end = PHYS_PCI_PRE_BASE + SZ_256M - 1;
+	pre_mem.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+
+	pci_v3.map_irq = pci_v3_map_irq;
+
+	pci_common_init_dev(&pdev->dev, &pci_v3);
+
+	return 0;
+}
+
+static const struct of_device_id pci_ids[] = {
+	{ .compatible = "v3,v360epc-pci", },
+	{},
+};
+
+static struct platform_driver pci_v3_driver = {
+	.driver = {
+		.name = "pci-v3",
+		.of_match_table = pci_ids,
+	},
+};
+
+static int __init pci_v3_init(void)
+{
+	return platform_driver_probe(&pci_v3_driver, pci_v3_probe);
+}
+
+subsys_initcall(pci_v3_init);
+
+/*
+ * Static mappings for the PCIv3 bridge
+ *
+ * e8000000	40000000	PCI memory		PHYS_PCI_MEM_BASE	(max 512M)
+ * ec000000	61000000	PCI config space	PHYS_PCI_CONFIG_BASE	(max 16M)
+ * fee00000	60000000	PCI IO			PHYS_PCI_IO_BASE	(max 16M)
+ */
+static struct map_desc pci_v3_io_desc[] __initdata __maybe_unused = {
+	{
+		.virtual	= (unsigned long)PCI_MEMORY_VADDR,
+		.pfn		= __phys_to_pfn(PHYS_PCI_MEM_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= (unsigned long)PCI_CONFIG_VADDR,
+		.pfn		= __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE
+	}
+};
+
+int __init pci_v3_early_init(void)
+{
+	iotable_init(pci_v3_io_desc, ARRAY_SIZE(pci_v3_io_desc));
+	vga_base = (unsigned long)PCI_MEMORY_VADDR;
+	pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
+	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-integrator/pci_v3.h linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/pci_v3.h
--- linux-libre-3.10-gnu/arch/arm/mach-integrator/pci_v3.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-integrator/pci_v3.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2 @@
+/* Simple oneliner include to the PCIv3 early init */
+extern int pci_v3_early_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-iop13xx/include/mach/iop13xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-iop13xx/include/mach/iop13xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-iop13xx/include/mach/iop13xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-iop13xx/include/mach/iop13xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -2,6 +2,9 @@
 #define _IOP13XX_HW_H_
 
 #ifndef __ASSEMBLY__
+
+#include <linux/reboot.h>
+
 /* The ATU offsets can change based on the strapping */
 extern u32 iop13xx_atux_pmmr_offset;
 extern u32 iop13xx_atue_pmmr_offset;
@@ -11,7 +14,7 @@ void iop13xx_map_io(void);
 void iop13xx_platform_init(void);
 void iop13xx_add_tpmi_devices(void);
 void iop13xx_init_irq(void);
-void iop13xx_restart(char, const char *);
+void iop13xx_restart(enum reboot_mode, const char *);
 
 /* CPUID CP6 R0 Page 0 */
 static inline int iop13xx_cpu_id(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-iop13xx/io.c linux-libre-3.11-rc7-gnu/arch/arm/mach-iop13xx/io.c
--- linux-libre-3.10-gnu/arch/arm/mach-iop13xx/io.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-iop13xx/io.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,7 @@
 
 #include "pci.h"
 
-static void __iomem *__iop13xx_ioremap_caller(unsigned long cookie,
+static void __iomem *__iop13xx_ioremap_caller(phys_addr_t cookie,
 	size_t size, unsigned int mtype, void *caller)
 {
 	void __iomem * retval;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-iop13xx/setup.c linux-libre-3.11-rc7-gnu/arch/arm/mach-iop13xx/setup.c
--- linux-libre-3.10-gnu/arch/arm/mach-iop13xx/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-iop13xx/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -469,7 +469,6 @@ void __init iop13xx_platform_init(void)
 			dma_cap_set(DMA_MEMCPY, plat_data->cap_mask);
 			dma_cap_set(DMA_XOR, plat_data->cap_mask);
 			dma_cap_set(DMA_XOR_VAL, plat_data->cap_mask);
-			dma_cap_set(DMA_MEMSET, plat_data->cap_mask);
 			dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask);
 			break;
 		case IOP13XX_INIT_ADMA_1:
@@ -479,7 +478,6 @@ void __init iop13xx_platform_init(void)
 			dma_cap_set(DMA_MEMCPY, plat_data->cap_mask);
 			dma_cap_set(DMA_XOR, plat_data->cap_mask);
 			dma_cap_set(DMA_XOR_VAL, plat_data->cap_mask);
-			dma_cap_set(DMA_MEMSET, plat_data->cap_mask);
 			dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask);
 			break;
 		case IOP13XX_INIT_ADMA_2:
@@ -489,7 +487,6 @@ void __init iop13xx_platform_init(void)
 			dma_cap_set(DMA_MEMCPY, plat_data->cap_mask);
 			dma_cap_set(DMA_XOR, plat_data->cap_mask);
 			dma_cap_set(DMA_XOR_VAL, plat_data->cap_mask);
-			dma_cap_set(DMA_MEMSET, plat_data->cap_mask);
 			dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask);
 			dma_cap_set(DMA_PQ, plat_data->cap_mask);
 			dma_cap_set(DMA_PQ_VAL, plat_data->cap_mask);
@@ -597,7 +594,7 @@ __setup("iop13xx_init_adma", iop13xx_ini
 __setup("iop13xx_init_uart", iop13xx_init_uart_setup);
 __setup("iop13xx_init_i2c", iop13xx_init_i2c_setup);
 
-void iop13xx_restart(char mode, const char *cmd)
+void iop13xx_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * Reset the internal bus (warning both cores are reset)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-iop32x/n2100.c linux-libre-3.11-rc7-gnu/arch/arm/mach-iop32x/n2100.c
--- linux-libre-3.10-gnu/arch/arm/mach-iop32x/n2100.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-iop32x/n2100.c	2013-08-25 20:43:22.000000000 -0400
@@ -286,7 +286,7 @@ static void n2100_power_off(void)
 		;
 }
 
-static void n2100_restart(char mode, const char *cmd)
+static void n2100_restart(enum reboot_mode mode, const char *cmd)
 {
 	gpio_line_set(N2100_HARDWARE_RESET, GPIO_LOW);
 	gpio_line_config(N2100_HARDWARE_RESET, GPIO_OUT);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/export.h>
 #include <linux/gpio.h>
 #include <linux/cpu.h>
+#include <linux/sched_clock.h>
 
 #include <mach/udc.h>
 #include <mach/hardware.h>
@@ -38,7 +39,6 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/irq.h>
-#include <asm/sched_clock.h>
 #include <asm/system_misc.h>
 
 #include <asm/mach/map.h>
@@ -531,9 +531,9 @@ static void __init ixp4xx_clockevent_ini
 					0xf, 0xfffffffe);
 }
 
-void ixp4xx_restart(char mode, const char *cmd)
+void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
 {
-	if ( 1 && mode == 's') {
+	if ( 1 && mode == REBOOT_SOFT) {
 		/* Jump into ROM at address 0 */
 		soft_restart(0);
 	} else {
@@ -559,7 +559,7 @@ void ixp4xx_restart(char mode, const cha
  * fallback to the default.
  */
 
-static void __iomem *ixp4xx_ioremap_caller(unsigned long addr, size_t size,
+static void __iomem *ixp4xx_ioremap_caller(phys_addr_t addr, size_t size,
 					   unsigned int mtype, void *caller)
 {
 	if (!is_pci_memory(addr))
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/dsmg600-setup.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/dsmg600-setup.c
--- linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/dsmg600-setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/dsmg600-setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,8 @@
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 
+#include <mach/hardware.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/include/mach/platform.h linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/include/mach/platform.h
--- linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/include/mach/platform.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/include/mach/platform.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/reboot.h>
+
 #include <asm/types.h>
 
 #ifndef	__ARMEB__
@@ -123,7 +125,7 @@ extern void ixp4xx_init_early(void);
 extern void ixp4xx_init_irq(void);
 extern void ixp4xx_sys_init(void);
 extern void ixp4xx_timer_init(void);
-extern void ixp4xx_restart(char, const char *);
+extern void ixp4xx_restart(enum reboot_mode, const char *);
 extern void ixp4xx_pci_preinit(void);
 struct pci_sys_data;
 extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/include/mach/timex.h linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/include/mach/timex.h
--- linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/include/mach/timex.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/include/mach/timex.h	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  * 
  */
 
-#include <mach/hardware.h>
+#include <mach/ixp4xx-regs.h>
 
 /*
  * We use IXP425 General purpose timer for our timer needs, it runs at 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -235,7 +235,6 @@ config IXP4XX_QMGR
 config IXP4XX_NPE
 	tristate "IXP4xx Network Processor Engine support"
 	select FW_LOADER
-	select HOTPLUG
 	help
 	  This driver supports IXP4xx built-in network coprocessors
 	  and is automatically selected by Ethernet and HSS drivers.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/omixp-setup.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/omixp-setup.c
--- linux-libre-3.10-gnu/arch/arm/mach-ixp4xx/omixp-setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ixp4xx/omixp-setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include <mach/hardware.h>
+
 static struct resource omixp_flash_resources[] = {
 	{
 		.flags	= IORESOURCE_MEM,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-keystone/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-keystone/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,15 @@
+config ARCH_KEYSTONE
+	bool "Texas Instruments Keystone Devices"
+	depends on ARCH_MULTI_V7
+	select CPU_V7
+	select ARM_GIC
+	select HAVE_ARM_ARCH_TIMER
+	select HAVE_SMP
+	select CLKSRC_MMIO
+	select GENERIC_CLOCKEVENTS
+	select HAVE_SCHED_CLOCK
+	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select ARM_ERRATA_798181 if SMP
+	help
+	  Support for boards based on the Texas Instruments Keystone family of
+	  SoCs.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-keystone/keystone.c linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/keystone.c
--- linux-libre-3.10-gnu/arch/arm/mach-keystone/keystone.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/keystone.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,75 @@
+/*
+ * Keystone2 based boards and SOC related code.
+ *
+ * Copyright 2013 Texas Instruments, Inc.
+ *	Cyril Chemparathy <cyril@ti.com>
+ *	Santosh Shilimkar <santosh.shillimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+
+#include <asm/setup.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/smp_plat.h>
+
+#include "keystone.h"
+
+#define PLL_RESET_WRITE_KEY_MASK		0xffff0000
+#define PLL_RESET_WRITE_KEY			0x5a69
+#define PLL_RESET				BIT(16)
+
+static void __iomem *keystone_rstctrl;
+
+static void __init keystone_init(void)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "ti,keystone-reset");
+	if (WARN_ON(!node))
+		pr_warn("ti,keystone-reset node undefined\n");
+
+	keystone_rstctrl = of_iomap(node, 0);
+	if (WARN_ON(!keystone_rstctrl))
+		pr_warn("ti,keystone-reset iomap error\n");
+
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *keystone_match[] __initconst = {
+	"ti,keystone-evm",
+	NULL,
+};
+
+void keystone_restart(enum reboot_mode mode, const char *cmd)
+{
+	u32 val;
+
+	BUG_ON(!keystone_rstctrl);
+
+	/* Enable write access to RSTCTRL */
+	val = readl(keystone_rstctrl);
+	val &= PLL_RESET_WRITE_KEY_MASK;
+	val |= PLL_RESET_WRITE_KEY;
+	writel(val, keystone_rstctrl);
+
+	/* Reset the SOC */
+	val = readl(keystone_rstctrl);
+	val &= ~PLL_RESET;
+	writel(val, keystone_rstctrl);
+}
+
+DT_MACHINE_START(KEYSTONE, "Keystone")
+	.smp		= smp_ops(keystone_smp_ops),
+	.init_machine	= keystone_init,
+	.dt_compat	= keystone_match,
+	.restart	= keystone_restart,
+MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-keystone/keystone.h linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/keystone.h
--- linux-libre-3.10-gnu/arch/arm/mach-keystone/keystone.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/keystone.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Texas Instruments, Inc.
+ *	Cyril Chemparathy <cyril@ti.com>
+ *	Santosh Shilimkar <santosh.shillimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef __KEYSTONE_H__
+#define __KEYSTONE_H__
+
+#define KEYSTONE_MON_CPU_UP_IDX		0x00
+
+#ifndef __ASSEMBLER__
+
+extern struct smp_operations keystone_smp_ops;
+extern void secondary_startup(void);
+extern u32 keystone_cpu_smc(u32 command, u32 cpu, u32 addr);
+
+#endif /* __ASSEMBLER__ */
+#endif /* __KEYSTONE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-keystone/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-keystone/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,6 @@
+obj-y					:= keystone.o smc.o
+
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_smc.o				:=-Wa,-march=armv7-a$(plus_sec)
+
+obj-$(CONFIG_SMP)			+= platsmp.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-keystone/Makefile.boot linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/Makefile.boot
--- linux-libre-3.10-gnu/arch/arm/mach-keystone/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/Makefile.boot	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+zreladdr-y	:= 0x80008000
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-keystone/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-keystone/platsmp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ * Keystone SOC SMP platform code
+ *
+ * Copyright 2013 Texas Instruments, Inc.
+ *	Cyril Chemparathy <cyril@ti.com>
+ *	Santosh Shilimkar <santosh.shillimkar@ti.com>
+ *
+ * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/smp_plat.h>
+#include <asm/prom.h>
+
+#include "keystone.h"
+
+static int keystone_smp_boot_secondary(unsigned int cpu,
+						struct task_struct *idle)
+{
+	unsigned long start = virt_to_phys(&secondary_startup);
+	int error;
+
+	pr_debug("keystone-smp: booting cpu %d, vector %08lx\n",
+		 cpu, start);
+
+	error = keystone_cpu_smc(KEYSTONE_MON_CPU_UP_IDX, cpu, start);
+	if (error)
+		pr_err("CPU %d bringup failed with %d\n", cpu, error);
+
+	return error;
+}
+
+struct smp_operations keystone_smp_ops __initdata = {
+	.smp_init_cpus		= arm_dt_init_cpu_maps,
+	.smp_boot_secondary	= keystone_smp_boot_secondary,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-keystone/smc.S linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/smc.S
--- linux-libre-3.10-gnu/arch/arm/mach-keystone/smc.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-keystone/smc.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,29 @@
+/*
+ * Keystone Secure APIs
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ * 	Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software,you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+/**
+ * u32 keystone_cpu_smc(u32 command, u32 cpu, u32 addr)
+ *
+ * Low level CPU monitor API
+ * @command:	Monitor command.
+ * @cpu:	CPU Number
+ * @addr:	Kernel jump address for boot CPU
+ *
+ * Return: Non zero value on failure
+ */
+ENTRY(keystone_cpu_smc)
+	stmfd   sp!, {r4-r12, lr}
+	smc	#0
+	dsb
+	ldmfd   sp!, {r4-r12, pc}
+ENDPROC(keystone_cpu_smc)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-db88f628x-bp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-db88f628x-bp.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-db88f628x-bp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-db88f628x-bp.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * Saeed Bishara <saeed@marvell.com>
+ *
+ * Marvell DB-88F628{1,2}-BP Development Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/mv643xx_eth.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data db88f628x_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+void __init db88f628x_init(void)
+{
+	kirkwood_ge00_init(&db88f628x_ge00_data);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-dt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/clk-provider.h>
-#include <linux/clk/mvebu.h>
 #include <linux/kexec.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -25,11 +24,6 @@
 #include <plat/common.h>
 #include "common.h"
 
-static struct of_device_id kirkwood_dt_match_table[] __initdata = {
-	{ .compatible = "simple-bus", },
-	{ }
-};
-
 /*
  * There are still devices that doesn't know about DT yet.  Get clock
  * gates here and add a clock lookup alias, so that old platform
@@ -77,7 +71,7 @@ static void __init kirkwood_legacy_clk_i
 
 static void __init kirkwood_of_clk_init(void)
 {
-	mvebu_clocks_init();
+	of_clk_init(NULL);
 	kirkwood_legacy_clk_init();
 }
 
@@ -97,6 +91,8 @@ static void __init kirkwood_dt_init(void
 
 	kirkwood_l2_init();
 
+	kirkwood_cpufreq_init();
+
 	/* Setup root of clk tree */
 	kirkwood_of_clk_init();
 
@@ -112,6 +108,9 @@ static void __init kirkwood_dt_init(void
 	if (of_machine_is_compatible("globalscale,guruplug"))
 		guruplug_dt_init();
 
+	if (of_machine_is_compatible("globalscale,sheevaplug"))
+		sheevaplug_dt_init();
+
 	if (of_machine_is_compatible("dlink,dns-kirkwood"))
 		dnskw_init();
 
@@ -147,6 +146,10 @@ static void __init kirkwood_dt_init(void
 	    of_machine_is_compatible("lacie,netspace_v2"))
 		ns2_init();
 
+	if (of_machine_is_compatible("marvell,db-88f6281-bp") ||
+	    of_machine_is_compatible("marvell,db-88f6282-bp"))
+		db88f628x_init();
+
 	if (of_machine_is_compatible("mpl,cec4"))
 		mplcec4_init();
 
@@ -159,12 +162,13 @@ static void __init kirkwood_dt_init(void
 	if (of_machine_is_compatible("usi,topkick"))
 		usi_topkick_init();
 
-	of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL);
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static const char * const kirkwood_dt_board_compat[] = {
 	"globalscale,dreamplug",
 	"globalscale,guruplug",
+	"globalscale,sheevaplug",
 	"dlink,dns-320",
 	"dlink,dns-325",
 	"iom,iconnect",
@@ -181,6 +185,8 @@ static const char * const kirkwood_dt_bo
 	"lacie,netspace_max_v2",
 	"lacie,netspace_mini_v2",
 	"lacie,netspace_v2",
+	"marvell,db-88f6281-bp",
+	"marvell,db-88f6282-bp",
 	"mpl,cec4",
 	"netgear,readynas-duo-v2",
 	"plathome,openblocks-a6",
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-iconnect.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-iconnect.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-iconnect.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-iconnect.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,11 +22,3 @@ void __init iconnect_init(void)
 {
 	kirkwood_ge00_init(&iconnect_ge00_data);
 }
-
-static int __init iconnect_pci_init(void)
-{
-	if (of_machine_is_compatible("iom,iconnect"))
-		kirkwood_pcie_init(KW_PCIE0);
-	return 0;
-}
-subsys_initcall(iconnect_pci_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-lsxl.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-lsxl.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-lsxl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-lsxl.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,19 +25,6 @@ static struct mv643xx_eth_platform_data
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
 };
 
-/*
- * On the LS-XHL/LS-CHLv2, the shutdown process is following:
- * - Userland monitors key events until the power switch goes to off position
- * - The board reboots
- * - U-boot starts and goes into an idle mode waiting for the user
- *   to move the switch to ON position
- *
- */
-static void lsxl_power_off(void)
-{
-	kirkwood_restart('h', NULL);
-}
-
 void __init lsxl_init(void)
 {
 	/*
@@ -46,7 +33,4 @@ void __init lsxl_init(void)
 
 	kirkwood_ge00_init(&lsxl_ge00_data);
 	kirkwood_ge01_init(&lsxl_ge01_data);
-
-	/* register power-off method */
-	pm_power_off = lsxl_power_off;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-mplcec4.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-mplcec4.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-mplcec4.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-mplcec4.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@ void __init mplcec4_init(void)
 	 */
 	kirkwood_ge00_init(&mplcec4_ge00_data);
 	kirkwood_ge01_init(&mplcec4_ge01_data);
-	kirkwood_pcie_init(KW_PCIE0);
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-nsa310.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-nsa310.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-nsa310.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-nsa310.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/nsa-310-setup.c
- *
- * ZyXEL NSA-310 Setup
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <mach/kirkwood.h>
-#include <linux/of.h>
-#include "common.h"
-
-static int __init nsa310_pci_init(void)
-{
-	if (of_machine_is_compatible("zyxel,nsa310"))
-		kirkwood_pcie_init(KW_PCIE0);
-
-	return 0;
-}
-
-subsys_initcall(nsa310_pci_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-readynas.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-readynas.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-readynas.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-readynas.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,5 +24,4 @@ static struct mv643xx_eth_platform_data
 void __init netgear_readynas_init(void)
 {
 	kirkwood_ge00_init(&netgear_readynas_ge00_data);
-	kirkwood_pcie_init(KW_PCIE0);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-sheevaplug.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-sheevaplug.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-sheevaplug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-sheevaplug.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-kirkwood/board-sheevaplug.c
+ *
+ * Marvell Sheevaplug Reference Board Init for drivers not converted to
+ * flattened device tree yet.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mv643xx_eth.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data sheevaplug_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
+};
+
+void __init sheevaplug_dt_init(void)
+{
+	/*
+	 * Basic setup. Needs to be called early.
+	 */
+	kirkwood_ge00_init(&sheevaplug_ge00_data);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-ts219.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-ts219.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/board-ts219.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/board-ts219.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,6 @@
 #include <asm/mach/arch.h>
 #include <mach/kirkwood.h>
 #include "common.h"
-#include "tsx1x-common.h"
 
 static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
@@ -38,6 +37,4 @@ void __init qnap_dt_ts219_init(void)
 		qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
 
 	kirkwood_ge00_init(&qnap_ts219_ge00_data);
-
-	pm_power_off = qnap_tsx1x_power_off;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/mv643xx_i2c.h>
 #include <linux/timex.h>
 #include <linux/kexec.h>
+#include <linux/reboot.h>
 #include <net/dsa.h>
 #include <asm/page.h>
 #include <asm/mach/map.h>
@@ -598,6 +599,29 @@ void __init kirkwood_audio_init(void)
 }
 
 /*****************************************************************************
+ * CPU Frequency
+ ****************************************************************************/
+static struct resource kirkwood_cpufreq_resources[] = {
+	[0] = {
+		.start  = CPU_CONTROL_PHYS,
+		.end    = CPU_CONTROL_PHYS + 3,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device kirkwood_cpufreq_device = {
+	.name		= "kirkwood-cpufreq",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(kirkwood_cpufreq_resources),
+	.resource	= kirkwood_cpufreq_resources,
+};
+
+void __init kirkwood_cpufreq_init(void)
+{
+	platform_device_register(&kirkwood_cpufreq_device);
+}
+
+/*****************************************************************************
  * General
  ****************************************************************************/
 /*
@@ -648,30 +672,6 @@ char * __init kirkwood_id(void)
 
 void __init kirkwood_setup_wins(void)
 {
-	/*
-	 * The PCIe windows will no longer be statically allocated
-	 * here once Kirkwood is migrated to the pci-mvebu driver.
-	 */
-	mvebu_mbus_add_window_remap_flags("pcie0.0",
-					  KIRKWOOD_PCIE_IO_PHYS_BASE,
-					  KIRKWOOD_PCIE_IO_SIZE,
-					  KIRKWOOD_PCIE_IO_BUS_BASE,
-					  MVEBU_MBUS_PCI_IO);
-	mvebu_mbus_add_window_remap_flags("pcie0.0",
-					  KIRKWOOD_PCIE_MEM_PHYS_BASE,
-					  KIRKWOOD_PCIE_MEM_SIZE,
-					  MVEBU_MBUS_NO_REMAP,
-					  MVEBU_MBUS_PCI_MEM);
-	mvebu_mbus_add_window_remap_flags("pcie1.0",
-					  KIRKWOOD_PCIE1_IO_PHYS_BASE,
-					  KIRKWOOD_PCIE1_IO_SIZE,
-					  KIRKWOOD_PCIE1_IO_BUS_BASE,
-					  MVEBU_MBUS_PCI_IO);
-	mvebu_mbus_add_window_remap_flags("pcie1.0",
-					  KIRKWOOD_PCIE1_MEM_PHYS_BASE,
-					  KIRKWOOD_PCIE1_MEM_SIZE,
-					  MVEBU_MBUS_NO_REMAP,
-					  MVEBU_MBUS_PCI_MEM);
 	mvebu_mbus_add_window("nand", KIRKWOOD_NAND_MEM_PHYS_BASE,
 			      KIRKWOOD_NAND_MEM_SIZE);
 	mvebu_mbus_add_window("sram", KIRKWOOD_SRAM_PHYS_BASE,
@@ -723,7 +723,7 @@ void __init kirkwood_init(void)
 #endif
 }
 
-void kirkwood_restart(char mode, const char *cmd)
+void kirkwood_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * Enable soft reset to assert RSTOUTn.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,8 @@
 #ifndef __ARCH_KIRKWOOD_COMMON_H
 #define __ARCH_KIRKWOOD_COMMON_H
 
+#include <linux/reboot.h>
+
 struct dsa_platform_data;
 struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
@@ -51,7 +53,9 @@ void kirkwood_nand_init_rnb(struct mtd_p
 			    int (*dev_ready)(struct mtd_info *));
 void kirkwood_audio_init(void);
 void kirkwood_cpuidle_init(void);
-void kirkwood_restart(char, const char *);
+void kirkwood_cpufreq_init(void);
+
+void kirkwood_restart(enum reboot_mode, const char *);
 void kirkwood_clk_init(void);
 
 /* board init functions for boards not fully converted to fdt */
@@ -65,6 +69,11 @@ void guruplug_dt_init(void);
 #else
 static inline void guruplug_dt_init(void) {};
 #endif
+#ifdef CONFIG_MACH_SHEEVAPLUG_DT
+void sheevaplug_dt_init(void);
+#else
+static inline void sheevaplug_dt_init(void) {};
+#endif
 #ifdef CONFIG_MACH_TS219_DT
 void qnap_dt_ts219_init(void);
 #else
@@ -119,6 +128,12 @@ void km_kirkwood_init(void);
 static inline void km_kirkwood_init(void) {};
 #endif
 
+#ifdef CONFIG_MACH_DB88F628X_BP_DT
+void db88f628x_init(void);
+#else
+static inline void db88f628x_init(void) {};
+#endif
+
 #ifdef CONFIG_MACH_MPLCEC4_DT
 void mplcec4_init(void);
 #else
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/db88f6281-bp-setup.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/db88f6281-bp-setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/db88f6281-bp-setup.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,108 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/db88f6281-bp-setup.c
- *
- * Marvell DB-88F6281-BP Development Board Setup
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sizes.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/partitions.h>
-#include <linux/ata_platform.h>
-#include <linux/mv643xx_eth.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/kirkwood.h>
-#include <linux/platform_data/mmc-mvsdio.h>
-#include "common.h"
-#include "mpp.h"
-
-static struct mtd_partition db88f6281_nand_parts[] = {
-	{
-		.name = "u-boot",
-		.offset = 0,
-		.size = SZ_1M
-	}, {
-		.name = "uImage",
-		.offset = MTDPART_OFS_NXTBLK,
-		.size = SZ_4M
-	}, {
-		.name = "root",
-		.offset = MTDPART_OFS_NXTBLK,
-		.size = MTDPART_SIZ_FULL
-	},
-};
-
-static struct mv643xx_eth_platform_data db88f6281_ge00_data = {
-	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
-};
-
-static struct mv_sata_platform_data db88f6281_sata_data = {
-	.n_ports	= 2,
-};
-
-static struct mvsdio_platform_data db88f6281_mvsdio_data = {
-	.gpio_write_protect	= 37,
-	.gpio_card_detect	= 38,
-};
-
-static unsigned int db88f6281_mpp_config[] __initdata = {
-	MPP0_NF_IO2,
-	MPP1_NF_IO3,
-	MPP2_NF_IO4,
-	MPP3_NF_IO5,
-	MPP4_NF_IO6,
-	MPP5_NF_IO7,
-	MPP18_NF_IO0,
-	MPP19_NF_IO1,
-	MPP37_GPIO,
-	MPP38_GPIO,
-	0
-};
-
-static void __init db88f6281_init(void)
-{
-	/*
-	 * Basic setup. Needs to be called early.
-	 */
-	kirkwood_init();
-	kirkwood_mpp_conf(db88f6281_mpp_config);
-
-	kirkwood_nand_init(ARRAY_AND_SIZE(db88f6281_nand_parts), 25);
-	kirkwood_ehci_init();
-	kirkwood_ge00_init(&db88f6281_ge00_data);
-	kirkwood_sata_init(&db88f6281_sata_data);
-	kirkwood_uart0_init();
-	kirkwood_sdio_init(&db88f6281_mvsdio_data);
-}
-
-static int __init db88f6281_pci_init(void)
-{
-	if (machine_is_db88f6281_bp()) {
-		u32 dev, rev;
-
-		kirkwood_pcie_id(&dev, &rev);
-		if (dev == MV88F6282_DEV_ID)
-			kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0);
-		else
-			kirkwood_pcie_init(KW_PCIE0);
-	}
-	return 0;
-}
-subsys_initcall(db88f6281_pci_init);
-
-MACHINE_START(DB88F6281_BP, "Marvell DB-88F6281-BP Development Board")
-	/* Maintainer: Saeed Bishara <saeed@marvell.com> */
-	.atag_offset	= 0x100,
-	.init_machine	= db88f6281_init,
-	.map_io		= kirkwood_map_io,
-	.init_early	= kirkwood_init_early,
-	.init_irq	= kirkwood_init_irq,
-	.init_time	= kirkwood_timer_init,
-	.restart	= kirkwood_restart,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/include/mach/bridge-regs.h linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/include/mach/bridge-regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/include/mach/bridge-regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,17 +17,16 @@
 #define CPU_CONFIG_ERROR_PROP	0x00000004
 
 #define CPU_CONTROL		(BRIDGE_VIRT_BASE + 0x0104)
+#define CPU_CONTROL_PHYS	(BRIDGE_PHYS_BASE + 0x0104)
 #define CPU_RESET		0x00000002
 
 #define RSTOUTn_MASK		(BRIDGE_VIRT_BASE + 0x0108)
-#define WDT_RESET_OUT_EN	0x00000002
 #define SOFT_RESET_OUT_EN	0x00000004
 
 #define SYSTEM_SOFT_RESET	(BRIDGE_VIRT_BASE + 0x010c)
 #define SOFT_RESET		0x00000001
 
 #define BRIDGE_CAUSE		(BRIDGE_VIRT_BASE + 0x0110)
-#define WDT_INT_REQ		0x0008
 
 #define BRIDGE_INT_TIMER1_CLR	(~0x0004)
 
@@ -69,6 +68,7 @@
 #define CGC_RUNIT		(1 << 7)
 #define CGC_XOR0		(1 << 8)
 #define CGC_AUDIO		(1 << 9)
+#define CGC_POWERSAVE           (1 << 11)
 #define CGC_SATA0		(1 << 14)
 #define CGC_SATA1		(1 << 15)
 #define CGC_XOR1		(1 << 16)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -8,12 +8,6 @@ config MACH_D2NET_V2
 	  Say 'Y' here if you want your kernel to support the
 	  LaCie d2 Network v2 NAS.
 
-config MACH_DB88F6281_BP
-	bool "Marvell DB-88F6281-BP Development Board"
-	help
-	  Say 'Y' here if you want your kernel to support the
-	  Marvell DB-88F6281-BP Development Board.
-
 config MACH_DOCKSTAR
 	bool "Seagate FreeAgent DockStar"
 	help
@@ -134,13 +128,12 @@ comment "Device tree entries"
 
 config ARCH_KIRKWOOD_DT
 	bool "Marvell Kirkwood Flattened Device Tree"
+	select KIRKWOOD_CLK
 	select POWER_SUPPLY
 	select POWER_RESET
 	select POWER_RESET_GPIO
 	select REGULATOR
 	select REGULATOR_FIXED_VOLTAGE
-	select MVEBU_CLK_CORE
-	select MVEBU_CLK_GATING
 	select USE_OF
 	help
 	  Say 'Y' here if you want your kernel to support the
@@ -153,6 +146,13 @@ config MACH_CLOUDBOX_DT
 	  Say 'Y' here if you want your kernel to support the LaCie
 	  CloudBox NAS, using Flattened Device Tree.
 
+config MACH_DB88F628X_BP_DT
+	bool "Marvell DB-88F628x-BP Development Board (Flattened Device Tree)"
+	help
+	  Say 'Y' here if you want your kernel to support the Marvell
+	  DB-88F6281-BP and DB-88F6282-BP Development Board (Flattened
+	  Device Tree).
+
 config MACH_DLINK_KIRKWOOD_DT
 	bool "D-Link Kirkwood-based NAS (Flattened Device Tree)"
 	select ARCH_KIRKWOOD_DT
@@ -227,6 +227,7 @@ config MACH_KM_KIRKWOOD_DT
 config MACH_LSXL_DT
 	bool "Buffalo Linkstation LS-XHL, LS-CHLv2 (Flattened Device Tree)"
 	select ARCH_KIRKWOOD_DT
+	select POWER_RESET_RESTART
 	help
 	  Say 'Y' here if you want your kernel to support the
 	  Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using
@@ -272,14 +273,6 @@ config MACH_NETSPACE_V2_DT
 	  Say 'Y' here if you want your kernel to support the LaCie
 	  Network Space v2 NAS, using Flattened Device Tree.
 
-config MACH_NSA310_DT
-	bool "ZyXEL NSA-310 (Flattened Device Tree)"
-	select ARCH_KIRKWOOD_DT
-	select ARM_ATAG_DTB_COMPAT
-	help
-	  Say 'Y' here if you want your kernel to support the
-	  ZyXEL NSA-310 board (Flattened Device Tree).
-
 config MACH_OPENBLOCKS_A6_DT
 	bool "Plat'Home OpenBlocks A6 (Flattened Device Tree)"
 	select ARCH_KIRKWOOD_DT
@@ -296,6 +289,13 @@ config MACH_READYNAS_DT
 	  Say 'Y' here if you want your kernel to support the
 	  NETGEAR ReadyNAS Duo v2 using Fattened Device Tree.
 
+config MACH_SHEEVAPLUG_DT
+	bool "Marvell (eSATA) SheevaPlug (Flattened Device Tree)"
+	select ARCH_KIRKWOOD_DT
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell (eSATA) SheevaPlug (Flattened Device Tree).
+
 config MACH_TOPKICK_DT
 	bool "USI Topkick (Flattened Device Tree)"
 	select ARCH_KIRKWOOD_DT
@@ -308,6 +308,7 @@ config MACH_TS219_DT
 	select ARCH_KIRKWOOD_DT
 	select ARM_APPENDED_DTB
 	select ARM_ATAG_DTB_COMPAT
+	select POWER_RESET_QNAP
 	help
 	  Say 'Y' here if you want your kernel to support the QNAP
 	  TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,6 @@
 obj-y				+= common.o irq.o pcie.o mpp.o
 
 obj-$(CONFIG_MACH_D2NET_V2)		+= d2net_v2-setup.o lacie_v2-common.o
-obj-$(CONFIG_MACH_DB88F6281_BP)		+= db88f6281-bp-setup.o
 obj-$(CONFIG_MACH_DOCKSTAR)		+= dockstar-setup.o
 obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG)	+= sheevaplug-setup.o
 obj-$(CONFIG_MACH_GURUPLUG)		+= guruplug-setup.o
@@ -21,6 +20,7 @@ obj-$(CONFIG_MACH_TS41X)		+= ts41x-setup
 
 obj-$(CONFIG_ARCH_KIRKWOOD_DT)		+= board-dt.o
 obj-$(CONFIG_MACH_CLOUDBOX_DT)		+= board-ns2.o
+obj-$(CONFIG_MACH_DB88F628X_BP_DT)	+= board-db88f628x-bp.o
 obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT)	+= board-dnskw.o
 obj-$(CONFIG_MACH_DOCKSTAR_DT)		+= board-dockstar.o
 obj-$(CONFIG_MACH_DREAMPLUG_DT)		+= board-dreamplug.o
@@ -37,8 +37,8 @@ obj-$(CONFIG_MACH_NETSPACE_LITE_V2_DT)	+
 obj-$(CONFIG_MACH_NETSPACE_MAX_V2_DT)	+= board-ns2.o
 obj-$(CONFIG_MACH_NETSPACE_MINI_V2_DT)	+= board-ns2.o
 obj-$(CONFIG_MACH_NETSPACE_V2_DT)	+= board-ns2.o
-obj-$(CONFIG_MACH_NSA310_DT)		+= board-nsa310.o
 obj-$(CONFIG_MACH_OPENBLOCKS_A6_DT)	+= board-openblocks_a6.o
 obj-$(CONFIG_MACH_READYNAS_DT)		+= board-readynas.o
+obj-$(CONFIG_MACH_SHEEVAPLUG_DT)	+= board-sheevaplug.o
 obj-$(CONFIG_MACH_TOPKICK_DT)		+= board-usi_topkick.o
 obj-$(CONFIG_MACH_TS219_DT)		+= board-ts219.o tsx1x-common.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-kirkwood/pcie.c linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/pcie.c
--- linux-libre-3.10-gnu/arch/arm/mach-kirkwood/pcie.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-kirkwood/pcie.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
+#include <linux/mbus.h>
 #include <video/vga.h>
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
@@ -253,6 +254,27 @@ static void __init add_pcie_port(int ind
 
 void __init kirkwood_pcie_init(unsigned int portmask)
 {
+	mvebu_mbus_add_window_remap_flags("pcie0.0",
+					  KIRKWOOD_PCIE_IO_PHYS_BASE,
+					  KIRKWOOD_PCIE_IO_SIZE,
+					  KIRKWOOD_PCIE_IO_BUS_BASE,
+					  MVEBU_MBUS_PCI_IO);
+	mvebu_mbus_add_window_remap_flags("pcie0.0",
+					  KIRKWOOD_PCIE_MEM_PHYS_BASE,
+					  KIRKWOOD_PCIE_MEM_SIZE,
+					  MVEBU_MBUS_NO_REMAP,
+					  MVEBU_MBUS_PCI_MEM);
+	mvebu_mbus_add_window_remap_flags("pcie1.0",
+					  KIRKWOOD_PCIE1_IO_PHYS_BASE,
+					  KIRKWOOD_PCIE1_IO_SIZE,
+					  KIRKWOOD_PCIE1_IO_BUS_BASE,
+					  MVEBU_MBUS_PCI_IO);
+	mvebu_mbus_add_window_remap_flags("pcie1.0",
+					  KIRKWOOD_PCIE1_MEM_PHYS_BASE,
+					  KIRKWOOD_PCIE1_MEM_SIZE,
+					  MVEBU_MBUS_NO_REMAP,
+					  MVEBU_MBUS_PCI_MEM);
+
 	vga_base = KIRKWOOD_PCIE_MEM_PHYS_BASE;
 
 	if (portmask & KW_PCIE0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ks8695/generic.h linux-libre-3.11-rc7-gnu/arch/arm/mach-ks8695/generic.h
--- linux-libre-3.10-gnu/arch/arm/mach-ks8695/generic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ks8695/generic.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,5 +12,5 @@
 
 extern __init void ks8695_map_io(void);
 extern __init void ks8695_init_irq(void);
-extern void ks8695_restart(char, const char *);
+extern void ks8695_restart(enum reboot_mode, const char *);
 extern void ks8695_timer_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ks8695/time.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ks8695/time.c
--- linux-libre-3.10-gnu/arch/arm/mach-ks8695/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ks8695/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -154,11 +154,11 @@ void __init ks8695_timer_init(void)
 	setup_irq(KS8695_IRQ_TIMER1, &ks8695_timer_irq);
 }
 
-void ks8695_restart(char mode, const char *cmd)
+void ks8695_restart(enum reboot_mode reboot_mode, const char *cmd)
 {
 	unsigned int reg;
 
-	if (mode == 's')
+	if (reboot_mode == REBOOT_SOFT)
 		soft_restart(0);
 
 	/* disable timer0 */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-lpc32xx/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-lpc32xx/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-lpc32xx/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-lpc32xx/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -207,11 +207,11 @@ void __init lpc32xx_map_io(void)
 	iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc));
 }
 
-void lpc23xx_restart(char mode, const char *cmd)
+void lpc23xx_restart(enum reboot_mode mode, const char *cmd)
 {
 	switch (mode) {
-	case 's':
-	case 'h':
+	case REBOOT_SOFT:
+	case REBOOT_HARD:
 		lpc32xx_watchdog_reset();
 		break;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-lpc32xx/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-lpc32xx/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-lpc32xx/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-lpc32xx/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 
 #include <mach/board.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 
 /*
  * Other arch specific structures and functions
@@ -29,7 +30,7 @@ extern void lpc32xx_timer_init(void);
 extern void __init lpc32xx_init_irq(void);
 extern void __init lpc32xx_map_io(void);
 extern void __init lpc32xx_serial_init(void);
-extern void lpc23xx_restart(char, const char *);
+extern void lpc23xx_restart(enum reboot_mode, const char *);
 
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-lpc32xx/phy3250.c linux-libre-3.11-rc7-gnu/arch/arm/mach-lpc32xx/phy3250.c
--- linux-libre-3.10-gnu/arch/arm/mach-lpc32xx/phy3250.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-lpc32xx/phy3250.c	2013-08-25 20:43:22.000000000 -0400
@@ -182,8 +182,8 @@ static void pl08x_put_signal(const struc
 static struct pl08x_platform_data pl08x_pd = {
 	.slave_channels = &pl08x_slave_channels[0],
 	.num_slave_channels = ARRAY_SIZE(pl08x_slave_channels),
-	.get_signal = pl08x_get_signal,
-	.put_signal = pl08x_put_signal,
+	.get_xfer_signal = pl08x_get_signal,
+	.put_xfer_signal = pl08x_put_signal,
 	.lli_buses = PL08X_AHB1,
 	.mem_buses = PL08X_AHB1,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mmp/aspenite.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/aspenite.c
--- linux-libre-3.10-gnu/arch/arm/mach-mmp/aspenite.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/aspenite.c	2013-08-25 20:43:22.000000000 -0400
@@ -210,7 +210,7 @@ struct pxa168fb_mach_info aspenite_lcd_i
 	.invert_pixclock	= 0,
 };
 
-static unsigned int aspenite_matrix_key_map[] = {
+static const unsigned int aspenite_matrix_key_map[] = {
 	KEY(0, 6, KEY_UP),	/* SW 4 */
 	KEY(0, 7, KEY_DOWN),	/* SW 5 */
 	KEY(1, 6, KEY_LEFT),	/* SW 6 */
@@ -219,11 +219,15 @@ static unsigned int aspenite_matrix_key_
 	KEY(4, 7, KEY_ESC),	/* SW 9 */
 };
 
+static struct matrix_keymap_data aspenite_matrix_keymap_data = {
+	.keymap			= aspenite_matrix_key_map,
+	.keymap_size		= ARRAY_SIZE(aspenite_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
 	.matrix_key_rows	= 5,
 	.matrix_key_cols	= 8,
-	.matrix_key_map		= aspenite_matrix_key_map,
-	.matrix_key_map_size	= ARRAY_SIZE(aspenite_matrix_key_map),
+	.matrix_keymap_data	= &aspenite_matrix_keymap_data,
 	.debounce_interval	= 30,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mmp/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-mmp/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,7 +47,7 @@ void __init mmp_map_io(void)
 	mmp_chip_id = __raw_readl(MMP_CHIPID);
 }
 
-void mmp_restart(char mode, const char *cmd)
+void mmp_restart(enum reboot_mode mode, const char *cmd)
 {
 	soft_restart(0);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mmp/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-mmp/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,10 +1,11 @@
+#include <linux/reboot.h>
 #define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
 
 extern void timer_init(int irq);
 
 extern void __init icu_init_irq(void);
 extern void __init mmp_map_io(void);
-extern void mmp_restart(char, const char *);
+extern void mmp_restart(enum reboot_mode, const char *);
 extern void __init pxa168_clk_init(void);
 extern void __init pxa910_clk_init(void);
 extern void __init mmp2_clk_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mmp/include/mach/pxa168.h linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/include/mach/pxa168.h
--- linux-libre-3.10-gnu/arch/arm/mach-mmp/include/mach/pxa168.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/include/mach/pxa168.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,9 +1,11 @@
 #ifndef __ASM_MACH_PXA168_H
 #define __ASM_MACH_PXA168_H
 
+#include <linux/reboot.h>
+
 extern void pxa168_timer_init(void);
 extern void __init pxa168_init_irq(void);
-extern void pxa168_restart(char, const char *);
+extern void pxa168_restart(enum reboot_mode, const char *);
 extern void pxa168_clear_keypad_wakeup(void);
 
 #include <linux/i2c.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mmp/pxa168.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/pxa168.c
--- linux-libre-3.10-gnu/arch/arm/mach-mmp/pxa168.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/pxa168.c	2013-08-25 20:43:22.000000000 -0400
@@ -172,7 +172,7 @@ int __init pxa168_add_usb_host(struct mv
 	return platform_device_register(&pxa168_device_usb_host);
 }
 
-void pxa168_restart(char mode, const char *cmd)
+void pxa168_restart(enum reboot_mode mode, const char *cmd)
 {
 	soft_restart(0xffff0000);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mmp/teton_bga.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/teton_bga.c
--- linux-libre-3.10-gnu/arch/arm/mach-mmp/teton_bga.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/teton_bga.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,11 +61,15 @@ static unsigned int teton_bga_matrix_key
 	KEY(1, 7, KEY_RIGHT),
 };
 
+static struct matrix_keymap_data teton_bga_matrix_keymap_data = {
+	.keymap			= teton_bga_matrix_key_map,
+	.keymap_size		= ARRAY_SIZE(teton_bga_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = {
 	.matrix_key_rows        = 2,
 	.matrix_key_cols        = 8,
-	.matrix_key_map         = teton_bga_matrix_key_map,
-	.matrix_key_map_size    = ARRAY_SIZE(teton_bga_matrix_key_map),
+	.matrix_keymap_data	= &teton_bga_matrix_keymap_data,
 	.debounce_interval      = 30,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mmp/time.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/time.c
--- linux-libre-3.10-gnu/arch/arm/mach-mmp/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mmp/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,8 +28,8 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/sched_clock.h>
 
-#include <asm/sched_clock.h>
 #include <mach/addr-map.h>
 #include <mach/regs-timers.h>
 #include <mach/regs-apbc.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/board-dt-8660.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-dt-8660.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/board-dt-8660.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-dt-8660.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/irqchip.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 
@@ -44,7 +43,6 @@ static const char *msm8x60_fluid_match[]
 DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
 	.smp = smp_ops(msm_smp_ops),
 	.map_io = msm_map_msm8x60_io,
-	.init_irq = irqchip_init,
 	.init_machine = msm8x60_dt_init,
 	.init_late = msm8x60_init_late,
 	.init_time	= msm_dt_timer_init,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/board-dt-8960.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-dt-8960.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/board-dt-8960.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-dt-8960.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/irqchip.h>
 #include <linux/of_platform.h>
 
 #include <asm/mach/arch.h>
@@ -31,7 +30,6 @@ static const char * const msm8960_dt_mat
 DT_MACHINE_START(MSM8960_DT, "Qualcomm MSM (Flattened Device Tree)")
 	.smp = smp_ops(msm_smp_ops),
 	.map_io = msm_map_msm8960_io,
-	.init_irq = irqchip_init,
 	.init_time	= msm_dt_timer_init,
 	.init_machine = msm_dt_init,
 	.dt_compat = msm8960_dt_match,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/board-halibut.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-halibut.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/board-halibut.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-halibut.c	2013-08-25 20:43:22.000000000 -0400
@@ -59,6 +59,7 @@ static struct platform_device smc91x_dev
 };
 
 static struct platform_device *devices[] __initdata = {
+	&msm_clock_7x01a,
 	&msm_device_gpio_7201,
 	&msm_device_uart3,
 	&msm_device_smd,
@@ -91,7 +92,6 @@ static void __init halibut_fixup(struct
 static void __init halibut_map_io(void)
 {
 	msm_map_common_io();
-	msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
 }
 
 static void __init halibut_init_late(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/board-msm7x30.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-msm7x30.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/board-msm7x30.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-msm7x30.c	2013-08-25 20:43:22.000000000 -0400
@@ -89,6 +89,7 @@ struct msm_gpiomux_config msm_gpiomux_co
 };
 
 static struct platform_device *devices[] __initdata = {
+	&msm_clock_7x30,
 	&msm_device_gpio_7x30,
 #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
         &msm_device_uart2,
@@ -116,7 +117,6 @@ static void __init msm7x30_init(void)
 static void __init msm7x30_map_io(void)
 {
 	msm_map_msm7x30_io();
-	msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30);
 }
 
 static void __init msm7x30_init_late(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/board-qsd8x50.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-qsd8x50.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/board-qsd8x50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-qsd8x50.c	2013-08-25 20:43:22.000000000 -0400
@@ -89,6 +89,7 @@ static struct msm_otg_platform_data msm_
 };
 
 static struct platform_device *devices[] __initdata = {
+	&msm_clock_8x50,
 	&msm_device_gpio_8x50,
 	&msm_device_uart3,
 	&msm_device_smd,
@@ -172,7 +173,6 @@ static void __init qsd8x50_init_mmc(void
 static void __init qsd8x50_map_io(void)
 {
 	msm_map_qsd8x50_io();
-	msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50);
 }
 
 static void __init qsd8x50_init_irq(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/board-trout.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-trout.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/board-trout.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-trout.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,7 @@
 extern int trout_init_mmc(unsigned int);
 
 static struct platform_device *devices[] __initdata = {
+	&msm_clock_7x01a,
 	&msm_device_gpio_7201,
 	&msm_device_uart3,
 	&msm_device_smd,
@@ -94,8 +95,6 @@ static void __init trout_map_io(void)
 	/* route UART3 to the "H2W" extended usb connector */
 	writeb(0x80, TROUT_CPLD_BASE + 0x00);
 #endif
-
-	msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
 }
 
 static void __init trout_init_late(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/board-trout-panel.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-trout-panel.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/board-trout-panel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/board-trout-panel.c	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,6 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/leds.h>
-#include <linux/clk.h>
 #include <linux/err.h>
 
 #include <asm/io.h>
@@ -19,6 +18,7 @@
 
 #include "board-trout.h"
 #include "proc_comm.h"
+#include "clock-pcom.h"
 #include "devices.h"
 
 #define TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS 255
@@ -170,7 +170,6 @@ static struct mddi_table mddi_toshiba_in
 #define INTMASK_VWAKEOUT (1U << 0)
 
 
-static struct clk *gp_clk;
 static int trout_new_backlight = 1;
 static struct vreg *vreg_mddi_1v5;
 static struct vreg *vreg_lcm_2v85;
@@ -273,18 +272,14 @@ int __init trout_init_panel(void)
 	} else {
 		uint32_t config = PCOM_GPIO_CFG(27, 1, GPIO_OUTPUT,
 						GPIO_NO_PULL, GPIO_8MA);
+		uint32_t id = P_GP_CLK;
+		uint32_t rate = 19200000;
+
 		msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
 
-		gp_clk = clk_get(NULL, "gp_clk");
-		if (IS_ERR(gp_clk)) {
-			printk(KERN_ERR "trout_init_panel: could not get gp"
-			       "clock\n");
-			gp_clk = NULL;
-		}
-		rc = clk_set_rate(gp_clk, 19200000);
-		if (rc)
-			printk(KERN_ERR "trout_init_panel: set clock rate "
-			       "failed\n");
+		msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+		if (id < 0)
+			pr_err("trout_init_panel: set clock rate failed\n");
 	}
 
 	rc = platform_device_register(&msm_device_mdp);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/clock-7x30.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock-7x30.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/clock-7x30.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock-7x30.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,155 +0,0 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ARCH_ARM_MACH_MSM_CLOCK_7X30_H
-#define __ARCH_ARM_MACH_MSM_CLOCK_7X30_H
-
-enum {
-	L_7X30_NONE_CLK = -1,
-	L_7X30_ADM_CLK,
-	L_7X30_I2C_CLK,
-	L_7X30_I2C_2_CLK,
-	L_7X30_QUP_I2C_CLK,
-	L_7X30_UART1DM_CLK,
-	L_7X30_UART1DM_P_CLK,
-	L_7X30_UART2DM_CLK,
-	L_7X30_UART2DM_P_CLK,
-	L_7X30_EMDH_CLK,
-	L_7X30_EMDH_P_CLK,
-	L_7X30_PMDH_CLK,
-	L_7X30_PMDH_P_CLK,
-	L_7X30_GRP_2D_CLK,
-	L_7X30_GRP_2D_P_CLK,
-	L_7X30_GRP_3D_SRC_CLK,
-	L_7X30_GRP_3D_CLK,
-	L_7X30_GRP_3D_P_CLK,
-	L_7X30_IMEM_CLK,
-	L_7X30_SDC1_CLK,
-	L_7X30_SDC1_P_CLK,
-	L_7X30_SDC2_CLK,
-	L_7X30_SDC2_P_CLK,
-	L_7X30_SDC3_CLK,
-	L_7X30_SDC3_P_CLK,
-	L_7X30_SDC4_CLK,
-	L_7X30_SDC4_P_CLK,
-	L_7X30_MDP_CLK,
-	L_7X30_MDP_P_CLK,
-	L_7X30_MDP_LCDC_PCLK_CLK,
-	L_7X30_MDP_LCDC_PAD_PCLK_CLK,
-	L_7X30_MDP_VSYNC_CLK,
-	L_7X30_MI2S_CODEC_RX_M_CLK,
-	L_7X30_MI2S_CODEC_RX_S_CLK,
-	L_7X30_MI2S_CODEC_TX_M_CLK,
-	L_7X30_MI2S_CODEC_TX_S_CLK,
-	L_7X30_MI2S_M_CLK,
-	L_7X30_MI2S_S_CLK,
-	L_7X30_LPA_CODEC_CLK,
-	L_7X30_LPA_CORE_CLK,
-	L_7X30_LPA_P_CLK,
-	L_7X30_MIDI_CLK,
-	L_7X30_MDC_CLK,
-	L_7X30_ROTATOR_IMEM_CLK,
-	L_7X30_ROTATOR_P_CLK,
-	L_7X30_SDAC_M_CLK,
-	L_7X30_SDAC_CLK,
-	L_7X30_UART1_CLK,
-	L_7X30_UART2_CLK,
-	L_7X30_UART3_CLK,
-	L_7X30_TV_CLK,
-	L_7X30_TV_DAC_CLK,
-	L_7X30_TV_ENC_CLK,
-	L_7X30_HDMI_CLK,
-	L_7X30_TSIF_REF_CLK,
-	L_7X30_TSIF_P_CLK,
-	L_7X30_USB_HS_SRC_CLK,
-	L_7X30_USB_HS_CLK,
-	L_7X30_USB_HS_CORE_CLK,
-	L_7X30_USB_HS_P_CLK,
-	L_7X30_USB_HS2_CLK,
-	L_7X30_USB_HS2_CORE_CLK,
-	L_7X30_USB_HS2_P_CLK,
-	L_7X30_USB_HS3_CLK,
-	L_7X30_USB_HS3_CORE_CLK,
-	L_7X30_USB_HS3_P_CLK,
-	L_7X30_VFE_CLK,
-	L_7X30_VFE_P_CLK,
-	L_7X30_VFE_MDC_CLK,
-	L_7X30_VFE_CAMIF_CLK,
-	L_7X30_CAMIF_PAD_P_CLK,
-	L_7X30_CAM_M_CLK,
-	L_7X30_JPEG_CLK,
-	L_7X30_JPEG_P_CLK,
-	L_7X30_VPE_CLK,
-	L_7X30_MFC_CLK,
-	L_7X30_MFC_DIV2_CLK,
-	L_7X30_MFC_P_CLK,
-	L_7X30_SPI_CLK,
-	L_7X30_SPI_P_CLK,
-	L_7X30_CSI0_CLK,
-	L_7X30_CSI0_VFE_CLK,
-	L_7X30_CSI0_P_CLK,
-	L_7X30_CSI1_CLK,
-	L_7X30_CSI1_VFE_CLK,
-	L_7X30_CSI1_P_CLK,
-	L_7X30_GLBL_ROOT_CLK,
-
-	L_7X30_AXI_LI_VG_CLK,
-	L_7X30_AXI_LI_GRP_CLK,
-	L_7X30_AXI_LI_JPEG_CLK,
-	L_7X30_AXI_GRP_2D_CLK,
-	L_7X30_AXI_MFC_CLK,
-	L_7X30_AXI_VPE_CLK,
-	L_7X30_AXI_LI_VFE_CLK,
-	L_7X30_AXI_LI_APPS_CLK,
-	L_7X30_AXI_MDP_CLK,
-	L_7X30_AXI_IMEM_CLK,
-	L_7X30_AXI_LI_ADSP_A_CLK,
-	L_7X30_AXI_ROTATOR_CLK,
-
-	L_7X30_NR_CLKS
-};
-
-struct clk_ops;
-extern struct clk_ops clk_ops_7x30;
-
-struct clk_ops *clk_7x30_is_local(uint32_t id);
-int clk_7x30_init(void);
-
-void pll_enable(uint32_t pll);
-void pll_disable(uint32_t pll);
-
-extern int internal_pwr_rail_ctl_auto(unsigned rail_id, bool enable);
-
-#define CLK_7X30(clk_name, clk_id, clk_dev, clk_flags) {	\
-	.con_id = clk_name, \
-	.dev_id = clk_dev, \
-	.clk = &(struct clk){ \
-		.id = L_7X30_##clk_id, \
-		.remote_id = P_##clk_id, \
-		.flags = clk_flags, \
-		.dbg_name = #clk_id, \
-	}, \
-	}
-
-#define CLK_7X30S(clk_name, l_id, r_id, clk_dev, clk_flags) {	\
-	.con_id = clk_name, \
-	.dev_id = clk_dev, \
-	.clk = &(struct clk){ \
-		.id = L_7X30_##l_id, \
-		.remote_id = P_##r_id, \
-		.flags = clk_flags, \
-		.dbg_name = #l_id, \
-		.ops = &clk_ops_pcom, \
-	}, \
-	}
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/clock.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/clock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -14,171 +14,15 @@
  *
  */
 
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/err.h>
-#include <linux/spinlock.h>
-#include <linux/pm_qos.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-#include <linux/string.h>
+#include <linux/clk-provider.h>
 #include <linux/module.h>
-#include <linux/clkdev.h>
 
 #include "clock.h"
 
-static DEFINE_MUTEX(clocks_mutex);
-static DEFINE_SPINLOCK(clocks_lock);
-static LIST_HEAD(clocks);
-
-/*
- * Standard clock functions defined in include/linux/clk.h
- */
-int clk_enable(struct clk *clk)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&clocks_lock, flags);
-	clk->count++;
-	if (clk->count == 1)
-		clk->ops->enable(clk->id);
-	spin_unlock_irqrestore(&clocks_lock, flags);
-	return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&clocks_lock, flags);
-	BUG_ON(clk->count == 0);
-	clk->count--;
-	if (clk->count == 0)
-		clk->ops->disable(clk->id);
-	spin_unlock_irqrestore(&clocks_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
 int clk_reset(struct clk *clk, enum clk_reset_action action)
 {
-	return clk->ops->reset(clk->remote_id, action);
+	struct clk_hw *hw = __clk_get_hw(clk);
+	struct msm_clk *m = to_msm_clk(hw);
+	return m->reset(hw, action);
 }
 EXPORT_SYMBOL(clk_reset);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	return clk->ops->get_rate(clk->id);
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret;
-	if (clk->flags & CLKFLAG_MAX) {
-		ret = clk->ops->set_max_rate(clk->id, rate);
-		if (ret)
-			return ret;
-	}
-	if (clk->flags & CLKFLAG_MIN) {
-		ret = clk->ops->set_min_rate(clk->id, rate);
-		if (ret)
-			return ret;
-	}
-
-	if (clk->flags & CLKFLAG_MAX || clk->flags & CLKFLAG_MIN)
-		return ret;
-
-	return clk->ops->set_rate(clk->id, rate);
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	return clk->ops->round_rate(clk->id, rate);
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_min_rate(struct clk *clk, unsigned long rate)
-{
-	return clk->ops->set_min_rate(clk->id, rate);
-}
-EXPORT_SYMBOL(clk_set_min_rate);
-
-int clk_set_max_rate(struct clk *clk, unsigned long rate)
-{
-	return clk->ops->set_max_rate(clk->id, rate);
-}
-EXPORT_SYMBOL(clk_set_max_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	return -ENOSYS;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-	return ERR_PTR(-ENOSYS);
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-int clk_set_flags(struct clk *clk, unsigned long flags)
-{
-	if (clk == NULL || IS_ERR(clk))
-		return -EINVAL;
-	return clk->ops->set_flags(clk->id, flags);
-}
-EXPORT_SYMBOL(clk_set_flags);
-
-/* EBI1 is the only shared clock that several clients want to vote on as of
- * this commit. If this changes in the future, then it might be better to
- * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more
- * generic to support different clocks.
- */
-static struct clk *ebi1_clk;
-
-void __init msm_clock_init(struct clk_lookup *clock_tbl, unsigned num_clocks)
-{
-	unsigned n;
-
-	mutex_lock(&clocks_mutex);
-	for (n = 0; n < num_clocks; n++) {
-		clkdev_add(&clock_tbl[n]);
-		list_add_tail(&clock_tbl[n].clk->list, &clocks);
-	}
-	mutex_unlock(&clocks_mutex);
-
-	ebi1_clk = clk_get(NULL, "ebi1_clk");
-	BUG_ON(ebi1_clk == NULL);
-
-}
-
-/* The bootloader and/or AMSS may have left various clocks enabled.
- * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have
- * not been explicitly enabled by a clk_enable() call.
- */
-static int __init clock_late_init(void)
-{
-	unsigned long flags;
-	struct clk *clk;
-	unsigned count = 0;
-
-	clock_debug_init();
-	mutex_lock(&clocks_mutex);
-	list_for_each_entry(clk, &clocks, list) {
-		clock_debug_add(clk);
-		if (clk->flags & CLKFLAG_AUTO_OFF) {
-			spin_lock_irqsave(&clocks_lock, flags);
-			if (!clk->count) {
-				count++;
-				clk->ops->auto_off(clk->id);
-			}
-			spin_unlock_irqrestore(&clocks_lock, flags);
-		}
-	}
-	mutex_unlock(&clocks_mutex);
-	pr_info("clock_late_init() disabled %d unused clocks\n", count);
-	return 0;
-}
-
-late_initcall(clock_late_init);
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/clock-debug.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock-debug.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/clock-debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock-debug.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/ctype.h>
-#include <linux/debugfs.h>
-#include <linux/clk.h>
-#include "clock.h"
-
-static int clock_debug_rate_set(void *data, u64 val)
-{
-	struct clk *clock = data;
-	int ret;
-
-	/* Only increases to max rate will succeed, but that's actually good
-	 * for debugging purposes so we don't check for error. */
-	if (clock->flags & CLK_MAX)
-		clk_set_max_rate(clock, val);
-	if (clock->flags & CLK_MIN)
-		ret = clk_set_min_rate(clock, val);
-	else
-		ret = clk_set_rate(clock, val);
-	if (ret != 0)
-		printk(KERN_ERR "clk_set%s_rate failed (%d)\n",
-			(clock->flags & CLK_MIN) ? "_min" : "", ret);
-	return ret;
-}
-
-static int clock_debug_rate_get(void *data, u64 *val)
-{
-	struct clk *clock = data;
-	*val = clk_get_rate(clock);
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get,
-			clock_debug_rate_set, "%llu\n");
-
-static int clock_debug_enable_set(void *data, u64 val)
-{
-	struct clk *clock = data;
-	int rc = 0;
-
-	if (val)
-		rc = clock->ops->enable(clock->id);
-	else
-		clock->ops->disable(clock->id);
-
-	return rc;
-}
-
-static int clock_debug_enable_get(void *data, u64 *val)
-{
-	struct clk *clock = data;
-
-	*val = clock->ops->is_enabled(clock->id);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
-			clock_debug_enable_set, "%llu\n");
-
-static int clock_debug_local_get(void *data, u64 *val)
-{
-	struct clk *clock = data;
-
-	*val = clock->ops->is_local(clock->id);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get,
-			NULL, "%llu\n");
-
-static struct dentry *debugfs_base;
-
-int __init clock_debug_init(void)
-{
-	debugfs_base = debugfs_create_dir("clk", NULL);
-	if (!debugfs_base)
-		return -ENOMEM;
-	return 0;
-}
-
-int __init clock_debug_add(struct clk *clock)
-{
-	char temp[50], *ptr;
-	struct dentry *clk_dir;
-
-	if (!debugfs_base)
-		return -ENOMEM;
-
-	strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1);
-	for (ptr = temp; *ptr; ptr++)
-		*ptr = tolower(*ptr);
-
-	clk_dir = debugfs_create_dir(temp, debugfs_base);
-	if (!clk_dir)
-		return -ENOMEM;
-
-	if (!debugfs_create_file("rate", S_IRUGO | S_IWUSR, clk_dir,
-				clock, &clock_rate_fops))
-		goto error;
-
-	if (!debugfs_create_file("enable", S_IRUGO | S_IWUSR, clk_dir,
-				clock, &clock_enable_fops))
-		goto error;
-
-	if (!debugfs_create_file("is_local", S_IRUGO, clk_dir, clock,
-				&clock_local_fops))
-		goto error;
-	return 0;
-error:
-	debugfs_remove_recursive(clk_dir);
-	return -ENOMEM;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/clock.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/clock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -17,56 +17,27 @@
 #ifndef __ARCH_ARM_MACH_MSM_CLOCK_H
 #define __ARCH_ARM_MACH_MSM_CLOCK_H
 
-#include <linux/init.h>
-#include <linux/list.h>
+#include <linux/clk-provider.h>
 #include <mach/clk.h>
 
-#define CLKFLAG_INVERT			0x00000001
-#define CLKFLAG_NOINVERT		0x00000002
-#define CLKFLAG_NONEST			0x00000004
-#define CLKFLAG_NORESET			0x00000008
-
 #define CLK_FIRST_AVAILABLE_FLAG	0x00000100
 #define CLKFLAG_AUTO_OFF		0x00000200
 #define CLKFLAG_MIN			0x00000400
 #define CLKFLAG_MAX			0x00000800
 
-struct clk_ops {
-	int (*enable)(unsigned id);
-	void (*disable)(unsigned id);
-	void (*auto_off)(unsigned id);
-	int (*reset)(unsigned id, enum clk_reset_action action);
-	int (*set_rate)(unsigned id, unsigned rate);
-	int (*set_min_rate)(unsigned id, unsigned rate);
-	int (*set_max_rate)(unsigned id, unsigned rate);
-	int (*set_flags)(unsigned id, unsigned flags);
-	unsigned (*get_rate)(unsigned id);
-	unsigned (*is_enabled)(unsigned id);
-	long (*round_rate)(unsigned id, unsigned rate);
-	bool (*is_local)(unsigned id);
-};
-
-struct clk {
-	uint32_t id;
-	uint32_t remote_id;
-	uint32_t count;
-	uint32_t flags;
-	struct clk_ops *ops;
-	const char *dbg_name;
-	struct list_head list;
-};
-
 #define OFF CLKFLAG_AUTO_OFF
 #define CLK_MIN CLKFLAG_MIN
 #define CLK_MAX CLKFLAG_MAX
 #define CLK_MINMAX (CLK_MIN | CLK_MAX)
 
-#ifdef CONFIG_DEBUG_FS
-int __init clock_debug_init(void);
-int __init clock_debug_add(struct clk *clock);
-#else
-static inline int __init clock_debug_init(void) { return 0; }
-static inline int __init clock_debug_add(struct clk *clock) { return 0; }
-#endif
+struct msm_clk {
+	int (*reset)(struct clk_hw *hw, enum clk_reset_action action);
+	struct clk_hw hw;
+};
+
+static inline struct msm_clk *to_msm_clk(struct clk_hw *hw)
+{
+	return container_of(hw, struct msm_clk, hw);
+}
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/clock-pcom.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock-pcom.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/clock-pcom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock-pcom.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -13,20 +13,33 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/err.h>
-#include <linux/ctype.h>
-#include <linux/stddef.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
 #include <mach/clk.h>
 
 #include "proc_comm.h"
 #include "clock.h"
 #include "clock-pcom.h"
 
-/*
- * glue for the proc_comm interface
- */
-static int pc_clk_enable(unsigned id)
+struct clk_pcom {
+	unsigned id;
+	unsigned long flags;
+	struct msm_clk msm_clk;
+};
+
+static inline struct clk_pcom *to_clk_pcom(struct clk_hw *hw)
+{
+	return container_of(to_msm_clk(hw), struct clk_pcom, msm_clk);
+}
+
+static int pc_clk_enable(struct clk_hw *hw)
 {
+	unsigned id = to_clk_pcom(hw)->id;
 	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
 	if (rc < 0)
 		return rc;
@@ -34,14 +47,16 @@ static int pc_clk_enable(unsigned id)
 		return (int)id < 0 ? -EINVAL : 0;
 }
 
-static void pc_clk_disable(unsigned id)
+static void pc_clk_disable(struct clk_hw *hw)
 {
+	unsigned id = to_clk_pcom(hw)->id;
 	msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
 }
 
-int pc_clk_reset(unsigned id, enum clk_reset_action action)
+static int pc_clk_reset(struct clk_hw *hw, enum clk_reset_action action)
 {
 	int rc;
+	unsigned id = to_clk_pcom(hw)->id;
 
 	if (action == CLK_RESET_ASSERT)
 		rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL);
@@ -54,85 +69,109 @@ int pc_clk_reset(unsigned id, enum clk_r
 		return (int)id < 0 ? -EINVAL : 0;
 }
 
-static int pc_clk_set_rate(unsigned id, unsigned rate)
+static int pc_clk_set_rate(struct clk_hw *hw, unsigned long new_rate,
+			   unsigned long p_rate)
 {
-	/* The rate _might_ be rounded off to the nearest KHz value by the
+	struct clk_pcom *p = to_clk_pcom(hw);
+	unsigned id = p->id, rate = new_rate;
+	int rc;
+
+	/*
+	 * The rate _might_ be rounded off to the nearest KHz value by the
 	 * remote function. So a return value of 0 doesn't necessarily mean
 	 * that the exact rate was set successfully.
 	 */
-	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
-	if (rc < 0)
-		return rc;
-	else
-		return (int)id < 0 ? -EINVAL : 0;
-}
-
-static int pc_clk_set_min_rate(unsigned id, unsigned rate)
-{
-	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
-	if (rc < 0)
-		return rc;
-	else
-		return (int)id < 0 ? -EINVAL : 0;
-}
-
-static int pc_clk_set_max_rate(unsigned id, unsigned rate)
-{
-	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
-	if (rc < 0)
-		return rc;
+	if (p->flags & CLKFLAG_MIN)
+		rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
 	else
-		return (int)id < 0 ? -EINVAL : 0;
-}
-
-static int pc_clk_set_flags(unsigned id, unsigned flags)
-{
-	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
+		rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
 	if (rc < 0)
 		return rc;
 	else
 		return (int)id < 0 ? -EINVAL : 0;
 }
 
-static unsigned pc_clk_get_rate(unsigned id)
+static unsigned long pc_clk_recalc_rate(struct clk_hw *hw, unsigned long p_rate)
 {
+	unsigned id = to_clk_pcom(hw)->id;
 	if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
 		return 0;
 	else
 		return id;
 }
 
-static unsigned pc_clk_is_enabled(unsigned id)
+static int pc_clk_is_enabled(struct clk_hw *hw)
 {
+	unsigned id = to_clk_pcom(hw)->id;
 	if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
 		return 0;
 	else
 		return id;
 }
 
-static long pc_clk_round_rate(unsigned id, unsigned rate)
+static long pc_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long *p_rate)
 {
-
 	/* Not really supported; pc_clk_set_rate() does rounding on it's own. */
 	return rate;
 }
 
-static bool pc_clk_is_local(unsigned id)
-{
-	return false;
-}
-
-struct clk_ops clk_ops_pcom = {
+static struct clk_ops clk_ops_pcom = {
 	.enable = pc_clk_enable,
 	.disable = pc_clk_disable,
-	.auto_off = pc_clk_disable,
-	.reset = pc_clk_reset,
 	.set_rate = pc_clk_set_rate,
-	.set_min_rate = pc_clk_set_min_rate,
-	.set_max_rate = pc_clk_set_max_rate,
-	.set_flags = pc_clk_set_flags,
-	.get_rate = pc_clk_get_rate,
+	.recalc_rate = pc_clk_recalc_rate,
 	.is_enabled = pc_clk_is_enabled,
 	.round_rate = pc_clk_round_rate,
-	.is_local = pc_clk_is_local,
 };
+
+static int msm_clock_pcom_probe(struct platform_device *pdev)
+{
+	const struct pcom_clk_pdata *pdata = pdev->dev.platform_data;
+	int i, ret;
+
+	for (i = 0; i < pdata->num_lookups; i++) {
+		const struct clk_pcom_desc *desc = &pdata->lookup[i];
+		struct clk *c;
+		struct clk_pcom *p;
+		struct clk_hw *hw;
+		struct clk_init_data init;
+
+		p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
+		if (!p)
+			return -ENOMEM;
+
+		p->id = desc->id;
+		p->flags = desc->flags;
+		p->msm_clk.reset = pc_clk_reset;
+
+		hw = &p->msm_clk.hw;
+		hw->init = &init;
+
+		init.name = desc->name;
+		init.ops = &clk_ops_pcom;
+		init.num_parents = 0;
+		init.flags = CLK_IS_ROOT;
+
+		if (!(p->flags & CLKFLAG_AUTO_OFF))
+			init.flags |= CLK_IGNORE_UNUSED;
+
+		c = devm_clk_register(&pdev->dev, hw);
+		ret = clk_register_clkdev(c, desc->con, desc->dev);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static struct platform_driver msm_clock_pcom_driver = {
+	.probe		= msm_clock_pcom_probe,
+	.driver		= {
+		.name	= "msm-clock-pcom",
+		.owner	= THIS_MODULE,
+	},
+};
+module_platform_driver(msm_clock_pcom_driver);
+
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/clock-pcom.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock-pcom.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/clock-pcom.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/clock-pcom.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,5 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/*
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -120,21 +121,25 @@
 
 #define P_NR_CLKS		102
 
-struct clk_ops;
-extern struct clk_ops clk_ops_pcom;
+struct clk_pcom_desc {
+	unsigned id;
+	const char *name;
+	const char *con;
+	const char *dev;
+	unsigned long flags;
+};
 
-int pc_clk_reset(unsigned id, enum clk_reset_action action);
+struct pcom_clk_pdata {
+	struct clk_pcom_desc *lookup;
+	u32 num_lookups;
+};
 
 #define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) {	\
-	.con_id = clk_name, \
-	.dev_id = clk_dev, \
-	.clk = &(struct clk){ \
-		.id = P_##clk_id, \
-		.remote_id = P_##clk_id, \
-		.ops = &clk_ops_pcom, \
-		.flags = clk_flags, \
-		.dbg_name = #clk_id, \
-	}, \
+	.id = P_##clk_id,					\
+	.name = #clk_id,					\
+	.con = clk_name,					\
+	.dev = clk_dev,						\
+	.flags = clk_flags,					\
 	}
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,7 @@ extern void msm_map_msm8x60_io(void);
 extern void msm_map_msm8960_io(void);
 extern void msm_map_qsd8x50_io(void);
 
-extern void __iomem *__msm_ioremap_caller(unsigned long phys_addr, size_t size,
+extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
 					  unsigned int mtype, void *caller);
 
 extern struct smp_operations msm_smp_ops;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/core.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/core.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-extern struct smp_operations msm_smp_ops;
-extern void msm_cpu_die(unsigned int cpu);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/devices.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/devices.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/devices.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/devices.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,10 +16,6 @@
 #ifndef __ARCH_ARM_MACH_MSM_DEVICES_H
 #define __ARCH_ARM_MACH_MSM_DEVICES_H
 
-#include <linux/clkdev.h>
-
-#include "clock.h"
-
 extern struct platform_device msm_device_gpio_7201;
 extern struct platform_device msm_device_gpio_7x30;
 extern struct platform_device msm_device_gpio_8x50;
@@ -50,13 +46,8 @@ extern struct platform_device msm_device
 extern struct platform_device msm_device_mddi1;
 extern struct platform_device msm_device_mdp;
 
-extern struct clk_lookup msm_clocks_7x01a[];
-extern unsigned msm_num_clocks_7x01a;
-
-extern struct clk_lookup msm_clocks_7x30[];
-extern unsigned msm_num_clocks_7x30;
-
-extern struct clk_lookup msm_clocks_8x50[];
-extern unsigned msm_num_clocks_8x50;
+extern struct platform_device msm_clock_7x01a;
+extern struct platform_device msm_clock_7x30;
+extern struct platform_device msm_clock_8x50;
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/devices-msm7x00.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/devices-msm7x00.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/devices-msm7x00.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/devices-msm7x00.c	2013-08-25 20:43:22.000000000 -0400
@@ -425,7 +425,7 @@ struct platform_device msm_device_mdp =
 	.resource = resources_mdp,
 };
 
-struct clk_lookup msm_clocks_7x01a[] = {
+static struct clk_pcom_desc msm_clocks_7x01a[] = {
 	CLK_PCOM("adm_clk",	ADM_CLK,	NULL, 0),
 	CLK_PCOM("adsp_clk",	ADSP_CLK,	NULL, 0),
 	CLK_PCOM("ebi1_clk",	EBI1_CLK,	NULL, 0),
@@ -469,4 +469,12 @@ struct clk_lookup msm_clocks_7x01a[] = {
 	CLK_PCOM("vfe_mdc_clk",	VFE_MDC_CLK,	NULL, OFF),
 };
 
-unsigned msm_num_clocks_7x01a = ARRAY_SIZE(msm_clocks_7x01a);
+static struct pcom_clk_pdata msm_clock_7x01a_pdata = {
+	.lookup = msm_clocks_7x01a,
+	.num_lookups = ARRAY_SIZE(msm_clocks_7x01a),
+};
+
+struct platform_device msm_clock_7x01a = {
+	.name = "msm-clock-pcom",
+	.dev.platform_data = &msm_clock_7x01a_pdata,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/devices-msm7x30.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/devices-msm7x30.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/devices-msm7x30.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/devices-msm7x30.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,8 +28,8 @@
 
 #include <asm/mach/flash.h>
 
+#include "clock.h"
 #include "clock-pcom.h"
-#include "clock-7x30.h"
 
 #include <linux/platform_data/mmc-msm_sdcc.h>
 
@@ -161,7 +161,7 @@ struct platform_device msm_device_hsusb_
 	},
 };
 
-struct clk_lookup msm_clocks_7x30[] = {
+static struct clk_pcom_desc msm_clocks_7x30[] = {
 	CLK_PCOM("adm_clk",	ADM_CLK,	NULL, 0),
 	CLK_PCOM("adsp_clk",	ADSP_CLK,	NULL, 0),
 	CLK_PCOM("cam_m_clk",	CAM_M_CLK,	NULL, 0),
@@ -177,7 +177,6 @@ struct clk_lookup msm_clocks_7x30[] = {
 	CLK_PCOM("grp_2d_pclk",	GRP_2D_P_CLK,	NULL, 0),
 	CLK_PCOM("grp_clk",	GRP_3D_CLK,	NULL, 0),
 	CLK_PCOM("grp_pclk",	GRP_3D_P_CLK,	NULL, 0),
-	CLK_7X30S("grp_src_clk", GRP_3D_SRC_CLK, GRP_3D_CLK,	NULL, 0),
 	CLK_PCOM("hdmi_clk",	HDMI_CLK,	NULL, 0),
 	CLK_PCOM("imem_clk",	IMEM_CLK,	NULL, OFF),
 	CLK_PCOM("jpeg_clk",	JPEG_CLK,	NULL, OFF),
@@ -210,7 +209,6 @@ struct clk_lookup msm_clocks_7x30[] = {
 	CLK_PCOM("sdac_clk",	SDAC_CLK,	NULL, OFF),
 	CLK_PCOM("spi_clk",	SPI_CLK,	NULL, 0),
 	CLK_PCOM("spi_pclk",	SPI_P_CLK,	NULL, 0),
-	CLK_7X30S("tv_src_clk",	TV_CLK, 	TV_ENC_CLK,	NULL, 0),
 	CLK_PCOM("tv_dac_clk",	TV_DAC_CLK,	NULL, 0),
 	CLK_PCOM("tv_enc_clk",	TV_ENC_CLK,	NULL, 0),
 	CLK_PCOM("uart_clk",	UART2_CLK,	"msm_serial.1", 0),
@@ -237,5 +235,12 @@ struct clk_lookup msm_clocks_7x30[] = {
 	CLK_PCOM("csi_vfe_clk",	CSI0_VFE_CLK,	NULL, 0),
 };
 
-unsigned msm_num_clocks_7x30 = ARRAY_SIZE(msm_clocks_7x30);
+static struct pcom_clk_pdata msm_clock_7x30_pdata = {
+	.lookup = msm_clocks_7x30,
+	.num_lookups = ARRAY_SIZE(msm_clocks_7x30),
+};
 
+struct platform_device msm_clock_7x30 = {
+	.name = "msm-clock-pcom",
+	.dev.platform_data = &msm_clock_7x30_pdata,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/devices-qsd8x50.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/devices-qsd8x50.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/devices-qsd8x50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/devices-qsd8x50.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,7 @@
 #include <asm/mach/flash.h>
 
 #include <linux/platform_data/mmc-msm_sdcc.h>
+#include "clock.h"
 #include "clock-pcom.h"
 
 static struct resource msm_gpio_resources[] = {
@@ -322,7 +323,7 @@ int __init msm_add_sdcc(unsigned int con
 	return platform_device_register(pdev);
 }
 
-struct clk_lookup msm_clocks_8x50[] = {
+static struct clk_pcom_desc msm_clocks_8x50[] = {
 	CLK_PCOM("adm_clk",	ADM_CLK,	NULL, 0),
 	CLK_PCOM("ce_clk",	CE_CLK,		NULL, 0),
 	CLK_PCOM("ebi1_clk",	EBI1_CLK,	NULL, CLK_MIN),
@@ -376,5 +377,12 @@ struct clk_lookup msm_clocks_8x50[] = {
 	CLK_PCOM("usb_phy_clk",	USB_PHY_CLK,	NULL, 0),
 };
 
-unsigned msm_num_clocks_8x50 = ARRAY_SIZE(msm_clocks_8x50);
+static struct pcom_clk_pdata msm_clock_8x50_pdata = {
+	.lookup = msm_clocks_8x50,
+	.num_lookups = ARRAY_SIZE(msm_clocks_8x50),
+};
 
+struct platform_device msm_clock_8x50 = {
+	.name = "msm-clock-pcom",
+	.dev.platform_data = &msm_clock_8x50_pdata,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/dma.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/dma.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -284,6 +284,7 @@ static int __init msm_init_datamover(voi
 	clk = clk_get(NULL, "adm_clk");
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
+	clk_prepare(clk);
 	msm_dmov_clk = clk;
 	ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
 	if (ret)
@@ -291,6 +292,4 @@ static int __init msm_init_datamover(voi
 	disable_irq(INT_ADM_AARM);
 	return 0;
 }
-
-arch_initcall(msm_init_datamover);
-
+module_init(msm_init_datamover);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux-8x60.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux-8x60.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux-8x60.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux-8x60.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#include "gpiomux.h"
-
-struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,9 +17,24 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include "gpiomux.h"
+#include "proc_comm.h"
 
 static DEFINE_SPINLOCK(gpiomux_lock);
 
+static void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+{
+	unsigned tlmm_config  = (val & ~GPIOMUX_CTL_MASK) |
+				((gpio & 0x3ff) << 4);
+	unsigned tlmm_disable = 0;
+	int rc;
+
+	rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
+			   &tlmm_config, &tlmm_disable);
+	if (rc)
+		pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n",
+		       __func__, rc, tlmm_config, tlmm_disable);
+}
+
 int msm_gpiomux_write(unsigned gpio,
 		      gpiomux_config_t active,
 		      gpiomux_config_t suspended)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux.h	2013-08-25 20:43:22.000000000 -0400
@@ -20,12 +20,7 @@
 #include <linux/bitops.h>
 #include <linux/errno.h>
 #include <mach/msm_gpiomux.h>
-
-#if defined(CONFIG_MSM_V2_TLMM)
-#include "gpiomux-v2.h"
-#else
 #include "gpiomux-v1.h"
-#endif
 
 /**
  * struct msm_gpiomux_config: gpiomux settings for one gpio line.
@@ -78,16 +73,6 @@ extern struct msm_gpiomux_config msm_gpi
 int msm_gpiomux_write(unsigned gpio,
 		      gpiomux_config_t active,
 		      gpiomux_config_t suspended);
-
-/* Architecture-internal function for use by the framework only.
- * This function can assume the following:
- * - the gpio value has passed a bounds-check
- * - the gpiomux spinlock has been obtained
- *
- * This function is not for public consumption.  External users
- * should use msm_gpiomux_write.
- */
-void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val);
 #else
 static inline int msm_gpiomux_write(unsigned gpio,
 				    gpiomux_config_t active,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux-v1.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux-v1.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux-v1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux-v1.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#include <linux/kernel.h>
-#include "gpiomux.h"
-#include "proc_comm.h"
-
-void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
-{
-	unsigned tlmm_config  = (val & ~GPIOMUX_CTL_MASK) |
-				((gpio & 0x3ff) << 4);
-	unsigned tlmm_disable = 0;
-	int rc;
-
-	rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
-			   &tlmm_config, &tlmm_disable);
-	if (rc)
-		pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n",
-		       __func__, rc, tlmm_config, tlmm_disable);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux-v2.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux-v2.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux-v2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux-v2.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#include <linux/io.h>
-#include <mach/msm_iomap.h>
-#include "gpiomux.h"
-
-void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
-{
-	writel(val & ~GPIOMUX_CTL_MASK,
-	       MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux-v2.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux-v2.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/gpiomux-v2.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/gpiomux-v2.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,61 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
-#define __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
-
-#define GPIOMUX_NGPIOS 173
-
-typedef u16 gpiomux_config_t;
-
-enum {
-	GPIOMUX_DRV_2MA  = 0UL << 6,
-	GPIOMUX_DRV_4MA  = 1UL << 6,
-	GPIOMUX_DRV_6MA  = 2UL << 6,
-	GPIOMUX_DRV_8MA  = 3UL << 6,
-	GPIOMUX_DRV_10MA = 4UL << 6,
-	GPIOMUX_DRV_12MA = 5UL << 6,
-	GPIOMUX_DRV_14MA = 6UL << 6,
-	GPIOMUX_DRV_16MA = 7UL << 6,
-};
-
-enum {
-	GPIOMUX_FUNC_GPIO = 0UL  << 2,
-	GPIOMUX_FUNC_1    = 1UL  << 2,
-	GPIOMUX_FUNC_2    = 2UL  << 2,
-	GPIOMUX_FUNC_3    = 3UL  << 2,
-	GPIOMUX_FUNC_4    = 4UL  << 2,
-	GPIOMUX_FUNC_5    = 5UL  << 2,
-	GPIOMUX_FUNC_6    = 6UL  << 2,
-	GPIOMUX_FUNC_7    = 7UL  << 2,
-	GPIOMUX_FUNC_8    = 8UL  << 2,
-	GPIOMUX_FUNC_9    = 9UL  << 2,
-	GPIOMUX_FUNC_A    = 10UL << 2,
-	GPIOMUX_FUNC_B    = 11UL << 2,
-	GPIOMUX_FUNC_C    = 12UL << 2,
-	GPIOMUX_FUNC_D    = 13UL << 2,
-	GPIOMUX_FUNC_E    = 14UL << 2,
-	GPIOMUX_FUNC_F    = 15UL << 2,
-};
-
-enum {
-	GPIOMUX_PULL_NONE   = 0UL,
-	GPIOMUX_PULL_DOWN   = 1UL,
-	GPIOMUX_PULL_KEEPER = 2UL,
-	GPIOMUX_PULL_UP     = 3UL,
-};
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/headsmp.S
--- linux-libre-3.10-gnu/arch/arm/mach-msm/headsmp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -11,8 +11,6 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-	__CPUINIT
-
 /*
  * MSM specific entry point for secondary CPUs.  This provides
  * a "holding pen" into which all secondary cores are held until we're
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/board.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/board.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/board.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/board.h	2013-08-25 20:43:22.000000000 -0400
@@ -20,16 +20,11 @@
 #include <linux/types.h>
 #include <linux/platform_data/mmc-msm_sdcc.h>
 
-/* platform device data structures */
-
-struct clk_lookup;
-
 /* common init routines for use by arch/arm/mach-msm/board-*.c */
 
 void __init msm_add_devices(void);
 void __init msm_init_irq(void);
 void __init msm_init_gpio(void);
-void __init msm_clock_init(struct clk_lookup *clock_tbl, unsigned num_clocks);
 int __init msm_add_sdcc(unsigned int controller,
 			struct msm_mmc_platform_data *plat,
 			unsigned int stat_irq, unsigned long stat_irq_flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/clk.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/clk.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/clk.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/clk.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,16 +25,7 @@ enum clk_reset_action {
 
 struct clk;
 
-/* Rate is minimum clock rate in Hz */
-int clk_set_min_rate(struct clk *clk, unsigned long rate);
-
-/* Rate is maximum clock rate in Hz */
-int clk_set_max_rate(struct clk *clk, unsigned long rate);
-
 /* Assert/Deassert reset to a hardware block associated with a clock */
 int clk_reset(struct clk *clk, enum clk_reset_action action);
 
-/* Set clock-specific configuration parameters */
-int clk_set_flags(struct clk *clk, unsigned long flags);
-
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/msm_iomap-8960.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/msm_iomap-8960.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/msm_iomap-8960.h	2013-08-25 20:43:22.000000000 -0400
@@ -32,13 +32,6 @@
  *
  */
 
-
-#define MSM8960_QGIC_DIST_PHYS	0x02000000
-#define MSM8960_QGIC_DIST_SIZE	SZ_4K
-
-#define MSM8960_QGIC_CPU_PHYS	0x02002000
-#define MSM8960_QGIC_CPU_SIZE	SZ_4K
-
 #define MSM8960_TMR_PHYS	0x0200A000
 #define MSM8960_TMR_SIZE	SZ_4K
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h	2013-08-25 20:43:22.000000000 -0400
@@ -35,12 +35,6 @@
  *
  */
 
-#define MSM8X60_QGIC_DIST_PHYS	0x02080000
-#define MSM8X60_QGIC_DIST_SIZE	SZ_4K
-
-#define MSM8X60_QGIC_CPU_PHYS	0x02081000
-#define MSM8X60_QGIC_CPU_SIZE	SZ_4K
-
 #define MSM_TLMM_BASE		IOMEM(0xF0004000)
 #define MSM_TLMM_PHYS		0x00800000
 #define MSM_TLMM_SIZE		SZ_16K
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/msm_iomap.h linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/msm_iomap.h
--- linux-libre-3.10-gnu/arch/arm/mach-msm/include/mach/msm_iomap.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/include/mach/msm_iomap.h	2013-08-25 20:43:22.000000000 -0400
@@ -62,8 +62,6 @@
 
 /* Virtual addresses shared across all MSM targets. */
 #define MSM_CSR_BASE		IOMEM(0xE0001000)
-#define MSM_QGIC_DIST_BASE	IOMEM(0xF0000000)
-#define MSM_QGIC_CPU_BASE	IOMEM(0xF0001000)
 #define MSM_TMR_BASE		IOMEM(0xF0200000)
 #define MSM_TMR0_BASE		IOMEM(0xF0201000)
 #define MSM_GPIO1_BASE		IOMEM(0xE0003000)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/io.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/io.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/io.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/io.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,8 +107,6 @@ void __init msm_map_qsd8x50_io(void)
 
 #ifdef CONFIG_ARCH_MSM8X60
 static struct map_desc msm8x60_io_desc[] __initdata = {
-	MSM_CHIP_DEVICE(QGIC_DIST, MSM8X60),
-	MSM_CHIP_DEVICE(QGIC_CPU, MSM8X60),
 	MSM_CHIP_DEVICE(TMR, MSM8X60),
 	MSM_CHIP_DEVICE(TMR0, MSM8X60),
 #ifdef CONFIG_DEBUG_MSM8660_UART
@@ -124,8 +122,6 @@ void __init msm_map_msm8x60_io(void)
 
 #ifdef CONFIG_ARCH_MSM8960
 static struct map_desc msm8960_io_desc[] __initdata = {
-	MSM_CHIP_DEVICE(QGIC_DIST, MSM8960),
-	MSM_CHIP_DEVICE(QGIC_CPU, MSM8960),
 	MSM_CHIP_DEVICE(TMR, MSM8960),
 	MSM_CHIP_DEVICE(TMR0, MSM8960),
 #ifdef CONFIG_DEBUG_MSM8960_UART
@@ -172,7 +168,7 @@ void __init msm_map_msm7x30_io(void)
 }
 #endif /* CONFIG_ARCH_MSM7X30 */
 
-void __iomem *__msm_ioremap_caller(unsigned long phys_addr, size_t size,
+void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size,
 				   unsigned int mtype, void *caller)
 {
 	if (mtype == MT_DEVICE) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-msm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -48,9 +48,7 @@ config ARCH_MSM8X60
 	select CPU_V7
 	select GPIO_MSM_V2
 	select HAVE_SMP
-	select MSM_GPIOMUX
 	select MSM_SCM if SMP
-	select MSM_V2_TLMM
 	select USE_OF
 
 config ARCH_MSM8960
@@ -58,9 +56,8 @@ config ARCH_MSM8960
 	select ARM_GIC
 	select CPU_V7
 	select HAVE_SMP
-	select MSM_GPIOMUX
+	select GPIO_MSM_V2
 	select MSM_SCM if SMP
-	select MSM_V2_TLMM
 	select USE_OF
 
 config MSM_HAS_DEBUG_UART_HS
@@ -125,9 +122,8 @@ config MSM_SMD
 
 config MSM_GPIOMUX
 	bool
-
-config MSM_V2_TLMM
-	bool
+	help
+	  Support for MSM V1 TLMM GPIOMUX architecture.
 
 config MSM_SCM
 	bool
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-msm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,16 +1,18 @@
 obj-y += io.o timer.o
 obj-y += clock.o
-obj-$(CONFIG_DEBUG_FS) += clock-debug.o
 
 obj-$(CONFIG_MSM_VIC) += irq-vic.o
 obj-$(CONFIG_MSM_IOMMU) += devices-iommu.o
 
-obj-$(CONFIG_ARCH_MSM7X00A) += dma.o irq.o
-obj-$(CONFIG_ARCH_MSM7X30) += dma.o
-obj-$(CONFIG_ARCH_QSD8X50) += dma.o sirc.o
+obj-$(CONFIG_ARCH_MSM7X00A) += irq.o
+obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
 
 obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o
 
+obj-$(CONFIG_ARCH_MSM7X00A) += dma.o
+obj-$(CONFIG_ARCH_MSM7X30) += dma.o
+obj-$(CONFIG_ARCH_QSD8X50) += dma.o
+
 obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
 obj-$(CONFIG_MSM_SMD) += last_radio_log.o
 obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
@@ -27,7 +29,5 @@ obj-$(CONFIG_ARCH_MSM7X30) += board-msm7
 obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
 obj-$(CONFIG_ARCH_MSM8X60) += board-dt-8660.o
 obj-$(CONFIG_ARCH_MSM8960) += board-dt-8960.o
-
-obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-v1.o gpiomux.o
-obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
-obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
+obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o
+obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,7 @@ static inline int get_core_count(void)
 	return ((read_cpuid_id() >> 4) & 3) + 1;
 }
 
-static void __cpuinit msm_secondary_init(unsigned int cpu)
+static void msm_secondary_init(unsigned int cpu)
 {
 	/*
 	 * let the primary processor know we're out of the
@@ -54,7 +54,7 @@ static void __cpuinit msm_secondary_init
 	spin_unlock(&boot_lock);
 }
 
-static __cpuinit void prepare_cold_cpu(unsigned int cpu)
+static void prepare_cold_cpu(unsigned int cpu)
 {
 	int ret;
 	ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
@@ -73,7 +73,7 @@ static __cpuinit void prepare_cold_cpu(u
 				  "address\n");
 }
 
-static int __cpuinit msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
 	static int cold_boot_done;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-msm/timer.c linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/timer.c
--- linux-libre-3.10-gnu/arch/arm/mach-msm/timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-msm/timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,10 +23,10 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/sched_clock.h>
 
 #include <asm/mach/time.h>
 #include <asm/localtimer.h>
-#include <asm/sched_clock.h>
 
 #include "common.h"
 
@@ -139,7 +139,7 @@ static struct clocksource msm_clocksourc
 };
 
 #ifdef CONFIG_LOCAL_TIMERS
-static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt)
+static int msm_local_timer_setup(struct clock_event_device *evt)
 {
 	/* Use existing clock_event for cpu 0 */
 	if (!smp_processor_id())
@@ -164,7 +164,7 @@ static void msm_local_timer_stop(struct
 	disable_percpu_irq(evt->irq);
 }
 
-static struct local_timer_ops msm_local_timer_ops __cpuinitdata = {
+static struct local_timer_ops msm_local_timer_ops = {
 	.setup	= msm_local_timer_setup,
 	.stop	= msm_local_timer_stop,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mv78xx0/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mv78xx0/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-mv78xx0/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mv78xx0/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -413,7 +413,7 @@ void __init mv78xx0_init(void)
 	clk_init();
 }
 
-void mv78xx0_restart(char mode, const char *cmd)
+void mv78xx0_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * Enable soft reset to assert RSTOUTn.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mv78xx0/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-mv78xx0/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-mv78xx0/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mv78xx0/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,8 @@
 #ifndef __ARCH_MV78XX0_COMMON_H
 #define __ARCH_MV78XX0_COMMON_H
 
+#include <linux/reboot.h>
+
 struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
 
@@ -45,7 +47,7 @@ void mv78xx0_uart1_init(void);
 void mv78xx0_uart2_init(void);
 void mv78xx0_uart3_init(void);
 void mv78xx0_i2c_init(void);
-void mv78xx0_restart(char, const char *);
+void mv78xx0_restart(enum reboot_mode, const char *);
 
 extern void mv78xx0_timer_init(void);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mvebu/armada-370-xp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/armada-370-xp.c
--- linux-libre-3.10-gnu/arch/arm/mach-mvebu/armada-370-xp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/armada-370-xp.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,13 +14,13 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/io.h>
 #include <linux/time-armada-370-xp.h>
-#include <linux/clk/mvebu.h>
 #include <linux/dma-mapping.h>
 #include <linux/mbus.h>
-#include <linux/irqchip.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -29,45 +29,49 @@
 #include "common.h"
 #include "coherency.h"
 
-static struct map_desc armada_370_xp_io_desc[] __initdata = {
-	{
-		.virtual	= (unsigned long) ARMADA_370_XP_REGS_VIRT_BASE,
-		.pfn		= __phys_to_pfn(ARMADA_370_XP_REGS_PHYS_BASE),
-		.length		= ARMADA_370_XP_REGS_SIZE,
-		.type		= MT_DEVICE,
-	},
-};
-
-void __init armada_370_xp_map_io(void)
+static void __init armada_370_xp_map_io(void)
 {
-	iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc));
+	debug_ll_io_init();
 }
 
-void __init armada_370_xp_timer_and_clk_init(void)
-{
-	mvebu_clocks_init();
-	armada_370_xp_timer_init();
-}
+/*
+ * This initialization will be replaced by a DT-based
+ * initialization once the mvebu-mbus driver gains DT support.
+ */
 
-void __init armada_370_xp_init_early(void)
+#define ARMADA_370_XP_MBUS_WINS_OFFS   0x20000
+#define ARMADA_370_XP_MBUS_WINS_SIZE   0x100
+#define ARMADA_370_XP_SDRAM_WINS_OFFS  0x20180
+#define ARMADA_370_XP_SDRAM_WINS_SIZE  0x20
+
+static void __init armada_370_xp_mbus_init(void)
 {
 	char *mbus_soc_name;
+	struct device_node *dn;
+	const __be32 mbus_wins_offs = cpu_to_be32(ARMADA_370_XP_MBUS_WINS_OFFS);
+	const __be32 sdram_wins_offs = cpu_to_be32(ARMADA_370_XP_SDRAM_WINS_OFFS);
 
-	/*
-	 * This initialization will be replaced by a DT-based
-	 * initialization once the mvebu-mbus driver gains DT support.
-	 */
 	if (of_machine_is_compatible("marvell,armada370"))
 		mbus_soc_name = "marvell,armada370-mbus";
 	else
 		mbus_soc_name = "marvell,armadaxp-mbus";
 
+	dn = of_find_node_by_name(NULL, "internal-regs");
+	BUG_ON(!dn);
+
 	mvebu_mbus_init(mbus_soc_name,
-			ARMADA_370_XP_MBUS_WINS_BASE,
+			of_translate_address(dn, &mbus_wins_offs),
 			ARMADA_370_XP_MBUS_WINS_SIZE,
-			ARMADA_370_XP_SDRAM_WINS_BASE,
+			of_translate_address(dn, &sdram_wins_offs),
 			ARMADA_370_XP_SDRAM_WINS_SIZE);
+}
 
+static void __init armada_370_xp_timer_and_clk_init(void)
+{
+	of_clk_init(NULL);
+	armada_370_xp_timer_init();
+	coherency_init();
+	armada_370_xp_mbus_init();
 #ifdef CONFIG_CACHE_L2X0
 	l2x0_of_init(0, ~0UL);
 #endif
@@ -76,7 +80,6 @@ void __init armada_370_xp_init_early(voi
 static void __init armada_370_xp_dt_init(void)
 {
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-	coherency_init();
 }
 
 static const char * const armada_370_xp_dt_compat[] = {
@@ -88,8 +91,6 @@ DT_MACHINE_START(ARMADA_XP_DT, "Marvell
 	.smp		= smp_ops(armada_xp_smp_ops),
 	.init_machine	= armada_370_xp_dt_init,
 	.map_io		= armada_370_xp_map_io,
-	.init_early	= armada_370_xp_init_early,
-	.init_irq	= irqchip_init,
 	.init_time	= armada_370_xp_timer_and_clk_init,
 	.restart	= mvebu_restart,
 	.dt_compat	= armada_370_xp_dt_compat,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mvebu/armada-370-xp.h linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/armada-370-xp.h
--- linux-libre-3.10-gnu/arch/arm/mach-mvebu/armada-370-xp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/armada-370-xp.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,16 +15,6 @@
 #ifndef __MACH_ARMADA_370_XP_H
 #define __MACH_ARMADA_370_XP_H
 
-#define ARMADA_370_XP_REGS_PHYS_BASE	0xd0000000
-#define ARMADA_370_XP_REGS_VIRT_BASE	IOMEM(0xfec00000)
-#define ARMADA_370_XP_REGS_SIZE		SZ_1M
-
-/* These defines can go away once mvebu-mbus has a DT binding */
-#define ARMADA_370_XP_MBUS_WINS_BASE    (ARMADA_370_XP_REGS_PHYS_BASE + 0x20000)
-#define ARMADA_370_XP_MBUS_WINS_SIZE    0x100
-#define ARMADA_370_XP_SDRAM_WINS_BASE   (ARMADA_370_XP_REGS_PHYS_BASE + 0x20180)
-#define ARMADA_370_XP_SDRAM_WINS_SIZE   0x20
-
 #ifdef CONFIG_SMP
 #include <linux/cpumask.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mvebu/coherency.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/coherency.c
--- linux-libre-3.10-gnu/arch/arm/mach-mvebu/coherency.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/coherency.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,16 +25,11 @@
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <asm/smp_plat.h>
+#include <asm/cacheflush.h>
 #include "armada-370-xp.h"
 
-/*
- * Some functions in this file are called very early during SMP
- * initialization. At that time the device tree framework is not yet
- * ready, and it is not possible to get the register address to
- * ioremap it. That's why the pointer below is given with an initial
- * value matching its virtual mapping
- */
-static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200;
+unsigned long coherency_phys_base;
+static void __iomem *coherency_base;
 static void __iomem *coherency_cpu_base;
 
 /* Coherency fabric registers */
@@ -47,18 +42,6 @@ static struct of_device_id of_coherency_
 	{ /* end of list */ },
 };
 
-#ifdef CONFIG_SMP
-int coherency_get_cpu_count(void)
-{
-	int reg, cnt;
-
-	reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET);
-	cnt = (reg & 0xF) + 1;
-
-	return cnt;
-}
-#endif
-
 /* Function defined in coherency_ll.S */
 int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id);
 
@@ -143,13 +126,31 @@ int __init coherency_init(void)
 
 	np = of_find_matching_node(NULL, of_coherency_table);
 	if (np) {
+		struct resource res;
 		pr_info("Initializing Coherency fabric\n");
+		of_address_to_resource(np, 0, &res);
+		coherency_phys_base = res.start;
+		/*
+		 * Ensure secondary CPUs will see the updated value,
+		 * which they read before they join the coherency
+		 * fabric, and therefore before they are coherent with
+		 * the boot CPU cache.
+		 */
+		sync_cache_w(&coherency_phys_base);
 		coherency_base = of_iomap(np, 0);
 		coherency_cpu_base = of_iomap(np, 1);
 		set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
-		bus_register_notifier(&platform_bus_type,
-					&mvebu_hwcc_platform_nb);
 	}
 
 	return 0;
 }
+
+static int __init coherency_late_init(void)
+{
+	if (of_find_matching_node(NULL, of_coherency_table))
+		bus_register_notifier(&platform_bus_type,
+				      &mvebu_hwcc_platform_nb);
+	return 0;
+}
+
+postcore_initcall(coherency_late_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mvebu/coherency.h linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/coherency.h
--- linux-libre-3.10-gnu/arch/arm/mach-mvebu/coherency.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/coherency.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
 #ifndef __MACH_370_XP_COHERENCY_H
 #define __MACH_370_XP_COHERENCY_H
 
-#ifdef CONFIG_SMP
-int coherency_get_cpu_count(void);
-#endif
-
 int set_cpu_coherent(int cpu_id, int smp_group_id);
 int coherency_init(void);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mvebu/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-mvebu/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,11 @@
 #ifndef __ARCH_MVEBU_COMMON_H
 #define __ARCH_MVEBU_COMMON_H
 
-void mvebu_restart(char mode, const char *cmd);
+#define ARMADA_XP_MAX_CPUS 4
+
+#include <linux/reboot.h>
+
+void mvebu_restart(enum reboot_mode mode, const char *cmd);
 
 void armada_370_xp_init_irq(void);
 void armada_370_xp_handle_irq(struct pt_regs *regs);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mvebu/headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/headsmp.S
--- linux-libre-3.10-gnu/arch/arm/mach-mvebu/headsmp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -22,28 +22,26 @@
 #include <linux/init.h>
 
 /*
- * At this stage the secondary CPUs don't have acces yet to the MMU, so
- * we have to provide physical addresses
- */
-#define ARMADA_XP_CFB_BASE	     0xD0020200
-
-	__CPUINIT
-
-/*
  * Armada XP specific entry point for secondary CPUs.
  * We add the CPU to the coherency fabric and then jump to secondary
  * startup
  */
 ENTRY(armada_xp_secondary_startup)
+	/* Get coherency fabric base physical address */
+	adr	r0, 1f
+	ldr	r1, [r0]
+	ldr	r0, [r0, r1]
 
 	/* Read CPU id */
 	mrc     p15, 0, r1, c0, c0, 5
 	and     r1, r1, #0xF
 
 	/* Add CPU to coherency fabric */
-	ldr     r0, =ARMADA_XP_CFB_BASE
-
 	bl	ll_set_cpu_coherent
 	b	secondary_startup
 
 ENDPROC(armada_xp_secondary_startup)
+
+	.align 2
+1:
+	.long	coherency_phys_base - .
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mvebu/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-mvebu/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -10,12 +10,11 @@ config ARCH_MVEBU
 	select PLAT_ORION
 	select SPARSE_IRQ
 	select CLKDEV_LOOKUP
-	select MVEBU_CLK_CORE
-	select MVEBU_CLK_CPU
-	select MVEBU_CLK_GATING
 	select MVEBU_MBUS
 	select ZONE_DMA if ARM_LPAE
 	select ARCH_REQUIRE_GPIOLIB
+	select MIGHT_HAVE_PCI
+	select PCI_QUIRKS if PCI
 
 if ARCH_MVEBU
 
@@ -30,6 +29,7 @@ config MACH_ARMADA_370_XP
 
 config MACH_ARMADA_370
 	bool "Marvell Armada 370 boards"
+	select ARMADA_370_CLK
 	select MACH_ARMADA_370_XP
 	select PINCTRL_ARMADA_370
 	help
@@ -38,6 +38,7 @@ config MACH_ARMADA_370
 
 config MACH_ARMADA_XP
 	bool "Marvell Armada XP boards"
+	select ARMADA_XP_CLK
 	select MACH_ARMADA_370_XP
 	select PINCTRL_ARMADA_XP
 	help
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mvebu/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-mvebu/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -71,13 +71,12 @@ void __init set_secondary_cpus_clock(voi
 	}
 }
 
-static void __cpuinit armada_xp_secondary_init(unsigned int cpu)
+static void armada_xp_secondary_init(unsigned int cpu)
 {
 	armada_xp_mpic_smp_cpu_init();
 }
 
-static int __cpuinit armada_xp_boot_secondary(unsigned int cpu,
-					      struct task_struct *idle)
+static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	pr_info("Booting CPU %d\n", cpu);
 
@@ -88,8 +87,16 @@ static int __cpuinit armada_xp_boot_seco
 
 static void __init armada_xp_smp_init_cpus(void)
 {
+	struct device_node *np;
 	unsigned int i, ncores;
-	ncores = coherency_get_cpu_count();
+
+	np = of_find_node_by_name(NULL, "cpus");
+	if (!np)
+		panic("No 'cpus' node found\n");
+
+	ncores = of_get_child_count(np);
+	if (ncores == 0 || ncores > ARMADA_XP_MAX_CPUS)
+		panic("Invalid number of CPUs in DT\n");
 
 	/* Limit possible CPUs to defconfig */
 	if (ncores > nr_cpu_ids) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mvebu/system-controller.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/system-controller.c
--- linux-libre-3.10-gnu/arch/arm/mach-mvebu/system-controller.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mvebu/system-controller.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/of_address.h>
 #include <linux/io.h>
+#include <linux/reboot.h>
 
 static void __iomem *system_controller_base;
 
@@ -63,7 +64,7 @@ static struct of_device_id of_system_con
 	{ /* end of list */ },
 };
 
-void mvebu_restart(char mode, const char *cmd)
+void mvebu_restart(enum reboot_mode mode, const char *cmd)
 {
 	if (!system_controller_base) {
 		pr_err("Cannot restart, system-controller not available: check the device tree\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mxs/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-mxs/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-mxs/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mxs/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,6 @@ config SOC_IMX23
 	select ARM_AMBA
 	select ARM_CPU_SUSPEND if PM
 	select CPU_ARM926T
-	select HAVE_PWM
 	select PINCTRL_IMX23
 
 config SOC_IMX28
@@ -11,8 +10,6 @@ config SOC_IMX28
 	select ARM_AMBA
 	select ARM_CPU_SUSPEND if PM
 	select CPU_ARM926T
-	select HAVE_CAN_FLEXCAN if CAN
-	select HAVE_PWM
 	select PINCTRL_IMX28
 
 config ARCH_MXS
@@ -25,6 +22,7 @@ config ARCH_MXS
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK_PREPARE
 	select PINCTRL
+	select SOC_BUS
 	select SOC_IMX23
 	select SOC_IMX28
 	select STMP_DEVICE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mxs/mach-mxs.c linux-libre-3.11-rc7-gnu/arch/arm/mach-mxs/mach-mxs.c
--- linux-libre-3.10-gnu/arch/arm/mach-mxs/mach-mxs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mxs/mach-mxs.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,18 +14,18 @@
 #include <linux/clk/mxs.h>
 #include <linux/clkdev.h>
 #include <linux/clocksource.h>
-#include <linux/can/platform/flexcan.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
-#include <linux/irqchip.h>
 #include <linux/irqchip/mxs.h>
+#include <linux/reboot.h>
 #include <linux/micrel_phy.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/phy.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/sys_soc.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -39,12 +39,28 @@
 #define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0		0x2
 #define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1		0x3
 
+#define HW_DIGCTL_CHIPID	0x310
+#define HW_DIGCTL_CHIPID_MASK	(0xffff << 16)
+#define HW_DIGCTL_REV_MASK	0xff
+#define HW_DIGCTL_CHIPID_MX23	(0x3780 << 16)
+#define HW_DIGCTL_CHIPID_MX28	(0x2800 << 16)
+
+#define MXS_CHIP_REVISION_1_0	0x10
+#define MXS_CHIP_REVISION_1_1	0x11
+#define MXS_CHIP_REVISION_1_2	0x12
+#define MXS_CHIP_REVISION_1_3	0x13
+#define MXS_CHIP_REVISION_1_4	0x14
+#define MXS_CHIP_REV_UNKNOWN	0xff
+
 #define MXS_GPIO_NR(bank, nr)	((bank) * 32 + (nr))
 
 #define MXS_SET_ADDR		0x4
 #define MXS_CLR_ADDR		0x8
 #define MXS_TOG_ADDR		0xc
 
+static u32 chipid;
+static u32 socid;
+
 static inline void __mxs_setl(u32 mask, void __iomem *reg)
 {
 	__raw_writel(mask, reg + MXS_SET_ADDR);
@@ -60,41 +76,6 @@ static inline void __mxs_togl(u32 mask,
 	__raw_writel(mask, reg + MXS_TOG_ADDR);
 }
 
-/*
- * MX28EVK_FLEXCAN_SWITCH is shared between both flexcan controllers
- */
-#define MX28EVK_FLEXCAN_SWITCH	MXS_GPIO_NR(2, 13)
-
-static int flexcan0_en, flexcan1_en;
-
-static void mx28evk_flexcan_switch(void)
-{
-	if (flexcan0_en || flexcan1_en)
-		gpio_set_value(MX28EVK_FLEXCAN_SWITCH, 1);
-	else
-		gpio_set_value(MX28EVK_FLEXCAN_SWITCH, 0);
-}
-
-static void mx28evk_flexcan0_switch(int enable)
-{
-	flexcan0_en = enable;
-	mx28evk_flexcan_switch();
-}
-
-static void mx28evk_flexcan1_switch(int enable)
-{
-	flexcan1_en = enable;
-	mx28evk_flexcan_switch();
-}
-
-static struct flexcan_platform_data flexcan_pdata[2];
-
-static struct of_dev_auxdata mxs_auxdata_lookup[] __initdata = {
-	OF_DEV_AUXDATA("fsl,imx28-flexcan", 0x80032000, NULL, &flexcan_pdata[0]),
-	OF_DEV_AUXDATA("fsl,imx28-flexcan", 0x80034000, NULL, &flexcan_pdata[1]),
-	{ /* sentinel */ }
-};
-
 #define OCOTP_WORD_OFFSET		0x20
 #define OCOTP_WORD_COUNT		0x20
 
@@ -254,15 +235,6 @@ static void __init imx28_evk_init(void)
 	mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
 }
 
-static void __init imx28_evk_post_init(void)
-{
-	if (!gpio_request_one(MX28EVK_FLEXCAN_SWITCH, GPIOF_DIR_OUT,
-			      "flexcan-switch")) {
-		flexcan_pdata[0].transceiver_switch = mx28evk_flexcan0_switch;
-		flexcan_pdata[1].transceiver_switch = mx28evk_flexcan1_switch;
-	}
-}
-
 static int apx4devkit_phy_fixup(struct phy_device *phy)
 {
 	phy->dev_flags |= MICREL_PHY_50MHZ_CLK;
@@ -352,35 +324,126 @@ static void __init tx28_post_init(void)
 	pinctrl_put(pctl);
 }
 
-static void __init cfa10049_init(void)
+static void __init crystalfontz_init(void)
 {
 	update_fec_mac_prop(OUI_CRYSTALFONTZ);
 }
 
-static void __init cfa10037_init(void)
+static const char __init *mxs_get_soc_id(void)
 {
-	update_fec_mac_prop(OUI_CRYSTALFONTZ);
+	struct device_node *np;
+	void __iomem *digctl_base;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx23-digctl");
+	digctl_base = of_iomap(np, 0);
+	WARN_ON(!digctl_base);
+
+	chipid = readl(digctl_base + HW_DIGCTL_CHIPID);
+	socid = chipid & HW_DIGCTL_CHIPID_MASK;
+
+	iounmap(digctl_base);
+	of_node_put(np);
+
+	switch (socid) {
+	case HW_DIGCTL_CHIPID_MX23:
+		return "i.MX23";
+	case HW_DIGCTL_CHIPID_MX28:
+		return "i.MX28";
+	default:
+		return "Unknown";
+	}
+}
+
+static u32 __init mxs_get_cpu_rev(void)
+{
+	u32 rev = chipid & HW_DIGCTL_REV_MASK;
+
+	switch (socid) {
+	case HW_DIGCTL_CHIPID_MX23:
+		switch (rev) {
+		case 0x0:
+			return MXS_CHIP_REVISION_1_0;
+		case 0x1:
+			return MXS_CHIP_REVISION_1_1;
+		case 0x2:
+			return MXS_CHIP_REVISION_1_2;
+		case 0x3:
+			return MXS_CHIP_REVISION_1_3;
+		case 0x4:
+			return MXS_CHIP_REVISION_1_4;
+		default:
+			return MXS_CHIP_REV_UNKNOWN;
+		}
+	case HW_DIGCTL_CHIPID_MX28:
+		switch (rev) {
+		case 0x0:
+			return MXS_CHIP_REVISION_1_1;
+		case 0x1:
+			return MXS_CHIP_REVISION_1_2;
+		default:
+			return MXS_CHIP_REV_UNKNOWN;
+		}
+	default:
+		return MXS_CHIP_REV_UNKNOWN;
+	}
+}
+
+static const char __init *mxs_get_revision(void)
+{
+	u32 rev = mxs_get_cpu_rev();
+
+	if (rev != MXS_CHIP_REV_UNKNOWN)
+		return kasprintf(GFP_KERNEL, "TO%d.%d", (rev >> 4) & 0xf,
+				rev & 0xf);
+	else
+		return kasprintf(GFP_KERNEL, "%s", "Unknown");
 }
 
 static void __init mxs_machine_init(void)
 {
+	struct device_node *root;
+	struct device *parent;
+	struct soc_device *soc_dev;
+	struct soc_device_attribute *soc_dev_attr;
+	int ret;
+
+	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+	if (!soc_dev_attr)
+		return;
+
+	root = of_find_node_by_path("/");
+	ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+	if (ret)
+		return;
+
+	soc_dev_attr->family = "Freescale MXS Family";
+	soc_dev_attr->soc_id = mxs_get_soc_id();
+	soc_dev_attr->revision = mxs_get_revision();
+
+	soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR(soc_dev)) {
+		kfree(soc_dev_attr->revision);
+		kfree(soc_dev_attr);
+		return;
+	}
+
+	parent = soc_device_to_device(soc_dev);
+
 	if (of_machine_is_compatible("fsl,imx28-evk"))
 		imx28_evk_init();
 	else if (of_machine_is_compatible("bluegiga,apx4devkit"))
 		apx4devkit_init();
-	else if (of_machine_is_compatible("crystalfontz,cfa10037"))
-		cfa10037_init();
-	else if (of_machine_is_compatible("crystalfontz,cfa10049"))
-		cfa10049_init();
+	else if (of_machine_is_compatible("crystalfontz,cfa10037") ||
+		 of_machine_is_compatible("crystalfontz,cfa10049") ||
+		 of_machine_is_compatible("crystalfontz,cfa10055") ||
+		 of_machine_is_compatible("crystalfontz,cfa10057"))
+		crystalfontz_init();
 
 	of_platform_populate(NULL, of_default_bus_match_table,
-			     mxs_auxdata_lookup, NULL);
+			     NULL, parent);
 
 	if (of_machine_is_compatible("karo,tx28"))
 		tx28_post_init();
-
-	if (of_machine_is_compatible("fsl,imx28-evk"))
-		imx28_evk_post_init();
 }
 
 #define MX23_CLKCTRL_RESET_OFFSET	0x120
@@ -390,7 +453,7 @@ static void __init mxs_machine_init(void
 /*
  * Reset the system. It is called by machine_restart().
  */
-static void mxs_restart(char mode, const char *cmd)
+static void mxs_restart(enum reboot_mode mode, const char *cmd)
 {
 	struct device_node *np;
 	void __iomem *reset_addr;
@@ -434,8 +497,6 @@ static const char *mxs_dt_compat[] __ini
 };
 
 DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)")
-	.map_io		= debug_ll_io_init,
-	.init_irq	= irqchip_init,
 	.handle_irq	= icoll_handle_irq,
 	.init_time	= mxs_timer_init,
 	.init_machine	= mxs_machine_init,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-mxs/pm.h linux-libre-3.11-rc7-gnu/arch/arm/mach-mxs/pm.h
--- linux-libre-3.10-gnu/arch/arm/mach-mxs/pm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-mxs/pm.h	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,10 @@
 #ifndef __ARCH_MXS_PM_H
 #define __ARCH_MXS_PM_H
 
+#ifdef CONFIG_PM
 void mxs_pm_init(void);
+#else
+#define mxs_pm_init NULL
+#endif
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-netx/generic.c linux-libre-3.11-rc7-gnu/arch/arm/mach-netx/generic.c
--- linux-libre-3.10-gnu/arch/arm/mach-netx/generic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-netx/generic.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/irqchip/arm-vic.h>
+#include <linux/reboot.h>
 #include <mach/hardware.h>
 #include <asm/mach/map.h>
 #include <mach/netx-regs.h>
@@ -187,7 +188,7 @@ static int __init netx_init(void)
 
 subsys_initcall(netx_init);
 
-void netx_restart(char mode, const char *cmd)
+void netx_restart(enum reboot_mode mode, const char *cmd)
 {
 	writel(NETX_SYSTEM_RES_CR_FIRMW_RES_EN | NETX_SYSTEM_RES_CR_FIRMW_RES,
 	       NETX_SYSTEM_RES_CR);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-netx/generic.h linux-libre-3.11-rc7-gnu/arch/arm/mach-netx/generic.h
--- linux-libre-3.10-gnu/arch/arm/mach-netx/generic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-netx/generic.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,8 +17,10 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/reboot.h>
+
 extern void __init netx_map_io(void);
 extern void __init netx_init_irq(void);
-extern void netx_restart(char, const char *);
+extern void netx_restart(enum reboot_mode, const char *);
 
 extern void netx_timer_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-nomadik/cpu-8815.c linux-libre-3.11-rc7-gnu/arch/arm/mach-nomadik/cpu-8815.c
--- linux-libre-3.10-gnu/arch/arm/mach-nomadik/cpu-8815.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-nomadik/cpu-8815.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,11 +25,8 @@
 #include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/dma-mapping.h>
-#include <linux/irqchip.h>
 #include <linux/platform_data/clk-nomadik.h>
-#include <linux/platform_data/pinctrl-nomadik.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/platform_data/clocksource-nomadik-mtu.h>
+#include <linux/clocksource.h>
 #include <linux/of_irq.h>
 #include <linux/of_gpio.h>
 #include <linux/of_address.h>
@@ -91,48 +88,6 @@
 #define NOMADIK_L2CC_BASE	0x10210000	/* L2 Cache controller */
 #define NOMADIK_UART1_VBASE	0xF01FB000
 
-static unsigned long out_low[] = { PIN_OUTPUT_LOW };
-static unsigned long out_high[] = { PIN_OUTPUT_HIGH };
-static unsigned long in_nopull[] = { PIN_INPUT_NOPULL };
-static unsigned long in_pullup[] = { PIN_INPUT_PULLUP };
-
-static struct pinctrl_map __initdata nhk8815_pinmap[] = {
-	PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-stn8815", "u0_a_1", "u0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("uart1", "pinctrl-stn8815", "u1_a_1", "u1"),
-	/* Hog in MMC/SD card mux */
-	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-stn8815", "mmcsd_a_1", "mmcsd"),
-	/* MCCLK */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO8_B10", out_low),
-	/* MCCMD */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO9_A10", in_pullup),
-	/* MCCMDDIR */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO10_C11", out_high),
-	/* MCDAT3-0 */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO11_B11", in_pullup),
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO12_A11", in_pullup),
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO13_C12", in_pullup),
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO14_B12", in_pullup),
-	/* MCDAT0DIR */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO15_A12", out_high),
-	/* MCDAT31DIR */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO16_C13", out_high),
-	/* MCMSFBCLK */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO24_C15", in_pullup),
-	/* CD input GPIO */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO111_H21", in_nopull),
-	/* CD bias drive */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO112_J21", out_low),
-	/* I2C0 */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO62_D3", in_pullup),
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO63_D2", in_pullup),
-	/* I2C1 */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO53_L4", in_pullup),
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO54_L3", in_pullup),
-	/* I2C2 */
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO73_C21", in_pullup),
-	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-stn8815", "GPIO74_C20", in_pullup),
-};
-
 /* This is needed for LL-debug/earlyprintk/debug-macro.S */
 static struct map_desc cpu8815_io_desc[] __initdata = {
 	{
@@ -148,7 +103,7 @@ static void __init cpu8815_map_io(void)
 	iotable_init(cpu8815_io_desc, ARRAY_SIZE(cpu8815_io_desc));
 }
 
-static void cpu8815_restart(char mode, const char *cmd)
+static void cpu8815_restart(enum reboot_mode mode, const char *cmd)
 {
 	void __iomem *srcbase = ioremap(NOMADIK_SRC_BASE, SZ_4K);
 
@@ -172,7 +127,7 @@ static void __init cpu8815_timer_init_of
 	/* We need this to be up now */
 	nomadik_clk_init();
 
-	mtu = of_find_node_by_path("/mtu0");
+	mtu = of_find_node_by_path("/mtu@101e2000");
 	if (!mtu)
 		return;
 	base = of_iomap(mtu, 0);
@@ -188,7 +143,7 @@ static void __init cpu8815_timer_init_of
 	src_cr |= SRC_CR_INIT_VAL;
 	writel(src_cr, base);
 
-	nmdk_timer_init(base, irq);
+	clocksource_of_init();
 }
 
 static struct fsmc_nand_timings cpu8815_nand_timings = {
@@ -280,28 +235,10 @@ device_initcall(cpu8815_mmcsd_init);
 
 /* These are mostly to get the right device names for the clock lookups */
 static struct of_dev_auxdata cpu8815_auxdata_lookup[] __initdata = {
-	OF_DEV_AUXDATA("st,nomadik-gpio", NOMADIK_GPIO0_BASE,
-		"gpio.0", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", NOMADIK_GPIO1_BASE,
-		"gpio.1", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", NOMADIK_GPIO2_BASE,
-		"gpio.2", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", NOMADIK_GPIO3_BASE,
-		"gpio.3", NULL),
-	OF_DEV_AUXDATA("stericsson,nmk-pinctrl-stn8815", 0,
-		"pinctrl-stn8815", NULL),
-	OF_DEV_AUXDATA("arm,primecell", NOMADIK_UART0_BASE,
-		"uart0", NULL),
-	OF_DEV_AUXDATA("arm,primecell", NOMADIK_UART1_BASE,
-		"uart1", NULL),
-	OF_DEV_AUXDATA("arm,primecell", NOMADIK_RNG_BASE,
-		"rng", NULL),
-	OF_DEV_AUXDATA("arm,primecell", NOMADIK_RTC_BASE,
-		"rtc-pl031", NULL),
 	OF_DEV_AUXDATA("stericsson,fsmc-nand", NOMADIK_FSMC_BASE,
-		"fsmc-nand", &cpu8815_nand_data),
+		NULL, &cpu8815_nand_data),
 	OF_DEV_AUXDATA("arm,primecell", NOMADIK_SDI_BASE,
-		"mmci", &mmcsd_plat_data),
+		NULL, &mmcsd_plat_data),
 	{ /* sentinel */ },
 };
 
@@ -311,7 +248,6 @@ static void __init cpu8815_init_of(void)
 	/* At full speed latency must be >=2, so 0x249 in low bits */
 	l2x0_of_init(0x00730249, 0xfe000fff);
 #endif
-	pinctrl_register_mappings(nhk8815_pinmap, ARRAY_SIZE(nhk8815_pinmap));
 	of_platform_populate(NULL, of_default_bus_match_table,
 			cpu8815_auxdata_lookup, NULL);
 }
@@ -323,7 +259,6 @@ static const char * cpu8815_board_compat
 
 DT_MACHINE_START(NOMADIK_DT, "Nomadik STn8815")
 	.map_io		= cpu8815_map_io,
-	.init_irq	= irqchip_init,
 	.init_time	= cpu8815_timer_init_of,
 	.init_machine	= cpu8815_init_of,
 	.restart	= cpu8815_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-nomadik/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-nomadik/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-nomadik/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-nomadik/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -6,6 +6,7 @@ config ARCH_NOMADIK
 	select ARM_VIC
 	select CLKSRC_NOMADIK_MTU
 	select CLKSRC_NOMADIK_MTU_SCHED_CLOCK
+	select CLKSRC_OF
 	select COMMON_CLK
 	select CPU_ARM926T
 	select GENERIC_CLOCKEVENTS
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-nspire/clcd.c linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/clcd.c
--- linux-libre-3.10-gnu/arch/arm/mach-nspire/clcd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/clcd.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,119 @@
+/*
+ *	linux/arch/arm/mach-nspire/clcd.c
+ *
+ *	Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/dma-mapping.h>
+
+static struct clcd_panel nspire_cx_lcd_panel = {
+	.mode		= {
+		.name		= "Color LCD",
+		.refresh	= 60,
+		.xres		= 320,
+		.yres		= 240,
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.pixclock	= 1,
+		.hsync_len	= 6,
+		.vsync_len	= 1,
+		.right_margin	= 50,
+		.left_margin	= 38,
+		.lower_margin	= 3,
+		.upper_margin	= 17,
+	},
+	.width		= 65, /* ~6.50 cm */
+	.height		= 49, /* ~4.87 cm */
+	.tim2		= TIM2_IPC,
+	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+	.bpp		= 16,
+	.caps		= CLCD_CAP_565,
+};
+
+static struct clcd_panel nspire_classic_lcd_panel = {
+	.mode		= {
+		.name		= "Grayscale LCD",
+		.refresh	= 60,
+		.xres		= 320,
+		.yres		= 240,
+		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.pixclock	= 1,
+		.hsync_len	= 6,
+		.vsync_len	= 1,
+		.right_margin	= 6,
+		.left_margin	= 6,
+	},
+	.width		= 71, /* 7.11cm */
+	.height		= 53, /* 5.33cm */
+	.tim2		= 0x80007d0,
+	.cntl		= CNTL_LCDMONO8,
+	.bpp		= 8,
+	.grayscale	= 1,
+	.caps		= CLCD_CAP_5551,
+};
+
+int nspire_clcd_setup(struct clcd_fb *fb)
+{
+	struct clcd_panel *panel;
+	size_t panel_size;
+	const char *type;
+	dma_addr_t dma;
+	int err;
+
+	BUG_ON(!fb->dev->dev.of_node);
+
+	err = of_property_read_string(fb->dev->dev.of_node, "lcd-type", &type);
+	if (err) {
+		pr_err("CLCD: Could not find lcd-type property\n");
+		return err;
+	}
+
+	if (!strcmp(type, "cx")) {
+		panel = &nspire_cx_lcd_panel;
+	} else if (!strcmp(type, "classic")) {
+		panel = &nspire_classic_lcd_panel;
+	} else {
+		pr_err("CLCD: Unknown lcd-type %s\n", type);
+		return -EINVAL;
+	}
+
+	panel_size = ((panel->mode.xres * panel->mode.yres) * panel->bpp) / 8;
+	panel_size = ALIGN(panel_size, PAGE_SIZE);
+
+	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev,
+		panel_size, &dma, GFP_KERNEL);
+
+	if (!fb->fb.screen_base) {
+		pr_err("CLCD: unable to map framebuffer\n");
+		return -ENOMEM;
+	}
+
+	fb->fb.fix.smem_start = dma;
+	fb->fb.fix.smem_len = panel_size;
+	fb->panel = panel;
+
+	return 0;
+}
+
+int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma,
+		fb->fb.screen_base, fb->fb.fix.smem_start,
+		fb->fb.fix.smem_len);
+}
+
+void nspire_clcd_remove(struct clcd_fb *fb)
+{
+	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+		fb->fb.screen_base, fb->fb.fix.smem_start);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-nspire/clcd.h linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/clcd.h
--- linux-libre-3.10-gnu/arch/arm/mach-nspire/clcd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/clcd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,14 @@
+/*
+ *	linux/arch/arm/mach-nspire/clcd.h
+ *
+ *	Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+int nspire_clcd_setup(struct clcd_fb *fb);
+int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma);
+void nspire_clcd_remove(struct clcd_fb *fb);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-nspire/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-nspire/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,16 @@
+config ARCH_NSPIRE
+	bool "TI-NSPIRE based"
+	depends on ARCH_MULTI_V4_V5
+	depends on MMU
+	select CPU_ARM926T
+	select COMMON_CLK
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_IRQ_CHIP
+	select SPARSE_IRQ
+	select ARM_AMBA
+	select ARM_VIC
+	select ARM_TIMER_SP804
+	select USE_OF
+	select CLKSRC_OF
+	help
+	  This enables support for systems using the TI-NSPIRE CPU
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-nspire/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-nspire/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2 @@
+obj-y				+= nspire.o
+obj-y				+= clcd.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-nspire/mmio.h linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/mmio.h
--- linux-libre-3.10-gnu/arch/arm/mach-nspire/mmio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/mmio.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ *	linux/arch/arm/mach-nspire/mmio.h
+ *
+ *	Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define NSPIRE_MISC_PHYS_BASE		0x900A0000
+#define NSPIRE_MISC_HWRESET		0x08
+
+#define NSPIRE_PWR_PHYS_BASE		0x900B0000
+#define NSPIRE_PWR_VIRT_BASE		0xFEEB0000
+#define NSPIRE_PWR_BUS_DISABLE1		0x18
+#define NSPIRE_PWR_BUS_DISABLE2		0x20
+
+#define NSPIRE_LCD_PHYS_BASE		0xC0000000
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-nspire/nspire.c linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/nspire.c
--- linux-libre-3.10-gnu/arch/arm/mach-nspire/nspire.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-nspire/nspire.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,89 @@
+/*
+ *	linux/arch/arm/mach-nspire/nspire.c
+ *
+ *	Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/init.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-vic.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/clocksource.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/hardware/timer-sp.h>
+
+#include "mmio.h"
+#include "clcd.h"
+
+static const char *nspire_dt_match[] __initconst = {
+	"ti,nspire",
+	"ti,nspire-cx",
+	"ti,nspire-tp",
+	"ti,nspire-clp",
+	NULL,
+};
+
+static void __init nspire_map_io(void)
+{
+	debug_ll_io_init();
+}
+
+static struct clcd_board nspire_clcd_data = {
+	.name		= "LCD",
+	.caps		= CLCD_CAP_5551 | CLCD_CAP_565,
+	.check		= clcdfb_check,
+	.decode		= clcdfb_decode,
+	.setup		= nspire_clcd_setup,
+	.mmap		= nspire_clcd_mmap,
+	.remove		= nspire_clcd_remove,
+};
+
+
+static struct of_dev_auxdata nspire_auxdata[] __initdata = {
+	OF_DEV_AUXDATA("arm,pl111", NSPIRE_LCD_PHYS_BASE,
+			NULL, &nspire_clcd_data),
+	{ }
+};
+
+static void __init nspire_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table,
+			nspire_auxdata, NULL);
+}
+
+static void __init nspire_init_time(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+}
+
+static void nspire_restart(char mode, const char *cmd)
+{
+	void __iomem *base = ioremap(NSPIRE_MISC_PHYS_BASE, SZ_4K);
+	if (!base)
+		return;
+
+	writel(2, base + NSPIRE_MISC_HWRESET);
+}
+
+DT_MACHINE_START(NSPIRE, "TI-NSPIRE")
+	.dt_compat	= nspire_dt_match,
+	.map_io		= nspire_map_io,
+	.init_time	= nspire_init_time,
+	.init_machine	= nspire_init,
+	.restart	= nspire_restart,
+MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/board-h2.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-h2.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/board-h2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-h2.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,7 +41,6 @@
 #include <mach/mux.h>
 #include <linux/omap-dma.h>
 #include <mach/tc.h>
-#include <mach/irda.h>
 #include <linux/platform_data/keypad-omap.h>
 #include <mach/flash.h>
 
@@ -50,7 +49,6 @@
 
 #include "common.h"
 #include "board-h2.h"
-#include "dma.h"
 
 /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
 #define OMAP1610_ETHR_START		0x04000300
@@ -276,39 +274,6 @@ static struct platform_device h2_kp_devi
 	.resource	= h2_kp_resources,
 };
 
-#define H2_IRDA_FIRSEL_GPIO_PIN	17
-
-static struct omap_irda_config h2_irda_data = {
-	.transceiver_cap	= IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
-	.rx_channel		= OMAP_DMA_UART3_RX,
-	.tx_channel		= OMAP_DMA_UART3_TX,
-	.dest_start		= UART3_THR,
-	.src_start		= UART3_RHR,
-	.tx_trigger		= 0,
-	.rx_trigger		= 0,
-};
-
-static struct resource h2_irda_resources[] = {
-	[0] = {
-		.start	= INT_UART3,
-		.end	= INT_UART3,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static u64 irda_dmamask = 0xffffffff;
-
-static struct platform_device h2_irda_device = {
-	.name		= "omapirda",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &h2_irda_data,
-		.dma_mask	= &irda_dmamask,
-	},
-	.num_resources	= ARRAY_SIZE(h2_irda_resources),
-	.resource	= h2_irda_resources,
-};
-
 static struct gpio_led h2_gpio_led_pins[] = {
 	{
 		.name		= "h2:red",
@@ -339,7 +304,6 @@ static struct platform_device *h2_device
 	&h2_nor_device,
 	&h2_nand_device,
 	&h2_smc91x_device,
-	&h2_irda_device,
 	&h2_kp_device,
 	&h2_gpio_leds,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/board-nokia770.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-nokia770.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/board-nokia770.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-nokia770.c	2013-08-25 20:43:22.000000000 -0400
@@ -234,16 +234,26 @@ static struct i2c_board_info nokia770_i2
 	{
 		I2C_BOARD_INFO("retu-mfd", 0x01),
 	},
+	{
+		I2C_BOARD_INFO("tahvo-mfd", 0x02),
+	},
 };
 
 static void __init nokia770_cbus_init(void)
 {
 	const int retu_irq_gpio = 62;
+	const int tahvo_irq_gpio = 40;
 
 	if (gpio_request_one(retu_irq_gpio, GPIOF_IN, "Retu IRQ"))
 		return;
+	if (gpio_request_one(tahvo_irq_gpio, GPIOF_IN, "Tahvo IRQ")) {
+		gpio_free(retu_irq_gpio);
+		return;
+	}
 	irq_set_irq_type(gpio_to_irq(retu_irq_gpio), IRQ_TYPE_EDGE_RISING);
+	irq_set_irq_type(gpio_to_irq(tahvo_irq_gpio), IRQ_TYPE_EDGE_RISING);
 	nokia770_i2c_board_info_2[0].irq = gpio_to_irq(retu_irq_gpio);
+	nokia770_i2c_board_info_2[1].irq = gpio_to_irq(tahvo_irq_gpio);
 	i2c_register_board_info(2, nokia770_i2c_board_info_2,
 				ARRAY_SIZE(nokia770_i2c_board_info_2));
 	platform_device_register(&nokia770_cbus_device);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/board-palmte.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-palmte.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/board-palmte.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-palmte.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,14 +38,12 @@
 #include <mach/mux.h>
 #include <mach/tc.h>
 #include <linux/omap-dma.h>
-#include <mach/irda.h>
 #include <linux/platform_data/keypad-omap.h>
 
 #include <mach/hardware.h>
 #include <mach/usb.h>
 
 #include "common.h"
-#include "dma.h"
 
 #define PALMTE_USBDETECT_GPIO	0
 #define PALMTE_USB_OR_DC_GPIO	1
@@ -167,40 +165,11 @@ static struct platform_device palmte_bac
 	},
 };
 
-static struct omap_irda_config palmte_irda_config = {
-	.transceiver_cap	= IR_SIRMODE,
-	.rx_channel		= OMAP_DMA_UART3_RX,
-	.tx_channel		= OMAP_DMA_UART3_TX,
-	.dest_start		= UART3_THR,
-	.src_start		= UART3_RHR,
-	.tx_trigger		= 0,
-	.rx_trigger		= 0,
-};
-
-static struct resource palmte_irda_resources[] = {
-	[0]	= {
-		.start	= INT_UART3,
-		.end	= INT_UART3,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device palmte_irda_device = {
-	.name		= "omapirda",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &palmte_irda_config,
-	},
-	.num_resources	= ARRAY_SIZE(palmte_irda_resources),
-	.resource	= palmte_irda_resources,
-};
-
 static struct platform_device *palmte_devices[] __initdata = {
 	&palmte_rom_device,
 	&palmte_kp_device,
 	&palmte_lcd_device,
 	&palmte_backlight_device,
-	&palmte_irda_device,
 };
 
 static struct omap_usb_config palmte_usb_config __initdata = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/board-palmtt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-palmtt.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/board-palmtt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-palmtt.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,14 +38,12 @@
 #include <mach/mux.h>
 #include <linux/omap-dma.h>
 #include <mach/tc.h>
-#include <mach/irda.h>
 #include <linux/platform_data/keypad-omap.h>
 
 #include <mach/hardware.h>
 #include <mach/usb.h>
 
 #include "common.h"
-#include "dma.h"
 
 #define PALMTT_USBDETECT_GPIO	0
 #define PALMTT_CABLE_GPIO	1
@@ -163,33 +161,6 @@ static struct platform_device palmtt_lcd
 	.name		= "lcd_palmtt",
 	.id		= -1,
 };
-static struct omap_irda_config palmtt_irda_config = {
-	.transceiver_cap	= IR_SIRMODE,
-	.rx_channel		= OMAP_DMA_UART3_RX,
-	.tx_channel		= OMAP_DMA_UART3_TX,
-	.dest_start		= UART3_THR,
-	.src_start		= UART3_RHR,
-	.tx_trigger		= 0,
-	.rx_trigger		= 0,
-};
-
-static struct resource palmtt_irda_resources[] = {
-	[0]	= {
-		.start	= INT_UART3,
-		.end	= INT_UART3,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device palmtt_irda_device = {
-	.name		= "omapirda",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &palmtt_irda_config,
-	},
-	.num_resources	= ARRAY_SIZE(palmtt_irda_resources),
-	.resource	= palmtt_irda_resources,
-};
 
 static struct platform_device palmtt_spi_device = {
 	.name		= "spi_palmtt",
@@ -234,7 +205,6 @@ static struct platform_device *palmtt_de
 	&palmtt_flash_device,
 	&palmtt_kp_device,
 	&palmtt_lcd_device,
-	&palmtt_irda_device,
 	&palmtt_spi_device,
 	&palmtt_backlight_device,
 	&palmtt_led_device,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/board-palmz71.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-palmz71.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/board-palmz71.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-palmz71.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,14 +40,12 @@
 #include <mach/mux.h>
 #include <linux/omap-dma.h>
 #include <mach/tc.h>
-#include <mach/irda.h>
 #include <linux/platform_data/keypad-omap.h>
 
 #include <mach/hardware.h>
 #include <mach/usb.h>
 
 #include "common.h"
-#include "dma.h"
 
 #define PALMZ71_USBDETECT_GPIO	0
 #define PALMZ71_PENIRQ_GPIO	6
@@ -153,34 +151,6 @@ static struct platform_device palmz71_lc
 	.id	= -1,
 };
 
-static struct omap_irda_config palmz71_irda_config = {
-	.transceiver_cap	= IR_SIRMODE,
-	.rx_channel		= OMAP_DMA_UART3_RX,
-	.tx_channel		= OMAP_DMA_UART3_TX,
-	.dest_start		= UART3_THR,
-	.src_start		= UART3_RHR,
-	.tx_trigger		= 0,
-	.rx_trigger		= 0,
-};
-
-static struct resource palmz71_irda_resources[] = {
-	[0] = {
-		.start	= INT_UART3,
-		.end	= INT_UART3,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device palmz71_irda_device = {
-	.name	= "omapirda",
-	.id	= -1,
-	.dev = {
-		.platform_data = &palmz71_irda_config,
-	},
-	.num_resources	= ARRAY_SIZE(palmz71_irda_resources),
-	.resource	= palmz71_irda_resources,
-};
-
 static struct platform_device palmz71_spi_device = {
 	.name	= "spi_palmz71",
 	.id	= -1,
@@ -202,7 +172,6 @@ static struct platform_device *devices[]
 	&palmz71_rom_device,
 	&palmz71_kp_device,
 	&palmz71_lcd_device,
-	&palmz71_irda_device,
 	&palmz71_spi_device,
 	&palmz71_backlight_device,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/board-sx1.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-sx1.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/board-sx1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-sx1.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,6 @@
 #include <mach/flash.h>
 #include <mach/mux.h>
 #include <linux/omap-dma.h>
-#include <mach/irda.h>
 #include <mach/tc.h>
 #include <mach/board-sx1.h>
 
@@ -45,7 +44,6 @@
 #include <mach/usb.h>
 
 #include "common.h"
-#include "dma.h"
 
 /* Write to I2C device */
 int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
@@ -228,39 +226,6 @@ static struct platform_device sx1_kp_dev
 	.resource	= sx1_kp_resources,
 };
 
-/*----------- IRDA -------------------------*/
-
-static struct omap_irda_config sx1_irda_data = {
-	.transceiver_cap	= IR_SIRMODE,
-	.rx_channel		= OMAP_DMA_UART3_RX,
-	.tx_channel		= OMAP_DMA_UART3_TX,
-	.dest_start		= UART3_THR,
-	.src_start		= UART3_RHR,
-	.tx_trigger		= 0,
-	.rx_trigger		= 0,
-};
-
-static struct resource sx1_irda_resources[] = {
-	[0] = {
-		.start	= INT_UART3,
-		.end	= INT_UART3,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static u64 irda_dmamask = 0xffffffff;
-
-static struct platform_device sx1_irda_device = {
-	.name		= "omapirda",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &sx1_irda_data,
-		.dma_mask	= &irda_dmamask,
-	},
-	.num_resources	= ARRAY_SIZE(sx1_irda_resources),
-	.resource	= sx1_irda_resources,
-};
-
 /*----------- MTD -------------------------*/
 
 static struct mtd_partition sx1_partitions[] = {
@@ -366,7 +331,6 @@ static struct omap_lcd_config sx1_lcd_co
 static struct platform_device *sx1_devices[] __initdata = {
 	&sx1_flash_device,
 	&sx1_kp_device,
-	&sx1_irda_device,
 };
 
 /*-----------------------------------------*/
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/board-voiceblue.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-voiceblue.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/board-voiceblue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/board-voiceblue.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/serial_reg.h>
 #include <linux/smc91x.h>
 #include <linux/export.h>
+#include <linux/reboot.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -215,7 +216,7 @@ void voiceblue_wdt_ping(void)
 	gpio_set_value(0, wdt_gpio_state);
 }
 
-static void voiceblue_restart(char mode, const char *cmd)
+static void voiceblue_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/mtd/mtd.h>
 #include <linux/i2c-omap.h>
+#include <linux/reboot.h>
 
 #include <plat/i2c.h>
 
@@ -70,7 +71,7 @@ static inline int omap_serial_wakeup_ini
 void omap1_init_early(void);
 void omap1_init_irq(void);
 void omap1_init_late(void);
-void omap1_restart(char, const char *);
+void omap1_restart(enum reboot_mode, const char *);
 
 extern void __init omap_check_revision(void);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/devices.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/devices.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/devices.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/devices.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,6 @@
 
 #include "common.h"
 #include "clock.h"
-#include "dma.h"
 #include "mmc.h"
 #include "sram.h"
 
@@ -223,16 +222,16 @@ void __init omap1_init_mmc(struct omap_m
 		case 0:
 			base = OMAP1_MMC1_BASE;
 			irq = INT_MMC;
-			rx_req = OMAP_DMA_MMC_RX;
-			tx_req = OMAP_DMA_MMC_TX;
+			rx_req = 22;
+			tx_req = 21;
 			break;
 		case 1:
 			if (!cpu_is_omap16xx())
 				return;
 			base = OMAP1_MMC2_BASE;
 			irq = INT_1610_MMC2;
-			rx_req = OMAP_DMA_MMC2_RX;
-			tx_req = OMAP_DMA_MMC2_TX;
+			rx_req = 55;
+			tx_req = 54;
 			break;
 		default:
 			continue;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/dma.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/dma.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,8 +30,6 @@
 
 #include <mach/irqs.h>
 
-#include "dma.h"
-
 #define OMAP1_DMA_BASE			(0xfffed800)
 #define OMAP1_LOGICAL_DMA_CH_COUNT	17
 #define OMAP1_DMA_STRIDE		0x40
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/dma.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/dma.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/dma.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/dma.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,42 +0,0 @@
-/*
- *  OMAP1 DMA channel definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __OMAP1_DMA_CHANNEL_H
-#define __OMAP1_DMA_CHANNEL_H
-
-/* DMA channels for omap1 */
-#define OMAP_DMA_NO_DEVICE		0
-#define OMAP_DMA_MCBSP1_TX		8
-#define OMAP_DMA_MCBSP1_RX		9
-#define OMAP_DMA_MCBSP3_TX		10
-#define OMAP_DMA_MCBSP3_RX		11
-#define OMAP_DMA_MCBSP2_TX		16
-#define OMAP_DMA_MCBSP2_RX		17
-#define OMAP_DMA_UART3_TX		18
-#define OMAP_DMA_UART3_RX		19
-#define OMAP_DMA_CAMERA_IF_RX		20
-#define OMAP_DMA_MMC_TX			21
-#define OMAP_DMA_MMC_RX			22
-#define OMAP_DMA_USB_W2FC_RX0		26
-#define OMAP_DMA_USB_W2FC_TX0		29
-
-/* These are only for 1610 */
-#define OMAP_DMA_MMC2_TX		54
-#define OMAP_DMA_MMC2_RX		55
-
-#endif /* __OMAP1_DMA_CHANNEL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/include/mach/irda.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/include/mach/irda.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/include/mach/irda.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/include/mach/irda.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/*
- *  arch/arm/plat-omap/include/mach/irda.h
- *
- *  Copyright (C) 2005-2006 Komal Shah <komal_shah802003@yahoo.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef ASMARM_ARCH_IRDA_H
-#define ASMARM_ARCH_IRDA_H
-
-/* board specific transceiver capabilities */
-
-#define IR_SEL		1	/* Selects IrDA */
-#define IR_SIRMODE	2
-#define IR_FIRMODE	4
-#define IR_MIRMODE	8
-
-struct omap_irda_config {
-	int transceiver_cap;
-	int (*transceiver_mode)(struct device *dev, int mode);
-	int (*select_irda)(struct device *dev, int state);
-	int rx_channel;
-	int tx_channel;
-	unsigned long dest_start;
-	unsigned long src_start;
-	int tx_trigger;
-	int rx_trigger;
-	int mode;
-};
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/lcd_dma.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/lcd_dma.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/lcd_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/lcd_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,8 +32,6 @@
 #include <mach/hardware.h>
 #include <mach/lcdc.h>
 
-#include "dma.h"
-
 int omap_lcd_dma_running(void)
 {
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/mailbox.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/mailbox.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/mailbox.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/mailbox.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,199 +0,0 @@
-/*
- * Mailbox reservation modules for OMAP1
- *
- * Copyright (C) 2006-2009 Nokia Corporation
- * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <plat/mailbox.h>
-
-#define MAILBOX_ARM2DSP1		0x00
-#define MAILBOX_ARM2DSP1b		0x04
-#define MAILBOX_DSP2ARM1		0x08
-#define MAILBOX_DSP2ARM1b		0x0c
-#define MAILBOX_DSP2ARM2		0x10
-#define MAILBOX_DSP2ARM2b		0x14
-#define MAILBOX_ARM2DSP1_Flag		0x18
-#define MAILBOX_DSP2ARM1_Flag		0x1c
-#define MAILBOX_DSP2ARM2_Flag		0x20
-
-static void __iomem *mbox_base;
-
-struct omap_mbox1_fifo {
-	unsigned long cmd;
-	unsigned long data;
-	unsigned long flag;
-};
-
-struct omap_mbox1_priv {
-	struct omap_mbox1_fifo tx_fifo;
-	struct omap_mbox1_fifo rx_fifo;
-};
-
-static inline int mbox_read_reg(size_t ofs)
-{
-	return __raw_readw(mbox_base + ofs);
-}
-
-static inline void mbox_write_reg(u32 val, size_t ofs)
-{
-	__raw_writew(val, mbox_base + ofs);
-}
-
-/* msg */
-static mbox_msg_t omap1_mbox_fifo_read(struct omap_mbox *mbox)
-{
-	struct omap_mbox1_fifo *fifo =
-		&((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
-	mbox_msg_t msg;
-
-	msg = mbox_read_reg(fifo->data);
-	msg |= ((mbox_msg_t) mbox_read_reg(fifo->cmd)) << 16;
-
-	return msg;
-}
-
-static void
-omap1_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
-{
-	struct omap_mbox1_fifo *fifo =
-		&((struct omap_mbox1_priv *)mbox->priv)->tx_fifo;
-
-	mbox_write_reg(msg & 0xffff, fifo->data);
-	mbox_write_reg(msg >> 16, fifo->cmd);
-}
-
-static int omap1_mbox_fifo_empty(struct omap_mbox *mbox)
-{
-	return 0;
-}
-
-static int omap1_mbox_fifo_full(struct omap_mbox *mbox)
-{
-	struct omap_mbox1_fifo *fifo =
-		&((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
-
-	return mbox_read_reg(fifo->flag);
-}
-
-/* irq */
-static void
-omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
-{
-	if (irq == IRQ_RX)
-		enable_irq(mbox->irq);
-}
-
-static void
-omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
-{
-	if (irq == IRQ_RX)
-		disable_irq(mbox->irq);
-}
-
-static int
-omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
-{
-	if (irq == IRQ_TX)
-		return 0;
-	return 1;
-}
-
-static struct omap_mbox_ops omap1_mbox_ops = {
-	.type		= OMAP_MBOX_TYPE1,
-	.fifo_read	= omap1_mbox_fifo_read,
-	.fifo_write	= omap1_mbox_fifo_write,
-	.fifo_empty	= omap1_mbox_fifo_empty,
-	.fifo_full	= omap1_mbox_fifo_full,
-	.enable_irq	= omap1_mbox_enable_irq,
-	.disable_irq	= omap1_mbox_disable_irq,
-	.is_irq		= omap1_mbox_is_irq,
-};
-
-/* FIXME: the following struct should be created automatically by the user id */
-
-/* DSP */
-static struct omap_mbox1_priv omap1_mbox_dsp_priv = {
-	.tx_fifo = {
-		.cmd	= MAILBOX_ARM2DSP1b,
-		.data	= MAILBOX_ARM2DSP1,
-		.flag	= MAILBOX_ARM2DSP1_Flag,
-	},
-	.rx_fifo = {
-		.cmd	= MAILBOX_DSP2ARM1b,
-		.data	= MAILBOX_DSP2ARM1,
-		.flag	= MAILBOX_DSP2ARM1_Flag,
-	},
-};
-
-static struct omap_mbox mbox_dsp_info = {
-	.name	= "dsp",
-	.ops	= &omap1_mbox_ops,
-	.priv	= &omap1_mbox_dsp_priv,
-};
-
-static struct omap_mbox *omap1_mboxes[] = { &mbox_dsp_info, NULL };
-
-static int omap1_mbox_probe(struct platform_device *pdev)
-{
-	struct resource *mem;
-	int ret;
-	struct omap_mbox **list;
-
-	list = omap1_mboxes;
-	list[0]->irq = platform_get_irq_byname(pdev, "dsp");
-
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mbox_base = ioremap(mem->start, resource_size(mem));
-	if (!mbox_base)
-		return -ENOMEM;
-
-	ret = omap_mbox_register(&pdev->dev, list);
-	if (ret) {
-		iounmap(mbox_base);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int omap1_mbox_remove(struct platform_device *pdev)
-{
-	omap_mbox_unregister();
-	iounmap(mbox_base);
-	return 0;
-}
-
-static struct platform_driver omap1_mbox_driver = {
-	.probe	= omap1_mbox_probe,
-	.remove	= omap1_mbox_remove,
-	.driver	= {
-		.name	= "omap-mailbox",
-	},
-};
-
-static int __init omap1_mbox_init(void)
-{
-	return platform_driver_register(&omap1_mbox_driver);
-}
-
-static void __exit omap1_mbox_exit(void)
-{
-	platform_driver_unregister(&omap1_mbox_driver);
-}
-
-module_init(omap1_mbox_init);
-module_exit(omap1_mbox_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("omap mailbox: omap1 architecture specific functions");
-MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
-MODULE_ALIAS("platform:omap1-mailbox");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -19,10 +19,6 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
 # Power Management
 obj-$(CONFIG_PM) += pm.o sleep.o
 
-# DSP
-obj-$(CONFIG_OMAP_MBOX_FWK)	+= mailbox_mach.o
-mailbox_mach-objs		:= mailbox.o
-
 i2c-omap-$(CONFIG_I2C_OMAP)		:= i2c.o
 obj-y					+= $(i2c-omap-m) $(i2c-omap-y)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/mcbsp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/mcbsp.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/mcbsp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/mcbsp.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,6 @@
 #include <mach/irqs.h>
 
 #include "iomap.h"
-#include "dma.h"
 
 #define DPS_RSTCT2_PER_EN	(1 << 0)
 #define DSP_RSTCT2_WD_PER_EN	(1 << 1)
@@ -114,12 +113,12 @@ struct resource omap7xx_mcbsp_res[][6] =
 		},
 		{
 			.name  = "rx",
-			.start = OMAP_DMA_MCBSP1_RX,
+			.start = 9,
 			.flags = IORESOURCE_DMA,
 		},
 		{
 			.name  = "tx",
-			.start = OMAP_DMA_MCBSP1_TX,
+			.start = 8,
 			.flags = IORESOURCE_DMA,
 		},
 	},
@@ -141,12 +140,12 @@ struct resource omap7xx_mcbsp_res[][6] =
 		},
 		{
 			.name  = "rx",
-			.start = OMAP_DMA_MCBSP3_RX,
+			.start = 11,
 			.flags = IORESOURCE_DMA,
 		},
 		{
 			.name  = "tx",
-			.start = OMAP_DMA_MCBSP3_TX,
+			.start = 10,
 			.flags = IORESOURCE_DMA,
 		},
 	},
@@ -191,12 +190,12 @@ struct resource omap15xx_mcbsp_res[][6]
 		},
 		{
 			.name  = "rx",
-			.start = OMAP_DMA_MCBSP1_RX,
+			.start = 9,
 			.flags = IORESOURCE_DMA,
 		},
 		{
 			.name  = "tx",
-			.start = OMAP_DMA_MCBSP1_TX,
+			.start = 8,
 			.flags = IORESOURCE_DMA,
 		},
 	},
@@ -218,12 +217,12 @@ struct resource omap15xx_mcbsp_res[][6]
 		},
 		{
 			.name  = "rx",
-			.start = OMAP_DMA_MCBSP2_RX,
+			.start = 17,
 			.flags = IORESOURCE_DMA,
 		},
 		{
 			.name  = "tx",
-			.start = OMAP_DMA_MCBSP2_TX,
+			.start = 16,
 			.flags = IORESOURCE_DMA,
 		},
 	},
@@ -245,12 +244,12 @@ struct resource omap15xx_mcbsp_res[][6]
 		},
 		{
 			.name  = "rx",
-			.start = OMAP_DMA_MCBSP3_RX,
+			.start = 11,
 			.flags = IORESOURCE_DMA,
 		},
 		{
 			.name  = "tx",
-			.start = OMAP_DMA_MCBSP3_TX,
+			.start = 10,
 			.flags = IORESOURCE_DMA,
 		},
 	},
@@ -298,12 +297,12 @@ struct resource omap16xx_mcbsp_res[][6]
 		},
 		{
 			.name  = "rx",
-			.start = OMAP_DMA_MCBSP1_RX,
+			.start = 9,
 			.flags = IORESOURCE_DMA,
 		},
 		{
 			.name  = "tx",
-			.start = OMAP_DMA_MCBSP1_TX,
+			.start = 8,
 			.flags = IORESOURCE_DMA,
 		},
 	},
@@ -325,12 +324,12 @@ struct resource omap16xx_mcbsp_res[][6]
 		},
 		{
 			.name  = "rx",
-			.start = OMAP_DMA_MCBSP2_RX,
+			.start = 17,
 			.flags = IORESOURCE_DMA,
 		},
 		{
 			.name  = "tx",
-			.start = OMAP_DMA_MCBSP2_TX,
+			.start = 16,
 			.flags = IORESOURCE_DMA,
 		},
 	},
@@ -352,12 +351,12 @@ struct resource omap16xx_mcbsp_res[][6]
 		},
 		{
 			.name  = "rx",
-			.start = OMAP_DMA_MCBSP3_RX,
+			.start = 11,
 			.flags = IORESOURCE_DMA,
 		},
 		{
 			.name  = "tx",
-			.start = OMAP_DMA_MCBSP3_TX,
+			.start = 10,
 			.flags = IORESOURCE_DMA,
 		},
 	},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/reset.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/reset.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/reset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/reset.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,6 +3,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/reboot.h>
 
 #include <mach/hardware.h>
 
@@ -22,7 +23,7 @@
 #define OMAP_EXTWARM_RST_SRC_ID_SHIFT			5
 
 
-void omap1_restart(char mode, const char *cmd)
+void omap1_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap1/time.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/time.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap1/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap1/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,9 +43,9 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/io.h>
+#include <linux/sched_clock.h>
 
 #include <asm/irq.h>
-#include <asm/sched_clock.h>
 
 #include <mach/hardware.h>
 #include <asm/mach/irq.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/am33xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/am33xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/am33xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/am33xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 #define AM33XX_SCM_BASE		0x44E10000
 #define AM33XX_CTRL_BASE	AM33XX_SCM_BASE
 #define AM33XX_PRCM_BASE	0x44E00000
+#define AM43XX_PRCM_BASE	0x44DF0000
 #define AM33XX_TAP_BASE		(AM33XX_CTRL_BASE + 0x3FC)
 
 #endif /* __ASM_ARCH_AM33XX_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/am33xx-restart.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/am33xx-restart.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/am33xx-restart.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/am33xx-restart.c	2013-08-25 20:43:22.000000000 -0400
@@ -6,6 +6,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/kernel.h>
+#include <linux/reboot.h>
 
 #include "common.h"
 #include "prm-regbits-33xx.h"
@@ -19,7 +20,7 @@
  * Resets the SoC.  For @cmd, see the 'reboot' syscall in
  * kernel/sys.c.  No return value.
  */
-void am33xx_restart(char mode, const char *cmd)
+void am33xx_restart(enum reboot_mode mode, const char *cmd)
 {
 	/* TODO: Handle mode and cmd if necessary */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-4430sdp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-4430sdp.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-4430sdp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-4430sdp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,765 +0,0 @@
-/*
- * Board support file for OMAP4430 SDP.
- *
- * Copyright (C) 2009 Texas Instruments
- *
- * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * Based on mach-omap2/board-3430sdp.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/usb/otg.h>
-#include <linux/spi/spi.h>
-#include <linux/i2c/twl.h>
-#include <linux/mfd/twl6040.h>
-#include <linux/gpio_keys.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/pwm.h>
-#include <linux/leds.h>
-#include <linux/leds_pwm.h>
-#include <linux/pwm_backlight.h>
-#include <linux/irqchip/arm-gic.h>
-#include <linux/platform_data/omap4-keypad.h>
-#include <linux/usb/musb.h>
-#include <linux/usb/phy.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-#include "omap4-keypad.h"
-#include <linux/wl12xx.h>
-#include <linux/platform_data/omap-abe-twl6040.h>
-
-#include "soc.h"
-#include "mux.h"
-#include "mmc.h"
-#include "hsmmc.h"
-#include "control.h"
-#include "common-board-devices.h"
-#include "dss-common.h"
-
-#define ETH_KS8851_IRQ			34
-#define ETH_KS8851_POWER_ON		48
-#define ETH_KS8851_QUART		138
-#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO	184
-#define OMAP4_SFH7741_ENABLE_GPIO		188
-
-#define GPIO_WIFI_PMENA		54
-#define GPIO_WIFI_IRQ		53
-
-static const int sdp4430_keymap[] = {
-	KEY(0, 0, KEY_E),
-	KEY(0, 1, KEY_R),
-	KEY(0, 2, KEY_T),
-	KEY(0, 3, KEY_HOME),
-	KEY(0, 4, KEY_F5),
-	KEY(0, 5, KEY_UNKNOWN),
-	KEY(0, 6, KEY_I),
-	KEY(0, 7, KEY_LEFTSHIFT),
-
-	KEY(1, 0, KEY_D),
-	KEY(1, 1, KEY_F),
-	KEY(1, 2, KEY_G),
-	KEY(1, 3, KEY_SEND),
-	KEY(1, 4, KEY_F6),
-	KEY(1, 5, KEY_UNKNOWN),
-	KEY(1, 6, KEY_K),
-	KEY(1, 7, KEY_ENTER),
-
-	KEY(2, 0, KEY_X),
-	KEY(2, 1, KEY_C),
-	KEY(2, 2, KEY_V),
-	KEY(2, 3, KEY_END),
-	KEY(2, 4, KEY_F7),
-	KEY(2, 5, KEY_UNKNOWN),
-	KEY(2, 6, KEY_DOT),
-	KEY(2, 7, KEY_CAPSLOCK),
-
-	KEY(3, 0, KEY_Z),
-	KEY(3, 1, KEY_KPPLUS),
-	KEY(3, 2, KEY_B),
-	KEY(3, 3, KEY_F1),
-	KEY(3, 4, KEY_F8),
-	KEY(3, 5, KEY_UNKNOWN),
-	KEY(3, 6, KEY_O),
-	KEY(3, 7, KEY_SPACE),
-
-	KEY(4, 0, KEY_W),
-	KEY(4, 1, KEY_Y),
-	KEY(4, 2, KEY_U),
-	KEY(4, 3, KEY_F2),
-	KEY(4, 4, KEY_VOLUMEUP),
-	KEY(4, 5, KEY_UNKNOWN),
-	KEY(4, 6, KEY_L),
-	KEY(4, 7, KEY_LEFT),
-
-	KEY(5, 0, KEY_S),
-	KEY(5, 1, KEY_H),
-	KEY(5, 2, KEY_J),
-	KEY(5, 3, KEY_F3),
-	KEY(5, 4, KEY_F9),
-	KEY(5, 5, KEY_VOLUMEDOWN),
-	KEY(5, 6, KEY_M),
-	KEY(5, 7, KEY_RIGHT),
-
-	KEY(6, 0, KEY_Q),
-	KEY(6, 1, KEY_A),
-	KEY(6, 2, KEY_N),
-	KEY(6, 3, KEY_BACK),
-	KEY(6, 4, KEY_BACKSPACE),
-	KEY(6, 5, KEY_UNKNOWN),
-	KEY(6, 6, KEY_P),
-	KEY(6, 7, KEY_UP),
-
-	KEY(7, 0, KEY_PROG1),
-	KEY(7, 1, KEY_PROG2),
-	KEY(7, 2, KEY_PROG3),
-	KEY(7, 3, KEY_PROG4),
-	KEY(7, 4, KEY_F4),
-	KEY(7, 5, KEY_UNKNOWN),
-	KEY(7, 6, KEY_OK),
-	KEY(7, 7, KEY_DOWN),
-};
-static struct omap_device_pad keypad_pads[] = {
-	{	.name   = "kpd_col1.kpd_col1",
-		.enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
-	},
-	{	.name   = "kpd_col1.kpd_col1",
-		.enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
-	},
-	{	.name   = "kpd_col2.kpd_col2",
-		.enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
-	},
-	{	.name   = "kpd_col3.kpd_col3",
-		.enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
-	},
-	{	.name   = "kpd_col4.kpd_col4",
-		.enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
-	},
-	{	.name   = "kpd_col5.kpd_col5",
-		.enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
-	},
-	{	.name   = "gpmc_a23.kpd_col7",
-		.enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
-	},
-	{	.name   = "gpmc_a22.kpd_col6",
-		.enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
-	},
-	{	.name   = "kpd_row0.kpd_row0",
-		.enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
-			OMAP_MUX_MODE1 | OMAP_INPUT_EN,
-	},
-	{	.name   = "kpd_row1.kpd_row1",
-		.enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
-			OMAP_MUX_MODE1 | OMAP_INPUT_EN,
-	},
-	{	.name   = "kpd_row2.kpd_row2",
-		.enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
-			OMAP_MUX_MODE1 | OMAP_INPUT_EN,
-	},
-	{	.name   = "kpd_row3.kpd_row3",
-		.enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
-			OMAP_MUX_MODE1 | OMAP_INPUT_EN,
-	},
-	{	.name   = "kpd_row4.kpd_row4",
-		.enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
-			OMAP_MUX_MODE1 | OMAP_INPUT_EN,
-	},
-	{	.name   = "kpd_row5.kpd_row5",
-		.enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
-			OMAP_MUX_MODE1 | OMAP_INPUT_EN,
-	},
-	{	.name   = "gpmc_a18.kpd_row6",
-		.enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
-			OMAP_MUX_MODE1 | OMAP_INPUT_EN,
-	},
-	{	.name   = "gpmc_a19.kpd_row7",
-		.enable = OMAP_PULL_ENA | OMAP_PULL_UP | OMAP_WAKEUP_EN |
-			OMAP_MUX_MODE1 | OMAP_INPUT_EN,
-	},
-};
-
-static struct matrix_keymap_data sdp4430_keymap_data = {
-	.keymap			= sdp4430_keymap,
-	.keymap_size		= ARRAY_SIZE(sdp4430_keymap),
-};
-
-static struct omap4_keypad_platform_data sdp4430_keypad_data = {
-	.keymap_data		= &sdp4430_keymap_data,
-	.rows			= 8,
-	.cols			= 8,
-};
-
-static struct omap_board_data keypad_data = {
-	.id	    		= 1,
-	.pads	 		= keypad_pads,
-	.pads_cnt       	= ARRAY_SIZE(keypad_pads),
-};
-
-static struct gpio_led sdp4430_gpio_leds[] = {
-	{
-		.name	= "omap4:green:debug0",
-		.gpio	= 61,
-	},
-	{
-		.name	= "omap4:green:debug1",
-		.gpio	= 30,
-	},
-	{
-		.name	= "omap4:green:debug2",
-		.gpio	= 7,
-	},
-	{
-		.name	= "omap4:green:debug3",
-		.gpio	= 8,
-	},
-	{
-		.name	= "omap4:green:debug4",
-		.gpio	= 50,
-	},
-	{
-		.name	= "omap4:blue:user",
-		.gpio	= 169,
-	},
-	{
-		.name	= "omap4:red:user",
-		.gpio	= 170,
-	},
-	{
-		.name	= "omap4:green:user",
-		.gpio	= 139,
-	},
-
-};
-
-static struct gpio_keys_button sdp4430_gpio_keys[] = {
-	{
-		.desc			= "Proximity Sensor",
-		.type			= EV_SW,
-		.code			= SW_FRONT_PROXIMITY,
-		.gpio			= OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
-		.active_low		= 0,
-	}
-};
-
-static struct gpio_led_platform_data sdp4430_led_data = {
-	.leds	= sdp4430_gpio_leds,
-	.num_leds	= ARRAY_SIZE(sdp4430_gpio_leds),
-};
-
-static struct pwm_lookup sdp4430_pwm_lookup[] = {
-	PWM_LOOKUP("twl-pwm", 0, "leds_pwm", "omap4::keypad"),
-	PWM_LOOKUP("twl-pwm", 1, "pwm-backlight", NULL),
-	PWM_LOOKUP("twl-pwmled", 0, "leds_pwm", "omap4:green:chrg"),
-};
-
-static struct led_pwm sdp4430_pwm_leds[] = {
-	{
-		.name		= "omap4::keypad",
-		.max_brightness	= 127,
-		.pwm_period_ns	= 7812500,
-	},
-	{
-		.name		= "omap4:green:chrg",
-		.max_brightness	= 255,
-		.pwm_period_ns	= 7812500,
-	},
-};
-
-static struct led_pwm_platform_data sdp4430_pwm_data = {
-	.num_leds	= ARRAY_SIZE(sdp4430_pwm_leds),
-	.leds		= sdp4430_pwm_leds,
-};
-
-static struct platform_device sdp4430_leds_pwm = {
-	.name	= "leds_pwm",
-	.id	= -1,
-	.dev	= {
-		.platform_data = &sdp4430_pwm_data,
-	},
-};
-
-/* Dummy regulator for pwm-backlight driver */
-static struct regulator_consumer_supply backlight_supply =
-	REGULATOR_SUPPLY("enable", "pwm-backlight");
-
-static struct platform_pwm_backlight_data sdp4430_backlight_data = {
-	.max_brightness = 127,
-	.dft_brightness = 127,
-	.pwm_period_ns = 7812500,
-};
-
-static struct platform_device sdp4430_backlight_pwm = {
-	.name   = "pwm-backlight",
-	.id     = -1,
-	.dev    = {
-		.platform_data = &sdp4430_backlight_data,
-	},
-};
-
-static int omap_prox_activate(struct device *dev)
-{
-	gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
-	return 0;
-}
-
-static void omap_prox_deactivate(struct device *dev)
-{
-	gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
-}
-
-static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
-	.buttons	= sdp4430_gpio_keys,
-	.nbuttons	= ARRAY_SIZE(sdp4430_gpio_keys),
-	.enable		= omap_prox_activate,
-	.disable	= omap_prox_deactivate,
-};
-
-static struct platform_device sdp4430_gpio_keys_device = {
-	.name	= "gpio-keys",
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &sdp4430_gpio_keys_data,
-	},
-};
-
-static struct platform_device sdp4430_leds_gpio = {
-	.name	= "leds-gpio",
-	.id	= -1,
-	.dev	= {
-		.platform_data = &sdp4430_led_data,
-	},
-};
-static struct spi_board_info sdp4430_spi_board_info[] __initdata = {
-	{
-		.modalias               = "ks8851",
-		.bus_num                = 1,
-		.chip_select            = 0,
-		.max_speed_hz           = 24000000,
-		/*
-		 * .irq is set to gpio_to_irq(ETH_KS8851_IRQ)
-		 * in omap_4430sdp_init
-		 */
-	},
-};
-
-static struct gpio sdp4430_eth_gpios[] __initdata = {
-	{ ETH_KS8851_POWER_ON,	GPIOF_OUT_INIT_HIGH,	"eth_power"	},
-	{ ETH_KS8851_QUART,	GPIOF_OUT_INIT_HIGH,	"quart"		},
-	{ ETH_KS8851_IRQ,	GPIOF_IN,		"eth_irq"	},
-};
-
-static int __init omap_ethernet_init(void)
-{
-	int status;
-
-	/* Request of GPIO lines */
-	status = gpio_request_array(sdp4430_eth_gpios,
-				    ARRAY_SIZE(sdp4430_eth_gpios));
-	if (status)
-		pr_err("Cannot request ETH GPIOs\n");
-
-	return status;
-}
-
-static struct regulator_consumer_supply sdp4430_vbat_supply[] = {
-	REGULATOR_SUPPLY("vddvibl", "twl6040-vibra"),
-	REGULATOR_SUPPLY("vddvibr", "twl6040-vibra"),
-};
-
-static struct regulator_init_data sdp4430_vbat_data = {
-	.constraints = {
-		.always_on	= 1,
-	},
-	.num_consumer_supplies	= ARRAY_SIZE(sdp4430_vbat_supply),
-	.consumer_supplies	= sdp4430_vbat_supply,
-};
-
-static struct fixed_voltage_config sdp4430_vbat_pdata = {
-	.supply_name	= "VBAT",
-	.microvolts	= 3750000,
-	.init_data	= &sdp4430_vbat_data,
-	.gpio		= -EINVAL,
-};
-
-static struct platform_device sdp4430_vbat = {
-	.name		= "reg-fixed-voltage",
-	.id		= -1,
-	.dev = {
-		.platform_data = &sdp4430_vbat_pdata,
-	},
-};
-
-static struct platform_device sdp4430_dmic_codec = {
-	.name	= "dmic-codec",
-	.id	= -1,
-};
-
-static struct platform_device sdp4430_hdmi_audio_codec = {
-	.name	= "hdmi-audio-codec",
-	.id	= -1,
-};
-
-static struct omap_abe_twl6040_data sdp4430_abe_audio_data = {
-	.card_name = "SDP4430",
-	.has_hs		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
-	.has_hf		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
-	.has_ep		= 1,
-	.has_aux	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
-	.has_vibra	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
-
-	.has_dmic	= 1,
-	.has_hsmic	= 1,
-	.has_mainmic	= 1,
-	.has_submic	= 1,
-	.has_afm	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
-
-	.jack_detection = 1,
-	/* MCLK input is 38.4MHz */
-	.mclk_freq	= 38400000,
-};
-
-static struct platform_device sdp4430_abe_audio = {
-	.name		= "omap-abe-twl6040",
-	.id		= -1,
-	.dev = {
-		.platform_data = &sdp4430_abe_audio_data,
-	},
-};
-
-static struct platform_device *sdp4430_devices[] __initdata = {
-	&sdp4430_gpio_keys_device,
-	&sdp4430_leds_gpio,
-	&sdp4430_leds_pwm,
-	&sdp4430_backlight_pwm,
-	&sdp4430_vbat,
-	&sdp4430_dmic_codec,
-	&sdp4430_abe_audio,
-	&sdp4430_hdmi_audio_codec,
-};
-
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type		= MUSB_INTERFACE_UTMI,
-	.mode			= MUSB_OTG,
-	.power			= 100,
-};
-
-static struct omap2_hsmmc_info mmc[] = {
-	{
-		.mmc		= 2,
-		.caps		=  MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
-		.gpio_cd	= -EINVAL,
-		.gpio_wp	= -EINVAL,
-		.nonremovable   = true,
-		.ocr_mask	= MMC_VDD_29_30,
-		.no_off_init	= true,
-	},
-	{
-		.mmc		= 1,
-		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
-		.gpio_cd	= -EINVAL,
-		.gpio_wp	= -EINVAL,
-	},
-	{
-		.mmc		= 5,
-		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
-		.pm_caps	= MMC_PM_KEEP_POWER,
-		.gpio_cd	= -EINVAL,
-		.gpio_wp	= -EINVAL,
-		.ocr_mask	= MMC_VDD_165_195,
-		.nonremovable	= true,
-	},
-	{}	/* Terminator */
-};
-
-static struct regulator_consumer_supply sdp4430_vaux_supply[] = {
-	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
-};
-
-static struct regulator_consumer_supply omap4_sdp4430_vmmc5_supply = {
-	.supply = "vmmc",
-	.dev_name = "omap_hsmmc.4",
-};
-
-static struct regulator_init_data sdp4430_vmmc5 = {
-	.constraints = {
-		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies = 1,
-	.consumer_supplies = &omap4_sdp4430_vmmc5_supply,
-};
-
-static struct fixed_voltage_config sdp4430_vwlan = {
-	.supply_name		= "vwl1271",
-	.microvolts		= 1800000, /* 1.8V */
-	.gpio			= GPIO_WIFI_PMENA,
-	.startup_delay		= 70000, /* 70msec */
-	.enable_high		= 1,
-	.enabled_at_boot	= 0,
-	.init_data		= &sdp4430_vmmc5,
-};
-
-static struct platform_device omap_vwlan_device = {
-	.name		= "reg-fixed-voltage",
-	.id		= 1,
-	.dev = {
-		.platform_data = &sdp4430_vwlan,
-	},
-};
-
-static struct regulator_init_data sdp4430_vaux1 = {
-	.constraints = {
-		.min_uV			= 1000000,
-		.max_uV			= 3000000,
-		.apply_uV		= true,
-		.valid_modes_mask	= REGULATOR_MODE_NORMAL
-					| REGULATOR_MODE_STANDBY,
-		.valid_ops_mask	 = REGULATOR_CHANGE_VOLTAGE
-					| REGULATOR_CHANGE_MODE
-					| REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies  = ARRAY_SIZE(sdp4430_vaux_supply),
-	.consumer_supplies      = sdp4430_vaux_supply,
-};
-
-static struct regulator_init_data sdp4430_vusim = {
-	.constraints = {
-		.min_uV			= 1200000,
-		.max_uV			= 2900000,
-		.apply_uV		= true,
-		.valid_modes_mask	= REGULATOR_MODE_NORMAL
-					| REGULATOR_MODE_STANDBY,
-		.valid_ops_mask	 = REGULATOR_CHANGE_VOLTAGE
-					| REGULATOR_CHANGE_MODE
-					| REGULATOR_CHANGE_STATUS,
-	},
-};
-
-static struct twl6040_codec_data twl6040_codec = {
-	/* single-step ramp for headset and handsfree */
-	.hs_left_step	= 0x0f,
-	.hs_right_step	= 0x0f,
-	.hf_left_step	= 0x1d,
-	.hf_right_step	= 0x1d,
-};
-
-static struct twl6040_vibra_data twl6040_vibra = {
-	.vibldrv_res = 8,
-	.vibrdrv_res = 3,
-	.viblmotor_res = 10,
-	.vibrmotor_res = 10,
-	.vddvibl_uV = 0,	/* fixed volt supply - VBAT */
-	.vddvibr_uV = 0,	/* fixed volt supply - VBAT */
-};
-
-static struct twl6040_platform_data twl6040_data = {
-	.codec		= &twl6040_codec,
-	.vibra		= &twl6040_vibra,
-	.audpwron_gpio	= 127,
-};
-
-static struct i2c_board_info __initdata sdp4430_i2c_1_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl6040", 0x4b),
-		.irq = 119 + OMAP44XX_IRQ_GIC_START,
-		.platform_data = &twl6040_data,
-	},
-};
-
-static struct twl4030_platform_data sdp4430_twldata = {
-	/* Regulators */
-	.vusim		= &sdp4430_vusim,
-	.vaux1		= &sdp4430_vaux1,
-};
-
-static struct i2c_board_info __initdata sdp4430_i2c_3_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("tmp105", 0x48),
-	},
-	{
-		I2C_BOARD_INFO("bh1780", 0x29),
-	},
-};
-static struct i2c_board_info __initdata sdp4430_i2c_4_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("hmc5843", 0x1e),
-	},
-};
-static int __init omap4_i2c_init(void)
-{
-	omap4_pmic_get_config(&sdp4430_twldata, TWL_COMMON_PDATA_USB,
-			TWL_COMMON_REGULATOR_VDAC |
-			TWL_COMMON_REGULATOR_VAUX2 |
-			TWL_COMMON_REGULATOR_VAUX3 |
-			TWL_COMMON_REGULATOR_VMMC |
-			TWL_COMMON_REGULATOR_VPP |
-			TWL_COMMON_REGULATOR_VANA |
-			TWL_COMMON_REGULATOR_VCXIO |
-			TWL_COMMON_REGULATOR_VUSB |
-			TWL_COMMON_REGULATOR_CLK32KG |
-			TWL_COMMON_REGULATOR_V1V8 |
-			TWL_COMMON_REGULATOR_V2V1);
-	omap4_pmic_init("twl6030", &sdp4430_twldata, sdp4430_i2c_1_boardinfo,
-			ARRAY_SIZE(sdp4430_i2c_1_boardinfo));
-	omap_register_i2c_bus(2, 400, NULL, 0);
-	omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
-				ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
-	omap_register_i2c_bus(4, 400, sdp4430_i2c_4_boardinfo,
-				ARRAY_SIZE(sdp4430_i2c_4_boardinfo));
-	return 0;
-}
-
-static void __init omap_sfh7741prox_init(void)
-{
-	int error;
-
-	error = gpio_request_one(OMAP4_SFH7741_ENABLE_GPIO,
-				 GPIOF_OUT_INIT_LOW, "sfh7741");
-	if (error < 0)
-		pr_err("%s:failed to request GPIO %d, error %d\n",
-			__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
-}
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
-	OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-	/* NIRQ2 for twl6040 */
-	OMAP4_MUX(SYS_NIRQ2, OMAP_MUX_MODE0 |
-		  OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
-	/* GPIO_127 for twl6040 */
-	OMAP4_MUX(HDQ_SIO, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
-	/* McPDM */
-	OMAP4_MUX(ABE_PDM_UL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	OMAP4_MUX(ABE_PDM_DL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	OMAP4_MUX(ABE_PDM_FRAME, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-	OMAP4_MUX(ABE_PDM_LB_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	OMAP4_MUX(ABE_CLKS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	/* DMIC */
-	OMAP4_MUX(ABE_DMIC_CLK1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
-	OMAP4_MUX(ABE_DMIC_DIN1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
-	OMAP4_MUX(ABE_DMIC_DIN2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
-	OMAP4_MUX(ABE_DMIC_DIN3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
-	/* McBSP1 */
-	OMAP4_MUX(ABE_MCBSP1_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
-	OMAP4_MUX(ABE_MCBSP1_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	OMAP4_MUX(ABE_MCBSP1_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT |
-		  OMAP_PULL_ENA),
-	OMAP4_MUX(ABE_MCBSP1_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
-	/* McBSP2 */
-	OMAP4_MUX(ABE_MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
-	OMAP4_MUX(ABE_MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	OMAP4_MUX(ABE_MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT |
-		  OMAP_PULL_ENA),
-	OMAP4_MUX(ABE_MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
-
-	{ .reg_offset = OMAP_MUX_TERMINATOR },
-};
-
-#else
-#define board_mux	NULL
- #endif
-
-static void __init omap4_sdp4430_wifi_mux_init(void)
-{
-	omap_mux_init_gpio(GPIO_WIFI_IRQ, OMAP_PIN_INPUT |
-				OMAP_PIN_OFF_WAKEUPENABLE);
-	omap_mux_init_gpio(GPIO_WIFI_PMENA, OMAP_PIN_OUTPUT);
-
-	omap_mux_init_signal("sdmmc5_cmd.sdmmc5_cmd",
-				OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
-	omap_mux_init_signal("sdmmc5_clk.sdmmc5_clk",
-				OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
-	omap_mux_init_signal("sdmmc5_dat0.sdmmc5_dat0",
-				OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
-	omap_mux_init_signal("sdmmc5_dat1.sdmmc5_dat1",
-				OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
-	omap_mux_init_signal("sdmmc5_dat2.sdmmc5_dat2",
-				OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
-	omap_mux_init_signal("sdmmc5_dat3.sdmmc5_dat3",
-				OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP);
-
-}
-
-static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = {
-	.board_ref_clock = WL12XX_REFCLOCK_26,
-	.board_tcxo_clock = WL12XX_TCXOCLOCK_26,
-};
-
-static void __init omap4_sdp4430_wifi_init(void)
-{
-	int ret;
-
-	omap4_sdp4430_wifi_mux_init();
-	omap4_sdp4430_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
-	ret = wl12xx_set_platform_data(&omap4_sdp4430_wlan_data);
-	if (ret)
-		pr_err("Error setting wl12xx data: %d\n", ret);
-	ret = platform_device_register(&omap_vwlan_device);
-	if (ret)
-		pr_err("Error registering wl12xx device: %d\n", ret);
-}
-
-static void __init omap_4430sdp_init(void)
-{
-	int status;
-	int package = OMAP_PACKAGE_CBS;
-
-	if (omap_rev() == OMAP4430_REV_ES1_0)
-		package = OMAP_PACKAGE_CBL;
-	omap4_mux_init(board_mux, NULL, package);
-
-	omap4_i2c_init();
-	omap_sfh7741prox_init();
-	regulator_register_always_on(0, "backlight-enable",
-				     &backlight_supply, 1, 0);
-	platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
-	omap_serial_init();
-	omap_sdrc_init(NULL, NULL);
-	omap4_sdp4430_wifi_init();
-	omap4_twl6030_hsmmc_init(mmc);
-
-	usb_bind_phy("musb-hdrc.2.auto", 0, "omap-usb2.3.auto");
-	usb_musb_init(&musb_board_data);
-
-	status = omap_ethernet_init();
-	if (status) {
-		pr_err("Ethernet initialization failed: %d\n", status);
-	} else {
-		sdp4430_spi_board_info[0].irq = gpio_to_irq(ETH_KS8851_IRQ);
-		spi_register_board_info(sdp4430_spi_board_info,
-				ARRAY_SIZE(sdp4430_spi_board_info));
-	}
-
-	pwm_add_table(sdp4430_pwm_lookup, ARRAY_SIZE(sdp4430_pwm_lookup));
-	status = omap4_keyboard_init(&sdp4430_keypad_data, &keypad_data);
-	if (status)
-		pr_err("Keypad initialization failed: %d\n", status);
-
-	omap_4430sdp_display_init();
-}
-
-MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
-	/* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(omap4_smp_ops),
-	.reserve	= omap_reserve,
-	.map_io		= omap4_map_io,
-	.init_early	= omap4430_init_early,
-	.init_irq	= gic_init_irq,
-	.init_machine	= omap_4430sdp_init,
-	.init_late	= omap4430_init_late,
-	.init_time	= omap4_local_timer_init,
-	.restart	= omap44xx_restart,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-cm-t35.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-cm-t35.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-cm-t35.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-cm-t35.c	2013-08-25 20:43:22.000000000 -0400
@@ -293,7 +293,8 @@ static struct regulator_consumer_supply
 static struct regulator_consumer_supply cm_t35_vio_supplies[] = {
 	REGULATOR_SUPPLY("vcc", "spi1.0"),
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-devkit8000.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-devkit8000.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-devkit8000.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-devkit8000.c	2013-08-25 20:43:22.000000000 -0400
@@ -222,6 +222,7 @@ static struct twl4030_gpio_platform_data
 
 static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-flash.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-flash.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-flash.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-flash.c	2013-08-25 20:43:22.000000000 -0400
@@ -112,6 +112,9 @@ struct gpmc_timings nand_default_timings
 		.cs_rd_off = 36,
 		.cs_wr_off = 36,
 
+		.we_on = 6,
+		.oe_on = 6,
+
 		.adv_on = 6,
 		.adv_rd_off = 24,
 		.adv_wr_off = 36,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-generic.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-generic.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-generic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-generic.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/irqdomain.h>
+#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 
@@ -35,6 +36,21 @@ static struct of_device_id omap_dt_match
 	{ }
 };
 
+/*
+ * Create alias for USB host PHY clock.
+ * Remove this when clock phandle can be provided via DT
+ */
+static void __init legacy_init_ehci_clk(char *clkname)
+{
+	int ret;
+
+	ret = clk_add_alias("main_clk", NULL, clkname, NULL);
+	if (ret) {
+		pr_err("%s:Failed to add main_clk alias to %s :%d\n",
+						__func__, clkname, ret);
+	}
+}
+
 static void __init omap_generic_init(void)
 {
 	omap_sdrc_init(NULL, NULL);
@@ -45,10 +61,15 @@ static void __init omap_generic_init(voi
 	 * HACK: call display setup code for selected boards to enable omapdss.
 	 * This will be removed when omapdss supports DT.
 	 */
-	if (of_machine_is_compatible("ti,omap4-panda"))
+	if (of_machine_is_compatible("ti,omap4-panda")) {
 		omap4_panda_display_init_of();
+		legacy_init_ehci_clk("auxclk3_ck");
+
+	}
 	else if (of_machine_is_compatible("ti,omap4-sdp"))
 		omap_4430sdp_display_init_of();
+	else if (of_machine_is_compatible("ti,omap5-uevm"))
+		legacy_init_ehci_clk("auxclk1_ck");
 }
 
 #ifdef CONFIG_SOC_OMAP2420
@@ -185,3 +206,19 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP
 	.restart	= omap44xx_restart,
 MACHINE_END
 #endif
+
+#ifdef CONFIG_SOC_AM43XX
+static const char *am43_boards_compat[] __initdata = {
+	"ti,am43",
+	NULL,
+};
+
+DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
+	.map_io		= am33xx_map_io,
+	.init_early	= am43xx_init_early,
+	.init_irq	= omap_gic_of_init,
+	.init_machine	= omap_generic_init,
+	.init_time	= omap3_sync32k_timer_init,
+	.dt_compat	= am43_boards_compat,
+MACHINE_END
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-igep0020.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-igep0020.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-igep0020.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-igep0020.c	2013-08-25 20:43:22.000000000 -0400
@@ -553,6 +553,37 @@ static struct usbhs_omap_platform_data i
 
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+	/* Display Sub System */
+	OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	/* TFP410 PanelBus DVI Transmitte (GPIO_170) */
+	OMAP3_MUX(HDQ_SIO, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
 	/* SMSC9221 LAN Controller ETH IRQ (GPIO_176) */
 	OMAP3_MUX(MCSPI1_CS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-ldp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-ldp.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-ldp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-ldp.c	2013-08-25 20:43:22.000000000 -0400
@@ -272,7 +272,8 @@ static struct regulator_init_data ldp_va
 
 static struct regulator_consumer_supply ldp_vpll2_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct regulator_init_data ldp_vpll2 = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-n8x0.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-n8x0.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-n8x0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-n8x0.c	2013-08-25 20:43:22.000000000 -0400
@@ -122,11 +122,7 @@ static struct musb_hdrc_config musb_conf
 };
 
 static struct musb_hdrc_platform_data tusb_data = {
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
 	.mode		= MUSB_OTG,
-#else
-	.mode		= MUSB_HOST,
-#endif
 	.set_power	= tusb_set_power,
 	.min_power	= 25,	/* x2 = 50 mA drawn from VBUS as peripheral */
 	.power		= 100,	/* Max 100 mA VBUS for host mode */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-omap3evm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-omap3evm.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-omap3evm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-omap3evm.c	2013-08-25 20:43:22.000000000 -0400
@@ -174,6 +174,7 @@ static struct panel_sharp_ls037v7dw01_da
 	.ud_gpio = OMAP3EVM_LCD_PANEL_UD,
 };
 
+#ifdef CONFIG_BROKEN
 static void __init omap3_evm_display_init(void)
 {
 	int r;
@@ -193,6 +194,7 @@ static void __init omap3_evm_display_ini
 	else
 		gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
 }
+#endif
 
 static struct omap_dss_device omap3_evm_lcd_device = {
 	.name			= "lcd",
@@ -715,7 +717,9 @@ static void __init omap3_evm_init(void)
 
 	omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
 	omap3evm_init_smsc911x();
+#ifdef CONFIG_BROKEN
 	omap3_evm_display_init();
+#endif
 	omap3_evm_wl12xx_init();
 	omap_twl4030_audio_init("omap3evm", NULL);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-omap3pandora.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-omap3pandora.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-omap3pandora.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-omap3pandora.c	2013-08-25 20:43:22.000000000 -0400
@@ -343,6 +343,7 @@ static struct regulator_consumer_supply
 static struct regulator_consumer_supply pandora_vdds_supplies[] = {
 	REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-omap4panda.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-omap4panda.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-omap4panda.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-omap4panda.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,455 +0,0 @@
-/*
- * Board support file for OMAP4430 based PandaBoard.
- *
- * Copyright (C) 2010 Texas Instruments
- *
- * Author: David Anders <x0132446@ti.com>
- *
- * Based on mach-omap2/board-4430sdp.c
- *
- * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * Based on mach-omap2/board-3430sdp.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/leds.h>
-#include <linux/gpio.h>
-#include <linux/usb/otg.h>
-#include <linux/i2c/twl.h>
-#include <linux/mfd/twl6040.h>
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/ti_wilink_st.h>
-#include <linux/usb/musb.h>
-#include <linux/usb/phy.h>
-#include <linux/usb/nop-usb-xceiv.h>
-#include <linux/wl12xx.h>
-#include <linux/irqchip/arm-gic.h>
-#include <linux/platform_data/omap-abe-twl6040.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-#include "soc.h"
-#include "mmc.h"
-#include "hsmmc.h"
-#include "control.h"
-#include "mux.h"
-#include "common-board-devices.h"
-#include "dss-common.h"
-
-#define GPIO_HUB_POWER		1
-#define GPIO_HUB_NRESET		62
-#define GPIO_WIFI_PMENA		43
-#define GPIO_WIFI_IRQ		53
-
-/* wl127x BT, FM, GPS connectivity chip */
-static struct ti_st_plat_data wilink_platform_data = {
-	.nshutdown_gpio	= 46,
-	.dev_name	= "/dev/ttyO1",
-	.flow_cntrl	= 1,
-	.baud_rate	= 3000000,
-	.chip_enable	= NULL,
-	.suspend	= NULL,
-	.resume		= NULL,
-};
-
-static struct platform_device wl1271_device = {
-	.name	= "kim",
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &wilink_platform_data,
-	},
-};
-
-static struct gpio_led gpio_leds[] = {
-	{
-		.name			= "pandaboard::status1",
-		.default_trigger	= "heartbeat",
-		.gpio			= 7,
-	},
-	{
-		.name			= "pandaboard::status2",
-		.default_trigger	= "mmc0",
-		.gpio			= 8,
-	},
-};
-
-static struct gpio_led_platform_data gpio_led_info = {
-	.leds		= gpio_leds,
-	.num_leds	= ARRAY_SIZE(gpio_leds),
-};
-
-static struct platform_device leds_gpio = {
-	.name	= "leds-gpio",
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &gpio_led_info,
-	},
-};
-
-static struct omap_abe_twl6040_data panda_abe_audio_data = {
-	/* Audio out */
-	.has_hs		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
-	/* HandsFree through expansion connector */
-	.has_hf		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
-	/* PandaBoard: FM TX, PandaBoardES: can be connected to audio out */
-	.has_aux	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
-	/* PandaBoard: FM RX, PandaBoardES: audio in */
-	.has_afm	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
-	/* No jack detection. */
-	.jack_detection	= 0,
-	/* MCLK input is 38.4MHz */
-	.mclk_freq	= 38400000,
-
-};
-
-static struct platform_device panda_abe_audio = {
-	.name		= "omap-abe-twl6040",
-	.id		= -1,
-	.dev = {
-		.platform_data = &panda_abe_audio_data,
-	},
-};
-
-static struct platform_device panda_hdmi_audio_codec = {
-	.name	= "hdmi-audio-codec",
-	.id	= -1,
-};
-
-static struct platform_device btwilink_device = {
-	.name	= "btwilink",
-	.id	= -1,
-};
-
-/* PHY device on HS USB Port 1 i.e. nop_usb_xceiv.1 */
-static struct nop_usb_xceiv_platform_data hsusb1_phy_data = {
-	/* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
-	.clk_rate = 19200000,
-};
-
-static struct usbhs_phy_data phy_data[] __initdata = {
-	{
-		.port = 1,
-		.reset_gpio = GPIO_HUB_NRESET,
-		.vcc_gpio = GPIO_HUB_POWER,
-		.vcc_polarity = 1,
-		.platform_data = &hsusb1_phy_data,
-	},
-};
-
-static struct platform_device *panda_devices[] __initdata = {
-	&leds_gpio,
-	&wl1271_device,
-	&panda_abe_audio,
-	&panda_hdmi_audio_codec,
-	&btwilink_device,
-};
-
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-static void __init omap4_ehci_init(void)
-{
-	int ret;
-
-	/* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
-	ret = clk_add_alias("main_clk", "nop_usb_xceiv.1", "auxclk3_ck", NULL);
-	if (ret)
-		pr_err("Failed to add main_clk alias to auxclk3_ck\n");
-
-	usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
-	usbhs_init(&usbhs_bdata);
-}
-
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type		= MUSB_INTERFACE_UTMI,
-	.mode			= MUSB_OTG,
-	.power			= 100,
-};
-
-static struct omap2_hsmmc_info mmc[] = {
-	{
-		.mmc		= 1,
-		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
-		.gpio_wp	= -EINVAL,
-		.gpio_cd	= -EINVAL,
-	},
-	{
-		.name		= "wl1271",
-		.mmc		= 5,
-		.caps		= MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
-		.gpio_wp	= -EINVAL,
-		.gpio_cd	= -EINVAL,
-		.ocr_mask	= MMC_VDD_165_195,
-		.nonremovable	= true,
-	},
-	{}	/* Terminator */
-};
-
-static struct regulator_consumer_supply omap4_panda_vmmc5_supply[] = {
-	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.4"),
-};
-
-static struct regulator_init_data panda_vmmc5 = {
-	.constraints = {
-		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(omap4_panda_vmmc5_supply),
-	.consumer_supplies = omap4_panda_vmmc5_supply,
-};
-
-static struct fixed_voltage_config panda_vwlan = {
-	.supply_name = "vwl1271",
-	.microvolts = 1800000, /* 1.8V */
-	.gpio = GPIO_WIFI_PMENA,
-	.startup_delay = 70000, /* 70msec */
-	.enable_high = 1,
-	.enabled_at_boot = 0,
-	.init_data = &panda_vmmc5,
-};
-
-static struct platform_device omap_vwlan_device = {
-	.name		= "reg-fixed-voltage",
-	.id		= 1,
-	.dev = {
-		.platform_data = &panda_vwlan,
-	},
-};
-
-static struct wl12xx_platform_data omap_panda_wlan_data  __initdata = {
-	.board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
-};
-
-static struct twl6040_codec_data twl6040_codec = {
-	/* single-step ramp for headset and handsfree */
-	.hs_left_step	= 0x0f,
-	.hs_right_step	= 0x0f,
-	.hf_left_step	= 0x1d,
-	.hf_right_step	= 0x1d,
-};
-
-static struct twl6040_platform_data twl6040_data = {
-	.codec		= &twl6040_codec,
-	.audpwron_gpio	= 127,
-};
-
-static struct i2c_board_info __initdata panda_i2c_1_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl6040", 0x4b),
-		.irq = 119 + OMAP44XX_IRQ_GIC_START,
-		.platform_data = &twl6040_data,
-	},
-};
-
-/* Panda board uses the common PMIC configuration */
-static struct twl4030_platform_data omap4_panda_twldata;
-
-/*
- * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
- * is connected as I2C slave device, and can be accessed at address 0x50
- */
-static struct i2c_board_info __initdata panda_i2c_eeprom[] = {
-	{
-		I2C_BOARD_INFO("eeprom", 0x50),
-	},
-};
-
-static int __init omap4_panda_i2c_init(void)
-{
-	omap4_pmic_get_config(&omap4_panda_twldata, TWL_COMMON_PDATA_USB,
-			TWL_COMMON_REGULATOR_VDAC |
-			TWL_COMMON_REGULATOR_VAUX2 |
-			TWL_COMMON_REGULATOR_VAUX3 |
-			TWL_COMMON_REGULATOR_VMMC |
-			TWL_COMMON_REGULATOR_VPP |
-			TWL_COMMON_REGULATOR_VANA |
-			TWL_COMMON_REGULATOR_VCXIO |
-			TWL_COMMON_REGULATOR_VUSB |
-			TWL_COMMON_REGULATOR_CLK32KG |
-			TWL_COMMON_REGULATOR_V1V8 |
-			TWL_COMMON_REGULATOR_V2V1);
-	omap4_pmic_init("twl6030", &omap4_panda_twldata, panda_i2c_1_boardinfo,
-			ARRAY_SIZE(panda_i2c_1_boardinfo));
-	omap_register_i2c_bus(2, 400, NULL, 0);
-	/*
-	 * Bus 3 is attached to the DVI port where devices like the pico DLP
-	 * projector don't work reliably with 400kHz
-	 */
-	omap_register_i2c_bus(3, 100, panda_i2c_eeprom,
-					ARRAY_SIZE(panda_i2c_eeprom));
-	omap_register_i2c_bus(4, 400, NULL, 0);
-	return 0;
-}
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
-	/* WLAN IRQ - GPIO 53 */
-	OMAP4_MUX(GPMC_NCS3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
-	/* WLAN POWER ENABLE - GPIO 43 */
-	OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
-	/* WLAN SDIO: MMC5 CMD */
-	OMAP4_MUX(SDMMC5_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-	/* WLAN SDIO: MMC5 CLK */
-	OMAP4_MUX(SDMMC5_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-	/* WLAN SDIO: MMC5 DAT[0-3] */
-	OMAP4_MUX(SDMMC5_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-	OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-	OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-	OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-	/* gpio 0 - TFP410 PD */
-	OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
-	/* dispc2_data23 */
-	OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data22 */
-	OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data21 */
-	OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data20 */
-	OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data19 */
-	OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data18 */
-	OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data15 */
-	OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data14 */
-	OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data13 */
-	OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data12 */
-	OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data11 */
-	OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data10 */
-	OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data9 */
-	OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data16 */
-	OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data17 */
-	OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_hsync */
-	OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_pclk */
-	OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_vsync */
-	OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_de */
-	OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data8 */
-	OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data7 */
-	OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data6 */
-	OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data5 */
-	OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data4 */
-	OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data3 */
-	OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data2 */
-	OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data1 */
-	OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* dispc2_data0 */
-	OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
-	/* NIRQ2 for twl6040 */
-	OMAP4_MUX(SYS_NIRQ2, OMAP_MUX_MODE0 |
-		  OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
-	/* GPIO_127 for twl6040 */
-	OMAP4_MUX(HDQ_SIO, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
-	/* McPDM */
-	OMAP4_MUX(ABE_PDM_UL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	OMAP4_MUX(ABE_PDM_DL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	OMAP4_MUX(ABE_PDM_FRAME, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
-	OMAP4_MUX(ABE_PDM_LB_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	OMAP4_MUX(ABE_CLKS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	/* McBSP1 */
-	OMAP4_MUX(ABE_MCBSP1_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
-	OMAP4_MUX(ABE_MCBSP1_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
-	OMAP4_MUX(ABE_MCBSP1_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT |
-		  OMAP_PULL_ENA),
-	OMAP4_MUX(ABE_MCBSP1_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
-
-	/* UART2 - BT/FM/GPS shared transport */
-	OMAP4_MUX(UART2_CTS,	OMAP_PIN_INPUT	| OMAP_MUX_MODE0),
-	OMAP4_MUX(UART2_RTS,	OMAP_PIN_OUTPUT	| OMAP_MUX_MODE0),
-	OMAP4_MUX(UART2_RX,	OMAP_PIN_INPUT	| OMAP_MUX_MODE0),
-	OMAP4_MUX(UART2_TX,	OMAP_PIN_OUTPUT	| OMAP_MUX_MODE0),
-
-	{ .reg_offset = OMAP_MUX_TERMINATOR },
-};
-
-#else
-#define board_mux	NULL
-#endif
-
-
-static void omap4_panda_init_rev(void)
-{
-	if (cpu_is_omap443x()) {
-		/* PandaBoard 4430 */
-		/* ASoC audio configuration */
-		panda_abe_audio_data.card_name = "PandaBoard";
-		panda_abe_audio_data.has_hsmic = 1;
-	} else {
-		/* PandaBoard ES */
-		/* ASoC audio configuration */
-		panda_abe_audio_data.card_name = "PandaBoardES";
-	}
-}
-
-static void __init omap4_panda_init(void)
-{
-	int package = OMAP_PACKAGE_CBS;
-	int ret;
-
-	if (omap_rev() == OMAP4430_REV_ES1_0)
-		package = OMAP_PACKAGE_CBL;
-	omap4_mux_init(board_mux, NULL, package);
-
-	omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ);
-	ret = wl12xx_set_platform_data(&omap_panda_wlan_data);
-	if (ret)
-		pr_err("error setting wl12xx data: %d\n", ret);
-
-	omap4_panda_init_rev();
-	omap4_panda_i2c_init();
-	platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
-	platform_device_register(&omap_vwlan_device);
-	omap_serial_init();
-	omap_sdrc_init(NULL, NULL);
-	omap4_twl6030_hsmmc_init(mmc);
-	omap4_ehci_init();
-	usb_bind_phy("musb-hdrc.2.auto", 0, "omap-usb2.3.auto");
-	usb_musb_init(&musb_board_data);
-	omap4_panda_display_init();
-}
-
-MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
-	/* Maintainer: David Anders - Texas Instruments Inc */
-	.atag_offset	= 0x100,
-	.smp		= smp_ops(omap4_smp_ops),
-	.reserve	= omap_reserve,
-	.map_io		= omap4_map_io,
-	.init_early	= omap4430_init_early,
-	.init_irq	= gic_init_irq,
-	.init_machine	= omap4_panda_init,
-	.init_late	= omap4430_init_late,
-	.init_time	= omap4_local_timer_init,
-	.restart	= omap44xx_restart,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-overo.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-overo.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-overo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-overo.c	2013-08-25 20:43:22.000000000 -0400
@@ -68,6 +68,7 @@
 
 #define OVERO_SMSC911X_CS      5
 #define OVERO_SMSC911X_GPIO    176
+#define OVERO_SMSC911X_NRESET  64
 #define OVERO_SMSC911X2_CS     4
 #define OVERO_SMSC911X2_GPIO   65
 
@@ -122,7 +123,7 @@ static struct omap_smsc911x_platform_dat
 	.id		= 0,
 	.cs             = OVERO_SMSC911X_CS,
 	.gpio_irq       = OVERO_SMSC911X_GPIO,
-	.gpio_reset     = -EINVAL,
+	.gpio_reset     = OVERO_SMSC911X_NRESET,
 	.flags		= SMSC911X_USE_32BIT,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-rx51.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-rx51.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-rx51.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-rx51.c	2013-08-25 20:43:22.000000000 -0400
@@ -85,7 +85,7 @@ static struct omap_board_mux board_mux[]
 
 static struct omap_musb_board_data musb_board_data = {
 	.interface_type		= MUSB_INTERFACE_ULPI,
-	.mode			= MUSB_PERIPHERAL,
+	.mode			= MUSB_OTG,
 	.power			= 0,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-rx51-peripherals.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-rx51-peripherals.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-rx51-peripherals.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-rx51-peripherals.c	2013-08-25 20:43:22.000000000 -0400
@@ -553,6 +553,7 @@ static struct regulator_consumer_supply
 
 static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
 	REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+	REGULATOR_SUPPLY("vdds_sdi", "omapdss_sdi.0"),
 	/* Si4713 supply */
 	REGULATOR_SUPPLY("vdd", "2-0063"),
 	/* lis3lv02d */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/board-rx51-video.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-rx51-video.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/board-rx51-video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/board-rx51-video.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,7 +61,7 @@ static struct omap_dss_board_info rx51_d
 
 static int __init rx51_video_init(void)
 {
-	if (!machine_is_nokia_rx51())
+	if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900"))
 		return 0;
 
 	if (omap_mux_init_gpio(RX51_LCD_RESET_GPIO, OMAP_PIN_OUTPUT)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/cclock33xx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cclock33xx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/cclock33xx_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cclock33xx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -431,15 +431,11 @@ DEFINE_STRUCT_CLK(aes0_fck, dpll_core_ck
  *  - Driver code is not yet migrated to use hwmod/runtime pm
  *  - Modules outside kernel access (to disable them by default)
  *
- *     - debugss
  *     - mmu (gfx domain)
  *     - cefuse
  *     - usbotg_fck (its additional clock and not really a modulemode)
  *     - ieee5000
  */
-DEFINE_CLK_GATE(debugss_ick, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
-		AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
-		0x0, NULL);
 
 DEFINE_CLK_GATE(mmu_fck, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
 		AM33XX_CM_GFX_MMUDATA_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
@@ -862,6 +858,69 @@ static struct clk_hw_omap wdt1_fck_hw =
 
 DEFINE_STRUCT_CLK(wdt1_fck, wdt_ck_parents, gpio_fck_ops);
 
+static const char *pwmss_clk_parents[] = {
+	"dpll_per_m2_ck",
+};
+
+static const struct clk_ops ehrpwm_tbclk_ops = {
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(ehrpwm0_tbclk, "l4ls_clkdm",
+			 NULL, NULL, 0,
+			 AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL),
+			 AM33XX_PWMSS0_TBCLKEN_SHIFT,
+			 NULL, pwmss_clk_parents, ehrpwm_tbclk_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(ehrpwm1_tbclk, "l4ls_clkdm",
+			 NULL, NULL, 0,
+			 AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL),
+			 AM33XX_PWMSS1_TBCLKEN_SHIFT,
+			 NULL, pwmss_clk_parents, ehrpwm_tbclk_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(ehrpwm2_tbclk, "l4ls_clkdm",
+			 NULL, NULL, 0,
+			 AM33XX_CTRL_REGADDR(AM33XX_PWMSS_TBCLK_CLKCTRL),
+			 AM33XX_PWMSS2_TBCLKEN_SHIFT,
+			 NULL, pwmss_clk_parents, ehrpwm_tbclk_ops);
+
+/*
+ * debugss optional clocks
+ */
+DEFINE_CLK_GATE(dbg_sysclk_ck, "sys_clkin_ck", &sys_clkin_ck,
+		0x0, AM33XX_CM_WKUP_DEBUGSS_CLKCTRL,
+		AM33XX_OPTFCLKEN_DBGSYSCLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(dbg_clka_ck, "dpll_core_m4_ck", &dpll_core_m4_ck,
+		0x0, AM33XX_CM_WKUP_DEBUGSS_CLKCTRL,
+		AM33XX_OPTCLK_DEBUG_CLKA_SHIFT, 0x0, NULL);
+
+static const char *stm_pmd_clock_mux_ck_parents[] = {
+	"dbg_sysclk_ck", "dbg_clka_ck",
+};
+
+DEFINE_CLK_MUX(stm_pmd_clock_mux_ck, stm_pmd_clock_mux_ck_parents, NULL, 0x0,
+	       AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, AM33XX_STM_PMD_CLKSEL_SHIFT,
+	       AM33XX_STM_PMD_CLKSEL_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_MUX(trace_pmd_clk_mux_ck, stm_pmd_clock_mux_ck_parents, NULL, 0x0,
+	       AM33XX_CM_WKUP_DEBUGSS_CLKCTRL,
+	       AM33XX_TRC_PMD_CLKSEL_SHIFT,
+	       AM33XX_TRC_PMD_CLKSEL_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_DIVIDER(stm_clk_div_ck, "stm_pmd_clock_mux_ck",
+		   &stm_pmd_clock_mux_ck, 0x0, AM33XX_CM_WKUP_DEBUGSS_CLKCTRL,
+		   AM33XX_STM_PMD_CLKDIVSEL_SHIFT,
+		   AM33XX_STM_PMD_CLKDIVSEL_WIDTH, CLK_DIVIDER_POWER_OF_TWO,
+		   NULL);
+
+DEFINE_CLK_DIVIDER(trace_clk_div_ck, "trace_pmd_clk_mux_ck",
+		   &trace_pmd_clk_mux_ck, 0x0, AM33XX_CM_WKUP_DEBUGSS_CLKCTRL,
+		   AM33XX_TRC_PMD_CLKDIVSEL_SHIFT,
+		   AM33XX_TRC_PMD_CLKDIVSEL_WIDTH, CLK_DIVIDER_POWER_OF_TWO,
+		   NULL);
+
 /*
  * clkdev
  */
@@ -899,7 +958,6 @@ static struct omap_clk am33xx_clks[] = {
 	CLK("481cc000.d_can",	NULL,		&dcan0_fck),
 	CLK(NULL,	"dcan1_fck",		&dcan1_fck),
 	CLK("481d0000.d_can",	NULL,		&dcan1_fck),
-	CLK(NULL,	"debugss_ick",		&debugss_ick),
 	CLK(NULL,	"pruss_ocp_gclk",	&pruss_ocp_gclk),
 	CLK(NULL,	"mcasp0_fck",		&mcasp0_fck),
 	CLK(NULL,	"mcasp1_fck",		&mcasp1_fck),
@@ -942,6 +1000,16 @@ static struct omap_clk am33xx_clks[] = {
 	CLK(NULL,	"clkout2_div_ck",	&clkout2_div_ck),
 	CLK(NULL,	"timer_32k_ck",		&clkdiv32k_ick),
 	CLK(NULL,	"timer_sys_ck",		&sys_clkin_ck),
+	CLK(NULL,	"dbg_sysclk_ck",	&dbg_sysclk_ck),
+	CLK(NULL,	"dbg_clka_ck",		&dbg_clka_ck),
+	CLK(NULL,	"stm_pmd_clock_mux_ck",	&stm_pmd_clock_mux_ck),
+	CLK(NULL,	"trace_pmd_clk_mux_ck",	&trace_pmd_clk_mux_ck),
+	CLK(NULL,	"stm_clk_div_ck",	&stm_clk_div_ck),
+	CLK(NULL,	"trace_clk_div_ck",	&trace_clk_div_ck),
+	CLK(NULL,	"clkout2_ck",		&clkout2_ck),
+	CLK("48300200.ehrpwm",	"tbclk",	&ehrpwm0_tbclk),
+	CLK("48302200.ehrpwm",	"tbclk",	&ehrpwm1_tbclk),
+	CLK("48304200.ehrpwm",	"tbclk",	&ehrpwm2_tbclk),
 };
 
 
@@ -952,6 +1020,7 @@ static const char *enable_init_clks[] =
 	"l4hs_gclk",
 	"l4fw_gclk",
 	"l4ls_gclk",
+	"clkout2_ck",	/* Required for external peripherals like, Audio codecs */
 };
 
 int __init am33xx_clk_init(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/cclock3xxx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cclock3xxx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/cclock3xxx_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cclock3xxx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -3329,11 +3329,7 @@ static struct omap_clk omap36xx_am35xx_o
 	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck),
 	CLK(NULL,	"ts_fck",	&ts_fck),
 	CLK(NULL,	"usbtll_fck",	&usbtll_fck),
-	CLK("usbhs_omap",	"usbtll_fck",	&usbtll_fck),
-	CLK("usbhs_tll",	"usbtll_fck",	&usbtll_fck),
 	CLK(NULL,	"usbtll_ick",	&usbtll_ick),
-	CLK("usbhs_omap",	"usbtll_ick",	&usbtll_ick),
-	CLK("usbhs_tll",	"usbtll_ick",	&usbtll_ick),
 	CLK("omap_hsmmc.2",	"ick",	&mmchs3_ick),
 	CLK(NULL,	"mmchs3_ick",	&mmchs3_ick),
 	CLK(NULL,	"mmchs3_fck",	&mmchs3_fck),
@@ -3343,7 +3339,6 @@ static struct omap_clk omap36xx_am35xx_o
 	CLK(NULL,	"usbhost_120m_fck", &usbhost_120m_fck),
 	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck),
 	CLK(NULL,	"usbhost_ick",	&usbhost_ick),
-	CLK("usbhs_omap",	"usbhost_ick",	&usbhost_ick),
 };
 
 /*
@@ -3463,12 +3458,6 @@ static struct omap_clk omap3xxx_clks[] =
 	CLK(NULL,	"utmi_p2_gfclk",	&dummy_ck),
 	CLK(NULL,	"xclk60mhsp1_ck",	&dummy_ck),
 	CLK(NULL,	"xclk60mhsp2_ck",	&dummy_ck),
-	CLK(NULL,	"usb_host_hs_utmi_p1_clk",	&dummy_ck),
-	CLK(NULL,	"usb_host_hs_utmi_p2_clk",	&dummy_ck),
-	CLK("usbhs_omap",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck),
-	CLK("usbhs_omap",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck),
-	CLK("usbhs_tll",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck),
-	CLK("usbhs_tll",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck),
 	CLK(NULL,	"init_60m_fclk",	&dummy_ck),
 	CLK(NULL,	"gpt1_fck",	&gpt1_fck),
 	CLK(NULL,	"aes2_ick",	&aes2_ick),
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/clockdomain.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/clockdomain.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/clockdomain.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/clockdomain.h	2013-08-25 20:43:22.000000000 -0400
@@ -216,6 +216,7 @@ extern void __init omap243x_clockdomains
 extern void __init omap3xxx_clockdomains_init(void);
 extern void __init am33xx_clockdomains_init(void);
 extern void __init omap44xx_clockdomains_init(void);
+extern void __init omap54xx_clockdomains_init(void);
 
 extern void clkdm_add_autodeps(struct clockdomain *clkdm);
 extern void clkdm_del_autodeps(struct clockdomain *clkdm);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/clockdomains54xx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/clockdomains54xx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/clockdomains54xx_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/clockdomains54xx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,464 @@
+/*
+ * OMAP54XX Clock domains framework
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ *
+ * Abhijit Pagare (abhijitpagare@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ * Paul Walmsley (paul@pwsan.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "cm1_54xx.h"
+#include "cm2_54xx.h"
+
+#include "cm-regbits-54xx.h"
+#include "prm54xx.h"
+#include "prcm44xx.h"
+#include "prcm_mpu54xx.h"
+
+/* Static Dependencies for OMAP4 Clock Domains */
+
+static struct clkdm_dep c2c_wkup_sleep_deps[] = {
+	{ .clkdm_name = "abe_clkdm" },
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l3init_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ .clkdm_name = "l3main2_clkdm" },
+	{ .clkdm_name = "l4cfg_clkdm" },
+	{ .clkdm_name = "l4per_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep cam_wkup_sleep_deps[] = {
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep dma_wkup_sleep_deps[] = {
+	{ .clkdm_name = "abe_clkdm" },
+	{ .clkdm_name = "dss_clkdm" },
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "ipu_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l3init_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ .clkdm_name = "l4cfg_clkdm" },
+	{ .clkdm_name = "l4per_clkdm" },
+	{ .clkdm_name = "l4sec_clkdm" },
+	{ .clkdm_name = "wkupaon_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep dsp_wkup_sleep_deps[] = {
+	{ .clkdm_name = "abe_clkdm" },
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l3init_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ .clkdm_name = "l3main2_clkdm" },
+	{ .clkdm_name = "l4cfg_clkdm" },
+	{ .clkdm_name = "l4per_clkdm" },
+	{ .clkdm_name = "wkupaon_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep dss_wkup_sleep_deps[] = {
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l3main2_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep gpu_wkup_sleep_deps[] = {
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep ipu_wkup_sleep_deps[] = {
+	{ .clkdm_name = "abe_clkdm" },
+	{ .clkdm_name = "dsp_clkdm" },
+	{ .clkdm_name = "dss_clkdm" },
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "gpu_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l3init_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ .clkdm_name = "l3main2_clkdm" },
+	{ .clkdm_name = "l4cfg_clkdm" },
+	{ .clkdm_name = "l4per_clkdm" },
+	{ .clkdm_name = "l4sec_clkdm" },
+	{ .clkdm_name = "wkupaon_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep iva_wkup_sleep_deps[] = {
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep l3init_wkup_sleep_deps[] = {
+	{ .clkdm_name = "abe_clkdm" },
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l4cfg_clkdm" },
+	{ .clkdm_name = "l4per_clkdm" },
+	{ .clkdm_name = "l4sec_clkdm" },
+	{ .clkdm_name = "wkupaon_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep l4sec_wkup_sleep_deps[] = {
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ .clkdm_name = "l4per_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep mipiext_wkup_sleep_deps[] = {
+	{ .clkdm_name = "abe_clkdm" },
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l3init_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ .clkdm_name = "l3main2_clkdm" },
+	{ .clkdm_name = "l4cfg_clkdm" },
+	{ .clkdm_name = "l4per_clkdm" },
+	{ NULL },
+};
+
+static struct clkdm_dep mpu_wkup_sleep_deps[] = {
+	{ .clkdm_name = "abe_clkdm" },
+	{ .clkdm_name = "dsp_clkdm" },
+	{ .clkdm_name = "dss_clkdm" },
+	{ .clkdm_name = "emif_clkdm" },
+	{ .clkdm_name = "gpu_clkdm" },
+	{ .clkdm_name = "ipu_clkdm" },
+	{ .clkdm_name = "iva_clkdm" },
+	{ .clkdm_name = "l3init_clkdm" },
+	{ .clkdm_name = "l3main1_clkdm" },
+	{ .clkdm_name = "l3main2_clkdm" },
+	{ .clkdm_name = "l4cfg_clkdm" },
+	{ .clkdm_name = "l4per_clkdm" },
+	{ .clkdm_name = "l4sec_clkdm" },
+	{ .clkdm_name = "wkupaon_clkdm" },
+	{ NULL },
+};
+
+static struct clockdomain l4sec_54xx_clkdm = {
+	.name		  = "l4sec_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_L4SEC_CDOFFS,
+	.dep_bit	  = OMAP54XX_L4SEC_STATDEP_SHIFT,
+	.wkdep_srcs	  = l4sec_wkup_sleep_deps,
+	.sleepdep_srcs	  = l4sec_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain iva_54xx_clkdm = {
+	.name		  = "iva_clkdm",
+	.pwrdm		  = { .name = "iva_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_IVA_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_IVA_IVA_CDOFFS,
+	.dep_bit	  = OMAP54XX_IVA_STATDEP_SHIFT,
+	.wkdep_srcs	  = iva_wkup_sleep_deps,
+	.sleepdep_srcs	  = iva_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain mipiext_54xx_clkdm = {
+	.name		  = "mipiext_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_MIPIEXT_CDOFFS,
+	.wkdep_srcs	  = mipiext_wkup_sleep_deps,
+	.sleepdep_srcs	  = mipiext_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l3main2_54xx_clkdm = {
+	.name		  = "l3main2_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_L3MAIN2_CDOFFS,
+	.dep_bit	  = OMAP54XX_L3MAIN2_STATDEP_SHIFT,
+	.flags		  = CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l3main1_54xx_clkdm = {
+	.name		  = "l3main1_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_L3MAIN1_CDOFFS,
+	.dep_bit	  = OMAP54XX_L3MAIN1_STATDEP_SHIFT,
+	.flags		  = CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain custefuse_54xx_clkdm = {
+	.name		  = "custefuse_clkdm",
+	.pwrdm		  = { .name = "custefuse_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CUSTEFUSE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain ipu_54xx_clkdm = {
+	.name		  = "ipu_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_IPU_CDOFFS,
+	.dep_bit	  = OMAP54XX_IPU_STATDEP_SHIFT,
+	.wkdep_srcs	  = ipu_wkup_sleep_deps,
+	.sleepdep_srcs	  = ipu_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain l4cfg_54xx_clkdm = {
+	.name		  = "l4cfg_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_L4CFG_CDOFFS,
+	.dep_bit	  = OMAP54XX_L4CFG_STATDEP_SHIFT,
+	.flags		  = CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain abe_54xx_clkdm = {
+	.name		  = "abe_clkdm",
+	.pwrdm		  = { .name = "abe_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_AON_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_AON_ABE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_AON_ABE_ABE_CDOFFS,
+	.dep_bit	  = OMAP54XX_ABE_STATDEP_SHIFT,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain dss_54xx_clkdm = {
+	.name		  = "dss_clkdm",
+	.pwrdm		  = { .name = "dss_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_DSS_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_DSS_DSS_CDOFFS,
+	.dep_bit	  = OMAP54XX_DSS_STATDEP_SHIFT,
+	.wkdep_srcs	  = dss_wkup_sleep_deps,
+	.sleepdep_srcs	  = dss_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain dsp_54xx_clkdm = {
+	.name		  = "dsp_clkdm",
+	.pwrdm		  = { .name = "dsp_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_AON_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_AON_DSP_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_AON_DSP_DSP_CDOFFS,
+	.dep_bit	  = OMAP54XX_DSP_STATDEP_SHIFT,
+	.wkdep_srcs	  = dsp_wkup_sleep_deps,
+	.sleepdep_srcs	  = dsp_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain c2c_54xx_clkdm = {
+	.name		  = "c2c_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_C2C_CDOFFS,
+	.wkdep_srcs	  = c2c_wkup_sleep_deps,
+	.sleepdep_srcs	  = c2c_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l4per_54xx_clkdm = {
+	.name		  = "l4per_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_L4PER_CDOFFS,
+	.dep_bit	  = OMAP54XX_L4PER_STATDEP_SHIFT,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain gpu_54xx_clkdm = {
+	.name		  = "gpu_clkdm",
+	.pwrdm		  = { .name = "gpu_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_GPU_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_GPU_GPU_CDOFFS,
+	.dep_bit	  = OMAP54XX_GPU_STATDEP_SHIFT,
+	.wkdep_srcs	  = gpu_wkup_sleep_deps,
+	.sleepdep_srcs	  = gpu_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain wkupaon_54xx_clkdm = {
+	.name		  = "wkupaon_clkdm",
+	.pwrdm		  = { .name = "wkupaon_pwrdm" },
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.cm_inst	  = OMAP54XX_PRM_WKUPAON_CM_INST,
+	.clkdm_offs	  = OMAP54XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS,
+	.dep_bit	  = OMAP54XX_WKUPAON_STATDEP_SHIFT,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain mpu0_54xx_clkdm = {
+	.name		  = "mpu0_clkdm",
+	.pwrdm		  = { .name = "cpu0_pwrdm" },
+	.prcm_partition	  = OMAP54XX_PRCM_MPU_PARTITION,
+	.cm_inst	  = OMAP54XX_PRCM_MPU_CM_C0_INST,
+	.clkdm_offs	  = OMAP54XX_PRCM_MPU_CM_C0_CPU0_CDOFFS,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain mpu1_54xx_clkdm = {
+	.name		  = "mpu1_clkdm",
+	.pwrdm		  = { .name = "cpu1_pwrdm" },
+	.prcm_partition	  = OMAP54XX_PRCM_MPU_PARTITION,
+	.cm_inst	  = OMAP54XX_PRCM_MPU_CM_C1_INST,
+	.clkdm_offs	  = OMAP54XX_PRCM_MPU_CM_C1_CPU1_CDOFFS,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain coreaon_54xx_clkdm = {
+	.name		  = "coreaon_clkdm",
+	.pwrdm		  = { .name = "coreaon_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_COREAON_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_COREAON_COREAON_CDOFFS,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain mpu_54xx_clkdm = {
+	.name		  = "mpu_clkdm",
+	.pwrdm		  = { .name = "mpu_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_AON_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_AON_MPU_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_AON_MPU_MPU_CDOFFS,
+	.wkdep_srcs	  = mpu_wkup_sleep_deps,
+	.sleepdep_srcs	  = mpu_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l3init_54xx_clkdm = {
+	.name		  = "l3init_clkdm",
+	.pwrdm		  = { .name = "l3init_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_L3INIT_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_L3INIT_L3INIT_CDOFFS,
+	.dep_bit	  = OMAP54XX_L3INIT_STATDEP_SHIFT,
+	.wkdep_srcs	  = l3init_wkup_sleep_deps,
+	.sleepdep_srcs	  = l3init_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain dma_54xx_clkdm = {
+	.name		  = "dma_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_DMA_CDOFFS,
+	.wkdep_srcs	  = dma_wkup_sleep_deps,
+	.sleepdep_srcs	  = dma_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain l3instr_54xx_clkdm = {
+	.name		  = "l3instr_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_L3INSTR_CDOFFS,
+};
+
+static struct clockdomain emif_54xx_clkdm = {
+	.name		  = "emif_clkdm",
+	.pwrdm		  = { .name = "core_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CORE_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CORE_EMIF_CDOFFS,
+	.dep_bit	  = OMAP54XX_EMIF_STATDEP_SHIFT,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain emu_54xx_clkdm = {
+	.name		  = "emu_clkdm",
+	.pwrdm		  = { .name = "emu_pwrdm" },
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.cm_inst	  = OMAP54XX_PRM_EMU_CM_INST,
+	.clkdm_offs	  = OMAP54XX_PRM_EMU_CM_EMU_CDOFFS,
+	.flags		  = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+};
+
+static struct clockdomain cam_54xx_clkdm = {
+	.name		  = "cam_clkdm",
+	.pwrdm		  = { .name = "cam_pwrdm" },
+	.prcm_partition	  = OMAP54XX_CM_CORE_PARTITION,
+	.cm_inst	  = OMAP54XX_CM_CORE_CAM_INST,
+	.clkdm_offs	  = OMAP54XX_CM_CORE_CAM_CAM_CDOFFS,
+	.wkdep_srcs	  = cam_wkup_sleep_deps,
+	.sleepdep_srcs	  = cam_wkup_sleep_deps,
+	.flags		  = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+/* As clockdomains are added or removed above, this list must also be changed */
+static struct clockdomain *clockdomains_omap54xx[] __initdata = {
+	&l4sec_54xx_clkdm,
+	&iva_54xx_clkdm,
+	&mipiext_54xx_clkdm,
+	&l3main2_54xx_clkdm,
+	&l3main1_54xx_clkdm,
+	&custefuse_54xx_clkdm,
+	&ipu_54xx_clkdm,
+	&l4cfg_54xx_clkdm,
+	&abe_54xx_clkdm,
+	&dss_54xx_clkdm,
+	&dsp_54xx_clkdm,
+	&c2c_54xx_clkdm,
+	&l4per_54xx_clkdm,
+	&gpu_54xx_clkdm,
+	&wkupaon_54xx_clkdm,
+	&mpu0_54xx_clkdm,
+	&mpu1_54xx_clkdm,
+	&coreaon_54xx_clkdm,
+	&mpu_54xx_clkdm,
+	&l3init_54xx_clkdm,
+	&dma_54xx_clkdm,
+	&l3instr_54xx_clkdm,
+	&emif_54xx_clkdm,
+	&emu_54xx_clkdm,
+	&cam_54xx_clkdm,
+	NULL
+};
+
+void __init omap54xx_clockdomains_init(void)
+{
+	clkdm_register_platform_funcs(&omap4_clkdm_operations);
+	clkdm_register_clkdms(clockdomains_omap54xx);
+	clkdm_complete_init();
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/cm1_44xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm1_44xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/cm1_44xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm1_44xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,8 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CM1_44XX_H
 #define __ARCH_ARM_MACH_OMAP2_CM1_44XX_H
 
+#include "cm_44xx_54xx.h"
+
 /* CM1 base address */
 #define OMAP4430_CM1_BASE		0x4a004000
 
@@ -217,9 +219,4 @@
 #define OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET		0x0088
 #define OMAP4430_CM1_ABE_WDT3_CLKCTRL			OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0088)
 
-/* Function prototypes */
-extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx);
-extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx);
-extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
-
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/cm1_54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm1_54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/cm1_54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm1_54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,213 @@
+/*
+ * OMAP54xx CM1 instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM1_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM1_54XX_H
+
+#include "cm_44xx_54xx.h"
+
+/* CM1 base address */
+#define OMAP54XX_CM_CORE_AON_BASE		0x4a004000
+
+#define OMAP54XX_CM_CORE_AON_REGADDR(inst, reg)				\
+	OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE + (inst) + (reg))
+
+/* CM_CORE_AON instances */
+#define OMAP54XX_CM_CORE_AON_OCP_SOCKET_INST	0x0000
+#define OMAP54XX_CM_CORE_AON_CKGEN_INST		0x0100
+#define OMAP54XX_CM_CORE_AON_MPU_INST		0x0300
+#define OMAP54XX_CM_CORE_AON_DSP_INST		0x0400
+#define OMAP54XX_CM_CORE_AON_ABE_INST		0x0500
+#define OMAP54XX_CM_CORE_AON_RESTORE_INST	0x0e00
+#define OMAP54XX_CM_CORE_AON_INSTR_INST		0x0f00
+
+/* CM_CORE_AON clockdomain register offsets (from instance start) */
+#define OMAP54XX_CM_CORE_AON_MPU_MPU_CDOFFS	0x0000
+#define OMAP54XX_CM_CORE_AON_DSP_DSP_CDOFFS	0x0000
+#define OMAP54XX_CM_CORE_AON_ABE_ABE_CDOFFS	0x0000
+
+/* CM_CORE_AON */
+
+/* CM_CORE_AON.OCP_SOCKET_CM_CORE_AON register offsets */
+#define OMAP54XX_REVISION_CM_CORE_AON_OFFSET			0x0000
+#define OMAP54XX_CM_CM_CORE_AON_PROFILING_CLKCTRL_OFFSET	0x0040
+#define OMAP54XX_CM_CM_CORE_AON_PROFILING_CLKCTRL		OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_OCP_SOCKET_INST, 0x0040)
+#define OMAP54XX_CM_CORE_AON_DEBUG_CFG_OFFSET			0x0080
+#define OMAP54XX_CM_CORE_AON_DEBUG_OUT_OFFSET			0x0084
+#define OMAP54XX_CM_CORE_AON_DEBUG_MPU_FD_TRANS_OFFSET		0x0090
+#define OMAP54XX_CM_CORE_AON_DEBUG_DSP_FD_TRANS_OFFSET		0x0094
+#define OMAP54XX_CM_CORE_AON_DEBUG_ABE_FD_TRANS_OFFSET		0x0098
+#define OMAP54XX_CM_CORE_AON_DEBUG_ABE_FD_TRANS2_OFFSET		0x009c
+#define OMAP54XX_CM_CORE_AON_DEBUG_CM_CORE_AON_FD_TRANS_OFFSET	0x00a0
+#define OMAP54XX_CM_CORE_AON_DEBUG_C2C_FD_TRANS_OFFSET		0x00a4
+#define OMAP54XX_CM_CORE_AON_DEBUG_CAM_FD_TRANS_OFFSET		0x00a8
+#define OMAP54XX_CM_CORE_AON_DEBUG_COREAON_FD_TRANS_OFFSET	0x00ac
+#define OMAP54XX_CM_CORE_AON_DEBUG_CUSTEFUSE_FD_TRANS_OFFSET	0x00b0
+#define OMAP54XX_CM_CORE_AON_DEBUG_DMA_FD_TRANS_OFFSET		0x00b4
+#define OMAP54XX_CM_CORE_AON_DEBUG_DSS_FD_TRANS_OFFSET		0x00b8
+#define OMAP54XX_CM_CORE_AON_DEBUG_EMIF_FD_TRANS_OFFSET		0x00bc
+#define OMAP54XX_CM_CORE_AON_DEBUG_GPU_FD_TRANS_OFFSET		0x00c0
+#define OMAP54XX_CM_CORE_AON_DEBUG_IPU_FD_TRANS_OFFSET		0x00c4
+#define OMAP54XX_CM_CORE_AON_DEBUG_IVA_FD_TRANS_OFFSET		0x00c8
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3INIT_FD_TRANS_OFFSET	0x00cc
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3INIT_FD_TRANS2_OFFSET	0x00d0
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3INSTR_FD_TRANS_OFFSET	0x00d4
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3MAIN1_FD_TRANS_OFFSET	0x00d8
+#define OMAP54XX_CM_CORE_AON_DEBUG_L3MAIN2_FD_TRANS_OFFSET	0x00dc
+#define OMAP54XX_CM_CORE_AON_DEBUG_L4CFG_FD_TRANS_OFFSET	0x00e0
+#define OMAP54XX_CM_CORE_AON_DEBUG_L4PER_FD_TRANS_OFFSET	0x00e4
+#define OMAP54XX_CM_CORE_AON_DEBUG_L4PER_FD_TRANS2_OFFSET	0x00e8
+#define OMAP54XX_CM_CORE_AON_DEBUG_L4SEC_FD_TRANS_OFFSET	0x00ec
+#define OMAP54XX_CM_CORE_AON_DEBUG_MIPIEXT_FD_TRANS_OFFSET	0x00f0
+
+/* CM_CORE_AON.CKGEN_CM_CORE_AON register offsets */
+#define OMAP54XX_CM_CLKSEL_CORE_OFFSET				0x0000
+#define OMAP54XX_CM_CLKSEL_CORE					OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0000)
+#define OMAP54XX_CM_CLKSEL_ABE_OFFSET				0x0008
+#define OMAP54XX_CM_CLKSEL_ABE					OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0008)
+#define OMAP54XX_CM_DLL_CTRL_OFFSET				0x0010
+#define OMAP54XX_CM_CLKMODE_DPLL_CORE_OFFSET			0x0020
+#define OMAP54XX_CM_CLKMODE_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0020)
+#define OMAP54XX_CM_IDLEST_DPLL_CORE_OFFSET			0x0024
+#define OMAP54XX_CM_IDLEST_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0024)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_CORE_OFFSET			0x0028
+#define OMAP54XX_CM_AUTOIDLE_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0028)
+#define OMAP54XX_CM_CLKSEL_DPLL_CORE_OFFSET			0x002c
+#define OMAP54XX_CM_CLKSEL_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x002c)
+#define OMAP54XX_CM_DIV_M2_DPLL_CORE_OFFSET			0x0030
+#define OMAP54XX_CM_DIV_M2_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0030)
+#define OMAP54XX_CM_DIV_M3_DPLL_CORE_OFFSET			0x0034
+#define OMAP54XX_CM_DIV_M3_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0034)
+#define OMAP54XX_CM_DIV_H11_DPLL_CORE_OFFSET			0x0038
+#define OMAP54XX_CM_DIV_H11_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0038)
+#define OMAP54XX_CM_DIV_H12_DPLL_CORE_OFFSET			0x003c
+#define OMAP54XX_CM_DIV_H12_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x003c)
+#define OMAP54XX_CM_DIV_H13_DPLL_CORE_OFFSET			0x0040
+#define OMAP54XX_CM_DIV_H13_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0040)
+#define OMAP54XX_CM_DIV_H14_DPLL_CORE_OFFSET			0x0044
+#define OMAP54XX_CM_DIV_H14_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0044)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET		0x0048
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET		0x004c
+#define OMAP54XX_CM_DIV_H21_DPLL_CORE_OFFSET			0x0050
+#define OMAP54XX_CM_DIV_H21_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0050)
+#define OMAP54XX_CM_DIV_H22_DPLL_CORE_OFFSET			0x0054
+#define OMAP54XX_CM_DIV_H22_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0054)
+#define OMAP54XX_CM_DIV_H23_DPLL_CORE_OFFSET			0x0058
+#define OMAP54XX_CM_DIV_H23_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0058)
+#define OMAP54XX_CM_DIV_H24_DPLL_CORE_OFFSET			0x005c
+#define OMAP54XX_CM_DIV_H24_DPLL_CORE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x005c)
+#define OMAP54XX_CM_CLKMODE_DPLL_MPU_OFFSET			0x0060
+#define OMAP54XX_CM_CLKMODE_DPLL_MPU				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0060)
+#define OMAP54XX_CM_IDLEST_DPLL_MPU_OFFSET			0x0064
+#define OMAP54XX_CM_IDLEST_DPLL_MPU				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0064)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_MPU_OFFSET			0x0068
+#define OMAP54XX_CM_AUTOIDLE_DPLL_MPU				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0068)
+#define OMAP54XX_CM_CLKSEL_DPLL_MPU_OFFSET			0x006c
+#define OMAP54XX_CM_CLKSEL_DPLL_MPU				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x006c)
+#define OMAP54XX_CM_DIV_M2_DPLL_MPU_OFFSET			0x0070
+#define OMAP54XX_CM_DIV_M2_DPLL_MPU				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x0070)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET		0x0088
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET		0x008c
+#define OMAP54XX_CM_BYPCLK_DPLL_MPU_OFFSET			0x009c
+#define OMAP54XX_CM_BYPCLK_DPLL_MPU				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x009c)
+#define OMAP54XX_CM_CLKMODE_DPLL_IVA_OFFSET			0x00a0
+#define OMAP54XX_CM_CLKMODE_DPLL_IVA				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00a0)
+#define OMAP54XX_CM_IDLEST_DPLL_IVA_OFFSET			0x00a4
+#define OMAP54XX_CM_IDLEST_DPLL_IVA				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00a4)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_IVA_OFFSET			0x00a8
+#define OMAP54XX_CM_AUTOIDLE_DPLL_IVA				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00a8)
+#define OMAP54XX_CM_CLKSEL_DPLL_IVA_OFFSET			0x00ac
+#define OMAP54XX_CM_CLKSEL_DPLL_IVA				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00ac)
+#define OMAP54XX_CM_DIV_H11_DPLL_IVA_OFFSET			0x00b8
+#define OMAP54XX_CM_DIV_H11_DPLL_IVA				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00b8)
+#define OMAP54XX_CM_DIV_H12_DPLL_IVA_OFFSET			0x00bc
+#define OMAP54XX_CM_DIV_H12_DPLL_IVA				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00bc)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET		0x00c8
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_IVA_OFFSET		0x00cc
+#define OMAP54XX_CM_BYPCLK_DPLL_IVA_OFFSET			0x00dc
+#define OMAP54XX_CM_BYPCLK_DPLL_IVA				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00dc)
+#define OMAP54XX_CM_CLKMODE_DPLL_ABE_OFFSET			0x00e0
+#define OMAP54XX_CM_CLKMODE_DPLL_ABE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00e0)
+#define OMAP54XX_CM_IDLEST_DPLL_ABE_OFFSET			0x00e4
+#define OMAP54XX_CM_IDLEST_DPLL_ABE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00e4)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_ABE_OFFSET			0x00e8
+#define OMAP54XX_CM_AUTOIDLE_DPLL_ABE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00e8)
+#define OMAP54XX_CM_CLKSEL_DPLL_ABE_OFFSET			0x00ec
+#define OMAP54XX_CM_CLKSEL_DPLL_ABE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00ec)
+#define OMAP54XX_CM_DIV_M2_DPLL_ABE_OFFSET			0x00f0
+#define OMAP54XX_CM_DIV_M2_DPLL_ABE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00f0)
+#define OMAP54XX_CM_DIV_M3_DPLL_ABE_OFFSET			0x00f4
+#define OMAP54XX_CM_DIV_M3_DPLL_ABE				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_CKGEN_INST, 0x00f4)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET		0x0108
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_ABE_OFFSET		0x010c
+#define OMAP54XX_CM_SHADOW_FREQ_CONFIG1_OFFSET			0x0160
+#define OMAP54XX_CM_SHADOW_FREQ_CONFIG2_OFFSET			0x0164
+#define OMAP54XX_CM_DYN_DEP_PRESCAL_OFFSET			0x0170
+#define OMAP54XX_CM_RESTORE_ST_OFFSET				0x0180
+
+/* CM_CORE_AON.MPU_CM_CORE_AON register offsets */
+#define OMAP54XX_CM_MPU_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_MPU_STATICDEP_OFFSET			0x0004
+#define OMAP54XX_CM_MPU_DYNAMICDEP_OFFSET			0x0008
+#define OMAP54XX_CM_MPU_MPU_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_MPU_MPU_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_MPU_INST, 0x0020)
+#define OMAP54XX_CM_MPU_MPU_MPU_DBG_CLKCTRL_OFFSET		0x0028
+#define OMAP54XX_CM_MPU_MPU_MPU_DBG_CLKCTRL			OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_MPU_INST, 0x0028)
+
+/* CM_CORE_AON.DSP_CM_CORE_AON register offsets */
+#define OMAP54XX_CM_DSP_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_DSP_STATICDEP_OFFSET			0x0004
+#define OMAP54XX_CM_DSP_DYNAMICDEP_OFFSET			0x0008
+#define OMAP54XX_CM_DSP_DSP_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_DSP_DSP_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_DSP_INST, 0x0020)
+
+/* CM_CORE_AON.ABE_CM_CORE_AON register offsets */
+#define OMAP54XX_CM_ABE_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_ABE_L4_ABE_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_ABE_L4_ABE_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0020)
+#define OMAP54XX_CM_ABE_AESS_CLKCTRL_OFFSET			0x0028
+#define OMAP54XX_CM_ABE_AESS_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0028)
+#define OMAP54XX_CM_ABE_MCPDM_CLKCTRL_OFFSET			0x0030
+#define OMAP54XX_CM_ABE_MCPDM_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0030)
+#define OMAP54XX_CM_ABE_DMIC_CLKCTRL_OFFSET			0x0038
+#define OMAP54XX_CM_ABE_DMIC_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0038)
+#define OMAP54XX_CM_ABE_MCASP_CLKCTRL_OFFSET			0x0040
+#define OMAP54XX_CM_ABE_MCASP_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0040)
+#define OMAP54XX_CM_ABE_MCBSP1_CLKCTRL_OFFSET			0x0048
+#define OMAP54XX_CM_ABE_MCBSP1_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0048)
+#define OMAP54XX_CM_ABE_MCBSP2_CLKCTRL_OFFSET			0x0050
+#define OMAP54XX_CM_ABE_MCBSP2_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0050)
+#define OMAP54XX_CM_ABE_MCBSP3_CLKCTRL_OFFSET			0x0058
+#define OMAP54XX_CM_ABE_MCBSP3_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0058)
+#define OMAP54XX_CM_ABE_SLIMBUS1_CLKCTRL_OFFSET			0x0060
+#define OMAP54XX_CM_ABE_SLIMBUS1_CLKCTRL			OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0060)
+#define OMAP54XX_CM_ABE_TIMER5_CLKCTRL_OFFSET			0x0068
+#define OMAP54XX_CM_ABE_TIMER5_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0068)
+#define OMAP54XX_CM_ABE_TIMER6_CLKCTRL_OFFSET			0x0070
+#define OMAP54XX_CM_ABE_TIMER6_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0070)
+#define OMAP54XX_CM_ABE_TIMER7_CLKCTRL_OFFSET			0x0078
+#define OMAP54XX_CM_ABE_TIMER7_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0078)
+#define OMAP54XX_CM_ABE_TIMER8_CLKCTRL_OFFSET			0x0080
+#define OMAP54XX_CM_ABE_TIMER8_CLKCTRL				OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0080)
+#define OMAP54XX_CM_ABE_WD_TIMER3_CLKCTRL_OFFSET		0x0088
+#define OMAP54XX_CM_ABE_WD_TIMER3_CLKCTRL			OMAP54XX_CM_CORE_AON_REGADDR(OMAP54XX_CM_CORE_AON_ABE_INST, 0x0088)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/cm2_44xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm2_44xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/cm2_44xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm2_44xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,8 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CM2_44XX_H
 #define __ARCH_ARM_MACH_OMAP2_CM2_44XX_H
 
+#include "cm_44xx_54xx.h"
+
 /* CM2 base address */
 #define OMAP4430_CM2_BASE		0x4a008000
 
@@ -449,9 +451,4 @@
 #define OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET		0x0020
 #define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL		OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0020)
 
-/* Function prototypes */
-extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx);
-extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx);
-extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
-
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/cm2_54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm2_54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/cm2_54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm2_54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,389 @@
+/*
+ * OMAP54xx CM2 instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM2_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM2_54XX_H
+
+#include "cm_44xx_54xx.h"
+
+/* CM2 base address */
+#define OMAP54XX_CM_CORE_BASE		0x4a008000
+
+#define OMAP54XX_CM_CORE_REGADDR(inst, reg)				\
+	OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE + (inst) + (reg))
+
+/* CM_CORE instances */
+#define OMAP54XX_CM_CORE_OCP_SOCKET_INST	0x0000
+#define OMAP54XX_CM_CORE_CKGEN_INST		0x0100
+#define OMAP54XX_CM_CORE_COREAON_INST		0x0600
+#define OMAP54XX_CM_CORE_CORE_INST		0x0700
+#define OMAP54XX_CM_CORE_IVA_INST		0x1200
+#define OMAP54XX_CM_CORE_CAM_INST		0x1300
+#define OMAP54XX_CM_CORE_DSS_INST		0x1400
+#define OMAP54XX_CM_CORE_GPU_INST		0x1500
+#define OMAP54XX_CM_CORE_L3INIT_INST		0x1600
+#define OMAP54XX_CM_CORE_CUSTEFUSE_INST		0x1700
+#define OMAP54XX_CM_CORE_RESTORE_INST		0x1e00
+#define OMAP54XX_CM_CORE_INSTR_INST		0x1f00
+
+/* CM_CORE clockdomain register offsets (from instance start) */
+#define OMAP54XX_CM_CORE_COREAON_COREAON_CDOFFS		0x0000
+#define OMAP54XX_CM_CORE_CORE_L3MAIN1_CDOFFS		0x0000
+#define OMAP54XX_CM_CORE_CORE_L3MAIN2_CDOFFS		0x0100
+#define OMAP54XX_CM_CORE_CORE_IPU_CDOFFS		0x0200
+#define OMAP54XX_CM_CORE_CORE_DMA_CDOFFS		0x0300
+#define OMAP54XX_CM_CORE_CORE_EMIF_CDOFFS		0x0400
+#define OMAP54XX_CM_CORE_CORE_C2C_CDOFFS		0x0500
+#define OMAP54XX_CM_CORE_CORE_L4CFG_CDOFFS		0x0600
+#define OMAP54XX_CM_CORE_CORE_L3INSTR_CDOFFS		0x0700
+#define OMAP54XX_CM_CORE_CORE_MIPIEXT_CDOFFS		0x0800
+#define OMAP54XX_CM_CORE_CORE_L4PER_CDOFFS		0x0900
+#define OMAP54XX_CM_CORE_CORE_L4SEC_CDOFFS		0x0a80
+#define OMAP54XX_CM_CORE_IVA_IVA_CDOFFS			0x0000
+#define OMAP54XX_CM_CORE_CAM_CAM_CDOFFS			0x0000
+#define OMAP54XX_CM_CORE_DSS_DSS_CDOFFS			0x0000
+#define OMAP54XX_CM_CORE_GPU_GPU_CDOFFS			0x0000
+#define OMAP54XX_CM_CORE_L3INIT_L3INIT_CDOFFS		0x0000
+#define OMAP54XX_CM_CORE_CUSTEFUSE_CUSTEFUSE_CDOFFS	0x0000
+
+/* CM_CORE */
+
+/* CM_CORE.OCP_SOCKET_CM_CORE register offsets */
+#define OMAP54XX_REVISION_CM_CORE_OFFSET			0x0000
+#define OMAP54XX_CM_CM_CORE_PROFILING_CLKCTRL_OFFSET		0x0040
+#define OMAP54XX_CM_CM_CORE_PROFILING_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_OCP_SOCKET_INST, 0x0040)
+#define OMAP54XX_CM_CORE_DEBUG_CFG_OFFSET			0x0080
+#define OMAP54XX_CM_CORE_DEBUG_OUT_OFFSET			0x0084
+
+/* CM_CORE.CKGEN_CM_CORE register offsets */
+#define OMAP54XX_CM_CLKSEL_USB_60MHZ_OFFSET			0x0004
+#define OMAP54XX_CM_CLKSEL_USB_60MHZ				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0004)
+#define OMAP54XX_CM_CLKMODE_DPLL_PER_OFFSET			0x0040
+#define OMAP54XX_CM_CLKMODE_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0040)
+#define OMAP54XX_CM_IDLEST_DPLL_PER_OFFSET			0x0044
+#define OMAP54XX_CM_IDLEST_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0044)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_PER_OFFSET			0x0048
+#define OMAP54XX_CM_AUTOIDLE_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0048)
+#define OMAP54XX_CM_CLKSEL_DPLL_PER_OFFSET			0x004c
+#define OMAP54XX_CM_CLKSEL_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x004c)
+#define OMAP54XX_CM_DIV_M2_DPLL_PER_OFFSET			0x0050
+#define OMAP54XX_CM_DIV_M2_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0050)
+#define OMAP54XX_CM_DIV_M3_DPLL_PER_OFFSET			0x0054
+#define OMAP54XX_CM_DIV_M3_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0054)
+#define OMAP54XX_CM_DIV_H11_DPLL_PER_OFFSET			0x0058
+#define OMAP54XX_CM_DIV_H11_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0058)
+#define OMAP54XX_CM_DIV_H12_DPLL_PER_OFFSET			0x005c
+#define OMAP54XX_CM_DIV_H12_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x005c)
+#define OMAP54XX_CM_DIV_H13_DPLL_PER_OFFSET			0x0060
+#define OMAP54XX_CM_DIV_H13_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0060)
+#define OMAP54XX_CM_DIV_H14_DPLL_PER_OFFSET			0x0064
+#define OMAP54XX_CM_DIV_H14_DPLL_PER				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0064)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET		0x0068
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET		0x006c
+#define OMAP54XX_CM_CLKMODE_DPLL_USB_OFFSET			0x0080
+#define OMAP54XX_CM_CLKMODE_DPLL_USB				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0080)
+#define OMAP54XX_CM_IDLEST_DPLL_USB_OFFSET			0x0084
+#define OMAP54XX_CM_IDLEST_DPLL_USB				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0084)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_USB_OFFSET			0x0088
+#define OMAP54XX_CM_AUTOIDLE_DPLL_USB				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0088)
+#define OMAP54XX_CM_CLKSEL_DPLL_USB_OFFSET			0x008c
+#define OMAP54XX_CM_CLKSEL_DPLL_USB				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x008c)
+#define OMAP54XX_CM_DIV_M2_DPLL_USB_OFFSET			0x0090
+#define OMAP54XX_CM_DIV_M2_DPLL_USB				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0090)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET		0x00a8
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_USB_OFFSET		0x00ac
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_USB_OFFSET			0x00b4
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_USB				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00b4)
+#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO2_OFFSET			0x00c0
+#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO2			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00c0)
+#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO2_OFFSET			0x00c4
+#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO2				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00c4)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO2_OFFSET		0x00c8
+#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO2			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00c8)
+#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO2_OFFSET			0x00cc
+#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO2				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00cc)
+#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO2_OFFSET			0x00d0
+#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO2				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00d0)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_UNIPRO2_OFFSET		0x00e8
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_UNIPRO2_OFFSET		0x00ec
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO2_OFFSET		0x00f4
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO2			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x00f4)
+#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO1_OFFSET			0x0100
+#define OMAP54XX_CM_CLKMODE_DPLL_UNIPRO1			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0100)
+#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO1_OFFSET			0x0104
+#define OMAP54XX_CM_IDLEST_DPLL_UNIPRO1				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0104)
+#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO1_OFFSET		0x0108
+#define OMAP54XX_CM_AUTOIDLE_DPLL_UNIPRO1			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0108)
+#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO1_OFFSET			0x010c
+#define OMAP54XX_CM_CLKSEL_DPLL_UNIPRO1				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x010c)
+#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO1_OFFSET			0x0110
+#define OMAP54XX_CM_DIV_M2_DPLL_UNIPRO1				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0110)
+#define OMAP54XX_CM_SSC_DELTAMSTEP_DPLL_UNIPRO1_OFFSET		0x0128
+#define OMAP54XX_CM_SSC_MODFREQDIV_DPLL_UNIPRO1_OFFSET		0x012c
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO1_OFFSET		0x0134
+#define OMAP54XX_CM_CLKDCOLDO_DPLL_UNIPRO1			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CKGEN_INST, 0x0134)
+
+/* CM_CORE.COREAON_CM_CORE register offsets */
+#define OMAP54XX_CM_COREAON_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL_OFFSET	0x0028
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL		OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0028)
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_MM_CLKCTRL_OFFSET	0x0030
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_MM_CLKCTRL		OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0030)
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL_OFFSET	0x0038
+#define OMAP54XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL		OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0038)
+#define OMAP54XX_CM_COREAON_USB_PHY_CORE_CLKCTRL_OFFSET		0x0040
+#define OMAP54XX_CM_COREAON_USB_PHY_CORE_CLKCTRL		OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0040)
+#define OMAP54XX_CM_COREAON_IO_SRCOMP_CLKCTRL_OFFSET		0x0050
+#define OMAP54XX_CM_COREAON_IO_SRCOMP_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_COREAON_INST, 0x0050)
+
+/* CM_CORE.CORE_CM_CORE register offsets */
+#define OMAP54XX_CM_L3MAIN1_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_L3MAIN1_DYNAMICDEP_OFFSET			0x0008
+#define OMAP54XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET		0x0020
+#define OMAP54XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0020)
+#define OMAP54XX_CM_L3MAIN2_CLKSTCTRL_OFFSET			0x0100
+#define OMAP54XX_CM_L3MAIN2_DYNAMICDEP_OFFSET			0x0108
+#define OMAP54XX_CM_L3MAIN2_L3_MAIN_2_CLKCTRL_OFFSET		0x0120
+#define OMAP54XX_CM_L3MAIN2_L3_MAIN_2_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0120)
+#define OMAP54XX_CM_L3MAIN2_GPMC_CLKCTRL_OFFSET			0x0128
+#define OMAP54XX_CM_L3MAIN2_GPMC_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0128)
+#define OMAP54XX_CM_L3MAIN2_OCMC_RAM_CLKCTRL_OFFSET		0x0130
+#define OMAP54XX_CM_L3MAIN2_OCMC_RAM_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0130)
+#define OMAP54XX_CM_IPU_CLKSTCTRL_OFFSET			0x0200
+#define OMAP54XX_CM_IPU_STATICDEP_OFFSET			0x0204
+#define OMAP54XX_CM_IPU_DYNAMICDEP_OFFSET			0x0208
+#define OMAP54XX_CM_IPU_IPU_CLKCTRL_OFFSET			0x0220
+#define OMAP54XX_CM_IPU_IPU_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0220)
+#define OMAP54XX_CM_DMA_CLKSTCTRL_OFFSET			0x0300
+#define OMAP54XX_CM_DMA_STATICDEP_OFFSET			0x0304
+#define OMAP54XX_CM_DMA_DYNAMICDEP_OFFSET			0x0308
+#define OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET		0x0320
+#define OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0320)
+#define OMAP54XX_CM_EMIF_CLKSTCTRL_OFFSET			0x0400
+#define OMAP54XX_CM_EMIF_DMM_CLKCTRL_OFFSET			0x0420
+#define OMAP54XX_CM_EMIF_DMM_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0420)
+#define OMAP54XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL_OFFSET		0x0428
+#define OMAP54XX_CM_EMIF_EMIF_OCP_FW_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0428)
+#define OMAP54XX_CM_EMIF_EMIF1_CLKCTRL_OFFSET			0x0430
+#define OMAP54XX_CM_EMIF_EMIF1_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0430)
+#define OMAP54XX_CM_EMIF_EMIF2_CLKCTRL_OFFSET			0x0438
+#define OMAP54XX_CM_EMIF_EMIF2_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0438)
+#define OMAP54XX_CM_EMIF_EMIF_DLL_CLKCTRL_OFFSET		0x0440
+#define OMAP54XX_CM_EMIF_EMIF_DLL_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0440)
+#define OMAP54XX_CM_C2C_CLKSTCTRL_OFFSET			0x0500
+#define OMAP54XX_CM_C2C_STATICDEP_OFFSET			0x0504
+#define OMAP54XX_CM_C2C_DYNAMICDEP_OFFSET			0x0508
+#define OMAP54XX_CM_C2C_C2C_CLKCTRL_OFFSET			0x0520
+#define OMAP54XX_CM_C2C_C2C_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0520)
+#define OMAP54XX_CM_C2C_MODEM_ICR_CLKCTRL_OFFSET		0x0528
+#define OMAP54XX_CM_C2C_MODEM_ICR_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0528)
+#define OMAP54XX_CM_C2C_C2C_OCP_FW_CLKCTRL_OFFSET		0x0530
+#define OMAP54XX_CM_C2C_C2C_OCP_FW_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0530)
+#define OMAP54XX_CM_L4CFG_CLKSTCTRL_OFFSET			0x0600
+#define OMAP54XX_CM_L4CFG_DYNAMICDEP_OFFSET			0x0608
+#define OMAP54XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET			0x0620
+#define OMAP54XX_CM_L4CFG_L4_CFG_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0620)
+#define OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET		0x0628
+#define OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0628)
+#define OMAP54XX_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET		0x0630
+#define OMAP54XX_CM_L4CFG_MAILBOX_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0630)
+#define OMAP54XX_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET		0x0638
+#define OMAP54XX_CM_L4CFG_SAR_ROM_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0638)
+#define OMAP54XX_CM_L4CFG_OCP2SCP2_CLKCTRL_OFFSET		0x0640
+#define OMAP54XX_CM_L4CFG_OCP2SCP2_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0640)
+#define OMAP54XX_CM_L3INSTR_CLKSTCTRL_OFFSET			0x0700
+#define OMAP54XX_CM_L3INSTR_L3_MAIN_3_CLKCTRL_OFFSET		0x0720
+#define OMAP54XX_CM_L3INSTR_L3_MAIN_3_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0720)
+#define OMAP54XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET		0x0728
+#define OMAP54XX_CM_L3INSTR_L3_INSTR_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0728)
+#define OMAP54XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL_OFFSET		0x0740
+#define OMAP54XX_CM_L3INSTR_OCP_WP_NOC_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0740)
+#define OMAP54XX_CM_L3INSTR_DLL_AGING_CLKCTRL_OFFSET		0x0748
+#define OMAP54XX_CM_L3INSTR_DLL_AGING_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0748)
+#define OMAP54XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL_OFFSET	0x0750
+#define OMAP54XX_CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL		OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0750)
+#define OMAP54XX_CM_MIPIEXT_CLKSTCTRL_OFFSET			0x0800
+#define OMAP54XX_CM_MIPIEXT_STATICDEP_OFFSET			0x0804
+#define OMAP54XX_CM_MIPIEXT_DYNAMICDEP_OFFSET			0x0808
+#define OMAP54XX_CM_MIPIEXT_LLI_CLKCTRL_OFFSET			0x0820
+#define OMAP54XX_CM_MIPIEXT_LLI_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0820)
+#define OMAP54XX_CM_MIPIEXT_LLI_OCP_FW_CLKCTRL_OFFSET		0x0828
+#define OMAP54XX_CM_MIPIEXT_LLI_OCP_FW_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0828)
+#define OMAP54XX_CM_MIPIEXT_MPHY_CLKCTRL_OFFSET			0x0830
+#define OMAP54XX_CM_MIPIEXT_MPHY_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0830)
+#define OMAP54XX_CM_L4PER_CLKSTCTRL_OFFSET			0x0900
+#define OMAP54XX_CM_L4PER_DYNAMICDEP_OFFSET			0x0908
+#define OMAP54XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET		0x0928
+#define OMAP54XX_CM_L4PER_TIMER10_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0928)
+#define OMAP54XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET		0x0930
+#define OMAP54XX_CM_L4PER_TIMER11_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0930)
+#define OMAP54XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET			0x0938
+#define OMAP54XX_CM_L4PER_TIMER2_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0938)
+#define OMAP54XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET			0x0940
+#define OMAP54XX_CM_L4PER_TIMER3_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0940)
+#define OMAP54XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET			0x0948
+#define OMAP54XX_CM_L4PER_TIMER4_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0948)
+#define OMAP54XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET			0x0950
+#define OMAP54XX_CM_L4PER_TIMER9_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0950)
+#define OMAP54XX_CM_L4PER_ELM_CLKCTRL_OFFSET			0x0958
+#define OMAP54XX_CM_L4PER_ELM_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0958)
+#define OMAP54XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET			0x0960
+#define OMAP54XX_CM_L4PER_GPIO2_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0960)
+#define OMAP54XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET			0x0968
+#define OMAP54XX_CM_L4PER_GPIO3_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0968)
+#define OMAP54XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET			0x0970
+#define OMAP54XX_CM_L4PER_GPIO4_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0970)
+#define OMAP54XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET			0x0978
+#define OMAP54XX_CM_L4PER_GPIO5_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0978)
+#define OMAP54XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET			0x0980
+#define OMAP54XX_CM_L4PER_GPIO6_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0980)
+#define OMAP54XX_CM_L4PER_HDQ1W_CLKCTRL_OFFSET			0x0988
+#define OMAP54XX_CM_L4PER_HDQ1W_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0988)
+#define OMAP54XX_CM_L4PER_I2C1_CLKCTRL_OFFSET			0x09a0
+#define OMAP54XX_CM_L4PER_I2C1_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09a0)
+#define OMAP54XX_CM_L4PER_I2C2_CLKCTRL_OFFSET			0x09a8
+#define OMAP54XX_CM_L4PER_I2C2_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09a8)
+#define OMAP54XX_CM_L4PER_I2C3_CLKCTRL_OFFSET			0x09b0
+#define OMAP54XX_CM_L4PER_I2C3_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09b0)
+#define OMAP54XX_CM_L4PER_I2C4_CLKCTRL_OFFSET			0x09b8
+#define OMAP54XX_CM_L4PER_I2C4_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09b8)
+#define OMAP54XX_CM_L4PER_L4_PER_CLKCTRL_OFFSET			0x09c0
+#define OMAP54XX_CM_L4PER_L4_PER_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09c0)
+#define OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET			0x09f0
+#define OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09f0)
+#define OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET			0x09f8
+#define OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x09f8)
+#define OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET			0x0a00
+#define OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a00)
+#define OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET			0x0a08
+#define OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a08)
+#define OMAP54XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET			0x0a10
+#define OMAP54XX_CM_L4PER_GPIO7_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a10)
+#define OMAP54XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET			0x0a18
+#define OMAP54XX_CM_L4PER_GPIO8_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a18)
+#define OMAP54XX_CM_L4PER_MMC3_CLKCTRL_OFFSET			0x0a20
+#define OMAP54XX_CM_L4PER_MMC3_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a20)
+#define OMAP54XX_CM_L4PER_MMC4_CLKCTRL_OFFSET			0x0a28
+#define OMAP54XX_CM_L4PER_MMC4_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a28)
+#define OMAP54XX_CM_L4PER_UART1_CLKCTRL_OFFSET			0x0a40
+#define OMAP54XX_CM_L4PER_UART1_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a40)
+#define OMAP54XX_CM_L4PER_UART2_CLKCTRL_OFFSET			0x0a48
+#define OMAP54XX_CM_L4PER_UART2_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a48)
+#define OMAP54XX_CM_L4PER_UART3_CLKCTRL_OFFSET			0x0a50
+#define OMAP54XX_CM_L4PER_UART3_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a50)
+#define OMAP54XX_CM_L4PER_UART4_CLKCTRL_OFFSET			0x0a58
+#define OMAP54XX_CM_L4PER_UART4_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a58)
+#define OMAP54XX_CM_L4PER_MMC5_CLKCTRL_OFFSET			0x0a60
+#define OMAP54XX_CM_L4PER_MMC5_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a60)
+#define OMAP54XX_CM_L4PER_I2C5_CLKCTRL_OFFSET			0x0a68
+#define OMAP54XX_CM_L4PER_I2C5_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a68)
+#define OMAP54XX_CM_L4PER_UART5_CLKCTRL_OFFSET			0x0a70
+#define OMAP54XX_CM_L4PER_UART5_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a70)
+#define OMAP54XX_CM_L4PER_UART6_CLKCTRL_OFFSET			0x0a78
+#define OMAP54XX_CM_L4PER_UART6_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0a78)
+#define OMAP54XX_CM_L4SEC_CLKSTCTRL_OFFSET			0x0a80
+#define OMAP54XX_CM_L4SEC_STATICDEP_OFFSET			0x0a84
+#define OMAP54XX_CM_L4SEC_DYNAMICDEP_OFFSET			0x0a88
+#define OMAP54XX_CM_L4SEC_AES1_CLKCTRL_OFFSET			0x0aa0
+#define OMAP54XX_CM_L4SEC_AES1_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0aa0)
+#define OMAP54XX_CM_L4SEC_AES2_CLKCTRL_OFFSET			0x0aa8
+#define OMAP54XX_CM_L4SEC_AES2_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0aa8)
+#define OMAP54XX_CM_L4SEC_DES3DES_CLKCTRL_OFFSET		0x0ab0
+#define OMAP54XX_CM_L4SEC_DES3DES_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ab0)
+#define OMAP54XX_CM_L4SEC_FPKA_CLKCTRL_OFFSET			0x0ab8
+#define OMAP54XX_CM_L4SEC_FPKA_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ab8)
+#define OMAP54XX_CM_L4SEC_RNG_CLKCTRL_OFFSET			0x0ac0
+#define OMAP54XX_CM_L4SEC_RNG_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ac0)
+#define OMAP54XX_CM_L4SEC_SHA2MD5_CLKCTRL_OFFSET		0x0ac8
+#define OMAP54XX_CM_L4SEC_SHA2MD5_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ac8)
+#define OMAP54XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL_OFFSET		0x0ad8
+#define OMAP54XX_CM_L4SEC_DMA_CRYPTO_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CORE_INST, 0x0ad8)
+
+/* CM_CORE.IVA_CM_CORE register offsets */
+#define OMAP54XX_CM_IVA_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_IVA_STATICDEP_OFFSET			0x0004
+#define OMAP54XX_CM_IVA_DYNAMICDEP_OFFSET			0x0008
+#define OMAP54XX_CM_IVA_IVA_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_IVA_IVA_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_IVA_INST, 0x0020)
+#define OMAP54XX_CM_IVA_SL2_CLKCTRL_OFFSET			0x0028
+#define OMAP54XX_CM_IVA_SL2_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_IVA_INST, 0x0028)
+
+/* CM_CORE.CAM_CM_CORE register offsets */
+#define OMAP54XX_CM_CAM_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_CAM_STATICDEP_OFFSET			0x0004
+#define OMAP54XX_CM_CAM_DYNAMICDEP_OFFSET			0x0008
+#define OMAP54XX_CM_CAM_ISS_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_CAM_ISS_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CAM_INST, 0x0020)
+#define OMAP54XX_CM_CAM_FDIF_CLKCTRL_OFFSET			0x0028
+#define OMAP54XX_CM_CAM_FDIF_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CAM_INST, 0x0028)
+#define OMAP54XX_CM_CAM_CAL_CLKCTRL_OFFSET			0x0030
+#define OMAP54XX_CM_CAM_CAL_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CAM_INST, 0x0030)
+
+/* CM_CORE.DSS_CM_CORE register offsets */
+#define OMAP54XX_CM_DSS_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_DSS_STATICDEP_OFFSET			0x0004
+#define OMAP54XX_CM_DSS_DYNAMICDEP_OFFSET			0x0008
+#define OMAP54XX_CM_DSS_DSS_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_DSS_DSS_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_DSS_INST, 0x0020)
+#define OMAP54XX_CM_DSS_BB2D_CLKCTRL_OFFSET			0x0030
+#define OMAP54XX_CM_DSS_BB2D_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_DSS_INST, 0x0030)
+
+/* CM_CORE.GPU_CM_CORE register offsets */
+#define OMAP54XX_CM_GPU_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_GPU_STATICDEP_OFFSET			0x0004
+#define OMAP54XX_CM_GPU_DYNAMICDEP_OFFSET			0x0008
+#define OMAP54XX_CM_GPU_GPU_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_GPU_GPU_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_GPU_INST, 0x0020)
+
+/* CM_CORE.L3INIT_CM_CORE register offsets */
+#define OMAP54XX_CM_L3INIT_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_L3INIT_STATICDEP_OFFSET			0x0004
+#define OMAP54XX_CM_L3INIT_DYNAMICDEP_OFFSET			0x0008
+#define OMAP54XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET			0x0028
+#define OMAP54XX_CM_L3INIT_MMC1_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0028)
+#define OMAP54XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET			0x0030
+#define OMAP54XX_CM_L3INIT_MMC2_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0030)
+#define OMAP54XX_CM_L3INIT_HSI_CLKCTRL_OFFSET			0x0038
+#define OMAP54XX_CM_L3INIT_HSI_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0038)
+#define OMAP54XX_CM_L3INIT_UNIPRO2_CLKCTRL_OFFSET		0x0040
+#define OMAP54XX_CM_L3INIT_UNIPRO2_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0040)
+#define OMAP54XX_CM_L3INIT_MPHY_UNIPRO2_CLKCTRL_OFFSET		0x0048
+#define OMAP54XX_CM_L3INIT_MPHY_UNIPRO2_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0048)
+#define OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL_OFFSET		0x0058
+#define OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0058)
+#define OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL_OFFSET		0x0068
+#define OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0068)
+#define OMAP54XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL_OFFSET	0x0078
+#define OMAP54XX_CM_L3INIT_IEEE1500_2_OCP_CLKCTRL		OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0078)
+#define OMAP54XX_CM_L3INIT_SATA_CLKCTRL_OFFSET			0x0088
+#define OMAP54XX_CM_L3INIT_SATA_CLKCTRL				OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x0088)
+#define OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET		0x00e0
+#define OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x00e0)
+#define OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET		0x00e8
+#define OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x00e8)
+#define OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL_OFFSET		0x00f0
+#define OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL			OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_L3INIT_INST, 0x00f0)
+
+/* CM_CORE.CUSTEFUSE_CM_CORE register offsets */
+#define OMAP54XX_CM_CUSTEFUSE_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL_OFFSET	0x0020
+#define OMAP54XX_CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL		OMAP54XX_CM_CORE_REGADDR(OMAP54XX_CM_CORE_CUSTEFUSE_INST, 0x0020)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/cm33xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm33xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/cm33xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm33xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -383,7 +383,7 @@ extern void am33xx_cm_clkdm_disable_hwsu
 extern void am33xx_cm_clkdm_force_sleep(s16 inst, u16 cdoffs);
 extern void am33xx_cm_clkdm_force_wakeup(s16 inst, u16 cdoffs);
 
-#ifdef CONFIG_SOC_AM33XX
+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
 extern int am33xx_cm_wait_module_idle(u16 inst, s16 cdoffs,
 					u16 clkctrl_offs);
 extern void am33xx_cm_module_enable(u8 mode, u16 inst, s16 cdoffs,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/cm_44xx_54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm_44xx_54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/cm_44xx_54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm_44xx_54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * OMAP44xx and OMAP54xx CM1/CM2 function prototypes
+ *
+ * Copyright (C) 2009-2013 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM_44XX_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_44XX_55XX_H
+
+/* CM1 Function prototypes */
+extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+
+/* CM2 Function prototypes */
+extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/cm-regbits-54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm-regbits-54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/cm-regbits-54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/cm-regbits-54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1737 @@
+/*
+ * OMAP54xx Clock Management register bits
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_54XX_H
+
+/* Used by CM_DSP_DYNAMICDEP, CM_L3MAIN1_DYNAMICDEP, CM_MPU_DYNAMICDEP */
+#define OMAP54XX_ABE_DYNDEP_SHIFT					3
+#define OMAP54XX_ABE_DYNDEP_WIDTH					0x1
+#define OMAP54XX_ABE_DYNDEP_MASK					(1 << 3)
+
+/*
+ * Used by CM_C2C_STATICDEP, CM_DMA_STATICDEP, CM_DSP_STATICDEP,
+ * CM_IPU_STATICDEP, CM_L3INIT_STATICDEP, CM_MIPIEXT_STATICDEP, CM_MPU_STATICDEP
+ */
+#define OMAP54XX_ABE_STATDEP_SHIFT					3
+#define OMAP54XX_ABE_STATDEP_WIDTH					0x1
+#define OMAP54XX_ABE_STATDEP_MASK					(1 << 3)
+
+/*
+ * Used by CM_AUTOIDLE_DPLL_ABE, CM_AUTOIDLE_DPLL_CORE, CM_AUTOIDLE_DPLL_IVA,
+ * CM_AUTOIDLE_DPLL_MPU, CM_AUTOIDLE_DPLL_PER, CM_AUTOIDLE_DPLL_UNIPRO1,
+ * CM_AUTOIDLE_DPLL_UNIPRO2, CM_AUTOIDLE_DPLL_USB
+ */
+#define OMAP54XX_AUTO_DPLL_MODE_SHIFT					0
+#define OMAP54XX_AUTO_DPLL_MODE_WIDTH					0x3
+#define OMAP54XX_AUTO_DPLL_MODE_MASK					(0x7 << 0)
+
+/* Used by CM_L3MAIN2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
+#define OMAP54XX_C2C_DYNDEP_SHIFT					18
+#define OMAP54XX_C2C_DYNDEP_WIDTH					0x1
+#define OMAP54XX_C2C_DYNDEP_MASK					(1 << 18)
+
+/* Used by CM_MPU_STATICDEP */
+#define OMAP54XX_C2C_STATDEP_SHIFT					18
+#define OMAP54XX_C2C_STATDEP_WIDTH					0x1
+#define OMAP54XX_C2C_STATDEP_MASK					(1 << 18)
+
+/* Used by CM_IPU_DYNAMICDEP, CM_L3MAIN2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
+#define OMAP54XX_CAM_DYNDEP_SHIFT					9
+#define OMAP54XX_CAM_DYNDEP_WIDTH					0x1
+#define OMAP54XX_CAM_DYNDEP_MASK					(1 << 9)
+
+/*
+ * Used by CM_DMA_STATICDEP, CM_DSP_STATICDEP, CM_IPU_STATICDEP,
+ * CM_MPU_STATICDEP
+ */
+#define OMAP54XX_CAM_STATDEP_SHIFT					9
+#define OMAP54XX_CAM_STATDEP_WIDTH					0x1
+#define OMAP54XX_CAM_STATDEP_MASK					(1 << 9)
+
+/* Used by CM_ABE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_ABE_24M_GFCLK_SHIFT			13
+#define OMAP54XX_CLKACTIVITY_ABE_24M_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_ABE_24M_GFCLK_MASK				(1 << 13)
+
+/* Used by CM_ABE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_ABE_32K_CLK_SHIFT				12
+#define OMAP54XX_CLKACTIVITY_ABE_32K_CLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_ABE_32K_CLK_MASK				(1 << 12)
+
+/* Used by CM_ABE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_ABE_GICLK_SHIFT				9
+#define OMAP54XX_CLKACTIVITY_ABE_GICLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_ABE_GICLK_MASK				(1 << 9)
+
+/* Used by CM_WKUPAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_ABE_LP_CLK_SHIFT				9
+#define OMAP54XX_CLKACTIVITY_ABE_LP_CLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_ABE_LP_CLK_MASK				(1 << 9)
+
+/* Used by CM_ABE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_ABE_SYS_CLK_SHIFT				11
+#define OMAP54XX_CLKACTIVITY_ABE_SYS_CLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_ABE_SYS_CLK_MASK				(1 << 11)
+
+/* Used by CM_ABE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_ABE_X2_CLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_ABE_X2_CLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_ABE_X2_CLK_MASK				(1 << 8)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_BB2D_GFCLK_SHIFT				13
+#define OMAP54XX_CLKACTIVITY_BB2D_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_BB2D_GFCLK_MASK				(1 << 13)
+
+/* Used by CM_C2C_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_C2C_GFCLK_SHIFT				9
+#define OMAP54XX_CLKACTIVITY_C2C_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_C2C_GFCLK_MASK				(1 << 9)
+
+/* Used by CM_C2C_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_C2C_GICLK_SHIFT				10
+#define OMAP54XX_CLKACTIVITY_C2C_GICLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_C2C_GICLK_MASK				(1 << 10)
+
+/* Used by CM_C2C_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_C2C_L4_GICLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_C2C_L4_GICLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_C2C_L4_GICLK_MASK				(1 << 8)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_CAM_BOOST_GCLK_SHIFT			11
+#define OMAP54XX_CLKACTIVITY_CAM_BOOST_GCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_CAM_BOOST_GCLK_MASK			(1 << 11)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_CAM_GCLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_CAM_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_CAM_GCLK_MASK				(1 << 8)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_CAM_L3_GICLK_SHIFT				12
+#define OMAP54XX_CLKACTIVITY_CAM_L3_GICLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_CAM_L3_GICLK_MASK				(1 << 12)
+
+/* Used by CM_COREAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_COREAON_32K_GFCLK_SHIFT			12
+#define OMAP54XX_CLKACTIVITY_COREAON_32K_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_COREAON_32K_GFCLK_MASK			(1 << 12)
+
+/* Used by CM_COREAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_COREAON_IO_SRCOMP_GFCLK_SHIFT		14
+#define OMAP54XX_CLKACTIVITY_COREAON_IO_SRCOMP_GFCLK_WIDTH		0x1
+#define OMAP54XX_CLKACTIVITY_COREAON_IO_SRCOMP_GFCLK_MASK		(1 << 14)
+
+/* Used by CM_COREAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_COREAON_L4_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_COREAON_L4_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_COREAON_L4_GICLK_MASK			(1 << 8)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_CSI_PHY_GFCLK_SHIFT			9
+#define OMAP54XX_CLKACTIVITY_CSI_PHY_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_CSI_PHY_GFCLK_MASK				(1 << 9)
+
+/* Used by CM_CUSTEFUSE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_CUSTEFUSE_L4_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_CUSTEFUSE_L4_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_CUSTEFUSE_L4_GICLK_MASK			(1 << 8)
+
+/* Used by CM_CUSTEFUSE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_CUSTEFUSE_SYS_GFCLK_SHIFT			9
+#define OMAP54XX_CLKACTIVITY_CUSTEFUSE_SYS_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_CUSTEFUSE_SYS_GFCLK_MASK			(1 << 9)
+
+/* Used by CM_EMIF_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_DLL_GCLK_SHIFT				9
+#define OMAP54XX_CLKACTIVITY_DLL_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_DLL_GCLK_MASK				(1 << 9)
+
+/* Used by CM_DMA_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_DMA_L3_GICLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_DMA_L3_GICLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_DMA_L3_GICLK_MASK				(1 << 8)
+
+/* Used by CM_DSP_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_DSP_GCLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_DSP_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_DSP_GCLK_MASK				(1 << 8)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_DSS_GFCLK_SHIFT				9
+#define OMAP54XX_CLKACTIVITY_DSS_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_DSS_GFCLK_MASK				(1 << 9)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_DSS_L3_GICLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_DSS_L3_GICLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_DSS_L3_GICLK_MASK				(1 << 8)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_DSS_SYS_GFCLK_SHIFT			10
+#define OMAP54XX_CLKACTIVITY_DSS_SYS_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_DSS_SYS_GFCLK_MASK				(1 << 10)
+
+/* Used by CM_EMIF_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_EMIF_L3_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_EMIF_L3_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_EMIF_L3_GICLK_MASK				(1 << 8)
+
+/* Used by CM_EMIF_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_EMIF_LL_GCLK_SHIFT				11
+#define OMAP54XX_CLKACTIVITY_EMIF_LL_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_EMIF_LL_GCLK_MASK				(1 << 11)
+
+/* Used by CM_EMIF_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_EMIF_PHY_GCLK_SHIFT			10
+#define OMAP54XX_CLKACTIVITY_EMIF_PHY_GCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_EMIF_PHY_GCLK_MASK				(1 << 10)
+
+/* Used by CM_EMU_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_EMU_SYS_GCLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_EMU_SYS_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_EMU_SYS_GCLK_MASK				(1 << 8)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_FDIF_GCLK_SHIFT				10
+#define OMAP54XX_CLKACTIVITY_FDIF_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_FDIF_GCLK_MASK				(1 << 10)
+
+/* Used by CM_ABE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_FUNC_24M_GFCLK_SHIFT			10
+#define OMAP54XX_CLKACTIVITY_FUNC_24M_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_FUNC_24M_GFCLK_MASK			(1 << 10)
+
+/* Used by CM_GPU_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_GPU_CORE_GCLK_SHIFT			9
+#define OMAP54XX_CLKACTIVITY_GPU_CORE_GCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_GPU_CORE_GCLK_MASK				(1 << 9)
+
+/* Used by CM_GPU_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_GPU_HYD_GCLK_SHIFT				10
+#define OMAP54XX_CLKACTIVITY_GPU_HYD_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_GPU_HYD_GCLK_MASK				(1 << 10)
+
+/* Used by CM_GPU_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_GPU_SYS_GCLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_GPU_SYS_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_GPU_SYS_GCLK_MASK				(1 << 8)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_HDMI_CEC_GFCLK_SHIFT			12
+#define OMAP54XX_CLKACTIVITY_HDMI_CEC_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_HDMI_CEC_GFCLK_MASK			(1 << 12)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_HDMI_PHY_GFCLK_SHIFT			11
+#define OMAP54XX_CLKACTIVITY_HDMI_PHY_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_HDMI_PHY_GFCLK_MASK			(1 << 11)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_HSIC_P1_480M_GFCLK_SHIFT			20
+#define OMAP54XX_CLKACTIVITY_HSIC_P1_480M_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_HSIC_P1_480M_GFCLK_MASK			(1 << 20)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_HSIC_P1_GFCLK_SHIFT			26
+#define OMAP54XX_CLKACTIVITY_HSIC_P1_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_HSIC_P1_GFCLK_MASK				(1 << 26)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_HSIC_P2_480M_GFCLK_SHIFT			21
+#define OMAP54XX_CLKACTIVITY_HSIC_P2_480M_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_HSIC_P2_480M_GFCLK_MASK			(1 << 21)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_HSIC_P2_GFCLK_SHIFT			27
+#define OMAP54XX_CLKACTIVITY_HSIC_P2_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_HSIC_P2_GFCLK_MASK				(1 << 27)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_HSIC_P3_480M_GFCLK_SHIFT			6
+#define OMAP54XX_CLKACTIVITY_HSIC_P3_480M_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_HSIC_P3_480M_GFCLK_MASK			(1 << 6)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_HSIC_P3_GFCLK_SHIFT			7
+#define OMAP54XX_CLKACTIVITY_HSIC_P3_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_HSIC_P3_GFCLK_MASK				(1 << 7)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_HSI_GFCLK_SHIFT				16
+#define OMAP54XX_CLKACTIVITY_HSI_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_HSI_GFCLK_MASK				(1 << 16)
+
+/* Used by CM_IPU_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_IPU_GCLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_IPU_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_IPU_GCLK_MASK				(1 << 8)
+
+/* Used by CM_IVA_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_IVA_GCLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_IVA_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_IVA_GCLK_MASK				(1 << 8)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3INIT_48M_GFCLK_SHIFT			12
+#define OMAP54XX_CLKACTIVITY_L3INIT_48M_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L3INIT_48M_GFCLK_MASK			(1 << 12)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3INIT_60M_P1_GFCLK_SHIFT			28
+#define OMAP54XX_CLKACTIVITY_L3INIT_60M_P1_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L3INIT_60M_P1_GFCLK_MASK			(1 << 28)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3INIT_60M_P2_GFCLK_SHIFT			29
+#define OMAP54XX_CLKACTIVITY_L3INIT_60M_P2_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L3INIT_60M_P2_GFCLK_MASK			(1 << 29)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3INIT_L3_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_L3INIT_L3_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L3INIT_L3_GICLK_MASK			(1 << 8)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3INIT_L4_GICLK_SHIFT			9
+#define OMAP54XX_CLKACTIVITY_L3INIT_L4_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L3INIT_L4_GICLK_MASK			(1 << 9)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3INIT_USB_OTG_SS_LFPS_TX_GFCLK_SHIFT	11
+#define OMAP54XX_CLKACTIVITY_L3INIT_USB_OTG_SS_LFPS_TX_GFCLK_WIDTH	0x1
+#define OMAP54XX_CLKACTIVITY_L3INIT_USB_OTG_SS_LFPS_TX_GFCLK_MASK	(1 << 11)
+
+/* Used by CM_L3INSTR_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3INSTR_DLL_AGING_GCLK_SHIFT		9
+#define OMAP54XX_CLKACTIVITY_L3INSTR_DLL_AGING_GCLK_WIDTH		0x1
+#define OMAP54XX_CLKACTIVITY_L3INSTR_DLL_AGING_GCLK_MASK		(1 << 9)
+
+/* Used by CM_L3INSTR_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3INSTR_L3_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_L3INSTR_L3_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L3INSTR_L3_GICLK_MASK			(1 << 8)
+
+/* Used by CM_L3INSTR_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3INSTR_TS_GCLK_SHIFT			10
+#define OMAP54XX_CLKACTIVITY_L3INSTR_TS_GCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L3INSTR_TS_GCLK_MASK			(1 << 10)
+
+/* Used by CM_L3MAIN1_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3MAIN1_L3_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_L3MAIN1_L3_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L3MAIN1_L3_GICLK_MASK			(1 << 8)
+
+/* Used by CM_L3MAIN2_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L3MAIN2_L3_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_L3MAIN2_L3_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L3MAIN2_L3_GICLK_MASK			(1 << 8)
+
+/* Used by CM_L4CFG_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L4CFG_L4_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_L4CFG_L4_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L4CFG_L4_GICLK_MASK			(1 << 8)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L4PER_L4_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_L4PER_L4_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L4PER_L4_GICLK_MASK			(1 << 8)
+
+/* Used by CM_L4SEC_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L4SEC_L3_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_L4SEC_L3_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L4SEC_L3_GICLK_MASK			(1 << 8)
+
+/* Used by CM_L4SEC_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_L4SEC_L4_GICLK_SHIFT			9
+#define OMAP54XX_CLKACTIVITY_L4SEC_L4_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_L4SEC_L4_GICLK_MASK			(1 << 9)
+
+/* Used by CM_MIPIEXT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_MIPIEXT_L3_GICLK_SHIFT			8
+#define OMAP54XX_CLKACTIVITY_MIPIEXT_L3_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_MIPIEXT_L3_GICLK_MASK			(1 << 8)
+
+/* Used by CM_MIPIEXT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_MIPIEXT_PHY_REF_GFCLK_SHIFT		11
+#define OMAP54XX_CLKACTIVITY_MIPIEXT_PHY_REF_GFCLK_WIDTH		0x1
+#define OMAP54XX_CLKACTIVITY_MIPIEXT_PHY_REF_GFCLK_MASK			(1 << 11)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_MMC1_32K_GFCLK_SHIFT			2
+#define OMAP54XX_CLKACTIVITY_MMC1_32K_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_MMC1_32K_GFCLK_MASK			(1 << 2)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_MMC1_GFCLK_SHIFT				17
+#define OMAP54XX_CLKACTIVITY_MMC1_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_MMC1_GFCLK_MASK				(1 << 17)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_MMC2_GFCLK_SHIFT				18
+#define OMAP54XX_CLKACTIVITY_MMC2_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_MMC2_GFCLK_MASK				(1 << 18)
+
+/* Used by CM_MPU_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_MPU_GCLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_MPU_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_MPU_GCLK_MASK				(1 << 8)
+
+/* Used by CM_ABE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_PAD_CLKS_SHIFT				14
+#define OMAP54XX_CLKACTIVITY_PAD_CLKS_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_PAD_CLKS_MASK				(1 << 14)
+
+/* Used by CM_ABE_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_PAD_SLIMBUS1_CLK_SHIFT			15
+#define OMAP54XX_CLKACTIVITY_PAD_SLIMBUS1_CLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_PAD_SLIMBUS1_CLK_MASK			(1 << 15)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_PAD_XCLK60MHSP1_SHIFT			3
+#define OMAP54XX_CLKACTIVITY_PAD_XCLK60MHSP1_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_PAD_XCLK60MHSP1_MASK			(1 << 3)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_PAD_XCLK60MHSP2_SHIFT			4
+#define OMAP54XX_CLKACTIVITY_PAD_XCLK60MHSP2_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_PAD_XCLK60MHSP2_MASK			(1 << 4)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_PER_12M_GFCLK_SHIFT			15
+#define OMAP54XX_CLKACTIVITY_PER_12M_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_PER_12M_GFCLK_MASK				(1 << 15)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_PER_32K_GFCLK_SHIFT			17
+#define OMAP54XX_CLKACTIVITY_PER_32K_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_PER_32K_GFCLK_MASK				(1 << 17)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_PER_48M_GFCLK_SHIFT			18
+#define OMAP54XX_CLKACTIVITY_PER_48M_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_PER_48M_GFCLK_MASK				(1 << 18)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_PER_96M_GFCLK_SHIFT			19
+#define OMAP54XX_CLKACTIVITY_PER_96M_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_PER_96M_GFCLK_MASK				(1 << 19)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_SATA_REF_GFCLK_SHIFT			19
+#define OMAP54XX_CLKACTIVITY_SATA_REF_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_SATA_REF_GFCLK_MASK			(1 << 19)
+
+/* Used by CM_COREAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_SR_CORE_SYS_GFCLK_SHIFT			11
+#define OMAP54XX_CLKACTIVITY_SR_CORE_SYS_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_SR_CORE_SYS_GFCLK_MASK			(1 << 11)
+
+/* Used by CM_COREAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_SR_MM_SYS_GFCLK_SHIFT			10
+#define OMAP54XX_CLKACTIVITY_SR_MM_SYS_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_SR_MM_SYS_GFCLK_MASK			(1 << 10)
+
+/* Used by CM_COREAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_SR_MPU_SYS_GFCLK_SHIFT			9
+#define OMAP54XX_CLKACTIVITY_SR_MPU_SYS_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_SR_MPU_SYS_GFCLK_MASK			(1 << 9)
+
+/* Used by CM_WKUPAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_SYS_CLK_SHIFT				8
+#define OMAP54XX_CLKACTIVITY_SYS_CLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_SYS_CLK_MASK				(1 << 8)
+
+/* Used by CM_WKUPAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_SYS_CLK_ALL_SHIFT				15
+#define OMAP54XX_CLKACTIVITY_SYS_CLK_ALL_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_SYS_CLK_ALL_MASK				(1 << 15)
+
+/* Used by CM_WKUPAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_SYS_CLK_FUNC_SHIFT				14
+#define OMAP54XX_CLKACTIVITY_SYS_CLK_FUNC_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_SYS_CLK_FUNC_MASK				(1 << 14)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_TIMER10_GFCLK_SHIFT			9
+#define OMAP54XX_CLKACTIVITY_TIMER10_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_TIMER10_GFCLK_MASK				(1 << 9)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_TIMER11_GFCLK_SHIFT			10
+#define OMAP54XX_CLKACTIVITY_TIMER11_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_TIMER11_GFCLK_MASK				(1 << 10)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_TIMER2_GFCLK_SHIFT				11
+#define OMAP54XX_CLKACTIVITY_TIMER2_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_TIMER2_GFCLK_MASK				(1 << 11)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_TIMER3_GFCLK_SHIFT				12
+#define OMAP54XX_CLKACTIVITY_TIMER3_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_TIMER3_GFCLK_MASK				(1 << 12)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_TIMER4_GFCLK_SHIFT				13
+#define OMAP54XX_CLKACTIVITY_TIMER4_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_TIMER4_GFCLK_MASK				(1 << 13)
+
+/* Used by CM_L4PER_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_TIMER9_GFCLK_SHIFT				14
+#define OMAP54XX_CLKACTIVITY_TIMER9_GFCLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_TIMER9_GFCLK_MASK				(1 << 14)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_TLL_CH0_GFCLK_SHIFT			22
+#define OMAP54XX_CLKACTIVITY_TLL_CH0_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_TLL_CH0_GFCLK_MASK				(1 << 22)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_TLL_CH1_GFCLK_SHIFT			23
+#define OMAP54XX_CLKACTIVITY_TLL_CH1_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_TLL_CH1_GFCLK_MASK				(1 << 23)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_TLL_CH2_GFCLK_SHIFT			24
+#define OMAP54XX_CLKACTIVITY_TLL_CH2_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_TLL_CH2_GFCLK_MASK				(1 << 24)
+
+/* Used by CM_MIPIEXT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_UNIPRO1_DPLL_CLK_SHIFT			10
+#define OMAP54XX_CLKACTIVITY_UNIPRO1_DPLL_CLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_UNIPRO1_DPLL_CLK_MASK			(1 << 10)
+
+/* Used by CM_MIPIEXT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_UNIPRO1_PHY_GFCLK_SHIFT			13
+#define OMAP54XX_CLKACTIVITY_UNIPRO1_PHY_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_UNIPRO1_PHY_GFCLK_MASK			(1 << 13)
+
+/* Used by CM_MIPIEXT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_UNIPRO1_TXPHY_LS_GFCLK_SHIFT		12
+#define OMAP54XX_CLKACTIVITY_UNIPRO1_TXPHY_LS_GFCLK_WIDTH		0x1
+#define OMAP54XX_CLKACTIVITY_UNIPRO1_TXPHY_LS_GFCLK_MASK		(1 << 12)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_UNIPRO2_DPLL_CLK_SHIFT			10
+#define OMAP54XX_CLKACTIVITY_UNIPRO2_DPLL_CLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_UNIPRO2_DPLL_CLK_MASK			(1 << 10)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_UNIPRO2_PHY_GFCLK_SHIFT			13
+#define OMAP54XX_CLKACTIVITY_UNIPRO2_PHY_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_UNIPRO2_PHY_GFCLK_MASK			(1 << 13)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_UNIPRO2_PHY_REF_GFCLK_SHIFT		5
+#define OMAP54XX_CLKACTIVITY_UNIPRO2_PHY_REF_GFCLK_WIDTH		0x1
+#define OMAP54XX_CLKACTIVITY_UNIPRO2_PHY_REF_GFCLK_MASK			(1 << 5)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_USB_DPLL_CLK_SHIFT				14
+#define OMAP54XX_CLKACTIVITY_USB_DPLL_CLK_WIDTH				0x1
+#define OMAP54XX_CLKACTIVITY_USB_DPLL_CLK_MASK				(1 << 14)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_USB_DPLL_HS_CLK_SHIFT			15
+#define OMAP54XX_CLKACTIVITY_USB_DPLL_HS_CLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_USB_DPLL_HS_CLK_MASK			(1 << 15)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_USB_OTG_SS_REF_CLK_SHIFT			31
+#define OMAP54XX_CLKACTIVITY_USB_OTG_SS_REF_CLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_USB_OTG_SS_REF_CLK_MASK			(1 << 31)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_UTMI_P3_GFCLK_SHIFT			30
+#define OMAP54XX_CLKACTIVITY_UTMI_P3_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_UTMI_P3_GFCLK_MASK				(1 << 30)
+
+/* Used by CM_L3INIT_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_UTMI_ROOT_GFCLK_SHIFT			25
+#define OMAP54XX_CLKACTIVITY_UTMI_ROOT_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_UTMI_ROOT_GFCLK_MASK			(1 << 25)
+
+/* Used by CM_WKUPAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_WKUPAON_32K_GFCLK_SHIFT			11
+#define OMAP54XX_CLKACTIVITY_WKUPAON_32K_GFCLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_WKUPAON_32K_GFCLK_MASK			(1 << 11)
+
+/* Used by CM_WKUPAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_WKUPAON_GICLK_SHIFT			12
+#define OMAP54XX_CLKACTIVITY_WKUPAON_GICLK_WIDTH			0x1
+#define OMAP54XX_CLKACTIVITY_WKUPAON_GICLK_MASK				(1 << 12)
+
+/* Used by CM_WKUPAON_CLKSTCTRL */
+#define OMAP54XX_CLKACTIVITY_WKUPAON_IO_SRCOMP_GFCLK_SHIFT		13
+#define OMAP54XX_CLKACTIVITY_WKUPAON_IO_SRCOMP_GFCLK_WIDTH		0x1
+#define OMAP54XX_CLKACTIVITY_WKUPAON_IO_SRCOMP_GFCLK_MASK		(1 << 13)
+
+/* Used by CM_COREAON_IO_SRCOMP_CLKCTRL, CM_WKUPAON_IO_SRCOMP_CLKCTRL */
+#define OMAP54XX_CLKEN_SRCOMP_FCLK_SHIFT				8
+#define OMAP54XX_CLKEN_SRCOMP_FCLK_WIDTH				0x1
+#define OMAP54XX_CLKEN_SRCOMP_FCLK_MASK					(1 << 8)
+
+/*
+ * Used by CM_ABE_TIMER5_CLKCTRL, CM_ABE_TIMER6_CLKCTRL, CM_ABE_TIMER7_CLKCTRL,
+ * CM_ABE_TIMER8_CLKCTRL, CM_L3INIT_HSI_CLKCTRL, CM_L4PER_TIMER10_CLKCTRL,
+ * CM_L4PER_TIMER11_CLKCTRL, CM_L4PER_TIMER2_CLKCTRL, CM_L4PER_TIMER3_CLKCTRL,
+ * CM_L4PER_TIMER4_CLKCTRL, CM_L4PER_TIMER9_CLKCTRL, CM_WKUPAON_TIMER1_CLKCTRL
+ */
+#define OMAP54XX_CLKSEL_SHIFT						24
+#define OMAP54XX_CLKSEL_WIDTH						0x1
+#define OMAP54XX_CLKSEL_MASK						(1 << 24)
+
+/*
+ * Renamed from CLKSEL Used by CM_CLKSEL_ABE_DSS_SYS, CM_CLKSEL_ABE_PLL_REF,
+ * CM_CLKSEL_USB_60MHZ, CM_CLKSEL_WKUPAON
+ */
+#define OMAP54XX_CLKSEL_0_0_SHIFT					0
+#define OMAP54XX_CLKSEL_0_0_WIDTH					0x1
+#define OMAP54XX_CLKSEL_0_0_MASK					(1 << 0)
+
+/* Renamed from CLKSEL Used by CM_BYPCLK_DPLL_IVA, CM_BYPCLK_DPLL_MPU */
+#define OMAP54XX_CLKSEL_0_1_SHIFT					0
+#define OMAP54XX_CLKSEL_0_1_WIDTH					0x2
+#define OMAP54XX_CLKSEL_0_1_MASK					(0x3 << 0)
+
+/* Renamed from CLKSEL Used by CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL */
+#define OMAP54XX_CLKSEL_24_25_SHIFT					24
+#define OMAP54XX_CLKSEL_24_25_WIDTH					0x2
+#define OMAP54XX_CLKSEL_24_25_MASK					(0x3 << 24)
+
+/* Used by CM_MPU_MPU_CLKCTRL */
+#define OMAP54XX_CLKSEL_ABE_DIV_MODE_SHIFT				26
+#define OMAP54XX_CLKSEL_ABE_DIV_MODE_WIDTH				0x1
+#define OMAP54XX_CLKSEL_ABE_DIV_MODE_MASK				(1 << 26)
+
+/* Used by CM_ABE_AESS_CLKCTRL */
+#define OMAP54XX_CLKSEL_AESS_FCLK_SHIFT					24
+#define OMAP54XX_CLKSEL_AESS_FCLK_WIDTH					0x1
+#define OMAP54XX_CLKSEL_AESS_FCLK_MASK					(1 << 24)
+
+/* Used by CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL */
+#define OMAP54XX_CLKSEL_DIV_SHIFT					25
+#define OMAP54XX_CLKSEL_DIV_WIDTH					0x1
+#define OMAP54XX_CLKSEL_DIV_MASK					(1 << 25)
+
+/* Used by CM_MPU_MPU_CLKCTRL */
+#define OMAP54XX_CLKSEL_EMIF_DIV_MODE_SHIFT				24
+#define OMAP54XX_CLKSEL_EMIF_DIV_MODE_WIDTH				0x2
+#define OMAP54XX_CLKSEL_EMIF_DIV_MODE_MASK				(0x3 << 24)
+
+/* Used by CM_CAM_FDIF_CLKCTRL */
+#define OMAP54XX_CLKSEL_FCLK_SHIFT					24
+#define OMAP54XX_CLKSEL_FCLK_WIDTH					0x1
+#define OMAP54XX_CLKSEL_FCLK_MASK					(1 << 24)
+
+/* Used by CM_GPU_GPU_CLKCTRL */
+#define OMAP54XX_CLKSEL_GPU_CORE_GCLK_SHIFT				24
+#define OMAP54XX_CLKSEL_GPU_CORE_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKSEL_GPU_CORE_GCLK_MASK				(1 << 24)
+
+/* Used by CM_GPU_GPU_CLKCTRL */
+#define OMAP54XX_CLKSEL_GPU_HYD_GCLK_SHIFT				25
+#define OMAP54XX_CLKSEL_GPU_HYD_GCLK_WIDTH				0x1
+#define OMAP54XX_CLKSEL_GPU_HYD_GCLK_MASK				(1 << 25)
+
+/* Used by CM_GPU_GPU_CLKCTRL */
+#define OMAP54XX_CLKSEL_GPU_SYS_CLK_SHIFT				26
+#define OMAP54XX_CLKSEL_GPU_SYS_CLK_WIDTH				0x1
+#define OMAP54XX_CLKSEL_GPU_SYS_CLK_MASK				(1 << 26)
+
+/*
+ * Used by CM_ABE_DMIC_CLKCTRL, CM_ABE_MCASP_CLKCTRL, CM_ABE_MCBSP1_CLKCTRL,
+ * CM_ABE_MCBSP2_CLKCTRL, CM_ABE_MCBSP3_CLKCTRL
+ */
+#define OMAP54XX_CLKSEL_INTERNAL_SOURCE_SHIFT				26
+#define OMAP54XX_CLKSEL_INTERNAL_SOURCE_WIDTH				0x2
+#define OMAP54XX_CLKSEL_INTERNAL_SOURCE_MASK				(0x3 << 26)
+
+/* Used by CM_CLKSEL_CORE */
+#define OMAP54XX_CLKSEL_L3_SHIFT					4
+#define OMAP54XX_CLKSEL_L3_WIDTH					0x1
+#define OMAP54XX_CLKSEL_L3_MASK						(1 << 4)
+
+/* Renamed from CLKSEL_L3 Used by CM_SHADOW_FREQ_CONFIG2 */
+#define OMAP54XX_CLKSEL_L3_1_1_SHIFT					1
+#define OMAP54XX_CLKSEL_L3_1_1_WIDTH					0x1
+#define OMAP54XX_CLKSEL_L3_1_1_MASK					(1 << 1)
+
+/* Used by CM_CLKSEL_CORE */
+#define OMAP54XX_CLKSEL_L4_SHIFT					8
+#define OMAP54XX_CLKSEL_L4_WIDTH					0x1
+#define OMAP54XX_CLKSEL_L4_MASK						(1 << 8)
+
+/* Used by CM_EMIF_EMIF1_CLKCTRL */
+#define OMAP54XX_CLKSEL_LL_SHIFT					24
+#define OMAP54XX_CLKSEL_LL_WIDTH					0x1
+#define OMAP54XX_CLKSEL_LL_MASK						(1 << 24)
+
+/* Used by CM_CLKSEL_ABE */
+#define OMAP54XX_CLKSEL_OPP_SHIFT					0
+#define OMAP54XX_CLKSEL_OPP_WIDTH					0x2
+#define OMAP54XX_CLKSEL_OPP_MASK					(0x3 << 0)
+
+/* Renamed from CLKSEL_OPP Used by CM_L3INIT_UNIPRO2_CLKCTRL */
+#define OMAP54XX_CLKSEL_OPP_24_24_SHIFT					24
+#define OMAP54XX_CLKSEL_OPP_24_24_WIDTH					0x1
+#define OMAP54XX_CLKSEL_OPP_24_24_MASK					(1 << 24)
+
+/*
+ * Used by CM_ABE_DMIC_CLKCTRL, CM_ABE_MCASP_CLKCTRL, CM_ABE_MCBSP1_CLKCTRL,
+ * CM_ABE_MCBSP2_CLKCTRL, CM_ABE_MCBSP3_CLKCTRL
+ */
+#define OMAP54XX_CLKSEL_SOURCE_SHIFT					24
+#define OMAP54XX_CLKSEL_SOURCE_WIDTH					0x2
+#define OMAP54XX_CLKSEL_SOURCE_MASK					(0x3 << 24)
+
+/*
+ * Renamed from CLKSEL_SOURCE Used by CM_L3INIT_MMC1_CLKCTRL,
+ * CM_L3INIT_MMC2_CLKCTRL
+ */
+#define OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_SHIFT			24
+#define OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_WIDTH			0x1
+#define OMAP54XX_CLKSEL_SOURCE_L3INIT_MMC1_MASK				(1 << 24)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_CLKSEL_UTMI_P1_SHIFT					24
+#define OMAP54XX_CLKSEL_UTMI_P1_WIDTH					0x1
+#define OMAP54XX_CLKSEL_UTMI_P1_MASK					(1 << 24)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_CLKSEL_UTMI_P2_SHIFT					25
+#define OMAP54XX_CLKSEL_UTMI_P2_WIDTH					0x1
+#define OMAP54XX_CLKSEL_UTMI_P2_MASK					(1 << 25)
+
+/*
+ * Used by CM_DIV_H11_DPLL_CORE, CM_DIV_H11_DPLL_IVA, CM_DIV_H11_DPLL_PER,
+ * CM_DIV_H12_DPLL_CORE, CM_DIV_H12_DPLL_IVA, CM_DIV_H12_DPLL_PER,
+ * CM_DIV_H13_DPLL_CORE, CM_DIV_H13_DPLL_PER, CM_DIV_H14_DPLL_CORE,
+ * CM_DIV_H14_DPLL_PER, CM_DIV_H21_DPLL_CORE, CM_DIV_H22_DPLL_CORE,
+ * CM_DIV_H23_DPLL_CORE, CM_DIV_H24_DPLL_CORE, CM_DIV_M2_DPLL_ABE,
+ * CM_DIV_M2_DPLL_CORE, CM_DIV_M2_DPLL_MPU, CM_DIV_M2_DPLL_PER,
+ * CM_DIV_M2_DPLL_UNIPRO1, CM_DIV_M2_DPLL_UNIPRO2, CM_DIV_M2_DPLL_USB,
+ * CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE, CM_DIV_M3_DPLL_PER
+ */
+#define OMAP54XX_CLKST_SHIFT						9
+#define OMAP54XX_CLKST_WIDTH						0x1
+#define OMAP54XX_CLKST_MASK						(1 << 9)
+
+/*
+ * Used by CM_ABE_CLKSTCTRL, CM_C2C_CLKSTCTRL, CM_CAM_CLKSTCTRL,
+ * CM_COREAON_CLKSTCTRL, CM_CUSTEFUSE_CLKSTCTRL, CM_DMA_CLKSTCTRL,
+ * CM_DSP_CLKSTCTRL, CM_DSS_CLKSTCTRL, CM_EMIF_CLKSTCTRL, CM_EMU_CLKSTCTRL,
+ * CM_GPU_CLKSTCTRL, CM_IPU_CLKSTCTRL, CM_IVA_CLKSTCTRL, CM_L3INIT_CLKSTCTRL,
+ * CM_L3INSTR_CLKSTCTRL, CM_L3MAIN1_CLKSTCTRL, CM_L3MAIN2_CLKSTCTRL,
+ * CM_L4CFG_CLKSTCTRL, CM_L4PER_CLKSTCTRL, CM_L4SEC_CLKSTCTRL,
+ * CM_MIPIEXT_CLKSTCTRL, CM_MPU_CLKSTCTRL, CM_WKUPAON_CLKSTCTRL
+ */
+#define OMAP54XX_CLKTRCTRL_SHIFT					0
+#define OMAP54XX_CLKTRCTRL_WIDTH					0x2
+#define OMAP54XX_CLKTRCTRL_MASK						(0x3 << 0)
+
+/* Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_PER */
+#define OMAP54XX_CLKX2ST_SHIFT						11
+#define OMAP54XX_CLKX2ST_WIDTH						0x1
+#define OMAP54XX_CLKX2ST_MASK						(1 << 11)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP54XX_COREAON_DYNDEP_SHIFT					16
+#define OMAP54XX_COREAON_DYNDEP_WIDTH					0x1
+#define OMAP54XX_COREAON_DYNDEP_MASK					(1 << 16)
+
+/* Used by CM_DSP_STATICDEP, CM_IPU_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP54XX_COREAON_STATDEP_SHIFT					16
+#define OMAP54XX_COREAON_STATDEP_WIDTH					0x1
+#define OMAP54XX_COREAON_STATDEP_MASK					(1 << 16)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP54XX_CUSTEFUSE_DYNDEP_SHIFT					17
+#define OMAP54XX_CUSTEFUSE_DYNDEP_WIDTH					0x1
+#define OMAP54XX_CUSTEFUSE_DYNDEP_MASK					(1 << 17)
+
+/* Used by CM_DSP_STATICDEP, CM_IPU_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP54XX_CUSTEFUSE_STATDEP_SHIFT				17
+#define OMAP54XX_CUSTEFUSE_STATDEP_WIDTH				0x1
+#define OMAP54XX_CUSTEFUSE_STATDEP_MASK					(1 << 17)
+
+/* Used by REVISION_CM_CORE, REVISION_CM_CORE_AON */
+#define OMAP54XX_CUSTOM_SHIFT						6
+#define OMAP54XX_CUSTOM_WIDTH						0x2
+#define OMAP54XX_CUSTOM_MASK						(0x3 << 6)
+
+/*
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO1,
+ * CM_CLKSEL_DPLL_UNIPRO2, CM_CLKSEL_DPLL_USB
+ */
+#define OMAP54XX_DCC_EN_SHIFT						22
+#define OMAP54XX_DCC_EN_WIDTH						0x1
+#define OMAP54XX_DCC_EN_MASK						(1 << 22)
+
+/*
+ * Used by CM_CORE_AON_DEBUG_CM_CORE_AON_FD_TRANS,
+ * CM_CORE_AON_DEBUG_DSS_FD_TRANS, CM_CORE_AON_DEBUG_EMIF_FD_TRANS,
+ * CM_CORE_AON_DEBUG_L4SEC_FD_TRANS
+ */
+#define OMAP54XX_CM_DEBUG_OUT_SHIFT					0
+#define OMAP54XX_CM_DEBUG_OUT_WIDTH					0xd
+#define OMAP54XX_CM_DEBUG_OUT_MASK					(0x1fff << 0)
+
+/*
+ * Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_ABE_FD_TRANS,
+ * CM_CORE_AON_DEBUG_L3INIT_FD_TRANS, CM_CORE_AON_DEBUG_L4PER_FD_TRANS
+ */
+#define OMAP54XX_DEBUG_OUT_0_31_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_31_WIDTH					0x20
+#define OMAP54XX_DEBUG_OUT_0_31_MASK					(0xffffffff << 0)
+
+/*
+ * Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_C2C_FD_TRANS,
+ * CM_CORE_AON_DEBUG_COREAON_FD_TRANS, CM_CORE_AON_DEBUG_L4CFG_FD_TRANS
+ */
+#define OMAP54XX_DEBUG_OUT_0_8_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_8_WIDTH					0x9
+#define OMAP54XX_DEBUG_OUT_0_8_MASK					(0x1ff << 0)
+
+/*
+ * Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_CUSTEFUSE_FD_TRANS,
+ * CM_CORE_AON_DEBUG_DMA_FD_TRANS, CM_CORE_AON_DEBUG_L3MAIN1_FD_TRANS
+ */
+#define OMAP54XX_DEBUG_OUT_0_4_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_4_WIDTH					0x5
+#define OMAP54XX_DEBUG_OUT_0_4_MASK					(0x1f << 0)
+
+/*
+ * Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_DSP_FD_TRANS,
+ * CM_CORE_AON_DEBUG_IPU_FD_TRANS, CM_CORE_AON_DEBUG_MPU_FD_TRANS
+ */
+#define OMAP54XX_DEBUG_OUT_0_5_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_5_WIDTH					0x6
+#define OMAP54XX_DEBUG_OUT_0_5_MASK					(0x3f << 0)
+
+/*
+ * Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_CAM_FD_TRANS,
+ * CM_CORE_AON_DEBUG_MIPIEXT_FD_TRANS
+ */
+#define OMAP54XX_DEBUG_OUT_0_10_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_10_WIDTH					0xb
+#define OMAP54XX_DEBUG_OUT_0_10_MASK					(0x7ff << 0)
+
+/*
+ * Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_IVA_FD_TRANS,
+ * CM_CORE_AON_DEBUG_L3MAIN2_FD_TRANS
+ */
+#define OMAP54XX_DEBUG_OUT_0_6_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_6_WIDTH					0x7
+#define OMAP54XX_DEBUG_OUT_0_6_MASK					(0x7f << 0)
+
+/* Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_ABE_FD_TRANS2 */
+#define OMAP54XX_DEBUG_OUT_0_19_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_19_WIDTH					0x14
+#define OMAP54XX_DEBUG_OUT_0_19_MASK					(0xfffff << 0)
+
+/* Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_GPU_FD_TRANS */
+#define OMAP54XX_DEBUG_OUT_0_9_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_9_WIDTH					0xa
+#define OMAP54XX_DEBUG_OUT_0_9_MASK					(0x3ff << 0)
+
+/* Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_L3INIT_FD_TRANS2 */
+#define OMAP54XX_DEBUG_OUT_0_26_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_26_WIDTH					0x1b
+#define OMAP54XX_DEBUG_OUT_0_26_MASK					(0x7ffffff << 0)
+
+/* Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_L3INSTR_FD_TRANS */
+#define OMAP54XX_DEBUG_OUT_0_13_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_13_WIDTH					0xe
+#define OMAP54XX_DEBUG_OUT_0_13_MASK					(0x3fff << 0)
+
+/* Renamed from DEBUG_OUT Used by CM_CORE_AON_DEBUG_L4PER_FD_TRANS2 */
+#define OMAP54XX_DEBUG_OUT_0_21_SHIFT					0
+#define OMAP54XX_DEBUG_OUT_0_21_WIDTH					0x16
+#define OMAP54XX_DEBUG_OUT_0_21_MASK					(0x3fffff << 0)
+
+/*
+ * Used by CM_SSC_DELTAMSTEP_DPLL_ABE, CM_SSC_DELTAMSTEP_DPLL_CORE,
+ * CM_SSC_DELTAMSTEP_DPLL_IVA, CM_SSC_DELTAMSTEP_DPLL_MPU,
+ * CM_SSC_DELTAMSTEP_DPLL_PER
+ */
+#define OMAP54XX_DELTAMSTEP_SHIFT					0
+#define OMAP54XX_DELTAMSTEP_WIDTH					0x14
+#define OMAP54XX_DELTAMSTEP_MASK					(0xfffff << 0)
+
+/*
+ * Renamed from DELTAMSTEP Used by CM_SSC_DELTAMSTEP_DPLL_UNIPRO1,
+ * CM_SSC_DELTAMSTEP_DPLL_UNIPRO2, CM_SSC_DELTAMSTEP_DPLL_USB
+ */
+#define OMAP54XX_DELTAMSTEP_0_20_SHIFT					0
+#define OMAP54XX_DELTAMSTEP_0_20_WIDTH					0x15
+#define OMAP54XX_DELTAMSTEP_0_20_MASK					(0x1fffff << 0)
+
+/*
+ * Used by CM_DIV_H11_DPLL_CORE, CM_DIV_H11_DPLL_IVA, CM_DIV_H11_DPLL_PER,
+ * CM_DIV_H12_DPLL_CORE, CM_DIV_H12_DPLL_IVA, CM_DIV_H12_DPLL_PER,
+ * CM_DIV_H13_DPLL_CORE, CM_DIV_H13_DPLL_PER, CM_DIV_H14_DPLL_CORE,
+ * CM_DIV_H14_DPLL_PER, CM_DIV_H21_DPLL_CORE, CM_DIV_H22_DPLL_CORE,
+ * CM_DIV_H23_DPLL_CORE, CM_DIV_H24_DPLL_CORE
+ */
+#define OMAP54XX_DIVHS_SHIFT						0
+#define OMAP54XX_DIVHS_WIDTH						0x6
+#define OMAP54XX_DIVHS_MASK						(0x3f << 0)
+
+/*
+ * Renamed from DIVHS Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_MPU, CM_DIV_M2_DPLL_PER, CM_DIV_M3_DPLL_ABE,
+ * CM_DIV_M3_DPLL_CORE, CM_DIV_M3_DPLL_PER
+ */
+#define OMAP54XX_DIVHS_0_4_SHIFT					0
+#define OMAP54XX_DIVHS_0_4_WIDTH					0x5
+#define OMAP54XX_DIVHS_0_4_MASK						(0x1f << 0)
+
+/*
+ * Renamed from DIVHS Used by CM_DIV_M2_DPLL_UNIPRO1, CM_DIV_M2_DPLL_UNIPRO2,
+ * CM_DIV_M2_DPLL_USB
+ */
+#define OMAP54XX_DIVHS_0_6_SHIFT					0
+#define OMAP54XX_DIVHS_0_6_WIDTH					0x7
+#define OMAP54XX_DIVHS_0_6_MASK						(0x7f << 0)
+
+/* Used by CM_DLL_CTRL */
+#define OMAP54XX_DLL_OVERRIDE_SHIFT					0
+#define OMAP54XX_DLL_OVERRIDE_WIDTH					0x1
+#define OMAP54XX_DLL_OVERRIDE_MASK					(1 << 0)
+
+/* Renamed from DLL_OVERRIDE Used by CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP54XX_DLL_OVERRIDE_2_2_SHIFT					2
+#define OMAP54XX_DLL_OVERRIDE_2_2_WIDTH					0x1
+#define OMAP54XX_DLL_OVERRIDE_2_2_MASK					(1 << 2)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP54XX_DLL_RESET_SHIFT					3
+#define OMAP54XX_DLL_RESET_WIDTH					0x1
+#define OMAP54XX_DLL_RESET_MASK						(1 << 3)
+
+/*
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO1,
+ * CM_CLKSEL_DPLL_UNIPRO2, CM_CLKSEL_DPLL_USB
+ */
+#define OMAP54XX_DPLL_BYP_CLKSEL_SHIFT					23
+#define OMAP54XX_DPLL_BYP_CLKSEL_WIDTH					0x1
+#define OMAP54XX_DPLL_BYP_CLKSEL_MASK					(1 << 23)
+
+/* Used by CM_CLKSEL_DPLL_CORE */
+#define OMAP54XX_DPLL_CLKOUTHIF_CLKSEL_SHIFT				20
+#define OMAP54XX_DPLL_CLKOUTHIF_CLKSEL_WIDTH				0x1
+#define OMAP54XX_DPLL_CLKOUTHIF_CLKSEL_MASK				(1 << 20)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP54XX_DPLL_CORE_DPLL_EN_SHIFT				8
+#define OMAP54XX_DPLL_CORE_DPLL_EN_WIDTH				0x3
+#define OMAP54XX_DPLL_CORE_DPLL_EN_MASK					(0x7 << 8)
+
+/* Used by CM_SHADOW_FREQ_CONFIG2 */
+#define OMAP54XX_DPLL_CORE_H12_DIV_SHIFT				2
+#define OMAP54XX_DPLL_CORE_H12_DIV_WIDTH				0x6
+#define OMAP54XX_DPLL_CORE_H12_DIV_MASK					(0x3f << 2)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP54XX_DPLL_CORE_M2_DIV_SHIFT					11
+#define OMAP54XX_DPLL_CORE_M2_DIV_WIDTH					0x5
+#define OMAP54XX_DPLL_CORE_M2_DIV_MASK					(0x1f << 11)
+
+/*
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER
+ */
+#define OMAP54XX_DPLL_DIV_SHIFT						0
+#define OMAP54XX_DPLL_DIV_WIDTH						0x7
+#define OMAP54XX_DPLL_DIV_MASK						(0x7f << 0)
+
+/*
+ * Renamed from DPLL_DIV Used by CM_CLKSEL_DPLL_UNIPRO1,
+ * CM_CLKSEL_DPLL_UNIPRO2, CM_CLKSEL_DPLL_USB
+ */
+#define OMAP54XX_DPLL_DIV_0_7_SHIFT					0
+#define OMAP54XX_DPLL_DIV_0_7_WIDTH					0x8
+#define OMAP54XX_DPLL_DIV_0_7_MASK					(0xff << 0)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
+ */
+#define OMAP54XX_DPLL_DRIFTGUARD_EN_SHIFT				8
+#define OMAP54XX_DPLL_DRIFTGUARD_EN_WIDTH				0x1
+#define OMAP54XX_DPLL_DRIFTGUARD_EN_MASK				(1 << 8)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO1,
+ * CM_CLKMODE_DPLL_UNIPRO2, CM_CLKMODE_DPLL_USB
+ */
+#define OMAP54XX_DPLL_EN_SHIFT						0
+#define OMAP54XX_DPLL_EN_WIDTH						0x3
+#define OMAP54XX_DPLL_EN_MASK						(0x7 << 0)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
+ */
+#define OMAP54XX_DPLL_LPMODE_EN_SHIFT					10
+#define OMAP54XX_DPLL_LPMODE_EN_WIDTH					0x1
+#define OMAP54XX_DPLL_LPMODE_EN_MASK					(1 << 10)
+
+/*
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER
+ */
+#define OMAP54XX_DPLL_MULT_SHIFT					8
+#define OMAP54XX_DPLL_MULT_WIDTH					0xb
+#define OMAP54XX_DPLL_MULT_MASK						(0x7ff << 8)
+
+/*
+ * Renamed from DPLL_MULT Used by CM_CLKSEL_DPLL_UNIPRO1,
+ * CM_CLKSEL_DPLL_UNIPRO2, CM_CLKSEL_DPLL_USB
+ */
+#define OMAP54XX_DPLL_MULT_UNIPRO1_SHIFT				8
+#define OMAP54XX_DPLL_MULT_UNIPRO1_WIDTH				0xc
+#define OMAP54XX_DPLL_MULT_UNIPRO1_MASK					(0xfff << 8)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
+ */
+#define OMAP54XX_DPLL_REGM4XEN_SHIFT					11
+#define OMAP54XX_DPLL_REGM4XEN_WIDTH					0x1
+#define OMAP54XX_DPLL_REGM4XEN_MASK					(1 << 11)
+
+/* Used by CM_CLKSEL_DPLL_UNIPRO1, CM_CLKSEL_DPLL_UNIPRO2, CM_CLKSEL_DPLL_USB */
+#define OMAP54XX_DPLL_SD_DIV_SHIFT					24
+#define OMAP54XX_DPLL_SD_DIV_WIDTH					0x8
+#define OMAP54XX_DPLL_SD_DIV_MASK					(0xff << 24)
+
+/* Used by CM_CLKSEL_DPLL_UNIPRO1, CM_CLKSEL_DPLL_UNIPRO2, CM_CLKSEL_DPLL_USB */
+#define OMAP54XX_DPLL_SELFREQDCO_SHIFT					21
+#define OMAP54XX_DPLL_SELFREQDCO_WIDTH					0x1
+#define OMAP54XX_DPLL_SELFREQDCO_MASK					(1 << 21)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO1,
+ * CM_CLKMODE_DPLL_UNIPRO2, CM_CLKMODE_DPLL_USB
+ */
+#define OMAP54XX_DPLL_SSC_ACK_SHIFT					13
+#define OMAP54XX_DPLL_SSC_ACK_WIDTH					0x1
+#define OMAP54XX_DPLL_SSC_ACK_MASK					(1 << 13)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO1,
+ * CM_CLKMODE_DPLL_UNIPRO2, CM_CLKMODE_DPLL_USB
+ */
+#define OMAP54XX_DPLL_SSC_DOWNSPREAD_SHIFT				14
+#define OMAP54XX_DPLL_SSC_DOWNSPREAD_WIDTH				0x1
+#define OMAP54XX_DPLL_SSC_DOWNSPREAD_MASK				(1 << 14)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO1,
+ * CM_CLKMODE_DPLL_UNIPRO2, CM_CLKMODE_DPLL_USB
+ */
+#define OMAP54XX_DPLL_SSC_EN_SHIFT					12
+#define OMAP54XX_DPLL_SSC_EN_WIDTH					0x1
+#define OMAP54XX_DPLL_SSC_EN_MASK					(1 << 12)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP54XX_DSP_DYNDEP_SHIFT					1
+#define OMAP54XX_DSP_DYNDEP_WIDTH					0x1
+#define OMAP54XX_DSP_DYNDEP_MASK					(1 << 1)
+
+/* Used by CM_IPU_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP54XX_DSP_STATDEP_SHIFT					1
+#define OMAP54XX_DSP_STATDEP_WIDTH					0x1
+#define OMAP54XX_DSP_STATDEP_MASK					(1 << 1)
+
+/* Used by CM_L3MAIN2_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
+#define OMAP54XX_DSS_DYNDEP_SHIFT					8
+#define OMAP54XX_DSS_DYNDEP_WIDTH					0x1
+#define OMAP54XX_DSS_DYNDEP_MASK					(1 << 8)
+
+/* Used by CM_DMA_STATICDEP, CM_IPU_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP54XX_DSS_STATDEP_SHIFT					8
+#define OMAP54XX_DSS_STATDEP_WIDTH					0x1
+#define OMAP54XX_DSS_STATDEP_MASK					(1 << 8)
+
+/*
+ * Used by CM_C2C_DYNAMICDEP, CM_L3MAIN1_DYNAMICDEP, CM_L4CFG_DYNAMICDEP,
+ * CM_MIPIEXT_DYNAMICDEP, CM_MPU_DYNAMICDEP
+ */
+#define OMAP54XX_EMIF_DYNDEP_SHIFT					4
+#define OMAP54XX_EMIF_DYNDEP_WIDTH					0x1
+#define OMAP54XX_EMIF_DYNDEP_MASK					(1 << 4)
+
+/*
+ * Used by CM_C2C_STATICDEP, CM_CAM_STATICDEP, CM_DMA_STATICDEP,
+ * CM_DSP_STATICDEP, CM_DSS_STATICDEP, CM_GPU_STATICDEP, CM_IPU_STATICDEP,
+ * CM_IVA_STATICDEP, CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP,
+ * CM_MIPIEXT_STATICDEP, CM_MPU_STATICDEP
+ */
+#define OMAP54XX_EMIF_STATDEP_SHIFT					4
+#define OMAP54XX_EMIF_STATDEP_WIDTH					0x1
+#define OMAP54XX_EMIF_STATDEP_MASK					(1 << 4)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1 */
+#define OMAP54XX_FREQ_UPDATE_SHIFT					0
+#define OMAP54XX_FREQ_UPDATE_WIDTH					0x1
+#define OMAP54XX_FREQ_UPDATE_MASK					(1 << 0)
+
+/* Used by REVISION_CM_CORE, REVISION_CM_CORE_AON */
+#define OMAP54XX_FUNC_SHIFT						16
+#define OMAP54XX_FUNC_WIDTH						0xc
+#define OMAP54XX_FUNC_MASK						(0xfff << 16)
+
+/* Used by CM_SHADOW_FREQ_CONFIG2 */
+#define OMAP54XX_GPMC_FREQ_UPDATE_SHIFT					0
+#define OMAP54XX_GPMC_FREQ_UPDATE_WIDTH					0x1
+#define OMAP54XX_GPMC_FREQ_UPDATE_MASK					(1 << 0)
+
+/* Used by CM_L3MAIN2_DYNAMICDEP */
+#define OMAP54XX_GPU_DYNDEP_SHIFT					10
+#define OMAP54XX_GPU_DYNDEP_WIDTH					0x1
+#define OMAP54XX_GPU_DYNDEP_MASK					(1 << 10)
+
+/* Used by CM_IPU_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP54XX_GPU_STATDEP_SHIFT					10
+#define OMAP54XX_GPU_STATDEP_WIDTH					0x1
+#define OMAP54XX_GPU_STATDEP_MASK					(1 << 10)
+
+/*
+ * Used by CM_ABE_AESS_CLKCTRL, CM_ABE_DMIC_CLKCTRL, CM_ABE_L4_ABE_CLKCTRL,
+ * CM_ABE_MCASP_CLKCTRL, CM_ABE_MCBSP1_CLKCTRL, CM_ABE_MCBSP2_CLKCTRL,
+ * CM_ABE_MCBSP3_CLKCTRL, CM_ABE_MCPDM_CLKCTRL, CM_ABE_SLIMBUS1_CLKCTRL,
+ * CM_ABE_TIMER5_CLKCTRL, CM_ABE_TIMER6_CLKCTRL, CM_ABE_TIMER7_CLKCTRL,
+ * CM_ABE_TIMER8_CLKCTRL, CM_ABE_WD_TIMER3_CLKCTRL, CM_C2C_C2C_CLKCTRL,
+ * CM_C2C_C2C_OCP_FW_CLKCTRL, CM_C2C_MODEM_ICR_CLKCTRL, CM_CAM_CAL_CLKCTRL,
+ * CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL, CM_CM_CORE_AON_PROFILING_CLKCTRL,
+ * CM_CM_CORE_PROFILING_CLKCTRL, CM_COREAON_SMARTREFLEX_CORE_CLKCTRL,
+ * CM_COREAON_SMARTREFLEX_MM_CLKCTRL, CM_COREAON_SMARTREFLEX_MPU_CLKCTRL,
+ * CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL, CM_DMA_DMA_SYSTEM_CLKCTRL,
+ * CM_DSP_DSP_CLKCTRL, CM_DSS_BB2D_CLKCTRL, CM_DSS_DSS_CLKCTRL,
+ * CM_EMIF_DMM_CLKCTRL, CM_EMIF_EMIF1_CLKCTRL, CM_EMIF_EMIF2_CLKCTRL,
+ * CM_EMIF_EMIF_OCP_FW_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL,
+ * CM_EMU_MPU_EMU_DBG_CLKCTRL, CM_GPU_GPU_CLKCTRL, CM_IPU_IPU_CLKCTRL,
+ * CM_IVA_IVA_CLKCTRL, CM_IVA_SL2_CLKCTRL, CM_L3INIT_HSI_CLKCTRL,
+ * CM_L3INIT_IEEE1500_2_OCP_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL,
+ * CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_MPHY_UNIPRO2_CLKCTRL,
+ * CM_L3INIT_OCP2SCP1_CLKCTRL, CM_L3INIT_OCP2SCP3_CLKCTRL,
+ * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_UNIPRO2_CLKCTRL,
+ * CM_L3INIT_USB_HOST_HS_CLKCTRL, CM_L3INIT_USB_OTG_SS_CLKCTRL,
+ * CM_L3INIT_USB_TLL_HS_CLKCTRL, CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL,
+ * CM_L3INSTR_DLL_AGING_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL,
+ * CM_L3INSTR_L3_MAIN_3_CLKCTRL, CM_L3INSTR_OCP_WP_NOC_CLKCTRL,
+ * CM_L3MAIN1_L3_MAIN_1_CLKCTRL, CM_L3MAIN2_GPMC_CLKCTRL,
+ * CM_L3MAIN2_L3_MAIN_2_CLKCTRL, CM_L3MAIN2_OCMC_RAM_CLKCTRL,
+ * CM_L4CFG_L4_CFG_CLKCTRL, CM_L4CFG_MAILBOX_CLKCTRL,
+ * CM_L4CFG_OCP2SCP2_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL,
+ * CM_L4CFG_SPINLOCK_CLKCTRL, CM_L4PER_ELM_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL,
+ * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL,
+ * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO7_CLKCTRL, CM_L4PER_GPIO8_CLKCTRL,
+ * CM_L4PER_HDQ1W_CLKCTRL, CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL,
+ * CM_L4PER_I2C3_CLKCTRL, CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL,
+ * CM_L4PER_L4_PER_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL,
+ * CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MMC3_CLKCTRL,
+ * CM_L4PER_MMC4_CLKCTRL, CM_L4PER_MMC5_CLKCTRL, CM_L4PER_TIMER10_CLKCTRL,
+ * CM_L4PER_TIMER11_CLKCTRL, CM_L4PER_TIMER2_CLKCTRL, CM_L4PER_TIMER3_CLKCTRL,
+ * CM_L4PER_TIMER4_CLKCTRL, CM_L4PER_TIMER9_CLKCTRL, CM_L4PER_UART1_CLKCTRL,
+ * CM_L4PER_UART2_CLKCTRL, CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL,
+ * CM_L4PER_UART5_CLKCTRL, CM_L4PER_UART6_CLKCTRL, CM_L4SEC_AES1_CLKCTRL,
+ * CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
+ * CM_L4SEC_DMA_CRYPTO_CLKCTRL, CM_L4SEC_FPKA_CLKCTRL, CM_L4SEC_RNG_CLKCTRL,
+ * CM_L4SEC_SHA2MD5_CLKCTRL, CM_MIPIEXT_LLI_CLKCTRL,
+ * CM_MIPIEXT_LLI_OCP_FW_CLKCTRL, CM_MIPIEXT_MPHY_CLKCTRL, CM_MPU_MPU_CLKCTRL,
+ * CM_MPU_MPU_MPU_DBG_CLKCTRL, CM_WKUPAON_COUNTER_32K_CLKCTRL,
+ * CM_WKUPAON_GPIO1_CLKCTRL, CM_WKUPAON_KBD_CLKCTRL,
+ * CM_WKUPAON_L4_WKUP_CLKCTRL, CM_WKUPAON_SAR_RAM_CLKCTRL,
+ * CM_WKUPAON_TIMER12_CLKCTRL, CM_WKUPAON_TIMER1_CLKCTRL,
+ * CM_WKUPAON_WD_TIMER1_CLKCTRL, CM_WKUPAON_WD_TIMER2_CLKCTRL
+ */
+#define OMAP54XX_IDLEST_SHIFT						16
+#define OMAP54XX_IDLEST_WIDTH						0x2
+#define OMAP54XX_IDLEST_MASK						(0x3 << 16)
+
+/* Used by CM_L3MAIN2_DYNAMICDEP */
+#define OMAP54XX_IPU_DYNDEP_SHIFT					0
+#define OMAP54XX_IPU_DYNDEP_WIDTH					0x1
+#define OMAP54XX_IPU_DYNDEP_MASK					(1 << 0)
+
+/* Used by CM_DMA_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP54XX_IPU_STATDEP_SHIFT					0
+#define OMAP54XX_IPU_STATDEP_WIDTH					0x1
+#define OMAP54XX_IPU_STATDEP_MASK					(1 << 0)
+
+/* Used by CM_DSP_DYNAMICDEP, CM_L3MAIN2_DYNAMICDEP */
+#define OMAP54XX_IVA_DYNDEP_SHIFT					2
+#define OMAP54XX_IVA_DYNDEP_WIDTH					0x1
+#define OMAP54XX_IVA_DYNDEP_MASK					(1 << 2)
+
+/*
+ * Used by CM_C2C_STATICDEP, CM_CAM_STATICDEP, CM_DMA_STATICDEP,
+ * CM_DSP_STATICDEP, CM_DSS_STATICDEP, CM_GPU_STATICDEP, CM_IPU_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_MIPIEXT_STATICDEP, CM_MPU_STATICDEP
+ */
+#define OMAP54XX_IVA_STATDEP_SHIFT					2
+#define OMAP54XX_IVA_STATDEP_WIDTH					0x1
+#define OMAP54XX_IVA_STATDEP_MASK					(1 << 2)
+
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
+#define OMAP54XX_L3INIT_DYNDEP_SHIFT					7
+#define OMAP54XX_L3INIT_DYNDEP_WIDTH					0x1
+#define OMAP54XX_L3INIT_DYNDEP_MASK					(1 << 7)
+
+/*
+ * Used by CM_C2C_STATICDEP, CM_DMA_STATICDEP, CM_DSP_STATICDEP,
+ * CM_IPU_STATICDEP, CM_MIPIEXT_STATICDEP, CM_MPU_STATICDEP
+ */
+#define OMAP54XX_L3INIT_STATDEP_SHIFT					7
+#define OMAP54XX_L3INIT_STATDEP_WIDTH					0x1
+#define OMAP54XX_L3INIT_STATDEP_MASK					(1 << 7)
+
+/*
+ * Used by CM_DSP_DYNAMICDEP, CM_DSS_DYNAMICDEP, CM_L3INIT_DYNAMICDEP,
+ * CM_L3MAIN2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP, CM_MPU_DYNAMICDEP
+ */
+#define OMAP54XX_L3MAIN1_DYNDEP_SHIFT					5
+#define OMAP54XX_L3MAIN1_DYNDEP_WIDTH					0x1
+#define OMAP54XX_L3MAIN1_DYNDEP_MASK					(1 << 5)
+
+/*
+ * Used by CM_C2C_STATICDEP, CM_CAM_STATICDEP, CM_DMA_STATICDEP,
+ * CM_DSP_STATICDEP, CM_DSS_STATICDEP, CM_GPU_STATICDEP, CM_IPU_STATICDEP,
+ * CM_IVA_STATICDEP, CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP,
+ * CM_MIPIEXT_STATICDEP, CM_MPU_STATICDEP
+ */
+#define OMAP54XX_L3MAIN1_STATDEP_SHIFT					5
+#define OMAP54XX_L3MAIN1_STATDEP_WIDTH					0x1
+#define OMAP54XX_L3MAIN1_STATDEP_MASK					(1 << 5)
+
+/*
+ * Used by CM_C2C_DYNAMICDEP, CM_CAM_DYNAMICDEP, CM_DMA_DYNAMICDEP,
+ * CM_DSS_DYNAMICDEP, CM_EMU_DYNAMICDEP, CM_GPU_DYNAMICDEP, CM_IPU_DYNAMICDEP,
+ * CM_IVA_DYNAMICDEP, CM_L3INIT_DYNAMICDEP, CM_L3MAIN1_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP, CM_L4SEC_DYNAMICDEP, CM_MIPIEXT_DYNAMICDEP
+ */
+#define OMAP54XX_L3MAIN2_DYNDEP_SHIFT					6
+#define OMAP54XX_L3MAIN2_DYNDEP_WIDTH					0x1
+#define OMAP54XX_L3MAIN2_DYNDEP_MASK					(1 << 6)
+
+/*
+ * Used by CM_C2C_STATICDEP, CM_CAM_STATICDEP, CM_DMA_STATICDEP,
+ * CM_DSP_STATICDEP, CM_DSS_STATICDEP, CM_GPU_STATICDEP, CM_IPU_STATICDEP,
+ * CM_IVA_STATICDEP, CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP,
+ * CM_MIPIEXT_STATICDEP, CM_MPU_STATICDEP
+ */
+#define OMAP54XX_L3MAIN2_STATDEP_SHIFT					6
+#define OMAP54XX_L3MAIN2_STATDEP_WIDTH					0x1
+#define OMAP54XX_L3MAIN2_STATDEP_MASK					(1 << 6)
+
+/* Used by CM_L3MAIN1_DYNAMICDEP */
+#define OMAP54XX_L4CFG_DYNDEP_SHIFT					12
+#define OMAP54XX_L4CFG_DYNDEP_WIDTH					0x1
+#define OMAP54XX_L4CFG_DYNDEP_MASK					(1 << 12)
+
+/*
+ * Used by CM_C2C_STATICDEP, CM_DMA_STATICDEP, CM_DSP_STATICDEP,
+ * CM_IPU_STATICDEP, CM_L3INIT_STATICDEP, CM_MIPIEXT_STATICDEP, CM_MPU_STATICDEP
+ */
+#define OMAP54XX_L4CFG_STATDEP_SHIFT					12
+#define OMAP54XX_L4CFG_STATDEP_WIDTH					0x1
+#define OMAP54XX_L4CFG_STATDEP_MASK					(1 << 12)
+
+/* Used by CM_L3MAIN2_DYNAMICDEP */
+#define OMAP54XX_L4PER_DYNDEP_SHIFT					13
+#define OMAP54XX_L4PER_DYNDEP_WIDTH					0x1
+#define OMAP54XX_L4PER_DYNDEP_MASK					(1 << 13)
+
+/*
+ * Used by CM_C2C_STATICDEP, CM_DMA_STATICDEP, CM_DSP_STATICDEP,
+ * CM_IPU_STATICDEP, CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP,
+ * CM_MIPIEXT_STATICDEP, CM_MPU_STATICDEP
+ */
+#define OMAP54XX_L4PER_STATDEP_SHIFT					13
+#define OMAP54XX_L4PER_STATDEP_WIDTH					0x1
+#define OMAP54XX_L4PER_STATDEP_MASK					(1 << 13)
+
+/* Used by CM_L3MAIN2_DYNAMICDEP, CM_L4PER_DYNAMICDEP */
+#define OMAP54XX_L4SEC_DYNDEP_SHIFT					14
+#define OMAP54XX_L4SEC_DYNDEP_WIDTH					0x1
+#define OMAP54XX_L4SEC_DYNDEP_MASK					(1 << 14)
+
+/*
+ * Used by CM_DMA_STATICDEP, CM_IPU_STATICDEP, CM_L3INIT_STATICDEP,
+ * CM_MPU_STATICDEP
+ */
+#define OMAP54XX_L4SEC_STATDEP_SHIFT					14
+#define OMAP54XX_L4SEC_STATDEP_WIDTH					0x1
+#define OMAP54XX_L4SEC_STATDEP_MASK					(1 << 14)
+
+/* Used by CM_L3MAIN2_DYNAMICDEP, CM_L4CFG_DYNAMICDEP */
+#define OMAP54XX_MIPIEXT_DYNDEP_SHIFT					21
+#define OMAP54XX_MIPIEXT_DYNDEP_WIDTH					0x1
+#define OMAP54XX_MIPIEXT_DYNDEP_MASK					(1 << 21)
+
+/* Used by CM_MPU_STATICDEP */
+#define OMAP54XX_MIPIEXT_STATDEP_SHIFT					21
+#define OMAP54XX_MIPIEXT_STATDEP_WIDTH					0x1
+#define OMAP54XX_MIPIEXT_STATDEP_MASK					(1 << 21)
+
+/*
+ * Used by CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
+ * CM_SSC_MODFREQDIV_DPLL_IVA, CM_SSC_MODFREQDIV_DPLL_MPU,
+ * CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO1,
+ * CM_SSC_MODFREQDIV_DPLL_UNIPRO2, CM_SSC_MODFREQDIV_DPLL_USB
+ */
+#define OMAP54XX_MODFREQDIV_EXPONENT_SHIFT				8
+#define OMAP54XX_MODFREQDIV_EXPONENT_WIDTH				0x3
+#define OMAP54XX_MODFREQDIV_EXPONENT_MASK				(0x7 << 8)
+
+/*
+ * Used by CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
+ * CM_SSC_MODFREQDIV_DPLL_IVA, CM_SSC_MODFREQDIV_DPLL_MPU,
+ * CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO1,
+ * CM_SSC_MODFREQDIV_DPLL_UNIPRO2, CM_SSC_MODFREQDIV_DPLL_USB
+ */
+#define OMAP54XX_MODFREQDIV_MANTISSA_SHIFT				0
+#define OMAP54XX_MODFREQDIV_MANTISSA_WIDTH				0x7
+#define OMAP54XX_MODFREQDIV_MANTISSA_MASK				(0x7f << 0)
+
+/*
+ * Used by CM_ABE_AESS_CLKCTRL, CM_ABE_DMIC_CLKCTRL, CM_ABE_L4_ABE_CLKCTRL,
+ * CM_ABE_MCASP_CLKCTRL, CM_ABE_MCBSP1_CLKCTRL, CM_ABE_MCBSP2_CLKCTRL,
+ * CM_ABE_MCBSP3_CLKCTRL, CM_ABE_MCPDM_CLKCTRL, CM_ABE_SLIMBUS1_CLKCTRL,
+ * CM_ABE_TIMER5_CLKCTRL, CM_ABE_TIMER6_CLKCTRL, CM_ABE_TIMER7_CLKCTRL,
+ * CM_ABE_TIMER8_CLKCTRL, CM_ABE_WD_TIMER3_CLKCTRL, CM_C2C_C2C_CLKCTRL,
+ * CM_C2C_C2C_OCP_FW_CLKCTRL, CM_C2C_MODEM_ICR_CLKCTRL, CM_CAM_CAL_CLKCTRL,
+ * CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL, CM_CM_CORE_AON_PROFILING_CLKCTRL,
+ * CM_CM_CORE_PROFILING_CLKCTRL, CM_COREAON_SMARTREFLEX_CORE_CLKCTRL,
+ * CM_COREAON_SMARTREFLEX_MM_CLKCTRL, CM_COREAON_SMARTREFLEX_MPU_CLKCTRL,
+ * CM_CUSTEFUSE_EFUSE_CTRL_CUST_CLKCTRL, CM_DMA_DMA_SYSTEM_CLKCTRL,
+ * CM_DSP_DSP_CLKCTRL, CM_DSS_BB2D_CLKCTRL, CM_DSS_DSS_CLKCTRL,
+ * CM_EMIF_DMM_CLKCTRL, CM_EMIF_EMIF1_CLKCTRL, CM_EMIF_EMIF2_CLKCTRL,
+ * CM_EMIF_EMIF_OCP_FW_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL,
+ * CM_EMU_MPU_EMU_DBG_CLKCTRL, CM_GPU_GPU_CLKCTRL, CM_IPU_IPU_CLKCTRL,
+ * CM_IVA_IVA_CLKCTRL, CM_IVA_SL2_CLKCTRL, CM_L3INIT_HSI_CLKCTRL,
+ * CM_L3INIT_IEEE1500_2_OCP_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL,
+ * CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_MPHY_UNIPRO2_CLKCTRL,
+ * CM_L3INIT_OCP2SCP1_CLKCTRL, CM_L3INIT_OCP2SCP3_CLKCTRL,
+ * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_UNIPRO2_CLKCTRL,
+ * CM_L3INIT_USB_HOST_HS_CLKCTRL, CM_L3INIT_USB_OTG_SS_CLKCTRL,
+ * CM_L3INIT_USB_TLL_HS_CLKCTRL, CM_L3INSTR_CTRL_MODULE_BANDGAP_CLKCTRL,
+ * CM_L3INSTR_DLL_AGING_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL,
+ * CM_L3INSTR_L3_MAIN_3_CLKCTRL, CM_L3INSTR_OCP_WP_NOC_CLKCTRL,
+ * CM_L3MAIN1_L3_MAIN_1_CLKCTRL, CM_L3MAIN2_GPMC_CLKCTRL,
+ * CM_L3MAIN2_L3_MAIN_2_CLKCTRL, CM_L3MAIN2_OCMC_RAM_CLKCTRL,
+ * CM_L4CFG_L4_CFG_CLKCTRL, CM_L4CFG_MAILBOX_CLKCTRL,
+ * CM_L4CFG_OCP2SCP2_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL,
+ * CM_L4CFG_SPINLOCK_CLKCTRL, CM_L4PER_ELM_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL,
+ * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL,
+ * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO7_CLKCTRL, CM_L4PER_GPIO8_CLKCTRL,
+ * CM_L4PER_HDQ1W_CLKCTRL, CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL,
+ * CM_L4PER_I2C3_CLKCTRL, CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL,
+ * CM_L4PER_L4_PER_CLKCTRL, CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL,
+ * CM_L4PER_MCSPI3_CLKCTRL, CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MMC3_CLKCTRL,
+ * CM_L4PER_MMC4_CLKCTRL, CM_L4PER_MMC5_CLKCTRL, CM_L4PER_TIMER10_CLKCTRL,
+ * CM_L4PER_TIMER11_CLKCTRL, CM_L4PER_TIMER2_CLKCTRL, CM_L4PER_TIMER3_CLKCTRL,
+ * CM_L4PER_TIMER4_CLKCTRL, CM_L4PER_TIMER9_CLKCTRL, CM_L4PER_UART1_CLKCTRL,
+ * CM_L4PER_UART2_CLKCTRL, CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL,
+ * CM_L4PER_UART5_CLKCTRL, CM_L4PER_UART6_CLKCTRL, CM_L4SEC_AES1_CLKCTRL,
+ * CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
+ * CM_L4SEC_DMA_CRYPTO_CLKCTRL, CM_L4SEC_FPKA_CLKCTRL, CM_L4SEC_RNG_CLKCTRL,
+ * CM_L4SEC_SHA2MD5_CLKCTRL, CM_MIPIEXT_LLI_CLKCTRL,
+ * CM_MIPIEXT_LLI_OCP_FW_CLKCTRL, CM_MIPIEXT_MPHY_CLKCTRL, CM_MPU_MPU_CLKCTRL,
+ * CM_MPU_MPU_MPU_DBG_CLKCTRL, CM_WKUPAON_COUNTER_32K_CLKCTRL,
+ * CM_WKUPAON_GPIO1_CLKCTRL, CM_WKUPAON_KBD_CLKCTRL,
+ * CM_WKUPAON_L4_WKUP_CLKCTRL, CM_WKUPAON_SAR_RAM_CLKCTRL,
+ * CM_WKUPAON_TIMER12_CLKCTRL, CM_WKUPAON_TIMER1_CLKCTRL,
+ * CM_WKUPAON_WD_TIMER1_CLKCTRL, CM_WKUPAON_WD_TIMER2_CLKCTRL
+ */
+#define OMAP54XX_MODULEMODE_SHIFT					0
+#define OMAP54XX_MODULEMODE_WIDTH					0x2
+#define OMAP54XX_MODULEMODE_MASK					(0x3 << 0)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP54XX_MPU_DYNDEP_SHIFT					19
+#define OMAP54XX_MPU_DYNDEP_WIDTH					0x1
+#define OMAP54XX_MPU_DYNDEP_MASK					(1 << 19)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_SHIFT				11
+#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_MASK				(1 << 11)
+
+/* Renamed from OPTFCLKEN_32KHZ_CLK Used by CM_L3INIT_MMC1_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_8_8_SHIFT				8
+#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_8_8_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_32KHZ_CLK_8_8_MASK				(1 << 8)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_48MHZ_CLK_SHIFT				9
+#define OMAP54XX_OPTFCLKEN_48MHZ_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_48MHZ_CLK_MASK				(1 << 9)
+
+/* Used by CM_COREAON_USB_PHY_CORE_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_CLK32K_SHIFT					8
+#define OMAP54XX_OPTFCLKEN_CLK32K_WIDTH					0x1
+#define OMAP54XX_OPTFCLKEN_CLK32K_MASK					(1 << 8)
+
+/* Used by CM_CAM_ISS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_CTRLCLK_SHIFT				8
+#define OMAP54XX_OPTFCLKEN_CTRLCLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_CTRLCLK_MASK					(1 << 8)
+
+/*
+ * Used by CM_L4PER_GPIO2_CLKCTRL, CM_L4PER_GPIO3_CLKCTRL,
+ * CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL, CM_L4PER_GPIO6_CLKCTRL,
+ * CM_L4PER_GPIO7_CLKCTRL, CM_L4PER_GPIO8_CLKCTRL, CM_WKUPAON_GPIO1_CLKCTRL
+ */
+#define OMAP54XX_OPTFCLKEN_DBCLK_SHIFT					8
+#define OMAP54XX_OPTFCLKEN_DBCLK_WIDTH					0x1
+#define OMAP54XX_OPTFCLKEN_DBCLK_MASK					(1 << 8)
+
+/* Used by CM_EMIF_EMIF_DLL_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_DLL_CLK_SHIFT				8
+#define OMAP54XX_OPTFCLKEN_DLL_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_DLL_CLK_MASK					(1 << 8)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_DSSCLK_SHIFT					8
+#define OMAP54XX_OPTFCLKEN_DSSCLK_WIDTH					0x1
+#define OMAP54XX_OPTFCLKEN_DSSCLK_MASK					(1 << 8)
+
+/* Used by CM_ABE_SLIMBUS1_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_FCLK0_SHIFT					8
+#define OMAP54XX_OPTFCLKEN_FCLK0_WIDTH					0x1
+#define OMAP54XX_OPTFCLKEN_FCLK0_MASK					(1 << 8)
+
+/* Used by CM_ABE_SLIMBUS1_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_FCLK1_SHIFT					9
+#define OMAP54XX_OPTFCLKEN_FCLK1_WIDTH					0x1
+#define OMAP54XX_OPTFCLKEN_FCLK1_MASK					(1 << 9)
+
+/* Used by CM_ABE_SLIMBUS1_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_FCLK2_SHIFT					10
+#define OMAP54XX_OPTFCLKEN_FCLK2_WIDTH					0x1
+#define OMAP54XX_OPTFCLKEN_FCLK2_MASK					(1 << 10)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_FUNC48M_CLK_SHIFT				15
+#define OMAP54XX_OPTFCLKEN_FUNC48M_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_FUNC48M_CLK_MASK				(1 << 15)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT			13
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P1_CLK_WIDTH			0x1
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P1_CLK_MASK				(1 << 13)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT			14
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P2_CLK_WIDTH			0x1
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P2_CLK_MASK				(1 << 14)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P3_CLK_SHIFT			7
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P3_CLK_WIDTH			0x1
+#define OMAP54XX_OPTFCLKEN_HSIC480M_P3_CLK_MASK				(1 << 7)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT				11
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P1_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P1_CLK_MASK				(1 << 11)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT				12
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P2_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P2_CLK_MASK				(1 << 12)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P3_CLK_SHIFT				6
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P3_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_HSIC60M_P3_CLK_MASK				(1 << 6)
+
+/* Used by CM_L3INIT_USB_OTG_SS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_REFCLK960M_SHIFT				8
+#define OMAP54XX_OPTFCLKEN_REFCLK960M_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_REFCLK960M_MASK				(1 << 8)
+
+/* Used by CM_L3INIT_SATA_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_REF_CLK_SHIFT				8
+#define OMAP54XX_OPTFCLKEN_REF_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_REF_CLK_MASK					(1 << 8)
+
+/* Used by CM_WKUPAON_SCRM_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_SCRM_CORE_SHIFT				8
+#define OMAP54XX_OPTFCLKEN_SCRM_CORE_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_SCRM_CORE_MASK				(1 << 8)
+
+/* Used by CM_WKUPAON_SCRM_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_SCRM_PER_SHIFT				9
+#define OMAP54XX_OPTFCLKEN_SCRM_PER_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_SCRM_PER_MASK				(1 << 9)
+
+/* Used by CM_ABE_SLIMBUS1_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_SLIMBUS_CLK_SHIFT				11
+#define OMAP54XX_OPTFCLKEN_SLIMBUS_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_SLIMBUS_CLK_MASK				(1 << 11)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_SYS_CLK_SHIFT				10
+#define OMAP54XX_OPTFCLKEN_SYS_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_SYS_CLK_MASK					(1 << 10)
+
+/* Used by CM_MIPIEXT_LLI_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_TXPHY_CLK_SHIFT				8
+#define OMAP54XX_OPTFCLKEN_TXPHY_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_TXPHY_CLK_MASK				(1 << 8)
+
+/* Used by CM_MIPIEXT_LLI_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_TXPHY_LS_CLK_SHIFT				9
+#define OMAP54XX_OPTFCLKEN_TXPHY_LS_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_TXPHY_LS_CLK_MASK				(1 << 9)
+
+/* Used by CM_L3INIT_USB_TLL_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_USB_CH0_CLK_SHIFT				8
+#define OMAP54XX_OPTFCLKEN_USB_CH0_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_USB_CH0_CLK_MASK				(1 << 8)
+
+/* Used by CM_L3INIT_USB_TLL_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_USB_CH1_CLK_SHIFT				9
+#define OMAP54XX_OPTFCLKEN_USB_CH1_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_USB_CH1_CLK_MASK				(1 << 9)
+
+/* Used by CM_L3INIT_USB_TLL_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_USB_CH2_CLK_SHIFT				10
+#define OMAP54XX_OPTFCLKEN_USB_CH2_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_USB_CH2_CLK_MASK				(1 << 10)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_UTMI_P1_CLK_SHIFT				8
+#define OMAP54XX_OPTFCLKEN_UTMI_P1_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_UTMI_P1_CLK_MASK				(1 << 8)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_UTMI_P2_CLK_SHIFT				9
+#define OMAP54XX_OPTFCLKEN_UTMI_P2_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_UTMI_P2_CLK_MASK				(1 << 9)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL */
+#define OMAP54XX_OPTFCLKEN_UTMI_P3_CLK_SHIFT				10
+#define OMAP54XX_OPTFCLKEN_UTMI_P3_CLK_WIDTH				0x1
+#define OMAP54XX_OPTFCLKEN_UTMI_P3_CLK_MASK				(1 << 10)
+
+/* Used by CM_CORE_AON_DEBUG_OUT, CM_CORE_DEBUG_OUT */
+#define OMAP54XX_OUTPUT_SHIFT						0
+#define OMAP54XX_OUTPUT_WIDTH						0x20
+#define OMAP54XX_OUTPUT_MASK						(0xffffffff << 0)
+
+/* Used by CM_CLKSEL_ABE */
+#define OMAP54XX_PAD_CLKS_GATE_SHIFT					8
+#define OMAP54XX_PAD_CLKS_GATE_WIDTH					0x1
+#define OMAP54XX_PAD_CLKS_GATE_MASK					(1 << 8)
+
+/* Used by CM_RESTORE_ST */
+#define OMAP54XX_PHASE1_COMPLETED_SHIFT					0
+#define OMAP54XX_PHASE1_COMPLETED_WIDTH					0x1
+#define OMAP54XX_PHASE1_COMPLETED_MASK					(1 << 0)
+
+/* Used by CM_RESTORE_ST */
+#define OMAP54XX_PHASE2A_COMPLETED_SHIFT				1
+#define OMAP54XX_PHASE2A_COMPLETED_WIDTH				0x1
+#define OMAP54XX_PHASE2A_COMPLETED_MASK					(1 << 1)
+
+/* Used by CM_RESTORE_ST */
+#define OMAP54XX_PHASE2B_COMPLETED_SHIFT				2
+#define OMAP54XX_PHASE2B_COMPLETED_WIDTH				0x1
+#define OMAP54XX_PHASE2B_COMPLETED_MASK					(1 << 2)
+
+/* Used by CM_DYN_DEP_PRESCAL */
+#define OMAP54XX_PRESCAL_SHIFT						0
+#define OMAP54XX_PRESCAL_WIDTH						0x6
+#define OMAP54XX_PRESCAL_MASK						(0x3f << 0)
+
+/* Used by REVISION_CM_CORE, REVISION_CM_CORE_AON */
+#define OMAP54XX_R_RTL_SHIFT						11
+#define OMAP54XX_R_RTL_WIDTH						0x5
+#define OMAP54XX_R_RTL_MASK						(0x1f << 11)
+
+/* Used by CM_L3INIT_USB_HOST_HS_CLKCTRL, CM_L3INIT_USB_TLL_HS_CLKCTRL */
+#define OMAP54XX_SAR_MODE_SHIFT						4
+#define OMAP54XX_SAR_MODE_WIDTH						0x1
+#define OMAP54XX_SAR_MODE_MASK						(1 << 4)
+
+/* Used by REVISION_CM_CORE, REVISION_CM_CORE_AON */
+#define OMAP54XX_SCHEME_SHIFT						30
+#define OMAP54XX_SCHEME_WIDTH						0x2
+#define OMAP54XX_SCHEME_MASK						(0x3 << 30)
+
+/* Used by CM_L4CFG_DYNAMICDEP */
+#define OMAP54XX_SDMA_DYNDEP_SHIFT					11
+#define OMAP54XX_SDMA_DYNDEP_WIDTH					0x1
+#define OMAP54XX_SDMA_DYNDEP_MASK					(1 << 11)
+
+/* Used by CM_IPU_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP54XX_SDMA_STATDEP_SHIFT					11
+#define OMAP54XX_SDMA_STATDEP_WIDTH					0x1
+#define OMAP54XX_SDMA_STATDEP_MASK					(1 << 11)
+
+/* Used by CM_CORE_AON_DEBUG_CFG */
+#define OMAP54XX_SEL0_SHIFT						0
+#define OMAP54XX_SEL0_WIDTH						0x7
+#define OMAP54XX_SEL0_MASK						(0x7f << 0)
+
+/* Renamed from SEL0 Used by CM_CORE_DEBUG_CFG */
+#define OMAP54XX_SEL0_0_7_SHIFT						0
+#define OMAP54XX_SEL0_0_7_WIDTH						0x8
+#define OMAP54XX_SEL0_0_7_MASK						(0xff << 0)
+
+/* Used by CM_CORE_AON_DEBUG_CFG */
+#define OMAP54XX_SEL1_SHIFT						8
+#define OMAP54XX_SEL1_WIDTH						0x7
+#define OMAP54XX_SEL1_MASK						(0x7f << 8)
+
+/* Renamed from SEL1 Used by CM_CORE_DEBUG_CFG */
+#define OMAP54XX_SEL1_CORE_DEBUG_CFG_SHIFT				8
+#define OMAP54XX_SEL1_CORE_DEBUG_CFG_WIDTH				0x8
+#define OMAP54XX_SEL1_CORE_DEBUG_CFG_MASK				(0xff << 8)
+
+/* Used by CM_CORE_AON_DEBUG_CFG */
+#define OMAP54XX_SEL2_SHIFT						16
+#define OMAP54XX_SEL2_WIDTH						0x7
+#define OMAP54XX_SEL2_MASK						(0x7f << 16)
+
+/* Renamed from SEL2 Used by CM_CORE_DEBUG_CFG */
+#define OMAP54XX_SEL2_CORE_DEBUG_CFG_SHIFT				16
+#define OMAP54XX_SEL2_CORE_DEBUG_CFG_WIDTH				0x8
+#define OMAP54XX_SEL2_CORE_DEBUG_CFG_MASK				(0xff << 16)
+
+/* Used by CM_CORE_AON_DEBUG_CFG */
+#define OMAP54XX_SEL3_SHIFT						24
+#define OMAP54XX_SEL3_WIDTH						0x7
+#define OMAP54XX_SEL3_MASK						(0x7f << 24)
+
+/* Renamed from SEL3 Used by CM_CORE_DEBUG_CFG */
+#define OMAP54XX_SEL3_CORE_DEBUG_CFG_SHIFT				24
+#define OMAP54XX_SEL3_CORE_DEBUG_CFG_WIDTH				0x8
+#define OMAP54XX_SEL3_CORE_DEBUG_CFG_MASK				(0xff << 24)
+
+/* Used by CM_CLKSEL_ABE */
+#define OMAP54XX_SLIMBUS1_CLK_GATE_SHIFT				10
+#define OMAP54XX_SLIMBUS1_CLK_GATE_WIDTH				0x1
+#define OMAP54XX_SLIMBUS1_CLK_GATE_MASK					(1 << 10)
+
+/*
+ * Used by CM_ABE_AESS_CLKCTRL, CM_C2C_C2C_CLKCTRL, CM_CAM_FDIF_CLKCTRL,
+ * CM_CAM_ISS_CLKCTRL, CM_DMA_DMA_SYSTEM_CLKCTRL, CM_DSP_DSP_CLKCTRL,
+ * CM_DSS_BB2D_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL,
+ * CM_GPU_GPU_CLKCTRL, CM_IPU_IPU_CLKCTRL, CM_IVA_IVA_CLKCTRL,
+ * CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_IEEE1500_2_OCP_CLKCTRL,
+ * CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_SATA_CLKCTRL,
+ * CM_L3INIT_UNIPRO2_CLKCTRL, CM_L3INIT_USB_HOST_HS_CLKCTRL,
+ * CM_L3INIT_USB_OTG_SS_CLKCTRL, CM_L4SEC_DMA_CRYPTO_CLKCTRL,
+ * CM_MIPIEXT_LLI_CLKCTRL, CM_MPU_MPU_CLKCTRL
+ */
+#define OMAP54XX_STBYST_SHIFT						18
+#define OMAP54XX_STBYST_WIDTH						0x1
+#define OMAP54XX_STBYST_MASK						(1 << 18)
+
+/*
+ * Used by CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_IVA,
+ * CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER, CM_IDLEST_DPLL_UNIPRO1,
+ * CM_IDLEST_DPLL_UNIPRO2, CM_IDLEST_DPLL_USB
+ */
+#define OMAP54XX_ST_DPLL_CLK_SHIFT					0
+#define OMAP54XX_ST_DPLL_CLK_WIDTH					0x1
+#define OMAP54XX_ST_DPLL_CLK_MASK					(1 << 0)
+
+/*
+ * Used by CM_CLKDCOLDO_DPLL_UNIPRO1, CM_CLKDCOLDO_DPLL_UNIPRO2,
+ * CM_CLKDCOLDO_DPLL_USB
+ */
+#define OMAP54XX_ST_DPLL_CLKDCOLDO_SHIFT				9
+#define OMAP54XX_ST_DPLL_CLKDCOLDO_WIDTH				0x1
+#define OMAP54XX_ST_DPLL_CLKDCOLDO_MASK					(1 << 9)
+
+/*
+ * Used by CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_IVA,
+ * CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER, CM_IDLEST_DPLL_UNIPRO1,
+ * CM_IDLEST_DPLL_UNIPRO2, CM_IDLEST_DPLL_USB
+ */
+#define OMAP54XX_ST_DPLL_INIT_SHIFT					4
+#define OMAP54XX_ST_DPLL_INIT_WIDTH					0x1
+#define OMAP54XX_ST_DPLL_INIT_MASK					(1 << 4)
+
+/*
+ * Used by CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_IVA,
+ * CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER, CM_IDLEST_DPLL_UNIPRO1,
+ * CM_IDLEST_DPLL_UNIPRO2, CM_IDLEST_DPLL_USB
+ */
+#define OMAP54XX_ST_DPLL_MODE_SHIFT					1
+#define OMAP54XX_ST_DPLL_MODE_WIDTH					0x3
+#define OMAP54XX_ST_DPLL_MODE_MASK					(0x7 << 1)
+
+/* Used by CM_CLKSEL_SYS */
+#define OMAP54XX_SYS_CLKSEL_SHIFT					0
+#define OMAP54XX_SYS_CLKSEL_WIDTH					0x3
+#define OMAP54XX_SYS_CLKSEL_MASK					(0x7 << 0)
+
+/*
+ * Used by CM_C2C_DYNAMICDEP, CM_DSP_DYNAMICDEP, CM_EMU_DYNAMICDEP,
+ * CM_IPU_DYNAMICDEP, CM_L3MAIN1_DYNAMICDEP, CM_L3MAIN2_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP, CM_L4PER_DYNAMICDEP, CM_MIPIEXT_DYNAMICDEP,
+ * CM_MPU_DYNAMICDEP
+ */
+#define OMAP54XX_WINDOWSIZE_SHIFT					24
+#define OMAP54XX_WINDOWSIZE_WIDTH					0x4
+#define OMAP54XX_WINDOWSIZE_MASK					(0xf << 24)
+
+/* Used by CM_L3MAIN1_DYNAMICDEP */
+#define OMAP54XX_WKUPAON_DYNDEP_SHIFT					15
+#define OMAP54XX_WKUPAON_DYNDEP_WIDTH					0x1
+#define OMAP54XX_WKUPAON_DYNDEP_MASK					(1 << 15)
+
+/*
+ * Used by CM_DMA_STATICDEP, CM_DSP_STATICDEP, CM_IPU_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_MPU_STATICDEP
+ */
+#define OMAP54XX_WKUPAON_STATDEP_SHIFT					15
+#define OMAP54XX_WKUPAON_STATDEP_WIDTH					0x1
+#define OMAP54XX_WKUPAON_STATDEP_MASK					(1 << 15)
+
+/* Used by REVISION_CM_CORE, REVISION_CM_CORE_AON */
+#define OMAP54XX_X_MAJOR_SHIFT						8
+#define OMAP54XX_X_MAJOR_WIDTH						0x3
+#define OMAP54XX_X_MAJOR_MASK						(0x7 << 8)
+
+/* Used by REVISION_CM_CORE, REVISION_CM_CORE_AON */
+#define OMAP54XX_Y_MINOR_SHIFT						0
+#define OMAP54XX_Y_MINOR_WIDTH						0x6
+#define OMAP54XX_Y_MINOR_MASK						(0x3f << 0)
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c/twl.h>
 #include <linux/i2c-omap.h>
+#include <linux/reboot.h>
 
 #include <asm/proc-fns.h>
 
@@ -96,6 +97,7 @@ void am33xx_init_early(void);
 void am35xx_init_early(void);
 void ti81xx_init_early(void);
 void am33xx_init_early(void);
+void am43xx_init_early(void);
 void omap4430_init_early(void);
 void omap5_init_early(void);
 void omap3_init_late(void);	/* Do not use this one */
@@ -118,33 +120,33 @@ static inline void omap_soc_device_init(
 #endif
 
 #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
-void omap2xxx_restart(char mode, const char *cmd);
+void omap2xxx_restart(enum reboot_mode mode, const char *cmd);
 #else
-static inline void omap2xxx_restart(char mode, const char *cmd)
+static inline void omap2xxx_restart(enum reboot_mode mode, const char *cmd)
 {
 }
 #endif
 
 #ifdef CONFIG_SOC_AM33XX
-void am33xx_restart(char mode, const char *cmd);
+void am33xx_restart(enum reboot_mode mode, const char *cmd);
 #else
-static inline void am33xx_restart(char mode, const char *cmd)
+static inline void am33xx_restart(enum reboot_mode mode, const char *cmd)
 {
 }
 #endif
 
 #ifdef CONFIG_ARCH_OMAP3
-void omap3xxx_restart(char mode, const char *cmd);
+void omap3xxx_restart(enum reboot_mode mode, const char *cmd);
 #else
-static inline void omap3xxx_restart(char mode, const char *cmd)
+static inline void omap3xxx_restart(enum reboot_mode mode, const char *cmd)
 {
 }
 #endif
 
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
-void omap44xx_restart(char mode, const char *cmd);
+void omap44xx_restart(enum reboot_mode mode, const char *cmd);
 #else
-static inline void omap44xx_restart(char mode, const char *cmd)
+static inline void omap44xx_restart(enum reboot_mode mode, const char *cmd)
 {
 }
 #endif
@@ -237,8 +239,8 @@ extern void omap_do_wfi(void);
 
 #ifdef CONFIG_SMP
 /* Needed for secondary core boot */
-extern void omap_secondary_startup(void);
-extern void omap_secondary_startup_4460(void);
+extern void omap4_secondary_startup(void);
+extern void omap4460_secondary_startup(void);
 extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
 extern void omap_auxcoreboot_addr(u32 cpu_addr);
 extern u32 omap_read_auxcoreboot0(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/control.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/control.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/control.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/control.c	2013-08-25 20:43:22.000000000 -0400
@@ -249,6 +249,7 @@ void omap_ctrl_write_dsp_boot_addr(u32 b
 	u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTADDR :
 		     cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTADDR :
 		     cpu_is_omap44xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR :
+		     soc_is_omap54xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR :
 		     0;
 
 	if (!offset) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/control.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/control.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/control.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/control.h	2013-08-25 20:43:22.000000000 -0400
@@ -358,6 +358,18 @@
 #define AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH		0x2
 #define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK		(0x3 << 22)
 
+/* AM33XX PWMSS Control register */
+#define AM33XX_PWMSS_TBCLK_CLKCTRL			0x664
+
+/* AM33XX  PWMSS Control bitfields */
+#define AM33XX_PWMSS0_TBCLKEN_SHIFT			0
+#define AM33XX_PWMSS1_TBCLKEN_SHIFT			1
+#define AM33XX_PWMSS2_TBCLKEN_SHIFT			2
+
+/* DEV Feature register to identify AM33XX features */
+#define AM33XX_DEV_FEATURE		0x604
+#define AM33XX_SGX_MASK			BIT(29)
+
 /* CONTROL OMAP STATUS register to identify OMAP3 features */
 #define OMAP3_CONTROL_OMAP_STATUS	0x044c
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/devices.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/devices.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/devices.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/devices.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,8 +19,8 @@
 #include <linux/of.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/platform_data/omap4-keypad.h>
-#include <linux/platform_data/omap_ocp2scp.h>
-#include <linux/usb/omap_control_usb.h>
+#include <linux/wl12xx.h>
+#include <linux/platform_data/mailbox-omap.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
@@ -37,7 +37,6 @@
 #include "mux.h"
 #include "control.h"
 #include "devices.h"
-#include "dma.h"
 
 #define L3_MODULES_MAX_LEN 12
 #define L3_MODULES 3
@@ -66,7 +65,7 @@ static int __init omap3_l3_init(void)
 
 	WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
 
-	return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
+	return PTR_RET(pdev);
 }
 omap_postcore_initcall(omap3_l3_init);
 
@@ -100,7 +99,7 @@ static int __init omap4_l3_init(void)
 
 	WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
 
-	return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
+	return PTR_RET(pdev);
 }
 omap_postcore_initcall(omap4_l3_init);
 
@@ -253,49 +252,6 @@ static inline void omap_init_camera(void
 #endif
 }
 
-#if IS_ENABLED(CONFIG_OMAP_CONTROL_USB)
-static struct omap_control_usb_platform_data omap4_control_usb_pdata = {
-	.type = 1,
-};
-
-struct resource omap4_control_usb_res[] = {
-	{
-		.name	= "control_dev_conf",
-		.start	= 0x4a002300,
-		.end	= 0x4a002303,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "otghs_control",
-		.start	= 0x4a00233c,
-		.end	= 0x4a00233f,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device omap4_control_usb = {
-	.name = "omap-control-usb",
-	.id = -1,
-	.dev = {
-		.platform_data = &omap4_control_usb_pdata,
-	},
-	.num_resources = 2,
-	.resource = omap4_control_usb_res,
-};
-
-static inline void __init omap_init_control_usb(void)
-{
-	if (!cpu_is_omap44xx())
-		return;
-
-	if (platform_device_register(&omap4_control_usb))
-		pr_err("Error registering omap_control_usb device\n");
-}
-
-#else
-static inline void omap_init_control_usb(void) { }
-#endif /* CONFIG_OMAP_CONTROL_USB */
-
 int __init omap4_keyboard_init(struct omap4_keypad_platform_data
 			*sdp4430_keypad_data, struct omap_board_data *bdata)
 {
@@ -327,25 +283,31 @@ int __init omap4_keyboard_init(struct om
 	return 0;
 }
 
-#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
+#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE)
 static inline void __init omap_init_mbox(void)
 {
 	struct omap_hwmod *oh;
 	struct platform_device *pdev;
+	struct omap_mbox_pdata *pdata;
 
 	oh = omap_hwmod_lookup("mailbox");
 	if (!oh) {
 		pr_err("%s: unable to find hwmod\n", __func__);
 		return;
 	}
+	if (!oh->dev_attr) {
+		pr_err("%s: hwmod doesn't have valid attrs\n", __func__);
+		return;
+	}
 
-	pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0);
+	pdata = (struct omap_mbox_pdata *)oh->dev_attr;
+	pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata));
 	WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",
 						__func__, PTR_ERR(pdev));
 }
 #else
 static inline void omap_init_mbox(void) { }
-#endif /* CONFIG_OMAP_MBOX_FWK */
+#endif /* CONFIG_OMAP2PLUS_MBOX */
 
 static inline void omap_init_sti(void) {}
 
@@ -374,10 +336,8 @@ static void __init omap_init_mcpdm(void)
 	struct platform_device *pdev;
 
 	oh = omap_hwmod_lookup("mcpdm");
-	if (!oh) {
-		printk(KERN_ERR "Could not look up mcpdm hw_mod\n");
+	if (!oh)
 		return;
-	}
 
 	pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0);
 	WARN(IS_ERR(pdev), "Can't build omap_device for omap-mcpdm.\n");
@@ -395,10 +355,8 @@ static void __init omap_init_dmic(void)
 	struct platform_device *pdev;
 
 	oh = omap_hwmod_lookup("dmic");
-	if (!oh) {
-		pr_err("Could not look up dmic hw_mod\n");
+	if (!oh)
 		return;
-	}
 
 	pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0);
 	WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n");
@@ -421,10 +379,8 @@ static void __init omap_init_hdmi_audio(
 	struct platform_device *pdev;
 
 	oh = omap_hwmod_lookup("dss_hdmi");
-	if (!oh) {
-		printk(KERN_ERR "Could not look up dss_hdmi hw_mod\n");
+	if (!oh)
 		return;
-	}
 
 	pdev = omap_device_build("omap-hdmi-audio-dai", -1, oh, NULL, 0);
 	WARN(IS_ERR(pdev),
@@ -557,80 +513,38 @@ static void omap_init_vout(void)
 static inline void omap_init_vout(void) {}
 #endif
 
-#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE)
-static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev)
-{
-	int cnt	= 0;
-
-	while (ocp2scp_dev->drv_name != NULL) {
-		cnt++;
-		ocp2scp_dev++;
-	}
+#if IS_ENABLED(CONFIG_WL12XX)
 
-	return cnt;
-}
+static struct wl12xx_platform_data wl12xx __initdata;
 
-static void __init omap_init_ocp2scp(void)
+void __init omap_init_wl12xx_of(void)
 {
-	struct omap_hwmod	*oh;
-	struct platform_device	*pdev;
-	int			bus_id = -1, dev_cnt = 0, i;
-	struct omap_ocp2scp_dev	*ocp2scp_dev;
-	const char		*oh_name, *name;
-	struct omap_ocp2scp_platform_data *pdata;
-
-	if (!cpu_is_omap44xx())
-		return;
-
-	oh_name = "ocp2scp_usb_phy";
-	name	= "omap-ocp2scp";
-
-	oh = omap_hwmod_lookup(oh_name);
-	if (!oh) {
-		pr_err("%s: could not find omap_hwmod for %s\n", __func__,
-								oh_name);
-		return;
-	}
-
-	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
-	if (!pdata) {
-		pr_err("%s: No memory for ocp2scp pdata\n", __func__);
-		return;
-	}
-
-	ocp2scp_dev = oh->dev_attr;
-	dev_cnt = count_ocp2scp_devices(ocp2scp_dev);
+	int ret;
 
-	if (!dev_cnt) {
-		pr_err("%s: No devices connected to ocp2scp\n", __func__);
-		kfree(pdata);
+	if (!of_have_populated_dt())
 		return;
-	}
 
-	pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *)
-					* dev_cnt, GFP_KERNEL);
-	if (!pdata->devices) {
-		pr_err("%s: No memory for ocp2scp pdata devices\n", __func__);
-		kfree(pdata);
+	if (of_machine_is_compatible("ti,omap4-sdp")) {
+		wl12xx.board_ref_clock = WL12XX_REFCLOCK_26;
+		wl12xx.board_tcxo_clock = WL12XX_TCXOCLOCK_26;
+		wl12xx.irq = gpio_to_irq(53);
+	} else if (of_machine_is_compatible("ti,omap4-panda")) {
+		wl12xx.board_ref_clock = WL12XX_REFCLOCK_38;
+		wl12xx.irq = gpio_to_irq(53);
+	} else {
 		return;
 	}
 
-	for (i = 0; i < dev_cnt; i++, ocp2scp_dev++)
-		pdata->devices[i] = ocp2scp_dev;
-
-	pdata->dev_cnt	= dev_cnt;
-
-	pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata));
-	if (IS_ERR(pdev)) {
-		pr_err("Could not build omap_device for %s %s\n",
-						name, oh_name);
-		kfree(pdata->devices);
-		kfree(pdata);
+	ret = wl12xx_set_platform_data(&wl12xx);
+	if (ret) {
+		pr_err("error setting wl12xx data: %d\n", ret);
 		return;
 	}
 }
 #else
-static inline void omap_init_ocp2scp(void) { }
+static inline void omap_init_wl12xx_of(void)
+{
+}
 #endif
 
 /*-------------------------------------------------------------------------*/
@@ -651,17 +565,18 @@ static int __init omap2_init_devices(voi
 	omap_init_mbox();
 	/* If dtb is there, the devices will be created dynamically */
 	if (!of_have_populated_dt()) {
-		omap_init_control_usb();
 		omap_init_dmic();
 		omap_init_mcpdm();
 		omap_init_mcspi();
 		omap_init_sham();
 		omap_init_aes();
+	} else {
+		/* These can be removed when bindings are done */
+		omap_init_wl12xx_of();
 	}
 	omap_init_sti();
 	omap_init_rng();
 	omap_init_vout();
-	omap_init_ocp2scp();
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/dma.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/dma.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/dma.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/dma.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,61 +0,0 @@
-/*
- *  OMAP2PLUS DMA channel definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __OMAP2PLUS_DMA_CHANNEL_H
-#define __OMAP2PLUS_DMA_CHANNEL_H
-
-
-/* DMA channels for 24xx */
-#define OMAP24XX_DMA_NO_DEVICE		0
-#define OMAP24XX_DMA_EXT_DMAREQ0	2	/* S_DMA_1 */
-#define OMAP24XX_DMA_EXT_DMAREQ1	3	/* S_DMA_2 */
-#define OMAP24XX_DMA_GPMC		4	/* S_DMA_3 */
-#define OMAP24XX_DMA_AES_TX		9	/* S_DMA_8 */
-#define OMAP24XX_DMA_AES_RX		10	/* S_DMA_9 */
-#define OMAP242X_DMA_EXT_DMAREQ2	14	/* S_DMA_13 */
-#define OMAP242X_DMA_EXT_DMAREQ3	15	/* S_DMA_14 */
-#define OMAP242X_DMA_EXT_DMAREQ4	16	/* S_DMA_15 */
-#define OMAP34XX_DMA_I2C3_TX		25	/* S_DMA_24 */
-#define OMAP34XX_DMA_I2C3_RX		26	/* S_DMA_25 */
-#define OMAP24XX_DMA_I2C1_TX		27	/* S_DMA_26 */
-#define OMAP24XX_DMA_I2C1_RX		28	/* S_DMA_27 */
-#define OMAP24XX_DMA_I2C2_TX		29	/* S_DMA_28 */
-#define OMAP24XX_DMA_I2C2_RX		30	/* S_DMA_29 */
-#define OMAP24XX_DMA_MMC2_TX		47	/* S_DMA_46 */
-#define OMAP24XX_DMA_MMC2_RX		48	/* S_DMA_47 */
-#define OMAP24XX_DMA_UART1_TX		49	/* S_DMA_48 */
-#define OMAP24XX_DMA_UART1_RX		50	/* S_DMA_49 */
-#define OMAP24XX_DMA_UART2_TX		51	/* S_DMA_50 */
-#define OMAP24XX_DMA_UART2_RX		52	/* S_DMA_51 */
-#define OMAP24XX_DMA_UART3_TX		53	/* S_DMA_52 */
-#define OMAP24XX_DMA_UART3_RX		54	/* S_DMA_53 */
-#define OMAP24XX_DMA_MMC1_TX		61	/* S_DMA_60 */
-#define OMAP24XX_DMA_MMC1_RX		62	/* S_DMA_61 */
-#define OMAP242X_DMA_EXT_DMAREQ5	64	/* S_DMA_63 */
-#define OMAP34XX_DMA_AES2_TX		65	/* S_DMA_64 */
-#define OMAP34XX_DMA_AES2_RX		66	/* S_DMA_65 */
-#define OMAP34XX_DMA_SHA1MD5_RX		69	/* S_DMA_68 */
-
-#define OMAP36XX_DMA_UART4_TX		81	/* S_DMA_80 */
-#define OMAP36XX_DMA_UART4_RX		82	/* S_DMA_81 */
-
-/* Only for AM35xx */
-#define AM35XX_DMA_UART4_TX		54
-#define AM35XX_DMA_UART4_RX		55
-
-#endif /* __OMAP2PLUS_DMA_CHANNEL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/dss-common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/dss-common.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/dss-common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/dss-common.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,7 +42,7 @@
 
 /* Using generic display panel */
 static struct tfp410_platform_data omap4_dvi_panel = {
-	.i2c_bus_num		= 3,
+	.i2c_bus_num		= 2,
 	.power_down_gpio	= PANDA_DVI_TFP410_POWER_DOWN_GPIO,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/fb.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/fb.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/fb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/fb.c	2013-08-25 20:43:22.000000000 -0400
@@ -83,10 +83,7 @@ static int __init omap_init_vrfb(void)
 	pdev = platform_device_register_resndata(NULL, "omapvrfb", -1,
 			res, num_res, NULL, 0);
 
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-	else
-		return 0;
+	return PTR_RET(pdev);
 }
 
 omap_arch_initcall(omap_init_vrfb);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/gpmc.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/gpmc.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/gpmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/gpmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/of_mtd.h>
 #include <linux/of_device.h>
 #include <linux/mtd/nand.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
 
@@ -155,6 +156,7 @@ static struct resource	gpmc_cs_mem[GPMC_
 static DEFINE_SPINLOCK(gpmc_mem_lock);
 /* Define chip-selects as reserved by default until probe completes */
 static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
+static unsigned int gpmc_cs_num = GPMC_CS_NUM;
 static unsigned int gpmc_nr_waitpins;
 static struct device *gpmc_dev;
 static int gpmc_irq;
@@ -521,8 +523,10 @@ static int gpmc_cs_remap(int cs, u32 bas
 	int ret;
 	u32 old_base, size;
 
-	if (cs > GPMC_CS_NUM)
+	if (cs > gpmc_cs_num) {
+		pr_err("%s: requested chip-select is disabled\n", __func__);
 		return -ENODEV;
+	}
 	gpmc_cs_get_memconf(cs, &old_base, &size);
 	if (base == old_base)
 		return 0;
@@ -545,9 +549,10 @@ int gpmc_cs_request(int cs, unsigned lon
 	struct resource *res = &gpmc_cs_mem[cs];
 	int r = -1;
 
-	if (cs > GPMC_CS_NUM)
+	if (cs > gpmc_cs_num) {
+		pr_err("%s: requested chip-select is disabled\n", __func__);
 		return -ENODEV;
-
+	}
 	size = gpmc_mem_align(size);
 	if (size > (1 << GPMC_SECTION_SHIFT))
 		return -ENOMEM;
@@ -582,7 +587,7 @@ EXPORT_SYMBOL(gpmc_cs_request);
 void gpmc_cs_free(int cs)
 {
 	spin_lock(&gpmc_mem_lock);
-	if (cs >= GPMC_CS_NUM || cs < 0 || !gpmc_cs_reserved(cs)) {
+	if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
 		printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
 		BUG();
 		spin_unlock(&gpmc_mem_lock);
@@ -777,7 +782,7 @@ static void gpmc_mem_exit(void)
 {
 	int cs;
 
-	for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+	for (cs = 0; cs < gpmc_cs_num; cs++) {
 		if (!gpmc_cs_mem_enabled(cs))
 			continue;
 		gpmc_cs_delete_mem(cs);
@@ -798,7 +803,7 @@ static void gpmc_mem_init(void)
 	gpmc_mem_root.end = GPMC_MEM_END;
 
 	/* Reserve all regions that has been set up by bootloader */
-	for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+	for (cs = 0; cs < gpmc_cs_num; cs++) {
 		u32 base, size;
 
 		if (!gpmc_cs_mem_enabled(cs))
@@ -1245,7 +1250,6 @@ void gpmc_read_settings_dt(struct device
 
 	p->sync_read = of_property_read_bool(np, "gpmc,sync-read");
 	p->sync_write = of_property_read_bool(np, "gpmc,sync-write");
-	p->device_nand = of_property_read_bool(np, "gpmc,device-nand");
 	of_property_read_u32(np, "gpmc,device-width", &p->device_width);
 	of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data);
 
@@ -1345,6 +1349,13 @@ static const char * const nand_ecc_opts[
 	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
 };
 
+static const char * const nand_xfer_types[] = {
+	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
+	[NAND_OMAP_POLLED]			= "polled",
+	[NAND_OMAP_PREFETCH_DMA]		= "prefetch-dma",
+	[NAND_OMAP_PREFETCH_IRQ]		= "prefetch-irq",
+};
+
 static int gpmc_probe_nand_child(struct platform_device *pdev,
 				 struct device_node *child)
 {
@@ -1374,6 +1385,13 @@ static int gpmc_probe_nand_child(struct
 				break;
 			}
 
+	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
+		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
+			if (!strcasecmp(s, nand_xfer_types[val])) {
+				gpmc_nand_data->xfer_type = val;
+				break;
+			}
+
 	val = of_get_nand_bus_width(child);
 	if (val == 16)
 		gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
@@ -1513,6 +1531,20 @@ static int gpmc_probe_dt(struct platform
 	if (!of_id)
 		return 0;
 
+	ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-cs",
+				   &gpmc_cs_num);
+	if (ret < 0) {
+		pr_err("%s: number of chip-selects not defined\n", __func__);
+		return ret;
+	} else if (gpmc_cs_num < 1) {
+		pr_err("%s: all chip-selects are disabled\n", __func__);
+		return -EINVAL;
+	} else if (gpmc_cs_num > GPMC_CS_NUM) {
+		pr_err("%s: number of supported chip-selects cannot be > %d\n",
+					 __func__, GPMC_CS_NUM);
+		return -EINVAL;
+	}
+
 	ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
 				   &gpmc_nr_waitpins);
 	if (ret < 0) {
@@ -1577,7 +1609,8 @@ static int gpmc_probe(struct platform_de
 		return PTR_ERR(gpmc_l3_clk);
 	}
 
-	clk_prepare_enable(gpmc_l3_clk);
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
 
 	gpmc_dev = &pdev->dev;
 
@@ -1610,12 +1643,14 @@ static int gpmc_probe(struct platform_de
 	/* Now the GPMC is initialised, unreserve the chip-selects */
 	gpmc_cs_map = 0;
 
-	if (!pdev->dev.of_node)
+	if (!pdev->dev.of_node) {
+		gpmc_cs_num	 = GPMC_CS_NUM;
 		gpmc_nr_waitpins = GPMC_NR_WAITPINS;
+	}
 
 	rc = gpmc_probe_dt(pdev);
 	if (rc < 0) {
-		clk_disable_unprepare(gpmc_l3_clk);
+		pm_runtime_put_sync(&pdev->dev);
 		clk_put(gpmc_l3_clk);
 		dev_err(gpmc_dev, "failed to probe DT parameters\n");
 		return rc;
@@ -1628,10 +1663,30 @@ static int gpmc_remove(struct platform_d
 {
 	gpmc_free_irq();
 	gpmc_mem_exit();
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	gpmc_dev = NULL;
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int gpmc_suspend(struct device *dev)
+{
+	omap3_gpmc_save_context();
+	pm_runtime_put_sync(dev);
+	return 0;
+}
+
+static int gpmc_resume(struct device *dev)
+{
+	pm_runtime_get_sync(dev);
+	omap3_gpmc_restore_context();
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(gpmc_pm_ops, gpmc_suspend, gpmc_resume);
+
 static struct platform_driver gpmc_driver = {
 	.probe		= gpmc_probe,
 	.remove		= gpmc_remove,
@@ -1639,6 +1694,7 @@ static struct platform_driver gpmc_drive
 		.name	= DEVICE_NAME,
 		.owner	= THIS_MODULE,
 		.of_match_table = of_match_ptr(gpmc_dt_ids),
+		.pm	= &gpmc_pm_ops,
 	},
 };
 
@@ -1678,7 +1734,7 @@ static int __init omap_gpmc_init(void)
 	pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0);
 	WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
 
-	return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
+	return PTR_RET(pdev);
 }
 omap_postcore_initcall(omap_gpmc_init);
 
@@ -1701,7 +1757,6 @@ static irqreturn_t gpmc_handle_irq(int i
 	return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_ARCH_OMAP3
 static struct omap3_gpmc_regs gpmc_context;
 
 void omap3_gpmc_save_context(void)
@@ -1715,7 +1770,7 @@ void omap3_gpmc_save_context(void)
 	gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
 	gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2);
 	gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL);
-	for (i = 0; i < GPMC_CS_NUM; i++) {
+	for (i = 0; i < gpmc_cs_num; i++) {
 		gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i);
 		if (gpmc_context.cs_context[i].is_valid) {
 			gpmc_context.cs_context[i].config1 =
@@ -1747,7 +1802,7 @@ void omap3_gpmc_restore_context(void)
 	gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1);
 	gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2);
 	gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control);
-	for (i = 0; i < GPMC_CS_NUM; i++) {
+	for (i = 0; i < gpmc_cs_num; i++) {
 		if (gpmc_context.cs_context[i].is_valid) {
 			gpmc_cs_write_reg(i, GPMC_CS_CONFIG1,
 				gpmc_context.cs_context[i].config1);
@@ -1766,4 +1821,3 @@ void omap3_gpmc_restore_context(void)
 		}
 	}
 }
-#endif /* CONFIG_ARCH_OMAP3 */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/gpmc-nand.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/gpmc-nand.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/gpmc-nand.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/gpmc-nand.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,44 +43,6 @@ static struct platform_device gpmc_nand_
 	.resource	= gpmc_nand_resource,
 };
 
-static int omap2_nand_gpmc_retime(
-				struct omap_nand_platform_data *gpmc_nand_data,
-				struct gpmc_timings *gpmc_t)
-{
-	struct gpmc_timings t;
-	int err;
-
-	memset(&t, 0, sizeof(t));
-	t.sync_clk = gpmc_t->sync_clk;
-	t.cs_on = gpmc_t->cs_on;
-	t.adv_on = gpmc_t->adv_on;
-
-	/* Read */
-	t.adv_rd_off = gpmc_t->adv_rd_off;
-	t.oe_on  = t.adv_on;
-	t.access = gpmc_t->access;
-	t.oe_off = gpmc_t->oe_off;
-	t.cs_rd_off = gpmc_t->cs_rd_off;
-	t.rd_cycle = gpmc_t->rd_cycle;
-
-	/* Write */
-	t.adv_wr_off = gpmc_t->adv_wr_off;
-	t.we_on  = t.oe_on;
-	if (cpu_is_omap34xx()) {
-		t.wr_data_mux_bus = gpmc_t->wr_data_mux_bus;
-		t.wr_access = gpmc_t->wr_access;
-	}
-	t.we_off = gpmc_t->we_off;
-	t.cs_wr_off = gpmc_t->cs_wr_off;
-	t.wr_cycle = gpmc_t->wr_cycle;
-
-	err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t);
-	if (err)
-		return err;
-
-	return 0;
-}
-
 static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
 {
 	/* support only OMAP3 class */
@@ -131,7 +93,7 @@ int gpmc_nand_init(struct omap_nand_plat
 				gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
 
 	if (gpmc_t) {
-		err = omap2_nand_gpmc_retime(gpmc_nand_data, gpmc_t);
+		err = gpmc_cs_set_timings(gpmc_nand_data->cs, gpmc_t);
 		if (err < 0) {
 			dev_err(dev, "Unable to set gpmc timings: %d\n", err);
 			return err;
@@ -140,8 +102,6 @@ int gpmc_nand_init(struct omap_nand_plat
 		if (gpmc_nand_data->of_node) {
 			gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
 		} else {
-			s.device_nand = true;
-
 			/* Enable RD PIN Monitoring Reg */
 			if (gpmc_nand_data->dev_ready) {
 				s.wait_on_read = true;
@@ -149,6 +109,8 @@ int gpmc_nand_init(struct omap_nand_plat
 			}
 		}
 
+		s.device_nand = true;
+
 		if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
 			s.device_width = GPMC_DEVWIDTH_16BIT;
 		else
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/hsmmc.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/hsmmc.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/hsmmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/hsmmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
 
 static u16 control_pbias_offset;
 static u16 control_devconf1_offset;
-static u16 control_mmc1;
 
 #define HSMMC_NAME_LEN	9
 
@@ -121,57 +120,6 @@ static void omap_hsmmc1_after_set_reg(st
 	}
 }
 
-static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot,
-				  int power_on, int vdd)
-{
-	u32 reg;
-
-	/*
-	 * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
-	 * card with Vcc regulator (from twl4030 or whatever).  OMAP has both
-	 * 1.8V and 3.0V modes, controlled by the PBIAS register.
-	 */
-	reg = omap4_ctrl_pad_readl(control_pbias_offset);
-	reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
-		OMAP4_MMC1_PWRDNZ_MASK |
-		OMAP4_MMC1_PBIASLITE_VMODE_MASK);
-	omap4_ctrl_pad_writel(reg, control_pbias_offset);
-}
-
-static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
-				 int power_on, int vdd)
-{
-	u32 reg;
-	unsigned long timeout;
-
-	if (power_on) {
-		reg = omap4_ctrl_pad_readl(control_pbias_offset);
-		reg |= OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK;
-		if ((1 << vdd) <= MMC_VDD_165_195)
-			reg &= ~OMAP4_MMC1_PBIASLITE_VMODE_MASK;
-		else
-			reg |= OMAP4_MMC1_PBIASLITE_VMODE_MASK;
-		reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
-			OMAP4_MMC1_PWRDNZ_MASK);
-		omap4_ctrl_pad_writel(reg, control_pbias_offset);
-
-		timeout = jiffies + msecs_to_jiffies(5);
-		do {
-			reg = omap4_ctrl_pad_readl(control_pbias_offset);
-			if (!(reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK))
-				break;
-			usleep_range(100, 200);
-		} while (!time_after(jiffies, timeout));
-
-		if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK) {
-			pr_err("Pbias Voltage is not same as LDO\n");
-			/* Caution : On VMODE_ERROR Power Down MMC IO */
-			reg &= ~(OMAP4_MMC1_PWRDNZ_MASK);
-			omap4_ctrl_pad_writel(reg, control_pbias_offset);
-		}
-	}
-}
-
 static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
 {
 	u32 reg;
@@ -317,11 +265,7 @@ static int __init omap_hsmmc_pdata_init(
 	mmc->slots[0].pm_caps = c->pm_caps;
 	mmc->slots[0].internal_clock = !c->ext_clock;
 	mmc->max_freq = c->max_freq;
-	if (cpu_is_omap44xx())
-		mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
-	else
-		mmc->reg_offset = 0;
-
+	mmc->reg_offset = 0;
 	mmc->get_context_loss_count = hsmmc_get_context_loss;
 
 	mmc->slots[0].switch_pin = c->gpio_cd;
@@ -368,24 +312,14 @@ static int __init omap_hsmmc_pdata_init(
 	if (!soc_is_am35xx())
 		mmc->slots[0].features |= HSMMC_HAS_PBIAS;
 
-	if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
-		mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
-
 	switch (c->mmc) {
 	case 1:
 		if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
 			/* on-chip level shifting via PBIAS0/PBIAS1 */
-			if (cpu_is_omap44xx()) {
-				mmc->slots[0].before_set_reg =
-						omap4_hsmmc1_before_set_reg;
-				mmc->slots[0].after_set_reg =
-						omap4_hsmmc1_after_set_reg;
-			} else {
-				mmc->slots[0].before_set_reg =
-						omap_hsmmc1_before_set_reg;
-				mmc->slots[0].after_set_reg =
-						omap_hsmmc1_after_set_reg;
-			}
+			mmc->slots[0].before_set_reg =
+					omap_hsmmc1_before_set_reg;
+			mmc->slots[0].after_set_reg =
+					omap_hsmmc1_after_set_reg;
 		}
 
 		if (soc_is_am35xx())
@@ -563,34 +497,17 @@ free_mmc:
 
 void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
 {
-	u32 reg;
-
 	if (omap_hsmmc_done)
 		return;
 
 	omap_hsmmc_done = 1;
 
-	if (!cpu_is_omap44xx()) {
-		if (cpu_is_omap2430()) {
-			control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
-			control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
-		} else {
-			control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
-			control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
-		}
+	if (cpu_is_omap2430()) {
+		control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
+		control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
 	} else {
-		control_pbias_offset =
-			OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE;
-		control_mmc1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1;
-		reg = omap4_ctrl_pad_readl(control_mmc1);
-		reg |= (OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK |
-			OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK);
-		reg &= ~(OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK |
-			OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK);
-		reg |= (OMAP4_SDMMC1_DR0_SPEEDCTRL_MASK |
-			OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK |
-			OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK);
-		omap4_ctrl_pad_writel(reg, control_mmc1);
+		control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
+		control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
 	}
 
 	for (; controllers->mmc; controllers++)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/id.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/id.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/id.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/id.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,7 +55,7 @@ int omap_type(void)
 
 	if (cpu_is_omap24xx()) {
 		val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
-	} else if (soc_is_am33xx()) {
+	} else if (soc_is_am33xx() || soc_is_am43xx()) {
 		val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
 	} else if (cpu_is_omap34xx()) {
 		val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
@@ -209,6 +209,8 @@ static void __init omap3_cpuinfo(void)
 		cpu_name = "TI816X";
 	} else if (soc_is_am335x()) {
 		cpu_name =  "AM335X";
+	} else if (soc_is_am437x()) {
+		cpu_name =  "AM437x";
 	} else if (cpu_is_ti814x()) {
 		cpu_name = "TI814X";
 	} else if (omap3_has_iva() && omap3_has_sgx()) {
@@ -302,6 +304,19 @@ void __init ti81xx_check_features(void)
 	omap3_cpuinfo();
 }
 
+void __init am33xx_check_features(void)
+{
+	u32 status;
+
+	omap_features = OMAP3_HAS_NEON;
+
+	status = omap_ctrl_readl(AM33XX_DEV_FEATURE);
+	if (status & AM33XX_SGX_MASK)
+		omap_features |= OMAP3_HAS_SGX;
+
+	omap3_cpuinfo();
+}
+
 void __init omap3xxx_check_revision(void)
 {
 	const char *cpu_rev;
@@ -405,11 +420,18 @@ void __init omap3xxx_check_revision(void
 			cpu_rev = "1.0";
 			break;
 		case 1:
-		/* FALLTHROUGH */
-		default:
 			omap_revision = TI8168_REV_ES1_1;
 			cpu_rev = "1.1";
 			break;
+		case 2:
+			omap_revision = TI8168_REV_ES2_0;
+			cpu_rev = "2.0";
+			break;
+		case 3:
+			/* FALLTHROUGH */
+		default:
+			omap_revision = TI8168_REV_ES2_1;
+			cpu_rev = "2.1";
 		}
 		break;
 	case 0xb944:
@@ -430,6 +452,10 @@ void __init omap3xxx_check_revision(void
 			break;
 		}
 		break;
+	case 0xb98c:
+		omap_revision = AM437X_REV_ES1_0;
+		cpu_rev = "1.0";
+		break;
 	case 0xb8f2:
 		switch (rev) {
 		case 0:
@@ -601,7 +627,7 @@ void __init omap2_set_globals_tap(u32 cl
 
 #ifdef CONFIG_SOC_BUS
 
-static const char const *omap_types[] = {
+static const char * const omap_types[] = {
 	[OMAP2_DEVICE_TYPE_TEST]	= "TST",
 	[OMAP2_DEVICE_TYPE_EMU]		= "EMU",
 	[OMAP2_DEVICE_TYPE_SEC]		= "HS",
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/io.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/io.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/io.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/io.c	2013-08-25 20:43:22.000000000 -0400
@@ -202,7 +202,7 @@ static struct map_desc omapti81xx_io_des
 };
 #endif
 
-#ifdef CONFIG_SOC_AM33XX
+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
 static struct map_desc omapam33xx_io_desc[] __initdata = {
 	{
 		.virtual	= L4_34XX_VIRT,
@@ -318,7 +318,7 @@ void __init ti81xx_map_io(void)
 }
 #endif
 
-#ifdef CONFIG_SOC_AM33XX
+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
 void __init am33xx_map_io(void)
 {
 	iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
@@ -394,7 +394,7 @@ static void __init omap_hwmod_init_posts
 	omap_pm_if_early_init();
 }
 
-static void __init omap_common_late_init(void)
+static void __init __maybe_unused omap_common_late_init(void)
 {
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
@@ -576,8 +576,7 @@ void __init am33xx_init_early(void)
 	omap2_set_globals_prm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE));
 	omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), NULL);
 	omap3xxx_check_revision();
-	ti81xx_check_features();
-	am33xx_voltagedomains_init();
+	am33xx_check_features();
 	am33xx_powerdomains_init();
 	am33xx_clockdomains_init();
 	am33xx_hwmod_init();
@@ -586,6 +585,19 @@ void __init am33xx_init_early(void)
 }
 #endif
 
+#ifdef CONFIG_SOC_AM43XX
+void __init am43xx_init_early(void)
+{
+	omap2_set_globals_tap(AM335X_CLASS,
+			      AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE));
+	omap2_set_globals_control(AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE),
+				  NULL);
+	omap2_set_globals_prm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE));
+	omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM43XX_PRCM_BASE), NULL);
+	omap3xxx_check_revision();
+}
+#endif
+
 #ifdef CONFIG_ARCH_OMAP4
 void __init omap4430_init_early(void)
 {
@@ -631,7 +643,13 @@ void __init omap5_init_early(void)
 	omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
 	omap_prm_base_init();
 	omap_cm_base_init();
+	omap44xx_prm_init();
 	omap5xxx_check_revision();
+	omap54xx_voltagedomains_init();
+	omap54xx_powerdomains_init();
+	omap54xx_clockdomains_init();
+	omap54xx_hwmod_init();
+	omap_hwmod_init_postsetup();
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,61 +1,10 @@
 config ARCH_OMAP
 	bool
 
-config ARCH_OMAP2PLUS
-	bool "TI OMAP2/3/4/5 SoCs with device tree support" if (ARCH_MULTI_V6 || ARCH_MULTI_V7)
-	select ARCH_HAS_CPUFREQ
-	select ARCH_HAS_HOLES_MEMORYMODEL
-	select ARCH_OMAP
-	select ARCH_REQUIRE_GPIOLIB
-	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
-	select GENERIC_CLOCKEVENTS
-	select GENERIC_IRQ_CHIP
-	select HAVE_CLK
-	select OMAP_DM_TIMER
-	select PINCTRL
-	select PROC_DEVICETREE if PROC_FS
-	select SOC_BUS
-	select SPARSE_IRQ
-	select USE_OF
-	help
-	  Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
-
-
-if ARCH_OMAP2PLUS
-
-menu "TI OMAP2/3/4 Specific Features"
-
-config ARCH_OMAP2PLUS_TYPICAL
-	bool "Typical OMAP configuration"
-	default y
-	select AEABI
-	select HIGHMEM
-	select I2C
-	select I2C_OMAP
-	select MENELAUS if ARCH_OMAP2
-	select NEON if ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5
-	select PM_RUNTIME
-	select REGULATOR
-	select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
-	select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
-	select VFP
-	help
-	  Compile a kernel suitable for booting most boards
-
-config SOC_HAS_OMAP2_SDRC
-	bool "OMAP2 SDRAM Controller support"
-
-config SOC_HAS_REALTIME_COUNTER
-	bool "Real time free running counter"
-	depends on SOC_OMAP5
-	default y
-
 config ARCH_OMAP2
 	bool "TI OMAP2"
-	depends on ARCH_OMAP2PLUS
 	depends on ARCH_MULTI_V6
-	default y
+	select ARCH_OMAP2PLUS
 	select CPU_V6
 	select MULTI_IRQ_HANDLER
 	select SOC_HAS_OMAP2_SDRC
@@ -63,9 +12,8 @@ config ARCH_OMAP2
 
 config ARCH_OMAP3
 	bool "TI OMAP3"
-	depends on ARCH_OMAP2PLUS
 	depends on ARCH_MULTI_V7
-	default y
+	select ARCH_OMAP2PLUS
 	select ARCH_HAS_OPP
 	select ARM_CPU_SUSPEND if PM
 	select CPU_V7
@@ -79,9 +27,8 @@ config ARCH_OMAP3
 
 config ARCH_OMAP4
 	bool "TI OMAP4"
-	default y
-	depends on ARCH_OMAP2PLUS
 	depends on ARCH_MULTI_V7
+	select ARCH_OMAP2PLUS
 	select ARCH_HAS_OPP
 	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
 	select ARM_CPU_SUSPEND if PM
@@ -106,12 +53,87 @@ config ARCH_OMAP4
 config SOC_OMAP5
 	bool "TI OMAP5"
 	depends on ARCH_MULTI_V7
+	select ARCH_OMAP2PLUS
 	select ARM_CPU_SUSPEND if PM
 	select ARM_GIC
 	select CPU_V7
+	select HAVE_ARM_SCU if SMP
+	select HAVE_ARM_TWD if LOCAL_TIMERS
 	select HAVE_SMP
 	select COMMON_CLK
 	select HAVE_ARM_ARCH_TIMER
+	select ARM_ERRATA_798181 if SMP
+
+config SOC_AM33XX
+	bool "AM33XX support"
+	depends on ARCH_MULTI_V7
+	select ARCH_OMAP2PLUS
+	select ARM_CPU_SUSPEND if PM
+	select CPU_V7
+	select MULTI_IRQ_HANDLER
+	select COMMON_CLK
+
+config SOC_AM43XX
+	bool "TI AM43x"
+	depends on ARCH_MULTI_V7
+	select CPU_V7
+	select ARCH_OMAP2PLUS
+	select MULTI_IRQ_HANDLER
+	select ARM_GIC
+	select COMMON_CLK
+	select MACH_OMAP_GENERIC
+
+config ARCH_OMAP2PLUS
+	bool
+	select ARCH_HAS_BANDGAP
+	select ARCH_HAS_CPUFREQ
+	select ARCH_HAS_HOLES_MEMORYMODEL
+	select ARCH_OMAP
+	select ARCH_REQUIRE_GPIOLIB
+	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_IRQ_CHIP
+	select HAVE_CLK
+	select OMAP_DM_TIMER
+	select PINCTRL
+	select PROC_DEVICETREE if PROC_FS
+	select SOC_BUS
+	select SPARSE_IRQ
+	select TI_PRIV_EDMA
+	select USE_OF
+	help
+	  Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
+
+
+if ARCH_OMAP2PLUS
+
+menu "TI OMAP2/3/4 Specific Features"
+
+config ARCH_OMAP2PLUS_TYPICAL
+	bool "Typical OMAP configuration"
+	default y
+	select AEABI
+	select HIGHMEM
+	select I2C
+	select I2C_OMAP
+	select MENELAUS if ARCH_OMAP2
+	select NEON if ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5
+	select PM_RUNTIME
+	select REGULATOR
+	select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
+	select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
+	select VFP
+	help
+	  Compile a kernel suitable for booting most boards
+
+config SOC_HAS_OMAP2_SDRC
+	bool "OMAP2 SDRAM Controller support"
+
+config SOC_HAS_REALTIME_COUNTER
+	bool "Real time free running counter"
+	depends on SOC_OMAP5
+	default y
 
 comment "OMAP Core Type"
 	depends on ARCH_OMAP2
@@ -140,15 +162,6 @@ config SOC_TI81XX
 	depends on ARCH_OMAP3
 	default y
 
-config SOC_AM33XX
-	bool "AM33XX support"
-	depends on ARCH_MULTI_V7
-	default y
-	select ARM_CPU_SUSPEND if PM
-	select CPU_V7
-	select MULTI_IRQ_HANDLER
-	select COMMON_CLK
-
 config OMAP_PACKAGE_ZAF
        bool
 
@@ -167,12 +180,6 @@ config OMAP_PACKAGE_CUS
 config OMAP_PACKAGE_CBP
        bool
 
-config OMAP_PACKAGE_CBL
-       bool
-
-config OMAP_PACKAGE_CBS
-       bool
-
 comment "OMAP Board Type"
 	depends on ARCH_OMAP2PLUS
 
@@ -378,22 +385,6 @@ config MACH_TI8148EVM
 	depends on SOC_TI81XX
 	default y
 
-config MACH_OMAP_4430SDP
-	bool "OMAP 4430 SDP board"
-	default y
-	depends on ARCH_OMAP4
-	select OMAP_PACKAGE_CBL
-	select OMAP_PACKAGE_CBS
-	select REGULATOR_FIXED_VOLTAGE if REGULATOR
-
-config MACH_OMAP4_PANDA
-	bool "OMAP4 Panda Board"
-	default y
-	depends on ARCH_OMAP4
-	select OMAP_PACKAGE_CBL
-	select OMAP_PACKAGE_CBS
-	select REGULATOR_FIXED_VOLTAGE if REGULATOR
-
 config OMAP3_EMU
 	bool "OMAP3 debugging peripherals"
 	depends on ARCH_OMAP3
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/mailbox.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/mailbox.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/mailbox.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/mailbox.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,430 +0,0 @@
-/*
- * Mailbox reservation modules for OMAP2/3
- *
- * Copyright (C) 2006-2009 Nokia Corporation
- * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
- *        and  Paul Mundt
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/pm_runtime.h>
-
-#include <plat/mailbox.h>
-
-#include "soc.h"
-
-#define MAILBOX_REVISION		0x000
-#define MAILBOX_MESSAGE(m)		(0x040 + 4 * (m))
-#define MAILBOX_FIFOSTATUS(m)		(0x080 + 4 * (m))
-#define MAILBOX_MSGSTATUS(m)		(0x0c0 + 4 * (m))
-#define MAILBOX_IRQSTATUS(u)		(0x100 + 8 * (u))
-#define MAILBOX_IRQENABLE(u)		(0x104 + 8 * (u))
-
-#define OMAP4_MAILBOX_IRQSTATUS(u)	(0x104 + 0x10 * (u))
-#define OMAP4_MAILBOX_IRQENABLE(u)	(0x108 + 0x10 * (u))
-#define OMAP4_MAILBOX_IRQENABLE_CLR(u)	(0x10c + 0x10 * (u))
-
-#define MAILBOX_IRQ_NEWMSG(m)		(1 << (2 * (m)))
-#define MAILBOX_IRQ_NOTFULL(m)		(1 << (2 * (m) + 1))
-
-#define MBOX_REG_SIZE			0x120
-
-#define OMAP4_MBOX_REG_SIZE		0x130
-
-#define MBOX_NR_REGS			(MBOX_REG_SIZE / sizeof(u32))
-#define OMAP4_MBOX_NR_REGS		(OMAP4_MBOX_REG_SIZE / sizeof(u32))
-
-static void __iomem *mbox_base;
-
-struct omap_mbox2_fifo {
-	unsigned long msg;
-	unsigned long fifo_stat;
-	unsigned long msg_stat;
-};
-
-struct omap_mbox2_priv {
-	struct omap_mbox2_fifo tx_fifo;
-	struct omap_mbox2_fifo rx_fifo;
-	unsigned long irqenable;
-	unsigned long irqstatus;
-	u32 newmsg_bit;
-	u32 notfull_bit;
-	u32 ctx[OMAP4_MBOX_NR_REGS];
-	unsigned long irqdisable;
-};
-
-static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
-				  omap_mbox_type_t irq);
-
-static inline unsigned int mbox_read_reg(size_t ofs)
-{
-	return __raw_readl(mbox_base + ofs);
-}
-
-static inline void mbox_write_reg(u32 val, size_t ofs)
-{
-	__raw_writel(val, mbox_base + ofs);
-}
-
-/* Mailbox H/W preparations */
-static int omap2_mbox_startup(struct omap_mbox *mbox)
-{
-	u32 l;
-
-	pm_runtime_enable(mbox->dev->parent);
-	pm_runtime_get_sync(mbox->dev->parent);
-
-	l = mbox_read_reg(MAILBOX_REVISION);
-	pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
-
-	return 0;
-}
-
-static void omap2_mbox_shutdown(struct omap_mbox *mbox)
-{
-	pm_runtime_put_sync(mbox->dev->parent);
-	pm_runtime_disable(mbox->dev->parent);
-}
-
-/* Mailbox FIFO handle functions */
-static mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox)
-{
-	struct omap_mbox2_fifo *fifo =
-		&((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
-	return (mbox_msg_t) mbox_read_reg(fifo->msg);
-}
-
-static void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
-{
-	struct omap_mbox2_fifo *fifo =
-		&((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
-	mbox_write_reg(msg, fifo->msg);
-}
-
-static int omap2_mbox_fifo_empty(struct omap_mbox *mbox)
-{
-	struct omap_mbox2_fifo *fifo =
-		&((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
-	return (mbox_read_reg(fifo->msg_stat) == 0);
-}
-
-static int omap2_mbox_fifo_full(struct omap_mbox *mbox)
-{
-	struct omap_mbox2_fifo *fifo =
-		&((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
-	return mbox_read_reg(fifo->fifo_stat);
-}
-
-/* Mailbox IRQ handle functions */
-static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
-		omap_mbox_type_t irq)
-{
-	struct omap_mbox2_priv *p = mbox->priv;
-	u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
-
-	l = mbox_read_reg(p->irqenable);
-	l |= bit;
-	mbox_write_reg(l, p->irqenable);
-}
-
-static void omap2_mbox_disable_irq(struct omap_mbox *mbox,
-		omap_mbox_type_t irq)
-{
-	struct omap_mbox2_priv *p = mbox->priv;
-	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
-
-	if (!cpu_is_omap44xx())
-		bit = mbox_read_reg(p->irqdisable) & ~bit;
-
-	mbox_write_reg(bit, p->irqdisable);
-}
-
-static void omap2_mbox_ack_irq(struct omap_mbox *mbox,
-		omap_mbox_type_t irq)
-{
-	struct omap_mbox2_priv *p = mbox->priv;
-	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
-
-	mbox_write_reg(bit, p->irqstatus);
-
-	/* Flush posted write for irq status to avoid spurious interrupts */
-	mbox_read_reg(p->irqstatus);
-}
-
-static int omap2_mbox_is_irq(struct omap_mbox *mbox,
-		omap_mbox_type_t irq)
-{
-	struct omap_mbox2_priv *p = mbox->priv;
-	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
-	u32 enable = mbox_read_reg(p->irqenable);
-	u32 status = mbox_read_reg(p->irqstatus);
-
-	return (int)(enable & status & bit);
-}
-
-static void omap2_mbox_save_ctx(struct omap_mbox *mbox)
-{
-	int i;
-	struct omap_mbox2_priv *p = mbox->priv;
-	int nr_regs;
-	if (cpu_is_omap44xx())
-		nr_regs = OMAP4_MBOX_NR_REGS;
-	else
-		nr_regs = MBOX_NR_REGS;
-	for (i = 0; i < nr_regs; i++) {
-		p->ctx[i] = mbox_read_reg(i * sizeof(u32));
-
-		dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
-			i, p->ctx[i]);
-	}
-}
-
-static void omap2_mbox_restore_ctx(struct omap_mbox *mbox)
-{
-	int i;
-	struct omap_mbox2_priv *p = mbox->priv;
-	int nr_regs;
-	if (cpu_is_omap44xx())
-		nr_regs = OMAP4_MBOX_NR_REGS;
-	else
-		nr_regs = MBOX_NR_REGS;
-	for (i = 0; i < nr_regs; i++) {
-		mbox_write_reg(p->ctx[i], i * sizeof(u32));
-
-		dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
-			i, p->ctx[i]);
-	}
-}
-
-static struct omap_mbox_ops omap2_mbox_ops = {
-	.type		= OMAP_MBOX_TYPE2,
-	.startup	= omap2_mbox_startup,
-	.shutdown	= omap2_mbox_shutdown,
-	.fifo_read	= omap2_mbox_fifo_read,
-	.fifo_write	= omap2_mbox_fifo_write,
-	.fifo_empty	= omap2_mbox_fifo_empty,
-	.fifo_full	= omap2_mbox_fifo_full,
-	.enable_irq	= omap2_mbox_enable_irq,
-	.disable_irq	= omap2_mbox_disable_irq,
-	.ack_irq	= omap2_mbox_ack_irq,
-	.is_irq		= omap2_mbox_is_irq,
-	.save_ctx	= omap2_mbox_save_ctx,
-	.restore_ctx	= omap2_mbox_restore_ctx,
-};
-
-/*
- * MAILBOX 0: ARM -> DSP,
- * MAILBOX 1: ARM <- DSP.
- * MAILBOX 2: ARM -> IVA,
- * MAILBOX 3: ARM <- IVA.
- */
-
-/* FIXME: the following structs should be filled automatically by the user id */
-
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP2)
-/* DSP */
-static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
-	.tx_fifo = {
-		.msg		= MAILBOX_MESSAGE(0),
-		.fifo_stat	= MAILBOX_FIFOSTATUS(0),
-	},
-	.rx_fifo = {
-		.msg		= MAILBOX_MESSAGE(1),
-		.msg_stat	= MAILBOX_MSGSTATUS(1),
-	},
-	.irqenable	= MAILBOX_IRQENABLE(0),
-	.irqstatus	= MAILBOX_IRQSTATUS(0),
-	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
-	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(1),
-	.irqdisable	= MAILBOX_IRQENABLE(0),
-};
-
-struct omap_mbox mbox_dsp_info = {
-	.name	= "dsp",
-	.ops	= &omap2_mbox_ops,
-	.priv	= &omap2_mbox_dsp_priv,
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP3)
-struct omap_mbox *omap3_mboxes[] = { &mbox_dsp_info, NULL };
-#endif
-
-#if defined(CONFIG_SOC_OMAP2420)
-/* IVA */
-static struct omap_mbox2_priv omap2_mbox_iva_priv = {
-	.tx_fifo = {
-		.msg		= MAILBOX_MESSAGE(2),
-		.fifo_stat	= MAILBOX_FIFOSTATUS(2),
-	},
-	.rx_fifo = {
-		.msg		= MAILBOX_MESSAGE(3),
-		.msg_stat	= MAILBOX_MSGSTATUS(3),
-	},
-	.irqenable	= MAILBOX_IRQENABLE(3),
-	.irqstatus	= MAILBOX_IRQSTATUS(3),
-	.notfull_bit	= MAILBOX_IRQ_NOTFULL(2),
-	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(3),
-	.irqdisable	= MAILBOX_IRQENABLE(3),
-};
-
-static struct omap_mbox mbox_iva_info = {
-	.name	= "iva",
-	.ops	= &omap2_mbox_ops,
-	.priv	= &omap2_mbox_iva_priv,
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2
-struct omap_mbox *omap2_mboxes[] = {
-	&mbox_dsp_info,
-#ifdef CONFIG_SOC_OMAP2420
-	&mbox_iva_info,
-#endif
-	NULL
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP4)
-/* OMAP4 */
-static struct omap_mbox2_priv omap2_mbox_1_priv = {
-	.tx_fifo = {
-		.msg		= MAILBOX_MESSAGE(0),
-		.fifo_stat	= MAILBOX_FIFOSTATUS(0),
-	},
-	.rx_fifo = {
-		.msg		= MAILBOX_MESSAGE(1),
-		.msg_stat	= MAILBOX_MSGSTATUS(1),
-	},
-	.irqenable	= OMAP4_MAILBOX_IRQENABLE(0),
-	.irqstatus	= OMAP4_MAILBOX_IRQSTATUS(0),
-	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
-	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(1),
-	.irqdisable	= OMAP4_MAILBOX_IRQENABLE_CLR(0),
-};
-
-struct omap_mbox mbox_1_info = {
-	.name	= "mailbox-1",
-	.ops	= &omap2_mbox_ops,
-	.priv	= &omap2_mbox_1_priv,
-};
-
-static struct omap_mbox2_priv omap2_mbox_2_priv = {
-	.tx_fifo = {
-		.msg		= MAILBOX_MESSAGE(3),
-		.fifo_stat	= MAILBOX_FIFOSTATUS(3),
-	},
-	.rx_fifo = {
-		.msg		= MAILBOX_MESSAGE(2),
-		.msg_stat	= MAILBOX_MSGSTATUS(2),
-	},
-	.irqenable	= OMAP4_MAILBOX_IRQENABLE(0),
-	.irqstatus	= OMAP4_MAILBOX_IRQSTATUS(0),
-	.notfull_bit	= MAILBOX_IRQ_NOTFULL(3),
-	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(2),
-	.irqdisable     = OMAP4_MAILBOX_IRQENABLE_CLR(0),
-};
-
-struct omap_mbox mbox_2_info = {
-	.name	= "mailbox-2",
-	.ops	= &omap2_mbox_ops,
-	.priv	= &omap2_mbox_2_priv,
-};
-
-struct omap_mbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL };
-#endif
-
-static int omap2_mbox_probe(struct platform_device *pdev)
-{
-	struct resource *mem;
-	int ret;
-	struct omap_mbox **list;
-
-	if (false)
-		;
-#if defined(CONFIG_ARCH_OMAP3)
-	else if (cpu_is_omap34xx()) {
-		list = omap3_mboxes;
-
-		list[0]->irq = platform_get_irq(pdev, 0);
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP2)
-	else if (cpu_is_omap2430()) {
-		list = omap2_mboxes;
-
-		list[0]->irq = platform_get_irq(pdev, 0);
-	} else if (cpu_is_omap2420()) {
-		list = omap2_mboxes;
-
-		list[0]->irq = platform_get_irq_byname(pdev, "dsp");
-		list[1]->irq = platform_get_irq_byname(pdev, "iva");
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-	else if (cpu_is_omap44xx()) {
-		list = omap4_mboxes;
-
-		list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
-	}
-#endif
-	else {
-		pr_err("%s: platform not supported\n", __func__);
-		return -ENODEV;
-	}
-
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mbox_base = ioremap(mem->start, resource_size(mem));
-	if (!mbox_base)
-		return -ENOMEM;
-
-	ret = omap_mbox_register(&pdev->dev, list);
-	if (ret) {
-		iounmap(mbox_base);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int omap2_mbox_remove(struct platform_device *pdev)
-{
-	omap_mbox_unregister();
-	iounmap(mbox_base);
-	return 0;
-}
-
-static struct platform_driver omap2_mbox_driver = {
-	.probe = omap2_mbox_probe,
-	.remove = omap2_mbox_remove,
-	.driver = {
-		.name = "omap-mailbox",
-	},
-};
-
-static int __init omap2_mbox_init(void)
-{
-	return platform_driver_register(&omap2_mbox_driver);
-}
-
-static void __exit omap2_mbox_exit(void)
-{
-	platform_driver_unregister(&omap2_mbox_driver);
-}
-
-module_init(omap2_mbox_init);
-module_exit(omap2_mbox_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("omap mailbox: omap2/3/4 architecture specific functions");
-MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
-MODULE_AUTHOR("Paul Mundt");
-MODULE_ALIAS("platform:omap2-mailbox");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@ obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-c
 obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
 obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common)
 obj-$(CONFIG_SOC_OMAP5)	 += prm44xx.o $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common)
 
 ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
 obj-y += mcbsp.o
@@ -34,10 +35,10 @@ obj-$(CONFIG_SOC_HAS_OMAP2_SDRC)	+= sdrc
 
 smp-$(CONFIG_SMP)			+= omap-smp.o omap-headsmp.o
 smp-$(CONFIG_HOTPLUG_CPU)		+= omap-hotplug.o
-omap-4-5-common				=  omap4-common.o omap-wakeupgen.o \
-					   sleep44xx.o
-obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-common) $(smp-y)
-obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-common) $(smp-y)
+omap-4-5-common				=  omap4-common.o omap-wakeupgen.o
+obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-common) $(smp-y) sleep44xx.o
+obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-common) $(smp-y) sleep44xx.o
+obj-$(CONFIG_SOC_AM43XX)		+= $(omap-4-5-common)
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_omap-headsmp.o			:=-Wa,-march=armv7-a$(plus_sec)
@@ -58,12 +59,13 @@ obj-$(CONFIG_SOC_OMAP2420)		+= omap2-res
 obj-$(CONFIG_SOC_OMAP2430)		+= omap2-restart.o
 obj-$(CONFIG_SOC_AM33XX)		+= am33xx-restart.o
 obj-$(CONFIG_ARCH_OMAP3)		+= omap3-restart.o
+obj-$(CONFIG_ARCH_OMAP4)		+= omap4-restart.o
+obj-$(CONFIG_SOC_OMAP5)			+= omap4-restart.o
 
 # Pin multiplexing
 obj-$(CONFIG_SOC_OMAP2420)		+= mux2420.o
 obj-$(CONFIG_SOC_OMAP2430)		+= mux2430.o
 obj-$(CONFIG_ARCH_OMAP3)		+= mux34xx.o
-obj-$(CONFIG_ARCH_OMAP4)		+= mux44xx.o
 
 # SMS/SDRC
 obj-$(CONFIG_ARCH_OMAP2)		+= sdrc2xxx.o
@@ -93,10 +95,6 @@ obj-$(CONFIG_POWER_AVS_OMAP_CLASS3)    +
 AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
 AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a$(plus_sec)
 
-ifeq ($(CONFIG_PM_VERBOSE),y)
-CFLAGS_pm_bus.o				+= -DDEBUG
-endif
-
 endif
 
 ifeq ($(CONFIG_CPU_IDLE),y)
@@ -110,6 +108,7 @@ obj-$(CONFIG_ARCH_OMAP2)		+= prm2xxx_3xx
 obj-$(CONFIG_ARCH_OMAP3)		+= prm2xxx_3xxx.o prm3xxx.o cm3xxx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= vc3xxx_data.o vp3xxx_data.o
 obj-$(CONFIG_SOC_AM33XX)		+= prm33xx.o cm33xx.o
+obj-$(CONFIG_SOC_AM43XX)		+= prm33xx.o cm33xx.o
 omap-prcm-4-5-common			=  cminst44xx.o cm44xx.o prm44xx.o \
 					   prcm_mpu44xx.o prminst44xx.o \
 					   vc44xx_data.o vp44xx_data.o
@@ -125,8 +124,9 @@ obj-$(CONFIG_ARCH_OMAP3)		+= voltagedoma
 obj-$(CONFIG_ARCH_OMAP4)		+= $(voltagedomain-common)
 obj-$(CONFIG_ARCH_OMAP4)		+= voltagedomains44xx_data.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(voltagedomain-common)
-obj-$(CONFIG_SOC_AM33XX)                += voltagedomains33xx_data.o
+obj-$(CONFIG_SOC_AM43XX)		+= $(voltagedomain-common)
 obj-$(CONFIG_SOC_OMAP5)			+= $(voltagedomain-common)
+obj-$(CONFIG_SOC_OMAP5)                += voltagedomains54xx_data.o
 
 # OMAP powerdomain framework
 powerdomain-common			+= powerdomain.o powerdomain-common.o
@@ -140,7 +140,9 @@ obj-$(CONFIG_ARCH_OMAP4)		+= $(powerdoma
 obj-$(CONFIG_ARCH_OMAP4)		+= powerdomains44xx_data.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(powerdomain-common)
 obj-$(CONFIG_SOC_AM33XX)		+= powerdomains33xx_data.o
+obj-$(CONFIG_SOC_AM43XX)		+= $(powerdomain-common)
 obj-$(CONFIG_SOC_OMAP5)			+= $(powerdomain-common)
+obj-$(CONFIG_SOC_OMAP5)			+= powerdomains54xx_data.o
 
 # PRCM clockdomain control
 clockdomain-common			+= clockdomain.o
@@ -155,7 +157,9 @@ obj-$(CONFIG_ARCH_OMAP4)		+= $(clockdoma
 obj-$(CONFIG_ARCH_OMAP4)		+= clockdomains44xx_data.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clockdomain-common)
 obj-$(CONFIG_SOC_AM33XX)		+= clockdomains33xx_data.o
+obj-$(CONFIG_SOC_AM43XX)		+= $(clockdomain-common)
 obj-$(CONFIG_SOC_OMAP5)			+= $(clockdomain-common)
+obj-$(CONFIG_SOC_OMAP5)			+= clockdomains54xx_data.o
 
 # Clock framework
 obj-$(CONFIG_ARCH_OMAP2)		+= $(clock-common) clock2xxx.o
@@ -198,14 +202,12 @@ obj-$(CONFIG_ARCH_OMAP3)		+= omap_hwmod_
 obj-$(CONFIG_ARCH_OMAP3)		+= omap_hwmod_3xxx_data.o
 obj-$(CONFIG_SOC_AM33XX)		+= omap_hwmod_33xx_data.o
 obj-$(CONFIG_ARCH_OMAP4)		+= omap_hwmod_44xx_data.o
+obj-$(CONFIG_SOC_OMAP5)			+= omap_hwmod_54xx_data.o
 
 # EMU peripherals
 obj-$(CONFIG_OMAP3_EMU)			+= emu.o
 obj-$(CONFIG_HW_PERF_EVENTS)		+= pmu.o
 
-obj-$(CONFIG_OMAP_MBOX_FWK)		+= mailbox_mach.o
-mailbox_mach-objs			:= mailbox.o
-
 iommu-$(CONFIG_OMAP_IOMMU)		:= omap-iommu.o
 obj-y					+= $(iommu-m) $(iommu-y)
 
@@ -251,8 +253,6 @@ obj-$(CONFIG_MACH_CM_T35)		+= board-cm-t
 obj-$(CONFIG_MACH_CM_T3517)		+= board-cm-t3517.o
 obj-$(CONFIG_MACH_IGEP0020)		+= board-igep0020.o
 obj-$(CONFIG_MACH_TOUCHBOOK)		+= board-omap3touchbook.o
-obj-$(CONFIG_MACH_OMAP_4430SDP)		+= board-4430sdp.o
-obj-$(CONFIG_MACH_OMAP4_PANDA)		+= board-omap4panda.o
 
 obj-$(CONFIG_MACH_OMAP3517EVM)		+= board-am3517evm.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/mux44xx.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/mux44xx.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/mux44xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/mux44xx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1356 +0,0 @@
-/*
- * OMAP44xx ES1.0 pin mux definition
- *
- * Copyright (C) 2010 Texas Instruments, Inc.
- *
- * Benoit Cousson (b-cousson@ti.com)
- *
- * - Based on mux34xx.c done by Tony Lindgren <tony@atomide.com>
- *
- * This file is automatically generated from the OMAP hardware databases.
- * We respectfully ask that any modifications to this file be coordinated
- * with the public linux-omap@vger.kernel.org mailing list and the
- * authors above to ensure that the autogeneration scripts are kept
- * up-to-date with the file contents.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include "mux.h"
-
-#ifdef CONFIG_OMAP_MUX
-
-#define _OMAP4_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7)	\
-{									\
-	.reg_offset	= (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET),	\
-	.gpio		= (g),						\
-	.muxnames	= { m0, m1, m2, m3, m4, m5, m6, m7 },		\
-}
-
-#else
-
-#define _OMAP4_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7)	\
-{									\
-	.reg_offset	= (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET),	\
-	.gpio		= (g),						\
-}
-
-#endif
-
-#define _OMAP4_BALLENTRY(M0, bb, bt)				\
-{									\
-	.reg_offset	= (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET),	\
-	.balls		= { bb, bt },					\
-}
-
-/*
- * Superset of all mux modes for omap4 ES1.0
- */
-static struct omap_mux __initdata omap4_core_muxmodes[] = {
-	_OMAP4_MUXENTRY(GPMC_AD0, 0, "gpmc_ad0", "sdmmc2_dat0", NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD1, 0, "gpmc_ad1", "sdmmc2_dat1", NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD2, 0, "gpmc_ad2", "sdmmc2_dat2", NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD3, 0, "gpmc_ad3", "sdmmc2_dat3", NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD4, 0, "gpmc_ad4", "sdmmc2_dat4",
-			"sdmmc2_dir_dat0", NULL, NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD5, 0, "gpmc_ad5", "sdmmc2_dat5",
-			"sdmmc2_dir_dat1", NULL, NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD6, 0, "gpmc_ad6", "sdmmc2_dat6",
-			"sdmmc2_dir_cmd", NULL, NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD7, 0, "gpmc_ad7", "sdmmc2_dat7",
-			"sdmmc2_clk_fdbk", NULL, NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD8, 32, "gpmc_ad8", "kpd_row0", "c2c_data15",
-			"gpio_32", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD9, 33, "gpmc_ad9", "kpd_row1", "c2c_data14",
-			"gpio_33", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD10, 34, "gpmc_ad10", "kpd_row2", "c2c_data13",
-			"gpio_34", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD11, 35, "gpmc_ad11", "kpd_row3", "c2c_data12",
-			"gpio_35", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD12, 36, "gpmc_ad12", "kpd_col0", "c2c_data11",
-			"gpio_36", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD13, 37, "gpmc_ad13", "kpd_col1", "c2c_data10",
-			"gpio_37", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD14, 38, "gpmc_ad14", "kpd_col2", "c2c_data9",
-			"gpio_38", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD15, 39, "gpmc_ad15", "kpd_col3", "c2c_data8",
-			"gpio_39", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_A16, 40, "gpmc_a16", "kpd_row4", "c2c_datain0",
-			"gpio_40", "venc_656_data0", NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_A17, 41, "gpmc_a17", "kpd_row5", "c2c_datain1",
-			"gpio_41", "venc_656_data1", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_A18, 42, "gpmc_a18", "kpd_row6", "c2c_datain2",
-			"gpio_42", "venc_656_data2", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_A19, 43, "gpmc_a19", "kpd_row7", "c2c_datain3",
-			"gpio_43", "venc_656_data3", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_A20, 44, "gpmc_a20", "kpd_col4", "c2c_datain4",
-			"gpio_44", "venc_656_data4", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_A21, 45, "gpmc_a21", "kpd_col5", "c2c_datain5",
-			"gpio_45", "venc_656_data5", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_A22, 46, "gpmc_a22", "kpd_col6", "c2c_datain6",
-			"gpio_46", "venc_656_data6", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_A23, 47, "gpmc_a23", "kpd_col7", "c2c_datain7",
-			"gpio_47", "venc_656_data7", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_A24, 48, "gpmc_a24", NULL, "c2c_clkout0",
-			"gpio_48", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_A25, 49, "gpmc_a25", NULL, "c2c_clkout1",
-			"gpio_49", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_NCS0, 50, "gpmc_ncs0", NULL, NULL, "gpio_50",
-			"sys_ndmareq0", NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_NCS1, 51, "gpmc_ncs1", NULL, "c2c_dataout6",
-			"gpio_51", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_NCS2, 52, "gpmc_ncs2", NULL, "c2c_dataout7",
-			"gpio_52", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_NCS3, 53, "gpmc_ncs3", "gpmc_dir",
-			"c2c_dataout4", "gpio_53", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_NWP, 54, "gpmc_nwp", "dsi1_te0", NULL, "gpio_54",
-			"sys_ndmareq1", NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_CLK, 55, "gpmc_clk", NULL, NULL, "gpio_55",
-			"sys_ndmareq2", NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_NADV_ALE, 56, "gpmc_nadv_ale", "dsi1_te1", NULL,
-			"gpio_56", "sys_ndmareq3", NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_NOE, 0, "gpmc_noe", "sdmmc2_clk", NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_NWE, 0, "gpmc_nwe", "sdmmc2_cmd", NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_NBE0_CLE, 59, "gpmc_nbe0_cle", "dsi2_te0", NULL,
-			"gpio_59", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_NBE1, 60, "gpmc_nbe1", NULL, "c2c_dataout5",
-			"gpio_60", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_WAIT0, 61, "gpmc_wait0", "dsi2_te1", NULL,
-			"gpio_61", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_WAIT1, 62, "gpmc_wait1", NULL, "c2c_dataout2",
-			"gpio_62", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(C2C_DATA11, 100, "c2c_data11", "usbc1_icusb_txen",
-			"c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(C2C_DATA12, 101, "c2c_data12", "dsi1_te0",
-			"c2c_clkin0", "gpio_101", "sys_ndmareq1", NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(C2C_DATA13, 102, "c2c_data13", "dsi1_te1",
-			"c2c_clkin1", "gpio_102", "sys_ndmareq2", NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(C2C_DATA14, 103, "c2c_data14", "dsi2_te0",
-			"c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(C2C_DATA15, 104, "c2c_data15", "dsi2_te1",
-			"c2c_dataout1", "gpio_104", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(HDMI_HPD, 63, "hdmi_hpd", NULL, NULL, "gpio_63", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(HDMI_CEC, 64, "hdmi_cec", NULL, NULL, "gpio_64", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(HDMI_DDC_SCL, 65, "hdmi_ddc_scl", NULL, NULL,
-			"gpio_65", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(HDMI_DDC_SDA, 66, "hdmi_ddc_sda", NULL, NULL,
-			"gpio_66", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DX0, 0, "csi21_dx0", NULL, NULL, "gpi_67", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DY0, 0, "csi21_dy0", NULL, NULL, "gpi_68", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DX1, 0, "csi21_dx1", NULL, NULL, "gpi_69", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DY1, 0, "csi21_dy1", NULL, NULL, "gpi_70", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DX2, 0, "csi21_dx2", NULL, NULL, "gpi_71", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DY2, 0, "csi21_dy2", NULL, NULL, "gpi_72", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DX3, 0, "csi21_dx3", NULL, NULL, "gpi_73", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DY3, 0, "csi21_dy3", NULL, NULL, "gpi_74", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DX4, 0, "csi21_dx4", NULL, NULL, "gpi_75", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI21_DY4, 0, "csi21_dy4", NULL, NULL, "gpi_76", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI22_DX0, 0, "csi22_dx0", NULL, NULL, "gpi_77", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI22_DY0, 0, "csi22_dy0", NULL, NULL, "gpi_78", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI22_DX1, 0, "csi22_dx1", NULL, NULL, "gpi_79", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CSI22_DY1, 0, "csi22_dy1", NULL, NULL, "gpi_80", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CAM_SHUTTER, 81, "cam_shutter", NULL, NULL, "gpio_81",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CAM_STROBE, 82, "cam_strobe", NULL, NULL, "gpio_82",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(CAM_GLOBALRESET, 83, "cam_globalreset", NULL, NULL,
-			"gpio_83", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_CLK, 84, "usbb1_ulpitll_clk",
-			"hsi1_cawake", NULL, "gpio_84", "usbb1_ulpiphy_clk",
-			NULL, "hw_dbg20", "safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_STP, 85, "usbb1_ulpitll_stp",
-			"hsi1_cadata", "mcbsp4_clkr", "gpio_85",
-			"usbb1_ulpiphy_stp", "usbb1_mm_rxdp", "hw_dbg21",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DIR, 86, "usbb1_ulpitll_dir",
-			"hsi1_caflag", "mcbsp4_fsr", "gpio_86",
-			"usbb1_ulpiphy_dir", NULL, "hw_dbg22", "safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_NXT, 87, "usbb1_ulpitll_nxt",
-			"hsi1_acready", "mcbsp4_fsx", "gpio_87",
-			"usbb1_ulpiphy_nxt", "usbb1_mm_rxdm", "hw_dbg23",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT0, 88, "usbb1_ulpitll_dat0",
-			"hsi1_acwake", "mcbsp4_clkx", "gpio_88",
-			"usbb1_ulpiphy_dat0", "usbb1_mm_rxrcv", "hw_dbg24",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT1, 89, "usbb1_ulpitll_dat1",
-			"hsi1_acdata", "mcbsp4_dx", "gpio_89",
-			"usbb1_ulpiphy_dat1", "usbb1_mm_txse0", "hw_dbg25",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT2, 90, "usbb1_ulpitll_dat2",
-			"hsi1_acflag", "mcbsp4_dr", "gpio_90",
-			"usbb1_ulpiphy_dat2", "usbb1_mm_txdat", "hw_dbg26",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT3, 91, "usbb1_ulpitll_dat3",
-			"hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3",
-			"usbb1_mm_txen", "hw_dbg27", "safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT4, 92, "usbb1_ulpitll_dat4",
-			"dmtimer8_pwm_evt", "abe_mcbsp3_dr", "gpio_92",
-			"usbb1_ulpiphy_dat4", NULL, "hw_dbg28", "safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT5, 93, "usbb1_ulpitll_dat5",
-			"dmtimer9_pwm_evt", "abe_mcbsp3_dx", "gpio_93",
-			"usbb1_ulpiphy_dat5", NULL, "hw_dbg29", "safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT6, 94, "usbb1_ulpitll_dat6",
-			"dmtimer10_pwm_evt", "abe_mcbsp3_clkx", "gpio_94",
-			"usbb1_ulpiphy_dat6", "abe_dmic_din3", "hw_dbg30",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT7, 95, "usbb1_ulpitll_dat7",
-			"dmtimer11_pwm_evt", "abe_mcbsp3_fsx", "gpio_95",
-			"usbb1_ulpiphy_dat7", "abe_dmic_clk3", "hw_dbg31",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_HSIC_DATA, 96, "usbb1_hsic_data", NULL, NULL,
-			"gpio_96", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_HSIC_STROBE, 97, "usbb1_hsic_strobe", NULL,
-			NULL, "gpio_97", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBC1_ICUSB_DP, 98, "usbc1_icusb_dp", NULL, NULL,
-			"gpio_98", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBC1_ICUSB_DM, 99, "usbc1_icusb_dm", NULL, NULL,
-			"gpio_99", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_CLK, 100, "sdmmc1_clk", NULL, "dpm_emu19",
-			"gpio_100", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_CMD, 101, "sdmmc1_cmd", NULL, "uart1_rx",
-			"gpio_101", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_DAT0, 102, "sdmmc1_dat0", NULL, "dpm_emu18",
-			"gpio_102", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_DAT1, 103, "sdmmc1_dat1", NULL, "dpm_emu17",
-			"gpio_103", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_DAT2, 104, "sdmmc1_dat2", NULL, "dpm_emu16",
-			"gpio_104", "jtag_tms_tmsc", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_DAT3, 105, "sdmmc1_dat3", NULL, "dpm_emu15",
-			"gpio_105", "jtag_tck", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_DAT4, 106, "sdmmc1_dat4", NULL, NULL,
-			"gpio_106", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_DAT5, 107, "sdmmc1_dat5", NULL, NULL,
-			"gpio_107", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_DAT6, 108, "sdmmc1_dat6", NULL, NULL,
-			"gpio_108", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC1_DAT7, 109, "sdmmc1_dat7", NULL, NULL,
-			"gpio_109", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_MCBSP2_CLKX, 110, "abe_mcbsp2_clkx", "mcspi2_clk",
-			"abe_mcasp_ahclkx", "gpio_110", "usbb2_mm_rxdm",
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_MCBSP2_DR, 111, "abe_mcbsp2_dr", "mcspi2_somi",
-			"abe_mcasp_axr", "gpio_111", "usbb2_mm_rxdp", NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_MCBSP2_DX, 112, "abe_mcbsp2_dx", "mcspi2_simo",
-			"abe_mcasp_amute", "gpio_112", "usbb2_mm_rxrcv", NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_MCBSP2_FSX, 113, "abe_mcbsp2_fsx", "mcspi2_cs0",
-			"abe_mcasp_afsx", "gpio_113", "usbb2_mm_txen", NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_MCBSP1_CLKX, 114, "abe_mcbsp1_clkx",
-			"abe_slimbus1_clock", NULL, "gpio_114", NULL, NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_MCBSP1_DR, 115, "abe_mcbsp1_dr",
-			"abe_slimbus1_data", NULL, "gpio_115", NULL, NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_MCBSP1_DX, 116, "abe_mcbsp1_dx", "sdmmc3_dat2",
-			"abe_mcasp_aclkx", "gpio_116", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(ABE_MCBSP1_FSX, 117, "abe_mcbsp1_fsx", "sdmmc3_dat3",
-			"abe_mcasp_amutein", "gpio_117", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(ABE_PDM_UL_DATA, 0, "abe_pdm_ul_data",
-			"abe_mcbsp3_dr", NULL, NULL, NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(ABE_PDM_DL_DATA, 0, "abe_pdm_dl_data",
-			"abe_mcbsp3_dx", NULL, NULL, NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(ABE_PDM_FRAME, 0, "abe_pdm_frame", "abe_mcbsp3_clkx",
-			NULL, NULL, NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_PDM_LB_CLK, 0, "abe_pdm_lb_clk", "abe_mcbsp3_fsx",
-			NULL, NULL, NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_CLKS, 118, "abe_clks", NULL, NULL, "gpio_118",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_DMIC_CLK1, 119, "abe_dmic_clk1", NULL, NULL,
-			"gpio_119", "usbb2_mm_txse0", NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(ABE_DMIC_DIN1, 120, "abe_dmic_din1", NULL, NULL,
-			"gpio_120", "usbb2_mm_txdat", NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(ABE_DMIC_DIN2, 121, "abe_dmic_din2", "slimbus2_clock",
-			NULL, "gpio_121", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_DMIC_DIN3, 122, "abe_dmic_din3", "slimbus2_data",
-			"abe_dmic_clk2", "gpio_122", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(UART2_CTS, 123, "uart2_cts", "sdmmc3_clk", NULL,
-			"gpio_123", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UART2_RTS, 124, "uart2_rts", "sdmmc3_cmd", NULL,
-			"gpio_124", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UART2_RX, 125, "uart2_rx", "sdmmc3_dat0", NULL,
-			"gpio_125", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UART2_TX, 126, "uart2_tx", "sdmmc3_dat1", NULL,
-			"gpio_126", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(HDQ_SIO, 127, "hdq_sio", "i2c3_sccb", "i2c2_sccb",
-			"gpio_127", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(I2C1_SCL, 0, "i2c1_scl", NULL, NULL, NULL, NULL, NULL,
-			NULL, NULL),
-	_OMAP4_MUXENTRY(I2C1_SDA, 0, "i2c1_sda", NULL, NULL, NULL, NULL, NULL,
-			NULL, NULL),
-	_OMAP4_MUXENTRY(I2C2_SCL, 128, "i2c2_scl", "uart1_rx", NULL,
-			"gpio_128", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(I2C2_SDA, 129, "i2c2_sda", "uart1_tx", NULL,
-			"gpio_129", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(I2C3_SCL, 130, "i2c3_scl", NULL, NULL, "gpio_130",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(I2C3_SDA, 131, "i2c3_sda", NULL, NULL, "gpio_131",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(I2C4_SCL, 132, "i2c4_scl", NULL, NULL, "gpio_132",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(I2C4_SDA, 133, "i2c4_sda", NULL, NULL, "gpio_133",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI1_CLK, 134, "mcspi1_clk", NULL, NULL, "gpio_134",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI1_SOMI, 135, "mcspi1_somi", NULL, NULL,
-			"gpio_135", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI1_SIMO, 136, "mcspi1_simo", NULL, NULL,
-			"gpio_136", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI1_CS0, 137, "mcspi1_cs0", NULL, NULL, "gpio_137",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI1_CS1, 138, "mcspi1_cs1", "uart1_rx", NULL,
-			"gpio_138", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI1_CS2, 139, "mcspi1_cs2", "uart1_cts",
-			"slimbus2_clock", "gpio_139", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI1_CS3, 140, "mcspi1_cs3", "uart1_rts",
-			"slimbus2_data", "gpio_140", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(UART3_CTS_RCTX, 141, "uart3_cts_rctx", "uart1_tx",
-			NULL, "gpio_141", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UART3_RTS_SD, 142, "uart3_rts_sd", NULL, NULL,
-			"gpio_142", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UART3_RX_IRRX, 143, "uart3_rx_irrx",
-			"dmtimer8_pwm_evt", NULL, "gpio_143", NULL, NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UART3_TX_IRTX, 144, "uart3_tx_irtx",
-			"dmtimer9_pwm_evt", NULL, "gpio_144", NULL, NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_CLK, 145, "sdmmc5_clk", "mcspi2_clk",
-			"usbc1_icusb_dp", "gpio_145", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_CMD, 146, "sdmmc5_cmd", "mcspi2_simo",
-			"usbc1_icusb_dm", "gpio_146", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_DAT0, 147, "sdmmc5_dat0", "mcspi2_somi",
-			"usbc1_icusb_rcv", "gpio_147", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_DAT1, 148, "sdmmc5_dat1", NULL,
-			"usbc1_icusb_txen", "gpio_148", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_DAT2, 149, "sdmmc5_dat2", "mcspi2_cs1", NULL,
-			"gpio_149", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_DAT3, 150, "sdmmc5_dat3", "mcspi2_cs0", NULL,
-			"gpio_150", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI4_CLK, 151, "mcspi4_clk", "sdmmc4_clk", NULL,
-			"gpio_151", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI4_SIMO, 152, "mcspi4_simo", "sdmmc4_cmd", NULL,
-			"gpio_152", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI4_SOMI, 153, "mcspi4_somi", "sdmmc4_dat0", NULL,
-			"gpio_153", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI4_CS0, 154, "mcspi4_cs0", "sdmmc4_dat3", NULL,
-			"gpio_154", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UART4_RX, 155, "uart4_rx", "sdmmc4_dat2", NULL,
-			"gpio_155", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UART4_TX, 156, "uart4_tx", "sdmmc4_dat1", NULL,
-			"gpio_156", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_CLK, 157, "usbb2_ulpitll_clk",
-			"usbb2_ulpiphy_clk", "sdmmc4_cmd", "gpio_157",
-			"hsi2_cawake", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_STP, 158, "usbb2_ulpitll_stp",
-			"usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158",
-			"hsi2_cadata", "dispc2_data23", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DIR, 159, "usbb2_ulpitll_dir",
-			"usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159",
-			"hsi2_caflag", "dispc2_data22", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_NXT, 160, "usbb2_ulpitll_nxt",
-			"usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160",
-			"hsi2_acready", "dispc2_data21", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT0, 161, "usbb2_ulpitll_dat0",
-			"usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161",
-			"hsi2_acwake", "dispc2_data20", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT1, 162, "usbb2_ulpitll_dat1",
-			"usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162",
-			"hsi2_acdata", "dispc2_data19", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT2, 163, "usbb2_ulpitll_dat2",
-			"usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163",
-			"hsi2_acflag", "dispc2_data18", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT3, 164, "usbb2_ulpitll_dat3",
-			"usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164",
-			"hsi2_caready", "dispc2_data15", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT4, 165, "usbb2_ulpitll_dat4",
-			"usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165",
-			"mcspi3_somi", "dispc2_data14", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT5, 166, "usbb2_ulpitll_dat5",
-			"usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166",
-			"mcspi3_cs0", "dispc2_data13", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT6, 167, "usbb2_ulpitll_dat6",
-			"usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167",
-			"mcspi3_simo", "dispc2_data12", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT7, 168, "usbb2_ulpitll_dat7",
-			"usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168",
-			"mcspi3_clk", "dispc2_data11", NULL, "reserved"),
-	_OMAP4_MUXENTRY(USBB2_HSIC_DATA, 169, "usbb2_hsic_data", NULL, NULL,
-			"gpio_169", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_HSIC_STROBE, 170, "usbb2_hsic_strobe", NULL,
-			NULL, "gpio_170", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_TX0, 171, "unipro_tx0", "kpd_col0", NULL,
-			"gpio_171", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_TY0, 172, "unipro_ty0", "kpd_col1", NULL,
-			"gpio_172", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_TX1, 173, "unipro_tx1", "kpd_col2", NULL,
-			"gpio_173", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_TY1, 174, "unipro_ty1", "kpd_col3", NULL,
-			"gpio_174", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_TX2, 0, "unipro_tx2", "kpd_col4", NULL,
-			"gpio_0", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_TY2, 1, "unipro_ty2", "kpd_col5", NULL,
-			"gpio_1", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_RX0, 0, "unipro_rx0", "kpd_row0", NULL,
-			"gpi_175", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_RY0, 0, "unipro_ry0", "kpd_row1", NULL,
-			"gpi_176", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_RX1, 0, "unipro_rx1", "kpd_row2", NULL,
-			"gpi_177", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_RY1, 0, "unipro_ry1", "kpd_row3", NULL,
-			"gpi_178", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_RX2, 0, "unipro_rx2", "kpd_row4", NULL,
-			"gpi_2", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UNIPRO_RY2, 0, "unipro_ry2", "kpd_row5", NULL,
-			"gpi_3", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBA0_OTG_CE, 0, "usba0_otg_ce", NULL, NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(USBA0_OTG_DP, 179, "usba0_otg_dp", "uart3_rx_irrx",
-			"uart2_rx", "gpio_179", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBA0_OTG_DM, 180, "usba0_otg_dm", "uart3_tx_irtx",
-			"uart2_tx", "gpio_180", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(FREF_CLK1_OUT, 181, "fref_clk1_out", NULL, NULL,
-			"gpio_181", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(FREF_CLK2_OUT, 182, "fref_clk2_out", NULL, NULL,
-			"gpio_182", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SYS_NIRQ1, 0, "sys_nirq1", NULL, NULL, NULL, NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SYS_NIRQ2, 183, "sys_nirq2", NULL, NULL, "gpio_183",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SYS_BOOT0, 184, "sys_boot0", NULL, NULL, "gpio_184",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SYS_BOOT1, 185, "sys_boot1", NULL, NULL, "gpio_185",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SYS_BOOT2, 186, "sys_boot2", NULL, NULL, "gpio_186",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SYS_BOOT3, 187, "sys_boot3", NULL, NULL, "gpio_187",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SYS_BOOT4, 188, "sys_boot4", NULL, NULL, "gpio_188",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SYS_BOOT5, 189, "sys_boot5", NULL, NULL, "gpio_189",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU0, 11, "dpm_emu0", NULL, NULL, "gpio_11", NULL,
-			NULL, "hw_dbg0", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU1, 12, "dpm_emu1", NULL, NULL, "gpio_12", NULL,
-			NULL, "hw_dbg1", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU2, 13, "dpm_emu2", "usba0_ulpiphy_clk", NULL,
-			"gpio_13", NULL, "dispc2_fid", "hw_dbg2", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU3, 14, "dpm_emu3", "usba0_ulpiphy_stp", NULL,
-			"gpio_14", NULL, "dispc2_data10", "hw_dbg3",
-			"reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU4, 15, "dpm_emu4", "usba0_ulpiphy_dir", NULL,
-			"gpio_15", NULL, "dispc2_data9", "hw_dbg4",
-			"reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU5, 16, "dpm_emu5", "usba0_ulpiphy_nxt", NULL,
-			"gpio_16", "rfbi_te_vsync0", "dispc2_data16",
-			"hw_dbg5", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU6, 17, "dpm_emu6", "usba0_ulpiphy_dat0",
-			"uart3_tx_irtx", "gpio_17", "rfbi_hsync0",
-			"dispc2_data17", "hw_dbg6", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU7, 18, "dpm_emu7", "usba0_ulpiphy_dat1",
-			"uart3_rx_irrx", "gpio_18", "rfbi_cs0",
-			"dispc2_hsync", "hw_dbg7", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU8, 19, "dpm_emu8", "usba0_ulpiphy_dat2",
-			"uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk",
-			"hw_dbg8", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU9, 20, "dpm_emu9", "usba0_ulpiphy_dat3",
-			"uart3_cts_rctx", "gpio_20", "rfbi_we",
-			"dispc2_vsync", "hw_dbg9", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU10, 21, "dpm_emu10", "usba0_ulpiphy_dat4",
-			NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10",
-			"reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU11, 22, "dpm_emu11", "usba0_ulpiphy_dat5",
-			NULL, "gpio_22", "rfbi_data8", "dispc2_data8",
-			"hw_dbg11", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU12, 23, "dpm_emu12", "usba0_ulpiphy_dat6",
-			NULL, "gpio_23", "rfbi_data7", "dispc2_data7",
-			"hw_dbg12", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU13, 24, "dpm_emu13", "usba0_ulpiphy_dat7",
-			NULL, "gpio_24", "rfbi_data6", "dispc2_data6",
-			"hw_dbg13", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU14, 25, "dpm_emu14", "sys_drm_msecure",
-			"uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5",
-			"hw_dbg14", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU15, 26, "dpm_emu15", "sys_secure_indicator",
-			NULL, "gpio_26", "rfbi_data4", "dispc2_data4",
-			"hw_dbg15", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU16, 27, "dpm_emu16", "dmtimer8_pwm_evt",
-			"dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3",
-			"hw_dbg16", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU17, 28, "dpm_emu17", "dmtimer9_pwm_evt",
-			"dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2",
-			"hw_dbg17", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU18, 190, "dpm_emu18", "dmtimer10_pwm_evt",
-			"dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1",
-			"hw_dbg18", "reserved"),
-	_OMAP4_MUXENTRY(DPM_EMU19, 191, "dpm_emu19", "dmtimer11_pwm_evt",
-			"dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0",
-			"hw_dbg19", "reserved"),
-	{ .reg_offset = OMAP_MUX_TERMINATOR },
-};
-
-/*
- * Balls for 44XX CBL package
- * 547-pin CBL ES1.0 S-FPGA-N547, 0.40mm Ball Pitch (Top),
- *				  0.40mm Ball Pitch (Bottom)
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)		\
-		&& defined(CONFIG_OMAP_PACKAGE_CBL)
-static struct omap_ball __initdata omap4_core_cbl_ball[] = {
-	_OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD3, "d13", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD4, "c15", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD5, "d15", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD6, "a16", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD7, "b16", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD8, "c16", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD9, "d16", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD10, "c17", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD11, "d17", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD12, "c18", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD13, "d18", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD14, "c19", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD15, "d19", NULL),
-	_OMAP4_BALLENTRY(GPMC_A16, "b17", NULL),
-	_OMAP4_BALLENTRY(GPMC_A17, "a18", NULL),
-	_OMAP4_BALLENTRY(GPMC_A18, "b18", NULL),
-	_OMAP4_BALLENTRY(GPMC_A19, "a19", NULL),
-	_OMAP4_BALLENTRY(GPMC_A20, "b19", NULL),
-	_OMAP4_BALLENTRY(GPMC_A21, "b20", NULL),
-	_OMAP4_BALLENTRY(GPMC_A22, "a21", NULL),
-	_OMAP4_BALLENTRY(GPMC_A23, "b21", NULL),
-	_OMAP4_BALLENTRY(GPMC_A24, "c20", NULL),
-	_OMAP4_BALLENTRY(GPMC_A25, "d20", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS0, "b25", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS1, "c21", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS2, "d21", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS3, "c22", NULL),
-	_OMAP4_BALLENTRY(GPMC_NWP, "c25", NULL),
-	_OMAP4_BALLENTRY(GPMC_CLK, "b22", NULL),
-	_OMAP4_BALLENTRY(GPMC_NADV_ALE, "d25", NULL),
-	_OMAP4_BALLENTRY(GPMC_NOE, "b11", NULL),
-	_OMAP4_BALLENTRY(GPMC_NWE, "b12", NULL),
-	_OMAP4_BALLENTRY(GPMC_NBE0_CLE, "c23", NULL),
-	_OMAP4_BALLENTRY(GPMC_NBE1, "d22", NULL),
-	_OMAP4_BALLENTRY(GPMC_WAIT0, "b26", NULL),
-	_OMAP4_BALLENTRY(GPMC_WAIT1, "b23", NULL),
-	_OMAP4_BALLENTRY(C2C_DATA11, "d23", NULL),
-	_OMAP4_BALLENTRY(C2C_DATA12, "a24", NULL),
-	_OMAP4_BALLENTRY(C2C_DATA13, "b24", NULL),
-	_OMAP4_BALLENTRY(C2C_DATA14, "c24", NULL),
-	_OMAP4_BALLENTRY(C2C_DATA15, "d24", NULL),
-	_OMAP4_BALLENTRY(HDMI_HPD, "b9", NULL),
-	_OMAP4_BALLENTRY(HDMI_CEC, "b10", NULL),
-	_OMAP4_BALLENTRY(HDMI_DDC_SCL, "a8", NULL),
-	_OMAP4_BALLENTRY(HDMI_DDC_SDA, "b8", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX0, "r26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY0, "r25", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX1, "t26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY1, "t25", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX2, "u26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY2, "u25", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX3, "v26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY3, "v25", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX4, "w26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY4, "w25", NULL),
-	_OMAP4_BALLENTRY(CSI22_DX0, "m26", NULL),
-	_OMAP4_BALLENTRY(CSI22_DY0, "m25", NULL),
-	_OMAP4_BALLENTRY(CSI22_DX1, "n26", NULL),
-	_OMAP4_BALLENTRY(CSI22_DY1, "n25", NULL),
-	_OMAP4_BALLENTRY(CAM_SHUTTER, "t27", NULL),
-	_OMAP4_BALLENTRY(CAM_STROBE, "u27", NULL),
-	_OMAP4_BALLENTRY(CAM_GLOBALRESET, "v27", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_CLK, "ae18", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_STP, "ag19", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DIR, "af19", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_NXT, "ae19", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT0, "af18", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT1, "ag18", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT2, "ae17", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT3, "af17", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT4, "ah17", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT5, "ae16", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT6, "af16", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT7, "ag16", NULL),
-	_OMAP4_BALLENTRY(USBB1_HSIC_DATA, "af14", NULL),
-	_OMAP4_BALLENTRY(USBB1_HSIC_STROBE, "ae14", NULL),
-	_OMAP4_BALLENTRY(USBC1_ICUSB_DP, "h2", NULL),
-	_OMAP4_BALLENTRY(USBC1_ICUSB_DM, "h3", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_CLK, "d2", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_CMD, "e3", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT0, "e4", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT1, "e2", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT2, "e1", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT3, "f4", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT4, "f3", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT5, "f1", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT6, "g4", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT7, "g3", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP2_CLKX, "ad27", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP2_DR, "ad26", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP2_DX, "ad25", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP2_FSX, "ac28", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP1_CLKX, "ac26", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP1_DR, "ac25", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP1_DX, "ab25", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP1_FSX, "ac27", NULL),
-	_OMAP4_BALLENTRY(ABE_PDM_UL_DATA, "ag25", NULL),
-	_OMAP4_BALLENTRY(ABE_PDM_DL_DATA, "af25", NULL),
-	_OMAP4_BALLENTRY(ABE_PDM_FRAME, "ae25", NULL),
-	_OMAP4_BALLENTRY(ABE_PDM_LB_CLK, "af26", NULL),
-	_OMAP4_BALLENTRY(ABE_CLKS, "ah26", NULL),
-	_OMAP4_BALLENTRY(ABE_DMIC_CLK1, "ae24", NULL),
-	_OMAP4_BALLENTRY(ABE_DMIC_DIN1, "af24", NULL),
-	_OMAP4_BALLENTRY(ABE_DMIC_DIN2, "ag24", NULL),
-	_OMAP4_BALLENTRY(ABE_DMIC_DIN3, "ah24", NULL),
-	_OMAP4_BALLENTRY(UART2_CTS, "ab26", NULL),
-	_OMAP4_BALLENTRY(UART2_RTS, "ab27", NULL),
-	_OMAP4_BALLENTRY(UART2_RX, "aa25", NULL),
-	_OMAP4_BALLENTRY(UART2_TX, "aa26", NULL),
-	_OMAP4_BALLENTRY(HDQ_SIO, "aa27", NULL),
-	_OMAP4_BALLENTRY(I2C1_SCL, "ae28", NULL),
-	_OMAP4_BALLENTRY(I2C1_SDA, "ae26", NULL),
-	_OMAP4_BALLENTRY(I2C2_SCL, "c26", NULL),
-	_OMAP4_BALLENTRY(I2C2_SDA, "d26", NULL),
-	_OMAP4_BALLENTRY(I2C3_SCL, "w27", NULL),
-	_OMAP4_BALLENTRY(I2C3_SDA, "y27", NULL),
-	_OMAP4_BALLENTRY(I2C4_SCL, "ag21", NULL),
-	_OMAP4_BALLENTRY(I2C4_SDA, "ah22", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CLK, "af22", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_SOMI, "ae22", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_SIMO, "ag22", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CS0, "ae23", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CS1, "af23", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CS2, "ag23", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CS3, "ah23", NULL),
-	_OMAP4_BALLENTRY(UART3_CTS_RCTX, "f27", NULL),
-	_OMAP4_BALLENTRY(UART3_RTS_SD, "f28", NULL),
-	_OMAP4_BALLENTRY(UART3_RX_IRRX, "g27", NULL),
-	_OMAP4_BALLENTRY(UART3_TX_IRTX, "g28", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_CLK, "ae5", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_CMD, "af5", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_DAT0, "ae4", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_DAT1, "af4", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_DAT2, "ag3", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_DAT3, "af3", NULL),
-	_OMAP4_BALLENTRY(MCSPI4_CLK, "ae21", NULL),
-	_OMAP4_BALLENTRY(MCSPI4_SIMO, "af20", NULL),
-	_OMAP4_BALLENTRY(MCSPI4_SOMI, "af21", NULL),
-	_OMAP4_BALLENTRY(MCSPI4_CS0, "ae20", NULL),
-	_OMAP4_BALLENTRY(UART4_RX, "ag20", NULL),
-	_OMAP4_BALLENTRY(UART4_TX, "ah19", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_CLK, "ag12", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_STP, "af12", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DIR, "ae12", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_NXT, "ag13", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT0, "ae11", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT1, "af11", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT2, "ag11", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT3, "ah11", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT4, "ae10", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT5, "af10", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT6, "ag10", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT7, "ae9", NULL),
-	_OMAP4_BALLENTRY(USBB2_HSIC_DATA, "af13", NULL),
-	_OMAP4_BALLENTRY(USBB2_HSIC_STROBE, "ae13", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_TX0, "g26", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_TY0, "g25", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_TX1, "h26", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_TY1, "h25", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_TX2, "j27", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_TY2, "h27", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_RX0, "j26", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_RY0, "j25", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_RX1, "k26", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_RY1, "k25", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_RX2, "l27", NULL),
-	_OMAP4_BALLENTRY(UNIPRO_RY2, "k27", NULL),
-	_OMAP4_BALLENTRY(USBA0_OTG_CE, "c3", NULL),
-	_OMAP4_BALLENTRY(USBA0_OTG_DP, "b5", NULL),
-	_OMAP4_BALLENTRY(USBA0_OTG_DM, "b4", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK1_OUT, "aa28", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK2_OUT, "y28", NULL),
-	_OMAP4_BALLENTRY(SYS_NIRQ1, "ae6", NULL),
-	_OMAP4_BALLENTRY(SYS_NIRQ2, "af6", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT0, "f26", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT1, "e27", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT2, "e26", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT3, "e25", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT4, "d28", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT5, "d27", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU0, "m2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU1, "n2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU2, "p2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU3, "v1", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU4, "v2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU5, "w1", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU6, "w2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU7, "w3", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU8, "w4", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU9, "y2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU10, "y3", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU11, "y4", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU12, "aa1", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU13, "aa2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU14, "aa3", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU15, "aa4", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU16, "ab2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU17, "ab3", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU18, "ab4", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU19, "ac4", NULL),
-	{ .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap4_core_cbl_ball  NULL
-#endif
-
-/*
- * Signals different on ES2.0 compared to superset
- */
-static struct omap_mux __initdata omap4_es2_core_subset[] = {
-	_OMAP4_MUXENTRY(GPMC_AD8, 32, "gpmc_ad8", "kpd_row0", "c2c_data15",
-			"gpio_32", NULL, "sdmmc1_dat0", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD9, 33, "gpmc_ad9", "kpd_row1", "c2c_data14",
-			"gpio_33", NULL, "sdmmc1_dat1", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD10, 34, "gpmc_ad10", "kpd_row2", "c2c_data13",
-			"gpio_34", NULL, "sdmmc1_dat2", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD11, 35, "gpmc_ad11", "kpd_row3", "c2c_data12",
-			"gpio_35", NULL, "sdmmc1_dat3", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD12, 36, "gpmc_ad12", "kpd_col0", "c2c_data11",
-			"gpio_36", NULL, "sdmmc1_dat4", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD13, 37, "gpmc_ad13", "kpd_col1", "c2c_data10",
-			"gpio_37", NULL, "sdmmc1_dat5", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD14, 38, "gpmc_ad14", "kpd_col2", "c2c_data9",
-			"gpio_38", NULL, "sdmmc1_dat6", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_AD15, 39, "gpmc_ad15", "kpd_col3", "c2c_data8",
-			"gpio_39", NULL, "sdmmc1_dat7", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_A16, 40, "gpmc_a16", "kpd_row4", "c2c_datain0",
-			"gpio_40", "venc_656_data0", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_A24, 48, "gpmc_a24", "kpd_col8", "c2c_clkout0",
-			"gpio_48", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_NCS2, 52, "gpmc_ncs2", "kpd_row8",
-			"c2c_dataout7", "gpio_52", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_CLK, 55, "gpmc_clk", NULL, NULL, "gpio_55",
-			"sys_ndmareq2", "sdmmc1_cmd", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_NADV_ALE, 56, "gpmc_nadv_ale", "dsi1_te1", NULL,
-			"gpio_56", "sys_ndmareq3", "sdmmc1_clk", NULL, NULL),
-	_OMAP4_MUXENTRY(GPMC_WAIT2, 100, "gpmc_wait2", "usbc1_icusb_txen",
-			"c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_NCS4, 101, "gpmc_ncs4", "dsi1_te0", "c2c_clkin0",
-			"gpio_101", "sys_ndmareq1", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_NCS5, 102, "gpmc_ncs5", "dsi1_te1", "c2c_clkin1",
-			"gpio_102", "sys_ndmareq2", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_NCS6, 103, "gpmc_ncs6", "dsi2_te0",
-			"c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(GPMC_NCS7, 104, "gpmc_ncs7", "dsi2_te1",
-			"c2c_dataout1", "gpio_104", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT0, 88, "usbb1_ulpitll_dat0",
-			"hsi1_acwake", "mcbsp4_clkx", "gpio_88",
-			"usbb1_ulpiphy_dat0", "usbb1_mm_txen", "hw_dbg24",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT1, 89, "usbb1_ulpitll_dat1",
-			"hsi1_acdata", "mcbsp4_dx", "gpio_89",
-			"usbb1_ulpiphy_dat1", "usbb1_mm_txdat", "hw_dbg25",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT2, 90, "usbb1_ulpitll_dat2",
-			"hsi1_acflag", "mcbsp4_dr", "gpio_90",
-			"usbb1_ulpiphy_dat2", "usbb1_mm_txse0", "hw_dbg26",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB1_ULPITLL_DAT3, 91, "usbb1_ulpitll_dat3",
-			"hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3",
-			"usbb1_mm_rxrcv", "hw_dbg27", "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_DMIC_CLK1, 119, "abe_dmic_clk1", NULL, NULL,
-			"gpio_119", "usbb2_mm_txse0", "uart4_cts", NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(ABE_DMIC_DIN1, 120, "abe_dmic_din1", NULL, NULL,
-			"gpio_120", "usbb2_mm_txdat", "uart4_rts", NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(ABE_DMIC_DIN2, 121, "abe_dmic_din2", "slimbus2_clock",
-			"abe_mcasp_axr", "gpio_121", NULL,
-			"dmtimer11_pwm_evt", NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(ABE_DMIC_DIN3, 122, "abe_dmic_din3", "slimbus2_data",
-			"abe_dmic_clk2", "gpio_122", NULL, "dmtimer9_pwm_evt",
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_CLK, 145, "sdmmc5_clk", "mcspi2_clk",
-			"usbc1_icusb_dp", "gpio_145", NULL, "sdmmc2_clk",
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_CMD, 146, "sdmmc5_cmd", "mcspi2_simo",
-			"usbc1_icusb_dm", "gpio_146", NULL, "sdmmc2_cmd",
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_DAT0, 147, "sdmmc5_dat0", "mcspi2_somi",
-			"usbc1_icusb_rcv", "gpio_147", NULL, "sdmmc2_dat0",
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_DAT1, 148, "sdmmc5_dat1", NULL,
-			"usbc1_icusb_txen", "gpio_148", NULL, "sdmmc2_dat1",
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_DAT2, 149, "sdmmc5_dat2", "mcspi2_cs1", NULL,
-			"gpio_149", NULL, "sdmmc2_dat2", NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SDMMC5_DAT3, 150, "sdmmc5_dat3", "mcspi2_cs0", NULL,
-			"gpio_150", NULL, "sdmmc2_dat3", NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI4_CLK, 151, "mcspi4_clk", "sdmmc4_clk",
-			"kpd_col6", "gpio_151", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI4_SIMO, 152, "mcspi4_simo", "sdmmc4_cmd",
-			"kpd_col7", "gpio_152", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI4_SOMI, 153, "mcspi4_somi", "sdmmc4_dat0",
-			"kpd_row6", "gpio_153", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(MCSPI4_CS0, 154, "mcspi4_cs0", "sdmmc4_dat3",
-			"kpd_row7", "gpio_154", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(UART4_RX, 155, "uart4_rx", "sdmmc4_dat2", "kpd_row8",
-			"gpio_155", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(UART4_TX, 156, "uart4_tx", "sdmmc4_dat1", "kpd_col8",
-			"gpio_156", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_STP, 158, "usbb2_ulpitll_stp",
-			"usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158",
-			"hsi2_cadata", "dispc2_data23", NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DIR, 159, "usbb2_ulpitll_dir",
-			"usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159",
-			"hsi2_caflag", "dispc2_data22", NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_NXT, 160, "usbb2_ulpitll_nxt",
-			"usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160",
-			"hsi2_acready", "dispc2_data21", NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT0, 161, "usbb2_ulpitll_dat0",
-			"usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161",
-			"hsi2_acwake", "dispc2_data20", "usbb2_mm_txen",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT1, 162, "usbb2_ulpitll_dat1",
-			"usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162",
-			"hsi2_acdata", "dispc2_data19", "usbb2_mm_txdat",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT2, 163, "usbb2_ulpitll_dat2",
-			"usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163",
-			"hsi2_acflag", "dispc2_data18", "usbb2_mm_txse0",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT3, 164, "usbb2_ulpitll_dat3",
-			"usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164",
-			"hsi2_caready", "dispc2_data15", "rfbi_data15",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT4, 165, "usbb2_ulpitll_dat4",
-			"usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165",
-			"mcspi3_somi", "dispc2_data14", "rfbi_data14",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT5, 166, "usbb2_ulpitll_dat5",
-			"usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166",
-			"mcspi3_cs0", "dispc2_data13", "rfbi_data13",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT6, 167, "usbb2_ulpitll_dat6",
-			"usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167",
-			"mcspi3_simo", "dispc2_data12", "rfbi_data12",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(USBB2_ULPITLL_DAT7, 168, "usbb2_ulpitll_dat7",
-			"usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168",
-			"mcspi3_clk", "dispc2_data11", "rfbi_data11",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(KPD_COL3, 171, "kpd_col3", "kpd_col0", NULL,
-			"gpio_171", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_COL4, 172, "kpd_col4", "kpd_col1", NULL,
-			"gpio_172", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_COL5, 173, "kpd_col5", "kpd_col2", NULL,
-			"gpio_173", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_COL0, 174, "kpd_col0", "kpd_col3", NULL,
-			"gpio_174", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_COL1, 0, "kpd_col1", "kpd_col4", NULL, "gpio_0",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_COL2, 1, "kpd_col2", "kpd_col5", NULL, "gpio_1",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_ROW3, 175, "kpd_row3", "kpd_row0", NULL,
-			"gpio_175", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_ROW4, 176, "kpd_row4", "kpd_row1", NULL,
-			"gpio_176", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_ROW5, 177, "kpd_row5", "kpd_row2", NULL,
-			"gpio_177", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_ROW0, 178, "kpd_row0", "kpd_row3", NULL,
-			"gpio_178", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_ROW1, 2, "kpd_row1", "kpd_row4", NULL, "gpio_2",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(KPD_ROW2, 3, "kpd_row2", "kpd_row5", NULL, "gpio_3",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBA0_OTG_DP, 0, "usba0_otg_dp", "uart3_rx_irrx",
-			"uart2_rx", NULL, NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(USBA0_OTG_DM, 0, "usba0_otg_dm", "uart3_tx_irtx",
-			"uart2_tx", NULL, NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU2, 13, "dpm_emu2", "usba0_ulpiphy_clk", NULL,
-			"gpio_13", NULL, "dispc2_fid", "hw_dbg2",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU3, 14, "dpm_emu3", "usba0_ulpiphy_stp", NULL,
-			"gpio_14", "rfbi_data10", "dispc2_data10", "hw_dbg3",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU4, 15, "dpm_emu4", "usba0_ulpiphy_dir", NULL,
-			"gpio_15", "rfbi_data9", "dispc2_data9", "hw_dbg4",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU5, 16, "dpm_emu5", "usba0_ulpiphy_nxt", NULL,
-			"gpio_16", "rfbi_te_vsync0", "dispc2_data16",
-			"hw_dbg5", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU6, 17, "dpm_emu6", "usba0_ulpiphy_dat0",
-			"uart3_tx_irtx", "gpio_17", "rfbi_hsync0",
-			"dispc2_data17", "hw_dbg6", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU7, 18, "dpm_emu7", "usba0_ulpiphy_dat1",
-			"uart3_rx_irrx", "gpio_18", "rfbi_cs0",
-			"dispc2_hsync", "hw_dbg7", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU8, 19, "dpm_emu8", "usba0_ulpiphy_dat2",
-			"uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk",
-			"hw_dbg8", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU9, 20, "dpm_emu9", "usba0_ulpiphy_dat3",
-			"uart3_cts_rctx", "gpio_20", "rfbi_we",
-			"dispc2_vsync", "hw_dbg9", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU10, 21, "dpm_emu10", "usba0_ulpiphy_dat4",
-			NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10",
-			"safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU11, 22, "dpm_emu11", "usba0_ulpiphy_dat5",
-			NULL, "gpio_22", "rfbi_data8", "dispc2_data8",
-			"hw_dbg11", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU12, 23, "dpm_emu12", "usba0_ulpiphy_dat6",
-			NULL, "gpio_23", "rfbi_data7", "dispc2_data7",
-			"hw_dbg12", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU13, 24, "dpm_emu13", "usba0_ulpiphy_dat7",
-			NULL, "gpio_24", "rfbi_data6", "dispc2_data6",
-			"hw_dbg13", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU14, 25, "dpm_emu14", "sys_drm_msecure",
-			"uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5",
-			"hw_dbg14", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU15, 26, "dpm_emu15", "sys_secure_indicator",
-			NULL, "gpio_26", "rfbi_data4", "dispc2_data4",
-			"hw_dbg15", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU16, 27, "dpm_emu16", "dmtimer8_pwm_evt",
-			"dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3",
-			"hw_dbg16", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU17, 28, "dpm_emu17", "dmtimer9_pwm_evt",
-			"dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2",
-			"hw_dbg17", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU18, 190, "dpm_emu18", "dmtimer10_pwm_evt",
-			"dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1",
-			"hw_dbg18", "safe_mode"),
-	_OMAP4_MUXENTRY(DPM_EMU19, 191, "dpm_emu19", "dmtimer11_pwm_evt",
-			"dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0",
-			"hw_dbg19", "safe_mode"),
-	{ .reg_offset = OMAP_MUX_TERMINATOR },
-};
-
-/*
- * Balls for 44XX CBS package
- * 547-pin CBL ES2.0 S-FPGA-N547, 0.40mm Ball Pitch (Top),
- *				  0.40mm Ball Pitch (Bottom)
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)		\
-		&& defined(CONFIG_OMAP_PACKAGE_CBS)
-static struct omap_ball __initdata omap4_core_cbs_ball[] = {
-	_OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD3, "d13", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD4, "c15", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD5, "d15", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD6, "a16", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD7, "b16", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD8, "c16", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD9, "d16", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD10, "c17", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD11, "d17", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD12, "c18", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD13, "d18", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD14, "c19", NULL),
-	_OMAP4_BALLENTRY(GPMC_AD15, "d19", NULL),
-	_OMAP4_BALLENTRY(GPMC_A16, "b17", NULL),
-	_OMAP4_BALLENTRY(GPMC_A17, "a18", NULL),
-	_OMAP4_BALLENTRY(GPMC_A18, "b18", NULL),
-	_OMAP4_BALLENTRY(GPMC_A19, "a19", NULL),
-	_OMAP4_BALLENTRY(GPMC_A20, "b19", NULL),
-	_OMAP4_BALLENTRY(GPMC_A21, "b20", NULL),
-	_OMAP4_BALLENTRY(GPMC_A22, "a21", NULL),
-	_OMAP4_BALLENTRY(GPMC_A23, "b21", NULL),
-	_OMAP4_BALLENTRY(GPMC_A24, "c20", NULL),
-	_OMAP4_BALLENTRY(GPMC_A25, "d20", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS0, "b25", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS1, "c21", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS2, "d21", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS3, "c22", NULL),
-	_OMAP4_BALLENTRY(GPMC_NWP, "c25", NULL),
-	_OMAP4_BALLENTRY(GPMC_CLK, "b22", NULL),
-	_OMAP4_BALLENTRY(GPMC_NADV_ALE, "d25", NULL),
-	_OMAP4_BALLENTRY(GPMC_NOE, "b11", NULL),
-	_OMAP4_BALLENTRY(GPMC_NWE, "b12", NULL),
-	_OMAP4_BALLENTRY(GPMC_NBE0_CLE, "c23", NULL),
-	_OMAP4_BALLENTRY(GPMC_NBE1, "d22", NULL),
-	_OMAP4_BALLENTRY(GPMC_WAIT0, "b26", NULL),
-	_OMAP4_BALLENTRY(GPMC_WAIT1, "b23", NULL),
-	_OMAP4_BALLENTRY(GPMC_WAIT2, "d23", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS4, "a24", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS5, "b24", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS6, "c24", NULL),
-	_OMAP4_BALLENTRY(GPMC_NCS7, "d24", NULL),
-	_OMAP4_BALLENTRY(HDMI_HPD, "b9", NULL),
-	_OMAP4_BALLENTRY(HDMI_CEC, "b10", NULL),
-	_OMAP4_BALLENTRY(HDMI_DDC_SCL, "a8", NULL),
-	_OMAP4_BALLENTRY(HDMI_DDC_SDA, "b8", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX0, "r26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY0, "r25", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX1, "t26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY1, "t25", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX2, "u26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY2, "u25", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX3, "v26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY3, "v25", NULL),
-	_OMAP4_BALLENTRY(CSI21_DX4, "w26", NULL),
-	_OMAP4_BALLENTRY(CSI21_DY4, "w25", NULL),
-	_OMAP4_BALLENTRY(CSI22_DX0, "m26", NULL),
-	_OMAP4_BALLENTRY(CSI22_DY0, "m25", NULL),
-	_OMAP4_BALLENTRY(CSI22_DX1, "n26", NULL),
-	_OMAP4_BALLENTRY(CSI22_DY1, "n25", NULL),
-	_OMAP4_BALLENTRY(CAM_SHUTTER, "t27", NULL),
-	_OMAP4_BALLENTRY(CAM_STROBE, "u27", NULL),
-	_OMAP4_BALLENTRY(CAM_GLOBALRESET, "v27", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_CLK, "ae18", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_STP, "ag19", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DIR, "af19", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_NXT, "ae19", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT0, "af18", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT1, "ag18", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT2, "ae17", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT3, "af17", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT4, "ah17", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT5, "ae16", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT6, "af16", NULL),
-	_OMAP4_BALLENTRY(USBB1_ULPITLL_DAT7, "ag16", NULL),
-	_OMAP4_BALLENTRY(USBB1_HSIC_DATA, "af14", NULL),
-	_OMAP4_BALLENTRY(USBB1_HSIC_STROBE, "ae14", NULL),
-	_OMAP4_BALLENTRY(USBC1_ICUSB_DP, "h2", NULL),
-	_OMAP4_BALLENTRY(USBC1_ICUSB_DM, "h3", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_CLK, "d2", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_CMD, "e3", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT0, "e4", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT1, "e2", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT2, "e1", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT3, "f4", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT4, "f3", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT5, "f1", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT6, "g4", NULL),
-	_OMAP4_BALLENTRY(SDMMC1_DAT7, "g3", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP2_CLKX, "ad27", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP2_DR, "ad26", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP2_DX, "ad25", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP2_FSX, "ac28", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP1_CLKX, "ac26", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP1_DR, "ac25", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP1_DX, "ab25", NULL),
-	_OMAP4_BALLENTRY(ABE_MCBSP1_FSX, "ac27", NULL),
-	_OMAP4_BALLENTRY(ABE_PDM_UL_DATA, "ag25", NULL),
-	_OMAP4_BALLENTRY(ABE_PDM_DL_DATA, "af25", NULL),
-	_OMAP4_BALLENTRY(ABE_PDM_FRAME, "ae25", NULL),
-	_OMAP4_BALLENTRY(ABE_PDM_LB_CLK, "af26", NULL),
-	_OMAP4_BALLENTRY(ABE_CLKS, "ah26", NULL),
-	_OMAP4_BALLENTRY(ABE_DMIC_CLK1, "ae24", NULL),
-	_OMAP4_BALLENTRY(ABE_DMIC_DIN1, "af24", NULL),
-	_OMAP4_BALLENTRY(ABE_DMIC_DIN2, "ag24", NULL),
-	_OMAP4_BALLENTRY(ABE_DMIC_DIN3, "ah24", NULL),
-	_OMAP4_BALLENTRY(UART2_CTS, "ab26", NULL),
-	_OMAP4_BALLENTRY(UART2_RTS, "ab27", NULL),
-	_OMAP4_BALLENTRY(UART2_RX, "aa25", NULL),
-	_OMAP4_BALLENTRY(UART2_TX, "aa26", NULL),
-	_OMAP4_BALLENTRY(HDQ_SIO, "aa27", NULL),
-	_OMAP4_BALLENTRY(I2C1_SCL, "ae28", NULL),
-	_OMAP4_BALLENTRY(I2C1_SDA, "ae26", NULL),
-	_OMAP4_BALLENTRY(I2C2_SCL, "c26", NULL),
-	_OMAP4_BALLENTRY(I2C2_SDA, "d26", NULL),
-	_OMAP4_BALLENTRY(I2C3_SCL, "w27", NULL),
-	_OMAP4_BALLENTRY(I2C3_SDA, "y27", NULL),
-	_OMAP4_BALLENTRY(I2C4_SCL, "ag21", NULL),
-	_OMAP4_BALLENTRY(I2C4_SDA, "ah22", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CLK, "af22", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_SOMI, "ae22", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_SIMO, "ag22", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CS0, "ae23", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CS1, "af23", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CS2, "ag23", NULL),
-	_OMAP4_BALLENTRY(MCSPI1_CS3, "ah23", NULL),
-	_OMAP4_BALLENTRY(UART3_CTS_RCTX, "f27", NULL),
-	_OMAP4_BALLENTRY(UART3_RTS_SD, "f28", NULL),
-	_OMAP4_BALLENTRY(UART3_RX_IRRX, "g27", NULL),
-	_OMAP4_BALLENTRY(UART3_TX_IRTX, "g28", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_CLK, "ae5", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_CMD, "af5", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_DAT0, "ae4", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_DAT1, "af4", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_DAT2, "ag3", NULL),
-	_OMAP4_BALLENTRY(SDMMC5_DAT3, "af3", NULL),
-	_OMAP4_BALLENTRY(MCSPI4_CLK, "ae21", NULL),
-	_OMAP4_BALLENTRY(MCSPI4_SIMO, "af20", NULL),
-	_OMAP4_BALLENTRY(MCSPI4_SOMI, "af21", NULL),
-	_OMAP4_BALLENTRY(MCSPI4_CS0, "ae20", NULL),
-	_OMAP4_BALLENTRY(UART4_RX, "ag20", NULL),
-	_OMAP4_BALLENTRY(UART4_TX, "ah19", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_CLK, "ag12", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_STP, "af12", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DIR, "ae12", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_NXT, "ag13", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT0, "ae11", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT1, "af11", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT2, "ag11", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT3, "ah11", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT4, "ae10", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT5, "af10", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT6, "ag10", NULL),
-	_OMAP4_BALLENTRY(USBB2_ULPITLL_DAT7, "ae9", NULL),
-	_OMAP4_BALLENTRY(USBB2_HSIC_DATA, "af13", NULL),
-	_OMAP4_BALLENTRY(USBB2_HSIC_STROBE, "ae13", NULL),
-	_OMAP4_BALLENTRY(KPD_COL3, "g26", NULL),
-	_OMAP4_BALLENTRY(KPD_COL4, "g25", NULL),
-	_OMAP4_BALLENTRY(KPD_COL5, "h26", NULL),
-	_OMAP4_BALLENTRY(KPD_COL0, "h25", NULL),
-	_OMAP4_BALLENTRY(KPD_COL1, "j27", NULL),
-	_OMAP4_BALLENTRY(KPD_COL2, "h27", NULL),
-	_OMAP4_BALLENTRY(KPD_ROW3, "j26", NULL),
-	_OMAP4_BALLENTRY(KPD_ROW4, "j25", NULL),
-	_OMAP4_BALLENTRY(KPD_ROW5, "k26", NULL),
-	_OMAP4_BALLENTRY(KPD_ROW0, "k25", NULL),
-	_OMAP4_BALLENTRY(KPD_ROW1, "l27", NULL),
-	_OMAP4_BALLENTRY(KPD_ROW2, "k27", NULL),
-	_OMAP4_BALLENTRY(USBA0_OTG_CE, "c3", NULL),
-	_OMAP4_BALLENTRY(USBA0_OTG_DP, "b5", NULL),
-	_OMAP4_BALLENTRY(USBA0_OTG_DM, "b4", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK1_OUT, "aa28", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK2_OUT, "y28", NULL),
-	_OMAP4_BALLENTRY(SYS_NIRQ1, "ae6", NULL),
-	_OMAP4_BALLENTRY(SYS_NIRQ2, "af6", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT0, "f26", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT1, "e27", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT2, "e26", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT3, "e25", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT4, "d28", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT5, "d27", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU0, "m2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU1, "n2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU2, "p2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU3, "v1", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU4, "v2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU5, "w1", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU6, "w2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU7, "w3", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU8, "w4", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU9, "y2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU10, "y3", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU11, "y4", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU12, "aa1", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU13, "aa2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU14, "aa3", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU15, "aa4", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU16, "ab2", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU17, "ab3", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU18, "ab4", NULL),
-	_OMAP4_BALLENTRY(DPM_EMU19, "ac4", NULL),
-	{ .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap4_core_cbs_ball  NULL
-#endif
-
-/*
- * Superset of all mux modes for omap4
- */
-static struct omap_mux __initdata omap4_wkup_muxmodes[] = {
-	_OMAP4_MUXENTRY(SIM_IO, 0, "sim_io", NULL, NULL, "gpio_wk0", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SIM_CLK, 1, "sim_clk", NULL, NULL, "gpio_wk1", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SIM_RESET, 2, "sim_reset", NULL, NULL, "gpio_wk2",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SIM_CD, 3, "sim_cd", NULL, NULL, "gpio_wk3", NULL,
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SIM_PWRCTRL, 4, "sim_pwrctrl", NULL, NULL, "gpio_wk4",
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(SR_SCL, 0, "sr_scl", NULL, NULL, NULL, NULL, NULL,
-			NULL, NULL),
-	_OMAP4_MUXENTRY(SR_SDA, 0, "sr_sda", NULL, NULL, NULL, NULL, NULL,
-			NULL, NULL),
-	_OMAP4_MUXENTRY(FREF_XTAL_IN, 0, "fref_xtal_in", NULL, NULL, NULL,
-			"c2c_wakereqin", NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(FREF_SLICER_IN, 0, "fref_slicer_in", NULL, NULL,
-			"gpi_wk5", "c2c_wakereqin", NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(FREF_CLK_IOREQ, 0, "fref_clk_ioreq", NULL, NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(FREF_CLK0_OUT, 6, "fref_clk0_out", "fref_clk1_req",
-			"sys_drm_msecure", "gpio_wk6", NULL, NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(FREF_CLK3_REQ, 30, "fref_clk3_req", "fref_clk1_req",
-			"sys_drm_msecure", "gpio_wk30", "c2c_wakereqin", NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(FREF_CLK3_OUT, 31, "fref_clk3_out", "fref_clk2_req",
-			"sys_secure_indicator", "gpio_wk31", "c2c_wakereqout",
-			NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(FREF_CLK4_REQ, 7, "fref_clk4_req", "fref_clk5_out",
-			NULL, "gpio_wk7", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(FREF_CLK4_OUT, 8, "fref_clk4_out", NULL, NULL,
-			"gpio_wk8", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(SYS_32K, 0, "sys_32k", NULL, NULL, NULL, NULL, NULL,
-			NULL, NULL),
-	_OMAP4_MUXENTRY(SYS_NRESPWRON, 0, "sys_nrespwron", NULL, NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(SYS_NRESWARM, 0, "sys_nreswarm", NULL, NULL, NULL,
-			NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(SYS_PWR_REQ, 0, "sys_pwr_req", NULL, NULL, NULL, NULL,
-			NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(SYS_PWRON_RESET_OUT, 29, "sys_pwron_reset_out", NULL,
-			NULL, "gpio_wk29", NULL, NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(SYS_BOOT6, 9, "sys_boot6", "dpm_emu18", NULL,
-			"gpio_wk9", "c2c_wakereqout", NULL, NULL,
-			"safe_mode"),
-	_OMAP4_MUXENTRY(SYS_BOOT7, 10, "sys_boot7", "dpm_emu19", NULL,
-			"gpio_wk10", NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(JTAG_NTRST, 0, "jtag_ntrst", NULL, NULL, NULL, NULL,
-			NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(JTAG_TCK, 0, "jtag_tck", NULL, NULL, NULL, NULL, NULL,
-			NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(JTAG_RTCK, 0, "jtag_rtck", NULL, NULL, NULL, NULL,
-			NULL, NULL, NULL),
-	_OMAP4_MUXENTRY(JTAG_TMS_TMSC, 0, "jtag_tms_tmsc", NULL, NULL, NULL,
-			NULL, NULL, NULL, "safe_mode"),
-	_OMAP4_MUXENTRY(JTAG_TDI, 0, "jtag_tdi", NULL, NULL, NULL, NULL, NULL,
-			NULL, NULL),
-	_OMAP4_MUXENTRY(JTAG_TDO, 0, "jtag_tdo", NULL, NULL, NULL, NULL, NULL,
-			NULL, NULL),
-	{ .reg_offset = OMAP_MUX_TERMINATOR },
-};
-
-/*
- * Balls for 44XX CBL & CBS package - wakeup partition
- * 547-pin CBL ES1.0 S-FPGA-N547, 0.40mm Ball Pitch (Top),
- *				  0.40mm Ball Pitch (Bottom)
- */
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)		\
-		&& defined(CONFIG_OMAP_PACKAGE_CBL)
-static struct omap_ball __initdata omap4_wkup_cbl_cbs_ball[] = {
-	_OMAP4_BALLENTRY(SIM_IO, "h4", NULL),
-	_OMAP4_BALLENTRY(SIM_CLK, "j2", NULL),
-	_OMAP4_BALLENTRY(SIM_RESET, "g2", NULL),
-	_OMAP4_BALLENTRY(SIM_CD, "j1", NULL),
-	_OMAP4_BALLENTRY(SIM_PWRCTRL, "k1", NULL),
-	_OMAP4_BALLENTRY(SR_SCL, "ag9", NULL),
-	_OMAP4_BALLENTRY(SR_SDA, "af9", NULL),
-	_OMAP4_BALLENTRY(FREF_XTAL_IN, "ah6", NULL),
-	_OMAP4_BALLENTRY(FREF_SLICER_IN, "ag8", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK_IOREQ, "ad1", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK0_OUT, "ad2", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK3_REQ, "ad3", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK3_OUT, "ad4", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK4_REQ, "ac2", NULL),
-	_OMAP4_BALLENTRY(FREF_CLK4_OUT, "ac3", NULL),
-	_OMAP4_BALLENTRY(SYS_32K, "ag7", NULL),
-	_OMAP4_BALLENTRY(SYS_NRESPWRON, "ae7", NULL),
-	_OMAP4_BALLENTRY(SYS_NRESWARM, "af7", NULL),
-	_OMAP4_BALLENTRY(SYS_PWR_REQ, "ah7", NULL),
-	_OMAP4_BALLENTRY(SYS_PWRON_RESET_OUT, "ag6", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT6, "af8", NULL),
-	_OMAP4_BALLENTRY(SYS_BOOT7, "ae8", NULL),
-	_OMAP4_BALLENTRY(JTAG_NTRST, "ah2", NULL),
-	_OMAP4_BALLENTRY(JTAG_TCK, "ag1", NULL),
-	_OMAP4_BALLENTRY(JTAG_RTCK, "ae3", NULL),
-	_OMAP4_BALLENTRY(JTAG_TMS_TMSC, "ah1", NULL),
-	_OMAP4_BALLENTRY(JTAG_TDI, "ae1", NULL),
-	_OMAP4_BALLENTRY(JTAG_TDO, "ae2", NULL),
-	{ .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#else
-#define omap4_wkup_cbl_cbs_ball  NULL
-#endif
-
-int __init omap4_mux_init(struct omap_board_mux *board_subset,
-	struct omap_board_mux *board_wkup_subset, int flags)
-{
-	struct omap_ball *package_balls_core;
-	struct omap_ball *package_balls_wkup = omap4_wkup_cbl_cbs_ball;
-	struct omap_mux *core_muxmodes;
-	struct omap_mux *core_subset = NULL;
-	int ret;
-
-	switch (flags & OMAP_PACKAGE_MASK) {
-	case OMAP_PACKAGE_CBL:
-		pr_debug("%s: OMAP4430 ES1.0 -> OMAP_PACKAGE_CBL\n", __func__);
-		package_balls_core = omap4_core_cbl_ball;
-		core_muxmodes = omap4_core_muxmodes;
-		break;
-	case OMAP_PACKAGE_CBS:
-		pr_debug("%s: OMAP4430 ES2.X -> OMAP_PACKAGE_CBS\n", __func__);
-		package_balls_core = omap4_core_cbs_ball;
-		core_muxmodes = omap4_core_muxmodes;
-		core_subset = omap4_es2_core_subset;
-		break;
-	default:
-		pr_err("%s: Unknown omap package, mux disabled\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = omap_mux_init("core",
-			    OMAP_MUX_GPIO_IN_MODE3,
-			    OMAP4_CTRL_MODULE_PAD_CORE_MUX_PBASE,
-			    OMAP4_CTRL_MODULE_PAD_CORE_MUX_SIZE,
-			    core_muxmodes, core_subset, board_subset,
-			    package_balls_core);
-	if (ret)
-		return ret;
-
-	ret = omap_mux_init("wkup",
-			    OMAP_MUX_GPIO_IN_MODE3,
-			    OMAP4_CTRL_MODULE_PAD_WKUP_MUX_PBASE,
-			    OMAP4_CTRL_MODULE_PAD_WKUP_MUX_SIZE,
-			    omap4_wkup_muxmodes, NULL, board_wkup_subset,
-			    package_balls_wkup);
-
-	return ret;
-}
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/mux44xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/mux44xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/mux44xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/mux44xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,298 +0,0 @@
-/*
- * OMAP44xx MUX registers and bitfields
- *
- * Copyright (C) 2009-2010 Texas Instruments, Inc.
- *
- * Benoit Cousson (b-cousson@ti.com)
- *
- * This file is automatically generated from the OMAP hardware databases.
- * We respectfully ask that any modifications to this file be coordinated
- * with the public linux-omap@vger.kernel.org mailing list and the
- * authors above to ensure that the autogeneration scripts are kept
- * up-to-date with the file contents.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ARCH_ARM_MACH_OMAP2_MUX_44XX_H
-#define __ARCH_ARM_MACH_OMAP2_MUX_44XX_H
-
-#define OMAP4_MUX(M0, mux_value)					\
-{									\
-	.reg_offset	= (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET),	\
-	.value		= (mux_value),					\
-}
-
-/* ctrl_module_pad_core base address */
-#define OMAP4_CTRL_MODULE_PAD_CORE_MUX_PBASE			0x4a100000
-
-/* ctrl_module_pad_core registers offset */
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD0_OFFSET			0x0040
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD1_OFFSET			0x0042
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD2_OFFSET			0x0044
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD3_OFFSET			0x0046
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD4_OFFSET			0x0048
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD5_OFFSET			0x004a
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD6_OFFSET			0x004c
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD7_OFFSET			0x004e
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD8_OFFSET			0x0050
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD9_OFFSET			0x0052
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD10_OFFSET			0x0054
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD11_OFFSET			0x0056
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD12_OFFSET			0x0058
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD13_OFFSET			0x005a
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD14_OFFSET			0x005c
-#define OMAP4_CTRL_MODULE_PAD_GPMC_AD15_OFFSET			0x005e
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A16_OFFSET			0x0060
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A17_OFFSET			0x0062
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A18_OFFSET			0x0064
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A19_OFFSET			0x0066
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A20_OFFSET			0x0068
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A21_OFFSET			0x006a
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A22_OFFSET			0x006c
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A23_OFFSET			0x006e
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A24_OFFSET			0x0070
-#define OMAP4_CTRL_MODULE_PAD_GPMC_A25_OFFSET			0x0072
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS0_OFFSET			0x0074
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS1_OFFSET			0x0076
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS2_OFFSET			0x0078
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS3_OFFSET			0x007a
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NWP_OFFSET			0x007c
-#define OMAP4_CTRL_MODULE_PAD_GPMC_CLK_OFFSET			0x007e
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NADV_ALE_OFFSET		0x0080
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NOE_OFFSET			0x0082
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NWE_OFFSET			0x0084
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NBE0_CLE_OFFSET		0x0086
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NBE1_OFFSET			0x0088
-#define OMAP4_CTRL_MODULE_PAD_GPMC_WAIT0_OFFSET			0x008a
-#define OMAP4_CTRL_MODULE_PAD_GPMC_WAIT1_OFFSET			0x008c
-#define OMAP4_CTRL_MODULE_PAD_C2C_DATA11_OFFSET			0x008e
-#define OMAP4_CTRL_MODULE_PAD_C2C_DATA12_OFFSET			0x0090
-#define OMAP4_CTRL_MODULE_PAD_C2C_DATA13_OFFSET			0x0092
-#define OMAP4_CTRL_MODULE_PAD_C2C_DATA14_OFFSET			0x0094
-#define OMAP4_CTRL_MODULE_PAD_C2C_DATA15_OFFSET			0x0096
-#define OMAP4_CTRL_MODULE_PAD_HDMI_HPD_OFFSET			0x0098
-#define OMAP4_CTRL_MODULE_PAD_HDMI_CEC_OFFSET			0x009a
-#define OMAP4_CTRL_MODULE_PAD_HDMI_DDC_SCL_OFFSET		0x009c
-#define OMAP4_CTRL_MODULE_PAD_HDMI_DDC_SDA_OFFSET		0x009e
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DX0_OFFSET			0x00a0
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DY0_OFFSET			0x00a2
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DX1_OFFSET			0x00a4
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DY1_OFFSET			0x00a6
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DX2_OFFSET			0x00a8
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DY2_OFFSET			0x00aa
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DX3_OFFSET			0x00ac
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DY3_OFFSET			0x00ae
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DX4_OFFSET			0x00b0
-#define OMAP4_CTRL_MODULE_PAD_CSI21_DY4_OFFSET			0x00b2
-#define OMAP4_CTRL_MODULE_PAD_CSI22_DX0_OFFSET			0x00b4
-#define OMAP4_CTRL_MODULE_PAD_CSI22_DY0_OFFSET			0x00b6
-#define OMAP4_CTRL_MODULE_PAD_CSI22_DX1_OFFSET			0x00b8
-#define OMAP4_CTRL_MODULE_PAD_CSI22_DY1_OFFSET			0x00ba
-#define OMAP4_CTRL_MODULE_PAD_CAM_SHUTTER_OFFSET		0x00bc
-#define OMAP4_CTRL_MODULE_PAD_CAM_STROBE_OFFSET			0x00be
-#define OMAP4_CTRL_MODULE_PAD_CAM_GLOBALRESET_OFFSET		0x00c0
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_CLK_OFFSET		0x00c2
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_STP_OFFSET		0x00c4
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DIR_OFFSET		0x00c6
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_NXT_OFFSET		0x00c8
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT0_OFFSET		0x00ca
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT1_OFFSET		0x00cc
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT2_OFFSET		0x00ce
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT3_OFFSET		0x00d0
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT4_OFFSET		0x00d2
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT5_OFFSET		0x00d4
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT6_OFFSET		0x00d6
-#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT7_OFFSET		0x00d8
-#define OMAP4_CTRL_MODULE_PAD_USBB1_HSIC_DATA_OFFSET		0x00da
-#define OMAP4_CTRL_MODULE_PAD_USBB1_HSIC_STROBE_OFFSET		0x00dc
-#define OMAP4_CTRL_MODULE_PAD_USBC1_ICUSB_DP_OFFSET		0x00de
-#define OMAP4_CTRL_MODULE_PAD_USBC1_ICUSB_DM_OFFSET		0x00e0
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_CLK_OFFSET			0x00e2
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_CMD_OFFSET			0x00e4
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT0_OFFSET		0x00e6
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT1_OFFSET		0x00e8
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT2_OFFSET		0x00ea
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT3_OFFSET		0x00ec
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT4_OFFSET		0x00ee
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT5_OFFSET		0x00f0
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT6_OFFSET		0x00f2
-#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT7_OFFSET		0x00f4
-#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_CLKX_OFFSET		0x00f6
-#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_DR_OFFSET		0x00f8
-#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_DX_OFFSET		0x00fa
-#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_FSX_OFFSET		0x00fc
-#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_CLKX_OFFSET		0x00fe
-#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_DR_OFFSET		0x0100
-#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_DX_OFFSET		0x0102
-#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_FSX_OFFSET		0x0104
-#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_UL_DATA_OFFSET		0x0106
-#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_DL_DATA_OFFSET		0x0108
-#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_FRAME_OFFSET		0x010a
-#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_LB_CLK_OFFSET		0x010c
-#define OMAP4_CTRL_MODULE_PAD_ABE_CLKS_OFFSET			0x010e
-#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_CLK1_OFFSET		0x0110
-#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_DIN1_OFFSET		0x0112
-#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_DIN2_OFFSET		0x0114
-#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_DIN3_OFFSET		0x0116
-#define OMAP4_CTRL_MODULE_PAD_UART2_CTS_OFFSET			0x0118
-#define OMAP4_CTRL_MODULE_PAD_UART2_RTS_OFFSET			0x011a
-#define OMAP4_CTRL_MODULE_PAD_UART2_RX_OFFSET			0x011c
-#define OMAP4_CTRL_MODULE_PAD_UART2_TX_OFFSET			0x011e
-#define OMAP4_CTRL_MODULE_PAD_HDQ_SIO_OFFSET			0x0120
-#define OMAP4_CTRL_MODULE_PAD_I2C1_SCL_OFFSET			0x0122
-#define OMAP4_CTRL_MODULE_PAD_I2C1_SDA_OFFSET			0x0124
-#define OMAP4_CTRL_MODULE_PAD_I2C2_SCL_OFFSET			0x0126
-#define OMAP4_CTRL_MODULE_PAD_I2C2_SDA_OFFSET			0x0128
-#define OMAP4_CTRL_MODULE_PAD_I2C3_SCL_OFFSET			0x012a
-#define OMAP4_CTRL_MODULE_PAD_I2C3_SDA_OFFSET			0x012c
-#define OMAP4_CTRL_MODULE_PAD_I2C4_SCL_OFFSET			0x012e
-#define OMAP4_CTRL_MODULE_PAD_I2C4_SDA_OFFSET			0x0130
-#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CLK_OFFSET			0x0132
-#define OMAP4_CTRL_MODULE_PAD_MCSPI1_SOMI_OFFSET		0x0134
-#define OMAP4_CTRL_MODULE_PAD_MCSPI1_SIMO_OFFSET		0x0136
-#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS0_OFFSET			0x0138
-#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS1_OFFSET			0x013a
-#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS2_OFFSET			0x013c
-#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS3_OFFSET			0x013e
-#define OMAP4_CTRL_MODULE_PAD_UART3_CTS_RCTX_OFFSET		0x0140
-#define OMAP4_CTRL_MODULE_PAD_UART3_RTS_SD_OFFSET		0x0142
-#define OMAP4_CTRL_MODULE_PAD_UART3_RX_IRRX_OFFSET		0x0144
-#define OMAP4_CTRL_MODULE_PAD_UART3_TX_IRTX_OFFSET		0x0146
-#define OMAP4_CTRL_MODULE_PAD_SDMMC5_CLK_OFFSET			0x0148
-#define OMAP4_CTRL_MODULE_PAD_SDMMC5_CMD_OFFSET			0x014a
-#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT0_OFFSET		0x014c
-#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT1_OFFSET		0x014e
-#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT2_OFFSET		0x0150
-#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT3_OFFSET		0x0152
-#define OMAP4_CTRL_MODULE_PAD_MCSPI4_CLK_OFFSET			0x0154
-#define OMAP4_CTRL_MODULE_PAD_MCSPI4_SIMO_OFFSET		0x0156
-#define OMAP4_CTRL_MODULE_PAD_MCSPI4_SOMI_OFFSET		0x0158
-#define OMAP4_CTRL_MODULE_PAD_MCSPI4_CS0_OFFSET			0x015a
-#define OMAP4_CTRL_MODULE_PAD_UART4_RX_OFFSET			0x015c
-#define OMAP4_CTRL_MODULE_PAD_UART4_TX_OFFSET			0x015e
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_CLK_OFFSET		0x0160
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_STP_OFFSET		0x0162
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DIR_OFFSET		0x0164
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_NXT_OFFSET		0x0166
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT0_OFFSET		0x0168
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT1_OFFSET		0x016a
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT2_OFFSET		0x016c
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT3_OFFSET		0x016e
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT4_OFFSET		0x0170
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT5_OFFSET		0x0172
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT6_OFFSET		0x0174
-#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT7_OFFSET		0x0176
-#define OMAP4_CTRL_MODULE_PAD_USBB2_HSIC_DATA_OFFSET		0x0178
-#define OMAP4_CTRL_MODULE_PAD_USBB2_HSIC_STROBE_OFFSET		0x017a
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TX0_OFFSET			0x017c
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TY0_OFFSET			0x017e
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TX1_OFFSET			0x0180
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TY1_OFFSET			0x0182
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TX2_OFFSET			0x0184
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TY2_OFFSET			0x0186
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RX0_OFFSET			0x0188
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RY0_OFFSET			0x018a
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RX1_OFFSET			0x018c
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RY1_OFFSET			0x018e
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RX2_OFFSET			0x0190
-#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RY2_OFFSET			0x0192
-#define OMAP4_CTRL_MODULE_PAD_USBA0_OTG_CE_OFFSET		0x0194
-#define OMAP4_CTRL_MODULE_PAD_USBA0_OTG_DP_OFFSET		0x0196
-#define OMAP4_CTRL_MODULE_PAD_USBA0_OTG_DM_OFFSET		0x0198
-#define OMAP4_CTRL_MODULE_PAD_FREF_CLK1_OUT_OFFSET		0x019a
-#define OMAP4_CTRL_MODULE_PAD_FREF_CLK2_OUT_OFFSET		0x019c
-#define OMAP4_CTRL_MODULE_PAD_SYS_NIRQ1_OFFSET			0x019e
-#define OMAP4_CTRL_MODULE_PAD_SYS_NIRQ2_OFFSET			0x01a0
-#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT0_OFFSET			0x01a2
-#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT1_OFFSET			0x01a4
-#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT2_OFFSET			0x01a6
-#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT3_OFFSET			0x01a8
-#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT4_OFFSET			0x01aa
-#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT5_OFFSET			0x01ac
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU0_OFFSET			0x01ae
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU1_OFFSET			0x01b0
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU2_OFFSET			0x01b2
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU3_OFFSET			0x01b4
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU4_OFFSET			0x01b6
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU5_OFFSET			0x01b8
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU6_OFFSET			0x01ba
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU7_OFFSET			0x01bc
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU8_OFFSET			0x01be
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU9_OFFSET			0x01c0
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU10_OFFSET			0x01c2
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU11_OFFSET			0x01c4
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU12_OFFSET			0x01c6
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU13_OFFSET			0x01c8
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU14_OFFSET			0x01ca
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU15_OFFSET			0x01cc
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU16_OFFSET			0x01ce
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU17_OFFSET			0x01d0
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU18_OFFSET			0x01d2
-#define OMAP4_CTRL_MODULE_PAD_DPM_EMU19_OFFSET			0x01d4
-
-/* ES2.0 only */
-#define OMAP4_CTRL_MODULE_PAD_GPMC_WAIT2_OFFSET			0x008e
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS4_OFFSET			0x0090
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS5_OFFSET			0x0092
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS6_OFFSET			0x0094
-#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS7_OFFSET			0x0096
-
-#define OMAP4_CTRL_MODULE_PAD_KPD_COL3_OFFSET			0x017c
-#define OMAP4_CTRL_MODULE_PAD_KPD_COL4_OFFSET			0x017e
-#define OMAP4_CTRL_MODULE_PAD_KPD_COL5_OFFSET			0x0180
-#define OMAP4_CTRL_MODULE_PAD_KPD_COL0_OFFSET			0x0182
-#define OMAP4_CTRL_MODULE_PAD_KPD_COL1_OFFSET			0x0184
-#define OMAP4_CTRL_MODULE_PAD_KPD_COL2_OFFSET			0x0186
-#define OMAP4_CTRL_MODULE_PAD_KPD_ROW3_OFFSET			0x0188
-#define OMAP4_CTRL_MODULE_PAD_KPD_ROW4_OFFSET			0x018a
-#define OMAP4_CTRL_MODULE_PAD_KPD_ROW5_OFFSET			0x018c
-#define OMAP4_CTRL_MODULE_PAD_KPD_ROW0_OFFSET			0x018e
-#define OMAP4_CTRL_MODULE_PAD_KPD_ROW1_OFFSET			0x0190
-#define OMAP4_CTRL_MODULE_PAD_KPD_ROW2_OFFSET			0x0192
-
-
-#define OMAP4_CTRL_MODULE_PAD_CORE_MUX_SIZE			\
-		(OMAP4_CTRL_MODULE_PAD_DPM_EMU19_OFFSET		\
-		 - OMAP4_CTRL_MODULE_PAD_GPMC_AD0_OFFSET + 2)
-
-/* ctrl_module_pad_wkup base address */
-#define OMAP4_CTRL_MODULE_PAD_WKUP_MUX_PBASE			0x4a31e000
-
-/* ctrl_module_pad_wkup registers offset */
-#define OMAP4_CTRL_MODULE_PAD_SIM_IO_OFFSET			0x0040
-#define OMAP4_CTRL_MODULE_PAD_SIM_CLK_OFFSET			0x0042
-#define OMAP4_CTRL_MODULE_PAD_SIM_RESET_OFFSET			0x0044
-#define OMAP4_CTRL_MODULE_PAD_SIM_CD_OFFSET			0x0046
-#define OMAP4_CTRL_MODULE_PAD_SIM_PWRCTRL_OFFSET		0x0048
-#define OMAP4_CTRL_MODULE_PAD_SR_SCL_OFFSET			0x004a
-#define OMAP4_CTRL_MODULE_PAD_SR_SDA_OFFSET			0x004c
-#define OMAP4_CTRL_MODULE_PAD_FREF_XTAL_IN_OFFSET		0x004e
-#define OMAP4_CTRL_MODULE_PAD_FREF_SLICER_IN_OFFSET		0x0050
-#define OMAP4_CTRL_MODULE_PAD_FREF_CLK_IOREQ_OFFSET		0x0052
-#define OMAP4_CTRL_MODULE_PAD_FREF_CLK0_OUT_OFFSET		0x0054
-#define OMAP4_CTRL_MODULE_PAD_FREF_CLK3_REQ_OFFSET		0x0056
-#define OMAP4_CTRL_MODULE_PAD_FREF_CLK3_OUT_OFFSET		0x0058
-#define OMAP4_CTRL_MODULE_PAD_FREF_CLK4_REQ_OFFSET		0x005a
-#define OMAP4_CTRL_MODULE_PAD_FREF_CLK4_OUT_OFFSET		0x005c
-#define OMAP4_CTRL_MODULE_PAD_SYS_32K_OFFSET			0x005e
-#define OMAP4_CTRL_MODULE_PAD_SYS_NRESPWRON_OFFSET		0x0060
-#define OMAP4_CTRL_MODULE_PAD_SYS_NRESWARM_OFFSET		0x0062
-#define OMAP4_CTRL_MODULE_PAD_SYS_PWR_REQ_OFFSET		0x0064
-#define OMAP4_CTRL_MODULE_PAD_SYS_PWRON_RESET_OUT_OFFSET	0x0066
-#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT6_OFFSET			0x0068
-#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT7_OFFSET			0x006a
-#define OMAP4_CTRL_MODULE_PAD_JTAG_NTRST_OFFSET			0x006c
-#define OMAP4_CTRL_MODULE_PAD_JTAG_TCK_OFFSET			0x006e
-#define OMAP4_CTRL_MODULE_PAD_JTAG_RTCK_OFFSET			0x0070
-#define OMAP4_CTRL_MODULE_PAD_JTAG_TMS_TMSC_OFFSET		0x0072
-#define OMAP4_CTRL_MODULE_PAD_JTAG_TDI_OFFSET			0x0074
-#define OMAP4_CTRL_MODULE_PAD_JTAG_TDO_OFFSET			0x0076
-
-#define OMAP4_CTRL_MODULE_PAD_WKUP_MUX_SIZE			\
-		(OMAP4_CTRL_MODULE_PAD_JTAG_TDO_OFFSET		\
-		 - OMAP4_CTRL_MODULE_PAD_SIM_IO_OFFSET + 2)
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/mux.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/mux.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/mux.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/mux.h	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,6 @@
 #include "mux2420.h"
 #include "mux2430.h"
 #include "mux34xx.h"
-#include "mux44xx.h"
 
 #define OMAP_MUX_TERMINATOR	0xffff
 
@@ -64,8 +63,6 @@
 
 /* Flags for omapX_mux_init */
 #define OMAP_PACKAGE_MASK		0xffff
-#define OMAP_PACKAGE_CBS		8		/* 547-pin 0.40 0.40 */
-#define OMAP_PACKAGE_CBL		7		/* 547-pin 0.40 0.40 */
 #define OMAP_PACKAGE_CBP		6		/* 515-pin 0.40 0.50 */
 #define OMAP_PACKAGE_CUS		5		/* 423-pin 0.65 */
 #define OMAP_PACKAGE_CBB		4		/* 515-pin 0.40 0.50 */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap2-restart.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap2-restart.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap2-restart.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap2-restart.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,7 @@ static struct clk *reset_virt_prcm_set_c
  * Set the DPLL to bypass so that reboot completes successfully.  No
  * return value.
  */
-void omap2xxx_restart(char mode, const char *cmd)
+void omap2xxx_restart(enum reboot_mode mode, const char *cmd)
 {
 	u32 rate;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap3-restart.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap3-restart.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap3-restart.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap3-restart.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/reboot.h>
 
 #include "iomap.h"
 #include "common.h"
@@ -28,7 +29,7 @@
  * Resets the SoC.  For @cmd, see the 'reboot' syscall in
  * kernel/sys.c.  No return value.
  */
-void omap3xxx_restart(char mode, const char *cmd)
+void omap3xxx_restart(enum reboot_mode mode, const char *cmd)
 {
 	omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0));
 	omap3xxx_prm_dpll3_reset(); /* never returns */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap4-common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap4-common.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap4-common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap4-common.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/export.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/of_address.h>
+#include <linux/reboot.h>
 
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/map.h>
@@ -339,19 +340,3 @@ int __init omap4_twl6030_hsmmc_init(stru
 	return 0;
 }
 #endif
-
-/**
- * omap44xx_restart - trigger a software restart of the SoC
- * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
- * @cmd: passed from the userspace program rebooting the system (if provided)
- *
- * Resets the SoC.  For @cmd, see the 'reboot' syscall in
- * kernel/sys.c.  No return value.
- */
-void omap44xx_restart(char mode, const char *cmd)
-{
-	/* XXX Should save 'cmd' into scratchpad for use after reboot */
-	omap4_prminst_global_warm_sw_reset(); /* never returns */
-	while (1);
-}
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap4-restart.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap4-restart.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap4-restart.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap4-restart.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * omap4-restart.c - Common to OMAP4 and OMAP5
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/reboot.h>
+#include "prminst44xx.h"
+
+/**
+ * omap44xx_restart - trigger a software restart of the SoC
+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
+ * @cmd: passed from the userspace program rebooting the system (if provided)
+ *
+ * Resets the SoC.  For @cmd, see the 'reboot' syscall in
+ * kernel/sys.c.  No return value.
+ */
+void omap44xx_restart(enum reboot_mode mode, const char *cmd)
+{
+	/* XXX Should save 'cmd' into scratchpad for use after reboot */
+	omap4_prminst_global_warm_sw_reset(); /* never returns */
+	while (1)
+		;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_device.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_device.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_device.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_device.c	2013-08-25 20:43:22.000000000 -0400
@@ -129,6 +129,7 @@ static int omap_device_build_from_dt(str
 	struct device_node *node = pdev->dev.of_node;
 	const char *oh_name;
 	int oh_cnt, i, ret = 0;
+	bool device_active = false;
 
 	oh_cnt = of_property_count_strings(node, "ti,hwmods");
 	if (oh_cnt <= 0) {
@@ -152,6 +153,8 @@ static int omap_device_build_from_dt(str
 			goto odbfd_exit1;
 		}
 		hwmods[i] = oh;
+		if (oh->flags & HWMOD_INIT_NO_IDLE)
+			device_active = true;
 	}
 
 	od = omap_device_alloc(pdev, hwmods, oh_cnt);
@@ -170,11 +173,13 @@ static int omap_device_build_from_dt(str
 			r->name = dev_name(&pdev->dev);
 	}
 
-	if (of_get_property(node, "ti,no_idle_on_suspend", NULL))
-		omap_device_disable_idle_on_suspend(pdev);
-
 	pdev->dev.pm_domain = &omap_device_pm_domain;
 
+	if (device_active) {
+		omap_device_enable(pdev);
+		pm_runtime_set_active(&pdev->dev);
+	}
+
 odbfd_exit1:
 	kfree(hwmods);
 odbfd_exit:
@@ -591,11 +596,6 @@ static int _od_runtime_suspend(struct de
 	return ret;
 }
 
-static int _od_runtime_idle(struct device *dev)
-{
-	return pm_generic_runtime_idle(dev);
-}
-
 static int _od_runtime_resume(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -621,8 +621,7 @@ static int _od_suspend_noirq(struct devi
 
 	if (!ret && !pm_runtime_status_suspended(dev)) {
 		if (pm_generic_runtime_suspend(dev) == 0) {
-			if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND))
-				omap_device_idle(pdev);
+			omap_device_idle(pdev);
 			od->flags |= OMAP_DEVICE_SUSPENDED;
 		}
 	}
@@ -638,8 +637,7 @@ static int _od_resume_noirq(struct devic
 	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
 	    !pm_runtime_status_suspended(dev)) {
 		od->flags &= ~OMAP_DEVICE_SUSPENDED;
-		if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND))
-			omap_device_enable(pdev);
+		omap_device_enable(pdev);
 		pm_generic_runtime_resume(dev);
 	}
 
@@ -653,7 +651,7 @@ static int _od_resume_noirq(struct devic
 struct dev_pm_domain omap_device_pm_domain = {
 	.ops = {
 		SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
-				   _od_runtime_idle)
+				   NULL)
 		USE_PLATFORM_PM_SLEEP_OPS
 		.suspend_noirq = _od_suspend_noirq,
 		.resume_noirq = _od_resume_noirq,
@@ -852,6 +850,7 @@ static int __init omap_device_late_idle(
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct omap_device *od = to_omap_device(pdev);
+	int i;
 
 	if (!od)
 		return 0;
@@ -860,6 +859,15 @@ static int __init omap_device_late_idle(
 	 * If omap_device state is enabled, but has no driver bound,
 	 * idle it.
 	 */
+
+	/*
+	 * Some devices (like memory controllers) are always kept
+	 * enabled, and should not be idled even with no drivers.
+	 */
+	for (i = 0; i < od->hwmods_cnt; i++)
+		if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
+			return 0;
+
 	if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
 		if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
 			dev_warn(dev, "%s: enabled but no driver.  Idling\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_device.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_device.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_device.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_device.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,6 @@ extern struct dev_pm_domain omap_device_
 
 /* omap_device.flags values */
 #define OMAP_DEVICE_SUSPENDED		BIT(0)
-#define OMAP_DEVICE_NO_IDLE_ON_SUSPEND	BIT(1)
 
 /**
  * struct omap_device - omap_device wrapper for platform_devices
@@ -101,13 +100,4 @@ static inline struct omap_device *to_oma
 {
 	return pdev ? pdev->archdata.od : NULL;
 }
-
-static inline
-void omap_device_disable_idle_on_suspend(struct platform_device *pdev)
-{
-	struct omap_device *od = to_omap_device(pdev);
-
-	od->flags |= OMAP_DEVICE_NO_IDLE_ON_SUSPEND;
-}
-
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap-headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap-headsmp.S
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap-headsmp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap-headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -20,8 +20,6 @@
 
 #include "omap44xx.h"
 
-	__CPUINIT
-
 /* Physical address needed since MMU not enabled yet on secondary core */
 #define AUX_CORE_BOOT0_PA			0x48281800
 
@@ -49,7 +47,7 @@ END(omap5_secondary_startup)
  * The primary core will update this flag using a hardware
  * register AuxCoreBoot0.
  */
-ENTRY(omap_secondary_startup)
+ENTRY(omap4_secondary_startup)
 hold:	ldr	r12,=0x103
 	dsb
 	smc	#0			@ read from AuxCoreBoot0
@@ -64,9 +62,9 @@ hold:	ldr	r12,=0x103
 	 * should now contain the SVC stack for this core
 	 */
 	b	secondary_startup
-ENDPROC(omap_secondary_startup)
+ENDPROC(omap4_secondary_startup)
 
-ENTRY(omap_secondary_startup_4460)
+ENTRY(omap4460_secondary_startup)
 hold_2:	ldr	r12,=0x103
 	dsb
 	smc	#0			@ read from AuxCoreBoot0
@@ -101,4 +99,4 @@ hold_2:	ldr	r12,=0x103
 	 * should now contain the SVC stack for this core
 	 */
 	b	secondary_startup
-ENDPROC(omap_secondary_startup_4460)
+ENDPROC(omap4460_secondary_startup)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_2420_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_2420_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_2420_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_2420_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/i2c-omap.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/omap-dma.h>
+#include <linux/platform_data/mailbox-omap.h>
 #include <plat/dmtimer.h>
 
 #include "omap_hwmod.h"
@@ -166,6 +167,18 @@ static struct omap_hwmod omap2420_dma_sy
 };
 
 /* mailbox */
+static struct omap_mbox_dev_info omap2420_mailbox_info[] = {
+	{ .name = "dsp", .tx_id = 0, .rx_id = 1, .irq_id = 0, .usr_id = 0 },
+	{ .name = "iva", .tx_id = 2, .rx_id = 3, .irq_id = 1, .usr_id = 3 },
+};
+
+static struct omap_mbox_pdata omap2420_mailbox_attrs = {
+	.num_users	= 4,
+	.num_fifos	= 6,
+	.info_cnt	= ARRAY_SIZE(omap2420_mailbox_info),
+	.info		= omap2420_mailbox_info,
+};
+
 static struct omap_hwmod_irq_info omap2420_mailbox_irqs[] = {
 	{ .name = "dsp", .irq = 26 + OMAP_INTC_START, },
 	{ .name = "iva", .irq = 34 + OMAP_INTC_START, },
@@ -186,6 +199,7 @@ static struct omap_hwmod omap2420_mailbo
 			.idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT,
 		},
 	},
+	.dev_attr	= &omap2420_mailbox_attrs,
 };
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_2430_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_2430_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_2430_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_2430_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/omap-dma.h>
+#include <linux/platform_data/mailbox-omap.h>
 #include <plat/dmtimer.h>
 
 #include "omap_hwmod.h"
@@ -170,6 +171,17 @@ static struct omap_hwmod omap2430_dma_sy
 };
 
 /* mailbox */
+static struct omap_mbox_dev_info omap2430_mailbox_info[] = {
+	{ .name = "dsp", .tx_id = 0, .rx_id = 1 },
+};
+
+static struct omap_mbox_pdata omap2430_mailbox_attrs = {
+	.num_users	= 4,
+	.num_fifos	= 6,
+	.info_cnt	= ARRAY_SIZE(omap2430_mailbox_info),
+	.info		= omap2430_mailbox_info,
+};
+
 static struct omap_hwmod_irq_info omap2430_mailbox_irqs[] = {
 	{ .irq = 26 + OMAP_INTC_START, },
 	{ .irq = -1 },
@@ -189,6 +201,7 @@ static struct omap_hwmod omap2430_mailbo
 			.idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT,
 		},
 	},
+	.dev_attr	= &omap2430_mailbox_attrs,
 };
 
 /* mcspi3 */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,6 @@
 #include "hdq1w.h"
 
 #include "omap_hwmod_common_data.h"
-#include "dma.h"
 
 /* UART */
 
@@ -89,32 +88,32 @@ struct omap_hwmod_class omap2_venc_hwmod
 
 /* Common DMA request line data */
 struct omap_hwmod_dma_info omap2_uart1_sdma_reqs[] = {
-	{ .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, },
-	{ .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, },
+	{ .name = "rx", .dma_req = 50, },
+	{ .name = "tx", .dma_req = 49, },
 	{ .dma_req = -1 }
 };
 
 struct omap_hwmod_dma_info omap2_uart2_sdma_reqs[] = {
-	{ .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, },
-	{ .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, },
+	{ .name = "rx", .dma_req = 52, },
+	{ .name = "tx", .dma_req = 51, },
 	{ .dma_req = -1 }
 };
 
 struct omap_hwmod_dma_info omap2_uart3_sdma_reqs[] = {
-	{ .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, },
-	{ .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, },
+	{ .name = "rx", .dma_req = 54, },
+	{ .name = "tx", .dma_req = 53, },
 	{ .dma_req = -1 }
 };
 
 struct omap_hwmod_dma_info omap2_i2c1_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX },
-	{ .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX },
+	{ .name = "tx", .dma_req = 27 },
+	{ .name = "rx", .dma_req = 28 },
 	{ .dma_req = -1 }
 };
 
 struct omap_hwmod_dma_info omap2_i2c2_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX },
-	{ .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX },
+	{ .name = "tx", .dma_req = 29 },
+	{ .name = "rx", .dma_req = 30 },
 	{ .dma_req = -1 }
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -512,7 +512,7 @@ struct omap_hwmod omap2xxx_uart1_hwmod =
 	.mpu_irqs	= omap2_uart1_mpu_irqs,
 	.sdma_reqs	= omap2_uart1_sdma_reqs,
 	.main_clk	= "uart1_fck",
-	.flags		= HWMOD_SWSUP_SIDLE_ACT,
+	.flags		= DEBUG_OMAP2UART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.prcm		= {
 		.omap2 = {
 			.module_offs = CORE_MOD,
@@ -532,7 +532,7 @@ struct omap_hwmod omap2xxx_uart2_hwmod =
 	.mpu_irqs	= omap2_uart2_mpu_irqs,
 	.sdma_reqs	= omap2_uart2_sdma_reqs,
 	.main_clk	= "uart2_fck",
-	.flags		= HWMOD_SWSUP_SIDLE_ACT,
+	.flags		= DEBUG_OMAP2UART2_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.prcm		= {
 		.omap2 = {
 			.module_offs = CORE_MOD,
@@ -552,7 +552,7 @@ struct omap_hwmod omap2xxx_uart3_hwmod =
 	.mpu_irqs	= omap2_uart3_mpu_irqs,
 	.sdma_reqs	= omap2_uart3_sdma_reqs,
 	.main_clk	= "uart3_fck",
-	.flags		= HWMOD_SWSUP_SIDLE_ACT,
+	.flags		= DEBUG_OMAP2UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.prcm		= {
 		.omap2 = {
 			.module_offs = CORE_MOD,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_33xx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_33xx_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_33xx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,29 +35,6 @@
  */
 
 /*
- * 'emif_fw' class
- * instance(s): emif_fw
- */
-static struct omap_hwmod_class am33xx_emif_fw_hwmod_class = {
-	.name		= "emif_fw",
-};
-
-/* emif_fw */
-static struct omap_hwmod am33xx_emif_fw_hwmod = {
-	.name		= "emif_fw",
-	.class		= &am33xx_emif_fw_hwmod_class,
-	.clkdm_name	= "l4fw_clkdm",
-	.main_clk	= "l4fw_gclk",
-	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-	.prcm		= {
-		.omap4	= {
-			.clkctrl_offs	= AM33XX_CM_PER_EMIF_FW_CLKCTRL_OFFSET,
-			.modulemode	= MODULEMODE_SWCTRL,
-		},
-	},
-};
-
-/*
  * 'emif' class
  * instance(s): emif
  */
@@ -70,18 +47,12 @@ static struct omap_hwmod_class am33xx_em
 	.sysc		= &am33xx_emif_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_emif_irqs[] = {
-	{ .name = "ddrerr0", .irq = 101 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 /* emif */
 static struct omap_hwmod am33xx_emif_hwmod = {
 	.name		= "emif",
 	.class		= &am33xx_emif_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
 	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-	.mpu_irqs	= am33xx_emif_irqs,
 	.main_clk	= "dpll_ddr_m2_div2_ck",
 	.prcm		= {
 		.omap4	= {
@@ -99,19 +70,11 @@ static struct omap_hwmod_class am33xx_l3
 	.name		= "l3",
 };
 
-/* l3_main (l3_fast) */
-static struct omap_hwmod_irq_info am33xx_l3_main_irqs[] = {
-	{ .name = "l3debug", .irq = 9 + OMAP_INTC_START, },
-	{ .name = "l3appint", .irq = 10 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_l3_main_hwmod = {
 	.name		= "l3_main",
 	.class		= &am33xx_l3_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
 	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-	.mpu_irqs	= am33xx_l3_main_irqs,
 	.main_clk	= "l3_gclk",
 	.prcm		= {
 		.omap4	= {
@@ -196,20 +159,6 @@ static struct omap_hwmod am33xx_l4_wkup_
 	},
 };
 
-/* l4_fw */
-static struct omap_hwmod am33xx_l4_fw_hwmod = {
-	.name		= "l4_fw",
-	.class		= &am33xx_l4_hwmod_class,
-	.clkdm_name	= "l4fw_clkdm",
-	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-	.prcm		= {
-		.omap4	= {
-			.clkctrl_offs	= AM33XX_CM_PER_L4FW_CLKCTRL_OFFSET,
-			.modulemode	= MODULEMODE_SWCTRL,
-		},
-	},
-};
-
 /*
  * 'mpu' class
  */
@@ -217,21 +166,11 @@ static struct omap_hwmod_class am33xx_mp
 	.name	= "mpu",
 };
 
-/* mpu */
-static struct omap_hwmod_irq_info am33xx_mpu_irqs[] = {
-	{ .name = "emuint", .irq = 0 + OMAP_INTC_START, },
-	{ .name = "commtx", .irq = 1 + OMAP_INTC_START, },
-	{ .name = "commrx", .irq = 2 + OMAP_INTC_START, },
-	{ .name = "bench", .irq = 3 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_mpu_hwmod = {
 	.name		= "mpu",
 	.class		= &am33xx_mpu_hwmod_class,
 	.clkdm_name	= "mpu_clkdm",
 	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-	.mpu_irqs	= am33xx_mpu_irqs,
 	.main_clk	= "dpll_mpu_m2_ck",
 	.prcm		= {
 		.omap4	= {
@@ -253,11 +192,6 @@ static struct omap_hwmod_rst_info am33xx
 	{ .name = "wkup_m3", .rst_shift = 3, .st_shift = 5 },
 };
 
-static struct omap_hwmod_irq_info am33xx_wkup_m3_irqs[] = {
-	{ .name = "txev", .irq = 78 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 /* wkup_m3  */
 static struct omap_hwmod am33xx_wkup_m3_hwmod = {
 	.name		= "wkup_m3",
@@ -265,7 +199,6 @@ static struct omap_hwmod am33xx_wkup_m3_
 	.clkdm_name	= "l4_wkup_aon_clkdm",
 	/* Keep hardreset asserted */
 	.flags		= HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
-	.mpu_irqs	= am33xx_wkup_m3_irqs,
 	.main_clk	= "dpll_core_m4_div2_ck",
 	.prcm		= {
 		.omap4	= {
@@ -291,25 +224,12 @@ static struct omap_hwmod_rst_info am33xx
 	{ .name = "pruss", .rst_shift = 1 },
 };
 
-static struct omap_hwmod_irq_info am33xx_pruss_irqs[] = {
-	{ .name = "evtout0", .irq = 20 + OMAP_INTC_START, },
-	{ .name = "evtout1", .irq = 21 + OMAP_INTC_START, },
-	{ .name = "evtout2", .irq = 22 + OMAP_INTC_START, },
-	{ .name = "evtout3", .irq = 23 + OMAP_INTC_START, },
-	{ .name = "evtout4", .irq = 24 + OMAP_INTC_START, },
-	{ .name = "evtout5", .irq = 25 + OMAP_INTC_START, },
-	{ .name = "evtout6", .irq = 26 + OMAP_INTC_START, },
-	{ .name = "evtout7", .irq = 27 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 /* pru-icss */
 /* Pseudo hwmod for reset control purpose only */
 static struct omap_hwmod am33xx_pruss_hwmod = {
 	.name		= "pruss",
 	.class		= &am33xx_pruss_hwmod_class,
 	.clkdm_name	= "pruss_ocp_clkdm",
-	.mpu_irqs	= am33xx_pruss_irqs,
 	.main_clk	= "pruss_ocp_gclk",
 	.prcm		= {
 		.omap4	= {
@@ -329,24 +249,19 @@ static struct omap_hwmod_class am33xx_gf
 };
 
 static struct omap_hwmod_rst_info am33xx_gfx_resets[] = {
-	{ .name = "gfx", .rst_shift = 0 },
-};
-
-static struct omap_hwmod_irq_info am33xx_gfx_irqs[] = {
-	{ .name = "gfxint", .irq = 37 + OMAP_INTC_START, },
-	{ .irq = -1 },
+	{ .name = "gfx", .rst_shift = 0, .st_shift = 0},
 };
 
 static struct omap_hwmod am33xx_gfx_hwmod = {
 	.name		= "gfx",
 	.class		= &am33xx_gfx_hwmod_class,
 	.clkdm_name	= "gfx_l3_clkdm",
-	.mpu_irqs	= am33xx_gfx_irqs,
 	.main_clk	= "gfx_fck_div_ck",
 	.prcm		= {
 		.omap4	= {
 			.clkctrl_offs	= AM33XX_CM_GFX_GFX_CLKCTRL_OFFSET,
 			.rstctrl_offs	= AM33XX_RM_GFX_RSTCTRL_OFFSET,
+			.rstst_offs	= AM33XX_RM_GFX_RSTST_OFFSET,
 			.modulemode	= MODULEMODE_SWCTRL,
 		},
 	},
@@ -387,16 +302,10 @@ static struct omap_hwmod_class am33xx_ad
 	.sysc		= &am33xx_adc_tsc_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_adc_tsc_irqs[] = {
-	{ .irq = 16 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_adc_tsc_hwmod = {
 	.name		= "adc_tsc",
 	.class		= &am33xx_adc_tsc_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
-	.mpu_irqs	= am33xx_adc_tsc_irqs,
 	.main_clk	= "adc_tsc_fck",
 	.prcm		= {
 		.omap4	= {
@@ -515,23 +424,10 @@ static struct omap_hwmod_class am33xx_ae
 	.sysc		= &am33xx_aes0_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_aes0_irqs[] = {
-	{ .irq = 103 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info am33xx_aes0_edma_reqs[] = {
-	{ .name = "tx", .dma_req = 6, },
-	{ .name = "rx", .dma_req = 5, },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod am33xx_aes0_hwmod = {
 	.name		= "aes",
 	.class		= &am33xx_aes0_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
-	.mpu_irqs	= am33xx_aes0_irqs,
-	.sdma_reqs	= am33xx_aes0_edma_reqs,
 	.main_clk	= "aes0_fck",
 	.prcm		= {
 		.omap4	= {
@@ -554,22 +450,10 @@ static struct omap_hwmod_class am33xx_sh
 	.sysc		= &am33xx_sha0_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_sha0_irqs[] = {
-	{ .irq = 109 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info am33xx_sha0_edma_reqs[] = {
-	{ .name = "rx", .dma_req = 36, },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod am33xx_sha0_hwmod = {
 	.name		= "sham",
 	.class		= &am33xx_sha0_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
-	.mpu_irqs	= am33xx_sha0_irqs,
-	.sdma_reqs	= am33xx_sha0_edma_reqs,
 	.main_clk	= "l3_gclk",
 	.prcm		= {
 		.omap4	= {
@@ -604,16 +488,10 @@ static struct omap_hwmod_class am33xx_sm
 };
 
 /* smartreflex0 */
-static struct omap_hwmod_irq_info am33xx_smartreflex0_irqs[] = {
-	{ .irq = 120 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_smartreflex0_hwmod = {
 	.name		= "smartreflex0",
 	.class		= &am33xx_smartreflex_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
-	.mpu_irqs	= am33xx_smartreflex0_irqs,
 	.main_clk	= "smartreflex0_fck",
 	.prcm		= {
 		.omap4	= {
@@ -624,16 +502,10 @@ static struct omap_hwmod am33xx_smartref
 };
 
 /* smartreflex1 */
-static struct omap_hwmod_irq_info am33xx_smartreflex1_irqs[] = {
-	{ .irq = 121 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_smartreflex1_hwmod = {
 	.name		= "smartreflex1",
 	.class		= &am33xx_smartreflex_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
-	.mpu_irqs	= am33xx_smartreflex1_irqs,
 	.main_clk	= "smartreflex1_fck",
 	.prcm		= {
 		.omap4	= {
@@ -650,17 +522,11 @@ static struct omap_hwmod_class am33xx_co
 	.name		= "control",
 };
 
-static struct omap_hwmod_irq_info am33xx_control_irqs[] = {
-	{ .irq = 8 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_control_hwmod = {
 	.name		= "control",
 	.class		= &am33xx_control_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
 	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-	.mpu_irqs	= am33xx_control_irqs,
 	.main_clk	= "dpll_core_m4_div2_ck",
 	.prcm		= {
 		.omap4	= {
@@ -690,21 +556,13 @@ static struct omap_hwmod_class am33xx_cp
 	.sysc		= &am33xx_cpgmac_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_cpgmac0_irqs[] = {
-	{ .name = "c0_rx_thresh_pend", .irq = 40 + OMAP_INTC_START, },
-	{ .name = "c0_rx_pend", .irq = 41 + OMAP_INTC_START, },
-	{ .name = "c0_tx_pend", .irq = 42 + OMAP_INTC_START, },
-	{ .name = "c0_misc_pend", .irq = 43 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_cpgmac0_hwmod = {
 	.name		= "cpgmac0",
 	.class		= &am33xx_cpgmac0_hwmod_class,
 	.clkdm_name	= "cpsw_125mhz_clkdm",
 	.flags		= (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
-	.mpu_irqs	= am33xx_cpgmac0_irqs,
 	.main_clk	= "cpsw_125mhz_gclk",
+	.mpu_rt_idx	= 1,
 	.prcm		= {
 		.omap4	= {
 			.clkctrl_offs	= AM33XX_CM_PER_CPGMAC0_CLKCTRL_OFFSET,
@@ -735,17 +593,10 @@ static struct omap_hwmod_class am33xx_dc
 };
 
 /* dcan0 */
-static struct omap_hwmod_irq_info am33xx_dcan0_irqs[] = {
-	{ .name = "d_can_ms", .irq = 52 + OMAP_INTC_START, },
-	{ .name = "d_can_mo", .irq = 53 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_dcan0_hwmod = {
 	.name		= "d_can0",
 	.class		= &am33xx_dcan_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_dcan0_irqs,
 	.main_clk	= "dcan0_fck",
 	.prcm		= {
 		.omap4	= {
@@ -756,16 +607,10 @@ static struct omap_hwmod am33xx_dcan0_hw
 };
 
 /* dcan1 */
-static struct omap_hwmod_irq_info am33xx_dcan1_irqs[] = {
-	{ .name = "d_can_ms", .irq = 55 + OMAP_INTC_START, },
-	{ .name = "d_can_mo", .irq = 56 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
 static struct omap_hwmod am33xx_dcan1_hwmod = {
 	.name		= "d_can1",
 	.class		= &am33xx_dcan_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_dcan1_irqs,
 	.main_clk	= "dcan1_fck",
 	.prcm		= {
 		.omap4	= {
@@ -792,16 +637,10 @@ static struct omap_hwmod_class am33xx_el
 	.sysc		= &am33xx_elm_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_elm_irqs[] = {
-	{ .irq = 4 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_elm_hwmod = {
 	.name		= "elm",
 	.class		= &am33xx_elm_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_elm_irqs,
 	.main_clk	= "l4ls_gclk",
 	.prcm		= {
 		.omap4	= {
@@ -854,45 +693,26 @@ static struct omap_hwmod am33xx_epwmss0_
 };
 
 /* ecap0 */
-static struct omap_hwmod_irq_info am33xx_ecap0_irqs[] = {
-	{ .irq = 31 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_ecap0_hwmod = {
 	.name		= "ecap0",
 	.class		= &am33xx_ecap_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_ecap0_irqs,
 	.main_clk	= "l4ls_gclk",
 };
 
 /* eqep0 */
-static struct omap_hwmod_irq_info am33xx_eqep0_irqs[] = {
-	{ .irq = 79 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_eqep0_hwmod = {
 	.name		= "eqep0",
 	.class		= &am33xx_eqep_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_eqep0_irqs,
 	.main_clk	= "l4ls_gclk",
 };
 
 /* ehrpwm0 */
-static struct omap_hwmod_irq_info am33xx_ehrpwm0_irqs[] = {
-	{ .name = "int", .irq = 86 + OMAP_INTC_START, },
-	{ .name = "tzint", .irq = 58 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_ehrpwm0_hwmod = {
 	.name		= "ehrpwm0",
 	.class		= &am33xx_ehrpwm_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_ehrpwm0_irqs,
 	.main_clk	= "l4ls_gclk",
 };
 
@@ -911,45 +731,26 @@ static struct omap_hwmod am33xx_epwmss1_
 };
 
 /* ecap1 */
-static struct omap_hwmod_irq_info am33xx_ecap1_irqs[] = {
-	{ .irq = 47 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_ecap1_hwmod = {
 	.name		= "ecap1",
 	.class		= &am33xx_ecap_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_ecap1_irqs,
 	.main_clk	= "l4ls_gclk",
 };
 
 /* eqep1 */
-static struct omap_hwmod_irq_info am33xx_eqep1_irqs[] = {
-	{ .irq = 88 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_eqep1_hwmod = {
 	.name		= "eqep1",
 	.class		= &am33xx_eqep_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_eqep1_irqs,
 	.main_clk	= "l4ls_gclk",
 };
 
 /* ehrpwm1 */
-static struct omap_hwmod_irq_info am33xx_ehrpwm1_irqs[] = {
-	{ .name = "int", .irq = 87 + OMAP_INTC_START, },
-	{ .name = "tzint", .irq = 59 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_ehrpwm1_hwmod = {
 	.name		= "ehrpwm1",
 	.class		= &am33xx_ehrpwm_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_ehrpwm1_irqs,
 	.main_clk	= "l4ls_gclk",
 };
 
@@ -968,45 +769,26 @@ static struct omap_hwmod am33xx_epwmss2_
 };
 
 /* ecap2 */
-static struct omap_hwmod_irq_info am33xx_ecap2_irqs[] = {
-	{ .irq = 61 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_ecap2_hwmod = {
 	.name		= "ecap2",
 	.class		= &am33xx_ecap_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_ecap2_irqs,
 	.main_clk	= "l4ls_gclk",
 };
 
 /* eqep2 */
-static struct omap_hwmod_irq_info am33xx_eqep2_irqs[] = {
-	{ .irq = 89 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_eqep2_hwmod = {
 	.name		= "eqep2",
 	.class		= &am33xx_eqep_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_eqep2_irqs,
 	.main_clk	= "l4ls_gclk",
 };
 
 /* ehrpwm2 */
-static struct omap_hwmod_irq_info am33xx_ehrpwm2_irqs[] = {
-	{ .name = "int", .irq = 39 + OMAP_INTC_START, },
-	{ .name = "tzint", .irq = 60 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_ehrpwm2_hwmod = {
 	.name		= "ehrpwm2",
 	.class		= &am33xx_ehrpwm_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_ehrpwm2_irqs,
 	.main_clk	= "l4ls_gclk",
 };
 
@@ -1041,17 +823,11 @@ static struct omap_hwmod_opt_clk gpio0_o
 	{ .role = "dbclk", .clk = "gpio0_dbclk" },
 };
 
-static struct omap_hwmod_irq_info am33xx_gpio0_irqs[] = {
-	{ .irq = 96 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_gpio0_hwmod = {
 	.name		= "gpio1",
 	.class		= &am33xx_gpio_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
 	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-	.mpu_irqs	= am33xx_gpio0_irqs,
 	.main_clk	= "dpll_core_m4_div2_ck",
 	.prcm		= {
 		.omap4	= {
@@ -1065,11 +841,6 @@ static struct omap_hwmod am33xx_gpio0_hw
 };
 
 /* gpio1 */
-static struct omap_hwmod_irq_info am33xx_gpio1_irqs[] = {
-	{ .irq = 98 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio1_dbclk" },
 };
@@ -1079,7 +850,6 @@ static struct omap_hwmod am33xx_gpio1_hw
 	.class		= &am33xx_gpio_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
 	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-	.mpu_irqs	= am33xx_gpio1_irqs,
 	.main_clk	= "l4ls_gclk",
 	.prcm		= {
 		.omap4	= {
@@ -1093,11 +863,6 @@ static struct omap_hwmod am33xx_gpio1_hw
 };
 
 /* gpio2 */
-static struct omap_hwmod_irq_info am33xx_gpio2_irqs[] = {
-	{ .irq = 32 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio2_dbclk" },
 };
@@ -1107,7 +872,6 @@ static struct omap_hwmod am33xx_gpio2_hw
 	.class		= &am33xx_gpio_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
 	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-	.mpu_irqs	= am33xx_gpio2_irqs,
 	.main_clk	= "l4ls_gclk",
 	.prcm		= {
 		.omap4	= {
@@ -1121,11 +885,6 @@ static struct omap_hwmod am33xx_gpio2_hw
 };
 
 /* gpio3 */
-static struct omap_hwmod_irq_info am33xx_gpio3_irqs[] = {
-	{ .irq = 62 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio3_dbclk" },
 };
@@ -1135,7 +894,6 @@ static struct omap_hwmod am33xx_gpio3_hw
 	.class		= &am33xx_gpio_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
 	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-	.mpu_irqs	= am33xx_gpio3_irqs,
 	.main_clk	= "l4ls_gclk",
 	.prcm		= {
 		.omap4	= {
@@ -1164,17 +922,11 @@ static struct omap_hwmod_class am33xx_gp
 	.sysc		= &gpmc_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_gpmc_irqs[] = {
-	{ .irq = 100 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_gpmc_hwmod = {
 	.name		= "gpmc",
 	.class		= &am33xx_gpmc_hwmod_class,
 	.clkdm_name	= "l3s_clkdm",
 	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-	.mpu_irqs	= am33xx_gpmc_irqs,
 	.main_clk	= "l3s_gclk",
 	.prcm		= {
 		.omap4	= {
@@ -1208,23 +960,10 @@ static struct omap_i2c_dev_attr i2c_dev_
 };
 
 /* i2c1 */
-static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = {
-	{ .irq = 70 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info i2c1_edma_reqs[] = {
-	{ .name = "tx", .dma_req = 0, },
-	{ .name = "rx", .dma_req = 0, },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod am33xx_i2c1_hwmod = {
 	.name		= "i2c1",
 	.class		= &i2c_class,
 	.clkdm_name	= "l4_wkup_clkdm",
-	.mpu_irqs	= i2c1_mpu_irqs,
-	.sdma_reqs	= i2c1_edma_reqs,
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
 	.main_clk	= "dpll_per_m2_div4_wkupdm_ck",
 	.prcm		= {
@@ -1237,23 +976,10 @@ static struct omap_hwmod am33xx_i2c1_hwm
 };
 
 /* i2c1 */
-static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = {
-	{ .irq = 71 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info i2c2_edma_reqs[] = {
-	{ .name = "tx", .dma_req = 0, },
-	{ .name = "rx", .dma_req = 0, },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod am33xx_i2c2_hwmod = {
 	.name		= "i2c2",
 	.class		= &i2c_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= i2c2_mpu_irqs,
-	.sdma_reqs	= i2c2_edma_reqs,
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
 	.main_clk	= "dpll_per_m2_div4_ck",
 	.prcm		= {
@@ -1266,23 +992,10 @@ static struct omap_hwmod am33xx_i2c2_hwm
 };
 
 /* i2c3 */
-static struct omap_hwmod_dma_info i2c3_edma_reqs[] = {
-	{ .name = "tx", .dma_req = 0, },
-	{ .name = "rx", .dma_req = 0, },
-	{ .dma_req = -1 }
-};
-
-static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = {
-	{ .irq = 30 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_i2c3_hwmod = {
 	.name		= "i2c3",
 	.class		= &i2c_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= i2c3_mpu_irqs,
-	.sdma_reqs	= i2c3_edma_reqs,
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
 	.main_clk	= "dpll_per_m2_div4_ck",
 	.prcm		= {
@@ -1309,16 +1022,10 @@ static struct omap_hwmod_class am33xx_lc
 	.sysc		= &lcdc_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_lcdc_irqs[] = {
-	{ .irq = 36 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_lcdc_hwmod = {
 	.name		= "lcdc",
 	.class		= &am33xx_lcdc_hwmod_class,
 	.clkdm_name	= "lcdc_clkdm",
-	.mpu_irqs	= am33xx_lcdc_irqs,
 	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
 	.main_clk	= "lcd_gclk",
 	.prcm		= {
@@ -1348,16 +1055,10 @@ static struct omap_hwmod_class am33xx_ma
 	.sysc	= &am33xx_mailbox_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_mailbox_irqs[] = {
-	{ .irq = 77 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_mailbox_hwmod = {
 	.name		= "mailbox",
 	.class		= &am33xx_mailbox_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_mailbox_irqs,
 	.main_clk	= "l4ls_gclk",
 	.prcm = {
 		.omap4 = {
@@ -1384,24 +1085,10 @@ static struct omap_hwmod_class am33xx_mc
 };
 
 /* mcasp0 */
-static struct omap_hwmod_irq_info am33xx_mcasp0_irqs[] = {
-	{ .name = "ax", .irq = 80 + OMAP_INTC_START, },
-	{ .name = "ar", .irq = 81 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info am33xx_mcasp0_edma_reqs[] = {
-	{ .name = "tx", .dma_req = 8, },
-	{ .name = "rx", .dma_req = 9, },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod am33xx_mcasp0_hwmod = {
 	.name		= "mcasp0",
 	.class		= &am33xx_mcasp_hwmod_class,
 	.clkdm_name	= "l3s_clkdm",
-	.mpu_irqs	= am33xx_mcasp0_irqs,
-	.sdma_reqs	= am33xx_mcasp0_edma_reqs,
 	.main_clk	= "mcasp0_fck",
 	.prcm		= {
 		.omap4	= {
@@ -1412,24 +1099,10 @@ static struct omap_hwmod am33xx_mcasp0_h
 };
 
 /* mcasp1 */
-static struct omap_hwmod_irq_info am33xx_mcasp1_irqs[] = {
-	{ .name = "ax", .irq = 82 + OMAP_INTC_START, },
-	{ .name = "ar", .irq = 83 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info am33xx_mcasp1_edma_reqs[] = {
-	{ .name = "tx", .dma_req = 10, },
-	{ .name = "rx", .dma_req = 11, },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod am33xx_mcasp1_hwmod = {
 	.name		= "mcasp1",
 	.class		= &am33xx_mcasp_hwmod_class,
 	.clkdm_name	= "l3s_clkdm",
-	.mpu_irqs	= am33xx_mcasp1_irqs,
-	.sdma_reqs	= am33xx_mcasp1_edma_reqs,
 	.main_clk	= "mcasp1_fck",
 	.prcm		= {
 		.omap4	= {
@@ -1457,17 +1130,6 @@ static struct omap_hwmod_class am33xx_mm
 };
 
 /* mmc0 */
-static struct omap_hwmod_irq_info am33xx_mmc0_irqs[] = {
-	{ .irq = 64 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info am33xx_mmc0_edma_reqs[] = {
-	{ .name = "tx", .dma_req = 24, },
-	{ .name = "rx", .dma_req = 25, },
-	{ .dma_req = -1 }
-};
-
 static struct omap_mmc_dev_attr am33xx_mmc0_dev_attr = {
 	.flags		= OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
 };
@@ -1476,8 +1138,6 @@ static struct omap_hwmod am33xx_mmc0_hwm
 	.name		= "mmc1",
 	.class		= &am33xx_mmc_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_mmc0_irqs,
-	.sdma_reqs	= am33xx_mmc0_edma_reqs,
 	.main_clk	= "mmc_clk",
 	.prcm		= {
 		.omap4	= {
@@ -1489,17 +1149,6 @@ static struct omap_hwmod am33xx_mmc0_hwm
 };
 
 /* mmc1 */
-static struct omap_hwmod_irq_info am33xx_mmc1_irqs[] = {
-	{ .irq = 28 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info am33xx_mmc1_edma_reqs[] = {
-	{ .name = "tx", .dma_req = 2, },
-	{ .name = "rx", .dma_req = 3, },
-	{ .dma_req = -1 }
-};
-
 static struct omap_mmc_dev_attr am33xx_mmc1_dev_attr = {
 	.flags		= OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
 };
@@ -1508,8 +1157,6 @@ static struct omap_hwmod am33xx_mmc1_hwm
 	.name		= "mmc2",
 	.class		= &am33xx_mmc_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_mmc1_irqs,
-	.sdma_reqs	= am33xx_mmc1_edma_reqs,
 	.main_clk	= "mmc_clk",
 	.prcm		= {
 		.omap4	= {
@@ -1521,17 +1168,6 @@ static struct omap_hwmod am33xx_mmc1_hwm
 };
 
 /* mmc2 */
-static struct omap_hwmod_irq_info am33xx_mmc2_irqs[] = {
-	{ .irq = 29 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info am33xx_mmc2_edma_reqs[] = {
-	{ .name = "tx", .dma_req = 64, },
-	{ .name = "rx", .dma_req = 65, },
-	{ .dma_req = -1 }
-};
-
 static struct omap_mmc_dev_attr am33xx_mmc2_dev_attr = {
 	.flags		= OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
 };
@@ -1539,8 +1175,6 @@ static struct omap_hwmod am33xx_mmc2_hwm
 	.name		= "mmc3",
 	.class		= &am33xx_mmc_hwmod_class,
 	.clkdm_name	= "l3s_clkdm",
-	.mpu_irqs	= am33xx_mmc2_irqs,
-	.sdma_reqs	= am33xx_mmc2_edma_reqs,
 	.main_clk	= "mmc_clk",
 	.prcm		= {
 		.omap4	= {
@@ -1569,17 +1203,10 @@ static struct omap_hwmod_class am33xx_rt
 	.sysc		= &am33xx_rtc_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_rtc_irqs[] = {
-	{ .name = "rtcint", .irq = 75 + OMAP_INTC_START, },
-	{ .name = "rtcalarmint", .irq = 76 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_rtc_hwmod = {
 	.name		= "rtc",
 	.class		= &am33xx_rtc_hwmod_class,
 	.clkdm_name	= "l4_rtc_clkdm",
-	.mpu_irqs	= am33xx_rtc_irqs,
 	.main_clk	= "clk_32768_ck",
 	.prcm		= {
 		.omap4	= {
@@ -1608,19 +1235,6 @@ static struct omap_hwmod_class am33xx_sp
 };
 
 /* spi0 */
-static struct omap_hwmod_irq_info am33xx_spi0_irqs[] = {
-	{ .irq = 65 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info am33xx_mcspi0_edma_reqs[] = {
-	{ .name = "rx0", .dma_req = 17 },
-	{ .name = "tx0", .dma_req = 16 },
-	{ .name = "rx1", .dma_req = 19 },
-	{ .name = "tx1", .dma_req = 18 },
-	{ .dma_req = -1 }
-};
-
 static struct omap2_mcspi_dev_attr mcspi_attrib = {
 	.num_chipselect	= 2,
 };
@@ -1628,8 +1242,6 @@ static struct omap_hwmod am33xx_spi0_hwm
 	.name		= "spi0",
 	.class		= &am33xx_spi_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_spi0_irqs,
-	.sdma_reqs	= am33xx_mcspi0_edma_reqs,
 	.main_clk	= "dpll_per_m2_div4_ck",
 	.prcm		= {
 		.omap4	= {
@@ -1641,25 +1253,10 @@ static struct omap_hwmod am33xx_spi0_hwm
 };
 
 /* spi1 */
-static struct omap_hwmod_irq_info am33xx_spi1_irqs[] = {
-	{ .irq = 125 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
-static struct omap_hwmod_dma_info am33xx_mcspi1_edma_reqs[] = {
-	{ .name = "rx0", .dma_req = 43 },
-	{ .name = "tx0", .dma_req = 42 },
-	{ .name = "rx1", .dma_req = 45 },
-	{ .name = "tx1", .dma_req = 44 },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod am33xx_spi1_hwmod = {
 	.name		= "spi1",
 	.class		= &am33xx_spi_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_spi1_irqs,
-	.sdma_reqs	= am33xx_mcspi1_edma_reqs,
 	.main_clk	= "dpll_per_m2_div4_ck",
 	.prcm		= {
 		.omap4	= {
@@ -1725,16 +1322,10 @@ static struct omap_hwmod_class am33xx_ti
 	.sysc		= &am33xx_timer1ms_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_timer1_irqs[] = {
-	{ .irq = 67 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_timer1_hwmod = {
 	.name		= "timer1",
 	.class		= &am33xx_timer1ms_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
-	.mpu_irqs	= am33xx_timer1_irqs,
 	.main_clk	= "timer1_fck",
 	.prcm		= {
 		.omap4	= {
@@ -1744,16 +1335,10 @@ static struct omap_hwmod am33xx_timer1_h
 	},
 };
 
-static struct omap_hwmod_irq_info am33xx_timer2_irqs[] = {
-	{ .irq = 68 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_timer2_hwmod = {
 	.name		= "timer2",
 	.class		= &am33xx_timer_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_timer2_irqs,
 	.main_clk	= "timer2_fck",
 	.prcm		= {
 		.omap4	= {
@@ -1763,16 +1348,10 @@ static struct omap_hwmod am33xx_timer2_h
 	},
 };
 
-static struct omap_hwmod_irq_info am33xx_timer3_irqs[] = {
-	{ .irq = 69 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_timer3_hwmod = {
 	.name		= "timer3",
 	.class		= &am33xx_timer_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_timer3_irqs,
 	.main_clk	= "timer3_fck",
 	.prcm		= {
 		.omap4	= {
@@ -1782,16 +1361,10 @@ static struct omap_hwmod am33xx_timer3_h
 	},
 };
 
-static struct omap_hwmod_irq_info am33xx_timer4_irqs[] = {
-	{ .irq = 92 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_timer4_hwmod = {
 	.name		= "timer4",
 	.class		= &am33xx_timer_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_timer4_irqs,
 	.main_clk	= "timer4_fck",
 	.prcm		= {
 		.omap4	= {
@@ -1801,16 +1374,10 @@ static struct omap_hwmod am33xx_timer4_h
 	},
 };
 
-static struct omap_hwmod_irq_info am33xx_timer5_irqs[] = {
-	{ .irq = 93 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_timer5_hwmod = {
 	.name		= "timer5",
 	.class		= &am33xx_timer_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_timer5_irqs,
 	.main_clk	= "timer5_fck",
 	.prcm		= {
 		.omap4	= {
@@ -1820,16 +1387,10 @@ static struct omap_hwmod am33xx_timer5_h
 	},
 };
 
-static struct omap_hwmod_irq_info am33xx_timer6_irqs[] = {
-	{ .irq = 94 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_timer6_hwmod = {
 	.name		= "timer6",
 	.class		= &am33xx_timer_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_timer6_irqs,
 	.main_clk	= "timer6_fck",
 	.prcm		= {
 		.omap4	= {
@@ -1839,16 +1400,10 @@ static struct omap_hwmod am33xx_timer6_h
 	},
 };
 
-static struct omap_hwmod_irq_info am33xx_timer7_irqs[] = {
-	{ .irq = 95 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_timer7_hwmod = {
 	.name		= "timer7",
 	.class		= &am33xx_timer_hwmod_class,
 	.clkdm_name	= "l4ls_clkdm",
-	.mpu_irqs	= am33xx_timer7_irqs,
 	.main_clk	= "timer7_fck",
 	.prcm		= {
 		.omap4	= {
@@ -1863,18 +1418,10 @@ static struct omap_hwmod_class am33xx_tp
 	.name		= "tpcc",
 };
 
-static struct omap_hwmod_irq_info am33xx_tpcc_irqs[] = {
-	{ .name	= "edma0", .irq = 12 + OMAP_INTC_START, },
-	{ .name = "edma0_mperr", .irq = 13 + OMAP_INTC_START, },
-	{ .name	= "edma0_err", .irq = 14 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_tpcc_hwmod = {
 	.name		= "tpcc",
 	.class		= &am33xx_tpcc_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
-	.mpu_irqs	= am33xx_tpcc_irqs,
 	.main_clk	= "l3_gclk",
 	.prcm		= {
 		.omap4	= {
@@ -1900,16 +1447,10 @@ static struct omap_hwmod_class am33xx_tp
 };
 
 /* tptc0 */
-static struct omap_hwmod_irq_info am33xx_tptc0_irqs[] = {
-	{ .irq = 112 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_tptc0_hwmod = {
 	.name		= "tptc0",
 	.class		= &am33xx_tptc_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
-	.mpu_irqs	= am33xx_tptc0_irqs,
 	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
 	.main_clk	= "l3_gclk",
 	.prcm		= {
@@ -1921,16 +1462,10 @@ static struct omap_hwmod am33xx_tptc0_hw
 };
 
 /* tptc1 */
-static struct omap_hwmod_irq_info am33xx_tptc1_irqs[] = {
-	{ .irq = 113 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_tptc1_hwmod = {
 	.name		= "tptc1",
 	.class		= &am33xx_tptc_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
-	.mpu_irqs	= am33xx_tptc1_irqs,
 	.flags		= (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
 	.main_clk	= "l3_gclk",
 	.prcm		= {
@@ -1942,16 +1477,10 @@ static struct omap_hwmod am33xx_tptc1_hw
 };
 
 /* tptc2 */
-static struct omap_hwmod_irq_info am33xx_tptc2_irqs[] = {
-	{ .irq = 114 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_tptc2_hwmod = {
 	.name		= "tptc2",
 	.class		= &am33xx_tptc_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
-	.mpu_irqs	= am33xx_tptc2_irqs,
 	.flags		= (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
 	.main_clk	= "l3_gclk",
 	.prcm		= {
@@ -1980,24 +1509,11 @@ static struct omap_hwmod_class uart_clas
 };
 
 /* uart1 */
-static struct omap_hwmod_dma_info uart1_edma_reqs[] = {
-	{ .name = "tx",	.dma_req = 26, },
-	{ .name = "rx",	.dma_req = 27, },
-	{ .dma_req = -1 }
-};
-
-static struct omap_hwmod_irq_info am33xx_uart1_irqs[] = {
-	{ .irq = 72 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_uart1_hwmod = {
 	.name		= "uart1",
 	.class		= &uart_class,
 	.clkdm_name	= "l4_wkup_clkdm",
-	.flags		= HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= am33xx_uart1_irqs,
-	.sdma_reqs	= uart1_edma_reqs,
+	.flags		= DEBUG_AM33XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.main_clk	= "dpll_per_m2_div4_wkupdm_ck",
 	.prcm		= {
 		.omap4	= {
@@ -2007,25 +1523,11 @@ static struct omap_hwmod am33xx_uart1_hw
 	},
 };
 
-/* uart2 */
-static struct omap_hwmod_dma_info uart2_edma_reqs[] = {
-	{ .name = "tx",	.dma_req = 28, },
-	{ .name = "rx",	.dma_req = 29, },
-	{ .dma_req = -1 }
-};
-
-static struct omap_hwmod_irq_info am33xx_uart2_irqs[] = {
-	{ .irq = 73 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_uart2_hwmod = {
 	.name		= "uart2",
 	.class		= &uart_class,
 	.clkdm_name	= "l4ls_clkdm",
 	.flags		= HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= am33xx_uart2_irqs,
-	.sdma_reqs	= uart2_edma_reqs,
 	.main_clk	= "dpll_per_m2_div4_ck",
 	.prcm		= {
 		.omap4	= {
@@ -2036,24 +1538,11 @@ static struct omap_hwmod am33xx_uart2_hw
 };
 
 /* uart3 */
-static struct omap_hwmod_dma_info uart3_edma_reqs[] = {
-	{ .name = "tx",	.dma_req = 30, },
-	{ .name = "rx",	.dma_req = 31, },
-	{ .dma_req = -1 }
-};
-
-static struct omap_hwmod_irq_info am33xx_uart3_irqs[] = {
-	{ .irq = 74 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_uart3_hwmod = {
 	.name		= "uart3",
 	.class		= &uart_class,
 	.clkdm_name	= "l4ls_clkdm",
 	.flags		= HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= am33xx_uart3_irqs,
-	.sdma_reqs	= uart3_edma_reqs,
 	.main_clk	= "dpll_per_m2_div4_ck",
 	.prcm		= {
 		.omap4	= {
@@ -2063,18 +1552,11 @@ static struct omap_hwmod am33xx_uart3_hw
 	},
 };
 
-static struct omap_hwmod_irq_info am33xx_uart4_irqs[] = {
-	{ .irq = 44 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_uart4_hwmod = {
 	.name		= "uart4",
 	.class		= &uart_class,
 	.clkdm_name	= "l4ls_clkdm",
 	.flags		= HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= am33xx_uart4_irqs,
-	.sdma_reqs	= uart1_edma_reqs,
 	.main_clk	= "dpll_per_m2_div4_ck",
 	.prcm		= {
 		.omap4	= {
@@ -2084,18 +1566,11 @@ static struct omap_hwmod am33xx_uart4_hw
 	},
 };
 
-static struct omap_hwmod_irq_info am33xx_uart5_irqs[] = {
-	{ .irq = 45 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_uart5_hwmod = {
 	.name		= "uart5",
 	.class		= &uart_class,
 	.clkdm_name	= "l4ls_clkdm",
 	.flags		= HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= am33xx_uart5_irqs,
-	.sdma_reqs	= uart1_edma_reqs,
 	.main_clk	= "dpll_per_m2_div4_ck",
 	.prcm		= {
 		.omap4	= {
@@ -2105,18 +1580,11 @@ static struct omap_hwmod am33xx_uart5_hw
 	},
 };
 
-static struct omap_hwmod_irq_info am33xx_uart6_irqs[] = {
-	{ .irq = 46 + OMAP_INTC_START, },
-	{ .irq = -1 },
-};
-
 static struct omap_hwmod am33xx_uart6_hwmod = {
 	.name		= "uart6",
 	.class		= &uart_class,
 	.clkdm_name	= "l4ls_clkdm",
 	.flags		= HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= am33xx_uart6_irqs,
-	.sdma_reqs	= uart1_edma_reqs,
 	.main_clk	= "dpll_per_m2_div4_ck",
 	.prcm		= {
 		.omap4	= {
@@ -2180,18 +1648,10 @@ static struct omap_hwmod_class am33xx_us
 	.sysc		= &am33xx_usbhsotg_sysc,
 };
 
-static struct omap_hwmod_irq_info am33xx_usbss_mpu_irqs[] = {
-	{ .name = "usbss-irq", .irq = 17 + OMAP_INTC_START, },
-	{ .name = "musb0-irq", .irq = 18 + OMAP_INTC_START, },
-	{ .name = "musb1-irq", .irq = 19 + OMAP_INTC_START, },
-	{ .irq = -1, },
-};
-
 static struct omap_hwmod am33xx_usbss_hwmod = {
 	.name		= "usb_otg_hs",
 	.class		= &am33xx_usbotg_class,
 	.clkdm_name	= "l3s_clkdm",
-	.mpu_irqs	= am33xx_usbss_mpu_irqs,
 	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
 	.main_clk	= "usbotg_fck",
 	.prcm		= {
@@ -2207,14 +1667,6 @@ static struct omap_hwmod am33xx_usbss_hw
  * Interfaces
  */
 
-/* l4 fw -> emif fw */
-static struct omap_hwmod_ocp_if am33xx_l4_fw__emif_fw = {
-	.master		= &am33xx_l4_fw_hwmod,
-	.slave		= &am33xx_emif_fw_hwmod,
-	.clk		= "l4fw_gclk",
-	.user		= OCP_USER_MPU,
-};
-
 static struct omap_hwmod_addr_space am33xx_emif_addrs[] = {
 	{
 		.pa_start	= 0x4c000000,
@@ -2272,14 +1724,6 @@ static struct omap_hwmod_ocp_if am33xx_l
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l3 s -> l4 fw */
-static struct omap_hwmod_ocp_if am33xx_l3_s__l4_fw = {
-	.master		= &am33xx_l3_s_hwmod,
-	.slave		= &am33xx_l4_fw_hwmod,
-	.clk		= "l3s_gclk",
-	.user		= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3 main -> l3 instr */
 static struct omap_hwmod_ocp_if am33xx_l3_main__l3_instr = {
 	.master		= &am33xx_l3_main_hwmod,
@@ -2329,261 +1773,114 @@ static struct omap_hwmod_ocp_if am33xx_g
 };
 
 /* l4 wkup -> wkup m3 */
-static struct omap_hwmod_addr_space am33xx_wkup_m3_addrs[] = {
-	{
-		.name		= "umem",
-		.pa_start	= 0x44d00000,
-		.pa_end		= 0x44d00000 + SZ_16K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{
-		.name		= "dmem",
-		.pa_start	= 0x44d80000,
-		.pa_end		= 0x44d80000 + SZ_8K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__wkup_m3 = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_wkup_m3_hwmod,
 	.clk		= "dpll_core_m4_div2_ck",
-	.addr		= am33xx_wkup_m3_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* l4 hs -> pru-icss */
-static struct omap_hwmod_addr_space am33xx_pruss_addrs[] = {
-	{
-		.pa_start	= 0x4a300000,
-		.pa_end		= 0x4a300000 + SZ_512K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_hs__pruss = {
 	.master		= &am33xx_l4_hs_hwmod,
 	.slave		= &am33xx_pruss_hwmod,
 	.clk		= "dpll_core_m4_ck",
-	.addr		= am33xx_pruss_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* l3 main -> gfx */
-static struct omap_hwmod_addr_space am33xx_gfx_addrs[] = {
-	{
-		.pa_start	= 0x56000000,
-		.pa_end		= 0x56000000 + SZ_16M - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l3_main__gfx = {
 	.master		= &am33xx_l3_main_hwmod,
 	.slave		= &am33xx_gfx_hwmod,
 	.clk		= "dpll_core_m4_ck",
-	.addr		= am33xx_gfx_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* l4 wkup -> smartreflex0 */
-static struct omap_hwmod_addr_space am33xx_smartreflex0_addrs[] = {
-	{
-		.pa_start	= 0x44e37000,
-		.pa_end		= 0x44e37000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex0 = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_smartreflex0_hwmod,
 	.clk		= "dpll_core_m4_div2_ck",
-	.addr		= am33xx_smartreflex0_addrs,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 wkup -> smartreflex1 */
-static struct omap_hwmod_addr_space am33xx_smartreflex1_addrs[] = {
-	{
-		.pa_start	= 0x44e39000,
-		.pa_end		= 0x44e39000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__smartreflex1 = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_smartreflex1_hwmod,
 	.clk		= "dpll_core_m4_div2_ck",
-	.addr		= am33xx_smartreflex1_addrs,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 wkup -> control */
-static struct omap_hwmod_addr_space am33xx_control_addrs[] = {
-	{
-		.pa_start	= 0x44e10000,
-		.pa_end		= 0x44e10000 + SZ_8K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_control_hwmod,
 	.clk		= "dpll_core_m4_div2_ck",
-	.addr		= am33xx_control_addrs,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 wkup -> rtc */
-static struct omap_hwmod_addr_space am33xx_rtc_addrs[] = {
-	{
-		.pa_start	= 0x44e3e000,
-		.pa_end		= 0x44e3e000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_rtc_hwmod,
 	.clk		= "clkdiv32k_ick",
-	.addr		= am33xx_rtc_addrs,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 per/ls -> DCAN0 */
-static struct omap_hwmod_addr_space am33xx_dcan0_addrs[] = {
-	{
-		.pa_start	= 0x481CC000,
-		.pa_end		= 0x481CC000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_per__dcan0 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_dcan0_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_dcan0_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* l4 per/ls -> DCAN1 */
-static struct omap_hwmod_addr_space am33xx_dcan1_addrs[] = {
-	{
-		.pa_start	= 0x481D0000,
-		.pa_end		= 0x481D0000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_per__dcan1 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_dcan1_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_dcan1_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* l4 per/ls -> GPIO2 */
-static struct omap_hwmod_addr_space am33xx_gpio1_addrs[] = {
-	{
-		.pa_start	= 0x4804C000,
-		.pa_end		= 0x4804C000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_per__gpio1 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_gpio1_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_gpio1_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* l4 per/ls -> gpio3 */
-static struct omap_hwmod_addr_space am33xx_gpio2_addrs[] = {
-	{
-		.pa_start	= 0x481AC000,
-		.pa_end		= 0x481AC000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_per__gpio2 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_gpio2_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_gpio2_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* l4 per/ls -> gpio4 */
-static struct omap_hwmod_addr_space am33xx_gpio3_addrs[] = {
-	{
-		.pa_start	= 0x481AE000,
-		.pa_end		= 0x481AE000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_per__gpio3 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_gpio3_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_gpio3_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
 /* L4 WKUP -> I2C1 */
-static struct omap_hwmod_addr_space am33xx_i2c1_addr_space[] = {
-	{
-		.pa_start	= 0x44E0B000,
-		.pa_end		= 0x44E0B000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__i2c1 = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_i2c1_hwmod,
 	.clk		= "dpll_core_m4_div2_ck",
-	.addr		= am33xx_i2c1_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* L4 WKUP -> GPIO1 */
-static struct omap_hwmod_addr_space am33xx_gpio0_addrs[] = {
-	{
-		.pa_start	= 0x44E07000,
-		.pa_end		= 0x44E07000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__gpio0 = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_gpio0_hwmod,
 	.clk		= "dpll_core_m4_div2_ck",
-	.addr		= am33xx_gpio0_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -2605,41 +1902,16 @@ static struct omap_hwmod_ocp_if am33xx_l
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_cpgmac0_addr_space[] = {
-	/* cpsw ss */
-	{
-		.pa_start	= 0x4a100000,
-		.pa_end		= 0x4a100000 + SZ_2K - 1,
-	},
-	/* cpsw wr */
-	{
-		.pa_start	= 0x4a101200,
-		.pa_end		= 0x4a101200 + SZ_256 - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_hs__cpgmac0 = {
 	.master		= &am33xx_l4_hs_hwmod,
 	.slave		= &am33xx_cpgmac0_hwmod,
 	.clk		= "cpsw_125mhz_gclk",
-	.addr		= am33xx_cpgmac0_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_mdio_addr_space[] = {
-	{
-		.pa_start	= 0x4A101000,
-		.pa_end		= 0x4A101000 + SZ_256 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = {
 	.master		= &am33xx_cpgmac0_hwmod,
 	.slave		= &am33xx_mdio_hwmod,
-	.addr		= am33xx_mdio_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
@@ -2677,51 +1949,24 @@ static struct omap_hwmod_ocp_if am33xx_l
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_ecap0_addr_space[] = {
-	{
-		.pa_start	= 0x48300100,
-		.pa_end		= 0x48300100 + SZ_128 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = {
 	.master		= &am33xx_epwmss0_hwmod,
 	.slave		= &am33xx_ecap0_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_ecap0_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_eqep0_addr_space[] = {
-	{
-		.pa_start	= 0x48300180,
-		.pa_end		= 0x48300180 + SZ_128 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = {
 	.master		= &am33xx_epwmss0_hwmod,
 	.slave		= &am33xx_eqep0_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_eqep0_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_ehrpwm0_addr_space[] = {
-	{
-		.pa_start	= 0x48300200,
-		.pa_end		= 0x48300200 + SZ_128 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = {
 	.master		= &am33xx_epwmss0_hwmod,
 	.slave		= &am33xx_ehrpwm0_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_ehrpwm0_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
@@ -2743,51 +1988,24 @@ static struct omap_hwmod_ocp_if am33xx_l
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_ecap1_addr_space[] = {
-	{
-		.pa_start	= 0x48302100,
-		.pa_end		= 0x48302100 + SZ_128 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = {
 	.master		= &am33xx_epwmss1_hwmod,
 	.slave		= &am33xx_ecap1_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_ecap1_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_eqep1_addr_space[] = {
-	{
-		.pa_start	= 0x48302180,
-		.pa_end		= 0x48302180 + SZ_128 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = {
 	.master		= &am33xx_epwmss1_hwmod,
 	.slave		= &am33xx_eqep1_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_eqep1_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_ehrpwm1_addr_space[] = {
-	{
-		.pa_start	= 0x48302200,
-		.pa_end		= 0x48302200 + SZ_128 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = {
 	.master		= &am33xx_epwmss1_hwmod,
 	.slave		= &am33xx_ehrpwm1_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_ehrpwm1_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
@@ -2808,51 +2026,24 @@ static struct omap_hwmod_ocp_if am33xx_l
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_ecap2_addr_space[] = {
-	{
-		.pa_start	= 0x48304100,
-		.pa_end		= 0x48304100 + SZ_128 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = {
 	.master		= &am33xx_epwmss2_hwmod,
 	.slave		= &am33xx_ecap2_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_ecap2_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_eqep2_addr_space[] = {
-	{
-		.pa_start	= 0x48304180,
-		.pa_end		= 0x48304180 + SZ_128 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = {
 	.master		= &am33xx_epwmss2_hwmod,
 	.slave		= &am33xx_eqep2_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_eqep2_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_ehrpwm2_addr_space[] = {
-	{
-		.pa_start	= 0x48304200,
-		.pa_end		= 0x48304200 + SZ_128 - 1,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = {
 	.master		= &am33xx_epwmss2_hwmod,
 	.slave		= &am33xx_ehrpwm2_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_ehrpwm2_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
@@ -2875,37 +2066,17 @@ static struct omap_hwmod_ocp_if am33xx_l
 };
 
 /* i2c2 */
-static struct omap_hwmod_addr_space am33xx_i2c2_addr_space[] = {
-	{
-		.pa_start	= 0x4802A000,
-		.pa_end		= 0x4802A000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_per__i2c2 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_i2c2_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_i2c2_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space am33xx_i2c3_addr_space[] = {
-	{
-		.pa_start	= 0x4819C000,
-		.pa_end		= 0x4819C000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_per__i2c3 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_i2c3_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_i2c3_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
@@ -2945,20 +2116,10 @@ static struct omap_hwmod_ocp_if am33xx_l
 };
 
 /* l4 ls -> spinlock */
-static struct omap_hwmod_addr_space am33xx_spinlock_addrs[] = {
-	{
-		.pa_start	= 0x480Ca000,
-		.pa_end		= 0x480Ca000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_spinlock_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_spinlock_addrs,
 	.user		= OCP_USER_MPU,
 };
 
@@ -2980,24 +2141,6 @@ static struct omap_hwmod_ocp_if am33xx_l
 	.user		= OCP_USER_MPU,
 };
 
-/* l3 s -> mcasp0 data */
-static struct omap_hwmod_addr_space am33xx_mcasp0_data_addr_space[] = {
-	{
-		.pa_start	= 0x46000000,
-		.pa_end		= 0x46000000 + SZ_4M - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l3_s__mcasp0_data = {
-	.master		= &am33xx_l3_s_hwmod,
-	.slave		= &am33xx_mcasp0_hwmod,
-	.clk		= "l3s_gclk",
-	.addr		= am33xx_mcasp0_data_addr_space,
-	.user		= OCP_USER_SDMA,
-};
-
 /* l4 ls -> mcasp1 */
 static struct omap_hwmod_addr_space am33xx_mcasp1_addr_space[] = {
 	{
@@ -3016,24 +2159,6 @@ static struct omap_hwmod_ocp_if am33xx_l
 	.user		= OCP_USER_MPU,
 };
 
-/* l3 s -> mcasp1 data */
-static struct omap_hwmod_addr_space am33xx_mcasp1_data_addr_space[] = {
-	{
-		.pa_start	= 0x46400000,
-		.pa_end		= 0x46400000 + SZ_4M - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
-static struct omap_hwmod_ocp_if am33xx_l3_s__mcasp1_data = {
-	.master		= &am33xx_l3_s_hwmod,
-	.slave		= &am33xx_mcasp1_hwmod,
-	.clk		= "l3s_gclk",
-	.addr		= am33xx_mcasp1_data_addr_space,
-	.user		= OCP_USER_SDMA,
-};
-
 /* l4 ls -> mmc0 */
 static struct omap_hwmod_addr_space am33xx_mmc0_addr_space[] = {
 	{
@@ -3089,182 +2214,82 @@ static struct omap_hwmod_ocp_if am33xx_l
 };
 
 /* l4 ls -> mcspi0 */
-static struct omap_hwmod_addr_space am33xx_mcspi0_addr_space[] = {
-	{
-		.pa_start	= 0x48030000,
-		.pa_end		= 0x48030000 + SZ_1K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_spi0_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_mcspi0_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 ls -> mcspi1 */
-static struct omap_hwmod_addr_space am33xx_mcspi1_addr_space[] = {
-	{
-		.pa_start	= 0x481A0000,
-		.pa_end		= 0x481A0000 + SZ_1K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_spi1_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_mcspi1_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 wkup -> timer1 */
-static struct omap_hwmod_addr_space am33xx_timer1_addr_space[] = {
-	{
-		.pa_start	= 0x44E31000,
-		.pa_end		= 0x44E31000 + SZ_1K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_timer1_hwmod,
 	.clk		= "dpll_core_m4_div2_ck",
-	.addr		= am33xx_timer1_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 per -> timer2 */
-static struct omap_hwmod_addr_space am33xx_timer2_addr_space[] = {
-	{
-		.pa_start	= 0x48040000,
-		.pa_end		= 0x48040000 + SZ_1K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_timer2_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_timer2_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 per -> timer3 */
-static struct omap_hwmod_addr_space am33xx_timer3_addr_space[] = {
-	{
-		.pa_start	= 0x48042000,
-		.pa_end		= 0x48042000 + SZ_1K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__timer3 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_timer3_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_timer3_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 per -> timer4 */
-static struct omap_hwmod_addr_space am33xx_timer4_addr_space[] = {
-	{
-		.pa_start	= 0x48044000,
-		.pa_end		= 0x48044000 + SZ_1K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__timer4 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_timer4_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_timer4_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 per -> timer5 */
-static struct omap_hwmod_addr_space am33xx_timer5_addr_space[] = {
-	{
-		.pa_start	= 0x48046000,
-		.pa_end		= 0x48046000 + SZ_1K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__timer5 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_timer5_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_timer5_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 per -> timer6 */
-static struct omap_hwmod_addr_space am33xx_timer6_addr_space[] = {
-	{
-		.pa_start	= 0x48048000,
-		.pa_end		= 0x48048000 + SZ_1K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__timer6 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_timer6_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_timer6_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 per -> timer7 */
-static struct omap_hwmod_addr_space am33xx_timer7_addr_space[] = {
-	{
-		.pa_start	= 0x4804A000,
-		.pa_end		= 0x4804A000 + SZ_1K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__timer7 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_timer7_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_timer7_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l3 main -> tpcc */
-static struct omap_hwmod_addr_space am33xx_tpcc_addr_space[] = {
-	{
-		.pa_start	= 0x49000000,
-		.pa_end		= 0x49000000 + SZ_32K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l3_main__tpcc = {
 	.master		= &am33xx_l3_main_hwmod,
 	.slave		= &am33xx_tpcc_hwmod,
 	.clk		= "l3_gclk",
-	.addr		= am33xx_tpcc_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
@@ -3323,160 +2348,67 @@ static struct omap_hwmod_ocp_if am33xx_l
 };
 
 /* l4 wkup -> uart1 */
-static struct omap_hwmod_addr_space am33xx_uart1_addr_space[] = {
-	{
-		.pa_start	= 0x44E09000,
-		.pa_end		= 0x44E09000 + SZ_8K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__uart1 = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_uart1_hwmod,
 	.clk		= "dpll_core_m4_div2_ck",
-	.addr		= am33xx_uart1_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 ls -> uart2 */
-static struct omap_hwmod_addr_space am33xx_uart2_addr_space[] = {
-	{
-		.pa_start	= 0x48022000,
-		.pa_end		= 0x48022000 + SZ_8K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__uart2 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_uart2_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_uart2_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 ls -> uart3 */
-static struct omap_hwmod_addr_space am33xx_uart3_addr_space[] = {
-	{
-		.pa_start	= 0x48024000,
-		.pa_end		= 0x48024000 + SZ_8K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__uart3 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_uart3_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_uart3_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 ls -> uart4 */
-static struct omap_hwmod_addr_space am33xx_uart4_addr_space[] = {
-	{
-		.pa_start	= 0x481A6000,
-		.pa_end		= 0x481A6000 + SZ_8K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__uart4 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_uart4_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_uart4_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 ls -> uart5 */
-static struct omap_hwmod_addr_space am33xx_uart5_addr_space[] = {
-	{
-		.pa_start	= 0x481A8000,
-		.pa_end		= 0x481A8000 + SZ_8K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__uart5 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_uart5_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_uart5_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 ls -> uart6 */
-static struct omap_hwmod_addr_space am33xx_uart6_addr_space[] = {
-	{
-		.pa_start	= 0x481aa000,
-		.pa_end		= 0x481aa000 + SZ_8K - 1,
-		.flags		= ADDR_TYPE_RT,
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_ls__uart6 = {
 	.master		= &am33xx_l4_ls_hwmod,
 	.slave		= &am33xx_uart6_hwmod,
 	.clk		= "l4ls_gclk",
-	.addr		= am33xx_uart6_addr_space,
 	.user		= OCP_USER_MPU,
 };
 
 /* l4 wkup -> wd_timer1 */
-static struct omap_hwmod_addr_space am33xx_wd_timer1_addrs[] = {
-	{
-		.pa_start	= 0x44e35000,
-		.pa_end		= 0x44e35000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__wd_timer1 = {
 	.master		= &am33xx_l4_wkup_hwmod,
 	.slave		= &am33xx_wd_timer1_hwmod,
 	.clk		= "dpll_core_m4_div2_ck",
-	.addr		= am33xx_wd_timer1_addrs,
 	.user		= OCP_USER_MPU,
 };
 
 /* usbss */
 /* l3 s -> USBSS interface */
-static struct omap_hwmod_addr_space am33xx_usbss_addr_space[] = {
-	{
-		.name		= "usbss",
-		.pa_start	= 0x47400000,
-		.pa_end		= 0x47400000 + SZ_4K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{
-		.name		= "musb0",
-		.pa_start	= 0x47401000,
-		.pa_end		= 0x47401000 + SZ_2K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{
-		.name		= "musb1",
-		.pa_start	= 0x47401800,
-		.pa_end		= 0x47401800 + SZ_2K - 1,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = {
 	.master		= &am33xx_l3_s_hwmod,
 	.slave		= &am33xx_usbss_hwmod,
 	.clk		= "l3s_gclk",
-	.addr		= am33xx_usbss_addr_space,
 	.user		= OCP_USER_MPU,
 	.flags		= OCPIF_SWSUP_IDLE,
 };
@@ -3525,13 +2457,11 @@ static struct omap_hwmod_ocp_if am33xx_l
 };
 
 static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
-	&am33xx_l4_fw__emif_fw,
 	&am33xx_l3_main__emif,
 	&am33xx_mpu__l3_main,
 	&am33xx_mpu__prcm,
 	&am33xx_l3_s__l4_ls,
 	&am33xx_l3_s__l4_wkup,
-	&am33xx_l3_s__l4_fw,
 	&am33xx_l3_main__l4_hs,
 	&am33xx_l3_main__l3_s,
 	&am33xx_l3_main__l3_instr,
@@ -3561,9 +2491,7 @@ static struct omap_hwmod_ocp_if *am33xx_
 	&am33xx_l4_per__i2c3,
 	&am33xx_l4_per__mailbox,
 	&am33xx_l4_ls__mcasp0,
-	&am33xx_l3_s__mcasp0_data,
 	&am33xx_l4_ls__mcasp1,
-	&am33xx_l3_s__mcasp1_data,
 	&am33xx_l4_ls__mmc0,
 	&am33xx_l4_ls__mmc1,
 	&am33xx_l3_s__mmc2,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/platform_data/iommu-omap.h>
+#include <linux/platform_data/mailbox-omap.h>
 #include <plat/dmtimer.h>
 
 #include "am35xx.h"
@@ -35,7 +36,6 @@
 #include "prm-regbits-34xx.h"
 #include "cm-regbits-34xx.h"
 
-#include "dma.h"
 #include "i2c.h"
 #include "mmc.h"
 #include "wd_timer.h"
@@ -490,7 +490,7 @@ static struct omap_hwmod omap3xxx_uart1_
 	.mpu_irqs	= omap2_uart1_mpu_irqs,
 	.sdma_reqs	= omap2_uart1_sdma_reqs,
 	.main_clk	= "uart1_fck",
-	.flags		= HWMOD_SWSUP_SIDLE_ACT,
+	.flags		= DEBUG_TI81XXUART1_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.prcm		= {
 		.omap2 = {
 			.module_offs = CORE_MOD,
@@ -509,7 +509,7 @@ static struct omap_hwmod omap3xxx_uart2_
 	.mpu_irqs	= omap2_uart2_mpu_irqs,
 	.sdma_reqs	= omap2_uart2_sdma_reqs,
 	.main_clk	= "uart2_fck",
-	.flags		= HWMOD_SWSUP_SIDLE_ACT,
+	.flags		= DEBUG_TI81XXUART2_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.prcm		= {
 		.omap2 = {
 			.module_offs = CORE_MOD,
@@ -528,7 +528,8 @@ static struct omap_hwmod omap3xxx_uart3_
 	.mpu_irqs	= omap2_uart3_mpu_irqs,
 	.sdma_reqs	= omap2_uart3_sdma_reqs,
 	.main_clk	= "uart3_fck",
-	.flags		= HWMOD_SWSUP_SIDLE_ACT,
+	.flags		= DEBUG_OMAP3UART3_FLAGS | DEBUG_TI81XXUART3_FLAGS |
+				HWMOD_SWSUP_SIDLE_ACT,
 	.prcm		= {
 		.omap2 = {
 			.module_offs = OMAP3430_PER_MOD,
@@ -548,8 +549,8 @@ static struct omap_hwmod_irq_info uart4_
 };
 
 static struct omap_hwmod_dma_info uart4_sdma_reqs[] = {
-	{ .name = "rx",	.dma_req = OMAP36XX_DMA_UART4_RX, },
-	{ .name = "tx",	.dma_req = OMAP36XX_DMA_UART4_TX, },
+	{ .name = "rx",	.dma_req = 82, },
+	{ .name = "tx",	.dma_req = 81, },
 	{ .dma_req = -1 }
 };
 
@@ -558,7 +559,7 @@ static struct omap_hwmod omap36xx_uart4_
 	.mpu_irqs	= uart4_mpu_irqs,
 	.sdma_reqs	= uart4_sdma_reqs,
 	.main_clk	= "uart4_fck",
-	.flags		= HWMOD_SWSUP_SIDLE_ACT,
+	.flags		= DEBUG_OMAP3UART4_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.prcm		= {
 		.omap2 = {
 			.module_offs = OMAP3430_PER_MOD,
@@ -577,8 +578,8 @@ static struct omap_hwmod_irq_info am35xx
 };
 
 static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = {
-	{ .name = "rx", .dma_req = AM35XX_DMA_UART4_RX, },
-	{ .name = "tx", .dma_req = AM35XX_DMA_UART4_TX, },
+	{ .name = "rx", .dma_req = 55, },
+	{ .name = "tx", .dma_req = 54, },
 	{ .dma_req = -1 }
 };
 
@@ -857,8 +858,8 @@ static struct omap_hwmod_irq_info i2c3_m
 };
 
 static struct omap_hwmod_dma_info i2c3_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = OMAP34XX_DMA_I2C3_TX },
-	{ .name = "rx", .dma_req = OMAP34XX_DMA_I2C3_RX },
+	{ .name = "tx", .dma_req = 25 },
+	{ .name = "rx", .dma_req = 26 },
 	{ .dma_req = -1 }
 };
 
@@ -1505,6 +1506,17 @@ static struct omap_hwmod_class omap3xxx_
 	.sysc = &omap3xxx_mailbox_sysc,
 };
 
+static struct omap_mbox_dev_info omap3xxx_mailbox_info[] = {
+	{ .name = "dsp", .tx_id = 0, .rx_id = 1 },
+};
+
+static struct omap_mbox_pdata omap3xxx_mailbox_attrs = {
+	.num_users	= 2,
+	.num_fifos	= 2,
+	.info_cnt	= ARRAY_SIZE(omap3xxx_mailbox_info),
+	.info		= omap3xxx_mailbox_info,
+};
+
 static struct omap_hwmod_irq_info omap3xxx_mailbox_irqs[] = {
 	{ .irq = 26 + OMAP_INTC_START, },
 	{ .irq = -1 },
@@ -1524,6 +1536,7 @@ static struct omap_hwmod omap3xxx_mailbo
 			.idlest_idle_bit = OMAP3430_ST_MAILBOXES_SHIFT,
 		},
 	},
+	.dev_attr	= &omap3xxx_mailbox_attrs,
 };
 
 /*
@@ -3581,7 +3594,7 @@ static struct omap_hwmod_irq_info omap3_
 };
 
 static struct omap_hwmod_dma_info omap3_sham_sdma_reqs[] = {
-	{ .name = "rx", .dma_req = OMAP34XX_DMA_SHA1MD5_RX, },
+	{ .name = "rx", .dma_req = 69, },
 	{ .dma_req = -1 }
 };
 
@@ -3642,8 +3655,8 @@ static struct omap_hwmod_class omap3xxx_
 };
 
 static struct omap_hwmod_dma_info omap3_aes_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = OMAP34XX_DMA_AES2_TX, },
-	{ .name = "rx", .dma_req = OMAP34XX_DMA_AES2_RX, },
+	{ .name = "tx", .dma_req = 65, },
+	{ .name = "rx", .dma_req = 66, },
 	{ .dma_req = -1 }
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_44xx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_44xx_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_44xx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,8 @@
  * with the public linux-omap@vger.kernel.org mailing list and the
  * authors above to ensure that the autogeneration scripts are kept
  * up-to-date with the file contents.
+ * Note that this file is currently not in sync with autogeneration scripts.
+ * The above note to be removed, once it is synced up.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -21,7 +23,6 @@
 #include <linux/io.h>
 #include <linux/platform_data/gpio-omap.h>
 #include <linux/power/smartreflex.h>
-#include <linux/platform_data/omap_ocp2scp.h>
 #include <linux/i2c-omap.h>
 
 #include <linux/omap-dma.h>
@@ -52,27 +53,6 @@
  */
 
 /*
- * 'c2c_target_fw' class
- * instance(s): c2c_target_fw
- */
-static struct omap_hwmod_class omap44xx_c2c_target_fw_hwmod_class = {
-	.name	= "c2c_target_fw",
-};
-
-/* c2c_target_fw */
-static struct omap_hwmod omap44xx_c2c_target_fw_hwmod = {
-	.name		= "c2c_target_fw",
-	.class		= &omap44xx_c2c_target_fw_hwmod_class,
-	.clkdm_name	= "d2d_clkdm",
-	.prcm = {
-		.omap4 = {
-			.clkctrl_offs = OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET,
-			.context_offs = OMAP4_RM_D2D_SAD2D_FW_CONTEXT_OFFSET,
-		},
-	},
-};
-
-/*
  * 'dmm' class
  * instance(s): dmm
  */
@@ -81,16 +61,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* dmm */
-static struct omap_hwmod_irq_info omap44xx_dmm_irqs[] = {
-	{ .irq = 113 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_dmm_hwmod = {
 	.name		= "dmm",
 	.class		= &omap44xx_dmm_hwmod_class,
 	.clkdm_name	= "l3_emif_clkdm",
-	.mpu_irqs	= omap44xx_dmm_irqs,
 	.prcm = {
 		.omap4 = {
 			.clkctrl_offs = OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET,
@@ -100,27 +74,6 @@ static struct omap_hwmod omap44xx_dmm_hw
 };
 
 /*
- * 'emif_fw' class
- * instance(s): emif_fw
- */
-static struct omap_hwmod_class omap44xx_emif_fw_hwmod_class = {
-	.name	= "emif_fw",
-};
-
-/* emif_fw */
-static struct omap_hwmod omap44xx_emif_fw_hwmod = {
-	.name		= "emif_fw",
-	.class		= &omap44xx_emif_fw_hwmod_class,
-	.clkdm_name	= "l3_emif_clkdm",
-	.prcm = {
-		.omap4 = {
-			.clkctrl_offs = OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET,
-			.context_offs = OMAP4_RM_MEMIF_EMIF_FW_CONTEXT_OFFSET,
-		},
-	},
-};
-
-/*
  * 'l3' class
  * instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3
  */
@@ -143,17 +96,10 @@ static struct omap_hwmod omap44xx_l3_ins
 };
 
 /* l3_main_1 */
-static struct omap_hwmod_irq_info omap44xx_l3_main_1_irqs[] = {
-	{ .name = "dbg_err", .irq = 9 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "app_err", .irq = 10 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
 	.name		= "l3_main_1",
 	.class		= &omap44xx_l3_hwmod_class,
 	.clkdm_name	= "l3_1_clkdm",
-	.mpu_irqs	= omap44xx_l3_main_1_irqs,
 	.prcm = {
 		.omap4 = {
 			.clkctrl_offs = OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET,
@@ -326,29 +272,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* aess */
-static struct omap_hwmod_irq_info omap44xx_aess_irqs[] = {
-	{ .irq = 99 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_aess_sdma_reqs[] = {
-	{ .name = "fifo0", .dma_req = 100 + OMAP44XX_DMA_REQ_START },
-	{ .name = "fifo1", .dma_req = 101 + OMAP44XX_DMA_REQ_START },
-	{ .name = "fifo2", .dma_req = 102 + OMAP44XX_DMA_REQ_START },
-	{ .name = "fifo3", .dma_req = 103 + OMAP44XX_DMA_REQ_START },
-	{ .name = "fifo4", .dma_req = 104 + OMAP44XX_DMA_REQ_START },
-	{ .name = "fifo5", .dma_req = 105 + OMAP44XX_DMA_REQ_START },
-	{ .name = "fifo6", .dma_req = 106 + OMAP44XX_DMA_REQ_START },
-	{ .name = "fifo7", .dma_req = 107 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_aess_hwmod = {
 	.name		= "aess",
 	.class		= &omap44xx_aess_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_aess_irqs,
-	.sdma_reqs	= omap44xx_aess_sdma_reqs,
 	.main_clk	= "aess_fclk",
 	.prcm = {
 		.omap4 = {
@@ -371,22 +298,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* c2c */
-static struct omap_hwmod_irq_info omap44xx_c2c_irqs[] = {
-	{ .irq = 88 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_c2c_sdma_reqs[] = {
-	{ .dma_req = 68 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_c2c_hwmod = {
 	.name		= "c2c",
 	.class		= &omap44xx_c2c_hwmod_class,
 	.clkdm_name	= "d2d_clkdm",
-	.mpu_irqs	= omap44xx_c2c_irqs,
-	.sdma_reqs	= omap44xx_c2c_sdma_reqs,
 	.prcm = {
 		.omap4 = {
 			.clkctrl_offs = OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET,
@@ -449,16 +364,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* ctrl_module_core */
-static struct omap_hwmod_irq_info omap44xx_ctrl_module_core_irqs[] = {
-	{ .irq = 8 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_ctrl_module_core_hwmod = {
 	.name		= "ctrl_module_core",
 	.class		= &omap44xx_ctrl_module_hwmod_class,
 	.clkdm_name	= "l4_cfg_clkdm",
-	.mpu_irqs	= omap44xx_ctrl_module_core_irqs,
 	.prcm = {
 		.omap4 = {
 			.flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
@@ -601,22 +510,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* dmic */
-static struct omap_hwmod_irq_info omap44xx_dmic_irqs[] = {
-	{ .irq = 114 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_dmic_sdma_reqs[] = {
-	{ .dma_req = 66 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_dmic_hwmod = {
 	.name		= "dmic",
 	.class		= &omap44xx_dmic_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_dmic_irqs,
-	.sdma_reqs	= omap44xx_dmic_sdma_reqs,
 	.main_clk	= "func_dmic_abe_gfclk",
 	.prcm = {
 		.omap4 = {
@@ -637,11 +534,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* dsp */
-static struct omap_hwmod_irq_info omap44xx_dsp_irqs[] = {
-	{ .irq = 28 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_rst_info omap44xx_dsp_resets[] = {
 	{ .name = "dsp", .rst_shift = 0 },
 };
@@ -650,7 +542,6 @@ static struct omap_hwmod omap44xx_dsp_hw
 	.name		= "dsp",
 	.class		= &omap44xx_dsp_hwmod_class,
 	.clkdm_name	= "tesla_clkdm",
-	.mpu_irqs	= omap44xx_dsp_irqs,
 	.rst_lines	= omap44xx_dsp_resets,
 	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_dsp_resets),
 	.main_clk	= "dpll_iva_m4x2_ck",
@@ -992,16 +883,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* elm */
-static struct omap_hwmod_irq_info omap44xx_elm_irqs[] = {
-	{ .irq = 4 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_elm_hwmod = {
 	.name		= "elm",
 	.class		= &omap44xx_elm_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_elm_irqs,
 	.prcm = {
 		.omap4 = {
 			.clkctrl_offs = OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET,
@@ -1025,17 +910,11 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* emif1 */
-static struct omap_hwmod_irq_info omap44xx_emif1_irqs[] = {
-	{ .irq = 110 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_emif1_hwmod = {
 	.name		= "emif1",
 	.class		= &omap44xx_emif_hwmod_class,
 	.clkdm_name	= "l3_emif_clkdm",
 	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
-	.mpu_irqs	= omap44xx_emif1_irqs,
 	.main_clk	= "ddrphy_ck",
 	.prcm = {
 		.omap4 = {
@@ -1047,17 +926,11 @@ static struct omap_hwmod omap44xx_emif1_
 };
 
 /* emif2 */
-static struct omap_hwmod_irq_info omap44xx_emif2_irqs[] = {
-	{ .irq = 111 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_emif2_hwmod = {
 	.name		= "emif2",
 	.class		= &omap44xx_emif_hwmod_class,
 	.clkdm_name	= "l3_emif_clkdm",
 	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
-	.mpu_irqs	= omap44xx_emif2_irqs,
 	.main_clk	= "ddrphy_ck",
 	.prcm = {
 		.omap4 = {
@@ -1098,16 +971,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* fdif */
-static struct omap_hwmod_irq_info omap44xx_fdif_irqs[] = {
-	{ .irq = 69 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_fdif_hwmod = {
 	.name		= "fdif",
 	.class		= &omap44xx_fdif_hwmod_class,
 	.clkdm_name	= "iss_clkdm",
-	.mpu_irqs	= omap44xx_fdif_irqs,
 	.main_clk	= "fdif_fck",
 	.prcm = {
 		.omap4 = {
@@ -1148,11 +1015,6 @@ static struct omap_gpio_dev_attr gpio_de
 };
 
 /* gpio1 */
-static struct omap_hwmod_irq_info omap44xx_gpio1_irqs[] = {
-	{ .irq = 29 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio1_dbclk" },
 };
@@ -1161,7 +1023,6 @@ static struct omap_hwmod omap44xx_gpio1_
 	.name		= "gpio1",
 	.class		= &omap44xx_gpio_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
-	.mpu_irqs	= omap44xx_gpio1_irqs,
 	.main_clk	= "l4_wkup_clk_mux_ck",
 	.prcm = {
 		.omap4 = {
@@ -1176,11 +1037,6 @@ static struct omap_hwmod omap44xx_gpio1_
 };
 
 /* gpio2 */
-static struct omap_hwmod_irq_info omap44xx_gpio2_irqs[] = {
-	{ .irq = 30 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio2_dbclk" },
 };
@@ -1190,7 +1046,6 @@ static struct omap_hwmod omap44xx_gpio2_
 	.class		= &omap44xx_gpio_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-	.mpu_irqs	= omap44xx_gpio2_irqs,
 	.main_clk	= "l4_div_ck",
 	.prcm = {
 		.omap4 = {
@@ -1205,11 +1060,6 @@ static struct omap_hwmod omap44xx_gpio2_
 };
 
 /* gpio3 */
-static struct omap_hwmod_irq_info omap44xx_gpio3_irqs[] = {
-	{ .irq = 31 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio3_dbclk" },
 };
@@ -1219,7 +1069,6 @@ static struct omap_hwmod omap44xx_gpio3_
 	.class		= &omap44xx_gpio_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-	.mpu_irqs	= omap44xx_gpio3_irqs,
 	.main_clk	= "l4_div_ck",
 	.prcm = {
 		.omap4 = {
@@ -1234,11 +1083,6 @@ static struct omap_hwmod omap44xx_gpio3_
 };
 
 /* gpio4 */
-static struct omap_hwmod_irq_info omap44xx_gpio4_irqs[] = {
-	{ .irq = 32 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio4_dbclk" },
 };
@@ -1248,7 +1092,6 @@ static struct omap_hwmod omap44xx_gpio4_
 	.class		= &omap44xx_gpio_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-	.mpu_irqs	= omap44xx_gpio4_irqs,
 	.main_clk	= "l4_div_ck",
 	.prcm = {
 		.omap4 = {
@@ -1263,11 +1106,6 @@ static struct omap_hwmod omap44xx_gpio4_
 };
 
 /* gpio5 */
-static struct omap_hwmod_irq_info omap44xx_gpio5_irqs[] = {
-	{ .irq = 33 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio5_dbclk" },
 };
@@ -1277,7 +1115,6 @@ static struct omap_hwmod omap44xx_gpio5_
 	.class		= &omap44xx_gpio_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-	.mpu_irqs	= omap44xx_gpio5_irqs,
 	.main_clk	= "l4_div_ck",
 	.prcm = {
 		.omap4 = {
@@ -1292,11 +1129,6 @@ static struct omap_hwmod omap44xx_gpio5_
 };
 
 /* gpio6 */
-static struct omap_hwmod_irq_info omap44xx_gpio6_irqs[] = {
-	{ .irq = 34 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
 	{ .role = "dbclk", .clk = "gpio6_dbclk" },
 };
@@ -1306,7 +1138,6 @@ static struct omap_hwmod omap44xx_gpio6_
 	.class		= &omap44xx_gpio_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
-	.mpu_irqs	= omap44xx_gpio6_irqs,
 	.main_clk	= "l4_div_ck",
 	.prcm = {
 		.omap4 = {
@@ -1341,16 +1172,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* gpmc */
-static struct omap_hwmod_irq_info omap44xx_gpmc_irqs[] = {
-	{ .irq = 20 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_gpmc_sdma_reqs[] = {
-	{ .dma_req = 3 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_gpmc_hwmod = {
 	.name		= "gpmc",
 	.class		= &omap44xx_gpmc_hwmod_class,
@@ -1364,8 +1185,6 @@ static struct omap_hwmod omap44xx_gpmc_h
 	 * HWMOD_INIT_NO_RESET should be removed ASAP.
 	 */
 	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
-	.mpu_irqs	= omap44xx_gpmc_irqs,
-	.sdma_reqs	= omap44xx_gpmc_sdma_reqs,
 	.prcm = {
 		.omap4 = {
 			.clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET,
@@ -1396,16 +1215,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* gpu */
-static struct omap_hwmod_irq_info omap44xx_gpu_irqs[] = {
-	{ .irq = 21 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_gpu_hwmod = {
 	.name		= "gpu",
 	.class		= &omap44xx_gpu_hwmod_class,
 	.clkdm_name	= "l3_gfx_clkdm",
-	.mpu_irqs	= omap44xx_gpu_irqs,
 	.main_clk	= "sgx_clk_mux",
 	.prcm = {
 		.omap4 = {
@@ -1436,17 +1249,11 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* hdq1w */
-static struct omap_hwmod_irq_info omap44xx_hdq1w_irqs[] = {
-	{ .irq = 58 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_hdq1w_hwmod = {
 	.name		= "hdq1w",
 	.class		= &omap44xx_hdq1w_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_INIT_NO_RESET, /* XXX temporary */
-	.mpu_irqs	= omap44xx_hdq1w_irqs,
 	.main_clk	= "func_12m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1482,18 +1289,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* hsi */
-static struct omap_hwmod_irq_info omap44xx_hsi_irqs[] = {
-	{ .name = "mpu_p1", .irq = 67 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "mpu_p2", .irq = 68 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "mpu_dma", .irq = 71 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_hsi_hwmod = {
 	.name		= "hsi",
 	.class		= &omap44xx_hsi_hwmod_class,
 	.clkdm_name	= "l3_init_clkdm",
-	.mpu_irqs	= omap44xx_hsi_irqs,
 	.main_clk	= "hsi_fck",
 	.prcm = {
 		.omap4 = {
@@ -1533,24 +1332,11 @@ static struct omap_i2c_dev_attr i2c_dev_
 };
 
 /* i2c1 */
-static struct omap_hwmod_irq_info omap44xx_i2c1_irqs[] = {
-	{ .irq = 56 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_i2c1_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 26 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 27 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_i2c1_hwmod = {
 	.name		= "i2c1",
 	.class		= &omap44xx_i2c_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
-	.mpu_irqs	= omap44xx_i2c1_irqs,
-	.sdma_reqs	= omap44xx_i2c1_sdma_reqs,
 	.main_clk	= "func_96m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1563,24 +1349,11 @@ static struct omap_hwmod omap44xx_i2c1_h
 };
 
 /* i2c2 */
-static struct omap_hwmod_irq_info omap44xx_i2c2_irqs[] = {
-	{ .irq = 57 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_i2c2_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 28 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 29 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_i2c2_hwmod = {
 	.name		= "i2c2",
 	.class		= &omap44xx_i2c_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
-	.mpu_irqs	= omap44xx_i2c2_irqs,
-	.sdma_reqs	= omap44xx_i2c2_sdma_reqs,
 	.main_clk	= "func_96m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1593,24 +1366,11 @@ static struct omap_hwmod omap44xx_i2c2_h
 };
 
 /* i2c3 */
-static struct omap_hwmod_irq_info omap44xx_i2c3_irqs[] = {
-	{ .irq = 61 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_i2c3_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 24 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 25 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_i2c3_hwmod = {
 	.name		= "i2c3",
 	.class		= &omap44xx_i2c_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
-	.mpu_irqs	= omap44xx_i2c3_irqs,
-	.sdma_reqs	= omap44xx_i2c3_sdma_reqs,
 	.main_clk	= "func_96m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1623,24 +1383,11 @@ static struct omap_hwmod omap44xx_i2c3_h
 };
 
 /* i2c4 */
-static struct omap_hwmod_irq_info omap44xx_i2c4_irqs[] = {
-	{ .irq = 62 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_i2c4_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 123 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 124 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_i2c4_hwmod = {
 	.name		= "i2c4",
 	.class		= &omap44xx_i2c_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
-	.mpu_irqs	= omap44xx_i2c4_irqs,
-	.sdma_reqs	= omap44xx_i2c4_sdma_reqs,
 	.main_clk	= "func_96m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -1662,11 +1409,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* ipu */
-static struct omap_hwmod_irq_info omap44xx_ipu_irqs[] = {
-	{ .irq = 100 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_rst_info omap44xx_ipu_resets[] = {
 	{ .name = "cpu0", .rst_shift = 0 },
 	{ .name = "cpu1", .rst_shift = 1 },
@@ -1676,7 +1418,6 @@ static struct omap_hwmod omap44xx_ipu_hw
 	.name		= "ipu",
 	.class		= &omap44xx_ipu_hwmod_class,
 	.clkdm_name	= "ducati_clkdm",
-	.mpu_irqs	= omap44xx_ipu_irqs,
 	.rst_lines	= omap44xx_ipu_resets,
 	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_ipu_resets),
 	.main_clk	= "ducati_clk_mux_ck",
@@ -1721,19 +1462,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* iss */
-static struct omap_hwmod_irq_info omap44xx_iss_irqs[] = {
-	{ .irq = 24 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_iss_sdma_reqs[] = {
-	{ .name = "1", .dma_req = 8 + OMAP44XX_DMA_REQ_START },
-	{ .name = "2", .dma_req = 9 + OMAP44XX_DMA_REQ_START },
-	{ .name = "3", .dma_req = 11 + OMAP44XX_DMA_REQ_START },
-	{ .name = "4", .dma_req = 12 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod_opt_clk iss_opt_clks[] = {
 	{ .role = "ctrlclk", .clk = "iss_ctrlclk" },
 };
@@ -1742,8 +1470,6 @@ static struct omap_hwmod omap44xx_iss_hw
 	.name		= "iss",
 	.class		= &omap44xx_iss_hwmod_class,
 	.clkdm_name	= "iss_clkdm",
-	.mpu_irqs	= omap44xx_iss_irqs,
-	.sdma_reqs	= omap44xx_iss_sdma_reqs,
 	.main_clk	= "ducati_clk_mux_ck",
 	.prcm = {
 		.omap4 = {
@@ -1766,13 +1492,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* iva */
-static struct omap_hwmod_irq_info omap44xx_iva_irqs[] = {
-	{ .name = "sync_1", .irq = 103 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "sync_0", .irq = 104 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "mailbox_0", .irq = 107 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_rst_info omap44xx_iva_resets[] = {
 	{ .name = "seq0", .rst_shift = 0 },
 	{ .name = "seq1", .rst_shift = 1 },
@@ -1783,7 +1502,6 @@ static struct omap_hwmod omap44xx_iva_hw
 	.name		= "iva",
 	.class		= &omap44xx_iva_hwmod_class,
 	.clkdm_name	= "ivahd_clkdm",
-	.mpu_irqs	= omap44xx_iva_irqs,
 	.rst_lines	= omap44xx_iva_resets,
 	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_iva_resets),
 	.main_clk	= "dpll_iva_m5x2_ck",
@@ -1820,16 +1538,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* kbd */
-static struct omap_hwmod_irq_info omap44xx_kbd_irqs[] = {
-	{ .irq = 120 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_kbd_hwmod = {
 	.name		= "kbd",
 	.class		= &omap44xx_kbd_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
-	.mpu_irqs	= omap44xx_kbd_irqs,
 	.main_clk	= "sys_32k_ck",
 	.prcm = {
 		.omap4 = {
@@ -1861,16 +1573,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* mailbox */
-static struct omap_hwmod_irq_info omap44xx_mailbox_irqs[] = {
-	{ .irq = 26 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_mailbox_hwmod = {
 	.name		= "mailbox",
 	.class		= &omap44xx_mailbox_hwmod_class,
 	.clkdm_name	= "l4_cfg_clkdm",
-	.mpu_irqs	= omap44xx_mailbox_irqs,
 	.prcm = {
 		.omap4 = {
 			.clkctrl_offs = OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET,
@@ -1903,24 +1609,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* mcasp */
-static struct omap_hwmod_irq_info omap44xx_mcasp_irqs[] = {
-	{ .name = "arevt", .irq = 108 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "axevt", .irq = 109 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_mcasp_sdma_reqs[] = {
-	{ .name = "axevt", .dma_req = 7 + OMAP44XX_DMA_REQ_START },
-	{ .name = "arevt", .dma_req = 10 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_mcasp_hwmod = {
 	.name		= "mcasp",
 	.class		= &omap44xx_mcasp_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_mcasp_irqs,
-	.sdma_reqs	= omap44xx_mcasp_sdma_reqs,
 	.main_clk	= "func_mcasp_abe_gfclk",
 	.prcm = {
 		.omap4 = {
@@ -1951,17 +1643,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* mcbsp1 */
-static struct omap_hwmod_irq_info omap44xx_mcbsp1_irqs[] = {
-	{ .name = "common", .irq = 17 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_mcbsp1_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 32 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 33 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = {
 	{ .role = "pad_fck", .clk = "pad_clks_ck" },
 	{ .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" },
@@ -1971,8 +1652,6 @@ static struct omap_hwmod omap44xx_mcbsp1
 	.name		= "mcbsp1",
 	.class		= &omap44xx_mcbsp_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_mcbsp1_irqs,
-	.sdma_reqs	= omap44xx_mcbsp1_sdma_reqs,
 	.main_clk	= "func_mcbsp1_gfclk",
 	.prcm = {
 		.omap4 = {
@@ -1986,17 +1665,6 @@ static struct omap_hwmod omap44xx_mcbsp1
 };
 
 /* mcbsp2 */
-static struct omap_hwmod_irq_info omap44xx_mcbsp2_irqs[] = {
-	{ .name = "common", .irq = 22 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_mcbsp2_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 16 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 17 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = {
 	{ .role = "pad_fck", .clk = "pad_clks_ck" },
 	{ .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" },
@@ -2006,8 +1674,6 @@ static struct omap_hwmod omap44xx_mcbsp2
 	.name		= "mcbsp2",
 	.class		= &omap44xx_mcbsp_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_mcbsp2_irqs,
-	.sdma_reqs	= omap44xx_mcbsp2_sdma_reqs,
 	.main_clk	= "func_mcbsp2_gfclk",
 	.prcm = {
 		.omap4 = {
@@ -2021,17 +1687,6 @@ static struct omap_hwmod omap44xx_mcbsp2
 };
 
 /* mcbsp3 */
-static struct omap_hwmod_irq_info omap44xx_mcbsp3_irqs[] = {
-	{ .name = "common", .irq = 23 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_mcbsp3_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 18 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 19 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = {
 	{ .role = "pad_fck", .clk = "pad_clks_ck" },
 	{ .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" },
@@ -2041,8 +1696,6 @@ static struct omap_hwmod omap44xx_mcbsp3
 	.name		= "mcbsp3",
 	.class		= &omap44xx_mcbsp_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_mcbsp3_irqs,
-	.sdma_reqs	= omap44xx_mcbsp3_sdma_reqs,
 	.main_clk	= "func_mcbsp3_gfclk",
 	.prcm = {
 		.omap4 = {
@@ -2056,17 +1709,6 @@ static struct omap_hwmod omap44xx_mcbsp3
 };
 
 /* mcbsp4 */
-static struct omap_hwmod_irq_info omap44xx_mcbsp4_irqs[] = {
-	{ .name = "common", .irq = 16 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_mcbsp4_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 30 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 31 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod_opt_clk mcbsp4_opt_clks[] = {
 	{ .role = "pad_fck", .clk = "pad_clks_ck" },
 	{ .role = "prcm_fck", .clk = "mcbsp4_sync_mux_ck" },
@@ -2076,8 +1718,6 @@ static struct omap_hwmod omap44xx_mcbsp4
 	.name		= "mcbsp4",
 	.class		= &omap44xx_mcbsp_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_mcbsp4_irqs,
-	.sdma_reqs	= omap44xx_mcbsp4_sdma_reqs,
 	.main_clk	= "per_mcbsp4_gfclk",
 	.prcm = {
 		.omap4 = {
@@ -2112,17 +1752,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* mcpdm */
-static struct omap_hwmod_irq_info omap44xx_mcpdm_irqs[] = {
-	{ .irq = 112 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_mcpdm_sdma_reqs[] = {
-	{ .name = "up_link", .dma_req = 64 + OMAP44XX_DMA_REQ_START },
-	{ .name = "dn_link", .dma_req = 65 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_mcpdm_hwmod = {
 	.name		= "mcpdm",
 	.class		= &omap44xx_mcpdm_hwmod_class,
@@ -2139,8 +1768,6 @@ static struct omap_hwmod omap44xx_mcpdm_
 	 * results 'slow motion' audio playback.
 	 */
 	.flags		= HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE,
-	.mpu_irqs	= omap44xx_mcpdm_irqs,
-	.sdma_reqs	= omap44xx_mcpdm_sdma_reqs,
 	.main_clk	= "pad_clks_ck",
 	.prcm = {
 		.omap4 = {
@@ -2174,11 +1801,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* mcspi1 */
-static struct omap_hwmod_irq_info omap44xx_mcspi1_irqs[] = {
-	{ .irq = 65 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_dma_info omap44xx_mcspi1_sdma_reqs[] = {
 	{ .name = "tx0", .dma_req = 34 + OMAP44XX_DMA_REQ_START },
 	{ .name = "rx0", .dma_req = 35 + OMAP44XX_DMA_REQ_START },
@@ -2200,7 +1822,6 @@ static struct omap_hwmod omap44xx_mcspi1
 	.name		= "mcspi1",
 	.class		= &omap44xx_mcspi_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_mcspi1_irqs,
 	.sdma_reqs	= omap44xx_mcspi1_sdma_reqs,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
@@ -2214,11 +1835,6 @@ static struct omap_hwmod omap44xx_mcspi1
 };
 
 /* mcspi2 */
-static struct omap_hwmod_irq_info omap44xx_mcspi2_irqs[] = {
-	{ .irq = 66 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_dma_info omap44xx_mcspi2_sdma_reqs[] = {
 	{ .name = "tx0", .dma_req = 42 + OMAP44XX_DMA_REQ_START },
 	{ .name = "rx0", .dma_req = 43 + OMAP44XX_DMA_REQ_START },
@@ -2236,7 +1852,6 @@ static struct omap_hwmod omap44xx_mcspi2
 	.name		= "mcspi2",
 	.class		= &omap44xx_mcspi_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_mcspi2_irqs,
 	.sdma_reqs	= omap44xx_mcspi2_sdma_reqs,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
@@ -2250,11 +1865,6 @@ static struct omap_hwmod omap44xx_mcspi2
 };
 
 /* mcspi3 */
-static struct omap_hwmod_irq_info omap44xx_mcspi3_irqs[] = {
-	{ .irq = 91 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_dma_info omap44xx_mcspi3_sdma_reqs[] = {
 	{ .name = "tx0", .dma_req = 14 + OMAP44XX_DMA_REQ_START },
 	{ .name = "rx0", .dma_req = 15 + OMAP44XX_DMA_REQ_START },
@@ -2272,7 +1882,6 @@ static struct omap_hwmod omap44xx_mcspi3
 	.name		= "mcspi3",
 	.class		= &omap44xx_mcspi_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_mcspi3_irqs,
 	.sdma_reqs	= omap44xx_mcspi3_sdma_reqs,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
@@ -2286,11 +1895,6 @@ static struct omap_hwmod omap44xx_mcspi3
 };
 
 /* mcspi4 */
-static struct omap_hwmod_irq_info omap44xx_mcspi4_irqs[] = {
-	{ .irq = 48 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_dma_info omap44xx_mcspi4_sdma_reqs[] = {
 	{ .name = "tx0", .dma_req = 69 + OMAP44XX_DMA_REQ_START },
 	{ .name = "rx0", .dma_req = 70 + OMAP44XX_DMA_REQ_START },
@@ -2306,7 +1910,6 @@ static struct omap_hwmod omap44xx_mcspi4
 	.name		= "mcspi4",
 	.class		= &omap44xx_mcspi_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_mcspi4_irqs,
 	.sdma_reqs	= omap44xx_mcspi4_sdma_reqs,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
@@ -2342,11 +1945,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* mmc1 */
-static struct omap_hwmod_irq_info omap44xx_mmc1_irqs[] = {
-	{ .irq = 83 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_dma_info omap44xx_mmc1_sdma_reqs[] = {
 	{ .name = "tx", .dma_req = 60 + OMAP44XX_DMA_REQ_START },
 	{ .name = "rx", .dma_req = 61 + OMAP44XX_DMA_REQ_START },
@@ -2362,7 +1960,6 @@ static struct omap_hwmod omap44xx_mmc1_h
 	.name		= "mmc1",
 	.class		= &omap44xx_mmc_hwmod_class,
 	.clkdm_name	= "l3_init_clkdm",
-	.mpu_irqs	= omap44xx_mmc1_irqs,
 	.sdma_reqs	= omap44xx_mmc1_sdma_reqs,
 	.main_clk	= "hsmmc1_fclk",
 	.prcm = {
@@ -2376,11 +1973,6 @@ static struct omap_hwmod omap44xx_mmc1_h
 };
 
 /* mmc2 */
-static struct omap_hwmod_irq_info omap44xx_mmc2_irqs[] = {
-	{ .irq = 86 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_dma_info omap44xx_mmc2_sdma_reqs[] = {
 	{ .name = "tx", .dma_req = 46 + OMAP44XX_DMA_REQ_START },
 	{ .name = "rx", .dma_req = 47 + OMAP44XX_DMA_REQ_START },
@@ -2391,7 +1983,6 @@ static struct omap_hwmod omap44xx_mmc2_h
 	.name		= "mmc2",
 	.class		= &omap44xx_mmc_hwmod_class,
 	.clkdm_name	= "l3_init_clkdm",
-	.mpu_irqs	= omap44xx_mmc2_irqs,
 	.sdma_reqs	= omap44xx_mmc2_sdma_reqs,
 	.main_clk	= "hsmmc2_fclk",
 	.prcm = {
@@ -2404,11 +1995,6 @@ static struct omap_hwmod omap44xx_mmc2_h
 };
 
 /* mmc3 */
-static struct omap_hwmod_irq_info omap44xx_mmc3_irqs[] = {
-	{ .irq = 94 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_dma_info omap44xx_mmc3_sdma_reqs[] = {
 	{ .name = "tx", .dma_req = 76 + OMAP44XX_DMA_REQ_START },
 	{ .name = "rx", .dma_req = 77 + OMAP44XX_DMA_REQ_START },
@@ -2419,7 +2005,6 @@ static struct omap_hwmod omap44xx_mmc3_h
 	.name		= "mmc3",
 	.class		= &omap44xx_mmc_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_mmc3_irqs,
 	.sdma_reqs	= omap44xx_mmc3_sdma_reqs,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
@@ -2432,11 +2017,6 @@ static struct omap_hwmod omap44xx_mmc3_h
 };
 
 /* mmc4 */
-static struct omap_hwmod_irq_info omap44xx_mmc4_irqs[] = {
-	{ .irq = 96 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_dma_info omap44xx_mmc4_sdma_reqs[] = {
 	{ .name = "tx", .dma_req = 56 + OMAP44XX_DMA_REQ_START },
 	{ .name = "rx", .dma_req = 57 + OMAP44XX_DMA_REQ_START },
@@ -2447,7 +2027,6 @@ static struct omap_hwmod omap44xx_mmc4_h
 	.name		= "mmc4",
 	.class		= &omap44xx_mmc_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_mmc4_irqs,
 	.sdma_reqs	= omap44xx_mmc4_sdma_reqs,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
@@ -2460,11 +2039,6 @@ static struct omap_hwmod omap44xx_mmc4_h
 };
 
 /* mmc5 */
-static struct omap_hwmod_irq_info omap44xx_mmc5_irqs[] = {
-	{ .irq = 59 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_dma_info omap44xx_mmc5_sdma_reqs[] = {
 	{ .name = "tx", .dma_req = 58 + OMAP44XX_DMA_REQ_START },
 	{ .name = "rx", .dma_req = 59 + OMAP44XX_DMA_REQ_START },
@@ -2475,7 +2049,6 @@ static struct omap_hwmod omap44xx_mmc5_h
 	.name		= "mmc5",
 	.class		= &omap44xx_mmc_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_mmc5_irqs,
 	.sdma_reqs	= omap44xx_mmc5_sdma_reqs,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
@@ -2517,11 +2090,6 @@ static struct omap_mmu_dev_attr mmu_ipu_
 };
 
 static struct omap_hwmod omap44xx_mmu_ipu_hwmod;
-static struct omap_hwmod_irq_info omap44xx_mmu_ipu_irqs[] = {
-	{ .irq = 100 + OMAP44XX_IRQ_GIC_START, },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_rst_info omap44xx_mmu_ipu_resets[] = {
 	{ .name = "mmu_cache", .rst_shift = 2 },
 };
@@ -2548,7 +2116,6 @@ static struct omap_hwmod omap44xx_mmu_ip
 	.name		= "mmu_ipu",
 	.class		= &omap44xx_mmu_hwmod_class,
 	.clkdm_name	= "ducati_clkdm",
-	.mpu_irqs	= omap44xx_mmu_ipu_irqs,
 	.rst_lines	= omap44xx_mmu_ipu_resets,
 	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_mmu_ipu_resets),
 	.main_clk	= "ducati_clk_mux_ck",
@@ -2572,11 +2139,6 @@ static struct omap_mmu_dev_attr mmu_dsp_
 };
 
 static struct omap_hwmod omap44xx_mmu_dsp_hwmod;
-static struct omap_hwmod_irq_info omap44xx_mmu_dsp_irqs[] = {
-	{ .irq = 28 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_rst_info omap44xx_mmu_dsp_resets[] = {
 	{ .name = "mmu_cache", .rst_shift = 1 },
 };
@@ -2603,7 +2165,6 @@ static struct omap_hwmod omap44xx_mmu_ds
 	.name		= "mmu_dsp",
 	.class		= &omap44xx_mmu_hwmod_class,
 	.clkdm_name	= "tesla_clkdm",
-	.mpu_irqs	= omap44xx_mmu_dsp_irqs,
 	.rst_lines	= omap44xx_mmu_dsp_resets,
 	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_mmu_dsp_resets),
 	.main_clk	= "dpll_iva_m4x2_ck",
@@ -2628,21 +2189,11 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* mpu */
-static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
-	{ .name = "pmu0", .irq = 54 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "pmu1", .irq = 55 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_mpu_hwmod = {
 	.name		= "mpu",
 	.class		= &omap44xx_mpu_hwmod_class,
 	.clkdm_name	= "mpuss_clkdm",
 	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
-	.mpu_irqs	= omap44xx_mpu_irqs,
 	.main_clk	= "dpll_mpu_m2_ck",
 	.prcm = {
 		.omap4 = {
@@ -2695,25 +2246,6 @@ static struct omap_hwmod_class omap44xx_
 	.sysc	= &omap44xx_ocp2scp_sysc,
 };
 
-/* ocp2scp dev_attr */
-static struct resource omap44xx_usb_phy_and_pll_addrs[] = {
-	{
-		.name		= "usb_phy",
-		.start		= 0x4a0ad080,
-		.end		= 0x4a0ae000,
-		.flags		= IORESOURCE_MEM,
-	},
-	{ }
-};
-
-static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = {
-	{
-		.drv_name       = "omap-usb2",
-		.res		= omap44xx_usb_phy_and_pll_addrs,
-	},
-	{ }
-};
-
 /* ocp2scp_usb_phy */
 static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
 	.name		= "ocp2scp_usb_phy",
@@ -2737,7 +2269,6 @@ static struct omap_hwmod omap44xx_ocp2sc
 			.modulemode   = MODULEMODE_HWCTRL,
 		},
 	},
-	.dev_attr	= ocp2scp_dev_attr,
 };
 
 /*
@@ -2788,11 +2319,6 @@ static struct omap_hwmod omap44xx_cm_cor
 };
 
 /* prm */
-static struct omap_hwmod_irq_info omap44xx_prm_irqs[] = {
-	{ .irq = 11 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_rst_info omap44xx_prm_resets[] = {
 	{ .name = "rst_global_warm_sw", .rst_shift = 0 },
 	{ .name = "rst_global_cold_sw", .rst_shift = 1 },
@@ -2801,7 +2327,6 @@ static struct omap_hwmod_rst_info omap44
 static struct omap_hwmod omap44xx_prm_hwmod = {
 	.name		= "prm",
 	.class		= &omap44xx_prcm_hwmod_class,
-	.mpu_irqs	= omap44xx_prm_irqs,
 	.rst_lines	= omap44xx_prm_resets,
 	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_prm_resets),
 };
@@ -2872,23 +2397,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* slimbus1 */
-static struct omap_hwmod_irq_info omap44xx_slimbus1_irqs[] = {
-	{ .irq = 97 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_slimbus1_sdma_reqs[] = {
-	{ .name = "tx0", .dma_req = 84 + OMAP44XX_DMA_REQ_START },
-	{ .name = "tx1", .dma_req = 85 + OMAP44XX_DMA_REQ_START },
-	{ .name = "tx2", .dma_req = 86 + OMAP44XX_DMA_REQ_START },
-	{ .name = "tx3", .dma_req = 87 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx0", .dma_req = 88 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx1", .dma_req = 89 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx2", .dma_req = 90 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx3", .dma_req = 91 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod_opt_clk slimbus1_opt_clks[] = {
 	{ .role = "fclk_1", .clk = "slimbus1_fclk_1" },
 	{ .role = "fclk_0", .clk = "slimbus1_fclk_0" },
@@ -2900,8 +2408,6 @@ static struct omap_hwmod omap44xx_slimbu
 	.name		= "slimbus1",
 	.class		= &omap44xx_slimbus_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_slimbus1_irqs,
-	.sdma_reqs	= omap44xx_slimbus1_sdma_reqs,
 	.prcm = {
 		.omap4 = {
 			.clkctrl_offs = OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET,
@@ -2914,23 +2420,6 @@ static struct omap_hwmod omap44xx_slimbu
 };
 
 /* slimbus2 */
-static struct omap_hwmod_irq_info omap44xx_slimbus2_irqs[] = {
-	{ .irq = 98 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_slimbus2_sdma_reqs[] = {
-	{ .name = "tx0", .dma_req = 92 + OMAP44XX_DMA_REQ_START },
-	{ .name = "tx1", .dma_req = 93 + OMAP44XX_DMA_REQ_START },
-	{ .name = "tx2", .dma_req = 94 + OMAP44XX_DMA_REQ_START },
-	{ .name = "tx3", .dma_req = 95 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx0", .dma_req = 96 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx1", .dma_req = 97 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx2", .dma_req = 98 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx3", .dma_req = 99 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod_opt_clk slimbus2_opt_clks[] = {
 	{ .role = "fclk_1", .clk = "slimbus2_fclk_1" },
 	{ .role = "fclk_0", .clk = "slimbus2_fclk_0" },
@@ -2941,8 +2430,6 @@ static struct omap_hwmod omap44xx_slimbu
 	.name		= "slimbus2",
 	.class		= &omap44xx_slimbus_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_slimbus2_irqs,
-	.sdma_reqs	= omap44xx_slimbus2_sdma_reqs,
 	.prcm = {
 		.omap4 = {
 			.clkctrl_offs = OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET,
@@ -2985,16 +2472,10 @@ static struct omap_smartreflex_dev_attr
 	.sensor_voltdm_name   = "core",
 };
 
-static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = {
-	{ .irq = 19 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
 	.name		= "smartreflex_core",
 	.class		= &omap44xx_smartreflex_hwmod_class,
 	.clkdm_name	= "l4_ao_clkdm",
-	.mpu_irqs	= omap44xx_smartreflex_core_irqs,
 
 	.main_clk	= "smartreflex_core_fck",
 	.prcm = {
@@ -3012,16 +2493,10 @@ static struct omap_smartreflex_dev_attr
 	.sensor_voltdm_name	= "iva",
 };
 
-static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = {
-	{ .irq = 102 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
 	.name		= "smartreflex_iva",
 	.class		= &omap44xx_smartreflex_hwmod_class,
 	.clkdm_name	= "l4_ao_clkdm",
-	.mpu_irqs	= omap44xx_smartreflex_iva_irqs,
 	.main_clk	= "smartreflex_iva_fck",
 	.prcm = {
 		.omap4 = {
@@ -3038,16 +2513,10 @@ static struct omap_smartreflex_dev_attr
 	.sensor_voltdm_name	= "mpu",
 };
 
-static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = {
-	{ .irq = 18 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
 	.name		= "smartreflex_mpu",
 	.class		= &omap44xx_smartreflex_hwmod_class,
 	.clkdm_name	= "l4_ao_clkdm",
-	.mpu_irqs	= omap44xx_smartreflex_mpu_irqs,
 	.main_clk	= "smartreflex_mpu_fck",
 	.prcm = {
 		.omap4 = {
@@ -3155,17 +2624,11 @@ static struct omap_timer_capability_dev_
 };
 
 /* timer1 */
-static struct omap_hwmod_irq_info omap44xx_timer1_irqs[] = {
-	{ .irq = 37 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer1_hwmod = {
 	.name		= "timer1",
 	.class		= &omap44xx_timer_1ms_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
-	.mpu_irqs	= omap44xx_timer1_irqs,
 	.main_clk	= "dmt1_clk_mux",
 	.prcm = {
 		.omap4 = {
@@ -3178,17 +2641,11 @@ static struct omap_hwmod omap44xx_timer1
 };
 
 /* timer2 */
-static struct omap_hwmod_irq_info omap44xx_timer2_irqs[] = {
-	{ .irq = 38 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer2_hwmod = {
 	.name		= "timer2",
 	.class		= &omap44xx_timer_1ms_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
-	.mpu_irqs	= omap44xx_timer2_irqs,
 	.main_clk	= "cm2_dm2_mux",
 	.prcm = {
 		.omap4 = {
@@ -3200,16 +2657,10 @@ static struct omap_hwmod omap44xx_timer2
 };
 
 /* timer3 */
-static struct omap_hwmod_irq_info omap44xx_timer3_irqs[] = {
-	{ .irq = 39 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer3_hwmod = {
 	.name		= "timer3",
 	.class		= &omap44xx_timer_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_timer3_irqs,
 	.main_clk	= "cm2_dm3_mux",
 	.prcm = {
 		.omap4 = {
@@ -3221,16 +2672,10 @@ static struct omap_hwmod omap44xx_timer3
 };
 
 /* timer4 */
-static struct omap_hwmod_irq_info omap44xx_timer4_irqs[] = {
-	{ .irq = 40 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer4_hwmod = {
 	.name		= "timer4",
 	.class		= &omap44xx_timer_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_timer4_irqs,
 	.main_clk	= "cm2_dm4_mux",
 	.prcm = {
 		.omap4 = {
@@ -3242,16 +2687,10 @@ static struct omap_hwmod omap44xx_timer4
 };
 
 /* timer5 */
-static struct omap_hwmod_irq_info omap44xx_timer5_irqs[] = {
-	{ .irq = 41 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer5_hwmod = {
 	.name		= "timer5",
 	.class		= &omap44xx_timer_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_timer5_irqs,
 	.main_clk	= "timer5_sync_mux",
 	.prcm = {
 		.omap4 = {
@@ -3264,16 +2703,10 @@ static struct omap_hwmod omap44xx_timer5
 };
 
 /* timer6 */
-static struct omap_hwmod_irq_info omap44xx_timer6_irqs[] = {
-	{ .irq = 42 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer6_hwmod = {
 	.name		= "timer6",
 	.class		= &omap44xx_timer_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_timer6_irqs,
 	.main_clk	= "timer6_sync_mux",
 	.prcm = {
 		.omap4 = {
@@ -3286,16 +2719,10 @@ static struct omap_hwmod omap44xx_timer6
 };
 
 /* timer7 */
-static struct omap_hwmod_irq_info omap44xx_timer7_irqs[] = {
-	{ .irq = 43 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer7_hwmod = {
 	.name		= "timer7",
 	.class		= &omap44xx_timer_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_timer7_irqs,
 	.main_clk	= "timer7_sync_mux",
 	.prcm = {
 		.omap4 = {
@@ -3308,16 +2735,10 @@ static struct omap_hwmod omap44xx_timer7
 };
 
 /* timer8 */
-static struct omap_hwmod_irq_info omap44xx_timer8_irqs[] = {
-	{ .irq = 44 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer8_hwmod = {
 	.name		= "timer8",
 	.class		= &omap44xx_timer_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_timer8_irqs,
 	.main_clk	= "timer8_sync_mux",
 	.prcm = {
 		.omap4 = {
@@ -3330,16 +2751,10 @@ static struct omap_hwmod omap44xx_timer8
 };
 
 /* timer9 */
-static struct omap_hwmod_irq_info omap44xx_timer9_irqs[] = {
-	{ .irq = 45 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer9_hwmod = {
 	.name		= "timer9",
 	.class		= &omap44xx_timer_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_timer9_irqs,
 	.main_clk	= "cm2_dm9_mux",
 	.prcm = {
 		.omap4 = {
@@ -3352,17 +2767,11 @@ static struct omap_hwmod omap44xx_timer9
 };
 
 /* timer10 */
-static struct omap_hwmod_irq_info omap44xx_timer10_irqs[] = {
-	{ .irq = 46 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer10_hwmod = {
 	.name		= "timer10",
 	.class		= &omap44xx_timer_1ms_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
-	.mpu_irqs	= omap44xx_timer10_irqs,
 	.main_clk	= "cm2_dm10_mux",
 	.prcm = {
 		.omap4 = {
@@ -3375,16 +2784,10 @@ static struct omap_hwmod omap44xx_timer1
 };
 
 /* timer11 */
-static struct omap_hwmod_irq_info omap44xx_timer11_irqs[] = {
-	{ .irq = 47 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_timer11_hwmod = {
 	.name		= "timer11",
 	.class		= &omap44xx_timer_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.mpu_irqs	= omap44xx_timer11_irqs,
 	.main_clk	= "cm2_dm11_mux",
 	.prcm = {
 		.omap4 = {
@@ -3419,24 +2822,11 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* uart1 */
-static struct omap_hwmod_irq_info omap44xx_uart1_irqs[] = {
-	{ .irq = 72 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_uart1_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 48 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 49 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_uart1_hwmod = {
 	.name		= "uart1",
 	.class		= &omap44xx_uart_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= omap44xx_uart1_irqs,
-	.sdma_reqs	= omap44xx_uart1_sdma_reqs,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -3448,24 +2838,11 @@ static struct omap_hwmod omap44xx_uart1_
 };
 
 /* uart2 */
-static struct omap_hwmod_irq_info omap44xx_uart2_irqs[] = {
-	{ .irq = 73 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_uart2_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 50 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 51 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_uart2_hwmod = {
 	.name		= "uart2",
 	.class		= &omap44xx_uart_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
 	.flags		= HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= omap44xx_uart2_irqs,
-	.sdma_reqs	= omap44xx_uart2_sdma_reqs,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -3477,25 +2854,11 @@ static struct omap_hwmod omap44xx_uart2_
 };
 
 /* uart3 */
-static struct omap_hwmod_irq_info omap44xx_uart3_irqs[] = {
-	{ .irq = 74 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_uart3_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 52 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 53 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_uart3_hwmod = {
 	.name		= "uart3",
 	.class		= &omap44xx_uart_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
-				HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= omap44xx_uart3_irqs,
-	.sdma_reqs	= omap44xx_uart3_sdma_reqs,
+	.flags		= DEBUG_OMAP4UART3_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -3507,24 +2870,11 @@ static struct omap_hwmod omap44xx_uart3_
 };
 
 /* uart4 */
-static struct omap_hwmod_irq_info omap44xx_uart4_irqs[] = {
-	{ .irq = 70 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
-static struct omap_hwmod_dma_info omap44xx_uart4_sdma_reqs[] = {
-	{ .name = "tx", .dma_req = 54 + OMAP44XX_DMA_REQ_START },
-	{ .name = "rx", .dma_req = 55 + OMAP44XX_DMA_REQ_START },
-	{ .dma_req = -1 }
-};
-
 static struct omap_hwmod omap44xx_uart4_hwmod = {
 	.name		= "uart4",
 	.class		= &omap44xx_uart_hwmod_class,
 	.clkdm_name	= "l4_per_clkdm",
-	.flags		= HWMOD_SWSUP_SIDLE_ACT,
-	.mpu_irqs	= omap44xx_uart4_irqs,
-	.sdma_reqs	= omap44xx_uart4_sdma_reqs,
+	.flags		= DEBUG_OMAP4UART4_FLAGS | HWMOD_SWSUP_SIDLE_ACT,
 	.main_clk	= "func_48m_fclk",
 	.prcm = {
 		.omap4 = {
@@ -3563,17 +2913,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* usb_host_fs */
-static struct omap_hwmod_irq_info omap44xx_usb_host_fs_irqs[] = {
-	{ .name = "std", .irq = 89 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "smi", .irq = 90 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_usb_host_fs_hwmod = {
 	.name		= "usb_host_fs",
 	.class		= &omap44xx_usb_host_fs_hwmod_class,
 	.clkdm_name	= "l3_init_clkdm",
-	.mpu_irqs	= omap44xx_usb_host_fs_irqs,
 	.main_clk	= "usb_host_fs_fck",
 	.prcm = {
 		.omap4 = {
@@ -3607,12 +2950,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* usb_host_hs */
-static struct omap_hwmod_irq_info omap44xx_usb_host_hs_irqs[] = {
-	{ .name = "ohci-irq", .irq = 76 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "ehci-irq", .irq = 77 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_usb_host_hs_hwmod = {
 	.name		= "usb_host_hs",
 	.class		= &omap44xx_usb_host_hs_hwmod_class,
@@ -3625,7 +2962,6 @@ static struct omap_hwmod omap44xx_usb_ho
 			.modulemode   = MODULEMODE_SWCTRL,
 		},
 	},
-	.mpu_irqs	= omap44xx_usb_host_hs_irqs,
 
 	/*
 	 * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
@@ -3700,12 +3036,6 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* usb_otg_hs */
-static struct omap_hwmod_irq_info omap44xx_usb_otg_hs_irqs[] = {
-	{ .name = "mc", .irq = 92 + OMAP44XX_IRQ_GIC_START },
-	{ .name = "dma", .irq = 93 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod_opt_clk usb_otg_hs_opt_clks[] = {
 	{ .role = "xclk", .clk = "usb_otg_hs_xclk" },
 };
@@ -3715,7 +3045,6 @@ static struct omap_hwmod omap44xx_usb_ot
 	.class		= &omap44xx_usb_otg_hs_hwmod_class,
 	.clkdm_name	= "l3_init_clkdm",
 	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
-	.mpu_irqs	= omap44xx_usb_otg_hs_irqs,
 	.main_clk	= "usb_otg_hs_ick",
 	.prcm = {
 		.omap4 = {
@@ -3749,16 +3078,10 @@ static struct omap_hwmod_class omap44xx_
 	.sysc	= &omap44xx_usb_tll_hs_sysc,
 };
 
-static struct omap_hwmod_irq_info omap44xx_usb_tll_hs_irqs[] = {
-	{ .name = "tll-irq", .irq = 78 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = {
 	.name		= "usb_tll_hs",
 	.class		= &omap44xx_usb_tll_hs_hwmod_class,
 	.clkdm_name	= "l3_init_clkdm",
-	.mpu_irqs	= omap44xx_usb_tll_hs_irqs,
 	.main_clk	= "usb_tll_hs_ick",
 	.prcm = {
 		.omap4 = {
@@ -3794,16 +3117,10 @@ static struct omap_hwmod_class omap44xx_
 };
 
 /* wd_timer2 */
-static struct omap_hwmod_irq_info omap44xx_wd_timer2_irqs[] = {
-	{ .irq = 80 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
 	.name		= "wd_timer2",
 	.class		= &omap44xx_wd_timer_hwmod_class,
 	.clkdm_name	= "l4_wkup_clkdm",
-	.mpu_irqs	= omap44xx_wd_timer2_irqs,
 	.main_clk	= "sys_32k_ck",
 	.prcm = {
 		.omap4 = {
@@ -3815,16 +3132,10 @@ static struct omap_hwmod omap44xx_wd_tim
 };
 
 /* wd_timer3 */
-static struct omap_hwmod_irq_info omap44xx_wd_timer3_irqs[] = {
-	{ .irq = 36 + OMAP44XX_IRQ_GIC_START },
-	{ .irq = -1 }
-};
-
 static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
 	.name		= "wd_timer3",
 	.class		= &omap44xx_wd_timer_hwmod_class,
 	.clkdm_name	= "abe_clkdm",
-	.mpu_irqs	= omap44xx_wd_timer3_irqs,
 	.main_clk	= "sys_32k_ck",
 	.prcm = {
 		.omap4 = {
@@ -3840,32 +3151,6 @@ static struct omap_hwmod omap44xx_wd_tim
  * interfaces
  */
 
-static struct omap_hwmod_addr_space omap44xx_c2c_target_fw_addrs[] = {
-	{
-		.pa_start	= 0x4a204000,
-		.pa_end		= 0x4a2040ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
-/* c2c -> c2c_target_fw */
-static struct omap_hwmod_ocp_if omap44xx_c2c__c2c_target_fw = {
-	.master		= &omap44xx_c2c_hwmod,
-	.slave		= &omap44xx_c2c_target_fw_hwmod,
-	.clk		= "div_core_ck",
-	.addr		= omap44xx_c2c_target_fw_addrs,
-	.user		= OCP_USER_MPU,
-};
-
-/* l4_cfg -> c2c_target_fw */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__c2c_target_fw = {
-	.master		= &omap44xx_l4_cfg_hwmod,
-	.slave		= &omap44xx_c2c_target_fw_hwmod,
-	.clk		= "l4_div_ck",
-	.user		= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3_main_1 -> dmm */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = {
 	.master		= &omap44xx_l3_main_1_hwmod,
@@ -3874,55 +3159,11 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_dmm_addrs[] = {
-	{
-		.pa_start	= 0x4e000000,
-		.pa_end		= 0x4e0007ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* mpu -> dmm */
 static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = {
 	.master		= &omap44xx_mpu_hwmod,
 	.slave		= &omap44xx_dmm_hwmod,
 	.clk		= "l3_div_ck",
-	.addr		= omap44xx_dmm_addrs,
-	.user		= OCP_USER_MPU,
-};
-
-/* c2c -> emif_fw */
-static struct omap_hwmod_ocp_if omap44xx_c2c__emif_fw = {
-	.master		= &omap44xx_c2c_hwmod,
-	.slave		= &omap44xx_emif_fw_hwmod,
-	.clk		= "div_core_ck",
-	.user		= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* dmm -> emif_fw */
-static struct omap_hwmod_ocp_if omap44xx_dmm__emif_fw = {
-	.master		= &omap44xx_dmm_hwmod,
-	.slave		= &omap44xx_emif_fw_hwmod,
-	.clk		= "l3_div_ck",
-	.user		= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod_addr_space omap44xx_emif_fw_addrs[] = {
-	{
-		.pa_start	= 0x4a20c000,
-		.pa_end		= 0x4a20c0ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
-/* l4_cfg -> emif_fw */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__emif_fw = {
-	.master		= &omap44xx_l4_cfg_hwmod,
-	.slave		= &omap44xx_emif_fw_hwmod,
-	.clk		= "l4_div_ck",
-	.addr		= omap44xx_emif_fw_addrs,
 	.user		= OCP_USER_MPU,
 };
 
@@ -3998,32 +3239,14 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_l3_main_1_addrs[] = {
-	{
-		.pa_start	= 0x44000000,
-		.pa_end		= 0x44000fff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* mpu -> l3_main_1 */
 static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = {
 	.master		= &omap44xx_mpu_hwmod,
 	.slave		= &omap44xx_l3_main_1_hwmod,
 	.clk		= "l3_div_ck",
-	.addr		= omap44xx_l3_main_1_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-/* c2c_target_fw -> l3_main_2 */
-static struct omap_hwmod_ocp_if omap44xx_c2c_target_fw__l3_main_2 = {
-	.master		= &omap44xx_c2c_target_fw_hwmod,
-	.slave		= &omap44xx_l3_main_2_hwmod,
-	.clk		= "l3_div_ck",
-	.user		= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* debugss -> l3_main_2 */
 static struct omap_hwmod_ocp_if omap44xx_debugss__l3_main_2 = {
 	.master		= &omap44xx_debugss_hwmod,
@@ -4088,21 +3311,11 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_l3_main_2_addrs[] = {
-	{
-		.pa_start	= 0x44800000,
-		.pa_end		= 0x44801fff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l3_main_1 -> l3_main_2 */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = {
 	.master		= &omap44xx_l3_main_1_hwmod,
 	.slave		= &omap44xx_l3_main_2_hwmod,
 	.clk		= "l3_div_ck",
-	.addr		= omap44xx_l3_main_2_addrs,
 	.user		= OCP_USER_MPU,
 };
 
@@ -4138,21 +3351,11 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_l3_main_3_addrs[] = {
-	{
-		.pa_start	= 0x45000000,
-		.pa_end		= 0x45000fff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l3_main_1 -> l3_main_3 */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_3 = {
 	.master		= &omap44xx_l3_main_1_hwmod,
 	.slave		= &omap44xx_l3_main_3_hwmod,
 	.clk		= "l3_div_ck",
-	.addr		= omap44xx_l3_main_3_addrs,
 	.user		= OCP_USER_MPU,
 };
 
@@ -4236,21 +3439,11 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_ocp_wp_noc_addrs[] = {
-	{
-		.pa_start	= 0x4a102000,
-		.pa_end		= 0x4a10207f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_cfg -> ocp_wp_noc */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp_wp_noc = {
 	.master		= &omap44xx_l4_cfg_hwmod,
 	.slave		= &omap44xx_ocp_wp_noc_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_ocp_wp_noc_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -4340,21 +3533,11 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_counter_32k_addrs[] = {
-	{
-		.pa_start	= 0x4a304000,
-		.pa_end		= 0x4a30401f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_wkup -> counter_32k */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__counter_32k = {
 	.master		= &omap44xx_l4_wkup_hwmod,
 	.slave		= &omap44xx_counter_32k_hwmod,
 	.clk		= "l4_wkup_clk_mux_ck",
-	.addr		= omap44xx_counter_32k_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -4430,21 +3613,11 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_debugss_addrs[] = {
-	{
-		.pa_start	= 0x54160000,
-		.pa_end		= 0x54167fff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l3_instr -> debugss */
 static struct omap_hwmod_ocp_if omap44xx_l3_instr__debugss = {
 	.master		= &omap44xx_l3_instr_hwmod,
 	.slave		= &omap44xx_debugss_hwmod,
 	.clk		= "l3_div_ck",
-	.addr		= omap44xx_debugss_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -4466,41 +3639,19 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_dmic_addrs[] = {
-	{
-		.name		= "mpu",
-		.pa_start	= 0x4012e000,
-		.pa_end		= 0x4012e07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> dmic */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_dmic_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_dmic_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_dmic_dma_addrs[] = {
-	{
-		.name		= "dma",
-		.pa_start	= 0x4902e000,
-		.pa_end		= 0x4902e07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> dmic (dma) */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic_dma = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_dmic_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_dmic_dma_addrs,
 	.user		= OCP_USER_SDMA,
 };
 
@@ -4798,42 +3949,6 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_emif1_addrs[] = {
-	{
-		.pa_start	= 0x4c000000,
-		.pa_end		= 0x4c0000ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
-/* emif_fw -> emif1 */
-static struct omap_hwmod_ocp_if omap44xx_emif_fw__emif1 = {
-	.master		= &omap44xx_emif_fw_hwmod,
-	.slave		= &omap44xx_emif1_hwmod,
-	.clk		= "l3_div_ck",
-	.addr		= omap44xx_emif1_addrs,
-	.user		= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod_addr_space omap44xx_emif2_addrs[] = {
-	{
-		.pa_start	= 0x4d000000,
-		.pa_end		= 0x4d0000ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
-/* emif_fw -> emif2 */
-static struct omap_hwmod_ocp_if omap44xx_emif_fw__emif2 = {
-	.master		= &omap44xx_emif_fw_hwmod,
-	.slave		= &omap44xx_emif2_hwmod,
-	.clk		= "l3_div_ck",
-	.addr		= omap44xx_emif2_addrs,
-	.user		= OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 static struct omap_hwmod_addr_space omap44xx_fdif_addrs[] = {
 	{
 		.pa_start	= 0x4a10a000,
@@ -4852,129 +3967,59 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_gpio1_addrs[] = {
-	{
-		.pa_start	= 0x4a310000,
-		.pa_end		= 0x4a3101ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_wkup -> gpio1 */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__gpio1 = {
 	.master		= &omap44xx_l4_wkup_hwmod,
 	.slave		= &omap44xx_gpio1_hwmod,
 	.clk		= "l4_wkup_clk_mux_ck",
-	.addr		= omap44xx_gpio1_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_gpio2_addrs[] = {
-	{
-		.pa_start	= 0x48055000,
-		.pa_end		= 0x480551ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> gpio2 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio2 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio2_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_gpio2_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_gpio3_addrs[] = {
-	{
-		.pa_start	= 0x48057000,
-		.pa_end		= 0x480571ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> gpio3 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio3 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio3_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_gpio3_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_gpio4_addrs[] = {
-	{
-		.pa_start	= 0x48059000,
-		.pa_end		= 0x480591ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> gpio4 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio4 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio4_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_gpio4_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_gpio5_addrs[] = {
-	{
-		.pa_start	= 0x4805b000,
-		.pa_end		= 0x4805b1ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> gpio5 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio5 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio5_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_gpio5_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_gpio6_addrs[] = {
-	{
-		.pa_start	= 0x4805d000,
-		.pa_end		= 0x4805d1ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> gpio6 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio6 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_gpio6_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_gpio6_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_gpmc_addrs[] = {
-	{
-		.pa_start	= 0x50000000,
-		.pa_end		= 0x500003ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l3_main_2 -> gpmc */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = {
 	.master		= &omap44xx_l3_main_2_hwmod,
 	.slave		= &omap44xx_gpmc_hwmod,
 	.clk		= "l3_div_ck",
-	.addr		= omap44xx_gpmc_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -5032,75 +4077,35 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_i2c1_addrs[] = {
-	{
-		.pa_start	= 0x48070000,
-		.pa_end		= 0x480700ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> i2c1 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c1 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_i2c1_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_i2c1_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_i2c2_addrs[] = {
-	{
-		.pa_start	= 0x48072000,
-		.pa_end		= 0x480720ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> i2c2 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c2 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_i2c2_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_i2c2_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_i2c3_addrs[] = {
-	{
-		.pa_start	= 0x48060000,
-		.pa_end		= 0x480600ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> i2c3 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c3 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_i2c3_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_i2c3_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_i2c4_addrs[] = {
-	{
-		.pa_start	= 0x48350000,
-		.pa_end		= 0x483500ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> i2c4 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c4 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_i2c4_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_i2c4_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -5138,39 +4143,19 @@ static struct omap_hwmod_ocp_if __maybe_
 	.user		= OCP_USER_IVA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_iva_addrs[] = {
-	{
-		.pa_start	= 0x5a000000,
-		.pa_end		= 0x5a07ffff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l3_main_2 -> iva */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iva = {
 	.master		= &omap44xx_l3_main_2_hwmod,
 	.slave		= &omap44xx_iva_hwmod,
 	.clk		= "l3_div_ck",
-	.addr		= omap44xx_iva_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_kbd_addrs[] = {
-	{
-		.pa_start	= 0x4a31c000,
-		.pa_end		= 0x4a31c07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_wkup -> kbd */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__kbd = {
 	.master		= &omap44xx_l4_wkup_hwmod,
 	.slave		= &omap44xx_kbd_hwmod,
 	.clk		= "l4_wkup_clk_mux_ck",
-	.addr		= omap44xx_kbd_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -5228,335 +4213,147 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcbsp1_addrs[] = {
-	{
-		.name		= "mpu",
-		.pa_start	= 0x40122000,
-		.pa_end		= 0x401220ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> mcbsp1 */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1 = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_mcbsp1_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_mcbsp1_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcbsp1_dma_addrs[] = {
-	{
-		.name		= "dma",
-		.pa_start	= 0x49022000,
-		.pa_end		= 0x490220ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> mcbsp1 (dma) */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1_dma = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_mcbsp1_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_mcbsp1_dma_addrs,
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcbsp2_addrs[] = {
-	{
-		.name		= "mpu",
-		.pa_start	= 0x40124000,
-		.pa_end		= 0x401240ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> mcbsp2 */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2 = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_mcbsp2_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_mcbsp2_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcbsp2_dma_addrs[] = {
-	{
-		.name		= "dma",
-		.pa_start	= 0x49024000,
-		.pa_end		= 0x490240ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> mcbsp2 (dma) */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2_dma = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_mcbsp2_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_mcbsp2_dma_addrs,
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcbsp3_addrs[] = {
-	{
-		.name		= "mpu",
-		.pa_start	= 0x40126000,
-		.pa_end		= 0x401260ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> mcbsp3 */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3 = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_mcbsp3_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_mcbsp3_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcbsp3_dma_addrs[] = {
-	{
-		.name		= "dma",
-		.pa_start	= 0x49026000,
-		.pa_end		= 0x490260ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> mcbsp3 (dma) */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3_dma = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_mcbsp3_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_mcbsp3_dma_addrs,
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcbsp4_addrs[] = {
-	{
-		.pa_start	= 0x48096000,
-		.pa_end		= 0x480960ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mcbsp4 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mcbsp4_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mcbsp4_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcpdm_addrs[] = {
-	{
-		.name		= "mpu",
-		.pa_start	= 0x40132000,
-		.pa_end		= 0x4013207f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> mcpdm */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_mcpdm_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_mcpdm_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcpdm_dma_addrs[] = {
-	{
-		.name		= "dma",
-		.pa_start	= 0x49032000,
-		.pa_end		= 0x4903207f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> mcpdm (dma) */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm_dma = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_mcpdm_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_mcpdm_dma_addrs,
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcspi1_addrs[] = {
-	{
-		.pa_start	= 0x48098000,
-		.pa_end		= 0x480981ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mcspi1 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi1 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mcspi1_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mcspi1_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcspi2_addrs[] = {
-	{
-		.pa_start	= 0x4809a000,
-		.pa_end		= 0x4809a1ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mcspi2 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi2 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mcspi2_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mcspi2_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcspi3_addrs[] = {
-	{
-		.pa_start	= 0x480b8000,
-		.pa_end		= 0x480b81ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mcspi3 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi3 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mcspi3_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mcspi3_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mcspi4_addrs[] = {
-	{
-		.pa_start	= 0x480ba000,
-		.pa_end		= 0x480ba1ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mcspi4 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi4 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mcspi4_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mcspi4_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mmc1_addrs[] = {
-	{
-		.pa_start	= 0x4809c000,
-		.pa_end		= 0x4809c3ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mmc1 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc1 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mmc1_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mmc1_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mmc2_addrs[] = {
-	{
-		.pa_start	= 0x480b4000,
-		.pa_end		= 0x480b43ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mmc2 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc2 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mmc2_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mmc2_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mmc3_addrs[] = {
-	{
-		.pa_start	= 0x480ad000,
-		.pa_end		= 0x480ad3ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mmc3 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc3 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mmc3_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mmc3_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mmc4_addrs[] = {
-	{
-		.pa_start	= 0x480d1000,
-		.pa_end		= 0x480d13ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mmc4 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc4 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mmc4_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mmc4_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_mmc5_addrs[] = {
-	{
-		.pa_start	= 0x480d5000,
-		.pa_end		= 0x480d53ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> mmc5 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc5 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_mmc5_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_mmc5_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -5568,111 +4365,51 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_ocp2scp_usb_phy_addrs[] = {
-	{
-		.pa_start	= 0x4a0ad000,
-		.pa_end		= 0x4a0ad01f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_cfg -> ocp2scp_usb_phy */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp2scp_usb_phy = {
 	.master		= &omap44xx_l4_cfg_hwmod,
 	.slave		= &omap44xx_ocp2scp_usb_phy_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_ocp2scp_usb_phy_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_prcm_mpu_addrs[] = {
-	{
-		.pa_start	= 0x48243000,
-		.pa_end		= 0x48243fff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* mpu_private -> prcm_mpu */
 static struct omap_hwmod_ocp_if omap44xx_mpu_private__prcm_mpu = {
 	.master		= &omap44xx_mpu_private_hwmod,
 	.slave		= &omap44xx_prcm_mpu_hwmod,
 	.clk		= "l3_div_ck",
-	.addr		= omap44xx_prcm_mpu_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_cm_core_aon_addrs[] = {
-	{
-		.pa_start	= 0x4a004000,
-		.pa_end		= 0x4a004fff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_wkup -> cm_core_aon */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__cm_core_aon = {
 	.master		= &omap44xx_l4_wkup_hwmod,
 	.slave		= &omap44xx_cm_core_aon_hwmod,
 	.clk		= "l4_wkup_clk_mux_ck",
-	.addr		= omap44xx_cm_core_aon_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_cm_core_addrs[] = {
-	{
-		.pa_start	= 0x4a008000,
-		.pa_end		= 0x4a009fff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_cfg -> cm_core */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__cm_core = {
 	.master		= &omap44xx_l4_cfg_hwmod,
 	.slave		= &omap44xx_cm_core_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_cm_core_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_prm_addrs[] = {
-	{
-		.pa_start	= 0x4a306000,
-		.pa_end		= 0x4a307fff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_wkup -> prm */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__prm = {
 	.master		= &omap44xx_l4_wkup_hwmod,
 	.slave		= &omap44xx_prm_hwmod,
 	.clk		= "l4_wkup_clk_mux_ck",
-	.addr		= omap44xx_prm_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_scrm_addrs[] = {
-	{
-		.pa_start	= 0x4a30a000,
-		.pa_end		= 0x4a30a7ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_wkup -> scrm */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__scrm = {
 	.master		= &omap44xx_l4_wkup_hwmod,
 	.slave		= &omap44xx_scrm_hwmod,
 	.clk		= "l4_wkup_clk_mux_ck",
-	.addr		= omap44xx_scrm_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -5810,447 +4547,195 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer1_addrs[] = {
-	{
-		.pa_start	= 0x4a318000,
-		.pa_end		= 0x4a31807f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_wkup -> timer1 */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__timer1 = {
 	.master		= &omap44xx_l4_wkup_hwmod,
 	.slave		= &omap44xx_timer1_hwmod,
 	.clk		= "l4_wkup_clk_mux_ck",
-	.addr		= omap44xx_timer1_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer2_addrs[] = {
-	{
-		.pa_start	= 0x48032000,
-		.pa_end		= 0x4803207f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> timer2 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__timer2 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_timer2_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_timer2_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer3_addrs[] = {
-	{
-		.pa_start	= 0x48034000,
-		.pa_end		= 0x4803407f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> timer3 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__timer3 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_timer3_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_timer3_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer4_addrs[] = {
-	{
-		.pa_start	= 0x48036000,
-		.pa_end		= 0x4803607f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> timer4 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__timer4 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_timer4_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_timer4_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer5_addrs[] = {
-	{
-		.pa_start	= 0x40138000,
-		.pa_end		= 0x4013807f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> timer5 */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5 = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_timer5_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_timer5_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer5_dma_addrs[] = {
-	{
-		.pa_start	= 0x49038000,
-		.pa_end		= 0x4903807f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> timer5 (dma) */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5_dma = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_timer5_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_timer5_dma_addrs,
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer6_addrs[] = {
-	{
-		.pa_start	= 0x4013a000,
-		.pa_end		= 0x4013a07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> timer6 */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6 = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_timer6_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_timer6_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer6_dma_addrs[] = {
-	{
-		.pa_start	= 0x4903a000,
-		.pa_end		= 0x4903a07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> timer6 (dma) */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6_dma = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_timer6_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_timer6_dma_addrs,
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer7_addrs[] = {
-	{
-		.pa_start	= 0x4013c000,
-		.pa_end		= 0x4013c07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> timer7 */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7 = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_timer7_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_timer7_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer7_dma_addrs[] = {
-	{
-		.pa_start	= 0x4903c000,
-		.pa_end		= 0x4903c07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> timer7 (dma) */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7_dma = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_timer7_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_timer7_dma_addrs,
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer8_addrs[] = {
-	{
-		.pa_start	= 0x4013e000,
-		.pa_end		= 0x4013e07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> timer8 */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8 = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_timer8_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_timer8_addrs,
 	.user		= OCP_USER_MPU,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer8_dma_addrs[] = {
-	{
-		.pa_start	= 0x4903e000,
-		.pa_end		= 0x4903e07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_abe -> timer8 (dma) */
 static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8_dma = {
 	.master		= &omap44xx_l4_abe_hwmod,
 	.slave		= &omap44xx_timer8_hwmod,
 	.clk		= "ocp_abe_iclk",
-	.addr		= omap44xx_timer8_dma_addrs,
 	.user		= OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer9_addrs[] = {
-	{
-		.pa_start	= 0x4803e000,
-		.pa_end		= 0x4803e07f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> timer9 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__timer9 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_timer9_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_timer9_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer10_addrs[] = {
-	{
-		.pa_start	= 0x48086000,
-		.pa_end		= 0x4808607f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> timer10 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__timer10 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_timer10_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_timer10_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_timer11_addrs[] = {
-	{
-		.pa_start	= 0x48088000,
-		.pa_end		= 0x4808807f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> timer11 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__timer11 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_timer11_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_timer11_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_uart1_addrs[] = {
-	{
-		.pa_start	= 0x4806a000,
-		.pa_end		= 0x4806a0ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> uart1 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__uart1 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_uart1_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_uart1_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_uart2_addrs[] = {
-	{
-		.pa_start	= 0x4806c000,
-		.pa_end		= 0x4806c0ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> uart2 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__uart2 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_uart2_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_uart2_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_uart3_addrs[] = {
-	{
-		.pa_start	= 0x48020000,
-		.pa_end		= 0x480200ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> uart3 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__uart3 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_uart3_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_uart3_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_uart4_addrs[] = {
-	{
-		.pa_start	= 0x4806e000,
-		.pa_end		= 0x4806e0ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_per -> uart4 */
 static struct omap_hwmod_ocp_if omap44xx_l4_per__uart4 = {
 	.master		= &omap44xx_l4_per_hwmod,
 	.slave		= &omap44xx_uart4_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_uart4_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_usb_host_fs_addrs[] = {
-	{
-		.pa_start	= 0x4a0a9000,
-		.pa_end		= 0x4a0a93ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_cfg -> usb_host_fs */
 static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_cfg__usb_host_fs = {
 	.master		= &omap44xx_l4_cfg_hwmod,
 	.slave		= &omap44xx_usb_host_fs_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_usb_host_fs_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = {
-	{
-		.name		= "uhh",
-		.pa_start	= 0x4a064000,
-		.pa_end		= 0x4a0647ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{
-		.name		= "ohci",
-		.pa_start	= 0x4a064800,
-		.pa_end		= 0x4a064bff,
-	},
-	{
-		.name		= "ehci",
-		.pa_start	= 0x4a064c00,
-		.pa_end		= 0x4a064fff,
-	},
-	{}
-};
-
 /* l4_cfg -> usb_host_hs */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = {
 	.master		= &omap44xx_l4_cfg_hwmod,
 	.slave		= &omap44xx_usb_host_hs_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_usb_host_hs_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_usb_otg_hs_addrs[] = {
-	{
-		.pa_start	= 0x4a0ab000,
-		.pa_end		= 0x4a0ab7ff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_cfg -> usb_otg_hs */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_otg_hs = {
 	.master		= &omap44xx_l4_cfg_hwmod,
 	.slave		= &omap44xx_usb_otg_hs_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_usb_otg_hs_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_usb_tll_hs_addrs[] = {
-	{
-		.name		= "tll",
-		.pa_start	= 0x4a062000,
-		.pa_end		= 0x4a063fff,
-		.flags		= ADDR_TYPE_RT
-	},
-	{}
-};
-
 /* l4_cfg -> usb_tll_hs */
 static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = {
 	.master		= &omap44xx_l4_cfg_hwmod,
 	.slave		= &omap44xx_usb_tll_hs_hwmod,
 	.clk		= "l4_div_ck",
-	.addr		= omap44xx_usb_tll_hs_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_addr_space omap44xx_wd_timer2_addrs[] = {
-	{
-		.pa_start	= 0x4a314000,
-		.pa_end		= 0x4a31407f,
-		.flags		= ADDR_TYPE_RT
-	},
-	{ }
-};
-
 /* l4_wkup -> wd_timer2 */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__wd_timer2 = {
 	.master		= &omap44xx_l4_wkup_hwmod,
 	.slave		= &omap44xx_wd_timer2_hwmod,
 	.clk		= "l4_wkup_clk_mux_ck",
-	.addr		= omap44xx_wd_timer2_addrs,
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
@@ -6290,14 +4775,25 @@ static struct omap_hwmod_ocp_if omap44xx
 	.user		= OCP_USER_SDMA,
 };
 
+/* mpu -> emif1 */
+static struct omap_hwmod_ocp_if omap44xx_mpu__emif1 = {
+	.master		= &omap44xx_mpu_hwmod,
+	.slave		= &omap44xx_emif1_hwmod,
+	.clk		= "l3_div_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> emif2 */
+static struct omap_hwmod_ocp_if omap44xx_mpu__emif2 = {
+	.master		= &omap44xx_mpu_hwmod,
+	.slave		= &omap44xx_emif2_hwmod,
+	.clk		= "l3_div_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
-	&omap44xx_c2c__c2c_target_fw,
-	&omap44xx_l4_cfg__c2c_target_fw,
 	&omap44xx_l3_main_1__dmm,
 	&omap44xx_mpu__dmm,
-	&omap44xx_c2c__emif_fw,
-	&omap44xx_dmm__emif_fw,
-	&omap44xx_l4_cfg__emif_fw,
 	&omap44xx_iva__l3_instr,
 	&omap44xx_l3_main_3__l3_instr,
 	&omap44xx_ocp_wp_noc__l3_instr,
@@ -6308,7 +4804,6 @@ static struct omap_hwmod_ocp_if *omap44x
 	&omap44xx_mmc1__l3_main_1,
 	&omap44xx_mmc2__l3_main_1,
 	&omap44xx_mpu__l3_main_1,
-	&omap44xx_c2c_target_fw__l3_main_2,
 	&omap44xx_debugss__l3_main_2,
 	&omap44xx_dma_system__l3_main_2,
 	&omap44xx_fdif__l3_main_2,
@@ -6364,8 +4859,6 @@ static struct omap_hwmod_ocp_if *omap44x
 	&omap44xx_l3_main_2__dss_venc,
 	&omap44xx_l4_per__dss_venc,
 	&omap44xx_l4_per__elm,
-	&omap44xx_emif_fw__emif1,
-	&omap44xx_emif_fw__emif2,
 	&omap44xx_l4_cfg__fdif,
 	&omap44xx_l4_wkup__gpio1,
 	&omap44xx_l4_per__gpio2,
@@ -6450,6 +4943,8 @@ static struct omap_hwmod_ocp_if *omap44x
 	&omap44xx_l4_wkup__wd_timer2,
 	&omap44xx_l4_abe__wd_timer3,
 	&omap44xx_l4_abe__wd_timer3_dma,
+	&omap44xx_mpu__emif1,
+	&omap44xx_mpu__emif2,
 	NULL,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_54xx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod_54xx_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod_54xx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2151 @@
+/*
+ * Hardware modules present on the OMAP54xx chips
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Paul Walmsley
+ * Benoit Cousson
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/power/smartreflex.h>
+#include <linux/i2c-omap.h>
+
+#include <linux/omap-dma.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod.h"
+#include "omap_hwmod_common_data.h"
+#include "cm1_54xx.h"
+#include "cm2_54xx.h"
+#include "prm54xx.h"
+#include "prm-regbits-54xx.h"
+#include "i2c.h"
+#include "mmc.h"
+#include "wd_timer.h"
+
+/* Base offset for all OMAP5 interrupts external to MPUSS */
+#define OMAP54XX_IRQ_GIC_START	32
+
+/* Base offset for all OMAP5 dma requests */
+#define OMAP54XX_DMA_REQ_START	1
+
+
+/*
+ * IP blocks
+ */
+
+/*
+ * 'dmm' class
+ * instance(s): dmm
+ */
+static struct omap_hwmod_class omap54xx_dmm_hwmod_class = {
+	.name	= "dmm",
+};
+
+/* dmm */
+static struct omap_hwmod omap54xx_dmm_hwmod = {
+	.name		= "dmm",
+	.class		= &omap54xx_dmm_hwmod_class,
+	.clkdm_name	= "emif_clkdm",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_EMIF_DMM_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_EMIF_DMM_CONTEXT_OFFSET,
+		},
+	},
+};
+
+/*
+ * 'l3' class
+ * instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3
+ */
+static struct omap_hwmod_class omap54xx_l3_hwmod_class = {
+	.name	= "l3",
+};
+
+/* l3_instr */
+static struct omap_hwmod omap54xx_l3_instr_hwmod = {
+	.name		= "l3_instr",
+	.class		= &omap54xx_l3_hwmod_class,
+	.clkdm_name	= "l3instr_clkdm",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+};
+
+/* l3_main_1 */
+static struct omap_hwmod omap54xx_l3_main_1_hwmod = {
+	.name		= "l3_main_1",
+	.class		= &omap54xx_l3_hwmod_class,
+	.clkdm_name	= "l3main1_clkdm",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L3MAIN1_L3_MAIN_1_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET,
+		},
+	},
+};
+
+/* l3_main_2 */
+static struct omap_hwmod omap54xx_l3_main_2_hwmod = {
+	.name		= "l3_main_2",
+	.class		= &omap54xx_l3_hwmod_class,
+	.clkdm_name	= "l3main2_clkdm",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L3MAIN2_L3_MAIN_2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L3MAIN2_L3_MAIN_2_CONTEXT_OFFSET,
+		},
+	},
+};
+
+/* l3_main_3 */
+static struct omap_hwmod omap54xx_l3_main_3_hwmod = {
+	.name		= "l3_main_3",
+	.class		= &omap54xx_l3_hwmod_class,
+	.clkdm_name	= "l3instr_clkdm",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L3INSTR_L3_MAIN_3_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L3INSTR_L3_MAIN_3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+};
+
+/*
+ * 'l4' class
+ * instance(s): l4_abe, l4_cfg, l4_per, l4_wkup
+ */
+static struct omap_hwmod_class omap54xx_l4_hwmod_class = {
+	.name	= "l4",
+};
+
+/* l4_abe */
+static struct omap_hwmod omap54xx_l4_abe_hwmod = {
+	.name		= "l4_abe",
+	.class		= &omap54xx_l4_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_L4_ABE_CLKCTRL_OFFSET,
+			.flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+		},
+	},
+};
+
+/* l4_cfg */
+static struct omap_hwmod omap54xx_l4_cfg_hwmod = {
+	.name		= "l4_cfg",
+	.class		= &omap54xx_l4_hwmod_class,
+	.clkdm_name	= "l4cfg_clkdm",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET,
+		},
+	},
+};
+
+/* l4_per */
+static struct omap_hwmod omap54xx_l4_per_hwmod = {
+	.name		= "l4_per",
+	.class		= &omap54xx_l4_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_L4_PER_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_L4_PER_CONTEXT_OFFSET,
+		},
+	},
+};
+
+/* l4_wkup */
+static struct omap_hwmod omap54xx_l4_wkup_hwmod = {
+	.name		= "l4_wkup",
+	.class		= &omap54xx_l4_hwmod_class,
+	.clkdm_name	= "wkupaon_clkdm",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET,
+		},
+	},
+};
+
+/*
+ * 'mpu_bus' class
+ * instance(s): mpu_private
+ */
+static struct omap_hwmod_class omap54xx_mpu_bus_hwmod_class = {
+	.name	= "mpu_bus",
+};
+
+/* mpu_private */
+static struct omap_hwmod omap54xx_mpu_private_hwmod = {
+	.name		= "mpu_private",
+	.class		= &omap54xx_mpu_bus_hwmod_class,
+	.clkdm_name	= "mpu_clkdm",
+	.prcm = {
+		.omap4 = {
+			.flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT,
+		},
+	},
+};
+
+/*
+ * 'counter' class
+ * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_counter_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= SYSC_HAS_SIDLEMODE,
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_counter_hwmod_class = {
+	.name	= "counter",
+	.sysc	= &omap54xx_counter_sysc,
+};
+
+/* counter_32k */
+static struct omap_hwmod omap54xx_counter_32k_hwmod = {
+	.name		= "counter_32k",
+	.class		= &omap54xx_counter_hwmod_class,
+	.clkdm_name	= "wkupaon_clkdm",
+	.flags		= HWMOD_SWSUP_SIDLE,
+	.main_clk	= "wkupaon_iclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET,
+		},
+	},
+};
+
+/*
+ * 'dma' class
+ * dma controller for data exchange between memory to memory (i.e. internal or
+ * external memory) and gp peripherals to memory or memory to gp peripherals
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_dma_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x002c,
+	.syss_offs	= 0x0028,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+			   SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+			   SYSS_HAS_RESET_STATUS),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_dma_hwmod_class = {
+	.name	= "dma",
+	.sysc	= &omap54xx_dma_sysc,
+};
+
+/* dma dev_attr */
+static struct omap_dma_dev_attr dma_dev_attr = {
+	.dev_caps	= RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+			  IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+	.lch_count	= 32,
+};
+
+/* dma_system */
+static struct omap_hwmod_irq_info omap54xx_dma_system_irqs[] = {
+	{ .name = "0", .irq = 12 + OMAP54XX_IRQ_GIC_START },
+	{ .name = "1", .irq = 13 + OMAP54XX_IRQ_GIC_START },
+	{ .name = "2", .irq = 14 + OMAP54XX_IRQ_GIC_START },
+	{ .name = "3", .irq = 15 + OMAP54XX_IRQ_GIC_START },
+	{ .irq = -1 }
+};
+
+static struct omap_hwmod omap54xx_dma_system_hwmod = {
+	.name		= "dma_system",
+	.class		= &omap54xx_dma_hwmod_class,
+	.clkdm_name	= "dma_clkdm",
+	.mpu_irqs	= omap54xx_dma_system_irqs,
+	.main_clk	= "l3_iclk_div",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET,
+		},
+	},
+	.dev_attr	= &dma_dev_attr,
+};
+
+/*
+ * 'dmic' class
+ * digital microphone controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_dmic_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_dmic_hwmod_class = {
+	.name	= "dmic",
+	.sysc	= &omap54xx_dmic_sysc,
+};
+
+/* dmic */
+static struct omap_hwmod omap54xx_dmic_hwmod = {
+	.name		= "dmic",
+	.class		= &omap54xx_dmic_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	.main_clk	= "dmic_gfclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_DMIC_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_ABE_DMIC_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/*
+ * 'emif' class
+ * external memory interface no1 (wrapper)
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_emif_sysc = {
+	.rev_offs	= 0x0000,
+};
+
+static struct omap_hwmod_class omap54xx_emif_hwmod_class = {
+	.name	= "emif",
+	.sysc	= &omap54xx_emif_sysc,
+};
+
+/* emif1 */
+static struct omap_hwmod omap54xx_emif1_hwmod = {
+	.name		= "emif1",
+	.class		= &omap54xx_emif_hwmod_class,
+	.clkdm_name	= "emif_clkdm",
+	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+	.main_clk	= "dpll_core_h11x2_ck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_EMIF_EMIF1_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_EMIF_EMIF1_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+};
+
+/* emif2 */
+static struct omap_hwmod omap54xx_emif2_hwmod = {
+	.name		= "emif2",
+	.class		= &omap54xx_emif_hwmod_class,
+	.clkdm_name	= "emif_clkdm",
+	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+	.main_clk	= "dpll_core_h11x2_ck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_EMIF_EMIF2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_EMIF_EMIF2_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_gpio_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0114,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+			   SYSS_HAS_RESET_STATUS),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_gpio_hwmod_class = {
+	.name	= "gpio",
+	.sysc	= &omap54xx_gpio_sysc,
+	.rev	= 2,
+};
+
+/* gpio dev_attr */
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+	.bank_width	= 32,
+	.dbck_flag	= true,
+};
+
+/* gpio1 */
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio1_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio1_hwmod = {
+	.name		= "gpio1",
+	.class		= &omap54xx_gpio_hwmod_class,
+	.clkdm_name	= "wkupaon_clkdm",
+	.main_clk	= "wkupaon_iclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+	.opt_clks	= gpio1_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio1_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
+};
+
+/* gpio2 */
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio2_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio2_hwmod = {
+	.name		= "gpio2",
+	.class		= &omap54xx_gpio_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+	.main_clk	= "l4_root_clk_div",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_GPIO2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_GPIO2_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+	.opt_clks	= gpio2_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio2_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
+};
+
+/* gpio3 */
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio3_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio3_hwmod = {
+	.name		= "gpio3",
+	.class		= &omap54xx_gpio_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+	.main_clk	= "l4_root_clk_div",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_GPIO3_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_GPIO3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+	.opt_clks	= gpio3_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio3_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
+};
+
+/* gpio4 */
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio4_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio4_hwmod = {
+	.name		= "gpio4",
+	.class		= &omap54xx_gpio_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+	.main_clk	= "l4_root_clk_div",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_GPIO4_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_GPIO4_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+	.opt_clks	= gpio4_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio4_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
+};
+
+/* gpio5 */
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio5_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio5_hwmod = {
+	.name		= "gpio5",
+	.class		= &omap54xx_gpio_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+	.main_clk	= "l4_root_clk_div",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_GPIO5_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_GPIO5_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+	.opt_clks	= gpio5_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio5_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
+};
+
+/* gpio6 */
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio6_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio6_hwmod = {
+	.name		= "gpio6",
+	.class		= &omap54xx_gpio_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+	.main_clk	= "l4_root_clk_div",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_GPIO6_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_GPIO6_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+	.opt_clks	= gpio6_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio6_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
+};
+
+/* gpio7 */
+static struct omap_hwmod_opt_clk gpio7_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio7_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio7_hwmod = {
+	.name		= "gpio7",
+	.class		= &omap54xx_gpio_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+	.main_clk	= "l4_root_clk_div",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_GPIO7_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_GPIO7_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+	.opt_clks	= gpio7_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio7_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
+};
+
+/* gpio8 */
+static struct omap_hwmod_opt_clk gpio8_opt_clks[] = {
+	{ .role = "dbclk", .clk = "gpio8_dbclk" },
+};
+
+static struct omap_hwmod omap54xx_gpio8_hwmod = {
+	.name		= "gpio8",
+	.class		= &omap54xx_gpio_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+	.main_clk	= "l4_root_clk_div",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_GPIO8_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_GPIO8_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+	.opt_clks	= gpio8_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(gpio8_opt_clks),
+	.dev_attr	= &gpio_dev_attr,
+};
+
+/*
+ * 'i2c' class
+ * multimaster high-speed i2c controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_i2c_sysc = {
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0090,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+			   SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP),
+	.clockact	= CLOCKACT_TEST_ICLK,
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_i2c_hwmod_class = {
+	.name	= "i2c",
+	.sysc	= &omap54xx_i2c_sysc,
+	.reset	= &omap_i2c_reset,
+	.rev	= OMAP_I2C_IP_VERSION_2,
+};
+
+/* i2c dev_attr */
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+	.flags	= OMAP_I2C_FLAG_BUS_SHIFT_NONE,
+};
+
+/* i2c1 */
+static struct omap_hwmod omap54xx_i2c1_hwmod = {
+	.name		= "i2c1",
+	.class		= &omap54xx_i2c_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+	.main_clk	= "func_96m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_I2C1_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_I2C1_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.dev_attr	= &i2c_dev_attr,
+};
+
+/* i2c2 */
+static struct omap_hwmod omap54xx_i2c2_hwmod = {
+	.name		= "i2c2",
+	.class		= &omap54xx_i2c_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+	.main_clk	= "func_96m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_I2C2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_I2C2_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.dev_attr	= &i2c_dev_attr,
+};
+
+/* i2c3 */
+static struct omap_hwmod omap54xx_i2c3_hwmod = {
+	.name		= "i2c3",
+	.class		= &omap54xx_i2c_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+	.main_clk	= "func_96m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_I2C3_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_I2C3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.dev_attr	= &i2c_dev_attr,
+};
+
+/* i2c4 */
+static struct omap_hwmod omap54xx_i2c4_hwmod = {
+	.name		= "i2c4",
+	.class		= &omap54xx_i2c_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+	.main_clk	= "func_96m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_I2C4_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_I2C4_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.dev_attr	= &i2c_dev_attr,
+};
+
+/* i2c5 */
+static struct omap_hwmod omap54xx_i2c5_hwmod = {
+	.name		= "i2c5",
+	.class		= &omap54xx_i2c_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
+	.main_clk	= "func_96m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_I2C5_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_I2C5_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.dev_attr	= &i2c_dev_attr,
+};
+
+/*
+ * 'kbd' class
+ * keyboard controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_kbd_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_kbd_hwmod_class = {
+	.name	= "kbd",
+	.sysc	= &omap54xx_kbd_sysc,
+};
+
+/* kbd */
+static struct omap_hwmod omap54xx_kbd_hwmod = {
+	.name		= "kbd",
+	.class		= &omap54xx_kbd_hwmod_class,
+	.clkdm_name	= "wkupaon_clkdm",
+	.main_clk	= "sys_32k_ck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_WKUPAON_KBD_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_mcbsp_sysc = {
+	.sysc_offs	= 0x008c,
+	.sysc_flags	= (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_mcbsp_hwmod_class = {
+	.name	= "mcbsp",
+	.sysc	= &omap54xx_mcbsp_sysc,
+	.rev	= MCBSP_CONFIG_TYPE4,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = {
+	{ .role = "pad_fck", .clk = "pad_clks_ck" },
+	{ .role = "prcm_fck", .clk = "mcbsp1_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap54xx_mcbsp1_hwmod = {
+	.name		= "mcbsp1",
+	.class		= &omap54xx_mcbsp_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	.main_clk	= "mcbsp1_gfclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_MCBSP1_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_ABE_MCBSP1_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.opt_clks	= mcbsp1_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(mcbsp1_opt_clks),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = {
+	{ .role = "pad_fck", .clk = "pad_clks_ck" },
+	{ .role = "prcm_fck", .clk = "mcbsp2_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap54xx_mcbsp2_hwmod = {
+	.name		= "mcbsp2",
+	.class		= &omap54xx_mcbsp_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	.main_clk	= "mcbsp2_gfclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_MCBSP2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_ABE_MCBSP2_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.opt_clks	= mcbsp2_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(mcbsp2_opt_clks),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = {
+	{ .role = "pad_fck", .clk = "pad_clks_ck" },
+	{ .role = "prcm_fck", .clk = "mcbsp3_sync_mux_ck" },
+};
+
+static struct omap_hwmod omap54xx_mcbsp3_hwmod = {
+	.name		= "mcbsp3",
+	.class		= &omap54xx_mcbsp_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	.main_clk	= "mcbsp3_gfclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_MCBSP3_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_ABE_MCBSP3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.opt_clks	= mcbsp3_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(mcbsp3_opt_clks),
+};
+
+/*
+ * 'mcpdm' class
+ * multi channel pdm controller (proprietary interface with phoenix power
+ * ic)
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_mcpdm_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_mcpdm_hwmod_class = {
+	.name	= "mcpdm",
+	.sysc	= &omap54xx_mcpdm_sysc,
+};
+
+/* mcpdm */
+static struct omap_hwmod omap54xx_mcpdm_hwmod = {
+	.name		= "mcpdm",
+	.class		= &omap54xx_mcpdm_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	/*
+	 * It's suspected that the McPDM requires an off-chip main
+	 * functional clock, controlled via I2C.  This IP block is
+	 * currently reset very early during boot, before I2C is
+	 * available, so it doesn't seem that we have any choice in
+	 * the kernel other than to avoid resetting it.  XXX This is
+	 * really a hardware issue workaround: every IP block should
+	 * be able to source its main functional clock from either
+	 * on-chip or off-chip sources.  McPDM seems to be the only
+	 * current exception.
+	 */
+
+	.flags		= HWMOD_EXT_OPT_MAIN_CLK,
+	.main_clk	= "pad_clks_ck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_MCPDM_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_ABE_MCPDM_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/*
+ * 'mcspi' class
+ * multichannel serial port interface (mcspi) / master/slave synchronous serial
+ * bus
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_mcspi_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_mcspi_hwmod_class = {
+	.name	= "mcspi",
+	.sysc	= &omap54xx_mcspi_sysc,
+	.rev	= OMAP4_MCSPI_REV,
+};
+
+/* mcspi1 */
+/* mcspi1 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi1_dev_attr = {
+	.num_chipselect	= 4,
+};
+
+static struct omap_hwmod omap54xx_mcspi1_hwmod = {
+	.name		= "mcspi1",
+	.class		= &omap54xx_mcspi_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI1_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.dev_attr	= &mcspi1_dev_attr,
+};
+
+/* mcspi2 */
+/* mcspi2 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi2_dev_attr = {
+	.num_chipselect	= 2,
+};
+
+static struct omap_hwmod omap54xx_mcspi2_hwmod = {
+	.name		= "mcspi2",
+	.class		= &omap54xx_mcspi_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.dev_attr	= &mcspi2_dev_attr,
+};
+
+/* mcspi3 */
+/* mcspi3 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi3_dev_attr = {
+	.num_chipselect	= 2,
+};
+
+static struct omap_hwmod omap54xx_mcspi3_hwmod = {
+	.name		= "mcspi3",
+	.class		= &omap54xx_mcspi_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI3_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.dev_attr	= &mcspi3_dev_attr,
+};
+
+/* mcspi4 */
+/* mcspi4 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi4_dev_attr = {
+	.num_chipselect	= 1,
+};
+
+static struct omap_hwmod omap54xx_mcspi4_hwmod = {
+	.name		= "mcspi4",
+	.class		= &omap54xx_mcspi_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_MCSPI4_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.dev_attr	= &mcspi4_dev_attr,
+};
+
+/*
+ * 'mmc' class
+ * multimedia card high-speed/sd/sdio (mmc/sd/sdio) host controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_mmc_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE |
+			   SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+			   MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_mmc_hwmod_class = {
+	.name	= "mmc",
+	.sysc	= &omap54xx_mmc_sysc,
+};
+
+/* mmc1 */
+static struct omap_hwmod_opt_clk mmc1_opt_clks[] = {
+	{ .role = "32khz_clk", .clk = "mmc1_32khz_clk" },
+};
+
+/* mmc1 dev_attr */
+static struct omap_mmc_dev_attr mmc1_dev_attr = {
+	.flags	= OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+static struct omap_hwmod omap54xx_mmc1_hwmod = {
+	.name		= "mmc1",
+	.class		= &omap54xx_mmc_hwmod_class,
+	.clkdm_name	= "l3init_clkdm",
+	.main_clk	= "mmc1_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L3INIT_MMC1_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L3INIT_MMC1_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+	.opt_clks	= mmc1_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(mmc1_opt_clks),
+	.dev_attr	= &mmc1_dev_attr,
+};
+
+/* mmc2 */
+static struct omap_hwmod omap54xx_mmc2_hwmod = {
+	.name		= "mmc2",
+	.class		= &omap54xx_mmc_hwmod_class,
+	.clkdm_name	= "l3init_clkdm",
+	.main_clk	= "mmc2_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L3INIT_MMC2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L3INIT_MMC2_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* mmc3 */
+static struct omap_hwmod omap54xx_mmc3_hwmod = {
+	.name		= "mmc3",
+	.class		= &omap54xx_mmc_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_MMC3_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_MMC3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* mmc4 */
+static struct omap_hwmod omap54xx_mmc4_hwmod = {
+	.name		= "mmc4",
+	.class		= &omap54xx_mmc_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_MMC4_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_MMC4_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* mmc5 */
+static struct omap_hwmod omap54xx_mmc5_hwmod = {
+	.name		= "mmc5",
+	.class		= &omap54xx_mmc_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_96m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_MMC5_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_MMC5_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/*
+ * 'mpu' class
+ * mpu sub-system
+ */
+
+static struct omap_hwmod_class omap54xx_mpu_hwmod_class = {
+	.name	= "mpu",
+};
+
+/* mpu */
+static struct omap_hwmod omap54xx_mpu_hwmod = {
+	.name		= "mpu",
+	.class		= &omap54xx_mpu_hwmod_class,
+	.clkdm_name	= "mpu_clkdm",
+	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+	.main_clk	= "dpll_mpu_m2_ck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_MPU_MPU_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_MPU_MPU_CONTEXT_OFFSET,
+		},
+	},
+};
+
+/*
+ * 'timer' class
+ * general purpose timer module with accurate 1ms tick
+ * This class contains several variants: ['timer_1ms', 'timer']
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_timer_1ms_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type2,
+	.clockact	= CLOCKACT_TEST_ICLK,
+};
+
+static struct omap_hwmod_class omap54xx_timer_1ms_hwmod_class = {
+	.name	= "timer",
+	.sysc	= &omap54xx_timer_1ms_sysc,
+};
+
+static struct omap_hwmod_class_sysconfig omap54xx_timer_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_timer_hwmod_class = {
+	.name	= "timer",
+	.sysc	= &omap54xx_timer_sysc,
+};
+
+/* timer1 */
+static struct omap_hwmod omap54xx_timer1_hwmod = {
+	.name		= "timer1",
+	.class		= &omap54xx_timer_1ms_hwmod_class,
+	.clkdm_name	= "wkupaon_clkdm",
+	.main_clk	= "timer1_gfclk_mux",
+	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer2 */
+static struct omap_hwmod omap54xx_timer2_hwmod = {
+	.name		= "timer2",
+	.class		= &omap54xx_timer_1ms_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "timer2_gfclk_mux",
+	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_TIMER2_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer3 */
+static struct omap_hwmod omap54xx_timer3_hwmod = {
+	.name		= "timer3",
+	.class		= &omap54xx_timer_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "timer3_gfclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_TIMER3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer4 */
+static struct omap_hwmod omap54xx_timer4_hwmod = {
+	.name		= "timer4",
+	.class		= &omap54xx_timer_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "timer4_gfclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_TIMER4_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer5 */
+static struct omap_hwmod omap54xx_timer5_hwmod = {
+	.name		= "timer5",
+	.class		= &omap54xx_timer_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	.main_clk	= "timer5_gfclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_TIMER5_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_ABE_TIMER5_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer6 */
+static struct omap_hwmod omap54xx_timer6_hwmod = {
+	.name		= "timer6",
+	.class		= &omap54xx_timer_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	.main_clk	= "timer6_gfclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_TIMER6_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_ABE_TIMER6_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer7 */
+static struct omap_hwmod omap54xx_timer7_hwmod = {
+	.name		= "timer7",
+	.class		= &omap54xx_timer_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	.main_clk	= "timer7_gfclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_TIMER7_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_ABE_TIMER7_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer8 */
+static struct omap_hwmod omap54xx_timer8_hwmod = {
+	.name		= "timer8",
+	.class		= &omap54xx_timer_hwmod_class,
+	.clkdm_name	= "abe_clkdm",
+	.main_clk	= "timer8_gfclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_ABE_TIMER8_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_ABE_TIMER8_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer9 */
+static struct omap_hwmod omap54xx_timer9_hwmod = {
+	.name		= "timer9",
+	.class		= &omap54xx_timer_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "timer9_gfclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_TIMER9_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer10 */
+static struct omap_hwmod omap54xx_timer10_hwmod = {
+	.name		= "timer10",
+	.class		= &omap54xx_timer_1ms_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "timer10_gfclk_mux",
+	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_TIMER10_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* timer11 */
+static struct omap_hwmod omap54xx_timer11_hwmod = {
+	.name		= "timer11",
+	.class		= &omap54xx_timer_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "timer11_gfclk_mux",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_TIMER11_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/*
+ * 'uart' class
+ * universal asynchronous receiver/transmitter (uart)
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_uart_sysc = {
+	.rev_offs	= 0x0050,
+	.sysc_offs	= 0x0054,
+	.syss_offs	= 0x0058,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+			   SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+			   SYSS_HAS_RESET_STATUS),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_uart_hwmod_class = {
+	.name	= "uart",
+	.sysc	= &omap54xx_uart_sysc,
+};
+
+/* uart1 */
+static struct omap_hwmod omap54xx_uart1_hwmod = {
+	.name		= "uart1",
+	.class		= &omap54xx_uart_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_UART1_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_UART1_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* uart2 */
+static struct omap_hwmod omap54xx_uart2_hwmod = {
+	.name		= "uart2",
+	.class		= &omap54xx_uart_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_UART2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_UART2_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* uart3 */
+static struct omap_hwmod omap54xx_uart3_hwmod = {
+	.name		= "uart3",
+	.class		= &omap54xx_uart_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= DEBUG_OMAP4UART3_FLAGS,
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_UART3_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_UART3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* uart4 */
+static struct omap_hwmod omap54xx_uart4_hwmod = {
+	.name		= "uart4",
+	.class		= &omap54xx_uart_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.flags		= DEBUG_OMAP4UART4_FLAGS,
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_UART4_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_UART4_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* uart5 */
+static struct omap_hwmod omap54xx_uart5_hwmod = {
+	.name		= "uart5",
+	.class		= &omap54xx_uart_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_UART5_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_UART5_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/* uart6 */
+static struct omap_hwmod omap54xx_uart6_hwmod = {
+	.name		= "uart6",
+	.class		= &omap54xx_uart_hwmod_class,
+	.clkdm_name	= "l4per_clkdm",
+	.main_clk	= "func_48m_fclk",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L4PER_UART6_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L4PER_UART6_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/*
+ * 'usb_otg_ss' class
+ * 2.0 super speed (usb_otg_ss) controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_usb_otg_ss_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.sysc_flags	= (SYSC_HAS_DMADISABLE | SYSC_HAS_MIDLEMODE |
+			   SYSC_HAS_SIDLEMODE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+			   MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap54xx_usb_otg_ss_hwmod_class = {
+	.name	= "usb_otg_ss",
+	.sysc	= &omap54xx_usb_otg_ss_sysc,
+};
+
+/* usb_otg_ss */
+static struct omap_hwmod_opt_clk usb_otg_ss_opt_clks[] = {
+	{ .role = "refclk960m", .clk = "usb_otg_ss_refclk960m" },
+};
+
+static struct omap_hwmod omap54xx_usb_otg_ss_hwmod = {
+	.name		= "usb_otg_ss",
+	.class		= &omap54xx_usb_otg_ss_hwmod_class,
+	.clkdm_name	= "l3init_clkdm",
+	.flags		= HWMOD_SWSUP_SIDLE,
+	.main_clk	= "dpll_core_h13x2_ck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_L3INIT_USB_OTG_SS_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_L3INIT_USB_OTG_SS_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_HWCTRL,
+		},
+	},
+	.opt_clks	= usb_otg_ss_opt_clks,
+	.opt_clks_cnt	= ARRAY_SIZE(usb_otg_ss_opt_clks),
+};
+
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap54xx_wd_timer_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   SIDLE_SMART_WKUP),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap54xx_wd_timer_hwmod_class = {
+	.name		= "wd_timer",
+	.sysc		= &omap54xx_wd_timer_sysc,
+	.pre_shutdown	= &omap2_wd_timer_disable,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod omap54xx_wd_timer2_hwmod = {
+	.name		= "wd_timer2",
+	.class		= &omap54xx_wd_timer_hwmod_class,
+	.clkdm_name	= "wkupaon_clkdm",
+	.main_clk	= "sys_32k_ck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET,
+			.context_offs = OMAP54XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+
+/*
+ * Interfaces
+ */
+
+/* l3_main_1 -> dmm */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__dmm = {
+	.master		= &omap54xx_l3_main_1_hwmod,
+	.slave		= &omap54xx_dmm_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_SDMA,
+};
+
+/* l3_main_3 -> l3_instr */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_3__l3_instr = {
+	.master		= &omap54xx_l3_main_3_hwmod,
+	.slave		= &omap54xx_l3_instr_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__l3_main_1 = {
+	.master		= &omap54xx_l3_main_2_hwmod,
+	.slave		= &omap54xx_l3_main_1_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_1 = {
+	.master		= &omap54xx_l4_cfg_hwmod,
+	.slave		= &omap54xx_l3_main_1_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap54xx_mpu__l3_main_1 = {
+	.master		= &omap54xx_mpu_hwmod,
+	.slave		= &omap54xx_l3_main_1_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU,
+};
+
+/* l3_main_1 -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l3_main_2 = {
+	.master		= &omap54xx_l3_main_1_hwmod,
+	.slave		= &omap54xx_l3_main_2_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU,
+};
+
+/* l4_cfg -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_2 = {
+	.master		= &omap54xx_l4_cfg_hwmod,
+	.slave		= &omap54xx_l3_main_2_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l3_main_3 = {
+	.master		= &omap54xx_l3_main_1_hwmod,
+	.slave		= &omap54xx_l3_main_3_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU,
+};
+
+/* l3_main_2 -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__l3_main_3 = {
+	.master		= &omap54xx_l3_main_2_hwmod,
+	.slave		= &omap54xx_l3_main_3_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_3 = {
+	.master		= &omap54xx_l4_cfg_hwmod,
+	.slave		= &omap54xx_l3_main_3_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_abe */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_abe = {
+	.master		= &omap54xx_l3_main_1_hwmod,
+	.slave		= &omap54xx_l4_abe_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> l4_abe */
+static struct omap_hwmod_ocp_if omap54xx_mpu__l4_abe = {
+	.master		= &omap54xx_mpu_hwmod,
+	.slave		= &omap54xx_l4_abe_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_cfg */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_cfg = {
+	.master		= &omap54xx_l3_main_1_hwmod,
+	.slave		= &omap54xx_l4_cfg_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> l4_per */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__l4_per = {
+	.master		= &omap54xx_l3_main_2_hwmod,
+	.slave		= &omap54xx_l4_per_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_wkup */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l4_wkup = {
+	.master		= &omap54xx_l3_main_1_hwmod,
+	.slave		= &omap54xx_l4_wkup_hwmod,
+	.clk		= "wkupaon_iclk_mux",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> mpu_private */
+static struct omap_hwmod_ocp_if omap54xx_mpu__mpu_private = {
+	.master		= &omap54xx_mpu_hwmod,
+	.slave		= &omap54xx_mpu_private_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> counter_32k */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__counter_32k = {
+	.master		= &omap54xx_l4_wkup_hwmod,
+	.slave		= &omap54xx_counter_32k_hwmod,
+	.clk		= "wkupaon_iclk_mux",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap54xx_dma_system_addrs[] = {
+	{
+		.pa_start	= 0x4a056000,
+		.pa_end		= 0x4a056fff,
+		.flags		= ADDR_TYPE_RT
+	},
+	{ }
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__dma_system = {
+	.master		= &omap54xx_l4_cfg_hwmod,
+	.slave		= &omap54xx_dma_system_hwmod,
+	.clk		= "l4_root_clk_div",
+	.addr		= omap54xx_dma_system_addrs,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_abe -> dmic */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__dmic = {
+	.master		= &omap54xx_l4_abe_hwmod,
+	.slave		= &omap54xx_dmic_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU,
+};
+
+/* mpu -> emif1 */
+static struct omap_hwmod_ocp_if omap54xx_mpu__emif1 = {
+	.master		= &omap54xx_mpu_hwmod,
+	.slave		= &omap54xx_emif1_hwmod,
+	.clk		= "dpll_core_h11x2_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> emif2 */
+static struct omap_hwmod_ocp_if omap54xx_mpu__emif2 = {
+	.master		= &omap54xx_mpu_hwmod,
+	.slave		= &omap54xx_emif2_hwmod,
+	.clk		= "dpll_core_h11x2_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__gpio1 = {
+	.master		= &omap54xx_l4_wkup_hwmod,
+	.slave		= &omap54xx_gpio1_hwmod,
+	.clk		= "wkupaon_iclk_mux",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio2 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_gpio2_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio3 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_gpio3_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio4 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_gpio4_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio5 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_gpio5_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio6 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio6 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_gpio6_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio7 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio7 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_gpio7_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio8 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__gpio8 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_gpio8_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c1 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_i2c1_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c2 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_i2c2_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c3 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_i2c3_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c4 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_i2c4_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> i2c5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__i2c5 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_i2c5_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> kbd */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__kbd = {
+	.master		= &omap54xx_l4_wkup_hwmod,
+	.slave		= &omap54xx_kbd_hwmod,
+	.clk		= "wkupaon_iclk_mux",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_abe -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp1 = {
+	.master		= &omap54xx_l4_abe_hwmod,
+	.slave		= &omap54xx_mcbsp1_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU,
+};
+
+/* l4_abe -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp2 = {
+	.master		= &omap54xx_l4_abe_hwmod,
+	.slave		= &omap54xx_mcbsp2_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU,
+};
+
+/* l4_abe -> mcbsp3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcbsp3 = {
+	.master		= &omap54xx_l4_abe_hwmod,
+	.slave		= &omap54xx_mcbsp3_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU,
+};
+
+/* l4_abe -> mcpdm */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcpdm = {
+	.master		= &omap54xx_l4_abe_hwmod,
+	.slave		= &omap54xx_mcpdm_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU,
+};
+
+/* l4_per -> mcspi1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi1 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_mcspi1_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mcspi2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi2 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_mcspi2_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mcspi3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi3 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_mcspi3_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mcspi4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mcspi4 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_mcspi4_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc1 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_mmc1_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc2 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_mmc2_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc3 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_mmc3_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc4 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_mmc4_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> mmc5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__mmc5 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_mmc5_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> mpu */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = {
+	.master		= &omap54xx_l4_cfg_hwmod,
+	.slave		= &omap54xx_mpu_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> timer1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = {
+	.master		= &omap54xx_l4_wkup_hwmod,
+	.slave		= &omap54xx_timer1_hwmod,
+	.clk		= "wkupaon_iclk_mux",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer2 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_timer2_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer3 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_timer3_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer4 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_timer4_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_abe -> timer5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer5 = {
+	.master		= &omap54xx_l4_abe_hwmod,
+	.slave		= &omap54xx_timer5_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU,
+};
+
+/* l4_abe -> timer6 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer6 = {
+	.master		= &omap54xx_l4_abe_hwmod,
+	.slave		= &omap54xx_timer6_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU,
+};
+
+/* l4_abe -> timer7 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer7 = {
+	.master		= &omap54xx_l4_abe_hwmod,
+	.slave		= &omap54xx_timer7_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU,
+};
+
+/* l4_abe -> timer8 */
+static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer8 = {
+	.master		= &omap54xx_l4_abe_hwmod,
+	.slave		= &omap54xx_timer8_hwmod,
+	.clk		= "abe_iclk",
+	.user		= OCP_USER_MPU,
+};
+
+/* l4_per -> timer9 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer9 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_timer9_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer10 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer10 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_timer10_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> timer11 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__timer11 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_timer11_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart1 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart1 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_uart1_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart2 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_uart2_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart3 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart3 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_uart3_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart4 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart4 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_uart4_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart5 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart5 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_uart5_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> uart6 */
+static struct omap_hwmod_ocp_if omap54xx_l4_per__uart6 = {
+	.master		= &omap54xx_l4_per_hwmod,
+	.slave		= &omap54xx_uart6_hwmod,
+	.clk		= "l4_root_clk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> usb_otg_ss */
+static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_otg_ss = {
+	.master		= &omap54xx_l4_cfg_hwmod,
+	.slave		= &omap54xx_usb_otg_ss_hwmod,
+	.clk		= "dpll_core_h13x2_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_ocp_if omap54xx_l4_wkup__wd_timer2 = {
+	.master		= &omap54xx_l4_wkup_hwmod,
+	.slave		= &omap54xx_wd_timer2_hwmod,
+	.clk		= "wkupaon_iclk_mux",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
+	&omap54xx_l3_main_1__dmm,
+	&omap54xx_l3_main_3__l3_instr,
+	&omap54xx_l3_main_2__l3_main_1,
+	&omap54xx_l4_cfg__l3_main_1,
+	&omap54xx_mpu__l3_main_1,
+	&omap54xx_l3_main_1__l3_main_2,
+	&omap54xx_l4_cfg__l3_main_2,
+	&omap54xx_l3_main_1__l3_main_3,
+	&omap54xx_l3_main_2__l3_main_3,
+	&omap54xx_l4_cfg__l3_main_3,
+	&omap54xx_l3_main_1__l4_abe,
+	&omap54xx_mpu__l4_abe,
+	&omap54xx_l3_main_1__l4_cfg,
+	&omap54xx_l3_main_2__l4_per,
+	&omap54xx_l3_main_1__l4_wkup,
+	&omap54xx_mpu__mpu_private,
+	&omap54xx_l4_wkup__counter_32k,
+	&omap54xx_l4_cfg__dma_system,
+	&omap54xx_l4_abe__dmic,
+	&omap54xx_mpu__emif1,
+	&omap54xx_mpu__emif2,
+	&omap54xx_l4_wkup__gpio1,
+	&omap54xx_l4_per__gpio2,
+	&omap54xx_l4_per__gpio3,
+	&omap54xx_l4_per__gpio4,
+	&omap54xx_l4_per__gpio5,
+	&omap54xx_l4_per__gpio6,
+	&omap54xx_l4_per__gpio7,
+	&omap54xx_l4_per__gpio8,
+	&omap54xx_l4_per__i2c1,
+	&omap54xx_l4_per__i2c2,
+	&omap54xx_l4_per__i2c3,
+	&omap54xx_l4_per__i2c4,
+	&omap54xx_l4_per__i2c5,
+	&omap54xx_l4_wkup__kbd,
+	&omap54xx_l4_abe__mcbsp1,
+	&omap54xx_l4_abe__mcbsp2,
+	&omap54xx_l4_abe__mcbsp3,
+	&omap54xx_l4_abe__mcpdm,
+	&omap54xx_l4_per__mcspi1,
+	&omap54xx_l4_per__mcspi2,
+	&omap54xx_l4_per__mcspi3,
+	&omap54xx_l4_per__mcspi4,
+	&omap54xx_l4_per__mmc1,
+	&omap54xx_l4_per__mmc2,
+	&omap54xx_l4_per__mmc3,
+	&omap54xx_l4_per__mmc4,
+	&omap54xx_l4_per__mmc5,
+	&omap54xx_l4_cfg__mpu,
+	&omap54xx_l4_wkup__timer1,
+	&omap54xx_l4_per__timer2,
+	&omap54xx_l4_per__timer3,
+	&omap54xx_l4_per__timer4,
+	&omap54xx_l4_abe__timer5,
+	&omap54xx_l4_abe__timer6,
+	&omap54xx_l4_abe__timer7,
+	&omap54xx_l4_abe__timer8,
+	&omap54xx_l4_per__timer9,
+	&omap54xx_l4_per__timer10,
+	&omap54xx_l4_per__timer11,
+	&omap54xx_l4_per__uart1,
+	&omap54xx_l4_per__uart2,
+	&omap54xx_l4_per__uart3,
+	&omap54xx_l4_per__uart4,
+	&omap54xx_l4_per__uart5,
+	&omap54xx_l4_per__uart6,
+	&omap54xx_l4_cfg__usb_otg_ss,
+	&omap54xx_l4_wkup__wd_timer2,
+	NULL,
+};
+
+int __init omap54xx_hwmod_init(void)
+{
+	omap_hwmod_init();
+	return omap_hwmod_register_links(omap54xx_hwmod_ocp_ifs);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod.c	2013-08-25 20:43:22.000000000 -0400
@@ -2386,7 +2386,7 @@ static void __init _init_mpu_rt_base(str
 
 		np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
 		if (np)
-			va_start = of_iomap(np, 0);
+			va_start = of_iomap(np, oh->mpu_rt_idx);
 	} else {
 		va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap_hwmod.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap_hwmod.h	2013-08-25 20:43:22.000000000 -0400
@@ -95,6 +95,54 @@ extern struct omap_hwmod_sysc_fields oma
 #define MODULEMODE_HWCTRL		1
 #define MODULEMODE_SWCTRL		2
 
+#define DEBUG_OMAP2UART1_FLAGS	0
+#define DEBUG_OMAP2UART2_FLAGS	0
+#define DEBUG_OMAP2UART3_FLAGS	0
+#define DEBUG_OMAP3UART3_FLAGS	0
+#define DEBUG_OMAP3UART4_FLAGS	0
+#define DEBUG_OMAP4UART3_FLAGS	0
+#define DEBUG_OMAP4UART4_FLAGS	0
+#define DEBUG_TI81XXUART1_FLAGS	0
+#define DEBUG_TI81XXUART2_FLAGS	0
+#define DEBUG_TI81XXUART3_FLAGS	0
+#define DEBUG_AM33XXUART1_FLAGS	0
+
+#define DEBUG_OMAPUART_FLAGS	(HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET)
+
+#if defined(CONFIG_DEBUG_OMAP2UART1)
+#undef DEBUG_OMAP2UART1_FLAGS
+#define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP2UART2)
+#undef DEBUG_OMAP2UART2_FLAGS
+#define DEBUG_OMAP2UART2_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP2UART3)
+#undef DEBUG_OMAP2UART3_FLAGS
+#define DEBUG_OMAP2UART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP3UART3)
+#undef DEBUG_OMAP3UART3_FLAGS
+#define DEBUG_OMAP3UART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP3UART4)
+#undef DEBUG_OMAP3UART4_FLAGS
+#define DEBUG_OMAP3UART4_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP4UART3)
+#undef DEBUG_OMAP4UART3_FLAGS
+#define DEBUG_OMAP4UART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_OMAP4UART4)
+#undef DEBUG_OMAP4UART4_FLAGS
+#define DEBUG_OMAP4UART4_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_TI81XXUART1)
+#undef DEBUG_TI81XXUART1_FLAGS
+#define DEBUG_TI81XXUART1_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_TI81XXUART2)
+#undef DEBUG_TI81XXUART2_FLAGS
+#define DEBUG_TI81XXUART2_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_TI81XXUART3)
+#undef DEBUG_TI81XXUART3_FLAGS
+#define DEBUG_TI81XXUART3_FLAGS DEBUG_OMAPUART_FLAGS
+#elif defined(CONFIG_DEBUG_AM33XXUART1)
+#undef DEBUG_AM33XXUART1_FLAGS
+#define DEBUG_AM33XXUART1_FLAGS DEBUG_OMAPUART_FLAGS
+#endif
 
 /**
  * struct omap_hwmod_mux_info - hwmod specific mux configuration
@@ -568,6 +616,7 @@ struct omap_hwmod_link {
  * @voltdm: pointer to voltage domain (filled in at runtime)
  * @dev_attr: arbitrary device attributes that can be passed to the driver
  * @_sysc_cache: internal-use hwmod flags
+ * @mpu_rt_idx: index of device address space for register target (for DT boot)
  * @_mpu_rt_va: cached register target start address (internal use)
  * @_mpu_port: cached MPU register target slave (internal use)
  * @opt_clks_cnt: number of @opt_clks
@@ -617,6 +666,7 @@ struct omap_hwmod {
 	struct list_head		node;
 	struct omap_hwmod_ocp_if	*_mpu_port;
 	u16				flags;
+	u8				mpu_rt_idx;
 	u8				response_lat;
 	u8				rst_lines_cnt;
 	u8				opt_clks_cnt;
@@ -699,6 +749,7 @@ extern int omap2420_hwmod_init(void);
 extern int omap2430_hwmod_init(void);
 extern int omap3xxx_hwmod_init(void);
 extern int omap44xx_hwmod_init(void);
+extern int omap54xx_hwmod_init(void);
 extern int am33xx_hwmod_init(void);
 
 extern int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap-mpuss-lowpower.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap-mpuss-lowpower.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap-mpuss-lowpower.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap-mpuss-lowpower.c	2013-08-25 20:43:22.000000000 -0400
@@ -71,10 +71,43 @@ struct omap4_cpu_pm_info {
 	void (*secondary_startup)(void);
 };
 
+/**
+ * struct cpu_pm_ops - CPU pm operations
+ * @finish_suspend:	CPU suspend finisher function pointer
+ * @resume:		CPU resume function pointer
+ * @scu_prepare:	CPU Snoop Control program function pointer
+ *
+ * Structure holds functions pointer for CPU low power operations like
+ * suspend, resume and scu programming.
+ */
+struct cpu_pm_ops {
+	int (*finish_suspend)(unsigned long cpu_state);
+	void (*resume)(void);
+	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
+};
+
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
 static void __iomem *sar_base;
 
+static int default_finish_suspend(unsigned long cpu_state)
+{
+	omap_do_wfi();
+	return 0;
+}
+
+static void dummy_cpu_resume(void)
+{}
+
+static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
+{}
+
+struct cpu_pm_ops omap_pm_ops = {
+	.finish_suspend		= default_finish_suspend,
+	.resume			= dummy_cpu_resume,
+	.scu_prepare		= dummy_scu_prepare,
+};
+
 /*
  * Program the wakeup routine address for the CPU0 and CPU1
  * used for OFF or DORMANT wakeup.
@@ -158,11 +191,12 @@ static void save_l2x0_context(void)
 {
 	u32 val;
 	void __iomem *l2x0_base = omap4_get_l2cache_base();
-
-	val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
-	__raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
-	val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
-	__raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
+	if (l2x0_base) {
+		val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
+		__raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
+		val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
+		__raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
+	}
 }
 #else
 static void save_l2x0_context(void)
@@ -225,14 +259,17 @@ int omap4_enter_lowpower(unsigned int cp
 
 	cpu_clear_prev_logic_pwrst(cpu);
 	pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
-	set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
-	scu_pwrst_prepare(cpu, power_state);
+	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume));
+	omap_pm_ops.scu_prepare(cpu, power_state);
 	l2x0_pwrst_prepare(cpu, save_state);
 
 	/*
 	 * Call low level function  with targeted low power state.
 	 */
-	cpu_suspend(save_state, omap4_finish_suspend);
+	if (save_state)
+		cpu_suspend(save_state, omap_pm_ops.finish_suspend);
+	else
+		omap_pm_ops.finish_suspend(save_state);
 
 	/*
 	 * Restore the CPUx power state to ON otherwise CPUx
@@ -254,7 +291,7 @@ int omap4_enter_lowpower(unsigned int cp
  * @cpu : CPU ID
  * @power_state: CPU low power state.
  */
-int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
+int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 {
 	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
 	unsigned int cpu_state = 0;
@@ -268,14 +305,14 @@ int __cpuinit omap4_hotplug_cpu(unsigned
 	pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
 	pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
 	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
-	scu_pwrst_prepare(cpu, power_state);
+	omap_pm_ops.scu_prepare(cpu, power_state);
 
 	/*
 	 * CPU never retuns back if targeted power state is OFF mode.
 	 * CPU ONLINE follows normal CPU ONLINE ptah via
-	 * omap_secondary_startup().
+	 * omap4_secondary_startup().
 	 */
-	omap4_finish_suspend(cpu_state);
+	omap_pm_ops.finish_suspend(cpu_state);
 
 	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
 	return 0;
@@ -319,9 +356,9 @@ int __init omap4_mpuss_init(void)
 	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
 	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
 	if (cpu_is_omap446x())
-		pm_info->secondary_startup = omap_secondary_startup_4460;
+		pm_info->secondary_startup = omap4460_secondary_startup;
 	else
-		pm_info->secondary_startup = omap_secondary_startup;
+		pm_info->secondary_startup = omap4_secondary_startup;
 
 	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
 	if (!pm_info->pwrdm) {
@@ -352,6 +389,12 @@ int __init omap4_mpuss_init(void)
 
 	save_l2x0_context();
 
+	if (cpu_is_omap44xx()) {
+		omap_pm_ops.finish_suspend = omap4_finish_suspend;
+		omap_pm_ops.resume = omap4_cpu_resume;
+		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
+	}
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap-smp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap-smp.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap-smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap-smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,7 +51,7 @@ void __iomem *omap4_get_scu_base(void)
 	return scu_base;
 }
 
-static void __cpuinit omap4_secondary_init(unsigned int cpu)
+static void omap4_secondary_init(unsigned int cpu)
 {
 	/*
 	 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
@@ -72,7 +72,7 @@ static void __cpuinit omap4_secondary_in
 	spin_unlock(&boot_lock);
 }
 
-static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	static struct clockdomain *cpu1_clkdm;
 	static bool booted;
@@ -87,7 +87,7 @@ static int __cpuinit omap4_boot_secondar
 
 	/*
 	 * Update the AuxCoreBoot0 with boot state for secondary core.
-	 * omap_secondary_startup() routine will hold the secondary core till
+	 * omap4_secondary_startup() routine will hold the secondary core till
 	 * the AuxCoreBoot1 register is updated with cpu state
 	 * A barrier is added to ensure that write buffer is drained
 	 */
@@ -200,7 +200,7 @@ static void __init omap4_smp_init_cpus(v
 
 static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
 {
-	void *startup_addr = omap_secondary_startup;
+	void *startup_addr = omap4_secondary_startup;
 	void __iomem *base = omap_get_wakeupgen_base();
 
 	/*
@@ -211,7 +211,7 @@ static void __init omap4_smp_prepare_cpu
 		scu_enable(scu_base);
 
 	if (cpu_is_omap446x()) {
-		startup_addr = omap_secondary_startup_4460;
+		startup_addr = omap4460_secondary_startup;
 		pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/omap-wakeupgen.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap-wakeupgen.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/omap-wakeupgen.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/omap-wakeupgen.c	2013-08-25 20:43:22.000000000 -0400
@@ -323,8 +323,8 @@ static void irq_save_secure_context(void
 #endif
 
 #ifdef CONFIG_HOTPLUG_CPU
-static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self,
-					 unsigned long action, void *hcpu)
+static int irq_cpu_hotplug_notify(struct notifier_block *self,
+				  unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned int)hcpu;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/pm44xx.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/pm44xx.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/pm44xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/pm44xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- * OMAP4 Power Management Routines
+ * OMAP4+ Power Management Routines
  *
- * Copyright (C) 2010-2011 Texas Instruments, Inc.
+ * Copyright (C) 2010-2013 Texas Instruments, Inc.
  * Rajendra Nayak <rnayak@ti.com>
  * Santosh Shilimkar <santosh.shilimkar@ti.com>
  *
@@ -135,16 +135,16 @@ static void omap_default_idle(void)
 }
 
 /**
- * omap4_pm_init - Init routine for OMAP4 PM
+ * omap4_init_static_deps - Add OMAP4 static dependencies
  *
- * Initializes all powerdomain and clockdomain target states
- * and all PRCM settings.
+ * Add needed static clockdomain dependencies on OMAP4 devices.
+ * Return: 0 on success or 'err' on failures
  */
-int __init omap4_pm_init(void)
+static inline int omap4_init_static_deps(void)
 {
-	int ret;
 	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
 	struct clockdomain *ducati_clkdm, *l3_2_clkdm;
+	int ret = 0;
 
 	if (omap_rev() == OMAP4430_REV_ES1_0) {
 		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
@@ -163,7 +163,7 @@ int __init omap4_pm_init(void)
 	ret = pwrdm_for_each(pwrdms_setup, NULL);
 	if (ret) {
 		pr_err("Failed to setup powerdomains\n");
-		goto err2;
+		return ret;
 	}
 
 	/*
@@ -171,6 +171,10 @@ int __init omap4_pm_init(void)
 	 * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
 	 * expected. The hardware recommendation is to enable static
 	 * dependencies for these to avoid system lock ups or random crashes.
+	 * The L4 wakeup depedency is added to workaround the OCP sync hardware
+	 * BUG with 32K synctimer which lead to incorrect timer value read
+	 * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
+	 * are part of L4 wakeup clockdomain.
 	 */
 	mpuss_clkdm = clkdm_lookup("mpuss_clkdm");
 	emif_clkdm = clkdm_lookup("l3_emif_clkdm");
@@ -179,7 +183,7 @@ int __init omap4_pm_init(void)
 	ducati_clkdm = clkdm_lookup("ducati_clkdm");
 	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
 		(!l3_2_clkdm) || (!ducati_clkdm))
-		goto err2;
+		return -EINVAL;
 
 	ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
 	ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
@@ -188,9 +192,42 @@ int __init omap4_pm_init(void)
 	ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);
 	if (ret) {
 		pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n");
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+/**
+ * omap4_pm_init - Init routine for OMAP4+ devices
+ *
+ * Initializes all powerdomain and clockdomain target states
+ * and all PRCM settings.
+ * Return: Returns the error code returned by called functions.
+ */
+int __init omap4_pm_init(void)
+{
+	int ret = 0;
+
+	if (omap_rev() == OMAP4430_REV_ES1_0) {
+		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
+		return -ENODEV;
+	}
+
+	pr_info("Power Management for TI OMAP4+ devices.\n");
+
+	ret = pwrdm_for_each(pwrdms_setup, NULL);
+	if (ret) {
+		pr_err("Failed to setup powerdomains.\n");
 		goto err2;
 	}
 
+	if (cpu_is_omap44xx()) {
+		ret = omap4_init_static_deps();
+		if (ret)
+			goto err2;
+	}
+
 	ret = omap4_mpuss_init();
 	if (ret) {
 		pr_err("Failed to initialise OMAP4 MPUSS\n");
@@ -206,7 +243,8 @@ int __init omap4_pm_init(void)
 	/* Overwrite the default cpu_do_idle() */
 	arm_pm_idle = omap_default_idle;
 
-	omap4_idle_init();
+	if (cpu_is_omap44xx())
+		omap4_idle_init();
 
 err2:
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/pmu.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/pmu.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/pmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/pmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,10 +54,7 @@ static int __init omap2_init_pmu(unsigne
 	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",
 	     dev_name);
 
-	if (IS_ERR(omap_pmu_dev))
-		return PTR_ERR(omap_pmu_dev);
-
-	return 0;
+	return PTR_RET(omap_pmu_dev);
 }
 
 static int __init omap_init_pmu(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/powerdomain.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/powerdomain.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/powerdomain.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/powerdomain.c	2013-08-25 20:43:22.000000000 -0400
@@ -102,6 +102,10 @@ static int _pwrdm_register(struct powerd
 	if (_pwrdm_lookup(pwrdm->name))
 		return -EEXIST;
 
+	if (arch_pwrdm && arch_pwrdm->pwrdm_has_voltdm)
+		if (!arch_pwrdm->pwrdm_has_voltdm())
+			goto skip_voltdm;
+
 	voltdm = voltdm_lookup(pwrdm->voltdm.name);
 	if (!voltdm) {
 		pr_err("powerdomain: %s: voltagedomain %s does not exist\n",
@@ -111,6 +115,7 @@ static int _pwrdm_register(struct powerd
 	pwrdm->voltdm.ptr = voltdm;
 	INIT_LIST_HEAD(&pwrdm->voltdm_node);
 	voltdm_add_pwrdm(voltdm, pwrdm);
+skip_voltdm:
 	spin_lock_init(&pwrdm->_lock);
 
 	list_add(&pwrdm->node, &pwrdm_list);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/powerdomain.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/powerdomain.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/powerdomain.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/powerdomain.h	2013-08-25 20:43:22.000000000 -0400
@@ -166,6 +166,7 @@ struct powerdomain {
  * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd
  * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep
  * @pwrdm_wait_transition: Wait for a pd state transition to complete
+ * @pwrdm_has_voltdm: Check if a voltdm association is needed
  *
  * Regarding @pwrdm_set_lowpwrstchange: On the OMAP2 and 3-family
  * chips, a powerdomain's power state is not allowed to directly
@@ -196,6 +197,7 @@ struct pwrdm_ops {
 	int	(*pwrdm_disable_hdwr_sar)(struct powerdomain *pwrdm);
 	int	(*pwrdm_set_lowpwrstchange)(struct powerdomain *pwrdm);
 	int	(*pwrdm_wait_transition)(struct powerdomain *pwrdm);
+	int	(*pwrdm_has_voltdm)(void);
 };
 
 int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs);
@@ -253,6 +255,7 @@ extern void omap243x_powerdomains_init(v
 extern void omap3xxx_powerdomains_init(void);
 extern void am33xx_powerdomains_init(void);
 extern void omap44xx_powerdomains_init(void);
+extern void omap54xx_powerdomains_init(void);
 
 extern struct pwrdm_ops omap2_pwrdm_operations;
 extern struct pwrdm_ops omap3_pwrdm_operations;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/powerdomains3xxx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/powerdomains3xxx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/powerdomains3xxx_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/powerdomains3xxx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -336,6 +336,54 @@ static struct powerdomain dpll5_pwrdm =
 	.voltdm		  = { .name = "core" },
 };
 
+static struct powerdomain device_81xx_pwrdm = {
+	.name		  = "device_pwrdm",
+	.prcm_offs	  = TI81XX_PRM_DEVICE_MOD,
+	.voltdm		  = { .name = "core" },
+};
+
+static struct powerdomain active_816x_pwrdm = {
+	.name		  = "active_pwrdm",
+	.prcm_offs	  = TI816X_PRM_ACTIVE_MOD,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.voltdm		  = { .name = "core" },
+};
+
+static struct powerdomain default_816x_pwrdm = {
+	.name		  = "default_pwrdm",
+	.prcm_offs	  = TI81XX_PRM_DEFAULT_MOD,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.voltdm		  = { .name = "core" },
+};
+
+static struct powerdomain ivahd0_816x_pwrdm = {
+	.name		  = "ivahd0_pwrdm",
+	.prcm_offs	  = TI816X_PRM_IVAHD0_MOD,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.voltdm		  = { .name = "mpu_iva" },
+};
+
+static struct powerdomain ivahd1_816x_pwrdm = {
+	.name		  = "ivahd1_pwrdm",
+	.prcm_offs	  = TI816X_PRM_IVAHD1_MOD,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.voltdm		  = { .name = "mpu_iva" },
+};
+
+static struct powerdomain ivahd2_816x_pwrdm = {
+	.name		  = "ivahd2_pwrdm",
+	.prcm_offs	  = TI816X_PRM_IVAHD2_MOD,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.voltdm		  = { .name = "mpu_iva" },
+};
+
+static struct powerdomain sgx_816x_pwrdm = {
+	.name		  = "sgx_pwrdm",
+	.prcm_offs	  = TI816X_PRM_SGX_MOD,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.voltdm		  = { .name = "core" },
+};
+
 /* As powerdomains are added or removed above, this list must also be changed */
 static struct powerdomain *powerdomains_omap3430_common[] __initdata = {
 	&wkup_omap2_pwrdm,
@@ -393,6 +441,17 @@ static struct powerdomain *powerdomains_
 	NULL
 };
 
+static struct powerdomain *powerdomains_ti81xx[] __initdata = {
+	&device_81xx_pwrdm,
+	&active_816x_pwrdm,
+	&default_816x_pwrdm,
+	&ivahd0_816x_pwrdm,
+	&ivahd1_816x_pwrdm,
+	&ivahd2_816x_pwrdm,
+	&sgx_816x_pwrdm,
+	NULL
+};
+
 void __init omap3xxx_powerdomains_init(void)
 {
 	unsigned int rev;
@@ -406,6 +465,9 @@ void __init omap3xxx_powerdomains_init(v
 
 	if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
 		pwrdm_register_pwrdms(powerdomains_am35x);
+	} else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1
+			|| rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) {
+		pwrdm_register_pwrdms(powerdomains_ti81xx);
 	} else {
 		pwrdm_register_pwrdms(powerdomains_omap3430_common);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/powerdomains54xx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/powerdomains54xx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/powerdomains54xx_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/powerdomains54xx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,331 @@
+/*
+ * OMAP54XX Power domains framework
+ *
+ * Copyright (C) 2013 Texas Instruments, Inc.
+ *
+ * Abhijit Pagare (abhijitpagare@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ * Paul Walmsley (paul@pwsan.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include "powerdomain.h"
+
+#include "prcm-common.h"
+#include "prcm44xx.h"
+#include "prm-regbits-54xx.h"
+#include "prm54xx.h"
+#include "prcm_mpu54xx.h"
+
+/* core_54xx_pwrdm: CORE power domain */
+static struct powerdomain core_54xx_pwrdm = {
+	.name		  = "core_pwrdm",
+	.voltdm		  = { .name = "core" },
+	.prcm_offs	  = OMAP54XX_PRM_CORE_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 5,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* core_nret_bank */
+		[1] = PWRSTS_OFF_RET,	/* core_ocmram */
+		[2] = PWRSTS_OFF_RET,	/* core_other_bank */
+		[3] = PWRSTS_OFF_RET,	/* ipu_l2ram */
+		[4] = PWRSTS_OFF_RET,	/* ipu_unicache */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* core_nret_bank */
+		[1] = PWRSTS_OFF_RET,	/* core_ocmram */
+		[2] = PWRSTS_OFF_RET,	/* core_other_bank */
+		[3] = PWRSTS_OFF_RET,	/* ipu_l2ram */
+		[4] = PWRSTS_OFF_RET,	/* ipu_unicache */
+	},
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* abe_54xx_pwrdm: Audio back end power domain */
+static struct powerdomain abe_54xx_pwrdm = {
+	.name		  = "abe_pwrdm",
+	.voltdm		  = { .name = "core" },
+	.prcm_offs	  = OMAP54XX_PRM_ABE_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF,
+	.banks		  = 2,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* aessmem */
+		[1] = PWRSTS_OFF_RET,	/* periphmem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* aessmem */
+		[1] = PWRSTS_OFF_RET,	/* periphmem */
+	},
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* coreaon_54xx_pwrdm: Always ON logic that sits in VDD_CORE voltage domain */
+static struct powerdomain coreaon_54xx_pwrdm = {
+	.name		  = "coreaon_pwrdm",
+	.voltdm		  = { .name = "core" },
+	.prcm_offs	  = OMAP54XX_PRM_COREAON_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_ON,
+};
+
+/* dss_54xx_pwrdm: Display subsystem power domain */
+static struct powerdomain dss_54xx_pwrdm = {
+	.name		  = "dss_pwrdm",
+	.voltdm		  = { .name = "core" },
+	.prcm_offs	  = OMAP54XX_PRM_DSS_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* dss_mem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* dss_mem */
+	},
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* cpu0_54xx_pwrdm: MPU0 processor and Neon coprocessor power domain */
+static struct powerdomain cpu0_54xx_pwrdm = {
+	.name		  = "cpu0_pwrdm",
+	.voltdm		  = { .name = "mpu" },
+	.prcm_offs	  = OMAP54XX_PRCM_MPU_PRM_C0_INST,
+	.prcm_partition	  = OMAP54XX_PRCM_MPU_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* cpu0_l1 */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_ON,	/* cpu0_l1 */
+	},
+};
+
+/* cpu1_54xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
+static struct powerdomain cpu1_54xx_pwrdm = {
+	.name		  = "cpu1_pwrdm",
+	.voltdm		  = { .name = "mpu" },
+	.prcm_offs	  = OMAP54XX_PRCM_MPU_PRM_C1_INST,
+	.prcm_partition	  = OMAP54XX_PRCM_MPU_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* cpu1_l1 */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_ON,	/* cpu1_l1 */
+	},
+};
+
+/* emu_54xx_pwrdm: Emulation power domain */
+static struct powerdomain emu_54xx_pwrdm = {
+	.name		  = "emu_pwrdm",
+	.voltdm		  = { .name = "wkup" },
+	.prcm_offs	  = OMAP54XX_PRM_EMU_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* emu_bank */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* emu_bank */
+	},
+};
+
+/* mpu_54xx_pwrdm: Modena processor and the Neon coprocessor power domain */
+static struct powerdomain mpu_54xx_pwrdm = {
+	.name		  = "mpu_pwrdm",
+	.voltdm		  = { .name = "mpu" },
+	.prcm_offs	  = OMAP54XX_PRM_MPU_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 2,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* mpu_l2 */
+		[1] = PWRSTS_RET,	/* mpu_ram */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* mpu_l2 */
+		[1] = PWRSTS_OFF_RET,	/* mpu_ram */
+	},
+};
+
+/* custefuse_54xx_pwrdm: Customer efuse controller power domain */
+static struct powerdomain custefuse_54xx_pwrdm = {
+	.name		  = "custefuse_pwrdm",
+	.voltdm		  = { .name = "core" },
+	.prcm_offs	  = OMAP54XX_PRM_CUSTEFUSE_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* dsp_54xx_pwrdm: Tesla processor power domain */
+static struct powerdomain dsp_54xx_pwrdm = {
+	.name		  = "dsp_pwrdm",
+	.voltdm		  = { .name = "mm" },
+	.prcm_offs	  = OMAP54XX_PRM_DSP_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 3,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* dsp_edma */
+		[1] = PWRSTS_OFF_RET,	/* dsp_l1 */
+		[2] = PWRSTS_OFF_RET,	/* dsp_l2 */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* dsp_edma */
+		[1] = PWRSTS_OFF_RET,	/* dsp_l1 */
+		[2] = PWRSTS_OFF_RET,	/* dsp_l2 */
+	},
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* cam_54xx_pwrdm: Camera subsystem power domain */
+static struct powerdomain cam_54xx_pwrdm = {
+	.name		  = "cam_pwrdm",
+	.voltdm		  = { .name = "core" },
+	.prcm_offs	  = OMAP54XX_PRM_CAM_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* cam_mem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* cam_mem */
+	},
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* l3init_54xx_pwrdm: L3 initators pheripherals power domain  */
+static struct powerdomain l3init_54xx_pwrdm = {
+	.name		  = "l3init_pwrdm",
+	.voltdm		  = { .name = "core" },
+	.prcm_offs	  = OMAP54XX_PRM_L3INIT_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF_RET,
+	.banks		  = 2,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* l3init_bank1 */
+		[1] = PWRSTS_OFF_RET,	/* l3init_bank2 */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* l3init_bank1 */
+		[1] = PWRSTS_OFF_RET,	/* l3init_bank2 */
+	},
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* gpu_54xx_pwrdm: 3D accelerator power domain */
+static struct powerdomain gpu_54xx_pwrdm = {
+	.name		  = "gpu_pwrdm",
+	.voltdm		  = { .name = "mm" },
+	.prcm_offs	  = OMAP54XX_PRM_GPU_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_ON,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* gpu_mem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* gpu_mem */
+	},
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* wkupaon_54xx_pwrdm: Wake-up power domain */
+static struct powerdomain wkupaon_54xx_pwrdm = {
+	.name		  = "wkupaon_pwrdm",
+	.voltdm		  = { .name = "wkup" },
+	.prcm_offs	  = OMAP54XX_PRM_WKUPAON_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_ON,
+	.banks		  = 1,
+	.pwrsts_mem_ret	= {
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_ON,	/* wkup_bank */
+	},
+};
+
+/* iva_54xx_pwrdm: IVA-HD power domain */
+static struct powerdomain iva_54xx_pwrdm = {
+	.name		  = "iva_pwrdm",
+	.voltdm		  = { .name = "mm" },
+	.prcm_offs	  = OMAP54XX_PRM_IVA_INST,
+	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
+	.pwrsts		  = PWRSTS_OFF_RET_ON,
+	.pwrsts_logic_ret = PWRSTS_OFF,
+	.banks		  = 4,
+	.pwrsts_mem_ret	= {
+		[0] = PWRSTS_OFF_RET,	/* hwa_mem */
+		[1] = PWRSTS_OFF_RET,	/* sl2_mem */
+		[2] = PWRSTS_OFF_RET,	/* tcm1_mem */
+		[3] = PWRSTS_OFF_RET,	/* tcm2_mem */
+	},
+	.pwrsts_mem_on	= {
+		[0] = PWRSTS_OFF_RET,	/* hwa_mem */
+		[1] = PWRSTS_OFF_RET,	/* sl2_mem */
+		[2] = PWRSTS_OFF_RET,	/* tcm1_mem */
+		[3] = PWRSTS_OFF_RET,	/* tcm2_mem */
+	},
+	.flags		  = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/*
+ * The following power domains are not under SW control
+ *
+ * mpuaon
+ * mmaon
+ */
+
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap54xx[] __initdata = {
+	&core_54xx_pwrdm,
+	&abe_54xx_pwrdm,
+	&coreaon_54xx_pwrdm,
+	&dss_54xx_pwrdm,
+	&cpu0_54xx_pwrdm,
+	&cpu1_54xx_pwrdm,
+	&emu_54xx_pwrdm,
+	&mpu_54xx_pwrdm,
+	&custefuse_54xx_pwrdm,
+	&dsp_54xx_pwrdm,
+	&cam_54xx_pwrdm,
+	&l3init_54xx_pwrdm,
+	&gpu_54xx_pwrdm,
+	&wkupaon_54xx_pwrdm,
+	&iva_54xx_pwrdm,
+	NULL
+};
+
+void __init omap54xx_powerdomains_init(void)
+{
+	pwrdm_register_platform_funcs(&omap4_pwrdm_operations);
+	pwrdm_register_pwrdms(powerdomains_omap54xx);
+	pwrdm_complete_init();
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm44xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm44xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm44xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm44xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,12 @@
 #define OMAP4430_SCRM_PARTITION			4
 #define OMAP4430_PRCM_MPU_PARTITION		5
 
+#define OMAP54XX_PRM_PARTITION			1
+#define OMAP54XX_CM_CORE_AON_PARTITION		2
+#define OMAP54XX_CM_CORE_PARTITION		3
+#define OMAP54XX_SCRM_PARTITION			4
+#define OMAP54XX_PRCM_MPU_PARTITION		5
+
 /*
  * OMAP4_MAX_PRCM_PARTITIONS: set to the highest value of the PRCM partition
  * IDs, plus one
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm-common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm-common.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm-common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm-common.h	2013-08-25 20:43:22.000000000 -0400
@@ -48,6 +48,17 @@
 #define OMAP3430_NEON_MOD				0xb00
 #define OMAP3430ES2_USBHOST_MOD				0xc00
 
+/*
+ * TI81XX PRM module offsets
+ */
+#define TI81XX_PRM_DEVICE_MOD			0x0000
+#define TI816X_PRM_ACTIVE_MOD			0x0a00
+#define TI81XX_PRM_DEFAULT_MOD			0x0b00
+#define TI816X_PRM_IVAHD0_MOD			0x0c00
+#define TI816X_PRM_IVAHD1_MOD			0x0d00
+#define TI816X_PRM_IVAHD2_MOD			0x0e00
+#define TI816X_PRM_SGX_MOD				0x0f00
+
 /* 24XX register bits shared between CM & PRM registers */
 
 /* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * OMAP44xx and OMAP54xx PRCM MPU function prototypes
+ *
+ * Copyright (C) 2010, 2013 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H
+
+#ifndef __ASSEMBLER__
+extern void __iomem *prcm_mpu_base;
+
+extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst,
+					    s16 idx);
+extern void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu);
+#endif
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm_mpu44xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm_mpu44xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm_mpu44xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm_mpu44xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,12 +25,9 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H
 #define __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H
 
+#include "prcm_mpu_44xx_54xx.h"
 #include "common.h"
 
-# ifndef __ASSEMBLER__
-extern void __iomem *prcm_mpu_base;
-# endif
-
 #define OMAP4430_PRCM_MPU_BASE			0x48243000
 
 #define OMAP44XX_PRCM_MPU_REGADDR(inst, reg)				\
@@ -98,13 +95,4 @@ extern void __iomem *prcm_mpu_base;
 #define OMAP4_CM_CPU1_CLKSTCTRL_OFFSET		0x0018
 #define OMAP4430_CM_CPU1_CLKSTCTRL		OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0018)
 
-/* Function prototypes */
-# ifndef __ASSEMBLER__
-extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx);
-extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx);
-extern u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst,
-					    s16 idx);
-extern void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu);
-# endif
-
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm_mpu54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm_mpu54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prcm_mpu54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prcm_mpu54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,87 @@
+/*
+ * OMAP54xx PRCM MPU instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU54XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU54XX_H
+
+#include "prcm_mpu_44xx_54xx.h"
+#include "common.h"
+
+#define OMAP54XX_PRCM_MPU_BASE			0x48243000
+
+#define OMAP54XX_PRCM_MPU_REGADDR(inst, reg)				\
+	OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE + (inst) + (reg))
+
+/* PRCM_MPU instances */
+#define OMAP54XX_PRCM_MPU_OCP_SOCKET_INST	0x0000
+#define OMAP54XX_PRCM_MPU_DEVICE_INST		0x0200
+#define OMAP54XX_PRCM_MPU_PRM_C0_INST		0x0400
+#define OMAP54XX_PRCM_MPU_CM_C0_INST		0x0600
+#define OMAP54XX_PRCM_MPU_PRM_C1_INST		0x0800
+#define OMAP54XX_PRCM_MPU_CM_C1_INST		0x0a00
+
+/* PRCM_MPU clockdomain register offsets (from instance start) */
+#define OMAP54XX_PRCM_MPU_CM_C0_CPU0_CDOFFS	0x0000
+#define OMAP54XX_PRCM_MPU_CM_C1_CPU1_CDOFFS	0x0000
+
+
+/*
+ * PRCM_MPU
+ *
+ * The PRCM_MPU is a local PRCM inside the MPU subsystem. For the PRCM (global)
+ * point of view the PRCM_MPU is a single entity. It shares the same
+ * programming model as the global PRCM and thus can be assimilate as two new
+ * MOD inside the PRCM
+ */
+
+/* PRCM_MPU.PRCM_MPU_OCP_SOCKET register offsets */
+#define OMAP54XX_REVISION_PRCM_MPU_OFFSET			0x0000
+
+/* PRCM_MPU.PRCM_MPU_DEVICE register offsets */
+#define OMAP54XX_PRCM_MPU_PRM_RSTST_OFFSET			0x0000
+#define OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET		0x0004
+#define OMAP54XX_PRM_FRAC_INCREMENTER_NUMERATOR_OFFSET		0x0010
+#define OMAP54XX_PRM_FRAC_INCREMENTER_DENUMERATOR_RELOAD_OFFSET	0x0014
+
+/* PRCM_MPU.PRCM_MPU_PRM_C0 register offsets */
+#define OMAP54XX_PM_CPU0_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_CPU0_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_CPU0_CPU0_RSTCTRL_OFFSET			0x0010
+#define OMAP54XX_RM_CPU0_CPU0_RSTST_OFFSET			0x0014
+#define OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET			0x0024
+
+/* PRCM_MPU.PRCM_MPU_CM_C0 register offsets */
+#define OMAP54XX_CM_CPU0_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_CPU0_CPU0_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_CPU0_CPU0_CLKCTRL				OMAP54XX_PRCM_MPU_REGADDR(OMAP54XX_PRCM_MPU_CM_C0_INST, 0x0020)
+
+/* PRCM_MPU.PRCM_MPU_PRM_C1 register offsets */
+#define OMAP54XX_PM_CPU1_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_CPU1_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_CPU1_CPU1_RSTCTRL_OFFSET			0x0010
+#define OMAP54XX_RM_CPU1_CPU1_RSTST_OFFSET			0x0014
+#define OMAP54XX_RM_CPU1_CPU1_CONTEXT_OFFSET			0x0024
+
+/* PRCM_MPU.PRCM_MPU_CM_C1 register offsets */
+#define OMAP54XX_CM_CPU1_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_CPU1_CPU1_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_CPU1_CPU1_CLKCTRL				OMAP54XX_PRCM_MPU_REGADDR(OMAP54XX_PRCM_MPU_CM_C1_INST, 0x0020)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prm33xx.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm33xx.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prm33xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm33xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -320,6 +320,12 @@ static int am33xx_pwrdm_wait_transition(
 	return 0;
 }
 
+static int am33xx_check_vcvp(void)
+{
+	/* No VC/VP on am33xx devices */
+	return 0;
+}
+
 struct pwrdm_ops am33xx_pwrdm_operations = {
 	.pwrdm_set_next_pwrst		= am33xx_pwrdm_set_next_pwrst,
 	.pwrdm_read_next_pwrst		= am33xx_pwrdm_read_next_pwrst,
@@ -335,4 +341,5 @@ struct pwrdm_ops am33xx_pwrdm_operations
 	.pwrdm_set_mem_onst		= am33xx_pwrdm_set_mem_onst,
 	.pwrdm_set_mem_retst		= am33xx_pwrdm_set_mem_retst,
 	.pwrdm_wait_transition		= am33xx_pwrdm_wait_transition,
+	.pwrdm_has_voltdm		= am33xx_check_vcvp,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prm44xx_54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm44xx_54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prm44xx_54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm44xx_54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,58 @@
+/*
+ * OMAP44xx and 54xx PRM common functions
+ *
+ * Copyright (C) 2009-2013 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM44XX_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM44XX_54XX_H
+
+/* Function prototypes */
+#ifndef __ASSEMBLER__
+
+extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+
+/* OMAP4/OMAP5-specific VP functions */
+u32 omap4_prm_vp_check_txdone(u8 vp_id);
+void omap4_prm_vp_clear_txdone(u8 vp_id);
+
+/*
+ * OMAP4/OMAP5 access functions for voltage controller (VC) and
+ * voltage proccessor (VP) in the PRM.
+ */
+extern u32 omap4_prm_vcvp_read(u8 offset);
+extern void omap4_prm_vcvp_write(u32 val, u8 offset);
+extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
+
+extern void omap44xx_prm_reconfigure_io_chain(void);
+
+/* PRM interrupt-related functions */
+extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
+extern void omap44xx_prm_ocp_barrier(void);
+extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
+extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
+
+extern int __init omap44xx_prm_init(void);
+extern u32 omap44xx_prm_get_reset_sources(void);
+
+#endif
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prm44xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm44xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prm44xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm44xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,7 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_PRM44XX_H
 #define __ARCH_ARM_MACH_OMAP2_PRM44XX_H
 
+#include "prm44xx_54xx.h"
 #include "prcm-common.h"
 #include "prm.h"
 
@@ -744,36 +745,4 @@
 #define OMAP4_PRM_VC_ERRST_OFFSET			0x00f8
 #define OMAP4430_PRM_VC_ERRST				OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f8)
 
-/* Function prototypes */
-# ifndef __ASSEMBLER__
-
-extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx);
-extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx);
-extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
-
-/* OMAP4-specific VP functions */
-u32 omap4_prm_vp_check_txdone(u8 vp_id);
-void omap4_prm_vp_clear_txdone(u8 vp_id);
-
-/*
- * OMAP4 access functions for voltage controller (VC) and
- * voltage proccessor (VP) in the PRM.
- */
-extern u32 omap4_prm_vcvp_read(u8 offset);
-extern void omap4_prm_vcvp_write(u32 val, u8 offset);
-extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
-
-extern void omap44xx_prm_reconfigure_io_chain(void);
-
-/* PRM interrupt-related functions */
-extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
-extern void omap44xx_prm_ocp_barrier(void);
-extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
-extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
-
-extern int __init omap44xx_prm_init(void);
-extern u32 omap44xx_prm_get_reset_sources(void);
-
-# endif
-
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prm54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prm54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,421 @@
+/*
+ * OMAP54xx PRM instance offset macros
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM54XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM54XX_H
+
+#include "prm44xx_54xx.h"
+#include "prcm-common.h"
+#include "prm.h"
+
+#define OMAP54XX_PRM_BASE		0x4ae06000
+
+#define OMAP54XX_PRM_REGADDR(inst, reg)				\
+	OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE + (inst) + (reg))
+
+
+/* PRM instances */
+#define OMAP54XX_PRM_OCP_SOCKET_INST	0x0000
+#define OMAP54XX_PRM_CKGEN_INST		0x0100
+#define OMAP54XX_PRM_MPU_INST		0x0300
+#define OMAP54XX_PRM_DSP_INST		0x0400
+#define OMAP54XX_PRM_ABE_INST		0x0500
+#define OMAP54XX_PRM_COREAON_INST	0x0600
+#define OMAP54XX_PRM_CORE_INST		0x0700
+#define OMAP54XX_PRM_IVA_INST		0x1200
+#define OMAP54XX_PRM_CAM_INST		0x1300
+#define OMAP54XX_PRM_DSS_INST		0x1400
+#define OMAP54XX_PRM_GPU_INST		0x1500
+#define OMAP54XX_PRM_L3INIT_INST	0x1600
+#define OMAP54XX_PRM_CUSTEFUSE_INST	0x1700
+#define OMAP54XX_PRM_WKUPAON_INST	0x1800
+#define OMAP54XX_PRM_WKUPAON_CM_INST	0x1900
+#define OMAP54XX_PRM_EMU_INST		0x1a00
+#define OMAP54XX_PRM_EMU_CM_INST	0x1b00
+#define OMAP54XX_PRM_DEVICE_INST	0x1c00
+#define OMAP54XX_PRM_INSTR_INST		0x1f00
+
+/* PRM clockdomain register offsets (from instance start) */
+#define OMAP54XX_PRM_WKUPAON_CM_WKUPAON_CDOFFS	0x0000
+#define OMAP54XX_PRM_EMU_CM_EMU_CDOFFS		0x0000
+
+/* PRM */
+
+/* PRM.OCP_SOCKET_PRM register offsets */
+#define OMAP54XX_REVISION_PRM_OFFSET				0x0000
+#define OMAP54XX_PRM_IRQSTATUS_MPU_OFFSET			0x0010
+#define OMAP54XX_PRM_IRQSTATUS_MPU_2_OFFSET			0x0014
+#define OMAP54XX_PRM_IRQENABLE_MPU_OFFSET			0x0018
+#define OMAP54XX_PRM_IRQENABLE_MPU_2_OFFSET			0x001c
+#define OMAP54XX_PRM_IRQSTATUS_IPU_OFFSET			0x0020
+#define OMAP54XX_PRM_IRQENABLE_IPU_OFFSET			0x0028
+#define OMAP54XX_PRM_IRQSTATUS_DSP_OFFSET			0x0030
+#define OMAP54XX_PRM_IRQENABLE_DSP_OFFSET			0x0038
+#define OMAP54XX_CM_PRM_PROFILING_CLKCTRL_OFFSET		0x0040
+#define OMAP54XX_CM_PRM_PROFILING_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_OCP_SOCKET_INST, 0x0040)
+#define OMAP54XX_PRM_DEBUG_OUT_OFFSET				0x0084
+#define OMAP54XX_PRM_DEBUG_TRANS_CFG_OFFSET			0x0090
+#define OMAP54XX_PRM_DEBUG_OFF_TRANS_OFFSET			0x0094
+#define OMAP54XX_PRM_DEBUG_CORE_RET_TRANS_OFFSET		0x0098
+#define OMAP54XX_PRM_DEBUG_MPU_RET_TRANS_OFFSET			0x009c
+#define OMAP54XX_PRM_DEBUG_MM_RET_TRANS_OFFSET			0x00a0
+#define OMAP54XX_PRM_DEBUG_WKUPAON_FD_TRANS_OFFSET		0x00a4
+
+/* PRM.CKGEN_PRM register offsets */
+#define OMAP54XX_CM_CLKSEL_ABE_DSS_SYS_OFFSET			0x0000
+#define OMAP54XX_CM_CLKSEL_ABE_DSS_SYS				OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x0000)
+#define OMAP54XX_CM_CLKSEL_WKUPAON_OFFSET			0x0008
+#define OMAP54XX_CM_CLKSEL_WKUPAON				OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x0008)
+#define OMAP54XX_CM_CLKSEL_ABE_PLL_REF_OFFSET			0x000c
+#define OMAP54XX_CM_CLKSEL_ABE_PLL_REF				OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x000c)
+#define OMAP54XX_CM_CLKSEL_SYS_OFFSET				0x0010
+#define OMAP54XX_CM_CLKSEL_SYS					OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_CKGEN_INST, 0x0010)
+
+/* PRM.MPU_PRM register offsets */
+#define OMAP54XX_PM_MPU_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_MPU_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_MPU_MPU_CONTEXT_OFFSET			0x0024
+
+/* PRM.DSP_PRM register offsets */
+#define OMAP54XX_PM_DSP_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_DSP_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_DSP_RSTCTRL_OFFSET				0x0010
+#define OMAP54XX_RM_DSP_RSTST_OFFSET				0x0014
+#define OMAP54XX_RM_DSP_DSP_CONTEXT_OFFSET			0x0024
+
+/* PRM.ABE_PRM register offsets */
+#define OMAP54XX_PM_ABE_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_ABE_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_ABE_AESS_CONTEXT_OFFSET			0x002c
+#define OMAP54XX_PM_ABE_MCPDM_WKDEP_OFFSET			0x0030
+#define OMAP54XX_RM_ABE_MCPDM_CONTEXT_OFFSET			0x0034
+#define OMAP54XX_PM_ABE_DMIC_WKDEP_OFFSET			0x0038
+#define OMAP54XX_RM_ABE_DMIC_CONTEXT_OFFSET			0x003c
+#define OMAP54XX_PM_ABE_MCASP_WKDEP_OFFSET			0x0040
+#define OMAP54XX_RM_ABE_MCASP_CONTEXT_OFFSET			0x0044
+#define OMAP54XX_PM_ABE_MCBSP1_WKDEP_OFFSET			0x0048
+#define OMAP54XX_RM_ABE_MCBSP1_CONTEXT_OFFSET			0x004c
+#define OMAP54XX_PM_ABE_MCBSP2_WKDEP_OFFSET			0x0050
+#define OMAP54XX_RM_ABE_MCBSP2_CONTEXT_OFFSET			0x0054
+#define OMAP54XX_PM_ABE_MCBSP3_WKDEP_OFFSET			0x0058
+#define OMAP54XX_RM_ABE_MCBSP3_CONTEXT_OFFSET			0x005c
+#define OMAP54XX_PM_ABE_SLIMBUS1_WKDEP_OFFSET			0x0060
+#define OMAP54XX_RM_ABE_SLIMBUS1_CONTEXT_OFFSET			0x0064
+#define OMAP54XX_PM_ABE_TIMER5_WKDEP_OFFSET			0x0068
+#define OMAP54XX_RM_ABE_TIMER5_CONTEXT_OFFSET			0x006c
+#define OMAP54XX_PM_ABE_TIMER6_WKDEP_OFFSET			0x0070
+#define OMAP54XX_RM_ABE_TIMER6_CONTEXT_OFFSET			0x0074
+#define OMAP54XX_PM_ABE_TIMER7_WKDEP_OFFSET			0x0078
+#define OMAP54XX_RM_ABE_TIMER7_CONTEXT_OFFSET			0x007c
+#define OMAP54XX_PM_ABE_TIMER8_WKDEP_OFFSET			0x0080
+#define OMAP54XX_RM_ABE_TIMER8_CONTEXT_OFFSET			0x0084
+#define OMAP54XX_PM_ABE_WD_TIMER3_WKDEP_OFFSET			0x0088
+#define OMAP54XX_RM_ABE_WD_TIMER3_CONTEXT_OFFSET		0x008c
+
+/* PRM.COREAON_PRM register offsets */
+#define OMAP54XX_PM_COREAON_SMARTREFLEX_MPU_WKDEP_OFFSET	0x0028
+#define OMAP54XX_RM_COREAON_SMARTREFLEX_MPU_CONTEXT_OFFSET	0x002c
+#define OMAP54XX_PM_COREAON_SMARTREFLEX_MM_WKDEP_OFFSET		0x0030
+#define OMAP54XX_RM_COREAON_SMARTREFLEX_MM_CONTEXT_OFFSET	0x0034
+#define OMAP54XX_PM_COREAON_SMARTREFLEX_CORE_WKDEP_OFFSET	0x0038
+#define OMAP54XX_RM_COREAON_SMARTREFLEX_CORE_CONTEXT_OFFSET	0x003c
+
+/* PRM.CORE_PRM register offsets */
+#define OMAP54XX_PM_CORE_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_CORE_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_L3MAIN1_L3_MAIN_1_CONTEXT_OFFSET		0x0024
+#define OMAP54XX_RM_L3MAIN2_L3_MAIN_2_CONTEXT_OFFSET		0x0124
+#define OMAP54XX_RM_L3MAIN2_GPMC_CONTEXT_OFFSET			0x012c
+#define OMAP54XX_RM_L3MAIN2_OCMC_RAM_CONTEXT_OFFSET		0x0134
+#define OMAP54XX_RM_IPU_RSTCTRL_OFFSET				0x0210
+#define OMAP54XX_RM_IPU_RSTST_OFFSET				0x0214
+#define OMAP54XX_RM_IPU_IPU_CONTEXT_OFFSET			0x0224
+#define OMAP54XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET		0x0324
+#define OMAP54XX_RM_EMIF_DMM_CONTEXT_OFFSET			0x0424
+#define OMAP54XX_RM_EMIF_EMIF_OCP_FW_CONTEXT_OFFSET		0x042c
+#define OMAP54XX_RM_EMIF_EMIF1_CONTEXT_OFFSET			0x0434
+#define OMAP54XX_RM_EMIF_EMIF2_CONTEXT_OFFSET			0x043c
+#define OMAP54XX_RM_EMIF_EMIF_DLL_CONTEXT_OFFSET		0x0444
+#define OMAP54XX_RM_C2C_C2C_CONTEXT_OFFSET			0x0524
+#define OMAP54XX_RM_C2C_MODEM_ICR_CONTEXT_OFFSET		0x052c
+#define OMAP54XX_RM_C2C_C2C_OCP_FW_CONTEXT_OFFSET		0x0534
+#define OMAP54XX_RM_L4CFG_L4_CFG_CONTEXT_OFFSET			0x0624
+#define OMAP54XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET		0x062c
+#define OMAP54XX_RM_L4CFG_MAILBOX_CONTEXT_OFFSET		0x0634
+#define OMAP54XX_RM_L4CFG_SAR_ROM_CONTEXT_OFFSET		0x063c
+#define OMAP54XX_RM_L4CFG_OCP2SCP2_CONTEXT_OFFSET		0x0644
+#define OMAP54XX_RM_L3INSTR_L3_MAIN_3_CONTEXT_OFFSET		0x0724
+#define OMAP54XX_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET		0x072c
+#define OMAP54XX_RM_L3INSTR_OCP_WP_NOC_CONTEXT_OFFSET		0x0744
+#define OMAP54XX_RM_MIPIEXT_LLI_CONTEXT_OFFSET			0x0824
+#define OMAP54XX_RM_MIPIEXT_LLI_OCP_FW_CONTEXT_OFFSET		0x082c
+#define OMAP54XX_RM_MIPIEXT_MPHY_CONTEXT_OFFSET			0x0834
+#define OMAP54XX_PM_L4PER_TIMER10_WKDEP_OFFSET			0x0928
+#define OMAP54XX_RM_L4PER_TIMER10_CONTEXT_OFFSET		0x092c
+#define OMAP54XX_PM_L4PER_TIMER11_WKDEP_OFFSET			0x0930
+#define OMAP54XX_RM_L4PER_TIMER11_CONTEXT_OFFSET		0x0934
+#define OMAP54XX_PM_L4PER_TIMER2_WKDEP_OFFSET			0x0938
+#define OMAP54XX_RM_L4PER_TIMER2_CONTEXT_OFFSET			0x093c
+#define OMAP54XX_PM_L4PER_TIMER3_WKDEP_OFFSET			0x0940
+#define OMAP54XX_RM_L4PER_TIMER3_CONTEXT_OFFSET			0x0944
+#define OMAP54XX_PM_L4PER_TIMER4_WKDEP_OFFSET			0x0948
+#define OMAP54XX_RM_L4PER_TIMER4_CONTEXT_OFFSET			0x094c
+#define OMAP54XX_PM_L4PER_TIMER9_WKDEP_OFFSET			0x0950
+#define OMAP54XX_RM_L4PER_TIMER9_CONTEXT_OFFSET			0x0954
+#define OMAP54XX_RM_L4PER_ELM_CONTEXT_OFFSET			0x095c
+#define OMAP54XX_PM_L4PER_GPIO2_WKDEP_OFFSET			0x0960
+#define OMAP54XX_RM_L4PER_GPIO2_CONTEXT_OFFSET			0x0964
+#define OMAP54XX_PM_L4PER_GPIO3_WKDEP_OFFSET			0x0968
+#define OMAP54XX_RM_L4PER_GPIO3_CONTEXT_OFFSET			0x096c
+#define OMAP54XX_PM_L4PER_GPIO4_WKDEP_OFFSET			0x0970
+#define OMAP54XX_RM_L4PER_GPIO4_CONTEXT_OFFSET			0x0974
+#define OMAP54XX_PM_L4PER_GPIO5_WKDEP_OFFSET			0x0978
+#define OMAP54XX_RM_L4PER_GPIO5_CONTEXT_OFFSET			0x097c
+#define OMAP54XX_PM_L4PER_GPIO6_WKDEP_OFFSET			0x0980
+#define OMAP54XX_RM_L4PER_GPIO6_CONTEXT_OFFSET			0x0984
+#define OMAP54XX_RM_L4PER_HDQ1W_CONTEXT_OFFSET			0x098c
+#define OMAP54XX_PM_L4PER_I2C1_WKDEP_OFFSET			0x09a0
+#define OMAP54XX_RM_L4PER_I2C1_CONTEXT_OFFSET			0x09a4
+#define OMAP54XX_PM_L4PER_I2C2_WKDEP_OFFSET			0x09a8
+#define OMAP54XX_RM_L4PER_I2C2_CONTEXT_OFFSET			0x09ac
+#define OMAP54XX_PM_L4PER_I2C3_WKDEP_OFFSET			0x09b0
+#define OMAP54XX_RM_L4PER_I2C3_CONTEXT_OFFSET			0x09b4
+#define OMAP54XX_PM_L4PER_I2C4_WKDEP_OFFSET			0x09b8
+#define OMAP54XX_RM_L4PER_I2C4_CONTEXT_OFFSET			0x09bc
+#define OMAP54XX_RM_L4PER_L4_PER_CONTEXT_OFFSET			0x09c0
+#define OMAP54XX_PM_L4PER_MCSPI1_WKDEP_OFFSET			0x09f0
+#define OMAP54XX_RM_L4PER_MCSPI1_CONTEXT_OFFSET			0x09f4
+#define OMAP54XX_PM_L4PER_MCSPI2_WKDEP_OFFSET			0x09f8
+#define OMAP54XX_RM_L4PER_MCSPI2_CONTEXT_OFFSET			0x09fc
+#define OMAP54XX_PM_L4PER_MCSPI3_WKDEP_OFFSET			0x0a00
+#define OMAP54XX_RM_L4PER_MCSPI3_CONTEXT_OFFSET			0x0a04
+#define OMAP54XX_PM_L4PER_MCSPI4_WKDEP_OFFSET			0x0a08
+#define OMAP54XX_RM_L4PER_MCSPI4_CONTEXT_OFFSET			0x0a0c
+#define OMAP54XX_PM_L4PER_GPIO7_WKDEP_OFFSET			0x0a10
+#define OMAP54XX_RM_L4PER_GPIO7_CONTEXT_OFFSET			0x0a14
+#define OMAP54XX_PM_L4PER_GPIO8_WKDEP_OFFSET			0x0a18
+#define OMAP54XX_RM_L4PER_GPIO8_CONTEXT_OFFSET			0x0a1c
+#define OMAP54XX_PM_L4PER_MMC3_WKDEP_OFFSET			0x0a20
+#define OMAP54XX_RM_L4PER_MMC3_CONTEXT_OFFSET			0x0a24
+#define OMAP54XX_PM_L4PER_MMC4_WKDEP_OFFSET			0x0a28
+#define OMAP54XX_RM_L4PER_MMC4_CONTEXT_OFFSET			0x0a2c
+#define OMAP54XX_PM_L4PER_UART1_WKDEP_OFFSET			0x0a40
+#define OMAP54XX_RM_L4PER_UART1_CONTEXT_OFFSET			0x0a44
+#define OMAP54XX_PM_L4PER_UART2_WKDEP_OFFSET			0x0a48
+#define OMAP54XX_RM_L4PER_UART2_CONTEXT_OFFSET			0x0a4c
+#define OMAP54XX_PM_L4PER_UART3_WKDEP_OFFSET			0x0a50
+#define OMAP54XX_RM_L4PER_UART3_CONTEXT_OFFSET			0x0a54
+#define OMAP54XX_RM_L4PER_UART4_CONTEXT_OFFSET			0x0a58
+#define OMAP54XX_PM_L4PER_UART4_WKDEP_OFFSET			0x0a5c
+#define OMAP54XX_PM_L4PER_MMC5_WKDEP_OFFSET			0x0a60
+#define OMAP54XX_RM_L4PER_MMC5_CONTEXT_OFFSET			0x0a64
+#define OMAP54XX_PM_L4PER_I2C5_WKDEP_OFFSET			0x0a68
+#define OMAP54XX_RM_L4PER_I2C5_CONTEXT_OFFSET			0x0a6c
+#define OMAP54XX_PM_L4PER_UART5_WKDEP_OFFSET			0x0a70
+#define OMAP54XX_RM_L4PER_UART5_CONTEXT_OFFSET			0x0a74
+#define OMAP54XX_PM_L4PER_UART6_WKDEP_OFFSET			0x0a78
+#define OMAP54XX_RM_L4PER_UART6_CONTEXT_OFFSET			0x0a7c
+#define OMAP54XX_RM_L4SEC_AES1_CONTEXT_OFFSET			0x0aa4
+#define OMAP54XX_RM_L4SEC_AES2_CONTEXT_OFFSET			0x0aac
+#define OMAP54XX_RM_L4SEC_DES3DES_CONTEXT_OFFSET		0x0ab4
+#define OMAP54XX_RM_L4SEC_FPKA_CONTEXT_OFFSET			0x0abc
+#define OMAP54XX_RM_L4SEC_RNG_CONTEXT_OFFSET			0x0ac4
+#define OMAP54XX_RM_L4SEC_SHA2MD5_CONTEXT_OFFSET		0x0acc
+#define OMAP54XX_RM_L4SEC_DMA_CRYPTO_CONTEXT_OFFSET		0x0adc
+
+/* PRM.IVA_PRM register offsets */
+#define OMAP54XX_PM_IVA_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_IVA_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_IVA_RSTCTRL_OFFSET				0x0010
+#define OMAP54XX_RM_IVA_RSTST_OFFSET				0x0014
+#define OMAP54XX_RM_IVA_IVA_CONTEXT_OFFSET			0x0024
+#define OMAP54XX_RM_IVA_SL2_CONTEXT_OFFSET			0x002c
+
+/* PRM.CAM_PRM register offsets */
+#define OMAP54XX_PM_CAM_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_CAM_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_CAM_ISS_CONTEXT_OFFSET			0x0024
+#define OMAP54XX_RM_CAM_FDIF_CONTEXT_OFFSET			0x002c
+#define OMAP54XX_RM_CAM_CAL_CONTEXT_OFFSET			0x0034
+
+/* PRM.DSS_PRM register offsets */
+#define OMAP54XX_PM_DSS_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_DSS_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_PM_DSS_DSS_WKDEP_OFFSET			0x0020
+#define OMAP54XX_RM_DSS_DSS_CONTEXT_OFFSET			0x0024
+#define OMAP54XX_RM_DSS_BB2D_CONTEXT_OFFSET			0x0034
+
+/* PRM.GPU_PRM register offsets */
+#define OMAP54XX_PM_GPU_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_GPU_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_GPU_GPU_CONTEXT_OFFSET			0x0024
+
+/* PRM.L3INIT_PRM register offsets */
+#define OMAP54XX_PM_L3INIT_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_L3INIT_PWRSTST_OFFSET			0x0004
+#define OMAP54XX_PM_L3INIT_MMC1_WKDEP_OFFSET			0x0028
+#define OMAP54XX_RM_L3INIT_MMC1_CONTEXT_OFFSET			0x002c
+#define OMAP54XX_PM_L3INIT_MMC2_WKDEP_OFFSET			0x0030
+#define OMAP54XX_RM_L3INIT_MMC2_CONTEXT_OFFSET			0x0034
+#define OMAP54XX_PM_L3INIT_HSI_WKDEP_OFFSET			0x0038
+#define OMAP54XX_RM_L3INIT_HSI_CONTEXT_OFFSET			0x003c
+#define OMAP54XX_PM_L3INIT_UNIPRO2_WKDEP_OFFSET			0x0040
+#define OMAP54XX_RM_L3INIT_UNIPRO2_CONTEXT_OFFSET		0x0044
+#define OMAP54XX_PM_L3INIT_USB_HOST_HS_WKDEP_OFFSET		0x0058
+#define OMAP54XX_RM_L3INIT_USB_HOST_HS_CONTEXT_OFFSET		0x005c
+#define OMAP54XX_PM_L3INIT_USB_TLL_HS_WKDEP_OFFSET		0x0068
+#define OMAP54XX_RM_L3INIT_USB_TLL_HS_CONTEXT_OFFSET		0x006c
+#define OMAP54XX_RM_L3INIT_IEEE1500_2_OCP_CONTEXT_OFFSET	0x007c
+#define OMAP54XX_PM_L3INIT_SATA_WKDEP_OFFSET			0x0088
+#define OMAP54XX_RM_L3INIT_SATA_CONTEXT_OFFSET			0x008c
+#define OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET		0x00e4
+#define OMAP54XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET		0x00ec
+#define OMAP54XX_PM_L3INIT_USB_OTG_SS_WKDEP_OFFSET		0x00f0
+#define OMAP54XX_RM_L3INIT_USB_OTG_SS_CONTEXT_OFFSET		0x00f4
+
+/* PRM.CUSTEFUSE_PRM register offsets */
+#define OMAP54XX_PM_CUSTEFUSE_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_CUSTEFUSE_PWRSTST_OFFSET			0x0004
+#define OMAP54XX_RM_CUSTEFUSE_EFUSE_CTRL_CUST_CONTEXT_OFFSET	0x0024
+
+/* PRM.WKUPAON_PRM register offsets */
+#define OMAP54XX_RM_WKUPAON_L4_WKUP_CONTEXT_OFFSET		0x0024
+#define OMAP54XX_RM_WKUPAON_WD_TIMER1_CONTEXT_OFFSET		0x002c
+#define OMAP54XX_PM_WKUPAON_WD_TIMER2_WKDEP_OFFSET		0x0030
+#define OMAP54XX_RM_WKUPAON_WD_TIMER2_CONTEXT_OFFSET		0x0034
+#define OMAP54XX_PM_WKUPAON_GPIO1_WKDEP_OFFSET			0x0038
+#define OMAP54XX_RM_WKUPAON_GPIO1_CONTEXT_OFFSET		0x003c
+#define OMAP54XX_PM_WKUPAON_TIMER1_WKDEP_OFFSET			0x0040
+#define OMAP54XX_RM_WKUPAON_TIMER1_CONTEXT_OFFSET		0x0044
+#define OMAP54XX_PM_WKUPAON_TIMER12_WKDEP_OFFSET		0x0048
+#define OMAP54XX_RM_WKUPAON_TIMER12_CONTEXT_OFFSET		0x004c
+#define OMAP54XX_RM_WKUPAON_COUNTER_32K_CONTEXT_OFFSET		0x0054
+#define OMAP54XX_RM_WKUPAON_SAR_RAM_CONTEXT_OFFSET		0x0064
+#define OMAP54XX_PM_WKUPAON_KBD_WKDEP_OFFSET			0x0078
+#define OMAP54XX_RM_WKUPAON_KBD_CONTEXT_OFFSET			0x007c
+
+/* PRM.WKUPAON_CM register offsets */
+#define OMAP54XX_CM_WKUPAON_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_WKUPAON_L4_WKUP_CLKCTRL_OFFSET		0x0020
+#define OMAP54XX_CM_WKUPAON_L4_WKUP_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0020)
+#define OMAP54XX_CM_WKUPAON_WD_TIMER1_CLKCTRL_OFFSET		0x0028
+#define OMAP54XX_CM_WKUPAON_WD_TIMER1_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0028)
+#define OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL_OFFSET		0x0030
+#define OMAP54XX_CM_WKUPAON_WD_TIMER2_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0030)
+#define OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL_OFFSET		0x0038
+#define OMAP54XX_CM_WKUPAON_GPIO1_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0038)
+#define OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL_OFFSET		0x0040
+#define OMAP54XX_CM_WKUPAON_TIMER1_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0040)
+#define OMAP54XX_CM_WKUPAON_TIMER12_CLKCTRL_OFFSET		0x0048
+#define OMAP54XX_CM_WKUPAON_TIMER12_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0048)
+#define OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL_OFFSET		0x0050
+#define OMAP54XX_CM_WKUPAON_COUNTER_32K_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0050)
+#define OMAP54XX_CM_WKUPAON_SAR_RAM_CLKCTRL_OFFSET		0x0060
+#define OMAP54XX_CM_WKUPAON_SAR_RAM_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0060)
+#define OMAP54XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET			0x0078
+#define OMAP54XX_CM_WKUPAON_KBD_CLKCTRL				OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0078)
+#define OMAP54XX_CM_WKUPAON_SCRM_CLKCTRL_OFFSET			0x0090
+#define OMAP54XX_CM_WKUPAON_SCRM_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0090)
+#define OMAP54XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL_OFFSET		0x0098
+#define OMAP54XX_CM_WKUPAON_IO_SRCOMP_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_WKUPAON_CM_INST, 0x0098)
+
+/* PRM.EMU_PRM register offsets */
+#define OMAP54XX_PM_EMU_PWRSTCTRL_OFFSET			0x0000
+#define OMAP54XX_PM_EMU_PWRSTST_OFFSET				0x0004
+#define OMAP54XX_RM_EMU_DEBUGSS_CONTEXT_OFFSET			0x0024
+
+/* PRM.EMU_CM register offsets */
+#define OMAP54XX_CM_EMU_CLKSTCTRL_OFFSET			0x0000
+#define OMAP54XX_CM_EMU_DYNAMICDEP_OFFSET			0x0008
+#define OMAP54XX_CM_EMU_DEBUGSS_CLKCTRL_OFFSET			0x0020
+#define OMAP54XX_CM_EMU_DEBUGSS_CLKCTRL				OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_EMU_CM_INST, 0x0020)
+#define OMAP54XX_CM_EMU_MPU_EMU_DBG_CLKCTRL_OFFSET		0x0028
+#define OMAP54XX_CM_EMU_MPU_EMU_DBG_CLKCTRL			OMAP54XX_PRM_REGADDR(OMAP54XX_PRM_EMU_CM_INST, 0x0028)
+
+/* PRM.DEVICE_PRM register offsets */
+#define OMAP54XX_PRM_RSTCTRL_OFFSET				0x0000
+#define OMAP54XX_PRM_RSTST_OFFSET				0x0004
+#define OMAP54XX_PRM_RSTTIME_OFFSET				0x0008
+#define OMAP54XX_PRM_CLKREQCTRL_OFFSET				0x000c
+#define OMAP54XX_PRM_VOLTCTRL_OFFSET				0x0010
+#define OMAP54XX_PRM_PWRREQCTRL_OFFSET				0x0014
+#define OMAP54XX_PRM_PSCON_COUNT_OFFSET				0x0018
+#define OMAP54XX_PRM_IO_COUNT_OFFSET				0x001c
+#define OMAP54XX_PRM_IO_PMCTRL_OFFSET				0x0020
+#define OMAP54XX_PRM_VOLTSETUP_WARMRESET_OFFSET			0x0024
+#define OMAP54XX_PRM_VOLTSETUP_CORE_OFF_OFFSET			0x0028
+#define OMAP54XX_PRM_VOLTSETUP_MPU_OFF_OFFSET			0x002c
+#define OMAP54XX_PRM_VOLTSETUP_MM_OFF_OFFSET			0x0030
+#define OMAP54XX_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET		0x0034
+#define OMAP54XX_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET		0x0038
+#define OMAP54XX_PRM_VOLTSETUP_MM_RET_SLEEP_OFFSET		0x003c
+#define OMAP54XX_PRM_VP_CORE_CONFIG_OFFSET			0x0040
+#define OMAP54XX_PRM_VP_CORE_STATUS_OFFSET			0x0044
+#define OMAP54XX_PRM_VP_CORE_VLIMITTO_OFFSET			0x0048
+#define OMAP54XX_PRM_VP_CORE_VOLTAGE_OFFSET			0x004c
+#define OMAP54XX_PRM_VP_CORE_VSTEPMAX_OFFSET			0x0050
+#define OMAP54XX_PRM_VP_CORE_VSTEPMIN_OFFSET			0x0054
+#define OMAP54XX_PRM_VP_MPU_CONFIG_OFFSET			0x0058
+#define OMAP54XX_PRM_VP_MPU_STATUS_OFFSET			0x005c
+#define OMAP54XX_PRM_VP_MPU_VLIMITTO_OFFSET			0x0060
+#define OMAP54XX_PRM_VP_MPU_VOLTAGE_OFFSET			0x0064
+#define OMAP54XX_PRM_VP_MPU_VSTEPMAX_OFFSET			0x0068
+#define OMAP54XX_PRM_VP_MPU_VSTEPMIN_OFFSET			0x006c
+#define OMAP54XX_PRM_VP_MM_CONFIG_OFFSET			0x0070
+#define OMAP54XX_PRM_VP_MM_STATUS_OFFSET			0x0074
+#define OMAP54XX_PRM_VP_MM_VLIMITTO_OFFSET			0x0078
+#define OMAP54XX_PRM_VP_MM_VOLTAGE_OFFSET			0x007c
+#define OMAP54XX_PRM_VP_MM_VSTEPMAX_OFFSET			0x0080
+#define OMAP54XX_PRM_VP_MM_VSTEPMIN_OFFSET			0x0084
+#define OMAP54XX_PRM_VC_SMPS_CORE_CONFIG_OFFSET			0x0088
+#define OMAP54XX_PRM_VC_SMPS_MM_CONFIG_OFFSET			0x008c
+#define OMAP54XX_PRM_VC_SMPS_MPU_CONFIG_OFFSET			0x0090
+#define OMAP54XX_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET		0x0094
+#define OMAP54XX_PRM_VC_VAL_CMD_VDD_MM_L_OFFSET			0x0098
+#define OMAP54XX_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET		0x009c
+#define OMAP54XX_PRM_VC_VAL_BYPASS_OFFSET			0x00a0
+#define OMAP54XX_PRM_VC_CORE_ERRST_OFFSET			0x00a4
+#define OMAP54XX_PRM_VC_MM_ERRST_OFFSET				0x00a8
+#define OMAP54XX_PRM_VC_MPU_ERRST_OFFSET			0x00ac
+#define OMAP54XX_PRM_VC_BYPASS_ERRST_OFFSET			0x00b0
+#define OMAP54XX_PRM_VC_CFG_I2C_MODE_OFFSET			0x00b4
+#define OMAP54XX_PRM_VC_CFG_I2C_CLK_OFFSET			0x00b8
+#define OMAP54XX_PRM_SRAM_COUNT_OFFSET				0x00bc
+#define OMAP54XX_PRM_SRAM_WKUP_SETUP_OFFSET			0x00c0
+#define OMAP54XX_PRM_SLDO_CORE_SETUP_OFFSET			0x00c4
+#define OMAP54XX_PRM_SLDO_CORE_CTRL_OFFSET			0x00c8
+#define OMAP54XX_PRM_SLDO_MPU_SETUP_OFFSET			0x00cc
+#define OMAP54XX_PRM_SLDO_MPU_CTRL_OFFSET			0x00d0
+#define OMAP54XX_PRM_SLDO_MM_SETUP_OFFSET			0x00d4
+#define OMAP54XX_PRM_SLDO_MM_CTRL_OFFSET			0x00d8
+#define OMAP54XX_PRM_ABBLDO_MPU_SETUP_OFFSET			0x00dc
+#define OMAP54XX_PRM_ABBLDO_MPU_CTRL_OFFSET			0x00e0
+#define OMAP54XX_PRM_ABBLDO_MM_SETUP_OFFSET			0x00e4
+#define OMAP54XX_PRM_ABBLDO_MM_CTRL_OFFSET			0x00e8
+#define OMAP54XX_PRM_BANDGAP_SETUP_OFFSET			0x00ec
+#define OMAP54XX_PRM_DEVICE_OFF_CTRL_OFFSET			0x00f0
+#define OMAP54XX_PRM_PHASE1_CNDP_OFFSET				0x00f4
+#define OMAP54XX_PRM_PHASE2A_CNDP_OFFSET			0x00f8
+#define OMAP54XX_PRM_PHASE2B_CNDP_OFFSET			0x00fc
+#define OMAP54XX_PRM_MODEM_IF_CTRL_OFFSET			0x0100
+#define OMAP54XX_PRM_VOLTST_MPU_OFFSET				0x0110
+#define OMAP54XX_PRM_VOLTST_MM_OFFSET				0x0114
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/prm-regbits-54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm-regbits-54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/prm-regbits-54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/prm-regbits-54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2701 @@
+/*
+ * OMAP54xx Power Management register bits
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_54XX_H
+
+/* Used by PRM_SLDO_CORE_SETUP, PRM_SLDO_MM_SETUP, PRM_SLDO_MPU_SETUP */
+#define OMAP54XX_ABBOFF_ACT_SHIFT						1
+#define OMAP54XX_ABBOFF_ACT_WIDTH						0x1
+#define OMAP54XX_ABBOFF_ACT_MASK						(1 << 1)
+
+/* Used by PRM_SLDO_CORE_SETUP, PRM_SLDO_MM_SETUP, PRM_SLDO_MPU_SETUP */
+#define OMAP54XX_ABBOFF_SLEEP_SHIFT						2
+#define OMAP54XX_ABBOFF_SLEEP_WIDTH						0x1
+#define OMAP54XX_ABBOFF_SLEEP_MASK						(1 << 2)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_ABB_MM_DONE_EN_SHIFT						31
+#define OMAP54XX_ABB_MM_DONE_EN_WIDTH						0x1
+#define OMAP54XX_ABB_MM_DONE_EN_MASK						(1 << 31)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_ABB_MM_DONE_ST_SHIFT						31
+#define OMAP54XX_ABB_MM_DONE_ST_WIDTH						0x1
+#define OMAP54XX_ABB_MM_DONE_ST_MASK						(1 << 31)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP54XX_ABB_MPU_DONE_EN_SHIFT						7
+#define OMAP54XX_ABB_MPU_DONE_EN_WIDTH						0x1
+#define OMAP54XX_ABB_MPU_DONE_EN_MASK						(1 << 7)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP54XX_ABB_MPU_DONE_ST_SHIFT						7
+#define OMAP54XX_ABB_MPU_DONE_ST_WIDTH						0x1
+#define OMAP54XX_ABB_MPU_DONE_ST_MASK						(1 << 7)
+
+/* Used by PRM_ABBLDO_MM_SETUP, PRM_ABBLDO_MPU_SETUP */
+#define OMAP54XX_ACTIVE_FBB_SEL_SHIFT						2
+#define OMAP54XX_ACTIVE_FBB_SEL_WIDTH						0x1
+#define OMAP54XX_ACTIVE_FBB_SEL_MASK						(1 << 2)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP54XX_AESSMEM_ONSTATE_SHIFT						16
+#define OMAP54XX_AESSMEM_ONSTATE_WIDTH						0x2
+#define OMAP54XX_AESSMEM_ONSTATE_MASK						(0x3 << 16)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP54XX_AESSMEM_RETSTATE_SHIFT						8
+#define OMAP54XX_AESSMEM_RETSTATE_WIDTH						0x1
+#define OMAP54XX_AESSMEM_RETSTATE_MASK						(1 << 8)
+
+/* Used by PM_ABE_PWRSTST */
+#define OMAP54XX_AESSMEM_STATEST_SHIFT						4
+#define OMAP54XX_AESSMEM_STATEST_WIDTH						0x2
+#define OMAP54XX_AESSMEM_STATEST_MASK						(0x3 << 4)
+
+/* Used by PRM_SLDO_CORE_SETUP, PRM_SLDO_MM_SETUP, PRM_SLDO_MPU_SETUP */
+#define OMAP54XX_AIPOFF_SHIFT							8
+#define OMAP54XX_AIPOFF_WIDTH							0x1
+#define OMAP54XX_AIPOFF_MASK							(1 << 8)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP54XX_AUTO_CTRL_VDD_CORE_L_SHIFT					0
+#define OMAP54XX_AUTO_CTRL_VDD_CORE_L_WIDTH					0x2
+#define OMAP54XX_AUTO_CTRL_VDD_CORE_L_MASK					(0x3 << 0)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP54XX_AUTO_CTRL_VDD_MM_L_SHIFT					4
+#define OMAP54XX_AUTO_CTRL_VDD_MM_L_WIDTH					0x2
+#define OMAP54XX_AUTO_CTRL_VDD_MM_L_MASK					(0x3 << 4)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP54XX_AUTO_CTRL_VDD_MPU_L_SHIFT					2
+#define OMAP54XX_AUTO_CTRL_VDD_MPU_L_WIDTH					0x2
+#define OMAP54XX_AUTO_CTRL_VDD_MPU_L_MASK					(0x3 << 2)
+
+/* Used by PRM_VC_BYPASS_ERRST */
+#define OMAP54XX_BYPS_RA_ERR_SHIFT						1
+#define OMAP54XX_BYPS_RA_ERR_WIDTH						0x1
+#define OMAP54XX_BYPS_RA_ERR_MASK						(1 << 1)
+
+/* Used by PRM_VC_BYPASS_ERRST */
+#define OMAP54XX_BYPS_SA_ERR_SHIFT						0
+#define OMAP54XX_BYPS_SA_ERR_WIDTH						0x1
+#define OMAP54XX_BYPS_SA_ERR_MASK						(1 << 0)
+
+/* Used by PRM_VC_BYPASS_ERRST */
+#define OMAP54XX_BYPS_TIMEOUT_ERR_SHIFT						2
+#define OMAP54XX_BYPS_TIMEOUT_ERR_WIDTH						0x1
+#define OMAP54XX_BYPS_TIMEOUT_ERR_MASK						(1 << 2)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_C2C_RST_SHIFT							10
+#define OMAP54XX_C2C_RST_WIDTH							0x1
+#define OMAP54XX_C2C_RST_MASK							(1 << 10)
+
+/* Used by PM_CAM_PWRSTCTRL */
+#define OMAP54XX_CAM_MEM_ONSTATE_SHIFT						16
+#define OMAP54XX_CAM_MEM_ONSTATE_WIDTH						0x2
+#define OMAP54XX_CAM_MEM_ONSTATE_MASK						(0x3 << 16)
+
+/* Used by PM_CAM_PWRSTST */
+#define OMAP54XX_CAM_MEM_STATEST_SHIFT						4
+#define OMAP54XX_CAM_MEM_STATEST_WIDTH						0x2
+#define OMAP54XX_CAM_MEM_STATEST_MASK						(0x3 << 4)
+
+/* Used by PRM_CLKREQCTRL */
+#define OMAP54XX_CLKREQ_COND_SHIFT						0
+#define OMAP54XX_CLKREQ_COND_WIDTH						0x3
+#define OMAP54XX_CLKREQ_COND_MASK						(0x7 << 0)
+
+/* Used by PRM_VC_SMPS_CORE_CONFIG */
+#define OMAP54XX_CMDRA_VDD_CORE_L_SHIFT						16
+#define OMAP54XX_CMDRA_VDD_CORE_L_WIDTH						0x8
+#define OMAP54XX_CMDRA_VDD_CORE_L_MASK						(0xff << 16)
+
+/* Used by PRM_VC_SMPS_MM_CONFIG */
+#define OMAP54XX_CMDRA_VDD_MM_L_SHIFT						16
+#define OMAP54XX_CMDRA_VDD_MM_L_WIDTH						0x8
+#define OMAP54XX_CMDRA_VDD_MM_L_MASK						(0xff << 16)
+
+/* Used by PRM_VC_SMPS_MPU_CONFIG */
+#define OMAP54XX_CMDRA_VDD_MPU_L_SHIFT						16
+#define OMAP54XX_CMDRA_VDD_MPU_L_WIDTH						0x8
+#define OMAP54XX_CMDRA_VDD_MPU_L_MASK						(0xff << 16)
+
+/* Used by PRM_VC_SMPS_CORE_CONFIG */
+#define OMAP54XX_CMD_VDD_CORE_L_SHIFT						28
+#define OMAP54XX_CMD_VDD_CORE_L_WIDTH						0x1
+#define OMAP54XX_CMD_VDD_CORE_L_MASK						(1 << 28)
+
+/* Used by PRM_VC_SMPS_MM_CONFIG */
+#define OMAP54XX_CMD_VDD_MM_L_SHIFT						28
+#define OMAP54XX_CMD_VDD_MM_L_WIDTH						0x1
+#define OMAP54XX_CMD_VDD_MM_L_MASK						(1 << 28)
+
+/* Used by PRM_VC_SMPS_MPU_CONFIG */
+#define OMAP54XX_CMD_VDD_MPU_L_SHIFT						28
+#define OMAP54XX_CMD_VDD_MPU_L_WIDTH						0x1
+#define OMAP54XX_CMD_VDD_MPU_L_MASK						(1 << 28)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_CORE_OCMRAM_ONSTATE_SHIFT					18
+#define OMAP54XX_CORE_OCMRAM_ONSTATE_WIDTH					0x2
+#define OMAP54XX_CORE_OCMRAM_ONSTATE_MASK					(0x3 << 18)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_CORE_OCMRAM_RETSTATE_SHIFT					9
+#define OMAP54XX_CORE_OCMRAM_RETSTATE_WIDTH					0x1
+#define OMAP54XX_CORE_OCMRAM_RETSTATE_MASK					(1 << 9)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP54XX_CORE_OCMRAM_STATEST_SHIFT					6
+#define OMAP54XX_CORE_OCMRAM_STATEST_WIDTH					0x2
+#define OMAP54XX_CORE_OCMRAM_STATEST_MASK					(0x3 << 6)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_CORE_OTHER_BANK_ONSTATE_SHIFT					16
+#define OMAP54XX_CORE_OTHER_BANK_ONSTATE_WIDTH					0x2
+#define OMAP54XX_CORE_OTHER_BANK_ONSTATE_MASK					(0x3 << 16)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_CORE_OTHER_BANK_RETSTATE_SHIFT					8
+#define OMAP54XX_CORE_OTHER_BANK_RETSTATE_WIDTH					0x1
+#define OMAP54XX_CORE_OTHER_BANK_RETSTATE_MASK					(1 << 8)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP54XX_CORE_OTHER_BANK_STATEST_SHIFT					4
+#define OMAP54XX_CORE_OTHER_BANK_STATEST_WIDTH					0x2
+#define OMAP54XX_CORE_OTHER_BANK_STATEST_MASK					(0x3 << 4)
+
+/* Used by REVISION_PRM */
+#define OMAP54XX_CUSTOM_SHIFT							6
+#define OMAP54XX_CUSTOM_WIDTH							0x2
+#define OMAP54XX_CUSTOM_MASK							(0x3 << 6)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP54XX_DATA_SHIFT							16
+#define OMAP54XX_DATA_WIDTH							0x8
+#define OMAP54XX_DATA_MASK							(0xff << 16)
+
+/* Used by PRM_DEBUG_CORE_RET_TRANS */
+#define OMAP54XX_PRM_DEBUG_OUT_SHIFT						0
+#define OMAP54XX_PRM_DEBUG_OUT_WIDTH						0x1c
+#define OMAP54XX_PRM_DEBUG_OUT_MASK						(0xfffffff << 0)
+
+/* Renamed from DEBUG_OUT Used by PRM_DEBUG_MM_RET_TRANS */
+#define OMAP54XX_DEBUG_OUT_0_9_SHIFT						0
+#define OMAP54XX_DEBUG_OUT_0_9_WIDTH						0xa
+#define OMAP54XX_DEBUG_OUT_0_9_MASK						(0x3ff << 0)
+
+/* Renamed from DEBUG_OUT Used by PRM_DEBUG_MPU_RET_TRANS */
+#define OMAP54XX_DEBUG_OUT_0_6_SHIFT						0
+#define OMAP54XX_DEBUG_OUT_0_6_WIDTH						0x7
+#define OMAP54XX_DEBUG_OUT_0_6_MASK						(0x7f << 0)
+
+/* Renamed from DEBUG_OUT Used by PRM_DEBUG_OFF_TRANS */
+#define OMAP54XX_DEBUG_OUT_0_31_SHIFT						0
+#define OMAP54XX_DEBUG_OUT_0_31_WIDTH						0x20
+#define OMAP54XX_DEBUG_OUT_0_31_MASK						(0xffffffff << 0)
+
+/* Renamed from DEBUG_OUT Used by PRM_DEBUG_WKUPAON_FD_TRANS */
+#define OMAP54XX_DEBUG_OUT_0_11_SHIFT						0
+#define OMAP54XX_DEBUG_OUT_0_11_WIDTH						0xc
+#define OMAP54XX_DEBUG_OUT_0_11_MASK						(0xfff << 0)
+
+/* Used by PRM_DEVICE_OFF_CTRL */
+#define OMAP54XX_DEVICE_OFF_ENABLE_SHIFT					0
+#define OMAP54XX_DEVICE_OFF_ENABLE_WIDTH					0x1
+#define OMAP54XX_DEVICE_OFF_ENABLE_MASK						(1 << 0)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP54XX_DFILTEREN_SHIFT						6
+#define OMAP54XX_DFILTEREN_WIDTH						0x1
+#define OMAP54XX_DFILTEREN_MASK							(1 << 6)
+
+/* Used by PRM_IRQENABLE_DSP, PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_DPLL_ABE_RECAL_EN_SHIFT					4
+#define OMAP54XX_DPLL_ABE_RECAL_EN_WIDTH					0x1
+#define OMAP54XX_DPLL_ABE_RECAL_EN_MASK						(1 << 4)
+
+/* Used by PRM_IRQSTATUS_DSP, PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_DPLL_ABE_RECAL_ST_SHIFT					4
+#define OMAP54XX_DPLL_ABE_RECAL_ST_WIDTH					0x1
+#define OMAP54XX_DPLL_ABE_RECAL_ST_MASK						(1 << 4)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_DPLL_CORE_RECAL_EN_SHIFT					0
+#define OMAP54XX_DPLL_CORE_RECAL_EN_WIDTH					0x1
+#define OMAP54XX_DPLL_CORE_RECAL_EN_MASK					(1 << 0)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_DPLL_CORE_RECAL_ST_SHIFT					0
+#define OMAP54XX_DPLL_CORE_RECAL_ST_WIDTH					0x1
+#define OMAP54XX_DPLL_CORE_RECAL_ST_MASK					(1 << 0)
+
+/* Used by PRM_IRQENABLE_DSP, PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_DPLL_IVA_RECAL_EN_SHIFT					2
+#define OMAP54XX_DPLL_IVA_RECAL_EN_WIDTH					0x1
+#define OMAP54XX_DPLL_IVA_RECAL_EN_MASK						(1 << 2)
+
+/* Used by PRM_IRQSTATUS_DSP, PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_DPLL_IVA_RECAL_ST_SHIFT					2
+#define OMAP54XX_DPLL_IVA_RECAL_ST_WIDTH					0x1
+#define OMAP54XX_DPLL_IVA_RECAL_ST_MASK						(1 << 2)
+
+/* Used by PRM_IRQENABLE_MPU */
+#define OMAP54XX_DPLL_MPU_RECAL_EN_SHIFT					1
+#define OMAP54XX_DPLL_MPU_RECAL_EN_WIDTH					0x1
+#define OMAP54XX_DPLL_MPU_RECAL_EN_MASK						(1 << 1)
+
+/* Used by PRM_IRQSTATUS_MPU */
+#define OMAP54XX_DPLL_MPU_RECAL_ST_SHIFT					1
+#define OMAP54XX_DPLL_MPU_RECAL_ST_WIDTH					0x1
+#define OMAP54XX_DPLL_MPU_RECAL_ST_MASK						(1 << 1)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_DPLL_PER_RECAL_EN_SHIFT					3
+#define OMAP54XX_DPLL_PER_RECAL_EN_WIDTH					0x1
+#define OMAP54XX_DPLL_PER_RECAL_EN_MASK						(1 << 3)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_DPLL_PER_RECAL_ST_SHIFT					3
+#define OMAP54XX_DPLL_PER_RECAL_ST_WIDTH					0x1
+#define OMAP54XX_DPLL_PER_RECAL_ST_MASK						(1 << 3)
+
+/* Used by PM_DSP_PWRSTCTRL */
+#define OMAP54XX_DSP_EDMA_ONSTATE_SHIFT						20
+#define OMAP54XX_DSP_EDMA_ONSTATE_WIDTH						0x2
+#define OMAP54XX_DSP_EDMA_ONSTATE_MASK						(0x3 << 20)
+
+/* Used by PM_DSP_PWRSTCTRL */
+#define OMAP54XX_DSP_EDMA_RETSTATE_SHIFT					10
+#define OMAP54XX_DSP_EDMA_RETSTATE_WIDTH					0x1
+#define OMAP54XX_DSP_EDMA_RETSTATE_MASK						(1 << 10)
+
+/* Used by PM_DSP_PWRSTST */
+#define OMAP54XX_DSP_EDMA_STATEST_SHIFT						8
+#define OMAP54XX_DSP_EDMA_STATEST_WIDTH						0x2
+#define OMAP54XX_DSP_EDMA_STATEST_MASK						(0x3 << 8)
+
+/* Used by PM_DSP_PWRSTCTRL */
+#define OMAP54XX_DSP_L1_ONSTATE_SHIFT						16
+#define OMAP54XX_DSP_L1_ONSTATE_WIDTH						0x2
+#define OMAP54XX_DSP_L1_ONSTATE_MASK						(0x3 << 16)
+
+/* Used by PM_DSP_PWRSTCTRL */
+#define OMAP54XX_DSP_L1_RETSTATE_SHIFT						8
+#define OMAP54XX_DSP_L1_RETSTATE_WIDTH						0x1
+#define OMAP54XX_DSP_L1_RETSTATE_MASK						(1 << 8)
+
+/* Used by PM_DSP_PWRSTST */
+#define OMAP54XX_DSP_L1_STATEST_SHIFT						4
+#define OMAP54XX_DSP_L1_STATEST_WIDTH						0x2
+#define OMAP54XX_DSP_L1_STATEST_MASK						(0x3 << 4)
+
+/* Used by PM_DSP_PWRSTCTRL */
+#define OMAP54XX_DSP_L2_ONSTATE_SHIFT						18
+#define OMAP54XX_DSP_L2_ONSTATE_WIDTH						0x2
+#define OMAP54XX_DSP_L2_ONSTATE_MASK						(0x3 << 18)
+
+/* Used by PM_DSP_PWRSTCTRL */
+#define OMAP54XX_DSP_L2_RETSTATE_SHIFT						9
+#define OMAP54XX_DSP_L2_RETSTATE_WIDTH						0x1
+#define OMAP54XX_DSP_L2_RETSTATE_MASK						(1 << 9)
+
+/* Used by PM_DSP_PWRSTST */
+#define OMAP54XX_DSP_L2_STATEST_SHIFT						6
+#define OMAP54XX_DSP_L2_STATEST_WIDTH						0x2
+#define OMAP54XX_DSP_L2_STATEST_MASK						(0x3 << 6)
+
+/* Used by PM_DSS_PWRSTCTRL */
+#define OMAP54XX_DSS_MEM_ONSTATE_SHIFT						16
+#define OMAP54XX_DSS_MEM_ONSTATE_WIDTH						0x2
+#define OMAP54XX_DSS_MEM_ONSTATE_MASK						(0x3 << 16)
+
+/* Used by PM_DSS_PWRSTCTRL */
+#define OMAP54XX_DSS_MEM_RETSTATE_SHIFT						8
+#define OMAP54XX_DSS_MEM_RETSTATE_WIDTH						0x1
+#define OMAP54XX_DSS_MEM_RETSTATE_MASK						(1 << 8)
+
+/* Used by PM_DSS_PWRSTST */
+#define OMAP54XX_DSS_MEM_STATEST_SHIFT						4
+#define OMAP54XX_DSS_MEM_STATEST_WIDTH						0x2
+#define OMAP54XX_DSS_MEM_STATEST_MASK						(0x3 << 4)
+
+/* Used by PRM_DEVICE_OFF_CTRL */
+#define OMAP54XX_EMIF1_OFFWKUP_DISABLE_SHIFT					8
+#define OMAP54XX_EMIF1_OFFWKUP_DISABLE_WIDTH					0x1
+#define OMAP54XX_EMIF1_OFFWKUP_DISABLE_MASK					(1 << 8)
+
+/* Used by PRM_DEVICE_OFF_CTRL */
+#define OMAP54XX_EMIF2_OFFWKUP_DISABLE_SHIFT					9
+#define OMAP54XX_EMIF2_OFFWKUP_DISABLE_WIDTH					0x1
+#define OMAP54XX_EMIF2_OFFWKUP_DISABLE_MASK					(1 << 9)
+
+/* Used by PM_EMU_PWRSTCTRL */
+#define OMAP54XX_EMU_BANK_ONSTATE_SHIFT						16
+#define OMAP54XX_EMU_BANK_ONSTATE_WIDTH						0x2
+#define OMAP54XX_EMU_BANK_ONSTATE_MASK						(0x3 << 16)
+
+/* Used by PM_EMU_PWRSTST */
+#define OMAP54XX_EMU_BANK_STATEST_SHIFT						4
+#define OMAP54XX_EMU_BANK_STATEST_WIDTH						0x2
+#define OMAP54XX_EMU_BANK_STATEST_MASK						(0x3 << 4)
+
+/*
+ * Used by PRM_SLDO_CORE_SETUP, PRM_SLDO_MM_SETUP, PRM_SLDO_MPU_SETUP,
+ * PRM_SRAM_WKUP_SETUP
+ */
+#define OMAP54XX_ENABLE_RTA_SHIFT						0
+#define OMAP54XX_ENABLE_RTA_WIDTH						0x1
+#define OMAP54XX_ENABLE_RTA_MASK						(1 << 0)
+
+/* Used by PRM_SLDO_CORE_SETUP, PRM_SLDO_MM_SETUP, PRM_SLDO_MPU_SETUP */
+#define OMAP54XX_ENFUNC1_SHIFT							3
+#define OMAP54XX_ENFUNC1_WIDTH							0x1
+#define OMAP54XX_ENFUNC1_MASK							(1 << 3)
+
+/* Used by PRM_SLDO_CORE_SETUP, PRM_SLDO_MM_SETUP, PRM_SLDO_MPU_SETUP */
+#define OMAP54XX_ENFUNC2_SHIFT							4
+#define OMAP54XX_ENFUNC2_WIDTH							0x1
+#define OMAP54XX_ENFUNC2_MASK							(1 << 4)
+
+/* Used by PRM_SLDO_CORE_SETUP, PRM_SLDO_MM_SETUP, PRM_SLDO_MPU_SETUP */
+#define OMAP54XX_ENFUNC3_SHIFT							5
+#define OMAP54XX_ENFUNC3_WIDTH							0x1
+#define OMAP54XX_ENFUNC3_MASK							(1 << 5)
+
+/* Used by PRM_SLDO_CORE_SETUP, PRM_SLDO_MM_SETUP, PRM_SLDO_MPU_SETUP */
+#define OMAP54XX_ENFUNC4_SHIFT							6
+#define OMAP54XX_ENFUNC4_WIDTH							0x1
+#define OMAP54XX_ENFUNC4_MASK							(1 << 6)
+
+/* Used by PRM_SLDO_CORE_SETUP, PRM_SLDO_MM_SETUP, PRM_SLDO_MPU_SETUP */
+#define OMAP54XX_ENFUNC5_SHIFT							7
+#define OMAP54XX_ENFUNC5_WIDTH							0x1
+#define OMAP54XX_ENFUNC5_MASK							(1 << 7)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_MM_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP54XX_ERRORGAIN_SHIFT						16
+#define OMAP54XX_ERRORGAIN_WIDTH						0x8
+#define OMAP54XX_ERRORGAIN_MASK							(0xff << 16)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_MM_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP54XX_ERROROFFSET_SHIFT						24
+#define OMAP54XX_ERROROFFSET_WIDTH						0x8
+#define OMAP54XX_ERROROFFSET_MASK						(0xff << 24)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_EXTERNAL_WARM_RST_SHIFT					5
+#define OMAP54XX_EXTERNAL_WARM_RST_WIDTH					0x1
+#define OMAP54XX_EXTERNAL_WARM_RST_MASK						(1 << 5)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_MM_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP54XX_FORCEUPDATE_SHIFT						1
+#define OMAP54XX_FORCEUPDATE_WIDTH						0x1
+#define OMAP54XX_FORCEUPDATE_MASK						(1 << 1)
+
+/* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_MM_VOLTAGE, PRM_VP_MPU_VOLTAGE */
+#define OMAP54XX_FORCEUPDATEWAIT_SHIFT						8
+#define OMAP54XX_FORCEUPDATEWAIT_WIDTH						0x18
+#define OMAP54XX_FORCEUPDATEWAIT_MASK						(0xffffff << 8)
+
+/* Used by PRM_IRQENABLE_DSP, PRM_IRQENABLE_IPU */
+#define OMAP54XX_FORCEWKUP_EN_SHIFT						10
+#define OMAP54XX_FORCEWKUP_EN_WIDTH						0x1
+#define OMAP54XX_FORCEWKUP_EN_MASK						(1 << 10)
+
+/* Used by PRM_IRQSTATUS_DSP, PRM_IRQSTATUS_IPU */
+#define OMAP54XX_FORCEWKUP_ST_SHIFT						10
+#define OMAP54XX_FORCEWKUP_ST_WIDTH						0x1
+#define OMAP54XX_FORCEWKUP_ST_MASK						(1 << 10)
+
+/* Used by REVISION_PRM */
+#define OMAP54XX_FUNC_SHIFT							16
+#define OMAP54XX_FUNC_WIDTH							0xc
+#define OMAP54XX_FUNC_MASK							(0xfff << 16)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_GLOBAL_COLD_RST_SHIFT						0
+#define OMAP54XX_GLOBAL_COLD_RST_WIDTH						0x1
+#define OMAP54XX_GLOBAL_COLD_RST_MASK						(1 << 0)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_GLOBAL_WARM_SW_RST_SHIFT					1
+#define OMAP54XX_GLOBAL_WARM_SW_RST_WIDTH					0x1
+#define OMAP54XX_GLOBAL_WARM_SW_RST_MASK					(1 << 1)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP54XX_GLOBAL_WUEN_SHIFT						16
+#define OMAP54XX_GLOBAL_WUEN_WIDTH						0x1
+#define OMAP54XX_GLOBAL_WUEN_MASK						(1 << 16)
+
+/* Used by PM_GPU_PWRSTCTRL */
+#define OMAP54XX_GPU_MEM_ONSTATE_SHIFT						16
+#define OMAP54XX_GPU_MEM_ONSTATE_WIDTH						0x2
+#define OMAP54XX_GPU_MEM_ONSTATE_MASK						(0x3 << 16)
+
+/* Used by PM_GPU_PWRSTST */
+#define OMAP54XX_GPU_MEM_STATEST_SHIFT						4
+#define OMAP54XX_GPU_MEM_STATEST_WIDTH						0x2
+#define OMAP54XX_GPU_MEM_STATEST_MASK						(0x3 << 4)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP54XX_HSMCODE_SHIFT							0
+#define OMAP54XX_HSMCODE_WIDTH							0x3
+#define OMAP54XX_HSMCODE_MASK							(0x7 << 0)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP54XX_HSMODEEN_SHIFT							3
+#define OMAP54XX_HSMODEEN_WIDTH							0x1
+#define OMAP54XX_HSMODEEN_MASK							(1 << 3)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP54XX_HSSCLH_SHIFT							16
+#define OMAP54XX_HSSCLH_WIDTH							0x8
+#define OMAP54XX_HSSCLH_MASK							(0xff << 16)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP54XX_HSSCLL_SHIFT							24
+#define OMAP54XX_HSSCLL_WIDTH							0x8
+#define OMAP54XX_HSSCLL_MASK							(0xff << 24)
+
+/* Used by PM_IVA_PWRSTCTRL */
+#define OMAP54XX_HWA_MEM_ONSTATE_SHIFT						16
+#define OMAP54XX_HWA_MEM_ONSTATE_WIDTH						0x2
+#define OMAP54XX_HWA_MEM_ONSTATE_MASK						(0x3 << 16)
+
+/* Used by PM_IVA_PWRSTCTRL */
+#define OMAP54XX_HWA_MEM_RETSTATE_SHIFT						8
+#define OMAP54XX_HWA_MEM_RETSTATE_WIDTH						0x1
+#define OMAP54XX_HWA_MEM_RETSTATE_MASK						(1 << 8)
+
+/* Used by PM_IVA_PWRSTST */
+#define OMAP54XX_HWA_MEM_STATEST_SHIFT						4
+#define OMAP54XX_HWA_MEM_STATEST_WIDTH						0x2
+#define OMAP54XX_HWA_MEM_STATEST_MASK						(0x3 << 4)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_ICEPICK_RST_SHIFT						9
+#define OMAP54XX_ICEPICK_RST_WIDTH						0x1
+#define OMAP54XX_ICEPICK_RST_MASK						(1 << 9)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_MM_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP54XX_INITVDD_SHIFT							2
+#define OMAP54XX_INITVDD_WIDTH							0x1
+#define OMAP54XX_INITVDD_MASK							(1 << 2)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_MM_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP54XX_INITVOLTAGE_SHIFT						8
+#define OMAP54XX_INITVOLTAGE_WIDTH						0x8
+#define OMAP54XX_INITVOLTAGE_MASK						(0xff << 8)
+
+/*
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CORE_PWRSTST,
+ * PM_CUSTEFUSE_PWRSTST, PM_DSP_PWRSTST, PM_DSS_PWRSTST, PM_EMU_PWRSTST,
+ * PM_GPU_PWRSTST, PM_IVA_PWRSTST, PM_L3INIT_PWRSTST, PM_MPU_PWRSTST,
+ * PRM_VOLTST_MM, PRM_VOLTST_MPU
+ */
+#define OMAP54XX_INTRANSITION_SHIFT						20
+#define OMAP54XX_INTRANSITION_WIDTH						0x1
+#define OMAP54XX_INTRANSITION_MASK						(1 << 20)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_IO_EN_SHIFT							9
+#define OMAP54XX_IO_EN_WIDTH							0x1
+#define OMAP54XX_IO_EN_MASK							(1 << 9)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP54XX_IO_ON_STATUS_SHIFT						5
+#define OMAP54XX_IO_ON_STATUS_WIDTH						0x1
+#define OMAP54XX_IO_ON_STATUS_MASK						(1 << 5)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_IO_ST_SHIFT							9
+#define OMAP54XX_IO_ST_WIDTH							0x1
+#define OMAP54XX_IO_ST_MASK							(1 << 9)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_IPU_L2RAM_ONSTATE_SHIFT					20
+#define OMAP54XX_IPU_L2RAM_ONSTATE_WIDTH					0x2
+#define OMAP54XX_IPU_L2RAM_ONSTATE_MASK						(0x3 << 20)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_IPU_L2RAM_RETSTATE_SHIFT					10
+#define OMAP54XX_IPU_L2RAM_RETSTATE_WIDTH					0x1
+#define OMAP54XX_IPU_L2RAM_RETSTATE_MASK					(1 << 10)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP54XX_IPU_L2RAM_STATEST_SHIFT					8
+#define OMAP54XX_IPU_L2RAM_STATEST_WIDTH					0x2
+#define OMAP54XX_IPU_L2RAM_STATEST_MASK						(0x3 << 8)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_IPU_UNICACHE_ONSTATE_SHIFT					22
+#define OMAP54XX_IPU_UNICACHE_ONSTATE_WIDTH					0x2
+#define OMAP54XX_IPU_UNICACHE_ONSTATE_MASK					(0x3 << 22)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_IPU_UNICACHE_RETSTATE_SHIFT					11
+#define OMAP54XX_IPU_UNICACHE_RETSTATE_WIDTH					0x1
+#define OMAP54XX_IPU_UNICACHE_RETSTATE_MASK					(1 << 11)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP54XX_IPU_UNICACHE_STATEST_SHIFT					10
+#define OMAP54XX_IPU_UNICACHE_STATEST_WIDTH					0x2
+#define OMAP54XX_IPU_UNICACHE_STATEST_MASK					(0x3 << 10)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP54XX_ISOCLK_OVERRIDE_SHIFT						0
+#define OMAP54XX_ISOCLK_OVERRIDE_WIDTH						0x1
+#define OMAP54XX_ISOCLK_OVERRIDE_MASK						(1 << 0)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP54XX_ISOCLK_STATUS_SHIFT						1
+#define OMAP54XX_ISOCLK_STATUS_WIDTH						0x1
+#define OMAP54XX_ISOCLK_STATUS_MASK						(1 << 1)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP54XX_ISOOVR_EXTEND_SHIFT						4
+#define OMAP54XX_ISOOVR_EXTEND_WIDTH						0x1
+#define OMAP54XX_ISOOVR_EXTEND_MASK						(1 << 4)
+
+/* Used by PRM_IO_COUNT */
+#define OMAP54XX_ISO_2_ON_TIME_SHIFT						0
+#define OMAP54XX_ISO_2_ON_TIME_WIDTH						0x8
+#define OMAP54XX_ISO_2_ON_TIME_MASK						(0xff << 0)
+
+/* Used by PM_L3INIT_PWRSTCTRL */
+#define OMAP54XX_L3INIT_BANK1_ONSTATE_SHIFT					16
+#define OMAP54XX_L3INIT_BANK1_ONSTATE_WIDTH					0x2
+#define OMAP54XX_L3INIT_BANK1_ONSTATE_MASK					(0x3 << 16)
+
+/* Used by PM_L3INIT_PWRSTCTRL */
+#define OMAP54XX_L3INIT_BANK1_RETSTATE_SHIFT					8
+#define OMAP54XX_L3INIT_BANK1_RETSTATE_WIDTH					0x1
+#define OMAP54XX_L3INIT_BANK1_RETSTATE_MASK					(1 << 8)
+
+/* Used by PM_L3INIT_PWRSTST */
+#define OMAP54XX_L3INIT_BANK1_STATEST_SHIFT					4
+#define OMAP54XX_L3INIT_BANK1_STATEST_WIDTH					0x2
+#define OMAP54XX_L3INIT_BANK1_STATEST_MASK					(0x3 << 4)
+
+/* Used by PM_L3INIT_PWRSTCTRL */
+#define OMAP54XX_L3INIT_BANK2_ONSTATE_SHIFT					18
+#define OMAP54XX_L3INIT_BANK2_ONSTATE_WIDTH					0x2
+#define OMAP54XX_L3INIT_BANK2_ONSTATE_MASK					(0x3 << 18)
+
+/* Used by PM_L3INIT_PWRSTCTRL */
+#define OMAP54XX_L3INIT_BANK2_RETSTATE_SHIFT					9
+#define OMAP54XX_L3INIT_BANK2_RETSTATE_WIDTH					0x1
+#define OMAP54XX_L3INIT_BANK2_RETSTATE_MASK					(1 << 9)
+
+/* Used by PM_L3INIT_PWRSTST */
+#define OMAP54XX_L3INIT_BANK2_STATEST_SHIFT					6
+#define OMAP54XX_L3INIT_BANK2_STATEST_WIDTH					0x2
+#define OMAP54XX_L3INIT_BANK2_STATEST_MASK					(0x3 << 6)
+
+/*
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CORE_PWRSTST,
+ * PM_CUSTEFUSE_PWRSTST, PM_DSP_PWRSTST, PM_DSS_PWRSTST, PM_EMU_PWRSTST,
+ * PM_GPU_PWRSTST, PM_IVA_PWRSTST, PM_L3INIT_PWRSTST, PM_MPU_PWRSTST
+ */
+#define OMAP54XX_LASTPOWERSTATEENTERED_SHIFT					24
+#define OMAP54XX_LASTPOWERSTATEENTERED_WIDTH					0x2
+#define OMAP54XX_LASTPOWERSTATEENTERED_MASK					(0x3 << 24)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_LLI_RST_SHIFT							14
+#define OMAP54XX_LLI_RST_WIDTH							0x1
+#define OMAP54XX_LLI_RST_MASK							(1 << 14)
+
+/*
+ * Used by PM_ABE_PWRSTCTRL, PM_CORE_PWRSTCTRL, PM_DSP_PWRSTCTRL,
+ * PM_DSS_PWRSTCTRL, PM_IVA_PWRSTCTRL, PM_L3INIT_PWRSTCTRL, PM_MPU_PWRSTCTRL
+ */
+#define OMAP54XX_LOGICRETSTATE_SHIFT						2
+#define OMAP54XX_LOGICRETSTATE_WIDTH						0x1
+#define OMAP54XX_LOGICRETSTATE_MASK						(1 << 2)
+
+/*
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CORE_PWRSTST,
+ * PM_CUSTEFUSE_PWRSTST, PM_DSP_PWRSTST, PM_DSS_PWRSTST, PM_EMU_PWRSTST,
+ * PM_GPU_PWRSTST, PM_IVA_PWRSTST, PM_L3INIT_PWRSTST, PM_MPU_PWRSTST
+ */
+#define OMAP54XX_LOGICSTATEST_SHIFT						2
+#define OMAP54XX_LOGICSTATEST_WIDTH						0x1
+#define OMAP54XX_LOGICSTATEST_MASK						(1 << 2)
+
+/*
+ * Used by RM_ABE_AESS_CONTEXT, RM_ABE_DMIC_CONTEXT, RM_ABE_MCASP_CONTEXT,
+ * RM_ABE_MCBSP1_CONTEXT, RM_ABE_MCBSP2_CONTEXT, RM_ABE_MCBSP3_CONTEXT,
+ * RM_ABE_MCPDM_CONTEXT, RM_ABE_SLIMBUS1_CONTEXT, RM_ABE_TIMER5_CONTEXT,
+ * RM_ABE_TIMER6_CONTEXT, RM_ABE_TIMER7_CONTEXT, RM_ABE_TIMER8_CONTEXT,
+ * RM_ABE_WD_TIMER3_CONTEXT, RM_C2C_C2C_CONTEXT, RM_C2C_C2C_OCP_FW_CONTEXT,
+ * RM_CAM_CAL_CONTEXT, RM_CAM_FDIF_CONTEXT, RM_CAM_ISS_CONTEXT,
+ * RM_COREAON_SMARTREFLEX_CORE_CONTEXT, RM_COREAON_SMARTREFLEX_MM_CONTEXT,
+ * RM_COREAON_SMARTREFLEX_MPU_CONTEXT, RM_CUSTEFUSE_EFUSE_CTRL_CUST_CONTEXT,
+ * RM_DSP_DSP_CONTEXT, RM_DSS_BB2D_CONTEXT, RM_DSS_DSS_CONTEXT,
+ * RM_EMIF_DMM_CONTEXT, RM_EMIF_EMIF1_CONTEXT, RM_EMIF_EMIF2_CONTEXT,
+ * RM_EMIF_EMIF_DLL_CONTEXT, RM_EMIF_EMIF_OCP_FW_CONTEXT,
+ * RM_EMU_DEBUGSS_CONTEXT, RM_GPU_GPU_CONTEXT, RM_IPU_IPU_CONTEXT,
+ * RM_IVA_IVA_CONTEXT, RM_IVA_SL2_CONTEXT, RM_L3INIT_IEEE1500_2_OCP_CONTEXT,
+ * RM_L3INIT_OCP2SCP1_CONTEXT, RM_L3INIT_OCP2SCP3_CONTEXT,
+ * RM_L3INIT_SATA_CONTEXT, RM_L3INIT_UNIPRO2_CONTEXT,
+ * RM_L3INSTR_L3_INSTR_CONTEXT, RM_L3INSTR_L3_MAIN_3_CONTEXT,
+ * RM_L3INSTR_OCP_WP_NOC_CONTEXT, RM_L3MAIN1_L3_MAIN_1_CONTEXT,
+ * RM_L3MAIN2_L3_MAIN_2_CONTEXT, RM_L3MAIN2_OCMC_RAM_CONTEXT,
+ * RM_L4CFG_L4_CFG_CONTEXT, RM_L4CFG_OCP2SCP2_CONTEXT,
+ * RM_L4CFG_SAR_ROM_CONTEXT, RM_L4PER_ELM_CONTEXT, RM_L4PER_HDQ1W_CONTEXT,
+ * RM_L4PER_I2C2_CONTEXT, RM_L4PER_I2C3_CONTEXT, RM_L4PER_I2C4_CONTEXT,
+ * RM_L4PER_I2C5_CONTEXT, RM_L4PER_L4_PER_CONTEXT, RM_L4PER_MCSPI1_CONTEXT,
+ * RM_L4PER_MCSPI2_CONTEXT, RM_L4PER_MCSPI3_CONTEXT, RM_L4PER_MCSPI4_CONTEXT,
+ * RM_L4PER_MMC3_CONTEXT, RM_L4PER_MMC4_CONTEXT, RM_L4PER_MMC5_CONTEXT,
+ * RM_L4PER_TIMER10_CONTEXT, RM_L4PER_TIMER11_CONTEXT, RM_L4PER_TIMER2_CONTEXT,
+ * RM_L4PER_TIMER3_CONTEXT, RM_L4PER_TIMER4_CONTEXT, RM_L4PER_TIMER9_CONTEXT,
+ * RM_L4SEC_FPKA_CONTEXT, RM_MIPIEXT_LLI_CONTEXT,
+ * RM_MIPIEXT_LLI_OCP_FW_CONTEXT, RM_MIPIEXT_MPHY_CONTEXT, RM_MPU_MPU_CONTEXT,
+ * RM_WKUPAON_COUNTER_32K_CONTEXT, RM_WKUPAON_GPIO1_CONTEXT,
+ * RM_WKUPAON_KBD_CONTEXT, RM_WKUPAON_L4_WKUP_CONTEXT,
+ * RM_WKUPAON_SAR_RAM_CONTEXT, RM_WKUPAON_TIMER12_CONTEXT,
+ * RM_WKUPAON_TIMER1_CONTEXT, RM_WKUPAON_WD_TIMER1_CONTEXT,
+ * RM_WKUPAON_WD_TIMER2_CONTEXT
+ */
+#define OMAP54XX_LOSTCONTEXT_DFF_SHIFT						0
+#define OMAP54XX_LOSTCONTEXT_DFF_WIDTH						0x1
+#define OMAP54XX_LOSTCONTEXT_DFF_MASK						(1 << 0)
+
+/*
+ * Used by RM_C2C_C2C_CONTEXT, RM_C2C_C2C_OCP_FW_CONTEXT,
+ * RM_C2C_MODEM_ICR_CONTEXT, RM_DMA_DMA_SYSTEM_CONTEXT, RM_DSP_DSP_CONTEXT,
+ * RM_DSS_DSS_CONTEXT, RM_EMIF_DMM_CONTEXT, RM_EMIF_EMIF1_CONTEXT,
+ * RM_EMIF_EMIF2_CONTEXT, RM_EMIF_EMIF_OCP_FW_CONTEXT, RM_IPU_IPU_CONTEXT,
+ * RM_L3INIT_HSI_CONTEXT, RM_L3INIT_MMC1_CONTEXT, RM_L3INIT_MMC2_CONTEXT,
+ * RM_L3INIT_USB_HOST_HS_CONTEXT, RM_L3INIT_USB_OTG_SS_CONTEXT,
+ * RM_L3INIT_USB_TLL_HS_CONTEXT, RM_L3INSTR_L3_MAIN_3_CONTEXT,
+ * RM_L3INSTR_OCP_WP_NOC_CONTEXT, RM_L3MAIN1_L3_MAIN_1_CONTEXT,
+ * RM_L3MAIN2_GPMC_CONTEXT, RM_L3MAIN2_L3_MAIN_2_CONTEXT,
+ * RM_L4CFG_L4_CFG_CONTEXT, RM_L4CFG_MAILBOX_CONTEXT,
+ * RM_L4CFG_SPINLOCK_CONTEXT, RM_L4PER_GPIO2_CONTEXT, RM_L4PER_GPIO3_CONTEXT,
+ * RM_L4PER_GPIO4_CONTEXT, RM_L4PER_GPIO5_CONTEXT, RM_L4PER_GPIO6_CONTEXT,
+ * RM_L4PER_GPIO7_CONTEXT, RM_L4PER_GPIO8_CONTEXT, RM_L4PER_I2C1_CONTEXT,
+ * RM_L4PER_L4_PER_CONTEXT, RM_L4PER_UART1_CONTEXT, RM_L4PER_UART2_CONTEXT,
+ * RM_L4PER_UART3_CONTEXT, RM_L4PER_UART4_CONTEXT, RM_L4PER_UART5_CONTEXT,
+ * RM_L4PER_UART6_CONTEXT, RM_L4SEC_AES1_CONTEXT, RM_L4SEC_AES2_CONTEXT,
+ * RM_L4SEC_DES3DES_CONTEXT, RM_L4SEC_DMA_CRYPTO_CONTEXT, RM_L4SEC_RNG_CONTEXT,
+ * RM_L4SEC_SHA2MD5_CONTEXT, RM_MIPIEXT_LLI_CONTEXT,
+ * RM_MIPIEXT_LLI_OCP_FW_CONTEXT, RM_MIPIEXT_MPHY_CONTEXT, RM_MPU_MPU_CONTEXT
+ */
+#define OMAP54XX_LOSTCONTEXT_RFF_SHIFT						1
+#define OMAP54XX_LOSTCONTEXT_RFF_WIDTH						0x1
+#define OMAP54XX_LOSTCONTEXT_RFF_MASK						(1 << 1)
+
+/* Used by RM_ABE_AESS_CONTEXT */
+#define OMAP54XX_LOSTMEM_AESSMEM_SHIFT						8
+#define OMAP54XX_LOSTMEM_AESSMEM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_AESSMEM_MASK						(1 << 8)
+
+/* Used by RM_CAM_CAL_CONTEXT */
+#define OMAP54XX_LOSTMEM_CAL_MEM_SHIFT						8
+#define OMAP54XX_LOSTMEM_CAL_MEM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_CAL_MEM_MASK						(1 << 8)
+
+/* Used by RM_CAM_FDIF_CONTEXT, RM_CAM_ISS_CONTEXT */
+#define OMAP54XX_LOSTMEM_CAM_MEM_SHIFT						8
+#define OMAP54XX_LOSTMEM_CAM_MEM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_CAM_MEM_MASK						(1 << 8)
+
+/* Used by RM_EMIF_DMM_CONTEXT */
+#define OMAP54XX_LOSTMEM_CORE_NRET_BANK_SHIFT					9
+#define OMAP54XX_LOSTMEM_CORE_NRET_BANK_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_CORE_NRET_BANK_MASK					(1 << 9)
+
+/* Renamed from LOSTMEM_CORE_NRET_BANK Used by RM_L3INSTR_OCP_WP_NOC_CONTEXT */
+#define OMAP54XX_LOSTMEM_CORE_NRET_BANK_8_8_SHIFT				8
+#define OMAP54XX_LOSTMEM_CORE_NRET_BANK_8_8_WIDTH				0x1
+#define OMAP54XX_LOSTMEM_CORE_NRET_BANK_8_8_MASK				(1 << 8)
+
+/* Used by RM_L3MAIN2_OCMC_RAM_CONTEXT */
+#define OMAP54XX_LOSTMEM_CORE_OCMRAM_SHIFT					8
+#define OMAP54XX_LOSTMEM_CORE_OCMRAM_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_CORE_OCMRAM_MASK					(1 << 8)
+
+/* Used by RM_DMA_DMA_SYSTEM_CONTEXT, RM_EMIF_DMM_CONTEXT */
+#define OMAP54XX_LOSTMEM_CORE_OTHER_BANK_SHIFT					8
+#define OMAP54XX_LOSTMEM_CORE_OTHER_BANK_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_CORE_OTHER_BANK_MASK					(1 << 8)
+
+/* Used by RM_DSP_DSP_CONTEXT */
+#define OMAP54XX_LOSTMEM_DSP_EDMA_SHIFT						10
+#define OMAP54XX_LOSTMEM_DSP_EDMA_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_DSP_EDMA_MASK						(1 << 10)
+
+/* Used by RM_DSP_DSP_CONTEXT */
+#define OMAP54XX_LOSTMEM_DSP_L1_SHIFT						8
+#define OMAP54XX_LOSTMEM_DSP_L1_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_DSP_L1_MASK						(1 << 8)
+
+/* Used by RM_DSP_DSP_CONTEXT */
+#define OMAP54XX_LOSTMEM_DSP_L2_SHIFT						9
+#define OMAP54XX_LOSTMEM_DSP_L2_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_DSP_L2_MASK						(1 << 9)
+
+/* Used by RM_DSS_BB2D_CONTEXT, RM_DSS_DSS_CONTEXT */
+#define OMAP54XX_LOSTMEM_DSS_MEM_SHIFT						8
+#define OMAP54XX_LOSTMEM_DSS_MEM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_DSS_MEM_MASK						(1 << 8)
+
+/* Used by RM_EMU_DEBUGSS_CONTEXT */
+#define OMAP54XX_LOSTMEM_EMU_BANK_SHIFT						8
+#define OMAP54XX_LOSTMEM_EMU_BANK_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_EMU_BANK_MASK						(1 << 8)
+
+/* Used by RM_GPU_GPU_CONTEXT */
+#define OMAP54XX_LOSTMEM_GPU_MEM_SHIFT						8
+#define OMAP54XX_LOSTMEM_GPU_MEM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_GPU_MEM_MASK						(1 << 8)
+
+/* Used by RM_IVA_IVA_CONTEXT */
+#define OMAP54XX_LOSTMEM_HWA_MEM_SHIFT						10
+#define OMAP54XX_LOSTMEM_HWA_MEM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_HWA_MEM_MASK						(1 << 10)
+
+/* Used by RM_IPU_IPU_CONTEXT */
+#define OMAP54XX_LOSTMEM_IPU_L2RAM_SHIFT					9
+#define OMAP54XX_LOSTMEM_IPU_L2RAM_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_IPU_L2RAM_MASK						(1 << 9)
+
+/* Used by RM_IPU_IPU_CONTEXT */
+#define OMAP54XX_LOSTMEM_IPU_UNICACHE_SHIFT					8
+#define OMAP54XX_LOSTMEM_IPU_UNICACHE_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_IPU_UNICACHE_MASK					(1 << 8)
+
+/*
+ * Used by RM_L3INIT_HSI_CONTEXT, RM_L3INIT_MMC1_CONTEXT,
+ * RM_L3INIT_MMC2_CONTEXT, RM_L3INIT_SATA_CONTEXT, RM_L3INIT_UNIPRO2_CONTEXT,
+ * RM_L3INIT_USB_OTG_SS_CONTEXT
+ */
+#define OMAP54XX_LOSTMEM_L3INIT_BANK1_SHIFT					8
+#define OMAP54XX_LOSTMEM_L3INIT_BANK1_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_L3INIT_BANK1_MASK					(1 << 8)
+
+/* Used by RM_MPU_MPU_CONTEXT */
+#define OMAP54XX_LOSTMEM_MPU_L2_SHIFT						9
+#define OMAP54XX_LOSTMEM_MPU_L2_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_MPU_L2_MASK						(1 << 9)
+
+/* Used by RM_MPU_MPU_CONTEXT */
+#define OMAP54XX_LOSTMEM_MPU_RAM_SHIFT						10
+#define OMAP54XX_LOSTMEM_MPU_RAM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_MPU_RAM_MASK						(1 << 10)
+
+/*
+ * Used by RM_L4PER_MMC3_CONTEXT, RM_L4PER_MMC4_CONTEXT, RM_L4PER_MMC5_CONTEXT,
+ * RM_L4SEC_FPKA_CONTEXT
+ */
+#define OMAP54XX_LOSTMEM_NONRETAINED_BANK_SHIFT					8
+#define OMAP54XX_LOSTMEM_NONRETAINED_BANK_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_NONRETAINED_BANK_MASK					(1 << 8)
+
+/*
+ * Used by RM_ABE_DMIC_CONTEXT, RM_ABE_MCBSP1_CONTEXT, RM_ABE_MCBSP2_CONTEXT,
+ * RM_ABE_MCBSP3_CONTEXT, RM_ABE_MCPDM_CONTEXT, RM_ABE_SLIMBUS1_CONTEXT
+ */
+#define OMAP54XX_LOSTMEM_PERIHPMEM_SHIFT					8
+#define OMAP54XX_LOSTMEM_PERIHPMEM_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_PERIHPMEM_MASK						(1 << 8)
+
+/*
+ * Used by RM_L4PER_UART1_CONTEXT, RM_L4PER_UART2_CONTEXT,
+ * RM_L4PER_UART3_CONTEXT, RM_L4PER_UART4_CONTEXT, RM_L4PER_UART5_CONTEXT,
+ * RM_L4PER_UART6_CONTEXT, RM_L4SEC_DMA_CRYPTO_CONTEXT
+ */
+#define OMAP54XX_LOSTMEM_RETAINED_BANK_SHIFT					8
+#define OMAP54XX_LOSTMEM_RETAINED_BANK_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_RETAINED_BANK_MASK					(1 << 8)
+
+/* Used by RM_IVA_SL2_CONTEXT */
+#define OMAP54XX_LOSTMEM_SL2_MEM_SHIFT						8
+#define OMAP54XX_LOSTMEM_SL2_MEM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_SL2_MEM_MASK						(1 << 8)
+
+/* Used by RM_IVA_IVA_CONTEXT */
+#define OMAP54XX_LOSTMEM_TCM1_MEM_SHIFT						8
+#define OMAP54XX_LOSTMEM_TCM1_MEM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_TCM1_MEM_MASK						(1 << 8)
+
+/* Used by RM_IVA_IVA_CONTEXT */
+#define OMAP54XX_LOSTMEM_TCM2_MEM_SHIFT						9
+#define OMAP54XX_LOSTMEM_TCM2_MEM_WIDTH						0x1
+#define OMAP54XX_LOSTMEM_TCM2_MEM_MASK						(1 << 9)
+
+/* Used by RM_WKUPAON_SAR_RAM_CONTEXT */
+#define OMAP54XX_LOSTMEM_WKUP_BANK_SHIFT					8
+#define OMAP54XX_LOSTMEM_WKUP_BANK_WIDTH					0x1
+#define OMAP54XX_LOSTMEM_WKUP_BANK_MASK						(1 << 8)
+
+/*
+ * Used by PM_ABE_PWRSTCTRL, PM_CAM_PWRSTCTRL, PM_CORE_PWRSTCTRL,
+ * PM_CUSTEFUSE_PWRSTCTRL, PM_DSP_PWRSTCTRL, PM_DSS_PWRSTCTRL,
+ * PM_GPU_PWRSTCTRL, PM_IVA_PWRSTCTRL, PM_L3INIT_PWRSTCTRL, PM_MPU_PWRSTCTRL
+ */
+#define OMAP54XX_LOWPOWERSTATECHANGE_SHIFT					4
+#define OMAP54XX_LOWPOWERSTATECHANGE_WIDTH					0x1
+#define OMAP54XX_LOWPOWERSTATECHANGE_MASK					(1 << 4)
+
+/* Used by PRM_DEBUG_TRANS_CFG */
+#define OMAP54XX_MODE_SHIFT							0
+#define OMAP54XX_MODE_WIDTH							0x2
+#define OMAP54XX_MODE_MASK							(0x3 << 0)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP54XX_MODEM_SHUTDOWN_IRQ_SHIFT					9
+#define OMAP54XX_MODEM_SHUTDOWN_IRQ_WIDTH					0x1
+#define OMAP54XX_MODEM_SHUTDOWN_IRQ_MASK					(1 << 9)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP54XX_MODEM_WAKE_IRQ_SHIFT						8
+#define OMAP54XX_MODEM_WAKE_IRQ_WIDTH						0x1
+#define OMAP54XX_MODEM_WAKE_IRQ_MASK						(1 << 8)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP54XX_MPU_L2_ONSTATE_SHIFT						18
+#define OMAP54XX_MPU_L2_ONSTATE_WIDTH						0x2
+#define OMAP54XX_MPU_L2_ONSTATE_MASK						(0x3 << 18)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP54XX_MPU_L2_RETSTATE_SHIFT						9
+#define OMAP54XX_MPU_L2_RETSTATE_WIDTH						0x1
+#define OMAP54XX_MPU_L2_RETSTATE_MASK						(1 << 9)
+
+/* Used by PM_MPU_PWRSTST */
+#define OMAP54XX_MPU_L2_STATEST_SHIFT						6
+#define OMAP54XX_MPU_L2_STATEST_WIDTH						0x2
+#define OMAP54XX_MPU_L2_STATEST_MASK						(0x3 << 6)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP54XX_MPU_RAM_ONSTATE_SHIFT						20
+#define OMAP54XX_MPU_RAM_ONSTATE_WIDTH						0x2
+#define OMAP54XX_MPU_RAM_ONSTATE_MASK						(0x3 << 20)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP54XX_MPU_RAM_RETSTATE_SHIFT						10
+#define OMAP54XX_MPU_RAM_RETSTATE_WIDTH						0x1
+#define OMAP54XX_MPU_RAM_RETSTATE_MASK						(1 << 10)
+
+/* Used by PM_MPU_PWRSTST */
+#define OMAP54XX_MPU_RAM_STATEST_SHIFT						8
+#define OMAP54XX_MPU_RAM_STATEST_WIDTH						0x2
+#define OMAP54XX_MPU_RAM_STATEST_MASK						(0x3 << 8)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_MPU_SECURITY_VIOL_RST_SHIFT					2
+#define OMAP54XX_MPU_SECURITY_VIOL_RST_WIDTH					0x1
+#define OMAP54XX_MPU_SECURITY_VIOL_RST_MASK					(1 << 2)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_MPU_WDT_RST_SHIFT						3
+#define OMAP54XX_MPU_WDT_RST_WIDTH						0x1
+#define OMAP54XX_MPU_WDT_RST_MASK						(1 << 3)
+
+/* Used by PRM_ABBLDO_MM_SETUP, PRM_ABBLDO_MPU_SETUP */
+#define OMAP54XX_NOCAP_SHIFT							4
+#define OMAP54XX_NOCAP_WIDTH							0x1
+#define OMAP54XX_NOCAP_MASK							(1 << 4)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_OCP_NRET_BANK_ONSTATE_SHIFT					24
+#define OMAP54XX_OCP_NRET_BANK_ONSTATE_WIDTH					0x2
+#define OMAP54XX_OCP_NRET_BANK_ONSTATE_MASK					(0x3 << 24)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP54XX_OCP_NRET_BANK_RETSTATE_SHIFT					12
+#define OMAP54XX_OCP_NRET_BANK_RETSTATE_WIDTH					0x1
+#define OMAP54XX_OCP_NRET_BANK_RETSTATE_MASK					(1 << 12)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP54XX_OCP_NRET_BANK_STATEST_SHIFT					12
+#define OMAP54XX_OCP_NRET_BANK_STATEST_WIDTH					0x2
+#define OMAP54XX_OCP_NRET_BANK_STATEST_MASK					(0x3 << 12)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_MM_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP54XX_OFF_SHIFT							0
+#define OMAP54XX_OFF_WIDTH							0x8
+#define OMAP54XX_OFF_MASK							(0xff << 0)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_MM_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP54XX_ON_SHIFT							24
+#define OMAP54XX_ON_WIDTH							0x8
+#define OMAP54XX_ON_MASK							(0xff << 24)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_MM_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP54XX_ONLP_SHIFT							16
+#define OMAP54XX_ONLP_WIDTH							0x8
+#define OMAP54XX_ONLP_MASK							(0xff << 16)
+
+/* Used by PRM_ABBLDO_MM_CTRL, PRM_ABBLDO_MPU_CTRL */
+#define OMAP54XX_OPP_CHANGE_SHIFT						2
+#define OMAP54XX_OPP_CHANGE_WIDTH						0x1
+#define OMAP54XX_OPP_CHANGE_MASK						(1 << 2)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP54XX_OPP_CHANGE_EMIF_LVL_SHIFT					25
+#define OMAP54XX_OPP_CHANGE_EMIF_LVL_WIDTH					0x1
+#define OMAP54XX_OPP_CHANGE_EMIF_LVL_MASK					(1 << 25)
+
+/* Used by PRM_ABBLDO_MM_CTRL, PRM_ABBLDO_MPU_CTRL */
+#define OMAP54XX_OPP_SEL_SHIFT							0
+#define OMAP54XX_OPP_SEL_WIDTH							0x2
+#define OMAP54XX_OPP_SEL_MASK							(0x3 << 0)
+
+/* Used by PRM_DEBUG_OUT */
+#define OMAP54XX_OUTPUT_SHIFT							0
+#define OMAP54XX_OUTPUT_WIDTH							0x20
+#define OMAP54XX_OUTPUT_MASK							(0xffffffff << 0)
+
+/* Used by PRM_SRAM_COUNT */
+#define OMAP54XX_PCHARGECNT_VALUE_SHIFT						0
+#define OMAP54XX_PCHARGECNT_VALUE_WIDTH						0x6
+#define OMAP54XX_PCHARGECNT_VALUE_MASK						(0x3f << 0)
+
+/* Used by PRM_PSCON_COUNT */
+#define OMAP54XX_PCHARGE_TIME_SHIFT						0
+#define OMAP54XX_PCHARGE_TIME_WIDTH						0x8
+#define OMAP54XX_PCHARGE_TIME_MASK						(0xff << 0)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP54XX_PERIPHMEM_ONSTATE_SHIFT					20
+#define OMAP54XX_PERIPHMEM_ONSTATE_WIDTH					0x2
+#define OMAP54XX_PERIPHMEM_ONSTATE_MASK						(0x3 << 20)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP54XX_PERIPHMEM_RETSTATE_SHIFT					10
+#define OMAP54XX_PERIPHMEM_RETSTATE_WIDTH					0x1
+#define OMAP54XX_PERIPHMEM_RETSTATE_MASK					(1 << 10)
+
+/* Used by PM_ABE_PWRSTST */
+#define OMAP54XX_PERIPHMEM_STATEST_SHIFT					8
+#define OMAP54XX_PERIPHMEM_STATEST_WIDTH					0x2
+#define OMAP54XX_PERIPHMEM_STATEST_MASK						(0x3 << 8)
+
+/* Used by PRM_PHASE1_CNDP */
+#define OMAP54XX_PHASE1_CNDP_SHIFT						0
+#define OMAP54XX_PHASE1_CNDP_WIDTH						0x20
+#define OMAP54XX_PHASE1_CNDP_MASK						(0xffffffff << 0)
+
+/* Used by PRM_PHASE2A_CNDP */
+#define OMAP54XX_PHASE2A_CNDP_SHIFT						0
+#define OMAP54XX_PHASE2A_CNDP_WIDTH						0x20
+#define OMAP54XX_PHASE2A_CNDP_MASK						(0xffffffff << 0)
+
+/* Used by PRM_PHASE2B_CNDP */
+#define OMAP54XX_PHASE2B_CNDP_SHIFT						0
+#define OMAP54XX_PHASE2B_CNDP_WIDTH						0x20
+#define OMAP54XX_PHASE2B_CNDP_MASK						(0xffffffff << 0)
+
+/* Used by PRM_PSCON_COUNT */
+#define OMAP54XX_PONOUT_2_PGOODIN_TIME_SHIFT					8
+#define OMAP54XX_PONOUT_2_PGOODIN_TIME_WIDTH					0x8
+#define OMAP54XX_PONOUT_2_PGOODIN_TIME_MASK					(0xff << 8)
+
+/*
+ * Used by PM_ABE_PWRSTCTRL, PM_CAM_PWRSTCTRL, PM_CORE_PWRSTCTRL,
+ * PM_CUSTEFUSE_PWRSTCTRL, PM_DSP_PWRSTCTRL, PM_DSS_PWRSTCTRL,
+ * PM_EMU_PWRSTCTRL, PM_GPU_PWRSTCTRL, PM_IVA_PWRSTCTRL, PM_L3INIT_PWRSTCTRL,
+ * PM_MPU_PWRSTCTRL
+ */
+#define OMAP54XX_POWERSTATE_SHIFT						0
+#define OMAP54XX_POWERSTATE_WIDTH						0x2
+#define OMAP54XX_POWERSTATE_MASK						(0x3 << 0)
+
+/*
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CORE_PWRSTST,
+ * PM_CUSTEFUSE_PWRSTST, PM_DSP_PWRSTST, PM_DSS_PWRSTST, PM_EMU_PWRSTST,
+ * PM_GPU_PWRSTST, PM_IVA_PWRSTST, PM_L3INIT_PWRSTST, PM_MPU_PWRSTST
+ */
+#define OMAP54XX_POWERSTATEST_SHIFT						0
+#define OMAP54XX_POWERSTATEST_WIDTH						0x2
+#define OMAP54XX_POWERSTATEST_MASK						(0x3 << 0)
+
+/* Used by PRM_PWRREQCTRL */
+#define OMAP54XX_PWRREQ_COND_SHIFT						0
+#define OMAP54XX_PWRREQ_COND_WIDTH						0x2
+#define OMAP54XX_PWRREQ_COND_MASK						(0x3 << 0)
+
+/* Used by PRM_VC_SMPS_CORE_CONFIG */
+#define OMAP54XX_RACEN_VDD_CORE_L_SHIFT						27
+#define OMAP54XX_RACEN_VDD_CORE_L_WIDTH						0x1
+#define OMAP54XX_RACEN_VDD_CORE_L_MASK						(1 << 27)
+
+/* Used by PRM_VC_SMPS_MM_CONFIG */
+#define OMAP54XX_RACEN_VDD_MM_L_SHIFT						27
+#define OMAP54XX_RACEN_VDD_MM_L_WIDTH						0x1
+#define OMAP54XX_RACEN_VDD_MM_L_MASK						(1 << 27)
+
+/* Used by PRM_VC_SMPS_MPU_CONFIG */
+#define OMAP54XX_RACEN_VDD_MPU_L_SHIFT						27
+#define OMAP54XX_RACEN_VDD_MPU_L_WIDTH						0x1
+#define OMAP54XX_RACEN_VDD_MPU_L_MASK						(1 << 27)
+
+/* Used by PRM_VC_SMPS_CORE_CONFIG */
+#define OMAP54XX_RAC_VDD_CORE_L_SHIFT						26
+#define OMAP54XX_RAC_VDD_CORE_L_WIDTH						0x1
+#define OMAP54XX_RAC_VDD_CORE_L_MASK						(1 << 26)
+
+/* Used by PRM_VC_SMPS_MM_CONFIG */
+#define OMAP54XX_RAC_VDD_MM_L_SHIFT						26
+#define OMAP54XX_RAC_VDD_MM_L_WIDTH						0x1
+#define OMAP54XX_RAC_VDD_MM_L_MASK						(1 << 26)
+
+/* Used by PRM_VC_SMPS_MPU_CONFIG */
+#define OMAP54XX_RAC_VDD_MPU_L_SHIFT						26
+#define OMAP54XX_RAC_VDD_MPU_L_WIDTH						0x1
+#define OMAP54XX_RAC_VDD_MPU_L_MASK						(1 << 26)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_MM_OFF, PRM_VOLTSETUP_MM_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP54XX_RAMP_DOWN_COUNT_SHIFT						16
+#define OMAP54XX_RAMP_DOWN_COUNT_WIDTH						0x6
+#define OMAP54XX_RAMP_DOWN_COUNT_MASK						(0x3f << 16)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_MM_OFF, PRM_VOLTSETUP_MM_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP54XX_RAMP_DOWN_PRESCAL_SHIFT					24
+#define OMAP54XX_RAMP_DOWN_PRESCAL_WIDTH					0x2
+#define OMAP54XX_RAMP_DOWN_PRESCAL_MASK						(0x3 << 24)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_MM_OFF, PRM_VOLTSETUP_MM_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP54XX_RAMP_UP_COUNT_SHIFT						0
+#define OMAP54XX_RAMP_UP_COUNT_WIDTH						0x6
+#define OMAP54XX_RAMP_UP_COUNT_MASK						(0x3f << 0)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_MM_OFF, PRM_VOLTSETUP_MM_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP54XX_RAMP_UP_PRESCAL_SHIFT						8
+#define OMAP54XX_RAMP_UP_PRESCAL_WIDTH						0x2
+#define OMAP54XX_RAMP_UP_PRESCAL_MASK						(0x3 << 8)
+
+/* Used by PRM_VC_SMPS_CORE_CONFIG */
+#define OMAP54XX_RAV_VDD_CORE_L_SHIFT						25
+#define OMAP54XX_RAV_VDD_CORE_L_WIDTH						0x1
+#define OMAP54XX_RAV_VDD_CORE_L_MASK						(1 << 25)
+
+/* Used by PRM_VC_SMPS_MM_CONFIG */
+#define OMAP54XX_RAV_VDD_MM_L_SHIFT						25
+#define OMAP54XX_RAV_VDD_MM_L_WIDTH						0x1
+#define OMAP54XX_RAV_VDD_MM_L_MASK						(1 << 25)
+
+/* Used by PRM_VC_SMPS_MPU_CONFIG */
+#define OMAP54XX_RAV_VDD_MPU_L_SHIFT						25
+#define OMAP54XX_RAV_VDD_MPU_L_WIDTH						0x1
+#define OMAP54XX_RAV_VDD_MPU_L_MASK						(1 << 25)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP54XX_REGADDR_SHIFT							8
+#define OMAP54XX_REGADDR_WIDTH							0x8
+#define OMAP54XX_REGADDR_MASK							(0xff << 8)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_MM_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP54XX_RET_SHIFT							8
+#define OMAP54XX_RET_WIDTH							0x8
+#define OMAP54XX_RET_MASK							(0xff << 8)
+
+/* Used by PRM_SLDO_CORE_CTRL, PRM_SLDO_MM_CTRL, PRM_SLDO_MPU_CTRL */
+#define OMAP54XX_RETMODE_ENABLE_SHIFT						0
+#define OMAP54XX_RETMODE_ENABLE_WIDTH						0x1
+#define OMAP54XX_RETMODE_ENABLE_MASK						(1 << 0)
+
+/* Used by PRM_RSTTIME */
+#define OMAP54XX_RSTTIME1_SHIFT							0
+#define OMAP54XX_RSTTIME1_WIDTH							0xa
+#define OMAP54XX_RSTTIME1_MASK							(0x3ff << 0)
+
+/* Used by PRM_RSTTIME */
+#define OMAP54XX_RSTTIME2_SHIFT							10
+#define OMAP54XX_RSTTIME2_WIDTH							0x5
+#define OMAP54XX_RSTTIME2_MASK							(0x1f << 10)
+
+/* Used by RM_IPU_RSTCTRL, RM_IPU_RSTST */
+#define OMAP54XX_RST_CPU0_SHIFT							0
+#define OMAP54XX_RST_CPU0_WIDTH							0x1
+#define OMAP54XX_RST_CPU0_MASK							(1 << 0)
+
+/* Used by RM_IPU_RSTCTRL, RM_IPU_RSTST */
+#define OMAP54XX_RST_CPU1_SHIFT							1
+#define OMAP54XX_RST_CPU1_WIDTH							0x1
+#define OMAP54XX_RST_CPU1_MASK							(1 << 1)
+
+/* Used by RM_DSP_RSTCTRL, RM_DSP_RSTST */
+#define OMAP54XX_RST_DSP_SHIFT							0
+#define OMAP54XX_RST_DSP_WIDTH							0x1
+#define OMAP54XX_RST_DSP_MASK							(1 << 0)
+
+/* Used by RM_DSP_RSTST */
+#define OMAP54XX_RST_DSP_EMU_SHIFT						2
+#define OMAP54XX_RST_DSP_EMU_WIDTH						0x1
+#define OMAP54XX_RST_DSP_EMU_MASK						(1 << 2)
+
+/* Used by RM_DSP_RSTST */
+#define OMAP54XX_RST_DSP_EMU_REQ_SHIFT						3
+#define OMAP54XX_RST_DSP_EMU_REQ_WIDTH						0x1
+#define OMAP54XX_RST_DSP_EMU_REQ_MASK						(1 << 3)
+
+/* Used by RM_DSP_RSTCTRL, RM_DSP_RSTST */
+#define OMAP54XX_RST_DSP_MMU_CACHE_SHIFT					1
+#define OMAP54XX_RST_DSP_MMU_CACHE_WIDTH					0x1
+#define OMAP54XX_RST_DSP_MMU_CACHE_MASK						(1 << 1)
+
+/* Used by RM_IPU_RSTST */
+#define OMAP54XX_RST_EMULATION_CPU0_SHIFT					3
+#define OMAP54XX_RST_EMULATION_CPU0_WIDTH					0x1
+#define OMAP54XX_RST_EMULATION_CPU0_MASK					(1 << 3)
+
+/* Used by RM_IPU_RSTST */
+#define OMAP54XX_RST_EMULATION_CPU1_SHIFT					4
+#define OMAP54XX_RST_EMULATION_CPU1_WIDTH					0x1
+#define OMAP54XX_RST_EMULATION_CPU1_MASK					(1 << 4)
+
+/* Used by RM_IVA_RSTST */
+#define OMAP54XX_RST_EMULATION_SEQ1_SHIFT					3
+#define OMAP54XX_RST_EMULATION_SEQ1_WIDTH					0x1
+#define OMAP54XX_RST_EMULATION_SEQ1_MASK					(1 << 3)
+
+/* Used by RM_IVA_RSTST */
+#define OMAP54XX_RST_EMULATION_SEQ2_SHIFT					4
+#define OMAP54XX_RST_EMULATION_SEQ2_WIDTH					0x1
+#define OMAP54XX_RST_EMULATION_SEQ2_MASK					(1 << 4)
+
+/* Used by PRM_RSTCTRL */
+#define OMAP54XX_RST_GLOBAL_COLD_SW_SHIFT					1
+#define OMAP54XX_RST_GLOBAL_COLD_SW_WIDTH					0x1
+#define OMAP54XX_RST_GLOBAL_COLD_SW_MASK					(1 << 1)
+
+/* Used by PRM_RSTCTRL */
+#define OMAP54XX_RST_GLOBAL_WARM_SW_SHIFT					0
+#define OMAP54XX_RST_GLOBAL_WARM_SW_WIDTH					0x1
+#define OMAP54XX_RST_GLOBAL_WARM_SW_MASK					(1 << 0)
+
+/* Used by RM_IPU_RSTST */
+#define OMAP54XX_RST_ICECRUSHER_CPU0_SHIFT					5
+#define OMAP54XX_RST_ICECRUSHER_CPU0_WIDTH					0x1
+#define OMAP54XX_RST_ICECRUSHER_CPU0_MASK					(1 << 5)
+
+/* Used by RM_IPU_RSTST */
+#define OMAP54XX_RST_ICECRUSHER_CPU1_SHIFT					6
+#define OMAP54XX_RST_ICECRUSHER_CPU1_WIDTH					0x1
+#define OMAP54XX_RST_ICECRUSHER_CPU1_MASK					(1 << 6)
+
+/* Used by RM_IVA_RSTST */
+#define OMAP54XX_RST_ICECRUSHER_SEQ1_SHIFT					5
+#define OMAP54XX_RST_ICECRUSHER_SEQ1_WIDTH					0x1
+#define OMAP54XX_RST_ICECRUSHER_SEQ1_MASK					(1 << 5)
+
+/* Used by RM_IVA_RSTST */
+#define OMAP54XX_RST_ICECRUSHER_SEQ2_SHIFT					6
+#define OMAP54XX_RST_ICECRUSHER_SEQ2_WIDTH					0x1
+#define OMAP54XX_RST_ICECRUSHER_SEQ2_MASK					(1 << 6)
+
+/* Used by RM_IPU_RSTCTRL, RM_IPU_RSTST */
+#define OMAP54XX_RST_IPU_MMU_CACHE_SHIFT					2
+#define OMAP54XX_RST_IPU_MMU_CACHE_WIDTH					0x1
+#define OMAP54XX_RST_IPU_MMU_CACHE_MASK						(1 << 2)
+
+/* Used by RM_IVA_RSTCTRL, RM_IVA_RSTST */
+#define OMAP54XX_RST_LOGIC_SHIFT						2
+#define OMAP54XX_RST_LOGIC_WIDTH						0x1
+#define OMAP54XX_RST_LOGIC_MASK							(1 << 2)
+
+/* Used by RM_IVA_RSTCTRL, RM_IVA_RSTST */
+#define OMAP54XX_RST_SEQ1_SHIFT							0
+#define OMAP54XX_RST_SEQ1_WIDTH							0x1
+#define OMAP54XX_RST_SEQ1_MASK							(1 << 0)
+
+/* Used by RM_IVA_RSTCTRL, RM_IVA_RSTST */
+#define OMAP54XX_RST_SEQ2_SHIFT							1
+#define OMAP54XX_RST_SEQ2_WIDTH							0x1
+#define OMAP54XX_RST_SEQ2_MASK							(1 << 1)
+
+/* Used by REVISION_PRM */
+#define OMAP54XX_R_RTL_SHIFT							11
+#define OMAP54XX_R_RTL_WIDTH							0x5
+#define OMAP54XX_R_RTL_MASK							(0x1f << 11)
+
+/* Used by PRM_VC_SMPS_CORE_CONFIG */
+#define OMAP54XX_SA_VDD_CORE_L_SHIFT						0
+#define OMAP54XX_SA_VDD_CORE_L_WIDTH						0x7
+#define OMAP54XX_SA_VDD_CORE_L_MASK						(0x7f << 0)
+
+/* Used by PRM_VC_SMPS_MM_CONFIG */
+#define OMAP54XX_SA_VDD_MM_L_SHIFT						0
+#define OMAP54XX_SA_VDD_MM_L_WIDTH						0x7
+#define OMAP54XX_SA_VDD_MM_L_MASK						(0x7f << 0)
+
+/* Used by PRM_VC_SMPS_MPU_CONFIG */
+#define OMAP54XX_SA_VDD_MPU_L_SHIFT						0
+#define OMAP54XX_SA_VDD_MPU_L_WIDTH						0x7
+#define OMAP54XX_SA_VDD_MPU_L_MASK						(0x7f << 0)
+
+/* Used by REVISION_PRM */
+#define OMAP54XX_SCHEME_SHIFT							30
+#define OMAP54XX_SCHEME_WIDTH							0x2
+#define OMAP54XX_SCHEME_MASK							(0x3 << 30)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP54XX_SCLH_SHIFT							0
+#define OMAP54XX_SCLH_WIDTH							0x8
+#define OMAP54XX_SCLH_MASK							(0xff << 0)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP54XX_SCLL_SHIFT							8
+#define OMAP54XX_SCLL_WIDTH							0x8
+#define OMAP54XX_SCLL_MASK							(0xff << 8)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_SECURE_WDT_RST_SHIFT						4
+#define OMAP54XX_SECURE_WDT_RST_WIDTH						0x1
+#define OMAP54XX_SECURE_WDT_RST_MASK						(1 << 4)
+
+/* Used by PRM_VC_SMPS_CORE_CONFIG */
+#define OMAP54XX_SEL_SA_VDD_CORE_L_SHIFT					24
+#define OMAP54XX_SEL_SA_VDD_CORE_L_WIDTH					0x1
+#define OMAP54XX_SEL_SA_VDD_CORE_L_MASK						(1 << 24)
+
+/* Used by PRM_VC_SMPS_MM_CONFIG */
+#define OMAP54XX_SEL_SA_VDD_MM_L_SHIFT						24
+#define OMAP54XX_SEL_SA_VDD_MM_L_WIDTH						0x1
+#define OMAP54XX_SEL_SA_VDD_MM_L_MASK						(1 << 24)
+
+/* Used by PRM_VC_SMPS_MPU_CONFIG */
+#define OMAP54XX_SEL_SA_VDD_MPU_L_SHIFT						24
+#define OMAP54XX_SEL_SA_VDD_MPU_L_WIDTH						0x1
+#define OMAP54XX_SEL_SA_VDD_MPU_L_MASK						(1 << 24)
+
+/* Used by PM_IVA_PWRSTCTRL */
+#define OMAP54XX_SL2_MEM_ONSTATE_SHIFT						18
+#define OMAP54XX_SL2_MEM_ONSTATE_WIDTH						0x2
+#define OMAP54XX_SL2_MEM_ONSTATE_MASK						(0x3 << 18)
+
+/* Used by PM_IVA_PWRSTCTRL */
+#define OMAP54XX_SL2_MEM_RETSTATE_SHIFT						9
+#define OMAP54XX_SL2_MEM_RETSTATE_WIDTH						0x1
+#define OMAP54XX_SL2_MEM_RETSTATE_MASK						(1 << 9)
+
+/* Used by PM_IVA_PWRSTST */
+#define OMAP54XX_SL2_MEM_STATEST_SHIFT						6
+#define OMAP54XX_SL2_MEM_STATEST_WIDTH						0x2
+#define OMAP54XX_SL2_MEM_STATEST_MASK						(0x3 << 6)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP54XX_SLAVEADDR_SHIFT						0
+#define OMAP54XX_SLAVEADDR_WIDTH						0x7
+#define OMAP54XX_SLAVEADDR_MASK							(0x7f << 0)
+
+/* Used by PRM_SRAM_COUNT */
+#define OMAP54XX_SLPCNT_VALUE_SHIFT						16
+#define OMAP54XX_SLPCNT_VALUE_WIDTH						0x8
+#define OMAP54XX_SLPCNT_VALUE_MASK						(0xff << 16)
+
+/* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_MM_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
+#define OMAP54XX_SMPSWAITTIMEMAX_SHIFT						8
+#define OMAP54XX_SMPSWAITTIMEMAX_WIDTH						0x10
+#define OMAP54XX_SMPSWAITTIMEMAX_MASK						(0xffff << 8)
+
+/* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_MM_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
+#define OMAP54XX_SMPSWAITTIMEMIN_SHIFT						8
+#define OMAP54XX_SMPSWAITTIMEMIN_WIDTH						0x10
+#define OMAP54XX_SMPSWAITTIMEMIN_MASK						(0xffff << 8)
+
+/* Used by PRM_VC_CORE_ERRST */
+#define OMAP54XX_SMPS_RA_ERR_CORE_SHIFT						1
+#define OMAP54XX_SMPS_RA_ERR_CORE_WIDTH						0x1
+#define OMAP54XX_SMPS_RA_ERR_CORE_MASK						(1 << 1)
+
+/* Used by PRM_VC_MM_ERRST */
+#define OMAP54XX_SMPS_RA_ERR_MM_SHIFT						1
+#define OMAP54XX_SMPS_RA_ERR_MM_WIDTH						0x1
+#define OMAP54XX_SMPS_RA_ERR_MM_MASK						(1 << 1)
+
+/* Used by PRM_VC_MPU_ERRST */
+#define OMAP54XX_SMPS_RA_ERR_MPU_SHIFT						1
+#define OMAP54XX_SMPS_RA_ERR_MPU_WIDTH						0x1
+#define OMAP54XX_SMPS_RA_ERR_MPU_MASK						(1 << 1)
+
+/* Used by PRM_VC_CORE_ERRST */
+#define OMAP54XX_SMPS_SA_ERR_CORE_SHIFT						0
+#define OMAP54XX_SMPS_SA_ERR_CORE_WIDTH						0x1
+#define OMAP54XX_SMPS_SA_ERR_CORE_MASK						(1 << 0)
+
+/* Used by PRM_VC_MM_ERRST */
+#define OMAP54XX_SMPS_SA_ERR_MM_SHIFT						0
+#define OMAP54XX_SMPS_SA_ERR_MM_WIDTH						0x1
+#define OMAP54XX_SMPS_SA_ERR_MM_MASK						(1 << 0)
+
+/* Used by PRM_VC_MPU_ERRST */
+#define OMAP54XX_SMPS_SA_ERR_MPU_SHIFT						0
+#define OMAP54XX_SMPS_SA_ERR_MPU_WIDTH						0x1
+#define OMAP54XX_SMPS_SA_ERR_MPU_MASK						(1 << 0)
+
+/* Used by PRM_VC_CORE_ERRST */
+#define OMAP54XX_SMPS_TIMEOUT_ERR_CORE_SHIFT					2
+#define OMAP54XX_SMPS_TIMEOUT_ERR_CORE_WIDTH					0x1
+#define OMAP54XX_SMPS_TIMEOUT_ERR_CORE_MASK					(1 << 2)
+
+/* Used by PRM_VC_MM_ERRST */
+#define OMAP54XX_SMPS_TIMEOUT_ERR_MM_SHIFT					2
+#define OMAP54XX_SMPS_TIMEOUT_ERR_MM_WIDTH					0x1
+#define OMAP54XX_SMPS_TIMEOUT_ERR_MM_MASK					(1 << 2)
+
+/* Used by PRM_VC_MPU_ERRST */
+#define OMAP54XX_SMPS_TIMEOUT_ERR_MPU_SHIFT					2
+#define OMAP54XX_SMPS_TIMEOUT_ERR_MPU_WIDTH					0x1
+#define OMAP54XX_SMPS_TIMEOUT_ERR_MPU_MASK					(1 << 2)
+
+/* Used by PRM_ABBLDO_MM_SETUP, PRM_ABBLDO_MPU_SETUP */
+#define OMAP54XX_SR2EN_SHIFT							0
+#define OMAP54XX_SR2EN_WIDTH							0x1
+#define OMAP54XX_SR2EN_MASK							(1 << 0)
+
+/* Used by PRM_ABBLDO_MM_CTRL, PRM_ABBLDO_MPU_CTRL */
+#define OMAP54XX_SR2_IN_TRANSITION_SHIFT					6
+#define OMAP54XX_SR2_IN_TRANSITION_WIDTH					0x1
+#define OMAP54XX_SR2_IN_TRANSITION_MASK						(1 << 6)
+
+/* Used by PRM_ABBLDO_MM_CTRL, PRM_ABBLDO_MPU_CTRL */
+#define OMAP54XX_SR2_STATUS_SHIFT						3
+#define OMAP54XX_SR2_STATUS_WIDTH						0x2
+#define OMAP54XX_SR2_STATUS_MASK						(0x3 << 3)
+
+/* Used by PRM_ABBLDO_MM_SETUP, PRM_ABBLDO_MPU_SETUP */
+#define OMAP54XX_SR2_WTCNT_VALUE_SHIFT						8
+#define OMAP54XX_SR2_WTCNT_VALUE_WIDTH						0x8
+#define OMAP54XX_SR2_WTCNT_VALUE_MASK						(0xff << 8)
+
+/* Used by PRM_SLDO_CORE_CTRL, PRM_SLDO_MM_CTRL, PRM_SLDO_MPU_CTRL */
+#define OMAP54XX_SRAMLDO_STATUS_SHIFT						8
+#define OMAP54XX_SRAMLDO_STATUS_WIDTH						0x1
+#define OMAP54XX_SRAMLDO_STATUS_MASK						(1 << 8)
+
+/* Used by PRM_SLDO_CORE_CTRL, PRM_SLDO_MM_CTRL, PRM_SLDO_MPU_CTRL */
+#define OMAP54XX_SRAM_IN_TRANSITION_SHIFT					9
+#define OMAP54XX_SRAM_IN_TRANSITION_WIDTH					0x1
+#define OMAP54XX_SRAM_IN_TRANSITION_MASK					(1 << 9)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP54XX_SRMODEEN_SHIFT							4
+#define OMAP54XX_SRMODEEN_WIDTH							0x1
+#define OMAP54XX_SRMODEEN_MASK							(1 << 4)
+
+/* Used by PRM_VOLTSETUP_WARMRESET */
+#define OMAP54XX_STABLE_COUNT_SHIFT						0
+#define OMAP54XX_STABLE_COUNT_WIDTH						0x6
+#define OMAP54XX_STABLE_COUNT_MASK						(0x3f << 0)
+
+/* Used by PRM_VOLTSETUP_WARMRESET */
+#define OMAP54XX_STABLE_PRESCAL_SHIFT						8
+#define OMAP54XX_STABLE_PRESCAL_WIDTH						0x2
+#define OMAP54XX_STABLE_PRESCAL_MASK						(0x3 << 8)
+
+/* Used by PRM_BANDGAP_SETUP */
+#define OMAP54XX_STARTUP_COUNT_SHIFT						0
+#define OMAP54XX_STARTUP_COUNT_WIDTH						0x8
+#define OMAP54XX_STARTUP_COUNT_MASK						(0xff << 0)
+
+/* Renamed from STARTUP_COUNT Used by PRM_SRAM_COUNT */
+#define OMAP54XX_STARTUP_COUNT_24_31_SHIFT					24
+#define OMAP54XX_STARTUP_COUNT_24_31_WIDTH					0x8
+#define OMAP54XX_STARTUP_COUNT_24_31_MASK					(0xff << 24)
+
+/* Used by PM_IVA_PWRSTCTRL */
+#define OMAP54XX_TCM1_MEM_ONSTATE_SHIFT						20
+#define OMAP54XX_TCM1_MEM_ONSTATE_WIDTH						0x2
+#define OMAP54XX_TCM1_MEM_ONSTATE_MASK						(0x3 << 20)
+
+/* Used by PM_IVA_PWRSTCTRL */
+#define OMAP54XX_TCM1_MEM_RETSTATE_SHIFT					10
+#define OMAP54XX_TCM1_MEM_RETSTATE_WIDTH					0x1
+#define OMAP54XX_TCM1_MEM_RETSTATE_MASK						(1 << 10)
+
+/* Used by PM_IVA_PWRSTST */
+#define OMAP54XX_TCM1_MEM_STATEST_SHIFT						8
+#define OMAP54XX_TCM1_MEM_STATEST_WIDTH						0x2
+#define OMAP54XX_TCM1_MEM_STATEST_MASK						(0x3 << 8)
+
+/* Used by PM_IVA_PWRSTCTRL */
+#define OMAP54XX_TCM2_MEM_ONSTATE_SHIFT						22
+#define OMAP54XX_TCM2_MEM_ONSTATE_WIDTH						0x2
+#define OMAP54XX_TCM2_MEM_ONSTATE_MASK						(0x3 << 22)
+
+/* Used by PM_IVA_PWRSTCTRL */
+#define OMAP54XX_TCM2_MEM_RETSTATE_SHIFT					11
+#define OMAP54XX_TCM2_MEM_RETSTATE_WIDTH					0x1
+#define OMAP54XX_TCM2_MEM_RETSTATE_MASK						(1 << 11)
+
+/* Used by PM_IVA_PWRSTST */
+#define OMAP54XX_TCM2_MEM_STATEST_SHIFT						10
+#define OMAP54XX_TCM2_MEM_STATEST_WIDTH						0x2
+#define OMAP54XX_TCM2_MEM_STATEST_MASK						(0x3 << 10)
+
+/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_MM_VLIMITTO, PRM_VP_MPU_VLIMITTO */
+#define OMAP54XX_TIMEOUT_SHIFT							0
+#define OMAP54XX_TIMEOUT_WIDTH							0x10
+#define OMAP54XX_TIMEOUT_MASK							(0xffff << 0)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_MM_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP54XX_TIMEOUTEN_SHIFT						3
+#define OMAP54XX_TIMEOUTEN_WIDTH						0x1
+#define OMAP54XX_TIMEOUTEN_MASK							(1 << 3)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_TRANSITION_EN_SHIFT						8
+#define OMAP54XX_TRANSITION_EN_WIDTH						0x1
+#define OMAP54XX_TRANSITION_EN_MASK						(1 << 8)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_TRANSITION_ST_SHIFT						8
+#define OMAP54XX_TRANSITION_ST_WIDTH						0x1
+#define OMAP54XX_TRANSITION_ST_MASK						(1 << 8)
+
+/* Used by PRM_DEBUG_TRANS_CFG */
+#define OMAP54XX_TRIGGER_CLEAR_SHIFT						2
+#define OMAP54XX_TRIGGER_CLEAR_WIDTH						0x1
+#define OMAP54XX_TRIGGER_CLEAR_MASK						(1 << 2)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_TSHUT_CORE_RST_SHIFT						13
+#define OMAP54XX_TSHUT_CORE_RST_WIDTH						0x1
+#define OMAP54XX_TSHUT_CORE_RST_MASK						(1 << 13)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_TSHUT_MM_RST_SHIFT						12
+#define OMAP54XX_TSHUT_MM_RST_WIDTH						0x1
+#define OMAP54XX_TSHUT_MM_RST_MASK						(1 << 12)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_TSHUT_MPU_RST_SHIFT						11
+#define OMAP54XX_TSHUT_MPU_RST_WIDTH						0x1
+#define OMAP54XX_TSHUT_MPU_RST_MASK						(1 << 11)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP54XX_VALID_SHIFT							24
+#define OMAP54XX_VALID_WIDTH							0x1
+#define OMAP54XX_VALID_MASK							(1 << 24)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VC_BYPASSACK_EN_SHIFT						14
+#define OMAP54XX_VC_BYPASSACK_EN_WIDTH						0x1
+#define OMAP54XX_VC_BYPASSACK_EN_MASK						(1 << 14)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VC_BYPASSACK_ST_SHIFT						14
+#define OMAP54XX_VC_BYPASSACK_ST_WIDTH						0x1
+#define OMAP54XX_VC_BYPASSACK_ST_MASK						(1 << 14)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VC_CORE_VPACK_EN_SHIFT						22
+#define OMAP54XX_VC_CORE_VPACK_EN_WIDTH						0x1
+#define OMAP54XX_VC_CORE_VPACK_EN_MASK						(1 << 22)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VC_CORE_VPACK_ST_SHIFT						22
+#define OMAP54XX_VC_CORE_VPACK_ST_WIDTH						0x1
+#define OMAP54XX_VC_CORE_VPACK_ST_MASK						(1 << 22)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VC_MM_VPACK_EN_SHIFT						30
+#define OMAP54XX_VC_MM_VPACK_EN_WIDTH						0x1
+#define OMAP54XX_VC_MM_VPACK_EN_MASK						(1 << 30)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VC_MM_VPACK_ST_SHIFT						30
+#define OMAP54XX_VC_MM_VPACK_ST_WIDTH						0x1
+#define OMAP54XX_VC_MM_VPACK_ST_MASK						(1 << 30)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP54XX_VC_MPU_VPACK_EN_SHIFT						6
+#define OMAP54XX_VC_MPU_VPACK_EN_WIDTH						0x1
+#define OMAP54XX_VC_MPU_VPACK_EN_MASK						(1 << 6)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP54XX_VC_MPU_VPACK_ST_SHIFT						6
+#define OMAP54XX_VC_MPU_VPACK_ST_WIDTH						0x1
+#define OMAP54XX_VC_MPU_VPACK_ST_MASK						(1 << 6)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VC_RAERR_EN_SHIFT						12
+#define OMAP54XX_VC_RAERR_EN_WIDTH						0x1
+#define OMAP54XX_VC_RAERR_EN_MASK						(1 << 12)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VC_RAERR_ST_SHIFT						12
+#define OMAP54XX_VC_RAERR_ST_WIDTH						0x1
+#define OMAP54XX_VC_RAERR_ST_MASK						(1 << 12)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VC_SAERR_EN_SHIFT						11
+#define OMAP54XX_VC_SAERR_EN_WIDTH						0x1
+#define OMAP54XX_VC_SAERR_EN_MASK						(1 << 11)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VC_SAERR_ST_SHIFT						11
+#define OMAP54XX_VC_SAERR_ST_WIDTH						0x1
+#define OMAP54XX_VC_SAERR_ST_MASK						(1 << 11)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VC_TOERR_EN_SHIFT						13
+#define OMAP54XX_VC_TOERR_EN_WIDTH						0x1
+#define OMAP54XX_VC_TOERR_EN_MASK						(1 << 13)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VC_TOERR_ST_SHIFT						13
+#define OMAP54XX_VC_TOERR_ST_WIDTH						0x1
+#define OMAP54XX_VC_TOERR_ST_MASK						(1 << 13)
+
+/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_MM_VLIMITTO, PRM_VP_MPU_VLIMITTO */
+#define OMAP54XX_VDDMAX_SHIFT							24
+#define OMAP54XX_VDDMAX_WIDTH							0x8
+#define OMAP54XX_VDDMAX_MASK							(0xff << 24)
+
+/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_MM_VLIMITTO, PRM_VP_MPU_VLIMITTO */
+#define OMAP54XX_VDDMIN_SHIFT							16
+#define OMAP54XX_VDDMIN_WIDTH							0x8
+#define OMAP54XX_VDDMIN_MASK							(0xff << 16)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP54XX_VDD_CORE_I2C_DISABLE_SHIFT					12
+#define OMAP54XX_VDD_CORE_I2C_DISABLE_WIDTH					0x1
+#define OMAP54XX_VDD_CORE_I2C_DISABLE_MASK					(1 << 12)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_VDD_CORE_VOLT_MGR_RST_SHIFT					8
+#define OMAP54XX_VDD_CORE_VOLT_MGR_RST_WIDTH					0x1
+#define OMAP54XX_VDD_CORE_VOLT_MGR_RST_MASK					(1 << 8)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP54XX_VDD_MM_I2C_DISABLE_SHIFT					14
+#define OMAP54XX_VDD_MM_I2C_DISABLE_WIDTH					0x1
+#define OMAP54XX_VDD_MM_I2C_DISABLE_MASK					(1 << 14)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP54XX_VDD_MM_PRESENCE_SHIFT						9
+#define OMAP54XX_VDD_MM_PRESENCE_WIDTH						0x1
+#define OMAP54XX_VDD_MM_PRESENCE_MASK						(1 << 9)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_VDD_MM_VOLT_MGR_RST_SHIFT					7
+#define OMAP54XX_VDD_MM_VOLT_MGR_RST_WIDTH					0x1
+#define OMAP54XX_VDD_MM_VOLT_MGR_RST_MASK					(1 << 7)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP54XX_VDD_MPU_I2C_DISABLE_SHIFT					13
+#define OMAP54XX_VDD_MPU_I2C_DISABLE_WIDTH					0x1
+#define OMAP54XX_VDD_MPU_I2C_DISABLE_MASK					(1 << 13)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP54XX_VDD_MPU_PRESENCE_SHIFT						8
+#define OMAP54XX_VDD_MPU_PRESENCE_WIDTH						0x1
+#define OMAP54XX_VDD_MPU_PRESENCE_MASK						(1 << 8)
+
+/* Used by PRM_RSTST */
+#define OMAP54XX_VDD_MPU_VOLT_MGR_RST_SHIFT					6
+#define OMAP54XX_VDD_MPU_VOLT_MGR_RST_WIDTH					0x1
+#define OMAP54XX_VDD_MPU_VOLT_MGR_RST_MASK					(1 << 6)
+
+/* Used by PRM_VC_CORE_ERRST */
+#define OMAP54XX_VFSM_RA_ERR_CORE_SHIFT						4
+#define OMAP54XX_VFSM_RA_ERR_CORE_WIDTH						0x1
+#define OMAP54XX_VFSM_RA_ERR_CORE_MASK						(1 << 4)
+
+/* Used by PRM_VC_MM_ERRST */
+#define OMAP54XX_VFSM_RA_ERR_MM_SHIFT						4
+#define OMAP54XX_VFSM_RA_ERR_MM_WIDTH						0x1
+#define OMAP54XX_VFSM_RA_ERR_MM_MASK						(1 << 4)
+
+/* Used by PRM_VC_MPU_ERRST */
+#define OMAP54XX_VFSM_RA_ERR_MPU_SHIFT						4
+#define OMAP54XX_VFSM_RA_ERR_MPU_WIDTH						0x1
+#define OMAP54XX_VFSM_RA_ERR_MPU_MASK						(1 << 4)
+
+/* Used by PRM_VC_CORE_ERRST */
+#define OMAP54XX_VFSM_SA_ERR_CORE_SHIFT						3
+#define OMAP54XX_VFSM_SA_ERR_CORE_WIDTH						0x1
+#define OMAP54XX_VFSM_SA_ERR_CORE_MASK						(1 << 3)
+
+/* Used by PRM_VC_MM_ERRST */
+#define OMAP54XX_VFSM_SA_ERR_MM_SHIFT						3
+#define OMAP54XX_VFSM_SA_ERR_MM_WIDTH						0x1
+#define OMAP54XX_VFSM_SA_ERR_MM_MASK						(1 << 3)
+
+/* Used by PRM_VC_MPU_ERRST */
+#define OMAP54XX_VFSM_SA_ERR_MPU_SHIFT						3
+#define OMAP54XX_VFSM_SA_ERR_MPU_WIDTH						0x1
+#define OMAP54XX_VFSM_SA_ERR_MPU_MASK						(1 << 3)
+
+/* Used by PRM_VC_CORE_ERRST */
+#define OMAP54XX_VFSM_TIMEOUT_ERR_CORE_SHIFT					5
+#define OMAP54XX_VFSM_TIMEOUT_ERR_CORE_WIDTH					0x1
+#define OMAP54XX_VFSM_TIMEOUT_ERR_CORE_MASK					(1 << 5)
+
+/* Used by PRM_VC_MM_ERRST */
+#define OMAP54XX_VFSM_TIMEOUT_ERR_MM_SHIFT					5
+#define OMAP54XX_VFSM_TIMEOUT_ERR_MM_WIDTH					0x1
+#define OMAP54XX_VFSM_TIMEOUT_ERR_MM_MASK					(1 << 5)
+
+/* Used by PRM_VC_MPU_ERRST */
+#define OMAP54XX_VFSM_TIMEOUT_ERR_MPU_SHIFT					5
+#define OMAP54XX_VFSM_TIMEOUT_ERR_MPU_WIDTH					0x1
+#define OMAP54XX_VFSM_TIMEOUT_ERR_MPU_MASK					(1 << 5)
+
+/* Used by PRM_VC_SMPS_CORE_CONFIG */
+#define OMAP54XX_VOLRA_VDD_CORE_L_SHIFT						8
+#define OMAP54XX_VOLRA_VDD_CORE_L_WIDTH						0x8
+#define OMAP54XX_VOLRA_VDD_CORE_L_MASK						(0xff << 8)
+
+/* Used by PRM_VC_SMPS_MM_CONFIG */
+#define OMAP54XX_VOLRA_VDD_MM_L_SHIFT						8
+#define OMAP54XX_VOLRA_VDD_MM_L_WIDTH						0x8
+#define OMAP54XX_VOLRA_VDD_MM_L_MASK						(0xff << 8)
+
+/* Used by PRM_VC_SMPS_MPU_CONFIG */
+#define OMAP54XX_VOLRA_VDD_MPU_L_SHIFT						8
+#define OMAP54XX_VOLRA_VDD_MPU_L_WIDTH						0x8
+#define OMAP54XX_VOLRA_VDD_MPU_L_MASK						(0xff << 8)
+
+/* Used by PRM_VOLTST_MM, PRM_VOLTST_MPU */
+#define OMAP54XX_VOLTSTATEST_SHIFT						0
+#define OMAP54XX_VOLTSTATEST_WIDTH						0x2
+#define OMAP54XX_VOLTSTATEST_MASK						(0x3 << 0)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_MM_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP54XX_VPENABLE_SHIFT							0
+#define OMAP54XX_VPENABLE_WIDTH							0x1
+#define OMAP54XX_VPENABLE_MASK							(1 << 0)
+
+/* Used by PRM_VP_CORE_STATUS, PRM_VP_MM_STATUS, PRM_VP_MPU_STATUS */
+#define OMAP54XX_VPINIDLE_SHIFT							0
+#define OMAP54XX_VPINIDLE_WIDTH							0x1
+#define OMAP54XX_VPINIDLE_MASK							(1 << 0)
+
+/* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_MM_VOLTAGE, PRM_VP_MPU_VOLTAGE */
+#define OMAP54XX_VPVOLTAGE_SHIFT						0
+#define OMAP54XX_VPVOLTAGE_WIDTH						0x8
+#define OMAP54XX_VPVOLTAGE_MASK							(0xff << 0)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_CORE_EQVALUE_EN_SHIFT					20
+#define OMAP54XX_VP_CORE_EQVALUE_EN_WIDTH					0x1
+#define OMAP54XX_VP_CORE_EQVALUE_EN_MASK					(1 << 20)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_CORE_EQVALUE_ST_SHIFT					20
+#define OMAP54XX_VP_CORE_EQVALUE_ST_WIDTH					0x1
+#define OMAP54XX_VP_CORE_EQVALUE_ST_MASK					(1 << 20)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_CORE_MAXVDD_EN_SHIFT					18
+#define OMAP54XX_VP_CORE_MAXVDD_EN_WIDTH					0x1
+#define OMAP54XX_VP_CORE_MAXVDD_EN_MASK						(1 << 18)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_CORE_MAXVDD_ST_SHIFT					18
+#define OMAP54XX_VP_CORE_MAXVDD_ST_WIDTH					0x1
+#define OMAP54XX_VP_CORE_MAXVDD_ST_MASK						(1 << 18)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_CORE_MINVDD_EN_SHIFT					17
+#define OMAP54XX_VP_CORE_MINVDD_EN_WIDTH					0x1
+#define OMAP54XX_VP_CORE_MINVDD_EN_MASK						(1 << 17)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_CORE_MINVDD_ST_SHIFT					17
+#define OMAP54XX_VP_CORE_MINVDD_ST_WIDTH					0x1
+#define OMAP54XX_VP_CORE_MINVDD_ST_MASK						(1 << 17)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_CORE_NOSMPSACK_EN_SHIFT					19
+#define OMAP54XX_VP_CORE_NOSMPSACK_EN_WIDTH					0x1
+#define OMAP54XX_VP_CORE_NOSMPSACK_EN_MASK					(1 << 19)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_CORE_NOSMPSACK_ST_SHIFT					19
+#define OMAP54XX_VP_CORE_NOSMPSACK_ST_WIDTH					0x1
+#define OMAP54XX_VP_CORE_NOSMPSACK_ST_MASK					(1 << 19)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_CORE_OPPCHANGEDONE_EN_SHIFT					16
+#define OMAP54XX_VP_CORE_OPPCHANGEDONE_EN_WIDTH					0x1
+#define OMAP54XX_VP_CORE_OPPCHANGEDONE_EN_MASK					(1 << 16)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_CORE_OPPCHANGEDONE_ST_SHIFT					16
+#define OMAP54XX_VP_CORE_OPPCHANGEDONE_ST_WIDTH					0x1
+#define OMAP54XX_VP_CORE_OPPCHANGEDONE_ST_MASK					(1 << 16)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_CORE_TRANXDONE_EN_SHIFT					21
+#define OMAP54XX_VP_CORE_TRANXDONE_EN_WIDTH					0x1
+#define OMAP54XX_VP_CORE_TRANXDONE_EN_MASK					(1 << 21)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_CORE_TRANXDONE_ST_SHIFT					21
+#define OMAP54XX_VP_CORE_TRANXDONE_ST_WIDTH					0x1
+#define OMAP54XX_VP_CORE_TRANXDONE_ST_MASK					(1 << 21)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_MM_EQVALUE_EN_SHIFT						28
+#define OMAP54XX_VP_MM_EQVALUE_EN_WIDTH						0x1
+#define OMAP54XX_VP_MM_EQVALUE_EN_MASK						(1 << 28)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_MM_EQVALUE_ST_SHIFT						28
+#define OMAP54XX_VP_MM_EQVALUE_ST_WIDTH						0x1
+#define OMAP54XX_VP_MM_EQVALUE_ST_MASK						(1 << 28)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_MM_MAXVDD_EN_SHIFT						26
+#define OMAP54XX_VP_MM_MAXVDD_EN_WIDTH						0x1
+#define OMAP54XX_VP_MM_MAXVDD_EN_MASK						(1 << 26)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_MM_MAXVDD_ST_SHIFT						26
+#define OMAP54XX_VP_MM_MAXVDD_ST_WIDTH						0x1
+#define OMAP54XX_VP_MM_MAXVDD_ST_MASK						(1 << 26)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_MM_MINVDD_EN_SHIFT						25
+#define OMAP54XX_VP_MM_MINVDD_EN_WIDTH						0x1
+#define OMAP54XX_VP_MM_MINVDD_EN_MASK						(1 << 25)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_MM_MINVDD_ST_SHIFT						25
+#define OMAP54XX_VP_MM_MINVDD_ST_WIDTH						0x1
+#define OMAP54XX_VP_MM_MINVDD_ST_MASK						(1 << 25)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_MM_NOSMPSACK_EN_SHIFT					27
+#define OMAP54XX_VP_MM_NOSMPSACK_EN_WIDTH					0x1
+#define OMAP54XX_VP_MM_NOSMPSACK_EN_MASK					(1 << 27)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_MM_NOSMPSACK_ST_SHIFT					27
+#define OMAP54XX_VP_MM_NOSMPSACK_ST_WIDTH					0x1
+#define OMAP54XX_VP_MM_NOSMPSACK_ST_MASK					(1 << 27)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_MM_OPPCHANGEDONE_EN_SHIFT					24
+#define OMAP54XX_VP_MM_OPPCHANGEDONE_EN_WIDTH					0x1
+#define OMAP54XX_VP_MM_OPPCHANGEDONE_EN_MASK					(1 << 24)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_MM_OPPCHANGEDONE_ST_SHIFT					24
+#define OMAP54XX_VP_MM_OPPCHANGEDONE_ST_WIDTH					0x1
+#define OMAP54XX_VP_MM_OPPCHANGEDONE_ST_MASK					(1 << 24)
+
+/* Used by PRM_IRQENABLE_IPU, PRM_IRQENABLE_MPU */
+#define OMAP54XX_VP_MM_TRANXDONE_EN_SHIFT					29
+#define OMAP54XX_VP_MM_TRANXDONE_EN_WIDTH					0x1
+#define OMAP54XX_VP_MM_TRANXDONE_EN_MASK					(1 << 29)
+
+/* Used by PRM_IRQSTATUS_IPU, PRM_IRQSTATUS_MPU */
+#define OMAP54XX_VP_MM_TRANXDONE_ST_SHIFT					29
+#define OMAP54XX_VP_MM_TRANXDONE_ST_WIDTH					0x1
+#define OMAP54XX_VP_MM_TRANXDONE_ST_MASK					(1 << 29)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP54XX_VP_MPU_EQVALUE_EN_SHIFT					4
+#define OMAP54XX_VP_MPU_EQVALUE_EN_WIDTH					0x1
+#define OMAP54XX_VP_MPU_EQVALUE_EN_MASK						(1 << 4)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP54XX_VP_MPU_EQVALUE_ST_SHIFT					4
+#define OMAP54XX_VP_MPU_EQVALUE_ST_WIDTH					0x1
+#define OMAP54XX_VP_MPU_EQVALUE_ST_MASK						(1 << 4)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP54XX_VP_MPU_MAXVDD_EN_SHIFT						2
+#define OMAP54XX_VP_MPU_MAXVDD_EN_WIDTH						0x1
+#define OMAP54XX_VP_MPU_MAXVDD_EN_MASK						(1 << 2)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP54XX_VP_MPU_MAXVDD_ST_SHIFT						2
+#define OMAP54XX_VP_MPU_MAXVDD_ST_WIDTH						0x1
+#define OMAP54XX_VP_MPU_MAXVDD_ST_MASK						(1 << 2)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP54XX_VP_MPU_MINVDD_EN_SHIFT						1
+#define OMAP54XX_VP_MPU_MINVDD_EN_WIDTH						0x1
+#define OMAP54XX_VP_MPU_MINVDD_EN_MASK						(1 << 1)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP54XX_VP_MPU_MINVDD_ST_SHIFT						1
+#define OMAP54XX_VP_MPU_MINVDD_ST_WIDTH						0x1
+#define OMAP54XX_VP_MPU_MINVDD_ST_MASK						(1 << 1)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP54XX_VP_MPU_NOSMPSACK_EN_SHIFT					3
+#define OMAP54XX_VP_MPU_NOSMPSACK_EN_WIDTH					0x1
+#define OMAP54XX_VP_MPU_NOSMPSACK_EN_MASK					(1 << 3)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP54XX_VP_MPU_NOSMPSACK_ST_SHIFT					3
+#define OMAP54XX_VP_MPU_NOSMPSACK_ST_WIDTH					0x1
+#define OMAP54XX_VP_MPU_NOSMPSACK_ST_MASK					(1 << 3)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP54XX_VP_MPU_OPPCHANGEDONE_EN_SHIFT					0
+#define OMAP54XX_VP_MPU_OPPCHANGEDONE_EN_WIDTH					0x1
+#define OMAP54XX_VP_MPU_OPPCHANGEDONE_EN_MASK					(1 << 0)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP54XX_VP_MPU_OPPCHANGEDONE_ST_SHIFT					0
+#define OMAP54XX_VP_MPU_OPPCHANGEDONE_ST_WIDTH					0x1
+#define OMAP54XX_VP_MPU_OPPCHANGEDONE_ST_MASK					(1 << 0)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP54XX_VP_MPU_TRANXDONE_EN_SHIFT					5
+#define OMAP54XX_VP_MPU_TRANXDONE_EN_WIDTH					0x1
+#define OMAP54XX_VP_MPU_TRANXDONE_EN_MASK					(1 << 5)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP54XX_VP_MPU_TRANXDONE_ST_SHIFT					5
+#define OMAP54XX_VP_MPU_TRANXDONE_ST_WIDTH					0x1
+#define OMAP54XX_VP_MPU_TRANXDONE_ST_MASK					(1 << 5)
+
+/* Used by PRM_SRAM_COUNT */
+#define OMAP54XX_VSETUPCNT_VALUE_SHIFT						8
+#define OMAP54XX_VSETUPCNT_VALUE_WIDTH						0x8
+#define OMAP54XX_VSETUPCNT_VALUE_MASK						(0xff << 8)
+
+/* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_MM_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
+#define OMAP54XX_VSTEPMAX_SHIFT							0
+#define OMAP54XX_VSTEPMAX_WIDTH							0x8
+#define OMAP54XX_VSTEPMAX_MASK							(0xff << 0)
+
+/* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_MM_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
+#define OMAP54XX_VSTEPMIN_SHIFT							0
+#define OMAP54XX_VSTEPMIN_WIDTH							0x8
+#define OMAP54XX_VSTEPMIN_MASK							(0xff << 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DISPC_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_DISPC_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DISPC_DSP_MASK						(1 << 2)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DISPC_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_DISPC_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DISPC_IPU_MASK						(1 << 1)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DISPC_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_DISPC_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DISPC_MPU_MASK						(1 << 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DISPC_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_DISPC_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DISPC_SDMA_MASK					(1 << 3)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP54XX_WKUPDEP_DMIC_DMA_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_DMIC_DMA_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DMIC_DMA_DSP_MASK					(1 << 6)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP54XX_WKUPDEP_DMIC_DMA_SDMA_SHIFT					7
+#define OMAP54XX_WKUPDEP_DMIC_DMA_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DMIC_DMA_SDMA_MASK					(1 << 7)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP54XX_WKUPDEP_DMIC_IRQ_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_DMIC_IRQ_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DMIC_IRQ_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP54XX_WKUPDEP_DMIC_IRQ_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_DMIC_IRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DMIC_IRQ_MPU_MASK					(1 << 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_A_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_DSI1_A_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_A_DSP_MASK					(1 << 6)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_A_IPU_SHIFT					5
+#define OMAP54XX_WKUPDEP_DSI1_A_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_A_IPU_MASK					(1 << 5)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_A_MPU_SHIFT					4
+#define OMAP54XX_WKUPDEP_DSI1_A_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_A_MPU_MASK					(1 << 4)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_A_SDMA_SHIFT					7
+#define OMAP54XX_WKUPDEP_DSI1_A_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_A_SDMA_MASK					(1 << 7)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_B_DSP_SHIFT					10
+#define OMAP54XX_WKUPDEP_DSI1_B_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_B_DSP_MASK					(1 << 10)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_B_IPU_SHIFT					9
+#define OMAP54XX_WKUPDEP_DSI1_B_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_B_IPU_MASK					(1 << 9)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_B_MPU_SHIFT					8
+#define OMAP54XX_WKUPDEP_DSI1_B_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_B_MPU_MASK					(1 << 8)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_B_SDMA_SHIFT					11
+#define OMAP54XX_WKUPDEP_DSI1_B_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_B_SDMA_MASK					(1 << 11)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_C_DSP_SHIFT					17
+#define OMAP54XX_WKUPDEP_DSI1_C_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_C_DSP_MASK					(1 << 17)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_C_IPU_SHIFT					16
+#define OMAP54XX_WKUPDEP_DSI1_C_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_C_IPU_MASK					(1 << 16)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_C_MPU_SHIFT					15
+#define OMAP54XX_WKUPDEP_DSI1_C_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_C_MPU_MASK					(1 << 15)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_DSI1_C_SDMA_SHIFT					18
+#define OMAP54XX_WKUPDEP_DSI1_C_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_DSI1_C_SDMA_MASK					(1 << 18)
+
+/* Used by PM_WKUPAON_GPIO1_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO1_IRQ1_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_GPIO1_IRQ1_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO1_IRQ1_IPU_MASK					(1 << 1)
+
+/* Used by PM_WKUPAON_GPIO1_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO1_IRQ1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_GPIO1_IRQ1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO1_IRQ1_MPU_MASK					(1 << 0)
+
+/* Used by PM_WKUPAON_GPIO1_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO1_IRQ2_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_GPIO1_IRQ2_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO1_IRQ2_DSP_MASK					(1 << 6)
+
+/* Used by PM_L4PER_GPIO2_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO2_IRQ1_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_GPIO2_IRQ1_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO2_IRQ1_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_GPIO2_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO2_IRQ1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_GPIO2_IRQ1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO2_IRQ1_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_GPIO2_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO2_IRQ2_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_GPIO2_IRQ2_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO2_IRQ2_DSP_MASK					(1 << 6)
+
+/* Used by PM_L4PER_GPIO3_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO3_IRQ1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_GPIO3_IRQ1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO3_IRQ1_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_GPIO3_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO3_IRQ2_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_GPIO3_IRQ2_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO3_IRQ2_DSP_MASK					(1 << 6)
+
+/* Used by PM_L4PER_GPIO4_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO4_IRQ1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_GPIO4_IRQ1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO4_IRQ1_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_GPIO4_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO4_IRQ2_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_GPIO4_IRQ2_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO4_IRQ2_DSP_MASK					(1 << 6)
+
+/* Used by PM_L4PER_GPIO5_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO5_IRQ1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_GPIO5_IRQ1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO5_IRQ1_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_GPIO5_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO5_IRQ2_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_GPIO5_IRQ2_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO5_IRQ2_DSP_MASK					(1 << 6)
+
+/* Used by PM_L4PER_GPIO6_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO6_IRQ1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_GPIO6_IRQ1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO6_IRQ1_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_GPIO6_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO6_IRQ2_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_GPIO6_IRQ2_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO6_IRQ2_DSP_MASK					(1 << 6)
+
+/* Used by PM_L4PER_GPIO7_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO7_IRQ1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_GPIO7_IRQ1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO7_IRQ1_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_GPIO8_WKDEP */
+#define OMAP54XX_WKUPDEP_GPIO8_IRQ1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_GPIO8_IRQ1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_GPIO8_IRQ1_MPU_MASK					(1 << 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_HDMIDMA_SDMA_SHIFT					19
+#define OMAP54XX_WKUPDEP_HDMIDMA_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_HDMIDMA_SDMA_MASK					(1 << 19)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_HDMIIRQ_DSP_SHIFT					14
+#define OMAP54XX_WKUPDEP_HDMIIRQ_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_HDMIIRQ_DSP_MASK					(1 << 14)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_HDMIIRQ_IPU_SHIFT					13
+#define OMAP54XX_WKUPDEP_HDMIIRQ_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_HDMIIRQ_IPU_MASK					(1 << 13)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP54XX_WKUPDEP_HDMIIRQ_MPU_SHIFT					12
+#define OMAP54XX_WKUPDEP_HDMIIRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_HDMIIRQ_MPU_MASK					(1 << 12)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP54XX_WKUPDEP_HSI_DSP_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_HSI_DSP_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_HSI_DSP_DSP_MASK					(1 << 6)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP54XX_WKUPDEP_HSI_MCU_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_HSI_MCU_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_HSI_MCU_IPU_MASK					(1 << 1)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP54XX_WKUPDEP_HSI_MCU_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_HSI_MCU_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_HSI_MCU_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_I2C1_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C1_DMA_SDMA_SHIFT					7
+#define OMAP54XX_WKUPDEP_I2C1_DMA_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C1_DMA_SDMA_MASK					(1 << 7)
+
+/* Used by PM_L4PER_I2C1_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C1_IRQ_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_I2C1_IRQ_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C1_IRQ_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_I2C1_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C1_IRQ_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_I2C1_IRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C1_IRQ_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_I2C2_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C2_DMA_SDMA_SHIFT					7
+#define OMAP54XX_WKUPDEP_I2C2_DMA_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C2_DMA_SDMA_MASK					(1 << 7)
+
+/* Used by PM_L4PER_I2C2_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C2_IRQ_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_I2C2_IRQ_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C2_IRQ_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_I2C2_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C2_IRQ_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_I2C2_IRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C2_IRQ_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_I2C3_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C3_DMA_SDMA_SHIFT					7
+#define OMAP54XX_WKUPDEP_I2C3_DMA_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C3_DMA_SDMA_MASK					(1 << 7)
+
+/* Used by PM_L4PER_I2C3_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C3_IRQ_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_I2C3_IRQ_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C3_IRQ_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_I2C3_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C3_IRQ_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_I2C3_IRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C3_IRQ_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_I2C4_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C4_DMA_SDMA_SHIFT					7
+#define OMAP54XX_WKUPDEP_I2C4_DMA_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C4_DMA_SDMA_MASK					(1 << 7)
+
+/* Used by PM_L4PER_I2C4_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C4_IRQ_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_I2C4_IRQ_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C4_IRQ_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_I2C4_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C4_IRQ_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_I2C4_IRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C4_IRQ_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_I2C5_WKDEP */
+#define OMAP54XX_WKUPDEP_I2C5_IRQ_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_I2C5_IRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_I2C5_IRQ_MPU_MASK					(1 << 0)
+
+/* Used by PM_WKUPAON_KBD_WKDEP */
+#define OMAP54XX_WKUPDEP_KBD_MPU_SHIFT						0
+#define OMAP54XX_WKUPDEP_KBD_MPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_KBD_MPU_MASK						(1 << 0)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP54XX_WKUPDEP_MCASP_DMA_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_MCASP_DMA_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCASP_DMA_DSP_MASK					(1 << 6)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP54XX_WKUPDEP_MCASP_DMA_SDMA_SHIFT					7
+#define OMAP54XX_WKUPDEP_MCASP_DMA_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCASP_DMA_SDMA_MASK					(1 << 7)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP54XX_WKUPDEP_MCASP_IRQ_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_MCASP_IRQ_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCASP_IRQ_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP54XX_WKUPDEP_MCASP_IRQ_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_MCASP_IRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCASP_IRQ_MPU_MASK					(1 << 0)
+
+/* Used by PM_ABE_MCBSP1_WKDEP */
+#define OMAP54XX_WKUPDEP_MCBSP1_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_MCBSP1_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCBSP1_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_MCBSP1_WKDEP */
+#define OMAP54XX_WKUPDEP_MCBSP1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_MCBSP1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCBSP1_MPU_MASK					(1 << 0)
+
+/* Used by PM_ABE_MCBSP1_WKDEP */
+#define OMAP54XX_WKUPDEP_MCBSP1_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MCBSP1_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCBSP1_SDMA_MASK					(1 << 3)
+
+/* Used by PM_ABE_MCBSP2_WKDEP */
+#define OMAP54XX_WKUPDEP_MCBSP2_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_MCBSP2_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCBSP2_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_MCBSP2_WKDEP */
+#define OMAP54XX_WKUPDEP_MCBSP2_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_MCBSP2_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCBSP2_MPU_MASK					(1 << 0)
+
+/* Used by PM_ABE_MCBSP2_WKDEP */
+#define OMAP54XX_WKUPDEP_MCBSP2_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MCBSP2_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCBSP2_SDMA_MASK					(1 << 3)
+
+/* Used by PM_ABE_MCBSP3_WKDEP */
+#define OMAP54XX_WKUPDEP_MCBSP3_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_MCBSP3_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCBSP3_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_MCBSP3_WKDEP */
+#define OMAP54XX_WKUPDEP_MCBSP3_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_MCBSP3_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCBSP3_MPU_MASK					(1 << 0)
+
+/* Used by PM_ABE_MCBSP3_WKDEP */
+#define OMAP54XX_WKUPDEP_MCBSP3_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MCBSP3_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCBSP3_SDMA_MASK					(1 << 3)
+
+/* Used by PM_ABE_MCPDM_WKDEP */
+#define OMAP54XX_WKUPDEP_MCPDM_DMA_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_MCPDM_DMA_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCPDM_DMA_DSP_MASK					(1 << 6)
+
+/* Used by PM_ABE_MCPDM_WKDEP */
+#define OMAP54XX_WKUPDEP_MCPDM_DMA_SDMA_SHIFT					7
+#define OMAP54XX_WKUPDEP_MCPDM_DMA_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCPDM_DMA_SDMA_MASK					(1 << 7)
+
+/* Used by PM_ABE_MCPDM_WKDEP */
+#define OMAP54XX_WKUPDEP_MCPDM_IRQ_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_MCPDM_IRQ_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCPDM_IRQ_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_MCPDM_WKDEP */
+#define OMAP54XX_WKUPDEP_MCPDM_IRQ_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_MCPDM_IRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCPDM_IRQ_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI1_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_MCSPI1_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI1_DSP_MASK					(1 << 2)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI1_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_MCSPI1_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI1_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_MCSPI1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI1_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI1_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MCSPI1_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI1_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L4PER_MCSPI2_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI2_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_MCSPI2_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI2_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_MCSPI2_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI2_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_MCSPI2_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI2_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_MCSPI2_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI2_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MCSPI2_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI2_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L4PER_MCSPI3_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI3_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_MCSPI3_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI3_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_MCSPI3_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI3_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MCSPI3_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI3_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L4PER_MCSPI4_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI4_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_MCSPI4_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI4_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_MCSPI4_WKDEP */
+#define OMAP54XX_WKUPDEP_MCSPI4_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MCSPI4_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MCSPI4_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC1_DSP_SHIFT						2
+#define OMAP54XX_WKUPDEP_MMC1_DSP_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC1_DSP_MASK						(1 << 2)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC1_IPU_SHIFT						1
+#define OMAP54XX_WKUPDEP_MMC1_IPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC1_IPU_MASK						(1 << 1)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC1_MPU_SHIFT						0
+#define OMAP54XX_WKUPDEP_MMC1_MPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC1_MPU_MASK						(1 << 0)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC1_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MMC1_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MMC1_SDMA_MASK						(1 << 3)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC2_DSP_SHIFT						2
+#define OMAP54XX_WKUPDEP_MMC2_DSP_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC2_DSP_MASK						(1 << 2)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC2_IPU_SHIFT						1
+#define OMAP54XX_WKUPDEP_MMC2_IPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC2_IPU_MASK						(1 << 1)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC2_MPU_SHIFT						0
+#define OMAP54XX_WKUPDEP_MMC2_MPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC2_MPU_MASK						(1 << 0)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC2_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MMC2_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MMC2_SDMA_MASK						(1 << 3)
+
+/* Used by PM_L4PER_MMC3_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC3_IPU_SHIFT						1
+#define OMAP54XX_WKUPDEP_MMC3_IPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC3_IPU_MASK						(1 << 1)
+
+/* Used by PM_L4PER_MMC3_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC3_MPU_SHIFT						0
+#define OMAP54XX_WKUPDEP_MMC3_MPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC3_MPU_MASK						(1 << 0)
+
+/* Used by PM_L4PER_MMC3_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC3_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MMC3_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MMC3_SDMA_MASK						(1 << 3)
+
+/* Used by PM_L4PER_MMC4_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC4_MPU_SHIFT						0
+#define OMAP54XX_WKUPDEP_MMC4_MPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC4_MPU_MASK						(1 << 0)
+
+/* Used by PM_L4PER_MMC4_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC4_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MMC4_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MMC4_SDMA_MASK						(1 << 3)
+
+/* Used by PM_L4PER_MMC5_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC5_MPU_SHIFT						0
+#define OMAP54XX_WKUPDEP_MMC5_MPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_MMC5_MPU_MASK						(1 << 0)
+
+/* Used by PM_L4PER_MMC5_WKDEP */
+#define OMAP54XX_WKUPDEP_MMC5_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_MMC5_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_MMC5_SDMA_MASK						(1 << 3)
+
+/* Used by PM_L3INIT_SATA_WKDEP */
+#define OMAP54XX_WKUPDEP_SATA_MPU_SHIFT						0
+#define OMAP54XX_WKUPDEP_SATA_MPU_WIDTH						0x1
+#define OMAP54XX_WKUPDEP_SATA_MPU_MASK						(1 << 0)
+
+/* Used by PM_ABE_SLIMBUS1_WKDEP */
+#define OMAP54XX_WKUPDEP_SLIMBUS1_DMA_DSP_SHIFT					6
+#define OMAP54XX_WKUPDEP_SLIMBUS1_DMA_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_SLIMBUS1_DMA_DSP_MASK					(1 << 6)
+
+/* Used by PM_ABE_SLIMBUS1_WKDEP */
+#define OMAP54XX_WKUPDEP_SLIMBUS1_DMA_SDMA_SHIFT				7
+#define OMAP54XX_WKUPDEP_SLIMBUS1_DMA_SDMA_WIDTH				0x1
+#define OMAP54XX_WKUPDEP_SLIMBUS1_DMA_SDMA_MASK					(1 << 7)
+
+/* Used by PM_ABE_SLIMBUS1_WKDEP */
+#define OMAP54XX_WKUPDEP_SLIMBUS1_IRQ_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_SLIMBUS1_IRQ_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_SLIMBUS1_IRQ_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_SLIMBUS1_WKDEP */
+#define OMAP54XX_WKUPDEP_SLIMBUS1_IRQ_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_SLIMBUS1_IRQ_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_SLIMBUS1_IRQ_MPU_MASK					(1 << 0)
+
+/* Used by PM_COREAON_SMARTREFLEX_CORE_WKDEP */
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_CORE_IPU_SHIFT				1
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_CORE_IPU_WIDTH				0x1
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_CORE_IPU_MASK				(1 << 1)
+
+/* Used by PM_COREAON_SMARTREFLEX_CORE_WKDEP */
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_CORE_MPU_SHIFT				0
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_CORE_MPU_WIDTH				0x1
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_CORE_MPU_MASK				(1 << 0)
+
+/* Used by PM_COREAON_SMARTREFLEX_MM_WKDEP */
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_MM_MPU_SHIFT				0
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_MM_MPU_WIDTH				0x1
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_MM_MPU_MASK				(1 << 0)
+
+/* Used by PM_COREAON_SMARTREFLEX_MPU_WKDEP */
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_MPU_MPU_SHIFT				0
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_MPU_MPU_WIDTH				0x1
+#define OMAP54XX_WKUPDEP_SMARTREFLEX_MPU_MPU_MASK				(1 << 0)
+
+/* Used by PM_L4PER_TIMER10_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER10_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER10_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER10_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_TIMER11_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER11_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_TIMER11_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER11_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_TIMER11_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER11_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER11_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER11_MPU_MASK					(1 << 0)
+
+/* Used by PM_WKUPAON_TIMER12_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER12_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER12_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER12_MPU_MASK					(1 << 0)
+
+/* Used by PM_WKUPAON_TIMER1_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER1_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_TIMER2_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER2_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER2_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER2_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_TIMER3_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER3_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_TIMER3_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER3_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_TIMER3_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER3_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER3_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER3_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_TIMER4_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER4_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_TIMER4_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER4_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_TIMER4_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER4_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER4_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER4_MPU_MASK					(1 << 0)
+
+/* Used by PM_ABE_TIMER5_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER5_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_TIMER5_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER5_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_TIMER5_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER5_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER5_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER5_MPU_MASK					(1 << 0)
+
+/* Used by PM_ABE_TIMER6_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER6_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_TIMER6_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER6_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_TIMER6_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER6_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER6_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER6_MPU_MASK					(1 << 0)
+
+/* Used by PM_ABE_TIMER7_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER7_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_TIMER7_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER7_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_TIMER7_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER7_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER7_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER7_MPU_MASK					(1 << 0)
+
+/* Used by PM_ABE_TIMER8_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER8_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_TIMER8_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER8_DSP_MASK					(1 << 2)
+
+/* Used by PM_ABE_TIMER8_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER8_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER8_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER8_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_TIMER9_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER9_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_TIMER9_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER9_IPU_MASK					(1 << 1)
+
+/* Used by PM_L4PER_TIMER9_WKDEP */
+#define OMAP54XX_WKUPDEP_TIMER9_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_TIMER9_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_TIMER9_MPU_MASK					(1 << 0)
+
+/* Used by PM_L4PER_UART1_WKDEP */
+#define OMAP54XX_WKUPDEP_UART1_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_UART1_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART1_MPU_MASK						(1 << 0)
+
+/* Used by PM_L4PER_UART1_WKDEP */
+#define OMAP54XX_WKUPDEP_UART1_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_UART1_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART1_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L4PER_UART2_WKDEP */
+#define OMAP54XX_WKUPDEP_UART2_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_UART2_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART2_MPU_MASK						(1 << 0)
+
+/* Used by PM_L4PER_UART2_WKDEP */
+#define OMAP54XX_WKUPDEP_UART2_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_UART2_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART2_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP54XX_WKUPDEP_UART3_DSP_SHIFT					2
+#define OMAP54XX_WKUPDEP_UART3_DSP_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART3_DSP_MASK						(1 << 2)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP54XX_WKUPDEP_UART3_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_UART3_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART3_IPU_MASK						(1 << 1)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP54XX_WKUPDEP_UART3_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_UART3_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART3_MPU_MASK						(1 << 0)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP54XX_WKUPDEP_UART3_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_UART3_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART3_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L4PER_UART4_WKDEP */
+#define OMAP54XX_WKUPDEP_UART4_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_UART4_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART4_MPU_MASK						(1 << 0)
+
+/* Used by PM_L4PER_UART4_WKDEP */
+#define OMAP54XX_WKUPDEP_UART4_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_UART4_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART4_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L4PER_UART5_WKDEP */
+#define OMAP54XX_WKUPDEP_UART5_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_UART5_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART5_MPU_MASK						(1 << 0)
+
+/* Used by PM_L4PER_UART5_WKDEP */
+#define OMAP54XX_WKUPDEP_UART5_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_UART5_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART5_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L4PER_UART6_WKDEP */
+#define OMAP54XX_WKUPDEP_UART6_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_UART6_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART6_MPU_MASK						(1 << 0)
+
+/* Used by PM_L4PER_UART6_WKDEP */
+#define OMAP54XX_WKUPDEP_UART6_SDMA_SHIFT					3
+#define OMAP54XX_WKUPDEP_UART6_SDMA_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UART6_SDMA_MASK					(1 << 3)
+
+/* Used by PM_L3INIT_UNIPRO2_WKDEP */
+#define OMAP54XX_WKUPDEP_UNIPRO2_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_UNIPRO2_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_UNIPRO2_MPU_MASK					(1 << 0)
+
+/* Used by PM_L3INIT_USB_HOST_HS_WKDEP */
+#define OMAP54XX_WKUPDEP_USB_HOST_HS_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_USB_HOST_HS_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_USB_HOST_HS_IPU_MASK					(1 << 1)
+
+/* Used by PM_L3INIT_USB_HOST_HS_WKDEP */
+#define OMAP54XX_WKUPDEP_USB_HOST_HS_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_USB_HOST_HS_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_USB_HOST_HS_MPU_MASK					(1 << 0)
+
+/* Used by PM_L3INIT_USB_OTG_SS_WKDEP */
+#define OMAP54XX_WKUPDEP_USB_OTG_SS_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_USB_OTG_SS_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_USB_OTG_SS_IPU_MASK					(1 << 1)
+
+/* Used by PM_L3INIT_USB_OTG_SS_WKDEP */
+#define OMAP54XX_WKUPDEP_USB_OTG_SS_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_USB_OTG_SS_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_USB_OTG_SS_MPU_MASK					(1 << 0)
+
+/* Used by PM_L3INIT_USB_TLL_HS_WKDEP */
+#define OMAP54XX_WKUPDEP_USB_TLL_HS_IPU_SHIFT					1
+#define OMAP54XX_WKUPDEP_USB_TLL_HS_IPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_USB_TLL_HS_IPU_MASK					(1 << 1)
+
+/* Used by PM_L3INIT_USB_TLL_HS_WKDEP */
+#define OMAP54XX_WKUPDEP_USB_TLL_HS_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_USB_TLL_HS_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_USB_TLL_HS_MPU_MASK					(1 << 0)
+
+/* Used by PM_WKUPAON_WD_TIMER2_WKDEP */
+#define OMAP54XX_WKUPDEP_WD_TIMER2_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_WD_TIMER2_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_WD_TIMER2_MPU_MASK					(1 << 0)
+
+/* Used by PM_ABE_WD_TIMER3_WKDEP */
+#define OMAP54XX_WKUPDEP_WD_TIMER3_MPU_SHIFT					0
+#define OMAP54XX_WKUPDEP_WD_TIMER3_MPU_WIDTH					0x1
+#define OMAP54XX_WKUPDEP_WD_TIMER3_MPU_MASK					(1 << 0)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP54XX_WUCLK_CTRL_SHIFT						8
+#define OMAP54XX_WUCLK_CTRL_WIDTH						0x1
+#define OMAP54XX_WUCLK_CTRL_MASK						(1 << 8)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP54XX_WUCLK_STATUS_SHIFT						9
+#define OMAP54XX_WUCLK_STATUS_WIDTH						0x1
+#define OMAP54XX_WUCLK_STATUS_MASK						(1 << 9)
+
+/* Used by REVISION_PRM */
+#define OMAP54XX_X_MAJOR_SHIFT							8
+#define OMAP54XX_X_MAJOR_WIDTH							0x3
+#define OMAP54XX_X_MAJOR_MASK							(0x7 << 8)
+
+/* Used by REVISION_PRM */
+#define OMAP54XX_Y_MINOR_SHIFT							0
+#define OMAP54XX_Y_MINOR_WIDTH							0x6
+#define OMAP54XX_Y_MINOR_MASK							(0x3f << 0)
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/scrm54xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/scrm54xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/scrm54xx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/scrm54xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,231 @@
+/*
+ * OMAP54XX SCRM registers and bitfields
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_SCRM_54XX_H
+#define __ARCH_ARM_MACH_OMAP2_SCRM_54XX_H
+
+#define OMAP5_SCRM_BASE		0x4ae0a000
+
+#define OMAP54XX_SCRM_REGADDR(reg)				\
+	OMAP2_L4_IO_ADDRESS(OMAP5_SCRM_BASE + (reg))
+
+/* SCRM */
+
+/* SCRM.SCRM register offsets */
+#define OMAP5_SCRM_REVISION_SCRM_OFFSET		0x0000
+#define OMAP5_SCRM_REVISION_SCRM		OMAP54XX_SCRM_REGADDR(0x0000)
+#define OMAP5_SCRM_CLKSETUPTIME_OFFSET		0x0100
+#define OMAP5_SCRM_CLKSETUPTIME			OMAP54XX_SCRM_REGADDR(0x0100)
+#define OMAP5_SCRM_PMICSETUPTIME_OFFSET		0x0104
+#define OMAP5_SCRM_PMICSETUPTIME		OMAP54XX_SCRM_REGADDR(0x0104)
+#define OMAP5_SCRM_ALTCLKSRC_OFFSET		0x0110
+#define OMAP5_SCRM_ALTCLKSRC			OMAP54XX_SCRM_REGADDR(0x0110)
+#define OMAP5_SCRM_MODEMCLKM_OFFSET		0x0118
+#define OMAP5_SCRM_MODEMCLKM			OMAP54XX_SCRM_REGADDR(0x0118)
+#define OMAP5_SCRM_D2DCLKM_OFFSET		0x011c
+#define OMAP5_SCRM_D2DCLKM			OMAP54XX_SCRM_REGADDR(0x011c)
+#define OMAP5_SCRM_EXTCLKREQ_OFFSET		0x0200
+#define OMAP5_SCRM_EXTCLKREQ			OMAP54XX_SCRM_REGADDR(0x0200)
+#define OMAP5_SCRM_ACCCLKREQ_OFFSET		0x0204
+#define OMAP5_SCRM_ACCCLKREQ			OMAP54XX_SCRM_REGADDR(0x0204)
+#define OMAP5_SCRM_PWRREQ_OFFSET		0x0208
+#define OMAP5_SCRM_PWRREQ			OMAP54XX_SCRM_REGADDR(0x0208)
+#define OMAP5_SCRM_AUXCLKREQ0_OFFSET		0x0210
+#define OMAP5_SCRM_AUXCLKREQ0			OMAP54XX_SCRM_REGADDR(0x0210)
+#define OMAP5_SCRM_AUXCLKREQ1_OFFSET		0x0214
+#define OMAP5_SCRM_AUXCLKREQ1			OMAP54XX_SCRM_REGADDR(0x0214)
+#define OMAP5_SCRM_AUXCLKREQ2_OFFSET		0x0218
+#define OMAP5_SCRM_AUXCLKREQ2			OMAP54XX_SCRM_REGADDR(0x0218)
+#define OMAP5_SCRM_AUXCLKREQ3_OFFSET		0x021c
+#define OMAP5_SCRM_AUXCLKREQ3			OMAP54XX_SCRM_REGADDR(0x021c)
+#define OMAP5_SCRM_AUXCLKREQ4_OFFSET		0x0220
+#define OMAP5_SCRM_AUXCLKREQ4			OMAP54XX_SCRM_REGADDR(0x0220)
+#define OMAP5_SCRM_AUXCLKREQ5_OFFSET		0x0224
+#define OMAP5_SCRM_AUXCLKREQ5			OMAP54XX_SCRM_REGADDR(0x0224)
+#define OMAP5_SCRM_D2DCLKREQ_OFFSET		0x0234
+#define OMAP5_SCRM_D2DCLKREQ			OMAP54XX_SCRM_REGADDR(0x0234)
+#define OMAP5_SCRM_AUXCLK0_OFFSET		0x0310
+#define OMAP5_SCRM_AUXCLK0			OMAP54XX_SCRM_REGADDR(0x0310)
+#define OMAP5_SCRM_AUXCLK1_OFFSET		0x0314
+#define OMAP5_SCRM_AUXCLK1			OMAP54XX_SCRM_REGADDR(0x0314)
+#define OMAP5_SCRM_AUXCLK2_OFFSET		0x0318
+#define OMAP5_SCRM_AUXCLK2			OMAP54XX_SCRM_REGADDR(0x0318)
+#define OMAP5_SCRM_AUXCLK3_OFFSET		0x031c
+#define OMAP5_SCRM_AUXCLK3			OMAP54XX_SCRM_REGADDR(0x031c)
+#define OMAP5_SCRM_AUXCLK4_OFFSET		0x0320
+#define OMAP5_SCRM_AUXCLK4			OMAP54XX_SCRM_REGADDR(0x0320)
+#define OMAP5_SCRM_AUXCLK5_OFFSET		0x0324
+#define OMAP5_SCRM_AUXCLK5			OMAP54XX_SCRM_REGADDR(0x0324)
+#define OMAP5_SCRM_RSTTIME_OFFSET		0x0400
+#define OMAP5_SCRM_RSTTIME			OMAP54XX_SCRM_REGADDR(0x0400)
+#define OMAP5_SCRM_MODEMRSTCTRL_OFFSET		0x0418
+#define OMAP5_SCRM_MODEMRSTCTRL			OMAP54XX_SCRM_REGADDR(0x0418)
+#define OMAP5_SCRM_D2DRSTCTRL_OFFSET		0x041c
+#define OMAP5_SCRM_D2DRSTCTRL			OMAP54XX_SCRM_REGADDR(0x041c)
+#define OMAP5_SCRM_EXTPWRONRSTCTRL_OFFSET	0x0420
+#define OMAP5_SCRM_EXTPWRONRSTCTRL		OMAP54XX_SCRM_REGADDR(0x0420)
+#define OMAP5_SCRM_EXTWARMRSTST_OFFSET		0x0510
+#define OMAP5_SCRM_EXTWARMRSTST			OMAP54XX_SCRM_REGADDR(0x0510)
+#define OMAP5_SCRM_APEWARMRSTST_OFFSET		0x0514
+#define OMAP5_SCRM_APEWARMRSTST			OMAP54XX_SCRM_REGADDR(0x0514)
+#define OMAP5_SCRM_MODEMWARMRSTST_OFFSET	0x0518
+#define OMAP5_SCRM_MODEMWARMRSTST		OMAP54XX_SCRM_REGADDR(0x0518)
+#define OMAP5_SCRM_D2DWARMRSTST_OFFSET		0x051c
+#define OMAP5_SCRM_D2DWARMRSTST			OMAP54XX_SCRM_REGADDR(0x051c)
+
+/*
+ * Used by AUXCLKREQ0, AUXCLKREQ1, AUXCLKREQ2, AUXCLKREQ3, AUXCLKREQ4,
+ * AUXCLKREQ5, D2DCLKREQ
+ */
+#define OMAP5_ACCURACY_SHIFT			1
+#define OMAP5_ACCURACY_WIDTH			0x1
+#define OMAP5_ACCURACY_MASK			(1 << 1)
+
+/* Used by APEWARMRSTST */
+#define OMAP5_APEWARMRSTST_SHIFT		1
+#define OMAP5_APEWARMRSTST_WIDTH		0x1
+#define OMAP5_APEWARMRSTST_MASK			(1 << 1)
+
+/* Used by AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5 */
+#define OMAP5_CLKDIV_SHIFT			16
+#define OMAP5_CLKDIV_WIDTH			0x4
+#define OMAP5_CLKDIV_MASK			(0xf << 16)
+
+/* Used by D2DCLKM, MODEMCLKM */
+#define OMAP5_CLK_32KHZ_SHIFT			0
+#define OMAP5_CLK_32KHZ_WIDTH			0x1
+#define OMAP5_CLK_32KHZ_MASK			(1 << 0)
+
+/* Used by D2DRSTCTRL, MODEMRSTCTRL */
+#define OMAP5_COLDRST_SHIFT			0
+#define OMAP5_COLDRST_WIDTH			0x1
+#define OMAP5_COLDRST_MASK			(1 << 0)
+
+/* Used by D2DWARMRSTST */
+#define OMAP5_D2DWARMRSTST_SHIFT		3
+#define OMAP5_D2DWARMRSTST_WIDTH		0x1
+#define OMAP5_D2DWARMRSTST_MASK			(1 << 3)
+
+/* Used by AUXCLK0 */
+#define OMAP5_DISABLECLK_SHIFT			9
+#define OMAP5_DISABLECLK_WIDTH			0x1
+#define OMAP5_DISABLECLK_MASK			(1 << 9)
+
+/* Used by CLKSETUPTIME */
+#define OMAP5_DOWNTIME_SHIFT			16
+#define OMAP5_DOWNTIME_WIDTH			0x6
+#define OMAP5_DOWNTIME_MASK			(0x3f << 16)
+
+/* Used by AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5 */
+#define OMAP5_ENABLE_SHIFT			8
+#define OMAP5_ENABLE_WIDTH			0x1
+#define OMAP5_ENABLE_MASK			(1 << 8)
+
+/* Renamed from ENABLE Used by EXTPWRONRSTCTRL */
+#define OMAP5_ENABLE_0_0_SHIFT			0
+#define OMAP5_ENABLE_0_0_WIDTH			0x1
+#define OMAP5_ENABLE_0_0_MASK			(1 << 0)
+
+/* Used by ALTCLKSRC */
+#define OMAP5_ENABLE_EXT_SHIFT			3
+#define OMAP5_ENABLE_EXT_WIDTH			0x1
+#define OMAP5_ENABLE_EXT_MASK			(1 << 3)
+
+/* Used by ALTCLKSRC */
+#define OMAP5_ENABLE_INT_SHIFT			2
+#define OMAP5_ENABLE_INT_WIDTH			0x1
+#define OMAP5_ENABLE_INT_MASK			(1 << 2)
+
+/* Used by EXTWARMRSTST */
+#define OMAP5_EXTWARMRSTST_SHIFT		0
+#define OMAP5_EXTWARMRSTST_WIDTH		0x1
+#define OMAP5_EXTWARMRSTST_MASK			(1 << 0)
+
+/*
+ * Used by AUXCLKREQ0, AUXCLKREQ1, AUXCLKREQ2, AUXCLKREQ3, AUXCLKREQ4,
+ * AUXCLKREQ5
+ */
+#define OMAP5_MAPPING_SHIFT			2
+#define OMAP5_MAPPING_WIDTH			0x3
+#define OMAP5_MAPPING_MASK			(0x7 << 2)
+
+/* Used by ALTCLKSRC */
+#define OMAP5_MODE_SHIFT			0
+#define OMAP5_MODE_WIDTH			0x2
+#define OMAP5_MODE_MASK				(0x3 << 0)
+
+/* Used by MODEMWARMRSTST */
+#define OMAP5_MODEMWARMRSTST_SHIFT		2
+#define OMAP5_MODEMWARMRSTST_WIDTH		0x1
+#define OMAP5_MODEMWARMRSTST_MASK		(1 << 2)
+
+/*
+ * Used by ACCCLKREQ, AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5,
+ * AUXCLKREQ0, AUXCLKREQ1, AUXCLKREQ2, AUXCLKREQ3, AUXCLKREQ4, AUXCLKREQ5,
+ * D2DCLKREQ, EXTCLKREQ, PWRREQ
+ */
+#define OMAP5_POLARITY_SHIFT			0
+#define OMAP5_POLARITY_WIDTH			0x1
+#define OMAP5_POLARITY_MASK			(1 << 0)
+
+/* Used by EXTPWRONRSTCTRL */
+#define OMAP5_PWRONRST_SHIFT			1
+#define OMAP5_PWRONRST_WIDTH			0x1
+#define OMAP5_PWRONRST_MASK			(1 << 1)
+
+/* Used by REVISION_SCRM */
+#define OMAP5_REV_SHIFT				0
+#define OMAP5_REV_WIDTH				0x8
+#define OMAP5_REV_MASK				(0xff << 0)
+
+/* Used by RSTTIME */
+#define OMAP5_RSTTIME_SHIFT			0
+#define OMAP5_RSTTIME_WIDTH			0x4
+#define OMAP5_RSTTIME_MASK			(0xf << 0)
+
+/* Used by CLKSETUPTIME */
+#define OMAP5_SETUPTIME_SHIFT			0
+#define OMAP5_SETUPTIME_WIDTH			0xc
+#define OMAP5_SETUPTIME_MASK			(0xfff << 0)
+
+/* Used by PMICSETUPTIME */
+#define OMAP5_SLEEPTIME_SHIFT			0
+#define OMAP5_SLEEPTIME_WIDTH			0x6
+#define OMAP5_SLEEPTIME_MASK			(0x3f << 0)
+
+/* Used by AUXCLK0, AUXCLK1, AUXCLK2, AUXCLK3, AUXCLK4, AUXCLK5 */
+#define OMAP5_SRCSELECT_SHIFT			1
+#define OMAP5_SRCSELECT_WIDTH			0x2
+#define OMAP5_SRCSELECT_MASK			(0x3 << 1)
+
+/* Used by D2DCLKM */
+#define OMAP5_SYSCLK_SHIFT			1
+#define OMAP5_SYSCLK_WIDTH			0x1
+#define OMAP5_SYSCLK_MASK			(1 << 1)
+
+/* Used by PMICSETUPTIME */
+#define OMAP5_WAKEUPTIME_SHIFT			16
+#define OMAP5_WAKEUPTIME_WIDTH			0x6
+#define OMAP5_WAKEUPTIME_MASK			(0x3f << 16)
+
+/* Used by D2DRSTCTRL, MODEMRSTCTRL */
+#define OMAP5_WARMRST_SHIFT			1
+#define OMAP5_WARMRST_WIDTH			0x1
+#define OMAP5_WARMRST_MASK			(1 << 1)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/serial.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/serial.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/serial.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/serial.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,7 +63,6 @@ struct omap_uart_state {
 static LIST_HEAD(uart_list);
 static u8 num_uarts;
 static u8 console_uart_id = -1;
-static u8 no_console_suspend;
 static u8 uart_debug;
 
 #define DEFAULT_RXDMA_POLLRATE		1	/* RX DMA polling rate (us) */
@@ -176,6 +175,9 @@ static char *cmdline_find_option(char *s
 
 static int __init omap_serial_early_init(void)
 {
+	if (of_have_populated_dt())
+		return -ENODEV;
+
 	do {
 		char oh_name[MAX_UART_HWMOD_NAME_LEN];
 		struct omap_hwmod *oh;
@@ -206,20 +208,6 @@ static int __init omap_serial_early_init
 				pr_info("%s used as console in debug mode: uart%d clocks will not be gated",
 					uart_name, uart->num);
 			}
-
-			if (cmdline_find_option("no_console_suspend"))
-				no_console_suspend = true;
-
-			/*
-			 * omap-uart can be used for earlyprintk logs
-			 * So if omap-uart is used as console then prevent
-			 * uart reset and idle to get logs from omap-uart
-			 * until uart console driver is available to take
-			 * care for console messages.
-			 * Idling or resetting omap-uart while printing logs
-			 * early boot logs can stall the boot-up.
-			 */
-			oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
 		}
 	} while (1);
 
@@ -292,9 +280,6 @@ void __init omap_serial_init_port(struct
 		return;
 	}
 
-	if ((console_uart_id == bdata->id) && no_console_suspend)
-		omap_device_disable_idle_on_suspend(pdev);
-
 	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
 	if (console_uart_id == bdata->id) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/sleep44xx.S linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/sleep44xx.S
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/sleep44xx.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/sleep44xx.S	2013-08-25 20:43:22.000000000 -0400
@@ -34,6 +34,8 @@ ppa_zero_params:
 ppa_por_params:
 	.word		1, 0
 
+#ifdef CONFIG_ARCH_OMAP4
+
 /*
  * =============================
  * == CPU suspend finisher ==
@@ -326,7 +328,9 @@ skip_l2en:
 
 	b	cpu_resume			@ Jump to generic resume
 ENDPROC(omap4_cpu_resume)
-#endif
+#endif	/* CONFIG_ARCH_OMAP4 */
+
+#endif	/* defined(CONFIG_SMP) && defined(CONFIG_PM) */
 
 #ifndef CONFIG_OMAP4_ERRATA_I688
 ENTRY(omap_bus_sync)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/smartreflex-class3.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/smartreflex-class3.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/smartreflex-class3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/smartreflex-class3.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,14 +26,14 @@ static int sr_class3_enable(struct omap_
 	}
 
 	omap_vp_enable(sr->voltdm);
-	return sr_enable(sr->voltdm, volt);
+	return sr_enable(sr, volt);
 }
 
 static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset)
 {
-	sr_disable_errgen(sr->voltdm);
+	sr_disable_errgen(sr);
 	omap_vp_disable(sr->voltdm);
-	sr_disable(sr->voltdm);
+	sr_disable(sr);
 	if (is_volt_reset)
 		voltdm_reset(sr->voltdm);
 
@@ -42,7 +42,7 @@ static int sr_class3_disable(struct omap
 
 static int sr_class3_configure(struct omap_sr *sr)
 {
-	return sr_configure_errgen(sr->voltdm);
+	return sr_configure_errgen(sr);
 }
 
 /* SR class3 structure */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/soc.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/soc.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/soc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/soc.h	2013-08-25 20:43:22.000000000 -0400
@@ -96,6 +96,15 @@
 # endif
 #endif
 
+#ifdef CONFIG_SOC_AM43XX
+# ifdef OMAP_NAME
+#  undef  MULTI_OMAP2
+#  define MULTI_OMAP2
+# else
+#  define OMAP_NAME am43xx
+# endif
+#endif
+
 /*
  * Omap device type i.e. EMU/HS/TST/GP/BAD
  */
@@ -187,6 +196,7 @@ IS_OMAP_CLASS(44xx, 0x44)
 IS_AM_CLASS(35xx, 0x35)
 IS_OMAP_CLASS(54xx, 0x54)
 IS_AM_CLASS(33xx, 0x33)
+IS_AM_CLASS(43xx, 0x43)
 
 IS_TI_CLASS(81xx, 0x81)
 
@@ -202,6 +212,7 @@ IS_OMAP_SUBCLASS(543x, 0x543)
 IS_TI_SUBCLASS(816x, 0x816)
 IS_TI_SUBCLASS(814x, 0x814)
 IS_AM_SUBCLASS(335x, 0x335)
+IS_AM_SUBCLASS(437x, 0x437)
 
 #define cpu_is_omap24xx()		0
 #define cpu_is_omap242x()		0
@@ -214,6 +225,8 @@ IS_AM_SUBCLASS(335x, 0x335)
 #define soc_is_am35xx()			0
 #define soc_is_am33xx()			0
 #define soc_is_am335x()			0
+#define soc_is_am43xx()			0
+#define soc_is_am437x()			0
 #define cpu_is_omap44xx()		0
 #define cpu_is_omap443x()		0
 #define cpu_is_omap446x()		0
@@ -341,6 +354,13 @@ IS_OMAP_TYPE(3430, 0x3430)
 # define soc_is_am335x()		is_am335x()
 #endif
 
+#ifdef	CONFIG_SOC_AM43XX
+# undef soc_is_am43xx
+# undef soc_is_am437x
+# define soc_is_am43xx()		is_am43xx()
+# define soc_is_am437x()		is_am437x()
+#endif
+
 # if defined(CONFIG_ARCH_OMAP4)
 # undef cpu_is_omap44xx
 # undef cpu_is_omap443x
@@ -383,6 +403,8 @@ IS_OMAP_TYPE(3430, 0x3430)
 #define TI816X_CLASS		0x81600034
 #define TI8168_REV_ES1_0	TI816X_CLASS
 #define TI8168_REV_ES1_1	(TI816X_CLASS | (0x1 << 8))
+#define TI8168_REV_ES2_0	(TI816X_CLASS | (0x2 << 8))
+#define TI8168_REV_ES2_1	(TI816X_CLASS | (0x3 << 8))
 
 #define TI814X_CLASS		0x81400034
 #define TI8148_REV_ES1_0	TI814X_CLASS
@@ -398,6 +420,9 @@ IS_OMAP_TYPE(3430, 0x3430)
 #define AM335X_REV_ES2_0	(AM335X_CLASS | (0x1 << 8))
 #define AM335X_REV_ES2_1	(AM335X_CLASS | (0x2 << 8))
 
+#define AM437X_CLASS		0x43700000
+#define AM437X_REV_ES1_0	AM437X_CLASS
+
 #define OMAP443X_CLASS		0x44300044
 #define OMAP4430_REV_ES1_0	(OMAP443X_CLASS | (0x10 << 8))
 #define OMAP4430_REV_ES2_0	(OMAP443X_CLASS | (0x20 << 8))
@@ -424,6 +449,7 @@ void omap4xxx_check_revision(void);
 void omap5xxx_check_revision(void);
 void omap3xxx_check_features(void);
 void ti81xx_check_features(void);
+void am33xx_check_features(void);
 void omap4xxx_check_features(void);
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/sram.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/sram.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/sram.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/sram.c	2013-08-25 20:43:22.000000000 -0400
@@ -119,6 +119,9 @@ static void __init omap_detect_sram(void
 		if (soc_is_am33xx()) {
 			omap_sram_start = AM33XX_SRAM_PA;
 			omap_sram_size = 0x10000; /* 64K */
+		} else if (soc_is_am43xx()) {
+			omap_sram_start = AM33XX_SRAM_PA;
+			omap_sram_size = SZ_256K;
 		} else if (cpu_is_omap34xx()) {
 			omap_sram_start = OMAP3_SRAM_PA;
 			omap_sram_size = 0x10000; /* 64K */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/timer.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/timer.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,10 +41,10 @@
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/dmtimer-omap.h>
+#include <linux/sched_clock.h>
 
 #include <asm/mach/time.h>
 #include <asm/smp_twd.h>
-#include <asm/sched_clock.h>
 
 #include "omap_hwmod.h"
 #include "omap_device.h"
@@ -220,7 +220,7 @@ static int __init omap_dm_timer_init_one
 					 int posted)
 {
 	char name[10]; /* 10 = sizeof("gptXX_Xck0") */
-	const char *oh_name;
+	const char *oh_name = NULL;
 	struct device_node *np;
 	struct omap_hwmod *oh;
 	struct resource irq, mem;
@@ -582,7 +582,7 @@ OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k
 			2, "timer_sys_ck", NULL);
 #endif /* CONFIG_ARCH_OMAP2 */
 
-#ifdef CONFIG_ARCH_OMAP3
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX)
 OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon",
 			2, "timer_sys_ck", NULL);
 OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure",
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/twl-common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/twl-common.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/twl-common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/twl-common.c	2013-08-25 20:43:22.000000000 -0400
@@ -140,6 +140,7 @@ static struct regulator_init_data omap3_
 
 static struct regulator_consumer_supply omap3_vpll2_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dpi.0"),
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/usb-host.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/usb-host.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/usb-host.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/usb-host.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/usb/phy.h>
+#include <linux/usb/nop-usb-xceiv.h>
 
 #include "soc.h"
 #include "omap_device.h"
@@ -188,125 +189,6 @@ static void __init setup_ehci_io_mux(con
 	return;
 }
 
-static
-void __init setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
-{
-	switch (port_mode[0]) {
-	case OMAP_EHCI_PORT_MODE_PHY:
-		omap_mux_init_signal("usbb1_ulpiphy_stp",
-			OMAP_PIN_OUTPUT);
-		omap_mux_init_signal("usbb1_ulpiphy_clk",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_dir",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_nxt",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_dat0",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_dat1",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_dat2",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_dat3",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_dat4",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_dat5",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_dat6",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpiphy_dat7",
-			OMAP_PIN_INPUT_PULLDOWN);
-			break;
-	case OMAP_EHCI_PORT_MODE_TLL:
-		omap_mux_init_signal("usbb1_ulpitll_stp",
-			OMAP_PIN_INPUT_PULLUP);
-		omap_mux_init_signal("usbb1_ulpitll_clk",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_dir",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_nxt",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_dat0",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_dat1",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_dat2",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_dat3",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_dat4",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_dat5",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_dat6",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_ulpitll_dat7",
-			OMAP_PIN_INPUT_PULLDOWN);
-			break;
-	case OMAP_USBHS_PORT_MODE_UNUSED:
-	default:
-			break;
-	}
-	switch (port_mode[1]) {
-	case OMAP_EHCI_PORT_MODE_PHY:
-		omap_mux_init_signal("usbb2_ulpiphy_stp",
-			OMAP_PIN_OUTPUT);
-		omap_mux_init_signal("usbb2_ulpiphy_clk",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_dir",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_nxt",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_dat0",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_dat1",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_dat2",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_dat3",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_dat4",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_dat5",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_dat6",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpiphy_dat7",
-			OMAP_PIN_INPUT_PULLDOWN);
-			break;
-	case OMAP_EHCI_PORT_MODE_TLL:
-		omap_mux_init_signal("usbb2_ulpitll_stp",
-			OMAP_PIN_INPUT_PULLUP);
-		omap_mux_init_signal("usbb2_ulpitll_clk",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_dir",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_nxt",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_dat0",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_dat1",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_dat2",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_dat3",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_dat4",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_dat5",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_dat6",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_ulpitll_dat7",
-			OMAP_PIN_INPUT_PULLDOWN);
-			break;
-	case OMAP_USBHS_PORT_MODE_UNUSED:
-	default:
-			break;
-	}
-}
-
 static void __init setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
 {
 	switch (port_mode[0]) {
@@ -404,78 +286,6 @@ static void __init setup_ohci_io_mux(con
 	}
 }
 
-static
-void __init setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
-{
-	switch (port_mode[0]) {
-	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
-	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
-	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
-	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
-		omap_mux_init_signal("usbb1_mm_rxdp",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_mm_rxdm",
-			OMAP_PIN_INPUT_PULLDOWN);
-
-	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
-	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
-		omap_mux_init_signal("usbb1_mm_rxrcv",
-			OMAP_PIN_INPUT_PULLDOWN);
-
-	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
-	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
-		omap_mux_init_signal("usbb1_mm_txen",
-			OMAP_PIN_INPUT_PULLDOWN);
-
-
-	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
-	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
-		omap_mux_init_signal("usbb1_mm_txdat",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb1_mm_txse0",
-			OMAP_PIN_INPUT_PULLDOWN);
-		break;
-
-	case OMAP_USBHS_PORT_MODE_UNUSED:
-	default:
-		break;
-	}
-
-	switch (port_mode[1]) {
-	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
-	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
-	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
-	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
-		omap_mux_init_signal("usbb2_mm_rxdp",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_mm_rxdm",
-			OMAP_PIN_INPUT_PULLDOWN);
-
-	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
-	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
-		omap_mux_init_signal("usbb2_mm_rxrcv",
-			OMAP_PIN_INPUT_PULLDOWN);
-
-	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
-	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
-		omap_mux_init_signal("usbb2_mm_txen",
-			OMAP_PIN_INPUT_PULLDOWN);
-
-
-	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
-	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
-		omap_mux_init_signal("usbb2_mm_txdat",
-			OMAP_PIN_INPUT_PULLDOWN);
-		omap_mux_init_signal("usbb2_mm_txse0",
-			OMAP_PIN_INPUT_PULLDOWN);
-		break;
-
-	case OMAP_USBHS_PORT_MODE_UNUSED:
-	default:
-		break;
-	}
-}
-
 void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
 {
 	struct omap_hwmod	*uhh_hwm, *tll_hwm;
@@ -489,9 +299,6 @@ void __init usbhs_init(struct usbhs_omap
 		if (omap_rev() <= OMAP3430_REV_ES2_1)
 			pdata->single_ulpi_bypass = true;
 
-	} else if (cpu_is_omap44xx()) {
-		setup_4430ehci_io_mux(pdata->port_mode);
-		setup_4430ohci_io_mux(pdata->port_mode);
 	}
 
 	uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
@@ -560,7 +367,8 @@ static int usbhs_add_regulator(char *nam
 	struct regulator_init_data *reg_data;
 	struct fixed_voltage_config *config;
 	struct platform_device *pdev;
-	int ret;
+	struct platform_device_info pdevinfo;
+	int ret = -ENOMEM;
 
 	supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
 	if (!supplies)
@@ -571,7 +379,7 @@ static int usbhs_add_regulator(char *nam
 
 	reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL);
 	if (!reg_data)
-		return -ENOMEM;
+		goto err_data;
 
 	reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
 	reg_data->consumer_supplies = supplies;
@@ -580,39 +388,53 @@ static int usbhs_add_regulator(char *nam
 	config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config),
 			GFP_KERNEL);
 	if (!config)
-		return -ENOMEM;
+		goto err_config;
+
+	config->supply_name = kstrdup(name, GFP_KERNEL);
+	if (!config->supply_name)
+		goto err_supplyname;
 
-	config->supply_name = name;
 	config->gpio = gpio;
 	config->enable_high = polarity;
 	config->init_data = reg_data;
 
 	/* create a regulator device */
-	pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
-	if (!pdev)
-		return -ENOMEM;
+	memset(&pdevinfo, 0, sizeof(pdevinfo));
+	pdevinfo.name = reg_name;
+	pdevinfo.id = PLATFORM_DEVID_AUTO;
+	pdevinfo.data = config;
+	pdevinfo.size_data = sizeof(*config);
 
-	pdev->id = PLATFORM_DEVID_AUTO;
-	pdev->name = reg_name;
-	pdev->dev.platform_data = config;
+	pdev = platform_device_register_full(&pdevinfo);
+	if (IS_ERR(pdev)) {
+		ret = PTR_ERR(pdev);
+		pr_err("%s: Failed registering regulator %s for %s : %d\n",
+				__func__, name, dev_id, ret);
+		goto err_register;
+	}
 
-	ret = platform_device_register(pdev);
-	if (ret)
-		pr_err("%s: Failed registering regulator %s for %s\n",
-				__func__, name, dev_id);
+	return 0;
 
+err_register:
+	kfree(config->supply_name);
+err_supplyname:
+	kfree(config);
+err_config:
+	kfree(reg_data);
+err_data:
+	kfree(supplies);
 	return ret;
 }
 
+#define MAX_STR 20
+
 int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
 {
-	char *rail_name;
-	int i, len;
+	char rail_name[MAX_STR];
+	int i;
 	struct platform_device *pdev;
 	char *phy_id;
-
-	/* the phy_id will be something like "nop_usb_xceiv.1" */
-	len = strlen(nop_name) + 3; /* 3 -> ".1" and NULL terminator */
+	struct platform_device_info pdevinfo;
 
 	for (i = 0; i < num_phys; i++) {
 
@@ -627,25 +449,26 @@ int usbhs_init_phys(struct usbhs_phy_dat
 			!gpio_is_valid(phy->vcc_gpio))
 			continue;
 
-		/* create a NOP PHY device */
-		pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
-		if (!pdev)
-			return -ENOMEM;
-
-		pdev->id = phy->port;
-		pdev->name = nop_name;
-		pdev->dev.platform_data = phy->platform_data;
-
-		phy_id = kmalloc(len, GFP_KERNEL);
-		if (!phy_id)
+		phy_id = kmalloc(MAX_STR, GFP_KERNEL);
+		if (!phy_id) {
+			pr_err("%s: kmalloc() failed\n", __func__);
 			return -ENOMEM;
+		}
 
-		scnprintf(phy_id, len, "nop_usb_xceiv.%d\n",
-					pdev->id);
+		/* create a NOP PHY device */
+		memset(&pdevinfo, 0, sizeof(pdevinfo));
+		pdevinfo.name = nop_name;
+		pdevinfo.id = phy->port;
+		pdevinfo.data = phy->platform_data;
+		pdevinfo.size_data = sizeof(struct nop_usb_xceiv_platform_data);
 
-		if (platform_device_register(pdev)) {
-			pr_err("%s: Failed to register device %s\n",
-				__func__,  phy_id);
+		scnprintf(phy_id, MAX_STR, "nop_usb_xceiv.%d",
+					phy->port);
+		pdev = platform_device_register_full(&pdevinfo);
+		if (IS_ERR(pdev)) {
+			pr_err("%s: Failed to register device %s : %ld\n",
+				__func__,  phy_id, PTR_ERR(pdev));
+			kfree(phy_id);
 			continue;
 		}
 
@@ -653,26 +476,15 @@ int usbhs_init_phys(struct usbhs_phy_dat
 
 		/* Do we need RESET regulator ? */
 		if (gpio_is_valid(phy->reset_gpio)) {
-
-			rail_name = kmalloc(13, GFP_KERNEL);
-			if (!rail_name)
-				return -ENOMEM;
-
-			scnprintf(rail_name, 13, "hsusb%d_reset", phy->port);
-
+			scnprintf(rail_name, MAX_STR,
+					"hsusb%d_reset", phy->port);
 			usbhs_add_regulator(rail_name, phy_id, "reset",
 						phy->reset_gpio, 1);
 		}
 
 		/* Do we need VCC regulator ? */
 		if (gpio_is_valid(phy->vcc_gpio)) {
-
-			rail_name = kmalloc(13, GFP_KERNEL);
-			if (!rail_name)
-				return -ENOMEM;
-
-			scnprintf(rail_name, 13, "hsusb%d_vcc", phy->port);
-
+			scnprintf(rail_name, MAX_STR, "hsusb%d_vcc", phy->port);
 			usbhs_add_regulator(rail_name, phy_id, "vcc",
 					phy->vcc_gpio, phy->vcc_polarity);
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/usb-musb.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/usb-musb.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/usb-musb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/usb-musb.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,11 +38,8 @@ static struct musb_hdrc_config musb_conf
 };
 
 static struct musb_hdrc_platform_data musb_plat = {
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
 	.mode		= MUSB_OTG,
-#else
-	.mode		= MUSB_HOST,
-#endif
+
 	/* .clock is set dynamically */
 	.config		= &musb_config,
 
@@ -85,9 +82,6 @@ void __init usb_musb_init(struct omap_mu
 	musb_plat.mode = board_data->mode;
 	musb_plat.extvbus = board_data->extvbus;
 
-	if (cpu_is_omap44xx())
-		musb_plat.has_mailbox = true;
-
 	if (soc_is_am35xx()) {
 		oh_name = "am35x_otg_hs";
 		name = "musb-am35x";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/voltagedomains33xx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/voltagedomains33xx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/voltagedomains33xx_data.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/voltagedomains33xx_data.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/*
- * AM33XX voltage domain data
- *
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include "voltage.h"
-
-static struct voltagedomain am33xx_voltdm_mpu = {
-	.name		= "mpu",
-};
-
-static struct voltagedomain am33xx_voltdm_core = {
-	.name		= "core",
-};
-
-static struct voltagedomain am33xx_voltdm_rtc = {
-	.name		= "rtc",
-};
-
-static struct voltagedomain *voltagedomains_am33xx[] __initdata = {
-	&am33xx_voltdm_mpu,
-	&am33xx_voltdm_core,
-	&am33xx_voltdm_rtc,
-	NULL,
-};
-
-void __init am33xx_voltagedomains_init(void)
-{
-	voltdm_init(voltagedomains_am33xx);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/voltagedomains54xx_data.c linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/voltagedomains54xx_data.c
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/voltagedomains54xx_data.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/voltagedomains54xx_data.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * OMAP5 Voltage Management Routines
+ *
+ * Based on voltagedomains44xx_data.c
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include "common.h"
+
+#include "prm54xx.h"
+#include "voltage.h"
+#include "omap_opp_data.h"
+#include "vc.h"
+#include "vp.h"
+
+static const struct omap_vfsm_instance omap5_vdd_mpu_vfsm = {
+	.voltsetup_reg = OMAP54XX_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
+};
+
+static const struct omap_vfsm_instance omap5_vdd_mm_vfsm = {
+	.voltsetup_reg = OMAP54XX_PRM_VOLTSETUP_MM_RET_SLEEP_OFFSET,
+};
+
+static const struct omap_vfsm_instance omap5_vdd_core_vfsm = {
+	.voltsetup_reg = OMAP54XX_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
+};
+
+static struct voltagedomain omap5_voltdm_mpu = {
+	.name = "mpu",
+	.scalable = true,
+	.read = omap4_prm_vcvp_read,
+	.write = omap4_prm_vcvp_write,
+	.rmw = omap4_prm_vcvp_rmw,
+	.vc = &omap4_vc_mpu,
+	.vfsm = &omap5_vdd_mpu_vfsm,
+	.vp = &omap4_vp_mpu,
+};
+
+static struct voltagedomain omap5_voltdm_mm = {
+	.name = "mm",
+	.scalable = true,
+	.read = omap4_prm_vcvp_read,
+	.write = omap4_prm_vcvp_write,
+	.rmw = omap4_prm_vcvp_rmw,
+	.vc = &omap4_vc_iva,
+	.vfsm = &omap5_vdd_mm_vfsm,
+	.vp = &omap4_vp_iva,
+};
+
+static struct voltagedomain omap5_voltdm_core = {
+	.name = "core",
+	.scalable = true,
+	.read = omap4_prm_vcvp_read,
+	.write = omap4_prm_vcvp_write,
+	.rmw = omap4_prm_vcvp_rmw,
+	.vc = &omap4_vc_core,
+	.vfsm = &omap5_vdd_core_vfsm,
+	.vp = &omap4_vp_core,
+};
+
+static struct voltagedomain omap5_voltdm_wkup = {
+	.name = "wkup",
+};
+
+static struct voltagedomain *voltagedomains_omap5[] __initdata = {
+	&omap5_voltdm_mpu,
+	&omap5_voltdm_mm,
+	&omap5_voltdm_core,
+	&omap5_voltdm_wkup,
+	NULL,
+};
+
+static const char *sys_clk_name __initdata = "sys_clkin";
+
+void __init omap54xx_voltagedomains_init(void)
+{
+	struct voltagedomain *voltdm;
+	int i;
+
+	for (i = 0; voltdm = voltagedomains_omap5[i], voltdm; i++)
+		voltdm->sys_clk.name = sys_clk_name;
+
+	voltdm_init(voltagedomains_omap5);
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-omap2/voltage.h linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/voltage.h
--- linux-libre-3.10-gnu/arch/arm/mach-omap2/voltage.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-omap2/voltage.h	2013-08-25 20:43:22.000000000 -0400
@@ -169,8 +169,8 @@ int omap_voltage_late_init(void);
 
 extern void omap2xxx_voltagedomains_init(void);
 extern void omap3xxx_voltagedomains_init(void);
-extern void am33xx_voltagedomains_init(void);
 extern void omap44xx_voltagedomains_init(void);
+extern void omap54xx_voltagedomains_init(void);
 
 struct voltagedomain *voltdm_lookup(const char *name);
 void voltdm_init(struct voltagedomain **voltdm_list);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-orion5x/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-orion5x/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -347,7 +347,7 @@ void __init orion5x_init(void)
 	orion5x_wdt_init();
 }
 
-void orion5x_restart(char mode, const char *cmd)
+void orion5x_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * Enable and issue soft reset
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-orion5x/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-orion5x/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,8 @@
 #ifndef __ARCH_ORION5X_COMMON_H
 #define __ARCH_ORION5X_COMMON_H
 
+#include <linux/reboot.h>
+
 struct dsa_platform_data;
 struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
@@ -29,7 +31,7 @@ void orion5x_spi_init(void);
 void orion5x_uart0_init(void);
 void orion5x_uart1_init(void);
 void orion5x_xor_init(void);
-void orion5x_restart(char, const char *);
+void orion5x_restart(enum reboot_mode, const char *);
 
 /*
  * PCIe/PCI functions.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-orion5x/include/mach/bridge-regs.h linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/include/mach/bridge-regs.h
--- linux-libre-3.10-gnu/arch/arm/mach-orion5x/include/mach/bridge-regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/include/mach/bridge-regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,6 @@
 #define CPU_CTRL		(ORION5X_BRIDGE_VIRT_BASE + 0x104)
 
 #define RSTOUTn_MASK		(ORION5X_BRIDGE_VIRT_BASE + 0x108)
-#define WDT_RESET_OUT_EN	0x0002
 
 #define CPU_SOFT_RESET		(ORION5X_BRIDGE_VIRT_BASE + 0x10c)
 
@@ -26,8 +25,6 @@
 
 #define POWER_MNG_CTRL_REG	(ORION5X_BRIDGE_VIRT_BASE + 0x11C)
 
-#define WDT_INT_REQ		0x0008
-
 #define BRIDGE_INT_TIMER1_CLR	(~0x0004)
 
 #define MAIN_IRQ_CAUSE		(ORION5X_BRIDGE_VIRT_BASE + 0x200)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-orion5x/ls-chl-setup.c linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/ls-chl-setup.c
--- linux-libre-3.10-gnu/arch/arm/mach-orion5x/ls-chl-setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/ls-chl-setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -139,7 +139,7 @@ static struct mv_sata_platform_data lsch
 
 static void lschl_power_off(void)
 {
-	orion5x_restart('h', NULL);
+	orion5x_restart(REBOOT_HARD, NULL);
 }
 
 /*****************************************************************************
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-orion5x/ls_hgl-setup.c linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/ls_hgl-setup.c
--- linux-libre-3.10-gnu/arch/arm/mach-orion5x/ls_hgl-setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/ls_hgl-setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -185,7 +185,7 @@ static struct mv_sata_platform_data ls_h
 
 static void ls_hgl_power_off(void)
 {
-	orion5x_restart('h', NULL);
+	orion5x_restart(REBOOT_HARD, NULL);
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-orion5x/lsmini-setup.c linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/lsmini-setup.c
--- linux-libre-3.10-gnu/arch/arm/mach-orion5x/lsmini-setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-orion5x/lsmini-setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -185,7 +185,7 @@ static struct mv_sata_platform_data lsmi
 
 static void lsmini_power_off(void)
 {
-	orion5x_restart('h', NULL);
+	orion5x_restart(REBOOT_HARD, NULL);
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-picoxcell/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-picoxcell/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-picoxcell/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-picoxcell/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,20 +8,14 @@
  * All enquiries to support@picochip.com
  */
 #include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/irqchip.h>
-#include <linux/irqdomain.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/of_irq.h>
 #include <linux/of_platform.h>
-#include <linux/dw_apb_timer.h>
+#include <linux/reboot.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include "common.h"
-
 #define PHYS_TO_IO(x)			(((x) & 0x00ffffff) | 0xfe000000)
 #define PICOXCELL_PERIPH_BASE		0x80000000
 #define PICOXCELL_PERIPH_LENGTH		SZ_4M
@@ -70,7 +64,7 @@ static const char *picoxcell_dt_match[]
 	NULL
 };
 
-static void picoxcell_wdt_restart(char mode, const char *cmd)
+static void picoxcell_wdt_restart(enum reboot_mode mode, const char *cmd)
 {
 	/*
 	 * Configure the watchdog to reset with the shortest possible timeout
@@ -86,9 +80,6 @@ static void picoxcell_wdt_restart(char m
 
 DT_MACHINE_START(PICOXCELL, "Picochip picoXcell")
 	.map_io		= picoxcell_map_io,
-	.nr_irqs	= NR_IRQS_LEGACY,
-	.init_irq	= irqchip_init,
-	.init_time	= dw_apb_timer_init,
 	.init_machine	= picoxcell_init_machine,
 	.dt_compat	= picoxcell_dt_match,
 	.restart	= picoxcell_wdt_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-picoxcell/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-picoxcell/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-picoxcell/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-picoxcell/common.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2011 Picochip Ltd., Jamie Iles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * All enquiries to support@picochip.com
- */
-#ifndef __PICOXCELL_COMMON_H__
-#define __PICOXCELL_COMMON_H__
-
-#include <asm/mach/time.h>
-
-extern void dw_apb_timer_init(void);
-
-#endif /* __PICOXCELL_COMMON_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-picoxcell/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-picoxcell/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-picoxcell/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-picoxcell/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,6 @@ config ARCH_PICOXCELL
 	select ARM_PATCH_PHYS_VIRT
 	select ARM_VIC
 	select CPU_V6K
-	select DW_APB_TIMER
 	select DW_APB_TIMER_OF
 	select GENERIC_CLOCKEVENTS
 	select HAVE_TCM
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-prima2/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-prima2/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,6 @@
 #include <linux/clocksource.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/irqchip.h>
 #include <asm/sizes.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -17,16 +16,6 @@
 #include <linux/of_platform.h>
 #include "common.h"
 
-static struct of_device_id sirfsoc_of_bus_ids[] __initdata = {
-	{ .compatible = "simple-bus", },
-	{},
-};
-
-void __init sirfsoc_mach_init(void)
-{
-	of_platform_bus_probe(NULL, sirfsoc_of_bus_ids, NULL);
-}
-
 void __init sirfsoc_init_late(void)
 {
 	sirfsoc_pm_init();
@@ -55,9 +44,7 @@ DT_MACHINE_START(ATLAS6_DT, "Generic ATL
 	/* Maintainer: Barry Song <baohua.song@csr.com> */
 	.nr_irqs	= 128,
 	.map_io         = sirfsoc_map_io,
-	.init_irq	= irqchip_init,
 	.init_time	= sirfsoc_init_time,
-	.init_machine	= sirfsoc_mach_init,
 	.init_late	= sirfsoc_init_late,
 	.dt_compat      = atlas6_dt_match,
 	.restart	= sirfsoc_restart,
@@ -66,18 +53,16 @@ MACHINE_END
 
 #ifdef CONFIG_ARCH_PRIMA2
 static const char *prima2_dt_match[] __initdata = {
-       "sirf,prima2",
-       NULL
+	"sirf,prima2",
+	NULL
 };
 
 DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)")
 	/* Maintainer: Barry Song <baohua.song@csr.com> */
 	.nr_irqs	= 128,
 	.map_io         = sirfsoc_map_io,
-	.init_irq	= irqchip_init,
 	.init_time	= sirfsoc_init_time,
 	.dma_zone_size	= SZ_256M,
-	.init_machine	= sirfsoc_mach_init,
 	.init_late	= sirfsoc_init_late,
 	.dt_compat      = prima2_dt_match,
 	.restart	= sirfsoc_restart,
@@ -94,9 +79,7 @@ DT_MACHINE_START(MARCO_DT, "Generic MARC
 	/* Maintainer: Barry Song <baohua.song@csr.com> */
 	.smp            = smp_ops(sirfsoc_smp_ops),
 	.map_io         = sirfsoc_map_io,
-	.init_irq	= irqchip_init,
 	.init_time	= sirfsoc_init_time,
-	.init_machine	= sirfsoc_mach_init,
 	.init_late	= sirfsoc_init_late,
 	.dt_compat      = marco_dt_match,
 	.restart	= sirfsoc_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-prima2/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-prima2/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,8 @@
 #define __MACH_PRIMA2_COMMON_H__
 
 #include <linux/init.h>
+#include <linux/reboot.h>
+
 #include <asm/mach/time.h>
 #include <asm/exception.h>
 
@@ -22,7 +24,7 @@ extern void sirfsoc_cpu_die(unsigned int
 
 extern void __init sirfsoc_of_irq_init(void);
 extern void __init sirfsoc_of_clk_init(void);
-extern void sirfsoc_restart(char, const char *);
+extern void sirfsoc_restart(enum reboot_mode, const char *);
 extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs);
 
 #ifndef CONFIG_DEBUG_LL
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-prima2/headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/headsmp.S
--- linux-libre-3.10-gnu/arch/arm/mach-prima2/headsmp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -9,8 +9,6 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-	__CPUINIT
-
 /*
  * SIRFSOC specific entry point for secondary CPUs.  This provides
  * a "holding pen" into which all secondary cores are held until we're
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-prima2/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-prima2/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,7 +44,7 @@ void __init sirfsoc_map_scu(void)
 	scu_base = (void __iomem *)SIRFSOC_VA(base);
 }
 
-static void __cpuinit sirfsoc_secondary_init(unsigned int cpu)
+static void sirfsoc_secondary_init(unsigned int cpu)
 {
 	/*
 	 * let the primary processor know we're out of the
@@ -65,7 +65,7 @@ static struct of_device_id rsc_ids[]  =
 	{},
 };
 
-static int __cpuinit sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
 	struct device_node *np;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-prima2/pm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/pm.c
--- linux-libre-3.10-gnu/arch/arm/mach-prima2/pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/suspend.h>
 #include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-prima2/rstc.c linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/rstc.c
--- linux-libre-3.10-gnu/arch/arm/mach-prima2/rstc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-prima2/rstc.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/reboot.h>
 
 void __iomem *sirfsoc_rstc_base;
 static DEFINE_MUTEX(rstc_lock);
@@ -84,7 +85,7 @@ int sirfsoc_reset_device(struct device *
 
 #define SIRFSOC_SYS_RST_BIT  BIT(31)
 
-void sirfsoc_restart(char mode, const char *cmd)
+void sirfsoc_restart(enum reboot_mode mode, const char *cmd)
 {
 	writel(SIRFSOC_SYS_RST_BIT, sirfsoc_rstc_base);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/corgi.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/corgi.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/corgi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/corgi.c	2013-08-25 20:43:22.000000000 -0400
@@ -663,16 +663,16 @@ static void corgi_poweroff(void)
 		/* Green LED off tells the bootloader to halt */
 		gpio_set_value(CORGI_GPIO_LED_GREEN, 0);
 
-	pxa_restart('h', NULL);
+	pxa_restart(REBOOT_HARD, NULL);
 }
 
-static void corgi_restart(char mode, const char *cmd)
+static void corgi_restart(enum reboot_mode mode, const char *cmd)
 {
 	if (!machine_is_corgi())
 		/* Green LED on tells the bootloader to reboot */
 		gpio_set_value(CORGI_GPIO_LED_GREEN, 1);
 
-	pxa_restart('h', cmd);
+	pxa_restart(REBOOT_HARD, cmd);
 }
 
 static void __init corgi_init(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/em-x270.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/em-x270.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/em-x270.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/em-x270.c	2013-08-25 20:43:22.000000000 -0400
@@ -477,16 +477,24 @@ static int em_x270_usb_hub_init(void)
 	/* USB Hub power-on and reset */
 	gpio_direction_output(usb_hub_reset, 1);
 	gpio_direction_output(GPIO9_USB_VBUS_EN, 0);
-	regulator_enable(em_x270_usb_ldo);
+	err = regulator_enable(em_x270_usb_ldo);
+	if (err)
+		goto err_free_rst_gpio;
+
 	gpio_set_value(usb_hub_reset, 0);
 	gpio_set_value(usb_hub_reset, 1);
 	regulator_disable(em_x270_usb_ldo);
-	regulator_enable(em_x270_usb_ldo);
+	err = regulator_enable(em_x270_usb_ldo);
+	if (err)
+		goto err_free_rst_gpio;
+
 	gpio_set_value(usb_hub_reset, 0);
 	gpio_set_value(GPIO9_USB_VBUS_EN, 1);
 
 	return 0;
 
+err_free_rst_gpio:
+	gpio_free(usb_hub_reset);
 err_free_vbus_gpio:
 	gpio_free(GPIO9_USB_VBUS_EN);
 err_free_usb_ldo:
@@ -592,7 +600,7 @@ err_irq:
 	return err;
 }
 
-static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
+static int em_x270_mci_setpower(struct device *dev, unsigned int vdd)
 {
 	struct pxamci_platform_data* p_d = dev->platform_data;
 
@@ -600,10 +608,11 @@ static void em_x270_mci_setpower(struct
 		int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000;
 
 		regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV);
-		regulator_enable(em_x270_sdio_ldo);
+		return regulator_enable(em_x270_sdio_ldo);
 	} else {
 		regulator_disable(em_x270_sdio_ldo);
 	}
+	return 0;
 }
 
 static void em_x270_mci_exit(struct device *dev, void *data)
@@ -833,21 +842,25 @@ static inline void em_x270_init_ac97(voi
 #endif
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int em_x270_module_matrix_keys[] = {
+static const unsigned int em_x270_module_matrix_keys[] = {
 	KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
 	KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
 	KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
 };
 
+static struct matrix_keymap_data em_x270_matrix_keymap_data = {
+	.keymap			= em_x270_module_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(em_x270_module_matrix_keys),
+};
+
 struct pxa27x_keypad_platform_data em_x270_module_keypad_info = {
 	/* code map for the matrix keys */
 	.matrix_key_rows	= 3,
 	.matrix_key_cols	= 3,
-	.matrix_key_map		= em_x270_module_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(em_x270_module_matrix_keys),
+	.matrix_keymap_data	= &em_x270_matrix_keymap_data,
 };
 
-static unsigned int em_x270_exeda_matrix_keys[] = {
+static const unsigned int em_x270_exeda_matrix_keys[] = {
 	KEY(0, 0, KEY_RIGHTSHIFT), KEY(0, 1, KEY_RIGHTCTRL),
 	KEY(0, 2, KEY_RIGHTALT), KEY(0, 3, KEY_SPACE),
 	KEY(0, 4, KEY_LEFTALT), KEY(0, 5, KEY_LEFTCTRL),
@@ -889,12 +902,16 @@ static unsigned int em_x270_exeda_matrix
 	KEY(7, 6, 0), KEY(7, 7, 0),
 };
 
+static struct matrix_keymap_data em_x270_exeda_matrix_keymap_data = {
+	.keymap			= em_x270_exeda_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(em_x270_exeda_matrix_keys),
+};
+
 struct pxa27x_keypad_platform_data em_x270_exeda_keypad_info = {
 	/* code map for the matrix keys */
 	.matrix_key_rows	= 8,
 	.matrix_key_cols	= 8,
-	.matrix_key_map		= em_x270_exeda_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(em_x270_exeda_matrix_keys),
+	.matrix_keymap_data	= &em_x270_exeda_matrix_keymap_data,
 };
 
 static void __init em_x270_init_keypad(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/ezx.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/ezx.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/ezx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/ezx.c	2013-08-25 20:43:22.000000000 -0400
@@ -392,7 +392,7 @@ static unsigned long e6_pin_config[] __i
 
 /* KEYPAD */
 #ifdef CONFIG_MACH_EZX_A780
-static unsigned int a780_key_map[] = {
+static const unsigned int a780_key_map[] = {
 	KEY(0, 0, KEY_SEND),
 	KEY(0, 1, KEY_BACK),
 	KEY(0, 2, KEY_END),
@@ -424,11 +424,15 @@ static unsigned int a780_key_map[] = {
 	KEY(4, 4, KEY_DOWN),
 };
 
+static struct matrix_keymap_data a780_matrix_keymap_data = {
+	.keymap			= a780_key_map,
+	.keymap_size		= ARRAY_SIZE(a780_key_map),
+};
+
 static struct pxa27x_keypad_platform_data a780_keypad_platform_data = {
 	.matrix_key_rows = 5,
 	.matrix_key_cols = 5,
-	.matrix_key_map = a780_key_map,
-	.matrix_key_map_size = ARRAY_SIZE(a780_key_map),
+	.matrix_keymap_data = &a780_matrix_keymap_data,
 
 	.direct_key_map = { KEY_CAMERA },
 	.direct_key_num = 1,
@@ -438,7 +442,7 @@ static struct pxa27x_keypad_platform_dat
 #endif /* CONFIG_MACH_EZX_A780 */
 
 #ifdef CONFIG_MACH_EZX_E680
-static unsigned int e680_key_map[] = {
+static const unsigned int e680_key_map[] = {
 	KEY(0, 0, KEY_UP),
 	KEY(0, 1, KEY_RIGHT),
 	KEY(0, 2, KEY_RESERVED),
@@ -455,11 +459,15 @@ static unsigned int e680_key_map[] = {
 	KEY(2, 3, KEY_KPENTER),
 };
 
+static struct matrix_keymap_data e680_matrix_keymap_data = {
+	.keymap			= e680_key_map,
+	.keymap_size		= ARRAY_SIZE(e680_key_map),
+};
+
 static struct pxa27x_keypad_platform_data e680_keypad_platform_data = {
 	.matrix_key_rows = 3,
 	.matrix_key_cols = 4,
-	.matrix_key_map = e680_key_map,
-	.matrix_key_map_size = ARRAY_SIZE(e680_key_map),
+	.matrix_keymap_data = &e680_matrix_keymap_data,
 
 	.direct_key_map = {
 		KEY_CAMERA,
@@ -476,7 +484,7 @@ static struct pxa27x_keypad_platform_dat
 #endif /* CONFIG_MACH_EZX_E680 */
 
 #ifdef CONFIG_MACH_EZX_A1200
-static unsigned int a1200_key_map[] = {
+static const unsigned int a1200_key_map[] = {
 	KEY(0, 0, KEY_RESERVED),
 	KEY(0, 1, KEY_RIGHT),
 	KEY(0, 2, KEY_PAGEDOWN),
@@ -513,18 +521,22 @@ static unsigned int a1200_key_map[] = {
 	KEY(4, 5, KEY_RESERVED),
 };
 
+static struct matrix_keymap_data a1200_matrix_keymap_data = {
+	.keymap			= a1200_key_map,
+	.keymap_size		= ARRAY_SIZE(a1200_key_map),
+};
+
 static struct pxa27x_keypad_platform_data a1200_keypad_platform_data = {
 	.matrix_key_rows = 5,
 	.matrix_key_cols = 6,
-	.matrix_key_map = a1200_key_map,
-	.matrix_key_map_size = ARRAY_SIZE(a1200_key_map),
+	.matrix_keymap_data = &a1200_matrix_keymap_data,
 
 	.debounce_interval = 30,
 };
 #endif /* CONFIG_MACH_EZX_A1200 */
 
 #ifdef CONFIG_MACH_EZX_E6
-static unsigned int e6_key_map[] = {
+static const unsigned int e6_key_map[] = {
 	KEY(0, 0, KEY_RESERVED),
 	KEY(0, 1, KEY_RIGHT),
 	KEY(0, 2, KEY_PAGEDOWN),
@@ -561,18 +573,22 @@ static unsigned int e6_key_map[] = {
 	KEY(4, 5, KEY_PREVIOUSSONG),
 };
 
+static struct matrix_keymap_data e6_keymap_data = {
+	.keymap			= e6_key_map,
+	.keymap_size		= ARRAY_SIZE(e6_key_map),
+};
+
 static struct pxa27x_keypad_platform_data e6_keypad_platform_data = {
 	.matrix_key_rows = 5,
 	.matrix_key_cols = 6,
-	.matrix_key_map = e6_key_map,
-	.matrix_key_map_size = ARRAY_SIZE(e6_key_map),
+	.matrix_keymap_data = &e6_keymap_data,
 
 	.debounce_interval = 30,
 };
 #endif /* CONFIG_MACH_EZX_E6 */
 
 #ifdef CONFIG_MACH_EZX_A910
-static unsigned int a910_key_map[] = {
+static const unsigned int a910_key_map[] = {
 	KEY(0, 0, KEY_NUMERIC_6),
 	KEY(0, 1, KEY_RIGHT),
 	KEY(0, 2, KEY_PAGEDOWN),
@@ -609,18 +625,22 @@ static unsigned int a910_key_map[] = {
 	KEY(4, 5, KEY_RESERVED),
 };
 
+static struct matrix_keymap_data a910_matrix_keymap_data = {
+	.keymap			= a910_key_map,
+	.keymap_size		= ARRAY_SIZE(a910_key_map),
+};
+
 static struct pxa27x_keypad_platform_data a910_keypad_platform_data = {
 	.matrix_key_rows = 5,
 	.matrix_key_cols = 6,
-	.matrix_key_map = a910_key_map,
-	.matrix_key_map_size = ARRAY_SIZE(a910_key_map),
+	.matrix_keymap_data = &a910_matrix_keymap_data,
 
 	.debounce_interval = 30,
 };
 #endif /* CONFIG_MACH_EZX_A910 */
 
 #ifdef CONFIG_MACH_EZX_E2
-static unsigned int e2_key_map[] = {
+static const unsigned int e2_key_map[] = {
 	KEY(0, 0, KEY_NUMERIC_6),
 	KEY(0, 1, KEY_RIGHT),
 	KEY(0, 2, KEY_NUMERIC_9),
@@ -657,11 +677,15 @@ static unsigned int e2_key_map[] = {
 	KEY(4, 5, KEY_RESERVED),
 };
 
+static struct matrix_keymap_data e2_matrix_keymap_data = {
+	.keymap			= e2_key_map,
+	.keymap_size		= ARRAY_SIZE(e2_key_map),
+};
+
 static struct pxa27x_keypad_platform_data e2_keypad_platform_data = {
 	.matrix_key_rows = 5,
 	.matrix_key_cols = 6,
-	.matrix_key_map = e2_key_map,
-	.matrix_key_map_size = ARRAY_SIZE(e2_key_map),
+	.matrix_keymap_data = &e2_matrix_keymap_data,
 
 	.debounce_interval = 30,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/generic.h linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/generic.h
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/generic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/generic.h	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/reboot.h>
+
 struct irq_data;
 
 extern void pxa_timer_init(void);
@@ -56,4 +58,4 @@ void __init pxa_set_btuart_info(void *in
 void __init pxa_set_stuart_info(void *info);
 void __init pxa_set_hwuart_info(void *info);
 
-void pxa_restart(char, const char *);
+void pxa_restart(enum reboot_mode, const char *);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -615,12 +615,14 @@ endmenu
 config PXA25x
 	bool
 	select CPU_XSCALE
+	select CPU_FREQ_TABLE if CPU_FREQ
 	help
 	  Select code specific to PXA21x/25x/26x variants
 
 config PXA27x
 	bool
 	select CPU_XSCALE
+	select CPU_FREQ_TABLE if CPU_FREQ
 	help
 	  Select code specific to PXA27x variants
 
@@ -633,6 +635,7 @@ config CPU_PXA26x
 config PXA3xx
 	bool
 	select CPU_XSC3
+	select CPU_FREQ_TABLE if CPU_FREQ
 	help
 	  Select code specific to PXA3xx variants
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/littleton.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/littleton.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/littleton.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/littleton.c	2013-08-25 20:43:22.000000000 -0400
@@ -222,7 +222,7 @@ static inline void littleton_init_spi(vo
 #endif
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int littleton_matrix_key_map[] = {
+static const unsigned int littleton_matrix_key_map[] = {
 	/* KEY(row, col, key_code) */
 	KEY(1, 3, KEY_0), KEY(0, 0, KEY_1), KEY(1, 0, KEY_2), KEY(2, 0, KEY_3),
 	KEY(0, 1, KEY_4), KEY(1, 1, KEY_5), KEY(2, 1, KEY_6), KEY(0, 2, KEY_7),
@@ -249,11 +249,15 @@ static unsigned int littleton_matrix_key
 	KEY(3, 1, KEY_F23),	/* soft2 */
 };
 
+static struct matrix_keymap_data littleton_matrix_keymap_data = {
+	.keymap			= littleton_matrix_key_map,
+	.keymap_size		= ARRAY_SIZE(littleton_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data littleton_keypad_info = {
 	.matrix_key_rows	= 6,
 	.matrix_key_cols	= 5,
-	.matrix_key_map		= littleton_matrix_key_map,
-	.matrix_key_map_size	= ARRAY_SIZE(littleton_matrix_key_map),
+	.matrix_keymap_data	= &littleton_matrix_keymap_data,
 
 	.enable_rotary0		= 1,
 	.rotary0_up_key		= KEY_UP,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/mainstone.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/mainstone.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/mainstone.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/mainstone.c	2013-08-25 20:43:22.000000000 -0400
@@ -408,7 +408,7 @@ static int mainstone_mci_init(struct dev
 	return err;
 }
 
-static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
+static int mainstone_mci_setpower(struct device *dev, unsigned int vdd)
 {
 	struct pxamci_platform_data* p_d = dev->platform_data;
 
@@ -420,6 +420,7 @@ static void mainstone_mci_setpower(struc
 		printk(KERN_DEBUG "%s: off\n", __func__);
 		MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
 	}
+	return 0;
 }
 
 static void mainstone_mci_exit(struct device *dev, void *data)
@@ -498,7 +499,7 @@ static struct pxaohci_platform_data main
 };
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int mainstone_matrix_keys[] = {
+static const unsigned int mainstone_matrix_keys[] = {
 	KEY(0, 0, KEY_A), KEY(1, 0, KEY_B), KEY(2, 0, KEY_C),
 	KEY(3, 0, KEY_D), KEY(4, 0, KEY_E), KEY(5, 0, KEY_F),
 	KEY(0, 1, KEY_G), KEY(1, 1, KEY_H), KEY(2, 1, KEY_I),
@@ -527,11 +528,15 @@ static unsigned int mainstone_matrix_key
 	KEY(4, 6, KEY_SELECT),
 };
 
+static struct matrix_keymap_data mainstone_matrix_keymap_data = {
+	.keymap			= mainstone_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(mainstone_matrix_keys),
+};
+
 struct pxa27x_keypad_platform_data mainstone_keypad_info = {
 	.matrix_key_rows	= 6,
 	.matrix_key_cols	= 7,
-	.matrix_key_map		= mainstone_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(mainstone_matrix_keys),
+	.matrix_keymap_data	= &mainstone_matrix_keymap_data,
 
 	.enable_rotary0		= 1,
 	.rotary0_up_key		= KEY_UP,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/mioa701.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/mioa701.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/mioa701.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/mioa701.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/wm97xx.h>
 #include <linux/mtd/physmap.h>
 #include <linux/usb/gpio_vbus.h>
+#include <linux/reboot.h>
 #include <linux/regulator/max1586.h>
 #include <linux/slab.h>
 #include <linux/i2c/pxa-i2c.h>
@@ -222,7 +223,7 @@ static struct pxafb_mach_info mioa701_px
 /*
  * Keyboard configuration
  */
-static unsigned int mioa701_matrix_keys[] = {
+static const unsigned int mioa701_matrix_keys[] = {
 	KEY(0, 0, KEY_UP),
 	KEY(0, 1, KEY_RIGHT),
 	KEY(0, 2, KEY_MEDIA),
@@ -233,11 +234,16 @@ static unsigned int mioa701_matrix_keys[
 	KEY(2, 1, KEY_PHONE),	/* Phone Green key */
 	KEY(2, 2, KEY_CAMERA)	/* Camera key */
 };
+
+static struct matrix_keymap_data mioa701_matrix_keymap_data = {
+	.keymap			= mioa701_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(mioa701_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data mioa701_keypad_info = {
 	.matrix_key_rows = 3,
 	.matrix_key_cols = 3,
-	.matrix_key_map = mioa701_matrix_keys,
-	.matrix_key_map_size = ARRAY_SIZE(mioa701_matrix_keys),
+	.matrix_keymap_data = &mioa701_matrix_keymap_data,
 };
 
 /*
@@ -691,13 +697,13 @@ static void mioa701_machine_exit(void);
 static void mioa701_poweroff(void)
 {
 	mioa701_machine_exit();
-	pxa_restart('s', NULL);
+	pxa_restart(REBOOT_SOFT, NULL);
 }
 
-static void mioa701_restart(char c, const char *cmd)
+static void mioa701_restart(enum reboot_mode c, const char *cmd)
 {
 	mioa701_machine_exit();
-	pxa_restart('s', cmd);
+	pxa_restart(REBOOT_SOFT, cmd);
 }
 
 static struct gpio global_gpios[] = {
@@ -756,7 +762,6 @@ static void mioa701_machine_exit(void)
 
 MACHINE_START(MIOA701, "MIO A701")
 	.atag_offset	= 0x100,
-	.restart_mode	= 's',
 	.map_io		= &pxa27x_map_io,
 	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= &pxa27x_init_irq,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/palmld.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmld.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/palmld.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmld.c	2013-08-25 20:43:22.000000000 -0400
@@ -173,7 +173,7 @@ static inline void palmld_nor_init(void)
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int palmld_matrix_keys[] = {
+static const unsigned int palmld_matrix_keys[] = {
 	KEY(0, 1, KEY_F2),
 	KEY(0, 2, KEY_UP),
 
@@ -190,11 +190,15 @@ static unsigned int palmld_matrix_keys[]
 	KEY(3, 2, KEY_LEFT),
 };
 
+static struct matrix_keymap_data palmld_matrix_keymap_data = {
+	.keymap			= palmld_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(palmld_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = {
 	.matrix_key_rows	= 4,
 	.matrix_key_cols	= 3,
-	.matrix_key_map		= palmld_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(palmld_matrix_keys),
+	.matrix_keymap_data	= &palmld_matrix_keymap_data,
 
 	.debounce_interval	= 30,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/palmt5.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmt5.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/palmt5.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmt5.c	2013-08-25 20:43:22.000000000 -0400
@@ -108,7 +108,7 @@ static unsigned long palmt5_pin_config[]
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int palmt5_matrix_keys[] = {
+static const unsigned int palmt5_matrix_keys[] = {
 	KEY(0, 0, KEY_POWER),
 	KEY(0, 1, KEY_F1),
 	KEY(0, 2, KEY_ENTER),
@@ -124,11 +124,15 @@ static unsigned int palmt5_matrix_keys[]
 	KEY(3, 2, KEY_LEFT),
 };
 
+static struct matrix_keymap_data palmt5_matrix_keymap_data = {
+	.keymap			= palmt5_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(palmt5_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data palmt5_keypad_platform_data = {
 	.matrix_key_rows	= 4,
 	.matrix_key_cols	= 3,
-	.matrix_key_map		= palmt5_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(palmt5_matrix_keys),
+	.matrix_keymap_data	= &palmt5_matrix_keymap_data,
 
 	.debounce_interval	= 30,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/palmtreo.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmtreo.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/palmtreo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmtreo.c	2013-08-25 20:43:22.000000000 -0400
@@ -168,7 +168,7 @@ static unsigned long centro685_pin_confi
  * GPIO keyboard
  ******************************************************************************/
 #if IS_ENABLED(CONFIG_KEYBOARD_PXA27x)
-static unsigned int treo680_matrix_keys[] = {
+static const unsigned int treo680_matrix_keys[] = {
 	KEY(0, 0, KEY_F8),		/* Red/Off/Power */
 	KEY(0, 1, KEY_LEFT),
 	KEY(0, 2, KEY_LEFTCTRL),	/* Alternate */
@@ -227,7 +227,7 @@ static unsigned int treo680_matrix_keys[
 	KEY(7, 5, KEY_I),
 };
 
-static unsigned int centro_matrix_keys[] = {
+static const unsigned int centro_matrix_keys[] = {
 	KEY(0, 0, KEY_F9),		/* Home */
 	KEY(0, 1, KEY_LEFT),
 	KEY(0, 2, KEY_LEFTCTRL),	/* Alternate */
@@ -286,11 +286,20 @@ static unsigned int centro_matrix_keys[]
 	KEY(7, 5, KEY_I),
 };
 
+static struct matrix_keymap_data treo680_matrix_keymap_data = {
+	.keymap			= treo680_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(treo680_matrix_keys),
+};
+
+static struct matrix_keymap_data centro_matrix_keymap_data = {
+	.keymap			= centro_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(centro_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data treo680_keypad_pdata = {
 	.matrix_key_rows	= 8,
 	.matrix_key_cols	= 7,
-	.matrix_key_map		= treo680_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(treo680_matrix_keys),
+	.matrix_keymap_data	= &treo680_matrix_keymap_data,
 	.direct_key_map		= { KEY_CONNECT },
 	.direct_key_num		= 1,
 
@@ -301,10 +310,8 @@ static void __init palmtreo_kpc_init(voi
 {
 	static struct pxa27x_keypad_platform_data *data = &treo680_keypad_pdata;
 
-	if (machine_is_centro()) {
-		data->matrix_key_map = centro_matrix_keys;
-		data->matrix_key_map_size = ARRAY_SIZE(centro_matrix_keys);
-	}
+	if (machine_is_centro())
+		data->matrix_keymap_data = &centro_matrix_keymap_data;
 
 	pxa_set_keypad_info(&treo680_keypad_pdata);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/palmtx.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmtx.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/palmtx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmtx.c	2013-08-25 20:43:22.000000000 -0400
@@ -176,7 +176,7 @@ static inline void palmtx_nor_init(void)
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int palmtx_matrix_keys[] = {
+static const unsigned int palmtx_matrix_keys[] = {
 	KEY(0, 0, KEY_POWER),
 	KEY(0, 1, KEY_F1),
 	KEY(0, 2, KEY_ENTER),
@@ -192,11 +192,15 @@ static unsigned int palmtx_matrix_keys[]
 	KEY(3, 2, KEY_LEFT),
 };
 
+static struct matrix_keymap_data palmtx_matrix_keymap_data = {
+	.keymap			= palmtx_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(palmtx_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
 	.matrix_key_rows	= 4,
 	.matrix_key_cols	= 3,
-	.matrix_key_map		= palmtx_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(palmtx_matrix_keys),
+	.matrix_keymap_data	= &palmtx_matrix_keymap_data,
 
 	.debounce_interval	= 30,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/palmz72.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmz72.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/palmz72.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/palmz72.c	2013-08-25 20:43:22.000000000 -0400
@@ -140,7 +140,7 @@ static unsigned long palmz72_pin_config[
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int palmz72_matrix_keys[] = {
+static const unsigned int palmz72_matrix_keys[] = {
 	KEY(0, 0, KEY_POWER),
 	KEY(0, 1, KEY_F1),
 	KEY(0, 2, KEY_ENTER),
@@ -156,11 +156,15 @@ static unsigned int palmz72_matrix_keys[
 	KEY(3, 2, KEY_LEFT),
 };
 
+static struct matrix_keymap_data almz72_matrix_keymap_data = {
+	.keymap			= palmz72_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(palmz72_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data palmz72_keypad_platform_data = {
 	.matrix_key_rows	= 4,
 	.matrix_key_cols	= 3,
-	.matrix_key_map		= palmz72_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(palmz72_matrix_keys),
+	.matrix_keymap_data	= &almz72_matrix_keymap_data,
 
 	.debounce_interval	= 30,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/pcm990-baseboard.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/pcm990-baseboard.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/pcm990-baseboard.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/pcm990-baseboard.c	2013-08-25 20:43:22.000000000 -0400
@@ -335,7 +335,7 @@ static int pcm990_mci_init(struct device
 	return err;
 }
 
-static void pcm990_mci_setpower(struct device *dev, unsigned int vdd)
+static int pcm990_mci_setpower(struct device *dev, unsigned int vdd)
 {
 	struct pxamci_platform_data *p_d = dev->platform_data;
 	u8 val;
@@ -348,6 +348,7 @@ static void pcm990_mci_setpower(struct d
 		val &= ~PCM990_CTRL_MMC2PWR;
 
 	pcm990_cpld_writeb(PCM990_CTRL_MMC2PWR, PCM990_CTRL_REG5);
+	return 0;
 }
 
 static void pcm990_mci_exit(struct device *dev, void *data)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/poodle.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/poodle.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/poodle.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/poodle.c	2013-08-25 20:43:22.000000000 -0400
@@ -258,7 +258,7 @@ err_free_2:
 	return err;
 }
 
-static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
+static int poodle_mci_setpower(struct device *dev, unsigned int vdd)
 {
 	struct pxamci_platform_data* p_d = dev->platform_data;
 
@@ -270,6 +270,8 @@ static void poodle_mci_setpower(struct d
 		gpio_set_value(POODLE_GPIO_SD_PWR1, 0);
 		gpio_set_value(POODLE_GPIO_SD_PWR, 0);
 	}
+
+	return 0;
 }
 
 static void poodle_mci_exit(struct device *dev, void *data)
@@ -422,7 +424,7 @@ static struct i2c_board_info __initdata
 
 static void poodle_poweroff(void)
 {
-	pxa_restart('h', NULL);
+	pxa_restart(REBOOT_HARD, NULL);
 }
 
 static void __init poodle_init(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/reset.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/reset.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/reset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/reset.c	2013-08-25 20:43:22.000000000 -0400
@@ -83,7 +83,7 @@ static void do_hw_reset(void)
 	writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3);
 }
 
-void pxa_restart(char mode, const char *cmd)
+void pxa_restart(enum reboot_mode mode, const char *cmd)
 {
 	local_irq_disable();
 	local_fiq_disable();
@@ -91,14 +91,14 @@ void pxa_restart(char mode, const char *
 	clear_reset_status(RESET_STATUS_ALL);
 
 	switch (mode) {
-	case 's':
+	case REBOOT_SOFT:
 		/* Jump into ROM at address 0 */
 		soft_restart(0);
 		break;
-	case 'g':
+	case REBOOT_GPIO:
 		do_gpio_reset();
 		break;
-	case 'h':
+	case REBOOT_HARD:
 	default:
 		do_hw_reset();
 		break;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/spitz.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/spitz.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/spitz.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/spitz.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/reboot.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -597,7 +598,7 @@ static inline void spitz_spi_init(void)
  * NOTE: The card detect interrupt isn't debounced so we delay it by 250ms to
  * give the card a chance to fully insert/eject.
  */
-static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
+static int spitz_mci_setpower(struct device *dev, unsigned int vdd)
 {
 	struct pxamci_platform_data* p_d = dev->platform_data;
 
@@ -605,6 +606,8 @@ static void spitz_mci_setpower(struct de
 		spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, SCOOP_CPR_SD_3V);
 	else
 		spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, 0x0);
+
+	return 0;
 }
 
 static struct pxamci_platform_data spitz_mci_platform_data = {
@@ -924,10 +927,10 @@ static inline void spitz_i2c_init(void)
  ******************************************************************************/
 static void spitz_poweroff(void)
 {
-	pxa_restart('g', NULL);
+	pxa_restart(REBOOT_GPIO, NULL);
 }
 
-static void spitz_restart(char mode, const char *cmd)
+static void spitz_restart(enum reboot_mode mode, const char *cmd)
 {
 	uint32_t msc0 = __raw_readl(MSC0);
 	/* Bootloader magic for a reboot */
@@ -979,7 +982,6 @@ static void __init spitz_fixup(struct ta
 
 #ifdef CONFIG_MACH_SPITZ
 MACHINE_START(SPITZ, "SHARP Spitz")
-	.restart_mode	= 'g',
 	.fixup		= spitz_fixup,
 	.map_io		= pxa27x_map_io,
 	.nr_irqs	= PXA_NR_IRQS,
@@ -993,7 +995,6 @@ MACHINE_END
 
 #ifdef CONFIG_MACH_BORZOI
 MACHINE_START(BORZOI, "SHARP Borzoi")
-	.restart_mode	= 'g',
 	.fixup		= spitz_fixup,
 	.map_io		= pxa27x_map_io,
 	.nr_irqs	= PXA_NR_IRQS,
@@ -1007,7 +1008,6 @@ MACHINE_END
 
 #ifdef CONFIG_MACH_AKITA
 MACHINE_START(AKITA, "SHARP Akita")
-	.restart_mode	= 'g',
 	.fixup		= spitz_fixup,
 	.map_io		= pxa27x_map_io,
 	.nr_irqs	= PXA_NR_IRQS,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/stargate2.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/stargate2.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/stargate2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/stargate2.c	2013-08-25 20:43:22.000000000 -0400
@@ -734,9 +734,10 @@ static int stargate2_mci_init(struct dev
  *
  * Very simple control. Either it is on or off and is controlled by
  * a gpio pin */
-static void stargate2_mci_setpower(struct device *dev, unsigned int vdd)
+static int stargate2_mci_setpower(struct device *dev, unsigned int vdd)
 {
 	gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd);
+	return 0;
 }
 
 static void stargate2_mci_exit(struct device *dev, void *data)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/tavorevb.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/tavorevb.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/tavorevb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/tavorevb.c	2013-08-25 20:43:22.000000000 -0400
@@ -106,7 +106,7 @@ static struct platform_device smc91x_dev
 };
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int tavorevb_matrix_key_map[] = {
+static const unsigned int tavorevb_matrix_key_map[] = {
 	/* KEY(row, col, key_code) */
 	KEY(0, 4, KEY_A), KEY(0, 5, KEY_B), KEY(0, 6, KEY_C),
 	KEY(1, 4, KEY_E), KEY(1, 5, KEY_F), KEY(1, 6, KEY_G),
@@ -147,11 +147,15 @@ static unsigned int tavorevb_matrix_key_
 	KEY(3, 3, KEY_F23),	/* soft2 */
 };
 
+static struct matrix_keymap_data tavorevb_matrix_keymap_data = {
+	.keymap		= tavorevb_matrix_key_map,
+	.keymap_size	= ARRAY_SIZE(tavorevb_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data tavorevb_keypad_info = {
 	.matrix_key_rows	= 7,
 	.matrix_key_cols	= 7,
-	.matrix_key_map		= tavorevb_matrix_key_map,
-	.matrix_key_map_size	= ARRAY_SIZE(tavorevb_matrix_key_map),
+	.matrix_keymap_data	= &tavorevb_matrix_keymap_data,
 	.debounce_interval	= 30,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/time.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/time.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,11 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/clockchips.h>
+#include <linux/sched_clock.h>
 
 #include <asm/div64.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
-#include <asm/sched_clock.h>
 #include <mach/regs-ost.h>
 #include <mach/irqs.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/tosa.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/tosa.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/tosa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/tosa.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/usb/gpio_vbus.h>
+#include <linux/reboot.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -911,10 +912,10 @@ static struct platform_device *devices[]
 
 static void tosa_poweroff(void)
 {
-	pxa_restart('g', NULL);
+	pxa_restart(REBOOT_GPIO, NULL);
 }
 
-static void tosa_restart(char mode, const char *cmd)
+static void tosa_restart(enum reboot_mode mode, const char *cmd)
 {
 	uint32_t msc0 = __raw_readl(MSC0);
 
@@ -969,7 +970,6 @@ static void __init fixup_tosa(struct tag
 }
 
 MACHINE_START(TOSA, "SHARP Tosa")
-	.restart_mode	= 'g',
 	.fixup          = fixup_tosa,
 	.map_io         = pxa25x_map_io,
 	.nr_irqs	= TOSA_NR_IRQS,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/z2.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/z2.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/z2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/z2.c	2013-08-25 20:43:22.000000000 -0400
@@ -345,7 +345,7 @@ static inline void z2_leds_init(void) {}
  * GPIO keyboard
  ******************************************************************************/
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int z2_matrix_keys[] = {
+static const unsigned int z2_matrix_keys[] = {
 	KEY(0, 0, KEY_OPTION),
 	KEY(1, 0, KEY_UP),
 	KEY(2, 0, KEY_DOWN),
@@ -405,11 +405,15 @@ static unsigned int z2_matrix_keys[] = {
 	KEY(5, 7, KEY_DOT),
 };
 
+static struct matrix_keymap_data z2_matrix_keymap_data = {
+	.keymap			= z2_matrix_keys,
+	.keymap_size		= ARRAY_SIZE(z2_matrix_keys),
+};
+
 static struct pxa27x_keypad_platform_data z2_keypad_platform_data = {
 	.matrix_key_rows	= 7,
 	.matrix_key_cols	= 8,
-	.matrix_key_map		= z2_matrix_keys,
-	.matrix_key_map_size	= ARRAY_SIZE(z2_matrix_keys),
+	.matrix_keymap_data	= &z2_matrix_keymap_data,
 
 	.debounce_interval	= 30,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-pxa/zylonite.c linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/zylonite.c
--- linux-libre-3.10-gnu/arch/arm/mach-pxa/zylonite.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-pxa/zylonite.c	2013-08-25 20:43:22.000000000 -0400
@@ -263,7 +263,7 @@ static inline void zylonite_init_mmc(voi
 #endif
 
 #if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int zylonite_matrix_key_map[] = {
+static const unsigned int zylonite_matrix_key_map[] = {
 	/* KEY(row, col, key_code) */
 	KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_C), KEY(0, 5, KEY_D),
 	KEY(1, 0, KEY_E), KEY(1, 1, KEY_F), KEY(1, 2, KEY_G), KEY(1, 5, KEY_H),
@@ -306,11 +306,15 @@ static unsigned int zylonite_matrix_key_
 	KEY(0, 3, KEY_AUX),	/* contact */
 };
 
+static struct matrix_keymap_data zylonite_matrix_keymap_data = {
+	.keymap			= zylonite_matrix_key_map,
+	.keymap_size		= ARRAY_SIZE(zylonite_matrix_key_map),
+};
+
 static struct pxa27x_keypad_platform_data zylonite_keypad_info = {
 	.matrix_key_rows	= 8,
 	.matrix_key_cols	= 8,
-	.matrix_key_map		= zylonite_matrix_key_map,
-	.matrix_key_map_size	= ARRAY_SIZE(zylonite_matrix_key_map),
+	.matrix_keymap_data	= &zylonite_matrix_keymap_data,
 
 	.enable_rotary0		= 1,
 	.rotary0_up_key		= KEY_UP,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-realview/realview_eb.c linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_eb.c
--- linux-libre-3.10-gnu/arch/arm/mach-realview/realview_eb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_eb.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -418,7 +419,7 @@ static void __init realview_eb_timer_ini
 	realview_eb_twd_init();
 }
 
-static void realview_eb_restart(char mode, const char *cmd)
+static void realview_eb_restart(enum reboot_mode mode, const char *cmd)
 {
 	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
 	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-realview/realview_pb1176.c linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_pb1176.c
--- linux-libre-3.10-gnu/arch/arm/mach-realview/realview_pb1176.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_pb1176.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/io.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -329,7 +330,7 @@ static void __init realview_pb1176_timer
 	realview_timer_init(IRQ_DC1176_TIMER0);
 }
 
-static void realview_pb1176_restart(char mode, const char *cmd)
+static void realview_pb1176_restart(enum reboot_mode mode, const char *cmd)
 {
 	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
 	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-realview/realview_pb11mp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_pb11mp.c
--- linux-libre-3.10-gnu/arch/arm/mach-realview/realview_pb11mp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_pb11mp.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -316,7 +317,7 @@ static void __init realview_pb11mp_timer
 	realview_pb11mp_twd_init();
 }
 
-static void realview_pb11mp_restart(char mode, const char *cmd)
+static void realview_pb11mp_restart(enum reboot_mode mode, const char *cmd)
 {
 	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
 	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-realview/realview_pba8.c linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_pba8.c
--- linux-libre-3.10-gnu/arch/arm/mach-realview/realview_pba8.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_pba8.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
@@ -264,7 +265,7 @@ static void __init realview_pba8_timer_i
 	realview_timer_init(IRQ_PBA8_TIMER0_1);
 }
 
-static void realview_pba8_restart(char mode, const char *cmd)
+static void realview_pba8_restart(enum reboot_mode mode, const char *cmd)
 {
 	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
 	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-realview/realview_pbx.c linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_pbx.c
--- linux-libre-3.10-gnu/arch/arm/mach-realview/realview_pbx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-realview/realview_pbx.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/io.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/platform_data/clk-realview.h>
+#include <linux/reboot.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
@@ -344,7 +345,7 @@ static void realview_pbx_fixup(struct ta
 #endif
 }
 
-static void realview_pbx_restart(char mode, const char *cmd)
+static void realview_pbx_restart(enum reboot_mode mode, const char *cmd)
 {
 	void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
 	void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-rockchip/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-rockchip/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-rockchip/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-rockchip/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,16 @@
+config ARCH_ROCKCHIP
+	bool "Rockchip RK2928 and RK3xxx SOCs" if ARCH_MULTI_V7
+	select PINCTRL
+	select PINCTRL_ROCKCHIP
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_GIC
+	select CACHE_L2X0
+	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_SMP
+	select LOCAL_TIMERS if SMP
+	select COMMON_CLK
+	select GENERIC_CLOCKEVENTS
+	select DW_APB_TIMER_OF
+	help
+	  Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs
+	  containing the RK2928, RK30xx and RK31xx series.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-rockchip/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-rockchip/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-rockchip/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-rockchip/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-rockchip/rockchip.c linux-libre-3.11-rc7-gnu/arch/arm/mach-rockchip/rockchip.c
--- linux-libre-3.10-gnu/arch/arm/mach-rockchip/rockchip.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-rockchip/rockchip.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,52 @@
+/*
+ * Device Tree support for Rockchip SoCs
+ *
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/irqchip.h>
+#include <linux/dw_apb_timer.h>
+#include <linux/clk-provider.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+
+static void __init rockchip_timer_init(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+}
+
+static void __init rockchip_dt_init(void)
+{
+	l2x0_of_init(0, ~0UL);
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char * const rockchip_board_dt_compat[] = {
+	"rockchip,rk2928",
+	"rockchip,rk3066a",
+	"rockchip,rk3066b",
+	"rockchip,rk3188",
+	NULL,
+};
+
+DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
+	.init_machine	= rockchip_dt_init,
+	.init_time	= rockchip_timer_init,
+	.dt_compat	= rockchip_board_dt_compat,
+MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-rpc/riscpc.c linux-libre-3.11-rc7-gnu/arch/arm/mach-rpc/riscpc.c
--- linux-libre-3.10-gnu/arch/arm/mach-rpc/riscpc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-rpc/riscpc.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/ata_platform.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
+#include <linux/reboot.h>
 
 #include <asm/elf.h>
 #include <asm/mach-types.h>
@@ -201,7 +202,7 @@ static int __init rpc_init(void)
 
 arch_initcall(rpc_init);
 
-static void rpc_restart(char mode, const char *cmd)
+static void rpc_restart(enum reboot_mode mode, const char *cmd)
 {
 	iomd_writeb(0, IOMD_ROMCR0);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/clock-s3c2410.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/clock-s3c2410.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/clock-s3c2410.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/clock-s3c2410.c	2013-08-25 20:43:22.000000000 -0400
@@ -119,66 +119,101 @@ static struct clk init_clocks_off[] = {
 	}
 };
 
-static struct clk init_clocks[] = {
-	{
-		.name		= "lcd",
-		.parent		= &clk_h,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_LCDC,
-	}, {
-		.name		= "gpio",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_GPIO,
-	}, {
-		.name		= "usb-host",
-		.parent		= &clk_h,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_USBH,
-	}, {
-		.name		= "usb-device",
-		.parent		= &clk_h,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_USBD,
-	}, {
-		.name		= "timers",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_PWMT,
-	}, {
-		.name		= "uart",
-		.devname	= "s3c2410-uart.0",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_UART0,
-	}, {
-		.name		= "uart",
-		.devname	= "s3c2410-uart.1",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_UART1,
-	}, {
-		.name		= "uart",
-		.devname	= "s3c2410-uart.2",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_UART2,
-	}, {
-		.name		= "rtc",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_RTC,
-	}, {
-		.name		= "watchdog",
-		.parent		= &clk_p,
-		.ctrlbit	= 0,
-	}, {
-		.name		= "usb-bus-host",
-		.parent		= &clk_usb_bus,
-	}, {
-		.name		= "usb-bus-gadget",
-		.parent		= &clk_usb_bus,
-	},
+static struct clk clk_lcd = {
+	.name		= "lcd",
+	.parent		= &clk_h,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2410_CLKCON_LCDC,
+};
+
+static struct clk clk_gpio = {
+	.name		= "gpio",
+	.parent		= &clk_p,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2410_CLKCON_GPIO,
+};
+
+static struct clk clk_usb_host = {
+	.name		= "usb-host",
+	.parent		= &clk_h,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2410_CLKCON_USBH,
+};
+
+static struct clk clk_usb_device = {
+	.name		= "usb-device",
+	.parent		= &clk_h,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2410_CLKCON_USBD,
+};
+
+static struct clk clk_timers = {
+	.name		= "timers",
+	.parent		= &clk_p,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2410_CLKCON_PWMT,
+};
+
+struct clk s3c24xx_clk_uart0 = {
+	.name		= "uart",
+	.devname	= "s3c2410-uart.0",
+	.parent		= &clk_p,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2410_CLKCON_UART0,
+};
+
+struct clk s3c24xx_clk_uart1 = {
+	.name		= "uart",
+	.devname	= "s3c2410-uart.1",
+	.parent		= &clk_p,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2410_CLKCON_UART1,
+};
+
+struct clk s3c24xx_clk_uart2 = {
+	.name		= "uart",
+	.devname	= "s3c2410-uart.2",
+	.parent		= &clk_p,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2410_CLKCON_UART2,
+};
+
+static struct clk clk_rtc = {
+	.name		= "rtc",
+	.parent		= &clk_p,
+	.enable		= s3c2410_clkcon_enable,
+	.ctrlbit	= S3C2410_CLKCON_RTC,
+};
+
+static struct clk clk_watchdog = {
+	.name		= "watchdog",
+	.parent		= &clk_p,
+	.ctrlbit	= 0,
+};
+
+static struct clk clk_usb_bus_host = {
+	.name		= "usb-bus-host",
+	.parent		= &clk_usb_bus,
+};
+
+static struct clk clk_usb_bus_gadget = {
+	.name		= "usb-bus-gadget",
+	.parent		= &clk_usb_bus,
+};
+
+static struct clk *init_clocks[] = {
+	&clk_lcd,
+	&clk_gpio,
+	&clk_usb_host,
+	&clk_usb_device,
+	&clk_timers,
+	&s3c24xx_clk_uart0,
+	&s3c24xx_clk_uart1,
+	&s3c24xx_clk_uart2,
+	&clk_rtc,
+	&clk_watchdog,
+	&clk_usb_bus_host,
+	&clk_usb_bus_gadget,
 };
 
 /* s3c2410_baseclk_add()
@@ -195,7 +230,6 @@ int __init s3c2410_baseclk_add(void)
 {
 	unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
 	unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
-	struct clk *clkp;
 	struct clk *xtal;
 	int ret;
 	int ptr;
@@ -207,8 +241,9 @@ int __init s3c2410_baseclk_add(void)
 
 	/* register clocks from clock array */
 
-	clkp = init_clocks;
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++) {
+		struct clk *clkp = init_clocks[ptr];
+
 		/* ensure that we note the clock state */
 
 		clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/clock-s3c2440.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/clock-s3c2440.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/clock-s3c2440.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/clock-s3c2440.c	2013-08-25 20:43:22.000000000 -0400
@@ -166,6 +166,9 @@ static struct clk_lookup s3c2440_clk_loo
 	CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
 	CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
 	CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
+	CLKDEV_INIT("s3c2440-uart.0", "uart", &s3c24xx_clk_uart0),
+	CLKDEV_INIT("s3c2440-uart.1", "uart", &s3c24xx_clk_uart1),
+	CLKDEV_INIT("s3c2440-uart.2", "uart", &s3c24xx_clk_uart2),
 	CLKDEV_INIT("s3c2440-camif", "camera", &s3c2440_clk_cam_upll),
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,8 @@
 #ifndef __ARCH_ARM_MACH_S3C24XX_COMMON_H
 #define __ARCH_ARM_MACH_S3C24XX_COMMON_H __FILE__
 
+#include <linux/reboot.h>
+
 struct s3c2410_uartcfg;
 
 #ifdef CONFIG_CPU_S3C2410
@@ -20,7 +22,7 @@ extern  int s3c2410a_init(void);
 extern void s3c2410_map_io(void);
 extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s3c2410_init_clocks(int xtal);
-extern void s3c2410_restart(char mode, const char *cmd);
+extern void s3c2410_restart(enum reboot_mode mode, const char *cmd);
 extern void s3c2410_init_irq(void);
 #else
 #define s3c2410_init_clocks NULL
@@ -36,7 +38,7 @@ extern void s3c2412_map_io(void);
 extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s3c2412_init_clocks(int xtal);
 extern  int s3c2412_baseclk_add(void);
-extern void s3c2412_restart(char mode, const char *cmd);
+extern void s3c2412_restart(enum reboot_mode mode, const char *cmd);
 extern void s3c2412_init_irq(void);
 #else
 #define s3c2412_init_clocks NULL
@@ -51,7 +53,7 @@ extern void s3c2416_map_io(void);
 extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s3c2416_init_clocks(int xtal);
 extern  int s3c2416_baseclk_add(void);
-extern void s3c2416_restart(char mode, const char *cmd);
+extern void s3c2416_restart(enum reboot_mode mode, const char *cmd);
 extern void s3c2416_init_irq(void);
 
 extern struct syscore_ops s3c2416_irq_syscore_ops;
@@ -66,7 +68,7 @@ extern struct syscore_ops s3c2416_irq_sy
 extern void s3c244x_map_io(void);
 extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s3c244x_init_clocks(int xtal);
-extern void s3c244x_restart(char mode, const char *cmd);
+extern void s3c244x_restart(enum reboot_mode mode, const char *cmd);
 #else
 #define s3c244x_init_clocks NULL
 #define s3c244x_init_uarts NULL
@@ -96,7 +98,7 @@ extern void s3c2443_map_io(void);
 extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 extern void s3c2443_init_clocks(int xtal);
 extern  int s3c2443_baseclk_add(void);
-extern void s3c2443_restart(char mode, const char *cmd);
+extern void s3c2443_restart(enum reboot_mode mode, const char *cmd);
 extern void s3c2443_init_irq(void);
 #else
 #define s3c2443_init_clocks NULL
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,711 +0,0 @@
-/*
- * Copyright (c) 2006-2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX CPU Frequency scaling
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/cpufreq.h>
-#include <linux/cpu.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/device.h>
-#include <linux/sysfs.h>
-#include <linux/slab.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <plat/cpu.h>
-#include <plat/clock.h>
-#include <plat/cpu-freq-core.h>
-
-#include <mach/regs-clock.h>
-
-/* note, cpufreq support deals in kHz, no Hz */
-
-static struct cpufreq_driver s3c24xx_driver;
-static struct s3c_cpufreq_config cpu_cur;
-static struct s3c_iotimings s3c24xx_iotiming;
-static struct cpufreq_frequency_table *pll_reg;
-static unsigned int last_target = ~0;
-static unsigned int ftab_size;
-static struct cpufreq_frequency_table *ftab;
-
-static struct clk *_clk_mpll;
-static struct clk *_clk_xtal;
-static struct clk *clk_fclk;
-static struct clk *clk_hclk;
-static struct clk *clk_pclk;
-static struct clk *clk_arm;
-
-#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
-struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void)
-{
-	return &cpu_cur;
-}
-
-struct s3c_iotimings *s3c_cpufreq_getiotimings(void)
-{
-	return &s3c24xx_iotiming;
-}
-#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUGFS */
-
-static void s3c_cpufreq_getcur(struct s3c_cpufreq_config *cfg)
-{
-	unsigned long fclk, pclk, hclk, armclk;
-
-	cfg->freq.fclk = fclk = clk_get_rate(clk_fclk);
-	cfg->freq.hclk = hclk = clk_get_rate(clk_hclk);
-	cfg->freq.pclk = pclk = clk_get_rate(clk_pclk);
-	cfg->freq.armclk = armclk = clk_get_rate(clk_arm);
-
-	cfg->pll.index = __raw_readl(S3C2410_MPLLCON);
-	cfg->pll.frequency = fclk;
-
-	cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
-
-	cfg->divs.h_divisor = fclk / hclk;
-	cfg->divs.p_divisor = fclk / pclk;
-}
-
-static inline void s3c_cpufreq_calc(struct s3c_cpufreq_config *cfg)
-{
-	unsigned long pll = cfg->pll.frequency;
-
-	cfg->freq.fclk = pll;
-	cfg->freq.hclk = pll / cfg->divs.h_divisor;
-	cfg->freq.pclk = pll / cfg->divs.p_divisor;
-
-	/* convert hclk into 10ths of nanoseconds for io calcs */
-	cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
-}
-
-static inline int closer(unsigned int target, unsigned int n, unsigned int c)
-{
-	int diff_cur = abs(target - c);
-	int diff_new = abs(target - n);
-
-	return (diff_new < diff_cur);
-}
-
-static void s3c_cpufreq_show(const char *pfx,
-				 struct s3c_cpufreq_config *cfg)
-{
-	s3c_freq_dbg("%s: Fvco=%u, F=%lu, A=%lu, H=%lu (%u), P=%lu (%u)\n",
-		     pfx, cfg->pll.frequency, cfg->freq.fclk, cfg->freq.armclk,
-		     cfg->freq.hclk, cfg->divs.h_divisor,
-		     cfg->freq.pclk, cfg->divs.p_divisor);
-}
-
-/* functions to wrapper the driver info calls to do the cpu specific work */
-
-static void s3c_cpufreq_setio(struct s3c_cpufreq_config *cfg)
-{
-	if (cfg->info->set_iotiming)
-		(cfg->info->set_iotiming)(cfg, &s3c24xx_iotiming);
-}
-
-static int s3c_cpufreq_calcio(struct s3c_cpufreq_config *cfg)
-{
-	if (cfg->info->calc_iotiming)
-		return (cfg->info->calc_iotiming)(cfg, &s3c24xx_iotiming);
-
-	return 0;
-}
-
-static void s3c_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
-{
-	(cfg->info->set_refresh)(cfg);
-}
-
-static void s3c_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
-{
-	(cfg->info->set_divs)(cfg);
-}
-
-static int s3c_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
-{
-	return (cfg->info->calc_divs)(cfg);
-}
-
-static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg)
-{
-	(cfg->info->set_fvco)(cfg);
-}
-
-static inline void s3c_cpufreq_resume_clocks(void)
-{
-	cpu_cur.info->resume_clocks();
-}
-
-static inline void s3c_cpufreq_updateclk(struct clk *clk,
-					 unsigned int freq)
-{
-	clk_set_rate(clk, freq);
-}
-
-static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
-				 unsigned int target_freq,
-				 struct cpufreq_frequency_table *pll)
-{
-	struct s3c_cpufreq_freqs freqs;
-	struct s3c_cpufreq_config cpu_new;
-	unsigned long flags;
-
-	cpu_new = cpu_cur;  /* copy new from current */
-
-	s3c_cpufreq_show("cur", &cpu_cur);
-
-	/* TODO - check for DMA currently outstanding */
-
-	cpu_new.pll = pll ? *pll : cpu_cur.pll;
-
-	if (pll)
-		freqs.pll_changing = 1;
-
-	/* update our frequencies */
-
-	cpu_new.freq.armclk = target_freq;
-	cpu_new.freq.fclk = cpu_new.pll.frequency;
-
-	if (s3c_cpufreq_calcdivs(&cpu_new) < 0) {
-		printk(KERN_ERR "no divisors for %d\n", target_freq);
-		goto err_notpossible;
-	}
-
-	s3c_freq_dbg("%s: got divs\n", __func__);
-
-	s3c_cpufreq_calc(&cpu_new);
-
-	s3c_freq_dbg("%s: calculated frequencies for new\n", __func__);
-
-	if (cpu_new.freq.hclk != cpu_cur.freq.hclk) {
-		if (s3c_cpufreq_calcio(&cpu_new) < 0) {
-			printk(KERN_ERR "%s: no IO timings\n", __func__);
-			goto err_notpossible;
-		}
-	}
-
-	s3c_cpufreq_show("new", &cpu_new);
-
-	/* setup our cpufreq parameters */
-
-	freqs.old = cpu_cur.freq;
-	freqs.new = cpu_new.freq;
-
-	freqs.freqs.old = cpu_cur.freq.armclk / 1000;
-	freqs.freqs.new = cpu_new.freq.armclk / 1000;
-
-	/* update f/h/p clock settings before we issue the change
-	 * notification, so that drivers do not need to do anything
-	 * special if they want to recalculate on CPUFREQ_PRECHANGE. */
-
-	s3c_cpufreq_updateclk(_clk_mpll, cpu_new.pll.frequency);
-	s3c_cpufreq_updateclk(clk_fclk, cpu_new.freq.fclk);
-	s3c_cpufreq_updateclk(clk_hclk, cpu_new.freq.hclk);
-	s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
-
-	/* start the frequency change */
-	cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_PRECHANGE);
-
-	/* If hclk is staying the same, then we do not need to
-	 * re-write the IO or the refresh timings whilst we are changing
-	 * speed. */
-
-	local_irq_save(flags);
-
-	/* is our memory clock slowing down? */
-	if (cpu_new.freq.hclk < cpu_cur.freq.hclk) {
-		s3c_cpufreq_setrefresh(&cpu_new);
-		s3c_cpufreq_setio(&cpu_new);
-	}
-
-	if (cpu_new.freq.fclk == cpu_cur.freq.fclk) {
-		/* not changing PLL, just set the divisors */
-
-		s3c_cpufreq_setdivs(&cpu_new);
-	} else {
-		if (cpu_new.freq.fclk < cpu_cur.freq.fclk) {
-			/* slow the cpu down, then set divisors */
-
-			s3c_cpufreq_setfvco(&cpu_new);
-			s3c_cpufreq_setdivs(&cpu_new);
-		} else {
-			/* set the divisors, then speed up */
-
-			s3c_cpufreq_setdivs(&cpu_new);
-			s3c_cpufreq_setfvco(&cpu_new);
-		}
-	}
-
-	/* did our memory clock speed up */
-	if (cpu_new.freq.hclk > cpu_cur.freq.hclk) {
-		s3c_cpufreq_setrefresh(&cpu_new);
-		s3c_cpufreq_setio(&cpu_new);
-	}
-
-	/* update our current settings */
-	cpu_cur = cpu_new;
-
-	local_irq_restore(flags);
-
-	/* notify everyone we've done this */
-	cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_POSTCHANGE);
-
-	s3c_freq_dbg("%s: finished\n", __func__);
-	return 0;
-
- err_notpossible:
-	printk(KERN_ERR "no compatible settings for %d\n", target_freq);
-	return -EINVAL;
-}
-
-/* s3c_cpufreq_target
- *
- * called by the cpufreq core to adjust the frequency that the CPU
- * is currently running at.
- */
-
-static int s3c_cpufreq_target(struct cpufreq_policy *policy,
-			      unsigned int target_freq,
-			      unsigned int relation)
-{
-	struct cpufreq_frequency_table *pll;
-	unsigned int index;
-
-	/* avoid repeated calls which cause a needless amout of duplicated
-	 * logging output (and CPU time as the calculation process is
-	 * done) */
-	if (target_freq == last_target)
-		return 0;
-
-	last_target = target_freq;
-
-	s3c_freq_dbg("%s: policy %p, target %u, relation %u\n",
-		     __func__, policy, target_freq, relation);
-
-	if (ftab) {
-		if (cpufreq_frequency_table_target(policy, ftab,
-						   target_freq, relation,
-						   &index)) {
-			s3c_freq_dbg("%s: table failed\n", __func__);
-			return -EINVAL;
-		}
-
-		s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__,
-			     target_freq, index, ftab[index].frequency);
-		target_freq = ftab[index].frequency;
-	}
-
-	target_freq *= 1000;  /* convert target to Hz */
-
-	/* find the settings for our new frequency */
-
-	if (!pll_reg || cpu_cur.lock_pll) {
-		/* either we've not got any PLL values, or we've locked
-		 * to the current one. */
-		pll = NULL;
-	} else {
-		struct cpufreq_policy tmp_policy;
-		int ret;
-
-		/* we keep the cpu pll table in Hz, to ensure we get an
-		 * accurate value for the PLL output. */
-
-		tmp_policy.min = policy->min * 1000;
-		tmp_policy.max = policy->max * 1000;
-		tmp_policy.cpu = policy->cpu;
-
-		/* cpufreq_frequency_table_target uses a pointer to 'index'
-		 * which is the number of the table entry, not the value of
-		 * the table entry's index field. */
-
-		ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg,
-						     target_freq, relation,
-						     &index);
-
-		if (ret < 0) {
-			printk(KERN_ERR "%s: no PLL available\n", __func__);
-			goto err_notpossible;
-		}
-
-		pll = pll_reg + index;
-
-		s3c_freq_dbg("%s: target %u => %u\n",
-			     __func__, target_freq, pll->frequency);
-
-		target_freq = pll->frequency;
-	}
-
-	return s3c_cpufreq_settarget(policy, target_freq, pll);
-
- err_notpossible:
-	printk(KERN_ERR "no compatible settings for %d\n", target_freq);
-	return -EINVAL;
-}
-
-static unsigned int s3c_cpufreq_get(unsigned int cpu)
-{
-	return clk_get_rate(clk_arm) / 1000;
-}
-
-struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
-{
-	struct clk *clk;
-
-	clk = clk_get(dev, name);
-	if (IS_ERR(clk))
-		printk(KERN_ERR "cpufreq: failed to get clock '%s'\n", name);
-
-	return clk;
-}
-
-static int s3c_cpufreq_init(struct cpufreq_policy *policy)
-{
-	printk(KERN_INFO "%s: initialising policy %p\n", __func__, policy);
-
-	if (policy->cpu != 0)
-		return -EINVAL;
-
-	policy->cur = s3c_cpufreq_get(0);
-	policy->min = policy->cpuinfo.min_freq = 0;
-	policy->max = policy->cpuinfo.max_freq = cpu_cur.info->max.fclk / 1000;
-	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-
-	/* feed the latency information from the cpu driver */
-	policy->cpuinfo.transition_latency = cpu_cur.info->latency;
-
-	if (ftab)
-		cpufreq_frequency_table_cpuinfo(policy, ftab);
-
-	return 0;
-}
-
-static __init int s3c_cpufreq_initclks(void)
-{
-	_clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll");
-	_clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal");
-	clk_fclk = s3c_cpufreq_clk_get(NULL, "fclk");
-	clk_hclk = s3c_cpufreq_clk_get(NULL, "hclk");
-	clk_pclk = s3c_cpufreq_clk_get(NULL, "pclk");
-	clk_arm = s3c_cpufreq_clk_get(NULL, "armclk");
-
-	if (IS_ERR(clk_fclk) || IS_ERR(clk_hclk) || IS_ERR(clk_pclk) ||
-	    IS_ERR(_clk_mpll) || IS_ERR(clk_arm) || IS_ERR(_clk_xtal)) {
-		printk(KERN_ERR "%s: could not get clock(s)\n", __func__);
-		return -ENOENT;
-	}
-
-	printk(KERN_INFO "%s: clocks f=%lu,h=%lu,p=%lu,a=%lu\n", __func__,
-	       clk_get_rate(clk_fclk) / 1000,
-	       clk_get_rate(clk_hclk) / 1000,
-	       clk_get_rate(clk_pclk) / 1000,
-	       clk_get_rate(clk_arm) / 1000);
-
-	return 0;
-}
-
-static int s3c_cpufreq_verify(struct cpufreq_policy *policy)
-{
-	if (policy->cpu != 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static struct cpufreq_frequency_table suspend_pll;
-static unsigned int suspend_freq;
-
-static int s3c_cpufreq_suspend(struct cpufreq_policy *policy)
-{
-	suspend_pll.frequency = clk_get_rate(_clk_mpll);
-	suspend_pll.index = __raw_readl(S3C2410_MPLLCON);
-	suspend_freq = s3c_cpufreq_get(0) * 1000;
-
-	return 0;
-}
-
-static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
-{
-	int ret;
-
-	s3c_freq_dbg("%s: resuming with policy %p\n", __func__, policy);
-
-	last_target = ~0;	/* invalidate last_target setting */
-
-	/* first, find out what speed we resumed at. */
-	s3c_cpufreq_resume_clocks();
-
-	/* whilst we will be called later on, we try and re-set the
-	 * cpu frequencies as soon as possible so that we do not end
-	 * up resuming devices and then immediately having to re-set
-	 * a number of settings once these devices have restarted.
-	 *
-	 * as a note, it is expected devices are not used until they
-	 * have been un-suspended and at that time they should have
-	 * used the updated clock settings.
-	 */
-
-	ret = s3c_cpufreq_settarget(NULL, suspend_freq, &suspend_pll);
-	if (ret) {
-		printk(KERN_ERR "%s: failed to reset pll/freq\n", __func__);
-		return ret;
-	}
-
-	return 0;
-}
-#else
-#define s3c_cpufreq_resume NULL
-#define s3c_cpufreq_suspend NULL
-#endif
-
-static struct cpufreq_driver s3c24xx_driver = {
-	.flags		= CPUFREQ_STICKY,
-	.verify		= s3c_cpufreq_verify,
-	.target		= s3c_cpufreq_target,
-	.get		= s3c_cpufreq_get,
-	.init		= s3c_cpufreq_init,
-	.suspend	= s3c_cpufreq_suspend,
-	.resume		= s3c_cpufreq_resume,
-	.name		= "s3c24xx",
-};
-
-
-int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info)
-{
-	if (!info || !info->name) {
-		printk(KERN_ERR "%s: failed to pass valid information\n",
-		       __func__);
-		return -EINVAL;
-	}
-
-	printk(KERN_INFO "S3C24XX CPU Frequency driver, %s cpu support\n",
-	       info->name);
-
-	/* check our driver info has valid data */
-
-	BUG_ON(info->set_refresh == NULL);
-	BUG_ON(info->set_divs == NULL);
-	BUG_ON(info->calc_divs == NULL);
-
-	/* info->set_fvco is optional, depending on whether there
-	 * is a need to set the clock code. */
-
-	cpu_cur.info = info;
-
-	/* Note, driver registering should probably update locktime */
-
-	return 0;
-}
-
-int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
-{
-	struct s3c_cpufreq_board *ours;
-
-	if (!board) {
-		printk(KERN_INFO "%s: no board data\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Copy the board information so that each board can make this
-	 * initdata. */
-
-	ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL);
-	if (ours == NULL) {
-		printk(KERN_ERR "%s: no memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	*ours = *board;
-	cpu_cur.board = ours;
-
-	return 0;
-}
-
-int __init s3c_cpufreq_auto_io(void)
-{
-	int ret;
-
-	if (!cpu_cur.info->get_iotiming) {
-		printk(KERN_ERR "%s: get_iotiming undefined\n", __func__);
-		return -ENOENT;
-	}
-
-	printk(KERN_INFO "%s: working out IO settings\n", __func__);
-
-	ret = (cpu_cur.info->get_iotiming)(&cpu_cur, &s3c24xx_iotiming);
-	if (ret)
-		printk(KERN_ERR "%s: failed to get timings\n", __func__);
-
-	return ret;
-}
-
-/* if one or is zero, then return the other, otherwise return the min */
-#define do_min(_a, _b) ((_a) == 0 ? (_b) : (_b) == 0 ? (_a) : min(_a, _b))
-
-/**
- * s3c_cpufreq_freq_min - find the minimum settings for the given freq.
- * @dst: The destination structure
- * @a: One argument.
- * @b: The other argument.
- *
- * Create a minimum of each frequency entry in the 'struct s3c_freq',
- * unless the entry is zero when it is ignored and the non-zero argument
- * used.
- */
-static void s3c_cpufreq_freq_min(struct s3c_freq *dst,
-				 struct s3c_freq *a, struct s3c_freq *b)
-{
-	dst->fclk = do_min(a->fclk, b->fclk);
-	dst->hclk = do_min(a->hclk, b->hclk);
-	dst->pclk = do_min(a->pclk, b->pclk);
-	dst->armclk = do_min(a->armclk, b->armclk);
-}
-
-static inline u32 calc_locktime(u32 freq, u32 time_us)
-{
-	u32 result;
-
-	result = freq * time_us;
-	result = DIV_ROUND_UP(result, 1000 * 1000);
-
-	return result;
-}
-
-static void s3c_cpufreq_update_loctkime(void)
-{
-	unsigned int bits = cpu_cur.info->locktime_bits;
-	u32 rate = (u32)clk_get_rate(_clk_xtal);
-	u32 val;
-
-	if (bits == 0) {
-		WARN_ON(1);
-		return;
-	}
-
-	val = calc_locktime(rate, cpu_cur.info->locktime_u) << bits;
-	val |= calc_locktime(rate, cpu_cur.info->locktime_m);
-
-	printk(KERN_INFO "%s: new locktime is 0x%08x\n", __func__, val);
-	__raw_writel(val, S3C2410_LOCKTIME);
-}
-
-static int s3c_cpufreq_build_freq(void)
-{
-	int size, ret;
-
-	if (!cpu_cur.info->calc_freqtable)
-		return -EINVAL;
-
-	kfree(ftab);
-	ftab = NULL;
-
-	size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
-	size++;
-
-	ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL);
-	if (!ftab) {
-		printk(KERN_ERR "%s: no memory for tables\n", __func__);
-		return -ENOMEM;
-	}
-
-	ftab_size = size;
-
-	ret = cpu_cur.info->calc_freqtable(&cpu_cur, ftab, size);
-	s3c_cpufreq_addfreq(ftab, ret, size, CPUFREQ_TABLE_END);
-
-	return 0;
-}
-
-static int __init s3c_cpufreq_initcall(void)
-{
-	int ret = 0;
-
-	if (cpu_cur.info && cpu_cur.board) {
-		ret = s3c_cpufreq_initclks();
-		if (ret)
-			goto out;
-
-		/* get current settings */
-		s3c_cpufreq_getcur(&cpu_cur);
-		s3c_cpufreq_show("cur", &cpu_cur);
-
-		if (cpu_cur.board->auto_io) {
-			ret = s3c_cpufreq_auto_io();
-			if (ret) {
-				printk(KERN_ERR "%s: failed to get io timing\n",
-				       __func__);
-				goto out;
-			}
-		}
-
-		if (cpu_cur.board->need_io && !cpu_cur.info->set_iotiming) {
-			printk(KERN_ERR "%s: no IO support registered\n",
-			       __func__);
-			ret = -EINVAL;
-			goto out;
-		}
-
-		if (!cpu_cur.info->need_pll)
-			cpu_cur.lock_pll = 1;
-
-		s3c_cpufreq_update_loctkime();
-
-		s3c_cpufreq_freq_min(&cpu_cur.max, &cpu_cur.board->max,
-				     &cpu_cur.info->max);
-
-		if (cpu_cur.info->calc_freqtable)
-			s3c_cpufreq_build_freq();
-
-		ret = cpufreq_register_driver(&s3c24xx_driver);
-	}
-
- out:
-	return ret;
-}
-
-late_initcall(s3c_cpufreq_initcall);
-
-/**
- * s3c_plltab_register - register CPU PLL table.
- * @plls: The list of PLL entries.
- * @plls_no: The size of the PLL entries @plls.
- *
- * Register the given set of PLLs with the system.
- */
-int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
-			       unsigned int plls_no)
-{
-	struct cpufreq_frequency_table *vals;
-	unsigned int size;
-
-	size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1);
-
-	vals = kmalloc(size, GFP_KERNEL);
-	if (vals) {
-		memcpy(vals, plls, size);
-		pll_reg = vals;
-
-		/* write a terminating entry, we don't store it in the
-		 * table that is stored in the kernel */
-		vals += plls_no;
-		vals->frequency = CPUFREQ_TABLE_END;
-
-		printk(KERN_INFO "cpufreq: %d PLL entries\n", plls_no);
-	} else
-		printk(KERN_ERR "cpufreq: no memory for PLL tables\n");
-
-	return vals ? 0 : -ENOMEM;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-debugfs.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-debugfs.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-debugfs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2009 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX CPU Frequency scaling - debugfs status support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/cpufreq.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/err.h>
-
-#include <plat/cpu-freq-core.h>
-
-static struct dentry *dbgfs_root;
-static struct dentry *dbgfs_file_io;
-static struct dentry *dbgfs_file_info;
-static struct dentry *dbgfs_file_board;
-
-#define print_ns(x) ((x) / 10), ((x) % 10)
-
-static void show_max(struct seq_file *seq, struct s3c_freq *f)
-{
-	seq_printf(seq, "MAX: F=%lu, H=%lu, P=%lu, A=%lu\n",
-		   f->fclk, f->hclk, f->pclk, f->armclk);
-}
-
-static int board_show(struct seq_file *seq, void *p)
-{
-	struct s3c_cpufreq_config *cfg;
-	struct s3c_cpufreq_board *brd;
-
-	cfg = s3c_cpufreq_getconfig();
-	if (!cfg) {
-		seq_printf(seq, "no configuration registered\n");
-		return 0;
-	}
-
-	brd = cfg->board;
-	if (!brd) {
-		seq_printf(seq, "no board definition set?\n");
-		return 0;
-	}
-
-	seq_printf(seq, "SDRAM refresh %u ns\n", brd->refresh);
-	seq_printf(seq, "auto_io=%u\n", brd->auto_io);
-	seq_printf(seq, "need_io=%u\n", brd->need_io);
-
-	show_max(seq, &brd->max);
-
-
-	return 0;
-}
-
-static int fops_board_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, board_show, NULL);
-}
-
-static const struct file_operations fops_board = {
-	.open		= fops_board_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-	.owner		= THIS_MODULE,
-};
-
-static int info_show(struct seq_file *seq, void *p)
-{
-	struct s3c_cpufreq_config *cfg;
-
-	cfg = s3c_cpufreq_getconfig();
-	if (!cfg) {
-		seq_printf(seq, "no configuration registered\n");
-		return 0;
-	}
-
-	seq_printf(seq, "  FCLK %ld Hz\n", cfg->freq.fclk);
-	seq_printf(seq, "  HCLK %ld Hz (%lu.%lu ns)\n",
-		   cfg->freq.hclk, print_ns(cfg->freq.hclk_tns));
-	seq_printf(seq, "  PCLK %ld Hz\n", cfg->freq.hclk);
-	seq_printf(seq, "ARMCLK %ld Hz\n", cfg->freq.armclk);
-	seq_printf(seq, "\n");
-
-	show_max(seq, &cfg->max);
-
-	seq_printf(seq, "Divisors: P=%d, H=%d, A=%d, dvs=%s\n",
-		   cfg->divs.h_divisor, cfg->divs.p_divisor,
-		   cfg->divs.arm_divisor, cfg->divs.dvs ? "on" : "off");
-	seq_printf(seq, "\n");
-
-	seq_printf(seq, "lock_pll=%u\n", cfg->lock_pll);
-
-	return 0;
-}
-
-static int fops_info_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, info_show, NULL);
-}
-
-static const struct file_operations fops_info = {
-	.open		= fops_info_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-	.owner		= THIS_MODULE,
-};
-
-static int io_show(struct seq_file *seq, void *p)
-{
-	void (*show_bank)(struct seq_file *, struct s3c_cpufreq_config *, union s3c_iobank *);
-	struct s3c_cpufreq_config *cfg;
-	struct s3c_iotimings *iot;
-	union s3c_iobank *iob;
-	int bank;
-
-	cfg = s3c_cpufreq_getconfig();
-	if (!cfg) {
-		seq_printf(seq, "no configuration registered\n");
-		return 0;
-	}
-
-	show_bank = cfg->info->debug_io_show;
-	if (!show_bank) {
-		seq_printf(seq, "no code to show bank timing\n");
-		return 0;
-	}
-
-	iot = s3c_cpufreq_getiotimings();
-	if (!iot) {
-		seq_printf(seq, "no io timings registered\n");
-		return 0;
-	}
-
-	seq_printf(seq, "hclk period is %lu.%lu ns\n", print_ns(cfg->freq.hclk_tns));
-
-	for (bank = 0; bank < MAX_BANKS; bank++) {
-		iob = &iot->bank[bank];
-
-		seq_printf(seq, "bank %d: ", bank);
-
-		if (!iob->io_2410) {
-			seq_printf(seq, "nothing set\n");
-			continue;
-		}
-
-		show_bank(seq, cfg, iob);
-	}
-
-	return 0;
-}
-
-static int fops_io_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, io_show, NULL);
-}
-
-static const struct file_operations fops_io = {
-	.open		= fops_io_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-	.owner		= THIS_MODULE,
-};
-
-
-static int __init s3c_freq_debugfs_init(void)
-{
-	dbgfs_root = debugfs_create_dir("s3c-cpufreq", NULL);
-	if (IS_ERR(dbgfs_root)) {
-		printk(KERN_ERR "%s: error creating debugfs root\n", __func__);
-		return PTR_ERR(dbgfs_root);
-	}
-
-	dbgfs_file_io = debugfs_create_file("io-timing", S_IRUGO, dbgfs_root,
-					    NULL, &fops_io);
-
-	dbgfs_file_info = debugfs_create_file("info", S_IRUGO, dbgfs_root,
-					      NULL, &fops_info);
-
-	dbgfs_file_board = debugfs_create_file("board", S_IRUGO, dbgfs_root,
-					       NULL, &fops_board);
-
-	return 0;
-}
-
-late_initcall(s3c_freq_debugfs_init);
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2410.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2410.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2410.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2410.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2006-2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 CPU Frequency scaling
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/cpufreq.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/clock.h>
-#include <plat/cpu-freq-core.h>
-
-/* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */
-
-static void s3c2410_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
-{
-	u32 clkdiv = 0;
-
-	if (cfg->divs.h_divisor == 2)
-		clkdiv |= S3C2410_CLKDIVN_HDIVN;
-
-	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
-		clkdiv |= S3C2410_CLKDIVN_PDIVN;
-
-	__raw_writel(clkdiv, S3C2410_CLKDIVN);
-}
-
-static int s3c2410_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
-{
-	unsigned long hclk, fclk, pclk;
-	unsigned int hdiv, pdiv;
-	unsigned long hclk_max;
-
-	fclk = cfg->freq.fclk;
-	hclk_max = cfg->max.hclk;
-
-	cfg->freq.armclk = fclk;
-
-	s3c_freq_dbg("%s: fclk is %lu, max hclk %lu\n",
-		      __func__, fclk, hclk_max);
-
-	hdiv = (fclk > cfg->max.hclk) ? 2 : 1;
-	hclk = fclk / hdiv;
-
-	if (hclk > cfg->max.hclk) {
-		s3c_freq_dbg("%s: hclk too big\n", __func__);
-		return -EINVAL;
-	}
-
-	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
-	pclk = hclk / pdiv;
-
-	if (pclk > cfg->max.pclk) {
-		s3c_freq_dbg("%s: pclk too big\n", __func__);
-		return -EINVAL;
-	}
-
-	pdiv *= hdiv;
-
-	/* record the result */
-	cfg->divs.p_divisor = pdiv;
-	cfg->divs.h_divisor = hdiv;
-
-	return 0;
-}
-
-static struct s3c_cpufreq_info s3c2410_cpufreq_info = {
-	.max		= {
-		.fclk	= 200000000,
-		.hclk	= 100000000,
-		.pclk	=  50000000,
-	},
-
-	/* transition latency is about 5ms worst-case, so
-	 * set 10ms to be sure */
-	.latency	= 10000000,
-
-	.locktime_m	= 150,
-	.locktime_u	= 150,
-	.locktime_bits	= 12,
-
-	.need_pll	= 1,
-
-	.name		= "s3c2410",
-	.calc_iotiming	= s3c2410_iotiming_calc,
-	.set_iotiming	= s3c2410_iotiming_set,
-	.get_iotiming	= s3c2410_iotiming_get,
-	.resume_clocks	= s3c2410_setup_clocks,
-
-	.set_fvco	= s3c2410_set_fvco,
-	.set_refresh	= s3c2410_cpufreq_setrefresh,
-	.set_divs	= s3c2410_cpufreq_setdivs,
-	.calc_divs	= s3c2410_cpufreq_calcdivs,
-
-	.debug_io_show	= s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
-};
-
-static int s3c2410_cpufreq_add(struct device *dev,
-			       struct subsys_interface *sif)
-{
-	return s3c_cpufreq_register(&s3c2410_cpufreq_info);
-}
-
-static struct subsys_interface s3c2410_cpufreq_interface = {
-	.name		= "s3c2410_cpufreq",
-	.subsys		= &s3c2410_subsys,
-	.add_dev	= s3c2410_cpufreq_add,
-};
-
-static int __init s3c2410_cpufreq_init(void)
-{
-	return subsys_interface_register(&s3c2410_cpufreq_interface);
-}
-arch_initcall(s3c2410_cpufreq_init);
-
-static int s3c2410a_cpufreq_add(struct device *dev,
-				struct subsys_interface *sif)
-{
-	/* alter the maximum freq settings for S3C2410A. If a board knows
-	 * it only has a maximum of 200, then it should register its own
-	 * limits. */
-
-	s3c2410_cpufreq_info.max.fclk = 266000000;
-	s3c2410_cpufreq_info.max.hclk = 133000000;
-	s3c2410_cpufreq_info.max.pclk =  66500000;
-	s3c2410_cpufreq_info.name = "s3c2410a";
-
-	return s3c2410_cpufreq_add(dev, sif);
-}
-
-static struct subsys_interface s3c2410a_cpufreq_interface = {
-	.name		= "s3c2410a_cpufreq",
-	.subsys		= &s3c2410a_subsys,
-	.add_dev	= s3c2410a_cpufreq_add,
-};
-
-static int __init s3c2410a_cpufreq_init(void)
-{
-	return subsys_interface_register(&s3c2410a_cpufreq_interface);
-}
-arch_initcall(s3c2410a_cpufreq_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2412.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2412.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2412.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2412.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,258 +0,0 @@
-/*
- * Copyright 2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2412 CPU Frequency scalling
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/cpufreq.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/clock.h>
-#include <plat/cpu-freq-core.h>
-
-#include "s3c2412.h"
-
-/* our clock resources. */
-static struct clk *xtal;
-static struct clk *fclk;
-static struct clk *hclk;
-static struct clk *armclk;
-
-/* HDIV: 1, 2, 3, 4, 6, 8 */
-
-static int s3c2412_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
-{
-	unsigned int hdiv, pdiv, armdiv, dvs;
-	unsigned long hclk, fclk, armclk, armdiv_clk;
-	unsigned long hclk_max;
-
-	fclk = cfg->freq.fclk;
-	armclk = cfg->freq.armclk;
-	hclk_max = cfg->max.hclk;
-
-	/* We can't run hclk above armclk as at the best we have to
-	 * have armclk and hclk in dvs mode. */
-
-	if (hclk_max > armclk)
-		hclk_max = armclk;
-
-	s3c_freq_dbg("%s: fclk=%lu, armclk=%lu, hclk_max=%lu\n",
-		     __func__, fclk, armclk, hclk_max);
-	s3c_freq_dbg("%s: want f=%lu, arm=%lu, h=%lu, p=%lu\n",
-		     __func__, cfg->freq.fclk, cfg->freq.armclk,
-		     cfg->freq.hclk, cfg->freq.pclk);
-
-	armdiv = fclk / armclk;
-
-	if (armdiv < 1)
-		armdiv = 1;
-	if (armdiv > 2)
-		armdiv = 2;
-
-	cfg->divs.arm_divisor = armdiv;
-	armdiv_clk = fclk / armdiv;
-
-	hdiv = armdiv_clk / hclk_max;
-	if (hdiv < 1)
-		hdiv = 1;
-
-	cfg->freq.hclk = hclk = armdiv_clk / hdiv;
-
-	/* set dvs depending on whether we reached armclk or not. */
-	cfg->divs.dvs = dvs = armclk < armdiv_clk;
-
-	/* update the actual armclk we achieved. */
-	cfg->freq.armclk = dvs ? hclk : armdiv_clk;
-
-	s3c_freq_dbg("%s: armclk %lu, hclk %lu, armdiv %d, hdiv %d, dvs %d\n",
-		     __func__, armclk, hclk, armdiv, hdiv, cfg->divs.dvs);
-
-	if (hdiv > 4)
-		goto invalid;
-
-	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
-
-	if ((hclk / pdiv) > cfg->max.pclk)
-		pdiv++;
-
-	cfg->freq.pclk = hclk / pdiv;
-
-	s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
-
-	if (pdiv > 2)
-		goto invalid;
-
-	pdiv *= hdiv;
-
-	/* store the result, and then return */
-
-	cfg->divs.h_divisor = hdiv * armdiv;
-	cfg->divs.p_divisor = pdiv * armdiv;
-
-	return 0;
-
-invalid:
-	return -EINVAL;
-}
-
-static void s3c2412_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
-{
-	unsigned long clkdiv;
-	unsigned long olddiv;
-
-	olddiv = clkdiv = __raw_readl(S3C2410_CLKDIVN);
-
-	/* clear off current clock info */
-
-	clkdiv &= ~S3C2412_CLKDIVN_ARMDIVN;
-	clkdiv &= ~S3C2412_CLKDIVN_HDIVN_MASK;
-	clkdiv &= ~S3C2412_CLKDIVN_PDIVN;
-
-	if (cfg->divs.arm_divisor == 2)
-		clkdiv |= S3C2412_CLKDIVN_ARMDIVN;
-
-	clkdiv |= ((cfg->divs.h_divisor / cfg->divs.arm_divisor) - 1);
-
-	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
-		clkdiv |= S3C2412_CLKDIVN_PDIVN;
-
-	s3c_freq_dbg("%s: div %08lx => %08lx\n", __func__, olddiv, clkdiv);
-	__raw_writel(clkdiv, S3C2410_CLKDIVN);
-
-	clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
-}
-
-static void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
-{
-	struct s3c_cpufreq_board *board = cfg->board;
-	unsigned long refresh;
-
-	s3c_freq_dbg("%s: refresh %u ns, hclk %lu\n", __func__,
-		     board->refresh, cfg->freq.hclk);
-
-	/* Reduce both the refresh time (in ns) and the frequency (in MHz)
-	 * by 10 each to ensure that we do not overflow 32 bit numbers. This
-	 * should work for HCLK up to 133MHz and refresh period up to 30usec.
-	 */
-
-	refresh = (board->refresh / 10);
-	refresh *= (cfg->freq.hclk / 100);
-	refresh /= (1 * 1000 * 1000);	/* 10^6 */
-
-	s3c_freq_dbg("%s: setting refresh 0x%08lx\n", __func__, refresh);
-	__raw_writel(refresh, S3C2412_REFRESH);
-}
-
-/* set the default cpu frequency information, based on an 200MHz part
- * as we have no other way of detecting the speed rating in software.
- */
-
-static struct s3c_cpufreq_info s3c2412_cpufreq_info = {
-	.max		= {
-		.fclk	= 200000000,
-		.hclk	= 100000000,
-		.pclk	=  50000000,
-	},
-
-	.latency	= 5000000, /* 5ms */
-
-	.locktime_m	= 150,
-	.locktime_u	= 150,
-	.locktime_bits	= 16,
-
-	.name		= "s3c2412",
-	.set_refresh	= s3c2412_cpufreq_setrefresh,
-	.set_divs	= s3c2412_cpufreq_setdivs,
-	.calc_divs	= s3c2412_cpufreq_calcdivs,
-
-	.calc_iotiming	= s3c2412_iotiming_calc,
-	.set_iotiming	= s3c2412_iotiming_set,
-	.get_iotiming	= s3c2412_iotiming_get,
-
-	.resume_clocks	= s3c2412_setup_clocks,
-
-	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs),
-};
-
-static int s3c2412_cpufreq_add(struct device *dev,
-			       struct subsys_interface *sif)
-{
-	unsigned long fclk_rate;
-
-	hclk = clk_get(NULL, "hclk");
-	if (IS_ERR(hclk)) {
-		printk(KERN_ERR "%s: cannot find hclk clock\n", __func__);
-		return -ENOENT;
-	}
-
-	fclk = clk_get(NULL, "fclk");
-	if (IS_ERR(fclk)) {
-		printk(KERN_ERR "%s: cannot find fclk clock\n", __func__);
-		goto err_fclk;
-	}
-
-	fclk_rate = clk_get_rate(fclk);
-	if (fclk_rate > 200000000) {
-		printk(KERN_INFO
-		       "%s: fclk %ld MHz, assuming 266MHz capable part\n",
-		       __func__, fclk_rate / 1000000);
-		s3c2412_cpufreq_info.max.fclk = 266000000;
-		s3c2412_cpufreq_info.max.hclk = 133000000;
-		s3c2412_cpufreq_info.max.pclk =  66000000;
-	}
-
-	armclk = clk_get(NULL, "armclk");
-	if (IS_ERR(armclk)) {
-		printk(KERN_ERR "%s: cannot find arm clock\n", __func__);
-		goto err_armclk;
-	}
-
-	xtal = clk_get(NULL, "xtal");
-	if (IS_ERR(xtal)) {
-		printk(KERN_ERR "%s: cannot find xtal clock\n", __func__);
-		goto err_xtal;
-	}
-
-	return s3c_cpufreq_register(&s3c2412_cpufreq_info);
-
-err_xtal:
-	clk_put(armclk);
-err_armclk:
-	clk_put(fclk);
-err_fclk:
-	clk_put(hclk);
-
-	return -ENOENT;
-}
-
-static struct subsys_interface s3c2412_cpufreq_interface = {
-	.name		= "s3c2412_cpufreq",
-	.subsys		= &s3c2412_subsys,
-	.add_dev	= s3c2412_cpufreq_add,
-};
-
-static int s3c2412_cpufreq_init(void)
-{
-	return subsys_interface_register(&s3c2412_cpufreq_interface);
-}
-arch_initcall(s3c2412_cpufreq_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2440.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2440.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2440.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-s3c2440.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,312 +0,0 @@
-/*
- * Copyright (c) 2006-2009 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *	Vincent Sanders <vince@simtec.co.uk>
- *
- * S3C2440/S3C2442 CPU Frequency scaling
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/cpufreq.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/cpu.h>
-#include <plat/cpu-freq-core.h>
-#include <plat/clock.h>
-
-static struct clk *xtal;
-static struct clk *fclk;
-static struct clk *hclk;
-static struct clk *armclk;
-
-/* HDIV: 1, 2, 3, 4, 6, 8 */
-
-static inline int within_khz(unsigned long a, unsigned long b)
-{
-	long diff = a - b;
-
-	return (diff >= -1000 && diff <= 1000);
-}
-
-/**
- * s3c2440_cpufreq_calcdivs - calculate divider settings
- * @cfg: The cpu frequency settings.
- *
- * Calcualte the divider values for the given frequency settings
- * specified in @cfg. The values are stored in @cfg for later use
- * by the relevant set routine if the request settings can be reached.
- */
-int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
-{
-	unsigned int hdiv, pdiv;
-	unsigned long hclk, fclk, armclk;
-	unsigned long hclk_max;
-
-	fclk = cfg->freq.fclk;
-	armclk = cfg->freq.armclk;
-	hclk_max = cfg->max.hclk;
-
-	s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n",
-		     __func__, fclk, armclk, hclk_max);
-
-	if (armclk > fclk) {
-		printk(KERN_WARNING "%s: armclk > fclk\n", __func__);
-		armclk = fclk;
-	}
-
-	/* if we are in DVS, we need HCLK to be <= ARMCLK */
-	if (armclk < fclk && armclk < hclk_max)
-		hclk_max = armclk;
-
-	for (hdiv = 1; hdiv < 9; hdiv++) {
-		if (hdiv == 5 || hdiv == 7)
-			hdiv++;
-
-		hclk = (fclk / hdiv);
-		if (hclk <= hclk_max || within_khz(hclk, hclk_max))
-			break;
-	}
-
-	s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv);
-
-	if (hdiv > 8)
-		goto invalid;
-
-	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
-
-	if ((hclk / pdiv) > cfg->max.pclk)
-		pdiv++;
-
-	s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
-
-	if (pdiv > 2)
-		goto invalid;
-
-	pdiv *= hdiv;
-
-	/* calculate a valid armclk */
-
-	if (armclk < hclk)
-		armclk = hclk;
-
-	/* if we're running armclk lower than fclk, this really means
-	 * that the system should go into dvs mode, which means that
-	 * armclk is connected to hclk. */
-	if (armclk < fclk) {
-		cfg->divs.dvs = 1;
-		armclk = hclk;
-	} else
-		cfg->divs.dvs = 0;
-
-	cfg->freq.armclk = armclk;
-
-	/* store the result, and then return */
-
-	cfg->divs.h_divisor = hdiv;
-	cfg->divs.p_divisor = pdiv;
-
-	return 0;
-
- invalid:
-	return -EINVAL;
-}
-
-#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \
-			   S3C2440_CAMDIVN_HCLK4_HALF)
-
-/**
- * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings
- * @cfg: The cpu frequency settings.
- *
- * Set the divisors from the settings in @cfg, which where generated
- * during the calculation phase by s3c2440_cpufreq_calcdivs().
- */
-static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
-{
-	unsigned long clkdiv, camdiv;
-
-	s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__,
-		     cfg->divs.h_divisor, cfg->divs.p_divisor);
-
-	clkdiv = __raw_readl(S3C2410_CLKDIVN);
-	camdiv = __raw_readl(S3C2440_CAMDIVN);
-
-	clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN);
-	camdiv &= ~CAMDIVN_HCLK_HALF;
-
-	switch (cfg->divs.h_divisor) {
-	case 1:
-		clkdiv |= S3C2440_CLKDIVN_HDIVN_1;
-		break;
-
-	case 2:
-		clkdiv |= S3C2440_CLKDIVN_HDIVN_2;
-		break;
-
-	case 6:
-		camdiv |= S3C2440_CAMDIVN_HCLK3_HALF;
-	case 3:
-		clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6;
-		break;
-
-	case 8:
-		camdiv |= S3C2440_CAMDIVN_HCLK4_HALF;
-	case 4:
-		clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8;
-		break;
-
-	default:
-		BUG();	/* we don't expect to get here. */
-	}
-
-	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
-		clkdiv |= S3C2440_CLKDIVN_PDIVN;
-
-	/* todo - set pclk. */
-
-	/* Write the divisors first with hclk intentionally halved so that
-	 * when we write clkdiv we will under-frequency instead of over. We
-	 * then make a short delay and remove the hclk halving if necessary.
-	 */
-
-	__raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN);
-	__raw_writel(clkdiv, S3C2410_CLKDIVN);
-
-	ndelay(20);
-	__raw_writel(camdiv, S3C2440_CAMDIVN);
-
-	clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
-}
-
-static int run_freq_for(unsigned long max_hclk, unsigned long fclk,
-			int *divs,
-			struct cpufreq_frequency_table *table,
-			size_t table_size)
-{
-	unsigned long freq;
-	int index = 0;
-	int div;
-
-	for (div = *divs; div > 0; div = *divs++) {
-		freq = fclk / div;
-
-		if (freq > max_hclk && div != 1)
-			continue;
-
-		freq /= 1000; /* table is in kHz */
-		index = s3c_cpufreq_addfreq(table, index, table_size, freq);
-		if (index < 0)
-			break;
-	}
-
-	return index;
-}
-
-static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 };
-
-static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg,
-				     struct cpufreq_frequency_table *table,
-				     size_t table_size)
-{
-	int ret;
-
-	WARN_ON(cfg->info == NULL);
-	WARN_ON(cfg->board == NULL);
-
-	ret = run_freq_for(cfg->info->max.hclk,
-			   cfg->info->max.fclk,
-			   hclk_divs,
-			   table, table_size);
-
-	s3c_freq_dbg("%s: returning %d\n", __func__, ret);
-
-	return ret;
-}
-
-struct s3c_cpufreq_info s3c2440_cpufreq_info = {
-	.max		= {
-		.fclk	= 400000000,
-		.hclk	= 133333333,
-		.pclk	=  66666666,
-	},
-
-	.locktime_m	= 300,
-	.locktime_u	= 300,
-	.locktime_bits	= 16,
-
-	.name		= "s3c244x",
-	.calc_iotiming	= s3c2410_iotiming_calc,
-	.set_iotiming	= s3c2410_iotiming_set,
-	.get_iotiming	= s3c2410_iotiming_get,
-	.set_fvco	= s3c2410_set_fvco,
-
-	.set_refresh	= s3c2410_cpufreq_setrefresh,
-	.set_divs	= s3c2440_cpufreq_setdivs,
-	.calc_divs	= s3c2440_cpufreq_calcdivs,
-	.calc_freqtable	= s3c2440_cpufreq_calctable,
-
-	.resume_clocks	= s3c244x_setup_clocks,
-
-	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
-};
-
-static int s3c2440_cpufreq_add(struct device *dev,
-			       struct subsys_interface *sif)
-{
-	xtal = s3c_cpufreq_clk_get(NULL, "xtal");
-	hclk = s3c_cpufreq_clk_get(NULL, "hclk");
-	fclk = s3c_cpufreq_clk_get(NULL, "fclk");
-	armclk = s3c_cpufreq_clk_get(NULL, "armclk");
-
-	if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) {
-		printk(KERN_ERR "%s: failed to get clocks\n", __func__);
-		return -ENOENT;
-	}
-
-	return s3c_cpufreq_register(&s3c2440_cpufreq_info);
-}
-
-static struct subsys_interface s3c2440_cpufreq_interface = {
-	.name		= "s3c2440_cpufreq",
-	.subsys		= &s3c2440_subsys,
-	.add_dev	= s3c2440_cpufreq_add,
-};
-
-static int s3c2440_cpufreq_init(void)
-{
-	return subsys_interface_register(&s3c2440_cpufreq_interface);
-}
-
-/* arch_initcall adds the clocks we need, so use subsys_initcall. */
-subsys_initcall(s3c2440_cpufreq_init);
-
-static struct subsys_interface s3c2442_cpufreq_interface = {
-	.name		= "s3c2442_cpufreq",
-	.subsys		= &s3c2442_subsys,
-	.add_dev	= s3c2440_cpufreq_add,
-};
-
-static int s3c2442_cpufreq_init(void)
-{
-	return subsys_interface_register(&s3c2442_cpufreq_interface);
-}
-subsys_initcall(s3c2442_cpufreq_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-utils.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-utils.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/cpufreq-utils.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/cpufreq-utils.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,5 +60,5 @@ void s3c2410_cpufreq_setrefresh(struct s
  */
 void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
 {
-	__raw_writel(cfg->pll.index, S3C2410_MPLLCON);
+	__raw_writel(cfg->pll.driver_data, S3C2410_MPLLCON);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/dma.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/dma.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -1159,9 +1159,6 @@ int s3c2410_dma_devconfig(enum dma_ch ch
 		return -EINVAL;
 	}
 
-	if (dma_sel.direction != NULL)
-		(dma_sel.direction)(chan, chan->map, source);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/dma-s3c2412.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/dma-s3c2412.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/dma-s3c2412.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/dma-s3c2412.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,121 +35,95 @@ static struct s3c24xx_dma_map __initdata
 	[DMACH_XD0] = {
 		.name		= "xdreq0",
 		.channels	= MAP(S3C2412_DMAREQSEL_XDREQ0),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_XDREQ0),
 	},
 	[DMACH_XD1] = {
 		.name		= "xdreq1",
 		.channels	= MAP(S3C2412_DMAREQSEL_XDREQ1),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_XDREQ1),
 	},
 	[DMACH_SDI] = {
 		.name		= "sdi",
 		.channels	= MAP(S3C2412_DMAREQSEL_SDI),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_SDI),
 	},
-	[DMACH_SPI0] = {
-		.name		= "spi0",
+	[DMACH_SPI0_RX] = {
+		.name		= "spi0-rx",
+		.channels	= MAP(S3C2412_DMAREQSEL_SPI0RX),
+	},
+	[DMACH_SPI0_TX] = {
+		.name		= "spi0-tx",
 		.channels	= MAP(S3C2412_DMAREQSEL_SPI0TX),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_SPI0RX),
 	},
-	[DMACH_SPI1] = {
-		.name		= "spi1",
+	[DMACH_SPI1_RX] = {
+		.name		= "spi1-rx",
+		.channels	= MAP(S3C2412_DMAREQSEL_SPI1RX),
+	},
+	[DMACH_SPI1_TX] = {
+		.name		= "spi1-tx",
 		.channels	= MAP(S3C2412_DMAREQSEL_SPI1TX),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_SPI1RX),
 	},
 	[DMACH_UART0] = {
 		.name		= "uart0",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART0_0),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART0_0),
 	},
 	[DMACH_UART1] = {
 		.name		= "uart1",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART1_0),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART1_0),
 	},
       	[DMACH_UART2] = {
 		.name		= "uart2",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART2_0),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART2_0),
 	},
 	[DMACH_UART0_SRC2] = {
 		.name		= "uart0",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART0_1),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART0_1),
 	},
 	[DMACH_UART1_SRC2] = {
 		.name		= "uart1",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART1_1),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART1_1),
 	},
       	[DMACH_UART2_SRC2] = {
 		.name		= "uart2",
 		.channels	= MAP(S3C2412_DMAREQSEL_UART2_1),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_UART2_1),
 	},
 	[DMACH_TIMER] = {
 		.name		= "timer",
 		.channels	= MAP(S3C2412_DMAREQSEL_TIMER),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_TIMER),
 	},
 	[DMACH_I2S_IN] = {
 		.name		= "i2s-sdi",
 		.channels	= MAP(S3C2412_DMAREQSEL_I2SRX),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_I2SRX),
 	},
 	[DMACH_I2S_OUT] = {
 		.name		= "i2s-sdo",
 		.channels	= MAP(S3C2412_DMAREQSEL_I2STX),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_I2STX),
 	},
 	[DMACH_USB_EP1] = {
 		.name		= "usb-ep1",
 		.channels	= MAP(S3C2412_DMAREQSEL_USBEP1),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_USBEP1),
 	},
 	[DMACH_USB_EP2] = {
 		.name		= "usb-ep2",
 		.channels	= MAP(S3C2412_DMAREQSEL_USBEP2),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_USBEP2),
 	},
 	[DMACH_USB_EP3] = {
 		.name		= "usb-ep3",
 		.channels	= MAP(S3C2412_DMAREQSEL_USBEP3),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_USBEP3),
 	},
 	[DMACH_USB_EP4] = {
 		.name		= "usb-ep4",
 		.channels	= MAP(S3C2412_DMAREQSEL_USBEP4),
-		.channels_rx	= MAP(S3C2412_DMAREQSEL_USBEP4),
 	},
 };
 
-static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
-				  struct s3c24xx_dma_map *map,
-				  enum dma_data_direction dir)
-{
-	unsigned long chsel;
-
-	if (dir == DMA_FROM_DEVICE)
-		chsel = map->channels_rx[0];
-	else
-		chsel = map->channels[0];
-
-	chsel &= ~DMA_CH_VALID;
-	chsel |= S3C2412_DMAREQSEL_HW;
-
-	writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL);
-}
-
 static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
 			       struct s3c24xx_dma_map *map)
 {
-	s3c2412_dma_direction(chan, map, chan->source);
+	unsigned long chsel = map->channels[0] & (~DMA_CH_VALID);
+	writel(chsel | S3C2412_DMAREQSEL_HW,
+	       chan->regs + S3C2412_DMA_DMAREQSEL);
 }
 
 static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
 	.select		= s3c2412_dma_select,
-	.direction	= s3c2412_dma_direction,
 	.dcon_mask	= 0,
 	.map		= s3c2412_dma_mappings,
 	.map_size	= ARRAY_SIZE(s3c2412_dma_mappings),
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/dma-s3c2443.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/dma-s3c2443.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/dma-s3c2443.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/dma-s3c2443.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,7 +128,8 @@ static struct s3c24xx_dma_map __initdata
 static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
 			       struct s3c24xx_dma_map *map)
 {
-	writel(map->channels[0] | S3C2443_DMAREQSEL_HW,
+	unsigned long chsel = map->channels[0] & (~DMA_CH_VALID);
+	writel(chsel | S3C2443_DMAREQSEL_HW,
 	       chan->regs + S3C2443_DMA_DMAREQSEL);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/include/mach/s3c2412.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/include/mach/s3c2412.h
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/include/mach/s3c2412.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/include/mach/s3c2412.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_H
+#define __ARCH_ARM_REGS_S3C24XX_S3C2412_H __FILE__
+
+#define S3C2412_MEMREG(x)		(S3C24XX_VA_MEMCTRL + (x))
+#define S3C2412_EBIREG(x)		(S3C2412_VA_EBI + (x))
+
+#define S3C2412_SSMCREG(x)		(S3C2412_VA_SSMC + (x))
+#define S3C2412_SSMC(x, o)		(S3C2412_SSMCREG((x * 0x20) + (o)))
+
+#define S3C2412_REFRESH			S3C2412_MEMREG(0x10)
+
+#define S3C2412_EBI_BANKCFG		S3C2412_EBIREG(0x4)
+
+#define S3C2412_SSMC_BANK(x)		S3C2412_SSMC(x, 0x0)
+
+#endif /* __ARCH_ARM_MACH_S3C24XX_S3C2412_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/include/mach/uncompress.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/include/mach/uncompress.h
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/include/mach/uncompress.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/include/mach/uncompress.h	2013-08-25 20:43:22.000000000 -0400
@@ -49,6 +49,9 @@ static void arch_detect_cpu(void)
 		fifo_mask = S3C2410_UFSTAT_TXMASK;
 		fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT;
 	}
+
+	uart_base = (volatile u8 *) S3C_PA_UART +
+		(S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
 }
 
 #endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/iotiming-s3c2412.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/iotiming-s3c2412.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/iotiming-s3c2412.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/iotiming-s3c2412.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,7 @@
 #include <plat/cpu-freq-core.h>
 #include <plat/clock.h>
 
-#include "s3c2412.h"
+#include <mach/s3c2412.h>
 
 #define print_ns(x) ((x) / 10), ((x) % 10)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -28,9 +28,10 @@ config CPU_S3C2410
 	select CPU_ARM920T
 	select CPU_LLSERIAL_S3C2410
 	select S3C2410_CLOCK
-	select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
+	select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
 	select S3C2410_PM if PM
 	select SAMSUNG_HRT
+	select SAMSUNG_WDT_RESET
 	help
 	  Support for S3C2410 and S3C2410A family from the S3C24XX line
 	  of Samsung Mobile CPUs.
@@ -81,6 +82,7 @@ config CPU_S3C2442
 config CPU_S3C244X
 	def_bool y
 	depends on CPU_S3C2440 || CPU_S3C2442
+	select SAMSUNG_WDT_RESET
 
 config CPU_S3C2443
 	bool "SAMSUNG S3C2443"
@@ -204,27 +206,38 @@ config S3C24XX_GPIO_EXTRA128
 	  Add an extra 128 gpio numbers to the available GPIO pool. This is
 	  available for boards that need extra gpios for external devices.
 
+config S3C24XX_PLL
+	bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
+	depends on ARM_S3C24XX_CPUFREQ
+	help
+	  Compile in support for changing the PLL frequency from the
+	  S3C24XX series CPUfreq driver. The PLL takes time to settle
+	  after a frequency change, so by default it is not enabled.
+
+	  This also means that the PLL tables for the selected CPU(s) will
+	  be built which may increase the size of the kernel image.
+
 # cpu frequency items common between s3c2410 and s3c2440/s3c2442
 
 config S3C2410_IOTIMING
 	bool
-	depends on CPU_FREQ_S3C24XX
+	depends on ARM_S3C24XX_CPUFREQ
 	help
 	  Internal node to select io timing code that is common to the s3c2410
 	  and s3c2440/s3c2442 cpu frequency support.
 
 config S3C2410_CPUFREQ_UTILS
-	bool
-	depends on CPU_FREQ_S3C24XX
-	help
-	  Internal node to select timing code that is common to the s3c2410
-	  and s3c2440/s3c244 cpu frequency support.
+       bool
+       depends on ARM_S3C24XX_CPUFREQ
+       help
+         Internal node to select timing code that is common to the s3c2410
+         and s3c2440/s3c244 cpu frequency support.
 
 # cpu frequency support common to s3c2412, s3c2413 and s3c2442
 
 config S3C2412_IOTIMING
 	bool
-	depends on CPU_FREQ_S3C24XX && (CPU_S3C2412 || CPU_S3C2443)
+	depends on ARM_S3C24XX_CPUFREQ && (CPU_S3C2412 || CPU_S3C2443)
 	help
 	  Intel node to select io timing code that is common to the s3c2412
 	  and the s3c2443.
@@ -233,16 +246,9 @@ config S3C2412_IOTIMING
 
 if CPU_S3C2410
 
-config S3C2410_CPUFREQ
-	bool
-	depends on CPU_FREQ_S3C24XX
-	select S3C2410_CPUFREQ_UTILS
-	help
-	  CPU Frequency scaling support for S3C2410
-
 config S3C2410_PLL
 	bool
-	depends on S3C2410_CPUFREQ && CPU_FREQ_S3C24XX_PLL
+	depends on ARM_S3C2410_CPUFREQ && S3C24XX_PLL
 	default y
 	help
 	  Select the PLL table for the S3C2410
@@ -278,7 +284,7 @@ config ARCH_BAST
 	bool "Simtec Electronics BAST (EB2410ITX)"
 	select ISA
 	select MACH_BAST_IDE
-	select S3C2410_IOTIMING if S3C2410_CPUFREQ
+	select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ
 	select S3C24XX_DCLK
 	select S3C24XX_SIMTEC_NOR
 	select S3C24XX_SIMTEC_PM if PM
@@ -385,14 +391,6 @@ config CPU_S3C2412_ONLY
 		   !CPU_S3C2442 && !CPU_S3C2443
 	default y
 
-config S3C2412_CPUFREQ
-	bool
-	depends on CPU_FREQ_S3C24XX
-	default y
-	select S3C2412_IOTIMING
-	help
-	  CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
-
 config S3C2412_DMA
 	bool
 	help
@@ -490,18 +488,22 @@ config MACH_SMDK2416
 	help
 	  Say Y here if you are using an SMDK2416
 
+config MACH_S3C2416_DT
+	bool "Samsung S3C2416 machine using devicetree"
+	select CLKSRC_OF
+	select USE_OF
+	select PINCTRL
+	select PINCTRL_S3C24XX
+	help
+	  Machine support for Samsung S3C2416 machines with device tree enabled.
+	  Select this if a fdt blob is available for the S3C2416 SoC based board.
+	  Note: This is under development and not all peripherals can be supported
+	  with this machine file.
+
 endif	# CPU_S3C2416
 
 if CPU_S3C2440
 
-config S3C2440_CPUFREQ
-	bool "S3C2440/S3C2442 CPU Frequency scaling support"
-	depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
-	default y
-	select S3C2410_CPUFREQ_UTILS
-	help
-	  CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
-
 config S3C2440_DMA
 	bool
 	help
@@ -521,15 +523,15 @@ config S3C2440_XTAL_16934400
 
 config S3C2440_PLL_12000000
 	bool
-	depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000
-	default y if CPU_FREQ_S3C24XX_PLL
+	depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_12000000
+	default y if S3C24XX_PLL
 	help
 	  PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
 
 config S3C2440_PLL_16934400
 	bool
-	depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400
-	default y if CPU_FREQ_S3C24XX_PLL
+	depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_16934400
+	default y if S3C24XX_PLL
 	help
 	  PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
 
@@ -583,7 +585,7 @@ config MACH_NEXCODER_2440
 
 config MACH_OSIRIS
 	bool "Simtec IM2440D20 (OSIRIS) module"
-	select S3C2410_IOTIMING if S3C2440_CPUFREQ
+	select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
 	select S3C2440_XTAL_12000000
 	select S3C24XX_DCLK
 	select S3C24XX_GPIO_EXTRA128
@@ -655,7 +657,7 @@ config MACH_RX1950
 	bool "HP iPAQ rx1950"
 	select I2C
 	select PM_H1940 if PM
-	select S3C2410_IOTIMING if S3C2440_CPUFREQ
+	select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
 	select S3C2440_XTAL_16934400
 	select S3C24XX_DCLK
 	select S3C24XX_PWM
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/mach-s3c2416-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,91 @@
+/*
+ * Samsung's S3C2416 flattened device tree enabled machine
+ *
+ * Copyright (c) 2012 Heiko Stuebner <heiko@sntech.de>
+ *
+ * based on mach-exynos/mach-exynos4-dt.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2010-2011 Linaro Ltd.
+ *		www.linaro.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/clocksource.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/regs-serial.h>
+
+#include "common.h"
+
+/*
+ * The following lookup table is used to override device names when devices
+ * are registered from device tree. This is temporarily added to enable
+ * device tree support addition for the S3C2416 architecture.
+ *
+ * For drivers that require platform data to be provided from the machine
+ * file, a platform data pointer can also be supplied along with the
+ * devices names. Usually, the platform data elements that cannot be parsed
+ * from the device tree by the drivers (example: function pointers) are
+ * supplied. But it should be noted that this is a temporary mechanism and
+ * at some point, the drivers should be capable of parsing all the platform
+ * data from the device tree.
+ */
+static const struct of_dev_auxdata s3c2416_auxdata_lookup[] __initconst = {
+	OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C24XX_PA_UART,
+				"s3c2440-uart.0", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C24XX_PA_UART + 0x4000,
+				"s3c2440-uart.1", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C24XX_PA_UART + 0x8000,
+				"s3c2440-uart.2", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-uart", S3C24XX_PA_UART + 0xC000,
+				"s3c2440-uart.3", NULL),
+	OF_DEV_AUXDATA("samsung,s3c6410-sdhci", S3C_PA_HSMMC0,
+				"s3c-sdhci.0", NULL),
+	OF_DEV_AUXDATA("samsung,s3c6410-sdhci", S3C_PA_HSMMC1,
+				"s3c-sdhci.1", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-i2c", S3C_PA_IIC,
+				"s3c2440-i2c.0", NULL),
+	{},
+};
+
+static void __init s3c2416_dt_map_io(void)
+{
+	s3c24xx_init_io(NULL, 0);
+	s3c24xx_init_clocks(12000000);
+}
+
+static void __init s3c2416_dt_machine_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table,
+				s3c2416_auxdata_lookup, NULL);
+
+	s3c_pm_init();
+}
+
+static char const *s3c2416_dt_compat[] __initdata = {
+	"samsung,s3c2416",
+	"samsung,s3c2450",
+	NULL
+};
+
+DT_MACHINE_START(S3C2416_DT, "Samsung S3C2416 (Flattened Device Tree)")
+	/* Maintainer: Heiko Stuebner <heiko@sntech.de> */
+	.dt_compat	= s3c2416_dt_compat,
+	.map_io		= s3c2416_dt_map_io,
+	.init_irq	= irqchip_init,
+	.init_machine	= s3c2416_dt_machine_init,
+	 .init_time	= clocksource_of_init,
+	.restart	= s3c2416_restart,
+MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -17,13 +17,11 @@ obj-				:=
 obj-y				+= common.o
 
 obj-$(CONFIG_CPU_S3C2410)	+= s3c2410.o
-obj-$(CONFIG_S3C2410_CPUFREQ)	+= cpufreq-s3c2410.o
 obj-$(CONFIG_S3C2410_DMA)	+= dma-s3c2410.o
 obj-$(CONFIG_S3C2410_PLL)	+= pll-s3c2410.o
 obj-$(CONFIG_S3C2410_PM)	+= pm-s3c2410.o sleep-s3c2410.o
 
 obj-$(CONFIG_CPU_S3C2412)	+= s3c2412.o clock-s3c2412.o
-obj-$(CONFIG_S3C2412_CPUFREQ)	+= cpufreq-s3c2412.o
 obj-$(CONFIG_S3C2412_DMA)	+= dma-s3c2412.o
 obj-$(CONFIG_S3C2412_PM)	+= pm-s3c2412.o
 obj-$(CONFIG_S3C2412_PM_SLEEP)	+= sleep-s3c2412.o
@@ -34,7 +32,6 @@ obj-$(CONFIG_S3C2416_PM)	+= pm-s3c2416.o
 obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o clock-s3c2440.o
 obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
 obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o clock-s3c244x.o
-obj-$(CONFIG_S3C2440_CPUFREQ)	+= cpufreq-s3c2440.o
 obj-$(CONFIG_S3C2440_DMA)	+= dma-s3c2440.o
 obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
 obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
@@ -59,9 +56,6 @@ obj-$(CONFIG_S3C2412_IOTIMING)	+= iotimi
 obj-$(CONFIG_S3C2443_COMMON)	+= common-s3c2443.o
 obj-$(CONFIG_S3C2443_DMA)	+= dma-s3c2443.o
 
-obj-$(CONFIG_CPU_FREQ_S3C24XX)	+= cpufreq.o
-obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpufreq-debugfs.o
-
 #
 # machine support
 # following is ordered alphabetically by option text.
@@ -85,6 +79,7 @@ obj-$(CONFIG_MACH_SMDK2413)		+= mach-smd
 obj-$(CONFIG_MACH_VSTMS)		+= mach-vstms.o
 
 obj-$(CONFIG_MACH_SMDK2416)		+= mach-smdk2416.o
+obj-$(CONFIG_MACH_S3C2416_DT)		+= mach-s3c2416-dt.o
 
 obj-$(CONFIG_MACH_ANUBIS)		+= mach-anubis.o
 obj-$(CONFIG_MACH_AT2440EVB)		+= mach-at2440evb.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/pll-s3c2410.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/pll-s3c2410.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/pll-s3c2410.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/pll-s3c2410.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,36 +33,36 @@
 #include <plat/cpu-freq-core.h>
 
 static struct cpufreq_frequency_table pll_vals_12MHz[] = {
-    { .frequency = 34000000,  .index = PLLVAL(82, 2, 3),   },
-    { .frequency = 45000000,  .index = PLLVAL(82, 1, 3),   },
-    { .frequency = 51000000,  .index = PLLVAL(161, 3, 3),  },
-    { .frequency = 48000000,  .index = PLLVAL(120, 2, 3),  },
-    { .frequency = 56000000,  .index = PLLVAL(142, 2, 3),  },
-    { .frequency = 68000000,  .index = PLLVAL(82, 2, 2),   },
-    { .frequency = 79000000,  .index = PLLVAL(71, 1, 2),   },
-    { .frequency = 85000000,  .index = PLLVAL(105, 2, 2),  },
-    { .frequency = 90000000,  .index = PLLVAL(112, 2, 2),  },
-    { .frequency = 101000000, .index = PLLVAL(127, 2, 2),  },
-    { .frequency = 113000000, .index = PLLVAL(105, 1, 2),  },
-    { .frequency = 118000000, .index = PLLVAL(150, 2, 2),  },
-    { .frequency = 124000000, .index = PLLVAL(116, 1, 2),  },
-    { .frequency = 135000000, .index = PLLVAL(82, 2, 1),   },
-    { .frequency = 147000000, .index = PLLVAL(90, 2, 1),   },
-    { .frequency = 152000000, .index = PLLVAL(68, 1, 1),   },
-    { .frequency = 158000000, .index = PLLVAL(71, 1, 1),   },
-    { .frequency = 170000000, .index = PLLVAL(77, 1, 1),   },
-    { .frequency = 180000000, .index = PLLVAL(82, 1, 1),   },
-    { .frequency = 186000000, .index = PLLVAL(85, 1, 1),   },
-    { .frequency = 192000000, .index = PLLVAL(88, 1, 1),   },
-    { .frequency = 203000000, .index = PLLVAL(161, 3, 1),  },
+    { .frequency = 34000000,  .driver_data = PLLVAL(82, 2, 3),   },
+    { .frequency = 45000000,  .driver_data = PLLVAL(82, 1, 3),   },
+    { .frequency = 51000000,  .driver_data = PLLVAL(161, 3, 3),  },
+    { .frequency = 48000000,  .driver_data = PLLVAL(120, 2, 3),  },
+    { .frequency = 56000000,  .driver_data = PLLVAL(142, 2, 3),  },
+    { .frequency = 68000000,  .driver_data = PLLVAL(82, 2, 2),   },
+    { .frequency = 79000000,  .driver_data = PLLVAL(71, 1, 2),   },
+    { .frequency = 85000000,  .driver_data = PLLVAL(105, 2, 2),  },
+    { .frequency = 90000000,  .driver_data = PLLVAL(112, 2, 2),  },
+    { .frequency = 101000000, .driver_data = PLLVAL(127, 2, 2),  },
+    { .frequency = 113000000, .driver_data = PLLVAL(105, 1, 2),  },
+    { .frequency = 118000000, .driver_data = PLLVAL(150, 2, 2),  },
+    { .frequency = 124000000, .driver_data = PLLVAL(116, 1, 2),  },
+    { .frequency = 135000000, .driver_data = PLLVAL(82, 2, 1),   },
+    { .frequency = 147000000, .driver_data = PLLVAL(90, 2, 1),   },
+    { .frequency = 152000000, .driver_data = PLLVAL(68, 1, 1),   },
+    { .frequency = 158000000, .driver_data = PLLVAL(71, 1, 1),   },
+    { .frequency = 170000000, .driver_data = PLLVAL(77, 1, 1),   },
+    { .frequency = 180000000, .driver_data = PLLVAL(82, 1, 1),   },
+    { .frequency = 186000000, .driver_data = PLLVAL(85, 1, 1),   },
+    { .frequency = 192000000, .driver_data = PLLVAL(88, 1, 1),   },
+    { .frequency = 203000000, .driver_data = PLLVAL(161, 3, 1),  },
 
     /* 2410A extras */
 
-    { .frequency = 210000000, .index = PLLVAL(132, 2, 1),  },
-    { .frequency = 226000000, .index = PLLVAL(105, 1, 1),  },
-    { .frequency = 266000000, .index = PLLVAL(125, 1, 1),  },
-    { .frequency = 268000000, .index = PLLVAL(126, 1, 1),  },
-    { .frequency = 270000000, .index = PLLVAL(127, 1, 1),  },
+    { .frequency = 210000000, .driver_data = PLLVAL(132, 2, 1),  },
+    { .frequency = 226000000, .driver_data = PLLVAL(105, 1, 1),  },
+    { .frequency = 266000000, .driver_data = PLLVAL(125, 1, 1),  },
+    { .frequency = 268000000, .driver_data = PLLVAL(126, 1, 1),  },
+    { .frequency = 270000000, .driver_data = PLLVAL(127, 1, 1),  },
 };
 
 static int s3c2410_plls_add(struct device *dev, struct subsys_interface *sif)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/pll-s3c2440-12000000.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,33 +21,33 @@
 #include <plat/cpu-freq-core.h>
 
 static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
-	{ .frequency = 75000000,	.index = PLLVAL(0x75, 3, 3),  }, 	/* FVco 600.000000 */
-	{ .frequency = 80000000,	.index = PLLVAL(0x98, 4, 3),  }, 	/* FVco 640.000000 */
-	{ .frequency = 90000000,	.index = PLLVAL(0x70, 2, 3),  }, 	/* FVco 720.000000 */
-	{ .frequency = 100000000,	.index = PLLVAL(0x5c, 1, 3),  }, 	/* FVco 800.000000 */
-	{ .frequency = 110000000,	.index = PLLVAL(0x66, 1, 3),  }, 	/* FVco 880.000000 */
-	{ .frequency = 120000000,	.index = PLLVAL(0x70, 1, 3),  }, 	/* FVco 960.000000 */
-	{ .frequency = 150000000,	.index = PLLVAL(0x75, 3, 2),  }, 	/* FVco 600.000000 */
-	{ .frequency = 160000000,	.index = PLLVAL(0x98, 4, 2),  }, 	/* FVco 640.000000 */
-	{ .frequency = 170000000,	.index = PLLVAL(0x4d, 1, 2),  }, 	/* FVco 680.000000 */
-	{ .frequency = 180000000,	.index = PLLVAL(0x70, 2, 2),  }, 	/* FVco 720.000000 */
-	{ .frequency = 190000000,	.index = PLLVAL(0x57, 1, 2),  }, 	/* FVco 760.000000 */
-	{ .frequency = 200000000,	.index = PLLVAL(0x5c, 1, 2),  }, 	/* FVco 800.000000 */
-	{ .frequency = 210000000,	.index = PLLVAL(0x84, 2, 2),  }, 	/* FVco 840.000000 */
-	{ .frequency = 220000000,	.index = PLLVAL(0x66, 1, 2),  }, 	/* FVco 880.000000 */
-	{ .frequency = 230000000,	.index = PLLVAL(0x6b, 1, 2),  }, 	/* FVco 920.000000 */
-	{ .frequency = 240000000,	.index = PLLVAL(0x70, 1, 2),  }, 	/* FVco 960.000000 */
-	{ .frequency = 300000000,	.index = PLLVAL(0x75, 3, 1),  }, 	/* FVco 600.000000 */
-	{ .frequency = 310000000,	.index = PLLVAL(0x93, 4, 1),  }, 	/* FVco 620.000000 */
-	{ .frequency = 320000000,	.index = PLLVAL(0x98, 4, 1),  }, 	/* FVco 640.000000 */
-	{ .frequency = 330000000,	.index = PLLVAL(0x66, 2, 1),  }, 	/* FVco 660.000000 */
-	{ .frequency = 340000000,	.index = PLLVAL(0x4d, 1, 1),  }, 	/* FVco 680.000000 */
-	{ .frequency = 350000000,	.index = PLLVAL(0xa7, 4, 1),  }, 	/* FVco 700.000000 */
-	{ .frequency = 360000000,	.index = PLLVAL(0x70, 2, 1),  }, 	/* FVco 720.000000 */
-	{ .frequency = 370000000,	.index = PLLVAL(0xb1, 4, 1),  }, 	/* FVco 740.000000 */
-	{ .frequency = 380000000,	.index = PLLVAL(0x57, 1, 1),  }, 	/* FVco 760.000000 */
-	{ .frequency = 390000000,	.index = PLLVAL(0x7a, 2, 1),  }, 	/* FVco 780.000000 */
-	{ .frequency = 400000000,	.index = PLLVAL(0x5c, 1, 1),  }, 	/* FVco 800.000000 */
+	{ .frequency = 75000000,	.driver_data = PLLVAL(0x75, 3, 3),  }, 	/* FVco 600.000000 */
+	{ .frequency = 80000000,	.driver_data = PLLVAL(0x98, 4, 3),  }, 	/* FVco 640.000000 */
+	{ .frequency = 90000000,	.driver_data = PLLVAL(0x70, 2, 3),  }, 	/* FVco 720.000000 */
+	{ .frequency = 100000000,	.driver_data = PLLVAL(0x5c, 1, 3),  }, 	/* FVco 800.000000 */
+	{ .frequency = 110000000,	.driver_data = PLLVAL(0x66, 1, 3),  }, 	/* FVco 880.000000 */
+	{ .frequency = 120000000,	.driver_data = PLLVAL(0x70, 1, 3),  }, 	/* FVco 960.000000 */
+	{ .frequency = 150000000,	.driver_data = PLLVAL(0x75, 3, 2),  }, 	/* FVco 600.000000 */
+	{ .frequency = 160000000,	.driver_data = PLLVAL(0x98, 4, 2),  }, 	/* FVco 640.000000 */
+	{ .frequency = 170000000,	.driver_data = PLLVAL(0x4d, 1, 2),  }, 	/* FVco 680.000000 */
+	{ .frequency = 180000000,	.driver_data = PLLVAL(0x70, 2, 2),  }, 	/* FVco 720.000000 */
+	{ .frequency = 190000000,	.driver_data = PLLVAL(0x57, 1, 2),  }, 	/* FVco 760.000000 */
+	{ .frequency = 200000000,	.driver_data = PLLVAL(0x5c, 1, 2),  }, 	/* FVco 800.000000 */
+	{ .frequency = 210000000,	.driver_data = PLLVAL(0x84, 2, 2),  }, 	/* FVco 840.000000 */
+	{ .frequency = 220000000,	.driver_data = PLLVAL(0x66, 1, 2),  }, 	/* FVco 880.000000 */
+	{ .frequency = 230000000,	.driver_data = PLLVAL(0x6b, 1, 2),  }, 	/* FVco 920.000000 */
+	{ .frequency = 240000000,	.driver_data = PLLVAL(0x70, 1, 2),  }, 	/* FVco 960.000000 */
+	{ .frequency = 300000000,	.driver_data = PLLVAL(0x75, 3, 1),  }, 	/* FVco 600.000000 */
+	{ .frequency = 310000000,	.driver_data = PLLVAL(0x93, 4, 1),  }, 	/* FVco 620.000000 */
+	{ .frequency = 320000000,	.driver_data = PLLVAL(0x98, 4, 1),  }, 	/* FVco 640.000000 */
+	{ .frequency = 330000000,	.driver_data = PLLVAL(0x66, 2, 1),  }, 	/* FVco 660.000000 */
+	{ .frequency = 340000000,	.driver_data = PLLVAL(0x4d, 1, 1),  }, 	/* FVco 680.000000 */
+	{ .frequency = 350000000,	.driver_data = PLLVAL(0xa7, 4, 1),  }, 	/* FVco 700.000000 */
+	{ .frequency = 360000000,	.driver_data = PLLVAL(0x70, 2, 1),  }, 	/* FVco 720.000000 */
+	{ .frequency = 370000000,	.driver_data = PLLVAL(0xb1, 4, 1),  }, 	/* FVco 740.000000 */
+	{ .frequency = 380000000,	.driver_data = PLLVAL(0x57, 1, 1),  }, 	/* FVco 760.000000 */
+	{ .frequency = 390000000,	.driver_data = PLLVAL(0x7a, 2, 1),  }, 	/* FVco 780.000000 */
+	{ .frequency = 400000000,	.driver_data = PLLVAL(0x5c, 1, 1),  }, 	/* FVco 800.000000 */
 };
 
 static int s3c2440_plls12_add(struct device *dev, struct subsys_interface *sif)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/pll-s3c2440-16934400.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,61 +21,61 @@
 #include <plat/cpu-freq-core.h>
 
 static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
-	{ .frequency = 78019200,	.index = PLLVAL(121, 5, 3), 	}, 	/* FVco 624.153600 */
-	{ .frequency = 84067200,	.index = PLLVAL(131, 5, 3), 	}, 	/* FVco 672.537600 */
-	{ .frequency = 90115200,	.index = PLLVAL(141, 5, 3), 	}, 	/* FVco 720.921600 */
-	{ .frequency = 96163200,	.index = PLLVAL(151, 5, 3), 	}, 	/* FVco 769.305600 */
-	{ .frequency = 102135600,	.index = PLLVAL(185, 6, 3), 	}, 	/* FVco 817.084800 */
-	{ .frequency = 108259200,	.index = PLLVAL(171, 5, 3), 	}, 	/* FVco 866.073600 */
-	{ .frequency = 114307200,	.index = PLLVAL(127, 3, 3), 	}, 	/* FVco 914.457600 */
-	{ .frequency = 120234240,	.index = PLLVAL(134, 3, 3), 	}, 	/* FVco 961.873920 */
-	{ .frequency = 126161280,	.index = PLLVAL(141, 3, 3), 	}, 	/* FVco 1009.290240 */
-	{ .frequency = 132088320,	.index = PLLVAL(148, 3, 3), 	}, 	/* FVco 1056.706560 */
-	{ .frequency = 138015360,	.index = PLLVAL(155, 3, 3), 	}, 	/* FVco 1104.122880 */
-	{ .frequency = 144789120,	.index = PLLVAL(163, 3, 3), 	}, 	/* FVco 1158.312960 */
-	{ .frequency = 150100363,	.index = PLLVAL(187, 9, 2), 	}, 	/* FVco 600.401454 */
-	{ .frequency = 156038400,	.index = PLLVAL(121, 5, 2), 	}, 	/* FVco 624.153600 */
-	{ .frequency = 162086400,	.index = PLLVAL(126, 5, 2), 	}, 	/* FVco 648.345600 */
-	{ .frequency = 168134400,	.index = PLLVAL(131, 5, 2), 	}, 	/* FVco 672.537600 */
-	{ .frequency = 174048000,	.index = PLLVAL(177, 7, 2), 	}, 	/* FVco 696.192000 */
-	{ .frequency = 180230400,	.index = PLLVAL(141, 5, 2), 	}, 	/* FVco 720.921600 */
-	{ .frequency = 186278400,	.index = PLLVAL(124, 4, 2), 	}, 	/* FVco 745.113600 */
-	{ .frequency = 192326400,	.index = PLLVAL(151, 5, 2), 	}, 	/* FVco 769.305600 */
-	{ .frequency = 198132480,	.index = PLLVAL(109, 3, 2), 	}, 	/* FVco 792.529920 */
-	{ .frequency = 204271200,	.index = PLLVAL(185, 6, 2), 	}, 	/* FVco 817.084800 */
-	{ .frequency = 210268800,	.index = PLLVAL(141, 4, 2), 	}, 	/* FVco 841.075200 */
-	{ .frequency = 216518400,	.index = PLLVAL(171, 5, 2), 	}, 	/* FVco 866.073600 */
-	{ .frequency = 222264000,	.index = PLLVAL(97, 2, 2), 	}, 	/* FVco 889.056000 */
-	{ .frequency = 228614400,	.index = PLLVAL(127, 3, 2), 	}, 	/* FVco 914.457600 */
-	{ .frequency = 234259200,	.index = PLLVAL(158, 4, 2), 	}, 	/* FVco 937.036800 */
-	{ .frequency = 240468480,	.index = PLLVAL(134, 3, 2), 	}, 	/* FVco 961.873920 */
-	{ .frequency = 246960000,	.index = PLLVAL(167, 4, 2), 	}, 	/* FVco 987.840000 */
-	{ .frequency = 252322560,	.index = PLLVAL(141, 3, 2), 	}, 	/* FVco 1009.290240 */
-	{ .frequency = 258249600,	.index = PLLVAL(114, 2, 2), 	}, 	/* FVco 1032.998400 */
-	{ .frequency = 264176640,	.index = PLLVAL(148, 3, 2), 	}, 	/* FVco 1056.706560 */
-	{ .frequency = 270950400,	.index = PLLVAL(120, 2, 2), 	}, 	/* FVco 1083.801600 */
-	{ .frequency = 276030720,	.index = PLLVAL(155, 3, 2), 	}, 	/* FVco 1104.122880 */
-	{ .frequency = 282240000,	.index = PLLVAL(92, 1, 2), 	}, 	/* FVco 1128.960000 */
-	{ .frequency = 289578240,	.index = PLLVAL(163, 3, 2), 	}, 	/* FVco 1158.312960 */
-	{ .frequency = 294235200,	.index = PLLVAL(131, 2, 2), 	}, 	/* FVco 1176.940800 */
-	{ .frequency = 300200727,	.index = PLLVAL(187, 9, 1), 	}, 	/* FVco 600.401454 */
-	{ .frequency = 306358690,	.index = PLLVAL(191, 9, 1), 	}, 	/* FVco 612.717380 */
-	{ .frequency = 312076800,	.index = PLLVAL(121, 5, 1), 	}, 	/* FVco 624.153600 */
-	{ .frequency = 318366720,	.index = PLLVAL(86, 3, 1), 	}, 	/* FVco 636.733440 */
-	{ .frequency = 324172800,	.index = PLLVAL(126, 5, 1), 	}, 	/* FVco 648.345600 */
-	{ .frequency = 330220800,	.index = PLLVAL(109, 4, 1), 	}, 	/* FVco 660.441600 */
-	{ .frequency = 336268800,	.index = PLLVAL(131, 5, 1), 	}, 	/* FVco 672.537600 */
-	{ .frequency = 342074880,	.index = PLLVAL(93, 3, 1), 	}, 	/* FVco 684.149760 */
-	{ .frequency = 348096000,	.index = PLLVAL(177, 7, 1), 	}, 	/* FVco 696.192000 */
-	{ .frequency = 355622400,	.index = PLLVAL(118, 4, 1), 	}, 	/* FVco 711.244800 */
-	{ .frequency = 360460800,	.index = PLLVAL(141, 5, 1), 	}, 	/* FVco 720.921600 */
-	{ .frequency = 366206400,	.index = PLLVAL(165, 6, 1), 	}, 	/* FVco 732.412800 */
-	{ .frequency = 372556800,	.index = PLLVAL(124, 4, 1), 	}, 	/* FVco 745.113600 */
-	{ .frequency = 378201600,	.index = PLLVAL(126, 4, 1), 	}, 	/* FVco 756.403200 */
-	{ .frequency = 384652800,	.index = PLLVAL(151, 5, 1), 	}, 	/* FVco 769.305600 */
-	{ .frequency = 391608000,	.index = PLLVAL(177, 6, 1), 	}, 	/* FVco 783.216000 */
-	{ .frequency = 396264960,	.index = PLLVAL(109, 3, 1), 	}, 	/* FVco 792.529920 */
-	{ .frequency = 402192000,	.index = PLLVAL(87, 2, 1), 	}, 	/* FVco 804.384000 */
+	{ .frequency = 78019200,	.driver_data = PLLVAL(121, 5, 3), 	}, 	/* FVco 624.153600 */
+	{ .frequency = 84067200,	.driver_data = PLLVAL(131, 5, 3), 	}, 	/* FVco 672.537600 */
+	{ .frequency = 90115200,	.driver_data = PLLVAL(141, 5, 3), 	}, 	/* FVco 720.921600 */
+	{ .frequency = 96163200,	.driver_data = PLLVAL(151, 5, 3), 	}, 	/* FVco 769.305600 */
+	{ .frequency = 102135600,	.driver_data = PLLVAL(185, 6, 3), 	}, 	/* FVco 817.084800 */
+	{ .frequency = 108259200,	.driver_data = PLLVAL(171, 5, 3), 	}, 	/* FVco 866.073600 */
+	{ .frequency = 114307200,	.driver_data = PLLVAL(127, 3, 3), 	}, 	/* FVco 914.457600 */
+	{ .frequency = 120234240,	.driver_data = PLLVAL(134, 3, 3), 	}, 	/* FVco 961.873920 */
+	{ .frequency = 126161280,	.driver_data = PLLVAL(141, 3, 3), 	}, 	/* FVco 1009.290240 */
+	{ .frequency = 132088320,	.driver_data = PLLVAL(148, 3, 3), 	}, 	/* FVco 1056.706560 */
+	{ .frequency = 138015360,	.driver_data = PLLVAL(155, 3, 3), 	}, 	/* FVco 1104.122880 */
+	{ .frequency = 144789120,	.driver_data = PLLVAL(163, 3, 3), 	}, 	/* FVco 1158.312960 */
+	{ .frequency = 150100363,	.driver_data = PLLVAL(187, 9, 2), 	}, 	/* FVco 600.401454 */
+	{ .frequency = 156038400,	.driver_data = PLLVAL(121, 5, 2), 	}, 	/* FVco 624.153600 */
+	{ .frequency = 162086400,	.driver_data = PLLVAL(126, 5, 2), 	}, 	/* FVco 648.345600 */
+	{ .frequency = 168134400,	.driver_data = PLLVAL(131, 5, 2), 	}, 	/* FVco 672.537600 */
+	{ .frequency = 174048000,	.driver_data = PLLVAL(177, 7, 2), 	}, 	/* FVco 696.192000 */
+	{ .frequency = 180230400,	.driver_data = PLLVAL(141, 5, 2), 	}, 	/* FVco 720.921600 */
+	{ .frequency = 186278400,	.driver_data = PLLVAL(124, 4, 2), 	}, 	/* FVco 745.113600 */
+	{ .frequency = 192326400,	.driver_data = PLLVAL(151, 5, 2), 	}, 	/* FVco 769.305600 */
+	{ .frequency = 198132480,	.driver_data = PLLVAL(109, 3, 2), 	}, 	/* FVco 792.529920 */
+	{ .frequency = 204271200,	.driver_data = PLLVAL(185, 6, 2), 	}, 	/* FVco 817.084800 */
+	{ .frequency = 210268800,	.driver_data = PLLVAL(141, 4, 2), 	}, 	/* FVco 841.075200 */
+	{ .frequency = 216518400,	.driver_data = PLLVAL(171, 5, 2), 	}, 	/* FVco 866.073600 */
+	{ .frequency = 222264000,	.driver_data = PLLVAL(97, 2, 2), 	}, 	/* FVco 889.056000 */
+	{ .frequency = 228614400,	.driver_data = PLLVAL(127, 3, 2), 	}, 	/* FVco 914.457600 */
+	{ .frequency = 234259200,	.driver_data = PLLVAL(158, 4, 2), 	}, 	/* FVco 937.036800 */
+	{ .frequency = 240468480,	.driver_data = PLLVAL(134, 3, 2), 	}, 	/* FVco 961.873920 */
+	{ .frequency = 246960000,	.driver_data = PLLVAL(167, 4, 2), 	}, 	/* FVco 987.840000 */
+	{ .frequency = 252322560,	.driver_data = PLLVAL(141, 3, 2), 	}, 	/* FVco 1009.290240 */
+	{ .frequency = 258249600,	.driver_data = PLLVAL(114, 2, 2), 	}, 	/* FVco 1032.998400 */
+	{ .frequency = 264176640,	.driver_data = PLLVAL(148, 3, 2), 	}, 	/* FVco 1056.706560 */
+	{ .frequency = 270950400,	.driver_data = PLLVAL(120, 2, 2), 	}, 	/* FVco 1083.801600 */
+	{ .frequency = 276030720,	.driver_data = PLLVAL(155, 3, 2), 	}, 	/* FVco 1104.122880 */
+	{ .frequency = 282240000,	.driver_data = PLLVAL(92, 1, 2), 	}, 	/* FVco 1128.960000 */
+	{ .frequency = 289578240,	.driver_data = PLLVAL(163, 3, 2), 	}, 	/* FVco 1158.312960 */
+	{ .frequency = 294235200,	.driver_data = PLLVAL(131, 2, 2), 	}, 	/* FVco 1176.940800 */
+	{ .frequency = 300200727,	.driver_data = PLLVAL(187, 9, 1), 	}, 	/* FVco 600.401454 */
+	{ .frequency = 306358690,	.driver_data = PLLVAL(191, 9, 1), 	}, 	/* FVco 612.717380 */
+	{ .frequency = 312076800,	.driver_data = PLLVAL(121, 5, 1), 	}, 	/* FVco 624.153600 */
+	{ .frequency = 318366720,	.driver_data = PLLVAL(86, 3, 1), 	}, 	/* FVco 636.733440 */
+	{ .frequency = 324172800,	.driver_data = PLLVAL(126, 5, 1), 	}, 	/* FVco 648.345600 */
+	{ .frequency = 330220800,	.driver_data = PLLVAL(109, 4, 1), 	}, 	/* FVco 660.441600 */
+	{ .frequency = 336268800,	.driver_data = PLLVAL(131, 5, 1), 	}, 	/* FVco 672.537600 */
+	{ .frequency = 342074880,	.driver_data = PLLVAL(93, 3, 1), 	}, 	/* FVco 684.149760 */
+	{ .frequency = 348096000,	.driver_data = PLLVAL(177, 7, 1), 	}, 	/* FVco 696.192000 */
+	{ .frequency = 355622400,	.driver_data = PLLVAL(118, 4, 1), 	}, 	/* FVco 711.244800 */
+	{ .frequency = 360460800,	.driver_data = PLLVAL(141, 5, 1), 	}, 	/* FVco 720.921600 */
+	{ .frequency = 366206400,	.driver_data = PLLVAL(165, 6, 1), 	}, 	/* FVco 732.412800 */
+	{ .frequency = 372556800,	.driver_data = PLLVAL(124, 4, 1), 	}, 	/* FVco 745.113600 */
+	{ .frequency = 378201600,	.driver_data = PLLVAL(126, 4, 1), 	}, 	/* FVco 756.403200 */
+	{ .frequency = 384652800,	.driver_data = PLLVAL(151, 5, 1), 	}, 	/* FVco 769.305600 */
+	{ .frequency = 391608000,	.driver_data = PLLVAL(177, 6, 1), 	}, 	/* FVco 783.216000 */
+	{ .frequency = 396264960,	.driver_data = PLLVAL(109, 3, 1), 	}, 	/* FVco 792.529920 */
+	{ .frequency = 402192000,	.driver_data = PLLVAL(87, 2, 1), 	}, 	/* FVco 804.384000 */
 };
 
 static int s3c2440_plls169344_add(struct device *dev,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2410.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2410.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2410.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2410.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/io.h>
 
 #include <asm/mach/arch.h>
@@ -138,6 +139,7 @@ void __init s3c2410_init_clocks(int xtal
 	s3c2410_baseclk_add();
 	s3c24xx_register_clock(&s3c2410_armclk);
 	clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
+	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
 
 struct bus_type s3c2410_subsys = {
@@ -195,13 +197,13 @@ int __init s3c2410a_init(void)
 	return s3c2410_init();
 }
 
-void s3c2410_restart(char mode, const char *cmd)
+void s3c2410_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's') {
+	if (mode == REBOOT_SOFT) {
 		soft_restart(0);
 	}
 
-	arch_wdt_reset();
+	samsung_wdt_reset();
 
 	/* we'll take a jump through zero as a poor second */
 	soft_restart(0);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2412.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2412.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2412.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2412.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/reboot.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -129,9 +130,9 @@ static void s3c2412_idle(void)
 	cpu_do_idle();
 }
 
-void s3c2412_restart(char mode, const char *cmd)
+void s3c2412_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's')
+	if (mode == REBOOT_SOFT)
 		soft_restart(0);
 
 	/* errata "Watch-dog/Software Reset Problem" specifies that
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2412.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2412.h
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2412.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2412.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_H
-#define __ARCH_ARM_REGS_S3C24XX_S3C2412_H __FILE__
-
-#define S3C2412_MEMREG(x)		(S3C24XX_VA_MEMCTRL + (x))
-#define S3C2412_EBIREG(x)		(S3C2412_VA_EBI + (x))
-
-#define S3C2412_SSMCREG(x)		(S3C2412_VA_SSMC + (x))
-#define S3C2412_SSMC(x, o)		(S3C2412_SSMCREG((x * 0x20) + (o)))
-
-#define S3C2412_REFRESH			S3C2412_MEMREG(0x10)
-
-#define S3C2412_EBI_BANKCFG		S3C2412_EBIREG(0x4)
-
-#define S3C2412_SSMC_BANK(x)		S3C2412_SSMC(x, 0x0)
-
-#endif /* __ARCH_ARM_MACH_S3C24XX_S3C2412_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2416.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2416.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2416.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2416.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/reboot.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -79,9 +80,9 @@ static struct device s3c2416_dev = {
 	.bus		= &s3c2416_subsys,
 };
 
-void s3c2416_restart(char mode, const char *cmd)
+void s3c2416_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's')
+	if (mode == REBOOT_SOFT)
 		soft_restart(0);
 
 	__raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2443.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2443.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c2443.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c2443.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/reboot.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -59,9 +60,9 @@ static struct device s3c2443_dev = {
 	.bus		= &s3c2443_subsys,
 };
 
-void s3c2443_restart(char mode, const char *cmd)
+void s3c2443_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's')
+	if (mode == REBOOT_SOFT)
 		soft_restart(0);
 
 	__raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c244x.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c244x.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c24xx/s3c244x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c24xx/s3c244x.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/device.h>
 #include <linux/syscore_ops.h>
 #include <linux/clk.h>
@@ -133,6 +134,7 @@ void __init s3c244x_init_clocks(int xtal
 	s3c24xx_register_baseclocks(xtal);
 	s3c244x_setup_clocks();
 	s3c2410_baseclk_add();
+	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
 
 /* Since the S3C2442 and S3C2440 share items, put both subsystems here */
@@ -197,12 +199,12 @@ struct syscore_ops s3c244x_pm_syscore_op
 	.resume		= s3c244x_resume,
 };
 
-void s3c244x_restart(char mode, const char *cmd)
+void s3c244x_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's')
+	if (mode == REBOOT_SOFT)
 		soft_restart(0);
 
-	arch_wdt_reset();
+	samsung_wdt_reset();
 
 	/* we'll take a jump through zero as a poor second */
 	soft_restart(0);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c64xx/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c64xx/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-s3c64xx/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c64xx/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
 #include <linux/irq.h>
@@ -183,6 +184,12 @@ core_initcall(s3c64xx_dev_init);
 
 void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
 {
+	/*
+	 * FIXME: there is no better place to put this at the moment
+	 * (samsung_wdt_reset_init needs clocks)
+	 */
+	samsung_wdt_reset_init(S3C_VA_WATCHDOG);
+
 	printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
 
 	/* initialise the pair of VICs */
@@ -375,10 +382,10 @@ static int __init s3c64xx_init_irq_eint(
 }
 arch_initcall(s3c64xx_init_irq_eint);
 
-void s3c64xx_restart(char mode, const char *cmd)
+void s3c64xx_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode != 's')
-		arch_wdt_reset();
+	if (mode != REBOOT_SOFT)
+		samsung_wdt_reset();
 
 	/* if all else fails, or mode was for soft, jump to 0 */
 	soft_restart(0);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c64xx/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c64xx/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-s3c64xx/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c64xx/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,13 +17,15 @@
 #ifndef __ARCH_ARM_MACH_S3C64XX_COMMON_H
 #define __ARCH_ARM_MACH_S3C64XX_COMMON_H
 
+#include <linux/reboot.h>
+
 void s3c64xx_init_irq(u32 vic0, u32 vic1);
 void s3c64xx_init_io(struct map_desc *mach_desc, int size);
 
 void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit);
 void s3c64xx_setup_clocks(void);
 
-void s3c64xx_restart(char mode, const char *cmd);
+void s3c64xx_restart(enum reboot_mode mode, const char *cmd);
 void s3c64xx_init_late(void);
 
 #ifdef CONFIG_CPU_S3C6400
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s3c64xx/include/mach/uncompress.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c64xx/include/mach/uncompress.h
--- linux-libre-3.10-gnu/arch/arm/mach-s3c64xx/include/mach/uncompress.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s3c64xx/include/mach/uncompress.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,9 @@ static void arch_detect_cpu(void)
 	/* we do not need to do any cpu detection here at the moment. */
 	fifo_mask = S3C2440_UFSTAT_TXMASK;
 	fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
+
+	uart_base = (volatile u8 *)S3C_PA_UART +
+		(S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT);
 }
 
 #endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5p64x0/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s5p64x0/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-s5p64x0/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5p64x0/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/gpio.h>
 #include <linux/irq.h>
+#include <linux/reboot.h>
 
 #include <asm/irq.h>
 #include <asm/proc-fns.h>
@@ -173,6 +174,8 @@ void __init s5p64x0_init_io(struct map_d
 	s5p_init_cpu(S5P64X0_SYS_ID);
 
 	s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
+	samsung_wdt_reset_init(S3C_VA_WATCHDOG);
+
 }
 
 void __init s5p6440_map_io(void)
@@ -437,10 +440,10 @@ static int __init s5p64x0_init_irq_eint(
 }
 arch_initcall(s5p64x0_init_irq_eint);
 
-void s5p64x0_restart(char mode, const char *cmd)
+void s5p64x0_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode != 's')
-		arch_wdt_reset();
+	if (mode != REBOOT_SOFT)
+		samsung_wdt_reset();
 
 	soft_restart(0);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5p64x0/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s5p64x0/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-s5p64x0/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5p64x0/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,8 @@
 #ifndef __ARCH_ARM_MACH_S5P64X0_COMMON_H
 #define __ARCH_ARM_MACH_S5P64X0_COMMON_H
 
+#include <linux/reboot.h>
+
 void s5p6440_init_irq(void);
 void s5p6450_init_irq(void);
 void s5p64x0_init_io(struct map_desc *mach_desc, int size);
@@ -22,7 +24,7 @@ void s5p6440_setup_clocks(void);
 void s5p6450_register_clocks(void);
 void s5p6450_setup_clocks(void);
 
-void s5p64x0_restart(char mode, const char *cmd);
+void s5p64x0_restart(enum reboot_mode mode, const char *cmd);
 
 #ifdef CONFIG_CPU_S5P6440
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5p64x0/include/mach/uncompress.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s5p64x0/include/mach/uncompress.h
--- linux-libre-3.10-gnu/arch/arm/mach-s5p64x0/include/mach/uncompress.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5p64x0/include/mach/uncompress.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,171 +14,21 @@
 #define __ASM_ARCH_UNCOMPRESS_H
 
 #include <mach/map.h>
+#include <plat/uncompress.h>
 
-/*
- * cannot use commonly <plat/uncompress.h>
- * because uart base of S5P6440 and S5P6450 is different
- */
-
-typedef unsigned int upf_t;	/* cannot include linux/serial_core.h */
-
-/* uart setup */
-
-unsigned int fifo_mask;
-unsigned int fifo_max;
-
-/* forward declerations */
-
-static void arch_detect_cpu(void);
-
-/* defines for UART registers */
-
-#include <plat/regs-serial.h>
-#include <plat/regs-watchdog.h>
-
-/* working in physical space... */
-#undef S3C2410_WDOGREG
-#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
-
-/* how many bytes we allow into the FIFO at a time in FIFO mode */
-#define FIFO_MAX	 (14)
-
-unsigned long uart_base;
-
-static __inline__ void get_uart_base(void)
+static void arch_detect_cpu(void)
 {
 	unsigned int chipid;
 
 	chipid = *(const volatile unsigned int __force *) 0xE0100118;
 
-	uart_base = S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT;
-
 	if ((chipid & 0xff000) == 0x50000)
-		uart_base += 0xEC800000;
+		uart_base = (volatile u8 *)S5P6450_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
 	else
-		uart_base += 0xEC000000;
-}
-
-static __inline__ void uart_wr(unsigned int reg, unsigned int val)
-{
-	volatile unsigned int *ptr;
-
-	get_uart_base();
-	ptr = (volatile unsigned int *)(reg + uart_base);
-	*ptr = val;
-}
-
-static __inline__ unsigned int uart_rd(unsigned int reg)
-{
-	volatile unsigned int *ptr;
-
-	get_uart_base();
-	ptr = (volatile unsigned int *)(reg + uart_base);
-	return *ptr;
-}
-
-/*
- * we can deal with the case the UARTs are being run
- * in FIFO mode, so that we don't hold up our execution
- * waiting for tx to happen...
- */
-
-static void putc(int ch)
-{
-	if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
-		int level;
-
-		while (1) {
-			level = uart_rd(S3C2410_UFSTAT);
-			level &= fifo_mask;
-
-			if (level < fifo_max)
-				break;
-		}
-
-	} else {
-		/* not using fifos */
-
-		while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
-			barrier();
-	}
-
-	/* write byte to transmission register */
-	uart_wr(S3C2410_UTXH, ch);
-}
-
-static inline void flush(void)
-{
-}
-
-#define __raw_writel(d, ad)			\
-	do {							\
-		*((volatile unsigned int __force *)(ad)) = (d); \
-	} while (0)
-
-
-#ifdef CONFIG_S3C_BOOT_ERROR_RESET
-
-static void arch_decomp_error(const char *x)
-{
-	putstr("\n\n");
-	putstr(x);
-	putstr("\n\n -- System resetting\n");
-
-	__raw_writel(0x4000, S3C2410_WTDAT);
-	__raw_writel(0x4000, S3C2410_WTCNT);
-	__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
-
-	while(1);
-}
-
-#define arch_error arch_decomp_error
-#endif
-
-#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
-static inline void arch_enable_uart_fifo(void)
-{
-	u32 fifocon = uart_rd(S3C2410_UFCON);
-
-	if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
-		fifocon |= S3C2410_UFCON_RESETBOTH;
-		uart_wr(S3C2410_UFCON, fifocon);
-
-		/* wait for fifo reset to complete */
-		while (1) {
-			fifocon = uart_rd(S3C2410_UFCON);
-			if (!(fifocon & S3C2410_UFCON_RESETBOTH))
-				break;
-		}
-	}
-}
-#else
-#define arch_enable_uart_fifo() do { } while(0)
-#endif
-
-static void arch_decomp_setup(void)
-{
-	/*
-	 * we may need to setup the uart(s) here if we are not running
-	 * on an BAST... the BAST will have left the uarts configured
-	 * after calling linux.
-	 */
-
-	arch_detect_cpu();
-
-	/*
-	 * Enable the UART FIFOs if they where not enabled and our
-	 * configuration says we should turn them on.
-	 */
-
-	arch_enable_uart_fifo();
-}
-
-
+		uart_base = (volatile u8 *)S5P6440_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
 
-static void arch_detect_cpu(void)
-{
-	/* we do not need to do any cpu detection here at the moment. */
+	fifo_mask = S3C2440_UFSTAT_TXMASK;
+	fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
 }
 
 #endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5pc100/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pc100/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-s5pc100/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pc100/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/reboot.h>
 
 #include <asm/irq.h>
 #include <asm/proc-fns.h>
@@ -178,6 +179,7 @@ void __init s5pc100_init_clocks(int xtal
 	s5p_register_clocks(xtal);
 	s5pc100_register_clocks();
 	s5pc100_setup_clocks();
+	samsung_wdt_reset_init(S3C_VA_WATCHDOG);
 }
 
 void __init s5pc100_init_irq(void)
@@ -216,10 +218,10 @@ void __init s5pc100_init_uarts(struct s3
 	s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
 }
 
-void s5pc100_restart(char mode, const char *cmd)
+void s5pc100_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode != 's')
-		arch_wdt_reset();
+	if (mode != REBOOT_SOFT)
+		samsung_wdt_reset();
 
 	soft_restart(0);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5pc100/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pc100/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-s5pc100/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pc100/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,13 +12,15 @@
 #ifndef __ARCH_ARM_MACH_S5PC100_COMMON_H
 #define __ARCH_ARM_MACH_S5PC100_COMMON_H
 
+#include <linux/reboot.h>
+
 void s5pc100_init_io(struct map_desc *mach_desc, int size);
 void s5pc100_init_irq(void);
 
 void s5pc100_register_clocks(void);
 void s5pc100_setup_clocks(void);
 
-void s5pc100_restart(char mode, const char *cmd);
+void s5pc100_restart(enum reboot_mode mode, const char *cmd);
 
 extern  int s5pc100_init(void);
 extern void s5pc100_map_io(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5pc100/include/mach/uncompress.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pc100/include/mach/uncompress.h
--- linux-libre-3.10-gnu/arch/arm/mach-s5pc100/include/mach/uncompress.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pc100/include/mach/uncompress.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,8 @@ static void arch_detect_cpu(void)
 	/* we do not need to do any cpu detection here at the moment. */
 	fifo_mask = S3C2440_UFSTAT_TXMASK;
 	fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
+
+	uart_base = (volatile u8 *)S5P_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
 }
 
 #endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5pv210/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-s5pv210/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -143,7 +143,7 @@ static struct map_desc s5pv210_iodesc[]
 	}
 };
 
-void s5pv210_restart(char mode, const char *cmd)
+void s5pv210_restart(enum reboot_mode mode, const char *cmd)
 {
 	__raw_writel(0x1, S5P_SWRESET);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5pv210/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-s5pv210/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,13 +12,15 @@
 #ifndef __ARCH_ARM_MACH_S5PV210_COMMON_H
 #define __ARCH_ARM_MACH_S5PV210_COMMON_H
 
+#include <linux/reboot.h>
+
 void s5pv210_init_io(struct map_desc *mach_desc, int size);
 void s5pv210_init_irq(void);
 
 void s5pv210_register_clocks(void);
 void s5pv210_setup_clocks(void);
 
-void s5pv210_restart(char mode, const char *cmd);
+void s5pv210_restart(enum reboot_mode mode, const char *cmd);
 
 extern  int s5pv210_init(void);
 extern void s5pv210_map_io(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5pv210/include/mach/uncompress.h linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/include/mach/uncompress.h
--- linux-libre-3.10-gnu/arch/arm/mach-s5pv210/include/mach/uncompress.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/include/mach/uncompress.h	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,8 @@ static void arch_detect_cpu(void)
 	/* we do not need to do any cpu detection here at the moment. */
 	fifo_mask = S5PV210_UFSTAT_TXMASK;
 	fifo_max = 63 << S5PV210_UFSTAT_TXSHIFT;
+
+	uart_base = (volatile u8 *)S5P_PA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT);
 }
 
 #endif /* __ASM_ARCH_UNCOMPRESS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5pv210/mach-aquila.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/mach-aquila.c
--- linux-libre-3.10-gnu/arch/arm/mach-s5pv210/mach-aquila.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/mach-aquila.c	2013-08-25 20:43:22.000000000 -0400
@@ -377,12 +377,8 @@ static struct max8998_platform_data aqui
 	.buck1_set1	= S5PV210_GPH0(3),
 	.buck1_set2	= S5PV210_GPH0(4),
 	.buck2_set3	= S5PV210_GPH0(5),
-	.buck1_voltage1	= 1200000,
-	.buck1_voltage2	= 1200000,
-	.buck1_voltage3	= 1200000,
-	.buck1_voltage4	= 1200000,
-	.buck2_voltage1	= 1200000,
-	.buck2_voltage2	= 1200000,
+	.buck1_voltage	= { 1200000, 1200000, 1200000, 1200000 },
+	.buck2_voltage	= { 1200000, 1200000 },
 };
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-s5pv210/mach-goni.c linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/mach-goni.c
--- linux-libre-3.10-gnu/arch/arm/mach-s5pv210/mach-goni.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-s5pv210/mach-goni.c	2013-08-25 20:43:22.000000000 -0400
@@ -580,12 +580,8 @@ static struct max8998_platform_data goni
 	.buck1_set1	= S5PV210_GPH0(3),
 	.buck1_set2	= S5PV210_GPH0(4),
 	.buck2_set3	= S5PV210_GPH0(5),
-	.buck1_voltage1	= 1200000,
-	.buck1_voltage2	= 1200000,
-	.buck1_voltage3	= 1200000,
-	.buck1_voltage4	= 1200000,
-	.buck2_voltage1	= 1200000,
-	.buck2_voltage2	= 1200000,
+	.buck1_voltage	= { 1200000, 1200000, 1200000, 1200000 },
+	.buck2_voltage	= { 1200000, 1200000 },
 };
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sa1100/generic.c linux-libre-3.11-rc7-gnu/arch/arm/mach-sa1100/generic.c
--- linux-libre-3.10-gnu/arch/arm/mach-sa1100/generic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sa1100/generic.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 
 #include <video/sa1100fb.h>
 
@@ -131,9 +132,9 @@ static void sa1100_power_off(void)
 	PMCR = PMCR_SF;
 }
 
-void sa11x0_restart(char mode, const char *cmd)
+void sa11x0_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's') {
+	if (mode == REBOOT_SOFT) {
 		/* Jump into ROM at address 0 */
 		soft_restart(0);
 	} else {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sa1100/generic.h linux-libre-3.11-rc7-gnu/arch/arm/mach-sa1100/generic.h
--- linux-libre-3.10-gnu/arch/arm/mach-sa1100/generic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sa1100/generic.h	2013-08-25 20:43:22.000000000 -0400
@@ -3,12 +3,13 @@
  *
  * Author: Nicolas Pitre
  */
+#include <linux/reboot.h>
 
 extern void sa1100_timer_init(void);
 extern void __init sa1100_map_io(void);
 extern void __init sa1100_init_irq(void);
 extern void __init sa1100_init_gpio(void);
-extern void sa11x0_restart(char, const char *);
+extern void sa11x0_restart(enum reboot_mode, const char *);
 extern void sa11x0_init_late(void);
 
 #define SET_BANK(__nr,__start,__size) \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sa1100/time.c linux-libre-3.11-rc7-gnu/arch/arm/mach-sa1100/time.c
--- linux-libre-3.10-gnu/arch/arm/mach-sa1100/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sa1100/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,9 +14,9 @@
 #include <linux/irq.h>
 #include <linux/timex.h>
 #include <linux/clockchips.h>
+#include <linux/sched_clock.h>
 
 #include <asm/mach/time.h>
-#include <asm/sched_clock.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shark/core.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shark/core.c
--- linux-libre-3.10-gnu/arch/arm/mach-shark/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shark/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/serial_8250.h>
 #include <linux/io.h>
 #include <linux/cpu.h>
+#include <linux/reboot.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -24,7 +25,7 @@
 #define ROMCARD_SIZE            0x08000000
 #define ROMCARD_START           0x10000000
 
-static void shark_restart(char mode, const char *cmd)
+static void shark_restart(enum reboot_mode mode, const char *cmd)
 {
         short temp;
         /* Reset the Machine via pc[3] of the sequoia chipset */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-ap4evb.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-ap4evb.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-ap4evb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-ap4evb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1332 +0,0 @@
-/*
- * AP4EVB board support
- *
- * Copyright (C) 2010  Magnus Damm
- * Copyright (C) 2008  Yoshihiro Shimoda
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/clk.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/mfd/tmio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sh_mobile_sdhi.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mmc/sh_mmcif.h>
-#include <linux/i2c.h>
-#include <linux/i2c/tsc2007.h>
-#include <linux/io.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/machine.h>
-#include <linux/smsc911x.h>
-#include <linux/sh_intc.h>
-#include <linux/sh_clk.h>
-#include <linux/gpio.h>
-#include <linux/input.h>
-#include <linux/leds.h>
-#include <linux/input/sh_keysc.h>
-#include <linux/usb/r8a66597.h>
-#include <linux/pm_clock.h>
-#include <linux/dma-mapping.h>
-
-#include <media/sh_mobile_ceu.h>
-#include <media/sh_mobile_csi2.h>
-#include <media/soc_camera.h>
-
-#include <sound/sh_fsi.h>
-#include <sound/simple_card.h>
-
-#include <video/sh_mobile_hdmi.h>
-#include <video/sh_mobile_lcdc.h>
-#include <video/sh_mipi_dsi.h>
-
-#include <mach/common.h>
-#include <mach/irqs.h>
-#include <mach/sh7372.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/setup.h>
-
-#include "sh-gpio.h"
-
-/*
- * Address	Interface		BusWidth	note
- * ------------------------------------------------------------------
- * 0x0000_0000	NOR Flash ROM (MCP)	16bit		SW7 : bit1 = ON
- * 0x0800_0000	user area		-
- * 0x1000_0000	NOR Flash ROM (MCP)	16bit		SW7 : bit1 = OFF
- * 0x1400_0000	Ether (LAN9220)		16bit
- * 0x1600_0000	user area		-		cannot use with NAND
- * 0x1800_0000	user area		-
- * 0x1A00_0000	-
- * 0x4000_0000	LPDDR2-SDRAM (POP)	32bit
- */
-
-/*
- * NOR Flash ROM
- *
- *  SW1  |     SW2    | SW7  | NOR Flash ROM
- *  bit1 | bit1  bit2 | bit1 | Memory allocation
- * ------+------------+------+------------------
- *  OFF  | ON     OFF | ON   |    Area 0
- *  OFF  | ON     OFF | OFF  |    Area 4
- */
-
-/*
- * NAND Flash ROM
- *
- *  SW1  |     SW2    | SW7  | NAND Flash ROM
- *  bit1 | bit1  bit2 | bit2 | Memory allocation
- * ------+------------+------+------------------
- *  OFF  | ON     OFF | ON   |    FCE 0
- *  OFF  | ON     OFF | OFF  |    FCE 1
- */
-
-/*
- * SMSC 9220
- *
- *  SW1		SMSC 9220
- * -----------------------
- *  ON		access disable
- *  OFF		access enable
- */
-
-/*
- * LCD / IRQ / KEYSC / IrDA
- *
- * IRQ = IRQ26 (TS), IRQ27 (VIO), IRQ28 (QHD-TouchScreen)
- * LCD = 2nd LCDC (WVGA)
- *
- * 		|		SW43			|
- * SW3		|	ON		|	OFF	|
- * -------------+-----------------------+---------------+
- * ON		| KEY / IrDA		| LCD		|
- * OFF		| KEY / IrDA / IRQ	| IRQ		|
- *
- *
- * QHD / WVGA display
- *
- * You can choice display type on menuconfig.
- * Then, check above dip-switch.
- */
-
-/*
- * USB
- *
- * J7 : 1-2  MAX3355E VBUS
- *      2-3  DC 5.0V
- *
- * S39: bit2: off
- */
-
-/*
- * FSI/FSMI
- *
- * SW41	:  ON : SH-Mobile AP4 Audio Mode
- *	: OFF : Bluetooth Audio Mode
- *
- * it needs amixer settings for playing
- *
- * amixer set "Headphone Enable" on
- */
-
-/*
- * MMC0/SDHI1 (CN7)
- *
- * J22 : select card voltage
- *       1-2 pin : 1.8v
- *       2-3 pin : 3.3v
- *
- *        SW1  |             SW33
- *             | bit1 | bit2 | bit3 | bit4
- * ------------+------+------+------+-------
- * MMC0   OFF  |  OFF |  ON  |  ON  |  X
- * SDHI1  OFF  |  ON  |   X  |  OFF | ON
- *
- * voltage lebel
- * CN7 : 1.8v
- * CN12: 3.3v
- */
-
-/* Dummy supplies, where voltage doesn't matter */
-static struct regulator_consumer_supply fixed1v8_power_consumers[] =
-{
-	/* J22 default position: 1.8V */
-	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
-	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
-	REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
-	REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
-};
-
-static struct regulator_consumer_supply fixed3v3_power_consumers[] =
-{
-	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
-	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
-};
-
-static struct regulator_consumer_supply dummy_supplies[] = {
-	REGULATOR_SUPPLY("vddvario", "smsc911x"),
-	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
-};
-
-/* MTD */
-static struct mtd_partition nor_flash_partitions[] = {
-	{
-		.name		= "loader",
-		.offset		= 0x00000000,
-		.size		= 512 * 1024,
-		.mask_flags	= MTD_WRITEABLE,
-	},
-	{
-		.name		= "bootenv",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= 512 * 1024,
-		.mask_flags	= MTD_WRITEABLE,
-	},
-	{
-		.name		= "kernel_ro",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= 8 * 1024 * 1024,
-		.mask_flags	= MTD_WRITEABLE,
-	},
-	{
-		.name		= "kernel",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= 8 * 1024 * 1024,
-	},
-	{
-		.name		= "data",
-		.offset		= MTDPART_OFS_APPEND,
-		.size		= MTDPART_SIZ_FULL,
-	},
-};
-
-static struct physmap_flash_data nor_flash_data = {
-	.width		= 2,
-	.parts		= nor_flash_partitions,
-	.nr_parts	= ARRAY_SIZE(nor_flash_partitions),
-};
-
-static struct resource nor_flash_resources[] = {
-	[0]	= {
-		.start	= 0x20000000, /* CS0 shadow instead of regular CS0 */
-		.end	= 0x28000000 - 1, /* needed by USB MASK ROM boot */
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct platform_device nor_flash_device = {
-	.name		= "physmap-flash",
-	.dev		= {
-		.platform_data	= &nor_flash_data,
-	},
-	.num_resources	= ARRAY_SIZE(nor_flash_resources),
-	.resource	= nor_flash_resources,
-};
-
-/* SMSC 9220 */
-static struct resource smc911x_resources[] = {
-	{
-		.start	= 0x14000000,
-		.end	= 0x16000000 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= evt2irq(0x02c0) /* IRQ6A */,
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
-};
-
-static struct smsc911x_platform_config smsc911x_info = {
-	.flags		= SMSC911X_USE_16BIT | SMSC911X_SAVE_MAC_ADDRESS,
-	.irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
-};
-
-static struct platform_device smc911x_device = {
-	.name           = "smsc911x",
-	.id             = -1,
-	.num_resources  = ARRAY_SIZE(smc911x_resources),
-	.resource       = smc911x_resources,
-	.dev            = {
-		.platform_data = &smsc911x_info,
-	},
-};
-
-/*
- * The card detect pin of the top SD/MMC slot (CN7) is active low and is
- * connected to GPIO A22 of SH7372 (GPIO 41).
- */
-static int slot_cn7_get_cd(struct platform_device *pdev)
-{
-	return !gpio_get_value(41);
-}
-/* MERAM */
-static struct sh_mobile_meram_info meram_info = {
-	.addr_mode      = SH_MOBILE_MERAM_MODE1,
-};
-
-static struct resource meram_resources[] = {
-	[0] = {
-		.name	= "regs",
-		.start	= 0xe8000000,
-		.end	= 0xe807ffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.name	= "meram",
-		.start	= 0xe8080000,
-		.end	= 0xe81fffff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device meram_device = {
-	.name           = "sh_mobile_meram",
-	.id             = 0,
-	.num_resources  = ARRAY_SIZE(meram_resources),
-	.resource       = meram_resources,
-	.dev            = {
-		.platform_data = &meram_info,
-	},
-};
-
-/* SH_MMCIF */
-static struct resource sh_mmcif_resources[] = {
-	[0] = {
-		.name	= "MMCIF",
-		.start	= 0xE6BD0000,
-		.end	= 0xE6BD00FF,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		/* MMC ERR */
-		.start	= evt2irq(0x1ac0),
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* MMC NOR */
-		.start	= evt2irq(0x1ae0),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct sh_mmcif_plat_data sh_mmcif_plat = {
-	.sup_pclk	= 0,
-	.ocr		= MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
-	.caps		= MMC_CAP_4_BIT_DATA |
-			  MMC_CAP_8_BIT_DATA |
-			  MMC_CAP_NEEDS_POLL,
-	.get_cd		= slot_cn7_get_cd,
-	.slave_id_tx	= SHDMA_SLAVE_MMCIF_TX,
-	.slave_id_rx	= SHDMA_SLAVE_MMCIF_RX,
-};
-
-static struct platform_device sh_mmcif_device = {
-	.name		= "sh_mmcif",
-	.id		= 0,
-	.dev		= {
-		.dma_mask		= NULL,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &sh_mmcif_plat,
-	},
-	.num_resources	= ARRAY_SIZE(sh_mmcif_resources),
-	.resource	= sh_mmcif_resources,
-};
-
-/* SDHI0 */
-static struct sh_mobile_sdhi_info sdhi0_info = {
-	.dma_slave_tx	= SHDMA_SLAVE_SDHI0_TX,
-	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
-	.tmio_caps	= MMC_CAP_SDIO_IRQ,
-};
-
-static struct resource sdhi0_resources[] = {
-	[0] = {
-		.name	= "SDHI0",
-		.start  = 0xe6850000,
-		.end    = 0xe68500ff,
-		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device sdhi0_device = {
-	.name           = "sh_mobile_sdhi",
-	.num_resources  = ARRAY_SIZE(sdhi0_resources),
-	.resource       = sdhi0_resources,
-	.id             = 0,
-	.dev	= {
-		.platform_data	= &sdhi0_info,
-	},
-};
-
-/* SDHI1 */
-static struct sh_mobile_sdhi_info sdhi1_info = {
-	.dma_slave_tx	= SHDMA_SLAVE_SDHI1_TX,
-	.dma_slave_rx	= SHDMA_SLAVE_SDHI1_RX,
-	.tmio_ocr_mask	= MMC_VDD_165_195,
-	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE,
-	.tmio_caps	= MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ,
-	.get_cd		= slot_cn7_get_cd,
-};
-
-static struct resource sdhi1_resources[] = {
-	[0] = {
-		.name	= "SDHI1",
-		.start  = 0xe6860000,
-		.end    = 0xe68600ff,
-		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.start	= evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
-		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
-		.start	= evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device sdhi1_device = {
-	.name           = "sh_mobile_sdhi",
-	.num_resources  = ARRAY_SIZE(sdhi1_resources),
-	.resource       = sdhi1_resources,
-	.id             = 1,
-	.dev	= {
-		.platform_data	= &sdhi1_info,
-	},
-};
-
-/* USB1 */
-static void usb1_host_port_power(int port, int power)
-{
-	if (!power) /* only power-on supported for now */
-		return;
-
-	/* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
-	__raw_writew(__raw_readw(IOMEM(0xE68B0008)) | 0x600, IOMEM(0xE68B0008));
-}
-
-static struct r8a66597_platdata usb1_host_data = {
-	.on_chip	= 1,
-	.port_power	= usb1_host_port_power,
-};
-
-static struct resource usb1_host_resources[] = {
-	[0] = {
-		.name	= "USBHS",
-		.start	= 0xE68B0000,
-		.end	= 0xE68B00E6 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= evt2irq(0x1ce0) /* USB1_USB1I0 */,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device usb1_host_device = {
-	.name	= "r8a66597_hcd",
-	.id	= 1,
-	.dev = {
-		.dma_mask		= NULL,         /*  not use dma */
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &usb1_host_data,
-	},
-	.num_resources	= ARRAY_SIZE(usb1_host_resources),
-	.resource	= usb1_host_resources,
-};
-
-/*
- * QHD display
- */
-#ifdef CONFIG_AP4EVB_QHD
-
-/* KEYSC (Needs SW43 set to ON) */
-static struct sh_keysc_info keysc_info = {
-	.mode		= SH_KEYSC_MODE_1,
-	.scan_timing	= 3,
-	.delay		= 2500,
-	.keycodes = {
-		KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
-		KEY_5, KEY_6, KEY_7, KEY_8, KEY_9,
-		KEY_A, KEY_B, KEY_C, KEY_D, KEY_E,
-		KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
-		KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
-	},
-};
-
-static struct resource keysc_resources[] = {
-	[0] = {
-		.name	= "KEYSC",
-		.start  = 0xe61b0000,
-		.end    = 0xe61b0063,
-		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start  = evt2irq(0x0be0), /* KEYSC_KEY */
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device keysc_device = {
-	.name           = "sh_keysc",
-	.id             = 0, /* "keysc0" clock */
-	.num_resources  = ARRAY_SIZE(keysc_resources),
-	.resource       = keysc_resources,
-	.dev	= {
-		.platform_data	= &keysc_info,
-	},
-};
-
-/* MIPI-DSI */
-static int sh_mipi_set_dot_clock(struct platform_device *pdev,
-				 void __iomem *base,
-				 int enable)
-{
-	struct clk *pck = clk_get(&pdev->dev, "dsip_clk");
-
-	if (IS_ERR(pck))
-		return PTR_ERR(pck);
-
-	if (enable) {
-		/*
-		 * DSIPCLK	= 24MHz
-		 * D-PHY	= DSIPCLK * ((0x6*2)+1) = 312MHz (see .phyctrl)
-		 * HsByteCLK	= D-PHY/8 = 39MHz
-		 *
-		 *  X * Y * FPS =
-		 * (544+72+600+16) * (961+8+8+2) * 30 = 36.1MHz
-		 */
-		clk_set_rate(pck, clk_round_rate(pck, 24000000));
-		clk_enable(pck);
-	} else {
-		clk_disable(pck);
-	}
-
-	clk_put(pck);
-
-	return 0;
-}
-
-static struct resource mipidsi0_resources[] = {
-	[0] = {
-		.start  = 0xffc60000,
-		.end    = 0xffc63073,
-		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start  = 0xffc68000,
-		.end    = 0xffc680ef,
-		.flags  = IORESOURCE_MEM,
-	},
-};
-
-static struct sh_mipi_dsi_info mipidsi0_info = {
-	.data_format	= MIPI_RGB888,
-	.channel	= LCDC_CHAN_MAINLCD,
-	.lane		= 2,
-	.vsynw_offset	= 17,
-	.phyctrl	= 0x6 << 8,
-	.flags		= SH_MIPI_DSI_SYNC_PULSES_MODE |
-			  SH_MIPI_DSI_HSbyteCLK,
-	.set_dot_clock	= sh_mipi_set_dot_clock,
-};
-
-static struct platform_device mipidsi0_device = {
-	.name           = "sh-mipi-dsi",
-	.num_resources  = ARRAY_SIZE(mipidsi0_resources),
-	.resource       = mipidsi0_resources,
-	.id             = 0,
-	.dev	= {
-		.platform_data	= &mipidsi0_info,
-	},
-};
-
-static struct platform_device *qhd_devices[] __initdata = {
-	&mipidsi0_device,
-	&keysc_device,
-};
-#endif /* CONFIG_AP4EVB_QHD */
-
-/* LCDC0 */
-static const struct fb_videomode ap4evb_lcdc_modes[] = {
-	{
-#ifdef CONFIG_AP4EVB_QHD
-		.name		= "R63302(QHD)",
-		.xres		= 544,
-		.yres		= 961,
-		.left_margin	= 72,
-		.right_margin	= 600,
-		.hsync_len	= 16,
-		.upper_margin	= 8,
-		.lower_margin	= 8,
-		.vsync_len	= 2,
-		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
-#else
-		.name		= "WVGA Panel",
-		.xres		= 800,
-		.yres		= 480,
-		.left_margin	= 220,
-		.right_margin	= 110,
-		.hsync_len	= 70,
-		.upper_margin	= 20,
-		.lower_margin	= 5,
-		.vsync_len	= 5,
-		.sync		= 0,
-#endif
-	},
-};
-
-static const struct sh_mobile_meram_cfg lcd_meram_cfg = {
-	.icb[0] = {
-		.meram_size     = 0x40,
-	},
-	.icb[1] = {
-		.meram_size     = 0x40,
-	},
-};
-
-static struct sh_mobile_lcdc_info lcdc_info = {
-	.meram_dev = &meram_info,
-	.ch[0] = {
-		.chan = LCDC_CHAN_MAINLCD,
-		.fourcc = V4L2_PIX_FMT_RGB565,
-		.lcd_modes = ap4evb_lcdc_modes,
-		.num_modes = ARRAY_SIZE(ap4evb_lcdc_modes),
-		.meram_cfg = &lcd_meram_cfg,
-#ifdef CONFIG_AP4EVB_QHD
-		.tx_dev = &mipidsi0_device,
-#endif
-	}
-};
-
-static struct resource lcdc_resources[] = {
-	[0] = {
-		.name	= "LCDC",
-		.start	= 0xfe940000, /* P4-only space */
-		.end	= 0xfe943fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= intcs_evt2irq(0x580),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device lcdc_device = {
-	.name		= "sh_mobile_lcdc_fb",
-	.num_resources	= ARRAY_SIZE(lcdc_resources),
-	.resource	= lcdc_resources,
-	.dev	= {
-		.platform_data	= &lcdc_info,
-		.coherent_dma_mask = ~0,
-	},
-};
-
-/* FSI */
-#define IRQ_FSI		evt2irq(0x1840)
-static struct sh_fsi_platform_info fsi_info = {
-	.port_b = {
-		.flags		= SH_FSI_CLK_CPG |
-				  SH_FSI_FMT_SPDIF,
-	},
-};
-
-static struct resource fsi_resources[] = {
-	[0] = {
-		.name	= "FSI",
-		.start	= 0xFE3C0000,
-		.end	= 0xFE3C0400 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start  = IRQ_FSI,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device fsi_device = {
-	.name		= "sh_fsi2",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(fsi_resources),
-	.resource	= fsi_resources,
-	.dev	= {
-		.platform_data	= &fsi_info,
-	},
-};
-
-static struct asoc_simple_card_info fsi2_ak4643_info = {
-	.name		= "AK4643",
-	.card		= "FSI2A-AK4643",
-	.codec		= "ak4642-codec.0-0013",
-	.platform	= "sh_fsi2",
-	.daifmt		= SND_SOC_DAIFMT_LEFT_J,
-	.cpu_dai = {
-		.name	= "fsia-dai",
-		.fmt	= SND_SOC_DAIFMT_CBS_CFS,
-	},
-	.codec_dai = {
-		.name	= "ak4642-hifi",
-		.fmt	= SND_SOC_DAIFMT_CBM_CFM,
-		.sysclk	= 11289600,
-	},
-};
-
-static struct platform_device fsi_ak4643_device = {
-	.name	= "asoc-simple-card",
-	.dev	= {
-		.platform_data	= &fsi2_ak4643_info,
-	},
-};
-
-/* LCDC1 */
-static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
-				unsigned long *parent_freq);
-
-static struct sh_mobile_hdmi_info hdmi_info = {
-	.flags = HDMI_SND_SRC_SPDIF,
-	.clk_optimize_parent = ap4evb_clk_optimize,
-};
-
-static struct resource hdmi_resources[] = {
-	[0] = {
-		.name	= "HDMI",
-		.start	= 0xe6be0000,
-		.end	= 0xe6be00ff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		/* There's also an HDMI interrupt on INTCS @ 0x18e0 */
-		.start	= evt2irq(0x17e0),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device hdmi_device = {
-	.name		= "sh-mobile-hdmi",
-	.num_resources	= ARRAY_SIZE(hdmi_resources),
-	.resource	= hdmi_resources,
-	.id             = -1,
-	.dev	= {
-		.platform_data	= &hdmi_info,
-	},
-};
-
-static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
-				unsigned long *parent_freq)
-{
-	struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
-	long error;
-
-	if (IS_ERR(hdmi_ick)) {
-		int ret = PTR_ERR(hdmi_ick);
-		pr_err("Cannot get HDMI ICK: %d\n", ret);
-		return ret;
-	}
-
-	error = clk_round_parent(hdmi_ick, target, best_freq, parent_freq, 1, 64);
-
-	clk_put(hdmi_ick);
-
-	return error;
-}
-
-static const struct sh_mobile_meram_cfg hdmi_meram_cfg = {
-	.icb[0] = {
-		.meram_size     = 0x100,
-	},
-	.icb[1] = {
-		.meram_size     = 0x100,
-	},
-};
-
-static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
-	.clock_source = LCDC_CLK_EXTERNAL,
-	.meram_dev = &meram_info,
-	.ch[0] = {
-		.chan = LCDC_CHAN_MAINLCD,
-		.fourcc = V4L2_PIX_FMT_RGB565,
-		.interface_type = RGB24,
-		.clock_divider = 1,
-		.flags = LCDC_FLAGS_DWPOL,
-		.meram_cfg = &hdmi_meram_cfg,
-		.tx_dev = &hdmi_device,
-	}
-};
-
-static struct resource lcdc1_resources[] = {
-	[0] = {
-		.name	= "LCDC1",
-		.start	= 0xfe944000,
-		.end	= 0xfe947fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= intcs_evt2irq(0x1780),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device lcdc1_device = {
-	.name		= "sh_mobile_lcdc_fb",
-	.num_resources	= ARRAY_SIZE(lcdc1_resources),
-	.resource	= lcdc1_resources,
-	.id             = 1,
-	.dev	= {
-		.platform_data	= &sh_mobile_lcdc1_info,
-		.coherent_dma_mask = ~0,
-	},
-};
-
-static struct asoc_simple_card_info fsi2_hdmi_info = {
-	.name		= "HDMI",
-	.card		= "FSI2B-HDMI",
-	.codec		= "sh-mobile-hdmi",
-	.platform	= "sh_fsi2",
-	.cpu_dai = {
-		.name	= "fsib-dai",
-		.fmt	= SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF,
-	},
-	.codec_dai = {
-		.name	= "sh_mobile_hdmi-hifi",
-	},
-};
-
-static struct platform_device fsi_hdmi_device = {
-	.name	= "asoc-simple-card",
-	.id	= 1,
-	.dev	= {
-		.platform_data	= &fsi2_hdmi_info,
-	},
-};
-
-static struct gpio_led ap4evb_leds[] = {
-	{
-		.name			= "led4",
-		.gpio			= 185,
-		.default_state	= LEDS_GPIO_DEFSTATE_ON,
-	},
-	{
-		.name			= "led2",
-		.gpio			= 186,
-		.default_state	= LEDS_GPIO_DEFSTATE_ON,
-	},
-	{
-		.name			= "led3",
-		.gpio			= 187,
-		.default_state	= LEDS_GPIO_DEFSTATE_ON,
-	},
-	{
-		.name			= "led1",
-		.gpio			= 188,
-		.default_state	= LEDS_GPIO_DEFSTATE_ON,
-	}
-};
-
-static struct gpio_led_platform_data ap4evb_leds_pdata = {
-	.num_leds = ARRAY_SIZE(ap4evb_leds),
-	.leds = ap4evb_leds,
-};
-
-static struct platform_device leds_device = {
-	.name = "leds-gpio",
-	.id = 0,
-	.dev = {
-		.platform_data  = &ap4evb_leds_pdata,
-	},
-};
-
-static struct i2c_board_info imx074_info = {
-	I2C_BOARD_INFO("imx074", 0x1a),
-};
-
-static struct soc_camera_link imx074_link = {
-	.bus_id		= 0,
-	.board_info	= &imx074_info,
-	.i2c_adapter_id	= 0,
-	.module_name	= "imx074",
-};
-
-static struct platform_device ap4evb_camera = {
-	.name   = "soc-camera-pdrv",
-	.id     = 0,
-	.dev    = {
-		.platform_data = &imx074_link,
-	},
-};
-
-static struct sh_csi2_client_config csi2_clients[] = {
-	{
-		.phy		= SH_CSI2_PHY_MAIN,
-		.lanes		= 0,		/* default: 2 lanes */
-		.channel	= 0,
-		.pdev		= &ap4evb_camera,
-	},
-};
-
-static struct sh_csi2_pdata csi2_info = {
-	.type		= SH_CSI2C,
-	.clients	= csi2_clients,
-	.num_clients	= ARRAY_SIZE(csi2_clients),
-	.flags		= SH_CSI2_ECC | SH_CSI2_CRC,
-};
-
-static struct resource csi2_resources[] = {
-	[0] = {
-		.name	= "CSI2",
-		.start	= 0xffc90000,
-		.end	= 0xffc90fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= intcs_evt2irq(0x17a0),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct sh_mobile_ceu_companion csi2 = {
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(csi2_resources),
-	.resource	= csi2_resources,
-	.platform_data	= &csi2_info,
-};
-
-static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
-	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
-	.max_width = 8188,
-	.max_height = 8188,
-	.csi2 = &csi2,
-};
-
-static struct resource ceu_resources[] = {
-	[0] = {
-		.name	= "CEU",
-		.start	= 0xfe910000,
-		.end	= 0xfe91009f,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= intcs_evt2irq(0x880),
-		.flags  = IORESOURCE_IRQ,
-	},
-	[2] = {
-		/* place holder for contiguous memory */
-	},
-};
-
-static struct platform_device ceu_device = {
-	.name		= "sh_mobile_ceu",
-	.id             = 0, /* "ceu0" clock */
-	.num_resources	= ARRAY_SIZE(ceu_resources),
-	.resource	= ceu_resources,
-	.dev	= {
-		.platform_data		= &sh_mobile_ceu_info,
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
-static struct platform_device *ap4evb_devices[] __initdata = {
-	&leds_device,
-	&nor_flash_device,
-	&smc911x_device,
-	&sdhi0_device,
-	&sdhi1_device,
-	&usb1_host_device,
-	&fsi_device,
-	&fsi_ak4643_device,
-	&fsi_hdmi_device,
-	&sh_mmcif_device,
-	&hdmi_device,
-	&lcdc_device,
-	&lcdc1_device,
-	&ceu_device,
-	&ap4evb_camera,
-	&meram_device,
-};
-
-static void __init hdmi_init_pm_clock(void)
-{
-	struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
-	int ret;
-	long rate;
-
-	if (IS_ERR(hdmi_ick)) {
-		ret = PTR_ERR(hdmi_ick);
-		pr_err("Cannot get HDMI ICK: %d\n", ret);
-		goto out;
-	}
-
-	ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk);
-	if (ret < 0) {
-		pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, sh7372_pllc2_clk.usecount);
-		goto out;
-	}
-
-	pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&sh7372_pllc2_clk));
-
-	rate = clk_round_rate(&sh7372_pllc2_clk, 594000000);
-	if (rate < 0) {
-		pr_err("Cannot get suitable rate: %ld\n", rate);
-		ret = rate;
-		goto out;
-	}
-
-	ret = clk_set_rate(&sh7372_pllc2_clk, rate);
-	if (ret < 0) {
-		pr_err("Cannot set rate %ld: %d\n", rate, ret);
-		goto out;
-	}
-
-	pr_debug("PLLC2 set frequency %lu\n", rate);
-
-	ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
-	if (ret < 0)
-		pr_err("Cannot set HDMI parent: %d\n", ret);
-
-out:
-	if (!IS_ERR(hdmi_ick))
-		clk_put(hdmi_ick);
-}
-
-/* TouchScreen */
-#ifdef CONFIG_AP4EVB_QHD
-# define GPIO_TSC_IRQ	GPIO_FN_IRQ28_123
-# define GPIO_TSC_PORT	123
-#else /* WVGA */
-# define GPIO_TSC_IRQ	GPIO_FN_IRQ7_40
-# define GPIO_TSC_PORT	40
-#endif
-
-#define IRQ28	evt2irq(0x3380) /* IRQ28A */
-#define IRQ7	evt2irq(0x02e0) /* IRQ7A */
-static int ts_get_pendown_state(void)
-{
-	int val;
-
-	gpio_free(GPIO_TSC_IRQ);
-
-	gpio_request_one(GPIO_TSC_PORT, GPIOF_IN, NULL);
-
-	val = gpio_get_value(GPIO_TSC_PORT);
-
-	gpio_request(GPIO_TSC_IRQ, NULL);
-
-	return !val;
-}
-
-static int ts_init(void)
-{
-	gpio_request(GPIO_TSC_IRQ, NULL);
-
-	return 0;
-}
-
-static struct tsc2007_platform_data tsc2007_info = {
-	.model			= 2007,
-	.x_plate_ohms		= 180,
-	.get_pendown_state	= ts_get_pendown_state,
-	.init_platform_hw	= ts_init,
-};
-
-static struct i2c_board_info tsc_device = {
-	I2C_BOARD_INFO("tsc2007", 0x48),
-	.type		= "tsc2007",
-	.platform_data	= &tsc2007_info,
-	/*.irq is selected on ap4evb_init */
-};
-
-/* I2C */
-static struct i2c_board_info i2c0_devices[] = {
-	{
-		I2C_BOARD_INFO("ak4643", 0x13),
-	},
-};
-
-static struct i2c_board_info i2c1_devices[] = {
-	{
-		I2C_BOARD_INFO("r2025sd", 0x32),
-	},
-};
-
-
-static const struct pinctrl_map ap4evb_pinctrl_map[] = {
-	/* MMCIF */
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh7372",
-				  "mmc0_data8_0", "mmc0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh7372",
-				  "mmc0_ctrl_0", "mmc0"),
-	/* SDHI0 */
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372",
-				  "sdhi0_data4", "sdhi0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372",
-				  "sdhi0_ctrl", "sdhi0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372",
-				  "sdhi0_cd", "sdhi0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372",
-				  "sdhi0_wp", "sdhi0"),
-	/* SDHI1 */
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh7372",
-				  "sdhi1_data4", "sdhi1"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh7372",
-				  "sdhi1_ctrl", "sdhi1"),
-};
-
-#define GPIO_PORT9CR	IOMEM(0xE6051009)
-#define GPIO_PORT10CR	IOMEM(0xE605100A)
-#define USCCR1		IOMEM(0xE6058144)
-static void __init ap4evb_init(void)
-{
-	struct pm_domain_device domain_devices[] = {
-		{ "A4LC", &lcdc1_device, },
-		{ "A4LC", &lcdc_device, },
-		{ "A4MP", &fsi_device, },
-		{ "A3SP", &sh_mmcif_device, },
-		{ "A3SP", &sdhi0_device, },
-		{ "A3SP", &sdhi1_device, },
-		{ "A4R", &ceu_device, },
-	};
-	u32 srcr4;
-	struct clk *clk;
-
-	regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers,
-				     ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
-	regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers,
-				     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
-	regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies));
-
-	/* External clock source */
-	clk_set_rate(&sh7372_dv_clki_clk, 27000000);
-
-	pinctrl_register_mappings(ap4evb_pinctrl_map,
-				  ARRAY_SIZE(ap4evb_pinctrl_map));
-	sh7372_pinmux_init();
-
-	/* enable SCIFA0 */
-	gpio_request(GPIO_FN_SCIFA0_TXD, NULL);
-	gpio_request(GPIO_FN_SCIFA0_RXD, NULL);
-
-	/* enable SMSC911X */
-	gpio_request(GPIO_FN_CS5A,	NULL);
-	gpio_request(GPIO_FN_IRQ6_39,	NULL);
-
-	/* enable Debug switch (S6) */
-	gpio_request_one(32, GPIOF_IN | GPIOF_EXPORT, NULL);
-	gpio_request_one(33, GPIOF_IN | GPIOF_EXPORT, NULL);
-	gpio_request_one(34, GPIOF_IN | GPIOF_EXPORT, NULL);
-	gpio_request_one(35, GPIOF_IN | GPIOF_EXPORT, NULL);
-
-	/* USB enable */
-	gpio_request(GPIO_FN_VBUS0_1,    NULL);
-	gpio_request(GPIO_FN_IDIN_1_18,  NULL);
-	gpio_request(GPIO_FN_PWEN_1_115, NULL);
-	gpio_request(GPIO_FN_OVCN_1_114, NULL);
-	gpio_request(GPIO_FN_EXTLP_1,    NULL);
-	gpio_request(GPIO_FN_OVCN2_1,    NULL);
-
-	/* setup USB phy */
-	__raw_writew(0x8a0a, IOMEM(0xE6058130));	/* USBCR4 */
-
-	/* enable FSI2 port A (ak4643) */
-	gpio_request(GPIO_FN_FSIAIBT,	NULL);
-	gpio_request(GPIO_FN_FSIAILR,	NULL);
-	gpio_request(GPIO_FN_FSIAISLD,	NULL);
-	gpio_request(GPIO_FN_FSIAOSLD,	NULL);
-	gpio_request_one(161, GPIOF_OUT_INIT_LOW, NULL); /* slave */
-
-	gpio_request(9, NULL);
-	gpio_request(10, NULL);
-	gpio_direction_none(GPIO_PORT9CR);  /* FSIAOBT needs no direction */
-	gpio_direction_none(GPIO_PORT10CR); /* FSIAOLR needs no direction */
-
-	/* card detect pin for MMC slot (CN7) */
-	gpio_request_one(41, GPIOF_IN, NULL);
-
-	/* setup FSI2 port B (HDMI) */
-	gpio_request(GPIO_FN_FSIBCK, NULL);
-	__raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */
-
-	/* set SPU2 clock to 119.6 MHz */
-	clk = clk_get(NULL, "spu_clk");
-	if (!IS_ERR(clk)) {
-		clk_set_rate(clk, clk_round_rate(clk, 119600000));
-		clk_put(clk);
-	}
-
-	/*
-	 * set irq priority, to avoid sound chopping
-	 * when NFS rootfs is used
-	 *  FSI(3) > SMSC911X(2)
-	 */
-	intc_set_priority(IRQ_FSI, 3);
-
-	i2c_register_board_info(0, i2c0_devices,
-				ARRAY_SIZE(i2c0_devices));
-
-	i2c_register_board_info(1, i2c1_devices,
-				ARRAY_SIZE(i2c1_devices));
-
-#ifdef CONFIG_AP4EVB_QHD
-
-	/*
-	 * For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and
-	 * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON.
-	 */
-
-	/* enable KEYSC */
-	gpio_request(GPIO_FN_KEYOUT0, NULL);
-	gpio_request(GPIO_FN_KEYOUT1, NULL);
-	gpio_request(GPIO_FN_KEYOUT2, NULL);
-	gpio_request(GPIO_FN_KEYOUT3, NULL);
-	gpio_request(GPIO_FN_KEYOUT4, NULL);
-	gpio_request(GPIO_FN_KEYIN0_136, NULL);
-	gpio_request(GPIO_FN_KEYIN1_135, NULL);
-	gpio_request(GPIO_FN_KEYIN2_134, NULL);
-	gpio_request(GPIO_FN_KEYIN3_133, NULL);
-	gpio_request(GPIO_FN_KEYIN4,     NULL);
-
-	/* enable TouchScreen */
-	irq_set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW);
-
-	tsc_device.irq = IRQ28;
-	i2c_register_board_info(1, &tsc_device, 1);
-
-	/* LCDC0 */
-	lcdc_info.clock_source			= LCDC_CLK_PERIPHERAL;
-	lcdc_info.ch[0].interface_type		= RGB24;
-	lcdc_info.ch[0].clock_divider		= 1;
-	lcdc_info.ch[0].flags			= LCDC_FLAGS_DWPOL;
-	lcdc_info.ch[0].panel_cfg.width		= 44;
-	lcdc_info.ch[0].panel_cfg.height	= 79;
-
-	platform_add_devices(qhd_devices, ARRAY_SIZE(qhd_devices));
-
-#else
-	/*
-	 * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and
-	 * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF.
-	 */
-
-	gpio_request(GPIO_FN_LCDD17,   NULL);
-	gpio_request(GPIO_FN_LCDD16,   NULL);
-	gpio_request(GPIO_FN_LCDD15,   NULL);
-	gpio_request(GPIO_FN_LCDD14,   NULL);
-	gpio_request(GPIO_FN_LCDD13,   NULL);
-	gpio_request(GPIO_FN_LCDD12,   NULL);
-	gpio_request(GPIO_FN_LCDD11,   NULL);
-	gpio_request(GPIO_FN_LCDD10,   NULL);
-	gpio_request(GPIO_FN_LCDD9,    NULL);
-	gpio_request(GPIO_FN_LCDD8,    NULL);
-	gpio_request(GPIO_FN_LCDD7,    NULL);
-	gpio_request(GPIO_FN_LCDD6,    NULL);
-	gpio_request(GPIO_FN_LCDD5,    NULL);
-	gpio_request(GPIO_FN_LCDD4,    NULL);
-	gpio_request(GPIO_FN_LCDD3,    NULL);
-	gpio_request(GPIO_FN_LCDD2,    NULL);
-	gpio_request(GPIO_FN_LCDD1,    NULL);
-	gpio_request(GPIO_FN_LCDD0,    NULL);
-	gpio_request(GPIO_FN_LCDDISP,  NULL);
-	gpio_request(GPIO_FN_LCDDCK,   NULL);
-
-	gpio_request_one(189, GPIOF_OUT_INIT_HIGH, NULL); /* backlight */
-	gpio_request_one(151, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */
-
-	lcdc_info.clock_source			= LCDC_CLK_BUS;
-	lcdc_info.ch[0].interface_type		= RGB18;
-	lcdc_info.ch[0].clock_divider		= 3;
-	lcdc_info.ch[0].flags			= 0;
-	lcdc_info.ch[0].panel_cfg.width		= 152;
-	lcdc_info.ch[0].panel_cfg.height	= 91;
-
-	/* enable TouchScreen */
-	irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
-
-	tsc_device.irq = IRQ7;
-	i2c_register_board_info(0, &tsc_device, 1);
-#endif /* CONFIG_AP4EVB_QHD */
-
-	/* CEU */
-
-	/*
-	 * TODO: reserve memory for V4L2 DMA buffers, when a suitable API
-	 * becomes available
-	 */
-
-	/* MIPI-CSI stuff */
-	gpio_request(GPIO_FN_VIO_CKO, NULL);
-
-	clk = clk_get(NULL, "vck1_clk");
-	if (!IS_ERR(clk)) {
-		clk_set_rate(clk, clk_round_rate(clk, 13000000));
-		clk_enable(clk);
-		clk_put(clk);
-	}
-
-	sh7372_add_standard_devices();
-
-	/* HDMI */
-	gpio_request(GPIO_FN_HDMI_HPD, NULL);
-	gpio_request(GPIO_FN_HDMI_CEC, NULL);
-
-	/* Reset HDMI, must be held at least one EXTALR (32768Hz) period */
-#define SRCR4 IOMEM(0xe61580bc)
-	srcr4 = __raw_readl(SRCR4);
-	__raw_writel(srcr4 | (1 << 13), SRCR4);
-	udelay(50);
-	__raw_writel(srcr4 & ~(1 << 13), SRCR4);
-
-	platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
-
-	rmobile_add_devices_to_domains(domain_devices,
-				       ARRAY_SIZE(domain_devices));
-
-	hdmi_init_pm_clock();
-	sh7372_pm_init();
-	pm_clk_add(&fsi_device.dev, "spu2");
-	pm_clk_add(&lcdc1_device.dev, "hdmi");
-}
-
-MACHINE_START(AP4EVB, "ap4evb")
-	.map_io		= sh7372_map_io,
-	.init_early	= sh7372_add_early_devices,
-	.init_irq	= sh7372_init_irq,
-	.handle_irq	= shmobile_handle_irq_intc,
-	.init_machine	= ap4evb_init,
-	.init_late	= sh7372_pm_init_late,
-	.init_time	= sh7372_earlytimer_init,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-ape6evm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-ape6evm.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-ape6evm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-ape6evm.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
+#include <linux/sh_clk.h>
 #include <linux/smsc911x.h>
 #include <mach/common.h>
 #include <mach/irqs.h>
@@ -65,7 +66,21 @@ static const struct pinctrl_map ape6evm_
 
 static void __init ape6evm_add_standard_devices(void)
 {
+
+	struct clk *parent;
+	struct clk *mp;
+
 	r8a73a4_clock_init();
+
+	/* MP clock parent = extal2 */
+	parent      = clk_get(NULL, "extal2");
+	mp          = clk_get(NULL, "mp");
+	BUG_ON(IS_ERR(parent) || IS_ERR(mp));
+
+	clk_set_parent(mp, parent);
+	clk_put(parent);
+	clk_put(mp);
+
 	pinctrl_register_mappings(ape6evm_pinctrl_map,
 				  ARRAY_SIZE(ape6evm_pinctrl_map));
 	r8a73a4_pinmux_init();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-armadillo800eva.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-armadillo800eva.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-armadillo800eva.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-armadillo800eva.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/mmc/sh_mmcif.h>
 #include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/i2c-gpio.h>
+#include <linux/reboot.h>
 #include <mach/common.h>
 #include <mach/irqs.h>
 #include <mach/r8a7740.h>
@@ -377,7 +378,7 @@ static struct resource sh_eth_resources[
 };
 
 static struct platform_device sh_eth_device = {
-	.name = "sh-eth",
+	.name = "r8a7740-gether",
 	.id = -1,
 	.dev = {
 		.platform_data = &sh_eth_platdata,
@@ -584,7 +585,7 @@ static struct regulator_init_data vcc_sd
 static struct fixed_voltage_config vcc_sdhi0_info = {
 	.supply_name = "SDHI0 Vcc",
 	.microvolts = 3300000,
-	.gpio = GPIO_PORT75,
+	.gpio = 75,
 	.enable_high = 1,
 	.init_data = &vcc_sdhi0_init_data,
 };
@@ -615,7 +616,7 @@ static struct regulator_init_data vccq_s
 };
 
 static struct gpio vccq_sdhi0_gpios[] = {
-	{GPIO_PORT17, GPIOF_OUT_INIT_LOW, "vccq-sdhi0" },
+	{17, GPIOF_OUT_INIT_LOW, "vccq-sdhi0" },
 };
 
 static struct gpio_regulator_state vccq_sdhi0_states[] = {
@@ -626,7 +627,7 @@ static struct gpio_regulator_state vccq_
 static struct gpio_regulator_config vccq_sdhi0_info = {
 	.supply_name = "vqmmc",
 
-	.enable_gpio = GPIO_PORT74,
+	.enable_gpio = 74,
 	.enable_high = 1,
 	.enabled_at_boot = 0,
 
@@ -664,7 +665,7 @@ static struct regulator_init_data vcc_sd
 static struct fixed_voltage_config vcc_sdhi1_info = {
 	.supply_name = "SDHI1 Vcc",
 	.microvolts = 3300000,
-	.gpio = GPIO_PORT16,
+	.gpio = 16,
 	.enable_high = 1,
 	.init_data = &vcc_sdhi1_init_data,
 };
@@ -693,7 +694,7 @@ static struct sh_mobile_sdhi_info sdhi0_
 	.tmio_caps	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
 			  MMC_CAP_POWER_OFF_CARD,
 	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD,
-	.cd_gpio	= GPIO_PORT167,
+	.cd_gpio	= 167,
 };
 
 static struct resource sdhi0_resources[] = {
@@ -736,7 +737,7 @@ static struct sh_mobile_sdhi_info sdhi1_
 			  MMC_CAP_POWER_OFF_CARD,
 	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_USE_GPIO_CD,
 	/* Port72 cannot generate IRQs, will be used in polling mode. */
-	.cd_gpio	= GPIO_PORT72,
+	.cd_gpio	= 72,
 };
 
 static struct resource sdhi1_resources[] = {
@@ -1046,6 +1047,35 @@ static struct platform_device *eva_devic
 };
 
 static const struct pinctrl_map eva_pinctrl_map[] = {
+	/* CEU0 */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740",
+				  "ceu0_data_0_7", "ceu0"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740",
+				  "ceu0_clk_0", "ceu0"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740",
+				  "ceu0_sync", "ceu0"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-r8a7740",
+				  "ceu0_field", "ceu0"),
+	/* FSIA */
+	PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740",
+				  "fsia_sclk_in", "fsia"),
+	PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740",
+				  "fsia_mclk_out", "fsia"),
+	PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740",
+				  "fsia_data_in_1", "fsia"),
+	PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-r8a7740",
+				  "fsia_data_out_0", "fsia"),
+	/* FSIB */
+	PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.1", "pfc-r8a7740",
+				  "fsib_mclk_in", "fsib"),
+	/* GETHER */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-eth", "pfc-r8a7740",
+				  "gether_mii", "gether"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-eth", "pfc-r8a7740",
+				  "gether_int", "gether"),
+	/* HDMI */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-mobile-hdmi", "pfc-r8a7740",
+				  "hdmi", "hdmi"),
 	/* LCD0 */
 	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
 				  "lcd0_data24_0", "lcd0"),
@@ -1058,6 +1088,9 @@ static const struct pinctrl_map eva_pinc
 				  "mmc0_data8_1", "mmc0"),
 	PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a7740",
 				  "mmc0_ctrl_1", "mmc0"),
+	/* SCIFA1 */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.1", "pfc-r8a7740",
+				  "scifa1_data", "scifa1"),
 	/* SDHI0 */
 	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7740",
 				  "sdhi0_data4", "sdhi0"),
@@ -1065,6 +1098,12 @@ static const struct pinctrl_map eva_pinc
 				  "sdhi0_ctrl", "sdhi0"),
 	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7740",
 				  "sdhi0_wp", "sdhi0"),
+	/* ST1232 */
+	PIN_MAP_MUX_GROUP_DEFAULT("0-0055", "pfc-r8a7740",
+				  "intc_irq10", "intc"),
+	/* USBHS */
+	PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7740",
+				  "intc_irq7_1", "intc"),
 };
 
 static void __init eva_clock_init(void)
@@ -1119,40 +1158,11 @@ static void __init eva_init(void)
 	r8a7740_pinmux_init();
 	r8a7740_meram_workaround();
 
-	/* SCIFA1 */
-	gpio_request(GPIO_FN_SCIFA1_RXD, NULL);
-	gpio_request(GPIO_FN_SCIFA1_TXD, NULL);
-
 	/* LCDC0 */
-	gpio_request(GPIO_FN_LCDC0_SELECT,	NULL);
-
 	gpio_request_one(61, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */
 	gpio_request_one(202, GPIOF_OUT_INIT_LOW, NULL); /* LCD0_LED_CONT */
 
-	/* Touchscreen */
-	gpio_request(GPIO_FN_IRQ10,	NULL); /* TP_INT */
-
 	/* GETHER */
-	gpio_request(GPIO_FN_ET_CRS,		NULL);
-	gpio_request(GPIO_FN_ET_MDC,		NULL);
-	gpio_request(GPIO_FN_ET_MDIO,		NULL);
-	gpio_request(GPIO_FN_ET_TX_ER,		NULL);
-	gpio_request(GPIO_FN_ET_RX_ER,		NULL);
-	gpio_request(GPIO_FN_ET_ERXD0,		NULL);
-	gpio_request(GPIO_FN_ET_ERXD1,		NULL);
-	gpio_request(GPIO_FN_ET_ERXD2,		NULL);
-	gpio_request(GPIO_FN_ET_ERXD3,		NULL);
-	gpio_request(GPIO_FN_ET_TX_CLK,		NULL);
-	gpio_request(GPIO_FN_ET_TX_EN,		NULL);
-	gpio_request(GPIO_FN_ET_ETXD0,		NULL);
-	gpio_request(GPIO_FN_ET_ETXD1,		NULL);
-	gpio_request(GPIO_FN_ET_ETXD2,		NULL);
-	gpio_request(GPIO_FN_ET_ETXD3,		NULL);
-	gpio_request(GPIO_FN_ET_PHY_INT,	NULL);
-	gpio_request(GPIO_FN_ET_COL,		NULL);
-	gpio_request(GPIO_FN_ET_RX_DV,		NULL);
-	gpio_request(GPIO_FN_ET_RX_CLK,		NULL);
-
 	gpio_request_one(18, GPIOF_OUT_INIT_HIGH, NULL); /* PHY_RST */
 
 	/* USB */
@@ -1163,34 +1173,17 @@ static void __init eva_init(void)
 	} else {
 		/* USB Func */
 		/*
-		 * A1 chip has 2 IRQ7 pin and it was controled by MSEL register.
-		 * OTOH, usbhs interrupt needs its value (HI/LOW) to decide
-		 * USB connection/disconnection (usbhsf_get_vbus()).
-		 * This means we needs to select GPIO_FN_IRQ7_PORT209 first,
-		 * and select GPIO 209 here
+		 * The USBHS interrupt handlers needs to read the IRQ pin value
+		 * (HI/LOW) to diffentiate USB connection and disconnection
+		 * events (usbhsf_get_vbus()). We thus need to select both the
+		 * intc_irq7_1 pin group and GPIO 209 here.
 		 */
-		gpio_request(GPIO_FN_IRQ7_PORT209, NULL);
 		gpio_request_one(209, GPIOF_IN, NULL);
 
 		platform_device_register(&usbhsf_device);
 		usb = &usbhsf_device;
 	}
 
-	/* CEU0 */
-	gpio_request(GPIO_FN_VIO0_D7,		NULL);
-	gpio_request(GPIO_FN_VIO0_D6,		NULL);
-	gpio_request(GPIO_FN_VIO0_D5,		NULL);
-	gpio_request(GPIO_FN_VIO0_D4,		NULL);
-	gpio_request(GPIO_FN_VIO0_D3,		NULL);
-	gpio_request(GPIO_FN_VIO0_D2,		NULL);
-	gpio_request(GPIO_FN_VIO0_D1,		NULL);
-	gpio_request(GPIO_FN_VIO0_D0,		NULL);
-	gpio_request(GPIO_FN_VIO0_CLK,		NULL);
-	gpio_request(GPIO_FN_VIO0_HD,		NULL);
-	gpio_request(GPIO_FN_VIO0_VD,		NULL);
-	gpio_request(GPIO_FN_VIO0_FIELD,	NULL);
-	gpio_request(GPIO_FN_VIO_CKO,		NULL);
-
 	/* CON1/CON15 Camera */
 	gpio_request_one(173, GPIOF_OUT_INIT_LOW, NULL);  /* STANDBY */
 	gpio_request_one(172, GPIOF_OUT_INIT_HIGH, NULL); /* RST */
@@ -1198,24 +1191,11 @@ static void __init eva_init(void)
 	gpio_request_one(158, GPIOF_OUT_INIT_LOW, NULL);  /* CAM_PON */
 
 	/* FSI-WM8978 */
-	gpio_request(GPIO_FN_FSIAIBT,		NULL);
-	gpio_request(GPIO_FN_FSIAILR,		NULL);
-	gpio_request(GPIO_FN_FSIAOMC,		NULL);
-	gpio_request(GPIO_FN_FSIAOSLD,		NULL);
-	gpio_request(GPIO_FN_FSIAISLD_PORT5,	NULL);
-
 	gpio_request(7, NULL);
 	gpio_request(8, NULL);
 	gpio_direction_none(GPIO_PORT7CR); /* FSIAOBT needs no direction */
 	gpio_direction_none(GPIO_PORT8CR); /* FSIAOLR needs no direction */
 
-	/* FSI-HDMI */
-	gpio_request(GPIO_FN_FSIBCK,		NULL);
-
-	/* HDMI */
-	gpio_request(GPIO_FN_HDMI_HPD,		NULL);
-	gpio_request(GPIO_FN_HDMI_CEC,		NULL);
-
 	/*
 	 * CAUTION
 	 *
@@ -1277,7 +1257,7 @@ static void __init eva_add_early_devices
 }
 
 #define RESCNT2 IOMEM(0xe6188020)
-static void eva_restart(char mode, const char *cmd)
+static void eva_restart(enum reboot_mode mode, const char *cmd)
 {
 	/* Do soft power on reset */
 	writel((1 << 31), RESCNT2);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-armadillo800eva-reference.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-armadillo800eva-reference.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-armadillo800eva-reference.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-armadillo800eva-reference.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,213 @@
+/*
+ * armadillo 800 eva board support
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/pinctrl/machine.h>
+#include <mach/common.h>
+#include <mach/r8a7740.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+
+/*
+ * CON1		Camera Module
+ * CON2		Extension Bus
+ * CON3		HDMI Output
+ * CON4		Composite Video Output
+ * CON5		H-UDI JTAG
+ * CON6		ARM JTAG
+ * CON7		SD1
+ * CON8		SD2
+ * CON9		RTC BackUp
+ * CON10	Monaural Mic Input
+ * CON11	Stereo Headphone Output
+ * CON12	Audio Line Output(L)
+ * CON13	Audio Line Output(R)
+ * CON14	AWL13 Module
+ * CON15	Extension
+ * CON16	LCD1
+ * CON17	LCD2
+ * CON19	Power Input
+ * CON20	USB1
+ * CON21	USB2
+ * CON22	Serial
+ * CON23	LAN
+ * CON24	USB3
+ * LED1		Camera LED(Yellow)
+ * LED2		Power LED (Green)
+ * ED3-LED6	User LED(Yellow)
+ * LED7		LAN link LED(Green)
+ * LED8		LAN activity LED(Yellow)
+ */
+
+/*
+ * DipSwitch
+ *
+ *                    SW1
+ *
+ * -12345678-+---------------+----------------------------
+ *  1        | boot          | hermit
+ *  0        | boot          | OS auto boot
+ * -12345678-+---------------+----------------------------
+ *   00      | boot device   | eMMC
+ *   10      | boot device   | SDHI0 (CON7)
+ *   01      | boot device   | -
+ *   11      | boot device   | Extension Buss (CS0)
+ * -12345678-+---------------+----------------------------
+ *     0     | Extension Bus | D8-D15 disable, eMMC enable
+ *     1     | Extension Bus | D8-D15 enable,  eMMC disable
+ * -12345678-+---------------+----------------------------
+ *      0    | SDHI1         | COM8 disable, COM14 enable
+ *      1    | SDHI1         | COM8 enable,  COM14 disable
+ * -12345678-+---------------+----------------------------
+ *       0   | USB0          | COM20 enable,  COM24 disable
+ *       1   | USB0          | COM20 disable, COM24 enable
+ * -12345678-+---------------+----------------------------
+ *        00 | JTAG          | SH-X2
+ *        10 | JTAG          | ARM
+ *        01 | JTAG          | -
+ *        11 | JTAG          | Boundary Scan
+ *-----------+---------------+----------------------------
+ */
+
+/*
+ * FSI-WM8978
+ *
+ * this command is required when playback.
+ *
+ * # amixer set "Headphone" 50
+ *
+ * this command is required when capture.
+ *
+ * # amixer set "Input PGA" 15
+ * # amixer set "Left Input Mixer MicP" on
+ * # amixer set "Left Input Mixer MicN" on
+ * # amixer set "Right Input Mixer MicN" on
+ * # amixer set "Right Input Mixer MicP" on
+ */
+
+/*
+ * USB function
+ *
+ * When you use USB Function,
+ * set SW1.6 ON, and connect cable to CN24.
+ *
+ * USBF needs workaround on R8A7740 chip.
+ * These are a little bit complex.
+ * see
+ *	usbhsf_power_ctrl()
+ */
+
+static const struct pinctrl_map eva_pinctrl_map[] = {
+	/* SCIFA1 */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.1", "pfc-r8a7740",
+				  "scifa1_data", "scifa1"),
+};
+
+static void __init eva_clock_init(void)
+{
+	struct clk *system	= clk_get(NULL, "system_clk");
+	struct clk *xtal1	= clk_get(NULL, "extal1");
+	struct clk *usb24s	= clk_get(NULL, "usb24s");
+	struct clk *fsibck	= clk_get(NULL, "fsibck");
+
+	if (IS_ERR(system)	||
+	    IS_ERR(xtal1)	||
+	    IS_ERR(usb24s)	||
+	    IS_ERR(fsibck)) {
+		pr_err("armadillo800eva board clock init failed\n");
+		goto clock_error;
+	}
+
+	/* armadillo 800 eva extal1 is 24MHz */
+	clk_set_rate(xtal1, 24000000);
+
+	/* usb24s use extal1 (= system) clock (= 24MHz) */
+	clk_set_parent(usb24s, system);
+
+	/* FSIBCK is 12.288MHz, and it is parent of FSI-B */
+	clk_set_rate(fsibck, 12288000);
+
+clock_error:
+	if (!IS_ERR(system))
+		clk_put(system);
+	if (!IS_ERR(xtal1))
+		clk_put(xtal1);
+	if (!IS_ERR(usb24s))
+		clk_put(usb24s);
+	if (!IS_ERR(fsibck))
+		clk_put(fsibck);
+}
+
+/*
+ * board init
+ */
+static void __init eva_init(void)
+{
+
+	r8a7740_clock_init(MD_CK0 | MD_CK2);
+	eva_clock_init();
+
+	pinctrl_register_mappings(eva_pinctrl_map, ARRAY_SIZE(eva_pinctrl_map));
+	r8a7740_pinmux_init();
+
+	r8a7740_meram_workaround();
+
+	/*
+	 * Touchscreen
+	 * TODO: Move reset GPIO over to .dts when we can reference it
+	 */
+	gpio_request_one(166, GPIOF_OUT_INIT_HIGH, NULL); /* TP_RST_B */
+
+#ifdef CONFIG_CACHE_L2X0
+	/* Early BRESP enable, Shared attribute override enable, 32K*8way */
+	l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
+#endif
+
+	r8a7740_add_standard_devices_dt();
+	r8a7740_pm_init();
+}
+
+#define RESCNT2 IOMEM(0xe6188020)
+static void eva_restart(char mode, const char *cmd)
+{
+	/* Do soft power on reset */
+	writel((1 << 31), RESCNT2);
+}
+
+static const char *eva_boards_compat_dt[] __initdata = {
+	"renesas,armadillo800eva-reference",
+	NULL,
+};
+
+DT_MACHINE_START(ARMADILLO800EVA_DT, "armadillo800eva-reference")
+	.map_io		= r8a7740_map_io,
+	.init_early	= r8a7740_init_delay,
+	.init_irq	= r8a7740_init_irq_of,
+	.init_machine	= eva_init,
+	.init_time	= shmobile_timer_init,
+	.init_late	= shmobile_init_late,
+	.dt_compat	= eva_boards_compat_dt,
+	.restart	= eva_restart,
+MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-bockw.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-bockw.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-bockw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-bockw.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,13 +18,52 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pinctrl/machine.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 #include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
 #include <mach/common.h>
 #include <mach/irqs.h>
 #include <mach/r8a7778.h>
 #include <asm/mach/arch.h>
 
+/*
+ *	CN9(Upper side) SCIF/RCAN selection
+ *
+ *		1,4	3,6
+ * SW40		SCIF	RCAN
+ * SW41		SCIF	RCAN
+ */
+
+/*
+ * MMC (CN26) pin
+ *
+ * SW6	(D2)	3 pin
+ * SW7	(D5)	ON
+ * SW8	(D3)	3 pin
+ * SW10	(D4)	1 pin
+ * SW12	(CLK)	1 pin
+ * SW13	(D6)	3 pin
+ * SW14	(CMD)	ON
+ * SW15	(D6)	1 pin
+ * SW16	(D0)	ON
+ * SW17	(D1)	ON
+ * SW18	(D7)	3 pin
+ * SW19	(MMC)	1 pin
+ */
+
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+	REGULATOR_SUPPLY("vddvario", "smsc911x"),
+	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
 static struct smsc911x_platform_config smsc911x_data = {
 	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
 	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
@@ -37,17 +76,134 @@ static struct resource smsc911x_resource
 	DEFINE_RES_IRQ(irq_pin(0)), /* IRQ 0 */
 };
 
+/* USB */
+static struct rcar_phy_platform_data usb_phy_platform_data __initdata;
+
+/* SDHI */
+static struct sh_mobile_sdhi_info sdhi0_info = {
+	.tmio_caps	= MMC_CAP_SD_HIGHSPEED,
+	.tmio_ocr_mask	= MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
+	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT,
+};
+
+static struct sh_eth_plat_data ether_platform_data __initdata = {
+	.phy		= 0x01,
+	.edmac_endian	= EDMAC_LITTLE_ENDIAN,
+	.register_type	= SH_ETH_REG_FAST_RCAR,
+	.phy_interface	= PHY_INTERFACE_MODE_RMII,
+	/*
+	 * Although the LINK signal is available on the board, it's connected to
+	 * the link/activity LED output of the PHY, thus the link disappears and
+	 * reappears after each packet.  We'd be better off ignoring such signal
+	 * and getting the link state from the PHY indirectly.
+	 */
+	.no_ether_link	= 1,
+};
+
+/* I2C */
+static struct i2c_board_info i2c0_devices[] = {
+	{
+		I2C_BOARD_INFO("rx8581", 0x51),
+	},
+};
+
+/* HSPI*/
+static struct mtd_partition m25p80_spi_flash_partitions[] = {
+	{
+		.name	= "data(spi)",
+		.size	= 0x0100000,
+		.offset	= 0,
+	},
+};
+
+static struct flash_platform_data spi_flash_data = {
+	.name		= "m25p80",
+	.type		= "s25fl008k",
+	.parts		= m25p80_spi_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(m25p80_spi_flash_partitions),
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+	{
+		.modalias	= "m25p80",
+		.max_speed_hz	= 104000000,
+		.chip_select	= 0,
+		.bus_num	= 0,
+		.mode		= SPI_MODE_0,
+		.platform_data	= &spi_flash_data,
+	},
+};
+
+/* MMC */
+static struct sh_mmcif_plat_data sh_mmcif_plat = {
+	.sup_pclk	= 0,
+	.ocr		= MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
+	.caps		= MMC_CAP_4_BIT_DATA |
+			  MMC_CAP_8_BIT_DATA |
+			  MMC_CAP_NEEDS_POLL,
+};
+
+static const struct pinctrl_map bockw_pinctrl_map[] = {
+	/* Ether */
+	PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778",
+				  "ether_rmii", "ether"),
+	/* HSPI0 */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7778",
+				  "hspi0_a", "hspi0"),
+	/* MMC */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif", "pfc-r8a7778",
+				  "mmc_data8", "mmc"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif", "pfc-r8a7778",
+				  "mmc_ctrl", "mmc"),
+	/* SCIF0 */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778",
+				  "scif0_data_a", "scif0"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a7778",
+				  "scif0_ctrl", "scif0"),
+	/* USB */
+	PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778",
+				  "usb0", "usb0"),
+	PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778",
+				  "usb1", "usb1"),
+	/* SDHI0 */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+				  "sdhi0_data4", "sdhi0"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+				  "sdhi0_ctrl", "sdhi0"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+				  "sdhi0_cd", "sdhi0"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778",
+				  "sdhi0_wp", "sdhi0"),
+};
+
+#define FPGA	0x18200000
 #define IRQ0MR	0x30
+#define PFC	0xfffc0000
+#define PUPR4	0x110
 static void __init bockw_init(void)
 {
-	void __iomem *fpga;
+	void __iomem *base;
 
 	r8a7778_clock_init();
 	r8a7778_init_irq_extpin(1);
 	r8a7778_add_standard_devices();
+	r8a7778_add_usb_phy_device(&usb_phy_platform_data);
+	r8a7778_add_ether_device(&ether_platform_data);
+	r8a7778_add_i2c_device(0);
+	r8a7778_add_hspi_device(0);
+	r8a7778_add_mmc_device(&sh_mmcif_plat);
 
-	fpga = ioremap_nocache(0x18200000, SZ_1M);
-	if (fpga) {
+	i2c_register_board_info(0, i2c0_devices,
+				ARRAY_SIZE(i2c0_devices));
+	spi_register_board_info(spi_board_info,
+				ARRAY_SIZE(spi_board_info));
+	pinctrl_register_mappings(bockw_pinctrl_map,
+				  ARRAY_SIZE(bockw_pinctrl_map));
+	r8a7778_pinmux_init();
+
+	/* for SMSC */
+	base = ioremap_nocache(FPGA, SZ_1M);
+	if (base) {
 		/*
 		 * CAUTION
 		 *
@@ -55,16 +211,33 @@ static void __init bockw_init(void)
 		 * it should be cared in the future
 		 * Now, it is assuming IRQ0 was used only from SMSC.
 		 */
-		u16 val = ioread16(fpga + IRQ0MR);
+		u16 val = ioread16(base + IRQ0MR);
 		val &= ~(1 << 4); /* enable SMSC911x */
-		iowrite16(val, fpga + IRQ0MR);
-		iounmap(fpga);
+		iowrite16(val, base + IRQ0MR);
+		iounmap(base);
+
+		regulator_register_fixed(0, dummy_supplies,
+					 ARRAY_SIZE(dummy_supplies));
 
 		platform_device_register_resndata(
 			&platform_bus, "smsc911x", -1,
 			smsc911x_resources, ARRAY_SIZE(smsc911x_resources),
 			&smsc911x_data, sizeof(smsc911x_data));
 	}
+
+	/* for SDHI */
+	base = ioremap_nocache(PFC, 0x200);
+	if (base) {
+		/*
+		 * FIXME
+		 *
+		 * SDHI CD/WP pin needs pull-up
+		 */
+		iowrite32(ioread32(base + PUPR4) | (3 << 26), base + PUPR4);
+		iounmap(base);
+
+		r8a7778_sdhi_init(0, &sdhi0_info);
+	}
 }
 
 static const char *bockw_boards_compat_dt[] __initdata = {
@@ -78,4 +251,5 @@ DT_MACHINE_START(BOCKW_DT, "bockw")
 	.init_machine	= bockw_init,
 	.init_time	= shmobile_timer_init,
 	.dt_compat	= bockw_boards_compat_dt,
+	.init_late      = r8a7778_init_late,
 MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-bonito.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-bonito.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-bonito.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-bonito.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,495 +0,0 @@
-/*
- * bonito board support
- *
- * Copyright (C) 2011 Renesas Solutions Corp.
- * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/machine.h>
-#include <linux/smsc911x.h>
-#include <linux/videodev2.h>
-#include <mach/common.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
-#include <asm/hardware/cache-l2x0.h>
-#include <mach/r8a7740.h>
-#include <mach/irqs.h>
-#include <video/sh_mobile_lcdc.h>
-
-/*
- * CS	Address		device			note
- *----------------------------------------------------------------
- * 0	0x0000_0000	NOR Flash (64MB)	SW12 : bit3 = OFF
- * 2	0x0800_0000	ExtNOR (64MB)		SW12 : bit3 = OFF
- * 4			-
- * 5A			-
- * 5B	0x1600_0000	SRAM (8MB)
- * 6	0x1800_0000	FPGA (64K)
- *	0x1801_0000	Ether (4KB)
- *	0x1801_1000	USB (4KB)
- */
-
-/*
- * SW12
- *
- *	bit1			bit2			bit3
- *----------------------------------------------------------------------------
- * ON	NOR WriteProtect	NAND WriteProtect	CS0 ExtNOR / CS2 NOR
- * OFF	NOR Not WriteProtect	NAND Not WriteProtect	CS0 NOR    / CS2 ExtNOR
- */
-
-/*
- * SCIFA5 (CN42)
- *
- * S38.3 = ON
- * S39.6 = ON
- * S43.1 = ON
- */
-
-/*
- * LCDC0 (CN3/CN4/CN7)
- *
- * S38.1 = OFF
- * S38.2 = OFF
- */
-
-/* Dummy supplies, where voltage doesn't matter */
-static struct regulator_consumer_supply dummy_supplies[] = {
-	REGULATOR_SUPPLY("vddvario", "smsc911x"),
-	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
-};
-
-/*
- * FPGA
- */
-#define IRQSR0		0x0020
-#define IRQSR1		0x0022
-#define IRQMR0		0x0030
-#define IRQMR1		0x0032
-#define BUSSWMR1	0x0070
-#define BUSSWMR2	0x0072
-#define BUSSWMR3	0x0074
-#define BUSSWMR4	0x0076
-
-#define LCDCR		0x10B4
-#define DEVRSTCR1	0x10D0
-#define DEVRSTCR2	0x10D2
-#define A1MDSR		0x10E0
-#define BVERR		0x1100
-
-/* FPGA IRQ */
-#define FPGA_IRQ_BASE		(512)
-#define FPGA_IRQ0		(FPGA_IRQ_BASE)
-#define FPGA_IRQ1		(FPGA_IRQ_BASE + 16)
-#define FPGA_ETH_IRQ		(FPGA_IRQ0 + 15)
-static u16 bonito_fpga_read(u32 offset)
-{
-	return __raw_readw(IOMEM(0xf0003000) + offset);
-}
-
-static void bonito_fpga_write(u32 offset, u16 val)
-{
-	__raw_writew(val, IOMEM(0xf0003000) + offset);
-}
-
-static void bonito_fpga_irq_disable(struct irq_data *data)
-{
-	unsigned int irq = data->irq;
-	u32 addr = (irq < 1016) ? IRQMR0 : IRQMR1;
-	int shift = irq % 16;
-
-	bonito_fpga_write(addr, bonito_fpga_read(addr) | (1 << shift));
-}
-
-static void bonito_fpga_irq_enable(struct irq_data *data)
-{
-	unsigned int irq = data->irq;
-	u32 addr = (irq < 1016) ? IRQMR0 : IRQMR1;
-	int shift = irq % 16;
-
-	bonito_fpga_write(addr, bonito_fpga_read(addr) & ~(1 << shift));
-}
-
-static struct irq_chip bonito_fpga_irq_chip __read_mostly = {
-	.name		= "bonito FPGA",
-	.irq_mask	= bonito_fpga_irq_disable,
-	.irq_unmask	= bonito_fpga_irq_enable,
-};
-
-static void bonito_fpga_irq_demux(unsigned int irq, struct irq_desc *desc)
-{
-	u32 val =  bonito_fpga_read(IRQSR1) << 16 |
-		   bonito_fpga_read(IRQSR0);
-	u32 mask = bonito_fpga_read(IRQMR1) << 16 |
-		   bonito_fpga_read(IRQMR0);
-
-	int i;
-
-	val &= ~mask;
-
-	for (i = 0; i < 32; i++) {
-		if (!(val & (1 << i)))
-			continue;
-
-		generic_handle_irq(FPGA_IRQ_BASE + i);
-	}
-}
-
-static void bonito_fpga_init(void)
-{
-	int i;
-
-	bonito_fpga_write(IRQMR0, 0xffff); /* mask all */
-	bonito_fpga_write(IRQMR1, 0xffff); /* mask all */
-
-	/* Device reset */
-	bonito_fpga_write(DEVRSTCR1,
-		   (1 << 2));	/* Eth */
-
-	/* FPGA irq require special handling */
-	for (i = FPGA_IRQ_BASE; i < FPGA_IRQ_BASE + 32; i++) {
-		irq_set_chip_and_handler_name(i, &bonito_fpga_irq_chip,
-					      handle_level_irq, "level");
-		set_irq_flags(i, IRQF_VALID); /* yuck */
-	}
-
-	irq_set_chained_handler(evt2irq(0x0340), bonito_fpga_irq_demux);
-	irq_set_irq_type(evt2irq(0x0340), IRQ_TYPE_LEVEL_LOW);
-}
-
-/*
-* PMIC settings
-*
-* FIXME
-*
-* bonito board needs some settings by pmic which use i2c access.
-* pmic settings use device_initcall() here for use it.
-*/
-static __u8 *pmic_settings = NULL;
-static __u8 pmic_do_2A[] = {
-	0x1C, 0x09,
-	0x1A, 0x80,
-	0xff, 0xff,
-};
-
-static int __init pmic_init(void)
-{
-	struct i2c_adapter *a = i2c_get_adapter(0);
-	struct i2c_msg msg;
-	__u8 buf[2];
-	int i, ret;
-
-	if (!pmic_settings)
-		return 0;
-	if (!a)
-		return 0;
-
-	msg.addr	= 0x46;
-	msg.buf		= buf;
-	msg.len		= 2;
-	msg.flags	= 0;
-
-	for (i = 0; ; i += 2) {
-		buf[0] = pmic_settings[i + 0];
-		buf[1] = pmic_settings[i + 1];
-
-		if ((0xff == buf[0]) && (0xff == buf[1]))
-			break;
-
-		ret = i2c_transfer(a, &msg, 1);
-		if (ret < 0) {
-			pr_err("i2c transfer fail\n");
-			break;
-		}
-	}
-
-	return 0;
-}
-device_initcall(pmic_init);
-
-/*
- * LCDC0
- */
-static const struct fb_videomode lcdc0_mode = {
-	.name		= "WVGA Panel",
-	.xres		= 800,
-	.yres		= 480,
-	.left_margin	= 88,
-	.right_margin	= 40,
-	.hsync_len	= 128,
-	.upper_margin	= 20,
-	.lower_margin	= 5,
-	.vsync_len	= 5,
-	.sync		= 0,
-};
-
-static struct sh_mobile_lcdc_info lcdc0_info = {
-	.clock_source	= LCDC_CLK_BUS,
-	.ch[0] = {
-		.chan			= LCDC_CHAN_MAINLCD,
-		.fourcc = V4L2_PIX_FMT_RGB565,
-		.interface_type		= RGB24,
-		.clock_divider		= 5,
-		.flags			= 0,
-		.lcd_modes		= &lcdc0_mode,
-		.num_modes		= 1,
-		.panel_cfg = {
-			.width	= 152,
-			.height = 91,
-		},
-	},
-};
-
-static struct resource lcdc0_resources[] = {
-	[0] = {
-		.name	= "LCDC0",
-		.start	= 0xfe940000,
-		.end	= 0xfe943fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= intcs_evt2irq(0x0580),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device lcdc0_device = {
-	.name		= "sh_mobile_lcdc_fb",
-	.id		= 0,
-	.resource	= lcdc0_resources,
-	.num_resources	= ARRAY_SIZE(lcdc0_resources),
-	.dev	= {
-		.platform_data	= &lcdc0_info,
-		.coherent_dma_mask = ~0,
-	},
-};
-
-static const struct pinctrl_map lcdc0_pinctrl_map[] = {
-	/* LCD0 */
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
-				  "lcd0_data24_1", "lcd0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
-				  "lcd0_lclk_1", "lcd0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-r8a7740",
-				  "lcd0_sync", "lcd0"),
-};
-
-/*
- * SMSC 9221
- */
-static struct resource smsc_resources[] = {
-	[0] = {
-		.start		= 0x18010000,
-		.end		= 0x18011000 - 1,
-		.flags		= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start		= FPGA_ETH_IRQ,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct smsc911x_platform_config smsc_platdata = {
-	.flags		= SMSC911X_USE_16BIT,
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
-};
-
-static struct platform_device smsc_device = {
-	.name		= "smsc911x",
-	.dev  = {
-		.platform_data = &smsc_platdata,
-	},
-	.resource	= smsc_resources,
-	.num_resources	= ARRAY_SIZE(smsc_resources),
-};
-
-/*
- * core board devices
- */
-static struct platform_device *bonito_core_devices[] __initdata = {
-};
-
-/*
- * base board devices
- */
-static struct platform_device *bonito_base_devices[] __initdata = {
-	&lcdc0_device,
-	&smsc_device,
-};
-
-/*
- * map I/O
- */
-static struct map_desc bonito_io_desc[] __initdata = {
-	/*
-	 * for FPGA (0x1800000-0x19ffffff)
-	 * 0x18000000-0x18002000 -> 0xf0003000-0xf0005000
-	 */
-	{
-		.virtual	= 0xf0003000,
-		.pfn		= __phys_to_pfn(0x18000000),
-		.length		= PAGE_SIZE * 2,
-		.type		= MT_DEVICE_NONSHARED
-	}
-};
-
-static void __init bonito_map_io(void)
-{
-	r8a7740_map_io();
-	iotable_init(bonito_io_desc, ARRAY_SIZE(bonito_io_desc));
-}
-
-/*
- * board init
- */
-#define BIT_ON(sw, bit)		(sw & (1 << bit))
-#define BIT_OFF(sw, bit)	(!(sw & (1 << bit)))
-
-#define VCCQ1CR		IOMEM(0xE6058140)
-#define VCCQ1LCDCR	IOMEM(0xE6058186)
-
-static void __init bonito_init(void)
-{
-	u16 val;
-
-	regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
-
-	r8a7740_pinmux_init();
-	bonito_fpga_init();
-
-	pmic_settings = pmic_do_2A;
-
-	/*
-	 * core board settings
-	 */
-
-#ifdef CONFIG_CACHE_L2X0
-	/* Early BRESP enable, Shared attribute override enable, 32K*8way */
-	l2x0_init(IOMEM(0xf0002000), 0x40440000, 0x82000fff);
-#endif
-
-	r8a7740_add_standard_devices();
-
-	platform_add_devices(bonito_core_devices,
-			     ARRAY_SIZE(bonito_core_devices));
-
-	/*
-	 * base board settings
-	 */
-	gpio_request_one(176, GPIOF_IN, NULL);
-	if (!gpio_get_value(176)) {
-		u16 bsw2;
-		u16 bsw3;
-		u16 bsw4;
-
-		/*
-		 * FPGA
-		 */
-		gpio_request(GPIO_FN_CS5B,		NULL);
-		gpio_request(GPIO_FN_CS6A,		NULL);
-		gpio_request(GPIO_FN_CS5A_PORT105,	NULL);
-		gpio_request(GPIO_FN_IRQ10,		NULL);
-
-		val = bonito_fpga_read(BVERR);
-		pr_info("bonito version: cpu %02x, base %02x\n",
-			((val >> 8) & 0xFF),
-			((val >> 0) & 0xFF));
-
-		bsw2 = bonito_fpga_read(BUSSWMR2);
-		bsw3 = bonito_fpga_read(BUSSWMR3);
-		bsw4 = bonito_fpga_read(BUSSWMR4);
-
-		/*
-		 * SCIFA5 (CN42)
-		 */
-		if (BIT_OFF(bsw2, 1) &&	/* S38.3 = ON */
-		    BIT_OFF(bsw3, 9) &&	/* S39.6 = ON */
-		    BIT_OFF(bsw4, 4)) {	/* S43.1 = ON */
-			gpio_request(GPIO_FN_SCIFA5_TXD_PORT91,	NULL);
-			gpio_request(GPIO_FN_SCIFA5_RXD_PORT92,	NULL);
-		}
-
-		/*
-		 * LCDC0 (CN3)
-		 */
-		if (BIT_ON(bsw2, 3) &&	/* S38.1 = OFF */
-		    BIT_ON(bsw2, 2)) {	/* S38.2 = OFF */
-			pinctrl_register_mappings(lcdc0_pinctrl_map,
-						  ARRAY_SIZE(lcdc0_pinctrl_map));
-			gpio_request(GPIO_FN_LCDC0_SELECT, NULL);
-
-			gpio_request_one(61, GPIOF_OUT_INIT_HIGH,
-					 NULL); /* LCDDON */
-
-			/* backlight on */
-			bonito_fpga_write(LCDCR, 1);
-
-			/*  drivability Max */
-			__raw_writew(0x00FF , VCCQ1LCDCR);
-			__raw_writew(0xFFFF , VCCQ1CR);
-		}
-
-		platform_add_devices(bonito_base_devices,
-				     ARRAY_SIZE(bonito_base_devices));
-	}
-}
-
-static void __init bonito_earlytimer_init(void)
-{
-	u16 val;
-	u8 md_ck = 0;
-
-	/* read MD_CK value */
-	val = bonito_fpga_read(A1MDSR);
-	if (val & (1 << 10))
-		md_ck |= MD_CK2;
-	if (val & (1 << 9))
-		md_ck |= MD_CK1;
-	if (val & (1 << 8))
-		md_ck |= MD_CK0;
-
-	r8a7740_clock_init(md_ck);
-	shmobile_earlytimer_init();
-}
-
-static void __init bonito_add_early_devices(void)
-{
-	r8a7740_add_early_devices();
-}
-
-MACHINE_START(BONITO, "bonito")
-	.map_io		= bonito_map_io,
-	.init_early	= bonito_add_early_devices,
-	.init_irq	= r8a7740_init_irq,
-	.handle_irq	= shmobile_handle_irq_intc,
-	.init_machine	= bonito_init,
-	.init_late	= shmobile_init_late,
-	.init_time	= bonito_earlytimer_init,
-MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-kzm9d.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-kzm9d.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-kzm9d.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-kzm9d.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,7 +56,7 @@ static struct smsc911x_platform_config s
 
 static struct platform_device smsc91x_device = {
 	.name	= "smsc911x",
-	.id	= 0,
+	.id	= -1,
 	.dev	= {
 		  .platform_data = &smsc911x_platdata,
 		},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-kzm9g.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-kzm9g.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-kzm9g.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-kzm9g.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,10 +29,12 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/sh_mmcif.h>
 #include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/mfd/as3711.h>
 #include <linux/mfd/tmio.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/pinctrl/pinconf-generic.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 #include <linux/smsc911x.h>
@@ -606,6 +608,140 @@ static struct platform_device fsi_ak4648
 };
 
 /* I2C */
+
+/* StepDown1 is used to supply 1.315V to the CPU */
+static struct regulator_init_data as3711_sd1 = {
+	.constraints = {
+		.name = "1.315V CPU",
+		.boot_on = 1,
+		.always_on = 1,
+		.min_uV = 1315000,
+		.max_uV = 1335000,
+	},
+};
+
+/* StepDown2 is used to supply 1.8V to the CPU and to the board */
+static struct regulator_init_data as3711_sd2 = {
+	.constraints = {
+		.name = "1.8V",
+		.boot_on = 1,
+		.always_on = 1,
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+	},
+};
+
+/*
+ * StepDown3 is switched in parallel with StepDown2, seems to be off,
+ * according to read-back pre-set register values
+ */
+
+/* StepDown4 is used to supply 1.215V to the CPU and to the board */
+static struct regulator_init_data as3711_sd4 = {
+	.constraints = {
+		.name = "1.215V",
+		.boot_on = 1,
+		.always_on = 1,
+		.min_uV = 1215000,
+		.max_uV = 1235000,
+	},
+};
+
+/* LDO1 is unused and unconnected */
+
+/* LDO2 is used to supply 2.8V to the CPU */
+static struct regulator_init_data as3711_ldo2 = {
+	.constraints = {
+		.name = "2.8V CPU",
+		.boot_on = 1,
+		.always_on = 1,
+		.min_uV = 2800000,
+		.max_uV = 2800000,
+	},
+};
+
+/* LDO3 is used to supply 3.0V to the CPU */
+static struct regulator_init_data as3711_ldo3 = {
+	.constraints = {
+		.name = "3.0V CPU",
+		.boot_on = 1,
+		.always_on = 1,
+		.min_uV = 3000000,
+		.max_uV = 3000000,
+	},
+};
+
+/* LDO4 is used to supply 2.8V to the board */
+static struct regulator_init_data as3711_ldo4 = {
+	.constraints = {
+		.name = "2.8V",
+		.boot_on = 1,
+		.always_on = 1,
+		.min_uV = 2800000,
+		.max_uV = 2800000,
+	},
+};
+
+/* LDO5 is switched parallel to LDO4, also set to 2.8V */
+static struct regulator_init_data as3711_ldo5 = {
+	.constraints = {
+		.name = "2.8V #2",
+		.boot_on = 1,
+		.always_on = 1,
+		.min_uV = 2800000,
+		.max_uV = 2800000,
+	},
+};
+
+/* LDO6 is unused and unconnected */
+
+/* LDO7 is used to supply 1.15V to the CPU */
+static struct regulator_init_data as3711_ldo7 = {
+	.constraints = {
+		.name = "1.15V CPU",
+		.boot_on = 1,
+		.always_on = 1,
+		.min_uV = 1150000,
+		.max_uV = 1150000,
+	},
+};
+
+/* LDO8 is switched parallel to LDO7, also set to 1.15V */
+static struct regulator_init_data as3711_ldo8 = {
+	.constraints = {
+		.name = "1.15V CPU #2",
+		.boot_on = 1,
+		.always_on = 1,
+		.min_uV = 1150000,
+		.max_uV = 1150000,
+	},
+};
+
+static struct as3711_platform_data as3711_pdata = {
+	.regulator	= {
+		.init_data	= {
+			[AS3711_REGULATOR_SD_1] = &as3711_sd1,
+			[AS3711_REGULATOR_SD_2] = &as3711_sd2,
+			[AS3711_REGULATOR_SD_4] = &as3711_sd4,
+			[AS3711_REGULATOR_LDO_2] = &as3711_ldo2,
+			[AS3711_REGULATOR_LDO_3] = &as3711_ldo3,
+			[AS3711_REGULATOR_LDO_4] = &as3711_ldo4,
+			[AS3711_REGULATOR_LDO_5] = &as3711_ldo5,
+			[AS3711_REGULATOR_LDO_7] = &as3711_ldo7,
+			[AS3711_REGULATOR_LDO_8] = &as3711_ldo8,
+		},
+	},
+	.backlight	= {
+		.su2_fb = "sh_mobile_lcdc_fb.0",
+		.su2_max_uA = 36000,
+		.su2_feedback = AS3711_SU2_CURR_AUTO,
+		.su2_fbprot = AS3711_SU2_GPIO4,
+		.su2_auto_curr1 = true,
+		.su2_auto_curr2 = true,
+		.su2_auto_curr3 = true,
+	},
+};
+
 static struct pcf857x_platform_data pcf8575_pdata = {
 	.gpio_base	= GPIO_PCF8575_BASE,
 };
@@ -625,6 +761,11 @@ static struct i2c_board_info i2c0_device
 		I2C_BOARD_INFO("adxl34x", 0x1d),
 		.irq = irq_pin(26), /* IRQ26 */
 	},
+	{
+		I2C_BOARD_INFO("as3711", 0x40),
+		.irq = intcs_evt2irq(0x3300), /* IRQ24 */
+		.platform_data = &as3711_pdata,
+	},
 };
 
 static struct i2c_board_info i2c1_devices[] = {
@@ -663,13 +804,13 @@ static unsigned long pin_pullup_conf[] =
 
 static const struct pinctrl_map kzm_pinctrl_map[] = {
 	/* FSIA (AK4648) */
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0",
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0",
 				  "fsia_mclk_in", "fsia"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0",
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0",
 				  "fsia_sclk_in", "fsia"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0",
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0",
 				  "fsia_data_in", "fsia"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2.0", "pfc-sh73a0",
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0",
 				  "fsia_data_out", "fsia"),
 	/* I2C3 */
 	PIN_MAP_MUX_GROUP_DEFAULT("i2c-sh_mobile.3", "pfc-sh73a0",
@@ -715,59 +856,6 @@ static const struct pinctrl_map kzm_pinc
 				  "usb_vbus", "usb"),
 };
 
-/*
- * FIXME
- *
- * This is quick hack for enabling LCDC backlight
- */
-static int __init as3711_enable_lcdc_backlight(void)
-{
-	struct i2c_adapter *a = i2c_get_adapter(0);
-	struct i2c_msg msg;
-	int i, ret;
-	__u8 magic[] = {
-		0x40, 0x2a,
-		0x43, 0x3c,
-		0x44, 0x3c,
-		0x45, 0x3c,
-		0x54, 0x03,
-		0x51, 0x00,
-		0x51, 0x01,
-		0xff, 0x00, /* wait */
-		0x43, 0xf0,
-		0x44, 0xf0,
-		0x45, 0xf0,
-	};
-
-	if (!of_machine_is_compatible("renesas,kzm9g"))
-		return 0;
-
-	if (!a)
-		return 0;
-
-	msg.addr	= 0x40;
-	msg.len		= 2;
-	msg.flags	= 0;
-
-	for (i = 0; i < ARRAY_SIZE(magic); i += 2) {
-		msg.buf = magic + i;
-
-		if (0xff == msg.buf[0]) {
-			udelay(500);
-			continue;
-		}
-
-		ret = i2c_transfer(a, &msg, 1);
-		if (ret < 0) {
-			pr_err("i2c transfer fail\n");
-			break;
-		}
-	}
-
-	return 0;
-}
-device_initcall(as3711_enable_lcdc_backlight);
-
 static void __init kzm_init(void)
 {
 	regulator_register_always_on(2, "fixed-1.8V", fixed1v8_power_consumers,
@@ -788,9 +876,6 @@ static void __init kzm_init(void)
 	/* Touchscreen */
 	gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */
 
-	/* enable SD */
-	gpio_request(GPIO_FN_SDHI0_VCCQ_MC0_ON,	NULL);
-
 #ifdef CONFIG_CACHE_L2X0
 	/* Early BRESP enable, Shared attribute override enable, 64K*8way */
 	l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
@@ -806,7 +891,7 @@ static void __init kzm_init(void)
 	sh73a0_pm_init();
 }
 
-static void kzm9g_restart(char mode, const char *cmd)
+static void kzm9g_restart(enum reboot_mode mode, const char *cmd)
 {
 #define RESCNT2 IOMEM(0xe6188020)
 	/* Do soft power on reset */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-kzm9g-reference.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-kzm9g-reference.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-kzm9g-reference.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-kzm9g-reference.c	2013-08-25 20:43:22.000000000 -0400
@@ -79,7 +79,6 @@ static void __init kzm_init(void)
 	sh73a0_pinmux_init();
 
 	/* enable SD */
-	gpio_request(GPIO_FN_SDHI0_VCCQ_MC0_ON,	NULL);
 	gpio_request_one(15, GPIOF_OUT_INIT_HIGH, NULL); /* power */
 
 	gpio_request_one(14, GPIOF_OUT_INIT_HIGH, NULL); /* power */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-lager.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-lager.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-lager.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-lager.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,19 +18,83 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/irqchip.h>
 #include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_device.h>
 #include <mach/common.h>
 #include <mach/r8a7790.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+/* LEDS */
+static struct gpio_led lager_leds[] = {
+	{
+		.name		= "led8",
+		.gpio		= RCAR_GP_PIN(5, 17),
+		.default_state	= LEDS_GPIO_DEFSTATE_ON,
+	}, {
+		.name		= "led7",
+		.gpio		= RCAR_GP_PIN(4, 23),
+		.default_state	= LEDS_GPIO_DEFSTATE_ON,
+	}, {
+		.name		= "led6",
+		.gpio		= RCAR_GP_PIN(4, 22),
+		.default_state	= LEDS_GPIO_DEFSTATE_ON,
+	},
+};
+
+static __initdata struct gpio_led_platform_data lager_leds_pdata = {
+	.leds		= lager_leds,
+	.num_leds	= ARRAY_SIZE(lager_leds),
+};
+
+/* GPIO KEY */
+#define GPIO_KEY(c, g, d, ...) \
+	{ .code = c, .gpio = g, .desc = d, .active_low = 1 }
+
+static struct gpio_keys_button gpio_buttons[] = {
+	GPIO_KEY(KEY_4,		RCAR_GP_PIN(1, 28),	"SW2-pin4"),
+	GPIO_KEY(KEY_3,		RCAR_GP_PIN(1, 26),	"SW2-pin3"),
+	GPIO_KEY(KEY_2,		RCAR_GP_PIN(1, 24),	"SW2-pin2"),
+	GPIO_KEY(KEY_1,		RCAR_GP_PIN(1, 14),	"SW2-pin1"),
+};
+
+static __initdata struct gpio_keys_platform_data lager_keys_pdata = {
+	.buttons	= gpio_buttons,
+	.nbuttons	= ARRAY_SIZE(gpio_buttons),
+};
+
+static const struct pinctrl_map lager_pinctrl_map[] = {
+	/* SCIF0 (CN19: DEBUG SERIAL0) */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790",
+				  "scif0_data", "scif0"),
+	/* SCIF1 (CN20: DEBUG SERIAL1) */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.7", "pfc-r8a7790",
+				  "scif1_data", "scif1"),
+};
+
 static void __init lager_add_standard_devices(void)
 {
 	r8a7790_clock_init();
+
+	pinctrl_register_mappings(lager_pinctrl_map,
+				  ARRAY_SIZE(lager_pinctrl_map));
+	r8a7790_pinmux_init();
+
 	r8a7790_add_standard_devices();
+	platform_device_register_data(&platform_bus, "leds-gpio", -1,
+				      &lager_leds_pdata,
+				      sizeof(lager_leds_pdata));
+	platform_device_register_data(&platform_bus, "gpio-keys", -1,
+				      &lager_keys_pdata,
+				      sizeof(lager_keys_pdata));
 }
 
 static const char *lager_boards_compat_dt[] __initdata = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-mackerel.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-mackerel.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-mackerel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-mackerel.c	2013-08-25 20:43:22.000000000 -0400
@@ -1309,6 +1309,49 @@ static struct i2c_board_info i2c1_device
 };
 
 static const struct pinctrl_map mackerel_pinctrl_map[] = {
+	/* ADXL34X */
+	PIN_MAP_MUX_GROUP_DEFAULT("1-0053", "pfc-sh7372",
+				  "intc_irq21", "intc"),
+	/* CEU */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-sh7372",
+				  "ceu_data_0_7", "ceu"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-sh7372",
+				  "ceu_clk_0", "ceu"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-sh7372",
+				  "ceu_sync", "ceu"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_ceu.0", "pfc-sh7372",
+				  "ceu_field", "ceu"),
+	/* FLCTL */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_flctl.0", "pfc-sh7372",
+				  "flctl_data", "flctl"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_flctl.0", "pfc-sh7372",
+				  "flctl_ce0", "flctl"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_flctl.0", "pfc-sh7372",
+				  "flctl_ctrl", "flctl"),
+	/* FSIA (AK4643) */
+	PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-sh7372",
+				  "fsia_sclk_in", "fsia"),
+	PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-sh7372",
+				  "fsia_data_in", "fsia"),
+	PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.0", "pfc-sh7372",
+				  "fsia_data_out", "fsia"),
+	/* FSIB (HDMI) */
+	PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.1", "pfc-sh7372",
+				  "fsib_mclk_in", "fsib"),
+	/* HDMI */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-mobile-hdmi", "pfc-sh7372",
+				  "hdmi", "hdmi"),
+	/* LCDC */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh7372",
+				  "lcd_data24", "lcd"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh7372",
+				  "lcd_sync", "lcd"),
+	/* SCIFA0 */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-sh7372",
+				  "scifa0_data", "scifa0"),
+	/* SCIFA2 (GT-720F GPS module) */
+	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.2", "pfc-sh7372",
+				  "scifa2_data", "scifa2"),
 	/* SDHI0 */
 	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372",
 				  "sdhi0_data4", "sdhi0"),
@@ -1316,6 +1359,8 @@ static const struct pinctrl_map mackerel
 				  "sdhi0_ctrl", "sdhi0"),
 	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372",
 				  "sdhi0_wp", "sdhi0"),
+	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh7372",
+				  "intc_irq26_1", "intc"),
 	/* SDHI1 */
 #if !IS_ENABLED(CONFIG_MMC_SH_MMCIF)
 	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-sh7372",
@@ -1334,6 +1379,25 @@ static const struct pinctrl_map mackerel
 				  "sdhi2_data4", "sdhi2"),
 	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-sh7372",
 				  "sdhi2_ctrl", "sdhi2"),
+	/* SMSC911X */
+	PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-sh7372",
+				  "bsc_cs5a", "bsc"),
+	PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-sh7372",
+				  "intc_irq6_0", "intc"),
+	/* ST1232 */
+	PIN_MAP_MUX_GROUP_DEFAULT("0-0055", "pfc-sh7372",
+				  "intc_irq7_0", "intc"),
+	/* TCA6416 */
+	PIN_MAP_MUX_GROUP_DEFAULT("0-0020", "pfc-sh7372",
+				  "intc_irq9_0", "intc"),
+	/* USBHS0 */
+	PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs.0", "pfc-sh7372",
+				  "usb0_vbus", "usb0"),
+	/* USBHS1 */
+	PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs.1", "pfc-sh7372",
+				  "usb1_vbus", "usb1"),
+	PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs.1", "pfc-sh7372",
+				  "usb1_otg_id_0", "usb1"),
 };
 
 #define GPIO_PORT9CR	IOMEM(0xE6051009)
@@ -1377,61 +1441,18 @@ static void __init mackerel_init(void)
 				  ARRAY_SIZE(mackerel_pinctrl_map));
 	sh7372_pinmux_init();
 
-	/* enable SCIFA0 */
-	gpio_request(GPIO_FN_SCIFA0_TXD, NULL);
-	gpio_request(GPIO_FN_SCIFA0_RXD, NULL);
-
-	/* enable SMSC911X */
-	gpio_request(GPIO_FN_CS5A,	NULL);
-	gpio_request(GPIO_FN_IRQ6_39,	NULL);
-
-	/* LCDC */
-	gpio_request(GPIO_FN_LCDD23,   NULL);
-	gpio_request(GPIO_FN_LCDD22,   NULL);
-	gpio_request(GPIO_FN_LCDD21,   NULL);
-	gpio_request(GPIO_FN_LCDD20,   NULL);
-	gpio_request(GPIO_FN_LCDD19,   NULL);
-	gpio_request(GPIO_FN_LCDD18,   NULL);
-	gpio_request(GPIO_FN_LCDD17,   NULL);
-	gpio_request(GPIO_FN_LCDD16,   NULL);
-	gpio_request(GPIO_FN_LCDD15,   NULL);
-	gpio_request(GPIO_FN_LCDD14,   NULL);
-	gpio_request(GPIO_FN_LCDD13,   NULL);
-	gpio_request(GPIO_FN_LCDD12,   NULL);
-	gpio_request(GPIO_FN_LCDD11,   NULL);
-	gpio_request(GPIO_FN_LCDD10,   NULL);
-	gpio_request(GPIO_FN_LCDD9,    NULL);
-	gpio_request(GPIO_FN_LCDD8,    NULL);
-	gpio_request(GPIO_FN_LCDD7,    NULL);
-	gpio_request(GPIO_FN_LCDD6,    NULL);
-	gpio_request(GPIO_FN_LCDD5,    NULL);
-	gpio_request(GPIO_FN_LCDD4,    NULL);
-	gpio_request(GPIO_FN_LCDD3,    NULL);
-	gpio_request(GPIO_FN_LCDD2,    NULL);
-	gpio_request(GPIO_FN_LCDD1,    NULL);
-	gpio_request(GPIO_FN_LCDD0,    NULL);
-	gpio_request(GPIO_FN_LCDDISP,  NULL);
-	gpio_request(GPIO_FN_LCDDCK,   NULL);
-
 	/* backlight, off by default */
 	gpio_request_one(31, GPIOF_OUT_INIT_LOW, NULL);
 
 	gpio_request_one(151, GPIOF_OUT_INIT_HIGH, NULL); /* LCDDON */
 
 	/* USBHS0 */
-	gpio_request(GPIO_FN_VBUS0_0, NULL);
 	gpio_request_pulldown(GPIO_PORT168CR); /* VBUS0_0 pull down */
 
 	/* USBHS1 */
-	gpio_request(GPIO_FN_VBUS0_1, NULL);
 	gpio_request_pulldown(GPIO_PORT167CR); /* VBUS0_1 pull down */
-	gpio_request(GPIO_FN_IDIN_1_113, NULL);
 
-	/* enable FSI2 port A (ak4643) */
-	gpio_request(GPIO_FN_FSIAIBT,	NULL);
-	gpio_request(GPIO_FN_FSIAILR,	NULL);
-	gpio_request(GPIO_FN_FSIAISLD,	NULL);
-	gpio_request(GPIO_FN_FSIAOSLD,	NULL);
+	/* FSI2 port A (ak4643) */
 	gpio_request_one(161, GPIOF_OUT_INIT_LOW, NULL); /* slave */
 
 	gpio_request(9,  NULL);
@@ -1441,8 +1462,7 @@ static void __init mackerel_init(void)
 
 	intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */
 
-	/* setup FSI2 port B (HDMI) */
-	gpio_request(GPIO_FN_FSIBCK, NULL);
+	/* FSI2 port B (HDMI) */
 	__raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */
 
 	/* set SPU2 clock to 119.6 MHz */
@@ -1452,68 +1472,15 @@ static void __init mackerel_init(void)
 		clk_put(clk);
 	}
 
-	/* enable Keypad */
-	gpio_request(GPIO_FN_IRQ9_42,	NULL);
+	/* Keypad */
 	irq_set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH);
 
-	/* enable Touchscreen */
-	gpio_request(GPIO_FN_IRQ7_40,	NULL);
+	/* Touchscreen */
 	irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
 
-	/* enable Accelerometer */
-	gpio_request(GPIO_FN_IRQ21,	NULL);
+	/* Accelerometer */
 	irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH);
 
-	/* SDHI0 PORT172 card-detect IRQ26 */
-	gpio_request(GPIO_FN_IRQ26_172, NULL);
-
-	/* FLCTL */
-	gpio_request(GPIO_FN_D0_NAF0, NULL);
-	gpio_request(GPIO_FN_D1_NAF1, NULL);
-	gpio_request(GPIO_FN_D2_NAF2, NULL);
-	gpio_request(GPIO_FN_D3_NAF3, NULL);
-	gpio_request(GPIO_FN_D4_NAF4, NULL);
-	gpio_request(GPIO_FN_D5_NAF5, NULL);
-	gpio_request(GPIO_FN_D6_NAF6, NULL);
-	gpio_request(GPIO_FN_D7_NAF7, NULL);
-	gpio_request(GPIO_FN_D8_NAF8, NULL);
-	gpio_request(GPIO_FN_D9_NAF9, NULL);
-	gpio_request(GPIO_FN_D10_NAF10, NULL);
-	gpio_request(GPIO_FN_D11_NAF11, NULL);
-	gpio_request(GPIO_FN_D12_NAF12, NULL);
-	gpio_request(GPIO_FN_D13_NAF13, NULL);
-	gpio_request(GPIO_FN_D14_NAF14, NULL);
-	gpio_request(GPIO_FN_D15_NAF15, NULL);
-	gpio_request(GPIO_FN_FCE0, NULL);
-	gpio_request(GPIO_FN_WE0_FWE, NULL);
-	gpio_request(GPIO_FN_FRB, NULL);
-	gpio_request(GPIO_FN_A4_FOE, NULL);
-	gpio_request(GPIO_FN_A5_FCDE, NULL);
-	gpio_request(GPIO_FN_RD_FSC, NULL);
-
-	/* enable GPS module (GT-720F) */
-	gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
-	gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);
-
-	/* CEU */
-	gpio_request(GPIO_FN_VIO_CLK, NULL);
-	gpio_request(GPIO_FN_VIO_VD, NULL);
-	gpio_request(GPIO_FN_VIO_HD, NULL);
-	gpio_request(GPIO_FN_VIO_FIELD, NULL);
-	gpio_request(GPIO_FN_VIO_CKO, NULL);
-	gpio_request(GPIO_FN_VIO_D7, NULL);
-	gpio_request(GPIO_FN_VIO_D6, NULL);
-	gpio_request(GPIO_FN_VIO_D5, NULL);
-	gpio_request(GPIO_FN_VIO_D4, NULL);
-	gpio_request(GPIO_FN_VIO_D3, NULL);
-	gpio_request(GPIO_FN_VIO_D2, NULL);
-	gpio_request(GPIO_FN_VIO_D1, NULL);
-	gpio_request(GPIO_FN_VIO_D0, NULL);
-
-	/* HDMI */
-	gpio_request(GPIO_FN_HDMI_HPD, NULL);
-	gpio_request(GPIO_FN_HDMI_CEC, NULL);
-
 	/* Reset HDMI, must be held at least one EXTALR (32768Hz) period */
 	srcr4 = __raw_readl(SRCR4);
 	__raw_writel(srcr4 | (1 << 13), SRCR4);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-marzen.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-marzen.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/board-marzen.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/board-marzen.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/leds.h>
 #include <linux/dma-mapping.h>
 #include <linux/pinctrl/machine.h>
+#include <linux/platform_data/gpio-rcar.h>
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 #include <linux/smsc911x.h>
@@ -36,10 +37,6 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/mfd/tmio.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/ehci_pdriver.h>
-#include <linux/usb/ohci_pdriver.h>
-#include <linux/pm_runtime.h>
 #include <mach/hardware.h>
 #include <mach/r8a7779.h>
 #include <mach/common.h>
@@ -60,6 +57,8 @@ static struct regulator_consumer_supply
 	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
 };
 
+static struct rcar_phy_platform_data usb_phy_platform_data __initdata;
+
 /* SMSC LAN89218 */
 static struct resource smsc911x_resources[] = {
 	[0] = {
@@ -68,7 +67,7 @@ static struct resource smsc911x_resource
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start		= gic_iid(0x3c), /* IRQ 1 */
+		.start		= irq_pin(1), /* IRQ 1 */
 		.flags		= IORESOURCE_IRQ,
 	},
 };
@@ -149,39 +148,19 @@ static struct platform_device hspi_devic
 	.num_resources	= ARRAY_SIZE(hspi_resources),
 };
 
-/* USB PHY */
-static struct resource usb_phy_resources[] = {
-	[0] = {
-		.start		= 0xffe70000,
-		.end		= 0xffe70900 - 1,
-		.flags		= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start		= 0xfff70000,
-		.end		= 0xfff70900 - 1,
-		.flags		= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device usb_phy_device = {
-	.name		= "rcar_usb_phy",
-	.resource	= usb_phy_resources,
-	.num_resources	= ARRAY_SIZE(usb_phy_resources),
-};
-
 /* LEDS */
 static struct gpio_led marzen_leds[] = {
 	{
 		.name		= "led2",
-		.gpio		= 157,
+		.gpio		= RCAR_GP_PIN(4, 29),
 		.default_state	= LEDS_GPIO_DEFSTATE_ON,
 	}, {
 		.name		= "led3",
-		.gpio		= 158,
+		.gpio		= RCAR_GP_PIN(4, 30),
 		.default_state	= LEDS_GPIO_DEFSTATE_ON,
 	}, {
 		.name		= "led4",
-		.gpio		= 159,
+		.gpio		= RCAR_GP_PIN(4, 31),
 		.default_state	= LEDS_GPIO_DEFSTATE_ON,
 	},
 };
@@ -204,161 +183,9 @@ static struct platform_device *marzen_de
 	&sdhi0_device,
 	&thermal_device,
 	&hspi_device,
-	&usb_phy_device,
 	&leds_device,
 };
 
-/* USB */
-static struct usb_phy *phy;
-static int usb_power_on(struct platform_device *pdev)
-{
-	if (IS_ERR(phy))
-		return PTR_ERR(phy);
-
-	pm_runtime_enable(&pdev->dev);
-	pm_runtime_get_sync(&pdev->dev);
-
-	usb_phy_init(phy);
-
-	return 0;
-}
-
-static void usb_power_off(struct platform_device *pdev)
-{
-	if (IS_ERR(phy))
-		return;
-
-	usb_phy_shutdown(phy);
-
-	pm_runtime_put_sync(&pdev->dev);
-	pm_runtime_disable(&pdev->dev);
-}
-
-static struct usb_ehci_pdata ehcix_pdata = {
-	.power_on	= usb_power_on,
-	.power_off	= usb_power_off,
-	.power_suspend	= usb_power_off,
-};
-
-static struct resource ehci0_resources[] = {
-	[0] = {
-		.start	= 0xffe70000,
-		.end	= 0xffe70400 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x4c),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ehci0_device = {
-	.name	= "ehci-platform",
-	.id	= 0,
-	.dev	= {
-		.dma_mask		= &ehci0_device.dev.coherent_dma_mask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &ehcix_pdata,
-	},
-	.num_resources	= ARRAY_SIZE(ehci0_resources),
-	.resource	= ehci0_resources,
-};
-
-static struct resource ehci1_resources[] = {
-	[0] = {
-		.start	= 0xfff70000,
-		.end	= 0xfff70400 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x4d),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ehci1_device = {
-	.name	= "ehci-platform",
-	.id	= 1,
-	.dev	= {
-		.dma_mask		= &ehci1_device.dev.coherent_dma_mask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &ehcix_pdata,
-	},
-	.num_resources	= ARRAY_SIZE(ehci1_resources),
-	.resource	= ehci1_resources,
-};
-
-static struct usb_ohci_pdata ohcix_pdata = {
-	.power_on	= usb_power_on,
-	.power_off	= usb_power_off,
-	.power_suspend	= usb_power_off,
-};
-
-static struct resource ohci0_resources[] = {
-	[0] = {
-		.start	= 0xffe70400,
-		.end	= 0xffe70800 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x4c),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ohci0_device = {
-	.name	= "ohci-platform",
-	.id	= 0,
-	.dev	= {
-		.dma_mask		= &ohci0_device.dev.coherent_dma_mask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &ohcix_pdata,
-	},
-	.num_resources	= ARRAY_SIZE(ohci0_resources),
-	.resource	= ohci0_resources,
-};
-
-static struct resource ohci1_resources[] = {
-	[0] = {
-		.start	= 0xfff70400,
-		.end	= 0xfff70800 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x4d),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ohci1_device = {
-	.name	= "ohci-platform",
-	.id	= 1,
-	.dev	= {
-		.dma_mask		= &ohci1_device.dev.coherent_dma_mask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &ohcix_pdata,
-	},
-	.num_resources	= ARRAY_SIZE(ohci1_resources),
-	.resource	= ohci1_resources,
-};
-
-static struct platform_device *marzen_late_devices[] __initdata = {
-	&ehci0_device,
-	&ehci1_device,
-	&ohci0_device,
-	&ohci1_device,
-};
-
-void __init marzen_init_late(void)
-{
-	/* get usb phy */
-	phy = usb_get_phy(USB_PHY_TYPE_USB2);
-
-	shmobile_init_late();
-	platform_add_devices(marzen_late_devices,
-			     ARRAY_SIZE(marzen_late_devices));
-}
-
 static const struct pinctrl_map marzen_pinctrl_map[] = {
 	/* HSPI0 */
 	PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7779",
@@ -404,8 +231,10 @@ static void __init marzen_init(void)
 	pinctrl_register_mappings(marzen_pinctrl_map,
 				  ARRAY_SIZE(marzen_pinctrl_map));
 	r8a7779_pinmux_init();
+	r8a7779_init_irq_extpin(1); /* IRQ1 as individual interrupt */
 
 	r8a7779_add_standard_devices();
+	r8a7779_add_usb_phy_device(&usb_phy_platform_data);
 	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
 }
 
@@ -416,6 +245,6 @@ MACHINE_START(MARZEN, "marzen")
 	.nr_irqs	= NR_IRQS_LEGACY,
 	.init_irq	= r8a7779_init_irq,
 	.init_machine	= marzen_init,
-	.init_late	= marzen_init_late,
+	.init_late	= r8a7779_init_late,
 	.init_time	= r8a7779_earlytimer_init,
 MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a73a4.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a73a4.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a73a4.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a73a4.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,15 +22,44 @@
 #include <linux/kernel.h>
 #include <linux/sh_clk.h>
 #include <linux/clkdev.h>
+#include <mach/clock.h>
 #include <mach/common.h>
 
 #define CPG_BASE 0xe6150000
 #define CPG_LEN 0x270
 
-#define MPCKCR 0xe6150080
 #define SMSTPCR2 0xe6150138
+#define SMSTPCR3 0xe615013c
 #define SMSTPCR5 0xe6150144
 
+#define FRQCRA		0xE6150000
+#define FRQCRB		0xE6150004
+#define VCLKCR1		0xE6150008
+#define VCLKCR2		0xE615000C
+#define VCLKCR3		0xE615001C
+#define VCLKCR4		0xE6150014
+#define VCLKCR5		0xE6150034
+#define ZBCKCR		0xE6150010
+#define SD0CKCR		0xE6150074
+#define SD1CKCR		0xE6150078
+#define SD2CKCR		0xE615007C
+#define MMC0CKCR	0xE6150240
+#define MMC1CKCR	0xE6150244
+#define FSIACKCR	0xE6150018
+#define FSIBCKCR	0xE6150090
+#define MPCKCR		0xe6150080
+#define SPUVCKCR	0xE6150094
+#define HSICKCR		0xE615026C
+#define M4CKCR		0xE6150098
+#define PLLECR		0xE61500D0
+#define PLL1CR		0xE6150028
+#define PLL2CR		0xE615002C
+#define PLL2SCR		0xE61501F4
+#define PLL2HCR		0xE61501E4
+#define CKSCR		0xE61500C0
+
+#define CPG_MAP(o) ((o - CPG_BASE) + cpg_mapping.base)
+
 static struct clk_mapping cpg_mapping = {
 	.phys   = CPG_BASE,
 	.len    = CPG_LEN,
@@ -51,29 +80,327 @@ static struct clk extal2_clk = {
 	.mapping	= &cpg_mapping,
 };
 
+static struct sh_clk_ops followparent_clk_ops = {
+	.recalc	= followparent_recalc,
+};
+
+static struct clk main_clk = {
+	/* .parent will be set r8a73a4_clock_init */
+	.ops	= &followparent_clk_ops,
+};
+
+SH_CLK_RATIO(div2,	1, 2);
+SH_CLK_RATIO(div4,	1, 4);
+
+SH_FIXED_RATIO_CLK(main_div2_clk,	main_clk,		div2);
+SH_FIXED_RATIO_CLK(extal1_div2_clk,	extal1_clk,		div2);
+SH_FIXED_RATIO_CLK(extal2_div2_clk,	extal2_clk,		div2);
+SH_FIXED_RATIO_CLK(extal2_div4_clk,	extal2_clk,		div4);
+
+/* External FSIACK/FSIBCK clock */
+static struct clk fsiack_clk = {
+};
+
+static struct clk fsibck_clk = {
+};
+
+/*
+ *		PLL clocks
+ */
+static struct clk *pll_parent_main[] = {
+	[0] = &main_clk,
+	[1] = &main_div2_clk
+};
+
+static struct clk *pll_parent_main_extal[8] = {
+	[0] = &main_div2_clk,
+	[1] = &extal2_div2_clk,
+	[3] = &extal2_div4_clk,
+	[4] = &main_clk,
+	[5] = &extal2_clk,
+};
+
+static unsigned long pll_recalc(struct clk *clk)
+{
+	unsigned long mult = 1;
+
+	if (ioread32(CPG_MAP(PLLECR)) & (1 << clk->enable_bit))
+		mult = (((ioread32(clk->mapped_reg) >> 24) & 0x7f) + 1);
+
+	return clk->parent->rate * mult;
+}
+
+static int pll_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 val;
+	int i, ret;
+
+	if (!clk->parent_table || !clk->parent_num)
+		return -EINVAL;
+
+	/* Search the parent */
+	for (i = 0; i < clk->parent_num; i++)
+		if (clk->parent_table[i] == parent)
+			break;
+
+	if (i == clk->parent_num)
+		return -ENODEV;
+
+	ret = clk_reparent(clk, parent);
+	if (ret < 0)
+		return ret;
+
+	val = ioread32(clk->mapped_reg) &
+		~(((1 << clk->src_width) - 1) << clk->src_shift);
+
+	iowrite32(val | i << clk->src_shift, clk->mapped_reg);
+
+	return 0;
+}
+
+static struct sh_clk_ops pll_clk_ops = {
+	.recalc		= pll_recalc,
+	.set_parent	= pll_set_parent,
+};
+
+#define PLL_CLOCK(name, p, pt, w, s, reg, e)		\
+	static struct clk name = {			\
+		.ops		= &pll_clk_ops,		\
+		.flags		= CLK_ENABLE_ON_INIT,	\
+		.parent		= p,			\
+		.parent_table	= pt,			\
+		.parent_num	= ARRAY_SIZE(pt),	\
+		.src_width	= w,			\
+		.src_shift	= s,			\
+		.enable_reg	= (void __iomem *)reg,	\
+		.enable_bit	= e,			\
+		.mapping	= &cpg_mapping,		\
+	}
+
+PLL_CLOCK(pll1_clk,  &main_clk,      pll_parent_main,       1, 7, PLL1CR,  1);
+PLL_CLOCK(pll2_clk,  &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2CR,  2);
+PLL_CLOCK(pll2s_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2SCR, 4);
+PLL_CLOCK(pll2h_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2HCR, 5);
+
+SH_FIXED_RATIO_CLK(pll1_div2_clk,	pll1_clk,	div2);
+
 static struct clk *main_clks[] = {
 	&extalr_clk,
 	&extal1_clk,
+	&extal1_div2_clk,
 	&extal2_clk,
+	&extal2_div2_clk,
+	&extal2_div4_clk,
+	&main_clk,
+	&main_div2_clk,
+	&fsiack_clk,
+	&fsibck_clk,
+	&pll1_clk,
+	&pll1_div2_clk,
+	&pll2_clk,
+	&pll2s_clk,
+	&pll2h_clk,
+};
+
+/* DIV4 */
+static void div4_kick(struct clk *clk)
+{
+	unsigned long value;
+
+	/* set KICK bit in FRQCRB to update hardware setting */
+	value = ioread32(CPG_MAP(FRQCRB));
+	value |= (1 << 31);
+	iowrite32(value, CPG_MAP(FRQCRB));
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10};
+
+static struct clk_div_mult_table div4_div_mult_table = {
+	.divisors	= divisors,
+	.nr_divisors	= ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+	.div_mult_table	= &div4_div_mult_table,
+	.kick		= div4_kick,
 };
 
 enum {
+	DIV4_I, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
+	DIV4_ZX, DIV4_ZS, DIV4_HP,
+	DIV4_NR };
+
+static struct clk div4_clks[DIV4_NR] = {
+	[DIV4_I]	= SH_CLK_DIV4(&pll1_clk, FRQCRA, 20, 0x0dff, CLK_ENABLE_ON_INIT),
+	[DIV4_M3]	= SH_CLK_DIV4(&pll1_clk, FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
+	[DIV4_B]	= SH_CLK_DIV4(&pll1_clk, FRQCRA,  8, 0x0dff, CLK_ENABLE_ON_INIT),
+	[DIV4_M1]	= SH_CLK_DIV4(&pll1_clk, FRQCRA,  4, 0x1dff, 0),
+	[DIV4_M2]	= SH_CLK_DIV4(&pll1_clk, FRQCRA,  0, 0x1dff, 0),
+	[DIV4_ZX]	= SH_CLK_DIV4(&pll1_clk, FRQCRB, 12, 0x0dff, 0),
+	[DIV4_ZS]	= SH_CLK_DIV4(&pll1_clk, FRQCRB,  8, 0x0dff, 0),
+	[DIV4_HP]	= SH_CLK_DIV4(&pll1_clk, FRQCRB,  4, 0x0dff, 0),
+};
+
+enum {
+	DIV6_ZB,
+	DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
+	DIV6_MMC0, DIV6_MMC1,
+	DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VCK4, DIV6_VCK5,
+	DIV6_FSIA, DIV6_FSIB,
+	DIV6_MP, DIV6_M4, DIV6_HSI, DIV6_SPUV,
+	DIV6_NR };
+
+static struct clk *div6_parents[8] = {
+	[0] = &pll1_div2_clk,
+	[1] = &pll2s_clk,
+	[3] = &extal2_clk,
+	[4] = &main_div2_clk,
+	[6] = &extalr_clk,
+};
+
+static struct clk *fsia_parents[4] = {
+	[0] = &pll1_div2_clk,
+	[1] = &pll2s_clk,
+	[2] = &fsiack_clk,
+};
+
+static struct clk *fsib_parents[4] = {
+	[0] = &pll1_div2_clk,
+	[1] = &pll2s_clk,
+	[2] = &fsibck_clk,
+};
+
+static struct clk *mp_parents[4] = {
+	[0] = &pll1_div2_clk,
+	[1] = &pll2s_clk,
+	[2] = &extal2_clk,
+	[3] = &extal2_clk,
+};
+
+static struct clk *m4_parents[2] = {
+	[0] = &pll2s_clk,
+};
+
+static struct clk *hsi_parents[4] = {
+	[0] = &pll2h_clk,
+	[1] = &pll1_div2_clk,
+	[3] = &pll2s_clk,
+};
+
+/*** FIXME ***
+ * SH_CLK_DIV6_EXT() macro doesn't care .mapping
+ * but, it is necessary on R-Car (= ioremap() base CPG)
+ * The difference between
+ * SH_CLK_DIV6_EXT() <--> SH_CLK_MAP_DIV6_EXT()
+ * is only .mapping
+ */
+#define SH_CLK_MAP_DIV6_EXT(_reg, _flags, _parents,			\
+			    _num_parents, _src_shift, _src_width)	\
+{									\
+	.enable_reg	= (void __iomem *)_reg,				\
+	.enable_bit	= 0, /* unused */				\
+	.flags		= _flags | CLK_MASK_DIV_ON_DISABLE,		\
+	.div_mask	= SH_CLK_DIV6_MSK,				\
+	.parent_table	= _parents,					\
+	.parent_num	= _num_parents,					\
+	.src_shift	= _src_shift,					\
+	.src_width	= _src_width,					\
+	.mapping	= &cpg_mapping,					\
+}
+
+static struct clk div6_clks[DIV6_NR] = {
+	[DIV6_ZB] = SH_CLK_MAP_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
+				div6_parents, 2, 7, 1),
+	[DIV6_SDHI0] = SH_CLK_MAP_DIV6_EXT(SD0CKCR, 0,
+				div6_parents, 2, 6, 2),
+	[DIV6_SDHI1] = SH_CLK_MAP_DIV6_EXT(SD1CKCR, 0,
+				div6_parents, 2, 6, 2),
+	[DIV6_SDHI2] = SH_CLK_MAP_DIV6_EXT(SD2CKCR, 0,
+				div6_parents, 2, 6, 2),
+	[DIV6_MMC0] = SH_CLK_MAP_DIV6_EXT(MMC0CKCR, 0,
+				div6_parents, 2, 6, 2),
+	[DIV6_MMC1] = SH_CLK_MAP_DIV6_EXT(MMC1CKCR, 0,
+				div6_parents, 2, 6, 2),
+	[DIV6_VCK1] = SH_CLK_MAP_DIV6_EXT(VCLKCR1, 0, /* didn't care bit[6-7] */
+				div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
+	[DIV6_VCK2] = SH_CLK_MAP_DIV6_EXT(VCLKCR2, 0, /* didn't care bit[6-7] */
+				div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
+	[DIV6_VCK3] = SH_CLK_MAP_DIV6_EXT(VCLKCR3, 0, /* didn't care bit[6-7] */
+				div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
+	[DIV6_VCK4] = SH_CLK_MAP_DIV6_EXT(VCLKCR4, 0, /* didn't care bit[6-7] */
+				div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
+	[DIV6_VCK5] = SH_CLK_MAP_DIV6_EXT(VCLKCR5, 0, /* didn't care bit[6-7] */
+				div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
+	[DIV6_FSIA] = SH_CLK_MAP_DIV6_EXT(FSIACKCR, 0,
+				fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2),
+	[DIV6_FSIB] = SH_CLK_MAP_DIV6_EXT(FSIBCKCR, 0,
+				fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2),
+	[DIV6_MP] = SH_CLK_MAP_DIV6_EXT(MPCKCR, 0, /* it needs bit[9-11] control */
+				mp_parents, ARRAY_SIZE(mp_parents), 6, 2),
+	/* pll2s will be selected always for M4 */
+	[DIV6_M4] = SH_CLK_MAP_DIV6_EXT(M4CKCR, 0, /* it needs bit[9] control */
+				m4_parents, ARRAY_SIZE(m4_parents), 6, 1),
+	[DIV6_HSI] = SH_CLK_MAP_DIV6_EXT(HSICKCR, 0, /* it needs bit[9] control */
+				hsi_parents, ARRAY_SIZE(hsi_parents), 6, 2),
+	[DIV6_SPUV] = SH_CLK_MAP_DIV6_EXT(SPUVCKCR, 0,
+				mp_parents, ARRAY_SIZE(mp_parents), 6, 2),
+};
+
+/* MSTP */
+enum {
 	MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
+	MSTP315, MSTP314, MSTP313, MSTP312, MSTP305,
 	MSTP522,
 	MSTP_NR
 };
 
 static struct clk mstp_clks[MSTP_NR] = {
-	[MSTP204] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 4, 0), /* SCIFA0 */
-	[MSTP203] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 3, 0), /* SCIFA1 */
-	[MSTP206] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
-	[MSTP207] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
-	[MSTP216] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
-	[MSTP217] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 17, 0), /* SCIFB3 */
+	[MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 4, 0), /* SCIFA0 */
+	[MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 3, 0), /* SCIFA1 */
+	[MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 6, 0), /* SCIFB0 */
+	[MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 7, 0), /* SCIFB1 */
+	[MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 16, 0), /* SCIFB2 */
+	[MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 17, 0), /* SCIFB3 */
+	[MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */
+	[MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */
+	[MSTP313] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI1],SMSTPCR3, 13, 0), /* SDHI1 */
+	[MSTP314] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI0],SMSTPCR3, 14, 0), /* SDHI0 */
+	[MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0],SMSTPCR3, 15, 0), /* MMCIF0 */
 	[MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */
 };
 
 static struct clk_lookup lookups[] = {
+	/* main clock */
+	CLKDEV_CON_ID("extal1",			&extal1_clk),
+	CLKDEV_CON_ID("extal1_div2",		&extal1_div2_clk),
+	CLKDEV_CON_ID("extal2",			&extal2_clk),
+	CLKDEV_CON_ID("extal2_div2",		&extal2_div2_clk),
+	CLKDEV_CON_ID("extal2_div4",		&extal2_div4_clk),
+	CLKDEV_CON_ID("fsiack",			&fsiack_clk),
+	CLKDEV_CON_ID("fsibck",			&fsibck_clk),
+
+	/* pll clock */
+	CLKDEV_CON_ID("pll1",			&pll1_clk),
+	CLKDEV_CON_ID("pll1_div2",		&pll1_div2_clk),
+	CLKDEV_CON_ID("pll2",			&pll2_clk),
+	CLKDEV_CON_ID("pll2s",			&pll2s_clk),
+	CLKDEV_CON_ID("pll2h",			&pll2h_clk),
+
+	/* DIV6 */
+	CLKDEV_CON_ID("zb",			&div6_clks[DIV6_ZB]),
+	CLKDEV_CON_ID("vck1",			&div6_clks[DIV6_VCK1]),
+	CLKDEV_CON_ID("vck2",			&div6_clks[DIV6_VCK2]),
+	CLKDEV_CON_ID("vck3",			&div6_clks[DIV6_VCK3]),
+	CLKDEV_CON_ID("vck4",			&div6_clks[DIV6_VCK4]),
+	CLKDEV_CON_ID("vck5",			&div6_clks[DIV6_VCK5]),
+	CLKDEV_CON_ID("fsia",			&div6_clks[DIV6_FSIA]),
+	CLKDEV_CON_ID("fsib",			&div6_clks[DIV6_FSIB]),
+	CLKDEV_CON_ID("mp",			&div6_clks[DIV6_MP]),
+	CLKDEV_CON_ID("m4",			&div6_clks[DIV6_M4]),
+	CLKDEV_CON_ID("hsi",			&div6_clks[DIV6_HSI]),
+	CLKDEV_CON_ID("spuv",			&div6_clks[DIV6_SPUV]),
+
+	/* MSTP */
 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),
@@ -81,6 +408,16 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]),
 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]),
 	CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
+	CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
+	CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]),
+	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
+	CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]),
+	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
+	CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]),
+	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
+	CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]),
+	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
+	CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
 
 	/* for DT */
 	CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]),
@@ -88,22 +425,40 @@ static struct clk_lookup lookups[] = {
 
 void __init r8a73a4_clock_init(void)
 {
-	void __iomem *cpg_base, *reg;
+	void __iomem *reg;
 	int k, ret = 0;
+	u32 ckscr;
 
-	/* fix MPCLK to EXTAL2 for now.
-	 * this is needed until more detailed clock topology is supported
-	 */
-	cpg_base = ioremap_nocache(CPG_BASE, CPG_LEN);
-	BUG_ON(!cpg_base);
-	reg = cpg_base + (MPCKCR - CPG_BASE);
-	iowrite32(ioread32(reg) | 1 << 7 | 0x0c, reg); /* set CKSEL */
-	iounmap(cpg_base);
+	reg = ioremap_nocache(CKSCR, PAGE_SIZE);
+	BUG_ON(!reg);
+	ckscr = ioread32(reg);
+	iounmap(reg);
+
+	switch ((ckscr >> 28) & 0x3) {
+	case 0:
+		main_clk.parent = &extal1_clk;
+		break;
+	case 1:
+		main_clk.parent = &extal1_div2_clk;
+		break;
+	case 2:
+		main_clk.parent = &extal2_clk;
+		break;
+	case 3:
+		main_clk.parent = &extal2_div2_clk;
+		break;
+	}
 
 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 		ret = clk_register(main_clks[k]);
 
 	if (!ret)
+		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+	if (!ret)
+		ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
+
+	if (!ret)
 		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
 
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a7740.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a7740.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a7740.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a7740.c	2013-08-25 20:43:22.000000000 -0400
@@ -266,7 +266,7 @@ static struct clk fsiack_clk = {
 static struct clk fsibck_clk = {
 };
 
-struct clk *main_clks[] = {
+static struct clk *main_clks[] = {
 	&extalr_clk,
 	&extal1_clk,
 	&extal2_clk,
@@ -317,7 +317,7 @@ enum {
 	DIV4_NR
 };
 
-struct clk div4_clks[DIV4_NR] = {
+static struct clk div4_clks[DIV4_NR] = {
 	[DIV4_I]	= SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
 	[DIV4_ZG]	= SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
 	[DIV4_B]	= SH_CLK_DIV4(&pllc1_clk, FRQCRA,  8, 0x6fff, CLK_ENABLE_ON_INIT),
@@ -461,7 +461,7 @@ enum {
 
 	MSTP329, MSTP328, MSTP323, MSTP320,
 	MSTP314, MSTP313, MSTP312,
-	MSTP309,
+	MSTP309, MSTP304,
 
 	MSTP416, MSTP415, MSTP407, MSTP406,
 
@@ -499,6 +499,7 @@ static struct clk mstp_clks[MSTP_NR] = {
 	[MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 13, 0), /* SDHI1 */
 	[MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 12, 0), /* MMC */
 	[MSTP309] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3,  9, 0), /* GEther */
+	[MSTP304] = SH_CLK_MSTP32(&div4_clks[DIV4_CP],	SMSTPCR3,  4, 0), /* TPU0 */
 
 	[MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR4, 16, 0), /* USBHOST */
 	[MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR4, 15, 0), /* SDHI2 */
@@ -551,6 +552,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh_tmu.4",		&mstp_clks[MSTP111]),
 	CLKDEV_DEV_ID("sh_tmu.5",		&mstp_clks[MSTP111]),
 	CLKDEV_DEV_ID("i2c-sh_mobile.0",	&mstp_clks[MSTP116]),
+	CLKDEV_DEV_ID("fff20000.i2c",		&mstp_clks[MSTP116]),
 	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1",	&mstp_clks[MSTP117]),
 	CLKDEV_DEV_ID("sh_tmu.0",		&mstp_clks[MSTP125]),
 	CLKDEV_DEV_ID("sh_tmu.1",		&mstp_clks[MSTP125]),
@@ -584,6 +586,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh_cmt.10",		&mstp_clks[MSTP329]),
 	CLKDEV_DEV_ID("sh_fsi2",		&mstp_clks[MSTP328]),
 	CLKDEV_DEV_ID("i2c-sh_mobile.1",	&mstp_clks[MSTP323]),
+	CLKDEV_DEV_ID("e6c20000.i2c",		&mstp_clks[MSTP323]),
 	CLKDEV_DEV_ID("renesas_usbhs",		&mstp_clks[MSTP320]),
 	CLKDEV_DEV_ID("sh_mobile_sdhi.0",	&mstp_clks[MSTP314]),
 	CLKDEV_DEV_ID("e6850000.sdhi",          &mstp_clks[MSTP314]),
@@ -591,7 +594,9 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("e6860000.sdhi",          &mstp_clks[MSTP313]),
 	CLKDEV_DEV_ID("sh_mmcif",		&mstp_clks[MSTP312]),
 	CLKDEV_DEV_ID("e6bd0000.mmcif",         &mstp_clks[MSTP312]),
-	CLKDEV_DEV_ID("sh-eth",			&mstp_clks[MSTP309]),
+	CLKDEV_DEV_ID("r8a7740-gether",		&mstp_clks[MSTP309]),
+	CLKDEV_DEV_ID("e9a00000.sh-eth",	&mstp_clks[MSTP309]),
+	CLKDEV_DEV_ID("renesas_tpu_pwm",	&mstp_clks[MSTP304]),
 
 	CLKDEV_DEV_ID("sh_mobile_sdhi.2",	&mstp_clks[MSTP415]),
 	CLKDEV_DEV_ID("e6870000.sdhi",          &mstp_clks[MSTP415]),
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a7778.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a7778.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a7778.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a7778.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,9 +23,23 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/*
+ *     MD      MD      MD      MD       PLLA   PLLB    EXTAL   clki    clkz
+ *     19      18      12      11                      (HMz)   (MHz)   (MHz)
+ *----------------------------------------------------------------------------
+ *     1       0       0       0       x21     x21     38.00   800     800
+ *     1       0       0       1       x24     x24     33.33   800     800
+ *     1       0       1       0       x28     x28     28.50   800     800
+ *     1       0       1       1       x32     x32     25.00   800     800
+ *     1       1       0       1       x24     x21     33.33   800     700
+ *     1       1       1       0       x28     x21     28.50   800     600
+ *     1       1       1       1       x32     x24     25.00   800     600
+ */
+
 #include <linux/io.h>
 #include <linux/sh_clk.h>
 #include <linux/clkdev.h>
+#include <mach/clock.h>
 #include <mach/common.h>
 
 #define MSTPCR0		IOMEM(0xffc80030)
@@ -37,6 +51,9 @@
 #define MSTPCR4		IOMEM(0xffc80050)
 #define MSTPCR5		IOMEM(0xffc80054)
 #define MSTPCR6		IOMEM(0xffc80058)
+#define MODEMR		0xFFCC0020
+
+#define MD(nr)	BIT(nr)
 
 /* ioremap() through clock mapping mandatory to avoid
  * collision with ARM coherent DMA virtual memory range.
@@ -47,37 +64,94 @@ static struct clk_mapping cpg_mapping =
 	.len	= 0x80,
 };
 
-static struct clk clkp = {
-	.rate   = 62500000, /* FIXME: shortcut */
-	.flags  = CLK_ENABLE_ON_INIT,
+static struct clk extal_clk = {
+	/* .rate will be updated on r8a7778_clock_init() */
 	.mapping = &cpg_mapping,
 };
 
+/*
+ * clock ratio of these clock will be updated
+ * on r8a7778_clock_init()
+ */
+SH_FIXED_RATIO_CLK_SET(plla_clk,	extal_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(pllb_clk,	extal_clk, 1, 1);
+SH_FIXED_RATIO_CLK_SET(i_clk,		plla_clk,  1, 1);
+SH_FIXED_RATIO_CLK_SET(s_clk,		plla_clk,  1, 1);
+SH_FIXED_RATIO_CLK_SET(s1_clk,		plla_clk,  1, 1);
+SH_FIXED_RATIO_CLK_SET(s3_clk,		plla_clk,  1, 1);
+SH_FIXED_RATIO_CLK_SET(s4_clk,		plla_clk,  1, 1);
+SH_FIXED_RATIO_CLK_SET(b_clk,		plla_clk,  1, 1);
+SH_FIXED_RATIO_CLK_SET(out_clk,		plla_clk,  1, 1);
+SH_FIXED_RATIO_CLK_SET(p_clk,		plla_clk,  1, 1);
+SH_FIXED_RATIO_CLK_SET(g_clk,		plla_clk,  1, 1);
+SH_FIXED_RATIO_CLK_SET(z_clk,		pllb_clk,  1, 1);
+
 static struct clk *main_clks[] = {
-	&clkp,
+	&extal_clk,
+	&plla_clk,
+	&pllb_clk,
+	&i_clk,
+	&s_clk,
+	&s1_clk,
+	&s3_clk,
+	&s4_clk,
+	&b_clk,
+	&out_clk,
+	&p_clk,
+	&g_clk,
+	&z_clk,
 };
 
 enum {
+	MSTP331,
+	MSTP323, MSTP322, MSTP321,
 	MSTP114,
-	MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
+	MSTP100,
+	MSTP030,
+	MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
 	MSTP016, MSTP015,
+	MSTP007,
 	MSTP_NR };
 
 static struct clk mstp_clks[MSTP_NR] = {
-	[MSTP114] = SH_CLK_MSTP32(&clkp, MSTPCR1, 14, 0), /* Ether */
-	[MSTP026] = SH_CLK_MSTP32(&clkp, MSTPCR0, 26, 0), /* SCIF0 */
-	[MSTP025] = SH_CLK_MSTP32(&clkp, MSTPCR0, 25, 0), /* SCIF1 */
-	[MSTP024] = SH_CLK_MSTP32(&clkp, MSTPCR0, 24, 0), /* SCIF2 */
-	[MSTP023] = SH_CLK_MSTP32(&clkp, MSTPCR0, 23, 0), /* SCIF3 */
-	[MSTP022] = SH_CLK_MSTP32(&clkp, MSTPCR0, 22, 0), /* SCIF4 */
-	[MSTP021] = SH_CLK_MSTP32(&clkp, MSTPCR0, 21, 0), /* SCIF5 */
-	[MSTP016] = SH_CLK_MSTP32(&clkp, MSTPCR0, 16, 0), /* TMU0 */
-	[MSTP015] = SH_CLK_MSTP32(&clkp, MSTPCR0, 15, 0), /* TMU1 */
+	[MSTP331] = SH_CLK_MSTP32(&s4_clk, MSTPCR3, 31, 0), /* MMC */
+	[MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */
+	[MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */
+	[MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */
+	[MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
+	[MSTP100] = SH_CLK_MSTP32(&p_clk, MSTPCR1,  0, 0), /* USB0/1 */
+	[MSTP030] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 30, 0), /* I2C0 */
+	[MSTP029] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 29, 0), /* I2C1 */
+	[MSTP028] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 28, 0), /* I2C2 */
+	[MSTP027] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 27, 0), /* I2C3 */
+	[MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */
+	[MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */
+	[MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */
+	[MSTP023] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 23, 0), /* SCIF3 */
+	[MSTP022] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 22, 0), /* SCIF4 */
+	[MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */
+	[MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */
+	[MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */
+	[MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0,  7, 0), /* HSPI */
 };
 
 static struct clk_lookup lookups[] = {
+	/* main */
+	CLKDEV_CON_ID("shyway_clk",	&s_clk),
+	CLKDEV_CON_ID("peripheral_clk",	&p_clk),
+
 	/* MSTP32 clocks */
-	CLKDEV_DEV_ID("sh-eth",	&mstp_clks[MSTP114]), /* Ether */
+	CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP331]), /* MMC */
+	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
+	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
+	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
+	CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
+	CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
+	CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
+	CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
+	CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
+	CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
+	CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
@@ -86,12 +160,93 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
 	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
 	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP015]), /* TMU01 */
+	CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
+	CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
+	CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
 };
 
 void __init r8a7778_clock_init(void)
 {
+	void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
+	u32 mode;
 	int k, ret = 0;
 
+	BUG_ON(!modemr);
+	mode = ioread32(modemr);
+	iounmap(modemr);
+
+	switch (mode & (MD(19) | MD(18) | MD(12) | MD(11))) {
+	case MD(19):
+		extal_clk.rate = 38000000;
+		SH_CLK_SET_RATIO(&plla_clk_ratio,	21, 1);
+		SH_CLK_SET_RATIO(&pllb_clk_ratio,	21, 1);
+		break;
+	case MD(19) | MD(11):
+		extal_clk.rate = 33333333;
+		SH_CLK_SET_RATIO(&plla_clk_ratio,	24, 1);
+		SH_CLK_SET_RATIO(&pllb_clk_ratio,	24, 1);
+		break;
+	case MD(19) | MD(12):
+		extal_clk.rate = 28500000;
+		SH_CLK_SET_RATIO(&plla_clk_ratio,	28, 1);
+		SH_CLK_SET_RATIO(&pllb_clk_ratio,	28, 1);
+		break;
+	case MD(19) | MD(12) | MD(11):
+		extal_clk.rate = 25000000;
+		SH_CLK_SET_RATIO(&plla_clk_ratio,	32, 1);
+		SH_CLK_SET_RATIO(&pllb_clk_ratio,	32, 1);
+		break;
+	case MD(19) | MD(18) | MD(11):
+		extal_clk.rate = 33333333;
+		SH_CLK_SET_RATIO(&plla_clk_ratio,	24, 1);
+		SH_CLK_SET_RATIO(&pllb_clk_ratio,	21, 1);
+		break;
+	case MD(19) | MD(18) | MD(12):
+		extal_clk.rate = 28500000;
+		SH_CLK_SET_RATIO(&plla_clk_ratio,	28, 1);
+		SH_CLK_SET_RATIO(&pllb_clk_ratio,	21, 1);
+		break;
+	case MD(19) | MD(18) | MD(12) | MD(11):
+		extal_clk.rate = 25000000;
+		SH_CLK_SET_RATIO(&plla_clk_ratio,	32, 1);
+		SH_CLK_SET_RATIO(&pllb_clk_ratio,	24, 1);
+		break;
+	default:
+		BUG();
+	}
+
+	if (mode & MD(1)) {
+		SH_CLK_SET_RATIO(&i_clk_ratio,	1, 1);
+		SH_CLK_SET_RATIO(&s_clk_ratio,	1, 3);
+		SH_CLK_SET_RATIO(&s1_clk_ratio,	1, 6);
+		SH_CLK_SET_RATIO(&s3_clk_ratio,	1, 4);
+		SH_CLK_SET_RATIO(&s4_clk_ratio,	1, 8);
+		SH_CLK_SET_RATIO(&p_clk_ratio,	1, 12);
+		SH_CLK_SET_RATIO(&g_clk_ratio,	1, 12);
+		if (mode & MD(2)) {
+			SH_CLK_SET_RATIO(&b_clk_ratio,		1, 18);
+			SH_CLK_SET_RATIO(&out_clk_ratio,	1, 18);
+		} else {
+			SH_CLK_SET_RATIO(&b_clk_ratio,		1, 12);
+			SH_CLK_SET_RATIO(&out_clk_ratio,	1, 12);
+		}
+	} else {
+		SH_CLK_SET_RATIO(&i_clk_ratio,	1, 1);
+		SH_CLK_SET_RATIO(&s_clk_ratio,	1, 4);
+		SH_CLK_SET_RATIO(&s1_clk_ratio,	1, 8);
+		SH_CLK_SET_RATIO(&s3_clk_ratio,	1, 4);
+		SH_CLK_SET_RATIO(&s4_clk_ratio,	1, 8);
+		SH_CLK_SET_RATIO(&p_clk_ratio,	1, 16);
+		SH_CLK_SET_RATIO(&g_clk_ratio,	1, 12);
+		if (mode & MD(2)) {
+			SH_CLK_SET_RATIO(&b_clk_ratio,		1, 16);
+			SH_CLK_SET_RATIO(&out_clk_ratio,	1, 16);
+		} else {
+			SH_CLK_SET_RATIO(&b_clk_ratio,		1, 12);
+			SH_CLK_SET_RATIO(&out_clk_ratio,	1, 12);
+		}
+	}
+
 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 		ret = clk_register(main_clks[k]);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a7779.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a7779.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a7779.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a7779.c	2013-08-25 20:43:22.000000000 -0400
@@ -112,7 +112,7 @@ static struct clk *main_clks[] = {
 };
 
 enum { MSTP323, MSTP322, MSTP321, MSTP320,
-	MSTP115, MSTP114,
+	MSTP116, MSTP115, MSTP114,
 	MSTP103, MSTP101, MSTP100,
 	MSTP030,
 	MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
@@ -125,6 +125,7 @@ static struct clk mstp_clks[MSTP_NR] = {
 	[MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
 	[MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
 	[MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
+	[MSTP116] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 16, 0), /* PCIe */
 	[MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */
 	[MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */
 	[MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1,  3, 0), /* DU */
@@ -161,9 +162,10 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("peripheral_clk",	&clkp_clk),
 
 	/* MSTP32 clocks */
+	CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */
 	CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
 	CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
-	CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */
+	CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
 	CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
 	CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
 	CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a7790.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a7790.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-r8a7790.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-r8a7790.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,48 +22,228 @@
 #include <linux/kernel.h>
 #include <linux/sh_clk.h>
 #include <linux/clkdev.h>
+#include <mach/clock.h>
 #include <mach/common.h>
 
+/*
+ *   MD		EXTAL		PLL0	PLL1	PLL3
+ * 14 13 19	(MHz)		*1	*1
+ *---------------------------------------------------
+ * 0  0  0	15 x 1		x172/2	x208/2	x106
+ * 0  0  1	15 x 1		x172/2	x208/2	x88
+ * 0  1  0	20 x 1		x130/2	x156/2	x80
+ * 0  1  1	20 x 1		x130/2	x156/2	x66
+ * 1  0  0	26 / 2		x200/2	x240/2	x122
+ * 1  0  1	26 / 2		x200/2	x240/2	x102
+ * 1  1  0	30 / 2		x172/2	x208/2	x106
+ * 1  1  1	30 / 2		x172/2	x208/2	x88
+ *
+ * *1 :	Table 7.6 indicates VCO ouput (PLLx = VCO/2)
+ *	see "p1 / 2" on R8A7790_CLOCK_ROOT() below
+ */
+
+#define MD(nr)	(1 << nr)
+
 #define CPG_BASE 0xe6150000
 #define CPG_LEN 0x1000
 
 #define SMSTPCR2 0xe6150138
+#define SMSTPCR3 0xe615013c
 #define SMSTPCR7 0xe615014c
 
+#define MODEMR		0xE6160060
+#define SDCKCR		0xE6150074
+#define SD2CKCR		0xE6150078
+#define SD3CKCR		0xE615007C
+#define MMC0CKCR	0xE6150240
+#define MMC1CKCR	0xE6150244
+#define SSPCKCR		0xE6150248
+#define SSPRSCKCR	0xE615024C
+
 static struct clk_mapping cpg_mapping = {
 	.phys   = CPG_BASE,
 	.len    = CPG_LEN,
 };
 
-static struct clk p_clk = {
-	.rate	= 65000000, /* shortcut for now */
+static struct clk extal_clk = {
+	/* .rate will be updated on r8a7790_clock_init() */
 	.mapping	= &cpg_mapping,
 };
 
-static struct clk mp_clk = {
-	.rate	= 52000000,  /* shortcut for now */
-	.mapping	= &cpg_mapping,
+static struct sh_clk_ops followparent_clk_ops = {
+	.recalc	= followparent_recalc,
+};
+
+static struct clk main_clk = {
+	/* .parent will be set r8a73a4_clock_init */
+	.ops	= &followparent_clk_ops,
 };
 
+/*
+ * clock ratio of these clock will be updated
+ * on r8a7790_clock_init()
+ */
+SH_FIXED_RATIO_CLK_SET(pll1_clk,		main_clk,	1, 1);
+SH_FIXED_RATIO_CLK_SET(pll3_clk,		main_clk,	1, 1);
+SH_FIXED_RATIO_CLK_SET(lb_clk,			pll1_clk,	1, 1);
+SH_FIXED_RATIO_CLK_SET(qspi_clk,		pll1_clk,	1, 1);
+
+/* fixed ratio clock */
+SH_FIXED_RATIO_CLK_SET(extal_div2_clk,		extal_clk,	1, 2);
+SH_FIXED_RATIO_CLK_SET(cp_clk,			extal_clk,	1, 2);
+
+SH_FIXED_RATIO_CLK_SET(pll1_div2_clk,		pll1_clk,	1, 2);
+SH_FIXED_RATIO_CLK_SET(zg_clk,			pll1_clk,	1, 3);
+SH_FIXED_RATIO_CLK_SET(zx_clk,			pll1_clk,	1, 3);
+SH_FIXED_RATIO_CLK_SET(zs_clk,			pll1_clk,	1, 6);
+SH_FIXED_RATIO_CLK_SET(hp_clk,			pll1_clk,	1, 12);
+SH_FIXED_RATIO_CLK_SET(i_clk,			pll1_clk,	1, 2);
+SH_FIXED_RATIO_CLK_SET(b_clk,			pll1_clk,	1, 12);
+SH_FIXED_RATIO_CLK_SET(p_clk,			pll1_clk,	1, 24);
+SH_FIXED_RATIO_CLK_SET(cl_clk,			pll1_clk,	1, 48);
+SH_FIXED_RATIO_CLK_SET(m2_clk,			pll1_clk,	1, 8);
+SH_FIXED_RATIO_CLK_SET(imp_clk,			pll1_clk,	1, 4);
+SH_FIXED_RATIO_CLK_SET(rclk_clk,		pll1_clk,	1, (48 * 1024));
+SH_FIXED_RATIO_CLK_SET(oscclk_clk,		pll1_clk,	1, (12 * 1024));
+
+SH_FIXED_RATIO_CLK_SET(zb3_clk,			pll3_clk,	1, 4);
+SH_FIXED_RATIO_CLK_SET(zb3d2_clk,		pll3_clk,	1, 8);
+SH_FIXED_RATIO_CLK_SET(ddr_clk,			pll3_clk,	1, 8);
+SH_FIXED_RATIO_CLK_SET(mp_clk,			pll1_div2_clk,	1, 15);
+
 static struct clk *main_clks[] = {
+	&extal_clk,
+	&extal_div2_clk,
+	&main_clk,
+	&pll1_clk,
+	&pll1_div2_clk,
+	&pll3_clk,
+	&lb_clk,
+	&qspi_clk,
+	&zg_clk,
+	&zx_clk,
+	&zs_clk,
+	&hp_clk,
+	&i_clk,
+	&b_clk,
 	&p_clk,
+	&cl_clk,
+	&m2_clk,
+	&imp_clk,
+	&rclk_clk,
+	&oscclk_clk,
+	&zb3_clk,
+	&zb3d2_clk,
+	&ddr_clk,
 	&mp_clk,
+	&cp_clk,
+};
+
+/* SDHI (DIV4) clock */
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+	.divisors = divisors,
+	.nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+	.div_mult_table = &div4_div_mult_table,
+};
+
+enum {
+	DIV4_SDH, DIV4_SD0, DIV4_SD1, DIV4_NR
+};
+
+static struct clk div4_clks[DIV4_NR] = {
+	[DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT),
+	[DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1de0, CLK_ENABLE_ON_INIT),
+	[DIV4_SD1] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 0, 0x1de0, CLK_ENABLE_ON_INIT),
+};
+
+/* DIV6 clocks */
+enum {
+	DIV6_SD2, DIV6_SD3,
+	DIV6_MMC0, DIV6_MMC1,
+	DIV6_SSP, DIV6_SSPRS,
+	DIV6_NR
+};
+
+static struct clk div6_clks[DIV6_NR] = {
+	[DIV6_SD2]	= SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
+	[DIV6_SD3]	= SH_CLK_DIV6(&pll1_div2_clk, SD3CKCR, 0),
+	[DIV6_MMC0]	= SH_CLK_DIV6(&pll1_div2_clk, MMC0CKCR, 0),
+	[DIV6_MMC1]	= SH_CLK_DIV6(&pll1_div2_clk, MMC1CKCR, 0),
+	[DIV6_SSP]	= SH_CLK_DIV6(&pll1_div2_clk, SSPCKCR, 0),
+	[DIV6_SSPRS]	= SH_CLK_DIV6(&pll1_div2_clk, SSPRSCKCR, 0),
+};
+
+/* MSTP */
+enum {
+	MSTP721, MSTP720,
+	MSTP717, MSTP716,
+	MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304,
+	MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,
+	MSTP_NR
 };
 
-enum { MSTP721, MSTP720,
-	MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP_NR };
 static struct clk mstp_clks[MSTP_NR] = {
 	[MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
 	[MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
+	[MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, 0), /* MMC0 */
+	[MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_SD0], SMSTPCR3, 14, 0), /* SDHI0 */
+	[MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_SD1], SMSTPCR3, 13, 0), /* SDHI1 */
+	[MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SD2], SMSTPCR3, 12, 0), /* SDHI2 */
+	[MSTP311] = SH_CLK_MSTP32(&div6_clks[DIV6_SD3], SMSTPCR3, 11, 0), /* SDHI3 */
+	[MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, 0), /* MMC1 */
+	[MSTP304] = SH_CLK_MSTP32(&cp_clk, SMSTPCR3, 4, 0), /* TPU0 */
 	[MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
 	[MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
 	[MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
 	[MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */
 	[MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */
 	[MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */
+	[MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */
+	[MSTP716] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 16, 0), /* HSCIF1 */
 };
 
 static struct clk_lookup lookups[] = {
+
+	/* main clocks */
+	CLKDEV_CON_ID("extal",		&extal_clk),
+	CLKDEV_CON_ID("extal_div2",	&extal_div2_clk),
+	CLKDEV_CON_ID("main",		&main_clk),
+	CLKDEV_CON_ID("pll1",		&pll1_clk),
+	CLKDEV_CON_ID("pll1_div2",	&pll1_div2_clk),
+	CLKDEV_CON_ID("pll3",		&pll3_clk),
+	CLKDEV_CON_ID("zg",		&zg_clk),
+	CLKDEV_CON_ID("zx",		&zx_clk),
+	CLKDEV_CON_ID("zs",		&zs_clk),
+	CLKDEV_CON_ID("hp",		&hp_clk),
+	CLKDEV_CON_ID("i",		&i_clk),
+	CLKDEV_CON_ID("b",		&b_clk),
+	CLKDEV_CON_ID("lb",		&lb_clk),
+	CLKDEV_CON_ID("p",		&p_clk),
+	CLKDEV_CON_ID("cl",		&cl_clk),
+	CLKDEV_CON_ID("m2",		&m2_clk),
+	CLKDEV_CON_ID("imp",		&imp_clk),
+	CLKDEV_CON_ID("rclk",		&rclk_clk),
+	CLKDEV_CON_ID("oscclk",		&oscclk_clk),
+	CLKDEV_CON_ID("zb3",		&zb3_clk),
+	CLKDEV_CON_ID("zb3d2",		&zb3d2_clk),
+	CLKDEV_CON_ID("ddr",		&ddr_clk),
+	CLKDEV_CON_ID("mp",		&mp_clk),
+	CLKDEV_CON_ID("qspi",		&qspi_clk),
+	CLKDEV_CON_ID("cp",		&cp_clk),
+
+	/* DIV4 */
+	CLKDEV_CON_ID("sdh",		&div4_clks[DIV4_SDH]),
+
+	/* DIV6 */
+	CLKDEV_CON_ID("ssp",		&div6_clks[DIV6_SSP]),
+	CLKDEV_CON_ID("ssprs",		&div6_clks[DIV6_SSPRS]),
+
+	/* MSTP */
 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),
@@ -72,16 +252,77 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]),
 	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]),
 	CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
+	CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
+	CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
+	CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]),
+	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
+	CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]),
+	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
+	CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]),
+	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
+	CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP312]),
+	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
+	CLKDEV_DEV_ID("ee160000.sdhi", &mstp_clks[MSTP311]),
+	CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
+	CLKDEV_DEV_ID("ee220000.mmcif", &mstp_clks[MSTP305]),
+	CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
 };
 
+#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31)		\
+	extal_clk.rate	= e * 1000 * 1000;			\
+	main_clk.parent	= m;					\
+	SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1);		\
+	if (mode & MD(19))					\
+		SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1);	\
+	else							\
+		SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
+
+
 void __init r8a7790_clock_init(void)
 {
+	void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
+	u32 mode;
 	int k, ret = 0;
 
+	BUG_ON(!modemr);
+	mode = ioread32(modemr);
+	iounmap(modemr);
+
+	switch (mode & (MD(14) | MD(13))) {
+	case 0:
+		R8A7790_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
+		break;
+	case MD(13):
+		R8A7790_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
+		break;
+	case MD(14):
+		R8A7790_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
+		break;
+	case MD(13) | MD(14):
+		R8A7790_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
+		break;
+	}
+
+	if (mode & (MD(18)))
+		SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 36);
+	else
+		SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 24);
+
+	if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2))
+		SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16);
+	else
+		SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20);
+
 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 		ret = clk_register(main_clks[k]);
 
 	if (!ret)
+		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+	if (!ret)
+		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+	if (!ret)
 		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
 
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-sh7372.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-sh7372.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-sh7372.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-sh7372.c	2013-08-25 20:43:22.000000000 -0400
@@ -142,15 +142,15 @@ static void pllc2_table_rebuild(struct c
 	/* Initialise PLLC2 frequency table */
 	for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
 		pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
-		pllc2_freq_table[i].index = i;
+		pllc2_freq_table[i].driver_data = i;
 	}
 
 	/* This is a special entry - switching PLL off makes it a repeater */
 	pllc2_freq_table[i].frequency = clk->parent->rate;
-	pllc2_freq_table[i].index = i;
+	pllc2_freq_table[i].driver_data = i;
 
 	pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
-	pllc2_freq_table[i].index = i;
+	pllc2_freq_table[i].driver_data = i;
 }
 
 static unsigned long pllc2_recalc(struct clk *clk)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-sh73a0.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-sh73a0.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/clock-sh73a0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/clock-sh73a0.c	2013-08-25 20:43:22.000000000 -0400
@@ -228,6 +228,11 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B,
 
 static struct clk div4_clks[DIV4_NR] = {
 	[DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
+	/*
+	 * ZG clock is dividing PLL0 frequency to supply SGX. Make sure not to
+	 * exceed maximum frequencies of 201.5MHz for VDD_DVFS=1.175 and
+	 * 239.2MHz for VDD_DVFS=1.315V.
+	 */
 	[DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
 	[DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
 	[DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
@@ -252,6 +257,101 @@ static struct clk twd_clk = {
 	.ops = &twd_clk_ops,
 };
 
+static struct sh_clk_ops zclk_ops, kicker_ops;
+static const struct sh_clk_ops *div4_clk_ops;
+
+static int zclk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret;
+
+	if (!clk->parent || !__clk_get(clk->parent))
+		return -ENODEV;
+
+	if (readl(FRQCRB) & (1 << 31))
+		return -EBUSY;
+
+	if (rate == clk_get_rate(clk->parent)) {
+		/* 1:1 - switch off divider */
+		__raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB);
+		/* nullify the divider to prepare for the next time */
+		ret = div4_clk_ops->set_rate(clk, rate / 2);
+		if (!ret)
+			ret = frqcr_kick();
+		if (ret > 0)
+			ret = 0;
+	} else {
+		/* Enable the divider */
+		__raw_writel(__raw_readl(FRQCRB) | (1 << 28), FRQCRB);
+
+		ret = frqcr_kick();
+		if (ret >= 0)
+			/*
+			 * set the divider - call the DIV4 method, it will kick
+			 * FRQCRB too
+			 */
+			ret = div4_clk_ops->set_rate(clk, rate);
+		if (ret < 0)
+			goto esetrate;
+	}
+
+esetrate:
+	__clk_put(clk->parent);
+	return ret;
+}
+
+static long zclk_round_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
+		parent_freq = clk_get_rate(clk->parent);
+
+	if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq)
+		return parent_freq;
+
+	return div_freq;
+}
+
+static unsigned long zclk_recalc(struct clk *clk)
+{
+	/*
+	 * Must recalculate frequencies in case PLL0 has been changed, even if
+	 * the divisor is unused ATM!
+	 */
+	unsigned long div_freq = div4_clk_ops->recalc(clk);
+
+	if (__raw_readl(FRQCRB) & (1 << 28))
+		return div_freq;
+
+	return clk_get_rate(clk->parent);
+}
+
+static int kicker_set_rate(struct clk *clk, unsigned long rate)
+{
+	if (__raw_readl(FRQCRB) & (1 << 31))
+		return -EBUSY;
+
+	return div4_clk_ops->set_rate(clk, rate);
+}
+
+static void div4_clk_extend(void)
+{
+	int i;
+
+	div4_clk_ops = div4_clks[0].ops;
+
+	/* Add a kicker-busy check before changing the rate */
+	kicker_ops = *div4_clk_ops;
+	/* We extend the DIV4 clock with a 1:1 pass-through case */
+	zclk_ops = *div4_clk_ops;
+
+	kicker_ops.set_rate = kicker_set_rate;
+	zclk_ops.set_rate = zclk_set_rate;
+	zclk_ops.round_rate = zclk_round_rate;
+	zclk_ops.recalc = zclk_recalc;
+
+	for (i = 0; i < DIV4_NR; i++)
+		div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
+}
+
 enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
 	DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
 	DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
@@ -450,7 +550,7 @@ static struct clk *late_main_clks[] = {
 };
 
 enum { MSTP001,
-	MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
+	MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
 	MSTP219, MSTP218, MSTP217,
 	MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
 	MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
@@ -471,6 +571,7 @@ static struct clk mstp_clks[MSTP_NR] = {
 	[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
 	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
 	[MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
+	[MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
 	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
 	[MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
 	[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
@@ -513,6 +614,9 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("r_clk", &r_clk),
 	CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
 
+	/* DIV4 clocks */
+	CLKDEV_DEV_ID("cpufreq-cpu0", &div4_clks[DIV4_Z]),
+
 	/* DIV6 clocks */
 	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
 	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
@@ -604,8 +708,11 @@ void __init sh73a0_clock_init(void)
 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 		ret = clk_register(main_clks[k]);
 
-	if (!ret)
+	if (!ret) {
 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+		if (!ret)
+			div4_clk_extend();
+	}
 
 	if (!ret)
 		ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/headsmp.S
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/headsmp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -14,8 +14,6 @@
 #include <linux/init.h>
 #include <asm/memory.h>
 
-	__CPUINIT
-
 ENTRY(shmobile_invalidate_start)
 	bl	v7_invalidate_l1
 	b	secondary_startup
@@ -27,7 +25,14 @@ ENDPROC(shmobile_invalidate_start)
  * We need _long_ jump to the physical address.
  */
 	.align  12
-ENTRY(shmobile_secondary_vector)
+ENTRY(shmobile_boot_vector)
+	ldr     r0, 2f
 	ldr     pc, 1f
-1:	.long   shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET
-ENDPROC(shmobile_secondary_vector)
+ENDPROC(shmobile_boot_vector)
+
+	.globl	shmobile_boot_fn
+shmobile_boot_fn:
+1:	.space	4
+	.globl	shmobile_boot_arg
+shmobile_boot_arg:
+2:	.space	4
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/headsmp-scu.S linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/headsmp-scu.S
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/headsmp-scu.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/headsmp-scu.S	2013-08-25 20:43:22.000000000 -0400
@@ -23,33 +23,25 @@
 #include <linux/init.h>
 #include <asm/memory.h>
 
-	__CPUINIT
 /*
- * Reset vector for secondary CPUs.
+ * Boot code for secondary CPUs.
  *
  * First we turn on L1 cache coherency for our CPU. Then we jump to
  * shmobile_invalidate_start that invalidates the cache and hands over control
  * to the common ARM startup code.
- * This function will be mapped to address 0 by the SBAR register.
- * A normal branch is out of range here so we need a long jump. We jump to
- * the physical address as the MMU is still turned off.
  */
-	.align	12
-ENTRY(shmobile_secondary_vector_scu)
-	mrc     p15, 0, r0, c0, c0, 5	@ read MIPDR
-	and	r0, r0, #3		@ mask out cpu ID
-	lsl	r0, r0, #3		@ we will shift by cpu_id * 8 bits
-	ldr	r1, 2f
-	ldr	r1, [r1]		@ SCU base address
-	ldr	r2, [r1, #8]		@ SCU Power Status Register
+ENTRY(shmobile_boot_scu)
+					@ r0 = SCU base address
+	mrc     p15, 0, r1, c0, c0, 5	@ read MIPDR
+	and	r1, r1, #3		@ mask out cpu ID
+	lsl	r1, r1, #3		@ we will shift by cpu_id * 8 bits
+	ldr	r2, [r0, #8]		@ SCU Power Status Register
 	mov	r3, #3
-	bic	r2, r2, r3, lsl r0	@ Clear bits of our CPU (Run Mode)
-	str	r2, [r1, #8]		@ write back
+	bic	r2, r2, r3, lsl r1	@ Clear bits of our CPU (Run Mode)
+	str	r2, [r0, #8]		@ write back
 
-	ldr	pc, 1f
-1:	.long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET
-2:	.long shmobile_scu_base - PAGE_OFFSET + PLAT_PHYS_OFFSET
-ENDPROC(shmobile_secondary_vector_scu)
+	b	shmobile_invalidate_start
+ENDPROC(shmobile_boot_scu)
 
 	.text
 	.globl	shmobile_scu_base
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/clock.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/clock.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/clock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/clock.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,16 +24,16 @@ struct clk name = {			\
 }
 
 #define SH_FIXED_RATIO_CLK(name, p, r)		\
-static SH_FIXED_RATIO_CLKg(name, p, r);
+static SH_FIXED_RATIO_CLKg(name, p, r)
 
 #define SH_FIXED_RATIO_CLK_SET(name, p, m, d)	\
 	SH_CLK_RATIO(name, m, d);		\
-	SH_FIXED_RATIO_CLK(name, p, name);
+	SH_FIXED_RATIO_CLK(name, p, name)
 
 #define SH_CLK_SET_RATIO(p, m, d)	\
-{			\
+do {			\
 	(p)->mul = m;	\
 	(p)->div = d;	\
-}
+} while (0)
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -7,8 +7,10 @@ extern void shmobile_setup_delay(unsigne
 			 unsigned int mult, unsigned int div);
 struct twd_local_timer;
 extern void shmobile_setup_console(void);
-extern void shmobile_secondary_vector(void);
-extern void shmobile_secondary_vector_scu(void);
+extern void shmobile_boot_vector(void);
+extern unsigned long shmobile_boot_fn;
+extern unsigned long shmobile_boot_arg;
+extern void shmobile_boot_scu(void);
 struct clk;
 extern int shmobile_clk_init(void);
 extern void shmobile_handle_irq_intc(struct pt_regs *);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,93 +0,0 @@
-LIST "partner-jet-setup.txt"
-LIST "(C) Copyright 2010 Renesas Solutions Corp"
-LIST "Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
-
-LIST "RWT Setting"
-EW 0xE6020004, 0xA500
-EW 0xE6030004, 0xA500
-
-LIST "GPIO Setting"
-EB 0xE6051013, 0xA2
-
-LIST "CPG"
-ED 0xE61500C0, 0x00000002
-
-WAIT 1, 0xFE40009C
-
-LIST "FRQCR"
-ED 0xE6150000, 0x2D1305C3
-ED 0xE61500E0, 0x9E40358E
-ED 0xE6150004, 0x80331050
-
-WAIT 1, 0xFE40009C
-
-ED 0xE61500E4, 0x00002000
-
-WAIT 1, 0xFE40009C
-
-LIST "PLL"
-ED 0xE6150028, 0x00004000
-
-WAIT 1, 0xFE40009C
-
-ED 0xE615002C, 0x93000040
-
-WAIT 1, 0xFE40009C
-
-LIST "SUB/USBClk"
-ED 0xE6150080, 0x00000180
-
-LIST "BSC"
-ED 0xFEC10000, 0x00E0001B
-
-LIST "SBSC1"
-ED 0xFE400354, 0x01AD8000
-ED 0xFE400354, 0x01AD8001
-
-WAIT 5, 0xFE40009C
-
-ED 0xFE400008, 0xBCC90151
-ED 0xFE400040, 0x41774113
-ED 0xFE400044, 0x2712E229
-ED 0xFE400048, 0x20C18505
-ED 0xFE40004C, 0x00110209
-ED 0xFE400010, 0x00000087
-
-WAIT 30, 0xFE40009C
-
-ED 0xFE400084, 0x0000003F
-EB 0xFE500000, 0x00
-
-WAIT 5, 0xFE40009C
-
-ED 0xFE400084, 0x0000FF0A
-EB 0xFE500000, 0x00
-
-WAIT 1, 0xFE40009C
-
-ED 0xFE400084, 0x00002201
-EB 0xFE500000, 0x00
-ED 0xFE400084, 0x00000302
-EB 0xFE500000, 0x00
-EB 0xFE5C0000, 0x00
-ED 0xFE400008, 0xBCC90159
-ED 0xFE40008C, 0x88800004
-ED 0xFE400094, 0x00000004
-ED 0xFE400028, 0xA55A0032
-ED 0xFE40002C, 0xA55A000C
-ED 0xFE400020, 0xA55A2048
-ED 0xFE400008, 0xBCC90959
-
-LIST "Change CPGA setting"
-ED 0xE61500E0, 0x9E40352E
-ED 0xE6150004, 0x80331050
-
-WAIT 1, 0xFE40009C
-
-ED 0xFE400354, 0x01AD8002
-
-LIST "SCIF0 - Serial port for earlyprintk"
-EB 0xE6053098, 0xe1
-EW 0xE6C40000, 0x0000
-EB 0xE6C40004, 0x19
-EW 0xE6C40008, 0x0030
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/irqs.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/irqs.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/irqs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/irqs.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,4 +16,9 @@
 #define IRQPIN_BASE		2000
 #define irq_pin(nr)		((nr) + IRQPIN_BASE)
 
+/* GPIO IRQ */
+#define _GPIO_IRQ_BASE		2500
+#define GPIO_IRQ_BASE(x)	(_GPIO_IRQ_BASE + (32 * x))
+#define GPIO_IRQ(x, y)		(_GPIO_IRQ_BASE + (32 * x) + y)
+
 #endif /* __ASM_MACH_IRQS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/memory.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/memory.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/memory.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,7 +0,0 @@
-#ifndef __ASM_MACH_MEMORY_H
-#define __ASM_MACH_MEMORY_H
-
-#define PLAT_PHYS_OFFSET	UL(CONFIG_MEMORY_START)
-#define MEM_SIZE	UL(CONFIG_MEMORY_SIZE)
-
-#endif /* __ASM_MACH_MEMORY_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-#ifndef MMC_AP4EB_H
-#define MMC_AP4EB_H
-
-#define PORT185CR      (void __iomem *)0xe60520b9
-#define PORT186CR      (void __iomem *)0xe60520ba
-#define PORT187CR      (void __iomem *)0xe60520bb
-#define PORT188CR      (void __iomem *)0xe60520bc
-
-#define PORTR191_160DR (void __iomem *)0xe6056014
-
-static inline void mmc_init_progress(void)
-{
-       /* Initialise LEDS1-4
-        * registers: PORT185CR-PORT188CR (LED1-LED4 Control)
-        * value:     0x10 - enable output
-        */
-       __raw_writeb(0x10, PORT185CR);
-       __raw_writeb(0x10, PORT186CR);
-       __raw_writeb(0x10, PORT187CR);
-       __raw_writeb(0x10, PORT188CR);
-}
-
-static inline void mmc_update_progress(int n)
-{
-	__raw_writel((__raw_readl(PORTR191_160DR) & ~(0xf << 25)) |
-		     (1 << (25 + n)), PORTR191_160DR);
-}
-
-#endif /* MMC_AP4EB_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/mmc.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/mmc.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/mmc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/mmc.h	2013-08-25 20:43:22.000000000 -0400
@@ -7,9 +7,7 @@
  *
  **************************************************/
 
-#ifdef CONFIG_MACH_AP4EVB
-#include "mach/mmc-ap4eb.h"
-#elif defined(CONFIG_MACH_MACKEREL)
+#ifdef CONFIG_MACH_MACKEREL
 #include "mach/mmc-mackerel.h"
 #else
 #error "unsupported board."
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/r8a7740.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/r8a7740.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/r8a7740.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/r8a7740.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,494 +28,6 @@
 #define MD_CK1	(1 << 1)
 #define MD_CK0	(1 << 0)
 
-/*
- * Pin Function Controller:
- *	GPIO_FN_xx - GPIO used to select pin function
- *	GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
- */
-enum {
-	/* PORT */
-	GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
-	GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
-
-	GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
-	GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
-
-	GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
-	GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
-
-	GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
-	GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
-
-	GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
-	GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
-
-	GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
-	GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
-
-	GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
-	GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
-
-	GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
-	GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
-
-	GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
-	GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
-
-	GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
-	GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
-
-	GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
-	GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
-
-	GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
-	GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
-
-	GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
-	GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
-
-	GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
-	GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
-
-	GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
-	GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
-
-	GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
-	GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
-
-	GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
-	GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
-
-	GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
-	GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
-
-	GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
-	GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
-
-	GPIO_PORT190, GPIO_PORT191, GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
-	GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
-
-	GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
-	GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
-
-	GPIO_PORT210, GPIO_PORT211,
-
-	/* IRQ */
-	GPIO_FN_IRQ0_PORT2,	GPIO_FN_IRQ0_PORT13,
-	GPIO_FN_IRQ1,
-	GPIO_FN_IRQ2_PORT11,	GPIO_FN_IRQ2_PORT12,
-	GPIO_FN_IRQ3_PORT10,	GPIO_FN_IRQ3_PORT14,
-	GPIO_FN_IRQ4_PORT15,	GPIO_FN_IRQ4_PORT172,
-	GPIO_FN_IRQ5_PORT0,	GPIO_FN_IRQ5_PORT1,
-	GPIO_FN_IRQ6_PORT121,	GPIO_FN_IRQ6_PORT173,
-	GPIO_FN_IRQ7_PORT120,	GPIO_FN_IRQ7_PORT209,
-	GPIO_FN_IRQ8,
-	GPIO_FN_IRQ9_PORT118,	GPIO_FN_IRQ9_PORT210,
-	GPIO_FN_IRQ10,
-	GPIO_FN_IRQ11,
-	GPIO_FN_IRQ12_PORT42,	GPIO_FN_IRQ12_PORT97,
-	GPIO_FN_IRQ13_PORT64,	GPIO_FN_IRQ13_PORT98,
-	GPIO_FN_IRQ14_PORT63,	GPIO_FN_IRQ14_PORT99,
-	GPIO_FN_IRQ15_PORT62,	GPIO_FN_IRQ15_PORT100,
-	GPIO_FN_IRQ16_PORT68,	GPIO_FN_IRQ16_PORT211,
-	GPIO_FN_IRQ17,
-	GPIO_FN_IRQ18,
-	GPIO_FN_IRQ19,
-	GPIO_FN_IRQ20,
-	GPIO_FN_IRQ21,
-	GPIO_FN_IRQ22,
-	GPIO_FN_IRQ23,
-	GPIO_FN_IRQ24,
-	GPIO_FN_IRQ25,
-	GPIO_FN_IRQ26_PORT58,	GPIO_FN_IRQ26_PORT81,
-	GPIO_FN_IRQ27_PORT57,	GPIO_FN_IRQ27_PORT168,
-	GPIO_FN_IRQ28_PORT56,	GPIO_FN_IRQ28_PORT169,
-	GPIO_FN_IRQ29_PORT50,	GPIO_FN_IRQ29_PORT170,
-	GPIO_FN_IRQ30_PORT49,	GPIO_FN_IRQ30_PORT171,
-	GPIO_FN_IRQ31_PORT41,	GPIO_FN_IRQ31_PORT167,
-
-	/* Function */
-
-	/* DBGT */
-	GPIO_FN_DBGMDT2,	GPIO_FN_DBGMDT1,	GPIO_FN_DBGMDT0,
-	GPIO_FN_DBGMD10,	GPIO_FN_DBGMD11,	GPIO_FN_DBGMD20,
-	GPIO_FN_DBGMD21,
-
-	/* FSI-A */
-	GPIO_FN_FSIAISLD_PORT0,		/* FSIAISLD Port 0/5 */
-	GPIO_FN_FSIAISLD_PORT5,
-	GPIO_FN_FSIASPDIF_PORT9,	/* FSIASPDIF Port 9/18 */
-	GPIO_FN_FSIASPDIF_PORT18,
-	GPIO_FN_FSIAOSLD1,	GPIO_FN_FSIAOSLD2,
-	GPIO_FN_FSIAOLR,	GPIO_FN_FSIAOBT,
-	GPIO_FN_FSIAOSLD,	GPIO_FN_FSIAOMC,
-	GPIO_FN_FSIACK,		GPIO_FN_FSIAILR,
-	GPIO_FN_FSIAIBT,
-
-	/* FSI-B */
-	GPIO_FN_FSIBCK,
-
-	/* FMSI */
-	GPIO_FN_FMSISLD_PORT1, /* FMSISLD Port 1/6 */
-	GPIO_FN_FMSISLD_PORT6,
-	GPIO_FN_FMSIILR,	GPIO_FN_FMSIIBT,
-	GPIO_FN_FMSIOLR,	GPIO_FN_FMSIOBT,
-	GPIO_FN_FMSICK,		GPIO_FN_FMSOILR,
-	GPIO_FN_FMSOIBT,	GPIO_FN_FMSOOLR,
-	GPIO_FN_FMSOOBT,	GPIO_FN_FMSOSLD,
-	GPIO_FN_FMSOCK,
-
-	/* SCIFA0 */
-	GPIO_FN_SCIFA0_SCK,	GPIO_FN_SCIFA0_CTS,
-	GPIO_FN_SCIFA0_RTS,	GPIO_FN_SCIFA0_RXD,
-	GPIO_FN_SCIFA0_TXD,
-
-	/* SCIFA1 */
-	GPIO_FN_SCIFA1_CTS,	GPIO_FN_SCIFA1_SCK,
-	GPIO_FN_SCIFA1_RXD,	GPIO_FN_SCIFA1_TXD,
-	GPIO_FN_SCIFA1_RTS,
-
-	/* SCIFA2 */
-	GPIO_FN_SCIFA2_SCK_PORT22, /* SCIFA2_SCK Port 22/199 */
-	GPIO_FN_SCIFA2_SCK_PORT199,
-	GPIO_FN_SCIFA2_RXD,	GPIO_FN_SCIFA2_TXD,
-	GPIO_FN_SCIFA2_CTS,	GPIO_FN_SCIFA2_RTS,
-
-	/* SCIFA3 */
-	GPIO_FN_SCIFA3_RTS_PORT105, /* MSEL5CR_8_0 */
-	GPIO_FN_SCIFA3_SCK_PORT116,
-	GPIO_FN_SCIFA3_CTS_PORT117,
-	GPIO_FN_SCIFA3_RXD_PORT174,
-	GPIO_FN_SCIFA3_TXD_PORT175,
-
-	GPIO_FN_SCIFA3_RTS_PORT161, /* MSEL5CR_8_1 */
-	GPIO_FN_SCIFA3_SCK_PORT158,
-	GPIO_FN_SCIFA3_CTS_PORT162,
-	GPIO_FN_SCIFA3_RXD_PORT159,
-	GPIO_FN_SCIFA3_TXD_PORT160,
-
-	/* SCIFA4 */
-	GPIO_FN_SCIFA4_RXD_PORT12, /* MSEL5CR[12:11] = 00 */
-	GPIO_FN_SCIFA4_TXD_PORT13,
-
-	GPIO_FN_SCIFA4_RXD_PORT204, /* MSEL5CR[12:11] = 01 */
-	GPIO_FN_SCIFA4_TXD_PORT203,
-
-	GPIO_FN_SCIFA4_RXD_PORT94, /* MSEL5CR[12:11] = 10 */
-	GPIO_FN_SCIFA4_TXD_PORT93,
-
-	GPIO_FN_SCIFA4_SCK_PORT21, /* SCIFA4_SCK Port 21/205 */
-	GPIO_FN_SCIFA4_SCK_PORT205,
-
-	/* SCIFA5 */
-	GPIO_FN_SCIFA5_TXD_PORT20, /* MSEL5CR[15:14] = 00 */
-	GPIO_FN_SCIFA5_RXD_PORT10,
-
-	GPIO_FN_SCIFA5_RXD_PORT207, /* MSEL5CR[15:14] = 01 */
-	GPIO_FN_SCIFA5_TXD_PORT208,
-
-	GPIO_FN_SCIFA5_TXD_PORT91, /* MSEL5CR[15:14] = 10 */
-	GPIO_FN_SCIFA5_RXD_PORT92,
-
-	GPIO_FN_SCIFA5_SCK_PORT23, /* SCIFA5_SCK Port 23/206 */
-	GPIO_FN_SCIFA5_SCK_PORT206,
-
-	/* SCIFA6 */
-	GPIO_FN_SCIFA6_SCK,	GPIO_FN_SCIFA6_RXD,	GPIO_FN_SCIFA6_TXD,
-
-	/* SCIFA7 */
-	GPIO_FN_SCIFA7_TXD,	GPIO_FN_SCIFA7_RXD,
-
-	/* SCIFAB */
-	GPIO_FN_SCIFB_SCK_PORT190, /* MSEL5CR_17_0 */
-	GPIO_FN_SCIFB_RXD_PORT191,
-	GPIO_FN_SCIFB_TXD_PORT192,
-	GPIO_FN_SCIFB_RTS_PORT186,
-	GPIO_FN_SCIFB_CTS_PORT187,
-
-	GPIO_FN_SCIFB_SCK_PORT2, /* MSEL5CR_17_1 */
-	GPIO_FN_SCIFB_RXD_PORT3,
-	GPIO_FN_SCIFB_TXD_PORT4,
-	GPIO_FN_SCIFB_RTS_PORT172,
-	GPIO_FN_SCIFB_CTS_PORT173,
-
-	/* LCD0 */
-	GPIO_FN_LCDC0_SELECT,
-
-	/* LCD1 */
-	GPIO_FN_LCDC1_SELECT,
-
-	/* RSPI */
-	GPIO_FN_RSPI_SSL0_A,	GPIO_FN_RSPI_SSL1_A,
-	GPIO_FN_RSPI_SSL2_A,	GPIO_FN_RSPI_SSL3_A,
-	GPIO_FN_RSPI_MOSI_A,	GPIO_FN_RSPI_MISO_A,
-	GPIO_FN_RSPI_CK_A,
-
-	/* VIO CKO */
-	GPIO_FN_VIO_CKO1,
-	GPIO_FN_VIO_CKO2,
-	GPIO_FN_VIO_CKO_1,
-	GPIO_FN_VIO_CKO,
-
-	/* VIO0 */
-	GPIO_FN_VIO0_D0,	GPIO_FN_VIO0_D1,	GPIO_FN_VIO0_D2,
-	GPIO_FN_VIO0_D3,	GPIO_FN_VIO0_D4,	GPIO_FN_VIO0_D5,
-	GPIO_FN_VIO0_D6,	GPIO_FN_VIO0_D7,	GPIO_FN_VIO0_D8,
-	GPIO_FN_VIO0_D9,	GPIO_FN_VIO0_D10,	GPIO_FN_VIO0_D11,
-	GPIO_FN_VIO0_D12,	GPIO_FN_VIO0_VD,	GPIO_FN_VIO0_HD,
-	GPIO_FN_VIO0_CLK,	GPIO_FN_VIO0_FIELD,
-
-	GPIO_FN_VIO0_D13_PORT26, /* MSEL5CR_27_0 */
-	GPIO_FN_VIO0_D14_PORT25,
-	GPIO_FN_VIO0_D15_PORT24,
-
-	GPIO_FN_VIO0_D13_PORT22, /* MSEL5CR_27_1 */
-	GPIO_FN_VIO0_D14_PORT95,
-	GPIO_FN_VIO0_D15_PORT96,
-
-	/* VIO1 */
-	GPIO_FN_VIO1_D0,	GPIO_FN_VIO1_D1,	GPIO_FN_VIO1_D2,
-	GPIO_FN_VIO1_D3,	GPIO_FN_VIO1_D4,	GPIO_FN_VIO1_D5,
-	GPIO_FN_VIO1_D6,	GPIO_FN_VIO1_D7,	GPIO_FN_VIO1_VD,
-	GPIO_FN_VIO1_HD,	GPIO_FN_VIO1_CLK,	GPIO_FN_VIO1_FIELD,
-
-	/* TPU0 */
-	GPIO_FN_TPU0TO0,	GPIO_FN_TPU0TO1,
-	GPIO_FN_TPU0TO3,
-	GPIO_FN_TPU0TO2_PORT66, /* TPU0TO2 Port 66/202 */
-	GPIO_FN_TPU0TO2_PORT202,
-
-	/* SSP1 0 */
-	GPIO_FN_STP0_IPD0,	GPIO_FN_STP0_IPD1,	GPIO_FN_STP0_IPD2,
-	GPIO_FN_STP0_IPD3,	GPIO_FN_STP0_IPD4,	GPIO_FN_STP0_IPD5,
-	GPIO_FN_STP0_IPD6,	GPIO_FN_STP0_IPD7,	GPIO_FN_STP0_IPEN,
-	GPIO_FN_STP0_IPCLK,	GPIO_FN_STP0_IPSYNC,
-
-	/* SSP1 1 */
-	GPIO_FN_STP1_IPD1,	GPIO_FN_STP1_IPD2,	GPIO_FN_STP1_IPD3,
-	GPIO_FN_STP1_IPD4,	GPIO_FN_STP1_IPD5,	GPIO_FN_STP1_IPD6,
-	GPIO_FN_STP1_IPD7,	GPIO_FN_STP1_IPCLK,	GPIO_FN_STP1_IPSYNC,
-
-	GPIO_FN_STP1_IPD0_PORT186, /* MSEL5CR_23_0 */
-	GPIO_FN_STP1_IPEN_PORT187,
-
-	GPIO_FN_STP1_IPD0_PORT194, /* MSEL5CR_23_1 */
-	GPIO_FN_STP1_IPEN_PORT193,
-
-	/* SIM */
-	GPIO_FN_SIM_RST,	GPIO_FN_SIM_CLK,
-	GPIO_FN_SIM_D_PORT22, /* SIM_D  Port 22/199 */
-	GPIO_FN_SIM_D_PORT199,
-
-	/* MSIOF2 */
-	GPIO_FN_MSIOF2_TXD,	GPIO_FN_MSIOF2_RXD,	GPIO_FN_MSIOF2_TSCK,
-	GPIO_FN_MSIOF2_SS2,	GPIO_FN_MSIOF2_TSYNC,	GPIO_FN_MSIOF2_SS1,
-	GPIO_FN_MSIOF2_MCK1,	GPIO_FN_MSIOF2_MCK0,	GPIO_FN_MSIOF2_RSYNC,
-	GPIO_FN_MSIOF2_RSCK,
-
-	/* KEYSC */
-	GPIO_FN_KEYIN4,		GPIO_FN_KEYIN5,
-	GPIO_FN_KEYIN6,		GPIO_FN_KEYIN7,
-	GPIO_FN_KEYOUT0,	GPIO_FN_KEYOUT1,	GPIO_FN_KEYOUT2,
-	GPIO_FN_KEYOUT3,	GPIO_FN_KEYOUT4,	GPIO_FN_KEYOUT5,
-	GPIO_FN_KEYOUT6,	GPIO_FN_KEYOUT7,
-
-	GPIO_FN_KEYIN0_PORT43, /* MSEL4CR_18_0 */
-	GPIO_FN_KEYIN1_PORT44,
-	GPIO_FN_KEYIN2_PORT45,
-	GPIO_FN_KEYIN3_PORT46,
-
-	GPIO_FN_KEYIN0_PORT58, /* MSEL4CR_18_1 */
-	GPIO_FN_KEYIN1_PORT57,
-	GPIO_FN_KEYIN2_PORT56,
-	GPIO_FN_KEYIN3_PORT55,
-
-	/* VOU */
-	GPIO_FN_DV_D0,	GPIO_FN_DV_D1,	GPIO_FN_DV_D2,	GPIO_FN_DV_D3,
-	GPIO_FN_DV_D4,	GPIO_FN_DV_D5,	GPIO_FN_DV_D6,	GPIO_FN_DV_D7,
-	GPIO_FN_DV_D8,	GPIO_FN_DV_D9,	GPIO_FN_DV_D10,	GPIO_FN_DV_D11,
-	GPIO_FN_DV_D12,	GPIO_FN_DV_D13,	GPIO_FN_DV_D14,	GPIO_FN_DV_D15,
-	GPIO_FN_DV_CLK,
-	GPIO_FN_DV_VSYNC,
-	GPIO_FN_DV_HSYNC,
-
-	/* MEMC */
-	GPIO_FN_MEMC_AD0,	GPIO_FN_MEMC_AD1,	GPIO_FN_MEMC_AD2,
-	GPIO_FN_MEMC_AD3,	GPIO_FN_MEMC_AD4,	GPIO_FN_MEMC_AD5,
-	GPIO_FN_MEMC_AD6,	GPIO_FN_MEMC_AD7,	GPIO_FN_MEMC_AD8,
-	GPIO_FN_MEMC_AD9,	GPIO_FN_MEMC_AD10,	GPIO_FN_MEMC_AD11,
-	GPIO_FN_MEMC_AD12,	GPIO_FN_MEMC_AD13,	GPIO_FN_MEMC_AD14,
-	GPIO_FN_MEMC_AD15,	GPIO_FN_MEMC_CS0,	GPIO_FN_MEMC_INT,
-	GPIO_FN_MEMC_NWE,	GPIO_FN_MEMC_NOE,
-
-	GPIO_FN_MEMC_CS1, /* MSEL4CR_6_0 */
-	GPIO_FN_MEMC_ADV,
-	GPIO_FN_MEMC_WAIT,
-	GPIO_FN_MEMC_BUSCLK,
-
-	GPIO_FN_MEMC_A1, /* MSEL4CR_6_1 */
-	GPIO_FN_MEMC_DREQ0,
-	GPIO_FN_MEMC_DREQ1,
-	GPIO_FN_MEMC_A0,
-
-	/* MSIOF0 */
-	GPIO_FN_MSIOF0_SS1,	GPIO_FN_MSIOF0_SS2,
-	GPIO_FN_MSIOF0_RXD,	GPIO_FN_MSIOF0_TXD,
-	GPIO_FN_MSIOF0_MCK0,	GPIO_FN_MSIOF0_MCK1,
-	GPIO_FN_MSIOF0_RSYNC,	GPIO_FN_MSIOF0_RSCK,
-	GPIO_FN_MSIOF0_TSCK,	GPIO_FN_MSIOF0_TSYNC,
-
-	/* MSIOF1 */
-	GPIO_FN_MSIOF1_RSCK,	GPIO_FN_MSIOF1_RSYNC,
-	GPIO_FN_MSIOF1_MCK0,	GPIO_FN_MSIOF1_MCK1,
-
-	GPIO_FN_MSIOF1_SS2_PORT116,	GPIO_FN_MSIOF1_SS1_PORT117,
-	GPIO_FN_MSIOF1_RXD_PORT118,	GPIO_FN_MSIOF1_TXD_PORT119,
-	GPIO_FN_MSIOF1_TSYNC_PORT120,
-	GPIO_FN_MSIOF1_TSCK_PORT121,	/* MSEL4CR_10_0 */
-
-	GPIO_FN_MSIOF1_SS1_PORT67,	GPIO_FN_MSIOF1_TSCK_PORT72,
-	GPIO_FN_MSIOF1_TSYNC_PORT73,	GPIO_FN_MSIOF1_TXD_PORT74,
-	GPIO_FN_MSIOF1_RXD_PORT75,
-	GPIO_FN_MSIOF1_SS2_PORT202,	/* MSEL4CR_10_1 */
-
-	/* GPIO */
-	GPIO_FN_GPO0,	GPIO_FN_GPI0,
-	GPIO_FN_GPO1,	GPIO_FN_GPI1,
-
-	/* USB0 */
-	GPIO_FN_USB0_OCI,	GPIO_FN_USB0_PPON,	GPIO_FN_VBUS,
-
-	/* USB1 */
-	GPIO_FN_USB1_OCI,	GPIO_FN_USB1_PPON,
-
-	/* BBIF1 */
-	GPIO_FN_BBIF1_RXD,	GPIO_FN_BBIF1_TXD,	GPIO_FN_BBIF1_TSYNC,
-	GPIO_FN_BBIF1_TSCK,	GPIO_FN_BBIF1_RSCK,	GPIO_FN_BBIF1_RSYNC,
-	GPIO_FN_BBIF1_FLOW,	GPIO_FN_BBIF1_RX_FLOW_N,
-
-	/* BBIF2 */
-	GPIO_FN_BBIF2_TXD2_PORT5, /* MSEL5CR_0_0 */
-	GPIO_FN_BBIF2_RXD2_PORT60,
-	GPIO_FN_BBIF2_TSYNC2_PORT6,
-	GPIO_FN_BBIF2_TSCK2_PORT59,
-
-	GPIO_FN_BBIF2_RXD2_PORT90, /* MSEL5CR_0_1 */
-	GPIO_FN_BBIF2_TXD2_PORT183,
-	GPIO_FN_BBIF2_TSCK2_PORT89,
-	GPIO_FN_BBIF2_TSYNC2_PORT184,
-
-	/* BSC / FLCTL / PCMCIA */
-	GPIO_FN_CS0,	GPIO_FN_CS2,	GPIO_FN_CS4,
-	GPIO_FN_CS5B,	GPIO_FN_CS6A,
-	GPIO_FN_CS5A_PORT105, /* CS5A PORT 19/105 */
-	GPIO_FN_CS5A_PORT19,
-	GPIO_FN_IOIS16, /* ? */
-
-	GPIO_FN_A0,	GPIO_FN_A1,	GPIO_FN_A2,	GPIO_FN_A3,
-	GPIO_FN_A4_FOE,		/* share with FLCTL */
-	GPIO_FN_A5_FCDE,	/* share with FLCTL */
-	GPIO_FN_A6,	GPIO_FN_A7,	GPIO_FN_A8,	GPIO_FN_A9,
-	GPIO_FN_A10,	GPIO_FN_A11,	GPIO_FN_A12,	GPIO_FN_A13,
-	GPIO_FN_A14,	GPIO_FN_A15,	GPIO_FN_A16,	GPIO_FN_A17,
-	GPIO_FN_A18,	GPIO_FN_A19,	GPIO_FN_A20,	GPIO_FN_A21,
-	GPIO_FN_A22,	GPIO_FN_A23,	GPIO_FN_A24,	GPIO_FN_A25,
-	GPIO_FN_A26,
-
-	GPIO_FN_D0_NAF0,	GPIO_FN_D1_NAF1,	/* share with FLCTL */
-	GPIO_FN_D2_NAF2,	GPIO_FN_D3_NAF3,	/* share with FLCTL */
-	GPIO_FN_D4_NAF4,	GPIO_FN_D5_NAF5,	/* share with FLCTL */
-	GPIO_FN_D6_NAF6,	GPIO_FN_D7_NAF7,	/* share with FLCTL */
-	GPIO_FN_D8_NAF8,	GPIO_FN_D9_NAF9,	/* share with FLCTL */
-	GPIO_FN_D10_NAF10,	GPIO_FN_D11_NAF11,	/* share with FLCTL */
-	GPIO_FN_D12_NAF12,	GPIO_FN_D13_NAF13,	/* share with FLCTL */
-	GPIO_FN_D14_NAF14,	GPIO_FN_D15_NAF15,	/* share with FLCTL */
-
-	GPIO_FN_D16,	GPIO_FN_D17,	GPIO_FN_D18,	GPIO_FN_D19,
-	GPIO_FN_D20,	GPIO_FN_D21,	GPIO_FN_D22,	GPIO_FN_D23,
-	GPIO_FN_D24,	GPIO_FN_D25,	GPIO_FN_D26,	GPIO_FN_D27,
-	GPIO_FN_D28,	GPIO_FN_D29,	GPIO_FN_D30,	GPIO_FN_D31,
-
-	GPIO_FN_WE0_FWE,	/* share with FLCTL */
-	GPIO_FN_WE1,
-	GPIO_FN_WE2_ICIORD,	/* share with PCMCIA */
-	GPIO_FN_WE3_ICIOWR,	/* share with PCMCIA */
-	GPIO_FN_CKO,	GPIO_FN_BS,	GPIO_FN_RDWR,
-	GPIO_FN_RD_FSC,		/* share with FLCTL */
-	GPIO_FN_WAIT_PORT177,	/* WAIT Port 90/177 */
-	GPIO_FN_WAIT_PORT90,
-
-	GPIO_FN_FCE0,	GPIO_FN_FCE1,	GPIO_FN_FRB, /* FLCTL */
-
-	/* IRDA */
-	GPIO_FN_IRDA_FIRSEL,	GPIO_FN_IRDA_IN,	GPIO_FN_IRDA_OUT,
-
-	/* ATAPI */
-	GPIO_FN_IDE_D0,		GPIO_FN_IDE_D1,		GPIO_FN_IDE_D2,
-	GPIO_FN_IDE_D3,		GPIO_FN_IDE_D4,		GPIO_FN_IDE_D5,
-	GPIO_FN_IDE_D6,		GPIO_FN_IDE_D7,		GPIO_FN_IDE_D8,
-	GPIO_FN_IDE_D9,		GPIO_FN_IDE_D10,	GPIO_FN_IDE_D11,
-	GPIO_FN_IDE_D12,	GPIO_FN_IDE_D13,	GPIO_FN_IDE_D14,
-	GPIO_FN_IDE_D15,	GPIO_FN_IDE_A0,		GPIO_FN_IDE_A1,
-	GPIO_FN_IDE_A2,		GPIO_FN_IDE_CS0,	GPIO_FN_IDE_CS1,
-	GPIO_FN_IDE_IOWR,	GPIO_FN_IDE_IORD,	GPIO_FN_IDE_IORDY,
-	GPIO_FN_IDE_INT,	GPIO_FN_IDE_RST,	GPIO_FN_IDE_DIRECTION,
-	GPIO_FN_IDE_EXBUF_ENB,	GPIO_FN_IDE_IODACK,	GPIO_FN_IDE_IODREQ,
-
-	/* RMII */
-	GPIO_FN_RMII_CRS_DV,	GPIO_FN_RMII_RX_ER,	GPIO_FN_RMII_RXD0,
-	GPIO_FN_RMII_RXD1,	GPIO_FN_RMII_TX_EN,	GPIO_FN_RMII_TXD0,
-	GPIO_FN_RMII_MDC,	GPIO_FN_RMII_TXD1,	GPIO_FN_RMII_MDIO,
-	GPIO_FN_RMII_REF50CK,	/* for RMII */
-	GPIO_FN_RMII_REF125CK,	/* for GMII */
-
-	/* GEther */
-	GPIO_FN_ET_TX_CLK,	GPIO_FN_ET_TX_EN,	GPIO_FN_ET_ETXD0,
-	GPIO_FN_ET_ETXD1,	GPIO_FN_ET_ETXD2,	GPIO_FN_ET_ETXD3,
-	GPIO_FN_ET_ETXD4,	GPIO_FN_ET_ETXD5, /* for GEther */
-	GPIO_FN_ET_ETXD6,	GPIO_FN_ET_ETXD7, /* for GEther */
-	GPIO_FN_ET_COL,		GPIO_FN_ET_TX_ER,
-	GPIO_FN_ET_RX_CLK,	GPIO_FN_ET_RX_DV,
-	GPIO_FN_ET_ERXD0,	GPIO_FN_ET_ERXD1,
-	GPIO_FN_ET_ERXD2,	GPIO_FN_ET_ERXD3,
-	GPIO_FN_ET_ERXD4,	GPIO_FN_ET_ERXD5, /* for GEther */
-	GPIO_FN_ET_ERXD6,	GPIO_FN_ET_ERXD7, /* for GEther */
-	GPIO_FN_ET_RX_ER,	GPIO_FN_ET_CRS,
-	GPIO_FN_ET_MDC,		GPIO_FN_ET_MDIO,
-	GPIO_FN_ET_LINK,	GPIO_FN_ET_PHY_INT,
-	GPIO_FN_ET_WOL,		GPIO_FN_ET_GTX_CLK,
-
-	/* DMA0 */
-	GPIO_FN_DREQ0,		GPIO_FN_DACK0,
-
-	/* DMA1 */
-	GPIO_FN_DREQ1,		GPIO_FN_DACK1,
-
-	/* SYSC */
-	GPIO_FN_RESETOUTS,
-	GPIO_FN_RESETP_PULLUP,
-	GPIO_FN_RESETP_PLAIN,
-
-	/* HDMI */
-	GPIO_FN_HDMI_HPD,
-	GPIO_FN_HDMI_CEC,
-
-	/* SDENC */
-	GPIO_FN_SDENC_CPG,
-	GPIO_FN_SDENC_DV_CLKI,
-
-	/* IRREM */
-	GPIO_FN_IROUT,
-
-	/* DEBUG */
-	GPIO_FN_EDEBGREQ_PULLDOWN,
-	GPIO_FN_EDEBGREQ_PULLUP,
-
-	GPIO_FN_TRACEAUD_FROM_VIO,
-	GPIO_FN_TRACEAUD_FROM_LCDC0,
-	GPIO_FN_TRACEAUD_FROM_MEMC,
-};
-
 /* DMA slave IDs */
 enum {
 	SHDMA_SLAVE_INVALID,
@@ -533,10 +45,13 @@ enum {
 };
 
 extern void r8a7740_meram_workaround(void);
+extern void r8a7740_init_delay(void);
 extern void r8a7740_init_irq(void);
+extern void r8a7740_init_irq_of(void);
 extern void r8a7740_map_io(void);
 extern void r8a7740_add_early_devices(void);
 extern void r8a7740_add_standard_devices(void);
+extern void r8a7740_add_standard_devices_dt(void);
 extern void r8a7740_clock_init(u8 md_ck);
 extern void r8a7740_pinmux_init(void);
 extern void r8a7740_pm_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/r8a7778.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/r8a7778.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/r8a7778.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/r8a7778.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,15 +18,26 @@
 #ifndef __ASM_R8A7778_H__
 #define __ASM_R8A7778_H__
 
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/sh_eth.h>
+#include <linux/platform_data/usb-rcar-phy.h>
 
 extern void r8a7778_add_standard_devices(void);
 extern void r8a7778_add_standard_devices_dt(void);
 extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata);
+extern void r8a7778_add_usb_phy_device(struct rcar_phy_platform_data *pdata);
+extern void r8a7778_add_i2c_device(int id);
+extern void r8a7778_add_hspi_device(int id);
+extern void r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info);
+
+extern void r8a7778_init_late(void);
 extern void r8a7778_init_delay(void);
 extern void r8a7778_init_irq(void);
 extern void r8a7778_init_irq_dt(void);
 extern void r8a7778_clock_init(void);
 extern void r8a7778_init_irq_extpin(int irlm);
+extern void r8a7778_pinmux_init(void);
+extern void r8a7778_sdhi_init(int id, struct sh_mobile_sdhi_info *info);
 
 #endif /* __ASM_R8A7778_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/r8a7779.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/r8a7779.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/r8a7779.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/r8a7779.h	2013-08-25 20:43:22.000000000 -0400
@@ -4,6 +4,7 @@
 #include <linux/sh_clk.h>
 #include <linux/pm_domain.h>
 #include <linux/sh_eth.h>
+#include <linux/platform_data/usb-rcar-phy.h>
 
 struct platform_device;
 
@@ -33,6 +34,8 @@ extern void r8a7779_add_early_devices(vo
 extern void r8a7779_add_standard_devices(void);
 extern void r8a7779_add_standard_devices_dt(void);
 extern void r8a7779_add_ether_device(struct sh_eth_plat_data *pdata);
+extern void r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata);
+extern void r8a7779_init_late(void);
 extern void r8a7779_clock_init(void);
 extern void r8a7779_pinmux_init(void);
 extern void r8a7779_pm_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/sh7372.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/sh7372.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/sh7372.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/sh7372.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,397 +15,6 @@
 #include <linux/pm_domain.h>
 #include <mach/pm-rmobile.h>
 
-/*
- * Pin Function Controller:
- *	GPIO_FN_xx - GPIO used to select pin function
- *	GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
- */
-enum {
-	/* PORT */
-	GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
-	GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
-
-	GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
-	GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
-
-	GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
-	GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
-
-	GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
-	GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
-
-	GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
-	GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
-
-	GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
-	GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
-
-	GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
-	GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
-
-	GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
-	GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
-
-	GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
-	GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
-
-	GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
-	GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
-
-	GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
-	GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
-
-	GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
-	GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
-
-	GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
-	GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
-
-	GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
-	GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
-
-	GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
-	GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
-
-	GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
-	GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
-
-	GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
-	GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
-
-	GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
-	GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
-
-	GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
-	GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
-
-	GPIO_PORT190,
-
-	/* IRQ */
-	GPIO_FN_IRQ0_6,		/* PORT   6 */
-	GPIO_FN_IRQ0_162,	/* PORT 162 */
-	GPIO_FN_IRQ1,		/* PORT  12 */
-	GPIO_FN_IRQ2_4,		/* PORT   4 */
-	GPIO_FN_IRQ2_5,		/* PORT   5 */
-	GPIO_FN_IRQ3_8,		/* PORT   8 */
-	GPIO_FN_IRQ3_16,	/* PORT  16 */
-	GPIO_FN_IRQ4_17,	/* PORT  17 */
-	GPIO_FN_IRQ4_163,	/* PORT 163 */
-	GPIO_FN_IRQ5,		/* PORT  18 */
-	GPIO_FN_IRQ6_39,	/* PORT  39 */
-	GPIO_FN_IRQ6_164,	/* PORT 164 */
-	GPIO_FN_IRQ7_40,	/* PORT  40 */
-	GPIO_FN_IRQ7_167,	/* PORT 167 */
-	GPIO_FN_IRQ8_41,	/* PORT  41 */
-	GPIO_FN_IRQ8_168,	/* PORT 168 */
-	GPIO_FN_IRQ9_42,	/* PORT  42 */
-	GPIO_FN_IRQ9_169,	/* PORT 169 */
-	GPIO_FN_IRQ10,		/* PORT  65 */
-	GPIO_FN_IRQ11,		/* PORT  67 */
-	GPIO_FN_IRQ12_80,	/* PORT  80 */
-	GPIO_FN_IRQ12_137,	/* PORT 137 */
-	GPIO_FN_IRQ13_81,	/* PORT  81 */
-	GPIO_FN_IRQ13_145,	/* PORT 145 */
-	GPIO_FN_IRQ14_82,	/* PORT  82 */
-	GPIO_FN_IRQ14_146,	/* PORT 146 */
-	GPIO_FN_IRQ15_83,	/* PORT  83 */
-	GPIO_FN_IRQ15_147,	/* PORT 147 */
-	GPIO_FN_IRQ16_84,	/* PORT  84 */
-	GPIO_FN_IRQ16_170,	/* PORT 170 */
-	GPIO_FN_IRQ17,		/* PORT  85 */
-	GPIO_FN_IRQ18,		/* PORT  86 */
-	GPIO_FN_IRQ19,		/* PORT  87 */
-	GPIO_FN_IRQ20,		/* PORT  92 */
-	GPIO_FN_IRQ21,		/* PORT  93 */
-	GPIO_FN_IRQ22,		/* PORT  94 */
-	GPIO_FN_IRQ23,		/* PORT  95 */
-	GPIO_FN_IRQ24,		/* PORT 112 */
-	GPIO_FN_IRQ25,		/* PORT 119 */
-	GPIO_FN_IRQ26_121,	/* PORT 121 */
-	GPIO_FN_IRQ26_172,	/* PORT 172 */
-	GPIO_FN_IRQ27_122,	/* PORT 122 */
-	GPIO_FN_IRQ27_180,	/* PORT 180 */
-	GPIO_FN_IRQ28_123,	/* PORT 123 */
-	GPIO_FN_IRQ28_181,	/* PORT 181 */
-	GPIO_FN_IRQ29_129,	/* PORT 129 */
-	GPIO_FN_IRQ29_182,	/* PORT 182 */
-	GPIO_FN_IRQ30_130,	/* PORT 130 */
-	GPIO_FN_IRQ30_183,	/* PORT 183 */
-	GPIO_FN_IRQ31_138,	/* PORT 138 */
-	GPIO_FN_IRQ31_184,	/* PORT 184 */
-
-	/*
-	 * MSIOF0	(PORT 36, 37, 38, 39
-	 * 		      40, 41, 42, 43, 44, 45)
-	 */
-	GPIO_FN_MSIOF0_TSYNC,	GPIO_FN_MSIOF0_TSCK,
-	GPIO_FN_MSIOF0_RXD,	GPIO_FN_MSIOF0_RSCK,
-	GPIO_FN_MSIOF0_RSYNC,	GPIO_FN_MSIOF0_MCK0,
-	GPIO_FN_MSIOF0_MCK1,	GPIO_FN_MSIOF0_SS1,
-	GPIO_FN_MSIOF0_SS2,	GPIO_FN_MSIOF0_TXD,
-
-	/*
-	 * MSIOF1	(PORT 39, 40, 41, 42, 43, 44
-	 * 		      84, 85, 86, 87, 88, 89, 90, 91, 92, 93)
-	 */
-	GPIO_FN_MSIOF1_TSCK_39,	GPIO_FN_MSIOF1_TSYNC_40,
-	GPIO_FN_MSIOF1_TSCK_88,	GPIO_FN_MSIOF1_TSYNC_89,
-	GPIO_FN_MSIOF1_TXD_41,	GPIO_FN_MSIOF1_RXD_42,
-	GPIO_FN_MSIOF1_TXD_90,	GPIO_FN_MSIOF1_RXD_91,
-	GPIO_FN_MSIOF1_SS1_43,	GPIO_FN_MSIOF1_SS2_44,
-	GPIO_FN_MSIOF1_SS1_92,	GPIO_FN_MSIOF1_SS2_93,
-	GPIO_FN_MSIOF1_RSCK,	GPIO_FN_MSIOF1_RSYNC,
-	GPIO_FN_MSIOF1_MCK0,	GPIO_FN_MSIOF1_MCK1,
-
-	/*
-	 * MSIOF2	(PORT 134, 135, 136, 137, 138, 139
-	 *		      148, 149, 150, 151)
-	 */
-	GPIO_FN_MSIOF2_RSCK,	GPIO_FN_MSIOF2_RSYNC,
-	GPIO_FN_MSIOF2_MCK0,	GPIO_FN_MSIOF2_MCK1,
-	GPIO_FN_MSIOF2_SS1,	GPIO_FN_MSIOF2_SS2,
-	GPIO_FN_MSIOF2_TSYNC,	GPIO_FN_MSIOF2_TSCK,
-	GPIO_FN_MSIOF2_RXD,	GPIO_FN_MSIOF2_TXD,
-
-	/* MSIOF3	(PORT 76, 77, 78, 79, 80, 81, 82, 83) */
-	GPIO_FN_BBIF1_RXD,	GPIO_FN_BBIF1_TSYNC,
-	GPIO_FN_BBIF1_TSCK,	GPIO_FN_BBIF1_TXD,
-	GPIO_FN_BBIF1_RSCK,	GPIO_FN_BBIF1_RSYNC,
-	GPIO_FN_BBIF1_FLOW,	GPIO_FN_BB_RX_FLOW_N,
-
-	/* MSIOF4	(PORT 0, 1, 2, 3) */
-	GPIO_FN_BBIF2_TSCK1,	GPIO_FN_BBIF2_TSYNC1,
-	GPIO_FN_BBIF2_TXD1,	GPIO_FN_BBIF2_RXD,
-
-	/* FSI		(PORT 4, 5, 6, 7, 8, 9, 10, 11, 15) */
-	GPIO_FN_FSIACK,		GPIO_FN_FSIBCK,
-	GPIO_FN_FSIAILR,	GPIO_FN_FSIAIBT,
-	GPIO_FN_FSIAISLD,	GPIO_FN_FSIAOMC,
-	GPIO_FN_FSIAOLR,	GPIO_FN_FSIAOBT,
-	GPIO_FN_FSIAOSLD,	GPIO_FN_FSIASPDIF_11,
-	GPIO_FN_FSIASPDIF_15,
-
-	/* FMSI		(PORT 12, 13, 14, 15, 16, 17, 18, 65) */
-	GPIO_FN_FMSOCK,		GPIO_FN_FMSOOLR,
-	GPIO_FN_FMSIOLR,	GPIO_FN_FMSOOBT,
-	GPIO_FN_FMSIOBT,	GPIO_FN_FMSOSLD,
-	GPIO_FN_FMSOILR,	GPIO_FN_FMSIILR,
-	GPIO_FN_FMSOIBT,	GPIO_FN_FMSIIBT,
-	GPIO_FN_FMSISLD,	GPIO_FN_FMSICK,
-
-	/* SCIFA0	(PORT 152, 153, 156, 157, 158) */
-	GPIO_FN_SCIFA0_TXD,	GPIO_FN_SCIFA0_RXD,
-	GPIO_FN_SCIFA0_SCK,	GPIO_FN_SCIFA0_RTS,
-	GPIO_FN_SCIFA0_CTS,
-
-	/* SCIFA1	(PORT 154, 155, 159, 160, 161) */
-	GPIO_FN_SCIFA1_TXD,	GPIO_FN_SCIFA1_RXD,
-	GPIO_FN_SCIFA1_SCK,	GPIO_FN_SCIFA1_RTS,
-	GPIO_FN_SCIFA1_CTS,
-
-	/* SCIFA2	(PORT 94, 95, 96, 97, 98) */
-	GPIO_FN_SCIFA2_CTS1,	GPIO_FN_SCIFA2_RTS1,
-	GPIO_FN_SCIFA2_TXD1,	GPIO_FN_SCIFA2_RXD1,
-	GPIO_FN_SCIFA2_SCK1,
-
-	/* SCIFA3	(PORT 43, 44,
-			     140, 141, 142, 143, 144) */
-	GPIO_FN_SCIFA3_CTS_43,	GPIO_FN_SCIFA3_CTS_140,
-	GPIO_FN_SCIFA3_RTS_44,	GPIO_FN_SCIFA3_RTS_141,
-	GPIO_FN_SCIFA3_SCK,	GPIO_FN_SCIFA3_TXD,
-	GPIO_FN_SCIFA3_RXD,
-
-	/* SCIFA4	(PORT 5, 6) */
-	GPIO_FN_SCIFA4_RXD,	GPIO_FN_SCIFA4_TXD,
-
-	/* SCIFA5	(PORT 8, 12) */
-	GPIO_FN_SCIFA5_RXD,	GPIO_FN_SCIFA5_TXD,
-
-	/* SCIFB	(PORT 162, 163, 164, 165, 166) */
-	GPIO_FN_SCIFB_SCK,	GPIO_FN_SCIFB_RTS,
-	GPIO_FN_SCIFB_CTS,	GPIO_FN_SCIFB_TXD,
-	GPIO_FN_SCIFB_RXD,
-
-	/*
-	 * CEU		(PORT 16, 17,
-	 *		      100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
-	 *		      110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
-	 *		      120)
-	 */
-	GPIO_FN_VIO_HD,		GPIO_FN_VIO_CKO1,	GPIO_FN_VIO_CKO2,
-	GPIO_FN_VIO_VD,		GPIO_FN_VIO_CLK,	GPIO_FN_VIO_FIELD,
-	GPIO_FN_VIO_CKO,
-	GPIO_FN_VIO_D0,		GPIO_FN_VIO_D1,		GPIO_FN_VIO_D2,
-	GPIO_FN_VIO_D3,		GPIO_FN_VIO_D4,		GPIO_FN_VIO_D5,
-	GPIO_FN_VIO_D6,		GPIO_FN_VIO_D7,		GPIO_FN_VIO_D8,
-	GPIO_FN_VIO_D9,		GPIO_FN_VIO_D10,	GPIO_FN_VIO_D11,
-	GPIO_FN_VIO_D12,	GPIO_FN_VIO_D13,	GPIO_FN_VIO_D14,
-	GPIO_FN_VIO_D15,
-
-	/* USB0		(PORT 113, 114, 115, 116, 117, 167) */
-	GPIO_FN_IDIN_0,		GPIO_FN_EXTLP_0,
-	GPIO_FN_OVCN2_0,	GPIO_FN_PWEN_0,
-	GPIO_FN_OVCN_0,		GPIO_FN_VBUS0_0,
-
-	/* USB1		(PORT 18, 113, 114, 115, 116, 117, 138, 162, 168) */
-	GPIO_FN_IDIN_1_18,	GPIO_FN_IDIN_1_113,
-	GPIO_FN_PWEN_1_115,	GPIO_FN_PWEN_1_138,
-	GPIO_FN_OVCN_1_114,	GPIO_FN_OVCN_1_162,
-	GPIO_FN_EXTLP_1,	GPIO_FN_OVCN2_1,
-	GPIO_FN_VBUS0_1,
-
-	/* GPIO		(PORT 41, 42, 43, 44) */
-	GPIO_FN_GPI0,	GPIO_FN_GPI1,	GPIO_FN_GPO0,	GPIO_FN_GPO1,
-
-	/*
-	 * BSC		(PORT 19,
-	 *		      20, 21, 22, 25, 26, 27, 28, 29,
-	 *		      30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
-	 *		      40, 41, 42, 43, 44, 45,
-	 *		      62, 63, 64, 65, 66, 67,
-	 *		      71, 72, 74, 75)
-	 */
-	GPIO_FN_BS,	GPIO_FN_WE1,
-	GPIO_FN_CKO,	GPIO_FN_WAIT,	GPIO_FN_RDWR,
-
-	GPIO_FN_A0,	GPIO_FN_A1,	GPIO_FN_A2,	GPIO_FN_A3,
-	GPIO_FN_A6,	GPIO_FN_A7,	GPIO_FN_A8,	GPIO_FN_A9,
-	GPIO_FN_A10,	GPIO_FN_A11,	GPIO_FN_A12,	GPIO_FN_A13,
-	GPIO_FN_A14,	GPIO_FN_A15,	GPIO_FN_A16,	GPIO_FN_A17,
-	GPIO_FN_A18,	GPIO_FN_A19,	GPIO_FN_A20,	GPIO_FN_A21,
-	GPIO_FN_A22,	GPIO_FN_A23,	GPIO_FN_A24,	GPIO_FN_A25,
-	GPIO_FN_A26,
-
-	GPIO_FN_CS0,	GPIO_FN_CS2,	GPIO_FN_CS4,
-	GPIO_FN_CS5A,	GPIO_FN_CS5B,	GPIO_FN_CS6A,
-
-	/*
-	 * BSC/FLCTL		(PORT 23, 24,
-	 *			      46, 47, 48, 49,
-	 *			      50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
-	 *			      60, 61, 69, 70)
-	 */
-	GPIO_FN_RD_FSC,		GPIO_FN_WE0_FWE,
-	GPIO_FN_A4_FOE,		GPIO_FN_A5_FCDE,
-	GPIO_FN_D0_NAF0,	GPIO_FN_D1_NAF1,	GPIO_FN_D2_NAF2,
-	GPIO_FN_D3_NAF3,	GPIO_FN_D4_NAF4,	GPIO_FN_D5_NAF5,
-	GPIO_FN_D6_NAF6,	GPIO_FN_D7_NAF7,	GPIO_FN_D8_NAF8,
-	GPIO_FN_D9_NAF9,	GPIO_FN_D10_NAF10,	GPIO_FN_D11_NAF11,
-	GPIO_FN_D12_NAF12,	GPIO_FN_D13_NAF13,	GPIO_FN_D14_NAF14,
-	GPIO_FN_D15_NAF15,
-
-	/* SPU2		(PORT 65) */
-	GPIO_FN_VINT_I,
-
-	/* FLCTL	(PORT 66, 68, 73) */
-	GPIO_FN_FCE1,	GPIO_FN_FCE0,	GPIO_FN_FRB,
-
-	/* HSI		(PORT 76, 77, 78, 79, 80, 81, 82, 83) */
-	GPIO_FN_GP_RX_FLAG,	GPIO_FN_GP_RX_DATA,	GPIO_FN_GP_TX_READY,
-	GPIO_FN_GP_RX_WAKE,	GPIO_FN_MP_TX_FLAG,	GPIO_FN_MP_TX_DATA,
-	GPIO_FN_MP_RX_READY,	GPIO_FN_MP_TX_WAKE,
-
-	/*
-	 * MFI		(PORT 76, 77, 78, 79,
-	 *		      80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
-	 *		      90, 91, 92, 93, 94, 95, 96, 97, 98, 99)
-	 */
-	GPIO_FN_MFIv6,	/* see MSEL4CR 6 */
-	GPIO_FN_MFIv4,	/* see MSEL4CR 6 */
-
-	GPIO_FN_MEMC_CS0,		GPIO_FN_MEMC_BUSCLK_MEMC_A0,
-	GPIO_FN_MEMC_CS1_MEMC_A1,	GPIO_FN_MEMC_ADV_MEMC_DREQ0,
-	GPIO_FN_MEMC_WAIT_MEMC_DREQ1,	GPIO_FN_MEMC_NOE,
-	GPIO_FN_MEMC_NWE,		GPIO_FN_MEMC_INT,
-
-	GPIO_FN_MEMC_AD0,	GPIO_FN_MEMC_AD1,	GPIO_FN_MEMC_AD2,
-	GPIO_FN_MEMC_AD3,	GPIO_FN_MEMC_AD4,	GPIO_FN_MEMC_AD5,
-	GPIO_FN_MEMC_AD6,	GPIO_FN_MEMC_AD7,	GPIO_FN_MEMC_AD8,
-	GPIO_FN_MEMC_AD9,	GPIO_FN_MEMC_AD10,	GPIO_FN_MEMC_AD11,
-	GPIO_FN_MEMC_AD12,	GPIO_FN_MEMC_AD13,	GPIO_FN_MEMC_AD14,
-	GPIO_FN_MEMC_AD15,
-
-	/* SIM		(PORT 94, 95, 98) */
-	GPIO_FN_SIM_RST,	GPIO_FN_SIM_CLK,	GPIO_FN_SIM_D,
-
-	/* TPU		(PORT 93, 99, 112, 160, 161) */
-	GPIO_FN_TPU0TO0,	GPIO_FN_TPU0TO1,
-	GPIO_FN_TPU0TO2_93,	GPIO_FN_TPU0TO2_99,
-	GPIO_FN_TPU0TO3,
-
-	/* I2C2		(PORT 110, 111) */
-	GPIO_FN_I2C_SCL2,	GPIO_FN_I2C_SDA2,
-
-	/* I2C3(1)	(PORT 114, 115) */
-	GPIO_FN_I2C_SCL3,	GPIO_FN_I2C_SDA3,
-
-	/* I2C3(2)	(PORT 137, 145) */
-	GPIO_FN_I2C_SCL3S,	GPIO_FN_I2C_SDA3S,
-
-	/* I2C4(2)	(PORT 116, 117) */
-	GPIO_FN_I2C_SCL4,	GPIO_FN_I2C_SDA4,
-
-	/* I2C4(2)	(PORT 146, 147) */
-	GPIO_FN_I2C_SCL4S,	GPIO_FN_I2C_SDA4S,
-
-	/*
-	 * KEYSC	(PORT 121, 122, 123, 124, 125, 126, 127, 128, 129,
-	 *		      130, 131, 132, 133, 134, 135, 136)
-	 */
-	GPIO_FN_KEYOUT0,	GPIO_FN_KEYIN0_121,	GPIO_FN_KEYIN0_136,
-	GPIO_FN_KEYOUT1,	GPIO_FN_KEYIN1_122,	GPIO_FN_KEYIN1_135,
-	GPIO_FN_KEYOUT2,	GPIO_FN_KEYIN2_123,	GPIO_FN_KEYIN2_134,
-	GPIO_FN_KEYOUT3,	GPIO_FN_KEYIN3_124,	GPIO_FN_KEYIN3_133,
-	GPIO_FN_KEYOUT4,	GPIO_FN_KEYIN4,
-	GPIO_FN_KEYOUT5,	GPIO_FN_KEYIN5,
-	GPIO_FN_KEYOUT6,	GPIO_FN_KEYIN6,
-	GPIO_FN_KEYOUT7,	GPIO_FN_KEYIN7,
-
-	/*
-	 * LCDC		(PORT      121, 122, 123, 124, 125, 126, 127, 128, 129,
-	 *		      130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
-	 *		      140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
-	 *		      150, 151)
-	 */
-	GPIO_FN_LCDC0_SELECT, /* LCDC 0 */
-	GPIO_FN_LCDC1_SELECT, /* LCDC 1 */
-	GPIO_FN_LCDHSYN,	GPIO_FN_LCDCS,	GPIO_FN_LCDVSYN,
-	GPIO_FN_LCDDCK,		GPIO_FN_LCDWR,	GPIO_FN_LCDRD,
-	GPIO_FN_LCDDISP,	GPIO_FN_LCDRS,	GPIO_FN_LCDLCLK,
-	GPIO_FN_LCDDON,
-
-	GPIO_FN_LCDD0,	GPIO_FN_LCDD1,	GPIO_FN_LCDD2,	GPIO_FN_LCDD3,
-	GPIO_FN_LCDD4,	GPIO_FN_LCDD5,	GPIO_FN_LCDD6,	GPIO_FN_LCDD7,
-	GPIO_FN_LCDD8,	GPIO_FN_LCDD9,	GPIO_FN_LCDD10,	GPIO_FN_LCDD11,
-	GPIO_FN_LCDD12,	GPIO_FN_LCDD13,	GPIO_FN_LCDD14,	GPIO_FN_LCDD15,
-	GPIO_FN_LCDD16,	GPIO_FN_LCDD17,	GPIO_FN_LCDD18,	GPIO_FN_LCDD19,
-	GPIO_FN_LCDD20,	GPIO_FN_LCDD21,	GPIO_FN_LCDD22,	GPIO_FN_LCDD23,
-
-	/* IRDA		(PORT 139, 140, 141, 142) */
-	GPIO_FN_IRDA_OUT,	GPIO_FN_IRDA_IN,	GPIO_FN_IRDA_FIRSEL,
-	GPIO_FN_IROUT_139,	GPIO_FN_IROUT_140,
-
-	/* TSIF1	(PORT 156, 157, 158, 159) */
-	GPIO_FN_TS0_1SELECT, /* TSIF0 - 1 select */
-	GPIO_FN_TS0_2SELECT, /* TSIF0 - 2 select */
-	GPIO_FN_TS1_1SELECT, /* TSIF1 - 1 select */
-	GPIO_FN_TS1_2SELECT, /* TSIF1 - 2 select */
-
-	GPIO_FN_TS_SPSYNC1,	GPIO_FN_TS_SDAT1,
-	GPIO_FN_TS_SDEN1,	GPIO_FN_TS_SCK1,
-
-	/* TSIF2	(PORT 137, 145, 146, 147) */
-	GPIO_FN_TS_SPSYNC2,	GPIO_FN_TS_SDAT2,
-	GPIO_FN_TS_SDEN2,	GPIO_FN_TS_SCK2,
-
-	/* HDMI		(PORT 169, 170) */
-	GPIO_FN_HDMI_HPD,	GPIO_FN_HDMI_CEC,
-
-	/* SDENC	see MSEL4CR 19 */
-	GPIO_FN_SDENC_CPG,
-	GPIO_FN_SDENC_DV_CLKI,
-};
-
 /* DMA slave IDs */
 enum {
 	SHDMA_SLAVE_INVALID,
@@ -466,6 +75,8 @@ extern void sh7372_intcs_resume(void);
 extern void sh7372_intca_suspend(void);
 extern void sh7372_intca_resume(void);
 
+extern unsigned long sh7372_cpu_resume;
+
 #ifdef CONFIG_PM
 extern void __init sh7372_init_pm_domains(void);
 #else
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/zboot.h linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/zboot.h
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/include/mach/zboot.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/include/mach/zboot.h	2013-08-25 20:43:22.000000000 -0400
@@ -10,11 +10,9 @@
  *
  **************************************************/
 
-#ifdef CONFIG_MACH_AP4EVB
-#define MACH_TYPE	MACH_TYPE_AP4EVB
-#include "mach/head-ap4evb.txt"
-#elif defined(CONFIG_MACH_MACKEREL)
+#ifdef CONFIG_MACH_MACKEREL
 #define MACH_TYPE	MACH_TYPE_MACKEREL
+#define MEMORY_START	0x40000000
 #include "mach/head-mackerel.txt"
 #else
 #error "unsupported board."
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/intc-r8a7740.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/intc-r8a7740.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/intc-r8a7740.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/intc-r8a7740.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,19 +20,15 @@
 
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irqchip.h>
 #include <linux/irqchip/arm-gic.h>
 
-void __init r8a7740_init_irq(void)
+static void __init r8a7740_init_irq_common(void)
 {
-	void __iomem *gic_dist_base = ioremap_nocache(0xc2800000, 0x1000);
-	void __iomem *gic_cpu_base = ioremap_nocache(0xc2000000, 0x1000);
 	void __iomem *intc_prio_base = ioremap_nocache(0xe6900010, 0x10);
 	void __iomem *intc_msk_base = ioremap_nocache(0xe6900040, 0x10);
 	void __iomem *pfc_inta_ctrl = ioremap_nocache(0xe605807c, 0x4);
 
-	/* initialize the Generic Interrupt Controller PL390 r0p0 */
-	gic_init(0, 29, gic_dist_base, gic_cpu_base);
-
 	/* route signals to GIC */
 	iowrite32(0x0, pfc_inta_ctrl);
 
@@ -54,3 +50,19 @@ void __init r8a7740_init_irq(void)
 	iounmap(intc_msk_base);
 	iounmap(pfc_inta_ctrl);
 }
+
+void __init r8a7740_init_irq_of(void)
+{
+	irqchip_init();
+	r8a7740_init_irq_common();
+}
+
+void __init r8a7740_init_irq(void)
+{
+	void __iomem *gic_dist_base = ioremap_nocache(0xc2800000, 0x1000);
+	void __iomem *gic_cpu_base = ioremap_nocache(0xc2000000, 0x1000);
+
+	/* initialize the Generic Interrupt Controller PL390 r0p0 */
+	gic_init(0, 29, gic_dist_base, gic_cpu_base);
+	r8a7740_init_irq_common();
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,7 @@ config ARCH_R8A73A4
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARM_GIC
 	select CPU_V7
-	select ARM_ARCH_TIMER
+	select HAVE_ARM_ARCH_TIMER
 	select SH_CLK_CPG
 	select RENESAS_IRQC
 
@@ -36,10 +36,13 @@ config ARCH_R8A7740
 	select RENESAS_INTC_IRQPIN
 
 config ARCH_R8A7778
-	bool "R-Car M1 (R8A77780)"
+	bool "R-Car M1A (R8A77781)"
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select CPU_V7
 	select SH_CLK_CPG
 	select ARM_GIC
+	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
 
 config ARCH_R8A7779
 	bool "R-Car H1 (R8A77790)"
@@ -56,7 +59,7 @@ config ARCH_R8A7790
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARM_GIC
 	select CPU_V7
-	select ARM_ARCH_TIMER
+	select HAVE_ARM_ARCH_TIMER
 	select SH_CLK_CPG
 	select RENESAS_IRQC
 
@@ -68,27 +71,6 @@ config ARCH_EMEV2
 
 comment "SH-Mobile Board Type"
 
-config MACH_AP4EVB
-	bool "AP4EVB board"
-	depends on ARCH_SH7372
-	select ARCH_REQUIRE_GPIOLIB
-	select REGULATOR_FIXED_VOLTAGE if REGULATOR
-	select SH_LCD_MIPI_DSI
-	select SND_SOC_AK4642 if SND_SIMPLE_CARD
-
-choice
-	prompt "AP4EVB LCD panel selection"
-	default AP4EVB_QHD
-	depends on MACH_AP4EVB
-
-config AP4EVB_QHD
-	bool "MIPI-DSI QHD (960x540)"
-
-config AP4EVB_WVGA
-	bool "Parallel WVGA (800x480)"
-
-endchoice
-
 config MACH_AG5EVM
 	bool "AG5EVM board"
 	depends on ARCH_SH73A0
@@ -115,19 +97,27 @@ config MACH_KOTA2
 	select ARCH_REQUIRE_GPIOLIB
 	select REGULATOR_FIXED_VOLTAGE if REGULATOR
 
-config MACH_BONITO
-	bool "bonito board"
+config MACH_ARMADILLO800EVA
+	bool "Armadillo-800 EVA board"
 	depends on ARCH_R8A7740
 	select ARCH_REQUIRE_GPIOLIB
 	select REGULATOR_FIXED_VOLTAGE if REGULATOR
+	select SND_SOC_WM8978 if SND_SIMPLE_CARD
+	select USE_OF
 
-config MACH_ARMADILLO800EVA
-	bool "Armadillo-800 EVA board"
+config MACH_ARMADILLO800EVA_REFERENCE
+	bool "Armadillo-800 EVA board - Reference Device Tree Implementation"
 	depends on ARCH_R8A7740
 	select ARCH_REQUIRE_GPIOLIB
 	select REGULATOR_FIXED_VOLTAGE if REGULATOR
 	select SND_SOC_WM8978 if SND_SIMPLE_CARD
 	select USE_OF
+	---help---
+	   Use reference implementation of Aramdillo800 EVA board support
+	   which makes a greater use of device tree at the expense
+	   of not supporting a number of devices.
+
+	   This is intended to aid developers
 
 config MACH_BOCKW
 	bool "BOCK-W platform"
@@ -169,6 +159,8 @@ config MACH_KZM9D
 config MACH_KZM9G
 	bool "KZM-A9-GT board"
 	depends on ARCH_SH73A0
+	select ARCH_HAS_CPUFREQ
+	select ARCH_HAS_OPP
 	select ARCH_REQUIRE_GPIOLIB
 	select REGULATOR_FIXED_VOLTAGE if REGULATOR
 	select SND_SOC_AK4642 if SND_SIMPLE_CARD
@@ -194,37 +186,6 @@ config CPU_HAS_INTEVT
         bool
 	default y
 
-menu "Memory configuration"
-
-config MEMORY_START
-	hex "Physical memory start address"
-	default "0x40000000" if MACH_AP4EVB || MACH_AG5EVM || \
-				MACH_MACKEREL || MACH_BONITO || \
-				MACH_ARMADILLO800EVA || MACH_APE6EVM || \
-				MACH_LAGER
-	default "0x41000000" if MACH_KOTA2
-	default "0x00000000"
-	---help---
-	  Tweak this only when porting to a new machine which does not
-	  already have a defconfig. Changing it from the known correct
-	  value on any of the known systems will only lead to disaster.
-
-config MEMORY_SIZE
-	hex "Physical memory size"
-	default "0x80000000" if MACH_LAGER
-	default "0x40000000" if MACH_APE6EVM
-	default "0x20000000" if MACH_AG5EVM || MACH_BONITO || \
-				MACH_ARMADILLO800EVA
-	default "0x1e000000" if MACH_KOTA2
-	default "0x10000000" if MACH_AP4EVB || MACH_MACKEREL
-	default "0x04000000"
-	help
-	  This sets the default memory size assumed by your kernel. It can
-	  be overridden as normal by the 'mem=' argument on the kernel command
-	  line.
-
-endmenu
-
 menu "Timer and clock configuration"
 
 config SHMOBILE_TIMER_HZ
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -35,17 +35,16 @@ obj-$(CONFIG_ARCH_R8A7779)	+= pm-r8a7779
 obj-$(CONFIG_ARCH_SH73A0)	+= pm-sh73a0.o
 
 # Board objects
-obj-$(CONFIG_MACH_AP4EVB)	+= board-ap4evb.o
 obj-$(CONFIG_MACH_AG5EVM)	+= board-ag5evm.o
 obj-$(CONFIG_MACH_APE6EVM)	+= board-ape6evm.o
 obj-$(CONFIG_MACH_MACKEREL)	+= board-mackerel.o
 obj-$(CONFIG_MACH_KOTA2)	+= board-kota2.o
-obj-$(CONFIG_MACH_BONITO)	+= board-bonito.o
 obj-$(CONFIG_MACH_BOCKW)	+= board-bockw.o
 obj-$(CONFIG_MACH_MARZEN)	+= board-marzen.o
 obj-$(CONFIG_MACH_MARZEN_REFERENCE)	+= board-marzen-reference.o
 obj-$(CONFIG_MACH_LAGER)	+= board-lager.o
 obj-$(CONFIG_MACH_ARMADILLO800EVA)	+= board-armadillo800eva.o
+obj-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE)	+= board-armadillo800eva-reference.o
 obj-$(CONFIG_MACH_KZM9D)	+= board-kzm9d.o
 obj-$(CONFIG_MACH_KZM9G)	+= board-kzm9g.o
 obj-$(CONFIG_MACH_KZM9G_REFERENCE)	+= board-kzm9g-reference.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/Makefile.boot linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/Makefile.boot
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/Makefile.boot	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/Makefile.boot	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,20 @@
-__ZRELADDR	:= $(shell /bin/bash -c 'printf "0x%08x" \
-		     $$[$(CONFIG_MEMORY_START) + 0x8000]')
+# per-board load address for uImage
+loadaddr-y	:=
+loadaddr-$(CONFIG_MACH_AG5EVM) += 0x40008000
+loadaddr-$(CONFIG_MACH_APE6EVM) += 0x40008000
+loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000
+loadaddr-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += 0x40008000
+loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000
+loadaddr-$(CONFIG_MACH_KOTA2) += 0x41008000
+loadaddr-$(CONFIG_MACH_KZM9D) += 0x40008000
+loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000
+loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000
+loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000
+loadaddr-$(CONFIG_MACH_MACKEREL) += 0x40008000
+loadaddr-$(CONFIG_MACH_MARZEN) += 0x60008000
+loadaddr-$(CONFIG_MACH_MARZEN_REFERENCE) += 0x60008000
 
+__ZRELADDR	:= $(sort $(loadaddr-y))
    zreladdr-y   += $(__ZRELADDR)
 
 # Unsupported legacy stuff
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/pm-sh7372.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/pm-sh7372.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/pm-sh7372.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/pm-sh7372.c	2013-08-25 20:43:22.000000000 -0400
@@ -351,6 +351,9 @@ static void sh7372_enter_a4s_common(int
 
 static void sh7372_pm_setup_smfram(void)
 {
+	/* pass physical address of cpu_resume() to assembly resume code */
+	sh7372_cpu_resume = virt_to_phys(cpu_resume);
+
 	memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
 }
 #else
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-emev2.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-emev2.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-emev2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-emev2.c	2013-08-25 20:43:22.000000000 -0400
@@ -287,14 +287,14 @@ static struct gpio_em_config gio3_config
 static struct resource gio3_resources[] = {
 	[0] = {
 		.name	= "GIO_096",
-		.start	= 0xe0050100,
-		.end	= 0xe005012b,
+		.start	= 0xe0050180,
+		.end	= 0xe00501ab,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
 		.name	= "GIO_096",
-		.start	= 0xe0050140,
-		.end	= 0xe005015f,
+		.start	= 0xe00501c0,
+		.end	= 0xe00501df,
 		.flags	= IORESOURCE_MEM,
 	},
 	[2] = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a73a4.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a73a4.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a73a4.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a73a4.c	2013-08-25 20:43:22.000000000 -0400
@@ -62,7 +62,7 @@ enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, S
 static const struct plat_sci_port scif[] = {
 	SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */
 	SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */
-	SCIFB_DATA(SCIFB0, 0xe6c50000, gic_spi(145)), /* SCIFB0 */
+	SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */
 	SCIFB_DATA(SCIFB1, 0xe6c30000, gic_spi(149)), /* SCIFB1 */
 	SCIFB_DATA(SCIFB2, 0xe6ce0000, gic_spi(150)), /* SCIFB2 */
 	SCIFB_DATA(SCIFB3, 0xe6cf0000, gic_spi(151)), /* SCIFB3 */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a7740.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a7740.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a7740.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a7740.c	2013-08-25 20:43:22.000000000 -0400
@@ -70,29 +70,15 @@ void __init r8a7740_map_io(void)
 }
 
 /* PFC */
-static struct resource r8a7740_pfc_resources[] = {
-	[0] = {
-		.start	= 0xe6050000,
-		.end	= 0xe6057fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 0xe605800c,
-		.end	= 0xe605802b,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct platform_device r8a7740_pfc_device = {
-	.name		= "pfc-r8a7740",
-	.id		= -1,
-	.resource	= r8a7740_pfc_resources,
-	.num_resources	= ARRAY_SIZE(r8a7740_pfc_resources),
+static const struct resource pfc_resources[] = {
+	DEFINE_RES_MEM(0xe6050000, 0x8000),
+	DEFINE_RES_MEM(0xe605800c, 0x0020),
 };
 
 void __init r8a7740_pinmux_init(void)
 {
-	platform_device_register(&r8a7740_pfc_device);
+	platform_device_register_simple("pfc-r8a7740", -1, pfc_resources,
+					ARRAY_SIZE(pfc_resources));
 }
 
 static struct renesas_intc_irqpin_config irqpin0_platform_data = {
@@ -531,11 +517,7 @@ static struct platform_device ipmmu_devi
 	.num_resources  = ARRAY_SIZE(ipmmu_resources),
 };
 
-static struct platform_device *r8a7740_early_devices[] __initdata = {
-	&irqpin0_device,
-	&irqpin1_device,
-	&irqpin2_device,
-	&irqpin3_device,
+static struct platform_device *r8a7740_devices_dt[] __initdata = {
 	&scif0_device,
 	&scif1_device,
 	&scif2_device,
@@ -546,6 +528,13 @@ static struct platform_device *r8a7740_e
 	&scif7_device,
 	&scifb_device,
 	&cmt10_device,
+};
+
+static struct platform_device *r8a7740_early_devices[] __initdata = {
+	&irqpin0_device,
+	&irqpin1_device,
+	&irqpin2_device,
+	&irqpin3_device,
 	&tmu00_device,
 	&tmu01_device,
 	&tmu02_device,
@@ -965,6 +954,8 @@ void __init r8a7740_add_standard_devices
 	/* add devices */
 	platform_add_devices(r8a7740_early_devices,
 			    ARRAY_SIZE(r8a7740_early_devices));
+	platform_add_devices(r8a7740_devices_dt,
+			    ARRAY_SIZE(r8a7740_devices_dt));
 	platform_add_devices(r8a7740_late_devices,
 			     ARRAY_SIZE(r8a7740_late_devices));
 
@@ -986,6 +977,8 @@ void __init r8a7740_add_early_devices(vo
 {
 	early_platform_add_devices(r8a7740_early_devices,
 				   ARRAY_SIZE(r8a7740_early_devices));
+	early_platform_add_devices(r8a7740_devices_dt,
+				   ARRAY_SIZE(r8a7740_devices_dt));
 
 	/* setup early console here as well */
 	shmobile_setup_console();
@@ -993,33 +986,29 @@ void __init r8a7740_add_early_devices(vo
 
 #ifdef CONFIG_USE_OF
 
-void __init r8a7740_add_early_devices_dt(void)
-{
-	shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */
-
-	early_platform_add_devices(r8a7740_early_devices,
-				   ARRAY_SIZE(r8a7740_early_devices));
-
-	/* setup early console here as well */
-	shmobile_setup_console();
-}
-
 static const struct of_dev_auxdata r8a7740_auxdata_lookup[] __initconst = {
 	{ }
 };
 
 void __init r8a7740_add_standard_devices_dt(void)
 {
-	/* clocks are setup late during boot in the case of DT */
-	r8a7740_clock_init(0);
-
-	platform_add_devices(r8a7740_early_devices,
-			    ARRAY_SIZE(r8a7740_early_devices));
-
+	platform_add_devices(r8a7740_devices_dt,
+			    ARRAY_SIZE(r8a7740_devices_dt));
 	of_platform_populate(NULL, of_default_bus_match_table,
 			     r8a7740_auxdata_lookup, NULL);
 }
 
+void __init r8a7740_init_delay(void)
+{
+	shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */
+};
+
+static void __init r8a7740_generic_init(void)
+{
+	r8a7740_clock_init(0);
+	r8a7740_add_standard_devices_dt();
+}
+
 static const char *r8a7740_boards_compat_dt[] __initdata = {
 	"renesas,r8a7740",
 	NULL,
@@ -1027,9 +1016,10 @@ static const char *r8a7740_boards_compat
 
 DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)")
 	.map_io		= r8a7740_map_io,
-	.init_early	= r8a7740_add_early_devices_dt,
-	.init_irq	= r8a7740_init_irq,
-	.init_machine	= r8a7740_add_standard_devices_dt,
+	.init_early	= r8a7740_init_delay,
+	.init_irq	= r8a7740_init_irq_of,
+	.init_machine	= r8a7740_generic_init,
+	.init_time	= shmobile_timer_init,
 	.dt_compat	= r8a7740_boards_compat_dt,
 MACHINE_END
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a7778.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a7778.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a7778.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a7778.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,11 +24,18 @@
 #include <linux/irqchip/arm-gic.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/irq-renesas-intc-irqpin.h>
 #include <linux/platform_device.h>
 #include <linux/irqchip.h>
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
+#include <linux/pm_runtime.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+#include <linux/dma-mapping.h>
 #include <mach/irqs.h>
 #include <mach/r8a7778.h>
 #include <mach/common.h>
@@ -80,12 +87,6 @@ static struct sh_timer_config sh_tmu1_pl
 	.clocksource_rating	= 200,
 };
 
-/* Ether */
-static struct resource ether_resources[] = {
-	DEFINE_RES_MEM(0xfde00000, 0x400),
-	DEFINE_RES_IRQ(gic_iid(0x89)),
-};
-
 #define r8a7778_register_tmu(idx)			\
 	platform_device_register_resndata(		\
 		&platform_bus, "sh_tmu", idx,		\
@@ -94,6 +95,244 @@ static struct resource ether_resources[]
 		&sh_tmu##idx##_platform_data,		\
 		sizeof(sh_tmu##idx##_platform_data))
 
+/* USB PHY */
+static struct resource usb_phy_resources[] __initdata = {
+	DEFINE_RES_MEM(0xffe70800, 0x100),
+	DEFINE_RES_MEM(0xffe76000, 0x100),
+};
+
+void __init r8a7778_add_usb_phy_device(struct rcar_phy_platform_data *pdata)
+{
+	platform_device_register_resndata(&platform_bus, "rcar_usb_phy", -1,
+					  usb_phy_resources,
+					  ARRAY_SIZE(usb_phy_resources),
+					  pdata, sizeof(*pdata));
+}
+
+/* USB */
+static struct usb_phy *phy;
+
+static int usb_power_on(struct platform_device *pdev)
+{
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
+
+	usb_phy_init(phy);
+
+	return 0;
+}
+
+static void usb_power_off(struct platform_device *pdev)
+{
+	if (IS_ERR(phy))
+		return;
+
+	usb_phy_shutdown(phy);
+
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+}
+
+static int ehci_init_internal_buffer(struct usb_hcd *hcd)
+{
+	/*
+	 * Below are recommended values from the datasheet;
+	 * see [USB :: Setting of EHCI Internal Buffer].
+	 */
+	/* EHCI IP internal buffer setting */
+	iowrite32(0x00ff0040, hcd->regs + 0x0094);
+	/* EHCI IP internal buffer enable */
+	iowrite32(0x00000001, hcd->regs + 0x009C);
+
+	return 0;
+}
+
+static struct usb_ehci_pdata ehci_pdata __initdata = {
+	.power_on	= usb_power_on,
+	.power_off	= usb_power_off,
+	.power_suspend	= usb_power_off,
+	.pre_setup	= ehci_init_internal_buffer,
+};
+
+static struct resource ehci_resources[] __initdata = {
+	DEFINE_RES_MEM(0xffe70000, 0x400),
+	DEFINE_RES_IRQ(gic_iid(0x4c)),
+};
+
+static struct usb_ohci_pdata ohci_pdata __initdata = {
+	.power_on	= usb_power_on,
+	.power_off	= usb_power_off,
+	.power_suspend	= usb_power_off,
+};
+
+static struct resource ohci_resources[] __initdata = {
+	DEFINE_RES_MEM(0xffe70400, 0x400),
+	DEFINE_RES_IRQ(gic_iid(0x4c)),
+};
+
+#define USB_PLATFORM_INFO(hci)					\
+static struct platform_device_info hci##_info __initdata = {	\
+	.parent		= &platform_bus,			\
+	.name		= #hci "-platform",			\
+	.id		= -1,					\
+	.res		= hci##_resources,			\
+	.num_res	= ARRAY_SIZE(hci##_resources),		\
+	.data		= &hci##_pdata,				\
+	.size_data	= sizeof(hci##_pdata),			\
+	.dma_mask	= DMA_BIT_MASK(32),			\
+}
+
+USB_PLATFORM_INFO(ehci);
+USB_PLATFORM_INFO(ohci);
+
+/* Ether */
+static struct resource ether_resources[] = {
+	DEFINE_RES_MEM(0xfde00000, 0x400),
+	DEFINE_RES_IRQ(gic_iid(0x89)),
+};
+
+void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata)
+{
+	platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1,
+					  ether_resources,
+					  ARRAY_SIZE(ether_resources),
+					  pdata, sizeof(*pdata));
+}
+
+/* PFC/GPIO */
+static struct resource pfc_resources[] = {
+	DEFINE_RES_MEM(0xfffc0000, 0x118),
+};
+
+#define R8A7778_GPIO(idx)						\
+static struct resource r8a7778_gpio##idx##_resources[] = {		\
+	DEFINE_RES_MEM(0xffc40000 + 0x1000 * (idx), 0x30),		\
+	DEFINE_RES_IRQ(gic_iid(0x87)),					\
+};									\
+									\
+static struct gpio_rcar_config r8a7778_gpio##idx##_platform_data = {	\
+	.gpio_base	= 32 * (idx),					\
+	.irq_base	= GPIO_IRQ_BASE(idx),				\
+	.number_of_pins	= 32,						\
+	.pctl_name	= "pfc-r8a7778",				\
+}
+
+R8A7778_GPIO(0);
+R8A7778_GPIO(1);
+R8A7778_GPIO(2);
+R8A7778_GPIO(3);
+R8A7778_GPIO(4);
+
+#define r8a7778_register_gpio(idx)				\
+	platform_device_register_resndata(			\
+		&platform_bus, "gpio_rcar", idx,		\
+		r8a7778_gpio##idx##_resources,			\
+		ARRAY_SIZE(r8a7778_gpio##idx##_resources),	\
+		&r8a7778_gpio##idx##_platform_data,		\
+		sizeof(r8a7778_gpio##idx##_platform_data))
+
+void __init r8a7778_pinmux_init(void)
+{
+	platform_device_register_simple(
+		"pfc-r8a7778", -1,
+		pfc_resources,
+		ARRAY_SIZE(pfc_resources));
+
+	r8a7778_register_gpio(0);
+	r8a7778_register_gpio(1);
+	r8a7778_register_gpio(2);
+	r8a7778_register_gpio(3);
+	r8a7778_register_gpio(4);
+};
+
+/* SDHI */
+static struct resource sdhi_resources[] = {
+	/* SDHI0 */
+	DEFINE_RES_MEM(0xFFE4C000, 0x100),
+	DEFINE_RES_IRQ(gic_iid(0x77)),
+	/* SDHI1 */
+	DEFINE_RES_MEM(0xFFE4D000, 0x100),
+	DEFINE_RES_IRQ(gic_iid(0x78)),
+	/* SDHI2 */
+	DEFINE_RES_MEM(0xFFE4F000, 0x100),
+	DEFINE_RES_IRQ(gic_iid(0x76)),
+};
+
+void __init r8a7778_sdhi_init(int id,
+			      struct sh_mobile_sdhi_info *info)
+{
+	BUG_ON(id < 0 || id > 2);
+
+	platform_device_register_resndata(
+		&platform_bus, "sh_mobile_sdhi", id,
+		sdhi_resources + (2 * id), 2,
+		info, sizeof(*info));
+}
+
+/* I2C */
+static struct resource i2c_resources[] __initdata = {
+	/* I2C0 */
+	DEFINE_RES_MEM(0xffc70000, 0x1000),
+	DEFINE_RES_IRQ(gic_iid(0x63)),
+	/* I2C1 */
+	DEFINE_RES_MEM(0xffc71000, 0x1000),
+	DEFINE_RES_IRQ(gic_iid(0x6e)),
+	/* I2C2 */
+	DEFINE_RES_MEM(0xffc72000, 0x1000),
+	DEFINE_RES_IRQ(gic_iid(0x6c)),
+	/* I2C3 */
+	DEFINE_RES_MEM(0xffc73000, 0x1000),
+	DEFINE_RES_IRQ(gic_iid(0x6d)),
+};
+
+void __init r8a7778_add_i2c_device(int id)
+{
+	BUG_ON(id < 0 || id > 3);
+
+	platform_device_register_simple(
+		"i2c-rcar", id,
+		i2c_resources + (2 * id), 2);
+}
+
+/* HSPI */
+static struct resource hspi_resources[] __initdata = {
+	/* HSPI0 */
+	DEFINE_RES_MEM(0xfffc7000, 0x18),
+	DEFINE_RES_IRQ(gic_iid(0x5f)),
+	/* HSPI1 */
+	DEFINE_RES_MEM(0xfffc8000, 0x18),
+	DEFINE_RES_IRQ(gic_iid(0x74)),
+	/* HSPI2 */
+	DEFINE_RES_MEM(0xfffc6000, 0x18),
+	DEFINE_RES_IRQ(gic_iid(0x75)),
+};
+
+void __init r8a7778_add_hspi_device(int id)
+{
+	BUG_ON(id < 0 || id > 2);
+
+	platform_device_register_simple(
+		"sh-hspi", id,
+		hspi_resources + (2 * id), 2);
+}
+
+/* MMC */
+static struct resource mmc_resources[] __initdata = {
+	DEFINE_RES_MEM(0xffe4e000, 0x100),
+	DEFINE_RES_IRQ(gic_iid(0x5d)),
+};
+
+void __init r8a7778_add_mmc_device(struct sh_mmcif_plat_data *info)
+{
+	platform_device_register_resndata(
+		&platform_bus, "sh_mmcif", -1,
+		mmc_resources, ARRAY_SIZE(mmc_resources),
+		info, sizeof(*info));
+}
+
 void __init r8a7778_add_standard_devices(void)
 {
 	int i;
@@ -118,12 +357,12 @@ void __init r8a7778_add_standard_devices
 	r8a7778_register_tmu(1);
 }
 
-void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata)
+void __init r8a7778_init_late(void)
 {
-	platform_device_register_resndata(&platform_bus, "sh_eth", -1,
-					  ether_resources,
-					  ARRAY_SIZE(ether_resources),
-					  pdata, sizeof(*pdata));
+	phy = usb_get_phy(USB_PHY_TYPE_USB2);
+
+	platform_device_register_full(&ehci_info);
+	platform_device_register_full(&ohci_info);
 }
 
 static struct renesas_intc_irqpin_config irqpin_platform_data = {
@@ -239,6 +478,7 @@ DT_MACHINE_START(R8A7778_DT, "Generic R8
 	.init_machine	= r8a7778_add_standard_devices_dt,
 	.init_time	= shmobile_timer_init,
 	.dt_compat	= r8a7778_compat_dt,
+	.init_late      = r8a7778_init_late,
 MACHINE_END
 
 #endif /* CONFIG_USE_OF */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a7779.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a7779.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a7779.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a7779.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,11 @@
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
 #include <linux/dma-mapping.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/hcd.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+#include <linux/pm_runtime.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 #include <mach/r8a7779.h>
@@ -65,11 +70,7 @@ void __init r8a7779_map_io(void)
 }
 
 static struct resource r8a7779_pfc_resources[] = {
-	[0] = {
-		.start	= 0xfffc0000,
-		.end	= 0xfffc023b,
-		.flags	= IORESOURCE_MEM,
-	},
+	DEFINE_RES_MEM(0xfffc0000, 0x023c),
 };
 
 static struct platform_device r8a7779_pfc_device = {
@@ -81,15 +82,8 @@ static struct platform_device r8a7779_pf
 
 #define R8A7779_GPIO(idx, npins) \
 static struct resource r8a7779_gpio##idx##_resources[] = {		\
-	[0] = {								\
-		.start	= 0xffc40000 + 0x1000 * (idx),			\
-		.end	= 0xffc4002b + 0x1000 * (idx),			\
-		.flags	= IORESOURCE_MEM,				\
-	},								\
-	[1] = {								\
-		.start	= gic_iid(0xad + (idx)),			\
-		.flags	= IORESOURCE_IRQ,				\
-	}								\
+	DEFINE_RES_MEM(0xffc40000 + (0x1000 * (idx)), 0x002c),		\
+	DEFINE_RES_IRQ(gic_iid(0xad + (idx))),				\
 };									\
 									\
 static struct gpio_rcar_config r8a7779_gpio##idx##_platform_data = {	\
@@ -394,6 +388,165 @@ static struct platform_device sata_devic
 	},
 };
 
+/* USB PHY */
+static struct resource usb_phy_resources[] __initdata = {
+	[0] = {
+		.start		= 0xffe70800,
+		.end		= 0xffe70900 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+/* USB */
+static struct usb_phy *phy;
+
+static int usb_power_on(struct platform_device *pdev)
+{
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
+
+	usb_phy_init(phy);
+
+	return 0;
+}
+
+static void usb_power_off(struct platform_device *pdev)
+{
+	if (IS_ERR(phy))
+		return;
+
+	usb_phy_shutdown(phy);
+
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+}
+
+static int ehci_init_internal_buffer(struct usb_hcd *hcd)
+{
+	/*
+	 * Below are recommended values from the datasheet;
+	 * see [USB :: Setting of EHCI Internal Buffer].
+	 */
+	/* EHCI IP internal buffer setting */
+	iowrite32(0x00ff0040, hcd->regs + 0x0094);
+	/* EHCI IP internal buffer enable */
+	iowrite32(0x00000001, hcd->regs + 0x009C);
+
+	return 0;
+}
+
+static struct usb_ehci_pdata ehcix_pdata = {
+	.power_on	= usb_power_on,
+	.power_off	= usb_power_off,
+	.power_suspend	= usb_power_off,
+	.pre_setup	= ehci_init_internal_buffer,
+};
+
+static struct resource ehci0_resources[] = {
+	[0] = {
+		.start	= 0xffe70000,
+		.end	= 0xffe70400 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_iid(0x4c),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ehci0_device = {
+	.name	= "ehci-platform",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ehci0_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &ehcix_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(ehci0_resources),
+	.resource	= ehci0_resources,
+};
+
+static struct resource ehci1_resources[] = {
+	[0] = {
+		.start	= 0xfff70000,
+		.end	= 0xfff70400 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_iid(0x4d),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ehci1_device = {
+	.name	= "ehci-platform",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ehci1_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &ehcix_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(ehci1_resources),
+	.resource	= ehci1_resources,
+};
+
+static struct usb_ohci_pdata ohcix_pdata = {
+	.power_on	= usb_power_on,
+	.power_off	= usb_power_off,
+	.power_suspend	= usb_power_off,
+};
+
+static struct resource ohci0_resources[] = {
+	[0] = {
+		.start	= 0xffe70400,
+		.end	= 0xffe70800 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_iid(0x4c),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ohci0_device = {
+	.name	= "ohci-platform",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ohci0_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &ohcix_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(ohci0_resources),
+	.resource	= ohci0_resources,
+};
+
+static struct resource ohci1_resources[] = {
+	[0] = {
+		.start	= 0xfff70400,
+		.end	= 0xfff70800 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_iid(0x4d),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ohci1_device = {
+	.name	= "ohci-platform",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ohci1_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &ohcix_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(ohci1_resources),
+	.resource	= ohci1_resources,
+};
+
 /* Ether */
 static struct resource ether_resources[] = {
 	{
@@ -417,7 +570,7 @@ static struct platform_device *r8a7779_d
 	&tmu01_device,
 };
 
-static struct platform_device *r8a7779_late_devices[] __initdata = {
+static struct platform_device *r8a7779_standard_devices[] __initdata = {
 	&i2c0_device,
 	&i2c1_device,
 	&i2c2_device,
@@ -437,18 +590,26 @@ void __init r8a7779_add_standard_devices
 
 	platform_add_devices(r8a7779_devices_dt,
 			    ARRAY_SIZE(r8a7779_devices_dt));
-	platform_add_devices(r8a7779_late_devices,
-			    ARRAY_SIZE(r8a7779_late_devices));
+	platform_add_devices(r8a7779_standard_devices,
+			    ARRAY_SIZE(r8a7779_standard_devices));
 }
 
 void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata)
 {
-	platform_device_register_resndata(&platform_bus, "sh_eth", -1,
+	platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1,
 					  ether_resources,
 					  ARRAY_SIZE(ether_resources),
 					  pdata, sizeof(*pdata));
 }
 
+void __init r8a7779_add_usb_phy_device(struct rcar_phy_platform_data *pdata)
+{
+	platform_device_register_resndata(&platform_bus, "rcar_usb_phy", -1,
+					  usb_phy_resources,
+					  ARRAY_SIZE(usb_phy_resources),
+					  pdata, sizeof(*pdata));
+}
+
 /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
 void __init __weak r8a7779_register_twd(void) { }
 
@@ -481,6 +642,23 @@ void __init r8a7779_add_early_devices(vo
 	 */
 }
 
+static struct platform_device *r8a7779_late_devices[] __initdata = {
+	&ehci0_device,
+	&ehci1_device,
+	&ohci0_device,
+	&ohci1_device,
+};
+
+void __init r8a7779_init_late(void)
+{
+	/* get USB PHY */
+	phy = usb_get_phy(USB_PHY_TYPE_USB2);
+
+	shmobile_init_late();
+	platform_add_devices(r8a7779_late_devices,
+			     ARRAY_SIZE(r8a7779_late_devices));
+}
+
 #ifdef CONFIG_USE_OF
 void __init r8a7779_init_delay(void)
 {
@@ -514,6 +692,7 @@ DT_MACHINE_START(R8A7779_DT, "Generic R8
 	.init_irq	= r8a7779_init_irq_dt,
 	.init_machine	= r8a7779_add_standard_devices_dt,
 	.init_time	= shmobile_timer_init,
+	.init_late	= r8a7779_init_late,
 	.dt_compat	= r8a7779_compat_dt,
 MACHINE_END
 #endif /* CONFIG_USE_OF */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a7790.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a7790.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-r8a7790.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-r8a7790.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,21 +23,55 @@
 #include <linux/kernel.h>
 #include <linux/of_platform.h>
 #include <linux/serial_sci.h>
+#include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/irq-renesas-irqc.h>
 #include <mach/common.h>
 #include <mach/irqs.h>
 #include <mach/r8a7790.h>
 #include <asm/mach/arch.h>
 
-static const struct resource pfc_resources[] = {
+static struct resource pfc_resources[] __initdata = {
 	DEFINE_RES_MEM(0xe6060000, 0x250),
-	DEFINE_RES_MEM(0xe6050000, 0x5050),
 };
 
+#define R8A7790_GPIO(idx)						\
+static struct resource r8a7790_gpio##idx##_resources[] __initdata = {	\
+	DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50),		\
+	DEFINE_RES_IRQ(gic_spi(4 + (idx))),				\
+};									\
+									\
+static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data __initdata = {	\
+	.gpio_base	= 32 * (idx),					\
+	.irq_base	= 0,						\
+	.number_of_pins	= 32,						\
+	.pctl_name	= "pfc-r8a7790",				\
+	.has_both_edge_trigger = 1,					\
+};									\
+
+R8A7790_GPIO(0);
+R8A7790_GPIO(1);
+R8A7790_GPIO(2);
+R8A7790_GPIO(3);
+R8A7790_GPIO(4);
+R8A7790_GPIO(5);
+
+#define r8a7790_register_gpio(idx)					\
+	platform_device_register_resndata(&platform_bus, "gpio_rcar", idx, \
+		r8a7790_gpio##idx##_resources,				\
+		ARRAY_SIZE(r8a7790_gpio##idx##_resources),		\
+		&r8a7790_gpio##idx##_platform_data,			\
+		sizeof(r8a7790_gpio##idx##_platform_data))
+
 void __init r8a7790_pinmux_init(void)
 {
 	platform_device_register_simple("pfc-r8a7790", -1, pfc_resources,
 					ARRAY_SIZE(pfc_resources));
+	r8a7790_register_gpio(0);
+	r8a7790_register_gpio(1);
+	r8a7790_register_gpio(2);
+	r8a7790_register_gpio(3);
+	r8a7790_register_gpio(4);
+	r8a7790_register_gpio(5);
 }
 
 #define SCIF_COMMON(scif_type, baseaddr, irq)			\
@@ -64,12 +98,20 @@ void __init r8a7790_pinmux_init(void)
 [index] = {						\
 	SCIF_COMMON(PORT_SCIF, baseaddr, irq),		\
 	.scbrr_algo_id	= SCBRR_ALGO_2,			\
-	.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,	\
+	.scscr = SCSCR_RE | SCSCR_TE,	\
 }
 
-enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1 };
+#define HSCIF_DATA(index, baseaddr, irq)		\
+[index] = {						\
+	SCIF_COMMON(PORT_HSCIF, baseaddr, irq),		\
+	.scbrr_algo_id	= SCBRR_ALGO_6,			\
+	.scscr = SCSCR_RE | SCSCR_TE,	\
+}
 
-static const struct plat_sci_port scif[] = {
+enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1,
+       HSCIF0, HSCIF1 };
+
+static struct plat_sci_port scif[] __initdata = {
 	SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */
 	SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */
 	SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */
@@ -78,6 +120,8 @@ static const struct plat_sci_port scif[]
 	SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */
 	SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */
 	SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */
+	HSCIF_DATA(HSCIF0, 0xe62c0000, gic_spi(154)), /* HSCIF0 */
+	HSCIF_DATA(HSCIF1, 0xe62c8000, gic_spi(155)), /* HSCIF1 */
 };
 
 static inline void r8a7790_register_scif(int idx)
@@ -86,11 +130,11 @@ static inline void r8a7790_register_scif
 				      sizeof(struct plat_sci_port));
 }
 
-static struct renesas_irqc_config irqc0_data = {
+static struct renesas_irqc_config irqc0_data __initdata = {
 	.irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
 };
 
-static struct resource irqc0_resources[] = {
+static struct resource irqc0_resources[] __initdata = {
 	DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */
 	DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */
 	DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */
@@ -115,6 +159,8 @@ void __init r8a7790_add_standard_devices
 	r8a7790_register_scif(SCIFA2);
 	r8a7790_register_scif(SCIF0);
 	r8a7790_register_scif(SCIF1);
+	r8a7790_register_scif(HSCIF0);
+	r8a7790_register_scif(HSCIF1);
 	r8a7790_register_irqc(0);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-sh73a0.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-sh73a0.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/setup-sh73a0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/setup-sh73a0.c	2013-08-25 20:43:22.000000000 -0400
@@ -288,12 +288,7 @@ static struct sh_timer_config tmu00_plat
 };
 
 static struct resource tmu00_resources[] = {
-	[0] = {
-		.name	= "TMU00",
-		.start	= 0xfff60008,
-		.end	= 0xfff60013,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM_NAMED(0xfff60008, 0xc, "TMU00"),
 	[1] = {
 		.start	= intcs_evt2irq(0x0e80), /* TMU0_TUNI00 */
 		.flags	= IORESOURCE_IRQ,
@@ -318,12 +313,7 @@ static struct sh_timer_config tmu01_plat
 };
 
 static struct resource tmu01_resources[] = {
-	[0] = {
-		.name	= "TMU01",
-		.start	= 0xfff60014,
-		.end	= 0xfff6001f,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM_NAMED(0xfff60014, 0xc, "TMU00"),
 	[1] = {
 		.start	= intcs_evt2irq(0x0ea0), /* TMU0_TUNI01 */
 		.flags	= IORESOURCE_IRQ,
@@ -341,12 +331,7 @@ static struct platform_device tmu01_devi
 };
 
 static struct resource i2c0_resources[] = {
-	[0] = {
-		.name	= "IIC0",
-		.start	= 0xe6820000,
-		.end	= 0xe6820425 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM_NAMED(0xe6820000, 0x426, "IIC0"),
 	[1] = {
 		.start	= gic_spi(167),
 		.end	= gic_spi(170),
@@ -355,12 +340,7 @@ static struct resource i2c0_resources[]
 };
 
 static struct resource i2c1_resources[] = {
-	[0] = {
-		.name	= "IIC1",
-		.start	= 0xe6822000,
-		.end	= 0xe6822425 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM_NAMED(0xe6822000, 0x426, "IIC1"),
 	[1] = {
 		.start	= gic_spi(51),
 		.end	= gic_spi(54),
@@ -369,12 +349,7 @@ static struct resource i2c1_resources[]
 };
 
 static struct resource i2c2_resources[] = {
-	[0] = {
-		.name	= "IIC2",
-		.start	= 0xe6824000,
-		.end	= 0xe6824425 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM_NAMED(0xe6824000, 0x426, "IIC2"),
 	[1] = {
 		.start	= gic_spi(171),
 		.end	= gic_spi(174),
@@ -383,12 +358,7 @@ static struct resource i2c2_resources[]
 };
 
 static struct resource i2c3_resources[] = {
-	[0] = {
-		.name	= "IIC3",
-		.start	= 0xe6826000,
-		.end	= 0xe6826425 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM_NAMED(0xe6826000, 0x426, "IIC3"),
 	[1] = {
 		.start	= gic_spi(183),
 		.end	= gic_spi(186),
@@ -397,12 +367,7 @@ static struct resource i2c3_resources[]
 };
 
 static struct resource i2c4_resources[] = {
-	[0] = {
-		.name	= "IIC4",
-		.start	= 0xe6828000,
-		.end	= 0xe6828425 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM_NAMED(0xe6828000, 0x426, "IIC4"),
 	[1] = {
 		.start	= gic_spi(187),
 		.end	= gic_spi(190),
@@ -623,12 +588,7 @@ static struct sh_dmae_pdata sh73a0_dmae_
 };
 
 static struct resource sh73a0_dmae_resources[] = {
-	{
-		/* Registers including DMAOR and channels including DMARSx */
-		.start  = 0xfe000020,
-		.end    = 0xfe008a00 - 1,
-		.flags  = IORESOURCE_MEM,
-	},
+	DEFINE_RES_MEM(0xfe000020, 0x89e0),
 	{
 		.name	= "error_irq",
 		.start  = gic_spi(129),
@@ -727,18 +687,10 @@ static struct sh_dmae_pdata sh73a0_mpdma
 
 /* Resource order important! */
 static struct resource sh73a0_mpdma_resources[] = {
-	{
-		/* Channel registers and DMAOR */
-		.start	= 0xec618020,
-		.end	= 0xec61828f,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		/* DMARSx */
-		.start	= 0xec619000,
-		.end	= 0xec61900b,
-		.flags	= IORESOURCE_MEM,
-	},
+	/* Channel registers and DMAOR */
+	DEFINE_RES_MEM(0xec618020, 0x270),
+	/* DMARSx */
+	DEFINE_RES_MEM(0xec619000, 0xc),
 	{
 		.name	= "error_irq",
 		.start	= gic_spi(181),
@@ -785,12 +737,7 @@ static struct platform_device pmu_device
 
 /* an IPMMU module for ICB */
 static struct resource ipmmu_resources[] = {
-	[0] = {
-		.name	= "IPMMU",
-		.start	= 0xfe951000,
-		.end	= 0xfe9510ff,
-		.flags	= IORESOURCE_MEM,
-	},
+	DEFINE_RES_MEM_NAMED(0xfe951000, 0x100, "IPMMU"),
 };
 
 static const char * const ipmmu_dev_names[] = {
@@ -982,11 +929,17 @@ void __init sh73a0_add_standard_devices(
 			    ARRAY_SIZE(sh73a0_late_devices));
 }
 
+void __init sh73a0_init_delay(void)
+{
+	shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */
+}
+
 /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
 void __init __weak sh73a0_register_twd(void) { }
 
 void __init sh73a0_earlytimer_init(void)
 {
+	sh73a0_init_delay();
 	sh73a0_clock_init();
 	shmobile_earlytimer_init();
 	sh73a0_register_twd();
@@ -1005,17 +958,14 @@ void __init sh73a0_add_early_devices(voi
 
 #ifdef CONFIG_USE_OF
 
-void __init sh73a0_init_delay(void)
-{
-	shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */
-}
-
 static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = {
 	{},
 };
 
 void __init sh73a0_add_standard_devices_dt(void)
 {
+	struct platform_device_info devinfo = { .name = "cpufreq-cpu0", .id = -1, };
+
 	/* clocks are setup late during boot in the case of DT */
 	sh73a0_clock_init();
 
@@ -1023,6 +973,9 @@ void __init sh73a0_add_standard_devices_
 			     ARRAY_SIZE(sh73a0_devices_dt));
 	of_platform_populate(NULL, of_default_bus_match_table,
 			     sh73a0_auxdata_lookup, NULL);
+
+	/* Instantiate cpufreq-cpu0 */
+	platform_device_register_full(&devinfo);
 }
 
 static const char *sh73a0_boards_compat_dt[] __initdata = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/sleep-sh7372.S linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/sleep-sh7372.S
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/sleep-sh7372.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/sleep-sh7372.S	2013-08-25 20:43:22.000000000 -0400
@@ -40,7 +40,10 @@
 	.global sh7372_resume_core_standby_sysc
 sh7372_resume_core_standby_sysc:
 	ldr     pc, 1f
-1:	.long   cpu_resume - PAGE_OFFSET + PLAT_PHYS_OFFSET
+
+	.globl	sh7372_cpu_resume
+sh7372_cpu_resume:
+1:	.space	4
 
 #define SPDCR 0xe6180008
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/smp-emev2.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/smp-emev2.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/smp-emev2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/smp-emev2.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,7 @@
 
 #define EMEV2_SCU_BASE 0x1e000000
 
-static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu)));
 	return 0;
@@ -40,8 +40,10 @@ static void __init emev2_smp_prepare_cpu
 {
 	scu_enable(shmobile_scu_base);
 
-	/* Tell ROM loader about our vector (in headsmp-scu.S) */
-	emev2_set_boot_vector(__pa(shmobile_secondary_vector_scu));
+	/* Tell ROM loader about our vector (in headsmp-scu.S, headsmp.S) */
+	emev2_set_boot_vector(__pa(shmobile_boot_vector));
+	shmobile_boot_fn = virt_to_phys(shmobile_boot_scu);
+	shmobile_boot_arg = (unsigned long)shmobile_scu_base;
 
 	/* enable cache coherency on booting CPU */
 	scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/smp-r8a7779.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/smp-r8a7779.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/smp-r8a7779.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/smp-r8a7779.c	2013-08-25 20:43:22.000000000 -0400
@@ -81,7 +81,7 @@ static int r8a7779_platform_cpu_kill(uns
 	return ret ? ret : 1;
 }
 
-static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	struct r8a7779_pm_ch *ch = NULL;
 	int ret = -EIO;
@@ -101,8 +101,10 @@ static void __init r8a7779_smp_prepare_c
 {
 	scu_enable(shmobile_scu_base);
 
-	/* Map the reset vector (in headsmp-scu.S) */
-	__raw_writel(__pa(shmobile_secondary_vector_scu), AVECR);
+	/* Map the reset vector (in headsmp-scu.S, headsmp.S) */
+	__raw_writel(__pa(shmobile_boot_vector), AVECR);
+	shmobile_boot_fn = virt_to_phys(shmobile_boot_scu);
+	shmobile_boot_arg = (unsigned long)shmobile_scu_base;
 
 	/* enable cache coherency on booting CPU */
 	scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-shmobile/smp-sh73a0.c linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/smp-sh73a0.c
--- linux-libre-3.10-gnu/arch/arm/mach-shmobile/smp-sh73a0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-shmobile/smp-sh73a0.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,7 +48,7 @@ void __init sh73a0_register_twd(void)
 }
 #endif
 
-static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	cpu = cpu_logical_map(cpu);
 
@@ -64,9 +64,11 @@ static void __init sh73a0_smp_prepare_cp
 {
 	scu_enable(shmobile_scu_base);
 
-	/* Map the reset vector (in headsmp-scu.S) */
+	/* Map the reset vector (in headsmp-scu.S, headsmp.S) */
 	__raw_writel(0, APARMBAREA);      /* 4k */
-	__raw_writel(__pa(shmobile_secondary_vector_scu), SBAR);
+	__raw_writel(__pa(shmobile_boot_vector), SBAR);
+	shmobile_boot_fn = virt_to_phys(shmobile_boot_scu);
+	shmobile_boot_arg = (unsigned long)shmobile_scu_base;
 
 	/* enable cache coherency on booting CPU */
 	scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-socfpga/headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/mach-socfpga/headsmp.S
--- linux-libre-3.10-gnu/arch/arm/mach-socfpga/headsmp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-socfpga/headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,6 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-	__CPUINIT
 	.arch	armv7-a
 
 ENTRY(secondary_trampoline)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-socfpga/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-socfpga/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-socfpga/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-socfpga/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -7,11 +7,11 @@ config ARCH_SOCFPGA
 	select CLKDEV_LOOKUP
 	select COMMON_CLK
 	select CPU_V7
-	select DW_APB_TIMER
 	select DW_APB_TIMER_OF
 	select GENERIC_CLOCKEVENTS
 	select GPIO_PL061 if GPIOLIB
 	select HAVE_ARM_SCU
 	select HAVE_SMP
+	select MFD_SYSCON
 	select SPARSE_IRQ
 	select USE_OF
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-socfpga/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-socfpga/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-socfpga/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-socfpga/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,7 @@
 
 #include "core.h"
 
-static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-socfpga/socfpga.c linux-libre-3.11-rc7-gnu/arch/arm/mach-socfpga/socfpga.c
--- linux-libre-3.10-gnu/arch/arm/mach-socfpga/socfpga.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-socfpga/socfpga.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,12 +14,12 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <linux/dw_apb_timer.h>
 #include <linux/clk-provider.h>
 #include <linux/irqchip.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/reboot.h>
 
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
@@ -90,13 +90,13 @@ static void __init socfpga_init_irq(void
 	socfpga_sysmgr_init();
 }
 
-static void socfpga_cyclone5_restart(char mode, const char *cmd)
+static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)
 {
 	u32 temp;
 
 	temp = readl(rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
 
-	if (mode == 'h')
+	if (mode == REBOOT_HARD)
 		temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
 	else
 		temp |= RSTMGR_CTRL_SWWARMRSTREQ;
@@ -120,7 +120,6 @@ DT_MACHINE_START(SOCFPGA, "Altera SOCFPG
 	.smp		= smp_ops(socfpga_smp_ops),
 	.map_io		= socfpga_map_io,
 	.init_irq	= socfpga_init_irq,
-	.init_time	= dw_apb_timer_init,
 	.init_machine	= socfpga_cyclone5_init,
 	.restart	= socfpga_cyclone5_restart,
 	.dt_compat	= altera_dt_match,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/generic.h linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/generic.h
--- linux-libre-3.10-gnu/arch/arm/mach-spear/generic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/generic.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,8 @@
 #include <linux/dmaengine.h>
 #include <linux/amba/pl08x.h>
 #include <linux/init.h>
+#include <linux/reboot.h>
+
 #include <asm/mach/time.h>
 
 extern void spear13xx_timer_init(void);
@@ -32,10 +34,10 @@ void __init spear6xx_clk_init(void __iom
 void __init spear13xx_map_io(void);
 void __init spear13xx_l2x0_init(void);
 
-void spear_restart(char, const char *);
+void spear_restart(enum reboot_mode, const char *);
 
 void spear13xx_secondary_startup(void);
-void __cpuinit spear13xx_cpu_die(unsigned int cpu);
+void spear13xx_cpu_die(unsigned int cpu);
 
 extern struct smp_operations spear13xx_smp_ops;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-spear/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@ static DEFINE_SPINLOCK(boot_lock);
 
 static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
 
-static void __cpuinit spear13xx_secondary_init(unsigned int cpu)
+static void spear13xx_secondary_init(unsigned int cpu)
 {
 	/*
 	 * let the primary processor know we're out of the
@@ -40,7 +40,7 @@ static void __cpuinit spear13xx_secondar
 	spin_unlock(&boot_lock);
 }
 
-static int __cpuinit spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/restart.c linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/restart.c
--- linux-libre-3.10-gnu/arch/arm/mach-spear/restart.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/restart.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,14 +12,15 @@
  */
 #include <linux/io.h>
 #include <linux/amba/sp810.h>
+#include <linux/reboot.h>
 #include <asm/system_misc.h>
 #include <mach/spear.h>
 #include "generic.h"
 
 #define SPEAR13XX_SYS_SW_RES			(VA_MISC_BASE + 0x204)
-void spear_restart(char mode, const char *cmd)
+void spear_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's') {
+	if (mode == REBOOT_SOFT) {
 		/* software reset, Jump into ROM at address 0 */
 		soft_restart(0);
 	} else {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/spear1310.c linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear1310.c
--- linux-libre-3.10-gnu/arch/arm/mach-spear/spear1310.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear1310.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,7 +14,6 @@
 #define pr_fmt(fmt) "SPEAr1310: " fmt
 
 #include <linux/amba/pl022.h>
-#include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <linux/pata_arasan_cf_data.h>
 #include <asm/mach/arch.h>
@@ -60,7 +59,6 @@ static void __init spear1310_map_io(void
 DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree")
 	.smp		=	smp_ops(spear13xx_smp_ops),
 	.map_io		=	spear1310_map_io,
-	.init_irq	=	irqchip_init,
 	.init_time	=	spear13xx_timer_init,
 	.init_machine	=	spear1310_dt_init,
 	.restart	=	spear_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/spear1340.c linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear1340.c
--- linux-libre-3.10-gnu/arch/arm/mach-spear/spear1340.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear1340.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/amba/serial.h>
 #include <linux/delay.h>
 #include <linux/of_platform.h>
-#include <linux/irqchip.h>
 #include <asm/mach/arch.h>
 #include "generic.h"
 #include <mach/spear.h>
@@ -155,7 +154,6 @@ static const char * const spear1340_dt_b
 DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree")
 	.smp		=	smp_ops(spear13xx_smp_ops),
 	.map_io		=	spear13xx_map_io,
-	.init_irq	=	irqchip_init,
 	.init_time	=	spear13xx_timer_init,
 	.init_machine	=	spear1340_dt_init,
 	.restart	=	spear_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/spear300.c linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear300.c
--- linux-libre-3.10-gnu/arch/arm/mach-spear/spear300.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear300.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,7 +14,6 @@
 #define pr_fmt(fmt) "SPEAr300: " fmt
 
 #include <linux/amba/pl08x.h>
-#include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include "generic.h"
@@ -212,7 +211,6 @@ static void __init spear300_map_io(void)
 
 DT_MACHINE_START(SPEAR300_DT, "ST SPEAr300 SoC with Flattened Device Tree")
 	.map_io		=	spear300_map_io,
-	.init_irq	=	irqchip_init,
 	.init_time	=	spear3xx_timer_init,
 	.init_machine	=	spear300_dt_init,
 	.restart	=	spear_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/spear310.c linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear310.c
--- linux-libre-3.10-gnu/arch/arm/mach-spear/spear310.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear310.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,6 @@
 
 #include <linux/amba/pl08x.h>
 #include <linux/amba/serial.h>
-#include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include "generic.h"
@@ -254,7 +253,6 @@ static void __init spear310_map_io(void)
 
 DT_MACHINE_START(SPEAR310_DT, "ST SPEAr310 SoC with Flattened Device Tree")
 	.map_io		=	spear310_map_io,
-	.init_irq	=	irqchip_init,
 	.init_time	=	spear3xx_timer_init,
 	.init_machine	=	spear310_dt_init,
 	.restart	=	spear_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/spear320.c linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear320.c
--- linux-libre-3.10-gnu/arch/arm/mach-spear/spear320.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear320.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/amba/pl022.h>
 #include <linux/amba/pl08x.h>
 #include <linux/amba/serial.h>
-#include <linux/irqchip.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -269,7 +268,6 @@ static void __init spear320_map_io(void)
 
 DT_MACHINE_START(SPEAR320_DT, "ST SPEAr320 SoC with Flattened Device Tree")
 	.map_io		=	spear320_map_io,
-	.init_irq	=	irqchip_init,
 	.init_time	=	spear3xx_timer_init,
 	.init_machine	=	spear320_dt_init,
 	.restart	=	spear_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/spear3xx.c linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear3xx.c
--- linux-libre-3.10-gnu/arch/arm/mach-spear/spear3xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear3xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,8 +56,8 @@ struct pl08x_platform_data pl080_plat_da
 	},
 	.lli_buses = PL08X_AHB1,
 	.mem_buses = PL08X_AHB1,
-	.get_signal = pl080_get_signal,
-	.put_signal = pl080_put_signal,
+	.get_xfer_signal = pl080_get_signal,
+	.put_xfer_signal = pl080_put_signal,
 };
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-spear/spear6xx.c linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear6xx.c
--- linux-libre-3.10-gnu/arch/arm/mach-spear/spear6xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-spear/spear6xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/amba/pl08x.h>
 #include <linux/clk.h>
 #include <linux/err.h>
-#include <linux/irqchip.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
@@ -335,8 +334,8 @@ static struct pl08x_platform_data spear6
 	},
 	.lli_buses = PL08X_AHB1,
 	.mem_buses = PL08X_AHB1,
-	.get_signal = pl080_get_signal,
-	.put_signal = pl080_put_signal,
+	.get_xfer_signal = pl080_get_signal,
+	.put_xfer_signal = pl080_put_signal,
 	.slave_channels = spear600_dma_info,
 	.num_slave_channels = ARRAY_SIZE(spear600_dma_info),
 };
@@ -423,7 +422,6 @@ static const char *spear600_dt_board_com
 
 DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)")
 	.map_io		=	spear6xx_map_io,
-	.init_irq	=	irqchip_init,
 	.init_time	=	spear6xx_timer_init,
 	.init_machine	=	spear600_dt_init,
 	.restart	=	spear_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sti/board-dt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/board-dt.c
--- linux-libre-3.10-gnu/arch/arm/mach-sti/board-dt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/board-dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author(s): Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/irq.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/arch.h>
+
+#include "smp.h"
+
+void __init stih41x_l2x0_init(void)
+{
+	u32 way_size = 0x4;
+	u32 aux_ctrl;
+	/* may be this can be encoded in macros like BIT*() */
+	aux_ctrl = (0x1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
+		(0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
+		(0x1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
+		(way_size << L2X0_AUX_CTRL_WAY_SIZE_SHIFT);
+
+	l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
+}
+
+static void __init stih41x_timer_init(void)
+{
+	of_clk_init(NULL);
+	clocksource_of_init();
+	stih41x_l2x0_init();
+}
+
+static const char *stih41x_dt_match[] __initdata = {
+	"st,stih415",
+	"st,stih416",
+	NULL
+};
+
+DT_MACHINE_START(STM, "STiH415/416 SoC with Flattened Device Tree")
+	.init_time	= stih41x_timer_init,
+	.smp		= smp_ops(sti_smp_ops),
+	.dt_compat	= stih41x_dt_match,
+MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sti/headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/headsmp.S
--- linux-libre-3.10-gnu/arch/arm/mach-sti/headsmp.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ *  arch/arm/mach-sti/headsmp.S
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *		http://www.st.com
+ *
+ * Cloned from linux/arch/arm/mach-vexpress/headsmp.S
+ *
+ *  Copyright (c) 2003 ARM Limited
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+/*
+ * ST specific entry point for secondary CPUs.  This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(sti_secondary_startup)
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, r0, #15
+	adr	r4, 1f
+	ldmia	r4, {r5, r6}
+	sub	r4, r4, r5
+	add	r6, r6, r4
+pen:	ldr	r7, [r6]
+	cmp	r7, r0
+	bne	pen
+
+	/*
+	 * we've been released from the holding pen: secondary_stack
+	 * should now contain the SVC stack for this core
+	 */
+	b	secondary_startup
+
+1:	.long	.
+	.long	pen_release
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sti/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-sti/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,46 @@
+menuconfig ARCH_STI
+	bool "STMicroelectronics Consumer Electronics SOCs with Device Trees" if ARCH_MULTI_V7
+	select GENERIC_CLOCKEVENTS
+	select CLKDEV_LOOKUP
+	select ARM_GIC
+	select ARM_GLOBAL_TIMER
+	select PINCTRL
+	select PINCTRL_ST
+	select MFD_SYSCON
+	select MIGHT_HAVE_CACHE_L2X0
+	select HAVE_SMP
+	select HAVE_ARM_SCU if SMP
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_ERRATA_754322
+	select ARM_ERRATA_764369
+	select ARM_ERRATA_775420
+	select PL310_ERRATA_753970 if CACHE_PL310
+	select PL310_ERRATA_769419 if CACHE_PL310
+	help
+	  Include support for STiH41x SOCs like STiH415/416 using the device tree
+	  for discovery
+	  More information at Documentation/arm/STiH41x and
+	  at Documentation/devicetree
+
+
+if ARCH_STI
+
+config SOC_STIH415
+	bool "STiH415 STMicroelectronics Consumer Electronics family"
+	default y
+	help
+	  This enables support for STMicroelectronics Digital Consumer
+	  Electronics family StiH415 parts, primarily targetted at set-top-box
+	  and other digital audio/video applications using Flattned Device
+	  Trees.
+
+config SOC_STIH416
+	bool "STiH416 STMicroelectronics Consumer Electronics family"
+	default y
+	help
+	  This enables support for STMicroelectronics Digital Consumer
+	  Electronics family StiH416 parts, primarily targetted at set-top-box
+	  and other digital audio/video applications using Flattened Device
+	  Trees.
+
+endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sti/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-sti/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
+obj-$(CONFIG_ARCH_STI) 		+= board-dt.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sti/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-sti/platsmp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,117 @@
+/*
+ *  arch/arm/mach-sti/platsmp.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *		http://www.st.com
+ *
+ * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "smp.h"
+
+static void write_pen_release(int val)
+{
+	pen_release = val;
+	smp_wmb();
+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void sti_secondary_init(unsigned int cpu)
+{
+	trace_hardirqs_off();
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+int sti_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+
+	/*
+	 * set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	write_pen_release(cpu_logical_map(cpu));
+
+	/*
+	 * Send the secondary CPU a soft interrupt, thereby causing
+	 * it to jump to the secondary entrypoint.
+	 */
+	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		smp_rmb();
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return pen_release != -1 ? -ENOSYS : 0;
+}
+
+void __init sti_smp_prepare_cpus(unsigned int max_cpus)
+{
+	void __iomem *scu_base = NULL;
+	struct device_node *np = of_find_compatible_node(
+					NULL, NULL, "arm,cortex-a9-scu");
+	if (np) {
+		scu_base = of_iomap(np, 0);
+		scu_enable(scu_base);
+		of_node_put(np);
+	}
+}
+
+struct smp_operations __initdata sti_smp_ops = {
+	.smp_prepare_cpus	= sti_smp_prepare_cpus,
+	.smp_secondary_init	= sti_secondary_init,
+	.smp_boot_secondary	= sti_boot_secondary,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sti/smp.h linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/smp.h
--- linux-libre-3.10-gnu/arch/arm/mach-sti/smp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sti/smp.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,17 @@
+/*
+ *  arch/arm/mach-sti/smp.h
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ *		http://www.st.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_STI_SMP_H
+#define __MACH_STI_SMP_H
+
+extern struct smp_operations	sti_smp_ops;
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sunxi/sunxi.c linux-libre-3.11-rc7-gnu/arch/arm/mach-sunxi/sunxi.c
--- linux-libre-3.10-gnu/arch/arm/mach-sunxi/sunxi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sunxi/sunxi.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,11 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/irqchip.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/io.h>
+#include <linux/reboot.h>
 
 #include <linux/clk/sunxi.h>
 
@@ -26,8 +26,6 @@
 #include <asm/mach/map.h>
 #include <asm/system_misc.h>
 
-#include "sunxi.h"
-
 #define SUN4I_WATCHDOG_CTRL_REG		0x00
 #define SUN4I_WATCHDOG_CTRL_RESTART		(1 << 0)
 #define SUN4I_WATCHDOG_MODE_REG		0x04
@@ -36,7 +34,7 @@
 
 static void __iomem *wdt_base;
 
-static void sun4i_restart(char mode, const char *cmd)
+static void sun4i_restart(enum reboot_mode mode, const char *cmd)
 {
 	if (!wdt_base)
 		return;
@@ -81,20 +79,6 @@ static void sunxi_setup_restart(void)
 	arm_pm_restart = of_id->data;
 }
 
-static struct map_desc sunxi_io_desc[] __initdata = {
-	{
-		.virtual	= (unsigned long) SUNXI_REGS_VIRT_BASE,
-		.pfn		= __phys_to_pfn(SUNXI_REGS_PHYS_BASE),
-		.length		= SUNXI_REGS_SIZE,
-		.type		= MT_DEVICE,
-	},
-};
-
-void __init sunxi_map_io(void)
-{
-	iotable_init(sunxi_io_desc, ARRAY_SIZE(sunxi_io_desc));
-}
-
 static void __init sunxi_timer_init(void)
 {
 	sunxi_init_clocks();
@@ -110,14 +94,13 @@ static void __init sunxi_dt_init(void)
 
 static const char * const sunxi_board_dt_compat[] = {
 	"allwinner,sun4i-a10",
+	"allwinner,sun5i-a10s",
 	"allwinner,sun5i-a13",
 	NULL,
 };
 
 DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
 	.init_machine	= sunxi_dt_init,
-	.map_io		= sunxi_map_io,
-	.init_irq	= irqchip_init,
 	.init_time	= sunxi_timer_init,
 	.dt_compat	= sunxi_board_dt_compat,
 MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-sunxi/sunxi.h linux-libre-3.11-rc7-gnu/arch/arm/mach-sunxi/sunxi.h
--- linux-libre-3.10-gnu/arch/arm/mach-sunxi/sunxi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-sunxi/sunxi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-/*
- * Generic definitions for Allwinner SunXi SoCs
- *
- * Copyright (C) 2012 Maxime Ripard
- *
- * Maxime Ripard <maxime.ripard@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __MACH_SUNXI_H
-#define __MACH_SUNXI_H
-
-#define SUNXI_REGS_PHYS_BASE	0x01c00000
-#define SUNXI_REGS_VIRT_BASE	IOMEM(0xf1c00000)
-#define SUNXI_REGS_SIZE		(SZ_2M + SZ_1M)
-
-#endif /* __MACH_SUNXI_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/board.h linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/board.h
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/board.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/board.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,8 +23,9 @@
 #define __MACH_TEGRA_BOARD_H
 
 #include <linux/types.h>
+#include <linux/reboot.h>
 
-void tegra_assert_system_reset(char mode, const char *cmd);
+void tegra_assert_system_reset(enum reboot_mode mode, const char *cmd);
 
 void __init tegra_init_early(void);
 void __init tegra_map_common_io(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,13 +22,15 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/reboot.h>
 #include <linux/irqchip.h>
-#include <linux/clk/tegra.h>
+#include <linux/clk-provider.h>
 
 #include <asm/hardware/cache-l2x0.h>
 
 #include "board.h"
 #include "common.h"
+#include "cpuidle.h"
 #include "fuse.h"
 #include "iomap.h"
 #include "irq.h"
@@ -59,7 +61,7 @@ u32 tegra_uart_config[4] = {
 #ifdef CONFIG_OF
 void __init tegra_dt_init_irq(void)
 {
-	tegra_clocks_init();
+	of_clk_init(NULL);
 	tegra_pmc_init();
 	tegra_init_irq();
 	irqchip_init();
@@ -67,7 +69,7 @@ void __init tegra_dt_init_irq(void)
 }
 #endif
 
-void tegra_assert_system_reset(char mode, const char *cmd)
+void tegra_assert_system_reset(enum reboot_mode mode, const char *cmd)
 {
 	void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0);
 	u32 reg;
@@ -108,5 +110,6 @@ void __init tegra_init_early(void)
 void __init tegra_init_late(void)
 {
 	tegra_init_suspend();
+	tegra_cpuidle_init();
 	tegra_powergate_debugfs_init();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -2,3 +2,4 @@ extern struct smp_operations tegra_smp_o
 
 extern int tegra_cpu_kill(unsigned int cpu);
 extern void tegra_cpu_die(unsigned int cpu);
+extern int tegra_cpu_disable(unsigned int cpu);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/cpuidle.c linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/cpuidle.c
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/cpuidle.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/cpuidle.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,25 +27,20 @@
 #include "fuse.h"
 #include "cpuidle.h"
 
-static int __init tegra_cpuidle_init(void)
+void __init tegra_cpuidle_init(void)
 {
-	int ret;
-
 	switch (tegra_chip_id) {
 	case TEGRA20:
-		ret = tegra20_cpuidle_init();
+		if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+			tegra20_cpuidle_init();
 		break;
 	case TEGRA30:
-		ret = tegra30_cpuidle_init();
+		if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC))
+			tegra30_cpuidle_init();
 		break;
 	case TEGRA114:
-		ret = tegra114_cpuidle_init();
-		break;
-	default:
-		ret = -ENODEV;
+		if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC))
+			tegra114_cpuidle_init();
 		break;
 	}
-
-	return ret;
 }
-device_initcall(tegra_cpuidle_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/cpuidle.h linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/cpuidle.h
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/cpuidle.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/cpuidle.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,22 +17,13 @@
 #ifndef __MACH_TEGRA_CPUIDLE_H
 #define __MACH_TEGRA_CPUIDLE_H
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+#ifdef CONFIG_CPU_IDLE
 int tegra20_cpuidle_init(void);
-#else
-static inline int tegra20_cpuidle_init(void) { return -ENODEV; }
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
 int tegra30_cpuidle_init(void);
-#else
-static inline int tegra30_cpuidle_init(void) { return -ENODEV; }
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_114_SOC
 int tegra114_cpuidle_init(void);
+void tegra_cpuidle_init(void);
 #else
-static inline int tegra114_cpuidle_init(void) { return -ENODEV; }
+static inline void tegra_cpuidle_init(void) {}
 #endif
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/cpuidle-tegra20.c linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/cpuidle-tegra20.c
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/cpuidle-tegra20.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/cpuidle-tegra20.c	2013-08-25 20:43:22.000000000 -0400
@@ -177,7 +177,6 @@ static int tegra20_idle_lp2_coupled(stru
 				    struct cpuidle_driver *drv,
 				    int index)
 {
-	u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu;
 	bool entered_lp2 = false;
 
 	if (tegra_pending_sgi())
@@ -193,16 +192,16 @@ static int tegra20_idle_lp2_coupled(stru
 
 	local_fiq_disable();
 
-	tegra_set_cpu_in_lp2(cpu);
+	tegra_set_cpu_in_lp2();
 	cpu_pm_enter();
 
-	if (cpu == 0)
+	if (dev->cpu == 0)
 		entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index);
 	else
 		entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index);
 
 	cpu_pm_exit();
-	tegra_clear_cpu_in_lp2(cpu);
+	tegra_clear_cpu_in_lp2();
 
 	local_fiq_enable();
 
@@ -214,8 +213,5 @@ static int tegra20_idle_lp2_coupled(stru
 
 int __init tegra20_cpuidle_init(void)
 {
-#ifdef CONFIG_PM_SLEEP
-	tegra_tear_down_cpu = tegra20_tear_down_cpu;
-#endif
 	return cpuidle_register(&tegra_idle_driver, cpu_possible_mask);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/cpuidle-tegra30.c linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/cpuidle-tegra30.c
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/cpuidle-tegra30.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/cpuidle-tegra30.c	2013-08-25 20:43:22.000000000 -0400
@@ -114,16 +114,15 @@ static int tegra30_idle_lp2(struct cpuid
 			    struct cpuidle_driver *drv,
 			    int index)
 {
-	u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu;
 	bool entered_lp2 = false;
 	bool last_cpu;
 
 	local_fiq_disable();
 
-	last_cpu = tegra_set_cpu_in_lp2(cpu);
+	last_cpu = tegra_set_cpu_in_lp2();
 	cpu_pm_enter();
 
-	if (cpu == 0) {
+	if (dev->cpu == 0) {
 		if (last_cpu)
 			entered_lp2 = tegra30_cpu_cluster_power_down(dev, drv,
 								     index);
@@ -134,7 +133,7 @@ static int tegra30_idle_lp2(struct cpuid
 	}
 
 	cpu_pm_exit();
-	tegra_clear_cpu_in_lp2(cpu);
+	tegra_clear_cpu_in_lp2();
 
 	local_fiq_enable();
 
@@ -146,8 +145,5 @@ static int tegra30_idle_lp2(struct cpuid
 
 int __init tegra30_cpuidle_init(void)
 {
-#ifdef CONFIG_PM_SLEEP
-	tegra_tear_down_cpu = tegra30_tear_down_cpu;
-#endif
 	return cpuidle_register(&tegra_idle_driver, NULL);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/flowctrl.h linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/flowctrl.h
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/flowctrl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/flowctrl.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,7 @@
 #define FLOW_CTRL_WAITEVENT		(2 << 29)
 #define FLOW_CTRL_WAIT_FOR_INTERRUPT	(4 << 29)
 #define FLOW_CTRL_JTAG_RESUME		(1 << 28)
+#define FLOW_CTRL_SCLK_RESUME		(1 << 27)
 #define FLOW_CTRL_HALT_CPU_IRQ		(1 << 10)
 #define	FLOW_CTRL_HALT_CPU_FIQ		(1 << 8)
 #define FLOW_CTRL_CPU0_CSR		0x8
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/fuse.h linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/fuse.h
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/fuse.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/fuse.h	2013-08-25 20:43:22.000000000 -0400
@@ -19,16 +19,6 @@
 #ifndef __MACH_TEGRA_FUSE_H
 #define __MACH_TEGRA_FUSE_H
 
-enum tegra_revision {
-	TEGRA_REVISION_UNKNOWN = 0,
-	TEGRA_REVISION_A01,
-	TEGRA_REVISION_A02,
-	TEGRA_REVISION_A03,
-	TEGRA_REVISION_A03p,
-	TEGRA_REVISION_A04,
-	TEGRA_REVISION_MAX,
-};
-
 #define SKU_ID_T20	8
 #define SKU_ID_T25SE	20
 #define SKU_ID_AP25	23
@@ -40,6 +30,17 @@ enum tegra_revision {
 #define TEGRA30		0x30
 #define TEGRA114	0x35
 
+#ifndef __ASSEMBLY__
+enum tegra_revision {
+	TEGRA_REVISION_UNKNOWN = 0,
+	TEGRA_REVISION_A01,
+	TEGRA_REVISION_A02,
+	TEGRA_REVISION_A03,
+	TEGRA_REVISION_A03p,
+	TEGRA_REVISION_A04,
+	TEGRA_REVISION_MAX,
+};
+
 extern int tegra_sku_id;
 extern int tegra_cpu_process_id;
 extern int tegra_core_process_id;
@@ -72,5 +73,6 @@ void tegra114_init_speedo_data(void);
 #else
 static inline void tegra114_init_speedo_data(void) {}
 #endif
+#endif /* __ASSEMBLY__ */
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/hotplug.c linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/hotplug.c
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/hotplug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/hotplug.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,6 +46,17 @@ void __ref tegra_cpu_die(unsigned int cp
 	BUG();
 }
 
+int tegra_cpu_disable(unsigned int cpu)
+{
+	switch (tegra_chip_id) {
+	case TEGRA20:
+	case TEGRA30:
+		return cpu == 0 ? -EPERM : 0;
+	default:
+		return 0;
+	}
+}
+
 void __init tegra_hotplug_init(void)
 {
 	if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
@@ -55,4 +66,6 @@ void __init tegra_hotplug_init(void)
 		tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
 		tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+	if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
+		tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,6 @@ config ARCH_TEGRA_2x_SOC
 	select ARM_ERRATA_754327 if SMP
 	select ARM_ERRATA_764369 if SMP
 	select ARM_GIC
-	select CPU_FREQ_TABLE if CPU_FREQ
 	select CPU_V7
 	select PINCTRL
 	select PINCTRL_TEGRA20
@@ -46,7 +45,6 @@ config ARCH_TEGRA_3x_SOC
 	select ARM_ERRATA_754322
 	select ARM_ERRATA_764369 if SMP
 	select ARM_GIC
-	select CPU_FREQ_TABLE if CPU_FREQ
 	select CPU_V7
 	select PINCTRL
 	select PINCTRL_TEGRA30
@@ -60,10 +58,9 @@ config ARCH_TEGRA_3x_SOC
 
 config ARCH_TEGRA_114_SOC
 	bool "Enable support for Tegra114 family"
-	select ARM_ARCH_TIMER
+	select HAVE_ARM_ARCH_TIMER
 	select ARM_GIC
 	select ARM_L1_CACHE_SHIFT_6
-	select CPU_FREQ_TABLE if CPU_FREQ
 	select CPU_V7
 	select PINCTRL
 	select PINCTRL_TEGRA114
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,7 @@ obj-$(CONFIG_HOTPLUG_CPU)
 obj-$(CONFIG_TEGRA_PCI)			+= pcie.o
 
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= tegra114_speedo.o
+obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= sleep-tegra30.o
 ifeq ($(CONFIG_CPU_IDLE),y)
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= cpuidle-tegra114.o
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,7 +35,7 @@
 
 static cpumask_t tegra_cpu_init_mask;
 
-static void __cpuinit tegra_secondary_init(unsigned int cpu)
+static void tegra_secondary_init(unsigned int cpu)
 {
 	cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
 }
@@ -140,11 +140,34 @@ remove_clamps:
 
 static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
+	int ret = 0;
+
 	cpu = cpu_logical_map(cpu);
-	return tegra_pmc_cpu_power_on(cpu);
+
+	if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
+		/*
+		 * Warm boot flow
+		 * The flow controller in charge of the power state and
+		 * control for each CPU.
+		 */
+		/* set SCLK as event trigger for flow controller */
+		flowctrl_write_cpu_csr(cpu, 1);
+		flowctrl_write_cpu_halt(cpu,
+				FLOW_CTRL_WAITEVENT | FLOW_CTRL_SCLK_RESUME);
+	} else {
+		/*
+		 * Cold boot flow
+		 * The CPU is powered up by toggling PMC directly. It will
+		 * also initial power state in flow controller. After that,
+		 * the CPU's power state is maintained by flow controller.
+		 */
+		ret = tegra_pmc_cpu_power_on(cpu);
+	}
+
+	return ret;
 }
 
-static int __cpuinit tegra_boot_secondary(unsigned int cpu,
+static int tegra_boot_secondary(unsigned int cpu,
 					  struct task_struct *idle)
 {
 	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
@@ -173,5 +196,6 @@ struct smp_operations tegra_smp_ops __in
 #ifdef CONFIG_HOTPLUG_CPU
 	.cpu_kill		= tegra_cpu_kill,
 	.cpu_die		= tegra_cpu_die,
+	.cpu_disable		= tegra_cpu_disable,
 #endif
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/pm.c linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/pm.c
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,6 +44,20 @@
 static DEFINE_SPINLOCK(tegra_lp2_lock);
 void (*tegra_tear_down_cpu)(void);
 
+static void tegra_tear_down_cpu_init(void)
+{
+	switch (tegra_chip_id) {
+	case TEGRA20:
+		if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+			tegra_tear_down_cpu = tegra20_tear_down_cpu;
+		break;
+	case TEGRA30:
+		if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC))
+			tegra_tear_down_cpu = tegra30_tear_down_cpu;
+		break;
+	}
+}
+
 /*
  * restore_cpu_complex
  *
@@ -91,8 +105,9 @@ static void suspend_cpu_complex(void)
 	flowctrl_cpu_suspend_enter(cpu);
 }
 
-void tegra_clear_cpu_in_lp2(int phy_cpu_id)
+void tegra_clear_cpu_in_lp2(void)
 {
+	int phy_cpu_id = cpu_logical_map(smp_processor_id());
 	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
 
 	spin_lock(&tegra_lp2_lock);
@@ -103,8 +118,9 @@ void tegra_clear_cpu_in_lp2(int phy_cpu_
 	spin_unlock(&tegra_lp2_lock);
 }
 
-bool tegra_set_cpu_in_lp2(int phy_cpu_id)
+bool tegra_set_cpu_in_lp2(void)
 {
+	int phy_cpu_id = cpu_logical_map(smp_processor_id());
 	bool last_cpu = false;
 	cpumask_t *cpu_lp2_mask = tegra_cpu_lp2_mask;
 	u32 *cpu_in_lp2 = tegra_cpu_lp2_mask;
@@ -175,7 +191,7 @@ static const char *lp_state[TEGRA_MAX_SU
 	[TEGRA_SUSPEND_LP0] = "LP0",
 };
 
-static int __cpuinit tegra_suspend_enter(suspend_state_t state)
+static int tegra_suspend_enter(suspend_state_t state)
 {
 	enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
 
@@ -192,7 +208,7 @@ static int __cpuinit tegra_suspend_enter
 	suspend_cpu_complex();
 	switch (mode) {
 	case TEGRA_SUSPEND_LP2:
-		tegra_set_cpu_in_lp2(0);
+		tegra_set_cpu_in_lp2();
 		break;
 	default:
 		break;
@@ -202,7 +218,7 @@ static int __cpuinit tegra_suspend_enter
 
 	switch (mode) {
 	case TEGRA_SUSPEND_LP2:
-		tegra_clear_cpu_in_lp2(0);
+		tegra_clear_cpu_in_lp2();
 		break;
 	default:
 		break;
@@ -224,6 +240,7 @@ void __init tegra_init_suspend(void)
 	if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NONE)
 		return;
 
+	tegra_tear_down_cpu_init();
 	tegra_pmc_suspend_init();
 
 	suspend_set_ops(&tegra_suspend_ops);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/pmc.c linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/pmc.c
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/pmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/pmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -234,7 +234,7 @@ static const struct of_device_id matches
 	{ }
 };
 
-static void tegra_pmc_parse_dt(void)
+static void __init tegra_pmc_parse_dt(void)
 {
 	struct device_node *np;
 	u32 prop;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/pm.h linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/pm.h
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/pm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/pm.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,8 +28,8 @@ extern unsigned long l2x0_saved_regs_add
 void save_cpu_arch_register(void);
 void restore_cpu_arch_register(void);
 
-void tegra_clear_cpu_in_lp2(int phy_cpu_id);
-bool tegra_set_cpu_in_lp2(int phy_cpu_id);
+void tegra_clear_cpu_in_lp2(void);
+bool tegra_set_cpu_in_lp2(void);
 
 void tegra_idle_lp2_last(void);
 extern void (*tegra_tear_down_cpu)(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/reset-handler.S linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/reset-handler.S
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/reset-handler.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/reset-handler.S	2013-08-25 20:43:22.000000000 -0400
@@ -22,11 +22,11 @@
 #include <asm/hardware/cache-l2x0.h>
 
 #include "flowctrl.h"
+#include "fuse.h"
 #include "iomap.h"
 #include "reset.h"
 #include "sleep.h"
 
-#define APB_MISC_GP_HIDREV	0x804
 #define PMC_SCRATCH41	0x140
 
 #define RESET_DATA(x)	((TEGRA_RESET_##x)*4)
@@ -38,34 +38,40 @@
  *	  CPU boot vector when restarting the a CPU following
  *	  an LP2 transition. Also branched to by LP0 and LP1 resume after
  *	  re-enabling sdram.
+ *
+ *	r6: SoC ID
  */
 ENTRY(tegra_resume)
 	bl	v7_invalidate_l1
 
 	cpu_id	r0
+	tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
+	cmp	r6, #TEGRA114
+	beq	no_cpu0_chk
+
 	cmp	r0, #0				@ CPU0?
  THUMB(	it	ne )
 	bne	cpu_resume			@ no
+no_cpu0_chk:
 
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
 	/* Are we on Tegra20? */
-	mov32	r6, TEGRA_APB_MISC_BASE
-	ldr	r0, [r6, #APB_MISC_GP_HIDREV]
-	and	r0, r0, #0xff00
-	cmp	r0, #(0x20 << 8)
+	cmp	r6, #TEGRA20
 	beq	1f				@ Yes
 	/* Clear the flow controller flags for this CPU. */
-	mov32	r2, TEGRA_FLOW_CTRL_BASE + FLOW_CTRL_CPU0_CSR	@ CPU0 CSR
-	ldr	r1, [r2]
+	cpu_to_csr_reg r1, r0
+	mov32	r2, TEGRA_FLOW_CTRL_BASE
+	ldr	r1, [r2, r1]
 	/* Clear event & intr flag */
 	orr	r1, r1, \
 		#FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
-	movw	r0, #0x0FFD	@ enable, cluster_switch, immed, & bitmaps
+	movw	r0, #0x3FFD	@ enable, cluster_switch, immed, bitmaps
+				@ & ext flags for CPU power mgnt
 	bic	r1, r1, r0
 	str	r1, [r2]
 1:
-#endif
 
+	check_cpu_part_num 0xc09, r8, r9
+	bne	not_ca9
 #ifdef CONFIG_HAVE_ARM_SCU
 	/* enable SCU */
 	mov32	r0, TEGRA_ARM_PERIF_BASE
@@ -76,6 +82,7 @@ ENTRY(tegra_resume)
 
 	/* L2 cache resume & re-enable */
 	l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
+not_ca9:
 
 	b	cpu_resume
 ENDPROC(tegra_resume)
@@ -98,7 +105,7 @@ ENTRY(__tegra_cpu_reset_handler_start)
  * Register usage within the reset handler:
  *
  *      Others: scratch
- *      R6  = SoC ID << 8
+ *      R6  = SoC ID
  *      R7  = CPU present (to the OS) mask
  *      R8  = CPU in LP1 state mask
  *      R9  = CPU in LP2 state mask
@@ -115,12 +122,10 @@ ENTRY(__tegra_cpu_reset_handler)
 
 	cpsid	aif, 0x13			@ SVC mode, interrupts disabled
 
-	mov32	r6, TEGRA_APB_MISC_BASE
-	ldr	r6, [r6, #APB_MISC_GP_HIDREV]
-	and	r6, r6, #0xff00
+	tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
 t20_check:
-	cmp	r6, #(0x20 << 8)
+	cmp	r6, #TEGRA20
 	bne	after_t20_check
 t20_errata:
 	# Tegra20 is a Cortex-A9 r1p1
@@ -136,7 +141,7 @@ after_t20_check:
 #endif
 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
 t30_check:
-	cmp	r6, #(0x30 << 8)
+	cmp	r6, #TEGRA30
 	bne	after_t30_check
 t30_errata:
 	# Tegra30 is a Cortex-A9 r2p9
@@ -163,7 +168,7 @@ after_errata:
 
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
 	/* Are we on Tegra20? */
-	cmp	r6, #(0x20 << 8)
+	cmp	r6, #TEGRA20
 	bne	1f
 	/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
 	mov32	r5, TEGRA_PMC_BASE
@@ -186,11 +191,14 @@ __is_not_lp2:
 
 #ifdef CONFIG_SMP
 	/*
-	 * Can only be secondary boot (initial or hotplug) but CPU 0
-	 * cannot be here.
+	 * Can only be secondary boot (initial or hotplug)
+	 * CPU0 can't be here for Tegra20/30
 	 */
+	cmp	r6, #TEGRA114
+	beq	__no_cpu0_chk
 	cmp	r10, #0
 	bleq	__die				@ CPU0 cannot be here
+__no_cpu0_chk:
 	ldr	lr, [r12, #RESET_DATA(STARTUP_SECONDARY)]
 	cmp	lr, #0
 	bleq	__die				@ no secondary startup handler
@@ -210,10 +218,7 @@ __die:
 	mov32	r7, TEGRA_CLK_RESET_BASE
 
 	/* Are we on Tegra20? */
-	mov32	r6, TEGRA_APB_MISC_BASE
-	ldr	r0, [r6, #APB_MISC_GP_HIDREV]
-	and	r0, r0, #0xff00
-	cmp	r0, #(0x20 << 8)
+	cmp	r6, #TEGRA20
 	bne	1f
 
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/sleep.h linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/sleep.h
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/sleep.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/sleep.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,8 @@
 					+ IO_PPSB_VIRT)
 #define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
 					+ IO_PPSB_VIRT)
+#define TEGRA_APB_MISC_VIRT (TEGRA_APB_MISC_BASE - IO_APB_PHYS \
+					+ IO_APB_VIRT)
 #define TEGRA_PMC_VIRT	(TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
 
 /* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */
@@ -70,19 +72,40 @@
 	movt	\reg, #:upper16:\val
 .endm
 
+/* Marco to check CPU part num */
+.macro check_cpu_part_num part_num, tmp1, tmp2
+	mrc	p15, 0, \tmp1, c0, c0, 0
+	ubfx	\tmp1, \tmp1, #4, #12
+	mov32	\tmp2, \part_num
+	cmp	\tmp1, \tmp2
+.endm
+
 /* Macro to exit SMP coherency. */
 .macro exit_smp, tmp1, tmp2
 	mrc	p15, 0, \tmp1, c1, c0, 1	@ ACTLR
 	bic	\tmp1, \tmp1, #(1<<6) | (1<<0)	@ clear ACTLR.SMP | ACTLR.FW
 	mcr	p15, 0, \tmp1, c1, c0, 1	@ ACTLR
 	isb
-	cpu_id	\tmp1
-	mov	\tmp1, \tmp1, lsl #2
-	mov	\tmp2, #0xf
-	mov	\tmp2, \tmp2, lsl \tmp1
-	mov32	\tmp1, TEGRA_ARM_PERIF_VIRT + 0xC
-	str	\tmp2, [\tmp1]			@ invalidate SCU tags for CPU
+#ifdef CONFIG_HAVE_ARM_SCU
+	check_cpu_part_num 0xc09, \tmp1, \tmp2
+	mrceq	p15, 0, \tmp1, c0, c0, 5
+	andeq	\tmp1, \tmp1, #0xF
+	moveq	\tmp1, \tmp1, lsl #2
+	moveq	\tmp2, #0xf
+	moveq	\tmp2, \tmp2, lsl \tmp1
+	ldreq	\tmp1, =(TEGRA_ARM_PERIF_VIRT + 0xC)
+	streq	\tmp2, [\tmp1]			@ invalidate SCU tags for CPU
 	dsb
+#endif
+.endm
+
+/* Macro to check Tegra revision */
+#define APB_MISC_GP_HIDREV	0x804
+.macro tegra_get_soc_id base, tmp1
+	mov32	\tmp1, \base
+	ldr	\tmp1, [\tmp1, #APB_MISC_GP_HIDREV]
+	and	\tmp1, \tmp1, #0xff00
+	mov	\tmp1, \tmp1, lsr #8
 .endm
 
 /* Macro to resume & re-enable L2 cache */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/sleep.S linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/sleep.S
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/sleep.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/sleep.S	2013-08-25 20:43:22.000000000 -0400
@@ -106,9 +106,11 @@ ENTRY(tegra_shut_off_mmu)
 	isb
 #ifdef CONFIG_CACHE_L2X0
 	/* Disable L2 cache */
-	mov32	r4, TEGRA_ARM_PERIF_BASE + 0x3000
-	mov	r5, #0
-	str	r5, [r4, #L2X0_CTRL]
+	check_cpu_part_num 0xc09, r9, r10
+	movweq	r4, #:lower16:(TEGRA_ARM_PERIF_BASE + 0x3000)
+	movteq	r4, #:upper16:(TEGRA_ARM_PERIF_BASE + 0x3000)
+	moveq	r5, #0
+	streq	r5, [r4, #L2X0_CTRL]
 #endif
 	mov	pc, r0
 ENDPROC(tegra_shut_off_mmu)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/sleep-tegra30.S linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/sleep-tegra30.S
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/sleep-tegra30.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/sleep-tegra30.S	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,7 @@
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
 
+#include "fuse.h"
 #include "sleep.h"
 #include "flowctrl.h"
 
@@ -43,14 +44,19 @@ ENDPROC(tegra30_hotplug_shutdown)
  *
  * Puts the current CPU in wait-for-event mode on the flow controller
  * and powergates it -- flags (in R0) indicate the request type.
- * Must never be called for CPU 0.
  *
- * corrupts r0-r4, r12
+ * r10 = SoC ID
+ * corrupts r0-r4, r10-r12
  */
 ENTRY(tegra30_cpu_shutdown)
 	cpu_id	r3
+	tegra_get_soc_id TEGRA_APB_MISC_VIRT, r10
+	cmp	r10, #TEGRA30
+	bne	_no_cpu0_chk	@ It's not Tegra30
+
 	cmp	r3, #0
 	moveq	pc, lr		@ Must never be called for CPU 0
+_no_cpu0_chk:
 
 	ldr	r12, =TEGRA_FLOW_CTRL_VIRT
 	cpu_to_csr_reg r1, r3
@@ -65,7 +71,9 @@ ENTRY(tegra30_cpu_shutdown)
 	movw	r12, \
 		FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG | \
 		FLOW_CTRL_CSR_ENABLE
-	mov	r4, #(1 << 4)
+	cmp	r10, #TEGRA30
+	moveq	r4, #(1 << 4)			@ wfe bitmap
+	movne	r4, #(1 << 8)			@ wfi bitmap
  ARM(	orr	r12, r12, r4, lsl r3	)
  THUMB(	lsl	r4, r4, r3		)
  THUMB(	orr	r12, r12, r4		)
@@ -79,9 +87,20 @@ delay_1:
 	cpsid	a				@ disable imprecise aborts.
 	ldr	r3, [r1]			@ read CSR
 	str	r3, [r1]			@ clear CSR
+
 	tst	r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN
+	beq	flow_ctrl_setting_for_lp2
+
+	/* flow controller set up for hotplug */
+	mov	r3, #FLOW_CTRL_WAITEVENT		@ For hotplug
+	b	flow_ctrl_done
+flow_ctrl_setting_for_lp2:
+	/* flow controller set up for LP2 */
+	cmp	r10, #TEGRA30
 	moveq   r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT	@ For LP2
-	movne	r3, #FLOW_CTRL_WAITEVENT		@ For hotplug
+	movne	r3, #FLOW_CTRL_WAITEVENT
+flow_ctrl_done:
+	cmp	r10, #TEGRA30
 	str	r3, [r2]
 	ldr	r0, [r2]
 	b	wfe_war
@@ -89,7 +108,8 @@ delay_1:
 __cpu_reset_again:
 	dsb
 	.align 5
-	wfe					@ CPU should be power gated here
+	wfeeq					@ CPU should be power gated here
+	wfine
 wfe_war:
 	b	__cpu_reset_again
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-tegra/tegra2_emc.c linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/tegra2_emc.c
--- linux-libre-3.10-gnu/arch/arm/mach-tegra/tegra2_emc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-tegra/tegra2_emc.c	2013-08-25 20:43:22.000000000 -0400
@@ -183,7 +183,7 @@ static struct device_node *tegra_emc_ram
 	u32 reg;
 
 	for_each_child_of_node(np, iter) {
-		if (of_property_read_u32(np, "nvidia,ram-code", &reg))
+		if (of_property_read_u32(iter, "nvidia,ram-code", &reg))
 			continue;
 		if (reg == tegra_bct_strapping)
 			return of_node_get(iter);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/core.c linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/core.c
--- linux-libre-3.10-gnu/arch/arm/mach-u300/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,46 +9,157 @@
  * Author: Linus Walleij <linus.walleij@stericsson.com>
  */
 #include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/device.h>
-#include <linux/mm.h>
-#include <linux/termios.h>
-#include <linux/dmaengine.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/mmci.h>
-#include <linux/amba/serial.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/fsmc.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/pinctrl/pinconf-generic.h>
-#include <linux/dma-mapping.h>
 #include <linux/platform_data/clk-u300.h>
-#include <linux/platform_data/pinctrl-coh901.h>
-#include <linux/platform_data/dma-coh901318.h>
-#include <linux/irqchip/arm-vic.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clocksource.h>
+#include <linux/clk.h>
 
-#include <asm/types.h>
-#include <asm/setup.h>
-#include <asm/memory.h>
 #include <asm/mach/map.h>
-#include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/hardware.h>
-#include <mach/syscon.h>
-#include <mach/irqs.h>
+/*
+ * These are the large blocks of memory allocated for I/O.
+ * the defines are used for setting up the I/O memory mapping.
+ */
 
-#include "timer.h"
-#include "spi.h"
-#include "i2c.h"
-#include "u300-gpio.h"
+/* NAND Flash CS0 */
+#define U300_NAND_CS0_PHYS_BASE		0x80000000
+/* NFIF */
+#define U300_NAND_IF_PHYS_BASE		0x9f800000
+/* ALE, CLE offset for FSMC NAND */
+#define PLAT_NAND_CLE			(1 << 16)
+#define PLAT_NAND_ALE			(1 << 17)
+/* AHB Peripherals */
+#define U300_AHB_PER_PHYS_BASE		0xa0000000
+#define U300_AHB_PER_VIRT_BASE		0xff010000
+/* FAST Peripherals */
+#define U300_FAST_PER_PHYS_BASE		0xc0000000
+#define U300_FAST_PER_VIRT_BASE		0xff020000
+/* SLOW Peripherals */
+#define U300_SLOW_PER_PHYS_BASE		0xc0010000
+#define U300_SLOW_PER_VIRT_BASE		0xff000000
+/* Boot ROM */
+#define U300_BOOTROM_PHYS_BASE		0xffff0000
+#define U300_BOOTROM_VIRT_BASE		0xffff0000
+/* SEMI config base */
+#define U300_SEMI_CONFIG_BASE		0x2FFE0000
+
+/*
+ * AHB peripherals
+ */
+
+/* AHB Peripherals Bridge Controller */
+#define U300_AHB_BRIDGE_BASE		(U300_AHB_PER_PHYS_BASE+0x0000)
+/* Vectored Interrupt Controller 0, servicing 32 interrupts */
+#define U300_INTCON0_BASE		(U300_AHB_PER_PHYS_BASE+0x1000)
+#define U300_INTCON0_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x1000)
+/* Vectored Interrupt Controller 1, servicing 32 interrupts */
+#define U300_INTCON1_BASE		(U300_AHB_PER_PHYS_BASE+0x2000)
+#define U300_INTCON1_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x2000)
+/* Memory Stick Pro (MSPRO) controller */
+#define U300_MSPRO_BASE			(U300_AHB_PER_PHYS_BASE+0x3000)
+/* EMIF Configuration Area */
+#define U300_EMIF_CFG_BASE		(U300_AHB_PER_PHYS_BASE+0x4000)
+
+/*
+ * FAST peripherals
+ */
+
+/* FAST bridge control */
+#define U300_FAST_BRIDGE_BASE		(U300_FAST_PER_PHYS_BASE+0x0000)
+/* MMC/SD controller */
+#define U300_MMCSD_BASE			(U300_FAST_PER_PHYS_BASE+0x1000)
+/* PCM I2S0 controller */
+#define U300_PCM_I2S0_BASE		(U300_FAST_PER_PHYS_BASE+0x2000)
+/* PCM I2S1 controller */
+#define U300_PCM_I2S1_BASE		(U300_FAST_PER_PHYS_BASE+0x3000)
+/* I2C0 controller */
+#define U300_I2C0_BASE			(U300_FAST_PER_PHYS_BASE+0x4000)
+/* I2C1 controller */
+#define U300_I2C1_BASE			(U300_FAST_PER_PHYS_BASE+0x5000)
+/* SPI controller */
+#define U300_SPI_BASE			(U300_FAST_PER_PHYS_BASE+0x6000)
+/* Fast UART1 on U335 only */
+#define U300_UART1_BASE			(U300_FAST_PER_PHYS_BASE+0x7000)
+
+/*
+ * SLOW peripherals
+ */
+
+/* SLOW bridge control */
+#define U300_SLOW_BRIDGE_BASE		(U300_SLOW_PER_PHYS_BASE)
+/* SYSCON */
+#define U300_SYSCON_BASE		(U300_SLOW_PER_PHYS_BASE+0x1000)
+#define U300_SYSCON_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000)
+/* Watchdog */
+#define U300_WDOG_BASE			(U300_SLOW_PER_PHYS_BASE+0x2000)
+/* UART0 */
+#define U300_UART0_BASE			(U300_SLOW_PER_PHYS_BASE+0x3000)
+/* APP side special timer */
+#define U300_TIMER_APP_BASE		(U300_SLOW_PER_PHYS_BASE+0x4000)
+#define U300_TIMER_APP_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000)
+/* Keypad */
+#define U300_KEYPAD_BASE		(U300_SLOW_PER_PHYS_BASE+0x5000)
+/* GPIO */
+#define U300_GPIO_BASE			(U300_SLOW_PER_PHYS_BASE+0x6000)
+/* RTC */
+#define U300_RTC_BASE			(U300_SLOW_PER_PHYS_BASE+0x7000)
+/* Bus tracer */
+#define U300_BUSTR_BASE			(U300_SLOW_PER_PHYS_BASE+0x8000)
+/* Event handler (hardware queue) */
+#define U300_EVHIST_BASE		(U300_SLOW_PER_PHYS_BASE+0x9000)
+/* Genric Timer */
+#define U300_TIMER_BASE			(U300_SLOW_PER_PHYS_BASE+0xa000)
+/* PPM */
+#define U300_PPM_BASE			(U300_SLOW_PER_PHYS_BASE+0xb000)
+
+/*
+ * REST peripherals
+ */
+
+/* ISP (image signal processor) */
+#define U300_ISP_BASE			(0xA0008000)
+/* DMA Controller base */
+#define U300_DMAC_BASE			(0xC0020000)
+/* MSL Base */
+#define U300_MSL_BASE			(0xc0022000)
+/* APEX Base */
+#define U300_APEX_BASE			(0xc0030000)
+/* Video Encoder Base */
+#define U300_VIDEOENC_BASE		(0xc0080000)
+/* XGAM Base */
+#define U300_XGAM_BASE			(0xd0000000)
+
+/*
+ * SYSCON addresses applicable to the core machine.
+ */
+
+/* Chip ID register 16bit (R/-) */
+#define U300_SYSCON_CIDR					(0x400)
+/* SMCR */
+#define U300_SYSCON_SMCR					(0x4d0)
+#define U300_SYSCON_SMCR_FIELD_MASK				(0x000e)
+#define U300_SYSCON_SMCR_SEMI_SREFACK_IND			(0x0008)
+#define U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE			(0x0004)
+#define U300_SYSCON_SMCR_SEMI_EXT_BOOT_MODE_ENABLE		(0x0002)
+/* CPU_SW_DBGEN Software Debug Enable 16bit (R/W) */
+#define U300_SYSCON_CSDR					(0x4f0)
+#define U300_SYSCON_CSDR_SW_DEBUG_ENABLE			(0x0001)
+/* PRINT_CONTROL Print Control 16bit (R/-) */
+#define U300_SYSCON_PCR						(0x4f8)
+#define U300_SYSCON_PCR_SERV_IND				(0x0001)
+/* BOOT_CONTROL 16bit (R/-) */
+#define U300_SYSCON_BCR						(0x4fc)
+#define U300_SYSCON_BCR_ACC_CPU_SUBSYS_VINITHI_IND		(0x0400)
+#define U300_SYSCON_BCR_APP_CPU_SUBSYS_VINITHI_IND		(0x0200)
+#define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK			(0x01FC)
+#define U300_SYSCON_BCR_APP_BOOT_SERV_MASK			(0x0003)
+
+static void __iomem *syscon_base;
 
 /*
  * Static I/O mappings that are needed for booting the U300 platforms. The
@@ -82,365 +193,6 @@ static void __init u300_map_io(void)
 	iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
 }
 
-/*
- * Declaration of devices found on the U300 board and
- * their respective memory locations.
- */
-
-static struct amba_pl011_data uart0_plat_data = {
-#ifdef CONFIG_COH901318
-	.dma_filter = coh901318_filter_id,
-	.dma_rx_param = (void *) U300_DMA_UART0_RX,
-	.dma_tx_param = (void *) U300_DMA_UART0_TX,
-#endif
-};
-
-/* Slow device at 0x3000 offset */
-static AMBA_APB_DEVICE(uart0, "uart0", 0, U300_UART0_BASE,
-	{ IRQ_U300_UART0 }, &uart0_plat_data);
-
-/* The U335 have an additional UART1 on the APP CPU */
-static struct amba_pl011_data uart1_plat_data = {
-#ifdef CONFIG_COH901318
-	.dma_filter = coh901318_filter_id,
-	.dma_rx_param = (void *) U300_DMA_UART1_RX,
-	.dma_tx_param = (void *) U300_DMA_UART1_TX,
-#endif
-};
-
-/* Fast device at 0x7000 offset */
-static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE,
-	{ IRQ_U300_UART1 }, &uart1_plat_data);
-
-/* AHB device at 0x4000 offset */
-static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL);
-
-/* Fast device at 0x6000 offset */
-static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE,
-	{ IRQ_U300_SPI }, NULL);
-
-/* Fast device at 0x1000 offset */
-#define U300_MMCSD_IRQS	{ IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }
-
-static struct mmci_platform_data mmcsd_platform_data = {
-	/*
-	 * Do not set ocr_mask or voltage translation function,
-	 * we have a regulator we can control instead.
-	 */
-	.f_max = 24000000,
-	.gpio_wp = -1,
-	.gpio_cd = U300_GPIO_PIN_MMC_CD,
-	.cd_invert = true,
-	.capabilities = MMC_CAP_MMC_HIGHSPEED |
-	MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
-#ifdef CONFIG_COH901318
-	.dma_filter = coh901318_filter_id,
-	.dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX,
-	/* Don't specify a TX channel, this RX channel is bidirectional */
-#endif
-};
-
-static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE,
-	U300_MMCSD_IRQS, &mmcsd_platform_data);
-
-/*
- * The order of device declaration may be important, since some devices
- * have dependencies on other devices being initialized first.
- */
-static struct amba_device *amba_devs[] __initdata = {
-	&uart0_device,
-	&uart1_device,
-	&pl022_device,
-	&pl172_device,
-	&mmcsd_device,
-};
-
-/* Here follows a list of all hw resources that the platform devices
- * allocate. Note, clock dependencies are not included
- */
-
-static struct resource gpio_resources[] = {
-	{
-		.start = U300_GPIO_BASE,
-		.end   = (U300_GPIO_BASE + SZ_4K - 1),
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.name  = "gpio0",
-		.start = IRQ_U300_GPIO_PORT0,
-		.end   = IRQ_U300_GPIO_PORT0,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name  = "gpio1",
-		.start = IRQ_U300_GPIO_PORT1,
-		.end   = IRQ_U300_GPIO_PORT1,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name  = "gpio2",
-		.start = IRQ_U300_GPIO_PORT2,
-		.end   = IRQ_U300_GPIO_PORT2,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name  = "gpio3",
-		.start = IRQ_U300_GPIO_PORT3,
-		.end   = IRQ_U300_GPIO_PORT3,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name  = "gpio4",
-		.start = IRQ_U300_GPIO_PORT4,
-		.end   = IRQ_U300_GPIO_PORT4,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name  = "gpio5",
-		.start = IRQ_U300_GPIO_PORT5,
-		.end   = IRQ_U300_GPIO_PORT5,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name  = "gpio6",
-		.start = IRQ_U300_GPIO_PORT6,
-		.end   = IRQ_U300_GPIO_PORT6,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource keypad_resources[] = {
-	{
-		.start = U300_KEYPAD_BASE,
-		.end   = U300_KEYPAD_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.name  = "coh901461-press",
-		.start = IRQ_U300_KEYPAD_KEYBF,
-		.end   = IRQ_U300_KEYPAD_KEYBF,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name  = "coh901461-release",
-		.start = IRQ_U300_KEYPAD_KEYBR,
-		.end   = IRQ_U300_KEYPAD_KEYBR,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource rtc_resources[] = {
-	{
-		.start = U300_RTC_BASE,
-		.end   = U300_RTC_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IRQ_U300_RTC,
-		.end   = IRQ_U300_RTC,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-/*
- * Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2)
- * but these are not yet used by the driver.
- */
-static struct resource fsmc_resources[] = {
-	{
-		.name  = "nand_addr",
-		.start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE,
-		.end   = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.name  = "nand_cmd",
-		.start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE,
-		.end   = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.name  = "nand_data",
-		.start = U300_NAND_CS0_PHYS_BASE,
-		.end   = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.name  = "fsmc_regs",
-		.start = U300_NAND_IF_PHYS_BASE,
-		.end   = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-static struct resource i2c0_resources[] = {
-	{
-		.start = U300_I2C0_BASE,
-		.end   = U300_I2C0_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IRQ_U300_I2C0,
-		.end   = IRQ_U300_I2C0,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource i2c1_resources[] = {
-	{
-		.start = U300_I2C1_BASE,
-		.end   = U300_I2C1_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IRQ_U300_I2C1,
-		.end   = IRQ_U300_I2C1,
-		.flags = IORESOURCE_IRQ,
-	},
-
-};
-
-static struct resource wdog_resources[] = {
-	{
-		.start = U300_WDOG_BASE,
-		.end   = U300_WDOG_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IRQ_U300_WDOG,
-		.end   = IRQ_U300_WDOG,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static struct resource dma_resource[] = {
-	{
-		.start = U300_DMAC_BASE,
-		.end = U300_DMAC_BASE + PAGE_SIZE - 1,
-		.flags =  IORESOURCE_MEM,
-	},
-	{
-		.start = IRQ_U300_DMA,
-		.end = IRQ_U300_DMA,
-		.flags =  IORESOURCE_IRQ,
-	}
-};
-
-
-static struct resource pinctrl_resources[] = {
-	{
-		.start = U300_SYSCON_BASE,
-		.end   = U300_SYSCON_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device wdog_device = {
-	.name = "coh901327_wdog",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(wdog_resources),
-	.resource = wdog_resources,
-};
-
-static struct platform_device i2c0_device = {
-	.name = "stu300",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(i2c0_resources),
-	.resource = i2c0_resources,
-};
-
-static struct platform_device i2c1_device = {
-	.name = "stu300",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(i2c1_resources),
-	.resource = i2c1_resources,
-};
-
-static struct platform_device pinctrl_device = {
-	.name = "pinctrl-u300",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(pinctrl_resources),
-	.resource = pinctrl_resources,
-};
-
-/*
- * The different variants have a few different versions of the
- * GPIO block, with different number of ports.
- */
-static struct u300_gpio_platform u300_gpio_plat = {
-	.ports = 7,
-	.gpio_base = 0,
-};
-
-static struct platform_device gpio_device = {
-	.name = "u300-gpio",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(gpio_resources),
-	.resource = gpio_resources,
-	.dev = {
-		.platform_data = &u300_gpio_plat,
-	},
-};
-
-static struct platform_device keypad_device = {
-	.name = "keypad",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(keypad_resources),
-	.resource = keypad_resources,
-};
-
-static struct platform_device rtc_device = {
-	.name = "rtc-coh901331",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(rtc_resources),
-	.resource = rtc_resources,
-};
-
-static struct mtd_partition u300_partitions[] = {
-	{
-		.name = "bootrecords",
-		.offset = 0,
-		.size = SZ_128K,
-	},
-	{
-		.name = "free",
-		.offset = SZ_128K,
-		.size = 8064 * SZ_1K,
-	},
-	{
-		.name = "platform",
-		.offset = 8192 * SZ_1K,
-		.size = 253952 * SZ_1K,
-	},
-};
-
-static struct fsmc_nand_platform_data nand_platform_data = {
-	.partitions = u300_partitions,
-	.nr_partitions = ARRAY_SIZE(u300_partitions),
-	.options = NAND_SKIP_BBTSCAN,
-	.width = FSMC_NAND_BW8,
-};
-
-static struct platform_device nand_device = {
-	.name = "fsmc-nand",
-	.id = -1,
-	.resource = fsmc_resources,
-	.num_resources = ARRAY_SIZE(fsmc_resources),
-	.dev = {
-		.platform_data = &nand_platform_data,
-	},
-};
-
-static struct platform_device dma_device = {
-	.name		= "coh901318",
-	.id		= -1,
-	.resource	= dma_resource,
-	.num_resources  = ARRAY_SIZE(dma_resource),
-	.dev = {
-		.coherent_dma_mask = ~0,
-	},
-};
-
 static unsigned long pin_pullup_conf[] = {
 	PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
 };
@@ -467,61 +219,6 @@ static struct pinctrl_map __initdata u30
 				    pin_highz_conf),
 };
 
-/*
- * Notice that AMBA devices are initialized before platform devices.
- *
- */
-static struct platform_device *platform_devs[] __initdata = {
-	&dma_device,
-	&i2c0_device,
-	&i2c1_device,
-	&keypad_device,
-	&rtc_device,
-	&pinctrl_device,
-	&gpio_device,
-	&nand_device,
-	&wdog_device,
-};
-
-/*
- * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
- * together so some interrupts are connected to the first one and some
- * to the second one.
- */
-static void __init u300_init_irq(void)
-{
-	u32 mask[2] = {0, 0};
-	struct clk *clk;
-	int i;
-
-	/* initialize clocking early, we want to clock the INTCON */
-	u300_clk_init(U300_SYSCON_VBASE);
-
-	/* Bootstrap EMIF and SEMI clocks */
-	clk = clk_get_sys("pl172", NULL);
-	BUG_ON(IS_ERR(clk));
-	clk_prepare_enable(clk);
-	clk = clk_get_sys("semi", NULL);
-	BUG_ON(IS_ERR(clk));
-	clk_prepare_enable(clk);
-
-	/* Clock the interrupt controller */
-	clk = clk_get_sys("intcon", NULL);
-	BUG_ON(IS_ERR(clk));
-	clk_prepare_enable(clk);
-
-	for (i = 0; i < U300_VIC_IRQS_END; i++)
-		set_bit(i, (unsigned long *) &mask[0]);
-	vic_init((void __iomem *) U300_INTCON0_VBASE, IRQ_U300_INTCON0_START,
-		 mask[0], mask[0]);
-	vic_init((void __iomem *) U300_INTCON1_VBASE, IRQ_U300_INTCON1_START,
-		 mask[1], mask[1]);
-}
-
-
-/*
- * U300 platforms peripheral handling
- */
 struct db_chip {
 	u16 chipid;
 	const char *name;
@@ -578,7 +275,7 @@ static void __init u300_init_check_chip(
 	const char unknown[] = "UNKNOWN";
 
 	/* Read out and print chip ID */
-	val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR);
+	val = readw(syscon_base + U300_SYSCON_CIDR);
 	/* This is in funky bigendian order... */
 	val = (val & 0xFFU) << 8 | (val >> 8);
 	chip = db_chips;
@@ -600,101 +297,119 @@ static void __init u300_init_check_chip(
 	}
 }
 
-/*
- * Some devices and their resources require reserved physical memory from
- * the end of the available RAM. This function traverses the list of devices
- * and assigns actual addresses to these.
- */
-static void __init u300_assign_physmem(void)
+/* Forward declare this function from the watchdog */
+void coh901327_watchdog_reset(void);
+
+static void u300_restart(enum reboot_mode mode, const char *cmd)
 {
-	unsigned long curr_start = __pa(high_memory);
-	int i, j;
+	switch (mode) {
+	case REBOOT_SOFT:
+	case REBOOT_HARD:
+#ifdef CONFIG_COH901327_WATCHDOG
+		coh901327_watchdog_reset();
+#endif
+		break;
+	default:
+		/* Do nothing */
+		break;
+	}
+	/* Wait for system do die/reset. */
+	while (1);
+}
 
-	for (i = 0; i < ARRAY_SIZE(platform_devs); i++) {
-		for (j = 0; j < platform_devs[i]->num_resources; j++) {
-			struct resource *const res =
-			  &platform_devs[i]->resource[j];
+/* These are mostly to get the right device names for the clock lookups */
+static struct of_dev_auxdata u300_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("stericsson,pinctrl-u300", U300_SYSCON_BASE,
+		"pinctrl-u300", NULL),
+	OF_DEV_AUXDATA("stericsson,gpio-coh901", U300_GPIO_BASE,
+		"u300-gpio", NULL),
+	OF_DEV_AUXDATA("stericsson,coh901327", U300_WDOG_BASE,
+		"coh901327_wdog", NULL),
+	OF_DEV_AUXDATA("stericsson,coh901331", U300_RTC_BASE,
+		"rtc-coh901331", NULL),
+	OF_DEV_AUXDATA("stericsson,coh901318", U300_DMAC_BASE,
+		"coh901318", NULL),
+	OF_DEV_AUXDATA("stericsson,fsmc-nand", U300_NAND_IF_PHYS_BASE,
+		"fsmc-nand", NULL),
+	OF_DEV_AUXDATA("arm,primecell", U300_UART0_BASE,
+		"uart0", NULL),
+	OF_DEV_AUXDATA("arm,primecell", U300_UART1_BASE,
+		"uart1", NULL),
+	OF_DEV_AUXDATA("arm,primecell", U300_SPI_BASE,
+		"pl022", NULL),
+	OF_DEV_AUXDATA("st,ddci2c", U300_I2C0_BASE,
+		"stu300.0", NULL),
+	OF_DEV_AUXDATA("st,ddci2c", U300_I2C1_BASE,
+		"stu300.1", NULL),
+	OF_DEV_AUXDATA("arm,primecell", U300_MMCSD_BASE,
+		"mmci", NULL),
+	{ /* sentinel */ },
+};
 
-			if (IORESOURCE_MEM == res->flags &&
-				     0 == res->start) {
-				res->start  = curr_start;
-				res->end   += curr_start;
-				curr_start += resource_size(res);
+static void __init u300_init_irq_dt(void)
+{
+	struct device_node *syscon;
+	struct clk *clk;
 
-				printk(KERN_INFO "core.c: Mapping RAM " \
-				       "%#x-%#x to device %s:%s\n",
-					res->start, res->end,
-				       platform_devs[i]->name, res->name);
-			}
-		}
+	syscon = of_find_node_by_path("/syscon@c0011000");
+	if (!syscon) {
+		pr_crit("could not find syscon node\n");
+		return;
+	}
+	syscon_base = of_iomap(syscon, 0);
+	if (!syscon_base) {
+		pr_crit("could not remap syscon\n");
+		return;
 	}
+	/* initialize clocking early, we want to clock the INTCON */
+	u300_clk_init(syscon_base);
+
+	/* Bootstrap EMIF and SEMI clocks */
+	clk = clk_get_sys("pl172", NULL);
+	BUG_ON(IS_ERR(clk));
+	clk_prepare_enable(clk);
+	clk = clk_get_sys("semi", NULL);
+	BUG_ON(IS_ERR(clk));
+	clk_prepare_enable(clk);
+
+	/* Clock the interrupt controller */
+	clk = clk_get_sys("intcon", NULL);
+	BUG_ON(IS_ERR(clk));
+	clk_prepare_enable(clk);
+
+	irqchip_init();
 }
 
-static void __init u300_init_machine(void)
+static void __init u300_init_machine_dt(void)
 {
-	int i;
 	u16 val;
 
 	/* Check what platform we run and print some status information */
 	u300_init_check_chip();
 
-	/* Initialize SPI device with some board specifics */
-	u300_spi_init(&pl022_device);
-
-	/* Register the AMBA devices in the AMBA bus abstraction layer */
-	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-		struct amba_device *d = amba_devs[i];
-		amba_device_register(d, &iomem_resource);
-	}
-
-	u300_assign_physmem();
-
 	/* Initialize pinmuxing */
 	pinctrl_register_mappings(u300_pinmux_map,
 				  ARRAY_SIZE(u300_pinmux_map));
 
-	/* Register subdevices on the I2C buses */
-	u300_i2c_register_board_devices();
-
-	/* Register the platform devices */
-	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
-
-	/* Register subdevices on the SPI bus */
-	u300_spi_register_board_devices();
+	of_platform_populate(NULL, of_default_bus_match_table,
+			u300_auxdata_lookup, NULL);
 
 	/* Enable SEMI self refresh */
-	val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
+	val = readw(syscon_base + U300_SYSCON_SMCR) |
 		U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
-	writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
+	writew(val, syscon_base + U300_SYSCON_SMCR);
 }
 
-/* Forward declare this function from the watchdog */
-void coh901327_watchdog_reset(void);
-
-static void u300_restart(char mode, const char *cmd)
-{
-	switch (mode) {
-	case 's':
-	case 'h':
-#ifdef CONFIG_COH901327_WATCHDOG
-		coh901327_watchdog_reset();
-#endif
-		break;
-	default:
-		/* Do nothing */
-		break;
-	}
-	/* Wait for system do die/reset. */
-	while (1);
-}
+static const char * u300_board_compat[] = {
+	"stericsson,u300",
+	NULL,
+};
 
-MACHINE_START(U300, "Ericsson AB U335 S335/B335 Prototype Board")
-	/* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */
-	.atag_offset	= 0x100,
+DT_MACHINE_START(U300_DT, "U300 S335/B335 (Device Tree)")
 	.map_io		= u300_map_io,
-	.nr_irqs	= 0,
-	.init_irq	= u300_init_irq,
-	.init_time	= u300_timer_init,
-	.init_machine	= u300_init_machine,
+	.init_irq	= u300_init_irq_dt,
+	.init_time	= clocksource_of_init,
+	.init_machine	= u300_init_machine_dt,
 	.restart	= u300_restart,
+	.dt_compat      = u300_board_compat,
 MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/dummyspichip.c linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/dummyspichip.c
--- linux-libre-3.10-gnu/arch/arm/mach-u300/dummyspichip.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/dummyspichip.c	2013-08-25 20:43:22.000000000 -0400
@@ -263,28 +263,22 @@ static int pl022_dummy_remove(struct spi
 	return 0;
 }
 
+static const struct of_device_id pl022_dummy_dt_match[] = {
+	{ .compatible = "arm,pl022-dummy" },
+	{},
+};
+
 static struct spi_driver pl022_dummy_driver = {
 	.driver = {
 		.name	= "spi-dummy",
 		.owner	= THIS_MODULE,
+		.of_match_table = pl022_dummy_dt_match,
 	},
 	.probe	= pl022_dummy_probe,
 	.remove	= pl022_dummy_remove,
 };
 
-static int __init pl022_init_dummy(void)
-{
-	return spi_register_driver(&pl022_dummy_driver);
-}
-
-static void __exit pl022_exit_dummy(void)
-{
-	spi_unregister_driver(&pl022_dummy_driver);
-}
-
-module_init(pl022_init_dummy);
-module_exit(pl022_exit_dummy);
-
+module_spi_driver(pl022_dummy_driver);
 MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
 MODULE_DESCRIPTION("PL022 SSP/SPI DUMMY Linux driver");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/i2c.c linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/i2c.c
--- linux-libre-3.10-gnu/arch/arm/mach-u300/i2c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/i2c.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,285 +0,0 @@
-/*
- * arch/arm/mach-u300/i2c.c
- *
- * Copyright (C) 2009-2012 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- *
- * Register board i2c devices
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/mfd/ab3100.h>
-#include <linux/regulator/machine.h>
-#include <linux/amba/bus.h>
-#include <mach/irqs.h>
-
-/*
- * Initial settings of ab3100 registers.
- * Common for below LDO regulator settings are that
- * bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0).
- * Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode.
- */
-
-/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */
-#define LDO_A_SETTING		0x16
-/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */
-#define LDO_C_SETTING		0x10
-/* LDO_D 0x10: 2.65V, ON, sleep mode not used */
-#define LDO_D_SETTING		0x10
-/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */
-#define LDO_E_SETTING		0x10
-/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */
-#define LDO_E_SLEEP_SETTING	0x00
-/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */
-#define LDO_F_SETTING		0xD0
-/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */
-#define LDO_G_SETTING		0x00
-/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */
-#define LDO_H_SETTING		0x18
-/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */
-#define LDO_K_SETTING		0x00
-/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */
-#define LDO_EXT_SETTING		0x00
-/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */
-#define BUCK_SETTING	0x7D
-/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */
-#define BUCK_SLEEP_SETTING	0xAC
-
-#ifdef CONFIG_AB3100_CORE
-static struct regulator_consumer_supply supply_ldo_c[] = {
-	{
-		.dev_name = "ab3100-codec",
-		.supply = "vaudio", /* Powers the codec */
-	},
-};
-
-/*
- * This one needs to be a supply so we can turn it off
- * in order to shut down the system.
- */
-static struct regulator_consumer_supply supply_ldo_d[] = {
-	{
-		.supply = "vana15", /* Powers the SoC (CPU etc) */
-	},
-};
-
-static struct regulator_consumer_supply supply_ldo_g[] = {
-	{
-		.dev_name = "mmci",
-		.supply = "vmmc", /* Powers MMC/SD card */
-	},
-};
-
-static struct regulator_consumer_supply supply_ldo_h[] = {
-	{
-		.dev_name = "xgam_pdi",
-		.supply = "vdisp", /* Powers camera, display etc */
-	},
-};
-
-static struct regulator_consumer_supply supply_ldo_k[] = {
-	{
-		.dev_name = "irda",
-		.supply = "vir", /* Power IrDA */
-	},
-};
-
-/*
- * This is a placeholder for whoever wish to use the
- * external power.
- */
-static struct regulator_consumer_supply supply_ldo_ext[] = {
-	{
-		.supply = "vext", /* External power */
-	},
-};
-
-/* Preset (hardware defined) voltages for these regulators */
-#define LDO_A_VOLTAGE 2750000
-#define LDO_C_VOLTAGE 2650000
-#define LDO_D_VOLTAGE 2650000
-
-static struct ab3100_platform_data ab3100_plf_data = {
-	.reg_constraints = {
-		/* LDO A routing and constraints */
-		{
-			.constraints = {
-				.name = "vrad",
-				.min_uV = LDO_A_VOLTAGE,
-				.max_uV = LDO_A_VOLTAGE,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.always_on = 1,
-				.boot_on = 1,
-			},
-		},
-		/* LDO C routing and constraints */
-		{
-			.constraints = {
-				.min_uV = LDO_C_VOLTAGE,
-				.max_uV = LDO_C_VOLTAGE,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-			},
-			.num_consumer_supplies = ARRAY_SIZE(supply_ldo_c),
-			.consumer_supplies = supply_ldo_c,
-		},
-		/* LDO D routing and constraints */
-		{
-			.constraints = {
-				.min_uV = LDO_D_VOLTAGE,
-				.max_uV = LDO_D_VOLTAGE,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.valid_ops_mask = REGULATOR_CHANGE_STATUS,
-				/*
-				 * Actually this is boot_on but we need
-				 * to reference count it externally to
-				 * be able to shut down the system.
-				 */
-			},
-			.num_consumer_supplies = ARRAY_SIZE(supply_ldo_d),
-			.consumer_supplies = supply_ldo_d,
-		},
-		/* LDO E routing and constraints */
-		{
-			.constraints = {
-				.name = "vio",
-				.min_uV = 1800000,
-				.max_uV = 1800000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.always_on = 1,
-				.boot_on = 1,
-			},
-		},
-		/* LDO F routing and constraints */
-		{
-			.constraints = {
-				.name = "vana25",
-				.min_uV = 2500000,
-				.max_uV = 2500000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.always_on = 1,
-				.boot_on = 1,
-			},
-		},
-		/* LDO G routing and constraints */
-		{
-			.constraints = {
-				.min_uV = 1500000,
-				.max_uV = 2850000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.valid_ops_mask =
-				REGULATOR_CHANGE_VOLTAGE |
-				REGULATOR_CHANGE_STATUS,
-			},
-			.num_consumer_supplies = ARRAY_SIZE(supply_ldo_g),
-			.consumer_supplies = supply_ldo_g,
-		},
-		/* LDO H routing and constraints */
-		{
-			.constraints = {
-				.min_uV = 1200000,
-				.max_uV = 2750000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.valid_ops_mask =
-				REGULATOR_CHANGE_VOLTAGE |
-				REGULATOR_CHANGE_STATUS,
-			},
-			.num_consumer_supplies = ARRAY_SIZE(supply_ldo_h),
-			.consumer_supplies = supply_ldo_h,
-		},
-		/* LDO K routing and constraints */
-		{
-			.constraints = {
-				.min_uV = 1800000,
-				.max_uV = 2750000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.valid_ops_mask =
-				REGULATOR_CHANGE_VOLTAGE |
-				REGULATOR_CHANGE_STATUS,
-			},
-			.num_consumer_supplies = ARRAY_SIZE(supply_ldo_k),
-			.consumer_supplies = supply_ldo_k,
-		},
-		/* External regulator interface. No fixed voltage specified.
-		 * If we knew the voltage of the external regulator and it
-		 * was connected on the board, we could add the (fixed)
-		 * voltage for it here.
-		 */
-		{
-			.constraints = {
-				.min_uV = 0,
-				.max_uV = 0,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.valid_ops_mask =
-				REGULATOR_CHANGE_STATUS,
-			},
-			.num_consumer_supplies = ARRAY_SIZE(supply_ldo_ext),
-			.consumer_supplies = supply_ldo_ext,
-		},
-		/* Buck converter routing and constraints */
-		{
-			.constraints = {
-				.name = "vcore",
-				.min_uV = 1200000,
-				.max_uV = 1800000,
-				.valid_modes_mask = REGULATOR_MODE_NORMAL,
-				.valid_ops_mask =
-				REGULATOR_CHANGE_VOLTAGE,
-				.always_on = 1,
-				.boot_on = 1,
-			},
-		},
-	},
-	.reg_initvals = {
-		LDO_A_SETTING,
-		LDO_C_SETTING,
-		LDO_E_SETTING,
-		LDO_E_SLEEP_SETTING,
-		LDO_F_SETTING,
-		LDO_G_SETTING,
-		LDO_H_SETTING,
-		LDO_K_SETTING,
-		LDO_EXT_SETTING,
-		BUCK_SETTING,
-		BUCK_SLEEP_SETTING,
-		LDO_D_SETTING,
-	},
-};
-#endif
-
-static struct i2c_board_info __initdata bus0_i2c_board_info[] = {
-#ifdef CONFIG_AB3100_CORE
-	{
-		.type = "ab3100",
-		.addr = 0x48,
-		.irq = IRQ_U300_IRQ0_EXT,
-		.platform_data = &ab3100_plf_data,
-	},
-#else
-	{ },
-#endif
-};
-
-static struct i2c_board_info __initdata bus1_i2c_board_info[] = {
-	{
-		.type = "fwcam",
-		.addr = 0x10,
-	},
-	{
-		.type = "fwcam",
-		.addr = 0x5d,
-	},
-};
-
-void __init u300_i2c_register_board_devices(void)
-{
-	i2c_register_board_info(0, bus0_i2c_board_info,
-				ARRAY_SIZE(bus0_i2c_board_info));
-	/*
-	 * This makes the core shut down all unused regulators
-	 * after all the initcalls have completed.
-	 */
-	regulator_has_full_constraints();
-	i2c_register_board_info(1, bus1_i2c_board_info,
-				ARRAY_SIZE(bus1_i2c_board_info));
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/i2c.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/i2c.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/i2c.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/i2c.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * arch/arm/mach-u300/i2c.h
- *
- * Copyright (C) 2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- *
- * Register board i2c devices
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-
-#ifndef MACH_U300_I2C_H
-#define MACH_U300_I2C_H
-
-#ifdef CONFIG_I2C_STU300
-void __init u300_i2c_register_board_devices(void);
-#else
-/* Compile out this stuff if no I2C adapter is available */
-static inline void __init u300_i2c_register_board_devices(void)
-{
-}
-#endif
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/debug-macro.S linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/debug-macro.S
--- linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/debug-macro.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-/*
- *
- * arch-arm/mach-u300/include/mach/debug-macro.S
- *
- *
- * Copyright (C) 2006-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * Debugging macro include header.
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-#include <mach/hardware.h>
-
-	.macro	addruart, rp, rv, tmp
-	/* If we move the address using MMU, use this. */
-	ldr	\rp,	  = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address
-	ldr	\rv,	  = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address
-	orr	\rp, \rp, #0x00003000
-	orr	\rv, \rv, #0x00003000
-	.endm
-
-#include <asm/hardware/debug-pl01x.S>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/hardware.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/hardware.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/hardware.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,5 +0,0 @@
-/*
- * arch/arm/mach-u300/include/mach/hardware.h
- */
-#include <asm/sizes.h>
-#include <mach/u300-regs.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/irqs.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/irqs.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/irqs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,80 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/include/mach/irqs.h
- *
- *
- * Copyright (C) 2006-2012 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * IRQ channel definitions for the U300 platforms.
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-
-#ifndef __MACH_IRQS_H
-#define __MACH_IRQS_H
-
-#define IRQ_U300_INTCON0_START		32
-#define IRQ_U300_INTCON1_START		64
-/* These are on INTCON0 - 30 lines */
-#define IRQ_U300_IRQ0_EXT		32
-#define IRQ_U300_IRQ1_EXT		33
-#define IRQ_U300_DMA			34
-#define IRQ_U300_VIDEO_ENC_0		35
-#define IRQ_U300_VIDEO_ENC_1		36
-#define IRQ_U300_AAIF_RX		37
-#define IRQ_U300_AAIF_TX		38
-#define IRQ_U300_AAIF_VGPIO		39
-#define IRQ_U300_AAIF_WAKEUP		40
-#define IRQ_U300_PCM_I2S0_FRAME		41
-#define IRQ_U300_PCM_I2S0_FIFO		42
-#define IRQ_U300_PCM_I2S1_FRAME		43
-#define IRQ_U300_PCM_I2S1_FIFO		44
-#define IRQ_U300_XGAM_GAMCON		45
-#define IRQ_U300_XGAM_CDI		46
-#define IRQ_U300_XGAM_CDICON		47
-#define IRQ_U300_XGAM_PDI		49
-#define IRQ_U300_XGAM_PDICON		50
-#define IRQ_U300_XGAM_GAMEACC		51
-#define IRQ_U300_XGAM_MCIDCT		52
-#define IRQ_U300_APEX			53
-#define IRQ_U300_UART0			54
-#define IRQ_U300_SPI			55
-#define IRQ_U300_TIMER_APP_OS		56
-#define IRQ_U300_TIMER_APP_DD		57
-#define IRQ_U300_TIMER_APP_GP1		58
-#define IRQ_U300_TIMER_APP_GP2		59
-#define IRQ_U300_TIMER_OS		60
-#define IRQ_U300_TIMER_MS		61
-#define IRQ_U300_KEYPAD_KEYBF		62
-#define IRQ_U300_KEYPAD_KEYBR		63
-/* These are on INTCON1 - 32 lines */
-#define IRQ_U300_GPIO_PORT0		64
-#define IRQ_U300_GPIO_PORT1		65
-#define IRQ_U300_GPIO_PORT2		66
-
-/* These are for DB3150, DB3200 and DB3350 */
-#define IRQ_U300_WDOG			67
-#define IRQ_U300_EVHIST			68
-#define IRQ_U300_MSPRO			69
-#define IRQ_U300_MMCSD_MCIINTR0		70
-#define IRQ_U300_MMCSD_MCIINTR1		71
-#define IRQ_U300_I2C0			72
-#define IRQ_U300_I2C1			73
-#define IRQ_U300_RTC			74
-#define IRQ_U300_NFIF			75
-#define IRQ_U300_NFIF2			76
-
-/* The DB3350-specific interrupt lines */
-#define IRQ_U300_ISP_F0			77
-#define IRQ_U300_ISP_F1			78
-#define IRQ_U300_ISP_F2			79
-#define IRQ_U300_ISP_F3			80
-#define IRQ_U300_ISP_F4			81
-#define IRQ_U300_GPIO_PORT3		82
-#define IRQ_U300_SYSCON_PLL_LOCK	83
-#define IRQ_U300_UART1			84
-#define IRQ_U300_GPIO_PORT4		85
-#define IRQ_U300_GPIO_PORT5		86
-#define IRQ_U300_GPIO_PORT6		87
-#define U300_VIC_IRQS_END		88
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/syscon.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/syscon.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/syscon.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/syscon.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,592 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/include/mach/syscon.h
- *
- *
- * Copyright (C) 2008-2012 ST-Ericsson AB
- *
- * Author: Rickard Andersson <rickard.andersson@stericsson.com>
- */
-
-#ifndef __MACH_SYSCON_H
-#define __MACH_SYSCON_H
-
-/*
- * All register defines for SYSCON registers that concerns individual
- * block clocks and reset lines are registered here. This is because
- * we don't want any other file to try to fool around with this stuff.
- */
-
-/* APP side SYSCON registers */
-/* TODO: this is incomplete. Add all from asic_syscon_map.h eventually. */
-/* CLK Control Register 16bit (R/W) */
-#define U300_SYSCON_CCR						(0x0000)
-#define U300_SYSCON_CCR_I2S1_USE_VCXO				(0x0040)
-#define U300_SYSCON_CCR_I2S0_USE_VCXO				(0x0020)
-#define U300_SYSCON_CCR_TURN_VCXO_ON				(0x0008)
-#define U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK			(0x0007)
-#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER		(0x04)
-#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW			(0x03)
-#define U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE		(0x02)
-#define U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH			(0x01)
-#define U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST			(0x00)
-/* CLK Status Register 16bit (R/W) */
-#define U300_SYSCON_CSR						(0x0004)
-#define U300_SYSCON_CSR_PLL208_LOCK_IND				(0x0002)
-#define U300_SYSCON_CSR_PLL13_LOCK_IND				(0x0001)
-/* Reset lines for SLOW devices 16bit (R/W) */
-#define U300_SYSCON_RSR						(0x0014)
-#define U300_SYSCON_RSR_PPM_RESET_EN				(0x0200)
-#define U300_SYSCON_RSR_ACC_TMR_RESET_EN			(0x0100)
-#define U300_SYSCON_RSR_APP_TMR_RESET_EN			(0x0080)
-#define U300_SYSCON_RSR_RTC_RESET_EN				(0x0040)
-#define U300_SYSCON_RSR_KEYPAD_RESET_EN				(0x0020)
-#define U300_SYSCON_RSR_GPIO_RESET_EN				(0x0010)
-#define U300_SYSCON_RSR_EH_RESET_EN				(0x0008)
-#define U300_SYSCON_RSR_BTR_RESET_EN				(0x0004)
-#define U300_SYSCON_RSR_UART_RESET_EN				(0x0002)
-#define U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN			(0x0001)
-/* Reset lines for FAST devices 16bit (R/W) */
-#define U300_SYSCON_RFR						(0x0018)
-#define U300_SYSCON_RFR_UART1_RESET_ENABLE			(0x0080)
-#define U300_SYSCON_RFR_SPI_RESET_ENABLE			(0x0040)
-#define U300_SYSCON_RFR_MMC_RESET_ENABLE			(0x0020)
-#define U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE			(0x0010)
-#define U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE			(0x0008)
-#define U300_SYSCON_RFR_I2C1_RESET_ENABLE			(0x0004)
-#define U300_SYSCON_RFR_I2C0_RESET_ENABLE			(0x0002)
-#define U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE		(0x0001)
-/* Reset lines for the rest of the peripherals 16bit (R/W) */
-#define U300_SYSCON_RRR						(0x001c)
-#define U300_SYSCON_RRR_CDS_RESET_EN				(0x4000)
-#define U300_SYSCON_RRR_ISP_RESET_EN				(0x2000)
-#define U300_SYSCON_RRR_INTCON_RESET_EN				(0x1000)
-#define U300_SYSCON_RRR_MSPRO_RESET_EN				(0x0800)
-#define U300_SYSCON_RRR_XGAM_RESET_EN				(0x0100)
-#define U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN			(0x0080)
-#define U300_SYSCON_RRR_NANDIF_RESET_EN				(0x0040)
-#define U300_SYSCON_RRR_EMIF_RESET_EN				(0x0020)
-#define U300_SYSCON_RRR_DMAC_RESET_EN				(0x0010)
-#define U300_SYSCON_RRR_CPU_RESET_EN				(0x0008)
-#define U300_SYSCON_RRR_APEX_RESET_EN				(0x0004)
-#define U300_SYSCON_RRR_AHB_RESET_EN				(0x0002)
-#define U300_SYSCON_RRR_AAIF_RESET_EN				(0x0001)
-/* Clock enable for SLOW peripherals 16bit (R/W) */
-#define U300_SYSCON_CESR					(0x0020)
-#define U300_SYSCON_CESR_PPM_CLK_EN				(0x0200)
-#define U300_SYSCON_CESR_ACC_TMR_CLK_EN				(0x0100)
-#define U300_SYSCON_CESR_APP_TMR_CLK_EN				(0x0080)
-#define U300_SYSCON_CESR_KEYPAD_CLK_EN				(0x0040)
-#define U300_SYSCON_CESR_GPIO_CLK_EN				(0x0010)
-#define U300_SYSCON_CESR_EH_CLK_EN				(0x0008)
-#define U300_SYSCON_CESR_BTR_CLK_EN				(0x0004)
-#define U300_SYSCON_CESR_UART_CLK_EN				(0x0002)
-#define U300_SYSCON_CESR_SLOW_BRIDGE_CLK_EN			(0x0001)
-/* Clock enable for FAST peripherals 16bit (R/W) */
-#define U300_SYSCON_CEFR					(0x0024)
-#define U300_SYSCON_CEFR_UART1_CLK_EN				(0x0200)
-#define U300_SYSCON_CEFR_I2S1_CORE_CLK_EN			(0x0100)
-#define U300_SYSCON_CEFR_I2S0_CORE_CLK_EN			(0x0080)
-#define U300_SYSCON_CEFR_SPI_CLK_EN				(0x0040)
-#define U300_SYSCON_CEFR_MMC_CLK_EN				(0x0020)
-#define U300_SYSCON_CEFR_I2S1_CLK_EN				(0x0010)
-#define U300_SYSCON_CEFR_I2S0_CLK_EN				(0x0008)
-#define U300_SYSCON_CEFR_I2C1_CLK_EN				(0x0004)
-#define U300_SYSCON_CEFR_I2C0_CLK_EN				(0x0002)
-#define U300_SYSCON_CEFR_FAST_BRIDGE_CLK_EN			(0x0001)
-/* Clock enable for the rest of the peripherals 16bit (R/W) */
-#define U300_SYSCON_CERR					(0x0028)
-#define U300_SYSCON_CERR_CDS_CLK_EN				(0x2000)
-#define U300_SYSCON_CERR_ISP_CLK_EN				(0x1000)
-#define U300_SYSCON_CERR_MSPRO_CLK_EN				(0x0800)
-#define U300_SYSCON_CERR_AHB_SUBSYS_BRIDGE_CLK_EN		(0x0400)
-#define U300_SYSCON_CERR_SEMI_CLK_EN				(0x0200)
-#define U300_SYSCON_CERR_XGAM_CLK_EN				(0x0100)
-#define U300_SYSCON_CERR_VIDEO_ENC_CLK_EN			(0x0080)
-#define U300_SYSCON_CERR_NANDIF_CLK_EN				(0x0040)
-#define U300_SYSCON_CERR_EMIF_CLK_EN				(0x0020)
-#define U300_SYSCON_CERR_DMAC_CLK_EN				(0x0010)
-#define U300_SYSCON_CERR_CPU_CLK_EN				(0x0008)
-#define U300_SYSCON_CERR_APEX_CLK_EN				(0x0004)
-#define U300_SYSCON_CERR_AHB_CLK_EN				(0x0002)
-#define U300_SYSCON_CERR_AAIF_CLK_EN				(0x0001)
-/* Single block clock enable 16bit (-/W) */
-#define U300_SYSCON_SBCER					(0x002c)
-#define U300_SYSCON_SBCER_PPM_CLK_EN				(0x0009)
-#define U300_SYSCON_SBCER_ACC_TMR_CLK_EN			(0x0008)
-#define U300_SYSCON_SBCER_APP_TMR_CLK_EN			(0x0007)
-#define U300_SYSCON_SBCER_KEYPAD_CLK_EN				(0x0006)
-#define U300_SYSCON_SBCER_GPIO_CLK_EN				(0x0004)
-#define U300_SYSCON_SBCER_EH_CLK_EN				(0x0003)
-#define U300_SYSCON_SBCER_BTR_CLK_EN				(0x0002)
-#define U300_SYSCON_SBCER_UART_CLK_EN				(0x0001)
-#define U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN			(0x0000)
-#define U300_SYSCON_SBCER_UART1_CLK_EN				(0x0019)
-#define U300_SYSCON_SBCER_I2S1_CORE_CLK_EN			(0x0018)
-#define U300_SYSCON_SBCER_I2S0_CORE_CLK_EN			(0x0017)
-#define U300_SYSCON_SBCER_SPI_CLK_EN				(0x0016)
-#define U300_SYSCON_SBCER_MMC_CLK_EN				(0x0015)
-#define U300_SYSCON_SBCER_I2S1_CLK_EN				(0x0014)
-#define U300_SYSCON_SBCER_I2S0_CLK_EN				(0x0013)
-#define U300_SYSCON_SBCER_I2C1_CLK_EN				(0x0012)
-#define U300_SYSCON_SBCER_I2C0_CLK_EN				(0x0011)
-#define U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN			(0x0010)
-#define U300_SYSCON_SBCER_CDS_CLK_EN				(0x002D)
-#define U300_SYSCON_SBCER_ISP_CLK_EN				(0x002C)
-#define U300_SYSCON_SBCER_MSPRO_CLK_EN				(0x002B)
-#define U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN		(0x002A)
-#define U300_SYSCON_SBCER_SEMI_CLK_EN				(0x0029)
-#define U300_SYSCON_SBCER_XGAM_CLK_EN				(0x0028)
-#define U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN			(0x0027)
-#define U300_SYSCON_SBCER_NANDIF_CLK_EN				(0x0026)
-#define U300_SYSCON_SBCER_EMIF_CLK_EN				(0x0025)
-#define U300_SYSCON_SBCER_DMAC_CLK_EN				(0x0024)
-#define U300_SYSCON_SBCER_CPU_CLK_EN				(0x0023)
-#define U300_SYSCON_SBCER_APEX_CLK_EN				(0x0022)
-#define U300_SYSCON_SBCER_AHB_CLK_EN				(0x0021)
-#define U300_SYSCON_SBCER_AAIF_CLK_EN				(0x0020)
-/* Single block clock disable 16bit (-/W) */
-#define U300_SYSCON_SBCDR					(0x0030)
-/* Same values as above for SBCER */
-/* Clock force SLOW peripherals 16bit (R/W) */
-#define U300_SYSCON_CFSR					(0x003c)
-#define U300_SYSCON_CFSR_PPM_CLK_FORCE_EN			(0x0200)
-#define U300_SYSCON_CFSR_ACC_TMR_CLK_FORCE_EN			(0x0100)
-#define U300_SYSCON_CFSR_APP_TMR_CLK_FORCE_EN			(0x0080)
-#define U300_SYSCON_CFSR_KEYPAD_CLK_FORCE_EN			(0x0020)
-#define U300_SYSCON_CFSR_GPIO_CLK_FORCE_EN			(0x0010)
-#define U300_SYSCON_CFSR_EH_CLK_FORCE_EN			(0x0008)
-#define U300_SYSCON_CFSR_BTR_CLK_FORCE_EN			(0x0004)
-#define U300_SYSCON_CFSR_UART_CLK_FORCE_EN			(0x0002)
-#define U300_SYSCON_CFSR_SLOW_BRIDGE_CLK_FORCE_EN		(0x0001)
-/* Clock force FAST peripherals 16bit (R/W) */
-#define U300_SYSCON_CFFR					(0x40)
-/* Values not defined. Define if you want to use them. */
-/* Clock force the rest of the peripherals 16bit (R/W) */
-#define U300_SYSCON_CFRR					(0x44)
-#define U300_SYSCON_CFRR_CDS_CLK_FORCE_EN			(0x2000)
-#define U300_SYSCON_CFRR_ISP_CLK_FORCE_EN			(0x1000)
-#define U300_SYSCON_CFRR_MSPRO_CLK_FORCE_EN			(0x0800)
-#define U300_SYSCON_CFRR_AHB_SUBSYS_BRIDGE_CLK_FORCE_EN		(0x0400)
-#define U300_SYSCON_CFRR_SEMI_CLK_FORCE_EN			(0x0200)
-#define U300_SYSCON_CFRR_XGAM_CLK_FORCE_EN			(0x0100)
-#define U300_SYSCON_CFRR_VIDEO_ENC_CLK_FORCE_EN			(0x0080)
-#define U300_SYSCON_CFRR_NANDIF_CLK_FORCE_EN			(0x0040)
-#define U300_SYSCON_CFRR_EMIF_CLK_FORCE_EN			(0x0020)
-#define U300_SYSCON_CFRR_DMAC_CLK_FORCE_EN			(0x0010)
-#define U300_SYSCON_CFRR_CPU_CLK_FORCE_EN			(0x0008)
-#define U300_SYSCON_CFRR_APEX_CLK_FORCE_EN			(0x0004)
-#define U300_SYSCON_CFRR_AHB_CLK_FORCE_EN			(0x0002)
-#define U300_SYSCON_CFRR_AAIF_CLK_FORCE_EN			(0x0001)
-/* PLL208 Frequency Control 16bit (R/W) */
-#define U300_SYSCON_PFCR					(0x48)
-#define U300_SYSCON_PFCR_DPLL_MULT_NUM				(0x000F)
-/* Power Management Control 16bit (R/W) */
-#define U300_SYSCON_PMCR					(0x50)
-#define U300_SYSCON_PMCR_DCON_ENABLE				(0x0002)
-#define U300_SYSCON_PMCR_PWR_MGNT_ENABLE			(0x0001)
-/*
- * All other clocking registers moved to clock.c!
- */
-/* Reset Out 16bit (R/W) */
-#define U300_SYSCON_RCR						(0x6c)
-#define U300_SYSCON_RCR_RESOUT0_RST_N_DISABLE			(0x0001)
-/* EMIF Slew Rate Control 16bit (R/W) */
-#define U300_SYSCON_SRCLR					(0x70)
-#define U300_SYSCON_SRCLR_MASK					(0x03FF)
-#define U300_SYSCON_SRCLR_VALUE					(0x03FF)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_B			(0x0200)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_A			(0x0100)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_B			(0x0080)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_A			(0x0040)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_B			(0x0020)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_A			(0x0010)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_B			(0x0008)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_A			(0x0004)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_B			(0x0002)
-#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_A			(0x0001)
-/* EMIF Clock Control Register 16bit (R/W) */
-#define U300_SYSCON_ECCR					(0x0078)
-#define U300_SYSCON_ECCR_MASK					(0x000F)
-#define U300_SYSCON_ECCR_EMIF_1_STATIC_CLK_EN_N_DISABLE		(0x0008)
-#define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE	(0x0004)
-#define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE		(0x0002)
-#define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE		(0x0001)
-/* Step one for killing the applications system 16bit (-/W) */
-#define U300_SYSCON_KA1R					(0x0080)
-#define U300_SYSCON_KA1R_MASK					(0xFFFF)
-#define U300_SYSCON_KA1R_VALUE					(0xFFFF)
-/* Step two for killing the application system 16bit (-/W) */
-#define U300_SYSCON_KA2R					(0x0084)
-#define U300_SYSCON_KA2R_MASK					(0xFFFF)
-#define U300_SYSCON_KA2R_VALUE					(0xFFFF)
-/* MMC/MSPRO frequency divider register 0 16bit (R/W) */
-#define U300_SYSCON_MMF0R					(0x90)
-#define U300_SYSCON_MMF0R_MASK					(0x00FF)
-#define U300_SYSCON_MMF0R_FREQ_0_HIGH_MASK			(0x00F0)
-#define U300_SYSCON_MMF0R_FREQ_0_LOW_MASK			(0x000F)
-/* MMC/MSPRO frequency divider register 1 16bit (R/W) */
-#define U300_SYSCON_MMF1R					(0x94)
-#define U300_SYSCON_MMF1R_MASK					(0x00FF)
-#define U300_SYSCON_MMF1R_FREQ_1_HIGH_MASK			(0x00F0)
-#define U300_SYSCON_MMF1R_FREQ_1_LOW_MASK			(0x000F)
-/* AAIF control register 16 bit (R/W) */
-#define U300_SYSCON_AAIFCR					(0x98)
-#define U300_SYSCON_AAIFCR_MASK					(0x0003)
-#define U300_SYSCON_AAIFCR_AASW_CTRL_MASK			(0x0003)
-#define U300_SYSCON_AAIFCR_AASW_CTRL_FUNCTIONAL			(0x0000)
-#define U300_SYSCON_AAIFCR_AASW_CTRL_MONITORING			(0x0001)
-#define U300_SYSCON_AAIFCR_AASW_CTRL_ACC_TO_EXT			(0x0002)
-#define U300_SYSCON_AAIFCR_AASW_CTRL_APP_TO_EXT			(0x0003)
-/* Clock control for the MMC and MSPRO blocks 16bit (R/W) */
-#define U300_SYSCON_MMCR					(0x9C)
-#define U300_SYSCON_MMCR_MASK					(0x0003)
-#define U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE			(0x0002)
-#define U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE			(0x0001)
-/* Pull up/down control (R/W) */
-#define U300_SYSCON_PUCR					(0x104)
-#define U300_SYSCON_PUCR_EMIF_1_WAIT_N_PU_ENABLE		(0x0200)
-#define U300_SYSCON_PUCR_EMIF_1_NFIF_READY_PU_ENABLE		(0x0100)
-#define U300_SYSCON_PUCR_EMIF_1_16BIT_PU_ENABLE			(0x0080)
-#define U300_SYSCON_PUCR_EMIF_1_8BIT_PU_ENABLE			(0x0040)
-#define U300_SYSCON_PUCR_KEY_IN_PU_EN_MASK			(0x003F)
-/* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */
-#define U300_SYSCON_S0CCR					(0x120)
-#define U300_SYSCON_S0CCR_FIELD_MASK				(0x43FF)
-#define U300_SYSCON_S0CCR_CLOCK_REQ				(0x4000)
-#define U300_SYSCON_S0CCR_CLOCK_REQ_MONITOR			(0x2000)
-#define U300_SYSCON_S0CCR_CLOCK_INV				(0x0200)
-#define U300_SYSCON_S0CCR_CLOCK_FREQ_MASK			(0x01E0)
-#define U300_SYSCON_S0CCR_CLOCK_SELECT_MASK			(0x001E)
-#define U300_SYSCON_S0CCR_CLOCK_ENABLE				(0x0001)
-#define U300_SYSCON_S0CCR_SEL_MCLK				(0x8<<1)
-#define U300_SYSCON_S0CCR_SEL_ACC_FSM_CLK			(0xA<<1)
-#define U300_SYSCON_S0CCR_SEL_PLL60_48_CLK			(0xC<<1)
-#define U300_SYSCON_S0CCR_SEL_PLL60_60_CLK			(0xD<<1)
-#define U300_SYSCON_S0CCR_SEL_ACC_PLL208_CLK			(0xE<<1)
-#define U300_SYSCON_S0CCR_SEL_APP_PLL13_CLK			(0x0<<1)
-#define U300_SYSCON_S0CCR_SEL_APP_FSM_CLK			(0x2<<1)
-#define U300_SYSCON_S0CCR_SEL_RTC_CLK				(0x4<<1)
-#define U300_SYSCON_S0CCR_SEL_APP_PLL208_CLK			(0x6<<1)
-/* SYS_1_CLK_CONTROL second clock control 16 bit (R/W) */
-#define U300_SYSCON_S1CCR					(0x124)
-#define U300_SYSCON_S1CCR_FIELD_MASK				(0x43FF)
-#define U300_SYSCON_S1CCR_CLOCK_REQ				(0x4000)
-#define U300_SYSCON_S1CCR_CLOCK_REQ_MONITOR			(0x2000)
-#define U300_SYSCON_S1CCR_CLOCK_INV				(0x0200)
-#define U300_SYSCON_S1CCR_CLOCK_FREQ_MASK			(0x01E0)
-#define U300_SYSCON_S1CCR_CLOCK_SELECT_MASK			(0x001E)
-#define U300_SYSCON_S1CCR_CLOCK_ENABLE				(0x0001)
-#define U300_SYSCON_S1CCR_SEL_MCLK				(0x8<<1)
-#define U300_SYSCON_S1CCR_SEL_ACC_FSM_CLK			(0xA<<1)
-#define U300_SYSCON_S1CCR_SEL_PLL60_48_CLK			(0xC<<1)
-#define U300_SYSCON_S1CCR_SEL_PLL60_60_CLK			(0xD<<1)
-#define U300_SYSCON_S1CCR_SEL_ACC_PLL208_CLK			(0xE<<1)
-#define U300_SYSCON_S1CCR_SEL_ACC_PLL13_CLK			(0x0<<1)
-#define U300_SYSCON_S1CCR_SEL_APP_FSM_CLK			(0x2<<1)
-#define U300_SYSCON_S1CCR_SEL_RTC_CLK				(0x4<<1)
-#define U300_SYSCON_S1CCR_SEL_APP_PLL208_CLK			(0x6<<1)
-/* SYS_2_CLK_CONTROL third clock contol 16 bit (R/W) */
-#define U300_SYSCON_S2CCR					(0x128)
-#define U300_SYSCON_S2CCR_FIELD_MASK				(0xC3FF)
-#define U300_SYSCON_S2CCR_CLK_STEAL				(0x8000)
-#define U300_SYSCON_S2CCR_CLOCK_REQ				(0x4000)
-#define U300_SYSCON_S2CCR_CLOCK_REQ_MONITOR			(0x2000)
-#define U300_SYSCON_S2CCR_CLOCK_INV				(0x0200)
-#define U300_SYSCON_S2CCR_CLOCK_FREQ_MASK			(0x01E0)
-#define U300_SYSCON_S2CCR_CLOCK_SELECT_MASK			(0x001E)
-#define U300_SYSCON_S2CCR_CLOCK_ENABLE				(0x0001)
-#define U300_SYSCON_S2CCR_SEL_MCLK				(0x8<<1)
-#define U300_SYSCON_S2CCR_SEL_ACC_FSM_CLK			(0xA<<1)
-#define U300_SYSCON_S2CCR_SEL_PLL60_48_CLK			(0xC<<1)
-#define U300_SYSCON_S2CCR_SEL_PLL60_60_CLK			(0xD<<1)
-#define U300_SYSCON_S2CCR_SEL_ACC_PLL208_CLK			(0xE<<1)
-#define U300_SYSCON_S2CCR_SEL_ACC_PLL13_CLK			(0x0<<1)
-#define U300_SYSCON_S2CCR_SEL_APP_FSM_CLK			(0x2<<1)
-#define U300_SYSCON_S2CCR_SEL_RTC_CLK				(0x4<<1)
-#define U300_SYSCON_S2CCR_SEL_APP_PLL208_CLK			(0x6<<1)
-/* SYS_MISC_CONTROL, miscellaneous 16bit (R/W) */
-#define U300_SYSCON_MCR						(0x12c)
-#define U300_SYSCON_MCR_FIELD_MASK				(0x00FF)
-#define U300_SYSCON_MCR_PMGEN_CR_4_MASK				(0x00C0)
-#define U300_SYSCON_MCR_PMGEN_CR_4_GPIO				(0x0000)
-#define U300_SYSCON_MCR_PMGEN_CR_4_SPI				(0x0040)
-#define U300_SYSCON_MCR_PMGEN_CR_4_AAIF				(0x00C0)
-#define U300_SYSCON_MCR_PMGEN_CR_2_MASK				(0x0030)
-#define U300_SYSCON_MCR_PMGEN_CR_2_GPIO				(0x0000)
-#define U300_SYSCON_MCR_PMGEN_CR_2_EMIF_1_STATIC		(0x0010)
-#define U300_SYSCON_MCR_PMGEN_CR_2_DSP				(0x0020)
-#define U300_SYSCON_MCR_PMGEN_CR_2_AAIF				(0x0030)
-#define U300_SYSCON_MCR_PMGEN_CR_0_MASK				(0x000C)
-#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M1		(0x0000)
-#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M2		(0x0004)
-#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M3		(0x0008)
-#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_0_SDRAM			(0x000C)
-#define U300_SYSCON_MCR_PM1G_MODE_ENABLE			(0x0002)
-#define U300_SYSCON_MCR_PMTG5_MODE_ENABLE			(0x0001)
-/* SC_PLL_IRQ_CONTROL 16bit (R/W) */
-#define U300_SYSCON_PICR					(0x0130)
-#define U300_SYSCON_PICR_MASK					(0x00FF)
-#define U300_SYSCON_PICR_FORCE_PLL208_LOCK_LOW_ENABLE		(0x0080)
-#define U300_SYSCON_PICR_FORCE_PLL208_LOCK_HIGH_ENABLE		(0x0040)
-#define U300_SYSCON_PICR_FORCE_PLL13_LOCK_LOW_ENABLE		(0x0020)
-#define U300_SYSCON_PICR_FORCE_PLL13_LOCK_HIGH_ENABLE		(0x0010)
-#define U300_SYSCON_PICR_IRQMASK_PLL13_UNLOCK_ENABLE		(0x0008)
-#define U300_SYSCON_PICR_IRQMASK_PLL13_LOCK_ENABLE		(0x0004)
-#define U300_SYSCON_PICR_IRQMASK_PLL208_UNLOCK_ENABLE		(0x0002)
-#define U300_SYSCON_PICR_IRQMASK_PLL208_LOCK_ENABLE		(0x0001)
-/* SC_PLL_IRQ_STATUS 16 bit (R/-) */
-#define U300_SYSCON_PISR					(0x0134)
-#define U300_SYSCON_PISR_MASK					(0x000F)
-#define U300_SYSCON_PISR_PLL13_UNLOCK_IND			(0x0008)
-#define U300_SYSCON_PISR_PLL13_LOCK_IND				(0x0004)
-#define U300_SYSCON_PISR_PLL208_UNLOCK_IND			(0x0002)
-#define U300_SYSCON_PISR_PLL208_LOCK_IND			(0x0001)
-/* SC_PLL_IRQ_CLEAR 16 bit (-/W) */
-#define U300_SYSCON_PICLR					(0x0138)
-#define U300_SYSCON_PICLR_MASK					(0x000F)
-#define U300_SYSCON_PICLR_RWMASK				(0x0000)
-#define U300_SYSCON_PICLR_PLL13_UNLOCK_SC			(0x0008)
-#define U300_SYSCON_PICLR_PLL13_LOCK_SC				(0x0004)
-#define U300_SYSCON_PICLR_PLL208_UNLOCK_SC			(0x0002)
-#define U300_SYSCON_PICLR_PLL208_LOCK_SC			(0x0001)
-/* CAMIF_CONTROL 16 bit (-/W) */
-#define U300_SYSCON_CICR					(0x013C)
-#define U300_SYSCON_CICR_MASK					(0x0FFF)
-#define U300_SYSCON_CICR_APP_SUBLVDS_TESTMODE_MASK		(0x0F00)
-#define U300_SYSCON_CICR_APP_SUBLVDS_TESTMODE_PORT1		(0x0C00)
-#define U300_SYSCON_CICR_APP_SUBLVDS_TESTMODE_PORT0		(0x0300)
-#define U300_SYSCON_CICR_APP_SUBLVDS_RESCON_MASK		(0x00F0)
-#define U300_SYSCON_CICR_APP_SUBLVDS_RESCON_PORT1		(0x00C0)
-#define U300_SYSCON_CICR_APP_SUBLVDS_RESCON_PORT0		(0x0030)
-#define U300_SYSCON_CICR_APP_SUBLVDS_PWR_DWN_N_MASK		(0x000F)
-#define U300_SYSCON_CICR_APP_SUBLVDS_PWR_DWN_N_PORT1		(0x000C)
-#define U300_SYSCON_CICR_APP_SUBLVDS_PWR_DWN_N_PORT0		(0x0003)
-/* Clock activity observability register 0 */
-#define U300_SYSCON_C0OAR					(0x140)
-#define U300_SYSCON_C0OAR_MASK					(0xFFFF)
-#define U300_SYSCON_C0OAR_VALUE					(0xFFFF)
-#define U300_SYSCON_C0OAR_BT_H_CLK				(0x8000)
-#define U300_SYSCON_C0OAR_ASPB_P_CLK				(0x4000)
-#define U300_SYSCON_C0OAR_APP_SEMI_H_CLK			(0x2000)
-#define U300_SYSCON_C0OAR_APP_SEMI_CLK				(0x1000)
-#define U300_SYSCON_C0OAR_APP_MMC_MSPRO_CLK			(0x0800)
-#define U300_SYSCON_C0OAR_APP_I2S1_CLK				(0x0400)
-#define U300_SYSCON_C0OAR_APP_I2S0_CLK				(0x0200)
-#define U300_SYSCON_C0OAR_APP_CPU_CLK				(0x0100)
-#define U300_SYSCON_C0OAR_APP_52_CLK				(0x0080)
-#define U300_SYSCON_C0OAR_APP_208_CLK				(0x0040)
-#define U300_SYSCON_C0OAR_APP_104_CLK				(0x0020)
-#define U300_SYSCON_C0OAR_APEX_CLK				(0x0010)
-#define U300_SYSCON_C0OAR_AHPB_M_H_CLK				(0x0008)
-#define U300_SYSCON_C0OAR_AHB_CLK				(0x0004)
-#define U300_SYSCON_C0OAR_AFPB_P_CLK				(0x0002)
-#define U300_SYSCON_C0OAR_AAIF_CLK				(0x0001)
-/* Clock activity observability register 1 */
-#define U300_SYSCON_C1OAR					(0x144)
-#define U300_SYSCON_C1OAR_MASK					(0x3FFE)
-#define U300_SYSCON_C1OAR_VALUE					(0x3FFE)
-#define U300_SYSCON_C1OAR_NFIF_F_CLK				(0x2000)
-#define U300_SYSCON_C1OAR_MSPRO_CLK				(0x1000)
-#define U300_SYSCON_C1OAR_MMC_P_CLK				(0x0800)
-#define U300_SYSCON_C1OAR_MMC_CLK				(0x0400)
-#define U300_SYSCON_C1OAR_KP_P_CLK				(0x0200)
-#define U300_SYSCON_C1OAR_I2C1_P_CLK				(0x0100)
-#define U300_SYSCON_C1OAR_I2C0_P_CLK				(0x0080)
-#define U300_SYSCON_C1OAR_GPIO_CLK				(0x0040)
-#define U300_SYSCON_C1OAR_EMIF_MPMC_CLK				(0x0020)
-#define U300_SYSCON_C1OAR_EMIF_H_CLK				(0x0010)
-#define U300_SYSCON_C1OAR_EVHIST_CLK				(0x0008)
-#define U300_SYSCON_C1OAR_PPM_CLK				(0x0004)
-#define U300_SYSCON_C1OAR_DMA_CLK				(0x0002)
-/* Clock activity observability register 2 */
-#define U300_SYSCON_C2OAR					(0x148)
-#define U300_SYSCON_C2OAR_MASK					(0x0FFF)
-#define U300_SYSCON_C2OAR_VALUE					(0x0FFF)
-#define U300_SYSCON_C2OAR_XGAM_CDI_CLK				(0x0800)
-#define U300_SYSCON_C2OAR_XGAM_CLK				(0x0400)
-#define U300_SYSCON_C2OAR_VC_H_CLK				(0x0200)
-#define U300_SYSCON_C2OAR_VC_CLK				(0x0100)
-#define U300_SYSCON_C2OAR_UA_P_CLK				(0x0080)
-#define U300_SYSCON_C2OAR_TMR1_CLK				(0x0040)
-#define U300_SYSCON_C2OAR_TMR0_CLK				(0x0020)
-#define U300_SYSCON_C2OAR_SPI_P_CLK				(0x0010)
-#define U300_SYSCON_C2OAR_PCM_I2S1_CORE_CLK			(0x0008)
-#define U300_SYSCON_C2OAR_PCM_I2S1_CLK				(0x0004)
-#define U300_SYSCON_C2OAR_PCM_I2S0_CORE_CLK			(0x0002)
-#define U300_SYSCON_C2OAR_PCM_I2S0_CLK				(0x0001)
-
-/* Chip ID register 16bit (R/-) */
-#define U300_SYSCON_CIDR					(0x400)
-/* Video IRQ clear 16bit (R/W) */
-#define U300_SYSCON_VICR					(0x404)
-#define U300_SYSCON_VICR_VIDEO1_IRQ_CLEAR_ENABLE		(0x0002)
-#define U300_SYSCON_VICR_VIDEO0_IRQ_CLEAR_ENABLE		(0x0001)
-/* SMCR */
-#define U300_SYSCON_SMCR					(0x4d0)
-#define U300_SYSCON_SMCR_FIELD_MASK				(0x000e)
-#define U300_SYSCON_SMCR_SEMI_SREFACK_IND			(0x0008)
-#define U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE			(0x0004)
-#define U300_SYSCON_SMCR_SEMI_EXT_BOOT_MODE_ENABLE		(0x0002)
-/* CPU_SW_DBGEN Software Debug Enable 16bit (R/W) */
-#define U300_SYSCON_CSDR					(0x4f0)
-#define U300_SYSCON_CSDR_SW_DEBUG_ENABLE			(0x0001)
-/* PRINT_CONTROL Print Control 16bit (R/-) */
-#define U300_SYSCON_PCR						(0x4f8)
-#define U300_SYSCON_PCR_SERV_IND				(0x0001)
-/* BOOT_CONTROL 16bit (R/-) */
-#define U300_SYSCON_BCR						(0x4fc)
-#define U300_SYSCON_BCR_ACC_CPU_SUBSYS_VINITHI_IND		(0x0400)
-#define U300_SYSCON_BCR_APP_CPU_SUBSYS_VINITHI_IND		(0x0200)
-#define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK			(0x01FC)
-#define U300_SYSCON_BCR_APP_BOOT_SERV_MASK			(0x0003)
-
-
-/* CPU clock defines */
-/**
- * CPU high frequency in MHz
- */
-#define SYSCON_CPU_CLOCK_HIGH    208
-/**
- * CPU medium frequency in MHz
- */
-#define SYSCON_CPU_CLOCK_MEDIUM   52
-/**
- * CPU low frequency in MHz
- */
-#define SYSCON_CPU_CLOCK_LOW      13
-
-/* EMIF clock defines */
-/**
- * EMIF high frequency in MHz
- */
-#define SYSCON_EMIF_CLOCK_HIGH   104
-/**
- * EMIF medium frequency in MHz
- */
-#define SYSCON_EMIF_CLOCK_MEDIUM  52
-/**
- * EMIF low frequency in MHz
- */
-#define SYSCON_EMIF_CLOCK_LOW     13
-
-/* AHB clock defines */
-/**
- * AHB high frequency in MHz
- */
-#define SYSCON_AHB_CLOCK_HIGH     52
-/**
- * AHB medium frequency in MHz
- */
-#define SYSCON_AHB_CLOCK_MEDIUM   26
-/**
- * AHB low frequency in MHz
- */
-#define SYSCON_AHB_CLOCK_LOW       7  /* i.e 13/2=6.5MHz */
-
-enum syscon_busmaster {
-  SYSCON_BM_DMAC,
-  SYSCON_BM_XGAM,
-  SYSCON_BM_VIDEO_ENC
-};
-
-/* Selectr a resistor or a set of resistors */
-enum syscon_pull_up_down {
-  SYSCON_PU_KEY_IN_EN,
-  SYSCON_PU_EMIF_1_8_BIT_EN,
-  SYSCON_PU_EMIF_1_16_BIT_EN,
-  SYSCON_PU_EMIF_1_NFIF_READY_EN,
-  SYSCON_PU_EMIF_1_NFIF_WAIT_N_EN,
-};
-
-/*
- * Note that this array must match the order of the array "clk_reg"
- * in syscon.c
- */
-enum syscon_clk {
-  SYSCON_CLKCONTROL_SLOW_BRIDGE,
-  SYSCON_CLKCONTROL_UART,
-  SYSCON_CLKCONTROL_BTR,
-  SYSCON_CLKCONTROL_EH,
-  SYSCON_CLKCONTROL_GPIO,
-  SYSCON_CLKCONTROL_KEYPAD,
-  SYSCON_CLKCONTROL_APP_TIMER,
-  SYSCON_CLKCONTROL_ACC_TIMER,
-  SYSCON_CLKCONTROL_FAST_BRIDGE,
-  SYSCON_CLKCONTROL_I2C0,
-  SYSCON_CLKCONTROL_I2C1,
-  SYSCON_CLKCONTROL_I2S0,
-  SYSCON_CLKCONTROL_I2S1,
-  SYSCON_CLKCONTROL_MMC,
-  SYSCON_CLKCONTROL_SPI,
-  SYSCON_CLKCONTROL_I2S0_CORE,
-  SYSCON_CLKCONTROL_I2S1_CORE,
-  SYSCON_CLKCONTROL_UART1,
-  SYSCON_CLKCONTROL_AAIF,
-  SYSCON_CLKCONTROL_AHB,
-  SYSCON_CLKCONTROL_APEX,
-  SYSCON_CLKCONTROL_CPU,
-  SYSCON_CLKCONTROL_DMA,
-  SYSCON_CLKCONTROL_EMIF,
-  SYSCON_CLKCONTROL_NAND_IF,
-  SYSCON_CLKCONTROL_VIDEO_ENC,
-  SYSCON_CLKCONTROL_XGAM,
-  SYSCON_CLKCONTROL_SEMI,
-  SYSCON_CLKCONTROL_AHB_SUBSYS,
-  SYSCON_CLKCONTROL_MSPRO
-};
-
-enum syscon_sysclk_mode {
-  SYSCON_SYSCLK_DISABLED,
-  SYSCON_SYSCLK_M_CLK,
-  SYSCON_SYSCLK_ACC_FSM,
-  SYSCON_SYSCLK_PLL60_48,
-  SYSCON_SYSCLK_PLL60_60,
-  SYSCON_SYSCLK_ACC_PLL208,
-  SYSCON_SYSCLK_APP_PLL13,
-  SYSCON_SYSCLK_APP_FSM,
-  SYSCON_SYSCLK_RTC,
-  SYSCON_SYSCLK_APP_PLL208
-};
-
-enum syscon_sysclk_req {
-  SYSCON_SYSCLKREQ_DISABLED,
-  SYSCON_SYSCLKREQ_ACTIVE_LOW,
-  SYSCON_SYSCLKREQ_MONITOR
-};
-
-enum syscon_clk_mode {
-  SYSCON_CLKMODE_OFF,
-  SYSCON_CLKMODE_DEFAULT,
-  SYSCON_CLKMODE_LOW,
-  SYSCON_CLKMODE_MEDIUM,
-  SYSCON_CLKMODE_HIGH,
-  SYSCON_CLKMODE_PERMANENT,
-  SYSCON_CLKMODE_ON,
-};
-
-enum syscon_call_mode {
-  SYSCON_CLKCALL_NOWAIT,
-  SYSCON_CLKCALL_WAIT,
-};
-
-int syscon_dc_on(bool keep_power_on);
-int syscon_set_busmaster_active_state(enum syscon_busmaster busmaster,
-				      bool active);
-bool syscon_get_busmaster_active_state(void);
-int syscon_set_sleep_mask(enum syscon_clk,
-			  bool sleep_ctrl);
-int syscon_config_sysclk(u32 sysclk,
-			 enum syscon_sysclk_mode sysclkmode,
-			 bool inverse,
-			 u32 divisor,
-			 enum syscon_sysclk_req sysclkreq);
-bool syscon_can_turn_off_semi_clock(void);
-
-/* This function is restricted to core.c */
-int syscon_request_normal_power(bool req);
-
-/* This function is restricted to be used by platform_speed.c */
-int syscon_speed_request(enum syscon_call_mode wait_mode,
-			 enum syscon_clk_mode req_clk_mode);
-#endif /* __MACH_SYSCON_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/timex.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/timex.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/timex.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/include/mach/timex.h
- *
- *
- * Copyright (C) 2006-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * Platform tick rate definition.
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-#ifndef __MACH_TIMEX_H
-#define __MACH_TIMEX_H
-
-/* This is for the APP OS GP1 (General Purpose 1) timer */
-#define CLOCK_TICK_RATE		1000000
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/u300-regs.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/u300-regs.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/u300-regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/u300-regs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,165 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/include/mach/u300-regs.h
- *
- *
- * Copyright (C) 2006-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * Basic register address definitions in physical memory and
- * some block definitions for core devices like the timer.
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-
-#ifndef __MACH_U300_REGS_H
-#define __MACH_U300_REGS_H
-
-/*
- * These are the large blocks of memory allocated for I/O.
- * the defines are used for setting up the I/O memory mapping.
- */
-
-/* NAND Flash CS0 */
-#define U300_NAND_CS0_PHYS_BASE		0x80000000
-
-/* NFIF */
-#define U300_NAND_IF_PHYS_BASE		0x9f800000
-
-/* ALE, CLE offset for FSMC NAND */
-#define PLAT_NAND_CLE			(1 << 16)
-#define PLAT_NAND_ALE			(1 << 17)
-
-/* AHB Peripherals */
-#define U300_AHB_PER_PHYS_BASE		0xa0000000
-#define U300_AHB_PER_VIRT_BASE		0xff010000
-
-/* FAST Peripherals */
-#define U300_FAST_PER_PHYS_BASE		0xc0000000
-#define U300_FAST_PER_VIRT_BASE		0xff020000
-
-/* SLOW Peripherals */
-#define U300_SLOW_PER_PHYS_BASE		0xc0010000
-#define U300_SLOW_PER_VIRT_BASE		0xff000000
-
-/* Boot ROM */
-#define U300_BOOTROM_PHYS_BASE		0xffff0000
-#define U300_BOOTROM_VIRT_BASE		0xffff0000
-
-/* SEMI config base */
-#define U300_SEMI_CONFIG_BASE		0x2FFE0000
-
-/*
- * AHB peripherals
- */
-
-/* AHB Peripherals Bridge Controller */
-#define U300_AHB_BRIDGE_BASE		(U300_AHB_PER_PHYS_BASE+0x0000)
-
-/* Vectored Interrupt Controller 0, servicing 32 interrupts */
-#define U300_INTCON0_BASE		(U300_AHB_PER_PHYS_BASE+0x1000)
-#define U300_INTCON0_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x1000)
-
-/* Vectored Interrupt Controller 1, servicing 32 interrupts */
-#define U300_INTCON1_BASE		(U300_AHB_PER_PHYS_BASE+0x2000)
-#define U300_INTCON1_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x2000)
-
-/* Memory Stick Pro (MSPRO) controller */
-#define U300_MSPRO_BASE			(U300_AHB_PER_PHYS_BASE+0x3000)
-
-/* EMIF Configuration Area */
-#define U300_EMIF_CFG_BASE		(U300_AHB_PER_PHYS_BASE+0x4000)
-
-
-/*
- * FAST peripherals
- */
-
-/* FAST bridge control */
-#define U300_FAST_BRIDGE_BASE		(U300_FAST_PER_PHYS_BASE+0x0000)
-
-/* MMC/SD controller */
-#define U300_MMCSD_BASE			(U300_FAST_PER_PHYS_BASE+0x1000)
-
-/* PCM I2S0 controller */
-#define U300_PCM_I2S0_BASE		(U300_FAST_PER_PHYS_BASE+0x2000)
-
-/* PCM I2S1 controller */
-#define U300_PCM_I2S1_BASE		(U300_FAST_PER_PHYS_BASE+0x3000)
-
-/* I2C0 controller */
-#define U300_I2C0_BASE			(U300_FAST_PER_PHYS_BASE+0x4000)
-
-/* I2C1 controller */
-#define U300_I2C1_BASE			(U300_FAST_PER_PHYS_BASE+0x5000)
-
-/* SPI controller */
-#define U300_SPI_BASE			(U300_FAST_PER_PHYS_BASE+0x6000)
-
-/* Fast UART1 on U335 only */
-#define U300_UART1_BASE			(U300_FAST_PER_PHYS_BASE+0x7000)
-
-/*
- * SLOW peripherals
- */
-
-/* SLOW bridge control */
-#define U300_SLOW_BRIDGE_BASE		(U300_SLOW_PER_PHYS_BASE)
-
-/* SYSCON */
-#define U300_SYSCON_BASE		(U300_SLOW_PER_PHYS_BASE+0x1000)
-#define U300_SYSCON_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000)
-
-/* Watchdog */
-#define U300_WDOG_BASE			(U300_SLOW_PER_PHYS_BASE+0x2000)
-
-/* UART0 */
-#define U300_UART0_BASE			(U300_SLOW_PER_PHYS_BASE+0x3000)
-
-/* APP side special timer */
-#define U300_TIMER_APP_BASE		(U300_SLOW_PER_PHYS_BASE+0x4000)
-#define U300_TIMER_APP_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000)
-
-/* Keypad */
-#define U300_KEYPAD_BASE		(U300_SLOW_PER_PHYS_BASE+0x5000)
-
-/* GPIO */
-#define U300_GPIO_BASE			(U300_SLOW_PER_PHYS_BASE+0x6000)
-
-/* RTC */
-#define U300_RTC_BASE			(U300_SLOW_PER_PHYS_BASE+0x7000)
-
-/* Bus tracer */
-#define U300_BUSTR_BASE			(U300_SLOW_PER_PHYS_BASE+0x8000)
-
-/* Event handler (hardware queue) */
-#define U300_EVHIST_BASE		(U300_SLOW_PER_PHYS_BASE+0x9000)
-
-/* Genric Timer */
-#define U300_TIMER_BASE			(U300_SLOW_PER_PHYS_BASE+0xa000)
-
-/* PPM */
-#define U300_PPM_BASE			(U300_SLOW_PER_PHYS_BASE+0xb000)
-
-
-/*
- * REST peripherals
- */
-
-/* ISP (image signal processor) */
-#define U300_ISP_BASE			(0xA0008000)
-
-/* DMA Controller base */
-#define U300_DMAC_BASE			(0xC0020000)
-
-/* MSL Base */
-#define U300_MSL_BASE			(0xc0022000)
-
-/* APEX Base */
-#define U300_APEX_BASE			(0xc0030000)
-
-/* Video Encoder Base */
-#define U300_VIDEOENC_BASE		(0xc0080000)
-
-/* XGAM Base */
-#define U300_XGAM_BASE			(0xd0000000)
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/uncompress.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/uncompress.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/include/mach/uncompress.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/*
- * arch/arm/mach-u300/include/mach/uncompress.h
- *
- * Copyright (C) 2003 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#define AMBA_UART_DR	(*(volatile unsigned char *)0xc0013000)
-#define AMBA_UART_LCRH	(*(volatile unsigned char *)0xc001302C)
-#define AMBA_UART_CR	(*(volatile unsigned char *)0xc0013030)
-#define AMBA_UART_FR	(*(volatile unsigned char *)0xc0013018)
-
-/*
- * This does not append a newline
- */
-static inline void putc(int c)
-{
-	while (AMBA_UART_FR & (1 << 5))
-		barrier();
-
-	AMBA_UART_DR = c;
-}
-
-static inline void flush(void)
-{
-	while (AMBA_UART_FR & (1 << 3))
-		barrier();
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-u300/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,24 +1,46 @@
-if ARCH_U300
-
 menu "ST-Ericsson AB U300/U335 Platform"
 
 comment "ST-Ericsson Mobile Platform Products"
 
-config MACH_U300
-	bool "U300"
+config ARCH_U300
+	bool "ST-Ericsson U300 Series" if ARCH_MULTI_V5
+	depends on MMU
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_AMBA
+	select ARM_PATCH_PHYS_VIRT
+	select ARM_VIC
+	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
+	select CLKSRC_OF
+	select COMMON_CLK
+	select CPU_ARM926T
+	select GENERIC_CLOCKEVENTS
+	select HAVE_TCM
 	select PINCTRL
 	select PINCTRL_COH901
 	select PINCTRL_U300
+	select SPARSE_IRQ
+	select MFD_SYSCON
+	select USE_OF
+	help
+	  Support for ST-Ericsson U300 series mobile platforms.
 
 comment "ST-Ericsson U300/U335 Feature Selections"
 
+config MACH_U300
+	depends on ARCH_U300
+	bool "U300"
+	default y
+
 config U300_DEBUG
+	depends on ARCH_U300
 	bool "Debug support for U300"
 	depends on PM
 	help
 		Debug support for U300 in sysfs, procfs etc.
 
 config MACH_U300_SPIDUMMY
+	depends on ARCH_U300
 	bool "SSP/SPI dummy chip"
 	select SPI
 	select SPI_MASTER
@@ -31,5 +53,3 @@ config MACH_U300_SPIDUMMY
 		SPI framework and ARM PL022 support.
 
 endmenu
-
-endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-u300/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,5 @@ obj-m		:=
 obj-n		:=
 obj-		:=
 
-obj-$(CONFIG_SPI_PL022)           += spi.o
 obj-$(CONFIG_MACH_U300_SPIDUMMY)  += dummyspichip.o
-obj-$(CONFIG_I2C_STU300)          += i2c.o
 obj-$(CONFIG_REGULATOR_AB3100)    += regulator.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/regulator.c linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/regulator.c
--- linux-libre-3.10-gnu/arch/arm/mach-u300/regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -10,11 +10,18 @@
 #include <linux/device.h>
 #include <linux/signal.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
 #include <linux/regulator/consumer.h>
-/* Those are just for writing in syscon */
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <mach/syscon.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+/* Power Management Control 16bit (R/W) */
+#define U300_SYSCON_PMCR					(0x50)
+#define U300_SYSCON_PMCR_DCON_ENABLE				(0x0002)
+#define U300_SYSCON_PMCR_PWR_MGNT_ENABLE			(0x0001)
 
 /*
  * Regulators that power the board and chip and which are
@@ -47,13 +54,28 @@ void u300_pm_poweroff(void)
 /*
  * Hog the regulators needed to power up the board.
  */
-static int __init u300_init_boardpower(void)
+static int __init __u300_init_boardpower(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *syscon_np;
+	struct regmap *regmap;
 	int err;
-	u32 val;
 
 	pr_info("U300: setting up board power\n");
-	main_power_15 = regulator_get(NULL, "vana15");
+
+	syscon_np = of_parse_phandle(np, "syscon", 0);
+	if (!syscon_np) {
+		pr_crit("U300: no syscon node\n");
+		return -ENODEV;
+	}
+	regmap = syscon_node_to_regmap(syscon_np);
+	if (!regmap) {
+		pr_crit("U300: could not locate syscon regmap\n");
+		return -ENODEV;
+	}
+
+	main_power_15 = regulator_get(&pdev->dev, "vana15");
+
 	if (IS_ERR(main_power_15)) {
 		pr_err("could not get vana15");
 		return PTR_ERR(main_power_15);
@@ -72,9 +94,8 @@ static int __init u300_init_boardpower(v
 	 * the rest of the U300 power management is implemented.
 	 */
 	pr_info("U300: disable system controller pull-up\n");
-	val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR);
-	val &= ~U300_SYSCON_PMCR_DCON_ENABLE;
-	writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR);
+	regmap_update_bits(regmap, U300_SYSCON_PMCR,
+			   U300_SYSCON_PMCR_DCON_ENABLE, 0);
 
 	/* Register globally exported PM poweroff hook */
 	pm_power_off = u300_pm_poweroff;
@@ -82,7 +103,31 @@ static int __init u300_init_boardpower(v
 	return 0;
 }
 
+static int __init s365_board_probe(struct platform_device *pdev)
+{
+	return __u300_init_boardpower(pdev);
+}
+
+static const struct of_device_id s365_board_match[] = {
+	{ .compatible = "stericsson,s365" },
+	{},
+};
+
+static struct platform_driver s365_board_driver = {
+	.driver		= {
+		.name   = "s365-board",
+		.owner  = THIS_MODULE,
+		.of_match_table = s365_board_match,
+	},
+};
+
 /*
  * So at module init time we hog the regulator!
  */
-module_init(u300_init_boardpower);
+static int __init u300_init_boardpower(void)
+{
+	return platform_driver_probe(&s365_board_driver,
+				     s365_board_probe);
+}
+
+device_initcall(u300_init_boardpower);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/spi.c linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/spi.c
--- linux-libre-3.10-gnu/arch/arm/mach-u300/spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/spi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,102 +0,0 @@
-/*
- * arch/arm/mach-u300/spi.c
- *
- * Copyright (C) 2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- *
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-#include <linux/device.h>
-#include <linux/amba/bus.h>
-#include <linux/spi/spi.h>
-#include <linux/amba/pl022.h>
-#include <linux/platform_data/dma-coh901318.h>
-#include <linux/err.h>
-
-/*
- * The following is for the actual devices on the SSP/SPI bus
- */
-#ifdef CONFIG_MACH_U300_SPIDUMMY
-static void select_dummy_chip(u32 chipselect)
-{
-	pr_debug("CORE: %s called with CS=0x%x (%s)\n",
-		 __func__,
-		 chipselect,
-		 chipselect ? "unselect chip" : "select chip");
-	/*
-	 * Here you would write the chip select value to the GPIO pins if
-	 * this was a real chip (but this is a loopback dummy).
-	 */
-}
-
-struct pl022_config_chip dummy_chip_info = {
-	/* available POLLING_TRANSFER, INTERRUPT_TRANSFER, DMA_TRANSFER */
-	.com_mode = DMA_TRANSFER,
-	.iface = SSP_INTERFACE_MOTOROLA_SPI,
-	/* We can only act as master but SSP_SLAVE is possible in theory */
-	.hierarchy = SSP_MASTER,
-	/* 0 = drive TX even as slave, 1 = do not drive TX as slave */
-	.slave_tx_disable = 0,
-	.rx_lev_trig = SSP_RX_4_OR_MORE_ELEM,
-	.tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC,
-	.ctrl_len = SSP_BITS_12,
-	.wait_state = SSP_MWIRE_WAIT_ZERO,
-	.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
-	/*
-	 * This is where you insert a call to a function to enable CS
-	 * (usually GPIO) for a certain chip.
-	 */
-	.cs_control = select_dummy_chip,
-};
-#endif
-
-static struct spi_board_info u300_spi_devices[] = {
-#ifdef CONFIG_MACH_U300_SPIDUMMY
-	{
-		/* A dummy chip used for loopback tests */
-		.modalias       = "spi-dummy",
-		/* Really dummy, pass in additional chip config here */
-		.platform_data  = NULL,
-		/* This defines how the controller shall handle the device */
-		.controller_data = &dummy_chip_info,
-		/* .irq - no external IRQ routed from this device */
-		.max_speed_hz   = 1000000,
-		.bus_num        = 0, /* Only one bus on this chip */
-		.chip_select    = 0,
-		/* Means SPI_CS_HIGH, change if e.g low CS */
-		.mode           = SPI_MODE_1 | SPI_LOOP,
-	},
-#endif
-};
-
-static struct pl022_ssp_controller ssp_platform_data = {
-	/* If you have several SPI buses this varies, we have only bus 0 */
-	.bus_id = 0,
-	/*
-	 * On the APP CPU GPIO 4, 5 and 6 are connected as generic
-	 * chip selects for SPI. (Same on U330, U335 and U365.)
-	 * TODO: make sure the GPIO driver can select these properly
-	 * and do padmuxing accordingly too.
-	 */
-	.num_chipselect = 3,
-#ifdef CONFIG_COH901318
-	.enable_dma = 1,
-	.dma_filter = coh901318_filter_id,
-	.dma_rx_param = (void *) U300_DMA_SPI_RX,
-	.dma_tx_param = (void *) U300_DMA_SPI_TX,
-#else
-	.enable_dma = 0,
-#endif
-};
-
-
-void __init u300_spi_init(struct amba_device *adev)
-{
-	adev->dev.platform_data = &ssp_platform_data;
-}
-
-void __init u300_spi_register_board_devices(void)
-{
-	/* Register any SPI devices */
-	spi_register_board_info(u300_spi_devices, ARRAY_SIZE(u300_spi_devices));
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/spi.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/spi.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/spi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/spi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/*
- * arch/arm/mach-u300/spi.h
- *
- * Copyright (C) 2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- *
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-#ifndef SPI_H
-#define SPI_H
-#include <linux/amba/bus.h>
-
-#ifdef CONFIG_SPI_PL022
-void __init u300_spi_init(struct amba_device *adev);
-void __init u300_spi_register_board_devices(void);
-#else
-/* Compile out SPI support if PL022 is not selected */
-static inline void __init u300_spi_init(struct amba_device *adev)
-{
-}
-static inline void __init u300_spi_register_board_devices(void)
-{
-}
-#endif
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/timer.c linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/timer.c
--- linux-libre-3.10-gnu/arch/arm/mach-u300/timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,17 +18,15 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/irqs.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
 
 /* Generic stuff */
-#include <asm/sched_clock.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include "timer.h"
-
 /*
  * APP side special timer registers
  * This timer contains four timers which can fire an interrupt each.
@@ -189,6 +187,8 @@
 #define TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ)
 #define US_PER_TICK ((1000000 + (HZ/2)) / HZ)
 
+static void __iomem *u300_timer_base;
+
 /*
  * The u300_set_mode() function is always called first, if we
  * have oneshot timer active, the oneshot scheduling function
@@ -201,28 +201,28 @@ static void u300_set_mode(enum clock_eve
 	case CLOCK_EVT_MODE_PERIODIC:
 		/* Disable interrupts on GPT1 */
 		writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+		       u300_timer_base + U300_TIMER_APP_GPT1IE);
 		/* Disable GP1 while we're reprogramming it. */
 		writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+		       u300_timer_base + U300_TIMER_APP_DGPT1);
 		/*
 		 * Set the periodic mode to a certain number of ticks per
 		 * jiffy.
 		 */
 		writel(TICKS_PER_JIFFY,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+		       u300_timer_base + U300_TIMER_APP_GPT1TC);
 		/*
 		 * Set continuous mode, so the timer keeps triggering
 		 * interrupts.
 		 */
 		writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+		       u300_timer_base + U300_TIMER_APP_SGPT1M);
 		/* Enable timer interrupts */
 		writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+		       u300_timer_base + U300_TIMER_APP_GPT1IE);
 		/* Then enable the OS timer again */
 		writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+		       u300_timer_base + U300_TIMER_APP_EGPT1);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* Just break; here? */
@@ -233,33 +233,33 @@ static void u300_set_mode(enum clock_eve
 		 */
 		/* Disable interrupts on GPT1 */
 		writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+		       u300_timer_base + U300_TIMER_APP_GPT1IE);
 		/* Disable GP1 while we're reprogramming it. */
 		writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+		       u300_timer_base + U300_TIMER_APP_DGPT1);
 		/*
 		 * Expire far in the future, u300_set_next_event() will be
 		 * called soon...
 		 */
-		writel(0xFFFFFFFF, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+		writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC);
 		/* We run one shot per tick here! */
 		writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+		       u300_timer_base + U300_TIMER_APP_SGPT1M);
 		/* Enable interrupts for this timer */
 		writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+		       u300_timer_base + U300_TIMER_APP_GPT1IE);
 		/* Enable timer */
 		writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+		       u300_timer_base + U300_TIMER_APP_EGPT1);
 		break;
 	case CLOCK_EVT_MODE_UNUSED:
 	case CLOCK_EVT_MODE_SHUTDOWN:
 		/* Disable interrupts on GP1 */
 		writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+		       u300_timer_base + U300_TIMER_APP_GPT1IE);
 		/* Disable GP1 */
 		writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
-		       U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+		       u300_timer_base + U300_TIMER_APP_DGPT1);
 		break;
 	case CLOCK_EVT_MODE_RESUME:
 		/* Ignore this call */
@@ -281,27 +281,27 @@ static int u300_set_next_event(unsigned
 {
 	/* Disable interrupts on GPT1 */
 	writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
-	       U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+	       u300_timer_base + U300_TIMER_APP_GPT1IE);
 	/* Disable GP1 while we're reprogramming it. */
 	writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
-	       U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+	       u300_timer_base + U300_TIMER_APP_DGPT1);
 	/* Reset the General Purpose timer 1. */
 	writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
-	       U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1);
+	       u300_timer_base + U300_TIMER_APP_RGPT1);
 	/* IRQ in n * cycles */
-	writel(cycles, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+	writel(cycles, u300_timer_base + U300_TIMER_APP_GPT1TC);
 	/*
 	 * We run one shot per tick here! (This is necessary to reconfigure,
 	 * the timer will tilt if you don't!)
 	 */
 	writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
-	       U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+	       u300_timer_base + U300_TIMER_APP_SGPT1M);
 	/* Enable timer interrupts */
 	writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
-	       U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+	       u300_timer_base + U300_TIMER_APP_GPT1IE);
 	/* Then enable the OS timer again */
 	writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
-	       U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+	       u300_timer_base + U300_TIMER_APP_EGPT1);
 	return 0;
 }
 
@@ -320,8 +320,9 @@ static irqreturn_t u300_timer_interrupt(
 {
 	struct clock_event_device *evt = &clockevent_u300_1mhz;
 	/* ACK/Clear timer IRQ for the APP GPT1 Timer */
+
 	writel(U300_TIMER_APP_GPT1IA_IRQ_ACK,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IA);
+		u300_timer_base + U300_TIMER_APP_GPT1IA);
 	evt->event_handler(evt);
 	return IRQ_HANDLED;
 }
@@ -342,65 +343,88 @@ static struct irqaction u300_timer_irq =
 
 static u32 notrace u300_read_sched_clock(void)
 {
-	return readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
+	return readl(u300_timer_base + U300_TIMER_APP_GPT2CC);
+}
+
+static unsigned long u300_read_current_timer(void)
+{
+	return readl(u300_timer_base + U300_TIMER_APP_GPT2CC);
 }
 
+static struct delay_timer u300_delay_timer;
 
 /*
  * This sets up the system timers, clock source and clock event.
  */
-void __init u300_timer_init(void)
+static void __init u300_timer_init_of(struct device_node *np)
 {
+	struct resource irq_res;
+	int irq;
 	struct clk *clk;
 	unsigned long rate;
 
+	u300_timer_base = of_iomap(np, 0);
+	if (!u300_timer_base)
+		panic("could not ioremap system timer\n");
+
+	/* Get the IRQ for the GP1 timer */
+	irq = of_irq_to_resource(np, 2, &irq_res);
+	if (irq <= 0)
+		panic("no IRQ for system timer\n");
+
+	pr_info("U300 GP1 timer @ base: %p, IRQ: %d\n", u300_timer_base, irq);
+
 	/* Clock the interrupt controller */
-	clk = clk_get_sys("apptimer", NULL);
+	clk = of_clk_get(np, 0);
 	BUG_ON(IS_ERR(clk));
 	clk_prepare_enable(clk);
 	rate = clk_get_rate(clk);
 
 	setup_sched_clock(u300_read_sched_clock, 32, rate);
 
+	u300_delay_timer.read_current_timer = &u300_read_current_timer;
+	u300_delay_timer.freq = rate;
+	register_current_timer_delay(&u300_delay_timer);
+
 	/*
 	 * Disable the "OS" and "DD" timers - these are designed for Symbian!
 	 * Example usage in cnh1601578 cpu subsystem pd_timer_app.c
 	 */
 	writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_CRC);
+		u300_timer_base + U300_TIMER_APP_CRC);
 	writel(U300_TIMER_APP_ROST_TIMER_RESET,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_ROST);
+		u300_timer_base + U300_TIMER_APP_ROST);
 	writel(U300_TIMER_APP_DOST_TIMER_DISABLE,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_DOST);
+		u300_timer_base + U300_TIMER_APP_DOST);
 	writel(U300_TIMER_APP_RDDT_TIMER_RESET,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_RDDT);
+		u300_timer_base + U300_TIMER_APP_RDDT);
 	writel(U300_TIMER_APP_DDDT_TIMER_DISABLE,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_DDDT);
+		u300_timer_base + U300_TIMER_APP_DDDT);
 
 	/* Reset the General Purpose timer 1. */
 	writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1);
+		u300_timer_base + U300_TIMER_APP_RGPT1);
 
 	/* Set up the IRQ handler */
-	setup_irq(IRQ_U300_TIMER_APP_GP1, &u300_timer_irq);
+	setup_irq(irq, &u300_timer_irq);
 
 	/* Reset the General Purpose timer 2 */
 	writel(U300_TIMER_APP_RGPT2_TIMER_RESET,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT2);
+		u300_timer_base + U300_TIMER_APP_RGPT2);
 	/* Set this timer to run around forever */
-	writel(0xFFFFFFFFU, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2TC);
+	writel(0xFFFFFFFFU, u300_timer_base + U300_TIMER_APP_GPT2TC);
 	/* Set continuous mode so it wraps around */
 	writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS,
-	       U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT2M);
+	       u300_timer_base + U300_TIMER_APP_SGPT2M);
 	/* Disable timer interrupts */
 	writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2IE);
+		u300_timer_base + U300_TIMER_APP_GPT2IE);
 	/* Then enable the GP2 timer to use as a free running us counter */
 	writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
-		U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2);
+		u300_timer_base + U300_TIMER_APP_EGPT2);
 
 	/* Use general purpose timer 2 as clock source */
-	if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC,
+	if (clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC,
 			"GPT2", rate, 300, 32, clocksource_mmio_readl_up))
 		pr_err("timer: failed to initialize U300 clock source\n");
 
@@ -413,3 +437,6 @@ void __init u300_timer_init(void)
 	 * used by hrtimers!
 	 */
 }
+
+CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer",
+		       u300_timer_init_of);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/timer.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/timer.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/timer.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/timer.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-extern void u300_timer_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-u300/u300-gpio.h linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/u300-gpio.h
--- linux-libre-3.10-gnu/arch/arm/mach-u300/u300-gpio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-u300/u300-gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,70 +0,0 @@
-/*
- * Individual pin assignments for the B335/S335.
- * Notice that the actual usage of these pins depends on the
- * PAD MUX settings, that is why the same number can potentially
- * appear several times. In the reference design each pin is only
- * used for one purpose. These were determined by inspecting the
- * S365 schematic.
- */
-#define U300_GPIO_PIN_UART_RX		0
-#define U300_GPIO_PIN_UART_TX		1
-#define U300_GPIO_PIN_UART_CTS		2
-#define U300_GPIO_PIN_UART_RTS		3
-#define U300_GPIO_PIN_CAM_MAIN_STANDBY	4 /* Camera MAIN standby */
-#define U300_GPIO_PIN_GPIO05		5 /* Unrouted */
-#define U300_GPIO_PIN_MS_CD		6 /* Memory Stick Card insertion */
-#define U300_GPIO_PIN_GPIO07		7 /* Test point TP2430 */
-
-#define U300_GPIO_PIN_GPIO08		8 /* Test point TP2437 */
-#define U300_GPIO_PIN_GPIO09		9 /* Test point TP2431 */
-#define U300_GPIO_PIN_GPIO10		10 /* Test point TP2432 */
-#define U300_GPIO_PIN_MMC_CLKRET	11 /* Clock return from MMC/SD card */
-#define U300_GPIO_PIN_MMC_CD		12 /* MMC Card insertion detection */
-#define U300_GPIO_PIN_CAM_SUB_STANDBY	13 /* Camera SUB standby */
-#define U300_GPIO_PIN_GPIO14		14 /* Test point TP2436 */
-#define U300_GPIO_PIN_GPIO15		15 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO16		16 /* Test point TP2438 */
-#define U300_GPIO_PIN_PHFSENSE		17 /* Headphone jack sensing */
-#define U300_GPIO_PIN_GPIO18		18 /* Test point TP2439 */
-#define U300_GPIO_PIN_GPIO19		19 /* Routed somewhere */
-#define U300_GPIO_PIN_GPIO20		20 /* Unrouted */
-#define U300_GPIO_PIN_GPIO21		21 /* Unrouted */
-#define U300_GPIO_PIN_GPIO22		22 /* Unrouted */
-#define U300_GPIO_PIN_GPIO23		23 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO24		24 /* Unrouted */
-#define U300_GPIO_PIN_GPIO25		25 /* Unrouted */
-#define U300_GPIO_PIN_GPIO26		26 /* Unrouted */
-#define U300_GPIO_PIN_GPIO27		27 /* Unrouted */
-#define U300_GPIO_PIN_GPIO28		28 /* Unrouted */
-#define U300_GPIO_PIN_GPIO29		29 /* Unrouted */
-#define U300_GPIO_PIN_GPIO30		30 /* Unrouted */
-#define U300_GPIO_PIN_GPIO31		31 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO32		32 /* Unrouted */
-#define U300_GPIO_PIN_GPIO33		33 /* Unrouted */
-#define U300_GPIO_PIN_GPIO34		34 /* Unrouted */
-#define U300_GPIO_PIN_GPIO35		35 /* Unrouted */
-#define U300_GPIO_PIN_GPIO36		36 /* Unrouted */
-#define U300_GPIO_PIN_GPIO37		37 /* Unrouted */
-#define U300_GPIO_PIN_GPIO38		38 /* Unrouted */
-#define U300_GPIO_PIN_GPIO39		39 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO40		40 /* Unrouted */
-#define U300_GPIO_PIN_GPIO41		41 /* Unrouted */
-#define U300_GPIO_PIN_GPIO42		42 /* Unrouted */
-#define U300_GPIO_PIN_GPIO43		43 /* Unrouted */
-#define U300_GPIO_PIN_GPIO44		44 /* Unrouted */
-#define U300_GPIO_PIN_GPIO45		45 /* Unrouted */
-#define U300_GPIO_PIN_GPIO46		46 /* Unrouted */
-#define U300_GPIO_PIN_GPIO47		47 /* Unrouted */
-
-#define U300_GPIO_PIN_GPIO48		48 /* Unrouted */
-#define U300_GPIO_PIN_GPIO49		49 /* Unrouted */
-#define U300_GPIO_PIN_GPIO50		50 /* Unrouted */
-#define U300_GPIO_PIN_GPIO51		51 /* Unrouted */
-#define U300_GPIO_PIN_GPIO52		52 /* Unrouted */
-#define U300_GPIO_PIN_GPIO53		53 /* Unrouted */
-#define U300_GPIO_PIN_GPIO54		54 /* Unrouted */
-#define U300_GPIO_PIN_GPIO55		55 /* Unrouted */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500-audio.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500-audio.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500-audio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500-audio.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,28 +21,14 @@
 
 static struct stedma40_chan_cfg msp0_dma_rx = {
 	.high_priority = true,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-
-	.src_dev_type = DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-
-	.src_info.psize = STEDMA40_PSIZE_LOG_4,
-	.dst_info.psize = STEDMA40_PSIZE_LOG_4,
-
-	/* data_width is set during configuration */
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,
 };
 
 static struct stedma40_chan_cfg msp0_dma_tx = {
 	.high_priority = true,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-
-	.src_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX,
-
-	.src_info.psize = STEDMA40_PSIZE_LOG_4,
-	.dst_info.psize = STEDMA40_PSIZE_LOG_4,
-
-	/* data_width is set during configuration */
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV31_MSP0_SLIM0_CH0,
 };
 
 struct msp_i2s_platform_data msp0_platform_data = {
@@ -53,28 +39,14 @@ struct msp_i2s_platform_data msp0_platfo
 
 static struct stedma40_chan_cfg msp1_dma_rx = {
 	.high_priority = true,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-
-	.src_dev_type = DB8500_DMA_DEV30_MSP3_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-
-	.src_info.psize = STEDMA40_PSIZE_LOG_4,
-	.dst_info.psize = STEDMA40_PSIZE_LOG_4,
-
-	/* data_width is set during configuration */
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type = DB8500_DMA_DEV30_MSP3,
 };
 
 static struct stedma40_chan_cfg msp1_dma_tx = {
 	.high_priority = true,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-
-	.src_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV30_MSP1_TX,
-
-	.src_info.psize = STEDMA40_PSIZE_LOG_4,
-	.dst_info.psize = STEDMA40_PSIZE_LOG_4,
-
-	/* data_width is set during configuration */
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV30_MSP1,
 };
 
 struct msp_i2s_platform_data msp1_platform_data = {
@@ -85,32 +57,16 @@ struct msp_i2s_platform_data msp1_platfo
 
 static struct stedma40_chan_cfg msp2_dma_rx = {
 	.high_priority = true,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-
-	.src_dev_type = DB8500_DMA_DEV14_MSP2_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-
-	/* MSP2 DMA doesn't work with PSIZE == 4 on DB8500v2 */
-	.src_info.psize = STEDMA40_PSIZE_LOG_1,
-	.dst_info.psize = STEDMA40_PSIZE_LOG_1,
-
-	/* data_width is set during configuration */
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type = DB8500_DMA_DEV14_MSP2,
 };
 
 static struct stedma40_chan_cfg msp2_dma_tx = {
 	.high_priority = true,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-
-	.src_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV14_MSP2_TX,
-
-	.src_info.psize = STEDMA40_PSIZE_LOG_4,
-	.dst_info.psize = STEDMA40_PSIZE_LOG_4,
-
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV14_MSP2,
 	.use_fixed_channel = true,
 	.phy_channel = 1,
-
-	/* data_width is set during configuration */
 };
 
 static struct platform_device *db8500_add_msp_i2s(struct device *parent,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500.c	2013-08-25 20:43:22.000000000 -0400
@@ -413,47 +413,23 @@ static void mop500_prox_deactivate(struc
 	regulator_put(prox_regulator);
 }
 
-void mop500_snowball_ethernet_clock_enable(void)
-{
-	struct clk *clk;
-
-	clk = clk_get_sys("fsmc", NULL);
-	if (!IS_ERR(clk))
-		clk_prepare_enable(clk);
-}
-
 static struct cryp_platform_data u8500_cryp1_platform_data = {
 		.mem_to_engine = {
-				.dir = STEDMA40_MEM_TO_PERIPH,
-				.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-				.dst_dev_type = DB8500_DMA_DEV48_CAC1_TX,
-				.src_info.data_width = STEDMA40_WORD_WIDTH,
-				.dst_info.data_width = STEDMA40_WORD_WIDTH,
+				.dir = DMA_MEM_TO_DEV,
+				.dev_type = DB8500_DMA_DEV48_CAC1,
 				.mode = STEDMA40_MODE_LOGICAL,
-				.src_info.psize = STEDMA40_PSIZE_LOG_4,
-				.dst_info.psize = STEDMA40_PSIZE_LOG_4,
 		},
 		.engine_to_mem = {
-				.dir = STEDMA40_PERIPH_TO_MEM,
-				.src_dev_type = DB8500_DMA_DEV48_CAC1_RX,
-				.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-				.src_info.data_width = STEDMA40_WORD_WIDTH,
-				.dst_info.data_width = STEDMA40_WORD_WIDTH,
+				.dir = DMA_DEV_TO_MEM,
+				.dev_type = DB8500_DMA_DEV48_CAC1,
 				.mode = STEDMA40_MODE_LOGICAL,
-				.src_info.psize = STEDMA40_PSIZE_LOG_4,
-				.dst_info.psize = STEDMA40_PSIZE_LOG_4,
 		}
 };
 
 static struct stedma40_chan_cfg u8500_hash_dma_cfg_tx = {
-		.dir = STEDMA40_MEM_TO_PERIPH,
-		.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-		.dst_dev_type = DB8500_DMA_DEV50_HAC1_TX,
-		.src_info.data_width = STEDMA40_WORD_WIDTH,
-		.dst_info.data_width = STEDMA40_WORD_WIDTH,
+		.dir = DMA_MEM_TO_DEV,
+		.dev_type = DB8500_DMA_DEV50_HAC1_TX,
 		.mode = STEDMA40_MODE_LOGICAL,
-		.src_info.psize = STEDMA40_PSIZE_LOG_16,
-		.dst_info.psize = STEDMA40_PSIZE_LOG_16,
 };
 
 static struct hash_platform_data u8500_hash1_platform_data = {
@@ -470,20 +446,14 @@ static struct platform_device *mop500_pl
 #ifdef CONFIG_STE_DMA40
 static struct stedma40_chan_cfg ssp0_dma_cfg_rx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-	.src_dev_type =  DB8500_DMA_DEV8_SSP0_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type = DB8500_DMA_DEV8_SSP0,
 };
 
 static struct stedma40_chan_cfg ssp0_dma_cfg_tx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-	.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV8_SSP0_TX,
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV8_SSP0,
 };
 #endif
 
@@ -511,56 +481,38 @@ static void __init mop500_spi_init(struc
 #ifdef CONFIG_STE_DMA40
 static struct stedma40_chan_cfg uart0_dma_cfg_rx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-	.src_dev_type =  DB8500_DMA_DEV13_UART0_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type = DB8500_DMA_DEV13_UART0,
 };
 
 static struct stedma40_chan_cfg uart0_dma_cfg_tx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-	.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV13_UART0_TX,
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV13_UART0,
 };
 
 static struct stedma40_chan_cfg uart1_dma_cfg_rx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-	.src_dev_type =  DB8500_DMA_DEV12_UART1_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type = DB8500_DMA_DEV12_UART1,
 };
 
 static struct stedma40_chan_cfg uart1_dma_cfg_tx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-	.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV12_UART1_TX,
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV12_UART1,
 };
 
 static struct stedma40_chan_cfg uart2_dma_cfg_rx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-	.src_dev_type =  DB8500_DMA_DEV11_UART2_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type = DB8500_DMA_DEV11_UART2,
 };
 
 static struct stedma40_chan_cfg uart2_dma_cfg_tx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-	.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV11_UART2_TX,
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV11_UART2,
 };
 #endif
 
@@ -674,7 +626,7 @@ static void __init snowball_init_machine
 	mop500_audio_init(parent);
 	mop500_uart_init(parent);
 
-	mop500_snowball_ethernet_clock_enable();
+	u8500_cryp1_hash1_init(parent);
 
 	/* This board has full regulator constraints */
 	regulator_has_full_constraints();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500.h linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500.h
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500.h	2013-08-25 20:43:22.000000000 -0400
@@ -93,6 +93,7 @@ extern struct amba_pl011_data uart0_plat
 extern struct amba_pl011_data uart1_plat;
 extern struct amba_pl011_data uart2_plat;
 extern struct pl022_ssp_controller ssp0_plat;
+extern struct stedma40_platform_data dma40_plat_data;
 
 extern void mop500_sdi_init(struct device *parent);
 extern void snowball_sdi_init(struct device *parent);
@@ -104,7 +105,6 @@ void __init mop500_pinmaps_init(void);
 void __init snowball_pinmaps_init(void);
 void __init hrefv60_pinmaps_init(void);
 void mop500_audio_init(struct device *parent);
-void mop500_snowball_ethernet_clock_enable(void);
 
 int __init mop500_uib_init(void);
 void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500-pins.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500-pins.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500-pins.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500-pins.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/bug.h>
 #include <linux/string.h>
 #include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/platform_data/pinctrl-nomadik.h>
 
 #include <asm/mach-types.h>
@@ -34,6 +35,11 @@ BIAS(in_pd, PIN_INPUT_PULLDOWN);
 BIAS(out_hi, PIN_OUTPUT_HIGH);
 BIAS(out_lo, PIN_OUTPUT_LOW);
 BIAS(out_lo_slpm_nowkup, PIN_OUTPUT_LOW|PIN_SLPM_WAKEUP_DISABLE);
+
+BIAS(abx500_out_lo, PIN_CONF_PACKED(PIN_CONFIG_OUTPUT, 0));
+BIAS(abx500_in_pd, PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 1));
+BIAS(abx500_in_nopull, PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_DOWN, 0));
+
 /* These also force them into GPIO mode */
 BIAS(gpio_in_pu, PIN_INPUT_PULLUP|PIN_GPIOMODE_ENABLED);
 BIAS(gpio_in_pd, PIN_INPUT_PULLDOWN|PIN_GPIOMODE_ENABLED);
@@ -42,8 +48,6 @@ BIAS(gpio_in_pd_slpm_gpio_nopull, PIN_IN
 BIAS(gpio_out_hi, PIN_OUTPUT_HIGH|PIN_GPIOMODE_ENABLED);
 BIAS(gpio_out_lo, PIN_OUTPUT_LOW|PIN_GPIOMODE_ENABLED);
 /* Sleep modes */
-BIAS(slpm_in_nopull_wkup, PIN_SLEEPMODE_ENABLED|
-	PIN_SLPM_DIR_INPUT|PIN_SLPM_PULL_NONE|PIN_SLPM_WAKEUP_ENABLE);
 BIAS(slpm_in_wkup_pdis, PIN_SLEEPMODE_ENABLED|
 	PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
 BIAS(slpm_in_wkup_pdis_en, PIN_SLEEPMODE_ENABLED|
@@ -54,8 +58,6 @@ BIAS(slpm_wkup_pdis_en, PIN_SLEEPMODE_EN
 	PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_ENABLED);
 BIAS(slpm_out_lo_pdis, PIN_SLEEPMODE_ENABLED|
 	PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_DISABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_out_lo_wkup, PIN_SLEEPMODE_ENABLED|
-	PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE);
 BIAS(slpm_out_lo_wkup_pdis, PIN_SLEEPMODE_ENABLED|
 	PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
 BIAS(slpm_out_hi_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_HIGH|
@@ -97,6 +99,252 @@ BIAS(out_wkup_pdis, PIN_SLPM_DIR_OUTPUT|
 #define DB8500_PIN_STATE(pin, conf, dev, state) \
 	PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-db8500", pin, conf)
 
+#define AB8500_MUX_HOG(group, func) \
+	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-ab8500.0", group, func)
+#define AB8500_PIN_HOG(pin, conf) \
+	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-ab8500.0", pin, abx500_##conf)
+
+#define AB8500_MUX_STATE(group, func, dev, state) \
+	PIN_MAP_MUX_GROUP(dev, state, "pinctrl-ab8500.0", group, func)
+#define AB8500_PIN_STATE(pin, conf, dev, state) \
+	PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-ab8500.0", pin, abx500_##conf)
+
+#define AB8505_MUX_HOG(group, func) \
+	PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-ab8505.0", group, func)
+#define AB8505_PIN_HOG(pin, conf) \
+	PIN_MAP_CONFIGS_PIN_HOG_DEFAULT("pinctrl-ab8505.0", pin, abx500_##conf)
+
+#define AB8505_MUX_STATE(group, func, dev, state) \
+	PIN_MAP_MUX_GROUP(dev, state, "pinctrl-ab8505.0", group, func)
+#define AB8505_PIN_STATE(pin, conf, dev, state) \
+	PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-ab8505.0", pin, abx500_##conf)
+
+static struct pinctrl_map __initdata ab8500_pinmap[] = {
+	/* Sysclkreq2 */
+	AB8500_MUX_STATE("sysclkreq2_d_1", "sysclkreq", "regulator.35", PINCTRL_STATE_DEFAULT),
+	AB8500_PIN_STATE("GPIO1_T10", in_nopull, "regulator.35", PINCTRL_STATE_DEFAULT),
+	/* sysclkreq2 disable, mux in gpio configured in input pulldown */
+	AB8500_MUX_STATE("gpio1_a_1", "gpio", "regulator.35", PINCTRL_STATE_SLEEP),
+	AB8500_PIN_STATE("GPIO1_T10", in_pd, "regulator.35", PINCTRL_STATE_SLEEP),
+
+	/* pins 2 is muxed in GPIO, configured in INPUT PULL DOWN */
+	AB8500_MUX_HOG("gpio2_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO2_T9", in_pd),
+
+	/* Sysclkreq4 */
+	AB8500_MUX_STATE("sysclkreq4_d_1", "sysclkreq", "regulator.36", PINCTRL_STATE_DEFAULT),
+	AB8500_PIN_STATE("GPIO3_U9", in_nopull, "regulator.36", PINCTRL_STATE_DEFAULT),
+	/* sysclkreq4 disable, mux in gpio configured in input pulldown */
+	AB8500_MUX_STATE("gpio3_a_1", "gpio", "regulator.36", PINCTRL_STATE_SLEEP),
+	AB8500_PIN_STATE("GPIO3_U9", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
+
+	/* pins 4 is muxed in GPIO, configured in INPUT PULL DOWN */
+	AB8500_MUX_HOG("gpio4_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO4_W2", in_pd),
+
+	/*
+	 * pins 6,7,8 and 9 are muxed in YCBCR0123
+	 * configured in INPUT PULL UP
+	 */
+	AB8500_MUX_HOG("ycbcr0123_d_1", "ycbcr"),
+	AB8500_PIN_HOG("GPIO6_Y18", in_nopull),
+	AB8500_PIN_HOG("GPIO7_AA20", in_nopull),
+	AB8500_PIN_HOG("GPIO8_W18", in_nopull),
+	AB8500_PIN_HOG("GPIO9_AA19", in_nopull),
+
+	/*
+	 * pins 10,11,12 and 13 are muxed in GPIO
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("gpio10_d_1", "gpio"),
+	AB8500_PIN_HOG("GPIO10_U17", in_pd),
+
+	AB8500_MUX_HOG("gpio11_d_1", "gpio"),
+	AB8500_PIN_HOG("GPIO11_AA18", in_pd),
+
+	AB8500_MUX_HOG("gpio12_d_1", "gpio"),
+	AB8500_PIN_HOG("GPIO12_U16", in_pd),
+
+	AB8500_MUX_HOG("gpio13_d_1", "gpio"),
+	AB8500_PIN_HOG("GPIO13_W17", in_pd),
+
+	/*
+	 * pins 14,15 are muxed in PWM1 and PWM2
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("pwmout1_d_1", "pwmout"),
+	AB8500_PIN_HOG("GPIO14_F14", in_pd),
+
+	AB8500_MUX_HOG("pwmout2_d_1", "pwmout"),
+	AB8500_PIN_HOG("GPIO15_B17", in_pd),
+
+	/*
+	 * pins 16 is muxed in GPIO
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("gpio16_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO14_F14", in_pd),
+
+	/*
+	 * pins 17,18,19 and 20 are muxed in AUDIO interface 1
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("adi1_d_1", "adi1"),
+	AB8500_PIN_HOG("GPIO17_P5", in_pd),
+	AB8500_PIN_HOG("GPIO18_R5", in_pd),
+	AB8500_PIN_HOG("GPIO19_U5", in_pd),
+	AB8500_PIN_HOG("GPIO20_T5", in_pd),
+
+	/*
+	 * pins 21,22 and 23 are muxed in USB UICC
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("usbuicc_d_1", "usbuicc"),
+	AB8500_PIN_HOG("GPIO21_H19", in_pd),
+	AB8500_PIN_HOG("GPIO22_G20", in_pd),
+	AB8500_PIN_HOG("GPIO23_G19", in_pd),
+
+	/*
+	 * pins 24,25 are muxed in GPIO
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("gpio24_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO24_T14", in_pd),
+
+	AB8500_MUX_HOG("gpio25_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO25_R16", in_pd),
+
+	/*
+	 * pins 26 is muxed in GPIO
+	 * configured in OUTPUT LOW
+	 */
+	AB8500_MUX_HOG("gpio26_d_1", "gpio"),
+	AB8500_PIN_HOG("GPIO26_M16", out_lo),
+
+	/*
+	 * pins 27,28 are muxed in DMIC12
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("dmic12_d_1", "dmic"),
+	AB8500_PIN_HOG("GPIO27_J6", in_pd),
+	AB8500_PIN_HOG("GPIO28_K6", in_pd),
+
+	/*
+	 * pins 29,30 are muxed in DMIC34
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("dmic34_d_1", "dmic"),
+	AB8500_PIN_HOG("GPIO29_G6", in_pd),
+	AB8500_PIN_HOG("GPIO30_H6", in_pd),
+
+	/*
+	 * pins 31,32 are muxed in DMIC56
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("dmic56_d_1", "dmic"),
+	AB8500_PIN_HOG("GPIO31_F5", in_pd),
+	AB8500_PIN_HOG("GPIO32_G5", in_pd),
+
+	/*
+	 * pins 34 is muxed in EXTCPENA
+	 * configured INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("extcpena_d_1", "extcpena"),
+	AB8500_PIN_HOG("GPIO34_R17", in_pd),
+
+	/*
+	 * pins 35 is muxed in GPIO
+	 * configured in OUTPUT LOW
+	 */
+	AB8500_MUX_HOG("gpio35_d_1", "gpio"),
+	AB8500_PIN_HOG("GPIO35_W15", in_pd),
+
+	/*
+	 * pins 36,37,38 and 39 are muxed in GPIO
+	 * configured in INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("gpio36_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO36_A17", in_pd),
+
+	AB8500_MUX_HOG("gpio37_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO37_E15", in_pd),
+
+	AB8500_MUX_HOG("gpio38_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO38_C17", in_pd),
+
+	AB8500_MUX_HOG("gpio39_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO39_E16", in_pd),
+
+	/*
+	 * pins 40 and 41 are muxed in MODCSLSDA
+	 * configured INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("modsclsda_d_1", "modsclsda"),
+	AB8500_PIN_HOG("GPIO40_T19", in_pd),
+	AB8500_PIN_HOG("GPIO41_U19", in_pd),
+
+	/*
+	 * pins 42 is muxed in GPIO
+	 * configured INPUT PULL DOWN
+	 */
+	AB8500_MUX_HOG("gpio42_a_1", "gpio"),
+	AB8500_PIN_HOG("GPIO42_U2", in_pd),
+};
+
+static struct pinctrl_map __initdata ab8505_pinmap[] = {
+	/* Sysclkreq2 */
+	AB8505_MUX_STATE("sysclkreq2_d_1", "sysclkreq", "regulator.36", PINCTRL_STATE_DEFAULT),
+	AB8505_PIN_STATE("GPIO1_N4", in_nopull, "regulator.36", PINCTRL_STATE_DEFAULT),
+	/* sysclkreq2 disable, mux in gpio configured in input pulldown */
+	AB8505_MUX_STATE("gpio1_a_1", "gpio", "regulator.36", PINCTRL_STATE_SLEEP),
+	AB8505_PIN_STATE("GPIO1_N4", in_pd, "regulator.36", PINCTRL_STATE_SLEEP),
+
+	/* pins 2 is muxed in GPIO, configured in INPUT PULL DOWN */
+	AB8505_MUX_HOG("gpio2_a_1", "gpio"),
+	AB8505_PIN_HOG("GPIO2_R5", in_pd),
+
+	/* Sysclkreq4 */
+	AB8505_MUX_STATE("sysclkreq4_d_1", "sysclkreq", "regulator.37", PINCTRL_STATE_DEFAULT),
+	AB8505_PIN_STATE("GPIO3_P5", in_nopull, "regulator.37", PINCTRL_STATE_DEFAULT),
+	/* sysclkreq4 disable, mux in gpio configured in input pulldown */
+	AB8505_MUX_STATE("gpio3_a_1", "gpio", "regulator.37", PINCTRL_STATE_SLEEP),
+	AB8505_PIN_STATE("GPIO3_P5", in_pd, "regulator.37", PINCTRL_STATE_SLEEP),
+
+	AB8505_MUX_HOG("gpio10_d_1", "gpio"),
+	AB8505_PIN_HOG("GPIO10_B16", in_pd),
+
+	AB8505_MUX_HOG("gpio11_d_1", "gpio"),
+	AB8505_PIN_HOG("GPIO11_B17", in_pd),
+
+	AB8505_MUX_HOG("gpio13_d_1", "gpio"),
+	AB8505_PIN_HOG("GPIO13_D17", in_nopull),
+
+	AB8505_MUX_HOG("pwmout1_d_1", "pwmout"),
+	AB8505_PIN_HOG("GPIO14_C16", in_pd),
+
+	AB8505_MUX_HOG("adi2_d_1", "adi2"),
+	AB8505_PIN_HOG("GPIO17_P2", in_pd),
+	AB8505_PIN_HOG("GPIO18_N3", in_pd),
+	AB8505_PIN_HOG("GPIO19_T1", in_pd),
+	AB8505_PIN_HOG("GPIO20_P3", in_pd),
+
+	AB8505_MUX_HOG("gpio34_a_1", "gpio"),
+	AB8505_PIN_HOG("GPIO34_H14", in_pd),
+
+	AB8505_MUX_HOG("modsclsda_d_1", "modsclsda"),
+	AB8505_PIN_HOG("GPIO40_J15", in_pd),
+	AB8505_PIN_HOG("GPIO41_J14", in_pd),
+
+	AB8505_MUX_HOG("gpio50_d_1", "gpio"),
+	AB8505_PIN_HOG("GPIO50_L4", in_nopull),
+
+	AB8505_MUX_HOG("resethw_d_1", "resethw"),
+	AB8505_PIN_HOG("GPIO52_D16", in_pd),
+
+	AB8505_MUX_HOG("service_d_1", "service"),
+	AB8505_PIN_HOG("GPIO53_D15", in_pd),
+};
+
 /* Pin control settings */
 static struct pinctrl_map __initdata mop500_family_pinmap[] = {
 	/*
@@ -174,17 +422,12 @@ static struct pinctrl_map __initdata mop
 	DB8500_PIN_SLEEP("GPIO4_AH6", slpm_in_wkup_pdis, "uart1"),
 	DB8500_PIN_SLEEP("GPIO5_AG6", slpm_out_wkup_pdis, "uart1"),
 	/* MSP1 for ALSA codec */
-	DB8500_MUX("msp1txrx_a_1", "msp1", "ux500-msp-i2s.1"),
-	DB8500_MUX("msp1_a_1", "msp1", "ux500-msp-i2s.1"),
-	DB8500_PIN("GPIO33_AF2", out_lo_slpm_nowkup, "ux500-msp-i2s.1"),
-	DB8500_PIN("GPIO34_AE1", in_nopull_slpm_nowkup, "ux500-msp-i2s.1"),
-	DB8500_PIN("GPIO35_AE2", in_nopull_slpm_nowkup, "ux500-msp-i2s.1"),
-	DB8500_PIN("GPIO36_AG2", in_nopull_slpm_nowkup, "ux500-msp-i2s.1"),
-	/* MSP1 sleep state */
-	DB8500_PIN_SLEEP("GPIO33_AF2", slpm_out_lo_wkup, "ux500-msp-i2s.1"),
-	DB8500_PIN_SLEEP("GPIO34_AE1", slpm_in_nopull_wkup, "ux500-msp-i2s.1"),
-	DB8500_PIN_SLEEP("GPIO35_AE2", slpm_in_nopull_wkup, "ux500-msp-i2s.1"),
-	DB8500_PIN_SLEEP("GPIO36_AG2", slpm_in_nopull_wkup, "ux500-msp-i2s.1"),
+	DB8500_MUX_HOG("msp1txrx_a_1", "msp1"),
+	DB8500_MUX_HOG("msp1_a_1", "msp1"),
+	DB8500_PIN_HOG("GPIO33_AF2", out_lo_slpm_nowkup),
+	DB8500_PIN_HOG("GPIO34_AE1", in_nopull_slpm_nowkup),
+	DB8500_PIN_HOG("GPIO35_AE2", in_nopull_slpm_nowkup),
+	DB8500_PIN_HOG("GPIO36_AG2", in_nopull_slpm_nowkup),
 	/* Mux in LCD data lines 8 thru 11 and LCDA CLK for MCDE TVOUT */
 	DB8500_MUX("lcd_d8_d11_a_1", "lcd", "mcde-tvout"),
 	DB8500_MUX("lcdaclk_b_1", "lcda", "mcde-tvout"),
@@ -821,6 +1064,12 @@ void __init mop500_pinmaps_init(void)
 	pinctrl_register_mappings(mop500_pinmap,
 				  ARRAY_SIZE(mop500_pinmap));
 	mop500_href_family_pinmaps_init();
+	if (machine_is_u8520())
+		pinctrl_register_mappings(ab8505_pinmap,
+					  ARRAY_SIZE(ab8505_pinmap));
+	else
+		pinctrl_register_mappings(ab8500_pinmap,
+					  ARRAY_SIZE(ab8500_pinmap));
 }
 
 void __init snowball_pinmaps_init(void)
@@ -831,6 +1080,8 @@ void __init snowball_pinmaps_init(void)
 				  ARRAY_SIZE(snowball_pinmap));
 	pinctrl_register_mappings(u8500_pinmap,
 				  ARRAY_SIZE(u8500_pinmap));
+	pinctrl_register_mappings(ab8500_pinmap,
+				  ARRAY_SIZE(ab8500_pinmap));
 }
 
 void __init hrefv60_pinmaps_init(void)
@@ -840,4 +1091,6 @@ void __init hrefv60_pinmaps_init(void)
 	pinctrl_register_mappings(hrefv60_pinmap,
 				  ARRAY_SIZE(hrefv60_pinmap));
 	mop500_href_family_pinmaps_init();
+	pinctrl_register_mappings(ab8500_pinmap,
+				  ARRAY_SIZE(ab8500_pinmap));
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500-regulators.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500-regulators.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500-regulators.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500-regulators.c	2013-08-25 20:43:22.000000000 -0400
@@ -999,7 +999,6 @@ struct ab8500_regulator_platform_data ab
 	.num_ext_regulator      = ARRAY_SIZE(ab8500_ext_regulators),
 };
 
-/* Use the AB8500 init settings for AB8505 as they are the same right now */
 struct ab8500_regulator_platform_data ab8505_regulator_plat_data = {
 	.reg_init               = ab8505_reg_init,
 	.num_reg_init           = ARRAY_SIZE(ab8505_reg_init),
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500-sdi.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500-sdi.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/board-mop500-sdi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/board-mop500-sdi.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,29 +34,25 @@
 #ifdef CONFIG_STE_DMA40
 struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-	.src_dev_type = DB8500_DMA_DEV29_SD_MM0_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.src_info.data_width = STEDMA40_WORD_WIDTH,
-	.dst_info.data_width = STEDMA40_WORD_WIDTH,
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type = DB8500_DMA_DEV29_SD_MM0,
 };
 
 static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-	.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV29_SD_MM0_TX,
-	.src_info.data_width = STEDMA40_WORD_WIDTH,
-	.dst_info.data_width = STEDMA40_WORD_WIDTH,
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV29_SD_MM0,
 };
 #endif
 
 struct mmci_platform_data mop500_sdi0_data = {
-	.ocr_mask	= MMC_VDD_29_30,
-	.f_max		= 50000000,
+	.f_max		= 100000000,
 	.capabilities	= MMC_CAP_4_BIT_DATA |
 				MMC_CAP_SD_HIGHSPEED |
-				MMC_CAP_MMC_HIGHSPEED,
+				MMC_CAP_MMC_HIGHSPEED |
+				MMC_CAP_ERASE |
+				MMC_CAP_UHS_SDR12 |
+				MMC_CAP_UHS_SDR25,
 	.gpio_wp	= -1,
 	.sigdir		= MCI_ST_FBCLKEN |
 				MCI_ST_CMDDIREN |
@@ -87,27 +83,22 @@ void mop500_sdi_tc35892_init(struct devi
 #ifdef CONFIG_STE_DMA40
 static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-	.src_dev_type = DB8500_DMA_DEV32_SD_MM1_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.src_info.data_width = STEDMA40_WORD_WIDTH,
-	.dst_info.data_width = STEDMA40_WORD_WIDTH,
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type = DB8500_DMA_DEV32_SD_MM1,
 };
 
 static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-	.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV32_SD_MM1_TX,
-	.src_info.data_width = STEDMA40_WORD_WIDTH,
-	.dst_info.data_width = STEDMA40_WORD_WIDTH,
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV32_SD_MM1,
 };
 #endif
 
 struct mmci_platform_data mop500_sdi1_data = {
 	.ocr_mask	= MMC_VDD_29_30,
-	.f_max		= 50000000,
-	.capabilities	= MMC_CAP_4_BIT_DATA,
+	.f_max		= 100000000,
+	.capabilities	= MMC_CAP_4_BIT_DATA |
+				MMC_CAP_NONREMOVABLE,
 	.gpio_cd	= -1,
 	.gpio_wp	= -1,
 #ifdef CONFIG_STE_DMA40
@@ -124,28 +115,26 @@ struct mmci_platform_data mop500_sdi1_da
 #ifdef CONFIG_STE_DMA40
 struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-	.src_dev_type =  DB8500_DMA_DEV28_SD_MM2_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.src_info.data_width = STEDMA40_WORD_WIDTH,
-	.dst_info.data_width = STEDMA40_WORD_WIDTH,
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type =  DB8500_DMA_DEV28_SD_MM2,
 };
 
 static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-	.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX,
-	.src_info.data_width = STEDMA40_WORD_WIDTH,
-	.dst_info.data_width = STEDMA40_WORD_WIDTH,
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV28_SD_MM2,
 };
 #endif
 
 struct mmci_platform_data mop500_sdi2_data = {
 	.ocr_mask	= MMC_VDD_165_195,
-	.f_max		= 50000000,
-	.capabilities	= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
-			  MMC_CAP_MMC_HIGHSPEED,
+	.f_max		= 100000000,
+	.capabilities	= MMC_CAP_4_BIT_DATA |
+				MMC_CAP_8_BIT_DATA |
+				MMC_CAP_NONREMOVABLE |
+				MMC_CAP_MMC_HIGHSPEED |
+				MMC_CAP_ERASE |
+				MMC_CAP_CMD23,
 	.gpio_cd	= -1,
 	.gpio_wp	= -1,
 #ifdef CONFIG_STE_DMA40
@@ -162,28 +151,25 @@ struct mmci_platform_data mop500_sdi2_da
 #ifdef CONFIG_STE_DMA40
 struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_PERIPH_TO_MEM,
-	.src_dev_type =  DB8500_DMA_DEV42_SD_MM4_RX,
-	.dst_dev_type = STEDMA40_DEV_DST_MEMORY,
-	.src_info.data_width = STEDMA40_WORD_WIDTH,
-	.dst_info.data_width = STEDMA40_WORD_WIDTH,
+	.dir = DMA_DEV_TO_MEM,
+	.dev_type =  DB8500_DMA_DEV42_SD_MM4,
 };
 
 static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = {
 	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = STEDMA40_MEM_TO_PERIPH,
-	.src_dev_type = STEDMA40_DEV_SRC_MEMORY,
-	.dst_dev_type = DB8500_DMA_DEV42_SD_MM4_TX,
-	.src_info.data_width = STEDMA40_WORD_WIDTH,
-	.dst_info.data_width = STEDMA40_WORD_WIDTH,
+	.dir = DMA_MEM_TO_DEV,
+	.dev_type = DB8500_DMA_DEV42_SD_MM4,
 };
 #endif
 
 struct mmci_platform_data mop500_sdi4_data = {
-	.ocr_mask	= MMC_VDD_29_30,
-	.f_max		= 50000000,
-	.capabilities	= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
-			  MMC_CAP_MMC_HIGHSPEED,
+	.f_max		= 100000000,
+	.capabilities	= MMC_CAP_4_BIT_DATA |
+				MMC_CAP_8_BIT_DATA |
+				MMC_CAP_NONREMOVABLE |
+				MMC_CAP_MMC_HIGHSPEED |
+				MMC_CAP_ERASE |
+				MMC_CAP_CMD23,
 	.gpio_cd	= -1,
 	.gpio_wp	= -1,
 #ifdef CONFIG_STE_DMA40
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/cache-l2x0.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/cache-l2x0.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/cache-l2x0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/cache-l2x0.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,7 +42,8 @@ static int __init ux500_l2x0_init(void)
 	if (cpu_is_u8500_family() || cpu_is_ux540_family())
 		l2x0_base = __io_address(U8500_L2CC_BASE);
 	else
-		ux500_unknown_soc();
+		/* Non-Ux500 platform */
+		return -ENODEV;
 
 	/* Unlock before init */
 	ux500_l2x0_unlock();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/cpu.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/cpu.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/cpu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/cpu.c	2013-08-25 20:43:22.000000000 -0400
@@ -76,13 +76,15 @@ void __init ux500_init_irq(void)
 	} else if (cpu_is_u9540()) {
 		prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1);
 		ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1);
-		u8500_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE,
+		u9540_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE,
 			       U8500_CLKRST3_BASE, U8500_CLKRST5_BASE,
 			       U8500_CLKRST6_BASE);
 	} else if (cpu_is_u8540()) {
 		prcmu_early_init(U8500_PRCMU_BASE, SZ_8K + SZ_4K - 1);
 		ux500_pm_init(U8500_PRCMU_BASE, SZ_8K + SZ_4K - 1);
-		u8540_clk_init();
+		u8540_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE,
+			       U8500_CLKRST3_BASE, U8500_CLKRST5_BASE,
+			       U8500_CLKRST6_BASE);
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/cpu-db8500.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/cpu-db8500.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/cpu-db8500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/cpu-db8500.c	2013-08-25 20:43:22.000000000 -0400
@@ -162,26 +162,15 @@ static void __init db8500_add_gpios(stru
 	dbx500_add_pinctrl(parent, "pinctrl-db8500", U8500_PRCMU_BASE);
 }
 
-static int usb_db8500_rx_dma_cfg[] = {
-	DB8500_DMA_DEV38_USB_OTG_IEP_1_9,
-	DB8500_DMA_DEV37_USB_OTG_IEP_2_10,
-	DB8500_DMA_DEV36_USB_OTG_IEP_3_11,
-	DB8500_DMA_DEV19_USB_OTG_IEP_4_12,
-	DB8500_DMA_DEV18_USB_OTG_IEP_5_13,
-	DB8500_DMA_DEV17_USB_OTG_IEP_6_14,
-	DB8500_DMA_DEV16_USB_OTG_IEP_7_15,
-	DB8500_DMA_DEV39_USB_OTG_IEP_8
-};
-
-static int usb_db8500_tx_dma_cfg[] = {
-	DB8500_DMA_DEV38_USB_OTG_OEP_1_9,
-	DB8500_DMA_DEV37_USB_OTG_OEP_2_10,
-	DB8500_DMA_DEV36_USB_OTG_OEP_3_11,
-	DB8500_DMA_DEV19_USB_OTG_OEP_4_12,
-	DB8500_DMA_DEV18_USB_OTG_OEP_5_13,
-	DB8500_DMA_DEV17_USB_OTG_OEP_6_14,
-	DB8500_DMA_DEV16_USB_OTG_OEP_7_15,
-	DB8500_DMA_DEV39_USB_OTG_OEP_8
+static int usb_db8500_dma_cfg[] = {
+	DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9,
+	DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10,
+	DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11,
+	DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12,
+	DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13,
+	DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14,
+	DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15,
+	DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8
 };
 
 static const char *db8500_read_soc_id(void)
@@ -215,7 +204,7 @@ struct device * __init u8500_init_device
 
 	db8500_add_rtc(parent);
 	db8500_add_gpios(parent);
-	db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
+	db8500_add_usb(parent, usb_db8500_dma_cfg, usb_db8500_dma_cfg);
 
 	for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
 		platform_devs[i]->dev.parent = parent;
@@ -226,34 +215,13 @@ struct device * __init u8500_init_device
 }
 
 #ifdef CONFIG_MACH_UX500_DT
-
-/* TODO: Once all pieces are DT:ed, remove completely. */
-static struct device * __init u8500_of_init_devices(void)
-{
-	struct device *parent = db8500_soc_device_init();
-
-	db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
-
-	u8500_dma40_device.dev.parent = parent;
-
-	/*
-	 * Devices to be DT:ed:
-	 *   u8500_dma40_device  = todo
-	 *   db8500_pmu_device   = done
-	 *   db8500_prcmu_device = done
-	 */
-	platform_device_register(&u8500_dma40_device);
-
-	return parent;
-}
-
 static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
 	/* Requires call-back bindings. */
 	OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
 	/* Requires DMA bindings. */
-	OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat),
-	OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat),
-	OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat),
+	OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", NULL),
+	OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", NULL),
+	OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", NULL),
 	OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0",  &ssp0_plat),
 	OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0",  &mop500_sdi0_data),
 	OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1",  &mop500_sdi1_data),
@@ -274,11 +242,16 @@ static struct of_dev_auxdata u8500_auxda
 	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80128000, "nmk-i2c.2", NULL),
 	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL),
 	OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),
+	OF_DEV_AUXDATA("stericsson,db8500-musb", 0xa03e0000, "musb-ux500.0", NULL),
 	OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu",
 			&db8500_prcmu_pdata),
 	OF_DEV_AUXDATA("smsc,lan9115", 0x50000000, "smsc911x.0", NULL),
+	OF_DEV_AUXDATA("stericsson,ux500-cryp", 0xa03cb000, "cryp1", NULL),
+	OF_DEV_AUXDATA("stericsson,ux500-hash", 0xa03c2000, "hash1", NULL),
+	OF_DEV_AUXDATA("stericsson,snd-soc-mop500", 0, "snd-soc-mop500.0",
+			NULL),
 	/* Requires device name bindings. */
-	OF_DEV_AUXDATA("stericsson,nmk-pinctrl", U8500_PRCMU_BASE,
+	OF_DEV_AUXDATA("stericsson,db8500-pinctrl", U8500_PRCMU_BASE,
 		"pinctrl-db8500", NULL),
 	/* Requires clock name and DMA bindings. */
 	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
@@ -289,6 +262,18 @@ static struct of_dev_auxdata u8500_auxda
 		"ux500-msp-i2s.2", &msp2_platform_data),
 	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000,
 		"ux500-msp-i2s.3", &msp3_platform_data),
+	/* Requires clock name bindings and channel address lookup table. */
+	OF_DEV_AUXDATA("stericsson,db8500-dma40", 0x801C0000, "dma40.0", NULL),
+	{},
+};
+
+static struct of_dev_auxdata u8540_auxdata_lookup[] __initdata = {
+	/* Requires DMA bindings. */
+	OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", NULL),
+	OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", NULL),
+	OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", NULL),
+	OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu",
+			&db8500_prcmu_pdata),
 	{},
 };
 
@@ -302,24 +287,25 @@ static const struct of_device_id u8500_l
 
 static void __init u8500_init_machine(void)
 {
-	struct device *parent = NULL;
+	struct device *parent = db8500_soc_device_init();
 
 	/* Pinmaps must be in place before devices register */
 	if (of_machine_is_compatible("st-ericsson,mop500"))
 		mop500_pinmaps_init();
 	else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
 		snowball_pinmaps_init();
-		mop500_snowball_ethernet_clock_enable();
 	} else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
 		hrefv60_pinmaps_init();
 	else if (of_machine_is_compatible("st-ericsson,ccu9540")) {}
 		/* TODO: Add pinmaps for ccu9540 board. */
 
-	/* TODO: Export SoC, USB, cpu-freq and DMA40 */
-	parent = u8500_of_init_devices();
-
-	/* automatically probe child nodes of db8500 device */
-	of_platform_populate(NULL, u8500_local_bus_nodes, u8500_auxdata_lookup, parent);
+	/* automatically probe child nodes of dbx5x0 devices */
+	if (of_machine_is_compatible("st-ericsson,u8540"))
+		of_platform_populate(NULL, u8500_local_bus_nodes,
+				     u8540_auxdata_lookup, parent);
+	else
+		of_platform_populate(NULL, u8500_local_bus_nodes,
+				     u8500_auxdata_lookup, parent);
 }
 
 static const char * stericsson_dt_platform_compat[] = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/db8500-regs.h linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/db8500-regs.h
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/db8500-regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/db8500-regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -102,7 +102,6 @@
 #define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x07000)
 #define U9540_DMC1_BASE		(U8500_PER4_BASE + 0x0A000)
 #define U8500_PRCMU_TCDM_BASE	(U8500_PER4_BASE + 0x68000)
-#define U9540_PRCMU_TCDM_BASE	(U8500_PER4_BASE + 0x6A000)
 #define U8500_PRCMU_TCPM_BASE   (U8500_PER4_BASE + 0x60000)
 #define U8500_PRCMU_TIMER_3_BASE (U8500_PER4_BASE + 0x07338)
 #define U8500_PRCMU_TIMER_4_BASE (U8500_PER4_BASE + 0x07450)
@@ -184,7 +183,7 @@
 #define U8500_IO_VIRTUAL	0xf0000000
 #define U8500_IO_PHYSICAL	0xa0000000
 /* This is where we map in the ROM to check ASIC IDs */
-#define UX500_VIRT_ROM		0xf0000000
+#define UX500_VIRT_ROM		IOMEM(0xf0000000)
 
 /* This macro is used in assembly, so no cast */
 #define IO_ADDRESS(x)           \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/devices-db8500.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/devices-db8500.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/devices-db8500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/devices-db8500.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,128 +42,7 @@ static struct resource dma40_resources[]
 	}
 };
 
-/* Default configuration for physcial memcpy */
-struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
-	.mode = STEDMA40_MODE_PHYSICAL,
-	.dir = STEDMA40_MEM_TO_MEM,
-
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.src_info.psize = STEDMA40_PSIZE_PHY_1,
-	.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
-
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.psize = STEDMA40_PSIZE_PHY_1,
-	.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
-};
-/* Default configuration for logical memcpy */
-struct stedma40_chan_cfg dma40_memcpy_conf_log = {
-	.dir = STEDMA40_MEM_TO_MEM,
-
-	.src_info.data_width = STEDMA40_BYTE_WIDTH,
-	.src_info.psize = STEDMA40_PSIZE_LOG_1,
-	.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
-
-	.dst_info.data_width = STEDMA40_BYTE_WIDTH,
-	.dst_info.psize = STEDMA40_PSIZE_LOG_1,
-	.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
-};
-
-/*
- * Mapping between destination event lines and physical device address.
- * The event line is tied to a device and therefore the address is constant.
- * When the address comes from a primecell it will be configured in runtime
- * and we set the address to -1 as a placeholder.
- */
-static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = {
-	/* MUSB - these will be runtime-reconfigured */
-	[DB8500_DMA_DEV39_USB_OTG_OEP_8] = -1,
-	[DB8500_DMA_DEV16_USB_OTG_OEP_7_15] = -1,
-	[DB8500_DMA_DEV17_USB_OTG_OEP_6_14] = -1,
-	[DB8500_DMA_DEV18_USB_OTG_OEP_5_13] = -1,
-	[DB8500_DMA_DEV19_USB_OTG_OEP_4_12] = -1,
-	[DB8500_DMA_DEV36_USB_OTG_OEP_3_11] = -1,
-	[DB8500_DMA_DEV37_USB_OTG_OEP_2_10] = -1,
-	[DB8500_DMA_DEV38_USB_OTG_OEP_1_9] = -1,
-	/* PrimeCells - run-time configured */
-	[DB8500_DMA_DEV0_SPI0_TX] = -1,
-	[DB8500_DMA_DEV1_SD_MMC0_TX] = -1,
-	[DB8500_DMA_DEV2_SD_MMC1_TX] = -1,
-	[DB8500_DMA_DEV3_SD_MMC2_TX] = -1,
-	[DB8500_DMA_DEV8_SSP0_TX] = -1,
-	[DB8500_DMA_DEV9_SSP1_TX] = -1,
-	[DB8500_DMA_DEV11_UART2_TX] = -1,
-	[DB8500_DMA_DEV12_UART1_TX] = -1,
-	[DB8500_DMA_DEV13_UART0_TX] = -1,
-	[DB8500_DMA_DEV28_SD_MM2_TX] = -1,
-	[DB8500_DMA_DEV29_SD_MM0_TX] = -1,
-	[DB8500_DMA_DEV32_SD_MM1_TX] = -1,
-	[DB8500_DMA_DEV33_SPI2_TX] = -1,
-	[DB8500_DMA_DEV35_SPI1_TX] = -1,
-	[DB8500_DMA_DEV40_SPI3_TX] = -1,
-	[DB8500_DMA_DEV41_SD_MM3_TX] = -1,
-	[DB8500_DMA_DEV42_SD_MM4_TX] = -1,
-	[DB8500_DMA_DEV43_SD_MM5_TX] = -1,
-	[DB8500_DMA_DEV14_MSP2_TX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
-	[DB8500_DMA_DEV30_MSP1_TX] = U8500_MSP1_BASE + MSP_TX_RX_REG_OFFSET,
-	[DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
-	[DB8500_DMA_DEV48_CAC1_TX] = U8500_CRYP1_BASE + CRYP1_TX_REG_OFFSET,
-	[DB8500_DMA_DEV50_HAC1_TX] = U8500_HASH1_BASE + HASH1_TX_REG_OFFSET,
-};
-
-/* Mapping between source event lines and physical device address */
-static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = {
-	/* MUSB - these will be runtime-reconfigured */
-	[DB8500_DMA_DEV39_USB_OTG_IEP_8] = -1,
-	[DB8500_DMA_DEV16_USB_OTG_IEP_7_15] = -1,
-	[DB8500_DMA_DEV17_USB_OTG_IEP_6_14] = -1,
-	[DB8500_DMA_DEV18_USB_OTG_IEP_5_13] = -1,
-	[DB8500_DMA_DEV19_USB_OTG_IEP_4_12] = -1,
-	[DB8500_DMA_DEV36_USB_OTG_IEP_3_11] = -1,
-	[DB8500_DMA_DEV37_USB_OTG_IEP_2_10] = -1,
-	[DB8500_DMA_DEV38_USB_OTG_IEP_1_9] = -1,
-	/* PrimeCells */
-	[DB8500_DMA_DEV0_SPI0_RX] = -1,
-	[DB8500_DMA_DEV1_SD_MMC0_RX] = -1,
-	[DB8500_DMA_DEV2_SD_MMC1_RX] = -1,
-	[DB8500_DMA_DEV3_SD_MMC2_RX] = -1,
-	[DB8500_DMA_DEV8_SSP0_RX] = -1,
-	[DB8500_DMA_DEV9_SSP1_RX] = -1,
-	[DB8500_DMA_DEV11_UART2_RX] = -1,
-	[DB8500_DMA_DEV12_UART1_RX] = -1,
-	[DB8500_DMA_DEV13_UART0_RX] = -1,
-	[DB8500_DMA_DEV28_SD_MM2_RX] = -1,
-	[DB8500_DMA_DEV29_SD_MM0_RX] = -1,
-	[DB8500_DMA_DEV32_SD_MM1_RX] = -1,
-	[DB8500_DMA_DEV33_SPI2_RX] = -1,
-	[DB8500_DMA_DEV35_SPI1_RX] = -1,
-	[DB8500_DMA_DEV40_SPI3_RX] = -1,
-	[DB8500_DMA_DEV41_SD_MM3_RX] = -1,
-	[DB8500_DMA_DEV42_SD_MM4_RX] = -1,
-	[DB8500_DMA_DEV43_SD_MM5_RX] = -1,
-	[DB8500_DMA_DEV14_MSP2_RX] = U8500_MSP2_BASE + MSP_TX_RX_REG_OFFSET,
-	[DB8500_DMA_DEV30_MSP3_RX] = U8500_MSP3_BASE + MSP_TX_RX_REG_OFFSET,
-	[DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX] = U8500_MSP0_BASE + MSP_TX_RX_REG_OFFSET,
-	[DB8500_DMA_DEV48_CAC1_RX] = U8500_CRYP1_BASE + CRYP1_RX_REG_OFFSET,
-};
-
-/* Reserved event lines for memcpy only */
-static int dma40_memcpy_event[] = {
-	DB8500_DMA_MEMCPY_TX_0,
-	DB8500_DMA_MEMCPY_TX_1,
-	DB8500_DMA_MEMCPY_TX_2,
-	DB8500_DMA_MEMCPY_TX_3,
-	DB8500_DMA_MEMCPY_TX_4,
-	DB8500_DMA_MEMCPY_TX_5,
-};
-
-static struct stedma40_platform_data dma40_plat_data = {
-	.dev_len = DB8500_DMA_NR_DEV,
-	.dev_rx = dma40_rx_map,
-	.dev_tx = dma40_tx_map,
-	.memcpy = dma40_memcpy_event,
-	.memcpy_len = ARRAY_SIZE(dma40_memcpy_event),
-	.memcpy_conf_phy = &dma40_memcpy_conf_phy,
-	.memcpy_conf_log = &dma40_memcpy_conf_log,
+struct stedma40_platform_data dma40_plat_data = {
 	.disabled_channels = {-1},
 };
 
@@ -227,7 +106,7 @@ static struct resource db8500_prcmu_res[
 	{
 		.name  = "prcmu-tcpm",
 		.start = U8500_PRCMU_TCPM_BASE,
-		.end   = U8500_PRCMU_TCPM_BASE + SZ_4K - 1,
+		.end   = U8500_PRCMU_TCPM_BASE + SZ_32K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/id.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/id.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/id.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/id.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,11 +21,11 @@
 
 struct dbx500_asic_id dbx500_id;
 
-static unsigned int ux500_read_asicid(phys_addr_t addr)
+static unsigned int __init ux500_read_asicid(phys_addr_t addr)
 {
 	phys_addr_t base = addr & ~0xfff;
 	struct map_desc desc = {
-		.virtual	= UX500_VIRT_ROM,
+		.virtual	= (unsigned long)UX500_VIRT_ROM,
 		.pfn		= __phys_to_pfn(base),
 		.length		= SZ_16K,
 		.type		= MT_DEVICE,
@@ -37,7 +37,7 @@ static unsigned int ux500_read_asicid(ph
 	local_flush_tlb_all();
 	flush_cache_all();
 
-	return readl(IOMEM(UX500_VIRT_ROM + (addr & 0xfff)));
+	return readl(UX500_VIRT_ROM + (addr & 0xfff));
 }
 
 static void ux500_print_soc_info(unsigned int asicid)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ static void __iomem *scu_base_addr(void)
 
 static DEFINE_SPINLOCK(boot_lock);
 
-static void __cpuinit ux500_secondary_init(unsigned int cpu)
+static void ux500_secondary_init(unsigned int cpu)
 {
 	/*
 	 * let the primary processor know we're out of the
@@ -69,7 +69,7 @@ static void __cpuinit ux500_secondary_in
 	spin_unlock(&boot_lock);
 }
 
-static int __cpuinit ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/ste-dma40-db8500.h linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/ste-dma40-db8500.h
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/ste-dma40-db8500.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/ste-dma40-db8500.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,133 +12,74 @@
 
 #define DB8500_DMA_NR_DEV 64
 
-enum dma_src_dev_type {
-	DB8500_DMA_DEV0_SPI0_RX = 0,
-	DB8500_DMA_DEV1_SD_MMC0_RX = 1,
-	DB8500_DMA_DEV2_SD_MMC1_RX = 2,
-	DB8500_DMA_DEV3_SD_MMC2_RX = 3,
-	DB8500_DMA_DEV4_I2C1_RX = 4,
-	DB8500_DMA_DEV5_I2C3_RX = 5,
-	DB8500_DMA_DEV6_I2C2_RX = 6,
-	DB8500_DMA_DEV7_I2C4_RX = 7, /* Only on V1 and later */
-	DB8500_DMA_DEV8_SSP0_RX = 8,
-	DB8500_DMA_DEV9_SSP1_RX = 9,
-	DB8500_DMA_DEV10_MCDE_RX = 10,
-	DB8500_DMA_DEV11_UART2_RX = 11,
-	DB8500_DMA_DEV12_UART1_RX = 12,
-	DB8500_DMA_DEV13_UART0_RX = 13,
-	DB8500_DMA_DEV14_MSP2_RX = 14,
-	DB8500_DMA_DEV15_I2C0_RX = 15,
-	DB8500_DMA_DEV16_USB_OTG_IEP_7_15 = 16,
-	DB8500_DMA_DEV17_USB_OTG_IEP_6_14 = 17,
-	DB8500_DMA_DEV18_USB_OTG_IEP_5_13 = 18,
-	DB8500_DMA_DEV19_USB_OTG_IEP_4_12 = 19,
-	DB8500_DMA_DEV20_SLIM0_CH0_RX_HSI_RX_CH0 = 20,
-	DB8500_DMA_DEV21_SLIM0_CH1_RX_HSI_RX_CH1 = 21,
-	DB8500_DMA_DEV22_SLIM0_CH2_RX_HSI_RX_CH2 = 22,
-	DB8500_DMA_DEV23_SLIM0_CH3_RX_HSI_RX_CH3 = 23,
-	DB8500_DMA_DEV24_SRC_SXA0_RX_TX = 24,
-	DB8500_DMA_DEV25_SRC_SXA1_RX_TX = 25,
-	DB8500_DMA_DEV26_SRC_SXA2_RX_TX = 26,
-	DB8500_DMA_DEV27_SRC_SXA3_RX_TX = 27,
-	DB8500_DMA_DEV28_SD_MM2_RX = 28,
-	DB8500_DMA_DEV29_SD_MM0_RX = 29,
-	DB8500_DMA_DEV30_MSP1_RX = 30,
+/*
+ * Unless otherwise specified, all channels numbers are used for
+ * TX & RX, and can be used for either source or destination
+ * channels.
+ */
+enum dma_dev_type {
+	DB8500_DMA_DEV0_SPI0 = 0,
+	DB8500_DMA_DEV1_SD_MMC0 = 1,
+	DB8500_DMA_DEV2_SD_MMC1 = 2,
+	DB8500_DMA_DEV3_SD_MMC2 = 3,
+	DB8500_DMA_DEV4_I2C1 = 4,
+	DB8500_DMA_DEV5_I2C3 = 5,
+	DB8500_DMA_DEV6_I2C2 = 6,
+	DB8500_DMA_DEV7_I2C4 = 7,			/* Only on V1 and later */
+	DB8500_DMA_DEV8_SSP0 = 8,
+	DB8500_DMA_DEV9_SSP1 = 9,
+	DB8500_DMA_DEV10_MCDE_RX = 10,			/* RX only */
+	DB8500_DMA_DEV11_UART2 = 11,
+	DB8500_DMA_DEV12_UART1 = 12,
+	DB8500_DMA_DEV13_UART0 = 13,
+	DB8500_DMA_DEV14_MSP2 = 14,
+	DB8500_DMA_DEV15_I2C0 = 15,
+	DB8500_DMA_DEV16_USB_OTG_IEP_AND_OEP_7_15 = 16,
+	DB8500_DMA_DEV17_USB_OTG_IEP_AND_OEP_6_14 = 17,
+	DB8500_DMA_DEV18_USB_OTG_IEP_AND_OEP_5_13 = 18,
+	DB8500_DMA_DEV19_USB_OTG_IEP_AND_OEP_4_12 = 19,
+	DB8500_DMA_DEV20_SLIM0_CH0_HSI_CH0 = 20,
+	DB8500_DMA_DEV21_SLIM0_CH1_HSI_CH1 = 21,
+	DB8500_DMA_DEV22_SLIM0_CH2_HSI_CH2 = 22,
+	DB8500_DMA_DEV23_SLIM0_CH3_HSI_CH3 = 23,
+	DB8500_DMA_DEV24_SXA0 = 24,
+	DB8500_DMA_DEV25_SXA1 = 25,
+	DB8500_DMA_DEV26_SXA2 = 26,
+	DB8500_DMA_DEV27_SXA3 = 27,
+	DB8500_DMA_DEV28_SD_MM2 = 28,
+	DB8500_DMA_DEV29_SD_MM0 = 29,
+	DB8500_DMA_DEV30_MSP1 = 30,
 	/* On DB8500v2, MSP3 RX replaces MSP1 RX */
-	DB8500_DMA_DEV30_MSP3_RX = 30,
-	DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX = 31,
-	DB8500_DMA_DEV32_SD_MM1_RX = 32,
-	DB8500_DMA_DEV33_SPI2_RX = 33,
-	DB8500_DMA_DEV34_I2C3_RX2 = 34,
-	DB8500_DMA_DEV35_SPI1_RX = 35,
-	DB8500_DMA_DEV36_USB_OTG_IEP_3_11 = 36,
-	DB8500_DMA_DEV37_USB_OTG_IEP_2_10 = 37,
-	DB8500_DMA_DEV38_USB_OTG_IEP_1_9 = 38,
-	DB8500_DMA_DEV39_USB_OTG_IEP_8 = 39,
-	DB8500_DMA_DEV40_SPI3_RX = 40,
-	DB8500_DMA_DEV41_SD_MM3_RX = 41,
-	DB8500_DMA_DEV42_SD_MM4_RX = 42,
-	DB8500_DMA_DEV43_SD_MM5_RX = 43,
-	DB8500_DMA_DEV44_SRC_SXA4_RX_TX = 44,
-	DB8500_DMA_DEV45_SRC_SXA5_RX_TX = 45,
-	DB8500_DMA_DEV46_SLIM0_CH8_RX_SRC_SXA6_RX_TX = 46,
-	DB8500_DMA_DEV47_SLIM0_CH9_RX_SRC_SXA7_RX_TX = 47,
-	DB8500_DMA_DEV48_CAC1_RX = 48,
-	/* 49, 50 and 51 are not used */
-	DB8500_DMA_DEV52_SLIM0_CH4_RX_HSI_RX_CH4 = 52,
-	DB8500_DMA_DEV53_SLIM0_CH5_RX_HSI_RX_CH5 = 53,
-	DB8500_DMA_DEV54_SLIM0_CH6_RX_HSI_RX_CH6 = 54,
-	DB8500_DMA_DEV55_SLIM0_CH7_RX_HSI_RX_CH7 = 55,
-	/* 56, 57, 58, 59 and 60 are not used */
-	DB8500_DMA_DEV61_CAC0_RX = 61,
-	/* 62 and 63 are not used */
-};
-
-enum dma_dest_dev_type {
-	DB8500_DMA_DEV0_SPI0_TX = 0,
-	DB8500_DMA_DEV1_SD_MMC0_TX = 1,
-	DB8500_DMA_DEV2_SD_MMC1_TX = 2,
-	DB8500_DMA_DEV3_SD_MMC2_TX = 3,
-	DB8500_DMA_DEV4_I2C1_TX = 4,
-	DB8500_DMA_DEV5_I2C3_TX = 5,
-	DB8500_DMA_DEV6_I2C2_TX = 6,
-	DB8500_DMA_DEV7_I2C4_TX = 7, /* Only on V1 and later */
-	DB8500_DMA_DEV8_SSP0_TX = 8,
-	DB8500_DMA_DEV9_SSP1_TX = 9,
-	/* 10 is not used*/
-	DB8500_DMA_DEV11_UART2_TX = 11,
-	DB8500_DMA_DEV12_UART1_TX = 12,
-	DB8500_DMA_DEV13_UART0_TX = 13,
-	DB8500_DMA_DEV14_MSP2_TX = 14,
-	DB8500_DMA_DEV15_I2C0_TX = 15,
-	DB8500_DMA_DEV16_USB_OTG_OEP_7_15 = 16,
-	DB8500_DMA_DEV17_USB_OTG_OEP_6_14 = 17,
-	DB8500_DMA_DEV18_USB_OTG_OEP_5_13 = 18,
-	DB8500_DMA_DEV19_USB_OTG_OEP_4_12 = 19,
-	DB8500_DMA_DEV20_SLIM0_CH0_TX_HSI_TX_CH0 = 20,
-	DB8500_DMA_DEV21_SLIM0_CH1_TX_HSI_TX_CH1 = 21,
-	DB8500_DMA_DEV22_SLIM0_CH2_TX_HSI_TX_CH2 = 22,
-	DB8500_DMA_DEV23_SLIM0_CH3_TX_HSI_TX_CH3 = 23,
-	DB8500_DMA_DEV24_DST_SXA0_RX_TX = 24,
-	DB8500_DMA_DEV25_DST_SXA1_RX_TX = 25,
-	DB8500_DMA_DEV26_DST_SXA2_RX_TX = 26,
-	DB8500_DMA_DEV27_DST_SXA3_RX_TX = 27,
-	DB8500_DMA_DEV28_SD_MM2_TX = 28,
-	DB8500_DMA_DEV29_SD_MM0_TX = 29,
-	DB8500_DMA_DEV30_MSP1_TX = 30,
-	DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX = 31,
-	DB8500_DMA_DEV32_SD_MM1_TX = 32,
-	DB8500_DMA_DEV33_SPI2_TX = 33,
-	DB8500_DMA_DEV34_I2C3_TX2 = 34,
-	DB8500_DMA_DEV35_SPI1_TX = 35,
-	DB8500_DMA_DEV36_USB_OTG_OEP_3_11 = 36,
-	DB8500_DMA_DEV37_USB_OTG_OEP_2_10 = 37,
-	DB8500_DMA_DEV38_USB_OTG_OEP_1_9 = 38,
-	DB8500_DMA_DEV39_USB_OTG_OEP_8 = 39,
-	DB8500_DMA_DEV40_SPI3_TX = 40,
-	DB8500_DMA_DEV41_SD_MM3_TX = 41,
-	DB8500_DMA_DEV42_SD_MM4_TX = 42,
-	DB8500_DMA_DEV43_SD_MM5_TX = 43,
-	DB8500_DMA_DEV44_DST_SXA4_RX_TX = 44,
-	DB8500_DMA_DEV45_DST_SXA5_RX_TX = 45,
-	DB8500_DMA_DEV46_SLIM0_CH8_TX_DST_SXA6_RX_TX = 46,
-	DB8500_DMA_DEV47_SLIM0_CH9_TX_DST_SXA7_RX_TX = 47,
-	DB8500_DMA_DEV48_CAC1_TX  = 48,
-	DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49,
-	DB8500_DMA_DEV50_HAC1_TX = 50,
-	DB8500_DMA_MEMCPY_TX_0 = 51,
-	DB8500_DMA_DEV52_SLIM1_CH4_TX_HSI_TX_CH4 = 52,
-	DB8500_DMA_DEV53_SLIM1_CH5_TX_HSI_TX_CH5 = 53,
-	DB8500_DMA_DEV54_SLIM1_CH6_TX_HSI_TX_CH6 = 54,
-	DB8500_DMA_DEV55_SLIM1_CH7_TX_HSI_TX_CH7 = 55,
-	DB8500_DMA_MEMCPY_TX_1 = 56,
-	DB8500_DMA_MEMCPY_TX_2 = 57,
-	DB8500_DMA_MEMCPY_TX_3 = 58,
-	DB8500_DMA_MEMCPY_TX_4 = 59,
-	DB8500_DMA_MEMCPY_TX_5 = 60,
-	DB8500_DMA_DEV61_CAC0_TX = 61,
-	DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62,
-	DB8500_DMA_DEV63_HAC0_TX = 63,
+	DB8500_DMA_DEV30_MSP3 = 30,
+	DB8500_DMA_DEV31_MSP0_SLIM0_CH0 = 31,
+	DB8500_DMA_DEV32_SD_MM1 = 32,
+	DB8500_DMA_DEV33_SPI2 = 33,
+	DB8500_DMA_DEV34_I2C3_RX2_TX2 = 34,
+	DB8500_DMA_DEV35_SPI1 = 35,
+	DB8500_DMA_DEV36_USB_OTG_IEP_AND_OEP_3_11 = 36,
+	DB8500_DMA_DEV37_USB_OTG_IEP_AND_OEP_2_10 = 37,
+	DB8500_DMA_DEV38_USB_OTG_IEP_AND_OEP_1_9 = 38,
+	DB8500_DMA_DEV39_USB_OTG_IEP_AND_OEP_8 = 39,
+	DB8500_DMA_DEV40_SPI3 = 40,
+	DB8500_DMA_DEV41_SD_MM3 = 41,
+	DB8500_DMA_DEV42_SD_MM4 = 42,
+	DB8500_DMA_DEV43_SD_MM5 = 43,
+	DB8500_DMA_DEV44_SXA4 = 44,
+	DB8500_DMA_DEV45_SXA5 = 45,
+	DB8500_DMA_DEV46_SLIM0_CH8_SRC_SXA6 = 46,
+	DB8500_DMA_DEV47_SLIM0_CH9_SRC_SXA7 = 47,
+	DB8500_DMA_DEV48_CAC1 = 48,
+	DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49,		/* TX only */
+	DB8500_DMA_DEV50_HAC1_TX = 50,			/* TX only */
+	DB8500_DMA_MEMCPY_TX_0 = 51,			/* TX only */
+	DB8500_DMA_DEV52_SLIM0_CH4_HSI_CH4 = 52,
+	DB8500_DMA_DEV53_SLIM0_CH5_HSI_CH5 = 53,
+	DB8500_DMA_DEV54_SLIM0_CH6_HSI_CH6 = 54,
+	DB8500_DMA_DEV55_SLIM0_CH7_HSI_CH7 = 55,
+	/* 56 -> 60 are channels reserved for memcpy only */
+	DB8500_DMA_DEV61_CAC0 = 61,
+	DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62,		/* TX only */
+	DB8500_DMA_DEV63_HAC0_TX = 63,			/* TX only */
 };
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-ux500/usb.c linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/usb.c
--- linux-libre-3.10-gnu/arch/arm/mach-ux500/usb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-ux500/usb.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,25 +14,15 @@
 
 #define MUSB_DMA40_RX_CH { \
 		.mode = STEDMA40_MODE_LOGICAL, \
-		.dir = STEDMA40_PERIPH_TO_MEM, \
-		.dst_dev_type = STEDMA40_DEV_DST_MEMORY, \
-		.src_info.data_width = STEDMA40_WORD_WIDTH, \
-		.dst_info.data_width = STEDMA40_WORD_WIDTH, \
-		.src_info.psize = STEDMA40_PSIZE_LOG_16, \
-		.dst_info.psize = STEDMA40_PSIZE_LOG_16, \
+		.dir = DMA_DEV_TO_MEM, \
 	}
 
 #define MUSB_DMA40_TX_CH { \
 		.mode = STEDMA40_MODE_LOGICAL, \
-		.dir = STEDMA40_MEM_TO_PERIPH, \
-		.src_dev_type = STEDMA40_DEV_SRC_MEMORY, \
-		.src_info.data_width = STEDMA40_WORD_WIDTH, \
-		.dst_info.data_width = STEDMA40_WORD_WIDTH, \
-		.src_info.psize = STEDMA40_PSIZE_LOG_16, \
-		.dst_info.psize = STEDMA40_PSIZE_LOG_16, \
+		.dir = DMA_MEM_TO_DEV, \
 	}
 
-static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS]
+static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
 	= {
 	MUSB_DMA40_RX_CH,
 	MUSB_DMA40_RX_CH,
@@ -44,7 +34,7 @@ static struct stedma40_chan_cfg musb_dma
 	MUSB_DMA40_RX_CH
 };
 
-static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS]
+static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS]
 	= {
 	MUSB_DMA40_TX_CH,
 	MUSB_DMA40_TX_CH,
@@ -56,7 +46,7 @@ static struct stedma40_chan_cfg musb_dma
 	MUSB_DMA40_TX_CH,
 };
 
-static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = {
+static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
 	&musb_dma_rx_ch[0],
 	&musb_dma_rx_ch[1],
 	&musb_dma_rx_ch[2],
@@ -67,7 +57,7 @@ static void *ux500_dma_rx_param_array[UX
 	&musb_dma_rx_ch[7]
 };
 
-static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = {
+static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_RX_TX_CHANNELS] = {
 	&musb_dma_tx_ch[0],
 	&musb_dma_tx_ch[1],
 	&musb_dma_tx_ch[2],
@@ -81,23 +71,11 @@ static void *ux500_dma_tx_param_array[UX
 static struct ux500_musb_board_data musb_board_data = {
 	.dma_rx_param_array = ux500_dma_rx_param_array,
 	.dma_tx_param_array = ux500_dma_tx_param_array,
-	.num_rx_channels = UX500_MUSB_DMA_NUM_RX_CHANNELS,
-	.num_tx_channels = UX500_MUSB_DMA_NUM_TX_CHANNELS,
 	.dma_filter = stedma40_filter,
 };
 
-static u64 ux500_musb_dmamask = DMA_BIT_MASK(32);
-
-static struct musb_hdrc_config musb_hdrc_config = {
-	.multipoint	= true,
-	.dyn_fifo	= true,
-	.num_eps	= 16,
-	.ram_bits	= 16,
-};
-
 static struct musb_hdrc_platform_data musb_platform_data = {
 	.mode = MUSB_OTG,
-	.config = &musb_hdrc_config,
 	.board_data = &musb_board_data,
 };
 
@@ -118,27 +96,26 @@ struct platform_device ux500_musb_device
 	.id = 0,
 	.dev = {
 		.platform_data = &musb_platform_data,
-		.dma_mask = &ux500_musb_dmamask,
 		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 	.num_resources = ARRAY_SIZE(usb_resources),
 	.resource = usb_resources,
 };
 
-static inline void ux500_usb_dma_update_rx_ch_config(int *src_dev_type)
+static inline void ux500_usb_dma_update_rx_ch_config(int *dev_type)
 {
 	u32 idx;
 
-	for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_CHANNELS; idx++)
-		musb_dma_rx_ch[idx].src_dev_type = src_dev_type[idx];
+	for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
+		musb_dma_rx_ch[idx].dev_type = dev_type[idx];
 }
 
-static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type)
+static inline void ux500_usb_dma_update_tx_ch_config(int *dev_type)
 {
 	u32 idx;
 
-	for (idx = 0; idx < UX500_MUSB_DMA_NUM_TX_CHANNELS; idx++)
-		musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx];
+	for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_TX_CHANNELS; idx++)
+		musb_dma_tx_ch[idx].dev_type = dev_type[idx];
 }
 
 void ux500_add_usb(struct device *parent, resource_size_t base, int irq,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-versatile/core.c linux-libre-3.11-rc7-gnu/arch/arm/mach-versatile/core.c
--- linux-libre-3.10-gnu/arch/arm/mach-versatile/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-versatile/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/clkdev.h>
 #include <linux/mtd/physmap.h>
 #include <linux/bitops.h>
+#include <linux/reboot.h>
 
 #include <asm/irq.h>
 #include <asm/hardware/arm_timer.h>
@@ -733,7 +734,7 @@ static void versatile_leds_event(led_eve
 }
 #endif	/* CONFIG_LEDS */
 
-void versatile_restart(char mode, const char *cmd)
+void versatile_restart(enum reboot_mode mode, const char *cmd)
 {
 	void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
 	u32 val;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-versatile/core.h linux-libre-3.11-rc7-gnu/arch/arm/mach-versatile/core.h
--- linux-libre-3.10-gnu/arch/arm/mach-versatile/core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-versatile/core.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,13 +24,14 @@
 
 #include <linux/amba/bus.h>
 #include <linux/of_platform.h>
+#include <linux/reboot.h>
 
 extern void __init versatile_init(void);
 extern void __init versatile_init_early(void);
 extern void __init versatile_init_irq(void);
 extern void __init versatile_map_io(void);
 extern void versatile_timer_init(void);
-extern void versatile_restart(char, const char *);
+extern void versatile_restart(enum reboot_mode, const char *);
 extern unsigned int mmc_status(struct device *dev);
 #ifdef CONFIG_OF
 extern struct of_dev_auxdata versatile_auxdata_lookup[];
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-vexpress/core.h linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/core.h
--- linux-libre-3.10-gnu/arch/arm/mach-vexpress/core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/core.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,6 +6,8 @@
 
 void vexpress_dt_smp_map_io(void);
 
+bool vexpress_smp_init_ops(void);
+
 extern struct smp_operations	vexpress_smp_ops;
 
 extern void vexpress_cpu_die(unsigned int cpu);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-vexpress/dcscb.c linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/dcscb.c
--- linux-libre-3.10-gnu/arch/arm/mach-vexpress/dcscb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/dcscb.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,253 @@
+/*
+ * arch/arm/mach-vexpress/dcscb.c - Dual Cluster System Configuration Block
+ *
+ * Created by:	Nicolas Pitre, May 2012
+ * Copyright:	(C) 2012-2013  Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/of_address.h>
+#include <linux/vexpress.h>
+#include <linux/arm-cci.h>
+
+#include <asm/mcpm.h>
+#include <asm/proc-fns.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <asm/cp15.h>
+
+
+#define RST_HOLD0	0x0
+#define RST_HOLD1	0x4
+#define SYS_SWRESET	0x8
+#define RST_STAT0	0xc
+#define RST_STAT1	0x10
+#define EAG_CFG_R	0x20
+#define EAG_CFG_W	0x24
+#define KFC_CFG_R	0x28
+#define KFC_CFG_W	0x2c
+#define DCS_CFG_R	0x30
+
+/*
+ * We can't use regular spinlocks. In the switcher case, it is possible
+ * for an outbound CPU to call power_down() while its inbound counterpart
+ * is already live using the same logical CPU number which trips lockdep
+ * debugging.
+ */
+static arch_spinlock_t dcscb_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+
+static void __iomem *dcscb_base;
+static int dcscb_use_count[4][2];
+static int dcscb_allcpus_mask[2];
+
+static int dcscb_power_up(unsigned int cpu, unsigned int cluster)
+{
+	unsigned int rst_hold, cpumask = (1 << cpu);
+	unsigned int all_mask = dcscb_allcpus_mask[cluster];
+
+	pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+	if (cpu >= 4 || cluster >= 2)
+		return -EINVAL;
+
+	/*
+	 * Since this is called with IRQs enabled, and no arch_spin_lock_irq
+	 * variant exists, we need to disable IRQs manually here.
+	 */
+	local_irq_disable();
+	arch_spin_lock(&dcscb_lock);
+
+	dcscb_use_count[cpu][cluster]++;
+	if (dcscb_use_count[cpu][cluster] == 1) {
+		rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+		if (rst_hold & (1 << 8)) {
+			/* remove cluster reset and add individual CPU's reset */
+			rst_hold &= ~(1 << 8);
+			rst_hold |= all_mask;
+		}
+		rst_hold &= ~(cpumask | (cpumask << 4));
+		writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+	} else if (dcscb_use_count[cpu][cluster] != 2) {
+		/*
+		 * The only possible values are:
+		 * 0 = CPU down
+		 * 1 = CPU (still) up
+		 * 2 = CPU requested to be up before it had a chance
+		 *     to actually make itself down.
+		 * Any other value is a bug.
+		 */
+		BUG();
+	}
+
+	arch_spin_unlock(&dcscb_lock);
+	local_irq_enable();
+
+	return 0;
+}
+
+static void dcscb_power_down(void)
+{
+	unsigned int mpidr, cpu, cluster, rst_hold, cpumask, all_mask;
+	bool last_man = false, skip_wfi = false;
+
+	mpidr = read_cpuid_mpidr();
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+	cpumask = (1 << cpu);
+	all_mask = dcscb_allcpus_mask[cluster];
+
+	pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+	BUG_ON(cpu >= 4 || cluster >= 2);
+
+	__mcpm_cpu_going_down(cpu, cluster);
+
+	arch_spin_lock(&dcscb_lock);
+	BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP);
+	dcscb_use_count[cpu][cluster]--;
+	if (dcscb_use_count[cpu][cluster] == 0) {
+		rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+		rst_hold |= cpumask;
+		if (((rst_hold | (rst_hold >> 4)) & all_mask) == all_mask) {
+			rst_hold |= (1 << 8);
+			last_man = true;
+		}
+		writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+	} else if (dcscb_use_count[cpu][cluster] == 1) {
+		/*
+		 * A power_up request went ahead of us.
+		 * Even if we do not want to shut this CPU down,
+		 * the caller expects a certain state as if the WFI
+		 * was aborted.  So let's continue with cache cleaning.
+		 */
+		skip_wfi = true;
+	} else
+		BUG();
+
+	if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) {
+		arch_spin_unlock(&dcscb_lock);
+
+		/*
+		 * Flush all cache levels for this cluster.
+		 *
+		 * A15/A7 can hit in the cache with SCTLR.C=0, so we don't need
+		 * a preliminary flush here for those CPUs.  At least, that's
+		 * the theory -- without the extra flush, Linux explodes on
+		 * RTSM (to be investigated).
+		 */
+		flush_cache_all();
+		set_cr(get_cr() & ~CR_C);
+		flush_cache_all();
+
+		/*
+		 * This is a harmless no-op.  On platforms with a real
+		 * outer cache this might either be needed or not,
+		 * depending on where the outer cache sits.
+		 */
+		outer_flush_all();
+
+		/* Disable local coherency by clearing the ACTLR "SMP" bit: */
+		set_auxcr(get_auxcr() & ~(1 << 6));
+
+		/*
+		 * Disable cluster-level coherency by masking
+		 * incoming snoops and DVM messages:
+		 */
+		cci_disable_port_by_cpu(mpidr);
+
+		__mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN);
+	} else {
+		arch_spin_unlock(&dcscb_lock);
+
+		/*
+		 * Flush the local CPU cache.
+		 *
+		 * A15/A7 can hit in the cache with SCTLR.C=0, so we don't need
+		 * a preliminary flush here for those CPUs.  At least, that's
+		 * the theory -- without the extra flush, Linux explodes on
+		 * RTSM (to be investigated).
+		 */
+		flush_cache_louis();
+		set_cr(get_cr() & ~CR_C);
+		flush_cache_louis();
+
+		/* Disable local coherency by clearing the ACTLR "SMP" bit: */
+		set_auxcr(get_auxcr() & ~(1 << 6));
+	}
+
+	__mcpm_cpu_down(cpu, cluster);
+
+	/* Now we are prepared for power-down, do it: */
+	dsb();
+	if (!skip_wfi)
+		wfi();
+
+	/* Not dead at this point?  Let our caller cope. */
+}
+
+static const struct mcpm_platform_ops dcscb_power_ops = {
+	.power_up	= dcscb_power_up,
+	.power_down	= dcscb_power_down,
+};
+
+static void __init dcscb_usage_count_init(void)
+{
+	unsigned int mpidr, cpu, cluster;
+
+	mpidr = read_cpuid_mpidr();
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+	pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+	BUG_ON(cpu >= 4 || cluster >= 2);
+	dcscb_use_count[cpu][cluster] = 1;
+}
+
+extern void dcscb_power_up_setup(unsigned int affinity_level);
+
+static int __init dcscb_init(void)
+{
+	struct device_node *node;
+	unsigned int cfg;
+	int ret;
+
+	if (!cci_probed())
+		return -ENODEV;
+
+	node = of_find_compatible_node(NULL, NULL, "arm,rtsm,dcscb");
+	if (!node)
+		return -ENODEV;
+	dcscb_base = of_iomap(node, 0);
+	if (!dcscb_base)
+		return -EADDRNOTAVAIL;
+	cfg = readl_relaxed(dcscb_base + DCS_CFG_R);
+	dcscb_allcpus_mask[0] = (1 << (((cfg >> 16) >> (0 << 2)) & 0xf)) - 1;
+	dcscb_allcpus_mask[1] = (1 << (((cfg >> 16) >> (1 << 2)) & 0xf)) - 1;
+	dcscb_usage_count_init();
+
+	ret = mcpm_platform_register(&dcscb_power_ops);
+	if (!ret)
+		ret = mcpm_sync_init(dcscb_power_up_setup);
+	if (ret) {
+		iounmap(dcscb_base);
+		return ret;
+	}
+
+	pr_info("VExpress DCSCB support installed\n");
+
+	/*
+	 * Future entries into the kernel can now go
+	 * through the cluster entry vectors.
+	 */
+	vexpress_flags_set(virt_to_phys(mcpm_entry_point));
+
+	return 0;
+}
+
+early_initcall(dcscb_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-vexpress/dcscb_setup.S linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/dcscb_setup.S
--- linux-libre-3.10-gnu/arch/arm/mach-vexpress/dcscb_setup.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/dcscb_setup.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/include/asm/dcscb_setup.S
+ *
+ * Created by:  Dave Martin, 2012-06-22
+ * Copyright:   (C) 2012-2013  Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+
+ENTRY(dcscb_power_up_setup)
+
+	cmp	r0, #0			@ check affinity level
+	beq	2f
+
+/*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ * The ACTLR SMP bit does not need to be set here, because cpu_resume()
+ * already restores that.
+ *
+ * A15/A7 may not require explicit L2 invalidation on reset, dependent
+ * on hardware integration decisions.
+ * For now, this code assumes that L2 is either already invalidated,
+ * or invalidation is not required.
+ */
+
+	b	cci_enable_port_for_self
+
+2:	@ Implementation-specific local CPU setup operations should go here,
+	@ if any.  In this case, there is nothing to do.
+
+	bx	lr
+
+ENDPROC(dcscb_power_up_setup)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-vexpress/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-vexpress/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -57,4 +57,13 @@ config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
 config ARCH_VEXPRESS_CA9X4
 	bool "Versatile Express Cortex-A9x4 tile"
 
+config ARCH_VEXPRESS_DCSCB
+	bool "Dual Cluster System Control Block (DCSCB) support"
+	depends on MCPM
+	select ARM_CCI
+	help
+	  Support for the Dual Cluster System Configuration Block (DCSCB).
+	  This is needed to provide CPU and cluster power management
+	  on RTSM implementing big.LITTLE.
+
 endmenu
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-vexpress/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-vexpress/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -6,5 +6,6 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) :=
 
 obj-y					:= v2m.o
 obj-$(CONFIG_ARCH_VEXPRESS_CA9X4)	+= ct-ca9x4.o
+obj-$(CONFIG_ARCH_VEXPRESS_DCSCB)	+= dcscb.o	dcscb_setup.o
 obj-$(CONFIG_SMP)			+= platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= hotplug.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-vexpress/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-vexpress/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,9 +12,11 @@
 #include <linux/errno.h>
 #include <linux/smp.h>
 #include <linux/io.h>
+#include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/vexpress.h>
 
+#include <asm/mcpm.h>
 #include <asm/smp_scu.h>
 #include <asm/mach/map.h>
 
@@ -203,3 +205,21 @@ struct smp_operations __initdata vexpres
 	.cpu_die		= vexpress_cpu_die,
 #endif
 };
+
+bool __init vexpress_smp_init_ops(void)
+{
+#ifdef CONFIG_MCPM
+	/*
+	 * The best way to detect a multi-cluster configuration at the moment
+	 * is to look for the presence of a CCI in the system.
+	 * Override the default vexpress_smp_ops if so.
+	 */
+	struct device_node *node;
+	node = of_find_compatible_node(NULL, NULL, "arm,cci-400");
+	if (node && of_device_is_available(node)) {
+		mcpm_smp_set_ops();
+		return true;
+	}
+#endif
+	return false;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-vexpress/v2m.c linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/v2m.c
--- linux-libre-3.10-gnu/arch/arm/mach-vexpress/v2m.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-vexpress/v2m.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,6 @@
 #include <linux/clocksource.h>
 #include <linux/smp.h>
 #include <linux/init.h>
-#include <linux/irqchip.h>
 #include <linux/of_address.h>
 #include <linux/of_fdt.h>
 #include <linux/of_irq.h>
@@ -456,9 +455,9 @@ static const char * const v2m_dt_match[]
 DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
 	.dt_compat	= v2m_dt_match,
 	.smp		= smp_ops(vexpress_smp_ops),
+	.smp_init	= smp_init_ops(vexpress_smp_init_ops),
 	.map_io		= v2m_dt_map_io,
 	.init_early	= v2m_dt_init_early,
-	.init_irq	= irqchip_init,
 	.init_time	= v2m_dt_timer_init,
 	.init_machine	= v2m_dt_init,
 MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-virt/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mach-virt/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mach-virt/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-virt/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,7 @@ config ARCH_VIRT
 	bool "Dummy Virtual Machine" if ARCH_MULTI_V7
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARM_GIC
-	select ARM_ARCH_TIMER
+	select HAVE_ARM_ARCH_TIMER
 	select ARM_PSCI
 	select HAVE_SMP
 	select CPU_V7
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-virt/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mach-virt/Makefile
--- linux-libre-3.10-gnu/arch/arm/mach-virt/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-virt/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,4 +3,3 @@
 #
 
 obj-y					:= virt.o
-obj-$(CONFIG_SMP)			+= platsmp.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-virt/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-virt/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-virt/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-virt/platsmp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/*
- * Dummy Virtual Machine - does what it says on the tin.
- *
- * Copyright (C) 2012 ARM Ltd
- * Author: Will Deacon <will.deacon@arm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/of.h>
-
-#include <asm/psci.h>
-#include <asm/smp_plat.h>
-
-extern void secondary_startup(void);
-
-static void __init virt_smp_init_cpus(void)
-{
-}
-
-static void __init virt_smp_prepare_cpus(unsigned int max_cpus)
-{
-}
-
-static int __cpuinit virt_boot_secondary(unsigned int cpu,
-					 struct task_struct *idle)
-{
-	if (psci_ops.cpu_on)
-		return psci_ops.cpu_on(cpu_logical_map(cpu),
-				       __pa(secondary_startup));
-	return -ENODEV;
-}
-
-struct smp_operations __initdata virt_smp_ops = {
-	.smp_init_cpus		= virt_smp_init_cpus,
-	.smp_prepare_cpus	= virt_smp_prepare_cpus,
-	.smp_boot_secondary	= virt_boot_secondary,
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-virt/virt.c linux-libre-3.11-rc7-gnu/arch/arm/mach-virt/virt.c
--- linux-libre-3.10-gnu/arch/arm/mach-virt/virt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-virt/virt.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,6 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <linux/irqchip.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/smp.h>
@@ -36,11 +35,7 @@ static const char *virt_dt_match[] = {
 	NULL
 };
 
-extern struct smp_operations virt_smp_ops;
-
 DT_MACHINE_START(VIRT, "Dummy Virtual Machine")
-	.init_irq	= irqchip_init,
 	.init_machine	= virt_init,
-	.smp		= smp_ops(virt_smp_ops),
 	.dt_compat	= virt_dt_match,
 MACHINE_END
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-vt8500/vt8500.c linux-libre-3.11-rc7-gnu/arch/arm/mach-vt8500/vt8500.c
--- linux-libre-3.10-gnu/arch/arm/mach-vt8500/vt8500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-vt8500/vt8500.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,8 +20,8 @@
 
 #include <linux/clocksource.h>
 #include <linux/io.h>
-#include <linux/irqchip.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -47,7 +47,7 @@
 
 static void __iomem *pmc_base;
 
-void vt8500_restart(char mode, const char *cmd)
+void vt8500_restart(enum reboot_mode mode, const char *cmd)
 {
 	if (pmc_base)
 		writel(1, pmc_base + VT8500_PMSR_REG);
@@ -179,7 +179,6 @@ static const char * const vt8500_dt_comp
 DT_MACHINE_START(WMT_DT, "VIA/Wondermedia SoC (Device Tree Support)")
 	.dt_compat	= vt8500_dt_compat,
 	.map_io		= vt8500_map_io,
-	.init_irq	= irqchip_init,
 	.init_machine	= vt8500_init,
 	.init_time	= clocksource_of_init,
 	.restart	= vt8500_restart,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-w90x900/cpu.c linux-libre-3.11-rc7-gnu/arch/arm/mach-w90x900/cpu.c
--- linux-libre-3.10-gnu/arch/arm/mach-w90x900/cpu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-w90x900/cpu.c	2013-08-25 20:43:22.000000000 -0400
@@ -230,9 +230,9 @@ void __init nuc900_init_clocks(void)
 #define	WTE	(1 << 7)
 #define	WTRE	(1 << 1)
 
-void nuc9xx_restart(char mode, const char *cmd)
+void nuc9xx_restart(enum reboot_mode mode, const char *cmd)
 {
-	if (mode == 's') {
+	if (mode == REBOOT_SOFT) {
 		/* Jump into ROM at address 0 */
 		soft_restart(0);
 	} else {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-w90x900/nuc9xx.h linux-libre-3.11-rc7-gnu/arch/arm/mach-w90x900/nuc9xx.h
--- linux-libre-3.10-gnu/arch/arm/mach-w90x900/nuc9xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-w90x900/nuc9xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,13 @@
  * published by the Free Software Foundation.
  *
  */
+
+#include <linux/reboot.h>
+
 struct map_desc;
 
 /* core initialisation functions */
 
 extern void nuc900_init_irq(void);
 extern void nuc900_timer_init(void);
-extern void nuc9xx_restart(char, const char *);
+extern void nuc9xx_restart(enum reboot_mode, const char *);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-zynq/common.c linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/common.c
--- linux-libre-3.10-gnu/arch/arm/mach-zynq/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of.h>
-#include <linux/irqchip.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -92,21 +91,19 @@ static void __init zynq_map_io(void)
 	zynq_scu_map_io();
 }
 
-static void zynq_system_reset(char mode, const char *cmd)
+static void zynq_system_reset(enum reboot_mode mode, const char *cmd)
 {
 	zynq_slcr_system_reset();
 }
 
 static const char * const zynq_dt_match[] = {
-	"xlnx,zynq-zc702",
 	"xlnx,zynq-7000",
 	NULL
 };
 
-MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
+DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform")
 	.smp		= smp_ops(zynq_smp_ops),
 	.map_io		= zynq_map_io,
-	.init_irq	= irqchip_init,
 	.init_machine	= zynq_init_machine,
 	.init_time	= zynq_timer_init,
 	.dt_compat	= zynq_dt_match,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-zynq/common.h linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/common.h
--- linux-libre-3.10-gnu/arch/arm/mach-zynq/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@ extern void secondary_startup(void);
 extern char zynq_secondary_trampoline;
 extern char zynq_secondary_trampoline_jump;
 extern char zynq_secondary_trampoline_end;
-extern int __cpuinit zynq_cpun_start(u32 address, int cpu);
+extern int zynq_cpun_start(u32 address, int cpu);
 extern struct smp_operations zynq_smp_ops __initdata;
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-zynq/headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/headsmp.S
--- linux-libre-3.10-gnu/arch/arm/mach-zynq/headsmp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -9,8 +9,6 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-	__CPUINIT
-
 ENTRY(zynq_secondary_trampoline)
 	ldr	r0, [pc]
 	bx	r0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-zynq/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/mach-zynq/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,11 +30,11 @@
 /*
  * Store number of cores in the system
  * Because of scu_get_core_count() must be in __init section and can't
- * be called from zynq_cpun_start() because it is in __cpuinit section.
+ * be called from zynq_cpun_start() because it is not in __init section.
  */
 static int ncores;
 
-int __cpuinit zynq_cpun_start(u32 address, int cpu)
+int zynq_cpun_start(u32 address, int cpu)
 {
 	u32 trampoline_code_size = &zynq_secondary_trampoline_end -
 						&zynq_secondary_trampoline;
@@ -53,34 +53,34 @@ int __cpuinit zynq_cpun_start(u32 addres
 						&zynq_secondary_trampoline;
 
 		zynq_slcr_cpu_stop(cpu);
-
-		if (__pa(PAGE_OFFSET)) {
-			zero = ioremap(0, trampoline_code_size);
-			if (!zero) {
-				pr_warn("BOOTUP jump vectors not accessible\n");
-				return -1;
+		if (address) {
+			if (__pa(PAGE_OFFSET)) {
+				zero = ioremap(0, trampoline_code_size);
+				if (!zero) {
+					pr_warn("BOOTUP jump vectors not accessible\n");
+					return -1;
+				}
+			} else {
+				zero = (__force u8 __iomem *)PAGE_OFFSET;
 			}
-		} else {
-			zero = (__force u8 __iomem *)PAGE_OFFSET;
-		}
-
-		/*
-		 * This is elegant way how to jump to any address
-		 * 0x0: Load address at 0x8 to r0
-		 * 0x4: Jump by mov instruction
-		 * 0x8: Jumping address
-		 */
-		memcpy((__force void *)zero, &zynq_secondary_trampoline,
-						trampoline_size);
-		writel(address, zero + trampoline_size);
 
-		flush_cache_all();
-		outer_flush_range(0, trampoline_code_size);
-		smp_wmb();
+			/*
+			* This is elegant way how to jump to any address
+			* 0x0: Load address at 0x8 to r0
+			* 0x4: Jump by mov instruction
+			* 0x8: Jumping address
+			*/
+			memcpy((__force void *)zero, &zynq_secondary_trampoline,
+							trampoline_size);
+			writel(address, zero + trampoline_size);
 
-		if (__pa(PAGE_OFFSET))
-			iounmap(zero);
+			flush_cache_all();
+			outer_flush_range(0, trampoline_code_size);
+			smp_wmb();
 
+			if (__pa(PAGE_OFFSET))
+				iounmap(zero);
+		}
 		zynq_slcr_cpu_start(cpu);
 
 		return 0;
@@ -92,7 +92,7 @@ int __cpuinit zynq_cpun_start(u32 addres
 }
 EXPORT_SYMBOL(zynq_cpun_start);
 
-static int __cpuinit zynq_boot_secondary(unsigned int cpu,
+static int zynq_boot_secondary(unsigned int cpu,
 						struct task_struct *idle)
 {
 	return zynq_cpun_start(virt_to_phys(secondary_startup), cpu);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mach-zynq/slcr.c linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/slcr.c
--- linux-libre-3.10-gnu/arch/arm/mach-zynq/slcr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mach-zynq/slcr.c	2013-08-25 20:43:22.000000000 -0400
@@ -117,7 +117,7 @@ int __init zynq_slcr_init(void)
 
 	pr_info("%s mapped to %p\n", np->name, zynq_slcr_base);
 
-	xilinx_zynq_clocks_init(zynq_slcr_base);
+	zynq_clock_init(zynq_slcr_base);
 
 	of_node_put(np);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/Makefile linux-libre-3.11-rc7-gnu/arch/arm/Makefile
--- linux-libre-3.10-gnu/arch/arm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -59,37 +59,44 @@ comma = ,
 # Note that GCC does not numerically define an architecture version
 # macro, but instead defines a whole series of macros which makes
 # testing for a specific architecture or later rather impossible.
-arch-$(CONFIG_CPU_32v7)		:=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
-arch-$(CONFIG_CPU_32v6)		:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
+arch-$(CONFIG_CPU_32v7M)	=-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m
+arch-$(CONFIG_CPU_32v7)		=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
+arch-$(CONFIG_CPU_32v6)		=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
 # Only override the compiler option if ARMv6. The ARMv6K extensions are
 # always available in ARMv7
 ifeq ($(CONFIG_CPU_32v6),y)
-arch-$(CONFIG_CPU_32v6K)	:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
+arch-$(CONFIG_CPU_32v6K)	=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
 endif
-arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
-arch-$(CONFIG_CPU_32v4T)	:=-D__LINUX_ARM_ARCH__=4 -march=armv4t
-arch-$(CONFIG_CPU_32v4)		:=-D__LINUX_ARM_ARCH__=4 -march=armv4
-arch-$(CONFIG_CPU_32v3)		:=-D__LINUX_ARM_ARCH__=3 -march=armv3
+arch-$(CONFIG_CPU_32v5)		=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
+arch-$(CONFIG_CPU_32v4T)	=-D__LINUX_ARM_ARCH__=4 -march=armv4t
+arch-$(CONFIG_CPU_32v4)		=-D__LINUX_ARM_ARCH__=4 -march=armv4
+arch-$(CONFIG_CPU_32v3)		=-D__LINUX_ARM_ARCH__=3 -march=armv3
+
+# Evaluate arch cc-option calls now
+arch-y := $(arch-y)
 
 # This selects how we optimise for the processor.
-tune-$(CONFIG_CPU_ARM7TDMI)	:=-mtune=arm7tdmi
-tune-$(CONFIG_CPU_ARM720T)	:=-mtune=arm7tdmi
-tune-$(CONFIG_CPU_ARM740T)	:=-mtune=arm7tdmi
-tune-$(CONFIG_CPU_ARM9TDMI)	:=-mtune=arm9tdmi
-tune-$(CONFIG_CPU_ARM940T)	:=-mtune=arm9tdmi
-tune-$(CONFIG_CPU_ARM946E)	:=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi)
-tune-$(CONFIG_CPU_ARM920T)	:=-mtune=arm9tdmi
-tune-$(CONFIG_CPU_ARM922T)	:=-mtune=arm9tdmi
-tune-$(CONFIG_CPU_ARM925T)	:=-mtune=arm9tdmi
-tune-$(CONFIG_CPU_ARM926T)	:=-mtune=arm9tdmi
-tune-$(CONFIG_CPU_FA526)	:=-mtune=arm9tdmi
-tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
-tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
-tune-$(CONFIG_CPU_XSCALE)	:=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
-tune-$(CONFIG_CPU_XSC3)		:=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
-tune-$(CONFIG_CPU_FEROCEON)	:=$(call cc-option,-mtune=marvell-f,-mtune=xscale)
-tune-$(CONFIG_CPU_V6)		:=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
-tune-$(CONFIG_CPU_V6K)		:=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
+tune-$(CONFIG_CPU_ARM7TDMI)	=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM720T)	=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM740T)	=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM9TDMI)	=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM940T)	=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM946E)	=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi)
+tune-$(CONFIG_CPU_ARM920T)	=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM922T)	=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM925T)	=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM926T)	=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_FA526)	=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_SA110)	=-mtune=strongarm110
+tune-$(CONFIG_CPU_SA1100)	=-mtune=strongarm1100
+tune-$(CONFIG_CPU_XSCALE)	=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
+tune-$(CONFIG_CPU_XSC3)		=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
+tune-$(CONFIG_CPU_FEROCEON)	=$(call cc-option,-mtune=marvell-f,-mtune=xscale)
+tune-$(CONFIG_CPU_V6)		=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
+tune-$(CONFIG_CPU_V6K)		=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
+
+# Evaluate tune cc-option calls now
+tune-y := $(tune-y)
 
 ifeq ($(CONFIG_AEABI),y)
 CFLAGS_ABI	:=-mabi=aapcs-linux -mno-thumb-interwork
@@ -146,6 +153,7 @@ machine-$(CONFIG_ARCH_DAVINCI)		+= davin
 machine-$(CONFIG_ARCH_DOVE)		+= dove
 machine-$(CONFIG_ARCH_EBSA110)		+= ebsa110
 machine-$(CONFIG_ARCH_EP93XX)		+= ep93xx
+machine-$(CONFIG_ARCH_EXYNOS)		+= exynos
 machine-$(CONFIG_ARCH_GEMINI)		+= gemini
 machine-$(CONFIG_ARCH_HIGHBANK)		+= highbank
 machine-$(CONFIG_ARCH_INTEGRATOR)	+= integrator
@@ -153,50 +161,54 @@ machine-$(CONFIG_ARCH_IOP13XX)		+= iop13
 machine-$(CONFIG_ARCH_IOP32X)		+= iop32x
 machine-$(CONFIG_ARCH_IOP33X)		+= iop33x
 machine-$(CONFIG_ARCH_IXP4XX)		+= ixp4xx
+machine-$(CONFIG_ARCH_KEYSTONE)		+= keystone
 machine-$(CONFIG_ARCH_KIRKWOOD)		+= kirkwood
 machine-$(CONFIG_ARCH_KS8695)		+= ks8695
 machine-$(CONFIG_ARCH_LPC32XX)		+= lpc32xx
 machine-$(CONFIG_ARCH_MMP)		+= mmp
 machine-$(CONFIG_ARCH_MSM)		+= msm
 machine-$(CONFIG_ARCH_MV78XX0)		+= mv78xx0
+machine-$(CONFIG_ARCH_MVEBU)		+= mvebu
 machine-$(CONFIG_ARCH_MXC)		+= imx
 machine-$(CONFIG_ARCH_MXS)		+= mxs
-machine-$(CONFIG_ARCH_MVEBU)		+= mvebu
 machine-$(CONFIG_ARCH_NETX)		+= netx
 machine-$(CONFIG_ARCH_NOMADIK)		+= nomadik
+machine-$(CONFIG_ARCH_NSPIRE)		+= nspire
 machine-$(CONFIG_ARCH_OMAP1)		+= omap1
 machine-$(CONFIG_ARCH_OMAP2PLUS)	+= omap2
 machine-$(CONFIG_ARCH_ORION5X)		+= orion5x
 machine-$(CONFIG_ARCH_PICOXCELL)	+= picoxcell
-machine-$(CONFIG_ARCH_PRIMA2)		+= prima2
 machine-$(CONFIG_ARCH_PXA)		+= pxa
 machine-$(CONFIG_ARCH_REALVIEW)		+= realview
+machine-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip
 machine-$(CONFIG_ARCH_RPC)		+= rpc
 machine-$(CONFIG_ARCH_S3C24XX)		+= s3c24xx
 machine-$(CONFIG_ARCH_S3C64XX)		+= s3c64xx
 machine-$(CONFIG_ARCH_S5P64X0)		+= s5p64x0
 machine-$(CONFIG_ARCH_S5PC100)		+= s5pc100
 machine-$(CONFIG_ARCH_S5PV210)		+= s5pv210
-machine-$(CONFIG_ARCH_EXYNOS)		+= exynos
 machine-$(CONFIG_ARCH_SA1100)		+= sa1100
 machine-$(CONFIG_ARCH_SHARK)		+= shark
 machine-$(CONFIG_ARCH_SHMOBILE) 	+= shmobile
+machine-$(CONFIG_ARCH_SIRF)		+= prima2
+machine-$(CONFIG_ARCH_SOCFPGA)		+= socfpga
+machine-$(CONFIG_ARCH_STI)		+= sti
+machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
 machine-$(CONFIG_ARCH_TEGRA)		+= tegra
 machine-$(CONFIG_ARCH_U300)		+= u300
 machine-$(CONFIG_ARCH_U8500)		+= ux500
 machine-$(CONFIG_ARCH_VERSATILE)	+= versatile
 machine-$(CONFIG_ARCH_VEXPRESS)		+= vexpress
+machine-$(CONFIG_ARCH_VIRT)		+= virt
 machine-$(CONFIG_ARCH_VT8500)		+= vt8500
 machine-$(CONFIG_ARCH_W90X900)		+= w90x900
+machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
 machine-$(CONFIG_FOOTBRIDGE)		+= footbridge
-machine-$(CONFIG_ARCH_SOCFPGA)		+= socfpga
 machine-$(CONFIG_PLAT_SPEAR)		+= spear
-machine-$(CONFIG_ARCH_VIRT)		+= virt
-machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
-machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
+plat-$(CONFIG_ARCH_EXYNOS)	+= samsung
 plat-$(CONFIG_ARCH_OMAP)	+= omap
 plat-$(CONFIG_ARCH_S3C64XX)	+= samsung
 plat-$(CONFIG_PLAT_IOP)		+= iop
@@ -289,9 +301,10 @@ zImage Image xipImage bootpImage uImage:
 zinstall uinstall install: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
 
-%.dtb: scripts
+%.dtb: | scripts
 	$(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
 
+PHONY += dtbs
 dtbs: scripts
 	$(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) dtbs
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/cache-l2x0.c linux-libre-3.11-rc7-gnu/arch/arm/mm/cache-l2x0.c
--- linux-libre-3.10-gnu/arch/arm/mm/cache-l2x0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/cache-l2x0.c	2013-08-25 20:43:22.000000000 -0400
@@ -523,6 +523,147 @@ static void aurora_flush_range(unsigned
 	}
 }
 
+/*
+ * For certain Broadcom SoCs, depending on the address range, different offsets
+ * need to be added to the address before passing it to L2 for
+ * invalidation/clean/flush
+ *
+ * Section Address Range              Offset        EMI
+ *   1     0x00000000 - 0x3FFFFFFF    0x80000000    VC
+ *   2     0x40000000 - 0xBFFFFFFF    0x40000000    SYS
+ *   3     0xC0000000 - 0xFFFFFFFF    0x80000000    VC
+ *
+ * When the start and end addresses have crossed two different sections, we
+ * need to break the L2 operation into two, each within its own section.
+ * For example, if we need to invalidate addresses starts at 0xBFFF0000 and
+ * ends at 0xC0001000, we need do invalidate 1) 0xBFFF0000 - 0xBFFFFFFF and 2)
+ * 0xC0000000 - 0xC0001000
+ *
+ * Note 1:
+ * By breaking a single L2 operation into two, we may potentially suffer some
+ * performance hit, but keep in mind the cross section case is very rare
+ *
+ * Note 2:
+ * We do not need to handle the case when the start address is in
+ * Section 1 and the end address is in Section 3, since it is not a valid use
+ * case
+ *
+ * Note 3:
+ * Section 1 in practical terms can no longer be used on rev A2. Because of
+ * that the code does not need to handle section 1 at all.
+ *
+ */
+#define BCM_SYS_EMI_START_ADDR        0x40000000UL
+#define BCM_VC_EMI_SEC3_START_ADDR    0xC0000000UL
+
+#define BCM_SYS_EMI_OFFSET            0x40000000UL
+#define BCM_VC_EMI_OFFSET             0x80000000UL
+
+static inline int bcm_addr_is_sys_emi(unsigned long addr)
+{
+	return (addr >= BCM_SYS_EMI_START_ADDR) &&
+		(addr < BCM_VC_EMI_SEC3_START_ADDR);
+}
+
+static inline unsigned long bcm_l2_phys_addr(unsigned long addr)
+{
+	if (bcm_addr_is_sys_emi(addr))
+		return addr + BCM_SYS_EMI_OFFSET;
+	else
+		return addr + BCM_VC_EMI_OFFSET;
+}
+
+static void bcm_inv_range(unsigned long start, unsigned long end)
+{
+	unsigned long new_start, new_end;
+
+	BUG_ON(start < BCM_SYS_EMI_START_ADDR);
+
+	if (unlikely(end <= start))
+		return;
+
+	new_start = bcm_l2_phys_addr(start);
+	new_end = bcm_l2_phys_addr(end);
+
+	/* normal case, no cross section between start and end */
+	if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
+		l2x0_inv_range(new_start, new_end);
+		return;
+	}
+
+	/* They cross sections, so it can only be a cross from section
+	 * 2 to section 3
+	 */
+	l2x0_inv_range(new_start,
+		bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
+	l2x0_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
+		new_end);
+}
+
+static void bcm_clean_range(unsigned long start, unsigned long end)
+{
+	unsigned long new_start, new_end;
+
+	BUG_ON(start < BCM_SYS_EMI_START_ADDR);
+
+	if (unlikely(end <= start))
+		return;
+
+	if ((end - start) >= l2x0_size) {
+		l2x0_clean_all();
+		return;
+	}
+
+	new_start = bcm_l2_phys_addr(start);
+	new_end = bcm_l2_phys_addr(end);
+
+	/* normal case, no cross section between start and end */
+	if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
+		l2x0_clean_range(new_start, new_end);
+		return;
+	}
+
+	/* They cross sections, so it can only be a cross from section
+	 * 2 to section 3
+	 */
+	l2x0_clean_range(new_start,
+		bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
+	l2x0_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
+		new_end);
+}
+
+static void bcm_flush_range(unsigned long start, unsigned long end)
+{
+	unsigned long new_start, new_end;
+
+	BUG_ON(start < BCM_SYS_EMI_START_ADDR);
+
+	if (unlikely(end <= start))
+		return;
+
+	if ((end - start) >= l2x0_size) {
+		l2x0_flush_all();
+		return;
+	}
+
+	new_start = bcm_l2_phys_addr(start);
+	new_end = bcm_l2_phys_addr(end);
+
+	/* normal case, no cross section between start and end */
+	if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) {
+		l2x0_flush_range(new_start, new_end);
+		return;
+	}
+
+	/* They cross sections, so it can only be a cross from section
+	 * 2 to section 3
+	 */
+	l2x0_flush_range(new_start,
+		bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1));
+	l2x0_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR),
+		new_end);
+}
+
 static void __init l2x0_of_setup(const struct device_node *np,
 				 u32 *aux_val, u32 *aux_mask)
 {
@@ -765,6 +906,21 @@ static const struct l2x0_of_data aurora_
 	},
 };
 
+static const struct l2x0_of_data bcm_l2x0_data = {
+	.setup = pl310_of_setup,
+	.save  = pl310_save,
+	.outer_cache = {
+		.resume      = pl310_resume,
+		.inv_range   = bcm_inv_range,
+		.clean_range = bcm_clean_range,
+		.flush_range = bcm_flush_range,
+		.sync        = l2x0_cache_sync,
+		.flush_all   = l2x0_flush_all,
+		.inv_all     = l2x0_inv_all,
+		.disable     = l2x0_disable,
+	},
+};
+
 static const struct of_device_id l2x0_ids[] __initconst = {
 	{ .compatible = "arm,pl310-cache", .data = (void *)&pl310_data },
 	{ .compatible = "arm,l220-cache", .data = (void *)&l2x0_data },
@@ -773,6 +929,8 @@ static const struct of_device_id l2x0_id
 	  .data = (void *)&aurora_no_outer_data},
 	{ .compatible = "marvell,aurora-outer-cache",
 	  .data = (void *)&aurora_with_outer_data},
+	{ .compatible = "bcm,bcm11351-a2-pl310-cache",
+	  .data = (void *)&bcm_l2x0_data},
 	{}
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/cache-nop.S linux-libre-3.11-rc7-gnu/arch/arm/mm/cache-nop.S
--- linux-libre-3.10-gnu/arch/arm/mm/cache-nop.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/cache-nop.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,50 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include "proc-macros.S"
+
+ENTRY(nop_flush_icache_all)
+	mov	pc, lr
+ENDPROC(nop_flush_icache_all)
+
+	.globl nop_flush_kern_cache_all
+	.equ nop_flush_kern_cache_all, nop_flush_icache_all
+
+	.globl nop_flush_kern_cache_louis
+	.equ nop_flush_kern_cache_louis, nop_flush_icache_all
+
+	.globl nop_flush_user_cache_all
+	.equ nop_flush_user_cache_all, nop_flush_icache_all
+
+	.globl nop_flush_user_cache_range
+	.equ nop_flush_user_cache_range, nop_flush_icache_all
+
+	.globl nop_coherent_kern_range
+	.equ nop_coherent_kern_range, nop_flush_icache_all
+
+ENTRY(nop_coherent_user_range)
+	mov	r0, 0
+	mov	pc, lr
+ENDPROC(nop_coherent_user_range)
+
+	.globl nop_flush_kern_dcache_area
+	.equ nop_flush_kern_dcache_area, nop_flush_icache_all
+
+	.globl nop_dma_flush_range
+	.equ nop_dma_flush_range, nop_flush_icache_all
+
+	.globl nop_dma_map_area
+	.equ nop_dma_map_area, nop_flush_icache_all
+
+	.globl nop_dma_unmap_area
+	.equ nop_dma_unmap_area, nop_flush_icache_all
+
+	__INITDATA
+
+	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+	define_cache_functions nop
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/context.c linux-libre-3.11-rc7-gnu/arch/arm/mm/context.c
--- linux-libre-3.10-gnu/arch/arm/mm/context.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/context.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <asm/smp_plat.h>
 #include <asm/thread_notify.h>
 #include <asm/tlbflush.h>
+#include <asm/proc-fns.h>
 
 /*
  * On ARMv6, we have the following structure in the Context ID:
@@ -39,33 +40,51 @@
  * non 64-bit operations.
  */
 #define ASID_FIRST_VERSION	(1ULL << ASID_BITS)
-#define NUM_USER_ASIDS		(ASID_FIRST_VERSION - 1)
-
-#define ASID_TO_IDX(asid)	((asid & ~ASID_MASK) - 1)
-#define IDX_TO_ASID(idx)	((idx + 1) & ~ASID_MASK)
+#define NUM_USER_ASIDS		ASID_FIRST_VERSION
 
 static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
 static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION);
 static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS);
 
-DEFINE_PER_CPU(atomic64_t, active_asids);
+static DEFINE_PER_CPU(atomic64_t, active_asids);
 static DEFINE_PER_CPU(u64, reserved_asids);
 static cpumask_t tlb_flush_pending;
 
+#ifdef CONFIG_ARM_ERRATA_798181
+void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
+			     cpumask_t *mask)
+{
+	int cpu;
+	unsigned long flags;
+	u64 context_id, asid;
+
+	raw_spin_lock_irqsave(&cpu_asid_lock, flags);
+	context_id = mm->context.id.counter;
+	for_each_online_cpu(cpu) {
+		if (cpu == this_cpu)
+			continue;
+		/*
+		 * We only need to send an IPI if the other CPUs are
+		 * running the same ASID as the one being invalidated.
+		 */
+		asid = per_cpu(active_asids, cpu).counter;
+		if (asid == 0)
+			asid = per_cpu(reserved_asids, cpu);
+		if (context_id == asid)
+			cpumask_set_cpu(cpu, mask);
+	}
+	raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
+}
+#endif
+
 #ifdef CONFIG_ARM_LPAE
 static void cpu_set_reserved_ttbr0(void)
 {
-	unsigned long ttbl = __pa(swapper_pg_dir);
-	unsigned long ttbh = 0;
-
 	/*
 	 * Set TTBR0 to swapper_pg_dir which contains only global entries. The
 	 * ASID is set to 0.
 	 */
-	asm volatile(
-	"	mcrr	p15, 0, %0, %1, c2		@ set TTBR0\n"
-	:
-	: "r" (ttbl), "r" (ttbh));
+	cpu_set_ttbr(0, __pa(swapper_pg_dir));
 	isb();
 }
 #else
@@ -128,7 +147,16 @@ static void flush_context(unsigned int c
 			asid = 0;
 		} else {
 			asid = atomic64_xchg(&per_cpu(active_asids, i), 0);
-			__set_bit(ASID_TO_IDX(asid), asid_map);
+			/*
+			 * If this CPU has already been through a
+			 * rollover, but hasn't run another task in
+			 * the meantime, we must preserve its reserved
+			 * ASID, as this is the only trace we have of
+			 * the process it is still running.
+			 */
+			if (asid == 0)
+				asid = per_cpu(reserved_asids, i);
+			__set_bit(asid & ~ASID_MASK, asid_map);
 		}
 		per_cpu(reserved_asids, i) = asid;
 	}
@@ -167,17 +195,19 @@ static u64 new_context(struct mm_struct
 		/*
 		 * Allocate a free ASID. If we can't find one, take a
 		 * note of the currently active ASIDs and mark the TLBs
-		 * as requiring flushes.
+		 * as requiring flushes. We always count from ASID #1,
+		 * as we reserve ASID #0 to switch via TTBR0 and indicate
+		 * rollover events.
 		 */
-		asid = find_first_zero_bit(asid_map, NUM_USER_ASIDS);
+		asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
 		if (asid == NUM_USER_ASIDS) {
 			generation = atomic64_add_return(ASID_FIRST_VERSION,
 							 &asid_generation);
 			flush_context(cpu);
-			asid = find_first_zero_bit(asid_map, NUM_USER_ASIDS);
+			asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
 		}
 		__set_bit(asid, asid_map);
-		asid = generation | IDX_TO_ASID(asid);
+		asid |= generation;
 		cpumask_clear(mm_cpumask(mm));
 	}
 
@@ -215,7 +245,8 @@ void check_and_switch_context(struct mm_
 	if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) {
 		local_flush_bp_all();
 		local_flush_tlb_all();
-		dummy_flush_tlb_a15_erratum();
+		if (erratum_a15_798181())
+			dummy_flush_tlb_a15_erratum();
 	}
 
 	atomic64_set(&per_cpu(active_asids, cpu), asid);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/dma-mapping.c linux-libre-3.11-rc7-gnu/arch/arm/mm/dma-mapping.c
--- linux-libre-3.10-gnu/arch/arm/mm/dma-mapping.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/dma-mapping.c	2013-08-25 20:43:22.000000000 -0400
@@ -250,7 +250,7 @@ static void __dma_free_buffer(struct pag
 
 #ifdef CONFIG_MMU
 #ifdef CONFIG_HUGETLB_PAGE
-#error ARM Coherent DMA allocator does not (yet) support huge TLB
+#warning ARM Coherent DMA allocator does not (yet) support huge TLB
 #endif
 
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
@@ -880,10 +880,24 @@ static void __dma_page_dev_to_cpu(struct
 	dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
 
 	/*
-	 * Mark the D-cache clean for this page to avoid extra flushing.
+	 * Mark the D-cache clean for these pages to avoid extra flushing.
 	 */
-	if (dir != DMA_TO_DEVICE && off == 0 && size >= PAGE_SIZE)
-		set_bit(PG_dcache_clean, &page->flags);
+	if (dir != DMA_TO_DEVICE && size >= PAGE_SIZE) {
+		unsigned long pfn;
+		size_t left = size;
+
+		pfn = page_to_pfn(page) + off / PAGE_SIZE;
+		off %= PAGE_SIZE;
+		if (off) {
+			pfn++;
+			left -= PAGE_SIZE - off;
+		}
+		while (left >= PAGE_SIZE) {
+			page = pfn_to_page(pfn++);
+			set_bit(PG_dcache_clean, &page->flags);
+			left -= PAGE_SIZE;
+		}
+	}
 }
 
 /**
@@ -1314,6 +1328,15 @@ static void *arm_iommu_alloc_attrs(struc
 	if (gfp & GFP_ATOMIC)
 		return __iommu_alloc_atomic(dev, size, handle);
 
+	/*
+	 * Following is a work-around (a.k.a. hack) to prevent pages
+	 * with __GFP_COMP being passed to split_page() which cannot
+	 * handle them.  The real problem is that this flag probably
+	 * should be 0 on ARM as it is not supported on this
+	 * platform; see CONFIG_HUGETLBFS.
+	 */
+	gfp &= ~(__GFP_COMP);
+
 	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
 	if (!pages)
 		return NULL;
@@ -1372,16 +1395,17 @@ static int arm_iommu_mmap_attrs(struct d
 void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 			  dma_addr_t handle, struct dma_attrs *attrs)
 {
-	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
+	struct page **pages;
 	size = PAGE_ALIGN(size);
 
-	if (!pages) {
-		WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
+	if (__in_atomic_pool(cpu_addr, size)) {
+		__iommu_free_atomic(dev, cpu_addr, handle, size);
 		return;
 	}
 
-	if (__in_atomic_pool(cpu_addr, size)) {
-		__iommu_free_atomic(dev, cpu_addr, handle, size);
+	pages = __iommu_get_pages(cpu_addr, attrs);
+	if (!pages) {
+		WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
 		return;
 	}
 
@@ -1636,13 +1660,27 @@ static dma_addr_t arm_coherent_iommu_map
 {
 	struct dma_iommu_mapping *mapping = dev->archdata.mapping;
 	dma_addr_t dma_addr;
-	int ret, len = PAGE_ALIGN(size + offset);
+	int ret, prot, len = PAGE_ALIGN(size + offset);
 
 	dma_addr = __alloc_iova(mapping, len);
 	if (dma_addr == DMA_ERROR_CODE)
 		return dma_addr;
 
-	ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, 0);
+	switch (dir) {
+	case DMA_BIDIRECTIONAL:
+		prot = IOMMU_READ | IOMMU_WRITE;
+		break;
+	case DMA_TO_DEVICE:
+		prot = IOMMU_READ;
+		break;
+	case DMA_FROM_DEVICE:
+		prot = IOMMU_WRITE;
+		break;
+	default:
+		prot = 0;
+	}
+
+	ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, prot);
 	if (ret < 0)
 		goto fail;
 
@@ -1907,7 +1945,7 @@ void arm_iommu_detach_device(struct devi
 
 	iommu_detach_device(mapping->domain, dev);
 	kref_put(&mapping->kref, release_iommu_mapping);
-	mapping = NULL;
+	dev->archdata.mapping = NULL;
 	set_dma_ops(dev, NULL);
 
 	pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/fault.c linux-libre-3.11-rc7-gnu/arch/arm/mm/fault.c
--- linux-libre-3.10-gnu/arch/arm/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -491,12 +491,14 @@ do_translation_fault(unsigned long addr,
  * Some section permission faults need to be handled gracefully.
  * They can happen due to a __{get,put}_user during an oops.
  */
+#ifndef CONFIG_ARM_LPAE
 static int
 do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	do_bad_area(addr, fsr, regs);
 	return 0;
 }
+#endif /* CONFIG_ARM_LPAE */
 
 /*
  * This abort handler always returns "fault".
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/flush.c linux-libre-3.11-rc7-gnu/arch/arm/mm/flush.c
--- linux-libre-3.10-gnu/arch/arm/mm/flush.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/flush.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,7 @@
 #include <asm/highmem.h>
 #include <asm/smp_plat.h>
 #include <asm/tlbflush.h>
+#include <linux/hugetlb.h>
 
 #include "mm.h"
 
@@ -168,19 +169,23 @@ void __flush_dcache_page(struct address_
 	 * coherent with the kernels mapping.
 	 */
 	if (!PageHighMem(page)) {
-		__cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+		size_t page_size = PAGE_SIZE << compound_order(page);
+		__cpuc_flush_dcache_area(page_address(page), page_size);
 	} else {
-		void *addr;
-
+		unsigned long i;
 		if (cache_is_vipt_nonaliasing()) {
-			addr = kmap_atomic(page);
-			__cpuc_flush_dcache_area(addr, PAGE_SIZE);
-			kunmap_atomic(addr);
-		} else {
-			addr = kmap_high_get(page);
-			if (addr) {
+			for (i = 0; i < (1 << compound_order(page)); i++) {
+				void *addr = kmap_atomic(page);
 				__cpuc_flush_dcache_area(addr, PAGE_SIZE);
-				kunmap_high(page);
+				kunmap_atomic(addr);
+			}
+		} else {
+			for (i = 0; i < (1 << compound_order(page)); i++) {
+				void *addr = kmap_high_get(page);
+				if (addr) {
+					__cpuc_flush_dcache_area(addr, PAGE_SIZE);
+					kunmap_high(page);
+				}
 			}
 		}
 	}
@@ -287,7 +292,7 @@ void flush_dcache_page(struct page *page
 	mapping = page_mapping(page);
 
 	if (!cache_ops_need_broadcast() &&
-	    mapping && !mapping_mapped(mapping))
+	    mapping && !page_mapped(page))
 		clear_bit(PG_dcache_clean, &page->flags);
 	else {
 		__flush_dcache_page(mapping, page);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/fsr-3level.c linux-libre-3.11-rc7-gnu/arch/arm/mm/fsr-3level.c
--- linux-libre-3.10-gnu/arch/arm/mm/fsr-3level.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/fsr-3level.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,11 +9,11 @@ static struct fsr_info fsr_info[] = {
 	{ do_page_fault,	SIGSEGV, SEGV_MAPERR,	"level 3 translation fault"	},
 	{ do_bad,		SIGBUS,  0,		"reserved access flag fault"	},
 	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"level 1 access flag fault"	},
-	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"level 2 access flag fault"	},
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 access flag fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 3 access flag fault"	},
 	{ do_bad,		SIGBUS,  0,		"reserved permission fault"	},
 	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"level 1 permission fault"	},
-	{ do_sect_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 permission fault"	},
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 permission fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 3 permission fault"	},
 	{ do_bad,		SIGBUS,  0,		"synchronous external abort"	},
 	{ do_bad,		SIGBUS,  0,		"asynchronous external abort"	},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/hugetlbpage.c linux-libre-3.11-rc7-gnu/arch/arm/mm/hugetlbpage.c
--- linux-libre-3.10-gnu/arch/arm/mm/hugetlbpage.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/hugetlbpage.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,101 @@
+/*
+ * arch/arm/mm/hugetlbpage.c
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h and Bill Carson's patches
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+
+/*
+ * On ARM, huge pages are backed by pmd's rather than pte's, so we do a lot
+ * of type casting from pmd_t * to pte_t *.
+ */
+
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd = NULL;
+
+	pgd = pgd_offset(mm, addr);
+	if (pgd_present(*pgd)) {
+		pud = pud_offset(pgd, addr);
+		if (pud_present(*pud))
+			pmd = pmd_offset(pud, addr);
+	}
+
+	return (pte_t *)pmd;
+}
+
+struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+			      int write)
+{
+	return ERR_PTR(-EINVAL);
+}
+
+int pud_huge(pud_t pud)
+{
+	return 0;
+}
+
+int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
+{
+	return 0;
+}
+
+pte_t *huge_pte_alloc(struct mm_struct *mm,
+			unsigned long addr, unsigned long sz)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pte_t *pte = NULL;
+
+	pgd = pgd_offset(mm, addr);
+	pud = pud_alloc(mm, pgd, addr);
+	if (pud)
+		pte = (pte_t *)pmd_alloc(mm, pud, addr);
+
+	return pte;
+}
+
+struct page *
+follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+		pmd_t *pmd, int write)
+{
+	struct page *page;
+
+	page = pte_page(*(pte_t *)pmd);
+	if (page)
+		page += ((address & ~PMD_MASK) >> PAGE_SHIFT);
+	return page;
+}
+
+int pmd_huge(pmd_t pmd)
+{
+	return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/init.c linux-libre-3.11-rc7-gnu/arch/arm/mm/init.c
--- linux-libre-3.10-gnu/arch/arm/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,12 +36,13 @@
 
 #include "mm.h"
 
-static unsigned long phys_initrd_start __initdata = 0;
+static phys_addr_t phys_initrd_start __initdata = 0;
 static unsigned long phys_initrd_size __initdata = 0;
 
 static int __init early_initrd(char *p)
 {
-	unsigned long start, size;
+	phys_addr_t start;
+	unsigned long size;
 	char *endp;
 
 	start = memparse(p, &endp);
@@ -350,14 +351,14 @@ void __init arm_memblock_init(struct mem
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (phys_initrd_size &&
 	    !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
-		pr_err("INITRD: 0x%08lx+0x%08lx is not a memory region - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
+		pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n",
+		       (u64)phys_initrd_start, phys_initrd_size);
 		phys_initrd_start = phys_initrd_size = 0;
 	}
 	if (phys_initrd_size &&
 	    memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
-		pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
-		       phys_initrd_start, phys_initrd_size);
+		pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n",
+		       (u64)phys_initrd_start, phys_initrd_size);
 		phys_initrd_start = phys_initrd_size = 0;
 	}
 	if (phys_initrd_size) {
@@ -442,7 +443,7 @@ static inline void
 free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 {
 	struct page *start_pg, *end_pg;
-	unsigned long pg, pgend;
+	phys_addr_t pg, pgend;
 
 	/*
 	 * Convert start_pfn/end_pfn to a struct page pointer.
@@ -454,8 +455,8 @@ free_memmap(unsigned long start_pfn, uns
 	 * Convert to physical addresses, and
 	 * round start upwards and end downwards.
 	 */
-	pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
-	pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
+	pg = PAGE_ALIGN(__pa(start_pg));
+	pgend = __pa(end_pg) & PAGE_MASK;
 
 	/*
 	 * If there are free pages between these,
@@ -582,9 +583,6 @@ static void __init free_highpages(void)
  */
 void __init mem_init(void)
 {
-	unsigned long reserved_pages, free_pages;
-	struct memblock_region *reg;
-	int i;
 #ifdef CONFIG_HAVE_TCM
 	/* These pointers are filled in on TCM detection */
 	extern u32 dtcm_end;
@@ -595,57 +593,16 @@ void __init mem_init(void)
 
 	/* this will put all unused low memory onto the freelists */
 	free_unused_memmap(&meminfo);
-
-	totalram_pages += free_all_bootmem();
+	free_all_bootmem();
 
 #ifdef CONFIG_SA1111
 	/* now that our DMA memory is actually so designated, we can free it */
-	free_reserved_area(__va(PHYS_PFN_OFFSET), swapper_pg_dir, 0, NULL);
+	free_reserved_area(__va(PHYS_OFFSET), swapper_pg_dir, -1, NULL);
 #endif
 
 	free_highpages();
 
-	reserved_pages = free_pages = 0;
-
-	for_each_bank(i, &meminfo) {
-		struct membank *bank = &meminfo.bank[i];
-		unsigned int pfn1, pfn2;
-		struct page *page, *end;
-
-		pfn1 = bank_pfn_start(bank);
-		pfn2 = bank_pfn_end(bank);
-
-		page = pfn_to_page(pfn1);
-		end  = pfn_to_page(pfn2 - 1) + 1;
-
-		do {
-			if (PageReserved(page))
-				reserved_pages++;
-			else if (!page_count(page))
-				free_pages++;
-			page++;
-		} while (page < end);
-	}
-
-	/*
-	 * Since our memory may not be contiguous, calculate the
-	 * real number of pages we have in this system
-	 */
-	printk(KERN_INFO "Memory:");
-	num_physpages = 0;
-	for_each_memblock(memory, reg) {
-		unsigned long pages = memblock_region_memory_end_pfn(reg) -
-			memblock_region_memory_base_pfn(reg);
-		num_physpages += pages;
-		printk(" %ldMB", pages >> (20 - PAGE_SHIFT));
-	}
-	printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
-
-	printk(KERN_NOTICE "Memory: %luk/%luk available, %luk reserved, %luK highmem\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		free_pages << (PAGE_SHIFT-10),
-		reserved_pages << (PAGE_SHIFT-10),
-		totalhigh_pages << (PAGE_SHIFT-10));
+	mem_init_print_info(NULL);
 
 #define MLK(b, t) b, t, ((t) - (b)) >> 10
 #define MLM(b, t) b, t, ((t) - (b)) >> 20
@@ -711,7 +668,7 @@ void __init mem_init(void)
 	BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE	> PAGE_OFFSET);
 #endif
 
-	if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
+	if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
 		extern int sysctl_overcommit_memory;
 		/*
 		 * On a machine this small we won't get
@@ -728,12 +685,12 @@ void free_initmem(void)
 	extern char __tcm_start, __tcm_end;
 
 	poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start);
-	free_reserved_area(&__tcm_start, &__tcm_end, 0, "TCM link");
+	free_reserved_area(&__tcm_start, &__tcm_end, -1, "TCM link");
 #endif
 
 	poison_init_mem(__init_begin, __init_end - __init_begin);
 	if (!machine_is_integrator() && !machine_is_cintegrator())
-		free_initmem_default(0);
+		free_initmem_default(-1);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -744,7 +701,7 @@ void free_initrd_mem(unsigned long start
 {
 	if (!keep_initrd) {
 		poison_init_mem((void *)start, PAGE_ALIGN(end) - start);
-		free_reserved_area(start, end, 0, "initrd");
+		free_reserved_area((void *)start, (void *)end, -1, "initrd");
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/ioremap.c linux-libre-3.11-rc7-gnu/arch/arm/mm/ioremap.c
--- linux-libre-3.10-gnu/arch/arm/mm/ioremap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/ioremap.c	2013-08-25 20:43:22.000000000 -0400
@@ -331,10 +331,10 @@ void __iomem * __arm_ioremap_pfn_caller(
 	return (void __iomem *) (offset + addr);
 }
 
-void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
+void __iomem *__arm_ioremap_caller(phys_addr_t phys_addr, size_t size,
 	unsigned int mtype, void *caller)
 {
-	unsigned long last_addr;
+	phys_addr_t last_addr;
  	unsigned long offset = phys_addr & ~PAGE_MASK;
  	unsigned long pfn = __phys_to_pfn(phys_addr);
 
@@ -367,12 +367,12 @@ __arm_ioremap_pfn(unsigned long pfn, uns
 }
 EXPORT_SYMBOL(__arm_ioremap_pfn);
 
-void __iomem * (*arch_ioremap_caller)(unsigned long, size_t,
+void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t,
 				      unsigned int, void *) =
 	__arm_ioremap_caller;
 
 void __iomem *
-__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+__arm_ioremap(phys_addr_t phys_addr, size_t size, unsigned int mtype)
 {
 	return arch_ioremap_caller(phys_addr, size, mtype,
 		__builtin_return_address(0));
@@ -387,7 +387,7 @@ EXPORT_SYMBOL(__arm_ioremap);
  * CONFIG_GENERIC_ALLOCATOR for allocating external memory.
  */
 void __iomem *
-__arm_ioremap_exec(unsigned long phys_addr, size_t size, bool cached)
+__arm_ioremap_exec(phys_addr_t phys_addr, size_t size, bool cached)
 {
 	unsigned int mtype;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/mm/Kconfig
--- linux-libre-3.10-gnu/arch/arm/mm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -392,11 +392,21 @@ config CPU_V7
 	select CPU_CACHE_V7
 	select CPU_CACHE_VIPT
 	select CPU_COPY_V6 if MMU
-	select CPU_CP15_MMU
+	select CPU_CP15_MMU if MMU
+	select CPU_CP15_MPU if !MMU
 	select CPU_HAS_ASID if MMU
 	select CPU_PABRT_V7
 	select CPU_TLB_V7 if MMU
 
+# ARMv7M
+config CPU_V7M
+	bool
+	select CPU_32v7M
+	select CPU_ABRT_NOMMU
+	select CPU_CACHE_NOP
+	select CPU_PABRT_LEGACY
+	select CPU_THUMBONLY
+
 config CPU_THUMBONLY
 	bool
 	# There are no CPUs available with MMU that don't implement an ARM ISA:
@@ -411,24 +421,28 @@ config CPU_32v3
 	select CPU_USE_DOMAINS if MMU
 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
 	select TLS_REG_EMUL if SMP || !MMU
+	select NEED_KUSER_HELPERS
 
 config CPU_32v4
 	bool
 	select CPU_USE_DOMAINS if MMU
 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
 	select TLS_REG_EMUL if SMP || !MMU
+	select NEED_KUSER_HELPERS
 
 config CPU_32v4T
 	bool
 	select CPU_USE_DOMAINS if MMU
 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
 	select TLS_REG_EMUL if SMP || !MMU
+	select NEED_KUSER_HELPERS
 
 config CPU_32v5
 	bool
 	select CPU_USE_DOMAINS if MMU
 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
 	select TLS_REG_EMUL if SMP || !MMU
+	select NEED_KUSER_HELPERS
 
 config CPU_32v6
 	bool
@@ -441,6 +455,9 @@ config CPU_32v6K
 config CPU_32v7
 	bool
 
+config CPU_32v7M
+	bool
+
 # The abort model
 config CPU_ABRT_NOMMU
 	bool
@@ -491,6 +508,9 @@ config CPU_CACHE_V6
 config CPU_CACHE_V7
 	bool
 
+config CPU_CACHE_NOP
+	bool
+
 config CPU_CACHE_VIVT
 	bool
 
@@ -613,7 +633,11 @@ config ARCH_DMA_ADDR_T_64BIT
 
 config ARM_THUMB
 	bool "Support Thumb user binaries" if !CPU_THUMBONLY
-	depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON
+	depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || \
+		CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || \
+		CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \
+		CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || \
+		CPU_V7 || CPU_FEROCEON || CPU_V7M
 	default y
 	help
 	  Say Y if you want to include kernel support for running user space
@@ -756,6 +780,7 @@ config CPU_BPREDICT_DISABLE
 
 config TLS_REG_EMUL
 	bool
+	select NEED_KUSER_HELPERS
 	help
 	  An SMP system using a pre-ARMv6 processor (there are apparently
 	  a few prototypes like that in existence) and therefore access to
@@ -763,11 +788,43 @@ config TLS_REG_EMUL
 
 config NEEDS_SYSCALL_FOR_CMPXCHG
 	bool
+	select NEED_KUSER_HELPERS
 	help
 	  SMP on a pre-ARMv6 processor?  Well OK then.
 	  Forget about fast user space cmpxchg support.
 	  It is just not possible.
 
+config NEED_KUSER_HELPERS
+	bool
+
+config KUSER_HELPERS
+	bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+	default y
+	help
+	  Warning: disabling this option may break user programs.
+
+	  Provide kuser helpers in the vector page.  The kernel provides
+	  helper code to userspace in read only form at a fixed location
+	  in the high vector page to allow userspace to be independent of
+	  the CPU type fitted to the system.  This permits binaries to be
+	  run on ARMv4 through to ARMv7 without modification.
+
+	  See Documentation/arm/kernel_user_helpers.txt for details.
+
+	  However, the fixed address nature of these helpers can be used
+	  by ROP (return orientated programming) authors when creating
+	  exploits.
+
+	  If all of the binaries and libraries which run on your platform
+	  are built specifically for your platform, and make no use of
+	  these helpers, then you can turn this option off to hinder
+	  such exploits. However, in that case, if a binary or library
+	  relying on those helpers is run, it will receive a SIGILL signal,
+	  which will terminate the program.
+
+	  Say N here only if you are absolutely certain that you do not
+	  need these helpers; otherwise, the safe option is to say Y.
+
 config DMA_CACHE_RWFO
 	bool "Enable read/write for ownership DMA cache maintenance"
 	depends on CPU_V6K && SMP
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/Makefile linux-libre-3.11-rc7-gnu/arch/arm/mm/Makefile
--- linux-libre-3.10-gnu/arch/arm/mm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,7 @@ obj-$(CONFIG_MODULES)		+= proc-syms.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)	+= alignment.o
 obj-$(CONFIG_HIGHMEM)		+= highmem.o
+obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 
 obj-$(CONFIG_CPU_ABRT_NOMMU)	+= abort-nommu.o
 obj-$(CONFIG_CPU_ABRT_EV4)	+= abort-ev4.o
@@ -39,6 +40,7 @@ obj-$(CONFIG_CPU_CACHE_V4WB)	+= cache-v4
 obj-$(CONFIG_CPU_CACHE_V6)	+= cache-v6.o
 obj-$(CONFIG_CPU_CACHE_V7)	+= cache-v7.o
 obj-$(CONFIG_CPU_CACHE_FA)	+= cache-fa.o
+obj-$(CONFIG_CPU_CACHE_NOP)	+= cache-nop.o
 
 AFLAGS_cache-v6.o	:=-Wa,-march=armv6
 AFLAGS_cache-v7.o	:=-Wa,-march=armv7-a
@@ -87,6 +89,7 @@ obj-$(CONFIG_CPU_FEROCEON)	+= proc-feroc
 obj-$(CONFIG_CPU_V6)		+= proc-v6.o
 obj-$(CONFIG_CPU_V6K)		+= proc-v6.o
 obj-$(CONFIG_CPU_V7)		+= proc-v7.o
+obj-$(CONFIG_CPU_V7M)		+= proc-v7m.o
 
 AFLAGS_proc-v6.o	:=-Wa,-march=armv6
 AFLAGS_proc-v7.o	:=-Wa,-march=armv7-a
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/mmap.c linux-libre-3.11-rc7-gnu/arch/arm/mm/mmap.c
--- linux-libre-3.10-gnu/arch/arm/mm/mmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/mmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -181,11 +181,9 @@ void arch_pick_mmap_layout(struct mm_str
 	if (mmap_is_legacy()) {
 		mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
 		mm->get_unmapped_area = arch_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
 	} else {
 		mm->mmap_base = mmap_base(random_factor);
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/mmu.c linux-libre-3.11-rc7-gnu/arch/arm/mm/mmu.c
--- linux-libre-3.10-gnu/arch/arm/mm/mmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/mmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -675,7 +675,8 @@ static void __init alloc_init_pmd(pud_t
 }
 
 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
-	unsigned long end, unsigned long phys, const struct mem_type *type)
+				  unsigned long end, phys_addr_t phys,
+				  const struct mem_type *type)
 {
 	pud_t *pud = pud_offset(pgd, addr);
 	unsigned long next;
@@ -949,7 +950,7 @@ void __init debug_ll_io_init(void)
 	map.virtual &= PAGE_MASK;
 	map.length = PAGE_SIZE;
 	map.type = MT_DEVICE;
-	create_mapping(&map);
+	iotable_init(&map, 1);
 }
 #endif
 
@@ -988,28 +989,30 @@ phys_addr_t arm_lowmem_limit __initdata
 
 void __init sanity_check_meminfo(void)
 {
+	phys_addr_t memblock_limit = 0;
 	int i, j, highmem = 0;
+	phys_addr_t vmalloc_limit = __pa(vmalloc_min - 1) + 1;
 
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
-		*bank = meminfo.bank[i];
+		phys_addr_t size_limit;
 
-		if (bank->start > ULONG_MAX)
-			highmem = 1;
+		*bank = meminfo.bank[i];
+		size_limit = bank->size;
 
-#ifdef CONFIG_HIGHMEM
-		if (__va(bank->start) >= vmalloc_min ||
-		    __va(bank->start) < (void *)PAGE_OFFSET)
+		if (bank->start >= vmalloc_limit)
 			highmem = 1;
+		else
+			size_limit = vmalloc_limit - bank->start;
 
 		bank->highmem = highmem;
 
+#ifdef CONFIG_HIGHMEM
 		/*
 		 * Split those memory banks which are partially overlapping
 		 * the vmalloc area greatly simplifying things later.
 		 */
-		if (!highmem && __va(bank->start) < vmalloc_min &&
-		    bank->size > vmalloc_min - __va(bank->start)) {
+		if (!highmem && bank->size > size_limit) {
 			if (meminfo.nr_banks >= NR_BANKS) {
 				printk(KERN_CRIT "NR_BANKS too low, "
 						 "ignoring high memory\n");
@@ -1018,16 +1021,14 @@ void __init sanity_check_meminfo(void)
 					(meminfo.nr_banks - i) * sizeof(*bank));
 				meminfo.nr_banks++;
 				i++;
-				bank[1].size -= vmalloc_min - __va(bank->start);
-				bank[1].start = __pa(vmalloc_min - 1) + 1;
+				bank[1].size -= size_limit;
+				bank[1].start = vmalloc_limit;
 				bank[1].highmem = highmem = 1;
 				j++;
 			}
-			bank->size = vmalloc_min - __va(bank->start);
+			bank->size = size_limit;
 		}
 #else
-		bank->highmem = highmem;
-
 		/*
 		 * Highmem banks not allowed with !CONFIG_HIGHMEM.
 		 */
@@ -1040,36 +1041,44 @@ void __init sanity_check_meminfo(void)
 		}
 
 		/*
-		 * Check whether this memory bank would entirely overlap
-		 * the vmalloc area.
-		 */
-		if (__va(bank->start) >= vmalloc_min ||
-		    __va(bank->start) < (void *)PAGE_OFFSET) {
-			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
-			       "(vmalloc region overlap).\n",
-			       (unsigned long long)bank->start,
-			       (unsigned long long)bank->start + bank->size - 1);
-			continue;
-		}
-
-		/*
 		 * Check whether this memory bank would partially overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start + bank->size - 1) >= vmalloc_min ||
-		    __va(bank->start + bank->size - 1) <= __va(bank->start)) {
-			unsigned long newsize = vmalloc_min - __va(bank->start);
+		if (bank->size > size_limit) {
 			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
 			       "to -%.8llx (vmalloc region overlap).\n",
 			       (unsigned long long)bank->start,
 			       (unsigned long long)bank->start + bank->size - 1,
-			       (unsigned long long)bank->start + newsize - 1);
-			bank->size = newsize;
+			       (unsigned long long)bank->start + size_limit - 1);
+			bank->size = size_limit;
 		}
 #endif
-		if (!bank->highmem && bank->start + bank->size > arm_lowmem_limit)
-			arm_lowmem_limit = bank->start + bank->size;
+		if (!bank->highmem) {
+			phys_addr_t bank_end = bank->start + bank->size;
+
+			if (bank_end > arm_lowmem_limit)
+				arm_lowmem_limit = bank_end;
 
+			/*
+			 * Find the first non-section-aligned page, and point
+			 * memblock_limit at it. This relies on rounding the
+			 * limit down to be section-aligned, which happens at
+			 * the end of this function.
+			 *
+			 * With this algorithm, the start or end of almost any
+			 * bank can be non-section-aligned. The only exception
+			 * is that the start of the bank 0 must be section-
+			 * aligned, since otherwise memory would need to be
+			 * allocated when mapping the start of bank 0, which
+			 * occurs before any free memory is mapped.
+			 */
+			if (!memblock_limit) {
+				if (!IS_ALIGNED(bank->start, SECTION_SIZE))
+					memblock_limit = bank->start;
+				else if (!IS_ALIGNED(bank_end, SECTION_SIZE))
+					memblock_limit = bank_end;
+			}
+		}
 		j++;
 	}
 #ifdef CONFIG_HIGHMEM
@@ -1094,7 +1103,18 @@ void __init sanity_check_meminfo(void)
 #endif
 	meminfo.nr_banks = j;
 	high_memory = __va(arm_lowmem_limit - 1) + 1;
-	memblock_set_current_limit(arm_lowmem_limit);
+
+	/*
+	 * Round the memblock limit down to a section size.  This
+	 * helps to ensure that we will allocate memory from the
+	 * last full section, which should be mapped.
+	 */
+	if (memblock_limit)
+		memblock_limit = round_down(memblock_limit, SECTION_SIZE);
+	if (!memblock_limit)
+		memblock_limit = arm_lowmem_limit;
+
+	memblock_set_current_limit(memblock_limit);
 }
 
 static inline void prepare_page_table(void)
@@ -1175,7 +1195,7 @@ static void __init devicemaps_init(struc
 	/*
 	 * Allocate the vector page early.
 	 */
-	vectors = early_alloc(PAGE_SIZE);
+	vectors = early_alloc(PAGE_SIZE * 2);
 
 	early_trap_init(vectors);
 
@@ -1220,20 +1240,34 @@ static void __init devicemaps_init(struc
 	map.pfn = __phys_to_pfn(virt_to_phys(vectors));
 	map.virtual = 0xffff0000;
 	map.length = PAGE_SIZE;
+#ifdef CONFIG_KUSER_HELPERS
 	map.type = MT_HIGH_VECTORS;
+#else
+	map.type = MT_LOW_VECTORS;
+#endif
 	create_mapping(&map);
 
 	if (!vectors_high()) {
 		map.virtual = 0;
+		map.length = PAGE_SIZE * 2;
 		map.type = MT_LOW_VECTORS;
 		create_mapping(&map);
 	}
 
+	/* Now create a kernel read-only mapping */
+	map.pfn += 1;
+	map.virtual = 0xffff0000 + PAGE_SIZE;
+	map.length = PAGE_SIZE;
+	map.type = MT_LOW_VECTORS;
+	create_mapping(&map);
+
 	/*
 	 * Ask the machine support to map in the statically mapped devices.
 	 */
 	if (mdesc->map_io)
 		mdesc->map_io();
+	else
+		debug_ll_io_init();
 	fill_pmd_gaps();
 
 	/* Reserve fixed i/o space in VMALLOC region */
@@ -1289,8 +1323,6 @@ void __init paging_init(struct machine_d
 {
 	void *zero_page;
 
-	memblock_set_current_limit(arm_lowmem_limit);
-
 	build_mem_type_table();
 	prepare_page_table();
 	map_lowmem();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/nommu.c linux-libre-3.11-rc7-gnu/arch/arm/mm/nommu.c
--- linux-libre-3.10-gnu/arch/arm/mm/nommu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/nommu.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,7 @@
 #include <linux/pagemap.h>
 #include <linux/io.h>
 #include <linux/memblock.h>
+#include <linux/kernel.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
@@ -15,22 +16,282 @@
 #include <asm/setup.h>
 #include <asm/traps.h>
 #include <asm/mach/arch.h>
+#include <asm/cputype.h>
+#include <asm/mpu.h>
 
 #include "mm.h"
 
+#ifdef CONFIG_ARM_MPU
+struct mpu_rgn_info mpu_rgn_info;
+
+/* Region number */
+static void rgnr_write(u32 v)
+{
+	asm("mcr        p15, 0, %0, c6, c2, 0" : : "r" (v));
+}
+
+/* Data-side / unified region attributes */
+
+/* Region access control register */
+static void dracr_write(u32 v)
+{
+	asm("mcr        p15, 0, %0, c6, c1, 4" : : "r" (v));
+}
+
+/* Region size register */
+static void drsr_write(u32 v)
+{
+	asm("mcr        p15, 0, %0, c6, c1, 2" : : "r" (v));
+}
+
+/* Region base address register */
+static void drbar_write(u32 v)
+{
+	asm("mcr        p15, 0, %0, c6, c1, 0" : : "r" (v));
+}
+
+static u32 drbar_read(void)
+{
+	u32 v;
+	asm("mrc        p15, 0, %0, c6, c1, 0" : "=r" (v));
+	return v;
+}
+/* Optional instruction-side region attributes */
+
+/* I-side Region access control register */
+static void iracr_write(u32 v)
+{
+	asm("mcr        p15, 0, %0, c6, c1, 5" : : "r" (v));
+}
+
+/* I-side Region size register */
+static void irsr_write(u32 v)
+{
+	asm("mcr        p15, 0, %0, c6, c1, 3" : : "r" (v));
+}
+
+/* I-side Region base address register */
+static void irbar_write(u32 v)
+{
+	asm("mcr        p15, 0, %0, c6, c1, 1" : : "r" (v));
+}
+
+static unsigned long irbar_read(void)
+{
+	unsigned long v;
+	asm("mrc        p15, 0, %0, c6, c1, 1" : "=r" (v));
+	return v;
+}
+
+/* MPU initialisation functions */
+void __init sanity_check_meminfo_mpu(void)
+{
+	int i;
+	struct membank *bank = meminfo.bank;
+	phys_addr_t phys_offset = PHYS_OFFSET;
+	phys_addr_t aligned_region_size, specified_mem_size, rounded_mem_size;
+
+	/* Initially only use memory continuous from PHYS_OFFSET */
+	if (bank_phys_start(&bank[0]) != phys_offset)
+		panic("First memory bank must be contiguous from PHYS_OFFSET");
+
+	/* Banks have already been sorted by start address */
+	for (i = 1; i < meminfo.nr_banks; i++) {
+		if (bank[i].start <= bank_phys_end(&bank[0]) &&
+		    bank_phys_end(&bank[i]) > bank_phys_end(&bank[0])) {
+			bank[0].size = bank_phys_end(&bank[i]) - bank[0].start;
+		} else {
+			pr_notice("Ignoring RAM after 0x%.8lx. "
+			"First non-contiguous (ignored) bank start: 0x%.8lx\n",
+				(unsigned long)bank_phys_end(&bank[0]),
+				(unsigned long)bank_phys_start(&bank[i]));
+			break;
+		}
+	}
+	/* All contiguous banks are now merged in to the first bank */
+	meminfo.nr_banks = 1;
+	specified_mem_size = bank[0].size;
+
+	/*
+	 * MPU has curious alignment requirements: Size must be power of 2, and
+	 * region start must be aligned to the region size
+	 */
+	if (phys_offset != 0)
+		pr_info("PHYS_OFFSET != 0 => MPU Region size constrained by alignment requirements\n");
+
+	/*
+	 * Maximum aligned region might overflow phys_addr_t if phys_offset is
+	 * 0. Hence we keep everything below 4G until we take the smaller of
+	 * the aligned_region_size and rounded_mem_size, one of which is
+	 * guaranteed to be smaller than the maximum physical address.
+	 */
+	aligned_region_size = (phys_offset - 1) ^ (phys_offset);
+	/* Find the max power-of-two sized region that fits inside our bank */
+	rounded_mem_size = (1 <<  __fls(bank[0].size)) - 1;
+
+	/* The actual region size is the smaller of the two */
+	aligned_region_size = aligned_region_size < rounded_mem_size
+				? aligned_region_size + 1
+				: rounded_mem_size + 1;
+
+	if (aligned_region_size != specified_mem_size)
+		pr_warn("Truncating memory from 0x%.8lx to 0x%.8lx (MPU region constraints)",
+				(unsigned long)specified_mem_size,
+				(unsigned long)aligned_region_size);
+
+	meminfo.bank[0].size = aligned_region_size;
+	pr_debug("MPU Region from 0x%.8lx size 0x%.8lx (end 0x%.8lx))\n",
+		(unsigned long)phys_offset,
+		(unsigned long)aligned_region_size,
+		(unsigned long)bank_phys_end(&bank[0]));
+
+}
+
+static int mpu_present(void)
+{
+	return ((read_cpuid_ext(CPUID_EXT_MMFR0) & MMFR0_PMSA) == MMFR0_PMSAv7);
+}
+
+static int mpu_max_regions(void)
+{
+	/*
+	 * We don't support a different number of I/D side regions so if we
+	 * have separate instruction and data memory maps then return
+	 * whichever side has a smaller number of supported regions.
+	 */
+	u32 dregions, iregions, mpuir;
+	mpuir = read_cpuid(CPUID_MPUIR);
+
+	dregions = iregions = (mpuir & MPUIR_DREGION_SZMASK) >> MPUIR_DREGION;
+
+	/* Check for separate d-side and i-side memory maps */
+	if (mpuir & MPUIR_nU)
+		iregions = (mpuir & MPUIR_IREGION_SZMASK) >> MPUIR_IREGION;
+
+	/* Use the smallest of the two maxima */
+	return min(dregions, iregions);
+}
+
+static int mpu_iside_independent(void)
+{
+	/* MPUIR.nU specifies whether there is *not* a unified memory map */
+	return read_cpuid(CPUID_MPUIR) & MPUIR_nU;
+}
+
+static int mpu_min_region_order(void)
+{
+	u32 drbar_result, irbar_result;
+	/* We've kept a region free for this probing */
+	rgnr_write(MPU_PROBE_REGION);
+	isb();
+	/*
+	 * As per ARM ARM, write 0xFFFFFFFC to DRBAR to find the minimum
+	 * region order
+	*/
+	drbar_write(0xFFFFFFFC);
+	drbar_result = irbar_result = drbar_read();
+	drbar_write(0x0);
+	/* If the MPU is non-unified, we use the larger of the two minima*/
+	if (mpu_iside_independent()) {
+		irbar_write(0xFFFFFFFC);
+		irbar_result = irbar_read();
+		irbar_write(0x0);
+	}
+	isb(); /* Ensure that MPU region operations have completed */
+	/* Return whichever result is larger */
+	return __ffs(max(drbar_result, irbar_result));
+}
+
+static int mpu_setup_region(unsigned int number, phys_addr_t start,
+			unsigned int size_order, unsigned int properties)
+{
+	u32 size_data;
+
+	/* We kept a region free for probing resolution of MPU regions*/
+	if (number > mpu_max_regions() || number == MPU_PROBE_REGION)
+		return -ENOENT;
+
+	if (size_order > 32)
+		return -ENOMEM;
+
+	if (size_order < mpu_min_region_order())
+		return -ENOMEM;
+
+	/* Writing N to bits 5:1 (RSR_SZ)  specifies region size 2^N+1 */
+	size_data = ((size_order - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN;
+
+	dsb(); /* Ensure all previous data accesses occur with old mappings */
+	rgnr_write(number);
+	isb();
+	drbar_write(start);
+	dracr_write(properties);
+	isb(); /* Propagate properties before enabling region */
+	drsr_write(size_data);
+
+	/* Check for independent I-side registers */
+	if (mpu_iside_independent()) {
+		irbar_write(start);
+		iracr_write(properties);
+		isb();
+		irsr_write(size_data);
+	}
+	isb();
+
+	/* Store region info (we treat i/d side the same, so only store d) */
+	mpu_rgn_info.rgns[number].dracr = properties;
+	mpu_rgn_info.rgns[number].drbar = start;
+	mpu_rgn_info.rgns[number].drsr = size_data;
+	return 0;
+}
+
+/*
+* Set up default MPU regions, doing nothing if there is no MPU
+*/
+void __init mpu_setup(void)
+{
+	int region_err;
+	if (!mpu_present())
+		return;
+
+	region_err = mpu_setup_region(MPU_RAM_REGION, PHYS_OFFSET,
+					ilog2(meminfo.bank[0].size),
+					MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL);
+	if (region_err) {
+		panic("MPU region initialization failure! %d", region_err);
+	} else {
+		pr_info("Using ARMv7 PMSA Compliant MPU. "
+			 "Region independence: %s, Max regions: %d\n",
+			mpu_iside_independent() ? "Yes" : "No",
+			mpu_max_regions());
+	}
+}
+#else
+static void sanity_check_meminfo_mpu(void) {}
+static void __init mpu_setup(void) {}
+#endif /* CONFIG_ARM_MPU */
+
 void __init arm_mm_memblock_reserve(void)
 {
+#ifndef CONFIG_CPU_V7M
 	/*
 	 * Register the exception vector page.
 	 * some architectures which the DRAM is the exception vector to trap,
 	 * alloc_page breaks with error, although it is not NULL, but "0."
 	 */
 	memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
+#else /* ifndef CONFIG_CPU_V7M */
+	/*
+	 * There is no dedicated vector page on V7-M. So nothing needs to be
+	 * reserved here.
+	 */
+#endif
 }
 
 void __init sanity_check_meminfo(void)
 {
-	phys_addr_t end = bank_phys_end(&meminfo.bank[meminfo.nr_banks - 1]);
+	phys_addr_t end;
+	sanity_check_meminfo_mpu();
+	end = bank_phys_end(&meminfo.bank[meminfo.nr_banks - 1]);
 	high_memory = __va(end - 1) + 1;
 }
 
@@ -41,6 +302,7 @@ void __init sanity_check_meminfo(void)
 void __init paging_init(struct machine_desc *mdesc)
 {
 	early_trap_init((void *)CONFIG_VECTORS_BASE);
+	mpu_setup();
 	bootmem_init();
 }
 
@@ -87,16 +349,16 @@ void __iomem *__arm_ioremap_pfn_caller(u
 	return __arm_ioremap_pfn(pfn, offset, size, mtype);
 }
 
-void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
+void __iomem *__arm_ioremap(phys_addr_t phys_addr, size_t size,
 			    unsigned int mtype)
 {
 	return (void __iomem *)phys_addr;
 }
 EXPORT_SYMBOL(__arm_ioremap);
 
-void __iomem * (*arch_ioremap_caller)(unsigned long, size_t, unsigned int, void *);
+void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t, unsigned int, void *);
 
-void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
+void __iomem *__arm_ioremap_caller(phys_addr_t phys_addr, size_t size,
 				   unsigned int mtype, void *caller)
 {
 	return __arm_ioremap(phys_addr, size, mtype);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm1020e.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm1020e.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm1020e.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm1020e.S	2013-08-25 20:43:22.000000000 -0400
@@ -425,8 +425,6 @@ ENTRY(cpu_arm1020e_set_pte_ext)
 #endif /* CONFIG_MMU */
 	mov	pc, lr
 
-	__CPUINIT
-
 	.type	__arm1020e_setup, #function
 __arm1020e_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm1020.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm1020.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm1020.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm1020.S	2013-08-25 20:43:22.000000000 -0400
@@ -443,8 +443,6 @@ ENTRY(cpu_arm1020_set_pte_ext)
 #endif /* CONFIG_MMU */
 	mov	pc, lr
 
-	__CPUINIT
-
 	.type	__arm1020_setup, #function
 __arm1020_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm1022.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm1022.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm1022.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm1022.S	2013-08-25 20:43:22.000000000 -0400
@@ -407,8 +407,6 @@ ENTRY(cpu_arm1022_set_pte_ext)
 #endif /* CONFIG_MMU */
 	mov	pc, lr
 
-	__CPUINIT
-
 	.type	__arm1022_setup, #function
 __arm1022_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm1026.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm1026.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm1026.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm1026.S	2013-08-25 20:43:22.000000000 -0400
@@ -396,9 +396,6 @@ ENTRY(cpu_arm1026_set_pte_ext)
 #endif /* CONFIG_MMU */
 	mov	pc, lr
 
-
-	__CPUINIT
-
 	.type	__arm1026_setup, #function
 __arm1026_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm720.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm720.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm720.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm720.S	2013-08-25 20:43:22.000000000 -0400
@@ -116,8 +116,6 @@ ENTRY(cpu_arm720_reset)
 ENDPROC(cpu_arm720_reset)
 		.popsection
 
-	__CPUINIT
-
 	.type	__arm710_setup, #function
 __arm710_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm740.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm740.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm740.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm740.S	2013-08-25 20:43:22.000000000 -0400
@@ -60,8 +60,6 @@ ENTRY(cpu_arm740_reset)
 ENDPROC(cpu_arm740_reset)
 	.popsection
 
-	__CPUINIT
-
 	.type	__arm740_setup, #function
 __arm740_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm7tdmi.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm7tdmi.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm7tdmi.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm7tdmi.S	2013-08-25 20:43:22.000000000 -0400
@@ -51,8 +51,6 @@ ENTRY(cpu_arm7tdmi_reset)
 ENDPROC(cpu_arm7tdmi_reset)
 		.popsection
 
-		__CPUINIT
-
 		.type	__arm7tdmi_setup, #function
 __arm7tdmi_setup:
 		mov	pc, lr
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm920.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm920.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm920.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm920.S	2013-08-25 20:43:22.000000000 -0400
@@ -410,8 +410,6 @@ ENTRY(cpu_arm920_do_resume)
 ENDPROC(cpu_arm920_do_resume)
 #endif
 
-	__CPUINIT
-
 	.type	__arm920_setup, #function
 __arm920_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm922.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm922.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm922.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm922.S	2013-08-25 20:43:22.000000000 -0400
@@ -388,8 +388,6 @@ ENTRY(cpu_arm922_set_pte_ext)
 #endif /* CONFIG_MMU */
 	mov	pc, lr
 
-	__CPUINIT
-
 	.type	__arm922_setup, #function
 __arm922_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm925.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm925.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm925.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm925.S	2013-08-25 20:43:22.000000000 -0400
@@ -438,8 +438,6 @@ ENTRY(cpu_arm925_set_pte_ext)
 #endif /* CONFIG_MMU */
 	mov	pc, lr
 
-	__CPUINIT
-
 	.type	__arm925_setup, #function
 __arm925_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm926.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm926.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm926.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm926.S	2013-08-25 20:43:22.000000000 -0400
@@ -425,8 +425,6 @@ ENTRY(cpu_arm926_do_resume)
 ENDPROC(cpu_arm926_do_resume)
 #endif
 
-	__CPUINIT
-
 	.type	__arm926_setup, #function
 __arm926_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm940.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm940.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm940.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm940.S	2013-08-25 20:43:22.000000000 -0400
@@ -273,8 +273,6 @@ ENDPROC(arm940_dma_unmap_area)
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm940
 
-	__CPUINIT
-
 	.type	__arm940_setup, #function
 __arm940_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm946.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm946.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm946.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm946.S	2013-08-25 20:43:22.000000000 -0400
@@ -326,8 +326,6 @@ ENTRY(cpu_arm946_dcache_clean_area)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
-	__CPUINIT
-
 	.type	__arm946_setup, #function
 __arm946_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-arm9tdmi.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm9tdmi.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-arm9tdmi.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-arm9tdmi.S	2013-08-25 20:43:22.000000000 -0400
@@ -51,8 +51,6 @@ ENTRY(cpu_arm9tdmi_reset)
 ENDPROC(cpu_arm9tdmi_reset)
 		.popsection
 
-		__CPUINIT
-
 		.type	__arm9tdmi_setup, #function
 __arm9tdmi_setup:
 		mov	pc, lr
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-fa526.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-fa526.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-fa526.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-fa526.S	2013-08-25 20:43:22.000000000 -0400
@@ -135,8 +135,6 @@ ENTRY(cpu_fa526_set_pte_ext)
 #endif
 	mov	pc, lr
 
-	__CPUINIT
-
 	.type	__fa526_setup, #function
 __fa526_setup:
 	/* On return of this routine, r0 must carry correct flags for CFG register */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-feroceon.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-feroceon.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-feroceon.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-feroceon.S	2013-08-25 20:43:22.000000000 -0400
@@ -514,8 +514,6 @@ ENTRY(cpu_feroceon_set_pte_ext)
 #endif
 	mov	pc, lr
 
-	__CPUINIT
-
 	.type	__feroceon_setup, #function
 __feroceon_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-mohawk.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-mohawk.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-mohawk.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-mohawk.S	2013-08-25 20:43:22.000000000 -0400
@@ -383,8 +383,6 @@ ENTRY(cpu_mohawk_do_resume)
 ENDPROC(cpu_mohawk_do_resume)
 #endif
 
-	__CPUINIT
-
 	.type	__mohawk_setup, #function
 __mohawk_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-sa1100.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-sa1100.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-sa1100.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-sa1100.S	2013-08-25 20:43:22.000000000 -0400
@@ -198,8 +198,6 @@ ENTRY(cpu_sa1100_do_resume)
 ENDPROC(cpu_sa1100_do_resume)
 #endif
 
-	__CPUINIT
-
 	.type	__sa1100_setup, #function
 __sa1100_setup:
 	mov	r0, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-sa110.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-sa110.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-sa110.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-sa110.S	2013-08-25 20:43:22.000000000 -0400
@@ -159,8 +159,6 @@ ENTRY(cpu_sa110_set_pte_ext)
 #endif
 	mov	pc, lr
 
-	__CPUINIT
-
 	.type	__sa110_setup, #function
 __sa110_setup:
 	mov	r10, #0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-v6.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v6.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-v6.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v6.S	2013-08-25 20:43:22.000000000 -0400
@@ -140,8 +140,10 @@ ENTRY(cpu_v6_set_pte_ext)
 ENTRY(cpu_v6_do_suspend)
 	stmfd	sp!, {r4 - r9, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
+#ifdef CONFIG_MMU
 	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID
 	mrc	p15, 0, r6, c2, c0, 1	@ Translation table base 1
+#endif
 	mrc	p15, 0, r7, c1, c0, 1	@ auxiliary control register
 	mrc	p15, 0, r8, c1, c0, 2	@ co-processor access control
 	mrc	p15, 0, r9, c1, c0, 0	@ control register
@@ -158,14 +160,16 @@ ENTRY(cpu_v6_do_resume)
 	mcr	p15, 0, ip, c13, c0, 1	@ set reserved context ID
 	ldmia	r0, {r4 - r9}
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
+#ifdef CONFIG_MMU
 	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID
 	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP)
 	mcr	p15, 0, r1, c2, c0, 0	@ Translation table base 0
 	mcr	p15, 0, r6, c2, c0, 1	@ Translation table base 1
+	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
+#endif
 	mcr	p15, 0, r7, c1, c0, 1	@ auxiliary control register
 	mcr	p15, 0, r8, c1, c0, 2	@ co-processor access control
-	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register
 	mcr	p15, 0, ip, c7, c5, 4	@ ISB
 	mov	r0, r9			@ control register
 	b	cpu_resume_mmu
@@ -176,8 +180,6 @@ ENDPROC(cpu_v6_do_resume)
 
 	.align
 
-	__CPUINIT
-
 /*
  *	__v6_setup
  *
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-v7-2level.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v7-2level.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-v7-2level.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v7-2level.S	2013-08-25 20:43:22.000000000 -0400
@@ -110,7 +110,7 @@ ENTRY(cpu_v7_set_pte_ext)
  ARM(	str	r3, [r0, #2048]! )
  THUMB(	add	r0, r0, #2048 )
  THUMB(	str	r3, [r0] )
-	ALT_SMP(mov	pc,lr)
+	ALT_SMP(W(nop))
 	ALT_UP (mcr	p15, 0, r0, c7, c10, 1)		@ flush_pte
 #endif
 	mov	pc, lr
@@ -160,8 +160,6 @@ ENDPROC(cpu_v7_set_pte_ext)
 	mcr	p15, 0, \ttbr1, c2, c0, 1	@ load TTB1
 	.endm
 
-	__CPUINIT
-
 	/*   AT
 	 *  TFR   EV X F   I D LR    S
 	 * .EEE ..EE PUI. .T.T 4RVI ZWRS BLDP WCAM
@@ -172,5 +170,3 @@ ENDPROC(cpu_v7_set_pte_ext)
 	.type	v7_crval, #object
 v7_crval:
 	crval	clear=0x2120c302, mmuset=0x10c03c7d, ucset=0x00c01c7c
-
-	.previous
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-v7-3level.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v7-3level.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-v7-3level.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v7-3level.S	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,14 @@
 #define TTB_FLAGS_SMP	(TTB_IRGN_WBWA|TTB_S|TTB_RGN_OC_WBWA)
 #define PMD_FLAGS_SMP	(PMD_SECT_WBWA|PMD_SECT_S)
 
+#ifndef __ARMEB__
+#  define rpgdl	r0
+#  define rpgdh	r1
+#else
+#  define rpgdl	r1
+#  define rpgdh	r0
+#endif
+
 /*
  * cpu_v7_switch_mm(pgd_phys, tsk)
  *
@@ -47,10 +55,10 @@
  */
 ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
-	mmid	r1, r1				@ get mm->context.id
-	asid	r3, r1
-	mov	r3, r3, lsl #(48 - 32)		@ ASID
-	mcrr	p15, 0, r0, r3, c2		@ set TTB 0
+	mmid	r2, r2
+	asid	r2, r2
+	orr	rpgdh, rpgdh, r2, lsl #(48 - 32)	@ upper 32-bits of pgd
+	mcrr	p15, 0, rpgdl, rpgdh, c2		@ set TTB 0
 	isb
 #endif
 	mov	pc, lr
@@ -73,7 +81,7 @@ ENTRY(cpu_v7_set_pte_ext)
 	tst	r3, #1 << (55 - 32)		@ L_PTE_DIRTY
 	orreq	r2, #L_PTE_RDONLY
 1:	strd	r2, r3, [r0]
-	ALT_SMP(mov	pc, lr)
+	ALT_SMP(W(nop))
 	ALT_UP (mcr	p15, 0, r0, c7, c10, 1)		@ flush_pte
 #endif
 	mov	pc, lr
@@ -106,7 +114,8 @@ ENDPROC(cpu_v7_set_pte_ext)
 	 */
 	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
 	ldr	\tmp, =swapper_pg_dir		@ swapper_pg_dir virtual address
-	cmp	\ttbr1, \tmp			@ PHYS_OFFSET > PAGE_OFFSET? (branch below)
+	mov	\tmp, \tmp, lsr #ARCH_PGD_SHIFT
+	cmp	\ttbr1, \tmp			@ PHYS_OFFSET > PAGE_OFFSET?
 	mrc	p15, 0, \tmp, c2, c0, 2		@ TTB control register
 	orr	\tmp, \tmp, #TTB_EAE
 	ALT_SMP(orr	\tmp, \tmp, #TTB_FLAGS_SMP)
@@ -114,31 +123,23 @@ ENDPROC(cpu_v7_set_pte_ext)
 	ALT_SMP(orr	\tmp, \tmp, #TTB_FLAGS_SMP << 16)
 	ALT_UP(orr	\tmp, \tmp, #TTB_FLAGS_UP << 16)
 	/*
-	 * TTBR0/TTBR1 split (PAGE_OFFSET):
-	 *   0x40000000: T0SZ = 2, T1SZ = 0 (not used)
-	 *   0x80000000: T0SZ = 0, T1SZ = 1
-	 *   0xc0000000: T0SZ = 0, T1SZ = 2
-	 *
-	 * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise
-	 * booting secondary CPUs would end up using TTBR1 for the identity
-	 * mapping set up in TTBR0.
+	 * Only use split TTBRs if PHYS_OFFSET <= PAGE_OFFSET (cmp above),
+	 * otherwise booting secondary CPUs would end up using TTBR1 for the
+	 * identity mapping set up in TTBR0.
 	 */
-	bhi	9001f				@ PHYS_OFFSET > PAGE_OFFSET?
-	orr	\tmp, \tmp, #(((PAGE_OFFSET >> 30) - 1) << 16) @ TTBCR.T1SZ
-#if defined CONFIG_VMSPLIT_2G
-	/* PAGE_OFFSET == 0x80000000, T1SZ == 1 */
-	add	\ttbr1, \ttbr1, #1 << 4		@ skip two L1 entries
-#elif defined CONFIG_VMSPLIT_3G
-	/* PAGE_OFFSET == 0xc0000000, T1SZ == 2 */
-	add	\ttbr1, \ttbr1, #4096 * (1 + 3)	@ only L2 used, skip pgd+3*pmd
-#endif
-	/* CONFIG_VMSPLIT_1G does not need TTBR1 adjustment */
-9001:	mcr	p15, 0, \tmp, c2, c0, 2		@ TTB control register
-	mcrr	p15, 1, \ttbr1, \zero, c2	@ load TTBR1
+	orrls	\tmp, \tmp, #TTBR1_SIZE				@ TTBCR.T1SZ
+	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
+	mov	\tmp, \ttbr1, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
+	mov	\ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT		@ lower bits
+	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
+	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
+	mov	\tmp, \ttbr0, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
+	mov	\ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT		@ lower bits
+	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
+	mcrr	p15, 1, \ttbr1, \zero, c2			@ load TTBR1
+	mcrr	p15, 0, \ttbr0, \zero, c2			@ load TTBR0
 	.endm
 
-	__CPUINIT
-
 	/*
 	 *   AT
 	 *  TFR   EV X F   IHD LR    S
@@ -150,5 +151,3 @@ ENDPROC(cpu_v7_set_pte_ext)
 	.type	v7_crval, #object
 v7_crval:
 	crval	clear=0x0120c302, mmuset=0x30c23c7d, ucset=0x00c01c7c
-
-	.previous
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-v7m.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v7m.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-v7m.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v7m.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,157 @@
+/*
+ *  linux/arch/arm/mm/proc-v7m.S
+ *
+ *  Copyright (C) 2008 ARM Ltd.
+ *  Copyright (C) 2001 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This is the "shell" of the ARMv7-M processor support.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/v7m.h>
+#include "proc-macros.S"
+
+ENTRY(cpu_v7m_proc_init)
+	mov	pc, lr
+ENDPROC(cpu_v7m_proc_init)
+
+ENTRY(cpu_v7m_proc_fin)
+	mov	pc, lr
+ENDPROC(cpu_v7m_proc_fin)
+
+/*
+ *	cpu_v7m_reset(loc)
+ *
+ *	Perform a soft reset of the system.  Put the CPU into the
+ *	same state as it would be if it had been reset, and branch
+ *	to what would be the reset vector.
+ *
+ *	- loc   - location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_v7m_reset)
+	mov	pc, r0
+ENDPROC(cpu_v7m_reset)
+
+/*
+ *	cpu_v7m_do_idle()
+ *
+ *	Idle the processor (eg, wait for interrupt).
+ *
+ *	IRQs are already disabled.
+ */
+ENTRY(cpu_v7m_do_idle)
+	wfi
+	mov	pc, lr
+ENDPROC(cpu_v7m_do_idle)
+
+ENTRY(cpu_v7m_dcache_clean_area)
+	mov	pc, lr
+ENDPROC(cpu_v7m_dcache_clean_area)
+
+/*
+ * There is no MMU, so here is nothing to do.
+ */
+ENTRY(cpu_v7m_switch_mm)
+	mov	pc, lr
+ENDPROC(cpu_v7m_switch_mm)
+
+.globl	cpu_v7m_suspend_size
+.equ	cpu_v7m_suspend_size, 0
+
+#ifdef CONFIG_ARM_CPU_SUSPEND
+ENTRY(cpu_v7m_do_suspend)
+	mov	pc, lr
+ENDPROC(cpu_v7m_do_suspend)
+
+ENTRY(cpu_v7m_do_resume)
+	mov	pc, lr
+ENDPROC(cpu_v7m_do_resume)
+#endif
+
+	.section ".text.init", #alloc, #execinstr
+
+/*
+ *	__v7m_setup
+ *
+ *	This should be able to cover all ARMv7-M cores.
+ */
+__v7m_setup:
+	@ Configure the vector table base address
+	ldr	r0, =BASEADDR_V7M_SCB
+	ldr	r12, =vector_table
+	str	r12, [r0, V7M_SCB_VTOR]
+
+	@ enable UsageFault, BusFault and MemManage fault.
+	ldr	r5, [r0, #V7M_SCB_SHCSR]
+	orr	r5, #(V7M_SCB_SHCSR_USGFAULTENA | V7M_SCB_SHCSR_BUSFAULTENA | V7M_SCB_SHCSR_MEMFAULTENA)
+	str	r5, [r0, #V7M_SCB_SHCSR]
+
+	@ Lower the priority of the SVC and PendSV exceptions
+	mov	r5, #0x80000000
+	str	r5, [r0, V7M_SCB_SHPR2]	@ set SVC priority
+	mov	r5, #0x00800000
+	str	r5, [r0, V7M_SCB_SHPR3]	@ set PendSV priority
+
+	@ SVC to run the kernel in this mode
+	adr	r1, BSYM(1f)
+	ldr	r5, [r12, #11 * 4]	@ read the SVC vector entry
+	str	r1, [r12, #11 * 4]	@ write the temporary SVC vector entry
+	mov	r6, lr			@ save LR
+	mov	r7, sp			@ save SP
+	ldr	sp, =__v7m_setup_stack_top
+	cpsie	i
+	svc	#0
+1:	cpsid	i
+	str	r5, [r12, #11 * 4]	@ restore the original SVC vector entry
+	mov	lr, r6			@ restore LR
+	mov	sp, r7			@ restore SP
+
+	@ Special-purpose control register
+	mov	r1, #1
+	msr	control, r1		@ Thread mode has unpriviledged access
+
+	@ Configure the System Control Register to ensure 8-byte stack alignment
+	@ Note the STKALIGN bit is either RW or RAO.
+	ldr	r12, [r0, V7M_SCB_CCR]	@ system control register
+	orr	r12, #V7M_SCB_CCR_STKALIGN
+	str	r12, [r0, V7M_SCB_CCR]
+	mov	pc, lr
+ENDPROC(__v7m_setup)
+
+	define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
+
+	.section ".rodata"
+	string cpu_arch_name, "armv7m"
+	string cpu_elf_name "v7m"
+	string cpu_v7m_name "ARMv7-M"
+
+	.section ".proc.info.init", #alloc, #execinstr
+
+	/*
+	 * Match any ARMv7-M processor core.
+	 */
+	.type	__v7m_proc_info, #object
+__v7m_proc_info:
+	.long	0x000f0000		@ Required ID value
+	.long	0x000f0000		@ Mask for ID
+	.long   0			@ proc_info_list.__cpu_mm_mmu_flags
+	.long   0			@ proc_info_list.__cpu_io_mmu_flags
+	b	__v7m_setup		@ proc_info_list.__cpu_flush
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT
+	.long	cpu_v7m_name
+	.long	v7m_processor_functions	@ proc_info_list.proc
+	.long	0			@ proc_info_list.tlb
+	.long	0			@ proc_info_list.user
+	.long	nop_cache_fns		@ proc_info_list.cache
+	.size	__v7m_proc_info, . - __v7m_proc_info
+
+__v7m_setup_stack:
+	.space	4 * 8				@ 8 registers
+__v7m_setup_stack_top:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-v7.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v7.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-v7.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-v7.S	2013-08-25 20:43:22.000000000 -0400
@@ -75,13 +75,14 @@ ENTRY(cpu_v7_do_idle)
 ENDPROC(cpu_v7_do_idle)
 
 ENTRY(cpu_v7_dcache_clean_area)
-	ALT_SMP(mov	pc, lr)			@ MP extensions imply L1 PTW
-	ALT_UP(W(nop))
-	dcache_line_size r2, r3
-1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	ALT_SMP(W(nop))			@ MP extensions imply L1 PTW
+	ALT_UP_B(1f)
+	mov	pc, lr
+1:	dcache_line_size r2, r3
+2:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	add	r0, r0, r2
 	subs	r1, r1, r2
-	bhi	1b
+	bhi	2b
 	dsb
 	mov	pc, lr
 ENDPROC(cpu_v7_dcache_clean_area)
@@ -98,9 +99,11 @@ ENTRY(cpu_v7_do_suspend)
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mrc	p15, 0, r5, c13, c0, 3	@ User r/o thread ID
 	stmia	r0!, {r4 - r5}
+#ifdef CONFIG_MMU
 	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
 	mrc	p15, 0, r7, c2, c0, 1	@ TTB 1
 	mrc	p15, 0, r11, c2, c0, 2	@ TTB control register
+#endif
 	mrc	p15, 0, r8, c1, c0, 0	@ Control register
 	mrc	p15, 0, r9, c1, c0, 1	@ Auxiliary control register
 	mrc	p15, 0, r10, c1, c0, 2	@ Co-processor access control
@@ -110,13 +113,14 @@ ENDPROC(cpu_v7_do_suspend)
 
 ENTRY(cpu_v7_do_resume)
 	mov	ip, #0
-	mcr	p15, 0, ip, c8, c7, 0	@ invalidate TLBs
 	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
 	mcr	p15, 0, ip, c13, c0, 1	@ set reserved context ID
 	ldmia	r0!, {r4 - r5}
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mcr	p15, 0, r5, c13, c0, 3	@ User r/o thread ID
 	ldmia	r0, {r6 - r11}
+#ifdef CONFIG_MMU
+	mcr	p15, 0, ip, c8, c7, 0	@ invalidate TLBs
 	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
 #ifndef CONFIG_ARM_LPAE
 	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP)
@@ -125,14 +129,15 @@ ENTRY(cpu_v7_do_resume)
 	mcr	p15, 0, r1, c2, c0, 0	@ TTB 0
 	mcr	p15, 0, r7, c2, c0, 1	@ TTB 1
 	mcr	p15, 0, r11, c2, c0, 2	@ TTB control register
-	mrc	p15, 0, r4, c1, c0, 1	@ Read Auxiliary control register
-	teq	r4, r9			@ Is it already set?
-	mcrne	p15, 0, r9, c1, c0, 1	@ No, so write it
-	mcr	p15, 0, r10, c1, c0, 2	@ Co-processor access control
 	ldr	r4, =PRRR		@ PRRR
 	ldr	r5, =NMRR		@ NMRR
 	mcr	p15, 0, r4, c10, c2, 0	@ write PRRR
 	mcr	p15, 0, r5, c10, c2, 1	@ write NMRR
+#endif	/* CONFIG_MMU */
+	mrc	p15, 0, r4, c1, c0, 1	@ Read Auxiliary control register
+	teq	r4, r9			@ Is it already set?
+	mcrne	p15, 0, r9, c1, c0, 1	@ No, so write it
+	mcr	p15, 0, r10, c1, c0, 2	@ Co-processor access control
 	isb
 	dsb
 	mov	r0, r8			@ control register
@@ -163,8 +168,6 @@ ENDPROC(cpu_pj4b_do_idle)
 
 #endif
 
-	__CPUINIT
-
 /*
  *	__v7_setup
  *
@@ -178,7 +181,8 @@ ENDPROC(cpu_pj4b_do_idle)
  */
 __v7_ca5mp_setup:
 __v7_ca9mp_setup:
-	mov	r10, #(1 << 0)			@ TLB ops broadcasting
+__v7_cr7mp_setup:
+	mov	r10, #(1 << 0)			@ Cache/TLB ops broadcasting
 	b	1f
 __v7_ca7mp_setup:
 __v7_ca15mp_setup:
@@ -443,6 +447,16 @@ __v7_pj4b_proc_info:
 #endif
 
 	/*
+	 * ARM Ltd. Cortex R7 processor.
+	 */
+	.type	__v7_cr7mp_proc_info, #object
+__v7_cr7mp_proc_info:
+	.long	0x410fc170
+	.long	0xff0ffff0
+	__v7_proc __v7_cr7mp_setup
+	.size	__v7_cr7mp_proc_info, . - __v7_cr7mp_proc_info
+
+	/*
 	 * ARM Ltd. Cortex A7 processor.
 	 */
 	.type	__v7_ca7mp_proc_info, #object
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-xsc3.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-xsc3.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-xsc3.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-xsc3.S	2013-08-25 20:43:22.000000000 -0400
@@ -446,8 +446,6 @@ ENTRY(cpu_xsc3_do_resume)
 ENDPROC(cpu_xsc3_do_resume)
 #endif
 
-	__CPUINIT
-
 	.type	__xsc3_setup, #function
 __xsc3_setup:
 	mov	r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/mm/proc-xscale.S linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-xscale.S
--- linux-libre-3.10-gnu/arch/arm/mm/proc-xscale.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/mm/proc-xscale.S	2013-08-25 20:43:22.000000000 -0400
@@ -558,8 +558,6 @@ ENTRY(cpu_xscale_do_resume)
 ENDPROC(cpu_xscale_do_resume)
 #endif
 
-	__CPUINIT
-
 	.type	__xscale_setup, #function
 __xscale_setup:
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I, D caches & BTB
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/net/bpf_jit_32.c linux-libre-3.11-rc7-gnu/arch/arm/net/bpf_jit_32.c
--- linux-libre-3.10-gnu/arch/arm/net/bpf_jit_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/net/bpf_jit_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -900,8 +900,7 @@ void bpf_jit_compile(struct sk_filter *f
 #endif
 
 	alloc_size = 4 * ctx.idx;
-	ctx.target = module_alloc(max(sizeof(struct work_struct),
-				      alloc_size));
+	ctx.target = module_alloc(alloc_size);
 	if (unlikely(ctx.target == NULL))
 		goto out;
 
@@ -927,19 +926,8 @@ out:
 	return;
 }
 
-static void bpf_jit_free_worker(struct work_struct *work)
-{
-	module_free(NULL, work);
-}
-
 void bpf_jit_free(struct sk_filter *fp)
 {
-	struct work_struct *work;
-
-	if (fp->bpf_func != sk_run_filter) {
-		work = (struct work_struct *)fp->bpf_func;
-
-		INIT_WORK(work, bpf_jit_free_worker);
-		schedule_work(work);
-	}
+	if (fp->bpf_func != sk_run_filter)
+		module_free(NULL, fp->bpf_func);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-iop/adma.c linux-libre-3.11-rc7-gnu/arch/arm/plat-iop/adma.c
--- linux-libre-3.10-gnu/arch/arm/plat-iop/adma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-iop/adma.c	2013-08-25 20:43:22.000000000 -0400
@@ -192,12 +192,10 @@ static int __init iop3xx_adma_cap_init(v
 
 	#ifdef CONFIG_ARCH_IOP32X /* the 32x AAU does not perform zero sum */
 	dma_cap_set(DMA_XOR, iop3xx_aau_data.cap_mask);
-	dma_cap_set(DMA_MEMSET, iop3xx_aau_data.cap_mask);
 	dma_cap_set(DMA_INTERRUPT, iop3xx_aau_data.cap_mask);
 	#else
 	dma_cap_set(DMA_XOR, iop3xx_aau_data.cap_mask);
 	dma_cap_set(DMA_XOR_VAL, iop3xx_aau_data.cap_mask);
-	dma_cap_set(DMA_MEMSET, iop3xx_aau_data.cap_mask);
 	dma_cap_set(DMA_INTERRUPT, iop3xx_aau_data.cap_mask);
 	#endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-iop/gpio.c linux-libre-3.11-rc7-gnu/arch/arm/plat-iop/gpio.c
--- linux-libre-3.10-gnu/arch/arm/plat-iop/gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-iop/gpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/gpio.h>
 #include <linux/export.h>
 #include <asm/hardware/iop3xx.h>
+#include <mach/gpio.h>
 
 void gpio_line_config(int line, int direction)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-iop/restart.c linux-libre-3.11-rc7-gnu/arch/arm/plat-iop/restart.c
--- linux-libre-3.10-gnu/arch/arm/plat-iop/restart.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-iop/restart.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,7 @@
 #include <asm/system_misc.h>
 #include <mach/hardware.h>
 
-void iop3xx_restart(char mode, const char *cmd)
+void iop3xx_restart(enum reboot_mode mode, const char *cmd)
 {
 	*IOP3XX_PCSR = 0x30;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-iop/time.c linux-libre-3.11-rc7-gnu/arch/arm/plat-iop/time.c
--- linux-libre-3.10-gnu/arch/arm/plat-iop/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-iop/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,9 +22,9 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/export.h>
+#include <linux/sched_clock.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
-#include <asm/sched_clock.h>
 #include <asm/uaccess.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-omap/counter_32k.c linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/counter_32k.c
--- linux-libre-3.10-gnu/arch/arm/plat-omap/counter_32k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/counter_32k.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,9 +18,9 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/clocksource.h>
+#include <linux/sched_clock.h>
 
 #include <asm/mach/time.h>
-#include <asm/sched_clock.h>
 
 #include <plat/counter-32k.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-omap/dma.c linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/dma.c
--- linux-libre-3.10-gnu/arch/arm/plat-omap/dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -701,8 +701,8 @@ int omap_request_dma(int dev_id, const c
 	for (ch = 0; ch < dma_chan_count; ch++) {
 		if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
 			free_ch = ch;
-			if (dev_id == 0)
-				break;
+			/* Exit after first free channel found */
+			break;
 		}
 	}
 	if (free_ch == -1) {
@@ -894,11 +894,12 @@ void omap_start_dma(int lch)
 		int next_lch, cur_lch;
 		char dma_chan_link_map[MAX_LOGICAL_DMA_CH_COUNT];
 
-		dma_chan_link_map[lch] = 1;
 		/* Set the link register of the first channel */
 		enable_lnk(lch);
 
 		memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
+		dma_chan_link_map[lch] = 1;
+
 		cur_lch = dma_chan[lch].next_lch;
 		do {
 			next_lch = dma_chan[cur_lch].next_lch;
@@ -2110,8 +2111,6 @@ exit_dma_irq_fail:
 	}
 
 exit_dma_lch_fail:
-	kfree(p);
-	kfree(d);
 	kfree(dma_chan);
 	return ret;
 }
@@ -2132,8 +2131,6 @@ static int omap_system_dma_remove(struct
 			free_irq(dma_irq, (void *)(irq_rel + 1));
 		}
 	}
-	kfree(p);
-	kfree(d);
 	kfree(dma_chan);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-omap/include/plat/mailbox.h linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/include/plat/mailbox.h
--- linux-libre-3.10-gnu/arch/arm/plat-omap/include/plat/mailbox.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/include/plat/mailbox.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,105 +0,0 @@
-/* mailbox.h */
-
-#ifndef MAILBOX_H
-#define MAILBOX_H
-
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/kfifo.h>
-
-typedef u32 mbox_msg_t;
-struct omap_mbox;
-
-typedef int __bitwise omap_mbox_irq_t;
-#define IRQ_TX ((__force omap_mbox_irq_t) 1)
-#define IRQ_RX ((__force omap_mbox_irq_t) 2)
-
-typedef int __bitwise omap_mbox_type_t;
-#define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1)
-#define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2)
-
-struct omap_mbox_ops {
-	omap_mbox_type_t	type;
-	int		(*startup)(struct omap_mbox *mbox);
-	void		(*shutdown)(struct omap_mbox *mbox);
-	/* fifo */
-	mbox_msg_t	(*fifo_read)(struct omap_mbox *mbox);
-	void		(*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
-	int		(*fifo_empty)(struct omap_mbox *mbox);
-	int		(*fifo_full)(struct omap_mbox *mbox);
-	/* irq */
-	void		(*enable_irq)(struct omap_mbox *mbox,
-						omap_mbox_irq_t irq);
-	void		(*disable_irq)(struct omap_mbox *mbox,
-						omap_mbox_irq_t irq);
-	void		(*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
-	int		(*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
-	/* ctx */
-	void		(*save_ctx)(struct omap_mbox *mbox);
-	void		(*restore_ctx)(struct omap_mbox *mbox);
-};
-
-struct omap_mbox_queue {
-	spinlock_t		lock;
-	struct kfifo		fifo;
-	struct work_struct	work;
-	struct tasklet_struct	tasklet;
-	struct omap_mbox	*mbox;
-	bool full;
-};
-
-struct omap_mbox {
-	char			*name;
-	unsigned int		irq;
-	struct omap_mbox_queue	*txq, *rxq;
-	struct omap_mbox_ops	*ops;
-	struct device		*dev;
-	void			*priv;
-	int			use_count;
-	struct blocking_notifier_head   notifier;
-};
-
-int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
-void omap_mbox_init_seq(struct omap_mbox *);
-
-struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
-void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb);
-
-int omap_mbox_register(struct device *parent, struct omap_mbox **);
-int omap_mbox_unregister(void);
-
-static inline void omap_mbox_save_ctx(struct omap_mbox *mbox)
-{
-	if (!mbox->ops->save_ctx) {
-		dev_err(mbox->dev, "%s:\tno save\n", __func__);
-		return;
-	}
-
-	mbox->ops->save_ctx(mbox);
-}
-
-static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox)
-{
-	if (!mbox->ops->restore_ctx) {
-		dev_err(mbox->dev, "%s:\tno restore\n", __func__);
-		return;
-	}
-
-	mbox->ops->restore_ctx(mbox);
-}
-
-static inline void omap_mbox_enable_irq(struct omap_mbox *mbox,
-					omap_mbox_irq_t irq)
-{
-	mbox->ops->enable_irq(mbox, irq);
-}
-
-static inline void omap_mbox_disable_irq(struct omap_mbox *mbox,
-					 omap_mbox_irq_t irq)
-{
-	mbox->ops->disable_irq(mbox, irq);
-}
-
-#endif /* MAILBOX_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-omap/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/Kconfig
--- linux-libre-3.10-gnu/arch/arm/plat-omap/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -86,22 +86,6 @@ config OMAP_MUX_WARNINGS
 	  to change the pin multiplexing setup.	 When there are no warnings
 	  printed, it's safe to deselect OMAP_MUX for your product.
 
-config OMAP_MBOX_FWK
-	tristate "Mailbox framework support"
-	depends on ARCH_OMAP && !ARCH_MULTIPLATFORM
-	help
-	  Say Y here if you want to use OMAP Mailbox framework support for
-	  DSP, IVA1.0 and IVA2 in OMAP1/2/3.
-
-config OMAP_MBOX_KFIFO_SIZE
-	int "Mailbox kfifo default buffer size (bytes)"
-	depends on OMAP_MBOX_FWK
-	default 256
-	help
-	  Specify the default size of mailbox's kfifo buffers (bytes).
-	  This can also be changed at runtime (via the mbox_kfifo_size
-	  module parameter).
-
 config OMAP_IOMMU_IVA2
 	bool
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-omap/mailbox.c linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/mailbox.c
--- linux-libre-3.10-gnu/arch/arm/plat-omap/mailbox.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/mailbox.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,435 +0,0 @@
-/*
- * OMAP mailbox driver
- *
- * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
- *
- * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/kfifo.h>
-#include <linux/err.h>
-#include <linux/notifier.h>
-#include <linux/module.h>
-
-#include <plat/mailbox.h>
-
-static struct omap_mbox **mboxes;
-
-static int mbox_configured;
-static DEFINE_MUTEX(mbox_configured_lock);
-
-static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
-module_param(mbox_kfifo_size, uint, S_IRUGO);
-MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
-
-/* Mailbox FIFO handle functions */
-static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
-{
-	return mbox->ops->fifo_read(mbox);
-}
-static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
-{
-	mbox->ops->fifo_write(mbox, msg);
-}
-static inline int mbox_fifo_empty(struct omap_mbox *mbox)
-{
-	return mbox->ops->fifo_empty(mbox);
-}
-static inline int mbox_fifo_full(struct omap_mbox *mbox)
-{
-	return mbox->ops->fifo_full(mbox);
-}
-
-/* Mailbox IRQ handle functions */
-static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
-	if (mbox->ops->ack_irq)
-		mbox->ops->ack_irq(mbox, irq);
-}
-static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
-	return mbox->ops->is_irq(mbox, irq);
-}
-
-/*
- * message sender
- */
-static int __mbox_poll_for_space(struct omap_mbox *mbox)
-{
-	int ret = 0, i = 1000;
-
-	while (mbox_fifo_full(mbox)) {
-		if (mbox->ops->type == OMAP_MBOX_TYPE2)
-			return -1;
-		if (--i == 0)
-			return -1;
-		udelay(1);
-	}
-	return ret;
-}
-
-int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
-{
-	struct omap_mbox_queue *mq = mbox->txq;
-	int ret = 0, len;
-
-	spin_lock_bh(&mq->lock);
-
-	if (kfifo_avail(&mq->fifo) < sizeof(msg)) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	if (kfifo_is_empty(&mq->fifo) && !__mbox_poll_for_space(mbox)) {
-		mbox_fifo_write(mbox, msg);
-		goto out;
-	}
-
-	len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
-	WARN_ON(len != sizeof(msg));
-
-	tasklet_schedule(&mbox->txq->tasklet);
-
-out:
-	spin_unlock_bh(&mq->lock);
-	return ret;
-}
-EXPORT_SYMBOL(omap_mbox_msg_send);
-
-static void mbox_tx_tasklet(unsigned long tx_data)
-{
-	struct omap_mbox *mbox = (struct omap_mbox *)tx_data;
-	struct omap_mbox_queue *mq = mbox->txq;
-	mbox_msg_t msg;
-	int ret;
-
-	while (kfifo_len(&mq->fifo)) {
-		if (__mbox_poll_for_space(mbox)) {
-			omap_mbox_enable_irq(mbox, IRQ_TX);
-			break;
-		}
-
-		ret = kfifo_out(&mq->fifo, (unsigned char *)&msg,
-								sizeof(msg));
-		WARN_ON(ret != sizeof(msg));
-
-		mbox_fifo_write(mbox, msg);
-	}
-}
-
-/*
- * Message receiver(workqueue)
- */
-static void mbox_rx_work(struct work_struct *work)
-{
-	struct omap_mbox_queue *mq =
-			container_of(work, struct omap_mbox_queue, work);
-	mbox_msg_t msg;
-	int len;
-
-	while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
-		len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
-		WARN_ON(len != sizeof(msg));
-
-		blocking_notifier_call_chain(&mq->mbox->notifier, len,
-								(void *)msg);
-		spin_lock_irq(&mq->lock);
-		if (mq->full) {
-			mq->full = false;
-			omap_mbox_enable_irq(mq->mbox, IRQ_RX);
-		}
-		spin_unlock_irq(&mq->lock);
-	}
-}
-
-/*
- * Mailbox interrupt handler
- */
-static void __mbox_tx_interrupt(struct omap_mbox *mbox)
-{
-	omap_mbox_disable_irq(mbox, IRQ_TX);
-	ack_mbox_irq(mbox, IRQ_TX);
-	tasklet_schedule(&mbox->txq->tasklet);
-}
-
-static void __mbox_rx_interrupt(struct omap_mbox *mbox)
-{
-	struct omap_mbox_queue *mq = mbox->rxq;
-	mbox_msg_t msg;
-	int len;
-
-	while (!mbox_fifo_empty(mbox)) {
-		if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
-			omap_mbox_disable_irq(mbox, IRQ_RX);
-			mq->full = true;
-			goto nomem;
-		}
-
-		msg = mbox_fifo_read(mbox);
-
-		len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
-		WARN_ON(len != sizeof(msg));
-
-		if (mbox->ops->type == OMAP_MBOX_TYPE1)
-			break;
-	}
-
-	/* no more messages in the fifo. clear IRQ source. */
-	ack_mbox_irq(mbox, IRQ_RX);
-nomem:
-	schedule_work(&mbox->rxq->work);
-}
-
-static irqreturn_t mbox_interrupt(int irq, void *p)
-{
-	struct omap_mbox *mbox = p;
-
-	if (is_mbox_irq(mbox, IRQ_TX))
-		__mbox_tx_interrupt(mbox);
-
-	if (is_mbox_irq(mbox, IRQ_RX))
-		__mbox_rx_interrupt(mbox);
-
-	return IRQ_HANDLED;
-}
-
-static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
-					void (*work) (struct work_struct *),
-					void (*tasklet)(unsigned long))
-{
-	struct omap_mbox_queue *mq;
-
-	mq = kzalloc(sizeof(struct omap_mbox_queue), GFP_KERNEL);
-	if (!mq)
-		return NULL;
-
-	spin_lock_init(&mq->lock);
-
-	if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL))
-		goto error;
-
-	if (work)
-		INIT_WORK(&mq->work, work);
-
-	if (tasklet)
-		tasklet_init(&mq->tasklet, tasklet, (unsigned long)mbox);
-	return mq;
-error:
-	kfree(mq);
-	return NULL;
-}
-
-static void mbox_queue_free(struct omap_mbox_queue *q)
-{
-	kfifo_free(&q->fifo);
-	kfree(q);
-}
-
-static int omap_mbox_startup(struct omap_mbox *mbox)
-{
-	int ret = 0;
-	struct omap_mbox_queue *mq;
-
-	mutex_lock(&mbox_configured_lock);
-	if (!mbox_configured++) {
-		if (likely(mbox->ops->startup)) {
-			ret = mbox->ops->startup(mbox);
-			if (unlikely(ret))
-				goto fail_startup;
-		} else
-			goto fail_startup;
-	}
-
-	if (!mbox->use_count++) {
-		ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
-							mbox->name, mbox);
-		if (unlikely(ret)) {
-			pr_err("failed to register mailbox interrupt:%d\n",
-									ret);
-			goto fail_request_irq;
-		}
-		mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
-		if (!mq) {
-			ret = -ENOMEM;
-			goto fail_alloc_txq;
-		}
-		mbox->txq = mq;
-
-		mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
-		if (!mq) {
-			ret = -ENOMEM;
-			goto fail_alloc_rxq;
-		}
-		mbox->rxq = mq;
-		mq->mbox = mbox;
-
-		omap_mbox_enable_irq(mbox, IRQ_RX);
-	}
-	mutex_unlock(&mbox_configured_lock);
-	return 0;
-
-fail_alloc_rxq:
-	mbox_queue_free(mbox->txq);
-fail_alloc_txq:
-	free_irq(mbox->irq, mbox);
-fail_request_irq:
-	if (mbox->ops->shutdown)
-		mbox->ops->shutdown(mbox);
-	mbox->use_count--;
-fail_startup:
-	mbox_configured--;
-	mutex_unlock(&mbox_configured_lock);
-	return ret;
-}
-
-static void omap_mbox_fini(struct omap_mbox *mbox)
-{
-	mutex_lock(&mbox_configured_lock);
-
-	if (!--mbox->use_count) {
-		omap_mbox_disable_irq(mbox, IRQ_RX);
-		free_irq(mbox->irq, mbox);
-		tasklet_kill(&mbox->txq->tasklet);
-		flush_work(&mbox->rxq->work);
-		mbox_queue_free(mbox->txq);
-		mbox_queue_free(mbox->rxq);
-	}
-
-	if (likely(mbox->ops->shutdown)) {
-		if (!--mbox_configured)
-			mbox->ops->shutdown(mbox);
-	}
-
-	mutex_unlock(&mbox_configured_lock);
-}
-
-struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb)
-{
-	struct omap_mbox *_mbox, *mbox = NULL;
-	int i, ret;
-
-	if (!mboxes)
-		return ERR_PTR(-EINVAL);
-
-	for (i = 0; (_mbox = mboxes[i]); i++) {
-		if (!strcmp(_mbox->name, name)) {
-			mbox = _mbox;
-			break;
-		}
-	}
-
-	if (!mbox)
-		return ERR_PTR(-ENOENT);
-
-	if (nb)
-		blocking_notifier_chain_register(&mbox->notifier, nb);
-
-	ret = omap_mbox_startup(mbox);
-	if (ret) {
-		blocking_notifier_chain_unregister(&mbox->notifier, nb);
-		return ERR_PTR(-ENODEV);
-	}
-
-	return mbox;
-}
-EXPORT_SYMBOL(omap_mbox_get);
-
-void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb)
-{
-	blocking_notifier_chain_unregister(&mbox->notifier, nb);
-	omap_mbox_fini(mbox);
-}
-EXPORT_SYMBOL(omap_mbox_put);
-
-static struct class omap_mbox_class = { .name = "mbox", };
-
-int omap_mbox_register(struct device *parent, struct omap_mbox **list)
-{
-	int ret;
-	int i;
-
-	mboxes = list;
-	if (!mboxes)
-		return -EINVAL;
-
-	for (i = 0; mboxes[i]; i++) {
-		struct omap_mbox *mbox = mboxes[i];
-		mbox->dev = device_create(&omap_mbox_class,
-				parent, 0, mbox, "%s", mbox->name);
-		if (IS_ERR(mbox->dev)) {
-			ret = PTR_ERR(mbox->dev);
-			goto err_out;
-		}
-
-		BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
-	}
-	return 0;
-
-err_out:
-	while (i--)
-		device_unregister(mboxes[i]->dev);
-	return ret;
-}
-EXPORT_SYMBOL(omap_mbox_register);
-
-int omap_mbox_unregister(void)
-{
-	int i;
-
-	if (!mboxes)
-		return -EINVAL;
-
-	for (i = 0; mboxes[i]; i++)
-		device_unregister(mboxes[i]->dev);
-	mboxes = NULL;
-	return 0;
-}
-EXPORT_SYMBOL(omap_mbox_unregister);
-
-static int __init omap_mbox_init(void)
-{
-	int err;
-
-	err = class_register(&omap_mbox_class);
-	if (err)
-		return err;
-
-	/* kfifo size sanity check: alignment and minimal size */
-	mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
-	mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
-							sizeof(mbox_msg_t));
-
-	return 0;
-}
-subsys_initcall(omap_mbox_init);
-
-static void __exit omap_mbox_exit(void)
-{
-	class_unregister(&omap_mbox_class);
-}
-module_exit(omap_mbox_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
-MODULE_AUTHOR("Toshihiro Kobayashi");
-MODULE_AUTHOR("Hiroshi DOYU");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-omap/Makefile linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/Makefile
--- linux-libre-3.10-gnu/arch/arm/plat-omap/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-omap/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,3 @@ obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-l
 i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
 obj-y += $(i2c-omap-m) $(i2c-omap-y)
 
-# OMAP mailbox framework
-obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-orion/common.c linux-libre-3.11-rc7-gnu/arch/arm/plat-orion/common.c
--- linux-libre-3.10-gnu/arch/arm/plat-orion/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-orion/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -666,14 +666,9 @@ void __init orion_xor0_init(unsigned lon
 	orion_xor0_shared_resources[3].start = irq_1;
 	orion_xor0_shared_resources[3].end = irq_1;
 
-	/*
-	 * two engines can't do memset simultaneously, this limitation
-	 * satisfied by removing memset support from one of the engines.
-	 */
 	dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[0].cap_mask);
 	dma_cap_set(DMA_XOR, orion_xor0_channels_data[0].cap_mask);
 
-	dma_cap_set(DMA_MEMSET, orion_xor0_channels_data[1].cap_mask);
 	dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[1].cap_mask);
 	dma_cap_set(DMA_XOR, orion_xor0_channels_data[1].cap_mask);
 
@@ -732,14 +727,9 @@ void __init orion_xor1_init(unsigned lon
 	orion_xor1_shared_resources[3].start = irq_1;
 	orion_xor1_shared_resources[3].end = irq_1;
 
-	/*
-	 * two engines can't do memset simultaneously, this limitation
-	 * satisfied by removing memset support from one of the engines.
-	 */
 	dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[0].cap_mask);
 	dma_cap_set(DMA_XOR, orion_xor1_channels_data[0].cap_mask);
 
-	dma_cap_set(DMA_MEMSET, orion_xor1_channels_data[1].cap_mask);
 	dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[1].cap_mask);
 	dma_cap_set(DMA_XOR, orion_xor1_channels_data[1].cap_mask);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-orion/gpio.c linux-libre-3.11-rc7-gnu/arch/arm/plat-orion/gpio.c
--- linux-libre-3.10-gnu/arch/arm/plat-orion/gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-orion/gpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -426,7 +426,7 @@ static void gpio_irq_handler(unsigned ir
 		if (!(cause & (1 << i)))
 			continue;
 
-		type = irqd_get_trigger_type(irq_get_irq_data(irq));
+		type = irq_get_trigger_type(irq);
 		if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
 			/* Swap polarity (race with GPIO line) */
 			u32 polarity;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-orion/time.c linux-libre-3.11-rc7-gnu/arch/arm/plat-orion/time.c
--- linux-libre-3.10-gnu/arch/arm/plat-orion/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-orion/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,7 @@
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <asm/sched_clock.h>
+#include <linux/sched_clock.h>
 
 /*
  * MBus bridge block registers.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/clock.h linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/clock.h
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/clock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/clock.h	2013-08-25 20:43:22.000000000 -0400
@@ -83,6 +83,11 @@ extern struct clk clk_ext;
 extern struct clksrc_clk clk_epllref;
 extern struct clksrc_clk clk_esysclk;
 
+/* S3C24XX UART clocks */
+extern struct clk s3c24xx_clk_uart0;
+extern struct clk s3c24xx_clk_uart1;
+extern struct clk s3c24xx_clk_uart2;
+
 /* S3C64XX specific clocks */
 extern struct clk clk_h2;
 extern struct clk clk_27m;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/cpu-freq-core.h linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/cpu-freq-core.h
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/cpu-freq-core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/cpu-freq-core.h	2013-08-25 20:43:22.000000000 -0400
@@ -202,7 +202,7 @@ extern int s3c_plltab_register(struct cp
 extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
 extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
 
-#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
+#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS
 #define s3c_cpufreq_debugfs_call(x) x
 #else
 #define s3c_cpufreq_debugfs_call(x) NULL
@@ -259,17 +259,17 @@ extern void s3c2412_iotiming_set(struct
 #define s3c2412_iotiming_set NULL
 #endif /* CONFIG_S3C2412_IOTIMING */
 
-#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
+#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG
 #define s3c_freq_dbg(x...) printk(KERN_INFO x)
 #else
 #define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
-#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
+#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG */
 
-#ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
+#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG
 #define s3c_freq_iodbg(x...) printk(KERN_INFO x)
 #else
 #define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
-#endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
+#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG */
 
 static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
 				      int index, size_t table_size,
@@ -285,7 +285,7 @@ static inline int s3c_cpufreq_addfreq(st
 		s3c_freq_dbg("%s: { %d = %u kHz }\n",
 			     __func__, index, freq);
 
-		table[index].index = index;
+		table[index].driver_data = index;
 		table[index].frequency = freq;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/cpu-freq.h linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/cpu-freq.h
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/cpu-freq.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/cpu-freq.h	2013-08-25 20:43:22.000000000 -0400
@@ -126,7 +126,7 @@ struct s3c_cpufreq_board {
 };
 
 /* Things depending on frequency scaling. */
-#ifdef CONFIG_CPU_FREQ_S3C
+#ifdef CONFIG_ARM_S3C_CPUFREQ
 #define __init_or_cpufreq
 #else
 #define __init_or_cpufreq __init
@@ -134,7 +134,7 @@ struct s3c_cpufreq_board {
 
 /* Board functions */
 
-#ifdef CONFIG_CPU_FREQ_S3C
+#ifdef CONFIG_ARM_S3C_CPUFREQ
 extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board);
 #else
 
@@ -142,4 +142,4 @@ static inline int s3c_cpufreq_setboard(s
 {
 	return 0;
 }
-#endif  /* CONFIG_CPU_FREQ_S3C */
+#endif  /* CONFIG_ARM_S3C_CPUFREQ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/cpu.h linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/cpu.h
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/cpu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/cpu.h	2013-08-25 20:43:22.000000000 -0400
@@ -46,6 +46,7 @@ extern unsigned long samsung_cpu_id;
 #define EXYNOS4_CPU_MASK	0xFFFE0000
 
 #define EXYNOS5250_SOC_ID	0x43520000
+#define EXYNOS5420_SOC_ID	0xE5420000
 #define EXYNOS5440_SOC_ID	0xE5440000
 #define EXYNOS5_SOC_MASK	0xFFFFF000
 
@@ -67,6 +68,7 @@ IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CP
 IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK)
 IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
 IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
+IS_SAMSUNG_CPU(exynos5420, EXYNOS5420_SOC_ID, EXYNOS5_SOC_MASK)
 IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
 
 #if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
@@ -142,6 +144,12 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SO
 # define soc_is_exynos5250()	0
 #endif
 
+#if defined(CONFIG_SOC_EXYNOS5420)
+# define soc_is_exynos5420()	is_samsung_exynos5420()
+#else
+# define soc_is_exynos5420()	0
+#endif
+
 #if defined(CONFIG_SOC_EXYNOS5440)
 # define soc_is_exynos5440()	is_samsung_exynos5440()
 #else
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,6 @@ struct s3c24xx_dma_map {
 	const char		*name;
 
 	unsigned long		 channels[S3C_DMA_CHANNELS];
-	unsigned long		 channels_rx[S3C_DMA_CHANNELS];
 };
 
 struct s3c24xx_dma_selection {
@@ -38,10 +37,6 @@ struct s3c24xx_dma_selection {
 
 	void	(*select)(struct s3c2410_dma_chan *chan,
 			  struct s3c24xx_dma_map *map);
-
-	void	(*direction)(struct s3c2410_dma_chan *chan,
-			     struct s3c24xx_dma_map *map,
-			     enum dma_data_direction dir);
 };
 
 extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/pm.h linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/pm.h
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/pm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/pm.h	2013-08-25 20:43:22.000000000 -0400
@@ -19,7 +19,7 @@
 
 struct device;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_SAMSUNG_PM
 
 extern __init int s3c_pm_init(void);
 extern __init int s3c64xx_pm_init(void);
@@ -58,8 +58,6 @@ extern unsigned char pm_uart_udivslot;
 
 /* from sleep.S */
 
-extern void s3c_cpu_resume(void);
-
 extern int s3c2410_cpu_suspend(unsigned long);
 
 /* sleep save info */
@@ -106,12 +104,14 @@ extern void s3c_pm_do_save(struct sleep_
 extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
 extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_SAMSUNG_PM
 extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
 extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
+extern void s3c_cpu_resume(void);
 #else
 #define s3c_irq_wake NULL
 #define s3c_irqext_wake NULL
+#define s3c_cpu_resume NULL
 #endif
 
 /* PM debug functions */
@@ -166,6 +166,7 @@ extern void s3c_pm_check_store(void);
  */
 extern void s3c_pm_configure_extint(void);
 
+#ifdef CONFIG_GPIO_SAMSUNG
 /**
  * samsung_pm_restore_gpios() - restore the state of the gpios after sleep.
  *
@@ -181,6 +182,10 @@ extern void samsung_pm_restore_gpios(voi
  * Save the GPIO states for resotration on resume. See samsung_pm_restore_gpios().
  */
 extern void samsung_pm_save_gpios(void);
+#else
+static inline void samsung_pm_restore_gpios(void) {}
+static inline void samsung_pm_save_gpios(void) {}
+#endif
 
 extern void s3c_pm_save_core(void);
 extern void s3c_pm_restore_core(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/regs-watchdog.h linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/regs-watchdog.h
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/regs-watchdog.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/regs-watchdog.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-watchdog.h
- *
- * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
- *		      http://www.simtec.co.uk/products/SWLINUX/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * S3C2410 Watchdog timer control
-*/
-
-
-#ifndef __ASM_ARCH_REGS_WATCHDOG_H
-#define __ASM_ARCH_REGS_WATCHDOG_H
-
-#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG)
-
-#define S3C2410_WTCON	   S3C_WDOGREG(0x00)
-#define S3C2410_WTDAT	   S3C_WDOGREG(0x04)
-#define S3C2410_WTCNT	   S3C_WDOGREG(0x08)
-
-/* the watchdog can either generate a reset pulse, or an
- * interrupt.
- */
-
-#define S3C2410_WTCON_RSTEN   (0x01)
-#define S3C2410_WTCON_INTEN   (1<<2)
-#define S3C2410_WTCON_ENABLE  (1<<5)
-
-#define S3C2410_WTCON_DIV16   (0<<3)
-#define S3C2410_WTCON_DIV32   (1<<3)
-#define S3C2410_WTCON_DIV64   (2<<3)
-#define S3C2410_WTCON_DIV128  (3<<3)
-
-#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
-#define S3C2410_WTCON_PRESCALE_MASK (0xff00)
-
-#endif /* __ASM_ARCH_REGS_WATCHDOG_H */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/uncompress.h linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/uncompress.h
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/uncompress.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/uncompress.h	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,8 @@ typedef unsigned int upf_t;	/* cannot in
 unsigned int fifo_mask;
 unsigned int fifo_max;
 
+volatile u8 *uart_base;
+
 /* forward declerations */
 
 static void arch_detect_cpu(void);
@@ -28,19 +30,24 @@ static void arch_detect_cpu(void);
 /* defines for UART registers */
 
 #include <plat/regs-serial.h>
-#include <plat/regs-watchdog.h>
 
 /* working in physical space... */
-#undef S3C2410_WDOGREG
-#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
+#define S3C_WDOGREG(x)	((S3C_PA_WDT + (x)))
+
+#define S3C2410_WTCON	S3C_WDOGREG(0x00)
+#define S3C2410_WTDAT	S3C_WDOGREG(0x04)
+#define S3C2410_WTCNT	S3C_WDOGREG(0x08)
+
+#define S3C2410_WTCON_RSTEN	(1 << 0)
+#define S3C2410_WTCON_ENABLE	(1 << 5)
+
+#define S3C2410_WTCON_DIV128	(3 << 3)
+
+#define S3C2410_WTCON_PRESCALE(x)	((x) << 8)
 
 /* how many bytes we allow into the FIFO at a time in FIFO mode */
 #define FIFO_MAX	 (14)
 
-#ifdef S3C_PA_UART
-#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
-#endif
-
 static __inline__ void
 uart_wr(unsigned int reg, unsigned int val)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/watchdog-reset.h linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/watchdog-reset.h
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/include/plat/watchdog-reset.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/include/plat/watchdog-reset.h	2013-08-25 20:43:22.000000000 -0400
@@ -10,37 +10,11 @@
  * published by the Free Software Foundation.
 */
 
-#include <plat/clock.h>
-#include <plat/regs-watchdog.h>
-#include <mach/map.h>
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-static inline void arch_wdt_reset(void)
-{
-	printk("arch_reset: attempting watchdog reset\n");
-
-	__raw_writel(0, S3C2410_WTCON);	  /* disable watchdog, to be safe  */
-
-	if (!IS_ERR(s3c2410_wdtclk))
-		clk_enable(s3c2410_wdtclk);
-
-	/* put initial values into count and data */
-	__raw_writel(0x80, S3C2410_WTCNT);
-	__raw_writel(0x80, S3C2410_WTDAT);
-
-	/* set the watchdog to go and reset... */
-	__raw_writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16|S3C2410_WTCON_RSTEN |
-		     S3C2410_WTCON_PRESCALE(0x20), S3C2410_WTCON);
-
-	/* wait for reset to assert... */
-	mdelay(500);
+#ifndef __PLAT_SAMSUNG_WATCHDOG_RESET_H
+#define __PLAT_SAMSUNG_WATCHDOG_RESET_H
 
-	printk(KERN_ERR "Watchdog reset failed to assert reset\n");
+extern void samsung_wdt_reset(void);
+extern void samsung_wdt_reset_of_init(void);
+extern void samsung_wdt_reset_init(void __iomem *base);
 
-	/* delay to allow the serial port to show the message */
-	mdelay(50);
-}
+#endif /* __PLAT_SAMSUNG_WATCHDOG_RESET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/init.c linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/init.c
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,12 +55,13 @@ void __init s3c_init_cpu(unsigned long i
 
 	printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
 
-	if (cpu->map_io == NULL || cpu->init == NULL) {
+	if (cpu->init == NULL) {
 		printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
 		panic("Unsupported Samsung CPU");
 	}
 
-	cpu->map_io();
+	if (cpu->map_io)
+		cpu->map_io();
 }
 
 /* s3c24xx_init_clocks
@@ -87,7 +88,7 @@ void __init s3c24xx_init_clocks(int xtal
 }
 
 /* uart management */
-
+#if IS_ENABLED(CONFIG_SAMSUNG_ATAGS)
 static int nr_uarts __initdata = 0;
 
 static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS];
@@ -134,11 +135,12 @@ void __init s3c24xx_init_uarts(struct s3
 	if (cpu == NULL)
 		return;
 
-	if (cpu->init_uarts == NULL) {
+	if (cpu->init_uarts == NULL && IS_ENABLED(CONFIG_SAMSUNG_ATAGS)) {
 		printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
 	} else
 		(cpu->init_uarts)(cfg, no);
 }
+#endif
 
 static int __init s3c_arch_init(void)
 {
@@ -152,8 +154,9 @@ static int __init s3c_arch_init(void)
 	ret = (cpu->init)();
 	if (ret != 0)
 		return ret;
-
+#if IS_ENABLED(CONFIG_SAMSUNG_ATAGS)
 	ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
+#endif
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/Kconfig linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/Kconfig
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
 
 config PLAT_SAMSUNG
 	bool
-	depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P
+	depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P || ARCH_EXYNOS
 	default y
 	select GENERIC_IRQ_CHIP
 	select NO_IOPORT
@@ -15,12 +15,10 @@ config PLAT_SAMSUNG
 
 config PLAT_S5P
 	bool
-	depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+	depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
 	default y
 	select ARCH_REQUIRE_GPIOLIB
-	select ARM_GIC if ARCH_EXYNOS
-	select ARM_VIC if !ARCH_EXYNOS
-	select GIC_NON_BANKED if ARCH_EXYNOS4
+	select ARM_VIC
 	select NO_IOPORT
 	select PLAT_SAMSUNG
 	select S3C_GPIO_TRACK
@@ -31,6 +29,13 @@ config PLAT_S5P
 	help
 	  Base platform code for Samsung's S5P series SoC.
 
+config SAMSUNG_PM
+	bool
+	depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || S5P_PM)
+	default y
+	help
+	  Base platform power management code for samsung code
+
 if PLAT_SAMSUNG
 
 # boot configurations
@@ -60,6 +65,20 @@ config S3C_LOWLEVEL_UART_PORT
 	  this configuration should be between zero and two. The port
 	  must have been initialised by the boot-loader before use.
 
+config SAMSUNG_ATAGS
+	def_bool n
+	depends on !ARCH_MULTIPLATFORM
+	depends on ATAGS
+	help
+	   This option enables ATAGS based boot support code for
+	   Samsung platforms, including static platform devices, legacy
+	   clock, timer and interrupt initialization, etc.
+
+	   Platforms that support only DT based boot need not to select
+	   this option.
+
+if SAMSUNG_ATAGS
+
 # timer options
 
 config SAMSUNG_HRT
@@ -367,11 +386,6 @@ config S5P_DEV_JPEG
 	help
 	  Compile in platform device definitions for JPEG codec
 
-config S5P_DEV_MFC
-	bool
-	help
-	  Compile in setup memory (init) code for MFC
-
 config S5P_DEV_ONENAND
 	bool
 	help
@@ -412,6 +426,21 @@ config S3C_DMA
 	help
 	  Internal configuration for S3C DMA core
 
+config S5P_IRQ_PM
+	bool
+	default y if S5P_PM
+	help
+	  Legacy IRQ power management for S5P platforms
+
+config SAMSUNG_PM_GPIO
+	bool
+	default y if GPIO_SAMSUNG && PM
+	help
+	  Include legacy GPIO power management code for platforms not using
+	  pinctrl-samsung driver.
+
+endif
+
 config SAMSUNG_DMADEV
 	bool
 	select ARM_AMBA
@@ -421,6 +450,11 @@ config SAMSUNG_DMADEV
 	help
 	  Use DMA device engine for PL330 DMAC.
 
+config S5P_DEV_MFC
+	bool
+	help
+	  Compile in setup memory (init) code for MFC
+
 comment "Power management"
 
 config SAMSUNG_PM_DEBUG
@@ -475,6 +509,12 @@ config SAMSUNG_WAKEMASK
 	  and above. This code allows a set of interrupt to wakeup-mask
 	  mappings. See <plat/wakeup-mask.h>
 
+config SAMSUNG_WDT_RESET
+	bool
+	help
+	  Compile support for system restart by triggering watchdog reset.
+	  Used on SoCs that do not provide dedicated reset control.
+
 config S5P_PM
 	bool
 	help
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/Makefile linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/Makefile
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -31,10 +31,10 @@ obj-$(CONFIG_S3C_ADC)	+= adc.o
 
 # devices
 
-obj-y				+= platformdata.o
+obj-$(CONFIG_SAMSUNG_ATAGS)	+= platformdata.o
 
-obj-y				+= devs.o
-obj-y				+= dev-uart.o
+obj-$(CONFIG_SAMSUNG_ATAGS)	+= devs.o
+obj-$(CONFIG_SAMSUNG_ATAGS)	+= dev-uart.o
 obj-$(CONFIG_S5P_DEV_MFC)	+= s5p-dev-mfc.o
 obj-$(CONFIG_S5P_DEV_UART)	+= s5p-dev-uart.o
 
@@ -51,11 +51,13 @@ obj-$(CONFIG_SAMSUNG_DMADEV)	+= dma-ops.
 
 # PM support
 
-obj-$(CONFIG_PM)		+= pm.o
-obj-$(CONFIG_PM)		+= pm-gpio.o
+obj-$(CONFIG_SAMSUNG_PM)	+= pm.o
+obj-$(CONFIG_SAMSUNG_PM_GPIO)	+= pm-gpio.o
 obj-$(CONFIG_SAMSUNG_PM_CHECK)	+= pm-check.o
 
 obj-$(CONFIG_SAMSUNG_WAKEMASK)	+= wakeup-mask.o
+obj-$(CONFIG_SAMSUNG_WDT_RESET)	+= watchdog-reset.o
 
-obj-$(CONFIG_S5P_PM)		+= s5p-pm.o s5p-irq-pm.o
+obj-$(CONFIG_S5P_PM)		+= s5p-pm.o
+obj-$(CONFIG_S5P_IRQ_PM)	+= s5p-irq-pm.o
 obj-$(CONFIG_S5P_SLEEP)		+= s5p-sleep.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/pm.c linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/pm.c
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,13 +22,17 @@
 
 #include <asm/cacheflush.h>
 #include <asm/suspend.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
 
 #include <plat/regs-serial.h>
+
+#ifdef CONFIG_SAMSUNG_ATAGS
+#include <mach/hardware.h>
+#include <mach/map.h>
 #include <mach/regs-clock.h>
 #include <mach/regs-irq.h>
 #include <mach/irqs.h>
+#endif
+
 #include <asm/irq.h>
 
 #include <plat/pm.h>
@@ -76,7 +80,7 @@ unsigned char pm_uart_udivslot;
 
 #ifdef CONFIG_SAMSUNG_PM_DEBUG
 
-static struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
+static struct pm_uart_save uart_save;
 
 static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
 {
@@ -97,11 +101,7 @@ static void s3c_pm_save_uart(unsigned in
 
 static void s3c_pm_save_uarts(void)
 {
-	struct pm_uart_save *save = uart_save;
-	unsigned int uart;
-
-	for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
-		s3c_pm_save_uart(uart, save);
+	s3c_pm_save_uart(CONFIG_DEBUG_S3C_UART, &uart_save);
 }
 
 static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
@@ -122,11 +122,7 @@ static void s3c_pm_restore_uart(unsigned
 
 static void s3c_pm_restore_uarts(void)
 {
-	struct pm_uart_save *save = uart_save;
-	unsigned int uart;
-
-	for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
-		s3c_pm_restore_uart(uart, save);
+	s3c_pm_restore_uart(CONFIG_DEBUG_S3C_UART, &uart_save);
 }
 #else
 static void s3c_pm_save_uarts(void) { }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/pm-gpio.c linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/pm-gpio.c
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/pm-gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/pm-gpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -192,7 +192,8 @@ struct samsung_gpio_pm samsung_gpio_pm_2
 	.resume = samsung_gpio_pm_2bit_resume,
 };
 
-#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
+#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P) \
+	|| defined(CONFIG_ARCH_EXYNOS)
 static void samsung_gpio_pm_4bit_save(struct samsung_gpio_chip *chip)
 {
 	chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
@@ -302,7 +303,7 @@ struct samsung_gpio_pm samsung_gpio_pm_4
 	.save	= samsung_gpio_pm_4bit_save,
 	.resume = samsung_gpio_pm_4bit_resume,
 };
-#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
+#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P || CONFIG_ARCH_EXYNOS */
 
 /**
  * samsung_pm_save_gpio() - save gpio chip data for suspend
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/s5p-dev-mfc.c linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/s5p-dev-mfc.c
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/s5p-dev-mfc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/s5p-dev-mfc.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,10 +17,12 @@
 #include <linux/of_fdt.h>
 #include <linux/of.h>
 
+#include <plat/mfc.h>
+
+#ifdef CONFIG_SAMSUNG_ATAGS
 #include <mach/map.h>
 #include <mach/irqs.h>
 #include <plat/devs.h>
-#include <plat/mfc.h>
 
 static struct resource s5p_mfc_resource[] = {
 	[0] = DEFINE_RES_MEM(S5P_PA_MFC, SZ_64K),
@@ -61,6 +63,10 @@ struct platform_device s5p_device_mfc_r
 		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 };
+#else
+static struct platform_device s5p_device_mfc_l;
+static struct platform_device s5p_device_mfc_r;
+#endif
 
 struct s5p_mfc_reserved_mem {
 	phys_addr_t	base;
@@ -70,6 +76,7 @@ struct s5p_mfc_reserved_mem {
 
 static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata;
 
+
 void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
 				phys_addr_t lbase, unsigned int lsize)
 {
@@ -93,6 +100,7 @@ void __init s5p_mfc_reserve_mem(phys_add
 	}
 }
 
+#ifdef CONFIG_SAMSUNG_ATAGS
 static int __init s5p_mfc_memory_init(void)
 {
 	int i;
@@ -111,6 +119,7 @@ static int __init s5p_mfc_memory_init(vo
 	return 0;
 }
 device_initcall(s5p_mfc_memory_init);
+#endif
 
 #ifdef CONFIG_OF
 int __init s5p_fdt_find_mfc_mem(unsigned long node, const char *uname,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/samsung-time.c linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/samsung-time.c
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/samsung-time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/samsung-time.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,12 +15,12 @@
 #include <linux/clk.h>
 #include <linux/clockchips.h>
 #include <linux/platform_device.h>
+#include <linux/sched_clock.h>
 
 #include <asm/smp_twd.h>
 #include <asm/mach/time.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/sched_clock.h>
 
 #include <mach/map.h>
 #include <plat/devs.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-samsung/watchdog-reset.c linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/watchdog-reset.c
--- linux-libre-3.10-gnu/arch/arm/plat-samsung/watchdog-reset.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-samsung/watchdog-reset.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,97 @@
+/* arch/arm/plat-samsung/watchdog-reset.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Coyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * Watchdog reset support for Samsung SoCs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define S3C2410_WTCON			0x00
+#define S3C2410_WTDAT			0x04
+#define S3C2410_WTCNT			0x08
+
+#define S3C2410_WTCON_ENABLE		(1 << 5)
+#define S3C2410_WTCON_DIV16		(0 << 3)
+#define S3C2410_WTCON_RSTEN		(1 << 0)
+#define S3C2410_WTCON_PRESCALE(x)	((x) << 8)
+
+static void __iomem *wdt_base;
+static struct clk *wdt_clock;
+
+void samsung_wdt_reset(void)
+{
+	if (!wdt_base) {
+		pr_err("%s: wdt reset not initialized\n", __func__);
+		/* delay to allow the serial port to show the message */
+		mdelay(50);
+		return;
+	}
+
+	if (!IS_ERR(wdt_clock))
+		clk_prepare_enable(wdt_clock);
+
+	/* disable watchdog, to be safe  */
+	__raw_writel(0, wdt_base + S3C2410_WTCON);
+
+	/* put initial values into count and data */
+	__raw_writel(0x80, wdt_base + S3C2410_WTCNT);
+	__raw_writel(0x80, wdt_base + S3C2410_WTDAT);
+
+	/* set the watchdog to go and reset... */
+	__raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV16 |
+			S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x20),
+			wdt_base + S3C2410_WTCON);
+
+	/* wait for reset to assert... */
+	mdelay(500);
+
+	pr_err("Watchdog reset failed to assert reset\n");
+
+	/* delay to allow the serial port to show the message */
+	mdelay(50);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id s3c2410_wdt_match[] = {
+	{ .compatible = "samsung,s3c2410-wdt" },
+	{},
+};
+
+void __init samsung_wdt_reset_of_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_matching_node(NULL, s3c2410_wdt_match);
+	if (!np) {
+		pr_err("%s: failed to find watchdog node\n", __func__);
+		return;
+	}
+
+	wdt_base = of_iomap(np, 0);
+	if (!wdt_base) {
+		pr_err("%s: failed to map watchdog registers\n", __func__);
+		return;
+	}
+
+	wdt_clock = of_clk_get(np, 0);
+}
+#endif
+
+void __init samsung_wdt_reset_init(void __iomem *base)
+{
+	wdt_base = base;
+	wdt_clock = clk_get(NULL, "watchdog");
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-versatile/headsmp.S linux-libre-3.11-rc7-gnu/arch/arm/plat-versatile/headsmp.S
--- linux-libre-3.10-gnu/arch/arm/plat-versatile/headsmp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-versatile/headsmp.S	2013-08-25 20:43:22.000000000 -0400
@@ -11,8 +11,6 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-	__INIT
-
 /*
  * Realview/Versatile Express specific entry point for secondary CPUs.
  * This provides a "holding pen" into which all secondary cores are held
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-versatile/platsmp.c linux-libre-3.11-rc7-gnu/arch/arm/plat-versatile/platsmp.c
--- linux-libre-3.10-gnu/arch/arm/plat-versatile/platsmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-versatile/platsmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,7 @@
  * observers, irrespective of whether they're taking part in coherency
  * or not.  This is necessary for the hotplug code to work reliably.
  */
-static void __cpuinit write_pen_release(int val)
+static void write_pen_release(int val)
 {
 	pen_release = val;
 	smp_wmb();
@@ -33,7 +33,7 @@ static void __cpuinit write_pen_release(
 
 static DEFINE_SPINLOCK(boot_lock);
 
-void __cpuinit versatile_secondary_init(unsigned int cpu)
+void versatile_secondary_init(unsigned int cpu)
 {
 	/*
 	 * let the primary processor know we're out of the
@@ -48,7 +48,7 @@ void __cpuinit versatile_secondary_init(
 	spin_unlock(&boot_lock);
 }
 
-int __cpuinit versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
+int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/plat-versatile/sched-clock.c linux-libre-3.11-rc7-gnu/arch/arm/plat-versatile/sched-clock.c
--- linux-libre-3.10-gnu/arch/arm/plat-versatile/sched-clock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/plat-versatile/sched-clock.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,8 +20,8 @@
  */
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/sched_clock.h>
 
-#include <asm/sched_clock.h>
 #include <plat/sched_clock.h>
 
 static void __iomem *ctr;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/xen/enlighten.c linux-libre-3.11-rc7-gnu/arch/arm/xen/enlighten.c
--- linux-libre-3.10-gnu/arch/arm/xen/enlighten.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/xen/enlighten.c	2013-08-25 20:43:22.000000000 -0400
@@ -170,9 +170,10 @@ static void __init xen_percpu_init(void
 	per_cpu(xen_vcpu, cpu) = vcpup;
 
 	enable_percpu_irq(xen_events_irq, 0);
+	put_cpu();
 }
 
-static void xen_restart(char str, const char *cmd)
+static void xen_restart(enum reboot_mode reboot_mode, const char *cmd)
 {
 	struct sched_shutdown r = { .reason = SHUTDOWN_reboot };
 	int rc;
@@ -314,4 +315,5 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op);
 EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
 EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
 EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);
+EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op);
 EXPORT_SYMBOL_GPL(privcmd_call);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm/xen/hypercall.S linux-libre-3.11-rc7-gnu/arch/arm/xen/hypercall.S
--- linux-libre-3.10-gnu/arch/arm/xen/hypercall.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm/xen/hypercall.S	2013-08-25 20:43:22.000000000 -0400
@@ -88,6 +88,7 @@ HYPERCALL2(hvm_op);
 HYPERCALL2(memory_op);
 HYPERCALL2(physdev_op);
 HYPERCALL3(vcpu_op);
+HYPERCALL1(tmem_op);
 
 ENTRY(privcmd_call)
 	stmdb sp!, {r4}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/boot/dts/apm-mustang.dts linux-libre-3.11-rc7-gnu/arch/arm64/boot/dts/apm-mustang.dts
--- linux-libre-3.10-gnu/arch/arm64/boot/dts/apm-mustang.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/boot/dts/apm-mustang.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,26 @@
+/*
+ * dts file for AppliedMicro (APM) Mustang Board
+ *
+ * Copyright (C) 2013, Applied Micro Circuits Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+/dts-v1/;
+
+/include/ "apm-storm.dtsi"
+
+/ {
+	model = "APM X-Gene Mustang board";
+	compatible = "apm,mustang", "apm,xgene-storm";
+
+	chosen { };
+
+	memory {
+		device_type = "memory";
+		reg = < 0x1 0x00000000 0x0 0x80000000 >; /* Updated by bootloader */
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/boot/dts/apm-storm.dtsi linux-libre-3.11-rc7-gnu/arch/arm64/boot/dts/apm-storm.dtsi
--- linux-libre-3.10-gnu/arch/arm64/boot/dts/apm-storm.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/boot/dts/apm-storm.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * dts file for AppliedMicro (APM) X-Gene Storm SOC
+ *
+ * Copyright (C) 2013, Applied Micro Circuits Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+/ {
+	compatible = "apm,xgene-storm";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu@000 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu@001 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu@100 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu@101 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu@200 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu@201 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu@300 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x300>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu@301 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x301>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+	};
+
+	gic: interrupt-controller@78010000 {
+		compatible = "arm,cortex-a15-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0x0 0x78010000 0x0 0x1000>,	/* GIC Dist */
+		      <0x0 0x78020000 0x0 0x1000>,	/* GIC CPU */
+		      <0x0 0x78040000 0x0 0x2000>,	/* GIC VCPU Control */
+		      <0x0 0x78060000 0x0 0x2000>;	/* GIC VCPU */
+		interrupts = <1 9 0xf04>;	/* GIC Maintenence IRQ */
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 0 0xff01>,	/* Secure Phys IRQ */
+			     <1 13 0xff01>,	/* Non-secure Phys IRQ */
+			     <1 14 0xff01>,	/* Virt IRQ */
+			     <1 15 0xff01>;	/* Hyp IRQ */
+		clock-frequency = <50000000>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		serial0: serial@1c020000 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0 0x1c020000 0x0 0x1000>;
+			reg-shift = <2>;
+			clock-frequency = <10000000>; /* Updated by bootloader */
+			interrupt-parent = <&gic>;
+			interrupts = <0x0 0x4c 0x4>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/boot/dts/Makefile linux-libre-3.11-rc7-gnu/arch/arm64/boot/dts/Makefile
--- linux-libre-3.10-gnu/arch/arm64/boot/dts/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/boot/dts/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,5 @@
 dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb
+dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb
 
 targets += dtbs
 targets += $(dtb-y)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/configs/defconfig linux-libre-3.11-rc7-gnu/arch/arm64/configs/defconfig
--- linux-libre-3.10-gnu/arch/arm64/configs/defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/configs/defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_ARCH_VEXPRESS=y
+CONFIG_ARCH_XGENE=y
 CONFIG_SMP=y
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_CMDLINE="console=ttyAMA0"
@@ -54,6 +55,9 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/arch_timer.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/arch_timer.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/arch_timer.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/arch_timer.h	2013-08-25 20:43:22.000000000 -0400
@@ -97,7 +97,7 @@ static inline u32 arch_timer_get_cntfrq(
 	return val;
 }
 
-static inline void __cpuinit arch_counter_set_user_access(void)
+static inline void arch_counter_set_user_access(void)
 {
 	u32 cntkctl;
 
@@ -110,16 +110,6 @@ static inline void __cpuinit arch_counte
 	asm volatile("msr	cntkctl_el1, %0" : : "r" (cntkctl));
 }
 
-static inline u64 arch_counter_get_cntpct(void)
-{
-	u64 cval;
-
-	isb();
-	asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
-
-	return cval;
-}
-
 static inline u64 arch_counter_get_cntvct(void)
 {
 	u64 cval;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/cacheflush.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/cacheflush.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/cacheflush.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/cacheflush.h	2013-08-25 20:43:22.000000000 -0400
@@ -123,9 +123,6 @@ static inline void __flush_icache_all(vo
 #define flush_dcache_mmap_unlock(mapping) \
 	spin_unlock_irq(&(mapping)->tree_lock)
 
-#define flush_icache_user_range(vma,page,addr,len) \
-	flush_dcache_page(page)
-
 /*
  * We don't appear to need to do anything here.  In fact, if we did, we'd
  * duplicate cache flushing elsewhere performed by flush_dcache_page().
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/cputype.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/cputype.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/cputype.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/cputype.h	2013-08-25 20:43:22.000000000 -0400
@@ -37,11 +37,14 @@
 })
 
 #define ARM_CPU_IMP_ARM		0x41
+#define ARM_CPU_IMP_APM		0x50
 
 #define ARM_CPU_PART_AEM_V8	0xD0F0
 #define ARM_CPU_PART_FOUNDATION	0xD000
 #define ARM_CPU_PART_CORTEX_A57	0xD070
 
+#define APM_CPU_PART_POTENZA	0x0000
+
 #ifndef __ASSEMBLY__
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/debug-monitors.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/debug-monitors.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/debug-monitors.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/debug-monitors.h	2013-08-25 20:43:22.000000000 -0400
@@ -83,6 +83,8 @@ static inline int reinstall_suspended_bp
 }
 #endif
 
+int aarch32_break_handler(struct pt_regs *regs);
+
 #endif	/* __ASSEMBLY */
 #endif	/* __KERNEL__ */
 #endif	/* __ASM_DEBUG_MONITORS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/device.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/device.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/device.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/device.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,9 @@
 
 struct dev_archdata {
 	struct dma_map_ops *dma_ops;
+#ifdef CONFIG_IOMMU_API
+	void *iommu;			/* private IOMMU data */
+#endif
 };
 
 struct pdev_archdata {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/dma-mapping.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/dma-mapping.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/dma-mapping.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/dma-mapping.h	2013-08-25 20:43:22.000000000 -0400
@@ -81,8 +81,12 @@ static inline void dma_mark_clean(void *
 {
 }
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flags)
+#define dma_alloc_coherent(d, s, h, f)	dma_alloc_attrs(d, s, h, f, NULL)
+#define dma_free_coherent(d, s, h, f)	dma_free_attrs(d, s, h, f, NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t flags,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *vaddr;
@@ -90,13 +94,14 @@ static inline void *dma_alloc_coherent(s
 	if (dma_alloc_from_coherent(dev, size, dma_handle, &vaddr))
 		return vaddr;
 
-	vaddr = ops->alloc(dev, size, dma_handle, flags, NULL);
+	vaddr = ops->alloc(dev, size, dma_handle, flags, attrs);
 	debug_dma_alloc_coherent(dev, size, *dma_handle, vaddr);
 	return vaddr;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t dev_addr)
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *vaddr, dma_addr_t dev_addr,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -104,7 +109,7 @@ static inline void dma_free_coherent(str
 		return;
 
 	debug_dma_free_coherent(dev, size, vaddr, dev_addr);
-	ops->free(dev, size, vaddr, dev_addr, NULL);
+	ops->free(dev, size, vaddr, dev_addr, attrs);
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/hugetlb.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/hugetlb.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/hugetlb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/hugetlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,117 @@
+/*
+ * arch/arm64/include/asm/hugetlb.h
+ *
+ * Copyright (C) 2013 Linaro Ltd.
+ *
+ * Based on arch/x86/include/asm/hugetlb.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_HUGETLB_H
+#define __ASM_HUGETLB_H
+
+#include <asm-generic/hugetlb.h>
+#include <asm/page.h>
+
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+	return *ptep;
+}
+
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+				   pte_t *ptep, pte_t pte)
+{
+	set_pte_at(mm, addr, ptep, pte);
+}
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+					 unsigned long addr, pte_t *ptep)
+{
+	ptep_clear_flush(vma, addr, ptep);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+					   unsigned long addr, pte_t *ptep)
+{
+	ptep_set_wrprotect(mm, addr, ptep);
+}
+
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+					    unsigned long addr, pte_t *ptep)
+{
+	return ptep_get_and_clear(mm, addr, ptep);
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+					     unsigned long addr, pte_t *ptep,
+					     pte_t pte, int dirty)
+{
+	return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+}
+
+static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
+					  unsigned long addr, unsigned long end,
+					  unsigned long floor,
+					  unsigned long ceiling)
+{
+	free_pgd_range(tlb, addr, end, floor, ceiling);
+}
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+					 unsigned long addr, unsigned long len)
+{
+	return 0;
+}
+
+static inline int prepare_hugepage_range(struct file *file,
+					 unsigned long addr, unsigned long len)
+{
+	struct hstate *h = hstate_file(file);
+	if (len & ~huge_page_mask(h))
+		return -EINVAL;
+	if (addr & ~huge_page_mask(h))
+		return -EINVAL;
+	return 0;
+}
+
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+}
+
+static inline int huge_pte_none(pte_t pte)
+{
+	return pte_none(pte);
+}
+
+static inline pte_t huge_pte_wrprotect(pte_t pte)
+{
+	return pte_wrprotect(pte);
+}
+
+static inline int arch_prepare_hugepage(struct page *page)
+{
+	return 0;
+}
+
+static inline void arch_release_hugepage(struct page *page)
+{
+}
+
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+	clear_bit(PG_dcache_clean, &page->flags);
+}
+
+#endif /* __ASM_HUGETLB_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/hypervisor.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/hypervisor.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/hypervisor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/hypervisor.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _ASM_ARM64_HYPERVISOR_H
+#define _ASM_ARM64_HYPERVISOR_H
+
+#include <asm/xen/hypervisor.h>
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/io.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/io.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/io.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/io.h	2013-08-25 20:43:22.000000000 -0400
@@ -228,10 +228,12 @@ extern void __iounmap(volatile void __io
 #define PROT_DEFAULT		(PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY)
 #define PROT_DEVICE_nGnRE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
 #define PROT_NORMAL_NC		(PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
+#define PROT_NORMAL		(PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
 
 #define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_nocache(addr, size)	__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
+#define ioremap_cached(addr, size)	__ioremap((addr), (size), __pgprot(PROT_NORMAL))
 #define iounmap				__iounmap
 
 #define PROT_SECT_DEFAULT	(PMD_TYPE_SECT | PMD_SECT_AF)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_arm.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_arm.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_arm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_arm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM64_KVM_ARM_H__
+#define __ARM64_KVM_ARM_H__
+
+#include <asm/types.h>
+
+/* Hyp Configuration Register (HCR) bits */
+#define HCR_ID		(UL(1) << 33)
+#define HCR_CD		(UL(1) << 32)
+#define HCR_RW_SHIFT	31
+#define HCR_RW		(UL(1) << HCR_RW_SHIFT)
+#define HCR_TRVM	(UL(1) << 30)
+#define HCR_HCD		(UL(1) << 29)
+#define HCR_TDZ		(UL(1) << 28)
+#define HCR_TGE		(UL(1) << 27)
+#define HCR_TVM		(UL(1) << 26)
+#define HCR_TTLB	(UL(1) << 25)
+#define HCR_TPU		(UL(1) << 24)
+#define HCR_TPC		(UL(1) << 23)
+#define HCR_TSW		(UL(1) << 22)
+#define HCR_TAC		(UL(1) << 21)
+#define HCR_TIDCP	(UL(1) << 20)
+#define HCR_TSC		(UL(1) << 19)
+#define HCR_TID3	(UL(1) << 18)
+#define HCR_TID2	(UL(1) << 17)
+#define HCR_TID1	(UL(1) << 16)
+#define HCR_TID0	(UL(1) << 15)
+#define HCR_TWE		(UL(1) << 14)
+#define HCR_TWI		(UL(1) << 13)
+#define HCR_DC		(UL(1) << 12)
+#define HCR_BSU		(3 << 10)
+#define HCR_BSU_IS	(UL(1) << 10)
+#define HCR_FB		(UL(1) << 9)
+#define HCR_VA		(UL(1) << 8)
+#define HCR_VI		(UL(1) << 7)
+#define HCR_VF		(UL(1) << 6)
+#define HCR_AMO		(UL(1) << 5)
+#define HCR_IMO		(UL(1) << 4)
+#define HCR_FMO		(UL(1) << 3)
+#define HCR_PTW		(UL(1) << 2)
+#define HCR_SWIO	(UL(1) << 1)
+#define HCR_VM		(UL(1) << 0)
+
+/*
+ * The bits we set in HCR:
+ * RW:		64bit by default, can be overriden for 32bit VMs
+ * TAC:		Trap ACTLR
+ * TSC:		Trap SMC
+ * TSW:		Trap cache operations by set/way
+ * TWI:		Trap WFI
+ * TIDCP:	Trap L2CTLR/L2ECTLR
+ * BSU_IS:	Upgrade barriers to the inner shareable domain
+ * FB:		Force broadcast of all maintainance operations
+ * AMO:		Override CPSR.A and enable signaling with VA
+ * IMO:		Override CPSR.I and enable signaling with VI
+ * FMO:		Override CPSR.F and enable signaling with VF
+ * SWIO:	Turn set/way invalidates into set/way clean+invalidate
+ */
+#define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWI | HCR_VM | HCR_BSU_IS | \
+			 HCR_FB | HCR_TAC | HCR_AMO | HCR_IMO | HCR_FMO | \
+			 HCR_SWIO | HCR_TIDCP | HCR_RW)
+#define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF)
+
+/* Hyp System Control Register (SCTLR_EL2) bits */
+#define SCTLR_EL2_EE	(1 << 25)
+#define SCTLR_EL2_WXN	(1 << 19)
+#define SCTLR_EL2_I	(1 << 12)
+#define SCTLR_EL2_SA	(1 << 3)
+#define SCTLR_EL2_C	(1 << 2)
+#define SCTLR_EL2_A	(1 << 1)
+#define SCTLR_EL2_M	1
+#define SCTLR_EL2_FLAGS	(SCTLR_EL2_M | SCTLR_EL2_A | SCTLR_EL2_C |	\
+			 SCTLR_EL2_SA | SCTLR_EL2_I)
+
+/* TCR_EL2 Registers bits */
+#define TCR_EL2_TBI	(1 << 20)
+#define TCR_EL2_PS	(7 << 16)
+#define TCR_EL2_PS_40B	(2 << 16)
+#define TCR_EL2_TG0	(1 << 14)
+#define TCR_EL2_SH0	(3 << 12)
+#define TCR_EL2_ORGN0	(3 << 10)
+#define TCR_EL2_IRGN0	(3 << 8)
+#define TCR_EL2_T0SZ	0x3f
+#define TCR_EL2_MASK	(TCR_EL2_TG0 | TCR_EL2_SH0 | \
+			 TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ)
+
+#define TCR_EL2_FLAGS	(TCR_EL2_PS_40B)
+
+/* VTCR_EL2 Registers bits */
+#define VTCR_EL2_PS_MASK	(7 << 16)
+#define VTCR_EL2_PS_40B		(2 << 16)
+#define VTCR_EL2_TG0_MASK	(1 << 14)
+#define VTCR_EL2_TG0_4K		(0 << 14)
+#define VTCR_EL2_TG0_64K	(1 << 14)
+#define VTCR_EL2_SH0_MASK	(3 << 12)
+#define VTCR_EL2_SH0_INNER	(3 << 12)
+#define VTCR_EL2_ORGN0_MASK	(3 << 10)
+#define VTCR_EL2_ORGN0_WBWA	(1 << 10)
+#define VTCR_EL2_IRGN0_MASK	(3 << 8)
+#define VTCR_EL2_IRGN0_WBWA	(1 << 8)
+#define VTCR_EL2_SL0_MASK	(3 << 6)
+#define VTCR_EL2_SL0_LVL1	(1 << 6)
+#define VTCR_EL2_T0SZ_MASK	0x3f
+#define VTCR_EL2_T0SZ_40B	24
+
+#ifdef CONFIG_ARM64_64K_PAGES
+/*
+ * Stage2 translation configuration:
+ * 40bits output (PS = 2)
+ * 40bits input  (T0SZ = 24)
+ * 64kB pages (TG0 = 1)
+ * 2 level page tables (SL = 1)
+ */
+#define VTCR_EL2_FLAGS		(VTCR_EL2_PS_40B | VTCR_EL2_TG0_64K | \
+				 VTCR_EL2_SH0_INNER | VTCR_EL2_ORGN0_WBWA | \
+				 VTCR_EL2_IRGN0_WBWA | VTCR_EL2_SL0_LVL1 | \
+				 VTCR_EL2_T0SZ_40B)
+#define VTTBR_X		(38 - VTCR_EL2_T0SZ_40B)
+#else
+/*
+ * Stage2 translation configuration:
+ * 40bits output (PS = 2)
+ * 40bits input  (T0SZ = 24)
+ * 4kB pages (TG0 = 0)
+ * 3 level page tables (SL = 1)
+ */
+#define VTCR_EL2_FLAGS		(VTCR_EL2_PS_40B | VTCR_EL2_TG0_4K | \
+				 VTCR_EL2_SH0_INNER | VTCR_EL2_ORGN0_WBWA | \
+				 VTCR_EL2_IRGN0_WBWA | VTCR_EL2_SL0_LVL1 | \
+				 VTCR_EL2_T0SZ_40B)
+#define VTTBR_X		(37 - VTCR_EL2_T0SZ_40B)
+#endif
+
+#define VTTBR_BADDR_SHIFT (VTTBR_X - 1)
+#define VTTBR_BADDR_MASK  (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT)
+#define VTTBR_VMID_SHIFT  (48LLU)
+#define VTTBR_VMID_MASK	  (0xffLLU << VTTBR_VMID_SHIFT)
+
+/* Hyp System Trap Register */
+#define HSTR_EL2_TTEE	(1 << 16)
+#define HSTR_EL2_T(x)	(1 << x)
+
+/* Hyp Coprocessor Trap Register */
+#define CPTR_EL2_TCPAC	(1 << 31)
+#define CPTR_EL2_TTA	(1 << 20)
+#define CPTR_EL2_TFP	(1 << 10)
+
+/* Hyp Debug Configuration Register bits */
+#define MDCR_EL2_TDRA		(1 << 11)
+#define MDCR_EL2_TDOSA		(1 << 10)
+#define MDCR_EL2_TDA		(1 << 9)
+#define MDCR_EL2_TDE		(1 << 8)
+#define MDCR_EL2_HPME		(1 << 7)
+#define MDCR_EL2_TPM		(1 << 6)
+#define MDCR_EL2_TPMCR		(1 << 5)
+#define MDCR_EL2_HPMN_MASK	(0x1F)
+
+/* Exception Syndrome Register (ESR) bits */
+#define ESR_EL2_EC_SHIFT	(26)
+#define ESR_EL2_EC		(0x3fU << ESR_EL2_EC_SHIFT)
+#define ESR_EL2_IL		(1U << 25)
+#define ESR_EL2_ISS		(ESR_EL2_IL - 1)
+#define ESR_EL2_ISV_SHIFT	(24)
+#define ESR_EL2_ISV		(1U << ESR_EL2_ISV_SHIFT)
+#define ESR_EL2_SAS_SHIFT	(22)
+#define ESR_EL2_SAS		(3U << ESR_EL2_SAS_SHIFT)
+#define ESR_EL2_SSE		(1 << 21)
+#define ESR_EL2_SRT_SHIFT	(16)
+#define ESR_EL2_SRT_MASK	(0x1f << ESR_EL2_SRT_SHIFT)
+#define ESR_EL2_SF 		(1 << 15)
+#define ESR_EL2_AR 		(1 << 14)
+#define ESR_EL2_EA 		(1 << 9)
+#define ESR_EL2_CM 		(1 << 8)
+#define ESR_EL2_S1PTW 		(1 << 7)
+#define ESR_EL2_WNR		(1 << 6)
+#define ESR_EL2_FSC		(0x3f)
+#define ESR_EL2_FSC_TYPE	(0x3c)
+
+#define ESR_EL2_CV_SHIFT	(24)
+#define ESR_EL2_CV		(1U << ESR_EL2_CV_SHIFT)
+#define ESR_EL2_COND_SHIFT	(20)
+#define ESR_EL2_COND		(0xfU << ESR_EL2_COND_SHIFT)
+
+
+#define FSC_FAULT	(0x04)
+#define FSC_PERM	(0x0c)
+
+/* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
+#define HPFAR_MASK	(~0xFUL)
+
+#define ESR_EL2_EC_UNKNOWN	(0x00)
+#define ESR_EL2_EC_WFI		(0x01)
+#define ESR_EL2_EC_CP15_32	(0x03)
+#define ESR_EL2_EC_CP15_64	(0x04)
+#define ESR_EL2_EC_CP14_MR	(0x05)
+#define ESR_EL2_EC_CP14_LS	(0x06)
+#define ESR_EL2_EC_FP_ASIMD	(0x07)
+#define ESR_EL2_EC_CP10_ID	(0x08)
+#define ESR_EL2_EC_CP14_64	(0x0C)
+#define ESR_EL2_EC_ILL_ISS	(0x0E)
+#define ESR_EL2_EC_SVC32	(0x11)
+#define ESR_EL2_EC_HVC32	(0x12)
+#define ESR_EL2_EC_SMC32	(0x13)
+#define ESR_EL2_EC_SVC64	(0x15)
+#define ESR_EL2_EC_HVC64	(0x16)
+#define ESR_EL2_EC_SMC64	(0x17)
+#define ESR_EL2_EC_SYS64	(0x18)
+#define ESR_EL2_EC_IABT		(0x20)
+#define ESR_EL2_EC_IABT_HYP	(0x21)
+#define ESR_EL2_EC_PC_ALIGN	(0x22)
+#define ESR_EL2_EC_DABT		(0x24)
+#define ESR_EL2_EC_DABT_HYP	(0x25)
+#define ESR_EL2_EC_SP_ALIGN	(0x26)
+#define ESR_EL2_EC_FP_EXC32	(0x28)
+#define ESR_EL2_EC_FP_EXC64	(0x2C)
+#define ESR_EL2_EC_SERRROR	(0x2F)
+#define ESR_EL2_EC_BREAKPT	(0x30)
+#define ESR_EL2_EC_BREAKPT_HYP	(0x31)
+#define ESR_EL2_EC_SOFTSTP	(0x32)
+#define ESR_EL2_EC_SOFTSTP_HYP	(0x33)
+#define ESR_EL2_EC_WATCHPT	(0x34)
+#define ESR_EL2_EC_WATCHPT_HYP	(0x35)
+#define ESR_EL2_EC_BKPT32	(0x38)
+#define ESR_EL2_EC_VECTOR32	(0x3A)
+#define ESR_EL2_EC_BRK64	(0x3C)
+
+#define ESR_EL2_EC_xABT_xFSR_EXTABT	0x10
+
+#endif /* __ARM64_KVM_ARM_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_asm.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_asm.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_asm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_asm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM_KVM_ASM_H__
+#define __ARM_KVM_ASM_H__
+
+/*
+ * 0 is reserved as an invalid value.
+ * Order *must* be kept in sync with the hyp switch code.
+ */
+#define	MPIDR_EL1	1	/* MultiProcessor Affinity Register */
+#define	CSSELR_EL1	2	/* Cache Size Selection Register */
+#define	SCTLR_EL1	3	/* System Control Register */
+#define	ACTLR_EL1	4	/* Auxilliary Control Register */
+#define	CPACR_EL1	5	/* Coprocessor Access Control */
+#define	TTBR0_EL1	6	/* Translation Table Base Register 0 */
+#define	TTBR1_EL1	7	/* Translation Table Base Register 1 */
+#define	TCR_EL1		8	/* Translation Control Register */
+#define	ESR_EL1		9	/* Exception Syndrome Register */
+#define	AFSR0_EL1	10	/* Auxilary Fault Status Register 0 */
+#define	AFSR1_EL1	11	/* Auxilary Fault Status Register 1 */
+#define	FAR_EL1		12	/* Fault Address Register */
+#define	MAIR_EL1	13	/* Memory Attribute Indirection Register */
+#define	VBAR_EL1	14	/* Vector Base Address Register */
+#define	CONTEXTIDR_EL1	15	/* Context ID Register */
+#define	TPIDR_EL0	16	/* Thread ID, User R/W */
+#define	TPIDRRO_EL0	17	/* Thread ID, User R/O */
+#define	TPIDR_EL1	18	/* Thread ID, Privileged */
+#define	AMAIR_EL1	19	/* Aux Memory Attribute Indirection Register */
+#define	CNTKCTL_EL1	20	/* Timer Control Register (EL1) */
+#define	PAR_EL1		21	/* Physical Address Register */
+/* 32bit specific registers. Keep them at the end of the range */
+#define	DACR32_EL2	22	/* Domain Access Control Register */
+#define	IFSR32_EL2	23	/* Instruction Fault Status Register */
+#define	FPEXC32_EL2	24	/* Floating-Point Exception Control Register */
+#define	DBGVCR32_EL2	25	/* Debug Vector Catch Register */
+#define	TEECR32_EL1	26	/* ThumbEE Configuration Register */
+#define	TEEHBR32_EL1	27	/* ThumbEE Handler Base Register */
+#define	NR_SYS_REGS	28
+
+/* 32bit mapping */
+#define c0_MPIDR	(MPIDR_EL1 * 2)	/* MultiProcessor ID Register */
+#define c0_CSSELR	(CSSELR_EL1 * 2)/* Cache Size Selection Register */
+#define c1_SCTLR	(SCTLR_EL1 * 2)	/* System Control Register */
+#define c1_ACTLR	(ACTLR_EL1 * 2)	/* Auxiliary Control Register */
+#define c1_CPACR	(CPACR_EL1 * 2)	/* Coprocessor Access Control */
+#define c2_TTBR0	(TTBR0_EL1 * 2)	/* Translation Table Base Register 0 */
+#define c2_TTBR0_high	(c2_TTBR0 + 1)	/* TTBR0 top 32 bits */
+#define c2_TTBR1	(TTBR1_EL1 * 2)	/* Translation Table Base Register 1 */
+#define c2_TTBR1_high	(c2_TTBR1 + 1)	/* TTBR1 top 32 bits */
+#define c2_TTBCR	(TCR_EL1 * 2)	/* Translation Table Base Control R. */
+#define c3_DACR		(DACR32_EL2 * 2)/* Domain Access Control Register */
+#define c5_DFSR		(ESR_EL1 * 2)	/* Data Fault Status Register */
+#define c5_IFSR		(IFSR32_EL2 * 2)/* Instruction Fault Status Register */
+#define c5_ADFSR	(AFSR0_EL1 * 2)	/* Auxiliary Data Fault Status R */
+#define c5_AIFSR	(AFSR1_EL1 * 2)	/* Auxiliary Instr Fault Status R */
+#define c6_DFAR		(FAR_EL1 * 2)	/* Data Fault Address Register */
+#define c6_IFAR		(c6_DFAR + 1)	/* Instruction Fault Address Register */
+#define c7_PAR		(PAR_EL1 * 2)	/* Physical Address Register */
+#define c7_PAR_high	(c7_PAR + 1)	/* PAR top 32 bits */
+#define c10_PRRR	(MAIR_EL1 * 2)	/* Primary Region Remap Register */
+#define c10_NMRR	(c10_PRRR + 1)	/* Normal Memory Remap Register */
+#define c12_VBAR	(VBAR_EL1 * 2)	/* Vector Base Address Register */
+#define c13_CID		(CONTEXTIDR_EL1 * 2)	/* Context ID Register */
+#define c13_TID_URW	(TPIDR_EL0 * 2)	/* Thread ID, User R/W */
+#define c13_TID_URO	(TPIDRRO_EL0 * 2)/* Thread ID, User R/O */
+#define c13_TID_PRIV	(TPIDR_EL1 * 2)	/* Thread ID, Privileged */
+#define c10_AMAIR	(AMAIR_EL1 * 2)	/* Aux Memory Attr Indirection Reg */
+#define c14_CNTKCTL	(CNTKCTL_EL1 * 2) /* Timer Control Register (PL1) */
+#define NR_CP15_REGS	(NR_SYS_REGS * 2)
+
+#define ARM_EXCEPTION_IRQ	  0
+#define ARM_EXCEPTION_TRAP	  1
+
+#ifndef __ASSEMBLY__
+struct kvm;
+struct kvm_vcpu;
+
+extern char __kvm_hyp_init[];
+extern char __kvm_hyp_init_end[];
+
+extern char __kvm_hyp_vector[];
+
+extern char __kvm_hyp_code_start[];
+extern char __kvm_hyp_code_end[];
+
+extern void __kvm_flush_vm_context(void);
+extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
+
+extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
+#endif
+
+#endif /* __ARM_KVM_ASM_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_coproc.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_coproc.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_coproc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_coproc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/include/asm/kvm_coproc.h
+ * Copyright (C) 2012 Rusty Russell IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM64_KVM_COPROC_H__
+#define __ARM64_KVM_COPROC_H__
+
+#include <linux/kvm_host.h>
+
+void kvm_reset_sys_regs(struct kvm_vcpu *vcpu);
+
+struct kvm_sys_reg_table {
+	const struct sys_reg_desc *table;
+	size_t num;
+};
+
+struct kvm_sys_reg_target_table {
+	struct kvm_sys_reg_table table64;
+	struct kvm_sys_reg_table table32;
+};
+
+void kvm_register_target_sys_reg_table(unsigned int target,
+				       struct kvm_sys_reg_target_table *table);
+
+int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run);
+
+#define kvm_coproc_table_init kvm_sys_reg_table_init
+void kvm_sys_reg_table_init(void);
+
+struct kvm_one_reg;
+int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
+int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *);
+int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *);
+unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu);
+
+#endif /* __ARM64_KVM_COPROC_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_emulate.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_emulate.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_emulate.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_emulate.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/include/kvm_emulate.h
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM64_KVM_EMULATE_H__
+#define __ARM64_KVM_EMULATE_H__
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_mmio.h>
+#include <asm/ptrace.h>
+
+unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num);
+unsigned long *vcpu_spsr32(const struct kvm_vcpu *vcpu);
+
+bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
+void kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr);
+
+void kvm_inject_undefined(struct kvm_vcpu *vcpu);
+void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
+void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
+
+static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
+{
+	return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc;
+}
+
+static inline unsigned long *vcpu_elr_el1(const struct kvm_vcpu *vcpu)
+{
+	return (unsigned long *)&vcpu_gp_regs(vcpu)->elr_el1;
+}
+
+static inline unsigned long *vcpu_cpsr(const struct kvm_vcpu *vcpu)
+{
+	return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pstate;
+}
+
+static inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu)
+{
+	return !!(*vcpu_cpsr(vcpu) & PSR_MODE32_BIT);
+}
+
+static inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu)
+{
+	if (vcpu_mode_is_32bit(vcpu))
+		return kvm_condition_valid32(vcpu);
+
+	return true;
+}
+
+static inline void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr)
+{
+	if (vcpu_mode_is_32bit(vcpu))
+		kvm_skip_instr32(vcpu, is_wide_instr);
+	else
+		*vcpu_pc(vcpu) += 4;
+}
+
+static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
+{
+	*vcpu_cpsr(vcpu) |= COMPAT_PSR_T_BIT;
+}
+
+static inline unsigned long *vcpu_reg(const struct kvm_vcpu *vcpu, u8 reg_num)
+{
+	if (vcpu_mode_is_32bit(vcpu))
+		return vcpu_reg32(vcpu, reg_num);
+
+	return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.regs[reg_num];
+}
+
+/* Get vcpu SPSR for current mode */
+static inline unsigned long *vcpu_spsr(const struct kvm_vcpu *vcpu)
+{
+	if (vcpu_mode_is_32bit(vcpu))
+		return vcpu_spsr32(vcpu);
+
+	return (unsigned long *)&vcpu_gp_regs(vcpu)->spsr[KVM_SPSR_EL1];
+}
+
+static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu)
+{
+	u32 mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK;
+
+	if (vcpu_mode_is_32bit(vcpu))
+		return mode > COMPAT_PSR_MODE_USR;
+
+	return mode != PSR_MODE_EL0t;
+}
+
+static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.fault.esr_el2;
+}
+
+static inline unsigned long kvm_vcpu_get_hfar(const struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.fault.far_el2;
+}
+
+static inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu)
+{
+	return ((phys_addr_t)vcpu->arch.fault.hpfar_el2 & HPFAR_MASK) << 8;
+}
+
+static inline bool kvm_vcpu_dabt_isvalid(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_EL2_ISV);
+}
+
+static inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_EL2_WNR);
+}
+
+static inline bool kvm_vcpu_dabt_issext(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_EL2_SSE);
+}
+
+static inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu)
+{
+	return (kvm_vcpu_get_hsr(vcpu) & ESR_EL2_SRT_MASK) >> ESR_EL2_SRT_SHIFT;
+}
+
+static inline bool kvm_vcpu_dabt_isextabt(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_EL2_EA);
+}
+
+static inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_EL2_S1PTW);
+}
+
+static inline int kvm_vcpu_dabt_get_as(const struct kvm_vcpu *vcpu)
+{
+	return 1 << ((kvm_vcpu_get_hsr(vcpu) & ESR_EL2_SAS) >> ESR_EL2_SAS_SHIFT);
+}
+
+/* This one is not specific to Data Abort */
+static inline bool kvm_vcpu_trap_il_is32bit(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_EL2_IL);
+}
+
+static inline u8 kvm_vcpu_trap_get_class(const struct kvm_vcpu *vcpu)
+{
+	return kvm_vcpu_get_hsr(vcpu) >> ESR_EL2_EC_SHIFT;
+}
+
+static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu)
+{
+	return kvm_vcpu_trap_get_class(vcpu) == ESR_EL2_EC_IABT;
+}
+
+static inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu)
+{
+	return kvm_vcpu_get_hsr(vcpu) & ESR_EL2_FSC_TYPE;
+}
+
+#endif /* __ARM64_KVM_EMULATE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_host.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_host.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_host.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_host.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/include/asm/kvm_host.h:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM64_KVM_HOST_H__
+#define __ARM64_KVM_HOST_H__
+
+#include <asm/kvm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_mmio.h>
+
+#define KVM_MAX_VCPUS 4
+#define KVM_USER_MEM_SLOTS 32
+#define KVM_PRIVATE_MEM_SLOTS 4
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
+
+#include <kvm/arm_vgic.h>
+#include <kvm/arm_arch_timer.h>
+
+#define KVM_VCPU_MAX_FEATURES 2
+
+/* We don't currently support large pages. */
+#define KVM_HPAGE_GFN_SHIFT(x)	0
+#define KVM_NR_PAGE_SIZES	1
+#define KVM_PAGES_PER_HPAGE(x)	(1UL<<31)
+
+struct kvm_vcpu;
+int kvm_target_cpu(void);
+int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
+int kvm_arch_dev_ioctl_check_extension(long ext);
+
+struct kvm_arch {
+	/* The VMID generation used for the virt. memory system */
+	u64    vmid_gen;
+	u32    vmid;
+
+	/* 1-level 2nd stage table and lock */
+	spinlock_t pgd_lock;
+	pgd_t *pgd;
+
+	/* VTTBR value associated with above pgd and vmid */
+	u64    vttbr;
+
+	/* Interrupt controller */
+	struct vgic_dist	vgic;
+
+	/* Timer */
+	struct arch_timer_kvm	timer;
+};
+
+#define KVM_NR_MEM_OBJS     40
+
+/*
+ * We don't want allocation failures within the mmu code, so we preallocate
+ * enough memory for a single page fault in a cache.
+ */
+struct kvm_mmu_memory_cache {
+	int nobjs;
+	void *objects[KVM_NR_MEM_OBJS];
+};
+
+struct kvm_vcpu_fault_info {
+	u32 esr_el2;		/* Hyp Syndrom Register */
+	u64 far_el2;		/* Hyp Fault Address Register */
+	u64 hpfar_el2;		/* Hyp IPA Fault Address Register */
+};
+
+struct kvm_cpu_context {
+	struct kvm_regs	gp_regs;
+	union {
+		u64 sys_regs[NR_SYS_REGS];
+		u32 cp15[NR_CP15_REGS];
+	};
+};
+
+typedef struct kvm_cpu_context kvm_cpu_context_t;
+
+struct kvm_vcpu_arch {
+	struct kvm_cpu_context ctxt;
+
+	/* HYP configuration */
+	u64 hcr_el2;
+
+	/* Exception Information */
+	struct kvm_vcpu_fault_info fault;
+
+	/* Pointer to host CPU context */
+	kvm_cpu_context_t *host_cpu_context;
+
+	/* VGIC state */
+	struct vgic_cpu vgic_cpu;
+	struct arch_timer_cpu timer_cpu;
+
+	/*
+	 * Anything that is not used directly from assembly code goes
+	 * here.
+	 */
+	/* dcache set/way operation pending */
+	int last_pcpu;
+	cpumask_t require_dcache_flush;
+
+	/* Don't run the guest */
+	bool pause;
+
+	/* IO related fields */
+	struct kvm_decode mmio_decode;
+
+	/* Interrupt related fields */
+	u64 irq_lines;		/* IRQ and FIQ levels */
+
+	/* Cache some mmu pages needed inside spinlock regions */
+	struct kvm_mmu_memory_cache mmu_page_cache;
+
+	/* Target CPU and feature flags */
+	int target;
+	DECLARE_BITMAP(features, KVM_VCPU_MAX_FEATURES);
+
+	/* Detect first run of a vcpu */
+	bool has_run_once;
+};
+
+#define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
+#define vcpu_sys_reg(v,r)	((v)->arch.ctxt.sys_regs[(r)])
+#define vcpu_cp15(v,r)		((v)->arch.ctxt.cp15[(r)])
+
+struct kvm_vm_stat {
+	u32 remote_tlb_flush;
+};
+
+struct kvm_vcpu_stat {
+	u32 halt_wakeup;
+};
+
+struct kvm_vcpu_init;
+int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
+			const struct kvm_vcpu_init *init);
+unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
+int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
+struct kvm_one_reg;
+int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+
+#define KVM_ARCH_WANT_MMU_NOTIFIER
+struct kvm;
+int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
+int kvm_unmap_hva_range(struct kvm *kvm,
+			unsigned long start, unsigned long end);
+void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
+
+/* We do not have shadow page tables, hence the empty hooks */
+static inline int kvm_age_hva(struct kvm *kvm, unsigned long hva)
+{
+	return 0;
+}
+
+static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
+{
+	return 0;
+}
+
+struct kvm_vcpu *kvm_arm_get_running_vcpu(void);
+struct kvm_vcpu __percpu **kvm_get_running_vcpus(void);
+
+u64 kvm_call_hyp(void *hypfn, ...);
+
+int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
+		int exception_index);
+
+int kvm_perf_init(void);
+int kvm_perf_teardown(void);
+
+static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
+				       phys_addr_t pgd_ptr,
+				       unsigned long hyp_stack_ptr,
+				       unsigned long vector_ptr)
+{
+	/*
+	 * Call initialization code, and switch to the full blown
+	 * HYP code.
+	 */
+	kvm_call_hyp((void *)boot_pgd_ptr, pgd_ptr,
+		     hyp_stack_ptr, vector_ptr);
+}
+
+#endif /* __ARM64_KVM_HOST_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_mmio.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_mmio.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_mmio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_mmio.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM64_KVM_MMIO_H__
+#define __ARM64_KVM_MMIO_H__
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_arm.h>
+
+/*
+ * This is annoying. The mmio code requires this, even if we don't
+ * need any decoding. To be fixed.
+ */
+struct kvm_decode {
+	unsigned long rt;
+	bool sign_extend;
+};
+
+/*
+ * The in-kernel MMIO emulation code wants to use a copy of run->mmio,
+ * which is an anonymous type. Use our own type instead.
+ */
+struct kvm_exit_mmio {
+	phys_addr_t	phys_addr;
+	u8		data[8];
+	u32		len;
+	bool		is_write;
+};
+
+static inline void kvm_prepare_mmio(struct kvm_run *run,
+				    struct kvm_exit_mmio *mmio)
+{
+	run->mmio.phys_addr	= mmio->phys_addr;
+	run->mmio.len		= mmio->len;
+	run->mmio.is_write	= mmio->is_write;
+	memcpy(run->mmio.data, mmio->data, mmio->len);
+	run->exit_reason	= KVM_EXIT_MMIO;
+}
+
+int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
+		 phys_addr_t fault_ipa);
+
+#endif	/* __ARM64_KVM_MMIO_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_mmu.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_mmu.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_mmu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_mmu.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM64_KVM_MMU_H__
+#define __ARM64_KVM_MMU_H__
+
+#include <asm/page.h>
+#include <asm/memory.h>
+
+/*
+ * As we only have the TTBR0_EL2 register, we cannot express
+ * "negative" addresses. This makes it impossible to directly share
+ * mappings with the kernel.
+ *
+ * Instead, give the HYP mode its own VA region at a fixed offset from
+ * the kernel by just masking the top bits (which are all ones for a
+ * kernel address).
+ */
+#define HYP_PAGE_OFFSET_SHIFT	VA_BITS
+#define HYP_PAGE_OFFSET_MASK	((UL(1) << HYP_PAGE_OFFSET_SHIFT) - 1)
+#define HYP_PAGE_OFFSET		(PAGE_OFFSET & HYP_PAGE_OFFSET_MASK)
+
+/*
+ * Our virtual mapping for the idmap-ed MMU-enable code. Must be
+ * shared across all the page-tables. Conveniently, we use the last
+ * possible page, where no kernel mapping will ever exist.
+ */
+#define TRAMPOLINE_VA		(HYP_PAGE_OFFSET_MASK & PAGE_MASK)
+
+#ifdef __ASSEMBLY__
+
+/*
+ * Convert a kernel VA into a HYP VA.
+ * reg: VA to be converted.
+ */
+.macro kern_hyp_va	reg
+	and	\reg, \reg, #HYP_PAGE_OFFSET_MASK
+.endm
+
+#else
+
+#include <asm/cachetype.h>
+#include <asm/cacheflush.h>
+
+#define KERN_TO_HYP(kva)	((unsigned long)kva - PAGE_OFFSET + HYP_PAGE_OFFSET)
+
+/*
+ * Align KVM with the kernel's view of physical memory. Should be
+ * 40bit IPA, with PGD being 8kB aligned in the 4KB page configuration.
+ */
+#define KVM_PHYS_SHIFT	PHYS_MASK_SHIFT
+#define KVM_PHYS_SIZE	(1UL << KVM_PHYS_SHIFT)
+#define KVM_PHYS_MASK	(KVM_PHYS_SIZE - 1UL)
+
+/* Make sure we get the right size, and thus the right alignment */
+#define PTRS_PER_S2_PGD (1 << (KVM_PHYS_SHIFT - PGDIR_SHIFT))
+#define S2_PGD_ORDER	get_order(PTRS_PER_S2_PGD * sizeof(pgd_t))
+
+int create_hyp_mappings(void *from, void *to);
+int create_hyp_io_mappings(void *from, void *to, phys_addr_t);
+void free_boot_hyp_pgd(void);
+void free_hyp_pgds(void);
+
+int kvm_alloc_stage2_pgd(struct kvm *kvm);
+void kvm_free_stage2_pgd(struct kvm *kvm);
+int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
+			  phys_addr_t pa, unsigned long size);
+
+int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run);
+
+void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
+
+phys_addr_t kvm_mmu_get_httbr(void);
+phys_addr_t kvm_mmu_get_boot_httbr(void);
+phys_addr_t kvm_get_idmap_vector(void);
+int kvm_mmu_init(void);
+void kvm_clear_hyp_idmap(void);
+
+#define	kvm_set_pte(ptep, pte)		set_pte(ptep, pte)
+
+static inline bool kvm_is_write_fault(unsigned long esr)
+{
+	unsigned long esr_ec = esr >> ESR_EL2_EC_SHIFT;
+
+	if (esr_ec == ESR_EL2_EC_IABT)
+		return false;
+
+	if ((esr & ESR_EL2_ISV) && !(esr & ESR_EL2_WNR))
+		return false;
+
+	return true;
+}
+
+static inline void kvm_clean_dcache_area(void *addr, size_t size) {}
+static inline void kvm_clean_pgd(pgd_t *pgd) {}
+static inline void kvm_clean_pmd_entry(pmd_t *pmd) {}
+static inline void kvm_clean_pte(pte_t *pte) {}
+static inline void kvm_clean_pte_entry(pte_t *pte) {}
+
+static inline void kvm_set_s2pte_writable(pte_t *pte)
+{
+	pte_val(*pte) |= PTE_S2_RDWR;
+}
+
+struct kvm;
+
+static inline void coherent_icache_guest_page(struct kvm *kvm, gfn_t gfn)
+{
+	if (!icache_is_aliasing()) {		/* PIPT */
+		unsigned long hva = gfn_to_hva(kvm, gfn);
+		flush_icache_range(hva, hva + PAGE_SIZE);
+	} else if (!icache_is_aivivt()) {	/* non ASID-tagged VIVT */
+		/* any kind of VIPT cache */
+		__flush_icache_all();
+	}
+}
+
+#define kvm_flush_dcache_to_poc(a,l)	__flush_dcache_area((a), (l))
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARM64_KVM_MMU_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_psci.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_psci.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/kvm_psci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/kvm_psci.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM64_KVM_PSCI_H__
+#define __ARM64_KVM_PSCI_H__
+
+bool kvm_psci_call(struct kvm_vcpu *vcpu);
+
+#endif /* __ARM64_KVM_PSCI_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/memory.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/memory.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/memory.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/memory.h	2013-08-25 20:43:22.000000000 -0400
@@ -90,6 +90,12 @@
 #define MT_NORMAL_NC		3
 #define MT_NORMAL		4
 
+/*
+ * Memory types for Stage-2 translation
+ */
+#define MT_S2_NORMAL		0xf
+#define MT_S2_DEVICE_nGnRE	0x1
+
 #ifndef __ASSEMBLY__
 
 extern phys_addr_t		memstart_addr;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/mmu_context.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/mmu_context.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/mmu_context.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/mmu_context.h	2013-08-25 20:43:22.000000000 -0400
@@ -151,12 +151,6 @@ switch_mm(struct mm_struct *prev, struct
 {
 	unsigned int cpu = smp_processor_id();
 
-#ifdef CONFIG_SMP
-	/* check for possible thread migration */
-	if (!cpumask_empty(mm_cpumask(next)) &&
-	    !cpumask_test_cpu(cpu, mm_cpumask(next)))
-		__flush_icache_all();
-#endif
 	if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next)
 		check_and_switch_context(next, tsk);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,8 +25,8 @@
  * Software defined PTE bits definition.
  */
 #define PTE_VALID		(_AT(pteval_t, 1) << 0)
-#define PTE_PROT_NONE		(_AT(pteval_t, 1) << 1)	/* only when !PTE_VALID */
-#define PTE_FILE		(_AT(pteval_t, 1) << 2)	/* only when !pte_present() */
+#define PTE_PROT_NONE		(_AT(pteval_t, 1) << 2)	/* only when !PTE_VALID */
+#define PTE_FILE		(_AT(pteval_t, 1) << 3)	/* only when !pte_present() */
 #define PTE_DIRTY		(_AT(pteval_t, 1) << 55)
 #define PTE_SPECIAL		(_AT(pteval_t, 1) << 56)
 
@@ -66,7 +66,7 @@ extern pgprot_t pgprot_default;
 
 #define _MOD_PROT(p, b)		__pgprot_modify(p, 0, b)
 
-#define PAGE_NONE		__pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE)
+#define PAGE_NONE		__pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN)
 #define PAGE_SHARED		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
 #define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
 #define PAGE_COPY		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
@@ -76,7 +76,13 @@ extern pgprot_t pgprot_default;
 #define PAGE_KERNEL		_MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
 #define PAGE_KERNEL_EXEC	_MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
 
-#define __PAGE_NONE		__pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE)
+#define PAGE_HYP		_MOD_PROT(pgprot_default, PTE_HYP)
+#define PAGE_HYP_DEVICE		__pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
+
+#define PAGE_S2			__pgprot_modify(pgprot_default, PTE_S2_MEMATTR_MASK, PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
+#define PAGE_S2_DEVICE		__pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN)
+
+#define __PAGE_NONE		__pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN)
 #define __PAGE_SHARED		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
 #define __PAGE_SHARED_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
 #define __PAGE_COPY		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
@@ -119,7 +125,7 @@ extern struct page *empty_zero_page;
 #define pte_none(pte)		(!pte_val(pte))
 #define pte_clear(mm,addr,ptep)	set_pte(ptep, __pte(0))
 #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
-#define pte_offset_kernel(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
+#define pte_offset_kernel(dir,addr)	(pmd_page_vaddr(*(dir)) + pte_index(addr))
 
 #define pte_offset_map(dir,addr)	pte_offset_kernel((dir), (addr))
 #define pte_offset_map_nested(dir,addr)	pte_offset_kernel((dir), (addr))
@@ -173,12 +179,76 @@ static inline void set_pte_at(struct mm_
 /*
  * Huge pte definitions.
  */
-#define pte_huge(pte)		((pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_HUGEPAGE)
-#define pte_mkhuge(pte)		(__pte((pte_val(pte) & ~PTE_TYPE_MASK) | PTE_TYPE_HUGEPAGE))
+#define pte_huge(pte)		(!(pte_val(pte) & PTE_TABLE_BIT))
+#define pte_mkhuge(pte)		(__pte(pte_val(pte) & ~PTE_TABLE_BIT))
+
+/*
+ * Hugetlb definitions.
+ */
+#define HUGE_MAX_HSTATE		2
+#define HPAGE_SHIFT		PMD_SHIFT
+#define HPAGE_SIZE		(_AC(1, UL) << HPAGE_SHIFT)
+#define HPAGE_MASK		(~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
 
 #define __HAVE_ARCH_PTE_SPECIAL
 
 /*
+ * Software PMD bits for THP
+ */
+
+#define PMD_SECT_DIRTY		(_AT(pmdval_t, 1) << 55)
+#define PMD_SECT_SPLITTING	(_AT(pmdval_t, 1) << 57)
+
+/*
+ * THP definitions.
+ */
+#define pmd_young(pmd)		(pmd_val(pmd) & PMD_SECT_AF)
+
+#define __HAVE_ARCH_PMD_WRITE
+#define pmd_write(pmd)		(!(pmd_val(pmd) & PMD_SECT_RDONLY))
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define pmd_trans_huge(pmd)	(pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
+#define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
+#endif
+
+#define PMD_BIT_FUNC(fn,op) \
+static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
+
+PMD_BIT_FUNC(wrprotect,	|= PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkold,	&= ~PMD_SECT_AF);
+PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
+PMD_BIT_FUNC(mkwrite,   &= ~PMD_SECT_RDONLY);
+PMD_BIT_FUNC(mkdirty,   |= PMD_SECT_DIRTY);
+PMD_BIT_FUNC(mkyoung,   |= PMD_SECT_AF);
+PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
+
+#define pmd_mkhuge(pmd)		(__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
+
+#define pmd_pfn(pmd)		(((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
+#define pfn_pmd(pfn,prot)	(__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+#define mk_pmd(page,prot)	pfn_pmd(page_to_pfn(page),prot)
+
+#define pmd_page(pmd)           pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+	const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN |
+			      PMD_SECT_RDONLY | PMD_SECT_PROT_NONE |
+			      PMD_SECT_VALID;
+	pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
+	return pmd;
+}
+
+#define set_pmd_at(mm, addr, pmdp, pmd)	set_pmd(pmdp, pmd)
+
+static inline int has_transparent_hugepage(void)
+{
+	return 1;
+}
+
+/*
  * Mark the prot value as uncacheable and unbufferable.
  */
 #define pgprot_noncached(prot) \
@@ -197,6 +267,12 @@ extern pgprot_t phys_mem_access_prot(str
 
 #define pmd_bad(pmd)		(!(pmd_val(pmd) & 2))
 
+#define pmd_table(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
+				 PMD_TYPE_TABLE)
+#define pmd_sect(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
+				 PMD_TYPE_SECT)
+
+
 static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 {
 	*pmdp = pmd;
@@ -263,7 +339,7 @@ static inline pmd_t *pmd_offset(pud_t *p
 #endif
 
 /* Find an entry in the third-level page table.. */
-#define __pte_index(addr)	(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_index(addr)		(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
@@ -281,12 +357,12 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
 
 /*
  * Encode and decode a swap entry:
- *	bits 0-1:	present (must be zero)
- *	bit  2:		PTE_FILE
- *	bits 3-8:	swap type
+ *	bits 0, 2:	present (must both be zero)
+ *	bit  3:		PTE_FILE
+ *	bits 4-8:	swap type
  *	bits 9-63:	swap offset
  */
-#define __SWP_TYPE_SHIFT	3
+#define __SWP_TYPE_SHIFT	4
 #define __SWP_TYPE_BITS		6
 #define __SWP_TYPE_MASK		((1 << __SWP_TYPE_BITS) - 1)
 #define __SWP_OFFSET_SHIFT	(__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
@@ -306,27 +382,20 @@ extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
 
 /*
  * Encode and decode a file entry:
- *	bits 0-1:	present (must be zero)
- *	bit  2:		PTE_FILE
- *	bits 3-63:	file offset / PAGE_SIZE
+ *	bits 0, 2:	present (must both be zero)
+ *	bit  3:		PTE_FILE
+ *	bits 4-63:	file offset / PAGE_SIZE
  */
 #define pte_file(pte)		(pte_val(pte) & PTE_FILE)
-#define pte_to_pgoff(x)		(pte_val(x) >> 3)
-#define pgoff_to_pte(x)		__pte(((x) << 3) | PTE_FILE)
+#define pte_to_pgoff(x)		(pte_val(x) >> 4)
+#define pgoff_to_pte(x)		__pte(((x) << 4) | PTE_FILE)
 
-#define PTE_FILE_MAX_BITS	61
+#define PTE_FILE_MAX_BITS	60
 
 extern int kern_addr_valid(unsigned long addr);
 
 #include <asm-generic/pgtable.h>
 
-/*
- * remap a physical page `pfn' of size `size' with page protection `prot'
- * into virtual address `from'
- */
-#define io_remap_pfn_range(vma,from,pfn,size,prot) \
-		remap_pfn_range(vma, from, pfn, size, prot)
-
 #define pgtable_cache_init() do { } while (0)
 
 #endif /* !__ASSEMBLY__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/pgtable-hwdef.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/pgtable-hwdef.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/pgtable-hwdef.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/pgtable-hwdef.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,16 +25,27 @@
 /*
  * Hardware page table definitions.
  *
+ * Level 1 descriptor (PUD).
+ */
+
+#define PUD_TABLE_BIT		(_AT(pgdval_t, 1) << 1)
+
+/*
  * Level 2 descriptor (PMD).
  */
 #define PMD_TYPE_MASK		(_AT(pmdval_t, 3) << 0)
 #define PMD_TYPE_FAULT		(_AT(pmdval_t, 0) << 0)
 #define PMD_TYPE_TABLE		(_AT(pmdval_t, 3) << 0)
 #define PMD_TYPE_SECT		(_AT(pmdval_t, 1) << 0)
+#define PMD_TABLE_BIT		(_AT(pmdval_t, 1) << 1)
 
 /*
  * Section
  */
+#define PMD_SECT_VALID		(_AT(pmdval_t, 1) << 0)
+#define PMD_SECT_PROT_NONE	(_AT(pmdval_t, 1) << 2)
+#define PMD_SECT_USER		(_AT(pmdval_t, 1) << 6)		/* AP[1] */
+#define PMD_SECT_RDONLY		(_AT(pmdval_t, 1) << 7)		/* AP[2] */
 #define PMD_SECT_S		(_AT(pmdval_t, 3) << 8)
 #define PMD_SECT_AF		(_AT(pmdval_t, 1) << 10)
 #define PMD_SECT_NG		(_AT(pmdval_t, 1) << 11)
@@ -53,6 +64,7 @@
 #define PTE_TYPE_MASK		(_AT(pteval_t, 3) << 0)
 #define PTE_TYPE_FAULT		(_AT(pteval_t, 0) << 0)
 #define PTE_TYPE_PAGE		(_AT(pteval_t, 3) << 0)
+#define PTE_TABLE_BIT		(_AT(pteval_t, 1) << 1)
 #define PTE_USER		(_AT(pteval_t, 1) << 6)		/* AP[1] */
 #define PTE_RDONLY		(_AT(pteval_t, 1) << 7)		/* AP[2] */
 #define PTE_SHARED		(_AT(pteval_t, 3) << 8)		/* SH[1:0], inner shareable */
@@ -68,6 +80,24 @@
 #define PTE_ATTRINDX_MASK	(_AT(pteval_t, 7) << 2)
 
 /*
+ * 2nd stage PTE definitions
+ */
+#define PTE_S2_RDONLY		(_AT(pteval_t, 1) << 6)   /* HAP[2:1] */
+#define PTE_S2_RDWR		(_AT(pteval_t, 3) << 6)   /* HAP[2:1] */
+
+/*
+ * Memory Attribute override for Stage-2 (MemAttr[3:0])
+ */
+#define PTE_S2_MEMATTR(t)	(_AT(pteval_t, (t)) << 2)
+#define PTE_S2_MEMATTR_MASK	(_AT(pteval_t, 0xf) << 2)
+
+/*
+ * EL2/HYP PTE/PMD definitions
+ */
+#define PMD_HYP			PMD_SECT_USER
+#define PTE_HYP			PTE_USER
+
+/*
  * 40-bit physical address supported.
  */
 #define PHYS_MASK_SHIFT		(40)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/ptrace.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/ptrace.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/ptrace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/ptrace.h	2013-08-25 20:43:22.000000000 -0400
@@ -171,7 +171,5 @@ extern unsigned long profile_pc(struct p
 #define profile_pc(regs) instruction_pointer(regs)
 #endif
 
-extern int aarch32_break_trap(struct pt_regs *regs);
-
 #endif /* __ASSEMBLY__ */
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/spinlock.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/spinlock.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/spinlock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/spinlock.h	2013-08-25 20:43:22.000000000 -0400
@@ -59,9 +59,10 @@ static inline int arch_spin_trylock(arch
 	unsigned int tmp;
 
 	asm volatile(
-	"	ldaxr	%w0, %1\n"
+	"2:	ldaxr	%w0, %1\n"
 	"	cbnz	%w0, 1f\n"
 	"	stxr	%w0, %w2, %1\n"
+	"	cbnz	%w0, 2b\n"
 	"1:\n"
 	: "=&r" (tmp), "+Q" (lock->lock)
 	: "r" (1)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/sync_bitops.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/sync_bitops.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/sync_bitops.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/sync_bitops.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,26 @@
+#ifndef __ASM_SYNC_BITOPS_H__
+#define __ASM_SYNC_BITOPS_H__
+
+#include <asm/bitops.h>
+#include <asm/cmpxchg.h>
+
+/* sync_bitops functions are equivalent to the SMP implementation of the
+ * original functions, independently from CONFIG_SMP being defined.
+ *
+ * We need them because _set_bit etc are not SMP safe if !CONFIG_SMP. But
+ * under Xen you might be communicating with a completely external entity
+ * who might be on another CPU (e.g. two uniprocessor guests communicating
+ * via event channels and grant tables). So we need a variant of the bit
+ * ops which are SMP safe even on a UP kernel.
+ */
+
+#define sync_set_bit(nr, p)            set_bit(nr, p)
+#define sync_clear_bit(nr, p)          clear_bit(nr, p)
+#define sync_change_bit(nr, p)         change_bit(nr, p)
+#define sync_test_and_set_bit(nr, p)   test_and_set_bit(nr, p)
+#define sync_test_and_clear_bit(nr, p) test_and_clear_bit(nr, p)
+#define sync_test_and_change_bit(nr, p)        test_and_change_bit(nr, p)
+#define sync_test_bit(nr, addr)                test_bit(nr, addr)
+#define sync_cmpxchg                   cmpxchg
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/system_misc.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/system_misc.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/system_misc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/system_misc.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/compiler.h>
 #include <linux/linkage.h>
 #include <linux/irqflags.h>
+#include <linux/reboot.h>
 
 struct pt_regs;
 
@@ -41,7 +42,7 @@ extern void show_pte(struct mm_struct *m
 extern void __show_regs(struct pt_regs *);
 
 void soft_restart(unsigned long);
-extern void (*arm_pm_restart)(char str, const char *cmd);
+extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
 
 #define UDBG_UNDEFINED	(1 << 0)
 #define UDBG_SYSCALL	(1 << 1)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/thread_info.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/thread_info.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/thread_info.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/thread_info.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,10 +24,10 @@
 #include <linux/compiler.h>
 
 #ifndef CONFIG_ARM64_64K_PAGES
-#define THREAD_SIZE_ORDER	1
+#define THREAD_SIZE_ORDER	2
 #endif
 
-#define THREAD_SIZE		8192
+#define THREAD_SIZE		16384
 #define THREAD_START_SP		(THREAD_SIZE - 16)
 
 #ifndef __ASSEMBLY__
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/timex.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/timex.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/timex.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/timex.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,14 +16,14 @@
 #ifndef __ASM_TIMEX_H
 #define __ASM_TIMEX_H
 
+#include <asm/arch_timer.h>
+
 /*
  * Use the current timer as a cycle counter since this is what we use for
  * the delay loop.
  */
-#define get_cycles()	({ cycles_t c; read_current_timer(&c); c; })
+#define get_cycles()	arch_counter_get_cntvct()
 
 #include <asm-generic/timex.h>
 
-#define ARCH_HAS_READ_CURRENT_TIMER
-
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/tlbflush.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/tlbflush.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/tlbflush.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/tlbflush.h	2013-08-25 20:43:22.000000000 -0400
@@ -117,6 +117,8 @@ static inline void update_mmu_cache(stru
 	dsb();
 }
 
+#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
+
 #endif
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/tlb.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/tlb.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/tlb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/tlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,7 @@ struct mmu_gather {
 	struct mm_struct	*mm;
 	unsigned int		fullmm;
 	struct vm_area_struct	*vma;
+	unsigned long		start, end;
 	unsigned long		range_start;
 	unsigned long		range_end;
 	unsigned int		nr;
@@ -97,10 +98,12 @@ static inline void tlb_flush_mmu(struct
 }
 
 static inline void
-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
 {
 	tlb->mm = mm;
-	tlb->fullmm = fullmm;
+	tlb->fullmm = !(start | (end+1));
+	tlb->start = start;
+	tlb->end = end;
 	tlb->vma = NULL;
 	tlb->max = ARRAY_SIZE(tlb->local);
 	tlb->pages = tlb->local;
@@ -187,4 +190,10 @@ static inline void __pmd_free_tlb(struct
 
 #define tlb_migrate_finish(mm)		do { } while (0)
 
+static inline void
+tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr)
+{
+	tlb_add_flush(tlb, addr);
+}
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/uaccess.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/uaccess.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/uaccess.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/uaccess.h	2013-08-25 20:43:22.000000000 -0400
@@ -166,7 +166,7 @@ do {									\
 
 #define get_user(x, ptr)						\
 ({									\
-	might_sleep();							\
+	might_fault();							\
 	access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) ?			\
 		__get_user((x), (ptr)) :				\
 		((x) = 0, -EFAULT);					\
@@ -227,7 +227,7 @@ do {									\
 
 #define put_user(x, ptr)						\
 ({									\
-	might_sleep();							\
+	might_fault();							\
 	access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) ?		\
 		__put_user((x), (ptr)) :				\
 		-EFAULT;						\
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/virt.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/virt.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/virt.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/virt.h	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 #define BOOT_CPU_MODE_EL2	(0x0e12b007)
 
 #ifndef __ASSEMBLY__
+#include <asm/cacheflush.h>
 
 /*
  * __boot_cpu_mode records what mode CPUs were booted in.
@@ -36,9 +37,20 @@ extern u32 __boot_cpu_mode[2];
 void __hyp_set_vectors(phys_addr_t phys_vector_base);
 phys_addr_t __hyp_get_vectors(void);
 
+static inline void sync_boot_mode(void)
+{
+	/*
+	 * As secondaries write to __boot_cpu_mode with caches disabled, we
+	 * must flush the corresponding cache entries to ensure the visibility
+	 * of their writes.
+	 */
+	__flush_dcache_area(__boot_cpu_mode, sizeof(__boot_cpu_mode));
+}
+
 /* Reports the availability of HYP mode */
 static inline bool is_hyp_mode_available(void)
 {
+	sync_boot_mode();
 	return (__boot_cpu_mode[0] == BOOT_CPU_MODE_EL2 &&
 		__boot_cpu_mode[1] == BOOT_CPU_MODE_EL2);
 }
@@ -46,6 +58,7 @@ static inline bool is_hyp_mode_available
 /* Check if the bootloader has booted CPUs in different modes */
 static inline bool is_hyp_mode_mismatched(void)
 {
+	sync_boot_mode();
 	return __boot_cpu_mode[0] != __boot_cpu_mode[1];
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/xen/events.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/events.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/xen/events.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/events.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,21 @@
+#ifndef _ASM_ARM64_XEN_EVENTS_H
+#define _ASM_ARM64_XEN_EVENTS_H
+
+#include <asm/ptrace.h>
+#include <asm/atomic.h>
+
+enum ipi_vector {
+	XEN_PLACEHOLDER_VECTOR,
+
+	/* Xen IPIs go here */
+	XEN_NR_IPIS,
+};
+
+static inline int xen_irqs_disabled(struct pt_regs *regs)
+{
+	return raw_irqs_disabled_flags((unsigned long) regs->pstate);
+}
+
+#define xchg_xen_ulong(ptr, val) xchg((ptr), (val))
+
+#endif /* _ASM_ARM64_XEN_EVENTS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/xen/hypercall.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/hypercall.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/xen/hypercall.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/hypercall.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+#include <../../arm/include/asm/xen/hypercall.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/xen/hypervisor.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/hypervisor.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/xen/hypervisor.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/hypervisor.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+#include <../../arm/include/asm/xen/hypervisor.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/xen/interface.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/interface.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/xen/interface.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/interface.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+#include <../../arm/include/asm/xen/interface.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/asm/xen/page.h linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/page.h
--- linux-libre-3.10-gnu/arch/arm64/include/asm/xen/page.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/asm/xen/page.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+#include <../../arm/include/asm/xen/page.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/include/uapi/asm/kvm.h linux-libre-3.11-rc7-gnu/arch/arm64/include/uapi/asm/kvm.h
--- linux-libre-3.10-gnu/arch/arm64/include/uapi/asm/kvm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/include/uapi/asm/kvm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/include/uapi/asm/kvm.h:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM_KVM_H__
+#define __ARM_KVM_H__
+
+#define KVM_SPSR_EL1	0
+#define KVM_SPSR_SVC	KVM_SPSR_EL1
+#define KVM_SPSR_ABT	1
+#define KVM_SPSR_UND	2
+#define KVM_SPSR_IRQ	3
+#define KVM_SPSR_FIQ	4
+#define KVM_NR_SPSR	5
+
+#ifndef __ASSEMBLY__
+#include <asm/types.h>
+#include <asm/ptrace.h>
+
+#define __KVM_HAVE_GUEST_DEBUG
+#define __KVM_HAVE_IRQ_LINE
+
+#define KVM_REG_SIZE(id)						\
+	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+
+struct kvm_regs {
+	struct user_pt_regs regs;	/* sp = sp_el0 */
+
+	__u64	sp_el1;
+	__u64	elr_el1;
+
+	__u64	spsr[KVM_NR_SPSR];
+
+	struct user_fpsimd_state fp_regs;
+};
+
+/* Supported Processor Types */
+#define KVM_ARM_TARGET_AEM_V8		0
+#define KVM_ARM_TARGET_FOUNDATION_V8	1
+#define KVM_ARM_TARGET_CORTEX_A57	2
+
+#define KVM_ARM_NUM_TARGETS		3
+
+/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
+#define KVM_ARM_DEVICE_TYPE_SHIFT	0
+#define KVM_ARM_DEVICE_TYPE_MASK	(0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_ID_SHIFT		16
+#define KVM_ARM_DEVICE_ID_MASK		(0xffff << KVM_ARM_DEVICE_ID_SHIFT)
+
+/* Supported device IDs */
+#define KVM_ARM_DEVICE_VGIC_V2		0
+
+/* Supported VGIC address types  */
+#define KVM_VGIC_V2_ADDR_TYPE_DIST	0
+#define KVM_VGIC_V2_ADDR_TYPE_CPU	1
+
+#define KVM_VGIC_V2_DIST_SIZE		0x1000
+#define KVM_VGIC_V2_CPU_SIZE		0x2000
+
+#define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
+#define KVM_ARM_VCPU_EL1_32BIT		1 /* CPU running a 32bit VM */
+
+struct kvm_vcpu_init {
+	__u32 target;
+	__u32 features[7];
+};
+
+struct kvm_sregs {
+};
+
+struct kvm_fpu {
+};
+
+struct kvm_guest_debug_arch {
+};
+
+struct kvm_debug_exit_arch {
+};
+
+struct kvm_sync_regs {
+};
+
+struct kvm_arch_memory_slot {
+};
+
+/* If you need to interpret the index values, here is the key: */
+#define KVM_REG_ARM_COPROC_MASK		0x000000000FFF0000
+#define KVM_REG_ARM_COPROC_SHIFT	16
+
+/* Normal registers are mapped as coprocessor 16. */
+#define KVM_REG_ARM_CORE		(0x0010 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_CORE_REG(name)	(offsetof(struct kvm_regs, name) / sizeof(__u32))
+
+/* Some registers need more space to represent values. */
+#define KVM_REG_ARM_DEMUX		(0x0011 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_DEMUX_ID_MASK	0x000000000000FF00
+#define KVM_REG_ARM_DEMUX_ID_SHIFT	8
+#define KVM_REG_ARM_DEMUX_ID_CCSIDR	(0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
+#define KVM_REG_ARM_DEMUX_VAL_MASK	0x00000000000000FF
+#define KVM_REG_ARM_DEMUX_VAL_SHIFT	0
+
+/* AArch64 system registers */
+#define KVM_REG_ARM64_SYSREG		(0x0013 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM64_SYSREG_OP0_MASK	0x000000000000c000
+#define KVM_REG_ARM64_SYSREG_OP0_SHIFT	14
+#define KVM_REG_ARM64_SYSREG_OP1_MASK	0x0000000000003800
+#define KVM_REG_ARM64_SYSREG_OP1_SHIFT	11
+#define KVM_REG_ARM64_SYSREG_CRN_MASK	0x0000000000000780
+#define KVM_REG_ARM64_SYSREG_CRN_SHIFT	7
+#define KVM_REG_ARM64_SYSREG_CRM_MASK	0x0000000000000078
+#define KVM_REG_ARM64_SYSREG_CRM_SHIFT	3
+#define KVM_REG_ARM64_SYSREG_OP2_MASK	0x0000000000000007
+#define KVM_REG_ARM64_SYSREG_OP2_SHIFT	0
+
+/* KVM_IRQ_LINE irq field index values */
+#define KVM_ARM_IRQ_TYPE_SHIFT		24
+#define KVM_ARM_IRQ_TYPE_MASK		0xff
+#define KVM_ARM_IRQ_VCPU_SHIFT		16
+#define KVM_ARM_IRQ_VCPU_MASK		0xff
+#define KVM_ARM_IRQ_NUM_SHIFT		0
+#define KVM_ARM_IRQ_NUM_MASK		0xffff
+
+/* irq_type field */
+#define KVM_ARM_IRQ_TYPE_CPU		0
+#define KVM_ARM_IRQ_TYPE_SPI		1
+#define KVM_ARM_IRQ_TYPE_PPI		2
+
+/* out-of-kernel GIC cpu interrupt injection irq_number field */
+#define KVM_ARM_IRQ_CPU_IRQ		0
+#define KVM_ARM_IRQ_CPU_FIQ		1
+
+/* Highest supported SPI, from VGIC_NR_IRQS */
+#define KVM_ARM_IRQ_GIC_MAX		127
+
+/* PSCI interface */
+#define KVM_PSCI_FN_BASE		0x95c1ba5e
+#define KVM_PSCI_FN(n)			(KVM_PSCI_FN_BASE + (n))
+
+#define KVM_PSCI_FN_CPU_SUSPEND		KVM_PSCI_FN(0)
+#define KVM_PSCI_FN_CPU_OFF		KVM_PSCI_FN(1)
+#define KVM_PSCI_FN_CPU_ON		KVM_PSCI_FN(2)
+#define KVM_PSCI_FN_MIGRATE		KVM_PSCI_FN(3)
+
+#define KVM_PSCI_RET_SUCCESS		0
+#define KVM_PSCI_RET_NI			((unsigned long)-1)
+#define KVM_PSCI_RET_INVAL		((unsigned long)-2)
+#define KVM_PSCI_RET_DENIED		((unsigned long)-3)
+
+#endif
+
+#endif /* __ARM_KVM_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/Kconfig linux-libre-3.11-rc7-gnu/arch/arm64/Kconfig
--- linux-libre-3.10-gnu/arch/arm64/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -7,6 +7,7 @@ config ARM64
 	select ARM_AMBA
 	select ARM_ARCH_TIMER
 	select ARM_GIC
+	select BUILDTIME_EXTABLE_SORT
 	select CLONE_BACKWARDS
 	select COMMON_CLK
 	select GENERIC_CLOCKEVENTS
@@ -111,6 +112,11 @@ config ARCH_VEXPRESS
 	  This enables support for the ARMv8 software model (Versatile
 	  Express).
 
+config ARCH_XGENE
+	bool "AppliedMicro X-Gene SOC Family"
+	help
+	  This enables support for AppliedMicro X-Gene SOC Family
+
 endmenu
 
 menu "Bus support"
@@ -148,6 +154,8 @@ config NR_CPUS
 	int "Maximum number of CPUs (2-32)"
 	range 2 32
 	depends on SMP
+	# These have to remain sorted largest to smallest
+	default "8" if ARCH_XGENE
 	default "4"
 
 source kernel/Kconfig.preempt
@@ -180,8 +188,35 @@ config HW_PERF_EVENTS
 	  Enable hardware performance counter support for perf events. If
 	  disabled, perf events will use software events only.
 
+config SYS_SUPPORTS_HUGETLBFS
+	def_bool y
+
+config ARCH_WANT_GENERAL_HUGETLB
+	def_bool y
+
+config ARCH_WANT_HUGE_PMD_SHARE
+	def_bool y if !ARM64_64K_PAGES
+
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
+	def_bool y
+
 source "mm/Kconfig"
 
+config XEN_DOM0
+	def_bool y
+	depends on XEN
+
+config XEN
+	bool "Xen guest support on ARM64 (EXPERIMENTAL)"
+	depends on ARM64 && OF
+	help
+	  Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64.
+
+config FORCE_MAX_ZONEORDER
+	int
+	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
+	default "11"
+
 endmenu
 
 menu "Boot options"
@@ -235,6 +270,8 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
+source "arch/arm64/kvm/Kconfig"
+
 source "arch/arm64/Kconfig.debug"
 
 source "security/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/asm-offsets.c linux-libre-3.11-rc7-gnu/arch/arm64/kernel/asm-offsets.c
--- linux-libre-3.10-gnu/arch/arm64/kernel/asm-offsets.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/asm-offsets.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
+#include <linux/kvm_host.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
 #include <asm/cputable.h>
@@ -104,5 +105,38 @@ int main(void)
   BLANK();
   DEFINE(TZ_MINWEST,		offsetof(struct timezone, tz_minuteswest));
   DEFINE(TZ_DSTTIME,		offsetof(struct timezone, tz_dsttime));
+  BLANK();
+#ifdef CONFIG_KVM_ARM_HOST
+  DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
+  DEFINE(CPU_GP_REGS,		offsetof(struct kvm_cpu_context, gp_regs));
+  DEFINE(CPU_USER_PT_REGS,	offsetof(struct kvm_regs, regs));
+  DEFINE(CPU_FP_REGS,		offsetof(struct kvm_regs, fp_regs));
+  DEFINE(CPU_SP_EL1,		offsetof(struct kvm_regs, sp_el1));
+  DEFINE(CPU_ELR_EL1,		offsetof(struct kvm_regs, elr_el1));
+  DEFINE(CPU_SPSR,		offsetof(struct kvm_regs, spsr));
+  DEFINE(CPU_SYSREGS,		offsetof(struct kvm_cpu_context, sys_regs));
+  DEFINE(VCPU_ESR_EL2,		offsetof(struct kvm_vcpu, arch.fault.esr_el2));
+  DEFINE(VCPU_FAR_EL2,		offsetof(struct kvm_vcpu, arch.fault.far_el2));
+  DEFINE(VCPU_HPFAR_EL2,	offsetof(struct kvm_vcpu, arch.fault.hpfar_el2));
+  DEFINE(VCPU_HCR_EL2,		offsetof(struct kvm_vcpu, arch.hcr_el2));
+  DEFINE(VCPU_IRQ_LINES,	offsetof(struct kvm_vcpu, arch.irq_lines));
+  DEFINE(VCPU_HOST_CONTEXT,	offsetof(struct kvm_vcpu, arch.host_cpu_context));
+  DEFINE(VCPU_TIMER_CNTV_CTL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
+  DEFINE(VCPU_TIMER_CNTV_CVAL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval));
+  DEFINE(KVM_TIMER_CNTVOFF,	offsetof(struct kvm, arch.timer.cntvoff));
+  DEFINE(KVM_TIMER_ENABLED,	offsetof(struct kvm, arch.timer.enabled));
+  DEFINE(VCPU_KVM,		offsetof(struct kvm_vcpu, kvm));
+  DEFINE(VCPU_VGIC_CPU,		offsetof(struct kvm_vcpu, arch.vgic_cpu));
+  DEFINE(VGIC_CPU_HCR,		offsetof(struct vgic_cpu, vgic_hcr));
+  DEFINE(VGIC_CPU_VMCR,		offsetof(struct vgic_cpu, vgic_vmcr));
+  DEFINE(VGIC_CPU_MISR,		offsetof(struct vgic_cpu, vgic_misr));
+  DEFINE(VGIC_CPU_EISR,		offsetof(struct vgic_cpu, vgic_eisr));
+  DEFINE(VGIC_CPU_ELRSR,	offsetof(struct vgic_cpu, vgic_elrsr));
+  DEFINE(VGIC_CPU_APR,		offsetof(struct vgic_cpu, vgic_apr));
+  DEFINE(VGIC_CPU_LR,		offsetof(struct vgic_cpu, vgic_lr));
+  DEFINE(VGIC_CPU_NR_LR,	offsetof(struct vgic_cpu, nr_lr));
+  DEFINE(KVM_VTTBR,		offsetof(struct kvm, arch.vttbr));
+  DEFINE(KVM_VGIC_VCTRL,	offsetof(struct kvm, arch.vgic.vctrl_base));
+#endif
   return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/debug-monitors.c linux-libre-3.11-rc7-gnu/arch/arm64/kernel/debug-monitors.c
--- linux-libre-3.10-gnu/arch/arm64/kernel/debug-monitors.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/debug-monitors.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/ptrace.h>
 #include <linux/stat.h>
+#include <linux/uaccess.h>
 
 #include <asm/debug-monitors.h>
 #include <asm/local.h>
@@ -140,7 +141,7 @@ static void clear_os_lock(void *unused)
 	isb();
 }
 
-static int __cpuinit os_lock_notify(struct notifier_block *self,
+static int os_lock_notify(struct notifier_block *self,
 				    unsigned long action, void *data)
 {
 	int cpu = (unsigned long)data;
@@ -149,11 +150,11 @@ static int __cpuinit os_lock_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata os_lock_nb = {
+static struct notifier_block os_lock_nb = {
 	.notifier_call = os_lock_notify,
 };
 
-static int __cpuinit debug_monitors_init(void)
+static int debug_monitors_init(void)
 {
 	/* Clear the OS lock. */
 	smp_call_function(clear_os_lock, NULL, 1);
@@ -226,13 +227,74 @@ static int single_step_handler(unsigned
 	return 0;
 }
 
-static int __init single_step_init(void)
+static int brk_handler(unsigned long addr, unsigned int esr,
+		       struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	if (!user_mode(regs))
+		return -EFAULT;
+
+	info = (siginfo_t) {
+		.si_signo = SIGTRAP,
+		.si_errno = 0,
+		.si_code  = TRAP_BRKPT,
+		.si_addr  = (void __user *)instruction_pointer(regs),
+	};
+
+	force_sig_info(SIGTRAP, &info, current);
+	return 0;
+}
+
+int aarch32_break_handler(struct pt_regs *regs)
+{
+	siginfo_t info;
+	unsigned int instr;
+	bool bp = false;
+	void __user *pc = (void __user *)instruction_pointer(regs);
+
+	if (!compat_user_mode(regs))
+		return -EFAULT;
+
+	if (compat_thumb_mode(regs)) {
+		/* get 16-bit Thumb instruction */
+		get_user(instr, (u16 __user *)pc);
+		if (instr == AARCH32_BREAK_THUMB2_LO) {
+			/* get second half of 32-bit Thumb-2 instruction */
+			get_user(instr, (u16 __user *)(pc + 2));
+			bp = instr == AARCH32_BREAK_THUMB2_HI;
+		} else {
+			bp = instr == AARCH32_BREAK_THUMB;
+		}
+	} else {
+		/* 32-bit ARM instruction */
+		get_user(instr, (u32 __user *)pc);
+		bp = (instr & ~0xf0000000) == AARCH32_BREAK_ARM;
+	}
+
+	if (!bp)
+		return -EFAULT;
+
+	info = (siginfo_t) {
+		.si_signo = SIGTRAP,
+		.si_errno = 0,
+		.si_code  = TRAP_BRKPT,
+		.si_addr  = pc,
+	};
+
+	force_sig_info(SIGTRAP, &info, current);
+	return 0;
+}
+
+static int __init debug_traps_init(void)
 {
 	hook_debug_fault_code(DBG_ESR_EVT_HWSS, single_step_handler, SIGTRAP,
 			      TRAP_HWBKPT, "single-step handler");
+	hook_debug_fault_code(DBG_ESR_EVT_BRK, brk_handler, SIGTRAP,
+			      TRAP_BRKPT, "ptrace BRK handler");
 	return 0;
 }
-arch_initcall(single_step_init);
+arch_initcall(debug_traps_init);
 
 /* Re-enable single step for syscall restarting. */
 void user_rewind_single_step(struct task_struct *task)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/entry.S linux-libre-3.11-rc7-gnu/arch/arm64/kernel/entry.S
--- linux-libre-3.10-gnu/arch/arm64/kernel/entry.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/entry.S	2013-08-25 20:43:22.000000000 -0400
@@ -121,7 +121,7 @@
 
 	.macro	get_thread_info, rd
 	mov	\rd, sp
-	and	\rd, \rd, #~((1 << 13) - 1)	// top of 8K stack
+	and	\rd, \rd, #~(THREAD_SIZE - 1)	// top of stack
 	.endm
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/hw_breakpoint.c linux-libre-3.11-rc7-gnu/arch/arm64/kernel/hw_breakpoint.c
--- linux-libre-3.10-gnu/arch/arm64/kernel/hw_breakpoint.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/hw_breakpoint.c	2013-08-25 20:43:22.000000000 -0400
@@ -821,7 +821,7 @@ static void reset_ctrl_regs(void *unused
 	}
 }
 
-static int __cpuinit hw_breakpoint_reset_notify(struct notifier_block *self,
+static int hw_breakpoint_reset_notify(struct notifier_block *self,
 						unsigned long action,
 						void *hcpu)
 {
@@ -831,7 +831,7 @@ static int __cpuinit hw_breakpoint_reset
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata hw_breakpoint_reset_nb = {
+static struct notifier_block hw_breakpoint_reset_nb = {
 	.notifier_call = hw_breakpoint_reset_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/perf_event.c linux-libre-3.11-rc7-gnu/arch/arm64/kernel/perf_event.c
--- linux-libre-3.10-gnu/arch/arm64/kernel/perf_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/perf_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,7 +107,12 @@ armpmu_map_cache_event(const unsigned (*
 static int
 armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
 {
-	int mapping = (*event_map)[config];
+	int mapping;
+
+	if (config >= PERF_COUNT_HW_MAX)
+		return -EINVAL;
+
+	mapping = (*event_map)[config];
 	return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
 }
 
@@ -317,6 +322,9 @@ validate_event(struct pmu_hw_events *hw_
 	struct hw_perf_event fake_event = event->hw;
 	struct pmu *leader_pmu = event->group_leader->pmu;
 
+	if (is_software_event(event))
+		return 1;
+
 	if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
 		return 1;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/process.c linux-libre-3.11-rc7-gnu/arch/arm64/kernel/process.c
--- linux-libre-3.10-gnu/arch/arm64/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -81,7 +81,7 @@ void soft_restart(unsigned long addr)
 void (*pm_power_off)(void);
 EXPORT_SYMBOL_GPL(pm_power_off);
 
-void (*arm_pm_restart)(char str, const char *cmd);
+void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
 EXPORT_SYMBOL_GPL(arm_pm_restart);
 
 void arch_cpu_idle_prepare(void)
@@ -132,7 +132,7 @@ void machine_restart(char *cmd)
 
 	/* Now call the architecture specific reboot code. */
 	if (arm_pm_restart)
-		arm_pm_restart('h', cmd);
+		arm_pm_restart(reboot_mode, cmd);
 
 	/*
 	 * Whoops - the architecture was unable to reboot.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/ptrace.c linux-libre-3.11-rc7-gnu/arch/arm64/kernel/ptrace.c
--- linux-libre-3.10-gnu/arch/arm64/kernel/ptrace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/ptrace.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,28 +53,6 @@ void ptrace_disable(struct task_struct *
 {
 }
 
-/*
- * Handle hitting a breakpoint.
- */
-static int ptrace_break(struct pt_regs *regs)
-{
-	siginfo_t info = {
-		.si_signo = SIGTRAP,
-		.si_errno = 0,
-		.si_code  = TRAP_BRKPT,
-		.si_addr  = (void __user *)instruction_pointer(regs),
-	};
-
-	force_sig_info(SIGTRAP, &info, current);
-	return 0;
-}
-
-static int arm64_break_trap(unsigned long addr, unsigned int esr,
-			    struct pt_regs *regs)
-{
-	return ptrace_break(regs);
-}
-
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 /*
  * Handle hitting a HW-breakpoint.
@@ -817,33 +795,6 @@ static const struct user_regset_view use
 	.regsets = aarch32_regsets, .n = ARRAY_SIZE(aarch32_regsets)
 };
 
-int aarch32_break_trap(struct pt_regs *regs)
-{
-	unsigned int instr;
-	bool bp = false;
-	void __user *pc = (void __user *)instruction_pointer(regs);
-
-	if (compat_thumb_mode(regs)) {
-		/* get 16-bit Thumb instruction */
-		get_user(instr, (u16 __user *)pc);
-		if (instr == AARCH32_BREAK_THUMB2_LO) {
-			/* get second half of 32-bit Thumb-2 instruction */
-			get_user(instr, (u16 __user *)(pc + 2));
-			bp = instr == AARCH32_BREAK_THUMB2_HI;
-		} else {
-			bp = instr == AARCH32_BREAK_THUMB;
-		}
-	} else {
-		/* 32-bit ARM instruction */
-		get_user(instr, (u32 __user *)pc);
-		bp = (instr & ~0xf0000000) == AARCH32_BREAK_ARM;
-	}
-
-	if (bp)
-		return ptrace_break(regs);
-	return 1;
-}
-
 static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off,
 				   compat_ulong_t __user *ret)
 {
@@ -1111,16 +1062,6 @@ long arch_ptrace(struct task_struct *chi
 	return ptrace_request(child, request, addr, data);
 }
 
-
-static int __init ptrace_break_init(void)
-{
-	hook_debug_fault_code(DBG_ESR_EVT_BRK, arm64_break_trap, SIGTRAP,
-			      TRAP_BRKPT, "ptrace BRK handler");
-	return 0;
-}
-core_initcall(ptrace_break_init);
-
-
 asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
 {
 	unsigned long saved_reg;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/arm64/kernel/smp.c
--- linux-libre-3.10-gnu/arch/arm64/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -71,7 +71,7 @@ static DEFINE_RAW_SPINLOCK(boot_lock);
  * in coherency or not.  This is necessary for the hotplug code to work
  * reliably.
  */
-static void __cpuinit write_pen_release(u64 val)
+static void write_pen_release(u64 val)
 {
 	void *start = (void *)&secondary_holding_pen_release;
 	unsigned long size = sizeof(secondary_holding_pen_release);
@@ -84,7 +84,7 @@ static void __cpuinit write_pen_release(
  * Boot a secondary CPU, and assign it the specified idle task.
  * This also gives us the initial stack to use for this CPU.
  */
-static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
 
@@ -122,7 +122,7 @@ static int __cpuinit boot_secondary(unsi
 
 static DECLARE_COMPLETION(cpu_running);
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
+int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	int ret;
 
@@ -162,7 +162,7 @@ int __cpuinit __cpu_up(unsigned int cpu,
  * This is the secondary CPU boot entry.  We're using this CPUs
  * idle thread stack, but a set of temporary page tables.
  */
-asmlinkage void __cpuinit secondary_start_kernel(void)
+asmlinkage void secondary_start_kernel(void)
 {
 	struct mm_struct *mm = &init_mm;
 	unsigned int cpu = smp_processor_id();
@@ -200,13 +200,6 @@ asmlinkage void __cpuinit secondary_star
 	raw_spin_unlock(&boot_lock);
 
 	/*
-	 * Enable local interrupts.
-	 */
-	notify_cpu_starting(cpu);
-	local_irq_enable();
-	local_fiq_enable();
-
-	/*
 	 * OK, now it's safe to let the boot CPU continue.  Wait for
 	 * the CPU migration code to notice that the CPU is online
 	 * before we continue.
@@ -215,6 +208,14 @@ asmlinkage void __cpuinit secondary_star
 	complete(&cpu_running);
 
 	/*
+	 * Enable GIC and timers.
+	 */
+	notify_cpu_starting(cpu);
+
+	local_irq_enable();
+	local_fiq_enable();
+
+	/*
 	 * OK, it's off to the idle thread for us
 	 */
 	cpu_startup_entry(CPUHP_ONLINE);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/time.c linux-libre-3.11-rc7-gnu/arch/arm64/kernel/time.c
--- linux-libre-3.10-gnu/arch/arm64/kernel/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -68,12 +68,6 @@ unsigned long long notrace sched_clock(v
 	return arch_timer_read_counter() * sched_clock_mult;
 }
 
-int read_current_timer(unsigned long *timer_value)
-{
-	*timer_value = arch_timer_read_counter();
-	return 0;
-}
-
 void __init time_init(void)
 {
 	u32 arch_timer_rate;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/arm64/kernel/traps.c
--- linux-libre-3.10-gnu/arch/arm64/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/syscalls.h>
 
 #include <asm/atomic.h>
+#include <asm/debug-monitors.h>
 #include <asm/traps.h>
 #include <asm/stacktrace.h>
 #include <asm/exception.h>
@@ -261,11 +262,9 @@ asmlinkage void __exception do_undefinst
 	siginfo_t info;
 	void __user *pc = (void __user *)instruction_pointer(regs);
 
-#ifdef CONFIG_COMPAT
 	/* check for AArch32 breakpoint instructions */
-	if (compat_user_mode(regs) && aarch32_break_trap(regs) == 0)
+	if (!aarch32_break_handler(regs))
 		return;
-#endif
 
 	if (show_unhandled_signals && unhandled_signal(current, SIGILL) &&
 	    printk_ratelimit()) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kernel/vmlinux.lds.S linux-libre-3.11-rc7-gnu/arch/arm64/kernel/vmlinux.lds.S
--- linux-libre-3.10-gnu/arch/arm64/kernel/vmlinux.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kernel/vmlinux.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,19 @@ ENTRY(stext)
 
 jiffies = jiffies_64;
 
+#define HYPERVISOR_TEXT					\
+	/*						\
+	 * Force the alignment to be compatible with	\
+	 * the vectors requirements			\
+	 */						\
+	. = ALIGN(2048);				\
+	VMLINUX_SYMBOL(__hyp_idmap_text_start) = .;	\
+	*(.hyp.idmap.text)				\
+	VMLINUX_SYMBOL(__hyp_idmap_text_end) = .;	\
+	VMLINUX_SYMBOL(__hyp_text_start) = .;		\
+	*(.hyp.text)					\
+	VMLINUX_SYMBOL(__hyp_text_end) = .;
+
 SECTIONS
 {
 	/*
@@ -49,6 +62,7 @@ SECTIONS
 			TEXT_TEXT
 			SCHED_TEXT
 			LOCK_TEXT
+			HYPERVISOR_TEXT
 			*(.fixup)
 			*(.gnu.warning)
 		. = ALIGN(16);
@@ -56,7 +70,7 @@ SECTIONS
 	}
 
 	RO_DATA(PAGE_SIZE)
-
+	EXCEPTION_TABLE(8)
 	_etext = .;			/* End of text and rodata section */
 
 	. = ALIGN(PAGE_SIZE);
@@ -99,14 +113,6 @@ SECTIONS
 		READ_MOSTLY_DATA(64)
 
 		/*
-		 * The exception fixup table (might need resorting at runtime)
-		 */
-		. = ALIGN(32);
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		/*
 		 * and the usual data section
 		 */
 		DATA_DATA
@@ -124,3 +130,9 @@ SECTIONS
 	STABS_DEBUG
 	.comment 0 : { *(.comment) }
 }
+
+/*
+ * The HYP init code can't be more than a page long.
+ */
+ASSERT(((__hyp_idmap_text_start + PAGE_SIZE) > __hyp_idmap_text_end),
+       "HYP init code too big")
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/emulate.c linux-libre-3.11-rc7-gnu/arch/arm64/kvm/emulate.c
--- linux-libre-3.10-gnu/arch/arm64/kvm/emulate.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/emulate.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,158 @@
+/*
+ * (not much of an) Emulation layer for 32bit guests.
+ *
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * based on arch/arm/kvm/emulate.c
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_emulate.h>
+
+/*
+ * stolen from arch/arm/kernel/opcodes.c
+ *
+ * condition code lookup table
+ * index into the table is test code: EQ, NE, ... LT, GT, AL, NV
+ *
+ * bit position in short is condition code: NZCV
+ */
+static const unsigned short cc_map[16] = {
+	0xF0F0,			/* EQ == Z set            */
+	0x0F0F,			/* NE                     */
+	0xCCCC,			/* CS == C set            */
+	0x3333,			/* CC                     */
+	0xFF00,			/* MI == N set            */
+	0x00FF,			/* PL                     */
+	0xAAAA,			/* VS == V set            */
+	0x5555,			/* VC                     */
+	0x0C0C,			/* HI == C set && Z clear */
+	0xF3F3,			/* LS == C clear || Z set */
+	0xAA55,			/* GE == (N==V)           */
+	0x55AA,			/* LT == (N!=V)           */
+	0x0A05,			/* GT == (!Z && (N==V))   */
+	0xF5FA,			/* LE == (Z || (N!=V))    */
+	0xFFFF,			/* AL always              */
+	0			/* NV                     */
+};
+
+static int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
+{
+	u32 esr = kvm_vcpu_get_hsr(vcpu);
+
+	if (esr & ESR_EL2_CV)
+		return (esr & ESR_EL2_COND) >> ESR_EL2_COND_SHIFT;
+
+	return -1;
+}
+
+/*
+ * Check if a trapped instruction should have been executed or not.
+ */
+bool kvm_condition_valid32(const struct kvm_vcpu *vcpu)
+{
+	unsigned long cpsr;
+	u32 cpsr_cond;
+	int cond;
+
+	/* Top two bits non-zero?  Unconditional. */
+	if (kvm_vcpu_get_hsr(vcpu) >> 30)
+		return true;
+
+	/* Is condition field valid? */
+	cond = kvm_vcpu_get_condition(vcpu);
+	if (cond == 0xE)
+		return true;
+
+	cpsr = *vcpu_cpsr(vcpu);
+
+	if (cond < 0) {
+		/* This can happen in Thumb mode: examine IT state. */
+		unsigned long it;
+
+		it = ((cpsr >> 8) & 0xFC) | ((cpsr >> 25) & 0x3);
+
+		/* it == 0 => unconditional. */
+		if (it == 0)
+			return true;
+
+		/* The cond for this insn works out as the top 4 bits. */
+		cond = (it >> 4);
+	}
+
+	cpsr_cond = cpsr >> 28;
+
+	if (!((cc_map[cond] >> cpsr_cond) & 1))
+		return false;
+
+	return true;
+}
+
+/**
+ * adjust_itstate - adjust ITSTATE when emulating instructions in IT-block
+ * @vcpu:	The VCPU pointer
+ *
+ * When exceptions occur while instructions are executed in Thumb IF-THEN
+ * blocks, the ITSTATE field of the CPSR is not advanced (updated), so we have
+ * to do this little bit of work manually. The fields map like this:
+ *
+ * IT[7:0] -> CPSR[26:25],CPSR[15:10]
+ */
+static void kvm_adjust_itstate(struct kvm_vcpu *vcpu)
+{
+	unsigned long itbits, cond;
+	unsigned long cpsr = *vcpu_cpsr(vcpu);
+	bool is_arm = !(cpsr & COMPAT_PSR_T_BIT);
+
+	BUG_ON(is_arm && (cpsr & COMPAT_PSR_IT_MASK));
+
+	if (!(cpsr & COMPAT_PSR_IT_MASK))
+		return;
+
+	cond = (cpsr & 0xe000) >> 13;
+	itbits = (cpsr & 0x1c00) >> (10 - 2);
+	itbits |= (cpsr & (0x3 << 25)) >> 25;
+
+	/* Perform ITAdvance (see page A2-52 in ARM DDI 0406C) */
+	if ((itbits & 0x7) == 0)
+		itbits = cond = 0;
+	else
+		itbits = (itbits << 1) & 0x1f;
+
+	cpsr &= ~COMPAT_PSR_IT_MASK;
+	cpsr |= cond << 13;
+	cpsr |= (itbits & 0x1c) << (10 - 2);
+	cpsr |= (itbits & 0x3) << 25;
+	*vcpu_cpsr(vcpu) = cpsr;
+}
+
+/**
+ * kvm_skip_instr - skip a trapped instruction and proceed to the next
+ * @vcpu: The vcpu pointer
+ */
+void kvm_skip_instr32(struct kvm_vcpu *vcpu, bool is_wide_instr)
+{
+	bool is_thumb;
+
+	is_thumb = !!(*vcpu_cpsr(vcpu) & COMPAT_PSR_T_BIT);
+	if (is_thumb && !is_wide_instr)
+		*vcpu_pc(vcpu) += 2;
+	else
+		*vcpu_pc(vcpu) += 4;
+	kvm_adjust_itstate(vcpu);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/guest.c linux-libre-3.11-rc7-gnu/arch/arm64/kvm/guest.c
--- linux-libre-3.10-gnu/arch/arm64/kvm/guest.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/guest.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/kvm/guest.c:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/kvm_host.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <asm/cputype.h>
+#include <asm/uaccess.h>
+#include <asm/kvm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_coproc.h>
+
+struct kvm_stats_debugfs_item debugfs_entries[] = {
+	{ NULL }
+};
+
+int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
+	return 0;
+}
+
+static u64 core_reg_offset_from_id(u64 id)
+{
+	return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE);
+}
+
+static int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	/*
+	 * Because the kvm_regs structure is a mix of 32, 64 and
+	 * 128bit fields, we index it as if it was a 32bit
+	 * array. Hence below, nr_regs is the number of entries, and
+	 * off the index in the "array".
+	 */
+	__u32 __user *uaddr = (__u32 __user *)(unsigned long)reg->addr;
+	struct kvm_regs *regs = vcpu_gp_regs(vcpu);
+	int nr_regs = sizeof(*regs) / sizeof(__u32);
+	u32 off;
+
+	/* Our ID is an index into the kvm_regs struct. */
+	off = core_reg_offset_from_id(reg->id);
+	if (off >= nr_regs ||
+	    (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs)
+		return -ENOENT;
+
+	if (copy_to_user(uaddr, ((u32 *)regs) + off, KVM_REG_SIZE(reg->id)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	__u32 __user *uaddr = (__u32 __user *)(unsigned long)reg->addr;
+	struct kvm_regs *regs = vcpu_gp_regs(vcpu);
+	int nr_regs = sizeof(*regs) / sizeof(__u32);
+	__uint128_t tmp;
+	void *valp = &tmp;
+	u64 off;
+	int err = 0;
+
+	/* Our ID is an index into the kvm_regs struct. */
+	off = core_reg_offset_from_id(reg->id);
+	if (off >= nr_regs ||
+	    (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >= nr_regs)
+		return -ENOENT;
+
+	if (KVM_REG_SIZE(reg->id) > sizeof(tmp))
+		return -EINVAL;
+
+	if (copy_from_user(valp, uaddr, KVM_REG_SIZE(reg->id))) {
+		err = -EFAULT;
+		goto out;
+	}
+
+	if (off == KVM_REG_ARM_CORE_REG(regs.pstate)) {
+		u32 mode = (*(u32 *)valp) & COMPAT_PSR_MODE_MASK;
+		switch (mode) {
+		case COMPAT_PSR_MODE_USR:
+		case COMPAT_PSR_MODE_FIQ:
+		case COMPAT_PSR_MODE_IRQ:
+		case COMPAT_PSR_MODE_SVC:
+		case COMPAT_PSR_MODE_ABT:
+		case COMPAT_PSR_MODE_UND:
+		case PSR_MODE_EL0t:
+		case PSR_MODE_EL1t:
+		case PSR_MODE_EL1h:
+			break;
+		default:
+			err = -EINVAL;
+			goto out;
+		}
+	}
+
+	memcpy((u32 *)regs + off, valp, KVM_REG_SIZE(reg->id));
+out:
+	return err;
+}
+
+int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+	return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+	return -EINVAL;
+}
+
+static unsigned long num_core_regs(void)
+{
+	return sizeof(struct kvm_regs) / sizeof(__u32);
+}
+
+/**
+ * kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG
+ *
+ * This is for all registers.
+ */
+unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
+{
+	return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu);
+}
+
+/**
+ * kvm_arm_copy_reg_indices - get indices of all registers.
+ *
+ * We do core registers right here, then we apppend system regs.
+ */
+int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+	unsigned int i;
+	const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE;
+
+	for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) {
+		if (put_user(core_reg | i, uindices))
+			return -EFAULT;
+		uindices++;
+	}
+
+	return kvm_arm_copy_sys_reg_indices(vcpu, uindices);
+}
+
+int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	/* We currently use nothing arch-specific in upper 32 bits */
+	if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM64 >> 32)
+		return -EINVAL;
+
+	/* Register group 16 means we want a core register. */
+	if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
+		return get_core_reg(vcpu, reg);
+
+	return kvm_arm_sys_reg_get_reg(vcpu, reg);
+}
+
+int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	/* We currently use nothing arch-specific in upper 32 bits */
+	if ((reg->id & ~KVM_REG_SIZE_MASK) >> 32 != KVM_REG_ARM64 >> 32)
+		return -EINVAL;
+
+	/* Register group 16 means we set a core register. */
+	if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
+		return set_core_reg(vcpu, reg);
+
+	return kvm_arm_sys_reg_set_reg(vcpu, reg);
+}
+
+int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
+				  struct kvm_sregs *sregs)
+{
+	return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
+				  struct kvm_sregs *sregs)
+{
+	return -EINVAL;
+}
+
+int __attribute_const__ kvm_target_cpu(void)
+{
+	unsigned long implementor = read_cpuid_implementor();
+	unsigned long part_number = read_cpuid_part_number();
+
+	if (implementor != ARM_CPU_IMP_ARM)
+		return -EINVAL;
+
+	switch (part_number) {
+	case ARM_CPU_PART_AEM_V8:
+		return KVM_ARM_TARGET_AEM_V8;
+	case ARM_CPU_PART_FOUNDATION:
+		return KVM_ARM_TARGET_FOUNDATION_V8;
+	case ARM_CPU_PART_CORTEX_A57:
+		/* Currently handled by the generic backend */
+		return KVM_ARM_TARGET_CORTEX_A57;
+	default:
+		return -EINVAL;
+	}
+}
+
+int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
+			const struct kvm_vcpu_init *init)
+{
+	unsigned int i;
+	int phys_target = kvm_target_cpu();
+
+	if (init->target != phys_target)
+		return -EINVAL;
+
+	vcpu->arch.target = phys_target;
+	bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
+
+	/* -ENOENT for unknown features, -EINVAL for invalid combinations. */
+	for (i = 0; i < sizeof(init->features) * 8; i++) {
+		if (init->features[i / 32] & (1 << (i % 32))) {
+			if (i >= KVM_VCPU_MAX_FEATURES)
+				return -ENOENT;
+			set_bit(i, vcpu->arch.features);
+		}
+	}
+
+	/* Now we know what it is, we can reset it. */
+	return kvm_reset_vcpu(vcpu);
+}
+
+int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+	return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+	return -EINVAL;
+}
+
+int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
+				  struct kvm_translation *tr)
+{
+	return -EINVAL;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/handle_exit.c linux-libre-3.11-rc7-gnu/arch/arm64/kvm/handle_exit.c
--- linux-libre-3.10-gnu/arch/arm64/kvm/handle_exit.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/handle_exit.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/kvm/handle_exit.c:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_coproc.h>
+#include <asm/kvm_mmu.h>
+#include <asm/kvm_psci.h>
+
+typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
+
+static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	if (kvm_psci_call(vcpu))
+		return 1;
+
+	kvm_inject_undefined(vcpu);
+	return 1;
+}
+
+static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	if (kvm_psci_call(vcpu))
+		return 1;
+
+	kvm_inject_undefined(vcpu);
+	return 1;
+}
+
+/**
+ * kvm_handle_wfi - handle a wait-for-interrupts instruction executed by a guest
+ * @vcpu:	the vcpu pointer
+ *
+ * Simply call kvm_vcpu_block(), which will halt execution of
+ * world-switches and schedule other host processes until there is an
+ * incoming IRQ or FIQ to the VM.
+ */
+static int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	kvm_vcpu_block(vcpu);
+	return 1;
+}
+
+static exit_handle_fn arm_exit_handlers[] = {
+	[ESR_EL2_EC_WFI]	= kvm_handle_wfi,
+	[ESR_EL2_EC_CP15_32]	= kvm_handle_cp15_32,
+	[ESR_EL2_EC_CP15_64]	= kvm_handle_cp15_64,
+	[ESR_EL2_EC_CP14_MR]	= kvm_handle_cp14_access,
+	[ESR_EL2_EC_CP14_LS]	= kvm_handle_cp14_load_store,
+	[ESR_EL2_EC_CP14_64]	= kvm_handle_cp14_access,
+	[ESR_EL2_EC_HVC32]	= handle_hvc,
+	[ESR_EL2_EC_SMC32]	= handle_smc,
+	[ESR_EL2_EC_HVC64]	= handle_hvc,
+	[ESR_EL2_EC_SMC64]	= handle_smc,
+	[ESR_EL2_EC_SYS64]	= kvm_handle_sys_reg,
+	[ESR_EL2_EC_IABT]	= kvm_handle_guest_abort,
+	[ESR_EL2_EC_DABT]	= kvm_handle_guest_abort,
+};
+
+static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
+{
+	u8 hsr_ec = kvm_vcpu_trap_get_class(vcpu);
+
+	if (hsr_ec >= ARRAY_SIZE(arm_exit_handlers) ||
+	    !arm_exit_handlers[hsr_ec]) {
+		kvm_err("Unkown exception class: hsr: %#08x\n",
+			(unsigned int)kvm_vcpu_get_hsr(vcpu));
+		BUG();
+	}
+
+	return arm_exit_handlers[hsr_ec];
+}
+
+/*
+ * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
+ * proper exit to userspace.
+ */
+int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
+		       int exception_index)
+{
+	exit_handle_fn exit_handler;
+
+	switch (exception_index) {
+	case ARM_EXCEPTION_IRQ:
+		return 1;
+	case ARM_EXCEPTION_TRAP:
+		/*
+		 * See ARM ARM B1.14.1: "Hyp traps on instructions
+		 * that fail their condition code check"
+		 */
+		if (!kvm_condition_valid(vcpu)) {
+			kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+			return 1;
+		}
+
+		exit_handler = kvm_get_exit_handler(vcpu);
+
+		return exit_handler(vcpu, run);
+	default:
+		kvm_pr_unimpl("Unsupported exception type: %d",
+			      exception_index);
+		run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+		return 0;
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/hyp-init.S linux-libre-3.11-rc7-gnu/arch/arm64/kvm/hyp-init.S
--- linux-libre-3.10-gnu/arch/arm64/kvm/hyp-init.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/hyp-init.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_mmu.h>
+
+	.text
+	.pushsection	.hyp.idmap.text, "ax"
+
+	.align	11
+
+ENTRY(__kvm_hyp_init)
+	ventry	__invalid		// Synchronous EL2t
+	ventry	__invalid		// IRQ EL2t
+	ventry	__invalid		// FIQ EL2t
+	ventry	__invalid		// Error EL2t
+
+	ventry	__invalid		// Synchronous EL2h
+	ventry	__invalid		// IRQ EL2h
+	ventry	__invalid		// FIQ EL2h
+	ventry	__invalid		// Error EL2h
+
+	ventry	__do_hyp_init		// Synchronous 64-bit EL1
+	ventry	__invalid		// IRQ 64-bit EL1
+	ventry	__invalid		// FIQ 64-bit EL1
+	ventry	__invalid		// Error 64-bit EL1
+
+	ventry	__invalid		// Synchronous 32-bit EL1
+	ventry	__invalid		// IRQ 32-bit EL1
+	ventry	__invalid		// FIQ 32-bit EL1
+	ventry	__invalid		// Error 32-bit EL1
+
+__invalid:
+	b	.
+
+	/*
+	 * x0: HYP boot pgd
+	 * x1: HYP pgd
+	 * x2: HYP stack
+	 * x3: HYP vectors
+	 */
+__do_hyp_init:
+
+	msr	ttbr0_el2, x0
+
+	mrs	x4, tcr_el1
+	ldr	x5, =TCR_EL2_MASK
+	and	x4, x4, x5
+	ldr	x5, =TCR_EL2_FLAGS
+	orr	x4, x4, x5
+	msr	tcr_el2, x4
+
+	ldr	x4, =VTCR_EL2_FLAGS
+	msr	vtcr_el2, x4
+
+	mrs	x4, mair_el1
+	msr	mair_el2, x4
+	isb
+
+	mov	x4, #SCTLR_EL2_FLAGS
+	msr	sctlr_el2, x4
+	isb
+
+	/* MMU is now enabled. Get ready for the trampoline dance */
+	ldr	x4, =TRAMPOLINE_VA
+	adr	x5, target
+	bfi	x4, x5, #0, #PAGE_SHIFT
+	br	x4
+
+target: /* We're now in the trampoline code, switch page tables */
+	msr	ttbr0_el2, x1
+	isb
+
+	/* Invalidate the old TLBs */
+	tlbi	alle2
+	dsb	sy
+
+	/* Set the stack and new vectors */
+	kern_hyp_va	x2
+	mov	sp, x2
+	kern_hyp_va	x3
+	msr	vbar_el2, x3
+
+	/* Hello, World! */
+	eret
+ENDPROC(__kvm_hyp_init)
+
+	.ltorg
+
+	.popsection
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/hyp.S linux-libre-3.11-rc7-gnu/arch/arm64/kvm/hyp.S
--- linux-libre-3.10-gnu/arch/arm64/kvm/hyp.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/hyp.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+#include <linux/irqchip/arm-gic.h>
+
+#include <asm/assembler.h>
+#include <asm/memory.h>
+#include <asm/asm-offsets.h>
+#include <asm/fpsimdmacros.h>
+#include <asm/kvm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_mmu.h>
+
+#define CPU_GP_REG_OFFSET(x)	(CPU_GP_REGS + x)
+#define CPU_XREG_OFFSET(x)	CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x)
+#define CPU_SPSR_OFFSET(x)	CPU_GP_REG_OFFSET(CPU_SPSR + 8*x)
+#define CPU_SYSREG_OFFSET(x)	(CPU_SYSREGS + 8*x)
+
+	.text
+	.pushsection	.hyp.text, "ax"
+	.align	PAGE_SHIFT
+
+__kvm_hyp_code_start:
+	.globl __kvm_hyp_code_start
+
+.macro save_common_regs
+	// x2: base address for cpu context
+	// x3: tmp register
+
+	add	x3, x2, #CPU_XREG_OFFSET(19)
+	stp	x19, x20, [x3]
+	stp	x21, x22, [x3, #16]
+	stp	x23, x24, [x3, #32]
+	stp	x25, x26, [x3, #48]
+	stp	x27, x28, [x3, #64]
+	stp	x29, lr, [x3, #80]
+
+	mrs	x19, sp_el0
+	mrs	x20, elr_el2		// EL1 PC
+	mrs	x21, spsr_el2		// EL1 pstate
+
+	stp	x19, x20, [x3, #96]
+	str	x21, [x3, #112]
+
+	mrs	x22, sp_el1
+	mrs	x23, elr_el1
+	mrs	x24, spsr_el1
+
+	str	x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
+	str	x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
+	str	x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
+.endm
+
+.macro restore_common_regs
+	// x2: base address for cpu context
+	// x3: tmp register
+
+	ldr	x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
+	ldr	x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
+	ldr	x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
+
+	msr	sp_el1, x22
+	msr	elr_el1, x23
+	msr	spsr_el1, x24
+
+	add	x3, x2, #CPU_XREG_OFFSET(31)    // SP_EL0
+	ldp	x19, x20, [x3]
+	ldr	x21, [x3, #16]
+
+	msr	sp_el0, x19
+	msr	elr_el2, x20 				// EL1 PC
+	msr	spsr_el2, x21 				// EL1 pstate
+
+	add	x3, x2, #CPU_XREG_OFFSET(19)
+	ldp	x19, x20, [x3]
+	ldp	x21, x22, [x3, #16]
+	ldp	x23, x24, [x3, #32]
+	ldp	x25, x26, [x3, #48]
+	ldp	x27, x28, [x3, #64]
+	ldp	x29, lr, [x3, #80]
+.endm
+
+.macro save_host_regs
+	save_common_regs
+.endm
+
+.macro restore_host_regs
+	restore_common_regs
+.endm
+
+.macro save_fpsimd
+	// x2: cpu context address
+	// x3, x4: tmp regs
+	add	x3, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
+	fpsimd_save x3, 4
+.endm
+
+.macro restore_fpsimd
+	// x2: cpu context address
+	// x3, x4: tmp regs
+	add	x3, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
+	fpsimd_restore x3, 4
+.endm
+
+.macro save_guest_regs
+	// x0 is the vcpu address
+	// x1 is the return code, do not corrupt!
+	// x2 is the cpu context
+	// x3 is a tmp register
+	// Guest's x0-x3 are on the stack
+
+	// Compute base to save registers
+	add	x3, x2, #CPU_XREG_OFFSET(4)
+	stp	x4, x5, [x3]
+	stp	x6, x7, [x3, #16]
+	stp	x8, x9, [x3, #32]
+	stp	x10, x11, [x3, #48]
+	stp	x12, x13, [x3, #64]
+	stp	x14, x15, [x3, #80]
+	stp	x16, x17, [x3, #96]
+	str	x18, [x3, #112]
+
+	pop	x6, x7			// x2, x3
+	pop	x4, x5			// x0, x1
+
+	add	x3, x2, #CPU_XREG_OFFSET(0)
+	stp	x4, x5, [x3]
+	stp	x6, x7, [x3, #16]
+
+	save_common_regs
+.endm
+
+.macro restore_guest_regs
+	// x0 is the vcpu address.
+	// x2 is the cpu context
+	// x3 is a tmp register
+
+	// Prepare x0-x3 for later restore
+	add	x3, x2, #CPU_XREG_OFFSET(0)
+	ldp	x4, x5, [x3]
+	ldp	x6, x7, [x3, #16]
+	push	x4, x5		// Push x0-x3 on the stack
+	push	x6, x7
+
+	// x4-x18
+	ldp	x4, x5, [x3, #32]
+	ldp	x6, x7, [x3, #48]
+	ldp	x8, x9, [x3, #64]
+	ldp	x10, x11, [x3, #80]
+	ldp	x12, x13, [x3, #96]
+	ldp	x14, x15, [x3, #112]
+	ldp	x16, x17, [x3, #128]
+	ldr	x18, [x3, #144]
+
+	// x19-x29, lr, sp*, elr*, spsr*
+	restore_common_regs
+
+	// Last bits of the 64bit state
+	pop	x2, x3
+	pop	x0, x1
+
+	// Do not touch any register after this!
+.endm
+
+/*
+ * Macros to perform system register save/restore.
+ *
+ * Ordering here is absolutely critical, and must be kept consistent
+ * in {save,restore}_sysregs, {save,restore}_guest_32bit_state,
+ * and in kvm_asm.h.
+ *
+ * In other words, don't touch any of these unless you know what
+ * you are doing.
+ */
+.macro save_sysregs
+	// x2: base address for cpu context
+	// x3: tmp register
+
+	add	x3, x2, #CPU_SYSREG_OFFSET(MPIDR_EL1)
+
+	mrs	x4,	vmpidr_el2
+	mrs	x5,	csselr_el1
+	mrs	x6,	sctlr_el1
+	mrs	x7,	actlr_el1
+	mrs	x8,	cpacr_el1
+	mrs	x9,	ttbr0_el1
+	mrs	x10,	ttbr1_el1
+	mrs	x11,	tcr_el1
+	mrs	x12,	esr_el1
+	mrs	x13, 	afsr0_el1
+	mrs	x14,	afsr1_el1
+	mrs	x15,	far_el1
+	mrs	x16,	mair_el1
+	mrs	x17,	vbar_el1
+	mrs	x18,	contextidr_el1
+	mrs	x19,	tpidr_el0
+	mrs	x20,	tpidrro_el0
+	mrs	x21,	tpidr_el1
+	mrs	x22, 	amair_el1
+	mrs	x23, 	cntkctl_el1
+	mrs	x24,	par_el1
+
+	stp	x4, x5, [x3]
+	stp	x6, x7, [x3, #16]
+	stp	x8, x9, [x3, #32]
+	stp	x10, x11, [x3, #48]
+	stp	x12, x13, [x3, #64]
+	stp	x14, x15, [x3, #80]
+	stp	x16, x17, [x3, #96]
+	stp	x18, x19, [x3, #112]
+	stp	x20, x21, [x3, #128]
+	stp	x22, x23, [x3, #144]
+	str	x24, [x3, #160]
+.endm
+
+.macro restore_sysregs
+	// x2: base address for cpu context
+	// x3: tmp register
+
+	add	x3, x2, #CPU_SYSREG_OFFSET(MPIDR_EL1)
+
+	ldp	x4, x5, [x3]
+	ldp	x6, x7, [x3, #16]
+	ldp	x8, x9, [x3, #32]
+	ldp	x10, x11, [x3, #48]
+	ldp	x12, x13, [x3, #64]
+	ldp	x14, x15, [x3, #80]
+	ldp	x16, x17, [x3, #96]
+	ldp	x18, x19, [x3, #112]
+	ldp	x20, x21, [x3, #128]
+	ldp	x22, x23, [x3, #144]
+	ldr	x24, [x3, #160]
+
+	msr	vmpidr_el2,	x4
+	msr	csselr_el1,	x5
+	msr	sctlr_el1,	x6
+	msr	actlr_el1,	x7
+	msr	cpacr_el1,	x8
+	msr	ttbr0_el1,	x9
+	msr	ttbr1_el1,	x10
+	msr	tcr_el1,	x11
+	msr	esr_el1,	x12
+	msr	afsr0_el1,	x13
+	msr	afsr1_el1,	x14
+	msr	far_el1,	x15
+	msr	mair_el1,	x16
+	msr	vbar_el1,	x17
+	msr	contextidr_el1,	x18
+	msr	tpidr_el0,	x19
+	msr	tpidrro_el0,	x20
+	msr	tpidr_el1,	x21
+	msr	amair_el1,	x22
+	msr	cntkctl_el1,	x23
+	msr	par_el1,	x24
+.endm
+
+.macro skip_32bit_state tmp, target
+	// Skip 32bit state if not needed
+	mrs	\tmp, hcr_el2
+	tbnz	\tmp, #HCR_RW_SHIFT, \target
+.endm
+
+.macro skip_tee_state tmp, target
+	// Skip ThumbEE state if not needed
+	mrs	\tmp, id_pfr0_el1
+	tbz	\tmp, #12, \target
+.endm
+
+.macro save_guest_32bit_state
+	skip_32bit_state x3, 1f
+
+	add	x3, x2, #CPU_SPSR_OFFSET(KVM_SPSR_ABT)
+	mrs	x4, spsr_abt
+	mrs	x5, spsr_und
+	mrs	x6, spsr_irq
+	mrs	x7, spsr_fiq
+	stp	x4, x5, [x3]
+	stp	x6, x7, [x3, #16]
+
+	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
+	mrs	x4, dacr32_el2
+	mrs	x5, ifsr32_el2
+	mrs	x6, fpexc32_el2
+	mrs	x7, dbgvcr32_el2
+	stp	x4, x5, [x3]
+	stp	x6, x7, [x3, #16]
+
+	skip_tee_state x8, 1f
+
+	add	x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1)
+	mrs	x4, teecr32_el1
+	mrs	x5, teehbr32_el1
+	stp	x4, x5, [x3]
+1:
+.endm
+
+.macro restore_guest_32bit_state
+	skip_32bit_state x3, 1f
+
+	add	x3, x2, #CPU_SPSR_OFFSET(KVM_SPSR_ABT)
+	ldp	x4, x5, [x3]
+	ldp	x6, x7, [x3, #16]
+	msr	spsr_abt, x4
+	msr	spsr_und, x5
+	msr	spsr_irq, x6
+	msr	spsr_fiq, x7
+
+	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
+	ldp	x4, x5, [x3]
+	ldp	x6, x7, [x3, #16]
+	msr	dacr32_el2, x4
+	msr	ifsr32_el2, x5
+	msr	fpexc32_el2, x6
+	msr	dbgvcr32_el2, x7
+
+	skip_tee_state x8, 1f
+
+	add	x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1)
+	ldp	x4, x5, [x3]
+	msr	teecr32_el1, x4
+	msr	teehbr32_el1, x5
+1:
+.endm
+
+.macro activate_traps
+	ldr	x2, [x0, #VCPU_IRQ_LINES]
+	ldr	x1, [x0, #VCPU_HCR_EL2]
+	orr	x2, x2, x1
+	msr	hcr_el2, x2
+
+	ldr	x2, =(CPTR_EL2_TTA)
+	msr	cptr_el2, x2
+
+	ldr	x2, =(1 << 15)	// Trap CP15 Cr=15
+	msr	hstr_el2, x2
+
+	mrs	x2, mdcr_el2
+	and	x2, x2, #MDCR_EL2_HPMN_MASK
+	orr	x2, x2, #(MDCR_EL2_TPM | MDCR_EL2_TPMCR)
+	msr	mdcr_el2, x2
+.endm
+
+.macro deactivate_traps
+	mov	x2, #HCR_RW
+	msr	hcr_el2, x2
+	msr	cptr_el2, xzr
+	msr	hstr_el2, xzr
+
+	mrs	x2, mdcr_el2
+	and	x2, x2, #MDCR_EL2_HPMN_MASK
+	msr	mdcr_el2, x2
+.endm
+
+.macro activate_vm
+	ldr	x1, [x0, #VCPU_KVM]
+	kern_hyp_va	x1
+	ldr	x2, [x1, #KVM_VTTBR]
+	msr	vttbr_el2, x2
+.endm
+
+.macro deactivate_vm
+	msr	vttbr_el2, xzr
+.endm
+
+/*
+ * Save the VGIC CPU state into memory
+ * x0: Register pointing to VCPU struct
+ * Do not corrupt x1!!!
+ */
+.macro save_vgic_state
+	/* Get VGIC VCTRL base into x2 */
+	ldr	x2, [x0, #VCPU_KVM]
+	kern_hyp_va	x2
+	ldr	x2, [x2, #KVM_VGIC_VCTRL]
+	kern_hyp_va	x2
+	cbz	x2, 2f		// disabled
+
+	/* Compute the address of struct vgic_cpu */
+	add	x3, x0, #VCPU_VGIC_CPU
+
+	/* Save all interesting registers */
+	ldr	w4, [x2, #GICH_HCR]
+	ldr	w5, [x2, #GICH_VMCR]
+	ldr	w6, [x2, #GICH_MISR]
+	ldr	w7, [x2, #GICH_EISR0]
+	ldr	w8, [x2, #GICH_EISR1]
+	ldr	w9, [x2, #GICH_ELRSR0]
+	ldr	w10, [x2, #GICH_ELRSR1]
+	ldr	w11, [x2, #GICH_APR]
+
+	str	w4, [x3, #VGIC_CPU_HCR]
+	str	w5, [x3, #VGIC_CPU_VMCR]
+	str	w6, [x3, #VGIC_CPU_MISR]
+	str	w7, [x3, #VGIC_CPU_EISR]
+	str	w8, [x3, #(VGIC_CPU_EISR + 4)]
+	str	w9, [x3, #VGIC_CPU_ELRSR]
+	str	w10, [x3, #(VGIC_CPU_ELRSR + 4)]
+	str	w11, [x3, #VGIC_CPU_APR]
+
+	/* Clear GICH_HCR */
+	str	wzr, [x2, #GICH_HCR]
+
+	/* Save list registers */
+	add	x2, x2, #GICH_LR0
+	ldr	w4, [x3, #VGIC_CPU_NR_LR]
+	add	x3, x3, #VGIC_CPU_LR
+1:	ldr	w5, [x2], #4
+	str	w5, [x3], #4
+	sub	w4, w4, #1
+	cbnz	w4, 1b
+2:
+.endm
+
+/*
+ * Restore the VGIC CPU state from memory
+ * x0: Register pointing to VCPU struct
+ */
+.macro restore_vgic_state
+	/* Get VGIC VCTRL base into x2 */
+	ldr	x2, [x0, #VCPU_KVM]
+	kern_hyp_va	x2
+	ldr	x2, [x2, #KVM_VGIC_VCTRL]
+	kern_hyp_va	x2
+	cbz	x2, 2f		// disabled
+
+	/* Compute the address of struct vgic_cpu */
+	add	x3, x0, #VCPU_VGIC_CPU
+
+	/* We only restore a minimal set of registers */
+	ldr	w4, [x3, #VGIC_CPU_HCR]
+	ldr	w5, [x3, #VGIC_CPU_VMCR]
+	ldr	w6, [x3, #VGIC_CPU_APR]
+
+	str	w4, [x2, #GICH_HCR]
+	str	w5, [x2, #GICH_VMCR]
+	str	w6, [x2, #GICH_APR]
+
+	/* Restore list registers */
+	add	x2, x2, #GICH_LR0
+	ldr	w4, [x3, #VGIC_CPU_NR_LR]
+	add	x3, x3, #VGIC_CPU_LR
+1:	ldr	w5, [x3], #4
+	str	w5, [x2], #4
+	sub	w4, w4, #1
+	cbnz	w4, 1b
+2:
+.endm
+
+.macro save_timer_state
+	// x0: vcpu pointer
+	ldr	x2, [x0, #VCPU_KVM]
+	kern_hyp_va x2
+	ldr	w3, [x2, #KVM_TIMER_ENABLED]
+	cbz	w3, 1f
+
+	mrs	x3, cntv_ctl_el0
+	and	x3, x3, #3
+	str	w3, [x0, #VCPU_TIMER_CNTV_CTL]
+	bic	x3, x3, #1		// Clear Enable
+	msr	cntv_ctl_el0, x3
+
+	isb
+
+	mrs	x3, cntv_cval_el0
+	str	x3, [x0, #VCPU_TIMER_CNTV_CVAL]
+
+1:
+	// Allow physical timer/counter access for the host
+	mrs	x2, cnthctl_el2
+	orr	x2, x2, #3
+	msr	cnthctl_el2, x2
+
+	// Clear cntvoff for the host
+	msr	cntvoff_el2, xzr
+.endm
+
+.macro restore_timer_state
+	// x0: vcpu pointer
+	// Disallow physical timer access for the guest
+	// Physical counter access is allowed
+	mrs	x2, cnthctl_el2
+	orr	x2, x2, #1
+	bic	x2, x2, #2
+	msr	cnthctl_el2, x2
+
+	ldr	x2, [x0, #VCPU_KVM]
+	kern_hyp_va x2
+	ldr	w3, [x2, #KVM_TIMER_ENABLED]
+	cbz	w3, 1f
+
+	ldr	x3, [x2, #KVM_TIMER_CNTVOFF]
+	msr	cntvoff_el2, x3
+	ldr	x2, [x0, #VCPU_TIMER_CNTV_CVAL]
+	msr	cntv_cval_el0, x2
+	isb
+
+	ldr	w2, [x0, #VCPU_TIMER_CNTV_CTL]
+	and	x2, x2, #3
+	msr	cntv_ctl_el0, x2
+1:
+.endm
+
+__save_sysregs:
+	save_sysregs
+	ret
+
+__restore_sysregs:
+	restore_sysregs
+	ret
+
+__save_fpsimd:
+	save_fpsimd
+	ret
+
+__restore_fpsimd:
+	restore_fpsimd
+	ret
+
+/*
+ * u64 __kvm_vcpu_run(struct kvm_vcpu *vcpu);
+ *
+ * This is the world switch. The first half of the function
+ * deals with entering the guest, and anything from __kvm_vcpu_return
+ * to the end of the function deals with reentering the host.
+ * On the enter path, only x0 (vcpu pointer) must be preserved until
+ * the last moment. On the exit path, x0 (vcpu pointer) and x1 (exception
+ * code) must both be preserved until the epilogue.
+ * In both cases, x2 points to the CPU context we're saving/restoring from/to.
+ */
+ENTRY(__kvm_vcpu_run)
+	kern_hyp_va	x0
+	msr	tpidr_el2, x0	// Save the vcpu register
+
+	// Host context
+	ldr	x2, [x0, #VCPU_HOST_CONTEXT]
+	kern_hyp_va x2
+
+	save_host_regs
+	bl __save_fpsimd
+	bl __save_sysregs
+
+	activate_traps
+	activate_vm
+
+	restore_vgic_state
+	restore_timer_state
+
+	// Guest context
+	add	x2, x0, #VCPU_CONTEXT
+
+	bl __restore_sysregs
+	bl __restore_fpsimd
+	restore_guest_32bit_state
+	restore_guest_regs
+
+	// That's it, no more messing around.
+	eret
+
+__kvm_vcpu_return:
+	// Assume x0 is the vcpu pointer, x1 the return code
+	// Guest's x0-x3 are on the stack
+
+	// Guest context
+	add	x2, x0, #VCPU_CONTEXT
+
+	save_guest_regs
+	bl __save_fpsimd
+	bl __save_sysregs
+	save_guest_32bit_state
+
+	save_timer_state
+	save_vgic_state
+
+	deactivate_traps
+	deactivate_vm
+
+	// Host context
+	ldr	x2, [x0, #VCPU_HOST_CONTEXT]
+	kern_hyp_va x2
+
+	bl __restore_sysregs
+	bl __restore_fpsimd
+	restore_host_regs
+
+	mov	x0, x1
+	ret
+END(__kvm_vcpu_run)
+
+// void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
+ENTRY(__kvm_tlb_flush_vmid_ipa)
+	dsb	ishst
+
+	kern_hyp_va	x0
+	ldr	x2, [x0, #KVM_VTTBR]
+	msr	vttbr_el2, x2
+	isb
+
+	/*
+	 * We could do so much better if we had the VA as well.
+	 * Instead, we invalidate Stage-2 for this IPA, and the
+	 * whole of Stage-1. Weep...
+	 */
+	tlbi	ipas2e1is, x1
+	dsb	sy
+	tlbi	vmalle1is
+	dsb	sy
+	isb
+
+	msr	vttbr_el2, xzr
+	ret
+ENDPROC(__kvm_tlb_flush_vmid_ipa)
+
+ENTRY(__kvm_flush_vm_context)
+	dsb	ishst
+	tlbi	alle1is
+	ic	ialluis
+	dsb	sy
+	ret
+ENDPROC(__kvm_flush_vm_context)
+
+__kvm_hyp_panic:
+	// Guess the context by looking at VTTBR:
+	// If zero, then we're already a host.
+	// Otherwise restore a minimal host context before panicing.
+	mrs	x0, vttbr_el2
+	cbz	x0, 1f
+
+	mrs	x0, tpidr_el2
+
+	deactivate_traps
+	deactivate_vm
+
+	ldr	x2, [x0, #VCPU_HOST_CONTEXT]
+	kern_hyp_va x2
+
+	bl __restore_sysregs
+
+1:	adr	x0, __hyp_panic_str
+	adr	x1, 2f
+	ldp	x2, x3, [x1]
+	sub	x0, x0, x2
+	add	x0, x0, x3
+	mrs	x1, spsr_el2
+	mrs	x2, elr_el2
+	mrs	x3, esr_el2
+	mrs	x4, far_el2
+	mrs	x5, hpfar_el2
+	mrs	x6, par_el1
+	mrs	x7, tpidr_el2
+
+	mov	lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
+		      PSR_MODE_EL1h)
+	msr	spsr_el2, lr
+	ldr	lr, =panic
+	msr	elr_el2, lr
+	eret
+
+	.align	3
+2:	.quad	HYP_PAGE_OFFSET
+	.quad	PAGE_OFFSET
+ENDPROC(__kvm_hyp_panic)
+
+__hyp_panic_str:
+	.ascii	"HYP panic:\nPS:%08x PC:%p ESR:%p\nFAR:%p HPFAR:%p PAR:%p\nVCPU:%p\n\0"
+
+	.align	2
+
+ENTRY(kvm_call_hyp)
+	hvc	#0
+	ret
+ENDPROC(kvm_call_hyp)
+
+.macro invalid_vector	label, target
+	.align	2
+\label:
+	b \target
+ENDPROC(\label)
+.endm
+
+	/* None of these should ever happen */
+	invalid_vector	el2t_sync_invalid, __kvm_hyp_panic
+	invalid_vector	el2t_irq_invalid, __kvm_hyp_panic
+	invalid_vector	el2t_fiq_invalid, __kvm_hyp_panic
+	invalid_vector	el2t_error_invalid, __kvm_hyp_panic
+	invalid_vector	el2h_sync_invalid, __kvm_hyp_panic
+	invalid_vector	el2h_irq_invalid, __kvm_hyp_panic
+	invalid_vector	el2h_fiq_invalid, __kvm_hyp_panic
+	invalid_vector	el2h_error_invalid, __kvm_hyp_panic
+	invalid_vector	el1_sync_invalid, __kvm_hyp_panic
+	invalid_vector	el1_irq_invalid, __kvm_hyp_panic
+	invalid_vector	el1_fiq_invalid, __kvm_hyp_panic
+	invalid_vector	el1_error_invalid, __kvm_hyp_panic
+
+el1_sync:					// Guest trapped into EL2
+	push	x0, x1
+	push	x2, x3
+
+	mrs	x1, esr_el2
+	lsr	x2, x1, #ESR_EL2_EC_SHIFT
+
+	cmp	x2, #ESR_EL2_EC_HVC64
+	b.ne	el1_trap
+
+	mrs	x3, vttbr_el2			// If vttbr is valid, the 64bit guest
+	cbnz	x3, el1_trap			// called HVC
+
+	/* Here, we're pretty sure the host called HVC. */
+	pop	x2, x3
+	pop	x0, x1
+
+	push	lr, xzr
+
+	/*
+	 * Compute the function address in EL2, and shuffle the parameters.
+	 */
+	kern_hyp_va	x0
+	mov	lr, x0
+	mov	x0, x1
+	mov	x1, x2
+	mov	x2, x3
+	blr	lr
+
+	pop	lr, xzr
+	eret
+
+el1_trap:
+	/*
+	 * x1: ESR
+	 * x2: ESR_EC
+	 */
+	cmp	x2, #ESR_EL2_EC_DABT
+	mov	x0, #ESR_EL2_EC_IABT
+	ccmp	x2, x0, #4, ne
+	b.ne	1f		// Not an abort we care about
+
+	/* This is an abort. Check for permission fault */
+	and	x2, x1, #ESR_EL2_FSC_TYPE
+	cmp	x2, #FSC_PERM
+	b.ne	1f		// Not a permission fault
+
+	/*
+	 * Check for Stage-1 page table walk, which is guaranteed
+	 * to give a valid HPFAR_EL2.
+	 */
+	tbnz	x1, #7, 1f	// S1PTW is set
+
+	/* Preserve PAR_EL1 */
+	mrs	x3, par_el1
+	push	x3, xzr
+
+	/*
+	 * Permission fault, HPFAR_EL2 is invalid.
+	 * Resolve the IPA the hard way using the guest VA.
+	 * Stage-1 translation already validated the memory access rights.
+	 * As such, we can use the EL1 translation regime, and don't have
+	 * to distinguish between EL0 and EL1 access.
+	 */
+	mrs	x2, far_el2
+	at	s1e1r, x2
+	isb
+
+	/* Read result */
+	mrs	x3, par_el1
+	pop	x0, xzr			// Restore PAR_EL1 from the stack
+	msr	par_el1, x0
+	tbnz	x3, #0, 3f		// Bail out if we failed the translation
+	ubfx	x3, x3, #12, #36	// Extract IPA
+	lsl	x3, x3, #4		// and present it like HPFAR
+	b	2f
+
+1:	mrs	x3, hpfar_el2
+	mrs	x2, far_el2
+
+2:	mrs	x0, tpidr_el2
+	str	x1, [x0, #VCPU_ESR_EL2]
+	str	x2, [x0, #VCPU_FAR_EL2]
+	str	x3, [x0, #VCPU_HPFAR_EL2]
+
+	mov	x1, #ARM_EXCEPTION_TRAP
+	b	__kvm_vcpu_return
+
+	/*
+	 * Translation failed. Just return to the guest and
+	 * let it fault again. Another CPU is probably playing
+	 * behind our back.
+	 */
+3:	pop	x2, x3
+	pop	x0, x1
+
+	eret
+
+el1_irq:
+	push	x0, x1
+	push	x2, x3
+	mrs	x0, tpidr_el2
+	mov	x1, #ARM_EXCEPTION_IRQ
+	b	__kvm_vcpu_return
+
+	.ltorg
+
+	.align 11
+
+ENTRY(__kvm_hyp_vector)
+	ventry	el2t_sync_invalid		// Synchronous EL2t
+	ventry	el2t_irq_invalid		// IRQ EL2t
+	ventry	el2t_fiq_invalid		// FIQ EL2t
+	ventry	el2t_error_invalid		// Error EL2t
+
+	ventry	el2h_sync_invalid		// Synchronous EL2h
+	ventry	el2h_irq_invalid		// IRQ EL2h
+	ventry	el2h_fiq_invalid		// FIQ EL2h
+	ventry	el2h_error_invalid		// Error EL2h
+
+	ventry	el1_sync			// Synchronous 64-bit EL1
+	ventry	el1_irq				// IRQ 64-bit EL1
+	ventry	el1_fiq_invalid			// FIQ 64-bit EL1
+	ventry	el1_error_invalid		// Error 64-bit EL1
+
+	ventry	el1_sync			// Synchronous 32-bit EL1
+	ventry	el1_irq				// IRQ 32-bit EL1
+	ventry	el1_fiq_invalid			// FIQ 32-bit EL1
+	ventry	el1_error_invalid		// Error 32-bit EL1
+ENDPROC(__kvm_hyp_vector)
+
+__kvm_hyp_code_end:
+	.globl	__kvm_hyp_code_end
+
+	.popsection
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/inject_fault.c linux-libre-3.11-rc7-gnu/arch/arm64/kvm/inject_fault.c
--- linux-libre-3.10-gnu/arch/arm64/kvm/inject_fault.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/inject_fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,203 @@
+/*
+ * Fault injection for both 32 and 64bit guests.
+ *
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Based on arch/arm/kvm/emulate.c
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_emulate.h>
+#include <asm/esr.h>
+
+#define PSTATE_FAULT_BITS_64 	(PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | \
+				 PSR_I_BIT | PSR_D_BIT)
+#define EL1_EXCEPT_SYNC_OFFSET	0x200
+
+static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset)
+{
+	unsigned long cpsr;
+	unsigned long new_spsr_value = *vcpu_cpsr(vcpu);
+	bool is_thumb = (new_spsr_value & COMPAT_PSR_T_BIT);
+	u32 return_offset = (is_thumb) ? 4 : 0;
+	u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR);
+
+	cpsr = mode | COMPAT_PSR_I_BIT;
+
+	if (sctlr & (1 << 30))
+		cpsr |= COMPAT_PSR_T_BIT;
+	if (sctlr & (1 << 25))
+		cpsr |= COMPAT_PSR_E_BIT;
+
+	*vcpu_cpsr(vcpu) = cpsr;
+
+	/* Note: These now point to the banked copies */
+	*vcpu_spsr(vcpu) = new_spsr_value;
+	*vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset;
+
+	/* Branch to exception vector */
+	if (sctlr & (1 << 13))
+		vect_offset += 0xffff0000;
+	else /* always have security exceptions */
+		vect_offset += vcpu_cp15(vcpu, c12_VBAR);
+
+	*vcpu_pc(vcpu) = vect_offset;
+}
+
+static void inject_undef32(struct kvm_vcpu *vcpu)
+{
+	prepare_fault32(vcpu, COMPAT_PSR_MODE_UND, 4);
+}
+
+/*
+ * Modelled after TakeDataAbortException() and TakePrefetchAbortException
+ * pseudocode.
+ */
+static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt,
+			 unsigned long addr)
+{
+	u32 vect_offset;
+	u32 *far, *fsr;
+	bool is_lpae;
+
+	if (is_pabt) {
+		vect_offset = 12;
+		far = &vcpu_cp15(vcpu, c6_IFAR);
+		fsr = &vcpu_cp15(vcpu, c5_IFSR);
+	} else { /* !iabt */
+		vect_offset = 16;
+		far = &vcpu_cp15(vcpu, c6_DFAR);
+		fsr = &vcpu_cp15(vcpu, c5_DFSR);
+	}
+
+	prepare_fault32(vcpu, COMPAT_PSR_MODE_ABT | COMPAT_PSR_A_BIT, vect_offset);
+
+	*far = addr;
+
+	/* Give the guest an IMPLEMENTATION DEFINED exception */
+	is_lpae = (vcpu_cp15(vcpu, c2_TTBCR) >> 31);
+	if (is_lpae)
+		*fsr = 1 << 9 | 0x34;
+	else
+		*fsr = 0x14;
+}
+
+static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr)
+{
+	unsigned long cpsr = *vcpu_cpsr(vcpu);
+	bool is_aarch32;
+	u32 esr = 0;
+
+	is_aarch32 = vcpu_mode_is_32bit(vcpu);
+
+	*vcpu_spsr(vcpu) = cpsr;
+	*vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu);
+
+	*vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
+	*vcpu_pc(vcpu) = vcpu_sys_reg(vcpu, VBAR_EL1) + EL1_EXCEPT_SYNC_OFFSET;
+
+	vcpu_sys_reg(vcpu, FAR_EL1) = addr;
+
+	/*
+	 * Build an {i,d}abort, depending on the level and the
+	 * instruction set. Report an external synchronous abort.
+	 */
+	if (kvm_vcpu_trap_il_is32bit(vcpu))
+		esr |= ESR_EL1_IL;
+
+	/*
+	 * Here, the guest runs in AArch64 mode when in EL1. If we get
+	 * an AArch32 fault, it means we managed to trap an EL0 fault.
+	 */
+	if (is_aarch32 || (cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
+		esr |= (ESR_EL1_EC_IABT_EL0 << ESR_EL1_EC_SHIFT);
+	else
+		esr |= (ESR_EL1_EC_IABT_EL1 << ESR_EL1_EC_SHIFT);
+
+	if (!is_iabt)
+		esr |= ESR_EL1_EC_DABT_EL0;
+
+	vcpu_sys_reg(vcpu, ESR_EL1) = esr | ESR_EL2_EC_xABT_xFSR_EXTABT;
+}
+
+static void inject_undef64(struct kvm_vcpu *vcpu)
+{
+	unsigned long cpsr = *vcpu_cpsr(vcpu);
+	u32 esr = (ESR_EL1_EC_UNKNOWN << ESR_EL1_EC_SHIFT);
+
+	*vcpu_spsr(vcpu) = cpsr;
+	*vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu);
+
+	*vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
+	*vcpu_pc(vcpu) = vcpu_sys_reg(vcpu, VBAR_EL1) + EL1_EXCEPT_SYNC_OFFSET;
+
+	/*
+	 * Build an unknown exception, depending on the instruction
+	 * set.
+	 */
+	if (kvm_vcpu_trap_il_is32bit(vcpu))
+		esr |= ESR_EL1_IL;
+
+	vcpu_sys_reg(vcpu, ESR_EL1) = esr;
+}
+
+/**
+ * kvm_inject_dabt - inject a data abort into the guest
+ * @vcpu: The VCPU to receive the undefined exception
+ * @addr: The address to report in the DFAR
+ *
+ * It is assumed that this code is called from the VCPU thread and that the
+ * VCPU therefore is not currently executing guest code.
+ */
+void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr)
+{
+	if (!(vcpu->arch.hcr_el2 & HCR_RW))
+		inject_abt32(vcpu, false, addr);
+
+	inject_abt64(vcpu, false, addr);
+}
+
+/**
+ * kvm_inject_pabt - inject a prefetch abort into the guest
+ * @vcpu: The VCPU to receive the undefined exception
+ * @addr: The address to report in the DFAR
+ *
+ * It is assumed that this code is called from the VCPU thread and that the
+ * VCPU therefore is not currently executing guest code.
+ */
+void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr)
+{
+	if (!(vcpu->arch.hcr_el2 & HCR_RW))
+		inject_abt32(vcpu, true, addr);
+
+	inject_abt64(vcpu, true, addr);
+}
+
+/**
+ * kvm_inject_undefined - inject an undefined instruction into the guest
+ *
+ * It is assumed that this code is called from the VCPU thread and that the
+ * VCPU therefore is not currently executing guest code.
+ */
+void kvm_inject_undefined(struct kvm_vcpu *vcpu)
+{
+	if (!(vcpu->arch.hcr_el2 & HCR_RW))
+		inject_undef32(vcpu);
+
+	inject_undef64(vcpu);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/Kconfig linux-libre-3.11-rc7-gnu/arch/arm64/kvm/Kconfig
--- linux-libre-3.10-gnu/arch/arm64/kvm/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,51 @@
+#
+# KVM configuration
+#
+
+source "virt/kvm/Kconfig"
+
+menuconfig VIRTUALIZATION
+	bool "Virtualization"
+	---help---
+	  Say Y here to get to see options for using your Linux host to run
+	  other operating systems inside virtual machines (guests).
+	  This option alone does not add any kernel code.
+
+	  If you say N, all options in this submenu will be skipped and
+	  disabled.
+
+if VIRTUALIZATION
+
+config KVM
+	bool "Kernel-based Virtual Machine (KVM) support"
+	select MMU_NOTIFIER
+	select PREEMPT_NOTIFIERS
+	select ANON_INODES
+	select KVM_MMIO
+	select KVM_ARM_HOST
+	select KVM_ARM_VGIC
+	select KVM_ARM_TIMER
+	---help---
+	  Support hosting virtualized guest machines.
+
+	  If unsure, say N.
+
+config KVM_ARM_HOST
+	bool
+	---help---
+	  Provides host support for ARM processors.
+
+config KVM_ARM_VGIC
+	bool
+	depends on KVM_ARM_HOST && OF
+	select HAVE_KVM_IRQCHIP
+	---help---
+	  Adds support for a hardware assisted, in-kernel GIC emulation.
+
+config KVM_ARM_TIMER
+	bool
+	depends on KVM_ARM_VGIC
+	---help---
+	  Adds support for the Architected Timers in virtual machines.
+
+endif # VIRTUALIZATION
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/Makefile linux-libre-3.11-rc7-gnu/arch/arm64/kvm/Makefile
--- linux-libre-3.10-gnu/arch/arm64/kvm/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,23 @@
+#
+# Makefile for Kernel-based Virtual Machine module
+#
+
+ccflags-y += -Ivirt/kvm -Iarch/arm64/kvm
+CFLAGS_arm.o := -I.
+CFLAGS_mmu.o := -I.
+
+KVM=../../../virt/kvm
+ARM=../../../arch/arm/kvm
+
+obj-$(CONFIG_KVM_ARM_HOST) += kvm.o
+
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o
+
+kvm-$(CONFIG_KVM_ARM_HOST) += emulate.o inject_fault.o regmap.o
+kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
+kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o
+
+kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o
+kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/regmap.c linux-libre-3.11-rc7-gnu/arch/arm64/kvm/regmap.c
--- linux-libre-3.10-gnu/arch/arm64/kvm/regmap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/regmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/kvm/emulate.c:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/mm.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_emulate.h>
+#include <asm/ptrace.h>
+
+#define VCPU_NR_MODES 6
+#define REG_OFFSET(_reg) \
+	(offsetof(struct user_pt_regs, _reg) / sizeof(unsigned long))
+
+#define USR_REG_OFFSET(R) REG_OFFSET(compat_usr(R))
+
+static const unsigned long vcpu_reg_offsets[VCPU_NR_MODES][16] = {
+	/* USR Registers */
+	{
+		USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+		USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+		USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+		USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+		USR_REG_OFFSET(12), USR_REG_OFFSET(13),	USR_REG_OFFSET(14),
+		REG_OFFSET(pc)
+	},
+
+	/* FIQ Registers */
+	{
+		USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+		USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+		USR_REG_OFFSET(6), USR_REG_OFFSET(7),
+		REG_OFFSET(compat_r8_fiq),  /* r8 */
+		REG_OFFSET(compat_r9_fiq),  /* r9 */
+		REG_OFFSET(compat_r10_fiq), /* r10 */
+		REG_OFFSET(compat_r11_fiq), /* r11 */
+		REG_OFFSET(compat_r12_fiq), /* r12 */
+		REG_OFFSET(compat_sp_fiq),  /* r13 */
+		REG_OFFSET(compat_lr_fiq),  /* r14 */
+		REG_OFFSET(pc)
+	},
+
+	/* IRQ Registers */
+	{
+		USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+		USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+		USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+		USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+		USR_REG_OFFSET(12),
+		REG_OFFSET(compat_sp_irq), /* r13 */
+		REG_OFFSET(compat_lr_irq), /* r14 */
+		REG_OFFSET(pc)
+	},
+
+	/* SVC Registers */
+	{
+		USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+		USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+		USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+		USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+		USR_REG_OFFSET(12),
+		REG_OFFSET(compat_sp_svc), /* r13 */
+		REG_OFFSET(compat_lr_svc), /* r14 */
+		REG_OFFSET(pc)
+	},
+
+	/* ABT Registers */
+	{
+		USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+		USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+		USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+		USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+		USR_REG_OFFSET(12),
+		REG_OFFSET(compat_sp_abt), /* r13 */
+		REG_OFFSET(compat_lr_abt), /* r14 */
+		REG_OFFSET(pc)
+	},
+
+	/* UND Registers */
+	{
+		USR_REG_OFFSET(0), USR_REG_OFFSET(1), USR_REG_OFFSET(2),
+		USR_REG_OFFSET(3), USR_REG_OFFSET(4), USR_REG_OFFSET(5),
+		USR_REG_OFFSET(6), USR_REG_OFFSET(7), USR_REG_OFFSET(8),
+		USR_REG_OFFSET(9), USR_REG_OFFSET(10), USR_REG_OFFSET(11),
+		USR_REG_OFFSET(12),
+		REG_OFFSET(compat_sp_und), /* r13 */
+		REG_OFFSET(compat_lr_und), /* r14 */
+		REG_OFFSET(pc)
+	},
+};
+
+/*
+ * Return a pointer to the register number valid in the current mode of
+ * the virtual CPU.
+ */
+unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num)
+{
+	unsigned long *reg_array = (unsigned long *)&vcpu->arch.ctxt.gp_regs.regs;
+	unsigned long mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
+
+	switch (mode) {
+	case COMPAT_PSR_MODE_USR ... COMPAT_PSR_MODE_SVC:
+		mode &= ~PSR_MODE32_BIT; /* 0 ... 3 */
+		break;
+
+	case COMPAT_PSR_MODE_ABT:
+		mode = 4;
+		break;
+
+	case COMPAT_PSR_MODE_UND:
+		mode = 5;
+		break;
+
+	case COMPAT_PSR_MODE_SYS:
+		mode = 0;	/* SYS maps to USR */
+		break;
+
+	default:
+		BUG();
+	}
+
+	return reg_array + vcpu_reg_offsets[mode][reg_num];
+}
+
+/*
+ * Return the SPSR for the current mode of the virtual CPU.
+ */
+unsigned long *vcpu_spsr32(const struct kvm_vcpu *vcpu)
+{
+	unsigned long mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK;
+	switch (mode) {
+	case COMPAT_PSR_MODE_SVC:
+		mode = KVM_SPSR_SVC;
+		break;
+	case COMPAT_PSR_MODE_ABT:
+		mode = KVM_SPSR_ABT;
+		break;
+	case COMPAT_PSR_MODE_UND:
+		mode = KVM_SPSR_UND;
+		break;
+	case COMPAT_PSR_MODE_IRQ:
+		mode = KVM_SPSR_IRQ;
+		break;
+	case COMPAT_PSR_MODE_FIQ:
+		mode = KVM_SPSR_FIQ;
+		break;
+	default:
+		BUG();
+	}
+
+	return (unsigned long *)&vcpu_gp_regs(vcpu)->spsr[mode];
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/reset.c linux-libre-3.11-rc7-gnu/arch/arm64/kvm/reset.c
--- linux-libre-3.10-gnu/arch/arm64/kvm/reset.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/reset.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/kvm/reset.c
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/errno.h>
+#include <linux/kvm_host.h>
+#include <linux/kvm.h>
+
+#include <kvm/arm_arch_timer.h>
+
+#include <asm/cputype.h>
+#include <asm/ptrace.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_coproc.h>
+
+/*
+ * ARMv8 Reset Values
+ */
+static const struct kvm_regs default_regs_reset = {
+	.regs.pstate = (PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT |
+			PSR_F_BIT | PSR_D_BIT),
+};
+
+static const struct kvm_regs default_regs_reset32 = {
+	.regs.pstate = (COMPAT_PSR_MODE_SVC | COMPAT_PSR_A_BIT |
+			COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT),
+};
+
+static const struct kvm_irq_level default_vtimer_irq = {
+	.irq	= 27,
+	.level	= 1,
+};
+
+static bool cpu_has_32bit_el1(void)
+{
+	u64 pfr0;
+
+	pfr0 = read_cpuid(ID_AA64PFR0_EL1);
+	return !!(pfr0 & 0x20);
+}
+
+int kvm_arch_dev_ioctl_check_extension(long ext)
+{
+	int r;
+
+	switch (ext) {
+	case KVM_CAP_ARM_EL1_32BIT:
+		r = cpu_has_32bit_el1();
+		break;
+	default:
+		r = 0;
+	}
+
+	return r;
+}
+
+/**
+ * kvm_reset_vcpu - sets core registers and sys_regs to reset value
+ * @vcpu: The VCPU pointer
+ *
+ * This function finds the right table above and sets the registers on
+ * the virtual CPU struct to their architectually defined reset
+ * values.
+ */
+int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
+{
+	const struct kvm_irq_level *cpu_vtimer_irq;
+	const struct kvm_regs *cpu_reset;
+
+	switch (vcpu->arch.target) {
+	default:
+		if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
+			if (!cpu_has_32bit_el1())
+				return -EINVAL;
+			cpu_reset = &default_regs_reset32;
+			vcpu->arch.hcr_el2 &= ~HCR_RW;
+		} else {
+			cpu_reset = &default_regs_reset;
+		}
+
+		cpu_vtimer_irq = &default_vtimer_irq;
+		break;
+	}
+
+	/* Reset core registers */
+	memcpy(vcpu_gp_regs(vcpu), cpu_reset, sizeof(*cpu_reset));
+
+	/* Reset system registers */
+	kvm_reset_sys_regs(vcpu);
+
+	/* Reset timer */
+	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/sys_regs.c linux-libre-3.11-rc7-gnu/arch/arm64/kvm/sys_regs.c
--- linux-libre-3.10-gnu/arch/arm64/kvm/sys_regs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/sys_regs.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1053 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/kvm/coproc.c:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Authors: Rusty Russell <rusty@rustcorp.com.au>
+ *          Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/mm.h>
+#include <linux/kvm_host.h>
+#include <linux/uaccess.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_host.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_coproc.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <trace/events/kvm.h>
+
+#include "sys_regs.h"
+
+/*
+ * All of this file is extremly similar to the ARM coproc.c, but the
+ * types are different. My gut feeling is that it should be pretty
+ * easy to merge, but that would be an ABI breakage -- again. VFP
+ * would also need to be abstracted.
+ *
+ * For AArch32, we only take care of what is being trapped. Anything
+ * that has to do with init and userspace access has to go via the
+ * 64bit interface.
+ */
+
+/* 3 bits per cache level, as per CLIDR, but non-existent caches always 0 */
+static u32 cache_levels;
+
+/* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */
+#define CSSELR_MAX 12
+
+/* Which cache CCSIDR represents depends on CSSELR value. */
+static u32 get_ccsidr(u32 csselr)
+{
+	u32 ccsidr;
+
+	/* Make sure noone else changes CSSELR during this! */
+	local_irq_disable();
+	/* Put value into CSSELR */
+	asm volatile("msr csselr_el1, %x0" : : "r" (csselr));
+	isb();
+	/* Read result out of CCSIDR */
+	asm volatile("mrs %0, ccsidr_el1" : "=r" (ccsidr));
+	local_irq_enable();
+
+	return ccsidr;
+}
+
+static void do_dc_cisw(u32 val)
+{
+	asm volatile("dc cisw, %x0" : : "r" (val));
+	dsb();
+}
+
+static void do_dc_csw(u32 val)
+{
+	asm volatile("dc csw, %x0" : : "r" (val));
+	dsb();
+}
+
+/* See note at ARM ARM B1.14.4 */
+static bool access_dcsw(struct kvm_vcpu *vcpu,
+			const struct sys_reg_params *p,
+			const struct sys_reg_desc *r)
+{
+	unsigned long val;
+	int cpu;
+
+	if (!p->is_write)
+		return read_from_write_only(vcpu, p);
+
+	cpu = get_cpu();
+
+	cpumask_setall(&vcpu->arch.require_dcache_flush);
+	cpumask_clear_cpu(cpu, &vcpu->arch.require_dcache_flush);
+
+	/* If we were already preempted, take the long way around */
+	if (cpu != vcpu->arch.last_pcpu) {
+		flush_cache_all();
+		goto done;
+	}
+
+	val = *vcpu_reg(vcpu, p->Rt);
+
+	switch (p->CRm) {
+	case 6:			/* Upgrade DCISW to DCCISW, as per HCR.SWIO */
+	case 14:		/* DCCISW */
+		do_dc_cisw(val);
+		break;
+
+	case 10:		/* DCCSW */
+		do_dc_csw(val);
+		break;
+	}
+
+done:
+	put_cpu();
+
+	return true;
+}
+
+/*
+ * We could trap ID_DFR0 and tell the guest we don't support performance
+ * monitoring.  Unfortunately the patch to make the kernel check ID_DFR0 was
+ * NAKed, so it will read the PMCR anyway.
+ *
+ * Therefore we tell the guest we have 0 counters.  Unfortunately, we
+ * must always support PMCCNTR (the cycle counter): we just RAZ/WI for
+ * all PM registers, which doesn't crash the guest kernel at least.
+ */
+static bool pm_fake(struct kvm_vcpu *vcpu,
+		    const struct sys_reg_params *p,
+		    const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return ignore_write(vcpu, p);
+	else
+		return read_zero(vcpu, p);
+}
+
+static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	u64 amair;
+
+	asm volatile("mrs %0, amair_el1\n" : "=r" (amair));
+	vcpu_sys_reg(vcpu, AMAIR_EL1) = amair;
+}
+
+static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	/*
+	 * Simply map the vcpu_id into the Aff0 field of the MPIDR.
+	 */
+	vcpu_sys_reg(vcpu, MPIDR_EL1) = (1UL << 31) | (vcpu->vcpu_id & 0xff);
+}
+
+/*
+ * Architected system registers.
+ * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
+ */
+static const struct sys_reg_desc sys_reg_descs[] = {
+	/* DC ISW */
+	{ Op0(0b01), Op1(0b000), CRn(0b0111), CRm(0b0110), Op2(0b010),
+	  access_dcsw },
+	/* DC CSW */
+	{ Op0(0b01), Op1(0b000), CRn(0b0111), CRm(0b1010), Op2(0b010),
+	  access_dcsw },
+	/* DC CISW */
+	{ Op0(0b01), Op1(0b000), CRn(0b0111), CRm(0b1110), Op2(0b010),
+	  access_dcsw },
+
+	/* TEECR32_EL1 */
+	{ Op0(0b10), Op1(0b010), CRn(0b0000), CRm(0b0000), Op2(0b000),
+	  NULL, reset_val, TEECR32_EL1, 0 },
+	/* TEEHBR32_EL1 */
+	{ Op0(0b10), Op1(0b010), CRn(0b0001), CRm(0b0000), Op2(0b000),
+	  NULL, reset_val, TEEHBR32_EL1, 0 },
+	/* DBGVCR32_EL2 */
+	{ Op0(0b10), Op1(0b100), CRn(0b0000), CRm(0b0111), Op2(0b000),
+	  NULL, reset_val, DBGVCR32_EL2, 0 },
+
+	/* MPIDR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0000), Op2(0b101),
+	  NULL, reset_mpidr, MPIDR_EL1 },
+	/* SCTLR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b000),
+	  NULL, reset_val, SCTLR_EL1, 0x00C50078 },
+	/* CPACR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b010),
+	  NULL, reset_val, CPACR_EL1, 0 },
+	/* TTBR0_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0010), CRm(0b0000), Op2(0b000),
+	  NULL, reset_unknown, TTBR0_EL1 },
+	/* TTBR1_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0010), CRm(0b0000), Op2(0b001),
+	  NULL, reset_unknown, TTBR1_EL1 },
+	/* TCR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0010), CRm(0b0000), Op2(0b010),
+	  NULL, reset_val, TCR_EL1, 0 },
+
+	/* AFSR0_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0101), CRm(0b0001), Op2(0b000),
+	  NULL, reset_unknown, AFSR0_EL1 },
+	/* AFSR1_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0101), CRm(0b0001), Op2(0b001),
+	  NULL, reset_unknown, AFSR1_EL1 },
+	/* ESR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0101), CRm(0b0010), Op2(0b000),
+	  NULL, reset_unknown, ESR_EL1 },
+	/* FAR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0110), CRm(0b0000), Op2(0b000),
+	  NULL, reset_unknown, FAR_EL1 },
+	/* PAR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0111), CRm(0b0100), Op2(0b000),
+	  NULL, reset_unknown, PAR_EL1 },
+
+	/* PMINTENSET_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b001),
+	  pm_fake },
+	/* PMINTENCLR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b1001), CRm(0b1110), Op2(0b010),
+	  pm_fake },
+
+	/* MAIR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b1010), CRm(0b0010), Op2(0b000),
+	  NULL, reset_unknown, MAIR_EL1 },
+	/* AMAIR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b1010), CRm(0b0011), Op2(0b000),
+	  NULL, reset_amair_el1, AMAIR_EL1 },
+
+	/* VBAR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b0000), Op2(0b000),
+	  NULL, reset_val, VBAR_EL1, 0 },
+	/* CONTEXTIDR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b001),
+	  NULL, reset_val, CONTEXTIDR_EL1, 0 },
+	/* TPIDR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b100),
+	  NULL, reset_unknown, TPIDR_EL1 },
+
+	/* CNTKCTL_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b1110), CRm(0b0001), Op2(0b000),
+	  NULL, reset_val, CNTKCTL_EL1, 0},
+
+	/* CSSELR_EL1 */
+	{ Op0(0b11), Op1(0b010), CRn(0b0000), CRm(0b0000), Op2(0b000),
+	  NULL, reset_unknown, CSSELR_EL1 },
+
+	/* PMCR_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b000),
+	  pm_fake },
+	/* PMCNTENSET_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b001),
+	  pm_fake },
+	/* PMCNTENCLR_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b010),
+	  pm_fake },
+	/* PMOVSCLR_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b011),
+	  pm_fake },
+	/* PMSWINC_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b100),
+	  pm_fake },
+	/* PMSELR_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b101),
+	  pm_fake },
+	/* PMCEID0_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110),
+	  pm_fake },
+	/* PMCEID1_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111),
+	  pm_fake },
+	/* PMCCNTR_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000),
+	  pm_fake },
+	/* PMXEVTYPER_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001),
+	  pm_fake },
+	/* PMXEVCNTR_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010),
+	  pm_fake },
+	/* PMUSERENR_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000),
+	  pm_fake },
+	/* PMOVSSET_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011),
+	  pm_fake },
+
+	/* TPIDR_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b010),
+	  NULL, reset_unknown, TPIDR_EL0 },
+	/* TPIDRRO_EL0 */
+	{ Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b011),
+	  NULL, reset_unknown, TPIDRRO_EL0 },
+
+	/* DACR32_EL2 */
+	{ Op0(0b11), Op1(0b100), CRn(0b0011), CRm(0b0000), Op2(0b000),
+	  NULL, reset_unknown, DACR32_EL2 },
+	/* IFSR32_EL2 */
+	{ Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0000), Op2(0b001),
+	  NULL, reset_unknown, IFSR32_EL2 },
+	/* FPEXC32_EL2 */
+	{ Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0011), Op2(0b000),
+	  NULL, reset_val, FPEXC32_EL2, 0x70 },
+};
+
+/* Trapped cp15 registers */
+static const struct sys_reg_desc cp15_regs[] = {
+	/*
+	 * DC{C,I,CI}SW operations:
+	 */
+	{ Op1( 0), CRn( 7), CRm( 6), Op2( 2), access_dcsw },
+	{ Op1( 0), CRn( 7), CRm(10), Op2( 2), access_dcsw },
+	{ Op1( 0), CRn( 7), CRm(14), Op2( 2), access_dcsw },
+	{ Op1( 0), CRn( 9), CRm(12), Op2( 0), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(12), Op2( 1), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(12), Op2( 2), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(12), Op2( 3), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(12), Op2( 5), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(12), Op2( 6), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(12), Op2( 7), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(13), Op2( 0), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(13), Op2( 1), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(13), Op2( 2), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(14), Op2( 0), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(14), Op2( 1), pm_fake },
+	{ Op1( 0), CRn( 9), CRm(14), Op2( 2), pm_fake },
+};
+
+/* Target specific emulation tables */
+static struct kvm_sys_reg_target_table *target_tables[KVM_ARM_NUM_TARGETS];
+
+void kvm_register_target_sys_reg_table(unsigned int target,
+				       struct kvm_sys_reg_target_table *table)
+{
+	target_tables[target] = table;
+}
+
+/* Get specific register table for this target. */
+static const struct sys_reg_desc *get_target_table(unsigned target,
+						   bool mode_is_64,
+						   size_t *num)
+{
+	struct kvm_sys_reg_target_table *table;
+
+	table = target_tables[target];
+	if (mode_is_64) {
+		*num = table->table64.num;
+		return table->table64.table;
+	} else {
+		*num = table->table32.num;
+		return table->table32.table;
+	}
+}
+
+static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params,
+					 const struct sys_reg_desc table[],
+					 unsigned int num)
+{
+	unsigned int i;
+
+	for (i = 0; i < num; i++) {
+		const struct sys_reg_desc *r = &table[i];
+
+		if (params->Op0 != r->Op0)
+			continue;
+		if (params->Op1 != r->Op1)
+			continue;
+		if (params->CRn != r->CRn)
+			continue;
+		if (params->CRm != r->CRm)
+			continue;
+		if (params->Op2 != r->Op2)
+			continue;
+
+		return r;
+	}
+	return NULL;
+}
+
+int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	kvm_inject_undefined(vcpu);
+	return 1;
+}
+
+int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	kvm_inject_undefined(vcpu);
+	return 1;
+}
+
+static void emulate_cp15(struct kvm_vcpu *vcpu,
+			 const struct sys_reg_params *params)
+{
+	size_t num;
+	const struct sys_reg_desc *table, *r;
+
+	table = get_target_table(vcpu->arch.target, false, &num);
+
+	/* Search target-specific then generic table. */
+	r = find_reg(params, table, num);
+	if (!r)
+		r = find_reg(params, cp15_regs, ARRAY_SIZE(cp15_regs));
+
+	if (likely(r)) {
+		/*
+		 * Not having an accessor means that we have
+		 * configured a trap that we don't know how to
+		 * handle. This certainly qualifies as a gross bug
+		 * that should be fixed right away.
+		 */
+		BUG_ON(!r->access);
+
+		if (likely(r->access(vcpu, params, r))) {
+			/* Skip instruction, since it was emulated */
+			kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+			return;
+		}
+		/* If access function fails, it should complain. */
+	}
+
+	kvm_err("Unsupported guest CP15 access at: %08lx\n", *vcpu_pc(vcpu));
+	print_sys_reg_instr(params);
+	kvm_inject_undefined(vcpu);
+}
+
+/**
+ * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	struct sys_reg_params params;
+	u32 hsr = kvm_vcpu_get_hsr(vcpu);
+	int Rt2 = (hsr >> 10) & 0xf;
+
+	params.CRm = (hsr >> 1) & 0xf;
+	params.Rt = (hsr >> 5) & 0xf;
+	params.is_write = ((hsr & 1) == 0);
+
+	params.Op0 = 0;
+	params.Op1 = (hsr >> 16) & 0xf;
+	params.Op2 = 0;
+	params.CRn = 0;
+
+	/*
+	 * Massive hack here. Store Rt2 in the top 32bits so we only
+	 * have one register to deal with. As we use the same trap
+	 * backends between AArch32 and AArch64, we get away with it.
+	 */
+	if (params.is_write) {
+		u64 val = *vcpu_reg(vcpu, params.Rt);
+		val &= 0xffffffff;
+		val |= *vcpu_reg(vcpu, Rt2) << 32;
+		*vcpu_reg(vcpu, params.Rt) = val;
+	}
+
+	emulate_cp15(vcpu, &params);
+
+	/* Do the opposite hack for the read side */
+	if (!params.is_write) {
+		u64 val = *vcpu_reg(vcpu, params.Rt);
+		val >>= 32;
+		*vcpu_reg(vcpu, Rt2) = val;
+	}
+
+	return 1;
+}
+
+/**
+ * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	struct sys_reg_params params;
+	u32 hsr = kvm_vcpu_get_hsr(vcpu);
+
+	params.CRm = (hsr >> 1) & 0xf;
+	params.Rt  = (hsr >> 5) & 0xf;
+	params.is_write = ((hsr & 1) == 0);
+	params.CRn = (hsr >> 10) & 0xf;
+	params.Op0 = 0;
+	params.Op1 = (hsr >> 14) & 0x7;
+	params.Op2 = (hsr >> 17) & 0x7;
+
+	emulate_cp15(vcpu, &params);
+	return 1;
+}
+
+static int emulate_sys_reg(struct kvm_vcpu *vcpu,
+			   const struct sys_reg_params *params)
+{
+	size_t num;
+	const struct sys_reg_desc *table, *r;
+
+	table = get_target_table(vcpu->arch.target, true, &num);
+
+	/* Search target-specific then generic table. */
+	r = find_reg(params, table, num);
+	if (!r)
+		r = find_reg(params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
+
+	if (likely(r)) {
+		/*
+		 * Not having an accessor means that we have
+		 * configured a trap that we don't know how to
+		 * handle. This certainly qualifies as a gross bug
+		 * that should be fixed right away.
+		 */
+		BUG_ON(!r->access);
+
+		if (likely(r->access(vcpu, params, r))) {
+			/* Skip instruction, since it was emulated */
+			kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+			return 1;
+		}
+		/* If access function fails, it should complain. */
+	} else {
+		kvm_err("Unsupported guest sys_reg access at: %lx\n",
+			*vcpu_pc(vcpu));
+		print_sys_reg_instr(params);
+	}
+	kvm_inject_undefined(vcpu);
+	return 1;
+}
+
+static void reset_sys_reg_descs(struct kvm_vcpu *vcpu,
+			      const struct sys_reg_desc *table, size_t num)
+{
+	unsigned long i;
+
+	for (i = 0; i < num; i++)
+		if (table[i].reset)
+			table[i].reset(vcpu, &table[i]);
+}
+
+/**
+ * kvm_handle_sys_reg -- handles a mrs/msr trap on a guest sys_reg access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	struct sys_reg_params params;
+	unsigned long esr = kvm_vcpu_get_hsr(vcpu);
+
+	params.Op0 = (esr >> 20) & 3;
+	params.Op1 = (esr >> 14) & 0x7;
+	params.CRn = (esr >> 10) & 0xf;
+	params.CRm = (esr >> 1) & 0xf;
+	params.Op2 = (esr >> 17) & 0x7;
+	params.Rt = (esr >> 5) & 0x1f;
+	params.is_write = !(esr & 1);
+
+	return emulate_sys_reg(vcpu, &params);
+}
+
+/******************************************************************************
+ * Userspace API
+ *****************************************************************************/
+
+static bool index_to_params(u64 id, struct sys_reg_params *params)
+{
+	switch (id & KVM_REG_SIZE_MASK) {
+	case KVM_REG_SIZE_U64:
+		/* Any unused index bits means it's not valid. */
+		if (id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK
+			      | KVM_REG_ARM_COPROC_MASK
+			      | KVM_REG_ARM64_SYSREG_OP0_MASK
+			      | KVM_REG_ARM64_SYSREG_OP1_MASK
+			      | KVM_REG_ARM64_SYSREG_CRN_MASK
+			      | KVM_REG_ARM64_SYSREG_CRM_MASK
+			      | KVM_REG_ARM64_SYSREG_OP2_MASK))
+			return false;
+		params->Op0 = ((id & KVM_REG_ARM64_SYSREG_OP0_MASK)
+			       >> KVM_REG_ARM64_SYSREG_OP0_SHIFT);
+		params->Op1 = ((id & KVM_REG_ARM64_SYSREG_OP1_MASK)
+			       >> KVM_REG_ARM64_SYSREG_OP1_SHIFT);
+		params->CRn = ((id & KVM_REG_ARM64_SYSREG_CRN_MASK)
+			       >> KVM_REG_ARM64_SYSREG_CRN_SHIFT);
+		params->CRm = ((id & KVM_REG_ARM64_SYSREG_CRM_MASK)
+			       >> KVM_REG_ARM64_SYSREG_CRM_SHIFT);
+		params->Op2 = ((id & KVM_REG_ARM64_SYSREG_OP2_MASK)
+			       >> KVM_REG_ARM64_SYSREG_OP2_SHIFT);
+		return true;
+	default:
+		return false;
+	}
+}
+
+/* Decode an index value, and find the sys_reg_desc entry. */
+static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu,
+						    u64 id)
+{
+	size_t num;
+	const struct sys_reg_desc *table, *r;
+	struct sys_reg_params params;
+
+	/* We only do sys_reg for now. */
+	if ((id & KVM_REG_ARM_COPROC_MASK) != KVM_REG_ARM64_SYSREG)
+		return NULL;
+
+	if (!index_to_params(id, &params))
+		return NULL;
+
+	table = get_target_table(vcpu->arch.target, true, &num);
+	r = find_reg(&params, table, num);
+	if (!r)
+		r = find_reg(&params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
+
+	/* Not saved in the sys_reg array? */
+	if (r && !r->reg)
+		r = NULL;
+
+	return r;
+}
+
+/*
+ * These are the invariant sys_reg registers: we let the guest see the
+ * host versions of these, so they're part of the guest state.
+ *
+ * A future CPU may provide a mechanism to present different values to
+ * the guest, or a future kvm may trap them.
+ */
+
+#define FUNCTION_INVARIANT(reg)						\
+	static void get_##reg(struct kvm_vcpu *v,			\
+			      const struct sys_reg_desc *r)		\
+	{								\
+		u64 val;						\
+									\
+		asm volatile("mrs %0, " __stringify(reg) "\n"		\
+			     : "=r" (val));				\
+		((struct sys_reg_desc *)r)->val = val;			\
+	}
+
+FUNCTION_INVARIANT(midr_el1)
+FUNCTION_INVARIANT(ctr_el0)
+FUNCTION_INVARIANT(revidr_el1)
+FUNCTION_INVARIANT(id_pfr0_el1)
+FUNCTION_INVARIANT(id_pfr1_el1)
+FUNCTION_INVARIANT(id_dfr0_el1)
+FUNCTION_INVARIANT(id_afr0_el1)
+FUNCTION_INVARIANT(id_mmfr0_el1)
+FUNCTION_INVARIANT(id_mmfr1_el1)
+FUNCTION_INVARIANT(id_mmfr2_el1)
+FUNCTION_INVARIANT(id_mmfr3_el1)
+FUNCTION_INVARIANT(id_isar0_el1)
+FUNCTION_INVARIANT(id_isar1_el1)
+FUNCTION_INVARIANT(id_isar2_el1)
+FUNCTION_INVARIANT(id_isar3_el1)
+FUNCTION_INVARIANT(id_isar4_el1)
+FUNCTION_INVARIANT(id_isar5_el1)
+FUNCTION_INVARIANT(clidr_el1)
+FUNCTION_INVARIANT(aidr_el1)
+
+/* ->val is filled in by kvm_sys_reg_table_init() */
+static struct sys_reg_desc invariant_sys_regs[] = {
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0000), Op2(0b000),
+	  NULL, get_midr_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0000), Op2(0b110),
+	  NULL, get_revidr_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b000),
+	  NULL, get_id_pfr0_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b001),
+	  NULL, get_id_pfr1_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b010),
+	  NULL, get_id_dfr0_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b011),
+	  NULL, get_id_afr0_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b100),
+	  NULL, get_id_mmfr0_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b101),
+	  NULL, get_id_mmfr1_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b110),
+	  NULL, get_id_mmfr2_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0001), Op2(0b111),
+	  NULL, get_id_mmfr3_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b000),
+	  NULL, get_id_isar0_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b001),
+	  NULL, get_id_isar1_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b010),
+	  NULL, get_id_isar2_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b011),
+	  NULL, get_id_isar3_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b100),
+	  NULL, get_id_isar4_el1 },
+	{ Op0(0b11), Op1(0b000), CRn(0b0000), CRm(0b0010), Op2(0b101),
+	  NULL, get_id_isar5_el1 },
+	{ Op0(0b11), Op1(0b001), CRn(0b0000), CRm(0b0000), Op2(0b001),
+	  NULL, get_clidr_el1 },
+	{ Op0(0b11), Op1(0b001), CRn(0b0000), CRm(0b0000), Op2(0b111),
+	  NULL, get_aidr_el1 },
+	{ Op0(0b11), Op1(0b011), CRn(0b0000), CRm(0b0000), Op2(0b001),
+	  NULL, get_ctr_el0 },
+};
+
+static int reg_from_user(void *val, const void __user *uaddr, u64 id)
+{
+	/* This Just Works because we are little endian. */
+	if (copy_from_user(val, uaddr, KVM_REG_SIZE(id)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
+static int reg_to_user(void __user *uaddr, const void *val, u64 id)
+{
+	/* This Just Works because we are little endian. */
+	if (copy_to_user(uaddr, val, KVM_REG_SIZE(id)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
+static int get_invariant_sys_reg(u64 id, void __user *uaddr)
+{
+	struct sys_reg_params params;
+	const struct sys_reg_desc *r;
+
+	if (!index_to_params(id, &params))
+		return -ENOENT;
+
+	r = find_reg(&params, invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs));
+	if (!r)
+		return -ENOENT;
+
+	return reg_to_user(uaddr, &r->val, id);
+}
+
+static int set_invariant_sys_reg(u64 id, void __user *uaddr)
+{
+	struct sys_reg_params params;
+	const struct sys_reg_desc *r;
+	int err;
+	u64 val = 0; /* Make sure high bits are 0 for 32-bit regs */
+
+	if (!index_to_params(id, &params))
+		return -ENOENT;
+	r = find_reg(&params, invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs));
+	if (!r)
+		return -ENOENT;
+
+	err = reg_from_user(&val, uaddr, id);
+	if (err)
+		return err;
+
+	/* This is what we mean by invariant: you can't change it. */
+	if (r->val != val)
+		return -EINVAL;
+
+	return 0;
+}
+
+static bool is_valid_cache(u32 val)
+{
+	u32 level, ctype;
+
+	if (val >= CSSELR_MAX)
+		return -ENOENT;
+
+	/* Bottom bit is Instruction or Data bit.  Next 3 bits are level. */
+	level = (val >> 1);
+	ctype = (cache_levels >> (level * 3)) & 7;
+
+	switch (ctype) {
+	case 0: /* No cache */
+		return false;
+	case 1: /* Instruction cache only */
+		return (val & 1);
+	case 2: /* Data cache only */
+	case 4: /* Unified cache */
+		return !(val & 1);
+	case 3: /* Separate instruction and data caches */
+		return true;
+	default: /* Reserved: we can't know instruction or data. */
+		return false;
+	}
+}
+
+static int demux_c15_get(u64 id, void __user *uaddr)
+{
+	u32 val;
+	u32 __user *uval = uaddr;
+
+	/* Fail if we have unknown bits set. */
+	if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK
+		   | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1)))
+		return -ENOENT;
+
+	switch (id & KVM_REG_ARM_DEMUX_ID_MASK) {
+	case KVM_REG_ARM_DEMUX_ID_CCSIDR:
+		if (KVM_REG_SIZE(id) != 4)
+			return -ENOENT;
+		val = (id & KVM_REG_ARM_DEMUX_VAL_MASK)
+			>> KVM_REG_ARM_DEMUX_VAL_SHIFT;
+		if (!is_valid_cache(val))
+			return -ENOENT;
+
+		return put_user(get_ccsidr(val), uval);
+	default:
+		return -ENOENT;
+	}
+}
+
+static int demux_c15_set(u64 id, void __user *uaddr)
+{
+	u32 val, newval;
+	u32 __user *uval = uaddr;
+
+	/* Fail if we have unknown bits set. */
+	if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK
+		   | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1)))
+		return -ENOENT;
+
+	switch (id & KVM_REG_ARM_DEMUX_ID_MASK) {
+	case KVM_REG_ARM_DEMUX_ID_CCSIDR:
+		if (KVM_REG_SIZE(id) != 4)
+			return -ENOENT;
+		val = (id & KVM_REG_ARM_DEMUX_VAL_MASK)
+			>> KVM_REG_ARM_DEMUX_VAL_SHIFT;
+		if (!is_valid_cache(val))
+			return -ENOENT;
+
+		if (get_user(newval, uval))
+			return -EFAULT;
+
+		/* This is also invariant: you can't change it. */
+		if (newval != get_ccsidr(val))
+			return -EINVAL;
+		return 0;
+	default:
+		return -ENOENT;
+	}
+}
+
+int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	const struct sys_reg_desc *r;
+	void __user *uaddr = (void __user *)(unsigned long)reg->addr;
+
+	if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX)
+		return demux_c15_get(reg->id, uaddr);
+
+	if (KVM_REG_SIZE(reg->id) != sizeof(__u64))
+		return -ENOENT;
+
+	r = index_to_sys_reg_desc(vcpu, reg->id);
+	if (!r)
+		return get_invariant_sys_reg(reg->id, uaddr);
+
+	return reg_to_user(uaddr, &vcpu_sys_reg(vcpu, r->reg), reg->id);
+}
+
+int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	const struct sys_reg_desc *r;
+	void __user *uaddr = (void __user *)(unsigned long)reg->addr;
+
+	if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX)
+		return demux_c15_set(reg->id, uaddr);
+
+	if (KVM_REG_SIZE(reg->id) != sizeof(__u64))
+		return -ENOENT;
+
+	r = index_to_sys_reg_desc(vcpu, reg->id);
+	if (!r)
+		return set_invariant_sys_reg(reg->id, uaddr);
+
+	return reg_from_user(&vcpu_sys_reg(vcpu, r->reg), uaddr, reg->id);
+}
+
+static unsigned int num_demux_regs(void)
+{
+	unsigned int i, count = 0;
+
+	for (i = 0; i < CSSELR_MAX; i++)
+		if (is_valid_cache(i))
+			count++;
+
+	return count;
+}
+
+static int write_demux_regids(u64 __user *uindices)
+{
+	u64 val = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX;
+	unsigned int i;
+
+	val |= KVM_REG_ARM_DEMUX_ID_CCSIDR;
+	for (i = 0; i < CSSELR_MAX; i++) {
+		if (!is_valid_cache(i))
+			continue;
+		if (put_user(val | i, uindices))
+			return -EFAULT;
+		uindices++;
+	}
+	return 0;
+}
+
+static u64 sys_reg_to_index(const struct sys_reg_desc *reg)
+{
+	return (KVM_REG_ARM64 | KVM_REG_SIZE_U64 |
+		KVM_REG_ARM64_SYSREG |
+		(reg->Op0 << KVM_REG_ARM64_SYSREG_OP0_SHIFT) |
+		(reg->Op1 << KVM_REG_ARM64_SYSREG_OP1_SHIFT) |
+		(reg->CRn << KVM_REG_ARM64_SYSREG_CRN_SHIFT) |
+		(reg->CRm << KVM_REG_ARM64_SYSREG_CRM_SHIFT) |
+		(reg->Op2 << KVM_REG_ARM64_SYSREG_OP2_SHIFT));
+}
+
+static bool copy_reg_to_user(const struct sys_reg_desc *reg, u64 __user **uind)
+{
+	if (!*uind)
+		return true;
+
+	if (put_user(sys_reg_to_index(reg), *uind))
+		return false;
+
+	(*uind)++;
+	return true;
+}
+
+/* Assumed ordered tables, see kvm_sys_reg_table_init. */
+static int walk_sys_regs(struct kvm_vcpu *vcpu, u64 __user *uind)
+{
+	const struct sys_reg_desc *i1, *i2, *end1, *end2;
+	unsigned int total = 0;
+	size_t num;
+
+	/* We check for duplicates here, to allow arch-specific overrides. */
+	i1 = get_target_table(vcpu->arch.target, true, &num);
+	end1 = i1 + num;
+	i2 = sys_reg_descs;
+	end2 = sys_reg_descs + ARRAY_SIZE(sys_reg_descs);
+
+	BUG_ON(i1 == end1 || i2 == end2);
+
+	/* Walk carefully, as both tables may refer to the same register. */
+	while (i1 || i2) {
+		int cmp = cmp_sys_reg(i1, i2);
+		/* target-specific overrides generic entry. */
+		if (cmp <= 0) {
+			/* Ignore registers we trap but don't save. */
+			if (i1->reg) {
+				if (!copy_reg_to_user(i1, &uind))
+					return -EFAULT;
+				total++;
+			}
+		} else {
+			/* Ignore registers we trap but don't save. */
+			if (i2->reg) {
+				if (!copy_reg_to_user(i2, &uind))
+					return -EFAULT;
+				total++;
+			}
+		}
+
+		if (cmp <= 0 && ++i1 == end1)
+			i1 = NULL;
+		if (cmp >= 0 && ++i2 == end2)
+			i2 = NULL;
+	}
+	return total;
+}
+
+unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu)
+{
+	return ARRAY_SIZE(invariant_sys_regs)
+		+ num_demux_regs()
+		+ walk_sys_regs(vcpu, (u64 __user *)NULL);
+}
+
+int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+	unsigned int i;
+	int err;
+
+	/* Then give them all the invariant registers' indices. */
+	for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++) {
+		if (put_user(sys_reg_to_index(&invariant_sys_regs[i]), uindices))
+			return -EFAULT;
+		uindices++;
+	}
+
+	err = walk_sys_regs(vcpu, uindices);
+	if (err < 0)
+		return err;
+	uindices += err;
+
+	return write_demux_regids(uindices);
+}
+
+void kvm_sys_reg_table_init(void)
+{
+	unsigned int i;
+	struct sys_reg_desc clidr;
+
+	/* Make sure tables are unique and in order. */
+	for (i = 1; i < ARRAY_SIZE(sys_reg_descs); i++)
+		BUG_ON(cmp_sys_reg(&sys_reg_descs[i-1], &sys_reg_descs[i]) >= 0);
+
+	/* We abuse the reset function to overwrite the table itself. */
+	for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++)
+		invariant_sys_regs[i].reset(NULL, &invariant_sys_regs[i]);
+
+	/*
+	 * CLIDR format is awkward, so clean it up.  See ARM B4.1.20:
+	 *
+	 *   If software reads the Cache Type fields from Ctype1
+	 *   upwards, once it has seen a value of 0b000, no caches
+	 *   exist at further-out levels of the hierarchy. So, for
+	 *   example, if Ctype3 is the first Cache Type field with a
+	 *   value of 0b000, the values of Ctype4 to Ctype7 must be
+	 *   ignored.
+	 */
+	get_clidr_el1(NULL, &clidr); /* Ugly... */
+	cache_levels = clidr.val;
+	for (i = 0; i < 7; i++)
+		if (((cache_levels >> (i*3)) & 7) == 0)
+			break;
+	/* Clear all higher bits. */
+	cache_levels &= (1 << (i*3))-1;
+}
+
+/**
+ * kvm_reset_sys_regs - sets system registers to reset value
+ * @vcpu: The VCPU pointer
+ *
+ * This function finds the right table above and sets the registers on the
+ * virtual CPU struct to their architecturally defined reset values.
+ */
+void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
+{
+	size_t num;
+	const struct sys_reg_desc *table;
+
+	/* Catch someone adding a register without putting in reset entry. */
+	memset(&vcpu->arch.ctxt.sys_regs, 0x42, sizeof(vcpu->arch.ctxt.sys_regs));
+
+	/* Generic chip reset first (so target could override). */
+	reset_sys_reg_descs(vcpu, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
+
+	table = get_target_table(vcpu->arch.target, true, &num);
+	reset_sys_reg_descs(vcpu, table, num);
+
+	for (num = 1; num < NR_SYS_REGS; num++)
+		if (vcpu_sys_reg(vcpu, num) == 0x4242424242424242)
+			panic("Didn't reset vcpu_sys_reg(%zi)", num);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/sys_regs_generic_v8.c linux-libre-3.11-rc7-gnu/arch/arm64/kvm/sys_regs_generic_v8.c
--- linux-libre-3.10-gnu/arch/arm64/kvm/sys_regs_generic_v8.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/sys_regs_generic_v8.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Based on arch/arm/kvm/coproc_a15.c:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Authors: Rusty Russell <rusty@rustcorp.au>
+ *          Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kvm_host.h>
+#include <asm/cputype.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_host.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_coproc.h>
+#include <linux/init.h>
+
+#include "sys_regs.h"
+
+static bool access_actlr(struct kvm_vcpu *vcpu,
+			 const struct sys_reg_params *p,
+			 const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return ignore_write(vcpu, p);
+
+	*vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, ACTLR_EL1);
+	return true;
+}
+
+static void reset_actlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	u64 actlr;
+
+	asm volatile("mrs %0, actlr_el1\n" : "=r" (actlr));
+	vcpu_sys_reg(vcpu, ACTLR_EL1) = actlr;
+}
+
+/*
+ * Implementation specific sys-reg registers.
+ * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
+ */
+static const struct sys_reg_desc genericv8_sys_regs[] = {
+	/* ACTLR_EL1 */
+	{ Op0(0b11), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001),
+	  access_actlr, reset_actlr, ACTLR_EL1 },
+};
+
+static const struct sys_reg_desc genericv8_cp15_regs[] = {
+	/* ACTLR */
+	{ Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001),
+	  access_actlr },
+};
+
+static struct kvm_sys_reg_target_table genericv8_target_table = {
+	.table64 = {
+		.table = genericv8_sys_regs,
+		.num = ARRAY_SIZE(genericv8_sys_regs),
+	},
+	.table32 = {
+		.table = genericv8_cp15_regs,
+		.num = ARRAY_SIZE(genericv8_cp15_regs),
+	},
+};
+
+static int __init sys_reg_genericv8_init(void)
+{
+	unsigned int i;
+
+	for (i = 1; i < ARRAY_SIZE(genericv8_sys_regs); i++)
+		BUG_ON(cmp_sys_reg(&genericv8_sys_regs[i-1],
+			       &genericv8_sys_regs[i]) >= 0);
+
+	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_AEM_V8,
+					  &genericv8_target_table);
+	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_FOUNDATION_V8,
+					  &genericv8_target_table);
+	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_CORTEX_A57,
+					  &genericv8_target_table);
+	return 0;
+}
+late_initcall(sys_reg_genericv8_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/kvm/sys_regs.h linux-libre-3.11-rc7-gnu/arch/arm64/kvm/sys_regs.h
--- linux-libre-3.10-gnu/arch/arm64/kvm/sys_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/kvm/sys_regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Derived from arch/arm/kvm/coproc.h
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Authors: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__
+#define __ARM64_KVM_SYS_REGS_LOCAL_H__
+
+struct sys_reg_params {
+	u8	Op0;
+	u8	Op1;
+	u8	CRn;
+	u8	CRm;
+	u8	Op2;
+	u8	Rt;
+	bool	is_write;
+};
+
+struct sys_reg_desc {
+	/* MRS/MSR instruction which accesses it. */
+	u8	Op0;
+	u8	Op1;
+	u8	CRn;
+	u8	CRm;
+	u8	Op2;
+
+	/* Trapped access from guest, if non-NULL. */
+	bool (*access)(struct kvm_vcpu *,
+		       const struct sys_reg_params *,
+		       const struct sys_reg_desc *);
+
+	/* Initialization for vcpu. */
+	void (*reset)(struct kvm_vcpu *, const struct sys_reg_desc *);
+
+	/* Index into sys_reg[], or 0 if we don't need to save it. */
+	int reg;
+
+	/* Value (usually reset value) */
+	u64 val;
+};
+
+static inline void print_sys_reg_instr(const struct sys_reg_params *p)
+{
+	/* Look, we even formatted it for you to paste into the table! */
+	kvm_pr_unimpl(" { Op0(%2u), Op1(%2u), CRn(%2u), CRm(%2u), Op2(%2u), func_%s },\n",
+		      p->Op0, p->Op1, p->CRn, p->CRm, p->Op2, p->is_write ? "write" : "read");
+}
+
+static inline bool ignore_write(struct kvm_vcpu *vcpu,
+				const struct sys_reg_params *p)
+{
+	return true;
+}
+
+static inline bool read_zero(struct kvm_vcpu *vcpu,
+			     const struct sys_reg_params *p)
+{
+	*vcpu_reg(vcpu, p->Rt) = 0;
+	return true;
+}
+
+static inline bool write_to_read_only(struct kvm_vcpu *vcpu,
+				      const struct sys_reg_params *params)
+{
+	kvm_debug("sys_reg write to read-only register at: %lx\n",
+		  *vcpu_pc(vcpu));
+	print_sys_reg_instr(params);
+	return false;
+}
+
+static inline bool read_from_write_only(struct kvm_vcpu *vcpu,
+					const struct sys_reg_params *params)
+{
+	kvm_debug("sys_reg read to write-only register at: %lx\n",
+		  *vcpu_pc(vcpu));
+	print_sys_reg_instr(params);
+	return false;
+}
+
+/* Reset functions */
+static inline void reset_unknown(struct kvm_vcpu *vcpu,
+				 const struct sys_reg_desc *r)
+{
+	BUG_ON(!r->reg);
+	BUG_ON(r->reg >= NR_SYS_REGS);
+	vcpu_sys_reg(vcpu, r->reg) = 0x1de7ec7edbadc0deULL;
+}
+
+static inline void reset_val(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	BUG_ON(!r->reg);
+	BUG_ON(r->reg >= NR_SYS_REGS);
+	vcpu_sys_reg(vcpu, r->reg) = r->val;
+}
+
+static inline int cmp_sys_reg(const struct sys_reg_desc *i1,
+			      const struct sys_reg_desc *i2)
+{
+	BUG_ON(i1 == i2);
+	if (!i1)
+		return 1;
+	else if (!i2)
+		return -1;
+	if (i1->Op0 != i2->Op0)
+		return i1->Op0 - i2->Op0;
+	if (i1->Op1 != i2->Op1)
+		return i1->Op1 - i2->Op1;
+	if (i1->CRn != i2->CRn)
+		return i1->CRn - i2->CRn;
+	if (i1->CRm != i2->CRm)
+		return i1->CRm - i2->CRm;
+	return i1->Op2 - i2->Op2;
+}
+
+
+#define Op0(_x) 	.Op0 = _x
+#define Op1(_x) 	.Op1 = _x
+#define CRn(_x)		.CRn = _x
+#define CRm(_x) 	.CRm = _x
+#define Op2(_x) 	.Op2 = _x
+
+#endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/Makefile linux-libre-3.11-rc7-gnu/arch/arm64/Makefile
--- linux-libre-3.10-gnu/arch/arm64/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -37,6 +37,8 @@ TEXT_OFFSET := 0x00080000
 export	TEXT_OFFSET GZFLAGS
 
 core-y		+= arch/arm64/kernel/ arch/arm64/mm/
+core-$(CONFIG_KVM) += arch/arm64/kvm/
+core-$(CONFIG_XEN) += arch/arm64/xen/
 libs-y		:= arch/arm64/lib/ $(libs-y)
 libs-y		+= $(LIBGCC)
 
@@ -60,6 +62,10 @@ zinstall install: vmlinux
 dtbs: scripts
 	$(Q)$(MAKE) $(build)=$(boot)/dts dtbs
 
+PHONY += vdso_install
+vdso_install:
+	$(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso $@
+
 # We use MRPROPER_FILES and CLEAN_FILES now
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/mm/fault.c linux-libre-3.11-rc7-gnu/arch/arm64/mm/fault.c
--- linux-libre-3.10-gnu/arch/arm64/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -152,25 +152,8 @@ void do_bad_area(unsigned long addr, uns
 #define ESR_CM			(1 << 8)
 #define ESR_LNX_EXEC		(1 << 24)
 
-/*
- * Check that the permissions on the VMA allow for the fault which occurred.
- * If we encountered a write fault, we must have write permission, otherwise
- * we allow any permission.
- */
-static inline bool access_error(unsigned int esr, struct vm_area_struct *vma)
-{
-	unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
-
-	if (esr & ESR_WRITE)
-		mask = VM_WRITE;
-	if (esr & ESR_LNX_EXEC)
-		mask = VM_EXEC;
-
-	return vma->vm_flags & mask ? false : true;
-}
-
 static int __do_page_fault(struct mm_struct *mm, unsigned long addr,
-			   unsigned int esr, unsigned int flags,
+			   unsigned int mm_flags, unsigned long vm_flags,
 			   struct task_struct *tsk)
 {
 	struct vm_area_struct *vma;
@@ -188,12 +171,17 @@ static int __do_page_fault(struct mm_str
 	 * it.
 	 */
 good_area:
-	if (access_error(esr, vma)) {
+	/*
+	 * Check that the permissions on the VMA allow for the fault which
+	 * occurred. If we encountered a write or exec fault, we must have
+	 * appropriate permissions, otherwise we allow any permission.
+	 */
+	if (!(vma->vm_flags & vm_flags)) {
 		fault = VM_FAULT_BADACCESS;
 		goto out;
 	}
 
-	return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
+	return handle_mm_fault(mm, vma, addr & PAGE_MASK, mm_flags);
 
 check_stack:
 	if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
@@ -208,9 +196,15 @@ static int __kprobes do_page_fault(unsig
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	int fault, sig, code;
-	bool write = (esr & ESR_WRITE) && !(esr & ESR_CM);
-	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
-		(write ? FAULT_FLAG_WRITE : 0);
+	unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC;
+	unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
+
+	if (esr & ESR_LNX_EXEC) {
+		vm_flags = VM_EXEC;
+	} else if ((esr & ESR_WRITE) && !(esr & ESR_CM)) {
+		vm_flags = VM_WRITE;
+		mm_flags |= FAULT_FLAG_WRITE;
+	}
 
 	tsk = current;
 	mm  = tsk->mm;
@@ -248,7 +242,7 @@ retry:
 #endif
 	}
 
-	fault = __do_page_fault(mm, addr, esr, flags, tsk);
+	fault = __do_page_fault(mm, addr, mm_flags, vm_flags, tsk);
 
 	/*
 	 * If we need to retry but a fatal signal is pending, handle the
@@ -265,7 +259,7 @@ retry:
 	 */
 
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
-	if (flags & FAULT_FLAG_ALLOW_RETRY) {
+	if (mm_flags & FAULT_FLAG_ALLOW_RETRY) {
 		if (fault & VM_FAULT_MAJOR) {
 			tsk->maj_flt++;
 			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs,
@@ -280,7 +274,7 @@ retry:
 			 * Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk of
 			 * starvation.
 			 */
-			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			mm_flags &= ~FAULT_FLAG_ALLOW_RETRY;
 			goto retry;
 		}
 	}
@@ -365,17 +359,6 @@ static int __kprobes do_translation_faul
 }
 
 /*
- * Some section permission faults need to be handled gracefully.  They can
- * happen due to a __{get,put}_user during an oops.
- */
-static int do_sect_fault(unsigned long addr, unsigned int esr,
-			 struct pt_regs *regs)
-{
-	do_bad_area(addr, esr, regs);
-	return 0;
-}
-
-/*
  * This abort handler always returns "fault".
  */
 static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
@@ -398,12 +381,12 @@ static struct fault_info {
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level 2 translation fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_MAPERR,	"level 3 translation fault"	},
 	{ do_bad,		SIGBUS,  0,		"reserved access flag fault"	},
-	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"level 1 access flag fault"	},
-	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"level 2 access flag fault"	},
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 1 access flag fault"	},
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 access flag fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 3 access flag fault"	},
 	{ do_bad,		SIGBUS,  0,		"reserved permission fault"	},
-	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"level 1 permission fault"	},
-	{ do_sect_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 permission fault"	},
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 1 permission fault"	},
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 permission fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 3 permission fault"	},
 	{ do_bad,		SIGBUS,  0,		"synchronous external abort"	},
 	{ do_bad,		SIGBUS,  0,		"asynchronous external abort"	},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/mm/flush.c linux-libre-3.11-rc7-gnu/arch/arm64/mm/flush.c
--- linux-libre-3.10-gnu/arch/arm64/mm/flush.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/mm/flush.c	2013-08-25 20:43:22.000000000 -0400
@@ -70,23 +70,16 @@ void copy_to_user_page(struct vm_area_st
 #endif
 }
 
-void __flush_dcache_page(struct page *page)
-{
-	__flush_dcache_area(page_address(page), PAGE_SIZE);
-}
-
 void __sync_icache_dcache(pte_t pte, unsigned long addr)
 {
-	unsigned long pfn;
-	struct page *page;
+	struct page *page = pte_page(pte);
 
-	pfn = pte_pfn(pte);
-	if (!pfn_valid(pfn))
+	/* no flushing needed for anonymous pages */
+	if (!page_mapping(page))
 		return;
 
-	page = pfn_to_page(pfn);
 	if (!test_and_set_bit(PG_dcache_clean, &page->flags)) {
-		__flush_dcache_page(page);
+		__flush_dcache_area(page_address(page), PAGE_SIZE);
 		__flush_icache_all();
 	} else if (icache_is_aivivt()) {
 		__flush_icache_all();
@@ -94,28 +87,14 @@ void __sync_icache_dcache(pte_t pte, uns
 }
 
 /*
- * Ensure cache coherency between kernel mapping and userspace mapping of this
- * page.
+ * This function is called when a page has been modified by the kernel. Mark
+ * it as dirty for later flushing when mapped in user space (if executable,
+ * see __sync_icache_dcache).
  */
 void flush_dcache_page(struct page *page)
 {
-	struct address_space *mapping;
-
-	/*
-	 * The zero page is never written to, so never has any dirty cache
-	 * lines, and therefore never needs to be flushed.
-	 */
-	if (page == ZERO_PAGE(0))
-		return;
-
-	mapping = page_mapping(page);
-	if (mapping && mapping_mapped(mapping)) {
-		__flush_dcache_page(page);
-		__flush_icache_all();
-		set_bit(PG_dcache_clean, &page->flags);
-	} else {
+	if (test_bit(PG_dcache_clean, &page->flags))
 		clear_bit(PG_dcache_clean, &page->flags);
-	}
 }
 EXPORT_SYMBOL(flush_dcache_page);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/mm/hugetlbpage.c linux-libre-3.11-rc7-gnu/arch/arm64/mm/hugetlbpage.c
--- linux-libre-3.10-gnu/arch/arm64/mm/hugetlbpage.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/mm/hugetlbpage.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,70 @@
+/*
+ * arch/arm64/mm/hugetlbpage.c
+ *
+ * Copyright (C) 2013 Linaro Ltd.
+ *
+ * Based on arch/x86/mm/hugetlbpage.c.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+
+#ifndef CONFIG_ARCH_WANT_HUGE_PMD_SHARE
+int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
+{
+	return 0;
+}
+#endif
+
+struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+			      int write)
+{
+	return ERR_PTR(-EINVAL);
+}
+
+int pmd_huge(pmd_t pmd)
+{
+	return !(pmd_val(pmd) & PMD_TABLE_BIT);
+}
+
+int pud_huge(pud_t pud)
+{
+	return !(pud_val(pud) & PUD_TABLE_BIT);
+}
+
+static __init int setup_hugepagesz(char *opt)
+{
+	unsigned long ps = memparse(opt, &opt);
+	if (ps == PMD_SIZE) {
+		hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
+	} else if (ps == PUD_SIZE) {
+		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
+	} else {
+		pr_err("hugepagesz: Unsupported page size %lu M\n", ps >> 20);
+		return 0;
+	}
+	return 1;
+}
+__setup("hugepagesz=", setup_hugepagesz);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/mm/init.c linux-libre-3.11-rc7-gnu/arch/arm64/mm/init.c
--- linux-libre-3.10-gnu/arch/arm64/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -197,14 +197,6 @@ void __init bootmem_init(void)
 	max_pfn = max_low_pfn = max;
 }
 
-/*
- * Poison init memory with an undefined instruction (0x0).
- */
-static inline void poison_init_mem(void *s, size_t count)
-{
-	memset(s, 0, count);
-}
-
 #ifndef CONFIG_SPARSEMEM_VMEMMAP
 static inline void free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 {
@@ -280,59 +272,17 @@ static void __init free_unused_memmap(vo
  */
 void __init mem_init(void)
 {
-	unsigned long reserved_pages, free_pages;
-	struct memblock_region *reg;
-
 	arm64_swiotlb_init();
 
 	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 
 #ifndef CONFIG_SPARSEMEM_VMEMMAP
-	/* this will put all unused low memory onto the freelists */
 	free_unused_memmap();
 #endif
+	/* this will put all unused low memory onto the freelists */
+	free_all_bootmem();
 
-	totalram_pages += free_all_bootmem();
-
-	reserved_pages = free_pages = 0;
-
-	for_each_memblock(memory, reg) {
-		unsigned int pfn1, pfn2;
-		struct page *page, *end;
-
-		pfn1 = __phys_to_pfn(reg->base);
-		pfn2 = pfn1 + __phys_to_pfn(reg->size);
-
-		page = pfn_to_page(pfn1);
-		end  = pfn_to_page(pfn2 - 1) + 1;
-
-		do {
-			if (PageReserved(page))
-				reserved_pages++;
-			else if (!page_count(page))
-				free_pages++;
-			page++;
-		} while (page < end);
-	}
-
-	/*
-	 * Since our memory may not be contiguous, calculate the real number
-	 * of pages we have in this system.
-	 */
-	pr_info("Memory:");
-	num_physpages = 0;
-	for_each_memblock(memory, reg) {
-		unsigned long pages = memblock_region_memory_end_pfn(reg) -
-			memblock_region_memory_base_pfn(reg);
-		num_physpages += pages;
-		printk(" %ldMB", pages >> (20 - PAGE_SHIFT));
-	}
-	printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
-
-	pr_notice("Memory: %luk/%luk available, %luk reserved\n",
-		  nr_free_pages() << (PAGE_SHIFT-10),
-		  free_pages << (PAGE_SHIFT-10),
-		  reserved_pages << (PAGE_SHIFT-10));
+	mem_init_print_info(NULL);
 
 #define MLK(b, t) b, t, ((t) - (b)) >> 10
 #define MLM(b, t) b, t, ((t) - (b)) >> 20
@@ -374,7 +324,7 @@ void __init mem_init(void)
 	BUILD_BUG_ON(TASK_SIZE_64			> MODULES_VADDR);
 	BUG_ON(TASK_SIZE_64				> MODULES_VADDR);
 
-	if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
+	if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
 		extern int sysctl_overcommit_memory;
 		/*
 		 * On a machine this small we won't get anywhere without
@@ -386,7 +336,6 @@ void __init mem_init(void)
 
 void free_initmem(void)
 {
-	poison_init_mem(__init_begin, __init_end - __init_begin);
 	free_initmem_default(0);
 }
 
@@ -396,10 +345,8 @@ static int keep_initrd;
 
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	if (!keep_initrd) {
-		poison_init_mem((void *)start, PAGE_ALIGN(end) - start);
-		free_reserved_area(start, end, 0, "initrd");
-	}
+	if (!keep_initrd)
+		free_reserved_area((void *)start, (void *)end, 0, "initrd");
 }
 
 static int __init keepinitrd_setup(char *__unused)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/mm/Makefile linux-libre-3.11-rc7-gnu/arch/arm64/mm/Makefile
--- linux-libre-3.10-gnu/arch/arm64/mm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/mm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -2,3 +2,4 @@ obj-y				:= dma-mapping.o extable.o faul
 				   cache.o copypage.o flush.o \
 				   ioremap.o mmap.o pgd.o mmu.o \
 				   context.o tlb.o proc.o
+obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/mm/mmap.c linux-libre-3.11-rc7-gnu/arch/arm64/mm/mmap.c
--- linux-libre-3.10-gnu/arch/arm64/mm/mmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/mm/mmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -90,11 +90,9 @@ void arch_pick_mmap_layout(struct mm_str
 	if (mmap_is_legacy()) {
 		mm->mmap_base = TASK_UNMAPPED_BASE;
 		mm->get_unmapped_area = arch_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
 	} else {
 		mm->mmap_base = mmap_base();
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
 EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/mm/mm.h linux-libre-3.11-rc7-gnu/arch/arm64/mm/mm.h
--- linux-libre-3.10-gnu/arch/arm64/mm/mm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/mm/mm.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,3 +1,2 @@
-extern void __flush_dcache_page(struct page *page);
 extern void __init bootmem_init(void);
 extern void __init arm64_swiotlb_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/mm/mmu.c linux-libre-3.11-rc7-gnu/arch/arm64/mm/mmu.c
--- linux-libre-3.10-gnu/arch/arm64/mm/mmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/arm64/mm/mmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -297,6 +297,16 @@ static void __init map_mem(void)
 {
 	struct memblock_region *reg;
 
+	/*
+	 * Temporarily limit the memblock range. We need to do this as
+	 * create_mapping requires puds, pmds and ptes to be allocated from
+	 * memory addressable from the initial direct kernel mapping.
+	 *
+	 * The initial direct kernel mapping, located at swapper_pg_dir,
+	 * gives us PGDIR_SIZE memory starting from PHYS_OFFSET (aligned).
+	 */
+	memblock_set_current_limit((PHYS_OFFSET & PGDIR_MASK) + PGDIR_SIZE);
+
 	/* map all the memory banks */
 	for_each_memblock(memory, reg) {
 		phys_addr_t start = reg->base;
@@ -307,6 +317,9 @@ static void __init map_mem(void)
 
 		create_mapping(start, __phys_to_virt(start), end - start);
 	}
+
+	/* Limit no longer required. */
+	memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE);
 }
 
 /*
@@ -317,12 +330,6 @@ void __init paging_init(void)
 {
 	void *zero_page;
 
-	/*
-	 * Maximum PGDIR_SIZE addressable via the initial direct kernel
-	 * mapping in swapper_pg_dir.
-	 */
-	memblock_set_current_limit((PHYS_OFFSET & PGDIR_MASK) + PGDIR_SIZE);
-
 	init_mem_pgprot();
 	map_mem();
 
@@ -339,7 +346,6 @@ void __init paging_init(void)
 	bootmem_init();
 
 	empty_zero_page = virt_to_page(zero_page);
-	__flush_dcache_page(empty_zero_page);
 
 	/*
 	 * TTBR0 is only used for the identity mapping at this stage. Make it
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/xen/hypercall.S linux-libre-3.11-rc7-gnu/arch/arm64/xen/hypercall.S
--- linux-libre-3.10-gnu/arch/arm64/xen/hypercall.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/xen/hypercall.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,93 @@
+/******************************************************************************
+ * hypercall.S
+ *
+ * Xen hypercall wrappers
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (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.
+ */
+
+/*
+ * The Xen hypercall calling convention is very similar to the procedure
+ * call standard for the ARM 64-bit architecture: the first parameter is
+ * passed in x0, the second in x1, the third in x2, the fourth in x3 and
+ * the fifth in x4.
+ *
+ * The hypercall number is passed in x16.
+ *
+ * The return value is in x0.
+ *
+ * The hvc ISS is required to be 0xEA1, that is the Xen specific ARM
+ * hypercall tag.
+ *
+ * Parameter structs passed to hypercalls are laid out according to
+ * the ARM 64-bit EABI standard.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <xen/interface/xen.h>
+
+
+#define XEN_IMM 0xEA1
+
+#define HYPERCALL_SIMPLE(hypercall)		\
+ENTRY(HYPERVISOR_##hypercall)			\
+	mov x16, #__HYPERVISOR_##hypercall;	\
+	hvc XEN_IMM;				\
+	ret;					\
+ENDPROC(HYPERVISOR_##hypercall)
+
+#define HYPERCALL0 HYPERCALL_SIMPLE
+#define HYPERCALL1 HYPERCALL_SIMPLE
+#define HYPERCALL2 HYPERCALL_SIMPLE
+#define HYPERCALL3 HYPERCALL_SIMPLE
+#define HYPERCALL4 HYPERCALL_SIMPLE
+#define HYPERCALL5 HYPERCALL_SIMPLE
+
+                .text
+
+HYPERCALL2(xen_version);
+HYPERCALL3(console_io);
+HYPERCALL3(grant_table_op);
+HYPERCALL2(sched_op);
+HYPERCALL2(event_channel_op);
+HYPERCALL2(hvm_op);
+HYPERCALL2(memory_op);
+HYPERCALL2(physdev_op);
+HYPERCALL3(vcpu_op);
+HYPERCALL1(tmem_op);
+
+ENTRY(privcmd_call)
+	mov x16, x0
+	mov x0, x1
+	mov x1, x2
+	mov x2, x3
+	mov x3, x4
+	mov x4, x5
+	hvc XEN_IMM
+	ret
+ENDPROC(privcmd_call);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/arm64/xen/Makefile linux-libre-3.11-rc7-gnu/arch/arm64/xen/Makefile
--- linux-libre-3.10-gnu/arch/arm64/xen/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/arm64/xen/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2 @@
+xen-arm-y	+= $(addprefix ../../arm/xen/, enlighten.o grant-table.o)
+obj-y		:= xen-arm.o hypercall.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/avr32/boards/atngw100/mrmt.c linux-libre-3.11-rc7-gnu/arch/avr32/boards/atngw100/mrmt.c
--- linux-libre-3.10-gnu/arch/avr32/boards/atngw100/mrmt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/avr32/boards/atngw100/mrmt.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,7 +150,6 @@ static struct ac97c_platform_data __init
 static struct platform_device rmt_ts_device = {
 	.name	= "ucb1400_ts",
 	.id	= -1,
-	}
 };
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/avr32/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/avr32/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/avr32/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/avr32/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -362,9 +362,6 @@ typedef pte_t *pte_addr_t;
 
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)	\
-	remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 /* No page table caches to initialize (?) */
 #define pgtable_cache_init()	do { } while(0)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/avr32/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/avr32/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/avr32/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/avr32/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -74,4 +74,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif /* __ASM_AVR32_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/avr32/kernel/process.c linux-libre-3.11-rc7-gnu/arch/avr32/kernel/process.c
--- linux-libre-3.10-gnu/arch/avr32/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/avr32/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -341,7 +341,7 @@ unsigned long get_wchan(struct task_stru
 		 * is actually quite ugly. It might be possible to
 		 * determine the frame size automatically at build
 		 * time by doing this:
-		 *   - compile sched.c
+		 *   - compile sched/core.c
 		 *   - disassemble the resulting sched.o
 		 *   - look for 'sub sp,??' shortly after '<schedule>:'
 		 */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/avr32/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/avr32/kernel/setup.c
--- linux-libre-3.10-gnu/arch/avr32/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/avr32/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -555,7 +555,7 @@ void __init setup_arch (char **cmdline_p
 {
 	struct clk *cpu_clk;
 
-	init_mm.start_code = (unsigned long)_text;
+	init_mm.start_code = (unsigned long)_stext;
 	init_mm.end_code = (unsigned long)_etext;
 	init_mm.end_data = (unsigned long)_edata;
 	init_mm.brk = (unsigned long)_end;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/avr32/kernel/vmlinux.lds.S linux-libre-3.11-rc7-gnu/arch/avr32/kernel/vmlinux.lds.S
--- linux-libre-3.10-gnu/arch/avr32/kernel/vmlinux.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/avr32/kernel/vmlinux.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,7 @@ SECTIONS
 {
 	. = CONFIG_ENTRY_ADDRESS;
 	.init		: AT(ADDR(.init) - LOAD_OFFSET) {
-		_stext = .;
+		_text = .;
 		__init_begin = .;
 			_sinittext = .;
 			*(.text.reset)
@@ -46,7 +46,7 @@ SECTIONS
 
 	.text		: AT(ADDR(.text) - LOAD_OFFSET) {
 		_evba = .;
-		_text = .;
+		_stext = .;
 		*(.ex.text)
 		*(.irq.text)
 		KPROBES_TEXT
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/avr32/mach-at32ap/at32ap700x.c linux-libre-3.11-rc7-gnu/arch/avr32/mach-at32ap/at32ap700x.c
--- linux-libre-3.10-gnu/arch/avr32/mach-at32ap/at32ap700x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/avr32/mach-at32ap/at32ap700x.c	2013-08-25 20:43:22.000000000 -0400
@@ -1060,7 +1060,9 @@ struct platform_device *__init at32_add_
 
 void __init at32_setup_serial_console(unsigned int usart_id)
 {
+#ifdef CONFIG_SERIAL_ATMEL
 	atmel_default_console_device = at32_usarts[usart_id];
+#endif
 }
 
 /* --------------------------------------------------------------------
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/avr32/mm/init.c linux-libre-3.11-rc7-gnu/arch/avr32/mm/init.c
--- linux-libre-3.10-gnu/arch/avr32/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/avr32/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -100,60 +100,26 @@ void __init paging_init(void)
 
 void __init mem_init(void)
 {
-	int codesize, reservedpages, datasize, initsize;
-	int nid, i;
+	pg_data_t *pgdat;
 
-	reservedpages = 0;
 	high_memory = NULL;
+	for_each_online_pgdat(pgdat)
+		high_memory = max_t(void *, high_memory,
+				    __va(pgdat_end_pfn(pgdat) << PAGE_SHIFT));
 
-	/* this will put all low memory onto the freelists */
-	for_each_online_node(nid) {
-		pg_data_t *pgdat = NODE_DATA(nid);
-		unsigned long node_pages = 0;
-		void *node_high_memory;
-
-		num_physpages += pgdat->node_present_pages;
-
-		if (pgdat->node_spanned_pages != 0)
-			node_pages = free_all_bootmem_node(pgdat);
-
-		totalram_pages += node_pages;
-
-		for (i = 0; i < node_pages; i++)
-			if (PageReserved(pgdat->node_mem_map + i))
-				reservedpages++;
-
-		node_high_memory = (void *)((pgdat->node_start_pfn
-					     + pgdat->node_spanned_pages)
-					    << PAGE_SHIFT);
-		if (node_high_memory > high_memory)
-			high_memory = node_high_memory;
-	}
-
-	max_mapnr = MAP_NR(high_memory);
-
-	codesize = (unsigned long)_etext - (unsigned long)_text;
-	datasize = (unsigned long)_edata - (unsigned long)_data;
-	initsize = (unsigned long)__init_end - (unsigned long)__init_begin;
-
-	printk ("Memory: %luk/%luk available (%dk kernel code, "
-		"%dk reserved, %dk data, %dk init)\n",
-		nr_free_pages() << (PAGE_SHIFT - 10),
-		totalram_pages << (PAGE_SHIFT - 10),
-		codesize >> 10,
-		reservedpages << (PAGE_SHIFT - 10),
-		datasize >> 10,
-		initsize >> 10);
+	set_max_mapnr(MAP_NR(high_memory));
+	free_all_bootmem();
+	mem_init_print_info(NULL);
 }
 
 void free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/include/asm/bfin6xx_spi.h linux-libre-3.11-rc7-gnu/arch/blackfin/include/asm/bfin6xx_spi.h
--- linux-libre-3.10-gnu/arch/blackfin/include/asm/bfin6xx_spi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/include/asm/bfin6xx_spi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,258 +0,0 @@
-/*
- * Analog Devices SPI3 controller driver
- *
- * Copyright (c) 2011 Analog Devices Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _SPI_CHANNEL_H_
-#define _SPI_CHANNEL_H_
-
-#include <linux/types.h>
-
-/* SPI_CONTROL */
-#define SPI_CTL_EN                  0x00000001    /* Enable */
-#define SPI_CTL_MSTR                0x00000002    /* Master/Slave */
-#define SPI_CTL_PSSE                0x00000004    /* controls modf error in master mode */
-#define SPI_CTL_ODM                 0x00000008    /* Open Drain Mode */
-#define SPI_CTL_CPHA                0x00000010    /* Clock Phase */
-#define SPI_CTL_CPOL                0x00000020    /* Clock Polarity */
-#define SPI_CTL_ASSEL               0x00000040    /* Slave Select Pin Control */
-#define SPI_CTL_SELST               0x00000080    /* Slave Select Polarity in-between transfers */
-#define SPI_CTL_EMISO               0x00000100    /* Enable MISO */
-#define SPI_CTL_SIZE                0x00000600    /* Word Transfer Size */
-#define SPI_CTL_SIZE08              0x00000000    /* SIZE: 8 bits */
-#define SPI_CTL_SIZE16              0x00000200    /* SIZE: 16 bits */
-#define SPI_CTL_SIZE32              0x00000400    /* SIZE: 32 bits */
-#define SPI_CTL_LSBF                0x00001000    /* LSB First */
-#define SPI_CTL_FCEN                0x00002000    /* Flow-Control Enable */
-#define SPI_CTL_FCCH                0x00004000    /* Flow-Control Channel Selection */
-#define SPI_CTL_FCPL                0x00008000    /* Flow-Control Polarity */
-#define SPI_CTL_FCWM                0x00030000    /* Flow-Control Water-Mark */
-#define SPI_CTL_FIFO0               0x00000000    /* FCWM: TFIFO empty or RFIFO Full */
-#define SPI_CTL_FIFO1               0x00010000    /* FCWM: TFIFO 75% or more empty or RFIFO 75% or more full */
-#define SPI_CTL_FIFO2               0x00020000    /* FCWM: TFIFO 50% or more empty or RFIFO 50% or more full */
-#define SPI_CTL_FMODE               0x00040000    /* Fast-mode Enable */
-#define SPI_CTL_MIOM                0x00300000    /* Multiple I/O Mode */
-#define SPI_CTL_MIO_DIS             0x00000000    /* MIOM: Disable */
-#define SPI_CTL_MIO_DUAL            0x00100000    /* MIOM: Enable DIOM (Dual I/O Mode) */
-#define SPI_CTL_MIO_QUAD            0x00200000    /* MIOM: Enable QUAD (Quad SPI Mode) */
-#define SPI_CTL_SOSI                0x00400000    /* Start on MOSI */
-/* SPI_RX_CONTROL */
-#define SPI_RXCTL_REN               0x00000001    /* Receive Channel Enable */
-#define SPI_RXCTL_RTI               0x00000004    /* Receive Transfer Initiate */
-#define SPI_RXCTL_RWCEN             0x00000008    /* Receive Word Counter Enable */
-#define SPI_RXCTL_RDR               0x00000070    /* Receive Data Request */
-#define SPI_RXCTL_RDR_DIS           0x00000000    /* RDR: Disabled */
-#define SPI_RXCTL_RDR_NE            0x00000010    /* RDR: RFIFO not empty */
-#define SPI_RXCTL_RDR_25            0x00000020    /* RDR: RFIFO 25% full */
-#define SPI_RXCTL_RDR_50            0x00000030    /* RDR: RFIFO 50% full */
-#define SPI_RXCTL_RDR_75            0x00000040    /* RDR: RFIFO 75% full */
-#define SPI_RXCTL_RDR_FULL          0x00000050    /* RDR: RFIFO full */
-#define SPI_RXCTL_RDO               0x00000100    /* Receive Data Over-Run */
-#define SPI_RXCTL_RRWM              0x00003000    /* FIFO Regular Water-Mark */
-#define SPI_RXCTL_RWM_0             0x00000000    /* RRWM: RFIFO Empty */
-#define SPI_RXCTL_RWM_25            0x00001000    /* RRWM: RFIFO 25% full */
-#define SPI_RXCTL_RWM_50            0x00002000    /* RRWM: RFIFO 50% full */
-#define SPI_RXCTL_RWM_75            0x00003000    /* RRWM: RFIFO 75% full */
-#define SPI_RXCTL_RUWM              0x00070000    /* FIFO Urgent Water-Mark */
-#define SPI_RXCTL_UWM_DIS           0x00000000    /* RUWM: Disabled */
-#define SPI_RXCTL_UWM_25            0x00010000    /* RUWM: RFIFO 25% full */
-#define SPI_RXCTL_UWM_50            0x00020000    /* RUWM: RFIFO 50% full */
-#define SPI_RXCTL_UWM_75            0x00030000    /* RUWM: RFIFO 75% full */
-#define SPI_RXCTL_UWM_FULL          0x00040000    /* RUWM: RFIFO full */
-/* SPI_TX_CONTROL */
-#define SPI_TXCTL_TEN               0x00000001    /* Transmit Channel Enable */
-#define SPI_TXCTL_TTI               0x00000004    /* Transmit Transfer Initiate */
-#define SPI_TXCTL_TWCEN             0x00000008    /* Transmit Word Counter Enable */
-#define SPI_TXCTL_TDR               0x00000070    /* Transmit Data Request */
-#define SPI_TXCTL_TDR_DIS           0x00000000    /* TDR: Disabled */
-#define SPI_TXCTL_TDR_NF            0x00000010    /* TDR: TFIFO not full */
-#define SPI_TXCTL_TDR_25            0x00000020    /* TDR: TFIFO 25% empty */
-#define SPI_TXCTL_TDR_50            0x00000030    /* TDR: TFIFO 50% empty */
-#define SPI_TXCTL_TDR_75            0x00000040    /* TDR: TFIFO 75% empty */
-#define SPI_TXCTL_TDR_EMPTY         0x00000050    /* TDR: TFIFO empty */
-#define SPI_TXCTL_TDU               0x00000100    /* Transmit Data Under-Run */
-#define SPI_TXCTL_TRWM              0x00003000    /* FIFO Regular Water-Mark */
-#define SPI_TXCTL_RWM_FULL          0x00000000    /* TRWM: TFIFO full */
-#define SPI_TXCTL_RWM_25            0x00001000    /* TRWM: TFIFO 25% empty */
-#define SPI_TXCTL_RWM_50            0x00002000    /* TRWM: TFIFO 50% empty */
-#define SPI_TXCTL_RWM_75            0x00003000    /* TRWM: TFIFO 75% empty */
-#define SPI_TXCTL_TUWM              0x00070000    /* FIFO Urgent Water-Mark */
-#define SPI_TXCTL_UWM_DIS           0x00000000    /* TUWM: Disabled */
-#define SPI_TXCTL_UWM_25            0x00010000    /* TUWM: TFIFO 25% empty */
-#define SPI_TXCTL_UWM_50            0x00020000    /* TUWM: TFIFO 50% empty */
-#define SPI_TXCTL_UWM_75            0x00030000    /* TUWM: TFIFO 75% empty */
-#define SPI_TXCTL_UWM_EMPTY         0x00040000    /* TUWM: TFIFO empty */
-/* SPI_CLOCK */
-#define SPI_CLK_BAUD                0x0000FFFF    /* Baud Rate */
-/* SPI_DELAY */
-#define SPI_DLY_STOP                0x000000FF    /* Transfer delay time in multiples of SCK period */
-#define SPI_DLY_LEADX               0x00000100    /* Extended (1 SCK) LEAD Control */
-#define SPI_DLY_LAGX                0x00000200    /* Extended (1 SCK) LAG control */
-/* SPI_SSEL */
-#define SPI_SLVSEL_SSE1             0x00000002    /* SPISSEL1 Enable */
-#define SPI_SLVSEL_SSE2             0x00000004    /* SPISSEL2 Enable */
-#define SPI_SLVSEL_SSE3             0x00000008    /* SPISSEL3 Enable */
-#define SPI_SLVSEL_SSE4             0x00000010    /* SPISSEL4 Enable */
-#define SPI_SLVSEL_SSE5             0x00000020    /* SPISSEL5 Enable */
-#define SPI_SLVSEL_SSE6             0x00000040    /* SPISSEL6 Enable */
-#define SPI_SLVSEL_SSE7             0x00000080    /* SPISSEL7 Enable */
-#define SPI_SLVSEL_SSEL1            0x00000200    /* SPISSEL1 Value */
-#define SPI_SLVSEL_SSEL2            0x00000400    /* SPISSEL2 Value */
-#define SPI_SLVSEL_SSEL3            0x00000800    /* SPISSEL3 Value */
-#define SPI_SLVSEL_SSEL4            0x00001000    /* SPISSEL4 Value */
-#define SPI_SLVSEL_SSEL5            0x00002000    /* SPISSEL5 Value */
-#define SPI_SLVSEL_SSEL6            0x00004000    /* SPISSEL6 Value */
-#define SPI_SLVSEL_SSEL7            0x00008000    /* SPISSEL7 Value */
-/* SPI_RWC */
-#define SPI_RWC_VALUE               0x0000FFFF    /* Received Word-Count */
-/* SPI_RWCR */
-#define SPI_RWCR_VALUE              0x0000FFFF    /* Received Word-Count Reload */
-/* SPI_TWC */
-#define SPI_TWC_VALUE               0x0000FFFF    /* Transmitted Word-Count */
-/* SPI_TWCR */
-#define SPI_TWCR_VALUE              0x0000FFFF    /* Transmitted Word-Count Reload */
-/* SPI_IMASK */
-#define SPI_IMSK_RUWM               0x00000002    /* Receive Urgent Water-Mark Interrupt Mask */
-#define SPI_IMSK_TUWM               0x00000004    /* Transmit Urgent Water-Mark Interrupt Mask */
-#define SPI_IMSK_ROM                0x00000010    /* Receive Over-Run Error Interrupt Mask */
-#define SPI_IMSK_TUM                0x00000020    /* Transmit Under-Run Error Interrupt Mask */
-#define SPI_IMSK_TCM                0x00000040    /* Transmit Collision Error Interrupt Mask */
-#define SPI_IMSK_MFM                0x00000080    /* Mode Fault Error Interrupt Mask */
-#define SPI_IMSK_RSM                0x00000100    /* Receive Start Interrupt Mask */
-#define SPI_IMSK_TSM                0x00000200    /* Transmit Start Interrupt Mask */
-#define SPI_IMSK_RFM                0x00000400    /* Receive Finish Interrupt Mask */
-#define SPI_IMSK_TFM                0x00000800    /* Transmit Finish Interrupt Mask */
-/* SPI_IMASKCL */
-#define SPI_IMSK_CLR_RUW            0x00000002    /* Receive Urgent Water-Mark Interrupt Mask */
-#define SPI_IMSK_CLR_TUWM           0x00000004    /* Transmit Urgent Water-Mark Interrupt Mask */
-#define SPI_IMSK_CLR_ROM            0x00000010    /* Receive Over-Run Error Interrupt Mask */
-#define SPI_IMSK_CLR_TUM            0x00000020    /* Transmit Under-Run Error Interrupt Mask */
-#define SPI_IMSK_CLR_TCM            0x00000040    /* Transmit Collision Error Interrupt Mask */
-#define SPI_IMSK_CLR_MFM            0x00000080    /* Mode Fault Error Interrupt Mask */
-#define SPI_IMSK_CLR_RSM            0x00000100    /* Receive Start Interrupt Mask */
-#define SPI_IMSK_CLR_TSM            0x00000200    /* Transmit Start Interrupt Mask */
-#define SPI_IMSK_CLR_RFM            0x00000400    /* Receive Finish Interrupt Mask */
-#define SPI_IMSK_CLR_TFM            0x00000800    /* Transmit Finish Interrupt Mask */
-/* SPI_IMASKST */
-#define SPI_IMSK_SET_RUWM           0x00000002    /* Receive Urgent Water-Mark Interrupt Mask */
-#define SPI_IMSK_SET_TUWM           0x00000004    /* Transmit Urgent Water-Mark Interrupt Mask */
-#define SPI_IMSK_SET_ROM            0x00000010    /* Receive Over-Run Error Interrupt Mask */
-#define SPI_IMSK_SET_TUM            0x00000020    /* Transmit Under-Run Error Interrupt Mask */
-#define SPI_IMSK_SET_TCM            0x00000040    /* Transmit Collision Error Interrupt Mask */
-#define SPI_IMSK_SET_MFM            0x00000080    /* Mode Fault Error Interrupt Mask */
-#define SPI_IMSK_SET_RSM            0x00000100    /* Receive Start Interrupt Mask */
-#define SPI_IMSK_SET_TSM            0x00000200    /* Transmit Start Interrupt Mask */
-#define SPI_IMSK_SET_RFM            0x00000400    /* Receive Finish Interrupt Mask */
-#define SPI_IMSK_SET_TFM            0x00000800    /* Transmit Finish Interrupt Mask */
-/* SPI_STATUS */
-#define SPI_STAT_SPIF               0x00000001    /* SPI Finished */
-#define SPI_STAT_RUWM               0x00000002    /* Receive Urgent Water-Mark Breached */
-#define SPI_STAT_TUWM               0x00000004    /* Transmit Urgent Water-Mark Breached */
-#define SPI_STAT_ROE                0x00000010    /* Receive Over-Run Error Indication */
-#define SPI_STAT_TUE                0x00000020    /* Transmit Under-Run Error Indication */
-#define SPI_STAT_TCE                0x00000040    /* Transmit Collision Error Indication */
-#define SPI_STAT_MODF               0x00000080    /* Mode Fault Error Indication */
-#define SPI_STAT_RS                 0x00000100    /* Receive Start Indication */
-#define SPI_STAT_TS                 0x00000200    /* Transmit Start Indication */
-#define SPI_STAT_RF                 0x00000400    /* Receive Finish Indication */
-#define SPI_STAT_TF                 0x00000800    /* Transmit Finish Indication */
-#define SPI_STAT_RFS                0x00007000    /* SPI_RFIFO status */
-#define SPI_STAT_RFIFO_EMPTY        0x00000000    /* RFS: RFIFO Empty */
-#define SPI_STAT_RFIFO_25           0x00001000    /* RFS: RFIFO 25% Full */
-#define SPI_STAT_RFIFO_50           0x00002000    /* RFS: RFIFO 50% Full */
-#define SPI_STAT_RFIFO_75           0x00003000    /* RFS: RFIFO 75% Full */
-#define SPI_STAT_RFIFO_FULL         0x00004000    /* RFS: RFIFO Full */
-#define SPI_STAT_TFS                0x00070000    /* SPI_TFIFO status */
-#define SPI_STAT_TFIFO_FULL         0x00000000    /* TFS: TFIFO full */
-#define SPI_STAT_TFIFO_25           0x00010000    /* TFS: TFIFO 25% empty */
-#define SPI_STAT_TFIFO_50           0x00020000    /* TFS: TFIFO 50% empty */
-#define SPI_STAT_TFIFO_75           0x00030000    /* TFS: TFIFO 75% empty */
-#define SPI_STAT_TFIFO_EMPTY        0x00040000    /* TFS: TFIFO empty */
-#define SPI_STAT_FCS                0x00100000    /* Flow-Control Stall Indication */
-#define SPI_STAT_RFE                0x00400000    /* SPI_RFIFO Empty */
-#define SPI_STAT_TFF                0x00800000    /* SPI_TFIFO Full */
-/* SPI_ILAT */
-#define SPI_ILAT_RUWMI              0x00000002    /* Receive Urgent Water Mark Interrupt */
-#define SPI_ILAT_TUWMI              0x00000004    /* Transmit Urgent Water Mark Interrupt */
-#define SPI_ILAT_ROI                0x00000010    /* Receive Over-Run Error Indication */
-#define SPI_ILAT_TUI                0x00000020    /* Transmit Under-Run Error Indication */
-#define SPI_ILAT_TCI                0x00000040    /* Transmit Collision Error Indication */
-#define SPI_ILAT_MFI                0x00000080    /* Mode Fault Error Indication */
-#define SPI_ILAT_RSI                0x00000100    /* Receive Start Indication */
-#define SPI_ILAT_TSI                0x00000200    /* Transmit Start Indication */
-#define SPI_ILAT_RFI                0x00000400    /* Receive Finish Indication */
-#define SPI_ILAT_TFI                0x00000800    /* Transmit Finish Indication */
-/* SPI_ILATCL */
-#define SPI_ILAT_CLR_RUWMI          0x00000002    /* Receive Urgent Water Mark Interrupt */
-#define SPI_ILAT_CLR_TUWMI          0x00000004    /* Transmit Urgent Water Mark Interrupt */
-#define SPI_ILAT_CLR_ROI            0x00000010    /* Receive Over-Run Error Indication */
-#define SPI_ILAT_CLR_TUI            0x00000020    /* Transmit Under-Run Error Indication */
-#define SPI_ILAT_CLR_TCI            0x00000040    /* Transmit Collision Error Indication */
-#define SPI_ILAT_CLR_MFI            0x00000080    /* Mode Fault Error Indication */
-#define SPI_ILAT_CLR_RSI            0x00000100    /* Receive Start Indication */
-#define SPI_ILAT_CLR_TSI            0x00000200    /* Transmit Start Indication */
-#define SPI_ILAT_CLR_RFI            0x00000400    /* Receive Finish Indication */
-#define SPI_ILAT_CLR_TFI            0x00000800    /* Transmit Finish Indication */
-
-/*
- * bfin spi3 registers layout
- */
-struct bfin_spi_regs {
-	u32 revid;
-	u32 control;
-	u32 rx_control;
-	u32 tx_control;
-	u32 clock;
-	u32 delay;
-	u32 ssel;
-	u32 rwc;
-	u32 rwcr;
-	u32 twc;
-	u32 twcr;
-	u32 reserved0;
-	u32 emask;
-	u32 emaskcl;
-	u32 emaskst;
-	u32 reserved1;
-	u32 status;
-	u32 elat;
-	u32 elatcl;
-	u32 reserved2;
-	u32 rfifo;
-	u32 reserved3;
-	u32 tfifo;
-};
-
-#define MAX_CTRL_CS          8  /* cs in spi controller */
-
-/* device.platform_data for SSP controller devices */
-struct bfin6xx_spi_master {
-	u16 num_chipselect;
-	u16 pin_req[7];
-};
-
-/* spi_board_info.controller_data for SPI slave devices,
- * copied to spi_device.platform_data ... mostly for dma tuning
- */
-struct bfin6xx_spi_chip {
-	u32 control;
-	u16 cs_chg_udelay; /* Some devices require 16-bit delays */
-	u32 tx_dummy_val; /* tx value for rx only transfer */
-	bool enable_dma;
-};
-
-#endif /* _SPI_CHANNEL_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/include/asm/bfin_spi3.h linux-libre-3.11-rc7-gnu/arch/blackfin/include/asm/bfin_spi3.h
--- linux-libre-3.10-gnu/arch/blackfin/include/asm/bfin_spi3.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/include/asm/bfin_spi3.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,258 @@
+/*
+ * Analog Devices SPI3 controller driver
+ *
+ * Copyright (c) 2011 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _SPI_CHANNEL_H_
+#define _SPI_CHANNEL_H_
+
+#include <linux/types.h>
+
+/* SPI_CONTROL */
+#define SPI_CTL_EN                  0x00000001    /* Enable */
+#define SPI_CTL_MSTR                0x00000002    /* Master/Slave */
+#define SPI_CTL_PSSE                0x00000004    /* controls modf error in master mode */
+#define SPI_CTL_ODM                 0x00000008    /* Open Drain Mode */
+#define SPI_CTL_CPHA                0x00000010    /* Clock Phase */
+#define SPI_CTL_CPOL                0x00000020    /* Clock Polarity */
+#define SPI_CTL_ASSEL               0x00000040    /* Slave Select Pin Control */
+#define SPI_CTL_SELST               0x00000080    /* Slave Select Polarity in-between transfers */
+#define SPI_CTL_EMISO               0x00000100    /* Enable MISO */
+#define SPI_CTL_SIZE                0x00000600    /* Word Transfer Size */
+#define SPI_CTL_SIZE08              0x00000000    /* SIZE: 8 bits */
+#define SPI_CTL_SIZE16              0x00000200    /* SIZE: 16 bits */
+#define SPI_CTL_SIZE32              0x00000400    /* SIZE: 32 bits */
+#define SPI_CTL_LSBF                0x00001000    /* LSB First */
+#define SPI_CTL_FCEN                0x00002000    /* Flow-Control Enable */
+#define SPI_CTL_FCCH                0x00004000    /* Flow-Control Channel Selection */
+#define SPI_CTL_FCPL                0x00008000    /* Flow-Control Polarity */
+#define SPI_CTL_FCWM                0x00030000    /* Flow-Control Water-Mark */
+#define SPI_CTL_FIFO0               0x00000000    /* FCWM: TFIFO empty or RFIFO Full */
+#define SPI_CTL_FIFO1               0x00010000    /* FCWM: TFIFO 75% or more empty or RFIFO 75% or more full */
+#define SPI_CTL_FIFO2               0x00020000    /* FCWM: TFIFO 50% or more empty or RFIFO 50% or more full */
+#define SPI_CTL_FMODE               0x00040000    /* Fast-mode Enable */
+#define SPI_CTL_MIOM                0x00300000    /* Multiple I/O Mode */
+#define SPI_CTL_MIO_DIS             0x00000000    /* MIOM: Disable */
+#define SPI_CTL_MIO_DUAL            0x00100000    /* MIOM: Enable DIOM (Dual I/O Mode) */
+#define SPI_CTL_MIO_QUAD            0x00200000    /* MIOM: Enable QUAD (Quad SPI Mode) */
+#define SPI_CTL_SOSI                0x00400000    /* Start on MOSI */
+/* SPI_RX_CONTROL */
+#define SPI_RXCTL_REN               0x00000001    /* Receive Channel Enable */
+#define SPI_RXCTL_RTI               0x00000004    /* Receive Transfer Initiate */
+#define SPI_RXCTL_RWCEN             0x00000008    /* Receive Word Counter Enable */
+#define SPI_RXCTL_RDR               0x00000070    /* Receive Data Request */
+#define SPI_RXCTL_RDR_DIS           0x00000000    /* RDR: Disabled */
+#define SPI_RXCTL_RDR_NE            0x00000010    /* RDR: RFIFO not empty */
+#define SPI_RXCTL_RDR_25            0x00000020    /* RDR: RFIFO 25% full */
+#define SPI_RXCTL_RDR_50            0x00000030    /* RDR: RFIFO 50% full */
+#define SPI_RXCTL_RDR_75            0x00000040    /* RDR: RFIFO 75% full */
+#define SPI_RXCTL_RDR_FULL          0x00000050    /* RDR: RFIFO full */
+#define SPI_RXCTL_RDO               0x00000100    /* Receive Data Over-Run */
+#define SPI_RXCTL_RRWM              0x00003000    /* FIFO Regular Water-Mark */
+#define SPI_RXCTL_RWM_0             0x00000000    /* RRWM: RFIFO Empty */
+#define SPI_RXCTL_RWM_25            0x00001000    /* RRWM: RFIFO 25% full */
+#define SPI_RXCTL_RWM_50            0x00002000    /* RRWM: RFIFO 50% full */
+#define SPI_RXCTL_RWM_75            0x00003000    /* RRWM: RFIFO 75% full */
+#define SPI_RXCTL_RUWM              0x00070000    /* FIFO Urgent Water-Mark */
+#define SPI_RXCTL_UWM_DIS           0x00000000    /* RUWM: Disabled */
+#define SPI_RXCTL_UWM_25            0x00010000    /* RUWM: RFIFO 25% full */
+#define SPI_RXCTL_UWM_50            0x00020000    /* RUWM: RFIFO 50% full */
+#define SPI_RXCTL_UWM_75            0x00030000    /* RUWM: RFIFO 75% full */
+#define SPI_RXCTL_UWM_FULL          0x00040000    /* RUWM: RFIFO full */
+/* SPI_TX_CONTROL */
+#define SPI_TXCTL_TEN               0x00000001    /* Transmit Channel Enable */
+#define SPI_TXCTL_TTI               0x00000004    /* Transmit Transfer Initiate */
+#define SPI_TXCTL_TWCEN             0x00000008    /* Transmit Word Counter Enable */
+#define SPI_TXCTL_TDR               0x00000070    /* Transmit Data Request */
+#define SPI_TXCTL_TDR_DIS           0x00000000    /* TDR: Disabled */
+#define SPI_TXCTL_TDR_NF            0x00000010    /* TDR: TFIFO not full */
+#define SPI_TXCTL_TDR_25            0x00000020    /* TDR: TFIFO 25% empty */
+#define SPI_TXCTL_TDR_50            0x00000030    /* TDR: TFIFO 50% empty */
+#define SPI_TXCTL_TDR_75            0x00000040    /* TDR: TFIFO 75% empty */
+#define SPI_TXCTL_TDR_EMPTY         0x00000050    /* TDR: TFIFO empty */
+#define SPI_TXCTL_TDU               0x00000100    /* Transmit Data Under-Run */
+#define SPI_TXCTL_TRWM              0x00003000    /* FIFO Regular Water-Mark */
+#define SPI_TXCTL_RWM_FULL          0x00000000    /* TRWM: TFIFO full */
+#define SPI_TXCTL_RWM_25            0x00001000    /* TRWM: TFIFO 25% empty */
+#define SPI_TXCTL_RWM_50            0x00002000    /* TRWM: TFIFO 50% empty */
+#define SPI_TXCTL_RWM_75            0x00003000    /* TRWM: TFIFO 75% empty */
+#define SPI_TXCTL_TUWM              0x00070000    /* FIFO Urgent Water-Mark */
+#define SPI_TXCTL_UWM_DIS           0x00000000    /* TUWM: Disabled */
+#define SPI_TXCTL_UWM_25            0x00010000    /* TUWM: TFIFO 25% empty */
+#define SPI_TXCTL_UWM_50            0x00020000    /* TUWM: TFIFO 50% empty */
+#define SPI_TXCTL_UWM_75            0x00030000    /* TUWM: TFIFO 75% empty */
+#define SPI_TXCTL_UWM_EMPTY         0x00040000    /* TUWM: TFIFO empty */
+/* SPI_CLOCK */
+#define SPI_CLK_BAUD                0x0000FFFF    /* Baud Rate */
+/* SPI_DELAY */
+#define SPI_DLY_STOP                0x000000FF    /* Transfer delay time in multiples of SCK period */
+#define SPI_DLY_LEADX               0x00000100    /* Extended (1 SCK) LEAD Control */
+#define SPI_DLY_LAGX                0x00000200    /* Extended (1 SCK) LAG control */
+/* SPI_SSEL */
+#define SPI_SLVSEL_SSE1             0x00000002    /* SPISSEL1 Enable */
+#define SPI_SLVSEL_SSE2             0x00000004    /* SPISSEL2 Enable */
+#define SPI_SLVSEL_SSE3             0x00000008    /* SPISSEL3 Enable */
+#define SPI_SLVSEL_SSE4             0x00000010    /* SPISSEL4 Enable */
+#define SPI_SLVSEL_SSE5             0x00000020    /* SPISSEL5 Enable */
+#define SPI_SLVSEL_SSE6             0x00000040    /* SPISSEL6 Enable */
+#define SPI_SLVSEL_SSE7             0x00000080    /* SPISSEL7 Enable */
+#define SPI_SLVSEL_SSEL1            0x00000200    /* SPISSEL1 Value */
+#define SPI_SLVSEL_SSEL2            0x00000400    /* SPISSEL2 Value */
+#define SPI_SLVSEL_SSEL3            0x00000800    /* SPISSEL3 Value */
+#define SPI_SLVSEL_SSEL4            0x00001000    /* SPISSEL4 Value */
+#define SPI_SLVSEL_SSEL5            0x00002000    /* SPISSEL5 Value */
+#define SPI_SLVSEL_SSEL6            0x00004000    /* SPISSEL6 Value */
+#define SPI_SLVSEL_SSEL7            0x00008000    /* SPISSEL7 Value */
+/* SPI_RWC */
+#define SPI_RWC_VALUE               0x0000FFFF    /* Received Word-Count */
+/* SPI_RWCR */
+#define SPI_RWCR_VALUE              0x0000FFFF    /* Received Word-Count Reload */
+/* SPI_TWC */
+#define SPI_TWC_VALUE               0x0000FFFF    /* Transmitted Word-Count */
+/* SPI_TWCR */
+#define SPI_TWCR_VALUE              0x0000FFFF    /* Transmitted Word-Count Reload */
+/* SPI_IMASK */
+#define SPI_IMSK_RUWM               0x00000002    /* Receive Urgent Water-Mark Interrupt Mask */
+#define SPI_IMSK_TUWM               0x00000004    /* Transmit Urgent Water-Mark Interrupt Mask */
+#define SPI_IMSK_ROM                0x00000010    /* Receive Over-Run Error Interrupt Mask */
+#define SPI_IMSK_TUM                0x00000020    /* Transmit Under-Run Error Interrupt Mask */
+#define SPI_IMSK_TCM                0x00000040    /* Transmit Collision Error Interrupt Mask */
+#define SPI_IMSK_MFM                0x00000080    /* Mode Fault Error Interrupt Mask */
+#define SPI_IMSK_RSM                0x00000100    /* Receive Start Interrupt Mask */
+#define SPI_IMSK_TSM                0x00000200    /* Transmit Start Interrupt Mask */
+#define SPI_IMSK_RFM                0x00000400    /* Receive Finish Interrupt Mask */
+#define SPI_IMSK_TFM                0x00000800    /* Transmit Finish Interrupt Mask */
+/* SPI_IMASKCL */
+#define SPI_IMSK_CLR_RUW            0x00000002    /* Receive Urgent Water-Mark Interrupt Mask */
+#define SPI_IMSK_CLR_TUWM           0x00000004    /* Transmit Urgent Water-Mark Interrupt Mask */
+#define SPI_IMSK_CLR_ROM            0x00000010    /* Receive Over-Run Error Interrupt Mask */
+#define SPI_IMSK_CLR_TUM            0x00000020    /* Transmit Under-Run Error Interrupt Mask */
+#define SPI_IMSK_CLR_TCM            0x00000040    /* Transmit Collision Error Interrupt Mask */
+#define SPI_IMSK_CLR_MFM            0x00000080    /* Mode Fault Error Interrupt Mask */
+#define SPI_IMSK_CLR_RSM            0x00000100    /* Receive Start Interrupt Mask */
+#define SPI_IMSK_CLR_TSM            0x00000200    /* Transmit Start Interrupt Mask */
+#define SPI_IMSK_CLR_RFM            0x00000400    /* Receive Finish Interrupt Mask */
+#define SPI_IMSK_CLR_TFM            0x00000800    /* Transmit Finish Interrupt Mask */
+/* SPI_IMASKST */
+#define SPI_IMSK_SET_RUWM           0x00000002    /* Receive Urgent Water-Mark Interrupt Mask */
+#define SPI_IMSK_SET_TUWM           0x00000004    /* Transmit Urgent Water-Mark Interrupt Mask */
+#define SPI_IMSK_SET_ROM            0x00000010    /* Receive Over-Run Error Interrupt Mask */
+#define SPI_IMSK_SET_TUM            0x00000020    /* Transmit Under-Run Error Interrupt Mask */
+#define SPI_IMSK_SET_TCM            0x00000040    /* Transmit Collision Error Interrupt Mask */
+#define SPI_IMSK_SET_MFM            0x00000080    /* Mode Fault Error Interrupt Mask */
+#define SPI_IMSK_SET_RSM            0x00000100    /* Receive Start Interrupt Mask */
+#define SPI_IMSK_SET_TSM            0x00000200    /* Transmit Start Interrupt Mask */
+#define SPI_IMSK_SET_RFM            0x00000400    /* Receive Finish Interrupt Mask */
+#define SPI_IMSK_SET_TFM            0x00000800    /* Transmit Finish Interrupt Mask */
+/* SPI_STATUS */
+#define SPI_STAT_SPIF               0x00000001    /* SPI Finished */
+#define SPI_STAT_RUWM               0x00000002    /* Receive Urgent Water-Mark Breached */
+#define SPI_STAT_TUWM               0x00000004    /* Transmit Urgent Water-Mark Breached */
+#define SPI_STAT_ROE                0x00000010    /* Receive Over-Run Error Indication */
+#define SPI_STAT_TUE                0x00000020    /* Transmit Under-Run Error Indication */
+#define SPI_STAT_TCE                0x00000040    /* Transmit Collision Error Indication */
+#define SPI_STAT_MODF               0x00000080    /* Mode Fault Error Indication */
+#define SPI_STAT_RS                 0x00000100    /* Receive Start Indication */
+#define SPI_STAT_TS                 0x00000200    /* Transmit Start Indication */
+#define SPI_STAT_RF                 0x00000400    /* Receive Finish Indication */
+#define SPI_STAT_TF                 0x00000800    /* Transmit Finish Indication */
+#define SPI_STAT_RFS                0x00007000    /* SPI_RFIFO status */
+#define SPI_STAT_RFIFO_EMPTY        0x00000000    /* RFS: RFIFO Empty */
+#define SPI_STAT_RFIFO_25           0x00001000    /* RFS: RFIFO 25% Full */
+#define SPI_STAT_RFIFO_50           0x00002000    /* RFS: RFIFO 50% Full */
+#define SPI_STAT_RFIFO_75           0x00003000    /* RFS: RFIFO 75% Full */
+#define SPI_STAT_RFIFO_FULL         0x00004000    /* RFS: RFIFO Full */
+#define SPI_STAT_TFS                0x00070000    /* SPI_TFIFO status */
+#define SPI_STAT_TFIFO_FULL         0x00000000    /* TFS: TFIFO full */
+#define SPI_STAT_TFIFO_25           0x00010000    /* TFS: TFIFO 25% empty */
+#define SPI_STAT_TFIFO_50           0x00020000    /* TFS: TFIFO 50% empty */
+#define SPI_STAT_TFIFO_75           0x00030000    /* TFS: TFIFO 75% empty */
+#define SPI_STAT_TFIFO_EMPTY        0x00040000    /* TFS: TFIFO empty */
+#define SPI_STAT_FCS                0x00100000    /* Flow-Control Stall Indication */
+#define SPI_STAT_RFE                0x00400000    /* SPI_RFIFO Empty */
+#define SPI_STAT_TFF                0x00800000    /* SPI_TFIFO Full */
+/* SPI_ILAT */
+#define SPI_ILAT_RUWMI              0x00000002    /* Receive Urgent Water Mark Interrupt */
+#define SPI_ILAT_TUWMI              0x00000004    /* Transmit Urgent Water Mark Interrupt */
+#define SPI_ILAT_ROI                0x00000010    /* Receive Over-Run Error Indication */
+#define SPI_ILAT_TUI                0x00000020    /* Transmit Under-Run Error Indication */
+#define SPI_ILAT_TCI                0x00000040    /* Transmit Collision Error Indication */
+#define SPI_ILAT_MFI                0x00000080    /* Mode Fault Error Indication */
+#define SPI_ILAT_RSI                0x00000100    /* Receive Start Indication */
+#define SPI_ILAT_TSI                0x00000200    /* Transmit Start Indication */
+#define SPI_ILAT_RFI                0x00000400    /* Receive Finish Indication */
+#define SPI_ILAT_TFI                0x00000800    /* Transmit Finish Indication */
+/* SPI_ILATCL */
+#define SPI_ILAT_CLR_RUWMI          0x00000002    /* Receive Urgent Water Mark Interrupt */
+#define SPI_ILAT_CLR_TUWMI          0x00000004    /* Transmit Urgent Water Mark Interrupt */
+#define SPI_ILAT_CLR_ROI            0x00000010    /* Receive Over-Run Error Indication */
+#define SPI_ILAT_CLR_TUI            0x00000020    /* Transmit Under-Run Error Indication */
+#define SPI_ILAT_CLR_TCI            0x00000040    /* Transmit Collision Error Indication */
+#define SPI_ILAT_CLR_MFI            0x00000080    /* Mode Fault Error Indication */
+#define SPI_ILAT_CLR_RSI            0x00000100    /* Receive Start Indication */
+#define SPI_ILAT_CLR_TSI            0x00000200    /* Transmit Start Indication */
+#define SPI_ILAT_CLR_RFI            0x00000400    /* Receive Finish Indication */
+#define SPI_ILAT_CLR_TFI            0x00000800    /* Transmit Finish Indication */
+
+/*
+ * bfin spi3 registers layout
+ */
+struct bfin_spi_regs {
+	u32 revid;
+	u32 control;
+	u32 rx_control;
+	u32 tx_control;
+	u32 clock;
+	u32 delay;
+	u32 ssel;
+	u32 rwc;
+	u32 rwcr;
+	u32 twc;
+	u32 twcr;
+	u32 reserved0;
+	u32 emask;
+	u32 emaskcl;
+	u32 emaskst;
+	u32 reserved1;
+	u32 status;
+	u32 elat;
+	u32 elatcl;
+	u32 reserved2;
+	u32 rfifo;
+	u32 reserved3;
+	u32 tfifo;
+};
+
+#define MAX_CTRL_CS          8  /* cs in spi controller */
+
+/* device.platform_data for SSP controller devices */
+struct bfin_spi3_master {
+	u16 num_chipselect;
+	u16 pin_req[7];
+};
+
+/* spi_board_info.controller_data for SPI slave devices,
+ * copied to spi_device.platform_data ... mostly for dma tuning
+ */
+struct bfin_spi3_chip {
+	u32 control;
+	u16 cs_chg_udelay; /* Some devices require 16-bit delays */
+	u32 tx_dummy_val; /* tx value for rx only transfer */
+	bool enable_dma;
+};
+
+#endif /* _SPI_CHANNEL_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/blackfin/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/blackfin/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -88,7 +88,6 @@ extern char empty_zero_page[];
  * No page table caches to initialise.
  */
 #define pgtable_cache_init()	do { } while (0)
-#define io_remap_pfn_range      remap_pfn_range
 
 /*
  * All 32bit addresses are effectively valid for vmalloc...
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/Kconfig linux-libre-3.11-rc7-gnu/arch/blackfin/Kconfig
--- linux-libre-3.10-gnu/arch/blackfin/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -41,6 +41,7 @@ config BLACKFIN
 	select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS
 	select HAVE_MOD_ARCH_SPECIFIC
 	select MODULES_USE_ELF_RELA
+	select HAVE_DEBUG_STACKOVERFLOW
 
 config GENERIC_CSUM
 	def_bool y
@@ -253,7 +254,7 @@ config NR_CPUS
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
-	depends on SMP && HOTPLUG
+	depends on SMP
 	default y
 
 config BF_REV_MIN
@@ -282,7 +283,7 @@ config BF_REV_0_0
 
 config BF_REV_0_1
 	bool "0.1"
-	depends on (BF51x || BF52x || (BF54x && !BF54xM))
+	depends on (BF51x || BF52x || (BF54x && !BF54xM) || BF60x)
 
 config BF_REV_0_2
 	bool "0.2"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/blackfin/Kconfig.debug
--- linux-libre-3.10-gnu/arch/blackfin/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -2,13 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-	help
-	  This option will cause messages to be printed if free stack space
-	  drops below a certain limit.
-
 config DEBUG_VERBOSE
 	bool "Verbose fault messages"
 	default y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/kernel/kgdb.c linux-libre-3.11-rc7-gnu/arch/blackfin/kernel/kgdb.c
--- linux-libre-3.10-gnu/arch/blackfin/kernel/kgdb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/kernel/kgdb.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/ptrace.h>		/* for linux pt_regs struct */
 #include <linux/kgdb.h>
 #include <linux/uaccess.h>
+#include <asm/irq_regs.h>
 
 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/kernel/perf_event.c linux-libre-3.11-rc7-gnu/arch/blackfin/kernel/perf_event.c
--- linux-libre-3.10-gnu/arch/blackfin/kernel/perf_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/kernel/perf_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -468,7 +468,7 @@ static void bfin_pmu_setup(int cpu)
 	memset(cpuhw, 0, sizeof(struct cpu_hw_events));
 }
 
-static int __cpuinit
+static int
 bfin_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (long)hcpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/blackfin/kernel/setup.c
--- linux-libre-3.10-gnu/arch/blackfin/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -99,7 +99,7 @@ void __init generate_cplb_tables(void)
 }
 #endif
 
-void __cpuinit bfin_setup_caches(unsigned int cpu)
+void bfin_setup_caches(unsigned int cpu)
 {
 #ifdef CONFIG_BFIN_ICACHE
 	bfin_icache_init(icplb_tbl[cpu]);
@@ -165,7 +165,7 @@ void __cpuinit bfin_setup_caches(unsigne
 #endif
 }
 
-void __cpuinit bfin_setup_cpudata(unsigned int cpu)
+void bfin_setup_cpudata(unsigned int cpu)
 {
 	struct blackfin_cpudata *cpudata = &per_cpu(cpu_data, cpu);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-bf527/boards/ad7160eval.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf527/boards/ad7160eval.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-bf527/boards/ad7160eval.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf527/boards/ad7160eval.c	2013-08-25 20:43:22.000000000 -0400
@@ -283,14 +283,6 @@ static struct platform_device bfin_i2s =
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-	.name = "bfin-tdm",
-	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
-};
-#endif
-
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_MTD_M25P80) \
 	|| defined(CONFIG_MTD_M25P80_MODULE)
@@ -800,10 +792,6 @@ static struct platform_device *stamp_dev
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
 	&bfin_i2s,
 #endif
-
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-	&bfin_tdm,
-#endif
 };
 
 static int __init ad7160eval_init(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-bf527/boards/ezkit.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf527/boards/ezkit.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-bf527/boards/ezkit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf527/boards/ezkit.c	2013-08-25 20:43:22.000000000 -0400
@@ -493,8 +493,7 @@ static const struct ad7879_platform_data
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
-	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
 
 static const u16 bfin_snd_pin[][7] = {
 	{P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
@@ -549,13 +548,6 @@ static struct platform_device bfin_i2s_p
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm_pcm = {
-	.name = "bfin-tdm-pcm-audio",
-	.id = -1,
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97_pcm = {
 	.name = "bfin-ac97-pcm-audio",
@@ -575,22 +567,10 @@ static struct platform_device bfin_i2s =
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-	.name = "bfin-tdm",
-	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
-	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
-	.dev = {
-		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
-	},
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
 	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-	"bfin-tdm.0",
+	"bfin-i2s.0",
 	"spi0.4",
 };
 static struct platform_device bfin_ad1836_machine = {
@@ -1269,10 +1249,6 @@ static struct platform_device *stamp_dev
 	&bfin_i2s_pcm,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-	&bfin_tdm_pcm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 	&bfin_ac97_pcm,
 #endif
@@ -1281,10 +1257,6 @@ static struct platform_device *stamp_dev
 	&bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-	&bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
 	defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 	&bfin_ad1836_machine,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-bf533/boards/ezkit.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf533/boards/ezkit.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-bf533/boards/ezkit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf533/boards/ezkit.c	2013-08-25 20:43:22.000000000 -0400
@@ -450,14 +450,6 @@ static struct platform_device bfin_i2s =
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-	.name = "bfin-tdm",
-	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
 	.name = "bfin-ac97",
@@ -516,10 +508,6 @@ static struct platform_device *ezkit_dev
 	&bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-	&bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 	&bfin_ac97,
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-bf533/boards/stamp.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf533/boards/stamp.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-bf533/boards/stamp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf533/boards/stamp.c	2013-08-25 20:43:22.000000000 -0400
@@ -542,8 +542,7 @@ static struct platform_device bfin_dpmc
 };
 
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
-	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) \
-	|| defined(CONFIG_SND_BF5XX_AC97) || \
+	defined(CONFIG_SND_BF5XX_AC97) || \
 	defined(CONFIG_SND_BF5XX_AC97_MODULE)
 
 #include <asm/bfin_sport.h>
@@ -603,13 +602,6 @@ static struct platform_device bfin_i2s_p
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm_pcm = {
-	.name = "bfin-tdm-pcm-audio",
-	.id = -1,
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97_pcm = {
 	.name = "bfin-ac97-pcm-audio",
@@ -620,7 +612,7 @@ static struct platform_device bfin_ac97_
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
 	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-	"bfin-tdm.0",
+	"bfin-i2s.0",
 	"spi0.4",
 };
 static struct platform_device bfin_ad1836_machine = {
@@ -675,20 +667,6 @@ static struct platform_device bfin_i2s =
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || \
-	defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-	.name = "bfin-tdm",
-	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	.num_resources =
-		ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
-	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
-	.dev = {
-		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
-	},
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || \
 	defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
@@ -761,10 +739,6 @@ static struct platform_device *stamp_dev
 	&bfin_i2s_pcm,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-	&bfin_tdm_pcm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 	&bfin_ac97_pcm,
 #endif
@@ -792,11 +766,6 @@ static struct platform_device *stamp_dev
 	&bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || \
-	defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-	&bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || \
 	defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 	&bfin_ac97,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-bf537/boards/stamp.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf537/boards/stamp.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-bf537/boards/stamp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf537/boards/stamp.c	2013-08-25 20:43:22.000000000 -0400
@@ -2570,7 +2570,6 @@ static struct platform_device bfin_dpmc
 };
 
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
-	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
 	defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 
 #define SPORT_REQ(x) \
@@ -2628,13 +2627,6 @@ static struct platform_device bfin_i2s_p
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm_pcm = {
-	.name = "bfin-tdm-pcm-audio",
-	.id = -1,
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97_pcm = {
 	.name = "bfin-ac97-pcm-audio",
@@ -2645,7 +2637,7 @@ static struct platform_device bfin_ac97_
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
 	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-	"bfin-tdm.0",
+	"bfin-i2s.0",
 	"spi0.4",
 };
 static struct platform_device bfin_ad1836_machine = {
@@ -2699,18 +2691,6 @@ static struct platform_device bfin_i2s =
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-	.name = "bfin-tdm",
-	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
-	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
-	.dev = {
-		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
-	},
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
 	.name = "bfin-ac97",
@@ -2935,10 +2915,6 @@ static struct platform_device *stamp_dev
 	&bfin_i2s_pcm,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-	&bfin_tdm_pcm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 	&bfin_ac97_pcm,
 #endif
@@ -2961,10 +2937,6 @@ static struct platform_device *stamp_dev
 	&bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-	&bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 	&bfin_ac97,
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-bf548/boards/ezkit.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf548/boards/ezkit.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-bf548/boards/ezkit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf548/boards/ezkit.c	2013-08-25 20:43:22.000000000 -0400
@@ -1393,7 +1393,6 @@ static struct platform_device bfin_dpmc
 };
 
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
-	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
 	defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 
 #define SPORT_REQ(x) \
@@ -1461,13 +1460,6 @@ static struct platform_device bfin_i2s_p
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm_pcm = {
-	.name = "bfin-tdm-pcm-audio",
-	.id = -1,
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97_pcm = {
 	.name = "bfin-ac97-pcm-audio",
@@ -1501,18 +1493,6 @@ static struct platform_device bfin_i2s =
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-	.name = "bfin-tdm",
-	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
-	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
-	.dev = {
-		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
-	},
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
 	.name = "bfin-ac97",
@@ -1646,9 +1626,7 @@ static struct platform_device *ezkit_dev
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
 	&bfin_i2s_pcm,
 #endif
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-	&bfin_tdm_pcm,
-#endif
+
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 	&bfin_ac97_pcm,
 #endif
@@ -1661,10 +1639,6 @@ static struct platform_device *ezkit_dev
 	&bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-	&bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 	&bfin_ac97,
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-bf561/boards/ezkit.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf561/boards/ezkit.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-bf561/boards/ezkit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf561/boards/ezkit.c	2013-08-25 20:43:22.000000000 -0400
@@ -523,14 +523,6 @@ static struct platform_device bfin_i2s =
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-static struct platform_device bfin_tdm = {
-	.name = "bfin-tdm",
-	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
-};
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
 	.name = "bfin-ac97",
@@ -542,7 +534,7 @@ static struct platform_device bfin_ac97
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
 	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-	"bfin-tdm.0",
+	"bfin-i2s.0",
 	"spi0.4",
 };
 static struct platform_device bfin_ad1836_machine = {
@@ -611,10 +603,6 @@ static struct platform_device *ezkit_dev
 	&bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
-	&bfin_tdm,
-#endif
-
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 	&bfin_ac97,
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-bf561/smp.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf561/smp.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-bf561/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf561/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,7 +48,7 @@ int __init setup_profiling_timer(unsigne
 	return -EINVAL;
 }
 
-void __cpuinit platform_secondary_init(unsigned int cpu)
+void platform_secondary_init(unsigned int cpu)
 {
 	/* Clone setup for peripheral interrupt sources from CoreA. */
 	bfin_write_SICB_IMASK0(bfin_read_SIC_IMASK0());
@@ -69,12 +69,11 @@ void __cpuinit platform_secondary_init(u
 	SSYNC();
 
 	/* We are done with local CPU inits, unblock the boot CPU. */
-	set_cpu_online(cpu, true);
 	spin_lock(&boot_lock);
 	spin_unlock(&boot_lock);
 }
 
-int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle)
+int platform_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
 
@@ -91,7 +90,9 @@ int __cpuinit platform_boot_secondary(un
 		SSYNC();
 	}
 
-	timeout = jiffies + 1 * HZ;
+	timeout = jiffies + HZ;
+	/* release the lock and let coreb run */
+	spin_unlock(&boot_lock);
 	while (time_before(jiffies, timeout)) {
 		if (cpu_online(cpu))
 			break;
@@ -100,8 +101,6 @@ int __cpuinit platform_boot_secondary(un
 	}
 
 	if (cpu_online(cpu)) {
-		/* release the lock and let coreb run */
-		spin_unlock(&boot_lock);
 		return 0;
 	} else
 		panic("CPU%u: processor failed to boot\n", cpu);
@@ -155,7 +154,7 @@ void platform_clear_ipi(unsigned int cpu
  * Setup core B's local core timer.
  * In SMP, core timer is used for clock event device.
  */
-void __cpuinit bfin_local_timer_setup(void)
+void bfin_local_timer_setup(void)
 {
 #if defined(CONFIG_TICKSOURCE_CORETMR)
 	struct irq_data *data = irq_get_irq_data(IRQ_CORETMR);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-bf609/boards/ezkit.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf609/boards/ezkit.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-bf609/boards/ezkit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-bf609/boards/ezkit.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/usb/musb.h>
-#include <asm/bfin6xx_spi.h>
+#include <asm/bfin_spi3.h>
 #include <asm/dma.h>
 #include <asm/gpio.h>
 #include <asm/nand.h>
@@ -108,7 +108,6 @@ static struct platform_device bfin_rotar
 static unsigned short pins[] = P_RMII0;
 
 static struct stmmac_mdio_bus_data phy_private_data = {
-	.bus_id = 0,
 	.phy_mask = 1,
 };
 
@@ -745,13 +744,13 @@ static struct flash_platform_data bfin_s
 	.type = "w25q32",
 };
 
-static struct bfin6xx_spi_chip spi_flash_chip_info = {
+static struct bfin_spi3_chip spi_flash_chip_info = {
 	.enable_dma = true,         /* use dma transfer with this chip*/
 };
 #endif
 
 #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
-static struct bfin6xx_spi_chip spidev_chip_info = {
+static struct bfin_spi3_chip spidev_chip_info = {
 	.enable_dma = true,
 };
 #endif
@@ -821,7 +820,7 @@ static struct platform_device bfin_i2s =
 #if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
 	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static const char * const ad1836_link[] = {
-	"bfin-tdm.0",
+	"bfin-i2s.0",
 	"spi0.76",
 };
 static struct platform_device bfin_ad1836_machine = {
@@ -1296,7 +1295,7 @@ static struct spi_board_info bfin_spi_bo
 	},
 #endif
 };
-#if defined(CONFIG_SPI_BFIN6XX) || defined(CONFIG_SPI_BFIN6XX_MODULE)
+#if IS_ENABLED(CONFIG_SPI_BFIN_V3)
 /* SPI (0) */
 static struct resource bfin_spi0_resource[] = {
 	{
@@ -1337,13 +1336,13 @@ static struct resource bfin_spi1_resourc
 };
 
 /* SPI controller data */
-static struct bfin6xx_spi_master bf60x_spi_master_info0 = {
+static struct bfin_spi3_master bf60x_spi_master_info0 = {
 	.num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS,
 	.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
 };
 
 static struct platform_device bf60x_spi_master0 = {
-	.name = "bfin-spi",
+	.name = "bfin-spi3",
 	.id = 0, /* Bus number */
 	.num_resources = ARRAY_SIZE(bfin_spi0_resource),
 	.resource = bfin_spi0_resource,
@@ -1352,13 +1351,13 @@ static struct platform_device bf60x_spi_
 	},
 };
 
-static struct bfin6xx_spi_master bf60x_spi_master_info1 = {
+static struct bfin_spi3_master bf60x_spi_master_info1 = {
 	.num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS,
 	.pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
 };
 
 static struct platform_device bf60x_spi_master1 = {
-	.name = "bfin-spi",
+	.name = "bfin-spi3",
 	.id = 1, /* Bus number */
 	.num_resources = ARRAY_SIZE(bfin_spi1_resource),
 	.resource = bfin_spi1_resource,
@@ -1534,7 +1533,7 @@ static struct platform_device *ezkit_dev
 	&bfin_sdh_device,
 #endif
 
-#if defined(CONFIG_SPI_BFIN6XX) || defined(CONFIG_SPI_BFIN6XX_MODULE)
+#if IS_ENABLED(CONFIG_SPI_BFIN_V3)
 	&bf60x_spi_master0,
 	&bf60x_spi_master1,
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-common/cache-c.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-common/cache-c.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-common/cache-c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-common/cache-c.c	2013-08-25 20:43:22.000000000 -0400
@@ -52,7 +52,7 @@ bfin_cache_init(struct cplb_entry *cplb_
 }
 
 #ifdef CONFIG_BFIN_ICACHE
-void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
+void bfin_icache_init(struct cplb_entry *icplb_tbl)
 {
 	bfin_cache_init(icplb_tbl, ICPLB_ADDR0, ICPLB_DATA0, IMEM_CONTROL,
 		(IMC | ENICPLB));
@@ -60,7 +60,7 @@ void __cpuinit bfin_icache_init(struct c
 #endif
 
 #ifdef CONFIG_BFIN_DCACHE
-void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
+void bfin_dcache_init(struct cplb_entry *dcplb_tbl)
 {
 	/*
 	 *  Anomaly notes:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-common/ints-priority.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-common/ints-priority.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-common/ints-priority.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-common/ints-priority.c	2013-08-25 20:43:22.000000000 -0400
@@ -1281,7 +1281,7 @@ static struct irq_chip bfin_gpio_irqchip
 	.irq_set_wake = bfin_gpio_set_wake,
 };
 
-void __cpuinit init_exception_vectors(void)
+void init_exception_vectors(void)
 {
 	/* cannot program in software:
 	 * evt0 - emulation (jtag)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mach-common/smp.c linux-libre-3.11-rc7-gnu/arch/blackfin/mach-common/smp.c
--- linux-libre-3.10-gnu/arch/blackfin/mach-common/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mach-common/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,9 +46,10 @@ struct corelock_slot corelock __attribut
 unsigned long blackfin_iflush_l1_entry[NR_CPUS];
 #endif
 
-struct blackfin_initial_pda __cpuinitdata initial_pda_coreb;
+struct blackfin_initial_pda initial_pda_coreb;
 
 enum ipi_message_type {
+	BFIN_IPI_NONE,
 	BFIN_IPI_TIMER,
 	BFIN_IPI_RESCHEDULE,
 	BFIN_IPI_CALL_FUNC,
@@ -72,8 +73,8 @@ static DEFINE_SPINLOCK(stop_lock);
 
 /* Simple FIFO buffer, overflow leads to panic */
 struct ipi_data {
-	unsigned long count;
-	unsigned long bits;
+	atomic_t count;
+	atomic_t bits;
 };
 
 static DEFINE_PER_CPU(struct ipi_data, bfin_ipi);
@@ -146,8 +147,7 @@ static irqreturn_t ipi_handler_int1(int
 	platform_clear_ipi(cpu, IRQ_SUPPLE_1);
 
 	bfin_ipi_data = &__get_cpu_var(bfin_ipi);
-	smp_mb();
-	while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) {
+	while ((pending = atomic_xchg(&bfin_ipi_data->bits, 0)) != 0) {
 		msg = 0;
 		do {
 			msg = find_next_bit(&pending, BITS_PER_LONG, msg + 1);
@@ -170,9 +170,8 @@ static irqreturn_t ipi_handler_int1(int
 				ipi_cpu_stop(cpu);
 				break;
 			}
+			atomic_dec(&bfin_ipi_data->count);
 		} while (msg < BITS_PER_LONG);
-
-		smp_mb();
 	}
 	return IRQ_HANDLED;
 }
@@ -183,8 +182,8 @@ static void bfin_ipi_init(void)
 	struct ipi_data *bfin_ipi_data;
 	for_each_possible_cpu(cpu) {
 		bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
-		bfin_ipi_data->bits = 0;
-		bfin_ipi_data->count = 0;
+		atomic_set(&bfin_ipi_data->bits, 0);
+		atomic_set(&bfin_ipi_data->count, 0);
 	}
 }
 
@@ -195,12 +194,10 @@ void send_ipi(const struct cpumask *cpum
 	unsigned long flags;
 
 	local_irq_save(flags);
-	smp_mb();
 	for_each_cpu(cpu, cpumask) {
 		bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
-		smp_mb();
-		set_bit(msg, &bfin_ipi_data->bits);
-		bfin_ipi_data->count++;
+		atomic_set_mask((1 << msg), &bfin_ipi_data->bits);
+		atomic_inc(&bfin_ipi_data->count);
 		platform_send_ipi_cpu(cpu, IRQ_SUPPLE_1);
 	}
 
@@ -249,7 +246,7 @@ void smp_send_stop(void)
 	return;
 }
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
+int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	int ret;
 
@@ -262,7 +259,7 @@ int __cpuinit __cpu_up(unsigned int cpu,
 	return ret;
 }
 
-static void __cpuinit setup_secondary(unsigned int cpu)
+static void setup_secondary(unsigned int cpu)
 {
 	unsigned long ilat;
 
@@ -280,7 +277,7 @@ static void __cpuinit setup_secondary(un
 	    IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
 }
 
-void __cpuinit secondary_start_kernel(void)
+void secondary_start_kernel(void)
 {
 	unsigned int cpu = smp_processor_id();
 	struct mm_struct *mm = &init_mm;
@@ -319,7 +316,6 @@ void __cpuinit secondary_start_kernel(vo
 	setup_secondary(cpu);
 
 	platform_secondary_init(cpu);
-
 	/* setup local core timer */
 	bfin_local_timer_setup();
 
@@ -335,6 +331,8 @@ void __cpuinit secondary_start_kernel(vo
 	 */
 	calibrate_delay();
 
+	/* We are done with local CPU inits, unblock the boot CPU. */
+	set_cpu_online(cpu, true);
 	cpu_startup_entry(CPUHP_ONLINE);
 }
 
@@ -404,7 +402,7 @@ EXPORT_SYMBOL(resync_core_dcache);
 #endif
 
 #ifdef CONFIG_HOTPLUG_CPU
-int __cpuexit __cpu_disable(void)
+int __cpu_disable(void)
 {
 	unsigned int cpu = smp_processor_id();
 
@@ -417,7 +415,7 @@ int __cpuexit __cpu_disable(void)
 
 static DECLARE_COMPLETION(cpu_killed);
 
-int __cpuexit __cpu_die(unsigned int cpu)
+int __cpu_die(unsigned int cpu)
 {
 	return wait_for_completion_timeout(&cpu_killed, 5000);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/blackfin/mm/init.c linux-libre-3.11-rc7-gnu/arch/blackfin/mm/init.c
--- linux-libre-3.10-gnu/arch/blackfin/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/blackfin/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -90,50 +90,24 @@ asmlinkage void __init init_pda(void)
 
 void __init mem_init(void)
 {
-	unsigned int codek = 0, datak = 0, initk = 0;
-	unsigned int reservedpages = 0, freepages = 0;
-	unsigned long tmp;
-	unsigned long start_mem = memory_start;
-	unsigned long end_mem = memory_end;
-
-	end_mem &= PAGE_MASK;
-	high_memory = (void *)end_mem;
+	char buf[64];
 
-	start_mem = PAGE_ALIGN(start_mem);
-	max_mapnr = num_physpages = MAP_NR(high_memory);
-	printk(KERN_DEBUG "Kernel managed physical pages: %lu\n", num_physpages);
+	high_memory = (void *)(memory_end & PAGE_MASK);
+	max_mapnr = MAP_NR(high_memory);
+	printk(KERN_DEBUG "Kernel managed physical pages: %lu\n", max_mapnr);
 
 	/* This will put all low memory onto the freelists. */
-	totalram_pages = free_all_bootmem();
-
-	reservedpages = 0;
-	for (tmp = ARCH_PFN_OFFSET; tmp < max_mapnr; tmp++)
-		if (PageReserved(pfn_to_page(tmp)))
-			reservedpages++;
-	freepages =  max_mapnr - ARCH_PFN_OFFSET - reservedpages;
-
-	/* do not count in kernel image between _rambase and _ramstart */
-	reservedpages -= (_ramstart - _rambase) >> PAGE_SHIFT;
-#if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263)
-	reservedpages += (_ramend - memory_end - DMA_UNCACHED_REGION) >> PAGE_SHIFT;
-#endif
-
-	codek = (_etext - _stext) >> 10;
-	initk = (__init_end - __init_begin) >> 10;
-	datak = ((_ramstart - _rambase) >> 10) - codek - initk;
+	free_all_bootmem();
 
-	printk(KERN_INFO
-	     "Memory available: %luk/%luk RAM, "
-		"(%uk init code, %uk kernel code, %uk data, %uk dma, %uk reserved)\n",
-		(unsigned long) freepages << (PAGE_SHIFT-10), (_ramend - CONFIG_PHY_RAM_BASE_ADDRESS) >> 10,
-		initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10)));
+	snprintf(buf, sizeof(buf) - 1, "%uK DMA", DMA_UNCACHED_REGION >> 10);
+	mem_init_print_info(buf);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
 #ifndef CONFIG_MPU
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 #endif
 }
 #endif
@@ -141,7 +115,7 @@ void __init free_initrd_mem(unsigned lon
 void __init_refok free_initmem(void)
 {
 #if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU
-	free_initmem_default(0);
+	free_initmem_default(-1);
 	if (memory_start == (unsigned long)(&__init_end))
 		memory_start = (unsigned long)(&__init_begin);
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/c6x/include/asm/Kbuild linux-libre-3.11-rc7-gnu/arch/c6x/include/asm/Kbuild
--- linux-libre-3.10-gnu/arch/c6x/include/asm/Kbuild	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/c6x/include/asm/Kbuild	2013-08-25 20:43:22.000000000 -0400
@@ -55,3 +55,4 @@ generic-y += types.h
 generic-y += ucontext.h
 generic-y += user.h
 generic-y += vga.h
+generic-y += xor.h
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/c6x/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/c6x/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/c6x/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/c6x/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -71,7 +71,6 @@ extern unsigned long empty_zero_page;
  * No page table caches to initialise
  */
 #define pgtable_cache_init()   do { } while (0)
-#define io_remap_pfn_range      remap_pfn_range
 
 #include <asm-generic/pgtable.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/c6x/kernel/vmlinux.lds.S linux-libre-3.11-rc7-gnu/arch/c6x/kernel/vmlinux.lds.S
--- linux-libre-3.10-gnu/arch/c6x/kernel/vmlinux.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/c6x/kernel/vmlinux.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -54,16 +54,15 @@ SECTIONS
 	}
 
 	. = ALIGN(PAGE_SIZE);
+	__init_begin = .;
 	.init :
 	{
-		_stext = .;
 		_sinittext = .;
 		HEAD_TEXT
 		INIT_TEXT
 		_einittext = .;
 	}
 
-	__init_begin = _stext;
 	INIT_DATA_SECTION(16)
 
 	PERCPU_SECTION(128)
@@ -74,6 +73,7 @@ SECTIONS
 	.text :
 	{
 		_text = .;
+		_stext = .;
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/c6x/mm/init.c linux-libre-3.11-rc7-gnu/arch/c6x/mm/init.c
--- linux-libre-3.10-gnu/arch/c6x/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/c6x/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/initrd.h>
 
 #include <asm/sections.h>
+#include <asm/uaccess.h>
 
 /*
  * ZERO_PAGE is a special page that is used for zero-initialized
@@ -57,31 +58,22 @@ void __init paging_init(void)
 
 void __init mem_init(void)
 {
-	int codek, datak;
-	unsigned long tmp;
-	unsigned long len = memory_end - memory_start;
-
 	high_memory = (void *)(memory_end & PAGE_MASK);
 
 	/* this will put all memory onto the freelists */
-	totalram_pages = free_all_bootmem();
-
-	codek = (_etext - _stext) >> 10;
-	datak = (_end - _sdata) >> 10;
+	free_all_bootmem();
 
-	tmp = nr_free_pages() << PAGE_SHIFT;
-	printk(KERN_INFO "Memory: %luk/%luk RAM (%dk kernel code, %dk data)\n",
-	       tmp >> 10, len >> 10, codek, datak);
+	mem_init_print_info(NULL);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
 
 void __init free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/arch-v10/drivers/Kconfig linux-libre-3.11-rc7-gnu/arch/cris/arch-v10/drivers/Kconfig
--- linux-libre-3.10-gnu/arch/cris/arch-v10/drivers/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/arch-v10/drivers/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -2,9 +2,7 @@ if ETRAX_ARCH_V10
 
 config ETRAX_ETHERNET
 	bool "Ethernet support"
-	depends on ETRAX_ARCH_V10
-	select ETHERNET
-	select NET_CORE
+	depends on ETRAX_ARCH_V10 && NETDEVICES
 	select MII
 	help
 	  This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/arch-v10/kernel/kgdb.c linux-libre-3.11-rc7-gnu/arch/cris/arch-v10/kernel/kgdb.c
--- linux-libre-3.10-gnu/arch/cris/arch-v10/kernel/kgdb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/arch-v10/kernel/kgdb.c	2013-08-25 20:43:22.000000000 -0400
@@ -230,46 +230,6 @@ struct register_image
 	unsigned int    usp;   /* 0x66 User mode stack pointer */
 } registers;
 
-/************** Prototypes for local library functions ***********************/
-
-/* Copy of strcpy from libc. */
-static char *gdb_cris_strcpy (char *s1, const char *s2);
-
-/* Copy of strlen from libc. */
-static int gdb_cris_strlen (const char *s);
-
-/* Copy of memchr from libc. */
-static void *gdb_cris_memchr (const void *s, int c, int n);
-
-/* Copy of strtol from libc. Does only support base 16. */
-static int gdb_cris_strtol (const char *s, char **endptr, int base);
-
-/********************** Prototypes for local functions. **********************/
-/* Copy the content of a register image into another. The size n is
-   the size of the register image. Due to struct assignment generation of
-   memcpy in libc. */
-static void copy_registers (registers *dptr, registers *sptr, int n);
-
-/* Copy the stored registers from the stack. Put the register contents
-   of thread thread_id in the struct reg. */
-static void copy_registers_from_stack (int thread_id, registers *reg);
-
-/* Copy the registers to the stack. Put the register contents of thread
-   thread_id from struct reg to the stack. */
-static void copy_registers_to_stack (int thread_id, registers *reg);
-
-/* Write a value to a specified register regno in the register image
-   of the current thread. */
-static int write_register (int regno, char *val);
-
-/* Write a value to a specified register in the stack of a thread other
-   than the current thread. */
-static int write_stack_register(int thread_id, int regno, char *valptr);
-
-/* Read a value from a specified register in the register image. Returns the
-   status of the read operation. The register value is returned in valptr. */
-static int read_register (char regno, unsigned int *valptr);
-
 /* Serial port, reads one character. ETRAX 100 specific. from debugport.c */
 int getDebugChar (void);
 
@@ -278,42 +238,6 @@ void putDebugChar (int val);
 
 void enableDebugIRQ (void);
 
-/* Returns the integer equivalent of a hexadecimal character. */
-static int hex (char ch);
-
-/* Convert the memory, pointed to by mem into hexadecimal representation.
-   Put the result in buf, and return a pointer to the last character
-   in buf (null). */
-static char *mem2hex (char *buf, unsigned char *mem, int count);
-
-/* Convert the array, in hexadecimal representation, pointed to by buf into
-   binary representation. Put the result in mem, and return a pointer to
-   the character after the last byte written. */
-static unsigned char *hex2mem (unsigned char *mem, char *buf, int count);
-
-/* Put the content of the array, in binary representation, pointed to by buf
-   into memory pointed to by mem, and return a pointer to
-   the character after the last byte written. */
-static unsigned char *bin2mem (unsigned char *mem, unsigned char *buf, int count);
-
-/* Await the sequence $<data>#<checksum> and store <data> in the array buffer
-   returned. */
-static void getpacket (char *buffer);
-
-/* Send $<data>#<checksum> from the <data> in the array buffer. */
-static void putpacket (char *buffer);
-
-/* Build and send a response packet in order to inform the host the
-   stub is stopped. */
-static void stub_is_stopped (int sigval);
-
-/* All expected commands are sent from remote.c. Send a response according
-   to the description in remote.c. */
-static void handle_exception (int sigval);
-
-/* Performs a complete re-start from scratch. ETRAX specific. */
-static void kill_restart (void);
-
 /******************** Prototypes for global functions. ***********************/
 
 /* The string str is prepended with the GDB printout token and sent. */
@@ -336,10 +260,6 @@ extern unsigned char executing_task;
 /* The number of characters used for a 64 bit thread identifier. */
 #define HEXCHARS_IN_THREAD_ID 16
 
-/* Avoid warning as the internal_stack is not used in the C-code. */
-#define USEDVAR(name)    { if (name) { ; } }
-#define USEDFUN(name) { void (*pf)(void) = (void *)name; USEDVAR(pf) }
-
 /********************************** Packet I/O ******************************/
 /* BUFMAX defines the maximum number of characters in
    inbound/outbound buffers */
@@ -405,7 +325,7 @@ static int register_size[] =
 
 /* Contains the register image of the executing thread in the assembler
    part of the code in order to avoid horrible addressing modes. */
-static registers reg;
+registers cris_reg;
 
 /* FIXME: Should this be used? Delete otherwise. */
 /* Contains the assumed consistency state of the register image. Uses the
@@ -413,7 +333,7 @@ static registers reg;
 static int consistency_status = SUCCESS;
 
 /********************************** Handle exceptions ************************/
-/* The variable reg contains the register image associated with the
+/* The variable cris_reg contains the register image associated with the
    current_thread_c variable. It is a complete register image created at
    entry. The reg_g contains a register image of a task where the general
    registers are taken from the stack and all special registers are taken
@@ -421,18 +341,10 @@ static int consistency_status = SUCCESS;
    in order to provide access mainly for 'g', 'G' and 'P'.
 */
 
-/* Need two task id pointers in order to handle Hct and Hgt commands. */
-static int current_thread_c = 0;
-static int current_thread_g = 0;
-
-/* Need two register images in order to handle Hct and Hgt commands. The
-   variable reg_g is in addition to reg above. */
-static registers reg_g;
-
 /********************************** Breakpoint *******************************/
 /* Use an internal stack in the breakpoint and interrupt response routines */
 #define INTERNAL_STACK_SIZE 1024
-static char internal_stack[INTERNAL_STACK_SIZE];
+char internal_stack[INTERNAL_STACK_SIZE];
 
 /* Due to the breakpoint return pointer, a state variable is needed to keep
    track of whether it is a static (compiled) or dynamic (gdb-invoked)
@@ -500,164 +412,6 @@ gdb_cris_strtol (const char *s, char **e
 	return x;
 }
 
-/********************************* Register image ****************************/
-/* Copy the content of a register image into another. The size n is
-   the size of the register image. Due to struct assignment generation of
-   memcpy in libc. */
-static void
-copy_registers (registers *dptr, registers *sptr, int n)
-{
-	unsigned char *dreg;
-	unsigned char *sreg;
-	
-	for (dreg = (unsigned char*)dptr, sreg = (unsigned char*)sptr; n > 0; n--)
-		*dreg++ = *sreg++;
-}
-
-#ifdef PROCESS_SUPPORT
-/* Copy the stored registers from the stack. Put the register contents
-   of thread thread_id in the struct reg. */
-static void
-copy_registers_from_stack (int thread_id, registers *regptr)
-{
-	int j;
-	stack_registers *s = (stack_registers *)stack_list[thread_id];
-	unsigned int *d = (unsigned int *)regptr;
-	
-	for (j = 13; j >= 0; j--)
-		*d++ = s->r[j];
-	regptr->sp = (unsigned int)stack_list[thread_id];
-	regptr->pc = s->pc;
-	regptr->dccr = s->dccr;
-	regptr->srp = s->srp;
-}
-
-/* Copy the registers to the stack. Put the register contents of thread
-   thread_id from struct reg to the stack. */
-static void
-copy_registers_to_stack (int thread_id, registers *regptr)
-{
-	int i;
-	stack_registers *d = (stack_registers *)stack_list[thread_id];
-	unsigned int *s = (unsigned int *)regptr;
-	
-	for (i = 0; i < 14; i++) {
-		d->r[i] = *s++;
-	}
-	d->pc = regptr->pc;
-	d->dccr = regptr->dccr;
-	d->srp = regptr->srp;
-}
-#endif
-
-/* Write a value to a specified register in the register image of the current
-   thread. Returns status code SUCCESS, E02 or E05. */
-static int
-write_register (int regno, char *val)
-{
-	int status = SUCCESS;
-	registers *current_reg = &reg;
-
-        if (regno >= R0 && regno <= PC) {
-		/* 32-bit register with simple offset. */
-		hex2mem ((unsigned char *)current_reg + regno * sizeof(unsigned int),
-			 val, sizeof(unsigned int));
-	}
-        else if (regno == P0 || regno == VR || regno == P4 || regno == P8) {
-		/* Do not support read-only registers. */
-		status = E02;
-	}
-        else if (regno == CCR) {
-		/* 16 bit register with complex offset. (P4 is read-only, P6 is not implemented, 
-                   and P7 (MOF) is 32 bits in ETRAX 100LX. */
-		hex2mem ((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short),
-			 val, sizeof(unsigned short));
-	}
-	else if (regno >= MOF && regno <= USP) {
-		/* 32 bit register with complex offset.  (P8 has been taken care of.) */
-		hex2mem ((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int),
-			 val, sizeof(unsigned int));
-	} 
-        else {
-		/* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */
-		status = E05;
-	}
-	return status;
-}
-
-#ifdef PROCESS_SUPPORT
-/* Write a value to a specified register in the stack of a thread other
-   than the current thread. Returns status code SUCCESS or E07. */
-static int
-write_stack_register (int thread_id, int regno, char *valptr)
-{
-	int status = SUCCESS;
-	stack_registers *d = (stack_registers *)stack_list[thread_id];
-	unsigned int val;
-	
-	hex2mem ((unsigned char *)&val, valptr, sizeof(unsigned int));
-	if (regno >= R0 && regno < SP) {
-		d->r[regno] = val;
-	}
-	else if (regno == SP) {
-		stack_list[thread_id] = val;
-	}
-	else if (regno == PC) {
-		d->pc = val;
-	}
-	else if (regno == SRP) {
-		d->srp = val;
-	}
-	else if (regno == DCCR) {
-		d->dccr = val;
-	}
-	else {
-		/* Do not support registers in the current thread. */
-		status = E07;
-	}
-	return status;
-}
-#endif
-
-/* Read a value from a specified register in the register image. Returns the
-   value in the register or -1 for non-implemented registers.
-   Should check consistency_status after a call which may be E05 after changes
-   in the implementation. */
-static int
-read_register (char regno, unsigned int *valptr)
-{
-	registers *current_reg = &reg;
-
-	if (regno >= R0 && regno <= PC) {
-		/* 32-bit register with simple offset. */
-		*valptr = *(unsigned int *)((char *)current_reg + regno * sizeof(unsigned int));
-                return SUCCESS;
-	}
-	else if (regno == P0 || regno == VR) {
-		/* 8 bit register with complex offset. */
-		*valptr = (unsigned int)(*(unsigned char *)
-                                         ((char *)&(current_reg->p0) + (regno-P0) * sizeof(char)));
-                return SUCCESS;
-	}
-	else if (regno == P4 || regno == CCR) {
-		/* 16 bit register with complex offset. */
-		*valptr = (unsigned int)(*(unsigned short *)
-                                         ((char *)&(current_reg->p4) + (regno-P4) * sizeof(unsigned short)));
-                return SUCCESS;
-	}
-	else if (regno >= MOF && regno <= USP) {
-		/* 32 bit register with complex offset. */
-		*valptr = *(unsigned int *)((char *)&(current_reg->p8)
-                                            + (regno-P8) * sizeof(unsigned int));
-                return SUCCESS;
-	}
-	else {
-		/* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */
-		consistency_status = E05;
-		return E05;
-	}
-}
-
 /********************************** Packet I/O ******************************/
 /* Returns the integer equivalent of a hexadecimal character. */
 static int
@@ -676,8 +430,6 @@ hex (char ch)
    Put the result in buf, and return a pointer to the last character
    in buf (null). */
 
-static int do_printk = 0;
-
 static char *
 mem2hex(char *buf, unsigned char *mem, int count)
 {
@@ -761,7 +513,7 @@ getpacket (char *buffer)
 		xmitcsum = -1;
 		count = 0;
 		/* Read until a # or the end of the buffer is reached */
-		while (count < BUFMAX) {
+		while (count < BUFMAX - 1) {
 			ch = getDebugChar ();
 			if (ch == '#')
 				break;
@@ -845,6 +597,81 @@ putDebugString (const unsigned char *str
         putpacket(remcomOutBuffer);
 }
 
+/********************************* Register image ****************************/
+/* Write a value to a specified register in the register image of the current
+   thread. Returns status code SUCCESS, E02 or E05. */
+static int
+write_register (int regno, char *val)
+{
+	int status = SUCCESS;
+	registers *current_reg = &cris_reg;
+
+        if (regno >= R0 && regno <= PC) {
+		/* 32-bit register with simple offset. */
+		hex2mem ((unsigned char *)current_reg + regno * sizeof(unsigned int),
+			 val, sizeof(unsigned int));
+	}
+        else if (regno == P0 || regno == VR || regno == P4 || regno == P8) {
+		/* Do not support read-only registers. */
+		status = E02;
+	}
+        else if (regno == CCR) {
+		/* 16 bit register with complex offset. (P4 is read-only, P6 is not implemented, 
+                   and P7 (MOF) is 32 bits in ETRAX 100LX. */
+		hex2mem ((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short),
+			 val, sizeof(unsigned short));
+	}
+	else if (regno >= MOF && regno <= USP) {
+		/* 32 bit register with complex offset.  (P8 has been taken care of.) */
+		hex2mem ((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int),
+			 val, sizeof(unsigned int));
+	} 
+        else {
+		/* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */
+		status = E05;
+	}
+	return status;
+}
+
+/* Read a value from a specified register in the register image. Returns the
+   value in the register or -1 for non-implemented registers.
+   Should check consistency_status after a call which may be E05 after changes
+   in the implementation. */
+static int
+read_register (char regno, unsigned int *valptr)
+{
+	registers *current_reg = &cris_reg;
+
+	if (regno >= R0 && regno <= PC) {
+		/* 32-bit register with simple offset. */
+		*valptr = *(unsigned int *)((char *)current_reg + regno * sizeof(unsigned int));
+                return SUCCESS;
+	}
+	else if (regno == P0 || regno == VR) {
+		/* 8 bit register with complex offset. */
+		*valptr = (unsigned int)(*(unsigned char *)
+                                         ((char *)&(current_reg->p0) + (regno-P0) * sizeof(char)));
+                return SUCCESS;
+	}
+	else if (regno == P4 || regno == CCR) {
+		/* 16 bit register with complex offset. */
+		*valptr = (unsigned int)(*(unsigned short *)
+                                         ((char *)&(current_reg->p4) + (regno-P4) * sizeof(unsigned short)));
+                return SUCCESS;
+	}
+	else if (regno >= MOF && regno <= USP) {
+		/* 32 bit register with complex offset. */
+		*valptr = *(unsigned int *)((char *)&(current_reg->p8)
+                                            + (regno-P8) * sizeof(unsigned int));
+                return SUCCESS;
+	}
+	else {
+		/* Do not support nonexisting or unimplemented registers (P2, P3, and P6). */
+		consistency_status = E05;
+		return E05;
+	}
+}
+
 /********************************** Handle exceptions ************************/
 /* Build and send a response packet in order to inform the host the
    stub is stopped. TAAn...:r...;n...:r...;n...:r...;
@@ -891,26 +718,6 @@ stub_is_stopped(int sigval)
                 
 	}
 
-#ifdef PROCESS_SUPPORT
-	/* Store the registers of the executing thread. Assume that both step,
-	   continue, and register content requests are with respect to this
-	   thread. The executing task is from the operating system scheduler. */
-
-	current_thread_c = executing_task;
-	current_thread_g = executing_task;
-
-	/* A struct assignment translates into a libc memcpy call. Avoid
-	   all libc functions in order to prevent recursive break points. */
-	copy_registers (&reg_g, &reg, sizeof(registers));
-
-	/* Store thread:r...; with the executing task TID. */
-	gdb_cris_strcpy (&remcomOutBuffer[pos], "thread:");
-	pos += gdb_cris_strlen ("thread:");
-	remcomOutBuffer[pos++] = hex_asc_hi(executing_task);
-	remcomOutBuffer[pos++] = hex_asc_lo(executing_task);
-	gdb_cris_strcpy (&remcomOutBuffer[pos], ";");
-#endif
-
 	/* null-terminate and send it off */
 
 	*ptr = 0;
@@ -918,16 +725,18 @@ stub_is_stopped(int sigval)
 	putpacket (remcomOutBuffer);
 }
 
+/* Performs a complete re-start from scratch. */
+static void
+kill_restart (void)
+{
+	machine_restart("");
+}
+
 /* All expected commands are sent from remote.c. Send a response according
    to the description in remote.c. */
-static void
+void
 handle_exception (int sigval)
 {
-	/* Avoid warning of not used. */
-
-	USEDFUN(handle_exception);
-	USEDVAR(internal_stack[0]);
-
 	/* Send response. */
 
 	stub_is_stopped (sigval);
@@ -943,19 +752,7 @@ handle_exception (int sigval)
 				   in a register  are in the same order the machine uses.
 				   Failure: void. */
 				
-				{
-#ifdef PROCESS_SUPPORT
-					/* Use the special register content in the executing thread. */
-					copy_registers (&reg_g, &reg, sizeof(registers));
-					/* Replace the content available on the stack. */
-					if (current_thread_g != executing_task) {
-						copy_registers_from_stack (current_thread_g, &reg_g);
-					}
-					mem2hex ((unsigned char *)remcomOutBuffer, (unsigned char *)&reg_g, sizeof(registers));
-#else
-					mem2hex(remcomOutBuffer, (char *)&reg, sizeof(registers));
-#endif
-				}
+				mem2hex(remcomOutBuffer, (char *)&cris_reg, sizeof(registers));
 				break;
 				
 			case 'G':
@@ -963,17 +760,7 @@ handle_exception (int sigval)
 				   Each byte of register data  is described by two hex digits.
 				   Success: OK
 				   Failure: void. */
-#ifdef PROCESS_SUPPORT
-				hex2mem ((unsigned char *)&reg_g, &remcomInBuffer[1], sizeof(registers));
-				if (current_thread_g == executing_task) {
-					copy_registers (&reg, &reg_g, sizeof(registers));
-				}
-				else {
-					copy_registers_to_stack(current_thread_g, &reg_g);
-				}
-#else
-				hex2mem((char *)&reg, &remcomInBuffer[1], sizeof(registers));
-#endif
+				hex2mem((char *)&cris_reg, &remcomInBuffer[1], sizeof(registers));
 				gdb_cris_strcpy (remcomOutBuffer, "OK");
 				break;
 				
@@ -989,12 +776,7 @@ handle_exception (int sigval)
 					char *suffix;
 					int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);
 					int status;
-#ifdef PROCESS_SUPPORT
-					if (current_thread_g != executing_task)
-						status = write_stack_register (current_thread_g, regno, suffix+1);
-					else
-#endif
-						status = write_register (regno, suffix+1);
+					status = write_register (regno, suffix+1);
 
 					switch (status) {
 						case E02:
@@ -1073,7 +855,7 @@ handle_exception (int sigval)
 				   Success: return to the executing thread.
 				   Failure: will never know. */
 				if (remcomInBuffer[1] != '\0') {
-					reg.pc = gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
+					cris_reg.pc = gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
 				}
 				enableDebugIRQ();
 				return;
@@ -1129,119 +911,6 @@ handle_exception (int sigval)
 				   Not supported: E04 */
 				gdb_cris_strcpy (remcomOutBuffer, error_message[E04]);
 				break;
-#ifdef PROCESS_SUPPORT
-
-			case 'T':
-				/* Thread alive. TXX
-				   Is thread XX alive?
-				   Success: OK, thread XX is alive.
-				   Failure: E03, thread XX is dead. */
-				{
-					int thread_id = (int)gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
-					/* Cannot tell whether it is alive or not. */
-					if (thread_id >= 0 && thread_id < number_of_tasks)
-						gdb_cris_strcpy (remcomOutBuffer, "OK");
-				}
-				break;
-								
-			case 'H':
-				/* Set thread for subsequent operations: Hct
-				   c = 'c' for thread used in step and continue;
-				   t can be -1 for all threads.
-				   c = 'g' for thread used in other  operations.
-				   t = 0 means pick any thread.
-				   Success: OK
-				   Failure: E01 */
-				{
-					int thread_id = gdb_cris_strtol (&remcomInBuffer[2], 0, 16);
-					if (remcomInBuffer[1] == 'c') {
-						/* c = 'c' for thread used in step and continue */
-						/* Do not change current_thread_c here. It would create a mess in
-						   the scheduler. */
-						gdb_cris_strcpy (remcomOutBuffer, "OK");
-					}
-					else if (remcomInBuffer[1] == 'g') {
-						/* c = 'g' for thread used in other  operations.
-						   t = 0 means pick any thread. Impossible since the scheduler does
-						   not allow that. */
-						if (thread_id >= 0 && thread_id < number_of_tasks) {
-							current_thread_g = thread_id;
-							gdb_cris_strcpy (remcomOutBuffer, "OK");
-						}
-						else {
-							/* Not expected - send an error message. */
-							gdb_cris_strcpy (remcomOutBuffer, error_message[E01]);
-						}
-					}
-					else {
-						/* Not expected - send an error message. */
-						gdb_cris_strcpy (remcomOutBuffer, error_message[E01]);
-					}
-				}
-				break;
-				
-			case 'q':
-			case 'Q':
-				/* Query of general interest. qXXXX
-				   Set general value XXXX. QXXXX=yyyy */
-				{
-					int pos;
-					int nextpos;
-					int thread_id;
-					
-					switch (remcomInBuffer[1]) {
-						case 'C':
-							/* Identify the remote current thread. */
-							gdb_cris_strcpy (&remcomOutBuffer[0], "QC");
-							remcomOutBuffer[2] = hex_asc_hi(current_thread_c);
-							remcomOutBuffer[3] = hex_asc_lo(current_thread_c);
-							remcomOutBuffer[4] = '\0';
-							break;
-						case 'L':
-							gdb_cris_strcpy (&remcomOutBuffer[0], "QM");
-							/* Reply with number of threads. */
-							if (os_is_started()) {
-								remcomOutBuffer[2] = hex_asc_hi(number_of_tasks);
-								remcomOutBuffer[3] = hex_asc_lo(number_of_tasks);
-							}
-							else {
-								remcomOutBuffer[2] = hex_asc_hi(0);
-								remcomOutBuffer[3] = hex_asc_lo(1);
-							}
-							/* Done with the reply. */
-							remcomOutBuffer[4] = hex_asc_lo(1);
-							pos = 5;
-							/* Expects the argument thread id. */
-							for (; pos < (5 + HEXCHARS_IN_THREAD_ID); pos++)
-								remcomOutBuffer[pos] = remcomInBuffer[pos];
-							/* Reply with the thread identifiers. */
-							if (os_is_started()) {
-								/* Store the thread identifiers of all tasks. */
-								for (thread_id = 0; thread_id < number_of_tasks; thread_id++) {
-									nextpos = pos + HEXCHARS_IN_THREAD_ID - 1;
-									for (; pos < nextpos; pos ++)
-										remcomOutBuffer[pos] = hex_asc_lo(0);
-									remcomOutBuffer[pos++] = hex_asc_lo(thread_id);
-								}
-							}
-							else {
-								/* Store the thread identifier of the boot task. */
-								nextpos = pos + HEXCHARS_IN_THREAD_ID - 1;
-								for (; pos < nextpos; pos ++)
-									remcomOutBuffer[pos] = hex_asc_lo(0);
-								remcomOutBuffer[pos++] = hex_asc_lo(current_thread_c);
-							}
-							remcomOutBuffer[pos] = '\0';
-							break;
-						default:
-							/* Not supported: "" */
-							/* Request information about section offsets: qOffsets. */
-							remcomOutBuffer[0] = 0;
-							break;
-					}
-				}
-				break;
-#endif /* PROCESS_SUPPORT */
 				
 			default:
 				/* The stub should ignore other request and send an empty
@@ -1254,13 +923,6 @@ handle_exception (int sigval)
 	}
 }
 
-/* Performs a complete re-start from scratch. */
-static void
-kill_restart ()
-{
-	machine_restart("");
-}
-
 /********************************** Breakpoint *******************************/
 /* The hook for both a static (compiled) and a dynamic breakpoint set by GDB.
    An internal stack is used by the stub. The register image of the caller is
@@ -1270,93 +932,93 @@ kill_restart ()
 
 void kgdb_handle_breakpoint(void);
 
-asm ("
-  .global kgdb_handle_breakpoint
-kgdb_handle_breakpoint:
-;;
-;; Response to the break-instruction
-;;
-;; Create a register image of the caller
-;;
-  move     $dccr,[reg+0x5E] ; Save the flags in DCCR before disable interrupts
-  di                        ; Disable interrupts
-  move.d   $r0,[reg]        ; Save R0
-  move.d   $r1,[reg+0x04]   ; Save R1
-  move.d   $r2,[reg+0x08]   ; Save R2
-  move.d   $r3,[reg+0x0C]   ; Save R3
-  move.d   $r4,[reg+0x10]   ; Save R4
-  move.d   $r5,[reg+0x14]   ; Save R5
-  move.d   $r6,[reg+0x18]   ; Save R6
-  move.d   $r7,[reg+0x1C]   ; Save R7
-  move.d   $r8,[reg+0x20]   ; Save R8
-  move.d   $r9,[reg+0x24]   ; Save R9
-  move.d   $r10,[reg+0x28]  ; Save R10
-  move.d   $r11,[reg+0x2C]  ; Save R11
-  move.d   $r12,[reg+0x30]  ; Save R12
-  move.d   $r13,[reg+0x34]  ; Save R13
-  move.d   $sp,[reg+0x38]   ; Save SP (R14)
-;; Due to the old assembler-versions BRP might not be recognized
-  .word 0xE670              ; move brp,$r0
-  subq     2,$r0             ; Set to address of previous instruction.
-  move.d   $r0,[reg+0x3c]   ; Save the address in PC (R15)
-  clear.b  [reg+0x40]      ; Clear P0
-  move     $vr,[reg+0x41]   ; Save special register P1
-  clear.w  [reg+0x42]      ; Clear P4
-  move     $ccr,[reg+0x44]  ; Save special register CCR
-  move     $mof,[reg+0x46]  ; P7
-  clear.d  [reg+0x4A]      ; Clear P8
-  move     $ibr,[reg+0x4E]  ; P9,
-  move     $irp,[reg+0x52]  ; P10,
-  move     $srp,[reg+0x56]  ; P11,
-  move     $dtp0,[reg+0x5A] ; P12, register BAR, assembler might not know BAR
-                            ; P13, register DCCR already saved
-;; Due to the old assembler-versions BRP might not be recognized
-  .word 0xE670              ; move brp,r0
-;; Static (compiled) breakpoints must return to the next instruction in order
-;; to avoid infinite loops. Dynamic (gdb-invoked) must restore the instruction
-;; in order to execute it when execution is continued.
-  test.b   [is_dyn_brkp]    ; Is this a dynamic breakpoint?
-  beq      is_static         ; No, a static breakpoint
-  nop
-  subq     2,$r0              ; rerun the instruction the break replaced
-is_static:
-  moveq    1,$r1
-  move.b   $r1,[is_dyn_brkp] ; Set the state variable to dynamic breakpoint
-  move.d   $r0,[reg+0x62]    ; Save the return address in BRP
-  move     $usp,[reg+0x66]   ; USP
-;;
-;; Handle the communication
-;;
-  move.d   internal_stack+1020,$sp ; Use the internal stack which grows upward
-  moveq    5,$r10                   ; SIGTRAP
-  jsr      handle_exception       ; Interactive routine
-;;
-;; Return to the caller
-;;
-   move.d  [reg],$r0         ; Restore R0
-   move.d  [reg+0x04],$r1    ; Restore R1
-   move.d  [reg+0x08],$r2    ; Restore R2
-   move.d  [reg+0x0C],$r3    ; Restore R3
-   move.d  [reg+0x10],$r4    ; Restore R4
-   move.d  [reg+0x14],$r5    ; Restore R5
-   move.d  [reg+0x18],$r6    ; Restore R6
-   move.d  [reg+0x1C],$r7    ; Restore R7
-   move.d  [reg+0x20],$r8    ; Restore R8
-   move.d  [reg+0x24],$r9    ; Restore R9
-   move.d  [reg+0x28],$r10   ; Restore R10
-   move.d  [reg+0x2C],$r11   ; Restore R11
-   move.d  [reg+0x30],$r12   ; Restore R12
-   move.d  [reg+0x34],$r13   ; Restore R13
-;;
-;; FIXME: Which registers should be restored?
-;;
-   move.d  [reg+0x38],$sp    ; Restore SP (R14)
-   move    [reg+0x56],$srp   ; Restore the subroutine return pointer.
-   move    [reg+0x5E],$dccr  ; Restore DCCR
-   move    [reg+0x66],$usp   ; Restore USP
-   jump    [reg+0x62]       ; A jump to the content in register BRP works.
-   nop                       ;
-");
+asm ("\n"
+"  .global kgdb_handle_breakpoint\n"
+"kgdb_handle_breakpoint:\n"
+";;\n"
+";; Response to the break-instruction\n"
+";;\n"
+";; Create a register image of the caller\n"
+";;\n"
+"  move     $dccr,[cris_reg+0x5E] ; Save the flags in DCCR before disable interrupts\n"
+"  di                        ; Disable interrupts\n"
+"  move.d   $r0,[cris_reg]        ; Save R0\n"
+"  move.d   $r1,[cris_reg+0x04]   ; Save R1\n"
+"  move.d   $r2,[cris_reg+0x08]   ; Save R2\n"
+"  move.d   $r3,[cris_reg+0x0C]   ; Save R3\n"
+"  move.d   $r4,[cris_reg+0x10]   ; Save R4\n"
+"  move.d   $r5,[cris_reg+0x14]   ; Save R5\n"
+"  move.d   $r6,[cris_reg+0x18]   ; Save R6\n"
+"  move.d   $r7,[cris_reg+0x1C]   ; Save R7\n"
+"  move.d   $r8,[cris_reg+0x20]   ; Save R8\n"
+"  move.d   $r9,[cris_reg+0x24]   ; Save R9\n"
+"  move.d   $r10,[cris_reg+0x28]  ; Save R10\n"
+"  move.d   $r11,[cris_reg+0x2C]  ; Save R11\n"
+"  move.d   $r12,[cris_reg+0x30]  ; Save R12\n"
+"  move.d   $r13,[cris_reg+0x34]  ; Save R13\n"
+"  move.d   $sp,[cris_reg+0x38]   ; Save SP (R14)\n"
+";; Due to the old assembler-versions BRP might not be recognized\n"
+"  .word 0xE670              ; move brp,$r0\n"
+"  subq     2,$r0             ; Set to address of previous instruction.\n"
+"  move.d   $r0,[cris_reg+0x3c]   ; Save the address in PC (R15)\n"
+"  clear.b  [cris_reg+0x40]      ; Clear P0\n"
+"  move     $vr,[cris_reg+0x41]   ; Save special register P1\n"
+"  clear.w  [cris_reg+0x42]      ; Clear P4\n"
+"  move     $ccr,[cris_reg+0x44]  ; Save special register CCR\n"
+"  move     $mof,[cris_reg+0x46]  ; P7\n"
+"  clear.d  [cris_reg+0x4A]      ; Clear P8\n"
+"  move     $ibr,[cris_reg+0x4E]  ; P9,\n"
+"  move     $irp,[cris_reg+0x52]  ; P10,\n"
+"  move     $srp,[cris_reg+0x56]  ; P11,\n"
+"  move     $dtp0,[cris_reg+0x5A] ; P12, register BAR, assembler might not know BAR\n"
+"                            ; P13, register DCCR already saved\n"
+";; Due to the old assembler-versions BRP might not be recognized\n"
+"  .word 0xE670              ; move brp,r0\n"
+";; Static (compiled) breakpoints must return to the next instruction in order\n"
+";; to avoid infinite loops. Dynamic (gdb-invoked) must restore the instruction\n"
+";; in order to execute it when execution is continued.\n"
+"  test.b   [is_dyn_brkp]    ; Is this a dynamic breakpoint?\n"
+"  beq      is_static         ; No, a static breakpoint\n"
+"  nop\n"
+"  subq     2,$r0              ; rerun the instruction the break replaced\n"
+"is_static:\n"
+"  moveq    1,$r1\n"
+"  move.b   $r1,[is_dyn_brkp] ; Set the state variable to dynamic breakpoint\n"
+"  move.d   $r0,[cris_reg+0x62]    ; Save the return address in BRP\n"
+"  move     $usp,[cris_reg+0x66]   ; USP\n"
+";;\n"
+";; Handle the communication\n"
+";;\n"
+"  move.d   internal_stack+1020,$sp ; Use the internal stack which grows upward\n"
+"  moveq    5,$r10                   ; SIGTRAP\n"
+"  jsr      handle_exception       ; Interactive routine\n"
+";;\n"
+";; Return to the caller\n"
+";;\n"
+"   move.d  [cris_reg],$r0         ; Restore R0\n"
+"   move.d  [cris_reg+0x04],$r1    ; Restore R1\n"
+"   move.d  [cris_reg+0x08],$r2    ; Restore R2\n"
+"   move.d  [cris_reg+0x0C],$r3    ; Restore R3\n"
+"   move.d  [cris_reg+0x10],$r4    ; Restore R4\n"
+"   move.d  [cris_reg+0x14],$r5    ; Restore R5\n"
+"   move.d  [cris_reg+0x18],$r6    ; Restore R6\n"
+"   move.d  [cris_reg+0x1C],$r7    ; Restore R7\n"
+"   move.d  [cris_reg+0x20],$r8    ; Restore R8\n"
+"   move.d  [cris_reg+0x24],$r9    ; Restore R9\n"
+"   move.d  [cris_reg+0x28],$r10   ; Restore R10\n"
+"   move.d  [cris_reg+0x2C],$r11   ; Restore R11\n"
+"   move.d  [cris_reg+0x30],$r12   ; Restore R12\n"
+"   move.d  [cris_reg+0x34],$r13   ; Restore R13\n"
+";;\n"
+";; FIXME: Which registers should be restored?\n"
+";;\n"
+"   move.d  [cris_reg+0x38],$sp    ; Restore SP (R14)\n"
+"   move    [cris_reg+0x56],$srp   ; Restore the subroutine return pointer.\n"
+"   move    [cris_reg+0x5E],$dccr  ; Restore DCCR\n"
+"   move    [cris_reg+0x66],$usp   ; Restore USP\n"
+"   jump    [cris_reg+0x62]       ; A jump to the content in register BRP works.\n"
+"   nop                       ;\n"
+"\n");
 
 /* The hook for an interrupt generated by GDB. An internal stack is used
    by the stub. The register image of the caller is stored in the structure
@@ -1367,94 +1029,94 @@ is_static:
 
 void kgdb_handle_serial(void);
 
-asm ("
-  .global kgdb_handle_serial
-kgdb_handle_serial:
-;;
-;; Response to a serial interrupt
-;;
-
-  move     $dccr,[reg+0x5E] ; Save the flags in DCCR
-  di                        ; Disable interrupts
-  move.d   $r0,[reg]        ; Save R0
-  move.d   $r1,[reg+0x04]   ; Save R1
-  move.d   $r2,[reg+0x08]   ; Save R2
-  move.d   $r3,[reg+0x0C]   ; Save R3
-  move.d   $r4,[reg+0x10]   ; Save R4
-  move.d   $r5,[reg+0x14]   ; Save R5
-  move.d   $r6,[reg+0x18]   ; Save R6
-  move.d   $r7,[reg+0x1C]   ; Save R7
-  move.d   $r8,[reg+0x20]   ; Save R8
-  move.d   $r9,[reg+0x24]   ; Save R9
-  move.d   $r10,[reg+0x28]  ; Save R10
-  move.d   $r11,[reg+0x2C]  ; Save R11
-  move.d   $r12,[reg+0x30]  ; Save R12
-  move.d   $r13,[reg+0x34]  ; Save R13
-  move.d   $sp,[reg+0x38]   ; Save SP (R14)
-  move     $irp,[reg+0x3c]  ; Save the address in PC (R15)
-  clear.b  [reg+0x40]      ; Clear P0
-  move     $vr,[reg+0x41]   ; Save special register P1,
-  clear.w  [reg+0x42]      ; Clear P4
-  move     $ccr,[reg+0x44]  ; Save special register CCR
-  move     $mof,[reg+0x46]  ; P7
-  clear.d  [reg+0x4A]      ; Clear P8
-  move     $ibr,[reg+0x4E]  ; P9,
-  move     $irp,[reg+0x52]  ; P10,
-  move     $srp,[reg+0x56]  ; P11,
-  move     $dtp0,[reg+0x5A] ; P12, register BAR, assembler might not know BAR
-                            ; P13, register DCCR already saved
-;; Due to the old assembler-versions BRP might not be recognized
-  .word 0xE670              ; move brp,r0
-  move.d   $r0,[reg+0x62]   ; Save the return address in BRP
-  move     $usp,[reg+0x66]  ; USP
-
-;; get the serial character (from debugport.c) and check if it is a ctrl-c
-
-  jsr getDebugChar
-  cmp.b 3, $r10
-  bne goback
-  nop
-
-  move.d  [reg+0x5E], $r10		; Get DCCR
-  btstq	   8, $r10			; Test the U-flag.
-  bmi	   goback
-  nop
-
-;;
-;; Handle the communication
-;;
-  move.d   internal_stack+1020,$sp ; Use the internal stack
-  moveq    2,$r10                   ; SIGINT
-  jsr      handle_exception       ; Interactive routine
-
-goback:
-;;
-;; Return to the caller
-;;
-   move.d  [reg],$r0         ; Restore R0
-   move.d  [reg+0x04],$r1    ; Restore R1
-   move.d  [reg+0x08],$r2    ; Restore R2
-   move.d  [reg+0x0C],$r3    ; Restore R3
-   move.d  [reg+0x10],$r4    ; Restore R4
-   move.d  [reg+0x14],$r5    ; Restore R5
-   move.d  [reg+0x18],$r6    ; Restore R6
-   move.d  [reg+0x1C],$r7    ; Restore R7
-   move.d  [reg+0x20],$r8    ; Restore R8
-   move.d  [reg+0x24],$r9    ; Restore R9
-   move.d  [reg+0x28],$r10   ; Restore R10
-   move.d  [reg+0x2C],$r11   ; Restore R11
-   move.d  [reg+0x30],$r12   ; Restore R12
-   move.d  [reg+0x34],$r13   ; Restore R13
-;;
-;; FIXME: Which registers should be restored?
-;;
-   move.d  [reg+0x38],$sp    ; Restore SP (R14)
-   move    [reg+0x56],$srp   ; Restore the subroutine return pointer.
-   move    [reg+0x5E],$dccr  ; Restore DCCR
-   move    [reg+0x66],$usp   ; Restore USP
-   reti                      ; Return from the interrupt routine
-   nop
-");
+asm ("\n"
+"  .global kgdb_handle_serial\n"
+"kgdb_handle_serial:\n"
+";;\n"
+";; Response to a serial interrupt\n"
+";;\n"
+"\n"
+"  move     $dccr,[cris_reg+0x5E] ; Save the flags in DCCR\n"
+"  di                        ; Disable interrupts\n"
+"  move.d   $r0,[cris_reg]        ; Save R0\n"
+"  move.d   $r1,[cris_reg+0x04]   ; Save R1\n"
+"  move.d   $r2,[cris_reg+0x08]   ; Save R2\n"
+"  move.d   $r3,[cris_reg+0x0C]   ; Save R3\n"
+"  move.d   $r4,[cris_reg+0x10]   ; Save R4\n"
+"  move.d   $r5,[cris_reg+0x14]   ; Save R5\n"
+"  move.d   $r6,[cris_reg+0x18]   ; Save R6\n"
+"  move.d   $r7,[cris_reg+0x1C]   ; Save R7\n"
+"  move.d   $r8,[cris_reg+0x20]   ; Save R8\n"
+"  move.d   $r9,[cris_reg+0x24]   ; Save R9\n"
+"  move.d   $r10,[cris_reg+0x28]  ; Save R10\n"
+"  move.d   $r11,[cris_reg+0x2C]  ; Save R11\n"
+"  move.d   $r12,[cris_reg+0x30]  ; Save R12\n"
+"  move.d   $r13,[cris_reg+0x34]  ; Save R13\n"
+"  move.d   $sp,[cris_reg+0x38]   ; Save SP (R14)\n"
+"  move     $irp,[cris_reg+0x3c]  ; Save the address in PC (R15)\n"
+"  clear.b  [cris_reg+0x40]      ; Clear P0\n"
+"  move     $vr,[cris_reg+0x41]   ; Save special register P1,\n"
+"  clear.w  [cris_reg+0x42]      ; Clear P4\n"
+"  move     $ccr,[cris_reg+0x44]  ; Save special register CCR\n"
+"  move     $mof,[cris_reg+0x46]  ; P7\n"
+"  clear.d  [cris_reg+0x4A]      ; Clear P8\n"
+"  move     $ibr,[cris_reg+0x4E]  ; P9,\n"
+"  move     $irp,[cris_reg+0x52]  ; P10,\n"
+"  move     $srp,[cris_reg+0x56]  ; P11,\n"
+"  move     $dtp0,[cris_reg+0x5A] ; P12, register BAR, assembler might not know BAR\n"
+"                            ; P13, register DCCR already saved\n"
+";; Due to the old assembler-versions BRP might not be recognized\n"
+"  .word 0xE670              ; move brp,r0\n"
+"  move.d   $r0,[cris_reg+0x62]   ; Save the return address in BRP\n"
+"  move     $usp,[cris_reg+0x66]  ; USP\n"
+"\n"
+";; get the serial character (from debugport.c) and check if it is a ctrl-c\n"
+"\n"
+"  jsr getDebugChar\n"
+"  cmp.b 3, $r10\n"
+"  bne goback\n"
+"  nop\n"
+"\n"
+"  move.d  [cris_reg+0x5E], $r10		; Get DCCR\n"
+"  btstq	   8, $r10			; Test the U-flag.\n"
+"  bmi	   goback\n"
+"  nop\n"
+"\n"
+";;\n"
+";; Handle the communication\n"
+";;\n"
+"  move.d   internal_stack+1020,$sp ; Use the internal stack\n"
+"  moveq    2,$r10                   ; SIGINT\n"
+"  jsr      handle_exception       ; Interactive routine\n"
+"\n"
+"goback:\n"
+";;\n"
+";; Return to the caller\n"
+";;\n"
+"   move.d  [cris_reg],$r0         ; Restore R0\n"
+"   move.d  [cris_reg+0x04],$r1    ; Restore R1\n"
+"   move.d  [cris_reg+0x08],$r2    ; Restore R2\n"
+"   move.d  [cris_reg+0x0C],$r3    ; Restore R3\n"
+"   move.d  [cris_reg+0x10],$r4    ; Restore R4\n"
+"   move.d  [cris_reg+0x14],$r5    ; Restore R5\n"
+"   move.d  [cris_reg+0x18],$r6    ; Restore R6\n"
+"   move.d  [cris_reg+0x1C],$r7    ; Restore R7\n"
+"   move.d  [cris_reg+0x20],$r8    ; Restore R8\n"
+"   move.d  [cris_reg+0x24],$r9    ; Restore R9\n"
+"   move.d  [cris_reg+0x28],$r10   ; Restore R10\n"
+"   move.d  [cris_reg+0x2C],$r11   ; Restore R11\n"
+"   move.d  [cris_reg+0x30],$r12   ; Restore R12\n"
+"   move.d  [cris_reg+0x34],$r13   ; Restore R13\n"
+";;\n"
+";; FIXME: Which registers should be restored?\n"
+";;\n"
+"   move.d  [cris_reg+0x38],$sp    ; Restore SP (R14)\n"
+"   move    [cris_reg+0x56],$srp   ; Restore the subroutine return pointer.\n"
+"   move    [cris_reg+0x5E],$dccr  ; Restore DCCR\n"
+"   move    [cris_reg+0x66],$usp   ; Restore USP\n"
+"   reti                      ; Return from the interrupt routine\n"
+"   nop\n"
+"\n");
 
 /* Use this static breakpoint in the start-up only. */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/arch-v32/drivers/Kconfig linux-libre-3.11-rc7-gnu/arch/cris/arch-v32/drivers/Kconfig
--- linux-libre-3.10-gnu/arch/cris/arch-v32/drivers/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/arch-v32/drivers/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -2,9 +2,7 @@ if ETRAX_ARCH_V32
 
 config ETRAX_ETHERNET
 	bool "Ethernet support"
-	depends on ETRAX_ARCH_V32
-	select ETHERNET
-	select NET_CORE
+	depends on ETRAX_ARCH_V32 && NETDEVICES
 	select MII
 	help
 	  This option enables the ETRAX FS built-in 10/100Mbit Ethernet
@@ -617,7 +615,6 @@ config ETRAX_PV_CHANGEABLE_BITS
 config ETRAX_CARDBUS
         bool "Cardbus support"
         depends on ETRAX_ARCH_V32
-        select HOTPLUG
         help
 	 Enabled the ETRAX Cardbus driver.
 
@@ -641,8 +638,6 @@ config ETRAX_STREAMCOPROC
 	  This option enables a driver for the stream co-processor
 	  for cryptographic operations.
 
-source drivers/mmc/Kconfig
-
 config ETRAX_MMC_IOP
 	tristate "MMC/SD host driver using IO-processor"
 	depends on ETRAX_ARCH_V32 && MMC
@@ -834,9 +829,4 @@ config ETRAX_SPI_MMC_WP_GPIO_PIN
 	  The pin to use for the SD/MMC write-protect signal for a memory
 	  card.  If defined as " " (space), the card is considered writable.
 
-# Avoid choices causing non-working configs by conditionalizing the inclusion.
-if ETRAX_SPI_MMC
-source drivers/spi/Kconfig
-endif
-
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/arch-v32/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/cris/arch-v32/kernel/smp.c
--- linux-libre-3.10-gnu/arch/cris/arch-v32/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/arch-v32/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -197,7 +197,7 @@ int setup_profiling_timer(unsigned int m
  */
 unsigned long cache_decay_ticks = 1;
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	smp_boot_one_cpu(cpu, tidle);
 	return cpu_online(cpu) ? 0 : -ENOSYS;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/include/arch-v10/arch/bitops.h linux-libre-3.11-rc7-gnu/arch/cris/include/arch-v10/arch/bitops.h
--- linux-libre-3.10-gnu/arch/cris/include/arch-v10/arch/bitops.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/include/arch-v10/arch/bitops.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,7 @@ static inline unsigned long cris_swapnwb
 	   in another register:
 	   !  __asm__ ("swapnwbr %2\n\tlz %2,%0"
 	   !	      : "=r,r" (res), "=r,X" (dummy) : "1,0" (w));
-	   confuses gcc (sched.c, gcc from cris-dist-1.14).  */
+	   confuses gcc (core.c, gcc from cris-dist-1.14).  */
 
 	unsigned long res;
 	__asm__ ("swapnwbr %0 \n\t"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/include/asm/io.h linux-libre-3.11-rc7-gnu/arch/cris/include/asm/io.h
--- linux-libre-3.10-gnu/arch/cris/include/asm/io.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/include/asm/io.h	2013-08-25 20:43:22.000000000 -0400
@@ -167,6 +167,9 @@ static inline void outsl(unsigned int po
 		cris_iops->write_io(port, (void *)addr, 4, count);
 }
 
+#define inb_p(port)             inb(port)
+#define outb_p(val, port)       outb((val), (port))
+
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
  * access
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/include/asm/Kbuild linux-libre-3.11-rc7-gnu/arch/cris/include/asm/Kbuild
--- linux-libre-3.10-gnu/arch/cris/include/asm/Kbuild	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/include/asm/Kbuild	2013-08-25 20:43:22.000000000 -0400
@@ -5,5 +5,9 @@ header-y += arch-v32/
 
 generic-y += clkdev.h
 generic-y += exec.h
+generic-y += kvm_para.h
+generic-y += linkage.h
 generic-y += module.h
 generic-y += trace_clock.h
+generic-y += vga.h
+generic-y += xor.h
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/include/asm/linkage.h linux-libre-3.11-rc7-gnu/arch/cris/include/asm/linkage.h
--- linux-libre-3.10-gnu/arch/cris/include/asm/linkage.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/include/asm/linkage.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#ifndef __ASM_LINKAGE_H
-#define __ASM_LINKAGE_H
-
-/* Nothing to see here... */
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/include/asm/page.h linux-libre-3.11-rc7-gnu/arch/cris/include/asm/page.h
--- linux-libre-3.10-gnu/arch/cris/include/asm/page.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/include/asm/page.h	2013-08-25 20:43:22.000000000 -0400
@@ -51,7 +51,6 @@ typedef struct page *pgtable_t;
  */ 
 
 #define virt_to_page(kaddr)    (mem_map + (((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT))
-#define VALID_PAGE(page)       (((page) - mem_map) < max_mapnr)
 #define virt_addr_valid(kaddr)	pfn_valid((unsigned)(kaddr) >> PAGE_SHIFT)
 
 /* convert a page (based on mem_map and forward) to a physical address
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/cris/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/cris/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -258,9 +258,6 @@ static inline pgd_t * pgd_offset(const s
 #define pgd_ERROR(e) \
         printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)         \
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/cris/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/cris/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -76,6 +76,8 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif /* _ASM_SOCKET_H */
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/Kconfig linux-libre-3.11-rc7-gnu/arch/cris/Kconfig
--- linux-libre-3.10-gnu/arch/cris/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -134,11 +134,13 @@ config SVINTO_SIM
 
 config ETRAXFS
 	bool "ETRAX-FS-V32"
+	select CPU_FREQ_TABLE if CPU_FREQ
 	help
 	  Support CRIS V32.
 
 config CRIS_MACH_ARTPEC3
         bool "ARTPEC-3"
+	select CPU_FREQ_TABLE if CPU_FREQ
         help
           Support Axis ARTPEC-3.
 
@@ -637,40 +639,10 @@ endchoice
 
 endmenu
 
-source "drivers/base/Kconfig"
-
-# standard linux drivers
-source "drivers/mtd/Kconfig"
-
-source "drivers/parport/Kconfig"
-
-source "drivers/pnp/Kconfig"
-
-source "drivers/block/Kconfig"
-
-source "drivers/ide/Kconfig"
-
-source "drivers/net/Kconfig"
-
-source "drivers/i2c/Kconfig"
-
-source "drivers/rtc/Kconfig"
-
-#
-# input before char - char/joystick depends on it. As does USB.
-#
-source "drivers/input/Kconfig"
-
-source "drivers/char/Kconfig"
+source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
-source "drivers/usb/Kconfig"
-
-source "drivers/uwb/Kconfig"
-
-source "drivers/staging/Kconfig"
-
 source "arch/cris/Kconfig.debug"
 
 source "security/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/cris/mm/init.c linux-libre-3.11-rc7-gnu/arch/cris/mm/init.c
--- linux-libre-3.10-gnu/arch/cris/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/cris/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,9 +19,6 @@ unsigned long empty_zero_page;
 void __init
 mem_init(void)
 {
-	int codesize, reservedpages, datasize, initsize;
-	unsigned long tmp;
-
 	BUG_ON(!mem_map);
 
 	/* max/min_low_pfn was set by setup.c
@@ -29,35 +26,9 @@ mem_init(void)
 	 *
 	 * high_memory was also set in setup.c
 	 */
-
-	max_mapnr = num_physpages = max_low_pfn - min_low_pfn;
- 
-	/* this will put all memory onto the freelists */
-        totalram_pages = free_all_bootmem();
-
-	reservedpages = 0;
-	for (tmp = 0; tmp < max_mapnr; tmp++) {
-		/*
-                 * Only count reserved RAM pages
-                 */
-		if (PageReserved(mem_map + tmp))
-			reservedpages++;
-	}
-
-	codesize =  (unsigned long) &_etext - (unsigned long) &_stext;
-        datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-        initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-	
-        printk(KERN_INFO
-               "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, "
-	       "%dk init)\n" ,
-	       nr_free_pages() << (PAGE_SHIFT-10),
-	       max_mapnr << (PAGE_SHIFT-10),
-	       codesize >> 10,
-	       reservedpages << (PAGE_SHIFT-10),
-	       datasize >> 10,
-	       initsize >> 10
-               );
+	max_mapnr = max_low_pfn - min_low_pfn;
+        free_all_bootmem();
+	mem_init_print_info(NULL);
 }
 
 /* free the pages occupied by initialization code */
@@ -65,5 +36,5 @@ mem_init(void)
 void 
 free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/frv/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/frv/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -488,9 +488,6 @@ static inline int pte_file(pte_t pte)
 #define PageSkip(page)		(0)
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/include/asm/uaccess.h linux-libre-3.11-rc7-gnu/arch/frv/include/asm/uaccess.h
--- linux-libre-3.10-gnu/arch/frv/include/asm/uaccess.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/include/asm/uaccess.h	2013-08-25 20:43:22.000000000 -0400
@@ -280,14 +280,14 @@ extern long __memcpy_user(void *dst, con
 static inline unsigned long __must_check
 __copy_to_user(void __user *to, const void *from, unsigned long n)
 {
-       might_sleep();
+       might_fault();
        return __copy_to_user_inatomic(to, from, n);
 }
 
 static inline unsigned long
 __copy_from_user(void *to, const void __user *from, unsigned long n)
 {
-       might_sleep();
+       might_fault();
        return __copy_from_user_inatomic(to, from, n);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/frv/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/frv/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -74,5 +74,7 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif /* _ASM_SOCKET_H */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/Kconfig linux-libre-3.11-rc7-gnu/arch/frv/Kconfig
--- linux-libre-3.10-gnu/arch/frv/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@ config FRV
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
+	select HAVE_DEBUG_STACKOVERFLOW
 
 config ZONE_DMA
 	bool
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/frv/Kconfig.debug
--- linux-libre-3.10-gnu/arch/frv/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -2,10 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-
 config GDBSTUB
 	bool "Remote GDB kernel debugging"
 	depends on DEBUG_KERNEL
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/kernel/head.S linux-libre-3.11-rc7-gnu/arch/frv/kernel/head.S
--- linux-libre-3.10-gnu/arch/frv/kernel/head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/kernel/head.S	2013-08-25 20:43:22.000000000 -0400
@@ -479,11 +479,6 @@ __head_mmu_enabled:
 
 	LEDS		0x000c
 
-	# initialise the processor and the peripherals
-	#call		SYMBOL_NAME(processor_init)
-	#call		SYMBOL_NAME(unit_init)
-	#LEDS		0x0aff
-
 	sethi.p		#0xe5e5,gr3
 	setlo		#0xe5e5,gr3
 	or.p		gr3,gr0,gr4
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/kernel/pm.c linux-libre-3.11-rc7-gnu/arch/frv/kernel/pm.c
--- linux-libre-3.10-gnu/arch/frv/kernel/pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/kernel/pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,7 +150,7 @@ static int user_atoi(char __user *ubuf,
 /*
  * Send us to sleep.
  */
-static int sysctl_pm_do_suspend(ctl_table *ctl, int write,
+static int sysctl_pm_do_suspend(struct ctl_table *ctl, int write,
 				void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int mode;
@@ -197,7 +197,7 @@ static int try_set_cmode(int new_cmode)
 }
 
 
-static int cmode_procctl(ctl_table *ctl, int write,
+static int cmode_procctl(struct ctl_table *ctl, int write,
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int new_cmode;
@@ -269,7 +269,7 @@ static int try_set_cm(int new_cm)
 	return 0;
 }
 
-static int p0_procctl(ctl_table *ctl, int write,
+static int p0_procctl(struct ctl_table *ctl, int write,
 		      void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int new_p0;
@@ -282,7 +282,7 @@ static int p0_procctl(ctl_table *ctl, in
 	return try_set_p0(new_p0)?:*lenp;
 }
 
-static int cm_procctl(ctl_table *ctl, int write,
+static int cm_procctl(struct ctl_table *ctl, int write,
 		      void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int new_cm;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/frv/kernel/setup.c
--- linux-libre-3.10-gnu/arch/frv/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -709,7 +709,7 @@ static void __init reserve_dma_coherent(
 /*
  * calibrate the delay loop
  */
-void __cpuinit calibrate_delay(void)
+void calibrate_delay(void)
 {
 	loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ);
 
@@ -735,7 +735,7 @@ static void __init parse_cmdline_early(c
 		/* "mem=XXX[kKmM]" sets SDRAM size to <mem>, overriding the value we worked
 		 * out from the SDRAM controller mask register
 		 */
-		if (!memcmp(cmdline, "mem=", 4)) {
+		if (!strncmp(cmdline, "mem=", 4)) {
 			unsigned long long mem_size;
 
 			mem_size = memparse(cmdline + 4, &cmdline);
@@ -876,6 +876,7 @@ late_initcall(setup_arch_serial);
 static void __init setup_linux_memory(void)
 {
 	unsigned long bootmap_size, low_top_pfn, kstart, kend, high_mem;
+	unsigned long physpages;
 
 	kstart	= (unsigned long) &__kernel_image_start - PAGE_OFFSET;
 	kend	= (unsigned long) &__kernel_image_end - PAGE_OFFSET;
@@ -893,19 +894,19 @@ static void __init setup_linux_memory(vo
 					 );
 
 	/* pass the memory that the kernel can immediately use over to the bootmem allocator */
-	max_mapnr = num_physpages = (memory_end - memory_start) >> PAGE_SHIFT;
+	max_mapnr = physpages = (memory_end - memory_start) >> PAGE_SHIFT;
 	low_top_pfn = (KERNEL_LOWMEM_END - KERNEL_LOWMEM_START) >> PAGE_SHIFT;
 	high_mem = 0;
 
-	if (num_physpages > low_top_pfn) {
+	if (physpages > low_top_pfn) {
 #ifdef CONFIG_HIGHMEM
-		high_mem = num_physpages - low_top_pfn;
+		high_mem = physpages - low_top_pfn;
 #else
-		max_mapnr = num_physpages = low_top_pfn;
+		max_mapnr = physpages = low_top_pfn;
 #endif
 	}
 	else {
-		low_top_pfn = num_physpages;
+		low_top_pfn = physpages;
 	}
 
 	min_low_pfn = memory_start >> PAGE_SHIFT;
@@ -979,7 +980,7 @@ static void __init setup_uclinux_memory(
 	free_bootmem(memory_start, memory_end - memory_start);
 
 	high_memory = (void *) (memory_end & PAGE_MASK);
-	max_mapnr = num_physpages = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+	max_mapnr = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
 
 	min_low_pfn = memory_start >> PAGE_SHIFT;
 	max_low_pfn = memory_end >> PAGE_SHIFT;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/kernel/sysctl.c linux-libre-3.11-rc7-gnu/arch/frv/kernel/sysctl.c
--- linux-libre-3.10-gnu/arch/frv/kernel/sysctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/kernel/sysctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,7 +46,7 @@ static void frv_change_dcache_mode(unsig
 /*
  * handle requests to dynamically switch the write caching mode delivered by /proc
  */
-static int procctl_frv_cachemode(ctl_table *table, int write,
+static int procctl_frv_cachemode(struct ctl_table *table, int write,
 				 void __user *buffer, size_t *lenp,
 				 loff_t *ppos)
 {
@@ -121,7 +121,7 @@ static int procctl_frv_cachemode(ctl_tab
  * permit the mm_struct the nominated process is using have its MMU context ID pinned
  */
 #ifdef CONFIG_MMU
-static int procctl_frv_pin_cxnr(ctl_table *table, int write,
+static int procctl_frv_pin_cxnr(struct ctl_table *table, int write,
 				void __user *buffer, size_t *lenp,
 				loff_t *ppos)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/frv/kernel/traps.c
--- linux-libre-3.10-gnu/arch/frv/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -523,7 +523,7 @@ void die_if_kernel(const char *str, ...)
 		return;
 
 	va_start(va, str);
-	vsprintf(buffer, str, va);
+	vsnprintf(buffer, sizeof(buffer), str, va);
 	va_end(va);
 
 	console_verbose();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/frv/mm/init.c linux-libre-3.11-rc7-gnu/arch/frv/mm/init.c
--- linux-libre-3.10-gnu/arch/frv/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/frv/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -78,7 +78,7 @@ void __init paging_init(void)
 	memset((void *) empty_zero_page, 0, PAGE_SIZE);
 
 #ifdef CONFIG_HIGHMEM
-	if (num_physpages - num_mappedpages) {
+	if (get_num_physpages() - num_mappedpages) {
 		pgd_t *pge;
 		pud_t *pue;
 		pmd_t *pme;
@@ -96,7 +96,7 @@ void __init paging_init(void)
 	 */
 	zones_size[ZONE_NORMAL]  = max_low_pfn - min_low_pfn;
 #ifdef CONFIG_HIGHMEM
-	zones_size[ZONE_HIGHMEM] = num_physpages - num_mappedpages;
+	zones_size[ZONE_HIGHMEM] = get_num_physpages() - num_mappedpages;
 #endif
 
 	free_area_init(zones_size);
@@ -114,45 +114,24 @@ void __init paging_init(void)
  */
 void __init mem_init(void)
 {
-	unsigned long npages = (memory_end - memory_start) >> PAGE_SHIFT;
-	unsigned long tmp;
-#ifdef CONFIG_MMU
-	unsigned long loop, pfn;
-	int datapages = 0;
-#endif
-	int codek = 0, datak = 0;
+	unsigned long code_size = _etext - _stext;
 
 	/* this will put all low memory onto the freelists */
-	totalram_pages = free_all_bootmem();
-
-#ifdef CONFIG_MMU
-	for (loop = 0 ; loop < npages ; loop++)
-		if (PageReserved(&mem_map[loop]))
-			datapages++;
-
-#ifdef CONFIG_HIGHMEM
-	for (pfn = num_physpages - 1; pfn >= num_mappedpages; pfn--)
-		free_highmem_page(&mem_map[pfn]);
-#endif
-
-	codek = ((unsigned long) &_etext - (unsigned long) &_stext) >> 10;
-	datak = datapages << (PAGE_SHIFT - 10);
+	free_all_bootmem();
+#if defined(CONFIG_MMU) && defined(CONFIG_HIGHMEM)
+	{
+		unsigned long pfn;
 
-#else
-	codek = (_etext - _stext) >> 10;
-	datak = 0; //(__bss_stop - _sdata) >> 10;
+		for (pfn = get_num_physpages() - 1;
+		     pfn >= num_mappedpages; pfn--)
+			free_highmem_page(&mem_map[pfn]);
+	}
 #endif
 
-	tmp = nr_free_pages() << PAGE_SHIFT;
-	printk("Memory available: %luKiB/%luKiB RAM, %luKiB/%luKiB ROM (%dKiB kernel code, %dKiB data)\n",
-	       tmp >> 10,
-	       npages << (PAGE_SHIFT - 10),
-	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
-	       rom_length >> 10,
-	       codek,
-	       datak
-	       );
-
+	mem_init_print_info(NULL);
+	if (rom_length > 0 && rom_length >= code_size)
+		printk("Memory available:  %luKiB/%luKiB ROM\n",
+			(rom_length - code_size) >> 10, rom_length >> 10);
 } /* end mem_init() */
 
 /*****************************************************************************/
@@ -162,7 +141,7 @@ void __init mem_init(void)
 void free_initmem(void)
 {
 #if defined(CONFIG_RAMKERNEL) && !defined(CONFIG_PROTECT_KERNEL)
-	free_initmem_default(0);
+	free_initmem_default(-1);
 #endif
 } /* end free_initmem() */
 
@@ -173,6 +152,6 @@ void free_initmem(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 } /* end free_initrd_mem() */
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/boot/compressed/Makefile linux-libre-3.11-rc7-gnu/arch/h8300/boot/compressed/Makefile
--- linux-libre-3.10-gnu/arch/h8300/boot/compressed/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/boot/compressed/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,7 @@ OBJECTS = $(obj)/head.o $(obj)/misc.o
 #
 CONFIG_MEMORY_START     ?= 0x00400000
 CONFIG_BOOT_LINK_OFFSET ?= 0x00140000
-IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)])
+IMAGE_OFFSET := $(shell printf "0x%08x" $$(($(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET))))
 
 LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -estartup $(obj)/vmlinux.lds
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/boot/compressed/misc.c linux-libre-3.11-rc7-gnu/arch/h8300/boot/compressed/misc.c
--- linux-libre-3.10-gnu/arch/h8300/boot/compressed/misc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/boot/compressed/misc.c	2013-08-25 20:43:22.000000000 -0400
@@ -79,7 +79,6 @@ static void error(char *m);
 
 int puts(const char *);
 
-extern int _text;		/* Defined in vmlinux.lds.S */
 extern int _end;
 static unsigned long free_mem_ptr;
 static unsigned long free_mem_end_ptr;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/include/asm/barrier.h linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/barrier.h
--- linux-libre-3.10-gnu/arch/h8300/include/asm/barrier.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/barrier.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,8 @@
 #define wmb()  asm volatile (""   : : :"memory")
 #define set_mb(var, value) do { xchg(&var, value); } while (0)
 
+#define read_barrier_depends()	do { } while (0)
+
 #ifdef CONFIG_SMP
 #define smp_mb()	mb()
 #define smp_rmb()	rmb()
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/include/asm/Kbuild linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/Kbuild
--- linux-libre-3.10-gnu/arch/h8300/include/asm/Kbuild	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/Kbuild	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,8 @@
 
 generic-y += clkdev.h
 generic-y += exec.h
+generic-y += linkage.h
 generic-y += mmu.h
 generic-y += module.h
 generic-y += trace_clock.h
+generic-y += xor.h
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/include/asm/linkage.h linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/linkage.h
--- linux-libre-3.10-gnu/arch/h8300/include/asm/linkage.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/linkage.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#ifndef _H8300_LINKAGE_H
-#define _H8300_LINKAGE_H
-
-#undef SYMBOL_NAME_LABEL
-#define SYMBOL_NAME_LABEL(_name_) _##_name_##:
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/h8300/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -52,9 +52,6 @@ extern int is_in_rom(unsigned long);
  */
 #define pgtable_cache_init()   do { } while (0)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 /*
  * All 32bit addresses are effectively valid for vmalloc...
  * Sort of meaningless for non-VM targets.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/include/asm/tlb.h linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/tlb.h
--- linux-libre-3.10-gnu/arch/h8300/include/asm/tlb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/include/asm/tlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,16 +1,3 @@
-/* 
-  include/asm-h8300/tlb.h 
-*/
-
-#ifndef __H8300_TLB_H__
-#define __H8300_TLB_H__
-
-#define tlb_flush(tlb)	do { } while(0)
-
-/* 
-  include/asm-h8300/tlb.h 
-*/
-
 #ifndef __H8300_TLB_H__
 #define __H8300_TLB_H__
 
@@ -19,5 +6,3 @@
 #include <asm-generic/tlb.h>
 
 #endif
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/h8300/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/h8300/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -74,4 +74,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif /* _ASM_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/Kconfig linux-libre-3.11-rc7-gnu/arch/h8300/Kconfig
--- linux-libre-3.10-gnu/arch/h8300/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -94,126 +94,10 @@ endmenu
 
 source "net/Kconfig"
 
-source "drivers/base/Kconfig"
-
-source "drivers/mtd/Kconfig"
-
-source "drivers/block/Kconfig"
-
-source "drivers/ide/Kconfig"
+source "drivers/Kconfig"
 
 source "arch/h8300/Kconfig.ide"
 
-source "drivers/net/Kconfig"
-
-#
-# input - input/joystick depends on it. As does USB.
-#
-source "drivers/input/Kconfig"
-
-menu "Character devices"
-
-config VT
-	bool "Virtual terminal"
-	---help---
-	  If you say Y here, you will get support for terminal devices with
-	  display and keyboard devices. These are called "virtual" because you
-	  can run several virtual terminals (also called virtual consoles) on
-	  one physical terminal. This is rather useful, for example one
-	  virtual terminal can collect system messages and warnings, another
-	  one can be used for a text-mode user session, and a third could run
-	  an X session, all in parallel. Switching between virtual terminals
-	  is done with certain key combinations, usually Alt-<function key>.
-
-	  The setterm command ("man setterm") can be used to change the
-	  properties (such as colors or beeping) of a virtual terminal. The
-	  man page console_codes(4) ("man console_codes") contains the special
-	  character sequences that can be used to change those properties
-	  directly. The fonts used on virtual terminals can be changed with
-	  the setfont ("man setfont") command and the key bindings are defined
-	  with the loadkeys ("man loadkeys") command.
-
-	  You need at least one virtual terminal device in order to make use
-	  of your keyboard and monitor. Therefore, only people configuring an
-	  embedded system would want to say N here in order to save some
-	  memory; the only way to log into such a system is then via a serial
-	  or network connection.
-
-	  If unsure, say Y, or else you won't be able to do much with your new
-	  shiny Linux system :-)
-
-config VT_CONSOLE
-	bool "Support for console on virtual terminal"
-	depends on VT
-	---help---
-	  The system console is the device which receives all kernel messages
-	  and warnings and which allows logins in single user mode. If you
-	  answer Y here, a virtual terminal (the device used to interact with
-	  a physical terminal) can be used as system console. This is the most
-	  common mode of operations, so you should say Y here unless you want
-	  the kernel messages be output only to a serial port (in which case
-	  you should say Y to "Console on serial port", below).
-
-	  If you do say Y here, by default the currently visible virtual
-	  terminal (/dev/tty0) will be used as system console. You can change
-	  that with a kernel command line option such as "console=tty3" which
-	  would use the third virtual terminal as system console. (Try "man
-	  bootparam" or see the documentation of your boot loader (lilo or
-	  loadlin) about how to pass options to the kernel at boot time.)
-
-	  If unsure, say Y.
-
-config HW_CONSOLE
-	bool
-	depends on VT
-	default y
-
-comment "Unix98 PTY support"
-
-config UNIX98_PTYS
-	bool "Unix98 PTY support"
-	---help---
-	  A pseudo terminal (PTY) is a software device consisting of two
-	  halves: a master and a slave. The slave device behaves identical to
-	  a physical terminal; the master device is used by a process to
-	  read data from and write data to the slave, thereby emulating a
-	  terminal. Typical programs for the master side are telnet servers
-	  and xterms.
-
-	  Linux has traditionally used the BSD-like names /dev/ptyxx for
-	  masters and /dev/ttyxx for slaves of pseudo terminals. This scheme
-	  has a number of problems. The GNU C library glibc 2.1 and later,
-	  however, supports the Unix98 naming standard: in order to acquire a
-	  pseudo terminal, a process opens /dev/ptmx; the number of the pseudo
-	  terminal is then made available to the process and the pseudo
-	  terminal slave can be accessed as /dev/pts/<number>. What was
-	  traditionally /dev/ttyp2 will then be /dev/pts/2, for example.
-
-	  The entries in /dev/pts/ are created on the fly by a virtual
-	  file system; therefore, if you say Y here you should say Y to
-	  "/dev/pts file system for Unix98 PTYs" as well.
-
-	  If you want to say Y here, you need to have the C library glibc 2.1
-	  or later (equal to libc-6.1, check with "ls -l /lib/libc.so.*").
-	  Read the instructions in <file:Documentation/Changes> pertaining to
-	  pseudo terminals. It's safe to say N.
-
-source "drivers/char/pcmcia/Kconfig"
-
-source "drivers/tty/serial/Kconfig"
-
-source "drivers/i2c/Kconfig"
-
-source "drivers/hwmon/Kconfig"
-
-source "drivers/usb/Kconfig"
-
-source "drivers/uwb/Kconfig"
-
-endmenu
-
-source "drivers/staging/Kconfig"
-
 source "fs/Kconfig"
 
 source "arch/h8300/Kconfig.debug"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/Kconfig.cpu linux-libre-3.11-rc7-gnu/arch/h8300/Kconfig.cpu
--- linux-libre-3.10-gnu/arch/h8300/Kconfig.cpu	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/Kconfig.cpu	2013-08-25 20:43:22.000000000 -0400
@@ -64,6 +64,7 @@ choice
 
 config H83002
 	bool "H8/3001,3002,3003"
+	depends on BROKEN
 	select CPU_H8300H
 
 config H83007
@@ -72,6 +73,7 @@ config H83007
 
 config H83048
 	bool "H8/3044,3045,3046,3047,3048,3052"
+	depends on BROKEN
 	select CPU_H8300H
 
 config H83068
@@ -155,10 +157,12 @@ config H8300_TIMER16_CH
 config H8300_ITU_CH
 	int "ITU channel"
 	depends on H8300_ITU
+	range 0 4
 
 config H8300_TPU_CH
 	int "TPU channel"
 	depends on H8300_TPU
+	range 0 4
 
 source "kernel/Kconfig.preempt"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/kernel/entry.S linux-libre-3.11-rc7-gnu/arch/h8300/kernel/entry.S
--- linux-libre-3.10-gnu/arch/h8300/kernel/entry.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/kernel/entry.S	2013-08-25 20:43:22.000000000 -0400
@@ -87,13 +87,13 @@ INTERRUPTS = 128
 	bne	5f
 
 	/* user mode */
-	mov.l	sp,@SYMBOL_NAME(sw_usp)
+	mov.l	sp,@_sw_usp
 	mov.l	@sp,er0				/* restore saved er0 */
 	orc	#0x10,ccr			/* switch kernel stack */
-	mov.l	@SYMBOL_NAME(sw_ksp),sp
+	mov.l	@_sw_ksp,sp
 	sub.l	#(LRET-LORIG),sp		/* allocate LORIG - LRET */
 	SAVEREGS
-	mov.l   @SYMBOL_NAME(sw_usp),er0
+	mov.l   @_sw_usp,er0
 	mov.l   @(USERRET:16,er0),er1           /* copy the RET addr */
 	mov.l   er1,@(LRET-LER3:16,sp)
 	SAVEEXR
@@ -128,7 +128,7 @@ INTERRUPTS = 128
 	bne	7f
 
 	orc	#0x80,ccr
-	mov.l	@SYMBOL_NAME(sw_usp),er0
+	mov.l	@_sw_usp,er0
 	mov.l	@(LER0-LER1:16,sp),er1		/* restore ER0 */
 	mov.l	er1,@er0
 	RESTOREEXR
@@ -141,7 +141,7 @@ INTERRUPTS = 128
 
 	mov.l	@sp+,er1
 	add.l	#(LRET-LER1),sp			/* remove LORIG - LRET */
-	mov.l	sp,@SYMBOL_NAME(sw_ksp)
+	mov.l	sp,@_sw_ksp
 	andc	#0xef,ccr			/* switch to user mode */
 	mov.l	er0,sp
 	bra	8f
@@ -155,20 +155,20 @@ INTERRUPTS = 128
 	rte
 	.endm
 
-.globl SYMBOL_NAME(system_call)
-.globl SYMBOL_NAME(ret_from_exception)
-.globl SYMBOL_NAME(ret_from_fork)
-.globl SYMBOL_NAME(ret_from_kernel_thread)
-.globl SYMBOL_NAME(ret_from_interrupt)
-.globl SYMBOL_NAME(interrupt_redirect_table)
-.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
-.globl SYMBOL_NAME(resume)
-.globl SYMBOL_NAME(interrupt_entry)
-.globl SYMBOL_NAME(trace_break)
+.globl _system_call
+.globl _ret_from_exception
+.globl _ret_from_fork
+.globl _ret_from_kernel_thread
+.globl _ret_from_interrupt
+.globl _interrupt_redirect_table
+.globl _sw_ksp,_sw_usp
+.globl _resume
+.globl _interrupt_entry
+.globl _trace_break
 
 #if defined(CONFIG_ROMKERNEL)
 	.section .int_redirect,"ax"
-SYMBOL_NAME_LABEL(interrupt_redirect_table)
+_interrupt_redirect_table:
 #if defined(CONFIG_CPU_H8300H)
 	.rept	7
 	.long	0
@@ -178,54 +178,54 @@ SYMBOL_NAME_LABEL(interrupt_redirect_tab
 	.rept	5
 	.long	0
 	.endr
-	jmp	@SYMBOL_NAME(trace_break)
+	jmp	@_trace_break
 	.long	0
 #endif
 
-	jsr	@SYMBOL_NAME(interrupt_entry)	/* NMI */
-	jmp	@SYMBOL_NAME(system_call)	/* TRAPA #0 (System call) */
+	jsr	@_interrupt_entry		/* NMI */
+	jmp	@_system_call			/* TRAPA #0 (System call) */
 	.long	0
 	.long	0
-	jmp	@SYMBOL_NAME(trace_break)	/* TRAPA #3 (breakpoint) */
+	jmp	@_trace_break			/* TRAPA #3 (breakpoint) */
 	.rept	INTERRUPTS-12
-	jsr	@SYMBOL_NAME(interrupt_entry)
+	jsr	@_interrupt_entry
 	.endr
 #endif
 #if defined(CONFIG_RAMKERNEL)
-.globl SYMBOL_NAME(interrupt_redirect_table)
+.globl _interrupt_redirect_table
 	.section .bss
-SYMBOL_NAME_LABEL(interrupt_redirect_table)
+_interrupt_redirect_table:
 	.space	4
 #endif
 
 	.section .text
 	.align	2
-SYMBOL_NAME_LABEL(interrupt_entry)
+_interrupt_entry:
 	SAVE_ALL
 	mov.l	sp,er0
 	add.l	#LVEC,er0
 	btst	#4,r1l
 	bne	1f
 	/* user LVEC */
-	mov.l	@SYMBOL_NAME(sw_usp),er0
+	mov.l	@_sw_usp,er0
 	adds	#4,er0
 1:
 	mov.l	@er0,er0			/* LVEC address */
 #if defined(CONFIG_ROMKERNEL)
-	sub.l	#SYMBOL_NAME(interrupt_redirect_table),er0
+	sub.l	#_interrupt_redirect_table,er0
 #endif
 #if defined(CONFIG_RAMKERNEL)
-	mov.l	@SYMBOL_NAME(interrupt_redirect_table),er1
+	mov.l	@_interrupt_redirect_table,er1
 	sub.l	er1,er0
 #endif
 	SHLR2	er0
 	dec.l	#1,er0
 	mov.l	sp,er1
 	subs	#4,er1				/* adjust ret_pc */
-	jsr	@SYMBOL_NAME(do_IRQ)
-	jmp	@SYMBOL_NAME(ret_from_interrupt)
+	jsr	@_do_IRQ
+	jmp	@_ret_from_interrupt
 
-SYMBOL_NAME_LABEL(system_call)
+_system_call:
 	subs	#4,sp				/* dummy LVEC */
 	SAVE_ALL
 	andc	#0x7f,ccr
@@ -233,21 +233,21 @@ SYMBOL_NAME_LABEL(system_call)
 
 	/* save top of frame */
 	mov.l	sp,er0
-	jsr	@SYMBOL_NAME(set_esp0)
+	jsr	@_set_esp0
 	mov.l	sp,er2
 	and.w	#0xe000,r2
 	mov.b	@((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
 	btst	#(TIF_SYSCALL_TRACE & 7),r2l
 	beq	1f
-	jsr	@SYMBOL_NAME(do_syscall_trace)
+	jsr	@_do_syscall_trace
 1:
 	cmp.l	#NR_syscalls,er4
 	bcc	badsys
 	SHLL2	er4
-	mov.l	#SYMBOL_NAME(sys_call_table),er0
+	mov.l	#_sys_call_table,er0
 	add.l	er4,er0
 	mov.l	@er0,er4
-	beq	SYMBOL_NAME(ret_from_exception):16
+	beq	_ret_from_exception:16
 	mov.l	@(LER1:16,sp),er0
 	mov.l	@(LER2:16,sp),er1
 	mov.l	@(LER3:16,sp),er2
@@ -258,10 +258,10 @@ SYMBOL_NAME_LABEL(system_call)
 	mov.b	@((TI_FLAGS+3-(TIF_SYSCALL_TRACE >> 3)):16,er2),r2l
 	btst	#(TIF_SYSCALL_TRACE & 7),r2l
 	beq	2f
-	jsr	@SYMBOL_NAME(do_syscall_trace)
+	jsr	@_do_syscall_trace
 2:
 #if defined(CONFIG_SYSCALL_PRINT)
-	jsr	@SYMBOL_NAME(syscall_print)
+	jsr	@_syscall_print
 #endif
 	orc	#0x80,ccr
 	bra	resume_userspace
@@ -275,11 +275,11 @@ badsys:
 #define resume_kernel restore_all
 #endif
 
-SYMBOL_NAME_LABEL(ret_from_exception)
+_ret_from_exception:
 #if defined(CONFIG_PREEMPT)
 	orc	#0x80,ccr
 #endif
-SYMBOL_NAME_LABEL(ret_from_interrupt)
+_ret_from_interrupt:
 	mov.b	@(LCCR+1:16,sp),r0l
 	btst	#4,r0l
 	bne	resume_kernel:8		/* return from kernel */
@@ -296,12 +296,12 @@ work_pending:
 	/* work notifysig */
 	mov.l	sp,er0
 	subs	#4,er0			/* er0: pt_regs */
-	jsr	@SYMBOL_NAME(do_notify_resume)
+	jsr	@_do_notify_resume
 	bra	restore_all:8
 work_resched:
 	mov.l	sp,er0
-	jsr	@SYMBOL_NAME(set_esp0)
-	jsr	@SYMBOL_NAME(schedule)
+	jsr	@_set_esp0
+	jsr	@_schedule
 	bra	resume_userspace:8
 restore_all:
 	RESTORE_ALL			/* Does RTE */
@@ -320,26 +320,26 @@ need_resched:
 	mov.l	er0,@(TI_PRE_COUNT:16,er4)
 	andc	#0x7f,ccr
 	mov.l	sp,er0
-	jsr	@SYMBOL_NAME(set_esp0)
-	jsr	@SYMBOL_NAME(schedule)
+	jsr	@_set_esp0
+	jsr	@_schedule
 	orc	#0x80,ccr
 	bra	need_resched:8
 #endif
 
-SYMBOL_NAME_LABEL(ret_from_fork)
+_ret_from_fork:
 	mov.l	er2,er0
-	jsr	@SYMBOL_NAME(schedule_tail)
-	jmp	@SYMBOL_NAME(ret_from_exception)
+	jsr	@_schedule_tail
+	jmp	@_ret_from_exception
 
-SYMBOL_NAME_LABEL(ret_from_kernel_thread)
+_ret_from_kernel_thread:
 	mov.l	er2,er0
-	jsr	@SYMBOL_NAME(schedule_tail)
+	jsr	@_schedule_tail
 	mov.l	@(LER4:16,sp),er0
 	mov.l	@(LER5:16,sp),er1
 	jsr	@er1
-	jmp	@SYMBOL_NAME(ret_from_exception)
+	jmp	@_ret_from_exception
 
-SYMBOL_NAME_LABEL(resume)
+_resume:
 	/*
 	 * Beware - when entering resume, offset of tss is in d1,
 	 * prev (the current task) is in a0, next (the new task)
@@ -355,7 +355,7 @@ SYMBOL_NAME_LABEL(resume)
 
 	/* disable interrupts */
 	orc	#0x80,ccr
-	mov.l	@SYMBOL_NAME(sw_usp),er3
+	mov.l	@_sw_usp,er3
 	mov.l	er3,@(THREAD_USP:16,er0)
 	mov.l	sp,@(THREAD_KSP:16,er0)
 
@@ -363,7 +363,7 @@ SYMBOL_NAME_LABEL(resume)
 	/* FIXME: what did we hack out of here, this does nothing! */
 
 	mov.l	@(THREAD_USP:16,er1),er0
-	mov.l	er0,@SYMBOL_NAME(sw_usp)
+	mov.l	er0,@_sw_usp
 	mov.l	@(THREAD_KSP:16,er1),sp
 
 	/* restore status register */
@@ -372,15 +372,15 @@ SYMBOL_NAME_LABEL(resume)
 	ldc	r3l,ccr
 	rts
 
-SYMBOL_NAME_LABEL(trace_break)
+_trace_break:
 	subs	#4,sp
 	SAVE_ALL
 	sub.l	er1,er1
 	dec.l	#1,er1
 	mov.l	er1,@(LORIG,sp)
 	mov.l	sp,er0
-	jsr	@SYMBOL_NAME(set_esp0)
-	mov.l	@SYMBOL_NAME(sw_usp),er0
+	jsr	@_set_esp0
+	mov.l	@_sw_usp,er0
 	mov.l	@er0,er1
 	mov.w	@(-2:16,er1),r2
 	cmp.w	#0x5730,r2
@@ -390,13 +390,13 @@ SYMBOL_NAME_LABEL(trace_break)
 1:
 	and.w	#0xff,e1
 	mov.l	er1,er0
-	jsr	@SYMBOL_NAME(trace_trap)
-	jmp	@SYMBOL_NAME(ret_from_exception)
+	jsr	@_trace_trap
+	jmp	@_ret_from_exception
 
 	.section	.bss
-SYMBOL_NAME_LABEL(sw_ksp)
+_sw_ksp:
 	.space	4
-SYMBOL_NAME_LABEL(sw_usp)
+_sw_usp:
 	.space	4
 
 	.end
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/kernel/syscalls.S linux-libre-3.11-rc7-gnu/arch/h8300/kernel/syscalls.S
--- linux-libre-3.10-gnu/arch/h8300/kernel/syscalls.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/kernel/syscalls.S	2013-08-25 20:43:22.000000000 -0400
@@ -2,8 +2,10 @@
 #include <linux/sys.h>
 #include <asm/linkage.h>
 #include <asm/unistd.h>
-	
-.globl SYMBOL_NAME(sys_call_table)
+
+#define CALL(x)	.long _ ## x
+
+.globl _sys_call_table
 
 #if defined(CONFIG_CPU_H8300H)
 	.h8300h
@@ -13,324 +15,324 @@
 #endif
 	.section .text
 	.align	2
-SYMBOL_NAME_LABEL(sys_call_table)	
-	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
-	.long SYMBOL_NAME(sys_exit)
-	.long SYMBOL_NAME(sys_fork)
-	.long SYMBOL_NAME(sys_read)
-	.long SYMBOL_NAME(sys_write)
-	.long SYMBOL_NAME(sys_open)		/* 5 */
-	.long SYMBOL_NAME(sys_close)
-	.long SYMBOL_NAME(sys_waitpid)
-	.long SYMBOL_NAME(sys_creat)
-	.long SYMBOL_NAME(sys_link)
-	.long SYMBOL_NAME(sys_unlink)		/* 10 */
-	.long SYMBOL_NAME(sys_execve)
-	.long SYMBOL_NAME(sys_chdir)
-	.long SYMBOL_NAME(sys_time)
-	.long SYMBOL_NAME(sys_mknod)
-	.long SYMBOL_NAME(sys_chmod)		/* 15 */
-	.long SYMBOL_NAME(sys_chown16)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* old break syscall holder */
-	.long SYMBOL_NAME(sys_stat)
-	.long SYMBOL_NAME(sys_lseek)
-	.long SYMBOL_NAME(sys_getpid)		/* 20 */
-	.long SYMBOL_NAME(sys_mount)
-	.long SYMBOL_NAME(sys_oldumount)
-	.long SYMBOL_NAME(sys_setuid16)
-	.long SYMBOL_NAME(sys_getuid16)
-	.long SYMBOL_NAME(sys_stime)		/* 25 */
-	.long SYMBOL_NAME(sys_ptrace)
-	.long SYMBOL_NAME(sys_alarm)
-	.long SYMBOL_NAME(sys_fstat)
-	.long SYMBOL_NAME(sys_pause)
-	.long SYMBOL_NAME(sys_utime)		/* 30 */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* old stty syscall holder */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* old gtty syscall holder */
-	.long SYMBOL_NAME(sys_access)
-	.long SYMBOL_NAME(sys_nice)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 old ftime syscall holder */
-	.long SYMBOL_NAME(sys_sync)
-	.long SYMBOL_NAME(sys_kill)
-	.long SYMBOL_NAME(sys_rename)
-	.long SYMBOL_NAME(sys_mkdir)
-	.long SYMBOL_NAME(sys_rmdir)		/* 40 */
-	.long SYMBOL_NAME(sys_dup)
-	.long SYMBOL_NAME(sys_pipe)
-	.long SYMBOL_NAME(sys_times)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* old prof syscall holder */
-	.long SYMBOL_NAME(sys_brk)		/* 45 */
-	.long SYMBOL_NAME(sys_setgid16)
-	.long SYMBOL_NAME(sys_getgid16)
-	.long SYMBOL_NAME(sys_signal)
-	.long SYMBOL_NAME(sys_geteuid16)
-	.long SYMBOL_NAME(sys_getegid16)	/* 50 */
-	.long SYMBOL_NAME(sys_acct)
-	.long SYMBOL_NAME(sys_umount)		/* recycled never used phys() */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* old lock syscall holder */
-	.long SYMBOL_NAME(sys_ioctl)
-	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* old mpx syscall holder */
-	.long SYMBOL_NAME(sys_setpgid)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* old ulimit syscall holder */
-	.long SYMBOL_NAME(sys_ni_syscall)
-	.long SYMBOL_NAME(sys_umask)		/* 60 */
-	.long SYMBOL_NAME(sys_chroot)
-	.long SYMBOL_NAME(sys_ustat)
-	.long SYMBOL_NAME(sys_dup2)
-	.long SYMBOL_NAME(sys_getppid)
-	.long SYMBOL_NAME(sys_getpgrp)		/* 65 */
-	.long SYMBOL_NAME(sys_setsid)
-	.long SYMBOL_NAME(sys_sigaction)
-	.long SYMBOL_NAME(sys_sgetmask)
-	.long SYMBOL_NAME(sys_ssetmask)
-	.long SYMBOL_NAME(sys_setreuid16)	/* 70 */
-	.long SYMBOL_NAME(sys_setregid16)
-	.long SYMBOL_NAME(sys_sigsuspend)
-	.long SYMBOL_NAME(sys_sigpending)
-	.long SYMBOL_NAME(sys_sethostname)
-	.long SYMBOL_NAME(sys_setrlimit)	/* 75 */
-	.long SYMBOL_NAME(sys_old_getrlimit)
-	.long SYMBOL_NAME(sys_getrusage)
-	.long SYMBOL_NAME(sys_gettimeofday)
-	.long SYMBOL_NAME(sys_settimeofday)
-	.long SYMBOL_NAME(sys_getgroups16)	/* 80 */
-	.long SYMBOL_NAME(sys_setgroups16)
-	.long SYMBOL_NAME(sys_old_select)
-	.long SYMBOL_NAME(sys_symlink)
-	.long SYMBOL_NAME(sys_lstat)
-	.long SYMBOL_NAME(sys_readlink)		/* 85 */
-	.long SYMBOL_NAME(sys_uselib)
-	.long SYMBOL_NAME(sys_swapon)
-	.long SYMBOL_NAME(sys_reboot)
-	.long SYMBOL_NAME(sys_old_readdir)
-	.long SYMBOL_NAME(sys_old_mmap)		/* 90 */
-	.long SYMBOL_NAME(sys_munmap)
-	.long SYMBOL_NAME(sys_truncate)
-	.long SYMBOL_NAME(sys_ftruncate)
-	.long SYMBOL_NAME(sys_fchmod)
-	.long SYMBOL_NAME(sys_fchown16)		/* 95 */
-	.long SYMBOL_NAME(sys_getpriority)
-	.long SYMBOL_NAME(sys_setpriority)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* old profil syscall holder */
-	.long SYMBOL_NAME(sys_statfs)
-	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* ioperm for i386 */
-	.long SYMBOL_NAME(sys_socketcall)
-	.long SYMBOL_NAME(sys_syslog)
-	.long SYMBOL_NAME(sys_setitimer)
-	.long SYMBOL_NAME(sys_getitimer)	/* 105 */
-	.long SYMBOL_NAME(sys_newstat)
-	.long SYMBOL_NAME(sys_newlstat)
-	.long SYMBOL_NAME(sys_newfstat)
-	.long SYMBOL_NAME(sys_ni_syscall)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* iopl for i386 */ /* 110 */
-	.long SYMBOL_NAME(sys_vhangup)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* obsolete idle() syscall */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* vm86old for i386 */
-	.long SYMBOL_NAME(sys_wait4)
-	.long SYMBOL_NAME(sys_swapoff)		/* 115 */
-	.long SYMBOL_NAME(sys_sysinfo)
-	.long SYMBOL_NAME(sys_ipc)
-	.long SYMBOL_NAME(sys_fsync)
-	.long SYMBOL_NAME(sys_sigreturn)
-	.long SYMBOL_NAME(sys_clone)		/* 120 */
-	.long SYMBOL_NAME(sys_setdomainname)
-	.long SYMBOL_NAME(sys_newuname)
-	.long SYMBOL_NAME(sys_cacheflush)	/* modify_ldt for i386 */
-	.long SYMBOL_NAME(sys_adjtimex)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* 125 sys_mprotect */
-	.long SYMBOL_NAME(sys_sigprocmask)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_create_module */
-	.long SYMBOL_NAME(sys_init_module)
-	.long SYMBOL_NAME(sys_delete_module)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* 130 sys_get_kernel_syms */
-	.long SYMBOL_NAME(sys_quotactl)
-	.long SYMBOL_NAME(sys_getpgid)
-	.long SYMBOL_NAME(sys_fchdir)
-	.long SYMBOL_NAME(sys_bdflush)
-	.long SYMBOL_NAME(sys_sysfs)		/* 135 */
-	.long SYMBOL_NAME(sys_personality)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* for afs_syscall */
-	.long SYMBOL_NAME(sys_setfsuid16)
-	.long SYMBOL_NAME(sys_setfsgid16)
-	.long SYMBOL_NAME(sys_llseek)		/* 140 */
-	.long SYMBOL_NAME(sys_getdents)
-	.long SYMBOL_NAME(sys_select)
-	.long SYMBOL_NAME(sys_flock)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_msync */
-	.long SYMBOL_NAME(sys_readv)		/* 145 */
-	.long SYMBOL_NAME(sys_writev)
-	.long SYMBOL_NAME(sys_getsid)
-	.long SYMBOL_NAME(sys_fdatasync)
-	.long SYMBOL_NAME(sys_sysctl)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* 150 sys_mlock */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_munlock */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_mlockall */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_munlockall */
-	.long SYMBOL_NAME(sys_sched_setparam)
-	.long SYMBOL_NAME(sys_sched_getparam)   /* 155 */
-	.long SYMBOL_NAME(sys_sched_setscheduler)
-	.long SYMBOL_NAME(sys_sched_getscheduler)
-	.long SYMBOL_NAME(sys_sched_yield)
-	.long SYMBOL_NAME(sys_sched_get_priority_max)
-	.long SYMBOL_NAME(sys_sched_get_priority_min)  /* 160 */
-	.long SYMBOL_NAME(sys_sched_rr_get_interval)
-	.long SYMBOL_NAME(sys_nanosleep)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_mremap */
-	.long SYMBOL_NAME(sys_setresuid16)
-	.long SYMBOL_NAME(sys_getresuid16)	/* 165 */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* for vm86 */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_query_module */
-	.long SYMBOL_NAME(sys_poll)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* old nfsservctl */
-	.long SYMBOL_NAME(sys_setresgid16)	/* 170 */
-	.long SYMBOL_NAME(sys_getresgid16)
-	.long SYMBOL_NAME(sys_prctl)
-	.long SYMBOL_NAME(sys_rt_sigreturn)
-	.long SYMBOL_NAME(sys_rt_sigaction)
-	.long SYMBOL_NAME(sys_rt_sigprocmask)	/* 175 */
-	.long SYMBOL_NAME(sys_rt_sigpending)
-	.long SYMBOL_NAME(sys_rt_sigtimedwait)
-	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
-	.long SYMBOL_NAME(sys_rt_sigsuspend)
-	.long SYMBOL_NAME(sys_pread64)		/* 180 */
-	.long SYMBOL_NAME(sys_pwrite64)
-	.long SYMBOL_NAME(sys_lchown16);
-	.long SYMBOL_NAME(sys_getcwd)
-	.long SYMBOL_NAME(sys_capget)
-	.long SYMBOL_NAME(sys_capset)           /* 185 */
-	.long SYMBOL_NAME(sys_sigaltstack)
-	.long SYMBOL_NAME(sys_sendfile)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* streams1 */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* streams2 */
-	.long SYMBOL_NAME(sys_vfork)            /* 190 */
-	.long SYMBOL_NAME(sys_getrlimit)
-	.long SYMBOL_NAME(sys_mmap_pgoff)
-	.long SYMBOL_NAME(sys_truncate64)
-	.long SYMBOL_NAME(sys_ftruncate64)
-	.long SYMBOL_NAME(sys_stat64)		/* 195 */
-	.long SYMBOL_NAME(sys_lstat64)
-	.long SYMBOL_NAME(sys_fstat64)
-	.long SYMBOL_NAME(sys_chown)
-	.long SYMBOL_NAME(sys_getuid)
-	.long SYMBOL_NAME(sys_getgid)		/* 200 */
-	.long SYMBOL_NAME(sys_geteuid)
-	.long SYMBOL_NAME(sys_getegid)
-	.long SYMBOL_NAME(sys_setreuid)
-	.long SYMBOL_NAME(sys_setregid)
-	.long SYMBOL_NAME(sys_getgroups)	/* 205 */
-	.long SYMBOL_NAME(sys_setgroups)
-	.long SYMBOL_NAME(sys_fchown)
-	.long SYMBOL_NAME(sys_setresuid)
-	.long SYMBOL_NAME(sys_getresuid)
-	.long SYMBOL_NAME(sys_setresgid)	/* 210 */
-	.long SYMBOL_NAME(sys_getresgid)
-	.long SYMBOL_NAME(sys_lchown)
-	.long SYMBOL_NAME(sys_setuid)
-	.long SYMBOL_NAME(sys_setgid)
-	.long SYMBOL_NAME(sys_setfsuid)		/* 215 */
-	.long SYMBOL_NAME(sys_setfsgid)
-	.long SYMBOL_NAME(sys_pivot_root)
-	.long SYMBOL_NAME(sys_ni_syscall)
-	.long SYMBOL_NAME(sys_ni_syscall)
-	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
-	.long SYMBOL_NAME(sys_fcntl64)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved TUX */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved Security */
-	.long SYMBOL_NAME(sys_gettid)
-	.long SYMBOL_NAME(sys_readahead)	/* 225 */
-	.long SYMBOL_NAME(sys_setxattr)
-	.long SYMBOL_NAME(sys_lsetxattr)
-	.long SYMBOL_NAME(sys_fsetxattr)
-	.long SYMBOL_NAME(sys_getxattr)
-	.long SYMBOL_NAME(sys_lgetxattr)	/* 230 */
-	.long SYMBOL_NAME(sys_fgetxattr)
-	.long SYMBOL_NAME(sys_listxattr)
-	.long SYMBOL_NAME(sys_llistxattr)
-	.long SYMBOL_NAME(sys_flistxattr)
-	.long SYMBOL_NAME(sys_removexattr)	/* 235 */
-	.long SYMBOL_NAME(sys_lremovexattr)
-	.long SYMBOL_NAME(sys_fremovexattr)
-	.long SYMBOL_NAME(sys_tkill)
-	.long SYMBOL_NAME(sys_sendfile64)
-	.long SYMBOL_NAME(sys_futex)		/* 240 */
-	.long SYMBOL_NAME(sys_sched_setaffinity)
-	.long SYMBOL_NAME(sys_sched_getaffinity)
-	.long SYMBOL_NAME(sys_ni_syscall)
-	.long SYMBOL_NAME(sys_ni_syscall)
-	.long SYMBOL_NAME(sys_io_setup)		/* 245 */
-	.long SYMBOL_NAME(sys_io_destroy)
-	.long SYMBOL_NAME(sys_io_getevents)
-	.long SYMBOL_NAME(sys_io_submit)
-	.long SYMBOL_NAME(sys_io_cancel)
-	.long SYMBOL_NAME(sys_fadvise64)	/* 250 */
-	.long SYMBOL_NAME(sys_ni_syscall)
-	.long SYMBOL_NAME(sys_exit_group)
-	.long SYMBOL_NAME(sys_lookup_dcookie)
-	.long SYMBOL_NAME(sys_epoll_create)
-	.long SYMBOL_NAME(sys_epoll_ctl)	/* 255 */
-	.long SYMBOL_NAME(sys_epoll_wait)
- 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_remap_file_pages */
- 	.long SYMBOL_NAME(sys_set_tid_address)
- 	.long SYMBOL_NAME(sys_timer_create)
- 	.long SYMBOL_NAME(sys_timer_settime)	/* 260 */
- 	.long SYMBOL_NAME(sys_timer_gettime)
- 	.long SYMBOL_NAME(sys_timer_getoverrun)
- 	.long SYMBOL_NAME(sys_timer_delete)
- 	.long SYMBOL_NAME(sys_clock_settime)
- 	.long SYMBOL_NAME(sys_clock_gettime)	/* 265 */
- 	.long SYMBOL_NAME(sys_clock_getres)
- 	.long SYMBOL_NAME(sys_clock_nanosleep)
-	.long SYMBOL_NAME(sys_statfs64)
-	.long SYMBOL_NAME(sys_fstatfs64)	
-	.long SYMBOL_NAME(sys_tgkill)		/* 270 */
-	.long SYMBOL_NAME(sys_utimes)
- 	.long SYMBOL_NAME(sys_fadvise64_64)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_vserver */
-	.long SYMBOL_NAME(sys_ni_syscall)
-	.long SYMBOL_NAME(sys_get_mempolicy)	/* 275 */
-	.long SYMBOL_NAME(sys_set_mempolicy)
-	.long SYMBOL_NAME(sys_mq_open)
-	.long SYMBOL_NAME(sys_mq_unlink)
-	.long SYMBOL_NAME(sys_mq_timedsend)
-	.long SYMBOL_NAME(sys_mq_timedreceive)	/* 280 */
-	.long SYMBOL_NAME(sys_mq_notify)
-	.long SYMBOL_NAME(sys_mq_getsetattr)
-	.long SYMBOL_NAME(sys_waitid)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_kexec_load */
-	.long SYMBOL_NAME(sys_add_key) 		/* 285 */
-	.long SYMBOL_NAME(sys_request_key)
-	.long SYMBOL_NAME(sys_keyctl)
-	.long SYMBOL_NAME(sys_ioprio_set)
-	.long SYMBOL_NAME(sys_ioprio_get)	/* 290 */
-	.long SYMBOL_NAME(sys_inotify_init)
-	.long SYMBOL_NAME(sys_inotify_add_watch)
-	.long SYMBOL_NAME(sys_inotify_rm_watch)
-	.long SYMBOL_NAME(sys_migrate_pages)
-	.long SYMBOL_NAME(sys_openat)		/* 295 */
-	.long SYMBOL_NAME(sys_mkdirat)
-	.long SYMBOL_NAME(sys_mknodat)
-	.long SYMBOL_NAME(sys_fchownat)
-	.long SYMBOL_NAME(sys_futimesat)
-	.long SYMBOL_NAME(sys_fstatat64)	/* 300 */
-	.long SYMBOL_NAME(sys_unlinkat)
-	.long SYMBOL_NAME(sys_renameat)
-	.long SYMBOL_NAME(sys_linkat)
-	.long SYMBOL_NAME(sys_symlinkat)
-	.long SYMBOL_NAME(sys_readlinkat)	/* 305 */
-	.long SYMBOL_NAME(sys_fchmodat)
-	.long SYMBOL_NAME(sys_faccessat)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_pselect6 */
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_ppoll */
-	.long SYMBOL_NAME(sys_unshare)		/* 310 */
-	.long SYMBOL_NAME(sys_set_robust_list)
-	.long SYMBOL_NAME(sys_get_robust_list)
-	.long SYMBOL_NAME(sys_splice)
-	.long SYMBOL_NAME(sys_sync_file_range)
-	.long SYMBOL_NAME(sys_tee)		/* 315 */
-	.long SYMBOL_NAME(sys_vmsplice)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_move_pages */
-	.long SYMBOL_NAME(sys_getcpu)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_pwait */
-	.long SYMBOL_NAME(sys_setns)		/* 320 */
+_sys_call_table:
+	CALL(sys_ni_syscall)		/* 0  -  old "setup()" system call*/
+	CALL(sys_exit)
+	CALL(sys_fork)
+	CALL(sys_read)
+	CALL(sys_write)
+	CALL(sys_open)			/* 5 */
+	CALL(sys_close)
+	CALL(sys_waitpid)
+	CALL(sys_creat)
+	CALL(sys_link)
+	CALL(sys_unlink)		/* 10 */
+	CALL(sys_execve)
+	CALL(sys_chdir)
+	CALL(sys_time)
+	CALL(sys_mknod)
+	CALL(sys_chmod)			/* 15 */
+	CALL(sys_chown16)
+	CALL(sys_ni_syscall)		/* old break syscall holder */
+	CALL(sys_stat)
+	CALL(sys_lseek)
+	CALL(sys_getpid)		/* 20 */
+	CALL(sys_mount)
+	CALL(sys_oldumount)
+	CALL(sys_setuid16)
+	CALL(sys_getuid16)
+	CALL(sys_stime)			/* 25 */
+	CALL(sys_ptrace)
+	CALL(sys_alarm)
+	CALL(sys_fstat)
+	CALL(sys_pause)
+	CALL(sys_utime)			/* 30 */
+	CALL(sys_ni_syscall)		/* old stty syscall holder */
+	CALL(sys_ni_syscall)		/* old gtty syscall holder */
+	CALL(sys_access)
+	CALL(sys_nice)
+	CALL(sys_ni_syscall)		/* 35 old ftime syscall holder */
+	CALL(sys_sync)
+	CALL(sys_kill)
+	CALL(sys_rename)
+	CALL(sys_mkdir)
+	CALL(sys_rmdir)			/* 40 */
+	CALL(sys_dup)
+	CALL(sys_pipe)
+	CALL(sys_times)
+	CALL(sys_ni_syscall)		/* old prof syscall holder */
+	CALL(sys_brk)			/* 45 */
+	CALL(sys_setgid16)
+	CALL(sys_getgid16)
+	CALL(sys_signal)
+	CALL(sys_geteuid16)
+	CALL(sys_getegid16)		/* 50 */
+	CALL(sys_acct)
+	CALL(sys_umount)		/* recycled never used phys() */
+	CALL(sys_ni_syscall)		/* old lock syscall holder */
+	CALL(sys_ioctl)
+	CALL(sys_fcntl)			/* 55 */
+	CALL(sys_ni_syscall)		/* old mpx syscall holder */
+	CALL(sys_setpgid)
+	CALL(sys_ni_syscall)		/* old ulimit syscall holder */
+	CALL(sys_ni_syscall)
+	CALL(sys_umask)			/* 60 */
+	CALL(sys_chroot)
+	CALL(sys_ustat)
+	CALL(sys_dup2)
+	CALL(sys_getppid)
+	CALL(sys_getpgrp)		/* 65 */
+	CALL(sys_setsid)
+	CALL(sys_sigaction)
+	CALL(sys_sgetmask)
+	CALL(sys_ssetmask)
+	CALL(sys_setreuid16)		/* 70 */
+	CALL(sys_setregid16)
+	CALL(sys_sigsuspend)
+	CALL(sys_sigpending)
+	CALL(sys_sethostname)
+	CALL(sys_setrlimit)		/* 75 */
+	CALL(sys_old_getrlimit)
+	CALL(sys_getrusage)
+	CALL(sys_gettimeofday)
+	CALL(sys_settimeofday)
+	CALL(sys_getgroups16)		/* 80 */
+	CALL(sys_setgroups16)
+	CALL(sys_old_select)
+	CALL(sys_symlink)
+	CALL(sys_lstat)
+	CALL(sys_readlink)		/* 85 */
+	CALL(sys_uselib)
+	CALL(sys_swapon)
+	CALL(sys_reboot)
+	CALL(sys_old_readdir)
+	CALL(sys_old_mmap)		/* 90 */
+	CALL(sys_munmap)
+	CALL(sys_truncate)
+	CALL(sys_ftruncate)
+	CALL(sys_fchmod)
+	CALL(sys_fchown16)		/* 95 */
+	CALL(sys_getpriority)
+	CALL(sys_setpriority)
+	CALL(sys_ni_syscall)		/* old profil syscall holder */
+	CALL(sys_statfs)
+	CALL(sys_fstatfs)		/* 100 */
+	CALL(sys_ni_syscall)		/* ioperm for i386 */
+	CALL(sys_socketcall)
+	CALL(sys_syslog)
+	CALL(sys_setitimer)
+	CALL(sys_getitimer)		/* 105 */
+	CALL(sys_newstat)
+	CALL(sys_newlstat)
+	CALL(sys_newfstat)
+	CALL(sys_ni_syscall)
+	CALL(sys_ni_syscall)		/* iopl for i386 */ /* 110 */
+	CALL(sys_vhangup)
+	CALL(sys_ni_syscall)		/* obsolete idle() syscall */
+	CALL(sys_ni_syscall)		/* vm86old for i386 */
+	CALL(sys_wait4)
+	CALL(sys_swapoff)		/* 115 */
+	CALL(sys_sysinfo)
+	CALL(sys_ipc)
+	CALL(sys_fsync)
+	CALL(sys_sigreturn)
+	CALL(sys_clone)			/* 120 */
+	CALL(sys_setdomainname)
+	CALL(sys_newuname)
+	CALL(sys_cacheflush)		/* modify_ldt for i386 */
+	CALL(sys_adjtimex)
+	CALL(sys_ni_syscall)		/* 125 sys_mprotect */
+	CALL(sys_sigprocmask)
+	CALL(sys_ni_syscall)		/* sys_create_module */
+	CALL(sys_init_module)
+	CALL(sys_delete_module)
+	CALL(sys_ni_syscall)		/* 130 sys_get_kernel_syms */
+	CALL(sys_quotactl)
+	CALL(sys_getpgid)
+	CALL(sys_fchdir)
+	CALL(sys_bdflush)
+	CALL(sys_sysfs)			/* 135 */
+	CALL(sys_personality)
+	CALL(sys_ni_syscall)		/* for afs_syscall */
+	CALL(sys_setfsuid16)
+	CALL(sys_setfsgid16)
+	CALL(sys_llseek)		/* 140 */
+	CALL(sys_getdents)
+	CALL(sys_select)
+	CALL(sys_flock)
+	CALL(sys_ni_syscall)		/* sys_msync */
+	CALL(sys_readv)			/* 145 */
+	CALL(sys_writev)
+	CALL(sys_getsid)
+	CALL(sys_fdatasync)
+	CALL(sys_sysctl)
+	CALL(sys_ni_syscall)		/* 150 sys_mlock */
+	CALL(sys_ni_syscall)		/* sys_munlock */
+	CALL(sys_ni_syscall)		/* sys_mlockall */
+	CALL(sys_ni_syscall)		/* sys_munlockall */
+	CALL(sys_sched_setparam)
+	CALL(sys_sched_getparam)	/* 155 */
+	CALL(sys_sched_setscheduler)
+	CALL(sys_sched_getscheduler)
+	CALL(sys_sched_yield)
+	CALL(sys_sched_get_priority_max)
+	CALL(sys_sched_get_priority_min)  /* 160 */
+	CALL(sys_sched_rr_get_interval)
+	CALL(sys_nanosleep)
+	CALL(sys_ni_syscall)		/* sys_mremap */
+	CALL(sys_setresuid16)
+	CALL(sys_getresuid16)		/* 165 */
+	CALL(sys_ni_syscall)		/* for vm86 */
+	CALL(sys_ni_syscall)		/* sys_query_module */
+	CALL(sys_poll)
+	CALL(sys_ni_syscall)		/* old nfsservctl */
+	CALL(sys_setresgid16)		/* 170 */
+	CALL(sys_getresgid16)
+	CALL(sys_prctl)
+	CALL(sys_rt_sigreturn)
+	CALL(sys_rt_sigaction)
+	CALL(sys_rt_sigprocmask)	/* 175 */
+	CALL(sys_rt_sigpending)
+	CALL(sys_rt_sigtimedwait)
+	CALL(sys_rt_sigqueueinfo)
+	CALL(sys_rt_sigsuspend)
+	CALL(sys_pread64)		/* 180 */
+	CALL(sys_pwrite64)
+	CALL(sys_lchown16);
+	CALL(sys_getcwd)
+	CALL(sys_capget)
+	CALL(sys_capset)		/* 185 */
+	CALL(sys_sigaltstack)
+	CALL(sys_sendfile)
+	CALL(sys_ni_syscall)		/* streams1 */
+	CALL(sys_ni_syscall)		/* streams2 */
+	CALL(sys_vfork)			/* 190 */
+	CALL(sys_getrlimit)
+	CALL(sys_mmap_pgoff)
+	CALL(sys_truncate64)
+	CALL(sys_ftruncate64)
+	CALL(sys_stat64)		/* 195 */
+	CALL(sys_lstat64)
+	CALL(sys_fstat64)
+	CALL(sys_chown)
+	CALL(sys_getuid)
+	CALL(sys_getgid)		/* 200 */
+	CALL(sys_geteuid)
+	CALL(sys_getegid)
+	CALL(sys_setreuid)
+	CALL(sys_setregid)
+	CALL(sys_getgroups)		/* 205 */
+	CALL(sys_setgroups)
+	CALL(sys_fchown)
+	CALL(sys_setresuid)
+	CALL(sys_getresuid)
+	CALL(sys_setresgid)		/* 210 */
+	CALL(sys_getresgid)
+	CALL(sys_lchown)
+	CALL(sys_setuid)
+	CALL(sys_setgid)
+	CALL(sys_setfsuid)		/* 215 */
+	CALL(sys_setfsgid)
+	CALL(sys_pivot_root)
+	CALL(sys_ni_syscall)
+	CALL(sys_ni_syscall)
+	CALL(sys_getdents64)		/* 220 */
+	CALL(sys_fcntl64)
+	CALL(sys_ni_syscall)		/* reserved TUX */
+	CALL(sys_ni_syscall)		/* reserved Security */
+	CALL(sys_gettid)
+	CALL(sys_readahead)		/* 225 */
+	CALL(sys_setxattr)
+	CALL(sys_lsetxattr)
+	CALL(sys_fsetxattr)
+	CALL(sys_getxattr)
+	CALL(sys_lgetxattr)		/* 230 */
+	CALL(sys_fgetxattr)
+	CALL(sys_listxattr)
+	CALL(sys_llistxattr)
+	CALL(sys_flistxattr)
+	CALL(sys_removexattr)		/* 235 */
+	CALL(sys_lremovexattr)
+	CALL(sys_fremovexattr)
+	CALL(sys_tkill)
+	CALL(sys_sendfile64)
+	CALL(sys_futex)			/* 240 */
+	CALL(sys_sched_setaffinity)
+	CALL(sys_sched_getaffinity)
+	CALL(sys_ni_syscall)
+	CALL(sys_ni_syscall)
+	CALL(sys_io_setup)		/* 245 */
+	CALL(sys_io_destroy)
+	CALL(sys_io_getevents)
+	CALL(sys_io_submit)
+	CALL(sys_io_cancel)
+	CALL(sys_fadvise64)		/* 250 */
+	CALL(sys_ni_syscall)
+	CALL(sys_exit_group)
+	CALL(sys_lookup_dcookie)
+	CALL(sys_epoll_create)
+	CALL(sys_epoll_ctl)		/* 255 */
+	CALL(sys_epoll_wait)
+	CALL(sys_ni_syscall)		/* sys_remap_file_pages */
+	CALL(sys_set_tid_address)
+	CALL(sys_timer_create)
+	CALL(sys_timer_settime)		/* 260 */
+	CALL(sys_timer_gettime)
+	CALL(sys_timer_getoverrun)
+	CALL(sys_timer_delete)
+	CALL(sys_clock_settime)
+	CALL(sys_clock_gettime)		/* 265 */
+	CALL(sys_clock_getres)
+	CALL(sys_clock_nanosleep)
+	CALL(sys_statfs64)
+	CALL(sys_fstatfs64)
+	CALL(sys_tgkill)		/* 270 */
+	CALL(sys_utimes)
+	CALL(sys_fadvise64_64)
+	CALL(sys_ni_syscall)		/* sys_vserver */
+	CALL(sys_ni_syscall)
+	CALL(sys_get_mempolicy)		/* 275 */
+	CALL(sys_set_mempolicy)
+	CALL(sys_mq_open)
+	CALL(sys_mq_unlink)
+	CALL(sys_mq_timedsend)
+	CALL(sys_mq_timedreceive)	/* 280 */
+	CALL(sys_mq_notify)
+	CALL(sys_mq_getsetattr)
+	CALL(sys_waitid)
+	CALL(sys_ni_syscall)		/* sys_kexec_load */
+	CALL(sys_add_key) 		/* 285 */
+	CALL(sys_request_key)
+	CALL(sys_keyctl)
+	CALL(sys_ioprio_set)
+	CALL(sys_ioprio_get)		/* 290 */
+	CALL(sys_inotify_init)
+	CALL(sys_inotify_add_watch)
+	CALL(sys_inotify_rm_watch)
+	CALL(sys_migrate_pages)
+	CALL(sys_openat)		/* 295 */
+	CALL(sys_mkdirat)
+	CALL(sys_mknodat)
+	CALL(sys_fchownat)
+	CALL(sys_futimesat)
+	CALL(sys_fstatat64)		/* 300 */
+	CALL(sys_unlinkat)
+	CALL(sys_renameat)
+	CALL(sys_linkat)
+	CALL(sys_symlinkat)
+	CALL(sys_readlinkat)		/* 305 */
+	CALL(sys_fchmodat)
+	CALL(sys_faccessat)
+	CALL(sys_ni_syscall)		/* sys_pselect6 */
+	CALL(sys_ni_syscall)		/* sys_ppoll */
+	CALL(sys_unshare)		/* 310 */
+	CALL(sys_set_robust_list)
+	CALL(sys_get_robust_list)
+	CALL(sys_splice)
+	CALL(sys_sync_file_range)
+	CALL(sys_tee)			/* 315 */
+	CALL(sys_vmsplice)
+	CALL(sys_ni_syscall)		/* sys_move_pages */
+	CALL(sys_getcpu)
+	CALL(sys_ni_syscall)		/* sys_epoll_pwait */
+	CALL(sys_setns)			/* 320 */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/kernel/vmlinux.lds.S linux-libre-3.11-rc7-gnu/arch/h8300/kernel/vmlinux.lds.S
--- linux-libre-3.10-gnu/arch/h8300/kernel/vmlinux.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/kernel/vmlinux.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -132,10 +132,12 @@ SECTIONS
         {
 	. = ALIGN(0x4) ;
 	__sbss = . ;
+	___bss_start = . ;
 		*(.bss*)
 	. = ALIGN(0x4) ;
 		*(COMMON)
 	. = ALIGN(0x4) ;
+	___bss_stop = . ;
 	__ebss = . ;
 	__end = . ;
 	__ramstart = .;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/lib/abs.S linux-libre-3.11-rc7-gnu/arch/h8300/lib/abs.S
--- linux-libre-3.10-gnu/arch/h8300/lib/abs.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/lib/abs.S	2013-08-25 20:43:22.000000000 -0400
@@ -9,10 +9,10 @@
 	.h8300s
 #endif
 	.text
-.global SYMBOL_NAME(abs)
+.global _abs
 
 ;;; int abs(int n)
-SYMBOL_NAME_LABEL(abs)
+_abs:
 	mov.l	er0,er0
 	bpl	1f
 	neg.l	er0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/lib/memcpy.S linux-libre-3.11-rc7-gnu/arch/h8300/lib/memcpy.S
--- linux-libre-3.10-gnu/arch/h8300/lib/memcpy.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/lib/memcpy.S	2013-08-25 20:43:22.000000000 -0400
@@ -10,10 +10,10 @@
 #endif
 
 	.text
-.global SYMBOL_NAME(memcpy)
+.global _memcpy
 
 ;;; void *memcpy(void *to, void *from, size_t n)
-SYMBOL_NAME_LABEL(memcpy)
+_memcpy:
 	mov.l	er2,er2
 	bne	1f
 	rts	
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/lib/memset.S linux-libre-3.11-rc7-gnu/arch/h8300/lib/memset.S
--- linux-libre-3.10-gnu/arch/h8300/lib/memset.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/lib/memset.S	2013-08-25 20:43:22.000000000 -0400
@@ -10,13 +10,13 @@
 #endif
 	.text
 
-.global	SYMBOL_NAME(memset)
+.global	_memset
 
 ;;void *memset(*ptr, int c, size_t count)
 ;; ptr = er0
 ;; c   = er1(r1l)
 ;; count = er2
-SYMBOL_NAME_LABEL(memset)
+_memset:
 	btst	#0,r0l
 	beq	2f
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/mm/init.c linux-libre-3.11-rc7-gnu/arch/h8300/mm/init.c
--- linux-libre-3.10-gnu/arch/h8300/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -121,47 +121,27 @@ void __init paging_init(void)
 
 void __init mem_init(void)
 {
-	int codek = 0, datak = 0, initk = 0;
-	/* DAVIDM look at setup memory map generically with reserved area */
-	unsigned long tmp;
-	extern unsigned long  _ramend, _ramstart;
-	unsigned long len = &_ramend - &_ramstart;
-	unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
-	unsigned long end_mem   = memory_end; /* DAVIDM - this must not include kernel stack at top */
-
-#ifdef DEBUG
-	printk(KERN_DEBUG "Mem_init: start=%lx, end=%lx\n", start_mem, end_mem);
-#endif
+	unsigned long codesize = _etext - _stext;
 
-	end_mem &= PAGE_MASK;
-	high_memory = (void *) end_mem;
+	pr_devel("Mem_init: start=%lx, end=%lx\n", memory_start, memory_end);
 
-	start_mem = PAGE_ALIGN(start_mem);
-	max_mapnr = num_physpages = MAP_NR(high_memory);
+	high_memory = (void *) (memory_end & PAGE_MASK);
+	max_mapnr = MAP_NR(high_memory);
 
 	/* this will put all low memory onto the freelists */
-	totalram_pages = free_all_bootmem();
-
-	codek = (_etext - _stext) >> 10;
-	datak = (__bss_stop - _sdata) >> 10;
-	initk = (__init_begin - __init_end) >> 10;
+	free_all_bootmem();
 
-	tmp = nr_free_pages() << PAGE_SHIFT;
-	printk(KERN_INFO "Memory available: %luk/%luk RAM, %luk/%luk ROM (%dk kernel code, %dk data)\n",
-	       tmp >> 10,
-	       len >> 10,
-	       (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
-	       rom_length >> 10,
-	       codek,
-	       datak
-	       );
+	mem_init_print_info(NULL);
+	if (rom_length > 0 && rom_length > codesize)
+		pr_info("Memory available: %luK/%luK ROM\n",
+			(rom_length - codesize) >> 10, rom_length >> 10);
 }
 
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
 
@@ -169,7 +149,7 @@ void
 free_initmem(void)
 {
 #ifdef CONFIG_RAMKERNEL
-	free_initmem_default(0);
+	free_initmem_default(-1);
 #endif
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S
--- linux-libre-3.10-gnu/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8300h/aki3068net/crt0_ram.S	2013-08-25 20:43:22.000000000 -0400
@@ -22,10 +22,10 @@
 #define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
 #endif
 	
-	.global SYMBOL_NAME(_start)
-	.global SYMBOL_NAME(command_line)
-	.global SYMBOL_NAME(_platform_gpio_table)
-	.global SYMBOL_NAME(_target_name)
+	.global __start
+	.global _command_line
+	.global __platform_gpio_table
+	.global __target_name
 	
 	.h8300h
 
@@ -33,7 +33,7 @@
 	.file	"crt0_ram.S"
 
 	/* CPU Reset entry */
-SYMBOL_NAME_LABEL(_start)
+__start:
 	mov.l	#RAMEND,sp
 	ldc	#0x80,ccr
 
@@ -59,13 +59,13 @@ SYMBOL_NAME_LABEL(_start)
 
 	/* copy kernel commandline */
 	mov.l	#COMMAND_START,er5
-	mov.l	#SYMBOL_NAME(command_line),er6
+	mov.l	#_command_line,er6
 	mov.w	#512,r4
 	eepmov.w
 
 	/* uClinux kernel start */
 	ldc	#0x90,ccr	/* running kernel */
-	mov.l	#SYMBOL_NAME(init_thread_union),sp
+	mov.l	#_init_thread_union,sp
 	add.l	#0x2000,sp
 	jsr	@_start_kernel
 _exit:
@@ -107,4 +107,4 @@ __target_name:
 	.asciz	"AE-3068"
 	
 	.section .bootvec,"ax"
-	jmp	@SYMBOL_NAME(_start)
+	jmp	@__start
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/platform/h8300h/generic/crt0_ram.S linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8300h/generic/crt0_ram.S
--- linux-libre-3.10-gnu/arch/h8300/platform/h8300h/generic/crt0_ram.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8300h/generic/crt0_ram.S	2013-08-25 20:43:22.000000000 -0400
@@ -22,10 +22,10 @@
 #define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
 #endif
 	
-	.global SYMBOL_NAME(_start)
-	.global SYMBOL_NAME(command_line)
-	.global SYMBOL_NAME(_platform_gpio_table)
-	.global SYMBOL_NAME(_target_name)
+	.global __start
+	.global _command_line
+	.global __platform_gpio_table
+	.global __target_name
 	
 	.h8300h
 
@@ -33,7 +33,7 @@
 	.file	"crt0_ram.S"
 
 	/* CPU Reset entry */
-SYMBOL_NAME_LABEL(_start)
+__start:
 	mov.l	#RAMEND,sp
 	ldc	#0x80,ccr
 
@@ -59,13 +59,13 @@ SYMBOL_NAME_LABEL(_start)
 
 	/* copy kernel commandline */
 	mov.l	#COMMAND_START,er5
-	mov.l	#SYMBOL_NAME(command_line),er6
+	mov.l	#_command_line,er6
 	mov.w	#512,r4
 	eepmov.w
 
 	/* uClinux kernel start */
 	ldc	#0x90,ccr	/* running kernel */
-	mov.l	#SYMBOL_NAME(init_thread_union),sp
+	mov.l	#_init_thread_union,sp
 	add.l	#0x2000,sp
 	jsr	@_start_kernel
 _exit:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/platform/h8300h/generic/crt0_rom.S linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8300h/generic/crt0_rom.S
--- linux-libre-3.10-gnu/arch/h8300/platform/h8300h/generic/crt0_rom.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8300h/generic/crt0_rom.S	2013-08-25 20:43:22.000000000 -0400
@@ -12,17 +12,17 @@
 
 #include <asm/linkage.h>
 	
-	.global SYMBOL_NAME(_start)
-	.global SYMBOL_NAME(_command_line)
-	.global SYMBOL_NAME(_platform_gpio_table)
-	.global SYMBOL_NAME(_target_name)
+	.global __start
+	.global __command_line
+	.global __platform_gpio_table
+	.global __target_name
 	
 	.h8300h
 	.section .text
 	.file	"crt0_rom.S"
 
 	/* CPU Reset entry */
-SYMBOL_NAME_LABEL(_start)
+__start:
 	mov.l	#__ramend,sp
 	ldc	#0x80,ccr
 
@@ -60,13 +60,13 @@ SYMBOL_NAME_LABEL(_start)
 
 	/* copy kernel commandline */
 	mov.l	#COMMAND_START,er5
-	mov.l	#SYMBOL_NAME(_command_line),er6
+	mov.l	#__command_line,er6
 	mov.w	#512,r4
 	eepmov.w
 
 	/* linux kernel start */
 	ldc	#0x90,ccr	/* running kernel */
-	mov.l	#SYMBOL_NAME(init_thread_union),sp
+	mov.l	#_init_thread_union,sp
 	add.l	#0x2000,sp
 	jsr	@_start_kernel
 _exit:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/platform/h8300h/h8max/crt0_ram.S linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8300h/h8max/crt0_ram.S
--- linux-libre-3.10-gnu/arch/h8300/platform/h8300h/h8max/crt0_ram.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8300h/h8max/crt0_ram.S	2013-08-25 20:43:22.000000000 -0400
@@ -22,10 +22,10 @@
 #define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
 #endif
 	
-	.global SYMBOL_NAME(_start)
-	.global SYMBOL_NAME(command_line)
-	.global SYMBOL_NAME(_platform_gpio_table)
-	.global SYMBOL_NAME(_target_name)
+	.global __start
+	.global _command_line
+	.global __platform_gpio_table
+	.global __target_name
 	
 	.h8300h
 
@@ -33,7 +33,7 @@
 	.file	"crt0_ram.S"
 
 	/* CPU Reset entry */
-SYMBOL_NAME_LABEL(_start)
+__start:
 	mov.l	#RAMEND,sp
 	ldc	#0x80,ccr
 
@@ -59,13 +59,13 @@ SYMBOL_NAME_LABEL(_start)
 
 	/* copy kernel commandline */
 	mov.l	#COMMAND_START,er5
-	mov.l	#SYMBOL_NAME(command_line),er6
+	mov.l	#_command_line,er6
 	mov.w	#512,r4
 	eepmov.w
 
 	/* uClinux kernel start */
 	ldc	#0x90,ccr	/* running kernel */
-	mov.l	#SYMBOL_NAME(init_thread_union),sp
+	mov.l	#_init_thread_union,sp
 	add.l	#0x2000,sp
 	jsr	@_start_kernel
 _exit:
@@ -107,4 +107,4 @@ __target_name:
 	.asciz	"H8MAX"
 	
 	.section .bootvec,"ax"
-	jmp	@SYMBOL_NAME(_start)
+	jmp	@__start
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/platform/h8s/edosk2674/crt0_ram.S linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8s/edosk2674/crt0_ram.S
--- linux-libre-3.10-gnu/arch/h8300/platform/h8s/edosk2674/crt0_ram.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8s/edosk2674/crt0_ram.S	2013-08-25 20:43:22.000000000 -0400
@@ -23,10 +23,10 @@
 #define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
 #endif
 	
-	.global SYMBOL_NAME(_start)
-	.global SYMBOL_NAME(_command_line)
-	.global SYMBOL_NAME(_platform_gpio_table)
-	.global SYMBOL_NAME(_target_name)
+	.global __start
+	.global __command_line
+	.global __platform_gpio_table
+	.global __target_name
 	
 	.h8300s
 
@@ -34,7 +34,7 @@
 	.file	"crt0_ram.S"
 
 	/* CPU Reset entry */
-SYMBOL_NAME_LABEL(_start)
+__start:
 	mov.l	#RAMEND,sp
 	ldc	#0x80,ccr
 	ldc	#0x00,exr
@@ -66,13 +66,13 @@ SYMBOL_NAME_LABEL(_start)
 
 	/* copy kernel commandline */
 	mov.l	#COMMAND_START,er5
-	mov.l	#SYMBOL_NAME(command_line),er6
+	mov.l	#_command_line,er6
 	mov.w	#512,r4
 	eepmov.w
 
 	/* uClinux kernel start */
 	ldc	#0x90,ccr	/* running kernel */
-	mov.l	#SYMBOL_NAME(init_thread_union),sp
+	mov.l	#_init_thread_union,sp
 	add.l	#0x2000,sp
 	jsr	@_start_kernel
 _exit:
@@ -127,4 +127,4 @@ __target_name:
 	.asciz	"EDOSK-2674"
 	
 	.section .bootvec,"ax"
-	jmp	@SYMBOL_NAME(_start)
+	jmp	@__start
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/platform/h8s/edosk2674/crt0_rom.S linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8s/edosk2674/crt0_rom.S
--- linux-libre-3.10-gnu/arch/h8300/platform/h8s/edosk2674/crt0_rom.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8s/edosk2674/crt0_rom.S	2013-08-25 20:43:22.000000000 -0400
@@ -13,17 +13,17 @@
 #include <asm/linkage.h>
 #include <asm/regs267x.h>
 		
-	.global SYMBOL_NAME(_start)
-	.global SYMBOL_NAME(_command_line)
-	.global SYMBOL_NAME(_platform_gpio_table)
-	.global SYMBOL_NAME(_target_name)
+	.global __start
+	.global __command_line
+	.global __platform_gpio_table
+	.global __target_name
 	
 	.h8300s
 	.section .text
 	.file	"crt0_rom.S"
 
 	/* CPU Reset entry */
-SYMBOL_NAME_LABEL(_start)
+__start:
 	mov.l	#__ramend,sp
 	ldc	#0x80,ccr
 	ldc	#0,exr
@@ -82,13 +82,13 @@ SYMBOL_NAME_LABEL(_start)
 
 	/* copy kernel commandline */
 	mov.l	#COMMAND_START,er5
-	mov.l	#SYMBOL_NAME(_command_line),er6
+	mov.l	#__command_line,er6
 	mov.w	#512,r4
 	eepmov.w
 
 	/* linux kernel start */
 	ldc	#0x90,ccr	/* running kernel */
-	mov.l	#SYMBOL_NAME(init_thread_union),sp
+	mov.l	#_init_thread_union,sp
 	add.l	#0x2000,sp
 	jsr	@_start_kernel
 _exit:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/platform/h8s/generic/crt0_ram.S linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8s/generic/crt0_ram.S
--- linux-libre-3.10-gnu/arch/h8300/platform/h8s/generic/crt0_ram.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8s/generic/crt0_ram.S	2013-08-25 20:43:22.000000000 -0400
@@ -23,10 +23,10 @@
 #define RAMEND CONFIG_BLKDEV_RESERVE_ADDRESS
 #endif
 	
-	.global SYMBOL_NAME(_start)
-	.global SYMBOL_NAME(_command_line)
-	.global SYMBOL_NAME(_platform_gpio_table)
-	.global SYMBOL_NAME(_target_name)
+	.global __start
+	.global __command_line
+	.global __platform_gpio_table
+	.global __target_name
 	
 	.h8300s
 
@@ -34,7 +34,7 @@
 	.file	"crt0_ram.S"
 
 	/* CPU Reset entry */
-SYMBOL_NAME_LABEL(_start)
+__start:
 	mov.l	#RAMEND,sp
 	ldc	#0x80,ccr
 	ldc	#0x00,exr
@@ -63,13 +63,13 @@ SYMBOL_NAME_LABEL(_start)
 
 	/* copy kernel commandline */
 	mov.l	#COMMAND_START,er5
-	mov.l	#SYMBOL_NAME(command_line),er6
+	mov.l	#_command_line,er6
 	mov.w	#512,r4
 	eepmov.w
 
 	/* uClinux kernel start */
 	ldc	#0x90,ccr	/* running kernel */
-	mov.l	#SYMBOL_NAME(init_thread_union),sp
+	mov.l	#_init_thread_union,sp
 	add.l	#0x2000,sp
 	jsr	@_start_kernel
 _exit:
@@ -124,4 +124,4 @@ __target_name:
 	.asciz	"generic"
 	
 	.section .bootvec,"ax"
-	jmp	@SYMBOL_NAME(_start)
+	jmp	@__start
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/h8300/platform/h8s/generic/crt0_rom.S linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8s/generic/crt0_rom.S
--- linux-libre-3.10-gnu/arch/h8300/platform/h8s/generic/crt0_rom.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/h8300/platform/h8s/generic/crt0_rom.S	2013-08-25 20:43:22.000000000 -0400
@@ -13,17 +13,17 @@
 #include <asm/linkage.h>
 #include <asm/regs267x.h>
 	
-	.global SYMBOL_NAME(_start)
-	.global SYMBOL_NAME(_command_line)
-	.global SYMBOL_NAME(_platform_gpio_table)
-	.global SYMBOL_NAME(_target_name)
+	.global __start
+	.global __command_line
+	.global __platform_gpio_table
+	.global __target_name
 	
 	.h8300s
 	.section .text
 	.file	"crt0_rom.S"
 
 	/* CPU Reset entry */
-SYMBOL_NAME_LABEL(_start)
+__start:
 	mov.l	#__ramend,sp
 	ldc	#0x80,ccr
 	ldc	#0,exr
@@ -61,7 +61,7 @@ SYMBOL_NAME_LABEL(_start)
 
 	/* linux kernel start */
 	ldc	#0x90,ccr	/* running kernel */
-	mov.l	#SYMBOL_NAME(init_thread_union),sp
+	mov.l	#_init_thread_union,sp
 	add.l	#0x2000,sp
 	jsr	@_start_kernel
 _exit:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/hexagon/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/hexagon/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/hexagon/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/hexagon/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -452,10 +452,6 @@ static inline int pte_exec(pte_t pte)
 
 #define __pte_offset(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
 
-/* Nothing special about IO remapping at this point */
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
-	remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 /*  I think this is in case we have page table caches; needed by init/main.c  */
 #define pgtable_cache_init()    do { } while (0)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/hexagon/Kconfig linux-libre-3.11-rc7-gnu/arch/hexagon/Kconfig
--- linux-libre-3.10-gnu/arch/hexagon/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/hexagon/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -158,6 +158,7 @@ source "kernel/Kconfig.hz"
 endmenu
 
 source "init/Kconfig"
+source "kernel/Kconfig.freezer"
 source "drivers/Kconfig"
 source "fs/Kconfig"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/hexagon/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/hexagon/kernel/setup.c
--- linux-libre-3.10-gnu/arch/hexagon/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/hexagon/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,7 +41,7 @@ static char default_command_line[COMMAND
 
 int on_simulator;
 
-void __cpuinit calibrate_delay(void)
+void calibrate_delay(void)
 {
 	loops_per_jiffy = thread_freq_mhz * 1000000 / HZ;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/hexagon/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/hexagon/kernel/smp.c
--- linux-libre-3.10-gnu/arch/hexagon/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/hexagon/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -146,7 +146,7 @@ void __init smp_prepare_boot_cpu(void)
  * to point to current thread info
  */
 
-void __cpuinit start_secondary(void)
+void start_secondary(void)
 {
 	unsigned int cpu;
 	unsigned long thread_ptr;
@@ -194,7 +194,7 @@ void __cpuinit start_secondary(void)
  * maintains control until "cpu_online(cpu)" is set.
  */
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
+int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	struct thread_info *thread = (struct thread_info *)idle->stack;
 	void *stack_start;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/hexagon/mm/init.c linux-libre-3.11-rc7-gnu/arch/hexagon/mm/init.c
--- linux-libre-3.10-gnu/arch/hexagon/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/hexagon/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -70,10 +70,8 @@ unsigned long long kmap_generation;
 void __init mem_init(void)
 {
 	/*  No idea where this is actually declared.  Seems to evade LXR.  */
-	totalram_pages += free_all_bootmem();
-	num_physpages = bootmem_lastpg-ARCH_PFN_OFFSET;
-
-	printk(KERN_INFO "totalram_pages = %ld\n", totalram_pages);
+	free_all_bootmem();
+	mem_init_print_info(NULL);
 
 	/*
 	 *  To-Do:  someone somewhere should wipe out the bootmem map
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/configs/generic_defconfig linux-libre-3.11-rc7-gnu/arch/ia64/configs/generic_defconfig
--- linux-libre-3.10-gnu/arch/ia64/configs/generic_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/configs/generic_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,7 @@ CONFIG_ACPI_FAN=m
 CONFIG_ACPI_DOCK=y
 CONFIG_ACPI_PROCESSOR=m
 CONFIG_ACPI_CONTAINER=m
-CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_ACPI=m
 CONFIG_PACKET=y
 CONFIG_UNIX=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/configs/gensparse_defconfig linux-libre-3.11-rc7-gnu/arch/ia64/configs/gensparse_defconfig
--- linux-libre-3.10-gnu/arch/ia64/configs/gensparse_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/configs/gensparse_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@ CONFIG_ACPI_BUTTON=m
 CONFIG_ACPI_FAN=m
 CONFIG_ACPI_PROCESSOR=m
 CONFIG_ACPI_CONTAINER=m
-CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_ACPI=m
 CONFIG_PACKET=y
 CONFIG_UNIX=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/configs/tiger_defconfig linux-libre-3.11-rc7-gnu/arch/ia64/configs/tiger_defconfig
--- linux-libre-3.10-gnu/arch/ia64/configs/tiger_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/configs/tiger_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,7 @@ CONFIG_ACPI_BUTTON=m
 CONFIG_ACPI_FAN=m
 CONFIG_ACPI_PROCESSOR=m
 CONFIG_ACPI_CONTAINER=m
-CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_ACPI=m
 CONFIG_PACKET=y
 CONFIG_UNIX=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/configs/xen_domu_defconfig linux-libre-3.11-rc7-gnu/arch/ia64/configs/xen_domu_defconfig
--- linux-libre-3.10-gnu/arch/ia64/configs/xen_domu_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/configs/xen_domu_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,7 @@ CONFIG_ACPI_BUTTON=m
 CONFIG_ACPI_FAN=m
 CONFIG_ACPI_PROCESSOR=m
 CONFIG_ACPI_CONTAINER=m
-CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_ACPI=m
 CONFIG_PACKET=y
 CONFIG_UNIX=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/hp/common/sba_iommu.c linux-libre-3.11-rc7-gnu/arch/ia64/hp/common/sba_iommu.c
--- linux-libre-3.10-gnu/arch/ia64/hp/common/sba_iommu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/hp/common/sba_iommu.c	2013-08-25 20:43:22.000000000 -0400
@@ -2042,7 +2042,8 @@ sba_map_ioc_to_node(struct ioc *ioc, acp
 #endif
 
 static int __init
-acpi_sba_ioc_add(struct acpi_device *device)
+acpi_sba_ioc_add(struct acpi_device *device,
+		 const struct acpi_device_id *not_used)
 {
 	struct ioc *ioc;
 	acpi_status status;
@@ -2090,14 +2091,18 @@ static const struct acpi_device_id hp_io
 	{"HWP0004", 0},
 	{"", 0},
 };
-static struct acpi_driver acpi_sba_ioc_driver = {
-	.name		= "IOC IOMMU Driver",
-	.ids		= hp_ioc_iommu_device_ids,
-	.ops		= {
-		.add	= acpi_sba_ioc_add,
-	},
+static struct acpi_scan_handler acpi_sba_ioc_handler = {
+	.ids	= hp_ioc_iommu_device_ids,
+	.attach	= acpi_sba_ioc_add,
 };
 
+static int __init acpi_sba_ioc_init_acpi(void)
+{
+	return acpi_scan_add_handler(&acpi_sba_ioc_handler);
+}
+/* This has to run before acpi_scan_init(). */
+arch_initcall(acpi_sba_ioc_init_acpi);
+
 extern struct dma_map_ops swiotlb_dma_ops;
 
 static int __init
@@ -2122,7 +2127,10 @@ sba_init(void)
 	}
 #endif
 
-	acpi_bus_register_driver(&acpi_sba_ioc_driver);
+	/*
+	 * ioc_list should be populated by the acpi_sba_ioc_handler's .attach()
+	 * routine, but that only happens if acpi_scan_init() has already run.
+	 */
 	if (!ioc_list) {
 #ifdef CONFIG_IA64_GENERIC
 		/*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/hp/sim/boot/fw-emu.c linux-libre-3.11-rc7-gnu/arch/ia64/hp/sim/boot/fw-emu.c
--- linux-libre-3.10-gnu/arch/ia64/hp/sim/boot/fw-emu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/hp/sim/boot/fw-emu.c	2013-08-25 20:43:22.000000000 -0400
@@ -290,16 +290,16 @@ sys_fw_init (const char *args, int argle
 	efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
 	efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
 	efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
-	efi_runtime->get_time = __pa(&fw_efi_get_time);
-	efi_runtime->set_time = __pa(&efi_unimplemented);
-	efi_runtime->get_wakeup_time = __pa(&efi_unimplemented);
-	efi_runtime->set_wakeup_time = __pa(&efi_unimplemented);
-	efi_runtime->set_virtual_address_map = __pa(&efi_unimplemented);
-	efi_runtime->get_variable = __pa(&efi_unimplemented);
-	efi_runtime->get_next_variable = __pa(&efi_unimplemented);
-	efi_runtime->set_variable = __pa(&efi_unimplemented);
-	efi_runtime->get_next_high_mono_count = __pa(&efi_unimplemented);
-	efi_runtime->reset_system = __pa(&efi_reset_system);
+	efi_runtime->get_time = (void *)__pa(&fw_efi_get_time);
+	efi_runtime->set_time = (void *)__pa(&efi_unimplemented);
+	efi_runtime->get_wakeup_time = (void *)__pa(&efi_unimplemented);
+	efi_runtime->set_wakeup_time = (void *)__pa(&efi_unimplemented);
+	efi_runtime->set_virtual_address_map = (void *)__pa(&efi_unimplemented);
+	efi_runtime->get_variable = (void *)__pa(&efi_unimplemented);
+	efi_runtime->get_next_variable = (void *)__pa(&efi_unimplemented);
+	efi_runtime->set_variable = (void *)__pa(&efi_unimplemented);
+	efi_runtime->get_next_high_mono_count = (void *)__pa(&efi_unimplemented);
+	efi_runtime->reset_system = (void *)__pa(&efi_reset_system);
 
 	efi_tables->guid = SAL_SYSTEM_TABLE_GUID;
 	efi_tables->table = __pa(sal_systab);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/hp/sim/simeth.c linux-libre-3.11-rc7-gnu/arch/ia64/hp/sim/simeth.c
--- linux-libre-3.10-gnu/arch/ia64/hp/sim/simeth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/hp/sim/simeth.c	2013-08-25 20:43:22.000000000 -0400
@@ -268,7 +268,7 @@ static __inline__ int dev_is_ethdev(stru
 static int
 simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct simeth_local *local;
 	struct in_device *in_dev;
 	struct in_ifaddr **ifap = NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/hp/sim/simscsi.c linux-libre-3.11-rc7-gnu/arch/ia64/hp/sim/simscsi.c
--- linux-libre-3.10-gnu/arch/ia64/hp/sim/simscsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/hp/sim/simscsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,8 +88,8 @@ simscsi_setup (char *s)
 	if (strlen(s) > MAX_ROOT_LEN) {
 		printk(KERN_ERR "simscsi_setup: prefix too long---using default %s\n",
 		       simscsi_root);
-	}
-	simscsi_root = s;
+	} else
+		simscsi_root = s;
 	return 1;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/include/asm/mutex.h linux-libre-3.11-rc7-gnu/arch/ia64/include/asm/mutex.h
--- linux-libre-3.10-gnu/arch/ia64/include/asm/mutex.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/include/asm/mutex.h	2013-08-25 20:43:22.000000000 -0400
@@ -29,17 +29,15 @@ __mutex_fastpath_lock(atomic_t *count, v
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns.
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
 static inline int
-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+__mutex_fastpath_lock_retval(atomic_t *count)
 {
 	if (unlikely(ia64_fetchadd4_acq(count, -1) != 1))
-		return fail_fn(count);
+		return -1;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/include/asm/pci.h linux-libre-3.11-rc7-gnu/arch/ia64/include/asm/pci.h
--- linux-libre-3.10-gnu/arch/ia64/include/asm/pci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/include/asm/pci.h	2013-08-25 20:43:22.000000000 -0400
@@ -89,9 +89,9 @@ extern int pci_mmap_legacy_page_range(st
 #define pci_legacy_read platform_pci_legacy_read
 #define pci_legacy_write platform_pci_legacy_write
 
-struct pci_window {
-	struct resource resource;
-	u64 offset;
+struct iospace_resource {
+	struct list_head list;
+	struct resource res;
 };
 
 struct pci_controller {
@@ -100,12 +100,10 @@ struct pci_controller {
 	int segment;
 	int node;		/* nearest node with memory or -1 for global allocation */
 
-	unsigned int windows;
-	struct pci_window *window;
-
 	void *platform_data;
 };
 
+
 #define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
 #define pci_domain_nr(busdev)    (PCI_CONTROLLER(busdev)->segment)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/ia64/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/ia64/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -493,9 +493,6 @@ extern void paging_init (void);
 #define pte_to_pgoff(pte)		((pte_val(pte) << 1) >> 3)
 #define pgoff_to_pte(off)		((pte_t) { ((off) << 2) | _PAGE_FILE })
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/include/asm/tlb.h linux-libre-3.11-rc7-gnu/arch/ia64/include/asm/tlb.h
--- linux-libre-3.10-gnu/arch/ia64/include/asm/tlb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/include/asm/tlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,7 @@
  * unmapping a portion of the virtual address space, these hooks are called according to
  * the following template:
  *
- *	tlb <- tlb_gather_mmu(mm, full_mm_flush);	// start unmap for address space MM
+ *	tlb <- tlb_gather_mmu(mm, start, end);		// start unmap for address space MM
  *	{
  *	  for each vma that needs a shootdown do {
  *	    tlb_start_vma(tlb, vma);
@@ -58,6 +58,7 @@ struct mmu_gather {
 	unsigned int		max;
 	unsigned char		fullmm;		/* non-zero means full mm flush */
 	unsigned char		need_flush;	/* really unmapped some PTEs? */
+	unsigned long		start, end;
 	unsigned long		start_addr;
 	unsigned long		end_addr;
 	struct page		**pages;
@@ -155,13 +156,15 @@ static inline void __tlb_alloc_page(stru
 
 
 static inline void
-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
 {
 	tlb->mm = mm;
 	tlb->max = ARRAY_SIZE(tlb->local);
 	tlb->pages = tlb->local;
 	tlb->nr = 0;
-	tlb->fullmm = full_mm_flush;
+	tlb->fullmm = !(start | (end+1));
+	tlb->start = start;
+	tlb->end = end;
 	tlb->start_addr = ~0UL;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/ia64/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/ia64/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -83,4 +83,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif /* _ASM_IA64_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/Kconfig linux-libre-3.11-rc7-gnu/arch/ia64/Kconfig
--- linux-libre-3.10-gnu/arch/ia64/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -376,7 +376,6 @@ config NR_CPUS
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
 	depends on SMP
-	select HOTPLUG
 	default n
 	---help---
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/acpi.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/acpi.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/acpi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/acpi.c	2013-08-25 20:43:22.000000000 -0400
@@ -807,7 +807,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq
  *  ACPI based hotplug CPU support
  */
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
-static __cpuinit
+static
 int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
 {
 #ifdef CONFIG_ACPI_NUMA
@@ -882,7 +882,7 @@ __init void prefill_possible_map(void)
 		set_cpu_possible(i, true);
 }
 
-static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
+static int _acpi_map_lsapic(acpi_handle handle, int *pcpu)
 {
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	union acpi_object *obj;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/efi.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/efi.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/efi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/efi.c	2013-08-25 20:43:22.000000000 -0400
@@ -1116,11 +1116,6 @@ efi_memmap_init(u64 *s, u64 *e)
 		if (!is_memory_available(md))
 			continue;
 
-#ifdef CONFIG_CRASH_DUMP
-		/* saved_max_pfn should ignore max_addr= command line arg */
-		if (saved_max_pfn < (efi_md_end(md) >> PAGE_SHIFT))
-			saved_max_pfn = (efi_md_end(md) >> PAGE_SHIFT);
-#endif
 		/*
 		 * Round ends inward to granule boundaries
 		 * Give trimmings to uncached allocator
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/err_inject.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/err_inject.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/err_inject.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/err_inject.c	2013-08-25 20:43:22.000000000 -0400
@@ -225,17 +225,17 @@ static struct attribute_group err_inject
 	.name = "err_inject"
 };
 /* Add/Remove err_inject interface for CPU device */
-static int __cpuinit err_inject_add_dev(struct device * sys_dev)
+static int err_inject_add_dev(struct device *sys_dev)
 {
 	return sysfs_create_group(&sys_dev->kobj, &err_inject_attr_group);
 }
 
-static int __cpuinit err_inject_remove_dev(struct device * sys_dev)
+static int err_inject_remove_dev(struct device *sys_dev)
 {
 	sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group);
 	return 0;
 }
-static int __cpuinit err_inject_cpu_callback(struct notifier_block *nfb,
+static int err_inject_cpu_callback(struct notifier_block *nfb,
 		unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
@@ -256,7 +256,7 @@ static int __cpuinit err_inject_cpu_call
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata err_inject_cpu_notifier =
+static struct notifier_block err_inject_cpu_notifier =
 {
 	.notifier_call = err_inject_cpu_callback,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/head.S linux-libre-3.11-rc7-gnu/arch/ia64/kernel/head.S
--- linux-libre-3.10-gnu/arch/ia64/kernel/head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/head.S	2013-08-25 20:43:22.000000000 -0400
@@ -1035,7 +1035,7 @@ END(ia64_delay_loop)
  * Return a CPU-local timestamp in nano-seconds.  This timestamp is
  * NOT synchronized across CPUs its return value must never be
  * compared against the values returned on another CPU.  The usage in
- * kernel/sched.c ensures that.
+ * kernel/sched/core.c ensures that.
  *
  * The return-value of sched_clock() is NOT supposed to wrap-around.
  * If it did, it would cause some scheduling hiccups (at the worst).
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/mca.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/mca.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/mca.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/mca.c	2013-08-25 20:43:22.000000000 -0400
@@ -631,7 +631,7 @@ ia64_mca_register_cpev (int cpev)
  * Outputs
  *	None
  */
-void __cpuinit
+void
 ia64_mca_cmc_vector_setup (void)
 {
 	cmcv_reg_t	cmcv;
@@ -1814,7 +1814,7 @@ static struct irqaction mca_cpep_irqacti
  * format most of the fields.
  */
 
-static void __cpuinit
+static void
 format_mca_init_stack(void *mca_data, unsigned long offset,
 		const char *type, int cpu)
 {
@@ -1844,7 +1844,7 @@ static void * __init_refok mca_bootmem(v
 }
 
 /* Do per-CPU MCA-related initialization.  */
-void __cpuinit
+void
 ia64_mca_cpu_init(void *cpu_data)
 {
 	void *pal_vaddr;
@@ -1896,7 +1896,7 @@ ia64_mca_cpu_init(void *cpu_data)
 							      PAGE_KERNEL));
 }
 
-static void __cpuinit ia64_mca_cmc_vector_adjust(void *dummy)
+static void ia64_mca_cmc_vector_adjust(void *dummy)
 {
 	unsigned long flags;
 
@@ -1906,7 +1906,7 @@ static void __cpuinit ia64_mca_cmc_vecto
 	local_irq_restore(flags);
 }
 
-static int __cpuinit mca_cpu_callback(struct notifier_block *nfb,
+static int mca_cpu_callback(struct notifier_block *nfb,
 				      unsigned long action,
 				      void *hcpu)
 {
@@ -1922,7 +1922,7 @@ static int __cpuinit mca_cpu_callback(st
 	return NOTIFY_OK;
 }
 
-static struct notifier_block mca_cpu_notifier __cpuinitdata = {
+static struct notifier_block mca_cpu_notifier = {
 	.notifier_call = mca_cpu_callback
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/numa.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/numa.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/numa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/numa.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,7 @@ EXPORT_SYMBOL(cpu_to_node_map);
 cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
 EXPORT_SYMBOL(node_to_cpu_mask);
 
-void __cpuinit map_cpu_to_node(int cpu, int nid)
+void map_cpu_to_node(int cpu, int nid)
 {
 	int oldnid;
 	if (nid < 0) { /* just initialize by zero */
@@ -51,7 +51,7 @@ void __cpuinit map_cpu_to_node(int cpu,
 	return;
 }
 
-void __cpuinit unmap_cpu_from_node(int cpu, int nid)
+void unmap_cpu_from_node(int cpu, int nid)
 {
 	WARN_ON(!cpu_isset(cpu, node_to_cpu_mask[nid]));
 	WARN_ON(cpu_to_node_map[cpu] != nid);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/palinfo.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/palinfo.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/palinfo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/palinfo.c	2013-08-25 20:43:22.000000000 -0400
@@ -932,7 +932,7 @@ static const struct file_operations proc
 	.release	= single_release,
 };
 
-static void __cpuinit
+static void
 create_palinfo_proc_entries(unsigned int cpu)
 {
 	pal_func_cpu_u_t f;
@@ -962,7 +962,7 @@ remove_palinfo_proc_entries(unsigned int
 	remove_proc_subtree(cpustr, palinfo_dir);
 }
 
-static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb,
+static int palinfo_cpu_callback(struct notifier_block *nfb,
 					unsigned long action, void *hcpu)
 {
 	unsigned int hotcpu = (unsigned long)hcpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/pci-dma.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/pci-dma.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/pci-dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/pci-dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,15 +33,6 @@ int force_iommu __read_mostly;
 
 int iommu_pass_through;
 
-/* Dummy device used for NULL arguments (normally ISA). Better would
-   be probably a smaller DMA mask, but this is bug-to-bug compatible
-   to i386. */
-struct device fallback_dev = {
-	.init_name = "fallback device",
-	.coherent_dma_mask = DMA_BIT_MASK(32),
-	.dma_mask = &fallback_dev.coherent_dma_mask,
-};
-
 extern struct dma_map_ops intel_dma_ops;
 
 static int __init pci_iommu_init(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/perfmon.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/perfmon.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/perfmon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/perfmon.c	2013-08-25 20:43:22.000000000 -0400
@@ -5647,24 +5647,8 @@ pfm_proc_show_header(struct seq_file *m)
 
 	list_for_each(pos, &pfm_buffer_fmt_list) {
 		entry = list_entry(pos, pfm_buffer_fmt_t, fmt_list);
-		seq_printf(m, "format                    : %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x %s\n",
-			entry->fmt_uuid[0],
-			entry->fmt_uuid[1],
-			entry->fmt_uuid[2],
-			entry->fmt_uuid[3],
-			entry->fmt_uuid[4],
-			entry->fmt_uuid[5],
-			entry->fmt_uuid[6],
-			entry->fmt_uuid[7],
-			entry->fmt_uuid[8],
-			entry->fmt_uuid[9],
-			entry->fmt_uuid[10],
-			entry->fmt_uuid[11],
-			entry->fmt_uuid[12],
-			entry->fmt_uuid[13],
-			entry->fmt_uuid[14],
-			entry->fmt_uuid[15],
-			entry->fmt_name);
+		seq_printf(m, "format                    : %16phD %s\n",
+			   entry->fmt_uuid, entry->fmt_name);
 	}
 	spin_unlock(&pfm_buffer_fmt_lock);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/salinfo.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/salinfo.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/salinfo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/salinfo.c	2013-08-25 20:43:22.000000000 -0400
@@ -568,7 +568,7 @@ static const struct file_operations sali
 	.llseek  = default_llseek,
 };
 
-static int __cpuinit
+static int
 salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
 {
 	unsigned int i, cpu = (unsigned long)hcpu;
@@ -609,7 +609,7 @@ salinfo_cpu_callback(struct notifier_blo
 	return NOTIFY_OK;
 }
 
-static struct notifier_block salinfo_cpu_notifier __cpuinitdata =
+static struct notifier_block salinfo_cpu_notifier =
 {
 	.notifier_call = salinfo_cpu_callback,
 	.priority = 0,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/setup.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -748,7 +748,7 @@ const struct seq_operations cpuinfo_op =
 #define MAX_BRANDS	8
 static char brandname[MAX_BRANDS][128];
 
-static char * __cpuinit
+static char *
 get_model_name(__u8 family, __u8 model)
 {
 	static int overflow;
@@ -778,7 +778,7 @@ get_model_name(__u8 family, __u8 model)
 	return "Unknown";
 }
 
-static void __cpuinit
+static void
 identify_cpu (struct cpuinfo_ia64 *c)
 {
 	union {
@@ -850,7 +850,7 @@ identify_cpu (struct cpuinfo_ia64 *c)
  * 2. the minimum of the i-cache stride sizes for "flush_icache_range()".
  * 3. the minimum of the cache stride sizes for "clflush_cache_range()".
  */
-static void __cpuinit
+static void
 get_cache_info(void)
 {
 	unsigned long line_size, max = 1;
@@ -915,10 +915,10 @@ get_cache_info(void)
  * cpu_init() initializes state that is per-CPU.  This function acts
  * as a 'CPU state barrier', nothing should get across.
  */
-void __cpuinit
+void
 cpu_init (void)
 {
-	extern void __cpuinit ia64_mmu_init (void *);
+	extern void ia64_mmu_init(void *);
 	static unsigned long max_num_phys_stacked = IA64_NUM_PHYS_STACK_REG;
 	unsigned long num_phys_stacked;
 	pal_vm_info_2_u_t vmi;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/smpboot.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/smpboot.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/smpboot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/smpboot.c	2013-08-25 20:43:22.000000000 -0400
@@ -351,7 +351,7 @@ static inline void smp_setup_percpu_time
 {
 }
 
-static void __cpuinit
+static void
 smp_callin (void)
 {
 	int cpuid, phys_id, itc_master;
@@ -442,7 +442,7 @@ smp_callin (void)
 /*
  * Activate a secondary processor.  head.S calls this.
  */
-int __cpuinit
+int
 start_secondary (void *unused)
 {
 	/* Early console may use I/O ports */
@@ -459,7 +459,7 @@ start_secondary (void *unused)
 	return 0;
 }
 
-static int __cpuinit
+static int
 do_boot_cpu (int sapicid, int cpu, struct task_struct *idle)
 {
 	int timeout;
@@ -728,7 +728,7 @@ static inline void set_cpu_sibling_map(i
 	}
 }
 
-int __cpuinit
+int
 __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/topology.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/topology.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/topology.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/topology.c	2013-08-25 20:43:22.000000000 -0400
@@ -135,11 +135,11 @@ struct cpu_cache_info {
 	struct kobject kobj;
 };
 
-static struct cpu_cache_info	all_cpu_cache_info[NR_CPUS] __cpuinitdata;
+static struct cpu_cache_info	all_cpu_cache_info[NR_CPUS];
 #define LEAF_KOBJECT_PTR(x,y)    (&all_cpu_cache_info[x].cache_leaves[y])
 
 #ifdef CONFIG_SMP
-static void __cpuinit cache_shared_cpu_map_setup( unsigned int cpu,
+static void cache_shared_cpu_map_setup(unsigned int cpu,
 		struct cache_info * this_leaf)
 {
 	pal_cache_shared_info_t	csi;
@@ -174,7 +174,7 @@ static void __cpuinit cache_shared_cpu_m
 				&csi) == PAL_STATUS_SUCCESS);
 }
 #else
-static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu,
+static void cache_shared_cpu_map_setup(unsigned int cpu,
 		struct cache_info * this_leaf)
 {
 	cpu_set(cpu, this_leaf->shared_cpu_map);
@@ -298,7 +298,7 @@ static struct kobj_type cache_ktype_perc
 	.sysfs_ops	= &cache_sysfs_ops,
 };
 
-static void __cpuinit cpu_cache_sysfs_exit(unsigned int cpu)
+static void cpu_cache_sysfs_exit(unsigned int cpu)
 {
 	kfree(all_cpu_cache_info[cpu].cache_leaves);
 	all_cpu_cache_info[cpu].cache_leaves = NULL;
@@ -307,7 +307,7 @@ static void __cpuinit cpu_cache_sysfs_ex
 	return;
 }
 
-static int __cpuinit cpu_cache_sysfs_init(unsigned int cpu)
+static int cpu_cache_sysfs_init(unsigned int cpu)
 {
 	unsigned long i, levels, unique_caches;
 	pal_cache_config_info_t cci;
@@ -351,7 +351,7 @@ static int __cpuinit cpu_cache_sysfs_ini
 }
 
 /* Add cache interface for CPU device */
-static int __cpuinit cache_add_dev(struct device * sys_dev)
+static int cache_add_dev(struct device *sys_dev)
 {
 	unsigned int cpu = sys_dev->id;
 	unsigned long i, j;
@@ -401,7 +401,7 @@ static int __cpuinit cache_add_dev(struc
 }
 
 /* Remove cache interface for CPU device */
-static int __cpuinit cache_remove_dev(struct device * sys_dev)
+static int cache_remove_dev(struct device *sys_dev)
 {
 	unsigned int cpu = sys_dev->id;
 	unsigned long i;
@@ -425,7 +425,7 @@ static int __cpuinit cache_remove_dev(st
  * When a cpu is hot-plugged, do a check and initiate
  * cache kobject if necessary
  */
-static int __cpuinit cache_cpu_callback(struct notifier_block *nfb,
+static int cache_cpu_callback(struct notifier_block *nfb,
 		unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
@@ -445,7 +445,7 @@ static int __cpuinit cache_cpu_callback(
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata cache_cpu_notifier =
+static struct notifier_block cache_cpu_notifier =
 {
 	.notifier_call = cache_cpu_callback
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/ia64/kernel/traps.c
--- linux-libre-3.10-gnu/arch/ia64/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -630,7 +630,7 @@ ia64_fault (unsigned long vector, unsign
 		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
 		       iip, ifa, isr);
 		force_sig(SIGSEGV, current);
-		break;
+		return;
 
 	      case 46:
 		printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/kvm/Makefile linux-libre-3.11-rc7-gnu/arch/ia64/kvm/Makefile
--- linux-libre-3.10-gnu/arch/ia64/kvm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/kvm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -47,12 +47,13 @@ FORCE : $(obj)/$(offsets-file)
 
 ccflags-y := -Ivirt/kvm -Iarch/ia64/kvm/
 asflags-y := -Ivirt/kvm -Iarch/ia64/kvm/
+KVM := ../../../virt/kvm
 
-common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
-		coalesced_mmio.o irq_comm.o)
+common-objs = $(KVM)/kvm_main.o $(KVM)/ioapic.o \
+		$(KVM)/coalesced_mmio.o $(KVM)/irq_comm.o
 
 ifeq ($(CONFIG_KVM_DEVICE_ASSIGNMENT),y)
-common-objs += $(addprefix ../../../virt/kvm/, assigned-dev.o iommu.o)
+common-objs += $(KVM)/assigned-dev.o $(KVM)/iommu.o
 endif
 
 kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/mm/contig.c linux-libre-3.11-rc7-gnu/arch/ia64/mm/contig.c
--- linux-libre-3.10-gnu/arch/ia64/mm/contig.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/mm/contig.c	2013-08-25 20:43:22.000000000 -0400
@@ -156,8 +156,7 @@ static void *cpu_data;
  *
  * Allocate and setup per-cpu data areas.
  */
-void * __cpuinit
-per_cpu_init (void)
+void *per_cpu_init(void)
 {
 	static bool first_time = true;
 	void *cpu0_data = __cpu0_per_cpu;
@@ -295,14 +294,6 @@ find_memory (void)
 	alloc_per_cpu_data();
 }
 
-static int count_pages(u64 start, u64 end, void *arg)
-{
-	unsigned long *count = arg;
-
-	*count += (end - start) >> PAGE_SHIFT;
-	return 0;
-}
-
 /*
  * Set up the page tables.
  */
@@ -313,9 +304,6 @@ paging_init (void)
 	unsigned long max_dma;
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
 
-	num_physpages = 0;
-	efi_memmap_walk(count_pages, &num_physpages);
-
 	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
 #ifdef CONFIG_ZONE_DMA
 	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/mm/discontig.c linux-libre-3.11-rc7-gnu/arch/ia64/mm/discontig.c
--- linux-libre-3.10-gnu/arch/ia64/mm/discontig.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/mm/discontig.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,6 @@ struct early_node_data {
 	struct ia64_node_data *node_data;
 	unsigned long pernode_addr;
 	unsigned long pernode_size;
-	unsigned long num_physpages;
 #ifdef CONFIG_ZONE_DMA
 	unsigned long num_dma_physpages;
 #endif
@@ -593,7 +592,7 @@ void __init find_memory(void)
  * find_pernode_space() does most of this already, we just need to set
  * local_per_cpu_offset
  */
-void __cpuinit *per_cpu_init(void)
+void *per_cpu_init(void)
 {
 	int cpu;
 	static int first_time = 1;
@@ -732,7 +731,6 @@ static __init int count_node_pages(unsig
 {
 	unsigned long end = start + len;
 
-	mem_data[node].num_physpages += len >> PAGE_SHIFT;
 #ifdef CONFIG_ZONE_DMA
 	if (start <= __pa(MAX_DMA_ADDRESS))
 		mem_data[node].num_dma_physpages +=
@@ -778,7 +776,6 @@ void __init paging_init(void)
 #endif
 
 	for_each_online_node(node) {
-		num_physpages += mem_data[node].num_physpages;
 		pfn_offset = mem_data[node].min_pfn;
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/mm/init.c linux-libre-3.11-rc7-gnu/arch/ia64/mm/init.c
--- linux-libre-3.10-gnu/arch/ia64/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -154,9 +154,8 @@ ia64_init_addr_space (void)
 void
 free_initmem (void)
 {
-	free_reserved_area((unsigned long)ia64_imva(__init_begin),
-			   (unsigned long)ia64_imva(__init_end),
-			   0, "unused kernel");
+	free_reserved_area(ia64_imva(__init_begin), ia64_imva(__init_end),
+			   -1, "unused kernel");
 }
 
 void __init
@@ -546,19 +545,6 @@ int __init register_active_ranges(u64 st
 	return 0;
 }
 
-static int __init
-count_reserved_pages(u64 start, u64 end, void *arg)
-{
-	unsigned long num_reserved = 0;
-	unsigned long *count = arg;
-
-	for (; start < end; start += PAGE_SIZE)
-		if (PageReserved(virt_to_page(start)))
-			++num_reserved;
-	*count += num_reserved;
-	return 0;
-}
-
 int
 find_max_min_low_pfn (u64 start, u64 end, void *arg)
 {
@@ -597,8 +583,6 @@ __setup("nolwsys", nolwsys_setup);
 void __init
 mem_init (void)
 {
-	long reserved_pages, codesize, datasize, initsize;
-	pg_data_t *pgdat;
 	int i;
 
 	BUG_ON(PTRS_PER_PGD * sizeof(pgd_t) != PAGE_SIZE);
@@ -616,27 +600,12 @@ mem_init (void)
 
 #ifdef CONFIG_FLATMEM
 	BUG_ON(!mem_map);
-	max_mapnr = max_low_pfn;
 #endif
 
+	set_max_mapnr(max_low_pfn);
 	high_memory = __va(max_low_pfn * PAGE_SIZE);
-
-	for_each_online_pgdat(pgdat)
-		if (pgdat->bdata->node_bootmem_map)
-			totalram_pages += free_all_bootmem_node(pgdat);
-
-	reserved_pages = 0;
-	efi_memmap_walk(count_reserved_pages, &reserved_pages);
-
-	codesize =  (unsigned long) _etext - (unsigned long) _stext;
-	datasize =  (unsigned long) _edata - (unsigned long) _etext;
-	initsize =  (unsigned long) __init_end - (unsigned long) __init_begin;
-
-	printk(KERN_INFO "Memory: %luk/%luk available (%luk code, %luk reserved, "
-	       "%luk data, %luk init)\n", nr_free_pages() << (PAGE_SHIFT - 10),
-	       num_physpages << (PAGE_SHIFT - 10), codesize >> 10,
-	       reserved_pages << (PAGE_SHIFT - 10), datasize >> 10, initsize >> 10);
-
+	free_all_bootmem();
+	mem_init_print_info(NULL);
 
 	/*
 	 * For fsyscall entrpoints with no light-weight handler, use the ordinary
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/mm/numa.c linux-libre-3.11-rc7-gnu/arch/ia64/mm/numa.c
--- linux-libre-3.10-gnu/arch/ia64/mm/numa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/mm/numa.c	2013-08-25 20:43:22.000000000 -0400
@@ -86,7 +86,7 @@ int __meminit __early_pfn_to_nid(unsigne
 	return -1;
 }
 
-void __cpuinit numa_clear_node(int cpu)
+void numa_clear_node(int cpu)
 {
 	unmap_cpu_from_node(cpu, NUMA_NO_NODE);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/pci/pci.c linux-libre-3.11-rc7-gnu/arch/ia64/pci/pci.c
--- linux-libre-3.10-gnu/arch/ia64/pci/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/pci/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -134,6 +134,10 @@ struct pci_root_info {
 	struct acpi_device *bridge;
 	struct pci_controller *controller;
 	struct list_head resources;
+	struct resource *res;
+	resource_size_t *res_offset;
+	unsigned int res_num;
+	struct list_head io_resources;
 	char *name;
 };
 
@@ -153,7 +157,7 @@ new_space (u64 phys_base, int sparse)
 			return i;
 
 	if (num_io_spaces == MAX_IO_SPACES) {
-		printk(KERN_ERR "PCI: Too many IO port spaces "
+		pr_err("PCI: Too many IO port spaces "
 			"(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
 		return ~0;
 	}
@@ -168,25 +172,22 @@ new_space (u64 phys_base, int sparse)
 static u64 add_io_space(struct pci_root_info *info,
 			struct acpi_resource_address64 *addr)
 {
+	struct iospace_resource *iospace;
 	struct resource *resource;
 	char *name;
 	unsigned long base, min, max, base_port;
 	unsigned int sparse = 0, space_nr, len;
 
-	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
-	if (!resource) {
-		printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
-			info->name);
+	len = strlen(info->name) + 32;
+	iospace = kzalloc(sizeof(*iospace) + len, GFP_KERNEL);
+	if (!iospace) {
+		dev_err(&info->bridge->dev,
+				"PCI: No memory for %s I/O port space\n",
+				info->name);
 		goto out;
 	}
 
-	len = strlen(info->name) + 32;
-	name = kzalloc(len, GFP_KERNEL);
-	if (!name) {
-		printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
-			info->name);
-		goto free_resource;
-	}
+	name = (char *)(iospace + 1);
 
 	min = addr->minimum;
 	max = min + addr->address_length - 1;
@@ -195,7 +196,7 @@ static u64 add_io_space(struct pci_root_
 
 	space_nr = new_space(addr->translation_offset, sparse);
 	if (space_nr == ~0)
-		goto free_name;
+		goto free_resource;
 
 	base = __pa(io_space[space_nr].mmio_base);
 	base_port = IO_SPACE_BASE(space_nr);
@@ -210,18 +211,23 @@ static u64 add_io_space(struct pci_root_
 	if (space_nr == 0)
 		sparse = 1;
 
+	resource = &iospace->res;
 	resource->name  = name;
 	resource->flags = IORESOURCE_MEM;
 	resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
 	resource->end   = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
-	insert_resource(&iomem_resource, resource);
+	if (insert_resource(&iomem_resource, resource)) {
+		dev_err(&info->bridge->dev,
+				"can't allocate host bridge io space resource  %pR\n",
+				resource);
+		goto free_resource;
+	}
 
+	list_add_tail(&iospace->list, &info->io_resources);
 	return base_port;
 
-free_name:
-	kfree(name);
 free_resource:
-	kfree(resource);
+	kfree(iospace);
 out:
 	return ~0;
 }
@@ -265,7 +271,7 @@ static acpi_status count_window(struct a
 static acpi_status add_window(struct acpi_resource *res, void *data)
 {
 	struct pci_root_info *info = data;
-	struct pci_window *window;
+	struct resource *resource;
 	struct acpi_resource_address64 addr;
 	acpi_status status;
 	unsigned long flags, offset = 0;
@@ -289,55 +295,146 @@ static acpi_status add_window(struct acp
 	} else
 		return AE_OK;
 
-	window = &info->controller->window[info->controller->windows++];
-	window->resource.name = info->name;
-	window->resource.flags = flags;
-	window->resource.start = addr.minimum + offset;
-	window->resource.end = window->resource.start + addr.address_length - 1;
-	window->offset = offset;
+	resource = &info->res[info->res_num];
+	resource->name = info->name;
+	resource->flags = flags;
+	resource->start = addr.minimum + offset;
+	resource->end = resource->start + addr.address_length - 1;
+	info->res_offset[info->res_num] = offset;
 
-	if (insert_resource(root, &window->resource)) {
+	if (insert_resource(root, resource)) {
 		dev_err(&info->bridge->dev,
 			"can't allocate host bridge window %pR\n",
-			&window->resource);
+			resource);
 	} else {
 		if (offset)
 			dev_info(&info->bridge->dev, "host bridge window %pR "
 				 "(PCI address [%#llx-%#llx])\n",
-				 &window->resource,
-				 window->resource.start - offset,
-				 window->resource.end - offset);
+				 resource,
+				 resource->start - offset,
+				 resource->end - offset);
 		else
 			dev_info(&info->bridge->dev,
-				 "host bridge window %pR\n",
-				 &window->resource);
+				 "host bridge window %pR\n", resource);
 	}
-
 	/* HP's firmware has a hack to work around a Windows bug.
 	 * Ignore these tiny memory ranges */
-	if (!((window->resource.flags & IORESOURCE_MEM) &&
-	      (window->resource.end - window->resource.start < 16)))
-		pci_add_resource_offset(&info->resources, &window->resource,
-					window->offset);
+	if (!((resource->flags & IORESOURCE_MEM) &&
+	      (resource->end - resource->start < 16)))
+		pci_add_resource_offset(&info->resources, resource,
+					info->res_offset[info->res_num]);
 
+	info->res_num++;
 	return AE_OK;
 }
 
+static void free_pci_root_info_res(struct pci_root_info *info)
+{
+	struct iospace_resource *iospace, *tmp;
+
+	list_for_each_entry_safe(iospace, tmp, &info->io_resources, list)
+		kfree(iospace);
+
+	kfree(info->name);
+	kfree(info->res);
+	info->res = NULL;
+	kfree(info->res_offset);
+	info->res_offset = NULL;
+	info->res_num = 0;
+	kfree(info->controller);
+	info->controller = NULL;
+}
+
+static void __release_pci_root_info(struct pci_root_info *info)
+{
+	int i;
+	struct resource *res;
+	struct iospace_resource *iospace;
+
+	list_for_each_entry(iospace, &info->io_resources, list)
+		release_resource(&iospace->res);
+
+	for (i = 0; i < info->res_num; i++) {
+		res = &info->res[i];
+
+		if (!res->parent)
+			continue;
+
+		if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
+			continue;
+
+		release_resource(res);
+	}
+
+	free_pci_root_info_res(info);
+	kfree(info);
+}
+
+static void release_pci_root_info(struct pci_host_bridge *bridge)
+{
+	struct pci_root_info *info = bridge->release_data;
+
+	__release_pci_root_info(info);
+}
+
+static int
+probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
+		int busnum, int domain)
+{
+	char *name;
+
+	name = kmalloc(16, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+
+	sprintf(name, "PCI Bus %04x:%02x", domain, busnum);
+	info->bridge = device;
+	info->name = name;
+
+	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
+			&info->res_num);
+	if (info->res_num) {
+		info->res =
+			kzalloc_node(sizeof(*info->res) * info->res_num,
+				     GFP_KERNEL, info->controller->node);
+		if (!info->res) {
+			kfree(name);
+			return -ENOMEM;
+		}
+
+		info->res_offset =
+			kzalloc_node(sizeof(*info->res_offset) * info->res_num,
+					GFP_KERNEL, info->controller->node);
+		if (!info->res_offset) {
+			kfree(name);
+			kfree(info->res);
+			info->res = NULL;
+			return -ENOMEM;
+		}
+
+		info->res_num = 0;
+		acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+			add_window, info);
+	} else
+		kfree(name);
+
+	return 0;
+}
+
 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 {
 	struct acpi_device *device = root->device;
 	int domain = root->segment;
 	int bus = root->secondary.start;
 	struct pci_controller *controller;
-	unsigned int windows = 0;
-	struct pci_root_info info;
+	struct pci_root_info *info = NULL;
+	int busnum = root->secondary.start;
 	struct pci_bus *pbus;
-	char *name;
-	int pxm;
+	int pxm, ret;
 
 	controller = alloc_pci_controller(domain);
 	if (!controller)
-		goto out1;
+		return NULL;
 
 	controller->acpi_handle = device->handle;
 
@@ -347,29 +444,27 @@ struct pci_bus *pci_acpi_scan_root(struc
 		controller->node = pxm_to_node(pxm);
 #endif
 
-	INIT_LIST_HEAD(&info.resources);
-	/* insert busn resource at first */
-	pci_add_resource(&info.resources, &root->secondary);
-	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
-			&windows);
-	if (windows) {
-		controller->window =
-			kzalloc_node(sizeof(*controller->window) * windows,
-				     GFP_KERNEL, controller->node);
-		if (!controller->window)
-			goto out2;
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info) {
+		dev_err(&device->dev,
+				"pci_bus %04x:%02x: ignored (out of memory)\n",
+				domain, busnum);
+		kfree(controller);
+		return NULL;
+	}
 
-		name = kmalloc(16, GFP_KERNEL);
-		if (!name)
-			goto out3;
+	info->controller = controller;
+	INIT_LIST_HEAD(&info->io_resources);
+	INIT_LIST_HEAD(&info->resources);
 
-		sprintf(name, "PCI Bus %04x:%02x", domain, bus);
-		info.bridge = device;
-		info.controller = controller;
-		info.name = name;
-		acpi_walk_resources(device->handle, METHOD_NAME__CRS,
-			add_window, &info);
+	ret = probe_pci_root_info(info, device, busnum, domain);
+	if (ret) {
+		kfree(info->controller);
+		kfree(info);
+		return NULL;
 	}
+	/* insert busn resource at first */
+	pci_add_resource(&info->resources, &root->secondary);
 	/*
 	 * See arch/x86/pci/acpi.c.
 	 * The desired pci bus might already be scanned in a quirk. We
@@ -377,21 +472,17 @@ struct pci_bus *pci_acpi_scan_root(struc
 	 * such quirk. So we just ignore the case now.
 	 */
 	pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
-				   &info.resources);
+				   &info->resources);
 	if (!pbus) {
-		pci_free_resource_list(&info.resources);
+		pci_free_resource_list(&info->resources);
+		__release_pci_root_info(info);
 		return NULL;
 	}
 
+	pci_set_host_bridge_release(to_pci_host_bridge(pbus->bridge),
+			release_pci_root_info, info);
 	pci_scan_child_bus(pbus);
 	return pbus;
-
-out3:
-	kfree(controller->window);
-out2:
-	kfree(controller);
-out1:
-	return NULL;
 }
 
 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
@@ -691,7 +782,7 @@ static void __init set_pci_dfl_cacheline
 
 	status = ia64_pal_cache_summary(&levels, &unique_caches);
 	if (status != 0) {
-		printk(KERN_ERR "%s: ia64_pal_cache_summary() failed "
+		pr_err("%s: ia64_pal_cache_summary() failed "
 			"(status=%ld)\n", __func__, status);
 		return;
 	}
@@ -699,7 +790,7 @@ static void __init set_pci_dfl_cacheline
 	status = ia64_pal_cache_config_info(levels - 1,
 				/* cache_type (data_or_unified)= */ 2, &cci);
 	if (status != 0) {
-		printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed "
+		pr_err("%s: ia64_pal_cache_config_info() failed "
 			"(status=%ld)\n", __func__, status);
 		return;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/sn/kernel/io_init.c linux-libre-3.11-rc7-gnu/arch/ia64/sn/kernel/io_init.c
--- linux-libre-3.10-gnu/arch/ia64/sn/kernel/io_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/sn/kernel/io_init.c	2013-08-25 20:43:22.000000000 -0400
@@ -118,76 +118,26 @@ static void __init sn_fixup_ionodes(void
 }
 
 /*
- * sn_pci_legacy_window_fixup - Create PCI controller windows for
+ * sn_pci_legacy_window_fixup - Setup PCI resources for
  *				legacy IO and MEM space. This needs to
  *				be done here, as the PROM does not have
  *				ACPI support defining the root buses
  *				and their resources (_CRS),
  */
 static void
-sn_legacy_pci_window_fixup(struct pci_controller *controller,
-			   u64 legacy_io, u64 legacy_mem)
-{
-		controller->window = kcalloc(2, sizeof(struct pci_window),
-					     GFP_KERNEL);
-		BUG_ON(controller->window == NULL);
-		controller->window[0].offset = legacy_io;
-		controller->window[0].resource.name = "legacy_io";
-		controller->window[0].resource.flags = IORESOURCE_IO;
-		controller->window[0].resource.start = legacy_io;
-		controller->window[0].resource.end =
-	    			controller->window[0].resource.start + 0xffff;
-		controller->window[0].resource.parent = &ioport_resource;
-		controller->window[1].offset = legacy_mem;
-		controller->window[1].resource.name = "legacy_mem";
-		controller->window[1].resource.flags = IORESOURCE_MEM;
-		controller->window[1].resource.start = legacy_mem;
-		controller->window[1].resource.end =
-	    	       controller->window[1].resource.start + (1024 * 1024) - 1;
-		controller->window[1].resource.parent = &iomem_resource;
-		controller->windows = 2;
-}
-
-/*
- * sn_pci_window_fixup() - Create a pci_window for each device resource.
- *			   It will setup pci_windows for use by
- *			   pcibios_bus_to_resource(), pcibios_resource_to_bus(),
- *			   etc.
- */
-static void
-sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
-		    s64 * pci_addrs)
+sn_legacy_pci_window_fixup(struct resource *res,
+		u64 legacy_io, u64 legacy_mem)
 {
-	struct pci_controller *controller = PCI_CONTROLLER(dev->bus);
-	unsigned int i;
-	unsigned int idx;
-	unsigned int new_count;
-	struct pci_window *new_window;
-
-	if (count == 0)
-		return;
-	idx = controller->windows;
-	new_count = controller->windows + count;
-	new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL);
-	BUG_ON(new_window == NULL);
-	if (controller->window) {
-		memcpy(new_window, controller->window,
-		       sizeof(struct pci_window) * controller->windows);
-		kfree(controller->window);
-	}
-
-	/* Setup a pci_window for each device resource. */
-	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-		if (pci_addrs[i] == -1)
-			continue;
-
-		new_window[idx].offset = dev->resource[i].start - pci_addrs[i];
-		new_window[idx].resource = dev->resource[i];
-		idx++;
-	}
-
-	controller->windows = new_count;
-	controller->window = new_window;
+		res[0].name = "legacy_io";
+		res[0].flags = IORESOURCE_IO;
+		res[0].start = legacy_io;
+		res[0].end = res[0].start + 0xffff;
+		res[0].parent = &ioport_resource;
+		res[1].name = "legacy_mem";
+		res[1].flags = IORESOURCE_MEM;
+		res[1].start = legacy_mem;
+		res[1].end = res[1].start + (1024 * 1024) - 1;
+		res[1].parent = &iomem_resource;
 }
 
 /*
@@ -199,9 +149,7 @@ sn_pci_window_fixup(struct pci_dev *dev,
 void
 sn_io_slot_fixup(struct pci_dev *dev)
 {
-	unsigned int count = 0;
 	int idx;
-	s64 pci_addrs[PCI_ROM_RESOURCE + 1];
 	unsigned long addr, end, size, start;
 	struct pcidev_info *pcidev_info;
 	struct sn_irq_info *sn_irq_info;
@@ -229,7 +177,6 @@ sn_io_slot_fixup(struct pci_dev *dev)
 	for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
 
 		if (!pcidev_info->pdi_pio_mapped_addr[idx]) {
-			pci_addrs[idx] = -1;
 			continue;
 		}
 
@@ -237,11 +184,8 @@ sn_io_slot_fixup(struct pci_dev *dev)
 		end = dev->resource[idx].end;
 		size = end - start;
 		if (size == 0) {
-			pci_addrs[idx] = -1;
 			continue;
 		}
-		pci_addrs[idx] = start;
-		count++;
 		addr = pcidev_info->pdi_pio_mapped_addr[idx];
 		addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET;
 		dev->resource[idx].start = addr;
@@ -276,11 +220,6 @@ sn_io_slot_fixup(struct pci_dev *dev)
 						 IORESOURCE_ROM_BIOS_COPY;
 		}
 	}
-	/* Create a pci_window in the pci_controller struct for
-	 * each device resource.
-	 */
-	if (count > 0)
-		sn_pci_window_fixup(dev, count, pci_addrs);
 
 	sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
 }
@@ -297,8 +236,8 @@ sn_pci_controller_fixup(int segment, int
 	s64 status = 0;
 	struct pci_controller *controller;
 	struct pcibus_bussoft *prom_bussoft_ptr;
+	struct resource *res;
 	LIST_HEAD(resources);
-	int i;
 
  	status = sal_get_pcibus_info((u64) segment, (u64) busnum,
  				     (u64) ia64_tpa(&prom_bussoft_ptr));
@@ -310,32 +249,29 @@ sn_pci_controller_fixup(int segment, int
 	BUG_ON(!controller);
 	controller->segment = segment;
 
+	res = kcalloc(2, sizeof(struct resource), GFP_KERNEL);
+	BUG_ON(!res);
+
 	/*
 	 * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup().
 	 * (platform_data will be overwritten later in sn_common_bus_fixup())
 	 */
 	controller->platform_data = prom_bussoft_ptr;
 
-	sn_legacy_pci_window_fixup(controller,
-				   prom_bussoft_ptr->bs_legacy_io,
-				   prom_bussoft_ptr->bs_legacy_mem);
-	for (i = 0; i < controller->windows; i++)
-		pci_add_resource_offset(&resources,
-					&controller->window[i].resource,
-					controller->window[i].offset);
+	sn_legacy_pci_window_fixup(res,
+			prom_bussoft_ptr->bs_legacy_io,
+			prom_bussoft_ptr->bs_legacy_mem);
+	pci_add_resource_offset(&resources,	&res[0],
+			prom_bussoft_ptr->bs_legacy_io);
+	pci_add_resource_offset(&resources,	&res[1],
+			prom_bussoft_ptr->bs_legacy_mem);
+
 	bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
 				&resources);
- 	if (bus == NULL)
- 		goto error_return; /* error, or bus already scanned */
-
-	bus->sysdata = controller;
-
-	return;
-
-error_return:
-
-	kfree(controller);
-	return;
+ 	if (bus == NULL) {
+		kfree(res);
+		kfree(controller);
+	}
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/sn/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/ia64/sn/kernel/setup.c
--- linux-libre-3.10-gnu/arch/ia64/sn/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/sn/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -192,7 +192,7 @@ void __init early_sn_setup(void)
 }
 
 extern int platform_intr_list[];
-static int __cpuinitdata shub_1_1_found;
+static int shub_1_1_found;
 
 /*
  * sn_check_for_wars
@@ -200,7 +200,7 @@ static int __cpuinitdata shub_1_1_found;
  * Set flag for enabling shub specific wars
  */
 
-static inline int __cpuinit is_shub_1_1(int nasid)
+static inline int is_shub_1_1(int nasid)
 {
 	unsigned long id;
 	int rev;
@@ -212,7 +212,7 @@ static inline int __cpuinit is_shub_1_1(
 	return rev <= 2;
 }
 
-static void __cpuinit sn_check_for_wars(void)
+static void sn_check_for_wars(void)
 {
 	int cnode;
 
@@ -558,7 +558,7 @@ static void __init sn_init_pdas(char **c
  * Also sets up a few fields in the nodepda.  Also known as
  * platform_cpu_init() by the ia64 machvec code.
  */
-void __cpuinit sn_cpu_init(void)
+void sn_cpu_init(void)
 {
 	int cpuid;
 	int cpuphyid;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/ia64/xen/hypervisor.c linux-libre-3.11-rc7-gnu/arch/ia64/xen/hypervisor.c
--- linux-libre-3.10-gnu/arch/ia64/xen/hypervisor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/ia64/xen/hypervisor.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,7 +74,7 @@ void __init xen_setup_vcpu_info_placemen
 		xen_vcpu_setup(cpu);
 }
 
-void __cpuinit
+void
 xen_cpu_init(void)
 {
 	xen_smp_intr_init();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/Kconfig linux-libre-3.11-rc7-gnu/arch/Kconfig
--- linux-libre-3.10-gnu/arch/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -365,6 +365,9 @@ config HAVE_IRQ_TIME_ACCOUNTING
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	bool
 
+config HAVE_ARCH_SOFT_DIRTY
+	bool
+
 config HAVE_MOD_ARCH_SPECIFIC
 	bool
 	help
@@ -404,6 +407,12 @@ config CLONE_BACKWARDS2
 	help
 	  Architecture has the first two arguments of clone(2) swapped.
 
+config CLONE_BACKWARDS3
+	bool
+	help
+	  Architecture has tls passed as the 3rd argument of clone(2),
+	  not the 5th one.
+
 config ODD_RT_SIGACTION
 	bool
 	help
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m32r/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/m32r/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/m32r/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m32r/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -347,9 +347,6 @@ static inline void pmd_set(pmd_t * pmdp,
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)	\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m32r/include/asm/uaccess.h linux-libre-3.11-rc7-gnu/arch/m32r/include/asm/uaccess.h
--- linux-libre-3.10-gnu/arch/m32r/include/asm/uaccess.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m32r/include/asm/uaccess.h	2013-08-25 20:43:22.000000000 -0400
@@ -216,7 +216,7 @@ extern int fixup_exception(struct pt_reg
 ({									\
 	long __gu_err = 0;						\
 	unsigned long __gu_val;						\
-	might_sleep();							\
+	might_fault();							\
 	__get_user_size(__gu_val,(ptr),(size),__gu_err);		\
 	(x) = (__typeof__(*(ptr)))__gu_val;				\
 	__gu_err;							\
@@ -227,7 +227,7 @@ extern int fixup_exception(struct pt_reg
 	long __gu_err = -EFAULT;					\
 	unsigned long __gu_val = 0;					\
 	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);		\
-	might_sleep();							\
+	might_fault();							\
 	if (access_ok(VERIFY_READ,__gu_addr,size))			\
 		__get_user_size(__gu_val,__gu_addr,(size),__gu_err);	\
 	(x) = (__typeof__(*(ptr)))__gu_val;				\
@@ -295,7 +295,7 @@ do {									\
 #define __put_user_nocheck(x,ptr,size)					\
 ({									\
 	long __pu_err;							\
-	might_sleep();							\
+	might_fault();							\
 	__put_user_size((x),(ptr),(size),__pu_err);			\
 	__pu_err;							\
 })
@@ -305,7 +305,7 @@ do {									\
 ({									\
 	long __pu_err = -EFAULT;					\
 	__typeof__(*(ptr)) __user *__pu_addr = (ptr);			\
-	might_sleep();							\
+	might_fault();							\
 	if (access_ok(VERIFY_WRITE,__pu_addr,size))			\
 		__put_user_size((x),__pu_addr,(size),__pu_err);		\
 	__pu_err;							\
@@ -597,7 +597,7 @@ unsigned long __generic_copy_from_user(v
  */
 #define copy_to_user(to,from,n)				\
 ({							\
-	might_sleep();					\
+	might_fault();					\
 	__generic_copy_to_user((to),(from),(n));	\
 })
 
@@ -638,7 +638,7 @@ unsigned long __generic_copy_from_user(v
  */
 #define copy_from_user(to,from,n)			\
 ({							\
-	might_sleep();					\
+	might_fault();					\
 	__generic_copy_from_user((to),(from),(n));	\
 })
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m32r/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/m32r/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/m32r/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m32r/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -74,4 +74,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif /* _ASM_M32R_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m32r/Kconfig linux-libre-3.11-rc7-gnu/arch/m32r/Kconfig
--- linux-libre-3.10-gnu/arch/m32r/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m32r/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,7 @@ config M32R
 	select GENERIC_ATOMIC64
 	select ARCH_USES_GETTIMEOFFSET
 	select MODULES_USE_ELF_RELA
+	select HAVE_DEBUG_STACKOVERFLOW
 
 config SBUS
 	bool
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m32r/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/m32r/Kconfig.debug
--- linux-libre-3.10-gnu/arch/m32r/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m32r/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -2,13 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-	help
-	  This option will cause messages to be printed if free stack space
-	  drops below a certain limit.
-
 config DEBUG_PAGEALLOC
 	bool "Debug page memory allocations"
 	depends on DEBUG_KERNEL && BROKEN
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m32r/kernel/smpboot.c linux-libre-3.11-rc7-gnu/arch/m32r/kernel/smpboot.c
--- linux-libre-3.10-gnu/arch/m32r/kernel/smpboot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m32r/kernel/smpboot.c	2013-08-25 20:43:22.000000000 -0400
@@ -343,7 +343,7 @@ static void __init do_boot_cpu(int phys_
 	}
 }
 
-int __cpuinit __cpu_up(unsigned int cpu_id, struct task_struct *tidle)
+int __cpu_up(unsigned int cpu_id, struct task_struct *tidle)
 {
 	int timeout;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m32r/mm/discontig.c linux-libre-3.11-rc7-gnu/arch/m32r/mm/discontig.c
--- linux-libre-3.10-gnu/arch/m32r/mm/discontig.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m32r/mm/discontig.c	2013-08-25 20:43:22.000000000 -0400
@@ -129,11 +129,10 @@ unsigned long __init setup_memory(void)
 #define START_PFN(nid)		(NODE_DATA(nid)->bdata->node_min_pfn)
 #define MAX_LOW_PFN(nid)	(NODE_DATA(nid)->bdata->node_low_pfn)
 
-unsigned long __init zone_sizes_init(void)
+void __init zone_sizes_init(void)
 {
 	unsigned long zones_size[MAX_NR_ZONES], zholes_size[MAX_NR_ZONES];
 	unsigned long low, start_pfn;
-	unsigned long holes = 0;
 	int nid, i;
 	mem_prof_t *mp;
 
@@ -147,7 +146,6 @@ unsigned long __init zone_sizes_init(voi
 		low = MAX_LOW_PFN(nid);
 		zones_size[ZONE_DMA] = low - start_pfn;
 		zholes_size[ZONE_DMA] = mp->holes;
-		holes += zholes_size[ZONE_DMA];
 
 		node_set_state(nid, N_NORMAL_MEMORY);
 		free_area_init_node(nid, zones_size, start_pfn, zholes_size);
@@ -161,6 +159,4 @@ unsigned long __init zone_sizes_init(voi
 	NODE_DATA(1)->node_zones->watermark[WMARK_MIN] = 0;
 	NODE_DATA(1)->node_zones->watermark[WMARK_LOW] = 0;
 	NODE_DATA(1)->node_zones->watermark[WMARK_HIGH] = 0;
-
-	return holes;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m32r/mm/init.c linux-libre-3.11-rc7-gnu/arch/m32r/mm/init.c
--- linux-libre-3.10-gnu/arch/m32r/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m32r/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,7 +40,6 @@ unsigned long mmu_context_cache_dat;
 #else
 unsigned long mmu_context_cache_dat[NR_CPUS];
 #endif
-static unsigned long hole_pages;
 
 /*
  * function prototype
@@ -57,7 +56,7 @@ void free_initrd_mem(unsigned long, unsi
 #define MAX_LOW_PFN(nid)	(NODE_DATA(nid)->bdata->node_low_pfn)
 
 #ifndef CONFIG_DISCONTIGMEM
-unsigned long __init zone_sizes_init(void)
+void __init zone_sizes_init(void)
 {
 	unsigned long  zones_size[MAX_NR_ZONES] = {0, };
 	unsigned long  max_dma;
@@ -83,11 +82,9 @@ unsigned long __init zone_sizes_init(voi
 #endif /* CONFIG_MMU */
 
 	free_area_init_node(0, zones_size, start_pfn, 0);
-
-	return 0;
 }
 #else	/* CONFIG_DISCONTIGMEM */
-extern unsigned long zone_sizes_init(void);
+extern void zone_sizes_init(void);
 #endif	/* CONFIG_DISCONTIGMEM */
 
 /*======================================================================*
@@ -105,24 +102,7 @@ void __init paging_init(void)
 	for (i = 0 ; i < USER_PTRS_PER_PGD * 2 ; i++)
 		pgd_val(pg_dir[i]) = 0;
 #endif /* CONFIG_MMU */
-	hole_pages = zone_sizes_init();
-}
-
-int __init reservedpages_count(void)
-{
-	int reservedpages, nid, i;
-
-	reservedpages = 0;
-	for_each_online_node(nid) {
-		unsigned long flags;
-		pgdat_resize_lock(NODE_DATA(nid), &flags);
-		for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++)
-			if (PageReserved(nid_page_nr(nid, i)))
-				reservedpages++;
-		pgdat_resize_unlock(NODE_DATA(nid), &flags);
-	}
-
-	return reservedpages;
+	zone_sizes_init();
 }
 
 /*======================================================================*
@@ -131,48 +111,20 @@ int __init reservedpages_count(void)
  *======================================================================*/
 void __init mem_init(void)
 {
-	int codesize, reservedpages, datasize, initsize;
-	int nid;
 #ifndef CONFIG_MMU
 	extern unsigned long memory_end;
-#endif
-
-	num_physpages = 0;
-	for_each_online_node(nid)
-		num_physpages += MAX_LOW_PFN(nid) - START_PFN(nid) + 1;
-
-	num_physpages -= hole_pages;
-
-#ifndef CONFIG_DISCONTIGMEM
-	max_mapnr = num_physpages;
-#endif	/* CONFIG_DISCONTIGMEM */
 
-#ifdef CONFIG_MMU
-	high_memory = (void *)__va(PFN_PHYS(MAX_LOW_PFN(0)));
-#else
 	high_memory = (void *)(memory_end & PAGE_MASK);
+#else
+	high_memory = (void *)__va(PFN_PHYS(MAX_LOW_PFN(0)));
 #endif /* CONFIG_MMU */
 
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
 
-	/* this will put all low memory onto the freelists */
-	for_each_online_node(nid)
-		totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
-
-	reservedpages = reservedpages_count() - hole_pages;
-	codesize = (unsigned long) &_etext - (unsigned long)&_text;
-	datasize = (unsigned long) &_edata - (unsigned long)&_etext;
-	initsize = (unsigned long) &__init_end - (unsigned long)&__init_begin;
-
-	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
-		"%dk reserved, %dk data, %dk init)\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10,
-		reservedpages << (PAGE_SHIFT-10),
-		datasize >> 10,
-		initsize >> 10);
+	set_max_mapnr(get_num_physpages());
+	free_all_bootmem();
+	mem_init_print_info(NULL);
 }
 
 /*======================================================================*
@@ -181,7 +133,7 @@ void __init mem_init(void)
  *======================================================================*/
 void free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -191,6 +143,6 @@ void free_initmem(void)
  *======================================================================*/
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/configs/multi_defconfig linux-libre-3.11-rc7-gnu/arch/m68k/configs/multi_defconfig
--- linux-libre-3.10-gnu/arch/m68k/configs/multi_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/configs/multi_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -214,6 +214,7 @@ CONFIG_DEVTMPFS=y
 # CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
 CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
 CONFIG_PARPORT_AMIGA=m
 CONFIG_PARPORT_MFC3=m
 CONFIG_PARPORT_ATARI=m
@@ -325,6 +326,7 @@ CONFIG_ZORRO8390=y
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PLIP=m
 CONFIG_PPP=m
 CONFIG_PPP_BSDCOMP=m
 CONFIG_PPP_DEFLATE=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/configs/q40_defconfig linux-libre-3.11-rc7-gnu/arch/m68k/configs/q40_defconfig
--- linux-libre-3.10-gnu/arch/m68k/configs/q40_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/configs/q40_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -199,6 +199,9 @@ CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 # CONFIG_FW_LOADER_USER_HELPER is not set
 CONFIG_CONNECTOR=m
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_1284=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_DRBD=m
@@ -267,6 +270,7 @@ CONFIG_NE2000=m
 # CONFIG_NET_VENDOR_SMSC is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PLIP=m
 CONFIG_PPP=m
 CONFIG_PPP_BSDCOMP=m
 CONFIG_PPP_DEFLATE=m
@@ -292,9 +296,11 @@ CONFIG_SERIO_Q40KBD=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
+CONFIG_PRINTER=m
 # CONFIG_HW_RANDOM is not set
 CONFIG_NTP_PPS=y
 CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_PARPORT=m
 CONFIG_PTP_1588_CLOCK=m
 # CONFIG_HWMON is not set
 CONFIG_FB=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/emu/natfeat.c linux-libre-3.11-rc7-gnu/arch/m68k/emu/natfeat.c
--- linux-libre-3.10-gnu/arch/m68k/emu/natfeat.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/emu/natfeat.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,9 +18,11 @@
 #include <asm/machdep.h>
 #include <asm/natfeat.h>
 
+extern long nf_get_id2(const char *feature_name);
+
 asm("\n"
-"	.global nf_get_id,nf_call\n"
-"nf_get_id:\n"
+"	.global nf_get_id2,nf_call\n"
+"nf_get_id2:\n"
 "	.short	0x7300\n"
 "	rts\n"
 "nf_call:\n"
@@ -29,12 +31,25 @@ asm("\n"
 "1:	moveq.l	#0,%d0\n"
 "	rts\n"
 "	.section __ex_table,\"a\"\n"
-"	.long	nf_get_id,1b\n"
+"	.long	nf_get_id2,1b\n"
 "	.long	nf_call,1b\n"
 "	.previous");
-EXPORT_SYMBOL_GPL(nf_get_id);
 EXPORT_SYMBOL_GPL(nf_call);
 
+long nf_get_id(const char *feature_name)
+{
+	/* feature_name may be in vmalloc()ed memory, so make a copy */
+	char name_copy[32];
+	size_t n;
+
+	n = strlcpy(name_copy, feature_name, sizeof(name_copy));
+	if (n >= sizeof(name_copy))
+		return 0;
+
+	return nf_get_id2(name_copy);
+}
+EXPORT_SYMBOL_GPL(nf_get_id);
+
 void nfprint(const char *fmt, ...)
 {
 	static char buf[256];
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/include/asm/div64.h linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/div64.h
--- linux-libre-3.10-gnu/arch/m68k/include/asm/div64.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/div64.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,16 +15,17 @@
 		unsigned long long n64;				\
 	} __n;							\
 	unsigned long __rem, __upper;				\
+	unsigned long __base = (base);				\
 								\
 	__n.n64 = (n);						\
 	if ((__upper = __n.n32[0])) {				\
 		asm ("divul.l %2,%1:%0"				\
-			: "=d" (__n.n32[0]), "=d" (__upper)	\
-			: "d" (base), "0" (__n.n32[0]));	\
+		     : "=d" (__n.n32[0]), "=d" (__upper)	\
+		     : "d" (__base), "0" (__n.n32[0]));		\
 	}							\
 	asm ("divu.l %2,%1:%0"					\
-		: "=d" (__n.n32[1]), "=d" (__rem)		\
-		: "d" (base), "1" (__upper), "0" (__n.n32[1]));	\
+	     : "=d" (__n.n32[1]), "=d" (__rem)			\
+	     : "d" (__base), "1" (__upper), "0" (__n.n32[1]));	\
 	(n) = __n.n64;						\
 	__rem;							\
 })
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/include/asm/parport.h linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/parport.h
--- linux-libre-3.10-gnu/arch/m68k/include/asm/parport.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/parport.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,8 @@
 #ifndef _ASM_M68K_PARPORT_H
 #define _ASM_M68K_PARPORT_H 1
 
+#undef insl
+#undef outsl
 #define insl(port,buf,len)   isa_insb(port,buf,(len)<<2)
 #define outsl(port,buf,len)  isa_outsb(port,buf,(len)<<2)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/include/asm/pgtable_mm.h linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/pgtable_mm.h
--- linux-libre-3.10-gnu/arch/m68k/include/asm/pgtable_mm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/pgtable_mm.h	2013-08-25 20:43:22.000000000 -0400
@@ -135,9 +135,6 @@ static inline void update_mmu_cache(stru
 
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 /* MMU-specific headers */
 
 #ifdef CONFIG_SUN3
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/include/asm/pgtable_no.h linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/pgtable_no.h
--- linux-libre-3.10-gnu/arch/m68k/include/asm/pgtable_no.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/pgtable_no.h	2013-08-25 20:43:22.000000000 -0400
@@ -55,9 +55,6 @@ extern unsigned int kobjsize(const void
  */
 #define pgtable_cache_init()	do { } while (0)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 /*
  * All 32bit addresses are effectively valid for vmalloc...
  * Sort of meaningless for non-VM targets.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/include/asm/string.h linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/string.h
--- linux-libre-3.10-gnu/arch/m68k/include/asm/string.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/string.h	2013-08-25 20:43:22.000000000 -0400
@@ -4,20 +4,6 @@
 #include <linux/types.h>
 #include <linux/compiler.h>
 
-static inline char *__kernel_strcpy(char *dest, const char *src)
-{
-	char *xdest = dest;
-
-	asm volatile ("\n"
-		"1:	move.b	(%1)+,(%0)+\n"
-		"	jne	1b"
-		: "+a" (dest), "+a" (src)
-		: : "memory");
-	return xdest;
-}
-
-#ifndef __IN_STRING_C
-
 #define __HAVE_ARCH_STRNLEN
 static inline size_t strnlen(const char *s, size_t count)
 {
@@ -34,16 +20,6 @@ static inline size_t strnlen(const char
 	return sc - s;
 }
 
-#define __HAVE_ARCH_STRCPY
-#if __GNUC__ >= 4
-#define strcpy(d, s)	(__builtin_constant_p(s) &&	\
-			 __builtin_strlen(s) <= 32 ?	\
-			 __builtin_strcpy(d, s) :	\
-			 __kernel_strcpy(d, s))
-#else
-#define strcpy(d, s)	__kernel_strcpy(d, s)
-#endif
-
 #define __HAVE_ARCH_STRNCPY
 static inline char *strncpy(char *dest, const char *src, size_t n)
 {
@@ -61,12 +37,6 @@ static inline char *strncpy(char *dest,
 	return xdest;
 }
 
-#define __HAVE_ARCH_STRCAT
-#define strcat(d, s)	({			\
-	char *__d = (d);			\
-	strcpy(__d + strlen(__d), (s));		\
-})
-
 #ifndef CONFIG_COLDFIRE
 #define __HAVE_ARCH_STRCMP
 static inline int strcmp(const char *cs, const char *ct)
@@ -100,6 +70,4 @@ extern void *memset(void *, int, __kerne
 extern void *memcpy(void *, const void *, __kernel_size_t);
 #define memcpy(d, s, n) __builtin_memcpy(d, s, n)
 
-#endif
-
 #endif /* _M68K_STRING_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/include/asm/uaccess_mm.h linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/uaccess_mm.h
--- linux-libre-3.10-gnu/arch/m68k/include/asm/uaccess_mm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/include/asm/uaccess_mm.h	2013-08-25 20:43:22.000000000 -0400
@@ -90,7 +90,7 @@ asm volatile ("\n"					\
 		__put_user_asm(__pu_err, __pu_val, ptr, b, d, -EFAULT);	\
 		break;							\
 	case 2:								\
-		__put_user_asm(__pu_err, __pu_val, ptr, w, d, -EFAULT);	\
+		__put_user_asm(__pu_err, __pu_val, ptr, w, r, -EFAULT);	\
 		break;							\
 	case 4:								\
 		__put_user_asm(__pu_err, __pu_val, ptr, l, r, -EFAULT);	\
@@ -158,7 +158,7 @@ asm volatile ("\n"					\
 		__get_user_asm(__gu_err, x, ptr, u8, b, d, -EFAULT);	\
 		break;							\
 	case 2:								\
-		__get_user_asm(__gu_err, x, ptr, u16, w, d, -EFAULT);	\
+		__get_user_asm(__gu_err, x, ptr, u16, w, r, -EFAULT);	\
 		break;							\
 	case 4:								\
 		__get_user_asm(__gu_err, x, ptr, u32, l, r, -EFAULT);	\
@@ -245,7 +245,7 @@ __constant_copy_from_user(void *to, cons
 		__get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1);
 		break;
 	case 2:
-		__get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, d, 2);
+		__get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, r, 2);
 		break;
 	case 3:
 		__constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,);
@@ -326,7 +326,7 @@ __constant_copy_to_user(void __user *to,
 		__put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1);
 		break;
 	case 2:
-		__put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, d, 2);
+		__put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, r, 2);
 		break;
 	case 3:
 		__constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/m68k/Kconfig.debug
--- linux-libre-3.10-gnu/arch/m68k/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -11,9 +11,8 @@ config BOOTPARAM_STRING
 	depends on BOOTPARAM
 
 config EARLY_PRINTK
-	bool "Early printk" if EMBEDDED
+	bool "Early printk"
 	depends on MVME16x || MAC
-	default y
 	help
           Write kernel log output directly to a serial port.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/kernel/asm-offsets.c linux-libre-3.11-rc7-gnu/arch/m68k/kernel/asm-offsets.c
--- linux-libre-3.10-gnu/arch/m68k/kernel/asm-offsets.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/kernel/asm-offsets.c	2013-08-25 20:43:22.000000000 -0400
@@ -77,7 +77,7 @@ int main(void)
 	DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
 	DEFINE(BIR_DATA, offsetof(struct bi_record, data));
 
-	/* offsets into font_desc (drivers/video/console/font.h) */
+	/* offsets into the font_desc struct */
 	DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));
 	DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));
 	DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/kernel/ints.c linux-libre-3.11-rc7-gnu/arch/m68k/kernel/ints.c
--- linux-libre-3.10-gnu/arch/m68k/kernel/ints.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/kernel/ints.c	2013-08-25 20:43:22.000000000 -0400
@@ -101,7 +101,7 @@ void __init m68k_setup_user_interrupt(un
 	BUG_ON(IRQ_USER + cnt > NR_IRQS);
 	m68k_first_user_vec = vec;
 	for (i = 0; i < cnt; i++)
-		irq_set_chip(IRQ_USER + i, &user_irq_chip);
+		irq_set_chip_and_handler(i, &user_irq_chip, handle_simple_irq);
 	*user_irqvec_fixup = vec - IRQ_USER;
 	flush_icache();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/lib/Makefile linux-libre-3.11-rc7-gnu/arch/m68k/lib/Makefile
--- linux-libre-3.10-gnu/arch/m68k/lib/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/lib/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
 lib-y	:= ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
 	   memcpy.o memset.o memmove.o
 
-lib-$(CONFIG_MMU) += string.o uaccess.o
+lib-$(CONFIG_MMU) += uaccess.o
 lib-$(CONFIG_CPU_HAS_NO_MULDIV64) += mulsi3.o divsi3.o udivsi3.o
 lib-$(CONFIG_CPU_HAS_NO_MULDIV64) += modsi3.o umodsi3.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/lib/string.c linux-libre-3.11-rc7-gnu/arch/m68k/lib/string.c
--- linux-libre-3.10-gnu/arch/m68k/lib/string.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/lib/string.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#define __IN_STRING_C
-
-#include <linux/module.h>
-#include <linux/string.h>
-
-char *strcpy(char *dest, const char *src)
-{
-	return __kernel_strcpy(dest, src);
-}
-EXPORT_SYMBOL(strcpy);
-
-char *strcat(char *dest, const char *src)
-{
-	return __kernel_strcpy(dest + strlen(dest), src);
-}
-EXPORT_SYMBOL(strcat);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/lib/uaccess.c linux-libre-3.11-rc7-gnu/arch/m68k/lib/uaccess.c
--- linux-libre-3.10-gnu/arch/m68k/lib/uaccess.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/lib/uaccess.c	2013-08-25 20:43:22.000000000 -0400
@@ -52,7 +52,7 @@ unsigned long __generic_copy_from_user(v
 		"	.long	3b,30b\n"
 		"	.long	5b,50b\n"
 		"	.previous"
-		: "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
+		: "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
 		: "0" (n / 4), "d" (n & 3));
 
 	return res;
@@ -96,7 +96,7 @@ unsigned long __generic_copy_to_user(voi
 		"	.long	7b,50b\n"
 		"	.long	8b,50b\n"
 		"	.previous"
-		: "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
+		: "=d" (res), "+a" (from), "+a" (to), "=&d" (tmp)
 		: "0" (n / 4), "d" (n & 3));
 
 	return res;
@@ -141,7 +141,7 @@ unsigned long __clear_user(void __user *
 		"	.long	7b,40b\n"
 		"	.previous"
 		: "=d" (res), "+a" (to)
-		: "r" (0), "0" (n / 4), "d" (n & 3));
+		: "d" (0), "0" (n / 4), "d" (n & 3));
 
     return res;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/math-emu/fp_arith.c linux-libre-3.11-rc7-gnu/arch/m68k/math-emu/fp_arith.c
--- linux-libre-3.10-gnu/arch/m68k/math-emu/fp_arith.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/math-emu/fp_arith.c	2013-08-25 20:43:22.000000000 -0400
@@ -519,7 +519,7 @@ static void fp_roundint(struct fp_ext *d
 				return;
 			break;
 		case 0x401e:
-			if (!(oldmant.m32[1] >= 0))
+			if (oldmant.m32[1] & 0x80000000)
 				return;
 			if (oldmant.m32[0] & 1)
 				break;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/mm/init.c linux-libre-3.11-rc7-gnu/arch/m68k/mm/init.c
--- linux-libre-3.10-gnu/arch/m68k/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -110,7 +110,7 @@ void __init paging_init(void)
 void free_initmem(void)
 {
 #ifndef CONFIG_MMU_SUN3
-	free_initmem_default(0);
+	free_initmem_default(-1);
 #endif /* CONFIG_MMU_SUN3 */
 }
 
@@ -146,38 +146,11 @@ void __init print_memmap(void)
 		MLK_ROUNDUP(__bss_start, __bss_stop));
 }
 
-void __init mem_init(void)
+static inline void init_pointer_tables(void)
 {
-	pg_data_t *pgdat;
-	int codepages = 0;
-	int datapages = 0;
-	int initpages = 0;
+#if defined(CONFIG_MMU) && !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
 	int i;
 
-	/* this will put all memory onto the freelists */
-	totalram_pages = num_physpages = 0;
-	for_each_online_pgdat(pgdat) {
-		num_physpages += pgdat->node_present_pages;
-
-		totalram_pages += free_all_bootmem_node(pgdat);
-		for (i = 0; i < pgdat->node_spanned_pages; i++) {
-			struct page *page = pgdat->node_mem_map + i;
-			char *addr = page_to_virt(page);
-
-			if (!PageReserved(page))
-				continue;
-			if (addr >= _text &&
-			    addr < _etext)
-				codepages++;
-			else if (addr >= __init_begin &&
-				 addr < __init_end)
-				initpages++;
-			else
-				datapages++;
-		}
-	}
-
-#if defined(CONFIG_MMU) && !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
 	/* insert pointer tables allocated so far into the tablelist */
 	init_pointer_table((unsigned long)kernel_pg_dir);
 	for (i = 0; i < PTRS_PER_PGD; i++) {
@@ -189,19 +162,20 @@ void __init mem_init(void)
 	if (zero_pgtable)
 		init_pointer_table((unsigned long)zero_pgtable);
 #endif
+}
 
-	pr_info("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n",
-	       nr_free_pages() << (PAGE_SHIFT-10),
-	       totalram_pages << (PAGE_SHIFT-10),
-	       codepages << (PAGE_SHIFT-10),
-	       datapages << (PAGE_SHIFT-10),
-	       initpages << (PAGE_SHIFT-10));
+void __init mem_init(void)
+{
+	/* this will put all memory onto the freelists */
+	free_all_bootmem();
+	init_pointer_tables();
+	mem_init_print_info(NULL);
 	print_memmap();
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/platform/coldfire/pci.c linux-libre-3.11-rc7-gnu/arch/m68k/platform/coldfire/pci.c
--- linux-libre-3.10-gnu/arch/m68k/platform/coldfire/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/platform/coldfire/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -320,7 +320,6 @@ static int __init mcf_pci_init(void)
 	pci_bus_size_bridges(rootbus);
 	pci_bus_assign_resources(rootbus);
 	pci_enable_bridges(rootbus);
-	pci_bus_add_devices(rootbus);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/m68k/sun3/sun3dvma.c linux-libre-3.11-rc7-gnu/arch/m68k/sun3/sun3dvma.c
--- linux-libre-3.10-gnu/arch/m68k/sun3/sun3dvma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/m68k/sun3/sun3dvma.c	2013-08-25 20:43:22.000000000 -0400
@@ -275,7 +275,7 @@ void dvma_init(void)
 
 }
 
-inline unsigned long dvma_map_align(unsigned long kaddr, int len, int align)
+unsigned long dvma_map_align(unsigned long kaddr, int len, int align)
 {
 
 	unsigned long baddr;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/boot/dts/Makefile linux-libre-3.11-rc7-gnu/arch/metag/boot/dts/Makefile
--- linux-libre-3.10-gnu/arch/metag/boot/dts/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/boot/dts/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,9 @@
 dtb-y	+= skeleton.dtb
+dtb-y	+= tz1090_generic.dtb
 
 # Built-in dtb
 builtindtb-y				:= skeleton
+builtindtb-$(CONFIG_SOC_TZ1090)		:= tz1090_generic
 
 ifneq ($(CONFIG_METAG_BUILTIN_DTB_NAME),"")
 	builtindtb-y			:= $(patsubst "%",%,$(CONFIG_METAG_BUILTIN_DTB_NAME))
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/boot/dts/skeleton.dts linux-libre-3.11-rc7-gnu/arch/metag/boot/dts/skeleton.dts
--- linux-libre-3.10-gnu/arch/metag/boot/dts/skeleton.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/boot/dts/skeleton.dts	2013-08-25 20:43:22.000000000 -0400
@@ -7,4 +7,4 @@
  */
 /dts-v1/;
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/boot/dts/tz1090.dtsi linux-libre-3.11-rc7-gnu/arch/metag/boot/dts/tz1090.dtsi
--- linux-libre-3.10-gnu/arch/metag/boot/dts/tz1090.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/metag/boot/dts/tz1090.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 Imagination Technologies Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "toumaz,tz1090", "img,meta";
+
+	interrupt-parent = <&intc>;
+
+	intc: interrupt-controller {
+		compatible = "img,meta-intc";
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		num-banks = <2>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		pinctrl: pinctrl@02005800 {
+			#gpio-range-cells = <3>;
+			compatible = "img,tz1090-pinctrl";
+			reg = <0x02005800 0xe4>;
+		};
+
+		pdc_pinctrl: pinctrl@02006500 {
+			#gpio-range-cells = <3>;
+			compatible = "img,tz1090-pdc-pinctrl";
+			reg = <0x02006500 0x100>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/boot/dts/tz1090_generic.dts linux-libre-3.11-rc7-gnu/arch/metag/boot/dts/tz1090_generic.dts
--- linux-libre-3.10-gnu/arch/metag/boot/dts/tz1090_generic.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/metag/boot/dts/tz1090_generic.dts	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2012 Imagination Technologies Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "tz1090.dtsi"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/boot/.gitignore linux-libre-3.11-rc7-gnu/arch/metag/boot/.gitignore
--- linux-libre-3.10-gnu/arch/metag/boot/.gitignore	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/boot/.gitignore	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
 vmlinux*
 uImage*
 ramdisk.*
-*.dtb
+*.dtb*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/configs/tz1090_defconfig linux-libre-3.11-rc7-gnu/arch/metag/configs/tz1090_defconfig
--- linux-libre-3.10-gnu/arch/metag/configs/tz1090_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/metag/configs/tz1090_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,42 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_ELF_CORE is not set
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_SOC_TZ1090=y
+CONFIG_METAG_HALT_ON_PANIC=y
+# CONFIG_METAG_FPU is not set
+CONFIG_METAG_DA=y
+CONFIG_HZ_100=y
+CONFIG_DEVTMPFS=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_DA_TTY=y
+CONFIG_DA_CONSOLE=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIOLIB=y
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_INFO=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/include/asm/bug.h linux-libre-3.11-rc7-gnu/arch/metag/include/asm/bug.h
--- linux-libre-3.10-gnu/arch/metag/include/asm/bug.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/include/asm/bug.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
 struct pt_regs;
 
 extern const char *trap_name(int trapno);
-extern void die(const char *str, struct pt_regs *regs, long err,
-		unsigned long addr) __attribute__ ((noreturn));
+extern void __noreturn die(const char *str, struct pt_regs *regs, long err,
+		unsigned long addr);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/include/asm/checksum.h linux-libre-3.11-rc7-gnu/arch/metag/include/asm/checksum.h
--- linux-libre-3.10-gnu/arch/metag/include/asm/checksum.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/include/asm/checksum.h	2013-08-25 20:43:22.000000000 -0400
@@ -64,7 +64,8 @@ static inline __wsum csum_tcpudp_nofold(
 					__wsum sum)
 {
 	unsigned long len_proto = (proto + len) << 8;
-	asm ("ADD    %0, %0, %1\n"
+	asm ("ADDS   %0, %0, %1\n"
+	     "ADDCS  %0, %0, #1\n"
 	     "ADDS   %0, %0, %2\n"
 	     "ADDCS  %0, %0, #1\n"
 	     "ADDS   %0, %0, %3\n"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/include/asm/clock.h linux-libre-3.11-rc7-gnu/arch/metag/include/asm/clock.h
--- linux-libre-3.10-gnu/arch/metag/include/asm/clock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/include/asm/clock.h	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,8 @@
  *			core frequency will be determined like this:
  *			Meta 1: based on loops_per_jiffy.
  *			Meta 2: (EXPAND_TIMER_DIV + 1) MHz.
+ *			If a "core" clock is provided by the device tree, it
+ *			will override this function.
  */
 struct meta_clock_desc {
 	unsigned long		(*get_core_freq)(void);
@@ -27,6 +29,12 @@ struct meta_clock_desc {
 extern struct meta_clock_desc _meta_clock;
 
 /*
+ * Perform platform clock initialisation, reading clocks from device tree etc.
+ * Only accessible during boot.
+ */
+void init_metag_clocks(void);
+
+/*
  * Set up the default clock, ensuring all callbacks are valid - only accessible
  * during boot.
  */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/include/asm/irq.h linux-libre-3.11-rc7-gnu/arch/metag/include/asm/irq.h
--- linux-libre-3.10-gnu/arch/metag/include/asm/irq.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/include/asm/irq.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,7 @@ struct pt_regs;
 
 int tbisig_map(unsigned int hw);
 extern void do_IRQ(int irq, struct pt_regs *regs);
+extern void init_IRQ(void);
 
 #ifdef CONFIG_METAG_SUSPEND_MEM
 int traps_save_context(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/metag/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/metag/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -333,9 +333,6 @@ static inline void update_mmu_cache(stru
 
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-	remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 /*
  * No page table caches to initialise
  */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/include/asm/processor.h linux-libre-3.11-rc7-gnu/arch/metag/include/asm/processor.h
--- linux-libre-3.10-gnu/arch/metag/include/asm/processor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/include/asm/processor.h	2013-08-25 20:43:22.000000000 -0400
@@ -199,4 +199,6 @@ extern void (*soc_halt)(void);
 extern void show_trace(struct task_struct *tsk, unsigned long *sp,
 		       struct pt_regs *regs);
 
+extern const struct seq_operations cpuinfo_op;
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/Kconfig linux-libre-3.11-rc7-gnu/arch/metag/Kconfig
--- linux-libre-3.10-gnu/arch/metag/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,7 @@ config METAG
 	select OF
 	select OF_EARLY_FLATTREE
 	select SPARSE_IRQ
+	select HAVE_DEBUG_STACKOVERFLOW
 
 config STACKTRACE_SUPPORT
 	def_bool y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/metag/Kconfig.debug
--- linux-libre-3.10-gnu/arch/metag/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -6,13 +6,6 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-	help
-	  This option will cause messages to be printed if free stack space
-	  drops below a certain limit.
-
 config 4KSTACKS
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
 	depends on DEBUG_KERNEL
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/Kconfig.soc linux-libre-3.11-rc7-gnu/arch/metag/Kconfig.soc
--- linux-libre-3.10-gnu/arch/metag/Kconfig.soc	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/Kconfig.soc	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,18 @@ config META21_FPGA
 	help
 	  This is a Meta 2.1 FPGA bitstream, just a bare CPU.
 
+config SOC_TZ1090
+	bool "Toumaz Xenif TZ1090 SoC (Comet)"
+	select METAG_LNKGET_AROUND_CACHE
+	select METAG_META21
+	select METAG_SMP_WRITE_REORDERING
+	select PINCTRL
+	select PINCTRL_TZ1090
+	select PINCTRL_TZ1090_PDC
+	help
+	  This is a Toumaz Technology Xenif TZ1090 (A.K.A. Comet) SoC containing
+	  a 2-threaded HTP.
+
 endchoice
 
 menu "SoC configuration"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/cachepart.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/cachepart.c
--- linux-libre-3.10-gnu/arch/metag/kernel/cachepart.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/cachepart.c	2013-08-25 20:43:22.000000000 -0400
@@ -100,22 +100,23 @@ void check_for_cache_aliasing(int thread
 		thread_cache_size =
 				get_thread_cache_size(cache_type, thread_id);
 		if (thread_cache_size < 0)
-			pr_emerg("Can't read %s cache size", \
+			pr_emerg("Can't read %s cache size\n",
 				 cache_type ? "DCACHE" : "ICACHE");
 		else if (thread_cache_size == 0)
 			/* Cache is off. No need to check for aliasing */
 			continue;
 		if (thread_cache_size / CACHE_ASSOCIATIVITY > PAGE_SIZE) {
-			pr_emerg("Cache aliasing detected in %s on Thread %d",
+			pr_emerg("Potential cache aliasing detected in %s on Thread %d\n",
 				 cache_type ? "DCACHE" : "ICACHE", thread_id);
-			pr_warn("Total %s size: %u bytes",
-				cache_type ? "DCACHE" : "ICACHE ",
+			pr_warn("Total %s size: %u bytes\n",
+				cache_type ? "DCACHE" : "ICACHE",
 				cache_type ? get_dcache_size()
 				: get_icache_size());
-			pr_warn("Thread %s size: %d bytes",
+			pr_warn("Thread %s size: %d bytes\n",
 				cache_type ? "CACHE" : "ICACHE",
 				thread_cache_size);
-			pr_warn("Page Size: %lu bytes", PAGE_SIZE);
+			pr_warn("Page Size: %lu bytes\n", PAGE_SIZE);
+			panic("Potential cache aliasing detected");
 		}
 	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/clock.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/clock.c
--- linux-libre-3.10-gnu/arch/metag/kernel/clock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/clock.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,8 +8,10 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/of.h>
 
 #include <asm/param.h>
 #include <asm/clock.h>
@@ -34,8 +36,63 @@ static unsigned long get_core_freq_defau
 #endif
 }
 
+static struct clk *clk_core;
+
+/* Clk based get_core_freq callback. */
+static unsigned long get_core_freq_clk(void)
+{
+	return clk_get_rate(clk_core);
+}
+
 /**
- * setup_meta_clocks() - Set up the Meta clock.
+ * init_metag_core_clock() - Set up core clock from devicetree.
+ *
+ * Checks to see if a "core" clock is provided in the device tree, and overrides
+ * the get_core_freq callback to use it.
+ */
+static void __init init_metag_core_clock(void)
+{
+	/*
+	 * See if a core clock is provided by the devicetree (and
+	 * registered by the init callback above).
+	 */
+	struct device_node *node;
+	node = of_find_compatible_node(NULL, NULL, "img,meta");
+	if (!node) {
+		pr_warn("%s: no compatible img,meta DT node found\n",
+			__func__);
+		return;
+	}
+
+	clk_core = of_clk_get_by_name(node, "core");
+	if (IS_ERR(clk_core)) {
+		pr_warn("%s: no core clock found in DT\n",
+			__func__);
+		return;
+	}
+
+	/*
+	 * Override the core frequency callback to use
+	 * this clk.
+	 */
+	_meta_clock.get_core_freq = get_core_freq_clk;
+}
+
+/**
+ * init_metag_clocks() - Set up clocks from devicetree.
+ *
+ * Set up important clocks from device tree. In particular any needed for clock
+ * sources.
+ */
+void __init init_metag_clocks(void)
+{
+	init_metag_core_clock();
+
+	pr_info("Core clock frequency: %lu Hz\n", get_coreclock());
+}
+
+/**
+ * setup_meta_clocks() - Early set up of the Meta clock.
  * @desc:	Clock descriptor usually provided by machine description
  *
  * Ensures all callbacks are valid.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/irq.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/irq.c
--- linux-libre-3.10-gnu/arch/metag/kernel/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@ static union irq_ctx *hardirq_ctx[NR_CPU
 static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
 #endif
 
-struct irq_domain *root_domain;
+static struct irq_domain *root_domain;
 
 static unsigned int startup_meta_irq(struct irq_data *data)
 {
@@ -279,11 +279,12 @@ static void route_irq(struct irq_data *d
 {
 	struct irq_desc *desc = irq_to_desc(irq);
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
+	unsigned long flags;
 
-	raw_spin_lock_irq(&desc->lock);
+	raw_spin_lock_irqsave(&desc->lock, flags);
 	if (chip->irq_set_affinity)
 		chip->irq_set_affinity(data, cpumask_of(cpu), false);
-	raw_spin_unlock_irq(&desc->lock);
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/kick.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/kick.c
--- linux-libre-3.10-gnu/arch/metag/kernel/kick.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/kick.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,8 @@
  * pass it as an argument.
  */
 #include <linux/export.h>
+#include <linux/hardirq.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/types.h>
@@ -66,6 +68,7 @@ EXPORT_SYMBOL(kick_unregister_func);
 TBIRES
 kick_handler(TBIRES State, int SigNum, int Triggers, int Inst, PTBI pTBI)
 {
+	struct pt_regs *old_regs;
 	struct kick_irq_handler *kh;
 	struct list_head *lh;
 	int handled = 0;
@@ -79,6 +82,9 @@ kick_handler(TBIRES State, int SigNum, i
 
 	trace_hardirqs_off();
 
+	old_regs = set_irq_regs((struct pt_regs *)State.Sig.pCtx);
+	irq_enter();
+
 	/*
 	 * There is no need to disable interrupts here because we
 	 * can't nest KICK interrupts in a KICK interrupt handler.
@@ -97,5 +103,8 @@ kick_handler(TBIRES State, int SigNum, i
 
 	WARN_ON(!handled);
 
+	irq_exit();
+	set_irq_regs(old_regs);
+
 	return tail_end(ret);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/metag_ksyms.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/metag_ksyms.c
--- linux-libre-3.10-gnu/arch/metag/kernel/metag_ksyms.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/metag_ksyms.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,7 @@
 #include <linux/export.h>
+#include <linux/types.h>
 
+#include <asm/checksum.h>
 #include <asm/div64.h>
 #include <asm/ftrace.h>
 #include <asm/page.h>
@@ -15,6 +17,9 @@ EXPORT_SYMBOL(max_pfn);
 EXPORT_SYMBOL(min_low_pfn);
 #endif
 
+/* Network checksum functions */
+EXPORT_SYMBOL(csum_partial);
+
 /* TBI symbols */
 EXPORT_SYMBOL(__TBI);
 EXPORT_SYMBOL(__TBIFindSeg);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/perf/perf_event.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/perf/perf_event.c
--- linux-libre-3.10-gnu/arch/metag/kernel/perf/perf_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/perf/perf_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -813,8 +813,8 @@ static struct metag_pmu _metag_pmu = {
 };
 
 /* PMU CPU hotplug notifier */
-static int __cpuinit metag_pmu_cpu_notify(struct notifier_block *b,
-		unsigned long action, void *hcpu)
+static int metag_pmu_cpu_notify(struct notifier_block *b, unsigned long action,
+				void *hcpu)
 {
 	unsigned int cpu = (unsigned int)hcpu;
 	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
@@ -828,7 +828,7 @@ static int __cpuinit metag_pmu_cpu_notif
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata metag_pmu_notifier = {
+static struct notifier_block metag_pmu_notifier = {
 	.notifier_call = metag_pmu_cpu_notify,
 };
 
@@ -882,7 +882,7 @@ static int __init init_hw_perf_events(vo
 	}
 
 	register_cpu_notifier(&metag_pmu_notifier);
-	ret = perf_pmu_register(&pmu, (char *)metag_pmu->name, PERF_TYPE_RAW);
+	ret = perf_pmu_register(&pmu, metag_pmu->name, PERF_TYPE_RAW);
 out:
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/setup.c
--- linux-libre-3.10-gnu/arch/metag/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/memblock.h>
 #include <linux/mm.h>
 #include <linux/of_fdt.h>
+#include <linux/of_platform.h>
 #include <linux/pfn.h>
 #include <linux/root_dev.h>
 #include <linux/sched.h>
@@ -424,6 +425,9 @@ static int __init customize_machine(void
 	/* customizes platform devices, or adds new ones */
 	if (machine_desc->init_machine)
 		machine_desc->init_machine();
+	else
+		of_platform_populate(NULL, of_default_bus_match_table, NULL,
+				     NULL);
 	return 0;
 }
 arch_initcall(customize_machine);
@@ -587,20 +591,20 @@ PTBI pTBI_get(unsigned int cpu)
 EXPORT_SYMBOL(pTBI_get);
 
 #if defined(CONFIG_METAG_DSP) && defined(CONFIG_METAG_FPU)
-char capabilites[] = "dsp fpu";
+static char capabilities[] = "dsp fpu";
 #elif defined(CONFIG_METAG_DSP)
-char capabilites[] = "dsp";
+static char capabilities[] = "dsp";
 #elif defined(CONFIG_METAG_FPU)
-char capabilites[] = "fpu";
+static char capabilities[] = "fpu";
 #else
-char capabilites[] = "";
+static char capabilities[] = "";
 #endif
 
 static struct ctl_table caps_kern_table[] = {
 	{
 		.procname	= "capabilities",
-		.data		= capabilites,
-		.maxlen		= sizeof(capabilites),
+		.data		= capabilities,
+		.maxlen		= sizeof(capabilities),
 		.mode		= 0444,
 		.proc_handler	= proc_dostring,
 	},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/smp.c
--- linux-libre-3.10-gnu/arch/metag/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/atomic.h>
+#include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
@@ -62,10 +63,12 @@ static DEFINE_PER_CPU(struct ipi_data, i
 
 static DEFINE_SPINLOCK(boot_lock);
 
+static DECLARE_COMPLETION(cpu_running);
+
 /*
  * "thread" is assumed to be a valid Meta hardware thread ID.
  */
-int __cpuinit boot_secondary(unsigned int thread, struct task_struct *idle)
+int boot_secondary(unsigned int thread, struct task_struct *idle)
 {
 	u32 val;
 
@@ -115,11 +118,9 @@ int __cpuinit boot_secondary(unsigned in
  * If the cache partition has changed, prints a message to the log describing
  * those changes.
  */
-static __cpuinit void describe_cachepart_change(unsigned int thread,
-						const char *label,
-						unsigned int sz,
-						unsigned int old,
-						unsigned int new)
+static void describe_cachepart_change(unsigned int thread, const char *label,
+				      unsigned int sz, unsigned int old,
+				      unsigned int new)
 {
 	unsigned int lor1, land1, gor1, gand1;
 	unsigned int lor2, land2, gor2, gand2;
@@ -167,7 +168,7 @@ static __cpuinit void describe_cachepart
  * Ensures that coherency is enabled and that the threads share the same cache
  * partitions.
  */
-static __cpuinit void setup_smp_cache(unsigned int thread)
+static void setup_smp_cache(unsigned int thread)
 {
 	unsigned int this_thread, lflags;
 	unsigned int dcsz, dcpart_this, dcpart_old, dcpart_new;
@@ -212,7 +213,7 @@ static __cpuinit void setup_smp_cache(un
 				  icpart_old, icpart_new);
 }
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle)
+int __cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned int thread = cpu_2_hwthread_id[cpu];
 	int ret;
@@ -235,20 +236,12 @@ int __cpuinit __cpu_up(unsigned int cpu,
 	 */
 	ret = boot_secondary(thread, idle);
 	if (ret == 0) {
-		unsigned long timeout;
-
 		/*
 		 * CPU was successfully started, wait for it
 		 * to come online or time out.
 		 */
-		timeout = jiffies + HZ;
-		while (time_before(jiffies, timeout)) {
-			if (cpu_online(cpu))
-				break;
-
-			udelay(10);
-			barrier();
-		}
+		wait_for_completion_timeout(&cpu_running,
+					    msecs_to_jiffies(1000));
 
 		if (!cpu_online(cpu))
 			ret = -EIO;
@@ -273,10 +266,9 @@ static DECLARE_COMPLETION(cpu_killed);
 /*
  * __cpu_disable runs on the processor to be shutdown.
  */
-int __cpuexit __cpu_disable(void)
+int __cpu_disable(void)
 {
 	unsigned int cpu = smp_processor_id();
-	struct task_struct *p;
 
 	/*
 	 * Take this CPU offline.  Once we clear this, we can't return,
@@ -296,12 +288,7 @@ int __cpuexit __cpu_disable(void)
 	flush_cache_all();
 	local_flush_tlb_all();
 
-	read_lock(&tasklist_lock);
-	for_each_process(p) {
-		if (p->mm)
-			cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
-	}
-	read_unlock(&tasklist_lock);
+	clear_tasks_mm_cpumask(cpu);
 
 	return 0;
 }
@@ -310,7 +297,7 @@ int __cpuexit __cpu_disable(void)
  * called on the thread which is asking for a CPU to be shutdown -
  * waits until shutdown has completed, or it is timed out.
  */
-void __cpuexit __cpu_die(unsigned int cpu)
+void __cpu_die(unsigned int cpu)
 {
 	if (!wait_for_completion_timeout(&cpu_killed, msecs_to_jiffies(1)))
 		pr_err("CPU%u: unable to kill\n", cpu);
@@ -322,7 +309,7 @@ void __cpuexit __cpu_die(unsigned int cp
  * Note that we do not return from this function. If this cpu is
  * brought online again it will need to run secondary_startup().
  */
-void __cpuexit cpu_die(void)
+void cpu_die(void)
 {
 	local_irq_disable();
 	idle_task_exit();
@@ -337,7 +324,7 @@ void __cpuexit cpu_die(void)
  * Called by both boot and secondaries to move global data into
  * per-processor storage.
  */
-void __cpuinit smp_store_cpu_info(unsigned int cpuid)
+void smp_store_cpu_info(unsigned int cpuid)
 {
 	struct cpuinfo_metag *cpu_info = &per_cpu(cpu_data, cpuid);
 
@@ -385,12 +372,7 @@ asmlinkage void secondary_start_kernel(v
 
 	setup_priv();
 
-	/*
-	 * Enable local interrupts.
-	 */
-	tbi_startup_interrupt(TBID_SIGNUM_TRT);
 	notify_cpu_starting(cpu);
-	local_irq_enable();
 
 	pr_info("CPU%u (thread %u): Booted secondary processor\n",
 		cpu, cpu_2_hwthread_id[cpu]);
@@ -402,12 +384,13 @@ asmlinkage void secondary_start_kernel(v
 	 * OK, now it's safe to let the boot CPU continue
 	 */
 	set_cpu_online(cpu, true);
+	complete(&cpu_running);
 
 	/*
-	 * Check for cache aliasing.
-	 * Preemption is disabled
+	 * Enable local interrupts.
 	 */
-	check_for_cache_aliasing(cpu);
+	tbi_startup_interrupt(TBID_SIGNUM_TRT);
+	local_irq_enable();
 
 	/*
 	 * OK, it's off to the idle thread for us
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/time.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/time.c
--- linux-libre-3.10-gnu/arch/metag/kernel/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -5,11 +5,21 @@
  *
  */
 
-#include <linux/init.h>
-
 #include <clocksource/metag_generic.h>
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <asm/clock.h>
 
 void __init time_init(void)
 {
+#ifdef CONFIG_COMMON_CLK
+	/* Init clocks from device tree */
+	of_clk_init(NULL);
+#endif
+
+	/* Init meta clocks, particularly the core clock */
+	init_metag_clocks();
+
+	/* Set up the timer clock sources */
 	metag_generic_timer_init();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/metag/kernel/traps.c
--- linux-libre-3.10-gnu/arch/metag/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,6 +33,7 @@
 #include <asm/siginfo.h>
 #include <asm/traps.h>
 #include <asm/hwthread.h>
+#include <asm/setup.h>
 #include <asm/switch.h>
 #include <asm/user_gateway.h>
 #include <asm/syscall.h>
@@ -87,8 +88,8 @@ const char *trap_name(int trapno)
 
 static DEFINE_SPINLOCK(die_lock);
 
-void die(const char *str, struct pt_regs *regs, long err,
-	 unsigned long addr)
+void __noreturn die(const char *str, struct pt_regs *regs,
+		    long err, unsigned long addr)
 {
 	static int die_counter;
 
@@ -811,7 +812,7 @@ static void set_trigger_mask(unsigned in
 }
 #endif
 
-void __cpuinit per_cpu_trap_init(unsigned long cpu)
+void per_cpu_trap_init(unsigned long cpu)
 {
 	TBIRES int_context;
 	unsigned int thread = cpu_2_hwthread_id[cpu];
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/lib/checksum.c linux-libre-3.11-rc7-gnu/arch/metag/lib/checksum.c
--- linux-libre-3.10-gnu/arch/metag/lib/checksum.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/lib/checksum.c	2013-08-25 20:43:22.000000000 -0400
@@ -124,7 +124,6 @@ __wsum csum_partial(const void *buff, in
 		result += 1;
 	return (__force __wsum)result;
 }
-EXPORT_SYMBOL(csum_partial);
 
 /*
  * this routine is used for miscellaneous IP-like checksums, mainly
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/Makefile linux-libre-3.11-rc7-gnu/arch/metag/Makefile
--- linux-libre-3.10-gnu/arch/metag/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -20,7 +20,7 @@ checkflags-$(CONFIG_METAG_META12)	+= -DM
 checkflags-$(CONFIG_METAG_META21)	+= -DMETAC_2_1
 CHECKFLAGS				+= -D__metag__ $(checkflags-y)
 
-KBUILD_DEFCONFIG			:= meta2_defconfig
+KBUILD_DEFCONFIG			:= tz1090_defconfig
 
 sflags-$(CONFIG_METAG_META12)		+= -mmetac=1.2
 ifeq ($(CONFIG_METAG_META12),y)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/mm/cache.c linux-libre-3.11-rc7-gnu/arch/metag/mm/cache.c
--- linux-libre-3.10-gnu/arch/metag/mm/cache.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/mm/cache.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,7 +45,7 @@ static volatile u32 lnkget_testdata[16]
 
 #define LNKGET_CONSTANT 0xdeadbeef
 
-void __init metag_lnkget_probe(void)
+static void __init metag_lnkget_probe(void)
 {
 	int temp;
 	long flags;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/mm/fault.c linux-libre-3.11-rc7-gnu/arch/metag/mm/fault.c
--- linux-libre-3.10-gnu/arch/metag/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -224,8 +224,10 @@ do_sigbus:
 	 */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	if (user_mode(regs))
-		do_group_exit(SIGKILL);
+	if (user_mode(regs)) {
+		pagefault_out_of_memory();
+		return 1;
+	}
 
 no_context:
 	/* Are we prepared to handle this kernel fault?  */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/metag/mm/init.c linux-libre-3.11-rc7-gnu/arch/metag/mm/init.c
--- linux-libre-3.10-gnu/arch/metag/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/metag/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -376,34 +376,21 @@ void __init paging_init(unsigned long me
 
 void __init mem_init(void)
 {
-	int nid;
-
 #ifdef CONFIG_HIGHMEM
 	unsigned long tmp;
+
+	/*
+	 * Explicitly reset zone->managed_pages because highmem pages are
+	 * freed before calling free_all_bootmem();
+	 */
+	reset_all_zones_managed_pages();
 	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++)
 		free_highmem_page(pfn_to_page(tmp));
-	num_physpages += totalhigh_pages;
 #endif /* CONFIG_HIGHMEM */
 
-	for_each_online_node(nid) {
-		pg_data_t *pgdat = NODE_DATA(nid);
-		unsigned long node_pages = 0;
-
-		num_physpages += pgdat->node_present_pages;
-
-		if (pgdat->node_spanned_pages)
-			node_pages = free_all_bootmem_node(pgdat);
-
-		totalram_pages += node_pages;
-	}
-
-	pr_info("Memory: %luk/%luk available\n",
-		(unsigned long)nr_free_pages() << (PAGE_SHIFT - 10),
-		num_physpages << (PAGE_SHIFT - 10));
-
+	free_all_bootmem();
+	mem_init_print_info(NULL);
 	show_mem(0);
-
-	return;
 }
 
 void free_initmem(void)
@@ -414,7 +401,8 @@ void free_initmem(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd");
+	free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
+			   "initrd");
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/microblaze/configs/mmu_defconfig linux-libre-3.11-rc7-gnu/arch/microblaze/configs/mmu_defconfig
--- linux-libre-3.10-gnu/arch/microblaze/configs/mmu_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/microblaze/configs/mmu_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_FHANDLE=y
@@ -81,6 +80,9 @@ CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_SLAB=y
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_INFO=y
+CONFIG_KGDB=y
+CONFIG_KGDB_TESTS=y
+CONFIG_KGDB_KDB=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_KEYS=y
 CONFIG_ENCRYPTED_KEYS=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/microblaze/include/asm/page.h linux-libre-3.11-rc7-gnu/arch/microblaze/include/asm/page.h
--- linux-libre-3.10-gnu/arch/microblaze/include/asm/page.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/microblaze/include/asm/page.h	2013-08-25 20:43:22.000000000 -0400
@@ -168,7 +168,6 @@ extern int page_is_ram(unsigned long pfn
 #  else /* CONFIG_MMU */
 #  define ARCH_PFN_OFFSET	(memory_start >> PAGE_SHIFT)
 #  define pfn_valid(pfn)	((pfn) < (max_mapnr + ARCH_PFN_OFFSET))
-#  define VALID_PAGE(page) 	((page - mem_map) < max_mapnr)
 #  endif /* CONFIG_MMU */
 
 # endif /* __ASSEMBLY__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/microblaze/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/microblaze/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/microblaze/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/microblaze/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,9 +13,6 @@
 
 #include <asm/setup.h>
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #ifndef __ASSEMBLY__
 extern int mem_init_done;
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/microblaze/include/asm/uaccess.h linux-libre-3.11-rc7-gnu/arch/microblaze/include/asm/uaccess.h
--- linux-libre-3.10-gnu/arch/microblaze/include/asm/uaccess.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/microblaze/include/asm/uaccess.h	2013-08-25 20:43:22.000000000 -0400
@@ -145,7 +145,7 @@ static inline unsigned long __must_check
 static inline unsigned long __must_check clear_user(void __user *to,
 							unsigned long n)
 {
-	might_sleep();
+	might_fault();
 	if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
 		return n;
 
@@ -371,7 +371,7 @@ extern long __user_bad(void);
 static inline long copy_from_user(void *to,
 		const void __user *from, unsigned long n)
 {
-	might_sleep();
+	might_fault();
 	if (access_ok(VERIFY_READ, from, n))
 		return __copy_from_user(to, from, n);
 	return n;
@@ -385,7 +385,7 @@ static inline long copy_from_user(void *
 static inline long copy_to_user(void __user *to,
 		const void *from, unsigned long n)
 {
-	might_sleep();
+	might_fault();
 	if (access_ok(VERIFY_WRITE, to, n))
 		return __copy_to_user(to, from, n);
 	return n;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/microblaze/include/asm/unistd.h linux-libre-3.11-rc7-gnu/arch/microblaze/include/asm/unistd.h
--- linux-libre-3.10-gnu/arch/microblaze/include/asm/unistd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/microblaze/include/asm/unistd.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,4 +38,7 @@
 #define __ARCH_WANT_SYS_FORK
 
 #endif /* __ASSEMBLY__ */
+
+#define __NR_syscalls         381
+
 #endif /* _ASM_MICROBLAZE_UNISTD_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/microblaze/include/uapi/asm/unistd.h linux-libre-3.11-rc7-gnu/arch/microblaze/include/uapi/asm/unistd.h
--- linux-libre-3.10-gnu/arch/microblaze/include/uapi/asm/unistd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/microblaze/include/uapi/asm/unistd.h	2013-08-25 20:43:22.000000000 -0400
@@ -397,6 +397,4 @@
 #define __NR_kcmp		379
 #define __NR_finit_module	380
 
-#define __NR_syscalls		381
-
 #endif /* _UAPI_ASM_MICROBLAZE_UNISTD_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/microblaze/Kconfig linux-libre-3.11-rc7-gnu/arch/microblaze/Kconfig
--- linux-libre-3.10-gnu/arch/microblaze/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/microblaze/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,7 @@ config MICROBLAZE
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_IDLE_POLL_SETUP
 	select MODULES_USE_ELF_RELA
-	select CLONE_BACKWARDS
+	select CLONE_BACKWARDS3
 
 config SWAP
 	def_bool n
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/microblaze/kernel/kgdb.c linux-libre-3.11-rc7-gnu/arch/microblaze/kernel/kgdb.c
--- linux-libre-3.10-gnu/arch/microblaze/kernel/kgdb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/microblaze/kernel/kgdb.c	2013-08-25 20:43:22.000000000 -0400
@@ -141,7 +141,7 @@ void kgdb_arch_exit(void)
 /*
  * Global data
  */
-const struct kgdb_arch arch_kgdb_ops = {
+struct kgdb_arch arch_kgdb_ops = {
 #ifdef __MICROBLAZEEL__
 	.gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */
 #else
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/microblaze/mm/init.c linux-libre-3.11-rc7-gnu/arch/microblaze/mm/init.c
--- linux-libre-3.10-gnu/arch/microblaze/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/microblaze/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -71,24 +71,17 @@ static void __init highmem_init(void)
 	kmap_prot = PAGE_KERNEL;
 }
 
-static unsigned long highmem_setup(void)
+static void highmem_setup(void)
 {
 	unsigned long pfn;
-	unsigned long reservedpages = 0;
 
 	for (pfn = max_low_pfn; pfn < max_pfn; ++pfn) {
 		struct page *page = pfn_to_page(pfn);
 
 		/* FIXME not sure about */
-		if (memblock_is_reserved(pfn << PAGE_SHIFT))
-			continue;
-		free_highmem_page(page);
-		reservedpages++;
+		if (!memblock_is_reserved(pfn << PAGE_SHIFT))
+			free_highmem_page(page);
 	}
-	pr_info("High memory: %luk\n",
-					totalhigh_pages << (PAGE_SHIFT-10));
-
-	return reservedpages;
 }
 #endif /* CONFIG_HIGHMEM */
 
@@ -167,13 +160,12 @@ void __init setup_memory(void)
 	 * min_low_pfn - the first page (mm/bootmem.c - node_boot_start)
 	 * max_low_pfn
 	 * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn)
-	 * num_physpages - number of all pages
 	 */
 
 	/* memory start is from the kernel end (aligned) to higher addr */
 	min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */
 	/* RAM is assumed contiguous */
-	num_physpages = max_mapnr = memory_size >> PAGE_SHIFT;
+	max_mapnr = memory_size >> PAGE_SHIFT;
 	max_low_pfn = ((u64)memory_start + (u64)lowmem_size) >> PAGE_SHIFT;
 	max_pfn = ((u64)memory_start + (u64)memory_size) >> PAGE_SHIFT;
 
@@ -235,57 +227,26 @@ void __init setup_memory(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
 
 void free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
 
 void __init mem_init(void)
 {
-	pg_data_t *pgdat;
-	unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
-
 	high_memory = (void *)__va(memory_start + lowmem_size - 1);
 
 	/* this will put all memory onto the freelists */
-	totalram_pages += free_all_bootmem();
-
-	for_each_online_pgdat(pgdat) {
-		unsigned long i;
-		struct page *page;
-
-		for (i = 0; i < pgdat->node_spanned_pages; i++) {
-			if (!pfn_valid(pgdat->node_start_pfn + i))
-				continue;
-			page = pgdat_page_nr(pgdat, i);
-			if (PageReserved(page))
-				reservedpages++;
-		}
-	}
-
+	free_all_bootmem();
 #ifdef CONFIG_HIGHMEM
-	reservedpages -= highmem_setup();
+	highmem_setup();
 #endif
 
-	codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
-	datasize = (unsigned long)&_edata - (unsigned long)&_sdata;
-	initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
-	bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
-
-	pr_info("Memory: %luk/%luk available (%luk kernel code, ",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10);
-	pr_cont("%luk reserved, %luk data, %luk bss, %luk init)\n",
-		reservedpages << (PAGE_SHIFT-10),
-		datasize >> 10,
-		bsssize >> 10,
-		initsize >> 10);
-
+	mem_init_print_info(NULL);
 #ifdef CONFIG_MMU
 	pr_info("Kernel virtual memory layout:\n");
 	pr_info("  * 0x%08lx..0x%08lx  : fixmap\n", FIXADDR_START, FIXADDR_TOP);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/ath79/mach-ap136.c linux-libre-3.11-rc7-gnu/arch/mips/ath79/mach-ap136.c
--- linux-libre-3.10-gnu/arch/mips/ath79/mach-ap136.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/ath79/mach-ap136.c	2013-08-25 20:43:22.000000000 -0400
@@ -132,7 +132,7 @@ static void __init ap136_pci_init(u8 *ee
 	ath79_register_pci();
 }
 #else
-static inline void ap136_pci_init(void) {}
+static inline void ap136_pci_init(u8 *eeprom) {}
 #endif /* CONFIG_PCI */
 
 static void __init ap136_setup(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/ath79/setup.c linux-libre-3.11-rc7-gnu/arch/mips/ath79/setup.c
--- linux-libre-3.10-gnu/arch/mips/ath79/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/ath79/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -182,7 +182,7 @@ const char *get_system_type(void)
 	return ath79_sys_type;
 }
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
 	return CP0_LEGACY_COMPARE_IRQ;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm47xx/Kconfig linux-libre-3.11-rc7-gnu/arch/mips/bcm47xx/Kconfig
--- linux-libre-3.10-gnu/arch/mips/bcm47xx/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm47xx/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,6 @@ if BCM47XX
 
 config BCM47XX_SSB
 	bool "SSB Support for Broadcom BCM47XX"
-	select SYS_HAS_CPU_MIPS32_R1
 	select SSB
 	select SSB_DRIVER_MIPS
 	select SSB_DRIVER_EXTIF
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/boards/board_bcm963xx.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/boards/board_bcm963xx.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/boards/board_bcm963xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/boards/board_bcm963xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,11 +28,47 @@
 #include <bcm63xx_dev_usb_usbd.h>
 #include <board_bcm963xx.h>
 
+#include <uapi/linux/bcm933xx_hcs.h>
+
 #define PFX	"board_bcm963xx: "
 
+#define HCS_OFFSET_128K			0x20000
+
 static struct board_info board;
 
 /*
+ * known 3368 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_3368
+static struct board_info __initdata board_cvg834g = {
+	.name				= "CVG834G_E15R3921",
+	.expected_cpu_id		= 0x3368,
+
+	.has_uart0			= 1,
+	.has_uart1			= 1,
+
+	.has_enet0			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+
+	.leds = {
+		{
+			.name		= "CVG834G:green:power",
+			.gpio		= 37,
+			.default_trigger= "default-on",
+		},
+	},
+
+	.ephy_reset_gpio		= 36,
+	.ephy_reset_gpio_flags		= GPIOF_INIT_HIGH,
+};
+#endif
+
+/*
  * known 6328 boards
  */
 #ifdef CONFIG_BCM63XX_CPU_6328
@@ -639,6 +675,9 @@ static struct board_info __initdata boar
  * all boards
  */
 static const struct board_info __initconst *bcm963xx_boards[] = {
+#ifdef CONFIG_BCM63XX_CPU_3368
+	&board_cvg834g,
+#endif
 #ifdef CONFIG_BCM63XX_CPU_6328
 	&board_96328avng,
 #endif
@@ -722,8 +761,9 @@ void __init board_prom_init(void)
 	unsigned int i;
 	u8 *boot_addr, *cfe;
 	char cfe_version[32];
-	char *board_name;
+	char *board_name = NULL;
 	u32 val;
+	struct bcm_hcs *hcs;
 
 	/* read base address of boot chip select (0)
 	 * 6328/6362 do not have MPI but boot from a fixed address
@@ -747,7 +787,12 @@ void __init board_prom_init(void)
 
 	bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);
 
-	board_name = bcm63xx_nvram_get_name();
+	if (BCMCPU_IS_3368()) {
+		hcs = (struct bcm_hcs *)boot_addr;
+		board_name = hcs->filename;
+	} else {
+		board_name = bcm63xx_nvram_get_name();
+	}
 	/* find board by name */
 	for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
 		if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
@@ -845,6 +890,10 @@ int __init board_register_devices(void)
 	    !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr))
 		bcm63xx_enet_register(1, &board.enet1);
 
+	if (board.has_enetsw &&
+	    !bcm63xx_nvram_get_mac_address(board.enetsw.mac_addr))
+		bcm63xx_enetsw_register(&board.enetsw);
+
 	if (board.has_usbd)
 		bcm63xx_usbd_register(&board.usbd);
 
@@ -873,5 +922,9 @@ int __init board_register_devices(void)
 
 	platform_device_register(&bcm63xx_gpio_leds);
 
+	if (board.ephy_reset_gpio && board.ephy_reset_gpio_flags)
+		gpio_request_one(board.ephy_reset_gpio,
+				board.ephy_reset_gpio_flags, "ephy-reset");
+
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/clk.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/clk.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/clk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/clk.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,7 +84,7 @@ static void enetx_set(struct clk *clk, i
 	else
 		clk_disable_unlocked(&clk_enet_misc);
 
-	if (BCMCPU_IS_6358()) {
+	if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
 		u32 mask;
 
 		if (clk->id == 0)
@@ -110,9 +110,8 @@ static struct clk clk_enet1 = {
  */
 static void ephy_set(struct clk *clk, int enable)
 {
-	if (!BCMCPU_IS_6358())
-		return;
-	bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
+	if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
+		bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
 }
 
 
@@ -155,9 +154,10 @@ static struct clk clk_enetsw = {
  */
 static void pcm_set(struct clk *clk, int enable)
 {
-	if (!BCMCPU_IS_6358())
-		return;
-	bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
+	if (BCMCPU_IS_3368())
+		bcm_hwclock_set(CKCTL_3368_PCM_EN, enable);
+	if (BCMCPU_IS_6358())
+		bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
 }
 
 static struct clk clk_pcm = {
@@ -211,7 +211,7 @@ static void spi_set(struct clk *clk, int
 		mask = CKCTL_6338_SPI_EN;
 	else if (BCMCPU_IS_6348())
 		mask = CKCTL_6348_SPI_EN;
-	else if (BCMCPU_IS_6358())
+	else if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
 		mask = CKCTL_6358_SPI_EN;
 	else if (BCMCPU_IS_6362())
 		mask = CKCTL_6362_SPI_EN;
@@ -318,6 +318,18 @@ unsigned long clk_get_rate(struct clk *c
 
 EXPORT_SYMBOL(clk_get_rate);
 
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	return 0;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	return 0;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
 struct clk *clk_get(struct device *dev, const char *id)
 {
 	if (!strcmp(id, "enet0"))
@@ -338,7 +350,7 @@ struct clk *clk_get(struct device *dev,
 		return &clk_xtm;
 	if (!strcmp(id, "periph"))
 		return &clk_periph;
-	if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
+	if ((BCMCPU_IS_3368() || BCMCPU_IS_6358()) && !strcmp(id, "pcm"))
 		return &clk_pcm;
 	if ((BCMCPU_IS_6362() || BCMCPU_IS_6368()) && !strcmp(id, "ipsec"))
 		return &clk_ipsec;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/cpu.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/cpu.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/cpu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/cpu.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,14 @@ static u8 bcm63xx_cpu_rev;
 static unsigned int bcm63xx_cpu_freq;
 static unsigned int bcm63xx_memory_size;
 
+static const unsigned long bcm3368_regs_base[] = {
+	__GEN_CPU_REGS_TABLE(3368)
+};
+
+static const int bcm3368_irqs[] = {
+	__GEN_CPU_IRQ_TABLE(3368)
+};
+
 static const unsigned long bcm6328_regs_base[] = {
 	__GEN_CPU_REGS_TABLE(6328)
 };
@@ -116,6 +124,9 @@ unsigned int bcm63xx_get_memory_size(voi
 static unsigned int detect_cpu_clock(void)
 {
 	switch (bcm63xx_get_cpu_id()) {
+	case BCM3368_CPU_ID:
+		return 300000000;
+
 	case BCM6328_CPU_ID:
 	{
 		unsigned int tmp, mips_pll_fcvo;
@@ -266,7 +277,7 @@ static unsigned int detect_memory_size(v
 		banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
 	}
 
-	if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
+	if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
 		val = bcm_memc_readl(MEMC_CFG_REG);
 		rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
 		cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
@@ -302,10 +313,17 @@ void __init bcm63xx_cpu_init(void)
 		chipid_reg = BCM_6345_PERF_BASE;
 		break;
 	case CPU_BMIPS4350:
-		if ((read_c0_prid() & 0xf0) == 0x10)
+		switch ((read_c0_prid() & 0xff)) {
+		case 0x04:
+			chipid_reg = BCM_3368_PERF_BASE;
+			break;
+		case 0x10:
 			chipid_reg = BCM_6345_PERF_BASE;
-		else
+			break;
+		default:
 			chipid_reg = BCM_6368_PERF_BASE;
+			break;
+		}
 		break;
 	}
 
@@ -322,6 +340,10 @@ void __init bcm63xx_cpu_init(void)
 	bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT;
 
 	switch (bcm63xx_cpu_id) {
+	case BCM3368_CPU_ID:
+		bcm63xx_regs_base = bcm3368_regs_base;
+		bcm63xx_irqs = bcm3368_irqs;
+		break;
 	case BCM6328_CPU_ID:
 		bcm63xx_regs_base = bcm6328_regs_base;
 		bcm63xx_irqs = bcm6328_irqs;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/dev-enet.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/dev-enet.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/dev-enet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/dev-enet.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,16 +9,60 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/export.h>
 #include <bcm63xx_dev_enet.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_regs.h>
 
+#ifdef BCMCPU_RUNTIME_DETECT
+static const unsigned long bcm6348_regs_enetdmac[] = {
+	[ENETDMAC_CHANCFG]	= ENETDMAC_CHANCFG_REG,
+	[ENETDMAC_IR]		= ENETDMAC_IR_REG,
+	[ENETDMAC_IRMASK]	= ENETDMAC_IRMASK_REG,
+	[ENETDMAC_MAXBURST]	= ENETDMAC_MAXBURST_REG,
+};
+
+static const unsigned long bcm6345_regs_enetdmac[] = {
+	[ENETDMAC_CHANCFG]	= ENETDMA_6345_CHANCFG_REG,
+	[ENETDMAC_IR]		= ENETDMA_6345_IR_REG,
+	[ENETDMAC_IRMASK]	= ENETDMA_6345_IRMASK_REG,
+	[ENETDMAC_MAXBURST]	= ENETDMA_6345_MAXBURST_REG,
+	[ENETDMAC_BUFALLOC]	= ENETDMA_6345_BUFALLOC_REG,
+	[ENETDMAC_RSTART]	= ENETDMA_6345_RSTART_REG,
+	[ENETDMAC_FC]		= ENETDMA_6345_FC_REG,
+	[ENETDMAC_LEN]		= ENETDMA_6345_LEN_REG,
+};
+
+const unsigned long *bcm63xx_regs_enetdmac;
+EXPORT_SYMBOL(bcm63xx_regs_enetdmac);
+
+static __init void bcm63xx_enetdmac_regs_init(void)
+{
+	if (BCMCPU_IS_6345())
+		bcm63xx_regs_enetdmac = bcm6345_regs_enetdmac;
+	else
+		bcm63xx_regs_enetdmac = bcm6348_regs_enetdmac;
+}
+#else
+static __init void bcm63xx_enetdmac_regs_init(void) { }
+#endif
+
 static struct resource shared_res[] = {
 	{
 		.start		= -1, /* filled at runtime */
 		.end		= -1, /* filled at runtime */
 		.flags		= IORESOURCE_MEM,
 	},
+	{
+		.start		= -1, /* filled at runtime */
+		.end		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= -1, /* filled at runtime */
+		.end		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
 };
 
 static struct platform_device bcm63xx_enet_shared_device = {
@@ -94,6 +138,71 @@ static struct platform_device bcm63xx_en
 	},
 };
 
+static struct resource enetsw_res[] = {
+	{
+		/* start & end filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		/* start filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		/* start filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct bcm63xx_enetsw_platform_data enetsw_pd;
+
+static struct platform_device bcm63xx_enetsw_device = {
+	.name		= "bcm63xx_enetsw",
+	.num_resources	= ARRAY_SIZE(enetsw_res),
+	.resource	= enetsw_res,
+	.dev		= {
+		.platform_data = &enetsw_pd,
+	},
+};
+
+static int __init register_shared(void)
+{
+	int ret, chan_count;
+
+	if (shared_device_registered)
+		return 0;
+
+	bcm63xx_enetdmac_regs_init();
+
+	shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
+	shared_res[0].end = shared_res[0].start;
+	if (BCMCPU_IS_6345())
+		shared_res[0].end += (RSET_6345_ENETDMA_SIZE) - 1;
+	else
+		shared_res[0].end += (RSET_ENETDMA_SIZE)  - 1;
+
+	if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368())
+		chan_count = 32;
+	else if (BCMCPU_IS_6345())
+		chan_count = 8;
+	else
+		chan_count = 16;
+
+	shared_res[1].start = bcm63xx_regset_address(RSET_ENETDMAC);
+	shared_res[1].end = shared_res[1].start;
+	shared_res[1].end += RSET_ENETDMAC_SIZE(chan_count)  - 1;
+
+	shared_res[2].start = bcm63xx_regset_address(RSET_ENETDMAS);
+	shared_res[2].end = shared_res[2].start;
+	shared_res[2].end += RSET_ENETDMAS_SIZE(chan_count)  - 1;
+
+	ret = platform_device_register(&bcm63xx_enet_shared_device);
+	if (ret)
+		return ret;
+	shared_device_registered = 1;
+
+	return 0;
+}
+
 int __init bcm63xx_enet_register(int unit,
 				 const struct bcm63xx_enet_platform_data *pd)
 {
@@ -104,22 +213,12 @@ int __init bcm63xx_enet_register(int uni
 	if (unit > 1)
 		return -ENODEV;
 
-	if (unit == 1 && BCMCPU_IS_6338())
+	if (unit == 1 && (BCMCPU_IS_6338() || BCMCPU_IS_6345()))
 		return -ENODEV;
 
-	if (!shared_device_registered) {
-		shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
-		shared_res[0].end = shared_res[0].start;
-		if (BCMCPU_IS_6338())
-			shared_res[0].end += (RSET_ENETDMA_SIZE / 2)  - 1;
-		else
-			shared_res[0].end += (RSET_ENETDMA_SIZE)  - 1;
-
-		ret = platform_device_register(&bcm63xx_enet_shared_device);
-		if (ret)
-			return ret;
-		shared_device_registered = 1;
-	}
+	ret = register_shared();
+	if (ret)
+		return ret;
 
 	if (unit == 0) {
 		enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0);
@@ -155,8 +254,62 @@ int __init bcm63xx_enet_register(int uni
 		dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY);
 	}
 
+	dpd->dma_chan_en_mask = ENETDMAC_CHANCFG_EN_MASK;
+	dpd->dma_chan_int_mask = ENETDMAC_IR_PKTDONE_MASK;
+	if (BCMCPU_IS_6345()) {
+		dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_CHAINING_MASK;
+		dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_WRAP_EN_MASK;
+		dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_FLOWC_EN_MASK;
+		dpd->dma_chan_int_mask |= ENETDMA_IR_BUFDONE_MASK;
+		dpd->dma_chan_int_mask |= ENETDMA_IR_NOTOWNER_MASK;
+		dpd->dma_chan_width = ENETDMA_6345_CHAN_WIDTH;
+		dpd->dma_desc_shift = ENETDMA_6345_DESC_SHIFT;
+	} else {
+		dpd->dma_has_sram = true;
+		dpd->dma_chan_width = ENETDMA_CHAN_WIDTH;
+	}
+
 	ret = platform_device_register(pdev);
 	if (ret)
 		return ret;
 	return 0;
 }
+
+int __init
+bcm63xx_enetsw_register(const struct bcm63xx_enetsw_platform_data *pd)
+{
+	int ret;
+
+	if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362() && !BCMCPU_IS_6368())
+		return -ENODEV;
+
+	ret = register_shared();
+	if (ret)
+		return ret;
+
+	enetsw_res[0].start = bcm63xx_regset_address(RSET_ENETSW);
+	enetsw_res[0].end = enetsw_res[0].start;
+	enetsw_res[0].end += RSET_ENETSW_SIZE - 1;
+	enetsw_res[1].start = bcm63xx_get_irq_number(IRQ_ENETSW_RXDMA0);
+	enetsw_res[2].start = bcm63xx_get_irq_number(IRQ_ENETSW_TXDMA0);
+	if (!enetsw_res[2].start)
+		enetsw_res[2].start = -1;
+
+	memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof(*pd));
+
+	if (BCMCPU_IS_6328())
+		enetsw_pd.num_ports = ENETSW_PORTS_6328;
+	else if (BCMCPU_IS_6362() || BCMCPU_IS_6368())
+		enetsw_pd.num_ports = ENETSW_PORTS_6368;
+
+	enetsw_pd.dma_has_sram = true;
+	enetsw_pd.dma_chan_width = ENETDMA_CHAN_WIDTH;
+	enetsw_pd.dma_chan_en_mask = ENETDMAC_CHANCFG_EN_MASK;
+	enetsw_pd.dma_chan_int_mask = ENETDMAC_IR_PKTDONE_MASK;
+
+	ret = platform_device_register(&bcm63xx_enetsw_device);
+	if (ret)
+		return ret;
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/dev-flash.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/dev-flash.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/dev-flash.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/dev-flash.c	2013-08-25 20:43:22.000000000 -0400
@@ -71,6 +71,7 @@ static int __init bcm63xx_detect_flash_t
 	case BCM6348_CPU_ID:
 		/* no way to auto detect so assume parallel */
 		return BCM63XX_FLASH_TYPE_PARALLEL;
+	case BCM3368_CPU_ID:
 	case BCM6358_CPU_ID:
 		val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
 		if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/dev-spi.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/dev-spi.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/dev-spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/dev-spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,8 @@ static __init void bcm63xx_spi_regs_init
 {
 	if (BCMCPU_IS_6338() || BCMCPU_IS_6348())
 		bcm63xx_regs_spi = bcm6348_regs_spi;
-	if (BCMCPU_IS_6358() || BCMCPU_IS_6362() || BCMCPU_IS_6368())
+	if (BCMCPU_IS_3368() || BCMCPU_IS_6358() ||
+		BCMCPU_IS_6362() || BCMCPU_IS_6368())
 		bcm63xx_regs_spi = bcm6358_regs_spi;
 }
 #else
@@ -87,7 +88,8 @@ int __init bcm63xx_spi_register(void)
 		spi_pdata.msg_ctl_width = SPI_6348_MSG_CTL_WIDTH;
 	}
 
-	if (BCMCPU_IS_6358() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) {
+	if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6362() ||
+		BCMCPU_IS_6368()) {
 		spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
 		spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
 		spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/dev-uart.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/dev-uart.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/dev-uart.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/dev-uart.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,8 @@ int __init bcm63xx_uart_register(unsigne
 	if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
 		return -ENODEV;
 
-	if (id == 1 && (!BCMCPU_IS_6358() && !BCMCPU_IS_6368()))
+	if (id == 1 && (!BCMCPU_IS_3368() && !BCMCPU_IS_6358() &&
+		!BCMCPU_IS_6368()))
 		return -ENODEV;
 
 	if (id == 0) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/irq.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/irq.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,17 @@ static void __internal_irq_unmask_32(uns
 static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
 
 #ifndef BCMCPU_RUNTIME_DETECT
+#ifdef CONFIG_BCM63XX_CPU_3368
+#define irq_stat_reg		PERF_IRQSTAT_3368_REG
+#define irq_mask_reg		PERF_IRQMASK_3368_REG
+#define irq_bits		32
+#define is_ext_irq_cascaded	0
+#define ext_irq_start		0
+#define ext_irq_end		0
+#define ext_irq_count		4
+#define ext_irq_cfg_reg1	PERF_EXTIRQ_CFG_REG_3368
+#define ext_irq_cfg_reg2	0
+#endif
 #ifdef CONFIG_BCM63XX_CPU_6328
 #define irq_stat_reg		PERF_IRQSTAT_6328_REG
 #define irq_mask_reg		PERF_IRQMASK_6328_REG
@@ -140,6 +151,13 @@ static void bcm63xx_init_irq(void)
 	irq_mask_addr = bcm63xx_regset_address(RSET_PERF);
 
 	switch (bcm63xx_get_cpu_id()) {
+	case BCM3368_CPU_ID:
+		irq_stat_addr += PERF_IRQSTAT_3368_REG;
+		irq_mask_addr += PERF_IRQMASK_3368_REG;
+		irq_bits = 32;
+		ext_irq_count = 4;
+		ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368;
+		break;
 	case BCM6328_CPU_ID:
 		irq_stat_addr += PERF_IRQSTAT_6328_REG;
 		irq_mask_addr += PERF_IRQMASK_6328_REG;
@@ -294,6 +312,10 @@ asmlinkage void plat_irq_dispatch(void)
 
 		if (cause & CAUSEF_IP7)
 			do_IRQ(7);
+		if (cause & CAUSEF_IP0)
+			do_IRQ(0);
+		if (cause & CAUSEF_IP1)
+			do_IRQ(1);
 		if (cause & CAUSEF_IP2)
 			dispatch_internal();
 		if (!is_ext_irq_cascaded) {
@@ -475,6 +497,7 @@ static int bcm63xx_external_irq_set_type
 			reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
 		break;
 
+	case BCM3368_CPU_ID:
 	case BCM6328_CPU_ID:
 	case BCM6338_CPU_ID:
 	case BCM6345_CPU_ID:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/Kconfig linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/Kconfig
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,10 @@
 menu "CPU support"
 	depends on BCM63XX
 
+config BCM63XX_CPU_3368
+	bool "support 3368 CPU"
+	select HW_HAS_PCI
+
 config BCM63XX_CPU_6328
 	bool "support 6328 CPU"
 	select HW_HAS_PCI
@@ -8,14 +12,9 @@ config BCM63XX_CPU_6328
 config BCM63XX_CPU_6338
 	bool "support 6338 CPU"
 	select HW_HAS_PCI
-	select USB_ARCH_HAS_OHCI
-	select USB_OHCI_BIG_ENDIAN_DESC
-	select USB_OHCI_BIG_ENDIAN_MMIO
 
 config BCM63XX_CPU_6345
 	bool "support 6345 CPU"
-	select USB_OHCI_BIG_ENDIAN_DESC
-	select USB_OHCI_BIG_ENDIAN_MMIO
 
 config BCM63XX_CPU_6348
 	bool "support 6348 CPU"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/nvram.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/nvram.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/nvram.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/nvram.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,6 +42,7 @@ void __init bcm63xx_nvram_init(void *add
 {
 	unsigned int check_len;
 	u32 crc, expected_crc;
+	u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff };
 
 	/* extract nvram data */
 	memcpy(&nvram, addr, sizeof(nvram));
@@ -62,6 +63,15 @@ void __init bcm63xx_nvram_init(void *add
 	if (crc != expected_crc)
 		pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
 			expected_crc, crc);
+
+	/* Cable modems have a different NVRAM which is embedded in the eCos
+	 * firmware and not easily extractible, give at least a MAC address
+	 * pool.
+	 */
+	if (BCMCPU_IS_3368()) {
+		memcpy(nvram.mac_addr_base, hcs_mac_addr, ETH_ALEN);
+		nvram.mac_addr_count = 2;
+	}
 }
 
 u8 *bcm63xx_nvram_get_name(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/prom.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/prom.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/prom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/prom.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,11 @@
 
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/smp.h>
 #include <asm/bootinfo.h>
+#include <asm/bmips.h>
+#include <asm/smp-ops.h>
+#include <asm/mipsregs.h>
 #include <bcm63xx_board.h>
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_io.h>
@@ -26,7 +30,9 @@ void __init prom_init(void)
 	bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
 
 	/* disable all hardware blocks clock for now */
-	if (BCMCPU_IS_6328())
+	if (BCMCPU_IS_3368())
+		mask = CKCTL_3368_ALL_SAFE_EN;
+	else if (BCMCPU_IS_6328())
 		mask = CKCTL_6328_ALL_SAFE_EN;
 	else if (BCMCPU_IS_6338())
 		mask = CKCTL_6338_ALL_SAFE_EN;
@@ -52,6 +58,47 @@ void __init prom_init(void)
 
 	/* do low level board init */
 	board_prom_init();
+
+	if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
+		/* set up SMP */
+		register_smp_ops(&bmips_smp_ops);
+
+		/*
+		 * BCM6328 might not have its second CPU enabled, while BCM6358
+		 * needs special handling for its shared TLB, so disable SMP
+		 * for now.
+		 */
+		if (BCMCPU_IS_6328()) {
+			reg = bcm_readl(BCM_6328_OTP_BASE +
+					OTP_USER_BITS_6328_REG(3));
+
+			if (reg & OTP_6328_REG3_TP1_DISABLED)
+				bmips_smp_enabled = 0;
+		} else if (BCMCPU_IS_6358()) {
+			bmips_smp_enabled = 0;
+		}
+
+		if (!bmips_smp_enabled)
+			return;
+
+		/*
+		 * The bootloader has set up the CPU1 reset vector at
+		 * 0xa000_0200.
+		 * This conflicts with the special interrupt vector (IV).
+		 * The bootloader has also set up CPU1 to respond to the wrong
+		 * IPI interrupt.
+		 * Here we will start up CPU1 in the background and ask it to
+		 * reconfigure itself then go back to sleep.
+		 */
+		memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
+		__sync();
+		set_c0_cause(C_SW0);
+		cpumask_set_cpu(1, &bmips_booted_mask);
+
+		/*
+		 * FIXME: we really should have some sort of hazard barrier here
+		 */
+	}
 }
 
 void __init prom_free_prom_memory(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/reset.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/reset.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/reset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/reset.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,19 @@
 	[BCM63XX_RESET_PCIE]		= BCM## __cpu ##_RESET_PCIE,	\
 	[BCM63XX_RESET_PCIE_EXT]	= BCM## __cpu ##_RESET_PCIE_EXT,
 
+#define BCM3368_RESET_SPI	SOFTRESET_3368_SPI_MASK
+#define BCM3368_RESET_ENET	SOFTRESET_3368_ENET_MASK
+#define BCM3368_RESET_USBH	0
+#define BCM3368_RESET_USBD	SOFTRESET_3368_USBS_MASK
+#define BCM3368_RESET_DSL	0
+#define BCM3368_RESET_SAR	0
+#define BCM3368_RESET_EPHY	SOFTRESET_3368_EPHY_MASK
+#define BCM3368_RESET_ENETSW	0
+#define BCM3368_RESET_PCM	SOFTRESET_3368_PCM_MASK
+#define BCM3368_RESET_MPI	SOFTRESET_3368_MPI_MASK
+#define BCM3368_RESET_PCIE	0
+#define BCM3368_RESET_PCIE_EXT	0
+
 #define BCM6328_RESET_SPI	SOFTRESET_6328_SPI_MASK
 #define BCM6328_RESET_ENET	0
 #define BCM6328_RESET_USBH	SOFTRESET_6328_USBH_MASK
@@ -117,6 +130,10 @@
 /*
  * core reset bits
  */
+static const u32 bcm3368_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(3368)
+};
+
 static const u32 bcm6328_reset_bits[] = {
 	__GEN_RESET_BITS_TABLE(6328)
 };
@@ -146,7 +163,10 @@ static int reset_reg;
 
 static int __init bcm63xx_reset_bits_init(void)
 {
-	if (BCMCPU_IS_6328()) {
+	if (BCMCPU_IS_3368()) {
+		reset_reg = PERF_SOFTRESET_6358_REG;
+		bcm63xx_reset_bits = bcm3368_reset_bits;
+	} else if (BCMCPU_IS_6328()) {
 		reset_reg = PERF_SOFTRESET_6328_REG;
 		bcm63xx_reset_bits = bcm6328_reset_bits;
 	} else if (BCMCPU_IS_6338()) {
@@ -170,6 +190,13 @@ static int __init bcm63xx_reset_bits_ini
 }
 #else
 
+#ifdef CONFIG_BCM63XX_CPU_3368
+static const u32 bcm63xx_reset_bits[] = {
+	__GEN_RESET_BITS_TABLE(3368)
+};
+#define reset_reg PERF_SOFTRESET_6358_REG
+#endif
+
 #ifdef CONFIG_BCM63XX_CPU_6328
 static const u32 bcm63xx_reset_bits[] = {
 	__GEN_RESET_BITS_TABLE(6328)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/bcm63xx/setup.c linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/setup.c
--- linux-libre-3.10-gnu/arch/mips/bcm63xx/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/bcm63xx/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void)
 
 	/* mask and clear all external irq */
 	switch (bcm63xx_get_cpu_id()) {
+	case BCM3368_CPU_ID:
+		perf_regs[0] = PERF_EXTIRQ_CFG_REG_3368;
+		break;
 	case BCM6328_CPU_ID:
 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328;
 		break;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/boot/compressed/Makefile linux-libre-3.11-rc7-gnu/arch/mips/boot/compressed/Makefile
--- linux-libre-3.10-gnu/arch/mips/boot/compressed/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/boot/compressed/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,8 @@ BOOT_HEAP_SIZE := 0x400000
 # Disable Function Tracer
 KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
 
+KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS))
+
 KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
 	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/boot/compressed/uart-16550.c linux-libre-3.11-rc7-gnu/arch/mips/boot/compressed/uart-16550.c
--- linux-libre-3.10-gnu/arch/mips/boot/compressed/uart-16550.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/boot/compressed/uart-16550.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,23 +23,39 @@
 #define PORT(offset) (UART0_BASE + (4 * offset))
 #endif
 
+#ifdef CONFIG_CPU_XLR
+#define UART0_BASE  0x1EF14000
+#define PORT(offset) (CKSEG1ADDR(UART0_BASE) + (4 * offset))
+#define IOTYPE unsigned int
+#endif
+
+#ifdef CONFIG_CPU_XLP
+#define UART0_BASE  0x18030100
+#define PORT(offset) (CKSEG1ADDR(UART0_BASE) + (4 * offset))
+#define IOTYPE unsigned int
+#endif
+
+#ifndef IOTYPE
+#define IOTYPE char
+#endif
+
 #ifndef PORT
 #error please define the serial port address for your own machine
 #endif
 
 static inline unsigned int serial_in(int offset)
 {
-	return *((char *)PORT(offset));
+	return *((volatile IOTYPE *)PORT(offset)) & 0xFF;
 }
 
 static inline void serial_out(int offset, int value)
 {
-	*((char *)PORT(offset)) = value;
+	*((volatile IOTYPE *)PORT(offset)) = value & 0xFF;
 }
 
 void putc(char c)
 {
-	int timeout = 1024;
+	int timeout = 1000000;
 
 	while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0))
 		;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/cavium-octeon/executive/cvmx-helper-board.c linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
--- linux-libre-3.10-gnu/arch/mips/cavium-octeon/executive/cvmx-helper-board.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/executive/cvmx-helper-board.c	2013-08-25 20:43:22.000000000 -0400
@@ -181,6 +181,11 @@ int cvmx_helper_board_get_mii_address(in
 			return ipd_port - 16 + 4;
 		else
 			return -1;
+	case CVMX_BOARD_TYPE_UBNT_E100:
+		if (ipd_port >= 0 && ipd_port <= 2)
+			return 7 - ipd_port;
+		else
+			return -1;
 	}
 
 	/* Some unknown board. Somebody forgot to update this function... */
@@ -706,6 +711,14 @@ int __cvmx_helper_board_hardware_enable(
 				}
 			}
 		}
+	} else if (cvmx_sysinfo_get()->board_type ==
+			CVMX_BOARD_TYPE_UBNT_E100) {
+		cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0);
+		cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10);
+		cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
+		cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0x10);
+		cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(2, interface), 0);
+		cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(2, interface), 0x10);
 	}
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/cavium-octeon/Kconfig linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/Kconfig
--- linux-libre-3.10-gnu/arch/mips/cavium-octeon/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,10 @@ config CAVIUM_CN63XXP1
 	  non-CN63XXP1 hardware, so it is recommended to select "n"
 	  unless it is known the workarounds are needed.
 
+endif # CPU_CAVIUM_OCTEON
+
+if CAVIUM_OCTEON_SOC
+
 config CAVIUM_OCTEON_2ND_KERNEL
 	bool "Build the kernel to be used as a 2nd kernel on the same chip"
 	default "n"
@@ -19,17 +23,6 @@ config CAVIUM_OCTEON_2ND_KERNEL
 	  with this option to be run at the same time as one built without this
 	  option.
 
-config CAVIUM_OCTEON_HW_FIX_UNALIGNED
-	bool "Enable hardware fixups of unaligned loads and stores"
-	default "y"
-	help
-	  Configure the Octeon hardware to automatically fix unaligned loads
-	  and stores. Normally unaligned accesses are fixed using a kernel
-	  exception handler. This option enables the hardware automatic fixups,
-	  which requires only an extra 3 cycles. Disable this option if you
-	  are running code that relies on address exceptions on unaligned
-	  accesses.
-
 config CAVIUM_OCTEON_CVMSEG_SIZE
 	int "Number of L1 cache lines reserved for CVMSEG memory"
 	range 0 54
@@ -103,4 +96,4 @@ config OCTEON_ILM
 	  To compile this driver as a module, choose M here.  The module
 	  will be called octeon-ilm
 
-endif # CPU_CAVIUM_OCTEON
+endif # CAVIUM_OCTEON_SOC
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/cavium-octeon/Makefile linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/Makefile
--- linux-libre-3.10-gnu/arch/mips/cavium-octeon/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -12,11 +12,12 @@
 CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt
 CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
 
-obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
-obj-y += dma-octeon.o flash_setup.o
+obj-y := cpu.o setup.o octeon-platform.o octeon-irq.o csrc-octeon.o
+obj-y += dma-octeon.o
 obj-y += octeon-memcpy.o
 obj-y += executive/
 
+obj-$(CONFIG_MTD)		      += flash_setup.o
 obj-$(CONFIG_SMP)		      += smp.o
 obj-$(CONFIG_OCTEON_ILM)	      += oct_ilm.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/cavium-octeon/octeon-irq.c linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/octeon-irq.c
--- linux-libre-3.10-gnu/arch/mips/cavium-octeon/octeon-irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/octeon-irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -607,7 +607,7 @@ static void octeon_irq_ciu_gpio_ack(stru
 
 static void octeon_irq_handle_gpio(unsigned int irq, struct irq_desc *desc)
 {
-	if (irqd_get_trigger_type(irq_desc_get_irq_data(desc)) & IRQ_TYPE_EDGE_BOTH)
+	if (irq_get_trigger_type(irq) & IRQ_TYPE_EDGE_BOTH)
 		handle_edge_irq(irq, desc);
 	else
 		handle_level_irq(irq, desc);
@@ -1095,7 +1095,7 @@ static void octeon_irq_ip3_ciu(void)
 
 static bool octeon_irq_use_ip4;
 
-static void __cpuinit octeon_irq_local_enable_ip4(void *arg)
+static void octeon_irq_local_enable_ip4(void *arg)
 {
 	set_c0_status(STATUSF_IP4);
 }
@@ -1110,21 +1110,21 @@ static void (*octeon_irq_ip2)(void);
 static void (*octeon_irq_ip3)(void);
 static void (*octeon_irq_ip4)(void);
 
-void __cpuinitdata (*octeon_irq_setup_secondary)(void);
+void (*octeon_irq_setup_secondary)(void);
 
-void __cpuinit octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t h)
+void octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t h)
 {
 	octeon_irq_ip4 = h;
 	octeon_irq_use_ip4 = true;
 	on_each_cpu(octeon_irq_local_enable_ip4, NULL, 1);
 }
 
-static void __cpuinit octeon_irq_percpu_enable(void)
+static void octeon_irq_percpu_enable(void)
 {
 	irq_cpu_online();
 }
 
-static void __cpuinit octeon_irq_init_ciu_percpu(void)
+static void octeon_irq_init_ciu_percpu(void)
 {
 	int coreid = cvmx_get_core_num();
 
@@ -1167,7 +1167,7 @@ static void octeon_irq_init_ciu2_percpu(
 	cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP2(coreid));
 }
 
-static void __cpuinit octeon_irq_setup_secondary_ciu(void)
+static void octeon_irq_setup_secondary_ciu(void)
 {
 	octeon_irq_init_ciu_percpu();
 	octeon_irq_percpu_enable();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/cavium-octeon/octeon-platform.c linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/octeon-platform.c
--- linux-libre-3.10-gnu/arch/mips/cavium-octeon/octeon-platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/octeon-platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -334,9 +334,10 @@ static void __init octeon_fdt_pip_iface(
 	char name_buffer[20];
 	int iface;
 	int p;
-	int count;
+	int count = 0;
 
-	count = cvmx_helper_interface_enumerate(idx);
+	if (cvmx_helper_interface_enumerate(idx) == 0)
+		count = cvmx_helper_ports_on_interface(idx);
 
 	snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx);
 	iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer);
@@ -490,8 +491,15 @@ int __init octeon_prune_device_tree(void
 
 		if (alias_prop) {
 			uart = fdt_path_offset(initial_boot_params, alias_prop);
-			if (uart_mask & (1 << i))
+			if (uart_mask & (1 << i)) {
+				__be32 f;
+
+				f = cpu_to_be32(octeon_get_io_clock_rate());
+				fdt_setprop_inplace(initial_boot_params,
+						    uart, "clock-frequency",
+						    &f, sizeof(f));
 				continue;
+			}
 			pr_debug("Deleting uart%d\n", i);
 			fdt_nop_node(initial_boot_params, uart);
 			fdt_nop_property(initial_boot_params, aliases,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/cavium-octeon/Platform linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/Platform
--- linux-libre-3.10-gnu/arch/mips/cavium-octeon/Platform	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/Platform	2013-08-25 20:43:22.000000000 -0400
@@ -1,11 +1,11 @@
 #
 # Cavium Octeon
 #
-platform-$(CONFIG_CPU_CAVIUM_OCTEON)	+= cavium-octeon/
-cflags-$(CONFIG_CPU_CAVIUM_OCTEON)	+=				\
+platform-$(CONFIG_CAVIUM_OCTEON_SOC)	+= cavium-octeon/
+cflags-$(CONFIG_CAVIUM_OCTEON_SOC)	+=				\
 		-I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
 ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
-load-$(CONFIG_CPU_CAVIUM_OCTEON)	+= 0xffffffff84100000
+load-$(CONFIG_CAVIUM_OCTEON_SOC)	+= 0xffffffff84100000
 else
-load-$(CONFIG_CPU_CAVIUM_OCTEON)	+= 0xffffffff81100000
+load-$(CONFIG_CAVIUM_OCTEON_SOC)	+= 0xffffffff81100000
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/cavium-octeon/serial.c linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/serial.c
--- linux-libre-3.10-gnu/arch/mips/cavium-octeon/serial.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/serial.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,109 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004-2007 Cavium Networks
- */
-#include <linux/console.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_reg.h>
-#include <linux/tty.h>
-#include <linux/irq.h>
-
-#include <asm/time.h>
-
-#include <asm/octeon/octeon.h>
-
-#define DEBUG_UART 1
-
-unsigned int octeon_serial_in(struct uart_port *up, int offset)
-{
-	int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
-	if (offset == UART_IIR && (rv & 0xf) == 7) {
-		/* Busy interrupt, read the USR (39) and try again. */
-		cvmx_read_csr((uint64_t)(up->membase + (39 << 3)));
-		rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
-	}
-	return rv;
-}
-
-void octeon_serial_out(struct uart_port *up, int offset, int value)
-{
-	/*
-	 * If bits 6 or 7 of the OCTEON UART's LCR are set, it quits
-	 * working.
-	 */
-	if (offset == UART_LCR)
-		value &= 0x9f;
-	cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value);
-}
-
-static int octeon_serial_probe(struct platform_device *pdev)
-{
-	int irq, res;
-	struct resource *res_mem;
-	struct uart_8250_port up;
-
-	/* All adaptors have an irq.  */
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
-	memset(&up, 0, sizeof(up));
-
-	up.port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
-	up.port.type = PORT_OCTEON;
-	up.port.iotype = UPIO_MEM;
-	up.port.regshift = 3;
-	up.port.dev = &pdev->dev;
-
-	if (octeon_is_simulation())
-		/* Make simulator output fast*/
-		up.port.uartclk = 115200 * 16;
-	else
-		up.port.uartclk = octeon_get_io_clock_rate();
-
-	up.port.serial_in = octeon_serial_in;
-	up.port.serial_out = octeon_serial_out;
-	up.port.irq = irq;
-
-	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res_mem == NULL) {
-		dev_err(&pdev->dev, "found no memory resource\n");
-		return -ENXIO;
-	}
-	up.port.mapbase = res_mem->start;
-	up.port.membase = ioremap(res_mem->start, resource_size(res_mem));
-
-	res = serial8250_register_8250_port(&up);
-
-	return res >= 0 ? 0 : res;
-}
-
-static struct of_device_id octeon_serial_match[] = {
-	{
-		.compatible = "cavium,octeon-3860-uart",
-	},
-	{},
-};
-MODULE_DEVICE_TABLE(of, octeon_serial_match);
-
-static struct platform_driver octeon_serial_driver = {
-	.probe		= octeon_serial_probe,
-	.driver		= {
-		.owner	= THIS_MODULE,
-		.name	= "octeon_serial",
-		.of_match_table = octeon_serial_match,
-	},
-};
-
-static int __init octeon_serial_init(void)
-{
-	return platform_driver_register(&octeon_serial_driver);
-}
-late_initcall(octeon_serial_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/cavium-octeon/setup.c linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/setup.c
--- linux-libre-3.10-gnu/arch/mips/cavium-octeon/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -7,6 +7,7 @@
  * Copyright (C) 2008, 2009 Wind River Systems
  *   written by Ralf Baechle <ralf@linux-mips.org>
  */
+#include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/console.h>
@@ -40,12 +41,6 @@
 #include <asm/octeon/pci-octeon.h>
 #include <asm/octeon/cvmx-mio-defs.h>
 
-#ifdef CONFIG_CAVIUM_DECODE_RSL
-extern void cvmx_interrupt_rsl_decode(void);
-extern int __cvmx_interrupt_ecc_report_single_bit_errors;
-extern void cvmx_interrupt_rsl_enable(void);
-#endif
-
 extern struct plat_smp_ops octeon_smp_ops;
 
 #ifdef CONFIG_PCI
@@ -463,18 +458,6 @@ static void octeon_halt(void)
 }
 
 /**
- * Handle all the error condition interrupts that might occur.
- *
- */
-#ifdef CONFIG_CAVIUM_DECODE_RSL
-static irqreturn_t octeon_rlm_interrupt(int cpl, void *dev_id)
-{
-	cvmx_interrupt_rsl_decode();
-	return IRQ_HANDLED;
-}
-#endif
-
-/**
  * Return a string representing the system type
  *
  * Returns
@@ -712,7 +695,7 @@ void __init prom_init(void)
 	if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) {
 		pr_info("Skipping L2 locking due to reduced L2 cache size\n");
 	} else {
-		uint32_t ebase = read_c0_ebase() & 0x3ffff000;
+		uint32_t __maybe_unused ebase = read_c0_ebase() & 0x3ffff000;
 #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB
 		/* TLB refill */
 		cvmx_l2c_lock_mem_region(ebase, 0x100);
@@ -996,7 +979,7 @@ void __init plat_mem_setup(void)
 	cvmx_bootmem_unlock();
 	/* Add the memory region for the kernel. */
 	kernel_start = (unsigned long) _text;
-	kernel_size = ALIGN(_end - _text, 0x100000);
+	kernel_size = _end - _text;
 
 	/* Adjust for physical offset. */
 	kernel_start &= ~0xffffffff80000000ULL;
@@ -1064,15 +1047,6 @@ void prom_free_prom_memory(void)
 			panic("Core-14449 WAR not in place (%04x).\n"
 			      "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).", insn);
 	}
-#ifdef CONFIG_CAVIUM_DECODE_RSL
-	cvmx_interrupt_rsl_enable();
-
-	/* Add an interrupt handler for general failures. */
-	if (request_irq(OCTEON_IRQ_RML, octeon_rlm_interrupt, IRQF_SHARED,
-			"RML/RSL", octeon_rlm_interrupt)) {
-		panic("Unable to request_irq(OCTEON_IRQ_RML)");
-	}
-#endif
 }
 
 int octeon_prune_device_tree(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/cavium-octeon/smp.c linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/smp.c
--- linux-libre-3.10-gnu/arch/mips/cavium-octeon/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/cavium-octeon/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -173,7 +173,7 @@ static void octeon_boot_secondary(int cp
  * After we've done initial boot, this function is called to allow the
  * board code to clean up state, if needed
  */
-static void __cpuinit octeon_init_secondary(void)
+static void octeon_init_secondary(void)
 {
 	unsigned int sr;
 
@@ -375,7 +375,7 @@ static int octeon_update_boot_vector(uns
 	return 0;
 }
 
-static int __cpuinit octeon_cpu_callback(struct notifier_block *nfb,
+static int octeon_cpu_callback(struct notifier_block *nfb,
 	unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
@@ -394,7 +394,7 @@ static int __cpuinit octeon_cpu_callback
 	return NOTIFY_OK;
 }
 
-static int __cpuinit register_cavium_notifier(void)
+static int register_cavium_notifier(void)
 {
 	hotcpu_notifier(octeon_cpu_callback, 0);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/configs/cavium_octeon_defconfig linux-libre-3.11-rc7-gnu/arch/mips/configs/cavium_octeon_defconfig
--- linux-libre-3.10-gnu/arch/mips/configs/cavium_octeon_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/configs/cavium_octeon_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,13 +1,11 @@
-CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD=y
+CONFIG_CAVIUM_OCTEON_SOC=y
 CONFIG_CAVIUM_CN63XXP1=y
 CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2
-CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 CONFIG_HZ_100=y
 CONFIG_PREEMPT=y
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
@@ -50,7 +48,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
 # CONFIG_MTD_OF_PARTS is not set
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_AMDSTD=y
@@ -114,6 +111,7 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=2
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_DW=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_OCTEON=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/configs/wrppmc_defconfig linux-libre-3.11-rc7-gnu/arch/mips/configs/wrppmc_defconfig
--- linux-libre-3.10-gnu/arch/mips/configs/wrppmc_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/configs/wrppmc_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,97 +0,0 @@
-CONFIG_WR_PPMC=y
-CONFIG_HZ_1000=y
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-# CONFIG_EPOLL is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_PCI=y
-CONFIG_HOTPLUG_PCI=y
-CONFIG_BINFMT_MISC=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_MIGRATE=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_IP_MROUTE=y
-CONFIG_ARPD=y
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_TCP_MD5SIG=y
-# CONFIG_IPV6 is not set
-CONFIG_NETWORK_SECMARK=y
-CONFIG_FW_LOADER=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_SGI_IOC4=m
-CONFIG_NETDEVICES=y
-CONFIG_PHYLIB=y
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-CONFIG_NET_ETHERNET=y
-CONFIG_NET_PCI=y
-CONFIG_E100=y
-CONFIG_QLA3XXX=m
-CONFIG_CHELSIO_T3=m
-CONFIG_NETXEN_NIC=m
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_RUNTIME_UARTS=1
-# CONFIG_HW_RANDOM is not set
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_DLM=m
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttyS0,115200n8"
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
-CONFIG_LIBCRC32C=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/dec/Makefile linux-libre-3.11-rc7-gnu/arch/mips/dec/Makefile
--- linux-libre-3.10-gnu/arch/mips/dec/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/dec/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,6 +5,5 @@
 obj-y		:= ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
 		   kn02-irq.o kn02xa-berr.o reset.o setup.o time.o
 
-obj-$(CONFIG_PROM_CONSOLE)	+= promcon.o
 obj-$(CONFIG_TC)		+= tc.o
 obj-$(CONFIG_CPU_HAS_WB)	+= wbflush.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/dec/promcon.c linux-libre-3.11-rc7-gnu/arch/mips/dec/promcon.c
--- linux-libre-3.10-gnu/arch/mips/dec/promcon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/dec/promcon.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-/*
- * Wrap-around code for a console using the
- * DECstation PROM io-routines.
- *
- * Copyright (c) 1998 Harald Koerfgen
- */
-
-#include <linux/tty.h>
-#include <linux/ptrace.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/fs.h>
-
-#include <asm/dec/prom.h>
-
-static void prom_console_write(struct console *co, const char *s,
-			       unsigned count)
-{
-	unsigned i;
-
-	/*
-	 *    Now, do each character
-	 */
-	for (i = 0; i < count; i++) {
-		if (*s == 10)
-			prom_printf("%c", 13);
-		prom_printf("%c", *s++);
-	}
-}
-
-static int __init prom_console_setup(struct console *co, char *options)
-{
-	return 0;
-}
-
-static struct console sercons = {
-	.name	= "ttyS",
-	.write	= prom_console_write,
-	.setup	= prom_console_setup,
-	.flags	= CON_PRINTBUFFER,
-	.index	= -1,
-};
-
-/*
- *    Register console.
- */
-
-static int __init prom_console_init(void)
-{
-	register_console(&sercons);
-
-	return 0;
-}
-console_initcall(prom_console_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/fw/cfe/cfe_api.c linux-libre-3.11-rc7-gnu/arch/mips/fw/cfe/cfe_api.c
--- linux-libre-3.10-gnu/arch/mips/fw/cfe/cfe_api.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/fw/cfe/cfe_api.c	2013-08-25 20:43:22.000000000 -0400
@@ -406,12 +406,12 @@ int cfe_setenv(char *name, char *val)
 	return xiocb.xiocb_status;
 }
 
-int cfe_write(int handle, unsigned char *buffer, int length)
+int cfe_write(int handle, const char *buffer, int length)
 {
 	return cfe_writeblk(handle, 0, buffer, length);
 }
 
-int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length)
+int cfe_writeblk(int handle, s64 offset, const char *buffer, int length)
 {
 	struct cfe_xiocb xiocb;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/cop2.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/cop2.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/cop2.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/cop2.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,35 @@
 
 #include <linux/notifier.h>
 
+#if defined(CONFIG_CPU_CAVIUM_OCTEON)
+
+extern void octeon_cop2_save(struct octeon_cop2_state *);
+extern void octeon_cop2_restore(struct octeon_cop2_state *);
+
+#define cop2_save(r)		octeon_cop2_save(r)
+#define cop2_restore(r)		octeon_cop2_restore(r)
+
+#define cop2_present		1
+#define cop2_lazy_restore	1
+
+#elif defined(CONFIG_CPU_XLP)
+
+extern void nlm_cop2_save(struct nlm_cop2_state *);
+extern void nlm_cop2_restore(struct nlm_cop2_state *);
+#define cop2_save(r)		nlm_cop2_save(r)
+#define cop2_restore(r)		nlm_cop2_restore(r)
+
+#define cop2_present		1
+#define cop2_lazy_restore	0
+
+#else
+
+#define cop2_present		0
+#define cop2_lazy_restore	0
+#define cop2_save(r)
+#define cop2_restore(r)
+#endif
+
 enum cu2_ops {
 	CU2_EXCEPTION,
 	CU2_LWC2_OP,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/cpu-features.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/cpu-features.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/cpu-features.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/cpu-features.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,8 @@
 #define current_cpu_type()	current_cpu_data.cputype
 #endif
 
+#define boot_cpu_type()		cpu_data[0].cputype
+
 /*
  * SMP assumption: Options of CPU 0 are a superset of all processors.
  * This is true for all known MIPS systems.
@@ -24,6 +26,16 @@
 #ifndef cpu_has_tlb
 #define cpu_has_tlb		(cpu_data[0].options & MIPS_CPU_TLB)
 #endif
+
+/*
+ * For the moment we don't consider R6000 and R8000 so we can assume that
+ * anything that doesn't support R4000-style exceptions and interrupts is
+ * R3000-like.  Users should still treat these two macro definitions as
+ * opaque.
+ */
+#ifndef cpu_has_3kex
+#define cpu_has_3kex		(!cpu_has_4kex)
+#endif
 #ifndef cpu_has_4kex
 #define cpu_has_4kex		(cpu_data[0].options & MIPS_CPU_4KEX)
 #endif
@@ -87,19 +99,23 @@
 #define cpu_has_mips16		(cpu_data[0].ases & MIPS_ASE_MIPS16)
 #endif
 #ifndef cpu_has_mdmx
-#define cpu_has_mdmx	       (cpu_data[0].ases & MIPS_ASE_MDMX)
+#define cpu_has_mdmx		(cpu_data[0].ases & MIPS_ASE_MDMX)
 #endif
 #ifndef cpu_has_mips3d
-#define cpu_has_mips3d	       (cpu_data[0].ases & MIPS_ASE_MIPS3D)
+#define cpu_has_mips3d		(cpu_data[0].ases & MIPS_ASE_MIPS3D)
 #endif
 #ifndef cpu_has_smartmips
-#define cpu_has_smartmips      (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
+#define cpu_has_smartmips	(cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
 #endif
 #ifndef cpu_has_rixi
 #define cpu_has_rixi		(cpu_data[0].options & MIPS_CPU_RIXI)
 #endif
 #ifndef cpu_has_mmips
-#define cpu_has_mmips		(cpu_data[0].options & MIPS_CPU_MICROMIPS)
+# ifdef CONFIG_SYS_SUPPORTS_MICROMIPS
+#  define cpu_has_mmips		(cpu_data[0].options & MIPS_CPU_MICROMIPS)
+# else
+#  define cpu_has_mmips		0
+# endif
 #endif
 #ifndef cpu_has_vtag_icache
 #define cpu_has_vtag_icache	(cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
@@ -111,7 +127,7 @@
 #define cpu_has_ic_fills_f_dc	(cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
 #endif
 #ifndef cpu_has_pindexed_dcache
-#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
+#define cpu_has_pindexed_dcache	(cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
 #endif
 #ifndef cpu_has_local_ebase
 #define cpu_has_local_ebase	1
@@ -136,7 +152,6 @@
 #endif
 #endif
 
-# define cpu_has_mips_1		(cpu_data[0].isa_level & MIPS_CPU_ISA_I)
 #ifndef cpu_has_mips_2
 # define cpu_has_mips_2		(cpu_data[0].isa_level & MIPS_CPU_ISA_II)
 #endif
@@ -149,18 +164,18 @@
 #ifndef cpu_has_mips_5
 # define cpu_has_mips_5		(cpu_data[0].isa_level & MIPS_CPU_ISA_V)
 #endif
-# ifndef cpu_has_mips32r1
+#ifndef cpu_has_mips32r1
 # define cpu_has_mips32r1	(cpu_data[0].isa_level & MIPS_CPU_ISA_M32R1)
-# endif
-# ifndef cpu_has_mips32r2
+#endif
+#ifndef cpu_has_mips32r2
 # define cpu_has_mips32r2	(cpu_data[0].isa_level & MIPS_CPU_ISA_M32R2)
-# endif
-# ifndef cpu_has_mips64r1
+#endif
+#ifndef cpu_has_mips64r1
 # define cpu_has_mips64r1	(cpu_data[0].isa_level & MIPS_CPU_ISA_M64R1)
-# endif
-# ifndef cpu_has_mips64r2
+#endif
+#ifndef cpu_has_mips64r2
 # define cpu_has_mips64r2	(cpu_data[0].isa_level & MIPS_CPU_ISA_M64R2)
-# endif
+#endif
 
 /*
  * Shortcuts ...
@@ -182,9 +197,9 @@
  * has CLO and CLZ but not DCLO nor DCLZ.  For 64-bit kernels
  * cpu_has_clo_clz also indicates the availability of DCLO and DCLZ.
  */
-# ifndef cpu_has_clo_clz
-# define cpu_has_clo_clz	cpu_has_mips_r
-# endif
+#ifndef cpu_has_clo_clz
+#define cpu_has_clo_clz	cpu_has_mips_r
+#endif
 
 #ifndef cpu_has_dsp
 #define cpu_has_dsp		(cpu_data[0].ases & MIPS_ASE_DSP)
@@ -210,7 +225,7 @@
 # define cpu_has_64bits		(cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
 # endif
 # ifndef cpu_has_64bit_zero_reg
-# define cpu_has_64bit_zero_reg (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
+# define cpu_has_64bit_zero_reg	(cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
 # endif
 # ifndef cpu_has_64bit_gp_regs
 # define cpu_has_64bit_gp_regs		0
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/cpu.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/cpu.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/cpu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/cpu.h	2013-08-25 20:43:22.000000000 -0400
@@ -282,18 +282,17 @@ enum cpu_type_enum {
  * ISA Level encodings
  *
  */
-#define MIPS_CPU_ISA_I		0x00000001
-#define MIPS_CPU_ISA_II		0x00000002
-#define MIPS_CPU_ISA_III	0x00000004
-#define MIPS_CPU_ISA_IV		0x00000008
-#define MIPS_CPU_ISA_V		0x00000010
-#define MIPS_CPU_ISA_M32R1	0x00000020
-#define MIPS_CPU_ISA_M32R2	0x00000040
-#define MIPS_CPU_ISA_M64R1	0x00000080
-#define MIPS_CPU_ISA_M64R2	0x00000100
+#define MIPS_CPU_ISA_II		0x00000001
+#define MIPS_CPU_ISA_III	0x00000002
+#define MIPS_CPU_ISA_IV		0x00000004
+#define MIPS_CPU_ISA_V		0x00000008
+#define MIPS_CPU_ISA_M32R1	0x00000010
+#define MIPS_CPU_ISA_M32R2	0x00000020
+#define MIPS_CPU_ISA_M64R1	0x00000040
+#define MIPS_CPU_ISA_M64R2	0x00000080
 
-#define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | \
-	MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2)
+#define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_II | MIPS_CPU_ISA_M32R1 | \
+	MIPS_CPU_ISA_M32R2)
 #define MIPS_CPU_ISA_64BIT (MIPS_CPU_ISA_III | MIPS_CPU_ISA_IV | \
 	MIPS_CPU_ISA_V | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/fw/cfe/cfe_api.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/fw/cfe/cfe_api.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/fw/cfe/cfe_api.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/fw/cfe/cfe_api.h	2013-08-25 20:43:22.000000000 -0400
@@ -115,8 +115,8 @@ int cfe_read(int handle, unsigned char *
 int cfe_readblk(int handle, int64_t offset, unsigned char *buffer,
 		int length);
 int cfe_setenv(char *name, char *val);
-int cfe_write(int handle, unsigned char *buffer, int length);
-int cfe_writeblk(int handle, int64_t offset, unsigned char *buffer,
+int cfe_write(int handle, const char *buffer, int length);
+int cfe_writeblk(int handle, int64_t offset, const char *buffer,
 		 int length);
 
 #endif				/* CFE_API_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/gic.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/gic.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/gic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/gic.h	2013-08-25 20:43:22.000000000 -0400
@@ -347,7 +347,7 @@ struct gic_shared_intr_map {
 #define GIC_CPU_INT2		2 /* .		      */
 #define GIC_CPU_INT3		3 /* .		      */
 #define GIC_CPU_INT4		4 /* .		      */
-#define GIC_CPU_INT5		5 /* Core Interrupt 5 */
+#define GIC_CPU_INT5		5 /* Core Interrupt 7 */
 
 /* Local GIC interrupts. */
 #define GIC_INT_TMR		(GIC_CPU_INT5)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/io.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/io.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/io.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/io.h	2013-08-25 20:43:22.000000000 -0400
@@ -170,6 +170,11 @@ static inline void * isa_bus_to_virt(uns
 extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags);
 extern void __iounmap(const volatile void __iomem *addr);
 
+#ifndef CONFIG_PCI
+struct pci_dev;
+static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
+#endif
+
 static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
 	unsigned long flags)
 {
@@ -449,6 +454,11 @@ __BUILDIO(q, u64)
 #define readl_relaxed			readl
 #define readq_relaxed			readq
 
+#define writeb_relaxed			writeb
+#define writew_relaxed			writew
+#define writel_relaxed			writel
+#define writeq_relaxed			writeq
+
 #define readb_be(addr)							\
 	__raw_readb((__force unsigned *)(addr))
 #define readw_be(addr)							\
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/kspd.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/kspd.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/kspd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/kspd.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- */
-
-#ifndef _ASM_KSPD_H
-#define _ASM_KSPD_H
-
-struct kspd_notifications {
-	void (*kspd_sp_exit)(int sp_id);
-
-	struct list_head list;
-};
-
-static inline void kspd_notify(struct kspd_notifications *notify)
-{
-}
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-ar7/spaces.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-ar7/spaces.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-ar7/spaces.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-ar7/spaces.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,8 +14,11 @@
  * This handles the memory map.
  * We handle pages at KSEG0 for kernels with 32 bit address space.
  */
-#define PAGE_OFFSET		0x94000000UL
-#define PHYS_OFFSET		0x14000000UL
+#define PAGE_OFFSET	_AC(0x94000000, UL)
+#define PHYS_OFFSET	_AC(0x14000000, UL)
+
+#define UNCAC_BASE	_AC(0xb4000000, UL)	/* 0xa0000000 + PHYS_OFFSET */
+#define IO_BASE		UNCAC_BASE
 
 #include <asm/mach-generic/spaces.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,7 @@
  * compile time if only one CPU support is enabled (idea stolen from
  * arm mach-types)
  */
+#define BCM3368_CPU_ID		0x3368
 #define BCM6328_CPU_ID		0x6328
 #define BCM6338_CPU_ID		0x6338
 #define BCM6345_CPU_ID		0x6345
@@ -22,6 +23,19 @@ u16 __bcm63xx_get_cpu_id(void);
 u8 bcm63xx_get_cpu_rev(void);
 unsigned int bcm63xx_get_cpu_freq(void);
 
+#ifdef CONFIG_BCM63XX_CPU_3368
+# ifdef bcm63xx_get_cpu_id
+#  undef bcm63xx_get_cpu_id
+#  define bcm63xx_get_cpu_id()	__bcm63xx_get_cpu_id()
+#  define BCMCPU_RUNTIME_DETECT
+# else
+#  define bcm63xx_get_cpu_id()	BCM3368_CPU_ID
+# endif
+# define BCMCPU_IS_3368()	(bcm63xx_get_cpu_id() == BCM3368_CPU_ID)
+#else
+# define BCMCPU_IS_3368()	(0)
+#endif
+
 #ifdef CONFIG_BCM63XX_CPU_6328
 # ifdef bcm63xx_get_cpu_id
 #  undef bcm63xx_get_cpu_id
@@ -173,7 +187,10 @@ enum bcm63xx_regs_set {
 #define BCM_6358_RSET_SPI_SIZE		1804
 #define BCM_6368_RSET_SPI_SIZE		1804
 #define RSET_ENET_SIZE			2048
-#define RSET_ENETDMA_SIZE		2048
+#define RSET_ENETDMA_SIZE		256
+#define RSET_6345_ENETDMA_SIZE		64
+#define RSET_ENETDMAC_SIZE(chans)	(16 * (chans))
+#define RSET_ENETDMAS_SIZE(chans)	(16 * (chans))
 #define RSET_ENETSW_SIZE		65536
 #define RSET_UART_SIZE			24
 #define RSET_UDC_SIZE			256
@@ -191,6 +208,53 @@ enum bcm63xx_regs_set {
 #define RSET_RNG_SIZE			20
 
 /*
+ * 3368 register sets base address
+ */
+#define BCM_3368_DSL_LMEM_BASE		(0xdeadbeef)
+#define BCM_3368_PERF_BASE		(0xfff8c000)
+#define BCM_3368_TIMER_BASE		(0xfff8c040)
+#define BCM_3368_WDT_BASE		(0xfff8c080)
+#define BCM_3368_UART0_BASE		(0xfff8c100)
+#define BCM_3368_UART1_BASE		(0xfff8c120)
+#define BCM_3368_GPIO_BASE		(0xfff8c080)
+#define BCM_3368_SPI_BASE		(0xfff8c800)
+#define BCM_3368_HSSPI_BASE		(0xdeadbeef)
+#define BCM_3368_UDC0_BASE		(0xdeadbeef)
+#define BCM_3368_USBDMA_BASE		(0xdeadbeef)
+#define BCM_3368_OHCI0_BASE		(0xdeadbeef)
+#define BCM_3368_OHCI_PRIV_BASE		(0xdeadbeef)
+#define BCM_3368_USBH_PRIV_BASE		(0xdeadbeef)
+#define BCM_3368_USBD_BASE		(0xdeadbeef)
+#define BCM_3368_MPI_BASE		(0xfff80000)
+#define BCM_3368_PCMCIA_BASE		(0xfff80054)
+#define BCM_3368_PCIE_BASE		(0xdeadbeef)
+#define BCM_3368_SDRAM_REGS_BASE	(0xdeadbeef)
+#define BCM_3368_DSL_BASE		(0xdeadbeef)
+#define BCM_3368_UBUS_BASE		(0xdeadbeef)
+#define BCM_3368_ENET0_BASE		(0xfff98000)
+#define BCM_3368_ENET1_BASE		(0xfff98800)
+#define BCM_3368_ENETDMA_BASE		(0xfff99800)
+#define BCM_3368_ENETDMAC_BASE		(0xfff99900)
+#define BCM_3368_ENETDMAS_BASE		(0xfff99a00)
+#define BCM_3368_ENETSW_BASE		(0xdeadbeef)
+#define BCM_3368_EHCI0_BASE		(0xdeadbeef)
+#define BCM_3368_SDRAM_BASE		(0xdeadbeef)
+#define BCM_3368_MEMC_BASE		(0xfff84000)
+#define BCM_3368_DDR_BASE		(0xdeadbeef)
+#define BCM_3368_M2M_BASE		(0xdeadbeef)
+#define BCM_3368_ATM_BASE		(0xdeadbeef)
+#define BCM_3368_XTM_BASE		(0xdeadbeef)
+#define BCM_3368_XTMDMA_BASE		(0xdeadbeef)
+#define BCM_3368_XTMDMAC_BASE		(0xdeadbeef)
+#define BCM_3368_XTMDMAS_BASE		(0xdeadbeef)
+#define BCM_3368_PCM_BASE		(0xfff9c200)
+#define BCM_3368_PCMDMA_BASE		(0xdeadbeef)
+#define BCM_3368_PCMDMAC_BASE		(0xdeadbeef)
+#define BCM_3368_PCMDMAS_BASE		(0xdeadbeef)
+#define BCM_3368_RNG_BASE		(0xdeadbeef)
+#define BCM_3368_MISC_BASE		(0xdeadbeef)
+
+/*
  * 6328 register sets base address
  */
 #define BCM_6328_DSL_LMEM_BASE		(0xdeadbeef)
@@ -235,6 +299,8 @@ enum bcm63xx_regs_set {
 #define BCM_6328_PCMDMAS_BASE		(0xdeadbeef)
 #define BCM_6328_RNG_BASE		(0xdeadbeef)
 #define BCM_6328_MISC_BASE		(0xb0001800)
+#define BCM_6328_OTP_BASE		(0xb0000600)
+
 /*
  * 6338 register sets base address
  */
@@ -298,7 +364,7 @@ enum bcm63xx_regs_set {
 #define BCM_6345_USBDMA_BASE		(0xfffe2800)
 #define BCM_6345_ENET0_BASE		(0xfffe1800)
 #define BCM_6345_ENETDMA_BASE		(0xfffe2800)
-#define BCM_6345_ENETDMAC_BASE		(0xfffe2900)
+#define BCM_6345_ENETDMAC_BASE		(0xfffe2840)
 #define BCM_6345_ENETDMAS_BASE		(0xfffe2a00)
 #define BCM_6345_ENETSW_BASE		(0xdeadbeef)
 #define BCM_6345_PCMCIA_BASE		(0xfffe2028)
@@ -620,6 +686,9 @@ static inline unsigned long bcm63xx_regs
 #ifdef BCMCPU_RUNTIME_DETECT
 	return bcm63xx_regs_base[set];
 #else
+#ifdef CONFIG_BCM63XX_CPU_3368
+	__GEN_RSET(3368)
+#endif
 #ifdef CONFIG_BCM63XX_CPU_6328
 	__GEN_RSET(6328)
 #endif
@@ -687,6 +756,52 @@ enum bcm63xx_irq {
 };
 
 /*
+ * 3368 irqs
+ */
+#define BCM_3368_TIMER_IRQ		(IRQ_INTERNAL_BASE + 0)
+#define BCM_3368_SPI_IRQ		(IRQ_INTERNAL_BASE + 1)
+#define BCM_3368_UART0_IRQ		(IRQ_INTERNAL_BASE + 2)
+#define BCM_3368_UART1_IRQ		(IRQ_INTERNAL_BASE + 3)
+#define BCM_3368_DSL_IRQ		0
+#define BCM_3368_UDC0_IRQ		0
+#define BCM_3368_OHCI0_IRQ		0
+#define BCM_3368_ENET0_IRQ		(IRQ_INTERNAL_BASE + 8)
+#define BCM_3368_ENET1_IRQ		(IRQ_INTERNAL_BASE + 6)
+#define BCM_3368_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 9)
+#define BCM_3368_ENET0_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 15)
+#define BCM_3368_ENET0_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 16)
+#define BCM_3368_HSSPI_IRQ		0
+#define BCM_3368_EHCI0_IRQ		0
+#define BCM_3368_USBD_IRQ		0
+#define BCM_3368_USBD_RXDMA0_IRQ	0
+#define BCM_3368_USBD_TXDMA0_IRQ	0
+#define BCM_3368_USBD_RXDMA1_IRQ	0
+#define BCM_3368_USBD_TXDMA1_IRQ	0
+#define BCM_3368_USBD_RXDMA2_IRQ	0
+#define BCM_3368_USBD_TXDMA2_IRQ	0
+#define BCM_3368_ENET1_RXDMA_IRQ        (IRQ_INTERNAL_BASE + 17)
+#define BCM_3368_ENET1_TXDMA_IRQ        (IRQ_INTERNAL_BASE + 18)
+#define BCM_3368_PCI_IRQ		(IRQ_INTERNAL_BASE + 31)
+#define BCM_3368_PCMCIA_IRQ		0
+#define BCM_3368_ATM_IRQ		0
+#define BCM_3368_ENETSW_RXDMA0_IRQ	0
+#define BCM_3368_ENETSW_RXDMA1_IRQ	0
+#define BCM_3368_ENETSW_RXDMA2_IRQ	0
+#define BCM_3368_ENETSW_RXDMA3_IRQ	0
+#define BCM_3368_ENETSW_TXDMA0_IRQ	0
+#define BCM_3368_ENETSW_TXDMA1_IRQ	0
+#define BCM_3368_ENETSW_TXDMA2_IRQ	0
+#define BCM_3368_ENETSW_TXDMA3_IRQ	0
+#define BCM_3368_XTM_IRQ		0
+#define BCM_3368_XTM_DMA0_IRQ		0
+
+#define BCM_3368_EXT_IRQ0		(IRQ_INTERNAL_BASE + 25)
+#define BCM_3368_EXT_IRQ1		(IRQ_INTERNAL_BASE + 26)
+#define BCM_3368_EXT_IRQ2		(IRQ_INTERNAL_BASE + 27)
+#define BCM_3368_EXT_IRQ3		(IRQ_INTERNAL_BASE + 28)
+
+
+/*
  * 6328 irqs
  */
 #define BCM_6328_HIGH_IRQ_BASE		(IRQ_INTERNAL_BASE + 32)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h	2013-08-25 20:43:22.000000000 -0400
@@ -4,6 +4,8 @@
 #include <linux/if_ether.h>
 #include <linux/init.h>
 
+#include <bcm63xx_regs.h>
+
 /*
  * on board ethernet platform data
  */
@@ -37,9 +39,129 @@ struct bcm63xx_enet_platform_data {
 					  int phy_id, int reg),
 			  void (*mii_write)(struct net_device *dev,
 					    int phy_id, int reg, int val));
+
+	/* DMA channel enable mask */
+	u32 dma_chan_en_mask;
+
+	/* DMA channel interrupt mask */
+	u32 dma_chan_int_mask;
+
+	/* DMA engine has internal SRAM */
+	bool dma_has_sram;
+
+	/* DMA channel register width */
+	unsigned int dma_chan_width;
+
+	/* DMA descriptor shift */
+	unsigned int dma_desc_shift;
+};
+
+/*
+ * on board ethernet switch platform data
+ */
+#define ENETSW_MAX_PORT	8
+#define ENETSW_PORTS_6328 5 /* 4 FE PHY + 1 RGMII */
+#define ENETSW_PORTS_6368 6 /* 4 FE PHY + 2 RGMII */
+
+#define ENETSW_RGMII_PORT0	4
+
+struct bcm63xx_enetsw_port {
+	int		used;
+	int		phy_id;
+
+	int		bypass_link;
+	int		force_speed;
+	int		force_duplex_full;
+
+	const char	*name;
+};
+
+struct bcm63xx_enetsw_platform_data {
+	char mac_addr[ETH_ALEN];
+	int num_ports;
+	struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT];
+
+	/* DMA channel enable mask */
+	u32 dma_chan_en_mask;
+
+	/* DMA channel interrupt mask */
+	u32 dma_chan_int_mask;
+
+	/* DMA channel register width */
+	unsigned int dma_chan_width;
+
+	/* DMA engine has internal SRAM */
+	bool dma_has_sram;
 };
 
 int __init bcm63xx_enet_register(int unit,
 				 const struct bcm63xx_enet_platform_data *pd);
 
+int bcm63xx_enetsw_register(const struct bcm63xx_enetsw_platform_data *pd);
+
+enum bcm63xx_regs_enetdmac {
+	ENETDMAC_CHANCFG,
+	ENETDMAC_IR,
+	ENETDMAC_IRMASK,
+	ENETDMAC_MAXBURST,
+	ENETDMAC_BUFALLOC,
+	ENETDMAC_RSTART,
+	ENETDMAC_FC,
+	ENETDMAC_LEN,
+};
+
+static inline unsigned long bcm63xx_enetdmacreg(enum bcm63xx_regs_enetdmac reg)
+{
+#ifdef BCMCPU_RUNTIME_DETECT
+	extern const unsigned long *bcm63xx_regs_enetdmac;
+
+	return bcm63xx_regs_enetdmac[reg];
+#else
+#ifdef CONFIG_BCM63XX_CPU_6345
+	switch (reg) {
+	case ENETDMAC_CHANCFG:
+		return ENETDMA_6345_CHANCFG_REG;
+	case ENETDMAC_IR:
+		return ENETDMA_6345_IR_REG;
+	case ENETDMAC_IRMASK:
+		return ENETDMA_6345_IRMASK_REG;
+	case ENETDMAC_MAXBURST:
+		return ENETDMA_6345_MAXBURST_REG;
+	case ENETDMAC_BUFALLOC:
+		return ENETDMA_6345_BUFALLOC_REG;
+	case ENETDMAC_RSTART:
+		return ENETDMA_6345_RSTART_REG;
+	case ENETDMAC_FC:
+		return ENETDMA_6345_FC_REG;
+	case ENETDMAC_LEN:
+		return ENETDMA_6345_LEN_REG;
+	}
+#endif
+#if defined(CONFIG_BCM63XX_CPU_6328) || \
+	defined(CONFIG_BCM63XX_CPU_6338) || \
+	defined(CONFIG_BCM63XX_CPU_6348) || \
+	defined(CONFIG_BCM63XX_CPU_6358) || \
+	defined(CONFIG_BCM63XX_CPU_6362) || \
+	defined(CONFIG_BCM63XX_CPU_6368)
+	switch (reg) {
+	case ENETDMAC_CHANCFG:
+		return ENETDMAC_CHANCFG_REG;
+	case ENETDMAC_IR:
+		return ENETDMAC_IR_REG;
+	case ENETDMAC_IRMASK:
+		return ENETDMAC_IRMASK_REG;
+	case ENETDMAC_MAXBURST:
+		return ENETDMAC_MAXBURST_REG;
+	case ENETDMAC_BUFALLOC:
+	case ENETDMAC_RSTART:
+	case ENETDMAC_FC:
+	case ENETDMAC_LEN:
+		return 0;
+	}
+#endif
+#endif
+	return 0;
+}
+
+
 #endif /* ! BCM63XX_DEV_ENET_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,7 @@ static inline unsigned long bcm63xx_gpio
 	switch (bcm63xx_get_cpu_id()) {
 	case BCM6328_CPU_ID:
 		return 32;
+	case BCM3368_CPU_ID:
 	case BCM6358_CPU_ID:
 		return 40;
 	case BCM6338_CPU_ID:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,39 @@
 /* Clock Control register */
 #define PERF_CKCTL_REG			0x4
 
+#define CKCTL_3368_MAC_EN		(1 << 3)
+#define CKCTL_3368_TC_EN		(1 << 5)
+#define CKCTL_3368_US_TOP_EN		(1 << 6)
+#define CKCTL_3368_DS_TOP_EN		(1 << 7)
+#define CKCTL_3368_APM_EN		(1 << 8)
+#define CKCTL_3368_SPI_EN		(1 << 9)
+#define CKCTL_3368_USBS_EN		(1 << 10)
+#define CKCTL_3368_BMU_EN		(1 << 11)
+#define CKCTL_3368_PCM_EN		(1 << 12)
+#define CKCTL_3368_NTP_EN		(1 << 13)
+#define CKCTL_3368_ACP_B_EN		(1 << 14)
+#define CKCTL_3368_ACP_A_EN		(1 << 15)
+#define CKCTL_3368_EMUSB_EN		(1 << 17)
+#define CKCTL_3368_ENET0_EN		(1 << 18)
+#define CKCTL_3368_ENET1_EN		(1 << 19)
+#define CKCTL_3368_USBU_EN		(1 << 20)
+#define CKCTL_3368_EPHY_EN		(1 << 21)
+
+#define CKCTL_3368_ALL_SAFE_EN		(CKCTL_3368_MAC_EN | \
+					 CKCTL_3368_TC_EN | \
+					 CKCTL_3368_US_TOP_EN | \
+					 CKCTL_3368_DS_TOP_EN | \
+					 CKCTL_3368_APM_EN | \
+					 CKCTL_3368_SPI_EN | \
+					 CKCTL_3368_USBS_EN | \
+					 CKCTL_3368_BMU_EN | \
+					 CKCTL_3368_PCM_EN | \
+					 CKCTL_3368_NTP_EN | \
+					 CKCTL_3368_ACP_B_EN | \
+					 CKCTL_3368_ACP_A_EN | \
+					 CKCTL_3368_EMUSB_EN | \
+					 CKCTL_3368_USBU_EN)
+
 #define CKCTL_6328_PHYMIPS_EN		(1 << 0)
 #define CKCTL_6328_ADSL_QPROC_EN	(1 << 1)
 #define CKCTL_6328_ADSL_AFE_EN		(1 << 2)
@@ -181,6 +214,7 @@
 #define SYS_PLL_SOFT_RESET		0x1
 
 /* Interrupt Mask register */
+#define PERF_IRQMASK_3368_REG		0xc
 #define PERF_IRQMASK_6328_REG		0x20
 #define PERF_IRQMASK_6338_REG		0xc
 #define PERF_IRQMASK_6345_REG		0xc
@@ -190,6 +224,7 @@
 #define PERF_IRQMASK_6368_REG		0x20
 
 /* Interrupt Status register */
+#define PERF_IRQSTAT_3368_REG		0x10
 #define PERF_IRQSTAT_6328_REG		0x28
 #define PERF_IRQSTAT_6338_REG		0x10
 #define PERF_IRQSTAT_6345_REG		0x10
@@ -199,6 +234,7 @@
 #define PERF_IRQSTAT_6368_REG		0x28
 
 /* External Interrupt Configuration register */
+#define PERF_EXTIRQ_CFG_REG_3368	0x14
 #define PERF_EXTIRQ_CFG_REG_6328	0x18
 #define PERF_EXTIRQ_CFG_REG_6338	0x14
 #define PERF_EXTIRQ_CFG_REG_6345	0x14
@@ -236,6 +272,13 @@
 #define PERF_SOFTRESET_6362_REG		0x10
 #define PERF_SOFTRESET_6368_REG		0x10
 
+#define SOFTRESET_3368_SPI_MASK		(1 << 0)
+#define SOFTRESET_3368_ENET_MASK	(1 << 2)
+#define SOFTRESET_3368_MPI_MASK		(1 << 3)
+#define SOFTRESET_3368_EPHY_MASK	(1 << 6)
+#define SOFTRESET_3368_USBS_MASK	(1 << 11)
+#define SOFTRESET_3368_PCM_MASK		(1 << 13)
+
 #define SOFTRESET_6328_SPI_MASK		(1 << 0)
 #define SOFTRESET_6328_EPHY_MASK	(1 << 1)
 #define SOFTRESET_6328_SAR_MASK		(1 << 2)
@@ -727,6 +770,8 @@
 /*************************************************************************
  * _REG relative to RSET_ENETDMA
  *************************************************************************/
+#define ENETDMA_CHAN_WIDTH		0x10
+#define ENETDMA_6345_CHAN_WIDTH		0x40
 
 /* Controller Configuration Register */
 #define ENETDMA_CFG_REG			(0x0)
@@ -782,31 +827,56 @@
 /* State Ram Word 4 */
 #define ENETDMA_SRAM4_REG(x)		(0x20c + (x) * 0x10)
 
+/* Broadcom 6345 ENET DMA definitions */
+#define ENETDMA_6345_CHANCFG_REG	(0x00)
+
+#define ENETDMA_6345_MAXBURST_REG	(0x40)
+
+#define ENETDMA_6345_RSTART_REG		(0x08)
+
+#define ENETDMA_6345_LEN_REG		(0x0C)
+
+#define ENETDMA_6345_IR_REG		(0x14)
+
+#define ENETDMA_6345_IRMASK_REG		(0x18)
+
+#define ENETDMA_6345_FC_REG		(0x1C)
+
+#define ENETDMA_6345_BUFALLOC_REG	(0x20)
+
+/* Shift down for EOP, SOP and WRAP bits */
+#define ENETDMA_6345_DESC_SHIFT		(3)
 
 /*************************************************************************
  * _REG relative to RSET_ENETDMAC
  *************************************************************************/
 
 /* Channel Configuration register */
-#define ENETDMAC_CHANCFG_REG(x)		((x) * 0x10)
+#define ENETDMAC_CHANCFG_REG		(0x0)
 #define ENETDMAC_CHANCFG_EN_SHIFT	0
 #define ENETDMAC_CHANCFG_EN_MASK	(1 << ENETDMAC_CHANCFG_EN_SHIFT)
 #define ENETDMAC_CHANCFG_PKTHALT_SHIFT	1
 #define ENETDMAC_CHANCFG_PKTHALT_MASK	(1 << ENETDMAC_CHANCFG_PKTHALT_SHIFT)
 #define ENETDMAC_CHANCFG_BUFHALT_SHIFT	2
 #define ENETDMAC_CHANCFG_BUFHALT_MASK	(1 << ENETDMAC_CHANCFG_BUFHALT_SHIFT)
+#define ENETDMAC_CHANCFG_CHAINING_SHIFT	2
+#define ENETDMAC_CHANCFG_CHAINING_MASK	(1 << ENETDMAC_CHANCFG_CHAINING_SHIFT)
+#define ENETDMAC_CHANCFG_WRAP_EN_SHIFT	3
+#define ENETDMAC_CHANCFG_WRAP_EN_MASK	(1 << ENETDMAC_CHANCFG_WRAP_EN_SHIFT)
+#define ENETDMAC_CHANCFG_FLOWC_EN_SHIFT	4
+#define ENETDMAC_CHANCFG_FLOWC_EN_MASK	(1 << ENETDMAC_CHANCFG_FLOWC_EN_SHIFT)
 
 /* Interrupt Control/Status register */
-#define ENETDMAC_IR_REG(x)		(0x4 + (x) * 0x10)
+#define ENETDMAC_IR_REG			(0x4)
 #define ENETDMAC_IR_BUFDONE_MASK	(1 << 0)
 #define ENETDMAC_IR_PKTDONE_MASK	(1 << 1)
 #define ENETDMAC_IR_NOTOWNER_MASK	(1 << 2)
 
 /* Interrupt Mask register */
-#define ENETDMAC_IRMASK_REG(x)		(0x8 + (x) * 0x10)
+#define ENETDMAC_IRMASK_REG		(0x8)
 
 /* Maximum Burst Length */
-#define ENETDMAC_MAXBURST_REG(x)	(0xc + (x) * 0x10)
+#define ENETDMAC_MAXBURST_REG		(0xc)
 
 
 /*************************************************************************
@@ -814,26 +884,76 @@
  *************************************************************************/
 
 /* Ring Start Address register */
-#define ENETDMAS_RSTART_REG(x)		((x) * 0x10)
+#define ENETDMAS_RSTART_REG		(0x0)
 
 /* State Ram Word 2 */
-#define ENETDMAS_SRAM2_REG(x)		(0x4 + (x) * 0x10)
+#define ENETDMAS_SRAM2_REG		(0x4)
 
 /* State Ram Word 3 */
-#define ENETDMAS_SRAM3_REG(x)		(0x8 + (x) * 0x10)
+#define ENETDMAS_SRAM3_REG		(0x8)
 
 /* State Ram Word 4 */
-#define ENETDMAS_SRAM4_REG(x)		(0xc + (x) * 0x10)
+#define ENETDMAS_SRAM4_REG		(0xc)
 
 
 /*************************************************************************
  * _REG relative to RSET_ENETSW
  *************************************************************************/
 
+/* Port traffic control */
+#define ENETSW_PTCTRL_REG(x)		(0x0 + (x))
+#define ENETSW_PTCTRL_RXDIS_MASK	(1 << 0)
+#define ENETSW_PTCTRL_TXDIS_MASK	(1 << 1)
+
+/* Switch mode register */
+#define ENETSW_SWMODE_REG		(0xb)
+#define ENETSW_SWMODE_FWD_EN_MASK	(1 << 1)
+
+/* IMP override Register */
+#define ENETSW_IMPOV_REG		(0xe)
+#define ENETSW_IMPOV_FORCE_MASK		(1 << 7)
+#define ENETSW_IMPOV_TXFLOW_MASK	(1 << 5)
+#define ENETSW_IMPOV_RXFLOW_MASK	(1 << 4)
+#define ENETSW_IMPOV_1000_MASK		(1 << 3)
+#define ENETSW_IMPOV_100_MASK		(1 << 2)
+#define ENETSW_IMPOV_FDX_MASK		(1 << 1)
+#define ENETSW_IMPOV_LINKUP_MASK	(1 << 0)
+
+/* Port override Register */
+#define ENETSW_PORTOV_REG(x)		(0x58 + (x))
+#define ENETSW_PORTOV_ENABLE_MASK	(1 << 6)
+#define ENETSW_PORTOV_TXFLOW_MASK	(1 << 5)
+#define ENETSW_PORTOV_RXFLOW_MASK	(1 << 4)
+#define ENETSW_PORTOV_1000_MASK		(1 << 3)
+#define ENETSW_PORTOV_100_MASK		(1 << 2)
+#define ENETSW_PORTOV_FDX_MASK		(1 << 1)
+#define ENETSW_PORTOV_LINKUP_MASK	(1 << 0)
+
+/* MDIO control register */
+#define ENETSW_MDIOC_REG		(0xb0)
+#define ENETSW_MDIOC_EXT_MASK		(1 << 16)
+#define ENETSW_MDIOC_REG_SHIFT		20
+#define ENETSW_MDIOC_PHYID_SHIFT	25
+#define ENETSW_MDIOC_RD_MASK		(1 << 30)
+#define ENETSW_MDIOC_WR_MASK		(1 << 31)
+
+/* MDIO data register */
+#define ENETSW_MDIOD_REG		(0xb4)
+
+/* Global Management Configuration Register */
+#define ENETSW_GMCR_REG			(0x200)
+#define ENETSW_GMCR_RST_MIB_MASK	(1 << 0)
+
 /* MIB register */
 #define ENETSW_MIB_REG(x)		(0x2800 + (x) * 4)
 #define ENETSW_MIB_REG_COUNT		47
 
+/* Jumbo control register port mask register */
+#define ENETSW_JMBCTL_PORT_REG		(0x4004)
+
+/* Jumbo control mib good frame register */
+#define ENETSW_JMBCTL_MAXSIZE_REG	(0x4008)
+
 
 /*************************************************************************
  * _REG relative to RSET_OHCI_PRIV
@@ -1293,7 +1413,7 @@
 #define SPI_6348_RX_DATA		0x80
 #define SPI_6348_RX_DATA_SIZE		0x3f
 
-/* BCM 6358/6262/6368 SPI core */
+/* BCM 3368/6358/6262/6368 SPI core */
 #define SPI_6358_MSG_CTL		0x00	/* 16-bits register */
 #define SPI_6358_MSG_CTL_WIDTH		16
 #define SPI_6358_MSG_DATA		0x02
@@ -1434,4 +1554,11 @@
 
 #define PCIE_DEVICE_OFFSET		0x8000
 
+/*************************************************************************
+ * _REG relative to RSET_OTP
+ *************************************************************************/
+
+#define OTP_USER_BITS_6328_REG(i)	(0x20 + (i) * 4)
+#define   OTP_6328_REG3_TP1_DISABLED	BIT(9)
+
 #endif /* BCM63XX_REGS_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@ struct board_info {
 	/* enabled feature/device */
 	unsigned int	has_enet0:1;
 	unsigned int	has_enet1:1;
+	unsigned int	has_enetsw:1;
 	unsigned int	has_pci:1;
 	unsigned int	has_pccard:1;
 	unsigned int	has_ohci0:1;
@@ -36,6 +37,7 @@ struct board_info {
 	/* ethernet config */
 	struct bcm63xx_enet_platform_data enet0;
 	struct bcm63xx_enet_platform_data enet1;
+	struct bcm63xx_enetsw_platform_data enetsw;
 
 	/* USB config */
 	struct bcm63xx_usbd_platform_data usbd;
@@ -45,6 +47,12 @@ struct board_info {
 
 	/* GPIO LEDs */
 	struct gpio_led leds[5];
+
+	/* External PHY reset GPIO */
+	unsigned int ephy_reset_gpio;
+
+	/* External PHY reset GPIO flags from gpio.h */
+	unsigned long ephy_reset_gpio_flags;
 };
 
 #endif /* ! BOARD_BCM963XX_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/ioremap.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/ioremap.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-bcm63xx/ioremap.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-bcm63xx/ioremap.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,10 @@ static inline phys_t fixup_bigphys_addr(
 static inline int is_bcm63xx_internal_registers(phys_t offset)
 {
 	switch (bcm63xx_get_cpu_id()) {
+	case BCM3368_CPU_ID:
+		if (offset >= 0xfff80000)
+			return 1;
+		break;
 	case BCM6338_CPU_ID:
 	case BCM6345_CPU_ID:
 	case BCM6348_CPU_ID:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,8 @@
 #ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
 #define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
 
+#include <linux/bug.h>
+
 struct device;
 
 extern void octeon_pci_dma_init(void);
@@ -21,18 +23,21 @@ static inline dma_addr_t plat_map_dma_me
 	size_t size)
 {
 	BUG();
+	return 0;
 }
 
 static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
 	struct page *page)
 {
 	BUG();
+	return 0;
 }
 
 static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
 	dma_addr_t dma_addr)
 {
 	BUG();
+	return 0;
 }
 
 static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
@@ -44,6 +49,7 @@ static inline void plat_unmap_dma_mem(st
 static inline int plat_dma_supported(struct device *dev, u64 mask)
 {
 	BUG();
+	return 0;
 }
 
 static inline void plat_extra_sync_for_device(struct device *dev)
@@ -60,6 +66,7 @@ static inline int plat_dma_mapping_error
 					 dma_addr_t dma_addr)
 {
 	BUG();
+	return 0;
 }
 
 dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h	2013-08-25 20:43:22.000000000 -0400
@@ -34,15 +34,10 @@
 	ori	v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
 	dmtc0	v0, CP0_CVMMEMCTL_REG	# Write the cavium mem control register
 	dmfc0	v0, CP0_CVMCTL_REG	# Read the cavium control register
-#ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED
 	# Disable unaligned load/store support but leave HW fixup enabled
+	# Needed for octeon specific memcpy
 	or  v0, v0, 0x5001
 	xor v0, v0, 0x1001
-#else
-	# Disable unaligned load/store and HW fixup support
-	or  v0, v0, 0x5001
-	xor v0, v0, 0x5001
-#endif
 	# Read the processor ID register
 	mfc0 v1, CP0_PRID_REG
 	# Disable instruction prefetching (Octeon Pass1 errata)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-cavium-octeon/spaces.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-cavium-octeon/spaces.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-cavium-octeon/spaces.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-cavium-octeon/spaces.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012 Cavium, Inc.
+ */
+#ifndef _ASM_MACH_CAVIUM_OCTEON_SPACES_H
+#define _ASM_MACH_CAVIUM_OCTEON_SPACES_H
+
+#include <linux/const.h>
+
+#ifdef CONFIG_64BIT
+/* They are all the same and some OCTEON II cores cannot handle 0xa8.. */
+#define CAC_BASE		_AC(0x8000000000000000, UL)
+#define UNCAC_BASE		_AC(0x8000000000000000, UL)
+#define IO_BASE			_AC(0x8000000000000000, UL)
+
+
+#endif /* CONFIG_64BIT */
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* _ASM_MACH_CAVIUM_OCTEON_SPACES_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-generic/dma-coherence.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-generic/dma-coherence.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-generic/dma-coherence.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-generic/dma-coherence.h	2013-08-25 20:43:22.000000000 -0400
@@ -66,4 +66,16 @@ static inline int plat_device_is_coheren
 #endif
 }
 
+#ifdef CONFIG_SWIOTLB
+static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+	return paddr;
+}
+
+static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+	return daddr;
+}
+#endif
+
 #endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-generic/kernel-entry-init.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-generic/kernel-entry-init.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-generic/kernel-entry-init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-generic/kernel-entry-init.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,8 +12,8 @@
 /* Intentionally empty macro, used in head.S. Override in
  * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
  */
-.macro	kernel_entry_setup
-.endm
+	.macro	kernel_entry_setup
+	.endm
 
 /*
  * Do SMP slave processor setup necessary before we can savely execute C code.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-generic/spaces.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-generic/spaces.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-generic/spaces.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-generic/spaces.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,8 +25,12 @@
 #else
 #define CAC_BASE		_AC(0x80000000, UL)
 #endif
+#ifndef IO_BASE
 #define IO_BASE			_AC(0xa0000000, UL)
+#endif
+#ifndef UNCAC_BASE
 #define UNCAC_BASE		_AC(0xa0000000, UL)
+#endif
 
 #ifndef MAP_BASE
 #ifdef CONFIG_KVM_GUEST
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-ip27/kernel-entry-init.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-ip27/kernel-entry-init.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-ip27/kernel-entry-init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-ip27/kernel-entry-init.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,53 @@
 	.endm
 
 /*
+ * TLB bits
+ */
+#define PAGE_GLOBAL		(1 << 6)
+#define PAGE_VALID		(1 << 7)
+#define PAGE_DIRTY		(1 << 8)
+#define CACHE_CACHABLE_COW	(5 << 9)
+
+	/*
+	 * inputs are the text nasid in t1, data nasid in t2.
+	 */
+	.macro MAPPED_KERNEL_SETUP_TLB
+#ifdef CONFIG_MAPPED_KERNEL
+	/*
+	 * This needs to read the nasid - assume 0 for now.
+	 * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
+	 * 0+DVG in tlblo_1.
+	 */
+	dli	t0, 0xffffffffc0000000
+	dmtc0	t0, CP0_ENTRYHI
+	li	t0, 0x1c000		# Offset of text into node memory
+	dsll	t1, NASID_SHFT		# Shift text nasid into place
+	dsll	t2, NASID_SHFT		# Same for data nasid
+	or	t1, t1, t0		# Physical load address of kernel text
+	or	t2, t2, t0		# Physical load address of kernel data
+	dsrl	t1, 12			# 4K pfn
+	dsrl	t2, 12			# 4K pfn
+	dsll	t1, 6			# Get pfn into place
+	dsll	t2, 6			# Get pfn into place
+	li	t0, ((PAGE_GLOBAL | PAGE_VALID | CACHE_CACHABLE_COW) >> 6)
+	or	t0, t0, t1
+	mtc0	t0, CP0_ENTRYLO0	# physaddr, VG, cach exlwr
+	li	t0, ((PAGE_GLOBAL | PAGE_VALID |  PAGE_DIRTY | CACHE_CACHABLE_COW) >> 6)
+	or	t0, t0, t2
+	mtc0	t0, CP0_ENTRYLO1	# physaddr, DVG, cach exlwr
+	li	t0, 0x1ffe000		# MAPPED_KERN_TLBMASK, TLBPGMASK_16M
+	mtc0	t0, CP0_PAGEMASK
+	li	t0, 0			# KMAP_INX
+	mtc0	t0, CP0_INDEX
+	li	t0, 1
+	mtc0	t0, CP0_WIRED
+	tlbwi
+#else
+	mtc0	zero, CP0_WIRED
+#endif
+	.endm
+
+/*
  * Intentionally empty macro, used in head.S. Override in
  * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
  */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-ip28/spaces.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-ip28/spaces.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-ip28/spaces.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-ip28/spaces.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,11 +11,14 @@
 #ifndef _ASM_MACH_IP28_SPACES_H
 #define _ASM_MACH_IP28_SPACES_H
 
-#define CAC_BASE		0xa800000000000000
+#define CAC_BASE	_AC(0xa800000000000000, UL)
 
-#define HIGHMEM_START		(~0UL)
+#define HIGHMEM_START	(~0UL)
 
-#define PHYS_OFFSET		_AC(0x20000000, UL)
+#define PHYS_OFFSET	_AC(0x20000000, UL)
+
+#define UNCAC_BASE	_AC(0xc0000000, UL)     /* 0xa0000000 + PHYS_OFFSET */
+#define IO_BASE		UNCAC_BASE
 
 #include <asm/mach-generic/spaces.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-jz4740/dma.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-jz4740/dma.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-jz4740/dma.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-jz4740/dma.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,8 +16,6 @@
 #ifndef __ASM_MACH_JZ4740_DMA_H__
 #define __ASM_MACH_JZ4740_DMA_H__
 
-struct jz4740_dma_chan;
-
 enum jz4740_dma_request_type {
 	JZ4740_DMA_TYPE_AUTO_REQUEST	= 8,
 	JZ4740_DMA_TYPE_UART_TRANSMIT	= 20,
@@ -33,58 +31,4 @@ enum jz4740_dma_request_type {
 	JZ4740_DMA_TYPE_SLCD		= 30,
 };
 
-enum jz4740_dma_width {
-	JZ4740_DMA_WIDTH_32BIT	= 0,
-	JZ4740_DMA_WIDTH_8BIT	= 1,
-	JZ4740_DMA_WIDTH_16BIT	= 2,
-};
-
-enum jz4740_dma_transfer_size {
-	JZ4740_DMA_TRANSFER_SIZE_4BYTE	= 0,
-	JZ4740_DMA_TRANSFER_SIZE_1BYTE	= 1,
-	JZ4740_DMA_TRANSFER_SIZE_2BYTE	= 2,
-	JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3,
-	JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4,
-};
-
-enum jz4740_dma_flags {
-	JZ4740_DMA_SRC_AUTOINC = 0x2,
-	JZ4740_DMA_DST_AUTOINC = 0x1,
-};
-
-enum jz4740_dma_mode {
-	JZ4740_DMA_MODE_SINGLE	= 0,
-	JZ4740_DMA_MODE_BLOCK	= 1,
-};
-
-struct jz4740_dma_config {
-	enum jz4740_dma_width src_width;
-	enum jz4740_dma_width dst_width;
-	enum jz4740_dma_transfer_size transfer_size;
-	enum jz4740_dma_request_type request_type;
-	enum jz4740_dma_flags flags;
-	enum jz4740_dma_mode mode;
-};
-
-typedef void (*jz4740_dma_complete_callback_t)(struct jz4740_dma_chan *, int, void *);
-
-struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name);
-void jz4740_dma_free(struct jz4740_dma_chan *dma);
-
-void jz4740_dma_configure(struct jz4740_dma_chan *dma,
-	const struct jz4740_dma_config *config);
-
-
-void jz4740_dma_enable(struct jz4740_dma_chan *dma);
-void jz4740_dma_disable(struct jz4740_dma_chan *dma);
-
-void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src);
-void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst);
-void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count);
-
-uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma);
-
-void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
-	jz4740_dma_complete_callback_t cb);
-
 #endif	/* __ASM_JZ4740_DMA_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-jz4740/platform.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-jz4740/platform.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-jz4740/platform.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-jz4740/platform.h	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,7 @@ extern struct platform_device jz4740_cod
 extern struct platform_device jz4740_adc_device;
 extern struct platform_device jz4740_wdt_device;
 extern struct platform_device jz4740_pwm_device;
+extern struct platform_device jz4740_dma_device;
 
 void jz4740_serial_device_register(void);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-pmcs-msp71xx/gpio.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-pmcs-msp71xx/gpio.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-pmcs-msp71xx/gpio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-pmcs-msp71xx/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,46 +0,0 @@
-/*
- * include/asm-mips/pmc-sierra/msp71xx/gpio.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * @author Patrick Glass <patrickglass@gmail.com>
- */
-
-#ifndef __PMC_MSP71XX_GPIO_H
-#define __PMC_MSP71XX_GPIO_H
-
-/* Max number of gpio's is 28 on chip plus 3 banks of I2C IO Expanders */
-#define ARCH_NR_GPIOS (28 + (3 * 8))
-
-/* new generic GPIO API - see Documentation/gpio.txt */
-#include <asm-generic/gpio.h>
-
-#define gpio_get_value	__gpio_get_value
-#define gpio_set_value	__gpio_set_value
-#define gpio_cansleep	__gpio_cansleep
-
-/* Setup calls for the gpio and gpio extended */
-extern void msp71xx_init_gpio(void);
-extern void msp71xx_init_gpio_extended(void);
-extern int msp71xx_set_output_drive(unsigned gpio, int value);
-
-/* Custom output drive functionss */
-static inline int gpio_set_output_drive(unsigned gpio, int value)
-{
-	return msp71xx_set_output_drive(gpio, value);
-}
-
-/* IRQ's are not supported for gpio lines */
-static inline int gpio_to_irq(unsigned gpio)
-{
-	return -EINVAL;
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
-	return -EINVAL;
-}
-
-#endif /* __PMC_MSP71XX_GPIO_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,83 +0,0 @@
-/*
- * This is a direct copy of the ev96100.h file, with a global
- * search and replace.	The numbers are the same.
- *
- * The reason I'm duplicating this is so that the 64120/96100
- * defines won't be confusing in the source code.
- */
-#ifndef __ASM_MIPS_GT64120_H
-#define __ASM_MIPS_GT64120_H
-
-/*
- * This is the CPU physical memory map of PPMC Board:
- *
- *    0x00000000-0x03FFFFFF	 - 64MB SDRAM (SCS[0]#)
- *    0x1C000000-0x1C000000	 - LED (CS0)
- *    0x1C800000-0x1C800007	 - UART 16550 port (CS1)
- *    0x1F000000-0x1F000000	 - MailBox (CS3)
- *    0x1FC00000-0x20000000	 - 4MB Flash (BOOT CS)
- */
-
-#define WRPPMC_SDRAM_SCS0_BASE	0x00000000
-#define WRPPMC_SDRAM_SCS0_SIZE	0x04000000
-
-#define WRPPMC_UART16550_BASE	0x1C800000
-#define WRPPMC_UART16550_CLOCK	3686400 /* 3.68MHZ */
-
-#define WRPPMC_LED_BASE		0x1C000000
-#define WRPPMC_MBOX_BASE	0x1F000000
-
-#define WRPPMC_BOOTROM_BASE	0x1FC00000
-#define WRPPMC_BOOTROM_SIZE	0x00400000 /* 4M Flash */
-
-#define WRPPMC_MIPS_TIMER_IRQ	7 /* MIPS compare/count timer interrupt */
-#define WRPPMC_UART16550_IRQ	6
-#define WRPPMC_PCI_INTA_IRQ	3
-
-/*
- * PCI Bus I/O and Memory resources allocation
- *
- * NOTE: We only have PCI_0 hose interface
- */
-#define GT_PCI_MEM_BASE 0x13000000UL
-#define GT_PCI_MEM_SIZE 0x02000000UL
-#define GT_PCI_IO_BASE	0x11000000UL
-#define GT_PCI_IO_SIZE	0x02000000UL
-
-/*
- * PCI interrupts will come in on either the INTA or INTD interrupt lines,
- * which are mapped to the #2 and #5 interrupt pins of the MIPS.  On our
- * boards, they all either come in on IntD or they all come in on IntA, they
- * aren't mixed. There can be numerous PCI interrupts, so we keep a list of the
- * "requested" interrupt numbers and go through the list whenever we get an
- * IntA/D.
- *
- * Interrupts < 8 are directly wired to the processor; PCI INTA is 8 and
- * INTD is 11.
- */
-#define GT_TIMER	4
-#define GT_INTA		2
-#define GT_INTD		5
-
-#ifndef __ASSEMBLY__
-
-/*
- * GT64120 internal register space base address
- */
-extern unsigned long gt64120_base;
-
-#define GT64120_BASE	(gt64120_base)
-
-/* define WRPPMC_EARLY_DEBUG to enable early output something to UART */
-#undef WRPPMC_EARLY_DEBUG
-
-#ifdef WRPPMC_EARLY_DEBUG
-extern void wrppmc_led_on(int mask);
-extern void wrppmc_led_off(int mask);
-extern void wrppmc_early_printk(const char *fmt, ...);
-#else
-#define wrppmc_early_printk(fmt, ...) do {} while (0)
-#endif /* WRPPMC_EARLY_DEBUG */
-
-#endif /* __ASSEMBLY__ */
-#endif /* __ASM_MIPS_GT64120_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mach-wrppmc/war.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-wrppmc/war.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mach-wrppmc/war.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mach-wrppmc/war.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_WRPPMC_WAR_H
-#define __ASM_MIPS_MACH_WRPPMC_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR	0
-#define R4600_V1_HIT_CACHEOP_WAR	0
-#define R4600_V2_HIT_CACHEOP_WAR	0
-#define R5432_CP0_INTERRUPT_WAR		0
-#define BCM1250_M3_WAR			0
-#define SIBYTE_1956_WAR			0
-#define MIPS4K_ICACHE_REFILL_WAR	0
-#define MIPS_CACHE_SYNC_WAR		0
-#define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define ICACHE_REFILLS_WORKAROUND_WAR	1
-#define R10000_LLSC_WAR			0
-#define MIPS34K_MISSED_ITLB_WAR		0
-
-#endif /* __ASM_MIPS_MACH_WRPPMC_WAR_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mips-boards/generic.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mips-boards/generic.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mips-boards/generic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mips-boards/generic.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,12 +24,6 @@
 #define ASCII_DISPLAY_POS_BASE	   0x1f000418
 
 /*
- * Reset register.
- */
-#define SOFTRES_REG	  0x1f000500
-#define GORESET		  0x42
-
-/*
  * Revision register.
  */
 #define MIPS_REVISION_REG		   0x1fc00010
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mipsregs.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mipsregs.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mipsregs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mipsregs.h	2013-08-25 20:43:22.000000000 -0400
@@ -596,7 +596,7 @@
 #define MIPS_CONF3_RXI		(_ULCAST_(1) << 12)
 #define MIPS_CONF3_ULRI		(_ULCAST_(1) << 13)
 #define MIPS_CONF3_ISA		(_ULCAST_(3) << 14)
-#define MIPS_CONF3_ISA_OE	(_ULCAST_(3) << 16)
+#define MIPS_CONF3_ISA_OE	(_ULCAST_(1) << 16)
 #define MIPS_CONF3_VZ		(_ULCAST_(1) << 23)
 
 #define MIPS_CONF4_MMUSIZEEXT	(_ULCAST_(255) << 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/mmu_context.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mmu_context.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/mmu_context.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/mmu_context.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,11 +28,7 @@
 
 #define TLBMISS_HANDLER_SETUP_PGD(pgd)					\
 do {									\
-	void (*tlbmiss_handler_setup_pgd)(unsigned long);		\
-	extern u32 tlbmiss_handler_setup_pgd_array[16];			\
-									\
-	tlbmiss_handler_setup_pgd =					\
-		(__typeof__(tlbmiss_handler_setup_pgd)) tlbmiss_handler_setup_pgd_array; \
+	extern void tlbmiss_handler_setup_pgd(unsigned long);		\
 	tlbmiss_handler_setup_pgd((unsigned long)(pgd));		\
 } while (0)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/netlogic/common.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/netlogic/common.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/netlogic/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/netlogic/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -39,11 +39,17 @@
  * Common SMP definitions
  */
 #define RESET_VEC_PHYS		0x1fc00000
+#define RESET_VEC_SIZE		8192		/* 8KB reset code and data */
 #define RESET_DATA_PHYS		(RESET_VEC_PHYS + (1<<10))
+
+/* Offsets of parameters in the RESET_DATA_PHYS area */
 #define BOOT_THREAD_MODE	0
 #define BOOT_NMI_LOCK		4
 #define BOOT_NMI_HANDLER	8
 
+/* CPU ready flags for each CPU */
+#define BOOT_CPU_READY		2048
+
 #ifndef __ASSEMBLY__
 #include <linux/cpumask.h>
 #include <linux/spinlock.h>
@@ -59,23 +65,32 @@ int nlm_wakeup_secondary_cpus(void);
 void nlm_rmiboot_preboot(void);
 void nlm_percpu_init(int hwcpuid);
 
+static inline void *
+nlm_get_boot_data(int offset)
+{
+	return (void *)(CKSEG1ADDR(RESET_DATA_PHYS) + offset);
+}
+
 static inline void
 nlm_set_nmi_handler(void *handler)
 {
-	char *reset_data;
+	void *nmih = nlm_get_boot_data(BOOT_NMI_HANDLER);
 
-	reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
-	*(int64_t *)(reset_data + BOOT_NMI_HANDLER) = (long)handler;
+	*(int64_t *)nmih = (long)handler;
 }
 
 /*
  * Misc.
  */
+void nlm_init_boot_cpu(void);
 unsigned int nlm_get_cpu_frequency(void);
 void nlm_node_init(int node);
 extern struct plat_smp_ops nlm_smp_ops;
 extern char nlm_reset_entry[], nlm_reset_entry_end[];
 
+/* SWIOTLB */
+extern struct dma_map_ops nlm_swiotlb_dma_ops;
+
 extern unsigned int nlm_threads_per_core;
 extern cpumask_t nlm_cpumask;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/netlogic/xlp-hal/pic.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/netlogic/xlp-hal/pic.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/netlogic/xlp-hal/pic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/netlogic/xlp-hal/pic.h	2013-08-25 20:43:22.000000000 -0400
@@ -315,7 +315,7 @@ nlm_pic_send_ipi(uint64_t base, int hwt,
 {
 	uint64_t ipi;
 
-	ipi = (nmi << 31) | (irq << 20);
+	ipi = ((uint64_t)nmi << 31) | (irq << 20);
 	ipi |= ((hwt >> 4) << 16) | (1 << (hwt & 0xf)); /* cpuset and mask */
 	nlm_write_pic_reg(base, PIC_IPI_CTL, ipi);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/netlogic/xlp-hal/xlp.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/netlogic/xlp-hal/xlp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/netlogic/xlp-hal/xlp.h	2013-08-25 20:43:22.000000000 -0400
@@ -59,6 +59,7 @@ void xlp_wakeup_secondary_cpus(void);
 
 void xlp_mmu_init(void);
 void nlm_hal_init(void);
+void *xlp_dt_init(void *fdtp);
 
 #endif /* !__ASSEMBLY__ */
 #endif /* _ASM_NLM_XLP_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/netlogic/xlr/fmn.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/netlogic/xlr/fmn.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/netlogic/xlr/fmn.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/netlogic/xlr/fmn.h	2013-08-25 20:43:22.000000000 -0400
@@ -175,6 +175,10 @@
 #define nlm_write_c2_cc14(s, v)		__write_32bit_c2_register($30, s, v)
 #define nlm_write_c2_cc15(s, v)		__write_32bit_c2_register($31, s, v)
 
+#define nlm_read_c2_status0()		__read_32bit_c2_register($2, 0)
+#define nlm_write_c2_status0(v)		__write_32bit_c2_register($2, 0, v)
+#define nlm_read_c2_status1()		__read_32bit_c2_register($2, 1)
+#define nlm_write_c2_status1(v)		__write_32bit_c2_register($2, 1, v)
 #define nlm_read_c2_status(sel)		__read_32bit_c2_register($2, 0)
 #define nlm_read_c2_config()		__read_32bit_c2_register($3, 0)
 #define nlm_write_c2_config(v)		__write_32bit_c2_register($3, 0, v)
@@ -237,7 +241,7 @@ static inline void nlm_msgwait(unsigned
 /*
  * Disable interrupts and enable COP2 access
  */
-static inline uint32_t nlm_cop2_enable(void)
+static inline uint32_t nlm_cop2_enable_irqsave(void)
 {
 	uint32_t sr = read_c0_status();
 
@@ -245,7 +249,7 @@ static inline uint32_t nlm_cop2_enable(v
 	return sr;
 }
 
-static inline void nlm_cop2_restore(uint32_t sr)
+static inline void nlm_cop2_disable_irqrestore(uint32_t sr)
 {
 	write_c0_status(sr);
 }
@@ -296,7 +300,7 @@ static inline int nlm_fmn_send(unsigned
 	 */
 	for (i = 0; i < 8; i++) {
 		nlm_msgsnd(dest);
-		status = nlm_read_c2_status(0);
+		status = nlm_read_c2_status0();
 		if ((status & 0x2) == 1)
 			pr_info("Send pending fail!\n");
 		if ((status & 0x4) == 0)
@@ -316,7 +320,7 @@ static inline int nlm_fmn_receive(int bu
 
 	/* wait for load pending to clear */
 	do {
-		status = nlm_read_c2_status(1);
+		status = nlm_read_c2_status0();
 	} while ((status & 0x08) != 0);
 
 	/* receive error bits */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/octeon/cvmx-bootinfo.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/octeon/cvmx-bootinfo.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/octeon/cvmx-bootinfo.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/octeon/cvmx-bootinfo.h	2013-08-25 20:43:22.000000000 -0400
@@ -227,6 +227,7 @@ enum cvmx_board_types_enum {
 	 * use any numbers in this range.
 	 */
 	CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
+	CVMX_BOARD_TYPE_UBNT_E100 = 20002,
 	CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
 
 	/* The remaining range is reserved for future use. */
@@ -325,6 +326,7 @@ static inline const char *cvmx_board_typ
 
 		    /* Customer private range */
 		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
+		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
 		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
 	}
 	return "Unsupported Board";
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/page.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/page.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/page.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/page.h	2013-08-25 20:43:22.000000000 -0400
@@ -205,10 +205,8 @@ extern int __virt_addr_valid(const volat
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE +	\
-								PHYS_OFFSET)
-#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET -	\
-								PHYS_OFFSET)
+#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + UNCAC_BASE)
+#define CAC_ADDR(addr)		((addr) - UNCAC_BASE + PAGE_OFFSET)
 
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/pci.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/pci.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/pci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/pci.h	2013-08-25 20:43:22.000000000 -0400
@@ -52,7 +52,6 @@ struct pci_controller {
 /*
  * Used by boards to register their PCI busses before the actual scanning.
  */
-extern struct pci_controller * alloc_pci_controller(void);
 extern void register_pci_controller(struct pci_controller *hose);
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -394,9 +394,7 @@ static inline int io_remap_pfn_range(str
 	phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
 	return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
 }
-#else
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
+#define io_remap_pfn_range io_remap_pfn_range
 #endif
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/processor.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/processor.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/processor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/processor.h	2013-08-25 20:43:22.000000000 -0400
@@ -137,7 +137,7 @@ union mips_watch_reg_state {
 	struct mips3264_watch_reg_state mips3264;
 };
 
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#if defined(CONFIG_CPU_CAVIUM_OCTEON)
 
 struct octeon_cop2_state {
 	/* DMFC2 rt, 0x0201 */
@@ -182,13 +182,26 @@ struct octeon_cop2_state {
 	/* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */
 	unsigned long	cop2_gfm_result[2];
 };
-#define INIT_OCTEON_COP2 {0,}
+#define COP2_INIT						\
+	.cp2			= {0,},
 
 struct octeon_cvmseg_state {
 	unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE]
 			    [cpu_dcache_line_size() / sizeof(unsigned long)];
 };
 
+#elif defined(CONFIG_CPU_XLP)
+struct nlm_cop2_state {
+	u64	rx[4];
+	u64	tx[4];
+	u32	tx_msg_status;
+	u32	rx_msg_status;
+};
+
+#define COP2_INIT						\
+	.cp2			= {{0}, {0}, 0, 0},
+#else
+#define COP2_INIT
 #endif
 
 typedef struct {
@@ -231,8 +244,11 @@ struct thread_struct {
 	unsigned long cp0_baduaddr;	/* Last kernel fault accessing USEG */
 	unsigned long error_code;
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
-    struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
-    struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
+	struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
+	struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
+#endif
+#ifdef CONFIG_CPU_XLP
+	struct nlm_cop2_state cp2;
 #endif
 	struct mips_abi *abi;
 };
@@ -245,13 +261,6 @@ struct thread_struct {
 #define FPAFF_INIT
 #endif /* CONFIG_MIPS_MT_FPAFF */
 
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-#define OCTEON_INIT						\
-	.cp2			= INIT_OCTEON_COP2,
-#else
-#define OCTEON_INIT
-#endif /* CONFIG_CPU_CAVIUM_OCTEON */
-
 #define INIT_THREAD  {						\
 	/*							\
 	 * Saved main processor registers			\
@@ -300,9 +309,9 @@ struct thread_struct {
 	.cp0_baduaddr		= 0,				\
 	.error_code		= 0,				\
 	/*							\
-	 * Cavium Octeon specifics (null if not Octeon)		\
+	 * Platform specific cop2 registers(null if no COP2)	\
 	 */							\
-	OCTEON_INIT						\
+	COP2_INIT						\
 }
 
 struct task_struct;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/stackframe.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/stackframe.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/stackframe.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/stackframe.h	2013-08-25 20:43:22.000000000 -0400
@@ -70,6 +70,14 @@
 #ifndef CONFIG_CPU_HAS_SMARTMIPS
 		LONG_S	v1, PT_LO(sp)
 #endif
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+		/*
+		 * The Octeon multiplier state is affected by general
+		 * multiply instructions. It must be saved before and
+		 * kernel code might corrupt it
+		 */
+		jal     octeon_mult_save
+#endif
 		.endm
 
 		.macro	SAVE_STATIC
@@ -218,17 +226,8 @@
 		ori	$28, sp, _THREAD_MASK
 		xori	$28, _THREAD_MASK
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
-		.set	mips64
-		pref	0, 0($28)	/* Prefetch the current pointer */
-		pref	0, PT_R31(sp)	/* Prefetch the $31(ra) */
-		/* The Octeon multiplier state is affected by general multiply
-		    instructions. It must be saved before and kernel code might
-		    corrupt it */
-		jal	octeon_mult_save
-		LONG_L	v1, 0($28)  /* Load the current pointer */
-			 /* Restore $31(ra) that was changed by the jal */
-		LONG_L	ra, PT_R31(sp)
-		pref	0, 0(v1)    /* Prefetch the current thread */
+		.set    mips64
+		pref    0, 0($28)       /* Prefetch the current pointer */
 #endif
 		.set	pop
 		.endm
@@ -248,6 +247,10 @@
 		.endm
 
 		.macro	RESTORE_TEMP
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+		/* Restore the Octeon multiplier state */
+		jal	octeon_mult_restore
+#endif
 #ifdef CONFIG_CPU_HAS_SMARTMIPS
 		LONG_L	$24, PT_ACX(sp)
 		mtlhx	$24
@@ -360,10 +363,6 @@
 		DVPE	5				# dvpe a1
 		jal	mips_ihb
 #endif /* CONFIG_MIPS_MT_SMTC */
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-		/* Restore the Octeon multiplier state */
-		jal	octeon_mult_restore
-#endif
 		mfc0	a0, CP0_STATUS
 		ori	a0, STATMASK
 		xori	a0, STATMASK
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/stackprotector.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/stackprotector.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/stackprotector.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/stackprotector.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,40 @@
+/*
+ * GCC stack protector support.
+ *
+ * (This is directly adopted from the ARM implementation)
+ *
+ * Stack protector works by putting predefined pattern at the start of
+ * the stack frame and verifying that it hasn't been overwritten when
+ * returning from the function.  The pattern is called stack canary
+ * and gcc expects it to be defined by a global variable called
+ * "__stack_chk_guard" on MIPS.  This unfortunately means that on SMP
+ * we cannot have a different canary value per task.
+ */
+
+#ifndef _ASM_STACKPROTECTOR_H
+#define _ASM_STACKPROTECTOR_H 1
+
+#include <linux/random.h>
+#include <linux/version.h>
+
+extern unsigned long __stack_chk_guard;
+
+/*
+ * Initialize the stackprotector canary value.
+ *
+ * NOTE: this must only be called from functions that never return,
+ * and it must always be inlined.
+ */
+static __always_inline void boot_init_stack_canary(void)
+{
+	unsigned long canary;
+
+	/* Try to get a semi random initial value. */
+	get_random_bytes(&canary, sizeof(canary));
+	canary ^= LINUX_VERSION_CODE;
+
+	current->stack_canary = canary;
+	__stack_chk_guard = current->stack_canary;
+}
+
+#endif	/* _ASM_STACKPROTECTOR_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/switch_to.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/switch_to.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/switch_to.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/switch_to.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@
 #include <asm/cpu-features.h>
 #include <asm/watch.h>
 #include <asm/dsp.h>
+#include <asm/cop2.h>
 
 struct task_struct;
 
@@ -66,10 +67,18 @@ do {									\
 
 #define switch_to(prev, next, last)					\
 do {									\
-	u32 __usedfpu;							\
+	u32 __usedfpu, __c0_stat;					\
 	__mips_mt_fpaff_switch_to(prev);				\
 	if (cpu_has_dsp)						\
 		__save_dsp(prev);					\
+	if (cop2_present && (KSTK_STATUS(prev) & ST0_CU2)) {		\
+		if (cop2_lazy_restore)					\
+			KSTK_STATUS(prev) &= ~ST0_CU2;			\
+		__c0_stat = read_c0_status();				\
+		write_c0_status(__c0_stat | ST0_CU2);			\
+		cop2_save(&prev->thread.cp2);				\
+		write_c0_status(__c0_stat & ~ST0_CU2);			\
+	}								\
 	__clear_software_ll_bit();					\
 	__usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU);	\
 	(last) = resume(prev, next, task_thread_info(next), __usedfpu); \
@@ -77,6 +86,14 @@ do {									\
 
 #define finish_arch_switch(prev)					\
 do {									\
+	u32 __c0_stat;							\
+	if (cop2_present && !cop2_lazy_restore &&			\
+			(KSTK_STATUS(current) & ST0_CU2)) {		\
+		__c0_stat = read_c0_status();				\
+		write_c0_status(__c0_stat | ST0_CU2);			\
+		cop2_restore(&current->thread.cp2);			\
+		write_c0_status(__c0_stat & ~ST0_CU2);			\
+	}								\
 	if (cpu_has_dsp)						\
 		__restore_dsp(current);					\
 	if (cpu_has_userlocal)						\
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/thread_info.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/thread_info.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/thread_info.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/thread_info.h	2013-08-25 20:43:22.000000000 -0400
@@ -109,6 +109,7 @@ static inline struct thread_info *curren
 #define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */
 #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
+#define TIF_NOHZ		19	/* in adaptive nohz mode */
 #define TIF_FIXADE		20	/* Fix address errors in software */
 #define TIF_LOGADE		21	/* Log address errors to syslog */
 #define TIF_32BIT_REGS		22	/* also implies 16/32 fprs */
@@ -124,6 +125,7 @@ static inline struct thread_info *curren
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_USEDFPU		(1<<TIF_USEDFPU)
+#define _TIF_NOHZ		(1<<TIF_NOHZ)
 #define _TIF_FIXADE		(1<<TIF_FIXADE)
 #define _TIF_LOGADE		(1<<TIF_LOGADE)
 #define _TIF_32BIT_REGS		(1<<TIF_32BIT_REGS)
@@ -131,14 +133,19 @@ static inline struct thread_info *curren
 #define _TIF_FPUBOUND		(1<<TIF_FPUBOUND)
 #define _TIF_LOAD_WATCH		(1<<TIF_LOAD_WATCH)
 
+#define _TIF_WORK_SYSCALL_ENTRY	(_TIF_NOHZ | _TIF_SYSCALL_TRACE |	\
+				 _TIF_SYSCALL_AUDIT)
+
 /* work to do in syscall_trace_leave() */
-#define _TIF_WORK_SYSCALL_EXIT	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
+#define _TIF_WORK_SYSCALL_EXIT	(_TIF_NOHZ | _TIF_SYSCALL_TRACE |	\
+				 _TIF_SYSCALL_AUDIT)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK		\
 	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
 /* work to do on any return to u-space */
-#define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK | _TIF_WORK_SYSCALL_EXIT)
+#define _TIF_ALLWORK_MASK	(_TIF_NOHZ | _TIF_WORK_MASK |		\
+				 _TIF_WORK_SYSCALL_EXIT)
 
 #endif /* __KERNEL__ */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/uasm.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/uasm.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/uasm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/uasm.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,12 +13,8 @@
 
 #ifdef CONFIG_EXPORT_UASM
 #include <linux/export.h>
-#define __uasminit
-#define __uasminitdata
 #define UASM_EXPORT_SYMBOL(sym) EXPORT_SYMBOL(sym)
 #else
-#define __uasminit __cpuinit
-#define __uasminitdata __cpuinitdata
 #define UASM_EXPORT_SYMBOL(sym)
 #endif
 
@@ -54,43 +50,36 @@
 #endif
 
 #define Ip_u1u2u3(op)							\
-void __uasminit								\
-ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
 
 #define Ip_u2u1u3(op)							\
-void __uasminit								\
-ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
 
 #define Ip_u3u1u2(op)							\
-void __uasminit								\
-ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
 
 #define Ip_u1u2s3(op)							\
-void __uasminit								\
-ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c)
+void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c)
 
 #define Ip_u2s3u1(op)							\
-void __uasminit								\
-ISAOPC(op)(u32 **buf, unsigned int a, signed int b, unsigned int c)
+void ISAOPC(op)(u32 **buf, unsigned int a, signed int b, unsigned int c)
 
 #define Ip_u2u1s3(op)							\
-void __uasminit								\
-ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c)
+void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c)
 
 #define Ip_u2u1msbu3(op)						\
-void __uasminit								\
-ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c,	\
+void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \
 	   unsigned int d)
 
 #define Ip_u1u2(op)							\
-void __uasminit ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b)
+void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b)
 
 #define Ip_u1s2(op)							\
-void __uasminit ISAOPC(op)(u32 **buf, unsigned int a, signed int b)
+void ISAOPC(op)(u32 **buf, unsigned int a, signed int b)
 
-#define Ip_u1(op) void __uasminit ISAOPC(op)(u32 **buf, unsigned int a)
+#define Ip_u1(op) void ISAOPC(op)(u32 **buf, unsigned int a)
 
-#define Ip_0(op) void __uasminit ISAOPC(op)(u32 **buf)
+#define Ip_0(op) void ISAOPC(op)(u32 **buf)
 
 Ip_u2u1s3(_addiu);
 Ip_u3u1u2(_addu);
@@ -163,7 +152,7 @@ struct uasm_label {
 	int lab;
 };
 
-void __uasminit ISAFUNC(uasm_build_label)(struct uasm_label **lab, u32 *addr,
+void ISAFUNC(uasm_build_label)(struct uasm_label **lab, u32 *addr,
 			int lid);
 #ifdef CONFIG_64BIT
 int ISAFUNC(uasm_in_compat_space_p)(long addr);
@@ -174,7 +163,7 @@ void ISAFUNC(UASM_i_LA_mostly)(u32 **buf
 void ISAFUNC(UASM_i_LA)(u32 **buf, unsigned int rs, long addr);
 
 #define UASM_L_LA(lb)							\
-static inline void __uasminit ISAFUNC(uasm_l##lb)(struct uasm_label **lab, u32 *addr) \
+static inline void ISAFUNC(uasm_l##lb)(struct uasm_label **lab, u32 *addr) \
 {									\
 	ISAFUNC(uasm_build_label)(lab, addr, label##lb);		\
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/asm/xtalk/xtalk.h linux-libre-3.11-rc7-gnu/arch/mips/include/asm/xtalk/xtalk.h
--- linux-libre-3.10-gnu/arch/mips/include/asm/xtalk/xtalk.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/asm/xtalk/xtalk.h	2013-08-25 20:43:22.000000000 -0400
@@ -47,6 +47,15 @@ typedef struct xtalk_piomap_s *xtalk_pio
 #define XIO_PORT(x)	((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT))
 #define XIO_PACK(p, o)	((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS))
 
+#ifdef CONFIG_PCI
+extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
+#else
+static inline int bridge_probe(nasid_t nasid, int widget, int masterwid)
+{
+	return 0;
+}
+#endif
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_XTALK_XTALK_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/uapi/asm/fcntl.h linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/fcntl.h
--- linux-libre-3.10-gnu/arch/mips/include/uapi/asm/fcntl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/fcntl.h	2013-08-25 20:43:22.000000000 -0400
@@ -5,9 +5,10 @@
  *
  * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle
  */
-#ifndef _ASM_FCNTL_H
-#define _ASM_FCNTL_H
+#ifndef _UAPI_ASM_FCNTL_H
+#define _UAPI_ASM_FCNTL_H
 
+#include <asm/sgidefs.h>
 
 #define O_APPEND	0x0008
 #define O_DSYNC		0x0010	/* used to be O_SYNC, see below */
@@ -55,14 +56,15 @@
  * contain all the same fields as struct flock.
  */
 
-#ifdef CONFIG_32BIT
+#if _MIPS_SIM != _MIPS_SIM_ABI64
+
 #include <linux/types.h>
 
 struct flock {
 	short	l_type;
 	short	l_whence;
-	off_t	l_start;
-	off_t	l_len;
+	__kernel_off_t	l_start;
+	__kernel_off_t	l_len;
 	long	l_sysid;
 	__kernel_pid_t l_pid;
 	long	pad[4];
@@ -70,8 +72,8 @@ struct flock {
 
 #define HAVE_ARCH_STRUCT_FLOCK
 
-#endif /* CONFIG_32BIT */
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #include <asm-generic/fcntl.h>
 
-#endif /* _ASM_FCNTL_H */
+#endif /* _UAPI_ASM_FCNTL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/uapi/asm/inst.h linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/inst.h
--- linux-libre-3.10-gnu/arch/mips/include/uapi/asm/inst.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/inst.h	2013-08-25 20:43:22.000000000 -0400
@@ -409,10 +409,11 @@ enum mm_32f_73_minor_op {
 enum mm_16c_minor_op {
 	mm_lwm16_op = 0x04,
 	mm_swm16_op = 0x05,
-	mm_jr16_op = 0x18,
-	mm_jrc_op = 0x1a,
-	mm_jalr16_op = 0x1c,
-	mm_jalrs16_op = 0x1e,
+	mm_jr16_op = 0x0c,
+	mm_jrc_op = 0x0d,
+	mm_jalr16_op = 0x0e,
+	mm_jalrs16_op = 0x0f,
+	mm_jraddiusp_op = 0x18,
 };
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/uapi/asm/msgbuf.h linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/msgbuf.h
--- linux-libre-3.10-gnu/arch/mips/include/uapi/asm/msgbuf.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/msgbuf.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,25 +14,25 @@
 
 struct msqid64_ds {
 	struct ipc64_perm msg_perm;
-#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if !defined(__mips64) && defined(__MIPSEB__)
 	unsigned long	__unused1;
 #endif
 	__kernel_time_t msg_stime;	/* last msgsnd time */
-#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if !defined(__mips64) && defined(__MIPSEL__)
 	unsigned long	__unused1;
 #endif
-#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if !defined(__mips64) && defined(__MIPSEB__)
 	unsigned long	__unused2;
 #endif
 	__kernel_time_t msg_rtime;	/* last msgrcv time */
-#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if !defined(__mips64) && defined(__MIPSEL__)
 	unsigned long	__unused2;
 #endif
-#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if !defined(__mips64) && defined(__MIPSEB__)
 	unsigned long	__unused3;
 #endif
 	__kernel_time_t msg_ctime;	/* last change time */
-#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN)
+#if !defined(__mips64) && defined(__MIPSEL__)
 	unsigned long	__unused3;
 #endif
 	unsigned long  msg_cbytes;	/* current number of bytes on queue */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/uapi/asm/resource.h linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/resource.h
--- linux-libre-3.10-gnu/arch/mips/include/uapi/asm/resource.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/resource.h	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,7 @@
  * but we keep the old value on MIPS32,
  * for compatibility:
  */
-#ifdef CONFIG_32BIT
+#ifndef __mips64
 # define RLIM_INFINITY		0x7fffffffUL
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/uapi/asm/siginfo.h linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/siginfo.h
--- linux-libre-3.10-gnu/arch/mips/include/uapi/asm/siginfo.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/siginfo.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,11 +25,12 @@ struct siginfo;
 /*
  * Careful to keep union _sifields from shifting ...
  */
-#ifdef CONFIG_32BIT
+#if _MIPS_SZLONG == 32
 #define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
-#endif
-#ifdef CONFIG_64BIT
+#elif _MIPS_SZLONG == 64
 #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+#else
+#error _MIPS_SZLONG neither 32 nor 64
 #endif
 
 #include <asm-generic/siginfo.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/mips/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -92,4 +92,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif /* _UAPI_ASM_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/include/uapi/asm/swab.h linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/swab.h
--- linux-libre-3.10-gnu/arch/mips/include/uapi/asm/swab.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/include/uapi/asm/swab.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 
 #define __SWAB_64_THRU_32__
 
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
 
 static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
 {
@@ -39,10 +39,10 @@ static inline __attribute_const__ __u32
 #define __arch_swab32 __arch_swab32
 
 /*
- * Having already checked for CONFIG_CPU_MIPSR2, enable the
- * optimized version for 64-bit kernel on r2 CPUs.
+ * Having already checked for MIPS R2, enable the optimized version for
+ * 64-bit kernel on r2 CPUs.
  */
-#ifdef CONFIG_64BIT
+#ifdef __mips64
 static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
 {
 	__asm__(
@@ -54,6 +54,6 @@ static inline __attribute_const__ __u64
 	return x;
 }
 #define __arch_swab64 __arch_swab64
-#endif /* CONFIG_64BIT */
-#endif /* CONFIG_CPU_MIPSR2 */
+#endif /* __mips64 */
+#endif /* MIPS R2 or newer  */
 #endif /* _ASM_SWAB_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/jz4740/board-qi_lb60.c linux-libre-3.11-rc7-gnu/arch/mips/jz4740/board-qi_lb60.c
--- linux-libre-3.10-gnu/arch/mips/jz4740/board-qi_lb60.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/jz4740/board-qi_lb60.c	2013-08-25 20:43:22.000000000 -0400
@@ -438,6 +438,7 @@ static struct platform_device *jz_platfo
 	&jz4740_rtc_device,
 	&jz4740_adc_device,
 	&jz4740_pwm_device,
+	&jz4740_dma_device,
 	&qi_lb60_gpio_keys,
 	&qi_lb60_pwm_beeper,
 	&qi_lb60_charger_device,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/jz4740/clock.c linux-libre-3.11-rc7-gnu/arch/mips/jz4740/clock.c
--- linux-libre-3.10-gnu/arch/mips/jz4740/clock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/jz4740/clock.c	2013-08-25 20:43:22.000000000 -0400
@@ -687,7 +687,7 @@ static struct clk jz4740_clock_simple_cl
 	[3] = {
 		.name = "dma",
 		.parent = &jz_clk_high_speed_peripheral.clk,
-		.gate_bit = JZ_CLOCK_GATE_UART0,
+		.gate_bit = JZ_CLOCK_GATE_DMAC,
 		.ops = &jz_clk_simple_ops,
 	},
 	[4] = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/jz4740/dma.c linux-libre-3.11-rc7-gnu/arch/mips/jz4740/dma.c
--- linux-libre-3.10-gnu/arch/mips/jz4740/dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/jz4740/dma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,287 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC DMA support
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General	 Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-
-#include <linux/dma-mapping.h>
-#include <asm/mach-jz4740/dma.h>
-#include <asm/mach-jz4740/base.h>
-
-#define JZ_REG_DMA_SRC_ADDR(x)		(0x00 + (x) * 0x20)
-#define JZ_REG_DMA_DST_ADDR(x)		(0x04 + (x) * 0x20)
-#define JZ_REG_DMA_TRANSFER_COUNT(x)	(0x08 + (x) * 0x20)
-#define JZ_REG_DMA_REQ_TYPE(x)		(0x0C + (x) * 0x20)
-#define JZ_REG_DMA_STATUS_CTRL(x)	(0x10 + (x) * 0x20)
-#define JZ_REG_DMA_CMD(x)		(0x14 + (x) * 0x20)
-#define JZ_REG_DMA_DESC_ADDR(x)		(0x18 + (x) * 0x20)
-
-#define JZ_REG_DMA_CTRL			0x300
-#define JZ_REG_DMA_IRQ			0x304
-#define JZ_REG_DMA_DOORBELL		0x308
-#define JZ_REG_DMA_DOORBELL_SET		0x30C
-
-#define JZ_DMA_STATUS_CTRL_NO_DESC		BIT(31)
-#define JZ_DMA_STATUS_CTRL_DESC_INV		BIT(6)
-#define JZ_DMA_STATUS_CTRL_ADDR_ERR		BIT(4)
-#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE	BIT(3)
-#define JZ_DMA_STATUS_CTRL_HALT			BIT(2)
-#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE	BIT(1)
-#define JZ_DMA_STATUS_CTRL_ENABLE		BIT(0)
-
-#define JZ_DMA_CMD_SRC_INC			BIT(23)
-#define JZ_DMA_CMD_DST_INC			BIT(22)
-#define JZ_DMA_CMD_RDIL_MASK			(0xf << 16)
-#define JZ_DMA_CMD_SRC_WIDTH_MASK		(0x3 << 14)
-#define JZ_DMA_CMD_DST_WIDTH_MASK		(0x3 << 12)
-#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK		(0x7 << 8)
-#define JZ_DMA_CMD_BLOCK_MODE			BIT(7)
-#define JZ_DMA_CMD_DESC_VALID			BIT(4)
-#define JZ_DMA_CMD_DESC_VALID_MODE		BIT(3)
-#define JZ_DMA_CMD_VALID_IRQ_ENABLE		BIT(2)
-#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE		BIT(1)
-#define JZ_DMA_CMD_LINK_ENABLE			BIT(0)
-
-#define JZ_DMA_CMD_FLAGS_OFFSET 22
-#define JZ_DMA_CMD_RDIL_OFFSET 16
-#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
-#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
-#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
-#define JZ_DMA_CMD_MODE_OFFSET 7
-
-#define JZ_DMA_CTRL_PRIORITY_MASK	(0x3 << 8)
-#define JZ_DMA_CTRL_HALT		BIT(3)
-#define JZ_DMA_CTRL_ADDRESS_ERROR	BIT(2)
-#define JZ_DMA_CTRL_ENABLE		BIT(0)
-
-
-static void __iomem *jz4740_dma_base;
-static spinlock_t jz4740_dma_lock;
-
-static inline uint32_t jz4740_dma_read(size_t reg)
-{
-	return readl(jz4740_dma_base + reg);
-}
-
-static inline void jz4740_dma_write(size_t reg, uint32_t val)
-{
-	writel(val, jz4740_dma_base + reg);
-}
-
-static inline void jz4740_dma_write_mask(size_t reg, uint32_t val, uint32_t mask)
-{
-	uint32_t val2;
-	val2 = jz4740_dma_read(reg);
-	val2 &= ~mask;
-	val2 |= val;
-	jz4740_dma_write(reg, val2);
-}
-
-struct jz4740_dma_chan {
-	unsigned int id;
-	void *dev;
-	const char *name;
-
-	enum jz4740_dma_flags flags;
-	uint32_t transfer_shift;
-
-	jz4740_dma_complete_callback_t complete_cb;
-
-	unsigned used:1;
-};
-
-#define JZ4740_DMA_CHANNEL(_id) { .id = _id }
-
-struct jz4740_dma_chan jz4740_dma_channels[] = {
-	JZ4740_DMA_CHANNEL(0),
-	JZ4740_DMA_CHANNEL(1),
-	JZ4740_DMA_CHANNEL(2),
-	JZ4740_DMA_CHANNEL(3),
-	JZ4740_DMA_CHANNEL(4),
-	JZ4740_DMA_CHANNEL(5),
-};
-
-struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name)
-{
-	unsigned int i;
-	struct jz4740_dma_chan *dma = NULL;
-
-	spin_lock(&jz4740_dma_lock);
-
-	for (i = 0; i < ARRAY_SIZE(jz4740_dma_channels); ++i) {
-		if (!jz4740_dma_channels[i].used) {
-			dma = &jz4740_dma_channels[i];
-			dma->used = 1;
-			break;
-		}
-	}
-
-	spin_unlock(&jz4740_dma_lock);
-
-	if (!dma)
-		return NULL;
-
-	dma->dev = dev;
-	dma->name = name;
-
-	return dma;
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_request);
-
-void jz4740_dma_configure(struct jz4740_dma_chan *dma,
-	const struct jz4740_dma_config *config)
-{
-	uint32_t cmd;
-
-	switch (config->transfer_size) {
-	case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
-		dma->transfer_shift = 1;
-		break;
-	case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
-		dma->transfer_shift = 2;
-		break;
-	case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
-		dma->transfer_shift = 4;
-		break;
-	case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
-		dma->transfer_shift = 5;
-		break;
-	default:
-		dma->transfer_shift = 0;
-		break;
-	}
-
-	cmd = config->flags << JZ_DMA_CMD_FLAGS_OFFSET;
-	cmd |= config->src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
-	cmd |= config->dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
-	cmd |= config->transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
-	cmd |= config->mode << JZ_DMA_CMD_MODE_OFFSET;
-	cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
-
-	jz4740_dma_write(JZ_REG_DMA_CMD(dma->id), cmd);
-	jz4740_dma_write(JZ_REG_DMA_STATUS_CTRL(dma->id), 0);
-	jz4740_dma_write(JZ_REG_DMA_REQ_TYPE(dma->id), config->request_type);
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_configure);
-
-void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src)
-{
-	jz4740_dma_write(JZ_REG_DMA_SRC_ADDR(dma->id), src);
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_set_src_addr);
-
-void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst)
-{
-	jz4740_dma_write(JZ_REG_DMA_DST_ADDR(dma->id), dst);
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_set_dst_addr);
-
-void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count)
-{
-	count >>= dma->transfer_shift;
-	jz4740_dma_write(JZ_REG_DMA_TRANSFER_COUNT(dma->id), count);
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_set_transfer_count);
-
-void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
-	jz4740_dma_complete_callback_t cb)
-{
-	dma->complete_cb = cb;
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_set_complete_cb);
-
-void jz4740_dma_free(struct jz4740_dma_chan *dma)
-{
-	dma->dev = NULL;
-	dma->complete_cb = NULL;
-	dma->used = 0;
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_free);
-
-void jz4740_dma_enable(struct jz4740_dma_chan *dma)
-{
-	jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id),
-			JZ_DMA_STATUS_CTRL_NO_DESC | JZ_DMA_STATUS_CTRL_ENABLE,
-			JZ_DMA_STATUS_CTRL_HALT | JZ_DMA_STATUS_CTRL_NO_DESC |
-			JZ_DMA_STATUS_CTRL_ENABLE);
-
-	jz4740_dma_write_mask(JZ_REG_DMA_CTRL,
-			JZ_DMA_CTRL_ENABLE,
-			JZ_DMA_CTRL_HALT | JZ_DMA_CTRL_ENABLE);
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_enable);
-
-void jz4740_dma_disable(struct jz4740_dma_chan *dma)
-{
-	jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
-			JZ_DMA_STATUS_CTRL_ENABLE);
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_disable);
-
-uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma)
-{
-	uint32_t residue;
-	residue = jz4740_dma_read(JZ_REG_DMA_TRANSFER_COUNT(dma->id));
-	return residue << dma->transfer_shift;
-}
-EXPORT_SYMBOL_GPL(jz4740_dma_get_residue);
-
-static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma)
-{
-	(void) jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id));
-
-	jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
-		JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
-
-	if (dma->complete_cb)
-		dma->complete_cb(dma, 0, dma->dev);
-}
-
-static irqreturn_t jz4740_dma_irq(int irq, void *dev_id)
-{
-	uint32_t irq_status;
-	unsigned int i;
-
-	irq_status = readl(jz4740_dma_base + JZ_REG_DMA_IRQ);
-
-	for (i = 0; i < 6; ++i) {
-		if (irq_status & (1 << i))
-			jz4740_dma_chan_irq(&jz4740_dma_channels[i]);
-	}
-
-	return IRQ_HANDLED;
-}
-
-static int jz4740_dma_init(void)
-{
-	unsigned int ret;
-
-	jz4740_dma_base = ioremap(JZ4740_DMAC_BASE_ADDR, 0x400);
-
-	if (!jz4740_dma_base)
-		return -EBUSY;
-
-	spin_lock_init(&jz4740_dma_lock);
-
-	ret = request_irq(JZ4740_IRQ_DMAC, jz4740_dma_irq, 0, "DMA", NULL);
-
-	if (ret)
-		printk(KERN_ERR "JZ4740 DMA: Failed to request irq: %d\n", ret);
-
-	return ret;
-}
-arch_initcall(jz4740_dma_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/jz4740/Makefile linux-libre-3.11-rc7-gnu/arch/mips/jz4740/Makefile
--- linux-libre-3.10-gnu/arch/mips/jz4740/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/jz4740/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,7 @@
 
 # Object file lists.
 
-obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
+obj-y += prom.o irq.o time.o reset.o setup.o \
 	gpio.o clock.o platform.o timer.o serial.o
 
 obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/jz4740/platform.c linux-libre-3.11-rc7-gnu/arch/mips/jz4740/platform.c
--- linux-libre-3.10-gnu/arch/mips/jz4740/platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/jz4740/platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -329,3 +329,24 @@ struct platform_device jz4740_pwm_device
 	.name = "jz4740-pwm",
 	.id   = -1,
 };
+
+/* DMA */
+static struct resource jz4740_dma_resources[] = {
+	{
+		.start	= JZ4740_DMAC_BASE_ADDR,
+		.end	= JZ4740_DMAC_BASE_ADDR + 0x400 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= JZ4740_IRQ_DMAC,
+		.end	= JZ4740_IRQ_DMAC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device jz4740_dma_device = {
+	.name		= "jz4740-dma",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(jz4740_dma_resources),
+	.resource	= jz4740_dma_resources,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/Kbuild.platforms linux-libre-3.11-rc7-gnu/arch/mips/Kbuild.platforms
--- linux-libre-3.10-gnu/arch/mips/Kbuild.platforms	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/Kbuild.platforms	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,6 @@ platforms += sibyte
 platforms += sni
 platforms += txx9
 platforms += vr41xx
-platforms += wrppmc
 
 # include the platform specific files
 include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/Kconfig linux-libre-3.11-rc7-gnu/arch/mips/Kconfig
--- linux-libre-3.10-gnu/arch/mips/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,7 @@
 config MIPS
 	bool
 	default y
+	select HAVE_CONTEXT_TRACKING
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_IDE
 	select HAVE_OPROFILE
@@ -27,6 +28,7 @@ config MIPS
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
+	select GENERIC_PCI_IOMAP
 	select HAVE_ARCH_JUMP_LABEL
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select IRQ_FORCED_THREADING
@@ -42,12 +44,10 @@ config MIPS
 	select MODULES_USE_ELF_REL if MODULES
 	select MODULES_USE_ELF_RELA if MODULES && 64BIT
 	select CLONE_BACKWARDS
+	select HAVE_DEBUG_STACKOVERFLOW
 
 menu "Machine selection"
 
-config ZONE_DMA
-	bool
-
 choice
 	prompt "System type"
 	default SGI_IP22
@@ -114,6 +114,7 @@ config BCM47XX
 	select FW_CFE
 	select HW_HAS_PCI
 	select IRQ_CPU
+	select SYS_HAS_CPU_MIPS32_R1
 	select NO_EXCEPT_FILL
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -123,11 +124,14 @@ config BCM47XX
 
 config BCM63XX
 	bool "Broadcom BCM63XX based boards"
+	select BOOT_RAW
 	select CEVT_R4K
 	select CSRC_R4K
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_HAS_CPU_BMIPS4350 if !BCM63XX_CPU_6338 && !BCM63XX_CPU_6345 && !BCM63XX_CPU_6348
+	select NR_CPUS_DEFAULT_2
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_HAS_EARLY_PRINTK
@@ -340,7 +344,6 @@ config MIPS_SEAD3
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select IRQ_GIC
-	select MIPS_CPU_SCACHE
 	select MIPS_MSC
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_HAS_CPU_MIPS32_R2
@@ -419,7 +422,6 @@ config POWERTV
 	select CSRC_POWERTV
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
-	select SYS_HAS_EARLY_PRINTK
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
@@ -712,46 +714,8 @@ config MIKROTIK_RB532
 	  Support the Mikrotik(tm) RouterBoard 532 series,
 	  based on the IDT RC32434 SoC.
 
-config WR_PPMC
-	bool "Wind River PPMC board"
-	select CEVT_R4K
-	select CSRC_R4K
-	select IRQ_CPU
-	select BOOT_ELF32
-	select DMA_NONCOHERENT
-	select HW_HAS_PCI
-	select PCI_GT64XXX_PCI0
-	select SWAP_IO_SPACE
-	select SYS_HAS_CPU_MIPS32_R1
-	select SYS_HAS_CPU_MIPS32_R2
-	select SYS_HAS_CPU_MIPS64_R1
-	select SYS_HAS_CPU_NEVADA
-	select SYS_HAS_CPU_RM7000
-	select SYS_SUPPORTS_32BIT_KERNEL
-	select SYS_SUPPORTS_64BIT_KERNEL
-	select SYS_SUPPORTS_BIG_ENDIAN
-	select SYS_SUPPORTS_LITTLE_ENDIAN
-	help
-	  This enables support for the Wind River MIPS32 4KC PPMC evaluation
-	  board, which is based on GT64120 bridge chip.
-
-config CAVIUM_OCTEON_SIMULATOR
-	bool "Cavium Networks Octeon Simulator"
-	select CEVT_R4K
-	select 64BIT_PHYS_ADDR
-	select DMA_COHERENT
-	select SYS_SUPPORTS_64BIT_KERNEL
-	select SYS_SUPPORTS_BIG_ENDIAN
-	select SYS_SUPPORTS_HOTPLUG_CPU
-	select SYS_HAS_CPU_CAVIUM_OCTEON
-	select HOLES_IN_ZONE
-	help
-	  The Octeon simulator is software performance model of the Cavium
-	  Octeon Processor. It supports simulating Octeon processors on x86
-	  hardware.
-
-config CAVIUM_OCTEON_REFERENCE_BOARD
-	bool "Cavium Networks Octeon reference board"
+config CAVIUM_OCTEON_SOC
+	bool "Cavium Networks Octeon SoC based boards"
 	select CEVT_R4K
 	select 64BIT_PHYS_ADDR
 	select DMA_COHERENT
@@ -805,6 +769,8 @@ config NLM_XLR_BOARD
 	select SYS_HAS_EARLY_PRINTK
 	select USB_ARCH_HAS_OHCI if USB_SUPPORT
 	select USB_ARCH_HAS_EHCI if USB_SUPPORT
+	select SYS_SUPPORTS_ZBOOT
+	select SYS_SUPPORTS_ZBOOT_UART16550
 	help
 	  Support for systems based on Netlogic XLR and XLS processors.
 	  Say Y here if you have a XLR or XLS based board.
@@ -831,6 +797,8 @@ config NLM_XLP_BOARD
 	select SYNC_R4K
 	select SYS_HAS_EARLY_PRINTK
 	select USE_OF
+	select SYS_SUPPORTS_ZBOOT
+	select SYS_SUPPORTS_ZBOOT_UART16550
 	help
 	  This board is based on Netlogic XLP Processor.
 	  Say Y here if you have a XLP based board.
@@ -962,7 +930,7 @@ config SYS_HAS_EARLY_PRINTK
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
-	depends on SMP && HOTPLUG && SYS_SUPPORTS_HOTPLUG_CPU
+	depends on SMP && SYS_SUPPORTS_HOTPLUG_CPU
 	help
 	  Say Y here to allow turning CPUs off and on. CPUs can be
 	  controlled through /sys/devices/system/cpu.
@@ -1030,7 +998,6 @@ config CPU_BIG_ENDIAN
 config CPU_LITTLE_ENDIAN
 	bool "Little endian"
 	depends on SYS_SUPPORTS_LITTLE_ENDIAN
-	help
 
 endchoice
 
@@ -1736,6 +1703,7 @@ endchoice
 
 config KVM_GUEST
 	bool "KVM Guest Kernel"
+	depends on BROKEN_ON_SMP
 	help
 	  Select this option if building a guest kernel for KVM (Trap & Emulate) mode
 
@@ -1963,7 +1931,7 @@ config MIPS_MT_FPAFF
 
 config MIPS_VPE_LOADER
 	bool "VPE loader support."
-	depends on SYS_SUPPORTS_MULTITHREADING
+	depends on SYS_SUPPORTS_MULTITHREADING && MODULES
 	select CPU_MIPSR2_IRQ_VI
 	select CPU_MIPSR2_IRQ_EI
 	select MIPS_MT
@@ -2381,6 +2349,19 @@ config SECCOMP
 
 	  If unsure, say Y. Only embedded should say N here.
 
+config CC_STACKPROTECTOR
+	bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
+	help
+	  This option turns on the -fstack-protector GCC feature. This
+	  feature puts, at the beginning of functions, a canary value on
+	  the stack just before the return address, and validates
+	  the value just before actually returning.  Stack based buffer
+	  overflows (that need to overwrite this return address) now also
+	  overwrite the canary, which gets detected and the attack is then
+	  neutralized via a kernel panic.
+
+	  This feature requires gcc version 4.2 or above.
+
 config USE_OF
 	bool
 	select OF
@@ -2412,7 +2393,6 @@ config PCI
 	bool "Support for PCI controller"
 	depends on HW_HAS_PCI
 	select PCI_DOMAINS
-	select GENERIC_PCI_IOMAP
 	select NO_GENERIC_PCI_IOPORT_MAP
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
@@ -2478,6 +2458,9 @@ config I8253
 	select CLKEVT_I8253
 	select MIPS_EXTERNAL_TIMER
 
+config ZONE_DMA
+	bool
+
 config ZONE_DMA32
 	bool
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/mips/Kconfig.debug
--- linux-libre-3.10-gnu/arch/mips/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -67,15 +67,6 @@ config CMDLINE_OVERRIDE
 
 	  Normally, you will choose 'N' here.
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-	help
-	  This option will cause messages to be printed if free stack space
-	  drops below a certain limit(2GB on MIPS). The debugging option
-	  provides another way to check stack overflow happened on kernel mode
-	  stack usually caused by nested interruption.
-
 config SMTC_IDLE_HOOK_DEBUG
 	bool "Enable additional debug checks before going into CPU idle loop"
 	depends on DEBUG_KERNEL && MIPS_MT_SMTC
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/asm-offsets.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/asm-offsets.c
--- linux-libre-3.10-gnu/arch/mips/kernel/asm-offsets.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/asm-offsets.c	2013-08-25 20:43:22.000000000 -0400
@@ -82,6 +82,9 @@ void output_task_defines(void)
 	OFFSET(TASK_FLAGS, task_struct, flags);
 	OFFSET(TASK_MM, task_struct, mm);
 	OFFSET(TASK_PID, task_struct, pid);
+#if defined(CONFIG_CC_STACKPROTECTOR)
+	OFFSET(TASK_STACK_CANARY, task_struct, stack_canary);
+#endif
 	DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct));
 	BLANK();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/bmips_vec.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/bmips_vec.S
--- linux-libre-3.10-gnu/arch/mips/kernel/bmips_vec.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/bmips_vec.S	2013-08-25 20:43:22.000000000 -0400
@@ -28,8 +28,6 @@
 	.set	mips0
 	.endm
 
-	__CPUINIT
-
 /***********************************************************************
  * Alternate CPU1 startup vector for BMIPS4350
  *
@@ -56,7 +54,11 @@ LEAF(bmips_smp_movevec)
 	/* set up CPU1 CBR; move BASE to 0xa000_0000 */
 	li	k0, 0xff400000
 	mtc0	k0, $22, 6
-	li	k1, CKSEG1 | BMIPS_RELO_VECTOR_CONTROL_1
+	/* set up relocation vector address based on thread ID */
+	mfc0	k1, $22, 3
+	srl	k1, 16
+	andi	k1, 0x8000
+	or	k1, CKSEG1 | BMIPS_RELO_VECTOR_CONTROL_0
 	or	k0, k1
 	li	k1, 0xa0080000
 	sw	k1, 0(k0)
@@ -216,8 +218,6 @@ END(bmips_smp_int_vec)
  * Certain CPUs support extending kseg0 to 1024MB.
  ***********************************************************************/
 
-	__CPUINIT
-
 LEAF(bmips_enable_xks01)
 
 #if defined(CONFIG_XKS01)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/branch.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/branch.c
--- linux-libre-3.10-gnu/arch/mips/kernel/branch.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/branch.c	2013-08-25 20:43:22.000000000 -0400
@@ -467,5 +467,4 @@ unaligned:
 	printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
 	force_sig(SIGBUS, current);
 	return -EFAULT;
-
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/cevt-bcm1480.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-bcm1480.c
--- linux-libre-3.10-gnu/arch/mips/kernel/cevt-bcm1480.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-bcm1480.c	2013-08-25 20:43:22.000000000 -0400
@@ -109,7 +109,7 @@ static DEFINE_PER_CPU(struct clock_event
 static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
 static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
 
-void __cpuinit sb1480_clockevent_init(void)
+void sb1480_clockevent_init(void)
 {
 	unsigned int cpu = smp_processor_id();
 	unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/cevt-gic.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-gic.c
--- linux-libre-3.10-gnu/arch/mips/kernel/cevt-gic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-gic.c	2013-08-25 20:43:22.000000000 -0400
@@ -59,7 +59,7 @@ void gic_event_handler(struct clock_even
 {
 }
 
-int __cpuinit gic_clockevent_init(void)
+int gic_clockevent_init(void)
 {
 	unsigned int cpu = smp_processor_id();
 	struct clock_event_device *cd;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/cevt-r4k.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-r4k.c
--- linux-libre-3.10-gnu/arch/mips/kernel/cevt-r4k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-r4k.c	2013-08-25 20:43:22.000000000 -0400
@@ -171,7 +171,7 @@ int c0_compare_int_usable(void)
 }
 
 #ifndef CONFIG_MIPS_MT_SMTC
-int __cpuinit r4k_clockevent_init(void)
+int r4k_clockevent_init(void)
 {
 	unsigned int cpu = smp_processor_id();
 	struct clock_event_device *cd;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/cevt-sb1250.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-sb1250.c
--- linux-libre-3.10-gnu/arch/mips/kernel/cevt-sb1250.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-sb1250.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,7 +107,7 @@ static DEFINE_PER_CPU(struct clock_event
 static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
 static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
 
-void __cpuinit sb1250_clockevent_init(void)
+void sb1250_clockevent_init(void)
 {
 	unsigned int cpu = smp_processor_id();
 	unsigned int irq = K_INT_TIMER_0 + cpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/cevt-smtc.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-smtc.c
--- linux-libre-3.10-gnu/arch/mips/kernel/cevt-smtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/cevt-smtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -248,7 +248,7 @@ irqreturn_t c0_compare_interrupt(int irq
 }
 
 
-int __cpuinit smtc_clockevent_init(void)
+int smtc_clockevent_init(void)
 {
 	uint64_t mips_freq = mips_hpt_frequency;
 	unsigned int cpu = smp_processor_id();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/cpu-bugs64.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/cpu-bugs64.c
--- linux-libre-3.10-gnu/arch/mips/kernel/cpu-bugs64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/cpu-bugs64.c	2013-08-25 20:43:22.000000000 -0400
@@ -6,6 +6,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
+#include <linux/context_tracking.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
@@ -167,12 +168,16 @@ static inline void check_mult_sh(void)
 	panic(bug64hit, !R4000_WAR ? r4kwar : nowar);
 }
 
-static volatile int daddi_ov __cpuinitdata;
+static volatile int daddi_ov;
 
 asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
 {
+	enum ctx_state prev_state;
+
+	prev_state = exception_enter();
 	daddi_ov = 1;
 	regs->cp0_epc += 4;
+	exception_exit(prev_state);
 }
 
 static inline void check_daddi(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/cpu-probe.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/cpu-probe.c
--- linux-libre-3.10-gnu/arch/mips/kernel/cpu-probe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/cpu-probe.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@
 #include <asm/spram.h>
 #include <asm/uaccess.h>
 
-static int __cpuinitdata mips_fpu_disabled;
+static int mips_fpu_disabled;
 
 static int __init fpu_disable(char *s)
 {
@@ -39,7 +39,7 @@ static int __init fpu_disable(char *s)
 
 __setup("nofpu", fpu_disable);
 
-int __cpuinitdata mips_dsp_disabled;
+int mips_dsp_disabled;
 
 static int __init dsp_disable(char *s)
 {
@@ -134,7 +134,7 @@ static inline void cpu_probe_vmbits(stru
 #endif
 }
 
-static void __cpuinit set_isa(struct cpuinfo_mips *c, unsigned int isa)
+static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
 {
 	switch (isa) {
 	case MIPS_CPU_ISA_M64R2:
@@ -146,8 +146,7 @@ static void __cpuinit set_isa(struct cpu
 	case MIPS_CPU_ISA_IV:
 		c->isa_level |= MIPS_CPU_ISA_IV;
 	case MIPS_CPU_ISA_III:
-		c->isa_level |= MIPS_CPU_ISA_I | MIPS_CPU_ISA_II |
-				MIPS_CPU_ISA_III;
+		c->isa_level |= MIPS_CPU_ISA_II | MIPS_CPU_ISA_III;
 		break;
 
 	case MIPS_CPU_ISA_M32R2:
@@ -156,13 +155,11 @@ static void __cpuinit set_isa(struct cpu
 		c->isa_level |= MIPS_CPU_ISA_M32R1;
 	case MIPS_CPU_ISA_II:
 		c->isa_level |= MIPS_CPU_ISA_II;
-	case MIPS_CPU_ISA_I:
-		c->isa_level |= MIPS_CPU_ISA_I;
 		break;
 	}
 }
 
-static char unknown_isa[] __cpuinitdata = KERN_ERR \
+static char unknown_isa[] = KERN_ERR \
 	"Unsupported ISA type, c0.config0: %d.";
 
 static inline unsigned int decode_config0(struct cpuinfo_mips *c)
@@ -272,9 +269,6 @@ static inline unsigned int decode_config
 		c->options |= MIPS_CPU_ULRI;
 	if (config3 & MIPS_CONF3_ISA)
 		c->options |= MIPS_CPU_MICROMIPS;
-#ifdef CONFIG_CPU_MICROMIPS
-	write_c0_config3(read_c0_config3() | MIPS_CONF3_ISA_OE);
-#endif
 	if (config3 & MIPS_CONF3_VZ)
 		c->ases |= MIPS_ASE_VZ;
 
@@ -296,7 +290,7 @@ static inline unsigned int decode_config
 	return config4 & MIPS_CONF_M;
 }
 
-static void __cpuinit decode_configs(struct cpuinfo_mips *c)
+static void decode_configs(struct cpuinfo_mips *c)
 {
 	int ok;
 
@@ -332,7 +326,6 @@ static inline void cpu_probe_legacy(stru
 	case PRID_IMP_R2000:
 		c->cputype = CPU_R2000;
 		__cpu_name[cpu] = "R2000";
-		set_isa(c, MIPS_CPU_ISA_I);
 		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
 			     MIPS_CPU_NOFPUEX;
 		if (__cpu_has_fpu())
@@ -352,7 +345,6 @@ static inline void cpu_probe_legacy(stru
 			c->cputype = CPU_R3000;
 			__cpu_name[cpu] = "R3000";
 		}
-		set_isa(c, MIPS_CPU_ISA_I);
 		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
 			     MIPS_CPU_NOFPUEX;
 		if (__cpu_has_fpu())
@@ -455,7 +447,6 @@ static inline void cpu_probe_legacy(stru
 		break;
 	#endif
 	case PRID_IMP_TX39:
-		set_isa(c, MIPS_CPU_ISA_I);
 		c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
 
 		if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
@@ -959,6 +950,7 @@ static inline void cpu_probe_netlogic(st
 		set_isa(c, MIPS_CPU_ISA_M64R1);
 		c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
 	}
+	c->kscratch_mask = 0xf;
 }
 
 #ifdef CONFIG_64BIT
@@ -970,7 +962,7 @@ EXPORT_SYMBOL(__ua_limit);
 const char *__cpu_name[NR_CPUS];
 const char *__elf_platform;
 
-__cpuinit void cpu_probe(void)
+void cpu_probe(void)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
 	unsigned int cpu = smp_processor_id();
@@ -1055,7 +1047,7 @@ __cpuinit void cpu_probe(void)
 #endif
 }
 
-__cpuinit void cpu_report(void)
+void cpu_report(void)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/crash_dump.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/crash_dump.c
--- linux-libre-3.10-gnu/arch/mips/kernel/crash_dump.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/crash_dump.c	2013-08-25 20:43:22.000000000 -0400
@@ -4,16 +4,6 @@
 #include <asm/uaccess.h>
 #include <linux/slab.h>
 
-static int __init parse_savemaxmem(char *p)
-{
-	if (p)
-		saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
-
-	return 1;
-}
-__setup("savemaxmem=", parse_savemaxmem);
-
-
 static void *kdump_buf_page;
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/head.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/head.S
--- linux-libre-3.10-gnu/arch/mips/kernel/head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/head.S	2013-08-25 20:43:22.000000000 -0400
@@ -28,45 +28,6 @@
 #include <kernel-entry-init.h>
 
 	/*
-	 * inputs are the text nasid in t1, data nasid in t2.
-	 */
-	.macro MAPPED_KERNEL_SETUP_TLB
-#ifdef CONFIG_MAPPED_KERNEL
-	/*
-	 * This needs to read the nasid - assume 0 for now.
-	 * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
-	 * 0+DVG in tlblo_1.
-	 */
-	dli	t0, 0xffffffffc0000000
-	dmtc0	t0, CP0_ENTRYHI
-	li	t0, 0x1c000		# Offset of text into node memory
-	dsll	t1, NASID_SHFT		# Shift text nasid into place
-	dsll	t2, NASID_SHFT		# Same for data nasid
-	or	t1, t1, t0		# Physical load address of kernel text
-	or	t2, t2, t0		# Physical load address of kernel data
-	dsrl	t1, 12			# 4K pfn
-	dsrl	t2, 12			# 4K pfn
-	dsll	t1, 6			# Get pfn into place
-	dsll	t2, 6			# Get pfn into place
-	li	t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6)
-	or	t0, t0, t1
-	mtc0	t0, CP0_ENTRYLO0	# physaddr, VG, cach exlwr
-	li	t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6)
-	or	t0, t0, t2
-	mtc0	t0, CP0_ENTRYLO1	# physaddr, DVG, cach exlwr
-	li	t0, 0x1ffe000		# MAPPED_KERN_TLBMASK, TLBPGMASK_16M
-	mtc0	t0, CP0_PAGEMASK
-	li	t0, 0			# KMAP_INX
-	mtc0	t0, CP0_INDEX
-	li	t0, 1
-	mtc0	t0, CP0_WIRED
-	tlbwi
-#else
-	mtc0	zero, CP0_WIRED
-#endif
-	.endm
-
-	/*
 	 * For the moment disable interrupts, mark the kernel mode and
 	 * set ST0_KX so that the CPU does not spit fire when using
 	 * 64-bit addresses.  A full initialization of the CPU's status
@@ -197,8 +158,6 @@ NESTED(kernel_entry, 16, sp)			# kernel
 	j		start_kernel
 	END(kernel_entry)
 
-	__CPUINIT
-
 #ifdef CONFIG_SMP
 /*
  * SMP slave cpus entry point.	Board specific code for bootstrap calls this
@@ -227,5 +186,3 @@ NESTED(smp_bootstrap, 16, sp)
 	j	start_secondary
 	END(smp_bootstrap)
 #endif /* CONFIG_SMP */
-
-	__FINIT
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/irq-gic.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/irq-gic.c
--- linux-libre-3.10-gnu/arch/mips/kernel/irq-gic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/irq-gic.c	2013-08-25 20:43:22.000000000 -0400
@@ -219,16 +219,15 @@ static int gic_set_affinity(struct irq_d
 
 	/* Assumption : cpumask refers to a single CPU */
 	spin_lock_irqsave(&gic_lock, flags);
-	for (;;) {
-		/* Re-route this IRQ */
-		GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
 
-		/* Update the pcpu_masks */
-		for (i = 0; i < NR_CPUS; i++)
-			clear_bit(irq, pcpu_masks[i].pcpu_mask);
-		set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
+	/* Re-route this IRQ */
+	GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
+
+	/* Update the pcpu_masks */
+	for (i = 0; i < NR_CPUS; i++)
+		clear_bit(irq, pcpu_masks[i].pcpu_mask);
+	set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
 
-	}
 	cpumask_copy(d->affinity, cpumask);
 	spin_unlock_irqrestore(&gic_lock, flags);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/mcount.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/mcount.S
--- linux-libre-3.10-gnu/arch/mips/kernel/mcount.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/mcount.S	2013-08-25 20:43:22.000000000 -0400
@@ -168,15 +168,11 @@ NESTED(ftrace_graph_caller, PT_SIZE, ra)
 #endif
 
 	/* arg3: Get frame pointer of current stack */
-#ifdef CONFIG_FRAME_POINTER
-	move	a2, fp
-#else /* ! CONFIG_FRAME_POINTER */
 #ifdef CONFIG_64BIT
 	PTR_LA	a2, PT_SIZE(sp)
 #else
 	PTR_LA	a2, (PT_SIZE+8)(sp)
 #endif
-#endif
 
 	jal	prepare_ftrace_return
 	 nop
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/mips-mt-fpaff.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/mips-mt-fpaff.c
--- linux-libre-3.10-gnu/arch/mips/kernel/mips-mt-fpaff.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/mips-mt-fpaff.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,12 +27,12 @@ unsigned long mt_fpemul_threshold;
  * FPU affinity with the user's requested processor affinity.
  * This code is 98% identical with the sys_sched_setaffinity()
  * and sys_sched_getaffinity() system calls, and should be
- * updated when kernel/sched.c changes.
+ * updated when kernel/sched/core.c changes.
  */
 
 /*
  * find_process_by_pid - find a process with a matching PID value.
- * used in sys_sched_set/getaffinity() in kernel/sched.c, so
+ * used in sys_sched_set/getaffinity() in kernel/sched/core.c, so
  * cloned here.
  */
 static inline struct task_struct *find_process_by_pid(pid_t pid)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/octeon_switch.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/octeon_switch.S
--- linux-libre-3.10-gnu/arch/mips/kernel/octeon_switch.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/octeon_switch.S	2013-08-25 20:43:22.000000000 -0400
@@ -40,33 +40,6 @@
 	cpu_save_nonscratch a0
 	LONG_S	ra, THREAD_REG31(a0)
 
-	/* check if we need to save COP2 registers */
-	PTR_L	t2, TASK_THREAD_INFO(a0)
-	LONG_L	t0, ST_OFF(t2)
-	bbit0	t0, 30, 1f
-
-	/* Disable COP2 in the stored process state */
-	li	t1, ST0_CU2
-	xor	t0, t1
-	LONG_S	t0, ST_OFF(t2)
-
-	/* Enable COP2 so we can save it */
-	mfc0	t0, CP0_STATUS
-	or	t0, t1
-	mtc0	t0, CP0_STATUS
-
-	/* Save COP2 */
-	daddu	a0, THREAD_CP2
-	jal octeon_cop2_save
-	dsubu	a0, THREAD_CP2
-
-	/* Disable COP2 now that we are done */
-	mfc0	t0, CP0_STATUS
-	li	t1, ST0_CU2
-	xor	t0, t1
-	mtc0	t0, CP0_STATUS
-
-1:
 #if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
 	/* Check if we need to store CVMSEG state */
 	mfc0	t0, $11,7	/* CvmMemCtl */
@@ -98,6 +71,13 @@
 	mtc0	t0, $11,7	/* CvmMemCtl */
 #endif
 3:
+
+#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
+	PTR_L	t8, __stack_chk_guard
+	LONG_L	t9, TASK_STACK_CANARY(a1)
+	LONG_S	t9, 0(t8)
+#endif
+
 	/*
 	 * The order of restoring the registers takes care of the race
 	 * updating $28, $29 and kernelsp without disabling ints.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/proc.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/proc.c
--- linux-libre-3.10-gnu/arch/mips/kernel/proc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/proc.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,9 +66,7 @@ static int show_cpuinfo(struct seq_file
 		seq_printf(m, "]\n");
 	}
 	if (cpu_has_mips_r) {
-		seq_printf(m, "isa\t\t\t:");
-		if (cpu_has_mips_1)
-			seq_printf(m, "%s", " mips1");
+		seq_printf(m, "isa\t\t\t: mips1");
 		if (cpu_has_mips_2)
 			seq_printf(m, "%s", " mips2");
 		if (cpu_has_mips_3)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/process.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/process.c
--- linux-libre-3.10-gnu/arch/mips/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -201,9 +201,12 @@ int dump_task_fpu(struct task_struct *t,
 	return 1;
 }
 
-/*
- *
- */
+#ifdef CONFIG_CC_STACKPROTECTOR
+#include <linux/stackprotector.h>
+unsigned long __stack_chk_guard __read_mostly;
+EXPORT_SYMBOL(__stack_chk_guard);
+#endif
+
 struct mips_frame_info {
 	void		*func;
 	unsigned long	func_size;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/prom.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/prom.c
--- linux-libre-3.10-gnu/arch/mips/kernel/prom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/prom.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,7 @@ __init void mips_set_machine_name(const
 	if (name == NULL)
 		return;
 
-	strncpy(mips_machine_name, name, sizeof(mips_machine_name));
+	strlcpy(mips_machine_name, name, sizeof(mips_machine_name));
 	pr_info("MIPS: machine is %s\n", mips_get_machine_name());
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/ptrace.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/ptrace.c
--- linux-libre-3.10-gnu/arch/mips/kernel/ptrace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/ptrace.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@
  * binaries.
  */
 #include <linux/compiler.h>
+#include <linux/context_tracking.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -534,6 +535,8 @@ static inline int audit_arch(void)
  */
 asmlinkage void syscall_trace_enter(struct pt_regs *regs)
 {
+	user_exit();
+
 	/* do the secure computing check first */
 	secure_computing_strict(regs->regs[2]);
 
@@ -570,6 +573,13 @@ out:
  */
 asmlinkage void syscall_trace_leave(struct pt_regs *regs)
 {
+        /*
+	 * We may come here right after calling schedule_user()
+	 * or do_notify_resume(), in which case we can be in RCU
+	 * user mode.
+	 */
+	user_exit();
+
 	audit_syscall_exit(regs);
 
 	if (!(current->ptrace & PT_PTRACED))
@@ -592,4 +602,6 @@ asmlinkage void syscall_trace_leave(stru
 		send_sig(current->exit_code, current, 1);
 		current->exit_code = 0;
 	}
+
+	user_enter();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/r2300_switch.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/r2300_switch.S
--- linux-libre-3.10-gnu/arch/mips/kernel/r2300_switch.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/r2300_switch.S	2013-08-25 20:43:22.000000000 -0400
@@ -65,6 +65,13 @@ LEAF(resume)
 	fpu_save_single a0, t0			# clobbers t0
 
 1:
+
+#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
+	PTR_L	t8, __stack_chk_guard
+	LONG_L	t9, TASK_STACK_CANARY(a1)
+	LONG_S	t9, 0(t8)
+#endif
+
 	/*
 	 * The order of restoring the registers takes care of the race
 	 * updating $28, $29 and kernelsp without disabling ints.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/r4k_switch.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/r4k_switch.S
--- linux-libre-3.10-gnu/arch/mips/kernel/r4k_switch.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/r4k_switch.S	2013-08-25 20:43:22.000000000 -0400
@@ -68,6 +68,12 @@
 						# clobbers t1
 1:
 
+#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
+	PTR_L	t8, __stack_chk_guard
+	LONG_L	t9, TASK_STACK_CANARY(a1)
+	LONG_S	t9, 0(t8)
+#endif
+
 	/*
 	 * The order of restoring the registers takes care of the race
 	 * updating $28, $29 and kernelsp without disabling ints.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/rtlx.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/rtlx.c
--- linux-libre-3.10-gnu/arch/mips/kernel/rtlx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/rtlx.c	2013-08-25 20:43:22.000000000 -0400
@@ -437,7 +437,6 @@ static ssize_t file_write(struct file *f
 			  size_t count, loff_t * ppos)
 {
 	int minor = iminor(file_inode(file));
-	struct rtlx_channel *rt = &rtlx->channel[minor];
 
 	/* any space left... */
 	if (!rtlx_write_poll(minor)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/scall32-o32.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/scall32-o32.S
--- linux-libre-3.10-gnu/arch/mips/kernel/scall32-o32.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/scall32-o32.S	2013-08-25 20:43:22.000000000 -0400
@@ -52,7 +52,7 @@ NESTED(handle_sys, PT_SIZE, sp)
 
 stack_done:
 	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
-	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	li	t1, _TIF_WORK_SYSCALL_ENTRY
 	and	t0, t1
 	bnez	t0, syscall_trace_entry # -> yes
 
@@ -476,8 +476,9 @@ einval: li	v0, -ENOSYS
 	/*
 	 * For FPU affinity scheduling on MIPS MT processors, we need to
 	 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
-	 * in kernel/sched.c.  Considered only temporary we only support these
-	 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
+	 * in kernel/sched/core.c.  Considered only temporary we only support
+	 * these hooks for the 32-bit kernel - there is no MIPS64 MT processor
+	 * atm.
 	 */
 	sys	mipsmt_sys_sched_setaffinity	3
 	sys	mipsmt_sys_sched_getaffinity	3
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/scall64-64.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/scall64-64.S
--- linux-libre-3.10-gnu/arch/mips/kernel/scall64-64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/scall64-64.S	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ NESTED(handle_sys64, PT_SIZE, sp)
 
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
-	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	li	t1, _TIF_WORK_SYSCALL_ENTRY
 	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	and	t0, t1, t0
 	bnez	t0, syscall_trace_entry
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/scall64-n32.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/scall64-n32.S
--- linux-libre-3.10-gnu/arch/mips/kernel/scall64-n32.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/scall64-n32.S	2013-08-25 20:43:22.000000000 -0400
@@ -47,7 +47,7 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
-	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	li	t1, _TIF_WORK_SYSCALL_ENTRY
 	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	and	t0, t1, t0
 	bnez	t0, n32_syscall_trace_entry
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/scall64-o32.S linux-libre-3.11-rc7-gnu/arch/mips/kernel/scall64-o32.S
--- linux-libre-3.10-gnu/arch/mips/kernel/scall64-o32.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/scall64-o32.S	2013-08-25 20:43:22.000000000 -0400
@@ -81,7 +81,7 @@ NESTED(handle_sys, PT_SIZE, sp)
 	PTR	4b, bad_stack
 	.previous
 
-	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	li	t1, _TIF_WORK_SYSCALL_ENTRY
 	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	and	t0, t1, t0
 	bnez	t0, trace_a_syscall
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/signal.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/signal.c
--- linux-libre-3.10-gnu/arch/mips/kernel/signal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/signal.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,7 @@
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/cache.h>
+#include <linux/context_tracking.h>
 #include <linux/irqflags.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -573,6 +574,8 @@ asmlinkage void do_notify_resume(struct
 {
 	local_irq_enable();
 
+	user_exit();
+
 	/* deal with pending signal delivery */
 	if (thread_info_flags & _TIF_SIGPENDING)
 		do_signal(regs);
@@ -581,6 +584,8 @@ asmlinkage void do_notify_resume(struct
 		clear_thread_flag(TIF_NOTIFY_RESUME);
 		tracehook_notify_resume(regs);
 	}
+
+	user_enter();
 }
 
 #ifdef CONFIG_SMP
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/smp-bmips.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/smp-bmips.c
--- linux-libre-3.10-gnu/arch/mips/kernel/smp-bmips.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/smp-bmips.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,22 +63,31 @@ static irqreturn_t bmips_ipi_interrupt(i
 
 static void __init bmips_smp_setup(void)
 {
-	int i;
+	int i, cpu = 1, boot_cpu = 0;
 
 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
+	int cpu_hw_intr;
+
 	/* arbitration priority */
 	clear_c0_brcm_cmt_ctrl(0x30);
 
 	/* NBK and weak order flags */
 	set_c0_brcm_config_0(0x30000);
 
+	/* Find out if we are running on TP0 or TP1 */
+	boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
+
 	/*
 	 * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
 	 * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
 	 * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
 	 */
-	change_c0_brcm_cmt_intr(0xf8018000,
-		(0x02 << 27) | (0x03 << 15));
+	if (boot_cpu == 0)
+		cpu_hw_intr = 0x02;
+	else
+		cpu_hw_intr = 0x1d;
+
+	change_c0_brcm_cmt_intr(0xf8018000, (cpu_hw_intr << 27) | (0x03 << 15));
 
 	/* single core, 2 threads (2 pipelines) */
 	max_cpus = 2;
@@ -106,9 +115,15 @@ static void __init bmips_smp_setup(void)
 	if (!board_ebase_setup)
 		board_ebase_setup = &bmips_ebase_setup;
 
+	__cpu_number_map[boot_cpu] = 0;
+	__cpu_logical_map[0] = boot_cpu;
+
 	for (i = 0; i < max_cpus; i++) {
-		__cpu_number_map[i] = 1;
-		__cpu_logical_map[i] = 1;
+		if (i != boot_cpu) {
+			__cpu_number_map[i] = cpu;
+			__cpu_logical_map[cpu] = i;
+			cpu++;
+		}
 		set_cpu_possible(i, 1);
 		set_cpu_present(i, 1);
 	}
@@ -157,7 +172,9 @@ static void bmips_boot_secondary(int cpu
 		bmips_send_ipi_single(cpu, 0);
 	else {
 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
-		set_c0_brcm_cmt_ctrl(0x01);
+		/* Reset slave TP1 if booting from TP0 */
+		if (cpu_logical_map(cpu) == 1)
+			set_c0_brcm_cmt_ctrl(0x01);
 #elif defined(CONFIG_CPU_BMIPS5000)
 		if (cpu & 0x01)
 			write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
@@ -185,9 +202,15 @@ static void bmips_init_secondary(void)
 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
 	void __iomem *cbr = BMIPS_GET_CBR();
 	unsigned long old_vec;
+	unsigned long relo_vector;
+	int boot_cpu;
 
-	old_vec = __raw_readl(cbr + BMIPS_RELO_VECTOR_CONTROL_1);
-	__raw_writel(old_vec & ~0x20000000, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+	boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
+	relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
+			  BMIPS_RELO_VECTOR_CONTROL_1;
+
+	old_vec = __raw_readl(cbr + relo_vector);
+	__raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
 
 	clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
 #elif defined(CONFIG_CPU_BMIPS5000)
@@ -381,7 +404,7 @@ struct plat_smp_ops bmips_smp_ops = {
  * UP BMIPS systems as well.
  ***********************************************************************/
 
-static void __cpuinit bmips_wr_vec(unsigned long dst, char *start, char *end)
+static void bmips_wr_vec(unsigned long dst, char *start, char *end)
 {
 	memcpy((void *)dst, start, end - start);
 	dma_cache_wback((unsigned long)start, end - start);
@@ -389,7 +412,7 @@ static void __cpuinit bmips_wr_vec(unsig
 	instruction_hazard();
 }
 
-static inline void __cpuinit bmips_nmi_handler_setup(void)
+static inline void bmips_nmi_handler_setup(void)
 {
 	bmips_wr_vec(BMIPS_NMI_RESET_VEC, &bmips_reset_nmi_vec,
 		&bmips_reset_nmi_vec_end);
@@ -397,7 +420,7 @@ static inline void __cpuinit bmips_nmi_h
 		&bmips_smp_int_vec_end);
 }
 
-void __cpuinit bmips_ebase_setup(void)
+void bmips_ebase_setup(void)
 {
 	unsigned long new_ebase = ebase;
 	void __iomem __maybe_unused *cbr;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/smp.c
--- linux-libre-3.10-gnu/arch/mips/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -86,7 +86,7 @@ static inline void set_cpu_sibling_map(i
 struct plat_smp_ops *mp_ops;
 EXPORT_SYMBOL(mp_ops);
 
-__cpuinit void register_smp_ops(struct plat_smp_ops *ops)
+void register_smp_ops(struct plat_smp_ops *ops)
 {
 	if (mp_ops)
 		printk(KERN_WARNING "Overriding previously set SMP ops\n");
@@ -98,7 +98,7 @@ __cpuinit void register_smp_ops(struct p
  * First C code run on the secondary CPUs after being started up by
  * the master.
  */
-asmlinkage __cpuinit void start_secondary(void)
+asmlinkage void start_secondary(void)
 {
 	unsigned int cpu;
 
@@ -197,7 +197,7 @@ void smp_prepare_boot_cpu(void)
 	cpu_set(0, cpu_callin_map);
 }
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	mp_ops->boot_secondary(cpu, tidle);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/smp-mt.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/smp-mt.c
--- linux-libre-3.10-gnu/arch/mips/kernel/smp-mt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/smp-mt.c	2013-08-25 20:43:22.000000000 -0400
@@ -149,7 +149,7 @@ static void vsmp_send_ipi_mask(const str
 		vsmp_send_ipi_single(i, action);
 }
 
-static void __cpuinit vsmp_init_secondary(void)
+static void vsmp_init_secondary(void)
 {
 #ifdef CONFIG_IRQ_GIC
 	/* This is Malta specific: IPI,performance and timer interrupts */
@@ -162,7 +162,7 @@ static void __cpuinit vsmp_init_secondar
 					 STATUSF_IP6 | STATUSF_IP7);
 }
 
-static void __cpuinit vsmp_smp_finish(void)
+static void vsmp_smp_finish(void)
 {
 	/* CDFIXME: remove this? */
 	write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
@@ -188,7 +188,7 @@ static void vsmp_cpus_done(void)
  * (unsigned long)idle->thread_info the gp
  * assumes a 1:1 mapping of TC => VPE
  */
-static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)
+static void vsmp_boot_secondary(int cpu, struct task_struct *idle)
 {
 	struct thread_info *gp = task_thread_info(idle);
 	dvpe();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/smp-up.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/smp-up.c
--- linux-libre-3.10-gnu/arch/mips/kernel/smp-up.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/smp-up.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,11 +28,11 @@ static inline void up_send_ipi_mask(cons
  *  After we've done initial boot, this function is called to allow the
  *  board code to clean up state, if needed
  */
-static void __cpuinit up_init_secondary(void)
+static void up_init_secondary(void)
 {
 }
 
-static void __cpuinit up_smp_finish(void)
+static void up_smp_finish(void)
 {
 }
 
@@ -44,7 +44,7 @@ static void up_cpus_done(void)
 /*
  * Firmware CPU startup hook
  */
-static void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle)
+static void up_boot_secondary(int cpu, struct task_struct *idle)
 {
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/smtc.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/smtc.c
--- linux-libre-3.10-gnu/arch/mips/kernel/smtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/smtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -645,7 +645,7 @@ void smtc_prepare_cpus(int cpus)
  * (unsigned long)idle->thread_info the gp
  *
  */
-void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle)
+void smtc_boot_secondary(int cpu, struct task_struct *idle)
 {
 	extern u32 kernelsp[NR_CPUS];
 	unsigned long flags;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/spram.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/spram.c
--- linux-libre-3.10-gnu/arch/mips/kernel/spram.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/spram.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,7 @@
 /*
  * Different semantics to the set_c0_* function built by __BUILD_SET_C0
  */
-static __cpuinit unsigned int bis_c0_errctl(unsigned int set)
+static unsigned int bis_c0_errctl(unsigned int set)
 {
 	unsigned int res;
 	res = read_c0_errctl();
@@ -45,7 +45,7 @@ static __cpuinit unsigned int bis_c0_err
 	return res;
 }
 
-static __cpuinit void ispram_store_tag(unsigned int offset, unsigned int data)
+static void ispram_store_tag(unsigned int offset, unsigned int data)
 {
 	unsigned int errctl;
 
@@ -64,7 +64,7 @@ static __cpuinit void ispram_store_tag(u
 }
 
 
-static __cpuinit unsigned int ispram_load_tag(unsigned int offset)
+static unsigned int ispram_load_tag(unsigned int offset)
 {
 	unsigned int data;
 	unsigned int errctl;
@@ -82,7 +82,7 @@ static __cpuinit unsigned int ispram_loa
 	return data;
 }
 
-static __cpuinit void dspram_store_tag(unsigned int offset, unsigned int data)
+static void dspram_store_tag(unsigned int offset, unsigned int data)
 {
 	unsigned int errctl;
 
@@ -98,7 +98,7 @@ static __cpuinit void dspram_store_tag(u
 }
 
 
-static __cpuinit unsigned int dspram_load_tag(unsigned int offset)
+static unsigned int dspram_load_tag(unsigned int offset)
 {
 	unsigned int data;
 	unsigned int errctl;
@@ -115,7 +115,7 @@ static __cpuinit unsigned int dspram_loa
 	return data;
 }
 
-static __cpuinit void probe_spram(char *type,
+static void probe_spram(char *type,
 	    unsigned int base,
 	    unsigned int (*read)(unsigned int),
 	    void (*write)(unsigned int, unsigned int))
@@ -196,7 +196,7 @@ static __cpuinit void probe_spram(char *
 		offset += 2 * SPRAM_TAG_STRIDE;
 	}
 }
-void __cpuinit spram_config(void)
+void spram_config(void)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
 	unsigned int config0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/sync-r4k.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/sync-r4k.c
--- linux-libre-3.10-gnu/arch/mips/kernel/sync-r4k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/sync-r4k.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,15 +20,15 @@
 #include <asm/barrier.h>
 #include <asm/mipsregs.h>
 
-static atomic_t __cpuinitdata count_start_flag = ATOMIC_INIT(0);
-static atomic_t __cpuinitdata count_count_start = ATOMIC_INIT(0);
-static atomic_t __cpuinitdata count_count_stop = ATOMIC_INIT(0);
-static atomic_t __cpuinitdata count_reference = ATOMIC_INIT(0);
+static atomic_t count_start_flag = ATOMIC_INIT(0);
+static atomic_t count_count_start = ATOMIC_INIT(0);
+static atomic_t count_count_stop = ATOMIC_INIT(0);
+static atomic_t count_reference = ATOMIC_INIT(0);
 
 #define COUNTON 100
 #define NR_LOOPS 5
 
-void __cpuinit synchronise_count_master(int cpu)
+void synchronise_count_master(int cpu)
 {
 	int i;
 	unsigned long flags;
@@ -106,7 +106,7 @@ void __cpuinit synchronise_count_master(
 	printk("done.\n");
 }
 
-void __cpuinit synchronise_count_slave(int cpu)
+void synchronise_count_slave(int cpu)
 {
 	int i;
 	unsigned int initcount;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/traps.c
--- linux-libre-3.10-gnu/arch/mips/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
  */
 #include <linux/bug.h>
 #include <linux/compiler.h>
+#include <linux/context_tracking.h>
 #include <linux/kexec.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -89,7 +90,7 @@ void (*board_nmi_handler_setup)(void);
 void (*board_ejtag_handler_setup)(void);
 void (*board_bind_eic_interrupt)(int irq, int regset);
 void (*board_ebase_setup)(void);
-void __cpuinitdata(*board_cache_error_setup)(void);
+void(*board_cache_error_setup)(void);
 
 static void show_raw_backtrace(unsigned long reg29)
 {
@@ -264,7 +265,7 @@ static void __show_regs(const struct pt_
 
 	printk("Status: %08x	", (uint32_t) regs->cp0_status);
 
-	if (current_cpu_data.isa_level == MIPS_CPU_ISA_I) {
+	if (cpu_has_3kex) {
 		if (regs->cp0_status & ST0_KUO)
 			printk("KUo ");
 		if (regs->cp0_status & ST0_IEO)
@@ -277,7 +278,7 @@ static void __show_regs(const struct pt_
 			printk("KUc ");
 		if (regs->cp0_status & ST0_IEC)
 			printk("IEc ");
-	} else {
+	} else if (cpu_has_4kex) {
 		if (regs->cp0_status & ST0_KX)
 			printk("KX ");
 		if (regs->cp0_status & ST0_SX)
@@ -423,7 +424,9 @@ asmlinkage void do_be(struct pt_regs *re
 	const struct exception_table_entry *fixup = NULL;
 	int data = regs->cp0_cause & 4;
 	int action = MIPS_BE_FATAL;
+	enum ctx_state prev_state;
 
+	prev_state = exception_enter();
 	/* XXX For now.	 Fixme, this searches the wrong table ...  */
 	if (data && !user_mode(regs))
 		fixup = search_dbe_tables(exception_epc(regs));
@@ -436,11 +439,11 @@ asmlinkage void do_be(struct pt_regs *re
 
 	switch (action) {
 	case MIPS_BE_DISCARD:
-		return;
+		goto out;
 	case MIPS_BE_FIXUP:
 		if (fixup) {
 			regs->cp0_epc = fixup->nextinsn;
-			return;
+			goto out;
 		}
 		break;
 	default:
@@ -455,10 +458,13 @@ asmlinkage void do_be(struct pt_regs *re
 	       field, regs->cp0_epc, field, regs->regs[31]);
 	if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS)
 	    == NOTIFY_STOP)
-		return;
+		goto out;
 
 	die_if_kernel("Oops", regs);
 	force_sig(SIGBUS, current);
+
+out:
+	exception_exit(prev_state);
 }
 
 /*
@@ -673,8 +679,10 @@ static int simulate_sync(struct pt_regs
 
 asmlinkage void do_ov(struct pt_regs *regs)
 {
+	enum ctx_state prev_state;
 	siginfo_t info;
 
+	prev_state = exception_enter();
 	die_if_kernel("Integer overflow", regs);
 
 	info.si_code = FPE_INTOVF;
@@ -682,6 +690,7 @@ asmlinkage void do_ov(struct pt_regs *re
 	info.si_errno = 0;
 	info.si_addr = (void __user *) regs->cp0_epc;
 	force_sig_info(SIGFPE, &info, current);
+	exception_exit(prev_state);
 }
 
 int process_fpemu_return(int sig, void __user *fault_addr)
@@ -713,11 +722,13 @@ int process_fpemu_return(int sig, void _
  */
 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
+	enum ctx_state prev_state;
 	siginfo_t info = {0};
 
+	prev_state = exception_enter();
 	if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
 	    == NOTIFY_STOP)
-		return;
+		goto out;
 	die_if_kernel("FP exception in kernel code", regs);
 
 	if (fcr31 & FPU_CSR_UNI_X) {
@@ -753,7 +764,7 @@ asmlinkage void do_fpe(struct pt_regs *r
 		/* If something went wrong, signal */
 		process_fpemu_return(sig, fault_addr);
 
-		return;
+		goto out;
 	} else if (fcr31 & FPU_CSR_INV_X)
 		info.si_code = FPE_FLTINV;
 	else if (fcr31 & FPU_CSR_DIV_X)
@@ -770,6 +781,9 @@ asmlinkage void do_fpe(struct pt_regs *r
 	info.si_errno = 0;
 	info.si_addr = (void __user *) regs->cp0_epc;
 	force_sig_info(SIGFPE, &info, current);
+
+out:
+	exception_exit(prev_state);
 }
 
 static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
@@ -835,9 +849,11 @@ static void do_trap_or_bp(struct pt_regs
 asmlinkage void do_bp(struct pt_regs *regs)
 {
 	unsigned int opcode, bcode;
+	enum ctx_state prev_state;
 	unsigned long epc;
 	u16 instr[2];
 
+	prev_state = exception_enter();
 	if (get_isa16_mode(regs->cp0_epc)) {
 		/* Calculate EPC. */
 		epc = exception_epc(regs);
@@ -852,7 +868,7 @@ asmlinkage void do_bp(struct pt_regs *re
 				goto out_sigsegv;
 		    bcode = (instr[0] >> 6) & 0x3f;
 		    do_trap_or_bp(regs, bcode, "Break");
-		    return;
+		    goto out;
 		}
 	} else {
 		if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
@@ -876,12 +892,12 @@ asmlinkage void do_bp(struct pt_regs *re
 	switch (bcode) {
 	case BRK_KPROBE_BP:
 		if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
-			return;
+			goto out;
 		else
 			break;
 	case BRK_KPROBE_SSTEPBP:
 		if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
-			return;
+			goto out;
 		else
 			break;
 	default:
@@ -889,18 +905,24 @@ asmlinkage void do_bp(struct pt_regs *re
 	}
 
 	do_trap_or_bp(regs, bcode, "Break");
+
+out:
+	exception_exit(prev_state);
 	return;
 
 out_sigsegv:
 	force_sig(SIGSEGV, current);
+	goto out;
 }
 
 asmlinkage void do_tr(struct pt_regs *regs)
 {
 	u32 opcode, tcode = 0;
+	enum ctx_state prev_state;
 	u16 instr[2];
 	unsigned long epc = msk_isa16_mode(exception_epc(regs));
 
+	prev_state = exception_enter();
 	if (get_isa16_mode(regs->cp0_epc)) {
 		if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
 		    __get_user(instr[1], (u16 __user *)(epc + 2)))
@@ -918,10 +940,14 @@ asmlinkage void do_tr(struct pt_regs *re
 	}
 
 	do_trap_or_bp(regs, tcode, "Trap");
+
+out:
+	exception_exit(prev_state);
 	return;
 
 out_sigsegv:
 	force_sig(SIGSEGV, current);
+	goto out;
 }
 
 asmlinkage void do_ri(struct pt_regs *regs)
@@ -929,17 +955,19 @@ asmlinkage void do_ri(struct pt_regs *re
 	unsigned int __user *epc = (unsigned int __user *)exception_epc(regs);
 	unsigned long old_epc = regs->cp0_epc;
 	unsigned long old31 = regs->regs[31];
+	enum ctx_state prev_state;
 	unsigned int opcode = 0;
 	int status = -1;
 
+	prev_state = exception_enter();
 	if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL)
 	    == NOTIFY_STOP)
-		return;
+		goto out;
 
 	die_if_kernel("Reserved instruction in kernel code", regs);
 
 	if (unlikely(compute_return_epc(regs) < 0))
-		return;
+		goto out;
 
 	if (get_isa16_mode(regs->cp0_epc)) {
 		unsigned short mmop[2] = { 0 };
@@ -974,6 +1002,9 @@ asmlinkage void do_ri(struct pt_regs *re
 		regs->regs[31] = old31;
 		force_sig(status, current);
 	}
+
+out:
+	exception_exit(prev_state);
 }
 
 /*
@@ -1025,21 +1056,16 @@ static int default_cu2_call(struct notif
 {
 	struct pt_regs *regs = data;
 
-	switch (action) {
-	default:
-		die_if_kernel("Unhandled kernel unaligned access or invalid "
+	die_if_kernel("COP2: Unhandled kernel unaligned access or invalid "
 			      "instruction", regs);
-		/* Fall through	 */
-
-	case CU2_EXCEPTION:
-		force_sig(SIGILL, current);
-	}
+	force_sig(SIGILL, current);
 
 	return NOTIFY_OK;
 }
 
 asmlinkage void do_cpu(struct pt_regs *regs)
 {
+	enum ctx_state prev_state;
 	unsigned int __user *epc;
 	unsigned long old_epc, old31;
 	unsigned int opcode;
@@ -1047,10 +1073,12 @@ asmlinkage void do_cpu(struct pt_regs *r
 	int status;
 	unsigned long __maybe_unused flags;
 
-	die_if_kernel("do_cpu invoked from kernel context!", regs);
-
+	prev_state = exception_enter();
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
 
+	if (cpid != 2)
+		die_if_kernel("do_cpu invoked from kernel context!", regs);
+
 	switch (cpid) {
 	case 0:
 		epc = (unsigned int __user *)exception_epc(regs);
@@ -1060,7 +1088,7 @@ asmlinkage void do_cpu(struct pt_regs *r
 		status = -1;
 
 		if (unlikely(compute_return_epc(regs) < 0))
-			return;
+			goto out;
 
 		if (get_isa16_mode(regs->cp0_epc)) {
 			unsigned short mmop[2] = { 0 };
@@ -1093,7 +1121,7 @@ asmlinkage void do_cpu(struct pt_regs *r
 			force_sig(status, current);
 		}
 
-		return;
+		goto out;
 
 	case 3:
 		/*
@@ -1131,19 +1159,26 @@ asmlinkage void do_cpu(struct pt_regs *r
 				mt_ase_fp_affinity();
 		}
 
-		return;
+		goto out;
 
 	case 2:
 		raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
-		return;
+		goto out;
 	}
 
 	force_sig(SIGILL, current);
+
+out:
+	exception_exit(prev_state);
 }
 
 asmlinkage void do_mdmx(struct pt_regs *regs)
 {
+	enum ctx_state prev_state;
+
+	prev_state = exception_enter();
 	force_sig(SIGILL, current);
+	exception_exit(prev_state);
 }
 
 /*
@@ -1151,8 +1186,10 @@ asmlinkage void do_mdmx(struct pt_regs *
  */
 asmlinkage void do_watch(struct pt_regs *regs)
 {
+	enum ctx_state prev_state;
 	u32 cause;
 
+	prev_state = exception_enter();
 	/*
 	 * Clear WP (bit 22) bit of cause register so we don't loop
 	 * forever.
@@ -1174,13 +1211,16 @@ asmlinkage void do_watch(struct pt_regs
 		mips_clear_watch_registers();
 		local_irq_enable();
 	}
+	exception_exit(prev_state);
 }
 
 asmlinkage void do_mcheck(struct pt_regs *regs)
 {
 	const int field = 2 * sizeof(unsigned long);
 	int multi_match = regs->cp0_status & ST0_TS;
+	enum ctx_state prev_state;
 
+	prev_state = exception_enter();
 	show_regs(regs);
 
 	if (multi_match) {
@@ -1627,7 +1667,6 @@ void *set_vi_handler(int n, vi_handler_t
 }
 
 extern void tlb_init(void);
-extern void flush_tlb_handlers(void);
 
 /*
  * Timer interrupt
@@ -1642,7 +1681,7 @@ int cp0_compare_irq_shift;
 int cp0_perfcount_irq;
 EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
 
-static int __cpuinitdata noulri;
+static int noulri;
 
 static int __init ulri_disable(char *s)
 {
@@ -1653,7 +1692,7 @@ static int __init ulri_disable(char *s)
 }
 __setup("noulri", ulri_disable);
 
-void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
+void per_cpu_trap_init(bool is_boot_cpu)
 {
 	unsigned int cpu = smp_processor_id();
 	unsigned int status_set = ST0_CU0;
@@ -1770,7 +1809,7 @@ void __cpuinit per_cpu_trap_init(bool is
 }
 
 /* Install CPU exception handler */
-void __cpuinit set_handler(unsigned long offset, void *addr, unsigned long size)
+void set_handler(unsigned long offset, void *addr, unsigned long size)
 {
 #ifdef CONFIG_CPU_MICROMIPS
 	memcpy((void *)(ebase + offset), ((unsigned char *)addr - 1), size);
@@ -1780,7 +1819,7 @@ void __cpuinit set_handler(unsigned long
 	local_flush_icache_range(ebase + offset, ebase + offset + size);
 }
 
-static char panic_null_cerr[] __cpuinitdata =
+static char panic_null_cerr[] =
 	"Trying to set NULL cache error exception handler";
 
 /*
@@ -1788,7 +1827,7 @@ static char panic_null_cerr[] __cpuinitd
  * This is suitable only for the cache error exception which is the only
  * exception handler that is being run uncached.
  */
-void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
+void set_uncached_handler(unsigned long offset, void *addr,
 	unsigned long size)
 {
 	unsigned long uncached_ebase = CKSEG1ADDR(ebase);
@@ -1837,6 +1876,15 @@ void __init trap_init(void)
 			ebase += (read_c0_ebase() & 0x3ffff000);
 	}
 
+	if (cpu_has_mmips) {
+		unsigned int config3 = read_c0_config3();
+
+		if (IS_ENABLED(CONFIG_CPU_MICROMIPS))
+			write_c0_config3(config3 | MIPS_CONF3_ISA_OE);
+		else
+			write_c0_config3(config3 & ~MIPS_CONF3_ISA_OE);
+	}
+
 	if (board_ebase_setup)
 		board_ebase_setup();
 	per_cpu_trap_init(true);
@@ -1956,7 +2004,6 @@ void __init trap_init(void)
 		set_handler(0x080, &except_vec3_generic, 0x80);
 
 	local_flush_icache_range(ebase, ebase + 0x400);
-	flush_tlb_handlers();
 
 	sort_extable(__start___dbe_table, __stop___dbe_table);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/unaligned.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/unaligned.c
--- linux-libre-3.10-gnu/arch/mips/kernel/unaligned.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/unaligned.c	2013-08-25 20:43:22.000000000 -0400
@@ -72,6 +72,7 @@
  *	 A store crossing a page boundary might be executed only partially.
  *	 Undo the partial store in this case.
  */
+#include <linux/context_tracking.h>
 #include <linux/mm.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
@@ -684,7 +685,8 @@ const int reg16to32[] = { 16, 17, 2, 3,
 /* Recode table from 16-bit STORE register notation to 32-bit GPR. */
 const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
 
-void emulate_load_store_microMIPS(struct pt_regs *regs, void __user * addr)
+static void emulate_load_store_microMIPS(struct pt_regs *regs,
+					 void __user *addr)
 {
 	unsigned long value;
 	unsigned int res;
@@ -1548,11 +1550,14 @@ sigill:
 	    ("Unhandled kernel unaligned access or invalid instruction", regs);
 	force_sig(SIGILL, current);
 }
+
 asmlinkage void do_ade(struct pt_regs *regs)
 {
+	enum ctx_state prev_state;
 	unsigned int __user *pc;
 	mm_segment_t seg;
 
+	prev_state = exception_enter();
 	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
 			1, regs, regs->cp0_badvaddr);
 	/*
@@ -1628,6 +1633,7 @@ sigbus:
 	/*
 	 * XXX On return from the signal handler we should advance the epc
 	 */
+	exception_exit(prev_state);
 }
 
 #ifdef CONFIG_DEBUG_FS
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kernel/watch.c linux-libre-3.11-rc7-gnu/arch/mips/kernel/watch.c
--- linux-libre-3.10-gnu/arch/mips/kernel/watch.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kernel/watch.c	2013-08-25 20:43:22.000000000 -0400
@@ -100,7 +100,7 @@ void mips_clear_watch_registers(void)
 	}
 }
 
-__cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c)
+void mips_probe_watch_registers(struct cpuinfo_mips *c)
 {
 	unsigned int t;
 
@@ -111,6 +111,7 @@ __cpuinit void mips_probe_watch_register
 	 * disable the register.
 	 */
 	write_c0_watchlo0(7);
+	back_to_back_c0_hazard();
 	t = read_c0_watchlo0();
 	write_c0_watchlo0(0);
 	c->watch_reg_masks[0] = t & 7;
@@ -121,12 +122,14 @@ __cpuinit void mips_probe_watch_register
 	c->watch_reg_use_cnt = 1;
 	t = read_c0_watchhi0();
 	write_c0_watchhi0(t | 0xff8);
+	back_to_back_c0_hazard();
 	t = read_c0_watchhi0();
 	c->watch_reg_masks[0] |= (t & 0xff8);
 	if ((t & 0x80000000) == 0)
 		return;
 
 	write_c0_watchlo1(7);
+	back_to_back_c0_hazard();
 	t = read_c0_watchlo1();
 	write_c0_watchlo1(0);
 	c->watch_reg_masks[1] = t & 7;
@@ -135,12 +138,14 @@ __cpuinit void mips_probe_watch_register
 	c->watch_reg_use_cnt = 2;
 	t = read_c0_watchhi1();
 	write_c0_watchhi1(t | 0xff8);
+	back_to_back_c0_hazard();
 	t = read_c0_watchhi1();
 	c->watch_reg_masks[1] |= (t & 0xff8);
 	if ((t & 0x80000000) == 0)
 		return;
 
 	write_c0_watchlo2(7);
+	back_to_back_c0_hazard();
 	t = read_c0_watchlo2();
 	write_c0_watchlo2(0);
 	c->watch_reg_masks[2] = t & 7;
@@ -149,12 +154,14 @@ __cpuinit void mips_probe_watch_register
 	c->watch_reg_use_cnt = 3;
 	t = read_c0_watchhi2();
 	write_c0_watchhi2(t | 0xff8);
+	back_to_back_c0_hazard();
 	t = read_c0_watchhi2();
 	c->watch_reg_masks[2] |= (t & 0xff8);
 	if ((t & 0x80000000) == 0)
 		return;
 
 	write_c0_watchlo3(7);
+	back_to_back_c0_hazard();
 	t = read_c0_watchlo3();
 	write_c0_watchlo3(0);
 	c->watch_reg_masks[3] = t & 7;
@@ -163,6 +170,7 @@ __cpuinit void mips_probe_watch_register
 	c->watch_reg_use_cnt = 4;
 	t = read_c0_watchhi3();
 	write_c0_watchhi3(t | 0xff8);
+	back_to_back_c0_hazard();
 	t = read_c0_watchhi3();
 	c->watch_reg_masks[3] |= (t & 0xff8);
 	if ((t & 0x80000000) == 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/kvm/Kconfig linux-libre-3.11-rc7-gnu/arch/mips/kvm/Kconfig
--- linux-libre-3.10-gnu/arch/mips/kvm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/kvm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,6 @@ source "virt/kvm/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
-	depends on HAVE_KVM
 	---help---
 	  Say Y here to get to see options for using your Linux host to run
 	  other operating systems inside virtual machines (guests).
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/lantiq/irq.c linux-libre-3.11-rc7-gnu/arch/mips/lantiq/irq.c
--- linux-libre-3.10-gnu/arch/mips/lantiq/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/lantiq/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -461,7 +461,7 @@ int __init icu_of_init(struct device_nod
 	return 0;
 }
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
 	return MIPS_CPU_TIMER_IRQ;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/lantiq/prom.c linux-libre-3.11-rc7-gnu/arch/mips/lantiq/prom.c
--- linux-libre-3.10-gnu/arch/mips/lantiq/prom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/lantiq/prom.c	2013-08-25 20:43:22.000000000 -0400
@@ -112,7 +112,7 @@ int __init plat_of_setup(void)
 	if (!of_have_populated_dt())
 		panic("device tree not present");
 
-	strncpy(of_ids[0].compatible, soc_info.compatible,
+	strlcpy(of_ids[0].compatible, soc_info.compatible,
 		sizeof(of_ids[0].compatible));
 	strncpy(of_ids[1].compatible, "simple-bus",
 		sizeof(of_ids[1].compatible));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/lasat/sysctl.c linux-libre-3.11-rc7-gnu/arch/mips/lasat/sysctl.c
--- linux-libre-3.10-gnu/arch/mips/lasat/sysctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/lasat/sysctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,7 @@
 
 
 /* And the same for proc */
-int proc_dolasatstring(ctl_table *table, int write,
+int proc_dolasatstring(struct ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
 	int r;
@@ -54,7 +54,7 @@ int proc_dolasatstring(ctl_table *table,
 }
 
 /* proc function to write EEPROM after changing int entry */
-int proc_dolasatint(ctl_table *table, int write,
+int proc_dolasatint(struct ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
 	int r;
@@ -72,7 +72,7 @@ int proc_dolasatint(ctl_table *table, in
 static int rtctmp;
 
 /* proc function to read/write RealTime Clock */
-int proc_dolasatrtc(ctl_table *table, int write,
+int proc_dolasatrtc(struct ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
 	struct timespec ts;
@@ -97,7 +97,7 @@ int proc_dolasatrtc(ctl_table *table, in
 #endif
 
 #ifdef CONFIG_INET
-int proc_lasat_ip(ctl_table *table, int write,
+int proc_lasat_ip(struct ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
 	unsigned int ip;
@@ -157,7 +157,7 @@ int proc_lasat_ip(ctl_table *table, int
 }
 #endif
 
-int proc_lasat_prid(ctl_table *table, int write,
+int proc_lasat_prid(struct ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
 	int r;
@@ -176,7 +176,7 @@ int proc_lasat_prid(ctl_table *table, in
 
 extern int lasat_boot_to_service;
 
-static ctl_table lasat_table[] = {
+static struct ctl_table lasat_table[] = {
 	{
 		.procname	= "cpu-hz",
 		.data		= &lasat_board_info.li_cpu_hz,
@@ -262,7 +262,7 @@ static ctl_table lasat_table[] = {
 	{}
 };
 
-static ctl_table lasat_root_table[] = {
+static struct ctl_table lasat_root_table[] = {
 	{
 		.procname	= "lasat",
 		.mode		=  0555,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/lib/uncached.c linux-libre-3.11-rc7-gnu/arch/mips/lib/uncached.c
--- linux-libre-3.10-gnu/arch/mips/lib/uncached.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/lib/uncached.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,7 @@
  * values, so we can avoid sharing the same stack area between a cached
  * and the uncached mode.
  */
-unsigned long __cpuinit run_uncached(void *func)
+unsigned long run_uncached(void *func)
 {
 	register long sp __asm__("$sp");
 	register long ret __asm__("$2");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/loongson/common/cs5536/cs5536_isa.c linux-libre-3.11-rc7-gnu/arch/mips/loongson/common/cs5536/cs5536_isa.c
--- linux-libre-3.10-gnu/arch/mips/loongson/common/cs5536/cs5536_isa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/loongson/common/cs5536/cs5536_isa.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
  * option) any later version.
  */
 
+#include <linux/pci.h>
 #include <cs5536/cs5536.h>
 #include <cs5536/cs5536_pci.h>
 
@@ -314,3 +315,16 @@ u32 pci_isa_read_reg(int reg)
 
 	return conf_data;
 }
+
+/*
+ * The mfgpt timer interrupt is running early, so we must keep the south bridge
+ * mmio always enabled. Otherwise we may race with the PCI configuration which
+ * may temporarily disable it. When that happens and the timer interrupt fires,
+ * we are not able to clear it and the system will hang.
+ */
+static void cs5536_isa_mmio_always_on(struct pci_dev *dev)
+{
+	dev->mmio_always_on = 1;
+}
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
+	PCI_CLASS_BRIDGE_ISA, 8, cs5536_isa_mmio_always_on);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/loongson/lemote-2f/clock.c linux-libre-3.11-rc7-gnu/arch/mips/loongson/lemote-2f/clock.c
--- linux-libre-3.10-gnu/arch/mips/loongson/lemote-2f/clock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/loongson/lemote-2f/clock.c	2013-08-25 20:43:22.000000000 -0400
@@ -121,7 +121,8 @@ int clk_set_rate(struct clk *clk, unsign
 	clk->rate = rate;
 
 	regval = LOONGSON_CHIPCFG0;
-	regval = (regval & ~0x7) | (loongson2_clockmod_table[i].index - 1);
+	regval = (regval & ~0x7) |
+		(loongson2_clockmod_table[i].driver_data - 1);
 	LOONGSON_CHIPCFG0 = regval;
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/Makefile linux-libre-3.11-rc7-gnu/arch/mips/Makefile
--- linux-libre-3.10-gnu/arch/mips/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -227,6 +227,10 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(d
 
 LDFLAGS			+= -m $(ld-emul)
 
+ifdef CONFIG_CC_STACKPROTECTOR
+  KBUILD_CFLAGS += -fstack-protector
+endif
+
 ifdef CONFIG_MIPS
 CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
 	egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/math-emu/cp1emu.c linux-libre-3.11-rc7-gnu/arch/mips/math-emu/cp1emu.c
--- linux-libre-3.10-gnu/arch/mips/math-emu/cp1emu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/math-emu/cp1emu.c	2013-08-25 20:43:22.000000000 -0400
@@ -471,6 +471,9 @@ int mm_isBranchInstr(struct pt_regs *reg
 	unsigned int fcr31;
 	unsigned int bit;
 
+	if (!cpu_has_mmips)
+		return 0;
+
 	switch (insn.mm_i_format.opcode) {
 	case mm_pool32a_op:
 		if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
@@ -800,6 +803,32 @@ static int isBranchInstr(struct pt_regs
 				dec_insn.next_pc_inc;
 		return 1;
 		break;
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+	case lwc2_op: /* This is bbit0 on Octeon */
+		if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt)) == 0)
+			*contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			*contpc = regs->cp0_epc + 8;
+		return 1;
+	case ldc2_op: /* This is bbit032 on Octeon */
+		if ((regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32))) == 0)
+			*contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			*contpc = regs->cp0_epc + 8;
+		return 1;
+	case swc2_op: /* This is bbit1 on Octeon */
+		if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
+			*contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			*contpc = regs->cp0_epc + 8;
+		return 1;
+	case sdc2_op: /* This is bbit132 on Octeon */
+		if (regs->regs[insn.i_format.rs] & (1ull<<(insn.i_format.rt + 32)))
+			*contpc = regs->cp0_epc + 4 + (insn.i_format.simmediate << 2);
+		else
+			*contpc = regs->cp0_epc + 8;
+		return 1;
+#endif
 	case cop0_op:
 	case cop1_op:
 	case cop2_op:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/cache.c linux-libre-3.11-rc7-gnu/arch/mips/mm/cache.c
--- linux-libre-3.10-gnu/arch/mips/mm/cache.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/cache.c	2013-08-25 20:43:22.000000000 -0400
@@ -182,7 +182,7 @@ static inline void setup_protection_map(
 	}
 }
 
-void __cpuinit cpu_cache_init(void)
+void cpu_cache_init(void)
 {
 	if (cpu_has_3k_cache) {
 		extern void __weak r3k_cache_init(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/cerr-sb1.c linux-libre-3.11-rc7-gnu/arch/mips/mm/cerr-sb1.c
--- linux-libre-3.10-gnu/arch/mips/mm/cerr-sb1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/cerr-sb1.c	2013-08-25 20:43:22.000000000 -0400
@@ -182,11 +182,7 @@ asmlinkage void sb1_cache_error(void)
 
 #ifdef CONFIG_SIBYTE_BW_TRACE
 	/* Freeze the trace buffer now */
-#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
-	csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
-#else
 	csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
-#endif
 	printk("Trace buffer frozen\n");
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/cex-sb1.S linux-libre-3.11-rc7-gnu/arch/mips/mm/cex-sb1.S
--- linux-libre-3.10-gnu/arch/mips/mm/cex-sb1.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/cex-sb1.S	2013-08-25 20:43:22.000000000 -0400
@@ -49,8 +49,6 @@
 	 * (0x170-0x17f) are used to preserve k0, k1, and ra.
 	 */
 
-	__CPUINIT
-
 LEAF(except_vec2_sb1)
 	/*
 	 * If this error is recoverable, we need to exit the handler
@@ -142,8 +140,6 @@ unrecoverable:
 
 END(except_vec2_sb1)
 
-	__FINIT
-
 	LEAF(handle_vec2_sb1)
 	mfc0	k0,CP0_CONFIG
 	li	k1,~CONF_CM_CMASK
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/c-octeon.c linux-libre-3.11-rc7-gnu/arch/mips/mm/c-octeon.c
--- linux-libre-3.10-gnu/arch/mips/mm/c-octeon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/c-octeon.c	2013-08-25 20:43:22.000000000 -0400
@@ -180,7 +180,7 @@ static void octeon_flush_kernel_vmap_ran
  * Probe Octeon's caches
  *
  */
-static void __cpuinit probe_octeon(void)
+static void probe_octeon(void)
 {
 	unsigned long icache_size;
 	unsigned long dcache_size;
@@ -251,7 +251,7 @@ static void __cpuinit probe_octeon(void)
 	}
 }
 
-static void  __cpuinit octeon_cache_error_setup(void)
+static void  octeon_cache_error_setup(void)
 {
 	extern char except_vec2_octeon;
 	set_handler(0x100, &except_vec2_octeon, 0x80);
@@ -261,7 +261,7 @@ static void  __cpuinit octeon_cache_erro
  * Setup the Octeon cache flush routines
  *
  */
-void __cpuinit octeon_cache_init(void)
+void octeon_cache_init(void)
 {
 	probe_octeon();
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/c-r3k.c linux-libre-3.11-rc7-gnu/arch/mips/mm/c-r3k.c
--- linux-libre-3.10-gnu/arch/mips/mm/c-r3k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/c-r3k.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,7 @@
 static unsigned long icache_size, dcache_size;		/* Size in bytes */
 static unsigned long icache_lsize, dcache_lsize;	/* Size in bytes */
 
-unsigned long __cpuinit r3k_cache_size(unsigned long ca_flags)
+unsigned long r3k_cache_size(unsigned long ca_flags)
 {
 	unsigned long flags, status, dummy, size;
 	volatile unsigned long *p;
@@ -61,7 +61,7 @@ unsigned long __cpuinit r3k_cache_size(u
 	return size * sizeof(*p);
 }
 
-unsigned long __cpuinit r3k_cache_lsize(unsigned long ca_flags)
+unsigned long r3k_cache_lsize(unsigned long ca_flags)
 {
 	unsigned long flags, status, lsize, i;
 	volatile unsigned long *p;
@@ -90,7 +90,7 @@ unsigned long __cpuinit r3k_cache_lsize(
 	return lsize * sizeof(*p);
 }
 
-static void __cpuinit r3k_probe_cache(void)
+static void r3k_probe_cache(void)
 {
 	dcache_size = r3k_cache_size(ST0_ISC);
 	if (dcache_size)
@@ -312,7 +312,7 @@ static void r3k_dma_cache_wback_inv(unsi
 	r3k_flush_dcache_range(start, start + size);
 }
 
-void __cpuinit r3k_cache_init(void)
+void r3k_cache_init(void)
 {
 	extern void build_clear_page(void);
 	extern void build_copy_page(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/c-r4k.c linux-libre-3.11-rc7-gnu/arch/mips/mm/c-r4k.c
--- linux-libre-3.10-gnu/arch/mips/mm/c-r4k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/c-r4k.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,7 +107,7 @@ static inline void r4k_blast_dcache_page
 	blast_dcache64_page(addr);
 }
 
-static void __cpuinit r4k_blast_dcache_page_setup(void)
+static void r4k_blast_dcache_page_setup(void)
 {
 	unsigned long  dc_lsize = cpu_dcache_line_size();
 
@@ -123,7 +123,7 @@ static void __cpuinit r4k_blast_dcache_p
 
 static void (* r4k_blast_dcache_page_indexed)(unsigned long addr);
 
-static void __cpuinit r4k_blast_dcache_page_indexed_setup(void)
+static void r4k_blast_dcache_page_indexed_setup(void)
 {
 	unsigned long dc_lsize = cpu_dcache_line_size();
 
@@ -140,7 +140,7 @@ static void __cpuinit r4k_blast_dcache_p
 void (* r4k_blast_dcache)(void);
 EXPORT_SYMBOL(r4k_blast_dcache);
 
-static void __cpuinit r4k_blast_dcache_setup(void)
+static void r4k_blast_dcache_setup(void)
 {
 	unsigned long dc_lsize = cpu_dcache_line_size();
 
@@ -227,7 +227,7 @@ static inline void tx49_blast_icache32_p
 
 static void (* r4k_blast_icache_page)(unsigned long addr);
 
-static void __cpuinit r4k_blast_icache_page_setup(void)
+static void r4k_blast_icache_page_setup(void)
 {
 	unsigned long ic_lsize = cpu_icache_line_size();
 
@@ -244,7 +244,7 @@ static void __cpuinit r4k_blast_icache_p
 
 static void (* r4k_blast_icache_page_indexed)(unsigned long addr);
 
-static void __cpuinit r4k_blast_icache_page_indexed_setup(void)
+static void r4k_blast_icache_page_indexed_setup(void)
 {
 	unsigned long ic_lsize = cpu_icache_line_size();
 
@@ -269,7 +269,7 @@ static void __cpuinit r4k_blast_icache_p
 void (* r4k_blast_icache)(void);
 EXPORT_SYMBOL(r4k_blast_icache);
 
-static void __cpuinit r4k_blast_icache_setup(void)
+static void r4k_blast_icache_setup(void)
 {
 	unsigned long ic_lsize = cpu_icache_line_size();
 
@@ -290,7 +290,7 @@ static void __cpuinit r4k_blast_icache_s
 
 static void (* r4k_blast_scache_page)(unsigned long addr);
 
-static void __cpuinit r4k_blast_scache_page_setup(void)
+static void r4k_blast_scache_page_setup(void)
 {
 	unsigned long sc_lsize = cpu_scache_line_size();
 
@@ -308,7 +308,7 @@ static void __cpuinit r4k_blast_scache_p
 
 static void (* r4k_blast_scache_page_indexed)(unsigned long addr);
 
-static void __cpuinit r4k_blast_scache_page_indexed_setup(void)
+static void r4k_blast_scache_page_indexed_setup(void)
 {
 	unsigned long sc_lsize = cpu_scache_line_size();
 
@@ -326,7 +326,7 @@ static void __cpuinit r4k_blast_scache_p
 
 static void (* r4k_blast_scache)(void);
 
-static void __cpuinit r4k_blast_scache_setup(void)
+static void r4k_blast_scache_setup(void)
 {
 	unsigned long sc_lsize = cpu_scache_line_size();
 
@@ -797,11 +797,11 @@ static inline void alias_74k_erratum(str
 	}
 }
 
-static char *way_string[] __cpuinitdata = { NULL, "direct mapped", "2-way",
+static char *way_string[] = { NULL, "direct mapped", "2-way",
 	"3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
 };
 
-static void __cpuinit probe_pcache(void)
+static void probe_pcache(void)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
 	unsigned int config = read_c0_config();
@@ -1119,7 +1119,7 @@ static void __cpuinit probe_pcache(void)
  * executes in KSEG1 space or else you will crash and burn badly.  You have
  * been warned.
  */
-static int __cpuinit probe_scache(void)
+static int probe_scache(void)
 {
 	unsigned long flags, addr, begin, end, pow2;
 	unsigned int config = read_c0_config();
@@ -1196,7 +1196,7 @@ extern int r5k_sc_init(void);
 extern int rm7k_sc_init(void);
 extern int mips_sc_init(void);
 
-static void __cpuinit setup_scache(void)
+static void setup_scache(void)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
 	unsigned int config = read_c0_config();
@@ -1329,7 +1329,7 @@ static void nxp_pr4450_fixup_config(void
 	NXP_BARRIER();
 }
 
-static int __cpuinitdata cca = -1;
+static int cca = -1;
 
 static int __init cca_setup(char *str)
 {
@@ -1340,7 +1340,7 @@ static int __init cca_setup(char *str)
 
 early_param("cca", cca_setup);
 
-static void __cpuinit coherency_setup(void)
+static void coherency_setup(void)
 {
 	if (cca < 0 || cca > 7)
 		cca = read_c0_config() & CONF_CM_CMASK;
@@ -1380,7 +1380,7 @@ static void __cpuinit coherency_setup(vo
 	}
 }
 
-static void __cpuinit r4k_cache_error_setup(void)
+static void r4k_cache_error_setup(void)
 {
 	extern char __weak except_vec2_generic;
 	extern char __weak except_vec2_sb1;
@@ -1398,7 +1398,7 @@ static void __cpuinit r4k_cache_error_se
 	}
 }
 
-void __cpuinit r4k_cache_init(void)
+void r4k_cache_init(void)
 {
 	extern void build_clear_page(void);
 	extern void build_copy_page(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/c-tx39.c linux-libre-3.11-rc7-gnu/arch/mips/mm/c-tx39.c
--- linux-libre-3.10-gnu/arch/mips/mm/c-tx39.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/c-tx39.c	2013-08-25 20:43:22.000000000 -0400
@@ -344,7 +344,7 @@ static __init void tx39_probe_cache(void
 	}
 }
 
-void __cpuinit tx39_cache_init(void)
+void tx39_cache_init(void)
 {
 	extern void build_clear_page(void);
 	extern void build_copy_page(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/dma-default.c linux-libre-3.11-rc7-gnu/arch/mips/mm/dma-default.c
--- linux-libre-3.10-gnu/arch/mips/mm/dma-default.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/dma-default.c	2013-08-25 20:43:22.000000000 -0400
@@ -246,6 +246,9 @@ static int mips_dma_map_sg(struct device
 		if (!plat_device_is_coherent(dev))
 			__dma_sync(sg_page(sg), sg->offset, sg->length,
 				   direction);
+#ifdef CONFIG_NEED_SG_DMA_LENGTH
+		sg->dma_length = sg->length;
+#endif
 		sg->dma_address = plat_map_dma_mem_page(dev, sg_page(sg)) +
 				  sg->offset;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/fault.c linux-libre-3.11-rc7-gnu/arch/mips/mm/fault.c
--- linux-libre-3.10-gnu/arch/mips/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1995 - 2000 by Ralf Baechle
  */
+#include <linux/context_tracking.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
@@ -32,8 +33,8 @@
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  */
-asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long write,
-			      unsigned long address)
+static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
+	unsigned long address)
 {
 	struct vm_area_struct * vma = NULL;
 	struct task_struct *tsk = current;
@@ -312,3 +313,13 @@ vmalloc_fault:
 	}
 #endif
 }
+
+asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
+	unsigned long write, unsigned long address)
+{
+	enum ctx_state prev_state;
+
+	prev_state = exception_enter();
+	__do_page_fault(regs, write, address);
+	exception_exit(prev_state);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/init.c linux-libre-3.11-rc7-gnu/arch/mips/mm/init.c
--- linux-libre-3.10-gnu/arch/mips/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -359,11 +359,24 @@ void __init paging_init(void)
 static struct kcore_list kcore_kseg0;
 #endif
 
-void __init mem_init(void)
+static inline void mem_init_free_highmem(void)
 {
-	unsigned long codesize, reservedpages, datasize, initsize;
-	unsigned long tmp, ram;
+#ifdef CONFIG_HIGHMEM
+	unsigned long tmp;
+
+	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
+		struct page *page = pfn_to_page(tmp);
 
+		if (!page_is_ram(tmp))
+			SetPageReserved(page);
+		else
+			free_highmem_page(page);
+	}
+#endif
+}
+
+void __init mem_init(void)
+{
 #ifdef CONFIG_HIGHMEM
 #ifdef CONFIG_DISCONTIGMEM
 #error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
@@ -374,34 +387,10 @@ void __init mem_init(void)
 #endif
 	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 
-	totalram_pages += free_all_bootmem();
+	free_all_bootmem();
 	setup_zero_pages();	/* Setup zeroed pages.  */
-
-	reservedpages = ram = 0;
-	for (tmp = 0; tmp < max_low_pfn; tmp++)
-		if (page_is_ram(tmp) && pfn_valid(tmp)) {
-			ram++;
-			if (PageReserved(pfn_to_page(tmp)))
-				reservedpages++;
-		}
-	num_physpages = ram;
-
-#ifdef CONFIG_HIGHMEM
-	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
-		struct page *page = pfn_to_page(tmp);
-
-		if (!page_is_ram(tmp)) {
-			SetPageReserved(page);
-			continue;
-		}
-		free_highmem_page(page);
-	}
-	num_physpages += totalhigh_pages;
-#endif
-
-	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+	mem_init_free_highmem();
+	mem_init_print_info(NULL);
 
 #ifdef CONFIG_64BIT
 	if ((unsigned long) &_text > (unsigned long) CKSEG0)
@@ -410,16 +399,6 @@ void __init mem_init(void)
 		kclist_add(&kcore_kseg0, (void *) CKSEG0,
 				0x80000000 - 4, KCORE_TEXT);
 #endif
-
-	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
-	       "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
-	       nr_free_pages() << (PAGE_SHIFT-10),
-	       ram << (PAGE_SHIFT-10),
-	       codesize >> 10,
-	       reservedpages << (PAGE_SHIFT-10),
-	       datasize >> 10,
-	       initsize >> 10,
-	       totalhigh_pages << (PAGE_SHIFT-10));
 }
 #endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
@@ -440,7 +419,8 @@ void free_init_pages(const char *what, u
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd");
+	free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
+			   "initrd");
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/Makefile linux-libre-3.11-rc7-gnu/arch/mips/mm/Makefile
--- linux-libre-3.10-gnu/arch/mips/mm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,7 @@
 
 obj-y				+= cache.o dma-default.o extable.o fault.o \
 				   gup.o init.o mmap.o page.o page-funcs.o \
-				   tlbex.o tlbex-fault.o uasm-mips.o
+				   tlbex.o tlbex-fault.o tlb-funcs.o uasm-mips.o
 
 obj-$(CONFIG_32BIT)		+= ioremap.o pgtable-32.o
 obj-$(CONFIG_64BIT)		+= pgtable-64.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/mmap.c linux-libre-3.11-rc7-gnu/arch/mips/mm/mmap.c
--- linux-libre-3.10-gnu/arch/mips/mm/mmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/mmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -158,11 +158,9 @@ void arch_pick_mmap_layout(struct mm_str
 	if (mmap_is_legacy()) {
 		mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
 		mm->get_unmapped_area = arch_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
 	} else {
 		mm->mmap_base = mmap_base(random_factor);
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/page.c linux-libre-3.11-rc7-gnu/arch/mips/mm/page.c
--- linux-libre-3.10-gnu/arch/mips/mm/page.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/page.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,29 +66,29 @@ UASM_L_LA(_copy_pref_both)
 UASM_L_LA(_copy_pref_store)
 
 /* We need one branch and therefore one relocation per target label. */
-static struct uasm_label __cpuinitdata labels[5];
-static struct uasm_reloc __cpuinitdata relocs[5];
+static struct uasm_label labels[5];
+static struct uasm_reloc relocs[5];
 
 #define cpu_is_r4600_v1_x()	((read_c0_prid() & 0xfffffff0) == 0x00002010)
 #define cpu_is_r4600_v2_x()	((read_c0_prid() & 0xfffffff0) == 0x00002020)
 
-static int pref_bias_clear_store __cpuinitdata;
-static int pref_bias_copy_load __cpuinitdata;
-static int pref_bias_copy_store __cpuinitdata;
+static int pref_bias_clear_store;
+static int pref_bias_copy_load;
+static int pref_bias_copy_store;
 
-static u32 pref_src_mode __cpuinitdata;
-static u32 pref_dst_mode __cpuinitdata;
+static u32 pref_src_mode;
+static u32 pref_dst_mode;
 
-static int clear_word_size __cpuinitdata;
-static int copy_word_size __cpuinitdata;
+static int clear_word_size;
+static int copy_word_size;
 
-static int half_clear_loop_size __cpuinitdata;
-static int half_copy_loop_size __cpuinitdata;
+static int half_clear_loop_size;
+static int half_copy_loop_size;
 
-static int cache_line_size __cpuinitdata;
+static int cache_line_size;
 #define cache_line_mask() (cache_line_size - 1)
 
-static inline void __cpuinit
+static inline void
 pg_addiu(u32 **buf, unsigned int reg1, unsigned int reg2, unsigned int off)
 {
 	if (cpu_has_64bit_gp_regs && DADDI_WAR && r4k_daddiu_bug()) {
@@ -108,7 +108,7 @@ pg_addiu(u32 **buf, unsigned int reg1, u
 	}
 }
 
-static void __cpuinit set_prefetch_parameters(void)
+static void set_prefetch_parameters(void)
 {
 	if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg)
 		clear_word_size = 8;
@@ -199,7 +199,7 @@ static void __cpuinit set_prefetch_param
 				      4 * copy_word_size));
 }
 
-static void __cpuinit build_clear_store(u32 **buf, int off)
+static void build_clear_store(u32 **buf, int off)
 {
 	if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg) {
 		uasm_i_sd(buf, ZERO, off, A0);
@@ -208,7 +208,7 @@ static void __cpuinit build_clear_store(
 	}
 }
 
-static inline void __cpuinit build_clear_pref(u32 **buf, int off)
+static inline void build_clear_pref(u32 **buf, int off)
 {
 	if (off & cache_line_mask())
 		return;
@@ -232,7 +232,7 @@ static inline void __cpuinit build_clear
 
 			uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0);
 		}
-		}
+	}
 }
 
 extern u32 __clear_page_start;
@@ -240,7 +240,7 @@ extern u32 __clear_page_end;
 extern u32 __copy_page_start;
 extern u32 __copy_page_end;
 
-void __cpuinit build_clear_page(void)
+void build_clear_page(void)
 {
 	int off;
 	u32 *buf = &__clear_page_start;
@@ -333,7 +333,7 @@ void __cpuinit build_clear_page(void)
 	pr_debug("\t.set pop\n");
 }
 
-static void __cpuinit build_copy_load(u32 **buf, int reg, int off)
+static void build_copy_load(u32 **buf, int reg, int off)
 {
 	if (cpu_has_64bit_gp_regs) {
 		uasm_i_ld(buf, reg, off, A1);
@@ -342,7 +342,7 @@ static void __cpuinit build_copy_load(u3
 	}
 }
 
-static void __cpuinit build_copy_store(u32 **buf, int reg, int off)
+static void build_copy_store(u32 **buf, int reg, int off)
 {
 	if (cpu_has_64bit_gp_regs) {
 		uasm_i_sd(buf, reg, off, A0);
@@ -387,7 +387,7 @@ static inline void build_copy_store_pref
 	}
 }
 
-void __cpuinit build_copy_page(void)
+void build_copy_page(void)
 {
 	int off;
 	u32 *buf = &__copy_page_start;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/sc-ip22.c linux-libre-3.11-rc7-gnu/arch/mips/mm/sc-ip22.c
--- linux-libre-3.10-gnu/arch/mips/mm/sc-ip22.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/sc-ip22.c	2013-08-25 20:43:22.000000000 -0400
@@ -167,7 +167,7 @@ static struct bcache_ops indy_sc_ops = {
 	.bc_inv = indy_sc_wback_invalidate
 };
 
-void __cpuinit indy_sc_init(void)
+void indy_sc_init(void)
 {
 	if (indy_sc_probe()) {
 		indy_sc_enable();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/sc-mips.c linux-libre-3.11-rc7-gnu/arch/mips/mm/sc-mips.c
--- linux-libre-3.10-gnu/arch/mips/mm/sc-mips.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/sc-mips.c	2013-08-25 20:43:22.000000000 -0400
@@ -132,7 +132,7 @@ static inline int __init mips_sc_probe(v
 	return 1;
 }
 
-int __cpuinit mips_sc_init(void)
+int mips_sc_init(void)
 {
 	int found = mips_sc_probe();
 	if (found) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/sc-r5k.c linux-libre-3.11-rc7-gnu/arch/mips/mm/sc-r5k.c
--- linux-libre-3.10-gnu/arch/mips/mm/sc-r5k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/sc-r5k.c	2013-08-25 20:43:22.000000000 -0400
@@ -98,7 +98,7 @@ static struct bcache_ops r5k_sc_ops = {
 	.bc_inv = r5k_dma_cache_inv_sc
 };
 
-void __cpuinit r5k_sc_init(void)
+void r5k_sc_init(void)
 {
 	if (r5k_sc_probe()) {
 		r5k_sc_enable();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/sc-rm7k.c linux-libre-3.11-rc7-gnu/arch/mips/mm/sc-rm7k.c
--- linux-libre-3.10-gnu/arch/mips/mm/sc-rm7k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/sc-rm7k.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,7 +104,7 @@ static void blast_rm7k_tcache(void)
 /*
  * This function is executed in uncached address space.
  */
-static __cpuinit void __rm7k_tc_enable(void)
+static void __rm7k_tc_enable(void)
 {
 	int i;
 
@@ -117,7 +117,7 @@ static __cpuinit void __rm7k_tc_enable(v
 		cache_op(Index_Store_Tag_T, CKSEG0ADDR(i));
 }
 
-static __cpuinit void rm7k_tc_enable(void)
+static void rm7k_tc_enable(void)
 {
 	if (read_c0_config() & RM7K_CONF_TE)
 		return;
@@ -130,7 +130,7 @@ static __cpuinit void rm7k_tc_enable(voi
 /*
  * This function is executed in uncached address space.
  */
-static __cpuinit void __rm7k_sc_enable(void)
+static void __rm7k_sc_enable(void)
 {
 	int i;
 
@@ -143,7 +143,7 @@ static __cpuinit void __rm7k_sc_enable(v
 		cache_op(Index_Store_Tag_SD, CKSEG0ADDR(i));
 }
 
-static __cpuinit void rm7k_sc_enable(void)
+static void rm7k_sc_enable(void)
 {
 	if (read_c0_config() & RM7K_CONF_SE)
 		return;
@@ -184,7 +184,7 @@ static struct bcache_ops rm7k_sc_ops = {
  * This is a probing function like the one found in c-r4k.c, we look for the
  * wrap around point with different addresses.
  */
-static __cpuinit void __probe_tcache(void)
+static void __probe_tcache(void)
 {
 	unsigned long flags, addr, begin, end, pow2;
 
@@ -226,7 +226,7 @@ static __cpuinit void __probe_tcache(voi
 	local_irq_restore(flags);
 }
 
-void __cpuinit rm7k_sc_init(void)
+void rm7k_sc_init(void)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
 	unsigned int config = read_c0_config();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/tlbex.c linux-libre-3.11-rc7-gnu/arch/mips/mm/tlbex.c
--- linux-libre-3.10-gnu/arch/mips/mm/tlbex.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/tlbex.c	2013-08-25 20:43:22.000000000 -0400
@@ -136,7 +136,7 @@ static int scratchpad_offset(int i)
  * why; it's not an issue caused by the core RTL.
  *
  */
-static int __cpuinit m4kc_tlbp_war(void)
+static int m4kc_tlbp_war(void)
 {
 	return (current_cpu_data.processor_id & 0xffff00) ==
 	       (PRID_COMP_MIPS | PRID_IMP_4KC);
@@ -181,11 +181,9 @@ UASM_L_LA(_large_segbits_fault)
 UASM_L_LA(_tlb_huge_update)
 #endif
 
-static int __cpuinitdata hazard_instance;
+static int hazard_instance;
 
-static void __cpuinit uasm_bgezl_hazard(u32 **p,
-					struct uasm_reloc **r,
-					int instance)
+static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance)
 {
 	switch (instance) {
 	case 0 ... 7:
@@ -196,9 +194,7 @@ static void __cpuinit uasm_bgezl_hazard(
 	}
 }
 
-static void __cpuinit uasm_bgezl_label(struct uasm_label **l,
-				       u32 **p,
-				       int instance)
+static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance)
 {
 	switch (instance) {
 	case 0 ... 7:
@@ -295,17 +291,28 @@ static inline void dump_handler(const ch
  * We deliberately chose a buffer size of 128, so we won't scribble
  * over anything important on overflow before we panic.
  */
-static u32 tlb_handler[128] __cpuinitdata;
+static u32 tlb_handler[128];
 
 /* simply assume worst case size for labels and relocs */
-static struct uasm_label labels[128] __cpuinitdata;
-static struct uasm_reloc relocs[128] __cpuinitdata;
+static struct uasm_label labels[128];
+static struct uasm_reloc relocs[128];
 
-static int check_for_high_segbits __cpuinitdata;
+static int check_for_high_segbits;
 
-static unsigned int kscratch_used_mask __cpuinitdata;
+static unsigned int kscratch_used_mask;
 
-static int __cpuinit allocate_kscratch(void)
+static inline int __maybe_unused c0_kscratch(void)
+{
+	switch (current_cpu_type()) {
+	case CPU_XLP:
+	case CPU_XLR:
+		return 22;
+	default:
+		return 31;
+	}
+}
+
+static int allocate_kscratch(void)
 {
 	int r;
 	unsigned int a = cpu_data[0].kscratch_mask & ~kscratch_used_mask;
@@ -322,11 +329,11 @@ static int __cpuinit allocate_kscratch(v
 	return r;
 }
 
-static int scratch_reg __cpuinitdata;
-static int pgd_reg __cpuinitdata;
+static int scratch_reg;
+static int pgd_reg;
 enum vmalloc64_mode {not_refill, refill_scratch, refill_noscratch};
 
-static struct work_registers __cpuinit build_get_work_registers(u32 **p)
+static struct work_registers build_get_work_registers(u32 **p)
 {
 	struct work_registers r;
 
@@ -334,9 +341,9 @@ static struct work_registers __cpuinit b
 	int smp_processor_id_sel;
 	int smp_processor_id_shift;
 
-	if (scratch_reg > 0) {
+	if (scratch_reg >= 0) {
 		/* Save in CPU local C0_KScratch? */
-		UASM_i_MTC0(p, 1, 31, scratch_reg);
+		UASM_i_MTC0(p, 1, c0_kscratch(), scratch_reg);
 		r.r1 = K0;
 		r.r2 = K1;
 		r.r3 = 1;
@@ -382,10 +389,10 @@ static struct work_registers __cpuinit b
 	return r;
 }
 
-static void __cpuinit build_restore_work_registers(u32 **p)
+static void build_restore_work_registers(u32 **p)
 {
-	if (scratch_reg > 0) {
-		UASM_i_MFC0(p, 1, 31, scratch_reg);
+	if (scratch_reg >= 0) {
+		UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
 		return;
 	}
 	/* K0 already points to save area, restore $1 and $2  */
@@ -407,7 +414,7 @@ extern unsigned long pgd_current[];
 /*
  * The R3000 TLB handler is simple.
  */
-static void __cpuinit build_r3000_tlb_refill_handler(void)
+static void build_r3000_tlb_refill_handler(void)
 {
 	long pgdc = (long)pgd_current;
 	u32 *p;
@@ -452,7 +459,7 @@ static void __cpuinit build_r3000_tlb_re
  * other one.To keep things simple, we first assume linear space,
  * then we relocate it to the final handler layout as needed.
  */
-static u32 final_handler[64] __cpuinitdata;
+static u32 final_handler[64];
 
 /*
  * Hazards
@@ -476,7 +483,7 @@ static u32 final_handler[64] __cpuinitda
  *
  * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
  */
-static void __cpuinit __maybe_unused build_tlb_probe_entry(u32 **p)
+static void __maybe_unused build_tlb_probe_entry(u32 **p)
 {
 	switch (current_cpu_type()) {
 	/* Found by experiment: R4600 v2.0/R4700 needs this, too.  */
@@ -500,9 +507,9 @@ static void __cpuinit __maybe_unused bui
  */
 enum tlb_write_entry { tlb_random, tlb_indexed };
 
-static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
-					 struct uasm_reloc **r,
-					 enum tlb_write_entry wmode)
+static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
+				  struct uasm_reloc **r,
+				  enum tlb_write_entry wmode)
 {
 	void(*tlbw)(u32 **) = NULL;
 
@@ -636,8 +643,8 @@ static void __cpuinit build_tlb_write_en
 	}
 }
 
-static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
-								  unsigned int reg)
+static __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
+							unsigned int reg)
 {
 	if (cpu_has_rixi) {
 		UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
@@ -652,11 +659,9 @@ static __cpuinit __maybe_unused void bui
 
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 
-static __cpuinit void build_restore_pagemask(u32 **p,
-					     struct uasm_reloc **r,
-					     unsigned int tmp,
-					     enum label_id lid,
-					     int restore_scratch)
+static void build_restore_pagemask(u32 **p, struct uasm_reloc **r,
+				   unsigned int tmp, enum label_id lid,
+				   int restore_scratch)
 {
 	if (restore_scratch) {
 		/* Reset default page size */
@@ -673,8 +678,8 @@ static __cpuinit void build_restore_page
 			uasm_i_mtc0(p, 0, C0_PAGEMASK);
 			uasm_il_b(p, r, lid);
 		}
-		if (scratch_reg > 0)
-			UASM_i_MFC0(p, 1, 31, scratch_reg);
+		if (scratch_reg >= 0)
+			UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
 		else
 			UASM_i_LW(p, 1, scratchpad_offset(0), 0);
 	} else {
@@ -695,12 +700,11 @@ static __cpuinit void build_restore_page
 	}
 }
 
-static __cpuinit void build_huge_tlb_write_entry(u32 **p,
-						 struct uasm_label **l,
-						 struct uasm_reloc **r,
-						 unsigned int tmp,
-						 enum tlb_write_entry wmode,
-						 int restore_scratch)
+static void build_huge_tlb_write_entry(u32 **p, struct uasm_label **l,
+				       struct uasm_reloc **r,
+				       unsigned int tmp,
+				       enum tlb_write_entry wmode,
+				       int restore_scratch)
 {
 	/* Set huge page tlb entry size */
 	uasm_i_lui(p, tmp, PM_HUGE_MASK >> 16);
@@ -715,9 +719,9 @@ static __cpuinit void build_huge_tlb_wri
 /*
  * Check if Huge PTE is present, if so then jump to LABEL.
  */
-static void __cpuinit
+static void
 build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int tmp,
-		unsigned int pmd, int lid)
+		  unsigned int pmd, int lid)
 {
 	UASM_i_LW(p, tmp, 0, pmd);
 	if (use_bbit_insns()) {
@@ -728,9 +732,8 @@ build_is_huge_pte(u32 **p, struct uasm_r
 	}
 }
 
-static __cpuinit void build_huge_update_entries(u32 **p,
-						unsigned int pte,
-						unsigned int tmp)
+static void build_huge_update_entries(u32 **p, unsigned int pte,
+				      unsigned int tmp)
 {
 	int small_sequence;
 
@@ -760,11 +763,10 @@ static __cpuinit void build_huge_update_
 	UASM_i_MTC0(p, pte, C0_ENTRYLO1); /* load it */
 }
 
-static __cpuinit void build_huge_handler_tail(u32 **p,
-					      struct uasm_reloc **r,
-					      struct uasm_label **l,
-					      unsigned int pte,
-					      unsigned int ptr)
+static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r,
+				    struct uasm_label **l,
+				    unsigned int pte,
+				    unsigned int ptr)
 {
 #ifdef CONFIG_SMP
 	UASM_i_SC(p, pte, 0, ptr);
@@ -783,7 +785,7 @@ static __cpuinit void build_huge_handler
  * TMP and PTR are scratch.
  * TMP will be clobbered, PTR will hold the pmd entry.
  */
-static void __cpuinit
+static void
 build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 		 unsigned int tmp, unsigned int ptr)
 {
@@ -817,7 +819,7 @@ build_get_pmde64(u32 **p, struct uasm_la
 #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
 	if (pgd_reg != -1) {
 		/* pgd is in pgd_reg */
-		UASM_i_MFC0(p, ptr, 31, pgd_reg);
+		UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
 	} else {
 		/*
 		 * &pgd << 11 stored in CONTEXT [23..63].
@@ -875,7 +877,7 @@ build_get_pmde64(u32 **p, struct uasm_la
  * BVADDR is the faulting address, PTR is scratch.
  * PTR will hold the pgd for vmalloc.
  */
-static void __cpuinit
+static void
 build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 			unsigned int bvaddr, unsigned int ptr,
 			enum vmalloc64_mode mode)
@@ -929,8 +931,8 @@ build_get_pgd_vmalloc64(u32 **p, struct
 		uasm_i_jr(p, ptr);
 
 		if (mode == refill_scratch) {
-			if (scratch_reg > 0)
-				UASM_i_MFC0(p, 1, 31, scratch_reg);
+			if (scratch_reg >= 0)
+				UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
 			else
 				UASM_i_LW(p, 1, scratchpad_offset(0), 0);
 		} else {
@@ -945,7 +947,7 @@ build_get_pgd_vmalloc64(u32 **p, struct
  * TMP and PTR are scratch.
  * TMP will be clobbered, PTR will hold the pgd entry.
  */
-static void __cpuinit __maybe_unused
+static void __maybe_unused
 build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
 {
 	long pgdc = (long)pgd_current;
@@ -961,7 +963,7 @@ build_get_pgde32(u32 **p, unsigned int t
 	uasm_i_srl(p, ptr, ptr, 19);
 #else
 	/*
-	 * smp_processor_id() << 3 is stored in CONTEXT.
+	 * smp_processor_id() << 2 is stored in CONTEXT.
 	 */
 	uasm_i_mfc0(p, ptr, C0_CONTEXT);
 	UASM_i_LA_mostly(p, tmp, pgdc);
@@ -980,7 +982,7 @@ build_get_pgde32(u32 **p, unsigned int t
 
 #endif /* !CONFIG_64BIT */
 
-static void __cpuinit build_adjust_context(u32 **p, unsigned int ctx)
+static void build_adjust_context(u32 **p, unsigned int ctx)
 {
 	unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12;
 	unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
@@ -1006,7 +1008,7 @@ static void __cpuinit build_adjust_conte
 	uasm_i_andi(p, ctx, ctx, mask);
 }
 
-static void __cpuinit build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
+static void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
 {
 	/*
 	 * Bug workaround for the Nevada. It seems as if under certain
@@ -1031,8 +1033,7 @@ static void __cpuinit build_get_ptep(u32
 	UASM_i_ADDU(p, ptr, ptr, tmp); /* add in offset */
 }
 
-static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
-					unsigned int ptep)
+static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
 {
 	/*
 	 * 64bit address support (36bit on a 32bit CPU) in a 32bit
@@ -1093,10 +1094,10 @@ struct mips_huge_tlb_info {
 	int restore_scratch;
 };
 
-static struct mips_huge_tlb_info __cpuinit
+static struct mips_huge_tlb_info
 build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
 			       struct uasm_reloc **r, unsigned int tmp,
-			       unsigned int ptr, int c0_scratch)
+			       unsigned int ptr, int c0_scratch_reg)
 {
 	struct mips_huge_tlb_info rv;
 	unsigned int even, odd;
@@ -1110,12 +1111,12 @@ build_fast_tlb_refill_handler (u32 **p,
 		UASM_i_MFC0(p, tmp, C0_BADVADDR);
 
 		if (pgd_reg != -1)
-			UASM_i_MFC0(p, ptr, 31, pgd_reg);
+			UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
 		else
 			UASM_i_MFC0(p, ptr, C0_CONTEXT);
 
-		if (c0_scratch >= 0)
-			UASM_i_MTC0(p, scratch, 31, c0_scratch);
+		if (c0_scratch_reg >= 0)
+			UASM_i_MTC0(p, scratch, c0_kscratch(), c0_scratch_reg);
 		else
 			UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
 
@@ -1130,14 +1131,14 @@ build_fast_tlb_refill_handler (u32 **p,
 		}
 	} else {
 		if (pgd_reg != -1)
-			UASM_i_MFC0(p, ptr, 31, pgd_reg);
+			UASM_i_MFC0(p, ptr, c0_kscratch(), pgd_reg);
 		else
 			UASM_i_MFC0(p, ptr, C0_CONTEXT);
 
 		UASM_i_MFC0(p, tmp, C0_BADVADDR);
 
-		if (c0_scratch >= 0)
-			UASM_i_MTC0(p, scratch, 31, c0_scratch);
+		if (c0_scratch_reg >= 0)
+			UASM_i_MTC0(p, scratch, c0_kscratch(), c0_scratch_reg);
 		else
 			UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
 
@@ -1242,8 +1243,8 @@ build_fast_tlb_refill_handler (u32 **p,
 	}
 	UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */
 
-	if (c0_scratch >= 0) {
-		UASM_i_MFC0(p, scratch, 31, c0_scratch);
+	if (c0_scratch_reg >= 0) {
+		UASM_i_MFC0(p, scratch, c0_kscratch(), c0_scratch_reg);
 		build_tlb_write_entry(p, l, r, tlb_random);
 		uasm_l_leave(l, *p);
 		rv.restore_scratch = 1;
@@ -1271,7 +1272,7 @@ build_fast_tlb_refill_handler (u32 **p,
  */
 #define MIPS64_REFILL_INSNS 32
 
-static void __cpuinit build_r4000_tlb_refill_handler(void)
+static void build_r4000_tlb_refill_handler(void)
 {
 	u32 *p = tlb_handler;
 	struct uasm_label *l = labels;
@@ -1286,7 +1287,7 @@ static void __cpuinit build_r4000_tlb_re
 	memset(relocs, 0, sizeof(relocs));
 	memset(final_handler, 0, sizeof(final_handler));
 
-	if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) {
+	if ((scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
 		htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
 							  scratch_reg);
 		vmalloc_mode = refill_scratch;
@@ -1444,27 +1445,25 @@ static void __cpuinit build_r4000_tlb_re
 	dump_handler("r4000_tlb_refill", (u32 *)ebase, 64);
 }
 
-/*
- * 128 instructions for the fastpath handler is generous and should
- * never be exceeded.
- */
-#define FASTPATH_SIZE 128
+extern u32 handle_tlbl[], handle_tlbl_end[];
+extern u32 handle_tlbs[], handle_tlbs_end[];
+extern u32 handle_tlbm[], handle_tlbm_end[];
 
-u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
-u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
-u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
 #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
-u32 tlbmiss_handler_setup_pgd_array[16] __cacheline_aligned;
+extern u32 tlbmiss_handler_setup_pgd[], tlbmiss_handler_setup_pgd_end[];
 
-static void __cpuinit build_r4000_setup_pgd(void)
+static void build_r4000_setup_pgd(void)
 {
 	const int a0 = 4;
 	const int a1 = 5;
-	u32 *p = tlbmiss_handler_setup_pgd_array;
+	u32 *p = tlbmiss_handler_setup_pgd;
+	const int tlbmiss_handler_setup_pgd_size =
+		tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd;
 	struct uasm_label *l = labels;
 	struct uasm_reloc *r = relocs;
 
-	memset(tlbmiss_handler_setup_pgd_array, 0, sizeof(tlbmiss_handler_setup_pgd_array));
+	memset(tlbmiss_handler_setup_pgd, 0, tlbmiss_handler_setup_pgd_size *
+					sizeof(tlbmiss_handler_setup_pgd[0]));
 	memset(labels, 0, sizeof(labels));
 	memset(relocs, 0, sizeof(relocs));
 
@@ -1490,21 +1489,21 @@ static void __cpuinit build_r4000_setup_
 	} else {
 		/* PGD in c0_KScratch */
 		uasm_i_jr(&p, 31);
-		UASM_i_MTC0(&p, a0, 31, pgd_reg);
+		UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg);
 	}
-	if (p - tlbmiss_handler_setup_pgd_array > ARRAY_SIZE(tlbmiss_handler_setup_pgd_array))
-		panic("tlbmiss_handler_setup_pgd_array space exceeded");
+	if (p >= tlbmiss_handler_setup_pgd_end)
+		panic("tlbmiss_handler_setup_pgd space exceeded");
+
 	uasm_resolve_relocs(relocs, labels);
-	pr_debug("Wrote tlbmiss_handler_setup_pgd_array (%u instructions).\n",
-		 (unsigned int)(p - tlbmiss_handler_setup_pgd_array));
+	pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n",
+		 (unsigned int)(p - tlbmiss_handler_setup_pgd));
 
-	dump_handler("tlbmiss_handler",
-		     tlbmiss_handler_setup_pgd_array,
-		     ARRAY_SIZE(tlbmiss_handler_setup_pgd_array));
+	dump_handler("tlbmiss_handler", tlbmiss_handler_setup_pgd,
+					tlbmiss_handler_setup_pgd_size);
 }
 #endif
 
-static void __cpuinit
+static void
 iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
 {
 #ifdef CONFIG_SMP
@@ -1524,7 +1523,7 @@ iPTE_LW(u32 **p, unsigned int pte, unsig
 #endif
 }
 
-static void __cpuinit
+static void
 iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
 	unsigned int mode)
 {
@@ -1584,7 +1583,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r,
  * the page table where this PTE is located, PTE will be re-loaded
  * with it's original value.
  */
-static void __cpuinit
+static void
 build_pte_present(u32 **p, struct uasm_reloc **r,
 		  int pte, int ptr, int scratch, enum label_id lid)
 {
@@ -1612,7 +1611,7 @@ build_pte_present(u32 **p, struct uasm_r
 }
 
 /* Make PTE valid, store result in PTR. */
-static void __cpuinit
+static void
 build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte,
 		 unsigned int ptr)
 {
@@ -1625,7 +1624,7 @@ build_make_valid(u32 **p, struct uasm_re
  * Check if PTE can be written to, if not branch to LABEL. Regardless
  * restore PTE with value from PTR when done.
  */
-static void __cpuinit
+static void
 build_pte_writable(u32 **p, struct uasm_reloc **r,
 		   unsigned int pte, unsigned int ptr, int scratch,
 		   enum label_id lid)
@@ -1645,7 +1644,7 @@ build_pte_writable(u32 **p, struct uasm_
 /* Make PTE writable, update software status bits as well, then store
  * at PTR.
  */
-static void __cpuinit
+static void
 build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte,
 		 unsigned int ptr)
 {
@@ -1659,7 +1658,7 @@ build_make_write(u32 **p, struct uasm_re
  * Check if PTE can be modified, if not branch to LABEL. Regardless
  * restore PTE with value from PTR when done.
  */
-static void __cpuinit
+static void
 build_pte_modifiable(u32 **p, struct uasm_reloc **r,
 		     unsigned int pte, unsigned int ptr, int scratch,
 		     enum label_id lid)
@@ -1688,7 +1687,7 @@ build_pte_modifiable(u32 **p, struct uas
  * This places the pte into ENTRYLO0 and writes it with tlbwi.
  * Then it returns.
  */
-static void __cpuinit
+static void
 build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp)
 {
 	uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
@@ -1704,7 +1703,7 @@ build_r3000_pte_reload_tlbwi(u32 **p, un
  * may have the probe fail bit set as a result of a trap on a
  * kseg2 access, i.e. without refill.  Then it returns.
  */
-static void __cpuinit
+static void
 build_r3000_tlb_reload_write(u32 **p, struct uasm_label **l,
 			     struct uasm_reloc **r, unsigned int pte,
 			     unsigned int tmp)
@@ -1722,7 +1721,7 @@ build_r3000_tlb_reload_write(u32 **p, st
 	uasm_i_rfe(p); /* branch delay */
 }
 
-static void __cpuinit
+static void
 build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
 				   unsigned int ptr)
 {
@@ -1742,13 +1741,14 @@ build_r3000_tlbchange_handler_head(u32 *
 	uasm_i_tlbp(p); /* load delay */
 }
 
-static void __cpuinit build_r3000_tlb_load_handler(void)
+static void build_r3000_tlb_load_handler(void)
 {
 	u32 *p = handle_tlbl;
+	const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
 	struct uasm_label *l = labels;
 	struct uasm_reloc *r = relocs;
 
-	memset(handle_tlbl, 0, sizeof(handle_tlbl));
+	memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
 	memset(labels, 0, sizeof(labels));
 	memset(relocs, 0, sizeof(relocs));
 
@@ -1762,23 +1762,24 @@ static void __cpuinit build_r3000_tlb_lo
 	uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
 	uasm_i_nop(&p);
 
-	if ((p - handle_tlbl) > FASTPATH_SIZE)
+	if (p >= handle_tlbl_end)
 		panic("TLB load handler fastpath space exceeded");
 
 	uasm_resolve_relocs(relocs, labels);
 	pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbl));
 
-	dump_handler("r3000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl));
+	dump_handler("r3000_tlb_load", handle_tlbl, handle_tlbl_size);
 }
 
-static void __cpuinit build_r3000_tlb_store_handler(void)
+static void build_r3000_tlb_store_handler(void)
 {
 	u32 *p = handle_tlbs;
+	const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
 	struct uasm_label *l = labels;
 	struct uasm_reloc *r = relocs;
 
-	memset(handle_tlbs, 0, sizeof(handle_tlbs));
+	memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
 	memset(labels, 0, sizeof(labels));
 	memset(relocs, 0, sizeof(relocs));
 
@@ -1792,23 +1793,24 @@ static void __cpuinit build_r3000_tlb_st
 	uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
 	uasm_i_nop(&p);
 
-	if ((p - handle_tlbs) > FASTPATH_SIZE)
+	if (p >= handle_tlbs_end)
 		panic("TLB store handler fastpath space exceeded");
 
 	uasm_resolve_relocs(relocs, labels);
 	pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbs));
 
-	dump_handler("r3000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs));
+	dump_handler("r3000_tlb_store", handle_tlbs, handle_tlbs_size);
 }
 
-static void __cpuinit build_r3000_tlb_modify_handler(void)
+static void build_r3000_tlb_modify_handler(void)
 {
 	u32 *p = handle_tlbm;
+	const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
 	struct uasm_label *l = labels;
 	struct uasm_reloc *r = relocs;
 
-	memset(handle_tlbm, 0, sizeof(handle_tlbm));
+	memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
 	memset(labels, 0, sizeof(labels));
 	memset(relocs, 0, sizeof(relocs));
 
@@ -1822,21 +1824,21 @@ static void __cpuinit build_r3000_tlb_mo
 	uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
 	uasm_i_nop(&p);
 
-	if ((p - handle_tlbm) > FASTPATH_SIZE)
+	if (p >= handle_tlbm_end)
 		panic("TLB modify handler fastpath space exceeded");
 
 	uasm_resolve_relocs(relocs, labels);
 	pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbm));
 
-	dump_handler("r3000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm));
+	dump_handler("r3000_tlb_modify", handle_tlbm, handle_tlbm_size);
 }
 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
 
 /*
  * R4000 style TLB load/store/modify handlers.
  */
-static struct work_registers __cpuinit
+static struct work_registers
 build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l,
 				   struct uasm_reloc **r)
 {
@@ -1872,7 +1874,7 @@ build_r4000_tlbchange_handler_head(u32 *
 	return wr;
 }
 
-static void __cpuinit
+static void
 build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
 				   struct uasm_reloc **r, unsigned int tmp,
 				   unsigned int ptr)
@@ -1890,14 +1892,15 @@ build_r4000_tlbchange_handler_tail(u32 *
 #endif
 }
 
-static void __cpuinit build_r4000_tlb_load_handler(void)
+static void build_r4000_tlb_load_handler(void)
 {
 	u32 *p = handle_tlbl;
+	const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
 	struct uasm_label *l = labels;
 	struct uasm_reloc *r = relocs;
 	struct work_registers wr;
 
-	memset(handle_tlbl, 0, sizeof(handle_tlbl));
+	memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
 	memset(labels, 0, sizeof(labels));
 	memset(relocs, 0, sizeof(relocs));
 
@@ -1935,6 +1938,19 @@ static void __cpuinit build_r4000_tlb_lo
 		uasm_i_nop(&p);
 
 		uasm_i_tlbr(&p);
+
+		switch (current_cpu_type()) {
+		default:
+			if (cpu_has_mips_r2) {
+				uasm_i_ehb(&p);
+
+		case CPU_CAVIUM_OCTEON:
+		case CPU_CAVIUM_OCTEON_PLUS:
+		case CPU_CAVIUM_OCTEON2:
+				break;
+			}
+		}
+
 		/* Examine  entrylo 0 or 1 based on ptr. */
 		if (use_bbit_insns()) {
 			uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8);
@@ -1989,6 +2005,19 @@ static void __cpuinit build_r4000_tlb_lo
 		uasm_i_nop(&p);
 
 		uasm_i_tlbr(&p);
+
+		switch (current_cpu_type()) {
+		default:
+			if (cpu_has_mips_r2) {
+				uasm_i_ehb(&p);
+
+		case CPU_CAVIUM_OCTEON:
+		case CPU_CAVIUM_OCTEON_PLUS:
+		case CPU_CAVIUM_OCTEON2:
+				break;
+			}
+		}
+
 		/* Examine  entrylo 0 or 1 based on ptr. */
 		if (use_bbit_insns()) {
 			uasm_i_bbit0(&p, wr.r2, ilog2(sizeof(pte_t)), 8);
@@ -2036,24 +2065,25 @@ static void __cpuinit build_r4000_tlb_lo
 	uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
 	uasm_i_nop(&p);
 
-	if ((p - handle_tlbl) > FASTPATH_SIZE)
+	if (p >= handle_tlbl_end)
 		panic("TLB load handler fastpath space exceeded");
 
 	uasm_resolve_relocs(relocs, labels);
 	pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbl));
 
-	dump_handler("r4000_tlb_load", handle_tlbl, ARRAY_SIZE(handle_tlbl));
+	dump_handler("r4000_tlb_load", handle_tlbl, handle_tlbl_size);
 }
 
-static void __cpuinit build_r4000_tlb_store_handler(void)
+static void build_r4000_tlb_store_handler(void)
 {
 	u32 *p = handle_tlbs;
+	const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
 	struct uasm_label *l = labels;
 	struct uasm_reloc *r = relocs;
 	struct work_registers wr;
 
-	memset(handle_tlbs, 0, sizeof(handle_tlbs));
+	memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
 	memset(labels, 0, sizeof(labels));
 	memset(relocs, 0, sizeof(relocs));
 
@@ -2090,24 +2120,25 @@ static void __cpuinit build_r4000_tlb_st
 	uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
 	uasm_i_nop(&p);
 
-	if ((p - handle_tlbs) > FASTPATH_SIZE)
+	if (p >= handle_tlbs_end)
 		panic("TLB store handler fastpath space exceeded");
 
 	uasm_resolve_relocs(relocs, labels);
 	pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbs));
 
-	dump_handler("r4000_tlb_store", handle_tlbs, ARRAY_SIZE(handle_tlbs));
+	dump_handler("r4000_tlb_store", handle_tlbs, handle_tlbs_size);
 }
 
-static void __cpuinit build_r4000_tlb_modify_handler(void)
+static void build_r4000_tlb_modify_handler(void)
 {
 	u32 *p = handle_tlbm;
+	const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
 	struct uasm_label *l = labels;
 	struct uasm_reloc *r = relocs;
 	struct work_registers wr;
 
-	memset(handle_tlbm, 0, sizeof(handle_tlbm));
+	memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
 	memset(labels, 0, sizeof(labels));
 	memset(relocs, 0, sizeof(relocs));
 
@@ -2145,17 +2176,31 @@ static void __cpuinit build_r4000_tlb_mo
 	uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
 	uasm_i_nop(&p);
 
-	if ((p - handle_tlbm) > FASTPATH_SIZE)
+	if (p >= handle_tlbm_end)
 		panic("TLB modify handler fastpath space exceeded");
 
 	uasm_resolve_relocs(relocs, labels);
 	pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
 		 (unsigned int)(p - handle_tlbm));
 
-	dump_handler("r4000_tlb_modify", handle_tlbm, ARRAY_SIZE(handle_tlbm));
+	dump_handler("r4000_tlb_modify", handle_tlbm, handle_tlbm_size);
 }
 
-void __cpuinit build_tlb_refill_handler(void)
+static void flush_tlb_handlers(void)
+{
+	local_flush_icache_range((unsigned long)handle_tlbl,
+			   (unsigned long)handle_tlbl_end);
+	local_flush_icache_range((unsigned long)handle_tlbs,
+			   (unsigned long)handle_tlbs_end);
+	local_flush_icache_range((unsigned long)handle_tlbm,
+			   (unsigned long)handle_tlbm_end);
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+	local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd,
+			   (unsigned long)tlbmiss_handler_setup_pgd_end);
+#endif
+}
+
+void build_tlb_refill_handler(void)
 {
 	/*
 	 * The refill handler is generated per-CPU, multi-node systems
@@ -2187,6 +2232,7 @@ void __cpuinit build_tlb_refill_handler(
 			build_r3000_tlb_load_handler();
 			build_r3000_tlb_store_handler();
 			build_r3000_tlb_modify_handler();
+			flush_tlb_handlers();
 			run_once++;
 		}
 #else
@@ -2214,23 +2260,10 @@ void __cpuinit build_tlb_refill_handler(
 			build_r4000_tlb_modify_handler();
 			if (!cpu_has_local_ebase)
 				build_r4000_tlb_refill_handler();
+			flush_tlb_handlers();
 			run_once++;
 		}
 		if (cpu_has_local_ebase)
 			build_r4000_tlb_refill_handler();
 	}
 }
-
-void __cpuinit flush_tlb_handlers(void)
-{
-	local_flush_icache_range((unsigned long)handle_tlbl,
-			   (unsigned long)handle_tlbl + sizeof(handle_tlbl));
-	local_flush_icache_range((unsigned long)handle_tlbs,
-			   (unsigned long)handle_tlbs + sizeof(handle_tlbs));
-	local_flush_icache_range((unsigned long)handle_tlbm,
-			   (unsigned long)handle_tlbm + sizeof(handle_tlbm));
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
-	local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd_array,
-			   (unsigned long)tlbmiss_handler_setup_pgd_array + sizeof(handle_tlbm));
-#endif
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/tlb-funcs.S linux-libre-3.11-rc7-gnu/arch/mips/mm/tlb-funcs.S
--- linux-libre-3.10-gnu/arch/mips/mm/tlb-funcs.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/tlb-funcs.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Micro-assembler generated tlb handler functions.
+ *
+ * Copyright (C) 2013  Broadcom Corporation.
+ *
+ * Based on mm/page-funcs.c
+ * Copyright (C) 2012  MIPS Technologies, Inc.
+ * Copyright (C) 2012  Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+#define FASTPATH_SIZE	128
+
+LEAF(tlbmiss_handler_setup_pgd)
+	.space		16 * 4
+END(tlbmiss_handler_setup_pgd)
+EXPORT(tlbmiss_handler_setup_pgd_end)
+
+LEAF(handle_tlbm)
+	.space		FASTPATH_SIZE * 4
+END(handle_tlbm)
+EXPORT(handle_tlbm_end)
+
+LEAF(handle_tlbs)
+	.space		FASTPATH_SIZE * 4
+END(handle_tlbs)
+EXPORT(handle_tlbs_end)
+
+LEAF(handle_tlbl)
+	.space		FASTPATH_SIZE * 4
+END(handle_tlbl)
+EXPORT(handle_tlbl_end)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/tlb-r3k.c linux-libre-3.11-rc7-gnu/arch/mips/mm/tlb-r3k.c
--- linux-libre-3.10-gnu/arch/mips/mm/tlb-r3k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/tlb-r3k.c	2013-08-25 20:43:22.000000000 -0400
@@ -276,7 +276,7 @@ void add_wired_entry(unsigned long entry
 	}
 }
 
-void __cpuinit tlb_init(void)
+void tlb_init(void)
 {
 	local_flush_tlb_all();
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/tlb-r4k.c linux-libre-3.11-rc7-gnu/arch/mips/mm/tlb-r4k.c
--- linux-libre-3.10-gnu/arch/mips/mm/tlb-r4k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/tlb-r4k.c	2013-08-25 20:43:22.000000000 -0400
@@ -389,7 +389,7 @@ int __init has_transparent_hugepage(void
 
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE  */
 
-static int __cpuinitdata ntlb;
+static int ntlb;
 static int __init set_ntlb(char *str)
 {
 	get_option(&str, &ntlb);
@@ -398,7 +398,7 @@ static int __init set_ntlb(char *str)
 
 __setup("ntlb=", set_ntlb);
 
-void __cpuinit tlb_init(void)
+void tlb_init(void)
 {
 	/*
 	 * You should never change this register:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/tlb-r8k.c linux-libre-3.11-rc7-gnu/arch/mips/mm/tlb-r8k.c
--- linux-libre-3.10-gnu/arch/mips/mm/tlb-r8k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/tlb-r8k.c	2013-08-25 20:43:22.000000000 -0400
@@ -213,14 +213,14 @@ void __update_tlb(struct vm_area_struct
 	local_irq_restore(flags);
 }
 
-static void __cpuinit probe_tlb(unsigned long config)
+static void probe_tlb(unsigned long config)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
 
 	c->tlbsize = 3 * 128;		/* 3 sets each 128 entries */
 }
 
-void __cpuinit tlb_init(void)
+void tlb_init(void)
 {
 	unsigned int config = read_c0_config();
 	unsigned long status;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/uasm.c linux-libre-3.11-rc7-gnu/arch/mips/mm/uasm.c
--- linux-libre-3.10-gnu/arch/mips/mm/uasm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/uasm.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,35 +63,35 @@ struct insn {
 	enum fields fields;
 };
 
-static inline __uasminit u32 build_rs(u32 arg)
+static inline u32 build_rs(u32 arg)
 {
 	WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n");
 
 	return (arg & RS_MASK) << RS_SH;
 }
 
-static inline __uasminit u32 build_rt(u32 arg)
+static inline u32 build_rt(u32 arg)
 {
 	WARN(arg & ~RT_MASK, KERN_WARNING "Micro-assembler field overflow\n");
 
 	return (arg & RT_MASK) << RT_SH;
 }
 
-static inline __uasminit u32 build_rd(u32 arg)
+static inline u32 build_rd(u32 arg)
 {
 	WARN(arg & ~RD_MASK, KERN_WARNING "Micro-assembler field overflow\n");
 
 	return (arg & RD_MASK) << RD_SH;
 }
 
-static inline __uasminit u32 build_re(u32 arg)
+static inline u32 build_re(u32 arg)
 {
 	WARN(arg & ~RE_MASK, KERN_WARNING "Micro-assembler field overflow\n");
 
 	return (arg & RE_MASK) << RE_SH;
 }
 
-static inline __uasminit u32 build_simm(s32 arg)
+static inline u32 build_simm(s32 arg)
 {
 	WARN(arg > 0x7fff || arg < -0x8000,
 	     KERN_WARNING "Micro-assembler field overflow\n");
@@ -99,14 +99,14 @@ static inline __uasminit u32 build_simm(
 	return arg & 0xffff;
 }
 
-static inline __uasminit u32 build_uimm(u32 arg)
+static inline u32 build_uimm(u32 arg)
 {
 	WARN(arg & ~IMM_MASK, KERN_WARNING "Micro-assembler field overflow\n");
 
 	return arg & IMM_MASK;
 }
 
-static inline __uasminit u32 build_scimm(u32 arg)
+static inline u32 build_scimm(u32 arg)
 {
 	WARN(arg & ~SCIMM_MASK,
 	     KERN_WARNING "Micro-assembler field overflow\n");
@@ -114,21 +114,21 @@ static inline __uasminit u32 build_scimm
 	return (arg & SCIMM_MASK) << SCIMM_SH;
 }
 
-static inline __uasminit u32 build_func(u32 arg)
+static inline u32 build_func(u32 arg)
 {
 	WARN(arg & ~FUNC_MASK, KERN_WARNING "Micro-assembler field overflow\n");
 
 	return arg & FUNC_MASK;
 }
 
-static inline __uasminit u32 build_set(u32 arg)
+static inline u32 build_set(u32 arg)
 {
 	WARN(arg & ~SET_MASK, KERN_WARNING "Micro-assembler field overflow\n");
 
 	return arg & SET_MASK;
 }
 
-static void __uasminit build_insn(u32 **buf, enum opcode opc, ...);
+static void build_insn(u32 **buf, enum opcode opc, ...);
 
 #define I_u1u2u3(op)					\
 Ip_u1u2u3(op)						\
@@ -286,7 +286,7 @@ I_u3u1u2(_ldx)
 
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
 #include <asm/octeon/octeon.h>
-void __uasminit ISAFUNC(uasm_i_pref)(u32 **buf, unsigned int a, signed int b,
+void ISAFUNC(uasm_i_pref)(u32 **buf, unsigned int a, signed int b,
 			    unsigned int c)
 {
 	if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5)
@@ -304,7 +304,7 @@ I_u2s3u1(_pref)
 #endif
 
 /* Handle labels. */
-void __uasminit ISAFUNC(uasm_build_label)(struct uasm_label **lab, u32 *addr, int lid)
+void ISAFUNC(uasm_build_label)(struct uasm_label **lab, u32 *addr, int lid)
 {
 	(*lab)->addr = addr;
 	(*lab)->lab = lid;
@@ -312,7 +312,7 @@ void __uasminit ISAFUNC(uasm_build_label
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_build_label));
 
-int __uasminit ISAFUNC(uasm_in_compat_space_p)(long addr)
+int ISAFUNC(uasm_in_compat_space_p)(long addr)
 {
 	/* Is this address in 32bit compat space? */
 #ifdef CONFIG_64BIT
@@ -323,7 +323,7 @@ int __uasminit ISAFUNC(uasm_in_compat_sp
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_in_compat_space_p));
 
-static int __uasminit uasm_rel_highest(long val)
+static int uasm_rel_highest(long val)
 {
 #ifdef CONFIG_64BIT
 	return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
@@ -332,7 +332,7 @@ static int __uasminit uasm_rel_highest(l
 #endif
 }
 
-static int __uasminit uasm_rel_higher(long val)
+static int uasm_rel_higher(long val)
 {
 #ifdef CONFIG_64BIT
 	return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
@@ -341,19 +341,19 @@ static int __uasminit uasm_rel_higher(lo
 #endif
 }
 
-int __uasminit ISAFUNC(uasm_rel_hi)(long val)
+int ISAFUNC(uasm_rel_hi)(long val)
 {
 	return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_rel_hi));
 
-int __uasminit ISAFUNC(uasm_rel_lo)(long val)
+int ISAFUNC(uasm_rel_lo)(long val)
 {
 	return ((val & 0xffff) ^ 0x8000) - 0x8000;
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_rel_lo));
 
-void __uasminit ISAFUNC(UASM_i_LA_mostly)(u32 **buf, unsigned int rs, long addr)
+void ISAFUNC(UASM_i_LA_mostly)(u32 **buf, unsigned int rs, long addr)
 {
 	if (!ISAFUNC(uasm_in_compat_space_p)(addr)) {
 		ISAFUNC(uasm_i_lui)(buf, rs, uasm_rel_highest(addr));
@@ -371,7 +371,7 @@ void __uasminit ISAFUNC(UASM_i_LA_mostly
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(UASM_i_LA_mostly));
 
-void __uasminit ISAFUNC(UASM_i_LA)(u32 **buf, unsigned int rs, long addr)
+void ISAFUNC(UASM_i_LA)(u32 **buf, unsigned int rs, long addr)
 {
 	ISAFUNC(UASM_i_LA_mostly)(buf, rs, addr);
 	if (ISAFUNC(uasm_rel_lo(addr))) {
@@ -386,8 +386,7 @@ void __uasminit ISAFUNC(UASM_i_LA)(u32 *
 UASM_EXPORT_SYMBOL(ISAFUNC(UASM_i_LA));
 
 /* Handle relocations. */
-void __uasminit
-ISAFUNC(uasm_r_mips_pc16)(struct uasm_reloc **rel, u32 *addr, int lid)
+void ISAFUNC(uasm_r_mips_pc16)(struct uasm_reloc **rel, u32 *addr, int lid)
 {
 	(*rel)->addr = addr;
 	(*rel)->type = R_MIPS_PC16;
@@ -396,11 +395,11 @@ ISAFUNC(uasm_r_mips_pc16)(struct uasm_re
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_r_mips_pc16));
 
-static inline void __uasminit
-__resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab);
+static inline void __resolve_relocs(struct uasm_reloc *rel,
+				    struct uasm_label *lab);
 
-void __uasminit
-ISAFUNC(uasm_resolve_relocs)(struct uasm_reloc *rel, struct uasm_label *lab)
+void ISAFUNC(uasm_resolve_relocs)(struct uasm_reloc *rel,
+				  struct uasm_label *lab)
 {
 	struct uasm_label *l;
 
@@ -411,8 +410,8 @@ ISAFUNC(uasm_resolve_relocs)(struct uasm
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_resolve_relocs));
 
-void __uasminit
-ISAFUNC(uasm_move_relocs)(struct uasm_reloc *rel, u32 *first, u32 *end, long off)
+void ISAFUNC(uasm_move_relocs)(struct uasm_reloc *rel, u32 *first, u32 *end,
+			       long off)
 {
 	for (; rel->lab != UASM_LABEL_INVALID; rel++)
 		if (rel->addr >= first && rel->addr < end)
@@ -420,8 +419,8 @@ ISAFUNC(uasm_move_relocs)(struct uasm_re
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_move_relocs));
 
-void __uasminit
-ISAFUNC(uasm_move_labels)(struct uasm_label *lab, u32 *first, u32 *end, long off)
+void ISAFUNC(uasm_move_labels)(struct uasm_label *lab, u32 *first, u32 *end,
+			       long off)
 {
 	for (; lab->lab != UASM_LABEL_INVALID; lab++)
 		if (lab->addr >= first && lab->addr < end)
@@ -429,9 +428,8 @@ ISAFUNC(uasm_move_labels)(struct uasm_la
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_move_labels));
 
-void __uasminit
-ISAFUNC(uasm_copy_handler)(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
-		  u32 *end, u32 *target)
+void ISAFUNC(uasm_copy_handler)(struct uasm_reloc *rel, struct uasm_label *lab,
+				u32 *first, u32 *end, u32 *target)
 {
 	long off = (long)(target - first);
 
@@ -442,7 +440,7 @@ ISAFUNC(uasm_copy_handler)(struct uasm_r
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_copy_handler));
 
-int __uasminit ISAFUNC(uasm_insn_has_bdelay)(struct uasm_reloc *rel, u32 *addr)
+int ISAFUNC(uasm_insn_has_bdelay)(struct uasm_reloc *rel, u32 *addr)
 {
 	for (; rel->lab != UASM_LABEL_INVALID; rel++) {
 		if (rel->addr == addr
@@ -456,83 +454,79 @@ int __uasminit ISAFUNC(uasm_insn_has_bde
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_insn_has_bdelay));
 
 /* Convenience functions for labeled branches. */
-void __uasminit
-ISAFUNC(uasm_il_bltz)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+void ISAFUNC(uasm_il_bltz)(u32 **p, struct uasm_reloc **r, unsigned int reg,
+			   int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_bltz)(p, reg, 0);
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bltz));
 
-void __uasminit
-ISAFUNC(uasm_il_b)(u32 **p, struct uasm_reloc **r, int lid)
+void ISAFUNC(uasm_il_b)(u32 **p, struct uasm_reloc **r, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_b)(p, 0);
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_b));
 
-void __uasminit
-ISAFUNC(uasm_il_beqz)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+void ISAFUNC(uasm_il_beqz)(u32 **p, struct uasm_reloc **r, unsigned int reg,
+			   int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_beqz)(p, reg, 0);
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_beqz));
 
-void __uasminit
-ISAFUNC(uasm_il_beqzl)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+void ISAFUNC(uasm_il_beqzl)(u32 **p, struct uasm_reloc **r, unsigned int reg,
+			    int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_beqzl)(p, reg, 0);
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_beqzl));
 
-void __uasminit
-ISAFUNC(uasm_il_bne)(u32 **p, struct uasm_reloc **r, unsigned int reg1,
-	unsigned int reg2, int lid)
+void ISAFUNC(uasm_il_bne)(u32 **p, struct uasm_reloc **r, unsigned int reg1,
+			  unsigned int reg2, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_bne)(p, reg1, reg2, 0);
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bne));
 
-void __uasminit
-ISAFUNC(uasm_il_bnez)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+void ISAFUNC(uasm_il_bnez)(u32 **p, struct uasm_reloc **r, unsigned int reg,
+			   int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_bnez)(p, reg, 0);
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bnez));
 
-void __uasminit
-ISAFUNC(uasm_il_bgezl)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+void ISAFUNC(uasm_il_bgezl)(u32 **p, struct uasm_reloc **r, unsigned int reg,
+			    int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_bgezl)(p, reg, 0);
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bgezl));
 
-void __uasminit
-ISAFUNC(uasm_il_bgez)(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+void ISAFUNC(uasm_il_bgez)(u32 **p, struct uasm_reloc **r, unsigned int reg,
+			   int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_bgez)(p, reg, 0);
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bgez));
 
-void __uasminit
-ISAFUNC(uasm_il_bbit0)(u32 **p, struct uasm_reloc **r, unsigned int reg,
-	      unsigned int bit, int lid)
+void ISAFUNC(uasm_il_bbit0)(u32 **p, struct uasm_reloc **r, unsigned int reg,
+			    unsigned int bit, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_bbit0)(p, reg, bit, 0);
 }
 UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_bbit0));
 
-void __uasminit
-ISAFUNC(uasm_il_bbit1)(u32 **p, struct uasm_reloc **r, unsigned int reg,
-	      unsigned int bit, int lid)
+void ISAFUNC(uasm_il_bbit1)(u32 **p, struct uasm_reloc **r, unsigned int reg,
+			    unsigned int bit, int lid)
 {
 	uasm_r_mips_pc16(r, *p, lid);
 	ISAFUNC(uasm_i_bbit1)(p, reg, bit, 0);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/uasm-micromips.c linux-libre-3.11-rc7-gnu/arch/mips/mm/uasm-micromips.c
--- linux-libre-3.10-gnu/arch/mips/mm/uasm-micromips.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/uasm-micromips.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,7 +49,7 @@
 
 #include "uasm.c"
 
-static struct insn insn_table_MM[] __uasminitdata = {
+static struct insn insn_table_MM[] = {
 	{ insn_addu, M(mm_pool32a_op, 0, 0, 0, 0, mm_addu32_op), RT | RS | RD },
 	{ insn_addiu, M(mm_addiu32_op, 0, 0, 0, 0, 0), RT | RS | SIMM },
 	{ insn_and, M(mm_pool32a_op, 0, 0, 0, 0, mm_and_op), RT | RS | RD },
@@ -118,7 +118,7 @@ static struct insn insn_table_MM[] __uas
 
 #undef M
 
-static inline __uasminit u32 build_bimm(s32 arg)
+static inline u32 build_bimm(s32 arg)
 {
 	WARN(arg > 0xffff || arg < -0x10000,
 	     KERN_WARNING "Micro-assembler field overflow\n");
@@ -128,7 +128,7 @@ static inline __uasminit u32 build_bimm(
 	return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 1) & 0x7fff);
 }
 
-static inline __uasminit u32 build_jimm(u32 arg)
+static inline u32 build_jimm(u32 arg)
 {
 
 	WARN(arg & ~((JIMM_MASK << 2) | 1),
@@ -141,7 +141,7 @@ static inline __uasminit u32 build_jimm(
  * The order of opcode arguments is implicitly left to right,
  * starting with RS and ending with FUNC or IMM.
  */
-static void __uasminit build_insn(u32 **buf, enum opcode opc, ...)
+static void build_insn(u32 **buf, enum opcode opc, ...)
 {
 	struct insn *ip = NULL;
 	unsigned int i;
@@ -199,7 +199,7 @@ static void __uasminit build_insn(u32 **
 	(*buf)++;
 }
 
-static inline void __uasminit
+static inline void
 __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
 {
 	long laddr = (long)lab->addr;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mm/uasm-mips.c linux-libre-3.11-rc7-gnu/arch/mips/mm/uasm-mips.c
--- linux-libre-3.10-gnu/arch/mips/mm/uasm-mips.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mm/uasm-mips.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,7 +49,7 @@
 
 #include "uasm.c"
 
-static struct insn insn_table[] __uasminitdata = {
+static struct insn insn_table[] = {
 	{ insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
 	{ insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
 	{ insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
@@ -119,7 +119,7 @@ static struct insn insn_table[] __uasmin
 
 #undef M
 
-static inline __uasminit u32 build_bimm(s32 arg)
+static inline u32 build_bimm(s32 arg)
 {
 	WARN(arg > 0x1ffff || arg < -0x20000,
 	     KERN_WARNING "Micro-assembler field overflow\n");
@@ -129,7 +129,7 @@ static inline __uasminit u32 build_bimm(
 	return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
 }
 
-static inline __uasminit u32 build_jimm(u32 arg)
+static inline u32 build_jimm(u32 arg)
 {
 	WARN(arg & ~(JIMM_MASK << 2),
 	     KERN_WARNING "Micro-assembler field overflow\n");
@@ -141,7 +141,7 @@ static inline __uasminit u32 build_jimm(
  * The order of opcode arguments is implicitly left to right,
  * starting with RS and ending with FUNC or IMM.
  */
-static void __uasminit build_insn(u32 **buf, enum opcode opc, ...)
+static void build_insn(u32 **buf, enum opcode opc, ...)
 {
 	struct insn *ip = NULL;
 	unsigned int i;
@@ -187,7 +187,7 @@ static void __uasminit build_insn(u32 **
 	(*buf)++;
 }
 
-static inline void __uasminit
+static inline void
 __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
 {
 	long laddr = (long)lab->addr;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mti-malta/Makefile linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/Makefile
--- linux-libre-3.10-gnu/arch/mips/mti-malta/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,6 @@ obj-y				:= malta-amon.o malta-display.o
 				   malta-reset.o malta-setup.o malta-time.o
 
 obj-$(CONFIG_EARLY_PRINTK)	+= malta-console.o
-obj-$(CONFIG_PCI)		+= malta-pci.o
 
 # FIXME FIXME FIXME
 obj-$(CONFIG_MIPS_MT_SMTC)	+= malta-smtc.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mti-malta/malta-int.c linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-int.c
--- linux-libre-3.10-gnu/arch/mips/mti-malta/malta-int.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-int.c	2013-08-25 20:43:22.000000000 -0400
@@ -422,8 +422,10 @@ static struct gic_intr_map gic_intr_map[
  */
 int __init gcmp_probe(unsigned long addr, unsigned long size)
 {
-	if (mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) {
+	if ((mips_revision_sconid != MIPS_REVISION_SCON_ROCIT)  &&
+	    (mips_revision_sconid != MIPS_REVISION_SCON_GT64120)) {
 		gcmp_present = 0;
+		pr_debug("GCMP NOT present\n");
 		return gcmp_present;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mti-malta/malta-pci.c linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-pci.c
--- linux-libre-3.10-gnu/arch/mips/mti-malta/malta-pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-pci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 1999, 2000, 2004, 2005	 MIPS Technologies, Inc.
- *	All rights reserved.
- *	Authors: Carsten Langgaard <carstenl@mips.com>
- *		 Maciej W. Rozycki <macro@mips.com>
- *
- * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * MIPS boards specific PCI support.
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/gt64120.h>
-#include <asm/gcmpregs.h>
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/bonito64.h>
-#include <asm/mips-boards/msc01_pci.h>
-
-static struct resource bonito64_mem_resource = {
-	.name	= "Bonito PCI MEM",
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct resource bonito64_io_resource = {
-	.name	= "Bonito PCI I/O",
-	.start	= 0x00000000UL,
-	.end	= 0x000fffffUL,
-	.flags	= IORESOURCE_IO,
-};
-
-static struct resource gt64120_mem_resource = {
-	.name	= "GT-64120 PCI MEM",
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct resource gt64120_io_resource = {
-	.name	= "GT-64120 PCI I/O",
-	.flags	= IORESOURCE_IO,
-};
-
-static struct resource msc_mem_resource = {
-	.name	= "MSC PCI MEM",
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct resource msc_io_resource = {
-	.name	= "MSC PCI I/O",
-	.flags	= IORESOURCE_IO,
-};
-
-extern struct pci_ops bonito64_pci_ops;
-extern struct pci_ops gt64xxx_pci0_ops;
-extern struct pci_ops msc_pci_ops;
-
-static struct pci_controller bonito64_controller = {
-	.pci_ops	= &bonito64_pci_ops,
-	.io_resource	= &bonito64_io_resource,
-	.mem_resource	= &bonito64_mem_resource,
-	.io_offset	= 0x00000000UL,
-};
-
-static struct pci_controller gt64120_controller = {
-	.pci_ops	= &gt64xxx_pci0_ops,
-	.io_resource	= &gt64120_io_resource,
-	.mem_resource	= &gt64120_mem_resource,
-};
-
-static struct pci_controller msc_controller = {
-	.pci_ops	= &msc_pci_ops,
-	.io_resource	= &msc_io_resource,
-	.mem_resource	= &msc_mem_resource,
-};
-
-void __init mips_pcibios_init(void)
-{
-	struct pci_controller *controller;
-	resource_size_t start, end, map, start1, end1, map1, map2, map3, mask;
-
-	switch (mips_revision_sconid) {
-	case MIPS_REVISION_SCON_GT64120:
-		/*
-		 * Due to a bug in the Galileo system controller, we need
-		 * to setup the PCI BAR for the Galileo internal registers.
-		 * This should be done in the bios/bootprom and will be
-		 * fixed in a later revision of YAMON (the MIPS boards
-		 * boot prom).
-		 */
-		GT_WRITE(GT_PCI0_CFGADDR_OFS,
-			 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
-			 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
-			 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
-			 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
-			 GT_PCI0_CFGADDR_CONFIGEN_BIT);
-
-		/* Perform the write */
-		GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
-
-		/* Set up resource ranges from the controller's registers.  */
-		start = GT_READ(GT_PCI0M0LD_OFS);
-		end = GT_READ(GT_PCI0M0HD_OFS);
-		map = GT_READ(GT_PCI0M0REMAP_OFS);
-		end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
-		start1 = GT_READ(GT_PCI0M1LD_OFS);
-		end1 = GT_READ(GT_PCI0M1HD_OFS);
-		map1 = GT_READ(GT_PCI0M1REMAP_OFS);
-		end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
-		/* Cannot support multiple windows, use the wider.  */
-		if (end1 - start1 > end - start) {
-			start = start1;
-			end = end1;
-			map = map1;
-		}
-		mask = ~(start ^ end);
-		/* We don't support remapping with a discontiguous mask.  */
-		BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
-		       mask != ~((mask & -mask) - 1));
-		gt64120_mem_resource.start = start;
-		gt64120_mem_resource.end = end;
-		gt64120_controller.mem_offset = (start & mask) - (map & mask);
-		/* Addresses are 36-bit, so do shifts in the destinations.  */
-		gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
-		gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
-		gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
-		gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
-
-		start = GT_READ(GT_PCI0IOLD_OFS);
-		end = GT_READ(GT_PCI0IOHD_OFS);
-		map = GT_READ(GT_PCI0IOREMAP_OFS);
-		end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
-		mask = ~(start ^ end);
-		/* We don't support remapping with a discontiguous mask.  */
-		BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
-		       mask != ~((mask & -mask) - 1));
-		gt64120_io_resource.start = map & mask;
-		gt64120_io_resource.end = (map & mask) | ~mask;
-		gt64120_controller.io_offset = 0;
-		/* Addresses are 36-bit, so do shifts in the destinations.  */
-		gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
-		gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
-		gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
-
-		controller = &gt64120_controller;
-		break;
-
-	case MIPS_REVISION_SCON_BONITO:
-		/* Set up resource ranges from the controller's registers.  */
-		map = BONITO_PCIMAP;
-		map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >>
-		       BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
-		map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >>
-		       BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
-		map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >>
-		       BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
-		/* Combine as many adjacent windows as possible.  */
-		map = map1;
-		start = BONITO_PCILO0_BASE;
-		end = 1;
-		if (map3 == map2 + 1) {
-			map = map2;
-			start = BONITO_PCILO1_BASE;
-			end++;
-		}
-		if (map2 == map1 + 1) {
-			map = map1;
-			start = BONITO_PCILO0_BASE;
-			end++;
-		}
-		bonito64_mem_resource.start = start;
-		bonito64_mem_resource.end = start +
-					    BONITO_PCIMAP_WINBASE(end) - 1;
-		bonito64_controller.mem_offset = start -
-						 BONITO_PCIMAP_WINBASE(map);
-
-		controller = &bonito64_controller;
-		break;
-
-	case MIPS_REVISION_SCON_SOCIT:
-	case MIPS_REVISION_SCON_ROCIT:
-	case MIPS_REVISION_SCON_SOCITSC:
-	case MIPS_REVISION_SCON_SOCITSCP:
-		/* Set up resource ranges from the controller's registers.  */
-		MSC_READ(MSC01_PCI_SC2PMBASL, start);
-		MSC_READ(MSC01_PCI_SC2PMMSKL, mask);
-		MSC_READ(MSC01_PCI_SC2PMMAPL, map);
-		msc_mem_resource.start = start & mask;
-		msc_mem_resource.end = (start & mask) | ~mask;
-		msc_controller.mem_offset = (start & mask) - (map & mask);
-#ifdef CONFIG_MIPS_CMP
-		if (gcmp_niocu())
-			gcmp_setregion(0, start, mask,
-				GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
-#endif
-		MSC_READ(MSC01_PCI_SC2PIOBASL, start);
-		MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
-		MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
-		msc_io_resource.start = map & mask;
-		msc_io_resource.end = (map & mask) | ~mask;
-		msc_controller.io_offset = 0;
-		ioport_resource.end = ~mask;
-#ifdef CONFIG_MIPS_CMP
-		if (gcmp_niocu())
-			gcmp_setregion(1, start, mask,
-				GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
-#endif
-		/* If ranges overlap I/O takes precedence.  */
-		start = start & mask;
-		end = start | ~mask;
-		if ((start >= msc_mem_resource.start &&
-		     start <= msc_mem_resource.end) ||
-		    (end >= msc_mem_resource.start &&
-		     end <= msc_mem_resource.end)) {
-			/* Use the larger space.  */
-			start = max(start, msc_mem_resource.start);
-			end = min(end, msc_mem_resource.end);
-			if (start - msc_mem_resource.start >=
-			    msc_mem_resource.end - end)
-				msc_mem_resource.end = start - 1;
-			else
-				msc_mem_resource.start = end + 1;
-		}
-
-		controller = &msc_controller;
-		break;
-	default:
-		return;
-	}
-
-	/* Change start address to avoid conflicts with ACPI and SMB devices */
-	if (controller->io_resource->start < 0x00002000UL)
-		controller->io_resource->start = 0x00002000UL;
-
-	iomem_resource.end &= 0xfffffffffULL;			/* 64 GB */
-	ioport_resource.end = controller->io_resource->end;
-
-	controller->io_map_base = mips_io_port_base;
-
-	register_pci_controller(controller);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mti-malta/malta-reset.c linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-reset.c
--- linux-libre-3.10-gnu/arch/mips/mti-malta/malta-reset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-reset.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,33 +1,18 @@
 /*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
  * Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Reset the MIPS boards.
- *
  */
-#include <linux/init.h>
+#include <linux/io.h>
 #include <linux/pm.h>
 
-#include <asm/io.h>
 #include <asm/reboot.h>
-#include <asm/mips-boards/generic.h>
+
+#define SOFTRES_REG	0x1f000500
+#define GORESET		0x42
 
 static void mips_machine_restart(char *command)
 {
@@ -45,7 +30,6 @@ static void mips_machine_halt(void)
 	__raw_writel(GORESET, softres_reg);
 }
 
-
 static int __init mips_reboot_setup(void)
 {
 	_machine_restart = mips_machine_restart;
@@ -54,5 +38,4 @@ static int __init mips_reboot_setup(void
 
 	return 0;
 }
-
 arch_initcall(mips_reboot_setup);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mti-malta/malta-smtc.c linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-smtc.c
--- linux-libre-3.10-gnu/arch/mips/mti-malta/malta-smtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-smtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,7 @@ static void msmtc_send_ipi_mask(const st
 /*
  * Post-config but pre-boot cleanup entry point
  */
-static void __cpuinit msmtc_init_secondary(void)
+static void msmtc_init_secondary(void)
 {
 	int myvpe;
 
@@ -53,7 +53,7 @@ static void __cpuinit msmtc_init_seconda
 /*
  * Platform "CPU" startup hook
  */
-static void __cpuinit msmtc_boot_secondary(int cpu, struct task_struct *idle)
+static void msmtc_boot_secondary(int cpu, struct task_struct *idle)
 {
 	smtc_boot_secondary(cpu, idle);
 }
@@ -61,7 +61,7 @@ static void __cpuinit msmtc_boot_seconda
 /*
  * SMP initialization finalization entry point
  */
-static void __cpuinit msmtc_smp_finish(void)
+static void msmtc_smp_finish(void)
 {
 	smtc_smp_finish();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mti-malta/malta-time.c linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-time.c
--- linux-libre-3.10-gnu/arch/mips/mti-malta/malta-time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mti-malta/malta-time.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,7 +150,7 @@ static void __init plat_perf_setup(void)
 	}
 }
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
 #ifdef MSC01E_INT_BASE
 	if (cpu_has_veic) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mti-sead3/sead3-reset.c linux-libre-3.11-rc7-gnu/arch/mips/mti-sead3/sead3-reset.c
--- linux-libre-3.10-gnu/arch/mips/mti-sead3/sead3-reset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mti-sead3/sead3-reset.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,9 @@
 #include <linux/pm.h>
 
 #include <asm/reboot.h>
-#include <asm/mips-boards/generic.h>
+
+#define SOFTRES_REG	0x1f000050
+#define GORESET		0x4d
 
 static void mips_machine_restart(char *command)
 {
@@ -35,5 +37,4 @@ static int __init mips_reboot_setup(void
 
 	return 0;
 }
-
 arch_initcall(mips_reboot_setup);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/mti-sead3/sead3-time.c linux-libre-3.11-rc7-gnu/arch/mips/mti-sead3/sead3-time.c
--- linux-libre-3.10-gnu/arch/mips/mti-sead3/sead3-time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/mti-sead3/sead3-time.c	2013-08-25 20:43:22.000000000 -0400
@@ -91,7 +91,7 @@ static void __init plat_perf_setup(void)
 	}
 }
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
 	if (cpu_has_vint)
 		set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/common/irq.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/irq.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/common/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,6 +40,10 @@
 #include <linux/slab.h>
 #include <linux/irq.h>
 
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
 #include <asm/errno.h>
 #include <asm/signal.h>
 #include <asm/ptrace.h>
@@ -223,17 +227,6 @@ static void nlm_init_node_irqs(int node)
 	nodep->irqmask = irqmask;
 }
 
-void __init arch_init_irq(void)
-{
-	/* Initialize the irq descriptors */
-	nlm_init_percpu_irqs();
-	nlm_init_node_irqs(0);
-	write_c0_eimr(nlm_current_node()->irqmask);
-#if defined(CONFIG_CPU_XLR)
-	nlm_setup_fmn_irq();
-#endif
-}
-
 void nlm_smp_irq_init(int hwcpuid)
 {
 	int node, cpu;
@@ -253,13 +246,12 @@ asmlinkage void plat_irq_dispatch(void)
 
 	node = nlm_nodeid();
 	eirr = read_c0_eirr_and_eimr();
-
-	i = __ilog2_u64(eirr);
-	if (i == -1)
+	if (eirr == 0)
 		return;
 
+	i = __ffs64(eirr);
 	/* per-CPU IRQs don't need translation */
-	if (eirr & PERCPU_IRQ_MASK) {
+	if (i < PIC_IRQ_BASE) {
 		do_IRQ(i);
 		return;
 	}
@@ -267,3 +259,56 @@ asmlinkage void plat_irq_dispatch(void)
 	/* top level irq handling */
 	do_IRQ(nlm_irq_to_xirq(node, i));
 }
+
+#ifdef CONFIG_OF
+static struct irq_domain *xlp_pic_domain;
+
+static const struct irq_domain_ops xlp_pic_irq_domain_ops = {
+	.xlate = irq_domain_xlate_onetwocell,
+};
+
+static int __init xlp_of_pic_init(struct device_node *node,
+					struct device_node *parent)
+{
+	const int n_picirqs = PIC_IRT_LAST_IRQ - PIC_IRQ_BASE + 1;
+	struct resource res;
+	int socid, ret;
+
+	/* we need a hack to get the PIC's SoC chip id */
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret < 0) {
+		pr_err("PIC %s: reg property not found!\n", node->name);
+		return -EINVAL;
+	}
+	socid = (res.start >> 18) & 0x3;
+	xlp_pic_domain = irq_domain_add_legacy(node, n_picirqs,
+		nlm_irq_to_xirq(socid, PIC_IRQ_BASE), PIC_IRQ_BASE,
+		&xlp_pic_irq_domain_ops, NULL);
+	if (xlp_pic_domain == NULL) {
+		pr_err("PIC %s: Creating legacy domain failed!\n", node->name);
+		return -EINVAL;
+	}
+	pr_info("Node %d: IRQ domain created for PIC@%pa\n", socid,
+							&res.start);
+	return 0;
+}
+
+static struct of_device_id __initdata xlp_pic_irq_ids[] = {
+	{ .compatible = "netlogic,xlp-pic", .data = xlp_of_pic_init },
+	{},
+};
+#endif
+
+void __init arch_init_irq(void)
+{
+	/* Initialize the irq descriptors */
+	nlm_init_percpu_irqs();
+	nlm_init_node_irqs(0);
+	write_c0_eimr(nlm_current_node()->irqmask);
+#if defined(CONFIG_CPU_XLR)
+	nlm_setup_fmn_irq();
+#endif
+#if defined(CONFIG_OF)
+	of_irq_init(xlp_pic_irq_ids);
+#endif
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/common/Makefile linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/Makefile
--- linux-libre-3.10-gnu/arch/mips/netlogic/common/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,3 +1,5 @@
 obj-y				+= irq.o time.o
+obj-y				+= nlm-dma.o
+obj-y				+= reset.o
 obj-$(CONFIG_SMP)		+= smp.o smpboot.o
 obj-$(CONFIG_EARLY_PRINTK)	+= earlycons.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/common/nlm-dma.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/nlm-dma.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/common/nlm-dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/nlm-dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,107 @@
+/*
+*  Copyright (C) 2003-2013 Broadcom Corporation
+*  All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/bootmem.h>
+#include <linux/export.h>
+#include <linux/swiotlb.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+
+static char *nlm_swiotlb;
+
+static void *nlm_dma_alloc_coherent(struct device *dev, size_t size,
+	dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+	void *ret;
+
+	if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
+		return ret;
+
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+
+#ifdef CONFIG_ZONE_DMA32
+	if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
+		gfp |= __GFP_DMA32;
+#endif
+
+	/* Don't invoke OOM killer */
+	gfp |= __GFP_NORETRY;
+
+	return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+}
+
+static void nlm_dma_free_coherent(struct device *dev, size_t size,
+	void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs)
+{
+	int order = get_order(size);
+
+	if (dma_release_from_coherent(dev, order, vaddr))
+		return;
+
+	swiotlb_free_coherent(dev, size, vaddr, dma_handle);
+}
+
+struct dma_map_ops nlm_swiotlb_dma_ops = {
+	.alloc = nlm_dma_alloc_coherent,
+	.free = nlm_dma_free_coherent,
+	.map_page = swiotlb_map_page,
+	.unmap_page = swiotlb_unmap_page,
+	.map_sg = swiotlb_map_sg_attrs,
+	.unmap_sg = swiotlb_unmap_sg_attrs,
+	.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+	.sync_single_for_device = swiotlb_sync_single_for_device,
+	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+	.sync_sg_for_device = swiotlb_sync_sg_for_device,
+	.mapping_error = swiotlb_dma_mapping_error,
+	.dma_supported = swiotlb_dma_supported
+};
+
+void __init plat_swiotlb_setup(void)
+{
+	size_t swiotlbsize;
+	unsigned long swiotlb_nslabs;
+
+	swiotlbsize = 1 << 20; /* 1 MB for now */
+	swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
+	swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
+	swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
+
+	nlm_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
+	swiotlb_init_with_tbl(nlm_swiotlb, swiotlb_nslabs, 1);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/common/reset.S linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/reset.S
--- linux-libre-3.10-gnu/arch/mips/netlogic/common/reset.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/reset.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2003-2013 Broadcom Corporation.
+ * All Rights Reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/asmmacro.h>
+#include <asm/addrspace.h>
+
+#include <asm/netlogic/common.h>
+
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/sys.h>
+#include <asm/netlogic/xlp-hal/cpucontrol.h>
+
+#define CP0_EBASE	$15
+#define SYS_CPU_COHERENT_BASE(node)	CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
+			XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
+			SYS_CPU_NONCOHERENT_MODE * 4
+
+/* Enable XLP features and workarounds in the LSU */
+.macro xlp_config_lsu
+	li	t0, LSU_DEFEATURE
+	mfcr	t1, t0
+
+	lui	t2, 0xc080	/* SUE, Enable Unaligned Access, L2HPE */
+	or	t1, t1, t2
+	mtcr	t1, t0
+
+	li	t0, ICU_DEFEATURE
+	mfcr	t1, t0
+	ori	t1, 0x1000	/* Enable Icache partitioning */
+	mtcr	t1, t0
+
+	li	t0, SCHED_DEFEATURE
+	lui	t1, 0x0100	/* Disable BRU accepting ALU ops */
+	mtcr	t1, t0
+.endm
+
+/*
+ * Low level flush for L1D cache on XLP, the normal cache ops does
+ * not do the complete and correct cache flush.
+ */
+.macro	xlp_flush_l1_dcache
+	li	t0, LSU_DEBUG_DATA0
+	li	t1, LSU_DEBUG_ADDR
+	li	t2, 0		/* index */
+	li	t3, 0x1000	/* loop count */
+1:
+	sll	v0, t2, 5
+	mtcr	zero, t0
+	ori	v1, v0, 0x3	/* way0 | write_enable | write_active */
+	mtcr	v1, t1
+2:
+	mfcr	v1, t1
+	andi	v1, 0x1		/* wait for write_active == 0 */
+	bnez	v1, 2b
+	nop
+	mtcr	zero, t0
+	ori	v1, v0, 0x7	/* way1 | write_enable | write_active */
+	mtcr	v1, t1
+3:
+	mfcr	v1, t1
+	andi	v1, 0x1		/* wait for write_active == 0 */
+	bnez	v1, 3b
+	nop
+	addi	t2, 1
+	bne	t3, t2, 1b
+	nop
+.endm
+
+/*
+ * nlm_reset_entry will be copied to the reset entry point for
+ * XLR and XLP. The XLP cores start here when they are woken up. This
+ * is also the NMI entry point.
+ *
+ * We use scratch reg 6/7 to save k0/k1 and check for NMI first.
+ *
+ * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS
+ * location, this will have the thread mask (used when core is woken up)
+ * and the current NMI handler in case we reached here for an NMI.
+ *
+ * When a core or thread is newly woken up, it marks itself ready and
+ * loops in a 'wait'. When the CPU really needs waking up, we send an NMI
+ * IPI to it, with the NMI handler set to prom_boot_secondary_cpus
+ */
+	.set	noreorder
+	.set	noat
+	.set	arch=xlr	/* for mfcr/mtcr, XLR is sufficient */
+
+FEXPORT(nlm_reset_entry)
+	dmtc0	k0, $22, 6
+	dmtc0	k1, $22, 7
+	mfc0	k0, CP0_STATUS
+	li	k1, 0x80000
+	and	k1, k0, k1
+	beqz	k1, 1f		/* go to real reset entry */
+	nop
+	li	k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
+	ld	k0, BOOT_NMI_HANDLER(k1)
+	jr	k0
+	nop
+
+1:	/* Entry point on core wakeup */
+	mfc0	t0, CP0_EBASE, 1
+	mfc0	t1, CP0_EBASE, 1
+	srl	t1, 5
+	andi	t1, 0x3			/* t1 <- node */
+	li	t2, 0x40000
+	mul	t3, t2, t1		/* t3 = node * 0x40000 */
+	srl	t0, t0, 2
+	and	t0, t0, 0x7		/* t0 <- core */
+	li	t1, 0x1
+	sll	t0, t1, t0
+	nor	t0, t0, zero		/* t0 <- ~(1 << core) */
+	li	t2, SYS_CPU_COHERENT_BASE(0)
+	add	t2, t2, t3		/* t2 <- SYS offset for node */
+	lw	t1, 0(t2)
+	and	t1, t1, t0
+	sw	t1, 0(t2)
+
+	/* read back to ensure complete */
+	lw	t1, 0(t2)
+	sync
+
+	/* Configure LSU on Non-0 Cores. */
+	xlp_config_lsu
+	/* FALL THROUGH */
+
+/*
+ * Wake up sibling threads from the initial thread in
+ * a core.
+ */
+EXPORT(nlm_boot_siblings)
+	/* core L1D flush before enable threads */
+	xlp_flush_l1_dcache
+	/* Enable hw threads by writing to MAP_THREADMODE of the core */
+	li	t0, CKSEG1ADDR(RESET_DATA_PHYS)
+	lw	t1, BOOT_THREAD_MODE(t0)	/* t1 <- thread mode */
+	li	t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
+	mfcr	t2, t0
+	or	t2, t2, t1
+	mtcr	t2, t0
+
+	/*
+	 * The new hardware thread starts at the next instruction
+	 * For all the cases other than core 0 thread 0, we will
+	* jump to the secondary wait function.
+	*/
+	mfc0	v0, CP0_EBASE, 1
+	andi	v0, 0x3ff		/* v0 <- node/core */
+
+	beqz	v0, 4f		/* boot cpu (cpuid == 0)? */
+	nop
+
+	/* setup status reg */
+	move	t1, zero
+#ifdef CONFIG_64BIT
+	ori	t1, ST0_KX
+#endif
+	mtc0	t1, CP0_STATUS
+
+	/* mark CPU ready, careful here, previous mtcr trashed registers */
+	li	t3, CKSEG1ADDR(RESET_DATA_PHYS)
+	ADDIU	t1, t3, BOOT_CPU_READY
+	sll	v1, v0, 2
+	PTR_ADDU t1, v1
+	li	t2, 1
+	sw	t2, 0(t1)
+	/* Wait until NMI hits */
+3:	wait
+	b	3b
+	nop
+
+	/*
+	 * For the boot CPU, we have to restore registers and
+	 * return
+	 */
+4:	dmfc0	t0, $4, 2	/* restore SP from UserLocal */
+	li	t1, 0xfadebeef
+	dmtc0	t1, $4, 2	/* restore SP from UserLocal */
+	PTR_SUBU sp, t0, PT_SIZE
+	RESTORE_ALL
+	jr	ra
+	nop
+EXPORT(nlm_reset_entry_end)
+
+LEAF(nlm_init_boot_cpu)
+#ifdef CONFIG_CPU_XLP
+	xlp_config_lsu
+#endif
+	jr	ra
+	nop
+END(nlm_init_boot_cpu)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/common/smpboot.S linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/smpboot.S
--- linux-libre-3.10-gnu/arch/mips/netlogic/common/smpboot.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/smpboot.S	2013-08-25 20:43:22.000000000 -0400
@@ -50,197 +50,12 @@
 #include <asm/netlogic/xlp-hal/cpucontrol.h>
 
 #define CP0_EBASE	$15
-#define SYS_CPU_COHERENT_BASE(node)	CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
-			XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
-			SYS_CPU_NONCOHERENT_MODE * 4
-
-#define XLP_AX_WORKAROUND	/* enable Ax silicon workarounds */
-
-/* Enable XLP features and workarounds in the LSU */
-.macro xlp_config_lsu
-	li	t0, LSU_DEFEATURE
-	mfcr	t1, t0
-
-	lui	t2, 0xc080	/* SUE, Enable Unaligned Access, L2HPE */
-	or	t1, t1, t2
-#ifdef XLP_AX_WORKAROUND
-	li	t2, ~0xe	/* S1RCM */
-	and	t1, t1, t2
-#endif
-	mtcr	t1, t0
-
-	li	t0, ICU_DEFEATURE
-	mfcr	t1, t0
-	ori	t1, 0x1000	/* Enable Icache partitioning */
-	mtcr	t1, t0
-
-
-#ifdef XLP_AX_WORKAROUND
-	li	t0, SCHED_DEFEATURE
-	lui	t1, 0x0100	/* Disable BRU accepting ALU ops */
-	mtcr	t1, t0
-#endif
-.endm
-
-/*
- * This is the code that will be copied to the reset entry point for
- * XLR and XLP. The XLP cores start here when they are woken up. This
- * is also the NMI entry point.
- */
-.macro	xlp_flush_l1_dcache
-	li	t0, LSU_DEBUG_DATA0
-	li	t1, LSU_DEBUG_ADDR
-	li	t2, 0		/* index */
-	li	t3, 0x1000	/* loop count */
-1:
-	sll	v0, t2, 5
-	mtcr	zero, t0
-	ori	v1, v0, 0x3	/* way0 | write_enable | write_active */
-	mtcr	v1, t1
-2:
-	mfcr	v1, t1
-	andi	v1, 0x1		/* wait for write_active == 0 */
-	bnez	v1, 2b
-	nop
-	mtcr	zero, t0
-	ori	v1, v0, 0x7	/* way1 | write_enable | write_active */
-	mtcr	v1, t1
-3:
-	mfcr	v1, t1
-	andi	v1, 0x1		/* wait for write_active == 0 */
-	bnez	v1, 3b
-	nop
-	addi	t2, 1
-	bne	t3, t2, 1b
-	nop
-.endm
-
-/*
- * The cores can come start when they are woken up. This is also the NMI
- * entry, so check that first.
- *
- * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS
- * location, this will have the thread mask (used when core is woken up)
- * and the current NMI handler in case we reached here for an NMI.
- *
- * When a core or thread is newly woken up, it loops in a 'wait'. When
- * the CPU really needs waking up, we send an NMI to it, with the NMI
- * handler set to prom_boot_secondary_cpus
- */
 
 	.set	noreorder
 	.set	noat
-	.set	arch=xlr	/* for mfcr/mtcr, XLR is sufficient */
-
-FEXPORT(nlm_reset_entry)
-	dmtc0	k0, $22, 6
-	dmtc0	k1, $22, 7
-	mfc0	k0, CP0_STATUS
-	li	k1, 0x80000
-	and	k1, k0, k1
-	beqz	k1, 1f		/* go to real reset entry */
-	nop
-	li	k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
-	ld	k0, BOOT_NMI_HANDLER(k1)
-	jr	k0
-	nop
-
-1:	/* Entry point on core wakeup */
-	mfc0	t0, CP0_EBASE, 1
-	mfc0	t1, CP0_EBASE, 1
-	srl	t1, 5
-	andi	t1, 0x3			/* t1 <- node */
-	li	t2, 0x40000
-	mul	t3, t2, t1		/* t3 = node * 0x40000 */
-	srl	t0, t0, 2
-	and	t0, t0, 0x7		/* t0 <- core */
-	li	t1, 0x1
-	sll	t0, t1, t0
-	nor	t0, t0, zero		/* t0 <- ~(1 << core) */
-	li	t2, SYS_CPU_COHERENT_BASE(0)
-	add	t2, t2, t3		/* t2 <- SYS offset for node */
-	lw	t1, 0(t2)
-	and	t1, t1, t0
-	sw	t1, 0(t2)
-
-	/* read back to ensure complete */
-	lw	t1, 0(t2)
-	sync
-
-	/* Configure LSU on Non-0 Cores. */
-	xlp_config_lsu
-	/* FALL THROUGH */
-
-/*
- * Wake up sibling threads from the initial thread in
- * a core.
- */
-EXPORT(nlm_boot_siblings)
-	/* core L1D flush before enable threads */
-	xlp_flush_l1_dcache
-	/* Enable hw threads by writing to MAP_THREADMODE of the core */
-	li	t0, CKSEG1ADDR(RESET_DATA_PHYS)
-	lw	t1, BOOT_THREAD_MODE(t0)	/* t1 <- thread mode */
-	li	t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
-	mfcr	t2, t0
-	or	t2, t2, t1
-	mtcr	t2, t0
-
-	/*
-	 * The new hardware thread starts at the next instruction
-	 * For all the cases other than core 0 thread 0, we will
-	* jump to the secondary wait function.
-	*/
-	mfc0	v0, CP0_EBASE, 1
-	andi	v0, 0x3ff		/* v0 <- node/core */
-
-	/* Init MMU in the first thread after changing THREAD_MODE
-	 * register (Ax Errata?)
-	 */
-	andi	v1, v0, 0x3		/* v1 <- thread id */
-	bnez	v1, 2f
-	nop
-
-	li	t0, MMU_SETUP
-	li	t1, 0
-	mtcr	t1, t0
-	_ehb
-
-2:	beqz	v0, 4f		/* boot cpu (cpuid == 0)? */
-	nop
-
-	/* setup status reg */
-	move	t1, zero
-#ifdef CONFIG_64BIT
-	ori	t1, ST0_KX
-#endif
-	mtc0	t1, CP0_STATUS
-	/* mark CPU ready */
-	PTR_LA	t1, nlm_cpu_ready
-	sll	v1, v0, 2
-	PTR_ADDU t1, v1
-	li	t2, 1
-	sw	t2, 0(t1)
-	/* Wait until NMI hits */
-3:	wait
-	j	3b
-	nop
-
-	/*
-	 * For the boot CPU, we have to restore registers and
-	 * return
-	 */
-4:	dmfc0	t0, $4, 2	/* restore SP from UserLocal */
-	li	t1, 0xfadebeef
-	dmtc0	t1, $4, 2	/* restore SP from UserLocal */
-	PTR_SUBU sp, t0, PT_SIZE
-	RESTORE_ALL
-	jr   ra
-	nop
-EXPORT(nlm_reset_entry_end)
+	.set	arch=xlr		/* for mfcr/mtcr, XLR is sufficient */
 
 FEXPORT(xlp_boot_core0_siblings)	/* "Master" cpu starts from here */
-	xlp_config_lsu
 	dmtc0	sp, $4, 2		/* SP saved in UserLocal */
 	SAVE_ALL
 	sync
@@ -255,7 +70,6 @@ FEXPORT(xlp_boot_core0_siblings)	/* "Mas
 	nop
 	/* not reached */
 
-	__CPUINIT
 NESTED(nlm_boot_secondary_cpus, 16, sp)
 	/* Initialize CP0 Status */
 	move	t1, zero
@@ -279,7 +93,6 @@ NESTED(nlm_boot_secondary_cpus, 16, sp)
 	jr	t0
 	nop
 END(nlm_boot_secondary_cpus)
-	__FINIT
 
 /*
  * In case of RMIboot bootloader which is used on XLR boards, the CPUs
@@ -287,15 +100,15 @@ END(nlm_boot_secondary_cpus)
  * This will get them out of the bootloader code and into linux. Needed
  *  because the bootloader area will be taken and initialized by linux.
  */
-	__CPUINIT
 NESTED(nlm_rmiboot_preboot, 16, sp)
 	mfc0	t0, $15, 1	/* read ebase */
 	andi	t0, 0x1f	/* t0 has the processor_id() */
 	andi	t2, t0, 0x3	/* thread num */
 	sll	t0, 2		/* offset in cpu array */
 
-	PTR_LA	t1, nlm_cpu_ready /* mark CPU ready */
-	PTR_ADDU t1, t0
+	li	t3, CKSEG1ADDR(RESET_DATA_PHYS)
+	ADDIU	t1, t3, BOOT_CPU_READY
+	ADDU	t1, t0
 	li	t3, 1
 	sw	t3, 0(t1)
 
@@ -321,7 +134,6 @@ NESTED(nlm_rmiboot_preboot, 16, sp)
 	mtcr	t1, t0		/* update core control */
 
 1:	wait
-	j	1b
+	b	1b
 	nop
 END(nlm_rmiboot_preboot)
-	__FINIT
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/common/smp.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/smp.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/common/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,7 +116,7 @@ void nlm_early_init_secondary(int cpu)
 /*
  * Code to run on secondary just after probing the CPU
  */
-static void __cpuinit nlm_init_secondary(void)
+static void nlm_init_secondary(void)
 {
 	int hwtid;
 
@@ -145,7 +145,6 @@ void nlm_cpus_done(void)
  * Boot all other cpus in the system, initialize them, and bring them into
  * the boot function
  */
-int nlm_cpu_ready[NR_CPUS];
 unsigned long nlm_next_gp;
 unsigned long nlm_next_sp;
 static cpumask_t phys_cpu_present_mask;
@@ -168,6 +167,7 @@ void __init nlm_smp_setup(void)
 {
 	unsigned int boot_cpu;
 	int num_cpus, i, ncore;
+	volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
 	char buf[64];
 
 	boot_cpu = hard_smp_processor_id();
@@ -181,10 +181,10 @@ void __init nlm_smp_setup(void)
 	num_cpus = 1;
 	for (i = 0; i < NR_CPUS; i++) {
 		/*
-		 * nlm_cpu_ready array is not set for the boot_cpu,
+		 * cpu_ready array is not set for the boot_cpu,
 		 * it is only set for ASPs (see smpboot.S)
 		 */
-		if (nlm_cpu_ready[i]) {
+		if (cpu_ready[i]) {
 			cpumask_set_cpu(i, &phys_cpu_present_mask);
 			__cpu_number_map[i] = num_cpus;
 			__cpu_logical_map[num_cpus] = i;
@@ -252,23 +252,17 @@ unsupp:
 	return 0;
 }
 
-int __cpuinit nlm_wakeup_secondary_cpus(void)
+int nlm_wakeup_secondary_cpus(void)
 {
-	unsigned long reset_vec;
-	char *reset_data;
+	u32 *reset_data;
 	int threadmode;
 
-	/* Update reset entry point with CPU init code */
-	reset_vec = CKSEG1ADDR(RESET_VEC_PHYS);
-	memcpy((void *)reset_vec, (void *)nlm_reset_entry,
-			(nlm_reset_entry_end - nlm_reset_entry));
-
 	/* verify the mask and setup core config variables */
 	threadmode = nlm_parse_cpumask(&nlm_cpumask);
 
 	/* Setup CPU init parameters */
-	reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
-	*(int *)(reset_data + BOOT_THREAD_MODE) = threadmode;
+	reset_data = nlm_get_boot_data(BOOT_THREAD_MODE);
+	*reset_data = threadmode;
 
 #ifdef CONFIG_CPU_XLP
 	xlp_wakeup_secondary_cpus();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/common/time.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/time.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/common/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/common/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@
 #error "Unknown CPU"
 #endif
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
 	return IRQ_TIMER;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/dts/xlp_evp.dts linux-libre-3.11-rc7-gnu/arch/mips/netlogic/dts/xlp_evp.dts
--- linux-libre-3.10-gnu/arch/mips/netlogic/dts/xlp_evp.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/dts/xlp_evp.dts	2013-08-25 20:43:22.000000000 -0400
@@ -76,10 +76,11 @@
 			};
 		};
 		pic: pic@4000 {
-			interrupt-controller;
+			compatible = "netlogic,xlp-pic";
 			#address-cells = <0>;
 			#interrupt-cells = <1>;
 			reg = <0 0x4000 0x200>;
+			interrupt-controller;
 		};
 
 		nor_flash@1,0 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/dts/xlp_svp.dts linux-libre-3.11-rc7-gnu/arch/mips/netlogic/dts/xlp_svp.dts
--- linux-libre-3.10-gnu/arch/mips/netlogic/dts/xlp_svp.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/dts/xlp_svp.dts	2013-08-25 20:43:22.000000000 -0400
@@ -76,10 +76,11 @@
 			};
 		};
 		pic: pic@4000 {
-			interrupt-controller;
+			compatible = "netlogic,xlp-pic";
 			#address-cells = <0>;
 			#interrupt-cells = <1>;
 			reg = <0 0x4000 0x200>;
+			interrupt-controller;
 		};
 
 		nor_flash@1,0 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/Kconfig linux-libre-3.11-rc7-gnu/arch/mips/netlogic/Kconfig
--- linux-libre-3.10-gnu/arch/mips/netlogic/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -51,4 +51,15 @@ endif
 config NLM_COMMON
 	bool
 
+config IOMMU_HELPER
+	bool
+
+config NEED_SG_DMA_LENGTH
+	bool
+
+config SWIOTLB
+	def_bool y
+	select NEED_SG_DMA_LENGTH
+	select IOMMU_HELPER
+
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/xlp/cop2-ex.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/cop2-ex.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/xlp/cop2-ex.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/cop2-ex.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,118 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Broadcom Corporation.
+ *
+ * based on arch/mips/cavium-octeon/cpu.c
+ * Copyright (C) 2009 Wind River Systems,
+ *   written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/init.h>
+#include <linux/irqflags.h>
+#include <linux/notifier.h>
+#include <linux/prefetch.h>
+#include <linux/sched.h>
+
+#include <asm/cop2.h>
+#include <asm/current.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+
+#include <asm/netlogic/mips-extns.h>
+
+/*
+ * 64 bit ops are done in inline assembly to support 32 bit
+ * compilation
+ */
+void nlm_cop2_save(struct nlm_cop2_state *r)
+{
+	asm volatile(
+		".set	push\n"
+		".set	noat\n"
+		"dmfc2	$1, $0, 0\n"
+		"sd	$1, 0(%1)\n"
+		"dmfc2	$1, $0, 1\n"
+		"sd	$1, 8(%1)\n"
+		"dmfc2	$1, $0, 2\n"
+		"sd	$1, 16(%1)\n"
+		"dmfc2	$1, $0, 3\n"
+		"sd	$1, 24(%1)\n"
+		"dmfc2	$1, $1, 0\n"
+		"sd	$1, 0(%2)\n"
+		"dmfc2	$1, $1, 1\n"
+		"sd	$1, 8(%2)\n"
+		"dmfc2	$1, $1, 2\n"
+		"sd	$1, 16(%2)\n"
+		"dmfc2	$1, $1, 3\n"
+		"sd	$1, 24(%2)\n"
+		".set	pop\n"
+		: "=m"(*r)
+		: "r"(r->tx), "r"(r->rx));
+
+	r->tx_msg_status = __read_32bit_c2_register($2, 0);
+	r->rx_msg_status = __read_32bit_c2_register($3, 0) & 0x0fffffff;
+}
+
+void nlm_cop2_restore(struct nlm_cop2_state *r)
+{
+	u32 rstat;
+
+	asm volatile(
+		".set	push\n"
+		".set	noat\n"
+		"ld	$1, 0(%1)\n"
+		"dmtc2	$1, $0, 0\n"
+		"ld	$1, 8(%1)\n"
+		"dmtc2	$1, $0, 1\n"
+		"ld	$1, 16(%1)\n"
+		"dmtc2	$1, $0, 2\n"
+		"ld	$1, 24(%1)\n"
+		"dmtc2	$1, $0, 3\n"
+		"ld	$1, 0(%2)\n"
+		"dmtc2	$1, $1, 0\n"
+		"ld	$1, 8(%2)\n"
+		"dmtc2	$1, $1, 1\n"
+		"ld	$1, 16(%2)\n"
+		"dmtc2	$1, $1, 2\n"
+		"ld	$1, 24(%2)\n"
+		"dmtc2	$1, $1, 3\n"
+		".set	pop\n"
+		: : "m"(*r), "r"(r->tx), "r"(r->rx));
+
+	__write_32bit_c2_register($2, 0, r->tx_msg_status);
+	rstat = __read_32bit_c2_register($3, 0) & 0xf0000000u;
+	__write_32bit_c2_register($3, 0, r->rx_msg_status | rstat);
+}
+
+static int nlm_cu2_call(struct notifier_block *nfb, unsigned long action,
+	void *data)
+{
+	unsigned long flags;
+	unsigned int status;
+
+	switch (action) {
+	case CU2_EXCEPTION:
+		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+			break;
+		local_irq_save(flags);
+		KSTK_STATUS(current) |= ST0_CU2;
+		status = read_c0_status();
+		write_c0_status(status | ST0_CU2);
+		nlm_cop2_restore(&(current->thread.cp2));
+		write_c0_status(status & ~ST0_CU2);
+		local_irq_restore(flags);
+		pr_info("COP2 access enabled for pid %d (%s)\n",
+					current->pid, current->comm);
+		return NOTIFY_BAD;	/* Don't call default notifier */
+	}
+
+	return NOTIFY_OK;		/* Let default notifier send signals */
+}
+
+static int __init nlm_cu2_setup(void)
+{
+	return cu2_notifier(nlm_cu2_call, 0);
+}
+early_initcall(nlm_cu2_setup);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/xlp/dt.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/dt.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/xlp/dt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/dt.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2003-2013 Broadcom Corporation.
+ * All Rights Reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bootmem.h>
+
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+
+extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_start[];
+
+void __init *xlp_dt_init(void *fdtp)
+{
+	if (!fdtp) {
+		switch (current_cpu_data.processor_id & 0xff00) {
+#ifdef CONFIG_DT_XLP_SVP
+		case PRID_IMP_NETLOGIC_XLP3XX:
+			fdtp = __dtb_xlp_svp_begin;
+			break;
+#endif
+#ifdef CONFIG_DT_XLP_EVP
+		case PRID_IMP_NETLOGIC_XLP8XX:
+			fdtp = __dtb_xlp_evp_begin;
+			break;
+#endif
+		default:
+			/* Pick a built-in if any, and hope for the best */
+			fdtp = __dtb_start;
+			break;
+		}
+	}
+	initial_boot_params = fdtp;
+	return fdtp;
+}
+
+void __init device_tree_init(void)
+{
+	unsigned long base, size;
+
+	if (!initial_boot_params)
+		return;
+
+	base = virt_to_phys((void *)initial_boot_params);
+	size = be32_to_cpu(initial_boot_params->totalsize);
+
+	/* Before we do anything, lets reserve the dt blob */
+	reserve_bootmem(base, size, BOOTMEM_DEFAULT);
+
+	unflatten_device_tree();
+
+	/* free the space reserved for the dt blob */
+	free_bootmem(base, size);
+}
+
+static struct of_device_id __initdata xlp_ids[] = {
+	{ .compatible = "simple-bus", },
+	{},
+};
+
+int __init xlp8xx_ds_publish_devices(void)
+{
+	if (!of_have_populated_dt())
+		return 0;
+	return of_platform_bus_probe(NULL, xlp_ids, NULL);
+}
+
+device_initcall(xlp8xx_ds_publish_devices);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/xlp/Makefile linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/Makefile
--- linux-libre-3.10-gnu/arch/mips/netlogic/xlp/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,3 +1,3 @@
-obj-y				+= setup.o nlm_hal.o
+obj-y				+= setup.o nlm_hal.o cop2-ex.o dt.o
 obj-$(CONFIG_SMP)		+= wakeup.o
 obj-$(CONFIG_USB)		+= usb-init.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/xlp/setup.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/setup.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/xlp/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,19 +33,13 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/serial_8250.h>
-#include <linux/pm.h>
-#include <linux/bootmem.h>
+#include <linux/of_fdt.h>
 
 #include <asm/idle.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/bootinfo.h>
 
-#include <linux/of_fdt.h>
-#include <linux/of_platform.h>
-#include <linux/of_device.h>
-
 #include <asm/netlogic/haldefs.h>
 #include <asm/netlogic/common.h>
 
@@ -57,7 +51,6 @@ uint64_t nlm_io_base;
 struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
 cpumask_t nlm_cpumask = CPU_MASK_CPU0;
 unsigned int nlm_threads_per_core;
-extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_start[];
 
 static void nlm_linux_exit(void)
 {
@@ -68,41 +61,28 @@ static void nlm_linux_exit(void)
 		cpu_wait();
 }
 
-void __init plat_mem_setup(void)
+static void nlm_fixup_mem(void)
 {
-	void *fdtp;
+	const int pref_backup = 512;
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+			continue;
+		boot_mem_map.map[i].size -= pref_backup;
+	}
+}
 
+void __init plat_mem_setup(void)
+{
 	panic_timeout	= 5;
 	_machine_restart = (void (*)(char *))nlm_linux_exit;
 	_machine_halt	= nlm_linux_exit;
 	pm_power_off	= nlm_linux_exit;
 
-	/*
-	 * If no FDT pointer is passed in, use the built-in FDT.
-	 * device_tree_init() does not handle CKSEG0 pointers in
-	 * 64-bit, so convert pointer.
-	 */
-	fdtp = (void *)(long)fw_arg0;
-	if (!fdtp) {
-		switch (current_cpu_data.processor_id & 0xff00) {
-#ifdef CONFIG_DT_XLP_SVP
-		case PRID_IMP_NETLOGIC_XLP3XX:
-			fdtp = __dtb_xlp_svp_begin;
-			break;
-#endif
-#ifdef CONFIG_DT_XLP_EVP
-		case PRID_IMP_NETLOGIC_XLP8XX:
-			fdtp = __dtb_xlp_evp_begin;
-			break;
-#endif
-		default:
-			/* Pick a built-in if any, and hope for the best */
-			fdtp = __dtb_start;
-			break;
-		}
-	}
-	fdtp = phys_to_virt(__pa(fdtp));
-	early_init_devtree(fdtp);
+	/* memory and bootargs from DT */
+	early_init_devtree(initial_boot_params);
+	nlm_fixup_mem();
 }
 
 const char *get_system_type(void)
@@ -131,9 +111,19 @@ void nlm_percpu_init(int hwcpuid)
 
 void __init prom_init(void)
 {
+	void *reset_vec;
+
 	nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
+	nlm_init_boot_cpu();
 	xlp_mmu_init();
 	nlm_node_init(0);
+	xlp_dt_init((void *)(long)fw_arg0);
+
+	/* Update reset entry point with CPU init code */
+	reset_vec = (void *)CKSEG1ADDR(RESET_VEC_PHYS);
+	memset(reset_vec, 0, RESET_VEC_SIZE);
+	memcpy(reset_vec, (void *)nlm_reset_entry,
+			(nlm_reset_entry_end - nlm_reset_entry));
 
 #ifdef CONFIG_SMP
 	cpumask_setall(&nlm_cpumask);
@@ -145,36 +135,3 @@ void __init prom_init(void)
 	register_smp_ops(&nlm_smp_ops);
 #endif
 }
-
-void __init device_tree_init(void)
-{
-	unsigned long base, size;
-
-	if (!initial_boot_params)
-		return;
-
-	base = virt_to_phys((void *)initial_boot_params);
-	size = be32_to_cpu(initial_boot_params->totalsize);
-
-	/* Before we do anything, lets reserve the dt blob */
-	reserve_bootmem(base, size, BOOTMEM_DEFAULT);
-
-	unflatten_device_tree();
-
-	/* free the space reserved for the dt blob */
-	free_bootmem(base, size);
-}
-
-static struct of_device_id __initdata xlp_ids[] = {
-	{ .compatible = "simple-bus", },
-	{},
-};
-
-int __init xlp8xx_ds_publish_devices(void)
-{
-	if (!of_have_populated_dt())
-		return 0;
-	return of_platform_bus_probe(NULL, xlp_ids, NULL);
-}
-
-device_initcall(xlp8xx_ds_publish_devices);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/xlp/usb-init.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/usb-init.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/xlp/usb-init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/usb-init.c	2013-08-25 20:43:22.000000000 -0400
@@ -119,7 +119,7 @@ static u64 xlp_usb_dmamask = ~(u32)0;
 static void nlm_usb_fixup_final(struct pci_dev *dev)
 {
 	dev->dev.dma_mask		= &xlp_usb_dmamask;
-	dev->dev.coherent_dma_mask	= DMA_BIT_MASK(64);
+	dev->dev.coherent_dma_mask	= DMA_BIT_MASK(32);
 	switch (dev->devfn) {
 	case 0x10:
 		dev->irq = PIC_EHCI_0_IRQ;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/xlp/wakeup.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/wakeup.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/xlp/wakeup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlp/wakeup.c	2013-08-25 20:43:22.000000000 -0400
@@ -77,12 +77,28 @@ static int xlp_wakeup_core(uint64_t sysb
 	return count != 0;
 }
 
+static int wait_for_cpus(int cpu, int bootcpu)
+{
+	volatile uint32_t *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
+	int i, count, notready;
+
+	count = 0x20000000;
+	do {
+		notready = nlm_threads_per_core;
+		for (i = 0; i < nlm_threads_per_core; i++)
+			if (cpu_ready[cpu + i] || cpu == bootcpu)
+				--notready;
+	} while (notready != 0 && --count > 0);
+
+	return count != 0;
+}
+
 static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
 {
 	struct nlm_soc_info *nodep;
 	uint64_t syspcibase;
 	uint32_t syscoremask;
-	int core, n, cpu, count, val;
+	int core, n, cpu;
 
 	for (n = 0; n < NLM_NR_NODES; n++) {
 		syspcibase = nlm_get_sys_pcibase(n);
@@ -122,11 +138,8 @@ static void xlp_enable_secondary_cores(c
 			/* core is up */
 			nodep->coremask |= 1u << core;
 
-			/* spin until the first hw thread sets its ready */
-			count = 0x20000000;
-			do {
-				val = *(volatile int *)&nlm_cpu_ready[cpu];
-			} while (val == 0 && --count > 0);
+			/* spin until the hw threads sets their ready */
+			wait_for_cpus(cpu, 0);
 		}
 	}
 }
@@ -138,6 +151,7 @@ void xlp_wakeup_secondary_cpus()
 	 * first wakeup core 0 threads
 	 */
 	xlp_boot_core0_siblings();
+	wait_for_cpus(0, 0);
 
 	/* now get other cores out of reset */
 	xlp_enable_secondary_cores(&nlm_cpumask);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/xlr/fmn.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlr/fmn.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/xlr/fmn.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlr/fmn.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,13 +74,13 @@ static irqreturn_t fmn_message_handler(i
 	struct nlm_fmn_msg msg;
 	uint32_t mflags, bkt_status;
 
-	mflags = nlm_cop2_enable();
+	mflags = nlm_cop2_enable_irqsave();
 	/* Disable message ring interrupt */
 	nlm_fmn_setup_intr(irq, 0);
 	while (1) {
 		/* 8 bkts per core, [24:31] each bit represents one bucket
 		 * Bit is Zero if bucket is not empty */
-		bkt_status = (nlm_read_c2_status() >> 24) & 0xff;
+		bkt_status = (nlm_read_c2_status0() >> 24) & 0xff;
 		if (bkt_status == 0xff)
 			break;
 		for (bucket = 0; bucket < 8; bucket++) {
@@ -97,16 +97,16 @@ static irqreturn_t fmn_message_handler(i
 				pr_warn("No msgring handler for stnid %d\n",
 						src_stnid);
 			else {
-				nlm_cop2_restore(mflags);
+				nlm_cop2_disable_irqrestore(mflags);
 				hndlr->action(bucket, src_stnid, size, code,
 					&msg, hndlr->arg);
-				mflags = nlm_cop2_enable();
+				mflags = nlm_cop2_enable_irqsave();
 			}
 		}
 	};
 	/* Enable message ring intr, to any thread in core */
 	nlm_fmn_setup_intr(irq, (1 << nlm_threads_per_core) - 1);
-	nlm_cop2_restore(mflags);
+	nlm_cop2_disable_irqrestore(mflags);
 	return IRQ_HANDLED;
 }
 
@@ -128,7 +128,7 @@ void xlr_percpu_fmn_init(void)
 
 	bucket_sizes = xlr_board_fmn_config.bucket_size;
 	cpu_fmn_info = &xlr_board_fmn_config.cpu[id];
-	flags = nlm_cop2_enable();
+	flags = nlm_cop2_enable_irqsave();
 
 	/* Setup bucket sizes for the core. */
 	nlm_write_c2_bucksize(0, bucket_sizes[id * 8 + 0]);
@@ -166,7 +166,7 @@ void xlr_percpu_fmn_init(void)
 
 	/* enable FMN interrupts on this CPU */
 	nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);
-	nlm_cop2_restore(flags);
+	nlm_cop2_disable_irqrestore(flags);
 }
 
 
@@ -198,7 +198,7 @@ void nlm_setup_fmn_irq(void)
 	/* setup irq only once */
 	setup_irq(IRQ_FMN, &fmn_irqaction);
 
-	flags = nlm_cop2_enable();
+	flags = nlm_cop2_enable_irqsave();
 	nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);
-	nlm_cop2_restore(flags);
+	nlm_cop2_disable_irqrestore(flags);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/xlr/setup.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlr/setup.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/xlr/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlr/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -196,6 +196,7 @@ void __init prom_init(void)
 {
 	int *argv, *envp;		/* passed as 32 bit ptrs */
 	struct psb_info *prom_infop;
+	void *reset_vec;
 #ifdef CONFIG_SMP
 	int i;
 #endif
@@ -208,6 +209,12 @@ void __init prom_init(void)
 	nlm_prom_info = *prom_infop;
 	nlm_init_node();
 
+	/* Update reset entry point with CPU init code */
+	reset_vec = (void *)CKSEG1ADDR(RESET_VEC_PHYS);
+	memset(reset_vec, 0, RESET_VEC_SIZE);
+	memcpy(reset_vec, (void *)nlm_reset_entry,
+			(nlm_reset_entry_end - nlm_reset_entry));
+
 	nlm_early_serial_setup();
 	build_arcs_cmdline(argv);
 	prom_add_memory();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/netlogic/xlr/wakeup.c linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlr/wakeup.c
--- linux-libre-3.10-gnu/arch/mips/netlogic/xlr/wakeup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/netlogic/xlr/wakeup.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,10 +49,11 @@
 #include <asm/netlogic/xlr/iomap.h>
 #include <asm/netlogic/xlr/pic.h>
 
-int __cpuinit xlr_wakeup_secondary_cpus(void)
+int xlr_wakeup_secondary_cpus(void)
 {
 	struct nlm_soc_info *nodep;
 	unsigned int i, j, boot_cpu;
+	volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
 
 	/*
 	 *  In case of RMI boot, hit with NMI to get the cores
@@ -71,7 +72,7 @@ int __cpuinit xlr_wakeup_secondary_cpus(
 	nodep->coremask = 1;
 	for (i = 1; i < NLM_CORES_PER_NODE; i++) {
 		for (j = 1000000; j > 0; j--) {
-			if (nlm_cpu_ready[i * NLM_THREADS_PER_CORE])
+			if (cpu_ready[i * NLM_THREADS_PER_CORE])
 				break;
 			udelay(10);
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/oprofile/op_model_mipsxx.c linux-libre-3.11-rc7-gnu/arch/mips/oprofile/op_model_mipsxx.c
--- linux-libre-3.10-gnu/arch/mips/oprofile/op_model_mipsxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/oprofile/op_model_mipsxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -166,7 +166,7 @@ static void mipsxx_reg_setup(struct op_c
 			reg.control[i] |= M_PERFCTL_USER;
 		if (ctr[i].exl)
 			reg.control[i] |= M_PERFCTL_EXL;
-		if (current_cpu_type() == CPU_XLR)
+		if (boot_cpu_type() == CPU_XLR)
 			reg.control[i] |= M_PERFCTL_COUNT_ALL_THREADS;
 		reg.counter[i] = 0x80000000 - ctr[i].count;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pci/fixup-wrppmc.c linux-libre-3.11-rc7-gnu/arch/mips/pci/fixup-wrppmc.c
--- linux-libre-3.10-gnu/arch/mips/pci/fixup-wrppmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pci/fixup-wrppmc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-/*
- * fixup-wrppmc.c: PPMC board specific PCI fixup
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006, Wind River Inc. Rongkai.zhan (rongkai.zhan@windriver.com)
- */
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/gt64120.h>
-
-/* PCI interrupt pins */
-#define PCI_INTA		1
-#define PCI_INTB		2
-#define PCI_INTC		3
-#define PCI_INTD		4
-
-#define PCI_SLOT_MAXNR	32 /* Each PCI bus has 32 physical slots */
-
-static char pci_irq_tab[PCI_SLOT_MAXNR][5] __initdata = {
-	/* 0	INTA   INTB   INTC   INTD */
-	[0] = {0, 0, 0, 0, 0},		/* Slot 0: GT64120 PCI bridge */
-	[6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0},
-};
-
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	return pci_irq_tab[slot][pin];
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-	return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pci/Makefile linux-libre-3.11-rc7-gnu/arch/mips/pci/Makefile
--- linux-libre-3.10-gnu/arch/mips/pci/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pci/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,7 @@ obj-$(CONFIG_LASAT)		+= pci-lasat.o
 obj-$(CONFIG_MIPS_COBALT)	+= fixup-cobalt.o
 obj-$(CONFIG_LEMOTE_FULOONG2E)	+= fixup-fuloong2e.o ops-loongson2.o
 obj-$(CONFIG_LEMOTE_MACH2F)	+= fixup-lemote2f.o ops-loongson2.o
-obj-$(CONFIG_MIPS_MALTA)	+= fixup-malta.o
+obj-$(CONFIG_MIPS_MALTA)	+= fixup-malta.o pci-malta.o
 obj-$(CONFIG_PMC_MSP7120_GW)	+= fixup-pmcmsp.o ops-pmcmsp.o
 obj-$(CONFIG_PMC_MSP7120_EVAL)	+= fixup-pmcmsp.o ops-pmcmsp.o
 obj-$(CONFIG_PMC_MSP7120_FPGA)	+= fixup-pmcmsp.o ops-pmcmsp.o
@@ -52,12 +52,11 @@ obj-$(CONFIG_TOSHIBA_RBTX4927)	+= fixup-
 obj-$(CONFIG_TOSHIBA_RBTX4938)	+= fixup-rbtx4938.o
 obj-$(CONFIG_VICTOR_MPC30X)	+= fixup-mpc30x.o
 obj-$(CONFIG_ZAO_CAPCELLA)	+= fixup-capcella.o
-obj-$(CONFIG_WR_PPMC)		+= fixup-wrppmc.o
 obj-$(CONFIG_MIKROTIK_RB532)	+= pci-rc32434.o ops-rc32434.o fixup-rc32434.o
-obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o
+obj-$(CONFIG_CAVIUM_OCTEON_SOC) += pci-octeon.o pcie-octeon.o
 obj-$(CONFIG_CPU_XLR)		+= pci-xlr.o
 obj-$(CONFIG_CPU_XLP)		+= pci-xlp.o
 
 ifdef CONFIG_PCI_MSI
-obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o
+obj-$(CONFIG_CAVIUM_OCTEON_SOC) += msi-octeon.o
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pci/pci-bcm1480.c linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-bcm1480.c
--- linux-libre-3.10-gnu/arch/mips/pci/pci-bcm1480.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-bcm1480.c	2013-08-25 20:43:22.000000000 -0400
@@ -257,7 +257,9 @@ static int __init bcm1480_pcibios_init(v
 	register_pci_controller(&bcm1480_controller);
 
 #ifdef CONFIG_VGA_CONSOLE
-	take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1);
+	console_lock();
+	do_take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1);
+	console_unlock();
 #endif
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pci/pci-bcm63xx.c linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-bcm63xx.c
--- linux-libre-3.10-gnu/arch/mips/pci/pci-bcm63xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-bcm63xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -266,7 +266,7 @@ static int __init bcm63xx_register_pci(v
 	/* setup PCI to local bus access, used by PCI device to target
 	 * local RAM while bus mastering */
 	bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3);
-	if (BCMCPU_IS_6358() || BCMCPU_IS_6368())
+	if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368())
 		val = MPI_SP0_REMAP_ENABLE_MASK;
 	else
 		val = 0;
@@ -338,6 +338,7 @@ static int __init bcm63xx_pci_init(void)
 	case BCM6328_CPU_ID:
 	case BCM6362_CPU_ID:
 		return bcm63xx_register_pcie();
+	case BCM3368_CPU_ID:
 	case BCM6348_CPU_ID:
 	case BCM6358_CPU_ID:
 	case BCM6368_CPU_ID:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pci/pci-ip27.c linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-ip27.c
--- linux-libre-3.10-gnu/arch/mips/pci/pci-ip27.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-ip27.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,7 +42,7 @@ int irq_to_slot[MAX_PCI_BUSSES * MAX_DEV
 
 extern struct pci_ops bridge_pci_ops;
 
-int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid)
+int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
 {
 	unsigned long offset = NODE_OFFSET(nasid);
 	struct bridge_controller *bc;
@@ -217,6 +217,7 @@ static void pci_fixup_ioc3(struct pci_de
 	pci_disable_swapping(d);
 }
 
+#ifdef CONFIG_NUMA
 int pcibus_to_node(struct pci_bus *bus)
 {
 	struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
@@ -224,6 +225,7 @@ int pcibus_to_node(struct pci_bus *bus)
 	return bc->nasid;
 }
 EXPORT_SYMBOL(pcibus_to_node);
+#endif /* CONFIG_NUMA */
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
 	pci_fixup_ioc3);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pci/pci-lantiq.c linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-lantiq.c
--- linux-libre-3.10-gnu/arch/mips/pci/pci-lantiq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-lantiq.c	2013-08-25 20:43:22.000000000 -0400
@@ -89,7 +89,7 @@ static inline u32 ltq_calc_bar11mask(voi
 	u32 mem, bar11mask;
 
 	/* BAR11MASK value depends on available memory on system. */
-	mem = num_physpages * PAGE_SIZE;
+	mem = get_num_physpages() * PAGE_SIZE;
 	bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) - 1)) - 1)) | 8;
 
 	return bar11mask;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pci/pci-malta.c linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-malta.c
--- linux-libre-3.10-gnu/arch/mips/pci/pci-malta.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-malta.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 1999, 2000, 2004, 2005	 MIPS Technologies, Inc.
+ *	All rights reserved.
+ *	Authors: Carsten Langgaard <carstenl@mips.com>
+ *		 Maciej W. Rozycki <macro@mips.com>
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS boards specific PCI support.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/gt64120.h>
+#include <asm/gcmpregs.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/bonito64.h>
+#include <asm/mips-boards/msc01_pci.h>
+
+static struct resource bonito64_mem_resource = {
+	.name	= "Bonito PCI MEM",
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource bonito64_io_resource = {
+	.name	= "Bonito PCI I/O",
+	.start	= 0x00000000UL,
+	.end	= 0x000fffffUL,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource gt64120_mem_resource = {
+	.name	= "GT-64120 PCI MEM",
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource gt64120_io_resource = {
+	.name	= "GT-64120 PCI I/O",
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource msc_mem_resource = {
+	.name	= "MSC PCI MEM",
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource msc_io_resource = {
+	.name	= "MSC PCI I/O",
+	.flags	= IORESOURCE_IO,
+};
+
+extern struct pci_ops bonito64_pci_ops;
+extern struct pci_ops gt64xxx_pci0_ops;
+extern struct pci_ops msc_pci_ops;
+
+static struct pci_controller bonito64_controller = {
+	.pci_ops	= &bonito64_pci_ops,
+	.io_resource	= &bonito64_io_resource,
+	.mem_resource	= &bonito64_mem_resource,
+	.io_offset	= 0x00000000UL,
+};
+
+static struct pci_controller gt64120_controller = {
+	.pci_ops	= &gt64xxx_pci0_ops,
+	.io_resource	= &gt64120_io_resource,
+	.mem_resource	= &gt64120_mem_resource,
+};
+
+static struct pci_controller msc_controller = {
+	.pci_ops	= &msc_pci_ops,
+	.io_resource	= &msc_io_resource,
+	.mem_resource	= &msc_mem_resource,
+};
+
+void __init mips_pcibios_init(void)
+{
+	struct pci_controller *controller;
+	resource_size_t start, end, map, start1, end1, map1, map2, map3, mask;
+
+	switch (mips_revision_sconid) {
+	case MIPS_REVISION_SCON_GT64120:
+		/*
+		 * Due to a bug in the Galileo system controller, we need
+		 * to setup the PCI BAR for the Galileo internal registers.
+		 * This should be done in the bios/bootprom and will be
+		 * fixed in a later revision of YAMON (the MIPS boards
+		 * boot prom).
+		 */
+		GT_WRITE(GT_PCI0_CFGADDR_OFS,
+			 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
+			 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
+			 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
+			 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
+			 GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+		/* Perform the write */
+		GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
+
+		/* Set up resource ranges from the controller's registers.  */
+		start = GT_READ(GT_PCI0M0LD_OFS);
+		end = GT_READ(GT_PCI0M0HD_OFS);
+		map = GT_READ(GT_PCI0M0REMAP_OFS);
+		end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+		start1 = GT_READ(GT_PCI0M1LD_OFS);
+		end1 = GT_READ(GT_PCI0M1HD_OFS);
+		map1 = GT_READ(GT_PCI0M1REMAP_OFS);
+		end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
+		/* Cannot support multiple windows, use the wider.  */
+		if (end1 - start1 > end - start) {
+			start = start1;
+			end = end1;
+			map = map1;
+		}
+		mask = ~(start ^ end);
+		/* We don't support remapping with a discontiguous mask.  */
+		BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+		       mask != ~((mask & -mask) - 1));
+		gt64120_mem_resource.start = start;
+		gt64120_mem_resource.end = end;
+		gt64120_controller.mem_offset = (start & mask) - (map & mask);
+		/* Addresses are 36-bit, so do shifts in the destinations.  */
+		gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
+		gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
+		gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+		gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
+
+		start = GT_READ(GT_PCI0IOLD_OFS);
+		end = GT_READ(GT_PCI0IOHD_OFS);
+		map = GT_READ(GT_PCI0IOREMAP_OFS);
+		end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+		mask = ~(start ^ end);
+		/* We don't support remapping with a discontiguous mask.  */
+		BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+		       mask != ~((mask & -mask) - 1));
+		gt64120_io_resource.start = map & mask;
+		gt64120_io_resource.end = (map & mask) | ~mask;
+		gt64120_controller.io_offset = 0;
+		/* Addresses are 36-bit, so do shifts in the destinations.  */
+		gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
+		gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
+		gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+
+		controller = &gt64120_controller;
+		break;
+
+	case MIPS_REVISION_SCON_BONITO:
+		/* Set up resource ranges from the controller's registers.  */
+		map = BONITO_PCIMAP;
+		map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >>
+		       BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
+		map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >>
+		       BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
+		map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >>
+		       BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
+		/* Combine as many adjacent windows as possible.  */
+		map = map1;
+		start = BONITO_PCILO0_BASE;
+		end = 1;
+		if (map3 == map2 + 1) {
+			map = map2;
+			start = BONITO_PCILO1_BASE;
+			end++;
+		}
+		if (map2 == map1 + 1) {
+			map = map1;
+			start = BONITO_PCILO0_BASE;
+			end++;
+		}
+		bonito64_mem_resource.start = start;
+		bonito64_mem_resource.end = start +
+					    BONITO_PCIMAP_WINBASE(end) - 1;
+		bonito64_controller.mem_offset = start -
+						 BONITO_PCIMAP_WINBASE(map);
+
+		controller = &bonito64_controller;
+		break;
+
+	case MIPS_REVISION_SCON_SOCIT:
+	case MIPS_REVISION_SCON_ROCIT:
+	case MIPS_REVISION_SCON_SOCITSC:
+	case MIPS_REVISION_SCON_SOCITSCP:
+		/* Set up resource ranges from the controller's registers.  */
+		MSC_READ(MSC01_PCI_SC2PMBASL, start);
+		MSC_READ(MSC01_PCI_SC2PMMSKL, mask);
+		MSC_READ(MSC01_PCI_SC2PMMAPL, map);
+		msc_mem_resource.start = start & mask;
+		msc_mem_resource.end = (start & mask) | ~mask;
+		msc_controller.mem_offset = (start & mask) - (map & mask);
+#ifdef CONFIG_MIPS_CMP
+		if (gcmp_niocu())
+			gcmp_setregion(0, start, mask,
+				GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
+#endif
+		MSC_READ(MSC01_PCI_SC2PIOBASL, start);
+		MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
+		MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
+		msc_io_resource.start = map & mask;
+		msc_io_resource.end = (map & mask) | ~mask;
+		msc_controller.io_offset = 0;
+		ioport_resource.end = ~mask;
+#ifdef CONFIG_MIPS_CMP
+		if (gcmp_niocu())
+			gcmp_setregion(1, start, mask,
+				GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
+#endif
+		/* If ranges overlap I/O takes precedence.  */
+		start = start & mask;
+		end = start | ~mask;
+		if ((start >= msc_mem_resource.start &&
+		     start <= msc_mem_resource.end) ||
+		    (end >= msc_mem_resource.start &&
+		     end <= msc_mem_resource.end)) {
+			/* Use the larger space.  */
+			start = max(start, msc_mem_resource.start);
+			end = min(end, msc_mem_resource.end);
+			if (start - msc_mem_resource.start >=
+			    msc_mem_resource.end - end)
+				msc_mem_resource.end = start - 1;
+			else
+				msc_mem_resource.start = end + 1;
+		}
+
+		controller = &msc_controller;
+		break;
+	default:
+		return;
+	}
+
+	/* Change start address to avoid conflicts with ACPI and SMB devices */
+	if (controller->io_resource->start < 0x00002000UL)
+		controller->io_resource->start = 0x00002000UL;
+
+	iomem_resource.end &= 0xfffffffffULL;			/* 64 GB */
+	ioport_resource.end = controller->io_resource->end;
+
+	controller->io_map_base = mips_io_port_base;
+
+	register_pci_controller(controller);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pci/pci-sb1250.c linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-sb1250.c
--- linux-libre-3.10-gnu/arch/mips/pci/pci-sb1250.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pci/pci-sb1250.c	2013-08-25 20:43:22.000000000 -0400
@@ -283,7 +283,9 @@ static int __init sb1250_pcibios_init(vo
 	register_pci_controller(&sb1250_controller);
 
 #ifdef CONFIG_VGA_CONSOLE
-	take_over_console(&vga_con, 0, MAX_NR_CONSOLES - 1, 1);
+	console_lock();
+	do_take_over_console(&vga_con, 0, MAX_NR_CONSOLES - 1, 1);
+	console_unlock();
 #endif
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/gpio.c linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/gpio.c
--- linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,216 +0,0 @@
-/*
- * Generic PMC MSP71xx GPIO handling. These base gpio are controlled by two
- * types of registers. The data register sets the output level when in output
- * mode and when in input mode will contain the value at the input. The config
- * register sets the various modes for each gpio.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * @author Patrick Glass <patrickglass@gmail.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-
-#define MSP71XX_CFG_OFFSET(gpio)	(4 * (gpio))
-#define CONF_MASK			0x0F
-#define MSP71XX_GPIO_INPUT		0x01
-#define MSP71XX_GPIO_OUTPUT		0x08
-
-#define MSP71XX_GPIO_BASE		0x0B8400000L
-
-#define to_msp71xx_gpio_chip(c) container_of(c, struct msp71xx_gpio_chip, chip)
-
-static spinlock_t gpio_lock;
-
-/*
- * struct msp71xx_gpio_chip - container for gpio chip and registers
- * @chip: chip structure for the specified gpio bank
- * @data_reg: register for reading and writing the gpio pin value
- * @config_reg: register to set the mode for the gpio pin bank
- * @out_drive_reg: register to set the output drive mode for the gpio pin bank
- */
-struct msp71xx_gpio_chip {
-	struct gpio_chip chip;
-	void __iomem *data_reg;
-	void __iomem *config_reg;
-	void __iomem *out_drive_reg;
-};
-
-/*
- * msp71xx_gpio_get() - return the chip's gpio value
- * @chip: chip structure which controls the specified gpio
- * @offset: gpio whose value will be returned
- *
- * It will return 0 if gpio value is low and other if high.
- */
-static int msp71xx_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip);
-
-	return __raw_readl(msp_chip->data_reg) & (1 << offset);
-}
-
-/*
- * msp71xx_gpio_set() - set the output value for the gpio
- * @chip: chip structure who controls the specified gpio
- * @offset: gpio whose value will be assigned
- * @value: logic level to assign to the gpio initially
- *
- * This will set the gpio bit specified to the desired value. It will set the
- * gpio pin low if value is 0 otherwise it will be high.
- */
-static void msp71xx_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-	struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip);
-	unsigned long flags;
-	u32 data;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-
-	data = __raw_readl(msp_chip->data_reg);
-	if (value)
-		data |= (1 << offset);
-	else
-		data &= ~(1 << offset);
-	__raw_writel(data, msp_chip->data_reg);
-
-	spin_unlock_irqrestore(&gpio_lock, flags);
-}
-
-/*
- * msp71xx_set_gpio_mode() - declare the mode for a gpio
- * @chip: chip structure which controls the specified gpio
- * @offset: gpio whose value will be assigned
- * @mode: desired configuration for the gpio (see datasheet)
- *
- * It will set the gpio pin config to the @mode value passed in.
- */
-static int msp71xx_set_gpio_mode(struct gpio_chip *chip,
-				 unsigned offset, int mode)
-{
-	struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip);
-	const unsigned bit_offset = MSP71XX_CFG_OFFSET(offset);
-	unsigned long flags;
-	u32 cfg;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-
-	cfg = __raw_readl(msp_chip->config_reg);
-	cfg &= ~(CONF_MASK << bit_offset);
-	cfg |= (mode << bit_offset);
-	__raw_writel(cfg, msp_chip->config_reg);
-
-	spin_unlock_irqrestore(&gpio_lock, flags);
-
-	return 0;
-}
-
-/*
- * msp71xx_direction_output() - declare the direction mode for a gpio
- * @chip: chip structure which controls the specified gpio
- * @offset: gpio whose value will be assigned
- * @value: logic level to assign to the gpio initially
- *
- * This call will set the mode for the @gpio to output. It will set the
- * gpio pin low if value is 0 otherwise it will be high.
- */
-static int msp71xx_direction_output(struct gpio_chip *chip,
-				    unsigned offset, int value)
-{
-	msp71xx_gpio_set(chip, offset, value);
-
-	return msp71xx_set_gpio_mode(chip, offset, MSP71XX_GPIO_OUTPUT);
-}
-
-/*
- * msp71xx_direction_input() - declare the direction mode for a gpio
- * @chip: chip structure which controls the specified gpio
- * @offset: gpio whose to which the value will be assigned
- *
- * This call will set the mode for the @gpio to input.
- */
-static int msp71xx_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	return msp71xx_set_gpio_mode(chip, offset, MSP71XX_GPIO_INPUT);
-}
-
-/*
- * msp71xx_set_output_drive() - declare the output drive for the gpio line
- * @gpio: gpio pin whose output drive you wish to modify
- * @value: zero for active drain 1 for open drain drive
- *
- * This call will set the output drive mode for the @gpio to output.
- */
-int msp71xx_set_output_drive(unsigned gpio, int value)
-{
-	unsigned long flags;
-	u32 data;
-
-	if (gpio > 15 || gpio < 0)
-		return -EINVAL;
-
-	spin_lock_irqsave(&gpio_lock, flags);
-
-	data = __raw_readl((void __iomem *)(MSP71XX_GPIO_BASE + 0x190));
-	if (value)
-		data |= (1 << gpio);
-	else
-		data &= ~(1 << gpio);
-	__raw_writel(data, (void __iomem *)(MSP71XX_GPIO_BASE + 0x190));
-
-	spin_unlock_irqrestore(&gpio_lock, flags);
-
-	return 0;
-}
-EXPORT_SYMBOL(msp71xx_set_output_drive);
-
-#define MSP71XX_GPIO_BANK(name, dr, cr, base_gpio, num_gpio) \
-{ \
-	.chip = { \
-		.label		  = name, \
-		.direction_input  = msp71xx_direction_input, \
-		.direction_output = msp71xx_direction_output, \
-		.get		  = msp71xx_gpio_get, \
-		.set		  = msp71xx_gpio_set, \
-		.base		  = base_gpio, \
-		.ngpio		  = num_gpio \
-	}, \
-	.data_reg	= (void __iomem *)(MSP71XX_GPIO_BASE + dr), \
-	.config_reg	= (void __iomem *)(MSP71XX_GPIO_BASE + cr), \
-	.out_drive_reg	= (void __iomem *)(MSP71XX_GPIO_BASE + 0x190), \
-}
-
-/*
- * struct msp71xx_gpio_banks[] - container array of gpio banks
- * @chip: chip structure for the specified gpio bank
- * @data_reg: register for reading and writing the gpio pin value
- * @config_reg: register to set the mode for the gpio pin bank
- *
- * This array structure defines the gpio banks for the PMC MIPS Processor.
- * We specify the bank name, the data register, the config register, base
- * starting gpio number, and the number of gpios exposed by the bank.
- */
-static struct msp71xx_gpio_chip msp71xx_gpio_banks[] = {
-
-	MSP71XX_GPIO_BANK("GPIO_1_0", 0x170, 0x180, 0, 2),
-	MSP71XX_GPIO_BANK("GPIO_5_2", 0x174, 0x184, 2, 4),
-	MSP71XX_GPIO_BANK("GPIO_9_6", 0x178, 0x188, 6, 4),
-	MSP71XX_GPIO_BANK("GPIO_15_10", 0x17C, 0x18C, 10, 6),
-};
-
-void __init msp71xx_init_gpio(void)
-{
-	int i;
-
-	spin_lock_init(&gpio_lock);
-
-	for (i = 0; i < ARRAY_SIZE(msp71xx_gpio_banks); i++)
-		gpiochip_add(&msp71xx_gpio_banks[i].chip);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/gpio_extended.c linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/gpio_extended.c
--- linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/gpio_extended.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/gpio_extended.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,146 +0,0 @@
-/*
- * Generic PMC MSP71xx EXTENDED (EXD) GPIO handling. The extended gpio is
- * a set of hardware registers that have no need for explicit locking as
- * it is handled by unique method of writing individual set/clr bits.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * @author Patrick Glass <patrickglass@gmail.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#define MSP71XX_DATA_OFFSET(gpio)	(2 * (gpio))
-#define MSP71XX_READ_OFFSET(gpio)	(MSP71XX_DATA_OFFSET(gpio) + 1)
-#define MSP71XX_CFG_OUT_OFFSET(gpio)	(MSP71XX_DATA_OFFSET(gpio) + 16)
-#define MSP71XX_CFG_IN_OFFSET(gpio)	(MSP71XX_CFG_OUT_OFFSET(gpio) + 1)
-
-#define MSP71XX_EXD_GPIO_BASE	0x0BC000000L
-
-#define to_msp71xx_exd_gpio_chip(c) \
-			container_of(c, struct msp71xx_exd_gpio_chip, chip)
-
-/*
- * struct msp71xx_exd_gpio_chip - container for gpio chip and registers
- * @chip: chip structure for the specified gpio bank
- * @reg: register for control and data of gpio pin
- */
-struct msp71xx_exd_gpio_chip {
-	struct gpio_chip chip;
-	void __iomem *reg;
-};
-
-/*
- * msp71xx_exd_gpio_get() - return the chip's gpio value
- * @chip: chip structure which controls the specified gpio
- * @offset: gpio whose value will be returned
- *
- * It will return 0 if gpio value is low and other if high.
- */
-static int msp71xx_exd_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	struct msp71xx_exd_gpio_chip *msp71xx_chip =
-	    to_msp71xx_exd_gpio_chip(chip);
-	const unsigned bit = MSP71XX_READ_OFFSET(offset);
-
-	return __raw_readl(msp71xx_chip->reg) & (1 << bit);
-}
-
-/*
- * msp71xx_exd_gpio_set() - set the output value for the gpio
- * @chip: chip structure who controls the specified gpio
- * @offset: gpio whose value will be assigned
- * @value: logic level to assign to the gpio initially
- *
- * This will set the gpio bit specified to the desired value. It will set the
- * gpio pin low if value is 0 otherwise it will be high.
- */
-static void msp71xx_exd_gpio_set(struct gpio_chip *chip,
-				 unsigned offset, int value)
-{
-	struct msp71xx_exd_gpio_chip *msp71xx_chip =
-	    to_msp71xx_exd_gpio_chip(chip);
-	const unsigned bit = MSP71XX_DATA_OFFSET(offset);
-
-	__raw_writel(1 << (bit + (value ? 1 : 0)), msp71xx_chip->reg);
-}
-
-/*
- * msp71xx_exd_direction_output() - declare the direction mode for a gpio
- * @chip: chip structure which controls the specified gpio
- * @offset: gpio whose value will be assigned
- * @value: logic level to assign to the gpio initially
- *
- * This call will set the mode for the @gpio to output. It will set the
- * gpio pin low if value is 0 otherwise it will be high.
- */
-static int msp71xx_exd_direction_output(struct gpio_chip *chip,
-					unsigned offset, int value)
-{
-	struct msp71xx_exd_gpio_chip *msp71xx_chip =
-	    to_msp71xx_exd_gpio_chip(chip);
-
-	msp71xx_exd_gpio_set(chip, offset, value);
-	__raw_writel(1 << MSP71XX_CFG_OUT_OFFSET(offset), msp71xx_chip->reg);
-	return 0;
-}
-
-/*
- * msp71xx_exd_direction_input() - declare the direction mode for a gpio
- * @chip: chip structure which controls the specified gpio
- * @offset: gpio whose to which the value will be assigned
- *
- * This call will set the mode for the @gpio to input.
- */
-static int msp71xx_exd_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct msp71xx_exd_gpio_chip *msp71xx_chip =
-	    to_msp71xx_exd_gpio_chip(chip);
-
-	__raw_writel(1 << MSP71XX_CFG_IN_OFFSET(offset), msp71xx_chip->reg);
-	return 0;
-}
-
-#define MSP71XX_EXD_GPIO_BANK(name, exd_reg, base_gpio, num_gpio) \
-{ \
-	.chip = { \
-		.label		  = name, \
-		.direction_input  = msp71xx_exd_direction_input, \
-		.direction_output = msp71xx_exd_direction_output, \
-		.get		  = msp71xx_exd_gpio_get, \
-		.set		  = msp71xx_exd_gpio_set, \
-		.base		  = base_gpio, \
-		.ngpio		  = num_gpio, \
-	}, \
-	.reg	= (void __iomem *)(MSP71XX_EXD_GPIO_BASE + exd_reg), \
-}
-
-/*
- * struct msp71xx_exd_gpio_banks[] - container array of gpio banks
- * @chip: chip structure for the specified gpio bank
- * @reg: register for reading and writing the gpio pin value
- *
- * This array structure defines the extended gpio banks for the
- * PMC MIPS Processor. We specify the bank name, the data/config
- * register,the base starting gpio number, and the number of
- * gpios exposed by the bank of gpios.
- */
-static struct msp71xx_exd_gpio_chip msp71xx_exd_gpio_banks[] = {
-
-	MSP71XX_EXD_GPIO_BANK("GPIO_23_16", 0x188, 16, 8),
-	MSP71XX_EXD_GPIO_BANK("GPIO_27_24", 0x18C, 24, 4),
-};
-
-void __init msp71xx_init_gpio_extended(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(msp71xx_exd_gpio_banks); i++)
-		gpiochip_add(&msp71xx_exd_gpio_banks[i].chip);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/Makefile linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/Makefile
--- linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,6 @@
 #
 obj-y += msp_prom.o msp_setup.o msp_irq.o \
 	 msp_time.o msp_serial.o msp_elb.o
-obj-$(CONFIG_HAVE_GPIO_LIB) += gpio.o gpio_extended.o
 obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o
 obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o
 obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/msp_smtc.c linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/msp_smtc.c
--- linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/msp_smtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/msp_smtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,7 @@ static void msp_smtc_send_ipi_mask(const
 /*
  * Post-config but pre-boot cleanup entry point
  */
-static void __cpuinit msp_smtc_init_secondary(void)
+static void msp_smtc_init_secondary(void)
 {
 	int myvpe;
 
@@ -48,8 +48,7 @@ static void __cpuinit msp_smtc_init_seco
 /*
  * Platform "CPU" startup hook
  */
-static void __cpuinit msp_smtc_boot_secondary(int cpu,
-					struct task_struct *idle)
+static void msp_smtc_boot_secondary(int cpu, struct task_struct *idle)
 {
 	smtc_boot_secondary(cpu, idle);
 }
@@ -57,7 +56,7 @@ static void __cpuinit msp_smtc_boot_seco
 /*
  * SMP initialization finalization entry point
  */
-static void __cpuinit msp_smtc_smp_finish(void)
+static void msp_smtc_smp_finish(void)
 {
 	smtc_smp_finish();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/msp_time.c linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/msp_time.c
--- linux-libre-3.10-gnu/arch/mips/pmcs-msp71xx/msp_time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pmcs-msp71xx/msp_time.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,7 +88,7 @@ void __init plat_time_init(void)
 	mips_hpt_frequency = cpu_rate/2;
 }
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
 	/* MIPS_MT modes may want timer for second VPE */
 	if ((get_current_vpe()) && !tim_installed) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pnx833x/common/interrupts.c linux-libre-3.11-rc7-gnu/arch/mips/pnx833x/common/interrupts.c
--- linux-libre-3.10-gnu/arch/mips/pnx833x/common/interrupts.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pnx833x/common/interrupts.c	2013-08-25 20:43:22.000000000 -0400
@@ -281,7 +281,7 @@ void __init arch_init_irq(void)
 	write_c0_status(read_c0_status() | IE_IRQ2);
 }
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
 	if (cpu_has_vint)
 		set_vi_handler(cp0_compare_irq, pnx833x_timer_dispatch);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/pnx833x/common/platform.c linux-libre-3.11-rc7-gnu/arch/mips/pnx833x/common/platform.c
--- linux-libre-3.10-gnu/arch/mips/pnx833x/common/platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/pnx833x/common/platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -206,11 +206,13 @@ static struct resource pnx833x_ethernet_
 		.end   = PNX8335_IP3902_PORTS_END,
 		.flags = IORESOURCE_MEM,
 	},
+#ifdef CONFIG_SOC_PNX8335
 	[1] = {
 		.start = PNX8335_PIC_ETHERNET_INT,
 		.end   = PNX8335_PIC_ETHERNET_INT,
 		.flags = IORESOURCE_IRQ,
 	},
+#endif
 };
 
 static struct platform_device pnx833x_ethernet_device = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/powertv/asic/asic_devices.c linux-libre-3.11-rc7-gnu/arch/mips/powertv/asic/asic_devices.c
--- linux-libre-3.10-gnu/arch/mips/powertv/asic/asic_devices.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/powertv/asic/asic_devices.c	2013-08-25 20:43:22.000000000 -0400
@@ -529,17 +529,7 @@ EXPORT_SYMBOL(asic_resource_get);
  */
 void platform_release_memory(void *ptr, int size)
 {
-	unsigned long addr;
-	unsigned long end;
-
-	addr = ((unsigned long)ptr + (PAGE_SIZE - 1)) & PAGE_MASK;
-	end = ((unsigned long)ptr + size) & PAGE_MASK;
-
-	for (; addr < end; addr += PAGE_SIZE) {
-		ClearPageReserved(virt_to_page(__va(addr)));
-		init_page_count(virt_to_page(__va(addr)));
-		free_page((unsigned long)__va(addr));
-	}
+	free_reserved_area(ptr, ptr + size, -1, NULL);
 }
 EXPORT_SYMBOL(platform_release_memory);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/powertv/time.c linux-libre-3.11-rc7-gnu/arch/mips/powertv/time.c
--- linux-libre-3.10-gnu/arch/mips/powertv/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/powertv/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@
 
 #include "powertv-clock.h"
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
 	return irq_mips_timer;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/ralink/irq.c linux-libre-3.11-rc7-gnu/arch/mips/ralink/irq.c
--- linux-libre-3.10-gnu/arch/mips/ralink/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/ralink/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -73,7 +73,7 @@ static struct irq_chip ralink_intc_irq_c
 	.irq_mask_ack	= ralink_intc_irq_mask,
 };
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
 	return CP0_LEGACY_COMPARE_IRQ;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/ralink/of.c linux-libre-3.11-rc7-gnu/arch/mips/ralink/of.c
--- linux-libre-3.10-gnu/arch/mips/ralink/of.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/ralink/of.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,7 +104,7 @@ static int __init plat_of_setup(void)
 	if (!of_have_populated_dt())
 		panic("device tree not present");
 
-	strncpy(of_ids[0].compatible, soc_info.compatible, len);
+	strlcpy(of_ids[0].compatible, soc_info.compatible, len);
 	strncpy(of_ids[1].compatible, "palmbus", len);
 
 	if (of_platform_populate(NULL, of_ids, NULL, NULL))
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-init.c linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-init.c
--- linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-init.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ extern void pcibr_setup(cnodeid_t);
 
 extern void xtalk_probe_node(cnodeid_t nid);
 
-static void __cpuinit per_hub_init(cnodeid_t cnode)
+static void per_hub_init(cnodeid_t cnode)
 {
 	struct hub_data *hub = hub_data(cnode);
 	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
@@ -110,7 +110,7 @@ static void __cpuinit per_hub_init(cnode
 	}
 }
 
-void __cpuinit per_cpu_init(void)
+void per_cpu_init(void)
 {
 	int cpu = smp_processor_id();
 	int slice = LOCAL_HUB_L(PI_CPU_NUM);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-irq.c linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-irq.c
--- linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
 #include <asm/mipsregs.h>
 
 #include <asm/processor.h>
-#include <asm/pci/bridge.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/agent.h>
 #include <asm/sn/arch.h>
@@ -54,50 +53,6 @@
 
 extern asmlinkage void ip27_irq(void);
 
-extern struct bridge_controller *irq_to_bridge[];
-extern int irq_to_slot[];
-
-/*
- * use these macros to get the encoded nasid and widget id
- * from the irq value
- */
-#define IRQ_TO_BRIDGE(i)		irq_to_bridge[(i)]
-#define SLOT_FROM_PCI_IRQ(i)		irq_to_slot[i]
-
-static inline int alloc_level(int cpu, int irq)
-{
-	struct hub_data *hub = hub_data(cpu_to_node(cpu));
-	struct slice_data *si = cpu_data[cpu].data;
-	int level;
-
-	level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
-	if (level >= LEVELS_PER_SLICE)
-		panic("Cpu %d flooded with devices", cpu);
-
-	__set_bit(level, hub->irq_alloc_mask);
-	si->level_to_irq[level] = irq;
-
-	return level;
-}
-
-static inline int find_level(cpuid_t *cpunum, int irq)
-{
-	int cpu, i;
-
-	for_each_online_cpu(cpu) {
-		struct slice_data *si = cpu_data[cpu].data;
-
-		for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
-			if (si->level_to_irq[i] == irq) {
-				*cpunum = cpu;
-
-				return i;
-			}
-	}
-
-	panic("Could not identify cpu/level for irq %d", irq);
-}
-
 /*
  * Find first bit set
  */
@@ -204,175 +159,6 @@ static void ip27_hub_error(void)
 	panic("CPU %d got a hub error interrupt", smp_processor_id());
 }
 
-static int intr_connect_level(int cpu, int bit)
-{
-	nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
-	struct slice_data *si = cpu_data[cpu].data;
-
-	set_bit(bit, si->irq_enable_mask);
-
-	if (!cputoslice(cpu)) {
-		REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
-		REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
-	} else {
-		REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
-		REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
-	}
-
-	return 0;
-}
-
-static int intr_disconnect_level(int cpu, int bit)
-{
-	nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
-	struct slice_data *si = cpu_data[cpu].data;
-
-	clear_bit(bit, si->irq_enable_mask);
-
-	if (!cputoslice(cpu)) {
-		REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
-		REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
-	} else {
-		REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
-		REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
-	}
-
-	return 0;
-}
-
-/* Startup one of the (PCI ...) IRQs routes over a bridge.  */
-static unsigned int startup_bridge_irq(struct irq_data *d)
-{
-	struct bridge_controller *bc;
-	bridgereg_t device;
-	bridge_t *bridge;
-	int pin, swlevel;
-	cpuid_t cpu;
-
-	pin = SLOT_FROM_PCI_IRQ(d->irq);
-	bc = IRQ_TO_BRIDGE(d->irq);
-	bridge = bc->base;
-
-	pr_debug("bridge_startup(): irq= 0x%x  pin=%d\n", d->irq, pin);
-	/*
-	 * "map" irq to a swlevel greater than 6 since the first 6 bits
-	 * of INT_PEND0 are taken
-	 */
-	swlevel = find_level(&cpu, d->irq);
-	bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
-	bridge->b_int_enable |= (1 << pin);
-	bridge->b_int_enable |= 0x7ffffe00;	/* more stuff in int_enable */
-
-	/*
-	 * Enable sending of an interrupt clear packt to the hub on a high to
-	 * low transition of the interrupt pin.
-	 *
-	 * IRIX sets additional bits in the address which are documented as
-	 * reserved in the bridge docs.
-	 */
-	bridge->b_int_mode |= (1UL << pin);
-
-	/*
-	 * We assume the bridge to have a 1:1 mapping between devices
-	 * (slots) and intr pins.
-	 */
-	device = bridge->b_int_device;
-	device &= ~(7 << (pin*3));
-	device |= (pin << (pin*3));
-	bridge->b_int_device = device;
-
-	bridge->b_wid_tflush;
-
-	intr_connect_level(cpu, swlevel);
-
-	return 0;	/* Never anything pending.  */
-}
-
-/* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
-static void shutdown_bridge_irq(struct irq_data *d)
-{
-	struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
-	bridge_t *bridge = bc->base;
-	int pin, swlevel;
-	cpuid_t cpu;
-
-	pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
-	pin = SLOT_FROM_PCI_IRQ(d->irq);
-
-	/*
-	 * map irq to a swlevel greater than 6 since the first 6 bits
-	 * of INT_PEND0 are taken
-	 */
-	swlevel = find_level(&cpu, d->irq);
-	intr_disconnect_level(cpu, swlevel);
-
-	bridge->b_int_enable &= ~(1 << pin);
-	bridge->b_wid_tflush;
-}
-
-static inline void enable_bridge_irq(struct irq_data *d)
-{
-	cpuid_t cpu;
-	int swlevel;
-
-	swlevel = find_level(&cpu, d->irq);	/* Criminal offence */
-	intr_connect_level(cpu, swlevel);
-}
-
-static inline void disable_bridge_irq(struct irq_data *d)
-{
-	cpuid_t cpu;
-	int swlevel;
-
-	swlevel = find_level(&cpu, d->irq);	/* Criminal offence */
-	intr_disconnect_level(cpu, swlevel);
-}
-
-static struct irq_chip bridge_irq_type = {
-	.name		= "bridge",
-	.irq_startup	= startup_bridge_irq,
-	.irq_shutdown	= shutdown_bridge_irq,
-	.irq_mask	= disable_bridge_irq,
-	.irq_unmask	= enable_bridge_irq,
-};
-
-void register_bridge_irq(unsigned int irq)
-{
-	irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
-}
-
-int request_bridge_irq(struct bridge_controller *bc)
-{
-	int irq = allocate_irqno();
-	int swlevel, cpu;
-	nasid_t nasid;
-
-	if (irq < 0)
-		return irq;
-
-	/*
-	 * "map" irq to a swlevel greater than 6 since the first 6 bits
-	 * of INT_PEND0 are taken
-	 */
-	cpu = bc->irq_cpu;
-	swlevel = alloc_level(cpu, irq);
-	if (unlikely(swlevel < 0)) {
-		free_irqno(irq);
-
-		return -EAGAIN;
-	}
-
-	/* Make sure it's not already pending when we connect it. */
-	nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
-	REMOTE_HUB_CLR_INTR(nasid, swlevel);
-
-	intr_connect_level(cpu, swlevel);
-
-	register_bridge_irq(irq);
-
-	return irq;
-}
-
 asmlinkage void plat_irq_dispatch(void)
 {
 	unsigned long pending = read_c0_cause() & read_c0_status();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-irq-pci.c linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-irq-pci.c
--- linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-irq-pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-irq-pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,266 @@
+/*
+ * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999 - 2001 Kanoj Sarcar
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/smp.h>
+#include <linux/random.h>
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+
+#include <asm/processor.h>
+#include <asm/pci/bridge.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/agent.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/hub.h>
+#include <asm/sn/intr.h>
+
+/*
+ * Linux has a controller-independent x86 interrupt architecture.
+ * every controller has a 'controller-template', that is used
+ * by the main code to do the right thing. Each driver-visible
+ * interrupt source is transparently wired to the appropriate
+ * controller. Thus drivers need not be aware of the
+ * interrupt-controller.
+ *
+ * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
+ * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
+ * (IO-APICs assumed to be messaging to Pentium local-APICs)
+ *
+ * the code is designed to be easily extended with new/different
+ * interrupt controllers, without having to do assembly magic.
+ */
+
+extern struct bridge_controller *irq_to_bridge[];
+extern int irq_to_slot[];
+
+/*
+ * use these macros to get the encoded nasid and widget id
+ * from the irq value
+ */
+#define IRQ_TO_BRIDGE(i)		irq_to_bridge[(i)]
+#define SLOT_FROM_PCI_IRQ(i)		irq_to_slot[i]
+
+static inline int alloc_level(int cpu, int irq)
+{
+	struct hub_data *hub = hub_data(cpu_to_node(cpu));
+	struct slice_data *si = cpu_data[cpu].data;
+	int level;
+
+	level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
+	if (level >= LEVELS_PER_SLICE)
+		panic("Cpu %d flooded with devices", cpu);
+
+	__set_bit(level, hub->irq_alloc_mask);
+	si->level_to_irq[level] = irq;
+
+	return level;
+}
+
+static inline int find_level(cpuid_t *cpunum, int irq)
+{
+	int cpu, i;
+
+	for_each_online_cpu(cpu) {
+		struct slice_data *si = cpu_data[cpu].data;
+
+		for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
+			if (si->level_to_irq[i] == irq) {
+				*cpunum = cpu;
+
+				return i;
+			}
+	}
+
+	panic("Could not identify cpu/level for irq %d", irq);
+}
+
+static int intr_connect_level(int cpu, int bit)
+{
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+	struct slice_data *si = cpu_data[cpu].data;
+
+	set_bit(bit, si->irq_enable_mask);
+
+	if (!cputoslice(cpu)) {
+		REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
+		REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
+	} else {
+		REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
+		REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
+	}
+
+	return 0;
+}
+
+static int intr_disconnect_level(int cpu, int bit)
+{
+	nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+	struct slice_data *si = cpu_data[cpu].data;
+
+	clear_bit(bit, si->irq_enable_mask);
+
+	if (!cputoslice(cpu)) {
+		REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
+		REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
+	} else {
+		REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
+		REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
+	}
+
+	return 0;
+}
+
+/* Startup one of the (PCI ...) IRQs routes over a bridge.  */
+static unsigned int startup_bridge_irq(struct irq_data *d)
+{
+	struct bridge_controller *bc;
+	bridgereg_t device;
+	bridge_t *bridge;
+	int pin, swlevel;
+	cpuid_t cpu;
+
+	pin = SLOT_FROM_PCI_IRQ(d->irq);
+	bc = IRQ_TO_BRIDGE(d->irq);
+	bridge = bc->base;
+
+	pr_debug("bridge_startup(): irq= 0x%x  pin=%d\n", d->irq, pin);
+	/*
+	 * "map" irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	swlevel = find_level(&cpu, d->irq);
+	bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
+	bridge->b_int_enable |= (1 << pin);
+	bridge->b_int_enable |= 0x7ffffe00;	/* more stuff in int_enable */
+
+	/*
+	 * Enable sending of an interrupt clear packt to the hub on a high to
+	 * low transition of the interrupt pin.
+	 *
+	 * IRIX sets additional bits in the address which are documented as
+	 * reserved in the bridge docs.
+	 */
+	bridge->b_int_mode |= (1UL << pin);
+
+	/*
+	 * We assume the bridge to have a 1:1 mapping between devices
+	 * (slots) and intr pins.
+	 */
+	device = bridge->b_int_device;
+	device &= ~(7 << (pin*3));
+	device |= (pin << (pin*3));
+	bridge->b_int_device = device;
+
+	bridge->b_wid_tflush;
+
+	intr_connect_level(cpu, swlevel);
+
+	return 0;	/* Never anything pending.  */
+}
+
+/* Shutdown one of the (PCI ...) IRQs routes over a bridge.  */
+static void shutdown_bridge_irq(struct irq_data *d)
+{
+	struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
+	bridge_t *bridge = bc->base;
+	int pin, swlevel;
+	cpuid_t cpu;
+
+	pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
+	pin = SLOT_FROM_PCI_IRQ(d->irq);
+
+	/*
+	 * map irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	swlevel = find_level(&cpu, d->irq);
+	intr_disconnect_level(cpu, swlevel);
+
+	bridge->b_int_enable &= ~(1 << pin);
+	bridge->b_wid_tflush;
+}
+
+static inline void enable_bridge_irq(struct irq_data *d)
+{
+	cpuid_t cpu;
+	int swlevel;
+
+	swlevel = find_level(&cpu, d->irq);	/* Criminal offence */
+	intr_connect_level(cpu, swlevel);
+}
+
+static inline void disable_bridge_irq(struct irq_data *d)
+{
+	cpuid_t cpu;
+	int swlevel;
+
+	swlevel = find_level(&cpu, d->irq);	/* Criminal offence */
+	intr_disconnect_level(cpu, swlevel);
+}
+
+static struct irq_chip bridge_irq_type = {
+	.name		= "bridge",
+	.irq_startup	= startup_bridge_irq,
+	.irq_shutdown	= shutdown_bridge_irq,
+	.irq_mask	= disable_bridge_irq,
+	.irq_unmask	= enable_bridge_irq,
+};
+
+void register_bridge_irq(unsigned int irq)
+{
+	irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
+}
+
+int request_bridge_irq(struct bridge_controller *bc)
+{
+	int irq = allocate_irqno();
+	int swlevel, cpu;
+	nasid_t nasid;
+
+	if (irq < 0)
+		return irq;
+
+	/*
+	 * "map" irq to a swlevel greater than 6 since the first 6 bits
+	 * of INT_PEND0 are taken
+	 */
+	cpu = bc->irq_cpu;
+	swlevel = alloc_level(cpu, irq);
+	if (unlikely(swlevel < 0)) {
+		free_irqno(irq);
+
+		return -EAGAIN;
+	}
+
+	/* Make sure it's not already pending when we connect it. */
+	nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+	REMOTE_HUB_CLR_INTR(nasid, swlevel);
+
+	intr_connect_level(cpu, swlevel);
+
+	register_bridge_irq(irq);
+
+	return irq;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-memory.c linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-memory.c
--- linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-memory.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-memory.c	2013-08-25 20:43:22.000000000 -0400
@@ -357,8 +357,6 @@ static void __init szmem(void)
 	int slot;
 	cnodeid_t node;
 
-	num_physpages = 0;
-
 	for_each_online_node(node) {
 		nodebytes = 0;
 		for (slot = 0; slot < MAX_MEM_SLOTS; slot++) {
@@ -381,7 +379,6 @@ static void __init szmem(void)
 				slot = MAX_MEM_SLOTS;
 				continue;
 			}
-			num_physpages += slot_psize;
 			memblock_add_node(PFN_PHYS(slot_getbasepfn(node, slot)),
 					  PFN_PHYS(slot_psize), node);
 		}
@@ -480,32 +477,8 @@ void __init paging_init(void)
 
 void __init mem_init(void)
 {
-	unsigned long codesize, datasize, initsize, tmp;
-	unsigned node;
-
-	high_memory = (void *) __va(num_physpages << PAGE_SHIFT);
-
-	for_each_online_node(node) {
-		/*
-		 * This will free up the bootmem, ie, slot 0 memory.
-		 */
-		totalram_pages += free_all_bootmem_node(NODE_DATA(node));
-	}
-
+	high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT);
+	free_all_bootmem();
 	setup_zero_pages();	/* This comes from node 0 */
-
-	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
-	tmp = nr_free_pages();
-	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
-	       "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
-	       tmp << (PAGE_SHIFT-10),
-	       num_physpages << (PAGE_SHIFT-10),
-	       codesize >> 10,
-	       (num_physpages - tmp) << (PAGE_SHIFT-10),
-	       datasize >> 10,
-	       initsize >> 10,
-	       totalhigh_pages << (PAGE_SHIFT-10));
+	mem_init_print_info(NULL);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-smp.c linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-smp.c
--- linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -173,12 +173,12 @@ static void ip27_send_ipi_mask(const str
 		ip27_send_ipi_single(i, action);
 }
 
-static void __cpuinit ip27_init_secondary(void)
+static void ip27_init_secondary(void)
 {
 	per_cpu_init();
 }
 
-static void __cpuinit ip27_smp_finish(void)
+static void ip27_smp_finish(void)
 {
 	extern void hub_rt_clock_event_init(void);
 
@@ -195,7 +195,7 @@ static void __init ip27_cpus_done(void)
  * set sp to the kernel stack of the newly created idle process, gp to the proc
  * struct so that current_thread_info() will work.
  */
-static void __cpuinit ip27_boot_secondary(int cpu, struct task_struct *idle)
+static void ip27_boot_secondary(int cpu, struct task_struct *idle)
 {
 	unsigned long gp = (unsigned long)task_thread_info(idle);
 	unsigned long sp = __KSTK_TOS(idle);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-timer.c linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-timer.c
--- linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -106,7 +106,7 @@ struct irqaction hub_rt_irqaction = {
 #define NSEC_PER_CYCLE		800
 #define CYCLES_PER_SEC		(NSEC_PER_SEC / NSEC_PER_CYCLE)
 
-void __cpuinit hub_rt_clock_event_init(void)
+void hub_rt_clock_event_init(void)
 {
 	unsigned int cpu = smp_processor_id();
 	struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
@@ -173,7 +173,7 @@ void __init plat_time_init(void)
 	hub_rt_clock_event_init();
 }
 
-void __cpuinit cpu_time_init(void)
+void cpu_time_init(void)
 {
 	lboard_t *board;
 	klcpu_t *cpu;
@@ -194,7 +194,7 @@ void __cpuinit cpu_time_init(void)
 	set_c0_status(SRB_TIMOCLK);
 }
 
-void __cpuinit hub_rtc_init(cnodeid_t cnode)
+void hub_rtc_init(cnodeid_t cnode)
 {
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-xtalk.c linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-xtalk.c
--- linux-libre-3.10-gnu/arch/mips/sgi-ip27/ip27-xtalk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/ip27-xtalk.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,7 @@
 
 extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
 
-static int __cpuinit probe_one_port(nasid_t nasid, int widget, int masterwid)
+static int probe_one_port(nasid_t nasid, int widget, int masterwid)
 {
 	widgetreg_t		widget_id;
 	xwidget_part_num_t	partnum;
@@ -47,7 +47,7 @@ static int __cpuinit probe_one_port(nasi
 	return 0;
 }
 
-static int __cpuinit xbow_probe(nasid_t nasid)
+static int xbow_probe(nasid_t nasid)
 {
 	lboard_t *brd;
 	klxbow_t *xbow_p;
@@ -100,7 +100,7 @@ static int __cpuinit xbow_probe(nasid_t
 	return 0;
 }
 
-void __cpuinit xtalk_probe_node(cnodeid_t nid)
+void xtalk_probe_node(cnodeid_t nid)
 {
 	volatile u64		hubreg;
 	nasid_t			nasid;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sgi-ip27/Makefile linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/Makefile
--- linux-libre-3.10-gnu/arch/mips/sgi-ip27/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sgi-ip27/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -7,4 +7,5 @@ obj-y	:= ip27-berr.o ip27-irq.o ip27-ini
 	   ip27-xtalk.o
 
 obj-$(CONFIG_EARLY_PRINTK)	+= ip27-console.o
+obj-$(CONFIG_PCI)		+= ip27-irq-pci.o
 obj-$(CONFIG_SMP)		+= ip27-smp.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sibyte/bcm1480/smp.c linux-libre-3.11-rc7-gnu/arch/mips/sibyte/bcm1480/smp.c
--- linux-libre-3.10-gnu/arch/mips/sibyte/bcm1480/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sibyte/bcm1480/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,7 +60,7 @@ static void *mailbox_0_regs[] = {
 /*
  * SMP init and finish on secondary CPUs
  */
-void __cpuinit bcm1480_smp_init(void)
+void bcm1480_smp_init(void)
 {
 	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
 		STATUSF_IP1 | STATUSF_IP0;
@@ -95,7 +95,7 @@ static void bcm1480_send_ipi_mask(const
 /*
  * Code to run on secondary just after probing the CPU
  */
-static void __cpuinit bcm1480_init_secondary(void)
+static void bcm1480_init_secondary(void)
 {
 	extern void bcm1480_smp_init(void);
 
@@ -106,7 +106,7 @@ static void __cpuinit bcm1480_init_secon
  * Do any tidying up before marking online and running the idle
  * loop
  */
-static void __cpuinit bcm1480_smp_finish(void)
+static void bcm1480_smp_finish(void)
 {
 	extern void sb1480_clockevent_init(void);
 
@@ -125,7 +125,7 @@ static void bcm1480_cpus_done(void)
  * Setup the PC, SP, and GP of a secondary processor and start it
  * running!
  */
-static void __cpuinit bcm1480_boot_secondary(int cpu, struct task_struct *idle)
+static void bcm1480_boot_secondary(int cpu, struct task_struct *idle)
 {
 	int retval;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sibyte/common/bus_watcher.c linux-libre-3.11-rc7-gnu/arch/mips/sibyte/common/bus_watcher.c
--- linux-libre-3.10-gnu/arch/mips/sibyte/common/bus_watcher.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/mips/sibyte/common/bus_watcher.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2002,2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * The Bus Watcher monitors internal bus transactions and maintains
+ * counts of transactions with error status, logging details and
+ * causing one of several interrupts.  This driver provides a handler
+ * for those interrupts which aggregates the counts (to avoid
+ * saturating the 8-bit counters) and provides a presence in
+ * /proc/bus_watcher if PROC_FS is on.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_scd.h>
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+#include <asm/sibyte/bcm1480_regs.h>
+#endif
+
+
+struct bw_stats_struct {
+	uint64_t status;
+	uint32_t l2_err;
+	uint32_t memio_err;
+	int status_printed;
+	unsigned long l2_cor_d;
+	unsigned long l2_bad_d;
+	unsigned long l2_cor_t;
+	unsigned long l2_bad_t;
+	unsigned long mem_cor_d;
+	unsigned long mem_bad_d;
+	unsigned long bus_error;
+} bw_stats;
+
+
+static void print_summary(uint32_t status, uint32_t l2_err,
+			  uint32_t memio_err)
+{
+	printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
+	printk("\nLast recorded signature:\n");
+	printk("Request %02x from %d, answered by %d with Dcode %d\n",
+	       (unsigned int)(G_SCD_BERR_TID(status) & 0x3f),
+	       (int)(G_SCD_BERR_TID(status) >> 6),
+	       (int)G_SCD_BERR_RID(status),
+	       (int)G_SCD_BERR_DCODE(status));
+}
+
+/*
+ * check_bus_watcher is exported for use in situations where we want
+ * to see the most recent status of the bus watcher, which might have
+ * already been destructively read out of the registers.
+ *
+ * notes: this is currently used by the cache error handler
+ *	  should provide locking against the interrupt handler
+ */
+void check_bus_watcher(void)
+{
+	u32 status, l2_err, memio_err;
+
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+	/* Destructive read, clears register and interrupt */
+	status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
+#elif defined(CONFIG_SIBYTE_BCM112X) || defined(CONFIG_SIBYTE_SB1250)
+	/* Use non-destructive register */
+	status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS_DEBUG));
+#elif defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+	/* Use non-destructive register */
+	/* Same as 1250 except BUS_ERR_STATUS_DEBUG is in a different place. */
+	status = csr_in32(IOADDR(A_BCM1480_BUS_ERR_STATUS_DEBUG));
+#else
+#error bus watcher being built for unknown Sibyte SOC!
+#endif
+	if (!(status & 0x7fffffff)) {
+		printk("Using last values reaped by bus watcher driver\n");
+		status = bw_stats.status;
+		l2_err = bw_stats.l2_err;
+		memio_err = bw_stats.memio_err;
+	} else {
+		l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+		memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
+	}
+	if (status & ~(1UL << 31))
+		print_summary(status, l2_err, memio_err);
+	else
+		printk("Bus watcher indicates no error\n");
+}
+
+#ifdef CONFIG_PROC_FS
+
+/* For simplicity, I want to assume a single read is required each
+   time */
+static int bw_proc_show(struct seq_file *m, void *v)
+{
+	struct bw_stats_struct *stats = m->private;
+
+	seq_puts(m, "SiByte Bus Watcher statistics\n");
+	seq_puts(m, "-----------------------------\n");
+	seq_printf(m, "L2-d-cor %8ld\nL2-d-bad %8ld\n",
+		   stats->l2_cor_d, stats->l2_bad_d);
+	seq_printf(m, "L2-t-cor %8ld\nL2-t-bad %8ld\n",
+		   stats->l2_cor_t, stats->l2_bad_t);
+	seq_printf(m, "MC-d-cor %8ld\nMC-d-bad %8ld\n",
+		   stats->mem_cor_d, stats->mem_bad_d);
+	seq_printf(m, "IO-err   %8ld\n", stats->bus_error);
+	seq_puts(m, "\nLast recorded signature:\n");
+	seq_printf(m, "Request %02x from %d, answered by %d with Dcode %d\n",
+		   (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f),
+		   (int)(G_SCD_BERR_TID(stats->status) >> 6),
+		   (int)G_SCD_BERR_RID(stats->status),
+		   (int)G_SCD_BERR_DCODE(stats->status));
+	/* XXXKW indicate multiple errors between printings, or stats
+	   collection (or both)? */
+	if (stats->status & M_SCD_BERR_MULTERRS)
+		seq_puts(m, "Multiple errors observed since last check.\n");
+	if (stats->status_printed) {
+		seq_puts(m, "(no change since last printing)\n");
+	} else {
+		stats->status_printed = 1;
+	}
+
+	return 0;
+}
+
+static int bw_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, bw_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations bw_proc_fops = {
+	.open		= bw_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static void create_proc_decoder(struct bw_stats_struct *stats)
+{
+	struct proc_dir_entry *ent;
+
+	ent = proc_create_data("bus_watcher", S_IWUSR | S_IRUGO, NULL,
+			       &bw_proc_fops, stats);
+	if (!ent) {
+		printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n");
+		return;
+	}
+}
+
+#endif /* CONFIG_PROC_FS */
+
+/*
+ * sibyte_bw_int - handle bus watcher interrupts and accumulate counts
+ *
+ * notes: possible re-entry due to multiple sources
+ *	  should check/indicate saturation
+ */
+static irqreturn_t sibyte_bw_int(int irq, void *data)
+{
+	struct bw_stats_struct *stats = data;
+	unsigned long cntr;
+#ifdef CONFIG_SIBYTE_BW_TRACE
+	int i;
+#endif
+
+#ifdef CONFIG_SIBYTE_BW_TRACE
+	csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
+	csr_out32(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
+
+	for (i=0; i<256*6; i++)
+		printk("%016llx\n",
+		       (long long)__raw_readq(IOADDR(A_SCD_TRACE_READ)));
+
+	csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+	csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
+#endif
+
+	/* Destructive read, clears register and interrupt */
+	stats->status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
+	stats->status_printed = 0;
+
+	stats->l2_err = cntr = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+	stats->l2_cor_d += G_SCD_L2ECC_CORR_D(cntr);
+	stats->l2_bad_d += G_SCD_L2ECC_BAD_D(cntr);
+	stats->l2_cor_t += G_SCD_L2ECC_CORR_T(cntr);
+	stats->l2_bad_t += G_SCD_L2ECC_BAD_T(cntr);
+	csr_out32(0, IOADDR(A_BUS_L2_ERRORS));
+
+	stats->memio_err = cntr = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
+	stats->mem_cor_d += G_SCD_MEM_ECC_CORR(cntr);
+	stats->mem_bad_d += G_SCD_MEM_ECC_BAD(cntr);
+	stats->bus_error += G_SCD_MEM_BUSERR(cntr);
+	csr_out32(0, IOADDR(A_BUS_MEM_IO_ERRORS));
+
+	return IRQ_HANDLED;
+}
+
+int __init sibyte_bus_watcher(void)
+{
+	memset(&bw_stats, 0, sizeof(struct bw_stats_struct));
+	bw_stats.status_printed = 1;
+
+	if (request_irq(K_INT_BAD_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
+		printk("Failed to register bus watcher BAD_ECC irq\n");
+		return -1;
+	}
+	if (request_irq(K_INT_COR_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
+		free_irq(K_INT_BAD_ECC, &bw_stats);
+		printk("Failed to register bus watcher COR_ECC irq\n");
+		return -1;
+	}
+	if (request_irq(K_INT_IO_BUS, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
+		free_irq(K_INT_BAD_ECC, &bw_stats);
+		free_irq(K_INT_COR_ECC, &bw_stats);
+		printk("Failed to register bus watcher IO_BUS irq\n");
+		return -1;
+	}
+
+#ifdef CONFIG_PROC_FS
+	create_proc_decoder(&bw_stats);
+#endif
+
+#ifdef CONFIG_SIBYTE_BW_TRACE
+	csr_out32((M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
+		   K_SCD_TRSEQ_TRIGGER_ALL),
+		  IOADDR(A_SCD_TRACE_SEQUENCE_0));
+	csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+	csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
+#endif
+
+	return 0;
+}
+
+__initcall(sibyte_bus_watcher);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sibyte/common/Makefile linux-libre-3.11-rc7-gnu/arch/mips/sibyte/common/Makefile
--- linux-libre-3.10-gnu/arch/mips/sibyte/common/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sibyte/common/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,3 +1,4 @@
 obj-y := cfe.o
+obj-$(CONFIG_SIBYTE_BUS_WATCHER)	+= bus_watcher.o
 obj-$(CONFIG_SIBYTE_CFE_CONSOLE)	+= cfe_console.o
 obj-$(CONFIG_SIBYTE_TBPROF)		+= sb_tbprof.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sibyte/common/sb_tbprof.c linux-libre-3.11-rc7-gnu/arch/mips/sibyte/common/sb_tbprof.c
--- linux-libre-3.10-gnu/arch/mips/sibyte/common/sb_tbprof.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sibyte/common/sb_tbprof.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
 #include <linux/errno.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sibyte/Kconfig linux-libre-3.11-rc7-gnu/arch/mips/sibyte/Kconfig
--- linux-libre-3.10-gnu/arch/mips/sibyte/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sibyte/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -147,7 +147,8 @@ config SIBYTE_CFE_CONSOLE
 
 config SIBYTE_BUS_WATCHER
 	bool "Support for Bus Watcher statistics"
-	depends on SIBYTE_SB1xxx_SOC
+	depends on SIBYTE_SB1xxx_SOC && \
+		(SIBYTE_BCM112X || SIBYTE_SB1250)
 	help
 	  Handle and keep statistics on the bus error interrupts (COR_ECC,
 	  BAD_ECC, IO_BUS).
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sibyte/Platform linux-libre-3.11-rc7-gnu/arch/mips/sibyte/Platform
--- linux-libre-3.10-gnu/arch/mips/sibyte/Platform	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sibyte/Platform	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,6 @@ cflags-$(CONFIG_SIBYTE_BCM112X) +=					\
 		-I$(srctree)/arch/mips/include/asm/mach-sibyte		\
 		-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
 
-platform-$(CONFIG_SIBYTE_SB1250)	+= sibyte/
 cflags-$(CONFIG_SIBYTE_SB1250)	+=					\
 		-I$(srctree)/arch/mips/include/asm/mach-sibyte		\
 		-DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
@@ -31,7 +30,8 @@ cflags-$(CONFIG_SIBYTE_BCM1x80) +=					\
 # Sibyte BCM91120C (CRhine) board
 # Sibyte BCM91125C (CRhone) board
 # Sibyte BCM91125E (Rhone) board
-# Sibyte SWARM board
+# Sibyte BCM91250A (SWARM) board
+# Sibyte BCM91250C2 (LittleSur) board
 # Sibyte BCM91x80 (BigSur) board
 #
 load-$(CONFIG_SIBYTE_CARMEL)	:= 0xffffffff80100000
@@ -41,3 +41,4 @@ load-$(CONFIG_SIBYTE_RHONE)	:= 0xfffffff
 load-$(CONFIG_SIBYTE_SENTOSA)	:= 0xffffffff80100000
 load-$(CONFIG_SIBYTE_SWARM)	:= 0xffffffff80100000
 load-$(CONFIG_SIBYTE_BIGSUR)	:= 0xffffffff80100000
+load-$(CONFIG_SIBYTE_LITTLESUR) := 0xffffffff80100000
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sibyte/sb1250/bus_watcher.c linux-libre-3.11-rc7-gnu/arch/mips/sibyte/sb1250/bus_watcher.c
--- linux-libre-3.10-gnu/arch/mips/sibyte/sb1250/bus_watcher.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sibyte/sb1250/bus_watcher.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2002,2003 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-/*
- * The Bus Watcher monitors internal bus transactions and maintains
- * counts of transactions with error status, logging details and
- * causing one of several interrupts.  This driver provides a handler
- * for those interrupts which aggregates the counts (to avoid
- * saturating the 8-bit counters) and provides a presence in
- * /proc/bus_watcher if PROC_FS is on.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <asm/io.h>
-
-#include <asm/sibyte/sb1250.h>
-#include <asm/sibyte/sb1250_regs.h>
-#include <asm/sibyte/sb1250_int.h>
-#include <asm/sibyte/sb1250_scd.h>
-
-
-struct bw_stats_struct {
-	uint64_t status;
-	uint32_t l2_err;
-	uint32_t memio_err;
-	int status_printed;
-	unsigned long l2_cor_d;
-	unsigned long l2_bad_d;
-	unsigned long l2_cor_t;
-	unsigned long l2_bad_t;
-	unsigned long mem_cor_d;
-	unsigned long mem_bad_d;
-	unsigned long bus_error;
-} bw_stats;
-
-
-static void print_summary(uint32_t status, uint32_t l2_err,
-			  uint32_t memio_err)
-{
-	printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
-	printk("\nLast recorded signature:\n");
-	printk("Request %02x from %d, answered by %d with Dcode %d\n",
-	       (unsigned int)(G_SCD_BERR_TID(status) & 0x3f),
-	       (int)(G_SCD_BERR_TID(status) >> 6),
-	       (int)G_SCD_BERR_RID(status),
-	       (int)G_SCD_BERR_DCODE(status));
-}
-
-/*
- * check_bus_watcher is exported for use in situations where we want
- * to see the most recent status of the bus watcher, which might have
- * already been destructively read out of the registers.
- *
- * notes: this is currently used by the cache error handler
- *	  should provide locking against the interrupt handler
- */
-void check_bus_watcher(void)
-{
-	u32 status, l2_err, memio_err;
-
-#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
-	/* Destructive read, clears register and interrupt */
-	status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
-#else
-	/* Use non-destructive register */
-	status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS_DEBUG));
-#endif
-	if (!(status & 0x7fffffff)) {
-		printk("Using last values reaped by bus watcher driver\n");
-		status = bw_stats.status;
-		l2_err = bw_stats.l2_err;
-		memio_err = bw_stats.memio_err;
-	} else {
-		l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
-		memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
-	}
-	if (status & ~(1UL << 31))
-		print_summary(status, l2_err, memio_err);
-	else
-		printk("Bus watcher indicates no error\n");
-}
-
-#ifdef CONFIG_PROC_FS
-
-/* For simplicity, I want to assume a single read is required each
-   time */
-static int bw_proc_show(struct seq_file *m, void *v)
-{
-	struct bw_stats_struct *stats = m->private;
-
-	seq_puts(m, "SiByte Bus Watcher statistics\n");
-	seq_puts(m, "-----------------------------\n");
-	seq_printf(m, "L2-d-cor %8ld\nL2-d-bad %8ld\n",
-		   stats->l2_cor_d, stats->l2_bad_d);
-	seq_printf(m, "L2-t-cor %8ld\nL2-t-bad %8ld\n",
-		   stats->l2_cor_t, stats->l2_bad_t);
-	seq_printf(m, "MC-d-cor %8ld\nMC-d-bad %8ld\n",
-		   stats->mem_cor_d, stats->mem_bad_d);
-	seq_printf(m, "IO-err   %8ld\n", stats->bus_error);
-	seq_puts(m, "\nLast recorded signature:\n");
-	seq_printf(m, "Request %02x from %d, answered by %d with Dcode %d\n",
-		   (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f),
-		   (int)(G_SCD_BERR_TID(stats->status) >> 6),
-		   (int)G_SCD_BERR_RID(stats->status),
-		   (int)G_SCD_BERR_DCODE(stats->status));
-	/* XXXKW indicate multiple errors between printings, or stats
-	   collection (or both)? */
-	if (stats->status & M_SCD_BERR_MULTERRS)
-		seq_puts(m, "Multiple errors observed since last check.\n");
-	if (stats->status_printed) {
-		seq_puts(m, "(no change since last printing)\n");
-	} else {
-		stats->status_printed = 1;
-	}
-
-	return 0;
-}
-
-static int bw_proc_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, bw_proc_show, PDE_DATA(inode));
-}
-
-static const struct file_operations bw_proc_fops = {
-	.open		= bw_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static void create_proc_decoder(struct bw_stats_struct *stats)
-{
-	struct proc_dir_entry *ent;
-
-	ent = proc_create_data("bus_watcher", S_IWUSR | S_IRUGO, NULL,
-			       &bw_proc_fops, stats);
-	if (!ent) {
-		printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n");
-		return;
-	}
-}
-
-#endif /* CONFIG_PROC_FS */
-
-/*
- * sibyte_bw_int - handle bus watcher interrupts and accumulate counts
- *
- * notes: possible re-entry due to multiple sources
- *	  should check/indicate saturation
- */
-static irqreturn_t sibyte_bw_int(int irq, void *data)
-{
-	struct bw_stats_struct *stats = data;
-	unsigned long cntr;
-#ifdef CONFIG_SIBYTE_BW_TRACE
-	int i;
-#endif
-#ifndef CONFIG_PROC_FS
-	char bw_buf[1024];
-#endif
-
-#ifdef CONFIG_SIBYTE_BW_TRACE
-	csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
-	csr_out32(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
-
-	for (i=0; i<256*6; i++)
-		printk("%016llx\n",
-		       (long long)__raw_readq(IOADDR(A_SCD_TRACE_READ)));
-
-	csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
-	csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
-#endif
-
-	/* Destructive read, clears register and interrupt */
-	stats->status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
-	stats->status_printed = 0;
-
-	stats->l2_err = cntr = csr_in32(IOADDR(A_BUS_L2_ERRORS));
-	stats->l2_cor_d += G_SCD_L2ECC_CORR_D(cntr);
-	stats->l2_bad_d += G_SCD_L2ECC_BAD_D(cntr);
-	stats->l2_cor_t += G_SCD_L2ECC_CORR_T(cntr);
-	stats->l2_bad_t += G_SCD_L2ECC_BAD_T(cntr);
-	csr_out32(0, IOADDR(A_BUS_L2_ERRORS));
-
-	stats->memio_err = cntr = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
-	stats->mem_cor_d += G_SCD_MEM_ECC_CORR(cntr);
-	stats->mem_bad_d += G_SCD_MEM_ECC_BAD(cntr);
-	stats->bus_error += G_SCD_MEM_BUSERR(cntr);
-	csr_out32(0, IOADDR(A_BUS_MEM_IO_ERRORS));
-
-	return IRQ_HANDLED;
-}
-
-int __init sibyte_bus_watcher(void)
-{
-	memset(&bw_stats, 0, sizeof(struct bw_stats_struct));
-	bw_stats.status_printed = 1;
-
-	if (request_irq(K_INT_BAD_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
-		printk("Failed to register bus watcher BAD_ECC irq\n");
-		return -1;
-	}
-	if (request_irq(K_INT_COR_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
-		free_irq(K_INT_BAD_ECC, &bw_stats);
-		printk("Failed to register bus watcher COR_ECC irq\n");
-		return -1;
-	}
-	if (request_irq(K_INT_IO_BUS, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
-		free_irq(K_INT_BAD_ECC, &bw_stats);
-		free_irq(K_INT_COR_ECC, &bw_stats);
-		printk("Failed to register bus watcher IO_BUS irq\n");
-		return -1;
-	}
-
-#ifdef CONFIG_PROC_FS
-	create_proc_decoder(&bw_stats);
-#endif
-
-#ifdef CONFIG_SIBYTE_BW_TRACE
-	csr_out32((M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
-		   K_SCD_TRSEQ_TRIGGER_ALL),
-		  IOADDR(A_SCD_TRACE_SEQUENCE_0));
-	csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
-	csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
-#endif
-
-	return 0;
-}
-
-__initcall(sibyte_bus_watcher);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sibyte/sb1250/Makefile linux-libre-3.11-rc7-gnu/arch/mips/sibyte/sb1250/Makefile
--- linux-libre-3.10-gnu/arch/mips/sibyte/sb1250/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sibyte/sb1250/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,3 @@
 obj-y := setup.o irq.o time.o
 
 obj-$(CONFIG_SMP)			+= smp.o
-obj-$(CONFIG_SIBYTE_BUS_WATCHER)	+= bus_watcher.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sibyte/sb1250/smp.c linux-libre-3.11-rc7-gnu/arch/mips/sibyte/sb1250/smp.c
--- linux-libre-3.10-gnu/arch/mips/sibyte/sb1250/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sibyte/sb1250/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,7 +48,7 @@ static void *mailbox_regs[] = {
 /*
  * SMP init and finish on secondary CPUs
  */
-void __cpuinit sb1250_smp_init(void)
+void sb1250_smp_init(void)
 {
 	unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
 		STATUSF_IP1 | STATUSF_IP0;
@@ -83,7 +83,7 @@ static inline void sb1250_send_ipi_mask(
 /*
  * Code to run on secondary just after probing the CPU
  */
-static void __cpuinit sb1250_init_secondary(void)
+static void sb1250_init_secondary(void)
 {
 	extern void sb1250_smp_init(void);
 
@@ -94,7 +94,7 @@ static void __cpuinit sb1250_init_second
  * Do any tidying up before marking online and running the idle
  * loop
  */
-static void __cpuinit sb1250_smp_finish(void)
+static void sb1250_smp_finish(void)
 {
 	extern void sb1250_clockevent_init(void);
 
@@ -113,7 +113,7 @@ static void sb1250_cpus_done(void)
  * Setup the PC, SP, and GP of a secondary processor and start it
  * running!
  */
-static void __cpuinit sb1250_boot_secondary(int cpu, struct task_struct *idle)
+static void sb1250_boot_secondary(int cpu, struct task_struct *idle)
 {
 	int retval;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sni/pcimt.c linux-libre-3.11-rc7-gnu/arch/mips/sni/pcimt.c
--- linux-libre-3.10-gnu/arch/mips/sni/pcimt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sni/pcimt.c	2013-08-25 20:43:22.000000000 -0400
@@ -185,6 +185,7 @@ static void __init sni_pcimt_resource_in
 
 extern struct pci_ops sni_pcimt_ops;
 
+#ifdef CONFIG_PCI
 static struct pci_controller sni_controller = {
 	.pci_ops	= &sni_pcimt_ops,
 	.mem_resource	= &sni_mem_resource,
@@ -193,6 +194,7 @@ static struct pci_controller sni_control
 	.io_offset	= 0x00000000UL,
 	.io_map_base	= SNI_PORT_BASE
 };
+#endif
 
 static void enable_pcimt_irq(struct irq_data *d)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/sni/pcit.c linux-libre-3.11-rc7-gnu/arch/mips/sni/pcit.c
--- linux-libre-3.10-gnu/arch/mips/sni/pcit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/sni/pcit.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,13 +128,6 @@ static struct resource pcit_io_resources
 	}
 };
 
-static struct resource sni_mem_resource = {
-	.start	= 0x18000000UL,
-	.end	= 0x1fbfffffUL,
-	.name	= "PCIT PCI MEM",
-	.flags	= IORESOURCE_MEM
-};
-
 static void __init sni_pcit_resource_init(void)
 {
 	int i;
@@ -147,6 +140,14 @@ static void __init sni_pcit_resource_ini
 
 extern struct pci_ops sni_pcit_ops;
 
+#ifdef CONFIG_PCI
+static struct resource sni_mem_resource = {
+	.start	= 0x18000000UL,
+	.end	= 0x1fbfffffUL,
+	.name	= "PCIT PCI MEM",
+	.flags	= IORESOURCE_MEM
+};
+
 static struct pci_controller sni_pcit_controller = {
 	.pci_ops	= &sni_pcit_ops,
 	.mem_resource	= &sni_mem_resource,
@@ -155,6 +156,7 @@ static struct pci_controller sni_pcit_co
 	.io_offset	= 0x00000000UL,
 	.io_map_base	= SNI_PORT_BASE
 };
+#endif /* CONFIG_PCI */
 
 static void enable_pcit_irq(struct irq_data *d)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/txx9/generic/setup_tx4939.c linux-libre-3.11-rc7-gnu/arch/mips/txx9/generic/setup_tx4939.c
--- linux-libre-3.10-gnu/arch/mips/txx9/generic/setup_tx4939.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/txx9/generic/setup_tx4939.c	2013-08-25 20:43:22.000000000 -0400
@@ -331,7 +331,8 @@ static int tx4939_netdev_event(struct no
 			       unsigned long event,
 			       void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+
 	if (event == NETDEV_CHANGE && netif_carrier_ok(dev)) {
 		__u64 bit = 0;
 		if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(0))
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/wrppmc/irq.c linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/irq.c
--- linux-libre-3.10-gnu/arch/mips/wrppmc/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/irq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-/*
- * irq.c: GT64120 Interrupt Controller
- *
- * Copyright (C) 2006, Wind River System Inc.
- * Author: Rongkai.Zhan, <rongkai.zhan@windriver.com>
- *
- * This program is free software; you can redistribute	it and/or modify it
- * under  the terms of	the GNU General	 Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <linux/hardirq.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/gt64120.h>
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-
-asmlinkage void plat_irq_dispatch(void)
-{
-	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
-
-	if (pending & STATUSF_IP7)
-		do_IRQ(WRPPMC_MIPS_TIMER_IRQ);	/* CPU Compare/Count internal timer */
-	else if (pending & STATUSF_IP6)
-		do_IRQ(WRPPMC_UART16550_IRQ);	/* UART 16550 port */
-	else if (pending & STATUSF_IP3)
-		do_IRQ(WRPPMC_PCI_INTA_IRQ);	/* PCI INT_A */
-	else
-		spurious_interrupt();
-}
-
-/**
- * Initialize GT64120 Interrupt Controller
- */
-void gt64120_init_pic(void)
-{
-	/* clear CPU Interrupt Cause Registers */
-	GT_WRITE(GT_INTRCAUSE_OFS, (0x1F << 21));
-	GT_WRITE(GT_HINTRCAUSE_OFS, 0x00);
-
-	/* Disable all interrupts from GT64120 bridge chip */
-	GT_WRITE(GT_INTRMASK_OFS, 0x00);
-	GT_WRITE(GT_HINTRMASK_OFS, 0x00);
-	GT_WRITE(GT_PCI0_ICMASK_OFS, 0x00);
-	GT_WRITE(GT_PCI0_HICMASK_OFS, 0x00);
-}
-
-void __init arch_init_irq(void)
-{
-	/* IRQ 0 - 7 are for MIPS common irq_cpu controller */
-	mips_cpu_irq_init();
-
-	gt64120_init_pic();
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/wrppmc/Makefile linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/Makefile
--- linux-libre-3.10-gnu/arch/mips/wrppmc/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright 2006 Wind River System, Inc.
-# Author: Rongkai.Zhan <rongkai.zhan@windriver.com>
-#
-# Makefile for the Wind River MIPS 4Kc PPMC Eval Board
-#
-
-obj-y += irq.o pci.o reset.o serial.o setup.o time.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/wrppmc/pci.c linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/pci.c
--- linux-libre-3.10-gnu/arch/mips/wrppmc/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/pci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/*
- * pci.c: GT64120 PCI support.
- *
- * Copyright (C) 2006, Wind River System Inc. Rongkai.Zhan <rongkai.zhan@windriver.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-
-#include <asm/gt64120.h>
-
-extern struct pci_ops gt64xxx_pci0_ops;
-
-static struct resource pci0_io_resource = {
-	.name  = "pci_0 io",
-	.start = GT_PCI_IO_BASE,
-	.end   = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1,
-	.flags = IORESOURCE_IO,
-};
-
-static struct resource pci0_mem_resource = {
-	.name  = "pci_0 memory",
-	.start = GT_PCI_MEM_BASE,
-	.end   = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1,
-	.flags = IORESOURCE_MEM,
-};
-
-static struct pci_controller hose_0 = {
-	.pci_ops	= &gt64xxx_pci0_ops,
-	.io_resource	= &pci0_io_resource,
-	.mem_resource	= &pci0_mem_resource,
-};
-
-static int __init gt64120_pci_init(void)
-{
-	(void) GT_READ(GT_PCI0_CMD_OFS);	/* Huh??? -- Ralf  */
-	(void) GT_READ(GT_PCI0_BARE_OFS);
-
-	/* reset the whole PCI I/O space range */
-	ioport_resource.start = GT_PCI_IO_BASE;
-	ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
-
-	register_pci_controller(&hose_0);
-	return 0;
-}
-
-arch_initcall(gt64120_pci_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/wrppmc/Platform linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/Platform
--- linux-libre-3.10-gnu/arch/mips/wrppmc/Platform	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/Platform	1969-12-31 19:00:00.000000000 -0500
@@ -1,7 +0,0 @@
-#
-# Wind River PPMC Board (4KC + GT64120)
-#
-platform-$(CONFIG_WR_PPMC)	+= wrppmc/
-cflags-$(CONFIG_WR_PPMC)	+=					\
-		-I$(srctree)/arch/mips/include/asm/mach-wrppmc
-load-$(CONFIG_WR_PPMC)		+= 0xffffffff80100000
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/wrppmc/reset.c linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/reset.c
--- linux-libre-3.10-gnu/arch/mips/wrppmc/reset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/reset.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1997 Ralf Baechle
- */
-#include <linux/irqflags.h>
-#include <linux/kernel.h>
-
-#include <asm/cacheflush.h>
-#include <asm/idle.h>
-#include <asm/mipsregs.h>
-#include <asm/processor.h>
-
-void wrppmc_machine_restart(char *command)
-{
-	/*
-	 * Ouch, we're still alive ... This time we take the silver bullet ...
-	 * ... and find that we leave the hardware in a state in which the
-	 * kernel in the flush locks up somewhen during of after the PCI
-	 * detection stuff.
-	 */
-	local_irq_disable();
-	set_c0_status(ST0_BEV | ST0_ERL);
-	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-	flush_cache_all();
-	write_c0_wired(0);
-	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
-}
-
-void wrppmc_machine_halt(void)
-{
-	local_irq_disable();
-
-	printk(KERN_NOTICE "You can safely turn off the power\n");
-	while (1) {
-		if (cpu_wait)
-			cpu_wait();
-	}
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/wrppmc/serial.c linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/serial.c
--- linux-libre-3.10-gnu/arch/mips/wrppmc/serial.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/serial.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,80 +0,0 @@
-/*
- *  Registration of WRPPMC UART platform device.
- *
- *  Copyright (C) 2007	Yoichi Yuasa <yuasa@linux-mips.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/serial_8250.h>
-
-#include <asm/gt64120.h>
-
-static struct resource wrppmc_uart_resource[] __initdata = {
-	{
-		.start	= WRPPMC_UART16550_BASE,
-		.end	= WRPPMC_UART16550_BASE + 7,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= WRPPMC_UART16550_IRQ,
-		.end	= WRPPMC_UART16550_IRQ,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct plat_serial8250_port wrppmc_serial8250_port[] = {
-	{
-		.irq		= WRPPMC_UART16550_IRQ,
-		.uartclk	= WRPPMC_UART16550_CLOCK,
-		.iotype		= UPIO_MEM,
-		.flags		= UPF_IOREMAP | UPF_SKIP_TEST,
-		.mapbase	= WRPPMC_UART16550_BASE,
-	},
-	{},
-};
-
-static __init int wrppmc_uart_add(void)
-{
-	struct platform_device *pdev;
-	int retval;
-
-	pdev = platform_device_alloc("serial8250", -1);
-	if (!pdev)
-		return -ENOMEM;
-
-	pdev->id = PLAT8250_DEV_PLATFORM;
-	pdev->dev.platform_data = wrppmc_serial8250_port;
-
-	retval = platform_device_add_resources(pdev, wrppmc_uart_resource,
-					ARRAY_SIZE(wrppmc_uart_resource));
-	if (retval)
-		goto err_free_device;
-
-	retval = platform_device_add(pdev);
-	if (retval)
-		goto err_free_device;
-
-	return 0;
-
-err_free_device:
-	platform_device_put(pdev);
-
-	return retval;
-}
-device_initcall(wrppmc_uart_add);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/wrppmc/setup.c linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/setup.c
--- linux-libre-3.10-gnu/arch/mips/wrppmc/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/setup.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,128 +0,0 @@
-/*
- * setup.c: Setup pointers to hardware dependent routines.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
- * Copyright (C) 2006, Wind River System Inc. Rongkai.zhan <rongkai.zhan@windriver.com>
- */
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/pm.h>
-
-#include <asm/io.h>
-#include <asm/bootinfo.h>
-#include <asm/reboot.h>
-#include <asm/time.h>
-#include <asm/gt64120.h>
-
-unsigned long gt64120_base = KSEG1ADDR(0x14000000);
-
-#ifdef WRPPMC_EARLY_DEBUG
-
-static volatile unsigned char * wrppmc_led = \
-	(volatile unsigned char *)KSEG1ADDR(WRPPMC_LED_BASE);
-
-/*
- * PPMC LED control register:
- * -) bit[0] controls DS1 LED (1 - OFF, 0 - ON)
- * -) bit[1] controls DS2 LED (1 - OFF, 0 - ON)
- * -) bit[2] controls DS4 LED (1 - OFF, 0 - ON)
- */
-void wrppmc_led_on(int mask)
-{
-	unsigned char value = *wrppmc_led;
-
-	value &= (0xF8 | mask);
-	*wrppmc_led = value;
-}
-
-/* If mask = 0, turn off all LEDs */
-void wrppmc_led_off(int mask)
-{
-	unsigned char value = *wrppmc_led;
-
-	value |= (0x7 & mask);
-	*wrppmc_led = value;
-}
-
-/*
- * We assume that bootloader has initialized UART16550 correctly
- */
-void __init wrppmc_early_putc(char ch)
-{
-	static volatile unsigned char *wrppmc_uart = \
-		(volatile unsigned char *)KSEG1ADDR(WRPPMC_UART16550_BASE);
-	unsigned char value;
-
-	/* Wait until Transmit-Holding-Register is empty */
-	while (1) {
-		value = *(wrppmc_uart + 5);
-		if (value & 0x20)
-			break;
-	}
-
-	*wrppmc_uart = ch;
-}
-
-void __init wrppmc_early_printk(const char *fmt, ...)
-{
-	static char pbuf[256] = {'\0', };
-	char *ch = pbuf;
-	va_list args;
-	unsigned int i;
-
-	memset(pbuf, 0, 256);
-	va_start(args, fmt);
-	i = vsprintf(pbuf, fmt, args);
-	va_end(args);
-
-	/* Print the string */
-	while (*ch != '\0') {
-		wrppmc_early_putc(*ch);
-		/* if print '\n', also print '\r' */
-		if (*ch++ == '\n')
-			wrppmc_early_putc('\r');
-	}
-}
-#endif /* WRPPMC_EARLY_DEBUG */
-
-void __init prom_free_prom_memory(void)
-{
-}
-
-void __init plat_mem_setup(void)
-{
-	extern void wrppmc_machine_restart(char *command);
-	extern void wrppmc_machine_halt(void);
-
-	_machine_restart = wrppmc_machine_restart;
-	_machine_halt	 = wrppmc_machine_halt;
-	pm_power_off	 = wrppmc_machine_halt;
-
-	/* This makes the operations of 'in/out[bwl]' to the
-	 * physical address ( < KSEG0) can work via KSEG1
-	 */
-	set_io_port_base(KSEG1);
-}
-
-const char *get_system_type(void)
-{
-	return "Wind River PPMC (GT64120)";
-}
-
-/*
- * Initializes basic routines and structures pointers, memory size (as
- * given by the bios and saves the command line.
- */
-void __init prom_init(void)
-{
-	add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM);
-	add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA);
-
-	wrppmc_early_printk("prom_init: GT64120 SDRAM Bank 0: 0x%x - 0x%08lx\n",
-			WRPPMC_SDRAM_SCS0_BASE, (WRPPMC_SDRAM_SCS0_BASE + WRPPMC_SDRAM_SCS0_SIZE));
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mips/wrppmc/time.c linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/time.c
--- linux-libre-3.10-gnu/arch/mips/wrppmc/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mips/wrppmc/time.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*
- * time.c: MIPS CPU Count/Compare timer hookup
- *
- * Author: Mark.Zhan, <rongkai.zhan@windriver.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
- * Copyright (C) 2006, Wind River System Inc.
- */
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <asm/gt64120.h>
-#include <asm/time.h>
-
-#define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */
-
-/*
- * Estimate CPU frequency.  Sets mips_hpt_frequency as a side-effect
- *
- * NOTE: We disable all GT64120 timers, and use MIPS processor internal
- * timer as the source of kernel clock tick.
- */
-void __init plat_time_init(void)
-{
-	/* Disable GT64120 timers */
-	GT_WRITE(GT_TC_CONTROL_OFS, 0x00);
-	GT_WRITE(GT_TC0_OFS, 0x00);
-	GT_WRITE(GT_TC1_OFS, 0x00);
-	GT_WRITE(GT_TC2_OFS, 0x00);
-	GT_WRITE(GT_TC3_OFS, 0x00);
-
-	/* Use MIPS compare/count internal timer */
-	mips_hpt_frequency = WRPPMC_CPU_CLK_FREQ;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mn10300/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/mn10300/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/mn10300/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mn10300/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -486,9 +486,6 @@ extern void update_mmu_cache(struct vm_a
 
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
-	remap_pfn_range((vma), (vaddr), (pfn), (size), (prot))
-
 #define MK_IOSPACE_PFN(space, pfn)	(pfn)
 #define GET_IOSPACE(pfn)		0
 #define GET_PFN(pfn)			(pfn)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mn10300/include/asm/uaccess.h linux-libre-3.11-rc7-gnu/arch/mn10300/include/asm/uaccess.h
--- linux-libre-3.10-gnu/arch/mn10300/include/asm/uaccess.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mn10300/include/asm/uaccess.h	2013-08-25 20:43:22.000000000 -0400
@@ -471,13 +471,13 @@ extern unsigned long __generic_copy_from
 
 #define __copy_to_user(to, from, n)			\
 ({							\
-	might_sleep();					\
+	might_fault();					\
 	__copy_to_user_inatomic((to), (from), (n));	\
 })
 
 #define __copy_from_user(to, from, n)			\
 ({							\
-	might_sleep();					\
+	might_fault();					\
 	__copy_from_user_inatomic((to), (from), (n));	\
 })
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mn10300/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/mn10300/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/mn10300/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mn10300/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -74,4 +74,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif /* _ASM_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mn10300/Kconfig linux-libre-3.11-rc7-gnu/arch/mn10300/Kconfig
--- linux-libre-3.10-gnu/arch/mn10300/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mn10300/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@ config MN10300
 	select MODULES_USE_ELF_RELA
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
+	select HAVE_DEBUG_STACKOVERFLOW
 
 config AM33_2
 	def_bool n
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mn10300/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/mn10300/Kconfig.debug
--- linux-libre-3.10-gnu/arch/mn10300/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mn10300/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -2,10 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-
 config DEBUG_DECOMPRESS_KERNEL
 	bool "Using serial port during decompressing kernel"
 	depends on DEBUG_KERNEL
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mn10300/mm/fault.c linux-libre-3.11-rc7-gnu/arch/mn10300/mm/fault.c
--- linux-libre-3.10-gnu/arch/mn10300/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mn10300/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -345,9 +345,10 @@ no_context:
  */
 out_of_memory:
 	up_read(&mm->mmap_sem);
-	printk(KERN_ALERT "VM: killing process %s\n", tsk->comm);
-	if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR)
-		do_exit(SIGKILL);
+	if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR) {
+		pagefault_out_of_memory();
+		return;
+	}
 	goto no_context;
 
 do_sigbus:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mn10300/mm/init.c linux-libre-3.11-rc7-gnu/arch/mn10300/mm/init.c
--- linux-libre-3.10-gnu/arch/mn10300/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mn10300/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -99,43 +99,21 @@ void __init paging_init(void)
  */
 void __init mem_init(void)
 {
-	int codesize, reservedpages, datasize, initsize;
-	int tmp;
-
 	BUG_ON(!mem_map);
 
 #define START_PFN	(contig_page_data.bdata->node_min_pfn)
 #define MAX_LOW_PFN	(contig_page_data.bdata->node_low_pfn)
 
-	max_mapnr = num_physpages = MAX_LOW_PFN - START_PFN;
+	max_mapnr = MAX_LOW_PFN - START_PFN;
 	high_memory = (void *) __va(MAX_LOW_PFN * PAGE_SIZE);
 
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
 
 	/* this will put all low memory onto the freelists */
-	totalram_pages += free_all_bootmem();
-
-	reservedpages = 0;
-	for (tmp = 0; tmp < num_physpages; tmp++)
-		if (PageReserved(&mem_map[tmp]))
-			reservedpages++;
-
-	codesize =  (unsigned long) &_etext - (unsigned long) &_stext;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+	free_all_bootmem();
 
-	printk(KERN_INFO
-	       "Memory: %luk/%luk available"
-	       " (%dk kernel code, %dk reserved, %dk data, %dk init,"
-	       " %ldk highmem)\n",
-	       nr_free_pages() << (PAGE_SHIFT - 10),
-	       max_mapnr << (PAGE_SHIFT - 10),
-	       codesize >> 10,
-	       reservedpages << (PAGE_SHIFT - 10),
-	       datasize >> 10,
-	       initsize >> 10,
-	       totalhigh_pages << (PAGE_SHIFT - 10));
+	mem_init_print_info(NULL);
 }
 
 /*
@@ -152,6 +130,7 @@ void free_initmem(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd");
+	free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
+			   "initrd");
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/mn10300/unit-asb2305/pci-asb2305.c linux-libre-3.11-rc7-gnu/arch/mn10300/unit-asb2305/pci-asb2305.c
--- linux-libre-3.10-gnu/arch/mn10300/unit-asb2305/pci-asb2305.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/mn10300/unit-asb2305/pci-asb2305.c	2013-08-25 20:43:22.000000000 -0400
@@ -221,7 +221,7 @@ int pci_mmap_page_range(struct pci_dev *
 	/* Leave vm_pgoff as-is, the PCI space address is the physical
 	 * address on this platform.
 	 */
-	vma->vm_flags |= VM_LOCKED | VM_IO;
+	vma->vm_flags |= VM_LOCKED;
 
 	prot = pgprot_val(vma->vm_page_prot);
 	prot &= ~_PAGE_CACHE;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/openrisc/include/asm/Kbuild linux-libre-3.11-rc7-gnu/arch/openrisc/include/asm/Kbuild
--- linux-libre-3.10-gnu/arch/openrisc/include/asm/Kbuild	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/openrisc/include/asm/Kbuild	2013-08-25 20:43:22.000000000 -0400
@@ -66,3 +66,4 @@ generic-y += types.h
 generic-y += ucontext.h
 generic-y += user.h
 generic-y += word-at-a-time.h
+generic-y += xor.h
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/openrisc/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/openrisc/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/openrisc/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/openrisc/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -446,9 +446,6 @@ static inline void update_mmu_cache(stru
 
 #define kern_addr_valid(addr)           (1)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)         \
-	remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #include <asm-generic/pgtable.h>
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/openrisc/Kconfig linux-libre-3.11-rc7-gnu/arch/openrisc/Kconfig
--- linux-libre-3.10-gnu/arch/openrisc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/openrisc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@ config OPENRISC
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select MODULES_USE_ELF_RELA
+	select HAVE_DEBUG_STACKOVERFLOW
 
 config MMU
 	def_bool y
@@ -54,6 +55,7 @@ config GENERIC_CSUM
 
 source "init/Kconfig"
 
+source "kernel/Kconfig.freezer"
 
 menu "Processor type and features"
 
@@ -128,16 +130,6 @@ config CMDLINE
 
 menu "Debugging options"
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for kernel stack overflow"
-	default y
-	help
-	  Make extra checks for space available on stack in some
-          critical functions. This will cause kernel to run a bit slower,
-	  but will catch most of kernel stack overruns and exit gracefully.
-
-	  Say Y if you are unsure.
-
 config JUMP_UPON_UNHANDLED_EXCEPTION
 	bool "Try to die gracefully"
 	default y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/openrisc/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/openrisc/kernel/setup.c
--- linux-libre-3.10-gnu/arch/openrisc/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/openrisc/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -267,7 +267,7 @@ void __init detect_unit_config(unsigned
  *
  */
 
-void __cpuinit calibrate_delay(void)
+void calibrate_delay(void)
 {
 	const int *val;
 	struct device_node *cpu = NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/openrisc/mm/fault.c linux-libre-3.11-rc7-gnu/arch/openrisc/mm/fault.c
--- linux-libre-3.10-gnu/arch/openrisc/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/openrisc/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -267,10 +267,10 @@ out_of_memory:
 	__asm__ __volatile__("l.nop 1");
 
 	up_read(&mm->mmap_sem);
-	printk("VM: killing process %s\n", tsk->comm);
-	if (user_mode(regs))
-		do_exit(SIGKILL);
-	goto no_context;
+	if (!user_mode(regs))
+		goto no_context;
+	pagefault_out_of_memory();
+	return;
 
 do_sigbus:
 	up_read(&mm->mmap_sem);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/openrisc/mm/init.c linux-libre-3.11-rc7-gnu/arch/openrisc/mm/init.c
--- linux-libre-3.10-gnu/arch/openrisc/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/openrisc/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -202,56 +202,20 @@ void __init paging_init(void)
 
 /* References to section boundaries */
 
-static int __init free_pages_init(void)
-{
-	int reservedpages, pfn;
-
-	/* this will put all low memory onto the freelists */
-	totalram_pages = free_all_bootmem();
-
-	reservedpages = 0;
-	for (pfn = 0; pfn < max_low_pfn; pfn++) {
-		/*
-		 * Only count reserved RAM pages
-		 */
-		if (PageReserved(mem_map + pfn))
-			reservedpages++;
-	}
-
-	return reservedpages;
-}
-
-static void __init set_max_mapnr_init(void)
-{
-	max_mapnr = num_physpages = max_low_pfn;
-}
-
 void __init mem_init(void)
 {
-	int codesize, reservedpages, datasize, initsize;
-
 	BUG_ON(!mem_map);
 
-	set_max_mapnr_init();
-
+	max_mapnr = max_low_pfn;
 	high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
 
 	/* clear the zero-page */
 	memset((void *)empty_zero_page, 0, PAGE_SIZE);
 
-	reservedpages = free_pages_init();
-
-	codesize = (unsigned long)&_etext - (unsigned long)&_stext;
-	datasize = (unsigned long)&_edata - (unsigned long)&_etext;
-	initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
+	/* this will put all low memory onto the freelists */
+	free_all_bootmem();
 
-	printk(KERN_INFO
-	       "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
-	       (unsigned long)nr_free_pages() << (PAGE_SHIFT - 10),
-	       max_mapnr << (PAGE_SHIFT - 10), codesize >> 10,
-	       reservedpages << (PAGE_SHIFT - 10), datasize >> 10,
-	       initsize >> 10, (unsigned long)(0 << (PAGE_SHIFT - 10))
-	    );
+	mem_init_print_info(NULL);
 
 	printk("mem_init_done ...........................................\n");
 	mem_init_done = 1;
@@ -261,11 +225,11 @@ void __init mem_init(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
 
 void free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/configs/c8000_defconfig linux-libre-3.11-rc7-gnu/arch/parisc/configs/c8000_defconfig
--- linux-libre-3.10-gnu/arch/parisc/configs/c8000_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/parisc/configs/c8000_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,279 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_PA8X00=y
+CONFIG_MLONGCALLS=y
+CONFIG_64BIT=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_IOMMU_CCIO=y
+CONFIG_PCI=y
+CONFIG_PCI_LBA=y
+# CONFIG_SUPERIO is not set
+# CONFIG_CHASSIS_LCD_LED is not set
+# CONFIG_PDC_CHASSIS is not set
+# CONFIG_PDC_CHASSIS_WARN is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_DIAG=m
+# CONFIG_IPV6 is not set
+CONFIG_IP_DCCP=m
+# CONFIG_IP_DCCP_CCID3 is not set
+CONFIG_TIPC=m
+CONFIG_LLC2=m
+CONFIG_DNS_RESOLVER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_FIFO=y
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=6144
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_WCACHE=y
+CONFIG_ATA_OVER_ETH=m
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_PLATFORM=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_ISCSI_TCP=m
+CONFIG_ISCSI_BOOT_SYSFS=m
+CONFIG_FUSION=y
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION_SAS=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_NETCONSOLE=m
+CONFIG_TUN=y
+CONFIG_E1000=y
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+# CONFIG_WLAN is not set
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_HIL_OLD is not set
+# CONFIG_KEYBOARD_HIL is not set
+CONFIG_MOUSE_PS2=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_CM109=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_PARKBD=m
+CONFIG_SERIO_GSCPS2=m
+# CONFIG_HP_SDC is not set
+CONFIG_SERIO_PCIPS2=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=8
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_MUX is not set
+CONFIG_SERIAL_JSM=m
+CONFIG_PRINTER=y
+CONFIG_HW_RANDOM=y
+CONFIG_RAW_DRIVER=m
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_SSB=m
+CONFIG_SSB_DRIVER_PCICORE=y
+CONFIG_AGP=y
+CONFIG_AGP_PARISC=y
+CONFIG_DRM=y
+CONFIG_DRM_RADEON=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_STI is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_STI_CONSOLE is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_AD1889=m
+# CONFIG_SND_USB is not set
+# CONFIG_SND_GSC is not set
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_KYE=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_LOGITECH_DJ=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_NTRIG=m
+CONFIG_HID_ORTEK=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_GREENASIA=m
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_HID_ZEROPLUS=m
+CONFIG_USB_HID=m
+CONFIG_USB=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=m
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_QUOTA=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_NFS_FS=m
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_SLAB_LEAK=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_RT_MUTEX_TESTER=y
+CONFIG_PROVE_RCU_DELAY=y
+CONFIG_DEBUG_BLOCK_EXT_DEVT=y
+CONFIG_LATENCYTOP=y
+CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
+CONFIG_KEYS=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_FONTS=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/defpalo.conf linux-libre-3.11-rc7-gnu/arch/parisc/defpalo.conf
--- linux-libre-3.10-gnu/arch/parisc/defpalo.conf	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/defpalo.conf	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,7 @@
 # Most people using 'make palo' want a bootable file, usable for
 # network or tape booting for example.
 --init-tape=lifimage
---recoverykernel=vmlinux
+--recoverykernel=vmlinuz
 
 ########## Pick your ROOT here! ##########
 # You need at least one 'root='!
@@ -12,10 +12,10 @@
 # If you want a root ramdisk, use the next 2 lines
 #   (Edit the ramdisk image name!!!!)
 --ramdisk=ram-disk-image-file
---commandline=0/vmlinux HOME=/ root=/dev/ram initrd=0/ramdisk
+--commandline=0/vmlinuz HOME=/ root=/dev/ram initrd=0/ramdisk panic_timeout=60 panic=-1
 
 # If you want NFS root, use the following command line (Edit the HOSTNAME!!!)
-#--commandline=0/vmlinux HOME=/ root=/dev/nfs nfsroot=HOSTNAME ip=bootp
+#--commandline=0/vmlinuz HOME=/ root=/dev/nfs nfsroot=HOSTNAME ip=bootp
 
 # If you have root on a disk partition, use this (Edit the partition name!!!)
-#--commandline=0/vmlinux HOME=/ root=/dev/sda1
+#--commandline=0/vmlinuz HOME=/ root=/dev/sda1
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/hpux/fs.c linux-libre-3.11-rc7-gnu/arch/parisc/hpux/fs.c
--- linux-libre-3.10-gnu/arch/parisc/hpux/fs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/hpux/fs.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,6 +60,7 @@ struct hpux_dirent {
 };
 
 struct getdents_callback {
+	struct dir_context ctx;
 	struct hpux_dirent __user *current_dir;
 	struct hpux_dirent __user *previous;
 	int count;
@@ -110,24 +111,23 @@ int hpux_getdents(unsigned int fd, struc
 {
 	struct fd arg;
 	struct hpux_dirent __user * lastdirent;
-	struct getdents_callback buf;
+	struct getdents_callback buf = {
+		.ctx.actor = filldir,
+		.current_dir = dirent,
+		.count = count
+	};
 	int error;
 
 	arg = fdget(fd);
 	if (!arg.file)
 		return -EBADF;
 
-	buf.current_dir = dirent;
-	buf.previous = NULL;
-	buf.count = count;
-	buf.error = 0;
-
-	error = vfs_readdir(arg.file, filldir, &buf);
+	error = iterate_dir(arg.file, &buf.ctx);
 	if (error >= 0)
 		error = buf.error;
 	lastdirent = buf.previous;
 	if (lastdirent) {
-		if (put_user(arg.file->f_pos, &lastdirent->d_off))
+		if (put_user(buf.ctx.pos, &lastdirent->d_off))
 			error = -EFAULT;
 		else
 			error = count - buf.count;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/include/asm/parisc-device.h linux-libre-3.11-rc7-gnu/arch/parisc/include/asm/parisc-device.h
--- linux-libre-3.10-gnu/arch/parisc/include/asm/parisc-device.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/include/asm/parisc-device.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,7 @@ struct parisc_device {
 	/* generic info returned from pdc_pat_cell_module() */
 	unsigned long	mod_info;	/* PAT specific - Misc Module info */
 	unsigned long	pmod_loc;	/* physical Module location */
+	unsigned long	mod0;
 #endif
 	u64		dma_mask;	/* DMA mask for I/O */
 	struct device 	dev;
@@ -61,4 +62,6 @@ parisc_get_drvdata(struct parisc_device
 
 extern struct bus_type parisc_bus_type;
 
+int iosapic_serial_irq(struct parisc_device *dev);
+
 #endif /*_ASM_PARISC_PARISC_DEVICE_H_*/
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/parisc/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/parisc/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -506,9 +506,6 @@ static inline void ptep_set_wrprotect(st
 #endif
 
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_NO_CACHE)
 
 /* We provide our own get_unmapped_area to provide cache coherency */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/include/asm/special_insns.h linux-libre-3.11-rc7-gnu/arch/parisc/include/asm/special_insns.h
--- linux-libre-3.10-gnu/arch/parisc/include/asm/special_insns.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/include/asm/special_insns.h	2013-08-25 20:43:22.000000000 -0400
@@ -32,9 +32,12 @@ static inline void set_eiem(unsigned lon
 	cr;				\
 })
 
-#define mtsp(gr, cr) \
-	__asm__ __volatile__("mtsp %0,%1" \
+#define mtsp(val, cr) \
+	{ if (__builtin_constant_p(val) && ((val) == 0)) \
+	 __asm__ __volatile__("mtsp %%r0,%0" : : "i" (cr) : "memory"); \
+	else \
+	 __asm__ __volatile__("mtsp %0,%1" \
 		: /* no outputs */ \
-		: "r" (gr), "i" (cr) : "memory")
+		: "r" (val), "i" (cr) : "memory"); }
 
 #endif /* __PARISC_SPECIAL_INSNS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/include/asm/tlbflush.h linux-libre-3.11-rc7-gnu/arch/parisc/include/asm/tlbflush.h
--- linux-libre-3.10-gnu/arch/parisc/include/asm/tlbflush.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/include/asm/tlbflush.h	2013-08-25 20:43:22.000000000 -0400
@@ -63,13 +63,14 @@ static inline void flush_tlb_mm(struct m
 static inline void flush_tlb_page(struct vm_area_struct *vma,
 	unsigned long addr)
 {
-	unsigned long flags;
+	unsigned long flags, sid;
 
 	/* For one page, it's not worth testing the split_tlb variable */
 
 	mb();
-	mtsp(vma->vm_mm->context,1);
+	sid = vma->vm_mm->context;
 	purge_tlb_start(flags);
+	mtsp(sid, 1);
 	pdtlb(addr);
 	pitlb(addr);
 	purge_tlb_end(flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/include/uapi/asm/fcntl.h linux-libre-3.11-rc7-gnu/arch/parisc/include/uapi/asm/fcntl.h
--- linux-libre-3.10-gnu/arch/parisc/include/uapi/asm/fcntl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/include/uapi/asm/fcntl.h	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #define O_INVISIBLE	004000000 /* invisible I/O, for DMAPI/XDSM */
 
 #define O_PATH		020000000
+#define __O_TMPFILE	040000000
 
 #define F_GETLK64	8
 #define F_SETLK64	9
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/parisc/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/parisc/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -73,6 +73,8 @@
 
 #define SO_SELECT_ERR_QUEUE	0x4026
 
+#define SO_BUSY_POLL		0x4027
+
 /* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
  * have to define SOCK_NONBLOCK to a different value here.
  */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/install.sh linux-libre-3.11-rc7-gnu/arch/parisc/install.sh
--- linux-libre-3.10-gnu/arch/parisc/install.sh	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/install.sh	2013-08-25 20:43:22.000000000 -0400
@@ -26,13 +26,13 @@ if [ -x /sbin/${INSTALLKERNEL} ]; then e
 
 # Default install
 
-if [ -f $4/vmlinux ]; then
-	mv $4/vmlinux $4/vmlinux.old
+if [ -f $4/vmlinuz ]; then
+	mv $4/vmlinuz $4/vmlinuz.old
 fi
 
 if [ -f $4/System.map ]; then
 	mv $4/System.map $4/System.old
 fi
 
-cat $2 > $4/vmlinux
+cat $2 > $4/vmlinuz
 cp $3 $4/System.map
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/Kconfig linux-libre-3.11-rc7-gnu/arch/parisc/Kconfig
--- linux-libre-3.10-gnu/arch/parisc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,7 @@ config PARISC
 	select MODULES_USE_ELF_RELA
 	select CLONE_BACKWARDS
 	select TTY # Needed for pdc_cons.c
+	select HAVE_DEBUG_STACKOVERFLOW
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
@@ -254,7 +255,6 @@ config IRQSTACKS
 config HOTPLUG_CPU
 	bool
 	default y if SMP
-	select HOTPLUG
 
 config ARCH_SELECT_MEMORY_MODEL
 	def_bool y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/parisc/Kconfig.debug
--- linux-libre-3.10-gnu/arch/parisc/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -13,14 +13,3 @@ config DEBUG_RODATA
          If in doubt, say "N".
 
 endmenu
-
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	default y
-	depends on DEBUG_KERNEL
-	---help---
-	  Say Y here if you want to check the overflows of kernel, IRQ
-	  and exception stacks. This option will cause messages of the
-	  stacks in detail when free stack space drops below a certain
-	  limit.
-	  If in doubt, say "N".
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/cache.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/cache.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/cache.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/cache.c	2013-08-25 20:43:22.000000000 -0400
@@ -71,18 +71,27 @@ flush_cache_all_local(void)
 }
 EXPORT_SYMBOL(flush_cache_all_local);
 
+/* Virtual address of pfn.  */
+#define pfn_va(pfn)	__va(PFN_PHYS(pfn))
+
 void
 update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
-	struct page *page = pte_page(*ptep);
+	unsigned long pfn = pte_pfn(*ptep);
+	struct page *page;
 
-	if (pfn_valid(page_to_pfn(page)) && page_mapping(page) &&
-	    test_bit(PG_dcache_dirty, &page->flags)) {
+	/* We don't have pte special.  As a result, we can be called with
+	   an invalid pfn and we don't need to flush the kernel dcache page.
+	   This occurs with FireGL card in C8000.  */
+	if (!pfn_valid(pfn))
+		return;
 
-		flush_kernel_dcache_page(page);
+	page = pfn_to_page(pfn);
+	if (page_mapping(page) && test_bit(PG_dcache_dirty, &page->flags)) {
+		flush_kernel_dcache_page_addr(pfn_va(pfn));
 		clear_bit(PG_dcache_dirty, &page->flags);
 	} else if (parisc_requires_coherency())
-		flush_kernel_dcache_page(page);
+		flush_kernel_dcache_page_addr(pfn_va(pfn));
 }
 
 void
@@ -440,8 +449,8 @@ void __flush_tlb_range(unsigned long sid
 	else {
 		unsigned long flags;
 
-		mtsp(sid, 1);
 		purge_tlb_start(flags);
+		mtsp(sid, 1);
 		if (split_tlb) {
 			while (npages--) {
 				pdtlb(start);
@@ -495,44 +504,42 @@ static inline pte_t *get_ptep(pgd_t *pgd
 
 void flush_cache_mm(struct mm_struct *mm)
 {
+	struct vm_area_struct *vma;
+	pgd_t *pgd;
+
 	/* Flushing the whole cache on each cpu takes forever on
 	   rp3440, etc.  So, avoid it if the mm isn't too big.  */
-	if (mm_total_size(mm) < parisc_cache_flush_threshold) {
-		struct vm_area_struct *vma;
-
-		if (mm->context == mfsp(3)) {
-			for (vma = mm->mmap; vma; vma = vma->vm_next) {
-				flush_user_dcache_range_asm(vma->vm_start,
-					vma->vm_end);
-				if (vma->vm_flags & VM_EXEC)
-					flush_user_icache_range_asm(
-					  vma->vm_start, vma->vm_end);
-			}
-		} else {
-			pgd_t *pgd = mm->pgd;
-
-			for (vma = mm->mmap; vma; vma = vma->vm_next) {
-				unsigned long addr;
+	if (mm_total_size(mm) >= parisc_cache_flush_threshold) {
+		flush_cache_all();
+		return;
+	}
 
-				for (addr = vma->vm_start; addr < vma->vm_end;
-				     addr += PAGE_SIZE) {
-					pte_t *ptep = get_ptep(pgd, addr);
-					if (ptep != NULL) {
-						pte_t pte = *ptep;
-						__flush_cache_page(vma, addr,
-						  page_to_phys(pte_page(pte)));
-					}
-				}
-			}
+	if (mm->context == mfsp(3)) {
+		for (vma = mm->mmap; vma; vma = vma->vm_next) {
+			flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
+			if ((vma->vm_flags & VM_EXEC) == 0)
+				continue;
+			flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
 		}
 		return;
 	}
 
-#ifdef CONFIG_SMP
-	flush_cache_all();
-#else
-	flush_cache_all_local();
-#endif
+	pgd = mm->pgd;
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		unsigned long addr;
+
+		for (addr = vma->vm_start; addr < vma->vm_end;
+		     addr += PAGE_SIZE) {
+			unsigned long pfn;
+			pte_t *ptep = get_ptep(pgd, addr);
+			if (!ptep)
+				continue;
+			pfn = pte_pfn(*ptep);
+			if (!pfn_valid(pfn))
+				continue;
+			__flush_cache_page(vma, addr, PFN_PHYS(pfn));
+		}
+	}
 }
 
 void
@@ -556,33 +563,32 @@ flush_user_icache_range(unsigned long st
 void flush_cache_range(struct vm_area_struct *vma,
 		unsigned long start, unsigned long end)
 {
-	BUG_ON(!vma->vm_mm->context);
+	unsigned long addr;
+	pgd_t *pgd;
 
-	if ((end - start) < parisc_cache_flush_threshold) {
-		if (vma->vm_mm->context == mfsp(3)) {
-			flush_user_dcache_range_asm(start, end);
-			if (vma->vm_flags & VM_EXEC)
-				flush_user_icache_range_asm(start, end);
-		} else {
-			unsigned long addr;
-			pgd_t *pgd = vma->vm_mm->pgd;
+	BUG_ON(!vma->vm_mm->context);
 
-			for (addr = start & PAGE_MASK; addr < end;
-			     addr += PAGE_SIZE) {
-				pte_t *ptep = get_ptep(pgd, addr);
-				if (ptep != NULL) {
-					pte_t pte = *ptep;
-					flush_cache_page(vma,
-					   addr, pte_pfn(pte));
-				}
-			}
-		}
-	} else {
-#ifdef CONFIG_SMP
+	if ((end - start) >= parisc_cache_flush_threshold) {
 		flush_cache_all();
-#else
-		flush_cache_all_local();
-#endif
+		return;
+	}
+
+	if (vma->vm_mm->context == mfsp(3)) {
+		flush_user_dcache_range_asm(start, end);
+		if (vma->vm_flags & VM_EXEC)
+			flush_user_icache_range_asm(start, end);
+		return;
+	}
+
+	pgd = vma->vm_mm->pgd;
+	for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) {
+		unsigned long pfn;
+		pte_t *ptep = get_ptep(pgd, addr);
+		if (!ptep)
+			continue;
+		pfn = pte_pfn(*ptep);
+		if (pfn_valid(pfn))
+			__flush_cache_page(vma, addr, PFN_PHYS(pfn));
 	}
 }
 
@@ -591,9 +597,10 @@ flush_cache_page(struct vm_area_struct *
 {
 	BUG_ON(!vma->vm_mm->context);
 
-	flush_tlb_page(vma, vmaddr);
-	__flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn)));
-
+	if (pfn_valid(pfn)) {
+		flush_tlb_page(vma, vmaddr);
+		__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
+	}
 }
 
 #ifdef CONFIG_PARISC_TMPALIAS
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/firmware.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/firmware.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/firmware.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/firmware.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,7 +150,7 @@ static void convert_to_wide(unsigned lon
 }
 
 #ifdef CONFIG_64BIT
-void __cpuinit set_firmware_width_unlocked(void)
+void set_firmware_width_unlocked(void)
 {
 	int ret;
 
@@ -167,7 +167,7 @@ void __cpuinit set_firmware_width_unlock
  * This function must be called before any pdc_* function that uses the
  * convert_to_wide function.
  */
-void __cpuinit set_firmware_width(void)
+void set_firmware_width(void)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&pdc_lock, flags);
@@ -175,11 +175,13 @@ void __cpuinit set_firmware_width(void)
 	spin_unlock_irqrestore(&pdc_lock, flags);
 }
 #else
-void __cpuinit set_firmware_width_unlocked(void) {
+void set_firmware_width_unlocked(void)
+{
 	return;
 }
 
-void __cpuinit set_firmware_width(void) {
+void set_firmware_width(void)
+{
 	return;
 }
 #endif /*CONFIG_64BIT*/
@@ -301,7 +303,7 @@ int pdc_chassis_warn(unsigned long *warn
 	return retval;
 }
 
-int __cpuinit pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info)
+int pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info)
 {
 	int ret;
 
@@ -322,7 +324,7 @@ int __cpuinit pdc_coproc_cfg_unlocked(st
  * This PDC call returns the presence and status of all the coprocessors
  * attached to the processor.
  */
-int __cpuinit pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
+int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
 {
 	int ret;
 	unsigned long flags;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/hardware.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/hardware.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/hardware.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/hardware.c	2013-08-25 20:43:22.000000000 -0400
@@ -1367,7 +1367,7 @@ const char *parisc_hardware_description(
 
 
 /* Interpret hversion (ret[0]) from PDC_MODEL(4)/PDC_MODEL_INFO(0) */
-enum cpu_type __cpuinit
+enum cpu_type
 parisc_get_cpu_type(unsigned long hversion)
 {
 	struct hp_cpu_type_mask *ptr;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/inventory.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/inventory.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/inventory.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/inventory.c	2013-08-25 20:43:22.000000000 -0400
@@ -211,6 +211,7 @@ pat_query_module(ulong pcell_loc, ulong
 	/* REVISIT: who is the consumer of this? not sure yet... */
 	dev->mod_info = pa_pdc_cell->mod_info;	/* pass to PAT_GET_ENTITY() */
 	dev->pmod_loc = pa_pdc_cell->mod_location;
+	dev->mod0 = pa_pdc_cell->mod[0];
 
 	register_parisc_device(dev);	/* advertise device */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/processor.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/processor.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/processor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/processor.c	2013-08-25 20:43:22.000000000 -0400
@@ -73,7 +73,7 @@ extern int update_cr16_clocksource(void)
  *
  * FIXME: doesn't do much yet...
  */
-static void __cpuinit
+static void
 init_percpu_prof(unsigned long cpunum)
 {
 	struct cpuinfo_parisc *p;
@@ -92,7 +92,7 @@ init_percpu_prof(unsigned long cpunum)
  * (return 1).  If so, initialize the chip and tell other partners in crime 
  * they have work to do.
  */
-static int __cpuinit processor_probe(struct parisc_device *dev)
+static int processor_probe(struct parisc_device *dev)
 {
 	unsigned long txn_addr;
 	unsigned long cpuid;
@@ -299,7 +299,7 @@ void __init collect_boot_cpu_data(void)
  *
  * o Enable CPU profiling hooks.
  */
-int __cpuinit init_per_cpu(int cpunum)
+int init_per_cpu(int cpunum)
 {
 	int ret;
 	struct pdc_coproc_cfg coproc_cfg;
@@ -371,10 +371,23 @@ show_cpuinfo (struct seq_file *m, void *
 
 		seq_printf(m, "capabilities\t:");
 		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32)
-			seq_printf(m, " os32");
+			seq_puts(m, " os32");
 		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS64)
-			seq_printf(m, " os64");
-		seq_printf(m, "\n");
+			seq_puts(m, " os64");
+		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC)
+			seq_puts(m, " iopdir_fdc");
+		switch (boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) {
+		case PDC_MODEL_NVA_SUPPORTED:
+			seq_puts(m, " nva_supported");
+			break;
+		case PDC_MODEL_NVA_SLOW:
+			seq_puts(m, " nva_slow");
+			break;
+		case PDC_MODEL_NVA_UNSUPPORTED:
+			seq_puts(m, " needs_equivalent_aliasing");
+			break;
+		}
+		seq_printf(m, " (0x%02lx)\n", boot_cpu_data.pdc.capabilities);
 
 		seq_printf(m, "model\t\t: %s\n"
 				"model name\t: %s\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/setup.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -156,7 +156,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
 #if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
-	conswitchp = &dummy_con;	/* we use take_over_console() later ! */
+	conswitchp = &dummy_con;	/* we use do_take_over_console() later ! */
 #endif
 
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/signal32.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/signal32.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/signal32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/signal32.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,7 +34,6 @@
 #include <asm/uaccess.h>
 
 #include "signal32.h"
-#include "sys32.h"
 
 #define DEBUG_COMPAT_SIG 0 
 #define DEBUG_COMPAT_SIG_LEVEL 2
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/signal.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/signal.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/signal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/signal.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,13 +56,6 @@
 #define A(__x)	((unsigned long)(__x))
 
 /*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-#ifdef CONFIG_64BIT
-#include "sys32.h"
-#endif
-
-/*
  * Do a signal return - restore sigcontext.
  */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/smp.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -62,9 +62,9 @@ static int smp_debug_lvl = 0;
 volatile struct task_struct *smp_init_current_idle_task;
 
 /* track which CPU is booting */
-static volatile int cpu_now_booting __cpuinitdata;
+static volatile int cpu_now_booting;
 
-static int parisc_max_cpus __cpuinitdata = 1;
+static int parisc_max_cpus = 1;
 
 static DEFINE_PER_CPU(spinlock_t, ipi_lock);
 
@@ -328,7 +328,7 @@ void __init smp_callin(void)
 /*
  * Bring one cpu online.
  */
-int __cpuinit smp_boot_one_cpu(int cpuid, struct task_struct *idle)
+int smp_boot_one_cpu(int cpuid, struct task_struct *idle)
 {
 	const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
 	long timeout;
@@ -424,7 +424,7 @@ void smp_cpus_done(unsigned int cpu_max)
 }
 
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	if (cpu != 0 && cpu < parisc_max_cpus)
 		smp_boot_one_cpu(cpu, tidle);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/sys32.h linux-libre-3.11-rc7-gnu/arch/parisc/kernel/sys32.h
--- linux-libre-3.10-gnu/arch/parisc/kernel/sys32.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/sys32.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/* 
- *    Copyright (C) 2002 Richard Hirst <rhirst at parisc-linux.org>
- *    Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
- *    Copyright (C) 2003 Randolph Chung <tausq with parisc-linux.org>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef _PARISC64_KERNEL_SYS32_H
-#define _PARISC64_KERNEL_SYS32_H
-
-#include <linux/compat.h>
-
-/* Call a kernel syscall which will use kernel space instead of user
- * space for its copy_to/from_user.
- */
-#define KERNEL_SYSCALL(ret, syscall, args...) \
-{ \
-    mm_segment_t old_fs = get_fs(); \
-    set_fs(KERNEL_DS); \
-    ret = syscall(args); \
-    set_fs (old_fs); \
-}
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/kernel/sys_parisc32.c linux-libre-3.11-rc7-gnu/arch/parisc/kernel/sys_parisc32.c
--- linux-libre-3.10-gnu/arch/parisc/kernel/sys_parisc32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/kernel/sys_parisc32.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,8 +42,6 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 
-#include "sys32.h"
-
 #undef DEBUG
 
 #ifdef DEBUG
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/lib/memcpy.c linux-libre-3.11-rc7-gnu/arch/parisc/lib/memcpy.c
--- linux-libre-3.10-gnu/arch/parisc/lib/memcpy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/lib/memcpy.c	2013-08-25 20:43:22.000000000 -0400
@@ -2,6 +2,7 @@
  *    Optimized memory copy routines.
  *
  *    Copyright (C) 2004 Randolph Chung <tausq@debian.org>
+ *    Copyright (C) 2013 Helge Deller <deller@gmx.de>
  *
  *    This program is free software; you can redistribute it and/or modify
  *    it under the terms of the GNU General Public License as published by
@@ -153,17 +154,21 @@ static inline void prefetch_dst(const vo
 #define prefetch_dst(addr) do { } while(0)
 #endif
 
+#define PA_MEMCPY_OK		0
+#define PA_MEMCPY_LOAD_ERROR	1
+#define PA_MEMCPY_STORE_ERROR	2
+
 /* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words
  * per loop.  This code is derived from glibc. 
  */
-static inline unsigned long copy_dstaligned(unsigned long dst, unsigned long src, unsigned long len, unsigned long o_dst, unsigned long o_src, unsigned long o_len)
+static inline unsigned long copy_dstaligned(unsigned long dst,
+					unsigned long src, unsigned long len)
 {
 	/* gcc complains that a2 and a3 may be uninitialized, but actually
 	 * they cannot be.  Initialize a2/a3 to shut gcc up.
 	 */
 	register unsigned int a0, a1, a2 = 0, a3 = 0;
 	int sh_1, sh_2;
-	struct exception_data *d;
 
 	/* prefetch_src((const void *)src); */
 
@@ -197,7 +202,7 @@ static inline unsigned long copy_dstalig
 			goto do2;
 		case 0:
 			if (len == 0)
-				return 0;
+				return PA_MEMCPY_OK;
 			/* a3 = ((unsigned int *) src)[0];
 			   a0 = ((unsigned int *) src)[1]; */
 			ldw(s_space, 0, src, a3, cda_ldw_exc);
@@ -256,42 +261,35 @@ do0:
 	preserve_branch(handle_load_error);
 	preserve_branch(handle_store_error);
 
-	return 0;
+	return PA_MEMCPY_OK;
 
 handle_load_error:
 	__asm__ __volatile__ ("cda_ldw_exc:\n");
-	d = &__get_cpu_var(exception_data);
-	DPRINTF("cda_ldw_exc: o_len=%lu fault_addr=%lu o_src=%lu ret=%lu\n",
-		o_len, d->fault_addr, o_src, o_len - d->fault_addr + o_src);
-	return o_len * 4 - d->fault_addr + o_src;
+	return PA_MEMCPY_LOAD_ERROR;
 
 handle_store_error:
 	__asm__ __volatile__ ("cda_stw_exc:\n");
-	d = &__get_cpu_var(exception_data);
-	DPRINTF("cda_stw_exc: o_len=%lu fault_addr=%lu o_dst=%lu ret=%lu\n",
-		o_len, d->fault_addr, o_dst, o_len - d->fault_addr + o_dst);
-	return o_len * 4 - d->fault_addr + o_dst;
+	return PA_MEMCPY_STORE_ERROR;
 }
 
 
-/* Returns 0 for success, otherwise, returns number of bytes not transferred. */
-static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
+/* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR.
+ * In case of an access fault the faulty address can be read from the per_cpu
+ * exception data struct. */
+static unsigned long pa_memcpy_internal(void *dstp, const void *srcp,
+					unsigned long len)
 {
 	register unsigned long src, dst, t1, t2, t3;
 	register unsigned char *pcs, *pcd;
 	register unsigned int *pws, *pwd;
 	register double *pds, *pdd;
-	unsigned long ret = 0;
-	unsigned long o_dst, o_src, o_len;
-	struct exception_data *d;
+	unsigned long ret;
 
 	src = (unsigned long)srcp;
 	dst = (unsigned long)dstp;
 	pcs = (unsigned char *)srcp;
 	pcd = (unsigned char *)dstp;
 
-	o_dst = dst; o_src = src; o_len = len;
-
 	/* prefetch_src((const void *)srcp); */
 
 	if (len < THRESHOLD)
@@ -401,7 +399,7 @@ byte_copy:
 		len--;
 	}
 
-	return 0;
+	return PA_MEMCPY_OK;
 
 unaligned_copy:
 	/* possibly we are aligned on a word, but not on a double... */
@@ -438,8 +436,7 @@ unaligned_copy:
 		src = (unsigned long)pcs;
 	}
 
-	ret = copy_dstaligned(dst, src, len / sizeof(unsigned int), 
-		o_dst, o_src, o_len);
+	ret = copy_dstaligned(dst, src, len / sizeof(unsigned int));
 	if (ret)
 		return ret;
 
@@ -454,17 +451,41 @@ unaligned_copy:
 
 handle_load_error:
 	__asm__ __volatile__ ("pmc_load_exc:\n");
-	d = &__get_cpu_var(exception_data);
-	DPRINTF("pmc_load_exc: o_len=%lu fault_addr=%lu o_src=%lu ret=%lu\n",
-		o_len, d->fault_addr, o_src, o_len - d->fault_addr + o_src);
-	return o_len - d->fault_addr + o_src;
+	return PA_MEMCPY_LOAD_ERROR;
 
 handle_store_error:
 	__asm__ __volatile__ ("pmc_store_exc:\n");
+	return PA_MEMCPY_STORE_ERROR;
+}
+
+
+/* Returns 0 for success, otherwise, returns number of bytes not transferred. */
+static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
+{
+	unsigned long ret, fault_addr, reference;
+	struct exception_data *d;
+
+	ret = pa_memcpy_internal(dstp, srcp, len);
+	if (likely(ret == PA_MEMCPY_OK))
+		return 0;
+
+	/* if a load or store fault occured we can get the faulty addr */
 	d = &__get_cpu_var(exception_data);
-	DPRINTF("pmc_store_exc: o_len=%lu fault_addr=%lu o_dst=%lu ret=%lu\n",
-		o_len, d->fault_addr, o_dst, o_len - d->fault_addr + o_dst);
-	return o_len - d->fault_addr + o_dst;
+	fault_addr = d->fault_addr;
+
+	/* error in load or store? */
+	if (ret == PA_MEMCPY_LOAD_ERROR)
+		reference = (unsigned long) srcp;
+	else
+		reference = (unsigned long) dstp;
+
+	DPRINTF("pa_memcpy: fault type = %lu, len=%lu fault_addr=%lu ref=%lu\n",
+		ret, len, fault_addr, reference);
+
+	if (fault_addr >= reference)
+		return len - (fault_addr - reference);
+	else
+		return len;
 }
 
 #ifdef __KERNEL__
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/Makefile linux-libre-3.11-rc7-gnu/arch/parisc/Makefile
--- linux-libre-3.10-gnu/arch/parisc/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,8 @@
 # Mike Shaver, Helge Deller and Martin K. Petersen
 #
 
+KBUILD_IMAGE := vmlinuz
+
 KBUILD_DEFCONFIG := default_defconfig
 
 NM		= sh $(srctree)/arch/parisc/nm
@@ -92,7 +94,7 @@ PALOCONF := $(shell if [ -f $(src)/palo.
 	else echo $(obj)/palo.conf; \
 	fi)
 
-palo: vmlinux
+palo: vmlinuz
 	@if test ! -x "$(PALO)"; then \
 		echo 'ERROR: Please install palo first (apt-get install palo)';\
 		echo 'or build it from source and install it somewhere in your $$PATH';\
@@ -107,10 +109,14 @@ palo: vmlinux
 	fi
 	$(PALO) -f $(PALOCONF)
 
-# Shorthands for known targets not supported by parisc, use vmlinux as default
-Image zImage bzImage: vmlinux
+# Shorthands for known targets not supported by parisc, use vmlinux/vmlinuz as default
+Image: vmlinux
+zImage bzImage: vmlinuz
 
-install: vmlinux
+vmlinuz: vmlinux
+	@gzip -cf -9 $< > $@
+
+install: vmlinuz
 	sh $(src)/arch/parisc/install.sh \
 			$(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
 
@@ -119,6 +125,7 @@ MRPROPER_FILES	+= palo.conf
 
 define archhelp
 	@echo  '* vmlinux	- Uncompressed kernel image (./vmlinux)'
+	@echo  '  vmlinuz	- Compressed kernel image (./vmlinuz)'
 	@echo  '  palo		- Bootable image (./lifimage)'
 	@echo  '  install	- Install kernel using'
 	@echo  '		  (your) ~/bin/$(INSTALLKERNEL) or'
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/parisc/mm/init.c linux-libre-3.11-rc7-gnu/arch/parisc/mm/init.c
--- linux-libre-3.10-gnu/arch/parisc/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/parisc/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -214,7 +214,6 @@ static void __init setup_bootmem(void)
 	mem_limit_func();       /* check for "mem=" argument */
 
 	mem_max = 0;
-	num_physpages = 0;
 	for (i = 0; i < npmem_ranges; i++) {
 		unsigned long rsize;
 
@@ -229,10 +228,8 @@ static void __init setup_bootmem(void)
 				npmem_ranges = i + 1;
 				mem_max = mem_limit;
 			}
-	        num_physpages += pmem_ranges[i].pages;
 			break;
 		}
-	    num_physpages += pmem_ranges[i].pages;
 		mem_max += rsize;
 	}
 
@@ -532,7 +529,7 @@ void free_initmem(void)
 	 * pages are no-longer executable */
 	flush_icache_range(init_begin, init_end);
 	
-	num_physpages += free_initmem_default(0);
+	free_initmem_default(-1);
 
 	/* set up a new led state on systems shipped LED State panel */
 	pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE);
@@ -580,8 +577,6 @@ unsigned long pcxl_dma_start __read_most
 
 void __init mem_init(void)
 {
-	int codesize, reservedpages, datasize, initsize;
-
 	/* Do sanity checks on page table constants */
 	BUILD_BUG_ON(PTE_ENTRY_SIZE != sizeof(pte_t));
 	BUILD_BUG_ON(PMD_ENTRY_SIZE != sizeof(pmd_t));
@@ -590,45 +585,8 @@ void __init mem_init(void)
 			> BITS_PER_LONG);
 
 	high_memory = __va((max_pfn << PAGE_SHIFT));
-
-#ifndef CONFIG_DISCONTIGMEM
-	max_mapnr = page_to_pfn(virt_to_page(high_memory - 1)) + 1;
-	totalram_pages += free_all_bootmem();
-#else
-	{
-		int i;
-
-		for (i = 0; i < npmem_ranges; i++)
-			totalram_pages += free_all_bootmem_node(NODE_DATA(i));
-	}
-#endif
-
-	codesize = (unsigned long)_etext - (unsigned long)_text;
-	datasize = (unsigned long)_edata - (unsigned long)_etext;
-	initsize = (unsigned long)__init_end - (unsigned long)__init_begin;
-
-	reservedpages = 0;
-{
-	unsigned long pfn;
-#ifdef CONFIG_DISCONTIGMEM
-	int i;
-
-	for (i = 0; i < npmem_ranges; i++) {
-		for (pfn = node_start_pfn(i); pfn < node_end_pfn(i); pfn++) {
-			if (PageReserved(pfn_to_page(pfn)))
-				reservedpages++;
-		}
-	}
-#else /* !CONFIG_DISCONTIGMEM */
-	for (pfn = 0; pfn < max_pfn; pfn++) {
-		/*
-		 * Only count reserved RAM pages
-		 */
-		if (PageReserved(pfn_to_page(pfn)))
-			reservedpages++;
-	}
-#endif
-}
+	set_max_mapnr(page_to_pfn(virt_to_page(high_memory - 1)) + 1);
+	free_all_bootmem();
 
 #ifdef CONFIG_PA11
 	if (hppa_dma_ops == &pcxl_dma_ops) {
@@ -643,15 +601,7 @@ void __init mem_init(void)
 	parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
 #endif
 
-	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10,
-		reservedpages << (PAGE_SHIFT-10),
-		datasize >> 10,
-		initsize >> 10
-	);
-
+	mem_init_print_info(NULL);
 #ifdef CONFIG_DEBUG_KERNEL /* double-sanity-check paranoia */
 	printk("virtual kernel memory layout:\n"
 	       "    vmalloc : 0x%p - 0x%p   (%4ld MB)\n"
@@ -1101,6 +1051,6 @@ void flush_tlb_all(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	num_physpages += free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/boot/dts/currituck.dts linux-libre-3.11-rc7-gnu/arch/powerpc/boot/dts/currituck.dts
--- linux-libre-3.10-gnu/arch/powerpc/boot/dts/currituck.dts	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/boot/dts/currituck.dts	2013-08-25 20:43:22.000000000 -0400
@@ -103,6 +103,11 @@
 				interrupts = <34 2>;
 			};
 
+			FPGA0: fpga@50000000 {
+				compatible = "ibm,currituck-fpga";
+				reg = <0x50000000 0x4>;
+			};
+
 			IIC0: i2c@00000000 {
 				compatible = "ibm,iic-currituck", "ibm,iic";
 				reg = <0x0 0x00000014>;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi linux-libre-3.11-rc7-gnu/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi
--- linux-libre-3.10-gnu/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * T4 Interlaken Look-aside Controller (LAC) device tree stub
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+lac: lac@229000 {
+	compatible = "fsl,interlaken-lac";
+	reg = <0x229000 0x1000>;
+	interrupts = <16 2 1 18>;
+};
+
+lac-hv@228000 {
+	compatible = "fsl,interlaken-lac-hv";
+	reg = <0x228000 0x1000>;
+	fsl,non-hv-node = <&lac>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi linux-libre-3.11-rc7-gnu/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi
--- linux-libre-3.10-gnu/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,156 @@
+/* T4240 Interlaken LAC Portal device tree stub with 24 portals.
+ *
+ * Copyright 2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#address-cells = <0x1>;
+#size-cells = <0x1>;
+compatible = "fsl,interlaken-lac-portals";
+
+lportal0: lac-portal@0 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x0 0x1000>;
+};
+
+lportal1: lac-portal@1000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x1000 0x1000>;
+};
+
+lportal2: lac-portal@2000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x2000 0x1000>;
+};
+
+lportal3: lac-portal@3000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x3000 0x1000>;
+};
+
+lportal4: lac-portal@4000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x4000 0x1000>;
+};
+
+lportal5: lac-portal@5000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x5000 0x1000>;
+};
+
+lportal6: lac-portal@6000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x6000 0x1000>;
+};
+
+lportal7: lac-portal@7000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x7000 0x1000>;
+};
+
+lportal8: lac-portal@8000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x8000 0x1000>;
+};
+
+lportal9: lac-portal@9000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x9000 0x1000>;
+};
+
+lportal10: lac-portal@A000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0xA000 0x1000>;
+};
+
+lportal11: lac-portal@B000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0xB000 0x1000>;
+};
+
+lportal12: lac-portal@C000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0xC000 0x1000>;
+};
+
+lportal13: lac-portal@D000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0xD000 0x1000>;
+};
+
+lportal14: lac-portal@E000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0xE000 0x1000>;
+};
+
+lportal15: lac-portal@F000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0xF000 0x1000>;
+};
+
+lportal16: lac-portal@10000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x10000 0x1000>;
+};
+
+lportal17: lac-portal@11000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x11000 0x1000>;
+};
+
+lportal18: lac-portal@1200 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x12000 0x1000>;
+};
+
+lportal19: lac-portal@13000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x13000 0x1000>;
+};
+
+lportal20: lac-portal@14000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x14000 0x1000>;
+};
+
+lportal21: lac-portal@15000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x15000 0x1000>;
+};
+
+lportal22: lac-portal@16000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x16000 0x1000>;
+};
+
+lportal23: lac-portal@17000 {
+	compatible = "fsl,interlaken-lac-portal-v1.0";
+	reg = <0x17000 0x1000>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/c2k_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/c2k_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/c2k_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/c2k_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -423,6 +423,8 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/g5_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/g5_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/g5_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/g5_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -284,6 +284,8 @@ CONFIG_DEBUG_MUTEXES=y
 CONFIG_LATENCYTOP=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_ECB=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/maple_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/maple_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/maple_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/maple_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -138,6 +138,8 @@ CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_XMON=y
 CONFIG_XMON_DEFAULT=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/mpc512x_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/mpc512x_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/mpc512x_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/mpc512x_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,6 @@
-CONFIG_EXPERIMENTAL=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
-CONFIG_SPARSE_IRQ=y
+CONFIG_NO_HZ=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_COMPAT_BRK is not set
@@ -9,6 +8,7 @@ CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
 # CONFIG_IOSCHED_CFQ is not set
 # CONFIG_PPC_CHRP is not set
 CONFIG_PPC_MPC512x=y
@@ -16,9 +16,7 @@ CONFIG_MPC5121_ADS=y
 CONFIG_MPC512x_GENERIC=y
 CONFIG_PDM360NG=y
 # CONFIG_PPC_PMAC is not set
-CONFIG_NO_HZ=y
 CONFIG_HZ_1000=y
-# CONFIG_MIGRATION is not set
 # CONFIG_SECCOMP is not set
 # CONFIG_PCI is not set
 CONFIG_NET=y
@@ -33,8 +31,6 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 CONFIG_CAN=y
-CONFIG_CAN_RAW=y
-CONFIG_CAN_BCM=y
 CONFIG_CAN_VCAN=y
 CONFIG_CAN_MSCAN=y
 CONFIG_CAN_DEBUG_DEVICES=y
@@ -46,7 +42,6 @@ CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_AMDSTD=y
@@ -60,7 +55,6 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=1
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_XIP=y
-CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_AT24=y
 CONFIG_EEPROM_AT25=y
 CONFIG_SCSI=y
@@ -68,6 +62,7 @@ CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 CONFIG_NETDEVICES=y
+CONFIG_FS_ENET=y
 CONFIG_MARVELL_PHY=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_QSEMI_PHY=y
@@ -83,10 +78,6 @@ CONFIG_STE10XP=y
 CONFIG_LSI_ET1011C_PHY=y
 CONFIG_FIXED_PHY=y
 CONFIG_MDIO_BITBANG=y
-CONFIG_NET_ETHERNET=y
-CONFIG_FS_ENET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
 # CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_EVDEV=y
@@ -106,14 +97,18 @@ CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_MPC8XXX=y
 # CONFIG_HWMON is not set
 CONFIG_MEDIA_SUPPORT=y
-CONFIG_VIDEO_DEV=y
 CONFIG_VIDEO_ADV_DEBUG=y
-# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
-CONFIG_VIDEO_SAA711X=y
 CONFIG_FB=y
 CONFIG_FB_FSL_DIU=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_FSL=y
+# CONFIG_USB_EHCI_HCD_PPC_OF is not set
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_FSL_USB2=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_M41T80=y
 CONFIG_RTC_DRV_MPC5121=y
@@ -129,9 +124,7 @@ CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_UBIFS_FS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/mpc85xx_smp_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/mpc85xx_smp_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/mpc85xx_smp_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/mpc85xx_smp_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -131,6 +131,7 @@ CONFIG_DUMMY=y
 CONFIG_FS_ENET=y
 CONFIG_UCC_GETH=y
 CONFIG_GIANFAR=y
+CONFIG_E1000E=y
 CONFIG_MARVELL_PHY=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_CICADA_PHY=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/pmac32_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/pmac32_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/pmac32_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/pmac32_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -350,6 +350,8 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_XMON=y
 CONFIG_XMON_DEFAULT=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_MD4=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/ppc64_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/ppc64_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/ppc64_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/ppc64_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -58,7 +58,7 @@ CONFIG_SCHED_SMT=y
 CONFIG_PPC_DENORMALISATION=y
 CONFIG_PCCARD=y
 CONFIG_ELECTRA_CF=y
-CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_RPA=m
 CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
 CONFIG_PACKET=y
@@ -398,6 +398,8 @@ CONFIG_FTR_FIXUP_SELFTEST=y
 CONFIG_MSI_BITMAP_SELFTEST=y
 CONFIG_XMON=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_PCBC=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/ppc64e_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/ppc64e_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/ppc64e_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/ppc64e_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,7 @@ CONFIG_IRQ_ALL_CPUS=y
 CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_PCI_MSI=y
 CONFIG_PCCARD=y
-CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_XFRM_USER=m
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/ppc6xx_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/ppc6xx_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/ppc6xx_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/ppc6xx_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1264,6 +1264,8 @@ CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_XMON=y
 CONFIG_BOOTX_TEXT=y
+CONFIG_PPC_EARLY_DEBUG=y
+CONFIG_PPC_EARLY_DEBUG_BOOTX=y
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/configs/pseries_defconfig linux-libre-3.11-rc7-gnu/arch/powerpc/configs/pseries_defconfig
--- linux-libre-3.10-gnu/arch/powerpc/configs/pseries_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/configs/pseries_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -53,7 +53,7 @@ CONFIG_PPC_64K_PAGES=y
 CONFIG_PPC_SUBPAGE_PROT=y
 CONFIG_SCHED_SMT=y
 CONFIG_PPC_DENORMALISATION=y
-CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_RPA=m
 CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
 CONFIG_PACKET=y
@@ -296,6 +296,7 @@ CONFIG_SQUASHFS=m
 CONFIG_SQUASHFS_XATTR=y
 CONFIG_SQUASHFS_LZO=y
 CONFIG_SQUASHFS_XZ=y
+CONFIG_PSTORE=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/eeh_event.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/eeh_event.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/eeh_event.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/eeh_event.h	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,9 @@ struct eeh_event {
 	struct eeh_pe		*pe;	/* EEH PE		*/
 };
 
+int eeh_event_init(void);
 int eeh_send_failure_event(struct eeh_pe *pe);
+void eeh_remove_event(struct eeh_pe *pe);
 void eeh_handle_event(struct eeh_pe *pe);
 
 #endif /* __KERNEL__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/eeh.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/eeh.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/eeh.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/eeh.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/string.h>
+#include <linux/time.h>
 
 struct pci_dev;
 struct pci_bus;
@@ -52,6 +53,9 @@ struct device_node;
 
 #define EEH_PE_ISOLATED		(1 << 0)	/* Isolated PE		*/
 #define EEH_PE_RECOVERING	(1 << 1)	/* Recovering PE	*/
+#define EEH_PE_PHB_DEAD		(1 << 2)	/* Dead PHB		*/
+
+#define EEH_PE_KEEP		(1 << 8)	/* Keep PE on hotplug	*/
 
 struct eeh_pe {
 	int type;			/* PE type: PHB/Bus/Device	*/
@@ -59,8 +63,10 @@ struct eeh_pe {
 	int config_addr;		/* Traditional PCI address	*/
 	int addr;			/* PE configuration address	*/
 	struct pci_controller *phb;	/* Associated PHB		*/
+	struct pci_bus *bus;		/* Top PCI bus for bus PE	*/
 	int check_count;		/* Times of ignored error	*/
 	int freeze_count;		/* Times of froze up		*/
+	struct timeval tstamp;		/* Time on first-time freeze	*/
 	int false_positives;		/* Times of reported #ff's	*/
 	struct eeh_pe *parent;		/* Parent PE			*/
 	struct list_head child_list;	/* Link PE to the child list	*/
@@ -68,8 +74,8 @@ struct eeh_pe {
 	struct list_head child;		/* Child PEs			*/
 };
 
-#define eeh_pe_for_each_dev(pe, edev) \
-		list_for_each_entry(edev, &pe->edevs, list)
+#define eeh_pe_for_each_dev(pe, edev, tmp) \
+		list_for_each_entry_safe(edev, tmp, &pe->edevs, list)
 
 /*
  * The struct is used to trace EEH state for the associated
@@ -78,7 +84,13 @@ struct eeh_pe {
  * another tree except the currently existing tree of PCI
  * buses and PCI devices
  */
-#define EEH_DEV_IRQ_DISABLED	(1<<0)	/* Interrupt disabled		*/
+#define EEH_DEV_BRIDGE		(1 << 0)	/* PCI bridge		*/
+#define EEH_DEV_ROOT_PORT	(1 << 1)	/* PCIe root port	*/
+#define EEH_DEV_DS_PORT		(1 << 2)	/* Downstream port	*/
+#define EEH_DEV_IRQ_DISABLED	(1 << 3)	/* Interrupt disabled	*/
+#define EEH_DEV_DISCONNECTED	(1 << 4)	/* Removing from PE	*/
+
+#define EEH_DEV_SYSFS		(1 << 8)	/* Sysfs created        */
 
 struct eeh_dev {
 	int mode;			/* EEH mode			*/
@@ -86,21 +98,23 @@ struct eeh_dev {
 	int config_addr;		/* Config address		*/
 	int pe_config_addr;		/* PE config address		*/
 	u32 config_space[16];		/* Saved PCI config space	*/
+	u8 pcie_cap;			/* Saved PCIe capability	*/
 	struct eeh_pe *pe;		/* Associated PE		*/
 	struct list_head list;		/* Form link list in the PE	*/
 	struct pci_controller *phb;	/* Associated PHB		*/
 	struct device_node *dn;		/* Associated device node	*/
 	struct pci_dev *pdev;		/* Associated PCI device	*/
+	struct pci_bus *bus;		/* PCI bus for partial hotplug	*/
 };
 
 static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev)
 {
-	return edev->dn;
+	return edev ? edev->dn : NULL;
 }
 
 static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev)
 {
-	return edev->pdev;
+	return edev ? edev->pdev : NULL;
 }
 
 /*
@@ -130,8 +144,9 @@ static inline struct pci_dev *eeh_dev_to
 struct eeh_ops {
 	char *name;
 	int (*init)(void);
+	int (*post_init)(void);
 	void* (*of_probe)(struct device_node *dn, void *flag);
-	void* (*dev_probe)(struct pci_dev *dev, void *flag);
+	int (*dev_probe)(struct pci_dev *dev, void *flag);
 	int (*set_option)(struct eeh_pe *pe, int option);
 	int (*get_pe_addr)(struct eeh_pe *pe);
 	int (*get_state)(struct eeh_pe *pe, int *state);
@@ -141,11 +156,12 @@ struct eeh_ops {
 	int (*configure_bridge)(struct eeh_pe *pe);
 	int (*read_config)(struct device_node *dn, int where, int size, u32 *val);
 	int (*write_config)(struct device_node *dn, int where, int size, u32 val);
+	int (*next_error)(struct eeh_pe **pe);
 };
 
 extern struct eeh_ops *eeh_ops;
 extern int eeh_subsystem_enabled;
-extern struct mutex eeh_mutex;
+extern raw_spinlock_t confirm_error_lock;
 extern int eeh_probe_mode;
 
 #define EEH_PROBE_MODE_DEV	(1<<0)	/* From PCI device	*/
@@ -166,14 +182,14 @@ static inline int eeh_probe_mode_dev(voi
 	return (eeh_probe_mode == EEH_PROBE_MODE_DEV);
 }
 
-static inline void eeh_lock(void)
+static inline void eeh_serialize_lock(unsigned long *flags)
 {
-	mutex_lock(&eeh_mutex);
+	raw_spin_lock_irqsave(&confirm_error_lock, *flags);
 }
 
-static inline void eeh_unlock(void)
+static inline void eeh_serialize_unlock(unsigned long flags)
 {
-	mutex_unlock(&eeh_mutex);
+	raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
 }
 
 /*
@@ -184,8 +200,13 @@ static inline void eeh_unlock(void)
 
 typedef void *(*eeh_traverse_func)(void *data, void *flag);
 int eeh_phb_pe_create(struct pci_controller *phb);
+struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb);
+struct eeh_pe *eeh_pe_get(struct eeh_dev *edev);
 int eeh_add_to_parent_pe(struct eeh_dev *edev);
-int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe);
+int eeh_rmv_from_parent_pe(struct eeh_dev *edev);
+void eeh_pe_update_time_stamp(struct eeh_pe *pe);
+void *eeh_pe_traverse(struct eeh_pe *root,
+		eeh_traverse_func fn, void *flag);
 void *eeh_pe_dev_traverse(struct eeh_pe *root,
 		eeh_traverse_func fn, void *flag);
 void eeh_pe_restore_bars(struct eeh_pe *pe);
@@ -193,16 +214,19 @@ struct pci_bus *eeh_pe_bus_get(struct ee
 
 void *eeh_dev_init(struct device_node *dn, void *data);
 void eeh_dev_phb_init_dynamic(struct pci_controller *phb);
+int eeh_init(void);
 int __init eeh_ops_register(struct eeh_ops *ops);
 int __exit eeh_ops_unregister(const char *name);
 unsigned long eeh_check_failure(const volatile void __iomem *token,
 				unsigned long val);
 int eeh_dev_check_failure(struct eeh_dev *edev);
-void __init eeh_addr_cache_build(void);
+void eeh_addr_cache_build(void);
+void eeh_add_device_early(struct device_node *);
 void eeh_add_device_tree_early(struct device_node *);
+void eeh_add_device_late(struct pci_dev *);
 void eeh_add_device_tree_late(struct pci_bus *);
 void eeh_add_sysfs_files(struct pci_bus *);
-void eeh_remove_bus_device(struct pci_dev *, int);
+void eeh_remove_device(struct pci_dev *);
 
 /**
  * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
@@ -221,6 +245,11 @@ void eeh_remove_bus_device(struct pci_de
 
 #else /* !CONFIG_EEH */
 
+static inline int eeh_init(void)
+{
+	return 0;
+}
+
 static inline void *eeh_dev_init(struct device_node *dn, void *data)
 {
 	return NULL;
@@ -237,16 +266,17 @@ static inline unsigned long eeh_check_fa
 
 static inline void eeh_addr_cache_build(void) { }
 
+static inline void eeh_add_device_early(struct device_node *dn) { }
+
 static inline void eeh_add_device_tree_early(struct device_node *dn) { }
 
+static inline void eeh_add_device_late(struct pci_dev *dev) { }
+
 static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }
 
 static inline void eeh_add_sysfs_files(struct pci_bus *bus) { }
 
-static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { }
-
-static inline void eeh_lock(void) { }
-static inline void eeh_unlock(void) { }
+static inline void eeh_remove_device(struct pci_dev *dev) { }
 
 #define EEH_POSSIBLE_ERROR(val, type) (0)
 #define EEH_IO_ERROR_VALUE(size) (-1UL)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/exception-64s.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/exception-64s.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/exception-64s.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/exception-64s.h	2013-08-25 20:43:22.000000000 -0400
@@ -358,12 +358,12 @@ label##_relon_pSeries:					\
 	/* No guest interrupts come through here */	\
 	SET_SCRATCH0(r13);		/* save r13 */	\
 	EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
-				       EXC_STD, KVMTEST_PR, vec)
+				       EXC_STD, NOTEST, vec)
 
 #define STD_RELON_EXCEPTION_PSERIES_OOL(vec, label)		\
 	.globl label##_relon_pSeries;				\
 label##_relon_pSeries:						\
-	EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec);	\
+	EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec);		\
 	EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, EXC_STD)
 
 #define STD_RELON_EXCEPTION_HV(loc, vec, label)		\
@@ -374,12 +374,12 @@ label##_relon_hv:					\
 	/* No guest interrupts come through here */	\
 	SET_SCRATCH0(r13);	/* save r13 */		\
 	EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
-				       EXC_HV, KVMTEST, vec)
+				       EXC_HV, NOTEST, vec)
 
 #define STD_RELON_EXCEPTION_HV_OOL(vec, label)			\
 	.globl label##_relon_hv;				\
 label##_relon_hv:						\
-	EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, vec);		\
+	EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec);		\
 	EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, EXC_HV)
 
 /* This associate vector numbers with bits in paca->irq_happened */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/hugetlb.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/hugetlb.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/hugetlb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/hugetlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -191,8 +191,14 @@ static inline void flush_hugetlb_page(st
 				      unsigned long vmaddr)
 {
 }
-#endif /* CONFIG_HUGETLB_PAGE */
 
+#define hugepd_shift(x) 0
+static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr,
+				    unsigned pdshift)
+{
+	return 0;
+}
+#endif /* CONFIG_HUGETLB_PAGE */
 
 /*
  * FSL Book3E platforms require special gpage handling - the gpages
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/hw_irq.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/hw_irq.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/hw_irq.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/hw_irq.h	2013-08-25 20:43:22.000000000 -0400
@@ -96,10 +96,11 @@ static inline bool arch_irqs_disabled(vo
 #endif
 
 #define hard_irq_disable()	do {			\
-	u8 _was_enabled = get_paca()->soft_enabled;	\
+	u8 _was_enabled;				\
 	__hard_irq_disable();				\
-	get_paca()->soft_enabled = 0;			\
-	get_paca()->irq_happened |= PACA_IRQ_HARD_DIS;	\
+	_was_enabled = local_paca->soft_enabled;	\
+	local_paca->soft_enabled = 0;			\
+	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;	\
 	if (_was_enabled)				\
 		trace_hardirqs_off();			\
 } while(0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/ibmebus.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/ibmebus.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/ibmebus.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/ibmebus.h	2013-08-25 20:43:22.000000000 -0400
@@ -48,8 +48,8 @@
 
 extern struct bus_type ibmebus_bus_type;
 
-int ibmebus_register_driver(struct of_platform_driver *drv);
-void ibmebus_unregister_driver(struct of_platform_driver *drv);
+int ibmebus_register_driver(struct platform_driver *drv);
+void ibmebus_unregister_driver(struct platform_driver *drv);
 
 int ibmebus_request_irq(u32 ist, irq_handler_t handler,
 			unsigned long irq_flags, const char *devname,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/iommu.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/iommu.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/iommu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/iommu.h	2013-08-25 20:43:22.000000000 -0400
@@ -76,6 +76,9 @@ struct iommu_table {
 	struct iommu_pool large_pool;
 	struct iommu_pool pools[IOMMU_NR_POOLS];
 	unsigned long *it_map;       /* A simple allocation bitmap for now */
+#ifdef CONFIG_IOMMU_API
+	struct iommu_group *it_group;
+#endif
 };
 
 struct scatterlist;
@@ -98,6 +101,8 @@ extern void iommu_free_table(struct iomm
  */
 extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
 					    int nid);
+extern void iommu_register_group(struct iommu_table *tbl,
+				 int pci_domain_number, unsigned long pe_num);
 
 extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
 			struct scatterlist *sglist, int nelems,
@@ -125,13 +130,6 @@ extern void iommu_init_early_pSeries(voi
 extern void iommu_init_early_dart(void);
 extern void iommu_init_early_pasemi(void);
 
-#ifdef CONFIG_PCI
-extern void pci_iommu_init(void);
-extern void pci_direct_iommu_init(void);
-#else
-static inline void pci_iommu_init(void) { }
-#endif
-
 extern void alloc_dart_table(void);
 #if defined(CONFIG_PPC64) && defined(CONFIG_PM)
 static inline void iommu_save(void)
@@ -147,5 +145,26 @@ static inline void iommu_restore(void)
 }
 #endif
 
+/* The API to support IOMMU operations for VFIO */
+extern int iommu_tce_clear_param_check(struct iommu_table *tbl,
+		unsigned long ioba, unsigned long tce_value,
+		unsigned long npages);
+extern int iommu_tce_put_param_check(struct iommu_table *tbl,
+		unsigned long ioba, unsigned long tce);
+extern int iommu_tce_build(struct iommu_table *tbl, unsigned long entry,
+		unsigned long hwaddr, enum dma_data_direction direction);
+extern unsigned long iommu_clear_tce(struct iommu_table *tbl,
+		unsigned long entry);
+extern int iommu_clear_tces_and_put_pages(struct iommu_table *tbl,
+		unsigned long entry, unsigned long pages);
+extern int iommu_put_tce_user_mode(struct iommu_table *tbl,
+		unsigned long entry, unsigned long tce);
+
+extern void iommu_flush_tce(struct iommu_table *tbl);
+extern int iommu_take_ownership(struct iommu_table *tbl);
+extern void iommu_release_ownership(struct iommu_table *tbl);
+
+extern enum dma_data_direction iommu_tce_direction(unsigned long tce);
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_IOMMU_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/kvm_book3s_64.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/kvm_book3s_64.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/kvm_book3s_64.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/kvm_book3s_64.h	2013-08-25 20:43:22.000000000 -0400
@@ -159,36 +159,46 @@ static inline int hpte_cache_flags_ok(un
 }
 
 /*
- * Lock and read a linux PTE.  If it's present and writable, atomically
- * set dirty and referenced bits and return the PTE, otherwise return 0.
+ * If it's present and writable, atomically set dirty and referenced bits and
+ * return the PTE, otherwise return 0. If we find a transparent hugepage
+ * and if it is marked splitting we return 0;
  */
-static inline pte_t kvmppc_read_update_linux_pte(pte_t *p, int writing)
+static inline pte_t kvmppc_read_update_linux_pte(pte_t *ptep, int writing,
+						 unsigned int hugepage)
 {
-	pte_t pte, tmp;
-
-	/* wait until _PAGE_BUSY is clear then set it atomically */
-	__asm__ __volatile__ (
-		"1:	ldarx	%0,0,%3\n"
-		"	andi.	%1,%0,%4\n"
-		"	bne-	1b\n"
-		"	ori	%1,%0,%4\n"
-		"	stdcx.	%1,0,%3\n"
-		"	bne-	1b"
-		: "=&r" (pte), "=&r" (tmp), "=m" (*p)
-		: "r" (p), "i" (_PAGE_BUSY)
-		: "cc");
+	pte_t old_pte, new_pte = __pte(0);
 
-	if (pte_present(pte)) {
-		pte = pte_mkyoung(pte);
-		if (writing && pte_write(pte))
-			pte = pte_mkdirty(pte);
-	}
+	while (1) {
+		old_pte = pte_val(*ptep);
+		/*
+		 * wait until _PAGE_BUSY is clear then set it atomically
+		 */
+		if (unlikely(old_pte & _PAGE_BUSY)) {
+			cpu_relax();
+			continue;
+		}
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+		/* If hugepage and is trans splitting return None */
+		if (unlikely(hugepage &&
+			     pmd_trans_splitting(pte_pmd(old_pte))))
+			return __pte(0);
+#endif
+		/* If pte is not present return None */
+		if (unlikely(!(old_pte & _PAGE_PRESENT)))
+			return __pte(0);
 
-	*p = pte;	/* clears _PAGE_BUSY */
+		new_pte = pte_mkyoung(old_pte);
+		if (writing && pte_write(old_pte))
+			new_pte = pte_mkdirty(new_pte);
 
-	return pte;
+		if (old_pte == __cmpxchg_u64((unsigned long *)ptep, old_pte,
+					     new_pte))
+			break;
+	}
+	return new_pte;
 }
 
+
 /* Return HPTE cache control bits corresponding to Linux pte bits */
 static inline unsigned long hpte_cache_bits(unsigned long pte_val)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/kvm_book3s.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/kvm_book3s.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/kvm_book3s.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/kvm_book3s.h	2013-08-25 20:43:22.000000000 -0400
@@ -107,8 +107,9 @@ struct kvmppc_vcpu_book3s {
 #define CONTEXT_GUEST		1
 #define CONTEXT_GUEST_END	2
 
-#define VSID_REAL	0x1fffffffffc00000ULL
-#define VSID_BAT	0x1fffffffffb00000ULL
+#define VSID_REAL	0x0fffffffffc00000ULL
+#define VSID_BAT	0x0fffffffffb00000ULL
+#define VSID_1T		0x1000000000000000ULL
 #define VSID_REAL_DR	0x2000000000000000ULL
 #define VSID_REAL_IR	0x4000000000000000ULL
 #define VSID_PR		0x8000000000000000ULL
@@ -123,6 +124,7 @@ extern void kvmppc_mmu_book3s_32_init(st
 extern void kvmppc_mmu_book3s_hv_init(struct kvm_vcpu *vcpu);
 extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte);
 extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr);
+extern void kvmppc_mmu_flush_segment(struct kvm_vcpu *vcpu, ulong eaddr, ulong seg_size);
 extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu);
 extern int kvmppc_book3s_hv_page_fault(struct kvm_run *run,
 			struct kvm_vcpu *vcpu, unsigned long addr,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/lppaca.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/lppaca.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/lppaca.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/lppaca.h	2013-08-25 20:43:22.000000000 -0400
@@ -66,7 +66,8 @@ struct lppaca {
 
 	u8	reserved6[48];
 	u8	cede_latency_hint;
-	u8	reserved7[7];
+	u8	ebb_regs_in_use;
+	u8	reserved7[6];
 	u8	dtl_enable_mask;	/* Dispatch Trace Log mask */
 	u8	donate_dedicated_cpu;	/* Donate dedicated CPU cycles */
 	u8	fpregs_in_use;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/machdep.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/machdep.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/machdep.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/machdep.h	2013-08-25 20:43:22.000000000 -0400
@@ -36,13 +36,13 @@ struct machdep_calls {
 #ifdef CONFIG_PPC64
 	void            (*hpte_invalidate)(unsigned long slot,
 					   unsigned long vpn,
-					   int psize, int ssize,
-					   int local);
+					   int bpsize, int apsize,
+					   int ssize, int local);
 	long		(*hpte_updatepp)(unsigned long slot, 
 					 unsigned long newpp, 
 					 unsigned long vpn,
-					 int psize, int ssize,
-					 int local);
+					 int bpsize, int apsize,
+					 int ssize, int local);
 	void            (*hpte_updateboltedpp)(unsigned long newpp, 
 					       unsigned long ea,
 					       int psize, int ssize);
@@ -57,6 +57,9 @@ struct machdep_calls {
 	void            (*hpte_removebolted)(unsigned long ea,
 					     int psize, int ssize);
 	void		(*flush_hash_range)(unsigned long number, int local);
+	void		(*hugepage_invalidate)(struct mm_struct *mm,
+					       unsigned char *hpte_slot_array,
+					       unsigned long addr, int psize);
 
 	/* special for kexec, to be called in real mode, linear mapping is
 	 * destroyed as well */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/mmu_context.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mmu_context.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/mmu_context.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mmu_context.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,7 @@ extern void drop_cop(unsigned long acop,
 
 /*
  * switch_mm is the entry point called from the architecture independent
- * code in kernel/sched.c
+ * code in kernel/sched/core.c
  */
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 			     struct task_struct *tsk)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/mmu-hash64.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mmu-hash64.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/mmu-hash64.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mmu-hash64.h	2013-08-25 20:43:22.000000000 -0400
@@ -340,6 +340,20 @@ extern int hash_page(unsigned long ea, u
 int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
 		     pte_t *ptep, unsigned long trap, int local, int ssize,
 		     unsigned int shift, unsigned int mmu_psize);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern int __hash_page_thp(unsigned long ea, unsigned long access,
+			   unsigned long vsid, pmd_t *pmdp, unsigned long trap,
+			   int local, int ssize, unsigned int psize);
+#else
+static inline int __hash_page_thp(unsigned long ea, unsigned long access,
+				  unsigned long vsid, pmd_t *pmdp,
+				  unsigned long trap, int local,
+				  int ssize, unsigned int psize)
+{
+	BUG();
+	return -1;
+}
+#endif
 extern void hash_failure_debug(unsigned long ea, unsigned long access,
 			       unsigned long vsid, unsigned long trap,
 			       int ssize, int psize, int lpsize,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/module.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/module.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/module.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/module.h	2013-08-25 20:43:22.000000000 -0400
@@ -82,10 +82,9 @@ struct exception_table_entry;
 void sort_ex_table(struct exception_table_entry *start,
 		   struct exception_table_entry *finish);
 
-#ifdef CONFIG_MODVERSIONS
+#if defined(CONFIG_MODVERSIONS) && defined(CONFIG_PPC64)
 #define ARCH_RELOCATES_KCRCTAB
-
-extern const unsigned long reloc_start[];
+#define reloc_start PHYSICAL_START
 #endif
 #endif /* __KERNEL__ */
 #endif	/* _ASM_POWERPC_MODULE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/mpc5121.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mpc5121.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/mpc5121.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mpc5121.h	2013-08-25 20:43:22.000000000 -0400
@@ -68,6 +68,5 @@ struct mpc512x_lpc {
 };
 
 int mpc512x_cs_config(unsigned int cs, u32 val);
-int __init mpc5121_clk_init(void);
 
 #endif /* __ASM_POWERPC_MPC5121_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/mpc52xx_psc.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mpc52xx_psc.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/mpc52xx_psc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mpc52xx_psc.h	2013-08-25 20:43:22.000000000 -0400
@@ -299,4 +299,53 @@ struct mpc512x_psc_fifo {
 #define rxdata_32 rxdata.rxdata_32
 };
 
+struct mpc5125_psc {
+	u8		mr1;			/* PSC + 0x00 */
+	u8		reserved0[3];
+	u8		mr2;			/* PSC + 0x04 */
+	u8		reserved1[3];
+	struct {
+		u16		status;		/* PSC + 0x08 */
+		u8		reserved2[2];
+		u8		clock_select;	/* PSC + 0x0c */
+		u8		reserved3[3];
+	} sr_csr;
+	u8		command;		/* PSC + 0x10 */
+	u8		reserved4[3];
+	union {					/* PSC + 0x14 */
+		u8		buffer_8;
+		u16		buffer_16;
+		u32		buffer_32;
+	} buffer;
+	struct {
+		u8		ipcr;		/* PSC + 0x18 */
+		u8		reserved5[3];
+		u8		acr;		/* PSC + 0x1c */
+		u8		reserved6[3];
+	} ipcr_acr;
+	struct {
+		u16		isr;		/* PSC + 0x20 */
+		u8		reserved7[2];
+		u16		imr;		/* PSC + 0x24 */
+		u8		reserved8[2];
+	} isr_imr;
+	u8		ctur;			/* PSC + 0x28 */
+	u8		reserved9[3];
+	u8		ctlr;			/* PSC + 0x2c */
+	u8		reserved10[3];
+	u32		ccr;			/* PSC + 0x30 */
+	u32		ac97slots;		/* PSC + 0x34 */
+	u32		ac97cmd;		/* PSC + 0x38 */
+	u32		ac97data;		/* PSC + 0x3c */
+	u8		reserved11[4];
+	u8		ip;			/* PSC + 0x44 */
+	u8		reserved12[3];
+	u8		op1;			/* PSC + 0x48 */
+	u8		reserved13[3];
+	u8		op0;			/* PSC + 0x4c */
+	u8		reserved14[3];
+	u32		sicr;			/* PSC + 0x50 */
+	u8		reserved15[4];	/* make eq. sizeof(mpc52xx_psc) */
+};
+
 #endif  /* __ASM_MPC52xx_PSC_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/mpic.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mpic.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/mpic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mpic.h	2013-08-25 20:43:22.000000000 -0400
@@ -339,6 +339,8 @@ struct mpic
 #endif
 };
 
+extern struct bus_type mpic_subsys;
+
 /*
  * MPIC flags (passed to mpic_alloc)
  *
@@ -393,6 +395,9 @@ struct mpic
 #define	MPIC_REGSET_STANDARD		MPIC_REGSET(0)	/* Original MPIC */
 #define	MPIC_REGSET_TSI108		MPIC_REGSET(1)	/* Tsi108/109 PIC */
 
+/* Get the version of primary MPIC */
+extern u32 fsl_mpic_primary_get_version(void);
+
 /* Allocate the controller structure and setup the linux irq descs
  * for the range if interrupts passed in. No HW initialization is
  * actually performed.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/mpic_timer.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mpic_timer.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/mpic_timer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mpic_timer.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,46 @@
+/*
+ * arch/powerpc/include/asm/mpic_timer.h
+ *
+ * Header file for Mpic Global Timer
+ *
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * Author: Wang Dongsheng <Dongsheng.Wang@freescale.com>
+ *	   Li Yang <leoli@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MPIC_TIMER__
+#define __MPIC_TIMER__
+
+#include <linux/interrupt.h>
+#include <linux/time.h>
+
+struct mpic_timer {
+	void			*dev;
+	struct cascade_priv	*cascade_handle;
+	unsigned int		num;
+	unsigned int		irq;
+};
+
+#ifdef CONFIG_MPIC_TIMER
+struct mpic_timer *mpic_request_timer(irq_handler_t fn,  void *dev,
+		const struct timeval *time);
+void mpic_start_timer(struct mpic_timer *handle);
+void mpic_stop_timer(struct mpic_timer *handle);
+void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time);
+void mpic_free_timer(struct mpic_timer *handle);
+#else
+struct mpic_timer *mpic_request_timer(irq_handler_t fn,  void *dev,
+		const struct timeval *time) { return NULL; }
+void mpic_start_timer(struct mpic_timer *handle) { }
+void mpic_stop_timer(struct mpic_timer *handle) { }
+void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time) { }
+void mpic_free_timer(struct mpic_timer *handle) { }
+#endif
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/mutex.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mutex.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/mutex.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/mutex.h	2013-08-25 20:43:22.000000000 -0400
@@ -82,17 +82,15 @@ __mutex_fastpath_lock(atomic_t *count, v
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns.
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
 static inline int
-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+__mutex_fastpath_lock_retval(atomic_t *count)
 {
 	if (unlikely(__mutex_dec_return_lock(count) < 0))
-		return fail_fn(count);
+		return -1;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/opal.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/opal.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/opal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/opal.h	2013-08-25 20:43:22.000000000 -0400
@@ -117,7 +117,13 @@ extern int opal_enter_rtas(struct rtas_a
 #define OPAL_SET_SLOT_LED_STATUS		55
 #define OPAL_GET_EPOW_STATUS			56
 #define OPAL_SET_SYSTEM_ATTENTION_LED		57
+#define OPAL_RESERVED1				58
+#define OPAL_RESERVED2				59
+#define OPAL_PCI_NEXT_ERROR			60
+#define OPAL_PCI_EEH_FREEZE_STATUS2		61
+#define OPAL_PCI_POLL				62
 #define OPAL_PCI_MSI_EOI			63
+#define OPAL_PCI_GET_PHB_DIAG_DATA2		64
 
 #ifndef __ASSEMBLY__
 
@@ -125,6 +131,7 @@ extern int opal_enter_rtas(struct rtas_a
 enum OpalVendorApiTokens {
 	OPAL_START_VENDOR_API_RANGE = 1000, OPAL_END_VENDOR_API_RANGE = 1999
 };
+
 enum OpalFreezeState {
 	OPAL_EEH_STOPPED_NOT_FROZEN = 0,
 	OPAL_EEH_STOPPED_MMIO_FREEZE = 1,
@@ -134,55 +141,69 @@ enum OpalFreezeState {
 	OPAL_EEH_STOPPED_TEMP_UNAVAIL = 5,
 	OPAL_EEH_STOPPED_PERM_UNAVAIL = 6
 };
+
 enum OpalEehFreezeActionToken {
 	OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO = 1,
 	OPAL_EEH_ACTION_CLEAR_FREEZE_DMA = 2,
 	OPAL_EEH_ACTION_CLEAR_FREEZE_ALL = 3
 };
+
 enum OpalPciStatusToken {
-	OPAL_EEH_PHB_NO_ERROR = 0,
-	OPAL_EEH_PHB_FATAL = 1,
-	OPAL_EEH_PHB_RECOVERABLE = 2,
-	OPAL_EEH_PHB_BUS_ERROR = 3,
-	OPAL_EEH_PCI_NO_DEVSEL = 4,
-	OPAL_EEH_PCI_TA = 5,
-	OPAL_EEH_PCIEX_UR = 6,
-	OPAL_EEH_PCIEX_CA = 7,
-	OPAL_EEH_PCI_MMIO_ERROR = 8,
-	OPAL_EEH_PCI_DMA_ERROR = 9
+	OPAL_EEH_NO_ERROR	= 0,
+	OPAL_EEH_IOC_ERROR	= 1,
+	OPAL_EEH_PHB_ERROR	= 2,
+	OPAL_EEH_PE_ERROR	= 3,
+	OPAL_EEH_PE_MMIO_ERROR	= 4,
+	OPAL_EEH_PE_DMA_ERROR	= 5
 };
+
+enum OpalPciErrorSeverity {
+	OPAL_EEH_SEV_NO_ERROR	= 0,
+	OPAL_EEH_SEV_IOC_DEAD	= 1,
+	OPAL_EEH_SEV_PHB_DEAD	= 2,
+	OPAL_EEH_SEV_PHB_FENCED	= 3,
+	OPAL_EEH_SEV_PE_ER	= 4,
+	OPAL_EEH_SEV_INF	= 5
+};
+
 enum OpalShpcAction {
 	OPAL_SHPC_GET_LINK_STATE = 0,
 	OPAL_SHPC_GET_SLOT_STATE = 1
 };
+
 enum OpalShpcLinkState {
 	OPAL_SHPC_LINK_DOWN = 0,
 	OPAL_SHPC_LINK_UP = 1
 };
+
 enum OpalMmioWindowType {
 	OPAL_M32_WINDOW_TYPE = 1,
 	OPAL_M64_WINDOW_TYPE = 2,
 	OPAL_IO_WINDOW_TYPE = 3
 };
+
 enum OpalShpcSlotState {
 	OPAL_SHPC_DEV_NOT_PRESENT = 0,
 	OPAL_SHPC_DEV_PRESENT = 1
 };
+
 enum OpalExceptionHandler {
 	OPAL_MACHINE_CHECK_HANDLER = 1,
 	OPAL_HYPERVISOR_MAINTENANCE_HANDLER = 2,
 	OPAL_SOFTPATCH_HANDLER = 3
 };
+
 enum OpalPendingState {
-	OPAL_EVENT_OPAL_INTERNAL = 0x1,
-	OPAL_EVENT_NVRAM = 0x2,
-	OPAL_EVENT_RTC = 0x4,
-	OPAL_EVENT_CONSOLE_OUTPUT = 0x8,
-	OPAL_EVENT_CONSOLE_INPUT = 0x10,
-	OPAL_EVENT_ERROR_LOG_AVAIL = 0x20,
-	OPAL_EVENT_ERROR_LOG = 0x40,
-	OPAL_EVENT_EPOW = 0x80,
-	OPAL_EVENT_LED_STATUS = 0x100
+	OPAL_EVENT_OPAL_INTERNAL	= 0x1,
+	OPAL_EVENT_NVRAM		= 0x2,
+	OPAL_EVENT_RTC			= 0x4,
+	OPAL_EVENT_CONSOLE_OUTPUT	= 0x8,
+	OPAL_EVENT_CONSOLE_INPUT	= 0x10,
+	OPAL_EVENT_ERROR_LOG_AVAIL	= 0x20,
+	OPAL_EVENT_ERROR_LOG		= 0x40,
+	OPAL_EVENT_EPOW			= 0x80,
+	OPAL_EVENT_LED_STATUS		= 0x100,
+	OPAL_EVENT_PCI_ERROR		= 0x200
 };
 
 /* Machine check related definitions */
@@ -364,15 +385,80 @@ struct opal_machine_check_event {
 	} u;
 };
 
+enum {
+	OPAL_P7IOC_DIAG_TYPE_NONE	= 0,
+	OPAL_P7IOC_DIAG_TYPE_RGC	= 1,
+	OPAL_P7IOC_DIAG_TYPE_BI		= 2,
+	OPAL_P7IOC_DIAG_TYPE_CI		= 3,
+	OPAL_P7IOC_DIAG_TYPE_MISC	= 4,
+	OPAL_P7IOC_DIAG_TYPE_I2C	= 5,
+	OPAL_P7IOC_DIAG_TYPE_LAST	= 6
+};
+
+struct OpalIoP7IOCErrorData {
+	uint16_t type;
+
+	/* GEM */
+	uint64_t gemXfir;
+	uint64_t gemRfir;
+	uint64_t gemRirqfir;
+	uint64_t gemMask;
+	uint64_t gemRwof;
+
+	/* LEM */
+	uint64_t lemFir;
+	uint64_t lemErrMask;
+	uint64_t lemAction0;
+	uint64_t lemAction1;
+	uint64_t lemWof;
+
+	union {
+		struct OpalIoP7IOCRgcErrorData {
+			uint64_t rgcStatus;		/* 3E1C10 */
+			uint64_t rgcLdcp;		/* 3E1C18 */
+		}rgc;
+		struct OpalIoP7IOCBiErrorData {
+			uint64_t biLdcp0;		/* 3C0100, 3C0118 */
+			uint64_t biLdcp1;		/* 3C0108, 3C0120 */
+			uint64_t biLdcp2;		/* 3C0110, 3C0128 */
+			uint64_t biFenceStatus;		/* 3C0130, 3C0130 */
+
+			uint8_t  biDownbound;		/* BI Downbound or Upbound */
+		}bi;
+		struct OpalIoP7IOCCiErrorData {
+			uint64_t ciPortStatus;		/* 3Dn008 */
+			uint64_t ciPortLdcp;		/* 3Dn010 */
+
+			uint8_t	 ciPort;		/* Index of CI port: 0/1 */
+		}ci;
+	};
+};
+
 /**
  * This structure defines the overlay which will be used to store PHB error
  * data upon request.
  */
 enum {
+	OPAL_PHB_ERROR_DATA_VERSION_1 = 1,
+};
+
+enum {
+	OPAL_PHB_ERROR_DATA_TYPE_P7IOC = 1,
+};
+
+enum {
 	OPAL_P7IOC_NUM_PEST_REGS = 128,
 };
 
+struct OpalIoPhbErrorCommon {
+	uint32_t version;
+	uint32_t ioType;
+	uint32_t len;
+};
+
 struct OpalIoP7IOCPhbErrorData {
+	struct OpalIoPhbErrorCommon common;
+
 	uint32_t brdgCtl;
 
 	// P7IOC utl regs
@@ -530,14 +616,21 @@ int64_t opal_pci_map_pe_dma_window_real(
 					uint64_t pci_mem_size);
 int64_t opal_pci_reset(uint64_t phb_id, uint8_t reset_scope, uint8_t assert_state);
 
-int64_t opal_pci_get_hub_diag_data(uint64_t hub_id, void *diag_buffer, uint64_t diag_buffer_len);
-int64_t opal_pci_get_phb_diag_data(uint64_t phb_id, void *diag_buffer, uint64_t diag_buffer_len);
+int64_t opal_pci_get_hub_diag_data(uint64_t hub_id, void *diag_buffer,
+				   uint64_t diag_buffer_len);
+int64_t opal_pci_get_phb_diag_data(uint64_t phb_id, void *diag_buffer,
+				   uint64_t diag_buffer_len);
+int64_t opal_pci_get_phb_diag_data2(uint64_t phb_id, void *diag_buffer,
+				    uint64_t diag_buffer_len);
 int64_t opal_pci_fence_phb(uint64_t phb_id);
 int64_t opal_pci_reinit(uint64_t phb_id, uint8_t reinit_scope);
 int64_t opal_pci_mask_pe_error(uint64_t phb_id, uint16_t pe_number, uint8_t error_type, uint8_t mask_action);
 int64_t opal_set_slot_led_status(uint64_t phb_id, uint64_t slot_id, uint8_t led_type, uint8_t led_action);
 int64_t opal_get_epow_status(uint64_t *status);
 int64_t opal_set_system_attention_led(uint8_t led_action);
+int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe,
+			    uint16_t *pci_error_type, uint16_t *severity);
+int64_t opal_pci_poll(uint64_t phb_id);
 
 /* Internal functions */
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
@@ -551,6 +644,11 @@ extern void hvc_opal_init_early(void);
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
 				   int depth, void *data);
 
+extern int opal_notifier_register(struct notifier_block *nb);
+extern void opal_notifier_enable(void);
+extern void opal_notifier_disable(void);
+extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val);
+
 extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
 extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/pci-bridge.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pci-bridge.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/pci-bridge.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pci-bridge.h	2013-08-25 20:43:22.000000000 -0400
@@ -209,7 +209,6 @@ static inline struct eeh_dev *of_node_to
 extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn);
 
 /** Remove all of the PCI devices under this bus */
-extern void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe);
 extern void pcibios_remove_pci_devices(struct pci_bus *bus);
 
 /** Discover new pci devices under this bus, and add them */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/perf_event_server.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/perf_event_server.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/perf_event_server.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/perf_event_server.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 #include <asm/hw_irq.h>
 #include <linux/device.h>
+#include <uapi/asm/perf_event.h>
 
 #define MAX_HWEVENTS		8
 #define MAX_EVENT_ALTERNATIVES	8
@@ -60,6 +61,7 @@ struct power_pmu {
 #define PPMU_HAS_SSLOT		0x00000020 /* Has sampled slot in MMCRA */
 #define PPMU_HAS_SIER		0x00000040 /* Has SIER */
 #define PPMU_BHRB		0x00000080 /* has BHRB feature enabled */
+#define PPMU_EBB		0x00000100 /* supports event based branch */
 
 /*
  * Values for flags to get_alternatives()
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/pgalloc-64.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pgalloc-64.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/pgalloc-64.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pgalloc-64.h	2013-08-25 20:43:22.000000000 -0400
@@ -221,17 +221,17 @@ static inline void __pte_free_tlb(struct
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-	return kmem_cache_alloc(PGT_CACHE(PMD_INDEX_SIZE),
+	return kmem_cache_alloc(PGT_CACHE(PMD_CACHE_INDEX),
 				GFP_KERNEL|__GFP_REPEAT);
 }
 
 static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 {
-	kmem_cache_free(PGT_CACHE(PMD_INDEX_SIZE), pmd);
+	kmem_cache_free(PGT_CACHE(PMD_CACHE_INDEX), pmd);
 }
 
 #define __pmd_free_tlb(tlb, pmd, addr)		      \
-	pgtable_free_tlb(tlb, pmd, PMD_INDEX_SIZE)
+	pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX)
 #ifndef CONFIG_PPC_64K_PAGES
 #define __pud_free_tlb(tlb, pud, addr)		      \
 	pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -198,9 +198,6 @@ extern void paging_init(void);
  */
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #include <asm-generic/pgtable.h>
 
 
@@ -220,6 +217,12 @@ extern int gup_hugepd(hugepd_t *hugepd,
 
 extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
 		       unsigned long end, int write, struct page **pages, int *nr);
+#ifndef CONFIG_TRANSPARENT_HUGEPAGE
+#define pmd_large(pmd)		0
+#define has_transparent_hugepage() 0
+#endif
+pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
+				 unsigned *shift);
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/pgtable-ppc64-64k.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pgtable-ppc64-64k.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/pgtable-ppc64-64k.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pgtable-ppc64-64k.h	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,8 @@
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 /* Bits to mask out from a PMD to get to the PTE page */
-#define PMD_MASKED_BITS		0x1ff
+/* PMDs point to PTE table fragments which are 4K aligned.  */
+#define PMD_MASKED_BITS		0xfff
 /* Bits to mask out from a PGD/PUD to get to the PMD page */
 #define PUD_MASKED_BITS		0x1ff
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/pgtable-ppc64.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pgtable-ppc64.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/pgtable-ppc64.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/pgtable-ppc64.h	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,7 @@
 #else
 #include <asm/pgtable-ppc64-4k.h>
 #endif
+#include <asm/barrier.h>
 
 #define FIRST_USER_ADDRESS	0
 
@@ -20,7 +21,11 @@
                 	    PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
 #define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE)
 
-
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define PMD_CACHE_INDEX	(PMD_INDEX_SIZE + 1)
+#else
+#define PMD_CACHE_INDEX	PMD_INDEX_SIZE
+#endif
 /*
  * Define the address range of the kernel non-linear virtual area
  */
@@ -150,7 +155,7 @@
 #define	pmd_present(pmd)	(pmd_val(pmd) != 0)
 #define	pmd_clear(pmdp)		(pmd_val(*(pmdp)) = 0)
 #define pmd_page_vaddr(pmd)	(pmd_val(pmd) & ~PMD_MASKED_BITS)
-#define pmd_page(pmd)		virt_to_page(pmd_page_vaddr(pmd))
+extern struct page *pmd_page(pmd_t pmd);
 
 #define pud_set(pudp, pudval)	(pud_val(*(pudp)) = (pudval))
 #define pud_none(pud)		(!pud_val(pud))
@@ -339,43 +344,217 @@ static inline void __ptep_set_access_fla
 
 void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
 void pgtable_cache_init(void);
+#endif /* __ASSEMBLY__ */
 
 /*
- * find_linux_pte returns the address of a linux pte for a given
- * effective address and directory.  If not found, it returns zero.
+ * THP pages can't be special. So use the _PAGE_SPECIAL
  */
-static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
+#define _PAGE_SPLITTING _PAGE_SPECIAL
+
+/*
+ * We need to differentiate between explicit huge page and THP huge
+ * page, since THP huge page also need to track real subpage details
+ */
+#define _PAGE_THP_HUGE  _PAGE_4K_PFN
+
+/*
+ * set of bits not changed in pmd_modify.
+ */
+#define _HPAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS |		\
+			 _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SPLITTING | \
+			 _PAGE_THP_HUGE)
+
+#ifndef __ASSEMBLY__
+/*
+ * The linux hugepage PMD now include the pmd entries followed by the address
+ * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits.
+ * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per
+ * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and
+ * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t.
+ *
+ * The last three bits are intentionally left to zero. This memory location
+ * are also used as normal page PTE pointers. So if we have any pointers
+ * left around while we collapse a hugepage, we need to make sure
+ * _PAGE_PRESENT and _PAGE_FILE bits of that are zero when we look at them
+ */
+static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index)
 {
-	pgd_t *pg;
-	pud_t *pu;
-	pmd_t *pm;
-	pte_t *pt = NULL;
+	return (hpte_slot_array[index] >> 3) & 0x1;
+}
 
-	pg = pgdir + pgd_index(ea);
-	if (!pgd_none(*pg)) {
-		pu = pud_offset(pg, ea);
-		if (!pud_none(*pu)) {
-			pm = pmd_offset(pu, ea);
-			if (pmd_present(*pm))
-				pt = pte_offset_kernel(pm, ea);
-		}
-	}
-	return pt;
+static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array,
+					   int index)
+{
+	return hpte_slot_array[index] >> 4;
 }
 
-#ifdef CONFIG_HUGETLB_PAGE
-pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
-				 unsigned *shift);
-#else
-static inline pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
-					       unsigned *shift)
+static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
+					unsigned int index, unsigned int hidx)
 {
-	if (shift)
-		*shift = 0;
-	return find_linux_pte(pgdir, ea);
+	hpte_slot_array[index] = hidx << 4 | 0x1 << 3;
 }
-#endif /* !CONFIG_HUGETLB_PAGE */
 
-#endif /* __ASSEMBLY__ */
+static inline char *get_hpte_slot_array(pmd_t *pmdp)
+{
+	/*
+	 * The hpte hindex is stored in the pgtable whose address is in the
+	 * second half of the PMD
+	 *
+	 * Order this load with the test for pmd_trans_huge in the caller
+	 */
+	smp_rmb();
+	return *(char **)(pmdp + PTRS_PER_PMD);
+
+
+}
 
+extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
+				   pmd_t *pmdp);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot);
+extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot);
+extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot);
+extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+		       pmd_t *pmdp, pmd_t pmd);
+extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+				 pmd_t *pmd);
+
+static inline int pmd_trans_huge(pmd_t pmd)
+{
+	/*
+	 * leaf pte for huge page, bottom two bits != 00
+	 */
+	return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE);
+}
+
+static inline int pmd_large(pmd_t pmd)
+{
+	/*
+	 * leaf pte for huge page, bottom two bits != 00
+	 */
+	if (pmd_trans_huge(pmd))
+		return pmd_val(pmd) & _PAGE_PRESENT;
+	return 0;
+}
+
+static inline int pmd_trans_splitting(pmd_t pmd)
+{
+	if (pmd_trans_huge(pmd))
+		return pmd_val(pmd) & _PAGE_SPLITTING;
+	return 0;
+}
+
+extern int has_transparent_hugepage(void);
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+static inline pte_t pmd_pte(pmd_t pmd)
+{
+	return __pte(pmd_val(pmd));
+}
+
+static inline pmd_t pte_pmd(pte_t pte)
+{
+	return __pmd(pte_val(pte));
+}
+
+static inline pte_t *pmdp_ptep(pmd_t *pmd)
+{
+	return (pte_t *)pmd;
+}
+
+#define pmd_pfn(pmd)		pte_pfn(pmd_pte(pmd))
+#define pmd_young(pmd)		pte_young(pmd_pte(pmd))
+#define pmd_mkold(pmd)		pte_pmd(pte_mkold(pmd_pte(pmd)))
+#define pmd_wrprotect(pmd)	pte_pmd(pte_wrprotect(pmd_pte(pmd)))
+#define pmd_mkdirty(pmd)	pte_pmd(pte_mkdirty(pmd_pte(pmd)))
+#define pmd_mkyoung(pmd)	pte_pmd(pte_mkyoung(pmd_pte(pmd)))
+#define pmd_mkwrite(pmd)	pte_pmd(pte_mkwrite(pmd_pte(pmd)))
+
+#define __HAVE_ARCH_PMD_WRITE
+#define pmd_write(pmd)		pte_write(pmd_pte(pmd))
+
+static inline pmd_t pmd_mkhuge(pmd_t pmd)
+{
+	/* Do nothing, mk_pmd() does this part.  */
+	return pmd;
+}
+
+static inline pmd_t pmd_mknotpresent(pmd_t pmd)
+{
+	pmd_val(pmd) &= ~_PAGE_PRESENT;
+	return pmd;
+}
+
+static inline pmd_t pmd_mksplitting(pmd_t pmd)
+{
+	pmd_val(pmd) |= _PAGE_SPLITTING;
+	return pmd;
+}
+
+#define __HAVE_ARCH_PMD_SAME
+static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)
+{
+	return (((pmd_val(pmd_a) ^ pmd_val(pmd_b)) & ~_PAGE_HPTEFLAGS) == 0);
+}
+
+#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
+extern int pmdp_set_access_flags(struct vm_area_struct *vma,
+				 unsigned long address, pmd_t *pmdp,
+				 pmd_t entry, int dirty);
+
+extern unsigned long pmd_hugepage_update(struct mm_struct *mm,
+					 unsigned long addr,
+					 pmd_t *pmdp, unsigned long clr);
+
+static inline int __pmdp_test_and_clear_young(struct mm_struct *mm,
+					      unsigned long addr, pmd_t *pmdp)
+{
+	unsigned long old;
+
+	if ((pmd_val(*pmdp) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
+		return 0;
+	old = pmd_hugepage_update(mm, addr, pmdp, _PAGE_ACCESSED);
+	return ((old & _PAGE_ACCESSED) != 0);
+}
+
+#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
+extern int pmdp_test_and_clear_young(struct vm_area_struct *vma,
+				     unsigned long address, pmd_t *pmdp);
+#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
+extern int pmdp_clear_flush_young(struct vm_area_struct *vma,
+				  unsigned long address, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
+extern pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+				unsigned long addr, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMDP_CLEAR_FLUSH
+extern pmd_t pmdp_clear_flush(struct vm_area_struct *vma, unsigned long address,
+			      pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMDP_SET_WRPROTECT
+static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+				      pmd_t *pmdp)
+{
+
+	if ((pmd_val(*pmdp) & _PAGE_RW) == 0)
+		return;
+
+	pmd_hugepage_update(mm, addr, pmdp, _PAGE_RW);
+}
+
+#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
+extern void pmdp_splitting_flush(struct vm_area_struct *vma,
+				 unsigned long address, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+				       pgtable_t pgtable);
+#define __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMDP_INVALIDATE
+extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
+			    pmd_t *pmdp);
+#endif /* __ASSEMBLY__ */
 #endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/probes.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/probes.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/probes.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/probes.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,5 +38,30 @@ typedef u32 ppc_opcode_t;
 #define is_trap(instr)		(IS_TW(instr) || IS_TWI(instr))
 #endif /* CONFIG_PPC64 */
 
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+#define MSR_SINGLESTEP	(MSR_DE)
+#else
+#define MSR_SINGLESTEP	(MSR_SE)
+#endif
+
+/* Enable single stepping for the current task */
+static inline void enable_single_step(struct pt_regs *regs)
+{
+	regs->msr |= MSR_SINGLESTEP;
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+	/*
+	 * We turn off Critical Input Exception(CE) to ensure that the single
+	 * step will be for the instruction we have the probe on; if we don't,
+	 * it is possible we'd get the single step reported for CE.
+	 */
+	regs->msr &= ~MSR_CE;
+	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
+#ifdef CONFIG_PPC_47x
+	isync();
+#endif
+#endif
+}
+
+
 #endif /* __KERNEL__ */
 #endif	/* _ASM_POWERPC_PROBES_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/processor.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/processor.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/processor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/processor.h	2013-08-25 20:43:22.000000000 -0400
@@ -168,10 +168,10 @@ struct thread_struct {
 	 * The following help to manage the use of Debug Control Registers
 	 * om the BookE platforms.
 	 */
-	unsigned long	dbcr0;
-	unsigned long	dbcr1;
+	uint32_t	dbcr0;
+	uint32_t	dbcr1;
 #ifdef CONFIG_BOOKE
-	unsigned long	dbcr2;
+	uint32_t	dbcr2;
 #endif
 	/*
 	 * The stored value of the DBSR register will be the value at the
@@ -179,7 +179,7 @@ struct thread_struct {
 	 * user (will never be written to) and has value while helping to
 	 * describe the reason for the last debug trap.  Torez
 	 */
-	unsigned long	dbsr;
+	uint32_t	dbsr;
 	/*
 	 * The following will contain addresses used by debug applications
 	 * to help trace and trap on particular address locations.
@@ -200,7 +200,7 @@ struct thread_struct {
 #endif
 #endif
 	/* FP and VSX 0-31 register set */
-	double		fpr[32][TS_FPRWIDTH];
+	double		fpr[32][TS_FPRWIDTH] __attribute__((aligned(16)));
 	struct {
 
 		unsigned int pad;
@@ -247,6 +247,10 @@ struct thread_struct {
 	unsigned long	tm_orig_msr;	/* Thread's MSR on ctx switch */
 	struct pt_regs	ckpt_regs;	/* Checkpointed registers */
 
+	unsigned long	tm_tar;
+	unsigned long	tm_ppr;
+	unsigned long	tm_dscr;
+
 	/*
 	 * Transactional FP and VSX 0-31 register set.
 	 * NOTE: the sense of these is the opposite of the integer ckpt_regs!
@@ -287,9 +291,9 @@ struct thread_struct {
 	unsigned long	siar;
 	unsigned long	sdar;
 	unsigned long	sier;
-	unsigned long	mmcr0;
 	unsigned long	mmcr2;
-	unsigned long	mmcra;
+	unsigned 	mmcr0;
+	unsigned 	used_ebb;
 #endif
 };
 
@@ -404,9 +408,7 @@ static inline void prefetchw(const void
 
 #define spin_lock_prefetch(x)	prefetchw(x)
 
-#ifdef CONFIG_PPC64
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
-#endif
 
 #ifdef CONFIG_PPC64
 static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/reg.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/reg.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -254,19 +254,28 @@
 #define SPRN_HRMOR	0x139	/* Real mode offset register */
 #define SPRN_HSRR0	0x13A	/* Hypervisor Save/Restore 0 */
 #define SPRN_HSRR1	0x13B	/* Hypervisor Save/Restore 1 */
+/* HFSCR and FSCR bit numbers are the same */
+#define FSCR_TAR_LG	8	/* Enable Target Address Register */
+#define FSCR_EBB_LG	7	/* Enable Event Based Branching */
+#define FSCR_TM_LG	5	/* Enable Transactional Memory */
+#define FSCR_PM_LG	4	/* Enable prob/priv access to PMU SPRs */
+#define FSCR_BHRB_LG	3	/* Enable Branch History Rolling Buffer*/
+#define FSCR_DSCR_LG	2	/* Enable Data Stream Control Register */
+#define FSCR_VECVSX_LG	1	/* Enable VMX/VSX  */
+#define FSCR_FP_LG	0	/* Enable Floating Point */
 #define SPRN_FSCR	0x099	/* Facility Status & Control Register */
-#define   FSCR_TAR	(1 << (63-55)) /* Enable Target Address Register */
-#define   FSCR_EBB	(1 << (63-56)) /* Enable Event Based Branching */
-#define   FSCR_DSCR	(1 << (63-61)) /* Enable Data Stream Control Register */
+#define   FSCR_TAR	__MASK(FSCR_TAR_LG)
+#define   FSCR_EBB	__MASK(FSCR_EBB_LG)
+#define   FSCR_DSCR	__MASK(FSCR_DSCR_LG)
 #define SPRN_HFSCR	0xbe	/* HV=1 Facility Status & Control Register */
-#define   HFSCR_TAR	(1 << (63-55)) /* Enable Target Address Register */
-#define   HFSCR_EBB	(1 << (63-56)) /* Enable Event Based Branching */
-#define   HFSCR_TM	(1 << (63-58)) /* Enable Transactional Memory */
-#define   HFSCR_PM	(1 << (63-60)) /* Enable prob/priv access to PMU SPRs */
-#define   HFSCR_BHRB	(1 << (63-59)) /* Enable Branch History Rolling Buffer*/
-#define   HFSCR_DSCR	(1 << (63-61)) /* Enable Data Stream Control Register */
-#define   HFSCR_VECVSX	(1 << (63-62)) /* Enable VMX/VSX  */
-#define   HFSCR_FP	(1 << (63-63)) /* Enable Floating Point */
+#define   HFSCR_TAR	__MASK(FSCR_TAR_LG)
+#define   HFSCR_EBB	__MASK(FSCR_EBB_LG)
+#define   HFSCR_TM	__MASK(FSCR_TM_LG)
+#define   HFSCR_PM	__MASK(FSCR_PM_LG)
+#define   HFSCR_BHRB	__MASK(FSCR_BHRB_LG)
+#define   HFSCR_DSCR	__MASK(FSCR_DSCR_LG)
+#define   HFSCR_VECVSX	__MASK(FSCR_VECVSX_LG)
+#define   HFSCR_FP	__MASK(FSCR_FP_LG)
 #define SPRN_TAR	0x32f	/* Target Address Register */
 #define SPRN_LPCR	0x13E	/* LPAR Control Register */
 #define   LPCR_VPM0	(1ul << (63-0))
@@ -621,11 +630,15 @@
 #define   MMCR0_PMXE	0x04000000UL /* performance monitor exception enable */
 #define   MMCR0_FCECE	0x02000000UL /* freeze ctrs on enabled cond or event */
 #define   MMCR0_TBEE	0x00400000UL /* time base exception enable */
+#define   MMCR0_EBE	0x00100000UL /* Event based branch enable */
+#define   MMCR0_PMCC	0x000c0000UL /* PMC control */
+#define   MMCR0_PMCC_U6	0x00080000UL /* PMC1-6 are R/W by user (PR) */
 #define   MMCR0_PMC1CE	0x00008000UL /* PMC1 count enable*/
 #define   MMCR0_PMCjCE	0x00004000UL /* PMCj count enable*/
 #define   MMCR0_TRIGGER	0x00002000UL /* TRIGGER enable */
 #define   MMCR0_PMAO	0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
 #define   MMCR0_SHRFC	0x00000040UL /* SHRre freeze conditions between threads */
+#define   MMCR0_FC56	0x00000010UL /* freeze counters 5 and 6 */
 #define   MMCR0_FCTI	0x00000008UL /* freeze counters in tags inactive mode */
 #define   MMCR0_FCTA	0x00000004UL /* freeze counters in tags active mode */
 #define   MMCR0_FCWAIT	0x00000002UL /* freeze counter in WAIT state */
@@ -673,6 +686,11 @@
 #define   SIER_SIAR_VALID	0x0400000	/* SIAR contents valid */
 #define   SIER_SDAR_VALID	0x0200000	/* SDAR contents valid */
 
+/* When EBB is enabled, some of MMCR0/MMCR2/SIER are user accessible */
+#define MMCR0_USER_MASK	(MMCR0_FC | MMCR0_PMXE | MMCR0_PMAO)
+#define MMCR2_USER_MASK	0x4020100804020000UL /* (FC1P|FC2P|FC3P|FC4P|FC5P|FC6P) */
+#define SIER_USER_MASK	0x7fffffUL
+
 #define SPRN_PA6T_MMCR0 795
 #define   PA6T_MMCR0_EN0	0x0000000000000001UL
 #define   PA6T_MMCR0_EN1	0x0000000000000002UL
@@ -1079,7 +1097,8 @@
 #define PVR_970MP	0x0044
 #define PVR_970GX	0x0045
 #define PVR_POWER7p	0x004A
-#define PVR_POWER8	0x004B
+#define PVR_POWER8E	0x004B
+#define PVR_POWER8	0x004D
 #define PVR_BE		0x0070
 #define PVR_PA6T	0x0090
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/rtas.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/rtas.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/rtas.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/rtas.h	2013-08-25 20:43:22.000000000 -0400
@@ -350,8 +350,8 @@ static inline u32 rtas_config_addr(int b
 			(devfn << 8) | (reg & 0xff);
 }
 
-extern void __cpuinit rtas_give_timebase(void);
-extern void __cpuinit rtas_take_timebase(void);
+extern void rtas_give_timebase(void);
+extern void rtas_take_timebase(void);
 
 #ifdef CONFIG_PPC_RTAS
 static inline int page_is_rtas_user_buf(unsigned long pfn)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/smp.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/smp.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/smp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/smp.h	2013-08-25 20:43:22.000000000 -0400
@@ -145,6 +145,10 @@ extern void __cpu_die(unsigned int cpu);
 #define smp_setup_cpu_maps()
 static inline void inhibit_secondary_onlining(void) {}
 static inline void uninhibit_secondary_onlining(void) {}
+static inline const struct cpumask *cpu_sibling_mask(int cpu)
+{
+	return cpumask_of(cpu);
+}
 
 #endif /* CONFIG_SMP */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/switch_to.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/switch_to.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/switch_to.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/switch_to.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,15 @@ extern struct task_struct *__switch_to(s
 struct thread_struct;
 extern struct task_struct *_switch(struct thread_struct *prev,
 				   struct thread_struct *next);
+#ifdef CONFIG_PPC_BOOK3S_64
+static inline void save_tar(struct thread_struct *prev)
+{
+	if (cpu_has_feature(CPU_FTR_ARCH_207S))
+		prev->tar = mfspr(SPRN_TAR);
+}
+#else
+static inline void save_tar(struct thread_struct *prev) {}
+#endif
 
 extern void giveup_fpu(struct task_struct *);
 extern void load_up_fpu(void);
@@ -67,4 +76,18 @@ static inline void flush_spe_to_thread(s
 }
 #endif
 
+static inline void clear_task_ebb(struct task_struct *t)
+{
+#ifdef CONFIG_PPC_BOOK3S_64
+    /* EBB perf events are not inherited, so clear all EBB state. */
+    t->thread.bescr = 0;
+    t->thread.mmcr2 = 0;
+    t->thread.mmcr0 = 0;
+    t->thread.siar = 0;
+    t->thread.sdar = 0;
+    t->thread.sier = 0;
+    t->thread.used_ebb = 0;
+#endif
+}
+
 #endif /* _ASM_POWERPC_SWITCH_TO_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/tlbflush.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/tlbflush.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/tlbflush.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/tlbflush.h	2013-08-25 20:43:22.000000000 -0400
@@ -165,7 +165,8 @@ static inline void flush_tlb_kernel_rang
 /* Private function for use by PCI IO mapping code */
 extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
 				     unsigned long end);
-
+extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
+				unsigned long addr);
 #else
 #error Unsupported MMU type
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/uaccess.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/uaccess.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/uaccess.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/uaccess.h	2013-08-25 20:43:22.000000000 -0400
@@ -178,7 +178,7 @@ do {								\
 	long __pu_err;						\
 	__typeof__(*(ptr)) __user *__pu_addr = (ptr);		\
 	if (!is_kernel_addr((unsigned long)__pu_addr))		\
-		might_sleep();					\
+		might_fault();					\
 	__chk_user_ptr(ptr);					\
 	__put_user_size((x), __pu_addr, (size), __pu_err);	\
 	__pu_err;						\
@@ -188,7 +188,7 @@ do {								\
 ({									\
 	long __pu_err = -EFAULT;					\
 	__typeof__(*(ptr)) __user *__pu_addr = (ptr);			\
-	might_sleep();							\
+	might_fault();							\
 	if (access_ok(VERIFY_WRITE, __pu_addr, size))			\
 		__put_user_size((x), __pu_addr, (size), __pu_err);	\
 	__pu_err;							\
@@ -268,7 +268,7 @@ do {								\
 	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);	\
 	__chk_user_ptr(ptr);					\
 	if (!is_kernel_addr((unsigned long)__gu_addr))		\
-		might_sleep();					\
+		might_fault();					\
 	__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
 	(x) = (__typeof__(*(ptr)))__gu_val;			\
 	__gu_err;						\
@@ -282,7 +282,7 @@ do {								\
 	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);	\
 	__chk_user_ptr(ptr);					\
 	if (!is_kernel_addr((unsigned long)__gu_addr))		\
-		might_sleep();					\
+		might_fault();					\
 	__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
 	(x) = (__typeof__(*(ptr)))__gu_val;			\
 	__gu_err;						\
@@ -294,7 +294,7 @@ do {								\
 	long __gu_err = -EFAULT;					\
 	unsigned long  __gu_val = 0;					\
 	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);		\
-	might_sleep();							\
+	might_fault();							\
 	if (access_ok(VERIFY_READ, __gu_addr, (size)))			\
 		__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
 	(x) = (__typeof__(*(ptr)))__gu_val;				\
@@ -419,14 +419,14 @@ static inline unsigned long __copy_to_us
 static inline unsigned long __copy_from_user(void *to,
 		const void __user *from, unsigned long size)
 {
-	might_sleep();
+	might_fault();
 	return __copy_from_user_inatomic(to, from, size);
 }
 
 static inline unsigned long __copy_to_user(void __user *to,
 		const void *from, unsigned long size)
 {
-	might_sleep();
+	might_fault();
 	return __copy_to_user_inatomic(to, from, size);
 }
 
@@ -434,7 +434,7 @@ extern unsigned long __clear_user(void _
 
 static inline unsigned long clear_user(void __user *addr, unsigned long size)
 {
-	might_sleep();
+	might_fault();
 	if (likely(access_ok(VERIFY_WRITE, addr, size)))
 		return __clear_user(addr, size);
 	if ((unsigned long)addr < TASK_SIZE) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/asm/vdso.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/vdso.h
--- linux-libre-3.10-gnu/arch/powerpc/include/asm/vdso.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/asm/vdso.h	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,7 @@ extern unsigned long vdso64_rt_sigtramp;
 extern unsigned long vdso32_sigtramp;
 extern unsigned long vdso32_rt_sigtramp;
 
-int __cpuinit vdso_getcpu_init(void);
+int vdso_getcpu_init(void);
 
 #else /* __ASSEMBLY__ */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/uapi/asm/Kbuild linux-libre-3.11-rc7-gnu/arch/powerpc/include/uapi/asm/Kbuild
--- linux-libre-3.10-gnu/arch/powerpc/include/uapi/asm/Kbuild	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/uapi/asm/Kbuild	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@ header-y += mman.h
 header-y += msgbuf.h
 header-y += nvram.h
 header-y += param.h
+header-y += perf_event.h
 header-y += poll.h
 header-y += posix_types.h
 header-y += ps3fb.h
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/uapi/asm/perf_event.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/uapi/asm/perf_event.h
--- linux-libre-3.10-gnu/arch/powerpc/include/uapi/asm/perf_event.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/uapi/asm/perf_event.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2013 Michael Ellerman, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ */
+
+#ifndef _UAPI_ASM_POWERPC_PERF_EVENT_H
+#define _UAPI_ASM_POWERPC_PERF_EVENT_H
+
+/*
+ * We use bit 63 of perf_event_attr.config as a flag to request EBB.
+ */
+#define PERF_EVENT_CONFIG_EBB_SHIFT	63
+
+#endif /* _UAPI_ASM_POWERPC_PERF_EVENT_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/powerpc/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/powerpc/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -81,4 +81,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif	/* _ASM_POWERPC_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/Kconfig linux-libre-3.11-rc7-gnu/arch/powerpc/Kconfig
--- linux-libre-3.10-gnu/arch/powerpc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -138,6 +138,7 @@ config PPC
 	select ARCH_USE_BUILTIN_BSWAP
 	select OLD_SIGSUSPEND
 	select OLD_SIGACTION if PPC32
+	select HAVE_DEBUG_STACKOVERFLOW
 
 config EARLY_PRINTK
 	bool
@@ -298,7 +299,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE
 
 config MATH_EMULATION
 	bool "Math emulation"
-	depends on 4xx || 8xx || E200 || PPC_MPC832x || E500
+	depends on 4xx || 8xx || PPC_MPC832x || BOOKE
 	---help---
 	  Some PowerPC chips designed for embedded applications do not have
 	  a floating-point unit and therefore do not implement the
@@ -307,6 +308,10 @@ config MATH_EMULATION
 	  unit, which will allow programs that use floating-point
 	  instructions to run.
 
+	  This is also useful to emulate missing (optional) instructions
+	  such as fsqrt on cores that do have an FPU but do not implement
+	  them (such as Freescale BookE).
+
 config PPC_TRANSACTIONAL_MEM
        bool "Transactional Memory support for POWERPC"
        depends on PPC_BOOK3S_64
@@ -315,17 +320,6 @@ config PPC_TRANSACTIONAL_MEM
        ---help---
          Support user-mode Transactional Memory on POWERPC.
 
-config 8XX_MINIMAL_FPEMU
-	bool "Minimal math emulation for 8xx"
-	depends on 8xx && !MATH_EMULATION
-	help
-	  Older arch/ppc kernels still emulated a few floating point
-	  instructions such as load and store, even when full math
-	  emulation is disabled.  Say "Y" here if you want to preserve
-	  this behavior.
-
-	  It is recommended that you build a soft-float userspace instead.
-
 config IOMMU_HELPER
 	def_bool PPC64
 
@@ -341,7 +335,7 @@ config SWIOTLB
 
 config HOTPLUG_CPU
 	bool "Support for enabling/disabling CPUs"
-	depends on SMP && HOTPLUG && (PPC_PSERIES || \
+	depends on SMP && (PPC_PSERIES || \
 	PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC))
 	---help---
 	  Say Y here to be able to disable and re-enable individual
@@ -572,7 +566,7 @@ config SCHED_SMT
 config PPC_DENORMALISATION
 	bool "PowerPC denormalisation exception handling"
 	depends on PPC_BOOK3S_64
-	default "n"
+	default "y" if PPC_POWERNV
 	---help---
 	  Add support for handling denormalisation of single precision
 	  values.  Useful for bare metal only.  If unsure say Y here.
@@ -674,7 +668,6 @@ config SBUS
 
 config FSL_SOC
 	bool
-	select HAVE_CAN_FLEXCAN if NET && CAN
 
 config FSL_PCI
  	bool
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/powerpc/Kconfig.debug
--- linux-libre-3.10-gnu/arch/powerpc/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -28,13 +28,6 @@ config PRINT_STACK_DEPTH
 	  too small and stack traces cause important information to
 	  scroll off the screen.
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-	help
-	  This option will cause messages to be printed if free stack space
-	  drops below a certain limit.
-
 config HCALL_STATS
 	bool "Hypervisor call instrumentation"
 	depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS
@@ -147,6 +140,13 @@ choice
 	  enable debugging for the wrong type of machine your kernel
 	  _will not boot_.
 
+config PPC_EARLY_DEBUG_BOOTX
+	bool "BootX or OpenFirmware"
+	depends on BOOTX_TEXT
+	help
+	  Select this to enable early debugging for a machine using BootX
+	  or OpenFirmware.
+
 config PPC_EARLY_DEBUG_LPAR
 	bool "LPAR HV Console"
 	depends on PPC_PSERIES
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/asm-offsets.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/asm-offsets.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/asm-offsets.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/asm-offsets.c	2013-08-25 20:43:22.000000000 -0400
@@ -105,9 +105,6 @@ int main(void)
 	DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid));
 #else /* CONFIG_PPC64 */
 	DEFINE(PGDIR, offsetof(struct thread_struct, pgdir));
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-	DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
-#endif
 #ifdef CONFIG_SPE
 	DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0]));
 	DEFINE(THREAD_ACC, offsetof(struct thread_struct, acc));
@@ -115,6 +112,9 @@ int main(void)
 	DEFINE(THREAD_USED_SPE, offsetof(struct thread_struct, used_spe));
 #endif /* CONFIG_SPE */
 #endif /* CONFIG_PPC64 */
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+	DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
+#endif
 #ifdef CONFIG_KVM_BOOK3S_32_HANDLER
 	DEFINE(THREAD_KVM_SVCPU, offsetof(struct thread_struct, kvm_shadow_vcpu));
 #endif
@@ -132,13 +132,15 @@ int main(void)
 	DEFINE(THREAD_SIER, offsetof(struct thread_struct, sier));
 	DEFINE(THREAD_MMCR0, offsetof(struct thread_struct, mmcr0));
 	DEFINE(THREAD_MMCR2, offsetof(struct thread_struct, mmcr2));
-	DEFINE(THREAD_MMCRA, offsetof(struct thread_struct, mmcra));
 #endif
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 	DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch));
 	DEFINE(THREAD_TM_TFHAR, offsetof(struct thread_struct, tm_tfhar));
 	DEFINE(THREAD_TM_TEXASR, offsetof(struct thread_struct, tm_texasr));
 	DEFINE(THREAD_TM_TFIAR, offsetof(struct thread_struct, tm_tfiar));
+	DEFINE(THREAD_TM_TAR, offsetof(struct thread_struct, tm_tar));
+	DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr));
+	DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr));
 	DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs));
 	DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct,
 					 transact_vr[0]));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/cacheinfo.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/cacheinfo.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/cacheinfo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/cacheinfo.c	2013-08-25 20:43:22.000000000 -0400
@@ -131,7 +131,8 @@ static const char *cache_type_string(con
 	return cache_type_info[cache->type].name;
 }
 
-static void __cpuinit cache_init(struct cache *cache, int type, int level, struct device_node *ofnode)
+static void cache_init(struct cache *cache, int type, int level,
+		       struct device_node *ofnode)
 {
 	cache->type = type;
 	cache->level = level;
@@ -140,7 +141,7 @@ static void __cpuinit cache_init(struct
 	list_add(&cache->list, &cache_list);
 }
 
-static struct cache *__cpuinit new_cache(int type, int level, struct device_node *ofnode)
+static struct cache *new_cache(int type, int level, struct device_node *ofnode)
 {
 	struct cache *cache;
 
@@ -324,7 +325,8 @@ static bool cache_node_is_unified(const
 	return of_get_property(np, "cache-unified", NULL);
 }
 
-static struct cache *__cpuinit cache_do_one_devnode_unified(struct device_node *node, int level)
+static struct cache *cache_do_one_devnode_unified(struct device_node *node,
+						  int level)
 {
 	struct cache *cache;
 
@@ -335,7 +337,8 @@ static struct cache *__cpuinit cache_do_
 	return cache;
 }
 
-static struct cache *__cpuinit cache_do_one_devnode_split(struct device_node *node, int level)
+static struct cache *cache_do_one_devnode_split(struct device_node *node,
+						int level)
 {
 	struct cache *dcache, *icache;
 
@@ -357,7 +360,7 @@ err:
 	return NULL;
 }
 
-static struct cache *__cpuinit cache_do_one_devnode(struct device_node *node, int level)
+static struct cache *cache_do_one_devnode(struct device_node *node, int level)
 {
 	struct cache *cache;
 
@@ -369,7 +372,8 @@ static struct cache *__cpuinit cache_do_
 	return cache;
 }
 
-static struct cache *__cpuinit cache_lookup_or_instantiate(struct device_node *node, int level)
+static struct cache *cache_lookup_or_instantiate(struct device_node *node,
+						 int level)
 {
 	struct cache *cache;
 
@@ -385,7 +389,7 @@ static struct cache *__cpuinit cache_loo
 	return cache;
 }
 
-static void __cpuinit link_cache_lists(struct cache *smaller, struct cache *bigger)
+static void link_cache_lists(struct cache *smaller, struct cache *bigger)
 {
 	while (smaller->next_local) {
 		if (smaller->next_local == bigger)
@@ -396,13 +400,13 @@ static void __cpuinit link_cache_lists(s
 	smaller->next_local = bigger;
 }
 
-static void __cpuinit do_subsidiary_caches_debugcheck(struct cache *cache)
+static void do_subsidiary_caches_debugcheck(struct cache *cache)
 {
 	WARN_ON_ONCE(cache->level != 1);
 	WARN_ON_ONCE(strcmp(cache->ofnode->type, "cpu"));
 }
 
-static void __cpuinit do_subsidiary_caches(struct cache *cache)
+static void do_subsidiary_caches(struct cache *cache)
 {
 	struct device_node *subcache_node;
 	int level = cache->level;
@@ -423,7 +427,7 @@ static void __cpuinit do_subsidiary_cach
 	}
 }
 
-static struct cache *__cpuinit cache_chain_instantiate(unsigned int cpu_id)
+static struct cache *cache_chain_instantiate(unsigned int cpu_id)
 {
 	struct device_node *cpu_node;
 	struct cache *cpu_cache = NULL;
@@ -448,7 +452,7 @@ out:
 	return cpu_cache;
 }
 
-static struct cache_dir *__cpuinit cacheinfo_create_cache_dir(unsigned int cpu_id)
+static struct cache_dir *cacheinfo_create_cache_dir(unsigned int cpu_id)
 {
 	struct cache_dir *cache_dir;
 	struct device *dev;
@@ -653,7 +657,7 @@ static struct kobj_type cache_index_type
 	.default_attrs = cache_index_default_attrs,
 };
 
-static void __cpuinit cacheinfo_create_index_opt_attrs(struct cache_index_dir *dir)
+static void cacheinfo_create_index_opt_attrs(struct cache_index_dir *dir)
 {
 	const char *cache_name;
 	const char *cache_type;
@@ -696,7 +700,8 @@ static void __cpuinit cacheinfo_create_i
 	kfree(buf);
 }
 
-static void __cpuinit cacheinfo_create_index_dir(struct cache *cache, int index, struct cache_dir *cache_dir)
+static void cacheinfo_create_index_dir(struct cache *cache, int index,
+				       struct cache_dir *cache_dir)
 {
 	struct cache_index_dir *index_dir;
 	int rc;
@@ -722,7 +727,8 @@ err:
 	kfree(index_dir);
 }
 
-static void __cpuinit cacheinfo_sysfs_populate(unsigned int cpu_id, struct cache *cache_list)
+static void cacheinfo_sysfs_populate(unsigned int cpu_id,
+				     struct cache *cache_list)
 {
 	struct cache_dir *cache_dir;
 	struct cache *cache;
@@ -740,7 +746,7 @@ static void __cpuinit cacheinfo_sysfs_po
 	}
 }
 
-void __cpuinit cacheinfo_cpu_online(unsigned int cpu_id)
+void cacheinfo_cpu_online(unsigned int cpu_id)
 {
 	struct cache *cache;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/cputable.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/cputable.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/cputable.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/cputable.c	2013-08-25 20:43:22.000000000 -0400
@@ -494,9 +494,27 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_restore		= __restore_cpu_power7,
 		.platform		= "power7+",
 	},
-	{	/* Power8 */
+	{	/* Power8E */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x004b0000,
+		.cpu_name		= "POWER8E (raw)",
+		.cpu_features		= CPU_FTRS_POWER8,
+		.cpu_user_features	= COMMON_USER_POWER8,
+		.cpu_user_features2	= COMMON_USER2_POWER8,
+		.mmu_features		= MMU_FTRS_POWER8,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.num_pmcs		= 6,
+		.pmc_type		= PPC_PMC_IBM,
+		.oprofile_cpu_type	= "ppc64/power8",
+		.oprofile_type		= PPC_OPROFILE_INVALID,
+		.cpu_setup		= __setup_cpu_power8,
+		.cpu_restore		= __restore_cpu_power8,
+		.platform		= "power8",
+	},
+	{	/* Power8 */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x004d0000,
 		.cpu_name		= "POWER8 (raw)",
 		.cpu_features		= CPU_FTRS_POWER8,
 		.cpu_user_features	= COMMON_USER_POWER8,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/crash_dump.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/crash_dump.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/crash_dump.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/crash_dump.c	2013-08-25 20:43:22.000000000 -0400
@@ -69,16 +69,6 @@ void __init setup_kdump_trampoline(void)
 }
 #endif /* CONFIG_NONSTATIC_KERNEL */
 
-static int __init parse_savemaxmem(char *p)
-{
-	if (p)
-		saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
-
-	return 1;
-}
-__setup("savemaxmem=", parse_savemaxmem);
-
-
 static size_t copy_oldmem_vaddr(void *vaddr, char *buf, size_t csize,
                                unsigned long offset, int userbuf)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/eeh.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/eeh.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1068 @@
+/*
+ * Copyright IBM Corporation 2001, 2005, 2006
+ * Copyright Dave Engebretsen & Todd Inglett 2001
+ * Copyright Linas Vepstas 2005, 2006
+ * Copyright 2001-2012 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/rbtree.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/export.h>
+#include <linux/of.h>
+
+#include <linux/atomic.h>
+#include <asm/eeh.h>
+#include <asm/eeh_event.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+#include <asm/rtas.h>
+
+
+/** Overview:
+ *  EEH, or "Extended Error Handling" is a PCI bridge technology for
+ *  dealing with PCI bus errors that can't be dealt with within the
+ *  usual PCI framework, except by check-stopping the CPU.  Systems
+ *  that are designed for high-availability/reliability cannot afford
+ *  to crash due to a "mere" PCI error, thus the need for EEH.
+ *  An EEH-capable bridge operates by converting a detected error
+ *  into a "slot freeze", taking the PCI adapter off-line, making
+ *  the slot behave, from the OS'es point of view, as if the slot
+ *  were "empty": all reads return 0xff's and all writes are silently
+ *  ignored.  EEH slot isolation events can be triggered by parity
+ *  errors on the address or data busses (e.g. during posted writes),
+ *  which in turn might be caused by low voltage on the bus, dust,
+ *  vibration, humidity, radioactivity or plain-old failed hardware.
+ *
+ *  Note, however, that one of the leading causes of EEH slot
+ *  freeze events are buggy device drivers, buggy device microcode,
+ *  or buggy device hardware.  This is because any attempt by the
+ *  device to bus-master data to a memory address that is not
+ *  assigned to the device will trigger a slot freeze.   (The idea
+ *  is to prevent devices-gone-wild from corrupting system memory).
+ *  Buggy hardware/drivers will have a miserable time co-existing
+ *  with EEH.
+ *
+ *  Ideally, a PCI device driver, when suspecting that an isolation
+ *  event has occurred (e.g. by reading 0xff's), will then ask EEH
+ *  whether this is the case, and then take appropriate steps to
+ *  reset the PCI slot, the PCI device, and then resume operations.
+ *  However, until that day,  the checking is done here, with the
+ *  eeh_check_failure() routine embedded in the MMIO macros.  If
+ *  the slot is found to be isolated, an "EEH Event" is synthesized
+ *  and sent out for processing.
+ */
+
+/* If a device driver keeps reading an MMIO register in an interrupt
+ * handler after a slot isolation event, it might be broken.
+ * This sets the threshold for how many read attempts we allow
+ * before printing an error message.
+ */
+#define EEH_MAX_FAILS	2100000
+
+/* Time to wait for a PCI slot to report status, in milliseconds */
+#define PCI_BUS_RESET_WAIT_MSEC (60*1000)
+
+/* Platform dependent EEH operations */
+struct eeh_ops *eeh_ops = NULL;
+
+int eeh_subsystem_enabled;
+EXPORT_SYMBOL(eeh_subsystem_enabled);
+
+/*
+ * EEH probe mode support. The intention is to support multiple
+ * platforms for EEH. Some platforms like pSeries do PCI emunation
+ * based on device tree. However, other platforms like powernv probe
+ * PCI devices from hardware. The flag is used to distinguish that.
+ * In addition, struct eeh_ops::probe would be invoked for particular
+ * OF node or PCI device so that the corresponding PE would be created
+ * there.
+ */
+int eeh_probe_mode;
+
+/* Lock to avoid races due to multiple reports of an error */
+DEFINE_RAW_SPINLOCK(confirm_error_lock);
+
+/* Buffer for reporting pci register dumps. Its here in BSS, and
+ * not dynamically alloced, so that it ends up in RMO where RTAS
+ * can access it.
+ */
+#define EEH_PCI_REGS_LOG_LEN 4096
+static unsigned char pci_regs_buf[EEH_PCI_REGS_LOG_LEN];
+
+/*
+ * The struct is used to maintain the EEH global statistic
+ * information. Besides, the EEH global statistics will be
+ * exported to user space through procfs
+ */
+struct eeh_stats {
+	u64 no_device;		/* PCI device not found		*/
+	u64 no_dn;		/* OF node not found		*/
+	u64 no_cfg_addr;	/* Config address not found	*/
+	u64 ignored_check;	/* EEH check skipped		*/
+	u64 total_mmio_ffs;	/* Total EEH checks		*/
+	u64 false_positives;	/* Unnecessary EEH checks	*/
+	u64 slot_resets;	/* PE reset			*/
+};
+
+static struct eeh_stats eeh_stats;
+
+#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
+
+/**
+ * eeh_gather_pci_data - Copy assorted PCI config space registers to buff
+ * @edev: device to report data for
+ * @buf: point to buffer in which to log
+ * @len: amount of room in buffer
+ *
+ * This routine captures assorted PCI configuration space data,
+ * and puts them into a buffer for RTAS error logging.
+ */
+static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
+{
+	struct device_node *dn = eeh_dev_to_of_node(edev);
+	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+	u32 cfg;
+	int cap, i;
+	int n = 0;
+
+	n += scnprintf(buf+n, len-n, "%s\n", dn->full_name);
+	printk(KERN_WARNING "EEH: of node=%s\n", dn->full_name);
+
+	eeh_ops->read_config(dn, PCI_VENDOR_ID, 4, &cfg);
+	n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg);
+	printk(KERN_WARNING "EEH: PCI device/vendor: %08x\n", cfg);
+
+	eeh_ops->read_config(dn, PCI_COMMAND, 4, &cfg);
+	n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
+	printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg);
+
+	if (!dev) {
+		printk(KERN_WARNING "EEH: no PCI device for this of node\n");
+		return n;
+	}
+
+	/* Gather bridge-specific registers */
+	if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
+		eeh_ops->read_config(dn, PCI_SEC_STATUS, 2, &cfg);
+		n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg);
+		printk(KERN_WARNING "EEH: Bridge secondary status: %04x\n", cfg);
+
+		eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &cfg);
+		n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg);
+		printk(KERN_WARNING "EEH: Bridge control: %04x\n", cfg);
+	}
+
+	/* Dump out the PCI-X command and status regs */
+	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+	if (cap) {
+		eeh_ops->read_config(dn, cap, 4, &cfg);
+		n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg);
+		printk(KERN_WARNING "EEH: PCI-X cmd: %08x\n", cfg);
+
+		eeh_ops->read_config(dn, cap+4, 4, &cfg);
+		n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg);
+		printk(KERN_WARNING "EEH: PCI-X status: %08x\n", cfg);
+	}
+
+	/* If PCI-E capable, dump PCI-E cap 10, and the AER */
+	cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (cap) {
+		n += scnprintf(buf+n, len-n, "pci-e cap10:\n");
+		printk(KERN_WARNING
+		       "EEH: PCI-E capabilities and status follow:\n");
+
+		for (i=0; i<=8; i++) {
+			eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
+			n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
+			printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg);
+		}
+
+		cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+		if (cap) {
+			n += scnprintf(buf+n, len-n, "pci-e AER:\n");
+			printk(KERN_WARNING
+			       "EEH: PCI-E AER capability register set follows:\n");
+
+			for (i=0; i<14; i++) {
+				eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
+				n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
+				printk(KERN_WARNING "EEH: PCI-E AER %02x: %08x\n", i, cfg);
+			}
+		}
+	}
+
+	return n;
+}
+
+/**
+ * eeh_slot_error_detail - Generate combined log including driver log and error log
+ * @pe: EEH PE
+ * @severity: temporary or permanent error log
+ *
+ * This routine should be called to generate the combined log, which
+ * is comprised of driver log and error log. The driver log is figured
+ * out from the config space of the corresponding PCI device, while
+ * the error log is fetched through platform dependent function call.
+ */
+void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
+{
+	size_t loglen = 0;
+	struct eeh_dev *edev, *tmp;
+	bool valid_cfg_log = true;
+
+	/*
+	 * When the PHB is fenced or dead, it's pointless to collect
+	 * the data from PCI config space because it should return
+	 * 0xFF's. For ER, we still retrieve the data from the PCI
+	 * config space.
+	 */
+	if (eeh_probe_mode_dev() &&
+	    (pe->type & EEH_PE_PHB) &&
+	    (pe->state & (EEH_PE_ISOLATED | EEH_PE_PHB_DEAD)))
+		valid_cfg_log = false;
+
+	if (valid_cfg_log) {
+		eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
+		eeh_ops->configure_bridge(pe);
+		eeh_pe_restore_bars(pe);
+
+		pci_regs_buf[0] = 0;
+		eeh_pe_for_each_dev(pe, edev, tmp) {
+			loglen += eeh_gather_pci_data(edev, pci_regs_buf + loglen,
+						      EEH_PCI_REGS_LOG_LEN - loglen);
+		}
+	}
+
+	eeh_ops->get_log(pe, severity, pci_regs_buf, loglen);
+}
+
+/**
+ * eeh_token_to_phys - Convert EEH address token to phys address
+ * @token: I/O token, should be address in the form 0xA....
+ *
+ * This routine should be called to convert virtual I/O address
+ * to physical one.
+ */
+static inline unsigned long eeh_token_to_phys(unsigned long token)
+{
+	pte_t *ptep;
+	unsigned long pa;
+	int hugepage_shift;
+
+	/*
+	 * We won't find hugepages here, iomem
+	 */
+	ptep = find_linux_pte_or_hugepte(init_mm.pgd, token, &hugepage_shift);
+	if (!ptep)
+		return token;
+	WARN_ON(hugepage_shift);
+	pa = pte_pfn(*ptep) << PAGE_SHIFT;
+
+	return pa | (token & (PAGE_SIZE-1));
+}
+
+/*
+ * On PowerNV platform, we might already have fenced PHB there.
+ * For that case, it's meaningless to recover frozen PE. Intead,
+ * We have to handle fenced PHB firstly.
+ */
+static int eeh_phb_check_failure(struct eeh_pe *pe)
+{
+	struct eeh_pe *phb_pe;
+	unsigned long flags;
+	int ret;
+
+	if (!eeh_probe_mode_dev())
+		return -EPERM;
+
+	/* Find the PHB PE */
+	phb_pe = eeh_phb_pe_get(pe->phb);
+	if (!phb_pe) {
+		pr_warning("%s Can't find PE for PHB#%d\n",
+			   __func__, pe->phb->global_number);
+		return -EEXIST;
+	}
+
+	/* If the PHB has been in problematic state */
+	eeh_serialize_lock(&flags);
+	if (phb_pe->state & (EEH_PE_ISOLATED | EEH_PE_PHB_DEAD)) {
+		ret = 0;
+		goto out;
+	}
+
+	/* Check PHB state */
+	ret = eeh_ops->get_state(phb_pe, NULL);
+	if ((ret < 0) ||
+	    (ret == EEH_STATE_NOT_SUPPORT) ||
+	    (ret & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) ==
+	    (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) {
+		ret = 0;
+		goto out;
+	}
+
+	/* Isolate the PHB and send event */
+	eeh_pe_state_mark(phb_pe, EEH_PE_ISOLATED);
+	eeh_serialize_unlock(flags);
+	eeh_send_failure_event(phb_pe);
+
+	pr_err("EEH: PHB#%x failure detected\n",
+		phb_pe->phb->global_number);
+	dump_stack();
+
+	return 1;
+out:
+	eeh_serialize_unlock(flags);
+	return ret;
+}
+
+/**
+ * eeh_dev_check_failure - Check if all 1's data is due to EEH slot freeze
+ * @edev: eeh device
+ *
+ * Check for an EEH failure for the given device node.  Call this
+ * routine if the result of a read was all 0xff's and you want to
+ * find out if this is due to an EEH slot freeze.  This routine
+ * will query firmware for the EEH status.
+ *
+ * Returns 0 if there has not been an EEH error; otherwise returns
+ * a non-zero value and queues up a slot isolation event notification.
+ *
+ * It is safe to call this routine in an interrupt context.
+ */
+int eeh_dev_check_failure(struct eeh_dev *edev)
+{
+	int ret;
+	unsigned long flags;
+	struct device_node *dn;
+	struct pci_dev *dev;
+	struct eeh_pe *pe;
+	int rc = 0;
+	const char *location;
+
+	eeh_stats.total_mmio_ffs++;
+
+	if (!eeh_subsystem_enabled)
+		return 0;
+
+	if (!edev) {
+		eeh_stats.no_dn++;
+		return 0;
+	}
+	dn = eeh_dev_to_of_node(edev);
+	dev = eeh_dev_to_pci_dev(edev);
+	pe = edev->pe;
+
+	/* Access to IO BARs might get this far and still not want checking. */
+	if (!pe) {
+		eeh_stats.ignored_check++;
+		pr_debug("EEH: Ignored check for %s %s\n",
+			eeh_pci_name(dev), dn->full_name);
+		return 0;
+	}
+
+	if (!pe->addr && !pe->config_addr) {
+		eeh_stats.no_cfg_addr++;
+		return 0;
+	}
+
+	/*
+	 * On PowerNV platform, we might already have fenced PHB
+	 * there and we need take care of that firstly.
+	 */
+	ret = eeh_phb_check_failure(pe);
+	if (ret > 0)
+		return ret;
+
+	/* If we already have a pending isolation event for this
+	 * slot, we know it's bad already, we don't need to check.
+	 * Do this checking under a lock; as multiple PCI devices
+	 * in one slot might report errors simultaneously, and we
+	 * only want one error recovery routine running.
+	 */
+	eeh_serialize_lock(&flags);
+	rc = 1;
+	if (pe->state & EEH_PE_ISOLATED) {
+		pe->check_count++;
+		if (pe->check_count % EEH_MAX_FAILS == 0) {
+			location = of_get_property(dn, "ibm,loc-code", NULL);
+			printk(KERN_ERR "EEH: %d reads ignored for recovering device at "
+				"location=%s driver=%s pci addr=%s\n",
+				pe->check_count, location,
+				eeh_driver_name(dev), eeh_pci_name(dev));
+			printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n",
+				eeh_driver_name(dev));
+			dump_stack();
+		}
+		goto dn_unlock;
+	}
+
+	/*
+	 * Now test for an EEH failure.  This is VERY expensive.
+	 * Note that the eeh_config_addr may be a parent device
+	 * in the case of a device behind a bridge, or it may be
+	 * function zero of a multi-function device.
+	 * In any case they must share a common PHB.
+	 */
+	ret = eeh_ops->get_state(pe, NULL);
+
+	/* Note that config-io to empty slots may fail;
+	 * they are empty when they don't have children.
+	 * We will punt with the following conditions: Failure to get
+	 * PE's state, EEH not support and Permanently unavailable
+	 * state, PE is in good state.
+	 */
+	if ((ret < 0) ||
+	    (ret == EEH_STATE_NOT_SUPPORT) ||
+	    (ret & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) ==
+	    (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) {
+		eeh_stats.false_positives++;
+		pe->false_positives++;
+		rc = 0;
+		goto dn_unlock;
+	}
+
+	eeh_stats.slot_resets++;
+
+	/* Avoid repeated reports of this failure, including problems
+	 * with other functions on this device, and functions under
+	 * bridges.
+	 */
+	eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
+	eeh_serialize_unlock(flags);
+
+	eeh_send_failure_event(pe);
+
+	/* Most EEH events are due to device driver bugs.  Having
+	 * a stack trace will help the device-driver authors figure
+	 * out what happened.  So print that out.
+	 */
+	pr_err("EEH: Frozen PE#%x detected on PHB#%x\n",
+		pe->addr, pe->phb->global_number);
+	dump_stack();
+
+	return 1;
+
+dn_unlock:
+	eeh_serialize_unlock(flags);
+	return rc;
+}
+
+EXPORT_SYMBOL_GPL(eeh_dev_check_failure);
+
+/**
+ * eeh_check_failure - Check if all 1's data is due to EEH slot freeze
+ * @token: I/O token, should be address in the form 0xA....
+ * @val: value, should be all 1's (XXX why do we need this arg??)
+ *
+ * Check for an EEH failure at the given token address.  Call this
+ * routine if the result of a read was all 0xff's and you want to
+ * find out if this is due to an EEH slot freeze event.  This routine
+ * will query firmware for the EEH status.
+ *
+ * Note this routine is safe to call in an interrupt context.
+ */
+unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
+{
+	unsigned long addr;
+	struct eeh_dev *edev;
+
+	/* Finding the phys addr + pci device; this is pretty quick. */
+	addr = eeh_token_to_phys((unsigned long __force) token);
+	edev = eeh_addr_cache_get_dev(addr);
+	if (!edev) {
+		eeh_stats.no_device++;
+		return val;
+	}
+
+	eeh_dev_check_failure(edev);
+	return val;
+}
+
+EXPORT_SYMBOL(eeh_check_failure);
+
+
+/**
+ * eeh_pci_enable - Enable MMIO or DMA transfers for this slot
+ * @pe: EEH PE
+ *
+ * This routine should be called to reenable frozen MMIO or DMA
+ * so that it would work correctly again. It's useful while doing
+ * recovery or log collection on the indicated device.
+ */
+int eeh_pci_enable(struct eeh_pe *pe, int function)
+{
+	int rc;
+
+	rc = eeh_ops->set_option(pe, function);
+	if (rc)
+		pr_warning("%s: Unexpected state change %d on PHB#%d-PE#%x, err=%d\n",
+			__func__, function, pe->phb->global_number, pe->addr, rc);
+
+	rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
+	if (rc > 0 && (rc & EEH_STATE_MMIO_ENABLED) &&
+	   (function == EEH_OPT_THAW_MMIO))
+		return 0;
+
+	return rc;
+}
+
+/**
+ * pcibios_set_pcie_slot_reset - Set PCI-E reset state
+ * @dev: pci device struct
+ * @state: reset state to enter
+ *
+ * Return value:
+ * 	0 if success
+ */
+int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
+{
+	struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
+	struct eeh_pe *pe = edev->pe;
+
+	if (!pe) {
+		pr_err("%s: No PE found on PCI device %s\n",
+			__func__, pci_name(dev));
+		return -EINVAL;
+	}
+
+	switch (state) {
+	case pcie_deassert_reset:
+		eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
+		break;
+	case pcie_hot_reset:
+		eeh_ops->reset(pe, EEH_RESET_HOT);
+		break;
+	case pcie_warm_reset:
+		eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	return 0;
+}
+
+/**
+ * eeh_set_pe_freset - Check the required reset for the indicated device
+ * @data: EEH device
+ * @flag: return value
+ *
+ * Each device might have its preferred reset type: fundamental or
+ * hot reset. The routine is used to collected the information for
+ * the indicated device and its children so that the bunch of the
+ * devices could be reset properly.
+ */
+static void *eeh_set_dev_freset(void *data, void *flag)
+{
+	struct pci_dev *dev;
+	unsigned int *freset = (unsigned int *)flag;
+	struct eeh_dev *edev = (struct eeh_dev *)data;
+
+	dev = eeh_dev_to_pci_dev(edev);
+	if (dev)
+		*freset |= dev->needs_freset;
+
+	return NULL;
+}
+
+/**
+ * eeh_reset_pe_once - Assert the pci #RST line for 1/4 second
+ * @pe: EEH PE
+ *
+ * Assert the PCI #RST line for 1/4 second.
+ */
+static void eeh_reset_pe_once(struct eeh_pe *pe)
+{
+	unsigned int freset = 0;
+
+	/* Determine type of EEH reset required for
+	 * Partitionable Endpoint, a hot-reset (1)
+	 * or a fundamental reset (3).
+	 * A fundamental reset required by any device under
+	 * Partitionable Endpoint trumps hot-reset.
+	 */
+	eeh_pe_dev_traverse(pe, eeh_set_dev_freset, &freset);
+
+	if (freset)
+		eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
+	else
+		eeh_ops->reset(pe, EEH_RESET_HOT);
+
+	/* The PCI bus requires that the reset be held high for at least
+	 * a 100 milliseconds. We wait a bit longer 'just in case'.
+	 */
+#define PCI_BUS_RST_HOLD_TIME_MSEC 250
+	msleep(PCI_BUS_RST_HOLD_TIME_MSEC);
+
+	/* We might get hit with another EEH freeze as soon as the
+	 * pci slot reset line is dropped. Make sure we don't miss
+	 * these, and clear the flag now.
+	 */
+	eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
+
+	eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
+
+	/* After a PCI slot has been reset, the PCI Express spec requires
+	 * a 1.5 second idle time for the bus to stabilize, before starting
+	 * up traffic.
+	 */
+#define PCI_BUS_SETTLE_TIME_MSEC 1800
+	msleep(PCI_BUS_SETTLE_TIME_MSEC);
+}
+
+/**
+ * eeh_reset_pe - Reset the indicated PE
+ * @pe: EEH PE
+ *
+ * This routine should be called to reset indicated device, including
+ * PE. A PE might include multiple PCI devices and sometimes PCI bridges
+ * might be involved as well.
+ */
+int eeh_reset_pe(struct eeh_pe *pe)
+{
+	int flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE);
+	int i, rc;
+
+	/* Take three shots at resetting the bus */
+	for (i=0; i<3; i++) {
+		eeh_reset_pe_once(pe);
+
+		rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
+		if ((rc & flags) == flags)
+			return 0;
+
+		if (rc < 0) {
+			pr_err("%s: Unrecoverable slot failure on PHB#%d-PE#%x",
+				__func__, pe->phb->global_number, pe->addr);
+			return -1;
+		}
+		pr_err("EEH: bus reset %d failed on PHB#%d-PE#%x, rc=%d\n",
+			i+1, pe->phb->global_number, pe->addr, rc);
+	}
+
+	return -1;
+}
+
+/**
+ * eeh_save_bars - Save device bars
+ * @edev: PCI device associated EEH device
+ *
+ * Save the values of the device bars. Unlike the restore
+ * routine, this routine is *not* recursive. This is because
+ * PCI devices are added individually; but, for the restore,
+ * an entire slot is reset at a time.
+ */
+void eeh_save_bars(struct eeh_dev *edev)
+{
+	int i;
+	struct device_node *dn;
+
+	if (!edev)
+		return;
+	dn = eeh_dev_to_of_node(edev);
+
+	for (i = 0; i < 16; i++)
+		eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]);
+}
+
+/**
+ * eeh_ops_register - Register platform dependent EEH operations
+ * @ops: platform dependent EEH operations
+ *
+ * Register the platform dependent EEH operation callback
+ * functions. The platform should call this function before
+ * any other EEH operations.
+ */
+int __init eeh_ops_register(struct eeh_ops *ops)
+{
+	if (!ops->name) {
+		pr_warning("%s: Invalid EEH ops name for %p\n",
+			__func__, ops);
+		return -EINVAL;
+	}
+
+	if (eeh_ops && eeh_ops != ops) {
+		pr_warning("%s: EEH ops of platform %s already existing (%s)\n",
+			__func__, eeh_ops->name, ops->name);
+		return -EEXIST;
+	}
+
+	eeh_ops = ops;
+
+	return 0;
+}
+
+/**
+ * eeh_ops_unregister - Unreigster platform dependent EEH operations
+ * @name: name of EEH platform operations
+ *
+ * Unregister the platform dependent EEH operation callback
+ * functions.
+ */
+int __exit eeh_ops_unregister(const char *name)
+{
+	if (!name || !strlen(name)) {
+		pr_warning("%s: Invalid EEH ops name\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	if (eeh_ops && !strcmp(eeh_ops->name, name)) {
+		eeh_ops = NULL;
+		return 0;
+	}
+
+	return -EEXIST;
+}
+
+/**
+ * eeh_init - EEH initialization
+ *
+ * Initialize EEH by trying to enable it for all of the adapters in the system.
+ * As a side effect we can determine here if eeh is supported at all.
+ * Note that we leave EEH on so failed config cycles won't cause a machine
+ * check.  If a user turns off EEH for a particular adapter they are really
+ * telling Linux to ignore errors.  Some hardware (e.g. POWER5) won't
+ * grant access to a slot if EEH isn't enabled, and so we always enable
+ * EEH for all slots/all devices.
+ *
+ * The eeh-force-off option disables EEH checking globally, for all slots.
+ * Even if force-off is set, the EEH hardware is still enabled, so that
+ * newer systems can boot.
+ */
+int eeh_init(void)
+{
+	struct pci_controller *hose, *tmp;
+	struct device_node *phb;
+	static int cnt = 0;
+	int ret = 0;
+
+	/*
+	 * We have to delay the initialization on PowerNV after
+	 * the PCI hierarchy tree has been built because the PEs
+	 * are figured out based on PCI devices instead of device
+	 * tree nodes
+	 */
+	if (machine_is(powernv) && cnt++ <= 0)
+		return ret;
+
+	/* call platform initialization function */
+	if (!eeh_ops) {
+		pr_warning("%s: Platform EEH operation not found\n",
+			__func__);
+		return -EEXIST;
+	} else if ((ret = eeh_ops->init())) {
+		pr_warning("%s: Failed to call platform init function (%d)\n",
+			__func__, ret);
+		return ret;
+	}
+
+	/* Initialize EEH event */
+	ret = eeh_event_init();
+	if (ret)
+		return ret;
+
+	/* Enable EEH for all adapters */
+	if (eeh_probe_mode_devtree()) {
+		list_for_each_entry_safe(hose, tmp,
+			&hose_list, list_node) {
+			phb = hose->dn;
+			traverse_pci_devices(phb, eeh_ops->of_probe, NULL);
+		}
+	} else if (eeh_probe_mode_dev()) {
+		list_for_each_entry_safe(hose, tmp,
+			&hose_list, list_node)
+			pci_walk_bus(hose->bus, eeh_ops->dev_probe, NULL);
+	} else {
+		pr_warning("%s: Invalid probe mode %d\n",
+			   __func__, eeh_probe_mode);
+		return -EINVAL;
+	}
+
+	/*
+	 * Call platform post-initialization. Actually, It's good chance
+	 * to inform platform that EEH is ready to supply service if the
+	 * I/O cache stuff has been built up.
+	 */
+	if (eeh_ops->post_init) {
+		ret = eeh_ops->post_init();
+		if (ret)
+			return ret;
+	}
+
+	if (eeh_subsystem_enabled)
+		pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n");
+	else
+		pr_warning("EEH: No capable adapters found\n");
+
+	return ret;
+}
+
+core_initcall_sync(eeh_init);
+
+/**
+ * eeh_add_device_early - Enable EEH for the indicated device_node
+ * @dn: device node for which to set up EEH
+ *
+ * This routine must be used to perform EEH initialization for PCI
+ * devices that were added after system boot (e.g. hotplug, dlpar).
+ * This routine must be called before any i/o is performed to the
+ * adapter (inluding any config-space i/o).
+ * Whether this actually enables EEH or not for this device depends
+ * on the CEC architecture, type of the device, on earlier boot
+ * command-line arguments & etc.
+ */
+void eeh_add_device_early(struct device_node *dn)
+{
+	struct pci_controller *phb;
+
+	/*
+	 * If we're doing EEH probe based on PCI device, we
+	 * would delay the probe until late stage because
+	 * the PCI device isn't available this moment.
+	 */
+	if (!eeh_probe_mode_devtree())
+		return;
+
+	if (!of_node_to_eeh_dev(dn))
+		return;
+	phb = of_node_to_eeh_dev(dn)->phb;
+
+	/* USB Bus children of PCI devices will not have BUID's */
+	if (NULL == phb || 0 == phb->buid)
+		return;
+
+	eeh_ops->of_probe(dn, NULL);
+}
+
+/**
+ * eeh_add_device_tree_early - Enable EEH for the indicated device
+ * @dn: device node
+ *
+ * This routine must be used to perform EEH initialization for the
+ * indicated PCI device that was added after system boot (e.g.
+ * hotplug, dlpar).
+ */
+void eeh_add_device_tree_early(struct device_node *dn)
+{
+	struct device_node *sib;
+
+	for_each_child_of_node(dn, sib)
+		eeh_add_device_tree_early(sib);
+	eeh_add_device_early(dn);
+}
+EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
+
+/**
+ * eeh_add_device_late - Perform EEH initialization for the indicated pci device
+ * @dev: pci device for which to set up EEH
+ *
+ * This routine must be used to complete EEH initialization for PCI
+ * devices that were added after system boot (e.g. hotplug, dlpar).
+ */
+void eeh_add_device_late(struct pci_dev *dev)
+{
+	struct device_node *dn;
+	struct eeh_dev *edev;
+
+	if (!dev || !eeh_subsystem_enabled)
+		return;
+
+	pr_debug("EEH: Adding device %s\n", pci_name(dev));
+
+	dn = pci_device_to_OF_node(dev);
+	edev = of_node_to_eeh_dev(dn);
+	if (edev->pdev == dev) {
+		pr_debug("EEH: Already referenced !\n");
+		return;
+	}
+
+	/*
+	 * The EEH cache might not be removed correctly because of
+	 * unbalanced kref to the device during unplug time, which
+	 * relies on pcibios_release_device(). So we have to remove
+	 * that here explicitly.
+	 */
+	if (edev->pdev) {
+		eeh_rmv_from_parent_pe(edev);
+		eeh_addr_cache_rmv_dev(edev->pdev);
+		eeh_sysfs_remove_device(edev->pdev);
+		edev->mode &= ~EEH_DEV_SYSFS;
+
+		edev->pdev = NULL;
+		dev->dev.archdata.edev = NULL;
+	}
+
+	edev->pdev = dev;
+	dev->dev.archdata.edev = edev;
+
+	/*
+	 * We have to do the EEH probe here because the PCI device
+	 * hasn't been created yet in the early stage.
+	 */
+	if (eeh_probe_mode_dev())
+		eeh_ops->dev_probe(dev, NULL);
+
+	eeh_addr_cache_insert_dev(dev);
+}
+
+/**
+ * eeh_add_device_tree_late - Perform EEH initialization for the indicated PCI bus
+ * @bus: PCI bus
+ *
+ * This routine must be used to perform EEH initialization for PCI
+ * devices which are attached to the indicated PCI bus. The PCI bus
+ * is added after system boot through hotplug or dlpar.
+ */
+void eeh_add_device_tree_late(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		eeh_add_device_late(dev);
+		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+			struct pci_bus *subbus = dev->subordinate;
+			if (subbus)
+				eeh_add_device_tree_late(subbus);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(eeh_add_device_tree_late);
+
+/**
+ * eeh_add_sysfs_files - Add EEH sysfs files for the indicated PCI bus
+ * @bus: PCI bus
+ *
+ * This routine must be used to add EEH sysfs files for PCI
+ * devices which are attached to the indicated PCI bus. The PCI bus
+ * is added after system boot through hotplug or dlpar.
+ */
+void eeh_add_sysfs_files(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		eeh_sysfs_add_device(dev);
+		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+			struct pci_bus *subbus = dev->subordinate;
+			if (subbus)
+				eeh_add_sysfs_files(subbus);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(eeh_add_sysfs_files);
+
+/**
+ * eeh_remove_device - Undo EEH setup for the indicated pci device
+ * @dev: pci device to be removed
+ *
+ * This routine should be called when a device is removed from
+ * a running system (e.g. by hotplug or dlpar).  It unregisters
+ * the PCI device from the EEH subsystem.  I/O errors affecting
+ * this device will no longer be detected after this call; thus,
+ * i/o errors affecting this slot may leave this device unusable.
+ */
+void eeh_remove_device(struct pci_dev *dev)
+{
+	struct eeh_dev *edev;
+
+	if (!dev || !eeh_subsystem_enabled)
+		return;
+	edev = pci_dev_to_eeh_dev(dev);
+
+	/* Unregister the device with the EEH/PCI address search system */
+	pr_debug("EEH: Removing device %s\n", pci_name(dev));
+
+	if (!edev || !edev->pdev || !edev->pe) {
+		pr_debug("EEH: Not referenced !\n");
+		return;
+	}
+
+	/*
+	 * During the hotplug for EEH error recovery, we need the EEH
+	 * device attached to the parent PE in order for BAR restore
+	 * a bit later. So we keep it for BAR restore and remove it
+	 * from the parent PE during the BAR resotre.
+	 */
+	edev->pdev = NULL;
+	dev->dev.archdata.edev = NULL;
+	if (!(edev->pe->state & EEH_PE_KEEP))
+		eeh_rmv_from_parent_pe(edev);
+	else
+		edev->mode |= EEH_DEV_DISCONNECTED;
+
+	eeh_addr_cache_rmv_dev(dev);
+	eeh_sysfs_remove_device(dev);
+	edev->mode &= ~EEH_DEV_SYSFS;
+}
+
+static int proc_eeh_show(struct seq_file *m, void *v)
+{
+	if (0 == eeh_subsystem_enabled) {
+		seq_printf(m, "EEH Subsystem is globally disabled\n");
+		seq_printf(m, "eeh_total_mmio_ffs=%llu\n", eeh_stats.total_mmio_ffs);
+	} else {
+		seq_printf(m, "EEH Subsystem is enabled\n");
+		seq_printf(m,
+				"no device=%llu\n"
+				"no device node=%llu\n"
+				"no config address=%llu\n"
+				"check not wanted=%llu\n"
+				"eeh_total_mmio_ffs=%llu\n"
+				"eeh_false_positives=%llu\n"
+				"eeh_slot_resets=%llu\n",
+				eeh_stats.no_device,
+				eeh_stats.no_dn,
+				eeh_stats.no_cfg_addr,
+				eeh_stats.ignored_check,
+				eeh_stats.total_mmio_ffs,
+				eeh_stats.false_positives,
+				eeh_stats.slot_resets);
+	}
+
+	return 0;
+}
+
+static int proc_eeh_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_eeh_show, NULL);
+}
+
+static const struct file_operations proc_eeh_operations = {
+	.open      = proc_eeh_open,
+	.read      = seq_read,
+	.llseek    = seq_lseek,
+	.release   = single_release,
+};
+
+static int __init eeh_init_proc(void)
+{
+	if (machine_is(pseries) || machine_is(powernv))
+		proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations);
+	return 0;
+}
+__initcall(eeh_init_proc);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_cache.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_cache.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_cache.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_cache.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,310 @@
+/*
+ * PCI address cache; allows the lookup of PCI devices based on I/O address
+ *
+ * Copyright IBM Corporation 2004
+ * Copyright Linas Vepstas <linas@austin.ibm.com> 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/rbtree.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/atomic.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+
+
+/**
+ * The pci address cache subsystem.  This subsystem places
+ * PCI device address resources into a red-black tree, sorted
+ * according to the address range, so that given only an i/o
+ * address, the corresponding PCI device can be **quickly**
+ * found. It is safe to perform an address lookup in an interrupt
+ * context; this ability is an important feature.
+ *
+ * Currently, the only customer of this code is the EEH subsystem;
+ * thus, this code has been somewhat tailored to suit EEH better.
+ * In particular, the cache does *not* hold the addresses of devices
+ * for which EEH is not enabled.
+ *
+ * (Implementation Note: The RB tree seems to be better/faster
+ * than any hash algo I could think of for this problem, even
+ * with the penalty of slow pointer chases for d-cache misses).
+ */
+struct pci_io_addr_range {
+	struct rb_node rb_node;
+	unsigned long addr_lo;
+	unsigned long addr_hi;
+	struct eeh_dev *edev;
+	struct pci_dev *pcidev;
+	unsigned int flags;
+};
+
+static struct pci_io_addr_cache {
+	struct rb_root rb_root;
+	spinlock_t piar_lock;
+} pci_io_addr_cache_root;
+
+static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr)
+{
+	struct rb_node *n = pci_io_addr_cache_root.rb_root.rb_node;
+
+	while (n) {
+		struct pci_io_addr_range *piar;
+		piar = rb_entry(n, struct pci_io_addr_range, rb_node);
+
+		if (addr < piar->addr_lo)
+			n = n->rb_left;
+		else if (addr > piar->addr_hi)
+			n = n->rb_right;
+		else
+			return piar->edev;
+	}
+
+	return NULL;
+}
+
+/**
+ * eeh_addr_cache_get_dev - Get device, given only address
+ * @addr: mmio (PIO) phys address or i/o port number
+ *
+ * Given an mmio phys address, or a port number, find a pci device
+ * that implements this address.  Be sure to pci_dev_put the device
+ * when finished.  I/O port numbers are assumed to be offset
+ * from zero (that is, they do *not* have pci_io_addr added in).
+ * It is safe to call this function within an interrupt.
+ */
+struct eeh_dev *eeh_addr_cache_get_dev(unsigned long addr)
+{
+	struct eeh_dev *edev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
+	edev = __eeh_addr_cache_get_device(addr);
+	spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
+	return edev;
+}
+
+#ifdef DEBUG
+/*
+ * Handy-dandy debug print routine, does nothing more
+ * than print out the contents of our addr cache.
+ */
+static void eeh_addr_cache_print(struct pci_io_addr_cache *cache)
+{
+	struct rb_node *n;
+	int cnt = 0;
+
+	n = rb_first(&cache->rb_root);
+	while (n) {
+		struct pci_io_addr_range *piar;
+		piar = rb_entry(n, struct pci_io_addr_range, rb_node);
+		pr_debug("PCI: %s addr range %d [%lx-%lx]: %s\n",
+		       (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
+		       piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
+		cnt++;
+		n = rb_next(n);
+	}
+}
+#endif
+
+/* Insert address range into the rb tree. */
+static struct pci_io_addr_range *
+eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
+		      unsigned long ahi, unsigned int flags)
+{
+	struct rb_node **p = &pci_io_addr_cache_root.rb_root.rb_node;
+	struct rb_node *parent = NULL;
+	struct pci_io_addr_range *piar;
+
+	/* Walk tree, find a place to insert into tree */
+	while (*p) {
+		parent = *p;
+		piar = rb_entry(parent, struct pci_io_addr_range, rb_node);
+		if (ahi < piar->addr_lo) {
+			p = &parent->rb_left;
+		} else if (alo > piar->addr_hi) {
+			p = &parent->rb_right;
+		} else {
+			if (dev != piar->pcidev ||
+			    alo != piar->addr_lo || ahi != piar->addr_hi) {
+				pr_warning("PIAR: overlapping address range\n");
+			}
+			return piar;
+		}
+	}
+	piar = kzalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
+	if (!piar)
+		return NULL;
+
+	piar->addr_lo = alo;
+	piar->addr_hi = ahi;
+	piar->edev = pci_dev_to_eeh_dev(dev);
+	piar->pcidev = dev;
+	piar->flags = flags;
+
+#ifdef DEBUG
+	pr_debug("PIAR: insert range=[%lx:%lx] dev=%s\n",
+	                  alo, ahi, pci_name(dev));
+#endif
+
+	rb_link_node(&piar->rb_node, parent, p);
+	rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
+
+	return piar;
+}
+
+static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
+{
+	struct device_node *dn;
+	struct eeh_dev *edev;
+	int i;
+
+	dn = pci_device_to_OF_node(dev);
+	if (!dn) {
+		pr_warning("PCI: no pci dn found for dev=%s\n", pci_name(dev));
+		return;
+	}
+
+	edev = of_node_to_eeh_dev(dn);
+	if (!edev) {
+		pr_warning("PCI: no EEH dev found for dn=%s\n",
+			dn->full_name);
+		return;
+	}
+
+	/* Skip any devices for which EEH is not enabled. */
+	if (!eeh_probe_mode_dev() && !edev->pe) {
+#ifdef DEBUG
+		pr_info("PCI: skip building address cache for=%s - %s\n",
+			pci_name(dev), dn->full_name);
+#endif
+		return;
+	}
+
+	/* Walk resources on this device, poke them into the tree */
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		unsigned long start = pci_resource_start(dev,i);
+		unsigned long end = pci_resource_end(dev,i);
+		unsigned int flags = pci_resource_flags(dev,i);
+
+		/* We are interested only bus addresses, not dma or other stuff */
+		if (0 == (flags & (IORESOURCE_IO | IORESOURCE_MEM)))
+			continue;
+		if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
+			 continue;
+		eeh_addr_cache_insert(dev, start, end, flags);
+	}
+}
+
+/**
+ * eeh_addr_cache_insert_dev - Add a device to the address cache
+ * @dev: PCI device whose I/O addresses we are interested in.
+ *
+ * In order to support the fast lookup of devices based on addresses,
+ * we maintain a cache of devices that can be quickly searched.
+ * This routine adds a device to that cache.
+ */
+void eeh_addr_cache_insert_dev(struct pci_dev *dev)
+{
+	unsigned long flags;
+
+	/* Ignore PCI bridges */
+	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+		return;
+
+	spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
+	__eeh_addr_cache_insert_dev(dev);
+	spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
+}
+
+static inline void __eeh_addr_cache_rmv_dev(struct pci_dev *dev)
+{
+	struct rb_node *n;
+
+restart:
+	n = rb_first(&pci_io_addr_cache_root.rb_root);
+	while (n) {
+		struct pci_io_addr_range *piar;
+		piar = rb_entry(n, struct pci_io_addr_range, rb_node);
+
+		if (piar->pcidev == dev) {
+			rb_erase(n, &pci_io_addr_cache_root.rb_root);
+			kfree(piar);
+			goto restart;
+		}
+		n = rb_next(n);
+	}
+}
+
+/**
+ * eeh_addr_cache_rmv_dev - remove pci device from addr cache
+ * @dev: device to remove
+ *
+ * Remove a device from the addr-cache tree.
+ * This is potentially expensive, since it will walk
+ * the tree multiple times (once per resource).
+ * But so what; device removal doesn't need to be that fast.
+ */
+void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
+	__eeh_addr_cache_rmv_dev(dev);
+	spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
+}
+
+/**
+ * eeh_addr_cache_build - Build a cache of I/O addresses
+ *
+ * Build a cache of pci i/o addresses.  This cache will be used to
+ * find the pci device that corresponds to a given address.
+ * This routine scans all pci busses to build the cache.
+ * Must be run late in boot process, after the pci controllers
+ * have been scanned for devices (after all device resources are known).
+ */
+void eeh_addr_cache_build(void)
+{
+	struct device_node *dn;
+	struct eeh_dev *edev;
+	struct pci_dev *dev = NULL;
+
+	spin_lock_init(&pci_io_addr_cache_root.piar_lock);
+
+	for_each_pci_dev(dev) {
+		dn = pci_device_to_OF_node(dev);
+		if (!dn)
+			continue;
+
+		edev = of_node_to_eeh_dev(dn);
+		if (!edev)
+			continue;
+
+		dev->dev.archdata.edev = edev;
+		edev->pdev = dev;
+
+		eeh_addr_cache_insert_dev(dev);
+		eeh_sysfs_add_device(dev);
+	}
+
+#ifdef DEBUG
+	/* Verify tree built up above, echo back the list of addrs. */
+	eeh_addr_cache_print(&pci_io_addr_cache_root);
+#endif
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_dev.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_dev.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_dev.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_dev.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,112 @@
+/*
+ * The file intends to implement dynamic creation of EEH device, which will
+ * be bound with OF node and PCI device simutaneously. The EEH devices would
+ * be foundamental information for EEH core components to work proerly. Besides,
+ * We have to support multiple situations where dynamic creation of EEH device
+ * is required:
+ *
+ * 1) Before PCI emunation starts, we need create EEH devices according to the
+ *    PCI sensitive OF nodes.
+ * 2) When PCI emunation is done, we need do the binding between PCI device and
+ *    the associated EEH device.
+ * 3) DR (Dynamic Reconfiguration) would create PCI sensitive OF node. EEH device
+ *    will be created while PCI sensitive OF node is detected from DR.
+ * 4) PCI hotplug needs redoing the binding between PCI device and EEH device. If
+ *    PHB is newly inserted, we also need create EEH devices accordingly.
+ *
+ * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/export.h>
+#include <linux/gfp.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+
+/**
+ * eeh_dev_init - Create EEH device according to OF node
+ * @dn: device node
+ * @data: PHB
+ *
+ * It will create EEH device according to the given OF node. The function
+ * might be called by PCI emunation, DR, PHB hotplug.
+ */
+void *eeh_dev_init(struct device_node *dn, void *data)
+{
+	struct pci_controller *phb = data;
+	struct eeh_dev *edev;
+
+	/* Allocate EEH device */
+	edev = kzalloc(sizeof(*edev), GFP_KERNEL);
+	if (!edev) {
+		pr_warning("%s: out of memory\n", __func__);
+		return NULL;
+	}
+
+	/* Associate EEH device with OF node */
+	PCI_DN(dn)->edev = edev;
+	edev->dn  = dn;
+	edev->phb = phb;
+	INIT_LIST_HEAD(&edev->list);
+
+	return NULL;
+}
+
+/**
+ * eeh_dev_phb_init_dynamic - Create EEH devices for devices included in PHB
+ * @phb: PHB
+ *
+ * Scan the PHB OF node and its child association, then create the
+ * EEH devices accordingly
+ */
+void eeh_dev_phb_init_dynamic(struct pci_controller *phb)
+{
+	struct device_node *dn = phb->dn;
+
+	/* EEH PE for PHB */
+	eeh_phb_pe_create(phb);
+
+	/* EEH device for PHB */
+	eeh_dev_init(dn, phb);
+
+	/* EEH devices for children OF nodes */
+	traverse_pci_devices(dn, eeh_dev_init, phb);
+}
+
+/**
+ * eeh_dev_phb_init - Create EEH devices for devices included in existing PHBs
+ *
+ * Scan all the existing PHBs and create EEH devices for their OF
+ * nodes and their children OF nodes
+ */
+static int __init eeh_dev_phb_init(void)
+{
+	struct pci_controller *phb, *tmp;
+
+	list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
+		eeh_dev_phb_init_dynamic(phb);
+
+	pr_info("EEH: devices created\n");
+
+	return 0;
+}
+
+core_initcall(eeh_dev_phb_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_driver.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_driver.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_driver.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,732 @@
+/*
+ * PCI Error Recovery Driver for RPA-compliant PPC64 platform.
+ * Copyright IBM Corp. 2004 2005
+ * Copyright Linas Vepstas <linas@linas.org> 2004, 2005
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
+ */
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <asm/eeh.h>
+#include <asm/eeh_event.h>
+#include <asm/ppc-pci.h>
+#include <asm/pci-bridge.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+
+/**
+ * eeh_pcid_name - Retrieve name of PCI device driver
+ * @pdev: PCI device
+ *
+ * This routine is used to retrieve the name of PCI device driver
+ * if that's valid.
+ */
+static inline const char *eeh_pcid_name(struct pci_dev *pdev)
+{
+	if (pdev && pdev->dev.driver)
+		return pdev->dev.driver->name;
+	return "";
+}
+
+/**
+ * eeh_pcid_get - Get the PCI device driver
+ * @pdev: PCI device
+ *
+ * The function is used to retrieve the PCI device driver for
+ * the indicated PCI device. Besides, we will increase the reference
+ * of the PCI device driver to prevent that being unloaded on
+ * the fly. Otherwise, kernel crash would be seen.
+ */
+static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev)
+{
+	if (!pdev || !pdev->driver)
+		return NULL;
+
+	if (!try_module_get(pdev->driver->driver.owner))
+		return NULL;
+
+	return pdev->driver;
+}
+
+/**
+ * eeh_pcid_put - Dereference on the PCI device driver
+ * @pdev: PCI device
+ *
+ * The function is called to do dereference on the PCI device
+ * driver of the indicated PCI device.
+ */
+static inline void eeh_pcid_put(struct pci_dev *pdev)
+{
+	if (!pdev || !pdev->driver)
+		return;
+
+	module_put(pdev->driver->driver.owner);
+}
+
+#if 0
+static void print_device_node_tree(struct pci_dn *pdn, int dent)
+{
+	int i;
+	struct device_node *pc;
+
+	if (!pdn)
+		return;
+	for (i = 0; i < dent; i++)
+		printk(" ");
+	printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
+		pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
+		pdn->eeh_pe_config_addr, pdn->node->full_name);
+	dent += 3;
+	pc = pdn->node->child;
+	while (pc) {
+		print_device_node_tree(PCI_DN(pc), dent);
+		pc = pc->sibling;
+	}
+}
+#endif
+
+/**
+ * eeh_disable_irq - Disable interrupt for the recovering device
+ * @dev: PCI device
+ *
+ * This routine must be called when reporting temporary or permanent
+ * error to the particular PCI device to disable interrupt of that
+ * device. If the device has enabled MSI or MSI-X interrupt, we needn't
+ * do real work because EEH should freeze DMA transfers for those PCI
+ * devices encountering EEH errors, which includes MSI or MSI-X.
+ */
+static void eeh_disable_irq(struct pci_dev *dev)
+{
+	struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
+
+	/* Don't disable MSI and MSI-X interrupts. They are
+	 * effectively disabled by the DMA Stopped state
+	 * when an EEH error occurs.
+	 */
+	if (dev->msi_enabled || dev->msix_enabled)
+		return;
+
+	if (!irq_has_action(dev->irq))
+		return;
+
+	edev->mode |= EEH_DEV_IRQ_DISABLED;
+	disable_irq_nosync(dev->irq);
+}
+
+/**
+ * eeh_enable_irq - Enable interrupt for the recovering device
+ * @dev: PCI device
+ *
+ * This routine must be called to enable interrupt while failed
+ * device could be resumed.
+ */
+static void eeh_enable_irq(struct pci_dev *dev)
+{
+	struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
+	struct irq_desc *desc;
+
+	if ((edev->mode) & EEH_DEV_IRQ_DISABLED) {
+		edev->mode &= ~EEH_DEV_IRQ_DISABLED;
+
+		desc = irq_to_desc(dev->irq);
+		if (desc && desc->depth > 0)
+			enable_irq(dev->irq);
+	}
+}
+
+/**
+ * eeh_report_error - Report pci error to each device driver
+ * @data: eeh device
+ * @userdata: return value
+ *
+ * Report an EEH error to each device driver, collect up and
+ * merge the device driver responses. Cumulative response
+ * passed back in "userdata".
+ */
+static void *eeh_report_error(void *data, void *userdata)
+{
+	struct eeh_dev *edev = (struct eeh_dev *)data;
+	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+	enum pci_ers_result rc, *res = userdata;
+	struct pci_driver *driver;
+
+	/* We might not have the associated PCI device,
+	 * then we should continue for next one.
+	 */
+	if (!dev) return NULL;
+	dev->error_state = pci_channel_io_frozen;
+
+	driver = eeh_pcid_get(dev);
+	if (!driver) return NULL;
+
+	eeh_disable_irq(dev);
+
+	if (!driver->err_handler ||
+	    !driver->err_handler->error_detected) {
+		eeh_pcid_put(dev);
+		return NULL;
+	}
+
+	rc = driver->err_handler->error_detected(dev, pci_channel_io_frozen);
+
+	/* A driver that needs a reset trumps all others */
+	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
+	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+
+	eeh_pcid_put(dev);
+	return NULL;
+}
+
+/**
+ * eeh_report_mmio_enabled - Tell drivers that MMIO has been enabled
+ * @data: eeh device
+ * @userdata: return value
+ *
+ * Tells each device driver that IO ports, MMIO and config space I/O
+ * are now enabled. Collects up and merges the device driver responses.
+ * Cumulative response passed back in "userdata".
+ */
+static void *eeh_report_mmio_enabled(void *data, void *userdata)
+{
+	struct eeh_dev *edev = (struct eeh_dev *)data;
+	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+	enum pci_ers_result rc, *res = userdata;
+	struct pci_driver *driver;
+
+	driver = eeh_pcid_get(dev);
+	if (!driver) return NULL;
+
+	if (!driver->err_handler ||
+	    !driver->err_handler->mmio_enabled) {
+		eeh_pcid_put(dev);
+		return NULL;
+	}
+
+	rc = driver->err_handler->mmio_enabled(dev);
+
+	/* A driver that needs a reset trumps all others */
+	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
+	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+
+	eeh_pcid_put(dev);
+	return NULL;
+}
+
+/**
+ * eeh_report_reset - Tell device that slot has been reset
+ * @data: eeh device
+ * @userdata: return value
+ *
+ * This routine must be called while EEH tries to reset particular
+ * PCI device so that the associated PCI device driver could take
+ * some actions, usually to save data the driver needs so that the
+ * driver can work again while the device is recovered.
+ */
+static void *eeh_report_reset(void *data, void *userdata)
+{
+	struct eeh_dev *edev = (struct eeh_dev *)data;
+	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+	enum pci_ers_result rc, *res = userdata;
+	struct pci_driver *driver;
+
+	if (!dev) return NULL;
+	dev->error_state = pci_channel_io_normal;
+
+	driver = eeh_pcid_get(dev);
+	if (!driver) return NULL;
+
+	eeh_enable_irq(dev);
+
+	if (!driver->err_handler ||
+	    !driver->err_handler->slot_reset) {
+		eeh_pcid_put(dev);
+		return NULL;
+	}
+
+	rc = driver->err_handler->slot_reset(dev);
+	if ((*res == PCI_ERS_RESULT_NONE) ||
+	    (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc;
+	if (*res == PCI_ERS_RESULT_DISCONNECT &&
+	     rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
+
+	eeh_pcid_put(dev);
+	return NULL;
+}
+
+/**
+ * eeh_report_resume - Tell device to resume normal operations
+ * @data: eeh device
+ * @userdata: return value
+ *
+ * This routine must be called to notify the device driver that it
+ * could resume so that the device driver can do some initialization
+ * to make the recovered device work again.
+ */
+static void *eeh_report_resume(void *data, void *userdata)
+{
+	struct eeh_dev *edev = (struct eeh_dev *)data;
+	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+	struct pci_driver *driver;
+
+	if (!dev) return NULL;
+	dev->error_state = pci_channel_io_normal;
+
+	driver = eeh_pcid_get(dev);
+	if (!driver) return NULL;
+
+	eeh_enable_irq(dev);
+
+	if (!driver->err_handler ||
+	    !driver->err_handler->resume) {
+		eeh_pcid_put(dev);
+		return NULL;
+	}
+
+	driver->err_handler->resume(dev);
+
+	eeh_pcid_put(dev);
+	return NULL;
+}
+
+/**
+ * eeh_report_failure - Tell device driver that device is dead.
+ * @data: eeh device
+ * @userdata: return value
+ *
+ * This informs the device driver that the device is permanently
+ * dead, and that no further recovery attempts will be made on it.
+ */
+static void *eeh_report_failure(void *data, void *userdata)
+{
+	struct eeh_dev *edev = (struct eeh_dev *)data;
+	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+	struct pci_driver *driver;
+
+	if (!dev) return NULL;
+	dev->error_state = pci_channel_io_perm_failure;
+
+	driver = eeh_pcid_get(dev);
+	if (!driver) return NULL;
+
+	eeh_disable_irq(dev);
+
+	if (!driver->err_handler ||
+	    !driver->err_handler->error_detected) {
+		eeh_pcid_put(dev);
+		return NULL;
+	}
+
+	driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
+
+	eeh_pcid_put(dev);
+	return NULL;
+}
+
+static void *eeh_rmv_device(void *data, void *userdata)
+{
+	struct pci_driver *driver;
+	struct eeh_dev *edev = (struct eeh_dev *)data;
+	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
+	int *removed = (int *)userdata;
+
+	/*
+	 * Actually, we should remove the PCI bridges as well.
+	 * However, that's lots of complexity to do that,
+	 * particularly some of devices under the bridge might
+	 * support EEH. So we just care about PCI devices for
+	 * simplicity here.
+	 */
+	if (!dev || (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
+		return NULL;
+	driver = eeh_pcid_get(dev);
+	if (driver && driver->err_handler)
+		return NULL;
+
+	/* Remove it from PCI subsystem */
+	pr_debug("EEH: Removing %s without EEH sensitive driver\n",
+		 pci_name(dev));
+	edev->bus = dev->bus;
+	edev->mode |= EEH_DEV_DISCONNECTED;
+	(*removed)++;
+
+	pci_stop_and_remove_bus_device(dev);
+
+	return NULL;
+}
+
+static void *eeh_pe_detach_dev(void *data, void *userdata)
+{
+	struct eeh_pe *pe = (struct eeh_pe *)data;
+	struct eeh_dev *edev, *tmp;
+
+	eeh_pe_for_each_dev(pe, edev, tmp) {
+		if (!(edev->mode & EEH_DEV_DISCONNECTED))
+			continue;
+
+		edev->mode &= ~(EEH_DEV_DISCONNECTED | EEH_DEV_IRQ_DISABLED);
+		eeh_rmv_from_parent_pe(edev);
+	}
+
+	return NULL;
+}
+
+/**
+ * eeh_reset_device - Perform actual reset of a pci slot
+ * @pe: EEH PE
+ * @bus: PCI bus corresponding to the isolcated slot
+ *
+ * This routine must be called to do reset on the indicated PE.
+ * During the reset, udev might be invoked because those affected
+ * PCI devices will be removed and then added.
+ */
+static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
+{
+	struct pci_bus *frozen_bus = eeh_pe_bus_get(pe);
+	struct timeval tstamp;
+	int cnt, rc, removed = 0;
+
+	/* pcibios will clear the counter; save the value */
+	cnt = pe->freeze_count;
+	tstamp = pe->tstamp;
+
+	/*
+	 * We don't remove the corresponding PE instances because
+	 * we need the information afterwords. The attached EEH
+	 * devices are expected to be attached soon when calling
+	 * into pcibios_add_pci_devices().
+	 */
+	eeh_pe_state_mark(pe, EEH_PE_KEEP);
+	if (bus)
+		pcibios_remove_pci_devices(bus);
+	else if (frozen_bus)
+		eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed);
+
+	/* Reset the pci controller. (Asserts RST#; resets config space).
+	 * Reconfigure bridges and devices. Don't try to bring the system
+	 * up if the reset failed for some reason.
+	 */
+	rc = eeh_reset_pe(pe);
+	if (rc)
+		return rc;
+
+	/* Restore PE */
+	eeh_ops->configure_bridge(pe);
+	eeh_pe_restore_bars(pe);
+
+	/* Give the system 5 seconds to finish running the user-space
+	 * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes,
+	 * this is a hack, but if we don't do this, and try to bring
+	 * the device up before the scripts have taken it down,
+	 * potentially weird things happen.
+	 */
+	if (bus) {
+		pr_info("EEH: Sleep 5s ahead of complete hotplug\n");
+		ssleep(5);
+
+		/*
+		 * The EEH device is still connected with its parent
+		 * PE. We should disconnect it so the binding can be
+		 * rebuilt when adding PCI devices.
+		 */
+		eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
+		pcibios_add_pci_devices(bus);
+	} else if (frozen_bus && removed) {
+		pr_info("EEH: Sleep 5s ahead of partial hotplug\n");
+		ssleep(5);
+
+		eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
+		pcibios_add_pci_devices(frozen_bus);
+	}
+	eeh_pe_state_clear(pe, EEH_PE_KEEP);
+
+	pe->tstamp = tstamp;
+	pe->freeze_count = cnt;
+
+	return 0;
+}
+
+/* The longest amount of time to wait for a pci device
+ * to come back on line, in seconds.
+ */
+#define MAX_WAIT_FOR_RECOVERY 150
+
+static void eeh_handle_normal_event(struct eeh_pe *pe)
+{
+	struct pci_bus *frozen_bus;
+	int rc = 0;
+	enum pci_ers_result result = PCI_ERS_RESULT_NONE;
+
+	frozen_bus = eeh_pe_bus_get(pe);
+	if (!frozen_bus) {
+		pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n",
+			__func__, pe->phb->global_number, pe->addr);
+		return;
+	}
+
+	eeh_pe_update_time_stamp(pe);
+	pe->freeze_count++;
+	if (pe->freeze_count > EEH_MAX_ALLOWED_FREEZES)
+		goto excess_failures;
+	pr_warning("EEH: This PCI device has failed %d times in the last hour\n",
+		pe->freeze_count);
+
+	/* Walk the various device drivers attached to this slot through
+	 * a reset sequence, giving each an opportunity to do what it needs
+	 * to accomplish the reset.  Each child gets a report of the
+	 * status ... if any child can't handle the reset, then the entire
+	 * slot is dlpar removed and added.
+	 */
+	pr_info("EEH: Notify device drivers to shutdown\n");
+	eeh_pe_dev_traverse(pe, eeh_report_error, &result);
+
+	/* Get the current PCI slot state. This can take a long time,
+	 * sometimes over 3 seconds for certain systems.
+	 */
+	rc = eeh_ops->wait_state(pe, MAX_WAIT_FOR_RECOVERY*1000);
+	if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) {
+		pr_warning("EEH: Permanent failure\n");
+		goto hard_fail;
+	}
+
+	/* Since rtas may enable MMIO when posting the error log,
+	 * don't post the error log until after all dev drivers
+	 * have been informed.
+	 */
+	pr_info("EEH: Collect temporary log\n");
+	eeh_slot_error_detail(pe, EEH_LOG_TEMP);
+
+	/* If all device drivers were EEH-unaware, then shut
+	 * down all of the device drivers, and hope they
+	 * go down willingly, without panicing the system.
+	 */
+	if (result == PCI_ERS_RESULT_NONE) {
+		pr_info("EEH: Reset with hotplug activity\n");
+		rc = eeh_reset_device(pe, frozen_bus);
+		if (rc) {
+			pr_warning("%s: Unable to reset, err=%d\n",
+				   __func__, rc);
+			goto hard_fail;
+		}
+	}
+
+	/* If all devices reported they can proceed, then re-enable MMIO */
+	if (result == PCI_ERS_RESULT_CAN_RECOVER) {
+		pr_info("EEH: Enable I/O for affected devices\n");
+		rc = eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
+
+		if (rc < 0)
+			goto hard_fail;
+		if (rc) {
+			result = PCI_ERS_RESULT_NEED_RESET;
+		} else {
+			pr_info("EEH: Notify device drivers to resume I/O\n");
+			result = PCI_ERS_RESULT_NONE;
+			eeh_pe_dev_traverse(pe, eeh_report_mmio_enabled, &result);
+		}
+	}
+
+	/* If all devices reported they can proceed, then re-enable DMA */
+	if (result == PCI_ERS_RESULT_CAN_RECOVER) {
+		pr_info("EEH: Enabled DMA for affected devices\n");
+		rc = eeh_pci_enable(pe, EEH_OPT_THAW_DMA);
+
+		if (rc < 0)
+			goto hard_fail;
+		if (rc)
+			result = PCI_ERS_RESULT_NEED_RESET;
+		else
+			result = PCI_ERS_RESULT_RECOVERED;
+	}
+
+	/* If any device has a hard failure, then shut off everything. */
+	if (result == PCI_ERS_RESULT_DISCONNECT) {
+		pr_warning("EEH: Device driver gave up\n");
+		goto hard_fail;
+	}
+
+	/* If any device called out for a reset, then reset the slot */
+	if (result == PCI_ERS_RESULT_NEED_RESET) {
+		pr_info("EEH: Reset without hotplug activity\n");
+		rc = eeh_reset_device(pe, NULL);
+		if (rc) {
+			pr_warning("%s: Cannot reset, err=%d\n",
+				   __func__, rc);
+			goto hard_fail;
+		}
+
+		pr_info("EEH: Notify device drivers "
+			"the completion of reset\n");
+		result = PCI_ERS_RESULT_NONE;
+		eeh_pe_dev_traverse(pe, eeh_report_reset, &result);
+	}
+
+	/* All devices should claim they have recovered by now. */
+	if ((result != PCI_ERS_RESULT_RECOVERED) &&
+	    (result != PCI_ERS_RESULT_NONE)) {
+		pr_warning("EEH: Not recovered\n");
+		goto hard_fail;
+	}
+
+	/* Tell all device drivers that they can resume operations */
+	pr_info("EEH: Notify device driver to resume\n");
+	eeh_pe_dev_traverse(pe, eeh_report_resume, NULL);
+
+	return;
+
+excess_failures:
+	/*
+	 * About 90% of all real-life EEH failures in the field
+	 * are due to poorly seated PCI cards. Only 10% or so are
+	 * due to actual, failed cards.
+	 */
+	pr_err("EEH: PHB#%d-PE#%x has failed %d times in the\n"
+	       "last hour and has been permanently disabled.\n"
+	       "Please try reseating or replacing it.\n",
+		pe->phb->global_number, pe->addr,
+		pe->freeze_count);
+	goto perm_error;
+
+hard_fail:
+	pr_err("EEH: Unable to recover from failure from PHB#%d-PE#%x.\n"
+	       "Please try reseating or replacing it\n",
+		pe->phb->global_number, pe->addr);
+
+perm_error:
+	eeh_slot_error_detail(pe, EEH_LOG_PERM);
+
+	/* Notify all devices that they're about to go down. */
+	eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
+
+	/* Shut down the device drivers for good. */
+	if (frozen_bus)
+		pcibios_remove_pci_devices(frozen_bus);
+}
+
+static void eeh_handle_special_event(void)
+{
+	struct eeh_pe *pe, *phb_pe;
+	struct pci_bus *bus;
+	struct pci_controller *hose, *tmp;
+	unsigned long flags;
+	int rc = 0;
+
+	/*
+	 * The return value from next_error() has been classified as follows.
+	 * It might be good to enumerate them. However, next_error() is only
+	 * supported by PowerNV platform for now. So it would be fine to use
+	 * integer directly:
+	 *
+	 * 4 - Dead IOC           3 - Dead PHB
+	 * 2 - Fenced PHB         1 - Frozen PE
+	 * 0 - No error found
+	 *
+	 */
+	rc = eeh_ops->next_error(&pe);
+	if (rc <= 0)
+		return;
+
+	switch (rc) {
+	case 4:
+		/* Mark all PHBs in dead state */
+		eeh_serialize_lock(&flags);
+		list_for_each_entry_safe(hose, tmp,
+				&hose_list, list_node) {
+			phb_pe = eeh_phb_pe_get(hose);
+			if (!phb_pe) continue;
+
+			eeh_pe_state_mark(phb_pe,
+				EEH_PE_ISOLATED | EEH_PE_PHB_DEAD);
+		}
+		eeh_serialize_unlock(flags);
+
+		/* Purge all events */
+		eeh_remove_event(NULL);
+		break;
+	case 3:
+	case 2:
+	case 1:
+		/* Mark the PE in fenced state */
+		eeh_serialize_lock(&flags);
+		if (rc == 3)
+			eeh_pe_state_mark(pe,
+				EEH_PE_ISOLATED | EEH_PE_PHB_DEAD);
+		else
+			eeh_pe_state_mark(pe,
+				EEH_PE_ISOLATED | EEH_PE_RECOVERING);
+		eeh_serialize_unlock(flags);
+
+		/* Purge all events of the PHB */
+		eeh_remove_event(pe);
+		break;
+	default:
+		pr_err("%s: Invalid value %d from next_error()\n",
+		       __func__, rc);
+		return;
+	}
+
+	/*
+	 * For fenced PHB and frozen PE, it's handled as normal
+	 * event. We have to remove the affected PHBs for dead
+	 * PHB and IOC
+	 */
+	if (rc == 2 || rc == 1)
+		eeh_handle_normal_event(pe);
+	else {
+		list_for_each_entry_safe(hose, tmp,
+			&hose_list, list_node) {
+			phb_pe = eeh_phb_pe_get(hose);
+			if (!phb_pe || !(phb_pe->state & EEH_PE_PHB_DEAD))
+				continue;
+
+			bus = eeh_pe_bus_get(phb_pe);
+			/* Notify all devices that they're about to go down. */
+			eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
+			pcibios_remove_pci_devices(bus);
+		}
+	}
+}
+
+/**
+ * eeh_handle_event - Reset a PCI device after hard lockup.
+ * @pe: EEH PE
+ *
+ * While PHB detects address or data parity errors on particular PCI
+ * slot, the associated PE will be frozen. Besides, DMA's occurring
+ * to wild addresses (which usually happen due to bugs in device
+ * drivers or in PCI adapter firmware) can cause EEH error. #SERR,
+ * #PERR or other misc PCI-related errors also can trigger EEH errors.
+ *
+ * Recovery process consists of unplugging the device driver (which
+ * generated hotplug events to userspace), then issuing a PCI #RST to
+ * the device, then reconfiguring the PCI config space for all bridges
+ * & devices under this slot, and then finally restarting the device
+ * drivers (which cause a second set of hotplug events to go out to
+ * userspace).
+ */
+void eeh_handle_event(struct eeh_pe *pe)
+{
+	if (pe)
+		eeh_handle_normal_event(pe);
+	else
+		eeh_handle_special_event();
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_event.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_event.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_event.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,182 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
+ */
+
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <asm/eeh_event.h>
+#include <asm/ppc-pci.h>
+
+/** Overview:
+ *  EEH error states may be detected within exception handlers;
+ *  however, the recovery processing needs to occur asynchronously
+ *  in a normal kernel context and not an interrupt context.
+ *  This pair of routines creates an event and queues it onto a
+ *  work-queue, where a worker thread can drive recovery.
+ */
+
+static DEFINE_SPINLOCK(eeh_eventlist_lock);
+static struct semaphore eeh_eventlist_sem;
+LIST_HEAD(eeh_eventlist);
+
+/**
+ * eeh_event_handler - Dispatch EEH events.
+ * @dummy - unused
+ *
+ * The detection of a frozen slot can occur inside an interrupt,
+ * where it can be hard to do anything about it.  The goal of this
+ * routine is to pull these detection events out of the context
+ * of the interrupt handler, and re-dispatch them for processing
+ * at a later time in a normal context.
+ */
+static int eeh_event_handler(void * dummy)
+{
+	unsigned long flags;
+	struct eeh_event *event;
+	struct eeh_pe *pe;
+
+	while (!kthread_should_stop()) {
+		if (down_interruptible(&eeh_eventlist_sem))
+			break;
+
+		/* Fetch EEH event from the queue */
+		spin_lock_irqsave(&eeh_eventlist_lock, flags);
+		event = NULL;
+		if (!list_empty(&eeh_eventlist)) {
+			event = list_entry(eeh_eventlist.next,
+					   struct eeh_event, list);
+			list_del(&event->list);
+		}
+		spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
+		if (!event)
+			continue;
+
+		/* We might have event without binding PE */
+		pe = event->pe;
+		if (pe) {
+			eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
+			pr_info("EEH: Detected PCI bus error on PHB#%d-PE#%x\n",
+				 pe->phb->global_number, pe->addr);
+			eeh_handle_event(pe);
+			eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
+		} else {
+			eeh_handle_event(NULL);
+		}
+
+		kfree(event);
+	}
+
+	return 0;
+}
+
+/**
+ * eeh_event_init - Start kernel thread to handle EEH events
+ *
+ * This routine is called to start the kernel thread for processing
+ * EEH event.
+ */
+int eeh_event_init(void)
+{
+	struct task_struct *t;
+	int ret = 0;
+
+	/* Initialize semaphore */
+	sema_init(&eeh_eventlist_sem, 0);
+
+	t = kthread_run(eeh_event_handler, NULL, "eehd");
+	if (IS_ERR(t)) {
+		ret = PTR_ERR(t);
+		pr_err("%s: Failed to start EEH daemon (%d)\n",
+			__func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * eeh_send_failure_event - Generate a PCI error event
+ * @pe: EEH PE
+ *
+ * This routine can be called within an interrupt context;
+ * the actual event will be delivered in a normal context
+ * (from a workqueue).
+ */
+int eeh_send_failure_event(struct eeh_pe *pe)
+{
+	unsigned long flags;
+	struct eeh_event *event;
+
+	event = kzalloc(sizeof(*event), GFP_ATOMIC);
+	if (!event) {
+		pr_err("EEH: out of memory, event not handled\n");
+		return -ENOMEM;
+	}
+	event->pe = pe;
+
+	/* We may or may not be called in an interrupt context */
+	spin_lock_irqsave(&eeh_eventlist_lock, flags);
+	list_add(&event->list, &eeh_eventlist);
+	spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
+
+	/* For EEH deamon to knick in */
+	up(&eeh_eventlist_sem);
+
+	return 0;
+}
+
+/**
+ * eeh_remove_event - Remove EEH event from the queue
+ * @pe: Event binding to the PE
+ *
+ * On PowerNV platform, we might have subsequent coming events
+ * is part of the former one. For that case, those subsequent
+ * coming events are totally duplicated and unnecessary, thus
+ * they should be removed.
+ */
+void eeh_remove_event(struct eeh_pe *pe)
+{
+	unsigned long flags;
+	struct eeh_event *event, *tmp;
+
+	spin_lock_irqsave(&eeh_eventlist_lock, flags);
+	list_for_each_entry_safe(event, tmp, &eeh_eventlist, list) {
+		/*
+		 * If we don't have valid PE passed in, that means
+		 * we already have event corresponding to dead IOC
+		 * and all events should be purged.
+		 */
+		if (!pe) {
+			list_del(&event->list);
+			kfree(event);
+		} else if (pe->type & EEH_PE_PHB) {
+			if (event->pe && event->pe->phb == pe->phb) {
+				list_del(&event->list);
+				kfree(event);
+			}
+		} else if (event->pe == pe) {
+			list_del(&event->list);
+			kfree(event);
+		}
+	}
+	spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_pe.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_pe.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_pe.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_pe.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,792 @@
+/*
+ * The file intends to implement PE based on the information from
+ * platforms. Basically, there have 3 types of PEs: PHB/Bus/Device.
+ * All the PEs should be organized as hierarchy tree. The first level
+ * of the tree will be associated to existing PHBs since the particular
+ * PE is only meaningful in one PHB domain.
+ *
+ * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2012.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/gfp.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+
+static LIST_HEAD(eeh_phb_pe);
+
+/**
+ * eeh_pe_alloc - Allocate PE
+ * @phb: PCI controller
+ * @type: PE type
+ *
+ * Allocate PE instance dynamically.
+ */
+static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)
+{
+	struct eeh_pe *pe;
+
+	/* Allocate PHB PE */
+	pe = kzalloc(sizeof(struct eeh_pe), GFP_KERNEL);
+	if (!pe) return NULL;
+
+	/* Initialize PHB PE */
+	pe->type = type;
+	pe->phb = phb;
+	INIT_LIST_HEAD(&pe->child_list);
+	INIT_LIST_HEAD(&pe->child);
+	INIT_LIST_HEAD(&pe->edevs);
+
+	return pe;
+}
+
+/**
+ * eeh_phb_pe_create - Create PHB PE
+ * @phb: PCI controller
+ *
+ * The function should be called while the PHB is detected during
+ * system boot or PCI hotplug in order to create PHB PE.
+ */
+int eeh_phb_pe_create(struct pci_controller *phb)
+{
+	struct eeh_pe *pe;
+
+	/* Allocate PHB PE */
+	pe = eeh_pe_alloc(phb, EEH_PE_PHB);
+	if (!pe) {
+		pr_err("%s: out of memory!\n", __func__);
+		return -ENOMEM;
+	}
+
+	/* Put it into the list */
+	list_add_tail(&pe->child, &eeh_phb_pe);
+
+	pr_debug("EEH: Add PE for PHB#%d\n", phb->global_number);
+
+	return 0;
+}
+
+/**
+ * eeh_phb_pe_get - Retrieve PHB PE based on the given PHB
+ * @phb: PCI controller
+ *
+ * The overall PEs form hierarchy tree. The first layer of the
+ * hierarchy tree is composed of PHB PEs. The function is used
+ * to retrieve the corresponding PHB PE according to the given PHB.
+ */
+struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb)
+{
+	struct eeh_pe *pe;
+
+	list_for_each_entry(pe, &eeh_phb_pe, child) {
+		/*
+		 * Actually, we needn't check the type since
+		 * the PE for PHB has been determined when that
+		 * was created.
+		 */
+		if ((pe->type & EEH_PE_PHB) && pe->phb == phb)
+			return pe;
+	}
+
+	return NULL;
+}
+
+/**
+ * eeh_pe_next - Retrieve the next PE in the tree
+ * @pe: current PE
+ * @root: root PE
+ *
+ * The function is used to retrieve the next PE in the
+ * hierarchy PE tree.
+ */
+static struct eeh_pe *eeh_pe_next(struct eeh_pe *pe,
+				  struct eeh_pe *root)
+{
+	struct list_head *next = pe->child_list.next;
+
+	if (next == &pe->child_list) {
+		while (1) {
+			if (pe == root)
+				return NULL;
+			next = pe->child.next;
+			if (next != &pe->parent->child_list)
+				break;
+			pe = pe->parent;
+		}
+	}
+
+	return list_entry(next, struct eeh_pe, child);
+}
+
+/**
+ * eeh_pe_traverse - Traverse PEs in the specified PHB
+ * @root: root PE
+ * @fn: callback
+ * @flag: extra parameter to callback
+ *
+ * The function is used to traverse the specified PE and its
+ * child PEs. The traversing is to be terminated once the
+ * callback returns something other than NULL, or no more PEs
+ * to be traversed.
+ */
+void *eeh_pe_traverse(struct eeh_pe *root,
+		      eeh_traverse_func fn, void *flag)
+{
+	struct eeh_pe *pe;
+	void *ret;
+
+	for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
+		ret = fn(pe, flag);
+		if (ret) return ret;
+	}
+
+	return NULL;
+}
+
+/**
+ * eeh_pe_dev_traverse - Traverse the devices from the PE
+ * @root: EEH PE
+ * @fn: function callback
+ * @flag: extra parameter to callback
+ *
+ * The function is used to traverse the devices of the specified
+ * PE and its child PEs.
+ */
+void *eeh_pe_dev_traverse(struct eeh_pe *root,
+		eeh_traverse_func fn, void *flag)
+{
+	struct eeh_pe *pe;
+	struct eeh_dev *edev, *tmp;
+	void *ret;
+
+	if (!root) {
+		pr_warning("%s: Invalid PE %p\n", __func__, root);
+		return NULL;
+	}
+
+	/* Traverse root PE */
+	for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
+		eeh_pe_for_each_dev(pe, edev, tmp) {
+			ret = fn(edev, flag);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * __eeh_pe_get - Check the PE address
+ * @data: EEH PE
+ * @flag: EEH device
+ *
+ * For one particular PE, it can be identified by PE address
+ * or tranditional BDF address. BDF address is composed of
+ * Bus/Device/Function number. The extra data referred by flag
+ * indicates which type of address should be used.
+ */
+static void *__eeh_pe_get(void *data, void *flag)
+{
+	struct eeh_pe *pe = (struct eeh_pe *)data;
+	struct eeh_dev *edev = (struct eeh_dev *)flag;
+
+	/* Unexpected PHB PE */
+	if (pe->type & EEH_PE_PHB)
+		return NULL;
+
+	/* We prefer PE address */
+	if (edev->pe_config_addr &&
+	   (edev->pe_config_addr == pe->addr))
+		return pe;
+
+	/* Try BDF address */
+	if (edev->config_addr &&
+	   (edev->config_addr == pe->config_addr))
+		return pe;
+
+	return NULL;
+}
+
+/**
+ * eeh_pe_get - Search PE based on the given address
+ * @edev: EEH device
+ *
+ * Search the corresponding PE based on the specified address which
+ * is included in the eeh device. The function is used to check if
+ * the associated PE has been created against the PE address. It's
+ * notable that the PE address has 2 format: traditional PE address
+ * which is composed of PCI bus/device/function number, or unified
+ * PE address.
+ */
+struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
+{
+	struct eeh_pe *root = eeh_phb_pe_get(edev->phb);
+	struct eeh_pe *pe;
+
+	pe = eeh_pe_traverse(root, __eeh_pe_get, edev);
+
+	return pe;
+}
+
+/**
+ * eeh_pe_get_parent - Retrieve the parent PE
+ * @edev: EEH device
+ *
+ * The whole PEs existing in the system are organized as hierarchy
+ * tree. The function is used to retrieve the parent PE according
+ * to the parent EEH device.
+ */
+static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
+{
+	struct device_node *dn;
+	struct eeh_dev *parent;
+
+	/*
+	 * It might have the case for the indirect parent
+	 * EEH device already having associated PE, but
+	 * the direct parent EEH device doesn't have yet.
+	 */
+	dn = edev->dn->parent;
+	while (dn) {
+		/* We're poking out of PCI territory */
+		if (!PCI_DN(dn)) return NULL;
+
+		parent = of_node_to_eeh_dev(dn);
+		/* We're poking out of PCI territory */
+		if (!parent) return NULL;
+
+		if (parent->pe)
+			return parent->pe;
+
+		dn = dn->parent;
+	}
+
+	return NULL;
+}
+
+/**
+ * eeh_add_to_parent_pe - Add EEH device to parent PE
+ * @edev: EEH device
+ *
+ * Add EEH device to the parent PE. If the parent PE already
+ * exists, the PE type will be changed to EEH_PE_BUS. Otherwise,
+ * we have to create new PE to hold the EEH device and the new
+ * PE will be linked to its parent PE as well.
+ */
+int eeh_add_to_parent_pe(struct eeh_dev *edev)
+{
+	struct eeh_pe *pe, *parent;
+
+	/*
+	 * Search the PE has been existing or not according
+	 * to the PE address. If that has been existing, the
+	 * PE should be composed of PCI bus and its subordinate
+	 * components.
+	 */
+	pe = eeh_pe_get(edev);
+	if (pe && !(pe->type & EEH_PE_INVALID)) {
+		if (!edev->pe_config_addr) {
+			pr_err("%s: PE with addr 0x%x already exists\n",
+				__func__, edev->config_addr);
+			return -EEXIST;
+		}
+
+		/* Mark the PE as type of PCI bus */
+		pe->type = EEH_PE_BUS;
+		edev->pe = pe;
+
+		/* Put the edev to PE */
+		list_add_tail(&edev->list, &pe->edevs);
+		pr_debug("EEH: Add %s to Bus PE#%x\n",
+			edev->dn->full_name, pe->addr);
+
+		return 0;
+	} else if (pe && (pe->type & EEH_PE_INVALID)) {
+		list_add_tail(&edev->list, &pe->edevs);
+		edev->pe = pe;
+		/*
+		 * We're running to here because of PCI hotplug caused by
+		 * EEH recovery. We need clear EEH_PE_INVALID until the top.
+		 */
+		parent = pe;
+		while (parent) {
+			if (!(parent->type & EEH_PE_INVALID))
+				break;
+			parent->type &= ~(EEH_PE_INVALID | EEH_PE_KEEP);
+			parent = parent->parent;
+		}
+		pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
+			edev->dn->full_name, pe->addr, pe->parent->addr);
+
+		return 0;
+	}
+
+	/* Create a new EEH PE */
+	pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
+	if (!pe) {
+		pr_err("%s: out of memory!\n", __func__);
+		return -ENOMEM;
+	}
+	pe->addr	= edev->pe_config_addr;
+	pe->config_addr	= edev->config_addr;
+
+	/*
+	 * While doing PE reset, we probably hot-reset the
+	 * upstream bridge. However, the PCI devices including
+	 * the associated EEH devices might be removed when EEH
+	 * core is doing recovery. So that won't safe to retrieve
+	 * the bridge through downstream EEH device. We have to
+	 * trace the parent PCI bus, then the upstream bridge.
+	 */
+	if (eeh_probe_mode_dev())
+		pe->bus = eeh_dev_to_pci_dev(edev)->bus;
+
+	/*
+	 * Put the new EEH PE into hierarchy tree. If the parent
+	 * can't be found, the newly created PE will be attached
+	 * to PHB directly. Otherwise, we have to associate the
+	 * PE with its parent.
+	 */
+	parent = eeh_pe_get_parent(edev);
+	if (!parent) {
+		parent = eeh_phb_pe_get(edev->phb);
+		if (!parent) {
+			pr_err("%s: No PHB PE is found (PHB Domain=%d)\n",
+				__func__, edev->phb->global_number);
+			edev->pe = NULL;
+			kfree(pe);
+			return -EEXIST;
+		}
+	}
+	pe->parent = parent;
+
+	/*
+	 * Put the newly created PE into the child list and
+	 * link the EEH device accordingly.
+	 */
+	list_add_tail(&pe->child, &parent->child_list);
+	list_add_tail(&edev->list, &pe->edevs);
+	edev->pe = pe;
+	pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
+		edev->dn->full_name, pe->addr, pe->parent->addr);
+
+	return 0;
+}
+
+/**
+ * eeh_rmv_from_parent_pe - Remove one EEH device from the associated PE
+ * @edev: EEH device
+ *
+ * The PE hierarchy tree might be changed when doing PCI hotplug.
+ * Also, the PCI devices or buses could be removed from the system
+ * during EEH recovery. So we have to call the function remove the
+ * corresponding PE accordingly if necessary.
+ */
+int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
+{
+	struct eeh_pe *pe, *parent, *child;
+	int cnt;
+
+	if (!edev->pe) {
+		pr_debug("%s: No PE found for EEH device %s\n",
+			 __func__, edev->dn->full_name);
+		return -EEXIST;
+	}
+
+	/* Remove the EEH device */
+	pe = edev->pe;
+	edev->pe = NULL;
+	list_del(&edev->list);
+
+	/*
+	 * Check if the parent PE includes any EEH devices.
+	 * If not, we should delete that. Also, we should
+	 * delete the parent PE if it doesn't have associated
+	 * child PEs and EEH devices.
+	 */
+	while (1) {
+		parent = pe->parent;
+		if (pe->type & EEH_PE_PHB)
+			break;
+
+		if (!(pe->state & EEH_PE_KEEP)) {
+			if (list_empty(&pe->edevs) &&
+			    list_empty(&pe->child_list)) {
+				list_del(&pe->child);
+				kfree(pe);
+			} else {
+				break;
+			}
+		} else {
+			if (list_empty(&pe->edevs)) {
+				cnt = 0;
+				list_for_each_entry(child, &pe->child_list, child) {
+					if (!(child->type & EEH_PE_INVALID)) {
+						cnt++;
+						break;
+					}
+				}
+
+				if (!cnt)
+					pe->type |= EEH_PE_INVALID;
+				else
+					break;
+			}
+		}
+
+		pe = parent;
+	}
+
+	return 0;
+}
+
+/**
+ * eeh_pe_update_time_stamp - Update PE's frozen time stamp
+ * @pe: EEH PE
+ *
+ * We have time stamp for each PE to trace its time of getting
+ * frozen in last hour. The function should be called to update
+ * the time stamp on first error of the specific PE. On the other
+ * handle, we needn't account for errors happened in last hour.
+ */
+void eeh_pe_update_time_stamp(struct eeh_pe *pe)
+{
+	struct timeval tstamp;
+
+	if (!pe) return;
+
+	if (pe->freeze_count <= 0) {
+		pe->freeze_count = 0;
+		do_gettimeofday(&pe->tstamp);
+	} else {
+		do_gettimeofday(&tstamp);
+		if (tstamp.tv_sec - pe->tstamp.tv_sec > 3600) {
+			pe->tstamp = tstamp;
+			pe->freeze_count = 0;
+		}
+	}
+}
+
+/**
+ * __eeh_pe_state_mark - Mark the state for the PE
+ * @data: EEH PE
+ * @flag: state
+ *
+ * The function is used to mark the indicated state for the given
+ * PE. Also, the associated PCI devices will be put into IO frozen
+ * state as well.
+ */
+static void *__eeh_pe_state_mark(void *data, void *flag)
+{
+	struct eeh_pe *pe = (struct eeh_pe *)data;
+	int state = *((int *)flag);
+	struct eeh_dev *edev, *tmp;
+	struct pci_dev *pdev;
+
+	/*
+	 * Mark the PE with the indicated state. Also,
+	 * the associated PCI device will be put into
+	 * I/O frozen state to avoid I/O accesses from
+	 * the PCI device driver.
+	 */
+	pe->state |= state;
+	eeh_pe_for_each_dev(pe, edev, tmp) {
+		pdev = eeh_dev_to_pci_dev(edev);
+		if (pdev)
+			pdev->error_state = pci_channel_io_frozen;
+	}
+
+	return NULL;
+}
+
+/**
+ * eeh_pe_state_mark - Mark specified state for PE and its associated device
+ * @pe: EEH PE
+ *
+ * EEH error affects the current PE and its child PEs. The function
+ * is used to mark appropriate state for the affected PEs and the
+ * associated devices.
+ */
+void eeh_pe_state_mark(struct eeh_pe *pe, int state)
+{
+	eeh_pe_traverse(pe, __eeh_pe_state_mark, &state);
+}
+
+/**
+ * __eeh_pe_state_clear - Clear state for the PE
+ * @data: EEH PE
+ * @flag: state
+ *
+ * The function is used to clear the indicated state from the
+ * given PE. Besides, we also clear the check count of the PE
+ * as well.
+ */
+static void *__eeh_pe_state_clear(void *data, void *flag)
+{
+	struct eeh_pe *pe = (struct eeh_pe *)data;
+	int state = *((int *)flag);
+
+	pe->state &= ~state;
+	pe->check_count = 0;
+
+	return NULL;
+}
+
+/**
+ * eeh_pe_state_clear - Clear state for the PE and its children
+ * @pe: PE
+ * @state: state to be cleared
+ *
+ * When the PE and its children has been recovered from error,
+ * we need clear the error state for that. The function is used
+ * for the purpose.
+ */
+void eeh_pe_state_clear(struct eeh_pe *pe, int state)
+{
+	eeh_pe_traverse(pe, __eeh_pe_state_clear, &state);
+}
+
+/*
+ * Some PCI bridges (e.g. PLX bridges) have primary/secondary
+ * buses assigned explicitly by firmware, and we probably have
+ * lost that after reset. So we have to delay the check until
+ * the PCI-CFG registers have been restored for the parent
+ * bridge.
+ *
+ * Don't use normal PCI-CFG accessors, which probably has been
+ * blocked on normal path during the stage. So we need utilize
+ * eeh operations, which is always permitted.
+ */
+static void eeh_bridge_check_link(struct eeh_dev *edev,
+				  struct device_node *dn)
+{
+	int cap;
+	uint32_t val;
+	int timeout = 0;
+
+	/*
+	 * We only check root port and downstream ports of
+	 * PCIe switches
+	 */
+	if (!(edev->mode & (EEH_DEV_ROOT_PORT | EEH_DEV_DS_PORT)))
+		return;
+
+	pr_debug("%s: Check PCIe link for %04x:%02x:%02x.%01x ...\n",
+		 __func__, edev->phb->global_number,
+		 edev->config_addr >> 8,
+		 PCI_SLOT(edev->config_addr & 0xFF),
+		 PCI_FUNC(edev->config_addr & 0xFF));
+
+	/* Check slot status */
+	cap = edev->pcie_cap;
+	eeh_ops->read_config(dn, cap + PCI_EXP_SLTSTA, 2, &val);
+	if (!(val & PCI_EXP_SLTSTA_PDS)) {
+		pr_debug("  No card in the slot (0x%04x) !\n", val);
+		return;
+	}
+
+	/* Check power status if we have the capability */
+	eeh_ops->read_config(dn, cap + PCI_EXP_SLTCAP, 2, &val);
+	if (val & PCI_EXP_SLTCAP_PCP) {
+		eeh_ops->read_config(dn, cap + PCI_EXP_SLTCTL, 2, &val);
+		if (val & PCI_EXP_SLTCTL_PCC) {
+			pr_debug("  In power-off state, power it on ...\n");
+			val &= ~(PCI_EXP_SLTCTL_PCC | PCI_EXP_SLTCTL_PIC);
+			val |= (0x0100 & PCI_EXP_SLTCTL_PIC);
+			eeh_ops->write_config(dn, cap + PCI_EXP_SLTCTL, 2, val);
+			msleep(2 * 1000);
+		}
+	}
+
+	/* Enable link */
+	eeh_ops->read_config(dn, cap + PCI_EXP_LNKCTL, 2, &val);
+	val &= ~PCI_EXP_LNKCTL_LD;
+	eeh_ops->write_config(dn, cap + PCI_EXP_LNKCTL, 2, val);
+
+	/* Check link */
+	eeh_ops->read_config(dn, cap + PCI_EXP_LNKCAP, 4, &val);
+	if (!(val & PCI_EXP_LNKCAP_DLLLARC)) {
+		pr_debug("  No link reporting capability (0x%08x) \n", val);
+		msleep(1000);
+		return;
+	}
+
+	/* Wait the link is up until timeout (5s) */
+	timeout = 0;
+	while (timeout < 5000) {
+		msleep(20);
+		timeout += 20;
+
+		eeh_ops->read_config(dn, cap + PCI_EXP_LNKSTA, 2, &val);
+		if (val & PCI_EXP_LNKSTA_DLLLA)
+			break;
+	}
+
+	if (val & PCI_EXP_LNKSTA_DLLLA)
+		pr_debug("  Link up (%s)\n",
+			 (val & PCI_EXP_LNKSTA_CLS_2_5GB) ? "2.5GB" : "5GB");
+	else
+		pr_debug("  Link not ready (0x%04x)\n", val);
+}
+
+#define BYTE_SWAP(OFF)	(8*((OFF)/4)+3-(OFF))
+#define SAVED_BYTE(OFF)	(((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])
+
+static void eeh_restore_bridge_bars(struct eeh_dev *edev,
+				    struct device_node *dn)
+{
+	int i;
+
+	/*
+	 * Device BARs: 0x10 - 0x18
+	 * Bus numbers and windows: 0x18 - 0x30
+	 */
+	for (i = 4; i < 13; i++)
+		eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]);
+	/* Rom: 0x38 */
+	eeh_ops->write_config(dn, 14*4, 4, edev->config_space[14]);
+
+	/* Cache line & Latency timer: 0xC 0xD */
+	eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1,
+                SAVED_BYTE(PCI_CACHE_LINE_SIZE));
+        eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1,
+                SAVED_BYTE(PCI_LATENCY_TIMER));
+	/* Max latency, min grant, interrupt ping and line: 0x3C */
+	eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]);
+
+	/* PCI Command: 0x4 */
+	eeh_ops->write_config(dn, PCI_COMMAND, 4, edev->config_space[1]);
+
+	/* Check the PCIe link is ready */
+	eeh_bridge_check_link(edev, dn);
+}
+
+static void eeh_restore_device_bars(struct eeh_dev *edev,
+				    struct device_node *dn)
+{
+	int i;
+	u32 cmd;
+
+	for (i = 4; i < 10; i++)
+		eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]);
+	/* 12 == Expansion ROM Address */
+	eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]);
+
+	eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1,
+		SAVED_BYTE(PCI_CACHE_LINE_SIZE));
+	eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1,
+		SAVED_BYTE(PCI_LATENCY_TIMER));
+
+	/* max latency, min grant, interrupt pin and line */
+	eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]);
+
+	/*
+	 * Restore PERR & SERR bits, some devices require it,
+	 * don't touch the other command bits
+	 */
+	eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd);
+	if (edev->config_space[1] & PCI_COMMAND_PARITY)
+		cmd |= PCI_COMMAND_PARITY;
+	else
+		cmd &= ~PCI_COMMAND_PARITY;
+	if (edev->config_space[1] & PCI_COMMAND_SERR)
+		cmd |= PCI_COMMAND_SERR;
+	else
+		cmd &= ~PCI_COMMAND_SERR;
+	eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd);
+}
+
+/**
+ * eeh_restore_one_device_bars - Restore the Base Address Registers for one device
+ * @data: EEH device
+ * @flag: Unused
+ *
+ * Loads the PCI configuration space base address registers,
+ * the expansion ROM base address, the latency timer, and etc.
+ * from the saved values in the device node.
+ */
+static void *eeh_restore_one_device_bars(void *data, void *flag)
+{
+	struct eeh_dev *edev = (struct eeh_dev *)data;
+	struct device_node *dn = eeh_dev_to_of_node(edev);
+
+	/* Do special restore for bridges */
+	if (edev->mode & EEH_DEV_BRIDGE)
+		eeh_restore_bridge_bars(edev, dn);
+	else
+		eeh_restore_device_bars(edev, dn);
+
+	return NULL;
+}
+
+/**
+ * eeh_pe_restore_bars - Restore the PCI config space info
+ * @pe: EEH PE
+ *
+ * This routine performs a recursive walk to the children
+ * of this device as well.
+ */
+void eeh_pe_restore_bars(struct eeh_pe *pe)
+{
+	/*
+	 * We needn't take the EEH lock since eeh_pe_dev_traverse()
+	 * will take that.
+	 */
+	eeh_pe_dev_traverse(pe, eeh_restore_one_device_bars, NULL);
+}
+
+/**
+ * eeh_pe_bus_get - Retrieve PCI bus according to the given PE
+ * @pe: EEH PE
+ *
+ * Retrieve the PCI bus according to the given PE. Basically,
+ * there're 3 types of PEs: PHB/Bus/Device. For PHB PE, the
+ * primary PCI bus will be retrieved. The parent bus will be
+ * returned for BUS PE. However, we don't have associated PCI
+ * bus for DEVICE PE.
+ */
+struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
+{
+	struct pci_bus *bus = NULL;
+	struct eeh_dev *edev;
+	struct pci_dev *pdev;
+
+	if (pe->type & EEH_PE_PHB) {
+		bus = pe->phb->bus;
+	} else if (pe->type & EEH_PE_BUS ||
+		   pe->type & EEH_PE_DEVICE) {
+		if (pe->bus) {
+			bus = pe->bus;
+			goto out;
+		}
+
+		edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
+		pdev = eeh_dev_to_pci_dev(edev);
+		if (pdev)
+			bus = pdev->bus;
+	}
+
+out:
+	return bus;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_sysfs.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_sysfs.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/eeh_sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/eeh_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * Sysfs entries for PCI Error Recovery for PAPR-compliant platform.
+ * Copyright IBM Corporation 2007
+ * Copyright Linas Vepstas <linas@austin.ibm.com> 2007
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
+ */
+#include <linux/pci.h>
+#include <linux/stat.h>
+#include <asm/ppc-pci.h>
+#include <asm/pci-bridge.h>
+
+/**
+ * EEH_SHOW_ATTR -- Create sysfs entry for eeh statistic
+ * @_name: name of file in sysfs directory
+ * @_memb: name of member in struct pci_dn to access
+ * @_format: printf format for display
+ *
+ * All of the attributes look very similar, so just
+ * auto-gen a cut-n-paste routine to display them.
+ */
+#define EEH_SHOW_ATTR(_name,_memb,_format)               \
+static ssize_t eeh_show_##_name(struct device *dev,      \
+		struct device_attribute *attr, char *buf)          \
+{                                                        \
+	struct pci_dev *pdev = to_pci_dev(dev);               \
+	struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);      \
+	                                                      \
+	if (!edev)                                            \
+		return 0;                                     \
+	                                                      \
+	return sprintf(buf, _format "\n", edev->_memb);       \
+}                                                        \
+static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL);
+
+EEH_SHOW_ATTR(eeh_mode,            mode,            "0x%x");
+EEH_SHOW_ATTR(eeh_config_addr,     config_addr,     "0x%x");
+EEH_SHOW_ATTR(eeh_pe_config_addr,  pe_config_addr,  "0x%x");
+
+void eeh_sysfs_add_device(struct pci_dev *pdev)
+{
+	struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
+	int rc=0;
+
+	if (edev && (edev->mode & EEH_DEV_SYSFS))
+		return;
+
+	rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode);
+	rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr);
+	rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
+
+	if (rc)
+		printk(KERN_WARNING "EEH: Unable to create sysfs entries\n");
+	else if (edev)
+		edev->mode |= EEH_DEV_SYSFS;
+}
+
+void eeh_sysfs_remove_device(struct pci_dev *pdev)
+{
+	struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
+
+	/*
+	 * The parent directory might have been removed. We needn't
+	 * continue for that case.
+	 */
+	if (!pdev->dev.kobj.sd) {
+		if (edev)
+			edev->mode &= ~EEH_DEV_SYSFS;
+		return;
+	}
+
+	device_remove_file(&pdev->dev, &dev_attr_eeh_mode);
+	device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr);
+	device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
+
+	if (edev)
+		edev->mode &= ~EEH_DEV_SYSFS;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/entry_64.S linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/entry_64.S
--- linux-libre-3.10-gnu/arch/powerpc/kernel/entry_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/entry_64.S	2013-08-25 20:43:22.000000000 -0400
@@ -449,15 +449,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_DSCR)
 
 #ifdef CONFIG_PPC_BOOK3S_64
 BEGIN_FTR_SECTION
-	/*
-	 * Back up the TAR across context switches.  Note that the TAR is not
-	 * available for use in the kernel.  (To provide this, the TAR should
-	 * be backed up/restored on exception entry/exit instead, and be in
-	 * pt_regs.  FIXME, this should be in pt_regs anyway (for debug).)
-	 */
-	mfspr	r0,SPRN_TAR
-	std	r0,THREAD_TAR(r3)
-
 	/* Event based branch registers */
 	mfspr	r0, SPRN_BESCR
 	std	r0, THREAD_BESCR(r3)
@@ -584,9 +575,34 @@ BEGIN_FTR_SECTION
 	ld	r7,DSCR_DEFAULT@toc(2)
 	ld	r0,THREAD_DSCR(r4)
 	cmpwi	r6,0
+	li	r8, FSCR_DSCR
 	bne	1f
 	ld	r0,0(r7)
-1:	cmpd	r0,r25
+	b	3f
+1:
+  BEGIN_FTR_SECTION_NESTED(70)
+	mfspr	r6, SPRN_FSCR
+	or	r6, r6, r8
+	mtspr	SPRN_FSCR, r6
+    BEGIN_FTR_SECTION_NESTED(69)
+	mfspr	r6, SPRN_HFSCR
+	or	r6, r6, r8
+	mtspr	SPRN_HFSCR, r6
+    END_FTR_SECTION_NESTED(CPU_FTR_HVMODE, CPU_FTR_HVMODE, 69)
+	b	4f
+  END_FTR_SECTION_NESTED(CPU_FTR_ARCH_207S, CPU_FTR_ARCH_207S, 70)
+3:
+  BEGIN_FTR_SECTION_NESTED(70)
+	mfspr	r6, SPRN_FSCR
+	andc	r6, r6, r8
+	mtspr	SPRN_FSCR, r6
+    BEGIN_FTR_SECTION_NESTED(69)
+	mfspr	r6, SPRN_HFSCR
+	andc	r6, r6, r8
+	mtspr	SPRN_HFSCR, r6
+    END_FTR_SECTION_NESTED(CPU_FTR_HVMODE, CPU_FTR_HVMODE, 69)
+  END_FTR_SECTION_NESTED(CPU_FTR_ARCH_207S, CPU_FTR_ARCH_207S, 70)
+4:	cmpd	r0,r25
 	beq	2f
 	mtspr	SPRN_DSCR,r0
 2:
@@ -629,21 +645,43 @@ _GLOBAL(ret_from_except_lite)
 
 	CURRENT_THREAD_INFO(r9, r1)
 	ld	r3,_MSR(r1)
+#ifdef CONFIG_PPC_BOOK3E
+	ld	r10,PACACURRENT(r13)
+#endif /* CONFIG_PPC_BOOK3E */
 	ld	r4,TI_FLAGS(r9)
 	andi.	r3,r3,MSR_PR
 	beq	resume_kernel
+#ifdef CONFIG_PPC_BOOK3E
+	lwz	r3,(THREAD+THREAD_DBCR0)(r10)
+#endif /* CONFIG_PPC_BOOK3E */
 
 	/* Check current_thread_info()->flags */
 	andi.	r0,r4,_TIF_USER_WORK_MASK
+#ifdef CONFIG_PPC_BOOK3E
+	bne	1f
+	/*
+	 * Check to see if the dbcr0 register is set up to debug.
+	 * Use the internal debug mode bit to do this.
+	 */
+	andis.	r0,r3,DBCR0_IDM@h
 	beq	restore
-
-	andi.	r0,r4,_TIF_NEED_RESCHED
-	beq	1f
+	mfmsr	r0
+	rlwinm	r0,r0,0,~MSR_DE	/* Clear MSR.DE */
+	mtmsr	r0
+	mtspr	SPRN_DBCR0,r3
+	li	r10, -1
+	mtspr	SPRN_DBSR,r10
+	b	restore
+#else
+	beq	restore
+#endif
+1:	andi.	r0,r4,_TIF_NEED_RESCHED
+	beq	2f
 	bl	.restore_interrupts
 	SCHEDULE_USER
 	b	.ret_from_except_lite
 
-1:	bl	.save_nvgprs
+2:	bl	.save_nvgprs
 	bl	.restore_interrupts
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_notify_resume
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/exceptions-64s.S linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/exceptions-64s.S
--- linux-libre-3.10-gnu/arch/powerpc/kernel/exceptions-64s.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/exceptions-64s.S	2013-08-25 20:43:22.000000000 -0400
@@ -341,10 +341,17 @@ vsx_unavailable_pSeries_1:
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	vsx_unavailable_pSeries
 
+facility_unavailable_trampoline:
 	. = 0xf60
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
-	b	tm_unavailable_pSeries
+	b	facility_unavailable_pSeries
+
+hv_facility_unavailable_trampoline:
+	. = 0xf80
+	SET_SCRATCH0(r13)
+	EXCEPTION_PROLOG_0(PACA_EXGEN)
+	b	facility_unavailable_hv
 
 #ifdef CONFIG_CBE_RAS
 	STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
@@ -522,8 +529,10 @@ denorm_done:
 	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf20)
 	STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
 	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40)
-	STD_EXCEPTION_PSERIES_OOL(0xf60, tm_unavailable)
+	STD_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
 	KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf60)
+	STD_EXCEPTION_HV_OOL(0xf82, facility_unavailable)
+	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xf82)
 
 /*
  * An interrupt came in while soft-disabled. We set paca->irq_happened, then:
@@ -793,14 +802,10 @@ system_call_relon_pSeries:
 	STD_RELON_EXCEPTION_PSERIES(0x4d00, 0xd00, single_step)
 
 	. = 0x4e00
-	SET_SCRATCH0(r13)
-	EXCEPTION_PROLOG_0(PACA_EXGEN)
-	b	h_data_storage_relon_hv
+	b	.	/* Can't happen, see v2.07 Book III-S section 6.5 */
 
 	. = 0x4e20
-	SET_SCRATCH0(r13)
-	EXCEPTION_PROLOG_0(PACA_EXGEN)
-	b	h_instr_storage_relon_hv
+	b	.	/* Can't happen, see v2.07 Book III-S section 6.5 */
 
 	. = 0x4e40
 	SET_SCRATCH0(r13)
@@ -808,9 +813,7 @@ system_call_relon_pSeries:
 	b	emulation_assist_relon_hv
 
 	. = 0x4e60
-	SET_SCRATCH0(r13)
-	EXCEPTION_PROLOG_0(PACA_EXGEN)
-	b	hmi_exception_relon_hv
+	b	.	/* Can't happen, see v2.07 Book III-S section 6.5 */
 
 	. = 0x4e80
 	SET_SCRATCH0(r13)
@@ -835,11 +838,17 @@ vsx_unavailable_relon_pSeries_1:
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	vsx_unavailable_relon_pSeries
 
-tm_unavailable_relon_pSeries_1:
+facility_unavailable_relon_trampoline:
 	. = 0x4f60
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
-	b	tm_unavailable_relon_pSeries
+	b	facility_unavailable_relon_pSeries
+
+hv_facility_unavailable_relon_trampoline:
+	. = 0x4f80
+	SET_SCRATCH0(r13)
+	EXCEPTION_PROLOG_0(PACA_EXGEN)
+	b	hv_facility_unavailable_relon_hv
 
 	STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint)
 #ifdef CONFIG_PPC_DENORMALISATION
@@ -1165,36 +1174,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
 	bl	.vsx_unavailable_exception
 	b	.ret_from_except
 
-	.align	7
-	.globl tm_unavailable_common
-tm_unavailable_common:
-	EXCEPTION_PROLOG_COMMON(0xf60, PACA_EXGEN)
-	bl	.save_nvgprs
-	DISABLE_INTS
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.tm_unavailable_exception
-	b	.ret_from_except
+	STD_EXCEPTION_COMMON(0xf60, facility_unavailable, .facility_unavailable_exception)
+	STD_EXCEPTION_COMMON(0xf80, hv_facility_unavailable, .facility_unavailable_exception)
 
 	.align	7
 	.globl	__end_handlers
 __end_handlers:
 
 	/* Equivalents to the above handlers for relocation-on interrupt vectors */
-	STD_RELON_EXCEPTION_HV_OOL(0xe00, h_data_storage)
-	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe00)
-	STD_RELON_EXCEPTION_HV_OOL(0xe20, h_instr_storage)
-	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe20)
 	STD_RELON_EXCEPTION_HV_OOL(0xe40, emulation_assist)
-	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe40)
-	STD_RELON_EXCEPTION_HV_OOL(0xe60, hmi_exception)
-	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe60)
 	MASKABLE_RELON_EXCEPTION_HV_OOL(0xe80, h_doorbell)
-	KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe80)
 
 	STD_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
 	STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
 	STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
-	STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, tm_unavailable)
+	STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
+	STD_RELON_EXCEPTION_HV_OOL(0xf80, hv_facility_unavailable)
 
 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/hw_breakpoint.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/hw_breakpoint.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/hw_breakpoint.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/hw_breakpoint.c	2013-08-25 20:43:22.000000000 -0400
@@ -176,7 +176,7 @@ int arch_validate_hwbkpt_settings(struct
 		length_max = 512 ; /* 64 doublewords */
 		/* DAWR region can't cross 512 boundary */
 		if ((bp->attr.bp_addr >> 10) != 
-		    ((bp->attr.bp_addr + bp->attr.bp_len) >> 10))
+		    ((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 10))
 			return -EINVAL;
 	}
 	if (info->len >
@@ -250,6 +250,7 @@ int __kprobes hw_breakpoint_handler(stru
 	 * we still need to single-step the instruction, but we don't
 	 * generate an event.
 	 */
+	info->type &= ~HW_BRK_TYPE_EXTRANEOUS_IRQ;
 	if (!((bp->attr.bp_addr <= dar) &&
 	      (dar - bp->attr.bp_addr < bp->attr.bp_len)))
 		info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/ibmebus.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/ibmebus.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/ibmebus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/ibmebus.c	2013-08-25 20:43:22.000000000 -0400
@@ -205,7 +205,7 @@ static int ibmebus_create_devices(const
 	return ret;
 }
 
-int ibmebus_register_driver(struct of_platform_driver *drv)
+int ibmebus_register_driver(struct platform_driver *drv)
 {
 	/* If the driver uses devices that ibmebus doesn't know, add them */
 	ibmebus_create_devices(drv->driver.of_match_table);
@@ -215,7 +215,7 @@ int ibmebus_register_driver(struct of_pl
 }
 EXPORT_SYMBOL(ibmebus_register_driver);
 
-void ibmebus_unregister_driver(struct of_platform_driver *drv)
+void ibmebus_unregister_driver(struct platform_driver *drv)
 {
 	driver_unregister(&drv->driver);
 }
@@ -338,11 +338,10 @@ static int ibmebus_bus_bus_match(struct
 static int ibmebus_bus_device_probe(struct device *dev)
 {
 	int error = -ENODEV;
-	struct of_platform_driver *drv;
+	struct platform_driver *drv;
 	struct platform_device *of_dev;
-	const struct of_device_id *match;
 
-	drv = to_of_platform_driver(dev->driver);
+	drv = to_platform_driver(dev->driver);
 	of_dev = to_platform_device(dev);
 
 	if (!drv->probe)
@@ -350,9 +349,8 @@ static int ibmebus_bus_device_probe(stru
 
 	of_dev_get(of_dev);
 
-	match = of_match_device(drv->driver.of_match_table, dev);
-	if (match)
-		error = drv->probe(of_dev, match);
+	if (of_driver_match_device(dev, dev->driver))
+		error = drv->probe(of_dev);
 	if (error)
 		of_dev_put(of_dev);
 
@@ -362,7 +360,7 @@ static int ibmebus_bus_device_probe(stru
 static int ibmebus_bus_device_remove(struct device *dev)
 {
 	struct platform_device *of_dev = to_platform_device(dev);
-	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 
 	if (dev->driver && drv->remove)
 		drv->remove(of_dev);
@@ -372,7 +370,7 @@ static int ibmebus_bus_device_remove(str
 static void ibmebus_bus_device_shutdown(struct device *dev)
 {
 	struct platform_device *of_dev = to_platform_device(dev);
-	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 
 	if (dev->driver && drv->shutdown)
 		drv->shutdown(of_dev);
@@ -419,7 +417,7 @@ struct device_attribute ibmebus_bus_devi
 static int ibmebus_bus_legacy_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct platform_device *of_dev = to_platform_device(dev);
-	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 	int ret = 0;
 
 	if (dev->driver && drv->suspend)
@@ -430,7 +428,7 @@ static int ibmebus_bus_legacy_suspend(st
 static int ibmebus_bus_legacy_resume(struct device *dev)
 {
 	struct platform_device *of_dev = to_platform_device(dev);
-	struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+	struct platform_driver *drv = to_platform_driver(dev->driver);
 	int ret = 0;
 
 	if (dev->driver && drv->resume)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/idle.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/idle.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/idle.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/idle.c	2013-08-25 20:43:22.000000000 -0400
@@ -85,7 +85,7 @@ int powersave_nap;
 /*
  * Register the sysctl to set/clear powersave_nap.
  */
-static ctl_table powersave_nap_ctl_table[]={
+static struct ctl_table powersave_nap_ctl_table[] = {
 	{
 		.procname	= "powersave-nap",
 		.data		= &powersave_nap,
@@ -95,7 +95,7 @@ static ctl_table powersave_nap_ctl_table
 	},
 	{}
 };
-static ctl_table powersave_nap_sysctl_root[] = {
+static struct ctl_table powersave_nap_sysctl_root[] = {
 	{
 		.procname	= "kernel",
 		.mode		= 0555,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/iommu.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/iommu.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/iommu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/iommu.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,8 @@
 #include <linux/hash.h>
 #include <linux/fault-inject.h>
 #include <linux/pci.h>
+#include <linux/iommu.h>
+#include <linux/sched.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/iommu.h>
@@ -44,6 +46,7 @@
 #include <asm/kdump.h>
 #include <asm/fadump.h>
 #include <asm/vio.h>
+#include <asm/tce.h>
 
 #define DBG(...)
 
@@ -724,6 +727,13 @@ void iommu_free_table(struct iommu_table
 	if (tbl->it_offset == 0)
 		clear_bit(0, tbl->it_map);
 
+#ifdef CONFIG_IOMMU_API
+	if (tbl->it_group) {
+		iommu_group_put(tbl->it_group);
+		BUG_ON(tbl->it_group);
+	}
+#endif
+
 	/* verify that table contains no entries */
 	if (!bitmap_empty(tbl->it_map, tbl->it_size))
 		pr_warn("%s: Unexpected TCEs for %s\n", __func__, node_name);
@@ -860,3 +870,316 @@ void iommu_free_coherent(struct iommu_ta
 		free_pages((unsigned long)vaddr, get_order(size));
 	}
 }
+
+#ifdef CONFIG_IOMMU_API
+/*
+ * SPAPR TCE API
+ */
+static void group_release(void *iommu_data)
+{
+	struct iommu_table *tbl = iommu_data;
+	tbl->it_group = NULL;
+}
+
+void iommu_register_group(struct iommu_table *tbl,
+		int pci_domain_number, unsigned long pe_num)
+{
+	struct iommu_group *grp;
+	char *name;
+
+	grp = iommu_group_alloc();
+	if (IS_ERR(grp)) {
+		pr_warn("powerpc iommu api: cannot create new group, err=%ld\n",
+				PTR_ERR(grp));
+		return;
+	}
+	tbl->it_group = grp;
+	iommu_group_set_iommudata(grp, tbl, group_release);
+	name = kasprintf(GFP_KERNEL, "domain%d-pe%lx",
+			pci_domain_number, pe_num);
+	if (!name)
+		return;
+	iommu_group_set_name(grp, name);
+	kfree(name);
+}
+
+enum dma_data_direction iommu_tce_direction(unsigned long tce)
+{
+	if ((tce & TCE_PCI_READ) && (tce & TCE_PCI_WRITE))
+		return DMA_BIDIRECTIONAL;
+	else if (tce & TCE_PCI_READ)
+		return DMA_TO_DEVICE;
+	else if (tce & TCE_PCI_WRITE)
+		return DMA_FROM_DEVICE;
+	else
+		return DMA_NONE;
+}
+EXPORT_SYMBOL_GPL(iommu_tce_direction);
+
+void iommu_flush_tce(struct iommu_table *tbl)
+{
+	/* Flush/invalidate TLB caches if necessary */
+	if (ppc_md.tce_flush)
+		ppc_md.tce_flush(tbl);
+
+	/* Make sure updates are seen by hardware */
+	mb();
+}
+EXPORT_SYMBOL_GPL(iommu_flush_tce);
+
+int iommu_tce_clear_param_check(struct iommu_table *tbl,
+		unsigned long ioba, unsigned long tce_value,
+		unsigned long npages)
+{
+	/* ppc_md.tce_free() does not support any value but 0 */
+	if (tce_value)
+		return -EINVAL;
+
+	if (ioba & ~IOMMU_PAGE_MASK)
+		return -EINVAL;
+
+	ioba >>= IOMMU_PAGE_SHIFT;
+	if (ioba < tbl->it_offset)
+		return -EINVAL;
+
+	if ((ioba + npages) > (tbl->it_offset + tbl->it_size))
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_tce_clear_param_check);
+
+int iommu_tce_put_param_check(struct iommu_table *tbl,
+		unsigned long ioba, unsigned long tce)
+{
+	if (!(tce & (TCE_PCI_WRITE | TCE_PCI_READ)))
+		return -EINVAL;
+
+	if (tce & ~(IOMMU_PAGE_MASK | TCE_PCI_WRITE | TCE_PCI_READ))
+		return -EINVAL;
+
+	if (ioba & ~IOMMU_PAGE_MASK)
+		return -EINVAL;
+
+	ioba >>= IOMMU_PAGE_SHIFT;
+	if (ioba < tbl->it_offset)
+		return -EINVAL;
+
+	if ((ioba + 1) > (tbl->it_offset + tbl->it_size))
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_tce_put_param_check);
+
+unsigned long iommu_clear_tce(struct iommu_table *tbl, unsigned long entry)
+{
+	unsigned long oldtce;
+	struct iommu_pool *pool = get_pool(tbl, entry);
+
+	spin_lock(&(pool->lock));
+
+	oldtce = ppc_md.tce_get(tbl, entry);
+	if (oldtce & (TCE_PCI_WRITE | TCE_PCI_READ))
+		ppc_md.tce_free(tbl, entry, 1);
+	else
+		oldtce = 0;
+
+	spin_unlock(&(pool->lock));
+
+	return oldtce;
+}
+EXPORT_SYMBOL_GPL(iommu_clear_tce);
+
+int iommu_clear_tces_and_put_pages(struct iommu_table *tbl,
+		unsigned long entry, unsigned long pages)
+{
+	unsigned long oldtce;
+	struct page *page;
+
+	for ( ; pages; --pages, ++entry) {
+		oldtce = iommu_clear_tce(tbl, entry);
+		if (!oldtce)
+			continue;
+
+		page = pfn_to_page(oldtce >> PAGE_SHIFT);
+		WARN_ON(!page);
+		if (page) {
+			if (oldtce & TCE_PCI_WRITE)
+				SetPageDirty(page);
+			put_page(page);
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_clear_tces_and_put_pages);
+
+/*
+ * hwaddr is a kernel virtual address here (0xc... bazillion),
+ * tce_build converts it to a physical address.
+ */
+int iommu_tce_build(struct iommu_table *tbl, unsigned long entry,
+		unsigned long hwaddr, enum dma_data_direction direction)
+{
+	int ret = -EBUSY;
+	unsigned long oldtce;
+	struct iommu_pool *pool = get_pool(tbl, entry);
+
+	spin_lock(&(pool->lock));
+
+	oldtce = ppc_md.tce_get(tbl, entry);
+	/* Add new entry if it is not busy */
+	if (!(oldtce & (TCE_PCI_WRITE | TCE_PCI_READ)))
+		ret = ppc_md.tce_build(tbl, entry, 1, hwaddr, direction, NULL);
+
+	spin_unlock(&(pool->lock));
+
+	/* if (unlikely(ret))
+		pr_err("iommu_tce: %s failed on hwaddr=%lx ioba=%lx kva=%lx ret=%d\n",
+				__func__, hwaddr, entry << IOMMU_PAGE_SHIFT,
+				hwaddr, ret); */
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_tce_build);
+
+int iommu_put_tce_user_mode(struct iommu_table *tbl, unsigned long entry,
+		unsigned long tce)
+{
+	int ret;
+	struct page *page = NULL;
+	unsigned long hwaddr, offset = tce & IOMMU_PAGE_MASK & ~PAGE_MASK;
+	enum dma_data_direction direction = iommu_tce_direction(tce);
+
+	ret = get_user_pages_fast(tce & PAGE_MASK, 1,
+			direction != DMA_TO_DEVICE, &page);
+	if (unlikely(ret != 1)) {
+		/* pr_err("iommu_tce: get_user_pages_fast failed tce=%lx ioba=%lx ret=%d\n",
+				tce, entry << IOMMU_PAGE_SHIFT, ret); */
+		return -EFAULT;
+	}
+	hwaddr = (unsigned long) page_address(page) + offset;
+
+	ret = iommu_tce_build(tbl, entry, hwaddr, direction);
+	if (ret)
+		put_page(page);
+
+	if (ret < 0)
+		pr_err("iommu_tce: %s failed ioba=%lx, tce=%lx, ret=%d\n",
+				__func__, entry << IOMMU_PAGE_SHIFT, tce, ret);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_put_tce_user_mode);
+
+int iommu_take_ownership(struct iommu_table *tbl)
+{
+	unsigned long sz = (tbl->it_size + 7) >> 3;
+
+	if (tbl->it_offset == 0)
+		clear_bit(0, tbl->it_map);
+
+	if (!bitmap_empty(tbl->it_map, tbl->it_size)) {
+		pr_err("iommu_tce: it_map is not empty");
+		return -EBUSY;
+	}
+
+	memset(tbl->it_map, 0xff, sz);
+	iommu_clear_tces_and_put_pages(tbl, tbl->it_offset, tbl->it_size);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_take_ownership);
+
+void iommu_release_ownership(struct iommu_table *tbl)
+{
+	unsigned long sz = (tbl->it_size + 7) >> 3;
+
+	iommu_clear_tces_and_put_pages(tbl, tbl->it_offset, tbl->it_size);
+	memset(tbl->it_map, 0, sz);
+
+	/* Restore bit#0 set by iommu_init_table() */
+	if (tbl->it_offset == 0)
+		set_bit(0, tbl->it_map);
+}
+EXPORT_SYMBOL_GPL(iommu_release_ownership);
+
+static int iommu_add_device(struct device *dev)
+{
+	struct iommu_table *tbl;
+	int ret = 0;
+
+	if (WARN_ON(dev->iommu_group)) {
+		pr_warn("iommu_tce: device %s is already in iommu group %d, skipping\n",
+				dev_name(dev),
+				iommu_group_id(dev->iommu_group));
+		return -EBUSY;
+	}
+
+	tbl = get_iommu_table_base(dev);
+	if (!tbl || !tbl->it_group) {
+		pr_debug("iommu_tce: skipping device %s with no tbl\n",
+				dev_name(dev));
+		return 0;
+	}
+
+	pr_debug("iommu_tce: adding %s to iommu group %d\n",
+			dev_name(dev), iommu_group_id(tbl->it_group));
+
+	ret = iommu_group_add_device(tbl->it_group, dev);
+	if (ret < 0)
+		pr_err("iommu_tce: %s has not been added, ret=%d\n",
+				dev_name(dev), ret);
+
+	return ret;
+}
+
+static void iommu_del_device(struct device *dev)
+{
+	iommu_group_remove_device(dev);
+}
+
+static int iommu_bus_notifier(struct notifier_block *nb,
+			      unsigned long action, void *data)
+{
+	struct device *dev = data;
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		return iommu_add_device(dev);
+	case BUS_NOTIFY_DEL_DEVICE:
+		iommu_del_device(dev);
+		return 0;
+	default:
+		return 0;
+	}
+}
+
+static struct notifier_block tce_iommu_bus_nb = {
+	.notifier_call = iommu_bus_notifier,
+};
+
+static int __init tce_iommu_init(void)
+{
+	struct pci_dev *pdev = NULL;
+
+	BUILD_BUG_ON(PAGE_SIZE < IOMMU_PAGE_SIZE);
+
+	for_each_pci_dev(pdev)
+		iommu_add_device(&pdev->dev);
+
+	bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb);
+	return 0;
+}
+
+subsys_initcall_sync(tce_iommu_init);
+
+#else
+
+void iommu_register_group(struct iommu_table *tbl,
+		int pci_domain_number, unsigned long pe_num)
+{
+}
+
+#endif /* CONFIG_IOMMU_API */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/io-workarounds.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/io-workarounds.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/io-workarounds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/io-workarounds.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,6 +55,7 @@ static struct iowa_bus *iowa_pci_find(un
 
 struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr)
 {
+	unsigned hugepage_shift;
 	struct iowa_bus *bus;
 	int token;
 
@@ -70,11 +71,17 @@ struct iowa_bus *iowa_mem_find_bus(const
 		if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
 			return NULL;
 
-		ptep = find_linux_pte(init_mm.pgd, vaddr);
+		ptep = find_linux_pte_or_hugepte(init_mm.pgd, vaddr,
+						 &hugepage_shift);
 		if (ptep == NULL)
 			paddr = 0;
-		else
+		else {
+			/*
+			 * we don't have hugepages backing iomem
+			 */
+			WARN_ON(hugepage_shift);
 			paddr = pte_pfn(*ptep) << PAGE_SHIFT;
+		}
 		bus = iowa_pci_find(vaddr, paddr);
 
 		if (bus == NULL)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/irq.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/irq.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,8 +116,6 @@ static inline notrace int decrementer_ch
  	u64 now = get_tb_or_rtc();
  	u64 *next_tb = &__get_cpu_var(decrementers_next_tb);
  
-	if (now >= *next_tb)
-		set_dec(1);
 	return now >= *next_tb;
 }
 
@@ -364,7 +362,7 @@ int arch_show_interrupts(struct seq_file
 		seq_printf(p, "%10u ", per_cpu(irq_stat, j).spurious_irqs);
 	seq_printf(p, "  Spurious interrupts\n");
 
-	seq_printf(p, "%*s: ", prec, "CNT");
+	seq_printf(p, "%*s: ", prec, "PMI");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs);
 	seq_printf(p, "  Performance monitoring interrupts\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/kprobes.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/kprobes.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/kprobes.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/kprobes.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,12 +36,6 @@
 #include <asm/sstep.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
-#define MSR_SINGLESTEP	(MSR_DE)
-#else
-#define MSR_SINGLESTEP	(MSR_SE)
-#endif
-
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
@@ -104,19 +98,7 @@ void __kprobes arch_remove_kprobe(struct
 
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
-	/* We turn off async exceptions to ensure that the single step will
-	 * be for the instruction we have the kprobe on, if we dont its
-	 * possible we'd get the single step reported for an exception handler
-	 * like Decrementer or External Interrupt */
-	regs->msr &= ~MSR_EE;
-	regs->msr |= MSR_SINGLESTEP;
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
-	regs->msr &= ~MSR_CE;
-	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
-#ifdef CONFIG_PPC_47x
-	isync();
-#endif
-#endif
+	enable_single_step(regs);
 
 	/*
 	 * On powerpc we should single step on the original
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/kvm.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/kvm.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/kvm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/kvm.c	2013-08-25 20:43:22.000000000 -0400
@@ -750,13 +750,8 @@ EXPORT_SYMBOL_GPL(kvm_hypercall);
 
 static __init void kvm_free_tmp(void)
 {
-	unsigned long start, end;
-
-	start = (ulong)&kvm_tmp[kvm_tmp_index + (PAGE_SIZE - 1)] & PAGE_MASK;
-	end = (ulong)&kvm_tmp[ARRAY_SIZE(kvm_tmp)] & PAGE_MASK;
-
-	/* Free the tmp space we don't need */
-	free_reserved_area(start, end, 0, NULL);
+	free_reserved_area(&kvm_tmp[kvm_tmp_index],
+			   &kvm_tmp[ARRAY_SIZE(kvm_tmp)], -1, NULL);
 }
 
 static int __init kvm_guest_init(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/Makefile linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/Makefile
--- linux-libre-3.10-gnu/arch/powerpc/kernel/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -58,6 +58,8 @@ obj-$(CONFIG_RTAS_PROC)		+= rtas-proc.o
 obj-$(CONFIG_LPARCFG)		+= lparcfg.o
 obj-$(CONFIG_IBMVIO)		+= vio.o
 obj-$(CONFIG_IBMEBUS)           += ibmebus.o
+obj-$(CONFIG_EEH)              += eeh.o eeh_pe.o eeh_dev.o eeh_cache.o \
+				  eeh_driver.o eeh_event.o eeh_sysfs.o
 obj-$(CONFIG_GENERIC_TBSYNC)	+= smp-tbsync.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_FA_DUMP)		+= fadump.o
@@ -100,7 +102,7 @@ obj-$(CONFIG_PPC_UDBG_16550)	+= legacy_s
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_SWIOTLB)		+= dma-swiotlb.o
 
-pci64-$(CONFIG_PPC64)		+= pci_dn.o isa-bridge.o
+pci64-$(CONFIG_PPC64)		+= pci_dn.o pci-hotplug.o isa-bridge.o
 obj-$(CONFIG_PCI)		+= pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
 				   pci-common.o pci_of_scan.o
 obj-$(CONFIG_PCI_MSI)		+= msi.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/nvram_64.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/nvram_64.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/nvram_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/nvram_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,22 +84,30 @@ static ssize_t dev_nvram_read(struct fil
 	char *tmp = NULL;
 	ssize_t size;
 
-	ret = -ENODEV;
-	if (!ppc_md.nvram_size)
+	if (!ppc_md.nvram_size) {
+		ret = -ENODEV;
 		goto out;
+	}
 
-	ret = 0;
 	size = ppc_md.nvram_size();
-	if (*ppos >= size || size < 0)
+	if (size < 0) {
+		ret = size;
+		goto out;
+	}
+
+	if (*ppos >= size) {
+		ret = 0;
 		goto out;
+	}
 
 	count = min_t(size_t, count, size - *ppos);
 	count = min(count, PAGE_SIZE);
 
-	ret = -ENOMEM;
 	tmp = kmalloc(count, GFP_KERNEL);
-	if (!tmp)
+	if (!tmp) {
+		ret = -ENOMEM;
 		goto out;
+	}
 
 	ret = ppc_md.nvram_read(tmp, count, ppos);
 	if (ret <= 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/pci-common.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/pci-common.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/pci-common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/pci-common.c	2013-08-25 20:43:22.000000000 -0400
@@ -1462,6 +1462,8 @@ void pcibios_finish_adding_to_bus(struct
 	/* Allocate bus and devices resources */
 	pcibios_allocate_bus_resources(bus);
 	pcibios_claim_one_bus(bus);
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		pci_assign_unassigned_bus_resources(bus);
 
 	/* Fixup EEH */
 	eeh_add_device_tree_late(bus);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/pci-hotplug.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/pci-hotplug.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/pci-hotplug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/pci-hotplug.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * Derived from "arch/powerpc/platforms/pseries/pci_dlpar.c"
+ *
+ * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
+ * Copyright (C) 2005 International Business Machines
+ *
+ * Updates, 2005, John Rose <johnrose@austin.ibm.com>
+ * Updates, 2005, Linas Vepstas <linas@austin.ibm.com>
+ * Updates, 2013, Gavin Shan <shangw@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/pci.h>
+#include <linux/export.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+#include <asm/firmware.h>
+#include <asm/eeh.h>
+
+/**
+ * pcibios_release_device - release PCI device
+ * @dev: PCI device
+ *
+ * The function is called before releasing the indicated PCI device.
+ */
+void pcibios_release_device(struct pci_dev *dev)
+{
+	eeh_remove_device(dev);
+}
+
+/**
+ * pcibios_remove_pci_devices - remove all devices under this bus
+ * @bus: the indicated PCI bus
+ *
+ * Remove all of the PCI devices under this bus both from the
+ * linux pci device tree, and from the powerpc EEH address cache.
+ */
+void pcibios_remove_pci_devices(struct pci_bus *bus)
+{
+	struct pci_dev *dev, *tmp;
+	struct pci_bus *child_bus;
+
+	/* First go down child busses */
+	list_for_each_entry(child_bus, &bus->children, node)
+		pcibios_remove_pci_devices(child_bus);
+
+	pr_debug("PCI: Removing devices on bus %04x:%02x\n",
+		 pci_domain_nr(bus),  bus->number);
+	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
+		pr_debug("   Removing %s...\n", pci_name(dev));
+		pci_stop_and_remove_bus_device(dev);
+	}
+}
+
+EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
+
+/**
+ * pcibios_add_pci_devices - adds new pci devices to bus
+ * @bus: the indicated PCI bus
+ *
+ * This routine will find and fixup new pci devices under
+ * the indicated bus. This routine presumes that there
+ * might already be some devices under this bridge, so
+ * it carefully tries to add only new devices.  (And that
+ * is how this routine differs from other, similar pcibios
+ * routines.)
+ */
+void pcibios_add_pci_devices(struct pci_bus * bus)
+{
+	int slotno, mode, pass, max;
+	struct pci_dev *dev;
+	struct device_node *dn = pci_bus_to_OF_node(bus);
+
+	eeh_add_device_tree_early(dn);
+
+	mode = PCI_PROBE_NORMAL;
+	if (ppc_md.pci_probe_mode)
+		mode = ppc_md.pci_probe_mode(bus);
+
+	if (mode == PCI_PROBE_DEVTREE) {
+		/* use ofdt-based probe */
+		of_rescan_bus(dn, bus);
+	} else if (mode == PCI_PROBE_NORMAL) {
+		/*
+		 * Use legacy probe. In the partial hotplug case, we
+		 * probably have grandchildren devices unplugged. So
+		 * we don't check the return value from pci_scan_slot() in
+		 * order for fully rescan all the way down to pick them up.
+		 * They can have been removed during partial hotplug.
+		 */
+		slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
+		pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+		pcibios_setup_bus_devices(bus);
+		max = bus->busn_res.start;
+		for (pass = 0; pass < 2; pass++) {
+			list_for_each_entry(dev, &bus->devices, bus_list) {
+				if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+				    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+					max = pci_scan_bridge(bus, dev,
+							      max, pass);
+			}
+		}
+	}
+	pcibios_finish_adding_to_bus(bus);
+}
+EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/pci_of_scan.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/pci_of_scan.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/pci_of_scan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/pci_of_scan.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,7 +128,7 @@ struct pci_dev *of_create_pci_dev(struct
 	const char *type;
 	struct pci_slot *slot;
 
-	dev = alloc_pci_dev();
+	dev = pci_alloc_dev(bus);
 	if (!dev)
 		return NULL;
 	type = of_get_property(node, "device_type", NULL);
@@ -137,7 +137,6 @@ struct pci_dev *of_create_pci_dev(struct
 
 	pr_debug("    create device, devfn: %x, type: %s\n", devfn, type);
 
-	dev->bus = bus;
 	dev->dev.of_node = of_node_get(node);
 	dev->dev.parent = bus->bridge;
 	dev->dev.bus = &pci_bus_type;
@@ -165,7 +164,7 @@ struct pci_dev *of_create_pci_dev(struct
 	pr_debug("    class: 0x%x\n", dev->class);
 	pr_debug("    revision: 0x%x\n", dev->revision);
 
-	dev->current_state = 4;		/* unknown power state */
+	dev->current_state = PCI_UNKNOWN;	/* unknown power state */
 	dev->error_state = pci_channel_io_normal;
 	dev->dma_mask = 0xffffffff;
 
@@ -231,11 +230,14 @@ void of_scan_pci_bridge(struct pci_dev *
 		return;
 	}
 
-	bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
+	bus = pci_find_bus(pci_domain_nr(dev->bus), busrange[0]);
 	if (!bus) {
-		printk(KERN_ERR "Failed to create pci bus for %s\n",
-		       node->full_name);
-		return;
+		bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
+		if (!bus) {
+			printk(KERN_ERR "Failed to create pci bus for %s\n",
+			       node->full_name);
+			return;
+		}
 	}
 
 	bus->primary = dev->bus->number;
@@ -293,6 +295,38 @@ void of_scan_pci_bridge(struct pci_dev *
 }
 EXPORT_SYMBOL(of_scan_pci_bridge);
 
+static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
+			    struct device_node *dn)
+{
+	struct pci_dev *dev = NULL;
+	const u32 *reg;
+	int reglen, devfn;
+
+	pr_debug("  * %s\n", dn->full_name);
+	if (!of_device_is_available(dn))
+		return NULL;
+
+	reg = of_get_property(dn, "reg", &reglen);
+	if (reg == NULL || reglen < 20)
+		return NULL;
+	devfn = (reg[0] >> 8) & 0xff;
+
+	/* Check if the PCI device is already there */
+	dev = pci_get_slot(bus, devfn);
+	if (dev) {
+		pci_dev_put(dev);
+		return dev;
+	}
+
+	/* create a new pci_dev for this device */
+	dev = of_create_pci_dev(dn, bus, devfn);
+	if (!dev)
+		return NULL;
+
+	pr_debug("  dev header type: %x\n", dev->hdr_type);
+	return dev;
+}
+
 /**
  * __of_scan_bus - given a PCI bus node, setup bus and scan for child devices
  * @node: device tree node for the PCI bus
@@ -303,8 +337,6 @@ static void __of_scan_bus(struct device_
 			  int rescan_existing)
 {
 	struct device_node *child;
-	const u32 *reg;
-	int reglen, devfn;
 	struct pci_dev *dev;
 
 	pr_debug("of_scan_bus(%s) bus no %d...\n",
@@ -312,16 +344,7 @@ static void __of_scan_bus(struct device_
 
 	/* Scan direct children */
 	for_each_child_of_node(node, child) {
-		pr_debug("  * %s\n", child->full_name);
-		if (!of_device_is_available(child))
-			continue;
-		reg = of_get_property(child, "reg", &reglen);
-		if (reg == NULL || reglen < 20)
-			continue;
-		devfn = (reg[0] >> 8) & 0xff;
-
-		/* create a new pci_dev for this device */
-		dev = of_create_pci_dev(child, bus, devfn);
+		dev = of_scan_pci_dev(bus, child);
 		if (!dev)
 			continue;
 		pr_debug("    dev header type: %x\n", dev->hdr_type);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/process.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/process.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -600,6 +600,16 @@ struct task_struct *__switch_to(struct t
 	struct ppc64_tlb_batch *batch;
 #endif
 
+	/* Back up the TAR across context switches.
+	 * Note that the TAR is not available for use in the kernel.  (To
+	 * provide this, the TAR should be backed up/restored on exception
+	 * entry/exit instead, and be in pt_regs.  FIXME, this should be in
+	 * pt_regs anyway (for debug).)
+	 * Save the TAR here before we do treclaim/trecheckpoint as these
+	 * will change the TAR.
+	 */
+	save_tar(&prev->thread);
+
 	__switch_to_tm(prev);
 
 #ifdef CONFIG_SMP
@@ -916,7 +926,11 @@ int arch_dup_task_struct(struct task_str
 	flush_altivec_to_thread(src);
 	flush_vsx_to_thread(src);
 	flush_spe_to_thread(src);
+
 	*dst = *src;
+
+	clear_task_ebb(dst);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/proc_powerpc.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/proc_powerpc.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/proc_powerpc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/proc_powerpc.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,25 +29,9 @@
 
 #ifdef CONFIG_PPC64
 
-static loff_t page_map_seek( struct file *file, loff_t off, int whence)
+static loff_t page_map_seek(struct file *file, loff_t off, int whence)
 {
-	loff_t new;
-	switch(whence) {
-	case 0:
-		new = off;
-		break;
-	case 1:
-		new = file->f_pos + off;
-		break;
-	case 2:
-		new = PAGE_SIZE + off;
-		break;
-	default:
-		return -EINVAL;
-	}
-	if ( new < 0 || new > PAGE_SIZE )
-		return -EINVAL;
-	return (file->f_pos = new);
+	return fixed_size_llseek(file, off, whence, PAGE_SIZE);
 }
 
 static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/prom.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/prom.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/prom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/prom.c	2013-08-25 20:43:22.000000000 -0400
@@ -559,6 +559,35 @@ void __init early_init_dt_setup_initrd_a
 }
 #endif
 
+static void __init early_reserve_mem_dt(void)
+{
+	unsigned long i, len, dt_root;
+	const __be32 *prop;
+
+	dt_root = of_get_flat_dt_root();
+
+	prop = of_get_flat_dt_prop(dt_root, "reserved-ranges", &len);
+
+	if (!prop)
+		return;
+
+	DBG("Found new-style reserved-ranges\n");
+
+	/* Each reserved range is an (address,size) pair, 2 cells each,
+	 * totalling 4 cells per range. */
+	for (i = 0; i < len / (sizeof(*prop) * 4); i++) {
+		u64 base, size;
+
+		base = of_read_number(prop + (i * 4) + 0, 2);
+		size = of_read_number(prop + (i * 4) + 2, 2);
+
+		if (size) {
+			DBG("reserving: %llx -> %llx\n", base, size);
+			memblock_reserve(base, size);
+		}
+	}
+}
+
 static void __init early_reserve_mem(void)
 {
 	u64 base, size;
@@ -574,12 +603,16 @@ static void __init early_reserve_mem(voi
 	self_size = initial_boot_params->totalsize;
 	memblock_reserve(self_base, self_size);
 
+	/* Look for the new "reserved-regions" property in the DT */
+	early_reserve_mem_dt();
+
 #ifdef CONFIG_BLK_DEV_INITRD
-	/* then reserve the initrd, if any */
-	if (initrd_start && (initrd_end > initrd_start))
+	/* Then reserve the initrd, if any */
+	if (initrd_start && (initrd_end > initrd_start)) {
 		memblock_reserve(_ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
 			_ALIGN_UP(initrd_end, PAGE_SIZE) -
 			_ALIGN_DOWN(initrd_start, PAGE_SIZE));
+	}
 #endif /* CONFIG_BLK_DEV_INITRD */
 
 #ifdef CONFIG_PPC32
@@ -591,6 +624,8 @@ static void __init early_reserve_mem(voi
 		u32 base_32, size_32;
 		u32 *reserve_map_32 = (u32 *)reserve_map;
 
+		DBG("Found old 32-bit reserve map\n");
+
 		while (1) {
 			base_32 = *(reserve_map_32++);
 			size_32 = *(reserve_map_32++);
@@ -605,6 +640,9 @@ static void __init early_reserve_mem(voi
 		return;
 	}
 #endif
+	DBG("Processing reserve map\n");
+
+	/* Handle the reserve map in the fdt blob if it exists */
 	while (1) {
 		base = *(reserve_map++);
 		size = *(reserve_map++);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/prom_init.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/prom_init.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/prom_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/prom_init.c	2013-08-25 20:43:22.000000000 -0400
@@ -644,7 +644,8 @@ unsigned char ibm_architecture_vec[] = {
 	W(0xfffe0000), W(0x003a0000),	/* POWER5/POWER5+ */
 	W(0xffff0000), W(0x003e0000),	/* POWER6 */
 	W(0xffff0000), W(0x003f0000),	/* POWER7 */
-	W(0xffff0000), W(0x004b0000),	/* POWER8 */
+	W(0xffff0000), W(0x004b0000),	/* POWER8E */
+	W(0xffff0000), W(0x004d0000),	/* POWER8 */
 	W(0xffffffff), W(0x0f000004),	/* all 2.07-compliant */
 	W(0xffffffff), W(0x0f000003),	/* all 2.06-compliant */
 	W(0xffffffff), W(0x0f000002),	/* all 2.05-compliant */
@@ -706,7 +707,7 @@ unsigned char ibm_architecture_vec[] = {
 	 * must match by the macro below. Update the definition if
 	 * the structure layout changes.
 	 */
-#define IBM_ARCH_VEC_NRCORES_OFFSET	117
+#define IBM_ARCH_VEC_NRCORES_OFFSET	125
 	W(NR_CPUS),			/* number of cores supported */
 	0,
 	0,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/ptrace.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/ptrace.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/ptrace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/ptrace.c	2013-08-25 20:43:22.000000000 -0400
@@ -975,16 +975,12 @@ int ptrace_set_debugreg(struct task_stru
 	hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
 	hw_brk.len = 8;
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-	if (ptrace_get_breakpoints(task) < 0)
-		return -ESRCH;
-
 	bp = thread->ptrace_bps[0];
 	if ((!data) || !(hw_brk.type & HW_BRK_TYPE_RDWR)) {
 		if (bp) {
 			unregister_hw_breakpoint(bp);
 			thread->ptrace_bps[0] = NULL;
 		}
-		ptrace_put_breakpoints(task);
 		return 0;
 	}
 	if (bp) {
@@ -997,11 +993,9 @@ int ptrace_set_debugreg(struct task_stru
 
 		ret =  modify_user_hw_breakpoint(bp, &attr);
 		if (ret) {
-			ptrace_put_breakpoints(task);
 			return ret;
 		}
 		thread->ptrace_bps[0] = bp;
-		ptrace_put_breakpoints(task);
 		thread->hw_brk = hw_brk;
 		return 0;
 	}
@@ -1016,12 +1010,9 @@ int ptrace_set_debugreg(struct task_stru
 					       ptrace_triggered, NULL, task);
 	if (IS_ERR(bp)) {
 		thread->ptrace_bps[0] = NULL;
-		ptrace_put_breakpoints(task);
 		return PTR_ERR(bp);
 	}
 
-	ptrace_put_breakpoints(task);
-
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 	task->thread.hw_brk = hw_brk;
 #else /* CONFIG_PPC_ADV_DEBUG_REGS */
@@ -1440,24 +1431,19 @@ static long ppc_set_hwdebug(struct task_
 	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
 		brk.type |= HW_BRK_TYPE_WRITE;
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-	if (ptrace_get_breakpoints(child) < 0)
-		return -ESRCH;
-
 	/*
 	 * Check if the request is for 'range' breakpoints. We can
 	 * support it if range < 8 bytes.
 	 */
-	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
+	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
 		len = bp_info->addr2 - bp_info->addr;
-	} else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
-		ptrace_put_breakpoints(child);
+	else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
+		len = 1;
+	else
 		return -EINVAL;
-	}
 	bp = thread->ptrace_bps[0];
-	if (bp) {
-		ptrace_put_breakpoints(child);
+	if (bp)
 		return -ENOSPC;
-	}
 
 	/* Create a new breakpoint request if one doesn't exist already */
 	hw_breakpoint_init(&attr);
@@ -1469,11 +1455,9 @@ static long ppc_set_hwdebug(struct task_
 					       ptrace_triggered, NULL, child);
 	if (IS_ERR(bp)) {
 		thread->ptrace_bps[0] = NULL;
-		ptrace_put_breakpoints(child);
 		return PTR_ERR(bp);
 	}
 
-	ptrace_put_breakpoints(child);
 	return 1;
 #endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
@@ -1517,16 +1501,12 @@ static long ppc_del_hwdebug(struct task_
 		return -EINVAL;
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
-	if (ptrace_get_breakpoints(child) < 0)
-		return -ESRCH;
-
 	bp = thread->ptrace_bps[0];
 	if (bp) {
 		unregister_hw_breakpoint(bp);
 		thread->ptrace_bps[0] = NULL;
 	} else
 		ret = -ENOENT;
-	ptrace_put_breakpoints(child);
 	return ret;
 #else /* CONFIG_HAVE_HW_BREAKPOINT */
 	if (child->thread.hw_brk.address == 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/reloc_32.S linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/reloc_32.S
--- linux-libre-3.10-gnu/arch/powerpc/kernel/reloc_32.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/reloc_32.S	2013-08-25 20:43:22.000000000 -0400
@@ -166,7 +166,7 @@ ha16:
 	/* R_PPC_ADDR16_LO */
 lo16:
 	cmpwi	r4, R_PPC_ADDR16_LO
-	bne	nxtrela
+	bne	unknown_type
 	lwz	r4, 0(r9)	/* r_offset */
 	lwz	r0, 8(r9)	/* r_addend */
 	add	r0, r0, r3
@@ -191,6 +191,7 @@ nxtrela:
 	dcbst	r4,r7
 	sync			/* Ensure the data is flushed before icbi */
 	icbi	r4,r7
+unknown_type:
 	cmpwi	r8, 0		/* relasz = 0 ? */
 	ble	done
 	add	r9, r9, r6	/* move to next entry in the .rela table */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/rtas.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/rtas.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/rtas.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/rtas.c	2013-08-25 20:43:22.000000000 -0400
@@ -1172,7 +1172,7 @@ int __init early_init_dt_scan_rtas(unsig
 static arch_spinlock_t timebase_lock;
 static u64 timebase = 0;
 
-void __cpuinit rtas_give_timebase(void)
+void rtas_give_timebase(void)
 {
 	unsigned long flags;
 
@@ -1189,7 +1189,7 @@ void __cpuinit rtas_give_timebase(void)
 	local_irq_restore(flags);
 }
 
-void __cpuinit rtas_take_timebase(void)
+void rtas_take_timebase(void)
 {
 	while (!timebase)
 		barrier();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/setup_64.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/setup_64.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/setup_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/setup_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -76,7 +76,7 @@
 #endif
 
 int boot_cpuid = 0;
-int __initdata spinning_secondaries;
+int spinning_secondaries;
 u64 ppc64_pft_size;
 
 /* Pick defaults since we might want to patch instructions
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/signal_32.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/signal_32.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/signal_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/signal_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -407,7 +407,8 @@ inline unsigned long copy_transact_fpr_f
  * altivec/spe instructions at some point.
  */
 static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
-		int sigret, int ctx_has_vsx_region)
+			  struct mcontext __user *tm_frame, int sigret,
+			  int ctx_has_vsx_region)
 {
 	unsigned long msr = regs->msr;
 
@@ -475,6 +476,12 @@ static int save_user_regs(struct pt_regs
 
 	if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
 		return 1;
+	/* We need to write 0 the MSR top 32 bits in the tm frame so that we
+	 * can check it on the restore to see if TM is active
+	 */
+	if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR]))
+		return 1;
+
 	if (sigret) {
 		/* Set up the sigreturn trampoline: li r0,sigret; sc */
 		if (__put_user(0x38000000UL + sigret, &frame->tramp[0])
@@ -747,7 +754,7 @@ static long restore_tm_user_regs(struct
 				 struct mcontext __user *tm_sr)
 {
 	long err;
-	unsigned long msr;
+	unsigned long msr, msr_hi;
 #ifdef CONFIG_VSX
 	int i;
 #endif
@@ -852,8 +859,11 @@ static long restore_tm_user_regs(struct
 	tm_enable();
 	/* This loads the checkpointed FP/VEC state, if used */
 	tm_recheckpoint(&current->thread, msr);
-	/* The task has moved into TM state S, so ensure MSR reflects this */
-	regs->msr = (regs->msr & ~MSR_TS_MASK) | MSR_TS_S;
+	/* Get the top half of the MSR */
+	if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
+		return 1;
+	/* Pull in MSR TM from user context */
+	regs->msr = (regs->msr & ~MSR_TS_MASK) | ((msr_hi<<32) & MSR_TS_MASK);
 
 	/* This loads the speculative FP/VEC state, if used */
 	if (msr & MSR_FP) {
@@ -952,6 +962,7 @@ int handle_rt_signal32(unsigned long sig
 {
 	struct rt_sigframe __user *rt_sf;
 	struct mcontext __user *frame;
+	struct mcontext __user *tm_frame = NULL;
 	void __user *addr;
 	unsigned long newsp = 0;
 	int sigret;
@@ -985,23 +996,24 @@ int handle_rt_signal32(unsigned long sig
 	}
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	tm_frame = &rt_sf->uc_transact.uc_mcontext;
 	if (MSR_TM_ACTIVE(regs->msr)) {
-		if (save_tm_user_regs(regs, &rt_sf->uc.uc_mcontext,
-				      &rt_sf->uc_transact.uc_mcontext, sigret))
+		if (save_tm_user_regs(regs, frame, tm_frame, sigret))
 			goto badframe;
 	}
 	else
 #endif
-		if (save_user_regs(regs, frame, sigret, 1))
+	{
+		if (save_user_regs(regs, frame, tm_frame, sigret, 1))
 			goto badframe;
+	}
 	regs->link = tramp;
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 	if (MSR_TM_ACTIVE(regs->msr)) {
 		if (__put_user((unsigned long)&rt_sf->uc_transact,
 			       &rt_sf->uc.uc_link)
-		    || __put_user(to_user_ptr(&rt_sf->uc_transact.uc_mcontext),
-				  &rt_sf->uc_transact.uc_regs))
+		    || __put_user((unsigned long)tm_frame, &rt_sf->uc_transact.uc_regs))
 			goto badframe;
 	}
 	else
@@ -1170,7 +1182,7 @@ long sys_swapcontext(struct ucontext __u
 		mctx = (struct mcontext __user *)
 			((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
 		if (!access_ok(VERIFY_WRITE, old_ctx, ctx_size)
-		    || save_user_regs(regs, mctx, 0, ctx_has_vsx_region)
+		    || save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region)
 		    || put_sigset_t(&old_ctx->uc_sigmask, &current->blocked)
 		    || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
 			return -EFAULT;
@@ -1233,7 +1245,7 @@ long sys_rt_sigreturn(int r3, int r4, in
 		if (__get_user(msr_hi, &mcp->mc_gregs[PT_MSR]))
 			goto bad;
 
-		if (MSR_TM_SUSPENDED(msr_hi<<32)) {
+		if (MSR_TM_ACTIVE(msr_hi<<32)) {
 			/* We only recheckpoint on return if we're
 			 * transaction.
 			 */
@@ -1392,6 +1404,7 @@ int handle_signal32(unsigned long sig, s
 {
 	struct sigcontext __user *sc;
 	struct sigframe __user *frame;
+	struct mcontext __user *tm_mctx = NULL;
 	unsigned long newsp = 0;
 	int sigret;
 	unsigned long tramp;
@@ -1425,6 +1438,7 @@ int handle_signal32(unsigned long sig, s
 	}
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	tm_mctx = &frame->mctx_transact;
 	if (MSR_TM_ACTIVE(regs->msr)) {
 		if (save_tm_user_regs(regs, &frame->mctx, &frame->mctx_transact,
 				      sigret))
@@ -1432,8 +1446,10 @@ int handle_signal32(unsigned long sig, s
 	}
 	else
 #endif
-		if (save_user_regs(regs, &frame->mctx, sigret, 1))
+	{
+		if (save_user_regs(regs, &frame->mctx, tm_mctx, sigret, 1))
 			goto badframe;
+	}
 
 	regs->link = tramp;
 
@@ -1481,16 +1497,22 @@ badframe:
 long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
 		       struct pt_regs *regs)
 {
+	struct sigframe __user *sf;
 	struct sigcontext __user *sc;
 	struct sigcontext sigctx;
 	struct mcontext __user *sr;
 	void __user *addr;
 	sigset_t set;
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	struct mcontext __user *mcp, *tm_mcp;
+	unsigned long msr_hi;
+#endif
 
 	/* Always make any pending restarted system calls return -EINTR */
 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
-	sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+	sf = (struct sigframe __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+	sc = &sf->sctx;
 	addr = sc;
 	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
 		goto badframe;
@@ -1507,11 +1529,25 @@ long sys_sigreturn(int r3, int r4, int r
 #endif
 	set_current_blocked(&set);
 
-	sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
-	addr = sr;
-	if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
-	    || restore_user_regs(regs, sr, 1))
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	mcp = (struct mcontext __user *)&sf->mctx;
+	tm_mcp = (struct mcontext __user *)&sf->mctx_transact;
+	if (__get_user(msr_hi, &tm_mcp->mc_gregs[PT_MSR]))
 		goto badframe;
+	if (MSR_TM_ACTIVE(msr_hi<<32)) {
+		if (!cpu_has_feature(CPU_FTR_TM))
+			goto badframe;
+		if (restore_tm_user_regs(regs, mcp, tm_mcp))
+			goto badframe;
+	} else
+#endif
+	{
+		sr = (struct mcontext __user *)from_user_ptr(sigctx.regs);
+		addr = sr;
+		if (!access_ok(VERIFY_READ, sr, sizeof(*sr))
+		    || restore_user_regs(regs, sr, 1))
+			goto badframe;
+	}
 
 	set_thread_flag(TIF_RESTOREALL);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/signal_64.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/signal_64.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/signal_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/signal_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -410,6 +410,10 @@ static long restore_tm_sigcontexts(struc
 
 	/* get MSR separately, transfer the LE bit if doing signal return */
 	err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
+	/* pull in MSR TM from user context */
+	regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
+
+	/* pull in MSR LE from user context */
 	regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
 
 	/* The following non-GPR non-FPR non-VR state is also checkpointed: */
@@ -505,8 +509,6 @@ static long restore_tm_sigcontexts(struc
 	tm_enable();
 	/* This loads the checkpointed FP/VEC state, if used */
 	tm_recheckpoint(&current->thread, msr);
-	/* The task has moved into TM state S, so ensure MSR reflects this: */
-	regs->msr = (regs->msr & ~MSR_TS_MASK) | __MASK(33);
 
 	/* This loads the speculative FP/VEC state, if used */
 	if (msr & MSR_FP) {
@@ -654,7 +656,7 @@ int sys_rt_sigreturn(unsigned long r3, u
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 	if (__get_user(msr, &uc->uc_mcontext.gp_regs[PT_MSR]))
 		goto badframe;
-	if (MSR_TM_SUSPENDED(msr)) {
+	if (MSR_TM_ACTIVE(msr)) {
 		/* We recheckpoint on return. */
 		struct ucontext __user *uc_transact;
 		if (__get_user(uc_transact, &uc->uc_link))
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/smp.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -480,7 +480,7 @@ static void cpu_idle_thread_init(unsigne
 	secondary_ti = current_set[cpu] = ti;
 }
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int rc, c;
 
@@ -610,7 +610,7 @@ static struct device_node *cpu_to_l2cach
 }
 
 /* Activate a secondary processor. */
-__cpuinit void start_secondary(void *unused)
+void start_secondary(void *unused)
 {
 	unsigned int cpu = smp_processor_id();
 	struct device_node *l2_cache;
@@ -637,12 +637,10 @@ __cpuinit void start_secondary(void *unu
 
 	vdso_getcpu_init();
 #endif
-	notify_cpu_starting(cpu);
-	set_cpu_online(cpu, true);
 	/* Update sibling maps */
 	base = cpu_first_thread_sibling(cpu);
 	for (i = 0; i < threads_per_core; i++) {
-		if (cpu_is_offline(base + i))
+		if (cpu_is_offline(base + i) && (cpu != base + i))
 			continue;
 		cpumask_set_cpu(cpu, cpu_sibling_mask(base + i));
 		cpumask_set_cpu(base + i, cpu_sibling_mask(cpu));
@@ -667,6 +665,10 @@ __cpuinit void start_secondary(void *unu
 	}
 	of_node_put(l2_cache);
 
+	smp_wmb();
+	notify_cpu_starting(cpu);
+	set_cpu_online(cpu, true);
+
 	local_irq_enable();
 
 	cpu_startup_entry(CPUHP_ONLINE);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/sysfs.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/sysfs.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -341,7 +341,7 @@ static struct device_attribute pa6t_attr
 #endif /* HAS_PPC_PMC_PA6T */
 #endif /* HAS_PPC_PMC_CLASSIC */
 
-static void __cpuinit register_cpu_online(unsigned int cpu)
+static void register_cpu_online(unsigned int cpu)
 {
 	struct cpu *c = &per_cpu(cpu_devices, cpu);
 	struct device *s = &c->dev;
@@ -502,7 +502,7 @@ ssize_t arch_cpu_release(const char *buf
 
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static int __cpuinit sysfs_cpu_notify(struct notifier_block *self,
+static int sysfs_cpu_notify(struct notifier_block *self,
 				      unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned int)(long)hcpu;
@@ -522,7 +522,7 @@ static int __cpuinit sysfs_cpu_notify(st
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata sysfs_cpu_nb = {
+static struct notifier_block sysfs_cpu_nb = {
 	.notifier_call	= sysfs_cpu_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/time.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/time.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -631,7 +631,6 @@ static int __init get_freq(char *name, i
 	return found;
 }
 
-/* should become __cpuinit when secondary_cpu_time_init also is */
 void start_cpu_decrementer(void)
 {
 #if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/tm.S linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/tm.S
--- linux-libre-3.10-gnu/arch/powerpc/kernel/tm.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/tm.S	2013-08-25 20:43:22.000000000 -0400
@@ -112,9 +112,18 @@ _GLOBAL(tm_reclaim)
 	std	r3, STACK_PARAM(0)(r1)
 	SAVE_NVGPRS(r1)
 
+	/* We need to setup MSR for VSX register save instructions.  Here we
+	 * also clear the MSR RI since when we do the treclaim, we won't have a
+	 * valid kernel pointer for a while.  We clear RI here as it avoids
+	 * adding another mtmsr closer to the treclaim.  This makes the region
+	 * maked as non-recoverable wider than it needs to be but it saves on
+	 * inserting another mtmsrd later.
+	 */
 	mfmsr	r14
 	mr	r15, r14
 	ori	r15, r15, MSR_FP
+	li	r16, MSR_RI
+	andc	r15, r15, r16
 	oris	r15, r15, MSR_VEC@h
 #ifdef CONFIG_VSX
 	BEGIN_FTR_SECTION
@@ -224,6 +233,16 @@ dont_backup_fp:
 	std	r5, _CCR(r7)
 	std	r6, _XER(r7)
 
+
+	/* ******************** TAR, PPR, DSCR ********** */
+	mfspr	r3, SPRN_TAR
+	mfspr	r4, SPRN_PPR
+	mfspr	r5, SPRN_DSCR
+
+	std	r3, THREAD_TM_TAR(r12)
+	std	r4, THREAD_TM_PPR(r12)
+	std	r5, THREAD_TM_DSCR(r12)
+
 	/* MSR and flags:  We don't change CRs, and we don't need to alter
 	 * MSR.
 	 */
@@ -338,6 +357,16 @@ dont_restore_fp:
 	mtmsr	r6				/* FP/Vec off again! */
 
 restore_gprs:
+
+	/* ******************** TAR, PPR, DSCR ********** */
+	ld	r4, THREAD_TM_TAR(r3)
+	ld	r5, THREAD_TM_PPR(r3)
+	ld	r6, THREAD_TM_DSCR(r3)
+
+	mtspr	SPRN_TAR,	r4
+	mtspr	SPRN_PPR,	r5
+	mtspr	SPRN_DSCR,	r6
+
 	/* ******************** CR,LR,CCR,MSR ********** */
 	ld	r3, _CTR(r7)
 	ld	r4, _LINK(r7)
@@ -349,9 +378,10 @@ restore_gprs:
 	mtcr	r5
 	mtxer	r6
 
-	/* MSR and flags:  We don't change CRs, and we don't need to alter
-	 * MSR.
+	/* Clear the MSR RI since we are about to change R1.  EE is already off
 	 */
+	li	r4, 0
+	mtmsrd	r4, 1
 
 	REST_4GPRS(0, r7)			/* GPR0-3 */
 	REST_GPR(4, r7)				/* GPR4-6 */
@@ -377,6 +407,10 @@ restore_gprs:
 	GET_PACA(r13)
 	GET_SCRATCH0(r1)
 
+	/* R1 is restored, so we are recoverable again.  EE is still off */
+	li	r4, MSR_RI
+	mtmsrd	r4, 1
+
 	REST_NVGPRS(r1)
 
 	addi    r1, r1, TM_FRAME_SIZE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/traps.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,9 +44,7 @@
 #include <asm/machdep.h>
 #include <asm/rtas.h>
 #include <asm/pmc.h>
-#ifdef CONFIG_PPC32
 #include <asm/reg.h>
-#endif
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
 #endif
@@ -866,6 +864,10 @@ static int emulate_string_inst(struct pt
 		u8 val;
 		u32 shift = 8 * (3 - (pos & 0x3));
 
+		/* if process is 32-bit, clear upper 32 bits of EA */
+		if ((regs->msr & MSR_64BIT) == 0)
+			EA &= 0xFFFFFFFF;
+
 		switch ((instword & PPC_INST_STRING_MASK)) {
 			case PPC_INST_LSWX:
 			case PPC_INST_LSWI:
@@ -1125,7 +1127,17 @@ void __kprobes program_check_exception(s
 	 * ESR_DST (!?) or 0.  In the process of chasing this with the
 	 * hardware people - not sure if it can happen on any illegal
 	 * instruction or only on FP instructions, whether there is a
-	 * pattern to occurrences etc. -dgibson 31/Mar/2003 */
+	 * pattern to occurrences etc. -dgibson 31/Mar/2003
+	 */
+
+	/*
+	 * If we support a HW FPU, we need to ensure the FP state
+	 * if flushed into the thread_struct before attempting
+	 * emulation
+	 */
+#ifdef CONFIG_PPC_FPU
+	flush_fp_to_thread(current);
+#endif
 	switch (do_mathemu(regs)) {
 	case 0:
 		emulate_single_step(regs);
@@ -1282,26 +1294,63 @@ void vsx_unavailable_exception(struct pt
 	die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT);
 }
 
-void tm_unavailable_exception(struct pt_regs *regs)
+#ifdef CONFIG_PPC64
+void facility_unavailable_exception(struct pt_regs *regs)
 {
+	static char *facility_strings[] = {
+		[FSCR_FP_LG] = "FPU",
+		[FSCR_VECVSX_LG] = "VMX/VSX",
+		[FSCR_DSCR_LG] = "DSCR",
+		[FSCR_PM_LG] = "PMU SPRs",
+		[FSCR_BHRB_LG] = "BHRB",
+		[FSCR_TM_LG] = "TM",
+		[FSCR_EBB_LG] = "EBB",
+		[FSCR_TAR_LG] = "TAR",
+	};
+	char *facility = "unknown";
+	u64 value;
+	u8 status;
+	bool hv;
+
+	hv = (regs->trap == 0xf80);
+	if (hv)
+		value = mfspr(SPRN_HFSCR);
+	else
+		value = mfspr(SPRN_FSCR);
+
+	status = value >> 56;
+	if (status == FSCR_DSCR_LG) {
+		/* User is acessing the DSCR.  Set the inherit bit and allow
+		 * the user to set it directly in future by setting via the
+		 * H/FSCR DSCR bit.
+		 */
+		current->thread.dscr_inherit = 1;
+		if (hv)
+			mtspr(SPRN_HFSCR, value | HFSCR_DSCR);
+		else
+			mtspr(SPRN_FSCR,  value | FSCR_DSCR);
+		return;
+	}
+
+	if ((status < ARRAY_SIZE(facility_strings)) &&
+	    facility_strings[status])
+		facility = facility_strings[status];
+
 	/* We restore the interrupt state now */
 	if (!arch_irq_disabled_regs(regs))
 		local_irq_enable();
 
-	/* Currently we never expect a TMU exception.  Catch
-	 * this and kill the process!
-	 */
-	printk(KERN_EMERG "Unexpected TM unavailable exception at %lx "
-	       "(msr %lx)\n",
-	       regs->nip, regs->msr);
+	pr_err("%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n",
+	       hv ? "Hypervisor " : "", facility, regs->nip, regs->msr);
 
 	if (user_mode(regs)) {
 		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
 		return;
 	}
 
-	die("Unexpected TM unavailable exception", regs, SIGABRT);
+	die("Unexpected facility unavailable exception", regs, SIGABRT);
 }
+#endif
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 
@@ -1396,8 +1445,7 @@ void performance_monitor_exception(struc
 void SoftwareEmulation(struct pt_regs *regs)
 {
 	extern int do_mathemu(struct pt_regs *);
-	extern int Soft_emulate_8xx(struct pt_regs *);
-#if defined(CONFIG_MATH_EMULATION) || defined(CONFIG_8XX_MINIMAL_FPEMU)
+#if defined(CONFIG_MATH_EMULATION)
 	int errcode;
 #endif
 
@@ -1430,23 +1478,6 @@ void SoftwareEmulation(struct pt_regs *r
 		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
 		return;
 	}
-
-#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
-	errcode = Soft_emulate_8xx(regs);
-	if (errcode >= 0)
-		PPC_WARN_EMULATED(8xx, regs);
-
-	switch (errcode) {
-	case 0:
-		emulate_single_step(regs);
-		return;
-	case 1:
-		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
-		return;
-	case -EFAULT:
-		_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
-		return;
-	}
 #else
 	_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
 #endif
@@ -1796,8 +1827,6 @@ struct ppc_emulated ppc_emulated = {
 	WARN_EMULATED_SETUP(unaligned),
 #ifdef CONFIG_MATH_EMULATION
 	WARN_EMULATED_SETUP(math),
-#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
-	WARN_EMULATED_SETUP(8xx),
 #endif
 #ifdef CONFIG_VSX
 	WARN_EMULATED_SETUP(vsx),
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/udbg.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/udbg.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/udbg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/udbg.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,7 +50,7 @@ void __init udbg_early_init(void)
 	udbg_init_debug_beat();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE)
 	udbg_init_pas_realmode();
-#elif defined(CONFIG_BOOTX_TEXT)
+#elif defined(CONFIG_PPC_EARLY_DEBUG_BOOTX)
 	udbg_init_btext();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
 	/* PPC44x debug */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/vdso.c linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/vdso.c
--- linux-libre-3.10-gnu/arch/powerpc/kernel/vdso.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/vdso.c	2013-08-25 20:43:22.000000000 -0400
@@ -711,7 +711,7 @@ static void __init vdso_setup_syscall_ma
 }
 
 #ifdef CONFIG_PPC64
-int __cpuinit vdso_getcpu_init(void)
+int vdso_getcpu_init(void)
 {
 	unsigned long cpu, node, val;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kernel/vmlinux.lds.S linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/vmlinux.lds.S
--- linux-libre-3.10-gnu/arch/powerpc/kernel/vmlinux.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kernel/vmlinux.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -38,9 +38,6 @@ jiffies = jiffies_64 + 4;
 #endif
 SECTIONS
 {
-	. = 0;
-	reloc_start = .;
-
 	. = KERNELBASE;
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_64_mmu.c linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_64_mmu.c
--- linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_64_mmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_64_mmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,7 @@
 #include <asm/tlbflush.h>
 #include <asm/kvm_ppc.h>
 #include <asm/kvm_book3s.h>
+#include <asm/mmu-hash64.h>
 
 /* #define DEBUG_MMU */
 
@@ -76,6 +77,24 @@ static struct kvmppc_slb *kvmppc_mmu_boo
 	return NULL;
 }
 
+static int kvmppc_slb_sid_shift(struct kvmppc_slb *slbe)
+{
+	return slbe->tb ? SID_SHIFT_1T : SID_SHIFT;
+}
+
+static u64 kvmppc_slb_offset_mask(struct kvmppc_slb *slbe)
+{
+	return (1ul << kvmppc_slb_sid_shift(slbe)) - 1;
+}
+
+static u64 kvmppc_slb_calc_vpn(struct kvmppc_slb *slb, gva_t eaddr)
+{
+	eaddr &= kvmppc_slb_offset_mask(slb);
+
+	return (eaddr >> VPN_SHIFT) |
+		((slb->vsid) << (kvmppc_slb_sid_shift(slb) - VPN_SHIFT));
+}
+
 static u64 kvmppc_mmu_book3s_64_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr,
 					 bool data)
 {
@@ -85,11 +104,7 @@ static u64 kvmppc_mmu_book3s_64_ea_to_vp
 	if (!slb)
 		return 0;
 
-	if (slb->tb)
-		return (((u64)eaddr >> 12) & 0xfffffff) |
-		       (((u64)slb->vsid) << 28);
-
-	return (((u64)eaddr >> 12) & 0xffff) | (((u64)slb->vsid) << 16);
+	return kvmppc_slb_calc_vpn(slb, eaddr);
 }
 
 static int kvmppc_mmu_book3s_64_get_pagesize(struct kvmppc_slb *slbe)
@@ -100,7 +115,8 @@ static int kvmppc_mmu_book3s_64_get_page
 static u32 kvmppc_mmu_book3s_64_get_page(struct kvmppc_slb *slbe, gva_t eaddr)
 {
 	int p = kvmppc_mmu_book3s_64_get_pagesize(slbe);
-	return ((eaddr & 0xfffffff) >> p);
+
+	return ((eaddr & kvmppc_slb_offset_mask(slbe)) >> p);
 }
 
 static hva_t kvmppc_mmu_book3s_64_get_pteg(
@@ -109,13 +125,15 @@ static hva_t kvmppc_mmu_book3s_64_get_pt
 				bool second)
 {
 	u64 hash, pteg, htabsize;
-	u32 page;
+	u32 ssize;
 	hva_t r;
+	u64 vpn;
 
-	page = kvmppc_mmu_book3s_64_get_page(slbe, eaddr);
 	htabsize = ((1 << ((vcpu_book3s->sdr1 & 0x1f) + 11)) - 1);
 
-	hash = slbe->vsid ^ page;
+	vpn = kvmppc_slb_calc_vpn(slbe, eaddr);
+	ssize = slbe->tb ? MMU_SEGSIZE_1T : MMU_SEGSIZE_256M;
+	hash = hpt_hash(vpn, kvmppc_mmu_book3s_64_get_pagesize(slbe), ssize);
 	if (second)
 		hash = ~hash;
 	hash &= ((1ULL << 39ULL) - 1ULL);
@@ -146,7 +164,7 @@ static u64 kvmppc_mmu_book3s_64_get_avpn
 	u64 avpn;
 
 	avpn = kvmppc_mmu_book3s_64_get_page(slbe, eaddr);
-	avpn |= slbe->vsid << (28 - p);
+	avpn |= slbe->vsid << (kvmppc_slb_sid_shift(slbe) - p);
 
 	if (p < 24)
 		avpn >>= ((80 - p) - 56) - 8;
@@ -167,7 +185,6 @@ static int kvmppc_mmu_book3s_64_xlate(st
 	int i;
 	u8 key = 0;
 	bool found = false;
-	bool perm_err = false;
 	int second = 0;
 	ulong mp_ea = vcpu->arch.magic_page_ea;
 
@@ -190,13 +207,15 @@ static int kvmppc_mmu_book3s_64_xlate(st
 	if (!slbe)
 		goto no_seg_found;
 
+	avpn = kvmppc_mmu_book3s_64_get_avpn(slbe, eaddr);
+	if (slbe->tb)
+		avpn |= SLB_VSID_B_1T;
+
 do_second:
 	ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu_book3s, slbe, eaddr, second);
 	if (kvm_is_error_hva(ptegp))
 		goto no_page_found;
 
-	avpn = kvmppc_mmu_book3s_64_get_avpn(slbe, eaddr);
-
 	if(copy_from_user(pteg, (void __user *)ptegp, sizeof(pteg))) {
 		printk(KERN_ERR "KVM can't copy data from 0x%lx!\n", ptegp);
 		goto no_page_found;
@@ -219,7 +238,7 @@ do_second:
 			continue;
 
 		/* AVPN compare */
-		if (HPTE_V_AVPN_VAL(avpn) == HPTE_V_AVPN_VAL(v)) {
+		if (HPTE_V_COMPARE(avpn, v)) {
 			u8 pp = (r & HPTE_R_PP) | key;
 			int eaddr_mask = 0xFFF;
 
@@ -248,11 +267,6 @@ do_second:
 				break;
 			}
 
-			if (!gpte->may_read) {
-				perm_err = true;
-				continue;
-			}
-
 			dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx "
 				"-> 0x%lx\n",
 				eaddr, avpn, gpte->vpage, gpte->raddr);
@@ -281,6 +295,8 @@ do_second:
 		if (pteg[i+1] != oldr)
 			copy_to_user((void __user *)ptegp, pteg, sizeof(pteg));
 
+		if (!gpte->may_read)
+			return -EPERM;
 		return 0;
 	} else {
 		dprintk("KVM MMU: No PTE found (ea=0x%lx sdr1=0x%llx "
@@ -296,13 +312,7 @@ do_second:
 		}
 	}
 
-
 no_page_found:
-
-
-	if (perm_err)
-		return -EPERM;
-
 	return -ENOENT;
 
 no_seg_found:
@@ -334,7 +344,7 @@ static void kvmppc_mmu_book3s_64_slbmte(
 	slbe->large = (rs & SLB_VSID_L) ? 1 : 0;
 	slbe->tb    = (rs & SLB_VSID_B_1T) ? 1 : 0;
 	slbe->esid  = slbe->tb ? esid_1t : esid;
-	slbe->vsid  = rs >> 12;
+	slbe->vsid  = (rs & ~SLB_VSID_B) >> (kvmppc_slb_sid_shift(slbe) - 16);
 	slbe->valid = (rb & SLB_ESID_V) ? 1 : 0;
 	slbe->Ks    = (rs & SLB_VSID_KS) ? 1 : 0;
 	slbe->Kp    = (rs & SLB_VSID_KP) ? 1 : 0;
@@ -375,6 +385,7 @@ static u64 kvmppc_mmu_book3s_64_slbmfev(
 static void kvmppc_mmu_book3s_64_slbie(struct kvm_vcpu *vcpu, u64 ea)
 {
 	struct kvmppc_slb *slbe;
+	u64 seg_size;
 
 	dprintk("KVM MMU: slbie(0x%llx)\n", ea);
 
@@ -386,8 +397,11 @@ static void kvmppc_mmu_book3s_64_slbie(s
 	dprintk("KVM MMU: slbie(0x%llx, 0x%llx)\n", ea, slbe->esid);
 
 	slbe->valid = false;
+	slbe->orige = 0;
+	slbe->origv = 0;
 
-	kvmppc_mmu_map_segment(vcpu, ea);
+	seg_size = 1ull << kvmppc_slb_sid_shift(slbe);
+	kvmppc_mmu_flush_segment(vcpu, ea & ~(seg_size - 1), seg_size);
 }
 
 static void kvmppc_mmu_book3s_64_slbia(struct kvm_vcpu *vcpu)
@@ -396,8 +410,11 @@ static void kvmppc_mmu_book3s_64_slbia(s
 
 	dprintk("KVM MMU: slbia()\n");
 
-	for (i = 1; i < vcpu->arch.slb_nr; i++)
+	for (i = 1; i < vcpu->arch.slb_nr; i++) {
 		vcpu->arch.slb[i].valid = false;
+		vcpu->arch.slb[i].orige = 0;
+		vcpu->arch.slb[i].origv = 0;
+	}
 
 	if (vcpu->arch.shared->msr & MSR_IR) {
 		kvmppc_mmu_flush_segments(vcpu);
@@ -467,8 +484,14 @@ static int kvmppc_mmu_book3s_64_esid_to_
 
 	if (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) {
 		slb = kvmppc_mmu_book3s_64_find_slbe(vcpu, ea);
-		if (slb)
+		if (slb) {
 			gvsid = slb->vsid;
+			if (slb->tb) {
+				gvsid <<= SID_SHIFT_1T - SID_SHIFT;
+				gvsid |= esid & ((1ul << (SID_SHIFT_1T - SID_SHIFT)) - 1);
+				gvsid |= VSID_1T;
+			}
+		}
 	}
 
 	switch (vcpu->arch.shared->msr & (MSR_DR|MSR_IR)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c
--- linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_64_mmu_host.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,7 +34,7 @@
 void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte)
 {
 	ppc_md.hpte_invalidate(pte->slot, pte->host_vpn,
-			       MMU_PAGE_4K, MMU_SEGSIZE_256M,
+			       MMU_PAGE_4K, MMU_PAGE_4K, MMU_SEGSIZE_256M,
 			       false);
 }
 
@@ -301,6 +301,23 @@ out:
 	return r;
 }
 
+void kvmppc_mmu_flush_segment(struct kvm_vcpu *vcpu, ulong ea, ulong seg_size)
+{
+	struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu);
+	ulong seg_mask = -seg_size;
+	int i;
+
+	for (i = 1; i < svcpu->slb_max; i++) {
+		if ((svcpu->slb[i].esid & SLB_ESID_V) &&
+		    (svcpu->slb[i].esid & seg_mask) == ea) {
+			/* Invalidate this entry */
+			svcpu->slb[i].esid = 0;
+		}
+	}
+
+	svcpu_put(svcpu);
+}
+
 void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu)
 {
 	struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu);
@@ -325,9 +342,9 @@ int kvmppc_mmu_init(struct kvm_vcpu *vcp
 		return -1;
 	vcpu3s->context_id[0] = err;
 
-	vcpu3s->proto_vsid_max = ((vcpu3s->context_id[0] + 1)
+	vcpu3s->proto_vsid_max = ((u64)(vcpu3s->context_id[0] + 1)
 				  << ESID_BITS) - 1;
-	vcpu3s->proto_vsid_first = vcpu3s->context_id[0] << ESID_BITS;
+	vcpu3s->proto_vsid_first = (u64)vcpu3s->context_id[0] << ESID_BITS;
 	vcpu3s->proto_vsid_next = vcpu3s->proto_vsid_first;
 
 	kvmppc_mmu_hpte_init(vcpu);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_64_mmu_hv.c linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_64_mmu_hv.c
--- linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_64_mmu_hv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_64_mmu_hv.c	2013-08-25 20:43:22.000000000 -0400
@@ -675,6 +675,7 @@ int kvmppc_book3s_hv_page_fault(struct k
 		}
 		/* if the guest wants write access, see if that is OK */
 		if (!writing && hpte_is_writable(r)) {
+			unsigned int hugepage_shift;
 			pte_t *ptep, pte;
 
 			/*
@@ -683,9 +684,10 @@ int kvmppc_book3s_hv_page_fault(struct k
 			 */
 			rcu_read_lock_sched();
 			ptep = find_linux_pte_or_hugepte(current->mm->pgd,
-							 hva, NULL);
-			if (ptep && pte_present(*ptep)) {
-				pte = kvmppc_read_update_linux_pte(ptep, 1);
+							 hva, &hugepage_shift);
+			if (ptep) {
+				pte = kvmppc_read_update_linux_pte(ptep, 1,
+							   hugepage_shift);
 				if (pte_write(pte))
 					write_ok = 1;
 			}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_64_slb.S linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_64_slb.S
--- linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_64_slb.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_64_slb.S	2013-08-25 20:43:22.000000000 -0400
@@ -66,10 +66,6 @@ slb_exit_skip_ ## num:
 
 	ld	r12, PACA_SLBSHADOWPTR(r13)
 
-	/* Save off the first entry so we can slbie it later */
-	ld	r10, SHADOW_SLB_ESID(0)(r12)
-	ld	r11, SHADOW_SLB_VSID(0)(r12)
-
 	/* Remove bolted entries */
 	UNBOLT_SLB_ENTRY(0)
 	UNBOLT_SLB_ENTRY(1)
@@ -81,15 +77,10 @@ slb_exit_skip_ ## num:
 
 	/* Flush SLB */
 
+	li	r10, 0
+	slbmte	r10, r10
 	slbia
 
-	/* r0 = esid & ESID_MASK */
-	rldicr  r10, r10, 0, 35
-	/* r0 |= CLASS_BIT(VSID) */
-	rldic   r12, r11, 56 - 36, 36
-	or      r10, r10, r12
-	slbie	r10
-
 	/* Fill SLB with our shadow */
 
 	lbz	r12, SVCPU_SLB_MAX(r3)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_hv.c linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_hv.c
--- linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_hv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_hv.c	2013-08-25 20:43:22.000000000 -0400
@@ -1809,7 +1809,7 @@ static int kvmppc_hv_setup_htab_rma(stru
 		rma_size <<= PAGE_SHIFT;
 		rmls = lpcr_rmls(rma_size);
 		err = -EINVAL;
-		if (rmls < 0) {
+		if ((long)rmls < 0) {
 			pr_err("KVM: Can't use RMA of 0x%lx bytes\n", rma_size);
 			goto out_srcu;
 		}
@@ -1864,7 +1864,7 @@ static int kvmppc_hv_setup_htab_rma(stru
 
  up_out:
 	up_read(&current->mm->mmap_sem);
-	goto out;
+	goto out_srcu;
 }
 
 int kvmppc_core_init_vm(struct kvm *kvm)
@@ -1874,7 +1874,7 @@ int kvmppc_core_init_vm(struct kvm *kvm)
 	/* Allocate the guest's logical partition ID */
 
 	lpid = kvmppc_alloc_lpid();
-	if (lpid < 0)
+	if ((long)lpid < 0)
 		return -ENOMEM;
 	kvm->arch.lpid = lpid;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_hv_rm_mmu.c linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_hv_rm_mmu.c
--- linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_hv_rm_mmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_hv_rm_mmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@ static void *real_vmalloc_addr(void *x)
 	unsigned long addr = (unsigned long) x;
 	pte_t *p;
 
-	p = find_linux_pte(swapper_pg_dir, addr);
+	p = find_linux_pte_or_hugepte(swapper_pg_dir, addr, NULL);
 	if (!p || !pte_present(*p))
 		return NULL;
 	/* assume we don't have huge pages in vmalloc space... */
@@ -139,20 +139,18 @@ static pte_t lookup_linux_pte(pgd_t *pgd
 {
 	pte_t *ptep;
 	unsigned long ps = *pte_sizep;
-	unsigned int shift;
+	unsigned int hugepage_shift;
 
-	ptep = find_linux_pte_or_hugepte(pgdir, hva, &shift);
+	ptep = find_linux_pte_or_hugepte(pgdir, hva, &hugepage_shift);
 	if (!ptep)
 		return __pte(0);
-	if (shift)
-		*pte_sizep = 1ul << shift;
+	if (hugepage_shift)
+		*pte_sizep = 1ul << hugepage_shift;
 	else
 		*pte_sizep = PAGE_SIZE;
 	if (ps > *pte_sizep)
 		return __pte(0);
-	if (!pte_present(*ptep))
-		return __pte(0);
-	return kvmppc_read_update_linux_pte(ptep, writing);
+	return kvmppc_read_update_linux_pte(ptep, writing, hugepage_shift);
 }
 
 static inline void unlock_hpte(unsigned long *hpte, unsigned long hpte_v)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_pr.c linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_pr.c
--- linux-libre-3.10-gnu/arch/powerpc/kvm/book3s_pr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/book3s_pr.c	2013-08-25 20:43:22.000000000 -0400
@@ -1047,11 +1047,12 @@ struct kvm_vcpu *kvmppc_core_vcpu_create
 	if (err)
 		goto free_shadow_vcpu;
 
+	err = -ENOMEM;
 	p = __get_free_page(GFP_KERNEL|__GFP_ZERO);
-	/* the real shared page fills the last 4k of our page */
-	vcpu->arch.shared = (void*)(p + PAGE_SIZE - 4096);
 	if (!p)
 		goto uninit_vcpu;
+	/* the real shared page fills the last 4k of our page */
+	vcpu->arch.shared = (void *)(p + PAGE_SIZE - 4096);
 
 #ifdef CONFIG_PPC_BOOK3S_64
 	/* default to book3s_64 (970fx) */
@@ -1239,8 +1240,7 @@ out:
 #ifdef CONFIG_PPC64
 int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, struct kvm_ppc_smmu_info *info)
 {
-	/* No flags */
-	info->flags = 0;
+	info->flags = KVM_PPC_1T_SEGMENTS;
 
 	/* SLB is always 64 entries */
 	info->slb_size = 64;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/booke.c linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/booke.c
--- linux-libre-3.10-gnu/arch/powerpc/kvm/booke.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/booke.c	2013-08-25 20:43:22.000000000 -0400
@@ -796,7 +796,7 @@ static void kvmppc_restart_interrupt(str
 		kvmppc_fill_pt_regs(&regs);
 		timer_interrupt(&regs);
 		break;
-#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_BOOK3E_64)
+#if defined(CONFIG_PPC_DOORBELL)
 	case BOOKE_INTERRUPT_DOORBELL:
 		kvmppc_fill_pt_regs(&regs);
 		doorbell_exception(&regs);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/emulate.c linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/emulate.c
--- linux-libre-3.10-gnu/arch/powerpc/kvm/emulate.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/emulate.c	2013-08-25 20:43:22.000000000 -0400
@@ -169,6 +169,9 @@ static int kvmppc_emulate_mtspr(struct k
 		vcpu->arch.shared->sprg3 = spr_val;
 		break;
 
+	/* PIR can legally be written, but we ignore it */
+	case SPRN_PIR: break;
+
 	default:
 		emulated = kvmppc_core_emulate_mtspr(vcpu, sprn,
 						     spr_val);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/kvm/Makefile linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/Makefile
--- linux-libre-3.10-gnu/arch/powerpc/kvm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/kvm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,9 +5,10 @@
 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 
 ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm
+KVM := ../../../virt/kvm
 
-common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o \
-						eventfd.o)
+common-objs-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \
+		$(KVM)/eventfd.o
 
 CFLAGS_44x_tlb.o  := -I.
 CFLAGS_e500_mmu.o := -I.
@@ -53,7 +54,7 @@ kvm-e500mc-objs := \
 kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs)
 
 kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \
-	../../../virt/kvm/coalesced_mmio.o \
+	$(KVM)/coalesced_mmio.o \
 	fpu.o \
 	book3s_paired_singles.o \
 	book3s_pr.o \
@@ -86,8 +87,8 @@ kvm-book3s_64-objs-$(CONFIG_KVM_XICS) +=
 	book3s_xics.o
 
 kvm-book3s_64-module-objs := \
-	../../../virt/kvm/kvm_main.o \
-	../../../virt/kvm/eventfd.o \
+	$(KVM)/kvm_main.o \
+	$(KVM)/eventfd.o \
 	powerpc.o \
 	emulate.o \
 	book3s.o \
@@ -111,7 +112,7 @@ kvm-book3s_32-objs := \
 kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs)
 
 kvm-objs-$(CONFIG_KVM_MPIC) += mpic.o
-kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(addprefix ../../../virt/kvm/, irqchip.o)
+kvm-objs-$(CONFIG_HAVE_KVM_IRQ_ROUTING) += $(KVM)/irqchip.o
 
 kvm-objs := $(kvm-objs-m) $(kvm-objs-y)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/lib/sstep.c linux-libre-3.11-rc7-gnu/arch/powerpc/lib/sstep.c
--- linux-libre-3.10-gnu/arch/powerpc/lib/sstep.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/lib/sstep.c	2013-08-25 20:43:22.000000000 -0400
@@ -580,7 +580,7 @@ int __kprobes emulate_step(struct pt_reg
 		if (instr & 1)
 			regs->link = regs->nip;
 		if (branch_taken(instr, regs))
-			regs->nip = imm;
+			regs->nip = truncate_if_32bit(regs->msr, imm);
 		return 1;
 #ifdef CONFIG_PPC64
 	case 17:	/* sc */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/math-emu/fre.c linux-libre-3.11-rc7-gnu/arch/powerpc/math-emu/fre.c
--- linux-libre-3.10-gnu/arch/powerpc/math-emu/fre.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/math-emu/fre.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+int fre(void *frD, void *frB)
+{
+#ifdef DEBUG
+	printk("%s: %p %p\n", __func__, frD, frB);
+#endif
+	return -ENOSYS;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/math-emu/frsqrtes.c linux-libre-3.11-rc7-gnu/arch/powerpc/math-emu/frsqrtes.c
--- linux-libre-3.10-gnu/arch/powerpc/math-emu/frsqrtes.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/math-emu/frsqrtes.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+
+int frsqrtes(void *frD, void *frB)
+{
+#ifdef DEBUG
+	printk("%s: %p %p\n", __func__, frD, frB);
+#endif
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/math-emu/Makefile linux-libre-3.11-rc7-gnu/arch/powerpc/math-emu/Makefile
--- linux-libre-3.10-gnu/arch/powerpc/math-emu/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/math-emu/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,8 @@ obj-$(CONFIG_MATH_EMULATION)	+= fabs.o f
 					fmadd.o fmadds.o fmsub.o fmsubs.o \
 					fmul.o fmuls.o fnabs.o fneg.o \
 					fnmadd.o fnmadds.o fnmsub.o fnmsubs.o \
-					fres.o frsp.o frsqrte.o fsel.o lfs.o \
+					fres.o fre.o frsp.o fsel.o lfs.o \
+					frsqrte.o frsqrtes.o \
 					fsqrt.o	fsqrts.o fsub.o fsubs.o \
 					mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
 					mtfsf.o mtfsfi.o stfiwx.o stfs.o \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/math-emu/math.c linux-libre-3.11-rc7-gnu/arch/powerpc/math-emu/math.c
--- linux-libre-3.10-gnu/arch/powerpc/math-emu/math.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/math-emu/math.c	2013-08-25 20:43:22.000000000 -0400
@@ -58,8 +58,10 @@ FLOATFUNC(fnabs);
 FLOATFUNC(fneg);
 
 /* Optional */
+FLOATFUNC(fre);
 FLOATFUNC(fres);
 FLOATFUNC(frsqrte);
+FLOATFUNC(frsqrtes);
 FLOATFUNC(fsel);
 FLOATFUNC(fsqrt);
 FLOATFUNC(fsqrts);
@@ -97,6 +99,7 @@ FLOATFUNC(fsqrts);
 #define FSQRTS		0x016		/*   22 */
 #define FRES		0x018		/*   24 */
 #define FMULS		0x019		/*   25 */
+#define FRSQRTES	0x01a		/*   26 */
 #define FMSUBS		0x01c		/*   28 */
 #define FMADDS		0x01d		/*   29 */
 #define FNMSUBS		0x01e		/*   30 */
@@ -109,6 +112,7 @@ FLOATFUNC(fsqrts);
 #define FADD		0x015		/*   21 */
 #define FSQRT		0x016		/*   22 */
 #define FSEL		0x017		/*   23 */
+#define FRE		0x018		/*   24 */
 #define FMUL		0x019		/*   25 */
 #define FRSQRTE		0x01a		/*   26 */
 #define FMSUB		0x01c		/*   28 */
@@ -299,9 +303,10 @@ do_mathemu(struct pt_regs *regs)
 		case FDIVS:	func = fdivs;	type = AB;	break;
 		case FSUBS:	func = fsubs;	type = AB;	break;
 		case FADDS:	func = fadds;	type = AB;	break;
-		case FSQRTS:	func = fsqrts;	type = AB;	break;
-		case FRES:	func = fres;	type = AB;	break;
+		case FSQRTS:	func = fsqrts;	type = XB;	break;
+		case FRES:	func = fres;	type = XB;	break;
 		case FMULS:	func = fmuls;	type = AC;	break;
+		case FRSQRTES:	func = frsqrtes;type = XB;	break;
 		case FMSUBS:	func = fmsubs;	type = ABC;	break;
 		case FMADDS:	func = fmadds;	type = ABC;	break;
 		case FNMSUBS:	func = fnmsubs;	type = ABC;	break;
@@ -317,10 +322,11 @@ do_mathemu(struct pt_regs *regs)
 			case FDIV:	func = fdiv;	type = AB;	break;
 			case FSUB:	func = fsub;	type = AB;	break;
 			case FADD:	func = fadd;	type = AB;	break;
-			case FSQRT:	func = fsqrt;	type = AB;	break;
+			case FSQRT:	func = fsqrt;	type = XB;	break;
+			case FRE:	func = fre;	type = XB;	break;
 			case FSEL:	func = fsel;	type = ABC;	break;
 			case FMUL:	func = fmul;	type = AC;	break;
-			case FRSQRTE:	func = frsqrte;	type = AB;	break;
+			case FRSQRTE:	func = frsqrte;	type = XB;	break;
 			case FMSUB:	func = fmsub;	type = ABC;	break;
 			case FMADD:	func = fmadd;	type = ABC;	break;
 			case FNMSUB:	func = fnmsub;	type = ABC;	break;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/44x_mmu.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/44x_mmu.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/44x_mmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/44x_mmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,7 +41,7 @@ int icache_44x_need_flush;
 
 unsigned long tlb_47x_boltmap[1024/8];
 
-static void __cpuinit ppc44x_update_tlb_hwater(void)
+static void ppc44x_update_tlb_hwater(void)
 {
 	extern unsigned int tlb_44x_patch_hwater_D[];
 	extern unsigned int tlb_44x_patch_hwater_I[];
@@ -134,7 +134,7 @@ static void __init ppc47x_update_boltmap
 /*
  * "Pins" a 256MB TLB entry in AS0 for kernel lowmem for 47x type MMU
  */
-static void __cpuinit ppc47x_pin_tlb(unsigned int virt, unsigned int phys)
+static void ppc47x_pin_tlb(unsigned int virt, unsigned int phys)
 {
 	unsigned int rA;
 	int bolted;
@@ -229,7 +229,7 @@ void setup_initial_memory_limit(phys_add
 }
 
 #ifdef CONFIG_SMP
-void __cpuinit mmu_init_secondary(int cpu)
+void mmu_init_secondary(int cpu)
 {
 	unsigned long addr;
 	unsigned long memstart = memstart_addr & ~(PPC_PIN_SIZE - 1);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/gup.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/gup.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/gup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/gup.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,7 +34,7 @@ static noinline int gup_pte_range(pmd_t
 
 	ptep = pte_offset_kernel(&pmd, addr);
 	do {
-		pte_t pte = *ptep;
+		pte_t pte = ACCESS_ONCE(*ptep);
 		struct page *page;
 
 		if ((pte_val(pte) & mask) != result)
@@ -63,12 +63,18 @@ static int gup_pmd_range(pud_t pud, unsi
 
 	pmdp = pmd_offset(&pud, addr);
 	do {
-		pmd_t pmd = *pmdp;
+		pmd_t pmd = ACCESS_ONCE(*pmdp);
 
 		next = pmd_addr_end(addr, end);
-		if (pmd_none(pmd))
+		/*
+		 * If we find a splitting transparent hugepage we
+		 * return zero. That will result in taking the slow
+		 * path which will call wait_split_huge_page()
+		 * if the pmd is still in splitting state
+		 */
+		if (pmd_none(pmd) || pmd_trans_splitting(pmd))
 			return 0;
-		if (pmd_huge(pmd)) {
+		if (pmd_huge(pmd) || pmd_large(pmd)) {
 			if (!gup_hugepte((pte_t *)pmdp, PMD_SIZE, addr, next,
 					 write, pages, nr))
 				return 0;
@@ -91,7 +97,7 @@ static int gup_pud_range(pgd_t pgd, unsi
 
 	pudp = pud_offset(&pgd, addr);
 	do {
-		pud_t pud = *pudp;
+		pud_t pud = ACCESS_ONCE(*pudp);
 
 		next = pud_addr_end(addr, end);
 		if (pud_none(pud))
@@ -154,7 +160,7 @@ int get_user_pages_fast(unsigned long st
 
 	pgdp = pgd_offset(mm, addr);
 	do {
-		pgd_t pgd = *pgdp;
+		pgd_t pgd = ACCESS_ONCE(*pgdp);
 
 		pr_devel("  %016lx: normal pgd %p\n", addr,
 			 (void *)pgd_val(pgd));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/hash_low_64.S linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hash_low_64.S
--- linux-libre-3.10-gnu/arch/powerpc/mm/hash_low_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hash_low_64.S	2013-08-25 20:43:22.000000000 -0400
@@ -289,9 +289,10 @@ htab_modify_pte:
 
 	/* Call ppc_md.hpte_updatepp */
 	mr	r5,r29			/* vpn */
-	li	r6,MMU_PAGE_4K		/* page size */
-	ld	r7,STK_PARAM(R9)(r1)	/* segment size */
-	ld	r8,STK_PARAM(R8)(r1)	/* get "local" param */
+	li	r6,MMU_PAGE_4K		/* base page size */
+	li	r7,MMU_PAGE_4K		/* actual page size */
+	ld	r8,STK_PARAM(R9)(r1)	/* segment size */
+	ld	r9,STK_PARAM(R8)(r1)	/* get "local" param */
 _GLOBAL(htab_call_hpte_updatepp)
 	bl	.			/* Patched by htab_finish_init() */
 
@@ -649,9 +650,10 @@ htab_modify_pte:
 
 	/* Call ppc_md.hpte_updatepp */
 	mr	r5,r29			/* vpn */
-	li	r6,MMU_PAGE_4K		/* page size */
-	ld	r7,STK_PARAM(R9)(r1)	/* segment size */
-	ld	r8,STK_PARAM(R8)(r1)	/* get "local" param */
+	li	r6,MMU_PAGE_4K		/* base page size */
+	li	r7,MMU_PAGE_4K		/* actual page size */
+	ld	r8,STK_PARAM(R9)(r1)	/* segment size */
+	ld	r9,STK_PARAM(R8)(r1)	/* get "local" param */
 _GLOBAL(htab_call_hpte_updatepp)
 	bl	.			/* patched by htab_finish_init() */
 
@@ -937,9 +939,10 @@ ht64_modify_pte:
 
 	/* Call ppc_md.hpte_updatepp */
 	mr	r5,r29			/* vpn */
-	li	r6,MMU_PAGE_64K
-	ld	r7,STK_PARAM(R9)(r1)	/* segment size */
-	ld	r8,STK_PARAM(R8)(r1)	/* get "local" param */
+	li	r6,MMU_PAGE_64K		/* base page size */
+	li	r7,MMU_PAGE_64K		/* actual page size */
+	ld	r8,STK_PARAM(R9)(r1)	/* segment size */
+	ld	r9,STK_PARAM(R8)(r1)	/* get "local" param */
 _GLOBAL(ht64_call_hpte_updatepp)
 	bl	.			/* patched by htab_finish_init() */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/hash_native_64.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hash_native_64.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/hash_native_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hash_native_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,6 +43,7 @@ static inline void __tlbie(unsigned long
 {
 	unsigned long va;
 	unsigned int penc;
+	unsigned long sllp;
 
 	/*
 	 * We need 14 to 65 bits of va for a tlibe of 4K page
@@ -64,7 +65,9 @@ static inline void __tlbie(unsigned long
 		/* clear out bits after (52) [0....52.....63] */
 		va &= ~((1ul << (64 - 52)) - 1);
 		va |= ssize << 8;
-		va |= mmu_psize_defs[apsize].sllp << 6;
+		sllp = ((mmu_psize_defs[apsize].sllp & SLB_VSID_L) >> 6) |
+			((mmu_psize_defs[apsize].sllp & SLB_VSID_LP) >> 4);
+		va |= sllp << 5;
 		asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2)
 			     : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
 			     : "memory");
@@ -98,6 +101,7 @@ static inline void __tlbiel(unsigned lon
 {
 	unsigned long va;
 	unsigned int penc;
+	unsigned long sllp;
 
 	/* VPN_SHIFT can be atmost 12 */
 	va = vpn << VPN_SHIFT;
@@ -113,7 +117,9 @@ static inline void __tlbiel(unsigned lon
 		/* clear out bits after(52) [0....52.....63] */
 		va &= ~((1ul << (64 - 52)) - 1);
 		va |= ssize << 8;
-		va |= mmu_psize_defs[apsize].sllp << 6;
+		sllp = ((mmu_psize_defs[apsize].sllp & SLB_VSID_L) >> 6) |
+			((mmu_psize_defs[apsize].sllp & SLB_VSID_LP) >> 4);
+		va |= sllp << 5;
 		asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)"
 			     : : "r"(va) : "memory");
 		break;
@@ -273,61 +279,15 @@ static long native_hpte_remove(unsigned
 	return i;
 }
 
-static inline int __hpte_actual_psize(unsigned int lp, int psize)
-{
-	int i, shift;
-	unsigned int mask;
-
-	/* start from 1 ignoring MMU_PAGE_4K */
-	for (i = 1; i < MMU_PAGE_COUNT; i++) {
-
-		/* invalid penc */
-		if (mmu_psize_defs[psize].penc[i] == -1)
-			continue;
-		/*
-		 * encoding bits per actual page size
-		 *        PTE LP     actual page size
-		 *    rrrr rrrz		>=8KB
-		 *    rrrr rrzz		>=16KB
-		 *    rrrr rzzz		>=32KB
-		 *    rrrr zzzz		>=64KB
-		 * .......
-		 */
-		shift = mmu_psize_defs[i].shift - LP_SHIFT;
-		if (shift > LP_BITS)
-			shift = LP_BITS;
-		mask = (1 << shift) - 1;
-		if ((lp & mask) == mmu_psize_defs[psize].penc[i])
-			return i;
-	}
-	return -1;
-}
-
-static inline int hpte_actual_psize(struct hash_pte *hptep, int psize)
-{
-	/* Look at the 8 bit LP value */
-	unsigned int lp = (hptep->r >> LP_SHIFT) & ((1 << LP_BITS) - 1);
-
-	if (!(hptep->v & HPTE_V_VALID))
-		return -1;
-
-	/* First check if it is large page */
-	if (!(hptep->v & HPTE_V_LARGE))
-		return MMU_PAGE_4K;
-
-	return __hpte_actual_psize(lp, psize);
-}
-
 static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
-				 unsigned long vpn, int psize, int ssize,
-				 int local)
+				 unsigned long vpn, int bpsize,
+				 int apsize, int ssize, int local)
 {
 	struct hash_pte *hptep = htab_address + slot;
 	unsigned long hpte_v, want_v;
 	int ret = 0;
-	int actual_psize;
 
-	want_v = hpte_encode_avpn(vpn, psize, ssize);
+	want_v = hpte_encode_avpn(vpn, bpsize, ssize);
 
 	DBG_LOW("    update(vpn=%016lx, avpnv=%016lx, group=%lx, newpp=%lx)",
 		vpn, want_v & HPTE_V_AVPN, slot, newpp);
@@ -335,7 +295,6 @@ static long native_hpte_updatepp(unsigne
 	native_lock_hpte(hptep);
 
 	hpte_v = hptep->v;
-	actual_psize = hpte_actual_psize(hptep, psize);
 	/*
 	 * We need to invalidate the TLB always because hpte_remove doesn't do
 	 * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less
@@ -343,12 +302,7 @@ static long native_hpte_updatepp(unsigne
 	 * (hpte_remove) because we assume the old translation is still
 	 * technically "valid".
 	 */
-	if (actual_psize < 0) {
-		actual_psize = psize;
-		ret = -1;
-		goto err_out;
-	}
-	if (!HPTE_V_COMPARE(hpte_v, want_v)) {
+	if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) {
 		DBG_LOW(" -> miss\n");
 		ret = -1;
 	} else {
@@ -357,11 +311,10 @@ static long native_hpte_updatepp(unsigne
 		hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
 			(newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C));
 	}
-err_out:
 	native_unlock_hpte(hptep);
 
 	/* Ensure it is out of the tlb too. */
-	tlbie(vpn, psize, actual_psize, ssize, local);
+	tlbie(vpn, bpsize, apsize, ssize, local);
 
 	return ret;
 }
@@ -402,7 +355,6 @@ static long native_hpte_find(unsigned lo
 static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
 				       int psize, int ssize)
 {
-	int actual_psize;
 	unsigned long vpn;
 	unsigned long vsid;
 	long slot;
@@ -415,36 +367,33 @@ static void native_hpte_updateboltedpp(u
 	if (slot == -1)
 		panic("could not find page to bolt\n");
 	hptep = htab_address + slot;
-	actual_psize = hpte_actual_psize(hptep, psize);
-	if (actual_psize < 0)
-		actual_psize = psize;
 
 	/* Update the HPTE */
 	hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
 		(newpp & (HPTE_R_PP | HPTE_R_N));
-
-	/* Ensure it is out of the tlb too. */
-	tlbie(vpn, psize, actual_psize, ssize, 0);
+	/*
+	 * Ensure it is out of the tlb too. Bolted entries base and
+	 * actual page size will be same.
+	 */
+	tlbie(vpn, psize, psize, ssize, 0);
 }
 
 static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
-				   int psize, int ssize, int local)
+				   int bpsize, int apsize, int ssize, int local)
 {
 	struct hash_pte *hptep = htab_address + slot;
 	unsigned long hpte_v;
 	unsigned long want_v;
 	unsigned long flags;
-	int actual_psize;
 
 	local_irq_save(flags);
 
 	DBG_LOW("    invalidate(vpn=%016lx, hash: %lx)\n", vpn, slot);
 
-	want_v = hpte_encode_avpn(vpn, psize, ssize);
+	want_v = hpte_encode_avpn(vpn, bpsize, ssize);
 	native_lock_hpte(hptep);
 	hpte_v = hptep->v;
 
-	actual_psize = hpte_actual_psize(hptep, psize);
 	/*
 	 * We need to invalidate the TLB always because hpte_remove doesn't do
 	 * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less
@@ -452,23 +401,120 @@ static void native_hpte_invalidate(unsig
 	 * (hpte_remove) because we assume the old translation is still
 	 * technically "valid".
 	 */
-	if (actual_psize < 0) {
-		actual_psize = psize;
-		native_unlock_hpte(hptep);
-		goto err_out;
-	}
-	if (!HPTE_V_COMPARE(hpte_v, want_v))
+	if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID))
 		native_unlock_hpte(hptep);
 	else
 		/* Invalidate the hpte. NOTE: this also unlocks it */
 		hptep->v = 0;
 
-err_out:
 	/* Invalidate the TLB */
-	tlbie(vpn, psize, actual_psize, ssize, local);
+	tlbie(vpn, bpsize, apsize, ssize, local);
+
 	local_irq_restore(flags);
 }
 
+static void native_hugepage_invalidate(struct mm_struct *mm,
+				       unsigned char *hpte_slot_array,
+				       unsigned long addr, int psize)
+{
+	int ssize = 0, i;
+	int lock_tlbie;
+	struct hash_pte *hptep;
+	int actual_psize = MMU_PAGE_16M;
+	unsigned int max_hpte_count, valid;
+	unsigned long flags, s_addr = addr;
+	unsigned long hpte_v, want_v, shift;
+	unsigned long hidx, vpn = 0, vsid, hash, slot;
+
+	shift = mmu_psize_defs[psize].shift;
+	max_hpte_count = 1U << (PMD_SHIFT - shift);
+
+	local_irq_save(flags);
+	for (i = 0; i < max_hpte_count; i++) {
+		valid = hpte_valid(hpte_slot_array, i);
+		if (!valid)
+			continue;
+		hidx =  hpte_hash_index(hpte_slot_array, i);
+
+		/* get the vpn */
+		addr = s_addr + (i * (1ul << shift));
+		if (!is_kernel_addr(addr)) {
+			ssize = user_segment_size(addr);
+			vsid = get_vsid(mm->context.id, addr, ssize);
+			WARN_ON(vsid == 0);
+		} else {
+			vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
+			ssize = mmu_kernel_ssize;
+		}
+
+		vpn = hpt_vpn(addr, vsid, ssize);
+		hash = hpt_hash(vpn, shift, ssize);
+		if (hidx & _PTEIDX_SECONDARY)
+			hash = ~hash;
+
+		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+		slot += hidx & _PTEIDX_GROUP_IX;
+
+		hptep = htab_address + slot;
+		want_v = hpte_encode_avpn(vpn, psize, ssize);
+		native_lock_hpte(hptep);
+		hpte_v = hptep->v;
+
+		/* Even if we miss, we need to invalidate the TLB */
+		if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID))
+			native_unlock_hpte(hptep);
+		else
+			/* Invalidate the hpte. NOTE: this also unlocks it */
+			hptep->v = 0;
+	}
+	/*
+	 * Since this is a hugepage, we just need a single tlbie.
+	 * use the last vpn.
+	 */
+	lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+	if (lock_tlbie)
+		raw_spin_lock(&native_tlbie_lock);
+
+	asm volatile("ptesync":::"memory");
+	__tlbie(vpn, psize, actual_psize, ssize);
+	asm volatile("eieio; tlbsync; ptesync":::"memory");
+
+	if (lock_tlbie)
+		raw_spin_unlock(&native_tlbie_lock);
+
+	local_irq_restore(flags);
+}
+
+static inline int __hpte_actual_psize(unsigned int lp, int psize)
+{
+	int i, shift;
+	unsigned int mask;
+
+	/* start from 1 ignoring MMU_PAGE_4K */
+	for (i = 1; i < MMU_PAGE_COUNT; i++) {
+
+		/* invalid penc */
+		if (mmu_psize_defs[psize].penc[i] == -1)
+			continue;
+		/*
+		 * encoding bits per actual page size
+		 *        PTE LP     actual page size
+		 *    rrrr rrrz		>=8KB
+		 *    rrrr rrzz		>=16KB
+		 *    rrrr rzzz		>=32KB
+		 *    rrrr zzzz		>=64KB
+		 * .......
+		 */
+		shift = mmu_psize_defs[i].shift - LP_SHIFT;
+		if (shift > LP_BITS)
+			shift = LP_BITS;
+		mask = (1 << shift) - 1;
+		if ((lp & mask) == mmu_psize_defs[psize].penc[i])
+			return i;
+	}
+	return -1;
+}
+
 static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
 			int *psize, int *apsize, int *ssize, unsigned long *vpn)
 {
@@ -514,6 +560,7 @@ static void hpte_decode(struct hash_pte
 			seg_off |= vpi << shift;
 		}
 		*vpn = vsid << (SID_SHIFT - VPN_SHIFT) | seg_off >> VPN_SHIFT;
+		break;
 	case MMU_SEGSIZE_1T:
 		/* We only have 40 - 23 bits of seg_off in avpn */
 		seg_off = (avpn & 0x1ffff) << 23;
@@ -523,6 +570,7 @@ static void hpte_decode(struct hash_pte
 			seg_off |= vpi << shift;
 		}
 		*vpn = vsid << (SID_SHIFT_1T - VPN_SHIFT) | seg_off >> VPN_SHIFT;
+		break;
 	default:
 		*vpn = size = 0;
 	}
@@ -672,4 +720,5 @@ void __init hpte_init_native(void)
 	ppc_md.hpte_remove	= native_hpte_remove;
 	ppc_md.hpte_clear_all	= native_hpte_clear;
 	ppc_md.flush_hash_range = native_flush_hash_range;
+	ppc_md.hugepage_invalidate   = native_hugepage_invalidate;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/hash_utils_64.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hash_utils_64.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/hash_utils_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hash_utils_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -807,7 +807,7 @@ void __init early_init_mmu(void)
 }
 
 #ifdef CONFIG_SMP
-void __cpuinit early_init_mmu_secondary(void)
+void early_init_mmu_secondary(void)
 {
 	/* Initialize hash table for that CPU */
 	if (!firmware_has_feature(FW_FEATURE_LPAR))
@@ -1050,13 +1050,26 @@ int hash_page(unsigned long ea, unsigned
 		goto bail;
 	}
 
-#ifdef CONFIG_HUGETLB_PAGE
 	if (hugeshift) {
-		rc = __hash_page_huge(ea, access, vsid, ptep, trap, local,
-					ssize, hugeshift, psize);
+		if (pmd_trans_huge(*(pmd_t *)ptep))
+			rc = __hash_page_thp(ea, access, vsid, (pmd_t *)ptep,
+					     trap, local, ssize, psize);
+#ifdef CONFIG_HUGETLB_PAGE
+		else
+			rc = __hash_page_huge(ea, access, vsid, ptep, trap,
+					      local, ssize, hugeshift, psize);
+#else
+		else {
+			/*
+			 * if we have hugeshift, and is not transhuge with
+			 * hugetlb disabled, something is really wrong.
+			 */
+			rc = 1;
+			WARN_ON(1);
+		}
+#endif
 		goto bail;
 	}
-#endif /* CONFIG_HUGETLB_PAGE */
 
 #ifndef CONFIG_PPC_64K_PAGES
 	DBG_LOW(" i-pte: %016lx\n", pte_val(*ptep));
@@ -1145,6 +1158,7 @@ EXPORT_SYMBOL_GPL(hash_page);
 void hash_preload(struct mm_struct *mm, unsigned long ea,
 		  unsigned long access, unsigned long trap)
 {
+	int hugepage_shift;
 	unsigned long vsid;
 	pgd_t *pgdir;
 	pte_t *ptep;
@@ -1166,10 +1180,27 @@ void hash_preload(struct mm_struct *mm,
 	pgdir = mm->pgd;
 	if (pgdir == NULL)
 		return;
-	ptep = find_linux_pte(pgdir, ea);
-	if (!ptep)
+
+	/* Get VSID */
+	ssize = user_segment_size(ea);
+	vsid = get_vsid(mm->context.id, ea, ssize);
+	if (!vsid)
 		return;
+	/*
+	 * Hash doesn't like irqs. Walking linux page table with irq disabled
+	 * saves us from holding multiple locks.
+	 */
+	local_irq_save(flags);
 
+	/*
+	 * THP pages use update_mmu_cache_pmd. We don't do
+	 * hash preload there. Hence can ignore THP here
+	 */
+	ptep = find_linux_pte_or_hugepte(pgdir, ea, &hugepage_shift);
+	if (!ptep)
+		goto out_exit;
+
+	WARN_ON(hugepage_shift);
 #ifdef CONFIG_PPC_64K_PAGES
 	/* If either _PAGE_4K_PFN or _PAGE_NO_CACHE is set (and we are on
 	 * a 64K kernel), then we don't preload, hash_page() will take
@@ -1178,18 +1209,9 @@ void hash_preload(struct mm_struct *mm,
 	 * page size demotion here
 	 */
 	if (pte_val(*ptep) & (_PAGE_4K_PFN | _PAGE_NO_CACHE))
-		return;
+		goto out_exit;
 #endif /* CONFIG_PPC_64K_PAGES */
 
-	/* Get VSID */
-	ssize = user_segment_size(ea);
-	vsid = get_vsid(mm->context.id, ea, ssize);
-	if (!vsid)
-		return;
-
-	/* Hash doesn't like irqs */
-	local_irq_save(flags);
-
 	/* Is that local to this CPU ? */
 	if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
 		local = 1;
@@ -1211,7 +1233,7 @@ void hash_preload(struct mm_struct *mm,
 				   mm->context.user_psize,
 				   mm->context.user_psize,
 				   pte_val(*ptep));
-
+out_exit:
 	local_irq_restore(flags);
 }
 
@@ -1232,7 +1254,11 @@ void flush_hash_page(unsigned long vpn,
 		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		slot += hidx & _PTEIDX_GROUP_IX;
 		DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx);
-		ppc_md.hpte_invalidate(slot, vpn, psize, ssize, local);
+		/*
+		 * We use same base page size and actual psize, because we don't
+		 * use these functions for hugepage
+		 */
+		ppc_md.hpte_invalidate(slot, vpn, psize, psize, ssize, local);
 	} pte_iterate_hashed_end();
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
@@ -1365,7 +1391,8 @@ static void kernel_unmap_linear_page(uns
 		hash = ~hash;
 	slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 	slot += hidx & _PTEIDX_GROUP_IX;
-	ppc_md.hpte_invalidate(slot, vpn, mmu_linear_psize, mmu_kernel_ssize, 0);
+	ppc_md.hpte_invalidate(slot, vpn, mmu_linear_psize, mmu_linear_psize,
+			       mmu_kernel_ssize, 0);
 }
 
 void kernel_map_pages(struct page *page, int numpages, int enable)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/hugepage-hash64.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hugepage-hash64.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/hugepage-hash64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hugepage-hash64.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,175 @@
+/*
+ * Copyright IBM Corporation, 2013
+ * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+/*
+ * PPC64 THP Support for hash based MMUs
+ */
+#include <linux/mm.h>
+#include <asm/machdep.h>
+
+int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
+		    pmd_t *pmdp, unsigned long trap, int local, int ssize,
+		    unsigned int psize)
+{
+	unsigned int index, valid;
+	unsigned char *hpte_slot_array;
+	unsigned long rflags, pa, hidx;
+	unsigned long old_pmd, new_pmd;
+	int ret, lpsize = MMU_PAGE_16M;
+	unsigned long vpn, hash, shift, slot;
+
+	/*
+	 * atomically mark the linux large page PMD busy and dirty
+	 */
+	do {
+		old_pmd = pmd_val(*pmdp);
+		/* If PMD busy, retry the access */
+		if (unlikely(old_pmd & _PAGE_BUSY))
+			return 0;
+		/* If PMD is trans splitting retry the access */
+		if (unlikely(old_pmd & _PAGE_SPLITTING))
+			return 0;
+		/* If PMD permissions don't match, take page fault */
+		if (unlikely(access & ~old_pmd))
+			return 1;
+		/*
+		 * Try to lock the PTE, add ACCESSED and DIRTY if it was
+		 * a write access
+		 */
+		new_pmd = old_pmd | _PAGE_BUSY | _PAGE_ACCESSED;
+		if (access & _PAGE_RW)
+			new_pmd |= _PAGE_DIRTY;
+	} while (old_pmd != __cmpxchg_u64((unsigned long *)pmdp,
+					  old_pmd, new_pmd));
+	/*
+	 * PP bits. _PAGE_USER is already PP bit 0x2, so we only
+	 * need to add in 0x1 if it's a read-only user page
+	 */
+	rflags = new_pmd & _PAGE_USER;
+	if ((new_pmd & _PAGE_USER) && !((new_pmd & _PAGE_RW) &&
+					   (new_pmd & _PAGE_DIRTY)))
+		rflags |= 0x1;
+	/*
+	 * _PAGE_EXEC -> HW_NO_EXEC since it's inverted
+	 */
+	rflags |= ((new_pmd & _PAGE_EXEC) ? 0 : HPTE_R_N);
+
+#if 0
+	if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
+
+		/*
+		 * No CPU has hugepages but lacks no execute, so we
+		 * don't need to worry about that case
+		 */
+		rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
+	}
+#endif
+	/*
+	 * Find the slot index details for this ea, using base page size.
+	 */
+	shift = mmu_psize_defs[psize].shift;
+	index = (ea & ~HPAGE_PMD_MASK) >> shift;
+	BUG_ON(index >= 4096);
+
+	vpn = hpt_vpn(ea, vsid, ssize);
+	hash = hpt_hash(vpn, shift, ssize);
+	hpte_slot_array = get_hpte_slot_array(pmdp);
+
+	valid = hpte_valid(hpte_slot_array, index);
+	if (valid) {
+		/* update the hpte bits */
+		hidx =  hpte_hash_index(hpte_slot_array, index);
+		if (hidx & _PTEIDX_SECONDARY)
+			hash = ~hash;
+		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+		slot += hidx & _PTEIDX_GROUP_IX;
+
+		ret = ppc_md.hpte_updatepp(slot, rflags, vpn,
+					   psize, lpsize, ssize, local);
+		/*
+		 * We failed to update, try to insert a new entry.
+		 */
+		if (ret == -1) {
+			/*
+			 * large pte is marked busy, so we can be sure
+			 * nobody is looking at hpte_slot_array. hence we can
+			 * safely update this here.
+			 */
+			valid = 0;
+			new_pmd &= ~_PAGE_HPTEFLAGS;
+			hpte_slot_array[index] = 0;
+		} else
+			/* clear the busy bits and set the hash pte bits */
+			new_pmd = (new_pmd & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
+	}
+
+	if (!valid) {
+		unsigned long hpte_group;
+
+		/* insert new entry */
+		pa = pmd_pfn(__pmd(old_pmd)) << PAGE_SHIFT;
+repeat:
+		hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+
+		/* clear the busy bits and set the hash pte bits */
+		new_pmd = (new_pmd & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
+
+		/* Add in WIMG bits */
+		rflags |= (new_pmd & (_PAGE_WRITETHRU | _PAGE_NO_CACHE |
+				      _PAGE_COHERENT | _PAGE_GUARDED));
+
+		/* Insert into the hash table, primary slot */
+		slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0,
+					  psize, lpsize, ssize);
+		/*
+		 * Primary is full, try the secondary
+		 */
+		if (unlikely(slot == -1)) {
+			hpte_group = ((~hash & htab_hash_mask) *
+				      HPTES_PER_GROUP) & ~0x7UL;
+			slot = ppc_md.hpte_insert(hpte_group, vpn, pa,
+						  rflags, HPTE_V_SECONDARY,
+						  psize, lpsize, ssize);
+			if (slot == -1) {
+				if (mftb() & 0x1)
+					hpte_group = ((hash & htab_hash_mask) *
+						      HPTES_PER_GROUP) & ~0x7UL;
+
+				ppc_md.hpte_remove(hpte_group);
+				goto repeat;
+			}
+		}
+		/*
+		 * Hypervisor failure. Restore old pmd and return -1
+		 * similar to __hash_page_*
+		 */
+		if (unlikely(slot == -2)) {
+			*pmdp = __pmd(old_pmd);
+			hash_failure_debug(ea, access, vsid, trap, ssize,
+					   psize, lpsize, old_pmd);
+			return -1;
+		}
+		/*
+		 * large pte is marked busy, so we can be sure
+		 * nobody is looking at hpte_slot_array. hence we can
+		 * safely update this here.
+		 */
+		mark_hpte_slot_valid(hpte_slot_array, index, slot);
+	}
+	/*
+	 * No need to use ldarx/stdcx here
+	 */
+	*pmdp = __pmd(new_pmd & ~_PAGE_BUSY);
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/hugetlbpage.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hugetlbpage.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/hugetlbpage.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hugetlbpage.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,9 @@
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
 #include <asm/setup.h>
+#include <asm/hugetlb.h>
+
+#ifdef CONFIG_HUGETLB_PAGE
 
 #define PAGE_SHIFT_64K	16
 #define PAGE_SHIFT_16M	24
@@ -100,68 +103,9 @@ int pgd_huge(pgd_t pgd)
 }
 #endif
 
-/*
- * We have 4 cases for pgds and pmds:
- * (1) invalid (all zeroes)
- * (2) pointer to next table, as normal; bottom 6 bits == 0
- * (3) leaf pte for huge page, bottom two bits != 00
- * (4) hugepd pointer, bottom two bits == 00, next 4 bits indicate size of table
- */
-pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift)
-{
-	pgd_t *pg;
-	pud_t *pu;
-	pmd_t *pm;
-	pte_t *ret_pte;
-	hugepd_t *hpdp = NULL;
-	unsigned pdshift = PGDIR_SHIFT;
-
-	if (shift)
-		*shift = 0;
-
-	pg = pgdir + pgd_index(ea);
-
-	if (pgd_huge(*pg)) {
-		ret_pte = (pte_t *) pg;
-		goto out;
-	} else if (is_hugepd(pg))
-		hpdp = (hugepd_t *)pg;
-	else if (!pgd_none(*pg)) {
-		pdshift = PUD_SHIFT;
-		pu = pud_offset(pg, ea);
-
-		if (pud_huge(*pu)) {
-			ret_pte = (pte_t *) pu;
-			goto out;
-		} else if (is_hugepd(pu))
-			hpdp = (hugepd_t *)pu;
-		else if (!pud_none(*pu)) {
-			pdshift = PMD_SHIFT;
-			pm = pmd_offset(pu, ea);
-
-			if (pmd_huge(*pm)) {
-				ret_pte = (pte_t *) pm;
-				goto out;
-			} else if (is_hugepd(pm))
-				hpdp = (hugepd_t *)pm;
-			else if (!pmd_none(*pm))
-				return pte_offset_kernel(pm, ea);
-		}
-	}
-	if (!hpdp)
-		return NULL;
-
-	ret_pte = hugepte_offset(hpdp, ea, pdshift);
-	pdshift = hugepd_shift(*hpdp);
-out:
-	if (shift)
-		*shift = pdshift;
-	return ret_pte;
-}
-EXPORT_SYMBOL_GPL(find_linux_pte_or_hugepte);
-
 pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
+	/* Only called for hugetlbfs pages, hence can ignore THP */
 	return find_linux_pte_or_hugepte(mm->pgd, addr, NULL);
 }
 
@@ -357,7 +301,7 @@ void add_gpage(u64 addr, u64 page_size,
 int alloc_bootmem_huge_page(struct hstate *hstate)
 {
 	struct huge_bootmem_page *m;
-	int idx = shift_to_mmu_psize(hstate->order + PAGE_SHIFT);
+	int idx = shift_to_mmu_psize(huge_page_shift(hstate));
 	int nr_gpages = gpage_freearray[idx].nr_gpages;
 
 	if (nr_gpages == 0)
@@ -736,11 +680,14 @@ follow_huge_addr(struct mm_struct *mm, u
 	struct page *page;
 	unsigned shift;
 	unsigned long mask;
-
+	/*
+	 * Transparent hugepages are handled by generic code. We can skip them
+	 * here.
+	 */
 	ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift);
 
 	/* Verify it is a huge page else bail. */
-	if (!ptep || !shift)
+	if (!ptep || !shift || pmd_trans_huge(*(pmd_t *)ptep))
 		return ERR_PTR(-EINVAL);
 
 	mask = (1UL << shift) - 1;
@@ -759,69 +706,6 @@ follow_huge_pmd(struct mm_struct *mm, un
 	return NULL;
 }
 
-int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
-		unsigned long end, int write, struct page **pages, int *nr)
-{
-	unsigned long mask;
-	unsigned long pte_end;
-	struct page *head, *page, *tail;
-	pte_t pte;
-	int refs;
-
-	pte_end = (addr + sz) & ~(sz-1);
-	if (pte_end < end)
-		end = pte_end;
-
-	pte = *ptep;
-	mask = _PAGE_PRESENT | _PAGE_USER;
-	if (write)
-		mask |= _PAGE_RW;
-
-	if ((pte_val(pte) & mask) != mask)
-		return 0;
-
-	/* hugepages are never "special" */
-	VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
-
-	refs = 0;
-	head = pte_page(pte);
-
-	page = head + ((addr & (sz-1)) >> PAGE_SHIFT);
-	tail = page;
-	do {
-		VM_BUG_ON(compound_head(page) != head);
-		pages[*nr] = page;
-		(*nr)++;
-		page++;
-		refs++;
-	} while (addr += PAGE_SIZE, addr != end);
-
-	if (!page_cache_add_speculative(head, refs)) {
-		*nr -= refs;
-		return 0;
-	}
-
-	if (unlikely(pte_val(pte) != pte_val(*ptep))) {
-		/* Could be optimized better */
-		*nr -= refs;
-		while (refs--)
-			put_page(head);
-		return 0;
-	}
-
-	/*
-	 * Any tail page need their mapcount reference taken before we
-	 * return.
-	 */
-	while (refs--) {
-		if (PageTail(tail))
-			get_huge_page_tail(tail);
-		tail++;
-	}
-
-	return 1;
-}
-
 static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
 				      unsigned long sz)
 {
@@ -1038,3 +922,168 @@ void flush_dcache_icache_hugepage(struct
 		}
 	}
 }
+
+#endif /* CONFIG_HUGETLB_PAGE */
+
+/*
+ * We have 4 cases for pgds and pmds:
+ * (1) invalid (all zeroes)
+ * (2) pointer to next table, as normal; bottom 6 bits == 0
+ * (3) leaf pte for huge page, bottom two bits != 00
+ * (4) hugepd pointer, bottom two bits == 00, next 4 bits indicate size of table
+ *
+ * So long as we atomically load page table pointers we are safe against teardown,
+ * we can follow the address down to the the page and take a ref on it.
+ */
+
+pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift)
+{
+	pgd_t pgd, *pgdp;
+	pud_t pud, *pudp;
+	pmd_t pmd, *pmdp;
+	pte_t *ret_pte;
+	hugepd_t *hpdp = NULL;
+	unsigned pdshift = PGDIR_SHIFT;
+
+	if (shift)
+		*shift = 0;
+
+	pgdp = pgdir + pgd_index(ea);
+	pgd  = ACCESS_ONCE(*pgdp);
+	/*
+	 * Always operate on the local stack value. This make sure the
+	 * value don't get updated by a parallel THP split/collapse,
+	 * page fault or a page unmap. The return pte_t * is still not
+	 * stable. So should be checked there for above conditions.
+	 */
+	if (pgd_none(pgd))
+		return NULL;
+	else if (pgd_huge(pgd)) {
+		ret_pte = (pte_t *) pgdp;
+		goto out;
+	} else if (is_hugepd(&pgd))
+		hpdp = (hugepd_t *)&pgd;
+	else {
+		/*
+		 * Even if we end up with an unmap, the pgtable will not
+		 * be freed, because we do an rcu free and here we are
+		 * irq disabled
+		 */
+		pdshift = PUD_SHIFT;
+		pudp = pud_offset(&pgd, ea);
+		pud  = ACCESS_ONCE(*pudp);
+
+		if (pud_none(pud))
+			return NULL;
+		else if (pud_huge(pud)) {
+			ret_pte = (pte_t *) pudp;
+			goto out;
+		} else if (is_hugepd(&pud))
+			hpdp = (hugepd_t *)&pud;
+		else {
+			pdshift = PMD_SHIFT;
+			pmdp = pmd_offset(&pud, ea);
+			pmd  = ACCESS_ONCE(*pmdp);
+			/*
+			 * A hugepage collapse is captured by pmd_none, because
+			 * it mark the pmd none and do a hpte invalidate.
+			 *
+			 * A hugepage split is captured by pmd_trans_splitting
+			 * because we mark the pmd trans splitting and do a
+			 * hpte invalidate
+			 *
+			 */
+			if (pmd_none(pmd) || pmd_trans_splitting(pmd))
+				return NULL;
+
+			if (pmd_huge(pmd) || pmd_large(pmd)) {
+				ret_pte = (pte_t *) pmdp;
+				goto out;
+			} else if (is_hugepd(&pmd))
+				hpdp = (hugepd_t *)&pmd;
+			else
+				return pte_offset_kernel(&pmd, ea);
+		}
+	}
+	if (!hpdp)
+		return NULL;
+
+	ret_pte = hugepte_offset(hpdp, ea, pdshift);
+	pdshift = hugepd_shift(*hpdp);
+out:
+	if (shift)
+		*shift = pdshift;
+	return ret_pte;
+}
+EXPORT_SYMBOL_GPL(find_linux_pte_or_hugepte);
+
+int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
+		unsigned long end, int write, struct page **pages, int *nr)
+{
+	unsigned long mask;
+	unsigned long pte_end;
+	struct page *head, *page, *tail;
+	pte_t pte;
+	int refs;
+
+	pte_end = (addr + sz) & ~(sz-1);
+	if (pte_end < end)
+		end = pte_end;
+
+	pte = ACCESS_ONCE(*ptep);
+	mask = _PAGE_PRESENT | _PAGE_USER;
+	if (write)
+		mask |= _PAGE_RW;
+
+	if ((pte_val(pte) & mask) != mask)
+		return 0;
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	/*
+	 * check for splitting here
+	 */
+	if (pmd_trans_splitting(pte_pmd(pte)))
+		return 0;
+#endif
+
+	/* hugepages are never "special" */
+	VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+
+	refs = 0;
+	head = pte_page(pte);
+
+	page = head + ((addr & (sz-1)) >> PAGE_SHIFT);
+	tail = page;
+	do {
+		VM_BUG_ON(compound_head(page) != head);
+		pages[*nr] = page;
+		(*nr)++;
+		page++;
+		refs++;
+	} while (addr += PAGE_SIZE, addr != end);
+
+	if (!page_cache_add_speculative(head, refs)) {
+		*nr -= refs;
+		return 0;
+	}
+
+	if (unlikely(pte_val(pte) != pte_val(*ptep))) {
+		/* Could be optimized better */
+		*nr -= refs;
+		while (refs--)
+			put_page(head);
+		return 0;
+	}
+
+	/*
+	 * Any tail page need their mapcount reference taken before we
+	 * return.
+	 */
+	while (refs--) {
+		if (PageTail(tail))
+			get_huge_page_tail(tail);
+		tail++;
+	}
+
+	return 1;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/hugetlbpage-hash64.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hugetlbpage-hash64.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/hugetlbpage-hash64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/hugetlbpage-hash64.c	2013-08-25 20:43:22.000000000 -0400
@@ -81,7 +81,7 @@ int __hash_page_huge(unsigned long ea, u
 		slot += (old_pte & _PAGE_F_GIX) >> 12;
 
 		if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize,
-					 ssize, local) == -1)
+					 mmu_psize, ssize, local) == -1)
 			old_pte &= ~_PAGE_HPTEFLAGS;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/init_64.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/init_64.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/init_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/init_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,7 +88,11 @@ static void pgd_ctor(void *addr)
 
 static void pmd_ctor(void *addr)
 {
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	memset(addr, 0, PMD_TABLE_SIZE * 2);
+#else
 	memset(addr, 0, PMD_TABLE_SIZE);
+#endif
 }
 
 struct kmem_cache *pgtable_cache[MAX_PGTABLE_INDEX_SIZE];
@@ -137,10 +141,9 @@ void pgtable_cache_add(unsigned shift, v
 void pgtable_cache_init(void)
 {
 	pgtable_cache_add(PGD_INDEX_SIZE, pgd_ctor);
-	pgtable_cache_add(PMD_INDEX_SIZE, pmd_ctor);
-	if (!PGT_CACHE(PGD_INDEX_SIZE) || !PGT_CACHE(PMD_INDEX_SIZE))
+	pgtable_cache_add(PMD_CACHE_INDEX, pmd_ctor);
+	if (!PGT_CACHE(PGD_INDEX_SIZE) || !PGT_CACHE(PMD_CACHE_INDEX))
 		panic("Couldn't allocate pgtable caches");
-
 	/* In all current configs, when the PUD index exists it's the
 	 * same size as either the pgd or pmd index.  Verify that the
 	 * initialization above has also created a PUD cache.  This
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/Makefile linux-libre-3.11-rc7-gnu/arch/powerpc/mm/Makefile
--- linux-libre-3.10-gnu/arch/powerpc/mm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -6,17 +6,16 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -
 
 ccflags-$(CONFIG_PPC64)	:= $(NO_MINIMAL_TOC)
 
-obj-y				:= fault.o mem.o pgtable.o gup.o \
+obj-y				:= fault.o mem.o pgtable.o gup.o mmap.o \
 				   init_$(CONFIG_WORD_SIZE).o \
 				   pgtable_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_PPC_MMU_NOHASH)	+= mmu_context_nohash.o tlb_nohash.o \
 				   tlb_nohash_low.o
 obj-$(CONFIG_PPC_BOOK3E)	+= tlb_low_$(CONFIG_WORD_SIZE)e.o
-obj-$(CONFIG_PPC64)		+= mmap_64.o
 hash64-$(CONFIG_PPC_NATIVE)	:= hash_native_64.o
 obj-$(CONFIG_PPC_STD_MMU_64)	+= hash_utils_64.o \
 				   slb_low.o slb.o stab.o \
-				   mmap_64.o $(hash64-y)
+				   $(hash64-y)
 obj-$(CONFIG_PPC_STD_MMU_32)	+= ppc_mmu_32.o
 obj-$(CONFIG_PPC_STD_MMU)	+= hash_low_$(CONFIG_WORD_SIZE).o \
 				   tlb_hash$(CONFIG_WORD_SIZE).o \
@@ -28,11 +27,12 @@ obj-$(CONFIG_44x)		+= 44x_mmu.o
 obj-$(CONFIG_PPC_FSL_BOOK3E)	+= fsl_booke_mmu.o
 obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
 obj-$(CONFIG_PPC_MM_SLICES)	+= slice.o
-ifeq ($(CONFIG_HUGETLB_PAGE),y)
 obj-y				+= hugetlbpage.o
+ifeq ($(CONFIG_HUGETLB_PAGE),y)
 obj-$(CONFIG_PPC_STD_MMU_64)	+= hugetlbpage-hash64.o
 obj-$(CONFIG_PPC_BOOK3E_MMU)	+= hugetlbpage-book3e.o
 endif
+obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += hugepage-hash64.o
 obj-$(CONFIG_PPC_SUBPAGE_PROT)	+= subpage-prot.o
 obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
 obj-$(CONFIG_HIGHMEM)		+= highmem.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/mem.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/mem.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/mem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/mem.c	2013-08-25 20:43:22.000000000 -0400
@@ -299,47 +299,13 @@ void __init paging_init(void)
 
 void __init mem_init(void)
 {
-#ifdef CONFIG_NEED_MULTIPLE_NODES
-	int nid;
-#endif
-	pg_data_t *pgdat;
-	unsigned long i;
-	struct page *page;
-	unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
-
 #ifdef CONFIG_SWIOTLB
 	swiotlb_init(0);
 #endif
 
-	num_physpages = memblock_phys_mem_size() >> PAGE_SHIFT;
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
-
-#ifdef CONFIG_NEED_MULTIPLE_NODES
-        for_each_online_node(nid) {
-		if (NODE_DATA(nid)->node_spanned_pages != 0) {
-			printk("freeing bootmem node %d\n", nid);
-			totalram_pages +=
-				free_all_bootmem_node(NODE_DATA(nid));
-		}
-	}
-#else
-	max_mapnr = max_pfn;
-	totalram_pages += free_all_bootmem();
-#endif
-	for_each_online_pgdat(pgdat) {
-		for (i = 0; i < pgdat->node_spanned_pages; i++) {
-			if (!pfn_valid(pgdat->node_start_pfn + i))
-				continue;
-			page = pgdat_page_nr(pgdat, i);
-			if (PageReserved(page))
-				reservedpages++;
-		}
-	}
-
-	codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
-	datasize = (unsigned long)&_edata - (unsigned long)&_sdata;
-	initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
-	bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start;
+	set_max_mapnr(max_pfn);
+	free_all_bootmem();
 
 #ifdef CONFIG_HIGHMEM
 	{
@@ -349,13 +315,9 @@ void __init mem_init(void)
 		for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
 			phys_addr_t paddr = (phys_addr_t)pfn << PAGE_SHIFT;
 			struct page *page = pfn_to_page(pfn);
-			if (memblock_is_reserved(paddr))
-				continue;
-			free_highmem_page(page);
-			reservedpages--;
+			if (!memblock_is_reserved(paddr))
+				free_highmem_page(page);
 		}
-		printk(KERN_DEBUG "High memory: %luk\n",
-		       totalhigh_pages << (PAGE_SHIFT-10));
 	}
 #endif /* CONFIG_HIGHMEM */
 
@@ -368,16 +330,7 @@ void __init mem_init(void)
 		(mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) - 1;
 #endif
 
-	printk(KERN_INFO "Memory: %luk/%luk available (%luk kernel code, "
-	       "%luk reserved, %luk data, %luk bss, %luk init)\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10,
-		reservedpages << (PAGE_SHIFT-10),
-		datasize >> 10,
-		bsssize >> 10,
-		initsize >> 10);
-
+	mem_init_print_info(NULL);
 #ifdef CONFIG_PPC32
 	pr_info("Kernel virtual memory layout:\n");
 	pr_info("  * 0x%08lx..0x%08lx  : fixmap\n", FIXADDR_START, FIXADDR_TOP);
@@ -407,7 +360,7 @@ void free_initmem(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
 
@@ -508,6 +461,10 @@ void update_mmu_cache(struct vm_area_str
 		      pte_t *ptep)
 {
 #ifdef CONFIG_PPC_STD_MMU
+	/*
+	 * We don't need to worry about _PAGE_PRESENT here because we are
+	 * called with either mm->page_table_lock held or ptl lock held
+	 */
 	unsigned long access = 0, trap;
 
 	/* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/mmap_64.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/mmap_64.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/mmap_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/mmap_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,101 +0,0 @@
-/*
- *  flexible mmap layout support
- *
- * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *
- * Started by Ingo Molnar <mingo@elte.hu>
- */
-
-#include <linux/personality.h>
-#include <linux/mm.h>
-#include <linux/random.h>
-#include <linux/sched.h>
-
-/*
- * Top of mmap area (just below the process stack).
- *
- * Leave at least a ~128 MB hole on 32bit applications.
- *
- * On 64bit applications we randomise the stack by 1GB so we need to
- * space our mmap start address by a further 1GB, otherwise there is a
- * chance the mmap area will end up closer to the stack than our ulimit
- * requires.
- */
-#define MIN_GAP32 (128*1024*1024)
-#define MIN_GAP64 ((128 + 1024)*1024*1024UL)
-#define MIN_GAP ((is_32bit_task()) ? MIN_GAP32 : MIN_GAP64)
-#define MAX_GAP (TASK_SIZE/6*5)
-
-static inline int mmap_is_legacy(void)
-{
-	if (current->personality & ADDR_COMPAT_LAYOUT)
-		return 1;
-
-	if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
-		return 1;
-
-	return sysctl_legacy_va_layout;
-}
-
-static unsigned long mmap_rnd(void)
-{
-	unsigned long rnd = 0;
-
-	if (current->flags & PF_RANDOMIZE) {
-		/* 8MB for 32bit, 1GB for 64bit */
-		if (is_32bit_task())
-			rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
-		else
-			rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
-	}
-	return rnd << PAGE_SHIFT;
-}
-
-static inline unsigned long mmap_base(void)
-{
-	unsigned long gap = rlimit(RLIMIT_STACK);
-
-	if (gap < MIN_GAP)
-		gap = MIN_GAP;
-	else if (gap > MAX_GAP)
-		gap = MAX_GAP;
-
-	return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
-}
-
-/*
- * This function, called very early during the creation of a new
- * process VM image, sets up which VM layout function to use:
- */
-void arch_pick_mmap_layout(struct mm_struct *mm)
-{
-	/*
-	 * Fall back to the standard layout if the personality
-	 * bit is set, or if the expected stack growth is unlimited:
-	 */
-	if (mmap_is_legacy()) {
-		mm->mmap_base = TASK_UNMAPPED_BASE;
-		mm->get_unmapped_area = arch_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
-	} else {
-		mm->mmap_base = mmap_base();
-		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
-	}
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/mmap.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/mmap.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/mmap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/mmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,99 @@
+/*
+ *  flexible mmap layout support
+ *
+ * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * Started by Ingo Molnar <mingo@elte.hu>
+ */
+
+#include <linux/personality.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+/*
+ * Top of mmap area (just below the process stack).
+ *
+ * Leave at least a ~128 MB hole on 32bit applications.
+ *
+ * On 64bit applications we randomise the stack by 1GB so we need to
+ * space our mmap start address by a further 1GB, otherwise there is a
+ * chance the mmap area will end up closer to the stack than our ulimit
+ * requires.
+ */
+#define MIN_GAP32 (128*1024*1024)
+#define MIN_GAP64 ((128 + 1024)*1024*1024UL)
+#define MIN_GAP ((is_32bit_task()) ? MIN_GAP32 : MIN_GAP64)
+#define MAX_GAP (TASK_SIZE/6*5)
+
+static inline int mmap_is_legacy(void)
+{
+	if (current->personality & ADDR_COMPAT_LAYOUT)
+		return 1;
+
+	if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)
+		return 1;
+
+	return sysctl_legacy_va_layout;
+}
+
+static unsigned long mmap_rnd(void)
+{
+	unsigned long rnd = 0;
+
+	if (current->flags & PF_RANDOMIZE) {
+		/* 8MB for 32bit, 1GB for 64bit */
+		if (is_32bit_task())
+			rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
+		else
+			rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
+	}
+	return rnd << PAGE_SHIFT;
+}
+
+static inline unsigned long mmap_base(void)
+{
+	unsigned long gap = rlimit(RLIMIT_STACK);
+
+	if (gap < MIN_GAP)
+		gap = MIN_GAP;
+	else if (gap > MAX_GAP)
+		gap = MAX_GAP;
+
+	return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
+}
+
+/*
+ * This function, called very early during the creation of a new
+ * process VM image, sets up which VM layout function to use:
+ */
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+	/*
+	 * Fall back to the standard layout if the personality
+	 * bit is set, or if the expected stack growth is unlimited:
+	 */
+	if (mmap_is_legacy()) {
+		mm->mmap_base = TASK_UNMAPPED_BASE;
+		mm->get_unmapped_area = arch_get_unmapped_area;
+	} else {
+		mm->mmap_base = mmap_base();
+		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/mmu_context_nohash.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/mmu_context_nohash.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/mmu_context_nohash.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/mmu_context_nohash.c	2013-08-25 20:43:22.000000000 -0400
@@ -112,8 +112,10 @@ static unsigned int steal_context_smp(un
 		 */
 		for_each_cpu(cpu, mm_cpumask(mm)) {
 			for (i = cpu_first_thread_sibling(cpu);
-			     i <= cpu_last_thread_sibling(cpu); i++)
-				__set_bit(id, stale_map[i]);
+			     i <= cpu_last_thread_sibling(cpu); i++) {
+				if (stale_map[i])
+					__set_bit(id, stale_map[i]);
+			}
 			cpu = i - 1;
 		}
 		return id;
@@ -272,7 +274,8 @@ void switch_mmu_context(struct mm_struct
 		/* XXX This clear should ultimately be part of local_flush_tlb_mm */
 		for (i = cpu_first_thread_sibling(cpu);
 		     i <= cpu_last_thread_sibling(cpu); i++) {
-			__clear_bit(id, stale_map[i]);
+			if (stale_map[i])
+				__clear_bit(id, stale_map[i]);
 		}
 	}
 
@@ -329,8 +332,8 @@ void destroy_context(struct mm_struct *m
 
 #ifdef CONFIG_SMP
 
-static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
-					    unsigned long action, void *hcpu)
+static int mmu_context_cpu_notify(struct notifier_block *self,
+				  unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned int)(long)hcpu;
 
@@ -363,7 +366,7 @@ static int __cpuinit mmu_context_cpu_not
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata mmu_context_cpu_nb = {
+static struct notifier_block mmu_context_cpu_nb = {
 	.notifier_call	= mmu_context_cpu_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/numa.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/numa.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/numa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/numa.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
+#include <asm/cputhreads.h>
 #include <asm/sparsemem.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
@@ -516,7 +517,7 @@ static int of_drconf_to_nid_single(struc
  * Figure out to which domain a cpu belongs and stick it there.
  * Return the id of the domain used.
  */
-static int __cpuinit numa_setup_cpu(unsigned long lcpu)
+static int numa_setup_cpu(unsigned long lcpu)
 {
 	int nid = 0;
 	struct device_node *cpu = of_get_cpu_node(lcpu, NULL);
@@ -538,8 +539,7 @@ out:
 	return nid;
 }
 
-static int __cpuinit cpu_numa_callback(struct notifier_block *nfb,
-			     unsigned long action,
+static int cpu_numa_callback(struct notifier_block *nfb, unsigned long action,
 			     void *hcpu)
 {
 	unsigned long lcpu = (unsigned long)hcpu;
@@ -919,7 +919,7 @@ static void __init *careful_zallocation(
 	return ret;
 }
 
-static struct notifier_block __cpuinitdata ppc64_numa_nb = {
+static struct notifier_block ppc64_numa_nb = {
 	.notifier_call = cpu_numa_callback,
 	.priority = 1 /* Must run before sched domains notifier. */
 };
@@ -1319,7 +1319,8 @@ static int update_cpu_associativity_chan
 			}
 		}
 		if (changed) {
-			cpumask_set_cpu(cpu, changes);
+			cpumask_or(changes, changes, cpu_sibling_mask(cpu));
+			cpu = cpu_last_thread_sibling(cpu);
 		}
 	}
 
@@ -1427,17 +1428,15 @@ static int update_cpu_topology(void *dat
 	if (!data)
 		return -EINVAL;
 
-	cpu = get_cpu();
+	cpu = smp_processor_id();
 
 	for (update = data; update; update = update->next) {
 		if (cpu != update->cpu)
 			continue;
 
-		unregister_cpu_under_node(update->cpu, update->old_nid);
 		unmap_cpu_from_node(update->cpu);
 		map_cpu_to_node(update->cpu, update->new_nid);
 		vdso_getcpu_init();
-		register_cpu_under_node(update->cpu, update->new_nid);
 	}
 
 	return 0;
@@ -1449,12 +1448,12 @@ static int update_cpu_topology(void *dat
  */
 int arch_update_cpu_topology(void)
 {
-	unsigned int cpu, changed = 0;
+	unsigned int cpu, sibling, changed = 0;
 	struct topology_update_data *updates, *ud;
 	unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};
 	cpumask_t updated_cpus;
 	struct device *dev;
-	int weight, i = 0;
+	int weight, new_nid, i = 0;
 
 	weight = cpumask_weight(&cpu_associativity_changes_mask);
 	if (!weight)
@@ -1467,24 +1466,54 @@ int arch_update_cpu_topology(void)
 	cpumask_clear(&updated_cpus);
 
 	for_each_cpu(cpu, &cpu_associativity_changes_mask) {
-		ud = &updates[i++];
-		ud->cpu = cpu;
-		vphn_get_associativity(cpu, associativity);
-		ud->new_nid = associativity_to_nid(associativity);
+		/*
+		 * If siblings aren't flagged for changes, updates list
+		 * will be too short. Skip on this update and set for next
+		 * update.
+		 */
+		if (!cpumask_subset(cpu_sibling_mask(cpu),
+					&cpu_associativity_changes_mask)) {
+			pr_info("Sibling bits not set for associativity "
+					"change, cpu%d\n", cpu);
+			cpumask_or(&cpu_associativity_changes_mask,
+					&cpu_associativity_changes_mask,
+					cpu_sibling_mask(cpu));
+			cpu = cpu_last_thread_sibling(cpu);
+			continue;
+		}
 
-		if (ud->new_nid < 0 || !node_online(ud->new_nid))
-			ud->new_nid = first_online_node;
+		/* Use associativity from first thread for all siblings */
+		vphn_get_associativity(cpu, associativity);
+		new_nid = associativity_to_nid(associativity);
+		if (new_nid < 0 || !node_online(new_nid))
+			new_nid = first_online_node;
 
-		ud->old_nid = numa_cpu_lookup_table[cpu];
-		cpumask_set_cpu(cpu, &updated_cpus);
+		if (new_nid == numa_cpu_lookup_table[cpu]) {
+			cpumask_andnot(&cpu_associativity_changes_mask,
+					&cpu_associativity_changes_mask,
+					cpu_sibling_mask(cpu));
+			cpu = cpu_last_thread_sibling(cpu);
+			continue;
+		}
 
-		if (i < weight)
-			ud->next = &updates[i];
+		for_each_cpu(sibling, cpu_sibling_mask(cpu)) {
+			ud = &updates[i++];
+			ud->cpu = sibling;
+			ud->new_nid = new_nid;
+			ud->old_nid = numa_cpu_lookup_table[sibling];
+			cpumask_set_cpu(sibling, &updated_cpus);
+			if (i < weight)
+				ud->next = &updates[i];
+		}
+		cpu = cpu_last_thread_sibling(cpu);
 	}
 
 	stop_machine(update_cpu_topology, &updates[0], &updated_cpus);
 
 	for (ud = &updates[0]; ud; ud = ud->next) {
+		unregister_cpu_under_node(ud->cpu, ud->old_nid);
+		register_cpu_under_node(ud->cpu, ud->new_nid);
+
 		dev = get_cpu_device(ud->cpu);
 		if (dev)
 			kobject_uevent(&dev->kobj, KOBJ_CHANGE);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/pgtable_64.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/pgtable_64.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/pgtable_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/pgtable_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -338,6 +338,19 @@ EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(__iounmap);
 EXPORT_SYMBOL(__iounmap_at);
 
+/*
+ * For hugepage we have pfn in the pmd, we use PTE_RPN_SHIFT bits for flags
+ * For PTE page, we have a PTE_FRAG_SIZE (4K) aligned virtual address.
+ */
+struct page *pmd_page(pmd_t pmd)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	if (pmd_trans_huge(pmd))
+		return pfn_to_page(pmd_pfn(pmd));
+#endif
+	return virt_to_page(pmd_page_vaddr(pmd));
+}
+
 #ifdef CONFIG_PPC_64K_PAGES
 static pte_t *get_from_cache(struct mm_struct *mm)
 {
@@ -455,3 +468,404 @@ void pgtable_free_tlb(struct mmu_gather
 }
 #endif
 #endif /* CONFIG_PPC_64K_PAGES */
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
+/*
+ * This is called when relaxing access to a hugepage. It's also called in the page
+ * fault path when we don't hit any of the major fault cases, ie, a minor
+ * update of _PAGE_ACCESSED, _PAGE_DIRTY, etc... The generic code will have
+ * handled those two for us, we additionally deal with missing execute
+ * permission here on some processors
+ */
+int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+			  pmd_t *pmdp, pmd_t entry, int dirty)
+{
+	int changed;
+#ifdef CONFIG_DEBUG_VM
+	WARN_ON(!pmd_trans_huge(*pmdp));
+	assert_spin_locked(&vma->vm_mm->page_table_lock);
+#endif
+	changed = !pmd_same(*(pmdp), entry);
+	if (changed) {
+		__ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
+		/*
+		 * Since we are not supporting SW TLB systems, we don't
+		 * have any thing similar to flush_tlb_page_nohash()
+		 */
+	}
+	return changed;
+}
+
+unsigned long pmd_hugepage_update(struct mm_struct *mm, unsigned long addr,
+				  pmd_t *pmdp, unsigned long clr)
+{
+
+	unsigned long old, tmp;
+
+#ifdef CONFIG_DEBUG_VM
+	WARN_ON(!pmd_trans_huge(*pmdp));
+	assert_spin_locked(&mm->page_table_lock);
+#endif
+
+#ifdef PTE_ATOMIC_UPDATES
+	__asm__ __volatile__(
+	"1:	ldarx	%0,0,%3\n\
+		andi.	%1,%0,%6\n\
+		bne-	1b \n\
+		andc	%1,%0,%4 \n\
+		stdcx.	%1,0,%3 \n\
+		bne-	1b"
+	: "=&r" (old), "=&r" (tmp), "=m" (*pmdp)
+	: "r" (pmdp), "r" (clr), "m" (*pmdp), "i" (_PAGE_BUSY)
+	: "cc" );
+#else
+	old = pmd_val(*pmdp);
+	*pmdp = __pmd(old & ~clr);
+#endif
+	if (old & _PAGE_HASHPTE)
+		hpte_do_hugepage_flush(mm, addr, pmdp);
+	return old;
+}
+
+pmd_t pmdp_clear_flush(struct vm_area_struct *vma, unsigned long address,
+		       pmd_t *pmdp)
+{
+	pmd_t pmd;
+
+	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+	if (pmd_trans_huge(*pmdp)) {
+		pmd = pmdp_get_and_clear(vma->vm_mm, address, pmdp);
+	} else {
+		/*
+		 * khugepaged calls this for normal pmd
+		 */
+		pmd = *pmdp;
+		pmd_clear(pmdp);
+		/*
+		 * Wait for all pending hash_page to finish. This is needed
+		 * in case of subpage collapse. When we collapse normal pages
+		 * to hugepage, we first clear the pmd, then invalidate all
+		 * the PTE entries. The assumption here is that any low level
+		 * page fault will see a none pmd and take the slow path that
+		 * will wait on mmap_sem. But we could very well be in a
+		 * hash_page with local ptep pointer value. Such a hash page
+		 * can result in adding new HPTE entries for normal subpages.
+		 * That means we could be modifying the page content as we
+		 * copy them to a huge page. So wait for parallel hash_page
+		 * to finish before invalidating HPTE entries. We can do this
+		 * by sending an IPI to all the cpus and executing a dummy
+		 * function there.
+		 */
+		kick_all_cpus_sync();
+		/*
+		 * Now invalidate the hpte entries in the range
+		 * covered by pmd. This make sure we take a
+		 * fault and will find the pmd as none, which will
+		 * result in a major fault which takes mmap_sem and
+		 * hence wait for collapse to complete. Without this
+		 * the __collapse_huge_page_copy can result in copying
+		 * the old content.
+		 */
+		flush_tlb_pmd_range(vma->vm_mm, &pmd, address);
+	}
+	return pmd;
+}
+
+int pmdp_test_and_clear_young(struct vm_area_struct *vma,
+			      unsigned long address, pmd_t *pmdp)
+{
+	return __pmdp_test_and_clear_young(vma->vm_mm, address, pmdp);
+}
+
+/*
+ * We currently remove entries from the hashtable regardless of whether
+ * the entry was young or dirty. The generic routines only flush if the
+ * entry was young or dirty which is not good enough.
+ *
+ * We should be more intelligent about this but for the moment we override
+ * these functions and force a tlb flush unconditionally
+ */
+int pmdp_clear_flush_young(struct vm_area_struct *vma,
+				  unsigned long address, pmd_t *pmdp)
+{
+	return __pmdp_test_and_clear_young(vma->vm_mm, address, pmdp);
+}
+
+/*
+ * We mark the pmd splitting and invalidate all the hpte
+ * entries for this hugepage.
+ */
+void pmdp_splitting_flush(struct vm_area_struct *vma,
+			  unsigned long address, pmd_t *pmdp)
+{
+	unsigned long old, tmp;
+
+	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+
+#ifdef CONFIG_DEBUG_VM
+	WARN_ON(!pmd_trans_huge(*pmdp));
+	assert_spin_locked(&vma->vm_mm->page_table_lock);
+#endif
+
+#ifdef PTE_ATOMIC_UPDATES
+
+	__asm__ __volatile__(
+	"1:	ldarx	%0,0,%3\n\
+		andi.	%1,%0,%6\n\
+		bne-	1b \n\
+		ori	%1,%0,%4 \n\
+		stdcx.	%1,0,%3 \n\
+		bne-	1b"
+	: "=&r" (old), "=&r" (tmp), "=m" (*pmdp)
+	: "r" (pmdp), "i" (_PAGE_SPLITTING), "m" (*pmdp), "i" (_PAGE_BUSY)
+	: "cc" );
+#else
+	old = pmd_val(*pmdp);
+	*pmdp = __pmd(old | _PAGE_SPLITTING);
+#endif
+	/*
+	 * If we didn't had the splitting flag set, go and flush the
+	 * HPTE entries.
+	 */
+	if (!(old & _PAGE_SPLITTING)) {
+		/* We need to flush the hpte */
+		if (old & _PAGE_HASHPTE)
+			hpte_do_hugepage_flush(vma->vm_mm, address, pmdp);
+	}
+}
+
+/*
+ * We want to put the pgtable in pmd and use pgtable for tracking
+ * the base page size hptes
+ */
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+				pgtable_t pgtable)
+{
+	pgtable_t *pgtable_slot;
+	assert_spin_locked(&mm->page_table_lock);
+	/*
+	 * we store the pgtable in the second half of PMD
+	 */
+	pgtable_slot = (pgtable_t *)pmdp + PTRS_PER_PMD;
+	*pgtable_slot = pgtable;
+	/*
+	 * expose the deposited pgtable to other cpus.
+	 * before we set the hugepage PTE at pmd level
+	 * hash fault code looks at the deposted pgtable
+	 * to store hash index values.
+	 */
+	smp_wmb();
+}
+
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
+{
+	pgtable_t pgtable;
+	pgtable_t *pgtable_slot;
+
+	assert_spin_locked(&mm->page_table_lock);
+	pgtable_slot = (pgtable_t *)pmdp + PTRS_PER_PMD;
+	pgtable = *pgtable_slot;
+	/*
+	 * Once we withdraw, mark the entry NULL.
+	 */
+	*pgtable_slot = NULL;
+	/*
+	 * We store HPTE information in the deposited PTE fragment.
+	 * zero out the content on withdraw.
+	 */
+	memset(pgtable, 0, PTE_FRAG_SIZE);
+	return pgtable;
+}
+
+/*
+ * set a new huge pmd. We should not be called for updating
+ * an existing pmd entry. That should go via pmd_hugepage_update.
+ */
+void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+		pmd_t *pmdp, pmd_t pmd)
+{
+#ifdef CONFIG_DEBUG_VM
+	WARN_ON(!pmd_none(*pmdp));
+	assert_spin_locked(&mm->page_table_lock);
+	WARN_ON(!pmd_trans_huge(pmd));
+#endif
+	return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd));
+}
+
+void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
+		     pmd_t *pmdp)
+{
+	pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT);
+}
+
+/*
+ * A linux hugepage PMD was changed and the corresponding hash table entries
+ * neesd to be flushed.
+ */
+void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
+			    pmd_t *pmdp)
+{
+	int ssize, i;
+	unsigned long s_addr;
+	int max_hpte_count;
+	unsigned int psize, valid;
+	unsigned char *hpte_slot_array;
+	unsigned long hidx, vpn, vsid, hash, shift, slot;
+
+	/*
+	 * Flush all the hptes mapping this hugepage
+	 */
+	s_addr = addr & HPAGE_PMD_MASK;
+	hpte_slot_array = get_hpte_slot_array(pmdp);
+	/*
+	 * IF we try to do a HUGE PTE update after a withdraw is done.
+	 * we will find the below NULL. This happens when we do
+	 * split_huge_page_pmd
+	 */
+	if (!hpte_slot_array)
+		return;
+
+	/* get the base page size */
+	psize = get_slice_psize(mm, s_addr);
+
+	if (ppc_md.hugepage_invalidate)
+		return ppc_md.hugepage_invalidate(mm, hpte_slot_array,
+						  s_addr, psize);
+	/*
+	 * No bluk hpte removal support, invalidate each entry
+	 */
+	shift = mmu_psize_defs[psize].shift;
+	max_hpte_count = HPAGE_PMD_SIZE >> shift;
+	for (i = 0; i < max_hpte_count; i++) {
+		/*
+		 * 8 bits per each hpte entries
+		 * 000| [ secondary group (one bit) | hidx (3 bits) | valid bit]
+		 */
+		valid = hpte_valid(hpte_slot_array, i);
+		if (!valid)
+			continue;
+		hidx =  hpte_hash_index(hpte_slot_array, i);
+
+		/* get the vpn */
+		addr = s_addr + (i * (1ul << shift));
+		if (!is_kernel_addr(addr)) {
+			ssize = user_segment_size(addr);
+			vsid = get_vsid(mm->context.id, addr, ssize);
+			WARN_ON(vsid == 0);
+		} else {
+			vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
+			ssize = mmu_kernel_ssize;
+		}
+
+		vpn = hpt_vpn(addr, vsid, ssize);
+		hash = hpt_hash(vpn, shift, ssize);
+		if (hidx & _PTEIDX_SECONDARY)
+			hash = ~hash;
+
+		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+		slot += hidx & _PTEIDX_GROUP_IX;
+		ppc_md.hpte_invalidate(slot, vpn, psize,
+				       MMU_PAGE_16M, ssize, 0);
+	}
+}
+
+static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot)
+{
+	pmd_val(pmd) |= pgprot_val(pgprot);
+	return pmd;
+}
+
+pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
+{
+	pmd_t pmd;
+	/*
+	 * For a valid pte, we would have _PAGE_PRESENT or _PAGE_FILE always
+	 * set. We use this to check THP page at pmd level.
+	 * leaf pte for huge page, bottom two bits != 00
+	 */
+	pmd_val(pmd) = pfn << PTE_RPN_SHIFT;
+	pmd_val(pmd) |= _PAGE_THP_HUGE;
+	pmd = pmd_set_protbits(pmd, pgprot);
+	return pmd;
+}
+
+pmd_t mk_pmd(struct page *page, pgprot_t pgprot)
+{
+	return pfn_pmd(page_to_pfn(page), pgprot);
+}
+
+pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+
+	pmd_val(pmd) &= _HPAGE_CHG_MASK;
+	pmd = pmd_set_protbits(pmd, newprot);
+	return pmd;
+}
+
+/*
+ * This is called at the end of handling a user page fault, when the
+ * fault has been handled by updating a HUGE PMD entry in the linux page tables.
+ * We use it to preload an HPTE into the hash table corresponding to
+ * the updated linux HUGE PMD entry.
+ */
+void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+			  pmd_t *pmd)
+{
+	return;
+}
+
+pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+			 unsigned long addr, pmd_t *pmdp)
+{
+	pmd_t old_pmd;
+	pgtable_t pgtable;
+	unsigned long old;
+	pgtable_t *pgtable_slot;
+
+	old = pmd_hugepage_update(mm, addr, pmdp, ~0UL);
+	old_pmd = __pmd(old);
+	/*
+	 * We have pmd == none and we are holding page_table_lock.
+	 * So we can safely go and clear the pgtable hash
+	 * index info.
+	 */
+	pgtable_slot = (pgtable_t *)pmdp + PTRS_PER_PMD;
+	pgtable = *pgtable_slot;
+	/*
+	 * Let's zero out old valid and hash index details
+	 * hash fault look at them.
+	 */
+	memset(pgtable, 0, PTE_FRAG_SIZE);
+	return old_pmd;
+}
+
+int has_transparent_hugepage(void)
+{
+	if (!mmu_has_feature(MMU_FTR_16M_PAGE))
+		return 0;
+	/*
+	 * We support THP only if PMD_SIZE is 16MB.
+	 */
+	if (mmu_psize_defs[MMU_PAGE_16M].shift != PMD_SHIFT)
+		return 0;
+	/*
+	 * We need to make sure that we support 16MB hugepage in a segement
+	 * with base page size 64K or 4K. We only enable THP with a PAGE_SIZE
+	 * of 64K.
+	 */
+	/*
+	 * If we have 64K HPTE, we will be using that by default
+	 */
+	if (mmu_psize_defs[MMU_PAGE_64K].shift &&
+	    (mmu_psize_defs[MMU_PAGE_64K].penc[MMU_PAGE_16M] == -1))
+		return 0;
+	/*
+	 * Ok we only have 4K HPTE
+	 */
+	if (mmu_psize_defs[MMU_PAGE_4K].penc[MMU_PAGE_16M] == -1)
+		return 0;
+
+	return 1;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/pgtable.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/pgtable.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/pgtable.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/pgtable.c	2013-08-25 20:43:22.000000000 -0400
@@ -235,6 +235,14 @@ void assert_pte_locked(struct mm_struct
 	pud = pud_offset(pgd, addr);
 	BUG_ON(pud_none(*pud));
 	pmd = pmd_offset(pud, addr);
+	/*
+	 * khugepaged to collapse normal pages to hugepage, first set
+	 * pmd to none to force page fault/gup to take mmap_sem. After
+	 * pmd is set to none, we do a pte_clear which does this assertion
+	 * so if we find pmd none, return.
+	 */
+	if (pmd_none(*pmd))
+		return;
 	BUG_ON(!pmd_present(*pmd));
 	assert_spin_locked(pte_lockptr(mm, pmd));
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/subpage-prot.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/subpage-prot.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/subpage-prot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/subpage-prot.c	2013-08-25 20:43:22.000000000 -0400
@@ -130,6 +130,53 @@ static void subpage_prot_clear(unsigned
 	up_write(&mm->mmap_sem);
 }
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static int subpage_walk_pmd_entry(pmd_t *pmd, unsigned long addr,
+				  unsigned long end, struct mm_walk *walk)
+{
+	struct vm_area_struct *vma = walk->private;
+	split_huge_page_pmd(vma, addr, pmd);
+	return 0;
+}
+
+static void subpage_mark_vma_nohuge(struct mm_struct *mm, unsigned long addr,
+				    unsigned long len)
+{
+	struct vm_area_struct *vma;
+	struct mm_walk subpage_proto_walk = {
+		.mm = mm,
+		.pmd_entry = subpage_walk_pmd_entry,
+	};
+
+	/*
+	 * We don't try too hard, we just mark all the vma in that range
+	 * VM_NOHUGEPAGE and split them.
+	 */
+	vma = find_vma(mm, addr);
+	/*
+	 * If the range is in unmapped range, just return
+	 */
+	if (vma && ((addr + len) <= vma->vm_start))
+		return;
+
+	while (vma) {
+		if (vma->vm_start >= (addr + len))
+			break;
+		vma->vm_flags |= VM_NOHUGEPAGE;
+		subpage_proto_walk.private = vma;
+		walk_page_range(vma->vm_start, vma->vm_end,
+				&subpage_proto_walk);
+		vma = vma->vm_next;
+	}
+}
+#else
+static void subpage_mark_vma_nohuge(struct mm_struct *mm, unsigned long addr,
+				    unsigned long len)
+{
+	return;
+}
+#endif
+
 /*
  * Copy in a subpage protection map for an address range.
  * The map has 2 bits per 4k subpage, so 32 bits per 64k page.
@@ -168,6 +215,7 @@ long sys_subpage_prot(unsigned long addr
 		return -EFAULT;
 
 	down_write(&mm->mmap_sem);
+	subpage_mark_vma_nohuge(mm, addr, len);
 	for (limit = addr + len; addr < limit; addr = next) {
 		next = pmd_addr_end(addr, limit);
 		err = -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/tlb_hash64.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/tlb_hash64.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/tlb_hash64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/tlb_hash64.c	2013-08-25 20:43:22.000000000 -0400
@@ -183,12 +183,13 @@ void tlb_flush(struct mmu_gather *tlb)
  * since 64K pages may overlap with other bridges when using 64K pages
  * with 4K HW pages on IO space.
  *
- * Because of that usage pattern, it's only available with CONFIG_HOTPLUG
- * and is implemented for small size rather than speed.
+ * Because of that usage pattern, it is implemented for small size rather
+ * than speed.
  */
 void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
 			      unsigned long end)
 {
+	int hugepage_shift;
 	unsigned long flags;
 
 	start = _ALIGN_DOWN(start, PAGE_SIZE);
@@ -206,7 +207,8 @@ void __flush_hash_table_range(struct mm_
 	local_irq_save(flags);
 	arch_enter_lazy_mmu_mode();
 	for (; start < end; start += PAGE_SIZE) {
-		pte_t *ptep = find_linux_pte(mm->pgd, start);
+		pte_t *ptep = find_linux_pte_or_hugepte(mm->pgd, start,
+							&hugepage_shift);
 		unsigned long pte;
 
 		if (ptep == NULL)
@@ -214,7 +216,37 @@ void __flush_hash_table_range(struct mm_
 		pte = pte_val(*ptep);
 		if (!(pte & _PAGE_HASHPTE))
 			continue;
-		hpte_need_flush(mm, start, ptep, pte, 0);
+		if (unlikely(hugepage_shift && pmd_trans_huge(*(pmd_t *)pte)))
+			hpte_do_hugepage_flush(mm, start, (pmd_t *)pte);
+		else
+			hpte_need_flush(mm, start, ptep, pte, 0);
+	}
+	arch_leave_lazy_mmu_mode();
+	local_irq_restore(flags);
+}
+
+void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd, unsigned long addr)
+{
+	pte_t *pte;
+	pte_t *start_pte;
+	unsigned long flags;
+
+	addr = _ALIGN_DOWN(addr, PMD_SIZE);
+	/* Note: Normally, we should only ever use a batch within a
+	 * PTE locked section. This violates the rule, but will work
+	 * since we don't actually modify the PTEs, we just flush the
+	 * hash while leaving the PTEs intact (including their reference
+	 * to being hashed). This is not the most performance oriented
+	 * way to do things but is fine for our needs here.
+	 */
+	local_irq_save(flags);
+	arch_enter_lazy_mmu_mode();
+	start_pte = pte_offset_map(pmd, addr);
+	for (pte = start_pte; pte < start_pte + PTRS_PER_PTE; pte++) {
+		unsigned long pteval = pte_val(*pte);
+		if (pteval & _PAGE_HASHPTE)
+			hpte_need_flush(mm, addr, pte, pteval, 0);
+		addr += PAGE_SIZE;
 	}
 	arch_leave_lazy_mmu_mode();
 	local_irq_restore(flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/mm/tlb_nohash.c linux-libre-3.11-rc7-gnu/arch/powerpc/mm/tlb_nohash.c
--- linux-libre-3.10-gnu/arch/powerpc/mm/tlb_nohash.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/mm/tlb_nohash.c	2013-08-25 20:43:22.000000000 -0400
@@ -648,7 +648,7 @@ void __init early_init_mmu(void)
 	__early_init_mmu(1);
 }
 
-void __cpuinit early_init_mmu_secondary(void)
+void early_init_mmu_secondary(void)
 {
 	__early_init_mmu(0);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/net/bpf_jit_comp.c linux-libre-3.11-rc7-gnu/arch/powerpc/net/bpf_jit_comp.c
--- linux-libre-3.10-gnu/arch/powerpc/net/bpf_jit_comp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/net/bpf_jit_comp.c	2013-08-25 20:43:22.000000000 -0400
@@ -650,8 +650,7 @@ void bpf_jit_compile(struct sk_filter *f
 
 	proglen = cgctx.idx * 4;
 	alloclen = proglen + FUNCTION_DESCR_SIZE;
-	image = module_alloc(max_t(unsigned int, alloclen,
-				   sizeof(struct work_struct)));
+	image = module_alloc(alloclen);
 	if (!image)
 		goto out;
 
@@ -688,20 +687,8 @@ out:
 	return;
 }
 
-static void jit_free_defer(struct work_struct *arg)
-{
-	module_free(NULL, arg);
-}
-
-/* run from softirq, we must use a work_struct to call
- * module_free() from process context
- */
 void bpf_jit_free(struct sk_filter *fp)
 {
-	if (fp->bpf_func != sk_run_filter) {
-		struct work_struct *work = (struct work_struct *)fp->bpf_func;
-
-		INIT_WORK(work, jit_free_defer);
-		schedule_work(work);
-	}
+	if (fp->bpf_func != sk_run_filter)
+		module_free(NULL, fp->bpf_func);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/perf/core-book3s.c linux-libre-3.11-rc7-gnu/arch/powerpc/perf/core-book3s.c
--- linux-libre-3.10-gnu/arch/powerpc/perf/core-book3s.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/perf/core-book3s.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,6 +75,11 @@ static unsigned int freeze_events_kernel
 
 #define MMCR0_FCHV		0
 #define MMCR0_PMCjCE		MMCR0_PMCnCE
+#define MMCR0_FC56		0
+#define MMCR0_PMAO		0
+#define MMCR0_EBE		0
+#define MMCR0_PMCC		0
+#define MMCR0_PMCC_U6		0
 
 #define SPRN_MMCRA		SPRN_MMCR2
 #define MMCRA_SAMPLE_ENABLE	0
@@ -102,6 +107,15 @@ static inline int siar_valid(struct pt_r
 	return 1;
 }
 
+static bool is_ebb_event(struct perf_event *event) { return false; }
+static int ebb_event_check(struct perf_event *event) { return 0; }
+static void ebb_event_add(struct perf_event *event) { }
+static void ebb_switch_out(unsigned long mmcr0) { }
+static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
+{
+	return mmcr0;
+}
+
 static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
 static inline void power_pmu_bhrb_disable(struct perf_event *event) {}
 void power_pmu_flush_branch_stack(void) {}
@@ -462,6 +476,89 @@ void power_pmu_bhrb_read(struct cpu_hw_e
 	return;
 }
 
+static bool is_ebb_event(struct perf_event *event)
+{
+	/*
+	 * This could be a per-PMU callback, but we'd rather avoid the cost. We
+	 * check that the PMU supports EBB, meaning those that don't can still
+	 * use bit 63 of the event code for something else if they wish.
+	 */
+	return (ppmu->flags & PPMU_EBB) &&
+	       ((event->attr.config >> PERF_EVENT_CONFIG_EBB_SHIFT) & 1);
+}
+
+static int ebb_event_check(struct perf_event *event)
+{
+	struct perf_event *leader = event->group_leader;
+
+	/* Event and group leader must agree on EBB */
+	if (is_ebb_event(leader) != is_ebb_event(event))
+		return -EINVAL;
+
+	if (is_ebb_event(event)) {
+		if (!(event->attach_state & PERF_ATTACH_TASK))
+			return -EINVAL;
+
+		if (!leader->attr.pinned || !leader->attr.exclusive)
+			return -EINVAL;
+
+		if (event->attr.inherit || event->attr.sample_period ||
+		    event->attr.enable_on_exec || event->attr.freq)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void ebb_event_add(struct perf_event *event)
+{
+	if (!is_ebb_event(event) || current->thread.used_ebb)
+		return;
+
+	/*
+	 * IFF this is the first time we've added an EBB event, set
+	 * PMXE in the user MMCR0 so we can detect when it's cleared by
+	 * userspace. We need this so that we can context switch while
+	 * userspace is in the EBB handler (where PMXE is 0).
+	 */
+	current->thread.used_ebb = 1;
+	current->thread.mmcr0 |= MMCR0_PMXE;
+}
+
+static void ebb_switch_out(unsigned long mmcr0)
+{
+	if (!(mmcr0 & MMCR0_EBE))
+		return;
+
+	current->thread.siar  = mfspr(SPRN_SIAR);
+	current->thread.sier  = mfspr(SPRN_SIER);
+	current->thread.sdar  = mfspr(SPRN_SDAR);
+	current->thread.mmcr0 = mmcr0 & MMCR0_USER_MASK;
+	current->thread.mmcr2 = mfspr(SPRN_MMCR2) & MMCR2_USER_MASK;
+}
+
+static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
+{
+	if (!ebb)
+		goto out;
+
+	/* Enable EBB and read/write to all 6 PMCs for userspace */
+	mmcr0 |= MMCR0_EBE | MMCR0_PMCC_U6;
+
+	/* Add any bits from the user reg, FC or PMAO */
+	mmcr0 |= current->thread.mmcr0;
+
+	/* Be careful not to set PMXE if userspace had it cleared */
+	if (!(current->thread.mmcr0 & MMCR0_PMXE))
+		mmcr0 &= ~MMCR0_PMXE;
+
+	mtspr(SPRN_SIAR, current->thread.siar);
+	mtspr(SPRN_SIER, current->thread.sier);
+	mtspr(SPRN_SDAR, current->thread.sdar);
+	mtspr(SPRN_MMCR2, current->thread.mmcr2);
+out:
+	return mmcr0;
+}
 #endif /* CONFIG_PPC64 */
 
 static void perf_event_interrupt(struct pt_regs *regs);
@@ -732,6 +829,13 @@ static void power_pmu_read(struct perf_e
 
 	if (!event->hw.idx)
 		return;
+
+	if (is_ebb_event(event)) {
+		val = read_pmc(event->hw.idx);
+		local64_set(&event->hw.prev_count, val);
+		return;
+	}
+
 	/*
 	 * Performance monitor interrupts come even when interrupts
 	 * are soft-disabled, as long as interrupts are hard-enabled.
@@ -852,7 +956,7 @@ static void write_mmcr0(struct cpu_hw_ev
 static void power_pmu_disable(struct pmu *pmu)
 {
 	struct cpu_hw_events *cpuhw;
-	unsigned long flags;
+	unsigned long flags, mmcr0, val;
 
 	if (!ppmu)
 		return;
@@ -860,9 +964,6 @@ static void power_pmu_disable(struct pmu
 	cpuhw = &__get_cpu_var(cpu_hw_events);
 
 	if (!cpuhw->disabled) {
-		cpuhw->disabled = 1;
-		cpuhw->n_added = 0;
-
 		/*
 		 * Check if we ever enabled the PMU on this cpu.
 		 */
@@ -872,6 +973,21 @@ static void power_pmu_disable(struct pmu
 		}
 
 		/*
+		 * Set the 'freeze counters' bit, clear EBE/PMCC/PMAO/FC56.
+		 */
+		val  = mmcr0 = mfspr(SPRN_MMCR0);
+		val |= MMCR0_FC;
+		val &= ~(MMCR0_EBE | MMCR0_PMCC | MMCR0_PMAO | MMCR0_FC56);
+
+		/*
+		 * The barrier is to make sure the mtspr has been
+		 * executed and the PMU has frozen the events etc.
+		 * before we return.
+		 */
+		write_mmcr0(cpuhw, val);
+		mb();
+
+		/*
 		 * Disable instruction sampling if it was enabled
 		 */
 		if (cpuhw->mmcr[2] & MMCRA_SAMPLE_ENABLE) {
@@ -880,15 +996,12 @@ static void power_pmu_disable(struct pmu
 			mb();
 		}
 
-		/*
-		 * Set the 'freeze counters' bit.
-		 * The barrier is to make sure the mtspr has been
-		 * executed and the PMU has frozen the events
-		 * before we return.
-		 */
-		write_mmcr0(cpuhw, mfspr(SPRN_MMCR0) | MMCR0_FC);
-		mb();
+		cpuhw->disabled = 1;
+		cpuhw->n_added = 0;
+
+		ebb_switch_out(mmcr0);
 	}
+
 	local_irq_restore(flags);
 }
 
@@ -903,23 +1016,36 @@ static void power_pmu_enable(struct pmu
 	struct cpu_hw_events *cpuhw;
 	unsigned long flags;
 	long i;
-	unsigned long val;
+	unsigned long val, mmcr0;
 	s64 left;
 	unsigned int hwc_index[MAX_HWEVENTS];
 	int n_lim;
 	int idx;
+	bool ebb;
 
 	if (!ppmu)
 		return;
 	local_irq_save(flags);
+
 	cpuhw = &__get_cpu_var(cpu_hw_events);
-	if (!cpuhw->disabled) {
-		local_irq_restore(flags);
-		return;
+	if (!cpuhw->disabled)
+		goto out;
+
+	if (cpuhw->n_events == 0) {
+		ppc_set_pmu_inuse(0);
+		goto out;
 	}
+
 	cpuhw->disabled = 0;
 
 	/*
+	 * EBB requires an exclusive group and all events must have the EBB
+	 * flag set, or not set, so we can just check a single event. Also we
+	 * know we have at least one event.
+	 */
+	ebb = is_ebb_event(cpuhw->event[0]);
+
+	/*
 	 * If we didn't change anything, or only removed events,
 	 * no need to recalculate MMCR* settings and reset the PMCs.
 	 * Just reenable the PMU with the current MMCR* settings
@@ -928,8 +1054,6 @@ static void power_pmu_enable(struct pmu
 	if (!cpuhw->n_added) {
 		mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
 		mtspr(SPRN_MMCR1, cpuhw->mmcr[1]);
-		if (cpuhw->n_events == 0)
-			ppc_set_pmu_inuse(0);
 		goto out_enable;
 	}
 
@@ -996,25 +1120,34 @@ static void power_pmu_enable(struct pmu
 			++n_lim;
 			continue;
 		}
-		val = 0;
-		if (event->hw.sample_period) {
-			left = local64_read(&event->hw.period_left);
-			if (left < 0x80000000L)
-				val = 0x80000000L - left;
+
+		if (ebb)
+			val = local64_read(&event->hw.prev_count);
+		else {
+			val = 0;
+			if (event->hw.sample_period) {
+				left = local64_read(&event->hw.period_left);
+				if (left < 0x80000000L)
+					val = 0x80000000L - left;
+			}
+			local64_set(&event->hw.prev_count, val);
 		}
-		local64_set(&event->hw.prev_count, val);
+
 		event->hw.idx = idx;
 		if (event->hw.state & PERF_HES_STOPPED)
 			val = 0;
 		write_pmc(idx, val);
+
 		perf_event_update_userpage(event);
 	}
 	cpuhw->n_limited = n_lim;
 	cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE;
 
  out_enable:
+	mmcr0 = ebb_switch_in(ebb, cpuhw->mmcr[0]);
+
 	mb();
-	write_mmcr0(cpuhw, cpuhw->mmcr[0]);
+	write_mmcr0(cpuhw, mmcr0);
 
 	/*
 	 * Enable instruction sampling if necessary
@@ -1112,13 +1245,18 @@ static int power_pmu_add(struct perf_eve
 	event->hw.config = cpuhw->events[n0];
 
 nocheck:
+	ebb_event_add(event);
+
 	++cpuhw->n_events;
 	++cpuhw->n_added;
 
 	ret = 0;
  out:
-	if (has_branch_stack(event))
+	if (has_branch_stack(event)) {
 		power_pmu_bhrb_enable(event);
+		cpuhw->bhrb_filter = ppmu->bhrb_filter_map(
+					event->attr.branch_sample_type);
+	}
 
 	perf_pmu_enable(event->pmu);
 	local_irq_restore(flags);
@@ -1472,6 +1610,11 @@ static int power_pmu_event_init(struct p
 		}
 	}
 
+	/* Extra checks for EBB */
+	err = ebb_event_check(event);
+	if (err)
+		return err;
+
 	/*
 	 * If this is in a group, check if it can go on with all the
 	 * other hardware events in the group.  We assume the event
@@ -1511,6 +1654,13 @@ static int power_pmu_event_init(struct p
 	local64_set(&event->hw.period_left, event->hw.last_period);
 
 	/*
+	 * For EBB events we just context switch the PMC value, we don't do any
+	 * of the sample_period logic. We use hw.prev_count for this.
+	 */
+	if (is_ebb_event(event))
+		local64_set(&event->hw.prev_count, 0);
+
+	/*
 	 * See if we need to reserve the PMU.
 	 * If no events are currently in use, then we have to take a
 	 * mutex to ensure that we don't race with another task doing
@@ -1786,7 +1936,7 @@ static void power_pmu_setup(int cpu)
 	cpuhw->mmcr[0] = MMCR0_FC;
 }
 
-static int __cpuinit
+static int
 power_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (long)hcpu;
@@ -1803,7 +1953,7 @@ power_pmu_notifier(struct notifier_block
 	return NOTIFY_OK;
 }
 
-int __cpuinit register_power_pmu(struct power_pmu *pmu)
+int register_power_pmu(struct power_pmu *pmu)
 {
 	if (ppmu)
 		return -EBUSY;		/* something's already registered */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/perf/power7-pmu.c linux-libre-3.11-rc7-gnu/arch/powerpc/perf/power7-pmu.c
--- linux-libre-3.10-gnu/arch/powerpc/perf/power7-pmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/perf/power7-pmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,7 +60,30 @@
 #define	PME_PM_LD_REF_L1		0xc880
 #define	PME_PM_LD_MISS_L1		0x400f0
 #define	PME_PM_BRU_FIN			0x10068
-#define	PME_PM_BRU_MPRED		0x400f6
+#define	PME_PM_BR_MPRED			0x400f6
+
+#define PME_PM_CMPLU_STALL_FXU			0x20014
+#define PME_PM_CMPLU_STALL_DIV			0x40014
+#define PME_PM_CMPLU_STALL_SCALAR		0x40012
+#define PME_PM_CMPLU_STALL_SCALAR_LONG		0x20018
+#define PME_PM_CMPLU_STALL_VECTOR		0x2001c
+#define PME_PM_CMPLU_STALL_VECTOR_LONG		0x4004a
+#define PME_PM_CMPLU_STALL_LSU			0x20012
+#define PME_PM_CMPLU_STALL_REJECT		0x40016
+#define PME_PM_CMPLU_STALL_ERAT_MISS		0x40018
+#define PME_PM_CMPLU_STALL_DCACHE_MISS		0x20016
+#define PME_PM_CMPLU_STALL_STORE		0x2004a
+#define PME_PM_CMPLU_STALL_THRD			0x1001c
+#define PME_PM_CMPLU_STALL_IFU			0x4004c
+#define PME_PM_CMPLU_STALL_BRU			0x4004e
+#define PME_PM_GCT_NOSLOT_IC_MISS		0x2001a
+#define PME_PM_GCT_NOSLOT_BR_MPRED		0x4001a
+#define PME_PM_GCT_NOSLOT_BR_MPRED_IC_MISS	0x4001c
+#define PME_PM_GRP_CMPL				0x30004
+#define PME_PM_1PLUS_PPC_CMPL			0x100f2
+#define PME_PM_CMPLU_STALL_DFU			0x2003c
+#define PME_PM_RUN_CYC				0x200f4
+#define PME_PM_RUN_INST_CMPL			0x400fa
 
 /*
  * Layout of constraint bits:
@@ -326,7 +349,7 @@ static int power7_generic_events[] = {
 	[PERF_COUNT_HW_CACHE_REFERENCES] =		PME_PM_LD_REF_L1,
 	[PERF_COUNT_HW_CACHE_MISSES] =			PME_PM_LD_MISS_L1,
 	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =		PME_PM_BRU_FIN,
-	[PERF_COUNT_HW_BRANCH_MISSES] =			PME_PM_BRU_MPRED,
+	[PERF_COUNT_HW_BRANCH_MISSES] =			PME_PM_BR_MPRED,
 };
 
 #define C(x)	PERF_COUNT_HW_CACHE_##x
@@ -382,7 +405,7 @@ GENERIC_EVENT_ATTR(instructions,		INST_C
 GENERIC_EVENT_ATTR(cache-references,		LD_REF_L1);
 GENERIC_EVENT_ATTR(cache-misses,		LD_MISS_L1);
 GENERIC_EVENT_ATTR(branch-instructions,		BRU_FIN);
-GENERIC_EVENT_ATTR(branch-misses,		BRU_MPRED);
+GENERIC_EVENT_ATTR(branch-misses,		BR_MPRED);
 
 POWER_EVENT_ATTR(CYC,				CYC);
 POWER_EVENT_ATTR(GCT_NOSLOT_CYC,		GCT_NOSLOT_CYC);
@@ -391,7 +414,32 @@ POWER_EVENT_ATTR(INST_CMPL,			INST_CMPL)
 POWER_EVENT_ATTR(LD_REF_L1,			LD_REF_L1);
 POWER_EVENT_ATTR(LD_MISS_L1,			LD_MISS_L1);
 POWER_EVENT_ATTR(BRU_FIN,			BRU_FIN)
-POWER_EVENT_ATTR(BRU_MPRED,			BRU_MPRED);
+POWER_EVENT_ATTR(BR_MPRED,			BR_MPRED);
+
+POWER_EVENT_ATTR(CMPLU_STALL_FXU,		CMPLU_STALL_FXU);
+POWER_EVENT_ATTR(CMPLU_STALL_DIV,		CMPLU_STALL_DIV);
+POWER_EVENT_ATTR(CMPLU_STALL_SCALAR,		CMPLU_STALL_SCALAR);
+POWER_EVENT_ATTR(CMPLU_STALL_SCALAR_LONG,	CMPLU_STALL_SCALAR_LONG);
+POWER_EVENT_ATTR(CMPLU_STALL_VECTOR,		CMPLU_STALL_VECTOR);
+POWER_EVENT_ATTR(CMPLU_STALL_VECTOR_LONG,	CMPLU_STALL_VECTOR_LONG);
+POWER_EVENT_ATTR(CMPLU_STALL_LSU,		CMPLU_STALL_LSU);
+POWER_EVENT_ATTR(CMPLU_STALL_REJECT,		CMPLU_STALL_REJECT);
+
+POWER_EVENT_ATTR(CMPLU_STALL_ERAT_MISS,		CMPLU_STALL_ERAT_MISS);
+POWER_EVENT_ATTR(CMPLU_STALL_DCACHE_MISS,	CMPLU_STALL_DCACHE_MISS);
+POWER_EVENT_ATTR(CMPLU_STALL_STORE,		CMPLU_STALL_STORE);
+POWER_EVENT_ATTR(CMPLU_STALL_THRD,		CMPLU_STALL_THRD);
+POWER_EVENT_ATTR(CMPLU_STALL_IFU,		CMPLU_STALL_IFU);
+POWER_EVENT_ATTR(CMPLU_STALL_BRU,		CMPLU_STALL_BRU);
+POWER_EVENT_ATTR(GCT_NOSLOT_IC_MISS,		GCT_NOSLOT_IC_MISS);
+
+POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED,		GCT_NOSLOT_BR_MPRED);
+POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED_IC_MISS,	GCT_NOSLOT_BR_MPRED_IC_MISS);
+POWER_EVENT_ATTR(GRP_CMPL,			GRP_CMPL);
+POWER_EVENT_ATTR(1PLUS_PPC_CMPL,		1PLUS_PPC_CMPL);
+POWER_EVENT_ATTR(CMPLU_STALL_DFU,		CMPLU_STALL_DFU);
+POWER_EVENT_ATTR(RUN_CYC,			RUN_CYC);
+POWER_EVENT_ATTR(RUN_INST_CMPL,			RUN_INST_CMPL);
 
 static struct attribute *power7_events_attr[] = {
 	GENERIC_EVENT_PTR(CYC),
@@ -401,7 +449,7 @@ static struct attribute *power7_events_a
 	GENERIC_EVENT_PTR(LD_REF_L1),
 	GENERIC_EVENT_PTR(LD_MISS_L1),
 	GENERIC_EVENT_PTR(BRU_FIN),
-	GENERIC_EVENT_PTR(BRU_MPRED),
+	GENERIC_EVENT_PTR(BR_MPRED),
 
 	POWER_EVENT_PTR(CYC),
 	POWER_EVENT_PTR(GCT_NOSLOT_CYC),
@@ -410,7 +458,32 @@ static struct attribute *power7_events_a
 	POWER_EVENT_PTR(LD_REF_L1),
 	POWER_EVENT_PTR(LD_MISS_L1),
 	POWER_EVENT_PTR(BRU_FIN),
-	POWER_EVENT_PTR(BRU_MPRED),
+	POWER_EVENT_PTR(BR_MPRED),
+
+	POWER_EVENT_PTR(CMPLU_STALL_FXU),
+	POWER_EVENT_PTR(CMPLU_STALL_DIV),
+	POWER_EVENT_PTR(CMPLU_STALL_SCALAR),
+	POWER_EVENT_PTR(CMPLU_STALL_SCALAR_LONG),
+	POWER_EVENT_PTR(CMPLU_STALL_VECTOR),
+	POWER_EVENT_PTR(CMPLU_STALL_VECTOR_LONG),
+	POWER_EVENT_PTR(CMPLU_STALL_LSU),
+	POWER_EVENT_PTR(CMPLU_STALL_REJECT),
+
+	POWER_EVENT_PTR(CMPLU_STALL_ERAT_MISS),
+	POWER_EVENT_PTR(CMPLU_STALL_DCACHE_MISS),
+	POWER_EVENT_PTR(CMPLU_STALL_STORE),
+	POWER_EVENT_PTR(CMPLU_STALL_THRD),
+	POWER_EVENT_PTR(CMPLU_STALL_IFU),
+	POWER_EVENT_PTR(CMPLU_STALL_BRU),
+	POWER_EVENT_PTR(GCT_NOSLOT_IC_MISS),
+	POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED),
+
+	POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED_IC_MISS),
+	POWER_EVENT_PTR(GRP_CMPL),
+	POWER_EVENT_PTR(1PLUS_PPC_CMPL),
+	POWER_EVENT_PTR(CMPLU_STALL_DFU),
+	POWER_EVENT_PTR(RUN_CYC),
+	POWER_EVENT_PTR(RUN_INST_CMPL),
 	NULL
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/perf/power8-pmu.c linux-libre-3.11-rc7-gnu/arch/powerpc/perf/power8-pmu.c
--- linux-libre-3.10-gnu/arch/powerpc/perf/power8-pmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/perf/power8-pmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,9 +31,9 @@
  *
  *        60        56        52        48        44        40        36        32
  * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
- *                                     [      thresh_cmp     ]   [  thresh_ctl   ]
- *                                                                       |
- *                                       thresh start/stop OR FAB match -*
+ *   |                                 [      thresh_cmp     ]   [  thresh_ctl   ]
+ *   |                                                                   |
+ *   *- EBB (Linux)                      thresh start/stop OR FAB match -*
  *
  *        28        24        20        16        12         8         4         0
  * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
@@ -85,6 +85,7 @@
  *
  */
 
+#define EVENT_EBB_MASK		1ull
 #define EVENT_THR_CMP_SHIFT	40	/* Threshold CMP value */
 #define EVENT_THR_CMP_MASK	0x3ff
 #define EVENT_THR_CTL_SHIFT	32	/* Threshold control value (start/stop) */
@@ -109,6 +110,17 @@
 #define EVENT_IS_MARKED		(EVENT_MARKED_MASK << EVENT_MARKED_SHIFT)
 #define EVENT_PSEL_MASK		0xff	/* PMCxSEL value */
 
+#define EVENT_VALID_MASK	\
+	((EVENT_THRESH_MASK    << EVENT_THRESH_SHIFT)		|	\
+	 (EVENT_SAMPLE_MASK    << EVENT_SAMPLE_SHIFT)		|	\
+	 (EVENT_CACHE_SEL_MASK << EVENT_CACHE_SEL_SHIFT)	|	\
+	 (EVENT_PMC_MASK       << EVENT_PMC_SHIFT)		|	\
+	 (EVENT_UNIT_MASK      << EVENT_UNIT_SHIFT)		|	\
+	 (EVENT_COMBINE_MASK   << EVENT_COMBINE_SHIFT)		|	\
+	 (EVENT_MARKED_MASK    << EVENT_MARKED_SHIFT)		|	\
+	 (EVENT_EBB_MASK       << PERF_EVENT_CONFIG_EBB_SHIFT)	|	\
+	  EVENT_PSEL_MASK)
+
 /* MMCRA IFM bits - POWER8 */
 #define	POWER8_MMCRA_IFM1		0x0000000040000000UL
 #define	POWER8_MMCRA_IFM2		0x0000000080000000UL
@@ -130,10 +142,10 @@
  *
  *        28        24        20        16        12         8         4         0
  * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
- *                       [ ]   [  sample ]   [     ]   [6] [5]   [4] [3]   [2] [1]
- *                        |                     |
- *      L1 I/D qualifier -*                     |      Count of events for each PMC.
- *                                              |        p1, p2, p3, p4, p5, p6.
+ *                   |   [ ]   [  sample ]   [     ]   [6] [5]   [4] [3]   [2] [1]
+ *              EBB -*    |                     |
+ *                        |                     |      Count of events for each PMC.
+ *      L1 I/D qualifier -*                     |        p1, p2, p3, p4, p5, p6.
  *                     nc - number of counters -*
  *
  * The PMC fields P1..P6, and NC, are adder fields. As we accumulate constraints
@@ -149,6 +161,9 @@
 #define CNST_THRESH_VAL(v)	(((v) & EVENT_THRESH_MASK) << 32)
 #define CNST_THRESH_MASK	CNST_THRESH_VAL(EVENT_THRESH_MASK)
 
+#define CNST_EBB_VAL(v)		(((v) & EVENT_EBB_MASK) << 24)
+#define CNST_EBB_MASK		CNST_EBB_VAL(EVENT_EBB_MASK)
+
 #define CNST_L1_QUAL_VAL(v)	(((v) & 3) << 22)
 #define CNST_L1_QUAL_MASK	CNST_L1_QUAL_VAL(3)
 
@@ -207,14 +222,21 @@ static inline bool event_is_fab_match(u6
 
 static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp)
 {
-	unsigned int unit, pmc, cache;
+	unsigned int unit, pmc, cache, ebb;
 	unsigned long mask, value;
 
 	mask = value = 0;
 
-	pmc   = (event >> EVENT_PMC_SHIFT)       & EVENT_PMC_MASK;
-	unit  = (event >> EVENT_UNIT_SHIFT)      & EVENT_UNIT_MASK;
-	cache = (event >> EVENT_CACHE_SEL_SHIFT) & EVENT_CACHE_SEL_MASK;
+	if (event & ~EVENT_VALID_MASK)
+		return -1;
+
+	pmc   = (event >> EVENT_PMC_SHIFT)        & EVENT_PMC_MASK;
+	unit  = (event >> EVENT_UNIT_SHIFT)       & EVENT_UNIT_MASK;
+	cache = (event >> EVENT_CACHE_SEL_SHIFT)  & EVENT_CACHE_SEL_MASK;
+	ebb   = (event >> PERF_EVENT_CONFIG_EBB_SHIFT) & EVENT_EBB_MASK;
+
+	/* Clear the EBB bit in the event, so event checks work below */
+	event &= ~(EVENT_EBB_MASK << PERF_EVENT_CONFIG_EBB_SHIFT);
 
 	if (pmc) {
 		if (pmc > 6)
@@ -284,6 +306,18 @@ static int power8_get_constraint(u64 eve
 		value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT);
 	}
 
+	if (!pmc && ebb)
+		/* EBB events must specify the PMC */
+		return -1;
+
+	/*
+	 * All events must agree on EBB, either all request it or none.
+	 * EBB events are pinned & exclusive, so this should never actually
+	 * hit, but we leave it as a fallback in case.
+	 */
+	mask  |= CNST_EBB_VAL(ebb);
+	value |= CNST_EBB_MASK;
+
 	*maskp = mask;
 	*valp = value;
 
@@ -378,6 +412,10 @@ static int power8_compute_mmcr(u64 event
 	if (pmc_inuse & 0x7c)
 		mmcr[0] |= MMCR0_PMCjCE;
 
+	/* If we're not using PMC 5 or 6, freeze them */
+	if (!(pmc_inuse & 0x60))
+		mmcr[0] |= MMCR0_FC56;
+
 	mmcr[1] = mmcr1;
 	mmcr[2] = mmcra;
 
@@ -523,18 +561,13 @@ static int power8_generic_events[] = {
 static u64 power8_bhrb_filter_map(u64 branch_sample_type)
 {
 	u64 pmu_bhrb_filter = 0;
-	u64 br_privilege = branch_sample_type & ONLY_PLM;
 
-	/* BHRB and regular PMU events share the same prvillege state
+	/* BHRB and regular PMU events share the same privilege state
 	 * filter configuration. BHRB is always recorded along with a
-	 * regular PMU event. So privilege state filter criteria for BHRB
-	 * and the companion PMU events has to be the same. As a default
-	 * "perf record" tool sets all privillege bits ON when no filter
-	 * criteria is provided in the command line. So as along as all
-	 * privillege bits are ON or they are OFF, we are good to go.
+	 * regular PMU event. As the privilege state filter is handled
+	 * in the basic PMC configuration of the accompanying regular
+	 * PMU event, we ignore any separate BHRB specific request.
 	 */
-	if ((br_privilege != 7) && (br_privilege != 0))
-		return -1;
 
 	/* No branch filter requested */
 	if (branch_sample_type & PERF_SAMPLE_BRANCH_ANY)
@@ -574,7 +607,7 @@ static struct power_pmu power8_pmu = {
 	.get_constraint		= power8_get_constraint,
 	.get_alternatives	= power8_get_alternatives,
 	.disable_pmc		= power8_disable_pmc,
-	.flags			= PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_BHRB,
+	.flags			= PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_BHRB | PPMU_EBB,
 	.n_generic		= ARRAY_SIZE(power8_generic_events),
 	.generic_events		= power8_generic_events,
 	.attr_groups		= power8_pmu_attr_groups,
@@ -583,10 +616,19 @@ static struct power_pmu power8_pmu = {
 
 static int __init init_power8_pmu(void)
 {
+	int rc;
+
 	if (!cur_cpu_spec->oprofile_cpu_type ||
 	    strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power8"))
 		return -ENODEV;
 
-	return register_power_pmu(&power8_pmu);
+	rc = register_power_pmu(&power8_pmu);
+	if (rc)
+		return rc;
+
+	/* Tell userspace that EBB is supported */
+	cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
+
+	return 0;
 }
 early_initcall(init_power8_pmu);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/44x/currituck.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/44x/currituck.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/44x/currituck.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/44x/currituck.c	2013-08-25 20:43:22.000000000 -0400
@@ -91,12 +91,12 @@ static void __init ppc47x_init_irq(void)
 }
 
 #ifdef CONFIG_SMP
-static void __cpuinit smp_ppc47x_setup_cpu(int cpu)
+static void smp_ppc47x_setup_cpu(int cpu)
 {
 	mpic_setup_this_cpu();
 }
 
-static int __cpuinit smp_ppc47x_kick_cpu(int cpu)
+static int smp_ppc47x_kick_cpu(int cpu)
 {
 	struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
 	const u64 *spin_table_addr_prop;
@@ -176,13 +176,48 @@ static int __init ppc47x_probe(void)
 	return 1;
 }
 
+static int board_rev = -1;
+static int __init ppc47x_get_board_rev(void)
+{
+	u8 fpga_reg0;
+	void *fpga;
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga");
+	if (!np)
+		goto fail;
+
+	fpga = of_iomap(np, 0);
+	of_node_put(np);
+	if (!fpga)
+		goto fail;
+
+	fpga_reg0 = ioread8(fpga);
+	board_rev = fpga_reg0 & 0x03;
+	pr_info("%s: Found board revision %d\n", __func__, board_rev);
+	iounmap(fpga);
+	return 0;
+
+fail:
+	pr_info("%s: Unable to find board revision\n", __func__);
+	return 0;
+}
+machine_arch_initcall(ppc47x, ppc47x_get_board_rev);
+
 /* Use USB controller should have been hardware swizzled but it wasn't :( */
 static void ppc47x_pci_irq_fixup(struct pci_dev *dev)
 {
 	if (dev->vendor == 0x1033 && (dev->device == 0x0035 ||
 	                              dev->device == 0x00e0)) {
-		dev->irq = irq_create_mapping(NULL, 47);
-		pr_info("%s: Mapping irq 47 %d\n", __func__, dev->irq);
+		if (board_rev == 0) {
+			dev->irq = irq_create_mapping(NULL, 47);
+			pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
+		} else if (board_rev == 2) {
+			dev->irq = irq_create_mapping(NULL, 49);
+			pr_info("%s: Mapping irq %d\n", __func__, dev->irq);
+		} else {
+			pr_alert("%s: Unknown board revision\n", __func__);
+		}
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/44x/iss4xx.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/44x/iss4xx.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/44x/iss4xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/44x/iss4xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -81,12 +81,12 @@ static void __init iss4xx_init_irq(void)
 }
 
 #ifdef CONFIG_SMP
-static void __cpuinit smp_iss4xx_setup_cpu(int cpu)
+static void smp_iss4xx_setup_cpu(int cpu)
 {
 	mpic_setup_this_cpu();
 }
 
-static int __cpuinit smp_iss4xx_kick_cpu(int cpu)
+static int smp_iss4xx_kick_cpu(int cpu)
 {
 	struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
 	const u64 *spin_table_addr_prop;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/512x/mpc5121_ads.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/mpc5121_ads.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/512x/mpc5121_ads.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/mpc5121_ads.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,9 +43,7 @@ static void __init mpc5121_ads_setup_arc
 		mpc83xx_add_bridge(np);
 #endif
 
-#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-	mpc512x_setup_diu();
-#endif
+	mpc512x_setup_arch();
 }
 
 static void __init mpc5121_ads_init_IRQ(void)
@@ -69,7 +67,7 @@ define_machine(mpc5121_ads) {
 	.probe			= mpc5121_ads_probe,
 	.setup_arch		= mpc5121_ads_setup_arch,
 	.init			= mpc512x_init,
-	.init_early		= mpc512x_init_diu,
+	.init_early		= mpc512x_init_early,
 	.init_IRQ		= mpc5121_ads_init_IRQ,
 	.get_irq		= ipic_get_irq,
 	.calibrate_decr		= generic_calibrate_decr,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/512x/mpc512x_generic.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/mpc512x_generic.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/512x/mpc512x_generic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/mpc512x_generic.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,8 +45,8 @@ define_machine(mpc512x_generic) {
 	.name			= "MPC512x generic",
 	.probe			= mpc512x_generic_probe,
 	.init			= mpc512x_init,
-	.init_early		= mpc512x_init_diu,
-	.setup_arch		= mpc512x_setup_diu,
+	.init_early		= mpc512x_init_early,
+	.setup_arch		= mpc512x_setup_arch,
 	.init_IRQ		= mpc512x_init_IRQ,
 	.get_irq		= ipic_get_irq,
 	.calibrate_decr		= generic_calibrate_decr,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/512x/mpc512x.h linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/mpc512x.h
--- linux-libre-3.10-gnu/arch/powerpc/platforms/512x/mpc512x.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/mpc512x.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,18 +12,12 @@
 #ifndef __MPC512X_H__
 #define __MPC512X_H__
 extern void __init mpc512x_init_IRQ(void);
+extern void __init mpc512x_init_early(void);
 extern void __init mpc512x_init(void);
+extern void __init mpc512x_setup_arch(void);
 extern int __init mpc5121_clk_init(void);
-void __init mpc512x_declare_of_platform_devices(void);
 extern const char *mpc512x_select_psc_compat(void);
+extern const char *mpc512x_select_reset_compat(void);
 extern void mpc512x_restart(char *cmd);
 
-#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-void mpc512x_init_diu(void);
-void mpc512x_setup_diu(void);
-#else
-#define mpc512x_init_diu NULL
-#define mpc512x_setup_diu NULL
-#endif
-
 #endif				/* __MPC512X_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/512x/mpc512x_shared.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/mpc512x_shared.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/512x/mpc512x_shared.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/mpc512x_shared.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,8 +35,10 @@ static struct mpc512x_reset_module __iom
 static void __init mpc512x_restart_init(void)
 {
 	struct device_node *np;
+	const char *reset_compat;
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-reset");
+	reset_compat = mpc512x_select_reset_compat();
+	np = of_find_compatible_node(NULL, NULL, reset_compat);
 	if (!np)
 		return;
 
@@ -58,7 +60,7 @@ void mpc512x_restart(char *cmd)
 		;
 }
 
-#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
+#if IS_ENABLED(CONFIG_FB_FSL_DIU)
 
 struct fsl_diu_shared_fb {
 	u8		gamma[0x300];	/* 32-bit aligned! */
@@ -355,6 +357,17 @@ const char *mpc512x_select_psc_compat(vo
 	return NULL;
 }
 
+const char *mpc512x_select_reset_compat(void)
+{
+	if (of_machine_is_compatible("fsl,mpc5121"))
+		return "fsl,mpc5121-reset";
+
+	if (of_machine_is_compatible("fsl,mpc5125"))
+		return "fsl,mpc5125-reset";
+
+	return NULL;
+}
+
 static unsigned int __init get_fifo_size(struct device_node *np,
 					 char *prop_name)
 {
@@ -436,14 +449,26 @@ void __init mpc512x_psc_fifo_init(void)
 	}
 }
 
+void __init mpc512x_init_early(void)
+{
+	mpc512x_restart_init();
+	if (IS_ENABLED(CONFIG_FB_FSL_DIU))
+		mpc512x_init_diu();
+}
+
 void __init mpc512x_init(void)
 {
 	mpc5121_clk_init();
 	mpc512x_declare_of_platform_devices();
-	mpc512x_restart_init();
 	mpc512x_psc_fifo_init();
 }
 
+void __init mpc512x_setup_arch(void)
+{
+	if (IS_ENABLED(CONFIG_FB_FSL_DIU))
+		mpc512x_setup_diu();
+}
+
 /**
  * mpc512x_cs_config - Setup chip select configuration
  * @cs: chip select number
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/512x/pdm360ng.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/pdm360ng.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/512x/pdm360ng.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/512x/pdm360ng.c	2013-08-25 20:43:22.000000000 -0400
@@ -119,9 +119,9 @@ static int __init pdm360ng_probe(void)
 define_machine(pdm360ng) {
 	.name			= "PDM360NG",
 	.probe			= pdm360ng_probe,
-	.setup_arch		= mpc512x_setup_diu,
+	.setup_arch		= mpc512x_setup_arch,
 	.init			= pdm360ng_init,
-	.init_early		= mpc512x_init_diu,
+	.init_early		= mpc512x_init_early,
 	.init_IRQ		= mpc512x_init_IRQ,
 	.get_irq		= ipic_get_irq,
 	.calibrate_decr		= generic_calibrate_decr,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c	2013-08-25 20:43:22.000000000 -0400
@@ -231,17 +231,7 @@ static struct i2c_driver mcu_driver = {
 	.id_table = mcu_ids,
 };
 
-static int __init mcu_init(void)
-{
-	return i2c_add_driver(&mcu_driver);
-}
-module_init(mcu_init);
-
-static void __exit mcu_exit(void)
-{
-	i2c_del_driver(&mcu_driver);
-}
-module_exit(mcu_exit);
+module_i2c_driver(mcu_driver);
 
 MODULE_DESCRIPTION("Power Management and GPIO expander driver for "
 		   "MPC8349E-mITX-compatible MCU");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/85xx/p5020_ds.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/85xx/p5020_ds.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/85xx/p5020_ds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/85xx/p5020_ds.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,12 +75,7 @@ define_machine(p5020_ds) {
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
 #endif
-/* coreint doesn't play nice with lazy EE, use legacy mpic for now */
-#ifdef CONFIG_PPC64
-	.get_irq		= mpic_get_irq,
-#else
 	.get_irq		= mpic_get_coreint_irq,
-#endif
 	.restart		= fsl_rstcr_restart,
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/85xx/p5040_ds.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/85xx/p5040_ds.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/85xx/p5040_ds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/85xx/p5040_ds.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,12 +66,7 @@ define_machine(p5040_ds) {
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
 #endif
-/* coreint doesn't play nice with lazy EE, use legacy mpic for now */
-#ifdef CONFIG_PPC64
-	.get_irq		= mpic_get_irq,
-#else
 	.get_irq		= mpic_get_coreint_irq,
-#endif
 	.restart		= fsl_rstcr_restart,
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/85xx/smp.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/85xx/smp.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/85xx/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/85xx/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -99,7 +99,7 @@ static void mpc85xx_take_timebase(void)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static void __cpuinit smp_85xx_mach_cpu_die(void)
+static void smp_85xx_mach_cpu_die(void)
 {
 	unsigned int cpu = smp_processor_id();
 	u32 tmp;
@@ -141,7 +141,7 @@ static inline u32 read_spin_table_addr_l
 	return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
 }
 
-static int __cpuinit smp_85xx_kick_cpu(int nr)
+static int smp_85xx_kick_cpu(int nr)
 {
 	unsigned long flags;
 	const u64 *cpu_rel_addr;
@@ -362,7 +362,7 @@ static void mpc85xx_smp_machine_kexec(st
 }
 #endif /* CONFIG_KEXEC */
 
-static void __cpuinit smp_85xx_setup_cpu(int cpu_nr)
+static void smp_85xx_setup_cpu(int cpu_nr)
 {
 	if (smp_85xx_ops.probe == smp_mpic_probe)
 		mpic_setup_this_cpu();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/85xx/t4240_qds.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/85xx/t4240_qds.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/85xx/t4240_qds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/85xx/t4240_qds.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,12 +75,7 @@ define_machine(t4240_qds) {
 #ifdef CONFIG_PCI
 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
 #endif
-/* coreint doesn't play nice with lazy EE, use legacy mpic for now */
-#ifdef CONFIG_PPC64
-	.get_irq		= mpic_get_irq,
-#else
 	.get_irq		= mpic_get_coreint_irq,
-#endif
 	.restart		= fsl_rstcr_restart,
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/8xx/m8xx_setup.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/8xx/m8xx_setup.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/8xx/m8xx_setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/8xx/m8xx_setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,6 +43,7 @@ static irqreturn_t timebase_interrupt(in
 
 static struct irqaction tbint_irqaction = {
 	.handler = timebase_interrupt,
+	.flags = IRQF_NO_THREAD,
 	.name = "tbint",
 };
 
@@ -218,19 +219,12 @@ void mpc8xx_restart(char *cmd)
 
 static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
 {
-	struct irq_chip *chip;
-	int cascade_irq;
-
-	if ((cascade_irq = cpm_get_irq()) >= 0) {
-		struct irq_desc *cdesc = irq_to_desc(cascade_irq);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int cascade_irq = cpm_get_irq();
 
+	if (cascade_irq >= 0)
 		generic_handle_irq(cascade_irq);
 
-		chip = irq_desc_get_chip(cdesc);
-		chip->irq_eoi(&cdesc->irq_data);
-	}
-
-	chip = irq_desc_get_chip(desc);
 	chip->irq_eoi(&desc->irq_data);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/cell/beat_htab.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/cell/beat_htab.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/cell/beat_htab.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/cell/beat_htab.c	2013-08-25 20:43:22.000000000 -0400
@@ -185,7 +185,8 @@ static void beat_lpar_hptab_clear(void)
 static long beat_lpar_hpte_updatepp(unsigned long slot,
 				    unsigned long newpp,
 				    unsigned long vpn,
-				    int psize, int ssize, int local)
+				    int psize, int apsize,
+				    int ssize, int local)
 {
 	unsigned long lpar_rc;
 	u64 dummy0, dummy1;
@@ -274,7 +275,8 @@ static void beat_lpar_hpte_updateboltedp
 }
 
 static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn,
-					 int psize, int ssize, int local)
+				      int psize, int apsize,
+				      int ssize, int local)
 {
 	unsigned long want_v;
 	unsigned long lpar_rc;
@@ -364,9 +366,10 @@ static long beat_lpar_hpte_insert_v3(uns
  * already zero.  For now I am paranoid.
  */
 static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
-				    unsigned long newpp,
-				    unsigned long vpn,
-				    int psize, int ssize, int local)
+				       unsigned long newpp,
+				       unsigned long vpn,
+				       int psize, int apsize,
+				       int ssize, int local)
 {
 	unsigned long lpar_rc;
 	unsigned long want_v;
@@ -394,7 +397,8 @@ static long beat_lpar_hpte_updatepp_v3(u
 }
 
 static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long vpn,
-					 int psize, int ssize, int local)
+					 int psize, int apsize,
+					 int ssize, int local)
 {
 	unsigned long want_v;
 	unsigned long lpar_rc;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/cell/beat_interrupt.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/cell/beat_interrupt.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/cell/beat_interrupt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/cell/beat_interrupt.c	2013-08-25 20:43:22.000000000 -0400
@@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void)
 	ppc_md.get_irq = beatic_get_irq;
 
 	/* Allocate an irq host */
-	beatic_host = irq_domain_add_nomap(NULL, 0, &beatic_pic_host_ops, NULL);
+	beatic_host = irq_domain_add_nomap(NULL, ~0, &beatic_pic_host_ops, NULL);
 	BUG_ON(beatic_host == NULL);
 	irq_set_default_host(beatic_host);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/cell/smp.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/cell/smp.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/cell/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/cell/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -142,7 +142,7 @@ static int smp_cell_cpu_bootable(unsigne
 	 * during boot if the user requests it.  Odd-numbered
 	 * cpus are assumed to be secondary threads.
 	 */
-	if (system_state < SYSTEM_RUNNING &&
+	if (system_state == SYSTEM_BOOTING &&
 	    cpu_has_feature(CPU_FTR_SMT) &&
 	    !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
 		return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/cell/spufs/inode.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/cell/spufs/inode.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/cell/spufs/inode.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/cell/spufs/inode.c	2013-08-25 20:43:22.000000000 -0400
@@ -238,7 +238,7 @@ const struct file_operations spufs_conte
 	.release	= spufs_dir_close,
 	.llseek		= dcache_dir_lseek,
 	.read		= generic_read_dir,
-	.readdir	= dcache_readdir,
+	.iterate	= dcache_readdir,
 	.fsync		= noop_fsync,
 };
 EXPORT_SYMBOL_GPL(spufs_context_fops);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/Kconfig linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/Kconfig
--- linux-libre-3.10-gnu/arch/powerpc/platforms/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -86,6 +86,27 @@ config MPIC
 	bool
 	default n
 
+config MPIC_TIMER
+	bool "MPIC Global Timer"
+	depends on MPIC && FSL_SOC
+	default n
+	help
+	  The MPIC global timer is a hardware timer inside the
+	  Freescale PIC complying with OpenPIC standard. When the
+	  specified interval times out, the hardware timer generates
+	  an interrupt. The driver currently is only tested on fsl
+	  chip, but it can potentially support other global timers
+	  complying with the OpenPIC standard.
+
+config FSL_MPIC_TIMER_WAKEUP
+	tristate "Freescale MPIC global timer wakeup driver"
+	depends on FSL_SOC &&  MPIC_TIMER && PM
+	default n
+	help
+	  The driver provides a way to wake up the system by MPIC
+	  timer.
+	  e.g. "echo 5 > /sys/devices/system/mpic/timer_wakeup"
+
 config PPC_EPAPR_HV_PIC
 	bool
 	default n
@@ -164,6 +185,11 @@ config IBMEBUS
 	help
 	  Bus device driver for GX bus based adapters.
 
+config EEH
+	bool
+	depends on (PPC_POWERNV || PPC_PSERIES) && PCI
+	default y
+
 config PPC_MPC106
 	bool
 	default n
@@ -193,37 +219,6 @@ config PPC_IO_WORKAROUNDS
 
 source "drivers/cpufreq/Kconfig"
 
-menu "CPU Frequency drivers"
-	depends on CPU_FREQ
-
-config CPU_FREQ_PMAC
-	bool "Support for Apple PowerBooks"
-	depends on ADB_PMU && PPC32
-	select CPU_FREQ_TABLE
-	help
-	  This adds support for frequency switching on Apple PowerBooks,
-	  this currently includes some models of iBook & Titanium
-	  PowerBook.
-
-config CPU_FREQ_PMAC64
-	bool "Support for some Apple G5s"
-	depends on PPC_PMAC && PPC64
-	select CPU_FREQ_TABLE
-	help
-	  This adds support for frequency switching on Apple iMac G5,
-	  and some of the more recent desktop G5 machines as well.
-
-config PPC_PASEMI_CPUFREQ
-	bool "Support for PA Semi PWRficient"
-	depends on PPC_PASEMI
-	default y
-	select CPU_FREQ_TABLE
-	help
-	  This adds the support for frequency switching on PA Semi
-	  PWRficient processors.
-
-endmenu
-
 menu "CPUIdle driver"
 
 source "drivers/cpuidle/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/Kconfig.cputype linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/Kconfig.cputype
--- linux-libre-3.10-gnu/arch/powerpc/platforms/Kconfig.cputype	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/Kconfig.cputype	2013-08-25 20:43:22.000000000 -0400
@@ -71,6 +71,7 @@ config PPC_BOOK3S_64
 	select PPC_FPU
 	select PPC_HAVE_PMU_SUPPORT
 	select SYS_SUPPORTS_HUGETLBFS
+	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if PPC_64K_PAGES
 
 config PPC_BOOK3E_64
 	bool "Embedded processors"
@@ -158,6 +159,7 @@ config E500
 config PPC_E500MC
 	bool "e500mc Support"
 	select PPC_FPU
+	select COMMON_CLK
 	depends on E500
 	help
 	  This must be enabled for running on e500mc (and derivatives
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pasemi/cpufreq.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pasemi/cpufreq.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pasemi/cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pasemi/cpufreq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,330 +0,0 @@
-/*
- * Copyright (C) 2007 PA Semi, Inc
- *
- * Authors: Egor Martovetsky <egor@pasemi.com>
- *	    Olof Johansson <olof@lixom.net>
- *
- * Maintained by: Olof Johansson <olof@lixom.net>
- *
- * Based on arch/powerpc/platforms/cell/cbe_cpufreq.c:
- * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/cpufreq.h>
-#include <linux/timer.h>
-#include <linux/module.h>
-
-#include <asm/hw_irq.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/time.h>
-#include <asm/smp.h>
-
-#define SDCASR_REG		0x0100
-#define SDCASR_REG_STRIDE	0x1000
-#define SDCPWR_CFGA0_REG	0x0100
-#define SDCPWR_PWST0_REG	0x0000
-#define SDCPWR_GIZTIME_REG	0x0440
-
-/* SDCPWR_GIZTIME_REG fields */
-#define SDCPWR_GIZTIME_GR	0x80000000
-#define SDCPWR_GIZTIME_LONGLOCK	0x000000ff
-
-/* Offset of ASR registers from SDC base */
-#define SDCASR_OFFSET		0x120000
-
-static void __iomem *sdcpwr_mapbase;
-static void __iomem *sdcasr_mapbase;
-
-static DEFINE_MUTEX(pas_switch_mutex);
-
-/* Current astate, is used when waking up from power savings on
- * one core, in case the other core has switched states during
- * the idle time.
- */
-static int current_astate;
-
-/* We support 5(A0-A4) power states excluding turbo(A5-A6) modes */
-static struct cpufreq_frequency_table pas_freqs[] = {
-	{0,	0},
-	{1,	0},
-	{2,	0},
-	{3,	0},
-	{4,	0},
-	{0,	CPUFREQ_TABLE_END},
-};
-
-static struct freq_attr *pas_cpu_freqs_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-/*
- * hardware specific functions
- */
-
-static int get_astate_freq(int astate)
-{
-	u32 ret;
-	ret = in_le32(sdcpwr_mapbase + SDCPWR_CFGA0_REG + (astate * 0x10));
-
-	return ret & 0x3f;
-}
-
-static int get_cur_astate(int cpu)
-{
-	u32 ret;
-
-	ret = in_le32(sdcpwr_mapbase + SDCPWR_PWST0_REG);
-	ret = (ret >> (cpu * 4)) & 0x7;
-
-	return ret;
-}
-
-static int get_gizmo_latency(void)
-{
-	u32 giztime, ret;
-
-	giztime = in_le32(sdcpwr_mapbase + SDCPWR_GIZTIME_REG);
-
-	/* just provide the upper bound */
-	if (giztime & SDCPWR_GIZTIME_GR)
-		ret = (giztime & SDCPWR_GIZTIME_LONGLOCK) * 128000;
-	else
-		ret = (giztime & SDCPWR_GIZTIME_LONGLOCK) * 1000;
-
-	return ret;
-}
-
-static void set_astate(int cpu, unsigned int astate)
-{
-	unsigned long flags;
-
-	/* Return if called before init has run */
-	if (unlikely(!sdcasr_mapbase))
-		return;
-
-	local_irq_save(flags);
-
-	out_le32(sdcasr_mapbase + SDCASR_REG + SDCASR_REG_STRIDE*cpu, astate);
-
-	local_irq_restore(flags);
-}
-
-int check_astate(void)
-{
-	return get_cur_astate(hard_smp_processor_id());
-}
-
-void restore_astate(int cpu)
-{
-	set_astate(cpu, current_astate);
-}
-
-/*
- * cpufreq functions
- */
-
-static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
-	const u32 *max_freqp;
-	u32 max_freq;
-	int i, cur_astate;
-	struct resource res;
-	struct device_node *cpu, *dn;
-	int err = -ENODEV;
-
-	cpu = of_get_cpu_node(policy->cpu, NULL);
-
-	if (!cpu)
-		goto out;
-
-	dn = of_find_compatible_node(NULL, NULL, "1682m-sdc");
-	if (!dn)
-		dn = of_find_compatible_node(NULL, NULL,
-					     "pasemi,pwrficient-sdc");
-	if (!dn)
-		goto out;
-	err = of_address_to_resource(dn, 0, &res);
-	of_node_put(dn);
-	if (err)
-		goto out;
-	sdcasr_mapbase = ioremap(res.start + SDCASR_OFFSET, 0x2000);
-	if (!sdcasr_mapbase) {
-		err = -EINVAL;
-		goto out;
-	}
-
-	dn = of_find_compatible_node(NULL, NULL, "1682m-gizmo");
-	if (!dn)
-		dn = of_find_compatible_node(NULL, NULL,
-					     "pasemi,pwrficient-gizmo");
-	if (!dn) {
-		err = -ENODEV;
-		goto out_unmap_sdcasr;
-	}
-	err = of_address_to_resource(dn, 0, &res);
-	of_node_put(dn);
-	if (err)
-		goto out_unmap_sdcasr;
-	sdcpwr_mapbase = ioremap(res.start, 0x1000);
-	if (!sdcpwr_mapbase) {
-		err = -EINVAL;
-		goto out_unmap_sdcasr;
-	}
-
-	pr_debug("init cpufreq on CPU %d\n", policy->cpu);
-
-	max_freqp = of_get_property(cpu, "clock-frequency", NULL);
-	if (!max_freqp) {
-		err = -EINVAL;
-		goto out_unmap_sdcpwr;
-	}
-
-	/* we need the freq in kHz */
-	max_freq = *max_freqp / 1000;
-
-	pr_debug("max clock-frequency is at %u kHz\n", max_freq);
-	pr_debug("initializing frequency table\n");
-
-	/* initialize frequency table */
-	for (i=0; pas_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
-		pas_freqs[i].frequency = get_astate_freq(pas_freqs[i].index) * 100000;
-		pr_debug("%d: %d\n", i, pas_freqs[i].frequency);
-	}
-
-	policy->cpuinfo.transition_latency = get_gizmo_latency();
-
-	cur_astate = get_cur_astate(policy->cpu);
-	pr_debug("current astate is at %d\n",cur_astate);
-
-	policy->cur = pas_freqs[cur_astate].frequency;
-	cpumask_copy(policy->cpus, cpu_online_mask);
-
-	ppc_proc_freq = policy->cur * 1000ul;
-
-	cpufreq_frequency_table_get_attr(pas_freqs, policy->cpu);
-
-	/* this ensures that policy->cpuinfo_min and policy->cpuinfo_max
-	 * are set correctly
-	 */
-	return cpufreq_frequency_table_cpuinfo(policy, pas_freqs);
-
-out_unmap_sdcpwr:
-	iounmap(sdcpwr_mapbase);
-
-out_unmap_sdcasr:
-	iounmap(sdcasr_mapbase);
-out:
-	return err;
-}
-
-static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy)
-{
-	/*
-	 * We don't support CPU hotplug. Don't unmap after the system
-	 * has already made it to a running state.
-	 */
-	if (system_state != SYSTEM_BOOTING)
-		return 0;
-
-	if (sdcasr_mapbase)
-		iounmap(sdcasr_mapbase);
-	if (sdcpwr_mapbase)
-		iounmap(sdcpwr_mapbase);
-
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	return 0;
-}
-
-static int pas_cpufreq_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, pas_freqs);
-}
-
-static int pas_cpufreq_target(struct cpufreq_policy *policy,
-			      unsigned int target_freq,
-			      unsigned int relation)
-{
-	struct cpufreq_freqs freqs;
-	int pas_astate_new;
-	int i;
-
-	cpufreq_frequency_table_target(policy,
-				       pas_freqs,
-				       target_freq,
-				       relation,
-				       &pas_astate_new);
-
-	freqs.old = policy->cur;
-	freqs.new = pas_freqs[pas_astate_new].frequency;
-
-	mutex_lock(&pas_switch_mutex);
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-
-	pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n",
-		 policy->cpu,
-		 pas_freqs[pas_astate_new].frequency,
-		 pas_freqs[pas_astate_new].index);
-
-	current_astate = pas_astate_new;
-
-	for_each_online_cpu(i)
-		set_astate(i, pas_astate_new);
-
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-	mutex_unlock(&pas_switch_mutex);
-
-	ppc_proc_freq = freqs.new * 1000ul;
-	return 0;
-}
-
-static struct cpufreq_driver pas_cpufreq_driver = {
-	.name		= "pas-cpufreq",
-	.owner		= THIS_MODULE,
-	.flags		= CPUFREQ_CONST_LOOPS,
-	.init		= pas_cpufreq_cpu_init,
-	.exit		= pas_cpufreq_cpu_exit,
-	.verify		= pas_cpufreq_verify,
-	.target		= pas_cpufreq_target,
-	.attr		= pas_cpu_freqs_attr,
-};
-
-/*
- * module init and destoy
- */
-
-static int __init pas_cpufreq_init(void)
-{
-	if (!of_machine_is_compatible("PA6T-1682M") &&
-	    !of_machine_is_compatible("pasemi,pwrficient"))
-		return -ENODEV;
-
-	return cpufreq_register_driver(&pas_cpufreq_driver);
-}
-
-static void __exit pas_cpufreq_exit(void)
-{
-	cpufreq_unregister_driver(&pas_cpufreq_driver);
-}
-
-module_init(pas_cpufreq_init);
-module_exit(pas_cpufreq_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>, Olof Johansson <olof@lixom.net>");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pasemi/Makefile linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pasemi/Makefile
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pasemi/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pasemi/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,3 +1,2 @@
 obj-y	+= setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o misc.o
 obj-$(CONFIG_PPC_PASEMI_MDIO)	+= gpio_mdio.o
-obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powermac/cpufreq_32.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powermac/cpufreq_32.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powermac/cpufreq_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powermac/cpufreq_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,721 +0,0 @@
-/*
- *  Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
- *  Copyright (C) 2004        John Steele Scott <toojays@toojays.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * TODO: Need a big cleanup here. Basically, we need to have different
- * cpufreq_driver structures for the different type of HW instead of the
- * current mess. We also need to better deal with the detection of the
- * type of machine.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/cpufreq.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/hardirq.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/irq.h>
-#include <asm/pmac_feature.h>
-#include <asm/mmu_context.h>
-#include <asm/sections.h>
-#include <asm/cputable.h>
-#include <asm/time.h>
-#include <asm/mpic.h>
-#include <asm/keylargo.h>
-#include <asm/switch_to.h>
-
-/* WARNING !!! This will cause calibrate_delay() to be called,
- * but this is an __init function ! So you MUST go edit
- * init/main.c to make it non-init before enabling DEBUG_FREQ
- */
-#undef DEBUG_FREQ
-
-extern void low_choose_7447a_dfs(int dfs);
-extern void low_choose_750fx_pll(int pll);
-extern void low_sleep_handler(void);
-
-/*
- * Currently, PowerMac cpufreq supports only high & low frequencies
- * that are set by the firmware
- */
-static unsigned int low_freq;
-static unsigned int hi_freq;
-static unsigned int cur_freq;
-static unsigned int sleep_freq;
-static unsigned long transition_latency;
-
-/*
- * Different models uses different mechanisms to switch the frequency
- */
-static int (*set_speed_proc)(int low_speed);
-static unsigned int (*get_speed_proc)(void);
-
-/*
- * Some definitions used by the various speedprocs
- */
-static u32 voltage_gpio;
-static u32 frequency_gpio;
-static u32 slew_done_gpio;
-static int no_schedule;
-static int has_cpu_l2lve;
-static int is_pmu_based;
-
-/* There are only two frequency states for each processor. Values
- * are in kHz for the time being.
- */
-#define CPUFREQ_HIGH                  0
-#define CPUFREQ_LOW                   1
-
-static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
-	{CPUFREQ_HIGH, 		0},
-	{CPUFREQ_LOW,		0},
-	{0,			CPUFREQ_TABLE_END},
-};
-
-static struct freq_attr* pmac_cpu_freqs_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-static inline void local_delay(unsigned long ms)
-{
-	if (no_schedule)
-		mdelay(ms);
-	else
-		msleep(ms);
-}
-
-#ifdef DEBUG_FREQ
-static inline void debug_calc_bogomips(void)
-{
-	/* This will cause a recalc of bogomips and display the
-	 * result. We backup/restore the value to avoid affecting the
-	 * core cpufreq framework's own calculation.
-	 */
-	unsigned long save_lpj = loops_per_jiffy;
-	calibrate_delay();
-	loops_per_jiffy = save_lpj;
-}
-#endif /* DEBUG_FREQ */
-
-/* Switch CPU speed under 750FX CPU control
- */
-static int cpu_750fx_cpu_speed(int low_speed)
-{
-	u32 hid2;
-
-	if (low_speed == 0) {
-		/* ramping up, set voltage first */
-		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
-		/* Make sure we sleep for at least 1ms */
-		local_delay(10);
-
-		/* tweak L2 for high voltage */
-		if (has_cpu_l2lve) {
-			hid2 = mfspr(SPRN_HID2);
-			hid2 &= ~0x2000;
-			mtspr(SPRN_HID2, hid2);
-		}
-	}
-#ifdef CONFIG_6xx
-	low_choose_750fx_pll(low_speed);
-#endif
-	if (low_speed == 1) {
-		/* tweak L2 for low voltage */
-		if (has_cpu_l2lve) {
-			hid2 = mfspr(SPRN_HID2);
-			hid2 |= 0x2000;
-			mtspr(SPRN_HID2, hid2);
-		}
-
-		/* ramping down, set voltage last */
-		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
-		local_delay(10);
-	}
-
-	return 0;
-}
-
-static unsigned int cpu_750fx_get_cpu_speed(void)
-{
-	if (mfspr(SPRN_HID1) & HID1_PS)
-		return low_freq;
-	else
-		return hi_freq;
-}
-
-/* Switch CPU speed using DFS */
-static int dfs_set_cpu_speed(int low_speed)
-{
-	if (low_speed == 0) {
-		/* ramping up, set voltage first */
-		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
-		/* Make sure we sleep for at least 1ms */
-		local_delay(1);
-	}
-
-	/* set frequency */
-#ifdef CONFIG_6xx
-	low_choose_7447a_dfs(low_speed);
-#endif
-	udelay(100);
-
-	if (low_speed == 1) {
-		/* ramping down, set voltage last */
-		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
-		local_delay(1);
-	}
-
-	return 0;
-}
-
-static unsigned int dfs_get_cpu_speed(void)
-{
-	if (mfspr(SPRN_HID1) & HID1_DFS)
-		return low_freq;
-	else
-		return hi_freq;
-}
-
-
-/* Switch CPU speed using slewing GPIOs
- */
-static int gpios_set_cpu_speed(int low_speed)
-{
-	int gpio, timeout = 0;
-
-	/* If ramping up, set voltage first */
-	if (low_speed == 0) {
-		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
-		/* Delay is way too big but it's ok, we schedule */
-		local_delay(10);
-	}
-
-	/* Set frequency */
-	gpio = 	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
-	if (low_speed == ((gpio & 0x01) == 0))
-		goto skip;
-
-	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
-			  low_speed ? 0x04 : 0x05);
-	udelay(200);
-	do {
-		if (++timeout > 100)
-			break;
-		local_delay(1);
-		gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
-	} while((gpio & 0x02) == 0);
- skip:
-	/* If ramping down, set voltage last */
-	if (low_speed == 1) {
-		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
-		/* Delay is way too big but it's ok, we schedule */
-		local_delay(10);
-	}
-
-#ifdef DEBUG_FREQ
-	debug_calc_bogomips();
-#endif
-
-	return 0;
-}
-
-/* Switch CPU speed under PMU control
- */
-static int pmu_set_cpu_speed(int low_speed)
-{
-	struct adb_request req;
-	unsigned long save_l2cr;
-	unsigned long save_l3cr;
-	unsigned int pic_prio;
-	unsigned long flags;
-
-	preempt_disable();
-
-#ifdef DEBUG_FREQ
-	printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
-#endif
-	pmu_suspend();
-
-	/* Disable all interrupt sources on openpic */
- 	pic_prio = mpic_cpu_get_priority();
-	mpic_cpu_set_priority(0xf);
-
-	/* Make sure the decrementer won't interrupt us */
-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-	/* Make sure any pending DEC interrupt occurring while we did
-	 * the above didn't re-enable the DEC */
-	mb();
-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-
-	/* We can now disable MSR_EE */
-	local_irq_save(flags);
-
-	/* Giveup the FPU & vec */
-	enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
-	if (cpu_has_feature(CPU_FTR_ALTIVEC))
-		enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
-	/* Save & disable L2 and L3 caches */
-	save_l3cr = _get_L3CR();	/* (returns -1 if not available) */
-	save_l2cr = _get_L2CR();	/* (returns -1 if not available) */
-
-	/* Send the new speed command. My assumption is that this command
-	 * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
-	 */
-	pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
-	while (!req.complete)
-		pmu_poll();
-
-	/* Prepare the northbridge for the speed transition */
-	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
-
-	/* Call low level code to backup CPU state and recover from
-	 * hardware reset
-	 */
-	low_sleep_handler();
-
-	/* Restore the northbridge */
-	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
-
-	/* Restore L2 cache */
-	if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
- 		_set_L2CR(save_l2cr);
-	/* Restore L3 cache */
-	if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
- 		_set_L3CR(save_l3cr);
-
-	/* Restore userland MMU context */
-	switch_mmu_context(NULL, current->active_mm);
-
-#ifdef DEBUG_FREQ
-	printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
-#endif
-
-	/* Restore low level PMU operations */
-	pmu_unlock();
-
-	/*
-	 * Restore decrementer; we'll take a decrementer interrupt
-	 * as soon as interrupts are re-enabled and the generic
-	 * clockevents code will reprogram it with the right value.
-	 */
-	set_dec(1);
-
-	/* Restore interrupts */
- 	mpic_cpu_set_priority(pic_prio);
-
-	/* Let interrupts flow again ... */
-	local_irq_restore(flags);
-
-#ifdef DEBUG_FREQ
-	debug_calc_bogomips();
-#endif
-
-	pmu_resume();
-
-	preempt_enable();
-
-	return 0;
-}
-
-static int do_set_cpu_speed(struct cpufreq_policy *policy, int speed_mode,
-		int notify)
-{
-	struct cpufreq_freqs freqs;
-	unsigned long l3cr;
-	static unsigned long prev_l3cr;
-
-	freqs.old = cur_freq;
-	freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
-
-	if (freqs.old == freqs.new)
-		return 0;
-
-	if (notify)
-		cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-	if (speed_mode == CPUFREQ_LOW &&
-	    cpu_has_feature(CPU_FTR_L3CR)) {
-		l3cr = _get_L3CR();
-		if (l3cr & L3CR_L3E) {
-			prev_l3cr = l3cr;
-			_set_L3CR(0);
-		}
-	}
-	set_speed_proc(speed_mode == CPUFREQ_LOW);
-	if (speed_mode == CPUFREQ_HIGH &&
-	    cpu_has_feature(CPU_FTR_L3CR)) {
-		l3cr = _get_L3CR();
-		if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
-			_set_L3CR(prev_l3cr);
-	}
-	if (notify)
-		cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-	cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
-
-	return 0;
-}
-
-static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
-{
-	return cur_freq;
-}
-
-static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
-}
-
-static int pmac_cpufreq_target(	struct cpufreq_policy *policy,
-					unsigned int target_freq,
-					unsigned int relation)
-{
-	unsigned int    newstate = 0;
-	int		rc;
-
-	if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
-			target_freq, relation, &newstate))
-		return -EINVAL;
-
-	rc = do_set_cpu_speed(policy, newstate, 1);
-
-	ppc_proc_freq = cur_freq * 1000ul;
-	return rc;
-}
-
-static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
-	if (policy->cpu != 0)
-		return -ENODEV;
-
-	policy->cpuinfo.transition_latency	= transition_latency;
-	policy->cur = cur_freq;
-
-	cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
-	return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
-}
-
-static u32 read_gpio(struct device_node *np)
-{
-	const u32 *reg = of_get_property(np, "reg", NULL);
-	u32 offset;
-
-	if (reg == NULL)
-		return 0;
-	/* That works for all keylargos but shall be fixed properly
-	 * some day... The problem is that it seems we can't rely
-	 * on the "reg" property of the GPIO nodes, they are either
-	 * relative to the base of KeyLargo or to the base of the
-	 * GPIO space, and the device-tree doesn't help.
-	 */
-	offset = *reg;
-	if (offset < KEYLARGO_GPIO_LEVELS0)
-		offset += KEYLARGO_GPIO_LEVELS0;
-	return offset;
-}
-
-static int pmac_cpufreq_suspend(struct cpufreq_policy *policy)
-{
-	/* Ok, this could be made a bit smarter, but let's be robust for now. We
-	 * always force a speed change to high speed before sleep, to make sure
-	 * we have appropriate voltage and/or bus speed for the wakeup process,
-	 * and to make sure our loops_per_jiffies are "good enough", that is will
-	 * not cause too short delays if we sleep in low speed and wake in high
-	 * speed..
-	 */
-	no_schedule = 1;
-	sleep_freq = cur_freq;
-	if (cur_freq == low_freq && !is_pmu_based)
-		do_set_cpu_speed(policy, CPUFREQ_HIGH, 0);
-	return 0;
-}
-
-static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
-{
-	/* If we resume, first check if we have a get() function */
-	if (get_speed_proc)
-		cur_freq = get_speed_proc();
-	else
-		cur_freq = 0;
-
-	/* We don't, hrm... we don't really know our speed here, best
-	 * is that we force a switch to whatever it was, which is
-	 * probably high speed due to our suspend() routine
-	 */
-	do_set_cpu_speed(policy, sleep_freq == low_freq ?
-			 CPUFREQ_LOW : CPUFREQ_HIGH, 0);
-
-	ppc_proc_freq = cur_freq * 1000ul;
-
-	no_schedule = 0;
-	return 0;
-}
-
-static struct cpufreq_driver pmac_cpufreq_driver = {
-	.verify 	= pmac_cpufreq_verify,
-	.target 	= pmac_cpufreq_target,
-	.get		= pmac_cpufreq_get_speed,
-	.init		= pmac_cpufreq_cpu_init,
-	.suspend	= pmac_cpufreq_suspend,
-	.resume		= pmac_cpufreq_resume,
-	.flags		= CPUFREQ_PM_NO_WARN,
-	.attr		= pmac_cpu_freqs_attr,
-	.name		= "powermac",
-	.owner		= THIS_MODULE,
-};
-
-
-static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
-{
-	struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
-								"voltage-gpio");
-	struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
-								"frequency-gpio");
-	struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
-								     "slewing-done");
-	const u32 *value;
-
-	/*
-	 * Check to see if it's GPIO driven or PMU only
-	 *
-	 * The way we extract the GPIO address is slightly hackish, but it
-	 * works well enough for now. We need to abstract the whole GPIO
-	 * stuff sooner or later anyway
-	 */
-
-	if (volt_gpio_np)
-		voltage_gpio = read_gpio(volt_gpio_np);
-	if (freq_gpio_np)
-		frequency_gpio = read_gpio(freq_gpio_np);
-	if (slew_done_gpio_np)
-		slew_done_gpio = read_gpio(slew_done_gpio_np);
-
-	/* If we use the frequency GPIOs, calculate the min/max speeds based
-	 * on the bus frequencies
-	 */
-	if (frequency_gpio && slew_done_gpio) {
-		int lenp, rc;
-		const u32 *freqs, *ratio;
-
-		freqs = of_get_property(cpunode, "bus-frequencies", &lenp);
-		lenp /= sizeof(u32);
-		if (freqs == NULL || lenp != 2) {
-			printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
-			return 1;
-		}
-		ratio = of_get_property(cpunode, "processor-to-bus-ratio*2",
-						NULL);
-		if (ratio == NULL) {
-			printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
-			return 1;
-		}
-
-		/* Get the min/max bus frequencies */
-		low_freq = min(freqs[0], freqs[1]);
-		hi_freq = max(freqs[0], freqs[1]);
-
-		/* Grrrr.. It _seems_ that the device-tree is lying on the low bus
-		 * frequency, it claims it to be around 84Mhz on some models while
-		 * it appears to be approx. 101Mhz on all. Let's hack around here...
-		 * fortunately, we don't need to be too precise
-		 */
-		if (low_freq < 98000000)
-			low_freq = 101000000;
-
-		/* Convert those to CPU core clocks */
-		low_freq = (low_freq * (*ratio)) / 2000;
-		hi_freq = (hi_freq * (*ratio)) / 2000;
-
-		/* Now we get the frequencies, we read the GPIO to see what is out current
-		 * speed
-		 */
-		rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
-		cur_freq = (rc & 0x01) ? hi_freq : low_freq;
-
-		set_speed_proc = gpios_set_cpu_speed;
-		return 1;
-	}
-
-	/* If we use the PMU, look for the min & max frequencies in the
-	 * device-tree
-	 */
-	value = of_get_property(cpunode, "min-clock-frequency", NULL);
-	if (!value)
-		return 1;
-	low_freq = (*value) / 1000;
-	/* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
-	 * here */
-	if (low_freq < 100000)
-		low_freq *= 10;
-
-	value = of_get_property(cpunode, "max-clock-frequency", NULL);
-	if (!value)
-		return 1;
-	hi_freq = (*value) / 1000;
-	set_speed_proc = pmu_set_cpu_speed;
-	is_pmu_based = 1;
-
-	return 0;
-}
-
-static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
-{
-	struct device_node *volt_gpio_np;
-
-	if (of_get_property(cpunode, "dynamic-power-step", NULL) == NULL)
-		return 1;
-
-	volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
-	if (volt_gpio_np)
-		voltage_gpio = read_gpio(volt_gpio_np);
-	if (!voltage_gpio){
-		printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
-		return 1;
-	}
-
-	/* OF only reports the high frequency */
-	hi_freq = cur_freq;
-	low_freq = cur_freq/2;
-
-	/* Read actual frequency from CPU */
-	cur_freq = dfs_get_cpu_speed();
-	set_speed_proc = dfs_set_cpu_speed;
-	get_speed_proc = dfs_get_cpu_speed;
-
-	return 0;
-}
-
-static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
-{
-	struct device_node *volt_gpio_np;
-	u32 pvr;
-	const u32 *value;
-
-	if (of_get_property(cpunode, "dynamic-power-step", NULL) == NULL)
-		return 1;
-
-	hi_freq = cur_freq;
-	value = of_get_property(cpunode, "reduced-clock-frequency", NULL);
-	if (!value)
-		return 1;
-	low_freq = (*value) / 1000;
-
-	volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
-	if (volt_gpio_np)
-		voltage_gpio = read_gpio(volt_gpio_np);
-
-	pvr = mfspr(SPRN_PVR);
-	has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
-
-	set_speed_proc = cpu_750fx_cpu_speed;
-	get_speed_proc = cpu_750fx_get_cpu_speed;
-	cur_freq = cpu_750fx_get_cpu_speed();
-
-	return 0;
-}
-
-/* Currently, we support the following machines:
- *
- *  - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
- *  - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
- *  - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
- *  - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
- *  - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
- *  - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
- *  - Recent MacRISC3 laptops
- *  - All new machines with 7447A CPUs
- */
-static int __init pmac_cpufreq_setup(void)
-{
-	struct device_node	*cpunode;
-	const u32		*value;
-
-	if (strstr(cmd_line, "nocpufreq"))
-		return 0;
-
-	/* Assume only one CPU */
-	cpunode = of_find_node_by_type(NULL, "cpu");
-	if (!cpunode)
-		goto out;
-
-	/* Get current cpu clock freq */
-	value = of_get_property(cpunode, "clock-frequency", NULL);
-	if (!value)
-		goto out;
-	cur_freq = (*value) / 1000;
-	transition_latency = CPUFREQ_ETERNAL;
-
-	/*  Check for 7447A based MacRISC3 */
-	if (of_machine_is_compatible("MacRISC3") &&
-	    of_get_property(cpunode, "dynamic-power-step", NULL) &&
-	    PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
-		pmac_cpufreq_init_7447A(cpunode);
-		transition_latency = 8000000;
-	/* Check for other MacRISC3 machines */
-	} else if (of_machine_is_compatible("PowerBook3,4") ||
-		   of_machine_is_compatible("PowerBook3,5") ||
-		   of_machine_is_compatible("MacRISC3")) {
-		pmac_cpufreq_init_MacRISC3(cpunode);
-	/* Else check for iBook2 500/600 */
-	} else if (of_machine_is_compatible("PowerBook4,1")) {
-		hi_freq = cur_freq;
-		low_freq = 400000;
-		set_speed_proc = pmu_set_cpu_speed;
-		is_pmu_based = 1;
-	}
-	/* Else check for TiPb 550 */
-	else if (of_machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
-		hi_freq = cur_freq;
-		low_freq = 500000;
-		set_speed_proc = pmu_set_cpu_speed;
-		is_pmu_based = 1;
-	}
-	/* Else check for TiPb 400 & 500 */
-	else if (of_machine_is_compatible("PowerBook3,2")) {
-		/* We only know about the 400 MHz and the 500Mhz model
-		 * they both have 300 MHz as low frequency
-		 */
-		if (cur_freq < 350000 || cur_freq > 550000)
-			goto out;
-		hi_freq = cur_freq;
-		low_freq = 300000;
-		set_speed_proc = pmu_set_cpu_speed;
-		is_pmu_based = 1;
-	}
-	/* Else check for 750FX */
-	else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
-		pmac_cpufreq_init_750FX(cpunode);
-out:
-	of_node_put(cpunode);
-	if (set_speed_proc == NULL)
-		return -ENODEV;
-
-	pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
-	pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
-	ppc_proc_freq = cur_freq * 1000ul;
-
-	printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
-	printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
-	       low_freq/1000, hi_freq/1000, cur_freq/1000);
-
-	return cpufreq_register_driver(&pmac_cpufreq_driver);
-}
-
-module_init(pmac_cpufreq_setup);
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powermac/cpufreq_64.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powermac/cpufreq_64.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powermac/cpufreq_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powermac/cpufreq_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,746 +0,0 @@
-/*
- *  Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
- *  and                       Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This driver adds basic cpufreq support for SMU & 970FX based G5 Macs,
- * that is iMac G5 and latest single CPU desktop.
- */
-
-#undef DEBUG
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/cpufreq.h>
-#include <linux/init.h>
-#include <linux/completion.h>
-#include <linux/mutex.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/irq.h>
-#include <asm/sections.h>
-#include <asm/cputable.h>
-#include <asm/time.h>
-#include <asm/smu.h>
-#include <asm/pmac_pfunc.h>
-
-#define DBG(fmt...) pr_debug(fmt)
-
-/* see 970FX user manual */
-
-#define SCOM_PCR 0x0aa001			/* PCR scom addr */
-
-#define PCR_HILO_SELECT		0x80000000U	/* 1 = PCR, 0 = PCRH */
-#define PCR_SPEED_FULL		0x00000000U	/* 1:1 speed value */
-#define PCR_SPEED_HALF		0x00020000U	/* 1:2 speed value */
-#define PCR_SPEED_QUARTER	0x00040000U	/* 1:4 speed value */
-#define PCR_SPEED_MASK		0x000e0000U	/* speed mask */
-#define PCR_SPEED_SHIFT		17
-#define PCR_FREQ_REQ_VALID	0x00010000U	/* freq request valid */
-#define PCR_VOLT_REQ_VALID	0x00008000U	/* volt request valid */
-#define PCR_TARGET_TIME_MASK	0x00006000U	/* target time */
-#define PCR_STATLAT_MASK	0x00001f00U	/* STATLAT value */
-#define PCR_SNOOPLAT_MASK	0x000000f0U	/* SNOOPLAT value */
-#define PCR_SNOOPACC_MASK	0x0000000fU	/* SNOOPACC value */
-
-#define SCOM_PSR 0x408001			/* PSR scom addr */
-/* warning: PSR is a 64 bits register */
-#define PSR_CMD_RECEIVED	0x2000000000000000U   /* command received */
-#define PSR_CMD_COMPLETED	0x1000000000000000U   /* command completed */
-#define PSR_CUR_SPEED_MASK	0x0300000000000000U   /* current speed */
-#define PSR_CUR_SPEED_SHIFT	(56)
-
-/*
- * The G5 only supports two frequencies (Quarter speed is not supported)
- */
-#define CPUFREQ_HIGH                  0
-#define CPUFREQ_LOW                   1
-
-static struct cpufreq_frequency_table g5_cpu_freqs[] = {
-	{CPUFREQ_HIGH, 		0},
-	{CPUFREQ_LOW,		0},
-	{0,			CPUFREQ_TABLE_END},
-};
-
-static struct freq_attr* g5_cpu_freqs_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-/* Power mode data is an array of the 32 bits PCR values to use for
- * the various frequencies, retrieved from the device-tree
- */
-static int g5_pmode_cur;
-
-static void (*g5_switch_volt)(int speed_mode);
-static int (*g5_switch_freq)(int speed_mode);
-static int (*g5_query_freq)(void);
-
-static DEFINE_MUTEX(g5_switch_mutex);
-
-static unsigned long transition_latency;
-
-#ifdef CONFIG_PMAC_SMU
-
-static const u32 *g5_pmode_data;
-static int g5_pmode_max;
-
-static struct smu_sdbp_fvt *g5_fvt_table;	/* table of op. points */
-static int g5_fvt_count;			/* number of op. points */
-static int g5_fvt_cur;				/* current op. point */
-
-/*
- * SMU based voltage switching for Neo2 platforms
- */
-
-static void g5_smu_switch_volt(int speed_mode)
-{
-	struct smu_simple_cmd	cmd;
-
-	DECLARE_COMPLETION_ONSTACK(comp);
-	smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, smu_done_complete,
-			 &comp, 'V', 'S', 'L', 'E', 'W',
-			 0xff, g5_fvt_cur+1, speed_mode);
-	wait_for_completion(&comp);
-}
-
-/*
- * Platform function based voltage/vdnap switching for Neo2
- */
-
-static struct pmf_function *pfunc_set_vdnap0;
-static struct pmf_function *pfunc_vdnap0_complete;
-
-static void g5_vdnap_switch_volt(int speed_mode)
-{
-	struct pmf_args args;
-	u32 slew, done = 0;
-	unsigned long timeout;
-
-	slew = (speed_mode == CPUFREQ_LOW) ? 1 : 0;
-	args.count = 1;
-	args.u[0].p = &slew;
-
-	pmf_call_one(pfunc_set_vdnap0, &args);
-
-	/* It's an irq GPIO so we should be able to just block here,
-	 * I'll do that later after I've properly tested the IRQ code for
-	 * platform functions
-	 */
-	timeout = jiffies + HZ/10;
-	while(!time_after(jiffies, timeout)) {
-		args.count = 1;
-		args.u[0].p = &done;
-		pmf_call_one(pfunc_vdnap0_complete, &args);
-		if (done)
-			break;
-		msleep(1);
-	}
-	if (done == 0)
-		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
-}
-
-
-/*
- * SCOM based frequency switching for 970FX rev3
- */
-static int g5_scom_switch_freq(int speed_mode)
-{
-	unsigned long flags;
-	int to;
-
-	/* If frequency is going up, first ramp up the voltage */
-	if (speed_mode < g5_pmode_cur)
-		g5_switch_volt(speed_mode);
-
-	local_irq_save(flags);
-
-	/* Clear PCR high */
-	scom970_write(SCOM_PCR, 0);
-	/* Clear PCR low */
-       	scom970_write(SCOM_PCR, PCR_HILO_SELECT | 0);
-	/* Set PCR low */
-	scom970_write(SCOM_PCR, PCR_HILO_SELECT |
-		      g5_pmode_data[speed_mode]);
-
-	/* Wait for completion */
-	for (to = 0; to < 10; to++) {
-		unsigned long psr = scom970_read(SCOM_PSR);
-
-		if ((psr & PSR_CMD_RECEIVED) == 0 &&
-		    (((psr >> PSR_CUR_SPEED_SHIFT) ^
-		      (g5_pmode_data[speed_mode] >> PCR_SPEED_SHIFT)) & 0x3)
-		    == 0)
-			break;
-		if (psr & PSR_CMD_COMPLETED)
-			break;
-		udelay(100);
-	}
-
-	local_irq_restore(flags);
-
-	/* If frequency is going down, last ramp the voltage */
-	if (speed_mode > g5_pmode_cur)
-		g5_switch_volt(speed_mode);
-
-	g5_pmode_cur = speed_mode;
-	ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;
-
-	return 0;
-}
-
-static int g5_scom_query_freq(void)
-{
-	unsigned long psr = scom970_read(SCOM_PSR);
-	int i;
-
-	for (i = 0; i <= g5_pmode_max; i++)
-		if ((((psr >> PSR_CUR_SPEED_SHIFT) ^
-		      (g5_pmode_data[i] >> PCR_SPEED_SHIFT)) & 0x3) == 0)
-			break;
-	return i;
-}
-
-/*
- * Fake voltage switching for platforms with missing support
- */
-
-static void g5_dummy_switch_volt(int speed_mode)
-{
-}
-
-#endif /* CONFIG_PMAC_SMU */
-
-/*
- * Platform function based voltage switching for PowerMac7,2 & 7,3
- */
-
-static struct pmf_function *pfunc_cpu0_volt_high;
-static struct pmf_function *pfunc_cpu0_volt_low;
-static struct pmf_function *pfunc_cpu1_volt_high;
-static struct pmf_function *pfunc_cpu1_volt_low;
-
-static void g5_pfunc_switch_volt(int speed_mode)
-{
-	if (speed_mode == CPUFREQ_HIGH) {
-		if (pfunc_cpu0_volt_high)
-			pmf_call_one(pfunc_cpu0_volt_high, NULL);
-		if (pfunc_cpu1_volt_high)
-			pmf_call_one(pfunc_cpu1_volt_high, NULL);
-	} else {
-		if (pfunc_cpu0_volt_low)
-			pmf_call_one(pfunc_cpu0_volt_low, NULL);
-		if (pfunc_cpu1_volt_low)
-			pmf_call_one(pfunc_cpu1_volt_low, NULL);
-	}
-	msleep(10); /* should be faster , to fix */
-}
-
-/*
- * Platform function based frequency switching for PowerMac7,2 & 7,3
- */
-
-static struct pmf_function *pfunc_cpu_setfreq_high;
-static struct pmf_function *pfunc_cpu_setfreq_low;
-static struct pmf_function *pfunc_cpu_getfreq;
-static struct pmf_function *pfunc_slewing_done;
-
-static int g5_pfunc_switch_freq(int speed_mode)
-{
-	struct pmf_args args;
-	u32 done = 0;
-	unsigned long timeout;
-	int rc;
-
-	DBG("g5_pfunc_switch_freq(%d)\n", speed_mode);
-
-	/* If frequency is going up, first ramp up the voltage */
-	if (speed_mode < g5_pmode_cur)
-		g5_switch_volt(speed_mode);
-
-	/* Do it */
-	if (speed_mode == CPUFREQ_HIGH)
-		rc = pmf_call_one(pfunc_cpu_setfreq_high, NULL);
-	else
-		rc = pmf_call_one(pfunc_cpu_setfreq_low, NULL);
-
-	if (rc)
-		printk(KERN_WARNING "cpufreq: pfunc switch error %d\n", rc);
-
-	/* It's an irq GPIO so we should be able to just block here,
-	 * I'll do that later after I've properly tested the IRQ code for
-	 * platform functions
-	 */
-	timeout = jiffies + HZ/10;
-	while(!time_after(jiffies, timeout)) {
-		args.count = 1;
-		args.u[0].p = &done;
-		pmf_call_one(pfunc_slewing_done, &args);
-		if (done)
-			break;
-		msleep(1);
-	}
-	if (done == 0)
-		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
-
-	/* If frequency is going down, last ramp the voltage */
-	if (speed_mode > g5_pmode_cur)
-		g5_switch_volt(speed_mode);
-
-	g5_pmode_cur = speed_mode;
-	ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;
-
-	return 0;
-}
-
-static int g5_pfunc_query_freq(void)
-{
-	struct pmf_args args;
-	u32 val = 0;
-
-	args.count = 1;
-	args.u[0].p = &val;
-	pmf_call_one(pfunc_cpu_getfreq, &args);
-	return val ? CPUFREQ_HIGH : CPUFREQ_LOW;
-}
-
-
-/*
- * Common interface to the cpufreq core
- */
-
-static int g5_cpufreq_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, g5_cpu_freqs);
-}
-
-static int g5_cpufreq_target(struct cpufreq_policy *policy,
-	unsigned int target_freq, unsigned int relation)
-{
-	unsigned int newstate = 0;
-	struct cpufreq_freqs freqs;
-	int rc;
-
-	if (cpufreq_frequency_table_target(policy, g5_cpu_freqs,
-			target_freq, relation, &newstate))
-		return -EINVAL;
-
-	if (g5_pmode_cur == newstate)
-		return 0;
-
-	mutex_lock(&g5_switch_mutex);
-
-	freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
-	freqs.new = g5_cpu_freqs[newstate].frequency;
-
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-	rc = g5_switch_freq(newstate);
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-
-	mutex_unlock(&g5_switch_mutex);
-
-	return rc;
-}
-
-static unsigned int g5_cpufreq_get_speed(unsigned int cpu)
-{
-	return g5_cpu_freqs[g5_pmode_cur].frequency;
-}
-
-static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
-	policy->cpuinfo.transition_latency = transition_latency;
-	policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
-	/* secondary CPUs are tied to the primary one by the
-	 * cpufreq core if in the secondary policy we tell it that
-	 * it actually must be one policy together with all others. */
-	cpumask_copy(policy->cpus, cpu_online_mask);
-	cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);
-
-	return cpufreq_frequency_table_cpuinfo(policy,
-		g5_cpu_freqs);
-}
-
-
-static struct cpufreq_driver g5_cpufreq_driver = {
-	.name		= "powermac",
-	.owner		= THIS_MODULE,
-	.flags		= CPUFREQ_CONST_LOOPS,
-	.init		= g5_cpufreq_cpu_init,
-	.verify		= g5_cpufreq_verify,
-	.target		= g5_cpufreq_target,
-	.get		= g5_cpufreq_get_speed,
-	.attr 		= g5_cpu_freqs_attr,
-};
-
-
-#ifdef CONFIG_PMAC_SMU
-
-static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
-{
-	struct device_node *cpunode;
-	unsigned int psize, ssize;
-	unsigned long max_freq;
-	char *freq_method, *volt_method;
-	const u32 *valp;
-	u32 pvr_hi;
-	int use_volts_vdnap = 0;
-	int use_volts_smu = 0;
-	int rc = -ENODEV;
-
-	/* Check supported platforms */
-	if (of_machine_is_compatible("PowerMac8,1") ||
-	    of_machine_is_compatible("PowerMac8,2") ||
-	    of_machine_is_compatible("PowerMac9,1"))
-		use_volts_smu = 1;
-	else if (of_machine_is_compatible("PowerMac11,2"))
-		use_volts_vdnap = 1;
-	else
-		return -ENODEV;
-
-	/* Get first CPU node */
-	for (cpunode = NULL;
-	     (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
-		const u32 *reg = of_get_property(cpunode, "reg", NULL);
-		if (reg == NULL || (*reg) != 0)
-			continue;
-		if (!strcmp(cpunode->type, "cpu"))
-			break;
-	}
-	if (cpunode == NULL) {
-		printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
-		return -ENODEV;
-	}
-
-	/* Check 970FX for now */
-	valp = of_get_property(cpunode, "cpu-version", NULL);
-	if (!valp) {
-		DBG("No cpu-version property !\n");
-		goto bail_noprops;
-	}
-	pvr_hi = (*valp) >> 16;
-	if (pvr_hi != 0x3c && pvr_hi != 0x44) {
-		printk(KERN_ERR "cpufreq: Unsupported CPU version\n");
-		goto bail_noprops;
-	}
-
-	/* Look for the powertune data in the device-tree */
-	g5_pmode_data = of_get_property(cpunode, "power-mode-data",&psize);
-	if (!g5_pmode_data) {
-		DBG("No power-mode-data !\n");
-		goto bail_noprops;
-	}
-	g5_pmode_max = psize / sizeof(u32) - 1;
-
-	if (use_volts_smu) {
-		const struct smu_sdbp_header *shdr;
-
-		/* Look for the FVT table */
-		shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
-		if (!shdr)
-			goto bail_noprops;
-		g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1];
-		ssize = (shdr->len * sizeof(u32)) -
-			sizeof(struct smu_sdbp_header);
-		g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt);
-		g5_fvt_cur = 0;
-
-		/* Sanity checking */
-		if (g5_fvt_count < 1 || g5_pmode_max < 1)
-			goto bail_noprops;
-
-		g5_switch_volt = g5_smu_switch_volt;
-		volt_method = "SMU";
-	} else if (use_volts_vdnap) {
-		struct device_node *root;
-
-		root = of_find_node_by_path("/");
-		if (root == NULL) {
-			printk(KERN_ERR "cpufreq: Can't find root of "
-			       "device tree\n");
-			goto bail_noprops;
-		}
-		pfunc_set_vdnap0 = pmf_find_function(root, "set-vdnap0");
-		pfunc_vdnap0_complete =
-			pmf_find_function(root, "slewing-done");
-		if (pfunc_set_vdnap0 == NULL ||
-		    pfunc_vdnap0_complete == NULL) {
-			printk(KERN_ERR "cpufreq: Can't find required "
-			       "platform function\n");
-			goto bail_noprops;
-		}
-
-		g5_switch_volt = g5_vdnap_switch_volt;
-		volt_method = "GPIO";
-	} else {
-		g5_switch_volt = g5_dummy_switch_volt;
-		volt_method = "none";
-	}
-
-	/*
-	 * From what I see, clock-frequency is always the maximal frequency.
-	 * The current driver can not slew sysclk yet, so we really only deal
-	 * with powertune steps for now. We also only implement full freq and
-	 * half freq in this version. So far, I haven't yet seen a machine
-	 * supporting anything else.
-	 */
-	valp = of_get_property(cpunode, "clock-frequency", NULL);
-	if (!valp)
-		return -ENODEV;
-	max_freq = (*valp)/1000;
-	g5_cpu_freqs[0].frequency = max_freq;
-	g5_cpu_freqs[1].frequency = max_freq/2;
-
-	/* Set callbacks */
-	transition_latency = 12000;
-	g5_switch_freq = g5_scom_switch_freq;
-	g5_query_freq = g5_scom_query_freq;
-	freq_method = "SCOM";
-
-	/* Force apply current frequency to make sure everything is in
-	 * sync (voltage is right for example). Firmware may leave us with
-	 * a strange setting ...
-	 */
-	g5_switch_volt(CPUFREQ_HIGH);
-	msleep(10);
-	g5_pmode_cur = -1;
-	g5_switch_freq(g5_query_freq());
-
-	printk(KERN_INFO "Registering G5 CPU frequency driver\n");
-	printk(KERN_INFO "Frequency method: %s, Voltage method: %s\n",
-	       freq_method, volt_method);
-	printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
-		g5_cpu_freqs[1].frequency/1000,
-		g5_cpu_freqs[0].frequency/1000,
-		g5_cpu_freqs[g5_pmode_cur].frequency/1000);
-
-	rc = cpufreq_register_driver(&g5_cpufreq_driver);
-
-	/* We keep the CPU node on hold... hopefully, Apple G5 don't have
-	 * hotplug CPU with a dynamic device-tree ...
-	 */
-	return rc;
-
- bail_noprops:
-	of_node_put(cpunode);
-
-	return rc;
-}
-
-#endif /* CONFIG_PMAC_SMU */
-
-
-static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
-{
-	struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
-	const u8 *eeprom = NULL;
-	const u32 *valp;
-	u64 max_freq, min_freq, ih, il;
-	int has_volt = 1, rc = 0;
-
-	DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and"
-	    " RackMac3,1...\n");
-
-	/* Get first CPU node */
-	for (cpunode = NULL;
-	     (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
-		if (!strcmp(cpunode->type, "cpu"))
-			break;
-	}
-	if (cpunode == NULL) {
-		printk(KERN_ERR "cpufreq: Can't find any CPU node\n");
-		return -ENODEV;
-	}
-
-	/* Lookup the cpuid eeprom node */
-        cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
-	if (cpuid != NULL)
-		eeprom = of_get_property(cpuid, "cpuid", NULL);
-	if (eeprom == NULL) {
-		printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n");
-		rc = -ENODEV;
-		goto bail;
-	}
-
-	/* Lookup the i2c hwclock */
-	for (hwclock = NULL;
-	     (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){
-		const char *loc = of_get_property(hwclock,
-				"hwctrl-location", NULL);
-		if (loc == NULL)
-			continue;
-		if (strcmp(loc, "CPU CLOCK"))
-			continue;
-		if (!of_get_property(hwclock, "platform-get-frequency", NULL))
-			continue;
-		break;
-	}
-	if (hwclock == NULL) {
-		printk(KERN_ERR "cpufreq: Can't find i2c clock chip !\n");
-		rc = -ENODEV;
-		goto bail;
-	}
-
-	DBG("cpufreq: i2c clock chip found: %s\n", hwclock->full_name);
-
-	/* Now get all the platform functions */
-	pfunc_cpu_getfreq =
-		pmf_find_function(hwclock, "get-frequency");
-	pfunc_cpu_setfreq_high =
-		pmf_find_function(hwclock, "set-frequency-high");
-	pfunc_cpu_setfreq_low =
-		pmf_find_function(hwclock, "set-frequency-low");
-	pfunc_slewing_done =
-		pmf_find_function(hwclock, "slewing-done");
-	pfunc_cpu0_volt_high =
-		pmf_find_function(hwclock, "set-voltage-high-0");
-	pfunc_cpu0_volt_low =
-		pmf_find_function(hwclock, "set-voltage-low-0");
-	pfunc_cpu1_volt_high =
-		pmf_find_function(hwclock, "set-voltage-high-1");
-	pfunc_cpu1_volt_low =
-		pmf_find_function(hwclock, "set-voltage-low-1");
-
-	/* Check we have minimum requirements */
-	if (pfunc_cpu_getfreq == NULL || pfunc_cpu_setfreq_high == NULL ||
-	    pfunc_cpu_setfreq_low == NULL || pfunc_slewing_done == NULL) {
-		printk(KERN_ERR "cpufreq: Can't find platform functions !\n");
-		rc = -ENODEV;
-		goto bail;
-	}
-
-	/* Check that we have complete sets */
-	if (pfunc_cpu0_volt_high == NULL || pfunc_cpu0_volt_low == NULL) {
-		pmf_put_function(pfunc_cpu0_volt_high);
-		pmf_put_function(pfunc_cpu0_volt_low);
-		pfunc_cpu0_volt_high = pfunc_cpu0_volt_low = NULL;
-		has_volt = 0;
-	}
-	if (!has_volt ||
-	    pfunc_cpu1_volt_high == NULL || pfunc_cpu1_volt_low == NULL) {
-		pmf_put_function(pfunc_cpu1_volt_high);
-		pmf_put_function(pfunc_cpu1_volt_low);
-		pfunc_cpu1_volt_high = pfunc_cpu1_volt_low = NULL;
-	}
-
-	/* Note: The device tree also contains a "platform-set-values"
-	 * function for which I haven't quite figured out the usage. It
-	 * might have to be called on init and/or wakeup, I'm not too sure
-	 * but things seem to work fine without it so far ...
-	 */
-
-	/* Get max frequency from device-tree */
-	valp = of_get_property(cpunode, "clock-frequency", NULL);
-	if (!valp) {
-		printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n");
-		rc = -ENODEV;
-		goto bail;
-	}
-
-	max_freq = (*valp)/1000;
-
-	/* Now calculate reduced frequency by using the cpuid input freq
-	 * ratio. This requires 64 bits math unless we are willing to lose
-	 * some precision
-	 */
-	ih = *((u32 *)(eeprom + 0x10));
-	il = *((u32 *)(eeprom + 0x20));
-
-	/* Check for machines with no useful settings */
-	if (il == ih) {
-		printk(KERN_WARNING "cpufreq: No low frequency mode available"
-		       " on this model !\n");
-		rc = -ENODEV;
-		goto bail;
-	}
-
-	min_freq = 0;
-	if (ih != 0 && il != 0)
-		min_freq = (max_freq * il) / ih;
-
-	/* Sanity check */
-	if (min_freq >= max_freq || min_freq < 1000) {
-		printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n");
-		rc = -ENXIO;
-		goto bail;
-	}
-	g5_cpu_freqs[0].frequency = max_freq;
-	g5_cpu_freqs[1].frequency = min_freq;
-
-	/* Set callbacks */
-	transition_latency = CPUFREQ_ETERNAL;
-	g5_switch_volt = g5_pfunc_switch_volt;
-	g5_switch_freq = g5_pfunc_switch_freq;
-	g5_query_freq = g5_pfunc_query_freq;
-
-	/* Force apply current frequency to make sure everything is in
-	 * sync (voltage is right for example). Firmware may leave us with
-	 * a strange setting ...
-	 */
-	g5_switch_volt(CPUFREQ_HIGH);
-	msleep(10);
-	g5_pmode_cur = -1;
-	g5_switch_freq(g5_query_freq());
-
-	printk(KERN_INFO "Registering G5 CPU frequency driver\n");
-	printk(KERN_INFO "Frequency method: i2c/pfunc, "
-	       "Voltage method: %s\n", has_volt ? "i2c/pfunc" : "none");
-	printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
-		g5_cpu_freqs[1].frequency/1000,
-		g5_cpu_freqs[0].frequency/1000,
-		g5_cpu_freqs[g5_pmode_cur].frequency/1000);
-
-	rc = cpufreq_register_driver(&g5_cpufreq_driver);
- bail:
-	if (rc != 0) {
-		pmf_put_function(pfunc_cpu_getfreq);
-		pmf_put_function(pfunc_cpu_setfreq_high);
-		pmf_put_function(pfunc_cpu_setfreq_low);
-		pmf_put_function(pfunc_slewing_done);
-		pmf_put_function(pfunc_cpu0_volt_high);
-		pmf_put_function(pfunc_cpu0_volt_low);
-		pmf_put_function(pfunc_cpu1_volt_high);
-		pmf_put_function(pfunc_cpu1_volt_low);
-	}
-	of_node_put(hwclock);
-	of_node_put(cpuid);
-	of_node_put(cpunode);
-
-	return rc;
-}
-
-static int __init g5_cpufreq_init(void)
-{
-	struct device_node *cpus;
-	int rc = 0;
-
-	cpus = of_find_node_by_path("/cpus");
-	if (cpus == NULL) {
-		DBG("No /cpus node !\n");
-		return -ENODEV;
-	}
-
-	if (of_machine_is_compatible("PowerMac7,2") ||
-	    of_machine_is_compatible("PowerMac7,3") ||
-	    of_machine_is_compatible("RackMac3,1"))
-		rc = g5_pm72_cpufreq_init(cpus);
-#ifdef CONFIG_PMAC_SMU
-	else
-		rc = g5_neo2_cpufreq_init(cpus);
-#endif /* CONFIG_PMAC_SMU */
-
-	of_node_put(cpus);
-	return rc;
-}
-
-module_init(g5_cpufreq_init);
-
-
-MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powermac/Makefile linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powermac/Makefile
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powermac/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powermac/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -9,8 +9,6 @@ obj-y				+= pic.o setup.o time.o feature
 				   sleep.o low_i2c.o cache.o pfunc_core.o \
 				   pfunc_base.o udbg_scc.o udbg_adb.o
 obj-$(CONFIG_PMAC_BACKLIGHT)	+= backlight.o
-obj-$(CONFIG_CPU_FREQ_PMAC)	+= cpufreq_32.o
-obj-$(CONFIG_CPU_FREQ_PMAC64)	+= cpufreq_64.o
 # CONFIG_NVRAM is an arch. independent tristate symbol, for pmac32 we really
 # need this to be a bool.  Cheat here and pretend CONFIG_NVRAM=m is really
 # CONFIG_NVRAM=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powermac/smp.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powermac/smp.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powermac/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powermac/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(voi
 {
 	int rc = -ENOMEM;
 
-	psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL);
+	psurge_host = irq_domain_add_nomap(NULL, ~0, &psurge_host_ops, NULL);
 
 	if (psurge_host)
 		psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
@@ -885,7 +885,7 @@ static int smp_core99_cpu_notify(struct
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata smp_core99_cpu_nb = {
+static struct notifier_block smp_core99_cpu_nb = {
 	.notifier_call	= smp_core99_cpu_notify,
 };
 #endif /* CONFIG_HOTPLUG_CPU */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/eeh-ioda.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/eeh-ioda.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/eeh-ioda.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/eeh-ioda.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,916 @@
+/*
+ * The file intends to implement the functions needed by EEH, which is
+ * built on IODA compliant chip. Actually, lots of functions related
+ * to EEH would be built based on the OPAL APIs.
+ *
+ * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2013.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/bootmem.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/msi.h>
+#include <linux/notifier.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+
+#include <asm/eeh.h>
+#include <asm/eeh_event.h>
+#include <asm/io.h>
+#include <asm/iommu.h>
+#include <asm/msi_bitmap.h>
+#include <asm/opal.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+#include <asm/tce.h>
+
+#include "powernv.h"
+#include "pci.h"
+
+/* Debugging option */
+#ifdef IODA_EEH_DBG_ON
+#define IODA_EEH_DBG(args...)	pr_info(args)
+#else
+#define IODA_EEH_DBG(args...)
+#endif
+
+static char *hub_diag = NULL;
+static int ioda_eeh_nb_init = 0;
+
+static int ioda_eeh_event(struct notifier_block *nb,
+			  unsigned long events, void *change)
+{
+	uint64_t changed_evts = (uint64_t)change;
+
+	/* We simply send special EEH event */
+	if ((changed_evts & OPAL_EVENT_PCI_ERROR) &&
+	    (events & OPAL_EVENT_PCI_ERROR))
+		eeh_send_failure_event(NULL);
+
+	return 0;
+}
+
+static struct notifier_block ioda_eeh_nb = {
+	.notifier_call	= ioda_eeh_event,
+	.next		= NULL,
+	.priority	= 0
+};
+
+#ifdef CONFIG_DEBUG_FS
+static int ioda_eeh_dbgfs_set(void *data, u64 val)
+{
+	struct pci_controller *hose = data;
+	struct pnv_phb *phb = hose->private_data;
+
+	out_be64(phb->regs + 0xD10, val);
+	return 0;
+}
+
+static int ioda_eeh_dbgfs_get(void *data, u64 *val)
+{
+	struct pci_controller *hose = data;
+	struct pnv_phb *phb = hose->private_data;
+
+	*val = in_be64(phb->regs + 0xD10);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_dbgfs_ops, ioda_eeh_dbgfs_get,
+			ioda_eeh_dbgfs_set, "0x%llx\n");
+#endif /* CONFIG_DEBUG_FS */
+
+/**
+ * ioda_eeh_post_init - Chip dependent post initialization
+ * @hose: PCI controller
+ *
+ * The function will be called after eeh PEs and devices
+ * have been built. That means the EEH is ready to supply
+ * service with I/O cache.
+ */
+static int ioda_eeh_post_init(struct pci_controller *hose)
+{
+	struct pnv_phb *phb = hose->private_data;
+	int ret;
+
+	/* Register OPAL event notifier */
+	if (!ioda_eeh_nb_init) {
+		ret = opal_notifier_register(&ioda_eeh_nb);
+		if (ret) {
+			pr_err("%s: Can't register OPAL event notifier (%d)\n",
+			       __func__, ret);
+			return ret;
+		}
+
+		ioda_eeh_nb_init = 1;
+	}
+
+	/* FIXME: Enable it for PHB3 later */
+	if (phb->type == PNV_PHB_IODA1) {
+		if (!hub_diag) {
+			hub_diag = (char *)__get_free_page(GFP_KERNEL |
+							   __GFP_ZERO);
+			if (!hub_diag) {
+				pr_err("%s: Out of memory !\n",
+				       __func__);
+				return -ENOMEM;
+			}
+		}
+
+#ifdef CONFIG_DEBUG_FS
+		if (phb->dbgfs)
+			debugfs_create_file("err_injct", 0600,
+					    phb->dbgfs, hose,
+					    &ioda_eeh_dbgfs_ops);
+#endif
+
+		phb->eeh_state |= PNV_EEH_STATE_ENABLED;
+	}
+
+	return 0;
+}
+
+/**
+ * ioda_eeh_set_option - Set EEH operation or I/O setting
+ * @pe: EEH PE
+ * @option: options
+ *
+ * Enable or disable EEH option for the indicated PE. The
+ * function also can be used to enable I/O or DMA for the
+ * PE.
+ */
+static int ioda_eeh_set_option(struct eeh_pe *pe, int option)
+{
+	s64 ret;
+	u32 pe_no;
+	struct pci_controller *hose = pe->phb;
+	struct pnv_phb *phb = hose->private_data;
+
+	/* Check on PE number */
+	if (pe->addr < 0 || pe->addr >= phb->ioda.total_pe) {
+		pr_err("%s: PE address %x out of range [0, %x] "
+		       "on PHB#%x\n",
+			__func__, pe->addr, phb->ioda.total_pe,
+			hose->global_number);
+		return -EINVAL;
+	}
+
+	pe_no = pe->addr;
+	switch (option) {
+	case EEH_OPT_DISABLE:
+		ret = -EEXIST;
+		break;
+	case EEH_OPT_ENABLE:
+		ret = 0;
+		break;
+	case EEH_OPT_THAW_MMIO:
+		ret = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
+				OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO);
+		if (ret) {
+			pr_warning("%s: Failed to enable MMIO for "
+				   "PHB#%x-PE#%x, err=%lld\n",
+				__func__, hose->global_number, pe_no, ret);
+			return -EIO;
+		}
+
+		break;
+	case EEH_OPT_THAW_DMA:
+		ret = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
+				OPAL_EEH_ACTION_CLEAR_FREEZE_DMA);
+		if (ret) {
+			pr_warning("%s: Failed to enable DMA for "
+				   "PHB#%x-PE#%x, err=%lld\n",
+				__func__, hose->global_number, pe_no, ret);
+			return -EIO;
+		}
+
+		break;
+	default:
+		pr_warning("%s: Invalid option %d\n", __func__, option);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+/**
+ * ioda_eeh_get_state - Retrieve the state of PE
+ * @pe: EEH PE
+ *
+ * The PE's state should be retrieved from the PEEV, PEST
+ * IODA tables. Since the OPAL has exported the function
+ * to do it, it'd better to use that.
+ */
+static int ioda_eeh_get_state(struct eeh_pe *pe)
+{
+	s64 ret = 0;
+	u8 fstate;
+	u16 pcierr;
+	u32 pe_no;
+	int result;
+	struct pci_controller *hose = pe->phb;
+	struct pnv_phb *phb = hose->private_data;
+
+	/*
+	 * Sanity check on PE address. The PHB PE address should
+	 * be zero.
+	 */
+	if (pe->addr < 0 || pe->addr >= phb->ioda.total_pe) {
+		pr_err("%s: PE address %x out of range [0, %x] "
+		       "on PHB#%x\n",
+		       __func__, pe->addr, phb->ioda.total_pe,
+		       hose->global_number);
+		return EEH_STATE_NOT_SUPPORT;
+	}
+
+	/* Retrieve PE status through OPAL */
+	pe_no = pe->addr;
+	ret = opal_pci_eeh_freeze_status(phb->opal_id, pe_no,
+			&fstate, &pcierr, NULL);
+	if (ret) {
+		pr_err("%s: Failed to get EEH status on "
+		       "PHB#%x-PE#%x\n, err=%lld\n",
+		       __func__, hose->global_number, pe_no, ret);
+		return EEH_STATE_NOT_SUPPORT;
+	}
+
+	/* Check PHB status */
+	if (pe->type & EEH_PE_PHB) {
+		result = 0;
+		result &= ~EEH_STATE_RESET_ACTIVE;
+
+		if (pcierr != OPAL_EEH_PHB_ERROR) {
+			result |= EEH_STATE_MMIO_ACTIVE;
+			result |= EEH_STATE_DMA_ACTIVE;
+			result |= EEH_STATE_MMIO_ENABLED;
+			result |= EEH_STATE_DMA_ENABLED;
+		}
+
+		return result;
+	}
+
+	/* Parse result out */
+	result = 0;
+	switch (fstate) {
+	case OPAL_EEH_STOPPED_NOT_FROZEN:
+		result &= ~EEH_STATE_RESET_ACTIVE;
+		result |= EEH_STATE_MMIO_ACTIVE;
+		result |= EEH_STATE_DMA_ACTIVE;
+		result |= EEH_STATE_MMIO_ENABLED;
+		result |= EEH_STATE_DMA_ENABLED;
+		break;
+	case OPAL_EEH_STOPPED_MMIO_FREEZE:
+		result &= ~EEH_STATE_RESET_ACTIVE;
+		result |= EEH_STATE_DMA_ACTIVE;
+		result |= EEH_STATE_DMA_ENABLED;
+		break;
+	case OPAL_EEH_STOPPED_DMA_FREEZE:
+		result &= ~EEH_STATE_RESET_ACTIVE;
+		result |= EEH_STATE_MMIO_ACTIVE;
+		result |= EEH_STATE_MMIO_ENABLED;
+		break;
+	case OPAL_EEH_STOPPED_MMIO_DMA_FREEZE:
+		result &= ~EEH_STATE_RESET_ACTIVE;
+		break;
+	case OPAL_EEH_STOPPED_RESET:
+		result |= EEH_STATE_RESET_ACTIVE;
+		break;
+	case OPAL_EEH_STOPPED_TEMP_UNAVAIL:
+		result |= EEH_STATE_UNAVAILABLE;
+		break;
+	case OPAL_EEH_STOPPED_PERM_UNAVAIL:
+		result |= EEH_STATE_NOT_SUPPORT;
+		break;
+	default:
+		pr_warning("%s: Unexpected EEH status 0x%x "
+			   "on PHB#%x-PE#%x\n",
+			   __func__, fstate, hose->global_number, pe_no);
+	}
+
+	return result;
+}
+
+static int ioda_eeh_pe_clear(struct eeh_pe *pe)
+{
+	struct pci_controller *hose;
+	struct pnv_phb *phb;
+	u32 pe_no;
+	u8 fstate;
+	u16 pcierr;
+	s64 ret;
+
+	pe_no = pe->addr;
+	hose = pe->phb;
+	phb = pe->phb->private_data;
+
+	/* Clear the EEH error on the PE */
+	ret = opal_pci_eeh_freeze_clear(phb->opal_id,
+			pe_no, OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
+	if (ret) {
+		pr_err("%s: Failed to clear EEH error for "
+		       "PHB#%x-PE#%x, err=%lld\n",
+		       __func__, hose->global_number, pe_no, ret);
+		return -EIO;
+	}
+
+	/*
+	 * Read the PE state back and verify that the frozen
+	 * state has been removed.
+	 */
+	ret = opal_pci_eeh_freeze_status(phb->opal_id, pe_no,
+			&fstate, &pcierr, NULL);
+	if (ret) {
+		pr_err("%s: Failed to get EEH status on "
+		       "PHB#%x-PE#%x\n, err=%lld\n",
+		       __func__, hose->global_number, pe_no, ret);
+		return -EIO;
+	}
+
+	if (fstate != OPAL_EEH_STOPPED_NOT_FROZEN) {
+		pr_err("%s: Frozen state not cleared on "
+		       "PHB#%x-PE#%x, sts=%x\n",
+		       __func__, hose->global_number, pe_no, fstate);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static s64 ioda_eeh_phb_poll(struct pnv_phb *phb)
+{
+	s64 rc = OPAL_HARDWARE;
+
+	while (1) {
+		rc = opal_pci_poll(phb->opal_id);
+		if (rc <= 0)
+			break;
+
+		msleep(rc);
+	}
+
+	return rc;
+}
+
+static int ioda_eeh_phb_reset(struct pci_controller *hose, int option)
+{
+	struct pnv_phb *phb = hose->private_data;
+	s64 rc = OPAL_HARDWARE;
+
+	pr_debug("%s: Reset PHB#%x, option=%d\n",
+		 __func__, hose->global_number, option);
+
+	/* Issue PHB complete reset request */
+	if (option == EEH_RESET_FUNDAMENTAL ||
+	    option == EEH_RESET_HOT)
+		rc = opal_pci_reset(phb->opal_id,
+				OPAL_PHB_COMPLETE,
+				OPAL_ASSERT_RESET);
+	else if (option == EEH_RESET_DEACTIVATE)
+		rc = opal_pci_reset(phb->opal_id,
+				OPAL_PHB_COMPLETE,
+				OPAL_DEASSERT_RESET);
+	if (rc < 0)
+		goto out;
+
+	/*
+	 * Poll state of the PHB until the request is done
+	 * successfully.
+	 */
+	rc = ioda_eeh_phb_poll(phb);
+out:
+	if (rc != OPAL_SUCCESS)
+		return -EIO;
+
+	return 0;
+}
+
+static int ioda_eeh_root_reset(struct pci_controller *hose, int option)
+{
+	struct pnv_phb *phb = hose->private_data;
+	s64 rc = OPAL_SUCCESS;
+
+	pr_debug("%s: Reset PHB#%x, option=%d\n",
+		 __func__, hose->global_number, option);
+
+	/*
+	 * During the reset deassert time, we needn't care
+	 * the reset scope because the firmware does nothing
+	 * for fundamental or hot reset during deassert phase.
+	 */
+	if (option == EEH_RESET_FUNDAMENTAL)
+		rc = opal_pci_reset(phb->opal_id,
+				OPAL_PCI_FUNDAMENTAL_RESET,
+				OPAL_ASSERT_RESET);
+	else if (option == EEH_RESET_HOT)
+		rc = opal_pci_reset(phb->opal_id,
+				OPAL_PCI_HOT_RESET,
+				OPAL_ASSERT_RESET);
+	else if (option == EEH_RESET_DEACTIVATE)
+		rc = opal_pci_reset(phb->opal_id,
+				OPAL_PCI_HOT_RESET,
+				OPAL_DEASSERT_RESET);
+	if (rc < 0)
+		goto out;
+
+	/* Poll state of the PHB until the request is done */
+	rc = ioda_eeh_phb_poll(phb);
+out:
+	if (rc != OPAL_SUCCESS)
+		return -EIO;
+
+	return 0;
+}
+
+static int ioda_eeh_bridge_reset(struct pci_controller *hose,
+		struct pci_dev *dev, int option)
+{
+	u16 ctrl;
+
+	pr_debug("%s: Reset device %04x:%02x:%02x.%01x with option %d\n",
+		 __func__, hose->global_number, dev->bus->number,
+		 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), option);
+
+	switch (option) {
+	case EEH_RESET_FUNDAMENTAL:
+	case EEH_RESET_HOT:
+		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl);
+		ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
+		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
+		break;
+	case EEH_RESET_DEACTIVATE:
+		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl);
+		ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
+		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ * ioda_eeh_reset - Reset the indicated PE
+ * @pe: EEH PE
+ * @option: reset option
+ *
+ * Do reset on the indicated PE. For PCI bus sensitive PE,
+ * we need to reset the parent p2p bridge. The PHB has to
+ * be reinitialized if the p2p bridge is root bridge. For
+ * PCI device sensitive PE, we will try to reset the device
+ * through FLR. For now, we don't have OPAL APIs to do HARD
+ * reset yet, so all reset would be SOFT (HOT) reset.
+ */
+static int ioda_eeh_reset(struct eeh_pe *pe, int option)
+{
+	struct pci_controller *hose = pe->phb;
+	struct eeh_dev *edev;
+	struct pci_dev *dev;
+	int ret;
+
+	/*
+	 * Anyway, we have to clear the problematic state for the
+	 * corresponding PE. However, we needn't do it if the PE
+	 * is PHB associated. That means the PHB is having fatal
+	 * errors and it needs reset. Further more, the AIB interface
+	 * isn't reliable any more.
+	 */
+	if (!(pe->type & EEH_PE_PHB) &&
+	    (option == EEH_RESET_HOT ||
+	    option == EEH_RESET_FUNDAMENTAL)) {
+		ret = ioda_eeh_pe_clear(pe);
+		if (ret)
+			return -EIO;
+	}
+
+	/*
+	 * The rules applied to reset, either fundamental or hot reset:
+	 *
+	 * We always reset the direct upstream bridge of the PE. If the
+	 * direct upstream bridge isn't root bridge, we always take hot
+	 * reset no matter what option (fundamental or hot) is. Otherwise,
+	 * we should do the reset according to the required option.
+	 */
+	if (pe->type & EEH_PE_PHB) {
+		ret = ioda_eeh_phb_reset(hose, option);
+	} else {
+		if (pe->type & EEH_PE_DEVICE) {
+			/*
+			 * If it's device PE, we didn't refer to the parent
+			 * PCI bus yet. So we have to figure it out indirectly.
+			 */
+			edev = list_first_entry(&pe->edevs,
+					struct eeh_dev, list);
+			dev = eeh_dev_to_pci_dev(edev);
+			dev = dev->bus->self;
+		} else {
+			/*
+			 * If it's bus PE, the parent PCI bus is already there
+			 * and just pick it up.
+			 */
+			dev = pe->bus->self;
+		}
+
+		/*
+		 * Do reset based on the fact that the direct upstream bridge
+		 * is root bridge (port) or not.
+		 */
+		if (dev->bus->number == 0)
+			ret = ioda_eeh_root_reset(hose, option);
+		else
+			ret = ioda_eeh_bridge_reset(hose, dev, option);
+	}
+
+	return ret;
+}
+
+/**
+ * ioda_eeh_get_log - Retrieve error log
+ * @pe: EEH PE
+ * @severity: Severity level of the log
+ * @drv_log: buffer to store the log
+ * @len: space of the log buffer
+ *
+ * The function is used to retrieve error log from P7IOC.
+ */
+static int ioda_eeh_get_log(struct eeh_pe *pe, int severity,
+			    char *drv_log, unsigned long len)
+{
+	s64 ret;
+	unsigned long flags;
+	struct pci_controller *hose = pe->phb;
+	struct pnv_phb *phb = hose->private_data;
+
+	spin_lock_irqsave(&phb->lock, flags);
+
+	ret = opal_pci_get_phb_diag_data2(phb->opal_id,
+			phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE);
+	if (ret) {
+		spin_unlock_irqrestore(&phb->lock, flags);
+		pr_warning("%s: Failed to get log for PHB#%x-PE#%x\n",
+			   __func__, hose->global_number, pe->addr);
+		return -EIO;
+	}
+
+	/*
+	 * FIXME: We probably need log the error in somewhere.
+	 * Lets make it up in future.
+	 */
+	/* pr_info("%s", phb->diag.blob); */
+
+	spin_unlock_irqrestore(&phb->lock, flags);
+
+	return 0;
+}
+
+/**
+ * ioda_eeh_configure_bridge - Configure the PCI bridges for the indicated PE
+ * @pe: EEH PE
+ *
+ * For particular PE, it might have included PCI bridges. In order
+ * to make the PE work properly, those PCI bridges should be configured
+ * correctly. However, we need do nothing on P7IOC since the reset
+ * function will do everything that should be covered by the function.
+ */
+static int ioda_eeh_configure_bridge(struct eeh_pe *pe)
+{
+	return 0;
+}
+
+static void ioda_eeh_hub_diag_common(struct OpalIoP7IOCErrorData *data)
+{
+	/* GEM */
+	pr_info("  GEM XFIR:        %016llx\n", data->gemXfir);
+	pr_info("  GEM RFIR:        %016llx\n", data->gemRfir);
+	pr_info("  GEM RIRQFIR:     %016llx\n", data->gemRirqfir);
+	pr_info("  GEM Mask:        %016llx\n", data->gemMask);
+	pr_info("  GEM RWOF:        %016llx\n", data->gemRwof);
+
+	/* LEM */
+	pr_info("  LEM FIR:         %016llx\n", data->lemFir);
+	pr_info("  LEM Error Mask:  %016llx\n", data->lemErrMask);
+	pr_info("  LEM Action 0:    %016llx\n", data->lemAction0);
+	pr_info("  LEM Action 1:    %016llx\n", data->lemAction1);
+	pr_info("  LEM WOF:         %016llx\n", data->lemWof);
+}
+
+static void ioda_eeh_hub_diag(struct pci_controller *hose)
+{
+	struct pnv_phb *phb = hose->private_data;
+	struct OpalIoP7IOCErrorData *data;
+	long rc;
+
+	data = (struct OpalIoP7IOCErrorData *)ioda_eeh_hub_diag;
+	rc = opal_pci_get_hub_diag_data(phb->hub_id, data, PAGE_SIZE);
+	if (rc != OPAL_SUCCESS) {
+		pr_warning("%s: Failed to get HUB#%llx diag-data (%ld)\n",
+			   __func__, phb->hub_id, rc);
+		return;
+	}
+
+	switch (data->type) {
+	case OPAL_P7IOC_DIAG_TYPE_RGC:
+		pr_info("P7IOC diag-data for RGC\n\n");
+		ioda_eeh_hub_diag_common(data);
+		pr_info("  RGC Status:      %016llx\n", data->rgc.rgcStatus);
+		pr_info("  RGC LDCP:        %016llx\n", data->rgc.rgcLdcp);
+		break;
+	case OPAL_P7IOC_DIAG_TYPE_BI:
+		pr_info("P7IOC diag-data for BI %s\n\n",
+			data->bi.biDownbound ? "Downbound" : "Upbound");
+		ioda_eeh_hub_diag_common(data);
+		pr_info("  BI LDCP 0:       %016llx\n", data->bi.biLdcp0);
+		pr_info("  BI LDCP 1:       %016llx\n", data->bi.biLdcp1);
+		pr_info("  BI LDCP 2:       %016llx\n", data->bi.biLdcp2);
+		pr_info("  BI Fence Status: %016llx\n", data->bi.biFenceStatus);
+		break;
+	case OPAL_P7IOC_DIAG_TYPE_CI:
+		pr_info("P7IOC diag-data for CI Port %d\\nn",
+			data->ci.ciPort);
+		ioda_eeh_hub_diag_common(data);
+		pr_info("  CI Port Status:  %016llx\n", data->ci.ciPortStatus);
+		pr_info("  CI Port LDCP:    %016llx\n", data->ci.ciPortLdcp);
+		break;
+	case OPAL_P7IOC_DIAG_TYPE_MISC:
+		pr_info("P7IOC diag-data for MISC\n\n");
+		ioda_eeh_hub_diag_common(data);
+		break;
+	case OPAL_P7IOC_DIAG_TYPE_I2C:
+		pr_info("P7IOC diag-data for I2C\n\n");
+		ioda_eeh_hub_diag_common(data);
+		break;
+	default:
+		pr_warning("%s: Invalid type of HUB#%llx diag-data (%d)\n",
+			   __func__, phb->hub_id, data->type);
+	}
+}
+
+static void ioda_eeh_p7ioc_phb_diag(struct pci_controller *hose,
+				    struct OpalIoPhbErrorCommon *common)
+{
+	struct OpalIoP7IOCPhbErrorData *data;
+	int i;
+
+	data = (struct OpalIoP7IOCPhbErrorData *)common;
+
+	pr_info("P7IOC PHB#%x Diag-data (Version: %d)\n\n",
+		hose->global_number, common->version);
+
+	pr_info("  brdgCtl:              %08x\n", data->brdgCtl);
+
+	pr_info("  portStatusReg:        %08x\n", data->portStatusReg);
+	pr_info("  rootCmplxStatus:      %08x\n", data->rootCmplxStatus);
+	pr_info("  busAgentStatus:       %08x\n", data->busAgentStatus);
+
+	pr_info("  deviceStatus:         %08x\n", data->deviceStatus);
+	pr_info("  slotStatus:           %08x\n", data->slotStatus);
+	pr_info("  linkStatus:           %08x\n", data->linkStatus);
+	pr_info("  devCmdStatus:         %08x\n", data->devCmdStatus);
+	pr_info("  devSecStatus:         %08x\n", data->devSecStatus);
+
+	pr_info("  rootErrorStatus:      %08x\n", data->rootErrorStatus);
+	pr_info("  uncorrErrorStatus:    %08x\n", data->uncorrErrorStatus);
+	pr_info("  corrErrorStatus:      %08x\n", data->corrErrorStatus);
+	pr_info("  tlpHdr1:              %08x\n", data->tlpHdr1);
+	pr_info("  tlpHdr2:              %08x\n", data->tlpHdr2);
+	pr_info("  tlpHdr3:              %08x\n", data->tlpHdr3);
+	pr_info("  tlpHdr4:              %08x\n", data->tlpHdr4);
+	pr_info("  sourceId:             %08x\n", data->sourceId);
+
+	pr_info("  errorClass:           %016llx\n", data->errorClass);
+	pr_info("  correlator:           %016llx\n", data->correlator);
+	pr_info("  p7iocPlssr:           %016llx\n", data->p7iocPlssr);
+	pr_info("  p7iocCsr:             %016llx\n", data->p7iocCsr);
+	pr_info("  lemFir:               %016llx\n", data->lemFir);
+	pr_info("  lemErrorMask:         %016llx\n", data->lemErrorMask);
+	pr_info("  lemWOF:               %016llx\n", data->lemWOF);
+	pr_info("  phbErrorStatus:       %016llx\n", data->phbErrorStatus);
+	pr_info("  phbFirstErrorStatus:  %016llx\n", data->phbFirstErrorStatus);
+	pr_info("  phbErrorLog0:         %016llx\n", data->phbErrorLog0);
+	pr_info("  phbErrorLog1:         %016llx\n", data->phbErrorLog1);
+	pr_info("  mmioErrorStatus:      %016llx\n", data->mmioErrorStatus);
+	pr_info("  mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus);
+	pr_info("  mmioErrorLog0:        %016llx\n", data->mmioErrorLog0);
+	pr_info("  mmioErrorLog1:        %016llx\n", data->mmioErrorLog1);
+	pr_info("  dma0ErrorStatus:      %016llx\n", data->dma0ErrorStatus);
+	pr_info("  dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus);
+	pr_info("  dma0ErrorLog0:        %016llx\n", data->dma0ErrorLog0);
+	pr_info("  dma0ErrorLog1:        %016llx\n", data->dma0ErrorLog1);
+	pr_info("  dma1ErrorStatus:      %016llx\n", data->dma1ErrorStatus);
+	pr_info("  dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus);
+	pr_info("  dma1ErrorLog0:        %016llx\n", data->dma1ErrorLog0);
+	pr_info("  dma1ErrorLog1:        %016llx\n", data->dma1ErrorLog1);
+
+	for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) {
+		if ((data->pestA[i] >> 63) == 0 &&
+		    (data->pestB[i] >> 63) == 0)
+			continue;
+
+		pr_info("  PE[%3d] PESTA:        %016llx\n", i, data->pestA[i]);
+		pr_info("          PESTB:        %016llx\n", data->pestB[i]);
+	}
+}
+
+static void ioda_eeh_phb_diag(struct pci_controller *hose)
+{
+	struct pnv_phb *phb = hose->private_data;
+	struct OpalIoPhbErrorCommon *common;
+	long rc;
+
+	common = (struct OpalIoPhbErrorCommon *)phb->diag.blob;
+	rc = opal_pci_get_phb_diag_data2(phb->opal_id, common, PAGE_SIZE);
+	if (rc != OPAL_SUCCESS) {
+		pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n",
+			    __func__, hose->global_number, rc);
+		return;
+	}
+
+	switch (common->ioType) {
+	case OPAL_PHB_ERROR_DATA_TYPE_P7IOC:
+		ioda_eeh_p7ioc_phb_diag(hose, common);
+		break;
+	default:
+		pr_warning("%s: Unrecognized I/O chip %d\n",
+			   __func__, common->ioType);
+	}
+}
+
+static int ioda_eeh_get_phb_pe(struct pci_controller *hose,
+			       struct eeh_pe **pe)
+{
+	struct eeh_pe *phb_pe;
+
+	phb_pe = eeh_phb_pe_get(hose);
+	if (!phb_pe) {
+		pr_warning("%s Can't find PE for PHB#%d\n",
+			   __func__, hose->global_number);
+		return -EEXIST;
+	}
+
+	*pe = phb_pe;
+	return 0;
+}
+
+static int ioda_eeh_get_pe(struct pci_controller *hose,
+			   u16 pe_no, struct eeh_pe **pe)
+{
+	struct eeh_pe *phb_pe, *dev_pe;
+	struct eeh_dev dev;
+
+	/* Find the PHB PE */
+	if (ioda_eeh_get_phb_pe(hose, &phb_pe))
+		return -EEXIST;
+
+	/* Find the PE according to PE# */
+	memset(&dev, 0, sizeof(struct eeh_dev));
+	dev.phb = hose;
+	dev.pe_config_addr = pe_no;
+	dev_pe = eeh_pe_get(&dev);
+	if (!dev_pe) {
+		pr_warning("%s: Can't find PE for PHB#%x - PE#%x\n",
+			   __func__, hose->global_number, pe_no);
+		return -EEXIST;
+	}
+
+	*pe = dev_pe;
+	return 0;
+}
+
+/**
+ * ioda_eeh_next_error - Retrieve next error for EEH core to handle
+ * @pe: The affected PE
+ *
+ * The function is expected to be called by EEH core while it gets
+ * special EEH event (without binding PE). The function calls to
+ * OPAL APIs for next error to handle. The informational error is
+ * handled internally by platform. However, the dead IOC, dead PHB,
+ * fenced PHB and frozen PE should be handled by EEH core eventually.
+ */
+static int ioda_eeh_next_error(struct eeh_pe **pe)
+{
+	struct pci_controller *hose, *tmp;
+	struct pnv_phb *phb;
+	u64 frozen_pe_no;
+	u16 err_type, severity;
+	long rc;
+	int ret = 1;
+
+	/*
+	 * While running here, it's safe to purge the event queue.
+	 * And we should keep the cached OPAL notifier event sychronized
+	 * between the kernel and firmware.
+	 */
+	eeh_remove_event(NULL);
+	opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
+
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+		/*
+		 * If the subordinate PCI buses of the PHB has been
+		 * removed, we needn't take care of it any more.
+		 */
+		phb = hose->private_data;
+		if (phb->eeh_state & PNV_EEH_STATE_REMOVED)
+			continue;
+
+		rc = opal_pci_next_error(phb->opal_id,
+				&frozen_pe_no, &err_type, &severity);
+
+		/* If OPAL API returns error, we needn't proceed */
+		if (rc != OPAL_SUCCESS) {
+			IODA_EEH_DBG("%s: Invalid return value on "
+				     "PHB#%x (0x%lx) from opal_pci_next_error",
+				     __func__, hose->global_number, rc);
+			continue;
+		}
+
+		/* If the PHB doesn't have error, stop processing */
+		if (err_type == OPAL_EEH_NO_ERROR ||
+		    severity == OPAL_EEH_SEV_NO_ERROR) {
+			IODA_EEH_DBG("%s: No error found on PHB#%x\n",
+				     __func__, hose->global_number);
+			continue;
+		}
+
+		/*
+		 * Processing the error. We're expecting the error with
+		 * highest priority reported upon multiple errors on the
+		 * specific PHB.
+		 */
+		IODA_EEH_DBG("%s: Error (%d, %d, %d) on PHB#%x\n",
+			err_type, severity, pe_no, hose->global_number);
+		switch (err_type) {
+		case OPAL_EEH_IOC_ERROR:
+			if (severity == OPAL_EEH_SEV_IOC_DEAD) {
+				list_for_each_entry_safe(hose, tmp,
+						&hose_list, list_node) {
+					phb = hose->private_data;
+					phb->eeh_state |= PNV_EEH_STATE_REMOVED;
+				}
+
+				pr_err("EEH: dead IOC detected\n");
+				ret = 4;
+				goto out;
+			} else if (severity == OPAL_EEH_SEV_INF) {
+				pr_info("EEH: IOC informative error "
+					"detected\n");
+				ioda_eeh_hub_diag(hose);
+			}
+
+			break;
+		case OPAL_EEH_PHB_ERROR:
+			if (severity == OPAL_EEH_SEV_PHB_DEAD) {
+				if (ioda_eeh_get_phb_pe(hose, pe))
+					break;
+
+				pr_err("EEH: dead PHB#%x detected\n",
+					hose->global_number);
+				phb->eeh_state |= PNV_EEH_STATE_REMOVED;
+				ret = 3;
+				goto out;
+			} else if (severity == OPAL_EEH_SEV_PHB_FENCED) {
+				if (ioda_eeh_get_phb_pe(hose, pe))
+					break;
+
+				pr_err("EEH: fenced PHB#%x detected\n",
+					hose->global_number);
+				ret = 2;
+				goto out;
+			} else if (severity == OPAL_EEH_SEV_INF) {
+				pr_info("EEH: PHB#%x informative error "
+					"detected\n",
+					hose->global_number);
+				ioda_eeh_phb_diag(hose);
+			}
+
+			break;
+		case OPAL_EEH_PE_ERROR:
+			if (ioda_eeh_get_pe(hose, frozen_pe_no, pe))
+				break;
+
+			pr_err("EEH: Frozen PE#%x on PHB#%x detected\n",
+				(*pe)->addr, (*pe)->phb->global_number);
+			ret = 1;
+			goto out;
+		}
+	}
+
+	ret = 0;
+out:
+	return ret;
+}
+
+struct pnv_eeh_ops ioda_eeh_ops = {
+	.post_init		= ioda_eeh_post_init,
+	.set_option		= ioda_eeh_set_option,
+	.get_state		= ioda_eeh_get_state,
+	.reset			= ioda_eeh_reset,
+	.get_log		= ioda_eeh_get_log,
+	.configure_bridge	= ioda_eeh_configure_bridge,
+	.next_error		= ioda_eeh_next_error
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/eeh-powernv.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/eeh-powernv.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/eeh-powernv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/eeh-powernv.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,390 @@
+/*
+ * The file intends to implement the platform dependent EEH operations on
+ * powernv platform. Actually, the powernv was created in order to fully
+ * hypervisor support.
+ *
+ * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2013.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/atomic.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/msi.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/rbtree.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+
+#include <asm/eeh.h>
+#include <asm/eeh_event.h>
+#include <asm/firmware.h>
+#include <asm/io.h>
+#include <asm/iommu.h>
+#include <asm/machdep.h>
+#include <asm/msi_bitmap.h>
+#include <asm/opal.h>
+#include <asm/ppc-pci.h>
+
+#include "powernv.h"
+#include "pci.h"
+
+/**
+ * powernv_eeh_init - EEH platform dependent initialization
+ *
+ * EEH platform dependent initialization on powernv
+ */
+static int powernv_eeh_init(void)
+{
+	/* We require OPALv3 */
+	if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
+		pr_warning("%s: OPALv3 is required !\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Set EEH probe mode */
+	eeh_probe_mode_set(EEH_PROBE_MODE_DEV);
+
+	return 0;
+}
+
+/**
+ * powernv_eeh_post_init - EEH platform dependent post initialization
+ *
+ * EEH platform dependent post initialization on powernv. When
+ * the function is called, the EEH PEs and devices should have
+ * been built. If the I/O cache staff has been built, EEH is
+ * ready to supply service.
+ */
+static int powernv_eeh_post_init(void)
+{
+	struct pci_controller *hose;
+	struct pnv_phb *phb;
+	int ret = 0;
+
+	list_for_each_entry(hose, &hose_list, list_node) {
+		phb = hose->private_data;
+
+		if (phb->eeh_ops && phb->eeh_ops->post_init) {
+			ret = phb->eeh_ops->post_init(hose);
+			if (ret)
+				break;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * powernv_eeh_dev_probe - Do probe on PCI device
+ * @dev: PCI device
+ * @flag: unused
+ *
+ * When EEH module is installed during system boot, all PCI devices
+ * are checked one by one to see if it supports EEH. The function
+ * is introduced for the purpose. By default, EEH has been enabled
+ * on all PCI devices. That's to say, we only need do necessary
+ * initialization on the corresponding eeh device and create PE
+ * accordingly.
+ *
+ * It's notable that's unsafe to retrieve the EEH device through
+ * the corresponding PCI device. During the PCI device hotplug, which
+ * was possiblly triggered by EEH core, the binding between EEH device
+ * and the PCI device isn't built yet.
+ */
+static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	struct pnv_phb *phb = hose->private_data;
+	struct device_node *dn = pci_device_to_OF_node(dev);
+	struct eeh_dev *edev = of_node_to_eeh_dev(dn);
+
+	/*
+	 * When probing the root bridge, which doesn't have any
+	 * subordinate PCI devices. We don't have OF node for
+	 * the root bridge. So it's not reasonable to continue
+	 * the probing.
+	 */
+	if (!dn || !edev || edev->pe)
+		return 0;
+
+	/* Skip for PCI-ISA bridge */
+	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
+		return 0;
+
+	/* Initialize eeh device */
+	edev->class_code = dev->class;
+	edev->mode	&= 0xFFFFFF00;
+	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+		edev->mode |= EEH_DEV_BRIDGE;
+	if (pci_is_pcie(dev)) {
+		edev->pcie_cap = pci_pcie_cap(dev);
+
+		if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+			edev->mode |= EEH_DEV_ROOT_PORT;
+		else if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)
+			edev->mode |= EEH_DEV_DS_PORT;
+	}
+
+	edev->config_addr	= ((dev->bus->number << 8) | dev->devfn);
+	edev->pe_config_addr	= phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff);
+
+	/* Create PE */
+	eeh_add_to_parent_pe(edev);
+
+	/*
+	 * Enable EEH explicitly so that we will do EEH check
+	 * while accessing I/O stuff
+	 *
+	 * FIXME: Enable that for PHB3 later
+	 */
+	if (phb->type == PNV_PHB_IODA1)
+		eeh_subsystem_enabled = 1;
+
+	/* Save memory bars */
+	eeh_save_bars(edev);
+
+	return 0;
+}
+
+/**
+ * powernv_eeh_set_option - Initialize EEH or MMIO/DMA reenable
+ * @pe: EEH PE
+ * @option: operation to be issued
+ *
+ * The function is used to control the EEH functionality globally.
+ * Currently, following options are support according to PAPR:
+ * Enable EEH, Disable EEH, Enable MMIO and Enable DMA
+ */
+static int powernv_eeh_set_option(struct eeh_pe *pe, int option)
+{
+	struct pci_controller *hose = pe->phb;
+	struct pnv_phb *phb = hose->private_data;
+	int ret = -EEXIST;
+
+	/*
+	 * What we need do is pass it down for hardware
+	 * implementation to handle it.
+	 */
+	if (phb->eeh_ops && phb->eeh_ops->set_option)
+		ret = phb->eeh_ops->set_option(pe, option);
+
+	return ret;
+}
+
+/**
+ * powernv_eeh_get_pe_addr - Retrieve PE address
+ * @pe: EEH PE
+ *
+ * Retrieve the PE address according to the given tranditional
+ * PCI BDF (Bus/Device/Function) address.
+ */
+static int powernv_eeh_get_pe_addr(struct eeh_pe *pe)
+{
+	return pe->addr;
+}
+
+/**
+ * powernv_eeh_get_state - Retrieve PE state
+ * @pe: EEH PE
+ * @delay: delay while PE state is temporarily unavailable
+ *
+ * Retrieve the state of the specified PE. For IODA-compitable
+ * platform, it should be retrieved from IODA table. Therefore,
+ * we prefer passing down to hardware implementation to handle
+ * it.
+ */
+static int powernv_eeh_get_state(struct eeh_pe *pe, int *delay)
+{
+	struct pci_controller *hose = pe->phb;
+	struct pnv_phb *phb = hose->private_data;
+	int ret = EEH_STATE_NOT_SUPPORT;
+
+	if (phb->eeh_ops && phb->eeh_ops->get_state) {
+		ret = phb->eeh_ops->get_state(pe);
+
+		/*
+		 * If the PE state is temporarily unavailable,
+		 * to inform the EEH core delay for default
+		 * period (1 second)
+		 */
+		if (delay) {
+			*delay = 0;
+			if (ret & EEH_STATE_UNAVAILABLE)
+				*delay = 1000;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * powernv_eeh_reset - Reset the specified PE
+ * @pe: EEH PE
+ * @option: reset option
+ *
+ * Reset the specified PE
+ */
+static int powernv_eeh_reset(struct eeh_pe *pe, int option)
+{
+	struct pci_controller *hose = pe->phb;
+	struct pnv_phb *phb = hose->private_data;
+	int ret = -EEXIST;
+
+	if (phb->eeh_ops && phb->eeh_ops->reset)
+		ret = phb->eeh_ops->reset(pe, option);
+
+	return ret;
+}
+
+/**
+ * powernv_eeh_wait_state - Wait for PE state
+ * @pe: EEH PE
+ * @max_wait: maximal period in microsecond
+ *
+ * Wait for the state of associated PE. It might take some time
+ * to retrieve the PE's state.
+ */
+static int powernv_eeh_wait_state(struct eeh_pe *pe, int max_wait)
+{
+	int ret;
+	int mwait;
+
+	while (1) {
+		ret = powernv_eeh_get_state(pe, &mwait);
+
+		/*
+		 * If the PE's state is temporarily unavailable,
+		 * we have to wait for the specified time. Otherwise,
+		 * the PE's state will be returned immediately.
+		 */
+		if (ret != EEH_STATE_UNAVAILABLE)
+			return ret;
+
+		max_wait -= mwait;
+		if (max_wait <= 0) {
+			pr_warning("%s: Timeout getting PE#%x's state (%d)\n",
+				   __func__, pe->addr, max_wait);
+			return EEH_STATE_NOT_SUPPORT;
+		}
+
+		msleep(mwait);
+	}
+
+	return EEH_STATE_NOT_SUPPORT;
+}
+
+/**
+ * powernv_eeh_get_log - Retrieve error log
+ * @pe: EEH PE
+ * @severity: temporary or permanent error log
+ * @drv_log: driver log to be combined with retrieved error log
+ * @len: length of driver log
+ *
+ * Retrieve the temporary or permanent error from the PE.
+ */
+static int powernv_eeh_get_log(struct eeh_pe *pe, int severity,
+			char *drv_log, unsigned long len)
+{
+	struct pci_controller *hose = pe->phb;
+	struct pnv_phb *phb = hose->private_data;
+	int ret = -EEXIST;
+
+	if (phb->eeh_ops && phb->eeh_ops->get_log)
+		ret = phb->eeh_ops->get_log(pe, severity, drv_log, len);
+
+	return ret;
+}
+
+/**
+ * powernv_eeh_configure_bridge - Configure PCI bridges in the indicated PE
+ * @pe: EEH PE
+ *
+ * The function will be called to reconfigure the bridges included
+ * in the specified PE so that the mulfunctional PE would be recovered
+ * again.
+ */
+static int powernv_eeh_configure_bridge(struct eeh_pe *pe)
+{
+	struct pci_controller *hose = pe->phb;
+	struct pnv_phb *phb = hose->private_data;
+	int ret = 0;
+
+	if (phb->eeh_ops && phb->eeh_ops->configure_bridge)
+		ret = phb->eeh_ops->configure_bridge(pe);
+
+	return ret;
+}
+
+/**
+ * powernv_eeh_next_error - Retrieve next EEH error to handle
+ * @pe: Affected PE
+ *
+ * Using OPAL API, to retrieve next EEH error for EEH core to handle
+ */
+static int powernv_eeh_next_error(struct eeh_pe **pe)
+{
+	struct pci_controller *hose;
+	struct pnv_phb *phb = NULL;
+
+	list_for_each_entry(hose, &hose_list, list_node) {
+		phb = hose->private_data;
+		break;
+	}
+
+	if (phb && phb->eeh_ops->next_error)
+		return phb->eeh_ops->next_error(pe);
+
+	return -EEXIST;
+}
+
+static struct eeh_ops powernv_eeh_ops = {
+	.name                   = "powernv",
+	.init                   = powernv_eeh_init,
+	.post_init              = powernv_eeh_post_init,
+	.of_probe               = NULL,
+	.dev_probe              = powernv_eeh_dev_probe,
+	.set_option             = powernv_eeh_set_option,
+	.get_pe_addr            = powernv_eeh_get_pe_addr,
+	.get_state              = powernv_eeh_get_state,
+	.reset                  = powernv_eeh_reset,
+	.wait_state             = powernv_eeh_wait_state,
+	.get_log                = powernv_eeh_get_log,
+	.configure_bridge       = powernv_eeh_configure_bridge,
+	.read_config            = pnv_pci_cfg_read,
+	.write_config           = pnv_pci_cfg_write,
+	.next_error		= powernv_eeh_next_error
+};
+
+/**
+ * eeh_powernv_init - Register platform dependent EEH operations
+ *
+ * EEH initialization on powernv platform. This function should be
+ * called before any EEH related functions.
+ */
+static int __init eeh_powernv_init(void)
+{
+	int ret = -EINVAL;
+
+	if (!machine_is(powernv))
+		return ret;
+
+	ret = eeh_ops_register(&powernv_eeh_ops);
+	if (!ret)
+		pr_info("EEH: PowerNV platform initialized\n");
+	else
+		pr_info("EEH: Failed to initialize PowerNV platform (%d)\n", ret);
+
+	return ret;
+}
+
+early_initcall(eeh_powernv_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/Makefile linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/Makefile
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,3 +3,4 @@ obj-y			+= opal-rtc.o opal-nvram.o
 
 obj-$(CONFIG_SMP)	+= smp.o
 obj-$(CONFIG_PCI)	+= pci.o pci-p5ioc2.o pci-ioda.o
+obj-$(CONFIG_EEH)	+= eeh-ioda.o eeh-powernv.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/opal.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/opal.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/opal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/opal.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/interrupt.h>
+#include <linux/notifier.h>
 #include <linux/slab.h>
 #include <asm/opal.h>
 #include <asm/firmware.h>
@@ -31,6 +32,10 @@ static DEFINE_SPINLOCK(opal_write_lock);
 extern u64 opal_mc_secondary_handler[];
 static unsigned int *opal_irqs;
 static unsigned int opal_irq_count;
+static ATOMIC_NOTIFIER_HEAD(opal_notifier_head);
+static DEFINE_SPINLOCK(opal_notifier_lock);
+static uint64_t last_notified_mask = 0x0ul;
+static atomic_t opal_notifier_hold = ATOMIC_INIT(0);
 
 int __init early_init_dt_scan_opal(unsigned long node,
 				   const char *uname, int depth, void *data)
@@ -95,6 +100,68 @@ static int __init opal_register_exceptio
 
 early_initcall(opal_register_exception_handlers);
 
+int opal_notifier_register(struct notifier_block *nb)
+{
+	if (!nb) {
+		pr_warning("%s: Invalid argument (%p)\n",
+			   __func__, nb);
+		return -EINVAL;
+	}
+
+	atomic_notifier_chain_register(&opal_notifier_head, nb);
+	return 0;
+}
+
+static void opal_do_notifier(uint64_t events)
+{
+	unsigned long flags;
+	uint64_t changed_mask;
+
+	if (atomic_read(&opal_notifier_hold))
+		return;
+
+	spin_lock_irqsave(&opal_notifier_lock, flags);
+	changed_mask = last_notified_mask ^ events;
+	last_notified_mask = events;
+	spin_unlock_irqrestore(&opal_notifier_lock, flags);
+
+	/*
+	 * We feed with the event bits and changed bits for
+	 * enough information to the callback.
+	 */
+	atomic_notifier_call_chain(&opal_notifier_head,
+				   events, (void *)changed_mask);
+}
+
+void opal_notifier_update_evt(uint64_t evt_mask,
+			      uint64_t evt_val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&opal_notifier_lock, flags);
+	last_notified_mask &= ~evt_mask;
+	last_notified_mask |= evt_val;
+	spin_unlock_irqrestore(&opal_notifier_lock, flags);
+}
+
+void opal_notifier_enable(void)
+{
+	int64_t rc;
+	uint64_t evt = 0;
+
+	atomic_set(&opal_notifier_hold, 0);
+
+	/* Process pending events */
+	rc = opal_poll_events(&evt);
+	if (rc == OPAL_SUCCESS && evt)
+		opal_do_notifier(evt);
+}
+
+void opal_notifier_disable(void)
+{
+	atomic_set(&opal_notifier_hold, 1);
+}
+
 int opal_get_chars(uint32_t vtermno, char *buf, int count)
 {
 	s64 len, rc;
@@ -297,7 +364,7 @@ static irqreturn_t opal_interrupt(int ir
 
 	opal_handle_interrupt(virq_to_hw(irq), &events);
 
-	/* XXX TODO: Do something with the events */
+	opal_do_notifier(events);
 
 	return IRQ_HANDLED;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/opal-wrappers.S linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/opal-wrappers.S
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/opal-wrappers.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/opal-wrappers.S	2013-08-25 20:43:22.000000000 -0400
@@ -107,4 +107,7 @@ OPAL_CALL(opal_pci_mask_pe_error,		OPAL_
 OPAL_CALL(opal_set_slot_led_status,		OPAL_SET_SLOT_LED_STATUS);
 OPAL_CALL(opal_get_epow_status,			OPAL_GET_EPOW_STATUS);
 OPAL_CALL(opal_set_system_attention_led,	OPAL_SET_SYSTEM_ATTENTION_LED);
+OPAL_CALL(opal_pci_next_error,			OPAL_PCI_NEXT_ERROR);
+OPAL_CALL(opal_pci_poll,			OPAL_PCI_POLL);
 OPAL_CALL(opal_pci_msi_eoi,			OPAL_PCI_MSI_EOI);
+OPAL_CALL(opal_pci_get_phb_diag_data2,		OPAL_PCI_GET_PHB_DIAG_DATA2);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/pci.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/pci.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/msi.h>
+#include <linux/iommu.h>
 
 #include <asm/sections.h>
 #include <asm/io.h>
@@ -32,6 +33,8 @@
 #include <asm/iommu.h>
 #include <asm/tce.h>
 #include <asm/firmware.h>
+#include <asm/eeh_event.h>
+#include <asm/eeh.h>
 
 #include "powernv.h"
 #include "pci.h"
@@ -202,7 +205,8 @@ static void pnv_pci_handle_eeh_config(st
 
 	spin_lock_irqsave(&phb->lock, flags);
 
-	rc = opal_pci_get_phb_diag_data(phb->opal_id, phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE);
+	rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob,
+					 PNV_PCI_DIAG_BUF_SIZE);
 	has_diag = (rc == OPAL_SUCCESS);
 
 	rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no,
@@ -227,43 +231,50 @@ static void pnv_pci_handle_eeh_config(st
 	spin_unlock_irqrestore(&phb->lock, flags);
 }
 
-static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus,
-				     u32 bdfn)
+static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
+				     struct device_node *dn)
 {
 	s64	rc;
 	u8	fstate;
 	u16	pcierr;
 	u32	pe_no;
 
-	/* Get PE# if we support IODA */
-	pe_no = phb->bdfn_to_pe ? phb->bdfn_to_pe(phb, bus, bdfn & 0xff) : 0;
+	/*
+	 * Get the PE#. During the PCI probe stage, we might not
+	 * setup that yet. So all ER errors should be mapped to
+	 * PE#0
+	 */
+	pe_no = PCI_DN(dn)->pe_number;
+	if (pe_no == IODA_INVALID_PE)
+		pe_no = 0;
 
 	/* Read freeze status */
 	rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr,
 					NULL);
 	if (rc) {
-		pr_warning("PCI %d: Failed to read EEH status for PE#%d,"
-			   " err %lld\n", phb->hose->global_number, pe_no, rc);
+		pr_warning("%s: Can't read EEH status (PE#%d) for "
+			   "%s, err %lld\n",
+			   __func__, pe_no, dn->full_name, rc);
 		return;
 	}
-	cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n",
-		bdfn, pe_no, fstate);
+	cfg_dbg(" -> EEH check, bdfn=%04x PE#%d fstate=%x\n",
+		(PCI_DN(dn)->busno << 8) | (PCI_DN(dn)->devfn),
+		pe_no, fstate);
 	if (fstate != 0)
 		pnv_pci_handle_eeh_config(phb, pe_no);
 }
 
-static int pnv_pci_read_config(struct pci_bus *bus,
-			       unsigned int devfn,
-			       int where, int size, u32 *val)
+int pnv_pci_cfg_read(struct device_node *dn,
+		     int where, int size, u32 *val)
 {
-	struct pci_controller *hose = pci_bus_to_host(bus);
-	struct pnv_phb *phb = hose->private_data;
-	u32 bdfn = (((uint64_t)bus->number) << 8) | devfn;
+	struct pci_dn *pdn = PCI_DN(dn);
+	struct pnv_phb *phb = pdn->phb->private_data;
+	u32 bdfn = (pdn->busno << 8) | pdn->devfn;
+#ifdef CONFIG_EEH
+	struct eeh_pe *phb_pe = NULL;
+#endif
 	s64 rc;
 
-	if (hose == NULL)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
 	switch (size) {
 	case 1: {
 		u8 v8;
@@ -287,28 +298,43 @@ static int pnv_pci_read_config(struct pc
 	default:
 		return PCIBIOS_FUNC_NOT_SUPPORTED;
 	}
-	cfg_dbg("pnv_pci_read_config bus: %x devfn: %x +%x/%x -> %08x\n",
-		bus->number, devfn, where, size, *val);
+	cfg_dbg("%s: bus: %x devfn: %x +%x/%x -> %08x\n",
+		__func__, pdn->busno, pdn->devfn, where, size, *val);
 
-	/* Check if the PHB got frozen due to an error (no response) */
-	pnv_pci_config_check_eeh(phb, bus, bdfn);
+	/*
+	 * Check if the specified PE has been put into frozen
+	 * state. On the other hand, we needn't do that while
+	 * the PHB has been put into frozen state because of
+	 * PHB-fatal errors.
+	 */
+#ifdef CONFIG_EEH
+	phb_pe = eeh_phb_pe_get(pdn->phb);
+	if (phb_pe && (phb_pe->state & EEH_PE_ISOLATED))
+		return PCIBIOS_SUCCESSFUL;
+
+	if (phb->eeh_state & PNV_EEH_STATE_ENABLED) {
+		if (*val == EEH_IO_ERROR_VALUE(size) &&
+		    eeh_dev_check_failure(of_node_to_eeh_dev(dn)))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+	} else {
+		pnv_pci_config_check_eeh(phb, dn);
+	}
+#else
+	pnv_pci_config_check_eeh(phb, dn);
+#endif
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int pnv_pci_write_config(struct pci_bus *bus,
-				unsigned int devfn,
-				int where, int size, u32 val)
+int pnv_pci_cfg_write(struct device_node *dn,
+		      int where, int size, u32 val)
 {
-	struct pci_controller *hose = pci_bus_to_host(bus);
-	struct pnv_phb *phb = hose->private_data;
-	u32 bdfn = (((uint64_t)bus->number) << 8) | devfn;
-
-	if (hose == NULL)
-		return PCIBIOS_DEVICE_NOT_FOUND;
+	struct pci_dn *pdn = PCI_DN(dn);
+	struct pnv_phb *phb = pdn->phb->private_data;
+	u32 bdfn = (pdn->busno << 8) | pdn->devfn;
 
-	cfg_dbg("pnv_pci_write_config bus: %x devfn: %x +%x/%x -> %08x\n",
-		bus->number, devfn, where, size, val);
+	cfg_dbg("%s: bus: %x devfn: %x +%x/%x -> %08x\n",
+		pdn->busno, pdn->devfn, where, size, val);
 	switch (size) {
 	case 1:
 		opal_pci_config_write_byte(phb->opal_id, bdfn, where, val);
@@ -322,14 +348,54 @@ static int pnv_pci_write_config(struct p
 	default:
 		return PCIBIOS_FUNC_NOT_SUPPORTED;
 	}
+
 	/* Check if the PHB got frozen due to an error (no response) */
-	pnv_pci_config_check_eeh(phb, bus, bdfn);
+#ifdef CONFIG_EEH
+	if (!(phb->eeh_state & PNV_EEH_STATE_ENABLED))
+		pnv_pci_config_check_eeh(phb, dn);
+#else
+	pnv_pci_config_check_eeh(phb, dn);
+#endif
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
+static int pnv_pci_read_config(struct pci_bus *bus,
+			       unsigned int devfn,
+			       int where, int size, u32 *val)
+{
+	struct device_node *dn, *busdn = pci_bus_to_OF_node(bus);
+	struct pci_dn *pdn;
+
+	for (dn = busdn->child; dn; dn = dn->sibling) {
+		pdn = PCI_DN(dn);
+		if (pdn && pdn->devfn == devfn)
+			return pnv_pci_cfg_read(dn, where, size, val);
+	}
+
+	*val = 0xFFFFFFFF;
+	return PCIBIOS_DEVICE_NOT_FOUND;
+
+}
+
+static int pnv_pci_write_config(struct pci_bus *bus,
+				unsigned int devfn,
+				int where, int size, u32 val)
+{
+	struct device_node *dn, *busdn = pci_bus_to_OF_node(bus);
+	struct pci_dn *pdn;
+
+	for (dn = busdn->child; dn; dn = dn->sibling) {
+		pdn = PCI_DN(dn);
+		if (pdn && pdn->devfn == devfn)
+			return pnv_pci_cfg_write(dn, where, size, val);
+	}
+
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
 struct pci_ops pnv_pci_ops = {
-	.read = pnv_pci_read_config,
+	.read  = pnv_pci_read_config,
 	.write = pnv_pci_write_config,
 };
 
@@ -412,6 +478,7 @@ static struct iommu_table *pnv_pci_setup
 	pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)),
 				  be32_to_cpup(sizep), 0);
 	iommu_init_table(tbl, hose->node);
+	iommu_register_group(tbl, pci_domain_nr(hose->bus), 0);
 
 	/* Deal with SW invalidated TCEs when needed (BML way) */
 	swinvp = of_get_property(hose->dn, "linux,tce-sw-invalidate-info",
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/pci.h linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/pci.h
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/pci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/pci.h	2013-08-25 20:43:22.000000000 -0400
@@ -66,15 +66,43 @@ struct pnv_ioda_pe {
 	struct list_head	list;
 };
 
+/* IOC dependent EEH operations */
+#ifdef CONFIG_EEH
+struct pnv_eeh_ops {
+	int (*post_init)(struct pci_controller *hose);
+	int (*set_option)(struct eeh_pe *pe, int option);
+	int (*get_state)(struct eeh_pe *pe);
+	int (*reset)(struct eeh_pe *pe, int option);
+	int (*get_log)(struct eeh_pe *pe, int severity,
+		       char *drv_log, unsigned long len);
+	int (*configure_bridge)(struct eeh_pe *pe);
+	int (*next_error)(struct eeh_pe **pe);
+};
+
+#define PNV_EEH_STATE_ENABLED	(1 << 0)	/* EEH enabled	*/
+#define PNV_EEH_STATE_REMOVED	(1 << 1)	/* PHB removed	*/
+
+#endif /* CONFIG_EEH */
+
 struct pnv_phb {
 	struct pci_controller	*hose;
 	enum pnv_phb_type	type;
 	enum pnv_phb_model	model;
+	u64			hub_id;
 	u64			opal_id;
 	void __iomem		*regs;
 	int			initialized;
 	spinlock_t		lock;
 
+#ifdef CONFIG_EEH
+	struct pnv_eeh_ops	*eeh_ops;
+	int			eeh_state;
+#endif
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry		*dbgfs;
+#endif
+
 #ifdef CONFIG_PCI_MSI
 	unsigned int		msi_base;
 	unsigned int		msi32_support;
@@ -150,7 +178,14 @@ struct pnv_phb {
 };
 
 extern struct pci_ops pnv_pci_ops;
+#ifdef CONFIG_EEH
+extern struct pnv_eeh_ops ioda_eeh_ops;
+#endif
 
+int pnv_pci_cfg_read(struct device_node *dn,
+		     int where, int size, u32 *val);
+int pnv_pci_cfg_write(struct device_node *dn,
+		      int where, int size, u32 val);
 extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
 				      void *tce_mem, u64 tce_size,
 				      u64 dma_offset);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/pci-ioda.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/pci-ioda.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/pci-ioda.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/pci-ioda.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
@@ -32,6 +33,7 @@
 #include <asm/iommu.h>
 #include <asm/tce.h>
 #include <asm/xics.h>
+#include <asm/debug.h>
 
 #include "powernv.h"
 #include "pci.h"
@@ -441,6 +443,17 @@ static void pnv_pci_ioda_dma_dev_setup(s
 	set_iommu_table_base(&pdev->dev, &pe->tce32_table);
 }
 
+static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		set_iommu_table_base(&dev->dev, &pe->tce32_table);
+		if (dev->subordinate)
+			pnv_ioda_setup_bus_dma(pe, dev->subordinate);
+	}
+}
+
 static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
 					 u64 *startp, u64 *endp)
 {
@@ -595,6 +608,12 @@ static void pnv_pci_ioda_setup_dma_pe(st
 			       TCE_PCI_SWINV_PAIR;
 	}
 	iommu_init_table(tbl, phb->hose->node);
+	iommu_register_group(tbl, pci_domain_nr(pe->pbus), pe->pe_number);
+
+	if (pe->pdev)
+		set_iommu_table_base(&pe->pdev->dev, tbl);
+	else
+		pnv_ioda_setup_bus_dma(pe, pe->pbus);
 
 	return;
  fail:
@@ -667,6 +686,11 @@ static void pnv_pci_ioda2_setup_dma_pe(s
 	}
 	iommu_init_table(tbl, phb->hose->node);
 
+	if (pe->pdev)
+		set_iommu_table_base(&pe->pdev->dev, tbl);
+	else
+		pnv_ioda_setup_bus_dma(pe, pe->pbus);
+
 	return;
 fail:
 	if (pe->tce32_seg >= 0)
@@ -968,11 +992,38 @@ static void pnv_pci_ioda_setup_DMA(void)
 	}
 }
 
+static void pnv_pci_ioda_create_dbgfs(void)
+{
+#ifdef CONFIG_DEBUG_FS
+	struct pci_controller *hose, *tmp;
+	struct pnv_phb *phb;
+	char name[16];
+
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+		phb = hose->private_data;
+
+		sprintf(name, "PCI%04x", hose->global_number);
+		phb->dbgfs = debugfs_create_dir(name, powerpc_debugfs_root);
+		if (!phb->dbgfs)
+			pr_warning("%s: Error on creating debugfs on PHB#%x\n",
+				__func__, hose->global_number);
+	}
+#endif /* CONFIG_DEBUG_FS */
+}
+
 static void pnv_pci_ioda_fixup(void)
 {
 	pnv_pci_ioda_setup_PEs();
 	pnv_pci_ioda_setup_seg();
 	pnv_pci_ioda_setup_DMA();
+
+	pnv_pci_ioda_create_dbgfs();
+
+#ifdef CONFIG_EEH
+	eeh_probe_mode_set(EEH_PROBE_MODE_DEV);
+	eeh_addr_cache_build();
+	eeh_init();
+#endif
 }
 
 /*
@@ -1049,7 +1100,8 @@ static void pnv_pci_ioda_shutdown(struct
 		       OPAL_ASSERT_RESET);
 }
 
-void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type)
+void __init pnv_pci_init_ioda_phb(struct device_node *np,
+				  u64 hub_id, int ioda_type)
 {
 	struct pci_controller *hose;
 	static int primary = 1;
@@ -1087,6 +1139,7 @@ void __init pnv_pci_init_ioda_phb(struct
 	hose->first_busno = 0;
 	hose->last_busno = 0xff;
 	hose->private_data = phb;
+	phb->hub_id = hub_id;
 	phb->opal_id = phb_id;
 	phb->type = ioda_type;
 
@@ -1172,6 +1225,9 @@ void __init pnv_pci_init_ioda_phb(struct
 		phb->ioda.io_size, phb->ioda.io_segsize);
 
 	phb->hose->ops = &pnv_pci_ops;
+#ifdef CONFIG_EEH
+	phb->eeh_ops = &ioda_eeh_ops;
+#endif
 
 	/* Setup RID -> PE mapping function */
 	phb->bdfn_to_pe = pnv_ioda_bdfn_to_pe;
@@ -1210,9 +1266,9 @@ void __init pnv_pci_init_ioda_phb(struct
 		opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE);
 }
 
-void pnv_pci_init_ioda2_phb(struct device_node *np)
+void __init pnv_pci_init_ioda2_phb(struct device_node *np)
 {
-	pnv_pci_init_ioda_phb(np, PNV_PHB_IODA2);
+	pnv_pci_init_ioda_phb(np, 0, PNV_PHB_IODA2);
 }
 
 void __init pnv_pci_init_ioda_hub(struct device_node *np)
@@ -1235,6 +1291,6 @@ void __init pnv_pci_init_ioda_hub(struct
 	for_each_child_of_node(np, phbn) {
 		/* Look for IODA1 PHBs */
 		if (of_device_is_compatible(phbn, "ibm,ioda-phb"))
-			pnv_pci_init_ioda_phb(phbn, PNV_PHB_IODA1);
+			pnv_pci_init_ioda_phb(phbn, hub_id, PNV_PHB_IODA1);
 	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/pci-p5ioc2.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/pci-p5ioc2.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/pci-p5ioc2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/pci-p5ioc2.c	2013-08-25 20:43:22.000000000 -0400
@@ -86,13 +86,16 @@ static void pnv_pci_init_p5ioc2_msis(str
 static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
 					 struct pci_dev *pdev)
 {
-	if (phb->p5ioc2.iommu_table.it_map == NULL)
+	if (phb->p5ioc2.iommu_table.it_map == NULL) {
 		iommu_init_table(&phb->p5ioc2.iommu_table, phb->hose->node);
+		iommu_register_group(&phb->p5ioc2.iommu_table,
+				pci_domain_nr(phb->hose->bus), phb->opal_id);
+	}
 
 	set_iommu_table_base(&pdev->dev, &phb->p5ioc2.iommu_table);
 }
 
-static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np,
+static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
 					   void *tce_mem, u64 tce_size)
 {
 	struct pnv_phb *phb;
@@ -133,6 +136,7 @@ static void __init pnv_pci_init_p5ioc2_p
 	phb->hose->first_busno = 0;
 	phb->hose->last_busno = 0xff;
 	phb->hose->private_data = phb;
+	phb->hub_id = hub_id;
 	phb->opal_id = phb_id;
 	phb->type = PNV_PHB_P5IOC2;
 	phb->model = PNV_PHB_MODEL_P5IOC2;
@@ -226,7 +230,8 @@ void __init pnv_pci_init_p5ioc2_hub(stru
 	for_each_child_of_node(np, phbn) {
 		if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
 		    of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) {
-			pnv_pci_init_p5ioc2_phb(phbn, tce_mem, tce_per_phb);
+			pnv_pci_init_p5ioc2_phb(phbn, hub_id,
+					tce_mem, tce_per_phb);
 			tce_mem += tce_per_phb;
 		}
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/setup.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/setup.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -93,6 +93,8 @@ static void  __noreturn pnv_restart(char
 {
 	long rc = OPAL_BUSY;
 
+	opal_notifier_disable();
+
 	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
 		rc = opal_cec_reboot();
 		if (rc == OPAL_BUSY_EVENT)
@@ -108,6 +110,8 @@ static void __noreturn pnv_power_off(voi
 {
 	long rc = OPAL_BUSY;
 
+	opal_notifier_disable();
+
 	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
 		rc = opal_cec_power_down(0);
 		if (rc == OPAL_BUSY_EVENT)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/smp.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/smp.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/powernv/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/powernv/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,7 +40,7 @@
 #define DBG(fmt...)
 #endif
 
-static void __cpuinit pnv_smp_setup_cpu(int cpu)
+static void pnv_smp_setup_cpu(int cpu)
 {
 	if (cpu != boot_cpuid)
 		xics_setup_cpu();
@@ -51,7 +51,7 @@ static int pnv_smp_cpu_bootable(unsigned
 	/* Special case - we inhibit secondary thread startup
 	 * during boot if the user requests it.
 	 */
-	if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) {
+	if (system_state == SYSTEM_BOOTING && cpu_has_feature(CPU_FTR_SMT)) {
 		if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
 			return 0;
 		if (smt_enabled_at_boot
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/ps3/htab.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/ps3/htab.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/ps3/htab.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/ps3/htab.c	2013-08-25 20:43:22.000000000 -0400
@@ -109,7 +109,8 @@ static long ps3_hpte_remove(unsigned lon
 }
 
 static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
-	unsigned long vpn, int psize, int ssize, int local)
+			      unsigned long vpn, int psize, int apsize,
+			      int ssize, int local)
 {
 	int result;
 	u64 hpte_v, want_v, hpte_rs;
@@ -162,7 +163,7 @@ static void ps3_hpte_updateboltedpp(unsi
 }
 
 static void ps3_hpte_invalidate(unsigned long slot, unsigned long vpn,
-	int psize, int ssize, int local)
+				int psize, int apsize, int ssize, int local)
 {
 	unsigned long flags;
 	int result;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,942 +0,0 @@
-/*
- * Copyright IBM Corporation 2001, 2005, 2006
- * Copyright Dave Engebretsen & Todd Inglett 2001
- * Copyright Linas Vepstas 2005, 2006
- * Copyright 2001-2012 IBM Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
- */
-
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/rbtree.h>
-#include <linux/seq_file.h>
-#include <linux/spinlock.h>
-#include <linux/export.h>
-#include <linux/of.h>
-
-#include <linux/atomic.h>
-#include <asm/eeh.h>
-#include <asm/eeh_event.h>
-#include <asm/io.h>
-#include <asm/machdep.h>
-#include <asm/ppc-pci.h>
-#include <asm/rtas.h>
-
-
-/** Overview:
- *  EEH, or "Extended Error Handling" is a PCI bridge technology for
- *  dealing with PCI bus errors that can't be dealt with within the
- *  usual PCI framework, except by check-stopping the CPU.  Systems
- *  that are designed for high-availability/reliability cannot afford
- *  to crash due to a "mere" PCI error, thus the need for EEH.
- *  An EEH-capable bridge operates by converting a detected error
- *  into a "slot freeze", taking the PCI adapter off-line, making
- *  the slot behave, from the OS'es point of view, as if the slot
- *  were "empty": all reads return 0xff's and all writes are silently
- *  ignored.  EEH slot isolation events can be triggered by parity
- *  errors on the address or data busses (e.g. during posted writes),
- *  which in turn might be caused by low voltage on the bus, dust,
- *  vibration, humidity, radioactivity or plain-old failed hardware.
- *
- *  Note, however, that one of the leading causes of EEH slot
- *  freeze events are buggy device drivers, buggy device microcode,
- *  or buggy device hardware.  This is because any attempt by the
- *  device to bus-master data to a memory address that is not
- *  assigned to the device will trigger a slot freeze.   (The idea
- *  is to prevent devices-gone-wild from corrupting system memory).
- *  Buggy hardware/drivers will have a miserable time co-existing
- *  with EEH.
- *
- *  Ideally, a PCI device driver, when suspecting that an isolation
- *  event has occurred (e.g. by reading 0xff's), will then ask EEH
- *  whether this is the case, and then take appropriate steps to
- *  reset the PCI slot, the PCI device, and then resume operations.
- *  However, until that day,  the checking is done here, with the
- *  eeh_check_failure() routine embedded in the MMIO macros.  If
- *  the slot is found to be isolated, an "EEH Event" is synthesized
- *  and sent out for processing.
- */
-
-/* If a device driver keeps reading an MMIO register in an interrupt
- * handler after a slot isolation event, it might be broken.
- * This sets the threshold for how many read attempts we allow
- * before printing an error message.
- */
-#define EEH_MAX_FAILS	2100000
-
-/* Time to wait for a PCI slot to report status, in milliseconds */
-#define PCI_BUS_RESET_WAIT_MSEC (60*1000)
-
-/* Platform dependent EEH operations */
-struct eeh_ops *eeh_ops = NULL;
-
-int eeh_subsystem_enabled;
-EXPORT_SYMBOL(eeh_subsystem_enabled);
-
-/*
- * EEH probe mode support. The intention is to support multiple
- * platforms for EEH. Some platforms like pSeries do PCI emunation
- * based on device tree. However, other platforms like powernv probe
- * PCI devices from hardware. The flag is used to distinguish that.
- * In addition, struct eeh_ops::probe would be invoked for particular
- * OF node or PCI device so that the corresponding PE would be created
- * there.
- */
-int eeh_probe_mode;
-
-/* Global EEH mutex */
-DEFINE_MUTEX(eeh_mutex);
-
-/* Lock to avoid races due to multiple reports of an error */
-static DEFINE_RAW_SPINLOCK(confirm_error_lock);
-
-/* Buffer for reporting pci register dumps. Its here in BSS, and
- * not dynamically alloced, so that it ends up in RMO where RTAS
- * can access it.
- */
-#define EEH_PCI_REGS_LOG_LEN 4096
-static unsigned char pci_regs_buf[EEH_PCI_REGS_LOG_LEN];
-
-/*
- * The struct is used to maintain the EEH global statistic
- * information. Besides, the EEH global statistics will be
- * exported to user space through procfs
- */
-struct eeh_stats {
-	u64 no_device;		/* PCI device not found		*/
-	u64 no_dn;		/* OF node not found		*/
-	u64 no_cfg_addr;	/* Config address not found	*/
-	u64 ignored_check;	/* EEH check skipped		*/
-	u64 total_mmio_ffs;	/* Total EEH checks		*/
-	u64 false_positives;	/* Unnecessary EEH checks	*/
-	u64 slot_resets;	/* PE reset			*/
-};
-
-static struct eeh_stats eeh_stats;
-
-#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
-
-/**
- * eeh_gather_pci_data - Copy assorted PCI config space registers to buff
- * @edev: device to report data for
- * @buf: point to buffer in which to log
- * @len: amount of room in buffer
- *
- * This routine captures assorted PCI configuration space data,
- * and puts them into a buffer for RTAS error logging.
- */
-static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len)
-{
-	struct device_node *dn = eeh_dev_to_of_node(edev);
-	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
-	u32 cfg;
-	int cap, i;
-	int n = 0;
-
-	n += scnprintf(buf+n, len-n, "%s\n", dn->full_name);
-	printk(KERN_WARNING "EEH: of node=%s\n", dn->full_name);
-
-	eeh_ops->read_config(dn, PCI_VENDOR_ID, 4, &cfg);
-	n += scnprintf(buf+n, len-n, "dev/vend:%08x\n", cfg);
-	printk(KERN_WARNING "EEH: PCI device/vendor: %08x\n", cfg);
-
-	eeh_ops->read_config(dn, PCI_COMMAND, 4, &cfg);
-	n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
-	printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg);
-
-	if (!dev) {
-		printk(KERN_WARNING "EEH: no PCI device for this of node\n");
-		return n;
-	}
-
-	/* Gather bridge-specific registers */
-	if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
-		eeh_ops->read_config(dn, PCI_SEC_STATUS, 2, &cfg);
-		n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg);
-		printk(KERN_WARNING "EEH: Bridge secondary status: %04x\n", cfg);
-
-		eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &cfg);
-		n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg);
-		printk(KERN_WARNING "EEH: Bridge control: %04x\n", cfg);
-	}
-
-	/* Dump out the PCI-X command and status regs */
-	cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
-	if (cap) {
-		eeh_ops->read_config(dn, cap, 4, &cfg);
-		n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg);
-		printk(KERN_WARNING "EEH: PCI-X cmd: %08x\n", cfg);
-
-		eeh_ops->read_config(dn, cap+4, 4, &cfg);
-		n += scnprintf(buf+n, len-n, "pcix-stat:%x\n", cfg);
-		printk(KERN_WARNING "EEH: PCI-X status: %08x\n", cfg);
-	}
-
-	/* If PCI-E capable, dump PCI-E cap 10, and the AER */
-	cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
-	if (cap) {
-		n += scnprintf(buf+n, len-n, "pci-e cap10:\n");
-		printk(KERN_WARNING
-		       "EEH: PCI-E capabilities and status follow:\n");
-
-		for (i=0; i<=8; i++) {
-			eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
-			n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
-			printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg);
-		}
-
-		cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-		if (cap) {
-			n += scnprintf(buf+n, len-n, "pci-e AER:\n");
-			printk(KERN_WARNING
-			       "EEH: PCI-E AER capability register set follows:\n");
-
-			for (i=0; i<14; i++) {
-				eeh_ops->read_config(dn, cap+4*i, 4, &cfg);
-				n += scnprintf(buf+n, len-n, "%02x:%x\n", 4*i, cfg);
-				printk(KERN_WARNING "EEH: PCI-E AER %02x: %08x\n", i, cfg);
-			}
-		}
-	}
-
-	return n;
-}
-
-/**
- * eeh_slot_error_detail - Generate combined log including driver log and error log
- * @pe: EEH PE
- * @severity: temporary or permanent error log
- *
- * This routine should be called to generate the combined log, which
- * is comprised of driver log and error log. The driver log is figured
- * out from the config space of the corresponding PCI device, while
- * the error log is fetched through platform dependent function call.
- */
-void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
-{
-	size_t loglen = 0;
-	struct eeh_dev *edev;
-
-	eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
-	eeh_ops->configure_bridge(pe);
-	eeh_pe_restore_bars(pe);
-
-	pci_regs_buf[0] = 0;
-	eeh_pe_for_each_dev(pe, edev) {
-		loglen += eeh_gather_pci_data(edev, pci_regs_buf,
-				EEH_PCI_REGS_LOG_LEN);
-        }
-
-	eeh_ops->get_log(pe, severity, pci_regs_buf, loglen);
-}
-
-/**
- * eeh_token_to_phys - Convert EEH address token to phys address
- * @token: I/O token, should be address in the form 0xA....
- *
- * This routine should be called to convert virtual I/O address
- * to physical one.
- */
-static inline unsigned long eeh_token_to_phys(unsigned long token)
-{
-	pte_t *ptep;
-	unsigned long pa;
-
-	ptep = find_linux_pte(init_mm.pgd, token);
-	if (!ptep)
-		return token;
-	pa = pte_pfn(*ptep) << PAGE_SHIFT;
-
-	return pa | (token & (PAGE_SIZE-1));
-}
-
-/**
- * eeh_dev_check_failure - Check if all 1's data is due to EEH slot freeze
- * @edev: eeh device
- *
- * Check for an EEH failure for the given device node.  Call this
- * routine if the result of a read was all 0xff's and you want to
- * find out if this is due to an EEH slot freeze.  This routine
- * will query firmware for the EEH status.
- *
- * Returns 0 if there has not been an EEH error; otherwise returns
- * a non-zero value and queues up a slot isolation event notification.
- *
- * It is safe to call this routine in an interrupt context.
- */
-int eeh_dev_check_failure(struct eeh_dev *edev)
-{
-	int ret;
-	unsigned long flags;
-	struct device_node *dn;
-	struct pci_dev *dev;
-	struct eeh_pe *pe;
-	int rc = 0;
-	const char *location;
-
-	eeh_stats.total_mmio_ffs++;
-
-	if (!eeh_subsystem_enabled)
-		return 0;
-
-	if (!edev) {
-		eeh_stats.no_dn++;
-		return 0;
-	}
-	dn = eeh_dev_to_of_node(edev);
-	dev = eeh_dev_to_pci_dev(edev);
-	pe = edev->pe;
-
-	/* Access to IO BARs might get this far and still not want checking. */
-	if (!pe) {
-		eeh_stats.ignored_check++;
-		pr_debug("EEH: Ignored check for %s %s\n",
-			eeh_pci_name(dev), dn->full_name);
-		return 0;
-	}
-
-	if (!pe->addr && !pe->config_addr) {
-		eeh_stats.no_cfg_addr++;
-		return 0;
-	}
-
-	/* If we already have a pending isolation event for this
-	 * slot, we know it's bad already, we don't need to check.
-	 * Do this checking under a lock; as multiple PCI devices
-	 * in one slot might report errors simultaneously, and we
-	 * only want one error recovery routine running.
-	 */
-	raw_spin_lock_irqsave(&confirm_error_lock, flags);
-	rc = 1;
-	if (pe->state & EEH_PE_ISOLATED) {
-		pe->check_count++;
-		if (pe->check_count % EEH_MAX_FAILS == 0) {
-			location = of_get_property(dn, "ibm,loc-code", NULL);
-			printk(KERN_ERR "EEH: %d reads ignored for recovering device at "
-				"location=%s driver=%s pci addr=%s\n",
-				pe->check_count, location,
-				eeh_driver_name(dev), eeh_pci_name(dev));
-			printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n",
-				eeh_driver_name(dev));
-			dump_stack();
-		}
-		goto dn_unlock;
-	}
-
-	/*
-	 * Now test for an EEH failure.  This is VERY expensive.
-	 * Note that the eeh_config_addr may be a parent device
-	 * in the case of a device behind a bridge, or it may be
-	 * function zero of a multi-function device.
-	 * In any case they must share a common PHB.
-	 */
-	ret = eeh_ops->get_state(pe, NULL);
-
-	/* Note that config-io to empty slots may fail;
-	 * they are empty when they don't have children.
-	 * We will punt with the following conditions: Failure to get
-	 * PE's state, EEH not support and Permanently unavailable
-	 * state, PE is in good state.
-	 */
-	if ((ret < 0) ||
-	    (ret == EEH_STATE_NOT_SUPPORT) ||
-	    (ret & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) ==
-	    (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) {
-		eeh_stats.false_positives++;
-		pe->false_positives++;
-		rc = 0;
-		goto dn_unlock;
-	}
-
-	eeh_stats.slot_resets++;
- 
-	/* Avoid repeated reports of this failure, including problems
-	 * with other functions on this device, and functions under
-	 * bridges.
-	 */
-	eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
-	raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
-
-	eeh_send_failure_event(pe);
-
-	/* Most EEH events are due to device driver bugs.  Having
-	 * a stack trace will help the device-driver authors figure
-	 * out what happened.  So print that out.
-	 */
-	WARN(1, "EEH: failure detected\n");
-	return 1;
-
-dn_unlock:
-	raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
-	return rc;
-}
-
-EXPORT_SYMBOL_GPL(eeh_dev_check_failure);
-
-/**
- * eeh_check_failure - Check if all 1's data is due to EEH slot freeze
- * @token: I/O token, should be address in the form 0xA....
- * @val: value, should be all 1's (XXX why do we need this arg??)
- *
- * Check for an EEH failure at the given token address.  Call this
- * routine if the result of a read was all 0xff's and you want to
- * find out if this is due to an EEH slot freeze event.  This routine
- * will query firmware for the EEH status.
- *
- * Note this routine is safe to call in an interrupt context.
- */
-unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
-{
-	unsigned long addr;
-	struct eeh_dev *edev;
-
-	/* Finding the phys addr + pci device; this is pretty quick. */
-	addr = eeh_token_to_phys((unsigned long __force) token);
-	edev = eeh_addr_cache_get_dev(addr);
-	if (!edev) {
-		eeh_stats.no_device++;
-		return val;
-	}
-
-	eeh_dev_check_failure(edev);
-
-	pci_dev_put(eeh_dev_to_pci_dev(edev));
-	return val;
-}
-
-EXPORT_SYMBOL(eeh_check_failure);
-
-
-/**
- * eeh_pci_enable - Enable MMIO or DMA transfers for this slot
- * @pe: EEH PE
- *
- * This routine should be called to reenable frozen MMIO or DMA
- * so that it would work correctly again. It's useful while doing
- * recovery or log collection on the indicated device.
- */
-int eeh_pci_enable(struct eeh_pe *pe, int function)
-{
-	int rc;
-
-	rc = eeh_ops->set_option(pe, function);
-	if (rc)
-		pr_warning("%s: Unexpected state change %d on PHB#%d-PE#%x, err=%d\n",
-			__func__, function, pe->phb->global_number, pe->addr, rc);
-
-	rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
-	if (rc > 0 && (rc & EEH_STATE_MMIO_ENABLED) &&
-	   (function == EEH_OPT_THAW_MMIO))
-		return 0;
-
-	return rc;
-}
-
-/**
- * pcibios_set_pcie_slot_reset - Set PCI-E reset state
- * @dev: pci device struct
- * @state: reset state to enter
- *
- * Return value:
- * 	0 if success
- */
-int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
-{
-	struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
-	struct eeh_pe *pe = edev->pe;
-
-	if (!pe) {
-		pr_err("%s: No PE found on PCI device %s\n",
-			__func__, pci_name(dev));
-		return -EINVAL;
-	}
-
-	switch (state) {
-	case pcie_deassert_reset:
-		eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
-		break;
-	case pcie_hot_reset:
-		eeh_ops->reset(pe, EEH_RESET_HOT);
-		break;
-	case pcie_warm_reset:
-		eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
-		break;
-	default:
-		return -EINVAL;
-	};
-
-	return 0;
-}
-
-/**
- * eeh_set_pe_freset - Check the required reset for the indicated device
- * @data: EEH device
- * @flag: return value
- *
- * Each device might have its preferred reset type: fundamental or
- * hot reset. The routine is used to collected the information for
- * the indicated device and its children so that the bunch of the
- * devices could be reset properly.
- */
-static void *eeh_set_dev_freset(void *data, void *flag)
-{
-	struct pci_dev *dev;
-	unsigned int *freset = (unsigned int *)flag;
-	struct eeh_dev *edev = (struct eeh_dev *)data;
-
-	dev = eeh_dev_to_pci_dev(edev);
-	if (dev)
-		*freset |= dev->needs_freset;
-
-	return NULL;
-}
-
-/**
- * eeh_reset_pe_once - Assert the pci #RST line for 1/4 second
- * @pe: EEH PE
- *
- * Assert the PCI #RST line for 1/4 second.
- */
-static void eeh_reset_pe_once(struct eeh_pe *pe)
-{
-	unsigned int freset = 0;
-
-	/* Determine type of EEH reset required for
-	 * Partitionable Endpoint, a hot-reset (1)
-	 * or a fundamental reset (3).
-	 * A fundamental reset required by any device under
-	 * Partitionable Endpoint trumps hot-reset.
-  	 */
-	eeh_pe_dev_traverse(pe, eeh_set_dev_freset, &freset);
-
-	if (freset)
-		eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL);
-	else
-		eeh_ops->reset(pe, EEH_RESET_HOT);
-
-	/* The PCI bus requires that the reset be held high for at least
-	 * a 100 milliseconds. We wait a bit longer 'just in case'.
-	 */
-#define PCI_BUS_RST_HOLD_TIME_MSEC 250
-	msleep(PCI_BUS_RST_HOLD_TIME_MSEC);
-	
-	/* We might get hit with another EEH freeze as soon as the 
-	 * pci slot reset line is dropped. Make sure we don't miss
-	 * these, and clear the flag now.
-	 */
-	eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
-
-	eeh_ops->reset(pe, EEH_RESET_DEACTIVATE);
-
-	/* After a PCI slot has been reset, the PCI Express spec requires
-	 * a 1.5 second idle time for the bus to stabilize, before starting
-	 * up traffic.
-	 */
-#define PCI_BUS_SETTLE_TIME_MSEC 1800
-	msleep(PCI_BUS_SETTLE_TIME_MSEC);
-}
-
-/**
- * eeh_reset_pe - Reset the indicated PE
- * @pe: EEH PE
- *
- * This routine should be called to reset indicated device, including
- * PE. A PE might include multiple PCI devices and sometimes PCI bridges
- * might be involved as well.
- */
-int eeh_reset_pe(struct eeh_pe *pe)
-{
-	int i, rc;
-
-	/* Take three shots at resetting the bus */
-	for (i=0; i<3; i++) {
-		eeh_reset_pe_once(pe);
-
-		rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
-		if (rc == (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE))
-			return 0;
-
-		if (rc < 0) {
-			pr_err("%s: Unrecoverable slot failure on PHB#%d-PE#%x",
-				__func__, pe->phb->global_number, pe->addr);
-			return -1;
-		}
-		pr_err("EEH: bus reset %d failed on PHB#%d-PE#%x, rc=%d\n",
-			i+1, pe->phb->global_number, pe->addr, rc);
-	}
-
-	return -1;
-}
-
-/**
- * eeh_save_bars - Save device bars
- * @edev: PCI device associated EEH device
- *
- * Save the values of the device bars. Unlike the restore
- * routine, this routine is *not* recursive. This is because
- * PCI devices are added individually; but, for the restore,
- * an entire slot is reset at a time.
- */
-void eeh_save_bars(struct eeh_dev *edev)
-{
-	int i;
-	struct device_node *dn;
-
-	if (!edev)
-		return;
-	dn = eeh_dev_to_of_node(edev);
-	
-	for (i = 0; i < 16; i++)
-		eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]);
-}
-
-/**
- * eeh_ops_register - Register platform dependent EEH operations
- * @ops: platform dependent EEH operations
- *
- * Register the platform dependent EEH operation callback
- * functions. The platform should call this function before
- * any other EEH operations.
- */
-int __init eeh_ops_register(struct eeh_ops *ops)
-{
-	if (!ops->name) {
-		pr_warning("%s: Invalid EEH ops name for %p\n",
-			__func__, ops);
-		return -EINVAL;
-	}
-
-	if (eeh_ops && eeh_ops != ops) {
-		pr_warning("%s: EEH ops of platform %s already existing (%s)\n",
-			__func__, eeh_ops->name, ops->name);
-		return -EEXIST;
-	}
-
-	eeh_ops = ops;
-
-	return 0;
-}
-
-/**
- * eeh_ops_unregister - Unreigster platform dependent EEH operations
- * @name: name of EEH platform operations
- *
- * Unregister the platform dependent EEH operation callback
- * functions.
- */
-int __exit eeh_ops_unregister(const char *name)
-{
-	if (!name || !strlen(name)) {
-		pr_warning("%s: Invalid EEH ops name\n",
-			__func__);
-		return -EINVAL;
-	}
-
-	if (eeh_ops && !strcmp(eeh_ops->name, name)) {
-		eeh_ops = NULL;
-		return 0;
-	}
-
-	return -EEXIST;
-}
-
-/**
- * eeh_init - EEH initialization
- *
- * Initialize EEH by trying to enable it for all of the adapters in the system.
- * As a side effect we can determine here if eeh is supported at all.
- * Note that we leave EEH on so failed config cycles won't cause a machine
- * check.  If a user turns off EEH for a particular adapter they are really
- * telling Linux to ignore errors.  Some hardware (e.g. POWER5) won't
- * grant access to a slot if EEH isn't enabled, and so we always enable
- * EEH for all slots/all devices.
- *
- * The eeh-force-off option disables EEH checking globally, for all slots.
- * Even if force-off is set, the EEH hardware is still enabled, so that
- * newer systems can boot.
- */
-static int __init eeh_init(void)
-{
-	struct pci_controller *hose, *tmp;
-	struct device_node *phb;
-	int ret;
-
-	/* call platform initialization function */
-	if (!eeh_ops) {
-		pr_warning("%s: Platform EEH operation not found\n",
-			__func__);
-		return -EEXIST;
-	} else if ((ret = eeh_ops->init())) {
-		pr_warning("%s: Failed to call platform init function (%d)\n",
-			__func__, ret);
-		return ret;
-	}
-
-	raw_spin_lock_init(&confirm_error_lock);
-
-	/* Enable EEH for all adapters */
-	if (eeh_probe_mode_devtree()) {
-		list_for_each_entry_safe(hose, tmp,
-			&hose_list, list_node) {
-			phb = hose->dn;
-			traverse_pci_devices(phb, eeh_ops->of_probe, NULL);
-		}
-	}
-
-	if (eeh_subsystem_enabled)
-		pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n");
-	else
-		pr_warning("EEH: No capable adapters found\n");
-
-	return ret;
-}
-
-core_initcall_sync(eeh_init);
-
-/**
- * eeh_add_device_early - Enable EEH for the indicated device_node
- * @dn: device node for which to set up EEH
- *
- * This routine must be used to perform EEH initialization for PCI
- * devices that were added after system boot (e.g. hotplug, dlpar).
- * This routine must be called before any i/o is performed to the
- * adapter (inluding any config-space i/o).
- * Whether this actually enables EEH or not for this device depends
- * on the CEC architecture, type of the device, on earlier boot
- * command-line arguments & etc.
- */
-static void eeh_add_device_early(struct device_node *dn)
-{
-	struct pci_controller *phb;
-
-	if (!of_node_to_eeh_dev(dn))
-		return;
-	phb = of_node_to_eeh_dev(dn)->phb;
-
-	/* USB Bus children of PCI devices will not have BUID's */
-	if (NULL == phb || 0 == phb->buid)
-		return;
-
-	/* FIXME: hotplug support on POWERNV */
-	eeh_ops->of_probe(dn, NULL);
-}
-
-/**
- * eeh_add_device_tree_early - Enable EEH for the indicated device
- * @dn: device node
- *
- * This routine must be used to perform EEH initialization for the
- * indicated PCI device that was added after system boot (e.g.
- * hotplug, dlpar).
- */
-void eeh_add_device_tree_early(struct device_node *dn)
-{
-	struct device_node *sib;
-
-	for_each_child_of_node(dn, sib)
-		eeh_add_device_tree_early(sib);
-	eeh_add_device_early(dn);
-}
-EXPORT_SYMBOL_GPL(eeh_add_device_tree_early);
-
-/**
- * eeh_add_device_late - Perform EEH initialization for the indicated pci device
- * @dev: pci device for which to set up EEH
- *
- * This routine must be used to complete EEH initialization for PCI
- * devices that were added after system boot (e.g. hotplug, dlpar).
- */
-static void eeh_add_device_late(struct pci_dev *dev)
-{
-	struct device_node *dn;
-	struct eeh_dev *edev;
-
-	if (!dev || !eeh_subsystem_enabled)
-		return;
-
-	pr_debug("EEH: Adding device %s\n", pci_name(dev));
-
-	dn = pci_device_to_OF_node(dev);
-	edev = of_node_to_eeh_dev(dn);
-	if (edev->pdev == dev) {
-		pr_debug("EEH: Already referenced !\n");
-		return;
-	}
-	WARN_ON(edev->pdev);
-
-	pci_dev_get(dev);
-	edev->pdev = dev;
-	dev->dev.archdata.edev = edev;
-
-	eeh_addr_cache_insert_dev(dev);
-}
-
-/**
- * eeh_add_device_tree_late - Perform EEH initialization for the indicated PCI bus
- * @bus: PCI bus
- *
- * This routine must be used to perform EEH initialization for PCI
- * devices which are attached to the indicated PCI bus. The PCI bus
- * is added after system boot through hotplug or dlpar.
- */
-void eeh_add_device_tree_late(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	list_for_each_entry(dev, &bus->devices, bus_list) {
- 		eeh_add_device_late(dev);
- 		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- 			struct pci_bus *subbus = dev->subordinate;
- 			if (subbus)
- 				eeh_add_device_tree_late(subbus);
- 		}
-	}
-}
-EXPORT_SYMBOL_GPL(eeh_add_device_tree_late);
-
-/**
- * eeh_add_sysfs_files - Add EEH sysfs files for the indicated PCI bus
- * @bus: PCI bus
- *
- * This routine must be used to add EEH sysfs files for PCI
- * devices which are attached to the indicated PCI bus. The PCI bus
- * is added after system boot through hotplug or dlpar.
- */
-void eeh_add_sysfs_files(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		eeh_sysfs_add_device(dev);
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-			struct pci_bus *subbus = dev->subordinate;
-			if (subbus)
-				eeh_add_sysfs_files(subbus);
-		}
-	}
-}
-EXPORT_SYMBOL_GPL(eeh_add_sysfs_files);
-
-/**
- * eeh_remove_device - Undo EEH setup for the indicated pci device
- * @dev: pci device to be removed
- * @purge_pe: remove the PE or not
- *
- * This routine should be called when a device is removed from
- * a running system (e.g. by hotplug or dlpar).  It unregisters
- * the PCI device from the EEH subsystem.  I/O errors affecting
- * this device will no longer be detected after this call; thus,
- * i/o errors affecting this slot may leave this device unusable.
- */
-static void eeh_remove_device(struct pci_dev *dev, int purge_pe)
-{
-	struct eeh_dev *edev;
-
-	if (!dev || !eeh_subsystem_enabled)
-		return;
-	edev = pci_dev_to_eeh_dev(dev);
-
-	/* Unregister the device with the EEH/PCI address search system */
-	pr_debug("EEH: Removing device %s\n", pci_name(dev));
-
-	if (!edev || !edev->pdev) {
-		pr_debug("EEH: Not referenced !\n");
-		return;
-	}
-	edev->pdev = NULL;
-	dev->dev.archdata.edev = NULL;
-	pci_dev_put(dev);
-
-	eeh_rmv_from_parent_pe(edev, purge_pe);
-	eeh_addr_cache_rmv_dev(dev);
-	eeh_sysfs_remove_device(dev);
-}
-
-/**
- * eeh_remove_bus_device - Undo EEH setup for the indicated PCI device
- * @dev: PCI device
- * @purge_pe: remove the corresponding PE or not
- *
- * This routine must be called when a device is removed from the
- * running system through hotplug or dlpar. The corresponding
- * PCI address cache will be removed.
- */
-void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe)
-{
-	struct pci_bus *bus = dev->subordinate;
-	struct pci_dev *child, *tmp;
-
-	eeh_remove_device(dev, purge_pe);
-
-	if (bus && dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-		list_for_each_entry_safe(child, tmp, &bus->devices, bus_list)
-			 eeh_remove_bus_device(child, purge_pe);
-	}
-}
-EXPORT_SYMBOL_GPL(eeh_remove_bus_device);
-
-static int proc_eeh_show(struct seq_file *m, void *v)
-{
-	if (0 == eeh_subsystem_enabled) {
-		seq_printf(m, "EEH Subsystem is globally disabled\n");
-		seq_printf(m, "eeh_total_mmio_ffs=%llu\n", eeh_stats.total_mmio_ffs);
-	} else {
-		seq_printf(m, "EEH Subsystem is enabled\n");
-		seq_printf(m,
-				"no device=%llu\n"
-				"no device node=%llu\n"
-				"no config address=%llu\n"
-				"check not wanted=%llu\n"
-				"eeh_total_mmio_ffs=%llu\n"
-				"eeh_false_positives=%llu\n"
-				"eeh_slot_resets=%llu\n",
-				eeh_stats.no_device,
-				eeh_stats.no_dn,
-				eeh_stats.no_cfg_addr,
-				eeh_stats.ignored_check,
-				eeh_stats.total_mmio_ffs,
-				eeh_stats.false_positives,
-				eeh_stats.slot_resets);
-	}
-
-	return 0;
-}
-
-static int proc_eeh_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, proc_eeh_show, NULL);
-}
-
-static const struct file_operations proc_eeh_operations = {
-	.open      = proc_eeh_open,
-	.read      = seq_read,
-	.llseek    = seq_lseek,
-	.release   = single_release,
-};
-
-static int __init eeh_init_proc(void)
-{
-	if (machine_is(pseries))
-		proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations);
-	return 0;
-}
-__initcall(eeh_init_proc);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_cache.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_cache.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_cache.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_cache.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,319 +0,0 @@
-/*
- * PCI address cache; allows the lookup of PCI devices based on I/O address
- *
- * Copyright IBM Corporation 2004
- * Copyright Linas Vepstas <linas@austin.ibm.com> 2004
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/list.h>
-#include <linux/pci.h>
-#include <linux/rbtree.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/atomic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc-pci.h>
-
-
-/**
- * The pci address cache subsystem.  This subsystem places
- * PCI device address resources into a red-black tree, sorted
- * according to the address range, so that given only an i/o
- * address, the corresponding PCI device can be **quickly**
- * found. It is safe to perform an address lookup in an interrupt
- * context; this ability is an important feature.
- *
- * Currently, the only customer of this code is the EEH subsystem;
- * thus, this code has been somewhat tailored to suit EEH better.
- * In particular, the cache does *not* hold the addresses of devices
- * for which EEH is not enabled.
- *
- * (Implementation Note: The RB tree seems to be better/faster
- * than any hash algo I could think of for this problem, even
- * with the penalty of slow pointer chases for d-cache misses).
- */
-struct pci_io_addr_range {
-	struct rb_node rb_node;
-	unsigned long addr_lo;
-	unsigned long addr_hi;
-	struct eeh_dev *edev;
-	struct pci_dev *pcidev;
-	unsigned int flags;
-};
-
-static struct pci_io_addr_cache {
-	struct rb_root rb_root;
-	spinlock_t piar_lock;
-} pci_io_addr_cache_root;
-
-static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr)
-{
-	struct rb_node *n = pci_io_addr_cache_root.rb_root.rb_node;
-
-	while (n) {
-		struct pci_io_addr_range *piar;
-		piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-
-		if (addr < piar->addr_lo) {
-			n = n->rb_left;
-		} else {
-			if (addr > piar->addr_hi) {
-				n = n->rb_right;
-			} else {
-				pci_dev_get(piar->pcidev);
-				return piar->edev;
-			}
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * eeh_addr_cache_get_dev - Get device, given only address
- * @addr: mmio (PIO) phys address or i/o port number
- *
- * Given an mmio phys address, or a port number, find a pci device
- * that implements this address.  Be sure to pci_dev_put the device
- * when finished.  I/O port numbers are assumed to be offset
- * from zero (that is, they do *not* have pci_io_addr added in).
- * It is safe to call this function within an interrupt.
- */
-struct eeh_dev *eeh_addr_cache_get_dev(unsigned long addr)
-{
-	struct eeh_dev *edev;
-	unsigned long flags;
-
-	spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
-	edev = __eeh_addr_cache_get_device(addr);
-	spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
-	return edev;
-}
-
-#ifdef DEBUG
-/*
- * Handy-dandy debug print routine, does nothing more
- * than print out the contents of our addr cache.
- */
-static void eeh_addr_cache_print(struct pci_io_addr_cache *cache)
-{
-	struct rb_node *n;
-	int cnt = 0;
-
-	n = rb_first(&cache->rb_root);
-	while (n) {
-		struct pci_io_addr_range *piar;
-		piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-		pr_debug("PCI: %s addr range %d [%lx-%lx]: %s\n",
-		       (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
-		       piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
-		cnt++;
-		n = rb_next(n);
-	}
-}
-#endif
-
-/* Insert address range into the rb tree. */
-static struct pci_io_addr_range *
-eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
-		      unsigned long ahi, unsigned int flags)
-{
-	struct rb_node **p = &pci_io_addr_cache_root.rb_root.rb_node;
-	struct rb_node *parent = NULL;
-	struct pci_io_addr_range *piar;
-
-	/* Walk tree, find a place to insert into tree */
-	while (*p) {
-		parent = *p;
-		piar = rb_entry(parent, struct pci_io_addr_range, rb_node);
-		if (ahi < piar->addr_lo) {
-			p = &parent->rb_left;
-		} else if (alo > piar->addr_hi) {
-			p = &parent->rb_right;
-		} else {
-			if (dev != piar->pcidev ||
-			    alo != piar->addr_lo || ahi != piar->addr_hi) {
-				pr_warning("PIAR: overlapping address range\n");
-			}
-			return piar;
-		}
-	}
-	piar = kzalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
-	if (!piar)
-		return NULL;
-
-	pci_dev_get(dev);
-	piar->addr_lo = alo;
-	piar->addr_hi = ahi;
-	piar->edev = pci_dev_to_eeh_dev(dev);
-	piar->pcidev = dev;
-	piar->flags = flags;
-
-#ifdef DEBUG
-	pr_debug("PIAR: insert range=[%lx:%lx] dev=%s\n",
-	                  alo, ahi, pci_name(dev));
-#endif
-
-	rb_link_node(&piar->rb_node, parent, p);
-	rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
-
-	return piar;
-}
-
-static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
-{
-	struct device_node *dn;
-	struct eeh_dev *edev;
-	int i;
-
-	dn = pci_device_to_OF_node(dev);
-	if (!dn) {
-		pr_warning("PCI: no pci dn found for dev=%s\n", pci_name(dev));
-		return;
-	}
-
-	edev = of_node_to_eeh_dev(dn);
-	if (!edev) {
-		pr_warning("PCI: no EEH dev found for dn=%s\n",
-			dn->full_name);
-		return;
-	}
-
-	/* Skip any devices for which EEH is not enabled. */
-	if (!edev->pe) {
-#ifdef DEBUG
-		pr_info("PCI: skip building address cache for=%s - %s\n",
-			pci_name(dev), dn->full_name);
-#endif
-		return;
-	}
-
-	/* Walk resources on this device, poke them into the tree */
-	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-		unsigned long start = pci_resource_start(dev,i);
-		unsigned long end = pci_resource_end(dev,i);
-		unsigned int flags = pci_resource_flags(dev,i);
-
-		/* We are interested only bus addresses, not dma or other stuff */
-		if (0 == (flags & (IORESOURCE_IO | IORESOURCE_MEM)))
-			continue;
-		if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
-			 continue;
-		eeh_addr_cache_insert(dev, start, end, flags);
-	}
-}
-
-/**
- * eeh_addr_cache_insert_dev - Add a device to the address cache
- * @dev: PCI device whose I/O addresses we are interested in.
- *
- * In order to support the fast lookup of devices based on addresses,
- * we maintain a cache of devices that can be quickly searched.
- * This routine adds a device to that cache.
- */
-void eeh_addr_cache_insert_dev(struct pci_dev *dev)
-{
-	unsigned long flags;
-
-	/* Ignore PCI bridges */
-	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
-		return;
-
-	spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
-	__eeh_addr_cache_insert_dev(dev);
-	spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
-}
-
-static inline void __eeh_addr_cache_rmv_dev(struct pci_dev *dev)
-{
-	struct rb_node *n;
-
-restart:
-	n = rb_first(&pci_io_addr_cache_root.rb_root);
-	while (n) {
-		struct pci_io_addr_range *piar;
-		piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-
-		if (piar->pcidev == dev) {
-			rb_erase(n, &pci_io_addr_cache_root.rb_root);
-			pci_dev_put(piar->pcidev);
-			kfree(piar);
-			goto restart;
-		}
-		n = rb_next(n);
-	}
-}
-
-/**
- * eeh_addr_cache_rmv_dev - remove pci device from addr cache
- * @dev: device to remove
- *
- * Remove a device from the addr-cache tree.
- * This is potentially expensive, since it will walk
- * the tree multiple times (once per resource).
- * But so what; device removal doesn't need to be that fast.
- */
-void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
-	__eeh_addr_cache_rmv_dev(dev);
-	spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
-}
-
-/**
- * eeh_addr_cache_build - Build a cache of I/O addresses
- *
- * Build a cache of pci i/o addresses.  This cache will be used to
- * find the pci device that corresponds to a given address.
- * This routine scans all pci busses to build the cache.
- * Must be run late in boot process, after the pci controllers
- * have been scanned for devices (after all device resources are known).
- */
-void __init eeh_addr_cache_build(void)
-{
-	struct device_node *dn;
-	struct eeh_dev *edev;
-	struct pci_dev *dev = NULL;
-
-	spin_lock_init(&pci_io_addr_cache_root.piar_lock);
-
-	for_each_pci_dev(dev) {
-		dn = pci_device_to_OF_node(dev);
-		if (!dn)
-			continue;
-
-		edev = of_node_to_eeh_dev(dn);
-		if (!edev)
-			continue;
-
-		pci_dev_get(dev);  /* matching put is in eeh_remove_device() */
-		dev->dev.archdata.edev = edev;
-		edev->pdev = dev;
-
-		eeh_addr_cache_insert_dev(dev);
-
-		eeh_sysfs_add_device(dev);
-	}
-
-#ifdef DEBUG
-	/* Verify tree built up above, echo back the list of addrs. */
-	eeh_addr_cache_print(&pci_io_addr_cache_root);
-#endif
-}
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_dev.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_dev.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_dev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_dev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,112 +0,0 @@
-/*
- * The file intends to implement dynamic creation of EEH device, which will
- * be bound with OF node and PCI device simutaneously. The EEH devices would
- * be foundamental information for EEH core components to work proerly. Besides,
- * We have to support multiple situations where dynamic creation of EEH device
- * is required:
- *
- * 1) Before PCI emunation starts, we need create EEH devices according to the
- *    PCI sensitive OF nodes.
- * 2) When PCI emunation is done, we need do the binding between PCI device and
- *    the associated EEH device.
- * 3) DR (Dynamic Reconfiguration) would create PCI sensitive OF node. EEH device
- *    will be created while PCI sensitive OF node is detected from DR.
- * 4) PCI hotplug needs redoing the binding between PCI device and EEH device. If
- *    PHB is newly inserted, we also need create EEH devices accordingly.
- *
- * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2012.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/export.h>
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-
-#include <asm/pci-bridge.h>
-#include <asm/ppc-pci.h>
-
-/**
- * eeh_dev_init - Create EEH device according to OF node
- * @dn: device node
- * @data: PHB
- *
- * It will create EEH device according to the given OF node. The function
- * might be called by PCI emunation, DR, PHB hotplug.
- */
-void *eeh_dev_init(struct device_node *dn, void *data)
-{
-	struct pci_controller *phb = data;
-	struct eeh_dev *edev;
-
-	/* Allocate EEH device */
-	edev = kzalloc(sizeof(*edev), GFP_KERNEL);
-	if (!edev) {
-		pr_warning("%s: out of memory\n", __func__);
-		return NULL;
-	}
-
-	/* Associate EEH device with OF node */
-	PCI_DN(dn)->edev = edev;
-	edev->dn  = dn;
-	edev->phb = phb;
-	INIT_LIST_HEAD(&edev->list);
-
-	return NULL;
-}
-
-/**
- * eeh_dev_phb_init_dynamic - Create EEH devices for devices included in PHB
- * @phb: PHB
- *
- * Scan the PHB OF node and its child association, then create the
- * EEH devices accordingly
- */
-void eeh_dev_phb_init_dynamic(struct pci_controller *phb)
-{
-	struct device_node *dn = phb->dn;
-
-	/* EEH PE for PHB */
-	eeh_phb_pe_create(phb);
-
-	/* EEH device for PHB */
-	eeh_dev_init(dn, phb);
-
-	/* EEH devices for children OF nodes */
-	traverse_pci_devices(dn, eeh_dev_init, phb);
-}
-
-/**
- * eeh_dev_phb_init - Create EEH devices for devices included in existing PHBs
- *
- * Scan all the existing PHBs and create EEH devices for their OF
- * nodes and their children OF nodes
- */
-static int __init eeh_dev_phb_init(void)
-{
-	struct pci_controller *phb, *tmp;
-
-	list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
-		eeh_dev_phb_init_dynamic(phb);
-
-	pr_info("EEH: devices created\n");
-
-	return 0;
-}
-
-core_initcall(eeh_dev_phb_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_driver.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_driver.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_driver.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,552 +0,0 @@
-/*
- * PCI Error Recovery Driver for RPA-compliant PPC64 platform.
- * Copyright IBM Corp. 2004 2005
- * Copyright Linas Vepstas <linas@linas.org> 2004, 2005
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
- */
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <asm/eeh.h>
-#include <asm/eeh_event.h>
-#include <asm/ppc-pci.h>
-#include <asm/pci-bridge.h>
-#include <asm/prom.h>
-#include <asm/rtas.h>
-
-/**
- * eeh_pcid_name - Retrieve name of PCI device driver
- * @pdev: PCI device
- *
- * This routine is used to retrieve the name of PCI device driver
- * if that's valid.
- */
-static inline const char *eeh_pcid_name(struct pci_dev *pdev)
-{
-	if (pdev && pdev->dev.driver)
-		return pdev->dev.driver->name;
-	return "";
-}
-
-/**
- * eeh_pcid_get - Get the PCI device driver
- * @pdev: PCI device
- *
- * The function is used to retrieve the PCI device driver for
- * the indicated PCI device. Besides, we will increase the reference
- * of the PCI device driver to prevent that being unloaded on
- * the fly. Otherwise, kernel crash would be seen.
- */
-static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev)
-{
-	if (!pdev || !pdev->driver)
-		return NULL;
-
-	if (!try_module_get(pdev->driver->driver.owner))
-		return NULL;
-
-	return pdev->driver;
-}
-
-/**
- * eeh_pcid_put - Dereference on the PCI device driver
- * @pdev: PCI device
- *
- * The function is called to do dereference on the PCI device
- * driver of the indicated PCI device.
- */
-static inline void eeh_pcid_put(struct pci_dev *pdev)
-{
-	if (!pdev || !pdev->driver)
-		return;
-
-	module_put(pdev->driver->driver.owner);
-}
-
-#if 0
-static void print_device_node_tree(struct pci_dn *pdn, int dent)
-{
-	int i;
-	struct device_node *pc;
-
-	if (!pdn)
-		return;
-	for (i = 0; i < dent; i++)
-		printk(" ");
-	printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
-		pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
-		pdn->eeh_pe_config_addr, pdn->node->full_name);
-	dent += 3;
-	pc = pdn->node->child;
-	while (pc) {
-		print_device_node_tree(PCI_DN(pc), dent);
-		pc = pc->sibling;
-	}
-}
-#endif
-
-/**
- * eeh_disable_irq - Disable interrupt for the recovering device
- * @dev: PCI device
- *
- * This routine must be called when reporting temporary or permanent
- * error to the particular PCI device to disable interrupt of that
- * device. If the device has enabled MSI or MSI-X interrupt, we needn't
- * do real work because EEH should freeze DMA transfers for those PCI
- * devices encountering EEH errors, which includes MSI or MSI-X.
- */
-static void eeh_disable_irq(struct pci_dev *dev)
-{
-	struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
-
-	/* Don't disable MSI and MSI-X interrupts. They are
-	 * effectively disabled by the DMA Stopped state
-	 * when an EEH error occurs.
-	 */
-	if (dev->msi_enabled || dev->msix_enabled)
-		return;
-
-	if (!irq_has_action(dev->irq))
-		return;
-
-	edev->mode |= EEH_DEV_IRQ_DISABLED;
-	disable_irq_nosync(dev->irq);
-}
-
-/**
- * eeh_enable_irq - Enable interrupt for the recovering device
- * @dev: PCI device
- *
- * This routine must be called to enable interrupt while failed
- * device could be resumed.
- */
-static void eeh_enable_irq(struct pci_dev *dev)
-{
-	struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
-
-	if ((edev->mode) & EEH_DEV_IRQ_DISABLED) {
-		edev->mode &= ~EEH_DEV_IRQ_DISABLED;
-		enable_irq(dev->irq);
-	}
-}
-
-/**
- * eeh_report_error - Report pci error to each device driver
- * @data: eeh device
- * @userdata: return value
- * 
- * Report an EEH error to each device driver, collect up and 
- * merge the device driver responses. Cumulative response 
- * passed back in "userdata".
- */
-static void *eeh_report_error(void *data, void *userdata)
-{
-	struct eeh_dev *edev = (struct eeh_dev *)data;
-	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
-	enum pci_ers_result rc, *res = userdata;
-	struct pci_driver *driver;
-
-	/* We might not have the associated PCI device,
-	 * then we should continue for next one.
-	 */
-	if (!dev) return NULL;
-	dev->error_state = pci_channel_io_frozen;
-
-	driver = eeh_pcid_get(dev);
-	if (!driver) return NULL;
-
-	eeh_disable_irq(dev);
-
-	if (!driver->err_handler ||
-	    !driver->err_handler->error_detected) {
-		eeh_pcid_put(dev);
-		return NULL;
-	}
-
-	rc = driver->err_handler->error_detected(dev, pci_channel_io_frozen);
-
-	/* A driver that needs a reset trumps all others */
-	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
-	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
-
-	eeh_pcid_put(dev);
-	return NULL;
-}
-
-/**
- * eeh_report_mmio_enabled - Tell drivers that MMIO has been enabled
- * @data: eeh device
- * @userdata: return value
- *
- * Tells each device driver that IO ports, MMIO and config space I/O
- * are now enabled. Collects up and merges the device driver responses.
- * Cumulative response passed back in "userdata".
- */
-static void *eeh_report_mmio_enabled(void *data, void *userdata)
-{
-	struct eeh_dev *edev = (struct eeh_dev *)data;
-	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
-	enum pci_ers_result rc, *res = userdata;
-	struct pci_driver *driver;
-
-	driver = eeh_pcid_get(dev);
-	if (!driver) return NULL;
-
-	if (!driver->err_handler ||
-	    !driver->err_handler->mmio_enabled) {
-		eeh_pcid_put(dev);
-		return NULL;
-	}
-
-	rc = driver->err_handler->mmio_enabled(dev);
-
-	/* A driver that needs a reset trumps all others */
-	if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
-	if (*res == PCI_ERS_RESULT_NONE) *res = rc;
-
-	eeh_pcid_put(dev);
-	return NULL;
-}
-
-/**
- * eeh_report_reset - Tell device that slot has been reset
- * @data: eeh device
- * @userdata: return value
- *
- * This routine must be called while EEH tries to reset particular
- * PCI device so that the associated PCI device driver could take
- * some actions, usually to save data the driver needs so that the
- * driver can work again while the device is recovered.
- */
-static void *eeh_report_reset(void *data, void *userdata)
-{
-	struct eeh_dev *edev = (struct eeh_dev *)data;
-	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
-	enum pci_ers_result rc, *res = userdata;
-	struct pci_driver *driver;
-
-	if (!dev) return NULL;
-	dev->error_state = pci_channel_io_normal;
-
-	driver = eeh_pcid_get(dev);
-	if (!driver) return NULL;
-
-	eeh_enable_irq(dev);
-
-	if (!driver->err_handler ||
-	    !driver->err_handler->slot_reset) {
-		eeh_pcid_put(dev);
-		return NULL;
-	}
-
-	rc = driver->err_handler->slot_reset(dev);
-	if ((*res == PCI_ERS_RESULT_NONE) ||
-	    (*res == PCI_ERS_RESULT_RECOVERED)) *res = rc;
-	if (*res == PCI_ERS_RESULT_DISCONNECT &&
-	     rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
-
-	eeh_pcid_put(dev);
-	return NULL;
-}
-
-/**
- * eeh_report_resume - Tell device to resume normal operations
- * @data: eeh device
- * @userdata: return value
- *
- * This routine must be called to notify the device driver that it
- * could resume so that the device driver can do some initialization
- * to make the recovered device work again.
- */
-static void *eeh_report_resume(void *data, void *userdata)
-{
-	struct eeh_dev *edev = (struct eeh_dev *)data;
-	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
-	struct pci_driver *driver;
-
-	if (!dev) return NULL;
-	dev->error_state = pci_channel_io_normal;
-
-	driver = eeh_pcid_get(dev);
-	if (!driver) return NULL;
-
-	eeh_enable_irq(dev);
-
-	if (!driver->err_handler ||
-	    !driver->err_handler->resume) {
-		eeh_pcid_put(dev);
-		return NULL;
-	}
-
-	driver->err_handler->resume(dev);
-
-	eeh_pcid_put(dev);
-	return NULL;
-}
-
-/**
- * eeh_report_failure - Tell device driver that device is dead.
- * @data: eeh device
- * @userdata: return value
- *
- * This informs the device driver that the device is permanently
- * dead, and that no further recovery attempts will be made on it.
- */
-static void *eeh_report_failure(void *data, void *userdata)
-{
-	struct eeh_dev *edev = (struct eeh_dev *)data;
-	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
-	struct pci_driver *driver;
-
-	if (!dev) return NULL;
-	dev->error_state = pci_channel_io_perm_failure;
-
-	driver = eeh_pcid_get(dev);
-	if (!driver) return NULL;
-
-	eeh_disable_irq(dev);
-
-	if (!driver->err_handler ||
-	    !driver->err_handler->error_detected) {
-		eeh_pcid_put(dev);
-		return NULL;
-	}
-
-	driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
-
-	eeh_pcid_put(dev);
-	return NULL;
-}
-
-/**
- * eeh_reset_device - Perform actual reset of a pci slot
- * @pe: EEH PE
- * @bus: PCI bus corresponding to the isolcated slot
- *
- * This routine must be called to do reset on the indicated PE.
- * During the reset, udev might be invoked because those affected
- * PCI devices will be removed and then added.
- */
-static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
-{
-	int cnt, rc;
-
-	/* pcibios will clear the counter; save the value */
-	cnt = pe->freeze_count;
-
-	/*
-	 * We don't remove the corresponding PE instances because
-	 * we need the information afterwords. The attached EEH
-	 * devices are expected to be attached soon when calling
-	 * into pcibios_add_pci_devices().
-	 */
-	if (bus)
-		__pcibios_remove_pci_devices(bus, 0);
-
-	/* Reset the pci controller. (Asserts RST#; resets config space).
-	 * Reconfigure bridges and devices. Don't try to bring the system
-	 * up if the reset failed for some reason.
-	 */
-	rc = eeh_reset_pe(pe);
-	if (rc)
-		return rc;
-
-	/* Restore PE */
-	eeh_ops->configure_bridge(pe);
-	eeh_pe_restore_bars(pe);
-
-	/* Give the system 5 seconds to finish running the user-space
-	 * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes, 
-	 * this is a hack, but if we don't do this, and try to bring 
-	 * the device up before the scripts have taken it down, 
-	 * potentially weird things happen.
-	 */
-	if (bus) {
-		ssleep(5);
-		pcibios_add_pci_devices(bus);
-	}
-	pe->freeze_count = cnt;
-
-	return 0;
-}
-
-/* The longest amount of time to wait for a pci device
- * to come back on line, in seconds.
- */
-#define MAX_WAIT_FOR_RECOVERY 150
-
-/**
- * eeh_handle_event - Reset a PCI device after hard lockup.
- * @pe: EEH PE
- *
- * While PHB detects address or data parity errors on particular PCI
- * slot, the associated PE will be frozen. Besides, DMA's occurring
- * to wild addresses (which usually happen due to bugs in device
- * drivers or in PCI adapter firmware) can cause EEH error. #SERR,
- * #PERR or other misc PCI-related errors also can trigger EEH errors.
- *
- * Recovery process consists of unplugging the device driver (which
- * generated hotplug events to userspace), then issuing a PCI #RST to
- * the device, then reconfiguring the PCI config space for all bridges
- * & devices under this slot, and then finally restarting the device
- * drivers (which cause a second set of hotplug events to go out to
- * userspace).
- */
-void eeh_handle_event(struct eeh_pe *pe)
-{
-	struct pci_bus *frozen_bus;
-	int rc = 0;
-	enum pci_ers_result result = PCI_ERS_RESULT_NONE;
-
-	frozen_bus = eeh_pe_bus_get(pe);
-	if (!frozen_bus) {
-		pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n",
-			__func__, pe->phb->global_number, pe->addr);
-		return;
-	}
-
-	pe->freeze_count++;
-	if (pe->freeze_count > EEH_MAX_ALLOWED_FREEZES)
-		goto excess_failures;
-	pr_warning("EEH: This PCI device has failed %d times in the last hour\n",
-		pe->freeze_count);
-
-	/* Walk the various device drivers attached to this slot through
-	 * a reset sequence, giving each an opportunity to do what it needs
-	 * to accomplish the reset.  Each child gets a report of the
-	 * status ... if any child can't handle the reset, then the entire
-	 * slot is dlpar removed and added.
-	 */
-	eeh_pe_dev_traverse(pe, eeh_report_error, &result);
-
-	/* Get the current PCI slot state. This can take a long time,
-	 * sometimes over 3 seconds for certain systems.
-	 */
-	rc = eeh_ops->wait_state(pe, MAX_WAIT_FOR_RECOVERY*1000);
-	if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) {
-		printk(KERN_WARNING "EEH: Permanent failure\n");
-		goto hard_fail;
-	}
-
-	/* Since rtas may enable MMIO when posting the error log,
-	 * don't post the error log until after all dev drivers
-	 * have been informed.
-	 */
-	eeh_slot_error_detail(pe, EEH_LOG_TEMP);
-
-	/* If all device drivers were EEH-unaware, then shut
-	 * down all of the device drivers, and hope they
-	 * go down willingly, without panicing the system.
-	 */
-	if (result == PCI_ERS_RESULT_NONE) {
-		rc = eeh_reset_device(pe, frozen_bus);
-		if (rc) {
-			printk(KERN_WARNING "EEH: Unable to reset, rc=%d\n", rc);
-			goto hard_fail;
-		}
-	}
-
-	/* If all devices reported they can proceed, then re-enable MMIO */
-	if (result == PCI_ERS_RESULT_CAN_RECOVER) {
-		rc = eeh_pci_enable(pe, EEH_OPT_THAW_MMIO);
-
-		if (rc < 0)
-			goto hard_fail;
-		if (rc) {
-			result = PCI_ERS_RESULT_NEED_RESET;
-		} else {
-			result = PCI_ERS_RESULT_NONE;
-			eeh_pe_dev_traverse(pe, eeh_report_mmio_enabled, &result);
-		}
-	}
-
-	/* If all devices reported they can proceed, then re-enable DMA */
-	if (result == PCI_ERS_RESULT_CAN_RECOVER) {
-		rc = eeh_pci_enable(pe, EEH_OPT_THAW_DMA);
-
-		if (rc < 0)
-			goto hard_fail;
-		if (rc)
-			result = PCI_ERS_RESULT_NEED_RESET;
-		else
-			result = PCI_ERS_RESULT_RECOVERED;
-	}
-
-	/* If any device has a hard failure, then shut off everything. */
-	if (result == PCI_ERS_RESULT_DISCONNECT) {
-		printk(KERN_WARNING "EEH: Device driver gave up\n");
-		goto hard_fail;
-	}
-
-	/* If any device called out for a reset, then reset the slot */
-	if (result == PCI_ERS_RESULT_NEED_RESET) {
-		rc = eeh_reset_device(pe, NULL);
-		if (rc) {
-			printk(KERN_WARNING "EEH: Cannot reset, rc=%d\n", rc);
-			goto hard_fail;
-		}
-		result = PCI_ERS_RESULT_NONE;
-		eeh_pe_dev_traverse(pe, eeh_report_reset, &result);
-	}
-
-	/* All devices should claim they have recovered by now. */
-	if ((result != PCI_ERS_RESULT_RECOVERED) &&
-	    (result != PCI_ERS_RESULT_NONE)) {
-		printk(KERN_WARNING "EEH: Not recovered\n");
-		goto hard_fail;
-	}
-
-	/* Tell all device drivers that they can resume operations */
-	eeh_pe_dev_traverse(pe, eeh_report_resume, NULL);
-
-	return;
-	
-excess_failures:
-	/*
-	 * About 90% of all real-life EEH failures in the field
-	 * are due to poorly seated PCI cards. Only 10% or so are
-	 * due to actual, failed cards.
-	 */
-	pr_err("EEH: PHB#%d-PE#%x has failed %d times in the\n"
-	       "last hour and has been permanently disabled.\n"
-	       "Please try reseating or replacing it.\n",
-		pe->phb->global_number, pe->addr,
-		pe->freeze_count);
-	goto perm_error;
-
-hard_fail:
-	pr_err("EEH: Unable to recover from failure from PHB#%d-PE#%x.\n"
-	       "Please try reseating or replacing it\n",
-		pe->phb->global_number, pe->addr);
-
-perm_error:
-	eeh_slot_error_detail(pe, EEH_LOG_PERM);
-
-	/* Notify all devices that they're about to go down. */
-	eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
-
-	/* Shut down the device drivers for good. */
-	if (frozen_bus)
-		pcibios_remove_pci_devices(frozen_bus);
-}
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_event.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_event.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_event.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,142 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
- */
-
-#include <linux/delay.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/kthread.h>
-#include <asm/eeh_event.h>
-#include <asm/ppc-pci.h>
-
-/** Overview:
- *  EEH error states may be detected within exception handlers;
- *  however, the recovery processing needs to occur asynchronously
- *  in a normal kernel context and not an interrupt context.
- *  This pair of routines creates an event and queues it onto a
- *  work-queue, where a worker thread can drive recovery.
- */
-
-/* EEH event workqueue setup. */
-static DEFINE_SPINLOCK(eeh_eventlist_lock);
-LIST_HEAD(eeh_eventlist);
-static void eeh_thread_launcher(struct work_struct *);
-DECLARE_WORK(eeh_event_wq, eeh_thread_launcher);
-
-/* Serialize reset sequences for a given pci device */
-DEFINE_MUTEX(eeh_event_mutex);
-
-/**
- * eeh_event_handler - Dispatch EEH events.
- * @dummy - unused
- *
- * The detection of a frozen slot can occur inside an interrupt,
- * where it can be hard to do anything about it.  The goal of this
- * routine is to pull these detection events out of the context
- * of the interrupt handler, and re-dispatch them for processing
- * at a later time in a normal context.
- */
-static int eeh_event_handler(void * dummy)
-{
-	unsigned long flags;
-	struct eeh_event *event;
-	struct eeh_pe *pe;
-
-	spin_lock_irqsave(&eeh_eventlist_lock, flags);
-	event = NULL;
-
-	/* Unqueue the event, get ready to process. */
-	if (!list_empty(&eeh_eventlist)) {
-		event = list_entry(eeh_eventlist.next, struct eeh_event, list);
-		list_del(&event->list);
-	}
-	spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
-
-	if (event == NULL)
-		return 0;
-
-	/* Serialize processing of EEH events */
-	mutex_lock(&eeh_event_mutex);
-	pe = event->pe;
-	eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
-	pr_info("EEH: Detected PCI bus error on PHB#%d-PE#%x\n",
-		pe->phb->global_number, pe->addr);
-
-	set_current_state(TASK_INTERRUPTIBLE);	/* Don't add to load average */
-	eeh_handle_event(pe);
-	eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
-
-	kfree(event);
-	mutex_unlock(&eeh_event_mutex);
-
-	/* If there are no new errors after an hour, clear the counter. */
-	if (pe && pe->freeze_count > 0) {
-		msleep_interruptible(3600*1000);
-		if (pe->freeze_count > 0)
-			pe->freeze_count--;
-
-	}
-
-	return 0;
-}
-
-/**
- * eeh_thread_launcher - Start kernel thread to handle EEH events
- * @dummy - unused
- *
- * This routine is called to start the kernel thread for processing
- * EEH event.
- */
-static void eeh_thread_launcher(struct work_struct *dummy)
-{
-	if (IS_ERR(kthread_run(eeh_event_handler, NULL, "eehd")))
-		printk(KERN_ERR "Failed to start EEH daemon\n");
-}
-
-/**
- * eeh_send_failure_event - Generate a PCI error event
- * @pe: EEH PE
- *
- * This routine can be called within an interrupt context;
- * the actual event will be delivered in a normal context
- * (from a workqueue).
- */
-int eeh_send_failure_event(struct eeh_pe *pe)
-{
-	unsigned long flags;
-	struct eeh_event *event;
-
-	event = kzalloc(sizeof(*event), GFP_ATOMIC);
-	if (!event) {
-		pr_err("EEH: out of memory, event not handled\n");
-		return -ENOMEM;
-	}
-	event->pe = pe;
-
-	/* We may or may not be called in an interrupt context */
-	spin_lock_irqsave(&eeh_eventlist_lock, flags);
-	list_add(&event->list, &eeh_eventlist);
-	spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
-
-	schedule_work(&eeh_event_wq);
-
-	return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_pe.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_pe.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_pe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_pe.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,653 +0,0 @@
-/*
- * The file intends to implement PE based on the information from
- * platforms. Basically, there have 3 types of PEs: PHB/Bus/Device.
- * All the PEs should be organized as hierarchy tree. The first level
- * of the tree will be associated to existing PHBs since the particular
- * PE is only meaningful in one PHB domain.
- *
- * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2012.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/export.h>
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-
-#include <asm/pci-bridge.h>
-#include <asm/ppc-pci.h>
-
-static LIST_HEAD(eeh_phb_pe);
-
-/**
- * eeh_pe_alloc - Allocate PE
- * @phb: PCI controller
- * @type: PE type
- *
- * Allocate PE instance dynamically.
- */
-static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type)
-{
-	struct eeh_pe *pe;
-
-	/* Allocate PHB PE */
-	pe = kzalloc(sizeof(struct eeh_pe), GFP_KERNEL);
-	if (!pe) return NULL;
-
-	/* Initialize PHB PE */
-	pe->type = type;
-	pe->phb = phb;
-	INIT_LIST_HEAD(&pe->child_list);
-	INIT_LIST_HEAD(&pe->child);
-	INIT_LIST_HEAD(&pe->edevs);
-
-	return pe;
-}
-
-/**
- * eeh_phb_pe_create - Create PHB PE
- * @phb: PCI controller
- *
- * The function should be called while the PHB is detected during
- * system boot or PCI hotplug in order to create PHB PE.
- */
-int eeh_phb_pe_create(struct pci_controller *phb)
-{
-	struct eeh_pe *pe;
-
-	/* Allocate PHB PE */
-	pe = eeh_pe_alloc(phb, EEH_PE_PHB);
-	if (!pe) {
-		pr_err("%s: out of memory!\n", __func__);
-		return -ENOMEM;
-	}
-
-	/* Put it into the list */
-	eeh_lock();
-	list_add_tail(&pe->child, &eeh_phb_pe);
-	eeh_unlock();
-
-	pr_debug("EEH: Add PE for PHB#%d\n", phb->global_number);
-
-	return 0;
-}
-
-/**
- * eeh_phb_pe_get - Retrieve PHB PE based on the given PHB
- * @phb: PCI controller
- *
- * The overall PEs form hierarchy tree. The first layer of the
- * hierarchy tree is composed of PHB PEs. The function is used
- * to retrieve the corresponding PHB PE according to the given PHB.
- */
-static struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb)
-{
-	struct eeh_pe *pe;
-
-	list_for_each_entry(pe, &eeh_phb_pe, child) {
-		/*
-		 * Actually, we needn't check the type since
-		 * the PE for PHB has been determined when that
-		 * was created.
-		 */
-		if ((pe->type & EEH_PE_PHB) && pe->phb == phb)
-			return pe;
-	}
-
-	return NULL;
-}
-
-/**
- * eeh_pe_next - Retrieve the next PE in the tree
- * @pe: current PE
- * @root: root PE
- *
- * The function is used to retrieve the next PE in the
- * hierarchy PE tree.
- */
-static struct eeh_pe *eeh_pe_next(struct eeh_pe *pe,
-				  struct eeh_pe *root)
-{
-	struct list_head *next = pe->child_list.next;
-
-	if (next == &pe->child_list) {
-		while (1) {
-			if (pe == root)
-				return NULL;
-			next = pe->child.next;
-			if (next != &pe->parent->child_list)
-				break;
-			pe = pe->parent;
-		}
-	}
-
-	return list_entry(next, struct eeh_pe, child);
-}
-
-/**
- * eeh_pe_traverse - Traverse PEs in the specified PHB
- * @root: root PE
- * @fn: callback
- * @flag: extra parameter to callback
- *
- * The function is used to traverse the specified PE and its
- * child PEs. The traversing is to be terminated once the
- * callback returns something other than NULL, or no more PEs
- * to be traversed.
- */
-static void *eeh_pe_traverse(struct eeh_pe *root,
-			eeh_traverse_func fn, void *flag)
-{
-	struct eeh_pe *pe;
-	void *ret;
-
-	for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
-		ret = fn(pe, flag);
-		if (ret) return ret;
-	}
-
-	return NULL;
-}
-
-/**
- * eeh_pe_dev_traverse - Traverse the devices from the PE
- * @root: EEH PE
- * @fn: function callback
- * @flag: extra parameter to callback
- *
- * The function is used to traverse the devices of the specified
- * PE and its child PEs.
- */
-void *eeh_pe_dev_traverse(struct eeh_pe *root,
-		eeh_traverse_func fn, void *flag)
-{
-	struct eeh_pe *pe;
-	struct eeh_dev *edev;
-	void *ret;
-
-	if (!root) {
-		pr_warning("%s: Invalid PE %p\n", __func__, root);
-		return NULL;
-	}
-
-	eeh_lock();
-
-	/* Traverse root PE */
-	for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
-		eeh_pe_for_each_dev(pe, edev) {
-			ret = fn(edev, flag);
-			if (ret) {
-				eeh_unlock();
-				return ret;
-			}
-		}
-	}
-
-	eeh_unlock();
-
-	return NULL;
-}
-
-/**
- * __eeh_pe_get - Check the PE address
- * @data: EEH PE
- * @flag: EEH device
- *
- * For one particular PE, it can be identified by PE address
- * or tranditional BDF address. BDF address is composed of
- * Bus/Device/Function number. The extra data referred by flag
- * indicates which type of address should be used.
- */
-static void *__eeh_pe_get(void *data, void *flag)
-{
-	struct eeh_pe *pe = (struct eeh_pe *)data;
-	struct eeh_dev *edev = (struct eeh_dev *)flag;
-
-	/* Unexpected PHB PE */
-	if (pe->type & EEH_PE_PHB)
-		return NULL;
-
-	/* We prefer PE address */
-	if (edev->pe_config_addr &&
-	   (edev->pe_config_addr == pe->addr))
-		return pe;
-
-	/* Try BDF address */
-	if (edev->pe_config_addr &&
-	   (edev->config_addr == pe->config_addr))
-		return pe;
-
-	return NULL;
-}
-
-/**
- * eeh_pe_get - Search PE based on the given address
- * @edev: EEH device
- *
- * Search the corresponding PE based on the specified address which
- * is included in the eeh device. The function is used to check if
- * the associated PE has been created against the PE address. It's
- * notable that the PE address has 2 format: traditional PE address
- * which is composed of PCI bus/device/function number, or unified
- * PE address.
- */
-static struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
-{
-	struct eeh_pe *root = eeh_phb_pe_get(edev->phb);
-	struct eeh_pe *pe;
-
-	pe = eeh_pe_traverse(root, __eeh_pe_get, edev);
-
-	return pe;
-}
-
-/**
- * eeh_pe_get_parent - Retrieve the parent PE
- * @edev: EEH device
- *
- * The whole PEs existing in the system are organized as hierarchy
- * tree. The function is used to retrieve the parent PE according
- * to the parent EEH device.
- */
-static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev)
-{
-	struct device_node *dn;
-	struct eeh_dev *parent;
-
-	/*
-	 * It might have the case for the indirect parent
-	 * EEH device already having associated PE, but
-	 * the direct parent EEH device doesn't have yet.
-	 */
-	dn = edev->dn->parent;
-	while (dn) {
-		/* We're poking out of PCI territory */
-		if (!PCI_DN(dn)) return NULL;
-
-		parent = of_node_to_eeh_dev(dn);
-		/* We're poking out of PCI territory */
-		if (!parent) return NULL;
-
-		if (parent->pe)
-			return parent->pe;
-
-		dn = dn->parent;
-	}
-
-	return NULL;
-}
-
-/**
- * eeh_add_to_parent_pe - Add EEH device to parent PE
- * @edev: EEH device
- *
- * Add EEH device to the parent PE. If the parent PE already
- * exists, the PE type will be changed to EEH_PE_BUS. Otherwise,
- * we have to create new PE to hold the EEH device and the new
- * PE will be linked to its parent PE as well.
- */
-int eeh_add_to_parent_pe(struct eeh_dev *edev)
-{
-	struct eeh_pe *pe, *parent;
-
-	eeh_lock();
-
-	/*
-	 * Search the PE has been existing or not according
-	 * to the PE address. If that has been existing, the
-	 * PE should be composed of PCI bus and its subordinate
-	 * components.
-	 */
-	pe = eeh_pe_get(edev);
-	if (pe && !(pe->type & EEH_PE_INVALID)) {
-		if (!edev->pe_config_addr) {
-			eeh_unlock();
-			pr_err("%s: PE with addr 0x%x already exists\n",
-				__func__, edev->config_addr);
-			return -EEXIST;
-		}
-
-		/* Mark the PE as type of PCI bus */
-		pe->type = EEH_PE_BUS;
-		edev->pe = pe;
-
-		/* Put the edev to PE */
-		list_add_tail(&edev->list, &pe->edevs);
-		eeh_unlock();
-		pr_debug("EEH: Add %s to Bus PE#%x\n",
-			edev->dn->full_name, pe->addr);
-
-		return 0;
-	} else if (pe && (pe->type & EEH_PE_INVALID)) {
-		list_add_tail(&edev->list, &pe->edevs);
-		edev->pe = pe;
-		/*
-		 * We're running to here because of PCI hotplug caused by
-		 * EEH recovery. We need clear EEH_PE_INVALID until the top.
-		 */
-		parent = pe;
-		while (parent) {
-			if (!(parent->type & EEH_PE_INVALID))
-				break;
-			parent->type &= ~EEH_PE_INVALID;
-			parent = parent->parent;
-		}
-		eeh_unlock();
-		pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
-			edev->dn->full_name, pe->addr, pe->parent->addr);
-
-		return 0;
-	}
-
-	/* Create a new EEH PE */
-	pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
-	if (!pe) {
-		eeh_unlock();
-		pr_err("%s: out of memory!\n", __func__);
-		return -ENOMEM;
-	}
-	pe->addr	= edev->pe_config_addr;
-	pe->config_addr	= edev->config_addr;
-
-	/*
-	 * Put the new EEH PE into hierarchy tree. If the parent
-	 * can't be found, the newly created PE will be attached
-	 * to PHB directly. Otherwise, we have to associate the
-	 * PE with its parent.
-	 */
-	parent = eeh_pe_get_parent(edev);
-	if (!parent) {
-		parent = eeh_phb_pe_get(edev->phb);
-		if (!parent) {
-			eeh_unlock();
-			pr_err("%s: No PHB PE is found (PHB Domain=%d)\n",
-				__func__, edev->phb->global_number);
-			edev->pe = NULL;
-			kfree(pe);
-			return -EEXIST;
-		}
-	}
-	pe->parent = parent;
-
-	/*
-	 * Put the newly created PE into the child list and
-	 * link the EEH device accordingly.
-	 */
-	list_add_tail(&pe->child, &parent->child_list);
-	list_add_tail(&edev->list, &pe->edevs);
-	edev->pe = pe;
-	eeh_unlock();
-	pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
-		edev->dn->full_name, pe->addr, pe->parent->addr);
-
-	return 0;
-}
-
-/**
- * eeh_rmv_from_parent_pe - Remove one EEH device from the associated PE
- * @edev: EEH device
- * @purge_pe: remove PE or not
- *
- * The PE hierarchy tree might be changed when doing PCI hotplug.
- * Also, the PCI devices or buses could be removed from the system
- * during EEH recovery. So we have to call the function remove the
- * corresponding PE accordingly if necessary.
- */
-int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
-{
-	struct eeh_pe *pe, *parent, *child;
-	int cnt;
-
-	if (!edev->pe) {
-		pr_warning("%s: No PE found for EEH device %s\n",
-			__func__, edev->dn->full_name);
-		return -EEXIST;
-	}
-
-	eeh_lock();
-
-	/* Remove the EEH device */
-	pe = edev->pe;
-	edev->pe = NULL;
-	list_del(&edev->list);
-
-	/*
-	 * Check if the parent PE includes any EEH devices.
-	 * If not, we should delete that. Also, we should
-	 * delete the parent PE if it doesn't have associated
-	 * child PEs and EEH devices.
-	 */
-	while (1) {
-		parent = pe->parent;
-		if (pe->type & EEH_PE_PHB)
-			break;
-
-		if (purge_pe) {
-			if (list_empty(&pe->edevs) &&
-			    list_empty(&pe->child_list)) {
-				list_del(&pe->child);
-				kfree(pe);
-			} else {
-				break;
-			}
-		} else {
-			if (list_empty(&pe->edevs)) {
-				cnt = 0;
-				list_for_each_entry(child, &pe->child_list, child) {
-					if (!(child->type & EEH_PE_INVALID)) {
-						cnt++;
-						break;
-					}
-				}
-
-				if (!cnt)
-					pe->type |= EEH_PE_INVALID;
-				else
-					break;
-			}
-		}
-
-		pe = parent;
-	}
-
-	eeh_unlock();
-
-	return 0;
-}
-
-/**
- * __eeh_pe_state_mark - Mark the state for the PE
- * @data: EEH PE
- * @flag: state
- *
- * The function is used to mark the indicated state for the given
- * PE. Also, the associated PCI devices will be put into IO frozen
- * state as well.
- */
-static void *__eeh_pe_state_mark(void *data, void *flag)
-{
-	struct eeh_pe *pe = (struct eeh_pe *)data;
-	int state = *((int *)flag);
-	struct eeh_dev *tmp;
-	struct pci_dev *pdev;
-
-	/*
-	 * Mark the PE with the indicated state. Also,
-	 * the associated PCI device will be put into
-	 * I/O frozen state to avoid I/O accesses from
-	 * the PCI device driver.
-	 */
-	pe->state |= state;
-	eeh_pe_for_each_dev(pe, tmp) {
-		pdev = eeh_dev_to_pci_dev(tmp);
-		if (pdev)
-			pdev->error_state = pci_channel_io_frozen;
-	}
-
-	return NULL;
-}
-
-/**
- * eeh_pe_state_mark - Mark specified state for PE and its associated device
- * @pe: EEH PE
- *
- * EEH error affects the current PE and its child PEs. The function
- * is used to mark appropriate state for the affected PEs and the
- * associated devices.
- */
-void eeh_pe_state_mark(struct eeh_pe *pe, int state)
-{
-	eeh_lock();
-	eeh_pe_traverse(pe, __eeh_pe_state_mark, &state);
-	eeh_unlock();
-}
-
-/**
- * __eeh_pe_state_clear - Clear state for the PE
- * @data: EEH PE
- * @flag: state
- *
- * The function is used to clear the indicated state from the
- * given PE. Besides, we also clear the check count of the PE
- * as well.
- */
-static void *__eeh_pe_state_clear(void *data, void *flag)
-{
-	struct eeh_pe *pe = (struct eeh_pe *)data;
-	int state = *((int *)flag);
-
-	pe->state &= ~state;
-	pe->check_count = 0;
-
-	return NULL;
-}
-
-/**
- * eeh_pe_state_clear - Clear state for the PE and its children
- * @pe: PE
- * @state: state to be cleared
- *
- * When the PE and its children has been recovered from error,
- * we need clear the error state for that. The function is used
- * for the purpose.
- */
-void eeh_pe_state_clear(struct eeh_pe *pe, int state)
-{
-	eeh_lock();
-	eeh_pe_traverse(pe, __eeh_pe_state_clear, &state);
-	eeh_unlock();
-}
-
-/**
- * eeh_restore_one_device_bars - Restore the Base Address Registers for one device
- * @data: EEH device
- * @flag: Unused
- *
- * Loads the PCI configuration space base address registers,
- * the expansion ROM base address, the latency timer, and etc.
- * from the saved values in the device node.
- */
-static void *eeh_restore_one_device_bars(void *data, void *flag)
-{
-	int i;
-	u32 cmd;
-	struct eeh_dev *edev = (struct eeh_dev *)data;
-	struct device_node *dn = eeh_dev_to_of_node(edev);
-
-	for (i = 4; i < 10; i++)
-		eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]);
-	/* 12 == Expansion ROM Address */
-	eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]);
-
-#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
-#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])
-
-	eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1,
-		SAVED_BYTE(PCI_CACHE_LINE_SIZE));
-	eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1,
-		SAVED_BYTE(PCI_LATENCY_TIMER));
-
-	/* max latency, min grant, interrupt pin and line */
-	eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]);
-
-	/*
-	 * Restore PERR & SERR bits, some devices require it,
-	 * don't touch the other command bits
-	 */
-	eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd);
-	if (edev->config_space[1] & PCI_COMMAND_PARITY)
-		cmd |= PCI_COMMAND_PARITY;
-	else
-		cmd &= ~PCI_COMMAND_PARITY;
-	if (edev->config_space[1] & PCI_COMMAND_SERR)
-		cmd |= PCI_COMMAND_SERR;
-	else
-		cmd &= ~PCI_COMMAND_SERR;
-	eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd);
-
-	return NULL;
-}
-
-/**
- * eeh_pe_restore_bars - Restore the PCI config space info
- * @pe: EEH PE
- *
- * This routine performs a recursive walk to the children
- * of this device as well.
- */
-void eeh_pe_restore_bars(struct eeh_pe *pe)
-{
-	/*
-	 * We needn't take the EEH lock since eeh_pe_dev_traverse()
-	 * will take that.
-	 */
-	eeh_pe_dev_traverse(pe, eeh_restore_one_device_bars, NULL);
-}
-
-/**
- * eeh_pe_bus_get - Retrieve PCI bus according to the given PE
- * @pe: EEH PE
- *
- * Retrieve the PCI bus according to the given PE. Basically,
- * there're 3 types of PEs: PHB/Bus/Device. For PHB PE, the
- * primary PCI bus will be retrieved. The parent bus will be
- * returned for BUS PE. However, we don't have associated PCI
- * bus for DEVICE PE.
- */
-struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
-{
-	struct pci_bus *bus = NULL;
-	struct eeh_dev *edev;
-	struct pci_dev *pdev;
-
-	eeh_lock();
-
-	if (pe->type & EEH_PE_PHB) {
-		bus = pe->phb->bus;
-	} else if (pe->type & EEH_PE_BUS ||
-		   pe->type & EEH_PE_DEVICE) {
-		edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
-		pdev = eeh_dev_to_pci_dev(edev);
-		if (pdev)
-			bus = pdev->bus;
-	}
-
-	eeh_unlock();
-
-	return bus;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_pseries.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_pseries.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_pseries.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_pseries.c	2013-08-25 20:43:22.000000000 -0400
@@ -133,6 +133,48 @@ static int pseries_eeh_init(void)
 	return 0;
 }
 
+static int pseries_eeh_cap_start(struct device_node *dn)
+{
+	struct pci_dn *pdn = PCI_DN(dn);
+	u32 status;
+
+	if (!pdn)
+		return 0;
+
+	rtas_read_config(pdn, PCI_STATUS, 2, &status);
+	if (!(status & PCI_STATUS_CAP_LIST))
+		return 0;
+
+	return PCI_CAPABILITY_LIST;
+}
+
+
+static int pseries_eeh_find_cap(struct device_node *dn, int cap)
+{
+	struct pci_dn *pdn = PCI_DN(dn);
+	int pos = pseries_eeh_cap_start(dn);
+	int cnt = 48;	/* Maximal number of capabilities */
+	u32 id;
+
+	if (!pos)
+		return 0;
+
+        while (cnt--) {
+		rtas_read_config(pdn, pos, 1, &pos);
+		if (pos < 0x40)
+			break;
+		pos &= ~3;
+		rtas_read_config(pdn, pos + PCI_CAP_LIST_ID, 1, &id);
+		if (id == 0xff)
+			break;
+		if (id == cap)
+			return pos;
+		pos += PCI_CAP_LIST_NEXT;
+	}
+
+	return 0;
+}
+
 /**
  * pseries_eeh_of_probe - EEH probe on the given device
  * @dn: OF node
@@ -146,14 +188,16 @@ static void *pseries_eeh_of_probe(struct
 {
 	struct eeh_dev *edev;
 	struct eeh_pe pe;
+	struct pci_dn *pdn = PCI_DN(dn);
 	const u32 *class_code, *vendor_id, *device_id;
 	const u32 *regs;
+	u32 pcie_flags;
 	int enable = 0;
 	int ret;
 
 	/* Retrieve OF node and eeh device */
 	edev = of_node_to_eeh_dev(dn);
-	if (!of_device_is_available(dn))
+	if (edev->pe || !of_device_is_available(dn))
 		return NULL;
 
 	/* Retrieve class/vendor/device IDs */
@@ -167,9 +211,26 @@ static void *pseries_eeh_of_probe(struct
 	if (dn->type && !strcmp(dn->type, "isa"))
 		return NULL;
 
-	/* Update class code and mode of eeh device */
+	/*
+	 * Update class code and mode of eeh device. We need
+	 * correctly reflects that current device is root port
+	 * or PCIe switch downstream port.
+	 */
 	edev->class_code = *class_code;
-	edev->mode = 0;
+	edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP);
+	edev->mode &= 0xFFFFFF00;
+	if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
+		edev->mode |= EEH_DEV_BRIDGE;
+		if (edev->pcie_cap) {
+			rtas_read_config(pdn, edev->pcie_cap + PCI_EXP_FLAGS,
+					 2, &pcie_flags);
+			pcie_flags = (pcie_flags & PCI_EXP_FLAGS_TYPE) >> 4;
+			if (pcie_flags == PCI_EXP_TYPE_ROOT_PORT)
+				edev->mode |= EEH_DEV_ROOT_PORT;
+			else if (pcie_flags == PCI_EXP_TYPE_DOWNSTREAM)
+				edev->mode |= EEH_DEV_DS_PORT;
+		}
+	}
 
 	/* Retrieve the device address */
 	regs = of_get_property(dn, "reg", NULL);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_sysfs.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_sysfs.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/eeh_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/eeh_sysfs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,75 +0,0 @@
-/*
- * Sysfs entries for PCI Error Recovery for PAPR-compliant platform.
- * Copyright IBM Corporation 2007
- * Copyright Linas Vepstas <linas@austin.ibm.com> 2007
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send comments and feedback to Linas Vepstas <linas@austin.ibm.com>
- */
-#include <linux/pci.h>
-#include <linux/stat.h>
-#include <asm/ppc-pci.h>
-#include <asm/pci-bridge.h>
-
-/**
- * EEH_SHOW_ATTR -- Create sysfs entry for eeh statistic
- * @_name: name of file in sysfs directory
- * @_memb: name of member in struct pci_dn to access
- * @_format: printf format for display
- *
- * All of the attributes look very similar, so just
- * auto-gen a cut-n-paste routine to display them.
- */
-#define EEH_SHOW_ATTR(_name,_memb,_format)               \
-static ssize_t eeh_show_##_name(struct device *dev,      \
-		struct device_attribute *attr, char *buf)          \
-{                                                        \
-	struct pci_dev *pdev = to_pci_dev(dev);               \
-	struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);      \
-	                                                      \
-	if (!edev)                                            \
-		return 0;                                     \
-	                                                      \
-	return sprintf(buf, _format "\n", edev->_memb);       \
-}                                                        \
-static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL);
-
-EEH_SHOW_ATTR(eeh_mode,            mode,            "0x%x");
-EEH_SHOW_ATTR(eeh_config_addr,     config_addr,     "0x%x");
-EEH_SHOW_ATTR(eeh_pe_config_addr,  pe_config_addr,  "0x%x");
-
-void eeh_sysfs_add_device(struct pci_dev *pdev)
-{
-	int rc=0;
-
-	rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode);
-	rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr);
-	rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
-
-	if (rc)
-		printk(KERN_WARNING "EEH: Unable to create sysfs entries\n");
-}
-
-void eeh_sysfs_remove_device(struct pci_dev *pdev)
-{
-	device_remove_file(&pdev->dev, &dev_attr_eeh_mode);
-	device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr);
-	device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
-}
-
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/io_event_irq.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/io_event_irq.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/io_event_irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/io_event_irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -115,7 +115,7 @@ static struct pseries_io_event * ioei_fi
  *   by scope or event type alone. For example, Torrent ISR route change
  *   event is reported with scope 0x00 (Not Applicatable) rather than
  *   0x3B (Torrent-hub). It is better to let the clients to identify
- *   who owns the the event.
+ *   who owns the event.
  */
 
 static irqreturn_t ioei_interrupt(int irq, void *dev_id)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/iommu.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/iommu.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/iommu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/iommu.c	2013-08-25 20:43:22.000000000 -0400
@@ -614,6 +614,7 @@ static void pci_dma_bus_setup_pSeries(st
 
 	iommu_table_setparms(pci->phb, dn, tbl);
 	pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
+	iommu_register_group(tbl, pci_domain_nr(bus), 0);
 
 	/* Divide the rest (1.75GB) among the children */
 	pci->phb->dma_window_size = 0x80000000ul;
@@ -658,6 +659,7 @@ static void pci_dma_bus_setup_pSeriesLP(
 				   ppci->phb->node);
 		iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
 		ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
+		iommu_register_group(tbl, pci_domain_nr(bus), 0);
 		pr_debug("  created table: %p\n", ppci->iommu_table);
 	}
 }
@@ -684,6 +686,7 @@ static void pci_dma_dev_setup_pSeries(st
 				   phb->node);
 		iommu_table_setparms(phb, dn, tbl);
 		PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
+		iommu_register_group(tbl, pci_domain_nr(phb->bus), 0);
 		set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table);
 		return;
 	}
@@ -1184,6 +1187,7 @@ static void pci_dma_dev_setup_pSeriesLP(
 				   pci->phb->node);
 		iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
 		pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
+		iommu_register_group(tbl, pci_domain_nr(pci->phb->bus), 0);
 		pr_debug("  created table: %p\n", pci->iommu_table);
 	} else {
 		pr_debug("  found DMA window, table: %p\n", pci->iommu_table);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/Kconfig linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/Kconfig
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -19,7 +19,6 @@ config PPC_PSERIES
 	select ZLIB_DEFLATE
 	select PPC_DOORBELL
 	select HAVE_CONTEXT_TRACKING
-	select HOTPLUG if SMP
 	select HOTPLUG_CPU if SMP
 	default y
 
@@ -33,11 +32,6 @@ config PPC_SPLPAR
 	  processors, that is, which share physical processors between
 	  two or more partitions.
 
-config EEH
-	bool
-	depends on PPC_PSERIES && PCI
-	default y
-
 config PSERIES_MSI
        bool
        depends on PCI_MSI && EEH
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/lpar.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/lpar.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/lpar.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/lpar.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,6 +45,13 @@
 #include "plpar_wrappers.h"
 #include "pseries.h"
 
+/* Flag bits for H_BULK_REMOVE */
+#define HBR_REQUEST	0x4000000000000000UL
+#define HBR_RESPONSE	0x8000000000000000UL
+#define HBR_END		0xc000000000000000UL
+#define HBR_AVPN	0x0200000000000000UL
+#define HBR_ANDCOND	0x0100000000000000UL
+
 
 /* in hvCall.S */
 EXPORT_SYMBOL(plpar_hcall);
@@ -64,6 +71,9 @@ void vpa_init(int cpu)
 	if (cpu_has_feature(CPU_FTR_ALTIVEC))
 		lppaca_of(cpu).vmxregs_in_use = 1;
 
+	if (cpu_has_feature(CPU_FTR_ARCH_207S))
+		lppaca_of(cpu).ebb_regs_in_use = 1;
+
 	addr = __pa(&lppaca_of(cpu));
 	ret = register_vpa(hwcpu, addr);
 
@@ -136,7 +146,7 @@ static long pSeries_lpar_hpte_insert(uns
 	flags = 0;
 
 	/* Make pHyp happy */
-	if ((rflags & _PAGE_NO_CACHE) & !(rflags & _PAGE_WRITETHRU))
+	if ((rflags & _PAGE_NO_CACHE) && !(rflags & _PAGE_WRITETHRU))
 		hpte_r &= ~_PAGE_COHERENT;
 	if (firmware_has_feature(FW_FEATURE_XCMO) && !(hpte_r & HPTE_R_N))
 		flags |= H_COALESCE_CAND;
@@ -240,7 +250,8 @@ static void pSeries_lpar_hptab_clear(voi
 static long pSeries_lpar_hpte_updatepp(unsigned long slot,
 				       unsigned long newpp,
 				       unsigned long vpn,
-				       int psize, int ssize, int local)
+				       int psize, int apsize,
+				       int ssize, int local)
 {
 	unsigned long lpar_rc;
 	unsigned long flags = (newpp & 7) | H_AVPN;
@@ -328,7 +339,8 @@ static void pSeries_lpar_hpte_updatebolt
 }
 
 static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn,
-					 int psize, int ssize, int local)
+					 int psize, int apsize,
+					 int ssize, int local)
 {
 	unsigned long want_v;
 	unsigned long lpar_rc;
@@ -345,6 +357,113 @@ static void pSeries_lpar_hpte_invalidate
 	BUG_ON(lpar_rc != H_SUCCESS);
 }
 
+/*
+ * Limit iterations holding pSeries_lpar_tlbie_lock to 3. We also need
+ * to make sure that we avoid bouncing the hypervisor tlbie lock.
+ */
+#define PPC64_HUGE_HPTE_BATCH 12
+
+static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
+					     unsigned long *vpn, int count,
+					     int psize, int ssize)
+{
+	unsigned long param[8];
+	int i = 0, pix = 0, rc;
+	unsigned long flags = 0;
+	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+
+	if (lock_tlbie)
+		spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
+
+	for (i = 0; i < count; i++) {
+
+		if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
+			pSeries_lpar_hpte_invalidate(slot[i], vpn[i], psize, 0,
+						     ssize, 0);
+		} else {
+			param[pix] = HBR_REQUEST | HBR_AVPN | slot[i];
+			param[pix+1] = hpte_encode_avpn(vpn[i], psize, ssize);
+			pix += 2;
+			if (pix == 8) {
+				rc = plpar_hcall9(H_BULK_REMOVE, param,
+						  param[0], param[1], param[2],
+						  param[3], param[4], param[5],
+						  param[6], param[7]);
+				BUG_ON(rc != H_SUCCESS);
+				pix = 0;
+			}
+		}
+	}
+	if (pix) {
+		param[pix] = HBR_END;
+		rc = plpar_hcall9(H_BULK_REMOVE, param, param[0], param[1],
+				  param[2], param[3], param[4], param[5],
+				  param[6], param[7]);
+		BUG_ON(rc != H_SUCCESS);
+	}
+
+	if (lock_tlbie)
+		spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
+}
+
+static void pSeries_lpar_hugepage_invalidate(struct mm_struct *mm,
+				       unsigned char *hpte_slot_array,
+				       unsigned long addr, int psize)
+{
+	int ssize = 0, i, index = 0;
+	unsigned long s_addr = addr;
+	unsigned int max_hpte_count, valid;
+	unsigned long vpn_array[PPC64_HUGE_HPTE_BATCH];
+	unsigned long slot_array[PPC64_HUGE_HPTE_BATCH];
+	unsigned long shift, hidx, vpn = 0, vsid, hash, slot;
+
+	shift = mmu_psize_defs[psize].shift;
+	max_hpte_count = 1U << (PMD_SHIFT - shift);
+
+	for (i = 0; i < max_hpte_count; i++) {
+		valid = hpte_valid(hpte_slot_array, i);
+		if (!valid)
+			continue;
+		hidx =  hpte_hash_index(hpte_slot_array, i);
+
+		/* get the vpn */
+		addr = s_addr + (i * (1ul << shift));
+		if (!is_kernel_addr(addr)) {
+			ssize = user_segment_size(addr);
+			vsid = get_vsid(mm->context.id, addr, ssize);
+			WARN_ON(vsid == 0);
+		} else {
+			vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
+			ssize = mmu_kernel_ssize;
+		}
+
+		vpn = hpt_vpn(addr, vsid, ssize);
+		hash = hpt_hash(vpn, shift, ssize);
+		if (hidx & _PTEIDX_SECONDARY)
+			hash = ~hash;
+
+		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
+		slot += hidx & _PTEIDX_GROUP_IX;
+
+		slot_array[index] = slot;
+		vpn_array[index] = vpn;
+		if (index == PPC64_HUGE_HPTE_BATCH - 1) {
+			/*
+			 * Now do a bluk invalidate
+			 */
+			__pSeries_lpar_hugepage_invalidate(slot_array,
+							   vpn_array,
+							   PPC64_HUGE_HPTE_BATCH,
+							   psize, ssize);
+			index = 0;
+		} else
+			index++;
+	}
+	if (index)
+		__pSeries_lpar_hugepage_invalidate(slot_array, vpn_array,
+						   index, psize, ssize);
+}
+
 static void pSeries_lpar_hpte_removebolted(unsigned long ea,
 					   int psize, int ssize)
 {
@@ -356,17 +475,12 @@ static void pSeries_lpar_hpte_removebolt
 
 	slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
 	BUG_ON(slot == -1);
-
-	pSeries_lpar_hpte_invalidate(slot, vpn, psize, ssize, 0);
+	/*
+	 * lpar doesn't use the passed actual page size
+	 */
+	pSeries_lpar_hpte_invalidate(slot, vpn, psize, 0, ssize, 0);
 }
 
-/* Flag bits for H_BULK_REMOVE */
-#define HBR_REQUEST	0x4000000000000000UL
-#define HBR_RESPONSE	0x8000000000000000UL
-#define HBR_END		0xc000000000000000UL
-#define HBR_AVPN	0x0200000000000000UL
-#define HBR_ANDCOND	0x0100000000000000UL
-
 /*
  * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
  * lock.
@@ -400,8 +514,11 @@ static void pSeries_lpar_flush_hash_rang
 			slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 			slot += hidx & _PTEIDX_GROUP_IX;
 			if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
+				/*
+				 * lpar doesn't use the passed actual page size
+				 */
 				pSeries_lpar_hpte_invalidate(slot, vpn, psize,
-							     ssize, local);
+							     0, ssize, local);
 			} else {
 				param[pix] = HBR_REQUEST | HBR_AVPN | slot;
 				param[pix+1] = hpte_encode_avpn(vpn, psize,
@@ -452,6 +569,7 @@ void __init hpte_init_lpar(void)
 	ppc_md.hpte_removebolted = pSeries_lpar_hpte_removebolted;
 	ppc_md.flush_hash_range	= pSeries_lpar_flush_hash_range;
 	ppc_md.hpte_clear_all   = pSeries_lpar_hptab_clear;
+	ppc_md.hugepage_invalidate = pSeries_lpar_hugepage_invalidate;
 }
 
 #ifdef CONFIG_PPC_SMLPAR
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/Makefile linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/Makefile
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -6,9 +6,7 @@ obj-y			:= lpar.o hvCall.o nvram.o recon
 			   firmware.o power.o dlpar.o mobility.o
 obj-$(CONFIG_SMP)	+= smp.o
 obj-$(CONFIG_SCANLOG)	+= scanlog.o
-obj-$(CONFIG_EEH)	+= eeh.o eeh_pe.o eeh_dev.o eeh_cache.o \
-			   eeh_driver.o eeh_event.o eeh_sysfs.o \
-			   eeh_pseries.o
+obj-$(CONFIG_EEH)	+= eeh_pseries.o
 obj-$(CONFIG_KEXEC)	+= kexec.o
 obj-$(CONFIG_PCI)	+= pci.o pci_dlpar.o
 obj-$(CONFIG_PSERIES_MSI)	+= msi.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/nvram.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/nvram.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/nvram.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/nvram.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/kmsg_dump.h>
+#include <linux/pstore.h>
 #include <linux/ctype.h>
 #include <linux/zlib.h>
 #include <asm/uaccess.h>
@@ -29,6 +30,13 @@
 /* Max bytes to read/write in one go */
 #define NVRW_CNT 0x20
 
+/*
+ * Set oops header version to distingush between old and new format header.
+ * lnx,oops-log partition max size is 4000, header version > 4000 will
+ * help in identifying new header.
+ */
+#define OOPS_HDR_VERSION 5000
+
 static unsigned int nvram_size;
 static int nvram_fetch, nvram_store;
 static char nvram_buf[NVRW_CNT];	/* assume this is in the first 4GB */
@@ -45,20 +53,23 @@ struct nvram_os_partition {
 	int min_size;	/* minimum acceptable size (0 means req_size) */
 	long size;	/* size of data portion (excluding err_log_info) */
 	long index;	/* offset of data portion of partition */
+	bool os_partition; /* partition initialized by OS, not FW */
 };
 
 static struct nvram_os_partition rtas_log_partition = {
 	.name = "ibm,rtas-log",
 	.req_size = 2079,
 	.min_size = 1055,
-	.index = -1
+	.index = -1,
+	.os_partition = true
 };
 
 static struct nvram_os_partition oops_log_partition = {
 	.name = "lnx,oops-log",
 	.req_size = 4000,
 	.min_size = 2000,
-	.index = -1
+	.index = -1,
+	.os_partition = true
 };
 
 static const char *pseries_nvram_os_partitions[] = {
@@ -67,6 +78,12 @@ static const char *pseries_nvram_os_part
 	NULL
 };
 
+struct oops_log_info {
+	u16 version;
+	u16 report_length;
+	u64 timestamp;
+} __attribute__((packed));
+
 static void oops_to_nvram(struct kmsg_dumper *dumper,
 			  enum kmsg_dump_reason reason);
 
@@ -83,28 +100,28 @@ static unsigned long last_unread_rtas_ev
 
  * big_oops_buf[] holds the uncompressed text we're capturing.
  *
- * oops_buf[] holds the compressed text, preceded by a prefix.
- * The prefix is just a u16 holding the length of the compressed* text.
- * (*Or uncompressed, if compression fails.)  oops_buf[] gets written
- * to NVRAM.
+ * oops_buf[] holds the compressed text, preceded by a oops header.
+ * oops header has u16 holding the version of oops header (to differentiate
+ * between old and new format header) followed by u16 holding the length of
+ * the compressed* text (*Or uncompressed, if compression fails.) and u64
+ * holding the timestamp. oops_buf[] gets written to NVRAM.
  *
- * oops_len points to the prefix.  oops_data points to the compressed text.
+ * oops_log_info points to the header. oops_data points to the compressed text.
  *
  * +- oops_buf
- * |		+- oops_data
- * v		v
- * +------------+-----------------------------------------------+
- * | length	| text                                          |
- * | (2 bytes)	| (oops_data_sz bytes)                          |
- * +------------+-----------------------------------------------+
+ * |                                   +- oops_data
+ * v                                   v
+ * +-----------+-----------+-----------+------------------------+
+ * | version   | length    | timestamp | text                   |
+ * | (2 bytes) | (2 bytes) | (8 bytes) | (oops_data_sz bytes)   |
+ * +-----------+-----------+-----------+------------------------+
  * ^
- * +- oops_len
+ * +- oops_log_info
  *
  * We preallocate these buffers during init to avoid kmalloc during oops/panic.
  */
 static size_t big_oops_buf_sz;
 static char *big_oops_buf, *oops_buf;
-static u16 *oops_len;
 static char *oops_data;
 static size_t oops_data_sz;
 
@@ -114,6 +131,30 @@ static size_t oops_data_sz;
 #define MEM_LEVEL 4
 static struct z_stream_s stream;
 
+#ifdef CONFIG_PSTORE
+static struct nvram_os_partition of_config_partition = {
+	.name = "of-config",
+	.index = -1,
+	.os_partition = false
+};
+
+static struct nvram_os_partition common_partition = {
+	.name = "common",
+	.index = -1,
+	.os_partition = false
+};
+
+static enum pstore_type_id nvram_type_ids[] = {
+	PSTORE_TYPE_DMESG,
+	PSTORE_TYPE_PPC_RTAS,
+	PSTORE_TYPE_PPC_OF,
+	PSTORE_TYPE_PPC_COMMON,
+	-1
+};
+static int read_type;
+static unsigned long last_rtas_event;
+#endif
+
 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
 {
 	unsigned int i;
@@ -275,48 +316,72 @@ int nvram_write_error_log(char * buff, i
 {
 	int rc = nvram_write_os_partition(&rtas_log_partition, buff, length,
 						err_type, error_log_cnt);
-	if (!rc)
+	if (!rc) {
 		last_unread_rtas_event = get_seconds();
+#ifdef CONFIG_PSTORE
+		last_rtas_event = get_seconds();
+#endif
+	}
+
 	return rc;
 }
 
-/* nvram_read_error_log
+/* nvram_read_partition
  *
- * Reads nvram for error log for at most 'length'
+ * Reads nvram partition for at most 'length'
  */
-int nvram_read_error_log(char * buff, int length,
-                         unsigned int * err_type, unsigned int * error_log_cnt)
+int nvram_read_partition(struct nvram_os_partition *part, char *buff,
+			int length, unsigned int *err_type,
+			unsigned int *error_log_cnt)
 {
 	int rc;
 	loff_t tmp_index;
 	struct err_log_info info;
 	
-	if (rtas_log_partition.index == -1)
+	if (part->index == -1)
 		return -1;
 
-	if (length > rtas_log_partition.size)
-		length = rtas_log_partition.size;
+	if (length > part->size)
+		length = part->size;
 
-	tmp_index = rtas_log_partition.index;
+	tmp_index = part->index;
 
-	rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index);
-	if (rc <= 0) {
-		printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
-		return rc;
+	if (part->os_partition) {
+		rc = ppc_md.nvram_read((char *)&info,
+					sizeof(struct err_log_info),
+					&tmp_index);
+		if (rc <= 0) {
+			pr_err("%s: Failed nvram_read (%d)\n", __FUNCTION__,
+									rc);
+			return rc;
+		}
 	}
 
 	rc = ppc_md.nvram_read(buff, length, &tmp_index);
 	if (rc <= 0) {
-		printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
+		pr_err("%s: Failed nvram_read (%d)\n", __FUNCTION__, rc);
 		return rc;
 	}
 
-	*error_log_cnt = info.seq_num;
-	*err_type = info.error_type;
+	if (part->os_partition) {
+		*error_log_cnt = info.seq_num;
+		*err_type = info.error_type;
+	}
 
 	return 0;
 }
 
+/* nvram_read_error_log
+ *
+ * Reads nvram for error log for at most 'length'
+ */
+int nvram_read_error_log(char *buff, int length,
+			unsigned int *err_type, unsigned int *error_log_cnt)
+{
+	return nvram_read_partition(&rtas_log_partition, buff, length,
+						err_type, error_log_cnt);
+}
+
 /* This doesn't actually zero anything, but it sets the event_logged
  * word to tell that this event is safely in syslog.
  */
@@ -405,9 +470,339 @@ static int __init pseries_nvram_init_os_
 	return 0;
 }
 
+/*
+ * Are we using the ibm,rtas-log for oops/panic reports?  And if so,
+ * would logging this oops/panic overwrite an RTAS event that rtas_errd
+ * hasn't had a chance to read and process?  Return 1 if so, else 0.
+ *
+ * We assume that if rtas_errd hasn't read the RTAS event in
+ * NVRAM_RTAS_READ_TIMEOUT seconds, it's probably not going to.
+ */
+static int clobbering_unread_rtas_event(void)
+{
+	return (oops_log_partition.index == rtas_log_partition.index
+		&& last_unread_rtas_event
+		&& get_seconds() - last_unread_rtas_event <=
+						NVRAM_RTAS_READ_TIMEOUT);
+}
+
+/* Derived from logfs_compress() */
+static int nvram_compress(const void *in, void *out, size_t inlen,
+							size_t outlen)
+{
+	int err, ret;
+
+	ret = -EIO;
+	err = zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
+						MEM_LEVEL, Z_DEFAULT_STRATEGY);
+	if (err != Z_OK)
+		goto error;
+
+	stream.next_in = in;
+	stream.avail_in = inlen;
+	stream.total_in = 0;
+	stream.next_out = out;
+	stream.avail_out = outlen;
+	stream.total_out = 0;
+
+	err = zlib_deflate(&stream, Z_FINISH);
+	if (err != Z_STREAM_END)
+		goto error;
+
+	err = zlib_deflateEnd(&stream);
+	if (err != Z_OK)
+		goto error;
+
+	if (stream.total_out >= stream.total_in)
+		goto error;
+
+	ret = stream.total_out;
+error:
+	return ret;
+}
+
+/* Compress the text from big_oops_buf into oops_buf. */
+static int zip_oops(size_t text_len)
+{
+	struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
+	int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
+								oops_data_sz);
+	if (zipped_len < 0) {
+		pr_err("nvram: compression failed; returned %d\n", zipped_len);
+		pr_err("nvram: logging uncompressed oops/panic report\n");
+		return -1;
+	}
+	oops_hdr->version = OOPS_HDR_VERSION;
+	oops_hdr->report_length = (u16) zipped_len;
+	oops_hdr->timestamp = get_seconds();
+	return 0;
+}
+
+#ifdef CONFIG_PSTORE
+/* Derived from logfs_uncompress */
+int nvram_decompress(void *in, void *out, size_t inlen, size_t outlen)
+{
+	int err, ret;
+
+	ret = -EIO;
+	err = zlib_inflateInit(&stream);
+	if (err != Z_OK)
+		goto error;
+
+	stream.next_in = in;
+	stream.avail_in = inlen;
+	stream.total_in = 0;
+	stream.next_out = out;
+	stream.avail_out = outlen;
+	stream.total_out = 0;
+
+	err = zlib_inflate(&stream, Z_FINISH);
+	if (err != Z_STREAM_END)
+		goto error;
+
+	err = zlib_inflateEnd(&stream);
+	if (err != Z_OK)
+		goto error;
+
+	ret = stream.total_out;
+error:
+	return ret;
+}
+
+static int nvram_pstore_open(struct pstore_info *psi)
+{
+	/* Reset the iterator to start reading partitions again */
+	read_type = -1;
+	return 0;
+}
+
+/**
+ * nvram_pstore_write - pstore write callback for nvram
+ * @type:               Type of message logged
+ * @reason:             reason behind dump (oops/panic)
+ * @id:                 identifier to indicate the write performed
+ * @part:               pstore writes data to registered buffer in parts,
+ *                      part number will indicate the same.
+ * @count:              Indicates oops count
+ * @hsize:              Size of header added by pstore
+ * @size:               number of bytes written to the registered buffer
+ * @psi:                registered pstore_info structure
+ *
+ * Called by pstore_dump() when an oops or panic report is logged in the
+ * printk buffer.
+ * Returns 0 on successful write.
+ */
+static int nvram_pstore_write(enum pstore_type_id type,
+				enum kmsg_dump_reason reason,
+				u64 *id, unsigned int part, int count,
+				size_t hsize, size_t size,
+				struct pstore_info *psi)
+{
+	int rc;
+	unsigned int err_type = ERR_TYPE_KERNEL_PANIC;
+	struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;
+
+	/* part 1 has the recent messages from printk buffer */
+	if (part > 1 || type != PSTORE_TYPE_DMESG ||
+				clobbering_unread_rtas_event())
+		return -1;
+
+	oops_hdr->version = OOPS_HDR_VERSION;
+	oops_hdr->report_length = (u16) size;
+	oops_hdr->timestamp = get_seconds();
+
+	if (big_oops_buf) {
+		rc = zip_oops(size);
+		/*
+		 * If compression fails copy recent log messages from
+		 * big_oops_buf to oops_data.
+		 */
+		if (rc != 0) {
+			size_t diff = size - oops_data_sz + hsize;
+
+			if (size > oops_data_sz) {
+				memcpy(oops_data, big_oops_buf, hsize);
+				memcpy(oops_data + hsize, big_oops_buf + diff,
+					oops_data_sz - hsize);
+
+				oops_hdr->report_length = (u16) oops_data_sz;
+			} else
+				memcpy(oops_data, big_oops_buf, size);
+		} else
+			err_type = ERR_TYPE_KERNEL_PANIC_GZ;
+	}
+
+	rc = nvram_write_os_partition(&oops_log_partition, oops_buf,
+		(int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type,
+		count);
+
+	if (rc != 0)
+		return rc;
+
+	*id = part;
+	return 0;
+}
+
+/*
+ * Reads the oops/panic report, rtas, of-config and common partition.
+ * Returns the length of the data we read from each partition.
+ * Returns 0 if we've been called before.
+ */
+static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
+				int *count, struct timespec *time, char **buf,
+				struct pstore_info *psi)
+{
+	struct oops_log_info *oops_hdr;
+	unsigned int err_type, id_no, size = 0;
+	struct nvram_os_partition *part = NULL;
+	char *buff = NULL, *big_buff = NULL;
+	int sig = 0;
+	loff_t p;
+
+	read_type++;
+
+	switch (nvram_type_ids[read_type]) {
+	case PSTORE_TYPE_DMESG:
+		part = &oops_log_partition;
+		*type = PSTORE_TYPE_DMESG;
+		break;
+	case PSTORE_TYPE_PPC_RTAS:
+		part = &rtas_log_partition;
+		*type = PSTORE_TYPE_PPC_RTAS;
+		time->tv_sec = last_rtas_event;
+		time->tv_nsec = 0;
+		break;
+	case PSTORE_TYPE_PPC_OF:
+		sig = NVRAM_SIG_OF;
+		part = &of_config_partition;
+		*type = PSTORE_TYPE_PPC_OF;
+		*id = PSTORE_TYPE_PPC_OF;
+		time->tv_sec = 0;
+		time->tv_nsec = 0;
+		break;
+	case PSTORE_TYPE_PPC_COMMON:
+		sig = NVRAM_SIG_SYS;
+		part = &common_partition;
+		*type = PSTORE_TYPE_PPC_COMMON;
+		*id = PSTORE_TYPE_PPC_COMMON;
+		time->tv_sec = 0;
+		time->tv_nsec = 0;
+		break;
+	default:
+		return 0;
+	}
+
+	if (!part->os_partition) {
+		p = nvram_find_partition(part->name, sig, &size);
+		if (p <= 0) {
+			pr_err("nvram: Failed to find partition %s, "
+				"err %d\n", part->name, (int)p);
+			return 0;
+		}
+		part->index = p;
+		part->size = size;
+	}
+
+	buff = kmalloc(part->size, GFP_KERNEL);
+
+	if (!buff)
+		return -ENOMEM;
+
+	if (nvram_read_partition(part, buff, part->size, &err_type, &id_no)) {
+		kfree(buff);
+		return 0;
+	}
+
+	*count = 0;
+
+	if (part->os_partition)
+		*id = id_no;
+
+	if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
+		int length, unzipped_len;
+		size_t hdr_size;
+
+		oops_hdr = (struct oops_log_info *)buff;
+		if (oops_hdr->version < OOPS_HDR_VERSION) {
+			/* Old format oops header had 2-byte record size */
+			hdr_size = sizeof(u16);
+			length = oops_hdr->version;
+			time->tv_sec = 0;
+			time->tv_nsec = 0;
+		} else {
+			hdr_size = sizeof(*oops_hdr);
+			length = oops_hdr->report_length;
+			time->tv_sec = oops_hdr->timestamp;
+			time->tv_nsec = 0;
+		}
+		*buf = kmalloc(length, GFP_KERNEL);
+		if (*buf == NULL)
+			return -ENOMEM;
+		memcpy(*buf, buff + hdr_size, length);
+		kfree(buff);
+
+		if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) {
+			big_buff = kmalloc(big_oops_buf_sz, GFP_KERNEL);
+			if (!big_buff)
+				return -ENOMEM;
+
+			unzipped_len = nvram_decompress(*buf, big_buff,
+						length, big_oops_buf_sz);
+
+			if (unzipped_len < 0) {
+				pr_err("nvram: decompression failed, returned "
+					"rc %d\n", unzipped_len);
+				kfree(big_buff);
+			} else {
+				*buf = big_buff;
+				length = unzipped_len;
+			}
+		}
+		return length;
+	}
+
+	*buf = buff;
+	return part->size;
+}
+
+static struct pstore_info nvram_pstore_info = {
+	.owner = THIS_MODULE,
+	.name = "nvram",
+	.open = nvram_pstore_open,
+	.read = nvram_pstore_read,
+	.write = nvram_pstore_write,
+};
+
+static int nvram_pstore_init(void)
+{
+	int rc = 0;
+
+	if (big_oops_buf) {
+		nvram_pstore_info.buf = big_oops_buf;
+		nvram_pstore_info.bufsize = big_oops_buf_sz;
+	} else {
+		nvram_pstore_info.buf = oops_data;
+		nvram_pstore_info.bufsize = oops_data_sz;
+	}
+
+	rc = pstore_register(&nvram_pstore_info);
+	if (rc != 0)
+		pr_err("nvram: pstore_register() failed, defaults to "
+				"kmsg_dump; returned %d\n", rc);
+
+	return rc;
+}
+#else
+static int nvram_pstore_init(void)
+{
+	return -1;
+}
+#endif
+
 static void __init nvram_init_oops_partition(int rtas_partition_exists)
 {
 	int rc;
+	size_t size;
 
 	rc = pseries_nvram_init_os_partition(&oops_log_partition);
 	if (rc != 0) {
@@ -425,9 +820,8 @@ static void __init nvram_init_oops_parti
 						oops_log_partition.name);
 		return;
 	}
-	oops_len = (u16*) oops_buf;
-	oops_data = oops_buf + sizeof(u16);
-	oops_data_sz = oops_log_partition.size - sizeof(u16);
+	oops_data = oops_buf + sizeof(struct oops_log_info);
+	oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info);
 
 	/*
 	 * Figure compression (preceded by elimination of each line's <n>
@@ -437,8 +831,9 @@ static void __init nvram_init_oops_parti
 	big_oops_buf_sz = (oops_data_sz * 100) / 45;
 	big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
 	if (big_oops_buf) {
-		stream.workspace = kmalloc(zlib_deflate_workspacesize(
-				WINDOW_BITS, MEM_LEVEL), GFP_KERNEL);
+		size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
+			zlib_inflate_workspacesize());
+		stream.workspace = kmalloc(size, GFP_KERNEL);
 		if (!stream.workspace) {
 			pr_err("nvram: No memory for compression workspace; "
 				"skipping compression of %s partition data\n",
@@ -452,6 +847,11 @@ static void __init nvram_init_oops_parti
 		stream.workspace = NULL;
 	}
 
+	rc = nvram_pstore_init();
+
+	if (!rc)
+		return;
+
 	rc = kmsg_dump_register(&nvram_kmsg_dumper);
 	if (rc != 0) {
 		pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc);
@@ -501,70 +901,6 @@ int __init pSeries_nvram_init(void)
 	return 0;
 }
 
-/*
- * Are we using the ibm,rtas-log for oops/panic reports?  And if so,
- * would logging this oops/panic overwrite an RTAS event that rtas_errd
- * hasn't had a chance to read and process?  Return 1 if so, else 0.
- *
- * We assume that if rtas_errd hasn't read the RTAS event in
- * NVRAM_RTAS_READ_TIMEOUT seconds, it's probably not going to.
- */
-static int clobbering_unread_rtas_event(void)
-{
-	return (oops_log_partition.index == rtas_log_partition.index
-		&& last_unread_rtas_event
-		&& get_seconds() - last_unread_rtas_event <=
-						NVRAM_RTAS_READ_TIMEOUT);
-}
-
-/* Derived from logfs_compress() */
-static int nvram_compress(const void *in, void *out, size_t inlen,
-							size_t outlen)
-{
-	int err, ret;
-
-	ret = -EIO;
-	err = zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
-						MEM_LEVEL, Z_DEFAULT_STRATEGY);
-	if (err != Z_OK)
-		goto error;
-
-	stream.next_in = in;
-	stream.avail_in = inlen;
-	stream.total_in = 0;
-	stream.next_out = out;
-	stream.avail_out = outlen;
-	stream.total_out = 0;
-
-	err = zlib_deflate(&stream, Z_FINISH);
-	if (err != Z_STREAM_END)
-		goto error;
-
-	err = zlib_deflateEnd(&stream);
-	if (err != Z_OK)
-		goto error;
-
-	if (stream.total_out >= stream.total_in)
-		goto error;
-
-	ret = stream.total_out;
-error:
-	return ret;
-}
-
-/* Compress the text from big_oops_buf into oops_buf. */
-static int zip_oops(size_t text_len)
-{
-	int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
-								oops_data_sz);
-	if (zipped_len < 0) {
-		pr_err("nvram: compression failed; returned %d\n", zipped_len);
-		pr_err("nvram: logging uncompressed oops/panic report\n");
-		return -1;
-	}
-	*oops_len = (u16) zipped_len;
-	return 0;
-}
 
 /*
  * This is our kmsg_dump callback, called after an oops or panic report
@@ -576,6 +912,7 @@ static int zip_oops(size_t text_len)
 static void oops_to_nvram(struct kmsg_dumper *dumper,
 			  enum kmsg_dump_reason reason)
 {
+	struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
 	static unsigned int oops_count = 0;
 	static bool panicking = false;
 	static DEFINE_SPINLOCK(lock);
@@ -619,14 +956,17 @@ static void oops_to_nvram(struct kmsg_du
 	}
 	if (rc != 0) {
 		kmsg_dump_rewind(dumper);
-		kmsg_dump_get_buffer(dumper, true,
+		kmsg_dump_get_buffer(dumper, false,
 				     oops_data, oops_data_sz, &text_len);
 		err_type = ERR_TYPE_KERNEL_PANIC;
-		*oops_len = (u16) text_len;
+		oops_hdr->version = OOPS_HDR_VERSION;
+		oops_hdr->report_length = (u16) text_len;
+		oops_hdr->timestamp = get_seconds();
 	}
 
 	(void) nvram_write_os_partition(&oops_log_partition, oops_buf,
-		(int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count);
+		(int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type,
+		++oops_count);
 
 	spin_unlock_irqrestore(&lock, flags);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/pci_dlpar.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/pci_dlpar.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/pci_dlpar.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/pci_dlpar.c	2013-08-25 20:43:22.000000000 -0400
@@ -64,91 +64,6 @@ pcibios_find_pci_bus(struct device_node
 }
 EXPORT_SYMBOL_GPL(pcibios_find_pci_bus);
 
-/**
- * __pcibios_remove_pci_devices - remove all devices under this bus
- * @bus: the indicated PCI bus
- * @purge_pe: destroy the PE on removal of PCI devices
- *
- * Remove all of the PCI devices under this bus both from the
- * linux pci device tree, and from the powerpc EEH address cache.
- * By default, the corresponding PE will be destroied during the
- * normal PCI hotplug path. For PCI hotplug during EEH recovery,
- * the corresponding PE won't be destroied and deallocated.
- */
-void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe)
-{
-	struct pci_dev *dev, *tmp;
-	struct pci_bus *child_bus;
-
-	/* First go down child busses */
-	list_for_each_entry(child_bus, &bus->children, node)
-		__pcibios_remove_pci_devices(child_bus, purge_pe);
-
-	pr_debug("PCI: Removing devices on bus %04x:%02x\n",
-		pci_domain_nr(bus),  bus->number);
-	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
-		pr_debug("     * Removing %s...\n", pci_name(dev));
-		eeh_remove_bus_device(dev, purge_pe);
-		pci_stop_and_remove_bus_device(dev);
-	}
-}
-
-/**
- * pcibios_remove_pci_devices - remove all devices under this bus
- *
- * Remove all of the PCI devices under this bus both from the
- * linux pci device tree, and from the powerpc EEH address cache.
- */
-void pcibios_remove_pci_devices(struct pci_bus *bus)
-{
-	__pcibios_remove_pci_devices(bus, 1);
-}
-EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
-
-/**
- * pcibios_add_pci_devices - adds new pci devices to bus
- *
- * This routine will find and fixup new pci devices under
- * the indicated bus. This routine presumes that there
- * might already be some devices under this bridge, so
- * it carefully tries to add only new devices.  (And that
- * is how this routine differs from other, similar pcibios
- * routines.)
- */
-void pcibios_add_pci_devices(struct pci_bus * bus)
-{
-	int slotno, num, mode, pass, max;
-	struct pci_dev *dev;
-	struct device_node *dn = pci_bus_to_OF_node(bus);
-
-	eeh_add_device_tree_early(dn);
-
-	mode = PCI_PROBE_NORMAL;
-	if (ppc_md.pci_probe_mode)
-		mode = ppc_md.pci_probe_mode(bus);
-
-	if (mode == PCI_PROBE_DEVTREE) {
-		/* use ofdt-based probe */
-		of_rescan_bus(dn, bus);
-	} else if (mode == PCI_PROBE_NORMAL) {
-		/* use legacy probe */
-		slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
-		num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
-		if (!num)
-			return;
-		pcibios_setup_bus_devices(bus);
-		max = bus->busn_res.start;
-		for (pass=0; pass < 2; pass++)
-			list_for_each_entry(dev, &bus->devices, bus_list) {
-			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
-			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
-				max = pci_scan_bridge(bus, dev, max, pass);
-		}
-	}
-	pcibios_finish_adding_to_bus(bus);
-}
-EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
-
 struct pci_controller *init_phb_dynamic(struct device_node *dn)
 {
 	struct pci_controller *phb;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/ras.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/ras.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/ras.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/ras.c	2013-08-25 20:43:22.000000000 -0400
@@ -83,7 +83,7 @@ static void handle_system_shutdown(char
 	switch (event_modifier) {
 	case EPOW_SHUTDOWN_NORMAL:
 		pr_emerg("Firmware initiated power off");
-		orderly_poweroff(1);
+		orderly_poweroff(true);
 		break;
 
 	case EPOW_SHUTDOWN_ON_UPS:
@@ -95,13 +95,13 @@ static void handle_system_shutdown(char
 		pr_emerg("Loss of system critical functions reported by "
 			"firmware");
 		pr_emerg("Check RTAS error log for details");
-		orderly_poweroff(1);
+		orderly_poweroff(true);
 		break;
 
 	case EPOW_SHUTDOWN_AMBIENT_TEMPERATURE_TOO_HIGH:
 		pr_emerg("Ambient temperature too high reported by firmware");
 		pr_emerg("Check RTAS error log for details");
-		orderly_poweroff(1);
+		orderly_poweroff(true);
 		break;
 
 	default:
@@ -162,7 +162,7 @@ void rtas_parse_epow_errlog(struct rtas_
 
 	case EPOW_SYSTEM_HALT:
 		pr_emerg("Firmware initiated power off");
-		orderly_poweroff(1);
+		orderly_poweroff(true);
 		break;
 
 	case EPOW_MAIN_ENCLOSURE:
@@ -287,6 +287,9 @@ static struct rtas_error_log *fwnmi_get_
 	unsigned long *savep;
 	struct rtas_error_log *h, *errhdr = NULL;
 
+	/* Mask top two bits */
+	regs->gpr[3] &= ~(0x3UL << 62);
+
 	if (!VALID_FWNMI_BUFFER(regs->gpr[3])) {
 		printk(KERN_ERR "FWNMI: corrupt r3 0x%016lx\n", regs->gpr[3]);
 		return NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/smp.c linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/smp.c
--- linux-libre-3.10-gnu/arch/powerpc/platforms/pseries/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/platforms/pseries/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -192,7 +192,7 @@ static int smp_pSeries_cpu_bootable(unsi
 	/* Special case - we inhibit secondary thread startup
 	 * during boot if the user requests it.
 	 */
-	if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) {
+	if (system_state == SYSTEM_BOOTING && cpu_has_feature(CPU_FTR_SMT)) {
 		if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
 			return 0;
 		if (smt_enabled_at_boot
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/relocs_check.pl linux-libre-3.11-rc7-gnu/arch/powerpc/relocs_check.pl
--- linux-libre-3.10-gnu/arch/powerpc/relocs_check.pl	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/relocs_check.pl	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@
 # as published by the Free Software Foundation; either version
 # 2 of the License, or (at your option) any later version.
 
-# This script checks the relcoations of a vmlinux for "suspicious"
+# This script checks the relocations of a vmlinux for "suspicious"
 # relocations.
 
 use strict;
@@ -28,7 +28,7 @@ open(FD, "$objdump -R $vmlinux|") or die
 while (<FD>) {
 	study $_;
 
-	# Only look at relcoation lines.
+	# Only look at relocation lines.
 	next if (!/\s+R_/);
 
 	# These relocations are okay
@@ -45,7 +45,7 @@ while (<FD>) {
 		 /\bR_PPC_ADDR16_HA\b/ or /\bR_PPC_RELATIVE\b/ or
 		 /\bR_PPC_NONE\b/);
 
-	# If we see this type of relcoation it's an idication that
+	# If we see this type of relocation it's an idication that
 	# we /may/ be using an old version of binutils.
 	if (/R_PPC64_UADDR64/) {
 		$old_binutils++;
@@ -61,6 +61,6 @@ if ($bad_relocs_count) {
 }
 
 if ($old_binutils) {
-	print "WARNING: You need at binutils >= 2.19 to build a ".
-	      "CONFIG_RELCOATABLE kernel\n";
+	print "WARNING: You need at least binutils >= 2.19 to build a ".
+	      "CONFIG_RELOCATABLE kernel\n";
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/sysdev/cpm1.c linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/cpm1.c
--- linux-libre-3.10-gnu/arch/powerpc/sysdev/cpm1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/cpm1.c	2013-08-25 20:43:22.000000000 -0400
@@ -120,6 +120,7 @@ static irqreturn_t cpm_error_interrupt(i
 
 static struct irqaction cpm_error_irqaction = {
 	.handler = cpm_error_interrupt,
+	.flags = IRQF_NO_THREAD,
 	.name = "error",
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c
--- linux-libre-3.10-gnu/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,161 @@
+/*
+ * MPIC timer wakeup driver
+ *
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+#include <asm/mpic_timer.h>
+#include <asm/mpic.h>
+
+struct fsl_mpic_timer_wakeup {
+	struct mpic_timer *timer;
+	struct work_struct free_work;
+};
+
+static struct fsl_mpic_timer_wakeup *fsl_wakeup;
+static DEFINE_MUTEX(sysfs_lock);
+
+static void fsl_free_resource(struct work_struct *ws)
+{
+	struct fsl_mpic_timer_wakeup *wakeup =
+		container_of(ws, struct fsl_mpic_timer_wakeup, free_work);
+
+	mutex_lock(&sysfs_lock);
+
+	if (wakeup->timer) {
+		disable_irq_wake(wakeup->timer->irq);
+		mpic_free_timer(wakeup->timer);
+	}
+
+	wakeup->timer = NULL;
+	mutex_unlock(&sysfs_lock);
+}
+
+static irqreturn_t fsl_mpic_timer_irq(int irq, void *dev_id)
+{
+	struct fsl_mpic_timer_wakeup *wakeup = dev_id;
+
+	schedule_work(&wakeup->free_work);
+
+	return wakeup->timer ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static ssize_t fsl_timer_wakeup_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct timeval interval;
+	int val = 0;
+
+	mutex_lock(&sysfs_lock);
+	if (fsl_wakeup->timer) {
+		mpic_get_remain_time(fsl_wakeup->timer, &interval);
+		val = interval.tv_sec + 1;
+	}
+	mutex_unlock(&sysfs_lock);
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t fsl_timer_wakeup_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf,
+				size_t count)
+{
+	struct timeval interval;
+	int ret;
+
+	interval.tv_usec = 0;
+	if (kstrtol(buf, 0, &interval.tv_sec))
+		return -EINVAL;
+
+	mutex_lock(&sysfs_lock);
+
+	if (fsl_wakeup->timer) {
+		disable_irq_wake(fsl_wakeup->timer->irq);
+		mpic_free_timer(fsl_wakeup->timer);
+		fsl_wakeup->timer = NULL;
+	}
+
+	if (!interval.tv_sec) {
+		mutex_unlock(&sysfs_lock);
+		return count;
+	}
+
+	fsl_wakeup->timer = mpic_request_timer(fsl_mpic_timer_irq,
+						fsl_wakeup, &interval);
+	if (!fsl_wakeup->timer) {
+		mutex_unlock(&sysfs_lock);
+		return -EINVAL;
+	}
+
+	ret = enable_irq_wake(fsl_wakeup->timer->irq);
+	if (ret) {
+		mpic_free_timer(fsl_wakeup->timer);
+		fsl_wakeup->timer = NULL;
+		mutex_unlock(&sysfs_lock);
+
+		return ret;
+	}
+
+	mpic_start_timer(fsl_wakeup->timer);
+
+	mutex_unlock(&sysfs_lock);
+
+	return count;
+}
+
+static struct device_attribute mpic_attributes = __ATTR(timer_wakeup, 0644,
+			fsl_timer_wakeup_show, fsl_timer_wakeup_store);
+
+static int __init fsl_wakeup_sys_init(void)
+{
+	int ret;
+
+	fsl_wakeup = kzalloc(sizeof(struct fsl_mpic_timer_wakeup), GFP_KERNEL);
+	if (!fsl_wakeup)
+		return -ENOMEM;
+
+	INIT_WORK(&fsl_wakeup->free_work, fsl_free_resource);
+
+	ret = device_create_file(mpic_subsys.dev_root, &mpic_attributes);
+	if (ret)
+		kfree(fsl_wakeup);
+
+	return ret;
+}
+
+static void __exit fsl_wakeup_sys_exit(void)
+{
+	device_remove_file(mpic_subsys.dev_root, &mpic_attributes);
+
+	mutex_lock(&sysfs_lock);
+
+	if (fsl_wakeup->timer) {
+		disable_irq_wake(fsl_wakeup->timer->irq);
+		mpic_free_timer(fsl_wakeup->timer);
+	}
+
+	kfree(fsl_wakeup);
+
+	mutex_unlock(&sysfs_lock);
+}
+
+module_init(fsl_wakeup_sys_init);
+module_exit(fsl_wakeup_sys_exit);
+
+MODULE_DESCRIPTION("Freescale MPIC global timer wakeup driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Wang Dongsheng <dongsheng.wang@freescale.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/sysdev/Makefile linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/Makefile
--- linux-libre-3.10-gnu/arch/powerpc/sysdev/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -4,6 +4,8 @@ ccflags-$(CONFIG_PPC64)		:= $(NO_MINIMAL
 
 mpic-msi-obj-$(CONFIG_PCI_MSI)	+= mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
 obj-$(CONFIG_MPIC)		+= mpic.o $(mpic-msi-obj-y)
+obj-$(CONFIG_MPIC_TIMER)        += mpic_timer.o
+obj-$(CONFIG_FSL_MPIC_TIMER_WAKEUP)	+= fsl_mpic_timer_wakeup.o
 mpic-msgr-obj-$(CONFIG_MPIC_MSGR)	+= mpic_msgr.o
 obj-$(CONFIG_MPIC)		+= mpic.o $(mpic-msi-obj-y) $(mpic-msgr-obj-y)
 obj-$(CONFIG_PPC_EPAPR_HV_PIC)	+= ehv_pic.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/sysdev/mpic.c linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/mpic.c
--- linux-libre-3.10-gnu/arch/powerpc/sysdev/mpic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/mpic.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,6 +48,12 @@
 #define DBG(fmt...)
 #endif
 
+struct bus_type mpic_subsys = {
+	.name = "mpic",
+	.dev_name = "mpic",
+};
+EXPORT_SYMBOL_GPL(mpic_subsys);
+
 static struct mpic *mpics;
 static struct mpic *mpic_primary;
 static DEFINE_RAW_SPINLOCK(mpic_lock);
@@ -920,6 +926,22 @@ int mpic_set_irq_type(struct irq_data *d
 	return IRQ_SET_MASK_OK_NOCOPY;
 }
 
+static int mpic_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+	struct irq_desc *desc = container_of(d, struct irq_desc, irq_data);
+	struct mpic *mpic = mpic_from_irq_data(d);
+
+	if (!(mpic->flags & MPIC_FSL))
+		return -ENXIO;
+
+	if (on)
+		desc->action->flags |= IRQF_NO_SUSPEND;
+	else
+		desc->action->flags &= ~IRQF_NO_SUSPEND;
+
+	return 0;
+}
+
 void mpic_set_vector(unsigned int virq, unsigned int vector)
 {
 	struct mpic *mpic = mpic_from_irq(virq);
@@ -957,6 +979,7 @@ static struct irq_chip mpic_irq_chip = {
 	.irq_unmask	= mpic_unmask_irq,
 	.irq_eoi	= mpic_end_irq,
 	.irq_set_type	= mpic_set_irq_type,
+	.irq_set_wake	= mpic_irq_set_wake,
 };
 
 #ifdef CONFIG_SMP
@@ -971,6 +994,7 @@ static struct irq_chip mpic_tm_chip = {
 	.irq_mask	= mpic_mask_tm,
 	.irq_unmask	= mpic_unmask_tm,
 	.irq_eoi	= mpic_end_irq,
+	.irq_set_wake	= mpic_irq_set_wake,
 };
 
 #ifdef CONFIG_MPIC_U3_HT_IRQS
@@ -1173,10 +1197,33 @@ static struct irq_domain_ops mpic_host_o
 	.xlate = mpic_host_xlate,
 };
 
+static u32 fsl_mpic_get_version(struct mpic *mpic)
+{
+	u32 brr1;
+
+	if (!(mpic->flags & MPIC_FSL))
+		return 0;
+
+	brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
+			MPIC_FSL_BRR1);
+
+	return brr1 & MPIC_FSL_BRR1_VER;
+}
+
 /*
  * Exported functions
  */
 
+u32 fsl_mpic_primary_get_version(void)
+{
+	struct mpic *mpic = mpic_primary;
+
+	if (mpic)
+		return fsl_mpic_get_version(mpic);
+
+	return 0;
+}
+
 struct mpic * __init mpic_alloc(struct device_node *node,
 				phys_addr_t phys_addr,
 				unsigned int flags,
@@ -1323,7 +1370,6 @@ struct mpic * __init mpic_alloc(struct d
 	mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
 
 	if (mpic->flags & MPIC_FSL) {
-		u32 brr1;
 		int ret;
 
 		/*
@@ -1334,9 +1380,7 @@ struct mpic * __init mpic_alloc(struct d
 		mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
 			 MPIC_CPU_THISBASE, 0x1000);
 
-		brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
-				MPIC_FSL_BRR1);
-		fsl_version = brr1 & MPIC_FSL_BRR1_VER;
+		fsl_version = fsl_mpic_get_version(mpic);
 
 		/* Error interrupt mask register (EIMR) is required for
 		 * handling individual device error interrupts. EIMR
@@ -1526,9 +1570,7 @@ void __init mpic_init(struct mpic *mpic)
 	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
 
 	if (mpic->flags & MPIC_FSL) {
-		u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
-				      MPIC_FSL_BRR1);
-		u32 version = brr1 & MPIC_FSL_BRR1_VER;
+		u32 version = fsl_mpic_get_version(mpic);
 
 		/*
 		 * Timer group B is present at the latest in MPIC 3.1 (e.g.
@@ -1999,6 +2041,8 @@ static struct syscore_ops mpic_syscore_o
 static int mpic_init_sys(void)
 {
 	register_syscore_ops(&mpic_syscore_ops);
+	subsys_system_register(&mpic_subsys, NULL);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/powerpc/sysdev/mpic_timer.c linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/mpic_timer.c
--- linux-libre-3.10-gnu/arch/powerpc/sysdev/mpic_timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/powerpc/sysdev/mpic_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,593 @@
+/*
+ * MPIC timer driver
+ *
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ * Author: Dongsheng Wang <Dongsheng.Wang@freescale.com>
+ *	   Li Yang <leoli@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/syscore_ops.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/io.h>
+
+#include <asm/mpic_timer.h>
+
+#define FSL_GLOBAL_TIMER		0x1
+
+/* Clock Ratio
+ * Divide by 64 0x00000300
+ * Divide by 32 0x00000200
+ * Divide by 16 0x00000100
+ * Divide by  8 0x00000000 (Hardware default div)
+ */
+#define MPIC_TIMER_TCR_CLKDIV		0x00000300
+
+#define MPIC_TIMER_TCR_ROVR_OFFSET	24
+
+#define TIMER_STOP			0x80000000
+#define TIMERS_PER_GROUP		4
+#define MAX_TICKS			(~0U >> 1)
+#define MAX_TICKS_CASCADE		(~0U)
+#define TIMER_OFFSET(num)		(1 << (TIMERS_PER_GROUP - 1 - num))
+
+/* tv_usec should be less than ONE_SECOND, otherwise use tv_sec */
+#define ONE_SECOND			1000000
+
+struct timer_regs {
+	u32	gtccr;
+	u32	res0[3];
+	u32	gtbcr;
+	u32	res1[3];
+	u32	gtvpr;
+	u32	res2[3];
+	u32	gtdr;
+	u32	res3[3];
+};
+
+struct cascade_priv {
+	u32 tcr_value;			/* TCR register: CASC & ROVR value */
+	unsigned int cascade_map;	/* cascade map */
+	unsigned int timer_num;		/* cascade control timer */
+};
+
+struct timer_group_priv {
+	struct timer_regs __iomem	*regs;
+	struct mpic_timer		timer[TIMERS_PER_GROUP];
+	struct list_head		node;
+	unsigned int			timerfreq;
+	unsigned int			idle;
+	unsigned int			flags;
+	spinlock_t			lock;
+	void __iomem			*group_tcr;
+};
+
+static struct cascade_priv cascade_timer[] = {
+	/* cascade timer 0 and 1 */
+	{0x1, 0xc, 0x1},
+	/* cascade timer 1 and 2 */
+	{0x2, 0x6, 0x2},
+	/* cascade timer 2 and 3 */
+	{0x4, 0x3, 0x3}
+};
+
+static LIST_HEAD(timer_group_list);
+
+static void convert_ticks_to_time(struct timer_group_priv *priv,
+		const u64 ticks, struct timeval *time)
+{
+	u64 tmp_sec;
+
+	time->tv_sec = (__kernel_time_t)div_u64(ticks, priv->timerfreq);
+	tmp_sec = (u64)time->tv_sec * (u64)priv->timerfreq;
+
+	time->tv_usec = (__kernel_suseconds_t)
+		div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq);
+
+	return;
+}
+
+/* the time set by the user is converted to "ticks" */
+static int convert_time_to_ticks(struct timer_group_priv *priv,
+		const struct timeval *time, u64 *ticks)
+{
+	u64 max_value;		/* prevent u64 overflow */
+	u64 tmp = 0;
+
+	u64 tmp_sec;
+	u64 tmp_ms;
+	u64 tmp_us;
+
+	max_value = div_u64(ULLONG_MAX, priv->timerfreq);
+
+	if (time->tv_sec > max_value ||
+			(time->tv_sec == max_value && time->tv_usec > 0))
+		return -EINVAL;
+
+	tmp_sec = (u64)time->tv_sec * (u64)priv->timerfreq;
+	tmp += tmp_sec;
+
+	tmp_ms = time->tv_usec / 1000;
+	tmp_ms = div_u64((u64)tmp_ms * (u64)priv->timerfreq, 1000);
+	tmp += tmp_ms;
+
+	tmp_us = time->tv_usec % 1000;
+	tmp_us = div_u64((u64)tmp_us * (u64)priv->timerfreq, 1000000);
+	tmp += tmp_us;
+
+	*ticks = tmp;
+
+	return 0;
+}
+
+/* detect whether there is a cascade timer available */
+static struct mpic_timer *detect_idle_cascade_timer(
+					struct timer_group_priv *priv)
+{
+	struct cascade_priv *casc_priv;
+	unsigned int map;
+	unsigned int array_size = ARRAY_SIZE(cascade_timer);
+	unsigned int num;
+	unsigned int i;
+	unsigned long flags;
+
+	casc_priv = cascade_timer;
+	for (i = 0; i < array_size; i++) {
+		spin_lock_irqsave(&priv->lock, flags);
+		map = casc_priv->cascade_map & priv->idle;
+		if (map == casc_priv->cascade_map) {
+			num = casc_priv->timer_num;
+			priv->timer[num].cascade_handle = casc_priv;
+
+			/* set timer busy */
+			priv->idle &= ~casc_priv->cascade_map;
+			spin_unlock_irqrestore(&priv->lock, flags);
+			return &priv->timer[num];
+		}
+		spin_unlock_irqrestore(&priv->lock, flags);
+		casc_priv++;
+	}
+
+	return NULL;
+}
+
+static int set_cascade_timer(struct timer_group_priv *priv, u64 ticks,
+		unsigned int num)
+{
+	struct cascade_priv *casc_priv;
+	u32 tcr;
+	u32 tmp_ticks;
+	u32 rem_ticks;
+
+	/* set group tcr reg for cascade */
+	casc_priv = priv->timer[num].cascade_handle;
+	if (!casc_priv)
+		return -EINVAL;
+
+	tcr = casc_priv->tcr_value |
+		(casc_priv->tcr_value << MPIC_TIMER_TCR_ROVR_OFFSET);
+	setbits32(priv->group_tcr, tcr);
+
+	tmp_ticks = div_u64_rem(ticks, MAX_TICKS_CASCADE, &rem_ticks);
+
+	out_be32(&priv->regs[num].gtccr, 0);
+	out_be32(&priv->regs[num].gtbcr, tmp_ticks | TIMER_STOP);
+
+	out_be32(&priv->regs[num - 1].gtccr, 0);
+	out_be32(&priv->regs[num - 1].gtbcr, rem_ticks);
+
+	return 0;
+}
+
+static struct mpic_timer *get_cascade_timer(struct timer_group_priv *priv,
+					u64 ticks)
+{
+	struct mpic_timer *allocated_timer;
+
+	/* Two cascade timers: Support the maximum time */
+	const u64 max_ticks = (u64)MAX_TICKS * (u64)MAX_TICKS_CASCADE;
+	int ret;
+
+	if (ticks > max_ticks)
+		return NULL;
+
+	/* detect idle timer */
+	allocated_timer = detect_idle_cascade_timer(priv);
+	if (!allocated_timer)
+		return NULL;
+
+	/* set ticks to timer */
+	ret = set_cascade_timer(priv, ticks, allocated_timer->num);
+	if (ret < 0)
+		return NULL;
+
+	return allocated_timer;
+}
+
+static struct mpic_timer *get_timer(const struct timeval *time)
+{
+	struct timer_group_priv *priv;
+	struct mpic_timer *timer;
+
+	u64 ticks;
+	unsigned int num;
+	unsigned int i;
+	unsigned long flags;
+	int ret;
+
+	list_for_each_entry(priv, &timer_group_list, node) {
+		ret = convert_time_to_ticks(priv, time, &ticks);
+		if (ret < 0)
+			return NULL;
+
+		if (ticks > MAX_TICKS) {
+			if (!(priv->flags & FSL_GLOBAL_TIMER))
+				return NULL;
+
+			timer = get_cascade_timer(priv, ticks);
+			if (!timer)
+				continue;
+
+			return timer;
+		}
+
+		for (i = 0; i < TIMERS_PER_GROUP; i++) {
+			/* one timer: Reverse allocation */
+			num = TIMERS_PER_GROUP - 1 - i;
+			spin_lock_irqsave(&priv->lock, flags);
+			if (priv->idle & (1 << i)) {
+				/* set timer busy */
+				priv->idle &= ~(1 << i);
+				/* set ticks & stop timer */
+				out_be32(&priv->regs[num].gtbcr,
+					ticks | TIMER_STOP);
+				out_be32(&priv->regs[num].gtccr, 0);
+				priv->timer[num].cascade_handle = NULL;
+				spin_unlock_irqrestore(&priv->lock, flags);
+				return &priv->timer[num];
+			}
+			spin_unlock_irqrestore(&priv->lock, flags);
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * mpic_start_timer - start hardware timer
+ * @handle: the timer to be started.
+ *
+ * It will do ->fn(->dev) callback from the hardware interrupt at
+ * the ->timeval point in the future.
+ */
+void mpic_start_timer(struct mpic_timer *handle)
+{
+	struct timer_group_priv *priv = container_of(handle,
+			struct timer_group_priv, timer[handle->num]);
+
+	clrbits32(&priv->regs[handle->num].gtbcr, TIMER_STOP);
+}
+EXPORT_SYMBOL(mpic_start_timer);
+
+/**
+ * mpic_stop_timer - stop hardware timer
+ * @handle: the timer to be stoped
+ *
+ * The timer periodically generates an interrupt. Unless user stops the timer.
+ */
+void mpic_stop_timer(struct mpic_timer *handle)
+{
+	struct timer_group_priv *priv = container_of(handle,
+			struct timer_group_priv, timer[handle->num]);
+	struct cascade_priv *casc_priv;
+
+	setbits32(&priv->regs[handle->num].gtbcr, TIMER_STOP);
+
+	casc_priv = priv->timer[handle->num].cascade_handle;
+	if (casc_priv) {
+		out_be32(&priv->regs[handle->num].gtccr, 0);
+		out_be32(&priv->regs[handle->num - 1].gtccr, 0);
+	} else {
+		out_be32(&priv->regs[handle->num].gtccr, 0);
+	}
+}
+EXPORT_SYMBOL(mpic_stop_timer);
+
+/**
+ * mpic_get_remain_time - get timer time
+ * @handle: the timer to be selected.
+ * @time: time for timer
+ *
+ * Query timer remaining time.
+ */
+void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time)
+{
+	struct timer_group_priv *priv = container_of(handle,
+			struct timer_group_priv, timer[handle->num]);
+	struct cascade_priv *casc_priv;
+
+	u64 ticks;
+	u32 tmp_ticks;
+
+	casc_priv = priv->timer[handle->num].cascade_handle;
+	if (casc_priv) {
+		tmp_ticks = in_be32(&priv->regs[handle->num].gtccr);
+		ticks = ((u64)tmp_ticks & UINT_MAX) * (u64)MAX_TICKS_CASCADE;
+		tmp_ticks = in_be32(&priv->regs[handle->num - 1].gtccr);
+		ticks += tmp_ticks;
+	} else {
+		ticks = in_be32(&priv->regs[handle->num].gtccr);
+	}
+
+	convert_ticks_to_time(priv, ticks, time);
+}
+EXPORT_SYMBOL(mpic_get_remain_time);
+
+/**
+ * mpic_free_timer - free hardware timer
+ * @handle: the timer to be removed.
+ *
+ * Free the timer.
+ *
+ * Note: can not be used in interrupt context.
+ */
+void mpic_free_timer(struct mpic_timer *handle)
+{
+	struct timer_group_priv *priv = container_of(handle,
+			struct timer_group_priv, timer[handle->num]);
+
+	struct cascade_priv *casc_priv;
+	unsigned long flags;
+
+	mpic_stop_timer(handle);
+
+	casc_priv = priv->timer[handle->num].cascade_handle;
+
+	free_irq(priv->timer[handle->num].irq, priv->timer[handle->num].dev);
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (casc_priv) {
+		u32 tcr;
+		tcr = casc_priv->tcr_value | (casc_priv->tcr_value <<
+					MPIC_TIMER_TCR_ROVR_OFFSET);
+		clrbits32(priv->group_tcr, tcr);
+		priv->idle |= casc_priv->cascade_map;
+		priv->timer[handle->num].cascade_handle = NULL;
+	} else {
+		priv->idle |= TIMER_OFFSET(handle->num);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+EXPORT_SYMBOL(mpic_free_timer);
+
+/**
+ * mpic_request_timer - get a hardware timer
+ * @fn: interrupt handler function
+ * @dev: callback function of the data
+ * @time: time for timer
+ *
+ * This executes the "request_irq", returning NULL
+ * else "handle" on success.
+ */
+struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev,
+					const struct timeval *time)
+{
+	struct mpic_timer *allocated_timer;
+	int ret;
+
+	if (list_empty(&timer_group_list))
+		return NULL;
+
+	if (!(time->tv_sec + time->tv_usec) ||
+			time->tv_sec < 0 || time->tv_usec < 0)
+		return NULL;
+
+	if (time->tv_usec > ONE_SECOND)
+		return NULL;
+
+	allocated_timer = get_timer(time);
+	if (!allocated_timer)
+		return NULL;
+
+	ret = request_irq(allocated_timer->irq, fn,
+			IRQF_TRIGGER_LOW, "global-timer", dev);
+	if (ret) {
+		mpic_free_timer(allocated_timer);
+		return NULL;
+	}
+
+	allocated_timer->dev = dev;
+
+	return allocated_timer;
+}
+EXPORT_SYMBOL(mpic_request_timer);
+
+static int timer_group_get_freq(struct device_node *np,
+			struct timer_group_priv *priv)
+{
+	u32 div;
+
+	if (priv->flags & FSL_GLOBAL_TIMER) {
+		struct device_node *dn;
+
+		dn = of_find_compatible_node(NULL, NULL, "fsl,mpic");
+		if (dn) {
+			of_property_read_u32(dn, "clock-frequency",
+					&priv->timerfreq);
+			of_node_put(dn);
+		}
+	}
+
+	if (priv->timerfreq <= 0)
+		return -EINVAL;
+
+	if (priv->flags & FSL_GLOBAL_TIMER) {
+		div = (1 << (MPIC_TIMER_TCR_CLKDIV >> 8)) * 8;
+		priv->timerfreq /= div;
+	}
+
+	return 0;
+}
+
+static int timer_group_get_irq(struct device_node *np,
+		struct timer_group_priv *priv)
+{
+	const u32 all_timer[] = { 0, TIMERS_PER_GROUP };
+	const u32 *p;
+	u32 offset;
+	u32 count;
+
+	unsigned int i;
+	unsigned int j;
+	unsigned int irq_index = 0;
+	unsigned int irq;
+	int len;
+
+	p = of_get_property(np, "fsl,available-ranges", &len);
+	if (p && len % (2 * sizeof(u32)) != 0) {
+		pr_err("%s: malformed available-ranges property.\n",
+				np->full_name);
+		return -EINVAL;
+	}
+
+	if (!p) {
+		p = all_timer;
+		len = sizeof(all_timer);
+	}
+
+	len /= 2 * sizeof(u32);
+
+	for (i = 0; i < len; i++) {
+		offset = p[i * 2];
+		count = p[i * 2 + 1];
+		for (j = 0; j < count; j++) {
+			irq = irq_of_parse_and_map(np, irq_index);
+			if (!irq) {
+				pr_err("%s: irq parse and map failed.\n",
+						np->full_name);
+				return -EINVAL;
+			}
+
+			/* Set timer idle */
+			priv->idle |= TIMER_OFFSET((offset + j));
+			priv->timer[offset + j].irq = irq;
+			priv->timer[offset + j].num = offset + j;
+			irq_index++;
+		}
+	}
+
+	return 0;
+}
+
+static void timer_group_init(struct device_node *np)
+{
+	struct timer_group_priv *priv;
+	unsigned int i = 0;
+	int ret;
+
+	priv = kzalloc(sizeof(struct timer_group_priv), GFP_KERNEL);
+	if (!priv) {
+		pr_err("%s: cannot allocate memory for group.\n",
+				np->full_name);
+		return;
+	}
+
+	if (of_device_is_compatible(np, "fsl,mpic-global-timer"))
+		priv->flags |= FSL_GLOBAL_TIMER;
+
+	priv->regs = of_iomap(np, i++);
+	if (!priv->regs) {
+		pr_err("%s: cannot ioremap timer register address.\n",
+				np->full_name);
+		goto out;
+	}
+
+	if (priv->flags & FSL_GLOBAL_TIMER) {
+		priv->group_tcr = of_iomap(np, i++);
+		if (!priv->group_tcr) {
+			pr_err("%s: cannot ioremap tcr address.\n",
+					np->full_name);
+			goto out;
+		}
+	}
+
+	ret = timer_group_get_freq(np, priv);
+	if (ret < 0) {
+		pr_err("%s: cannot get timer frequency.\n", np->full_name);
+		goto out;
+	}
+
+	ret = timer_group_get_irq(np, priv);
+	if (ret < 0) {
+		pr_err("%s: cannot get timer irqs.\n", np->full_name);
+		goto out;
+	}
+
+	spin_lock_init(&priv->lock);
+
+	/* Init FSL timer hardware */
+	if (priv->flags & FSL_GLOBAL_TIMER)
+		setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
+
+	list_add_tail(&priv->node, &timer_group_list);
+
+	return;
+
+out:
+	if (priv->regs)
+		iounmap(priv->regs);
+
+	if (priv->group_tcr)
+		iounmap(priv->group_tcr);
+
+	kfree(priv);
+}
+
+static void mpic_timer_resume(void)
+{
+	struct timer_group_priv *priv;
+
+	list_for_each_entry(priv, &timer_group_list, node) {
+		/* Init FSL timer hardware */
+		if (priv->flags & FSL_GLOBAL_TIMER)
+			setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);
+	}
+}
+
+static const struct of_device_id mpic_timer_ids[] = {
+	{ .compatible = "fsl,mpic-global-timer", },
+	{},
+};
+
+static struct syscore_ops mpic_timer_syscore_ops = {
+	.resume = mpic_timer_resume,
+};
+
+static int __init mpic_timer_init(void)
+{
+	struct device_node *np = NULL;
+
+	for_each_matching_node(np, mpic_timer_ids)
+		timer_group_init(np);
+
+	register_syscore_ops(&mpic_timer_syscore_ops);
+
+	if (list_empty(&timer_group_list))
+		return -ENODEV;
+
+	return 0;
+}
+subsys_initcall(mpic_timer_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/appldata/appldata_mem.c linux-libre-3.11-rc7-gnu/arch/s390/appldata/appldata_mem.c
--- linux-libre-3.10-gnu/arch/s390/appldata/appldata_mem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/appldata/appldata_mem.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,7 @@
  * book:
  * http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml
  */
-static struct appldata_mem_data {
+struct appldata_mem_data {
 	u64 timestamp;
 	u32 sync_count_1;       /* after VM collected the record data, */
 	u32 sync_count_2;	/* sync_count_1 and sync_count_2 should be the
@@ -63,7 +63,7 @@ static struct appldata_mem_data {
 	u64 pgmajfault;		/* page faults (major only) */
 // <-- New in 2.6
 
-} __attribute__((packed)) appldata_mem_data;
+} __packed;
 
 
 /*
@@ -118,7 +118,6 @@ static struct appldata_ops ops = {
 	.record_nr = APPLDATA_RECORD_MEM_ID,
 	.size	   = sizeof(struct appldata_mem_data),
 	.callback  = &appldata_get_mem_data,
-	.data      = &appldata_mem_data,
 	.owner     = THIS_MODULE,
 	.mod_lvl   = {0xF0, 0xF0},		/* EBCDIC "00" */
 };
@@ -131,7 +130,17 @@ static struct appldata_ops ops = {
  */
 static int __init appldata_mem_init(void)
 {
-	return appldata_register_ops(&ops);
+	int ret;
+
+	ops.data = kzalloc(sizeof(struct appldata_mem_data), GFP_KERNEL);
+	if (!ops.data)
+		return -ENOMEM;
+
+	ret = appldata_register_ops(&ops);
+	if (ret)
+		kfree(ops.data);
+
+	return ret;
 }
 
 /*
@@ -142,6 +151,7 @@ static int __init appldata_mem_init(void
 static void __exit appldata_mem_exit(void)
 {
 	appldata_unregister_ops(&ops);
+	kfree(ops.data);
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/appldata/appldata_net_sum.c linux-libre-3.11-rc7-gnu/arch/s390/appldata/appldata_net_sum.c
--- linux-libre-3.10-gnu/arch/s390/appldata/appldata_net_sum.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/appldata/appldata_net_sum.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,7 @@
  * book:
  * http://oss.software.ibm.com/developerworks/opensource/linux390/index.shtml
  */
-static struct appldata_net_sum_data {
+struct appldata_net_sum_data {
 	u64 timestamp;
 	u32 sync_count_1;	/* after VM collected the record data, */
 	u32 sync_count_2;	/* sync_count_1 and sync_count_2 should be the
@@ -51,7 +51,7 @@ static struct appldata_net_sum_data {
 	u64 rx_dropped;		/* no space in linux buffers     */
 	u64 tx_dropped;		/* no space available in linux   */
 	u64 collisions;		/* collisions while transmitting */
-} __attribute__((packed)) appldata_net_sum_data;
+} __packed;
 
 
 /*
@@ -121,7 +121,6 @@ static struct appldata_ops ops = {
 	.record_nr = APPLDATA_RECORD_NET_SUM_ID,
 	.size	   = sizeof(struct appldata_net_sum_data),
 	.callback  = &appldata_get_net_sum_data,
-	.data      = &appldata_net_sum_data,
 	.owner     = THIS_MODULE,
 	.mod_lvl   = {0xF0, 0xF0},		/* EBCDIC "00" */
 };
@@ -134,7 +133,17 @@ static struct appldata_ops ops = {
  */
 static int __init appldata_net_init(void)
 {
-	return appldata_register_ops(&ops);
+	int ret;
+
+	ops.data = kzalloc(sizeof(struct appldata_net_sum_data), GFP_KERNEL);
+	if (!ops.data)
+		return -ENOMEM;
+
+	ret = appldata_register_ops(&ops);
+	if (ret)
+		kfree(ops.data);
+
+	return ret;
 }
 
 /*
@@ -145,6 +154,7 @@ static int __init appldata_net_init(void
 static void __exit appldata_net_exit(void)
 {
 	appldata_unregister_ops(&ops);
+	kfree(ops.data);
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/boot/compressed/Makefile linux-libre-3.11-rc7-gnu/arch/s390/boot/compressed/Makefile
--- linux-libre-3.10-gnu/arch/s390/boot/compressed/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/boot/compressed/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -6,9 +6,9 @@
 
 BITS := $(if $(CONFIG_64BIT),64,31)
 
-targets	:= vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
-	   vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo misc.o piggy.o \
-	   sizes.h head$(BITS).o
+targets	:= vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
+targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
+targets += misc.o piggy.o sizes.h head$(BITS).o
 
 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
@@ -48,6 +48,7 @@ vmlinux.bin.all-y := $(obj)/vmlinux.bin
 
 suffix-$(CONFIG_KERNEL_GZIP)  := gz
 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+suffix-$(CONFIG_KERNEL_LZ4)  := lz4
 suffix-$(CONFIG_KERNEL_LZMA)  := lzma
 suffix-$(CONFIG_KERNEL_LZO)  := lzo
 suffix-$(CONFIG_KERNEL_XZ)  := xz
@@ -56,6 +57,8 @@ $(obj)/vmlinux.bin.gz: $(vmlinux.bin.all
 	$(call if_changed,gzip)
 $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
 	$(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y)
+	$(call if_changed,lz4)
 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
 	$(call if_changed,lzma)
 $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/boot/compressed/misc.c linux-libre-3.11-rc7-gnu/arch/s390/boot/compressed/misc.c
--- linux-libre-3.10-gnu/arch/s390/boot/compressed/misc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/boot/compressed/misc.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,6 +47,10 @@ static unsigned long free_mem_end_ptr;
 #include "../../../../lib/decompress_bunzip2.c"
 #endif
 
+#ifdef CONFIG_KERNEL_LZ4
+#include "../../../../lib/decompress_unlz4.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZMA
 #include "../../../../lib/decompress_unlzma.c"
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/hypfs/hypfs_diag.c linux-libre-3.11-rc7-gnu/arch/s390/hypfs/hypfs_diag.c
--- linux-libre-3.10-gnu/arch/s390/hypfs/hypfs_diag.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/hypfs/hypfs_diag.c	2013-08-25 20:43:22.000000000 -0400
@@ -651,9 +651,7 @@ static int hypfs_create_cpu_files(struct
 	}
 	diag224_idx2name(cpu_info__ctidx(diag204_info_type, cpu_info), buffer);
 	rc = hypfs_create_str(sb, cpu_dir, "type", buffer);
-	if (IS_ERR(rc))
-		return PTR_ERR(rc);
-	return 0;
+	return PTR_RET(rc);
 }
 
 static void *hypfs_create_lpar_files(struct super_block *sb,
@@ -702,9 +700,7 @@ static int hypfs_create_phys_cpu_files(s
 		return PTR_ERR(rc);
 	diag224_idx2name(phys_cpu__ctidx(diag204_info_type, cpu_info), buffer);
 	rc = hypfs_create_str(sb, cpu_dir, "type", buffer);
-	if (IS_ERR(rc))
-		return PTR_ERR(rc);
-	return 0;
+	return PTR_RET(rc);
 }
 
 static void *hypfs_create_phys_files(struct super_block *sb,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/airq.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/airq.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/airq.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/airq.h	2013-08-25 20:43:22.000000000 -0400
@@ -9,9 +9,18 @@
 #ifndef _ASM_S390_AIRQ_H
 #define _ASM_S390_AIRQ_H
 
-typedef void (*adapter_int_handler_t)(void *, void *);
+struct airq_struct {
+	struct hlist_node list;		/* Handler queueing. */
+	void (*handler)(struct airq_struct *);	/* Thin-interrupt handler */
+	u8 *lsi_ptr;			/* Local-Summary-Indicator pointer */
+	u8 lsi_mask;			/* Local-Summary-Indicator mask */
+	u8 isc;				/* Interrupt-subclass */
+	u8 flags;
+};
 
-void *s390_register_adapter_interrupt(adapter_int_handler_t, void *, u8);
-void s390_unregister_adapter_interrupt(void *, u8);
+#define AIRQ_PTR_ALLOCATED	0x01
+
+int register_adapter_interrupt(struct airq_struct *airq);
+void unregister_adapter_interrupt(struct airq_struct *airq);
 
 #endif /* _ASM_S390_AIRQ_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/bitops.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/bitops.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/bitops.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/bitops.h	2013-08-25 20:43:22.000000000 -0400
@@ -693,7 +693,7 @@ static inline int find_next_bit_left(con
 	size -= offset;
 	p = addr + offset / BITS_PER_LONG;
 	if (bit) {
-		set = __flo_word(0, *p & (~0UL << bit));
+		set = __flo_word(0, *p & (~0UL >> bit));
 		if (set >= size)
 			return size + offset;
 		if (set < BITS_PER_LONG)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/dma-mapping.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/dma-mapping.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/dma-mapping.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/dma-mapping.h	2013-08-25 20:43:22.000000000 -0400
@@ -53,7 +53,7 @@ static inline int dma_mapping_error(stru
 	debug_dma_mapping_error(dev, dma_addr);
 	if (dma_ops->mapping_error)
 		return dma_ops->mapping_error(dev, dma_addr);
-	return (dma_addr == DMA_ERROR_CODE);
+	return dma_addr == DMA_ERROR_CODE;
 }
 
 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/facility.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/facility.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/facility.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/facility.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,16 @@
 
 #define MAX_FACILITY_BIT (256*8)	/* stfle_fac_list has 256 bytes */
 
+static inline int __test_facility(unsigned long nr, void *facilities)
+{
+	unsigned char *ptr;
+
+	if (nr >= MAX_FACILITY_BIT)
+		return 0;
+	ptr = (unsigned char *) facilities + (nr >> 3);
+	return (*ptr & (0x80 >> (nr & 7))) != 0;
+}
+
 /*
  * The test_facility function uses the bit odering where the MSB is bit 0.
  * That makes it easier to query facility bits with the bit number as
@@ -20,12 +30,7 @@
  */
 static inline int test_facility(unsigned long nr)
 {
-	unsigned char *ptr;
-
-	if (nr >= MAX_FACILITY_BIT)
-		return 0;
-	ptr = (unsigned char *) &S390_lowcore.stfle_fac_list + (nr >> 3);
-	return (*ptr & (0x80 >> (nr & 7))) != 0;
+	return __test_facility(nr, &S390_lowcore.stfle_fac_list);
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/io.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/io.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/io.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/io.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,28 +13,6 @@
 #include <asm/page.h>
 #include <asm/pci_io.h>
 
-/*
- * Change virtual addresses to physical addresses and vv.
- * These are pretty trivial
- */
-static inline unsigned long virt_to_phys(volatile void * address)
-{
-	unsigned long real_address;
-	asm volatile(
-		 "	lra	%0,0(%1)\n"
-		 "	jz	0f\n"
-		 "	la	%0,0\n"
-		 "0:"
-		 : "=a" (real_address) : "a" (address) : "cc");
-	return real_address;
-}
-#define virt_to_phys virt_to_phys
-
-static inline void * phys_to_virt(unsigned long address)
-{
-	return (void *) address;
-}
-
 void *xlate_dev_mem_ptr(unsigned long phys);
 #define xlate_dev_mem_ptr xlate_dev_mem_ptr
 void unxlate_dev_mem_ptr(unsigned long phys, void *addr);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/kvm_host.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/kvm_host.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/kvm_host.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/kvm_host.h	2013-08-25 20:43:22.000000000 -0400
@@ -62,13 +62,20 @@ struct sca_block {
 #define CPUSTAT_MCDS       0x00000100
 #define CPUSTAT_SM         0x00000080
 #define CPUSTAT_G          0x00000008
+#define CPUSTAT_GED        0x00000004
 #define CPUSTAT_J          0x00000002
 #define CPUSTAT_P          0x00000001
 
 struct kvm_s390_sie_block {
 	atomic_t cpuflags;		/* 0x0000 */
 	__u32	prefix;			/* 0x0004 */
-	__u8	reserved8[32];		/* 0x0008 */
+	__u8	reserved08[4];		/* 0x0008 */
+#define PROG_IN_SIE (1<<0)
+	__u32	prog0c;			/* 0x000c */
+	__u8	reserved10[16];		/* 0x0010 */
+#define PROG_BLOCK_SIE 0x00000001
+	atomic_t prog20;		/* 0x0020 */
+	__u8	reserved24[4];		/* 0x0024 */
 	__u64	cputm;			/* 0x0028 */
 	__u64	ckc;			/* 0x0030 */
 	__u64	epoch;			/* 0x0038 */
@@ -90,7 +97,8 @@ struct kvm_s390_sie_block {
 	__u32	scaoh;			/* 0x005c */
 	__u8	reserved60;		/* 0x0060 */
 	__u8	ecb;			/* 0x0061 */
-	__u8	reserved62[2];		/* 0x0062 */
+	__u8    ecb2;                   /* 0x0062 */
+	__u8    reserved63[1];          /* 0x0063 */
 	__u32	scaol;			/* 0x0064 */
 	__u8	reserved68[4];		/* 0x0068 */
 	__u32	todpr;			/* 0x006c */
@@ -130,6 +138,7 @@ struct kvm_vcpu_stat {
 	u32 deliver_program_int;
 	u32 deliver_io_int;
 	u32 exit_wait_state;
+	u32 instruction_pfmf;
 	u32 instruction_stidp;
 	u32 instruction_spx;
 	u32 instruction_stpx;
@@ -166,7 +175,7 @@ struct kvm_s390_ext_info {
 };
 
 #define PGM_OPERATION            0x01
-#define PGM_PRIVILEGED_OPERATION 0x02
+#define PGM_PRIVILEGED_OP	 0x02
 #define PGM_EXECUTE              0x03
 #define PGM_PROTECTION           0x04
 #define PGM_ADDRESSING           0x05
@@ -219,7 +228,7 @@ struct kvm_s390_local_interrupt {
 	atomic_t active;
 	struct kvm_s390_float_interrupt *float_int;
 	int timer_due; /* event indicator for waitqueue below */
-	wait_queue_head_t wq;
+	wait_queue_head_t *wq;
 	atomic_t *cpuflags;
 	unsigned int action_bits;
 };
@@ -266,4 +275,5 @@ struct kvm_arch{
 };
 
 extern int sie64a(struct kvm_s390_sie_block *, u64 *);
+extern char sie_exit;
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/pci.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/pci.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/pci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/pci.h	2013-08-25 20:43:22.000000000 -0400
@@ -120,7 +120,6 @@ struct zpci_dev {
 
 	struct dentry	*debugfs_dev;
 	struct dentry	*debugfs_perf;
-	struct dentry	*debugfs_debug;
 };
 
 struct pci_hp_callback_ops {
@@ -143,7 +142,6 @@ int zpci_enable_device(struct zpci_dev *
 int zpci_disable_device(struct zpci_dev *);
 void zpci_stop_device(struct zpci_dev *);
 void zpci_free_device(struct zpci_dev *);
-int zpci_scan_device(struct zpci_dev *);
 int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
 int zpci_unregister_ioat(struct zpci_dev *, u8);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/perf_event.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/perf_event.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/perf_event.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/perf_event.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,3 +14,13 @@
 /* Per-CPU flags for PMU states */
 #define PMU_F_RESERVED			0x1000
 #define PMU_F_ENABLED			0x2000
+
+#ifdef CONFIG_64BIT
+
+/* Perf callbacks */
+struct pt_regs;
+extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
+extern unsigned long perf_misc_flags(struct pt_regs *regs);
+#define perf_misc_flags(regs) perf_misc_flags(regs)
+
+#endif /* CONFIG_64BIT */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/pgalloc.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/pgalloc.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/pgalloc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/pgalloc.h	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,9 @@ unsigned long *page_table_alloc(struct m
 void page_table_free(struct mm_struct *, unsigned long *);
 void page_table_free_rcu(struct mmu_gather *, unsigned long *);
 
+int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
+			  unsigned long key, bool nq);
+
 static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
 {
 	typedef struct { char _[n]; } addrtype;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -58,9 +58,6 @@ extern unsigned long zero_page_mask;
 #define __HAVE_COLOR_ZERO_PAGE
 
 /* TODO: s390 cannot support io_remap_pfn_range... */
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) 	       \
-	remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #endif /* !__ASSEMBLY__ */
 
 /*
@@ -299,18 +296,16 @@ extern unsigned long MODULES_END;
 #define _SEGMENT_ENTRY_EMPTY	(_SEGMENT_ENTRY_INV)
 
 /* Page status table bits for virtualization */
-#define RCP_ACC_BITS	0xf0000000UL
-#define RCP_FP_BIT	0x08000000UL
-#define RCP_PCL_BIT	0x00800000UL
-#define RCP_HR_BIT	0x00400000UL
-#define RCP_HC_BIT	0x00200000UL
-#define RCP_GR_BIT	0x00040000UL
-#define RCP_GC_BIT	0x00020000UL
-#define RCP_IN_BIT	0x00002000UL	/* IPTE notify bit */
-
-/* User dirty / referenced bit for KVM's migration feature */
-#define KVM_UR_BIT	0x00008000UL
-#define KVM_UC_BIT	0x00004000UL
+#define PGSTE_ACC_BITS	0xf0000000UL
+#define PGSTE_FP_BIT	0x08000000UL
+#define PGSTE_PCL_BIT	0x00800000UL
+#define PGSTE_HR_BIT	0x00400000UL
+#define PGSTE_HC_BIT	0x00200000UL
+#define PGSTE_GR_BIT	0x00040000UL
+#define PGSTE_GC_BIT	0x00020000UL
+#define PGSTE_UR_BIT	0x00008000UL
+#define PGSTE_UC_BIT	0x00004000UL	/* user dirty (migration) */
+#define PGSTE_IN_BIT	0x00002000UL	/* IPTE notify bit */
 
 #else /* CONFIG_64BIT */
 
@@ -367,18 +362,16 @@ extern unsigned long MODULES_END;
 				 | _SEGMENT_ENTRY_SPLIT | _SEGMENT_ENTRY_CO)
 
 /* Page status table bits for virtualization */
-#define RCP_ACC_BITS	0xf000000000000000UL
-#define RCP_FP_BIT	0x0800000000000000UL
-#define RCP_PCL_BIT	0x0080000000000000UL
-#define RCP_HR_BIT	0x0040000000000000UL
-#define RCP_HC_BIT	0x0020000000000000UL
-#define RCP_GR_BIT	0x0004000000000000UL
-#define RCP_GC_BIT	0x0002000000000000UL
-#define RCP_IN_BIT	0x0000200000000000UL	/* IPTE notify bit */
-
-/* User dirty / referenced bit for KVM's migration feature */
-#define KVM_UR_BIT	0x0000800000000000UL
-#define KVM_UC_BIT	0x0000400000000000UL
+#define PGSTE_ACC_BITS	0xf000000000000000UL
+#define PGSTE_FP_BIT	0x0800000000000000UL
+#define PGSTE_PCL_BIT	0x0080000000000000UL
+#define PGSTE_HR_BIT	0x0040000000000000UL
+#define PGSTE_HC_BIT	0x0020000000000000UL
+#define PGSTE_GR_BIT	0x0004000000000000UL
+#define PGSTE_GC_BIT	0x0002000000000000UL
+#define PGSTE_UR_BIT	0x0000800000000000UL
+#define PGSTE_UC_BIT	0x0000400000000000UL	/* user dirty (migration) */
+#define PGSTE_IN_BIT	0x0000200000000000UL	/* IPTE notify bit */
 
 #endif /* CONFIG_64BIT */
 
@@ -618,8 +611,8 @@ static inline pgste_t pgste_get_lock(pte
 	asm(
 		"	lg	%0,%2\n"
 		"0:	lgr	%1,%0\n"
-		"	nihh	%0,0xff7f\n"	/* clear RCP_PCL_BIT in old */
-		"	oihh	%1,0x0080\n"	/* set RCP_PCL_BIT in new */
+		"	nihh	%0,0xff7f\n"	/* clear PCL bit in old */
+		"	oihh	%1,0x0080\n"	/* set PCL bit in new */
 		"	csg	%0,%1,%2\n"
 		"	jl	0b\n"
 		: "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE])
@@ -632,7 +625,7 @@ static inline void pgste_set_unlock(pte_
 {
 #ifdef CONFIG_PGSTE
 	asm(
-		"	nihh	%1,0xff7f\n"	/* clear RCP_PCL_BIT */
+		"	nihh	%1,0xff7f\n"	/* clear PCL bit */
 		"	stg	%1,%0\n"
 		: "=Q" (ptep[PTRS_PER_PTE])
 		: "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE])
@@ -665,14 +658,14 @@ static inline pgste_t pgste_update_all(p
 	else if (bits)
 		page_reset_referenced(address);
 	/* Transfer page changed & referenced bit to guest bits in pgste */
-	pgste_val(pgste) |= bits << 48;		/* RCP_GR_BIT & RCP_GC_BIT */
+	pgste_val(pgste) |= bits << 48;		/* GR bit & GC bit */
 	/* Get host changed & referenced bits from pgste */
-	bits |= (pgste_val(pgste) & (RCP_HR_BIT | RCP_HC_BIT)) >> 52;
+	bits |= (pgste_val(pgste) & (PGSTE_HR_BIT | PGSTE_HC_BIT)) >> 52;
 	/* Transfer page changed & referenced bit to kvm user bits */
-	pgste_val(pgste) |= bits << 45;		/* KVM_UR_BIT & KVM_UC_BIT */
+	pgste_val(pgste) |= bits << 45;		/* PGSTE_UR_BIT & PGSTE_UC_BIT */
 	/* Clear relevant host bits in pgste. */
-	pgste_val(pgste) &= ~(RCP_HR_BIT | RCP_HC_BIT);
-	pgste_val(pgste) &= ~(RCP_ACC_BITS | RCP_FP_BIT);
+	pgste_val(pgste) &= ~(PGSTE_HR_BIT | PGSTE_HC_BIT);
+	pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT);
 	/* Copy page access key and fetch protection bit to pgste */
 	pgste_val(pgste) |=
 		(unsigned long) (skey & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56;
@@ -693,15 +686,15 @@ static inline pgste_t pgste_update_young
 	/* Get referenced bit from storage key */
 	young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK);
 	if (young)
-		pgste_val(pgste) |= RCP_GR_BIT;
+		pgste_val(pgste) |= PGSTE_GR_BIT;
 	/* Get host referenced bit from pgste */
-	if (pgste_val(pgste) & RCP_HR_BIT) {
-		pgste_val(pgste) &= ~RCP_HR_BIT;
+	if (pgste_val(pgste) & PGSTE_HR_BIT) {
+		pgste_val(pgste) &= ~PGSTE_HR_BIT;
 		young = 1;
 	}
 	/* Transfer referenced bit to kvm user bits and pte */
 	if (young) {
-		pgste_val(pgste) |= KVM_UR_BIT;
+		pgste_val(pgste) |= PGSTE_UR_BIT;
 		pte_val(*ptep) |= _PAGE_SWR;
 	}
 #endif
@@ -723,7 +716,7 @@ static inline void pgste_set_key(pte_t *
 	 * The guest C/R information is still in the PGSTE, set real
 	 * key C/R to 0.
 	 */
-	nkey = (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56;
+	nkey = (pgste_val(pgste) & (PGSTE_ACC_BITS | PGSTE_FP_BIT)) >> 56;
 	page_set_storage_key(address, nkey, 0);
 #endif
 }
@@ -753,6 +746,7 @@ struct gmap {
 	struct mm_struct *mm;
 	unsigned long *table;
 	unsigned long asce;
+	void *private;
 	struct list_head crst_list;
 };
 
@@ -811,8 +805,8 @@ static inline pgste_t pgste_ipte_notify(
 					pte_t *ptep, pgste_t pgste)
 {
 #ifdef CONFIG_PGSTE
-	if (pgste_val(pgste) & RCP_IN_BIT) {
-		pgste_val(pgste) &= ~RCP_IN_BIT;
+	if (pgste_val(pgste) & PGSTE_IN_BIT) {
+		pgste_val(pgste) &= ~PGSTE_IN_BIT;
 		gmap_do_ipte_notify(mm, addr, ptep);
 	}
 #endif
@@ -980,8 +974,8 @@ static inline int ptep_test_and_clear_us
 	if (mm_has_pgste(mm)) {
 		pgste = pgste_get_lock(ptep);
 		pgste = pgste_update_all(ptep, pgste);
-		dirty = !!(pgste_val(pgste) & KVM_UC_BIT);
-		pgste_val(pgste) &= ~KVM_UC_BIT;
+		dirty = !!(pgste_val(pgste) & PGSTE_UC_BIT);
+		pgste_val(pgste) &= ~PGSTE_UC_BIT;
 		pgste_set_unlock(ptep, pgste);
 		return dirty;
 	}
@@ -1000,8 +994,8 @@ static inline int ptep_test_and_clear_us
 	if (mm_has_pgste(mm)) {
 		pgste = pgste_get_lock(ptep);
 		pgste = pgste_update_young(ptep, pgste);
-		young = !!(pgste_val(pgste) & KVM_UR_BIT);
-		pgste_val(pgste) &= ~KVM_UR_BIT;
+		young = !!(pgste_val(pgste) & PGSTE_UR_BIT);
+		pgste_val(pgste) &= ~PGSTE_UR_BIT;
 		pgste_set_unlock(ptep, pgste);
 	}
 	return young;
@@ -1370,10 +1364,11 @@ static inline pmd_t pmd_mkwrite(pmd_t pm
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 
 #define __HAVE_ARCH_PGTABLE_DEPOSIT
-extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+				       pgtable_t pgtable);
 
 #define __HAVE_ARCH_PGTABLE_WITHDRAW
-extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm);
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
 
 static inline int pmd_trans_splitting(pmd_t pmd)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/processor.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/processor.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/processor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/processor.h	2013-08-25 20:43:22.000000000 -0400
@@ -91,7 +91,15 @@ struct thread_struct {
 #endif
 };
 
-#define PER_FLAG_NO_TE		1UL	/* Flag to disable transactions. */
+/* Flag to disable transactions. */
+#define PER_FLAG_NO_TE			1UL
+/* Flag to enable random transaction aborts. */
+#define PER_FLAG_TE_ABORT_RAND		2UL
+/* Flag to specify random transaction abort mode:
+ * - abort each transaction at a random instruction before TEND if set.
+ * - abort random transactions at a random instruction if cleared.
+ */
+#define PER_FLAG_TE_ABORT_RAND_TEND	4UL
 
 typedef struct thread_struct thread_struct;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/ptrace.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/ptrace.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/ptrace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/ptrace.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@ struct pt_regs
 	unsigned long gprs[NUM_GPRS];
 	unsigned long orig_gpr2;
 	unsigned int int_code;
+	unsigned int int_parm;
 	unsigned long int_parm_long;
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/switch_to.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/switch_to.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/switch_to.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/switch_to.h	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@
 #include <linux/thread_info.h>
 
 extern struct task_struct *__switch_to(void *, void *);
-extern void update_per_regs(struct task_struct *task);
+extern void update_cr_regs(struct task_struct *task);
 
 static inline void save_fp_regs(s390_fp_regs *fpregs)
 {
@@ -86,7 +86,7 @@ static inline void restore_access_regs(u
 		restore_fp_regs(&next->thread.fp_regs);			\
 		restore_access_regs(&next->thread.acrs[0]);		\
 		restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb);	\
-		update_per_regs(next);					\
+		update_cr_regs(next);					\
 	}								\
 	prev = __switch_to(prev,next);					\
 } while (0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/asm/tlb.h linux-libre-3.11-rc7-gnu/arch/s390/include/asm/tlb.h
--- linux-libre-3.10-gnu/arch/s390/include/asm/tlb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/asm/tlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,7 @@ struct mmu_gather {
 	struct mm_struct *mm;
 	struct mmu_table_batch *batch;
 	unsigned int fullmm;
+	unsigned long start, end;
 };
 
 struct mmu_table_batch {
@@ -48,10 +49,13 @@ extern void tlb_remove_table(struct mmu_
 
 static inline void tlb_gather_mmu(struct mmu_gather *tlb,
 				  struct mm_struct *mm,
-				  unsigned int full_mm_flush)
+				  unsigned long start,
+				  unsigned long end)
 {
 	tlb->mm = mm;
-	tlb->fullmm = full_mm_flush;
+	tlb->start = start;
+	tlb->end = end;
+	tlb->fullmm = !(start | (end+1));
 	tlb->batch = NULL;
 	if (tlb->fullmm)
 		__tlb_flush_mm(mm);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/uapi/asm/chsc.h linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/chsc.h
--- linux-libre-3.10-gnu/arch/s390/include/uapi/asm/chsc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/chsc.h	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,16 @@ struct chsc_async_area {
 	__u8 data[CHSC_SIZE - sizeof(struct chsc_async_header)];
 } __attribute__ ((packed));
 
+struct chsc_header {
+	__u16 length;
+	__u16 code;
+} __attribute__ ((packed));
+
+struct chsc_sync_area {
+	struct chsc_header header;
+	__u8 data[CHSC_SIZE - sizeof(struct chsc_header)];
+} __attribute__ ((packed));
+
 struct chsc_response_struct {
 	__u16 length;
 	__u16 code;
@@ -126,5 +136,8 @@ struct chsc_cpd_info {
 #define CHSC_INFO_CCL _IOWR(CHSC_IOCTL_MAGIC, 0x86, struct chsc_comp_list)
 #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info)
 #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal)
+#define CHSC_START_SYNC _IOWR(CHSC_IOCTL_MAGIC, 0x89, struct chsc_sync_area)
+#define CHSC_ON_CLOSE_SET _IOWR(CHSC_IOCTL_MAGIC, 0x8a, struct chsc_async_area)
+#define CHSC_ON_CLOSE_REMOVE _IO(CHSC_IOCTL_MAGIC, 0x8b)
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/uapi/asm/dasd.h linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/dasd.h
--- linux-libre-3.10-gnu/arch/s390/include/uapi/asm/dasd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/dasd.h	2013-08-25 20:43:22.000000000 -0400
@@ -261,6 +261,10 @@ struct dasd_snid_ioctl_data {
 #define BIODASDQUIESCE _IO(DASD_IOCTL_LETTER,6) 
 /* Resume IO on device */
 #define BIODASDRESUME  _IO(DASD_IOCTL_LETTER,7) 
+/* Abort all I/O on a device */
+#define BIODASDABORTIO _IO(DASD_IOCTL_LETTER, 240)
+/* Allow I/O on a device */
+#define BIODASDALLOWIO _IO(DASD_IOCTL_LETTER, 241)
 
 
 /* retrieve API version number */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/uapi/asm/Kbuild linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/Kbuild
--- linux-libre-3.10-gnu/arch/s390/include/uapi/asm/Kbuild	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/Kbuild	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,7 @@ header-y += siginfo.h
 header-y += signal.h
 header-y += socket.h
 header-y += sockios.h
+header-y += sclp_ctl.h
 header-y += stat.h
 header-y += statfs.h
 header-y += swab.h
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/uapi/asm/ptrace.h linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/ptrace.h
--- linux-libre-3.10-gnu/arch/s390/include/uapi/asm/ptrace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/ptrace.h	2013-08-25 20:43:22.000000000 -0400
@@ -400,6 +400,7 @@ typedef struct
 #define PTRACE_POKE_SYSTEM_CALL	      0x5008
 #define PTRACE_ENABLE_TE	      0x5009
 #define PTRACE_DISABLE_TE	      0x5010
+#define PTRACE_TE_ABORT_RAND	      0x5011
 
 /*
  * PT_PROT definition is loosely based on hppa bsd definition in
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/uapi/asm/sclp_ctl.h linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/sclp_ctl.h
--- linux-libre-3.10-gnu/arch/s390/include/uapi/asm/sclp_ctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/sclp_ctl.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * IOCTL interface for SCLP
+ *
+ * Copyright IBM Corp. 2012
+ *
+ * Author: Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#ifndef _ASM_SCLP_CTL_H
+#define _ASM_SCLP_CTL_H
+
+#include <linux/types.h>
+
+struct sclp_ctl_sccb {
+	__u32	cmdw;
+	__u64	sccb;
+} __attribute__((packed));
+
+#define SCLP_CTL_IOCTL_MAGIC 0x10
+
+#define SCLP_CTL_SCCB \
+	_IOWR(SCLP_CTL_IOCTL_MAGIC, 0x10, struct sclp_ctl_sccb)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/s390/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -80,4 +80,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif /* _ASM_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/Kconfig linux-libre-3.11-rc7-gnu/arch/s390/Kconfig
--- linux-libre-3.10-gnu/arch/s390/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -118,6 +118,7 @@ config S390
 	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_LZ4
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_XZ
@@ -227,11 +228,12 @@ config MARCH_Z196
 	  not work on older machines.
 
 config MARCH_ZEC12
-	bool "IBM zEC12"
+	bool "IBM zBC12 and zEC12"
 	select HAVE_MARCH_ZEC12_FEATURES if 64BIT
 	help
-	  Select this to enable optimizations for IBM zEC12 (2827 series). The
-	  kernel will be slightly faster but will not work on older machines.
+	  Select this to enable optimizations for IBM zBC12 and zEC12 (2828 and
+	  2827 series). The kernel will be slightly faster but will not work on
+	  older machines.
 
 endchoice
 
@@ -301,7 +303,6 @@ config HOTPLUG_CPU
 	def_bool y
 	prompt "Support for hot-pluggable CPUs"
 	depends on SMP
-	select HOTPLUG
 	help
 	  Say Y here to be able to turn CPUs off and on. CPUs
 	  can be controlled through /sys/devices/system/cpu/cpu#.
@@ -710,6 +711,7 @@ config S390_GUEST
 	def_bool y
 	prompt "s390 support for virtio devices"
 	depends on 64BIT
+	select TTY
 	select VIRTUALIZATION
 	select VIRTIO
 	select VIRTIO_CONSOLE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/asm-offsets.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/asm-offsets.c
--- linux-libre-3.10-gnu/arch/s390/kernel/asm-offsets.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/asm-offsets.c	2013-08-25 20:43:22.000000000 -0400
@@ -7,6 +7,7 @@
 #define ASM_OFFSETS_C
 
 #include <linux/kbuild.h>
+#include <linux/kvm_host.h>
 #include <linux/sched.h>
 #include <asm/cputime.h>
 #include <asm/vdso.h>
@@ -47,6 +48,7 @@ int main(void)
 	DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs));
 	DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2));
 	DEFINE(__PT_INT_CODE, offsetof(struct pt_regs, int_code));
+	DEFINE(__PT_INT_PARM, offsetof(struct pt_regs, int_parm));
 	DEFINE(__PT_INT_PARM_LONG, offsetof(struct pt_regs, int_parm_long));
 	DEFINE(__PT_SIZE, sizeof(struct pt_regs));
 	BLANK();
@@ -161,6 +163,8 @@ int main(void)
 	DEFINE(__LC_PGM_TDB, offsetof(struct _lowcore, pgm_tdb));
 	DEFINE(__THREAD_trap_tdb, offsetof(struct task_struct, thread.trap_tdb));
 	DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce));
+	DEFINE(__SIE_PROG0C, offsetof(struct kvm_s390_sie_block, prog0c));
+	DEFINE(__SIE_PROG20, offsetof(struct kvm_s390_sie_block, prog20));
 #endif /* CONFIG_32BIT */
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/cache.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/cache.c
--- linux-libre-3.10-gnu/arch/s390/kernel/cache.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/cache.c	2013-08-25 20:43:22.000000000 -0400
@@ -173,7 +173,7 @@ error:
 	}
 }
 
-static struct cache_dir *__cpuinit cache_create_cache_dir(int cpu)
+static struct cache_dir *cache_create_cache_dir(int cpu)
 {
 	struct cache_dir *cache_dir;
 	struct kobject *kobj = NULL;
@@ -289,9 +289,8 @@ static struct kobj_type cache_index_type
 	.default_attrs = cache_index_default_attrs,
 };
 
-static int __cpuinit cache_create_index_dir(struct cache_dir *cache_dir,
-					    struct cache *cache, int index,
-					    int cpu)
+static int cache_create_index_dir(struct cache_dir *cache_dir,
+				  struct cache *cache, int index, int cpu)
 {
 	struct cache_index_dir *index_dir;
 	int rc;
@@ -313,7 +312,7 @@ out:
 	return rc;
 }
 
-static int __cpuinit cache_add_cpu(int cpu)
+static int cache_add_cpu(int cpu)
 {
 	struct cache_dir *cache_dir;
 	struct cache *cache;
@@ -335,7 +334,7 @@ static int __cpuinit cache_add_cpu(int c
 	return 0;
 }
 
-static void __cpuinit cache_remove_cpu(int cpu)
+static void cache_remove_cpu(int cpu)
 {
 	struct cache_index_dir *index, *next;
 	struct cache_dir *cache_dir;
@@ -354,8 +353,8 @@ static void __cpuinit cache_remove_cpu(i
 	cache_dir_cpu[cpu] = NULL;
 }
 
-static int __cpuinit cache_hotplug(struct notifier_block *nfb,
-				   unsigned long action, void *hcpu)
+static int cache_hotplug(struct notifier_block *nfb, unsigned long action,
+			 void *hcpu)
 {
 	int cpu = (long)hcpu;
 	int rc = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/crash_dump.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/crash_dump.c
--- linux-libre-3.10-gnu/arch/s390/kernel/crash_dump.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/crash_dump.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,48 @@
 #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y)))
 #define PTR_DIFF(x, y) ((unsigned long)(((char *) (x)) - ((unsigned long) (y))))
 
+
+/*
+ * Return physical address for virtual address
+ */
+static inline void *load_real_addr(void *addr)
+{
+	unsigned long real_addr;
+
+	asm volatile(
+		   "	lra     %0,0(%1)\n"
+		   "	jz	0f\n"
+		   "	la	%0,0\n"
+		   "0:"
+		   : "=a" (real_addr) : "a" (addr) : "cc");
+	return (void *)real_addr;
+}
+
+/*
+ * Copy up to one page to vmalloc or real memory
+ */
+static ssize_t copy_page_real(void *buf, void *src, size_t csize)
+{
+	size_t size;
+
+	if (is_vmalloc_addr(buf)) {
+		BUG_ON(csize >= PAGE_SIZE);
+		/* If buf is not page aligned, copy first part */
+		size = min(roundup(__pa(buf), PAGE_SIZE) - __pa(buf), csize);
+		if (size) {
+			if (memcpy_real(load_real_addr(buf), src, size))
+				return -EFAULT;
+			buf += size;
+			src += size;
+		}
+		/* Copy second part */
+		size = csize - size;
+		return (size) ? memcpy_real(load_real_addr(buf), src, size) : 0;
+	} else {
+		return memcpy_real(buf, src, csize);
+	}
+}
+
 /*
  * Copy one page from "oldmem"
  *
@@ -32,6 +74,7 @@ ssize_t copy_oldmem_page(unsigned long p
 			 size_t csize, unsigned long offset, int userbuf)
 {
 	unsigned long src;
+	int rc;
 
 	if (!csize)
 		return 0;
@@ -43,11 +86,11 @@ ssize_t copy_oldmem_page(unsigned long p
 		 src < OLDMEM_BASE + OLDMEM_SIZE)
 		src -= OLDMEM_BASE;
 	if (userbuf)
-		copy_to_user_real((void __force __user *) buf, (void *) src,
-				  csize);
+		rc = copy_to_user_real((void __force __user *) buf,
+				       (void *) src, csize);
 	else
-		memcpy_real(buf, (void *) src, csize);
-	return csize;
+		rc = copy_page_real(buf, (void *) src, csize);
+	return (rc == 0) ? csize : rc;
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/entry64.S linux-libre-3.11-rc7-gnu/arch/s390/kernel/entry64.S
--- linux-libre-3.10-gnu/arch/s390/kernel/entry64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/entry64.S	2013-08-25 20:43:22.000000000 -0400
@@ -47,7 +47,6 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_
 		 _TIF_MCCK_PENDING)
 _TIF_TRACE    = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
 		 _TIF_SYSCALL_TRACEPOINT)
-_TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
 
 #define BASED(name) name-system_call(%r13)
 
@@ -81,23 +80,27 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_
 #endif
 	.endm
 
-	.macro	HANDLE_SIE_INTERCEPT scratch,pgmcheck
+	.macro	HANDLE_SIE_INTERCEPT scratch,reason
 #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
 	tmhh	%r8,0x0001		# interrupting from user ?
-	jnz	.+42
+	jnz	.+62
 	lgr	\scratch,%r9
-	slg	\scratch,BASED(.Lsie_loop)
-	clg	\scratch,BASED(.Lsie_length)
-	.if	\pgmcheck
+	slg	\scratch,BASED(.Lsie_critical)
+	clg	\scratch,BASED(.Lsie_critical_length)
+	.if	\reason==1
 	# Some program interrupts are suppressing (e.g. protection).
 	# We must also check the instruction after SIE in that case.
 	# do_protection_exception will rewind to rewind_pad
-	jh	.+22
+	jh	.+42
 	.else
-	jhe	.+22
+	jhe	.+42
 	.endif
-	lg	%r9,BASED(.Lsie_loop)
-	LPP	BASED(.Lhost_id)	# set host id
+	lg	%r14,__SF_EMPTY(%r15)		# get control block pointer
+	LPP	__SF_EMPTY+16(%r15)		# set host id
+	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
+	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
+	larl	%r9,sie_exit			# skip forward to sie_exit
+	mvi	__SF_EMPTY+31(%r15),\reason	# set exit reason
 #endif
 	.endm
 
@@ -450,7 +453,7 @@ ENTRY(io_int_handler)
 	lg	%r12,__LC_THREAD_INFO
 	larl	%r13,system_call
 	lmg	%r8,%r9,__LC_IO_OLD_PSW
-	HANDLE_SIE_INTERCEPT %r14,0
+	HANDLE_SIE_INTERCEPT %r14,2
 	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
 	tmhh	%r8,0x0001		# interrupting from user?
 	jz	io_skip
@@ -460,10 +463,18 @@ io_skip:
 	stmg	%r0,%r7,__PT_R0(%r11)
 	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
 	stmg	%r8,%r9,__PT_PSW(%r11)
+	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
 	TRACE_IRQS_OFF
 	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+io_loop:
 	lgr	%r2,%r11		# pass pointer to pt_regs
 	brasl	%r14,do_IRQ
+	tm	__LC_MACHINE_FLAGS+6,0x10	# MACHINE_FLAG_LPAR
+	jz	io_return
+	tpi	0
+	jz	io_return
+	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
+	j	io_loop
 io_return:
 	LOCKDEP_SYS_EXIT
 	TRACE_IRQS_ON
@@ -595,7 +606,7 @@ ENTRY(ext_int_handler)
 	lg	%r12,__LC_THREAD_INFO
 	larl	%r13,system_call
 	lmg	%r8,%r9,__LC_EXT_OLD_PSW
-	HANDLE_SIE_INTERCEPT %r14,0
+	HANDLE_SIE_INTERCEPT %r14,3
 	SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
 	tmhh	%r8,0x0001		# interrupting from user ?
 	jz	ext_skip
@@ -605,13 +616,13 @@ ext_skip:
 	stmg	%r0,%r7,__PT_R0(%r11)
 	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
 	stmg	%r8,%r9,__PT_PSW(%r11)
+	lghi	%r1,__LC_EXT_PARAMS2
+	mvc	__PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
+	mvc	__PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
+	mvc	__PT_INT_PARM_LONG(8,%r11),0(%r1)
 	TRACE_IRQS_OFF
 	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
-	lghi	%r1,4096
 	lgr	%r2,%r11		# pass pointer to pt_regs
-	llgf	%r3,__LC_EXT_CPU_ADDR	# get cpu address + interruption code
-	llgf	%r4,__LC_EXT_PARAMS	# get external parameter
-	lg	%r5,__LC_EXT_PARAMS2-4096(%r1)	# get 64 bit external parameter
 	brasl	%r14,do_extint
 	j	io_return
 
@@ -643,7 +654,7 @@ ENTRY(mcck_int_handler)
 	lg	%r12,__LC_THREAD_INFO
 	larl	%r13,system_call
 	lmg	%r8,%r9,__LC_MCK_OLD_PSW
-	HANDLE_SIE_INTERCEPT %r14,0
+	HANDLE_SIE_INTERCEPT %r14,4
 	tm	__LC_MCCK_CODE,0x80	# system damage?
 	jo	mcck_panic		# yes -> rest of mcck code invalid
 	lghi	%r14,__LC_CPU_TIMER_SAVE_AREA
@@ -937,56 +948,50 @@ ENTRY(sie64a)
 	stmg	%r6,%r14,__SF_GPRS(%r15)	# save kernel registers
 	stg	%r2,__SF_EMPTY(%r15)		# save control block pointer
 	stg	%r3,__SF_EMPTY+8(%r15)		# save guest register save area
-	xc	__SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0
+	xc	__SF_EMPTY+16(16,%r15),__SF_EMPTY+16(%r15) # host id & reason
 	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13
-# some program checks are suppressing. C code (e.g. do_protection_exception)
-# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other
-# instructions in the sie_loop should not cause program interrupts. So
-# lets use a nop (47 00 00 00) as a landing pad.
-# See also HANDLE_SIE_INTERCEPT
-rewind_pad:
-	nop	0
-sie_loop:
-	lg	%r14,__LC_THREAD_INFO		# pointer thread_info struct
-	tm	__TI_flags+7(%r14),_TIF_EXIT_SIE
-	jnz	sie_exit
 	lg	%r14,__LC_GMAP			# get gmap pointer
 	ltgr	%r14,%r14
 	jz	sie_gmap
 	lctlg	%c1,%c1,__GMAP_ASCE(%r14)	# load primary asce
 sie_gmap:
 	lg	%r14,__SF_EMPTY(%r15)		# get control block pointer
+	oi	__SIE_PROG0C+3(%r14),1		# we are going into SIE now
+	tm	__SIE_PROG20+3(%r14),1		# last exit...
+	jnz	sie_done
 	LPP	__SF_EMPTY(%r15)		# set guest id
 	sie	0(%r14)
 sie_done:
 	LPP	__SF_EMPTY+16(%r15)		# set host id
-	lg	%r14,__LC_THREAD_INFO		# pointer thread_info struct
-sie_exit:
+	ni	__SIE_PROG0C+3(%r14),0xfe	# no longer in SIE
 	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
+# some program checks are suppressing. C code (e.g. do_protection_exception)
+# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other
+# instructions beween sie64a and sie_done should not cause program
+# interrupts. So lets use a nop (47 00 00 00) as a landing pad.
+# See also HANDLE_SIE_INTERCEPT
+rewind_pad:
+	nop	0
+	.globl sie_exit
+sie_exit:
 	lg	%r14,__SF_EMPTY+8(%r15)		# load guest register save area
 	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
 	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
-	lghi	%r2,0
+	lg	%r2,__SF_EMPTY+24(%r15)		# return exit reason code
 	br	%r14
 sie_fault:
-	lctlg	%c1,%c1,__LC_USER_ASCE		# load primary asce
-	lg	%r14,__LC_THREAD_INFO		# pointer thread_info struct
-	lg	%r14,__SF_EMPTY+8(%r15)		# load guest register save area
-	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13
-	lmg	%r6,%r14,__SF_GPRS(%r15)	# restore kernel registers
-	lghi	%r2,-EFAULT
-	br	%r14
+	lghi	%r14,-EFAULT
+	stg	%r14,__SF_EMPTY+24(%r15)	# set exit reason code
+	j	sie_exit
 
 	.align	8
-.Lsie_loop:
-	.quad	sie_loop
-.Lsie_length:
-	.quad	sie_done - sie_loop
-.Lhost_id:
-	.quad	0
+.Lsie_critical:
+	.quad	sie_gmap
+.Lsie_critical_length:
+	.quad	sie_done - sie_gmap
 
 	EX_TABLE(rewind_pad,sie_fault)
-	EX_TABLE(sie_loop,sie_fault)
+	EX_TABLE(sie_exit,sie_fault)
 #endif
 
 		.section .rodata, "a"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/entry.h linux-libre-3.11-rc7-gnu/arch/s390/kernel/entry.h
--- linux-libre-3.10-gnu/arch/s390/kernel/entry.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/entry.h	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ void handle_signal32(unsigned long sig,
 void do_notify_resume(struct pt_regs *regs);
 
 struct ext_code;
-void do_extint(struct pt_regs *regs, struct ext_code, unsigned int, unsigned long);
+void do_extint(struct pt_regs *regs);
 void do_restart(void);
 void __init startup_init(void);
 void die(struct pt_regs *regs, const char *str);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/entry.S linux-libre-3.11-rc7-gnu/arch/s390/kernel/entry.S
--- linux-libre-3.10-gnu/arch/s390/kernel/entry.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/entry.S	2013-08-25 20:43:22.000000000 -0400
@@ -429,11 +429,19 @@ io_skip:
 	stm	%r0,%r7,__PT_R0(%r11)
 	mvc	__PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
 	stm	%r8,%r9,__PT_PSW(%r11)
+	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
 	TRACE_IRQS_OFF
 	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
+io_loop:
 	l	%r1,BASED(.Ldo_IRQ)
 	lr	%r2,%r11		# pass pointer to pt_regs
 	basr	%r14,%r1		# call do_IRQ
+	tm	__LC_MACHINE_FLAGS+2,0x10	# MACHINE_FLAG_LPAR
+	jz	io_return
+	tpi	0
+	jz	io_return
+	mvc	__PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
+	j	io_loop
 io_return:
 	LOCKDEP_SYS_EXIT
 	TRACE_IRQS_ON
@@ -573,10 +581,10 @@ ext_skip:
 	stm	%r0,%r7,__PT_R0(%r11)
 	mvc	__PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
 	stm	%r8,%r9,__PT_PSW(%r11)
+	mvc	__PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
+	mvc	__PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
 	TRACE_IRQS_OFF
 	lr	%r2,%r11		# pass pointer to pt_regs
-	l	%r3,__LC_EXT_CPU_ADDR	# get cpu address + interruption code
-	l	%r4,__LC_EXT_PARAMS	# get external parameters
 	l	%r1,BASED(.Ldo_extint)
 	basr	%r14,%r1		# call do_extint
 	j	io_return
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/irq.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/irq.c
--- linux-libre-3.10-gnu/arch/s390/kernel/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -234,9 +234,9 @@ int unregister_external_interrupt(u16 co
 }
 EXPORT_SYMBOL(unregister_external_interrupt);
 
-void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,
-			   unsigned int param32, unsigned long param64)
+void __irq_entry do_extint(struct pt_regs *regs)
 {
+	struct ext_code ext_code;
 	struct pt_regs *old_regs;
 	struct ext_int_info *p;
 	int index;
@@ -248,6 +248,7 @@ void __irq_entry do_extint(struct pt_reg
 		clock_comparator_work();
 	}
 	kstat_incr_irqs_this_cpu(EXTERNAL_INTERRUPT, NULL);
+	ext_code = *(struct ext_code *) &regs->int_code;
 	if (ext_code.code != 0x1004)
 		__get_cpu_var(s390_idle).nohz_delay = 1;
 
@@ -255,7 +256,8 @@ void __irq_entry do_extint(struct pt_reg
 	rcu_read_lock();
 	list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
 		if (likely(p->code == ext_code.code))
-			p->handler(ext_code, param32, param64);
+			p->handler(ext_code, regs->int_parm,
+				   regs->int_parm_long);
 	rcu_read_unlock();
 	irq_exit();
 	set_irq_regs(old_regs);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/perf_cpum_cf.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/perf_cpum_cf.c
--- linux-libre-3.10-gnu/arch/s390/kernel/perf_cpum_cf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/perf_cpum_cf.c	2013-08-25 20:43:22.000000000 -0400
@@ -639,8 +639,8 @@ static struct pmu cpumf_pmu = {
 	.cancel_txn   = cpumf_pmu_cancel_txn,
 };
 
-static int __cpuinit cpumf_pmu_notifier(struct notifier_block *self,
-					unsigned long action, void *hcpu)
+static int cpumf_pmu_notifier(struct notifier_block *self, unsigned long action,
+			      void *hcpu)
 {
 	unsigned int cpu = (long) hcpu;
 	int flags;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/perf_event.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/perf_event.c
--- linux-libre-3.10-gnu/arch/s390/kernel/perf_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/perf_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/perf_event.h>
+#include <linux/kvm_host.h>
 #include <linux/percpu.h>
 #include <linux/export.h>
 #include <asm/irq.h>
@@ -39,6 +40,58 @@ int perf_num_counters(void)
 }
 EXPORT_SYMBOL(perf_num_counters);
 
+static struct kvm_s390_sie_block *sie_block(struct pt_regs *regs)
+{
+	struct stack_frame *stack = (struct stack_frame *) regs->gprs[15];
+
+	if (!stack)
+		return NULL;
+
+	return (struct kvm_s390_sie_block *) stack->empty1[0];
+}
+
+static bool is_in_guest(struct pt_regs *regs)
+{
+	if (user_mode(regs))
+		return false;
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+	return instruction_pointer(regs) == (unsigned long) &sie_exit;
+#else
+	return false;
+#endif
+}
+
+static unsigned long guest_is_user_mode(struct pt_regs *regs)
+{
+	return sie_block(regs)->gpsw.mask & PSW_MASK_PSTATE;
+}
+
+static unsigned long instruction_pointer_guest(struct pt_regs *regs)
+{
+	return sie_block(regs)->gpsw.addr & PSW_ADDR_INSN;
+}
+
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
+{
+	return is_in_guest(regs) ? instruction_pointer_guest(regs)
+				 : instruction_pointer(regs);
+}
+
+static unsigned long perf_misc_guest_flags(struct pt_regs *regs)
+{
+	return guest_is_user_mode(regs) ? PERF_RECORD_MISC_GUEST_USER
+					: PERF_RECORD_MISC_GUEST_KERNEL;
+}
+
+unsigned long perf_misc_flags(struct pt_regs *regs)
+{
+	if (is_in_guest(regs))
+		return perf_misc_guest_flags(regs);
+
+	return user_mode(regs) ? PERF_RECORD_MISC_USER
+			       : PERF_RECORD_MISC_KERNEL;
+}
+
 void perf_event_print_debug(void)
 {
 	struct cpumf_ctr_info cf_info;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/processor.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/processor.c
--- linux-libre-3.10-gnu/arch/s390/kernel/processor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/processor.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,7 +21,7 @@ static DEFINE_PER_CPU(struct cpuid, cpu_
 /*
  * cpu_init - initializes state that is per-CPU.
  */
-void __cpuinit cpu_init(void)
+void cpu_init(void)
 {
 	struct s390_idle_data *idle = &__get_cpu_var(s390_idle);
 	struct cpuid *id = &__get_cpu_var(cpu_id);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/ptrace.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/ptrace.c
--- linux-libre-3.10-gnu/arch/s390/kernel/ptrace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/ptrace.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,7 +47,7 @@ enum s390_regset {
 	REGSET_GENERAL_EXTENDED,
 };
 
-void update_per_regs(struct task_struct *task)
+void update_cr_regs(struct task_struct *task)
 {
 	struct pt_regs *regs = task_pt_regs(task);
 	struct thread_struct *thread = &task->thread;
@@ -56,17 +56,25 @@ void update_per_regs(struct task_struct
 #ifdef CONFIG_64BIT
 	/* Take care of the enable/disable of transactional execution. */
 	if (MACHINE_HAS_TE) {
-		unsigned long cr0, cr0_new;
+		unsigned long cr[3], cr_new[3];
 
-		__ctl_store(cr0, 0, 0);
-		/* set or clear transaction execution bits 8 and 9. */
+		__ctl_store(cr, 0, 2);
+		cr_new[1] = cr[1];
+		/* Set or clear transaction execution TXC/PIFO bits 8 and 9. */
 		if (task->thread.per_flags & PER_FLAG_NO_TE)
-			cr0_new = cr0 & ~(3UL << 54);
+			cr_new[0] = cr[0] & ~(3UL << 54);
 		else
-			cr0_new = cr0 | (3UL << 54);
-		/* Only load control register 0 if necessary. */
-		if (cr0 != cr0_new)
-			__ctl_load(cr0_new, 0, 0);
+			cr_new[0] = cr[0] | (3UL << 54);
+		/* Set or clear transaction execution TDC bits 62 and 63. */
+		cr_new[2] = cr[2] & ~3UL;
+		if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) {
+			if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND)
+				cr_new[2] |= 1UL;
+			else
+				cr_new[2] |= 2UL;
+		}
+		if (memcmp(&cr_new, &cr, sizeof(cr)))
+			__ctl_load(cr_new, 0, 2);
 	}
 #endif
 	/* Copy user specified PER registers */
@@ -100,14 +108,14 @@ void user_enable_single_step(struct task
 {
 	set_tsk_thread_flag(task, TIF_SINGLE_STEP);
 	if (task == current)
-		update_per_regs(task);
+		update_cr_regs(task);
 }
 
 void user_disable_single_step(struct task_struct *task)
 {
 	clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
 	if (task == current)
-		update_per_regs(task);
+		update_cr_regs(task);
 }
 
 /*
@@ -447,6 +455,26 @@ long arch_ptrace(struct task_struct *chi
 		if (!MACHINE_HAS_TE)
 			return -EIO;
 		child->thread.per_flags |= PER_FLAG_NO_TE;
+		child->thread.per_flags &= ~PER_FLAG_TE_ABORT_RAND;
+		return 0;
+	case PTRACE_TE_ABORT_RAND:
+		if (!MACHINE_HAS_TE || (child->thread.per_flags & PER_FLAG_NO_TE))
+			return -EIO;
+		switch (data) {
+		case 0UL:
+			child->thread.per_flags &= ~PER_FLAG_TE_ABORT_RAND;
+			break;
+		case 1UL:
+			child->thread.per_flags |= PER_FLAG_TE_ABORT_RAND;
+			child->thread.per_flags |= PER_FLAG_TE_ABORT_RAND_TEND;
+			break;
+		case 2UL:
+			child->thread.per_flags |= PER_FLAG_TE_ABORT_RAND;
+			child->thread.per_flags &= ~PER_FLAG_TE_ABORT_RAND_TEND;
+			break;
+		default:
+			return -EINVAL;
+		}
 		return 0;
 	default:
 		/* Removing high order bit from addr (only for 31 bit). */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/s390_ksyms.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/s390_ksyms.c
--- linux-libre-3.10-gnu/arch/s390/kernel/s390_ksyms.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/s390_ksyms.c	2013-08-25 20:43:22.000000000 -0400
@@ -7,6 +7,7 @@ EXPORT_SYMBOL(_mcount);
 #endif
 #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
 EXPORT_SYMBOL(sie64a);
+EXPORT_SYMBOL(sie_exit);
 #endif
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/setup.c
--- linux-libre-3.10-gnu/arch/s390/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -719,10 +719,6 @@ static void reserve_oldmem(void)
 	}
 	create_mem_hole(memory_chunk, OLDMEM_BASE, OLDMEM_SIZE);
 	create_mem_hole(memory_chunk, OLDMEM_SIZE, real_size - OLDMEM_SIZE);
-	if (OLDMEM_BASE + OLDMEM_SIZE == real_size)
-		saved_max_pfn = PFN_DOWN(OLDMEM_BASE) - 1;
-	else
-		saved_max_pfn = PFN_DOWN(real_size) - 1;
 #endif
 }
 
@@ -998,6 +994,7 @@ static void __init setup_hwcaps(void)
 		strcpy(elf_platform, "z196");
 		break;
 	case 0x2827:
+	case 0x2828:
 		strcpy(elf_platform, "zEC12");
 		break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/smp.c
--- linux-libre-3.10-gnu/arch/s390/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,7 +49,6 @@
 
 enum {
 	ec_schedule = 0,
-	ec_call_function,
 	ec_call_function_single,
 	ec_stop_cpu,
 };
@@ -166,7 +165,7 @@ static void pcpu_ec_call(struct pcpu *pc
 	pcpu_sigp_retry(pcpu, order, 0);
 }
 
-static int __cpuinit pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
+static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
 {
 	struct _lowcore *lc;
 
@@ -438,8 +437,6 @@ static void smp_handle_ext_call(void)
 		smp_stop_cpu();
 	if (test_bit(ec_schedule, &bits))
 		scheduler_ipi();
-	if (test_bit(ec_call_function, &bits))
-		generic_smp_call_function_interrupt();
 	if (test_bit(ec_call_function_single, &bits))
 		generic_smp_call_function_single_interrupt();
 }
@@ -456,7 +453,7 @@ void arch_send_call_function_ipi_mask(co
 	int cpu;
 
 	for_each_cpu(cpu, mask)
-		pcpu_ec_call(pcpu_devices + cpu, ec_call_function);
+		pcpu_ec_call(pcpu_devices + cpu, ec_call_function_single);
 }
 
 void arch_send_call_function_single_ipi(int cpu)
@@ -619,10 +616,9 @@ static struct sclp_cpu_info *smp_get_cpu
 	return info;
 }
 
-static int __cpuinit smp_add_present_cpu(int cpu);
+static int smp_add_present_cpu(int cpu);
 
-static int __cpuinit __smp_rescan_cpus(struct sclp_cpu_info *info,
-				       int sysfs_add)
+static int __smp_rescan_cpus(struct sclp_cpu_info *info, int sysfs_add)
 {
 	struct pcpu *pcpu;
 	cpumask_t avail;
@@ -688,7 +684,7 @@ static void __init smp_detect_cpus(void)
 /*
  *	Activate a secondary processor.
  */
-static void __cpuinit smp_start_secondary(void *cpuvoid)
+static void smp_start_secondary(void *cpuvoid)
 {
 	S390_lowcore.last_update_clock = get_tod_clock();
 	S390_lowcore.restart_stack = (unsigned long) restart_stack;
@@ -711,7 +707,7 @@ static void __cpuinit smp_start_secondar
 }
 
 /* Upping and downing of CPUs */
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	struct pcpu *pcpu;
 	int rc;
@@ -967,8 +963,8 @@ static struct attribute_group cpu_online
 	.attrs = cpu_online_attrs,
 };
 
-static int __cpuinit smp_cpu_notify(struct notifier_block *self,
-				    unsigned long action, void *hcpu)
+static int smp_cpu_notify(struct notifier_block *self, unsigned long action,
+			  void *hcpu)
 {
 	unsigned int cpu = (unsigned int)(long)hcpu;
 	struct cpu *c = &pcpu_devices[cpu].cpu;
@@ -986,7 +982,7 @@ static int __cpuinit smp_cpu_notify(stru
 	return notifier_from_errno(err);
 }
 
-static int __cpuinit smp_add_present_cpu(int cpu)
+static int smp_add_present_cpu(int cpu)
 {
 	struct cpu *c = &pcpu_devices[cpu].cpu;
 	struct device *s = &c->dev;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/sysinfo.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/sysinfo.c
--- linux-libre-3.10-gnu/arch/s390/kernel/sysinfo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/sysinfo.c	2013-08-25 20:43:22.000000000 -0400
@@ -418,7 +418,7 @@ void s390_adjust_jiffies(void)
 /*
  * calibrate the delay loop
  */
-void __cpuinit calibrate_delay(void)
+void calibrate_delay(void)
 {
 	s390_adjust_jiffies();
 	/* Print the good old Bogomips line .. */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kernel/vtime.c linux-libre-3.11-rc7-gnu/arch/s390/kernel/vtime.c
--- linux-libre-3.10-gnu/arch/s390/kernel/vtime.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kernel/vtime.c	2013-08-25 20:43:22.000000000 -0400
@@ -371,14 +371,14 @@ EXPORT_SYMBOL(del_virt_timer);
 /*
  * Start the virtual CPU timer on the current CPU.
  */
-void __cpuinit init_cpu_vtimer(void)
+void init_cpu_vtimer(void)
 {
 	/* set initial cpu timer */
 	set_vtimer(VTIMER_MAX_SLICE);
 }
 
-static int __cpuinit s390_nohz_notify(struct notifier_block *self,
-				      unsigned long action, void *hcpu)
+static int s390_nohz_notify(struct notifier_block *self, unsigned long action,
+			    void *hcpu)
 {
 	struct s390_idle_data *idle;
 	long cpu = (long) hcpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kvm/diag.c linux-libre-3.11-rc7-gnu/arch/s390/kvm/diag.c
--- linux-libre-3.10-gnu/arch/s390/kvm/diag.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kvm/diag.c	2013-08-25 20:43:22.000000000 -0400
@@ -132,6 +132,9 @@ int kvm_s390_handle_diag(struct kvm_vcpu
 {
 	int code = (vcpu->arch.sie_block->ipb & 0xfff0000) >> 16;
 
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	trace_kvm_s390_handle_diag(vcpu, code);
 	switch (code) {
 	case 0x10:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kvm/intercept.c linux-libre-3.11-rc7-gnu/arch/s390/kvm/intercept.c
--- linux-libre-3.10-gnu/arch/s390/kvm/intercept.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kvm/intercept.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,87 +22,6 @@
 #include "trace.h"
 #include "trace-s390.h"
 
-static int handle_lctlg(struct kvm_vcpu *vcpu)
-{
-	int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
-	int reg3 = vcpu->arch.sie_block->ipa & 0x000f;
-	u64 useraddr;
-	int reg, rc;
-
-	vcpu->stat.instruction_lctlg++;
-
-	useraddr = kvm_s390_get_base_disp_rsy(vcpu);
-
-	if (useraddr & 7)
-		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
-
-	reg = reg1;
-
-	VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x, addr:%llx", reg1, reg3,
-		   useraddr);
-	trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, useraddr);
-
-	do {
-		rc = get_guest(vcpu, vcpu->arch.sie_block->gcr[reg],
-			       (u64 __user *) useraddr);
-		if (rc)
-			return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
-		useraddr += 8;
-		if (reg == reg3)
-			break;
-		reg = (reg + 1) % 16;
-	} while (1);
-	return 0;
-}
-
-static int handle_lctl(struct kvm_vcpu *vcpu)
-{
-	int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
-	int reg3 = vcpu->arch.sie_block->ipa & 0x000f;
-	u64 useraddr;
-	u32 val = 0;
-	int reg, rc;
-
-	vcpu->stat.instruction_lctl++;
-
-	useraddr = kvm_s390_get_base_disp_rs(vcpu);
-
-	if (useraddr & 3)
-		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
-
-	VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x, addr:%llx", reg1, reg3,
-		   useraddr);
-	trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, useraddr);
-
-	reg = reg1;
-	do {
-		rc = get_guest(vcpu, val, (u32 __user *) useraddr);
-		if (rc)
-			return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
-		vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul;
-		vcpu->arch.sie_block->gcr[reg] |= val;
-		useraddr += 4;
-		if (reg == reg3)
-			break;
-		reg = (reg + 1) % 16;
-	} while (1);
-	return 0;
-}
-
-static const intercept_handler_t eb_handlers[256] = {
-	[0x2f] = handle_lctlg,
-	[0x8a] = kvm_s390_handle_priv_eb,
-};
-
-static int handle_eb(struct kvm_vcpu *vcpu)
-{
-	intercept_handler_t handler;
-
-	handler = eb_handlers[vcpu->arch.sie_block->ipb & 0xff];
-	if (handler)
-		return handler(vcpu);
-	return -EOPNOTSUPP;
-}
 
 static const intercept_handler_t instruction_handlers[256] = {
 	[0x01] = kvm_s390_handle_01,
@@ -110,10 +29,10 @@ static const intercept_handler_t instruc
 	[0x83] = kvm_s390_handle_diag,
 	[0xae] = kvm_s390_handle_sigp,
 	[0xb2] = kvm_s390_handle_b2,
-	[0xb7] = handle_lctl,
+	[0xb7] = kvm_s390_handle_lctl,
 	[0xb9] = kvm_s390_handle_b9,
 	[0xe5] = kvm_s390_handle_e5,
-	[0xeb] = handle_eb,
+	[0xeb] = kvm_s390_handle_eb,
 };
 
 static int handle_noop(struct kvm_vcpu *vcpu)
@@ -174,47 +93,12 @@ static int handle_stop(struct kvm_vcpu *
 
 static int handle_validity(struct kvm_vcpu *vcpu)
 {
-	unsigned long vmaddr;
 	int viwhy = vcpu->arch.sie_block->ipb >> 16;
-	int rc;
 
 	vcpu->stat.exit_validity++;
 	trace_kvm_s390_intercept_validity(vcpu, viwhy);
-	if (viwhy == 0x37) {
-		vmaddr = gmap_fault(vcpu->arch.sie_block->prefix,
-				    vcpu->arch.gmap);
-		if (IS_ERR_VALUE(vmaddr)) {
-			rc = -EOPNOTSUPP;
-			goto out;
-		}
-		rc = fault_in_pages_writeable((char __user *) vmaddr,
-			 PAGE_SIZE);
-		if (rc) {
-			/* user will receive sigsegv, exit to user */
-			rc = -EOPNOTSUPP;
-			goto out;
-		}
-		vmaddr = gmap_fault(vcpu->arch.sie_block->prefix + PAGE_SIZE,
-				    vcpu->arch.gmap);
-		if (IS_ERR_VALUE(vmaddr)) {
-			rc = -EOPNOTSUPP;
-			goto out;
-		}
-		rc = fault_in_pages_writeable((char __user *) vmaddr,
-			 PAGE_SIZE);
-		if (rc) {
-			/* user will receive sigsegv, exit to user */
-			rc = -EOPNOTSUPP;
-			goto out;
-		}
-	} else
-		rc = -EOPNOTSUPP;
-
-out:
-	if (rc)
-		VCPU_EVENT(vcpu, 2, "unhandled validity intercept code %d",
-			   viwhy);
-	return rc;
+	WARN_ONCE(true, "kvm: unhandled validity intercept 0x%x\n", viwhy);
+	return -EOPNOTSUPP;
 }
 
 static int handle_instruction(struct kvm_vcpu *vcpu)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kvm/interrupt.c linux-libre-3.11-rc7-gnu/arch/s390/kvm/interrupt.c
--- linux-libre-3.10-gnu/arch/s390/kvm/interrupt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kvm/interrupt.c	2013-08-25 20:43:22.000000000 -0400
@@ -438,7 +438,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu
 no_timer:
 	spin_lock(&vcpu->arch.local_int.float_int->lock);
 	spin_lock_bh(&vcpu->arch.local_int.lock);
-	add_wait_queue(&vcpu->arch.local_int.wq, &wait);
+	add_wait_queue(&vcpu->wq, &wait);
 	while (list_empty(&vcpu->arch.local_int.list) &&
 		list_empty(&vcpu->arch.local_int.float_int->list) &&
 		(!vcpu->arch.local_int.timer_due) &&
@@ -452,7 +452,7 @@ no_timer:
 	}
 	__unset_cpu_idle(vcpu);
 	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&vcpu->arch.local_int.wq, &wait);
+	remove_wait_queue(&vcpu->wq, &wait);
 	spin_unlock_bh(&vcpu->arch.local_int.lock);
 	spin_unlock(&vcpu->arch.local_int.float_int->lock);
 	hrtimer_try_to_cancel(&vcpu->arch.ckc_timer);
@@ -465,8 +465,8 @@ void kvm_s390_tasklet(unsigned long parm
 
 	spin_lock(&vcpu->arch.local_int.lock);
 	vcpu->arch.local_int.timer_due = 1;
-	if (waitqueue_active(&vcpu->arch.local_int.wq))
-		wake_up_interruptible(&vcpu->arch.local_int.wq);
+	if (waitqueue_active(&vcpu->wq))
+		wake_up_interruptible(&vcpu->wq);
 	spin_unlock(&vcpu->arch.local_int.lock);
 }
 
@@ -613,7 +613,7 @@ int kvm_s390_inject_program_int(struct k
 	spin_lock_bh(&li->lock);
 	list_add(&inti->list, &li->list);
 	atomic_set(&li->active, 1);
-	BUG_ON(waitqueue_active(&li->wq));
+	BUG_ON(waitqueue_active(li->wq));
 	spin_unlock_bh(&li->lock);
 	return 0;
 }
@@ -746,8 +746,8 @@ int kvm_s390_inject_vm(struct kvm *kvm,
 	li = fi->local_int[sigcpu];
 	spin_lock_bh(&li->lock);
 	atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 	spin_unlock_bh(&li->lock);
 	spin_unlock(&fi->lock);
 	mutex_unlock(&kvm->lock);
@@ -832,8 +832,8 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu
 	if (inti->type == KVM_S390_SIGP_STOP)
 		li->action_bits |= ACTION_STOP_ON_STOP;
 	atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&vcpu->arch.local_int.wq);
+	if (waitqueue_active(&vcpu->wq))
+		wake_up_interruptible(&vcpu->wq);
 	spin_unlock_bh(&li->lock);
 	mutex_unlock(&vcpu->kvm->lock);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kvm/kvm-s390.c linux-libre-3.11-rc7-gnu/arch/s390/kvm/kvm-s390.c
--- linux-libre-3.10-gnu/arch/s390/kvm/kvm-s390.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kvm/kvm-s390.c	2013-08-25 20:43:22.000000000 -0400
@@ -59,6 +59,7 @@ struct kvm_stats_debugfs_item debugfs_en
 	{ "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
 	{ "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
 	{ "exit_wait_state", VCPU_STAT(exit_wait_state) },
+	{ "instruction_pfmf", VCPU_STAT(instruction_pfmf) },
 	{ "instruction_stidp", VCPU_STAT(instruction_stidp) },
 	{ "instruction_spx", VCPU_STAT(instruction_spx) },
 	{ "instruction_stpx", VCPU_STAT(instruction_stpx) },
@@ -84,6 +85,7 @@ struct kvm_stats_debugfs_item debugfs_en
 };
 
 static unsigned long long *facilities;
+static struct gmap_notifier gmap_notifier;
 
 /* Section: not file related */
 int kvm_arch_hardware_enable(void *garbage)
@@ -96,13 +98,18 @@ void kvm_arch_hardware_disable(void *gar
 {
 }
 
+static void kvm_gmap_notifier(struct gmap *gmap, unsigned long address);
+
 int kvm_arch_hardware_setup(void)
 {
+	gmap_notifier.notifier_call = kvm_gmap_notifier;
+	gmap_register_ipte_notifier(&gmap_notifier);
 	return 0;
 }
 
 void kvm_arch_hardware_unsetup(void)
 {
+	gmap_unregister_ipte_notifier(&gmap_notifier);
 }
 
 void kvm_arch_check_processor_compat(void *rtn)
@@ -239,6 +246,7 @@ int kvm_arch_init_vm(struct kvm *kvm, un
 		kvm->arch.gmap = gmap_alloc(current->mm);
 		if (!kvm->arch.gmap)
 			goto out_nogmap;
+		kvm->arch.gmap->private = kvm;
 	}
 
 	kvm->arch.css_support = 0;
@@ -270,7 +278,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vc
 
 	free_page((unsigned long)(vcpu->arch.sie_block));
 	kvm_vcpu_uninit(vcpu);
-	kfree(vcpu);
+	kmem_cache_free(kvm_vcpu_cache, vcpu);
 }
 
 static void kvm_free_vcpus(struct kvm *kvm)
@@ -309,6 +317,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
 		vcpu->arch.gmap = gmap_alloc(current->mm);
 		if (!vcpu->arch.gmap)
 			return -ENOMEM;
+		vcpu->arch.gmap->private = vcpu->kvm;
 		return 0;
 	}
 
@@ -373,8 +382,10 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu
 {
 	atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
 						    CPUSTAT_SM |
-						    CPUSTAT_STOPPED);
+						    CPUSTAT_STOPPED |
+						    CPUSTAT_GED);
 	vcpu->arch.sie_block->ecb   = 6;
+	vcpu->arch.sie_block->ecb2  = 8;
 	vcpu->arch.sie_block->eca   = 0xC1002001U;
 	vcpu->arch.sie_block->fac   = (int) (long) facilities;
 	hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
@@ -397,7 +408,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 
 	rc = -ENOMEM;
 
-	vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
+	vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
 	if (!vcpu)
 		goto out;
 
@@ -427,7 +438,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 	vcpu->arch.local_int.float_int = &kvm->arch.float_int;
 	spin_lock(&kvm->arch.float_int.lock);
 	kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
-	init_waitqueue_head(&vcpu->arch.local_int.wq);
+	vcpu->arch.local_int.wq = &vcpu->wq;
 	vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
 	spin_unlock(&kvm->arch.float_int.lock);
 
@@ -442,7 +453,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(st
 out_free_sie_block:
 	free_page((unsigned long)(vcpu->arch.sie_block));
 out_free_cpu:
-	kfree(vcpu);
+	kmem_cache_free(kvm_vcpu_cache, vcpu);
 out:
 	return ERR_PTR(rc);
 }
@@ -454,6 +465,50 @@ int kvm_arch_vcpu_runnable(struct kvm_vc
 	return 0;
 }
 
+void s390_vcpu_block(struct kvm_vcpu *vcpu)
+{
+	atomic_set_mask(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20);
+}
+
+void s390_vcpu_unblock(struct kvm_vcpu *vcpu)
+{
+	atomic_clear_mask(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20);
+}
+
+/*
+ * Kick a guest cpu out of SIE and wait until SIE is not running.
+ * If the CPU is not running (e.g. waiting as idle) the function will
+ * return immediately. */
+void exit_sie(struct kvm_vcpu *vcpu)
+{
+	atomic_set_mask(CPUSTAT_STOP_INT, &vcpu->arch.sie_block->cpuflags);
+	while (vcpu->arch.sie_block->prog0c & PROG_IN_SIE)
+		cpu_relax();
+}
+
+/* Kick a guest cpu out of SIE and prevent SIE-reentry */
+void exit_sie_sync(struct kvm_vcpu *vcpu)
+{
+	s390_vcpu_block(vcpu);
+	exit_sie(vcpu);
+}
+
+static void kvm_gmap_notifier(struct gmap *gmap, unsigned long address)
+{
+	int i;
+	struct kvm *kvm = gmap->private;
+	struct kvm_vcpu *vcpu;
+
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		/* match against both prefix pages */
+		if (vcpu->arch.sie_block->prefix == (address & ~0x1000UL)) {
+			VCPU_EVENT(vcpu, 2, "gmap notifier for %lx", address);
+			kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu);
+			exit_sie_sync(vcpu);
+		}
+	}
+}
+
 int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
 {
 	/* kvm common code refers to this, but never calls it */
@@ -606,6 +661,27 @@ int kvm_arch_vcpu_ioctl_set_mpstate(stru
 	return -EINVAL; /* not implemented yet */
 }
 
+static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * We use MMU_RELOAD just to re-arm the ipte notifier for the
+	 * guest prefix page. gmap_ipte_notify will wait on the ptl lock.
+	 * This ensures that the ipte instruction for this request has
+	 * already finished. We might race against a second unmapper that
+	 * wants to set the blocking bit. Lets just retry the request loop.
+	 */
+	while (kvm_check_request(KVM_REQ_MMU_RELOAD, vcpu)) {
+		int rc;
+		rc = gmap_ipte_notify(vcpu->arch.gmap,
+				      vcpu->arch.sie_block->prefix,
+				      PAGE_SIZE * 2);
+		if (rc)
+			return rc;
+		s390_vcpu_unblock(vcpu);
+	}
+	return 0;
+}
+
 static int __vcpu_run(struct kvm_vcpu *vcpu)
 {
 	int rc;
@@ -621,16 +697,33 @@ static int __vcpu_run(struct kvm_vcpu *v
 	if (!kvm_is_ucontrol(vcpu->kvm))
 		kvm_s390_deliver_pending_interrupts(vcpu);
 
+	rc = kvm_s390_handle_requests(vcpu);
+	if (rc)
+		return rc;
+
 	vcpu->arch.sie_block->icptcode = 0;
-	preempt_disable();
-	kvm_guest_enter();
-	preempt_enable();
 	VCPU_EVENT(vcpu, 6, "entering sie flags %x",
 		   atomic_read(&vcpu->arch.sie_block->cpuflags));
 	trace_kvm_s390_sie_enter(vcpu,
 				 atomic_read(&vcpu->arch.sie_block->cpuflags));
+
+	/*
+	 * As PF_VCPU will be used in fault handler, between guest_enter
+	 * and guest_exit should be no uaccess.
+	 */
+	preempt_disable();
+	kvm_guest_enter();
+	preempt_enable();
 	rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
-	if (rc) {
+	kvm_guest_exit();
+
+	VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
+		   vcpu->arch.sie_block->icptcode);
+	trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode);
+
+	if (rc > 0)
+		rc = 0;
+	if (rc < 0) {
 		if (kvm_is_ucontrol(vcpu->kvm)) {
 			rc = SIE_INTERCEPT_UCONTROL;
 		} else {
@@ -639,10 +732,6 @@ static int __vcpu_run(struct kvm_vcpu *v
 			rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
 		}
 	}
-	VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
-		   vcpu->arch.sie_block->icptcode);
-	trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode);
-	kvm_guest_exit();
 
 	memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
 	return rc;
@@ -1046,7 +1135,7 @@ static int __init kvm_s390_init(void)
 		return -ENOMEM;
 	}
 	memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
-	facilities[0] &= 0xff00fff3f47c0000ULL;
+	facilities[0] &= 0xff82fff3f47c0000ULL;
 	facilities[1] &= 0x001c000000000000ULL;
 	return 0;
 }
@@ -1059,3 +1148,12 @@ static void __exit kvm_s390_exit(void)
 
 module_init(kvm_s390_init);
 module_exit(kvm_s390_exit);
+
+/*
+ * Enable autoloading of the kvm module.
+ * Note that we add the module alias here instead of virt/kvm/kvm_main.c
+ * since x86 takes a different approach.
+ */
+#include <linux/miscdevice.h>
+MODULE_ALIAS_MISCDEV(KVM_MINOR);
+MODULE_ALIAS("devname:kvm");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kvm/kvm-s390.h linux-libre-3.11-rc7-gnu/arch/s390/kvm/kvm-s390.h
--- linux-libre-3.10-gnu/arch/s390/kvm/kvm-s390.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kvm/kvm-s390.h	2013-08-25 20:43:22.000000000 -0400
@@ -63,6 +63,7 @@ static inline void kvm_s390_set_prefix(s
 {
 	vcpu->arch.sie_block->prefix = prefix & 0x7fffe000u;
 	vcpu->arch.sie_block->ihcpu  = 0xffff;
+	kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu);
 }
 
 static inline u64 kvm_s390_get_base_disp_s(struct kvm_vcpu *vcpu)
@@ -85,6 +86,12 @@ static inline void kvm_s390_get_base_dis
 	*address2 = (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2;
 }
 
+static inline void kvm_s390_get_regs_rre(struct kvm_vcpu *vcpu, int *r1, int *r2)
+{
+	*r1 = (vcpu->arch.sie_block->ipb & 0x00f00000) >> 20;
+	*r2 = (vcpu->arch.sie_block->ipb & 0x000f0000) >> 16;
+}
+
 static inline u64 kvm_s390_get_base_disp_rsy(struct kvm_vcpu *vcpu)
 {
 	u32 base2 = vcpu->arch.sie_block->ipb >> 28;
@@ -125,7 +132,8 @@ int kvm_s390_handle_e5(struct kvm_vcpu *
 int kvm_s390_handle_01(struct kvm_vcpu *vcpu);
 int kvm_s390_handle_b9(struct kvm_vcpu *vcpu);
 int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu);
-int kvm_s390_handle_priv_eb(struct kvm_vcpu *vcpu);
+int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu);
+int kvm_s390_handle_eb(struct kvm_vcpu *vcpu);
 
 /* implemented in sigp.c */
 int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
@@ -133,6 +141,10 @@ int kvm_s390_handle_sigp(struct kvm_vcpu
 /* implemented in kvm-s390.c */
 int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu,
 				 unsigned long addr);
+void s390_vcpu_block(struct kvm_vcpu *vcpu);
+void s390_vcpu_unblock(struct kvm_vcpu *vcpu);
+void exit_sie(struct kvm_vcpu *vcpu);
+void exit_sie_sync(struct kvm_vcpu *vcpu);
 /* implemented in diag.c */
 int kvm_s390_handle_diag(struct kvm_vcpu *vcpu);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kvm/Makefile linux-libre-3.11-rc7-gnu/arch/s390/kvm/Makefile
--- linux-libre-3.10-gnu/arch/s390/kvm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kvm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,8 @@
 # it under the terms of the GNU General Public License (version 2 only)
 # as published by the Free Software Foundation.
 
-common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o eventfd.o)
+KVM := ../../../virt/kvm
+common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o
 
 ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kvm/priv.c linux-libre-3.11-rc7-gnu/arch/s390/kvm/priv.c
--- linux-libre-3.10-gnu/arch/s390/kvm/priv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kvm/priv.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * handling privileged instructions
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008, 2013
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -16,10 +16,14 @@
 #include <linux/errno.h>
 #include <linux/compat.h>
 #include <asm/asm-offsets.h>
+#include <asm/facility.h>
 #include <asm/current.h>
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
 #include <asm/sysinfo.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
 #include <asm/ptrace.h>
 #include <asm/compat.h>
 #include "gaccess.h"
@@ -34,6 +38,9 @@ static int handle_set_prefix(struct kvm_
 
 	vcpu->stat.instruction_spx++;
 
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	operand2 = kvm_s390_get_base_disp_s(vcpu);
 
 	/* must be word boundary */
@@ -65,6 +72,9 @@ static int handle_store_prefix(struct kv
 
 	vcpu->stat.instruction_stpx++;
 
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	operand2 = kvm_s390_get_base_disp_s(vcpu);
 
 	/* must be word boundary */
@@ -89,6 +99,9 @@ static int handle_store_cpu_address(stru
 
 	vcpu->stat.instruction_stap++;
 
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	useraddr = kvm_s390_get_base_disp_s(vcpu);
 
 	if (useraddr & 1)
@@ -105,7 +118,12 @@ static int handle_store_cpu_address(stru
 static int handle_skey(struct kvm_vcpu *vcpu)
 {
 	vcpu->stat.instruction_storage_key++;
-	vcpu->arch.sie_block->gpsw.addr -= 4;
+
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
+	vcpu->arch.sie_block->gpsw.addr =
+		__rewind_psw(vcpu->arch.sie_block->gpsw, 4);
 	VCPU_EVENT(vcpu, 4, "%s", "retrying storage key operation");
 	return 0;
 }
@@ -129,9 +147,10 @@ static int handle_tpi(struct kvm_vcpu *v
 		 * Store the two-word I/O interruption code into the
 		 * provided area.
 		 */
-		put_guest(vcpu, inti->io.subchannel_id, (u16 __user *) addr);
-		put_guest(vcpu, inti->io.subchannel_nr, (u16 __user *) (addr + 2));
-		put_guest(vcpu, inti->io.io_int_parm, (u32 __user *) (addr + 4));
+		if (put_guest(vcpu, inti->io.subchannel_id, (u16 __user *)addr)
+		    || put_guest(vcpu, inti->io.subchannel_nr, (u16 __user *)(addr + 2))
+		    || put_guest(vcpu, inti->io.io_int_parm, (u32 __user *)(addr + 4)))
+			return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
 	} else {
 		/*
 		 * Store the three-word I/O interruption code into
@@ -182,6 +201,9 @@ static int handle_io_inst(struct kvm_vcp
 {
 	VCPU_EVENT(vcpu, 4, "%s", "I/O instruction");
 
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	if (vcpu->kvm->arch.css_support) {
 		/*
 		 * Most I/O instructions will be handled by userspace.
@@ -210,8 +232,12 @@ static int handle_stfl(struct kvm_vcpu *
 	int rc;
 
 	vcpu->stat.instruction_stfl++;
+
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	/* only pass the facility bits, which we can handle */
-	facility_list = S390_lowcore.stfl_fac_list & 0xff00fff3;
+	facility_list = S390_lowcore.stfl_fac_list & 0xff82fff3;
 
 	rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list),
 			   &facility_list, sizeof(facility_list));
@@ -255,8 +281,8 @@ int kvm_s390_handle_lpsw(struct kvm_vcpu
 	u64 addr;
 
 	if (gpsw->mask & PSW_MASK_PSTATE)
-		return kvm_s390_inject_program_int(vcpu,
-						   PGM_PRIVILEGED_OPERATION);
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	addr = kvm_s390_get_base_disp_s(vcpu);
 	if (addr & 7)
 		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
@@ -278,6 +304,9 @@ static int handle_lpswe(struct kvm_vcpu
 	psw_t new_psw;
 	u64 addr;
 
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	addr = kvm_s390_get_base_disp_s(vcpu);
 	if (addr & 7)
 		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
@@ -296,6 +325,9 @@ static int handle_stidp(struct kvm_vcpu
 
 	vcpu->stat.instruction_stidp++;
 
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	operand2 = kvm_s390_get_base_disp_s(vcpu);
 
 	if (operand2 & 7)
@@ -351,16 +383,30 @@ static int handle_stsi(struct kvm_vcpu *
 	vcpu->stat.instruction_stsi++;
 	VCPU_EVENT(vcpu, 4, "stsi: fc: %x sel1: %x sel2: %x", fc, sel1, sel2);
 
-	operand2 = kvm_s390_get_base_disp_s(vcpu);
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
-	if (operand2 & 0xfff && fc > 0)
+	if (fc > 3) {
+		vcpu->arch.sie_block->gpsw.mask |= 3ul << 44;	  /* cc 3 */
+		return 0;
+	}
+
+	if (vcpu->run->s.regs.gprs[0] & 0x0fffff00
+	    || vcpu->run->s.regs.gprs[1] & 0xffff0000)
 		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
 
-	switch (fc) {
-	case 0:
+	if (fc == 0) {
 		vcpu->run->s.regs.gprs[0] = 3 << 28;
-		vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
+		vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);  /* cc 0 */
 		return 0;
+	}
+
+	operand2 = kvm_s390_get_base_disp_s(vcpu);
+
+	if (operand2 & 0xfff)
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	switch (fc) {
 	case 1: /* same handling for 1 and 2 */
 	case 2:
 		mem = get_zeroed_page(GFP_KERNEL);
@@ -377,8 +423,6 @@ static int handle_stsi(struct kvm_vcpu *
 			goto out_no_data;
 		handle_stsi_3_2_2(vcpu, (void *) mem);
 		break;
-	default:
-		goto out_no_data;
 	}
 
 	if (copy_to_guest_absolute(vcpu, operand2, (void *) mem, PAGE_SIZE)) {
@@ -432,20 +476,14 @@ int kvm_s390_handle_b2(struct kvm_vcpu *
 	intercept_handler_t handler;
 
 	/*
-	 * a lot of B2 instructions are priviledged. We first check for
-	 * the privileged ones, that we can handle in the kernel. If the
-	 * kernel can handle this instruction, we check for the problem
-	 * state bit and (a) handle the instruction or (b) send a code 2
-	 * program check.
-	 * Anything else goes to userspace.*/
+	 * A lot of B2 instructions are priviledged. Here we check for
+	 * the privileged ones, that we can handle in the kernel.
+	 * Anything else goes to userspace.
+	 */
 	handler = b2_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
-	if (handler) {
-		if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
-			return kvm_s390_inject_program_int(vcpu,
-						   PGM_PRIVILEGED_OPERATION);
-		else
-			return handler(vcpu);
-	}
+	if (handler)
+		return handler(vcpu);
+
 	return -EOPNOTSUPP;
 }
 
@@ -453,8 +491,7 @@ static int handle_epsw(struct kvm_vcpu *
 {
 	int reg1, reg2;
 
-	reg1 = (vcpu->arch.sie_block->ipb & 0x00f00000) >> 24;
-	reg2 = (vcpu->arch.sie_block->ipb & 0x000f0000) >> 16;
+	kvm_s390_get_regs_rre(vcpu, &reg1, &reg2);
 
 	/* This basically extracts the mask half of the psw. */
 	vcpu->run->s.regs.gprs[reg1] &= 0xffffffff00000000;
@@ -467,9 +504,87 @@ static int handle_epsw(struct kvm_vcpu *
 	return 0;
 }
 
+#define PFMF_RESERVED   0xfffc0101UL
+#define PFMF_SK         0x00020000UL
+#define PFMF_CF         0x00010000UL
+#define PFMF_UI         0x00008000UL
+#define PFMF_FSC        0x00007000UL
+#define PFMF_NQ         0x00000800UL
+#define PFMF_MR         0x00000400UL
+#define PFMF_MC         0x00000200UL
+#define PFMF_KEY        0x000000feUL
+
+static int handle_pfmf(struct kvm_vcpu *vcpu)
+{
+	int reg1, reg2;
+	unsigned long start, end;
+
+	vcpu->stat.instruction_pfmf++;
+
+	kvm_s390_get_regs_rre(vcpu, &reg1, &reg2);
+
+	if (!MACHINE_HAS_PFMF)
+		return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
+
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
+	if (vcpu->run->s.regs.gprs[reg1] & PFMF_RESERVED)
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	/* Only provide non-quiescing support if the host supports it */
+	if (vcpu->run->s.regs.gprs[reg1] & PFMF_NQ && !test_facility(14))
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	/* No support for conditional-SSKE */
+	if (vcpu->run->s.regs.gprs[reg1] & (PFMF_MR | PFMF_MC))
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	start = vcpu->run->s.regs.gprs[reg2] & PAGE_MASK;
+	switch (vcpu->run->s.regs.gprs[reg1] & PFMF_FSC) {
+	case 0x00000000:
+		end = (start + (1UL << 12)) & ~((1UL << 12) - 1);
+		break;
+	case 0x00001000:
+		end = (start + (1UL << 20)) & ~((1UL << 20) - 1);
+		break;
+	/* We dont support EDAT2
+	case 0x00002000:
+		end = (start + (1UL << 31)) & ~((1UL << 31) - 1);
+		break;*/
+	default:
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+	}
+	while (start < end) {
+		unsigned long useraddr;
+
+		useraddr = gmap_translate(start, vcpu->arch.gmap);
+		if (IS_ERR((void *)useraddr))
+			return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+
+		if (vcpu->run->s.regs.gprs[reg1] & PFMF_CF) {
+			if (clear_user((void __user *)useraddr, PAGE_SIZE))
+				return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+		}
+
+		if (vcpu->run->s.regs.gprs[reg1] & PFMF_SK) {
+			if (set_guest_storage_key(current->mm, useraddr,
+					vcpu->run->s.regs.gprs[reg1] & PFMF_KEY,
+					vcpu->run->s.regs.gprs[reg1] & PFMF_NQ))
+				return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+		}
+
+		start += PAGE_SIZE;
+	}
+	if (vcpu->run->s.regs.gprs[reg1] & PFMF_FSC)
+		vcpu->run->s.regs.gprs[reg2] = end;
+	return 0;
+}
+
 static const intercept_handler_t b9_handlers[256] = {
 	[0x8d] = handle_epsw,
 	[0x9c] = handle_io_inst,
+	[0xaf] = handle_pfmf,
 };
 
 int kvm_s390_handle_b9(struct kvm_vcpu *vcpu)
@@ -478,29 +593,96 @@ int kvm_s390_handle_b9(struct kvm_vcpu *
 
 	/* This is handled just as for the B2 instructions. */
 	handler = b9_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
-	if (handler) {
-		if ((handler != handle_epsw) &&
-		    (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE))
-			return kvm_s390_inject_program_int(vcpu,
-						   PGM_PRIVILEGED_OPERATION);
-		else
-			return handler(vcpu);
-	}
+	if (handler)
+		return handler(vcpu);
+
 	return -EOPNOTSUPP;
 }
 
+int kvm_s390_handle_lctl(struct kvm_vcpu *vcpu)
+{
+	int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
+	int reg3 = vcpu->arch.sie_block->ipa & 0x000f;
+	u64 useraddr;
+	u32 val = 0;
+	int reg, rc;
+
+	vcpu->stat.instruction_lctl++;
+
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
+	useraddr = kvm_s390_get_base_disp_rs(vcpu);
+
+	if (useraddr & 3)
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	VCPU_EVENT(vcpu, 5, "lctl r1:%x, r3:%x, addr:%llx", reg1, reg3,
+		   useraddr);
+	trace_kvm_s390_handle_lctl(vcpu, 0, reg1, reg3, useraddr);
+
+	reg = reg1;
+	do {
+		rc = get_guest(vcpu, val, (u32 __user *) useraddr);
+		if (rc)
+			return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+		vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul;
+		vcpu->arch.sie_block->gcr[reg] |= val;
+		useraddr += 4;
+		if (reg == reg3)
+			break;
+		reg = (reg + 1) % 16;
+	} while (1);
+
+	return 0;
+}
+
+static int handle_lctlg(struct kvm_vcpu *vcpu)
+{
+	int reg1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
+	int reg3 = vcpu->arch.sie_block->ipa & 0x000f;
+	u64 useraddr;
+	int reg, rc;
+
+	vcpu->stat.instruction_lctlg++;
+
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
+	useraddr = kvm_s390_get_base_disp_rsy(vcpu);
+
+	if (useraddr & 7)
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	reg = reg1;
+
+	VCPU_EVENT(vcpu, 5, "lctlg r1:%x, r3:%x, addr:%llx", reg1, reg3,
+		   useraddr);
+	trace_kvm_s390_handle_lctl(vcpu, 1, reg1, reg3, useraddr);
+
+	do {
+		rc = get_guest(vcpu, vcpu->arch.sie_block->gcr[reg],
+			       (u64 __user *) useraddr);
+		if (rc)
+			return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+		useraddr += 8;
+		if (reg == reg3)
+			break;
+		reg = (reg + 1) % 16;
+	} while (1);
+
+	return 0;
+}
+
 static const intercept_handler_t eb_handlers[256] = {
+	[0x2f] = handle_lctlg,
 	[0x8a] = handle_io_inst,
 };
 
-int kvm_s390_handle_priv_eb(struct kvm_vcpu *vcpu)
+int kvm_s390_handle_eb(struct kvm_vcpu *vcpu)
 {
 	intercept_handler_t handler;
 
-	/* All eb instructions that end up here are privileged. */
-	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
-		return kvm_s390_inject_program_int(vcpu,
-						   PGM_PRIVILEGED_OPERATION);
 	handler = eb_handlers[vcpu->arch.sie_block->ipb & 0xff];
 	if (handler)
 		return handler(vcpu);
@@ -515,6 +697,9 @@ static int handle_tprot(struct kvm_vcpu
 
 	vcpu->stat.instruction_tprot++;
 
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
 	kvm_s390_get_base_disp_sse(vcpu, &address1, &address2);
 
 	/* we only handle the Linux memory detection case:
@@ -560,8 +745,7 @@ static int handle_sckpf(struct kvm_vcpu
 	u32 value;
 
 	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
-		return kvm_s390_inject_program_int(vcpu,
-						   PGM_PRIVILEGED_OPERATION);
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
 	if (vcpu->run->s.regs.gprs[0] & 0x00000000ffff0000)
 		return kvm_s390_inject_program_int(vcpu,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/kvm/sigp.c linux-libre-3.11-rc7-gnu/arch/s390/kvm/sigp.c
--- linux-libre-3.10-gnu/arch/s390/kvm/sigp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/kvm/sigp.c	2013-08-25 20:43:22.000000000 -0400
@@ -79,8 +79,8 @@ static int __sigp_emergency(struct kvm_v
 	list_add_tail(&inti->list, &li->list);
 	atomic_set(&li->active, 1);
 	atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 	spin_unlock_bh(&li->lock);
 	rc = SIGP_CC_ORDER_CODE_ACCEPTED;
 	VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", cpu_addr);
@@ -117,8 +117,8 @@ static int __sigp_external_call(struct k
 	list_add_tail(&inti->list, &li->list);
 	atomic_set(&li->active, 1);
 	atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 	spin_unlock_bh(&li->lock);
 	rc = SIGP_CC_ORDER_CODE_ACCEPTED;
 	VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x", cpu_addr);
@@ -145,8 +145,8 @@ static int __inject_sigp_stop(struct kvm
 	atomic_set(&li->active, 1);
 	atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
 	li->action_bits |= action;
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 out:
 	spin_unlock_bh(&li->lock);
 
@@ -250,8 +250,8 @@ static int __sigp_set_prefix(struct kvm_
 
 	list_add_tail(&inti->list, &li->list);
 	atomic_set(&li->active, 1);
-	if (waitqueue_active(&li->wq))
-		wake_up_interruptible(&li->wq);
+	if (waitqueue_active(li->wq))
+		wake_up_interruptible(li->wq);
 	rc = SIGP_CC_ORDER_CODE_ACCEPTED;
 
 	VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", cpu_addr, address);
@@ -333,8 +333,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu
 
 	/* sigp in userspace can exit */
 	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
-		return kvm_s390_inject_program_int(vcpu,
-						   PGM_PRIVILEGED_OPERATION);
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
 
 	order_code = kvm_s390_get_base_disp_rs(vcpu);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/mm/fault.c linux-libre-3.11-rc7-gnu/arch/s390/mm/fault.c
--- linux-libre-3.10-gnu/arch/s390/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -639,8 +639,8 @@ out:
 	put_task_struct(tsk);
 }
 
-static int __cpuinit pfault_cpu_notify(struct notifier_block *self,
-				       unsigned long action, void *hcpu)
+static int pfault_cpu_notify(struct notifier_block *self, unsigned long action,
+			     void *hcpu)
 {
 	struct thread_struct *thread, *next;
 	struct task_struct *tsk;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/mm/init.c linux-libre-3.11-rc7-gnu/arch/s390/mm/init.c
--- linux-libre-3.10-gnu/arch/s390/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -69,6 +69,7 @@ static void __init setup_zero_pages(void
 		order = 2;
 		break;
 	case 0x2827:	/* zEC12 */
+	case 0x2828:	/* zEC12 */
 	default:
 		order = 5;
 		break;
@@ -135,30 +136,17 @@ void __init paging_init(void)
 
 void __init mem_init(void)
 {
-	unsigned long codesize, reservedpages, datasize, initsize;
-
-        max_mapnr = num_physpages = max_low_pfn;
+        max_mapnr = max_low_pfn;
         high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
 	/* Setup guest page hinting */
 	cmma_init();
 
 	/* this will put all low memory onto the freelists */
-	totalram_pages += free_all_bootmem();
+	free_all_bootmem();
 	setup_zero_pages();	/* Setup zeroed pages. */
 
-	reservedpages = 0;
-
-	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-        printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, %ldk data, %ldk init)\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-                max_mapnr << (PAGE_SHIFT-10),
-                codesize >> 10,
-                reservedpages << (PAGE_SHIFT-10),
-                datasize >>10,
-                initsize >> 10);
+	mem_init_print_info(NULL);
 	printk("Write protected kernel read-only data: %#lx - %#lx\n",
 	       (unsigned long)&_stext,
 	       PFN_ALIGN((unsigned long)&_eshared) - 1);
@@ -166,13 +154,14 @@ void __init mem_init(void)
 
 void free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(POISON_FREE_INITMEM);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd");
+	free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
+			   "initrd");
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/mm/mmap.c linux-libre-3.11-rc7-gnu/arch/s390/mm/mmap.c
--- linux-libre-3.10-gnu/arch/s390/mm/mmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/mm/mmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -91,11 +91,9 @@ void arch_pick_mmap_layout(struct mm_str
 	if (mmap_is_legacy()) {
 		mm->mmap_base = TASK_UNMAPPED_BASE;
 		mm->get_unmapped_area = arch_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
 	} else {
 		mm->mmap_base = mmap_base();
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
 
@@ -176,11 +174,9 @@ void arch_pick_mmap_layout(struct mm_str
 	if (mmap_is_legacy()) {
 		mm->mmap_base = TASK_UNMAPPED_BASE;
 		mm->get_unmapped_area = s390_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
 	} else {
 		mm->mmap_base = mmap_base();
 		mm->get_unmapped_area = s390_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/mm/pgtable.c linux-libre-3.11-rc7-gnu/arch/s390/mm/pgtable.c
--- linux-libre-3.10-gnu/arch/s390/mm/pgtable.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/mm/pgtable.c	2013-08-25 20:43:22.000000000 -0400
@@ -689,7 +689,7 @@ int gmap_ipte_notify(struct gmap *gmap,
 		entry = *ptep;
 		if ((pte_val(entry) & (_PAGE_INVALID | _PAGE_RO)) == 0) {
 			pgste = pgste_get_lock(ptep);
-			pgste_val(pgste) |= RCP_IN_BIT;
+			pgste_val(pgste) |= PGSTE_IN_BIT;
 			pgste_set_unlock(ptep, pgste);
 			start += PAGE_SIZE;
 			len -= PAGE_SIZE;
@@ -771,6 +771,54 @@ static inline void page_table_free_pgste
 	__free_page(page);
 }
 
+int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
+			  unsigned long key, bool nq)
+{
+	spinlock_t *ptl;
+	pgste_t old, new;
+	pte_t *ptep;
+
+	down_read(&mm->mmap_sem);
+	ptep = get_locked_pte(current->mm, addr, &ptl);
+	if (unlikely(!ptep)) {
+		up_read(&mm->mmap_sem);
+		return -EFAULT;
+	}
+
+	new = old = pgste_get_lock(ptep);
+	pgste_val(new) &= ~(PGSTE_GR_BIT | PGSTE_GC_BIT |
+			    PGSTE_ACC_BITS | PGSTE_FP_BIT);
+	pgste_val(new) |= (key & (_PAGE_CHANGED | _PAGE_REFERENCED)) << 48;
+	pgste_val(new) |= (key & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56;
+	if (!(pte_val(*ptep) & _PAGE_INVALID)) {
+		unsigned long address, bits;
+		unsigned char skey;
+
+		address = pte_val(*ptep) & PAGE_MASK;
+		skey = page_get_storage_key(address);
+		bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
+		/* Set storage key ACC and FP */
+		page_set_storage_key(address,
+				(key & (_PAGE_ACC_BITS | _PAGE_FP_BIT)),
+				!nq);
+
+		/* Merge host changed & referenced into pgste  */
+		pgste_val(new) |= bits << 52;
+		/* Transfer skey changed & referenced bit to kvm user bits */
+		pgste_val(new) |= bits << 45;	/* PGSTE_UR_BIT & PGSTE_UC_BIT */
+	}
+	/* changing the guest storage key is considered a change of the page */
+	if ((pgste_val(new) ^ pgste_val(old)) &
+	    (PGSTE_ACC_BITS | PGSTE_FP_BIT | PGSTE_GR_BIT | PGSTE_GC_BIT))
+		pgste_val(new) |= PGSTE_UC_BIT;
+
+	pgste_set_unlock(ptep, new);
+	pte_unmap_unlock(*ptep, ptl);
+	up_read(&mm->mmap_sem);
+	return 0;
+}
+EXPORT_SYMBOL(set_guest_storage_key);
+
 #else /* CONFIG_PGSTE */
 
 static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm,
@@ -1117,7 +1165,8 @@ void pmdp_splitting_flush(struct vm_area
 	}
 }
 
-void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable)
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+				pgtable_t pgtable)
 {
 	struct list_head *lh = (struct list_head *) pgtable;
 
@@ -1131,7 +1180,7 @@ void pgtable_trans_huge_deposit(struct m
 	mm->pmd_huge_pte = pgtable;
 }
 
-pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm)
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
 {
 	struct list_head *lh;
 	pgtable_t pgtable;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/net/bpf_jit_comp.c linux-libre-3.11-rc7-gnu/arch/s390/net/bpf_jit_comp.c
--- linux-libre-3.10-gnu/arch/s390/net/bpf_jit_comp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/net/bpf_jit_comp.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,8 @@
 #include <linux/netdevice.h>
 #include <linux/if_vlan.h>
 #include <linux/filter.h>
+#include <linux/random.h>
+#include <linux/init.h>
 #include <asm/cacheflush.h>
 #include <asm/processor.h>
 #include <asm/facility.h>
@@ -221,6 +223,37 @@ static void bpf_jit_epilogue(struct bpf_
 	EMIT2(0x07fe);
 }
 
+/* Helper to find the offset of pkt_type in sk_buff
+ * Make sure its still a 3bit field starting at the MSBs within a byte.
+ */
+#define PKT_TYPE_MAX 0xe0
+static int pkt_type_offset;
+
+static int __init bpf_pkt_type_offset_init(void)
+{
+	struct sk_buff skb_probe = {
+		.pkt_type = ~0,
+	};
+	char *ct = (char *)&skb_probe;
+	int off;
+
+	pkt_type_offset = -1;
+	for (off = 0; off < sizeof(struct sk_buff); off++) {
+		if (!ct[off])
+			continue;
+		if (ct[off] == PKT_TYPE_MAX)
+			pkt_type_offset = off;
+		else {
+			/* Found non matching bit pattern, fix needed. */
+			WARN_ON_ONCE(1);
+			pkt_type_offset = -1;
+			return -1;
+		}
+	}
+	return 0;
+}
+device_initcall(bpf_pkt_type_offset_init);
+
 /*
  * make sure we dont leak kernel information to user
  */
@@ -720,6 +753,16 @@ call_fn:	/* lg %r1,<d(function)>(%r13) *
 			EMIT4_DISP(0x88500000, 12);
 		}
 		break;
+	case BPF_S_ANC_PKTTYPE:
+		if (pkt_type_offset < 0)
+			goto out;
+		/* lhi %r5,0 */
+		EMIT4(0xa7580000);
+		/* ic %r5,<d(pkt_type_offset)>(%r2) */
+		EMIT4_DISP(0x43502000, pkt_type_offset);
+		/* srl %r5,5 */
+		EMIT4_DISP(0x88500000, 5);
+		break;
 	case BPF_S_ANC_CPU: /* A = smp_processor_id() */
 #ifdef CONFIG_SMP
 		/* l %r5,<d(cpu_nr)> */
@@ -738,8 +781,41 @@ out:
 	return -1;
 }
 
+/*
+ * Note: for security reasons, bpf code will follow a randomly
+ *	 sized amount of illegal instructions.
+ */
+struct bpf_binary_header {
+	unsigned int pages;
+	u8 image[];
+};
+
+static struct bpf_binary_header *bpf_alloc_binary(unsigned int bpfsize,
+						  u8 **image_ptr)
+{
+	struct bpf_binary_header *header;
+	unsigned int sz, hole;
+
+	/* Most BPF filters are really small, but if some of them fill a page,
+	 * allow at least 128 extra bytes for illegal instructions.
+	 */
+	sz = round_up(bpfsize + sizeof(*header) + 128, PAGE_SIZE);
+	header = module_alloc(sz);
+	if (!header)
+		return NULL;
+	memset(header, 0, sz);
+	header->pages = sz / PAGE_SIZE;
+	hole = sz - bpfsize + sizeof(*header);
+	/* Insert random number of illegal instructions before BPF code
+	 * and make sure the first instruction starts at an even address.
+	 */
+	*image_ptr = &header->image[(prandom_u32() % hole) & -2];
+	return header;
+}
+
 void bpf_jit_compile(struct sk_filter *fp)
 {
+	struct bpf_binary_header *header = NULL;
 	unsigned long size, prg_len, lit_len;
 	struct bpf_jit jit, cjit;
 	unsigned int *addrs;
@@ -772,12 +848,11 @@ void bpf_jit_compile(struct sk_filter *f
 		} else if (jit.prg == cjit.prg && jit.lit == cjit.lit) {
 			prg_len = jit.prg - jit.start;
 			lit_len = jit.lit - jit.mid;
-			size = max_t(unsigned long, prg_len + lit_len,
-				     sizeof(struct work_struct));
+			size = prg_len + lit_len;
 			if (size >= BPF_SIZE_MAX)
 				goto out;
-			jit.start = module_alloc(size);
-			if (!jit.start)
+			header = bpf_alloc_binary(size, &jit.start);
+			if (!header)
 				goto out;
 			jit.prg = jit.mid = jit.start + prg_len;
 			jit.lit = jit.end = jit.start + prg_len + lit_len;
@@ -788,37 +863,25 @@ void bpf_jit_compile(struct sk_filter *f
 		cjit = jit;
 	}
 	if (bpf_jit_enable > 1) {
-		pr_err("flen=%d proglen=%lu pass=%d image=%p\n",
-		       fp->len, jit.end - jit.start, pass, jit.start);
-		if (jit.start) {
-			printk(KERN_ERR "JIT code:\n");
+		bpf_jit_dump(fp->len, jit.end - jit.start, pass, jit.start);
+		if (jit.start)
 			print_fn_code(jit.start, jit.mid - jit.start);
-			print_hex_dump(KERN_ERR, "JIT literals:\n",
-				       DUMP_PREFIX_ADDRESS, 16, 1,
-				       jit.mid, jit.end - jit.mid, false);
-		}
 	}
-	if (jit.start)
+	if (jit.start) {
+		set_memory_ro((unsigned long)header, header->pages);
 		fp->bpf_func = (void *) jit.start;
+	}
 out:
 	kfree(addrs);
 }
 
-static void jit_free_defer(struct work_struct *arg)
-{
-	module_free(NULL, arg);
-}
-
-/* run from softirq, we must use a work_struct to call
- * module_free() from process context
- */
 void bpf_jit_free(struct sk_filter *fp)
 {
-	struct work_struct *work;
+	unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK;
+	struct bpf_binary_header *header = (void *)addr;
 
 	if (fp->bpf_func == sk_run_filter)
 		return;
-	work = (struct work_struct *)fp->bpf_func;
-	INIT_WORK(work, jit_free_defer);
-	schedule_work(work);
+	set_memory_rw(addr, header->pages);
+	module_free(NULL, header);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/oprofile/hwsampler.h linux-libre-3.11-rc7-gnu/arch/s390/oprofile/hwsampler.h
--- linux-libre-3.10-gnu/arch/s390/oprofile/hwsampler.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/oprofile/hwsampler.h	2013-08-25 20:43:22.000000000 -0400
@@ -81,8 +81,8 @@ struct hws_data_entry {
 	unsigned int:16;
 	unsigned int prim_asn:16;   /* primary ASN                       */
 	unsigned long long ia;      /* Instruction Address               */
-	unsigned long long lpp;     /* Logical-Partition Program Param.  */
-	unsigned long long vpp;     /* Virtual-Machine Program Param.    */
+	unsigned long long gpp;     /* Guest Program Parameter		 */
+	unsigned long long hpp;     /* Host Program Parameter		 */
 };
 
 struct hws_trailer_entry {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/oprofile/init.c linux-libre-3.11-rc7-gnu/arch/s390/oprofile/init.c
--- linux-libre-3.10-gnu/arch/s390/oprofile/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/oprofile/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -440,7 +440,7 @@ static int oprofile_hwsampler_init(struc
 		switch (id.machine) {
 		case 0x2097: case 0x2098: ops->cpu_type = "s390/z10"; break;
 		case 0x2817: case 0x2818: ops->cpu_type = "s390/z196"; break;
-		case 0x2827:              ops->cpu_type = "s390/zEC12"; break;
+		case 0x2827: case 0x2828: ops->cpu_type = "s390/zEC12"; break;
 		default: return -ENODEV;
 		}
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/pci/pci.c linux-libre-3.11-rc7-gnu/arch/s390/pci/pci.c
--- linux-libre-3.10-gnu/arch/s390/pci/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/pci/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -82,10 +82,13 @@ struct intr_bucket {
 
 static struct intr_bucket *bucket;
 
-/* Adapter local summary indicator */
-static u8 *zpci_irq_si;
+/* Adapter interrupt definitions */
+static void zpci_irq_handler(struct airq_struct *airq);
 
-static atomic_t irq_retries = ATOMIC_INIT(0);
+static struct airq_struct zpci_airq = {
+	.handler = zpci_irq_handler,
+	.isc = PCI_ISC,
+};
 
 /* I/O Map */
 static DEFINE_SPINLOCK(zpci_iomap_lock);
@@ -404,7 +407,7 @@ static struct pci_ops pci_root_ops = {
 /* store the last handled bit to implement fair scheduling of devices */
 static DEFINE_PER_CPU(unsigned long, next_sbit);
 
-static void zpci_irq_handler(void *dont, void *need)
+static void zpci_irq_handler(struct airq_struct *airq)
 {
 	unsigned long sbit, mbit, last = 0, start = __get_cpu_var(next_sbit);
 	int rescan = 0, max = aisb_max;
@@ -452,7 +455,6 @@ scan:
 	max = aisb_max;
 	sbit = find_first_bit_left(bucket->aisb, max);
 	if (sbit != max) {
-		atomic_inc(&irq_retries);
 		rescan++;
 		goto scan;
 	}
@@ -565,7 +567,21 @@ static void zpci_map_resources(struct zp
 		pr_debug("BAR%i: -> start: %Lx  end: %Lx\n",
 			i, pdev->resource[i].start, pdev->resource[i].end);
 	}
-};
+}
+
+static void zpci_unmap_resources(struct zpci_dev *zdev)
+{
+	struct pci_dev *pdev = zdev->pdev;
+	resource_size_t len;
+	int i;
+
+	for (i = 0; i < PCI_BAR_COUNT; i++) {
+		len = pci_resource_len(pdev, i);
+		if (!len)
+			continue;
+		pci_iounmap(pdev, (void *) pdev->resource[i].start);
+	}
+}
 
 struct zpci_dev *zpci_alloc_device(void)
 {
@@ -701,25 +717,20 @@ static int __init zpci_irq_init(void)
 		goto out_alloc;
 	}
 
-	isc_register(PCI_ISC);
-	zpci_irq_si = s390_register_adapter_interrupt(&zpci_irq_handler, NULL, PCI_ISC);
-	if (IS_ERR(zpci_irq_si)) {
-		rc = PTR_ERR(zpci_irq_si);
-		zpci_irq_si = NULL;
+	rc = register_adapter_interrupt(&zpci_airq);
+	if (rc)
 		goto out_ai;
-	}
+	/* Set summary to 1 to be called every time for the ISC. */
+	*zpci_airq.lsi_ptr = 1;
 
 	for_each_online_cpu(cpu)
 		per_cpu(next_sbit, cpu) = 0;
 
 	spin_lock_init(&bucket->lock);
-	/* set summary to 1 to be called every time for the ISC */
-	*zpci_irq_si = 1;
 	set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);
 	return 0;
 
 out_ai:
-	isc_unregister(PCI_ISC);
 	free_page((unsigned long) bucket->alloc);
 out_alloc:
 	free_page((unsigned long) bucket->aisb);
@@ -732,21 +743,10 @@ static void zpci_irq_exit(void)
 {
 	free_page((unsigned long) bucket->alloc);
 	free_page((unsigned long) bucket->aisb);
-	s390_unregister_adapter_interrupt(zpci_irq_si, PCI_ISC);
-	isc_unregister(PCI_ISC);
+	unregister_adapter_interrupt(&zpci_airq);
 	kfree(bucket);
 }
 
-void zpci_debug_info(struct zpci_dev *zdev, struct seq_file *m)
-{
-	if (!zdev)
-		return;
-
-	seq_printf(m, "global irq retries: %u\n", atomic_read(&irq_retries));
-	seq_printf(m, "aibv[0]:%016lx  aibv[1]:%016lx  aisb:%016lx\n",
-		   get_imap(0)->aibv, get_imap(1)->aibv, *bucket->aisb);
-}
-
 static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size,
 						unsigned long flags, int domain)
 {
@@ -810,6 +810,16 @@ int pcibios_add_device(struct pci_dev *p
 	return 0;
 }
 
+void pcibios_release_device(struct pci_dev *pdev)
+{
+	struct zpci_dev *zdev = get_zdev(pdev);
+
+	zpci_unmap_resources(zdev);
+	zpci_fmb_disable_device(zdev);
+	zpci_debug_exit_device(zdev);
+	zdev->pdev = NULL;
+}
+
 static int zpci_scan_bus(struct zpci_dev *zdev)
 {
 	struct resource *res;
@@ -950,25 +960,6 @@ void zpci_stop_device(struct zpci_dev *z
 }
 EXPORT_SYMBOL_GPL(zpci_stop_device);
 
-int zpci_scan_device(struct zpci_dev *zdev)
-{
-	zdev->pdev = pci_scan_single_device(zdev->bus, ZPCI_DEVFN);
-	if (!zdev->pdev) {
-		pr_err("pci_scan_single_device failed for fid: 0x%x\n",
-			zdev->fid);
-		goto out;
-	}
-
-	pci_bus_add_devices(zdev->bus);
-
-	return 0;
-out:
-	zpci_dma_exit_device(zdev);
-	clp_disable_fh(zdev);
-	return -EIO;
-}
-EXPORT_SYMBOL_GPL(zpci_scan_device);
-
 static inline int barsize(u8 size)
 {
 	return (size) ? (1 << size) >> 10 : 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/pci/pci_clp.c linux-libre-3.11-rc7-gnu/arch/s390/pci/pci_clp.c
--- linux-libre-3.10-gnu/arch/s390/pci/pci_clp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/pci/pci_clp.c	2013-08-25 20:43:22.000000000 -0400
@@ -236,7 +236,6 @@ int clp_disable_fh(struct zpci_dev *zdev
 	if (!zdev_enabled(zdev))
 		return 0;
 
-	dev_info(&zdev->pdev->dev, "disabling fn handle: 0x%x\n", fh);
 	rc = clp_set_pci_fn(&fh, 0, CLP_SET_DISABLE_PCI_FN);
 	if (!rc)
 		/* Success -> store disabled handle in zdev */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/pci/pci_debug.c linux-libre-3.11-rc7-gnu/arch/s390/pci/pci_debug.c
--- linux-libre-3.10-gnu/arch/s390/pci/pci_debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/pci/pci_debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -115,27 +115,6 @@ static const struct file_operations debu
 	.release = single_release,
 };
 
-static int pci_debug_show(struct seq_file *m, void *v)
-{
-	struct zpci_dev *zdev = m->private;
-
-	zpci_debug_info(zdev, m);
-	return 0;
-}
-
-static int pci_debug_seq_open(struct inode *inode, struct file *filp)
-{
-	return single_open(filp, pci_debug_show,
-			   file_inode(filp)->i_private);
-}
-
-static const struct file_operations debugfs_pci_debug_fops = {
-	.open	 = pci_debug_seq_open,
-	.read	 = seq_read,
-	.llseek  = seq_lseek,
-	.release = single_release,
-};
-
 void zpci_debug_init_device(struct zpci_dev *zdev)
 {
 	zdev->debugfs_dev = debugfs_create_dir(dev_name(&zdev->pdev->dev),
@@ -149,19 +128,11 @@ void zpci_debug_init_device(struct zpci_
 				&debugfs_pci_perf_fops);
 	if (IS_ERR(zdev->debugfs_perf))
 		zdev->debugfs_perf = NULL;
-
-	zdev->debugfs_debug = debugfs_create_file("debug",
-				S_IFREG | S_IRUGO | S_IWUSR,
-				zdev->debugfs_dev, zdev,
-				&debugfs_pci_debug_fops);
-	if (IS_ERR(zdev->debugfs_debug))
-		zdev->debugfs_debug = NULL;
 }
 
 void zpci_debug_exit_device(struct zpci_dev *zdev)
 {
 	debugfs_remove(zdev->debugfs_perf);
-	debugfs_remove(zdev->debugfs_debug);
 	debugfs_remove(zdev->debugfs_dev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/pci/pci_dma.c linux-libre-3.11-rc7-gnu/arch/s390/pci/pci_dma.c
--- linux-libre-3.10-gnu/arch/s390/pci/pci_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/pci/pci_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -263,7 +263,7 @@ static dma_addr_t s390_dma_map_pages(str
 				     enum dma_data_direction direction,
 				     struct dma_attrs *attrs)
 {
-	struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
+	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
 	unsigned long nr_pages, iommu_page_index;
 	unsigned long pa = page_to_phys(page) + offset;
 	int flags = ZPCI_PTE_VALID;
@@ -304,7 +304,7 @@ static void s390_dma_unmap_pages(struct
 				 size_t size, enum dma_data_direction direction,
 				 struct dma_attrs *attrs)
 {
-	struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
+	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
 	unsigned long iommu_page_index;
 	int npages;
 
@@ -323,7 +323,7 @@ static void *s390_dma_alloc(struct devic
 			    dma_addr_t *dma_handle, gfp_t flag,
 			    struct dma_attrs *attrs)
 {
-	struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
+	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
 	struct page *page;
 	unsigned long pa;
 	dma_addr_t map;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/s390/pci/pci_sysfs.c linux-libre-3.11-rc7-gnu/arch/s390/pci/pci_sysfs.c
--- linux-libre-3.10-gnu/arch/s390/pci/pci_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/s390/pci/pci_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,40 +15,36 @@
 static ssize_t show_fid(struct device *dev, struct device_attribute *attr,
 			char *buf)
 {
-	struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
+	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
 
-	sprintf(buf, "0x%08x\n", zdev->fid);
-	return strlen(buf);
+	return sprintf(buf, "0x%08x\n", zdev->fid);
 }
 static DEVICE_ATTR(function_id, S_IRUGO, show_fid, NULL);
 
 static ssize_t show_fh(struct device *dev, struct device_attribute *attr,
 		       char *buf)
 {
-	struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
+	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
 
-	sprintf(buf, "0x%08x\n", zdev->fh);
-	return strlen(buf);
+	return sprintf(buf, "0x%08x\n", zdev->fh);
 }
 static DEVICE_ATTR(function_handle, S_IRUGO, show_fh, NULL);
 
 static ssize_t show_pchid(struct device *dev, struct device_attribute *attr,
 			  char *buf)
 {
-	struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
+	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
 
-	sprintf(buf, "0x%04x\n", zdev->pchid);
-	return strlen(buf);
+	return sprintf(buf, "0x%04x\n", zdev->pchid);
 }
 static DEVICE_ATTR(pchid, S_IRUGO, show_pchid, NULL);
 
 static ssize_t show_pfgid(struct device *dev, struct device_attribute *attr,
 			  char *buf)
 {
-	struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev));
+	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
 
-	sprintf(buf, "0x%02x\n", zdev->pfgid);
-	return strlen(buf);
+	return sprintf(buf, "0x%02x\n", zdev->pfgid);
 }
 static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/score/include/asm/dma-mapping.h linux-libre-3.11-rc7-gnu/arch/score/include/asm/dma-mapping.h
--- linux-libre-3.10-gnu/arch/score/include/asm/dma-mapping.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/score/include/asm/dma-mapping.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#ifndef _ASM_SCORE_DMA_MAPPING_H
-#define _ASM_SCORE_DMA_MAPPING_H
-
-#include <asm-generic/dma-mapping-broken.h>
-
-#endif /* _ASM_SCORE_DMA_MAPPING_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/score/include/asm/Kbuild linux-libre-3.11-rc7-gnu/arch/score/include/asm/Kbuild
--- linux-libre-3.10-gnu/arch/score/include/asm/Kbuild	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/score/include/asm/Kbuild	2013-08-25 20:43:22.000000000 -0400
@@ -3,3 +3,4 @@ header-y +=
 
 generic-y += clkdev.h
 generic-y += trace_clock.h
+generic-y += xor.h
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/score/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/score/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/score/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/score/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -113,9 +113,6 @@ static inline pte_t pte_mkspecial(pte_t
 #define pte_clear(mm, addr, xp)		\
 	do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 /*
  * The "pgd_xxx()" functions here are trivial for a folded two-level
  * setup: the pgd is never bad, and a pmd always exists (as it's folded
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/score/Kconfig linux-libre-3.11-rc7-gnu/arch/score/Kconfig
--- linux-libre-3.10-gnu/arch/score/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/score/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -87,6 +87,8 @@ config STACKTRACE_SUPPORT
 
 source "init/Kconfig"
 
+source "kernel/Kconfig.freezer"
+
 config MMU
 	def_bool y
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/score/kernel/vmlinux.lds.S linux-libre-3.11-rc7-gnu/arch/score/kernel/vmlinux.lds.S
--- linux-libre-3.10-gnu/arch/score/kernel/vmlinux.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/score/kernel/vmlinux.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -49,6 +49,7 @@ SECTIONS
 	}
 
 	. = ALIGN(16);
+	_sdata =  .;			/* Start of data section */
 	RODATA
 
 	EXCEPTION_TABLE(16)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/score/mm/fault.c linux-libre-3.11-rc7-gnu/arch/score/mm/fault.c
--- linux-libre-3.10-gnu/arch/score/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/score/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -172,10 +172,10 @@ out_of_memory:
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
-	printk("VM: killing process %s\n", tsk->comm);
-	if (user_mode(regs))
-		do_group_exit(SIGKILL);
-	goto no_context;
+	if (!user_mode(regs))
+		goto no_context;
+	pagefault_out_of_memory();
+	return;
 
 do_sigbus:
 	up_read(&mm->mmap_sem);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/score/mm/init.c linux-libre-3.11-rc7-gnu/arch/score/mm/init.c
--- linux-libre-3.10-gnu/arch/score/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/score/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,40 +75,19 @@ void __init paging_init(void)
 
 void __init mem_init(void)
 {
-	unsigned long codesize, reservedpages, datasize, initsize;
-	unsigned long tmp, ram = 0;
-
 	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
-	totalram_pages += free_all_bootmem();
+	free_all_bootmem();
 	setup_zero_page();	/* Setup zeroed pages. */
-	reservedpages = 0;
 
-	for (tmp = 0; tmp < max_low_pfn; tmp++)
-		if (page_is_ram(tmp)) {
-			ram++;
-			if (PageReserved(pfn_to_page(tmp)))
-				reservedpages++;
-		}
-
-	num_physpages = ram;
-	codesize = (unsigned long) &_etext - (unsigned long) &_text;
-	datasize = (unsigned long) &_edata - (unsigned long) &_etext;
-	initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
-	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
-			"%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
-			(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-			ram << (PAGE_SHIFT-10), codesize >> 10,
-			reservedpages << (PAGE_SHIFT-10), datasize >> 10,
-			initsize >> 10,
-			totalhigh_pages << (PAGE_SHIFT-10));
+	mem_init_print_info(NULL);
 }
 #endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd");
+	free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
+			   "initrd");
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/score/mm/tlb-score.c linux-libre-3.11-rc7-gnu/arch/score/mm/tlb-score.c
--- linux-libre-3.10-gnu/arch/score/mm/tlb-score.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/score/mm/tlb-score.c	2013-08-25 20:43:22.000000000 -0400
@@ -240,7 +240,7 @@ void __update_tlb(struct vm_area_struct
 	local_irq_restore(flags);
 }
 
-void __cpuinit tlb_init(void)
+void tlb_init(void)
 {
 	tlblock_set(0);
 	local_flush_tlb_all();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/boards/board-espt.c linux-libre-3.11-rc7-gnu/arch/sh/boards/board-espt.c
--- linux-libre-3.10-gnu/arch/sh/boards/board-espt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/boards/board-espt.c	2013-08-25 20:43:22.000000000 -0400
@@ -85,7 +85,7 @@ static struct sh_eth_plat_data sh7763_et
 };
 
 static struct platform_device espt_eth_device = {
-	.name       = "sh-eth",
+	.name       = "sh7763-gether",
 	.resource   = sh_eth_resources,
 	.num_resources  = ARRAY_SIZE(sh_eth_resources),
 	.dev        = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/boards/board-sh7757lcr.c linux-libre-3.11-rc7-gnu/arch/sh/boards/board-sh7757lcr.c
--- linux-libre-3.10-gnu/arch/sh/boards/board-sh7757lcr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/boards/board-sh7757lcr.c	2013-08-25 20:43:22.000000000 -0400
@@ -82,7 +82,7 @@ static struct sh_eth_plat_data sh7757_et
 };
 
 static struct platform_device sh7757_eth0_device = {
-	.name		= "sh-eth",
+	.name		= "sh7757-ether",
 	.resource	= sh_eth0_resources,
 	.id		= 0,
 	.num_resources	= ARRAY_SIZE(sh_eth0_resources),
@@ -111,7 +111,7 @@ static struct sh_eth_plat_data sh7757_et
 };
 
 static struct platform_device sh7757_eth1_device = {
-	.name		= "sh-eth",
+	.name		= "sh7757-ether",
 	.resource	= sh_eth1_resources,
 	.id		= 1,
 	.num_resources	= ARRAY_SIZE(sh_eth1_resources),
@@ -157,7 +157,7 @@ static struct sh_eth_plat_data sh7757_et
 };
 
 static struct platform_device sh7757_eth_giga0_device = {
-	.name		= "sh-eth",
+	.name		= "sh7757-gether",
 	.resource	= sh_eth_giga0_resources,
 	.id		= 2,
 	.num_resources	= ARRAY_SIZE(sh_eth_giga0_resources),
@@ -192,7 +192,7 @@ static struct sh_eth_plat_data sh7757_et
 };
 
 static struct platform_device sh7757_eth_giga1_device = {
-	.name		= "sh-eth",
+	.name		= "sh7757-gether",
 	.resource	= sh_eth_giga1_resources,
 	.id		= 3,
 	.num_resources	= ARRAY_SIZE(sh_eth_giga1_resources),
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/boards/mach-ecovec24/setup.c linux-libre-3.11-rc7-gnu/arch/sh/boards/mach-ecovec24/setup.c
--- linux-libre-3.10-gnu/arch/sh/boards/mach-ecovec24/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/boards/mach-ecovec24/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -165,8 +165,8 @@ static struct sh_eth_plat_data sh_eth_pl
 };
 
 static struct platform_device sh_eth_device = {
-	.name = "sh-eth",
-	.id	= 0,
+	.name = "sh7724-ether",
+	.id = 0,
 	.dev = {
 		.platform_data = &sh_eth_plat,
 	},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/boards/mach-se/770x/setup.c linux-libre-3.11-rc7-gnu/arch/sh/boards/mach-se/770x/setup.c
--- linux-libre-3.10-gnu/arch/sh/boards/mach-se/770x/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/boards/mach-se/770x/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,8 +128,8 @@ static struct resource sh_eth0_resources
 };
 
 static struct platform_device sh_eth0_device = {
-	.name = "sh-eth",
-	.id	= 0,
+	.name = "sh771x-ether",
+	.id = 0,
 	.dev = {
 		.platform_data = PHY_ID,
 	},
@@ -151,8 +151,8 @@ static struct resource sh_eth1_resources
 };
 
 static struct platform_device sh_eth1_device = {
-	.name = "sh-eth",
-	.id	= 1,
+	.name = "sh771x-ether",
+	.id = 1,
 	.dev = {
 		.platform_data = PHY_ID,
 	},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/boards/mach-se/7724/setup.c linux-libre-3.11-rc7-gnu/arch/sh/boards/mach-se/7724/setup.c
--- linux-libre-3.10-gnu/arch/sh/boards/mach-se/7724/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/boards/mach-se/7724/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -380,8 +380,8 @@ static struct sh_eth_plat_data sh_eth_pl
 };
 
 static struct platform_device sh_eth_device = {
-	.name = "sh-eth",
-	.id	= 0,
+	.name = "sh7724-ether",
+	.id = 0,
 	.dev = {
 		.platform_data = &sh_eth_plat,
 	},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/boards/mach-sh7763rdp/setup.c linux-libre-3.11-rc7-gnu/arch/sh/boards/mach-sh7763rdp/setup.c
--- linux-libre-3.10-gnu/arch/sh/boards/mach-sh7763rdp/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/boards/mach-sh7763rdp/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -93,7 +93,7 @@ static struct sh_eth_plat_data sh7763_et
 };
 
 static struct platform_device sh7763rdp_eth_device = {
-	.name       = "sh-eth",
+	.name       = "sh7763-gether",
 	.resource   = sh_eth_resources,
 	.num_resources  = ARRAY_SIZE(sh_eth_resources),
 	.dev        = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/configs/sh03_defconfig linux-libre-3.11-rc7-gnu/arch/sh/configs/sh03_defconfig
--- linux-libre-3.10-gnu/arch/sh/configs/sh03_defconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/configs/sh03_defconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,7 @@ CONFIG_PREEMPT=y
 CONFIG_CMDLINE_OVERWRITE=y
 CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
 CONFIG_PCI=y
-CONFIG_HOTPLUG_PCI=m
+CONFIG_HOTPLUG_PCI=y
 CONFIG_BINFMT_MISC=y
 CONFIG_NET=y
 CONFIG_PACKET=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/include/asm/mutex-llsc.h linux-libre-3.11-rc7-gnu/arch/sh/include/asm/mutex-llsc.h
--- linux-libre-3.10-gnu/arch/sh/include/asm/mutex-llsc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/include/asm/mutex-llsc.h	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,7 @@ __mutex_fastpath_lock(atomic_t *count, v
 }
 
 static inline int
-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+__mutex_fastpath_lock_retval(atomic_t *count)
 {
 	int __done, __res;
 
@@ -51,7 +51,7 @@ __mutex_fastpath_lock_retval(atomic_t *c
 		: "t");
 
 	if (unlikely(!__done || __res != 0))
-		__res = fail_fn(count);
+		__res = -1;
 
 	return __res;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/sh/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/sh/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -124,9 +124,6 @@ typedef pte_t *pte_addr_t;
 
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #define pte_pfn(x)		((unsigned long)(((x).pte_low >> PAGE_SHIFT)))
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/include/asm/tlb.h linux-libre-3.11-rc7-gnu/arch/sh/include/asm/tlb.h
--- linux-libre-3.10-gnu/arch/sh/include/asm/tlb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/include/asm/tlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -36,10 +36,12 @@ static inline void init_tlb_gather(struc
 }
 
 static inline void
-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
 {
 	tlb->mm = mm;
-	tlb->fullmm = full_mm_flush;
+	tlb->start = start;
+	tlb->end = end;
+	tlb->fullmm = !(start | (end+1));
 
 	init_tlb_gather(tlb);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/Kconfig linux-libre-3.11-rc7-gnu/arch/sh/Kconfig
--- linux-libre-3.10-gnu/arch/sh/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -748,7 +748,7 @@ config NR_CPUS
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
-	depends on SMP && HOTPLUG
+	depends on SMP
 	help
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/init.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/init.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,9 +43,9 @@
  * peripherals (nofpu, nodsp, and so forth).
  */
 #define onchip_setup(x)					\
-static int x##_disabled __cpuinitdata = !cpu_has_##x;	\
+static int x##_disabled = !cpu_has_##x;			\
 							\
-static int __cpuinit x##_setup(char *opts)			\
+static int x##_setup(char *opts)			\
 {							\
 	x##_disabled = 1;				\
 	return 1;					\
@@ -59,7 +59,7 @@ onchip_setup(dsp);
 #define CPUOPM		0xff2f0000
 #define CPUOPM_RABD	(1 << 5)
 
-static void __cpuinit speculative_execution_init(void)
+static void speculative_execution_init(void)
 {
 	/* Clear RABD */
 	__raw_writel(__raw_readl(CPUOPM) & ~CPUOPM_RABD, CPUOPM);
@@ -78,7 +78,7 @@ static void __cpuinit speculative_execut
 #define EXPMASK_BRDSSLP		(1 << 1)
 #define EXPMASK_MMCAW		(1 << 4)
 
-static void __cpuinit expmask_init(void)
+static void expmask_init(void)
 {
 	unsigned long expmask = __raw_readl(EXPMASK);
 
@@ -217,7 +217,7 @@ static void detect_cache_shape(void)
 		l2_cache_shape = -1; /* No S-cache */
 }
 
-static void __cpuinit fpu_init(void)
+static void fpu_init(void)
 {
 	/* Disable the FPU */
 	if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) {
@@ -230,7 +230,7 @@ static void __cpuinit fpu_init(void)
 }
 
 #ifdef CONFIG_SH_DSP
-static void __cpuinit release_dsp(void)
+static void release_dsp(void)
 {
 	unsigned long sr;
 
@@ -244,7 +244,7 @@ static void __cpuinit release_dsp(void)
 	);
 }
 
-static void __cpuinit dsp_init(void)
+static void dsp_init(void)
 {
 	unsigned long sr;
 
@@ -276,7 +276,7 @@ static void __cpuinit dsp_init(void)
 	release_dsp();
 }
 #else
-static inline void __cpuinit dsp_init(void) { }
+static inline void dsp_init(void) { }
 #endif /* CONFIG_SH_DSP */
 
 /**
@@ -295,7 +295,7 @@ static inline void __cpuinit dsp_init(vo
  * Each processor family is still responsible for doing its own probing
  * and cache configuration in cpu_probe().
  */
-asmlinkage void __cpuinit cpu_init(void)
+asmlinkage void cpu_init(void)
 {
 	current_thread_info()->cpu = hard_smp_processor_id();
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh2/probe.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh2/probe.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh2/probe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh2/probe.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 #include <asm/processor.h>
 #include <asm/cache.h>
 
-void __cpuinit cpu_probe(void)
+void cpu_probe(void)
 {
 #if defined(CONFIG_CPU_SUBTYPE_SH7619)
 	boot_cpu_data.type			= CPU_SH7619;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh2/setup-sh7619.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh2/setup-sh7619.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh2/setup-sh7619.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh2/setup-sh7619.c	2013-08-25 20:43:22.000000000 -0400
@@ -124,8 +124,8 @@ static struct resource eth_resources[] =
 };
 
 static struct platform_device eth_device = {
-	.name = "sh-eth",
-	.id	= -1,
+	.name = "sh7619-ether",
+	.id = -1,
 	.dev = {
 		.platform_data = (void *)1,
 	},
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh2a/probe.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh2a/probe.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh2a/probe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh2a/probe.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 #include <asm/processor.h>
 #include <asm/cache.h>
 
-void __cpuinit cpu_probe(void)
+void cpu_probe(void)
 {
 	boot_cpu_data.family			= CPU_FAMILY_SH2A;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh3/probe.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh3/probe.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh3/probe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh3/probe.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,7 @@
 #include <asm/cache.h>
 #include <asm/io.h>
 
-void __cpuinit cpu_probe(void)
+void cpu_probe(void)
 {
 	unsigned long addr0, addr1, data0, data1, data2, data3;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh4/probe.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh4/probe.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh4/probe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh4/probe.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,7 @@
 #include <asm/processor.h>
 #include <asm/cache.h>
 
-void __cpuinit cpu_probe(void)
+void cpu_probe(void)
 {
 	unsigned long pvr, prr, cvr;
 	unsigned long size;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh4a/clock-sh7724.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh4a/clock-sh7724.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh4a/clock-sh7724.c	2013-08-25 20:43:22.000000000 -0400
@@ -329,7 +329,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[HWBLK_IIC0]),
 	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[HWBLK_IIC1]),
 	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[HWBLK_MMC]),
-	CLKDEV_DEV_ID("sh-eth.0", &mstp_clks[HWBLK_ETHER]),
+	CLKDEV_DEV_ID("sh7724-ether.0", &mstp_clks[HWBLK_ETHER]),
 	CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]),
 	CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]),
 	CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]),
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh4a/clock-sh7734.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh4a/clock-sh7734.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh4a/clock-sh7734.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh4a/clock-sh7734.c	2013-08-25 20:43:22.000000000 -0400
@@ -238,7 +238,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("adc0", &mstp_clks[MSTP313]),
 	CLKDEV_CON_ID("mtu0", &mstp_clks[MSTP312]),
 	CLKDEV_CON_ID("iebus0", &mstp_clks[MSTP304]),
-	CLKDEV_DEV_ID("sh-eth.0", &mstp_clks[MSTP114]),
+	CLKDEV_DEV_ID("sh7734-gether.0", &mstp_clks[MSTP114]),
 	CLKDEV_CON_ID("rtc0", &mstp_clks[MSTP303]),
 	CLKDEV_CON_ID("hif0", &mstp_clks[MSTP302]),
 	CLKDEV_CON_ID("stif0", &mstp_clks[MSTP301]),
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh4a/smp-shx3.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh4a/smp-shx3.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh4a/smp-shx3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh4a/smp-shx3.c	2013-08-25 20:43:22.000000000 -0400
@@ -124,7 +124,7 @@ static void shx3_update_boot_vector(unsi
 	__raw_writel(STBCR_RESET, STBCR_REG(cpu));
 }
 
-static int __cpuinit
+static int
 shx3_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned int)hcpu;
@@ -143,11 +143,11 @@ shx3_cpu_callback(struct notifier_block
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata shx3_cpu_notifier = {
+static struct notifier_block shx3_cpu_notifier = {
 	.notifier_call		= shx3_cpu_callback,
 };
 
-static int __cpuinit register_shx3_cpu_notifier(void)
+static int register_shx3_cpu_notifier(void)
 {
 	register_hotcpu_notifier(&shx3_cpu_notifier);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh5/probe.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh5/probe.c
--- linux-libre-3.10-gnu/arch/sh/kernel/cpu/sh5/probe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/cpu/sh5/probe.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,7 @@
 #include <asm/cache.h>
 #include <asm/tlb.h>
 
-void __cpuinit cpu_probe(void)
+void cpu_probe(void)
 {
 	unsigned long long cir;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/perf_event.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/perf_event.c
--- linux-libre-3.10-gnu/arch/sh/kernel/perf_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/perf_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -367,7 +367,7 @@ static void sh_pmu_setup(int cpu)
 	memset(cpuhw, 0, sizeof(struct cpu_hw_events));
 }
 
-static int __cpuinit
+static int
 sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (long)hcpu;
@@ -384,7 +384,7 @@ sh_pmu_notifier(struct notifier_block *s
 	return NOTIFY_OK;
 }
 
-int __cpuinit register_sh_pmu(struct sh_pmu *_pmu)
+int register_sh_pmu(struct sh_pmu *_pmu)
 {
 	if (sh_pmu)
 		return -EBUSY;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/process.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/process.c
--- linux-libre-3.10-gnu/arch/sh/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -65,7 +65,7 @@ void arch_task_cache_init(void)
 # define HAVE_SOFTFP	0
 #endif
 
-void __cpuinit init_thread_xstate(void)
+void init_thread_xstate(void)
 {
 	if (boot_cpu_data.flags & CPU_HAS_FPU)
 		xstate_size = sizeof(struct sh_fpu_hard_struct);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/ptrace_32.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/ptrace_32.c
--- linux-libre-3.10-gnu/arch/sh/kernel/ptrace_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/ptrace_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -117,11 +117,7 @@ void user_enable_single_step(struct task
 
 	set_tsk_thread_flag(child, TIF_SINGLESTEP);
 
-	if (ptrace_get_breakpoints(child) < 0)
-		return;
-
 	set_single_step(child, pc);
-	ptrace_put_breakpoints(child);
 }
 
 void user_disable_single_step(struct task_struct *child)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/setup.c
--- linux-libre-3.10-gnu/arch/sh/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -172,7 +172,7 @@ disable:
 #endif
 }
 
-void __cpuinit calibrate_delay(void)
+void calibrate_delay(void)
 {
 	struct clk *clk = clk_get(NULL, "cpu_clk");
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/smp.c
--- linux-libre-3.10-gnu/arch/sh/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,7 @@ struct plat_smp_ops *mp_ops = NULL;
 /* State of each CPU */
 DEFINE_PER_CPU(int, cpu_state) = { 0 };
 
-void __cpuinit register_smp_ops(struct plat_smp_ops *ops)
+void register_smp_ops(struct plat_smp_ops *ops)
 {
 	if (mp_ops)
 		printk(KERN_WARNING "Overriding previously set SMP ops\n");
@@ -45,7 +45,7 @@ void __cpuinit register_smp_ops(struct p
 	mp_ops = ops;
 }
 
-static inline void __cpuinit smp_store_cpu_info(unsigned int cpu)
+static inline void smp_store_cpu_info(unsigned int cpu)
 {
 	struct sh_cpuinfo *c = cpu_data + cpu;
 
@@ -174,7 +174,7 @@ void native_play_dead(void)
 }
 #endif
 
-asmlinkage void __cpuinit start_secondary(void)
+asmlinkage void start_secondary(void)
 {
 	unsigned int cpu = smp_processor_id();
 	struct mm_struct *mm = &init_mm;
@@ -215,7 +215,7 @@ extern struct {
 	void *thread_info;
 } stack_start;
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tsk)
+int __cpu_up(unsigned int cpu, struct task_struct *tsk)
 {
 	unsigned long timeout;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/traps_32.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/traps_32.c
--- linux-libre-3.10-gnu/arch/sh/kernel/traps_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/traps_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -741,7 +741,7 @@ asmlinkage void do_exception_error(unsig
 	die_if_kernel("exception", regs, ex);
 }
 
-void __cpuinit per_cpu_trap_init(void)
+void per_cpu_trap_init(void)
 {
 	extern void *vbr_base;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/kernel/traps_64.c linux-libre-3.11-rc7-gnu/arch/sh/kernel/traps_64.c
--- linux-libre-3.10-gnu/arch/sh/kernel/traps_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/kernel/traps_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -810,7 +810,7 @@ asmlinkage void do_debug_interrupt(unsig
 	poke_real_address_q(DM_EXP_CAUSE_PHY, 0x0);
 }
 
-void __cpuinit per_cpu_trap_init(void)
+void per_cpu_trap_init(void)
 {
 	/* Nothing to do for now, VBR initialization later. */
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/mm/init.c linux-libre-3.11-rc7-gnu/arch/sh/mm/init.c
--- linux-libre-3.10-gnu/arch/sh/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -407,30 +407,16 @@ unsigned int mem_init_done = 0;
 
 void __init mem_init(void)
 {
-	int codesize, datasize, initsize;
-	int nid;
+	pg_data_t *pgdat;
 
 	iommu_init();
 
-	num_physpages = 0;
 	high_memory = NULL;
+	for_each_online_pgdat(pgdat)
+		high_memory = max_t(void *, high_memory,
+				    __va(pgdat_end_pfn(pgdat) << PAGE_SHIFT));
 
-	for_each_online_node(nid) {
-		pg_data_t *pgdat = NODE_DATA(nid);
-		void *node_high_memory;
-
-		num_physpages += pgdat->node_present_pages;
-
-		if (pgdat->node_spanned_pages)
-			totalram_pages += free_all_bootmem_node(pgdat);
-
-
-		node_high_memory = (void *)__va((pgdat->node_start_pfn +
-						 pgdat->node_spanned_pages) <<
-						 PAGE_SHIFT);
-		if (node_high_memory > high_memory)
-			high_memory = node_high_memory;
-	}
+	free_all_bootmem();
 
 	/* Set this up early, so we can take care of the zero page */
 	cpu_cache_init();
@@ -441,19 +427,8 @@ void __init mem_init(void)
 
 	vsyscall_init();
 
-	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
-	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
-	       "%dk data, %dk init)\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10,
-		datasize >> 10,
-		initsize >> 10);
-
-	printk(KERN_INFO "virtual kernel memory layout:\n"
+	mem_init_print_info(NULL);
+	pr_info("virtual kernel memory layout:\n"
 		"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
 #ifdef CONFIG_HIGHMEM
 		"    pkmap   : 0x%08lx - 0x%08lx   (%4ld kB)\n"
@@ -499,13 +474,13 @@ void __init mem_init(void)
 
 void free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sh/mm/tlb-sh5.c linux-libre-3.11-rc7-gnu/arch/sh/mm/tlb-sh5.c
--- linux-libre-3.10-gnu/arch/sh/mm/tlb-sh5.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sh/mm/tlb-sh5.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,7 @@
 /**
  * sh64_tlb_init - Perform initial setup for the DTLB and ITLB.
  */
-int __cpuinit sh64_tlb_init(void)
+int sh64_tlb_init(void)
 {
 	/* Assign some sane DTLB defaults */
 	cpu_data->dtlb.entries	= 64;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/include/asm/leon.h linux-libre-3.11-rc7-gnu/arch/sparc/include/asm/leon.h
--- linux-libre-3.10-gnu/arch/sparc/include/asm/leon.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/include/asm/leon.h	2013-08-25 20:43:22.000000000 -0400
@@ -108,7 +108,7 @@ static inline int sparc_leon3_snooping_e
 {
 	u32 cctrl;
 	__asm__ __volatile__("lda [%%g0] 2, %0\n\t" : "=r"(cctrl));
-        return (cctrl >> 23) & 1;
+	return ((cctrl >> 23) & 1) && ((cctrl >> 17) & 1);
 };
 
 static inline void sparc_leon3_disable_cache(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/include/asm/pgtable_32.h linux-libre-3.11-rc7-gnu/arch/sparc/include/asm/pgtable_32.h
--- linux-libre-3.10-gnu/arch/sparc/include/asm/pgtable_32.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/include/asm/pgtable_32.h	2013-08-25 20:43:22.000000000 -0400
@@ -443,6 +443,7 @@ static inline int io_remap_pfn_range(str
 
 	return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
 }
+#define io_remap_pfn_range io_remap_pfn_range 
 
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/include/asm/pgtable_64.h linux-libre-3.11-rc7-gnu/arch/sparc/include/asm/pgtable_64.h
--- linux-libre-3.10-gnu/arch/sparc/include/asm/pgtable_64.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/include/asm/pgtable_64.h	2013-08-25 20:43:22.000000000 -0400
@@ -853,10 +853,11 @@ extern void update_mmu_cache_pmd(struct
 				 pmd_t *pmd);
 
 #define __HAVE_ARCH_PGTABLE_DEPOSIT
-extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+				       pgtable_t pgtable);
 
 #define __HAVE_ARCH_PGTABLE_WITHDRAW
-extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm);
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
 #endif
 
 /* Encode and de-code a swap entry */
@@ -914,6 +915,7 @@ static inline int io_remap_pfn_range(str
 
 	return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
 }
+#define io_remap_pfn_range io_remap_pfn_range 
 
 #include <asm/tlbflush.h>
 #include <asm-generic/pgtable.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/include/uapi/asm/fcntl.h linux-libre-3.11-rc7-gnu/arch/sparc/include/uapi/asm/fcntl.h
--- linux-libre-3.10-gnu/arch/sparc/include/uapi/asm/fcntl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/include/uapi/asm/fcntl.h	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,7 @@
 #define O_SYNC		(__O_SYNC|O_DSYNC)
 
 #define O_PATH		0x1000000
+#define __O_TMPFILE	0x2000000
 
 #define F_GETOWN	5	/*  for sockets. */
 #define F_SETOWN	6	/*  for sockets. */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/sparc/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/sparc/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -70,6 +70,8 @@
 
 #define SO_SELECT_ERR_QUEUE	0x0029
 
+#define SO_BUSY_POLL		0x0030
+
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x5001
 #define SO_SECURITY_ENCRYPTION_TRANSPORT	0x5002
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/Kconfig linux-libre-3.11-rc7-gnu/arch/sparc/Kconfig
--- linux-libre-3.10-gnu/arch/sparc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -243,7 +243,6 @@ config SECCOMP
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
 	depends on SPARC64 && SMP
-	select HOTPLUG
 	help
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu/cpu#.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/asm-offsets.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/asm-offsets.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/asm-offsets.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/asm-offsets.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,6 +49,8 @@ int foo(void)
 	DEFINE(AOFF_task_thread, offsetof(struct task_struct, thread));
 	BLANK();
 	DEFINE(AOFF_mm_context, offsetof(struct mm_struct, context));
+	BLANK();
+	DEFINE(VMA_VM_MM,    offsetof(struct vm_area_struct, vm_mm));
 
 	/* DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); */
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/ds.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/ds.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/ds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/ds.c	2013-08-25 20:43:22.000000000 -0400
@@ -528,10 +528,8 @@ static void dr_cpu_mark(struct ds_data *
 	}
 }
 
-static int __cpuinit dr_cpu_configure(struct ds_info *dp,
-				      struct ds_cap_state *cp,
-				      u64 req_num,
-				      cpumask_t *mask)
+static int dr_cpu_configure(struct ds_info *dp, struct ds_cap_state *cp,
+			    u64 req_num, cpumask_t *mask)
 {
 	struct ds_data *resp;
 	int resp_len, ncpus, cpu;
@@ -627,9 +625,8 @@ static int dr_cpu_unconfigure(struct ds_
 	return 0;
 }
 
-static void __cpuinit dr_cpu_data(struct ds_info *dp,
-				  struct ds_cap_state *cp,
-				  void *buf, int len)
+static void dr_cpu_data(struct ds_info *dp, struct ds_cap_state *cp, void *buf,
+			int len)
 {
 	struct ds_data *data = buf;
 	struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1);
@@ -783,6 +780,16 @@ void ldom_set_var(const char *var, const
 		char  *base, *p;
 		int msg_len, loops;
 
+		if (strlen(var) + strlen(value) + 2 >
+		    sizeof(pkt) - sizeof(pkt.header)) {
+			printk(KERN_ERR PFX
+				"contents length: %zu, which more than max: %lu,"
+				"so could not set (%s) variable to (%s).\n",
+				strlen(var) + strlen(value) + 2,
+				sizeof(pkt) - sizeof(pkt.header), var, value);
+			return;
+		}
+
 		memset(&pkt, 0, sizeof(pkt));
 		pkt.header.data.tag.type = DS_DATA;
 		pkt.header.data.handle = cp->handle;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/entry.h linux-libre-3.11-rc7-gnu/arch/sparc/kernel/entry.h
--- linux-libre-3.10-gnu/arch/sparc/kernel/entry.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/entry.h	2013-08-25 20:43:22.000000000 -0400
@@ -250,7 +250,7 @@ extern struct ino_bucket *ivector_table;
 extern unsigned long ivector_table_pa;
 
 extern void init_irqwork_curcpu(void);
-extern void __cpuinit sun4v_register_mondo_queues(int this_cpu);
+extern void sun4v_register_mondo_queues(int this_cpu);
 
 #endif /* CONFIG_SPARC32 */
 #endif /* _ENTRY_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/hvtramp.S linux-libre-3.11-rc7-gnu/arch/sparc/kernel/hvtramp.S
--- linux-libre-3.10-gnu/arch/sparc/kernel/hvtramp.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/hvtramp.S	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,6 @@
 #include <asm/asi.h>
 #include <asm/pil.h>
 
-	__CPUINIT
 	.align		8
 	.globl		hv_cpu_startup, hv_cpu_startup_end
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/irq_64.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/irq_64.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/irq_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/irq_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -835,7 +835,8 @@ void notrace init_irqwork_curcpu(void)
  * Therefore you cannot make any OBP calls, not even prom_printf,
  * from these two routines.
  */
-static void __cpuinit notrace register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask)
+static void notrace register_one_mondo(unsigned long paddr, unsigned long type,
+				       unsigned long qmask)
 {
 	unsigned long num_entries = (qmask + 1) / 64;
 	unsigned long status;
@@ -848,7 +849,7 @@ static void __cpuinit notrace register_o
 	}
 }
 
-void __cpuinit notrace sun4v_register_mondo_queues(int this_cpu)
+void notrace sun4v_register_mondo_queues(int this_cpu)
 {
 	struct trap_per_cpu *tb = &trap_block[this_cpu];
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/leon_smp.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/leon_smp.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/leon_smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/leon_smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ extern ctxd_t *srmmu_ctx_table_phys;
 static int smp_processors_ready;
 extern volatile unsigned long cpu_callin_map[NR_CPUS];
 extern cpumask_t smp_commenced_mask;
-void __cpuinit leon_configure_cache_smp(void);
+void leon_configure_cache_smp(void);
 static void leon_ipi_init(void);
 
 /* IRQ number of LEON IPIs */
@@ -69,12 +69,12 @@ static inline unsigned long do_swap(vola
 	return val;
 }
 
-void __cpuinit leon_cpu_pre_starting(void *arg)
+void leon_cpu_pre_starting(void *arg)
 {
 	leon_configure_cache_smp();
 }
 
-void __cpuinit leon_cpu_pre_online(void *arg)
+void leon_cpu_pre_online(void *arg)
 {
 	int cpuid = hard_smp_processor_id();
 
@@ -106,7 +106,7 @@ void __cpuinit leon_cpu_pre_online(void
 
 extern struct linux_prom_registers smp_penguin_ctable;
 
-void __cpuinit leon_configure_cache_smp(void)
+void leon_configure_cache_smp(void)
 {
 	unsigned long cfg = sparc_leon3_get_dcachecfg();
 	int me = smp_processor_id();
@@ -186,7 +186,7 @@ void __init leon_boot_cpus(void)
 
 }
 
-int __cpuinit leon_boot_one_cpu(int i, struct task_struct *idle)
+int leon_boot_one_cpu(int i, struct task_struct *idle)
 {
 	int timeout;
 
@@ -254,15 +254,12 @@ void __init leon_smp_done(void)
 	/* Free unneeded trap tables */
 	if (!cpu_present(1)) {
 		free_reserved_page(virt_to_page(&trapbase_cpu1));
-		num_physpages++;
 	}
 	if (!cpu_present(2)) {
 		free_reserved_page(virt_to_page(&trapbase_cpu2));
-		num_physpages++;
 	}
 	if (!cpu_present(3)) {
 		free_reserved_page(virt_to_page(&trapbase_cpu3));
-		num_physpages++;
 	}
 	/* Ok, they are spinning and ready to go. */
 	smp_processors_ready = 1;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/mdesc.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/mdesc.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/mdesc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/mdesc.c	2013-08-25 20:43:22.000000000 -0400
@@ -571,9 +571,7 @@ static void __init report_platform_prope
 	mdesc_release(hp);
 }
 
-static void __cpuinit fill_in_one_cache(cpuinfo_sparc *c,
-					struct mdesc_handle *hp,
-					u64 mp)
+static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp)
 {
 	const u64 *level = mdesc_get_property(hp, mp, "level", NULL);
 	const u64 *size = mdesc_get_property(hp, mp, "size", NULL);
@@ -616,7 +614,7 @@ static void __cpuinit fill_in_one_cache(
 	}
 }
 
-static void __cpuinit mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id)
+static void mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id)
 {
 	u64 a;
 
@@ -649,7 +647,7 @@ static void __cpuinit mark_core_ids(stru
 	}
 }
 
-static void __cpuinit set_core_ids(struct mdesc_handle *hp)
+static void set_core_ids(struct mdesc_handle *hp)
 {
 	int idx;
 	u64 mp;
@@ -674,7 +672,7 @@ static void __cpuinit set_core_ids(struc
 	}
 }
 
-static void __cpuinit mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
+static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
 {
 	u64 a;
 
@@ -693,7 +691,7 @@ static void __cpuinit mark_proc_ids(stru
 	}
 }
 
-static void __cpuinit __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
+static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
 {
 	int idx;
 	u64 mp;
@@ -714,14 +712,14 @@ static void __cpuinit __set_proc_ids(str
 	}
 }
 
-static void __cpuinit set_proc_ids(struct mdesc_handle *hp)
+static void set_proc_ids(struct mdesc_handle *hp)
 {
 	__set_proc_ids(hp, "exec_unit");
 	__set_proc_ids(hp, "exec-unit");
 }
 
-static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask,
-					 unsigned long def, unsigned long max)
+static void get_one_mondo_bits(const u64 *p, unsigned int *mask,
+			       unsigned long def, unsigned long max)
 {
 	u64 val;
 
@@ -742,8 +740,8 @@ use_default:
 	*mask = ((1U << def) * 64U) - 1U;
 }
 
-static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp,
-				     struct trap_per_cpu *tb)
+static void get_mondo_data(struct mdesc_handle *hp, u64 mp,
+			   struct trap_per_cpu *tb)
 {
 	static int printed;
 	const u64 *val;
@@ -769,7 +767,7 @@ static void __cpuinit get_mondo_data(str
 	}
 }
 
-static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask)
+static void *mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask)
 {
 	struct mdesc_handle *hp = mdesc_grab();
 	void *ret = NULL;
@@ -799,7 +797,8 @@ out:
 	return ret;
 }
 
-static void * __cpuinit record_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg)
+static void *record_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid,
+			    void *arg)
 {
 	ncpus_probed++;
 #ifdef CONFIG_SMP
@@ -808,7 +807,7 @@ static void * __cpuinit record_one_cpu(s
 	return NULL;
 }
 
-void __cpuinit mdesc_populate_present_mask(cpumask_t *mask)
+void mdesc_populate_present_mask(cpumask_t *mask)
 {
 	if (tlb_type != hypervisor)
 		return;
@@ -841,7 +840,8 @@ void __init mdesc_get_page_sizes(cpumask
 	mdesc_iterate_over_cpus(check_one_pgsz, pgsz_mask, mask);
 }
 
-static void * __cpuinit fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg)
+static void *fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid,
+			     void *arg)
 {
 	const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL);
 	struct trap_per_cpu *tb;
@@ -890,7 +890,7 @@ static void * __cpuinit fill_in_one_cpu(
 	return NULL;
 }
 
-void __cpuinit mdesc_fill_in_cpu_data(cpumask_t *mask)
+void mdesc_fill_in_cpu_data(cpumask_t *mask)
 {
 	struct mdesc_handle *hp;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/pci.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/pci.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -254,7 +254,7 @@ static struct pci_dev *of_create_pci_dev
 	const char *type;
 	u32 class;
 
-	dev = alloc_pci_dev();
+	dev = pci_alloc_dev(bus);
 	if (!dev)
 		return NULL;
 
@@ -281,7 +281,6 @@ static struct pci_dev *of_create_pci_dev
 		printk("    create device, devfn: %x, type: %s\n",
 		       devfn, type);
 
-	dev->bus = bus;
 	dev->sysdata = node;
 	dev->dev.parent = bus->bridge;
 	dev->dev.bus = &pci_bus_type;
@@ -327,7 +326,7 @@ static struct pci_dev *of_create_pci_dev
 	if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)
 		pci_set_master(dev);
 
-	dev->current_state = 4;		/* unknown power state */
+	dev->current_state = PCI_UNKNOWN;	/* unknown power state */
 	dev->error_state = pci_channel_io_normal;
 	dev->dma_mask = 0xffffffff;
 
@@ -773,15 +772,6 @@ static int __pci_mmap_make_offset(struct
 	return 0;
 }
 
-/* Set vm_flags of VMA, as appropriate for this architecture, for a pci device
- * mapping.
- */
-static void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
-					    enum pci_mmap_state mmap_state)
-{
-	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
-}
-
 /* Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
  * device mapping.
  */
@@ -809,7 +799,6 @@ int pci_mmap_page_range(struct pci_dev *
 	if (ret < 0)
 		return ret;
 
-	__pci_mmap_set_flags(dev, vma, mmap_state);
 	__pci_mmap_set_pgprot(dev, vma, mmap_state);
 
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/smp_32.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/smp_32.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/smp_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/smp_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,7 @@
 #include "kernel.h"
 #include "irq.h"
 
-volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,};
+volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
 
 cpumask_t smp_commenced_mask = CPU_MASK_NONE;
 
@@ -53,7 +53,7 @@ const struct sparc32_ipi_ops *sparc32_ip
  * instruction which is much better...
  */
 
-void __cpuinit smp_store_cpu_info(int id)
+void smp_store_cpu_info(int id)
 {
 	int cpu_node;
 	int mid;
@@ -120,7 +120,7 @@ void cpu_panic(void)
 	panic("SMP bolixed\n");
 }
 
-struct linux_prom_registers smp_penguin_ctable __cpuinitdata = { 0 };
+struct linux_prom_registers smp_penguin_ctable = { 0 };
 
 void smp_send_reschedule(int cpu)
 {
@@ -259,10 +259,10 @@ void __init smp_prepare_boot_cpu(void)
 	set_cpu_possible(cpuid, true);
 }
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	extern int __cpuinit smp4m_boot_one_cpu(int, struct task_struct *);
-	extern int __cpuinit smp4d_boot_one_cpu(int, struct task_struct *);
+	extern int smp4m_boot_one_cpu(int, struct task_struct *);
+	extern int smp4d_boot_one_cpu(int, struct task_struct *);
 	int ret=0;
 
 	switch(sparc_cpu_model) {
@@ -297,7 +297,7 @@ int __cpuinit __cpu_up(unsigned int cpu,
 	return ret;
 }
 
-void __cpuinit arch_cpu_pre_starting(void *arg)
+void arch_cpu_pre_starting(void *arg)
 {
 	local_ops->cache_all();
 	local_ops->tlb_all();
@@ -317,7 +317,7 @@ void __cpuinit arch_cpu_pre_starting(voi
 	}
 }
 
-void __cpuinit arch_cpu_pre_online(void *arg)
+void arch_cpu_pre_online(void *arg)
 {
 	unsigned int cpuid = hard_smp_processor_id();
 
@@ -344,7 +344,7 @@ void __cpuinit arch_cpu_pre_online(void
 	}
 }
 
-void __cpuinit sparc_start_secondary(void *arg)
+void sparc_start_secondary(void *arg)
 {
 	unsigned int cpu;
 
@@ -375,7 +375,7 @@ void __cpuinit sparc_start_secondary(voi
 	BUG();
 }
 
-void __cpuinit smp_callin(void)
+void smp_callin(void)
 {
 	sparc_start_secondary(NULL);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/smp_64.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/smp_64.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/smp_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/smp_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -87,7 +87,7 @@ extern void setup_sparc64_timer(void);
 
 static volatile unsigned long callin_flag = 0;
 
-void __cpuinit smp_callin(void)
+void smp_callin(void)
 {
 	int cpuid = hard_smp_processor_id();
 
@@ -281,7 +281,8 @@ static unsigned long kimage_addr_to_ra(v
 	return kern_base + (val - KERNBASE);
 }
 
-static void __cpuinit ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg, void **descrp)
+static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg,
+				void **descrp)
 {
 	extern unsigned long sparc64_ttable_tl0;
 	extern unsigned long kern_locked_tte_data;
@@ -342,7 +343,7 @@ extern unsigned long sparc64_cpu_startup
  */
 static struct thread_info *cpu_new_thread = NULL;
 
-static int __cpuinit smp_boot_one_cpu(unsigned int cpu, struct task_struct *idle)
+static int smp_boot_one_cpu(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long entry =
 		(unsigned long)(&sparc64_cpu_startup);
@@ -1266,7 +1267,7 @@ void smp_fill_in_sib_core_maps(void)
 	}
 }
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int ret = smp_boot_one_cpu(cpu, tidle);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/sun4d_smp.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/sun4d_smp.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/sun4d_smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/sun4d_smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,7 +50,7 @@ static inline void show_leds(int cpuid)
 			      "i" (ASI_M_CTL));
 }
 
-void __cpuinit sun4d_cpu_pre_starting(void *arg)
+void sun4d_cpu_pre_starting(void *arg)
 {
 	int cpuid = hard_smp_processor_id();
 
@@ -62,7 +62,7 @@ void __cpuinit sun4d_cpu_pre_starting(vo
 	cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000);
 }
 
-void __cpuinit sun4d_cpu_pre_online(void *arg)
+void sun4d_cpu_pre_online(void *arg)
 {
 	unsigned long flags;
 	int cpuid;
@@ -118,7 +118,7 @@ void __init smp4d_boot_cpus(void)
 	local_ops->cache_all();
 }
 
-int __cpuinit smp4d_boot_one_cpu(int i, struct task_struct *idle)
+int smp4d_boot_one_cpu(int i, struct task_struct *idle)
 {
 	unsigned long *entry = &sun4d_cpu_startup;
 	int timeout;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/sun4m_smp.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/sun4m_smp.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/sun4m_smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/sun4m_smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,11 +34,11 @@ swap_ulong(volatile unsigned long *ptr,
 	return val;
 }
 
-void __cpuinit sun4m_cpu_pre_starting(void *arg)
+void sun4m_cpu_pre_starting(void *arg)
 {
 }
 
-void __cpuinit sun4m_cpu_pre_online(void *arg)
+void sun4m_cpu_pre_online(void *arg)
 {
 	int cpuid = hard_smp_processor_id();
 
@@ -75,7 +75,7 @@ void __init smp4m_boot_cpus(void)
 	local_ops->cache_all();
 }
 
-int __cpuinit smp4m_boot_one_cpu(int i, struct task_struct *idle)
+int smp4m_boot_one_cpu(int i, struct task_struct *idle)
 {
 	unsigned long *entry = &sun4m_cpu_startup;
 	int timeout;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/sysfs.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/sysfs.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -246,7 +246,7 @@ static void unregister_cpu_online(unsign
 }
 #endif
 
-static int __cpuinit sysfs_cpu_notify(struct notifier_block *self,
+static int sysfs_cpu_notify(struct notifier_block *self,
 				      unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned int)(long)hcpu;
@@ -266,7 +266,7 @@ static int __cpuinit sysfs_cpu_notify(st
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata sysfs_cpu_nb = {
+static struct notifier_block sysfs_cpu_nb = {
 	.notifier_call	= sysfs_cpu_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/sys_sparc_64.c linux-libre-3.11-rc7-gnu/arch/sparc/kernel/sys_sparc_64.c
--- linux-libre-3.10-gnu/arch/sparc/kernel/sys_sparc_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/sys_sparc_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -290,7 +290,6 @@ void arch_pick_mmap_layout(struct mm_str
 	    sysctl_legacy_va_layout) {
 		mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
 		mm->get_unmapped_area = arch_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
 	} else {
 		/* We know it's 32-bit */
 		unsigned long task_size = STACK_TOP32;
@@ -302,7 +301,6 @@ void arch_pick_mmap_layout(struct mm_str
 
 		mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/trampoline_32.S linux-libre-3.11-rc7-gnu/arch/sparc/kernel/trampoline_32.S
--- linux-libre-3.10-gnu/arch/sparc/kernel/trampoline_32.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/trampoline_32.S	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,6 @@
 	.globl sun4m_cpu_startup
 	.globl sun4d_cpu_startup
 
-	__CPUINIT
 	.align 4
 
 /* When we start up a cpu for the first time it enters this routine.
@@ -94,7 +93,6 @@ smp_panic:
 /* CPUID in bootbus can be found at PA 0xff0140000 */
 #define SUN4D_BOOTBUS_CPUID	0xf0140000
 
-	__CPUINIT
 	.align	4
 
 sun4d_cpu_startup:
@@ -146,7 +144,6 @@ sun4d_cpu_startup:
 
 	b,a	smp_panic
 
-	__CPUINIT
 	.align	4
         .global leon_smp_cpu_startup, smp_penguin_ctable
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/kernel/trampoline_64.S linux-libre-3.11-rc7-gnu/arch/sparc/kernel/trampoline_64.S
--- linux-libre-3.10-gnu/arch/sparc/kernel/trampoline_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/kernel/trampoline_64.S	2013-08-25 20:43:22.000000000 -0400
@@ -32,13 +32,11 @@ itlb_load:
 dtlb_load:
 	.asciz	"SUNW,dtlb-load"
 
-	/* XXX __cpuinit this thing XXX */
 #define TRAMP_STACK_SIZE	1024
 	.align	16
 tramp_stack:
 	.skip	TRAMP_STACK_SIZE
 
-	__CPUINIT
 	.align		8
 	.globl		sparc64_cpu_startup, sparc64_cpu_startup_end
 sparc64_cpu_startup:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/mm/hypersparc.S linux-libre-3.11-rc7-gnu/arch/sparc/mm/hypersparc.S
--- linux-libre-3.10-gnu/arch/sparc/mm/hypersparc.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/mm/hypersparc.S	2013-08-25 20:43:22.000000000 -0400
@@ -74,7 +74,7 @@ hypersparc_flush_cache_mm_out:
 
 	/* The things we do for performance... */
 hypersparc_flush_cache_range:
-	ld	[%o0 + 0x0], %o0		/* XXX vma->vm_mm, GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 #ifndef CONFIG_SMP
 	ld	[%o0 + AOFF_mm_context], %g1
 	cmp	%g1, -1
@@ -163,7 +163,7 @@ hypersparc_flush_cache_range_out:
 	 */
 	/* Verified, my ass... */
 hypersparc_flush_cache_page:
-	ld	[%o0 + 0x0], %o0		/* XXX vma->vm_mm, GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	ld	[%o0 + AOFF_mm_context], %g2
 #ifndef CONFIG_SMP
 	cmp	%g2, -1
@@ -284,7 +284,7 @@ hypersparc_flush_tlb_mm_out:
 	 sta	%g5, [%g1] ASI_M_MMUREGS
 
 hypersparc_flush_tlb_range:
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	mov	SRMMU_CTX_REG, %g1
 	ld	[%o0 + AOFF_mm_context], %o3
 	lda	[%g1] ASI_M_MMUREGS, %g5
@@ -307,7 +307,7 @@ hypersparc_flush_tlb_range_out:
 	 sta	%g5, [%g1] ASI_M_MMUREGS
 
 hypersparc_flush_tlb_page:
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	mov	SRMMU_CTX_REG, %g1
 	ld	[%o0 + AOFF_mm_context], %o3
 	andn	%o1, (PAGE_SIZE - 1), %o1
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/mm/init_32.c linux-libre-3.11-rc7-gnu/arch/sparc/mm/init_32.c
--- linux-libre-3.10-gnu/arch/sparc/mm/init_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/mm/init_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -288,10 +288,6 @@ static void map_high_region(unsigned lon
 
 void __init mem_init(void)
 {
-	int codepages = 0;
-	int datapages = 0;
-	int initpages = 0; 
-	int reservedpages = 0;
 	int i;
 
 	if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
@@ -323,15 +319,12 @@ void __init mem_init(void)
 
 	max_mapnr = last_valid_pfn - pfn_base;
 	high_memory = __va(max_low_pfn << PAGE_SHIFT);
-
-	totalram_pages = free_all_bootmem();
+	free_all_bootmem();
 
 	for (i = 0; sp_banks[i].num_bytes != 0; i++) {
 		unsigned long start_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
 		unsigned long end_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
 
-		num_physpages += sp_banks[i].num_bytes >> PAGE_SHIFT;
-
 		if (end_pfn <= highstart_pfn)
 			continue;
 
@@ -341,39 +334,19 @@ void __init mem_init(void)
 		map_high_region(start_pfn, end_pfn);
 	}
 	
-	codepages = (((unsigned long) &_etext) - ((unsigned long)&_start));
-	codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT;
-	datapages = (((unsigned long) &_edata) - ((unsigned long)&_etext));
-	datapages = PAGE_ALIGN(datapages) >> PAGE_SHIFT;
-	initpages = (((unsigned long) &__init_end) - ((unsigned long) &__init_begin));
-	initpages = PAGE_ALIGN(initpages) >> PAGE_SHIFT;
-
-	/* Ignore memory holes for the purpose of counting reserved pages */
-	for (i=0; i < max_low_pfn; i++)
-		if (test_bit(i >> (20 - PAGE_SHIFT), sparc_valid_addr_bitmap)
-		    && PageReserved(pfn_to_page(i)))
-			reservedpages++;
-
-	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
-	       nr_free_pages() << (PAGE_SHIFT-10),
-	       num_physpages << (PAGE_SHIFT - 10),
-	       codepages << (PAGE_SHIFT-10),
-	       reservedpages << (PAGE_SHIFT - 10),
-	       datapages << (PAGE_SHIFT-10), 
-	       initpages << (PAGE_SHIFT-10),
-	       totalhigh_pages << (PAGE_SHIFT-10));
+	mem_init_print_info(NULL);
 }
 
 void free_initmem (void)
 {
-	num_physpages += free_initmem_default(POISON_FREE_INITMEM);
+	free_initmem_default(POISON_FREE_INITMEM);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	num_physpages += free_reserved_area(start, end, POISON_FREE_INITMEM,
-					    "initrd");
+	free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
+			   "initrd");
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/mm/init_64.c linux-libre-3.11-rc7-gnu/arch/sparc/mm/init_64.c
--- linux-libre-3.10-gnu/arch/sparc/mm/init_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/mm/init_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -1694,7 +1694,7 @@ static void __init sun4v_ktsb_init(void)
 #endif
 }
 
-void __cpuinit sun4v_ktsb_register(void)
+void sun4v_ktsb_register(void)
 {
 	unsigned long pa, ret;
 
@@ -2045,7 +2045,6 @@ static void __init register_page_bootmem
 }
 void __init mem_init(void)
 {
-	unsigned long codepages, datapages, initpages;
 	unsigned long addr, last;
 
 	addr = PAGE_OFFSET + kern_base;
@@ -2061,12 +2060,7 @@ void __init mem_init(void)
 	high_memory = __va(last_valid_pfn << PAGE_SHIFT);
 
 	register_page_bootmem_info();
-	totalram_pages = free_all_bootmem();
-
-	/* We subtract one to account for the mem_map_zero page
-	 * allocated below.
-	 */
-	num_physpages = totalram_pages - 1;
+	free_all_bootmem();
 
 	/*
 	 * Set up the zero page, mark it reserved, so that page count
@@ -2079,19 +2073,7 @@ void __init mem_init(void)
 	}
 	mark_page_reserved(mem_map_zero);
 
-	codepages = (((unsigned long) _etext) - ((unsigned long) _start));
-	codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT;
-	datapages = (((unsigned long) _edata) - ((unsigned long) _etext));
-	datapages = PAGE_ALIGN(datapages) >> PAGE_SHIFT;
-	initpages = (((unsigned long) __init_end) - ((unsigned long) __init_begin));
-	initpages = PAGE_ALIGN(initpages) >> PAGE_SHIFT;
-
-	printk("Memory: %luk available (%ldk kernel code, %ldk data, %ldk init) [%016lx,%016lx]\n",
-	       nr_free_pages() << (PAGE_SHIFT-10),
-	       codepages << (PAGE_SHIFT-10),
-	       datapages << (PAGE_SHIFT-10), 
-	       initpages << (PAGE_SHIFT-10), 
-	       PAGE_OFFSET, (last_valid_pfn << PAGE_SHIFT));
+	mem_init_print_info(NULL);
 
 	if (tlb_type == cheetah || tlb_type == cheetah_plus)
 		cheetah_ecache_flush_init();
@@ -2131,8 +2113,8 @@ void free_initmem(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	num_physpages += free_reserved_area(start, end, POISON_FREE_INITMEM,
-					    "initrd");
+	free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM,
+			   "initrd");
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/mm/srmmu.c linux-libre-3.11-rc7-gnu/arch/sparc/mm/srmmu.c
--- linux-libre-3.10-gnu/arch/sparc/mm/srmmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/mm/srmmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -858,7 +858,7 @@ static void __init map_kernel(void)
 	}
 }
 
-void (*poke_srmmu)(void) __cpuinitdata = NULL;
+void (*poke_srmmu)(void) = NULL;
 
 extern unsigned long bootmem_init(unsigned long *pages_avail);
 
@@ -1055,7 +1055,7 @@ static void __init init_vac_layout(void)
 	       (int)vac_cache_size, (int)vac_line_size);
 }
 
-static void __cpuinit poke_hypersparc(void)
+static void poke_hypersparc(void)
 {
 	volatile unsigned long clear;
 	unsigned long mreg = srmmu_get_mmureg();
@@ -1107,7 +1107,7 @@ static void __init init_hypersparc(void)
 	hypersparc_setup_blockops();
 }
 
-static void __cpuinit poke_swift(void)
+static void poke_swift(void)
 {
 	unsigned long mreg;
 
@@ -1287,7 +1287,7 @@ static void turbosparc_flush_tlb_page(st
 }
 
 
-static void __cpuinit poke_turbosparc(void)
+static void poke_turbosparc(void)
 {
 	unsigned long mreg = srmmu_get_mmureg();
 	unsigned long ccreg;
@@ -1350,7 +1350,7 @@ static void __init init_turbosparc(void)
 	poke_srmmu = poke_turbosparc;
 }
 
-static void __cpuinit poke_tsunami(void)
+static void poke_tsunami(void)
 {
 	unsigned long mreg = srmmu_get_mmureg();
 
@@ -1391,7 +1391,7 @@ static void __init init_tsunami(void)
 	tsunami_setup_blockops();
 }
 
-static void __cpuinit poke_viking(void)
+static void poke_viking(void)
 {
 	unsigned long mreg = srmmu_get_mmureg();
 	static int smp_catch;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/mm/swift.S linux-libre-3.11-rc7-gnu/arch/sparc/mm/swift.S
--- linux-libre-3.10-gnu/arch/sparc/mm/swift.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/mm/swift.S	2013-08-25 20:43:22.000000000 -0400
@@ -105,7 +105,7 @@ swift_flush_cache_mm_out:
 
 	.globl	swift_flush_cache_range
 swift_flush_cache_range:
-	ld	[%o0 + 0x0], %o0		/* XXX vma->vm_mm, GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	sub	%o2, %o1, %o2
 	sethi	%hi(4096), %o3
 	cmp	%o2, %o3
@@ -116,7 +116,7 @@ swift_flush_cache_range:
 
 	.globl	swift_flush_cache_page
 swift_flush_cache_page:
-	ld	[%o0 + 0x0], %o0		/* XXX vma->vm_mm, GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 70:
 	ld	[%o0 + AOFF_mm_context], %g2
 	cmp	%g2, -1
@@ -219,7 +219,7 @@ swift_flush_sig_insns:
 	.globl	swift_flush_tlb_range
 	.globl	swift_flush_tlb_all
 swift_flush_tlb_range:
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 swift_flush_tlb_mm:
 	ld	[%o0 + AOFF_mm_context], %g2
 	cmp	%g2, -1
@@ -233,7 +233,7 @@ swift_flush_tlb_all_out:
 
 	.globl	swift_flush_tlb_page
 swift_flush_tlb_page:
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	mov	SRMMU_CTX_REG, %g1
 	ld	[%o0 + AOFF_mm_context], %o3
 	andn	%o1, (PAGE_SIZE - 1), %o1
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/mm/tlb.c linux-libre-3.11-rc7-gnu/arch/sparc/mm/tlb.c
--- linux-libre-3.10-gnu/arch/sparc/mm/tlb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/mm/tlb.c	2013-08-25 20:43:22.000000000 -0400
@@ -188,7 +188,8 @@ void set_pmd_at(struct mm_struct *mm, un
 	}
 }
 
-void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable)
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+				pgtable_t pgtable)
 {
 	struct list_head *lh = (struct list_head *) pgtable;
 
@@ -202,7 +203,7 @@ void pgtable_trans_huge_deposit(struct m
 	mm->pmd_huge_pte = pgtable;
 }
 
-pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm)
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
 {
 	struct list_head *lh;
 	pgtable_t pgtable;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/mm/tsunami.S linux-libre-3.11-rc7-gnu/arch/sparc/mm/tsunami.S
--- linux-libre-3.10-gnu/arch/sparc/mm/tsunami.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/mm/tsunami.S	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
 	/* Sliiick... */
 tsunami_flush_cache_page:
 tsunami_flush_cache_range:
-	ld	[%o0 + 0x0], %o0	/* XXX vma->vm_mm, GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 tsunami_flush_cache_mm:
 	ld	[%o0 + AOFF_mm_context], %g2
 	cmp	%g2, -1
@@ -46,7 +46,7 @@ tsunami_flush_sig_insns:
 
 	/* More slick stuff... */
 tsunami_flush_tlb_range:
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 tsunami_flush_tlb_mm:
 	ld	[%o0 + AOFF_mm_context], %g2
 	cmp	%g2, -1
@@ -65,7 +65,7 @@ tsunami_flush_tlb_out:
 
 	/* This one can be done in a fine grained manner... */
 tsunami_flush_tlb_page:
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	mov	SRMMU_CTX_REG, %g1
 	ld	[%o0 + AOFF_mm_context], %o3
 	andn	%o1, (PAGE_SIZE - 1), %o1
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/mm/viking.S linux-libre-3.11-rc7-gnu/arch/sparc/mm/viking.S
--- linux-libre-3.10-gnu/arch/sparc/mm/viking.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/mm/viking.S	2013-08-25 20:43:22.000000000 -0400
@@ -108,7 +108,7 @@ viking_mxcc_flush_page:
 viking_flush_cache_page:
 viking_flush_cache_range:
 #ifndef CONFIG_SMP
-	ld	[%o0 + 0x0], %o0		/* XXX vma->vm_mm, GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 #endif
 viking_flush_cache_mm:
 #ifndef CONFIG_SMP
@@ -148,7 +148,7 @@ viking_flush_tlb_mm:
 #endif
 
 viking_flush_tlb_range:
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	mov	SRMMU_CTX_REG, %g1
 	ld	[%o0 + AOFF_mm_context], %o3
 	lda	[%g1] ASI_M_MMUREGS, %g5
@@ -173,7 +173,7 @@ viking_flush_tlb_range:
 #endif
 
 viking_flush_tlb_page:
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	mov	SRMMU_CTX_REG, %g1
 	ld	[%o0 + AOFF_mm_context], %o3
 	lda	[%g1] ASI_M_MMUREGS, %g5
@@ -239,7 +239,7 @@ sun4dsmp_flush_tlb_range:
 	tst	%g5
 	bne	3f
 	 mov	SRMMU_CTX_REG, %g1
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	ld	[%o0 + AOFF_mm_context], %o3
 	lda	[%g1] ASI_M_MMUREGS, %g5
 	sethi	%hi(~((1 << SRMMU_PGDIR_SHIFT) - 1)), %o4
@@ -265,7 +265,7 @@ sun4dsmp_flush_tlb_page:
 	tst	%g5
 	bne	2f
 	 mov	SRMMU_CTX_REG, %g1
-	ld	[%o0 + 0x00], %o0	/* XXX vma->vm_mm GROSS XXX */
+	ld	[%o0 + VMA_VM_MM], %o0
 	ld	[%o0 + AOFF_mm_context], %o3
 	lda	[%g1] ASI_M_MMUREGS, %g5
 	and	%o1, PAGE_MASK, %o1
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/sparc/net/bpf_jit_comp.c linux-libre-3.11-rc7-gnu/arch/sparc/net/bpf_jit_comp.c
--- linux-libre-3.10-gnu/arch/sparc/net/bpf_jit_comp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/sparc/net/bpf_jit_comp.c	2013-08-25 20:43:22.000000000 -0400
@@ -785,9 +785,7 @@ cond_branch:			f_offset = addrs[i + filt
 			break;
 		}
 		if (proglen == oldproglen) {
-			image = module_alloc(max_t(unsigned int,
-						   proglen,
-						   sizeof(struct work_struct)));
+			image = module_alloc(proglen);
 			if (!image)
 				goto out;
 		}
@@ -806,20 +804,8 @@ out:
 	return;
 }
 
-static void jit_free_defer(struct work_struct *arg)
-{
-	module_free(NULL, arg);
-}
-
-/* run from softirq, we must use a work_struct to call
- * module_free() from process context
- */
 void bpf_jit_free(struct sk_filter *fp)
 {
-	if (fp->bpf_func != sk_run_filter) {
-		struct work_struct *work = (struct work_struct *)fp->bpf_func;
-
-		INIT_WORK(work, jit_free_defer);
-		schedule_work(work);
-	}
+	if (fp->bpf_func != sk_run_filter)
+		module_free(NULL, fp->bpf_func);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/tile/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/tile/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -362,9 +362,6 @@ do {						\
 #define kern_addr_valid(addr)	(1)
 #endif /* CONFIG_FLATMEM */
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
-		remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 extern void vmalloc_sync_all(void);
 
 #endif /* !__ASSEMBLY__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/include/asm/processor.h linux-libre-3.11-rc7-gnu/arch/tile/include/asm/processor.h
--- linux-libre-3.10-gnu/arch/tile/include/asm/processor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/include/asm/processor.h	2013-08-25 20:43:22.000000000 -0400
@@ -225,7 +225,7 @@ extern int do_work_pending(struct pt_reg
 
 /*
  * Return saved (kernel) PC of a blocked thread.
- * Only used in a printk() in kernel/sched.c, so don't work too hard.
+ * Only used in a printk() in kernel/sched/core.c, so don't work too hard.
  */
 #define thread_saved_pc(t)   ((t)->thread.pc)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/include/asm/sections.h linux-libre-3.11-rc7-gnu/arch/tile/include/asm/sections.h
--- linux-libre-3.10-gnu/arch/tile/include/asm/sections.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/include/asm/sections.h	2013-08-25 20:43:22.000000000 -0400
@@ -34,7 +34,7 @@ extern char __sys_cmpxchg_grab_lock[];
 extern char __start_atomic_asm_code[], __end_atomic_asm_code[];
 #endif
 
-/* Handle the discontiguity between _sdata and _stext. */
+/* Handle the discontiguity between _sdata and _text. */
 static inline int arch_is_kernel_data(unsigned long addr)
 {
 	return addr >= (unsigned long)_sdata &&
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/include/asm/uaccess.h linux-libre-3.11-rc7-gnu/arch/tile/include/asm/uaccess.h
--- linux-libre-3.10-gnu/arch/tile/include/asm/uaccess.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/include/asm/uaccess.h	2013-08-25 20:43:22.000000000 -0400
@@ -442,7 +442,7 @@ extern unsigned long __copy_in_user_inat
 static inline unsigned long __must_check
 __copy_in_user(void __user *to, const void __user *from, unsigned long n)
 {
-	might_sleep();
+	might_fault();
 	return __copy_in_user_inatomic(to, from, n);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/Kconfig linux-libre-3.11-rc7-gnu/arch/tile/Kconfig
--- linux-libre-3.10-gnu/arch/tile/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,7 @@ config TILE
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_SYSCALL_TRACEPOINTS
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+	select HAVE_DEBUG_STACKOVERFLOW
 
 # FIXME: investigate whether we need/want these options.
 #	select HAVE_IOREMAP_PROT
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/tile/Kconfig.debug
--- linux-libre-3.10-gnu/arch/tile/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -14,13 +14,6 @@ config EARLY_PRINTK
 	  with klogd/syslogd. You should normally N here,
 	  unless you want to debug such a crash.
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-	help
-	  This option will cause messages to be printed if free stack space
-	  drops below a certain limit.
-
 config DEBUG_EXTRA_FLAGS
 	string "Additional compiler arguments when building with '-g'"
 	depends on DEBUG_INFO
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/kernel/irq.c linux-libre-3.11-rc7-gnu/arch/tile/kernel/irq.c
--- linux-libre-3.10-gnu/arch/tile/kernel/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/kernel/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -220,7 +220,7 @@ void __init init_IRQ(void)
 	ipi_init();
 }
 
-void __cpuinit setup_irq_regs(void)
+void setup_irq_regs(void)
 {
 	/* Enable interrupt delivery. */
 	unmask_irqs(~0UL);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/kernel/messaging.c linux-libre-3.11-rc7-gnu/arch/tile/kernel/messaging.c
--- linux-libre-3.10-gnu/arch/tile/kernel/messaging.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/kernel/messaging.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@
 /* All messages are stored here */
 static DEFINE_PER_CPU(HV_MsgState, msg_state);
 
-void __cpuinit init_messaging(void)
+void init_messaging(void)
 {
 	/* Allocate storage for messages in kernel space */
 	HV_MsgState *state = &__get_cpu_var(msg_state);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/tile/kernel/setup.c
--- linux-libre-3.10-gnu/arch/tile/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -58,8 +58,8 @@ struct pglist_data node_data[MAX_NUMNODE
 EXPORT_SYMBOL(node_data);
 
 /* Information on the NUMA nodes that we compute early */
-unsigned long __cpuinitdata node_start_pfn[MAX_NUMNODES];
-unsigned long __cpuinitdata node_end_pfn[MAX_NUMNODES];
+unsigned long node_start_pfn[MAX_NUMNODES];
+unsigned long node_end_pfn[MAX_NUMNODES];
 unsigned long __initdata node_memmap_pfn[MAX_NUMNODES];
 unsigned long __initdata node_percpu_pfn[MAX_NUMNODES];
 unsigned long __initdata node_free_pfn[MAX_NUMNODES];
@@ -84,7 +84,7 @@ unsigned long __initdata boot_pc = (unsi
 
 #ifdef CONFIG_HIGHMEM
 /* Page frame index of end of lowmem on each controller. */
-unsigned long __cpuinitdata node_lowmem_end_pfn[MAX_NUMNODES];
+unsigned long node_lowmem_end_pfn[MAX_NUMNODES];
 
 /* Number of pages that can be mapped into lowmem. */
 static unsigned long __initdata mappable_physpages;
@@ -290,7 +290,7 @@ static void *__init setup_pa_va_mapping(
  * This is up to 4 mappings for lowmem, one mapping per memory
  * controller, plus one for our text segment.
  */
-static void __cpuinit store_permanent_mappings(void)
+static void store_permanent_mappings(void)
 {
 	int i;
 
@@ -307,8 +307,8 @@ static void __cpuinit store_permanent_ma
 		hv_store_mapping(addr, pages << PAGE_SHIFT, pa);
 	}
 
-	hv_store_mapping((HV_VirtAddr)_stext,
-			 (uint32_t)(_einittext - _stext), 0);
+	hv_store_mapping((HV_VirtAddr)_text,
+			 (uint32_t)(_einittext - _text), 0);
 }
 
 /*
@@ -329,6 +329,7 @@ static void __init setup_memory(void)
 #if defined(CONFIG_HIGHMEM) || defined(__tilegx__)
 	long lowmem_pages;
 #endif
+	unsigned long physpages = 0;
 
 	/* We are using a char to hold the cpu_2_node[] mapping */
 	BUILD_BUG_ON(MAX_NUMNODES > 127);
@@ -388,8 +389,8 @@ static void __init setup_memory(void)
 				continue;
 			}
 		}
-		if (num_physpages + PFN_DOWN(range.size) > maxmem_pfn) {
-			int max_size = maxmem_pfn - num_physpages;
+		if (physpages + PFN_DOWN(range.size) > maxmem_pfn) {
+			int max_size = maxmem_pfn - physpages;
 			if (max_size > 0) {
 				pr_err("Maxmem reduced node %d to %d pages\n",
 				       i, max_size);
@@ -446,7 +447,7 @@ static void __init setup_memory(void)
 		node_start_pfn[i] = start;
 		node_end_pfn[i] = end;
 		node_controller[i] = range.controller;
-		num_physpages += size;
+		physpages += size;
 		max_pfn = end;
 
 		/* Mark node as online */
@@ -465,7 +466,7 @@ static void __init setup_memory(void)
 	 * we're willing to use at 8 million pages (32GB of 4KB pages).
 	 */
 	cap = 8 * 1024 * 1024;  /* 8 million pages */
-	if (num_physpages > cap) {
+	if (physpages > cap) {
 		int num_nodes = num_online_nodes();
 		int cap_each = cap / num_nodes;
 		unsigned long dropped_pages = 0;
@@ -476,10 +477,10 @@ static void __init setup_memory(void)
 				node_end_pfn[i] = node_start_pfn[i] + cap_each;
 			}
 		}
-		num_physpages -= dropped_pages;
+		physpages -= dropped_pages;
 		pr_warning("Only using %ldMB memory;"
 		       " ignoring %ldMB.\n",
-		       num_physpages >> (20 - PAGE_SHIFT),
+		       physpages >> (20 - PAGE_SHIFT),
 		       dropped_pages >> (20 - PAGE_SHIFT));
 		pr_warning("Consider using a larger page size.\n");
 	}
@@ -497,7 +498,7 @@ static void __init setup_memory(void)
 
 	lowmem_pages = (mappable_physpages > MAXMEM_PFN) ?
 		MAXMEM_PFN : mappable_physpages;
-	highmem_pages = (long) (num_physpages - lowmem_pages);
+	highmem_pages = (long) (physpages - lowmem_pages);
 
 	pr_notice("%ldMB HIGHMEM available.\n",
 	       pages_to_mb(highmem_pages > 0 ? highmem_pages : 0));
@@ -514,7 +515,6 @@ static void __init setup_memory(void)
 		pr_warning("Use a HIGHMEM enabled kernel.\n");
 		max_low_pfn = MAXMEM_PFN;
 		max_pfn = MAXMEM_PFN;
-		num_physpages = MAXMEM_PFN;
 		node_end_pfn[0] = MAXMEM_PFN;
 	} else {
 		pr_notice("%ldMB memory available.\n",
@@ -935,7 +935,7 @@ subsys_initcall(topology_init);
  * So the values we set up here in the hypervisor may be overridden on
  * the boot cpu as arguments are parsed.
  */
-static __cpuinit void init_super_pages(void)
+static void init_super_pages(void)
 {
 #ifdef CONFIG_HUGETLB_SUPER_PAGES
 	int i;
@@ -950,7 +950,7 @@ static __cpuinit void init_super_pages(v
  *
  * Called from setup_arch() on the boot cpu, or online_secondary().
  */
-void __cpuinit setup_cpu(int boot)
+void setup_cpu(int boot)
 {
 	/* The boot cpu sets up its permanent mappings much earlier. */
 	if (!boot)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/kernel/smpboot.c linux-libre-3.11-rc7-gnu/arch/tile/kernel/smpboot.c
--- linux-libre-3.10-gnu/arch/tile/kernel/smpboot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/kernel/smpboot.c	2013-08-25 20:43:22.000000000 -0400
@@ -133,14 +133,14 @@ static __init int reset_init_affinity(vo
 }
 late_initcall(reset_init_affinity);
 
-static struct cpumask cpu_started __cpuinitdata;
+static struct cpumask cpu_started;
 
 /*
  * Activate a secondary processor.  Very minimal; don't add anything
  * to this path without knowing what you're doing, since SMP booting
  * is pretty fragile.
  */
-static void __cpuinit start_secondary(void)
+static void start_secondary(void)
 {
 	int cpuid = smp_processor_id();
 
@@ -183,7 +183,7 @@ static void __cpuinit start_secondary(vo
 /*
  * Bring a secondary processor online.
  */
-void __cpuinit online_secondary(void)
+void online_secondary(void)
 {
 	/*
 	 * low-memory mappings have been cleared, flush them from
@@ -210,7 +210,7 @@ void __cpuinit online_secondary(void)
 	cpu_startup_entry(CPUHP_ONLINE);
 }
 
-int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	/* Wait 5s total for all CPUs for them to come online */
 	static int timeout;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/kernel/stack.c linux-libre-3.11-rc7-gnu/arch/tile/kernel/stack.c
--- linux-libre-3.10-gnu/arch/tile/kernel/stack.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/kernel/stack.c	2013-08-25 20:43:22.000000000 -0400
@@ -442,7 +442,7 @@ void _KBacktraceIterator_init_current(st
 				regs_to_pt_regs(&regs, pc, lr, sp, r52));
 }
 
-/* This is called only from kernel/sched.c, with esp == NULL */
+/* This is called only from kernel/sched/core.c, with esp == NULL */
 void show_stack(struct task_struct *task, unsigned long *esp)
 {
 	struct KBacktraceIterator kbt;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/kernel/time.c linux-libre-3.11-rc7-gnu/arch/tile/kernel/time.c
--- linux-libre-3.10-gnu/arch/tile/kernel/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/kernel/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -159,7 +159,7 @@ static DEFINE_PER_CPU(struct clock_event
 	.set_mode = tile_timer_set_mode,
 };
 
-void __cpuinit setup_tile_timer(void)
+void setup_tile_timer(void)
 {
 	struct clock_event_device *evt = &__get_cpu_var(tile_timer);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/kernel/vmlinux.lds.S linux-libre-3.11-rc7-gnu/arch/tile/kernel/vmlinux.lds.S
--- linux-libre-3.10-gnu/arch/tile/kernel/vmlinux.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/kernel/vmlinux.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,6 @@ SECTIONS
   .intrpt1 (LOAD_OFFSET) : AT ( 0 )   /* put at the start of physical memory */
   {
     _text = .;
-    _stext = .;
     *(.intrpt1)
   } :intrpt1 =0
 
@@ -36,6 +35,7 @@ SECTIONS
 
   /* Now the real code */
   . = ALIGN(0x20000);
+  _stext = .;
   .text : AT (ADDR(.text) - LOAD_OFFSET) {
     HEAD_TEXT
     SCHED_TEXT
@@ -58,11 +58,13 @@ SECTIONS
   #define LOAD_OFFSET PAGE_OFFSET
 
   . = ALIGN(PAGE_SIZE);
+  __init_begin = .;
   VMLINUX_SYMBOL(_sinitdata) = .;
   INIT_DATA_SECTION(16) :data =0
   PERCPU_SECTION(L2_CACHE_BYTES)
   . = ALIGN(PAGE_SIZE);
   VMLINUX_SYMBOL(_einitdata) = .;
+  __init_end = .;
 
   _sdata = .;                   /* Start of data section */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/mm/fault.c linux-libre-3.11-rc7-gnu/arch/tile/mm/fault.c
--- linux-libre-3.10-gnu/arch/tile/mm/fault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/mm/fault.c	2013-08-25 20:43:22.000000000 -0400
@@ -573,10 +573,10 @@ out_of_memory:
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
-	pr_alert("VM: killing process %s\n", tsk->comm);
-	if (!is_kernel_mode)
-		do_group_exit(SIGKILL);
-	goto no_context;
+	if (is_kernel_mode)
+		goto no_context;
+	pagefault_out_of_memory();
+	return 0;
 
 do_sigbus:
 	up_read(&mm->mmap_sem);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/mm/init.c linux-libre-3.11-rc7-gnu/arch/tile/mm/init.c
--- linux-libre-3.10-gnu/arch/tile/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -562,7 +562,7 @@ static void __init kernel_physical_mappi
 			prot = ktext_set_nocache(prot);
 		}
 
-		BUG_ON(address != (unsigned long)_stext);
+		BUG_ON(address != (unsigned long)_text);
 		pte = NULL;
 		for (; address < (unsigned long)_einittext;
 		     pfn++, address += PAGE_SIZE) {
@@ -720,7 +720,7 @@ static void __init init_free_pfn_range(u
 		}
 		init_page_count(page);
 		__free_pages(page, order);
-		totalram_pages += count;
+		adjust_managed_page_count(page, count);
 
 		page += count;
 		pfn += count;
@@ -821,7 +821,6 @@ static void __init set_max_mapnr_init(vo
 
 void __init mem_init(void)
 {
-	int codesize, datasize, initsize;
 	int i;
 #ifndef __tilegx__
 	void *last;
@@ -846,26 +845,14 @@ void __init mem_init(void)
 	set_max_mapnr_init();
 
 	/* this will put all bootmem onto the freelists */
-	totalram_pages += free_all_bootmem();
+	free_all_bootmem();
 
 #ifndef CONFIG_64BIT
 	/* count all remaining LOWMEM and give all HIGHMEM to page allocator */
 	set_non_bootmem_pages_init();
 #endif
 
-	codesize =  (unsigned long)&_etext - (unsigned long)&_text;
-	datasize =  (unsigned long)&_end - (unsigned long)&_sdata;
-	initsize =  (unsigned long)&_einittext - (unsigned long)&_sinittext;
-	initsize += (unsigned long)&_einitdata - (unsigned long)&_sinitdata;
-
-	pr_info("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
-		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10,
-		datasize >> 10,
-		initsize >> 10,
-		(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
-	       );
+	mem_init_print_info(NULL);
 
 	/*
 	 * In debug mode, dump some interesting memory mappings.
@@ -1024,16 +1011,13 @@ static void free_init_pages(char *what,
 			pte_clear(&init_mm, addr, ptep);
 			continue;
 		}
-		__ClearPageReserved(page);
-		init_page_count(page);
 		if (pte_huge(*ptep))
 			BUG_ON(!kdata_huge);
 		else
 			set_pte_at(&init_mm, addr, ptep,
 				   pfn_pte(pfn, PAGE_KERNEL));
 		memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
-		free_page(addr);
-		totalram_pages++;
+		free_reserved_page(page);
 	}
 	pr_info("Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/tile/mm/mmap.c linux-libre-3.11-rc7-gnu/arch/tile/mm/mmap.c
--- linux-libre-3.10-gnu/arch/tile/mm/mmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/tile/mm/mmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,10 +66,8 @@ void arch_pick_mmap_layout(struct mm_str
 	if (!is_32bit || rlimit(RLIMIT_STACK) == RLIM_INFINITY) {
 		mm->mmap_base = TASK_UNMAPPED_BASE;
 		mm->get_unmapped_area = arch_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
 	} else {
 		mm->mmap_base = mmap_base(mm);
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/include/asm/common.lds.S linux-libre-3.11-rc7-gnu/arch/um/include/asm/common.lds.S
--- linux-libre-3.10-gnu/arch/um/include/asm/common.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/include/asm/common.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -57,7 +57,6 @@
 	*(.uml.initcall.init)
 	__uml_initcall_end = .;
   }
-  __init_end = .;
 
   SECURITY_INIT
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/um/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/um/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -69,8 +69,6 @@ extern unsigned long end_iomem;
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
 #define PAGE_KERNEL_EXEC	__pgprot(__PAGE_KERNEL_EXEC)
 
-#define io_remap_pfn_range	remap_pfn_range
-
 /*
  * The i386 can't do page protection for execute, and considers that the same
  * are read.
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/include/asm/tlb.h linux-libre-3.11-rc7-gnu/arch/um/include/asm/tlb.h
--- linux-libre-3.10-gnu/arch/um/include/asm/tlb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/include/asm/tlb.h	2013-08-25 20:43:22.000000000 -0400
@@ -45,10 +45,12 @@ static inline void init_tlb_gather(struc
 }
 
 static inline void
-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
 {
 	tlb->mm = mm;
-	tlb->fullmm = full_mm_flush;
+	tlb->start = start;
+	tlb->end = end;
+	tlb->fullmm = !(start | (end+1));
 
 	init_tlb_gather(tlb);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/include/shared/frame_kern.h linux-libre-3.11-rc7-gnu/arch/um/include/shared/frame_kern.h
--- linux-libre-3.10-gnu/arch/um/include/shared/frame_kern.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/include/shared/frame_kern.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,13 +6,13 @@
 #ifndef __FRAME_KERN_H_
 #define __FRAME_KERN_H_
 
-extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 
+extern int setup_signal_stack_sc(unsigned long stack_top, int sig,
 				 struct k_sigaction *ka,
-				 struct pt_regs *regs, 
+				 struct pt_regs *regs,
 				 sigset_t *mask);
-extern int setup_signal_stack_si(unsigned long stack_top, int sig, 
+extern int setup_signal_stack_si(unsigned long stack_top, int sig,
 				 struct k_sigaction *ka,
-				 struct pt_regs *regs, siginfo_t *info, 
+				 struct pt_regs *regs, struct siginfo *info,
 				 sigset_t *mask);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/kernel/dyn.lds.S linux-libre-3.11-rc7-gnu/arch/um/kernel/dyn.lds.S
--- linux-libre-3.10-gnu/arch/um/kernel/dyn.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/kernel/dyn.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -14,8 +14,6 @@ SECTIONS
   __binary_start = .;
   . = ALIGN(4096);		/* Init code and data */
   _text = .;
-  _stext = .;
-  __init_begin = .;
   INIT_TEXT_SECTION(PAGE_SIZE)
 
   . = ALIGN(PAGE_SIZE);
@@ -67,6 +65,7 @@ SECTIONS
   } =0x90909090
   .plt            : { *(.plt) }
   .text           : {
+    _stext = .;
     TEXT_TEXT
     SCHED_TEXT
     LOCK_TEXT
@@ -91,7 +90,9 @@ SECTIONS
 
   #include <asm/common.lds.S>
 
+  __init_begin = .;
   init.data : { INIT_DATA }
+  __init_end = .;
 
   /* Ensure the __preinit_array_start label is properly aligned.  We
      could instead move the label definition inside the section, but
@@ -155,6 +156,7 @@ SECTIONS
    . = ALIGN(32 / 8);
   . = ALIGN(32 / 8);
   }
+   __bss_stop = .;
   _end = .;
   PROVIDE (end = .);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/kernel/mem.c linux-libre-3.11-rc7-gnu/arch/um/kernel/mem.c
--- linux-libre-3.10-gnu/arch/um/kernel/mem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/kernel/mem.c	2013-08-25 20:43:22.000000000 -0400
@@ -65,15 +65,13 @@ void __init mem_init(void)
 	uml_reserved = brk_end;
 
 	/* this will put all low memory onto the freelists */
-	totalram_pages = free_all_bootmem();
+	free_all_bootmem();
 	max_low_pfn = totalram_pages;
 #ifdef CONFIG_HIGHMEM
 	setup_highmem(end_iomem, highmem);
 #endif
-	num_physpages = totalram_pages;
 	max_pfn = totalram_pages;
-	printk(KERN_INFO "Memory: %luk available\n",
-	       nr_free_pages() << (PAGE_SHIFT-10));
+	mem_init_print_info(NULL);
 	kmalloc_ok = 1;
 }
 
@@ -244,7 +242,7 @@ void free_initmem(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	free_reserved_area(start, end, 0, "initrd");
+	free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/kernel/signal.c linux-libre-3.11-rc7-gnu/arch/um/kernel/signal.c
--- linux-libre-3.10-gnu/arch/um/kernel/signal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/kernel/signal.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,7 +19,7 @@ EXPORT_SYMBOL(unblock_signals);
  * OK, we're invoking a handler
  */
 static void handle_signal(struct pt_regs *regs, unsigned long signr,
-			 struct k_sigaction *ka, siginfo_t *info)
+			 struct k_sigaction *ka, struct siginfo *info)
 {
 	sigset_t *oldset = sigmask_to_save();
 	int singlestep = 0;
@@ -71,7 +71,7 @@ static void handle_signal(struct pt_regs
 static int kern_do_signal(struct pt_regs *regs)
 {
 	struct k_sigaction ka_copy;
-	siginfo_t info;
+	struct siginfo info;
 	int sig, handled_sig = 0;
 
 	while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/kernel/skas/mmu.c linux-libre-3.11-rc7-gnu/arch/um/kernel/skas/mmu.c
--- linux-libre-3.10-gnu/arch/um/kernel/skas/mmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/kernel/skas/mmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -123,7 +123,7 @@ void uml_setup_stubs(struct mm_struct *m
 	/* dup_mmap already holds mmap_sem */
 	err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START,
 				      VM_READ | VM_MAYREAD | VM_EXEC |
-				      VM_MAYEXEC | VM_DONTCOPY,
+				      VM_MAYEXEC | VM_DONTCOPY | VM_PFNMAP,
 				      mm->context.stub_pages);
 	if (err) {
 		printk(KERN_ERR "install_special_mapping returned %d\n", err);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/kernel/skas/uaccess.c linux-libre-3.11-rc7-gnu/arch/um/kernel/skas/uaccess.c
--- linux-libre-3.10-gnu/arch/um/kernel/skas/uaccess.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/kernel/skas/uaccess.c	2013-08-25 20:43:22.000000000 -0400
@@ -254,6 +254,6 @@ int strnlen_user(const void __user *str,
 	n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
 	if (n == 0)
 		return count + 1;
-	return -EFAULT;
+	return 0;
 }
 EXPORT_SYMBOL(strnlen_user);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/kernel/sysrq.c linux-libre-3.11-rc7-gnu/arch/um/kernel/sysrq.c
--- linux-libre-3.10-gnu/arch/um/kernel/sysrq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/kernel/sysrq.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,7 @@ void show_trace(struct task_struct *task
 static const int kstack_depth_to_print = 24;
 
 /* This recently started being used in arch-independent code too, as in
- * kernel/sched.c.*/
+ * kernel/sched/core.c.*/
 void show_stack(struct task_struct *task, unsigned long *esp)
 {
 	unsigned long *stack;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/kernel/uml.lds.S linux-libre-3.11-rc7-gnu/arch/um/kernel/uml.lds.S
--- linux-libre-3.10-gnu/arch/um/kernel/uml.lds.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/kernel/uml.lds.S	2013-08-25 20:43:22.000000000 -0400
@@ -20,13 +20,12 @@ SECTIONS
   . = START + SIZEOF_HEADERS;
 
   _text = .;
-  _stext = .;
-  __init_begin = .;
   INIT_TEXT_SECTION(0)
   . = ALIGN(PAGE_SIZE);
 
   .text      :
   {
+    _stext = .;
     TEXT_TEXT
     SCHED_TEXT
     LOCK_TEXT
@@ -62,7 +61,10 @@ SECTIONS
 
   #include <asm/common.lds.S>
 
+  __init_begin = .;
   init.data : { INIT_DATA }
+  __init_end = .;
+
   .data    :
   {
     INIT_TASK_DATA(KERNEL_STACK_SIZE)
@@ -97,6 +99,7 @@ SECTIONS
   PROVIDE(_bss_start = .);
   SBSS(0)
   BSS(0)
+   __bss_stop = .;
   _end = .;
   PROVIDE (end = .);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/os-Linux/mem.c linux-libre-3.11-rc7-gnu/arch/um/os-Linux/mem.c
--- linux-libre-3.10-gnu/arch/um/os-Linux/mem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/os-Linux/mem.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,6 +53,25 @@ static void __init find_tempdir(void)
 }
 
 /*
+ * Remove bytes from the front of the buffer and refill it so that if there's a
+ * partial string that we care about, it will be completed, and we can recognize
+ * it.
+ */
+static int pop(int fd, char *buf, size_t size, size_t npop)
+{
+	ssize_t n;
+	size_t len = strlen(&buf[npop]);
+
+	memmove(buf, &buf[npop], len + 1);
+	n = read(fd, &buf[len], size - len - 1);
+	if (n < 0)
+		return -errno;
+
+	buf[len + n] = '\0';
+	return 1;
+}
+
+/*
  * This will return 1, with the first character in buf being the
  * character following the next instance of c in the file.  This will
  * read the file as needed.  If there's an error, -errno is returned;
@@ -61,7 +80,6 @@ static void __init find_tempdir(void)
 static int next(int fd, char *buf, size_t size, char c)
 {
 	ssize_t n;
-	size_t len;
 	char *ptr;
 
 	while ((ptr = strchr(buf, c)) == NULL) {
@@ -74,20 +92,129 @@ static int next(int fd, char *buf, size_
 		buf[n] = '\0';
 	}
 
-	ptr++;
-	len = strlen(ptr);
-	memmove(buf, ptr, len + 1);
+	return pop(fd, buf, size, ptr - buf + 1);
+}
+
+/*
+ * Decode an octal-escaped and space-terminated path of the form used by
+ * /proc/mounts. May be used to decode a path in-place. "out" must be at least
+ * as large as the input. The output is always null-terminated. "len" gets the
+ * length of the output, excluding the trailing null. Returns 0 if a full path
+ * was successfully decoded, otherwise an error.
+ */
+static int decode_path(const char *in, char *out, size_t *len)
+{
+	char *first = out;
+	int c;
+	int i;
+	int ret = -EINVAL;
+	while (1) {
+		switch (*in) {
+		case '\0':
+			goto out;
+
+		case ' ':
+			ret = 0;
+			goto out;
+
+		case '\\':
+			in++;
+			c = 0;
+			for (i = 0; i < 3; i++) {
+				if (*in < '0' || *in > '7')
+					goto out;
+				c = (c << 3) | (*in++ - '0');
+			}
+			*(unsigned char *)out++ = (unsigned char) c;
+			break;
+
+		default:
+			*out++ = *in++;
+			break;
+		}
+	}
+
+out:
+	*out = '\0';
+	*len = out - first;
+	return ret;
+}
+
+/*
+ * Computes the length of s when encoded with three-digit octal escape sequences
+ * for the characters in chars.
+ */
+static size_t octal_encoded_length(const char *s, const char *chars)
+{
+	size_t len = strlen(s);
+	while ((s = strpbrk(s, chars)) != NULL) {
+		len += 3;
+		s++;
+	}
+
+	return len;
+}
+
+enum {
+	OUTCOME_NOTHING_MOUNTED,
+	OUTCOME_TMPFS_MOUNT,
+	OUTCOME_NON_TMPFS_MOUNT,
+};
+
+/* Read a line of /proc/mounts data looking for a tmpfs mount at "path". */
+static int read_mount(int fd, char *buf, size_t bufsize, const char *path,
+		      int *outcome)
+{
+	int found;
+	int match;
+	char *space;
+	size_t len;
+
+	enum {
+		MATCH_NONE,
+		MATCH_EXACT,
+		MATCH_PARENT,
+	};
+
+	found = next(fd, buf, bufsize, ' ');
+	if (found != 1)
+		return found;
 
 	/*
-	 * Refill the buffer so that if there's a partial string that we care
-	 * about, it will be completed, and we can recognize it.
+	 * If there's no following space in the buffer, then this path is
+	 * truncated, so it can't be the one we're looking for.
 	 */
-	n = read(fd, &buf[len], size - len - 1);
-	if (n < 0)
-		return -errno;
+	space = strchr(buf, ' ');
+	if (space) {
+		match = MATCH_NONE;
+		if (!decode_path(buf, buf, &len)) {
+			if (!strcmp(buf, path))
+				match = MATCH_EXACT;
+			else if (!strncmp(buf, path, len)
+				 && (path[len] == '/' || !strcmp(buf, "/")))
+				match = MATCH_PARENT;
+		}
 
-	buf[len + n] = '\0';
-	return 1;
+		found = pop(fd, buf, bufsize, space - buf + 1);
+		if (found != 1)
+			return found;
+
+		switch (match) {
+		case MATCH_EXACT:
+			if (!strncmp(buf, "tmpfs", strlen("tmpfs")))
+				*outcome = OUTCOME_TMPFS_MOUNT;
+			else
+				*outcome = OUTCOME_NON_TMPFS_MOUNT;
+			break;
+
+		case MATCH_PARENT:
+			/* This mount obscures any previous ones. */
+			*outcome = OUTCOME_NOTHING_MOUNTED;
+			break;
+		}
+	}
+
+	return next(fd, buf, bufsize, '\n');
 }
 
 /* which_tmpdir is called only during early boot */
@@ -106,8 +233,12 @@ static int checked_tmpdir = 0;
  */
 static void which_tmpdir(void)
 {
-	int fd, found;
-	char buf[128] = { '\0' };
+	int fd;
+	int found;
+	int outcome;
+	char *path;
+	char *buf;
+	size_t bufsize;
 
 	if (checked_tmpdir)
 		return;
@@ -116,49 +247,66 @@ static void which_tmpdir(void)
 
 	printf("Checking for tmpfs mount on /dev/shm...");
 
+	path = realpath("/dev/shm", NULL);
+	if (!path) {
+		printf("failed to check real path, errno = %d\n", errno);
+		return;
+	}
+	printf("%s...", path);
+
+	/*
+	 * The buffer needs to be able to fit the full octal-escaped path, a
+	 * space, and a trailing null in order to successfully decode it.
+	 */
+	bufsize = octal_encoded_length(path, " \t\n\\") + 2;
+
+	if (bufsize < 128)
+		bufsize = 128;
+
+	buf = malloc(bufsize);
+	if (!buf) {
+		printf("malloc failed, errno = %d\n", errno);
+		goto out;
+	}
+	buf[0] = '\0';
+
 	fd = open("/proc/mounts", O_RDONLY);
 	if (fd < 0) {
 		printf("failed to open /proc/mounts, errno = %d\n", errno);
-		return;
+		goto out1;
 	}
 
+	outcome = OUTCOME_NOTHING_MOUNTED;
 	while (1) {
-		found = next(fd, buf, ARRAY_SIZE(buf), ' ');
-		if (found != 1)
-			break;
-
-		if (!strncmp(buf, "/dev/shm", strlen("/dev/shm")))
-			goto found;
-
-		found = next(fd, buf, ARRAY_SIZE(buf), '\n');
+		found = read_mount(fd, buf, bufsize, path, &outcome);
 		if (found != 1)
 			break;
 	}
 
-err:
-	if (found == 0)
-		printf("nothing mounted on /dev/shm\n");
-	else if (found < 0)
+	if (found < 0) {
 		printf("read returned errno %d\n", -found);
+	} else {
+		switch (outcome) {
+		case OUTCOME_TMPFS_MOUNT:
+			printf("OK\n");
+			default_tmpdir = "/dev/shm";
+			break;
 
-out:
-	close(fd);
-
-	return;
-
-found:
-	found = next(fd, buf, ARRAY_SIZE(buf), ' ');
-	if (found != 1)
-		goto err;
+		case OUTCOME_NON_TMPFS_MOUNT:
+			printf("not tmpfs\n");
+			break;
 
-	if (strncmp(buf, "tmpfs", strlen("tmpfs"))) {
-		printf("not tmpfs\n");
-		goto out;
+		default:
+			printf("nothing mounted on /dev/shm\n");
+			break;
+		}
 	}
 
-	printf("OK\n");
-	default_tmpdir = "/dev/shm";
-	goto out;
+	close(fd);
+out1:
+	free(buf);
+out:
+	free(path);
 }
 
 static int __init make_tempfile(const char *template, char **out_tempname,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/os-Linux/signal.c linux-libre-3.11-rc7-gnu/arch/um/os-Linux/signal.c
--- linux-libre-3.10-gnu/arch/um/os-Linux/signal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/os-Linux/signal.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@ void (*sig_info[NSIG])(int, struct sigin
 	[SIGIO]		= sigio_handler,
 	[SIGVTALRM]	= timer_handler };
 
-static void sig_handler_common(int sig, siginfo_t *si, mcontext_t *mc)
+static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
 {
 	struct uml_pt_regs r;
 	int save_errno = errno;
@@ -61,7 +61,7 @@ static void sig_handler_common(int sig,
 static int signals_enabled;
 static unsigned int signals_pending;
 
-void sig_handler(int sig, siginfo_t *si, mcontext_t *mc)
+void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
 {
 	int enabled;
 
@@ -120,7 +120,7 @@ void set_sigstack(void *sig_stack, int s
 		panic("enabling signal stack failed, errno = %d\n", errno);
 }
 
-static void (*handlers[_NSIG])(int sig, siginfo_t *si, mcontext_t *mc) = {
+static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = {
 	[SIGSEGV] = sig_handler,
 	[SIGBUS] = sig_handler,
 	[SIGILL] = sig_handler,
@@ -162,7 +162,7 @@ static void hard_handler(int sig, siginf
 		while ((sig = ffs(pending)) != 0){
 			sig--;
 			pending &= ~(1 << sig);
-			(*handlers[sig])(sig, si, mc);
+			(*handlers[sig])(sig, (struct siginfo *)si, mc);
 		}
 
 		/*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/um/os-Linux/skas/process.c linux-libre-3.11-rc7-gnu/arch/um/os-Linux/skas/process.c
--- linux-libre-3.10-gnu/arch/um/os-Linux/skas/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/um/os-Linux/skas/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ static int ptrace_dump_regs(int pid)
 
 void wait_stub_done(int pid)
 {
-	int n, status, err;
+	int n, status, err, bad_stop = 0;
 
 	while (1) {
 		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL));
@@ -74,6 +74,8 @@ void wait_stub_done(int pid)
 
 	if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
 		return;
+	else
+		bad_stop = 1;
 
 bad_wait:
 	err = ptrace_dump_regs(pid);
@@ -83,7 +85,10 @@ bad_wait:
 	printk(UM_KERN_ERR "wait_stub_done : failed to wait for SIGTRAP, "
 	       "pid = %d, n = %d, errno = %d, status = 0x%x\n", pid, n, errno,
 	       status);
-	fatal_sigsegv();
+	if (bad_stop)
+		kill(pid, SIGKILL);
+	else
+		fatal_sigsegv();
 }
 
 extern unsigned long current_stub_stack(void);
@@ -409,7 +414,7 @@ void userspace(struct uml_pt_regs *regs)
 		if (WIFSTOPPED(status)) {
 			int sig = WSTOPSIG(status);
 
-			ptrace(PTRACE_GETSIGINFO, pid, 0, &si);
+			ptrace(PTRACE_GETSIGINFO, pid, 0, (struct siginfo *)&si);
 
 			switch (sig) {
 			case SIGSEGV:
@@ -417,7 +422,7 @@ void userspace(struct uml_pt_regs *regs)
 				    !ptrace_faultinfo) {
 					get_skas_faultinfo(pid,
 							   &regs->faultinfo);
-					(*sig_info[SIGSEGV])(SIGSEGV, &si,
+					(*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si,
 							     regs);
 				}
 				else handle_segv(pid, regs);
@@ -426,14 +431,14 @@ void userspace(struct uml_pt_regs *regs)
 			        handle_trap(pid, regs, local_using_sysemu);
 				break;
 			case SIGTRAP:
-				relay_signal(SIGTRAP, &si, regs);
+				relay_signal(SIGTRAP, (struct siginfo *)&si, regs);
 				break;
 			case SIGVTALRM:
 				now = os_nsecs();
 				if (now < nsecs)
 					break;
 				block_signals();
-				(*sig_info[sig])(sig, &si, regs);
+				(*sig_info[sig])(sig, (struct siginfo *)&si, regs);
 				unblock_signals();
 				nsecs = timer.it_value.tv_sec *
 					UM_NSEC_PER_SEC +
@@ -447,7 +452,7 @@ void userspace(struct uml_pt_regs *regs)
 			case SIGFPE:
 			case SIGWINCH:
 				block_signals();
-				(*sig_info[sig])(sig, &si, regs);
+				(*sig_info[sig])(sig, (struct siginfo *)&si, regs);
 				unblock_signals();
 				break;
 			default:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/unicore32/boot/compressed/Makefile linux-libre-3.11-rc7-gnu/arch/unicore32/boot/compressed/Makefile
--- linux-libre-3.10-gnu/arch/unicore32/boot/compressed/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/unicore32/boot/compressed/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,7 @@ OBJS		:= misc.o
 
 # font.c and font.o
 CFLAGS_font.o	:= -Dstatic=
-$(obj)/font.c: $(srctree)/drivers/video/console/font_8x8.c
+$(obj)/font.c: $(srctree)/lib/fonts/font_8x8.c
 	$(call cmd,shipped)
 
 # piggy.S and piggy.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/unicore32/include/asm/memory.h linux-libre-3.11-rc7-gnu/arch/unicore32/include/asm/memory.h
--- linux-libre-3.10-gnu/arch/unicore32/include/asm/memory.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/unicore32/include/asm/memory.h	2013-08-25 20:43:22.000000000 -0400
@@ -98,12 +98,6 @@
 /*
  * Conversion between a struct page and a physical address.
  *
- * Note: when converting an unknown physical address to a
- * struct page, the resulting pointer must be validated
- * using VALID_PAGE().  It must return an invalid struct page
- * for any physical address not corresponding to a system
- * RAM address.
- *
  *  page_to_pfn(page)	convert a struct page * to a PFN number
  *  pfn_to_page(pfn)	convert a _valid_ PFN number to struct page *
  *
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/unicore32/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/unicore32/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/unicore32/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/unicore32/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -303,13 +303,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD
 
 #include <asm-generic/pgtable.h>
 
-/*
- * remap a physical page `pfn' of size `size' with page protection `prot'
- * into virtual address `from'
- */
-#define io_remap_pfn_range(vma, from, pfn, size, prot)	\
-		remap_pfn_range(vma, from, pfn, size, prot)
-
 #define pgtable_cache_init() do { } while (0)
 
 #endif /* !__ASSEMBLY__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/unicore32/kernel/pci.c linux-libre-3.11-rc7-gnu/arch/unicore32/kernel/pci.c
--- linux-libre-3.10-gnu/arch/unicore32/kernel/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/unicore32/kernel/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -277,11 +277,6 @@ static int __init pci_common_init(void)
 		pci_bus_assign_resources(puv3_bus);
 	}
 
-	/*
-	 * Tell drivers about devices found.
-	 */
-	pci_bus_add_devices(puv3_bus);
-
 	return 0;
 }
 subsys_initcall(pci_common_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/unicore32/kernel/process.c linux-libre-3.11-rc7-gnu/arch/unicore32/kernel/process.c
--- linux-libre-3.10-gnu/arch/unicore32/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/unicore32/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,16 +51,6 @@ void arch_cpu_idle(void)
 	local_irq_enable();
 }
 
-static char reboot_mode = 'h';
-
-int __init reboot_setup(char *str)
-{
-	reboot_mode = str[0];
-	return 1;
-}
-
-__setup("reboot=", reboot_setup);
-
 void machine_halt(void)
 {
 	gpio_set_value(GPO_SOFT_OFF, 0);
@@ -88,7 +78,7 @@ void machine_restart(char *cmd)
 	 * we may need it to insert some 1:1 mappings so that
 	 * soft boot works.
 	 */
-	setup_mm_for_reboot(reboot_mode);
+	setup_mm_for_reboot();
 
 	/* Clean and invalidate caches */
 	flush_cache_all();
@@ -102,7 +92,7 @@ void machine_restart(char *cmd)
 	/*
 	 * Now handle reboot code.
 	 */
-	if (reboot_mode == 's') {
+	if (reboot_mode == REBOOT_SOFT) {
 		/* Jump into ROM at address 0xffff0000 */
 		cpu_reset(VECTORS_BASE);
 	} else {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/unicore32/kernel/setup.h linux-libre-3.11-rc7-gnu/arch/unicore32/kernel/setup.h
--- linux-libre-3.10-gnu/arch/unicore32/kernel/setup.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/unicore32/kernel/setup.h	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,7 @@ extern void puv3_ps2_init(void);
 extern void pci_puv3_preinit(void);
 extern void __init puv3_init_gpio(void);
 
-extern void setup_mm_for_reboot(char mode);
+extern void setup_mm_for_reboot(void);
 
 extern char __stubs_start[], __stubs_end[];
 extern char __vectors_start[], __vectors_end[];
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/unicore32/mm/init.c linux-libre-3.11-rc7-gnu/arch/unicore32/mm/init.c
--- linux-libre-3.10-gnu/arch/unicore32/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/unicore32/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -383,59 +383,14 @@ static void __init free_unused_memmap(st
  */
 void __init mem_init(void)
 {
-	unsigned long reserved_pages, free_pages;
-	struct memblock_region *reg;
-	int i;
-
 	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 
 	free_unused_memmap(&meminfo);
 
 	/* this will put all unused low memory onto the freelists */
-	totalram_pages += free_all_bootmem();
-
-	reserved_pages = free_pages = 0;
-
-	for_each_bank(i, &meminfo) {
-		struct membank *bank = &meminfo.bank[i];
-		unsigned int pfn1, pfn2;
-		struct page *page, *end;
-
-		pfn1 = bank_pfn_start(bank);
-		pfn2 = bank_pfn_end(bank);
-
-		page = pfn_to_page(pfn1);
-		end  = pfn_to_page(pfn2 - 1) + 1;
-
-		do {
-			if (PageReserved(page))
-				reserved_pages++;
-			else if (!page_count(page))
-				free_pages++;
-			page++;
-		} while (page < end);
-	}
-
-	/*
-	 * Since our memory may not be contiguous, calculate the
-	 * real number of pages we have in this system
-	 */
-	printk(KERN_INFO "Memory:");
-	num_physpages = 0;
-	for_each_memblock(memory, reg) {
-		unsigned long pages = memblock_region_memory_end_pfn(reg) -
-			memblock_region_memory_base_pfn(reg);
-		num_physpages += pages;
-		printk(" %ldMB", pages >> (20 - PAGE_SHIFT));
-	}
-	printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
-
-	printk(KERN_NOTICE "Memory: %luk/%luk available, %luk reserved, %luK highmem\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		free_pages << (PAGE_SHIFT-10),
-		reserved_pages << (PAGE_SHIFT-10),
-		totalhigh_pages << (PAGE_SHIFT-10));
+	free_all_bootmem();
 
+	mem_init_print_info(NULL);
 	printk(KERN_NOTICE "Virtual kernel memory layout:\n"
 		"    vector  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
 		"    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
@@ -464,7 +419,7 @@ void __init mem_init(void)
 	BUILD_BUG_ON(TASK_SIZE				> MODULES_VADDR);
 	BUG_ON(TASK_SIZE				> MODULES_VADDR);
 
-	if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
+	if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
 		/*
 		 * On a machine this small we won't get
 		 * anywhere without overcommit, so turn
@@ -476,7 +431,7 @@ void __init mem_init(void)
 
 void free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -486,7 +441,7 @@ static int keep_initrd;
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
 	if (!keep_initrd)
-		free_reserved_area(start, end, 0, "initrd");
+		free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 
 static int __init keepinitrd_setup(char *__unused)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/unicore32/mm/mmu.c linux-libre-3.11-rc7-gnu/arch/unicore32/mm/mmu.c
--- linux-libre-3.10-gnu/arch/unicore32/mm/mmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/unicore32/mm/mmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -445,7 +445,7 @@ void __init paging_init(void)
  * the user-mode pages.  This will then ensure that we have predictable
  * results when turning the mmu off
  */
-void setup_mm_for_reboot(char mode)
+void setup_mm_for_reboot(void)
 {
 	unsigned long base_pmdval;
 	pgd_t *pgd;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/boot/compressed/eboot.c linux-libre-3.11-rc7-gnu/arch/x86/boot/compressed/eboot.c
--- linux-libre-3.10-gnu/arch/x86/boot/compressed/eboot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/boot/compressed/eboot.c	2013-08-25 20:43:22.000000000 -0400
@@ -225,7 +225,7 @@ static void low_free(unsigned long size,
 	unsigned long nr_pages;
 
 	nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
-	efi_call_phys2(sys_table->boottime->free_pages, addr, size);
+	efi_call_phys2(sys_table->boottime->free_pages, addr, nr_pages);
 }
 
 static void find_bits(unsigned long mask, u8 *pos, u8 *size)
@@ -992,18 +992,20 @@ static efi_status_t exit_boot(struct boo
 	efi_memory_desc_t *mem_map;
 	efi_status_t status;
 	__u32 desc_version;
+	bool called_exit = false;
 	u8 nr_entries;
 	int i;
 
 	size = sizeof(*mem_map) * 32;
 
 again:
-	size += sizeof(*mem_map);
+	size += sizeof(*mem_map) * 2;
 	_size = size;
 	status = low_alloc(size, 1, (unsigned long *)&mem_map);
 	if (status != EFI_SUCCESS)
 		return status;
 
+get_map:
 	status = efi_call_phys5(sys_table->boottime->get_memory_map, &size,
 				mem_map, &key, &desc_size, &desc_version);
 	if (status == EFI_BUFFER_TOO_SMALL) {
@@ -1029,8 +1031,20 @@ again:
 	/* Might as well exit boot services now */
 	status = efi_call_phys2(sys_table->boottime->exit_boot_services,
 				handle, key);
-	if (status != EFI_SUCCESS)
-		goto free_mem_map;
+	if (status != EFI_SUCCESS) {
+		/*
+		 * ExitBootServices() will fail if any of the event
+		 * handlers change the memory map. In which case, we
+		 * must be prepared to retry, but only once so that
+		 * we're guaranteed to exit on repeated failures instead
+		 * of spinning forever.
+		 */
+		if (called_exit)
+			goto free_mem_map;
+
+		called_exit = true;
+		goto get_map;
+	}
 
 	/* Historic? */
 	boot_params->alt_mem_k = 32 * 1024;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/boot/compressed/head_64.S linux-libre-3.11-rc7-gnu/arch/x86/boot/compressed/head_64.S
--- linux-libre-3.10-gnu/arch/x86/boot/compressed/head_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/boot/compressed/head_64.S	2013-08-25 20:43:22.000000000 -0400
@@ -27,8 +27,6 @@
 #include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/segment.h>
-#include <asm/pgtable_types.h>
-#include <asm/page_types.h>
 #include <asm/boot.h>
 #include <asm/msr.h>
 #include <asm/processor-flags.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/boot/compressed/Makefile linux-libre-3.11-rc7-gnu/arch/x86/boot/compressed/Makefile
--- linux-libre-3.10-gnu/arch/x86/boot/compressed/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/boot/compressed/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,8 @@
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo
+targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
+	vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
 
 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
@@ -63,12 +64,15 @@ $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all
 	$(call if_changed,xzkern)
 $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
 	$(call if_changed,lzo)
+$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) FORCE
+	$(call if_changed,lz4)
 
 suffix-$(CONFIG_KERNEL_GZIP)	:= gz
 suffix-$(CONFIG_KERNEL_BZIP2)	:= bz2
 suffix-$(CONFIG_KERNEL_LZMA)	:= lzma
 suffix-$(CONFIG_KERNEL_XZ)	:= xz
 suffix-$(CONFIG_KERNEL_LZO) 	:= lzo
+suffix-$(CONFIG_KERNEL_LZ4) 	:= lz4
 
 quiet_cmd_mkpiggy = MKPIGGY $@
       cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false )
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/boot/compressed/misc.c linux-libre-3.11-rc7-gnu/arch/x86/boot/compressed/misc.c
--- linux-libre-3.10-gnu/arch/x86/boot/compressed/misc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/boot/compressed/misc.c	2013-08-25 20:43:22.000000000 -0400
@@ -145,6 +145,10 @@ static int lines, cols;
 #include "../../../../lib/decompress_unlzo.c"
 #endif
 
+#ifdef CONFIG_KERNEL_LZ4
+#include "../../../../lib/decompress_unlz4.c"
+#endif
+
 static void scroll(void)
 {
 	int i;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/boot/tools/build.c linux-libre-3.11-rc7-gnu/arch/x86/boot/tools/build.c
--- linux-libre-3.10-gnu/arch/x86/boot/tools/build.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/boot/tools/build.c	2013-08-25 20:43:22.000000000 -0400
@@ -243,6 +243,7 @@ static void parse_zoffset(char *fname)
 	c = fread(buf, 1, sizeof(buf) - 1, file);
 	if (ferror(file))
 		die("read-error on `zoffset.h'");
+	fclose(file);
 	buf[c] = 0;
 
 	p = (char *)buf;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/configs/kvm_guest.config linux-libre-3.11-rc7-gnu/arch/x86/configs/kvm_guest.config
--- linux-libre-3.10-gnu/arch/x86/configs/kvm_guest.config	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/x86/configs/kvm_guest.config	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,28 @@
+CONFIG_NET=y
+CONFIG_NET_CORE=y
+CONFIG_NETDEVICES=y
+CONFIG_BLOCK=y
+CONFIG_BLK_DEV=y
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_INET=y
+CONFIG_TTY=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_BINFMT_ELF=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_HYPERVISOR_GUEST=y
+CONFIG_PARAVIRT=y
+CONFIG_KVM_GUEST=y
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BLK=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_NET=y
+CONFIG_9P_FS=y
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/blowfish-avx2-asm_64.S linux-libre-3.11-rc7-gnu/arch/x86/crypto/blowfish-avx2-asm_64.S
--- linux-libre-3.10-gnu/arch/x86/crypto/blowfish-avx2-asm_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/blowfish-avx2-asm_64.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,449 +0,0 @@
-/*
- * x86_64/AVX2 assembler optimized version of Blowfish
- *
- * Copyright © 2012-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/linkage.h>
-
-.file "blowfish-avx2-asm_64.S"
-
-.data
-.align 32
-
-.Lprefetch_mask:
-.long 0*64
-.long 1*64
-.long 2*64
-.long 3*64
-.long 4*64
-.long 5*64
-.long 6*64
-.long 7*64
-
-.Lbswap32_mask:
-.long 0x00010203
-.long 0x04050607
-.long 0x08090a0b
-.long 0x0c0d0e0f
-
-.Lbswap128_mask:
-	.byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
-.Lbswap_iv_mask:
-	.byte 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0
-
-.text
-/* structure of crypto context */
-#define p	0
-#define s0	((16 + 2) * 4)
-#define s1	((16 + 2 + (1 * 256)) * 4)
-#define s2	((16 + 2 + (2 * 256)) * 4)
-#define s3	((16 + 2 + (3 * 256)) * 4)
-
-/* register macros */
-#define CTX	%rdi
-#define RIO	 %rdx
-
-#define RS0	%rax
-#define RS1	%r8
-#define RS2	%r9
-#define RS3	%r10
-
-#define RLOOP	%r11
-#define RLOOPd	%r11d
-
-#define RXr0	%ymm8
-#define RXr1	%ymm9
-#define RXr2	%ymm10
-#define RXr3	%ymm11
-#define RXl0	%ymm12
-#define RXl1	%ymm13
-#define RXl2	%ymm14
-#define RXl3	%ymm15
-
-/* temp regs */
-#define RT0	%ymm0
-#define RT0x	%xmm0
-#define RT1	%ymm1
-#define RT1x	%xmm1
-#define RIDX0	%ymm2
-#define RIDX1	%ymm3
-#define RIDX1x	%xmm3
-#define RIDX2	%ymm4
-#define RIDX3	%ymm5
-
-/* vpgatherdd mask and '-1' */
-#define RNOT	%ymm6
-
-/* byte mask, (-1 >> 24) */
-#define RBYTE	%ymm7
-
-/***********************************************************************
- * 32-way AVX2 blowfish
- ***********************************************************************/
-#define F(xl, xr) \
-	vpsrld $24, xl, RIDX0; \
-	vpsrld $16, xl, RIDX1; \
-	vpsrld $8, xl, RIDX2; \
-	vpand RBYTE, RIDX1, RIDX1; \
-	vpand RBYTE, RIDX2, RIDX2; \
-	vpand RBYTE, xl, RIDX3; \
-	\
-	vpgatherdd RNOT, (RS0, RIDX0, 4), RT0; \
-	vpcmpeqd RNOT, RNOT, RNOT; \
-	vpcmpeqd RIDX0, RIDX0, RIDX0; \
-	\
-	vpgatherdd RNOT, (RS1, RIDX1, 4), RT1; \
-	vpcmpeqd RIDX1, RIDX1, RIDX1; \
-	vpaddd RT0, RT1, RT0; \
-	\
-	vpgatherdd RIDX0, (RS2, RIDX2, 4), RT1; \
-	vpxor RT0, RT1, RT0; \
-	\
-	vpgatherdd RIDX1, (RS3, RIDX3, 4), RT1; \
-	vpcmpeqd RNOT, RNOT, RNOT; \
-	vpaddd RT0, RT1, RT0; \
-	\
-	vpxor RT0, xr, xr;
-
-#define add_roundkey(xl, nmem) \
-	vpbroadcastd nmem, RT0; \
-	vpxor RT0, xl ## 0, xl ## 0; \
-	vpxor RT0, xl ## 1, xl ## 1; \
-	vpxor RT0, xl ## 2, xl ## 2; \
-	vpxor RT0, xl ## 3, xl ## 3;
-
-#define round_enc() \
-	add_roundkey(RXr, p(CTX,RLOOP,4)); \
-	F(RXl0, RXr0); \
-	F(RXl1, RXr1); \
-	F(RXl2, RXr2); \
-	F(RXl3, RXr3); \
-	\
-	add_roundkey(RXl, p+4(CTX,RLOOP,4)); \
-	F(RXr0, RXl0); \
-	F(RXr1, RXl1); \
-	F(RXr2, RXl2); \
-	F(RXr3, RXl3);
-
-#define round_dec() \
-	add_roundkey(RXr, p+4*2(CTX,RLOOP,4)); \
-	F(RXl0, RXr0); \
-	F(RXl1, RXr1); \
-	F(RXl2, RXr2); \
-	F(RXl3, RXr3); \
-	\
-	add_roundkey(RXl, p+4(CTX,RLOOP,4)); \
-	F(RXr0, RXl0); \
-	F(RXr1, RXl1); \
-	F(RXr2, RXl2); \
-	F(RXr3, RXl3);
-
-#define init_round_constants() \
-	vpcmpeqd RNOT, RNOT, RNOT; \
-	leaq s0(CTX), RS0; \
-	leaq s1(CTX), RS1; \
-	leaq s2(CTX), RS2; \
-	leaq s3(CTX), RS3; \
-	vpsrld $24, RNOT, RBYTE;
-
-#define transpose_2x2(x0, x1, t0) \
-	vpunpckldq x0, x1, t0; \
-	vpunpckhdq x0, x1, x1; \
-	\
-	vpunpcklqdq t0, x1, x0; \
-	vpunpckhqdq t0, x1, x1;
-
-#define read_block(xl, xr) \
-	vbroadcasti128 .Lbswap32_mask, RT1; \
-	\
-	vpshufb RT1, xl ## 0, xl ## 0; \
-	vpshufb RT1, xr ## 0, xr ## 0; \
-	vpshufb RT1, xl ## 1, xl ## 1; \
-	vpshufb RT1, xr ## 1, xr ## 1; \
-	vpshufb RT1, xl ## 2, xl ## 2; \
-	vpshufb RT1, xr ## 2, xr ## 2; \
-	vpshufb RT1, xl ## 3, xl ## 3; \
-	vpshufb RT1, xr ## 3, xr ## 3; \
-	\
-	transpose_2x2(xl ## 0, xr ## 0, RT0); \
-	transpose_2x2(xl ## 1, xr ## 1, RT0); \
-	transpose_2x2(xl ## 2, xr ## 2, RT0); \
-	transpose_2x2(xl ## 3, xr ## 3, RT0);
-
-#define write_block(xl, xr) \
-	vbroadcasti128 .Lbswap32_mask, RT1; \
-	\
-	transpose_2x2(xl ## 0, xr ## 0, RT0); \
-	transpose_2x2(xl ## 1, xr ## 1, RT0); \
-	transpose_2x2(xl ## 2, xr ## 2, RT0); \
-	transpose_2x2(xl ## 3, xr ## 3, RT0); \
-	\
-	vpshufb RT1, xl ## 0, xl ## 0; \
-	vpshufb RT1, xr ## 0, xr ## 0; \
-	vpshufb RT1, xl ## 1, xl ## 1; \
-	vpshufb RT1, xr ## 1, xr ## 1; \
-	vpshufb RT1, xl ## 2, xl ## 2; \
-	vpshufb RT1, xr ## 2, xr ## 2; \
-	vpshufb RT1, xl ## 3, xl ## 3; \
-	vpshufb RT1, xr ## 3, xr ## 3;
-
-.align 8
-__blowfish_enc_blk32:
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	RXl0..4, RXr0..4: plaintext
-	 * output:
-	 *	RXl0..4, RXr0..4: ciphertext (RXl <=> RXr swapped)
-	 */
-	init_round_constants();
-
-	read_block(RXl, RXr);
-
-	movl $1, RLOOPd;
-	add_roundkey(RXl, p+4*(0)(CTX));
-
-.align 4
-.L__enc_loop:
-	round_enc();
-
-	leal 2(RLOOPd), RLOOPd;
-	cmpl $17, RLOOPd;
-	jne .L__enc_loop;
-
-	add_roundkey(RXr, p+4*(17)(CTX));
-
-	write_block(RXl, RXr);
-
-	ret;
-ENDPROC(__blowfish_enc_blk32)
-
-.align 8
-__blowfish_dec_blk32:
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	RXl0..4, RXr0..4: ciphertext
-	 * output:
-	 *	RXl0..4, RXr0..4: plaintext (RXl <=> RXr swapped)
-	 */
-	init_round_constants();
-
-	read_block(RXl, RXr);
-
-	movl $14, RLOOPd;
-	add_roundkey(RXl, p+4*(17)(CTX));
-
-.align 4
-.L__dec_loop:
-	round_dec();
-
-	addl $-2, RLOOPd;
-	jns .L__dec_loop;
-
-	add_roundkey(RXr, p+4*(0)(CTX));
-
-	write_block(RXl, RXr);
-
-	ret;
-ENDPROC(__blowfish_dec_blk32)
-
-ENTRY(blowfish_ecb_enc_32way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst
-	 *	%rdx: src
-	 */
-
-	vzeroupper;
-
-	vmovdqu 0*32(%rdx), RXl0;
-	vmovdqu 1*32(%rdx), RXr0;
-	vmovdqu 2*32(%rdx), RXl1;
-	vmovdqu 3*32(%rdx), RXr1;
-	vmovdqu 4*32(%rdx), RXl2;
-	vmovdqu 5*32(%rdx), RXr2;
-	vmovdqu 6*32(%rdx), RXl3;
-	vmovdqu 7*32(%rdx), RXr3;
-
-	call __blowfish_enc_blk32;
-
-	vmovdqu RXr0, 0*32(%rsi);
-	vmovdqu RXl0, 1*32(%rsi);
-	vmovdqu RXr1, 2*32(%rsi);
-	vmovdqu RXl1, 3*32(%rsi);
-	vmovdqu RXr2, 4*32(%rsi);
-	vmovdqu RXl2, 5*32(%rsi);
-	vmovdqu RXr3, 6*32(%rsi);
-	vmovdqu RXl3, 7*32(%rsi);
-
-	vzeroupper;
-
-	ret;
-ENDPROC(blowfish_ecb_enc_32way)
-
-ENTRY(blowfish_ecb_dec_32way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst
-	 *	%rdx: src
-	 */
-
-	vzeroupper;
-
-	vmovdqu 0*32(%rdx), RXl0;
-	vmovdqu 1*32(%rdx), RXr0;
-	vmovdqu 2*32(%rdx), RXl1;
-	vmovdqu 3*32(%rdx), RXr1;
-	vmovdqu 4*32(%rdx), RXl2;
-	vmovdqu 5*32(%rdx), RXr2;
-	vmovdqu 6*32(%rdx), RXl3;
-	vmovdqu 7*32(%rdx), RXr3;
-
-	call __blowfish_dec_blk32;
-
-	vmovdqu RXr0, 0*32(%rsi);
-	vmovdqu RXl0, 1*32(%rsi);
-	vmovdqu RXr1, 2*32(%rsi);
-	vmovdqu RXl1, 3*32(%rsi);
-	vmovdqu RXr2, 4*32(%rsi);
-	vmovdqu RXl2, 5*32(%rsi);
-	vmovdqu RXr3, 6*32(%rsi);
-	vmovdqu RXl3, 7*32(%rsi);
-
-	vzeroupper;
-
-	ret;
-ENDPROC(blowfish_ecb_dec_32way)
-
-ENTRY(blowfish_cbc_dec_32way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst
-	 *	%rdx: src
-	 */
-
-	vzeroupper;
-
-	vmovdqu 0*32(%rdx), RXl0;
-	vmovdqu 1*32(%rdx), RXr0;
-	vmovdqu 2*32(%rdx), RXl1;
-	vmovdqu 3*32(%rdx), RXr1;
-	vmovdqu 4*32(%rdx), RXl2;
-	vmovdqu 5*32(%rdx), RXr2;
-	vmovdqu 6*32(%rdx), RXl3;
-	vmovdqu 7*32(%rdx), RXr3;
-
-	call __blowfish_dec_blk32;
-
-	/* xor with src */
-	vmovq (%rdx), RT0x;
-	vpshufd $0x4f, RT0x, RT0x;
-	vinserti128 $1, 8(%rdx), RT0, RT0;
-	vpxor RT0, RXr0, RXr0;
-	vpxor 0*32+24(%rdx), RXl0, RXl0;
-	vpxor 1*32+24(%rdx), RXr1, RXr1;
-	vpxor 2*32+24(%rdx), RXl1, RXl1;
-	vpxor 3*32+24(%rdx), RXr2, RXr2;
-	vpxor 4*32+24(%rdx), RXl2, RXl2;
-	vpxor 5*32+24(%rdx), RXr3, RXr3;
-	vpxor 6*32+24(%rdx), RXl3, RXl3;
-
-	vmovdqu RXr0, (0*32)(%rsi);
-	vmovdqu RXl0, (1*32)(%rsi);
-	vmovdqu RXr1, (2*32)(%rsi);
-	vmovdqu RXl1, (3*32)(%rsi);
-	vmovdqu RXr2, (4*32)(%rsi);
-	vmovdqu RXl2, (5*32)(%rsi);
-	vmovdqu RXr3, (6*32)(%rsi);
-	vmovdqu RXl3, (7*32)(%rsi);
-
-	vzeroupper;
-
-	ret;
-ENDPROC(blowfish_cbc_dec_32way)
-
-ENTRY(blowfish_ctr_32way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst
-	 *	%rdx: src
-	 *	%rcx: iv (big endian, 64bit)
-	 */
-
-	vzeroupper;
-
-	vpcmpeqd RT0, RT0, RT0;
-	vpsrldq $8, RT0, RT0; /* a: -1, b: 0, c: -1, d: 0 */
-
-	vpcmpeqd RT1x, RT1x, RT1x;
-	vpaddq RT1x, RT1x, RT1x; /* a: -2, b: -2 */
-	vpxor RIDX0, RIDX0, RIDX0;
-	vinserti128 $1, RT1x, RIDX0, RIDX0; /* a: 0, b: 0, c: -2, d: -2 */
-
-	vpaddq RIDX0, RT0, RT0; /* a: -1, b: 0, c: -3, d: -2 */
-
-	vpcmpeqd RT1, RT1, RT1;
-	vpaddq RT1, RT1, RT1; /* a: -2, b: -2, c: -2, d: -2 */
-	vpaddq RT1, RT1, RIDX2; /* a: -4, b: -4, c: -4, d: -4 */
-
-	vbroadcasti128 .Lbswap_iv_mask, RIDX0;
-	vbroadcasti128 .Lbswap128_mask, RIDX1;
-
-	/* load IV and byteswap */
-	vmovq (%rcx), RT1x;
-	vinserti128 $1, RT1x, RT1, RT1; /* a: BE, b: 0, c: BE, d: 0 */
-	vpshufb RIDX0, RT1, RT1; /* a: LE, b: LE, c: LE, d: LE */
-
-	/* construct IVs */
-	vpsubq RT0, RT1, RT1;		/* a: le1, b: le0, c: le3, d: le2 */
-	vpshufb RIDX1, RT1, RXl0;	/* a: be0, b: be1, c: be2, d: be3 */
-	vpsubq RIDX2, RT1, RT1;		/* le5, le4, le7, le6 */
-	vpshufb RIDX1, RT1, RXr0;	/* be4, be5, be6, be7 */
-	vpsubq RIDX2, RT1, RT1;
-	vpshufb RIDX1, RT1, RXl1;
-	vpsubq RIDX2, RT1, RT1;
-	vpshufb RIDX1, RT1, RXr1;
-	vpsubq RIDX2, RT1, RT1;
-	vpshufb RIDX1, RT1, RXl2;
-	vpsubq RIDX2, RT1, RT1;
-	vpshufb RIDX1, RT1, RXr2;
-	vpsubq RIDX2, RT1, RT1;
-	vpshufb RIDX1, RT1, RXl3;
-	vpsubq RIDX2, RT1, RT1;
-	vpshufb RIDX1, RT1, RXr3;
-
-	/* store last IV */
-	vpsubq RIDX2, RT1, RT1; /* a: le33, b: le32, ... */
-	vpshufb RIDX1x, RT1x, RT1x; /* a: be32, ... */
-	vmovq RT1x, (%rcx);
-
-	call __blowfish_enc_blk32;
-
-	/* dst = src ^ iv */
-	vpxor 0*32(%rdx), RXr0, RXr0;
-	vpxor 1*32(%rdx), RXl0, RXl0;
-	vpxor 2*32(%rdx), RXr1, RXr1;
-	vpxor 3*32(%rdx), RXl1, RXl1;
-	vpxor 4*32(%rdx), RXr2, RXr2;
-	vpxor 5*32(%rdx), RXl2, RXl2;
-	vpxor 6*32(%rdx), RXr3, RXr3;
-	vpxor 7*32(%rdx), RXl3, RXl3;
-	vmovdqu RXr0, (0*32)(%rsi);
-	vmovdqu RXl0, (1*32)(%rsi);
-	vmovdqu RXr1, (2*32)(%rsi);
-	vmovdqu RXl1, (3*32)(%rsi);
-	vmovdqu RXr2, (4*32)(%rsi);
-	vmovdqu RXl2, (5*32)(%rsi);
-	vmovdqu RXr3, (6*32)(%rsi);
-	vmovdqu RXl3, (7*32)(%rsi);
-
-	vzeroupper;
-
-	ret;
-ENDPROC(blowfish_ctr_32way)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/blowfish_avx2_glue.c linux-libre-3.11-rc7-gnu/arch/x86/crypto/blowfish_avx2_glue.c
--- linux-libre-3.10-gnu/arch/x86/crypto/blowfish_avx2_glue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/blowfish_avx2_glue.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,585 +0,0 @@
-/*
- * Glue Code for x86_64/AVX2 assembler optimized version of Blowfish
- *
- * Copyright © 2012-2013 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
- *
- * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
- *   Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
- * CTR part based on code (crypto/ctr.c) by:
- *   (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/crypto.h>
-#include <linux/err.h>
-#include <crypto/algapi.h>
-#include <crypto/blowfish.h>
-#include <crypto/cryptd.h>
-#include <crypto/ctr.h>
-#include <asm/i387.h>
-#include <asm/xcr.h>
-#include <asm/xsave.h>
-#include <asm/crypto/blowfish.h>
-#include <asm/crypto/ablk_helper.h>
-#include <crypto/scatterwalk.h>
-
-#define BF_AVX2_PARALLEL_BLOCKS 32
-
-/* 32-way AVX2 parallel cipher functions */
-asmlinkage void blowfish_ecb_enc_32way(struct bf_ctx *ctx, u8 *dst,
-				       const u8 *src);
-asmlinkage void blowfish_ecb_dec_32way(struct bf_ctx *ctx, u8 *dst,
-				       const u8 *src);
-asmlinkage void blowfish_cbc_dec_32way(struct bf_ctx *ctx, u8 *dst,
-				       const u8 *src);
-asmlinkage void blowfish_ctr_32way(struct bf_ctx *ctx, u8 *dst, const u8 *src,
-				   __be64 *iv);
-
-static inline bool bf_fpu_begin(bool fpu_enabled, unsigned int nbytes)
-{
-	if (fpu_enabled)
-		return true;
-
-	/* FPU is only used when chunk to be processed is large enough, so
-	 * do not enable FPU until it is necessary.
-	 */
-	if (nbytes < BF_BLOCK_SIZE * BF_AVX2_PARALLEL_BLOCKS)
-		return false;
-
-	kernel_fpu_begin();
-	return true;
-}
-
-static inline void bf_fpu_end(bool fpu_enabled)
-{
-	if (fpu_enabled)
-		kernel_fpu_end();
-}
-
-static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk,
-		     bool enc)
-{
-	bool fpu_enabled = false;
-	struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-	const unsigned int bsize = BF_BLOCK_SIZE;
-	unsigned int nbytes;
-	int err;
-
-	err = blkcipher_walk_virt(desc, walk);
-	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
-
-	while ((nbytes = walk->nbytes)) {
-		u8 *wsrc = walk->src.virt.addr;
-		u8 *wdst = walk->dst.virt.addr;
-
-		fpu_enabled = bf_fpu_begin(fpu_enabled, nbytes);
-
-		/* Process multi-block AVX2 batch */
-		if (nbytes >= bsize * BF_AVX2_PARALLEL_BLOCKS) {
-			do {
-				if (enc)
-					blowfish_ecb_enc_32way(ctx, wdst, wsrc);
-				else
-					blowfish_ecb_dec_32way(ctx, wdst, wsrc);
-
-				wsrc += bsize * BF_AVX2_PARALLEL_BLOCKS;
-				wdst += bsize * BF_AVX2_PARALLEL_BLOCKS;
-				nbytes -= bsize * BF_AVX2_PARALLEL_BLOCKS;
-			} while (nbytes >= bsize * BF_AVX2_PARALLEL_BLOCKS);
-
-			if (nbytes < bsize)
-				goto done;
-		}
-
-		/* Process multi-block batch */
-		if (nbytes >= bsize * BF_PARALLEL_BLOCKS) {
-			do {
-				if (enc)
-					blowfish_enc_blk_4way(ctx, wdst, wsrc);
-				else
-					blowfish_dec_blk_4way(ctx, wdst, wsrc);
-
-				wsrc += bsize * BF_PARALLEL_BLOCKS;
-				wdst += bsize * BF_PARALLEL_BLOCKS;
-				nbytes -= bsize * BF_PARALLEL_BLOCKS;
-			} while (nbytes >= bsize * BF_PARALLEL_BLOCKS);
-
-			if (nbytes < bsize)
-				goto done;
-		}
-
-		/* Handle leftovers */
-		do {
-			if (enc)
-				blowfish_enc_blk(ctx, wdst, wsrc);
-			else
-				blowfish_dec_blk(ctx, wdst, wsrc);
-
-			wsrc += bsize;
-			wdst += bsize;
-			nbytes -= bsize;
-		} while (nbytes >= bsize);
-
-done:
-		err = blkcipher_walk_done(desc, walk, nbytes);
-	}
-
-	bf_fpu_end(fpu_enabled);
-	return err;
-}
-
-static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	struct blkcipher_walk walk;
-
-	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return ecb_crypt(desc, &walk, true);
-}
-
-static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	struct blkcipher_walk walk;
-
-	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return ecb_crypt(desc, &walk, false);
-}
-
-static unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
-				  struct blkcipher_walk *walk)
-{
-	struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-	unsigned int bsize = BF_BLOCK_SIZE;
-	unsigned int nbytes = walk->nbytes;
-	u64 *src = (u64 *)walk->src.virt.addr;
-	u64 *dst = (u64 *)walk->dst.virt.addr;
-	u64 *iv = (u64 *)walk->iv;
-
-	do {
-		*dst = *src ^ *iv;
-		blowfish_enc_blk(ctx, (u8 *)dst, (u8 *)dst);
-		iv = dst;
-
-		src += 1;
-		dst += 1;
-		nbytes -= bsize;
-	} while (nbytes >= bsize);
-
-	*(u64 *)walk->iv = *iv;
-	return nbytes;
-}
-
-static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	struct blkcipher_walk walk;
-	int err;
-
-	blkcipher_walk_init(&walk, dst, src, nbytes);
-	err = blkcipher_walk_virt(desc, &walk);
-
-	while ((nbytes = walk.nbytes)) {
-		nbytes = __cbc_encrypt(desc, &walk);
-		err = blkcipher_walk_done(desc, &walk, nbytes);
-	}
-
-	return err;
-}
-
-static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
-				  struct blkcipher_walk *walk)
-{
-	struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-	const unsigned int bsize = BF_BLOCK_SIZE;
-	unsigned int nbytes = walk->nbytes;
-	u64 *src = (u64 *)walk->src.virt.addr;
-	u64 *dst = (u64 *)walk->dst.virt.addr;
-	u64 last_iv;
-	int i;
-
-	/* Start of the last block. */
-	src += nbytes / bsize - 1;
-	dst += nbytes / bsize - 1;
-
-	last_iv = *src;
-
-	/* Process multi-block AVX2 batch */
-	if (nbytes >= bsize * BF_AVX2_PARALLEL_BLOCKS) {
-		do {
-			nbytes -= bsize * (BF_AVX2_PARALLEL_BLOCKS - 1);
-			src -= BF_AVX2_PARALLEL_BLOCKS - 1;
-			dst -= BF_AVX2_PARALLEL_BLOCKS - 1;
-
-			blowfish_cbc_dec_32way(ctx, (u8 *)dst, (u8 *)src);
-
-			nbytes -= bsize;
-			if (nbytes < bsize)
-				goto done;
-
-			*dst ^= *(src - 1);
-			src -= 1;
-			dst -= 1;
-		} while (nbytes >= bsize * BF_AVX2_PARALLEL_BLOCKS);
-
-		if (nbytes < bsize)
-			goto done;
-	}
-
-	/* Process multi-block batch */
-	if (nbytes >= bsize * BF_PARALLEL_BLOCKS) {
-		u64 ivs[BF_PARALLEL_BLOCKS - 1];
-
-		do {
-			nbytes -= bsize * (BF_PARALLEL_BLOCKS - 1);
-			src -= BF_PARALLEL_BLOCKS - 1;
-			dst -= BF_PARALLEL_BLOCKS - 1;
-
-			for (i = 0; i < BF_PARALLEL_BLOCKS - 1; i++)
-				ivs[i] = src[i];
-
-			blowfish_dec_blk_4way(ctx, (u8 *)dst, (u8 *)src);
-
-			for (i = 0; i < BF_PARALLEL_BLOCKS - 1; i++)
-				dst[i + 1] ^= ivs[i];
-
-			nbytes -= bsize;
-			if (nbytes < bsize)
-				goto done;
-
-			*dst ^= *(src - 1);
-			src -= 1;
-			dst -= 1;
-		} while (nbytes >= bsize * BF_PARALLEL_BLOCKS);
-
-		if (nbytes < bsize)
-			goto done;
-	}
-
-	/* Handle leftovers */
-	for (;;) {
-		blowfish_dec_blk(ctx, (u8 *)dst, (u8 *)src);
-
-		nbytes -= bsize;
-		if (nbytes < bsize)
-			break;
-
-		*dst ^= *(src - 1);
-		src -= 1;
-		dst -= 1;
-	}
-
-done:
-	*dst ^= *(u64 *)walk->iv;
-	*(u64 *)walk->iv = last_iv;
-
-	return nbytes;
-}
-
-static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	bool fpu_enabled = false;
-	struct blkcipher_walk walk;
-	int err;
-
-	blkcipher_walk_init(&walk, dst, src, nbytes);
-	err = blkcipher_walk_virt(desc, &walk);
-	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
-
-	while ((nbytes = walk.nbytes)) {
-		fpu_enabled = bf_fpu_begin(fpu_enabled, nbytes);
-		nbytes = __cbc_decrypt(desc, &walk);
-		err = blkcipher_walk_done(desc, &walk, nbytes);
-	}
-
-	bf_fpu_end(fpu_enabled);
-	return err;
-}
-
-static void ctr_crypt_final(struct blkcipher_desc *desc,
-			    struct blkcipher_walk *walk)
-{
-	struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-	u8 *ctrblk = walk->iv;
-	u8 keystream[BF_BLOCK_SIZE];
-	u8 *src = walk->src.virt.addr;
-	u8 *dst = walk->dst.virt.addr;
-	unsigned int nbytes = walk->nbytes;
-
-	blowfish_enc_blk(ctx, keystream, ctrblk);
-	crypto_xor(keystream, src, nbytes);
-	memcpy(dst, keystream, nbytes);
-
-	crypto_inc(ctrblk, BF_BLOCK_SIZE);
-}
-
-static unsigned int __ctr_crypt(struct blkcipher_desc *desc,
-				struct blkcipher_walk *walk)
-{
-	struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-	unsigned int bsize = BF_BLOCK_SIZE;
-	unsigned int nbytes = walk->nbytes;
-	u64 *src = (u64 *)walk->src.virt.addr;
-	u64 *dst = (u64 *)walk->dst.virt.addr;
-	int i;
-
-	/* Process multi-block AVX2 batch */
-	if (nbytes >= bsize * BF_AVX2_PARALLEL_BLOCKS) {
-		do {
-			blowfish_ctr_32way(ctx, (u8 *)dst, (u8 *)src,
-					   (__be64 *)walk->iv);
-
-			src += BF_AVX2_PARALLEL_BLOCKS;
-			dst += BF_AVX2_PARALLEL_BLOCKS;
-			nbytes -= bsize * BF_AVX2_PARALLEL_BLOCKS;
-		} while (nbytes >= bsize * BF_AVX2_PARALLEL_BLOCKS);
-
-		if (nbytes < bsize)
-			goto done;
-	}
-
-	/* Process four block batch */
-	if (nbytes >= bsize * BF_PARALLEL_BLOCKS) {
-		__be64 ctrblocks[BF_PARALLEL_BLOCKS];
-		u64 ctrblk = be64_to_cpu(*(__be64 *)walk->iv);
-
-		do {
-			/* create ctrblks for parallel encrypt */
-			for (i = 0; i < BF_PARALLEL_BLOCKS; i++) {
-				if (dst != src)
-					dst[i] = src[i];
-
-				ctrblocks[i] = cpu_to_be64(ctrblk++);
-			}
-
-			blowfish_enc_blk_xor_4way(ctx, (u8 *)dst,
-						  (u8 *)ctrblocks);
-
-			src += BF_PARALLEL_BLOCKS;
-			dst += BF_PARALLEL_BLOCKS;
-			nbytes -= bsize * BF_PARALLEL_BLOCKS;
-		} while (nbytes >= bsize * BF_PARALLEL_BLOCKS);
-
-		*(__be64 *)walk->iv = cpu_to_be64(ctrblk);
-
-		if (nbytes < bsize)
-			goto done;
-	}
-
-	/* Handle leftovers */
-	do {
-		u64 ctrblk;
-
-		if (dst != src)
-			*dst = *src;
-
-		ctrblk = *(u64 *)walk->iv;
-		be64_add_cpu((__be64 *)walk->iv, 1);
-
-		blowfish_enc_blk_xor(ctx, (u8 *)dst, (u8 *)&ctrblk);
-
-		src += 1;
-		dst += 1;
-	} while ((nbytes -= bsize) >= bsize);
-
-done:
-	return nbytes;
-}
-
-static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		     struct scatterlist *src, unsigned int nbytes)
-{
-	bool fpu_enabled = false;
-	struct blkcipher_walk walk;
-	int err;
-
-	blkcipher_walk_init(&walk, dst, src, nbytes);
-	err = blkcipher_walk_virt_block(desc, &walk, BF_BLOCK_SIZE);
-	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
-
-	while ((nbytes = walk.nbytes) >= BF_BLOCK_SIZE) {
-		fpu_enabled = bf_fpu_begin(fpu_enabled, nbytes);
-		nbytes = __ctr_crypt(desc, &walk);
-		err = blkcipher_walk_done(desc, &walk, nbytes);
-	}
-
-	bf_fpu_end(fpu_enabled);
-
-	if (walk.nbytes) {
-		ctr_crypt_final(desc, &walk);
-		err = blkcipher_walk_done(desc, &walk, 0);
-	}
-
-	return err;
-}
-
-static struct crypto_alg bf_algs[6] = { {
-	.cra_name		= "__ecb-blowfish-avx2",
-	.cra_driver_name	= "__driver-ecb-blowfish-avx2",
-	.cra_priority		= 0,
-	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
-	.cra_blocksize		= BF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct bf_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_blkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_u = {
-		.blkcipher = {
-			.min_keysize	= BF_MIN_KEY_SIZE,
-			.max_keysize	= BF_MAX_KEY_SIZE,
-			.setkey		= blowfish_setkey,
-			.encrypt	= ecb_encrypt,
-			.decrypt	= ecb_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "__cbc-blowfish-avx2",
-	.cra_driver_name	= "__driver-cbc-blowfish-avx2",
-	.cra_priority		= 0,
-	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
-	.cra_blocksize		= BF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct bf_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_blkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_u = {
-		.blkcipher = {
-			.min_keysize	= BF_MIN_KEY_SIZE,
-			.max_keysize	= BF_MAX_KEY_SIZE,
-			.setkey		= blowfish_setkey,
-			.encrypt	= cbc_encrypt,
-			.decrypt	= cbc_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "__ctr-blowfish-avx2",
-	.cra_driver_name	= "__driver-ctr-blowfish-avx2",
-	.cra_priority		= 0,
-	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
-	.cra_blocksize		= 1,
-	.cra_ctxsize		= sizeof(struct bf_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_blkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_u = {
-		.blkcipher = {
-			.min_keysize	= BF_MIN_KEY_SIZE,
-			.max_keysize	= BF_MAX_KEY_SIZE,
-			.ivsize		= BF_BLOCK_SIZE,
-			.setkey		= blowfish_setkey,
-			.encrypt	= ctr_crypt,
-			.decrypt	= ctr_crypt,
-		},
-	},
-}, {
-	.cra_name		= "ecb(blowfish)",
-	.cra_driver_name	= "ecb-blowfish-avx2",
-	.cra_priority		= 400,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
-	.cra_blocksize		= BF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct async_helper_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_ablkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_init		= ablk_init,
-	.cra_exit		= ablk_exit,
-	.cra_u = {
-		.ablkcipher = {
-			.min_keysize	= BF_MIN_KEY_SIZE,
-			.max_keysize	= BF_MAX_KEY_SIZE,
-			.setkey		= ablk_set_key,
-			.encrypt	= ablk_encrypt,
-			.decrypt	= ablk_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "cbc(blowfish)",
-	.cra_driver_name	= "cbc-blowfish-avx2",
-	.cra_priority		= 400,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
-	.cra_blocksize		= BF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct async_helper_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_ablkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_init		= ablk_init,
-	.cra_exit		= ablk_exit,
-	.cra_u = {
-		.ablkcipher = {
-			.min_keysize	= BF_MIN_KEY_SIZE,
-			.max_keysize	= BF_MAX_KEY_SIZE,
-			.ivsize		= BF_BLOCK_SIZE,
-			.setkey		= ablk_set_key,
-			.encrypt	= __ablk_encrypt,
-			.decrypt	= ablk_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "ctr(blowfish)",
-	.cra_driver_name	= "ctr-blowfish-avx2",
-	.cra_priority		= 400,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
-	.cra_blocksize		= 1,
-	.cra_ctxsize		= sizeof(struct async_helper_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_ablkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_init		= ablk_init,
-	.cra_exit		= ablk_exit,
-	.cra_u = {
-		.ablkcipher = {
-			.min_keysize	= BF_MIN_KEY_SIZE,
-			.max_keysize	= BF_MAX_KEY_SIZE,
-			.ivsize		= BF_BLOCK_SIZE,
-			.setkey		= ablk_set_key,
-			.encrypt	= ablk_encrypt,
-			.decrypt	= ablk_encrypt,
-			.geniv		= "chainiv",
-		},
-	},
-} };
-
-
-static int __init init(void)
-{
-	u64 xcr0;
-
-	if (!cpu_has_avx2 || !cpu_has_osxsave) {
-		pr_info("AVX2 instructions are not detected.\n");
-		return -ENODEV;
-	}
-
-	xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
-	if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) {
-		pr_info("AVX detected but unusable.\n");
-		return -ENODEV;
-	}
-
-	return crypto_register_algs(bf_algs, ARRAY_SIZE(bf_algs));
-}
-
-static void __exit fini(void)
-{
-	crypto_unregister_algs(bf_algs, ARRAY_SIZE(bf_algs));
-}
-
-module_init(init);
-module_exit(fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Blowfish Cipher Algorithm, AVX2 optimized");
-MODULE_ALIAS("blowfish");
-MODULE_ALIAS("blowfish-asm");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/blowfish_glue.c linux-libre-3.11-rc7-gnu/arch/x86/crypto/blowfish_glue.c
--- linux-libre-3.10-gnu/arch/x86/crypto/blowfish_glue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/blowfish_glue.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Glue Code for assembler optimized version of Blowfish
  *
- * Copyright © 2011-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
  *
  * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
  *   Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
@@ -32,24 +32,40 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <crypto/algapi.h>
-#include <asm/crypto/blowfish.h>
 
 /* regular block cipher functions */
 asmlinkage void __blowfish_enc_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src,
 				   bool xor);
-EXPORT_SYMBOL_GPL(__blowfish_enc_blk);
-
 asmlinkage void blowfish_dec_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src);
-EXPORT_SYMBOL_GPL(blowfish_dec_blk);
 
 /* 4-way parallel cipher functions */
 asmlinkage void __blowfish_enc_blk_4way(struct bf_ctx *ctx, u8 *dst,
 					const u8 *src, bool xor);
-EXPORT_SYMBOL_GPL(__blowfish_enc_blk_4way);
-
 asmlinkage void blowfish_dec_blk_4way(struct bf_ctx *ctx, u8 *dst,
 				      const u8 *src);
-EXPORT_SYMBOL_GPL(blowfish_dec_blk_4way);
+
+static inline void blowfish_enc_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src)
+{
+	__blowfish_enc_blk(ctx, dst, src, false);
+}
+
+static inline void blowfish_enc_blk_xor(struct bf_ctx *ctx, u8 *dst,
+					const u8 *src)
+{
+	__blowfish_enc_blk(ctx, dst, src, true);
+}
+
+static inline void blowfish_enc_blk_4way(struct bf_ctx *ctx, u8 *dst,
+					 const u8 *src)
+{
+	__blowfish_enc_blk_4way(ctx, dst, src, false);
+}
+
+static inline void blowfish_enc_blk_xor_4way(struct bf_ctx *ctx, u8 *dst,
+				      const u8 *src)
+{
+	__blowfish_enc_blk_4way(ctx, dst, src, true);
+}
 
 static void blowfish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/camellia-aesni-avx2-asm_64.S linux-libre-3.11-rc7-gnu/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
--- linux-libre-3.10-gnu/arch/x86/crypto/camellia-aesni-avx2-asm_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/camellia-aesni-avx2-asm_64.S	2013-08-25 20:43:22.000000000 -0400
@@ -51,16 +51,6 @@
 #define ymm14_x xmm14
 #define ymm15_x xmm15
 
-/*
- * AES-NI instructions do not support ymmX registers, so we need splitting and
- * merging.
- */
-#define vaesenclast256(zero, yreg, tmp) \
-	vextracti128 $1, yreg, tmp##_x; \
-	vaesenclast zero##_x, yreg##_x, yreg##_x; \
-	vaesenclast zero##_x, tmp##_x, tmp##_x; \
-	vinserti128 $1, tmp##_x, yreg, yreg;
-
 /**********************************************************************
   32-way camellia
  **********************************************************************/
@@ -79,46 +69,70 @@
 	 * S-function with AES subbytes \
 	 */ \
 	vbroadcasti128 .Linv_shift_row, t4; \
-	vpbroadcastb .L0f0f0f0f, t7; \
-	vbroadcasti128 .Lpre_tf_lo_s1, t0; \
-	vbroadcasti128 .Lpre_tf_hi_s1, t1; \
+	vpbroadcastd .L0f0f0f0f, t7; \
+	vbroadcasti128 .Lpre_tf_lo_s1, t5; \
+	vbroadcasti128 .Lpre_tf_hi_s1, t6; \
+	vbroadcasti128 .Lpre_tf_lo_s4, t2; \
+	vbroadcasti128 .Lpre_tf_hi_s4, t3; \
 	\
 	/* AES inverse shift rows */ \
 	vpshufb t4, x0, x0; \
 	vpshufb t4, x7, x7; \
-	vpshufb t4, x1, x1; \
-	vpshufb t4, x4, x4; \
-	vpshufb t4, x2, x2; \
-	vpshufb t4, x5, x5; \
 	vpshufb t4, x3, x3; \
 	vpshufb t4, x6, x6; \
+	vpshufb t4, x2, x2; \
+	vpshufb t4, x5, x5; \
+	vpshufb t4, x1, x1; \
+	vpshufb t4, x4, x4; \
 	\
 	/* prefilter sboxes 1, 2 and 3 */ \
-	vbroadcasti128 .Lpre_tf_lo_s4, t2; \
-	vbroadcasti128 .Lpre_tf_hi_s4, t3; \
-	filter_8bit(x0, t0, t1, t7, t6); \
-	filter_8bit(x7, t0, t1, t7, t6); \
-	filter_8bit(x1, t0, t1, t7, t6); \
-	filter_8bit(x4, t0, t1, t7, t6); \
-	filter_8bit(x2, t0, t1, t7, t6); \
-	filter_8bit(x5, t0, t1, t7, t6); \
-	\
 	/* prefilter sbox 4 */ \
+	filter_8bit(x0, t5, t6, t7, t4); \
+	filter_8bit(x7, t5, t6, t7, t4); \
+	vextracti128 $1, x0, t0##_x; \
+	vextracti128 $1, x7, t1##_x; \
+	filter_8bit(x3, t2, t3, t7, t4); \
+	filter_8bit(x6, t2, t3, t7, t4); \
+	vextracti128 $1, x3, t3##_x; \
+	vextracti128 $1, x6, t2##_x; \
+	filter_8bit(x2, t5, t6, t7, t4); \
+	filter_8bit(x5, t5, t6, t7, t4); \
+	filter_8bit(x1, t5, t6, t7, t4); \
+	filter_8bit(x4, t5, t6, t7, t4); \
+	\
 	vpxor t4##_x, t4##_x, t4##_x; \
-	filter_8bit(x3, t2, t3, t7, t6); \
-	filter_8bit(x6, t2, t3, t7, t6); \
 	\
 	/* AES subbytes + AES shift rows */ \
+	vextracti128 $1, x2, t6##_x; \
+	vextracti128 $1, x5, t5##_x; \
+	vaesenclast t4##_x, x0##_x, x0##_x; \
+	vaesenclast t4##_x, t0##_x, t0##_x; \
+	vinserti128 $1, t0##_x, x0, x0; \
+	vaesenclast t4##_x, x7##_x, x7##_x; \
+	vaesenclast t4##_x, t1##_x, t1##_x; \
+	vinserti128 $1, t1##_x, x7, x7; \
+	vaesenclast t4##_x, x3##_x, x3##_x; \
+	vaesenclast t4##_x, t3##_x, t3##_x; \
+	vinserti128 $1, t3##_x, x3, x3; \
+	vaesenclast t4##_x, x6##_x, x6##_x; \
+	vaesenclast t4##_x, t2##_x, t2##_x; \
+	vinserti128 $1, t2##_x, x6, x6; \
+	vextracti128 $1, x1, t3##_x; \
+	vextracti128 $1, x4, t2##_x; \
 	vbroadcasti128 .Lpost_tf_lo_s1, t0; \
 	vbroadcasti128 .Lpost_tf_hi_s1, t1; \
-	vaesenclast256(t4, x0, t5); \
-	vaesenclast256(t4, x7, t5); \
-	vaesenclast256(t4, x1, t5); \
-	vaesenclast256(t4, x4, t5); \
-	vaesenclast256(t4, x2, t5); \
-	vaesenclast256(t4, x5, t5); \
-	vaesenclast256(t4, x3, t5); \
-	vaesenclast256(t4, x6, t5); \
+	vaesenclast t4##_x, x2##_x, x2##_x; \
+	vaesenclast t4##_x, t6##_x, t6##_x; \
+	vinserti128 $1, t6##_x, x2, x2; \
+	vaesenclast t4##_x, x5##_x, x5##_x; \
+	vaesenclast t4##_x, t5##_x, t5##_x; \
+	vinserti128 $1, t5##_x, x5, x5; \
+	vaesenclast t4##_x, x1##_x, x1##_x; \
+	vaesenclast t4##_x, t3##_x, t3##_x; \
+	vinserti128 $1, t3##_x, x1, x1; \
+	vaesenclast t4##_x, x4##_x, x4##_x; \
+	vaesenclast t4##_x, t2##_x, t2##_x; \
+	vinserti128 $1, t2##_x, x4, x4; \
 	\
 	/* postfilter sboxes 1 and 4 */ \
 	vbroadcasti128 .Lpost_tf_lo_s3, t2; \
@@ -139,22 +153,12 @@
 	/* postfilter sbox 2 */ \
 	filter_8bit(x1, t4, t5, t7, t2); \
 	filter_8bit(x4, t4, t5, t7, t2); \
+	vpxor t7, t7, t7; \
 	\
 	vpsrldq $1, t0, t1; \
 	vpsrldq $2, t0, t2; \
+	vpshufb t7, t1, t1; \
 	vpsrldq $3, t0, t3; \
-	vpsrldq $4, t0, t4; \
-	vpsrldq $5, t0, t5; \
-	vpsrldq $6, t0, t6; \
-	vpsrldq $7, t0, t7; \
-	vpbroadcastb t0##_x, t0; \
-	vpbroadcastb t1##_x, t1; \
-	vpbroadcastb t2##_x, t2; \
-	vpbroadcastb t3##_x, t3; \
-	vpbroadcastb t4##_x, t4; \
-	vpbroadcastb t6##_x, t6; \
-	vpbroadcastb t5##_x, t5; \
-	vpbroadcastb t7##_x, t7; \
 	\
 	/* P-function */ \
 	vpxor x5, x0, x0; \
@@ -162,11 +166,21 @@
 	vpxor x7, x2, x2; \
 	vpxor x4, x3, x3; \
 	\
+	vpshufb t7, t2, t2; \
+	vpsrldq $4, t0, t4; \
+	vpshufb t7, t3, t3; \
+	vpsrldq $5, t0, t5; \
+	vpshufb t7, t4, t4; \
+	\
 	vpxor x2, x4, x4; \
 	vpxor x3, x5, x5; \
 	vpxor x0, x6, x6; \
 	vpxor x1, x7, x7; \
 	\
+	vpsrldq $6, t0, t6; \
+	vpshufb t7, t5, t5; \
+	vpshufb t7, t6, t6; \
+	\
 	vpxor x7, x0, x0; \
 	vpxor x4, x1, x1; \
 	vpxor x5, x2, x2; \
@@ -179,12 +193,16 @@
 	\
 	/* Add key material and result to CD (x becomes new CD) */ \
 	\
-	vpxor t7, x0, x0; \
-	vpxor 4 * 32(mem_cd), x0, x0; \
-	\
 	vpxor t6, x1, x1; \
 	vpxor 5 * 32(mem_cd), x1, x1; \
 	\
+	vpsrldq $7, t0, t6; \
+	vpshufb t7, t0, t0; \
+	vpshufb t7, t6, t7; \
+	\
+	vpxor t7, x0, x0; \
+	vpxor 4 * 32(mem_cd), x0, x0; \
+	\
 	vpxor t5, x2, x2; \
 	vpxor 6 * 32(mem_cd), x2, x2; \
 	\
@@ -204,7 +222,7 @@
 	vpxor 3 * 32(mem_cd), x7, x7;
 
 /*
- * Size optimization... with inlined roundsm16 binary would be over 5 times
+ * Size optimization... with inlined roundsm32 binary would be over 5 times
  * larger and would only marginally faster.
  */
 .align 8
@@ -324,13 +342,13 @@ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x
 	 */ \
 	vpbroadcastd kll, t0; /* only lowest 32-bit used */ \
 	vpxor tt0, tt0, tt0; \
-	vpbroadcastb t0##_x, t3; \
+	vpshufb tt0, t0, t3; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t2; \
+	vpshufb tt0, t0, t2; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t1; \
+	vpshufb tt0, t0, t1; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t0; \
+	vpshufb tt0, t0, t0; \
 	\
 	vpand l0, t0, t0; \
 	vpand l1, t1, t1; \
@@ -340,6 +358,7 @@ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x
 	rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
 	\
 	vpxor l4, t0, l4; \
+	vpbroadcastd krr, t0; /* only lowest 32-bit used */ \
 	vmovdqu l4, 4 * 32(l); \
 	vpxor l5, t1, l5; \
 	vmovdqu l5, 5 * 32(l); \
@@ -354,14 +373,13 @@ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x
 	 * rl ^= t2; \
 	 */ \
 	\
-	vpbroadcastd krr, t0; /* only lowest 32-bit used */ \
-	vpbroadcastb t0##_x, t3; \
+	vpshufb tt0, t0, t3; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t2; \
+	vpshufb tt0, t0, t2; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t1; \
+	vpshufb tt0, t0, t1; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t0; \
+	vpshufb tt0, t0, t0; \
 	\
 	vpor 4 * 32(r), t0, t0; \
 	vpor 5 * 32(r), t1, t1; \
@@ -373,6 +391,7 @@ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x
 	vpxor 2 * 32(r), t2, t2; \
 	vpxor 3 * 32(r), t3, t3; \
 	vmovdqu t0, 0 * 32(r); \
+	vpbroadcastd krl, t0; /* only lowest 32-bit used */ \
 	vmovdqu t1, 1 * 32(r); \
 	vmovdqu t2, 2 * 32(r); \
 	vmovdqu t3, 3 * 32(r); \
@@ -382,14 +401,13 @@ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x
 	 * t2 &= rl; \
 	 * rr ^= rol32(t2, 1); \
 	 */ \
-	vpbroadcastd krl, t0; /* only lowest 32-bit used */ \
-	vpbroadcastb t0##_x, t3; \
+	vpshufb tt0, t0, t3; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t2; \
+	vpshufb tt0, t0, t2; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t1; \
+	vpshufb tt0, t0, t1; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t0; \
+	vpshufb tt0, t0, t0; \
 	\
 	vpand 0 * 32(r), t0, t0; \
 	vpand 1 * 32(r), t1, t1; \
@@ -403,6 +421,7 @@ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x
 	vpxor 6 * 32(r), t2, t2; \
 	vpxor 7 * 32(r), t3, t3; \
 	vmovdqu t0, 4 * 32(r); \
+	vpbroadcastd klr, t0; /* only lowest 32-bit used */ \
 	vmovdqu t1, 5 * 32(r); \
 	vmovdqu t2, 6 * 32(r); \
 	vmovdqu t3, 7 * 32(r); \
@@ -413,14 +432,13 @@ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x
 	 * ll ^= t0; \
 	 */ \
 	\
-	vpbroadcastd klr, t0; /* only lowest 32-bit used */ \
-	vpbroadcastb t0##_x, t3; \
+	vpshufb tt0, t0, t3; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t2; \
+	vpshufb tt0, t0, t2; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t1; \
+	vpshufb tt0, t0, t1; \
 	vpsrldq $1, t0, t0; \
-	vpbroadcastb t0##_x, t0; \
+	vpshufb tt0, t0, t0; \
 	\
 	vpor l4, t0, t0; \
 	vpor l5, t1, t1; \
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/Makefile linux-libre-3.11-rc7-gnu/arch/x86/crypto/Makefile
--- linux-libre-3.10-gnu/arch/x86/crypto/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,8 +3,6 @@
 #
 
 avx_supported := $(call as-instr,vpxor %xmm0$(comma)%xmm0$(comma)%xmm0,yes,no)
-avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\
-					$(comma)4)$(comma)%ymm2,yes,no)
 
 obj-$(CONFIG_CRYPTO_ABLK_HELPER_X86) += ablk_helper.o
 obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o
@@ -42,10 +40,8 @@ endif
 
 # These modules require assembler to support AVX2.
 ifeq ($(avx2_supported),yes)
-	obj-$(CONFIG_CRYPTO_BLOWFISH_AVX2_X86_64) += blowfish-avx2.o
 	obj-$(CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64) += camellia-aesni-avx2.o
 	obj-$(CONFIG_CRYPTO_SERPENT_AVX2_X86_64) += serpent-avx2.o
-	obj-$(CONFIG_CRYPTO_TWOFISH_AVX2_X86_64) += twofish-avx2.o
 endif
 
 aes-i586-y := aes-i586-asm_32.o aes_glue.o
@@ -73,10 +69,8 @@ ifeq ($(avx_supported),yes)
 endif
 
 ifeq ($(avx2_supported),yes)
-	blowfish-avx2-y := blowfish-avx2-asm_64.o blowfish_avx2_glue.o
 	camellia-aesni-avx2-y := camellia-aesni-avx2-asm_64.o camellia_aesni_avx2_glue.o
 	serpent-avx2-y := serpent-avx2-asm_64.o serpent_avx2_glue.o
-	twofish-avx2-y := twofish-avx2-asm_64.o twofish_avx2_glue.o
 endif
 
 aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/sha256_ssse3_glue.c linux-libre-3.11-rc7-gnu/arch/x86/crypto/sha256_ssse3_glue.c
--- linux-libre-3.10-gnu/arch/x86/crypto/sha256_ssse3_glue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/sha256_ssse3_glue.c	2013-08-25 20:43:22.000000000 -0400
@@ -187,7 +187,36 @@ static int sha256_ssse3_import(struct sh
 	return 0;
 }
 
-static struct shash_alg alg = {
+static int sha224_ssse3_init(struct shash_desc *desc)
+{
+	struct sha256_state *sctx = shash_desc_ctx(desc);
+
+	sctx->state[0] = SHA224_H0;
+	sctx->state[1] = SHA224_H1;
+	sctx->state[2] = SHA224_H2;
+	sctx->state[3] = SHA224_H3;
+	sctx->state[4] = SHA224_H4;
+	sctx->state[5] = SHA224_H5;
+	sctx->state[6] = SHA224_H6;
+	sctx->state[7] = SHA224_H7;
+	sctx->count = 0;
+
+	return 0;
+}
+
+static int sha224_ssse3_final(struct shash_desc *desc, u8 *hash)
+{
+	u8 D[SHA256_DIGEST_SIZE];
+
+	sha256_ssse3_final(desc, D);
+
+	memcpy(hash, D, SHA224_DIGEST_SIZE);
+	memset(D, 0, SHA256_DIGEST_SIZE);
+
+	return 0;
+}
+
+static struct shash_alg algs[] = { {
 	.digestsize	=	SHA256_DIGEST_SIZE,
 	.init		=	sha256_ssse3_init,
 	.update		=	sha256_ssse3_update,
@@ -204,7 +233,24 @@ static struct shash_alg alg = {
 		.cra_blocksize	=	SHA256_BLOCK_SIZE,
 		.cra_module	=	THIS_MODULE,
 	}
-};
+}, {
+	.digestsize	=	SHA224_DIGEST_SIZE,
+	.init		=	sha224_ssse3_init,
+	.update		=	sha256_ssse3_update,
+	.final		=	sha224_ssse3_final,
+	.export		=	sha256_ssse3_export,
+	.import		=	sha256_ssse3_import,
+	.descsize	=	sizeof(struct sha256_state),
+	.statesize	=	sizeof(struct sha256_state),
+	.base		=	{
+		.cra_name	=	"sha224",
+		.cra_driver_name =	"sha224-ssse3",
+		.cra_priority	=	150,
+		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize	=	SHA224_BLOCK_SIZE,
+		.cra_module	=	THIS_MODULE,
+	}
+} };
 
 #ifdef CONFIG_AS_AVX
 static bool __init avx_usable(void)
@@ -227,7 +273,7 @@ static bool __init avx_usable(void)
 
 static int __init sha256_ssse3_mod_init(void)
 {
-	/* test for SSE3 first */
+	/* test for SSSE3 first */
 	if (cpu_has_ssse3)
 		sha256_transform_asm = sha256_transform_ssse3;
 
@@ -254,7 +300,7 @@ static int __init sha256_ssse3_mod_init(
 		else
 #endif
 			pr_info("Using SSSE3 optimized SHA-256 implementation\n");
-		return crypto_register_shash(&alg);
+		return crypto_register_shashes(algs, ARRAY_SIZE(algs));
 	}
 	pr_info("Neither AVX nor SSSE3 is available/usable.\n");
 
@@ -263,7 +309,7 @@ static int __init sha256_ssse3_mod_init(
 
 static void __exit sha256_ssse3_mod_fini(void)
 {
-	crypto_unregister_shash(&alg);
+	crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
 }
 
 module_init(sha256_ssse3_mod_init);
@@ -273,3 +319,4 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm, Supplemental SSE3 accelerated");
 
 MODULE_ALIAS("sha256");
+MODULE_ALIAS("sha384");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/sha512_ssse3_glue.c linux-libre-3.11-rc7-gnu/arch/x86/crypto/sha512_ssse3_glue.c
--- linux-libre-3.10-gnu/arch/x86/crypto/sha512_ssse3_glue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/sha512_ssse3_glue.c	2013-08-25 20:43:22.000000000 -0400
@@ -194,7 +194,37 @@ static int sha512_ssse3_import(struct sh
 	return 0;
 }
 
-static struct shash_alg alg = {
+static int sha384_ssse3_init(struct shash_desc *desc)
+{
+	struct sha512_state *sctx = shash_desc_ctx(desc);
+
+	sctx->state[0] = SHA384_H0;
+	sctx->state[1] = SHA384_H1;
+	sctx->state[2] = SHA384_H2;
+	sctx->state[3] = SHA384_H3;
+	sctx->state[4] = SHA384_H4;
+	sctx->state[5] = SHA384_H5;
+	sctx->state[6] = SHA384_H6;
+	sctx->state[7] = SHA384_H7;
+
+	sctx->count[0] = sctx->count[1] = 0;
+
+	return 0;
+}
+
+static int sha384_ssse3_final(struct shash_desc *desc, u8 *hash)
+{
+	u8 D[SHA512_DIGEST_SIZE];
+
+	sha512_ssse3_final(desc, D);
+
+	memcpy(hash, D, SHA384_DIGEST_SIZE);
+	memset(D, 0, SHA512_DIGEST_SIZE);
+
+	return 0;
+}
+
+static struct shash_alg algs[] = { {
 	.digestsize	=	SHA512_DIGEST_SIZE,
 	.init		=	sha512_ssse3_init,
 	.update		=	sha512_ssse3_update,
@@ -211,7 +241,24 @@ static struct shash_alg alg = {
 		.cra_blocksize	=	SHA512_BLOCK_SIZE,
 		.cra_module	=	THIS_MODULE,
 	}
-};
+},  {
+	.digestsize	=	SHA384_DIGEST_SIZE,
+	.init		=	sha384_ssse3_init,
+	.update		=	sha512_ssse3_update,
+	.final		=	sha384_ssse3_final,
+	.export		=	sha512_ssse3_export,
+	.import		=	sha512_ssse3_import,
+	.descsize	=	sizeof(struct sha512_state),
+	.statesize	=	sizeof(struct sha512_state),
+	.base		=	{
+		.cra_name	=	"sha384",
+		.cra_driver_name =	"sha384-ssse3",
+		.cra_priority	=	150,
+		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize	=	SHA384_BLOCK_SIZE,
+		.cra_module	=	THIS_MODULE,
+	}
+} };
 
 #ifdef CONFIG_AS_AVX
 static bool __init avx_usable(void)
@@ -234,7 +281,7 @@ static bool __init avx_usable(void)
 
 static int __init sha512_ssse3_mod_init(void)
 {
-	/* test for SSE3 first */
+	/* test for SSSE3 first */
 	if (cpu_has_ssse3)
 		sha512_transform_asm = sha512_transform_ssse3;
 
@@ -261,7 +308,7 @@ static int __init sha512_ssse3_mod_init(
 		else
 #endif
 			pr_info("Using SSSE3 optimized SHA-512 implementation\n");
-		return crypto_register_shash(&alg);
+		return crypto_register_shashes(algs, ARRAY_SIZE(algs));
 	}
 	pr_info("Neither AVX nor SSSE3 is available/usable.\n");
 
@@ -270,7 +317,7 @@ static int __init sha512_ssse3_mod_init(
 
 static void __exit sha512_ssse3_mod_fini(void)
 {
-	crypto_unregister_shash(&alg);
+	crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
 }
 
 module_init(sha512_ssse3_mod_init);
@@ -280,3 +327,4 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SHA512 Secure Hash Algorithm, Supplemental SSE3 accelerated");
 
 MODULE_ALIAS("sha512");
+MODULE_ALIAS("sha384");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/twofish-avx2-asm_64.S linux-libre-3.11-rc7-gnu/arch/x86/crypto/twofish-avx2-asm_64.S
--- linux-libre-3.10-gnu/arch/x86/crypto/twofish-avx2-asm_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/twofish-avx2-asm_64.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,600 +0,0 @@
-/*
- * x86_64/AVX2 assembler optimized version of Twofish
- *
- * Copyright © 2012-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/linkage.h>
-#include "glue_helper-asm-avx2.S"
-
-.file "twofish-avx2-asm_64.S"
-
-.data
-.align 16
-
-.Lvpshufb_mask0:
-.long 0x80808000
-.long 0x80808004
-.long 0x80808008
-.long 0x8080800c
-
-.Lbswap128_mask:
-	.byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
-.Lxts_gf128mul_and_shl1_mask_0:
-	.byte 0x87, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
-.Lxts_gf128mul_and_shl1_mask_1:
-	.byte 0x0e, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0
-
-.text
-
-/* structure of crypto context */
-#define s0	0
-#define s1	1024
-#define s2	2048
-#define s3	3072
-#define w	4096
-#define	k	4128
-
-/* register macros */
-#define CTX	%rdi
-
-#define RS0	CTX
-#define RS1	%r8
-#define RS2	%r9
-#define RS3	%r10
-#define RK	%r11
-#define RW	%rax
-#define RROUND  %r12
-#define RROUNDd %r12d
-
-#define RA0	%ymm8
-#define RB0	%ymm9
-#define RC0	%ymm10
-#define RD0	%ymm11
-#define RA1	%ymm12
-#define RB1	%ymm13
-#define RC1	%ymm14
-#define RD1	%ymm15
-
-/* temp regs */
-#define RX0	%ymm0
-#define RY0	%ymm1
-#define RX1	%ymm2
-#define RY1	%ymm3
-#define RT0	%ymm4
-#define RIDX	%ymm5
-
-#define RX0x	%xmm0
-#define RY0x	%xmm1
-#define RX1x	%xmm2
-#define RY1x	%xmm3
-#define RT0x	%xmm4
-
-/* vpgatherdd mask and '-1' */
-#define RNOT	%ymm6
-
-/* byte mask, (-1 >> 24) */
-#define RBYTE	%ymm7
-
-/**********************************************************************
-  16-way AVX2 twofish
- **********************************************************************/
-#define init_round_constants() \
-	vpcmpeqd RNOT, RNOT, RNOT; \
-	vpsrld $24, RNOT, RBYTE; \
-	leaq k(CTX), RK; \
-	leaq w(CTX), RW; \
-	leaq s1(CTX), RS1; \
-	leaq s2(CTX), RS2; \
-	leaq s3(CTX), RS3; \
-
-#define g16(ab, rs0, rs1, rs2, rs3, xy) \
-	vpand RBYTE, ab ## 0, RIDX; \
-	vpgatherdd RNOT, (rs0, RIDX, 4), xy ## 0; \
-	vpcmpeqd RNOT, RNOT, RNOT; \
-		\
-		vpand RBYTE, ab ## 1, RIDX; \
-		vpgatherdd RNOT, (rs0, RIDX, 4), xy ## 1; \
-		vpcmpeqd RNOT, RNOT, RNOT; \
-	\
-	vpsrld $8, ab ## 0, RIDX; \
-	vpand RBYTE, RIDX, RIDX; \
-	vpgatherdd RNOT, (rs1, RIDX, 4), RT0; \
-	vpcmpeqd RNOT, RNOT, RNOT; \
-	vpxor RT0, xy ## 0, xy ## 0; \
-		\
-		vpsrld $8, ab ## 1, RIDX; \
-		vpand RBYTE, RIDX, RIDX; \
-		vpgatherdd RNOT, (rs1, RIDX, 4), RT0; \
-		vpcmpeqd RNOT, RNOT, RNOT; \
-		vpxor RT0, xy ## 1, xy ## 1; \
-	\
-	vpsrld $16, ab ## 0, RIDX; \
-	vpand RBYTE, RIDX, RIDX; \
-	vpgatherdd RNOT, (rs2, RIDX, 4), RT0; \
-	vpcmpeqd RNOT, RNOT, RNOT; \
-	vpxor RT0, xy ## 0, xy ## 0; \
-		\
-		vpsrld $16, ab ## 1, RIDX; \
-		vpand RBYTE, RIDX, RIDX; \
-		vpgatherdd RNOT, (rs2, RIDX, 4), RT0; \
-		vpcmpeqd RNOT, RNOT, RNOT; \
-		vpxor RT0, xy ## 1, xy ## 1; \
-	\
-	vpsrld $24, ab ## 0, RIDX; \
-	vpgatherdd RNOT, (rs3, RIDX, 4), RT0; \
-	vpcmpeqd RNOT, RNOT, RNOT; \
-	vpxor RT0, xy ## 0, xy ## 0; \
-		\
-		vpsrld $24, ab ## 1, RIDX; \
-		vpgatherdd RNOT, (rs3, RIDX, 4), RT0; \
-		vpcmpeqd RNOT, RNOT, RNOT; \
-		vpxor RT0, xy ## 1, xy ## 1;
-
-#define g1_16(a, x) \
-	g16(a, RS0, RS1, RS2, RS3, x);
-
-#define g2_16(b, y) \
-	g16(b, RS1, RS2, RS3, RS0, y);
-
-#define encrypt_round_end16(a, b, c, d, nk) \
-	vpaddd RY0, RX0, RX0; \
-	vpaddd RX0, RY0, RY0; \
-	vpbroadcastd nk(RK,RROUND,8), RT0; \
-	vpaddd RT0, RX0, RX0; \
-	vpbroadcastd 4+nk(RK,RROUND,8), RT0; \
-	vpaddd RT0, RY0, RY0; \
-	\
-	vpxor RY0, d ## 0, d ## 0; \
-	\
-	vpxor RX0, c ## 0, c ## 0; \
-	vpsrld $1, c ## 0, RT0; \
-	vpslld $31, c ## 0, c ## 0; \
-	vpor RT0, c ## 0, c ## 0; \
-	\
-		vpaddd RY1, RX1, RX1; \
-		vpaddd RX1, RY1, RY1; \
-		vpbroadcastd nk(RK,RROUND,8), RT0; \
-		vpaddd RT0, RX1, RX1; \
-		vpbroadcastd 4+nk(RK,RROUND,8), RT0; \
-		vpaddd RT0, RY1, RY1; \
-		\
-		vpxor RY1, d ## 1, d ## 1; \
-		\
-		vpxor RX1, c ## 1, c ## 1; \
-		vpsrld $1, c ## 1, RT0; \
-		vpslld $31, c ## 1, c ## 1; \
-		vpor RT0, c ## 1, c ## 1; \
-
-#define encrypt_round16(a, b, c, d, nk) \
-	g2_16(b, RY); \
-	\
-	vpslld $1, b ## 0, RT0; \
-	vpsrld $31, b ## 0, b ## 0; \
-	vpor RT0, b ## 0, b ## 0; \
-	\
-		vpslld $1, b ## 1, RT0; \
-		vpsrld $31, b ## 1, b ## 1; \
-		vpor RT0, b ## 1, b ## 1; \
-	\
-	g1_16(a, RX); \
-	\
-	encrypt_round_end16(a, b, c, d, nk);
-
-#define encrypt_round_first16(a, b, c, d, nk) \
-	vpslld $1, d ## 0, RT0; \
-	vpsrld $31, d ## 0, d ## 0; \
-	vpor RT0, d ## 0, d ## 0; \
-	\
-		vpslld $1, d ## 1, RT0; \
-		vpsrld $31, d ## 1, d ## 1; \
-		vpor RT0, d ## 1, d ## 1; \
-	\
-	encrypt_round16(a, b, c, d, nk);
-
-#define encrypt_round_last16(a, b, c, d, nk) \
-	g2_16(b, RY); \
-	\
-	g1_16(a, RX); \
-	\
-	encrypt_round_end16(a, b, c, d, nk);
-
-#define decrypt_round_end16(a, b, c, d, nk) \
-	vpaddd RY0, RX0, RX0; \
-	vpaddd RX0, RY0, RY0; \
-	vpbroadcastd nk(RK,RROUND,8), RT0; \
-	vpaddd RT0, RX0, RX0; \
-	vpbroadcastd 4+nk(RK,RROUND,8), RT0; \
-	vpaddd RT0, RY0, RY0; \
-	\
-	vpxor RX0, c ## 0, c ## 0; \
-	\
-	vpxor RY0, d ## 0, d ## 0; \
-	vpsrld $1, d ## 0, RT0; \
-	vpslld $31, d ## 0, d ## 0; \
-	vpor RT0, d ## 0, d ## 0; \
-	\
-		vpaddd RY1, RX1, RX1; \
-		vpaddd RX1, RY1, RY1; \
-		vpbroadcastd nk(RK,RROUND,8), RT0; \
-		vpaddd RT0, RX1, RX1; \
-		vpbroadcastd 4+nk(RK,RROUND,8), RT0; \
-		vpaddd RT0, RY1, RY1; \
-		\
-		vpxor RX1, c ## 1, c ## 1; \
-		\
-		vpxor RY1, d ## 1, d ## 1; \
-		vpsrld $1, d ## 1, RT0; \
-		vpslld $31, d ## 1, d ## 1; \
-		vpor RT0, d ## 1, d ## 1;
-
-#define decrypt_round16(a, b, c, d, nk) \
-	g1_16(a, RX); \
-	\
-	vpslld $1, a ## 0, RT0; \
-	vpsrld $31, a ## 0, a ## 0; \
-	vpor RT0, a ## 0, a ## 0; \
-	\
-		vpslld $1, a ## 1, RT0; \
-		vpsrld $31, a ## 1, a ## 1; \
-		vpor RT0, a ## 1, a ## 1; \
-	\
-	g2_16(b, RY); \
-	\
-	decrypt_round_end16(a, b, c, d, nk);
-
-#define decrypt_round_first16(a, b, c, d, nk) \
-	vpslld $1, c ## 0, RT0; \
-	vpsrld $31, c ## 0, c ## 0; \
-	vpor RT0, c ## 0, c ## 0; \
-	\
-		vpslld $1, c ## 1, RT0; \
-		vpsrld $31, c ## 1, c ## 1; \
-		vpor RT0, c ## 1, c ## 1; \
-	\
-	decrypt_round16(a, b, c, d, nk)
-
-#define decrypt_round_last16(a, b, c, d, nk) \
-	g1_16(a, RX); \
-	\
-	g2_16(b, RY); \
-	\
-	decrypt_round_end16(a, b, c, d, nk);
-
-#define encrypt_cycle16() \
-	encrypt_round16(RA, RB, RC, RD, 0); \
-	encrypt_round16(RC, RD, RA, RB, 8);
-
-#define encrypt_cycle_first16() \
-	encrypt_round_first16(RA, RB, RC, RD, 0); \
-	encrypt_round16(RC, RD, RA, RB, 8);
-
-#define encrypt_cycle_last16() \
-	encrypt_round16(RA, RB, RC, RD, 0); \
-	encrypt_round_last16(RC, RD, RA, RB, 8);
-
-#define decrypt_cycle16(n) \
-	decrypt_round16(RC, RD, RA, RB, 8); \
-	decrypt_round16(RA, RB, RC, RD, 0);
-
-#define decrypt_cycle_first16(n) \
-	decrypt_round_first16(RC, RD, RA, RB, 8); \
-	decrypt_round16(RA, RB, RC, RD, 0);
-
-#define decrypt_cycle_last16(n) \
-	decrypt_round16(RC, RD, RA, RB, 8); \
-	decrypt_round_last16(RA, RB, RC, RD, 0);
-
-#define transpose_4x4(x0,x1,x2,x3,t1,t2) \
-	vpunpckhdq x1, x0, t2; \
-	vpunpckldq x1, x0, x0; \
-	\
-	vpunpckldq x3, x2, t1; \
-	vpunpckhdq x3, x2, x2; \
-	\
-	vpunpckhqdq t1,	x0, x1; \
-	vpunpcklqdq t1,	x0, x0; \
-	\
-	vpunpckhqdq x2, t2, x3; \
-	vpunpcklqdq x2,	t2, x2;
-
-#define read_blocks8(offs,a,b,c,d) \
-	transpose_4x4(a, b, c, d, RX0, RY0);
-
-#define write_blocks8(offs,a,b,c,d) \
-	transpose_4x4(a, b, c, d, RX0, RY0);
-
-#define inpack_enc8(a,b,c,d) \
-	vpbroadcastd 4*0(RW), RT0; \
-	vpxor RT0, a, a; \
-	\
-	vpbroadcastd 4*1(RW), RT0; \
-	vpxor RT0, b, b; \
-	\
-	vpbroadcastd 4*2(RW), RT0; \
-	vpxor RT0, c, c; \
-	\
-	vpbroadcastd 4*3(RW), RT0; \
-	vpxor RT0, d, d;
-
-#define outunpack_enc8(a,b,c,d) \
-	vpbroadcastd 4*4(RW), RX0; \
-	vpbroadcastd 4*5(RW), RY0; \
-	vpxor RX0, c, RX0; \
-	vpxor RY0, d, RY0; \
-	\
-	vpbroadcastd 4*6(RW), RT0; \
-	vpxor RT0, a, c; \
-	vpbroadcastd 4*7(RW), RT0; \
-	vpxor RT0, b, d; \
-	\
-	vmovdqa RX0, a; \
-	vmovdqa RY0, b;
-
-#define inpack_dec8(a,b,c,d) \
-	vpbroadcastd 4*4(RW), RX0; \
-	vpbroadcastd 4*5(RW), RY0; \
-	vpxor RX0, a, RX0; \
-	vpxor RY0, b, RY0; \
-	\
-	vpbroadcastd 4*6(RW), RT0; \
-	vpxor RT0, c, a; \
-	vpbroadcastd 4*7(RW), RT0; \
-	vpxor RT0, d, b; \
-	\
-	vmovdqa RX0, c; \
-	vmovdqa RY0, d;
-
-#define outunpack_dec8(a,b,c,d) \
-	vpbroadcastd 4*0(RW), RT0; \
-	vpxor RT0, a, a; \
-	\
-	vpbroadcastd 4*1(RW), RT0; \
-	vpxor RT0, b, b; \
-	\
-	vpbroadcastd 4*2(RW), RT0; \
-	vpxor RT0, c, c; \
-	\
-	vpbroadcastd 4*3(RW), RT0; \
-	vpxor RT0, d, d;
-
-#define read_blocks16(a,b,c,d) \
-	read_blocks8(0, a ## 0, b ## 0, c ## 0, d ## 0); \
-	read_blocks8(8, a ## 1, b ## 1, c ## 1, d ## 1);
-
-#define write_blocks16(a,b,c,d) \
-	write_blocks8(0, a ## 0, b ## 0, c ## 0, d ## 0); \
-	write_blocks8(8, a ## 1, b ## 1, c ## 1, d ## 1);
-
-#define xor_blocks16(a,b,c,d) \
-	xor_blocks8(0, a ## 0, b ## 0, c ## 0, d ## 0); \
-	xor_blocks8(8, a ## 1, b ## 1, c ## 1, d ## 1);
-
-#define inpack_enc16(a,b,c,d) \
-	inpack_enc8(a ## 0, b ## 0, c ## 0, d ## 0); \
-	inpack_enc8(a ## 1, b ## 1, c ## 1, d ## 1);
-
-#define outunpack_enc16(a,b,c,d) \
-	outunpack_enc8(a ## 0, b ## 0, c ## 0, d ## 0); \
-	outunpack_enc8(a ## 1, b ## 1, c ## 1, d ## 1);
-
-#define inpack_dec16(a,b,c,d) \
-	inpack_dec8(a ## 0, b ## 0, c ## 0, d ## 0); \
-	inpack_dec8(a ## 1, b ## 1, c ## 1, d ## 1);
-
-#define outunpack_dec16(a,b,c,d) \
-	outunpack_dec8(a ## 0, b ## 0, c ## 0, d ## 0); \
-	outunpack_dec8(a ## 1, b ## 1, c ## 1, d ## 1);
-
-.align 8
-__twofish_enc_blk16:
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1: plaintext
-	 * output:
-	 *	RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1: ciphertext
-	 */
-	init_round_constants();
-
-	read_blocks16(RA, RB, RC, RD);
-	inpack_enc16(RA, RB, RC, RD);
-
-	xorl RROUNDd, RROUNDd;
-	encrypt_cycle_first16();
-	movl $2, RROUNDd;
-
-.align 4
-.L__enc_loop:
-	encrypt_cycle16();
-
-	addl $2, RROUNDd;
-	cmpl $14, RROUNDd;
-	jne .L__enc_loop;
-
-	encrypt_cycle_last16();
-
-	outunpack_enc16(RA, RB, RC, RD);
-	write_blocks16(RA, RB, RC, RD);
-
-	ret;
-ENDPROC(__twofish_enc_blk16)
-
-.align 8
-__twofish_dec_blk16:
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1: ciphertext
-	 * output:
-	 *	RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1: plaintext
-	 */
-	init_round_constants();
-
-	read_blocks16(RA, RB, RC, RD);
-	inpack_dec16(RA, RB, RC, RD);
-
-	movl $14, RROUNDd;
-	decrypt_cycle_first16();
-	movl $12, RROUNDd;
-
-.align 4
-.L__dec_loop:
-	decrypt_cycle16();
-
-	addl $-2, RROUNDd;
-	jnz .L__dec_loop;
-
-	decrypt_cycle_last16();
-
-	outunpack_dec16(RA, RB, RC, RD);
-	write_blocks16(RA, RB, RC, RD);
-
-	ret;
-ENDPROC(__twofish_dec_blk16)
-
-ENTRY(twofish_ecb_enc_16way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst
-	 *	%rdx: src
-	 */
-
-	vzeroupper;
-	pushq %r12;
-
-	load_16way(%rdx, RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1);
-
-	call __twofish_enc_blk16;
-
-	store_16way(%rsi, RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1);
-
-	popq %r12;
-	vzeroupper;
-
-	ret;
-ENDPROC(twofish_ecb_enc_16way)
-
-ENTRY(twofish_ecb_dec_16way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst
-	 *	%rdx: src
-	 */
-
-	vzeroupper;
-	pushq %r12;
-
-	load_16way(%rdx, RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1);
-
-	call __twofish_dec_blk16;
-
-	store_16way(%rsi, RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1);
-
-	popq %r12;
-	vzeroupper;
-
-	ret;
-ENDPROC(twofish_ecb_dec_16way)
-
-ENTRY(twofish_cbc_dec_16way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst
-	 *	%rdx: src
-	 */
-
-	vzeroupper;
-	pushq %r12;
-
-	load_16way(%rdx, RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1);
-
-	call __twofish_dec_blk16;
-
-	store_cbc_16way(%rdx, %rsi, RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1,
-			RX0);
-
-	popq %r12;
-	vzeroupper;
-
-	ret;
-ENDPROC(twofish_cbc_dec_16way)
-
-ENTRY(twofish_ctr_16way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst (16 blocks)
-	 *	%rdx: src (16 blocks)
-	 *	%rcx: iv (little endian, 128bit)
-	 */
-
-	vzeroupper;
-	pushq %r12;
-
-	load_ctr_16way(%rcx, .Lbswap128_mask, RA0, RB0, RC0, RD0, RA1, RB1, RC1,
-		       RD1, RX0, RX0x, RX1, RX1x, RY0, RY0x, RY1, RY1x, RNOT,
-		       RBYTE);
-
-	call __twofish_enc_blk16;
-
-	store_ctr_16way(%rdx, %rsi, RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1);
-
-	popq %r12;
-	vzeroupper;
-
-	ret;
-ENDPROC(twofish_ctr_16way)
-
-.align 8
-twofish_xts_crypt_16way:
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst (16 blocks)
-	 *	%rdx: src (16 blocks)
-	 *	%rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸))
-	 *	%r8: pointer to __twofish_enc_blk16 or __twofish_dec_blk16
-	 */
-
-	vzeroupper;
-	pushq %r12;
-
-	load_xts_16way(%rcx, %rdx, %rsi, RA0, RB0, RC0, RD0, RA1, RB1, RC1,
-		       RD1, RX0, RX0x, RX1, RX1x, RY0, RY0x, RY1, RY1x, RNOT,
-		       .Lxts_gf128mul_and_shl1_mask_0,
-		       .Lxts_gf128mul_and_shl1_mask_1);
-
-	call *%r8;
-
-	store_xts_16way(%rsi, RA0, RB0, RC0, RD0, RA1, RB1, RC1, RD1);
-
-	popq %r12;
-	vzeroupper;
-
-	ret;
-ENDPROC(twofish_xts_crypt_16way)
-
-ENTRY(twofish_xts_enc_16way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst (16 blocks)
-	 *	%rdx: src (16 blocks)
-	 *	%rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸))
-	 */
-	leaq __twofish_enc_blk16, %r8;
-	jmp twofish_xts_crypt_16way;
-ENDPROC(twofish_xts_enc_16way)
-
-ENTRY(twofish_xts_dec_16way)
-	/* input:
-	 *	%rdi: ctx, CTX
-	 *	%rsi: dst (16 blocks)
-	 *	%rdx: src (16 blocks)
-	 *	%rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸))
-	 */
-	leaq __twofish_dec_blk16, %r8;
-	jmp twofish_xts_crypt_16way;
-ENDPROC(twofish_xts_dec_16way)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/twofish_avx2_glue.c linux-libre-3.11-rc7-gnu/arch/x86/crypto/twofish_avx2_glue.c
--- linux-libre-3.10-gnu/arch/x86/crypto/twofish_avx2_glue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/twofish_avx2_glue.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,584 +0,0 @@
-/*
- * Glue Code for x86_64/AVX2 assembler optimized version of Twofish
- *
- * Copyright © 2012-2013 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/crypto.h>
-#include <linux/err.h>
-#include <crypto/algapi.h>
-#include <crypto/ctr.h>
-#include <crypto/twofish.h>
-#include <crypto/lrw.h>
-#include <crypto/xts.h>
-#include <asm/xcr.h>
-#include <asm/xsave.h>
-#include <asm/crypto/twofish.h>
-#include <asm/crypto/ablk_helper.h>
-#include <asm/crypto/glue_helper.h>
-#include <crypto/scatterwalk.h>
-
-#define TF_AVX2_PARALLEL_BLOCKS 16
-
-/* 16-way AVX2 parallel cipher functions */
-asmlinkage void twofish_ecb_enc_16way(struct twofish_ctx *ctx, u8 *dst,
-				      const u8 *src);
-asmlinkage void twofish_ecb_dec_16way(struct twofish_ctx *ctx, u8 *dst,
-				      const u8 *src);
-asmlinkage void twofish_cbc_dec_16way(void *ctx, u128 *dst, const u128 *src);
-
-asmlinkage void twofish_ctr_16way(void *ctx, u128 *dst, const u128 *src,
-				  le128 *iv);
-
-asmlinkage void twofish_xts_enc_16way(struct twofish_ctx *ctx, u8 *dst,
-				      const u8 *src, le128 *iv);
-asmlinkage void twofish_xts_dec_16way(struct twofish_ctx *ctx, u8 *dst,
-				      const u8 *src, le128 *iv);
-
-static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
-					const u8 *src)
-{
-	__twofish_enc_blk_3way(ctx, dst, src, false);
-}
-
-static const struct common_glue_ctx twofish_enc = {
-	.num_funcs = 4,
-	.fpu_blocks_limit = 8,
-
-	.funcs = { {
-		.num_blocks = 16,
-		.fn_u = { .ecb = GLUE_FUNC_CAST(twofish_ecb_enc_16way) }
-	}, {
-		.num_blocks = 8,
-		.fn_u = { .ecb = GLUE_FUNC_CAST(twofish_ecb_enc_8way) }
-	}, {
-		.num_blocks = 3,
-		.fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_3way) }
-	}, {
-		.num_blocks = 1,
-		.fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk) }
-	} }
-};
-
-static const struct common_glue_ctx twofish_ctr = {
-	.num_funcs = 4,
-	.fpu_blocks_limit = 8,
-
-	.funcs = { {
-		.num_blocks = 16,
-		.fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_ctr_16way) }
-	},  {
-		.num_blocks = 8,
-		.fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_ctr_8way) }
-	}, {
-		.num_blocks = 3,
-		.fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr_3way) }
-	}, {
-		.num_blocks = 1,
-		.fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr) }
-	} }
-};
-
-static const struct common_glue_ctx twofish_enc_xts = {
-	.num_funcs = 3,
-	.fpu_blocks_limit = 8,
-
-	.funcs = { {
-		.num_blocks = 16,
-		.fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_enc_16way) }
-	}, {
-		.num_blocks = 8,
-		.fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_enc_8way) }
-	}, {
-		.num_blocks = 1,
-		.fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_enc) }
-	} }
-};
-
-static const struct common_glue_ctx twofish_dec = {
-	.num_funcs = 4,
-	.fpu_blocks_limit = 8,
-
-	.funcs = { {
-		.num_blocks = 16,
-		.fn_u = { .ecb = GLUE_FUNC_CAST(twofish_ecb_dec_16way) }
-	}, {
-		.num_blocks = 8,
-		.fn_u = { .ecb = GLUE_FUNC_CAST(twofish_ecb_dec_8way) }
-	}, {
-		.num_blocks = 3,
-		.fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk_3way) }
-	}, {
-		.num_blocks = 1,
-		.fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk) }
-	} }
-};
-
-static const struct common_glue_ctx twofish_dec_cbc = {
-	.num_funcs = 4,
-	.fpu_blocks_limit = 8,
-
-	.funcs = { {
-		.num_blocks = 16,
-		.fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_cbc_dec_16way) }
-	}, {
-		.num_blocks = 8,
-		.fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_cbc_dec_8way) }
-	}, {
-		.num_blocks = 3,
-		.fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_3way) }
-	}, {
-		.num_blocks = 1,
-		.fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk) }
-	} }
-};
-
-static const struct common_glue_ctx twofish_dec_xts = {
-	.num_funcs = 3,
-	.fpu_blocks_limit = 8,
-
-	.funcs = { {
-		.num_blocks = 16,
-		.fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_dec_16way) }
-	}, {
-		.num_blocks = 8,
-		.fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_dec_8way) }
-	}, {
-		.num_blocks = 1,
-		.fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_dec) }
-	} }
-};
-
-static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	return glue_ecb_crypt_128bit(&twofish_enc, desc, dst, src, nbytes);
-}
-
-static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	return glue_ecb_crypt_128bit(&twofish_dec, desc, dst, src, nbytes);
-}
-
-static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(twofish_enc_blk), desc,
-				       dst, src, nbytes);
-}
-
-static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	return glue_cbc_decrypt_128bit(&twofish_dec_cbc, desc, dst, src,
-				       nbytes);
-}
-
-static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		     struct scatterlist *src, unsigned int nbytes)
-{
-	return glue_ctr_crypt_128bit(&twofish_ctr, desc, dst, src, nbytes);
-}
-
-static inline bool twofish_fpu_begin(bool fpu_enabled, unsigned int nbytes)
-{
-	/* since reusing AVX functions, starts using FPU at 8 parallel blocks */
-	return glue_fpu_begin(TF_BLOCK_SIZE, 8, NULL, fpu_enabled, nbytes);
-}
-
-static inline void twofish_fpu_end(bool fpu_enabled)
-{
-	glue_fpu_end(fpu_enabled);
-}
-
-struct crypt_priv {
-	struct twofish_ctx *ctx;
-	bool fpu_enabled;
-};
-
-static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
-{
-	const unsigned int bsize = TF_BLOCK_SIZE;
-	struct crypt_priv *ctx = priv;
-	int i;
-
-	ctx->fpu_enabled = twofish_fpu_begin(ctx->fpu_enabled, nbytes);
-
-	while (nbytes >= TF_AVX2_PARALLEL_BLOCKS * bsize) {
-		twofish_ecb_enc_16way(ctx->ctx, srcdst, srcdst);
-		srcdst += bsize * TF_AVX2_PARALLEL_BLOCKS;
-		nbytes -= bsize * TF_AVX2_PARALLEL_BLOCKS;
-	}
-
-	while (nbytes >= 8 * bsize) {
-		twofish_ecb_enc_8way(ctx->ctx, srcdst, srcdst);
-		srcdst += bsize * 8;
-		nbytes -= bsize * 8;
-	}
-
-	while (nbytes >= 3 * bsize) {
-		twofish_enc_blk_3way(ctx->ctx, srcdst, srcdst);
-		srcdst += bsize * 3;
-		nbytes -= bsize * 3;
-	}
-
-	for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
-		twofish_enc_blk(ctx->ctx, srcdst, srcdst);
-}
-
-static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
-{
-	const unsigned int bsize = TF_BLOCK_SIZE;
-	struct crypt_priv *ctx = priv;
-	int i;
-
-	ctx->fpu_enabled = twofish_fpu_begin(ctx->fpu_enabled, nbytes);
-
-	while (nbytes >= TF_AVX2_PARALLEL_BLOCKS * bsize) {
-		twofish_ecb_dec_16way(ctx->ctx, srcdst, srcdst);
-		srcdst += bsize * TF_AVX2_PARALLEL_BLOCKS;
-		nbytes -= bsize * TF_AVX2_PARALLEL_BLOCKS;
-	}
-
-	while (nbytes >= 8 * bsize) {
-		twofish_ecb_dec_8way(ctx->ctx, srcdst, srcdst);
-		srcdst += bsize * 8;
-		nbytes -= bsize * 8;
-	}
-
-	while (nbytes >= 3 * bsize) {
-		twofish_dec_blk_3way(ctx->ctx, srcdst, srcdst);
-		srcdst += bsize * 3;
-		nbytes -= bsize * 3;
-	}
-
-	for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
-		twofish_dec_blk(ctx->ctx, srcdst, srcdst);
-}
-
-static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-	be128 buf[TF_AVX2_PARALLEL_BLOCKS];
-	struct crypt_priv crypt_ctx = {
-		.ctx = &ctx->twofish_ctx,
-		.fpu_enabled = false,
-	};
-	struct lrw_crypt_req req = {
-		.tbuf = buf,
-		.tbuflen = sizeof(buf),
-
-		.table_ctx = &ctx->lrw_table,
-		.crypt_ctx = &crypt_ctx,
-		.crypt_fn = encrypt_callback,
-	};
-	int ret;
-
-	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
-	ret = lrw_crypt(desc, dst, src, nbytes, &req);
-	twofish_fpu_end(crypt_ctx.fpu_enabled);
-
-	return ret;
-}
-
-static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-	be128 buf[TF_AVX2_PARALLEL_BLOCKS];
-	struct crypt_priv crypt_ctx = {
-		.ctx = &ctx->twofish_ctx,
-		.fpu_enabled = false,
-	};
-	struct lrw_crypt_req req = {
-		.tbuf = buf,
-		.tbuflen = sizeof(buf),
-
-		.table_ctx = &ctx->lrw_table,
-		.crypt_ctx = &crypt_ctx,
-		.crypt_fn = decrypt_callback,
-	};
-	int ret;
-
-	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
-	ret = lrw_crypt(desc, dst, src, nbytes, &req);
-	twofish_fpu_end(crypt_ctx.fpu_enabled);
-
-	return ret;
-}
-
-static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-
-	return glue_xts_crypt_128bit(&twofish_enc_xts, desc, dst, src, nbytes,
-				     XTS_TWEAK_CAST(twofish_enc_blk),
-				     &ctx->tweak_ctx, &ctx->crypt_ctx);
-}
-
-static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
-		       struct scatterlist *src, unsigned int nbytes)
-{
-	struct twofish_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
-
-	return glue_xts_crypt_128bit(&twofish_dec_xts, desc, dst, src, nbytes,
-				     XTS_TWEAK_CAST(twofish_enc_blk),
-				     &ctx->tweak_ctx, &ctx->crypt_ctx);
-}
-
-static struct crypto_alg tf_algs[10] = { {
-	.cra_name		= "__ecb-twofish-avx2",
-	.cra_driver_name	= "__driver-ecb-twofish-avx2",
-	.cra_priority		= 0,
-	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
-	.cra_blocksize		= TF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct twofish_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_blkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_u = {
-		.blkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE,
-			.max_keysize	= TF_MAX_KEY_SIZE,
-			.setkey		= twofish_setkey,
-			.encrypt	= ecb_encrypt,
-			.decrypt	= ecb_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "__cbc-twofish-avx2",
-	.cra_driver_name	= "__driver-cbc-twofish-avx2",
-	.cra_priority		= 0,
-	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
-	.cra_blocksize		= TF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct twofish_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_blkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_u = {
-		.blkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE,
-			.max_keysize	= TF_MAX_KEY_SIZE,
-			.setkey		= twofish_setkey,
-			.encrypt	= cbc_encrypt,
-			.decrypt	= cbc_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "__ctr-twofish-avx2",
-	.cra_driver_name	= "__driver-ctr-twofish-avx2",
-	.cra_priority		= 0,
-	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
-	.cra_blocksize		= 1,
-	.cra_ctxsize		= sizeof(struct twofish_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_blkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_u = {
-		.blkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE,
-			.max_keysize	= TF_MAX_KEY_SIZE,
-			.ivsize		= TF_BLOCK_SIZE,
-			.setkey		= twofish_setkey,
-			.encrypt	= ctr_crypt,
-			.decrypt	= ctr_crypt,
-		},
-	},
-}, {
-	.cra_name		= "__lrw-twofish-avx2",
-	.cra_driver_name	= "__driver-lrw-twofish-avx2",
-	.cra_priority		= 0,
-	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
-	.cra_blocksize		= TF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct twofish_lrw_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_blkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_exit		= lrw_twofish_exit_tfm,
-	.cra_u = {
-		.blkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE +
-					  TF_BLOCK_SIZE,
-			.max_keysize	= TF_MAX_KEY_SIZE +
-					  TF_BLOCK_SIZE,
-			.ivsize		= TF_BLOCK_SIZE,
-			.setkey		= lrw_twofish_setkey,
-			.encrypt	= lrw_encrypt,
-			.decrypt	= lrw_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "__xts-twofish-avx2",
-	.cra_driver_name	= "__driver-xts-twofish-avx2",
-	.cra_priority		= 0,
-	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
-	.cra_blocksize		= TF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct twofish_xts_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_blkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_u = {
-		.blkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE * 2,
-			.max_keysize	= TF_MAX_KEY_SIZE * 2,
-			.ivsize		= TF_BLOCK_SIZE,
-			.setkey		= xts_twofish_setkey,
-			.encrypt	= xts_encrypt,
-			.decrypt	= xts_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "ecb(twofish)",
-	.cra_driver_name	= "ecb-twofish-avx2",
-	.cra_priority		= 500,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
-	.cra_blocksize		= TF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct async_helper_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_ablkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_init		= ablk_init,
-	.cra_exit		= ablk_exit,
-	.cra_u = {
-		.ablkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE,
-			.max_keysize	= TF_MAX_KEY_SIZE,
-			.setkey		= ablk_set_key,
-			.encrypt	= ablk_encrypt,
-			.decrypt	= ablk_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "cbc(twofish)",
-	.cra_driver_name	= "cbc-twofish-avx2",
-	.cra_priority		= 500,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
-	.cra_blocksize		= TF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct async_helper_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_ablkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_init		= ablk_init,
-	.cra_exit		= ablk_exit,
-	.cra_u = {
-		.ablkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE,
-			.max_keysize	= TF_MAX_KEY_SIZE,
-			.ivsize		= TF_BLOCK_SIZE,
-			.setkey		= ablk_set_key,
-			.encrypt	= __ablk_encrypt,
-			.decrypt	= ablk_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "ctr(twofish)",
-	.cra_driver_name	= "ctr-twofish-avx2",
-	.cra_priority		= 500,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
-	.cra_blocksize		= 1,
-	.cra_ctxsize		= sizeof(struct async_helper_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_ablkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_init		= ablk_init,
-	.cra_exit		= ablk_exit,
-	.cra_u = {
-		.ablkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE,
-			.max_keysize	= TF_MAX_KEY_SIZE,
-			.ivsize		= TF_BLOCK_SIZE,
-			.setkey		= ablk_set_key,
-			.encrypt	= ablk_encrypt,
-			.decrypt	= ablk_encrypt,
-			.geniv		= "chainiv",
-		},
-	},
-}, {
-	.cra_name		= "lrw(twofish)",
-	.cra_driver_name	= "lrw-twofish-avx2",
-	.cra_priority		= 500,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
-	.cra_blocksize		= TF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct async_helper_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_ablkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_init		= ablk_init,
-	.cra_exit		= ablk_exit,
-	.cra_u = {
-		.ablkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE +
-					  TF_BLOCK_SIZE,
-			.max_keysize	= TF_MAX_KEY_SIZE +
-					  TF_BLOCK_SIZE,
-			.ivsize		= TF_BLOCK_SIZE,
-			.setkey		= ablk_set_key,
-			.encrypt	= ablk_encrypt,
-			.decrypt	= ablk_decrypt,
-		},
-	},
-}, {
-	.cra_name		= "xts(twofish)",
-	.cra_driver_name	= "xts-twofish-avx2",
-	.cra_priority		= 500,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
-	.cra_blocksize		= TF_BLOCK_SIZE,
-	.cra_ctxsize		= sizeof(struct async_helper_ctx),
-	.cra_alignmask		= 0,
-	.cra_type		= &crypto_ablkcipher_type,
-	.cra_module		= THIS_MODULE,
-	.cra_init		= ablk_init,
-	.cra_exit		= ablk_exit,
-	.cra_u = {
-		.ablkcipher = {
-			.min_keysize	= TF_MIN_KEY_SIZE * 2,
-			.max_keysize	= TF_MAX_KEY_SIZE * 2,
-			.ivsize		= TF_BLOCK_SIZE,
-			.setkey		= ablk_set_key,
-			.encrypt	= ablk_encrypt,
-			.decrypt	= ablk_decrypt,
-		},
-	},
-} };
-
-static int __init init(void)
-{
-	u64 xcr0;
-
-	if (!cpu_has_avx2 || !cpu_has_osxsave) {
-		pr_info("AVX2 instructions are not detected.\n");
-		return -ENODEV;
-	}
-
-	xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
-	if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) {
-		pr_info("AVX2 detected but unusable.\n");
-		return -ENODEV;
-	}
-
-	return crypto_register_algs(tf_algs, ARRAY_SIZE(tf_algs));
-}
-
-static void __exit fini(void)
-{
-	crypto_unregister_algs(tf_algs, ARRAY_SIZE(tf_algs));
-}
-
-module_init(init);
-module_exit(fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Twofish Cipher Algorithm, AVX2 optimized");
-MODULE_ALIAS("twofish");
-MODULE_ALIAS("twofish-asm");
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/crypto/twofish_avx_glue.c linux-libre-3.11-rc7-gnu/arch/x86/crypto/twofish_avx_glue.c
--- linux-libre-3.10-gnu/arch/x86/crypto/twofish_avx_glue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/crypto/twofish_avx_glue.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,26 +50,18 @@
 /* 8-way parallel cipher functions */
 asmlinkage void twofish_ecb_enc_8way(struct twofish_ctx *ctx, u8 *dst,
 				     const u8 *src);
-EXPORT_SYMBOL_GPL(twofish_ecb_enc_8way);
-
 asmlinkage void twofish_ecb_dec_8way(struct twofish_ctx *ctx, u8 *dst,
 				     const u8 *src);
-EXPORT_SYMBOL_GPL(twofish_ecb_dec_8way);
 
 asmlinkage void twofish_cbc_dec_8way(struct twofish_ctx *ctx, u8 *dst,
 				     const u8 *src);
-EXPORT_SYMBOL_GPL(twofish_cbc_dec_8way);
-
 asmlinkage void twofish_ctr_8way(struct twofish_ctx *ctx, u8 *dst,
 				 const u8 *src, le128 *iv);
-EXPORT_SYMBOL_GPL(twofish_ctr_8way);
 
 asmlinkage void twofish_xts_enc_8way(struct twofish_ctx *ctx, u8 *dst,
 				     const u8 *src, le128 *iv);
-EXPORT_SYMBOL_GPL(twofish_xts_enc_8way);
 asmlinkage void twofish_xts_dec_8way(struct twofish_ctx *ctx, u8 *dst,
 				     const u8 *src, le128 *iv);
-EXPORT_SYMBOL_GPL(twofish_xts_dec_8way);
 
 static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
 					const u8 *src)
@@ -77,19 +69,17 @@ static inline void twofish_enc_blk_3way(
 	__twofish_enc_blk_3way(ctx, dst, src, false);
 }
 
-void twofish_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv)
+static void twofish_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv)
 {
 	glue_xts_crypt_128bit_one(ctx, dst, src, iv,
 				  GLUE_FUNC_CAST(twofish_enc_blk));
 }
-EXPORT_SYMBOL_GPL(twofish_xts_enc);
 
-void twofish_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv)
+static void twofish_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv)
 {
 	glue_xts_crypt_128bit_one(ctx, dst, src, iv,
 				  GLUE_FUNC_CAST(twofish_dec_blk));
 }
-EXPORT_SYMBOL_GPL(twofish_xts_dec);
 
 
 static const struct common_glue_ctx twofish_enc = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/ia32/ia32_aout.c linux-libre-3.11-rc7-gnu/arch/x86/ia32/ia32_aout.c
--- linux-libre-3.10-gnu/arch/x86/ia32/ia32_aout.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/ia32/ia32_aout.c	2013-08-25 20:43:22.000000000 -0400
@@ -308,8 +308,6 @@ static int load_aout_binary(struct linux
 		(current->mm->start_data = N_DATADDR(ex));
 	current->mm->brk = ex.a_bss +
 		(current->mm->start_brk = N_BSSADDR(ex));
-	current->mm->free_area_cache = TASK_UNMAPPED_BASE;
-	current->mm->cached_hole_size = 0;
 
 	retval = setup_arg_pages(bprm, IA32_STACK_TOP, EXSTACK_DEFAULT);
 	if (retval < 0) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/ia32/ia32_signal.c linux-libre-3.11-rc7-gnu/arch/x86/ia32/ia32_signal.c
--- linux-libre-3.10-gnu/arch/x86/ia32/ia32_signal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/ia32/ia32_signal.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,8 +34,6 @@
 #include <asm/sys_ia32.h>
 #include <asm/smap.h>
 
-#define FIX_EFLAGS	__FIX_EFLAGS
-
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 {
 	int err = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/acpi.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/acpi.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/acpi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/acpi.h	2013-08-25 20:43:22.000000000 -0400
@@ -111,7 +111,7 @@ static inline void acpi_disable_pci(void
 }
 
 /* Low-level suspend routine. */
-extern int acpi_suspend_lowlevel(void);
+extern int (*acpi_suspend_lowlevel)(void);
 
 /* Physical address to resume after wakeup */
 #define acpi_wakeup_address ((unsigned long)(real_mode_header->wakeup_start))
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/apic.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/apic.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/apic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/apic.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,7 @@
 #include <asm/fixmap.h>
 #include <asm/mpspec.h>
 #include <asm/msr.h>
+#include <asm/idle.h>
 
 #define ARCH_APICTIMER_STOPS_ON_C3	1
 
@@ -687,5 +688,31 @@ extern int default_check_phys_apicid_pre
 #endif
 
 #endif /* CONFIG_X86_LOCAL_APIC */
+extern void irq_enter(void);
+extern void irq_exit(void);
+
+static inline void entering_irq(void)
+{
+	irq_enter();
+	exit_idle();
+}
+
+static inline void entering_ack_irq(void)
+{
+	ack_APIC_irq();
+	entering_irq();
+}
+
+static inline void exiting_irq(void)
+{
+	irq_exit();
+}
+
+static inline void exiting_ack_irq(void)
+{
+	irq_exit();
+	/* Ack only at the end to avoid potential reentry */
+	ack_APIC_irq();
+}
 
 #endif /* _ASM_X86_APIC_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/bootparam_utils.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/bootparam_utils.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/bootparam_utils.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/bootparam_utils.h	2013-08-25 20:43:22.000000000 -0400
@@ -35,9 +35,9 @@ static void sanitize_boot_params(struct
 	 */
 	if (boot_params->sentinel) {
 		/* fields in boot_params are left uninitialized, clear them */
-		memset(&boot_params->olpc_ofw_header, 0,
+		memset(&boot_params->ext_ramdisk_image, 0,
 		       (char *)&boot_params->efi_info -
-			(char *)&boot_params->olpc_ofw_header);
+			(char *)&boot_params->ext_ramdisk_image);
 		memset(&boot_params->kbd_status, 0,
 		       (char *)&boot_params->hdr -
 		       (char *)&boot_params->kbd_status);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/cpufeature.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/cpufeature.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/cpufeature.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/cpufeature.h	2013-08-25 20:43:22.000000000 -0400
@@ -92,7 +92,7 @@
 #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* "" Lfence synchronizes RDTSC */
 #define X86_FEATURE_11AP	(3*32+19) /* "" Bad local APIC aka 11AP */
 #define X86_FEATURE_NOPL	(3*32+20) /* The NOPL (0F 1F) instructions */
-					  /* 21 available, was AMD_C1E */
+#define X86_FEATURE_ALWAYS	(3*32+21) /* "" Always-present feature */
 #define X86_FEATURE_XTOPOLOGY	(3*32+22) /* cpu topology enum extensions */
 #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */
 #define X86_FEATURE_NONSTOP_TSC	(3*32+24) /* TSC does not stop in C states */
@@ -356,15 +356,36 @@ extern const char * const x86_power_flag
 #endif /* CONFIG_X86_64 */
 
 #if __GNUC__ >= 4
+extern void warn_pre_alternatives(void);
+extern bool __static_cpu_has_safe(u16 bit);
+
 /*
  * Static testing of CPU features.  Used the same as boot_cpu_has().
  * These are only valid after alternatives have run, but will statically
  * patch the target code for additional performance.
- *
  */
 static __always_inline __pure bool __static_cpu_has(u16 bit)
 {
 #if __GNUC__ > 4 || __GNUC_MINOR__ >= 5
+
+#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
+		/*
+		 * Catch too early usage of this before alternatives
+		 * have run.
+		 */
+		asm goto("1: jmp %l[t_warn]\n"
+			 "2:\n"
+			 ".section .altinstructions,\"a\"\n"
+			 " .long 1b - .\n"
+			 " .long 0\n"		/* no replacement */
+			 " .word %P0\n"		/* 1: do replace */
+			 " .byte 2b - 1b\n"	/* source len */
+			 " .byte 0\n"		/* replacement len */
+			 ".previous\n"
+			 /* skipping size check since replacement size = 0 */
+			 : : "i" (X86_FEATURE_ALWAYS) : : t_warn);
+#endif
+
 		asm goto("1: jmp %l[t_no]\n"
 			 "2:\n"
 			 ".section .altinstructions,\"a\"\n"
@@ -379,7 +400,13 @@ static __always_inline __pure bool __sta
 		return true;
 	t_no:
 		return false;
-#else
+
+#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
+	t_warn:
+		warn_pre_alternatives();
+		return false;
+#endif
+#else /* GCC_VERSION >= 40500 */
 		u8 flag;
 		/* Open-coded due to __stringify() in ALTERNATIVE() */
 		asm volatile("1: movb $0,%0\n"
@@ -411,11 +438,94 @@ static __always_inline __pure bool __sta
 		__static_cpu_has(bit) :				\
 		boot_cpu_has(bit)				\
 )
+
+static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
+{
+#if __GNUC__ > 4 || __GNUC_MINOR__ >= 5
+/*
+ * We need to spell the jumps to the compiler because, depending on the offset,
+ * the replacement jump can be bigger than the original jump, and this we cannot
+ * have. Thus, we force the jump to the widest, 4-byte, signed relative
+ * offset even though the last would often fit in less bytes.
+ */
+		asm goto("1: .byte 0xe9\n .long %l[t_dynamic] - 2f\n"
+			 "2:\n"
+			 ".section .altinstructions,\"a\"\n"
+			 " .long 1b - .\n"		/* src offset */
+			 " .long 3f - .\n"		/* repl offset */
+			 " .word %P1\n"			/* always replace */
+			 " .byte 2b - 1b\n"		/* src len */
+			 " .byte 4f - 3f\n"		/* repl len */
+			 ".previous\n"
+			 ".section .altinstr_replacement,\"ax\"\n"
+			 "3: .byte 0xe9\n .long %l[t_no] - 2b\n"
+			 "4:\n"
+			 ".previous\n"
+			 ".section .altinstructions,\"a\"\n"
+			 " .long 1b - .\n"		/* src offset */
+			 " .long 0\n"			/* no replacement */
+			 " .word %P0\n"			/* feature bit */
+			 " .byte 2b - 1b\n"		/* src len */
+			 " .byte 0\n"			/* repl len */
+			 ".previous\n"
+			 : : "i" (bit), "i" (X86_FEATURE_ALWAYS)
+			 : : t_dynamic, t_no);
+		return true;
+	t_no:
+		return false;
+	t_dynamic:
+		return __static_cpu_has_safe(bit);
+#else /* GCC_VERSION >= 40500 */
+		u8 flag;
+		/* Open-coded due to __stringify() in ALTERNATIVE() */
+		asm volatile("1: movb $2,%0\n"
+			     "2:\n"
+			     ".section .altinstructions,\"a\"\n"
+			     " .long 1b - .\n"		/* src offset */
+			     " .long 3f - .\n"		/* repl offset */
+			     " .word %P2\n"		/* always replace */
+			     " .byte 2b - 1b\n"		/* source len */
+			     " .byte 4f - 3f\n"		/* replacement len */
+			     ".previous\n"
+			     ".section .discard,\"aw\",@progbits\n"
+			     " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
+			     ".previous\n"
+			     ".section .altinstr_replacement,\"ax\"\n"
+			     "3: movb $0,%0\n"
+			     "4:\n"
+			     ".previous\n"
+			     ".section .altinstructions,\"a\"\n"
+			     " .long 1b - .\n"		/* src offset */
+			     " .long 5f - .\n"		/* repl offset */
+			     " .word %P1\n"		/* feature bit */
+			     " .byte 4b - 3b\n"		/* src len */
+			     " .byte 6f - 5f\n"		/* repl len */
+			     ".previous\n"
+			     ".section .discard,\"aw\",@progbits\n"
+			     " .byte 0xff + (6f-5f) - (4b-3b)\n" /* size check */
+			     ".previous\n"
+			     ".section .altinstr_replacement,\"ax\"\n"
+			     "5: movb $1,%0\n"
+			     "6:\n"
+			     ".previous\n"
+			     : "=qm" (flag)
+			     : "i" (bit), "i" (X86_FEATURE_ALWAYS));
+		return (flag == 2 ? __static_cpu_has_safe(bit) : flag);
+#endif
+}
+
+#define static_cpu_has_safe(bit)				\
+(								\
+	__builtin_constant_p(boot_cpu_has(bit)) ?		\
+		boot_cpu_has(bit) :				\
+		_static_cpu_has_safe(bit)			\
+)
 #else
 /*
  * gcc 3.x is too stupid to do the static test; fall back to dynamic.
  */
-#define static_cpu_has(bit) boot_cpu_has(bit)
+#define static_cpu_has(bit)		boot_cpu_has(bit)
+#define static_cpu_has_safe(bit)	boot_cpu_has(bit)
 #endif
 
 #define cpu_has_bug(c, bit)	cpu_has(c, (bit))
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/cpu.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/cpu.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/cpu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/cpu.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,7 @@ struct x86_cpu {
 #ifdef CONFIG_HOTPLUG_CPU
 extern int arch_register_cpu(int num);
 extern void arch_unregister_cpu(int);
-extern void __cpuinit start_cpu0(void);
+extern void start_cpu0(void);
 #ifdef CONFIG_DEBUG_HOTPLUG_CPU0
 extern int _debug_hotplug_cpu(int cpu, int action);
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/crypto/blowfish.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/crypto/blowfish.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/crypto/blowfish.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/crypto/blowfish.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-#ifndef ASM_X86_BLOWFISH_H
-#define ASM_X86_BLOWFISH_H
-
-#include <linux/crypto.h>
-#include <crypto/blowfish.h>
-
-#define BF_PARALLEL_BLOCKS 4
-
-/* regular block cipher functions */
-asmlinkage void __blowfish_enc_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src,
-				   bool xor);
-asmlinkage void blowfish_dec_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src);
-
-/* 4-way parallel cipher functions */
-asmlinkage void __blowfish_enc_blk_4way(struct bf_ctx *ctx, u8 *dst,
-					const u8 *src, bool xor);
-asmlinkage void blowfish_dec_blk_4way(struct bf_ctx *ctx, u8 *dst,
-				      const u8 *src);
-
-static inline void blowfish_enc_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src)
-{
-	__blowfish_enc_blk(ctx, dst, src, false);
-}
-
-static inline void blowfish_enc_blk_xor(struct bf_ctx *ctx, u8 *dst,
-					const u8 *src)
-{
-	__blowfish_enc_blk(ctx, dst, src, true);
-}
-
-static inline void blowfish_enc_blk_4way(struct bf_ctx *ctx, u8 *dst,
-					 const u8 *src)
-{
-	__blowfish_enc_blk_4way(ctx, dst, src, false);
-}
-
-static inline void blowfish_enc_blk_xor_4way(struct bf_ctx *ctx, u8 *dst,
-				      const u8 *src)
-{
-	__blowfish_enc_blk_4way(ctx, dst, src, true);
-}
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/crypto/twofish.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/crypto/twofish.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/crypto/twofish.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/crypto/twofish.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,20 +28,6 @@ asmlinkage void __twofish_enc_blk_3way(s
 asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst,
 				     const u8 *src);
 
-/* 8-way parallel cipher functions */
-asmlinkage void twofish_ecb_enc_8way(struct twofish_ctx *ctx, u8 *dst,
-				     const u8 *src);
-asmlinkage void twofish_ecb_dec_8way(struct twofish_ctx *ctx, u8 *dst,
-				     const u8 *src);
-asmlinkage void twofish_cbc_dec_8way(struct twofish_ctx *ctx, u8 *dst,
-				     const u8 *src);
-asmlinkage void twofish_ctr_8way(struct twofish_ctx *ctx, u8 *dst,
-				 const u8 *src, le128 *iv);
-asmlinkage void twofish_xts_enc_8way(struct twofish_ctx *ctx, u8 *dst,
-				     const u8 *src, le128 *iv);
-asmlinkage void twofish_xts_dec_8way(struct twofish_ctx *ctx, u8 *dst,
-				     const u8 *src, le128 *iv);
-
 /* helpers from twofish_x86_64-3way module */
 extern void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src);
 extern void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src,
@@ -57,8 +43,4 @@ extern void lrw_twofish_exit_tfm(struct
 extern int xts_twofish_setkey(struct crypto_tfm *tfm, const u8 *key,
 			      unsigned int keylen);
 
-/* helpers from twofish-avx module */
-extern void twofish_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv);
-extern void twofish_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv);
-
 #endif /* ASM_X86_TWOFISH_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/desc.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/desc.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/desc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/desc.h	2013-08-25 20:43:22.000000000 -0400
@@ -36,8 +36,8 @@ static inline void fill_ldt(struct desc_
 
 extern struct desc_ptr idt_descr;
 extern gate_desc idt_table[];
-extern struct desc_ptr nmi_idt_descr;
-extern gate_desc nmi_idt_table[];
+extern struct desc_ptr debug_idt_descr;
+extern gate_desc debug_idt_table[];
 
 struct gdt_page {
 	struct desc_struct gdt[GDT_ENTRIES];
@@ -316,7 +316,20 @@ static inline void set_nmi_gate(int gate
 	gate_desc s;
 
 	pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS);
-	write_idt_entry(nmi_idt_table, gate, &s);
+	write_idt_entry(debug_idt_table, gate, &s);
+}
+#endif
+
+#ifdef CONFIG_TRACING
+extern struct desc_ptr trace_idt_descr;
+extern gate_desc trace_idt_table[];
+static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
+{
+	write_idt_entry(trace_idt_table, entry, gate);
+}
+#else
+static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
+{
 }
 #endif
 
@@ -331,6 +344,7 @@ static inline void _set_gate(int gate, u
 	 * setup time
 	 */
 	write_idt_entry(idt_table, gate, &s);
+	write_trace_idt_entry(gate, &s);
 }
 
 /*
@@ -360,12 +374,39 @@ static inline void alloc_system_vector(i
 	}
 }
 
-static inline void alloc_intr_gate(unsigned int n, void *addr)
+#ifdef CONFIG_TRACING
+static inline void trace_set_intr_gate(unsigned int gate, void *addr)
+{
+	gate_desc s;
+
+	pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS);
+	write_idt_entry(trace_idt_table, gate, &s);
+}
+
+static inline void __trace_alloc_intr_gate(unsigned int n, void *addr)
+{
+	trace_set_intr_gate(n, addr);
+}
+#else
+static inline void trace_set_intr_gate(unsigned int gate, void *addr)
+{
+}
+
+#define __trace_alloc_intr_gate(n, addr)
+#endif
+
+static inline void __alloc_intr_gate(unsigned int n, void *addr)
 {
-	alloc_system_vector(n);
 	set_intr_gate(n, addr);
 }
 
+#define alloc_intr_gate(n, addr)				\
+	do {							\
+		alloc_system_vector(n);				\
+		__alloc_intr_gate(n, addr);			\
+		__trace_alloc_intr_gate(n, trace_##addr);	\
+	} while (0)
+
 /*
  * This routine sets up an interrupt gate at directory privilege level 3.
  */
@@ -405,4 +446,70 @@ static inline void set_system_intr_gate_
 	_set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
 }
 
+#ifdef CONFIG_X86_64
+DECLARE_PER_CPU(u32, debug_idt_ctr);
+static inline bool is_debug_idt_enabled(void)
+{
+	if (this_cpu_read(debug_idt_ctr))
+		return true;
+
+	return false;
+}
+
+static inline void load_debug_idt(void)
+{
+	load_idt((const struct desc_ptr *)&debug_idt_descr);
+}
+#else
+static inline bool is_debug_idt_enabled(void)
+{
+	return false;
+}
+
+static inline void load_debug_idt(void)
+{
+}
+#endif
+
+#ifdef CONFIG_TRACING
+extern atomic_t trace_idt_ctr;
+static inline bool is_trace_idt_enabled(void)
+{
+	if (atomic_read(&trace_idt_ctr))
+		return true;
+
+	return false;
+}
+
+static inline void load_trace_idt(void)
+{
+	load_idt((const struct desc_ptr *)&trace_idt_descr);
+}
+#else
+static inline bool is_trace_idt_enabled(void)
+{
+	return false;
+}
+
+static inline void load_trace_idt(void)
+{
+}
+#endif
+
+/*
+ * The load_current_idt() must be called with interrupts disabled
+ * to avoid races. That way the IDT will always be set back to the expected
+ * descriptor. It's also called when a CPU is being initialized, and
+ * that doesn't need to disable interrupts, as nothing should be
+ * bothering the CPU then.
+ */
+static inline void load_current_idt(void)
+{
+	if (is_debug_idt_enabled())
+		load_debug_idt();
+	else if (is_trace_idt_enabled())
+		load_trace_idt();
+	else
+		load_idt((const struct desc_ptr *)&idt_descr);
+}
 #endif /* _ASM_X86_DESC_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/efi.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/efi.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/efi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/efi.h	2013-08-25 20:43:22.000000000 -0400
@@ -52,40 +52,40 @@ extern u64 efi_call6(void *fp, u64 arg1,
 		     u64 arg4, u64 arg5, u64 arg6);
 
 #define efi_call_phys0(f)			\
-	efi_call0((void *)(f))
+	efi_call0((f))
 #define efi_call_phys1(f, a1)			\
-	efi_call1((void *)(f), (u64)(a1))
+	efi_call1((f), (u64)(a1))
 #define efi_call_phys2(f, a1, a2)			\
-	efi_call2((void *)(f), (u64)(a1), (u64)(a2))
+	efi_call2((f), (u64)(a1), (u64)(a2))
 #define efi_call_phys3(f, a1, a2, a3)				\
-	efi_call3((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3))
+	efi_call3((f), (u64)(a1), (u64)(a2), (u64)(a3))
 #define efi_call_phys4(f, a1, a2, a3, a4)				\
-	efi_call4((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3),		\
+	efi_call4((f), (u64)(a1), (u64)(a2), (u64)(a3),		\
 		  (u64)(a4))
 #define efi_call_phys5(f, a1, a2, a3, a4, a5)				\
-	efi_call5((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3),		\
+	efi_call5((f), (u64)(a1), (u64)(a2), (u64)(a3),		\
 		  (u64)(a4), (u64)(a5))
 #define efi_call_phys6(f, a1, a2, a3, a4, a5, a6)			\
-	efi_call6((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3),		\
+	efi_call6((f), (u64)(a1), (u64)(a2), (u64)(a3),		\
 		  (u64)(a4), (u64)(a5), (u64)(a6))
 
 #define efi_call_virt0(f)				\
-	efi_call0((void *)(efi.systab->runtime->f))
+	efi_call0((efi.systab->runtime->f))
 #define efi_call_virt1(f, a1)					\
-	efi_call1((void *)(efi.systab->runtime->f), (u64)(a1))
+	efi_call1((efi.systab->runtime->f), (u64)(a1))
 #define efi_call_virt2(f, a1, a2)					\
-	efi_call2((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2))
+	efi_call2((efi.systab->runtime->f), (u64)(a1), (u64)(a2))
 #define efi_call_virt3(f, a1, a2, a3)					\
-	efi_call3((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
+	efi_call3((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
 		  (u64)(a3))
 #define efi_call_virt4(f, a1, a2, a3, a4)				\
-	efi_call4((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
+	efi_call4((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
 		  (u64)(a3), (u64)(a4))
 #define efi_call_virt5(f, a1, a2, a3, a4, a5)				\
-	efi_call5((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
+	efi_call5((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
 		  (u64)(a3), (u64)(a4), (u64)(a5))
 #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6)			\
-	efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
+	efi_call6((efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
 		  (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
 
 extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/emergency-restart.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/emergency-restart.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/emergency-restart.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/emergency-restart.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,18 +1,6 @@
 #ifndef _ASM_X86_EMERGENCY_RESTART_H
 #define _ASM_X86_EMERGENCY_RESTART_H
 
-enum reboot_type {
-	BOOT_TRIPLE = 't',
-	BOOT_KBD = 'k',
-	BOOT_BIOS = 'b',
-	BOOT_ACPI = 'a',
-	BOOT_EFI = 'e',
-	BOOT_CF9 = 'p',
-	BOOT_CF9_COND = 'q',
-};
-
-extern enum reboot_type reboot_type;
-
 extern void machine_emergency_restart(void);
 
 #endif /* _ASM_X86_EMERGENCY_RESTART_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/entry_arch.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/entry_arch.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/entry_arch.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/entry_arch.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,14 +13,16 @@
 BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
 BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
 BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
-BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
-BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR)
+BUILD_INTERRUPT3(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR,
+		 smp_irq_move_cleanup_interrupt)
+BUILD_INTERRUPT3(reboot_interrupt, REBOOT_VECTOR, smp_reboot_interrupt)
 #endif
 
 BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)
 
 #ifdef CONFIG_HAVE_KVM
-BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR)
+BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR,
+		 smp_kvm_posted_intr_ipi)
 #endif
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/fixmap.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/fixmap.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/fixmap.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/fixmap.h	2013-08-25 20:43:22.000000000 -0400
@@ -81,11 +81,11 @@ enum fixed_addresses {
 			    + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1,
 	VVAR_PAGE,
 	VSYSCALL_HPET,
-#endif
 #ifdef CONFIG_PARAVIRT_CLOCK
 	PVCLOCK_FIXMAP_BEGIN,
 	PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
 #endif
+#endif
 	FIX_DBGP_BASE,
 	FIX_EARLYCON_MEM_BASE,
 #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/fpu-internal.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/fpu-internal.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/fpu-internal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/fpu-internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -62,10 +62,8 @@ extern user_regset_set_fn fpregs_set, xf
 #define xstateregs_active	fpregs_active
 
 #ifdef CONFIG_MATH_EMULATION
-# define HAVE_HWFP		(boot_cpu_data.hard_math)
 extern void finit_soft_fpu(struct i387_soft_struct *soft);
 #else
-# define HAVE_HWFP		1
 static inline void finit_soft_fpu(struct i387_soft_struct *soft) {}
 #endif
 
@@ -345,7 +343,7 @@ static inline void __thread_fpu_end(stru
 
 static inline void __thread_fpu_begin(struct task_struct *tsk)
 {
-	if (!use_eager_fpu())
+	if (!static_cpu_has_safe(X86_FEATURE_EAGER_FPU))
 		clts();
 	__thread_set_has_fpu(tsk);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/hw_irq.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/hw_irq.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/hw_irq.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/hw_irq.h	2013-08-25 20:43:22.000000000 -0400
@@ -77,6 +77,23 @@ extern void threshold_interrupt(void);
 extern void call_function_interrupt(void);
 extern void call_function_single_interrupt(void);
 
+#ifdef CONFIG_TRACING
+/* Interrupt handlers registered during init_IRQ */
+extern void trace_apic_timer_interrupt(void);
+extern void trace_x86_platform_ipi(void);
+extern void trace_error_interrupt(void);
+extern void trace_irq_work_interrupt(void);
+extern void trace_spurious_interrupt(void);
+extern void trace_thermal_interrupt(void);
+extern void trace_reschedule_interrupt(void);
+extern void trace_threshold_interrupt(void);
+extern void trace_call_function_interrupt(void);
+extern void trace_call_function_single_interrupt(void);
+#define trace_irq_move_cleanup_interrupt  irq_move_cleanup_interrupt
+#define trace_reboot_interrupt  reboot_interrupt
+#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
+#endif /* CONFIG_TRACING */
+
 /* IOAPIC */
 #define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
 extern unsigned long io_apic_irqs;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/io.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/io.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/io.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/io.h	2013-08-25 20:43:22.000000000 -0400
@@ -345,4 +345,11 @@ extern bool xen_biovec_phys_mergeable(co
 
 #define IO_SPACE_LIMIT 0xffff
 
+#ifdef CONFIG_MTRR
+extern int __must_check arch_phys_wc_add(unsigned long base,
+					 unsigned long size);
+extern void arch_phys_wc_del(int handle);
+#define arch_phys_wc_add arch_phys_wc_add
+#endif
+
 #endif /* _ASM_X86_IO_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/kvm_host.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/kvm_host.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/kvm_host.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/kvm_host.h	2013-08-25 20:43:22.000000000 -0400
@@ -59,7 +59,7 @@
 	(~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\
 			  | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE     \
 			  | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \
-			  | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_RDWRGSFS \
+			  | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \
 			  | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE))
 
 #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
@@ -222,14 +222,22 @@ struct kvm_mmu_page {
 	int root_count;          /* Currently serving as active root */
 	unsigned int unsync_children;
 	unsigned long parent_ptes;	/* Reverse mapping for parent_pte */
+
+	/* The page is obsolete if mmu_valid_gen != kvm->arch.mmu_valid_gen.  */
+	unsigned long mmu_valid_gen;
+
 	DECLARE_BITMAP(unsync_child_bitmap, 512);
 
 #ifdef CONFIG_X86_32
+	/*
+	 * Used out of the mmu-lock to avoid reading spte values while an
+	 * update is in progress; see the comments in __get_spte_lockless().
+	 */
 	int clear_spte_count;
 #endif
 
+	/* Number of writes since the last time traversal visited this page.  */
 	int write_flooding_count;
-	bool mmio_cached;
 };
 
 struct kvm_pio_request {
@@ -529,11 +537,14 @@ struct kvm_arch {
 	unsigned int n_requested_mmu_pages;
 	unsigned int n_max_mmu_pages;
 	unsigned int indirect_shadow_pages;
+	unsigned long mmu_valid_gen;
 	struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
 	/*
 	 * Hash table of struct kvm_mmu_page.
 	 */
 	struct list_head active_mmu_pages;
+	struct list_head zapped_obsolete_pages;
+
 	struct list_head assigned_dev_head;
 	struct iommu_domain *iommu_domain;
 	int iommu_flags;
@@ -769,7 +780,7 @@ void kvm_mmu_write_protect_pt_masked(str
 				     struct kvm_memory_slot *slot,
 				     gfn_t gfn_offset, unsigned long mask);
 void kvm_mmu_zap_all(struct kvm *kvm);
-void kvm_mmu_zap_mmio_sptes(struct kvm *kvm);
+void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm);
 unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm);
 void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/mc146818rtc.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mc146818rtc.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/mc146818rtc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mc146818rtc.h	2013-08-25 20:43:22.000000000 -0400
@@ -95,8 +95,8 @@ static inline unsigned char current_lock
 unsigned char rtc_cmos_read(unsigned char addr);
 void rtc_cmos_write(unsigned char val, unsigned char addr);
 
-extern int mach_set_rtc_mmss(unsigned long nowtime);
-extern unsigned long mach_get_cmos_time(void);
+extern int mach_set_rtc_mmss(const struct timespec *now);
+extern void mach_get_cmos_time(struct timespec *now);
 
 #define RTC_IRQ 8
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/mce.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mce.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/mce.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mce.h	2013-08-25 20:43:22.000000000 -0400
@@ -61,7 +61,7 @@
 #define MCJ_CTX_IRQ		0x2  /* inject context: IRQ */
 #define MCJ_NMI_BROADCAST	0x4  /* do NMI broadcasting */
 #define MCJ_EXCEPTION		0x8  /* raise as exception */
-#define MCJ_IRQ_BRAODCAST	0x10 /* do IRQ broadcasting */
+#define MCJ_IRQ_BROADCAST	0x10 /* do IRQ broadcasting */
 
 #define MCE_OVERFLOW 0		/* bit 0 in flags means overflow */
 
@@ -214,6 +214,13 @@ void mce_log_therm_throt_event(__u64 sta
 /* Interrupt Handler for core thermal thresholds */
 extern int (*platform_thermal_notify)(__u64 msr_val);
 
+/* Interrupt Handler for package thermal thresholds */
+extern int (*platform_thermal_package_notify)(__u64 msr_val);
+
+/* Callback support of rate control, return true, if
+ * callback has rate control */
+extern bool (*platform_thermal_package_rate_control)(void);
+
 #ifdef CONFIG_X86_THERMAL_VECTOR
 extern void mcheck_intel_therm_init(void);
 #else
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/microcode_amd.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/microcode_amd.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/microcode_amd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/microcode_amd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,78 @@
+#ifndef _ASM_X86_MICROCODE_AMD_H
+#define _ASM_X86_MICROCODE_AMD_H
+
+#include <asm/microcode.h>
+
+#define UCODE_MAGIC			0x00414d44
+#define UCODE_EQUIV_CPU_TABLE_TYPE	0x00000000
+#define UCODE_UCODE_TYPE		0x00000001
+
+#define SECTION_HDR_SIZE		8
+#define CONTAINER_HDR_SZ		12
+
+struct equiv_cpu_entry {
+	u32	installed_cpu;
+	u32	fixed_errata_mask;
+	u32	fixed_errata_compare;
+	u16	equiv_cpu;
+	u16	res;
+} __attribute__((packed));
+
+struct microcode_header_amd {
+	u32	data_code;
+	u32	patch_id;
+	u16	mc_patch_data_id;
+	u8	mc_patch_data_len;
+	u8	init_flag;
+	u32	mc_patch_data_checksum;
+	u32	nb_dev_id;
+	u32	sb_dev_id;
+	u16	processor_rev_id;
+	u8	nb_rev_id;
+	u8	sb_rev_id;
+	u8	bios_api_rev;
+	u8	reserved1[3];
+	u32	match_reg[8];
+} __attribute__((packed));
+
+struct microcode_amd {
+	struct microcode_header_amd	hdr;
+	unsigned int			mpb[0];
+};
+
+static inline u16 find_equiv_id(struct equiv_cpu_entry *equiv_cpu_table,
+				unsigned int sig)
+{
+	int i = 0;
+
+	if (!equiv_cpu_table)
+		return 0;
+
+	while (equiv_cpu_table[i].installed_cpu != 0) {
+		if (sig == equiv_cpu_table[i].installed_cpu)
+			return equiv_cpu_table[i].equiv_cpu;
+
+		i++;
+	}
+	return 0;
+}
+
+extern int __apply_microcode_amd(struct microcode_amd *mc_amd);
+extern int apply_microcode_amd(int cpu);
+extern enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size);
+
+#ifdef CONFIG_MICROCODE_AMD_EARLY
+#ifdef CONFIG_X86_32
+#define MPB_MAX_SIZE PAGE_SIZE
+extern u8 amd_bsp_mpb[MPB_MAX_SIZE];
+#endif
+extern void __init load_ucode_amd_bsp(void);
+extern void load_ucode_amd_ap(void);
+extern int __init save_microcode_in_initrd_amd(void);
+#else
+static inline void __init load_ucode_amd_bsp(void) {}
+static inline void load_ucode_amd_ap(void) {}
+static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
+#endif
+
+#endif /* _ASM_X86_MICROCODE_AMD_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/microcode.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/microcode.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/microcode.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/microcode.h	2013-08-25 20:43:22.000000000 -0400
@@ -60,11 +60,11 @@ static inline void __exit exit_amd_micro
 #ifdef CONFIG_MICROCODE_EARLY
 #define MAX_UCODE_COUNT 128
 extern void __init load_ucode_bsp(void);
-extern void __cpuinit load_ucode_ap(void);
+extern void load_ucode_ap(void);
 extern int __init save_microcode_in_initrd(void);
 #else
 static inline void __init load_ucode_bsp(void) {}
-static inline void __cpuinit load_ucode_ap(void) {}
+static inline void load_ucode_ap(void) {}
 static inline int __init save_microcode_in_initrd(void)
 {
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/microcode_intel.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/microcode_intel.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/microcode_intel.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/microcode_intel.h	2013-08-25 20:43:22.000000000 -0400
@@ -65,12 +65,14 @@ update_match_revision(struct microcode_h
 
 #ifdef CONFIG_MICROCODE_INTEL_EARLY
 extern void __init load_ucode_intel_bsp(void);
-extern void __cpuinit load_ucode_intel_ap(void);
+extern void load_ucode_intel_ap(void);
 extern void show_ucode_info_early(void);
+extern int __init save_microcode_in_initrd_intel(void);
 #else
 static inline __init void load_ucode_intel_bsp(void) {}
-static inline __cpuinit void load_ucode_intel_ap(void) {}
+static inline void load_ucode_intel_ap(void) {}
 static inline void show_ucode_info_early(void) {}
+static inline int __init save_microcode_in_initrd_intel(void) { return -EINVAL; }
 #endif
 
 #if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/mmconfig.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mmconfig.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/mmconfig.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mmconfig.h	2013-08-25 20:43:22.000000000 -0400
@@ -2,8 +2,8 @@
 #define _ASM_X86_MMCONFIG_H
 
 #ifdef CONFIG_PCI_MMCONFIG
-extern void __cpuinit fam10h_check_enable_mmcfg(void);
-extern void __cpuinit check_enable_amd_mmconf_dmi(void);
+extern void fam10h_check_enable_mmcfg(void);
+extern void check_enable_amd_mmconf_dmi(void);
 #else
 static inline void fam10h_check_enable_mmcfg(void) { }
 static inline void check_enable_amd_mmconf_dmi(void) { }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/mpspec.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mpspec.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/mpspec.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mpspec.h	2013-08-25 20:43:22.000000000 -0400
@@ -94,7 +94,7 @@ static inline void early_reserve_e820_mp
 #define default_get_smp_config x86_init_uint_noop
 #endif
 
-void __cpuinit generic_processor_info(int apicid, int version);
+void generic_processor_info(int apicid, int version);
 #ifdef CONFIG_ACPI
 extern void mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/mrst-vrtc.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mrst-vrtc.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/mrst-vrtc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mrst-vrtc.h	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
 
 extern unsigned char vrtc_cmos_read(unsigned char reg);
 extern void vrtc_cmos_write(unsigned char val, unsigned char reg);
-extern unsigned long vrtc_get_time(void);
-extern int vrtc_set_mmss(unsigned long nowtime);
+extern void vrtc_get_time(struct timespec *now);
+extern int vrtc_set_mmss(const struct timespec *now);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/mshyperv.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mshyperv.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/mshyperv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mshyperv.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,9 @@ struct ms_hyperv_info {
 extern struct ms_hyperv_info ms_hyperv;
 
 void hyperv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_hyperv_callback_vector hyperv_callback_vector
+#endif
 void hyperv_vector_handler(struct pt_regs *regs);
 void hv_register_vmbus_handler(int irq, irq_handler_t handler);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/mtrr.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mtrr.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/mtrr.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mtrr.h	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,10 @@
 #include <uapi/asm/mtrr.h>
 
 
-/*  The following functions are for use by other drivers  */
+/*
+ * The following functions are for use by other drivers that cannot use
+ * arch_phys_wc_add and arch_phys_wc_del.
+ */
 # ifdef CONFIG_MTRR
 extern u8 mtrr_type_lookup(u64 addr, u64 end);
 extern void mtrr_save_fixed_ranges(void *);
@@ -45,6 +48,7 @@ extern void mtrr_aps_init(void);
 extern void mtrr_bp_restore(void);
 extern int mtrr_trim_uncached_memory(unsigned long end_pfn);
 extern int amd_special_default_mtrr(void);
+extern int phys_wc_to_mtrr_index(int handle);
 #  else
 static inline u8 mtrr_type_lookup(u64 addr, u64 end)
 {
@@ -80,6 +84,10 @@ static inline int mtrr_trim_uncached_mem
 static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
 {
 }
+static inline int phys_wc_to_mtrr_index(int handle)
+{
+	return -1;
+}
 
 #define mtrr_ap_init() do {} while (0)
 #define mtrr_bp_init() do {} while (0)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/mutex_32.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mutex_32.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/mutex_32.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mutex_32.h	2013-08-25 20:43:22.000000000 -0400
@@ -42,17 +42,14 @@ do {								\
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if it
- * wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
-static inline int __mutex_fastpath_lock_retval(atomic_t *count,
-					       int (*fail_fn)(atomic_t *))
+static inline int __mutex_fastpath_lock_retval(atomic_t *count)
 {
 	if (unlikely(atomic_dec_return(count) < 0))
-		return fail_fn(count);
+		return -1;
 	else
 		return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/mutex_64.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mutex_64.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/mutex_64.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/mutex_64.h	2013-08-25 20:43:22.000000000 -0400
@@ -37,17 +37,14 @@ do {								\
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
-static inline int __mutex_fastpath_lock_retval(atomic_t *count,
-					       int (*fail_fn)(atomic_t *))
+static inline int __mutex_fastpath_lock_retval(atomic_t *count)
 {
 	if (unlikely(atomic_dec_return(count) < 0))
-		return fail_fn(count);
+		return -1;
 	else
 		return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/numa.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/numa.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/numa.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/numa.h	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,7 @@ static inline void set_apicid_to_node(in
 	__apicid_to_node[apicid] = node;
 }
 
-extern int __cpuinit numa_cpu_node(int cpu);
+extern int numa_cpu_node(int cpu);
 
 #else	/* CONFIG_NUMA */
 static inline void set_apicid_to_node(int apicid, s16 node)
@@ -60,8 +60,8 @@ static inline int numa_cpu_node(int cpu)
 extern void numa_set_node(int cpu, int node);
 extern void numa_clear_node(int cpu);
 extern void __init init_cpu_to_node(void);
-extern void __cpuinit numa_add_cpu(int cpu);
-extern void __cpuinit numa_remove_cpu(int cpu);
+extern void numa_add_cpu(int cpu);
+extern void numa_remove_cpu(int cpu);
 #else	/* CONFIG_NUMA */
 static inline void numa_set_node(int cpu, int node)	{ }
 static inline void numa_clear_node(int cpu)		{ }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/perf_event.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/perf_event.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/perf_event.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/perf_event.h	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,9 @@
 #define ARCH_PERFMON_EVENTSEL_INV			(1ULL << 23)
 #define ARCH_PERFMON_EVENTSEL_CMASK			0xFF000000ULL
 
+#define HSW_IN_TX					(1ULL << 32)
+#define HSW_IN_TX_CHECKPOINTED				(1ULL << 33)
+
 #define AMD64_EVENTSEL_INT_CORE_ENABLE			(1ULL << 36)
 #define AMD64_EVENTSEL_GUESTONLY			(1ULL << 40)
 #define AMD64_EVENTSEL_HOSTONLY				(1ULL << 41)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/pgtable-2level.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/pgtable-2level.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/pgtable-2level.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/pgtable-2level.h	2013-08-25 20:43:22.000000000 -0400
@@ -55,9 +55,53 @@ static inline pmd_t native_pmdp_get_and_
 #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp)
 #endif
 
+#ifdef CONFIG_MEM_SOFT_DIRTY
+
+/*
+ * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE, _PAGE_BIT_SOFT_DIRTY and
+ * _PAGE_BIT_PROTNONE are taken, split up the 28 bits of offset
+ * into this range.
+ */
+#define PTE_FILE_MAX_BITS	28
+#define PTE_FILE_SHIFT1		(_PAGE_BIT_PRESENT + 1)
+#define PTE_FILE_SHIFT2		(_PAGE_BIT_FILE + 1)
+#define PTE_FILE_SHIFT3		(_PAGE_BIT_PROTNONE + 1)
+#define PTE_FILE_SHIFT4		(_PAGE_BIT_SOFT_DIRTY + 1)
+#define PTE_FILE_BITS1		(PTE_FILE_SHIFT2 - PTE_FILE_SHIFT1 - 1)
+#define PTE_FILE_BITS2		(PTE_FILE_SHIFT3 - PTE_FILE_SHIFT2 - 1)
+#define PTE_FILE_BITS3		(PTE_FILE_SHIFT4 - PTE_FILE_SHIFT3 - 1)
+
+#define pte_to_pgoff(pte)						\
+	((((pte).pte_low >> (PTE_FILE_SHIFT1))				\
+	  & ((1U << PTE_FILE_BITS1) - 1)))				\
+	+ ((((pte).pte_low >> (PTE_FILE_SHIFT2))			\
+	    & ((1U << PTE_FILE_BITS2) - 1))				\
+	   << (PTE_FILE_BITS1))						\
+	+ ((((pte).pte_low >> (PTE_FILE_SHIFT3))			\
+	    & ((1U << PTE_FILE_BITS3) - 1))				\
+	   << (PTE_FILE_BITS1 + PTE_FILE_BITS2))			\
+	+ ((((pte).pte_low >> (PTE_FILE_SHIFT4)))			\
+	    << (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3))
+
+#define pgoff_to_pte(off)						\
+	((pte_t) { .pte_low =						\
+	 ((((off)) & ((1U << PTE_FILE_BITS1) - 1)) << PTE_FILE_SHIFT1)	\
+	 + ((((off) >> PTE_FILE_BITS1)					\
+	     & ((1U << PTE_FILE_BITS2) - 1))				\
+	    << PTE_FILE_SHIFT2)						\
+	 + ((((off) >> (PTE_FILE_BITS1 + PTE_FILE_BITS2))		\
+	     & ((1U << PTE_FILE_BITS3) - 1))				\
+	    << PTE_FILE_SHIFT3)						\
+	 + ((((off) >>							\
+	      (PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)))	\
+	    << PTE_FILE_SHIFT4)						\
+	 + _PAGE_FILE })
+
+#else /* CONFIG_MEM_SOFT_DIRTY */
+
 /*
  * Bits _PAGE_BIT_PRESENT, _PAGE_BIT_FILE and _PAGE_BIT_PROTNONE are taken,
- * split up the 29 bits of offset into this range:
+ * split up the 29 bits of offset into this range.
  */
 #define PTE_FILE_MAX_BITS	29
 #define PTE_FILE_SHIFT1		(_PAGE_BIT_PRESENT + 1)
@@ -88,6 +132,8 @@ static inline pmd_t native_pmdp_get_and_
 	    << PTE_FILE_SHIFT3)						\
 	 + _PAGE_FILE })
 
+#endif /* CONFIG_MEM_SOFT_DIRTY */
+
 /* Encode and de-code a swap entry */
 #if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE
 #define SWP_TYPE_BITS (_PAGE_BIT_FILE - _PAGE_BIT_PRESENT - 1)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/pgtable-3level.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/pgtable-3level.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/pgtable-3level.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/pgtable-3level.h	2013-08-25 20:43:22.000000000 -0400
@@ -179,6 +179,9 @@ static inline pmd_t native_pmdp_get_and_
 /*
  * Bits 0, 6 and 7 are taken in the low part of the pte,
  * put the 32 bits of offset into the high part.
+ *
+ * For soft-dirty tracking 11 bit is taken from
+ * the low part of pte as well.
  */
 #define pte_to_pgoff(pte) ((pte).pte_high)
 #define pgoff_to_pte(off)						\
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -207,7 +207,7 @@ static inline pte_t pte_mkexec(pte_t pte
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
-	return pte_set_flags(pte, _PAGE_DIRTY);
+	return pte_set_flags(pte, _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
 }
 
 static inline pte_t pte_mkyoung(pte_t pte)
@@ -271,7 +271,7 @@ static inline pmd_t pmd_wrprotect(pmd_t
 
 static inline pmd_t pmd_mkdirty(pmd_t pmd)
 {
-	return pmd_set_flags(pmd, _PAGE_DIRTY);
+	return pmd_set_flags(pmd, _PAGE_DIRTY | _PAGE_SOFT_DIRTY);
 }
 
 static inline pmd_t pmd_mkhuge(pmd_t pmd)
@@ -294,6 +294,56 @@ static inline pmd_t pmd_mknotpresent(pmd
 	return pmd_clear_flags(pmd, _PAGE_PRESENT);
 }
 
+static inline int pte_soft_dirty(pte_t pte)
+{
+	return pte_flags(pte) & _PAGE_SOFT_DIRTY;
+}
+
+static inline int pmd_soft_dirty(pmd_t pmd)
+{
+	return pmd_flags(pmd) & _PAGE_SOFT_DIRTY;
+}
+
+static inline pte_t pte_mksoft_dirty(pte_t pte)
+{
+	return pte_set_flags(pte, _PAGE_SOFT_DIRTY);
+}
+
+static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
+{
+	return pmd_set_flags(pmd, _PAGE_SOFT_DIRTY);
+}
+
+static inline pte_t pte_swp_mksoft_dirty(pte_t pte)
+{
+	return pte_set_flags(pte, _PAGE_SWP_SOFT_DIRTY);
+}
+
+static inline int pte_swp_soft_dirty(pte_t pte)
+{
+	return pte_flags(pte) & _PAGE_SWP_SOFT_DIRTY;
+}
+
+static inline pte_t pte_swp_clear_soft_dirty(pte_t pte)
+{
+	return pte_clear_flags(pte, _PAGE_SWP_SOFT_DIRTY);
+}
+
+static inline pte_t pte_file_clear_soft_dirty(pte_t pte)
+{
+	return pte_clear_flags(pte, _PAGE_SOFT_DIRTY);
+}
+
+static inline pte_t pte_file_mksoft_dirty(pte_t pte)
+{
+	return pte_set_flags(pte, _PAGE_SOFT_DIRTY);
+}
+
+static inline int pte_file_soft_dirty(pte_t pte)
+{
+	return pte_flags(pte) & _PAGE_SOFT_DIRTY;
+}
+
 /*
  * Mask out unsupported bits in a present pgprot.  Non-present pgprots
  * can use those bits for other purposes, so leave them be.
@@ -506,9 +556,6 @@ static inline unsigned long pages_to_mb(
 	return npg >> (20 - PAGE_SHIFT);
 }
 
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)	\
-	remap_pfn_range(vma, vaddr, pfn, size, prot)
-
 #if PAGETABLE_LEVELS > 2
 static inline int pud_none(pud_t pud)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/pgtable_types.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/pgtable_types.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/pgtable_types.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/pgtable_types.h	2013-08-25 20:43:22.000000000 -0400
@@ -55,6 +55,33 @@
 #define _PAGE_HIDDEN	(_AT(pteval_t, 0))
 #endif
 
+/*
+ * The same hidden bit is used by kmemcheck, but since kmemcheck
+ * works on kernel pages while soft-dirty engine on user space,
+ * they do not conflict with each other.
+ */
+
+#define _PAGE_BIT_SOFT_DIRTY	_PAGE_BIT_HIDDEN
+
+#ifdef CONFIG_MEM_SOFT_DIRTY
+#define _PAGE_SOFT_DIRTY	(_AT(pteval_t, 1) << _PAGE_BIT_SOFT_DIRTY)
+#else
+#define _PAGE_SOFT_DIRTY	(_AT(pteval_t, 0))
+#endif
+
+/*
+ * Tracking soft dirty bit when a page goes to a swap is tricky.
+ * We need a bit which can be stored in pte _and_ not conflict
+ * with swap entry format. On x86 bits 6 and 7 are *not* involved
+ * into swap entry computation, but bit 6 is used for nonlinear
+ * file mapping, so we borrow bit 7 for soft dirty tracking.
+ */
+#ifdef CONFIG_MEM_SOFT_DIRTY
+#define _PAGE_SWP_SOFT_DIRTY	_PAGE_PSE
+#else
+#define _PAGE_SWP_SOFT_DIRTY	(_AT(pteval_t, 0))
+#endif
+
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
 #define _PAGE_NX	(_AT(pteval_t, 1) << _PAGE_BIT_NX)
 #else
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/processor.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/processor.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/processor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/processor.h	2013-08-25 20:43:22.000000000 -0400
@@ -89,9 +89,9 @@ struct cpuinfo_x86 {
 	char			wp_works_ok;	/* It doesn't on 386's */
 
 	/* Problems on some 486Dx4's and old 386's: */
-	char			hard_math;
 	char			rfu;
 	char			pad0;
+	char			pad1;
 #else
 	/* Number of 4K pages in DTLB/ITLB combined(in pages): */
 	int			x86_tlbsize;
@@ -164,6 +164,7 @@ extern const struct seq_operations cpuin
 #define cache_line_size()	(boot_cpu_data.x86_cache_alignment)
 
 extern void cpu_detect(struct cpuinfo_x86 *c);
+extern void fpu_detect(struct cpuinfo_x86 *c);
 
 extern void early_cpu_init(void);
 extern void identify_boot_cpu(void);
@@ -981,5 +982,5 @@ bool xen_set_default_idle(void);
 #endif
 
 void stop_this_cpu(void *dummy);
-
+void df_debug(struct pt_regs *regs, long error_code);
 #endif /* _ASM_X86_PROCESSOR_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/prom.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/prom.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/prom.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/prom.h	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@ extern int of_ioapic;
 extern u64 initial_dtb;
 extern void add_dtb(u64 data);
 extern void x86_add_irq_domains(void);
-void __cpuinit x86_of_pci_init(void);
+void x86_of_pci_init(void);
 void x86_dtb_init(void);
 #else
 static inline void add_dtb(u64 data) { }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/sighandling.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/sighandling.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/sighandling.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/sighandling.h	2013-08-25 20:43:22.000000000 -0400
@@ -7,10 +7,10 @@
 
 #include <asm/processor-flags.h>
 
-#define __FIX_EFLAGS	(X86_EFLAGS_AC | X86_EFLAGS_OF | \
+#define FIX_EFLAGS	(X86_EFLAGS_AC | X86_EFLAGS_OF | \
 			 X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
 			 X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
-			 X86_EFLAGS_CF)
+			 X86_EFLAGS_CF | X86_EFLAGS_RF)
 
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/smp.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/smp.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/smp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/smp.h	2013-08-25 20:43:22.000000000 -0400
@@ -179,7 +179,7 @@ static inline int wbinvd_on_all_cpus(voi
 }
 #endif /* CONFIG_SMP */
 
-extern unsigned disabled_cpus __cpuinitdata;
+extern unsigned disabled_cpus;
 
 #ifdef CONFIG_X86_32_SMP
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/special_insns.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/special_insns.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/special_insns.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/special_insns.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,7 @@ static inline void native_clts(void)
  * all loads stores around it, which can hurt performance. Solution is to
  * use a variable and mimic reads and writes to it to enforce serialization
  */
-static unsigned long __force_order;
+extern unsigned long __force_order;
 
 static inline unsigned long native_read_cr0(void)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/spinlock.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/spinlock.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/spinlock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/spinlock.h	2013-08-25 20:43:22.000000000 -0400
@@ -233,8 +233,4 @@ static inline void arch_write_unlock(arc
 #define arch_read_relax(lock)	cpu_relax()
 #define arch_write_relax(lock)	cpu_relax()
 
-/* The {read|write|spin}_lock() on x86 are full memory barriers. */
-static inline void smp_mb__after_lock(void) { }
-#define ARCH_HAS_SMP_MB_AFTER_LOCK
-
 #endif /* _ASM_X86_SPINLOCK_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/thread_info.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/thread_info.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/thread_info.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/thread_info.h	2013-08-25 20:43:22.000000000 -0400
@@ -89,7 +89,6 @@ struct thread_info {
 #define TIF_FORK		18	/* ret_from_fork */
 #define TIF_NOHZ		19	/* in adaptive nohz mode */
 #define TIF_MEMDIE		20	/* is terminating due to OOM killer */
-#define TIF_DEBUG		21	/* uses debug registers */
 #define TIF_IO_BITMAP		22	/* uses I/O bitmap */
 #define TIF_FORCED_TF		24	/* true if TF in eflags artificially */
 #define TIF_BLOCKSTEP		25	/* set when we want DEBUGCTLMSR_BTF */
@@ -113,7 +112,6 @@ struct thread_info {
 #define _TIF_IA32		(1 << TIF_IA32)
 #define _TIF_FORK		(1 << TIF_FORK)
 #define _TIF_NOHZ		(1 << TIF_NOHZ)
-#define _TIF_DEBUG		(1 << TIF_DEBUG)
 #define _TIF_IO_BITMAP		(1 << TIF_IO_BITMAP)
 #define _TIF_FORCED_TF		(1 << TIF_FORCED_TF)
 #define _TIF_BLOCKSTEP		(1 << TIF_BLOCKSTEP)
@@ -154,7 +152,7 @@ struct thread_info {
 	(_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP)
 
 #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY)
-#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG)
+#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW)
 
 #define PREEMPT_ACTIVE		0x10000000
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/tlbflush.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/tlbflush.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/tlbflush.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/tlbflush.h	2013-08-25 20:43:22.000000000 -0400
@@ -62,7 +62,7 @@ static inline void __flush_tlb_all(void)
 
 static inline void __flush_tlb_one(unsigned long addr)
 {
-		__flush_tlb_single(addr);
+	__flush_tlb_single(addr);
 }
 
 #define TLB_FLUSH_ALL	-1UL
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/trace/irq_vectors.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/trace/irq_vectors.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/trace/irq_vectors.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/trace/irq_vectors.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,104 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM irq_vectors
+
+#if !defined(_TRACE_IRQ_VECTORS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_IRQ_VECTORS_H
+
+#include <linux/tracepoint.h>
+
+extern void trace_irq_vector_regfunc(void);
+extern void trace_irq_vector_unregfunc(void);
+
+DECLARE_EVENT_CLASS(x86_irq_vector,
+
+	TP_PROTO(int vector),
+
+	TP_ARGS(vector),
+
+	TP_STRUCT__entry(
+		__field(		int,	vector	)
+	),
+
+	TP_fast_assign(
+		__entry->vector = vector;
+	),
+
+	TP_printk("vector=%d", __entry->vector) );
+
+#define DEFINE_IRQ_VECTOR_EVENT(name)		\
+DEFINE_EVENT_FN(x86_irq_vector, name##_entry,	\
+	TP_PROTO(int vector),			\
+	TP_ARGS(vector),			\
+	trace_irq_vector_regfunc,		\
+	trace_irq_vector_unregfunc);		\
+DEFINE_EVENT_FN(x86_irq_vector, name##_exit,	\
+	TP_PROTO(int vector),			\
+	TP_ARGS(vector),			\
+	trace_irq_vector_regfunc,		\
+	trace_irq_vector_unregfunc);
+
+
+/*
+ * local_timer - called when entering/exiting a local timer interrupt
+ * vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(local_timer);
+
+/*
+ * reschedule - called when entering/exiting a reschedule vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(reschedule);
+
+/*
+ * spurious_apic - called when entering/exiting a spurious apic vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(spurious_apic);
+
+/*
+ * error_apic - called when entering/exiting an error apic vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(error_apic);
+
+/*
+ * x86_platform_ipi - called when entering/exiting a x86 platform ipi interrupt
+ * vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi);
+
+/*
+ * irq_work - called when entering/exiting a irq work interrupt
+ * vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(irq_work);
+
+/*
+ * call_function - called when entering/exiting a call function interrupt
+ * vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(call_function);
+
+/*
+ * call_function_single - called when entering/exiting a call function
+ * single interrupt vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(call_function_single);
+
+/*
+ * threshold_apic - called when entering/exiting a threshold apic interrupt
+ * vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(threshold_apic);
+
+/*
+ * thermal_apic - called when entering/exiting a thermal apic interrupt
+ * vector handler
+ */
+DEFINE_IRQ_VECTOR_EVENT(thermal_apic);
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE irq_vectors
+#endif /*  _TRACE_IRQ_VECTORS_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/uaccess_64.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/uaccess_64.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/uaccess_64.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/uaccess_64.h	2013-08-25 20:43:22.000000000 -0400
@@ -235,7 +235,7 @@ extern long __copy_user_nocache(void *ds
 static inline int
 __copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
 {
-	might_sleep();
+	might_fault();
 	return __copy_user_nocache(dst, src, size, 1);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/uv/uv_bau.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/uv/uv_bau.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/uv/uv_bau.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/uv/uv_bau.h	2013-08-25 20:43:22.000000000 -0400
@@ -731,6 +731,9 @@ static inline void bau_cpubits_clear(str
 }
 
 extern void uv_bau_message_intr1(void);
+#ifdef CONFIG_TRACING
+#define trace_uv_bau_message_intr1 uv_bau_message_intr1
+#endif
 extern void uv_bau_timeout_intr1(void);
 
 struct atomic_short {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/asm/x86_init.h linux-libre-3.11-rc7-gnu/arch/x86/include/asm/x86_init.h
--- linux-libre-3.10-gnu/arch/x86/include/asm/x86_init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/asm/x86_init.h	2013-08-25 20:43:22.000000000 -0400
@@ -142,6 +142,8 @@ struct x86_cpuinit_ops {
 	void (*fixup_cpu_id)(struct cpuinfo_x86 *c, int node);
 };
 
+struct timespec;
+
 /**
  * struct x86_platform_ops - platform specific runtime functions
  * @calibrate_tsc:		calibrate TSC
@@ -156,8 +158,8 @@ struct x86_cpuinit_ops {
  */
 struct x86_platform_ops {
 	unsigned long (*calibrate_tsc)(void);
-	unsigned long (*get_wallclock)(void);
-	int (*set_wallclock)(unsigned long nowtime);
+	void (*get_wallclock)(struct timespec *ts);
+	int (*set_wallclock)(const struct timespec *ts);
 	void (*iommu_shutdown)(void);
 	bool (*is_untracked_pat_range)(u64 start, u64 end);
 	void (*nmi_init)(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/uapi/asm/msr-index.h linux-libre-3.11-rc7-gnu/arch/x86/include/uapi/asm/msr-index.h
--- linux-libre-3.10-gnu/arch/x86/include/uapi/asm/msr-index.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/uapi/asm/msr-index.h	2013-08-25 20:43:22.000000000 -0400
@@ -170,6 +170,9 @@
 #define MSR_KNC_EVNTSEL0               0x00000028
 #define MSR_KNC_EVNTSEL1               0x00000029
 
+/* Alternative perfctr range with full access. */
+#define MSR_IA32_PMC0			0x000004c1
+
 /* AMD64 MSRs. Not complete. See the architecture manual for a more
    complete list. */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/include/uapi/asm/processor-flags.h linux-libre-3.11-rc7-gnu/arch/x86/include/uapi/asm/processor-flags.h
--- linux-libre-3.10-gnu/arch/x86/include/uapi/asm/processor-flags.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/include/uapi/asm/processor-flags.h	2013-08-25 20:43:22.000000000 -0400
@@ -2,75 +2,129 @@
 #define _UAPI_ASM_X86_PROCESSOR_FLAGS_H
 /* Various flags defined: can be included from assembler. */
 
+#include <linux/const.h>
+
 /*
  * EFLAGS bits
  */
-#define X86_EFLAGS_CF	0x00000001 /* Carry Flag */
-#define X86_EFLAGS_BIT1	0x00000002 /* Bit 1 - always on */
-#define X86_EFLAGS_PF	0x00000004 /* Parity Flag */
-#define X86_EFLAGS_AF	0x00000010 /* Auxiliary carry Flag */
-#define X86_EFLAGS_ZF	0x00000040 /* Zero Flag */
-#define X86_EFLAGS_SF	0x00000080 /* Sign Flag */
-#define X86_EFLAGS_TF	0x00000100 /* Trap Flag */
-#define X86_EFLAGS_IF	0x00000200 /* Interrupt Flag */
-#define X86_EFLAGS_DF	0x00000400 /* Direction Flag */
-#define X86_EFLAGS_OF	0x00000800 /* Overflow Flag */
-#define X86_EFLAGS_IOPL	0x00003000 /* IOPL mask */
-#define X86_EFLAGS_NT	0x00004000 /* Nested Task */
-#define X86_EFLAGS_RF	0x00010000 /* Resume Flag */
-#define X86_EFLAGS_VM	0x00020000 /* Virtual Mode */
-#define X86_EFLAGS_AC	0x00040000 /* Alignment Check */
-#define X86_EFLAGS_VIF	0x00080000 /* Virtual Interrupt Flag */
-#define X86_EFLAGS_VIP	0x00100000 /* Virtual Interrupt Pending */
-#define X86_EFLAGS_ID	0x00200000 /* CPUID detection flag */
+#define X86_EFLAGS_CF_BIT	0 /* Carry Flag */
+#define X86_EFLAGS_CF		_BITUL(X86_EFLAGS_CF_BIT)
+#define X86_EFLAGS_FIXED_BIT	1 /* Bit 1 - always on */
+#define X86_EFLAGS_FIXED	_BITUL(X86_EFLAGS_FIXED_BIT)
+#define X86_EFLAGS_PF_BIT	2 /* Parity Flag */
+#define X86_EFLAGS_PF		_BITUL(X86_EFLAGS_PF_BIT)
+#define X86_EFLAGS_AF_BIT	4 /* Auxiliary carry Flag */
+#define X86_EFLAGS_AF		_BITUL(X86_EFLAGS_AF_BIT)
+#define X86_EFLAGS_ZF_BIT	6 /* Zero Flag */
+#define X86_EFLAGS_ZF		_BITUL(X86_EFLAGS_ZF_BIT)
+#define X86_EFLAGS_SF_BIT	7 /* Sign Flag */
+#define X86_EFLAGS_SF		_BITUL(X86_EFLAGS_SF_BIT)
+#define X86_EFLAGS_TF_BIT	8 /* Trap Flag */
+#define X86_EFLAGS_TF		_BITUL(X86_EFLAGS_TF_BIT)
+#define X86_EFLAGS_IF_BIT	9 /* Interrupt Flag */
+#define X86_EFLAGS_IF		_BITUL(X86_EFLAGS_IF_BIT)
+#define X86_EFLAGS_DF_BIT	10 /* Direction Flag */
+#define X86_EFLAGS_DF		_BITUL(X86_EFLAGS_DF_BIT)
+#define X86_EFLAGS_OF_BIT	11 /* Overflow Flag */
+#define X86_EFLAGS_OF		_BITUL(X86_EFLAGS_OF_BIT)
+#define X86_EFLAGS_IOPL_BIT	12 /* I/O Privilege Level (2 bits) */
+#define X86_EFLAGS_IOPL		(_AC(3,UL) << X86_EFLAGS_IOPL_BIT)
+#define X86_EFLAGS_NT_BIT	14 /* Nested Task */
+#define X86_EFLAGS_NT		_BITUL(X86_EFLAGS_NT_BIT)
+#define X86_EFLAGS_RF_BIT	16 /* Resume Flag */
+#define X86_EFLAGS_RF		_BITUL(X86_EFLAGS_RF_BIT)
+#define X86_EFLAGS_VM_BIT	17 /* Virtual Mode */
+#define X86_EFLAGS_VM		_BITUL(X86_EFLAGS_VM_BIT)
+#define X86_EFLAGS_AC_BIT	18 /* Alignment Check/Access Control */
+#define X86_EFLAGS_AC		_BITUL(X86_EFLAGS_AC_BIT)
+#define X86_EFLAGS_AC_BIT	18 /* Alignment Check/Access Control */
+#define X86_EFLAGS_AC		_BITUL(X86_EFLAGS_AC_BIT)
+#define X86_EFLAGS_VIF_BIT	19 /* Virtual Interrupt Flag */
+#define X86_EFLAGS_VIF		_BITUL(X86_EFLAGS_VIF_BIT)
+#define X86_EFLAGS_VIP_BIT	20 /* Virtual Interrupt Pending */
+#define X86_EFLAGS_VIP		_BITUL(X86_EFLAGS_VIP_BIT)
+#define X86_EFLAGS_ID_BIT	21 /* CPUID detection */
+#define X86_EFLAGS_ID		_BITUL(X86_EFLAGS_ID_BIT)
 
 /*
  * Basic CPU control in CR0
  */
-#define X86_CR0_PE	0x00000001 /* Protection Enable */
-#define X86_CR0_MP	0x00000002 /* Monitor Coprocessor */
-#define X86_CR0_EM	0x00000004 /* Emulation */
-#define X86_CR0_TS	0x00000008 /* Task Switched */
-#define X86_CR0_ET	0x00000010 /* Extension Type */
-#define X86_CR0_NE	0x00000020 /* Numeric Error */
-#define X86_CR0_WP	0x00010000 /* Write Protect */
-#define X86_CR0_AM	0x00040000 /* Alignment Mask */
-#define X86_CR0_NW	0x20000000 /* Not Write-through */
-#define X86_CR0_CD	0x40000000 /* Cache Disable */
-#define X86_CR0_PG	0x80000000 /* Paging */
+#define X86_CR0_PE_BIT		0 /* Protection Enable */
+#define X86_CR0_PE		_BITUL(X86_CR0_PE_BIT)
+#define X86_CR0_MP_BIT		1 /* Monitor Coprocessor */
+#define X86_CR0_MP		_BITUL(X86_CR0_MP_BIT)
+#define X86_CR0_EM_BIT		2 /* Emulation */
+#define X86_CR0_EM		_BITUL(X86_CR0_EM_BIT)
+#define X86_CR0_TS_BIT		3 /* Task Switched */
+#define X86_CR0_TS		_BITUL(X86_CR0_TS_BIT)
+#define X86_CR0_ET_BIT		4 /* Extension Type */
+#define X86_CR0_ET		_BITUL(X86_CR0_ET_BIT)
+#define X86_CR0_NE_BIT		5 /* Numeric Error */
+#define X86_CR0_NE		_BITUL(X86_CR0_NE_BIT)
+#define X86_CR0_WP_BIT		16 /* Write Protect */
+#define X86_CR0_WP		_BITUL(X86_CR0_WP_BIT)
+#define X86_CR0_AM_BIT		18 /* Alignment Mask */
+#define X86_CR0_AM		_BITUL(X86_CR0_AM_BIT)
+#define X86_CR0_NW_BIT		29 /* Not Write-through */
+#define X86_CR0_NW		_BITUL(X86_CR0_NW_BIT)
+#define X86_CR0_CD_BIT		30 /* Cache Disable */
+#define X86_CR0_CD		_BITUL(X86_CR0_CD_BIT)
+#define X86_CR0_PG_BIT		31 /* Paging */
+#define X86_CR0_PG		_BITUL(X86_CR0_PG_BIT)
 
 /*
  * Paging options in CR3
  */
-#define X86_CR3_PWT	0x00000008 /* Page Write Through */
-#define X86_CR3_PCD	0x00000010 /* Page Cache Disable */
-#define X86_CR3_PCID_MASK 0x00000fff /* PCID Mask */
+#define X86_CR3_PWT_BIT		3 /* Page Write Through */
+#define X86_CR3_PWT		_BITUL(X86_CR3_PWT_BIT)
+#define X86_CR3_PCD_BIT		4 /* Page Cache Disable */
+#define X86_CR3_PCD		_BITUL(X86_CR3_PCD_BIT)
+#define X86_CR3_PCID_MASK	_AC(0x00000fff,UL) /* PCID Mask */
 
 /*
  * Intel CPU features in CR4
  */
-#define X86_CR4_VME	0x00000001 /* enable vm86 extensions */
-#define X86_CR4_PVI	0x00000002 /* virtual interrupts flag enable */
-#define X86_CR4_TSD	0x00000004 /* disable time stamp at ipl 3 */
-#define X86_CR4_DE	0x00000008 /* enable debugging extensions */
-#define X86_CR4_PSE	0x00000010 /* enable page size extensions */
-#define X86_CR4_PAE	0x00000020 /* enable physical address extensions */
-#define X86_CR4_MCE	0x00000040 /* Machine check enable */
-#define X86_CR4_PGE	0x00000080 /* enable global pages */
-#define X86_CR4_PCE	0x00000100 /* enable performance counters at ipl 3 */
-#define X86_CR4_OSFXSR	0x00000200 /* enable fast FPU save and restore */
-#define X86_CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */
-#define X86_CR4_VMXE	0x00002000 /* enable VMX virtualization */
-#define X86_CR4_RDWRGSFS 0x00010000 /* enable RDWRGSFS support */
-#define X86_CR4_PCIDE	0x00020000 /* enable PCID support */
-#define X86_CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */
-#define X86_CR4_SMEP	0x00100000 /* enable SMEP support */
-#define X86_CR4_SMAP	0x00200000 /* enable SMAP support */
+#define X86_CR4_VME_BIT		0 /* enable vm86 extensions */
+#define X86_CR4_VME		_BITUL(X86_CR4_VME_BIT)
+#define X86_CR4_PVI_BIT		1 /* virtual interrupts flag enable */
+#define X86_CR4_PVI		_BITUL(X86_CR4_PVI_BIT)
+#define X86_CR4_TSD_BIT		2 /* disable time stamp at ipl 3 */
+#define X86_CR4_TSD		_BITUL(X86_CR4_TSD_BIT)
+#define X86_CR4_DE_BIT		3 /* enable debugging extensions */
+#define X86_CR4_DE		_BITUL(X86_CR4_DE_BIT)
+#define X86_CR4_PSE_BIT		4 /* enable page size extensions */
+#define X86_CR4_PSE		_BITUL(X86_CR4_PSE_BIT)
+#define X86_CR4_PAE_BIT		5 /* enable physical address extensions */
+#define X86_CR4_PAE		_BITUL(X86_CR4_PAE_BIT)
+#define X86_CR4_MCE_BIT		6 /* Machine check enable */
+#define X86_CR4_MCE		_BITUL(X86_CR4_MCE_BIT)
+#define X86_CR4_PGE_BIT		7 /* enable global pages */
+#define X86_CR4_PGE		_BITUL(X86_CR4_PGE_BIT)
+#define X86_CR4_PCE_BIT		8 /* enable performance counters at ipl 3 */
+#define X86_CR4_PCE		_BITUL(X86_CR4_PCE_BIT)
+#define X86_CR4_OSFXSR_BIT	9 /* enable fast FPU save and restore */
+#define X86_CR4_OSFXSR		_BITUL(X86_CR4_OSFXSR_BIT)
+#define X86_CR4_OSXMMEXCPT_BIT	10 /* enable unmasked SSE exceptions */
+#define X86_CR4_OSXMMEXCPT	_BITUL(X86_CR4_OSXMMEXCPT_BIT)
+#define X86_CR4_VMXE_BIT	13 /* enable VMX virtualization */
+#define X86_CR4_VMXE		_BITUL(X86_CR4_VMXE_BIT)
+#define X86_CR4_SMXE_BIT	14 /* enable safer mode (TXT) */
+#define X86_CR4_SMXE		_BITUL(X86_CR4_SMXE_BIT)
+#define X86_CR4_FSGSBASE_BIT	16 /* enable RDWRFSGS support */
+#define X86_CR4_FSGSBASE	_BITUL(X86_CR4_FSGSBASE_BIT)
+#define X86_CR4_PCIDE_BIT	17 /* enable PCID support */
+#define X86_CR4_PCIDE		_BITUL(X86_CR4_PCIDE_BIT)
+#define X86_CR4_OSXSAVE_BIT	18 /* enable xsave and xrestore */
+#define X86_CR4_OSXSAVE		_BITUL(X86_CR4_OSXSAVE_BIT)
+#define X86_CR4_SMEP_BIT	20 /* enable SMEP support */
+#define X86_CR4_SMEP		_BITUL(X86_CR4_SMEP_BIT)
+#define X86_CR4_SMAP_BIT	21 /* enable SMAP support */
+#define X86_CR4_SMAP		_BITUL(X86_CR4_SMAP_BIT)
 
 /*
  * x86-64 Task Priority Register, CR8
  */
-#define X86_CR8_TPR	0x0000000F /* task priority register */
+#define X86_CR8_TPR		_AC(0x0000000f,UL) /* task priority register */
 
 /*
  * AMD and Transmeta use MSRs for configuration; see <asm/msr-index.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/Kconfig linux-libre-3.11-rc7-gnu/arch/x86/Kconfig
--- linux-libre-3.10-gnu/arch/x86/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -65,6 +65,7 @@ config X86
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_XZ
 	select HAVE_KERNEL_LZO
+	select HAVE_KERNEL_LZ4
 	select HAVE_HW_BREAKPOINT
 	select HAVE_MIXED_BREAKPOINTS_REGS
 	select PERF_EVENTS
@@ -102,6 +103,7 @@ config X86
 	select HAVE_ARCH_SECCOMP_FILTER
 	select BUILDTIME_EXTABLE_SORT
 	select GENERIC_CMOS_UPDATE
+	select HAVE_ARCH_SOFT_DIRTY
 	select CLOCKSOURCE_WATCHDOG
 	select GENERIC_CLOCKEVENTS
 	select ARCH_CLOCKSOURCE_DATA if X86_64
@@ -121,6 +123,7 @@ config X86
 	select OLD_SIGACTION if X86_32
 	select COMPAT_OLD_SIGACTION if IA32_EMULATION
 	select RTC_LIB
+	select HAVE_DEBUG_STACKOVERFLOW
 
 config INSTRUCTION_DECODER
 	def_bool y
@@ -207,6 +210,12 @@ config ARCH_HIBERNATION_POSSIBLE
 config ARCH_SUSPEND_POSSIBLE
 	def_bool y
 
+config ARCH_WANT_HUGE_PMD_SHARE
+	def_bool y
+
+config ARCH_WANT_GENERAL_HUGETLB
+	def_bool y
+
 config ZONE_DMA32
 	bool
 	default X86_64
@@ -336,6 +345,7 @@ config X86_EXTENDED_PLATFORM
 
 	  If you enable this option then you'll be able to select support
 	  for the following (non-PC) 32 bit x86 platforms:
+		Goldfish (Android emulator)
 		AMD Elan
 		NUMAQ (IBM/Sequent)
 		RDC R-321x SoC
@@ -410,6 +420,7 @@ config X86_UV
 config X86_GOLDFISH
        bool "Goldfish (Virtual Platform)"
        depends on X86_32
+       depends on X86_EXTENDED_PLATFORM
        ---help---
 	 Enable support for the Goldfish virtual platform used primarily
 	 for Android development. Unless you are building for the Android
@@ -1058,8 +1069,16 @@ config MICROCODE_INTEL_LIB
 	depends on MICROCODE_INTEL
 
 config MICROCODE_INTEL_EARLY
+	def_bool n
+
+config MICROCODE_AMD_EARLY
+	def_bool n
+
+config MICROCODE_EARLY
 	bool "Early load microcode"
-	depends on MICROCODE_INTEL && BLK_DEV_INITRD
+	depends on MICROCODE=y && BLK_DEV_INITRD
+	select MICROCODE_INTEL_EARLY if MICROCODE_INTEL
+	select MICROCODE_AMD_EARLY if MICROCODE_AMD
 	default y
 	help
 	  This option provides functionality to read additional microcode data
@@ -1067,10 +1086,6 @@ config MICROCODE_INTEL_EARLY
 	  microcode to CPU's as early as possible. No functional change if no
 	  microcode data is glued to the initrd, therefore it's safe to say Y.
 
-config MICROCODE_EARLY
-	def_bool y
-	depends on MICROCODE_INTEL_EARLY
-
 config X86_MSR
 	tristate "/dev/cpu/*/msr - Model-specific register support"
 	---help---
@@ -1725,7 +1740,7 @@ config PHYSICAL_ALIGN
 
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
-	depends on SMP && HOTPLUG
+	depends on SMP
 	---help---
 	  Say Y here to allow turning CPUs off and on. CPUs can be
 	  controlled through /sys/devices/system/cpu.
@@ -2246,11 +2261,11 @@ source "drivers/pcmcia/Kconfig"
 source "drivers/pci/hotplug/Kconfig"
 
 config RAPIDIO
-	bool "RapidIO support"
+	tristate "RapidIO support"
 	depends on PCI
 	default n
 	help
-	  If you say Y here, the kernel will include drivers and
+	  If enabled this option will include drivers and the core
 	  infrastructure code to support RapidIO interconnect devices.
 
 source "drivers/rapidio/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/x86/Kconfig.debug
--- linux-libre-3.10-gnu/arch/x86/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -59,16 +59,6 @@ config EARLY_PRINTK_DBGP
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash. You need usb debug device.
 
-config DEBUG_STACKOVERFLOW
-	bool "Check for stack overflows"
-	depends on DEBUG_KERNEL
-	---help---
-	  Say Y here if you want to check the overflows of kernel, IRQ
-	  and exception stacks. This option will cause messages of the
-	  stacks in detail when free stack space drops below a certain
-	  limit.
-	  If in doubt, say "N".
-
 config X86_PTDUMP
 	bool "Export kernel pagetable layout to userspace via debugfs"
 	depends on DEBUG_KERNEL
@@ -122,7 +112,6 @@ config DEBUG_NX_TEST
 config DOUBLEFAULT
 	default y
 	bool "Enable doublefault exception handler" if EXPERT
-	depends on X86_32
 	---help---
 	  This option allows trapping of rare doublefault exceptions that
 	  would otherwise cause a system to silently reboot. Disabling this
@@ -304,4 +293,14 @@ config DEBUG_NMI_SELFTEST
 
 	  If unsure, say N.
 
+config X86_DEBUG_STATIC_CPU_HAS
+	bool "Debug alternatives"
+	depends on DEBUG_KERNEL
+	---help---
+	  This option causes additional code to be generated which
+	  fails if static_cpu_has() is used before alternatives have
+	  run.
+
+	  If unsure, say N.
+
 endmenu
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/acpi/boot.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/acpi/boot.c
--- linux-libre-3.10-gnu/arch/x86/kernel/acpi/boot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/acpi/boot.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,6 +44,7 @@
 #include <asm/mpspec.h>
 #include <asm/smp.h>
 
+#include "sleep.h" /* To include x86_acpi_suspend_lowlevel */
 static int __initdata acpi_force = 0;
 u32 acpi_rsdt_forced;
 int acpi_disabled;
@@ -194,7 +195,7 @@ static int __init acpi_parse_madt(struct
 	return 0;
 }
 
-static void __cpuinit acpi_register_lapic(int id, u8 enabled)
+static void acpi_register_lapic(int id, u8 enabled)
 {
 	unsigned int ver = 0;
 
@@ -559,6 +560,12 @@ static int acpi_register_gsi_ioapic(stru
 int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
 			   int trigger, int polarity) = acpi_register_gsi_pic;
 
+#ifdef CONFIG_ACPI_SLEEP
+int (*acpi_suspend_lowlevel)(void) = x86_acpi_suspend_lowlevel;
+#else
+int (*acpi_suspend_lowlevel)(void);
+#endif
+
 /*
  * success: return IRQ number (>=0)
  * failure: return < 0
@@ -600,7 +607,7 @@ void __init acpi_set_irq_model_ioapic(vo
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
 #include <acpi/processor.h>
 
-static void __cpuinit acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
+static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
 {
 #ifdef CONFIG_ACPI_NUMA
 	int nid;
@@ -613,7 +620,7 @@ static void __cpuinit acpi_map_cpu2node(
 #endif
 }
 
-static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
+static int _acpi_map_lsapic(acpi_handle handle, int *pcpu)
 {
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	union acpi_object *obj;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/acpi/sleep.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/acpi/sleep.c
--- linux-libre-3.10-gnu/arch/x86/kernel/acpi/sleep.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/acpi/sleep.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,12 +26,12 @@ static char temp_stack[4096];
 #endif
 
 /**
- * acpi_suspend_lowlevel - save kernel state
+ * x86_acpi_suspend_lowlevel - save kernel state
  *
  * Create an identity mapped page table and copy the wakeup routine to
  * low memory.
  */
-int acpi_suspend_lowlevel(void)
+int x86_acpi_suspend_lowlevel(void)
 {
 	struct wakeup_header *header =
 		(struct wakeup_header *) __va(real_mode_header->wakeup_header);
@@ -48,9 +48,20 @@ int acpi_suspend_lowlevel(void)
 #ifndef CONFIG_64BIT
 	native_store_gdt((struct desc_ptr *)&header->pmode_gdt);
 
+	/*
+	 * We have to check that we can write back the value, and not
+	 * just read it.  At least on 90 nm Pentium M (Family 6, Model
+	 * 13), reading an invalid MSR is not guaranteed to trap, see
+	 * Erratum X4 in "Intel Pentium M Processor on 90 nm Process
+	 * with 2-MB L2 Cache and Intel® Processor A100 and A110 on 90
+	 * nm process with 512-KB L2 Cache Specification Update".
+	 */
 	if (!rdmsr_safe(MSR_EFER,
 			&header->pmode_efer_low,
-			&header->pmode_efer_high))
+			&header->pmode_efer_high) &&
+	    !wrmsr_safe(MSR_EFER,
+			header->pmode_efer_low,
+			header->pmode_efer_high))
 		header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_EFER);
 #endif /* !CONFIG_64BIT */
 
@@ -61,7 +72,10 @@ int acpi_suspend_lowlevel(void)
 	}
 	if (!rdmsr_safe(MSR_IA32_MISC_ENABLE,
 			&header->pmode_misc_en_low,
-			&header->pmode_misc_en_high))
+			&header->pmode_misc_en_high) &&
+	    !wrmsr_safe(MSR_IA32_MISC_ENABLE,
+			header->pmode_misc_en_low,
+			header->pmode_misc_en_high))
 		header->pmode_behavior |=
 			(1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE);
 	header->realmode_flags = acpi_realmode_flags;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/acpi/sleep.h linux-libre-3.11-rc7-gnu/arch/x86/kernel/acpi/sleep.h
--- linux-libre-3.10-gnu/arch/x86/kernel/acpi/sleep.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/acpi/sleep.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,3 +15,5 @@ extern unsigned long acpi_copy_wakeup_ro
 extern void wakeup_long64(void);
 
 extern void do_suspend_lowlevel(void);
+
+extern int x86_acpi_suspend_lowlevel(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/apic/apic.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/apic.c
--- linux-libre-3.10-gnu/arch/x86/kernel/apic/apic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/apic.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/smp.h>
 #include <linux/mm.h>
 
+#include <asm/trace/irq_vectors.h>
 #include <asm/irq_remapping.h>
 #include <asm/perf_event.h>
 #include <asm/x86_init.h>
@@ -57,7 +58,7 @@
 
 unsigned int num_processors;
 
-unsigned disabled_cpus __cpuinitdata;
+unsigned disabled_cpus;
 
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
@@ -543,7 +544,7 @@ static DEFINE_PER_CPU(struct clock_event
  * Setup the local APIC timer for this CPU. Copy the initialized values
  * of the boot CPU and register the clock event in the framework.
  */
-static void __cpuinit setup_APIC_timer(void)
+static void setup_APIC_timer(void)
 {
 	struct clock_event_device *levt = &__get_cpu_var(lapic_events);
 
@@ -865,7 +866,7 @@ void __init setup_boot_APIC_clock(void)
 	setup_APIC_timer();
 }
 
-void __cpuinit setup_secondary_APIC_clock(void)
+void setup_secondary_APIC_clock(void)
 {
 	setup_APIC_timer();
 }
@@ -919,17 +920,35 @@ void __irq_entry smp_apic_timer_interrup
 	/*
 	 * NOTE! We'd better ACK the irq immediately,
 	 * because timer handling can be slow.
+	 *
+	 * update_process_times() expects us to have done irq_enter().
+	 * Besides, if we don't timer interrupts ignore the global
+	 * interrupt lock, which is the WrongThing (tm) to do.
 	 */
-	ack_APIC_irq();
+	entering_ack_irq();
+	local_apic_timer_interrupt();
+	exiting_irq();
+
+	set_irq_regs(old_regs);
+}
+
+void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
+
 	/*
+	 * NOTE! We'd better ACK the irq immediately,
+	 * because timer handling can be slow.
+	 *
 	 * update_process_times() expects us to have done irq_enter().
 	 * Besides, if we don't timer interrupts ignore the global
 	 * interrupt lock, which is the WrongThing (tm) to do.
 	 */
-	irq_enter();
-	exit_idle();
+	entering_ack_irq();
+	trace_local_timer_entry(LOCAL_TIMER_VECTOR);
 	local_apic_timer_interrupt();
-	irq_exit();
+	trace_local_timer_exit(LOCAL_TIMER_VECTOR);
+	exiting_irq();
 
 	set_irq_regs(old_regs);
 }
@@ -1210,7 +1229,7 @@ void __init init_bsp_APIC(void)
 	apic_write(APIC_LVT1, value);
 }
 
-static void __cpuinit lapic_setup_esr(void)
+static void lapic_setup_esr(void)
 {
 	unsigned int oldvalue, value, maxlvt;
 
@@ -1257,7 +1276,7 @@ static void __cpuinit lapic_setup_esr(vo
  * Used to setup local APIC while initializing BSP or bringin up APs.
  * Always called with preemption disabled.
  */
-void __cpuinit setup_local_APIC(void)
+void setup_local_APIC(void)
 {
 	int cpu = smp_processor_id();
 	unsigned int value, queued;
@@ -1452,7 +1471,7 @@ void __cpuinit setup_local_APIC(void)
 #endif
 }
 
-void __cpuinit end_local_APIC_setup(void)
+void end_local_APIC_setup(void)
 {
 	lapic_setup_esr();
 
@@ -1907,12 +1926,10 @@ int __init APIC_init_uniprocessor(void)
 /*
  * This interrupt should _never_ happen with our APIC/SMP architecture
  */
-void smp_spurious_interrupt(struct pt_regs *regs)
+static inline void __smp_spurious_interrupt(void)
 {
 	u32 v;
 
-	irq_enter();
-	exit_idle();
 	/*
 	 * Check if this really is a spurious interrupt and ACK it
 	 * if it is a vectored one.  Just in case...
@@ -1927,13 +1944,28 @@ void smp_spurious_interrupt(struct pt_re
 	/* see sw-dev-man vol 3, chapter 7.4.13.5 */
 	pr_info("spurious APIC interrupt on CPU#%d, "
 		"should never happen.\n", smp_processor_id());
-	irq_exit();
+}
+
+void smp_spurious_interrupt(struct pt_regs *regs)
+{
+	entering_irq();
+	__smp_spurious_interrupt();
+	exiting_irq();
+}
+
+void smp_trace_spurious_interrupt(struct pt_regs *regs)
+{
+	entering_irq();
+	trace_spurious_apic_entry(SPURIOUS_APIC_VECTOR);
+	__smp_spurious_interrupt();
+	trace_spurious_apic_exit(SPURIOUS_APIC_VECTOR);
+	exiting_irq();
 }
 
 /*
  * This interrupt should never happen with our APIC/SMP architecture
  */
-void smp_error_interrupt(struct pt_regs *regs)
+static inline void __smp_error_interrupt(struct pt_regs *regs)
 {
 	u32 v0, v1;
 	u32 i = 0;
@@ -1948,8 +1980,6 @@ void smp_error_interrupt(struct pt_regs
 		"Illegal register address",	/* APIC Error Bit 7 */
 	};
 
-	irq_enter();
-	exit_idle();
 	/* First tickle the hardware, only then report what went on. -- REW */
 	v0 = apic_read(APIC_ESR);
 	apic_write(APIC_ESR, 0);
@@ -1970,7 +2000,22 @@ void smp_error_interrupt(struct pt_regs
 
 	apic_printk(APIC_DEBUG, KERN_CONT "\n");
 
-	irq_exit();
+}
+
+void smp_error_interrupt(struct pt_regs *regs)
+{
+	entering_irq();
+	__smp_error_interrupt(regs);
+	exiting_irq();
+}
+
+void smp_trace_error_interrupt(struct pt_regs *regs)
+{
+	entering_irq();
+	trace_error_apic_entry(ERROR_APIC_VECTOR);
+	__smp_error_interrupt(regs);
+	trace_error_apic_exit(ERROR_APIC_VECTOR);
+	exiting_irq();
 }
 
 /**
@@ -2062,7 +2107,7 @@ void disconnect_bsp_APIC(int virt_wire_s
 	apic_write(APIC_LVT1, value);
 }
 
-void __cpuinit generic_processor_info(int apicid, int version)
+void generic_processor_info(int apicid, int version)
 {
 	int cpu, max = nr_cpu_ids;
 	bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid,
@@ -2302,7 +2347,7 @@ static void lapic_resume(void)
 	apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
 	apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
 	apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
+#if defined(CONFIG_X86_MCE_INTEL)
 	if (maxlvt >= 5)
 		apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
 #endif
@@ -2332,7 +2377,7 @@ static struct syscore_ops lapic_syscore_
 	.suspend	= lapic_suspend,
 };
 
-static void __cpuinit apic_pm_activate(void)
+static void apic_pm_activate(void)
 {
 	apic_pm_state.active = 1;
 }
@@ -2357,7 +2402,7 @@ static void apic_pm_activate(void) { }
 
 #ifdef CONFIG_X86_64
 
-static int __cpuinit apic_cluster_num(void)
+static int apic_cluster_num(void)
 {
 	int i, clusters, zeros;
 	unsigned id;
@@ -2402,10 +2447,10 @@ static int __cpuinit apic_cluster_num(vo
 	return clusters;
 }
 
-static int __cpuinitdata multi_checked;
-static int __cpuinitdata multi;
+static int multi_checked;
+static int multi;
 
-static int __cpuinit set_multi(const struct dmi_system_id *d)
+static int set_multi(const struct dmi_system_id *d)
 {
 	if (multi)
 		return 0;
@@ -2414,7 +2459,7 @@ static int __cpuinit set_multi(const str
 	return 0;
 }
 
-static const __cpuinitconst struct dmi_system_id multi_dmi_table[] = {
+static const struct dmi_system_id multi_dmi_table[] = {
 	{
 		.callback = set_multi,
 		.ident = "IBM System Summit2",
@@ -2426,7 +2471,7 @@ static const __cpuinitconst struct dmi_s
 	{}
 };
 
-static void __cpuinit dmi_check_multi(void)
+static void dmi_check_multi(void)
 {
 	if (multi_checked)
 		return;
@@ -2443,7 +2488,7 @@ static void __cpuinit dmi_check_multi(vo
  * multi-chassis.
  * Use DMI to check them
  */
-__cpuinit int apic_is_clustered_box(void)
+int apic_is_clustered_box(void)
 {
 	dmi_check_multi();
 	if (multi)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/apic/apic_numachip.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/apic_numachip.c
--- linux-libre-3.10-gnu/arch/x86/kernel/apic/apic_numachip.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/apic_numachip.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,7 +74,7 @@ static int numachip_phys_pkg_id(int init
 	return initial_apic_id >> index_msb;
 }
 
-static int __cpuinit numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip)
+static int numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip)
 {
 	union numachip_csr_g3_ext_irq_gen int_gen;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/apic/es7000_32.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/es7000_32.c
--- linux-libre-3.10-gnu/arch/x86/kernel/apic/es7000_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/es7000_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -130,7 +130,7 @@ int					es7000_plat;
  */
 
 
-static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
+static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
 {
 	unsigned long vect = 0, psaival = 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/apic/numaq_32.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/numaq_32.c
--- linux-libre-3.10-gnu/arch/x86/kernel/apic/numaq_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/numaq_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -105,7 +105,7 @@ static void __init smp_dump_qct(void)
 	}
 }
 
-void __cpuinit numaq_tsc_disable(void)
+void numaq_tsc_disable(void)
 {
 	if (!found_numaq)
 		return;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/apic/x2apic_cluster.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/x2apic_cluster.c
--- linux-libre-3.10-gnu/arch/x86/kernel/apic/x2apic_cluster.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/x2apic_cluster.c	2013-08-25 20:43:22.000000000 -0400
@@ -148,7 +148,7 @@ static void init_x2apic_ldr(void)
  /*
   * At CPU state changes, update the x2apic cluster sibling info.
   */
-static int __cpuinit
+static int
 update_clusterinfo(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
 	unsigned int this_cpu = (unsigned long)hcpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/apic/x2apic_uv_x.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-libre-3.10-gnu/arch/x86/kernel/apic/x2apic_uv_x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/apic/x2apic_uv_x.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/kdebug.h>
 #include <linux/delay.h>
 #include <linux/crash_dump.h>
+#include <linux/reboot.h>
 
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
@@ -36,7 +37,6 @@
 #include <asm/ipi.h>
 #include <asm/smp.h>
 #include <asm/x86_init.h>
-#include <asm/emergency-restart.h>
 #include <asm/nmi.h>
 
 /* BMC sets a bit this MMR non-zero before sending an NMI */
@@ -51,6 +51,8 @@ DEFINE_PER_CPU(int, x2apic_extra_bits);
 
 static enum uv_system_type uv_system_type;
 static u64 gru_start_paddr, gru_end_paddr;
+static u64 gru_dist_base, gru_first_node_paddr = -1LL, gru_last_node_paddr;
+static u64 gru_dist_lmask, gru_dist_umask;
 static union uvh_apicid uvh_apicid;
 int uv_min_hub_revision_id;
 EXPORT_SYMBOL_GPL(uv_min_hub_revision_id);
@@ -72,7 +74,20 @@ static unsigned long __init uv_early_rea
 
 static inline bool is_GRU_range(u64 start, u64 end)
 {
-	return start >= gru_start_paddr && end <= gru_end_paddr;
+	if (gru_dist_base) {
+		u64 su = start & gru_dist_umask; /* upper (incl pnode) bits */
+		u64 sl = start & gru_dist_lmask; /* base offset bits */
+		u64 eu = end & gru_dist_umask;
+		u64 el = end & gru_dist_lmask;
+
+		/* Must reside completely within a single GRU range */
+		return (sl == gru_dist_base && el == gru_dist_base &&
+			su >= gru_first_node_paddr &&
+			su <= gru_last_node_paddr &&
+			eu == su);
+	} else {
+		return start >= gru_start_paddr && end <= gru_end_paddr;
+	}
 }
 
 static bool uv_is_untracked_pat_range(u64 start, u64 end)
@@ -194,7 +209,7 @@ EXPORT_SYMBOL_GPL(uv_possible_blades);
 unsigned long sn_rtc_cycles_per_second;
 EXPORT_SYMBOL(sn_rtc_cycles_per_second);
 
-static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
+static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
 {
 #ifdef CONFIG_SMP
 	unsigned long val;
@@ -401,7 +416,7 @@ static struct apic __refdata apic_x2apic
 	.safe_wait_icr_idle		= native_safe_x2apic_wait_icr_idle,
 };
 
-static __cpuinit void set_x2apic_extra_bits(int pnode)
+static void set_x2apic_extra_bits(int pnode)
 {
 	__this_cpu_write(x2apic_extra_bits, pnode << uvh_apicid.s.pnode_shift);
 }
@@ -463,26 +478,63 @@ static __init void map_high(char *id, un
 		pr_info("UV: Map %s_HI base address NULL\n", id);
 		return;
 	}
-	pr_info("UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, paddr + bytes);
+	pr_debug("UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, paddr + bytes);
 	if (map_type == map_uc)
 		init_extra_mapping_uc(paddr, bytes);
 	else
 		init_extra_mapping_wb(paddr, bytes);
 }
 
+static __init void map_gru_distributed(unsigned long c)
+{
+	union uvh_rh_gam_gru_overlay_config_mmr_u gru;
+	u64 paddr;
+	unsigned long bytes;
+	int nid;
+
+	gru.v = c;
+	/* only base bits 42:28 relevant in dist mode */
+	gru_dist_base = gru.v & 0x000007fff0000000UL;
+	if (!gru_dist_base) {
+		pr_info("UV: Map GRU_DIST base address NULL\n");
+		return;
+	}
+	bytes = 1UL << UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT;
+	gru_dist_lmask = ((1UL << uv_hub_info->m_val) - 1) & ~(bytes - 1);
+	gru_dist_umask = ~((1UL << uv_hub_info->m_val) - 1);
+	gru_dist_base &= gru_dist_lmask; /* Clear bits above M */
+	for_each_online_node(nid) {
+		paddr = ((u64)uv_node_to_pnode(nid) << uv_hub_info->m_val) |
+				gru_dist_base;
+		init_extra_mapping_wb(paddr, bytes);
+		gru_first_node_paddr = min(paddr, gru_first_node_paddr);
+		gru_last_node_paddr = max(paddr, gru_last_node_paddr);
+	}
+	/* Save upper (63:M) bits of address only for is_GRU_range */
+	gru_first_node_paddr &= gru_dist_umask;
+	gru_last_node_paddr &= gru_dist_umask;
+	pr_debug("UV: Map GRU_DIST base 0x%016llx  0x%016llx - 0x%016llx\n",
+		gru_dist_base, gru_first_node_paddr, gru_last_node_paddr);
+}
+
 static __init void map_gru_high(int max_pnode)
 {
 	union uvh_rh_gam_gru_overlay_config_mmr_u gru;
 	int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT;
 
 	gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR);
-	if (gru.s.enable) {
-		map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb);
-		gru_start_paddr = ((u64)gru.s.base << shift);
-		gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1);
-	} else {
+	if (!gru.s.enable) {
 		pr_info("UV: GRU disabled\n");
+		return;
+	}
+
+	if (is_uv3_hub() && gru.s3.mode) {
+		map_gru_distributed(gru.v);
+		return;
 	}
+	map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb);
+	gru_start_paddr = ((u64)gru.s.base << shift);
+	gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1);
 }
 
 static __init void map_mmr_high(int max_pnode)
@@ -683,7 +735,7 @@ static void uv_heartbeat(unsigned long i
 	mod_timer_pinned(timer, jiffies + SCIR_CPU_HB_INTERVAL);
 }
 
-static void __cpuinit uv_heartbeat_enable(int cpu)
+static void uv_heartbeat_enable(int cpu)
 {
 	while (!uv_cpu_hub_info(cpu)->scir.enabled) {
 		struct timer_list *timer = &uv_cpu_hub_info(cpu)->scir.timer;
@@ -700,7 +752,7 @@ static void __cpuinit uv_heartbeat_enabl
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static void __cpuinit uv_heartbeat_disable(int cpu)
+static void uv_heartbeat_disable(int cpu)
 {
 	if (uv_cpu_hub_info(cpu)->scir.enabled) {
 		uv_cpu_hub_info(cpu)->scir.enabled = 0;
@@ -712,8 +764,8 @@ static void __cpuinit uv_heartbeat_disab
 /*
  * cpu hotplug notifier
  */
-static __cpuinit int uv_scir_cpu_notify(struct notifier_block *self,
-				       unsigned long action, void *hcpu)
+static int uv_scir_cpu_notify(struct notifier_block *self, unsigned long action,
+			      void *hcpu)
 {
 	long cpu = (long)hcpu;
 
@@ -783,7 +835,7 @@ int uv_set_vga_state(struct pci_dev *pde
  * Called on each cpu to initialize the per_cpu UV data area.
  * FIXME: hotplug not supported yet
  */
-void __cpuinit uv_cpu_init(void)
+void uv_cpu_init(void)
 {
 	/* CPU 0 initilization will be done via uv_system_init. */
 	if (!uv_blade_info)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/asm-offsets_32.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/asm-offsets_32.c
--- linux-libre-3.10-gnu/arch/x86/kernel/asm-offsets_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/asm-offsets_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,6 @@ void foo(void)
 	OFFSET(CPUINFO_x86_vendor, cpuinfo_x86, x86_vendor);
 	OFFSET(CPUINFO_x86_model, cpuinfo_x86, x86_model);
 	OFFSET(CPUINFO_x86_mask, cpuinfo_x86, x86_mask);
-	OFFSET(CPUINFO_hard_math, cpuinfo_x86, hard_math);
 	OFFSET(CPUINFO_cpuid_level, cpuinfo_x86, cpuid_level);
 	OFFSET(CPUINFO_x86_capability, cpuinfo_x86, x86_capability);
 	OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/amd.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/amd.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/amd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/amd.c	2013-08-25 20:43:22.000000000 -0400
@@ -69,7 +69,7 @@ static inline int wrmsrl_amd_safe(unsign
 extern void vide(void);
 __asm__(".align 4\nvide: ret");
 
-static void __cpuinit init_amd_k5(struct cpuinfo_x86 *c)
+static void init_amd_k5(struct cpuinfo_x86 *c)
 {
 /*
  * General Systems BIOSen alias the cpu frequency registers
@@ -87,10 +87,10 @@ static void __cpuinit init_amd_k5(struct
 }
 
 
-static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c)
+static void init_amd_k6(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
-	int mbytes = num_physpages >> (20-PAGE_SHIFT);
+	int mbytes = get_num_physpages() >> (20-PAGE_SHIFT);
 
 	if (c->x86_model < 6) {
 		/* Based on AMD doc 20734R - June 2000 */
@@ -179,7 +179,7 @@ static void __cpuinit init_amd_k6(struct
 	}
 }
 
-static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
+static void amd_k7_smp_check(struct cpuinfo_x86 *c)
 {
 	/* calling is from identify_secondary_cpu() ? */
 	if (!c->cpu_index)
@@ -222,7 +222,7 @@ static void __cpuinit amd_k7_smp_check(s
 	add_taint(TAINT_UNSAFE_SMP, LOCKDEP_NOW_UNRELIABLE);
 }
 
-static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
+static void init_amd_k7(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 
@@ -267,7 +267,7 @@ static void __cpuinit init_amd_k7(struct
  * To workaround broken NUMA config.  Read the comment in
  * srat_detect_node().
  */
-static int __cpuinit nearby_node(int apicid)
+static int nearby_node(int apicid)
 {
 	int i, node;
 
@@ -292,7 +292,7 @@ static int __cpuinit nearby_node(int api
  * (2) AMD processors supporting compute units
  */
 #ifdef CONFIG_X86_HT
-static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c)
+static void amd_get_topology(struct cpuinfo_x86 *c)
 {
 	u32 nodes, cores_per_cu = 1;
 	u8 node_id;
@@ -342,7 +342,7 @@ static void __cpuinit amd_get_topology(s
  * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
  * Assumes number of cores is a power of two.
  */
-static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
+static void amd_detect_cmp(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_HT
 	unsigned bits;
@@ -369,7 +369,7 @@ u16 amd_get_nb_id(int cpu)
 }
 EXPORT_SYMBOL_GPL(amd_get_nb_id);
 
-static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
+static void srat_detect_node(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_NUMA
 	int cpu = smp_processor_id();
@@ -421,7 +421,7 @@ static void __cpuinit srat_detect_node(s
 #endif
 }
 
-static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c)
+static void early_init_amd_mc(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_HT
 	unsigned bits, ecx;
@@ -447,7 +447,7 @@ static void __cpuinit early_init_amd_mc(
 #endif
 }
 
-static void __cpuinit bsp_init_amd(struct cpuinfo_x86 *c)
+static void bsp_init_amd(struct cpuinfo_x86 *c)
 {
 	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
 
@@ -475,7 +475,7 @@ static void __cpuinit bsp_init_amd(struc
 	}
 }
 
-static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
+static void early_init_amd(struct cpuinfo_x86 *c)
 {
 	early_init_amd_mc(c);
 
@@ -512,9 +512,9 @@ static void __cpuinit early_init_amd(str
 
 static const int amd_erratum_383[];
 static const int amd_erratum_400[];
-static bool cpu_has_amd_erratum(const int *erratum);
+static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum);
 
-static void __cpuinit init_amd(struct cpuinfo_x86 *c)
+static void init_amd(struct cpuinfo_x86 *c)
 {
 	u32 dummy;
 	unsigned long long value;
@@ -729,19 +729,18 @@ static void __cpuinit init_amd(struct cp
 		value &= ~(1ULL << 24);
 		wrmsrl_safe(MSR_AMD64_BU_CFG2, value);
 
-		if (cpu_has_amd_erratum(amd_erratum_383))
+		if (cpu_has_amd_erratum(c, amd_erratum_383))
 			set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH);
 	}
 
-	if (cpu_has_amd_erratum(amd_erratum_400))
+	if (cpu_has_amd_erratum(c, amd_erratum_400))
 		set_cpu_bug(c, X86_BUG_AMD_APIC_C1E);
 
 	rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
 }
 
 #ifdef CONFIG_X86_32
-static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c,
-							unsigned int size)
+static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
 {
 	/* AMD errata T13 (order #21922) */
 	if ((c->x86 == 6)) {
@@ -757,7 +756,7 @@ static unsigned int __cpuinit amd_size_c
 }
 #endif
 
-static void __cpuinit cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c)
+static void cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c)
 {
 	tlb_flushall_shift = 5;
 
@@ -765,7 +764,7 @@ static void __cpuinit cpu_set_tlb_flusha
 		tlb_flushall_shift = 4;
 }
 
-static void __cpuinit cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
+static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
 {
 	u32 ebx, eax, ecx, edx;
 	u16 mask = 0xfff;
@@ -820,7 +819,7 @@ static void __cpuinit cpu_detect_tlb_amd
 	cpu_set_tlb_flushall_shift(c);
 }
 
-static const struct cpu_dev __cpuinitconst amd_cpu_dev = {
+static const struct cpu_dev amd_cpu_dev = {
 	.c_vendor	= "AMD",
 	.c_ident	= { "AuthenticAMD" },
 #ifdef CONFIG_X86_32
@@ -879,23 +878,13 @@ static const int amd_erratum_400[] =
 static const int amd_erratum_383[] =
 	AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf));
 
-static bool cpu_has_amd_erratum(const int *erratum)
+
+static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
 {
-	struct cpuinfo_x86 *cpu = __this_cpu_ptr(&cpu_info);
 	int osvw_id = *erratum++;
 	u32 range;
 	u32 ms;
 
-	/*
-	 * If called early enough that current_cpu_data hasn't been initialized
-	 * yet, fall back to boot_cpu_data.
-	 */
-	if (cpu->x86 == 0)
-		cpu = &boot_cpu_data;
-
-	if (cpu->x86_vendor != X86_VENDOR_AMD)
-		return false;
-
 	if (osvw_id >= 0 && osvw_id < 65536 &&
 	    cpu_has(cpu, X86_FEATURE_OSVW)) {
 		u64 osvw_len;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/bugs.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/bugs.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/bugs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/bugs.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,15 +17,6 @@
 #include <asm/paravirt.h>
 #include <asm/alternative.h>
 
-static int __init no_387(char *s)
-{
-	boot_cpu_data.hard_math = 0;
-	write_cr0(X86_CR0_TS | X86_CR0_EM | X86_CR0_MP | read_cr0());
-	return 1;
-}
-
-__setup("no387", no_387);
-
 static double __initdata x = 4195835.0;
 static double __initdata y = 3145727.0;
 
@@ -44,15 +35,6 @@ static void __init check_fpu(void)
 {
 	s32 fdiv_bug;
 
-	if (!boot_cpu_data.hard_math) {
-#ifndef CONFIG_MATH_EMULATION
-		pr_emerg("No coprocessor found and no math emulation present\n");
-		pr_emerg("Giving up\n");
-		for (;;) ;
-#endif
-		return;
-	}
-
 	kernel_fpu_begin();
 
 	/*
@@ -107,5 +89,6 @@ void __init check_bugs(void)
 	 * kernel_fpu_begin/end() in check_fpu() relies on the patched
 	 * alternative instructions.
 	 */
-	check_fpu();
+	if (cpu_has_fpu)
+		check_fpu();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/centaur.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/centaur.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/centaur.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/centaur.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,7 @@
 
 #ifdef CONFIG_X86_OOSTORE
 
-static u32 __cpuinit power2(u32 x)
+static u32 power2(u32 x)
 {
 	u32 s = 1;
 
@@ -25,7 +25,7 @@ static u32 __cpuinit power2(u32 x)
 /*
  * Set up an actual MCR
  */
-static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key)
+static void centaur_mcr_insert(int reg, u32 base, u32 size, int key)
 {
 	u32 lo, hi;
 
@@ -42,7 +42,7 @@ static void __cpuinit centaur_mcr_insert
  *
  * Shortcut: We know you can't put 4Gig of RAM on a winchip
  */
-static u32 __cpuinit ramtop(void)
+static u32 ramtop(void)
 {
 	u32 clip = 0xFFFFFFFFUL;
 	u32 top = 0;
@@ -91,7 +91,7 @@ static u32 __cpuinit ramtop(void)
 /*
  * Compute a set of MCR's to give maximum coverage
  */
-static int __cpuinit centaur_mcr_compute(int nr, int key)
+static int centaur_mcr_compute(int nr, int key)
 {
 	u32 mem = ramtop();
 	u32 root = power2(mem);
@@ -157,7 +157,7 @@ static int __cpuinit centaur_mcr_compute
 	return ct;
 }
 
-static void __cpuinit centaur_create_optimal_mcr(void)
+static void centaur_create_optimal_mcr(void)
 {
 	int used;
 	int i;
@@ -181,7 +181,7 @@ static void __cpuinit centaur_create_opt
 		wrmsr(MSR_IDT_MCR0+i, 0, 0);
 }
 
-static void __cpuinit winchip2_create_optimal_mcr(void)
+static void winchip2_create_optimal_mcr(void)
 {
 	u32 lo, hi;
 	int used;
@@ -217,7 +217,7 @@ static void __cpuinit winchip2_create_op
 /*
  * Handle the MCR key on the Winchip 2.
  */
-static void __cpuinit winchip2_unprotect_mcr(void)
+static void winchip2_unprotect_mcr(void)
 {
 	u32 lo, hi;
 	u32 key;
@@ -229,7 +229,7 @@ static void __cpuinit winchip2_unprotect
 	wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
 }
 
-static void __cpuinit winchip2_protect_mcr(void)
+static void winchip2_protect_mcr(void)
 {
 	u32 lo, hi;
 
@@ -247,7 +247,7 @@ static void __cpuinit winchip2_protect_m
 #define RNG_ENABLED	(1 << 3)
 #define RNG_ENABLE	(1 << 6)	/* MSR_VIA_RNG */
 
-static void __cpuinit init_c3(struct cpuinfo_x86 *c)
+static void init_c3(struct cpuinfo_x86 *c)
 {
 	u32  lo, hi;
 
@@ -318,7 +318,7 @@ enum {
 		EAMD3D		= 1<<20,
 };
 
-static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
+static void early_init_centaur(struct cpuinfo_x86 *c)
 {
 	switch (c->x86) {
 #ifdef CONFIG_X86_32
@@ -337,7 +337,7 @@ static void __cpuinit early_init_centaur
 #endif
 }
 
-static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
+static void init_centaur(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_32
 	char *name;
@@ -468,7 +468,7 @@ static void __cpuinit init_centaur(struc
 #endif
 }
 
-static unsigned int __cpuinit
+static unsigned int
 centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size)
 {
 #ifdef CONFIG_X86_32
@@ -488,7 +488,7 @@ centaur_size_cache(struct cpuinfo_x86 *c
 	return size;
 }
 
-static const struct cpu_dev __cpuinitconst centaur_cpu_dev = {
+static const struct cpu_dev centaur_cpu_dev = {
 	.c_vendor	= "Centaur",
 	.c_ident	= { "CentaurHauls" },
 	.c_early_init	= early_init_centaur,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/common.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/common.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,7 +63,7 @@ void __init setup_cpu_local_masks(void)
 	alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
 }
 
-static void __cpuinit default_init(struct cpuinfo_x86 *c)
+static void default_init(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_64
 	cpu_detect_cache_sizes(c);
@@ -80,13 +80,13 @@ static void __cpuinit default_init(struc
 #endif
 }
 
-static const struct cpu_dev __cpuinitconst default_cpu = {
+static const struct cpu_dev default_cpu = {
 	.c_init		= default_init,
 	.c_vendor	= "Unknown",
 	.c_x86_vendor	= X86_VENDOR_UNKNOWN,
 };
 
-static const struct cpu_dev *this_cpu __cpuinitdata = &default_cpu;
+static const struct cpu_dev *this_cpu = &default_cpu;
 
 DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
 #ifdef CONFIG_X86_64
@@ -160,8 +160,8 @@ static int __init x86_xsaveopt_setup(cha
 __setup("noxsaveopt", x86_xsaveopt_setup);
 
 #ifdef CONFIG_X86_32
-static int cachesize_override __cpuinitdata = -1;
-static int disable_x86_serial_nr __cpuinitdata = 1;
+static int cachesize_override = -1;
+static int disable_x86_serial_nr = 1;
 
 static int __init cachesize_setup(char *str)
 {
@@ -215,12 +215,12 @@ static inline int flag_is_changeable_p(u
 }
 
 /* Probe for the CPUID instruction */
-int __cpuinit have_cpuid_p(void)
+int have_cpuid_p(void)
 {
 	return flag_is_changeable_p(X86_EFLAGS_ID);
 }
 
-static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
+static void squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
 {
 	unsigned long lo, hi;
 
@@ -298,7 +298,7 @@ struct cpuid_dependent_feature {
 	u32 level;
 };
 
-static const struct cpuid_dependent_feature __cpuinitconst
+static const struct cpuid_dependent_feature
 cpuid_dependent_features[] = {
 	{ X86_FEATURE_MWAIT,		0x00000005 },
 	{ X86_FEATURE_DCA,		0x00000009 },
@@ -306,7 +306,7 @@ cpuid_dependent_features[] = {
 	{ 0, 0 }
 };
 
-static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
+static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
 {
 	const struct cpuid_dependent_feature *df;
 
@@ -344,7 +344,7 @@ static void __cpuinit filter_cpuid_featu
  */
 
 /* Look up CPU names by table lookup. */
-static const char *__cpuinit table_lookup_model(struct cpuinfo_x86 *c)
+static const char *table_lookup_model(struct cpuinfo_x86 *c)
 {
 	const struct cpu_model_info *info;
 
@@ -364,8 +364,8 @@ static const char *__cpuinit table_looku
 	return NULL;		/* Not found */
 }
 
-__u32 cpu_caps_cleared[NCAPINTS] __cpuinitdata;
-__u32 cpu_caps_set[NCAPINTS] __cpuinitdata;
+__u32 cpu_caps_cleared[NCAPINTS];
+__u32 cpu_caps_set[NCAPINTS];
 
 void load_percpu_segment(int cpu)
 {
@@ -394,9 +394,9 @@ void switch_to_new_gdt(int cpu)
 	load_percpu_segment(cpu);
 }
 
-static const struct cpu_dev *__cpuinitdata cpu_devs[X86_VENDOR_NUM] = {};
+static const struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {};
 
-static void __cpuinit get_model_name(struct cpuinfo_x86 *c)
+static void get_model_name(struct cpuinfo_x86 *c)
 {
 	unsigned int *v;
 	char *p, *q;
@@ -425,7 +425,7 @@ static void __cpuinit get_model_name(str
 	}
 }
 
-void __cpuinit cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
+void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
 {
 	unsigned int n, dummy, ebx, ecx, edx, l2size;
 
@@ -479,7 +479,7 @@ u16 __read_mostly tlb_lld_4m[NR_INFO];
  */
 s8  __read_mostly tlb_flushall_shift = -1;
 
-void __cpuinit cpu_detect_tlb(struct cpuinfo_x86 *c)
+void cpu_detect_tlb(struct cpuinfo_x86 *c)
 {
 	if (this_cpu->c_detect_tlb)
 		this_cpu->c_detect_tlb(c);
@@ -493,7 +493,7 @@ void __cpuinit cpu_detect_tlb(struct cpu
 		tlb_flushall_shift);
 }
 
-void __cpuinit detect_ht(struct cpuinfo_x86 *c)
+void detect_ht(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_HT
 	u32 eax, ebx, ecx, edx;
@@ -544,7 +544,7 @@ out:
 #endif
 }
 
-static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
+static void get_cpu_vendor(struct cpuinfo_x86 *c)
 {
 	char *v = c->x86_vendor_id;
 	int i;
@@ -571,7 +571,7 @@ static void __cpuinit get_cpu_vendor(str
 	this_cpu = &default_cpu;
 }
 
-void __cpuinit cpu_detect(struct cpuinfo_x86 *c)
+void cpu_detect(struct cpuinfo_x86 *c)
 {
 	/* Get vendor name */
 	cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
@@ -601,7 +601,7 @@ void __cpuinit cpu_detect(struct cpuinfo
 	}
 }
 
-void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
+void get_cpu_cap(struct cpuinfo_x86 *c)
 {
 	u32 tfms, xlvl;
 	u32 ebx;
@@ -652,7 +652,7 @@ void __cpuinit get_cpu_cap(struct cpuinf
 	init_scattered_cpuid_features(c);
 }
 
-static void __cpuinit identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
+static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_32
 	int i;
@@ -711,10 +711,9 @@ static void __init early_identify_cpu(st
 		return;
 
 	cpu_detect(c);
-
 	get_cpu_vendor(c);
-
 	get_cpu_cap(c);
+	fpu_detect(c);
 
 	if (this_cpu->c_early_init)
 		this_cpu->c_early_init(c);
@@ -724,6 +723,8 @@ static void __init early_identify_cpu(st
 
 	if (this_cpu->c_bsp_init)
 		this_cpu->c_bsp_init(c);
+
+	setup_force_cpu_cap(X86_FEATURE_ALWAYS);
 }
 
 void __init early_cpu_init(void)
@@ -768,7 +769,7 @@ void __init early_cpu_init(void)
  * unless we can find a reliable way to detect all the broken cases.
  * Enable it explicitly on 64-bit for non-constant inputs of cpu_has().
  */
-static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
+static void detect_nopl(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_32
 	clear_cpu_cap(c, X86_FEATURE_NOPL);
@@ -777,7 +778,7 @@ static void __cpuinit detect_nopl(struct
 #endif
 }
 
-static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
+static void generic_identify(struct cpuinfo_x86 *c)
 {
 	c->extended_cpuid_level = 0;
 
@@ -814,7 +815,7 @@ static void __cpuinit generic_identify(s
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
-static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
+static void identify_cpu(struct cpuinfo_x86 *c)
 {
 	int i;
 
@@ -959,7 +960,7 @@ void __init identify_boot_cpu(void)
 	cpu_detect_tlb(&boot_cpu_data);
 }
 
-void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c)
+void identify_secondary_cpu(struct cpuinfo_x86 *c)
 {
 	BUG_ON(c == &boot_cpu_data);
 	identify_cpu(c);
@@ -974,14 +975,14 @@ struct msr_range {
 	unsigned	max;
 };
 
-static const struct msr_range msr_range_array[] __cpuinitconst = {
+static const struct msr_range msr_range_array[] = {
 	{ 0x00000000, 0x00000418},
 	{ 0xc0000000, 0xc000040b},
 	{ 0xc0010000, 0xc0010142},
 	{ 0xc0011000, 0xc001103b},
 };
 
-static void __cpuinit __print_cpu_msr(void)
+static void __print_cpu_msr(void)
 {
 	unsigned index_min, index_max;
 	unsigned index;
@@ -1000,7 +1001,7 @@ static void __cpuinit __print_cpu_msr(vo
 	}
 }
 
-static int show_msr __cpuinitdata;
+static int show_msr;
 
 static __init int setup_show_msr(char *arg)
 {
@@ -1021,7 +1022,7 @@ static __init int setup_noclflush(char *
 }
 __setup("noclflush", setup_noclflush);
 
-void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
+void print_cpu_info(struct cpuinfo_x86 *c)
 {
 	const char *vendor = NULL;
 
@@ -1050,7 +1051,7 @@ void __cpuinit print_cpu_info(struct cpu
 	print_cpu_msr(c);
 }
 
-void __cpuinit print_cpu_msr(struct cpuinfo_x86 *c)
+void print_cpu_msr(struct cpuinfo_x86 *c)
 {
 	if (c->cpu_index < show_msr)
 		__print_cpu_msr();
@@ -1071,8 +1072,8 @@ __setup("clearcpuid=", setup_disablecpui
 
 #ifdef CONFIG_X86_64
 struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table };
-struct desc_ptr nmi_idt_descr = { NR_VECTORS * 16 - 1,
-				    (unsigned long) nmi_idt_table };
+struct desc_ptr debug_idt_descr = { NR_VECTORS * 16 - 1,
+				    (unsigned long) debug_idt_table };
 
 DEFINE_PER_CPU_FIRST(union irq_stack_union,
 		     irq_stack_union) __aligned(PAGE_SIZE);
@@ -1148,20 +1149,20 @@ int is_debug_stack(unsigned long addr)
 		 addr > (__get_cpu_var(debug_stack_addr) - DEBUG_STKSZ));
 }
 
-static DEFINE_PER_CPU(u32, debug_stack_use_ctr);
+DEFINE_PER_CPU(u32, debug_idt_ctr);
 
 void debug_stack_set_zero(void)
 {
-	this_cpu_inc(debug_stack_use_ctr);
-	load_idt((const struct desc_ptr *)&nmi_idt_descr);
+	this_cpu_inc(debug_idt_ctr);
+	load_current_idt();
 }
 
 void debug_stack_reset(void)
 {
-	if (WARN_ON(!this_cpu_read(debug_stack_use_ctr)))
+	if (WARN_ON(!this_cpu_read(debug_idt_ctr)))
 		return;
-	if (this_cpu_dec_return(debug_stack_use_ctr) == 0)
-		load_idt((const struct desc_ptr *)&idt_descr);
+	if (this_cpu_dec_return(debug_idt_ctr) == 0)
+		load_current_idt();
 }
 
 #else	/* CONFIG_X86_64 */
@@ -1215,7 +1216,7 @@ static void dbg_restore_debug_regs(void)
  */
 #ifdef CONFIG_X86_64
 
-void __cpuinit cpu_init(void)
+void cpu_init(void)
 {
 	struct orig_ist *oist;
 	struct task_struct *me;
@@ -1257,7 +1258,7 @@ void __cpuinit cpu_init(void)
 	switch_to_new_gdt(cpu);
 	loadsegment(fs, 0);
 
-	load_idt((const struct desc_ptr *)&idt_descr);
+	load_current_idt();
 
 	memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
 	syscall_init();
@@ -1314,7 +1315,7 @@ void __cpuinit cpu_init(void)
 
 #else
 
-void __cpuinit cpu_init(void)
+void cpu_init(void)
 {
 	int cpu = smp_processor_id();
 	struct task_struct *curr = current;
@@ -1334,7 +1335,7 @@ void __cpuinit cpu_init(void)
 	if (cpu_has_vme || cpu_has_tsc || cpu_has_de)
 		clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
 
-	load_idt(&idt_descr);
+	load_current_idt();
 	switch_to_new_gdt(cpu);
 
 	/*
@@ -1363,3 +1364,17 @@ void __cpuinit cpu_init(void)
 	fpu_init();
 }
 #endif
+
+#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
+void warn_pre_alternatives(void)
+{
+	WARN(1, "You're using static_cpu_has before alternatives have run!\n");
+}
+EXPORT_SYMBOL_GPL(warn_pre_alternatives);
+#endif
+
+inline bool __static_cpu_has_safe(u16 bit)
+{
+	return boot_cpu_has(bit);
+}
+EXPORT_SYMBOL_GPL(__static_cpu_has_safe);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/cyrix.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/cyrix.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/cyrix.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/cyrix.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,7 @@
 /*
  * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
  */
-static void __cpuinit __do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+static void __do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
 {
 	unsigned char ccr2, ccr3;
 
@@ -44,7 +44,7 @@ static void __cpuinit __do_cyrix_devid(u
 	}
 }
 
-static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
+static void do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
 {
 	unsigned long flags;
 
@@ -59,25 +59,25 @@ static void __cpuinit do_cyrix_devid(uns
  * Actually since bugs.h doesn't even reference this perhaps someone should
  * fix the documentation ???
  */
-static unsigned char Cx86_dir0_msb __cpuinitdata = 0;
+static unsigned char Cx86_dir0_msb = 0;
 
-static const char __cpuinitconst Cx86_model[][9] = {
+static const char Cx86_model[][9] = {
 	"Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ",
 	"M II ", "Unknown"
 };
-static const char __cpuinitconst Cx486_name[][5] = {
+static const char Cx486_name[][5] = {
 	"SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx",
 	"SRx2", "DRx2"
 };
-static const char __cpuinitconst Cx486S_name[][4] = {
+static const char Cx486S_name[][4] = {
 	"S", "S2", "Se", "S2e"
 };
-static const char __cpuinitconst Cx486D_name[][4] = {
+static const char Cx486D_name[][4] = {
 	"DX", "DX2", "?", "?", "?", "DX4"
 };
-static char Cx86_cb[] __cpuinitdata = "?.5x Core/Bus Clock";
-static const char __cpuinitconst cyrix_model_mult1[] = "12??43";
-static const char __cpuinitconst cyrix_model_mult2[] = "12233445";
+static char Cx86_cb[] = "?.5x Core/Bus Clock";
+static const char cyrix_model_mult1[] = "12??43";
+static const char cyrix_model_mult2[] = "12233445";
 
 /*
  * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old
@@ -87,7 +87,7 @@ static const char __cpuinitconst cyrix_m
  * FIXME: our newer udelay uses the tsc. We don't need to frob with SLOP
  */
 
-static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c)
+static void check_cx686_slop(struct cpuinfo_x86 *c)
 {
 	unsigned long flags;
 
@@ -112,7 +112,7 @@ static void __cpuinit check_cx686_slop(s
 }
 
 
-static void __cpuinit set_cx86_reorder(void)
+static void set_cx86_reorder(void)
 {
 	u8 ccr3;
 
@@ -127,7 +127,7 @@ static void __cpuinit set_cx86_reorder(v
 	setCx86(CX86_CCR3, ccr3);
 }
 
-static void __cpuinit set_cx86_memwb(void)
+static void set_cx86_memwb(void)
 {
 	printk(KERN_INFO "Enable Memory-Write-back mode on Cyrix/NSC processor.\n");
 
@@ -143,7 +143,7 @@ static void __cpuinit set_cx86_memwb(voi
  *	Configure later MediaGX and/or Geode processor.
  */
 
-static void __cpuinit geode_configure(void)
+static void geode_configure(void)
 {
 	unsigned long flags;
 	u8 ccr3;
@@ -166,7 +166,7 @@ static void __cpuinit geode_configure(vo
 	local_irq_restore(flags);
 }
 
-static void __cpuinit early_init_cyrix(struct cpuinfo_x86 *c)
+static void early_init_cyrix(struct cpuinfo_x86 *c)
 {
 	unsigned char dir0, dir0_msn, dir1 = 0;
 
@@ -185,7 +185,7 @@ static void __cpuinit early_init_cyrix(s
 	}
 }
 
-static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
+static void init_cyrix(struct cpuinfo_x86 *c)
 {
 	unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;
 	char *buf = c->x86_model_id;
@@ -333,7 +333,7 @@ static void __cpuinit init_cyrix(struct
 		switch (dir0_lsn) {
 		case 0xd:  /* either a 486SLC or DLC w/o DEVID */
 			dir0_msn = 0;
-			p = Cx486_name[(c->hard_math) ? 1 : 0];
+			p = Cx486_name[(cpu_has_fpu ? 1 : 0)];
 			break;
 
 		case 0xe:  /* a 486S A step */
@@ -356,7 +356,7 @@ static void __cpuinit init_cyrix(struct
 /*
  * Handle National Semiconductor branded processors
  */
-static void __cpuinit init_nsc(struct cpuinfo_x86 *c)
+static void init_nsc(struct cpuinfo_x86 *c)
 {
 	/*
 	 * There may be GX1 processors in the wild that are branded
@@ -405,7 +405,7 @@ static inline int test_cyrix_52div(void)
 	return (unsigned char) (test >> 8) == 0x02;
 }
 
-static void __cpuinit cyrix_identify(struct cpuinfo_x86 *c)
+static void cyrix_identify(struct cpuinfo_x86 *c)
 {
 	/* Detect Cyrix with disabled CPUID */
 	if (c->x86 == 4 && test_cyrix_52div()) {
@@ -441,7 +441,7 @@ static void __cpuinit cyrix_identify(str
 	}
 }
 
-static const struct cpu_dev __cpuinitconst cyrix_cpu_dev = {
+static const struct cpu_dev cyrix_cpu_dev = {
 	.c_vendor	= "Cyrix",
 	.c_ident	= { "CyrixInstead" },
 	.c_early_init	= early_init_cyrix,
@@ -452,7 +452,7 @@ static const struct cpu_dev __cpuinitcon
 
 cpu_dev_register(cyrix_cpu_dev);
 
-static const struct cpu_dev __cpuinitconst nsc_cpu_dev = {
+static const struct cpu_dev nsc_cpu_dev = {
 	.c_vendor	= "NSC",
 	.c_ident	= { "Geode by NSC" },
 	.c_init		= init_nsc,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/hypervisor.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/hypervisor.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/hypervisor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/hypervisor.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,7 +60,7 @@ detect_hypervisor_vendor(void)
 	}
 }
 
-void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
+void init_hypervisor(struct cpuinfo_x86 *c)
 {
 	if (x86_hyper && x86_hyper->set_cpu_features)
 		x86_hyper->set_cpu_features(c);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/intel.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/intel.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/intel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/intel.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,7 @@
 #include <asm/apic.h>
 #endif
 
-static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
+static void early_init_intel(struct cpuinfo_x86 *c)
 {
 	u64 misc_enable;
 
@@ -163,7 +163,7 @@ static void __cpuinit early_init_intel(s
  *	This is called before we do cpu ident work
  */
 
-int __cpuinit ppro_with_ram_bug(void)
+int ppro_with_ram_bug(void)
 {
 	/* Uses data from early_cpu_detect now */
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
@@ -176,7 +176,7 @@ int __cpuinit ppro_with_ram_bug(void)
 	return 0;
 }
 
-static void __cpuinit intel_smp_check(struct cpuinfo_x86 *c)
+static void intel_smp_check(struct cpuinfo_x86 *c)
 {
 	/* calling is from identify_secondary_cpu() ? */
 	if (!c->cpu_index)
@@ -196,7 +196,7 @@ static void __cpuinit intel_smp_check(st
 	}
 }
 
-static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
+static void intel_workarounds(struct cpuinfo_x86 *c)
 {
 	unsigned long lo, hi;
 
@@ -275,12 +275,12 @@ static void __cpuinit intel_workarounds(
 	intel_smp_check(c);
 }
 #else
-static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
+static void intel_workarounds(struct cpuinfo_x86 *c)
 {
 }
 #endif
 
-static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
+static void srat_detect_node(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_NUMA
 	unsigned node;
@@ -300,7 +300,7 @@ static void __cpuinit srat_detect_node(s
 /*
  * find out the number of processor cores on the die
  */
-static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
+static int intel_num_cpu_cores(struct cpuinfo_x86 *c)
 {
 	unsigned int eax, ebx, ecx, edx;
 
@@ -315,7 +315,7 @@ static int __cpuinit intel_num_cpu_cores
 		return 1;
 }
 
-static void __cpuinit detect_vmx_virtcap(struct cpuinfo_x86 *c)
+static void detect_vmx_virtcap(struct cpuinfo_x86 *c)
 {
 	/* Intel VMX MSR indicated features */
 #define X86_VMX_FEATURE_PROC_CTLS_TPR_SHADOW	0x00200000
@@ -353,7 +353,7 @@ static void __cpuinit detect_vmx_virtcap
 	}
 }
 
-static void __cpuinit init_intel(struct cpuinfo_x86 *c)
+static void init_intel(struct cpuinfo_x86 *c)
 {
 	unsigned int l2 = 0;
 
@@ -472,7 +472,7 @@ static void __cpuinit init_intel(struct
 }
 
 #ifdef CONFIG_X86_32
-static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
+static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
 {
 	/*
 	 * Intel PIII Tualatin. This comes in two flavours.
@@ -506,7 +506,7 @@ static unsigned int __cpuinit intel_size
 
 #define STLB_4K		0x41
 
-static const struct _tlb_table intel_tlb_table[] __cpuinitconst = {
+static const struct _tlb_table intel_tlb_table[] = {
 	{ 0x01, TLB_INST_4K,		32,	" TLB_INST 4 KByte pages, 4-way set associative" },
 	{ 0x02, TLB_INST_4M,		2,	" TLB_INST 4 MByte pages, full associative" },
 	{ 0x03, TLB_DATA_4K,		64,	" TLB_DATA 4 KByte pages, 4-way set associative" },
@@ -536,7 +536,7 @@ static const struct _tlb_table intel_tlb
 	{ 0x00, 0, 0 }
 };
 
-static void __cpuinit intel_tlb_lookup(const unsigned char desc)
+static void intel_tlb_lookup(const unsigned char desc)
 {
 	unsigned char k;
 	if (desc == 0)
@@ -605,7 +605,7 @@ static void __cpuinit intel_tlb_lookup(c
 	}
 }
 
-static void __cpuinit intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c)
+static void intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c)
 {
 	switch ((c->x86 << 8) + c->x86_model) {
 	case 0x60f: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
@@ -634,7 +634,7 @@ static void __cpuinit intel_tlb_flushall
 	}
 }
 
-static void __cpuinit intel_detect_tlb(struct cpuinfo_x86 *c)
+static void intel_detect_tlb(struct cpuinfo_x86 *c)
 {
 	int i, j, n;
 	unsigned int regs[4];
@@ -661,7 +661,7 @@ static void __cpuinit intel_detect_tlb(s
 	intel_tlb_flushall_shift_set(c);
 }
 
-static const struct cpu_dev __cpuinitconst intel_cpu_dev = {
+static const struct cpu_dev intel_cpu_dev = {
 	.c_vendor	= "Intel",
 	.c_ident	= { "GenuineIntel" },
 #ifdef CONFIG_X86_32
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/intel_cacheinfo.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/intel_cacheinfo.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/intel_cacheinfo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/intel_cacheinfo.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,7 @@ struct _cache_table {
 /* All the cache descriptor types we care about (no TLB or
    trace cache entries) */
 
-static const struct _cache_table __cpuinitconst cache_table[] =
+static const struct _cache_table cache_table[] =
 {
 	{ 0x06, LVL_1_INST, 8 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x08, LVL_1_INST, 16 },	/* 4-way set assoc, 32 byte line size */
@@ -203,7 +203,7 @@ union l3_cache {
 	unsigned val;
 };
 
-static const unsigned short __cpuinitconst assocs[] = {
+static const unsigned short assocs[] = {
 	[1] = 1,
 	[2] = 2,
 	[4] = 4,
@@ -217,10 +217,10 @@ static const unsigned short __cpuinitcon
 	[0xf] = 0xffff /* fully associative - no way to show this currently */
 };
 
-static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
-static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
+static const unsigned char levels[] = { 1, 1, 2, 3 };
+static const unsigned char types[] = { 1, 2, 3, 3 };
 
-static void __cpuinit
+static void
 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 		     union _cpuid4_leaf_ebx *ebx,
 		     union _cpuid4_leaf_ecx *ecx)
@@ -302,7 +302,7 @@ struct _cache_attr {
 /*
  * L3 cache descriptors
  */
-static void __cpuinit amd_calc_l3_indices(struct amd_northbridge *nb)
+static void amd_calc_l3_indices(struct amd_northbridge *nb)
 {
 	struct amd_l3_cache *l3 = &nb->l3_cache;
 	unsigned int sc0, sc1, sc2, sc3;
@@ -325,7 +325,7 @@ static void __cpuinit amd_calc_l3_indice
 	l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1;
 }
 
-static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index)
+static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index)
 {
 	int node;
 
@@ -528,8 +528,7 @@ static struct _cache_attr subcaches =
 #endif  /* CONFIG_AMD_NB && CONFIG_SYSFS */
 
 static int
-__cpuinit cpuid4_cache_lookup_regs(int index,
-				   struct _cpuid4_info_regs *this_leaf)
+cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf)
 {
 	union _cpuid4_leaf_eax	eax;
 	union _cpuid4_leaf_ebx	ebx;
@@ -560,7 +559,7 @@ __cpuinit cpuid4_cache_lookup_regs(int i
 	return 0;
 }
 
-static int __cpuinit find_num_cache_leaves(struct cpuinfo_x86 *c)
+static int find_num_cache_leaves(struct cpuinfo_x86 *c)
 {
 	unsigned int		eax, ebx, ecx, edx, op;
 	union _cpuid4_leaf_eax	cache_eax;
@@ -580,7 +579,7 @@ static int __cpuinit find_num_cache_leav
 	return i;
 }
 
-void __cpuinit init_amd_cacheinfo(struct cpuinfo_x86 *c)
+void init_amd_cacheinfo(struct cpuinfo_x86 *c)
 {
 
 	if (cpu_has_topoext) {
@@ -593,7 +592,7 @@ void __cpuinit init_amd_cacheinfo(struct
 	}
 }
 
-unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
+unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
 	/* Cache sizes */
 	unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
@@ -618,36 +617,34 @@ unsigned int __cpuinit init_intel_cachei
 		 * parameters cpuid leaf to find the cache details
 		 */
 		for (i = 0; i < num_cache_leaves; i++) {
-			struct _cpuid4_info_regs this_leaf;
+			struct _cpuid4_info_regs this_leaf = {};
 			int retval;
 
 			retval = cpuid4_cache_lookup_regs(i, &this_leaf);
-			if (retval >= 0) {
-				switch (this_leaf.eax.split.level) {
-				case 1:
-					if (this_leaf.eax.split.type ==
-							CACHE_TYPE_DATA)
-						new_l1d = this_leaf.size/1024;
-					else if (this_leaf.eax.split.type ==
-							CACHE_TYPE_INST)
-						new_l1i = this_leaf.size/1024;
-					break;
-				case 2:
-					new_l2 = this_leaf.size/1024;
-					num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
-					index_msb = get_count_order(num_threads_sharing);
-					l2_id = c->apicid & ~((1 << index_msb) - 1);
-					break;
-				case 3:
-					new_l3 = this_leaf.size/1024;
-					num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
-					index_msb = get_count_order(
-							num_threads_sharing);
-					l3_id = c->apicid & ~((1 << index_msb) - 1);
-					break;
-				default:
-					break;
-				}
+			if (retval < 0)
+				continue;
+
+			switch (this_leaf.eax.split.level) {
+			case 1:
+				if (this_leaf.eax.split.type == CACHE_TYPE_DATA)
+					new_l1d = this_leaf.size/1024;
+				else if (this_leaf.eax.split.type == CACHE_TYPE_INST)
+					new_l1i = this_leaf.size/1024;
+				break;
+			case 2:
+				new_l2 = this_leaf.size/1024;
+				num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
+				index_msb = get_count_order(num_threads_sharing);
+				l2_id = c->apicid & ~((1 << index_msb) - 1);
+				break;
+			case 3:
+				new_l3 = this_leaf.size/1024;
+				num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
+				index_msb = get_count_order(num_threads_sharing);
+				l3_id = c->apicid & ~((1 << index_msb) - 1);
+				break;
+			default:
+				break;
 			}
 		}
 	}
@@ -746,7 +743,7 @@ static DEFINE_PER_CPU(struct _cpuid4_inf
 
 #ifdef CONFIG_SMP
 
-static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
+static int cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
 {
 	struct _cpuid4_info *this_leaf;
 	int i, sibling;
@@ -795,7 +792,7 @@ static int __cpuinit cache_shared_amd_cp
 	return 1;
 }
 
-static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+static void cache_shared_cpu_map_setup(unsigned int cpu, int index)
 {
 	struct _cpuid4_info *this_leaf, *sibling_leaf;
 	unsigned long num_threads_sharing;
@@ -830,7 +827,7 @@ static void __cpuinit cache_shared_cpu_m
 		}
 	}
 }
-static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
+static void cache_remove_shared_cpu_map(unsigned int cpu, int index)
 {
 	struct _cpuid4_info	*this_leaf, *sibling_leaf;
 	int sibling;
@@ -843,16 +840,16 @@ static void __cpuinit cache_remove_share
 	}
 }
 #else
-static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+static void cache_shared_cpu_map_setup(unsigned int cpu, int index)
 {
 }
 
-static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
+static void cache_remove_shared_cpu_map(unsigned int cpu, int index)
 {
 }
 #endif
 
-static void __cpuinit free_cache_attributes(unsigned int cpu)
+static void free_cache_attributes(unsigned int cpu)
 {
 	int i;
 
@@ -863,7 +860,7 @@ static void __cpuinit free_cache_attribu
 	per_cpu(ici_cpuid4_info, cpu) = NULL;
 }
 
-static void __cpuinit get_cpu_leaves(void *_retval)
+static void get_cpu_leaves(void *_retval)
 {
 	int j, *retval = _retval, cpu = smp_processor_id();
 
@@ -883,7 +880,7 @@ static void __cpuinit get_cpu_leaves(voi
 	}
 }
 
-static int __cpuinit detect_cache_attributes(unsigned int cpu)
+static int detect_cache_attributes(unsigned int cpu)
 {
 	int			retval;
 
@@ -1017,7 +1014,7 @@ static struct attribute *default_attrs[]
 };
 
 #ifdef CONFIG_AMD_NB
-static struct attribute ** __cpuinit amd_l3_attrs(void)
+static struct attribute **amd_l3_attrs(void)
 {
 	static struct attribute **attrs;
 	int n;
@@ -1093,7 +1090,7 @@ static struct kobj_type ktype_percpu_ent
 	.sysfs_ops	= &sysfs_ops,
 };
 
-static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
+static void cpuid4_cache_sysfs_exit(unsigned int cpu)
 {
 	kfree(per_cpu(ici_cache_kobject, cpu));
 	kfree(per_cpu(ici_index_kobject, cpu));
@@ -1102,7 +1099,7 @@ static void __cpuinit cpuid4_cache_sysfs
 	free_cache_attributes(cpu);
 }
 
-static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
+static int cpuid4_cache_sysfs_init(unsigned int cpu)
 {
 	int err;
 
@@ -1134,7 +1131,7 @@ err_out:
 static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
 
 /* Add/Remove cache interface for CPU device */
-static int __cpuinit cache_add_dev(struct device *dev)
+static int cache_add_dev(struct device *dev)
 {
 	unsigned int cpu = dev->id;
 	unsigned long i, j;
@@ -1185,7 +1182,7 @@ static int __cpuinit cache_add_dev(struc
 	return 0;
 }
 
-static void __cpuinit cache_remove_dev(struct device *dev)
+static void cache_remove_dev(struct device *dev)
 {
 	unsigned int cpu = dev->id;
 	unsigned long i;
@@ -1202,8 +1199,8 @@ static void __cpuinit cache_remove_dev(s
 	cpuid4_cache_sysfs_exit(cpu);
 }
 
-static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
-					unsigned long action, void *hcpu)
+static int cacheinfo_cpu_callback(struct notifier_block *nfb,
+				  unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
 	struct device *dev;
@@ -1222,7 +1219,7 @@ static int __cpuinit cacheinfo_cpu_callb
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
+static struct notifier_block cacheinfo_cpu_notifier = {
 	.notifier_call = cacheinfo_cpu_callback,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/Makefile linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/Makefile
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -31,11 +31,15 @@ obj-$(CONFIG_PERF_EVENTS)		+= perf_event
 
 ifdef CONFIG_PERF_EVENTS
 obj-$(CONFIG_CPU_SUP_AMD)		+= perf_event_amd.o perf_event_amd_uncore.o
+ifdef CONFIG_AMD_IOMMU
+obj-$(CONFIG_CPU_SUP_AMD)		+= perf_event_amd_iommu.o
+endif
 obj-$(CONFIG_CPU_SUP_INTEL)		+= perf_event_p6.o perf_event_knc.o perf_event_p4.o
 obj-$(CONFIG_CPU_SUP_INTEL)		+= perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o
 obj-$(CONFIG_CPU_SUP_INTEL)		+= perf_event_intel_uncore.o
 endif
 
+
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce_amd.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce_amd.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce_amd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce_amd.c	2013-08-25 20:43:22.000000000 -0400
@@ -458,10 +458,8 @@ static struct kobj_type threshold_ktype
 	.default_attrs		= default_attrs,
 };
 
-static __cpuinit int allocate_threshold_blocks(unsigned int cpu,
-					       unsigned int bank,
-					       unsigned int block,
-					       u32 address)
+static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank,
+				     unsigned int block, u32 address)
 {
 	struct threshold_block *b = NULL;
 	u32 low, high;
@@ -543,7 +541,7 @@ out_free:
 	return err;
 }
 
-static __cpuinit int __threshold_add_blocks(struct threshold_bank *b)
+static int __threshold_add_blocks(struct threshold_bank *b)
 {
 	struct list_head *head = &b->blocks->miscj;
 	struct threshold_block *pos = NULL;
@@ -567,7 +565,7 @@ static __cpuinit int __threshold_add_blo
 	return err;
 }
 
-static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
+static int threshold_create_bank(unsigned int cpu, unsigned int bank)
 {
 	struct device *dev = per_cpu(mce_device, cpu);
 	struct amd_northbridge *nb = NULL;
@@ -632,7 +630,7 @@ static __cpuinit int threshold_create_ba
 }
 
 /* create dir/files for all valid threshold banks */
-static __cpuinit int threshold_create_device(unsigned int cpu)
+static int threshold_create_device(unsigned int cpu)
 {
 	unsigned int bank;
 	struct threshold_bank **bp;
@@ -736,7 +734,7 @@ static void threshold_remove_device(unsi
 }
 
 /* get notified when a cpu comes on/off */
-static void __cpuinit
+static void
 amd_64_threshold_cpu_callback(unsigned long action, unsigned int cpu)
 {
 	switch (action) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce.c	2013-08-25 20:43:22.000000000 -0400
@@ -89,7 +89,10 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_chrde
 static DEFINE_PER_CPU(struct mce, mces_seen);
 static int			cpu_missing;
 
-/* MCA banks polled by the period polling timer for corrected events */
+/*
+ * MCA banks polled by the period polling timer for corrected events.
+ * With Intel CMCI, this only has MCA banks which do not support CMCI (if any).
+ */
 DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
 	[0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL
 };
@@ -1360,7 +1363,7 @@ int mce_notify_irq(void)
 }
 EXPORT_SYMBOL_GPL(mce_notify_irq);
 
-static int __cpuinit __mcheck_cpu_mce_banks_init(void)
+static int __mcheck_cpu_mce_banks_init(void)
 {
 	int i;
 	u8 num_banks = mca_cfg.banks;
@@ -1381,7 +1384,7 @@ static int __cpuinit __mcheck_cpu_mce_ba
 /*
  * Initialize Machine Checks for a CPU.
  */
-static int __cpuinit __mcheck_cpu_cap_init(void)
+static int __mcheck_cpu_cap_init(void)
 {
 	unsigned b;
 	u64 cap;
@@ -1480,7 +1483,7 @@ static void quirk_sandybridge_ifu(int ba
 }
 
 /* Add per CPU specific workarounds here */
-static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
+static int __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
 {
 	struct mca_config *cfg = &mca_cfg;
 
@@ -1590,7 +1593,7 @@ static int __cpuinit __mcheck_cpu_apply_
 	return 0;
 }
 
-static int __cpuinit __mcheck_cpu_ancient_init(struct cpuinfo_x86 *c)
+static int __mcheck_cpu_ancient_init(struct cpuinfo_x86 *c)
 {
 	if (c->x86 != 5)
 		return 0;
@@ -1661,7 +1664,7 @@ void (*machine_check_vector)(struct pt_r
  * Called for each booted CPU to set up machine checks.
  * Must be called with preempt off:
  */
-void __cpuinit mcheck_cpu_init(struct cpuinfo_x86 *c)
+void mcheck_cpu_init(struct cpuinfo_x86 *c)
 {
 	if (mca_cfg.disabled)
 		return;
@@ -2079,7 +2082,6 @@ static struct bus_type mce_subsys = {
 
 DEFINE_PER_CPU(struct device *, mce_device);
 
-__cpuinitdata
 void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
 
 static inline struct mce_bank *attr_to_bank(struct device_attribute *attr)
@@ -2225,7 +2227,7 @@ static void mce_device_release(struct de
 }
 
 /* Per cpu device init. All of the cpus still share the same ctrl bank: */
-static __cpuinit int mce_device_create(unsigned int cpu)
+static int mce_device_create(unsigned int cpu)
 {
 	struct device *dev;
 	int err;
@@ -2271,7 +2273,7 @@ error:
 	return err;
 }
 
-static __cpuinit void mce_device_remove(unsigned int cpu)
+static void mce_device_remove(unsigned int cpu)
 {
 	struct device *dev = per_cpu(mce_device, cpu);
 	int i;
@@ -2291,7 +2293,7 @@ static __cpuinit void mce_device_remove(
 }
 
 /* Make sure there are no machine checks on offlined CPUs. */
-static void __cpuinit mce_disable_cpu(void *h)
+static void mce_disable_cpu(void *h)
 {
 	unsigned long action = *(unsigned long *)h;
 	int i;
@@ -2309,7 +2311,7 @@ static void __cpuinit mce_disable_cpu(vo
 	}
 }
 
-static void __cpuinit mce_reenable_cpu(void *h)
+static void mce_reenable_cpu(void *h)
 {
 	unsigned long action = *(unsigned long *)h;
 	int i;
@@ -2328,7 +2330,7 @@ static void __cpuinit mce_reenable_cpu(v
 }
 
 /* Get notified when a cpu comes on/off. Be hotplug friendly. */
-static int __cpuinit
+static int
 mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
@@ -2364,7 +2366,7 @@ mce_cpu_callback(struct notifier_block *
 	return NOTIFY_OK;
 }
 
-static struct notifier_block mce_cpu_notifier __cpuinitdata = {
+static struct notifier_block mce_cpu_notifier = {
 	.notifier_call = mce_cpu_callback,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce-inject.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce-inject.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce-inject.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce-inject.c	2013-08-25 20:43:22.000000000 -0400
@@ -153,7 +153,7 @@ static void raise_mce(struct mce *m)
 		return;
 
 #ifdef CONFIG_X86_LOCAL_APIC
-	if (m->inject_flags & (MCJ_IRQ_BRAODCAST | MCJ_NMI_BROADCAST)) {
+	if (m->inject_flags & (MCJ_IRQ_BROADCAST | MCJ_NMI_BROADCAST)) {
 		unsigned long start;
 		int cpu;
 
@@ -167,7 +167,7 @@ static void raise_mce(struct mce *m)
 				cpumask_clear_cpu(cpu, mce_inject_cpumask);
 		}
 		if (!cpumask_empty(mce_inject_cpumask)) {
-			if (m->inject_flags & MCJ_IRQ_BRAODCAST) {
+			if (m->inject_flags & MCJ_IRQ_BROADCAST) {
 				/*
 				 * don't wait because mce_irq_ipi is necessary
 				 * to be sync with following raise_local
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce_intel.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce_intel.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce_intel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce_intel.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,18 @@
  * Also supports reliable discovery of shared banks.
  */
 
+/*
+ * CMCI can be delivered to multiple cpus that share a machine check bank
+ * so we need to designate a single cpu to process errors logged in each bank
+ * in the interrupt handler (otherwise we would have many races and potential
+ * double reporting of the same error).
+ * Note that this can change when a cpu is offlined or brought online since
+ * some MCA banks are shared across cpus. When a cpu is offlined, cmci_clear()
+ * disables CMCI on all banks owned by the cpu and clears this bitfield. At
+ * this point, cmci_rediscover() kicks in and a different cpu may end up
+ * taking ownership of some of the shared MCA banks that were previously
+ * owned by the offlined cpu.
+ */
 static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned);
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce-severity.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce-severity.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/mce-severity.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/mce-severity.c	2013-08-25 20:43:22.000000000 -0400
@@ -110,22 +110,17 @@ static struct severity {
 	/* known AR MCACODs: */
 #ifdef	CONFIG_MEMORY_FAILURE
 	MCESEV(
-		KEEP, "HT thread notices Action required: data load error",
-		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
-		MCGMASK(MCG_STATUS_EIPV, 0)
+		KEEP, "Action required but unaffected thread is continuable",
+		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR, MCI_UC_SAR|MCI_ADDR),
+		MCGMASK(MCG_STATUS_RIPV|MCG_STATUS_EIPV, MCG_STATUS_RIPV)
 		),
 	MCESEV(
-		AR, "Action required: data load error",
+		AR, "Action required: data load error in a user process",
 		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
 		USER
 		),
 	MCESEV(
-		KEEP, "HT thread notices Action required: instruction fetch error",
-		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR),
-		MCGMASK(MCG_STATUS_EIPV, 0)
-		),
-	MCESEV(
-		AR, "Action required: instruction fetch error",
+		AR, "Action required: instruction fetch error in a user process",
 		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR),
 		USER
 		),
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/therm_throt.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/therm_throt.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/therm_throt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/therm_throt.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,7 @@
 #include <asm/idle.h>
 #include <asm/mce.h>
 #include <asm/msr.h>
+#include <asm/trace/irq_vectors.h>
 
 /* How long to wait between reporting thermal events */
 #define CHECK_INTERVAL		(300 * HZ)
@@ -54,12 +55,24 @@ struct thermal_state {
 	struct _thermal_state package_power_limit;
 	struct _thermal_state core_thresh0;
 	struct _thermal_state core_thresh1;
+	struct _thermal_state pkg_thresh0;
+	struct _thermal_state pkg_thresh1;
 };
 
 /* Callback to handle core threshold interrupts */
 int (*platform_thermal_notify)(__u64 msr_val);
 EXPORT_SYMBOL(platform_thermal_notify);
 
+/* Callback to handle core package threshold_interrupts */
+int (*platform_thermal_package_notify)(__u64 msr_val);
+EXPORT_SYMBOL_GPL(platform_thermal_package_notify);
+
+/* Callback support of rate control, return true, if
+ * callback has rate control */
+bool (*platform_thermal_package_rate_control)(void);
+EXPORT_SYMBOL_GPL(platform_thermal_package_rate_control);
+
+
 static DEFINE_PER_CPU(struct thermal_state, thermal_state);
 
 static atomic_t therm_throt_en	= ATOMIC_INIT(0);
@@ -181,11 +194,6 @@ static int therm_throt_process(bool new_
 				this_cpu,
 				level == CORE_LEVEL ? "Core" : "Package",
 				state->count);
-		else
-			printk(KERN_CRIT "CPU%d: %s power limit notification (total events = %lu)\n",
-				this_cpu,
-				level == CORE_LEVEL ? "Core" : "Package",
-				state->count);
 		return 1;
 	}
 	if (old_event) {
@@ -193,36 +201,46 @@ static int therm_throt_process(bool new_
 			printk(KERN_INFO "CPU%d: %s temperature/speed normal\n",
 				this_cpu,
 				level == CORE_LEVEL ? "Core" : "Package");
-		else
-			printk(KERN_INFO "CPU%d: %s power limit normal\n",
-				this_cpu,
-				level == CORE_LEVEL ? "Core" : "Package");
 		return 1;
 	}
 
 	return 0;
 }
 
-static int thresh_event_valid(int event)
+static int thresh_event_valid(int level, int event)
 {
 	struct _thermal_state *state;
 	unsigned int this_cpu = smp_processor_id();
 	struct thermal_state *pstate = &per_cpu(thermal_state, this_cpu);
 	u64 now = get_jiffies_64();
 
-	state = (event == 0) ? &pstate->core_thresh0 : &pstate->core_thresh1;
+	if (level == PACKAGE_LEVEL)
+		state = (event == 0) ? &pstate->pkg_thresh0 :
+						&pstate->pkg_thresh1;
+	else
+		state = (event == 0) ? &pstate->core_thresh0 :
+						&pstate->core_thresh1;
 
 	if (time_before64(now, state->next_check))
 		return 0;
 
 	state->next_check = now + CHECK_INTERVAL;
+
+	return 1;
+}
+
+static bool int_pln_enable;
+static int __init int_pln_enable_setup(char *s)
+{
+	int_pln_enable = true;
+
 	return 1;
 }
+__setup("int_pln_enable", int_pln_enable_setup);
 
 #ifdef CONFIG_SYSFS
 /* Add/Remove thermal_throttle interface for CPU device: */
-static __cpuinit int thermal_throttle_add_dev(struct device *dev,
-				unsigned int cpu)
+static int thermal_throttle_add_dev(struct device *dev, unsigned int cpu)
 {
 	int err;
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
@@ -231,7 +249,7 @@ static __cpuinit int thermal_throttle_ad
 	if (err)
 		return err;
 
-	if (cpu_has(c, X86_FEATURE_PLN))
+	if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
 		err = sysfs_add_file_to_group(&dev->kobj,
 					      &dev_attr_core_power_limit_count.attr,
 					      thermal_attr_group.name);
@@ -239,7 +257,7 @@ static __cpuinit int thermal_throttle_ad
 		err = sysfs_add_file_to_group(&dev->kobj,
 					      &dev_attr_package_throttle_count.attr,
 					      thermal_attr_group.name);
-		if (cpu_has(c, X86_FEATURE_PLN))
+		if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
 			err = sysfs_add_file_to_group(&dev->kobj,
 					&dev_attr_package_power_limit_count.attr,
 					thermal_attr_group.name);
@@ -248,7 +266,7 @@ static __cpuinit int thermal_throttle_ad
 	return err;
 }
 
-static __cpuinit void thermal_throttle_remove_dev(struct device *dev)
+static void thermal_throttle_remove_dev(struct device *dev)
 {
 	sysfs_remove_group(&dev->kobj, &thermal_attr_group);
 }
@@ -257,7 +275,7 @@ static __cpuinit void thermal_throttle_r
 static DEFINE_MUTEX(therm_cpu_lock);
 
 /* Get notified when a cpu comes on/off. Be hotplug friendly. */
-static __cpuinit int
+static int
 thermal_throttle_cpu_callback(struct notifier_block *nfb,
 			      unsigned long action,
 			      void *hcpu)
@@ -288,7 +306,7 @@ thermal_throttle_cpu_callback(struct not
 	return notifier_from_errno(err);
 }
 
-static struct notifier_block thermal_throttle_cpu_notifier __cpuinitdata =
+static struct notifier_block thermal_throttle_cpu_notifier =
 {
 	.notifier_call = thermal_throttle_cpu_callback,
 };
@@ -321,6 +339,39 @@ device_initcall(thermal_throttle_init_de
 
 #endif /* CONFIG_SYSFS */
 
+static void notify_package_thresholds(__u64 msr_val)
+{
+	bool notify_thres_0 = false;
+	bool notify_thres_1 = false;
+
+	if (!platform_thermal_package_notify)
+		return;
+
+	/* lower threshold check */
+	if (msr_val & THERM_LOG_THRESHOLD0)
+		notify_thres_0 = true;
+	/* higher threshold check */
+	if (msr_val & THERM_LOG_THRESHOLD1)
+		notify_thres_1 = true;
+
+	if (!notify_thres_0 && !notify_thres_1)
+		return;
+
+	if (platform_thermal_package_rate_control &&
+		platform_thermal_package_rate_control()) {
+		/* Rate control is implemented in callback */
+		platform_thermal_package_notify(msr_val);
+		return;
+	}
+
+	/* lower threshold reached */
+	if (notify_thres_0 && thresh_event_valid(PACKAGE_LEVEL, 0))
+		platform_thermal_package_notify(msr_val);
+	/* higher threshold reached */
+	if (notify_thres_1 && thresh_event_valid(PACKAGE_LEVEL, 1))
+		platform_thermal_package_notify(msr_val);
+}
+
 static void notify_thresholds(__u64 msr_val)
 {
 	/* check whether the interrupt handler is defined;
@@ -330,10 +381,12 @@ static void notify_thresholds(__u64 msr_
 		return;
 
 	/* lower threshold reached */
-	if ((msr_val & THERM_LOG_THRESHOLD0) &&	thresh_event_valid(0))
+	if ((msr_val & THERM_LOG_THRESHOLD0) &&
+			thresh_event_valid(CORE_LEVEL, 0))
 		platform_thermal_notify(msr_val);
 	/* higher threshold reached */
-	if ((msr_val & THERM_LOG_THRESHOLD1) && thresh_event_valid(1))
+	if ((msr_val & THERM_LOG_THRESHOLD1) &&
+			thresh_event_valid(CORE_LEVEL, 1))
 		platform_thermal_notify(msr_val);
 }
 
@@ -352,17 +405,19 @@ static void intel_thermal_interrupt(void
 				CORE_LEVEL) != 0)
 		mce_log_therm_throt_event(msr_val);
 
-	if (this_cpu_has(X86_FEATURE_PLN))
+	if (this_cpu_has(X86_FEATURE_PLN) && int_pln_enable)
 		therm_throt_process(msr_val & THERM_STATUS_POWER_LIMIT,
 					POWER_LIMIT_EVENT,
 					CORE_LEVEL);
 
 	if (this_cpu_has(X86_FEATURE_PTS)) {
 		rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
+		/* check violations of package thermal thresholds */
+		notify_package_thresholds(msr_val);
 		therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT,
 					THERMAL_THROTTLING_EVENT,
 					PACKAGE_LEVEL);
-		if (this_cpu_has(X86_FEATURE_PLN))
+		if (this_cpu_has(X86_FEATURE_PLN) && int_pln_enable)
 			therm_throt_process(msr_val &
 					PACKAGE_THERM_STATUS_POWER_LIMIT,
 					POWER_LIMIT_EVENT,
@@ -378,15 +433,26 @@ static void unexpected_thermal_interrupt
 
 static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt;
 
-asmlinkage void smp_thermal_interrupt(struct pt_regs *regs)
+static inline void __smp_thermal_interrupt(void)
 {
-	irq_enter();
-	exit_idle();
 	inc_irq_stat(irq_thermal_count);
 	smp_thermal_vector();
-	irq_exit();
-	/* Ack only at the end to avoid potential reentry */
-	ack_APIC_irq();
+}
+
+asmlinkage void smp_thermal_interrupt(struct pt_regs *regs)
+{
+	entering_irq();
+	__smp_thermal_interrupt();
+	exiting_ack_irq();
+}
+
+asmlinkage void smp_trace_thermal_interrupt(struct pt_regs *regs)
+{
+	entering_irq();
+	trace_thermal_apic_entry(THERMAL_APIC_VECTOR);
+	__smp_thermal_interrupt();
+	trace_thermal_apic_exit(THERMAL_APIC_VECTOR);
+	exiting_ack_irq();
 }
 
 /* Thermal monitoring depends on APIC, ACPI and clock modulation */
@@ -470,9 +536,13 @@ void intel_init_thermal(struct cpuinfo_x
 	apic_write(APIC_LVTTHMR, h);
 
 	rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
-	if (cpu_has(c, X86_FEATURE_PLN))
+	if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable)
 		wrmsr(MSR_IA32_THERM_INTERRUPT,
-		      l | (THERM_INT_LOW_ENABLE
+			(l | (THERM_INT_LOW_ENABLE
+			| THERM_INT_HIGH_ENABLE)) & ~THERM_INT_PLN_ENABLE, h);
+	else if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
+		wrmsr(MSR_IA32_THERM_INTERRUPT,
+			l | (THERM_INT_LOW_ENABLE
 			| THERM_INT_HIGH_ENABLE | THERM_INT_PLN_ENABLE), h);
 	else
 		wrmsr(MSR_IA32_THERM_INTERRUPT,
@@ -480,9 +550,14 @@ void intel_init_thermal(struct cpuinfo_x
 
 	if (cpu_has(c, X86_FEATURE_PTS)) {
 		rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
-		if (cpu_has(c, X86_FEATURE_PLN))
+		if (cpu_has(c, X86_FEATURE_PLN) && !int_pln_enable)
 			wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
-			      l | (PACKAGE_THERM_INT_LOW_ENABLE
+				(l | (PACKAGE_THERM_INT_LOW_ENABLE
+				| PACKAGE_THERM_INT_HIGH_ENABLE))
+				& ~PACKAGE_THERM_INT_PLN_ENABLE, h);
+		else if (cpu_has(c, X86_FEATURE_PLN) && int_pln_enable)
+			wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
+				l | (PACKAGE_THERM_INT_LOW_ENABLE
 				| PACKAGE_THERM_INT_HIGH_ENABLE
 				| PACKAGE_THERM_INT_PLN_ENABLE), h);
 		else
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/threshold.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/threshold.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mcheck/threshold.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mcheck/threshold.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,7 @@
 #include <asm/apic.h>
 #include <asm/idle.h>
 #include <asm/mce.h>
+#include <asm/trace/irq_vectors.h>
 
 static void default_threshold_interrupt(void)
 {
@@ -17,13 +18,24 @@ static void default_threshold_interrupt(
 
 void (*mce_threshold_vector)(void) = default_threshold_interrupt;
 
-asmlinkage void smp_threshold_interrupt(void)
+static inline void __smp_threshold_interrupt(void)
 {
-	irq_enter();
-	exit_idle();
 	inc_irq_stat(irq_threshold_count);
 	mce_threshold_vector();
-	irq_exit();
-	/* Ack only at the end to avoid potential reentry */
-	ack_APIC_irq();
+}
+
+asmlinkage void smp_threshold_interrupt(void)
+{
+	entering_irq();
+	__smp_threshold_interrupt();
+	exiting_ack_irq();
+}
+
+asmlinkage void smp_trace_threshold_interrupt(void)
+{
+	entering_irq();
+	trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR);
+	__smp_threshold_interrupt();
+	trace_threshold_apic_exit(THRESHOLD_APIC_VECTOR);
+	exiting_ack_irq();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mtrr/cyrix.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mtrr/cyrix.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mtrr/cyrix.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mtrr/cyrix.c	2013-08-25 20:43:22.000000000 -0400
@@ -167,7 +167,7 @@ static void post_set(void)
 	setCx86(CX86_CCR3, ccr3);
 
 	/* Enable caches */
-	write_cr0(read_cr0() & 0xbfffffff);
+	write_cr0(read_cr0() & ~X86_CR0_CD);
 
 	/* Restore value of CR4 */
 	if (cpu_has_pge)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mtrr/generic.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mtrr/generic.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mtrr/generic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mtrr/generic.c	2013-08-25 20:43:22.000000000 -0400
@@ -510,8 +510,9 @@ generic_get_free_region(unsigned long ba
 static void generic_get_mtrr(unsigned int reg, unsigned long *base,
 			     unsigned long *size, mtrr_type *type)
 {
-	unsigned int mask_lo, mask_hi, base_lo, base_hi;
-	unsigned int tmp, hi;
+	u32 mask_lo, mask_hi, base_lo, base_hi;
+	unsigned int hi;
+	u64 tmp, mask;
 
 	/*
 	 * get_mtrr doesn't need to update mtrr_state, also it could be called
@@ -532,18 +533,18 @@ static void generic_get_mtrr(unsigned in
 	rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
 
 	/* Work out the shifted address mask: */
-	tmp = mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT;
-	mask_lo = size_or_mask | tmp;
+	tmp = (u64)mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT;
+	mask = size_or_mask | tmp;
 
 	/* Expand tmp with high bits to all 1s: */
-	hi = fls(tmp);
+	hi = fls64(tmp);
 	if (hi > 0) {
-		tmp |= ~((1<<(hi - 1)) - 1);
+		tmp |= ~((1ULL<<(hi - 1)) - 1);
 
-		if (tmp != mask_lo) {
+		if (tmp != mask) {
 			printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
 			add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
-			mask_lo = tmp;
+			mask = tmp;
 		}
 	}
 
@@ -551,8 +552,8 @@ static void generic_get_mtrr(unsigned in
 	 * This works correctly if size is a power of two, i.e. a
 	 * contiguous range:
 	 */
-	*size = -mask_lo;
-	*base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
+	*size = -mask;
+	*base = (u64)base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
 	*type = base_lo & 0xff;
 
 out_put_cpu:
@@ -701,7 +702,7 @@ static void post_set(void) __releases(se
 	mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
 
 	/* Enable caches */
-	write_cr0(read_cr0() & 0xbfffffff);
+	write_cr0(read_cr0() & ~X86_CR0_CD);
 
 	/* Restore value of CR4 */
 	if (cpu_has_pge)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/mtrr/main.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mtrr/main.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/mtrr/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/mtrr/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,9 +51,13 @@
 #include <asm/e820.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
+#include <asm/pat.h>
 
 #include "mtrr.h"
 
+/* arch_phys_wc_add returns an MTRR register index plus this offset. */
+#define MTRR_TO_PHYS_WC_OFFSET 1000
+
 u32 num_var_ranges;
 
 unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
@@ -305,7 +309,8 @@ int mtrr_add_page(unsigned long base, un
 		return -EINVAL;
 	}
 
-	if (base & size_or_mask || size & size_or_mask) {
+	if ((base | (base + size - 1)) >>
+	    (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) {
 		pr_warning("mtrr: base or size exceeds the MTRR width\n");
 		return -EINVAL;
 	}
@@ -524,6 +529,73 @@ int mtrr_del(int reg, unsigned long base
 }
 EXPORT_SYMBOL(mtrr_del);
 
+/**
+ * arch_phys_wc_add - add a WC MTRR and handle errors if PAT is unavailable
+ * @base: Physical base address
+ * @size: Size of region
+ *
+ * If PAT is available, this does nothing.  If PAT is unavailable, it
+ * attempts to add a WC MTRR covering size bytes starting at base and
+ * logs an error if this fails.
+ *
+ * Drivers must store the return value to pass to mtrr_del_wc_if_needed,
+ * but drivers should not try to interpret that return value.
+ */
+int arch_phys_wc_add(unsigned long base, unsigned long size)
+{
+	int ret;
+
+	if (pat_enabled)
+		return 0;  /* Success!  (We don't need to do anything.) */
+
+	ret = mtrr_add(base, size, MTRR_TYPE_WRCOMB, true);
+	if (ret < 0) {
+		pr_warn("Failed to add WC MTRR for [%p-%p]; performance may suffer.",
+			(void *)base, (void *)(base + size - 1));
+		return ret;
+	}
+	return ret + MTRR_TO_PHYS_WC_OFFSET;
+}
+EXPORT_SYMBOL(arch_phys_wc_add);
+
+/*
+ * arch_phys_wc_del - undoes arch_phys_wc_add
+ * @handle: Return value from arch_phys_wc_add
+ *
+ * This cleans up after mtrr_add_wc_if_needed.
+ *
+ * The API guarantees that mtrr_del_wc_if_needed(error code) and
+ * mtrr_del_wc_if_needed(0) do nothing.
+ */
+void arch_phys_wc_del(int handle)
+{
+	if (handle >= 1) {
+		WARN_ON(handle < MTRR_TO_PHYS_WC_OFFSET);
+		mtrr_del(handle - MTRR_TO_PHYS_WC_OFFSET, 0, 0);
+	}
+}
+EXPORT_SYMBOL(arch_phys_wc_del);
+
+/*
+ * phys_wc_to_mtrr_index - translates arch_phys_wc_add's return value
+ * @handle: Return value from arch_phys_wc_add
+ *
+ * This will turn the return value from arch_phys_wc_add into an mtrr
+ * index suitable for debugging.
+ *
+ * Note: There is no legitimate use for this function, except possibly
+ * in printk line.  Alas there is an illegitimate use in some ancient
+ * drm ioctls.
+ */
+int phys_wc_to_mtrr_index(int handle)
+{
+	if (handle < MTRR_TO_PHYS_WC_OFFSET)
+		return -1;
+	else
+		return handle - MTRR_TO_PHYS_WC_OFFSET;
+}
+EXPORT_SYMBOL_GPL(phys_wc_to_mtrr_index);
+
 /*
  * HACK ALERT!
  * These should be called implicitly, but we can't yet until all the initcall
@@ -583,6 +655,7 @@ static struct syscore_ops mtrr_syscore_o
 
 int __initdata changed_by_mtrr_cleanup;
 
+#define SIZE_OR_MASK_BITS(n)  (~((1ULL << ((n) - PAGE_SHIFT)) - 1))
 /**
  * mtrr_bp_init - initialize mtrrs on the boot CPU
  *
@@ -600,7 +673,7 @@ void __init mtrr_bp_init(void)
 
 	if (cpu_has_mtrr) {
 		mtrr_if = &generic_mtrr_ops;
-		size_or_mask = 0xff000000;			/* 36 bits */
+		size_or_mask = SIZE_OR_MASK_BITS(36);
 		size_and_mask = 0x00f00000;
 		phys_addr = 36;
 
@@ -619,7 +692,7 @@ void __init mtrr_bp_init(void)
 			     boot_cpu_data.x86_mask == 0x4))
 				phys_addr = 36;
 
-			size_or_mask = ~((1ULL << (phys_addr - PAGE_SHIFT)) - 1);
+			size_or_mask = SIZE_OR_MASK_BITS(phys_addr);
 			size_and_mask = ~size_or_mask & 0xfffff00000ULL;
 		} else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
 			   boot_cpu_data.x86 == 6) {
@@ -627,7 +700,7 @@ void __init mtrr_bp_init(void)
 			 * VIA C* family have Intel style MTRRs,
 			 * but don't support PAE
 			 */
-			size_or_mask = 0xfff00000;		/* 32 bits */
+			size_or_mask = SIZE_OR_MASK_BITS(32);
 			size_and_mask = 0;
 			phys_addr = 32;
 		}
@@ -637,21 +710,21 @@ void __init mtrr_bp_init(void)
 			if (cpu_has_k6_mtrr) {
 				/* Pre-Athlon (K6) AMD CPU MTRRs */
 				mtrr_if = mtrr_ops[X86_VENDOR_AMD];
-				size_or_mask = 0xfff00000;	/* 32 bits */
+				size_or_mask = SIZE_OR_MASK_BITS(32);
 				size_and_mask = 0;
 			}
 			break;
 		case X86_VENDOR_CENTAUR:
 			if (cpu_has_centaur_mcr) {
 				mtrr_if = mtrr_ops[X86_VENDOR_CENTAUR];
-				size_or_mask = 0xfff00000;	/* 32 bits */
+				size_or_mask = SIZE_OR_MASK_BITS(32);
 				size_and_mask = 0;
 			}
 			break;
 		case X86_VENDOR_CYRIX:
 			if (cpu_has_cyrix_arr) {
 				mtrr_if = mtrr_ops[X86_VENDOR_CYRIX];
-				size_or_mask = 0xfff00000;	/* 32 bits */
+				size_or_mask = SIZE_OR_MASK_BITS(32);
 				size_and_mask = 0;
 			}
 			break;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd.c	2013-08-25 20:43:22.000000000 -0400
@@ -648,48 +648,48 @@ static __initconst const struct x86_pmu
 	.cpu_dead		= amd_pmu_cpu_dead,
 };
 
-static int setup_event_constraints(void)
+static int __init amd_core_pmu_init(void)
 {
-	if (boot_cpu_data.x86 == 0x15)
+	if (!cpu_has_perfctr_core)
+		return 0;
+
+	switch (boot_cpu_data.x86) {
+	case 0x15:
+		pr_cont("Fam15h ");
 		x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
-	return 0;
-}
+		break;
 
-static int setup_perfctr_core(void)
-{
-	if (!cpu_has_perfctr_core) {
-		WARN(x86_pmu.get_event_constraints == amd_get_event_constraints_f15h,
-		     KERN_ERR "Odd, counter constraints enabled but no core perfctrs detected!");
+	default:
+		pr_err("core perfctr but no constraints; unknown hardware!\n");
 		return -ENODEV;
 	}
 
-	WARN(x86_pmu.get_event_constraints == amd_get_event_constraints,
-	     KERN_ERR "hw perf events core counters need constraints handler!");
-
 	/*
 	 * If core performance counter extensions exists, we must use
 	 * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
-	 * x86_pmu_addr_offset().
+	 * amd_pmu_addr_offset().
 	 */
 	x86_pmu.eventsel	= MSR_F15H_PERF_CTL;
 	x86_pmu.perfctr		= MSR_F15H_PERF_CTR;
 	x86_pmu.num_counters	= AMD64_NUM_COUNTERS_CORE;
 
-	printk(KERN_INFO "perf: AMD core performance counters detected\n");
-
+	pr_cont("core perfctr, ");
 	return 0;
 }
 
 __init int amd_pmu_init(void)
 {
+	int ret;
+
 	/* Performance-monitoring supported from K7 and later: */
 	if (boot_cpu_data.x86 < 6)
 		return -ENODEV;
 
 	x86_pmu = amd_pmu;
 
-	setup_event_constraints();
-	setup_perfctr_core();
+	ret = amd_core_pmu_init();
+	if (ret)
+		return ret;
 
 	/* Events are common for all AMDs */
 	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd_ibs.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd_ibs.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd_ibs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd_ibs.c	2013-08-25 20:43:22.000000000 -0400
@@ -851,7 +851,7 @@ static void clear_APIC_ibs(void *dummy)
 		setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
 }
 
-static int __cpuinit
+static int
 perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
 {
 	switch (action & ~CPU_TASKS_FROZEN) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd_iommu.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd_iommu.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd_iommu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd_iommu.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,502 @@
+/*
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ *
+ * Author: Steven Kinney <Steven.Kinney@amd.com>
+ * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
+ *
+ * Perf: amd_iommu - AMD IOMMU Performance Counter PMU implementation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/perf_event.h>
+#include <linux/module.h>
+#include <linux/cpumask.h>
+#include <linux/slab.h>
+
+#include "perf_event.h"
+#include "perf_event_amd_iommu.h"
+
+#define COUNTER_SHIFT		16
+
+#define _GET_BANK(ev)       ((u8)(ev->hw.extra_reg.reg >> 8))
+#define _GET_CNTR(ev)       ((u8)(ev->hw.extra_reg.reg))
+
+/* iommu pmu config masks */
+#define _GET_CSOURCE(ev)    ((ev->hw.config & 0xFFULL))
+#define _GET_DEVID(ev)      ((ev->hw.config >> 8)  & 0xFFFFULL)
+#define _GET_PASID(ev)      ((ev->hw.config >> 24) & 0xFFFFULL)
+#define _GET_DOMID(ev)      ((ev->hw.config >> 40) & 0xFFFFULL)
+#define _GET_DEVID_MASK(ev) ((ev->hw.extra_reg.config)  & 0xFFFFULL)
+#define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xFFFFULL)
+#define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xFFFFULL)
+
+static struct perf_amd_iommu __perf_iommu;
+
+struct perf_amd_iommu {
+	struct pmu pmu;
+	u8 max_banks;
+	u8 max_counters;
+	u64 cntr_assign_mask;
+	raw_spinlock_t lock;
+	const struct attribute_group *attr_groups[4];
+};
+
+#define format_group	attr_groups[0]
+#define cpumask_group	attr_groups[1]
+#define events_group	attr_groups[2]
+#define null_group	attr_groups[3]
+
+/*---------------------------------------------
+ * sysfs format attributes
+ *---------------------------------------------*/
+PMU_FORMAT_ATTR(csource,    "config:0-7");
+PMU_FORMAT_ATTR(devid,      "config:8-23");
+PMU_FORMAT_ATTR(pasid,      "config:24-39");
+PMU_FORMAT_ATTR(domid,      "config:40-55");
+PMU_FORMAT_ATTR(devid_mask, "config1:0-15");
+PMU_FORMAT_ATTR(pasid_mask, "config1:16-31");
+PMU_FORMAT_ATTR(domid_mask, "config1:32-47");
+
+static struct attribute *iommu_format_attrs[] = {
+	&format_attr_csource.attr,
+	&format_attr_devid.attr,
+	&format_attr_pasid.attr,
+	&format_attr_domid.attr,
+	&format_attr_devid_mask.attr,
+	&format_attr_pasid_mask.attr,
+	&format_attr_domid_mask.attr,
+	NULL,
+};
+
+static struct attribute_group amd_iommu_format_group = {
+	.name = "format",
+	.attrs = iommu_format_attrs,
+};
+
+/*---------------------------------------------
+ * sysfs events attributes
+ *---------------------------------------------*/
+struct amd_iommu_event_desc {
+	struct kobj_attribute attr;
+	const char *event;
+};
+
+static ssize_t _iommu_event_show(struct kobject *kobj,
+				struct kobj_attribute *attr, char *buf)
+{
+	struct amd_iommu_event_desc *event =
+		container_of(attr, struct amd_iommu_event_desc, attr);
+	return sprintf(buf, "%s\n", event->event);
+}
+
+#define AMD_IOMMU_EVENT_DESC(_name, _event)			\
+{								\
+	.attr  = __ATTR(_name, 0444, _iommu_event_show, NULL),	\
+	.event = _event,					\
+}
+
+static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = {
+	AMD_IOMMU_EVENT_DESC(mem_pass_untrans,        "csource=0x01"),
+	AMD_IOMMU_EVENT_DESC(mem_pass_pretrans,       "csource=0x02"),
+	AMD_IOMMU_EVENT_DESC(mem_pass_excl,           "csource=0x03"),
+	AMD_IOMMU_EVENT_DESC(mem_target_abort,        "csource=0x04"),
+	AMD_IOMMU_EVENT_DESC(mem_trans_total,         "csource=0x05"),
+	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_hit,   "csource=0x06"),
+	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pte_mis,   "csource=0x07"),
+	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_hit,   "csource=0x08"),
+	AMD_IOMMU_EVENT_DESC(mem_iommu_tlb_pde_mis,   "csource=0x09"),
+	AMD_IOMMU_EVENT_DESC(mem_dte_hit,             "csource=0x0a"),
+	AMD_IOMMU_EVENT_DESC(mem_dte_mis,             "csource=0x0b"),
+	AMD_IOMMU_EVENT_DESC(page_tbl_read_tot,       "csource=0x0c"),
+	AMD_IOMMU_EVENT_DESC(page_tbl_read_nst,       "csource=0x0d"),
+	AMD_IOMMU_EVENT_DESC(page_tbl_read_gst,       "csource=0x0e"),
+	AMD_IOMMU_EVENT_DESC(int_dte_hit,             "csource=0x0f"),
+	AMD_IOMMU_EVENT_DESC(int_dte_mis,             "csource=0x10"),
+	AMD_IOMMU_EVENT_DESC(cmd_processed,           "csource=0x11"),
+	AMD_IOMMU_EVENT_DESC(cmd_processed_inv,       "csource=0x12"),
+	AMD_IOMMU_EVENT_DESC(tlb_inv,                 "csource=0x13"),
+	{ /* end: all zeroes */ },
+};
+
+/*---------------------------------------------
+ * sysfs cpumask attributes
+ *---------------------------------------------*/
+static cpumask_t iommu_cpumask;
+
+static ssize_t _iommu_cpumask_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	int n = cpulist_scnprintf(buf, PAGE_SIZE - 2, &iommu_cpumask);
+	buf[n++] = '\n';
+	buf[n] = '\0';
+	return n;
+}
+static DEVICE_ATTR(cpumask, S_IRUGO, _iommu_cpumask_show, NULL);
+
+static struct attribute *iommu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static struct attribute_group amd_iommu_cpumask_group = {
+	.attrs = iommu_cpumask_attrs,
+};
+
+/*---------------------------------------------*/
+
+static int get_next_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu)
+{
+	unsigned long flags;
+	int shift, bank, cntr, retval;
+	int max_banks = perf_iommu->max_banks;
+	int max_cntrs = perf_iommu->max_counters;
+
+	raw_spin_lock_irqsave(&perf_iommu->lock, flags);
+
+	for (bank = 0, shift = 0; bank < max_banks; bank++) {
+		for (cntr = 0; cntr < max_cntrs; cntr++) {
+			shift = bank + (bank*3) + cntr;
+			if (perf_iommu->cntr_assign_mask & (1ULL<<shift)) {
+				continue;
+			} else {
+				perf_iommu->cntr_assign_mask |= (1ULL<<shift);
+				retval = ((u16)((u16)bank<<8) | (u8)(cntr));
+				goto out;
+			}
+		}
+	}
+	retval = -ENOSPC;
+out:
+	raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
+	return retval;
+}
+
+static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu,
+					u8 bank, u8 cntr)
+{
+	unsigned long flags;
+	int max_banks, max_cntrs;
+	int shift = 0;
+
+	max_banks = perf_iommu->max_banks;
+	max_cntrs = perf_iommu->max_counters;
+
+	if ((bank > max_banks) || (cntr > max_cntrs))
+		return -EINVAL;
+
+	shift = bank + cntr + (bank*3);
+
+	raw_spin_lock_irqsave(&perf_iommu->lock, flags);
+	perf_iommu->cntr_assign_mask &= ~(1ULL<<shift);
+	raw_spin_unlock_irqrestore(&perf_iommu->lock, flags);
+
+	return 0;
+}
+
+static int perf_iommu_event_init(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_amd_iommu *perf_iommu;
+	u64 config, config1;
+
+	/* test the event attr type check for PMU enumeration */
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	/*
+	 * IOMMU counters are shared across all cores.
+	 * Therefore, it does not support per-process mode.
+	 * Also, it does not support event sampling mode.
+	 */
+	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+		return -EINVAL;
+
+	/* IOMMU counters do not have usr/os/guest/host bits */
+	if (event->attr.exclude_user || event->attr.exclude_kernel ||
+	    event->attr.exclude_host || event->attr.exclude_guest)
+		return -EINVAL;
+
+	if (event->cpu < 0)
+		return -EINVAL;
+
+	perf_iommu = &__perf_iommu;
+
+	if (event->pmu != &perf_iommu->pmu)
+		return -ENOENT;
+
+	if (perf_iommu) {
+		config = event->attr.config;
+		config1 = event->attr.config1;
+	} else {
+		return -EINVAL;
+	}
+
+	/* integrate with iommu base devid (0000), assume one iommu */
+	perf_iommu->max_banks =
+		amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID);
+	perf_iommu->max_counters =
+		amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID);
+	if ((perf_iommu->max_banks == 0) || (perf_iommu->max_counters == 0))
+		return -EINVAL;
+
+	/* update the hw_perf_event struct with the iommu config data */
+	hwc->config = config;
+	hwc->extra_reg.config = config1;
+
+	return 0;
+}
+
+static void perf_iommu_enable_event(struct perf_event *ev)
+{
+	u8 csource = _GET_CSOURCE(ev);
+	u16 devid = _GET_DEVID(ev);
+	u64 reg = 0ULL;
+
+	reg = csource;
+	amd_iommu_pc_get_set_reg_val(devid,
+			_GET_BANK(ev), _GET_CNTR(ev) ,
+			 IOMMU_PC_COUNTER_SRC_REG, &reg, true);
+
+	reg = 0ULL | devid | (_GET_DEVID_MASK(ev) << 32);
+	if (reg)
+		reg |= (1UL << 31);
+	amd_iommu_pc_get_set_reg_val(devid,
+			_GET_BANK(ev), _GET_CNTR(ev) ,
+			 IOMMU_PC_DEVID_MATCH_REG, &reg, true);
+
+	reg = 0ULL | _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32);
+	if (reg)
+		reg |= (1UL << 31);
+	amd_iommu_pc_get_set_reg_val(devid,
+			_GET_BANK(ev), _GET_CNTR(ev) ,
+			 IOMMU_PC_PASID_MATCH_REG, &reg, true);
+
+	reg = 0ULL | _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32);
+	if (reg)
+		reg |= (1UL << 31);
+	amd_iommu_pc_get_set_reg_val(devid,
+			_GET_BANK(ev), _GET_CNTR(ev) ,
+			 IOMMU_PC_DOMID_MATCH_REG, &reg, true);
+}
+
+static void perf_iommu_disable_event(struct perf_event *event)
+{
+	u64 reg = 0ULL;
+
+	amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
+			_GET_BANK(event), _GET_CNTR(event),
+			IOMMU_PC_COUNTER_SRC_REG, &reg, true);
+}
+
+static void perf_iommu_start(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	pr_debug("perf: amd_iommu:perf_iommu_start\n");
+	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+		return;
+
+	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+	hwc->state = 0;
+
+	if (flags & PERF_EF_RELOAD) {
+		u64 prev_raw_count =  local64_read(&hwc->prev_count);
+		amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
+				_GET_BANK(event), _GET_CNTR(event),
+				IOMMU_PC_COUNTER_REG, &prev_raw_count, true);
+	}
+
+	perf_iommu_enable_event(event);
+	perf_event_update_userpage(event);
+
+}
+
+static void perf_iommu_read(struct perf_event *event)
+{
+	u64 count = 0ULL;
+	u64 prev_raw_count = 0ULL;
+	u64 delta = 0ULL;
+	struct hw_perf_event *hwc = &event->hw;
+	pr_debug("perf: amd_iommu:perf_iommu_read\n");
+
+	amd_iommu_pc_get_set_reg_val(_GET_DEVID(event),
+				_GET_BANK(event), _GET_CNTR(event),
+				IOMMU_PC_COUNTER_REG, &count, false);
+
+	/* IOMMU pc counter register is only 48 bits */
+	count &= 0xFFFFFFFFFFFFULL;
+
+	prev_raw_count =  local64_read(&hwc->prev_count);
+	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+					count) != prev_raw_count)
+		return;
+
+	/* Handling 48-bit counter overflowing */
+	delta = (count << COUNTER_SHIFT) - (prev_raw_count << COUNTER_SHIFT);
+	delta >>= COUNTER_SHIFT;
+	local64_add(delta, &event->count);
+
+}
+
+static void perf_iommu_stop(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 config;
+
+	pr_debug("perf: amd_iommu:perf_iommu_stop\n");
+
+	if (hwc->state & PERF_HES_UPTODATE)
+		return;
+
+	perf_iommu_disable_event(event);
+	WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+	hwc->state |= PERF_HES_STOPPED;
+
+	if (hwc->state & PERF_HES_UPTODATE)
+		return;
+
+	config = hwc->config;
+	perf_iommu_read(event);
+	hwc->state |= PERF_HES_UPTODATE;
+}
+
+static int perf_iommu_add(struct perf_event *event, int flags)
+{
+	int retval;
+	struct perf_amd_iommu *perf_iommu =
+			container_of(event->pmu, struct perf_amd_iommu, pmu);
+
+	pr_debug("perf: amd_iommu:perf_iommu_add\n");
+	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+	/* request an iommu bank/counter */
+	retval = get_next_avail_iommu_bnk_cntr(perf_iommu);
+	if (retval != -ENOSPC)
+		event->hw.extra_reg.reg = (u16)retval;
+	else
+		return retval;
+
+	if (flags & PERF_EF_START)
+		perf_iommu_start(event, PERF_EF_RELOAD);
+
+	return 0;
+}
+
+static void perf_iommu_del(struct perf_event *event, int flags)
+{
+	struct perf_amd_iommu *perf_iommu =
+			container_of(event->pmu, struct perf_amd_iommu, pmu);
+
+	pr_debug("perf: amd_iommu:perf_iommu_del\n");
+	perf_iommu_stop(event, PERF_EF_UPDATE);
+
+	/* clear the assigned iommu bank/counter */
+	clear_avail_iommu_bnk_cntr(perf_iommu,
+				     _GET_BANK(event),
+				     _GET_CNTR(event));
+
+	perf_event_update_userpage(event);
+}
+
+static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu)
+{
+	struct attribute **attrs;
+	struct attribute_group *attr_group;
+	int i = 0, j;
+
+	while (amd_iommu_v2_event_descs[i].attr.attr.name)
+		i++;
+
+	attr_group = kzalloc(sizeof(struct attribute *)
+		* (i + 1) + sizeof(*attr_group), GFP_KERNEL);
+	if (!attr_group)
+		return -ENOMEM;
+
+	attrs = (struct attribute **)(attr_group + 1);
+	for (j = 0; j < i; j++)
+		attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr;
+
+	attr_group->name = "events";
+	attr_group->attrs = attrs;
+	perf_iommu->events_group = attr_group;
+
+	return 0;
+}
+
+static __init void amd_iommu_pc_exit(void)
+{
+	if (__perf_iommu.events_group != NULL) {
+		kfree(__perf_iommu.events_group);
+		__perf_iommu.events_group = NULL;
+	}
+}
+
+static __init int _init_perf_amd_iommu(
+	struct perf_amd_iommu *perf_iommu, char *name)
+{
+	int ret;
+
+	raw_spin_lock_init(&perf_iommu->lock);
+
+	/* Init format attributes */
+	perf_iommu->format_group = &amd_iommu_format_group;
+
+	/* Init cpumask attributes to only core 0 */
+	cpumask_set_cpu(0, &iommu_cpumask);
+	perf_iommu->cpumask_group = &amd_iommu_cpumask_group;
+
+	/* Init events attributes */
+	if (_init_events_attrs(perf_iommu) != 0)
+		pr_err("perf: amd_iommu: Only support raw events.\n");
+
+	/* Init null attributes */
+	perf_iommu->null_group = NULL;
+	perf_iommu->pmu.attr_groups = perf_iommu->attr_groups;
+
+	ret = perf_pmu_register(&perf_iommu->pmu, name, -1);
+	if (ret) {
+		pr_err("perf: amd_iommu: Failed to initialized.\n");
+		amd_iommu_pc_exit();
+	} else {
+		pr_info("perf: amd_iommu: Detected. (%d banks, %d counters/bank)\n",
+			amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID),
+			amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID));
+	}
+
+	return ret;
+}
+
+static struct perf_amd_iommu __perf_iommu = {
+	.pmu = {
+		.event_init	= perf_iommu_event_init,
+		.add		= perf_iommu_add,
+		.del		= perf_iommu_del,
+		.start		= perf_iommu_start,
+		.stop		= perf_iommu_stop,
+		.read		= perf_iommu_read,
+	},
+	.max_banks		= 0x00,
+	.max_counters		= 0x00,
+	.cntr_assign_mask	= 0ULL,
+	.format_group		= NULL,
+	.cpumask_group		= NULL,
+	.events_group		= NULL,
+	.null_group		= NULL,
+};
+
+static __init int amd_iommu_pc_init(void)
+{
+	/* Make sure the IOMMU PC resource is available */
+	if (!amd_iommu_pc_supported())
+		return -ENODEV;
+
+	_init_perf_amd_iommu(&__perf_iommu, "amd_iommu");
+
+	return 0;
+}
+
+device_initcall(amd_iommu_pc_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd_iommu.h linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd_iommu.h
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd_iommu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd_iommu.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ *
+ * Author: Steven Kinney <Steven.Kinney@amd.com>
+ * Author: Suravee Suthikulpanit <Suraveee.Suthikulpanit@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _PERF_EVENT_AMD_IOMMU_H_
+#define _PERF_EVENT_AMD_IOMMU_H_
+
+/* iommu pc mmio region register indexes */
+#define IOMMU_PC_COUNTER_REG			0x00
+#define IOMMU_PC_COUNTER_SRC_REG		0x08
+#define IOMMU_PC_PASID_MATCH_REG		0x10
+#define IOMMU_PC_DOMID_MATCH_REG		0x18
+#define IOMMU_PC_DEVID_MATCH_REG		0x20
+#define IOMMU_PC_COUNTER_REPORT_REG		0x28
+
+/* maximun specified bank/counters */
+#define PC_MAX_SPEC_BNKS			64
+#define PC_MAX_SPEC_CNTRS			16
+
+/* iommu pc reg masks*/
+#define IOMMU_BASE_DEVID			0x0000
+
+/* amd_iommu_init.c external support functions */
+extern bool amd_iommu_pc_supported(void);
+
+extern u8 amd_iommu_pc_get_max_banks(u16 devid);
+
+extern u8 amd_iommu_pc_get_max_counters(u16 devid);
+
+extern int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr,
+			u8 fxn, u64 *value, bool is_write);
+
+#endif /*_PERF_EVENT_AMD_IOMMU_H_*/
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd_uncore.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd_uncore.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_amd_uncore.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_amd_uncore.c	2013-08-25 20:43:22.000000000 -0400
@@ -288,13 +288,13 @@ static struct pmu amd_l2_pmu = {
 	.read		= amd_uncore_read,
 };
 
-static struct amd_uncore * __cpuinit amd_uncore_alloc(unsigned int cpu)
+static struct amd_uncore *amd_uncore_alloc(unsigned int cpu)
 {
 	return kzalloc_node(sizeof(struct amd_uncore), GFP_KERNEL,
 			cpu_to_node(cpu));
 }
 
-static void __cpuinit amd_uncore_cpu_up_prepare(unsigned int cpu)
+static void amd_uncore_cpu_up_prepare(unsigned int cpu)
 {
 	struct amd_uncore *uncore;
 
@@ -322,8 +322,8 @@ static void __cpuinit amd_uncore_cpu_up_
 }
 
 static struct amd_uncore *
-__cpuinit amd_uncore_find_online_sibling(struct amd_uncore *this,
-					 struct amd_uncore * __percpu *uncores)
+amd_uncore_find_online_sibling(struct amd_uncore *this,
+			       struct amd_uncore * __percpu *uncores)
 {
 	unsigned int cpu;
 	struct amd_uncore *that;
@@ -348,7 +348,7 @@ __cpuinit amd_uncore_find_online_sibling
 	return this;
 }
 
-static void __cpuinit amd_uncore_cpu_starting(unsigned int cpu)
+static void amd_uncore_cpu_starting(unsigned int cpu)
 {
 	unsigned int eax, ebx, ecx, edx;
 	struct amd_uncore *uncore;
@@ -376,8 +376,8 @@ static void __cpuinit amd_uncore_cpu_sta
 	}
 }
 
-static void __cpuinit uncore_online(unsigned int cpu,
-				    struct amd_uncore * __percpu *uncores)
+static void uncore_online(unsigned int cpu,
+			  struct amd_uncore * __percpu *uncores)
 {
 	struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
 
@@ -388,7 +388,7 @@ static void __cpuinit uncore_online(unsi
 		cpumask_set_cpu(cpu, uncore->active_mask);
 }
 
-static void __cpuinit amd_uncore_cpu_online(unsigned int cpu)
+static void amd_uncore_cpu_online(unsigned int cpu)
 {
 	if (amd_uncore_nb)
 		uncore_online(cpu, amd_uncore_nb);
@@ -397,8 +397,8 @@ static void __cpuinit amd_uncore_cpu_onl
 		uncore_online(cpu, amd_uncore_l2);
 }
 
-static void __cpuinit uncore_down_prepare(unsigned int cpu,
-					  struct amd_uncore * __percpu *uncores)
+static void uncore_down_prepare(unsigned int cpu,
+				struct amd_uncore * __percpu *uncores)
 {
 	unsigned int i;
 	struct amd_uncore *this = *per_cpu_ptr(uncores, cpu);
@@ -423,7 +423,7 @@ static void __cpuinit uncore_down_prepar
 	}
 }
 
-static void __cpuinit amd_uncore_cpu_down_prepare(unsigned int cpu)
+static void amd_uncore_cpu_down_prepare(unsigned int cpu)
 {
 	if (amd_uncore_nb)
 		uncore_down_prepare(cpu, amd_uncore_nb);
@@ -432,8 +432,7 @@ static void __cpuinit amd_uncore_cpu_dow
 		uncore_down_prepare(cpu, amd_uncore_l2);
 }
 
-static void __cpuinit uncore_dead(unsigned int cpu,
-				  struct amd_uncore * __percpu *uncores)
+static void uncore_dead(unsigned int cpu, struct amd_uncore * __percpu *uncores)
 {
 	struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu);
 
@@ -445,7 +444,7 @@ static void __cpuinit uncore_dead(unsign
 	*per_cpu_ptr(amd_uncore_nb, cpu) = NULL;
 }
 
-static void __cpuinit amd_uncore_cpu_dead(unsigned int cpu)
+static void amd_uncore_cpu_dead(unsigned int cpu)
 {
 	if (amd_uncore_nb)
 		uncore_dead(cpu, amd_uncore_nb);
@@ -454,7 +453,7 @@ static void __cpuinit amd_uncore_cpu_dea
 		uncore_dead(cpu, amd_uncore_l2);
 }
 
-static int __cpuinit
+static int
 amd_uncore_cpu_notifier(struct notifier_block *self, unsigned long action,
 			void *hcpu)
 {
@@ -489,7 +488,7 @@ amd_uncore_cpu_notifier(struct notifier_
 	return NOTIFY_OK;
 }
 
-static struct notifier_block amd_uncore_cpu_notifier_block __cpuinitdata = {
+static struct notifier_block amd_uncore_cpu_notifier_block = {
 	.notifier_call	= amd_uncore_cpu_notifier,
 	.priority	= CPU_PRI_PERF + 1,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -403,7 +403,8 @@ int x86_pmu_hw_config(struct perf_event
 		 * check that PEBS LBR correction does not conflict with
 		 * whatever the user is asking with attr->branch_sample_type
 		 */
-		if (event->attr.precise_ip > 1) {
+		if (event->attr.precise_ip > 1 &&
+		    x86_pmu.intel_cap.pebs_format < 2) {
 			u64 *br_type = &event->attr.branch_sample_type;
 
 			if (has_branch_stack(event)) {
@@ -568,7 +569,7 @@ struct sched_state {
 struct perf_sched {
 	int			max_weight;
 	int			max_events;
-	struct event_constraint	**constraints;
+	struct perf_event	**events;
 	struct sched_state	state;
 	int			saved_states;
 	struct sched_state	saved[SCHED_STATES_MAX];
@@ -577,7 +578,7 @@ struct perf_sched {
 /*
  * Initialize interator that runs through all events and counters.
  */
-static void perf_sched_init(struct perf_sched *sched, struct event_constraint **c,
+static void perf_sched_init(struct perf_sched *sched, struct perf_event **events,
 			    int num, int wmin, int wmax)
 {
 	int idx;
@@ -585,10 +586,10 @@ static void perf_sched_init(struct perf_
 	memset(sched, 0, sizeof(*sched));
 	sched->max_events	= num;
 	sched->max_weight	= wmax;
-	sched->constraints	= c;
+	sched->events		= events;
 
 	for (idx = 0; idx < num; idx++) {
-		if (c[idx]->weight == wmin)
+		if (events[idx]->hw.constraint->weight == wmin)
 			break;
 	}
 
@@ -635,8 +636,7 @@ static bool __perf_sched_find_counter(st
 	if (sched->state.event >= sched->max_events)
 		return false;
 
-	c = sched->constraints[sched->state.event];
-
+	c = sched->events[sched->state.event]->hw.constraint;
 	/* Prefer fixed purpose counters */
 	if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) {
 		idx = INTEL_PMC_IDX_FIXED;
@@ -694,7 +694,7 @@ static bool perf_sched_next_event(struct
 			if (sched->state.weight > sched->max_weight)
 				return false;
 		}
-		c = sched->constraints[sched->state.event];
+		c = sched->events[sched->state.event]->hw.constraint;
 	} while (c->weight != sched->state.weight);
 
 	sched->state.counter = 0;	/* start with first counter */
@@ -705,12 +705,12 @@ static bool perf_sched_next_event(struct
 /*
  * Assign a counter for each event.
  */
-int perf_assign_events(struct event_constraint **constraints, int n,
+int perf_assign_events(struct perf_event **events, int n,
 			int wmin, int wmax, int *assign)
 {
 	struct perf_sched sched;
 
-	perf_sched_init(&sched, constraints, n, wmin, wmax);
+	perf_sched_init(&sched, events, n, wmin, wmax);
 
 	do {
 		if (!perf_sched_find_counter(&sched))
@@ -724,16 +724,19 @@ int perf_assign_events(struct event_cons
 
 int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
 {
-	struct event_constraint *c, *constraints[X86_PMC_IDX_MAX];
+	struct event_constraint *c;
 	unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	struct perf_event *e;
 	int i, wmin, wmax, num = 0;
 	struct hw_perf_event *hwc;
 
 	bitmap_zero(used_mask, X86_PMC_IDX_MAX);
 
 	for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) {
+		hwc = &cpuc->event_list[i]->hw;
 		c = x86_pmu.get_event_constraints(cpuc, cpuc->event_list[i]);
-		constraints[i] = c;
+		hwc->constraint = c;
+
 		wmin = min(wmin, c->weight);
 		wmax = max(wmax, c->weight);
 	}
@@ -743,7 +746,7 @@ int x86_schedule_events(struct cpu_hw_ev
 	 */
 	for (i = 0; i < n; i++) {
 		hwc = &cpuc->event_list[i]->hw;
-		c = constraints[i];
+		c = hwc->constraint;
 
 		/* never assigned */
 		if (hwc->idx == -1)
@@ -764,16 +767,35 @@ int x86_schedule_events(struct cpu_hw_ev
 
 	/* slow path */
 	if (i != n)
-		num = perf_assign_events(constraints, n, wmin, wmax, assign);
+		num = perf_assign_events(cpuc->event_list, n, wmin,
+					 wmax, assign);
 
 	/*
+	 * Mark the event as committed, so we do not put_constraint()
+	 * in case new events are added and fail scheduling.
+	 */
+	if (!num && assign) {
+		for (i = 0; i < n; i++) {
+			e = cpuc->event_list[i];
+			e->hw.flags |= PERF_X86_EVENT_COMMITTED;
+		}
+	}
+	/*
 	 * scheduling failed or is just a simulation,
 	 * free resources if necessary
 	 */
 	if (!assign || num) {
 		for (i = 0; i < n; i++) {
+			e = cpuc->event_list[i];
+			/*
+			 * do not put_constraint() on comitted events,
+			 * because they are good to go
+			 */
+			if ((e->hw.flags & PERF_X86_EVENT_COMMITTED))
+				continue;
+
 			if (x86_pmu.put_event_constraints)
-				x86_pmu.put_event_constraints(cpuc, cpuc->event_list[i]);
+				x86_pmu.put_event_constraints(cpuc, e);
 		}
 	}
 	return num ? -EINVAL : 0;
@@ -1153,6 +1175,11 @@ static void x86_pmu_del(struct perf_even
 	int i;
 
 	/*
+	 * event is descheduled
+	 */
+	event->hw.flags &= ~PERF_X86_EVENT_COMMITTED;
+
+	/*
 	 * If we're called during a txn, we don't need to do anything.
 	 * The events never got scheduled and ->cancel_txn will truncate
 	 * the event_list.
@@ -1249,16 +1276,26 @@ void perf_events_lapic_init(void)
 static int __kprobes
 perf_event_nmi_handler(unsigned int cmd, struct pt_regs *regs)
 {
+	int ret;
+	u64 start_clock;
+	u64 finish_clock;
+
 	if (!atomic_read(&active_events))
 		return NMI_DONE;
 
-	return x86_pmu.handle_irq(regs);
+	start_clock = local_clock();
+	ret = x86_pmu.handle_irq(regs);
+	finish_clock = local_clock();
+
+	perf_sample_event_took(finish_clock - start_clock);
+
+	return ret;
 }
 
 struct event_constraint emptyconstraint;
 struct event_constraint unconstrained;
 
-static int __cpuinit
+static int
 x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (long)hcpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event.h linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event.h
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event.h	2013-08-25 20:43:22.000000000 -0400
@@ -63,10 +63,12 @@ struct event_constraint {
 	int	flags;
 };
 /*
- * struct event_constraint flags
+ * struct hw_perf_event.flags flags
  */
 #define PERF_X86_EVENT_PEBS_LDLAT	0x1 /* ld+ldlat data address sampling */
 #define PERF_X86_EVENT_PEBS_ST		0x2 /* st data address sampling */
+#define PERF_X86_EVENT_PEBS_ST_HSW	0x4 /* haswell style st data sampling */
+#define PERF_X86_EVENT_COMMITTED	0x8 /* event passed commit_txn */
 
 struct amd_nb {
 	int nb_id;  /* NorthBridge id */
@@ -227,11 +229,14 @@ struct cpu_hw_events {
  *  - inv
  *  - edge
  *  - cnt-mask
+ *  - in_tx
+ *  - in_tx_checkpointed
  *  The other filters are supported by fixed counters.
  *  The any-thread option is supported starting with v3.
  */
+#define FIXED_EVENT_FLAGS (X86_RAW_EVENT_MASK|HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)
 #define FIXED_EVENT_CONSTRAINT(c, n)	\
-	EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK)
+	EVENT_CONSTRAINT(c, (1ULL << (32+n)), FIXED_EVENT_FLAGS)
 
 /*
  * Constraint on the Event code + UMask
@@ -247,6 +252,11 @@ struct cpu_hw_events {
 	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \
 			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST)
 
+/* DataLA version of store sampling without extra enable bit. */
+#define INTEL_PST_HSW_CONSTRAINT(c, n)	\
+	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \
+			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW)
+
 #define EVENT_CONSTRAINT_END		\
 	EVENT_CONSTRAINT(0, 0, 0)
 
@@ -301,6 +311,11 @@ union perf_capabilities {
 		u64	pebs_arch_reg:1;
 		u64	pebs_format:4;
 		u64	smm_freeze:1;
+		/*
+		 * PMU supports separate counter range for writing
+		 * values > 32bit.
+		 */
+		u64	full_width_write:1;
 	};
 	u64	capabilities;
 };
@@ -375,6 +390,7 @@ struct x86_pmu {
 	struct event_constraint *event_constraints;
 	struct x86_pmu_quirk *quirks;
 	int		perfctr_second_write;
+	bool		late_ack;
 
 	/*
 	 * sysfs attrs
@@ -528,7 +544,7 @@ static inline void __x86_pmu_enable_even
 
 void x86_pmu_enable_all(int added);
 
-int perf_assign_events(struct event_constraint **constraints, int n,
+int perf_assign_events(struct perf_event **events, int n,
 			int wmin, int wmax, int *assign);
 int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign);
 
@@ -633,6 +649,8 @@ extern struct event_constraint intel_snb
 
 extern struct event_constraint intel_ivb_pebs_event_constraints[];
 
+extern struct event_constraint intel_hsw_pebs_event_constraints[];
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event);
 
 void intel_pmu_pebs_enable(struct perf_event *event);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/export.h>
 
+#include <asm/cpufeature.h>
 #include <asm/hardirq.h>
 #include <asm/apic.h>
 
@@ -190,6 +191,22 @@ struct attribute *snb_events_attrs[] = {
 	NULL,
 };
 
+static struct event_constraint intel_hsw_event_constraints[] = {
+	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+	INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.* */
+	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
+	INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+	/* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */
+	INTEL_EVENT_CONSTRAINT(0x08a3, 0x4),
+	/* CYCLE_ACTIVITY.STALLS_L1D_PENDING */
+	INTEL_EVENT_CONSTRAINT(0x0ca3, 0x4),
+	/* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */
+	INTEL_EVENT_CONSTRAINT(0x04a3, 0xf),
+	EVENT_CONSTRAINT_END
+};
+
 static u64 intel_pmu_event_map(int hw_event)
 {
 	return intel_perfmon_event_map[hw_event];
@@ -872,7 +889,8 @@ static inline bool intel_pmu_needs_lbr_s
 		return true;
 
 	/* implicit branch sampling to correct PEBS skid */
-	if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
+	if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1 &&
+	    x86_pmu.intel_cap.pebs_format < 2)
 		return true;
 
 	return false;
@@ -1167,15 +1185,11 @@ static int intel_pmu_handle_irq(struct p
 	cpuc = &__get_cpu_var(cpu_hw_events);
 
 	/*
-	 * Some chipsets need to unmask the LVTPC in a particular spot
-	 * inside the nmi handler.  As a result, the unmasking was pushed
-	 * into all the nmi handlers.
-	 *
-	 * This handler doesn't seem to have any issues with the unmasking
-	 * so it was left at the top.
+	 * No known reason to not always do late ACK,
+	 * but just in case do it opt-in.
 	 */
-	apic_write(APIC_LVTPC, APIC_DM_NMI);
-
+	if (!x86_pmu.late_ack)
+		apic_write(APIC_LVTPC, APIC_DM_NMI);
 	intel_pmu_disable_all();
 	handled = intel_pmu_drain_bts_buffer();
 	status = intel_pmu_get_status();
@@ -1188,8 +1202,12 @@ static int intel_pmu_handle_irq(struct p
 again:
 	intel_pmu_ack_status(status);
 	if (++loops > 100) {
-		WARN_ONCE(1, "perfevents: irq loop stuck!\n");
-		perf_event_print_debug();
+		static bool warned = false;
+		if (!warned) {
+			WARN(1, "perfevents: irq loop stuck!\n");
+			perf_event_print_debug();
+			warned = true;
+		}
 		intel_pmu_reset();
 		goto done;
 	}
@@ -1235,6 +1253,13 @@ again:
 
 done:
 	intel_pmu_enable_all(0);
+	/*
+	 * Only unmask the NMI after the overflow counters
+	 * have been reset. This avoids spurious NMIs on
+	 * Haswell CPUs.
+	 */
+	if (x86_pmu.late_ack)
+		apic_write(APIC_LVTPC, APIC_DM_NMI);
 	return handled;
 }
 
@@ -1425,7 +1450,6 @@ x86_get_event_constraints(struct cpu_hw_
 	if (x86_pmu.event_constraints) {
 		for_each_event_constraint(c, x86_pmu.event_constraints) {
 			if ((event->hw.config & c->cmask) == c->code) {
-				/* hw.flags zeroed at initialization */
 				event->hw.flags |= c->flags;
 				return c;
 			}
@@ -1473,7 +1497,6 @@ intel_put_shared_regs_event_constraints(
 static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
 					struct perf_event *event)
 {
-	event->hw.flags = 0;
 	intel_put_shared_regs_event_constraints(cpuc, event);
 }
 
@@ -1646,6 +1669,47 @@ static void core_pmu_enable_all(int adde
 	}
 }
 
+static int hsw_hw_config(struct perf_event *event)
+{
+	int ret = intel_pmu_hw_config(event);
+
+	if (ret)
+		return ret;
+	if (!boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has(X86_FEATURE_HLE))
+		return 0;
+	event->hw.config |= event->attr.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED);
+
+	/*
+	 * IN_TX/IN_TX-CP filters are not supported by the Haswell PMU with
+	 * PEBS or in ANY thread mode. Since the results are non-sensical forbid
+	 * this combination.
+	 */
+	if ((event->hw.config & (HSW_IN_TX|HSW_IN_TX_CHECKPOINTED)) &&
+	     ((event->hw.config & ARCH_PERFMON_EVENTSEL_ANY) ||
+	      event->attr.precise_ip > 0))
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static struct event_constraint counter2_constraint =
+			EVENT_CONSTRAINT(0, 0x4, 0);
+
+static struct event_constraint *
+hsw_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
+{
+	struct event_constraint *c = intel_get_event_constraints(cpuc, event);
+
+	/* Handle special quirk on in_tx_checkpointed only in counter 2 */
+	if (event->hw.config & HSW_IN_TX_CHECKPOINTED) {
+		if (c->idxmsk64 & (1U << 2))
+			return &counter2_constraint;
+		return &emptyconstraint;
+	}
+
+	return c;
+}
+
 PMU_FORMAT_ATTR(event,	"config:0-7"	);
 PMU_FORMAT_ATTR(umask,	"config:8-15"	);
 PMU_FORMAT_ATTR(edge,	"config:18"	);
@@ -1653,6 +1717,8 @@ PMU_FORMAT_ATTR(pc,	"config:19"	);
 PMU_FORMAT_ATTR(any,	"config:21"	); /* v3 + */
 PMU_FORMAT_ATTR(inv,	"config:23"	);
 PMU_FORMAT_ATTR(cmask,	"config:24-31"	);
+PMU_FORMAT_ATTR(in_tx,  "config:32");
+PMU_FORMAT_ATTR(in_tx_cp, "config:33");
 
 static struct attribute *intel_arch_formats_attr[] = {
 	&format_attr_event.attr,
@@ -1807,6 +1873,8 @@ static struct attribute *intel_arch3_for
 	&format_attr_any.attr,
 	&format_attr_inv.attr,
 	&format_attr_cmask.attr,
+	&format_attr_in_tx.attr,
+	&format_attr_in_tx_cp.attr,
 
 	&format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */
 	&format_attr_ldlat.attr, /* PEBS load latency */
@@ -1966,6 +2034,15 @@ static __init void intel_nehalem_quirk(v
 	}
 }
 
+EVENT_ATTR_STR(mem-loads,      mem_ld_hsw,     "event=0xcd,umask=0x1,ldlat=3");
+EVENT_ATTR_STR(mem-stores,     mem_st_hsw,     "event=0xd0,umask=0x82")
+
+static struct attribute *hsw_events_attrs[] = {
+	EVENT_PTR(mem_ld_hsw),
+	EVENT_PTR(mem_st_hsw),
+	NULL
+};
+
 __init int intel_pmu_init(void)
 {
 	union cpuid10_edx edx;
@@ -2189,6 +2266,31 @@ __init int intel_pmu_init(void)
 		break;
 
 
+	case 60: /* Haswell Client */
+	case 70:
+	case 71:
+	case 63:
+	case 69:
+		x86_pmu.late_ack = true;
+		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+		memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+
+		intel_pmu_lbr_init_snb();
+
+		x86_pmu.event_constraints = intel_hsw_event_constraints;
+		x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
+		x86_pmu.extra_regs = intel_snb_extra_regs;
+		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+		/* all extra regs are per-cpu when HT is on */
+		x86_pmu.er_flags |= ERF_HAS_RSP_1;
+		x86_pmu.er_flags |= ERF_NO_HT_SHARING;
+
+		x86_pmu.hw_config = hsw_hw_config;
+		x86_pmu.get_event_constraints = hsw_get_event_constraints;
+		x86_pmu.cpu_events = hsw_events_attrs;
+		pr_cont("Haswell events, ");
+		break;
+
 	default:
 		switch (x86_pmu.version) {
 		case 1:
@@ -2227,7 +2329,7 @@ __init int intel_pmu_init(void)
 		 * counter, so do not extend mask to generic counters
 		 */
 		for_each_event_constraint(c, x86_pmu.event_constraints) {
-			if (c->cmask != X86_RAW_EVENT_MASK
+			if (c->cmask != FIXED_EVENT_FLAGS
 			    || c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) {
 				continue;
 			}
@@ -2237,5 +2339,12 @@ __init int intel_pmu_init(void)
 		}
 	}
 
+	/* Support full width counters using alternative MSR range */
+	if (x86_pmu.intel_cap.full_width_write) {
+		x86_pmu.max_period = x86_pmu.cntval_mask;
+		x86_pmu.perfctr = MSR_IA32_PMC0;
+		pr_cont("full-width counters, ");
+	}
+
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel_ds.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_ds.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel_ds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_ds.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,6 +107,19 @@ static u64 precise_store_data(u64 status
 	return val;
 }
 
+static u64 precise_store_data_hsw(u64 status)
+{
+	union perf_mem_data_src dse;
+
+	dse.val = 0;
+	dse.mem_op = PERF_MEM_OP_STORE;
+	dse.mem_lvl = PERF_MEM_LVL_NA;
+	if (status & 1)
+		dse.mem_lvl = PERF_MEM_LVL_L1;
+	/* Nothing else supported. Sorry. */
+	return dse.val;
+}
+
 static u64 load_latency_data(u64 status)
 {
 	union intel_x86_pebs_dse dse;
@@ -165,6 +178,22 @@ struct pebs_record_nhm {
 	u64 status, dla, dse, lat;
 };
 
+/*
+ * Same as pebs_record_nhm, with two additional fields.
+ */
+struct pebs_record_hsw {
+	struct pebs_record_nhm nhm;
+	/*
+	 * Real IP of the event. In the Intel documentation this
+	 * is called eventingrip.
+	 */
+	u64 real_ip;
+	/*
+	 * TSX tuning information field: abort cycles and abort flags.
+	 */
+	u64 tsx_tuning;
+};
+
 void init_debug_store_on_cpu(int cpu)
 {
 	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
@@ -548,6 +577,42 @@ struct event_constraint intel_ivb_pebs_e
         EVENT_CONSTRAINT_END
 };
 
+struct event_constraint intel_hsw_pebs_event_constraints[] = {
+	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+	INTEL_PST_HSW_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+	INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
+	INTEL_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
+	INTEL_UEVENT_CONSTRAINT(0x01c5, 0xf), /* BR_MISP_RETIRED.CONDITIONAL */
+	INTEL_UEVENT_CONSTRAINT(0x04c5, 0xf), /* BR_MISP_RETIRED.ALL_BRANCHES */
+	INTEL_UEVENT_CONSTRAINT(0x20c5, 0xf), /* BR_MISP_RETIRED.NEAR_TAKEN */
+	INTEL_PLD_CONSTRAINT(0x01cd, 0x8),    /* MEM_TRANS_RETIRED.* */
+	/* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
+	INTEL_UEVENT_CONSTRAINT(0x11d0, 0xf),
+	/* MEM_UOPS_RETIRED.STLB_MISS_STORES */
+	INTEL_UEVENT_CONSTRAINT(0x12d0, 0xf),
+	INTEL_UEVENT_CONSTRAINT(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */
+	INTEL_UEVENT_CONSTRAINT(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
+	/* MEM_UOPS_RETIRED.SPLIT_STORES */
+	INTEL_UEVENT_CONSTRAINT(0x42d0, 0xf),
+	INTEL_UEVENT_CONSTRAINT(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
+	INTEL_PST_HSW_CONSTRAINT(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */
+	INTEL_UEVENT_CONSTRAINT(0x01d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L1_HIT */
+	INTEL_UEVENT_CONSTRAINT(0x02d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L2_HIT */
+	INTEL_UEVENT_CONSTRAINT(0x04d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L3_HIT */
+	/* MEM_LOAD_UOPS_RETIRED.HIT_LFB */
+	INTEL_UEVENT_CONSTRAINT(0x40d1, 0xf),
+	/* MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS */
+	INTEL_UEVENT_CONSTRAINT(0x01d2, 0xf),
+	/* MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT */
+	INTEL_UEVENT_CONSTRAINT(0x02d2, 0xf),
+	/* MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM */
+	INTEL_UEVENT_CONSTRAINT(0x01d3, 0xf),
+	INTEL_UEVENT_CONSTRAINT(0x04c8, 0xf), /* HLE_RETIRED.Abort */
+	INTEL_UEVENT_CONSTRAINT(0x04c9, 0xf), /* RTM_RETIRED.Abort */
+
+	EVENT_CONSTRAINT_END
+};
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 {
 	struct event_constraint *c;
@@ -588,6 +653,12 @@ void intel_pmu_pebs_disable(struct perf_
 	struct hw_perf_event *hwc = &event->hw;
 
 	cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
+
+	if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_LDLAT)
+		cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32));
+	else if (event->hw.constraint->flags & PERF_X86_EVENT_PEBS_ST)
+		cpuc->pebs_enabled &= ~(1ULL << 63);
+
 	if (cpuc->enabled)
 		wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
 
@@ -697,6 +768,7 @@ static void __intel_pmu_pebs_event(struc
 	 */
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct pebs_record_nhm *pebs = __pebs;
+	struct pebs_record_hsw *pebs_hsw = __pebs;
 	struct perf_sample_data data;
 	struct pt_regs regs;
 	u64 sample_type;
@@ -706,7 +778,8 @@ static void __intel_pmu_pebs_event(struc
 		return;
 
 	fll = event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT;
-	fst = event->hw.flags & PERF_X86_EVENT_PEBS_ST;
+	fst = event->hw.flags & (PERF_X86_EVENT_PEBS_ST |
+				 PERF_X86_EVENT_PEBS_ST_HSW);
 
 	perf_sample_data_init(&data, 0, event->hw.last_period);
 
@@ -717,9 +790,6 @@ static void __intel_pmu_pebs_event(struc
 	 * if PEBS-LL or PreciseStore
 	 */
 	if (fll || fst) {
-		if (sample_type & PERF_SAMPLE_ADDR)
-			data.addr = pebs->dla;
-
 		/*
 		 * Use latency for weight (only avail with PEBS-LL)
 		 */
@@ -732,6 +802,9 @@ static void __intel_pmu_pebs_event(struc
 		if (sample_type & PERF_SAMPLE_DATA_SRC) {
 			if (fll)
 				data.data_src.val = load_latency_data(pebs->dse);
+			else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW)
+				data.data_src.val =
+					precise_store_data_hsw(pebs->dse);
 			else
 				data.data_src.val = precise_store_data(pebs->dse);
 		}
@@ -753,11 +826,18 @@ static void __intel_pmu_pebs_event(struc
 	regs.bp = pebs->bp;
 	regs.sp = pebs->sp;
 
-	if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(&regs))
+	if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
+		regs.ip = pebs_hsw->real_ip;
+		regs.flags |= PERF_EFLAGS_EXACT;
+	} else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(&regs))
 		regs.flags |= PERF_EFLAGS_EXACT;
 	else
 		regs.flags &= ~PERF_EFLAGS_EXACT;
 
+	if ((event->attr.sample_type & PERF_SAMPLE_ADDR) &&
+		x86_pmu.intel_cap.pebs_format >= 1)
+		data.addr = pebs->dla;
+
 	if (has_branch_stack(event))
 		data.br_stack = &cpuc->lbr_stack;
 
@@ -806,35 +886,22 @@ static void intel_pmu_drain_pebs_core(st
 	__intel_pmu_pebs_event(event, iregs, at);
 }
 
-static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
+static void __intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, void *at,
+					void *top)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct debug_store *ds = cpuc->ds;
-	struct pebs_record_nhm *at, *top;
 	struct perf_event *event = NULL;
 	u64 status = 0;
-	int bit, n;
-
-	if (!x86_pmu.pebs_active)
-		return;
-
-	at  = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
-	top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
+	int bit;
 
 	ds->pebs_index = ds->pebs_buffer_base;
 
-	n = top - at;
-	if (n <= 0)
-		return;
-
-	/*
-	 * Should not happen, we program the threshold at 1 and do not
-	 * set a reset value.
-	 */
-	WARN_ONCE(n > x86_pmu.max_pebs_events, "Unexpected number of pebs records %d\n", n);
+	for (; at < top; at += x86_pmu.pebs_record_size) {
+		struct pebs_record_nhm *p = at;
 
-	for ( ; at < top; at++) {
-		for_each_set_bit(bit, (unsigned long *)&at->status, x86_pmu.max_pebs_events) {
+		for_each_set_bit(bit, (unsigned long *)&p->status,
+				 x86_pmu.max_pebs_events) {
 			event = cpuc->events[bit];
 			if (!test_bit(bit, cpuc->active_mask))
 				continue;
@@ -857,6 +924,61 @@ static void intel_pmu_drain_pebs_nhm(str
 	}
 }
 
+static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct debug_store *ds = cpuc->ds;
+	struct pebs_record_nhm *at, *top;
+	int n;
+
+	if (!x86_pmu.pebs_active)
+		return;
+
+	at  = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
+	top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
+
+	ds->pebs_index = ds->pebs_buffer_base;
+
+	n = top - at;
+	if (n <= 0)
+		return;
+
+	/*
+	 * Should not happen, we program the threshold at 1 and do not
+	 * set a reset value.
+	 */
+	WARN_ONCE(n > x86_pmu.max_pebs_events,
+		  "Unexpected number of pebs records %d\n", n);
+
+	return __intel_pmu_drain_pebs_nhm(iregs, at, top);
+}
+
+static void intel_pmu_drain_pebs_hsw(struct pt_regs *iregs)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct debug_store *ds = cpuc->ds;
+	struct pebs_record_hsw *at, *top;
+	int n;
+
+	if (!x86_pmu.pebs_active)
+		return;
+
+	at  = (struct pebs_record_hsw *)(unsigned long)ds->pebs_buffer_base;
+	top = (struct pebs_record_hsw *)(unsigned long)ds->pebs_index;
+
+	n = top - at;
+	if (n <= 0)
+		return;
+	/*
+	 * Should not happen, we program the threshold at 1 and do not
+	 * set a reset value.
+	 */
+	WARN_ONCE(n > x86_pmu.max_pebs_events,
+		  "Unexpected number of pebs records %d\n", n);
+
+	return __intel_pmu_drain_pebs_nhm(iregs, at, top);
+}
+
 /*
  * BTS, PEBS probe and setup
  */
@@ -888,6 +1010,12 @@ void intel_ds_init(void)
 			x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
 			break;
 
+		case 2:
+			pr_cont("PEBS fmt2%c, ", pebs_type);
+			x86_pmu.pebs_record_size = sizeof(struct pebs_record_hsw);
+			x86_pmu.drain_pebs = intel_pmu_drain_pebs_hsw;
+			break;
+
 		default:
 			printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
 			x86_pmu.pebs = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel_lbr.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_lbr.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel_lbr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_lbr.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,16 @@ enum {
 	LBR_FORMAT_LIP		= 0x01,
 	LBR_FORMAT_EIP		= 0x02,
 	LBR_FORMAT_EIP_FLAGS	= 0x03,
+	LBR_FORMAT_EIP_FLAGS2	= 0x04,
+	LBR_FORMAT_MAX_KNOWN    = LBR_FORMAT_EIP_FLAGS2,
+};
+
+static enum {
+	LBR_EIP_FLAGS		= 1,
+	LBR_TSX			= 2,
+} lbr_desc[LBR_FORMAT_MAX_KNOWN + 1] = {
+	[LBR_FORMAT_EIP_FLAGS]  = LBR_EIP_FLAGS,
+	[LBR_FORMAT_EIP_FLAGS2] = LBR_EIP_FLAGS | LBR_TSX,
 };
 
 /*
@@ -56,6 +66,8 @@ enum {
 	 LBR_FAR)
 
 #define LBR_FROM_FLAG_MISPRED  (1ULL << 63)
+#define LBR_FROM_FLAG_IN_TX    (1ULL << 62)
+#define LBR_FROM_FLAG_ABORT    (1ULL << 61)
 
 #define for_each_branch_sample_type(x) \
 	for ((x) = PERF_SAMPLE_BRANCH_USER; \
@@ -81,9 +93,13 @@ enum {
 	X86_BR_JMP      = 1 << 9, /* jump */
 	X86_BR_IRQ      = 1 << 10,/* hw interrupt or trap or fault */
 	X86_BR_IND_CALL = 1 << 11,/* indirect calls */
+	X86_BR_ABORT    = 1 << 12,/* transaction abort */
+	X86_BR_IN_TX    = 1 << 13,/* in transaction */
+	X86_BR_NO_TX    = 1 << 14,/* not in transaction */
 };
 
 #define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
+#define X86_BR_ANYTX (X86_BR_NO_TX | X86_BR_IN_TX)
 
 #define X86_BR_ANY       \
 	(X86_BR_CALL    |\
@@ -95,6 +111,7 @@ enum {
 	 X86_BR_JCC     |\
 	 X86_BR_JMP	 |\
 	 X86_BR_IRQ	 |\
+	 X86_BR_ABORT	 |\
 	 X86_BR_IND_CALL)
 
 #define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
@@ -270,21 +287,31 @@ static void intel_pmu_lbr_read_64(struct
 
 	for (i = 0; i < x86_pmu.lbr_nr; i++) {
 		unsigned long lbr_idx = (tos - i) & mask;
-		u64 from, to, mis = 0, pred = 0;
+		u64 from, to, mis = 0, pred = 0, in_tx = 0, abort = 0;
+		int skip = 0;
+		int lbr_flags = lbr_desc[lbr_format];
 
 		rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
 		rdmsrl(x86_pmu.lbr_to   + lbr_idx, to);
 
-		if (lbr_format == LBR_FORMAT_EIP_FLAGS) {
+		if (lbr_flags & LBR_EIP_FLAGS) {
 			mis = !!(from & LBR_FROM_FLAG_MISPRED);
 			pred = !mis;
-			from = (u64)((((s64)from) << 1) >> 1);
+			skip = 1;
 		}
+		if (lbr_flags & LBR_TSX) {
+			in_tx = !!(from & LBR_FROM_FLAG_IN_TX);
+			abort = !!(from & LBR_FROM_FLAG_ABORT);
+			skip = 3;
+		}
+		from = (u64)((((s64)from) << skip) >> skip);
 
 		cpuc->lbr_entries[i].from	= from;
 		cpuc->lbr_entries[i].to		= to;
 		cpuc->lbr_entries[i].mispred	= mis;
 		cpuc->lbr_entries[i].predicted	= pred;
+		cpuc->lbr_entries[i].in_tx	= in_tx;
+		cpuc->lbr_entries[i].abort	= abort;
 		cpuc->lbr_entries[i].reserved	= 0;
 	}
 	cpuc->lbr_stack.nr = i;
@@ -310,7 +337,7 @@ void intel_pmu_lbr_read(void)
  * - in case there is no HW filter
  * - in case the HW filter has errata or limitations
  */
-static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
+static void intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
 {
 	u64 br_type = event->attr.branch_sample_type;
 	int mask = 0;
@@ -318,11 +345,8 @@ static int intel_pmu_setup_sw_lbr_filter
 	if (br_type & PERF_SAMPLE_BRANCH_USER)
 		mask |= X86_BR_USER;
 
-	if (br_type & PERF_SAMPLE_BRANCH_KERNEL) {
-		if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
-			return -EACCES;
+	if (br_type & PERF_SAMPLE_BRANCH_KERNEL)
 		mask |= X86_BR_KERNEL;
-	}
 
 	/* we ignore BRANCH_HV here */
 
@@ -337,13 +361,21 @@ static int intel_pmu_setup_sw_lbr_filter
 
 	if (br_type & PERF_SAMPLE_BRANCH_IND_CALL)
 		mask |= X86_BR_IND_CALL;
+
+	if (br_type & PERF_SAMPLE_BRANCH_ABORT_TX)
+		mask |= X86_BR_ABORT;
+
+	if (br_type & PERF_SAMPLE_BRANCH_IN_TX)
+		mask |= X86_BR_IN_TX;
+
+	if (br_type & PERF_SAMPLE_BRANCH_NO_TX)
+		mask |= X86_BR_NO_TX;
+
 	/*
 	 * stash actual user request into reg, it may
 	 * be used by fixup code for some CPU
 	 */
 	event->hw.branch_reg.reg = mask;
-
-	return 0;
 }
 
 /*
@@ -391,9 +423,7 @@ int intel_pmu_setup_lbr_filter(struct pe
 	/*
 	 * setup SW LBR filter
 	 */
-	ret = intel_pmu_setup_sw_lbr_filter(event);
-	if (ret)
-		return ret;
+	intel_pmu_setup_sw_lbr_filter(event);
 
 	/*
 	 * setup HW LBR filter, if any
@@ -415,7 +445,7 @@ int intel_pmu_setup_lbr_filter(struct pe
  * decoded (e.g., text page not present), then X86_BR_NONE is
  * returned.
  */
-static int branch_type(unsigned long from, unsigned long to)
+static int branch_type(unsigned long from, unsigned long to, int abort)
 {
 	struct insn insn;
 	void *addr;
@@ -435,6 +465,9 @@ static int branch_type(unsigned long fro
 	if (from == 0 || to == 0)
 		return X86_BR_NONE;
 
+	if (abort)
+		return X86_BR_ABORT | to_plm;
+
 	if (from_plm == X86_BR_USER) {
 		/*
 		 * can happen if measuring at the user level only
@@ -581,7 +614,13 @@ intel_pmu_lbr_filter(struct cpu_hw_event
 		from = cpuc->lbr_entries[i].from;
 		to = cpuc->lbr_entries[i].to;
 
-		type = branch_type(from, to);
+		type = branch_type(from, to, cpuc->lbr_entries[i].abort);
+		if (type != X86_BR_NONE && (br_sel & X86_BR_ANYTX)) {
+			if (cpuc->lbr_entries[i].in_tx)
+				type |= X86_BR_IN_TX;
+			else
+				type |= X86_BR_NO_TX;
+		}
 
 		/* if type does not correspond, then discard */
 		if (type == X86_BR_NONE || (br_sel & type) != type) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel_uncore.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_uncore.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel_uncore.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_uncore.c	2013-08-25 20:43:22.000000000 -0400
@@ -314,8 +314,8 @@ static struct uncore_event_desc snbep_un
 static struct uncore_event_desc snbep_uncore_qpi_events[] = {
 	INTEL_UNCORE_EVENT_DESC(clockticks,       "event=0x14"),
 	INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"),
-	INTEL_UNCORE_EVENT_DESC(drs_data,         "event=0x02,umask=0x08"),
-	INTEL_UNCORE_EVENT_DESC(ncb_data,         "event=0x03,umask=0x04"),
+	INTEL_UNCORE_EVENT_DESC(drs_data,         "event=0x102,umask=0x08"),
+	INTEL_UNCORE_EVENT_DESC(ncb_data,         "event=0x103,umask=0x04"),
 	{ /* end: all zeroes */ },
 };
 
@@ -536,7 +536,7 @@ __snbep_cbox_get_constraint(struct intel
 	if (!uncore_box_is_fake(box))
 		reg1->alloc |= alloc;
 
-	return 0;
+	return NULL;
 fail:
 	for (; i >= 0; i--) {
 		if (alloc & (0x1 << i))
@@ -644,7 +644,7 @@ snbep_pcu_get_constraint(struct intel_un
 	    (!uncore_box_is_fake(box) && reg1->alloc))
 		return NULL;
 again:
-	mask = 0xff << (idx * 8);
+	mask = 0xffULL << (idx * 8);
 	raw_spin_lock_irqsave(&er->lock, flags);
 	if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) ||
 	    !((config1 ^ er->config) & mask)) {
@@ -1923,7 +1923,7 @@ static u64 nhmex_mbox_alter_er(struct pe
 {
 	struct hw_perf_event *hwc = &event->hw;
 	struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
-	int idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
+	u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
 	u64 config = reg1->config;
 
 	/* get the non-shared control bits and shift them */
@@ -2723,15 +2723,16 @@ static void uncore_put_event_constraint(
 static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n)
 {
 	unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
-	struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX];
+	struct event_constraint *c;
 	int i, wmin, wmax, ret = 0;
 	struct hw_perf_event *hwc;
 
 	bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX);
 
 	for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) {
+		hwc = &box->event_list[i]->hw;
 		c = uncore_get_event_constraint(box, box->event_list[i]);
-		constraints[i] = c;
+		hwc->constraint = c;
 		wmin = min(wmin, c->weight);
 		wmax = max(wmax, c->weight);
 	}
@@ -2739,7 +2740,7 @@ static int uncore_assign_events(struct i
 	/* fastpath, try to reuse previous register */
 	for (i = 0; i < n; i++) {
 		hwc = &box->event_list[i]->hw;
-		c = constraints[i];
+		c = hwc->constraint;
 
 		/* never assigned */
 		if (hwc->idx == -1)
@@ -2759,7 +2760,8 @@ static int uncore_assign_events(struct i
 	}
 	/* slow path */
 	if (i != n)
-		ret = perf_assign_events(constraints, n, wmin, wmax, assign);
+		ret = perf_assign_events(box->event_list, n,
+					 wmin, wmax, assign);
 
 	if (!assign || ret) {
 		for (i = 0; i < n; i++)
@@ -3295,7 +3297,7 @@ static void __init uncore_pci_exit(void)
 /* CPU hot plug/unplug are serialized by cpu_add_remove_lock mutex */
 static LIST_HEAD(boxes_to_free);
 
-static void __cpuinit uncore_kfree_boxes(void)
+static void uncore_kfree_boxes(void)
 {
 	struct intel_uncore_box *box;
 
@@ -3307,7 +3309,7 @@ static void __cpuinit uncore_kfree_boxes
 	}
 }
 
-static void __cpuinit uncore_cpu_dying(int cpu)
+static void uncore_cpu_dying(int cpu)
 {
 	struct intel_uncore_type *type;
 	struct intel_uncore_pmu *pmu;
@@ -3326,7 +3328,7 @@ static void __cpuinit uncore_cpu_dying(i
 	}
 }
 
-static int __cpuinit uncore_cpu_starting(int cpu)
+static int uncore_cpu_starting(int cpu)
 {
 	struct intel_uncore_type *type;
 	struct intel_uncore_pmu *pmu;
@@ -3369,7 +3371,7 @@ static int __cpuinit uncore_cpu_starting
 	return 0;
 }
 
-static int __cpuinit uncore_cpu_prepare(int cpu, int phys_id)
+static int uncore_cpu_prepare(int cpu, int phys_id)
 {
 	struct intel_uncore_type *type;
 	struct intel_uncore_pmu *pmu;
@@ -3395,7 +3397,7 @@ static int __cpuinit uncore_cpu_prepare(
 	return 0;
 }
 
-static void __cpuinit
+static void
 uncore_change_context(struct intel_uncore_type **uncores, int old_cpu, int new_cpu)
 {
 	struct intel_uncore_type *type;
@@ -3433,7 +3435,7 @@ uncore_change_context(struct intel_uncor
 	}
 }
 
-static void __cpuinit uncore_event_exit_cpu(int cpu)
+static void uncore_event_exit_cpu(int cpu)
 {
 	int i, phys_id, target;
 
@@ -3461,7 +3463,7 @@ static void __cpuinit uncore_event_exit_
 	uncore_change_context(pci_uncores, cpu, target);
 }
 
-static void __cpuinit uncore_event_init_cpu(int cpu)
+static void uncore_event_init_cpu(int cpu)
 {
 	int i, phys_id;
 
@@ -3477,8 +3479,8 @@ static void __cpuinit uncore_event_init_
 	uncore_change_context(pci_uncores, -1, cpu);
 }
 
-static int
- __cpuinit uncore_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+static int uncore_cpu_notifier(struct notifier_block *self,
+			       unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (long)hcpu;
 
@@ -3518,7 +3520,7 @@ static int
 	return NOTIFY_OK;
 }
 
-static struct notifier_block uncore_cpu_nb __cpuinitdata = {
+static struct notifier_block uncore_cpu_nb = {
 	.notifier_call	= uncore_cpu_notifier,
 	/*
 	 * to migrate uncore events, our notifier should be executed
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel_uncore.h linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_uncore.h
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/perf_event_intel_uncore.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/perf_event_intel_uncore.h	2013-08-25 20:43:22.000000000 -0400
@@ -337,10 +337,10 @@
 		 NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)
 
 #define NHMEX_M_PMON_ZDP_CTL_FVC_MASK		(((1 << 11) - 1) | (1 << 23))
-#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7 << (11 + 3 * (n)))
+#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7ULL << (11 + 3 * (n)))
 
 #define WSMEX_M_PMON_ZDP_CTL_FVC_MASK		(((1 << 12) - 1) | (1 << 24))
-#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7 << (12 + 3 * (n)))
+#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n)	(0x7ULL << (12 + 3 * (n)))
 
 /*
  * use the 9~13 bits to select event If the 7th bit is not set,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/powerflags.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/powerflags.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/powerflags.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/powerflags.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,10 +11,10 @@ const char *const x86_power_flags[32] =
 	"fid",  /* frequency id control */
 	"vid",  /* voltage id control */
 	"ttp",  /* thermal trip */
-	"tm",
-	"stc",
-	"100mhzsteps",
-	"hwpstate",
+	"tm",	/* hardware thermal control */
+	"stc",	/* software thermal control */
+	"100mhzsteps", /* 100 MHz multiplier control */
+	"hwpstate", /* hardware P-state control */
 	"",	/* tsc invariant mapped to constant_tsc */
 	"cpb",  /* core performance boost */
 	"eff_freq_ro", /* Readonly aperf/mperf */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/proc.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/proc.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/proc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/proc.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,8 +37,8 @@ static void show_cpuinfo_misc(struct seq
 		   static_cpu_has_bug(X86_BUG_FDIV) ? "yes" : "no",
 		   static_cpu_has_bug(X86_BUG_F00F) ? "yes" : "no",
 		   static_cpu_has_bug(X86_BUG_COMA) ? "yes" : "no",
-		   c->hard_math ? "yes" : "no",
-		   c->hard_math ? "yes" : "no",
+		   static_cpu_has(X86_FEATURE_FPU) ? "yes" : "no",
+		   static_cpu_has(X86_FEATURE_FPU) ? "yes" : "no",
 		   c->cpuid_level,
 		   c->wp_works_ok ? "yes" : "no");
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/rdrand.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/rdrand.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/rdrand.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/rdrand.c	2013-08-25 20:43:22.000000000 -0400
@@ -52,7 +52,7 @@ static inline int rdrand_long(unsigned l
  */
 #define RESEED_LOOP ((512*128)/sizeof(unsigned long))
 
-void __cpuinit x86_init_rdrand(struct cpuinfo_x86 *c)
+void x86_init_rdrand(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_ARCH_RANDOM
 	unsigned long tmp;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/scattered.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/scattered.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/scattered.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/scattered.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,13 +24,13 @@ enum cpuid_regs {
 	CR_EBX
 };
 
-void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
+void init_scattered_cpuid_features(struct cpuinfo_x86 *c)
 {
 	u32 max_level;
 	u32 regs[4];
 	const struct cpuid_bit *cb;
 
-	static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
+	static const struct cpuid_bit cpuid_bits[] = {
 		{ X86_FEATURE_DTHERM,		CR_EAX, 0, 0x00000006, 0 },
 		{ X86_FEATURE_IDA,		CR_EAX, 1, 0x00000006, 0 },
 		{ X86_FEATURE_ARAT,		CR_EAX, 2, 0x00000006, 0 },
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/topology.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/topology.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/topology.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/topology.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,7 @@
  * exists, use it for populating initial_apicid and cpu topology
  * detection.
  */
-void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c)
+void detect_extended_topology(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
 	unsigned int eax, ebx, ecx, edx, sub_index;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/transmeta.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/transmeta.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/transmeta.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/transmeta.c	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,7 @@
 #include <asm/msr.h>
 #include "cpu.h"
 
-static void __cpuinit early_init_transmeta(struct cpuinfo_x86 *c)
+static void early_init_transmeta(struct cpuinfo_x86 *c)
 {
 	u32 xlvl;
 
@@ -17,7 +17,7 @@ static void __cpuinit early_init_transme
 	}
 }
 
-static void __cpuinit init_transmeta(struct cpuinfo_x86 *c)
+static void init_transmeta(struct cpuinfo_x86 *c)
 {
 	unsigned int cap_mask, uk, max, dummy;
 	unsigned int cms_rev1, cms_rev2;
@@ -98,7 +98,7 @@ static void __cpuinit init_transmeta(str
 #endif
 }
 
-static const struct cpu_dev __cpuinitconst transmeta_cpu_dev = {
+static const struct cpu_dev transmeta_cpu_dev = {
 	.c_vendor	= "Transmeta",
 	.c_ident	= { "GenuineTMx86", "TransmetaCPU" },
 	.c_early_init	= early_init_transmeta,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/umc.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/umc.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/umc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/umc.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
  * so no special init takes place.
  */
 
-static const struct cpu_dev __cpuinitconst umc_cpu_dev = {
+static const struct cpu_dev umc_cpu_dev = {
 	.c_vendor	= "UMC",
 	.c_ident	= { "UMC UMC UMC" },
 	.c_models = {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpu/vmware.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/vmware.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpu/vmware.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpu/vmware.c	2013-08-25 20:43:22.000000000 -0400
@@ -122,7 +122,7 @@ static bool __init vmware_platform(void)
  * so that the kernel could just trust the hypervisor with providing a
  * reliable virtual TSC that is suitable for timekeeping.
  */
-static void __cpuinit vmware_set_cpu_features(struct cpuinfo_x86 *c)
+static void vmware_set_cpu_features(struct cpuinfo_x86 *c)
 {
 	set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 	set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/cpuid.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpuid.c
--- linux-libre-3.10-gnu/arch/x86/kernel/cpuid.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/cpuid.c	2013-08-25 20:43:22.000000000 -0400
@@ -137,7 +137,7 @@ static const struct file_operations cpui
 	.open = cpuid_open,
 };
 
-static __cpuinit int cpuid_device_create(int cpu)
+static int cpuid_device_create(int cpu)
 {
 	struct device *dev;
 
@@ -151,9 +151,8 @@ static void cpuid_device_destroy(int cpu
 	device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
 }
 
-static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
-					      unsigned long action,
-					      void *hcpu)
+static int cpuid_class_cpu_callback(struct notifier_block *nfb,
+				    unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
 	int err = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/devicetree.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/devicetree.c
--- linux-libre-3.10-gnu/arch/x86/kernel/devicetree.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/devicetree.c	2013-08-25 20:43:22.000000000 -0400
@@ -133,7 +133,7 @@ static void x86_of_pci_irq_disable(struc
 {
 }
 
-void __cpuinit x86_of_pci_init(void)
+void x86_of_pci_init(void)
 {
 	pcibios_enable_irq = x86_of_pci_irq_enable;
 	pcibios_disable_irq = x86_of_pci_irq_disable;
@@ -364,9 +364,7 @@ static void dt_add_ioapic_domain(unsigne
 		 * and assigned so we can keep the 1:1 mapping which the ioapic
 		 * is having.
 		 */
-		ret = irq_domain_associate_many(id, 0, 0, NR_IRQS_LEGACY);
-		if (ret)
-			pr_err("Error mapping legacy IRQs: %d\n", ret);
+		irq_domain_associate_many(id, 0, 0, NR_IRQS_LEGACY);
 
 		if (num > NR_IRQS_LEGACY) {
 			ret = irq_create_strict_mappings(id, NR_IRQS_LEGACY,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/doublefault_32.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/doublefault_32.c
--- linux-libre-3.10-gnu/arch/x86/kernel/doublefault_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/doublefault_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,69 +0,0 @@
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/init_task.h>
-#include <linux/fs.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/desc.h>
-
-#define DOUBLEFAULT_STACKSIZE (1024)
-static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
-
-#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
-
-static void doublefault_fn(void)
-{
-	struct desc_ptr gdt_desc = {0, 0};
-	unsigned long gdt, tss;
-
-	native_store_gdt(&gdt_desc);
-	gdt = gdt_desc.address;
-
-	printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
-
-	if (ptr_ok(gdt)) {
-		gdt += GDT_ENTRY_TSS << 3;
-		tss = get_desc_base((struct desc_struct *)gdt);
-		printk(KERN_EMERG "double fault, tss at %08lx\n", tss);
-
-		if (ptr_ok(tss)) {
-			struct x86_hw_tss *t = (struct x86_hw_tss *)tss;
-
-			printk(KERN_EMERG "eip = %08lx, esp = %08lx\n",
-			       t->ip, t->sp);
-
-			printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
-				t->ax, t->bx, t->cx, t->dx);
-			printk(KERN_EMERG "esi = %08lx, edi = %08lx\n",
-				t->si, t->di);
-		}
-	}
-
-	for (;;)
-		cpu_relax();
-}
-
-struct tss_struct doublefault_tss __cacheline_aligned = {
-	.x86_tss = {
-		.sp0		= STACK_START,
-		.ss0		= __KERNEL_DS,
-		.ldt		= 0,
-		.io_bitmap_base	= INVALID_IO_BITMAP_OFFSET,
-
-		.ip		= (unsigned long) doublefault_fn,
-		/* 0x2 bit is always set */
-		.flags		= X86_EFLAGS_SF | 0x2,
-		.sp		= STACK_START,
-		.es		= __USER_DS,
-		.cs		= __KERNEL_CS,
-		.ss		= __KERNEL_DS,
-		.ds		= __USER_DS,
-		.fs		= __KERNEL_PERCPU,
-
-		.__cr3		= __pa_nodebug(swapper_pg_dir),
-	}
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/doublefault.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/doublefault.c
--- linux-libre-3.10-gnu/arch/x86/kernel/doublefault.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/doublefault.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,84 @@
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/desc.h>
+
+#ifdef CONFIG_X86_32
+
+#define DOUBLEFAULT_STACKSIZE (1024)
+static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
+#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
+
+#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
+
+static void doublefault_fn(void)
+{
+	struct desc_ptr gdt_desc = {0, 0};
+	unsigned long gdt, tss;
+
+	native_store_gdt(&gdt_desc);
+	gdt = gdt_desc.address;
+
+	printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
+
+	if (ptr_ok(gdt)) {
+		gdt += GDT_ENTRY_TSS << 3;
+		tss = get_desc_base((struct desc_struct *)gdt);
+		printk(KERN_EMERG "double fault, tss at %08lx\n", tss);
+
+		if (ptr_ok(tss)) {
+			struct x86_hw_tss *t = (struct x86_hw_tss *)tss;
+
+			printk(KERN_EMERG "eip = %08lx, esp = %08lx\n",
+			       t->ip, t->sp);
+
+			printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
+				t->ax, t->bx, t->cx, t->dx);
+			printk(KERN_EMERG "esi = %08lx, edi = %08lx\n",
+				t->si, t->di);
+		}
+	}
+
+	for (;;)
+		cpu_relax();
+}
+
+struct tss_struct doublefault_tss __cacheline_aligned = {
+	.x86_tss = {
+		.sp0		= STACK_START,
+		.ss0		= __KERNEL_DS,
+		.ldt		= 0,
+		.io_bitmap_base	= INVALID_IO_BITMAP_OFFSET,
+
+		.ip		= (unsigned long) doublefault_fn,
+		/* 0x2 bit is always set */
+		.flags		= X86_EFLAGS_SF | 0x2,
+		.sp		= STACK_START,
+		.es		= __USER_DS,
+		.cs		= __KERNEL_CS,
+		.ss		= __KERNEL_DS,
+		.ds		= __USER_DS,
+		.fs		= __KERNEL_PERCPU,
+
+		.__cr3		= __pa_nodebug(swapper_pg_dir),
+	}
+};
+
+/* dummy for do_double_fault() call */
+void df_debug(struct pt_regs *regs, long error_code) {}
+
+#else /* !CONFIG_X86_32 */
+
+void df_debug(struct pt_regs *regs, long error_code)
+{
+	pr_emerg("PANIC: double fault, error_code: 0x%lx\n", error_code);
+	show_regs(regs);
+	panic("Machine halted.");
+}
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/early-quirks.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/early-quirks.c
--- linux-libre-3.10-gnu/arch/x86/kernel/early-quirks.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/early-quirks.c	2013-08-25 20:43:22.000000000 -0400
@@ -196,15 +196,23 @@ static void __init ati_bugs_contd(int nu
 static void __init intel_remapping_check(int num, int slot, int func)
 {
 	u8 revision;
+	u16 device;
 
+	device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID);
 	revision = read_pci_config_byte(num, slot, func, PCI_REVISION_ID);
 
 	/*
-	 * Revision 0x13 of this chipset supports irq remapping
-	 * but has an erratum that breaks its behavior, flag it as such
+ 	 * Revision 13 of all triggering devices id in this quirk have
+	 * a problem draining interrupts when irq remapping is enabled,
+	 * and should be flagged as broken.  Additionally revisions 0x12
+	 * and 0x22 of device id 0x3405 has this problem.
 	 */
 	if (revision == 0x13)
 		set_irq_remapping_broken();
+	else if ((device == 0x3405) &&
+	    ((revision == 0x12) ||
+	     (revision == 0x22)))
+		set_irq_remapping_broken();
 
 }
 
@@ -239,6 +247,8 @@ static struct chipset early_qrk[] __init
 	  PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
 	{ PCI_VENDOR_ID_INTEL, 0x3403, PCI_CLASS_BRIDGE_HOST,
 	  PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
+	{ PCI_VENDOR_ID_INTEL, 0x3405, PCI_CLASS_BRIDGE_HOST,
+	  PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
 	{ PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST,
 	  PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
 	{}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/entry_32.S linux-libre-3.11-rc7-gnu/arch/x86/kernel/entry_32.S
--- linux-libre-3.10-gnu/arch/x86/kernel/entry_32.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/entry_32.S	2013-08-25 20:43:22.000000000 -0400
@@ -801,7 +801,17 @@ ENTRY(name)				\
 	CFI_ENDPROC;			\
 ENDPROC(name)
 
-#define BUILD_INTERRUPT(name, nr)	BUILD_INTERRUPT3(name, nr, smp_##name)
+
+#ifdef CONFIG_TRACING
+#define TRACE_BUILD_INTERRUPT(name, nr)		\
+	BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name)
+#else
+#define TRACE_BUILD_INTERRUPT(name, nr)
+#endif
+
+#define BUILD_INTERRUPT(name, nr) \
+	BUILD_INTERRUPT3(name, nr, smp_##name); \
+	TRACE_BUILD_INTERRUPT(name, nr)
 
 /* The include is where all of the SMP etc. interrupts come from */
 #include <asm/entry_arch.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/entry_64.S linux-libre-3.11-rc7-gnu/arch/x86/kernel/entry_64.S
--- linux-libre-3.10-gnu/arch/x86/kernel/entry_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/entry_64.S	2013-08-25 20:43:22.000000000 -0400
@@ -365,7 +365,7 @@ ENDPROC(native_usergs_sysret64)
 	/*CFI_REL_OFFSET	ss,0*/
 	pushq_cfi %rax /* rsp */
 	CFI_REL_OFFSET	rsp,0
-	pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_BIT1) /* eflags - interrupts on */
+	pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_FIXED) /* eflags - interrupts on */
 	/*CFI_REL_OFFSET	rflags,0*/
 	pushq_cfi $__KERNEL_CS /* cs */
 	/*CFI_REL_OFFSET	cs,0*/
@@ -1138,7 +1138,7 @@ END(common_interrupt)
 /*
  * APIC interrupts.
  */
-.macro apicinterrupt num sym do_sym
+.macro apicinterrupt3 num sym do_sym
 ENTRY(\sym)
 	INTR_FRAME
 	ASM_CLAC
@@ -1150,15 +1150,32 @@ ENTRY(\sym)
 END(\sym)
 .endm
 
+#ifdef CONFIG_TRACING
+#define trace(sym) trace_##sym
+#define smp_trace(sym) smp_trace_##sym
+
+.macro trace_apicinterrupt num sym
+apicinterrupt3 \num trace(\sym) smp_trace(\sym)
+.endm
+#else
+.macro trace_apicinterrupt num sym do_sym
+.endm
+#endif
+
+.macro apicinterrupt num sym do_sym
+apicinterrupt3 \num \sym \do_sym
+trace_apicinterrupt \num \sym
+.endm
+
 #ifdef CONFIG_SMP
-apicinterrupt IRQ_MOVE_CLEANUP_VECTOR \
+apicinterrupt3 IRQ_MOVE_CLEANUP_VECTOR \
 	irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt
-apicinterrupt REBOOT_VECTOR \
+apicinterrupt3 REBOOT_VECTOR \
 	reboot_interrupt smp_reboot_interrupt
 #endif
 
 #ifdef CONFIG_X86_UV
-apicinterrupt UV_BAU_MESSAGE \
+apicinterrupt3 UV_BAU_MESSAGE \
 	uv_bau_message_intr1 uv_bau_message_interrupt
 #endif
 apicinterrupt LOCAL_TIMER_VECTOR \
@@ -1167,14 +1184,19 @@ apicinterrupt X86_PLATFORM_IPI_VECTOR \
 	x86_platform_ipi smp_x86_platform_ipi
 
 #ifdef CONFIG_HAVE_KVM
-apicinterrupt POSTED_INTR_VECTOR \
+apicinterrupt3 POSTED_INTR_VECTOR \
 	kvm_posted_intr_ipi smp_kvm_posted_intr_ipi
 #endif
 
+#ifdef CONFIG_X86_MCE_THRESHOLD
 apicinterrupt THRESHOLD_APIC_VECTOR \
 	threshold_interrupt smp_threshold_interrupt
+#endif
+
+#ifdef CONFIG_X86_THERMAL_VECTOR
 apicinterrupt THERMAL_APIC_VECTOR \
 	thermal_interrupt smp_thermal_interrupt
+#endif
 
 #ifdef CONFIG_SMP
 apicinterrupt CALL_FUNCTION_SINGLE_VECTOR \
@@ -1451,13 +1473,13 @@ ENTRY(xen_failsafe_callback)
 	CFI_ENDPROC
 END(xen_failsafe_callback)
 
-apicinterrupt HYPERVISOR_CALLBACK_VECTOR \
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
 	xen_hvm_callback_vector xen_evtchn_do_upcall
 
 #endif /* CONFIG_XEN */
 
 #if IS_ENABLED(CONFIG_HYPERV)
-apicinterrupt HYPERVISOR_CALLBACK_VECTOR \
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
 	hyperv_callback_vector hyperv_vector_handler
 #endif /* CONFIG_HYPERV */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/head_32.S linux-libre-3.11-rc7-gnu/arch/x86/kernel/head_32.S
--- linux-libre-3.10-gnu/arch/x86/kernel/head_32.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/head_32.S	2013-08-25 20:43:22.000000000 -0400
@@ -292,7 +292,6 @@ ENDPROC(start_cpu0)
  * If cpu hotplug is not supported then this code can go in init section
  * which will be freed later
  */
-__CPUINIT
 ENTRY(startup_32_smp)
 	cld
 	movl $(__BOOT_DS),%eax
@@ -444,7 +443,6 @@ is486:
 	orl %ecx,%eax
 	movl %eax,%cr0
 
-	call check_x87
 	lgdt early_gdt_descr
 	lidt idt_descr
 	ljmp $(__KERNEL_CS),$1f
@@ -467,26 +465,6 @@ is486:
 	pushl $0		# fake return address for unwinder
 	jmp *(initial_code)
 
-/*
- * We depend on ET to be correct. This checks for 287/387.
- */
-check_x87:
-	movb $0,X86_HARD_MATH
-	clts
-	fninit
-	fstsw %ax
-	cmpb $0,%al
-	je 1f
-	movl %cr0,%eax		/* no coprocessor: have to set bits */
-	xorl $4,%eax		/* set EM */
-	movl %eax,%cr0
-	ret
-	ALIGN
-1:	movb $1,X86_HARD_MATH
-	.byte 0xDB,0xE4		/* fsetpm for 287, ignored by 387 */
-	ret
-
-	
 #include "verify_cpu.S"
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/head_64.S linux-libre-3.11-rc7-gnu/arch/x86/kernel/head_64.S
--- linux-libre-3.10-gnu/arch/x86/kernel/head_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/head_64.S	2013-08-25 20:43:22.000000000 -0400
@@ -512,15 +512,6 @@ ENTRY(phys_base)
 
 #include "../../x86/xen/xen-head.S"
 	
-	.section .bss, "aw", @nobits
-	.align L1_CACHE_BYTES
-ENTRY(idt_table)
-	.skip IDT_ENTRIES * 16
-
-	.align L1_CACHE_BYTES
-ENTRY(nmi_idt_table)
-	.skip IDT_ENTRIES * 16
-
 	__PAGE_ALIGNED_BSS
 NEXT_PAGE(empty_zero_page)
 	.skip PAGE_SIZE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/hw_breakpoint.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/hw_breakpoint.c
--- linux-libre-3.10-gnu/arch/x86/kernel/hw_breakpoint.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/hw_breakpoint.c	2013-08-25 20:43:22.000000000 -0400
@@ -393,6 +393,9 @@ void flush_ptrace_hw_breakpoint(struct t
 		unregister_hw_breakpoint(t->ptrace_bps[i]);
 		t->ptrace_bps[i] = NULL;
 	}
+
+	t->debugreg6 = 0;
+	t->ptrace_dr7 = 0;
 }
 
 void hw_breakpoint_restore(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/i387.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/i387.c
--- linux-libre-3.10-gnu/arch/x86/kernel/i387.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/i387.c	2013-08-25 20:43:22.000000000 -0400
@@ -108,15 +108,15 @@ EXPORT_SYMBOL(unlazy_fpu);
 unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
 unsigned int xstate_size;
 EXPORT_SYMBOL_GPL(xstate_size);
-static struct i387_fxsave_struct fx_scratch __cpuinitdata;
+static struct i387_fxsave_struct fx_scratch;
 
-static void __cpuinit mxcsr_feature_mask_init(void)
+static void mxcsr_feature_mask_init(void)
 {
 	unsigned long mask = 0;
 
 	if (cpu_has_fxsr) {
 		memset(&fx_scratch, 0, sizeof(struct i387_fxsave_struct));
-		asm volatile("fxsave %0" : : "m" (fx_scratch));
+		asm volatile("fxsave %0" : "+m" (fx_scratch));
 		mask = fx_scratch.mxcsr_mask;
 		if (mask == 0)
 			mask = 0x0000ffbf;
@@ -124,14 +124,14 @@ static void __cpuinit mxcsr_feature_mask
 	mxcsr_feature_mask &= mask;
 }
 
-static void __cpuinit init_thread_xstate(void)
+static void init_thread_xstate(void)
 {
 	/*
 	 * Note that xstate_size might be overwriten later during
 	 * xsave_init().
 	 */
 
-	if (!HAVE_HWFP) {
+	if (!cpu_has_fpu) {
 		/*
 		 * Disable xsave as we do not support it if i387
 		 * emulation is enabled.
@@ -153,11 +153,19 @@ static void __cpuinit init_thread_xstate
  * into all processes.
  */
 
-void __cpuinit fpu_init(void)
+void fpu_init(void)
 {
 	unsigned long cr0;
 	unsigned long cr4_mask = 0;
 
+#ifndef CONFIG_MATH_EMULATION
+	if (!cpu_has_fpu) {
+		pr_emerg("No FPU found and no math emulation present\n");
+		pr_emerg("Giving up\n");
+		for (;;)
+			asm volatile("hlt");
+	}
+#endif
 	if (cpu_has_fxsr)
 		cr4_mask |= X86_CR4_OSFXSR;
 	if (cpu_has_xmm)
@@ -167,7 +175,7 @@ void __cpuinit fpu_init(void)
 
 	cr0 = read_cr0();
 	cr0 &= ~(X86_CR0_TS|X86_CR0_EM); /* clear TS and EM */
-	if (!HAVE_HWFP)
+	if (!cpu_has_fpu)
 		cr0 |= X86_CR0_EM;
 	write_cr0(cr0);
 
@@ -185,7 +193,7 @@ void __cpuinit fpu_init(void)
 
 void fpu_finit(struct fpu *fpu)
 {
-	if (!HAVE_HWFP) {
+	if (!cpu_has_fpu) {
 		finit_soft_fpu(&fpu->state->soft);
 		return;
 	}
@@ -214,7 +222,7 @@ int init_fpu(struct task_struct *tsk)
 	int ret;
 
 	if (tsk_used_math(tsk)) {
-		if (HAVE_HWFP && tsk == current)
+		if (cpu_has_fpu && tsk == current)
 			unlazy_fpu(tsk);
 		tsk->thread.fpu.last_cpu = ~0;
 		return 0;
@@ -511,14 +519,13 @@ int fpregs_get(struct task_struct *targe
 	if (ret)
 		return ret;
 
-	if (!HAVE_HWFP)
+	if (!static_cpu_has(X86_FEATURE_FPU))
 		return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf);
 
-	if (!cpu_has_fxsr) {
+	if (!cpu_has_fxsr)
 		return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
 					   &target->thread.fpu.state->fsave, 0,
 					   -1);
-	}
 
 	sanitize_i387_state(target);
 
@@ -545,13 +552,13 @@ int fpregs_set(struct task_struct *targe
 
 	sanitize_i387_state(target);
 
-	if (!HAVE_HWFP)
+	if (!static_cpu_has(X86_FEATURE_FPU))
 		return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf);
 
-	if (!cpu_has_fxsr) {
+	if (!cpu_has_fxsr)
 		return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-					  &target->thread.fpu.state->fsave, 0, -1);
-	}
+					  &target->thread.fpu.state->fsave, 0,
+					  -1);
 
 	if (pos > 0 || count < sizeof(env))
 		convert_from_fxsr(&env, target);
@@ -592,3 +599,33 @@ int dump_fpu(struct pt_regs *regs, struc
 EXPORT_SYMBOL(dump_fpu);
 
 #endif	/* CONFIG_X86_32 || CONFIG_IA32_EMULATION */
+
+static int __init no_387(char *s)
+{
+	setup_clear_cpu_cap(X86_FEATURE_FPU);
+	return 1;
+}
+
+__setup("no387", no_387);
+
+void fpu_detect(struct cpuinfo_x86 *c)
+{
+	unsigned long cr0;
+	u16 fsw, fcw;
+
+	fsw = fcw = 0xffff;
+
+	cr0 = read_cr0();
+	cr0 &= ~(X86_CR0_TS | X86_CR0_EM);
+	write_cr0(cr0);
+
+	asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
+		     : "+m" (fsw), "+m" (fcw));
+
+	if (fsw == 0 && (fcw & 0x103f) == 0x003f)
+		set_cpu_cap(c, X86_FEATURE_FPU);
+	else
+		clear_cpu_cap(c, X86_FEATURE_FPU);
+
+	/* The final cr0 value is set in fpu_init() */
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/irq_32.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/irq_32.c
--- linux-libre-3.10-gnu/arch/x86/kernel/irq_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/irq_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -119,7 +119,7 @@ execute_on_irq_stack(int overflow, struc
 /*
  * allocate per-cpu stacks for hardirq and for softirq processing
  */
-void __cpuinit irq_ctx_init(int cpu)
+void irq_ctx_init(int cpu)
 {
 	union irq_ctx *irqctx;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/irq.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/irq.c
--- linux-libre-3.10-gnu/arch/x86/kernel/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,9 @@
 #include <asm/mce.h>
 #include <asm/hw_irq.h>
 
+#define CREATE_TRACE_POINTS
+#include <asm/trace/irq_vectors.h>
+
 atomic_t irq_err_count;
 
 /* Function pointer for generic interrupt vector handling */
@@ -204,23 +207,21 @@ unsigned int __irq_entry do_IRQ(struct p
 /*
  * Handler for X86_PLATFORM_IPI_VECTOR.
  */
-void smp_x86_platform_ipi(struct pt_regs *regs)
+void __smp_x86_platform_ipi(void)
 {
-	struct pt_regs *old_regs = set_irq_regs(regs);
-
-	ack_APIC_irq();
-
-	irq_enter();
-
-	exit_idle();
-
 	inc_irq_stat(x86_platform_ipis);
 
 	if (x86_platform_ipi_callback)
 		x86_platform_ipi_callback();
+}
 
-	irq_exit();
+void smp_x86_platform_ipi(struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
 
+	entering_ack_irq();
+	__smp_x86_platform_ipi();
+	exiting_irq();
 	set_irq_regs(old_regs);
 }
 
@@ -246,6 +247,18 @@ void smp_kvm_posted_intr_ipi(struct pt_r
 }
 #endif
 
+void smp_trace_x86_platform_ipi(struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
+
+	entering_ack_irq();
+	trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR);
+	__smp_x86_platform_ipi();
+	trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR);
+	exiting_irq();
+	set_irq_regs(old_regs);
+}
+
 EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
 
 #ifdef CONFIG_HOTPLUG_CPU
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/irq_work.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/irq_work.c
--- linux-libre-3.10-gnu/arch/x86/kernel/irq_work.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/irq_work.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,14 +8,34 @@
 #include <linux/irq_work.h>
 #include <linux/hardirq.h>
 #include <asm/apic.h>
+#include <asm/trace/irq_vectors.h>
 
-void smp_irq_work_interrupt(struct pt_regs *regs)
+static inline void irq_work_entering_irq(void)
 {
 	irq_enter();
 	ack_APIC_irq();
+}
+
+static inline void __smp_irq_work_interrupt(void)
+{
 	inc_irq_stat(apic_irq_work_irqs);
 	irq_work_run();
-	irq_exit();
+}
+
+void smp_irq_work_interrupt(struct pt_regs *regs)
+{
+	irq_work_entering_irq();
+	__smp_irq_work_interrupt();
+	exiting_irq();
+}
+
+void smp_trace_irq_work_interrupt(struct pt_regs *regs)
+{
+	irq_work_entering_irq();
+	trace_irq_work_entry(IRQ_WORK_VECTOR);
+	__smp_irq_work_interrupt();
+	trace_irq_work_exit(IRQ_WORK_VECTOR);
+	exiting_irq();
 }
 
 void arch_irq_work_raise(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/kvm.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/kvm.c
--- linux-libre-3.10-gnu/arch/x86/kernel/kvm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/kvm.c	2013-08-25 20:43:22.000000000 -0400
@@ -320,7 +320,7 @@ static void kvm_guest_apic_eoi_write(u32
 	apic_write(APIC_EOI, APIC_EOI_ACK);
 }
 
-void __cpuinit kvm_guest_cpu_init(void)
+void kvm_guest_cpu_init(void)
 {
 	if (!kvm_para_available())
 		return;
@@ -421,7 +421,7 @@ static void __init kvm_smp_prepare_boot_
 	native_smp_prepare_boot_cpu();
 }
 
-static void __cpuinit kvm_guest_cpu_online(void *dummy)
+static void kvm_guest_cpu_online(void *dummy)
 {
 	kvm_guest_cpu_init();
 }
@@ -435,8 +435,8 @@ static void kvm_guest_cpu_offline(void *
 	apf_task_wake_all();
 }
 
-static int __cpuinit kvm_cpu_notify(struct notifier_block *self,
-				    unsigned long action, void *hcpu)
+static int kvm_cpu_notify(struct notifier_block *self, unsigned long action,
+			  void *hcpu)
 {
 	int cpu = (unsigned long)hcpu;
 	switch (action) {
@@ -455,7 +455,7 @@ static int __cpuinit kvm_cpu_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata kvm_cpu_notifier = {
+static struct notifier_block kvm_cpu_notifier = {
         .notifier_call  = kvm_cpu_notify,
 };
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/kvmclock.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/kvmclock.c
--- linux-libre-3.10-gnu/arch/x86/kernel/kvmclock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/kvmclock.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,10 +48,9 @@ static struct pvclock_wall_clock wall_cl
  * have elapsed since the hypervisor wrote the data. So we try to account for
  * that with system time
  */
-static unsigned long kvm_get_wallclock(void)
+static void kvm_get_wallclock(struct timespec *now)
 {
 	struct pvclock_vcpu_time_info *vcpu_time;
-	struct timespec ts;
 	int low, high;
 	int cpu;
 
@@ -64,14 +63,12 @@ static unsigned long kvm_get_wallclock(v
 	cpu = smp_processor_id();
 
 	vcpu_time = &hv_clock[cpu].pvti;
-	pvclock_read_wallclock(&wall_clock, vcpu_time, &ts);
+	pvclock_read_wallclock(&wall_clock, vcpu_time, now);
 
 	preempt_enable();
-
-	return ts.tv_sec;
 }
 
-static int kvm_set_wallclock(unsigned long now)
+static int kvm_set_wallclock(const struct timespec *now)
 {
 	return -1;
 }
@@ -185,7 +182,7 @@ static void kvm_restore_sched_clock_stat
 }
 
 #ifdef CONFIG_X86_LOCAL_APIC
-static void __cpuinit kvm_setup_secondary_clock(void)
+static void kvm_setup_secondary_clock(void)
 {
 	/*
 	 * Now that the first cpu already had this clocksource initialized,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/Makefile linux-libre-3.11-rc7-gnu/arch/x86/kernel/Makefile
--- linux-libre-3.10-gnu/arch/x86/kernel/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,8 @@ CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_early_printk.o = -pg
 endif
 
+CFLAGS_irq.o := -I$(src)/../include/asm/trace
+
 obj-y			:= process_$(BITS).o signal.o entry_$(BITS).o
 obj-y			+= traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 obj-y			+= time.o ioport.o ldt.o dumpstack.o nmi.o
@@ -67,7 +69,7 @@ obj-$(CONFIG_KEXEC)		+= relocate_kernel_
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
 obj-y				+= kprobes/
 obj-$(CONFIG_MODULES)		+= module.o
-obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault_32.o
+obj-$(CONFIG_DOUBLEFAULT)	+= doublefault.o
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_VM86)		+= vm86_32.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
@@ -93,6 +95,7 @@ obj-$(CONFIG_MICROCODE_INTEL_LIB)	+= mic
 microcode-y				:= microcode_core.o
 microcode-$(CONFIG_MICROCODE_INTEL)	+= microcode_intel.o
 microcode-$(CONFIG_MICROCODE_AMD)	+= microcode_amd.o
+obj-$(CONFIG_MICROCODE_AMD_EARLY)	+= microcode_amd_early.o
 obj-$(CONFIG_MICROCODE)			+= microcode.o
 
 obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
@@ -102,6 +105,7 @@ obj-$(CONFIG_OF)			+= devicetree.o
 obj-$(CONFIG_UPROBES)			+= uprobes.o
 
 obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
+obj-$(CONFIG_TRACING)			+= tracepoint.o
 
 ###
 # 64 bit specific files
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/microcode_amd.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_amd.c
--- linux-libre-3.10-gnu/arch/x86/kernel/microcode_amd.c	2013-07-01 10:31:09.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_amd.c	2013-08-31 17:50:34.000000000 -0400
@@ -31,48 +31,12 @@
 #include <asm/microcode.h>
 #include <asm/processor.h>
 #include <asm/msr.h>
+#include <asm/microcode_amd.h>
 
 MODULE_DESCRIPTION("AMD Microcode Update Driver");
 MODULE_AUTHOR("Peter Oruba");
 MODULE_LICENSE("GPL v2");
 
-#define UCODE_MAGIC                0x00414d44
-#define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000
-#define UCODE_UCODE_TYPE           0x00000001
-
-struct equiv_cpu_entry {
-	u32	installed_cpu;
-	u32	fixed_errata_mask;
-	u32	fixed_errata_compare;
-	u16	equiv_cpu;
-	u16	res;
-} __attribute__((packed));
-
-struct microcode_header_amd {
-	u32	data_code;
-	u32	patch_id;
-	u16	mc_patch_data_id;
-	u8	mc_patch_data_len;
-	u8	init_flag;
-	u32	mc_patch_data_checksum;
-	u32	nb_dev_id;
-	u32	sb_dev_id;
-	u16	processor_rev_id;
-	u8	nb_rev_id;
-	u8	sb_rev_id;
-	u8	bios_api_rev;
-	u8	reserved1[3];
-	u32	match_reg[8];
-} __attribute__((packed));
-
-struct microcode_amd {
-	struct microcode_header_amd	hdr;
-	unsigned int			mpb[0];
-};
-
-#define SECTION_HDR_SIZE	8
-#define CONTAINER_HDR_SZ	12
-
 static struct equiv_cpu_entry *equiv_cpu_table;
 
 struct ucode_patch {
@@ -84,21 +48,10 @@ struct ucode_patch {
 
 static LIST_HEAD(pcache);
 
-static u16 find_equiv_id(unsigned int cpu)
+static u16 __find_equiv_id(unsigned int cpu)
 {
 	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-	int i = 0;
-
-	if (!equiv_cpu_table)
-		return 0;
-
-	while (equiv_cpu_table[i].installed_cpu != 0) {
-		if (uci->cpu_sig.sig == equiv_cpu_table[i].installed_cpu)
-			return equiv_cpu_table[i].equiv_cpu;
-
-		i++;
-	}
-	return 0;
+	return find_equiv_id(equiv_cpu_table, uci->cpu_sig.sig);
 }
 
 static u32 find_cpu_family_by_equiv_cpu(u16 equiv_cpu)
@@ -163,7 +116,7 @@ static struct ucode_patch *find_patch(un
 {
 	u16 equiv_id;
 
-	equiv_id = find_equiv_id(cpu);
+	equiv_id = __find_equiv_id(cpu);
 	if (!equiv_id)
 		return NULL;
 
@@ -173,18 +126,28 @@ static struct ucode_patch *find_patch(un
 static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
 {
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
+	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+	struct ucode_patch *p;
 
 	csig->sig = cpuid_eax(0x00000001);
 	csig->rev = c->microcode;
+
+	/*
+	 * a patch could have been loaded early, set uci->mc so that
+	 * mc_bp_resume() can call apply_microcode()
+	 */
+	p = find_patch(cpu);
+	if (p && (p->patch_id == csig->rev))
+		uci->mc = p->data;
+
 	pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev);
 
 	return 0;
 }
 
-static unsigned int verify_patch_size(int cpu, u32 patch_size,
+static unsigned int verify_patch_size(u8 family, u32 patch_size,
 				      unsigned int size)
 {
-	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	u32 max_size;
 
 #define F1XH_MPB_MAX_SIZE 2048
@@ -192,7 +155,7 @@ static unsigned int verify_patch_size(in
 #define F15H_MPB_MAX_SIZE 4096
 #define F16H_MPB_MAX_SIZE 3458
 
-	switch (c->x86) {
+	switch (family) {
 	case 0x14:
 		max_size = F14H_MPB_MAX_SIZE;
 		break;
@@ -215,7 +178,21 @@ static unsigned int verify_patch_size(in
 	return patch_size;
 }
 
-static int apply_microcode_amd(int cpu)
+int __apply_microcode_amd(struct microcode_amd *mc_amd)
+{
+	u32 rev, dummy;
+
+	wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code);
+
+	/* verify patch application was successful */
+	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+	if (rev != mc_amd->hdr.patch_id)
+		return -1;
+
+	return 0;
+}
+
+int apply_microcode_amd(int cpu)
 {
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	struct microcode_amd *mc_amd;
@@ -242,19 +219,16 @@ static int apply_microcode_amd(int cpu)
 		return 0;
 	}
 
-	wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code);
-
-	/* verify patch application was successful */
-	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
-	if (rev != mc_amd->hdr.patch_id) {
+	if (__apply_microcode_amd(mc_amd)) {
 		pr_err("CPU%d: update failed for patch_level=0x%08x\n",
-		       cpu, mc_amd->hdr.patch_id);
+			cpu, mc_amd->hdr.patch_id);
 		return -1;
 	}
+	pr_info("CPU%d: new patch_level=0x%08x\n", cpu,
+		mc_amd->hdr.patch_id);
 
-	pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev);
-	uci->cpu_sig.rev = rev;
-	c->microcode = rev;
+	uci->cpu_sig.rev = mc_amd->hdr.patch_id;
+	c->microcode = mc_amd->hdr.patch_id;
 
 	return 0;
 }
@@ -302,9 +276,8 @@ static void cleanup(void)
  * driver cannot continue functioning normally. In such cases, we tear
  * down everything we've used up so far and exit.
  */
-static int verify_and_add_patch(unsigned int cpu, u8 *fw, unsigned int leftover)
+static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover)
 {
-	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	struct microcode_header_amd *mc_hdr;
 	struct ucode_patch *patch;
 	unsigned int patch_size, crnt_size, ret;
@@ -324,7 +297,7 @@ static int verify_and_add_patch(unsigned
 
 	/* check if patch is for the current family */
 	proc_fam = ((proc_fam >> 8) & 0xf) + ((proc_fam >> 20) & 0xff);
-	if (proc_fam != c->x86)
+	if (proc_fam != family)
 		return crnt_size;
 
 	if (mc_hdr->nb_dev_id || mc_hdr->sb_dev_id) {
@@ -333,7 +306,7 @@ static int verify_and_add_patch(unsigned
 		return crnt_size;
 	}
 
-	ret = verify_patch_size(cpu, patch_size, leftover);
+	ret = verify_patch_size(family, patch_size, leftover);
 	if (!ret) {
 		pr_err("Patch-ID 0x%08x: size mismatch.\n", mc_hdr->patch_id);
 		return crnt_size;
@@ -364,7 +337,8 @@ static int verify_and_add_patch(unsigned
 	return crnt_size;
 }
 
-static enum ucode_state load_microcode_amd(int cpu, const u8 *data, size_t size)
+static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
+					     size_t size)
 {
 	enum ucode_state ret = UCODE_ERROR;
 	unsigned int leftover;
@@ -387,7 +361,7 @@ static enum ucode_state load_microcode_a
 	}
 
 	while (leftover) {
-		crnt_size = verify_and_add_patch(cpu, fw, leftover);
+		crnt_size = verify_and_add_patch(family, fw, leftover);
 		if (crnt_size < 0)
 			return ret;
 
@@ -398,6 +372,32 @@ static enum ucode_state load_microcode_a
 	return UCODE_OK;
 }
 
+enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size)
+{
+	enum ucode_state ret;
+
+	/* free old equiv table */
+	free_equiv_cpu_table();
+
+	ret = __load_microcode_amd(family, data, size);
+
+	if (ret != UCODE_OK)
+		cleanup();
+
+#if defined(CONFIG_MICROCODE_AMD_EARLY) && defined(CONFIG_X86_32)
+	/* save BSP's matching patch for early load */
+	if (cpu_data(smp_processor_id()).cpu_index == boot_cpu_data.cpu_index) {
+		struct ucode_patch *p = find_patch(smp_processor_id());
+		if (p) {
+			memset(amd_bsp_mpb, 0, MPB_MAX_SIZE);
+			memcpy(amd_bsp_mpb, p->data, min_t(u32, ksize(p->data),
+							   MPB_MAX_SIZE));
+		}
+	}
+#endif
+	return ret;
+}
+
 /*(DEBLOBBED)*/
 static enum ucode_state request_microcode_amd(int cpu, struct device *device,
 					      bool refresh_fw)
@@ -425,12 +425,7 @@ static enum ucode_state request_microcod
 		goto fw_release;
 	}
 
-	/* free old equiv table */
-	free_equiv_cpu_table();
-
-	ret = load_microcode_amd(cpu, fw->data, fw->size);
-	if (ret != UCODE_OK)
-		cleanup();
+	ret = load_microcode_amd(c->x86, fw->data, fw->size);
 
  fw_release:
 	release_firmware(fw);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/microcode_amd_early.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_amd_early.c
--- linux-libre-3.10-gnu/arch/x86/kernel/microcode_amd_early.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_amd_early.c	2013-08-31 17:50:36.000000000 -0400
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ *
+ * Author: Jacob Shin <jacob.shin@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/earlycpio.h>
+#include <linux/initrd.h>
+
+#include <asm/cpu.h>
+#include <asm/setup.h>
+#include <asm/microcode_amd.h>
+
+static bool ucode_loaded;
+static u32 ucode_new_rev;
+static unsigned long ucode_offset;
+static size_t ucode_size;
+
+/*
+ * Microcode patch container file is prepended to the initrd in cpio format.
+ * See Documentation/x86/early-microcode.txt
+ */
+static __initdata char ucode_path[] = "/*(DEBLOBBED)*/";
+
+static struct cpio_data __init find_ucode_in_initrd(void)
+{
+	long offset = 0;
+	char *path;
+	void *start;
+	size_t size;
+	unsigned long *uoffset;
+	size_t *usize;
+	struct cpio_data cd;
+
+#ifdef CONFIG_X86_32
+	struct boot_params *p;
+
+	/*
+	 * On 32-bit, early load occurs before paging is turned on so we need
+	 * to use physical addresses.
+	 */
+	p       = (struct boot_params *)__pa_nodebug(&boot_params);
+	path    = (char *)__pa_nodebug(ucode_path);
+	start   = (void *)p->hdr.ramdisk_image;
+	size    = p->hdr.ramdisk_size;
+	uoffset = (unsigned long *)__pa_nodebug(&ucode_offset);
+	usize   = (size_t *)__pa_nodebug(&ucode_size);
+#else
+	path    = ucode_path;
+	start   = (void *)(boot_params.hdr.ramdisk_image + PAGE_OFFSET);
+	size    = boot_params.hdr.ramdisk_size;
+	uoffset = &ucode_offset;
+	usize   = &ucode_size;
+#endif
+
+	cd = find_cpio_data(path, start, size, &offset);
+	if (!cd.data)
+		return cd;
+
+	if (*(u32 *)cd.data != UCODE_MAGIC) {
+		cd.data = NULL;
+		cd.size = 0;
+		return cd;
+	}
+
+	*uoffset = (u8 *)cd.data - (u8 *)start;
+	*usize   = cd.size;
+
+	return cd;
+}
+
+/*
+ * Early load occurs before we can vmalloc(). So we look for the microcode
+ * patch container file in initrd, traverse equivalent cpu table, look for a
+ * matching microcode patch, and update, all in initrd memory in place.
+ * When vmalloc() is available for use later -- on 64-bit during first AP load,
+ * and on 32-bit during save_microcode_in_initrd_amd() -- we can call
+ * load_microcode_amd() to save equivalent cpu table and microcode patches in
+ * kernel heap memory.
+ */
+static void apply_ucode_in_initrd(void *ucode, size_t size)
+{
+	struct equiv_cpu_entry *eq;
+	u32 *header;
+	u8  *data;
+	u16 eq_id = 0;
+	int offset, left;
+	u32 rev, eax;
+	u32 *new_rev;
+	unsigned long *uoffset;
+	size_t *usize;
+
+#ifdef CONFIG_X86_32
+	new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
+	uoffset = (unsigned long *)__pa_nodebug(&ucode_offset);
+	usize   = (size_t *)__pa_nodebug(&ucode_size);
+#else
+	new_rev = &ucode_new_rev;
+	uoffset = &ucode_offset;
+	usize   = &ucode_size;
+#endif
+
+	data   = ucode;
+	left   = size;
+	header = (u32 *)data;
+
+	/* find equiv cpu table */
+
+	if (header[1] != UCODE_EQUIV_CPU_TABLE_TYPE || /* type */
+	    header[2] == 0)                            /* size */
+		return;
+
+	eax = cpuid_eax(0x00000001);
+
+	while (left > 0) {
+		eq = (struct equiv_cpu_entry *)(data + CONTAINER_HDR_SZ);
+
+		offset = header[2] + CONTAINER_HDR_SZ;
+		data  += offset;
+		left  -= offset;
+
+		eq_id = find_equiv_id(eq, eax);
+		if (eq_id)
+			break;
+
+		/*
+		 * support multiple container files appended together. if this
+		 * one does not have a matching equivalent cpu entry, we fast
+		 * forward to the next container file.
+		 */
+		while (left > 0) {
+			header = (u32 *)data;
+			if (header[0] == UCODE_MAGIC &&
+			    header[1] == UCODE_EQUIV_CPU_TABLE_TYPE)
+				break;
+
+			offset = header[1] + SECTION_HDR_SIZE;
+			data  += offset;
+			left  -= offset;
+		}
+
+		/* mark where the next microcode container file starts */
+		offset    = data - (u8 *)ucode;
+		*uoffset += offset;
+		*usize   -= offset;
+		ucode     = data;
+	}
+
+	if (!eq_id) {
+		*usize = 0;
+		return;
+	}
+
+	/* find ucode and update if needed */
+
+	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
+
+	while (left > 0) {
+		struct microcode_amd *mc;
+
+		header = (u32 *)data;
+		if (header[0] != UCODE_UCODE_TYPE || /* type */
+		    header[1] == 0)                  /* size */
+			break;
+
+		mc = (struct microcode_amd *)(data + SECTION_HDR_SIZE);
+		if (eq_id == mc->hdr.processor_rev_id && rev < mc->hdr.patch_id)
+			if (__apply_microcode_amd(mc) == 0) {
+				rev = mc->hdr.patch_id;
+				*new_rev = rev;
+			}
+
+		offset  = header[1] + SECTION_HDR_SIZE;
+		data   += offset;
+		left   -= offset;
+	}
+
+	/* mark where this microcode container file ends */
+	offset  = *usize - (data - (u8 *)ucode);
+	*usize -= offset;
+
+	if (!(*new_rev))
+		*usize = 0;
+}
+
+void __init load_ucode_amd_bsp(void)
+{
+	struct cpio_data cd = find_ucode_in_initrd();
+	if (!cd.data)
+		return;
+
+	apply_ucode_in_initrd(cd.data, cd.size);
+}
+
+#ifdef CONFIG_X86_32
+u8 amd_bsp_mpb[MPB_MAX_SIZE];
+
+/*
+ * On 32-bit, since AP's early load occurs before paging is turned on, we
+ * cannot traverse cpu_equiv_table and pcache in kernel heap memory. So during
+ * cold boot, AP will apply_ucode_in_initrd() just like the BSP. During
+ * save_microcode_in_initrd_amd() BSP's patch is copied to amd_bsp_mpb, which
+ * is used upon resume from suspend.
+ */
+void load_ucode_amd_ap(void)
+{
+	struct microcode_amd *mc;
+	unsigned long *initrd;
+	unsigned long *uoffset;
+	size_t *usize;
+	void *ucode;
+
+	mc = (struct microcode_amd *)__pa(amd_bsp_mpb);
+	if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
+		__apply_microcode_amd(mc);
+		return;
+	}
+
+	initrd  = (unsigned long *)__pa(&initrd_start);
+	uoffset = (unsigned long *)__pa(&ucode_offset);
+	usize   = (size_t *)__pa(&ucode_size);
+
+	if (!*usize || !*initrd)
+		return;
+
+	ucode = (void *)((unsigned long)__pa(*initrd) + *uoffset);
+	apply_ucode_in_initrd(ucode, *usize);
+}
+
+static void __init collect_cpu_sig_on_bsp(void *arg)
+{
+	unsigned int cpu = smp_processor_id();
+	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+	uci->cpu_sig.sig = cpuid_eax(0x00000001);
+}
+#else
+void load_ucode_amd_ap(void)
+{
+	unsigned int cpu = smp_processor_id();
+	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+	u32 rev, eax;
+
+	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
+	eax = cpuid_eax(0x00000001);
+
+	uci->cpu_sig.rev = rev;
+	uci->cpu_sig.sig = eax;
+
+	if (cpu && !ucode_loaded) {
+		void *ucode;
+
+		if (!ucode_size || !initrd_start)
+			return;
+
+		ucode = (void *)(initrd_start + ucode_offset);
+		eax   = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
+		if (load_microcode_amd(eax, ucode, ucode_size) != UCODE_OK)
+			return;
+
+		ucode_loaded = true;
+	}
+
+	apply_microcode_amd(cpu);
+}
+#endif
+
+int __init save_microcode_in_initrd_amd(void)
+{
+	enum ucode_state ret;
+	void *ucode;
+	u32 eax;
+
+#ifdef CONFIG_X86_32
+	unsigned int bsp = boot_cpu_data.cpu_index;
+	struct ucode_cpu_info *uci = ucode_cpu_info + bsp;
+
+	if (!uci->cpu_sig.sig)
+		smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1);
+#endif
+	if (ucode_new_rev)
+		pr_info("microcode: updated early to new patch_level=0x%08x\n",
+			ucode_new_rev);
+
+	if (ucode_loaded || !ucode_size || !initrd_start)
+		return 0;
+
+	ucode = (void *)(initrd_start + ucode_offset);
+	eax   = cpuid_eax(0x00000001);
+	eax   = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff);
+
+	ret = load_microcode_amd(eax, ucode, ucode_size);
+	if (ret != UCODE_OK)
+		return -EINVAL;
+
+	ucode_loaded = true;
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/microcode_core.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_core.c
--- linux-libre-3.10-gnu/arch/x86/kernel/microcode_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -468,7 +468,7 @@ static struct syscore_ops mc_syscore_ops
 	.resume			= mc_bp_resume,
 };
 
-static __cpuinit int
+static int
 mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/microcode_core_early.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_core_early.c
--- linux-libre-3.10-gnu/arch/x86/kernel/microcode_core_early.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_core_early.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
  */
 #include <linux/module.h>
 #include <asm/microcode_intel.h>
+#include <asm/microcode_amd.h>
 #include <asm/processor.h>
 
 #define QCHAR(a, b, c, d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24))
@@ -40,7 +41,7 @@
  *
  * x86_vendor() gets vendor information directly through cpuid.
  */
-static int __cpuinit x86_vendor(void)
+static int x86_vendor(void)
 {
 	u32 eax = 0x00000000;
 	u32 ebx, ecx = 0, edx;
@@ -56,7 +57,7 @@ static int __cpuinit x86_vendor(void)
 	return X86_VENDOR_UNKNOWN;
 }
 
-static int __cpuinit x86_family(void)
+static int x86_family(void)
 {
 	u32 eax = 0x00000001;
 	u32 ebx, ecx = 0, edx;
@@ -81,11 +82,21 @@ void __init load_ucode_bsp(void)
 	vendor = x86_vendor();
 	x86 = x86_family();
 
-	if (vendor == X86_VENDOR_INTEL && x86 >= 6)
-		load_ucode_intel_bsp();
+	switch (vendor) {
+	case X86_VENDOR_INTEL:
+		if (x86 >= 6)
+			load_ucode_intel_bsp();
+		break;
+	case X86_VENDOR_AMD:
+		if (x86 >= 0x10)
+			load_ucode_amd_bsp();
+		break;
+	default:
+		break;
+	}
 }
 
-void __cpuinit load_ucode_ap(void)
+void load_ucode_ap(void)
 {
 	int vendor, x86;
 
@@ -95,6 +106,36 @@ void __cpuinit load_ucode_ap(void)
 	vendor = x86_vendor();
 	x86 = x86_family();
 
-	if (vendor == X86_VENDOR_INTEL && x86 >= 6)
-		load_ucode_intel_ap();
+	switch (vendor) {
+	case X86_VENDOR_INTEL:
+		if (x86 >= 6)
+			load_ucode_intel_ap();
+		break;
+	case X86_VENDOR_AMD:
+		if (x86 >= 0x10)
+			load_ucode_amd_ap();
+		break;
+	default:
+		break;
+	}
+}
+
+int __init save_microcode_in_initrd(void)
+{
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+
+	switch (c->x86_vendor) {
+	case X86_VENDOR_INTEL:
+		if (c->x86 >= 6)
+			save_microcode_in_initrd_intel();
+		break;
+	case X86_VENDOR_AMD:
+		if (c->x86 >= 0x10)
+			save_microcode_in_initrd_amd();
+		break;
+	default:
+		break;
+	}
+
+	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/microcode_intel_early.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_intel_early.c
--- linux-libre-3.10-gnu/arch/x86/kernel/microcode_intel_early.c	2013-07-01 10:31:18.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/microcode_intel_early.c	2013-08-31 17:50:40.000000000 -0400
@@ -34,7 +34,7 @@ struct mc_saved_data {
 	struct microcode_intel **mc_saved;
 } mc_saved_data;
 
-static enum ucode_state __cpuinit
+static enum ucode_state
 generic_load_microcode_early(struct microcode_intel **mc_saved_p,
 			     unsigned int mc_saved_count,
 			     struct ucode_cpu_info *uci)
@@ -69,7 +69,7 @@ out:
 	return state;
 }
 
-static void __cpuinit
+static void
 microcode_pointer(struct microcode_intel **mc_saved,
 		  unsigned long *mc_saved_in_initrd,
 		  unsigned long initrd_start, int mc_saved_count)
@@ -82,7 +82,7 @@ microcode_pointer(struct microcode_intel
 }
 
 #ifdef CONFIG_X86_32
-static void __cpuinit
+static void
 microcode_phys(struct microcode_intel **mc_saved_tmp,
 	       struct mc_saved_data *mc_saved_data)
 {
@@ -101,7 +101,7 @@ microcode_phys(struct microcode_intel **
 }
 #endif
 
-static enum ucode_state __cpuinit
+static enum ucode_state
 load_microcode(struct mc_saved_data *mc_saved_data,
 	       unsigned long *mc_saved_in_initrd,
 	       unsigned long initrd_start,
@@ -375,7 +375,7 @@ do {						\
 #define native_wrmsr(msr, low, high)		\
 	native_write_msr(msr, low, high);
 
-static int __cpuinit collect_cpu_info_early(struct ucode_cpu_info *uci)
+static int collect_cpu_info_early(struct ucode_cpu_info *uci)
 {
 	unsigned int val[2];
 	u8 x86, x86_model;
@@ -529,7 +529,7 @@ int save_mc_for_early(u8 *mc)
 	 */
 	ret = save_microcode(&mc_saved_data, mc_saved_tmp, mc_saved_count);
 	if (ret) {
-		pr_err("Can not save microcode patch.\n");
+		pr_err("Cannot save microcode patch.\n");
 		goto out;
 	}
 
@@ -584,7 +584,7 @@ scan_microcode(unsigned long start, unsi
 /*
  * Print ucode update info.
  */
-static void __cpuinit
+static void
 print_ucode_info(struct ucode_cpu_info *uci, unsigned int date)
 {
 	int cpu = smp_processor_id();
@@ -605,7 +605,7 @@ static int current_mc_date;
 /*
  * Print early updated ucode info after printk works. This is delayed info dump.
  */
-void __cpuinit show_ucode_info_early(void)
+void show_ucode_info_early(void)
 {
 	struct ucode_cpu_info uci;
 
@@ -621,7 +621,7 @@ void __cpuinit show_ucode_info_early(voi
  * mc_saved_data.mc_saved and delay printing microcode info in
  * show_ucode_info_early() until printk() works.
  */
-static void __cpuinit print_ucode(struct ucode_cpu_info *uci)
+static void print_ucode(struct ucode_cpu_info *uci)
 {
 	struct microcode_intel *mc_intel;
 	int *delay_ucode_info_p;
@@ -643,12 +643,12 @@ static void __cpuinit print_ucode(struct
  * Flush global tlb. We only do this in x86_64 where paging has been enabled
  * already and PGE should be enabled as well.
  */
-static inline void __cpuinit flush_tlb_early(void)
+static inline void flush_tlb_early(void)
 {
 	__native_flush_tlb_global_irq_disabled();
 }
 
-static inline void __cpuinit print_ucode(struct ucode_cpu_info *uci)
+static inline void print_ucode(struct ucode_cpu_info *uci)
 {
 	struct microcode_intel *mc_intel;
 
@@ -660,8 +660,8 @@ static inline void __cpuinit print_ucode
 }
 #endif
 
-static int __cpuinit apply_microcode_early(struct mc_saved_data *mc_saved_data,
-					   struct ucode_cpu_info *uci)
+static int apply_microcode_early(struct mc_saved_data *mc_saved_data,
+				 struct ucode_cpu_info *uci)
 {
 	struct microcode_intel *mc_intel;
 	unsigned int val[2];
@@ -699,7 +699,7 @@ static int __cpuinit apply_microcode_ear
  * This function converts microcode patch offsets previously stored in
  * mc_saved_in_initrd to pointers and stores the pointers in mc_saved_data.
  */
-int __init save_microcode_in_initrd(void)
+int __init save_microcode_in_initrd_intel(void)
 {
 	unsigned int count = mc_saved_data.mc_saved_count;
 	struct microcode_intel *mc_saved[MAX_UCODE_COUNT];
@@ -711,7 +711,7 @@ int __init save_microcode_in_initrd(void
 	microcode_pointer(mc_saved, mc_saved_in_initrd, initrd_start, count);
 	ret = save_microcode(&mc_saved_data, mc_saved, count);
 	if (ret)
-		pr_err("Can not save microcod patches from initrd");
+		pr_err("Cannot save microcode patches from initrd.\n");
 
 	show_saved_mc();
 
@@ -763,7 +763,7 @@ load_ucode_intel_bsp(void)
 #endif
 }
 
-void __cpuinit load_ucode_intel_ap(void)
+void load_ucode_intel_ap(void)
 {
 	struct mc_saved_data *mc_saved_data_p;
 	struct ucode_cpu_info uci;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/mmconf-fam10h_64.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/mmconf-fam10h_64.c
--- linux-libre-3.10-gnu/arch/x86/kernel/mmconf-fam10h_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/mmconf-fam10h_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,14 +24,14 @@ struct pci_hostbridge_probe {
 	u32 device;
 };
 
-static u64 __cpuinitdata fam10h_pci_mmconf_base;
+static u64 fam10h_pci_mmconf_base;
 
-static struct pci_hostbridge_probe pci_probes[] __cpuinitdata = {
+static struct pci_hostbridge_probe pci_probes[] = {
 	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
 	{ 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
 };
 
-static int __cpuinit cmp_range(const void *x1, const void *x2)
+static int cmp_range(const void *x1, const void *x2)
 {
 	const struct range *r1 = x1;
 	const struct range *r2 = x2;
@@ -49,7 +49,7 @@ static int __cpuinit cmp_range(const voi
 /* need to avoid (0xfd<<32), (0xfe<<32), and (0xff<<32), ht used space */
 #define FAM10H_PCI_MMCONF_BASE (0xfcULL<<32)
 #define BASE_VALID(b) ((b) + MMCONF_SIZE <= (0xfdULL<<32) || (b) >= (1ULL<<40))
-static void __cpuinit get_fam10h_pci_mmconf_base(void)
+static void get_fam10h_pci_mmconf_base(void)
 {
 	int i;
 	unsigned bus;
@@ -166,7 +166,7 @@ out:
 	fam10h_pci_mmconf_base = base;
 }
 
-void __cpuinit fam10h_check_enable_mmcfg(void)
+void fam10h_check_enable_mmcfg(void)
 {
 	u64 val;
 	u32 address;
@@ -230,7 +230,7 @@ static const struct dmi_system_id __init
 	{}
 };
 
-/* Called from a __cpuinit function, but only on the BSP. */
+/* Called from a non __init function, but only on the BSP. */
 void __ref check_enable_amd_mmconf_dmi(void)
 {
 	dmi_check_system(mmconf_dmi_table);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/msr.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/msr.c
--- linux-libre-3.10-gnu/arch/x86/kernel/msr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/msr.c	2013-08-25 20:43:22.000000000 -0400
@@ -200,7 +200,7 @@ static const struct file_operations msr_
 	.compat_ioctl = msr_ioctl,
 };
 
-static int __cpuinit msr_device_create(int cpu)
+static int msr_device_create(int cpu)
 {
 	struct device *dev;
 
@@ -214,8 +214,8 @@ static void msr_device_destroy(int cpu)
 	device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
 }
 
-static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb,
-				unsigned long action, void *hcpu)
+static int msr_class_cpu_callback(struct notifier_block *nfb,
+				  unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
 	int err = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/nmi.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/nmi.c
--- linux-libre-3.10-gnu/arch/x86/kernel/nmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/nmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
 #include <linux/nmi.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/hardirq.h>
 #include <linux/slab.h>
@@ -29,6 +30,9 @@
 #include <asm/nmi.h>
 #include <asm/x86_init.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/nmi.h>
+
 struct nmi_desc {
 	spinlock_t lock;
 	struct list_head head;
@@ -82,6 +86,15 @@ __setup("unknown_nmi_panic", setup_unkno
 
 #define nmi_to_desc(type) (&nmi_desc[type])
 
+static u64 nmi_longest_ns = 1 * NSEC_PER_MSEC;
+static int __init nmi_warning_debugfs(void)
+{
+	debugfs_create_u64("nmi_longest_ns", 0644,
+			arch_debugfs_dir, &nmi_longest_ns);
+	return 0;
+}
+fs_initcall(nmi_warning_debugfs);
+
 static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2b)
 {
 	struct nmi_desc *desc = nmi_to_desc(type);
@@ -96,8 +109,28 @@ static int __kprobes nmi_handle(unsigned
 	 * can be latched at any given time.  Walk the whole list
 	 * to handle those situations.
 	 */
-	list_for_each_entry_rcu(a, &desc->head, list)
-		handled += a->handler(type, regs);
+	list_for_each_entry_rcu(a, &desc->head, list) {
+		u64 before, delta, whole_msecs;
+		int remainder_ns, decimal_msecs, thishandled;
+
+		before = local_clock();
+		thishandled = a->handler(type, regs);
+		handled += thishandled;
+		delta = local_clock() - before;
+		trace_nmi_handler(a->handler, (int)delta, thishandled);
+
+		if (delta < nmi_longest_ns)
+			continue;
+
+		nmi_longest_ns = delta;
+		whole_msecs = delta;
+		remainder_ns = do_div(whole_msecs, (1000 * 1000));
+		decimal_msecs = remainder_ns / 1000;
+		printk_ratelimited(KERN_INFO
+			"INFO: NMI handler (%ps) took too long to run: "
+			"%lld.%03d msecs\n", a->handler, whole_msecs,
+			decimal_msecs);
+	}
 
 	rcu_read_unlock();
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/process_32.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/process_32.c
--- linux-libre-3.10-gnu/arch/x86/kernel/process_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/process_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -110,11 +110,16 @@ void __show_regs(struct pt_regs *regs, i
 	get_debugreg(d1, 1);
 	get_debugreg(d2, 2);
 	get_debugreg(d3, 3);
-	printk(KERN_DEFAULT "DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
-			d0, d1, d2, d3);
-
 	get_debugreg(d6, 6);
 	get_debugreg(d7, 7);
+
+	/* Only print out debug registers if they are in their non-default state. */
+	if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) &&
+	    (d6 == DR6_RESERVED) && (d7 == 0x400))
+		return;
+
+	printk(KERN_DEFAULT "DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
+			d0, d1, d2, d3);
 	printk(KERN_DEFAULT "DR6: %08lx DR7: %08lx\n",
 			d6, d7);
 }
@@ -147,7 +152,7 @@ int copy_thread(unsigned long clone_flag
 		childregs->bp = arg;
 		childregs->orig_ax = -1;
 		childregs->cs = __KERNEL_CS | get_kernel_rpl();
-		childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+		childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
 		p->fpu_counter = 0;
 		p->thread.io_bitmap_ptr = NULL;
 		memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/process_64.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/process_64.c
--- linux-libre-3.10-gnu/arch/x86/kernel/process_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/process_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -105,11 +105,18 @@ void __show_regs(struct pt_regs *regs, i
 	get_debugreg(d0, 0);
 	get_debugreg(d1, 1);
 	get_debugreg(d2, 2);
-	printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
 	get_debugreg(d3, 3);
 	get_debugreg(d6, 6);
 	get_debugreg(d7, 7);
+
+	/* Only print out debug registers if they are in their non-default state. */
+	if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) &&
+	    (d6 == DR6_RESERVED) && (d7 == 0x400))
+		return;
+
+	printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
 	printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
+
 }
 
 void release_thread(struct task_struct *dead_task)
@@ -176,7 +183,7 @@ int copy_thread(unsigned long clone_flag
 		childregs->bp = arg;
 		childregs->orig_ax = -1;
 		childregs->cs = __KERNEL_CS | get_kernel_rpl();
-		childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+		childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
 		return 0;
 	}
 	*childregs = *current_pt_regs();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/process.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/process.c
--- linux-libre-3.10-gnu/arch/x86/kernel/process.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/process.c	2013-08-25 20:43:22.000000000 -0400
@@ -398,7 +398,7 @@ static void amd_e400_idle(void)
 		default_idle();
 }
 
-void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
+void select_idle_routine(const struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
 	if (boot_option_idle_override == IDLE_POLL && smp_num_siblings > 1)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/ptrace.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/ptrace.c
--- linux-libre-3.10-gnu/arch/x86/kernel/ptrace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/ptrace.c	2013-08-25 20:43:22.000000000 -0400
@@ -601,30 +601,48 @@ static unsigned long ptrace_get_dr7(stru
 	return dr7;
 }
 
-static int
-ptrace_modify_breakpoint(struct perf_event *bp, int len, int type,
-			 struct task_struct *tsk, int disabled)
+static int ptrace_fill_bp_fields(struct perf_event_attr *attr,
+					int len, int type, bool disabled)
+{
+	int err, bp_len, bp_type;
+
+	err = arch_bp_generic_fields(len, type, &bp_len, &bp_type);
+	if (!err) {
+		attr->bp_len = bp_len;
+		attr->bp_type = bp_type;
+		attr->disabled = disabled;
+	}
+
+	return err;
+}
+
+static struct perf_event *
+ptrace_register_breakpoint(struct task_struct *tsk, int len, int type,
+				unsigned long addr, bool disabled)
 {
-	int err;
-	int gen_len, gen_type;
 	struct perf_event_attr attr;
+	int err;
 
-	/*
-	 * We should have at least an inactive breakpoint at this
-	 * slot. It means the user is writing dr7 without having
-	 * written the address register first
-	 */
-	if (!bp)
-		return -EINVAL;
+	ptrace_breakpoint_init(&attr);
+	attr.bp_addr = addr;
 
-	err = arch_bp_generic_fields(len, type, &gen_len, &gen_type);
+	err = ptrace_fill_bp_fields(&attr, len, type, disabled);
 	if (err)
-		return err;
+		return ERR_PTR(err);
 
-	attr = bp->attr;
-	attr.bp_len = gen_len;
-	attr.bp_type = gen_type;
-	attr.disabled = disabled;
+	return register_user_hw_breakpoint(&attr, ptrace_triggered,
+						 NULL, tsk);
+}
+
+static int ptrace_modify_breakpoint(struct perf_event *bp, int len, int type,
+					int disabled)
+{
+	struct perf_event_attr attr = bp->attr;
+	int err;
+
+	err = ptrace_fill_bp_fields(&attr, len, type, disabled);
+	if (err)
+		return err;
 
 	return modify_user_hw_breakpoint(bp, &attr);
 }
@@ -634,67 +652,50 @@ ptrace_modify_breakpoint(struct perf_eve
  */
 static int ptrace_write_dr7(struct task_struct *tsk, unsigned long data)
 {
-	struct thread_struct *thread = &(tsk->thread);
+	struct thread_struct *thread = &tsk->thread;
 	unsigned long old_dr7;
-	int i, orig_ret = 0, rc = 0;
-	int enabled, second_pass = 0;
-	unsigned len, type;
-	struct perf_event *bp;
-
-	if (ptrace_get_breakpoints(tsk) < 0)
-		return -ESRCH;
+	bool second_pass = false;
+	int i, rc, ret = 0;
 
 	data &= ~DR_CONTROL_RESERVED;
 	old_dr7 = ptrace_get_dr7(thread->ptrace_bps);
+
 restore:
-	/*
-	 * Loop through all the hardware breakpoints, making the
-	 * appropriate changes to each.
-	 */
+	rc = 0;
 	for (i = 0; i < HBP_NUM; i++) {
-		enabled = decode_dr7(data, i, &len, &type);
-		bp = thread->ptrace_bps[i];
+		unsigned len, type;
+		bool disabled = !decode_dr7(data, i, &len, &type);
+		struct perf_event *bp = thread->ptrace_bps[i];
 
-		if (!enabled) {
-			if (bp) {
-				/*
-				 * Don't unregister the breakpoints right-away,
-				 * unless all register_user_hw_breakpoint()
-				 * requests have succeeded. This prevents
-				 * any window of opportunity for debug
-				 * register grabbing by other users.
-				 */
-				if (!second_pass)
-					continue;
+		if (!bp) {
+			if (disabled)
+				continue;
 
-				rc = ptrace_modify_breakpoint(bp, len, type,
-							      tsk, 1);
-				if (rc)
-					break;
+			bp = ptrace_register_breakpoint(tsk,
+					len, type, 0, disabled);
+			if (IS_ERR(bp)) {
+				rc = PTR_ERR(bp);
+				break;
 			}
+
+			thread->ptrace_bps[i] = bp;
 			continue;
 		}
 
-		rc = ptrace_modify_breakpoint(bp, len, type, tsk, 0);
+		rc = ptrace_modify_breakpoint(bp, len, type, disabled);
 		if (rc)
 			break;
 	}
-	/*
-	 * Make a second pass to free the remaining unused breakpoints
-	 * or to restore the original breakpoints if an error occurred.
-	 */
-	if (!second_pass) {
-		second_pass = 1;
-		if (rc < 0) {
-			orig_ret = rc;
-			data = old_dr7;
-		}
+
+	/* Restore if the first pass failed, second_pass shouldn't fail. */
+	if (rc && !WARN_ON(second_pass)) {
+		ret = rc;
+		data = old_dr7;
+		second_pass = true;
 		goto restore;
 	}
 
-	ptrace_put_breakpoints(tsk);
-
-	return ((orig_ret < 0) ? orig_ret : rc);
+	return ret;
 }
 
 /*
@@ -702,25 +703,17 @@ restore:
  */
 static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
 {
-	struct thread_struct *thread = &(tsk->thread);
+	struct thread_struct *thread = &tsk->thread;
 	unsigned long val = 0;
 
 	if (n < HBP_NUM) {
-		struct perf_event *bp;
-
-		if (ptrace_get_breakpoints(tsk) < 0)
-			return -ESRCH;
+		struct perf_event *bp = thread->ptrace_bps[n];
 
-		bp = thread->ptrace_bps[n];
-		if (!bp)
-			val = 0;
-		else
+		if (bp)
 			val = bp->hw.info.address;
-
-		ptrace_put_breakpoints(tsk);
 	} else if (n == 6) {
 		val = thread->debugreg6;
-	 } else if (n == 7) {
+	} else if (n == 7) {
 		val = thread->ptrace_dr7;
 	}
 	return val;
@@ -729,29 +722,14 @@ static unsigned long ptrace_get_debugreg
 static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
 				      unsigned long addr)
 {
-	struct perf_event *bp;
 	struct thread_struct *t = &tsk->thread;
-	struct perf_event_attr attr;
+	struct perf_event *bp = t->ptrace_bps[nr];
 	int err = 0;
 
-	if (ptrace_get_breakpoints(tsk) < 0)
-		return -ESRCH;
-
-	if (!t->ptrace_bps[nr]) {
-		ptrace_breakpoint_init(&attr);
-		/*
-		 * Put stub len and type to register (reserve) an inactive but
-		 * correct bp
-		 */
-		attr.bp_addr = addr;
-		attr.bp_len = HW_BREAKPOINT_LEN_1;
-		attr.bp_type = HW_BREAKPOINT_W;
-		attr.disabled = 1;
-
-		bp = register_user_hw_breakpoint(&attr, ptrace_triggered,
-						 NULL, tsk);
-
+	if (!bp) {
 		/*
+		 * Put stub len and type to create an inactive but correct bp.
+		 *
 		 * CHECKME: the previous code returned -EIO if the addr wasn't
 		 * a valid task virtual addr. The new one will return -EINVAL in
 		 *  this case.
@@ -760,22 +738,20 @@ static int ptrace_set_breakpoint_addr(st
 		 * writing for the user. And anyway this is the previous
 		 * behaviour.
 		 */
-		if (IS_ERR(bp)) {
+		bp = ptrace_register_breakpoint(tsk,
+				X86_BREAKPOINT_LEN_1, X86_BREAKPOINT_WRITE,
+				addr, true);
+		if (IS_ERR(bp))
 			err = PTR_ERR(bp);
-			goto put;
-		}
-
-		t->ptrace_bps[nr] = bp;
+		else
+			t->ptrace_bps[nr] = bp;
 	} else {
-		bp = t->ptrace_bps[nr];
+		struct perf_event_attr attr = bp->attr;
 
-		attr = bp->attr;
 		attr.bp_addr = addr;
 		err = modify_user_hw_breakpoint(bp, &attr);
 	}
 
-put:
-	ptrace_put_breakpoints(tsk);
 	return err;
 }
 
@@ -785,30 +761,20 @@ put:
 static int ptrace_set_debugreg(struct task_struct *tsk, int n,
 			       unsigned long val)
 {
-	struct thread_struct *thread = &(tsk->thread);
-	int rc = 0;
-
+	struct thread_struct *thread = &tsk->thread;
 	/* There are no DR4 or DR5 registers */
-	if (n == 4 || n == 5)
-		return -EIO;
+	int rc = -EIO;
 
-	if (n == 6) {
-		thread->debugreg6 = val;
-		goto ret_path;
-	}
 	if (n < HBP_NUM) {
 		rc = ptrace_set_breakpoint_addr(tsk, n, val);
-		if (rc)
-			return rc;
-	}
-	/* All that's left is DR7 */
-	if (n == 7) {
+	} else if (n == 6) {
+		thread->debugreg6 = val;
+		rc = 0;
+	} else if (n == 7) {
 		rc = ptrace_write_dr7(tsk, val);
 		if (!rc)
 			thread->ptrace_dr7 = val;
 	}
-
-ret_path:
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/reboot.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/reboot.c
--- linux-libre-3.10-gnu/arch/x86/kernel/reboot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/reboot.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,22 +36,6 @@ void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
 static const struct desc_ptr no_idt = {};
-static int reboot_mode;
-enum reboot_type reboot_type = BOOT_ACPI;
-int reboot_force;
-
-/*
- * This variable is used privately to keep track of whether or not
- * reboot_type is still set to its default value (i.e., reboot= hasn't
- * been set on the command line).  This is needed so that we can
- * suppress DMI scanning for reboot quirks.  Without it, it's
- * impossible to override a faulty reboot quirk without recompiling.
- */
-static int reboot_default = 1;
-
-#ifdef CONFIG_SMP
-static int reboot_cpu = -1;
-#endif
 
 /*
  * This is set if we need to go through the 'emergency' path.
@@ -64,79 +48,6 @@ static int reboot_emergency;
 bool port_cf9_safe = false;
 
 /*
- * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci]
- * warm   Don't set the cold reboot flag
- * cold   Set the cold reboot flag
- * bios   Reboot by jumping through the BIOS
- * smp    Reboot by executing reset on BSP or other CPU
- * triple Force a triple fault (init)
- * kbd    Use the keyboard controller. cold reset (default)
- * acpi   Use the RESET_REG in the FADT
- * efi    Use efi reset_system runtime service
- * pci    Use the so-called "PCI reset register", CF9
- * force  Avoid anything that could hang.
- */
-static int __init reboot_setup(char *str)
-{
-	for (;;) {
-		/*
-		 * Having anything passed on the command line via
-		 * reboot= will cause us to disable DMI checking
-		 * below.
-		 */
-		reboot_default = 0;
-
-		switch (*str) {
-		case 'w':
-			reboot_mode = 0x1234;
-			break;
-
-		case 'c':
-			reboot_mode = 0;
-			break;
-
-#ifdef CONFIG_SMP
-		case 's':
-			if (isdigit(*(str+1))) {
-				reboot_cpu = (int) (*(str+1) - '0');
-				if (isdigit(*(str+2)))
-					reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
-			}
-			/*
-			 * We will leave sorting out the final value
-			 * when we are ready to reboot, since we might not
-			 * have detected BSP APIC ID or smp_num_cpu
-			 */
-			break;
-#endif /* CONFIG_SMP */
-
-		case 'b':
-		case 'a':
-		case 'k':
-		case 't':
-		case 'e':
-		case 'p':
-			reboot_type = *str;
-			break;
-
-		case 'f':
-			reboot_force = 1;
-			break;
-		}
-
-		str = strchr(str, ',');
-		if (str)
-			str++;
-		else
-			break;
-	}
-	return 1;
-}
-
-__setup("reboot=", reboot_setup);
-
-
-/*
  * Reboot options and system auto-detection code provided by
  * Dell Inc. so their systems "just work". :-)
  */
@@ -536,6 +447,7 @@ static void native_machine_emergency_res
 	int i;
 	int attempt = 0;
 	int orig_reboot_type = reboot_type;
+	unsigned short mode;
 
 	if (reboot_emergency)
 		emergency_vmx_disable_all();
@@ -543,7 +455,8 @@ static void native_machine_emergency_res
 	tboot_shutdown(TB_SHUTDOWN_REBOOT);
 
 	/* Tell the BIOS if we want cold or warm reboot */
-	*((unsigned short *)__va(0x472)) = reboot_mode;
+	mode = reboot_mode == REBOOT_WARM ? 0x1234 : 0;
+	*((unsigned short *)__va(0x472)) = mode;
 
 	for (;;) {
 		/* Could also try the reset bit in the Hammer NB */
@@ -585,7 +498,7 @@ static void native_machine_emergency_res
 
 		case BOOT_EFI:
 			if (efi_enabled(EFI_RUNTIME_SERVICES))
-				efi.reset_system(reboot_mode ?
+				efi.reset_system(reboot_mode == REBOOT_WARM ?
 						 EFI_RESET_WARM :
 						 EFI_RESET_COLD,
 						 EFI_SUCCESS, 0, NULL);
@@ -614,26 +527,10 @@ void native_machine_shutdown(void)
 {
 	/* Stop the cpus and apics */
 #ifdef CONFIG_SMP
-
-	/* The boot cpu is always logical cpu 0 */
-	int reboot_cpu_id = 0;
-
-	/* See if there has been given a command line override */
-	if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) &&
-		cpu_online(reboot_cpu))
-		reboot_cpu_id = reboot_cpu;
-
-	/* Make certain the cpu I'm about to reboot on is online */
-	if (!cpu_online(reboot_cpu_id))
-		reboot_cpu_id = smp_processor_id();
-
-	/* Make certain I only run on the appropriate processor */
-	set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id));
-
 	/*
-	 * O.K Now that I'm on the appropriate processor, stop all of the
-	 * others. Also disable the local irq to not receive the per-cpu
-	 * timer interrupt which may trigger scheduler's load balance.
+	 * Stop all of the others. Also disable the local irq to
+	 * not receive the per-cpu timer interrupt which may trigger
+	 * scheduler's load balance.
 	 */
 	local_irq_disable();
 	stop_other_cpus();
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/relocate_kernel_32.S linux-libre-3.11-rc7-gnu/arch/x86/kernel/relocate_kernel_32.S
--- linux-libre-3.10-gnu/arch/x86/kernel/relocate_kernel_32.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/relocate_kernel_32.S	2013-08-25 20:43:22.000000000 -0400
@@ -186,7 +186,7 @@ identity_mapped:
 	movl	CP_PA_PGD(%ebx), %eax
 	movl	%eax, %cr3
 	movl	%cr0, %eax
-	orl	$(1<<31), %eax
+	orl	$X86_CR0_PG, %eax
 	movl	%eax, %cr0
 	lea	PAGE_SIZE(%edi), %esp
 	movl	%edi, %eax
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/relocate_kernel_64.S linux-libre-3.11-rc7-gnu/arch/x86/kernel/relocate_kernel_64.S
--- linux-libre-3.10-gnu/arch/x86/kernel/relocate_kernel_64.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/relocate_kernel_64.S	2013-08-25 20:43:22.000000000 -0400
@@ -151,21 +151,21 @@ identity_mapped:
 
 	testq	%r11, %r11
 	jnz 1f
-	xorq	%rax, %rax
-	xorq	%rbx, %rbx
-	xorq    %rcx, %rcx
-	xorq    %rdx, %rdx
-	xorq    %rsi, %rsi
-	xorq    %rdi, %rdi
-	xorq    %rbp, %rbp
-	xorq	%r8,  %r8
-	xorq	%r9,  %r9
-	xorq	%r10, %r10
-	xorq	%r11, %r11
-	xorq	%r12, %r12
-	xorq	%r13, %r13
-	xorq	%r14, %r14
-	xorq	%r15, %r15
+	xorl	%eax, %eax
+	xorl	%ebx, %ebx
+	xorl    %ecx, %ecx
+	xorl    %edx, %edx
+	xorl    %esi, %esi
+	xorl    %edi, %edi
+	xorl    %ebp, %ebp
+	xorl	%r8d, %r8d
+	xorl	%r9d, %r9d
+	xorl	%r10d, %r10d
+	xorl	%r11d, %r11d
+	xorl	%r12d, %r12d
+	xorl	%r13d, %r13d
+	xorl	%r14d, %r14d
+	xorl	%r15d, %r15d
 
 	ret
 
@@ -212,8 +212,8 @@ virtual_mapped:
 	/* Do the copies */
 swap_pages:
 	movq	%rdi, %rcx 	/* Put the page_list in %rcx */
-	xorq	%rdi, %rdi
-	xorq	%rsi, %rsi
+	xorl	%edi, %edi
+	xorl	%esi, %esi
 	jmp	1f
 
 0:	/* top, read another word for the indirection page */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/rtc.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/rtc.c
--- linux-libre-3.10-gnu/arch/x86/kernel/rtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/rtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,8 +38,9 @@ EXPORT_SYMBOL(rtc_lock);
  * jump to the next second precisely 500 ms later. Check the Motorola
  * MC146818A or Dallas DS12887 data sheet for details.
  */
-int mach_set_rtc_mmss(unsigned long nowtime)
+int mach_set_rtc_mmss(const struct timespec *now)
 {
+	unsigned long nowtime = now->tv_sec;
 	struct rtc_time tm;
 	int retval = 0;
 
@@ -58,7 +59,7 @@ int mach_set_rtc_mmss(unsigned long nowt
 	return retval;
 }
 
-unsigned long mach_get_cmos_time(void)
+void mach_get_cmos_time(struct timespec *now)
 {
 	unsigned int status, year, mon, day, hour, min, sec, century = 0;
 	unsigned long flags;
@@ -107,7 +108,8 @@ unsigned long mach_get_cmos_time(void)
 	} else
 		year += CMOS_YEARS_OFFS;
 
-	return mktime(year, mon, day, hour, min, sec);
+	now->tv_sec = mktime(year, mon, day, hour, min, sec);
+	now->tv_nsec = 0;
 }
 
 /* Routines for accessing the CMOS RAM/RTC. */
@@ -135,18 +137,13 @@ EXPORT_SYMBOL(rtc_cmos_write);
 
 int update_persistent_clock(struct timespec now)
 {
-	return x86_platform.set_wallclock(now.tv_sec);
+	return x86_platform.set_wallclock(&now);
 }
 
 /* not static: needed by APM */
 void read_persistent_clock(struct timespec *ts)
 {
-	unsigned long retval;
-
-	retval = x86_platform.get_wallclock();
-
-	ts->tv_sec = retval;
-	ts->tv_nsec = 0;
+	x86_platform.get_wallclock(ts);
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/setup.c
--- linux-libre-3.10-gnu/arch/x86/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -170,7 +170,7 @@ static struct resource bss_resource = {
 
 #ifdef CONFIG_X86_32
 /* cpu data as detected by the assembly code in head.S */
-struct cpuinfo_x86 new_cpu_data __cpuinitdata = {
+struct cpuinfo_x86 new_cpu_data = {
 	.wp_works_ok = -1,
 };
 /* common cpu data for all cpus */
@@ -1040,8 +1040,6 @@ void __init setup_arch(char **cmdline_p)
 	/* max_low_pfn get updated here */
 	find_low_pfn_range();
 #else
-	num_physpages = max_pfn;
-
 	check_x2apic();
 
 	/* How many end-of-memory variables you have, grandma! */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/signal.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/signal.c
--- linux-libre-3.10-gnu/arch/x86/kernel/signal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/signal.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,12 +43,6 @@
 
 #include <asm/sigframe.h>
 
-#ifdef CONFIG_X86_32
-# define FIX_EFLAGS	(__FIX_EFLAGS | X86_EFLAGS_RF)
-#else
-# define FIX_EFLAGS	__FIX_EFLAGS
-#endif
-
 #define COPY(x)			do {			\
 	get_user_ex(regs->x, &sc->x);			\
 } while (0)
@@ -668,15 +662,17 @@ handle_signal(struct ksignal *ksig, stru
 	if (!failed) {
 		/*
 		 * Clear the direction flag as per the ABI for function entry.
-		 */
-		regs->flags &= ~X86_EFLAGS_DF;
-		/*
+		 *
+		 * Clear RF when entering the signal handler, because
+		 * it might disable possible debug exception from the
+		 * signal handler.
+		 *
 		 * Clear TF when entering the signal handler, but
 		 * notify any tracer that was single-stepping it.
 		 * The tracer may want to single-step inside the
 		 * handler too.
 		 */
-		regs->flags &= ~X86_EFLAGS_TF;
+		regs->flags &= ~(X86_EFLAGS_DF|X86_EFLAGS_RF|X86_EFLAGS_TF);
 	}
 	signal_setup_done(failed, ksig, test_thread_flag(TIF_SINGLESTEP));
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/smpboot.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/smpboot.c
--- linux-libre-3.10-gnu/arch/x86/kernel/smpboot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/smpboot.c	2013-08-25 20:43:22.000000000 -0400
@@ -130,7 +130,7 @@ atomic_t init_deasserted;
  * Report back to the Boot Processor during boot time or to the caller processor
  * during CPU online.
  */
-static void __cpuinit smp_callin(void)
+static void smp_callin(void)
 {
 	int cpuid, phys_id;
 	unsigned long timeout;
@@ -237,7 +237,7 @@ static int enable_start_cpu0;
 /*
  * Activate a secondary processor.
  */
-notrace static void __cpuinit start_secondary(void *unused)
+static void notrace start_secondary(void *unused)
 {
 	/*
 	 * Don't put *anything* before cpu_init(), SMP booting is too
@@ -300,7 +300,7 @@ void __init smp_store_boot_cpu_info(void
  * The bootstrap kernel entry code has set these up. Save them for
  * a given CPU
  */
-void __cpuinit smp_store_cpu_info(int id)
+void smp_store_cpu_info(int id)
 {
 	struct cpuinfo_x86 *c = &cpu_data(id);
 
@@ -313,7 +313,7 @@ void __cpuinit smp_store_cpu_info(int id
 	identify_secondary_cpu(c);
 }
 
-static bool __cpuinit
+static bool
 topology_sane(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o, const char *name)
 {
 	int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
@@ -330,7 +330,7 @@ do {									\
 	cpumask_set_cpu((c2), cpu_##_m##_mask(c1));			\
 } while (0)
 
-static bool __cpuinit match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
+static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 {
 	if (cpu_has_topoext) {
 		int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
@@ -348,7 +348,7 @@ static bool __cpuinit match_smt(struct c
 	return false;
 }
 
-static bool __cpuinit match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
+static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 {
 	int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
 
@@ -359,7 +359,7 @@ static bool __cpuinit match_llc(struct c
 	return false;
 }
 
-static bool __cpuinit match_mc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
+static bool match_mc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 {
 	if (c->phys_proc_id == o->phys_proc_id) {
 		if (cpu_has(c, X86_FEATURE_AMD_DCM))
@@ -370,7 +370,7 @@ static bool __cpuinit match_mc(struct cp
 	return false;
 }
 
-void __cpuinit set_cpu_sibling_map(int cpu)
+void set_cpu_sibling_map(int cpu)
 {
 	bool has_smt = smp_num_siblings > 1;
 	bool has_mp = has_smt || boot_cpu_data.x86_max_cores > 1;
@@ -499,7 +499,7 @@ void __inquire_remote_apic(int apicid)
  * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this
  * won't ... remember to clear down the APIC, etc later.
  */
-int __cpuinit
+int
 wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip)
 {
 	unsigned long send_status, accept_status = 0;
@@ -533,7 +533,7 @@ wakeup_secondary_cpu_via_nmi(int apicid,
 	return (send_status | accept_status);
 }
 
-static int __cpuinit
+static int
 wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
 {
 	unsigned long send_status, accept_status = 0;
@@ -649,7 +649,7 @@ wakeup_secondary_cpu_via_init(int phys_a
 }
 
 /* reduce the number of lines printed when booting a large cpu count system */
-static void __cpuinit announce_cpu(int cpu, int apicid)
+static void announce_cpu(int cpu, int apicid)
 {
 	static int current_node = -1;
 	int node = early_cpu_to_node(cpu);
@@ -691,7 +691,7 @@ static int wakeup_cpu0_nmi(unsigned int
  * We'll change this code in the future to wake up hard offlined CPU0 if
  * real platform and request are available.
  */
-static int __cpuinit
+static int
 wakeup_cpu_via_init_nmi(int cpu, unsigned long start_ip, int apicid,
 	       int *cpu0_nmi_registered)
 {
@@ -731,7 +731,7 @@ wakeup_cpu_via_init_nmi(int cpu, unsigne
  * Returns zero if CPU booted OK, else error code from
  * ->wakeup_secondary_cpu.
  */
-static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
+static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
 {
 	volatile u32 *trampoline_status =
 		(volatile u32 *) __va(real_mode_header->trampoline_status);
@@ -872,7 +872,7 @@ static int __cpuinit do_boot_cpu(int api
 	return boot_error;
 }
 
-int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
+int native_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int apicid = apic->cpu_present_to_apicid(cpu);
 	unsigned long flags;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/smp.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/smp.c
--- linux-libre-3.10-gnu/arch/x86/kernel/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,7 @@
 #include <asm/proto.h>
 #include <asm/apic.h>
 #include <asm/nmi.h>
+#include <asm/trace/irq_vectors.h>
 /*
  *	Some notes on x86 processor bugs affecting SMP operation:
  *
@@ -249,32 +250,87 @@ finish:
 /*
  * Reschedule call back.
  */
-void smp_reschedule_interrupt(struct pt_regs *regs)
+static inline void __smp_reschedule_interrupt(void)
 {
-	ack_APIC_irq();
 	inc_irq_stat(irq_resched_count);
 	scheduler_ipi();
+}
+
+void smp_reschedule_interrupt(struct pt_regs *regs)
+{
+	ack_APIC_irq();
+	__smp_reschedule_interrupt();
 	/*
 	 * KVM uses this interrupt to force a cpu out of guest mode
 	 */
 }
 
-void smp_call_function_interrupt(struct pt_regs *regs)
+static inline void smp_entering_irq(void)
 {
 	ack_APIC_irq();
 	irq_enter();
+}
+
+void smp_trace_reschedule_interrupt(struct pt_regs *regs)
+{
+	/*
+	 * Need to call irq_enter() before calling the trace point.
+	 * __smp_reschedule_interrupt() calls irq_enter/exit() too (in
+	 * scheduler_ipi(). This is OK, since those functions are allowed
+	 * to nest.
+	 */
+	smp_entering_irq();
+	trace_reschedule_entry(RESCHEDULE_VECTOR);
+	__smp_reschedule_interrupt();
+	trace_reschedule_exit(RESCHEDULE_VECTOR);
+	exiting_irq();
+	/*
+	 * KVM uses this interrupt to force a cpu out of guest mode
+	 */
+}
+
+static inline void __smp_call_function_interrupt(void)
+{
 	generic_smp_call_function_interrupt();
 	inc_irq_stat(irq_call_count);
-	irq_exit();
 }
 
-void smp_call_function_single_interrupt(struct pt_regs *regs)
+void smp_call_function_interrupt(struct pt_regs *regs)
+{
+	smp_entering_irq();
+	__smp_call_function_interrupt();
+	exiting_irq();
+}
+
+void smp_trace_call_function_interrupt(struct pt_regs *regs)
+{
+	smp_entering_irq();
+	trace_call_function_entry(CALL_FUNCTION_VECTOR);
+	__smp_call_function_interrupt();
+	trace_call_function_exit(CALL_FUNCTION_VECTOR);
+	exiting_irq();
+}
+
+static inline void __smp_call_function_single_interrupt(void)
 {
-	ack_APIC_irq();
-	irq_enter();
 	generic_smp_call_function_single_interrupt();
 	inc_irq_stat(irq_call_count);
-	irq_exit();
+}
+
+void smp_call_function_single_interrupt(struct pt_regs *regs)
+{
+	smp_entering_irq();
+	__smp_call_function_single_interrupt();
+	exiting_irq();
+}
+
+void smp_trace_call_function_single_interrupt(struct pt_regs *regs)
+{
+	smp_entering_irq();
+	trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR);
+	__smp_call_function_single_interrupt();
+	trace_call_function_single_exit(CALL_FUNCTION_SINGLE_VECTOR);
+	exiting_irq();
 }
 
 static int __init nonmi_ipi_setup(char *str)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/sys_x86_64.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/sys_x86_64.c
--- linux-libre-3.10-gnu/arch/x86/kernel/sys_x86_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/sys_x86_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -101,7 +101,7 @@ static void find_start_end(unsigned long
 				*begin = new_begin;
 		}
 	} else {
-		*begin = TASK_UNMAPPED_BASE;
+		*begin = current->mm->mmap_legacy_base;
 		*end = TASK_SIZE;
 	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/tboot.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/tboot.c
--- linux-libre-3.10-gnu/arch/x86/kernel/tboot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/tboot.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/pfn.h>
 #include <linux/mm.h>
 #include <linux/tboot.h>
+#include <linux/debugfs.h>
 
 #include <asm/realmode.h>
 #include <asm/processor.h>
@@ -319,8 +320,8 @@ static int tboot_wait_for_aps(int num_ap
 	return !(atomic_read((atomic_t *)&tboot->num_in_wfs) == num_aps);
 }
 
-static int __cpuinit tboot_cpu_callback(struct notifier_block *nfb,
-			unsigned long action, void *hcpu)
+static int tboot_cpu_callback(struct notifier_block *nfb, unsigned long action,
+			      void *hcpu)
 {
 	switch (action) {
 	case CPU_DYING:
@@ -333,11 +334,78 @@ static int __cpuinit tboot_cpu_callback(
 	return NOTIFY_OK;
 }
 
-static struct notifier_block tboot_cpu_notifier __cpuinitdata =
+static struct notifier_block tboot_cpu_notifier =
 {
 	.notifier_call = tboot_cpu_callback,
 };
 
+#ifdef CONFIG_DEBUG_FS
+
+#define TBOOT_LOG_UUID	{ 0x26, 0x25, 0x19, 0xc0, 0x30, 0x6b, 0xb4, 0x4d, \
+			  0x4c, 0x84, 0xa3, 0xe9, 0x53, 0xb8, 0x81, 0x74 }
+
+#define TBOOT_SERIAL_LOG_ADDR	0x60000
+#define TBOOT_SERIAL_LOG_SIZE	0x08000
+#define LOG_MAX_SIZE_OFF	16
+#define LOG_BUF_OFF		24
+
+static uint8_t tboot_log_uuid[16] = TBOOT_LOG_UUID;
+
+static ssize_t tboot_log_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
+{
+	void __iomem *log_base;
+	u8 log_uuid[16];
+	u32 max_size;
+	void *kbuf;
+	int ret = -EFAULT;
+
+	log_base = ioremap_nocache(TBOOT_SERIAL_LOG_ADDR, TBOOT_SERIAL_LOG_SIZE);
+	if (!log_base)
+		return ret;
+
+	memcpy_fromio(log_uuid, log_base, sizeof(log_uuid));
+	if (memcmp(&tboot_log_uuid, log_uuid, sizeof(log_uuid)))
+		goto err_iounmap;
+
+	max_size = readl(log_base + LOG_MAX_SIZE_OFF);
+	if (*ppos >= max_size) {
+		ret = 0;
+		goto err_iounmap;
+	}
+
+	if (*ppos + count > max_size)
+		count = max_size - *ppos;
+
+	kbuf = kmalloc(count, GFP_KERNEL);
+	if (!kbuf) {
+		ret = -ENOMEM;
+		goto err_iounmap;
+	}
+
+	memcpy_fromio(kbuf, log_base + LOG_BUF_OFF + *ppos, count);
+	if (copy_to_user(user_buf, kbuf, count))
+		goto err_kfree;
+
+	*ppos += count;
+
+	ret = count;
+
+err_kfree:
+	kfree(kbuf);
+
+err_iounmap:
+	iounmap(log_base);
+
+	return ret;
+}
+
+static const struct file_operations tboot_log_fops = {
+	.read	= tboot_log_read,
+	.llseek	= default_llseek,
+};
+
+#endif /* CONFIG_DEBUG_FS */
+
 static __init int tboot_late_init(void)
 {
 	if (!tboot_enabled())
@@ -348,6 +416,11 @@ static __init int tboot_late_init(void)
 	atomic_set(&ap_wfs_count, 0);
 	register_hotcpu_notifier(&tboot_cpu_notifier);
 
+#ifdef CONFIG_DEBUG_FS
+	debugfs_create_file("tboot_log", S_IRUSR,
+			arch_debugfs_dir, NULL, &tboot_log_fops);
+#endif
+
 	acpi_os_set_prepare_sleep(&tboot_sleep);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/tracepoint.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/tracepoint.c
--- linux-libre-3.10-gnu/arch/x86/kernel/tracepoint.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/tracepoint.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,59 @@
+/*
+ * Code for supporting irq vector tracepoints.
+ *
+ * Copyright (C) 2013 Seiji Aguchi <seiji.aguchi@hds.com>
+ *
+ */
+#include <asm/hw_irq.h>
+#include <asm/desc.h>
+#include <linux/atomic.h>
+
+atomic_t trace_idt_ctr = ATOMIC_INIT(0);
+struct desc_ptr trace_idt_descr = { NR_VECTORS * 16 - 1,
+				(unsigned long) trace_idt_table };
+
+/* No need to be aligned, but done to keep all IDTs defined the same way. */
+gate_desc trace_idt_table[NR_VECTORS] __page_aligned_bss;
+
+static int trace_irq_vector_refcount;
+static DEFINE_MUTEX(irq_vector_mutex);
+
+static void set_trace_idt_ctr(int val)
+{
+	atomic_set(&trace_idt_ctr, val);
+	/* Ensure the trace_idt_ctr is set before sending IPI */
+	wmb();
+}
+
+static void switch_idt(void *arg)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	load_current_idt();
+	local_irq_restore(flags);
+}
+
+void trace_irq_vector_regfunc(void)
+{
+	mutex_lock(&irq_vector_mutex);
+	if (!trace_irq_vector_refcount) {
+		set_trace_idt_ctr(1);
+		smp_call_function(switch_idt, NULL, 0);
+		switch_idt(NULL);
+	}
+	trace_irq_vector_refcount++;
+	mutex_unlock(&irq_vector_mutex);
+}
+
+void trace_irq_vector_unregfunc(void)
+{
+	mutex_lock(&irq_vector_mutex);
+	trace_irq_vector_refcount--;
+	if (!trace_irq_vector_refcount) {
+		set_trace_idt_ctr(0);
+		smp_call_function(switch_idt, NULL, 0);
+		switch_idt(NULL);
+	}
+	mutex_unlock(&irq_vector_mutex);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/traps.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/traps.c
--- linux-libre-3.10-gnu/arch/x86/kernel/traps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/traps.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,19 +63,19 @@
 #include <asm/x86_init.h>
 #include <asm/pgalloc.h>
 #include <asm/proto.h>
+
+/* No need to be aligned, but done to keep all IDTs defined the same way. */
+gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss;
 #else
 #include <asm/processor-flags.h>
 #include <asm/setup.h>
 
 asmlinkage int system_call(void);
-
-/*
- * The IDT has to be page-aligned to simplify the Pentium
- * F0 0F bug workaround.
- */
-gate_desc idt_table[NR_VECTORS] __page_aligned_data = { { { { 0, 0 } } }, };
 #endif
 
+/* Must be page-aligned because the real IDT is used in a fixmap. */
+gate_desc idt_table[NR_VECTORS] __page_aligned_bss;
+
 DECLARE_BITMAP(used_vectors, NR_VECTORS);
 EXPORT_SYMBOL_GPL(used_vectors);
 
@@ -254,6 +254,9 @@ dotraplinkage void do_double_fault(struc
 	tsk->thread.error_code = error_code;
 	tsk->thread.trap_nr = X86_TRAP_DF;
 
+#ifdef CONFIG_DOUBLEFAULT
+	df_debug(regs, error_code);
+#endif
 	/*
 	 * This is always a kernel trap and never fixable (and thus must
 	 * never return).
@@ -437,7 +440,7 @@ dotraplinkage void __kprobes do_debug(st
 	/* Store the virtualized DR6 value */
 	tsk->thread.debugreg6 = dr6;
 
-	if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code,
+	if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, error_code,
 							SIGTRAP) == NOTIFY_STOP)
 		goto exit;
 
@@ -785,7 +788,7 @@ void __init trap_init(void)
 	x86_init.irqs.trap_init();
 
 #ifdef CONFIG_X86_64
-	memcpy(&nmi_idt_table, &idt_table, IDT_ENTRIES * 16);
+	memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16);
 	set_nmi_gate(X86_TRAP_DB, &debug);
 	set_nmi_gate(X86_TRAP_BP, &int3);
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/tsc.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/tsc.c
--- linux-libre-3.10-gnu/arch/x86/kernel/tsc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/tsc.c	2013-08-25 20:43:22.000000000 -0400
@@ -824,7 +824,7 @@ static void __init check_system_tsc_reli
  * Make an educated guess if the TSC is trustworthy and synchronized
  * over all CPUs.
  */
-__cpuinit int unsynchronized_tsc(void)
+int unsynchronized_tsc(void)
 {
 	if (!cpu_has_tsc || tsc_unstable)
 		return 1;
@@ -1020,7 +1020,7 @@ void __init tsc_init(void)
  * been calibrated. This assumes that CONSTANT_TSC applies to all
  * cpus in the socket - this should be a safe assumption.
  */
-unsigned long __cpuinit calibrate_delay_is_known(void)
+unsigned long calibrate_delay_is_known(void)
 {
 	int i, cpu = smp_processor_id();
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/tsc_sync.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/tsc_sync.c
--- linux-libre-3.10-gnu/arch/x86/kernel/tsc_sync.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/tsc_sync.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,24 +25,24 @@
  * Entry/exit counters that make sure that both CPUs
  * run the measurement code at once:
  */
-static __cpuinitdata atomic_t start_count;
-static __cpuinitdata atomic_t stop_count;
+static atomic_t start_count;
+static atomic_t stop_count;
 
 /*
  * We use a raw spinlock in this exceptional case, because
  * we want to have the fastest, inlined, non-debug version
  * of a critical section, to be able to prove TSC time-warps:
  */
-static __cpuinitdata arch_spinlock_t sync_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+static arch_spinlock_t sync_lock = __ARCH_SPIN_LOCK_UNLOCKED;
 
-static __cpuinitdata cycles_t last_tsc;
-static __cpuinitdata cycles_t max_warp;
-static __cpuinitdata int nr_warps;
+static cycles_t last_tsc;
+static cycles_t max_warp;
+static int nr_warps;
 
 /*
  * TSC-warp measurement loop running on both CPUs:
  */
-static __cpuinit void check_tsc_warp(unsigned int timeout)
+static void check_tsc_warp(unsigned int timeout)
 {
 	cycles_t start, now, prev, end;
 	int i;
@@ -121,7 +121,7 @@ static inline unsigned int loop_timeout(
  * Source CPU calls into this - it waits for the freshly booted
  * target CPU to arrive and then starts the measurement:
  */
-void __cpuinit check_tsc_sync_source(int cpu)
+void check_tsc_sync_source(int cpu)
 {
 	int cpus = 2;
 
@@ -187,7 +187,7 @@ void __cpuinit check_tsc_sync_source(int
 /*
  * Freshly booted CPUs call into this:
  */
-void __cpuinit check_tsc_sync_target(void)
+void check_tsc_sync_target(void)
 {
 	int cpus = 2;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/vsyscall_64.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/vsyscall_64.c
--- linux-libre-3.10-gnu/arch/x86/kernel/vsyscall_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/vsyscall_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -331,7 +331,7 @@ sigsegv:
  * Assume __initcall executes before all user space. Hopefully kmod
  * doesn't violate that. We'll find out if it does.
  */
-static void __cpuinit vsyscall_set_cpu(int cpu)
+static void vsyscall_set_cpu(int cpu)
 {
 	unsigned long d;
 	unsigned long node = 0;
@@ -353,13 +353,13 @@ static void __cpuinit vsyscall_set_cpu(i
 	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S);
 }
 
-static void __cpuinit cpu_vsyscall_init(void *arg)
+static void cpu_vsyscall_init(void *arg)
 {
 	/* preemption should be already off */
 	vsyscall_set_cpu(raw_smp_processor_id());
 }
 
-static int __cpuinit
+static int
 cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg)
 {
 	long cpu = (long)arg;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/x86_init.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/x86_init.c
--- linux-libre-3.10-gnu/arch/x86/kernel/x86_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/x86_init.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@
 #include <asm/iommu.h>
 #include <asm/mach_traps.h>
 
-void __cpuinit x86_init_noop(void) { }
+void x86_init_noop(void) { }
 void __init x86_init_uint_noop(unsigned int unused) { }
 int __init iommu_init_noop(void) { return 0; }
 void iommu_shutdown_noop(void) { }
@@ -85,7 +85,7 @@ struct x86_init_ops x86_init __initdata
 	},
 };
 
-struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
+struct x86_cpuinit_ops x86_cpuinit = {
 	.early_percpu_clock_init	= x86_init_noop,
 	.setup_percpu_clockev		= setup_secondary_APIC_clock,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kernel/xsave.c linux-libre-3.11-rc7-gnu/arch/x86/kernel/xsave.c
--- linux-libre-3.10-gnu/arch/x86/kernel/xsave.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kernel/xsave.c	2013-08-25 20:43:22.000000000 -0400
@@ -243,7 +243,7 @@ int save_xstate_sig(void __user *buf, vo
 	if (!access_ok(VERIFY_WRITE, buf, size))
 		return -EACCES;
 
-	if (!HAVE_HWFP)
+	if (!static_cpu_has(X86_FEATURE_FPU))
 		return fpregs_soft_get(current, NULL, 0,
 			sizeof(struct user_i387_ia32_struct), NULL,
 			(struct _fpstate_ia32 __user *) buf) ? -1 : 1;
@@ -350,11 +350,10 @@ int __restore_xstate_sig(void __user *bu
 	if (!used_math() && init_fpu(tsk))
 		return -1;
 
-	if (!HAVE_HWFP) {
+	if (!static_cpu_has(X86_FEATURE_FPU))
 		return fpregs_soft_set(current, NULL,
 				       0, sizeof(struct user_i387_ia32_struct),
 				       NULL, buf) != 0;
-	}
 
 	if (use_xsave()) {
 		struct _fpx_sw_bytes fx_sw_user;
@@ -574,7 +573,7 @@ static void __init xstate_enable_boot_cp
  * This is somewhat obfuscated due to the lack of powerful enough
  * overrides for the section checks.
  */
-void __cpuinit xsave_init(void)
+void xsave_init(void)
 {
 	static __refdata void (*next_func)(void) = xstate_enable_boot_cpu;
 	void (*this_func)(void);
@@ -595,7 +594,7 @@ static inline void __init eager_fpu_init
 		setup_init_fpu_buf();
 }
 
-void __cpuinit eager_fpu_init(void)
+void eager_fpu_init(void)
 {
 	static __refdata void (*boot_func)(void) = eager_fpu_init_bp;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/emulate.c linux-libre-3.11-rc7-gnu/arch/x86/kvm/emulate.c
--- linux-libre-3.10-gnu/arch/x86/kvm/emulate.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/emulate.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,6 +61,8 @@
 #define OpMem8            26ull  /* 8-bit zero extended memory operand */
 #define OpImm64           27ull  /* Sign extended 16/32/64-bit immediate */
 #define OpXLat            28ull  /* memory at BX/EBX/RBX + zero-extended AL */
+#define OpAccLo           29ull  /* Low part of extended acc (AX/AX/EAX/RAX) */
+#define OpAccHi           30ull  /* High part of extended acc (-/DX/EDX/RDX) */
 
 #define OpBits             5  /* Width of operand field */
 #define OpMask             ((1ull << OpBits) - 1)
@@ -86,6 +88,7 @@
 #define DstMem64    (OpMem64 << DstShift)
 #define DstImmUByte (OpImmUByte << DstShift)
 #define DstDX       (OpDX << DstShift)
+#define DstAccLo    (OpAccLo << DstShift)
 #define DstMask     (OpMask << DstShift)
 /* Source operand type. */
 #define SrcShift    6
@@ -108,6 +111,7 @@
 #define SrcImm64    (OpImm64 << SrcShift)
 #define SrcDX       (OpDX << SrcShift)
 #define SrcMem8     (OpMem8 << SrcShift)
+#define SrcAccHi    (OpAccHi << SrcShift)
 #define SrcMask     (OpMask << SrcShift)
 #define BitOp       (1<<11)
 #define MemAbs      (1<<12)      /* Memory operand is absolute displacement */
@@ -138,6 +142,7 @@
 /* Source 2 operand type */
 #define Src2Shift   (31)
 #define Src2None    (OpNone << Src2Shift)
+#define Src2Mem     (OpMem << Src2Shift)
 #define Src2CL      (OpCL << Src2Shift)
 #define Src2ImmByte (OpImmByte << Src2Shift)
 #define Src2One     (OpOne << Src2Shift)
@@ -155,6 +160,9 @@
 #define Avx         ((u64)1 << 43)  /* Advanced Vector Extensions */
 #define Fastop      ((u64)1 << 44)  /* Use opcode::u.fastop */
 #define NoWrite     ((u64)1 << 45)  /* No writeback */
+#define SrcWrite    ((u64)1 << 46)  /* Write back src operand */
+
+#define DstXacc     (DstAccLo | SrcAccHi | SrcWrite)
 
 #define X2(x...) x, x
 #define X3(x...) X2(x), x
@@ -171,10 +179,11 @@
 /*
  * fastop functions have a special calling convention:
  *
- * dst:    [rdx]:rax  (in/out)
- * src:    rbx        (in/out)
+ * dst:    rax        (in/out)
+ * src:    rdx        (in/out)
  * src2:   rcx        (in)
  * flags:  rflags     (in/out)
+ * ex:     rsi        (in:fastop pointer, out:zero if exception)
  *
  * Moreover, they are all exactly FASTOP_SIZE bytes long, so functions for
  * different operand sizes can be reached by calculation, rather than a jump
@@ -276,174 +285,17 @@ static void invalidate_registers(struct
 }
 
 /*
- * Instruction emulation:
- * Most instructions are emulated directly via a fragment of inline assembly
- * code. This allows us to save/restore EFLAGS and thus very easily pick up
- * any modified flags.
- */
-
-#if defined(CONFIG_X86_64)
-#define _LO32 "k"		/* force 32-bit operand */
-#define _STK  "%%rsp"		/* stack pointer */
-#elif defined(__i386__)
-#define _LO32 ""		/* force 32-bit operand */
-#define _STK  "%%esp"		/* stack pointer */
-#endif
-
-/*
  * These EFLAGS bits are restored from saved value during emulation, and
  * any changes are written back to the saved value after emulation.
  */
 #define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF)
 
-/* Before executing instruction: restore necessary bits in EFLAGS. */
-#define _PRE_EFLAGS(_sav, _msk, _tmp)					\
-	/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \
-	"movl %"_sav",%"_LO32 _tmp"; "                                  \
-	"push %"_tmp"; "                                                \
-	"push %"_tmp"; "                                                \
-	"movl %"_msk",%"_LO32 _tmp"; "                                  \
-	"andl %"_LO32 _tmp",("_STK"); "                                 \
-	"pushf; "                                                       \
-	"notl %"_LO32 _tmp"; "                                          \
-	"andl %"_LO32 _tmp",("_STK"); "                                 \
-	"andl %"_LO32 _tmp","__stringify(BITS_PER_LONG/4)"("_STK"); "	\
-	"pop  %"_tmp"; "                                                \
-	"orl  %"_LO32 _tmp",("_STK"); "                                 \
-	"popf; "                                                        \
-	"pop  %"_sav"; "
-
-/* After executing instruction: write-back necessary bits in EFLAGS. */
-#define _POST_EFLAGS(_sav, _msk, _tmp) \
-	/* _sav |= EFLAGS & _msk; */		\
-	"pushf; "				\
-	"pop  %"_tmp"; "			\
-	"andl %"_msk",%"_LO32 _tmp"; "		\
-	"orl  %"_LO32 _tmp",%"_sav"; "
-
 #ifdef CONFIG_X86_64
 #define ON64(x) x
 #else
 #define ON64(x)
 #endif
 
-#define ____emulate_2op(ctxt, _op, _x, _y, _suffix, _dsttype)	\
-	do {								\
-		__asm__ __volatile__ (					\
-			_PRE_EFLAGS("0", "4", "2")			\
-			_op _suffix " %"_x"3,%1; "			\
-			_POST_EFLAGS("0", "4", "2")			\
-			: "=m" ((ctxt)->eflags),			\
-			  "+q" (*(_dsttype*)&(ctxt)->dst.val),		\
-			  "=&r" (_tmp)					\
-			: _y ((ctxt)->src.val), "i" (EFLAGS_MASK));	\
-	} while (0)
-
-
-/* Raw emulation: instruction has two explicit operands. */
-#define __emulate_2op_nobyte(ctxt,_op,_wx,_wy,_lx,_ly,_qx,_qy)		\
-	do {								\
-		unsigned long _tmp;					\
-									\
-		switch ((ctxt)->dst.bytes) {				\
-		case 2:							\
-			____emulate_2op(ctxt,_op,_wx,_wy,"w",u16);	\
-			break;						\
-		case 4:							\
-			____emulate_2op(ctxt,_op,_lx,_ly,"l",u32);	\
-			break;						\
-		case 8:							\
-			ON64(____emulate_2op(ctxt,_op,_qx,_qy,"q",u64)); \
-			break;						\
-		}							\
-	} while (0)
-
-#define __emulate_2op(ctxt,_op,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy)		     \
-	do {								     \
-		unsigned long _tmp;					     \
-		switch ((ctxt)->dst.bytes) {				     \
-		case 1:							     \
-			____emulate_2op(ctxt,_op,_bx,_by,"b",u8);	     \
-			break;						     \
-		default:						     \
-			__emulate_2op_nobyte(ctxt, _op,			     \
-					     _wx, _wy, _lx, _ly, _qx, _qy);  \
-			break;						     \
-		}							     \
-	} while (0)
-
-/* Source operand is byte-sized and may be restricted to just %cl. */
-#define emulate_2op_SrcB(ctxt, _op)					\
-	__emulate_2op(ctxt, _op, "b", "c", "b", "c", "b", "c", "b", "c")
-
-/* Source operand is byte, word, long or quad sized. */
-#define emulate_2op_SrcV(ctxt, _op)					\
-	__emulate_2op(ctxt, _op, "b", "q", "w", "r", _LO32, "r", "", "r")
-
-/* Source operand is word, long or quad sized. */
-#define emulate_2op_SrcV_nobyte(ctxt, _op)				\
-	__emulate_2op_nobyte(ctxt, _op, "w", "r", _LO32, "r", "", "r")
-
-/* Instruction has three operands and one operand is stored in ECX register */
-#define __emulate_2op_cl(ctxt, _op, _suffix, _type)		\
-	do {								\
-		unsigned long _tmp;					\
-		_type _clv  = (ctxt)->src2.val;				\
-		_type _srcv = (ctxt)->src.val;				\
-		_type _dstv = (ctxt)->dst.val;				\
-									\
-		__asm__ __volatile__ (					\
-			_PRE_EFLAGS("0", "5", "2")			\
-			_op _suffix " %4,%1 \n"				\
-			_POST_EFLAGS("0", "5", "2")			\
-			: "=m" ((ctxt)->eflags), "+r" (_dstv), "=&r" (_tmp) \
-			: "c" (_clv) , "r" (_srcv), "i" (EFLAGS_MASK)	\
-			);						\
-									\
-		(ctxt)->src2.val  = (unsigned long) _clv;		\
-		(ctxt)->src2.val = (unsigned long) _srcv;		\
-		(ctxt)->dst.val = (unsigned long) _dstv;		\
-	} while (0)
-
-#define emulate_2op_cl(ctxt, _op)					\
-	do {								\
-		switch ((ctxt)->dst.bytes) {				\
-		case 2:							\
-			__emulate_2op_cl(ctxt, _op, "w", u16);		\
-			break;						\
-		case 4:							\
-			__emulate_2op_cl(ctxt, _op, "l", u32);		\
-			break;						\
-		case 8:							\
-			ON64(__emulate_2op_cl(ctxt, _op, "q", ulong));	\
-			break;						\
-		}							\
-	} while (0)
-
-#define __emulate_1op(ctxt, _op, _suffix)				\
-	do {								\
-		unsigned long _tmp;					\
-									\
-		__asm__ __volatile__ (					\
-			_PRE_EFLAGS("0", "3", "2")			\
-			_op _suffix " %1; "				\
-			_POST_EFLAGS("0", "3", "2")			\
-			: "=m" ((ctxt)->eflags), "+m" ((ctxt)->dst.val), \
-			  "=&r" (_tmp)					\
-			: "i" (EFLAGS_MASK));				\
-	} while (0)
-
-/* Instruction has only one explicit operand (no source operand). */
-#define emulate_1op(ctxt, _op)						\
-	do {								\
-		switch ((ctxt)->dst.bytes) {				\
-		case 1:	__emulate_1op(ctxt, _op, "b"); break;		\
-		case 2:	__emulate_1op(ctxt, _op, "w"); break;		\
-		case 4:	__emulate_1op(ctxt, _op, "l"); break;		\
-		case 8:	ON64(__emulate_1op(ctxt, _op, "q")); break;	\
-		}							\
-	} while (0)
-
 static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *));
 
 #define FOP_ALIGN ".align " __stringify(FASTOP_SIZE) " \n\t"
@@ -462,7 +314,10 @@ static int fastop(struct x86_emulate_ctx
 #define FOPNOP() FOP_ALIGN FOP_RET
 
 #define FOP1E(op,  dst) \
-	FOP_ALIGN #op " %" #dst " \n\t" FOP_RET
+	FOP_ALIGN "10: " #op " %" #dst " \n\t" FOP_RET
+
+#define FOP1EEX(op,  dst) \
+	FOP1E(op, dst) _ASM_EXTABLE(10b, kvm_fastop_exception)
 
 #define FASTOP1(op) \
 	FOP_START(op) \
@@ -472,24 +327,42 @@ static int fastop(struct x86_emulate_ctx
 	ON64(FOP1E(op##q, rax))	\
 	FOP_END
 
+/* 1-operand, using src2 (for MUL/DIV r/m) */
+#define FASTOP1SRC2(op, name) \
+	FOP_START(name) \
+	FOP1E(op, cl) \
+	FOP1E(op, cx) \
+	FOP1E(op, ecx) \
+	ON64(FOP1E(op, rcx)) \
+	FOP_END
+
+/* 1-operand, using src2 (for MUL/DIV r/m), with exceptions */
+#define FASTOP1SRC2EX(op, name) \
+	FOP_START(name) \
+	FOP1EEX(op, cl) \
+	FOP1EEX(op, cx) \
+	FOP1EEX(op, ecx) \
+	ON64(FOP1EEX(op, rcx)) \
+	FOP_END
+
 #define FOP2E(op,  dst, src)	   \
 	FOP_ALIGN #op " %" #src ", %" #dst " \n\t" FOP_RET
 
 #define FASTOP2(op) \
 	FOP_START(op) \
-	FOP2E(op##b, al, bl) \
-	FOP2E(op##w, ax, bx) \
-	FOP2E(op##l, eax, ebx) \
-	ON64(FOP2E(op##q, rax, rbx)) \
+	FOP2E(op##b, al, dl) \
+	FOP2E(op##w, ax, dx) \
+	FOP2E(op##l, eax, edx) \
+	ON64(FOP2E(op##q, rax, rdx)) \
 	FOP_END
 
 /* 2 operand, word only */
 #define FASTOP2W(op) \
 	FOP_START(op) \
 	FOPNOP() \
-	FOP2E(op##w, ax, bx) \
-	FOP2E(op##l, eax, ebx) \
-	ON64(FOP2E(op##q, rax, rbx)) \
+	FOP2E(op##w, ax, dx) \
+	FOP2E(op##l, eax, edx) \
+	ON64(FOP2E(op##q, rax, rdx)) \
 	FOP_END
 
 /* 2 operand, src is CL */
@@ -508,14 +381,17 @@ static int fastop(struct x86_emulate_ctx
 #define FASTOP3WCL(op) \
 	FOP_START(op) \
 	FOPNOP() \
-	FOP3E(op##w, ax, bx, cl) \
-	FOP3E(op##l, eax, ebx, cl) \
-	ON64(FOP3E(op##q, rax, rbx, cl)) \
+	FOP3E(op##w, ax, dx, cl) \
+	FOP3E(op##l, eax, edx, cl) \
+	ON64(FOP3E(op##q, rax, rdx, cl)) \
 	FOP_END
 
 /* Special case for SETcc - 1 instruction per cc */
 #define FOP_SETCC(op) ".align 4; " #op " %al; ret \n\t"
 
+asm(".global kvm_fastop_exception \n"
+    "kvm_fastop_exception: xor %esi, %esi; ret");
+
 FOP_START(setcc)
 FOP_SETCC(seto)
 FOP_SETCC(setno)
@@ -538,47 +414,6 @@ FOP_END;
 FOP_START(salc) "pushf; sbb %al, %al; popf \n\t" FOP_RET
 FOP_END;
 
-#define __emulate_1op_rax_rdx(ctxt, _op, _suffix, _ex)			\
-	do {								\
-		unsigned long _tmp;					\
-		ulong *rax = reg_rmw((ctxt), VCPU_REGS_RAX);		\
-		ulong *rdx = reg_rmw((ctxt), VCPU_REGS_RDX);		\
-									\
-		__asm__ __volatile__ (					\
-			_PRE_EFLAGS("0", "5", "1")			\
-			"1: \n\t"					\
-			_op _suffix " %6; "				\
-			"2: \n\t"					\
-			_POST_EFLAGS("0", "5", "1")			\
-			".pushsection .fixup,\"ax\" \n\t"		\
-			"3: movb $1, %4 \n\t"				\
-			"jmp 2b \n\t"					\
-			".popsection \n\t"				\
-			_ASM_EXTABLE(1b, 3b)				\
-			: "=m" ((ctxt)->eflags), "=&r" (_tmp),		\
-			  "+a" (*rax), "+d" (*rdx), "+qm"(_ex)		\
-			: "i" (EFLAGS_MASK), "m" ((ctxt)->src.val));	\
-	} while (0)
-
-/* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
-#define emulate_1op_rax_rdx(ctxt, _op, _ex)	\
-	do {								\
-		switch((ctxt)->src.bytes) {				\
-		case 1:							\
-			__emulate_1op_rax_rdx(ctxt, _op, "b", _ex);	\
-			break;						\
-		case 2:							\
-			__emulate_1op_rax_rdx(ctxt, _op, "w", _ex);	\
-			break;						\
-		case 4:							\
-			__emulate_1op_rax_rdx(ctxt, _op, "l", _ex);	\
-			break;						\
-		case 8: ON64(						\
-			__emulate_1op_rax_rdx(ctxt, _op, "q", _ex));	\
-			break;						\
-		}							\
-	} while (0)
-
 static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt,
 				    enum x86_intercept intercept,
 				    enum x86_intercept_stage stage)
@@ -988,6 +823,11 @@ FASTOP2(xor);
 FASTOP2(cmp);
 FASTOP2(test);
 
+FASTOP1SRC2(mul, mul_ex);
+FASTOP1SRC2(imul, imul_ex);
+FASTOP1SRC2EX(div, div_ex);
+FASTOP1SRC2EX(idiv, idiv_ex);
+
 FASTOP3WCL(shld);
 FASTOP3WCL(shrd);
 
@@ -1013,6 +853,8 @@ FASTOP2W(bts);
 FASTOP2W(btr);
 FASTOP2W(btc);
 
+FASTOP2(xadd);
+
 static u8 test_cc(unsigned int condition, unsigned long flags)
 {
 	u8 rc;
@@ -1726,45 +1568,42 @@ static void write_register_operand(struc
 	}
 }
 
-static int writeback(struct x86_emulate_ctxt *ctxt)
+static int writeback(struct x86_emulate_ctxt *ctxt, struct operand *op)
 {
 	int rc;
 
-	if (ctxt->d & NoWrite)
-		return X86EMUL_CONTINUE;
-
-	switch (ctxt->dst.type) {
+	switch (op->type) {
 	case OP_REG:
-		write_register_operand(&ctxt->dst);
+		write_register_operand(op);
 		break;
 	case OP_MEM:
 		if (ctxt->lock_prefix)
 			rc = segmented_cmpxchg(ctxt,
-					       ctxt->dst.addr.mem,
-					       &ctxt->dst.orig_val,
-					       &ctxt->dst.val,
-					       ctxt->dst.bytes);
+					       op->addr.mem,
+					       &op->orig_val,
+					       &op->val,
+					       op->bytes);
 		else
 			rc = segmented_write(ctxt,
-					     ctxt->dst.addr.mem,
-					     &ctxt->dst.val,
-					     ctxt->dst.bytes);
+					     op->addr.mem,
+					     &op->val,
+					     op->bytes);
 		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		break;
 	case OP_MEM_STR:
 		rc = segmented_write(ctxt,
-				ctxt->dst.addr.mem,
-				ctxt->dst.data,
-				ctxt->dst.bytes * ctxt->dst.count);
+				op->addr.mem,
+				op->data,
+				op->bytes * op->count);
 		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		break;
 	case OP_XMM:
-		write_sse_reg(ctxt, &ctxt->dst.vec_val, ctxt->dst.addr.xmm);
+		write_sse_reg(ctxt, &op->vec_val, op->addr.xmm);
 		break;
 	case OP_MM:
-		write_mmx_reg(ctxt, &ctxt->dst.mm_val, ctxt->dst.addr.mm);
+		write_mmx_reg(ctxt, &op->mm_val, op->addr.mm);
 		break;
 	case OP_NONE:
 		/* no writeback */
@@ -2117,42 +1956,6 @@ static int em_jmp_far(struct x86_emulate
 	return X86EMUL_CONTINUE;
 }
 
-static int em_mul_ex(struct x86_emulate_ctxt *ctxt)
-{
-	u8 ex = 0;
-
-	emulate_1op_rax_rdx(ctxt, "mul", ex);
-	return X86EMUL_CONTINUE;
-}
-
-static int em_imul_ex(struct x86_emulate_ctxt *ctxt)
-{
-	u8 ex = 0;
-
-	emulate_1op_rax_rdx(ctxt, "imul", ex);
-	return X86EMUL_CONTINUE;
-}
-
-static int em_div_ex(struct x86_emulate_ctxt *ctxt)
-{
-	u8 de = 0;
-
-	emulate_1op_rax_rdx(ctxt, "div", de);
-	if (de)
-		return emulate_de(ctxt);
-	return X86EMUL_CONTINUE;
-}
-
-static int em_idiv_ex(struct x86_emulate_ctxt *ctxt)
-{
-	u8 de = 0;
-
-	emulate_1op_rax_rdx(ctxt, "idiv", de);
-	if (de)
-		return emulate_de(ctxt);
-	return X86EMUL_CONTINUE;
-}
-
 static int em_grp45(struct x86_emulate_ctxt *ctxt)
 {
 	int rc = X86EMUL_CONTINUE;
@@ -3734,10 +3537,10 @@ static const struct opcode group3[] = {
 	F(DstMem | SrcImm | NoWrite, em_test),
 	F(DstMem | SrcNone | Lock, em_not),
 	F(DstMem | SrcNone | Lock, em_neg),
-	I(SrcMem, em_mul_ex),
-	I(SrcMem, em_imul_ex),
-	I(SrcMem, em_div_ex),
-	I(SrcMem, em_idiv_ex),
+	F(DstXacc | Src2Mem, em_mul_ex),
+	F(DstXacc | Src2Mem, em_imul_ex),
+	F(DstXacc | Src2Mem, em_div_ex),
+	F(DstXacc | Src2Mem, em_idiv_ex),
 };
 
 static const struct opcode group4[] = {
@@ -4064,7 +3867,7 @@ static const struct opcode twobyte_table
 	F(DstReg | SrcMem | ModRM, em_bsf), F(DstReg | SrcMem | ModRM, em_bsr),
 	D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
 	/* 0xC0 - 0xC7 */
-	D2bv(DstMem | SrcReg | ModRM | Lock),
+	F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd),
 	N, D(DstMem | SrcReg | ModRM | Mov),
 	N, N, N, GD(0, &group9),
 	/* 0xC8 - 0xCF */
@@ -4172,6 +3975,24 @@ static int decode_operand(struct x86_emu
 		fetch_register_operand(op);
 		op->orig_val = op->val;
 		break;
+	case OpAccLo:
+		op->type = OP_REG;
+		op->bytes = (ctxt->d & ByteOp) ? 2 : ctxt->op_bytes;
+		op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX);
+		fetch_register_operand(op);
+		op->orig_val = op->val;
+		break;
+	case OpAccHi:
+		if (ctxt->d & ByteOp) {
+			op->type = OP_NONE;
+			break;
+		}
+		op->type = OP_REG;
+		op->bytes = ctxt->op_bytes;
+		op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RDX);
+		fetch_register_operand(op);
+		op->orig_val = op->val;
+		break;
 	case OpDI:
 		op->type = OP_MEM;
 		op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes;
@@ -4553,11 +4374,15 @@ static void fetch_possible_mmx_operand(s
 static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *))
 {
 	ulong flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF;
-	fop += __ffs(ctxt->dst.bytes) * FASTOP_SIZE;
+	if (!(ctxt->d & ByteOp))
+		fop += __ffs(ctxt->dst.bytes) * FASTOP_SIZE;
 	asm("push %[flags]; popf; call *%[fastop]; pushf; pop %[flags]\n"
-	    : "+a"(ctxt->dst.val), "+b"(ctxt->src.val), [flags]"+D"(flags)
-	: "c"(ctxt->src2.val), [fastop]"S"(fop));
+	    : "+a"(ctxt->dst.val), "+d"(ctxt->src.val), [flags]"+D"(flags),
+	      [fastop]"+S"(fop)
+	    : "c"(ctxt->src2.val));
 	ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK);
+	if (!fop) /* exception is returned in fop variable */
+		return emulate_de(ctxt);
 	return X86EMUL_CONTINUE;
 }
 
@@ -4773,9 +4598,17 @@ special_insn:
 		goto done;
 
 writeback:
-	rc = writeback(ctxt);
-	if (rc != X86EMUL_CONTINUE)
-		goto done;
+	if (!(ctxt->d & NoWrite)) {
+		rc = writeback(ctxt, &ctxt->dst);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+	}
+	if (ctxt->d & SrcWrite) {
+		BUG_ON(ctxt->src.type == OP_MEM || ctxt->src.type == OP_MEM_STR);
+		rc = writeback(ctxt, &ctxt->src);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+	}
 
 	/*
 	 * restore dst type in case the decoding will be reused
@@ -4872,12 +4705,6 @@ twobyte_insn:
 		ctxt->dst.val = (ctxt->src.bytes == 1) ? (s8) ctxt->src.val :
 							(s16) ctxt->src.val;
 		break;
-	case 0xc0 ... 0xc1:	/* xadd */
-		fastop(ctxt, em_add);
-		/* Write back the register source. */
-		ctxt->src.val = ctxt->dst.orig_val;
-		write_register_operand(&ctxt->src);
-		break;
 	case 0xc3:		/* movnti */
 		ctxt->dst.bytes = ctxt->op_bytes;
 		ctxt->dst.val = (ctxt->op_bytes == 4) ? (u32) ctxt->src.val :
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/lapic.c linux-libre-3.11-rc7-gnu/arch/x86/kvm/lapic.c
--- linux-libre-3.10-gnu/arch/x86/kvm/lapic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/lapic.c	2013-08-25 20:43:22.000000000 -0400
@@ -1608,8 +1608,8 @@ void kvm_inject_apic_timer_irqs(struct k
 		return;
 
 	if (atomic_read(&apic->lapic_timer.pending) > 0) {
-		if (kvm_apic_local_deliver(apic, APIC_LVTT))
-			atomic_dec(&apic->lapic_timer.pending);
+		kvm_apic_local_deliver(apic, APIC_LVTT);
+		atomic_set(&apic->lapic_timer.pending, 0);
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/Makefile linux-libre-3.11-rc7-gnu/arch/x86/kvm/Makefile
--- linux-libre-3.10-gnu/arch/x86/kvm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,12 +5,13 @@ CFLAGS_x86.o := -I.
 CFLAGS_svm.o := -I.
 CFLAGS_vmx.o := -I.
 
-kvm-y			+= $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
-				coalesced_mmio.o irq_comm.o eventfd.o \
-				irqchip.o)
-kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT)	+= $(addprefix ../../../virt/kvm/, \
-				assigned-dev.o iommu.o)
-kvm-$(CONFIG_KVM_ASYNC_PF)	+= $(addprefix ../../../virt/kvm/, async_pf.o)
+KVM := ../../../virt/kvm
+
+kvm-y			+= $(KVM)/kvm_main.o $(KVM)/ioapic.o \
+				$(KVM)/coalesced_mmio.o $(KVM)/irq_comm.o \
+				$(KVM)/eventfd.o $(KVM)/irqchip.o
+kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT)	+= $(KVM)/assigned-dev.o $(KVM)/iommu.o
+kvm-$(CONFIG_KVM_ASYNC_PF)	+= $(KVM)/async_pf.o
 
 kvm-y			+= x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
 			   i8254.o cpuid.o pmu.o
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/mmu.c linux-libre-3.11-rc7-gnu/arch/x86/kvm/mmu.c
--- linux-libre-3.10-gnu/arch/x86/kvm/mmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/mmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -197,15 +197,63 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmio
 }
 EXPORT_SYMBOL_GPL(kvm_mmu_set_mmio_spte_mask);
 
-static void mark_mmio_spte(u64 *sptep, u64 gfn, unsigned access)
+/*
+ * spte bits of bit 3 ~ bit 11 are used as low 9 bits of generation number,
+ * the bits of bits 52 ~ bit 61 are used as high 10 bits of generation
+ * number.
+ */
+#define MMIO_SPTE_GEN_LOW_SHIFT		3
+#define MMIO_SPTE_GEN_HIGH_SHIFT	52
+
+#define MMIO_GEN_SHIFT			19
+#define MMIO_GEN_LOW_SHIFT		9
+#define MMIO_GEN_LOW_MASK		((1 << MMIO_GEN_LOW_SHIFT) - 1)
+#define MMIO_GEN_MASK			((1 << MMIO_GEN_SHIFT) - 1)
+#define MMIO_MAX_GEN			((1 << MMIO_GEN_SHIFT) - 1)
+
+static u64 generation_mmio_spte_mask(unsigned int gen)
 {
-	struct kvm_mmu_page *sp =  page_header(__pa(sptep));
+	u64 mask;
+
+	WARN_ON(gen > MMIO_MAX_GEN);
+
+	mask = (gen & MMIO_GEN_LOW_MASK) << MMIO_SPTE_GEN_LOW_SHIFT;
+	mask |= ((u64)gen >> MMIO_GEN_LOW_SHIFT) << MMIO_SPTE_GEN_HIGH_SHIFT;
+	return mask;
+}
+
+static unsigned int get_mmio_spte_generation(u64 spte)
+{
+	unsigned int gen;
+
+	spte &= ~shadow_mmio_mask;
+
+	gen = (spte >> MMIO_SPTE_GEN_LOW_SHIFT) & MMIO_GEN_LOW_MASK;
+	gen |= (spte >> MMIO_SPTE_GEN_HIGH_SHIFT) << MMIO_GEN_LOW_SHIFT;
+	return gen;
+}
+
+static unsigned int kvm_current_mmio_generation(struct kvm *kvm)
+{
+	/*
+	 * Init kvm generation close to MMIO_MAX_GEN to easily test the
+	 * code of handling generation number wrap-around.
+	 */
+	return (kvm_memslots(kvm)->generation +
+		      MMIO_MAX_GEN - 150) & MMIO_GEN_MASK;
+}
+
+static void mark_mmio_spte(struct kvm *kvm, u64 *sptep, u64 gfn,
+			   unsigned access)
+{
+	unsigned int gen = kvm_current_mmio_generation(kvm);
+	u64 mask = generation_mmio_spte_mask(gen);
 
 	access &= ACC_WRITE_MASK | ACC_USER_MASK;
+	mask |= shadow_mmio_mask | access | gfn << PAGE_SHIFT;
 
-	sp->mmio_cached = true;
-	trace_mark_mmio_spte(sptep, gfn, access);
-	mmu_spte_set(sptep, shadow_mmio_mask | access | gfn << PAGE_SHIFT);
+	trace_mark_mmio_spte(sptep, gfn, access, gen);
+	mmu_spte_set(sptep, mask);
 }
 
 static bool is_mmio_spte(u64 spte)
@@ -215,24 +263,38 @@ static bool is_mmio_spte(u64 spte)
 
 static gfn_t get_mmio_spte_gfn(u64 spte)
 {
-	return (spte & ~shadow_mmio_mask) >> PAGE_SHIFT;
+	u64 mask = generation_mmio_spte_mask(MMIO_MAX_GEN) | shadow_mmio_mask;
+	return (spte & ~mask) >> PAGE_SHIFT;
 }
 
 static unsigned get_mmio_spte_access(u64 spte)
 {
-	return (spte & ~shadow_mmio_mask) & ~PAGE_MASK;
+	u64 mask = generation_mmio_spte_mask(MMIO_MAX_GEN) | shadow_mmio_mask;
+	return (spte & ~mask) & ~PAGE_MASK;
 }
 
-static bool set_mmio_spte(u64 *sptep, gfn_t gfn, pfn_t pfn, unsigned access)
+static bool set_mmio_spte(struct kvm *kvm, u64 *sptep, gfn_t gfn,
+			  pfn_t pfn, unsigned access)
 {
 	if (unlikely(is_noslot_pfn(pfn))) {
-		mark_mmio_spte(sptep, gfn, access);
+		mark_mmio_spte(kvm, sptep, gfn, access);
 		return true;
 	}
 
 	return false;
 }
 
+static bool check_mmio_spte(struct kvm *kvm, u64 spte)
+{
+	unsigned int kvm_gen, spte_gen;
+
+	kvm_gen = kvm_current_mmio_generation(kvm);
+	spte_gen = get_mmio_spte_generation(spte);
+
+	trace_check_mmio_spte(spte, kvm_gen, spte_gen);
+	return likely(kvm_gen == spte_gen);
+}
+
 static inline u64 rsvd_bits(int s, int e)
 {
 	return ((1ULL << (e - s + 1)) - 1) << s;
@@ -404,9 +466,20 @@ static u64 __update_clear_spte_slow(u64
 /*
  * The idea using the light way get the spte on x86_32 guest is from
  * gup_get_pte(arch/x86/mm/gup.c).
- * The difference is we can not catch the spte tlb flush if we leave
- * guest mode, so we emulate it by increase clear_spte_count when spte
- * is cleared.
+ *
+ * An spte tlb flush may be pending, because kvm_set_pte_rmapp
+ * coalesces them and we are running out of the MMU lock.  Therefore
+ * we need to protect against in-progress updates of the spte.
+ *
+ * Reading the spte while an update is in progress may get the old value
+ * for the high part of the spte.  The race is fine for a present->non-present
+ * change (because the high part of the spte is ignored for non-present spte),
+ * but for a present->present change we must reread the spte.
+ *
+ * All such changes are done in two steps (present->non-present and
+ * non-present->present), hence it is enough to count the number of
+ * present->non-present updates: if it changed while reading the spte,
+ * we might have hit the race.  This is done using clear_spte_count.
  */
 static u64 __get_spte_lockless(u64 *sptep)
 {
@@ -1511,6 +1584,12 @@ static struct kvm_mmu_page *kvm_mmu_allo
 	if (!direct)
 		sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache);
 	set_page_private(virt_to_page(sp->spt), (unsigned long)sp);
+
+	/*
+	 * The active_mmu_pages list is the FIFO list, do not move the
+	 * page until it is zapped. kvm_zap_obsolete_pages depends on
+	 * this feature. See the comments in kvm_zap_obsolete_pages().
+	 */
 	list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages);
 	sp->parent_ptes = 0;
 	mmu_page_add_parent_pte(vcpu, sp, parent_pte);
@@ -1648,6 +1727,16 @@ static int kvm_mmu_prepare_zap_page(stru
 static void kvm_mmu_commit_zap_page(struct kvm *kvm,
 				    struct list_head *invalid_list);
 
+/*
+ * NOTE: we should pay more attention on the zapped-obsolete page
+ * (is_obsolete_sp(sp) && sp->role.invalid) when you do hash list walk
+ * since it has been deleted from active_mmu_pages but still can be found
+ * at hast list.
+ *
+ * for_each_gfn_indirect_valid_sp has skipped that kind of page and
+ * kvm_mmu_get_page(), the only user of for_each_gfn_sp(), has skipped
+ * all the obsolete pages.
+ */
 #define for_each_gfn_sp(_kvm, _sp, _gfn)				\
 	hlist_for_each_entry(_sp,					\
 	  &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)], hash_link) \
@@ -1838,6 +1927,11 @@ static void clear_sp_write_flooding_coun
 	__clear_sp_write_flooding_count(sp);
 }
 
+static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
+{
+	return unlikely(sp->mmu_valid_gen != kvm->arch.mmu_valid_gen);
+}
+
 static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
 					     gfn_t gfn,
 					     gva_t gaddr,
@@ -1864,6 +1958,9 @@ static struct kvm_mmu_page *kvm_mmu_get_
 		role.quadrant = quadrant;
 	}
 	for_each_gfn_sp(vcpu->kvm, sp, gfn) {
+		if (is_obsolete_sp(vcpu->kvm, sp))
+			continue;
+
 		if (!need_sync && sp->unsync)
 			need_sync = true;
 
@@ -1900,6 +1997,7 @@ static struct kvm_mmu_page *kvm_mmu_get_
 
 		account_shadowed(vcpu->kvm, gfn);
 	}
+	sp->mmu_valid_gen = vcpu->kvm->arch.mmu_valid_gen;
 	init_shadow_page_table(sp);
 	trace_kvm_mmu_get_page(sp, true);
 	return sp;
@@ -2070,8 +2168,10 @@ static int kvm_mmu_prepare_zap_page(stru
 	ret = mmu_zap_unsync_children(kvm, sp, invalid_list);
 	kvm_mmu_page_unlink_children(kvm, sp);
 	kvm_mmu_unlink_parents(kvm, sp);
+
 	if (!sp->role.invalid && !sp->role.direct)
 		unaccount_shadowed(kvm, sp->gfn);
+
 	if (sp->unsync)
 		kvm_unlink_unsync_page(kvm, sp);
 	if (!sp->root_count) {
@@ -2081,7 +2181,13 @@ static int kvm_mmu_prepare_zap_page(stru
 		kvm_mod_used_mmu_pages(kvm, -1);
 	} else {
 		list_move(&sp->link, &kvm->arch.active_mmu_pages);
-		kvm_reload_remote_mmus(kvm);
+
+		/*
+		 * The obsolete pages can not be used on any vcpus.
+		 * See the comments in kvm_mmu_invalidate_zap_all_pages().
+		 */
+		if (!sp->role.invalid && !is_obsolete_sp(kvm, sp))
+			kvm_reload_remote_mmus(kvm);
 	}
 
 	sp->role.invalid = 1;
@@ -2331,7 +2437,7 @@ static int set_spte(struct kvm_vcpu *vcp
 	u64 spte;
 	int ret = 0;
 
-	if (set_mmio_spte(sptep, gfn, pfn, pte_access))
+	if (set_mmio_spte(vcpu->kvm, sptep, gfn, pfn, pte_access))
 		return 0;
 
 	spte = PT_PRESENT_MASK;
@@ -2705,6 +2811,13 @@ exit:
 static bool page_fault_can_be_fast(struct kvm_vcpu *vcpu, u32 error_code)
 {
 	/*
+	 * Do not fix the mmio spte with invalid generation number which
+	 * need to be updated by slow page fault path.
+	 */
+	if (unlikely(error_code & PFERR_RSVD_MASK))
+		return false;
+
+	/*
 	 * #PF can be fast only if the shadow page table is present and it
 	 * is caused by write-protect, that means we just need change the
 	 * W bit of the spte which can be done out of mmu-lock.
@@ -2869,22 +2982,25 @@ static void mmu_free_roots(struct kvm_vc
 
 	if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
 		return;
-	spin_lock(&vcpu->kvm->mmu_lock);
+
 	if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL &&
 	    (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL ||
 	     vcpu->arch.mmu.direct_map)) {
 		hpa_t root = vcpu->arch.mmu.root_hpa;
 
+		spin_lock(&vcpu->kvm->mmu_lock);
 		sp = page_header(root);
 		--sp->root_count;
 		if (!sp->root_count && sp->role.invalid) {
 			kvm_mmu_prepare_zap_page(vcpu->kvm, sp, &invalid_list);
 			kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
 		}
-		vcpu->arch.mmu.root_hpa = INVALID_PAGE;
 		spin_unlock(&vcpu->kvm->mmu_lock);
+		vcpu->arch.mmu.root_hpa = INVALID_PAGE;
 		return;
 	}
+
+	spin_lock(&vcpu->kvm->mmu_lock);
 	for (i = 0; i < 4; ++i) {
 		hpa_t root = vcpu->arch.mmu.pae_root[i];
 
@@ -3148,17 +3264,12 @@ static u64 walk_shadow_page_get_mmio_spt
 	return spte;
 }
 
-/*
- * If it is a real mmio page fault, return 1 and emulat the instruction
- * directly, return 0 to let CPU fault again on the address, -1 is
- * returned if bug is detected.
- */
 int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct)
 {
 	u64 spte;
 
 	if (quickly_check_mmio_pf(vcpu, addr, direct))
-		return 1;
+		return RET_MMIO_PF_EMULATE;
 
 	spte = walk_shadow_page_get_mmio_spte(vcpu, addr);
 
@@ -3166,12 +3277,15 @@ int handle_mmio_page_fault_common(struct
 		gfn_t gfn = get_mmio_spte_gfn(spte);
 		unsigned access = get_mmio_spte_access(spte);
 
+		if (!check_mmio_spte(vcpu->kvm, spte))
+			return RET_MMIO_PF_INVALID;
+
 		if (direct)
 			addr = 0;
 
 		trace_handle_mmio_page_fault(addr, gfn, access);
 		vcpu_cache_mmio_info(vcpu, addr, gfn, access);
-		return 1;
+		return RET_MMIO_PF_EMULATE;
 	}
 
 	/*
@@ -3179,13 +3293,13 @@ int handle_mmio_page_fault_common(struct
 	 * it's a BUG if the gfn is not a mmio page.
 	 */
 	if (direct && !check_direct_spte_mmio_pf(spte))
-		return -1;
+		return RET_MMIO_PF_BUG;
 
 	/*
 	 * If the page table is zapped by other cpus, let CPU fault again on
 	 * the address.
 	 */
-	return 0;
+	return RET_MMIO_PF_RETRY;
 }
 EXPORT_SYMBOL_GPL(handle_mmio_page_fault_common);
 
@@ -3195,7 +3309,7 @@ static int handle_mmio_page_fault(struct
 	int ret;
 
 	ret = handle_mmio_page_fault_common(vcpu, addr, direct);
-	WARN_ON(ret < 0);
+	WARN_ON(ret == RET_MMIO_PF_BUG);
 	return ret;
 }
 
@@ -3207,8 +3321,12 @@ static int nonpaging_page_fault(struct k
 
 	pgprintk("%s: gva %lx error %x\n", __func__, gva, error_code);
 
-	if (unlikely(error_code & PFERR_RSVD_MASK))
-		return handle_mmio_page_fault(vcpu, gva, error_code, true);
+	if (unlikely(error_code & PFERR_RSVD_MASK)) {
+		r = handle_mmio_page_fault(vcpu, gva, error_code, true);
+
+		if (likely(r != RET_MMIO_PF_INVALID))
+			return r;
+	}
 
 	r = mmu_topup_memory_caches(vcpu);
 	if (r)
@@ -3284,8 +3402,12 @@ static int tdp_page_fault(struct kvm_vcp
 	ASSERT(vcpu);
 	ASSERT(VALID_PAGE(vcpu->arch.mmu.root_hpa));
 
-	if (unlikely(error_code & PFERR_RSVD_MASK))
-		return handle_mmio_page_fault(vcpu, gpa, error_code, true);
+	if (unlikely(error_code & PFERR_RSVD_MASK)) {
+		r = handle_mmio_page_fault(vcpu, gpa, error_code, true);
+
+		if (likely(r != RET_MMIO_PF_INVALID))
+			return r;
+	}
 
 	r = mmu_topup_memory_caches(vcpu);
 	if (r)
@@ -3391,8 +3513,8 @@ static inline void protect_clean_gpte(un
 	*access &= mask;
 }
 
-static bool sync_mmio_spte(u64 *sptep, gfn_t gfn, unsigned access,
-			   int *nr_present)
+static bool sync_mmio_spte(struct kvm *kvm, u64 *sptep, gfn_t gfn,
+			   unsigned access, int *nr_present)
 {
 	if (unlikely(is_mmio_spte(*sptep))) {
 		if (gfn != get_mmio_spte_gfn(*sptep)) {
@@ -3401,7 +3523,7 @@ static bool sync_mmio_spte(u64 *sptep, g
 		}
 
 		(*nr_present)++;
-		mark_mmio_spte(sptep, gfn, access);
+		mark_mmio_spte(kvm, sptep, gfn, access);
 		return true;
 	}
 
@@ -3764,9 +3886,7 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
 	if (r)
 		goto out;
 	r = mmu_alloc_roots(vcpu);
-	spin_lock(&vcpu->kvm->mmu_lock);
-	mmu_sync_roots(vcpu);
-	spin_unlock(&vcpu->kvm->mmu_lock);
+	kvm_mmu_sync_roots(vcpu);
 	if (r)
 		goto out;
 	/* set_cr3() should ensure TLB has been flushed */
@@ -4179,39 +4299,107 @@ void kvm_mmu_slot_remove_write_access(st
 	spin_unlock(&kvm->mmu_lock);
 }
 
-void kvm_mmu_zap_all(struct kvm *kvm)
+#define BATCH_ZAP_PAGES	10
+static void kvm_zap_obsolete_pages(struct kvm *kvm)
 {
 	struct kvm_mmu_page *sp, *node;
-	LIST_HEAD(invalid_list);
+	int batch = 0;
 
-	spin_lock(&kvm->mmu_lock);
 restart:
-	list_for_each_entry_safe(sp, node, &kvm->arch.active_mmu_pages, link)
-		if (kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list))
+	list_for_each_entry_safe_reverse(sp, node,
+	      &kvm->arch.active_mmu_pages, link) {
+		int ret;
+
+		/*
+		 * No obsolete page exists before new created page since
+		 * active_mmu_pages is the FIFO list.
+		 */
+		if (!is_obsolete_sp(kvm, sp))
+			break;
+
+		/*
+		 * Since we are reversely walking the list and the invalid
+		 * list will be moved to the head, skip the invalid page
+		 * can help us to avoid the infinity list walking.
+		 */
+		if (sp->role.invalid)
+			continue;
+
+		/*
+		 * Need not flush tlb since we only zap the sp with invalid
+		 * generation number.
+		 */
+		if (batch >= BATCH_ZAP_PAGES &&
+		      cond_resched_lock(&kvm->mmu_lock)) {
+			batch = 0;
 			goto restart;
+		}
 
-	kvm_mmu_commit_zap_page(kvm, &invalid_list);
-	spin_unlock(&kvm->mmu_lock);
+		ret = kvm_mmu_prepare_zap_page(kvm, sp,
+				&kvm->arch.zapped_obsolete_pages);
+		batch += ret;
+
+		if (ret)
+			goto restart;
+	}
+
+	/*
+	 * Should flush tlb before free page tables since lockless-walking
+	 * may use the pages.
+	 */
+	kvm_mmu_commit_zap_page(kvm, &kvm->arch.zapped_obsolete_pages);
 }
 
-void kvm_mmu_zap_mmio_sptes(struct kvm *kvm)
+/*
+ * Fast invalidate all shadow pages and use lock-break technique
+ * to zap obsolete pages.
+ *
+ * It's required when memslot is being deleted or VM is being
+ * destroyed, in these cases, we should ensure that KVM MMU does
+ * not use any resource of the being-deleted slot or all slots
+ * after calling the function.
+ */
+void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm)
 {
-	struct kvm_mmu_page *sp, *node;
-	LIST_HEAD(invalid_list);
-
 	spin_lock(&kvm->mmu_lock);
-restart:
-	list_for_each_entry_safe(sp, node, &kvm->arch.active_mmu_pages, link) {
-		if (!sp->mmio_cached)
-			continue;
-		if (kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list))
-			goto restart;
-	}
+	trace_kvm_mmu_invalidate_zap_all_pages(kvm);
+	kvm->arch.mmu_valid_gen++;
 
-	kvm_mmu_commit_zap_page(kvm, &invalid_list);
+	/*
+	 * Notify all vcpus to reload its shadow page table
+	 * and flush TLB. Then all vcpus will switch to new
+	 * shadow page table with the new mmu_valid_gen.
+	 *
+	 * Note: we should do this under the protection of
+	 * mmu-lock, otherwise, vcpu would purge shadow page
+	 * but miss tlb flush.
+	 */
+	kvm_reload_remote_mmus(kvm);
+
+	kvm_zap_obsolete_pages(kvm);
 	spin_unlock(&kvm->mmu_lock);
 }
 
+static bool kvm_has_zapped_obsolete_pages(struct kvm *kvm)
+{
+	return unlikely(!list_empty_careful(&kvm->arch.zapped_obsolete_pages));
+}
+
+void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm)
+{
+	/*
+	 * The very rare case: if the generation-number is round,
+	 * zap all shadow pages.
+	 *
+	 * The max value is MMIO_MAX_GEN - 1 since it is not called
+	 * when mark memslot invalid.
+	 */
+	if (unlikely(kvm_current_mmio_generation(kvm) >= (MMIO_MAX_GEN - 1))) {
+		printk_ratelimited(KERN_INFO "kvm: zapping shadow pages for mmio generation wraparound\n");
+		kvm_mmu_invalidate_zap_all_pages(kvm);
+	}
+}
+
 static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc)
 {
 	struct kvm *kvm;
@@ -4240,15 +4428,23 @@ static int mmu_shrink(struct shrinker *s
 		 * want to shrink a VM that only started to populate its MMU
 		 * anyway.
 		 */
-		if (!kvm->arch.n_used_mmu_pages)
+		if (!kvm->arch.n_used_mmu_pages &&
+		      !kvm_has_zapped_obsolete_pages(kvm))
 			continue;
 
 		idx = srcu_read_lock(&kvm->srcu);
 		spin_lock(&kvm->mmu_lock);
 
+		if (kvm_has_zapped_obsolete_pages(kvm)) {
+			kvm_mmu_commit_zap_page(kvm,
+			      &kvm->arch.zapped_obsolete_pages);
+			goto unlock;
+		}
+
 		prepare_zap_oldest_mmu_page(kvm, &invalid_list);
 		kvm_mmu_commit_zap_page(kvm, &invalid_list);
 
+unlock:
 		spin_unlock(&kvm->mmu_lock);
 		srcu_read_unlock(&kvm->srcu, idx);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/mmu.h linux-libre-3.11-rc7-gnu/arch/x86/kvm/mmu.h
--- linux-libre-3.10-gnu/arch/x86/kvm/mmu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/mmu.h	2013-08-25 20:43:22.000000000 -0400
@@ -52,6 +52,23 @@
 
 int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
 void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask);
+
+/*
+ * Return values of handle_mmio_page_fault_common:
+ * RET_MMIO_PF_EMULATE: it is a real mmio page fault, emulate the instruction
+ *			directly.
+ * RET_MMIO_PF_INVALID: invalid spte is detected then let the real page
+ *			fault path update the mmio spte.
+ * RET_MMIO_PF_RETRY: let CPU fault again on the address.
+ * RET_MMIO_PF_BUG: bug is detected.
+ */
+enum {
+	RET_MMIO_PF_EMULATE = 1,
+	RET_MMIO_PF_INVALID = 2,
+	RET_MMIO_PF_RETRY = 0,
+	RET_MMIO_PF_BUG = -1
+};
+
 int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct);
 int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context);
 
@@ -97,4 +114,5 @@ static inline bool permission_fault(stru
 	return (mmu->permissions[pfec >> 1] >> pte_access) & 1;
 }
 
+void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm);
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/mmutrace.h linux-libre-3.11-rc7-gnu/arch/x86/kvm/mmutrace.h
--- linux-libre-3.10-gnu/arch/x86/kvm/mmutrace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/mmutrace.h	2013-08-25 20:43:22.000000000 -0400
@@ -7,16 +7,18 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM kvmmmu
 
-#define KVM_MMU_PAGE_FIELDS \
-	__field(__u64, gfn) \
-	__field(__u32, role) \
-	__field(__u32, root_count) \
+#define KVM_MMU_PAGE_FIELDS			\
+	__field(unsigned long, mmu_valid_gen)	\
+	__field(__u64, gfn)			\
+	__field(__u32, role)			\
+	__field(__u32, root_count)		\
 	__field(bool, unsync)
 
-#define KVM_MMU_PAGE_ASSIGN(sp)			     \
-	__entry->gfn = sp->gfn;			     \
-	__entry->role = sp->role.word;		     \
-	__entry->root_count = sp->root_count;        \
+#define KVM_MMU_PAGE_ASSIGN(sp)				\
+	__entry->mmu_valid_gen = sp->mmu_valid_gen;	\
+	__entry->gfn = sp->gfn;				\
+	__entry->role = sp->role.word;			\
+	__entry->root_count = sp->root_count;		\
 	__entry->unsync = sp->unsync;
 
 #define KVM_MMU_PAGE_PRINTK() ({				        \
@@ -28,8 +30,8 @@
 								        \
 	role.word = __entry->role;					\
 									\
-	trace_seq_printf(p, "sp gfn %llx %u%s q%u%s %s%s"		\
-			 " %snxe root %u %s%c",				\
+	trace_seq_printf(p, "sp gen %lx gfn %llx %u%s q%u%s %s%s"	\
+			 " %snxe root %u %s%c",	__entry->mmu_valid_gen,	\
 			 __entry->gfn, role.level,			\
 			 role.cr4_pae ? " pae" : "",			\
 			 role.quadrant,					\
@@ -197,23 +199,25 @@ DEFINE_EVENT(kvm_mmu_page_class, kvm_mmu
 
 TRACE_EVENT(
 	mark_mmio_spte,
-	TP_PROTO(u64 *sptep, gfn_t gfn, unsigned access),
-	TP_ARGS(sptep, gfn, access),
+	TP_PROTO(u64 *sptep, gfn_t gfn, unsigned access, unsigned int gen),
+	TP_ARGS(sptep, gfn, access, gen),
 
 	TP_STRUCT__entry(
 		__field(void *, sptep)
 		__field(gfn_t, gfn)
 		__field(unsigned, access)
+		__field(unsigned int, gen)
 	),
 
 	TP_fast_assign(
 		__entry->sptep = sptep;
 		__entry->gfn = gfn;
 		__entry->access = access;
+		__entry->gen = gen;
 	),
 
-	TP_printk("sptep:%p gfn %llx access %x", __entry->sptep, __entry->gfn,
-		  __entry->access)
+	TP_printk("sptep:%p gfn %llx access %x gen %x", __entry->sptep,
+		  __entry->gfn, __entry->access, __entry->gen)
 );
 
 TRACE_EVENT(
@@ -274,6 +278,50 @@ TRACE_EVENT(
 		  __spte_satisfied(old_spte), __spte_satisfied(new_spte)
 	)
 );
+
+TRACE_EVENT(
+	kvm_mmu_invalidate_zap_all_pages,
+	TP_PROTO(struct kvm *kvm),
+	TP_ARGS(kvm),
+
+	TP_STRUCT__entry(
+		__field(unsigned long, mmu_valid_gen)
+		__field(unsigned int, mmu_used_pages)
+	),
+
+	TP_fast_assign(
+		__entry->mmu_valid_gen = kvm->arch.mmu_valid_gen;
+		__entry->mmu_used_pages = kvm->arch.n_used_mmu_pages;
+	),
+
+	TP_printk("kvm-mmu-valid-gen %lx used_pages %x",
+		  __entry->mmu_valid_gen, __entry->mmu_used_pages
+	)
+);
+
+
+TRACE_EVENT(
+	check_mmio_spte,
+	TP_PROTO(u64 spte, unsigned int kvm_gen, unsigned int spte_gen),
+	TP_ARGS(spte, kvm_gen, spte_gen),
+
+	TP_STRUCT__entry(
+		__field(unsigned int, kvm_gen)
+		__field(unsigned int, spte_gen)
+		__field(u64, spte)
+	),
+
+	TP_fast_assign(
+		__entry->kvm_gen = kvm_gen;
+		__entry->spte_gen = spte_gen;
+		__entry->spte = spte;
+	),
+
+	TP_printk("spte %llx kvm_gen %x spte-gen %x valid %d", __entry->spte,
+		  __entry->kvm_gen, __entry->spte_gen,
+		  __entry->kvm_gen == __entry->spte_gen
+	)
+);
 #endif /* _TRACE_KVMMMU_H */
 
 #undef TRACE_INCLUDE_PATH
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/paging_tmpl.h linux-libre-3.11-rc7-gnu/arch/x86/kvm/paging_tmpl.h
--- linux-libre-3.10-gnu/arch/x86/kvm/paging_tmpl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/paging_tmpl.h	2013-08-25 20:43:22.000000000 -0400
@@ -552,9 +552,12 @@ static int FNAME(page_fault)(struct kvm_
 
 	pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code);
 
-	if (unlikely(error_code & PFERR_RSVD_MASK))
-		return handle_mmio_page_fault(vcpu, addr, error_code,
+	if (unlikely(error_code & PFERR_RSVD_MASK)) {
+		r = handle_mmio_page_fault(vcpu, addr, error_code,
 					      mmu_is_nested(vcpu));
+		if (likely(r != RET_MMIO_PF_INVALID))
+			return r;
+	};
 
 	r = mmu_topup_memory_caches(vcpu);
 	if (r)
@@ -792,7 +795,8 @@ static int FNAME(sync_page)(struct kvm_v
 		pte_access &= gpte_access(vcpu, gpte);
 		protect_clean_gpte(&pte_access, gpte);
 
-		if (sync_mmio_spte(&sp->spt[i], gfn, pte_access, &nr_present))
+		if (sync_mmio_spte(vcpu->kvm, &sp->spt[i], gfn, pte_access,
+		      &nr_present))
 			continue;
 
 		if (gfn != sp->gfns[i]) {
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/svm.c linux-libre-3.11-rc7-gnu/arch/x86/kvm/svm.c
--- linux-libre-3.10-gnu/arch/x86/kvm/svm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/svm.c	2013-08-25 20:43:22.000000000 -0400
@@ -1026,7 +1026,10 @@ static void svm_write_tsc_offset(struct
 		g_tsc_offset = svm->vmcb->control.tsc_offset -
 			       svm->nested.hsave->control.tsc_offset;
 		svm->nested.hsave->control.tsc_offset = offset;
-	}
+	} else
+		trace_kvm_write_tsc_offset(vcpu->vcpu_id,
+					   svm->vmcb->control.tsc_offset,
+					   offset);
 
 	svm->vmcb->control.tsc_offset = offset + g_tsc_offset;
 
@@ -1044,6 +1047,11 @@ static void svm_adjust_tsc_offset(struct
 	svm->vmcb->control.tsc_offset += adjustment;
 	if (is_guest_mode(vcpu))
 		svm->nested.hsave->control.tsc_offset += adjustment;
+	else
+		trace_kvm_write_tsc_offset(vcpu->vcpu_id,
+				     svm->vmcb->control.tsc_offset - adjustment,
+				     svm->vmcb->control.tsc_offset);
+
 	mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/trace.h linux-libre-3.11-rc7-gnu/arch/x86/kvm/trace.h
--- linux-libre-3.10-gnu/arch/x86/kvm/trace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/trace.h	2013-08-25 20:43:22.000000000 -0400
@@ -756,6 +756,27 @@ TRACE_EVENT(
 		  __entry->gpa_match ? "GPA" : "GVA")
 );
 
+TRACE_EVENT(kvm_write_tsc_offset,
+	TP_PROTO(unsigned int vcpu_id, __u64 previous_tsc_offset,
+		 __u64 next_tsc_offset),
+	TP_ARGS(vcpu_id, previous_tsc_offset, next_tsc_offset),
+
+	TP_STRUCT__entry(
+		__field( unsigned int,	vcpu_id				)
+		__field(	__u64,	previous_tsc_offset		)
+		__field(	__u64,	next_tsc_offset			)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu_id		= vcpu_id;
+		__entry->previous_tsc_offset	= previous_tsc_offset;
+		__entry->next_tsc_offset	= next_tsc_offset;
+	),
+
+	TP_printk("vcpu=%u prev=%llu next=%llu", __entry->vcpu_id,
+		  __entry->previous_tsc_offset, __entry->next_tsc_offset)
+);
+
 #ifdef CONFIG_X86_64
 
 #define host_clocks					\
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/vmx.c linux-libre-3.11-rc7-gnu/arch/x86/kvm/vmx.c
--- linux-libre-3.10-gnu/arch/x86/kvm/vmx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/vmx.c	2013-08-25 20:43:22.000000000 -0400
@@ -2096,6 +2096,8 @@ static void vmx_write_tsc_offset(struct
 			(nested_cpu_has(vmcs12, CPU_BASED_USE_TSC_OFFSETING) ?
 			 vmcs12->tsc_offset : 0));
 	} else {
+		trace_kvm_write_tsc_offset(vcpu->vcpu_id,
+					   vmcs_read64(TSC_OFFSET), offset);
 		vmcs_write64(TSC_OFFSET, offset);
 	}
 }
@@ -2103,11 +2105,14 @@ static void vmx_write_tsc_offset(struct
 static void vmx_adjust_tsc_offset(struct kvm_vcpu *vcpu, s64 adjustment, bool host)
 {
 	u64 offset = vmcs_read64(TSC_OFFSET);
+
 	vmcs_write64(TSC_OFFSET, offset + adjustment);
 	if (is_guest_mode(vcpu)) {
 		/* Even when running L2, the adjustment needs to apply to L1 */
 		to_vmx(vcpu)->nested.vmcs01_tsc_offset += adjustment;
-	}
+	} else
+		trace_kvm_write_tsc_offset(vcpu->vcpu_id, offset,
+					   offset + adjustment);
 }
 
 static u64 vmx_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
@@ -3399,15 +3404,22 @@ static void vmx_get_segment(struct kvm_v
 	var->limit = vmx_read_guest_seg_limit(vmx, seg);
 	var->selector = vmx_read_guest_seg_selector(vmx, seg);
 	ar = vmx_read_guest_seg_ar(vmx, seg);
+	var->unusable = (ar >> 16) & 1;
 	var->type = ar & 15;
 	var->s = (ar >> 4) & 1;
 	var->dpl = (ar >> 5) & 3;
-	var->present = (ar >> 7) & 1;
+	/*
+	 * Some userspaces do not preserve unusable property. Since usable
+	 * segment has to be present according to VMX spec we can use present
+	 * property to amend userspace bug by making unusable segment always
+	 * nonpresent. vmx_segment_access_rights() already marks nonpresent
+	 * segment as unusable.
+	 */
+	var->present = !var->unusable;
 	var->avl = (ar >> 12) & 1;
 	var->l = (ar >> 13) & 1;
 	var->db = (ar >> 14) & 1;
 	var->g = (ar >> 15) & 1;
-	var->unusable = (ar >> 16) & 1;
 }
 
 static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
@@ -4176,10 +4188,10 @@ static void ept_set_mmio_spte_mask(void)
 	/*
 	 * EPT Misconfigurations can be generated if the value of bits 2:0
 	 * of an EPT paging-structure entry is 110b (write/execute).
-	 * Also, magic bits (0xffull << 49) is set to quickly identify mmio
+	 * Also, magic bits (0x3ull << 62) is set to quickly identify mmio
 	 * spte.
 	 */
-	kvm_mmu_set_mmio_spte_mask(0xffull << 49 | 0x6ull);
+	kvm_mmu_set_mmio_spte_mask((0x3ull << 62) | 0x6ull);
 }
 
 /*
@@ -5366,10 +5378,14 @@ static int handle_ept_misconfig(struct k
 	gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
 
 	ret = handle_mmio_page_fault_common(vcpu, gpa, true);
-	if (likely(ret == 1))
+	if (likely(ret == RET_MMIO_PF_EMULATE))
 		return x86_emulate_instruction(vcpu, gpa, 0, NULL, 0) ==
 					      EMULATE_DONE;
-	if (unlikely(!ret))
+
+	if (unlikely(ret == RET_MMIO_PF_INVALID))
+		return kvm_mmu_page_fault(vcpu, gpa, 0, NULL, 0);
+
+	if (unlikely(ret == RET_MMIO_PF_RETRY))
 		return 1;
 
 	/* It is the real ept misconfig */
@@ -7942,7 +7958,7 @@ static void load_vmcs12_host_state(struc
 
 	kvm_register_write(vcpu, VCPU_REGS_RSP, vmcs12->host_rsp);
 	kvm_register_write(vcpu, VCPU_REGS_RIP, vmcs12->host_rip);
-	vmx_set_rflags(vcpu, X86_EFLAGS_BIT1);
+	vmx_set_rflags(vcpu, X86_EFLAGS_FIXED);
 	/*
 	 * Note that calling vmx_set_cr0 is important, even if cr0 hasn't
 	 * actually changed, because it depends on the current state of
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/kvm/x86.c linux-libre-3.11-rc7-gnu/arch/x86/kvm/x86.c
--- linux-libre-3.10-gnu/arch/x86/kvm/x86.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/kvm/x86.c	2013-08-25 20:43:22.000000000 -0400
@@ -618,7 +618,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, u
 	if (!guest_cpuid_has_smep(vcpu) && (cr4 & X86_CR4_SMEP))
 		return 1;
 
-	if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_RDWRGSFS))
+	if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE))
 		return 1;
 
 	if (is_long_mode(vcpu)) {
@@ -1193,20 +1193,37 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu
 	elapsed = ns - kvm->arch.last_tsc_nsec;
 
 	if (vcpu->arch.virtual_tsc_khz) {
+		int faulted = 0;
+
 		/* n.b - signed multiplication and division required */
 		usdiff = data - kvm->arch.last_tsc_write;
 #ifdef CONFIG_X86_64
 		usdiff = (usdiff * 1000) / vcpu->arch.virtual_tsc_khz;
 #else
 		/* do_div() only does unsigned */
-		asm("idivl %2; xor %%edx, %%edx"
-		: "=A"(usdiff)
-		: "A"(usdiff * 1000), "rm"(vcpu->arch.virtual_tsc_khz));
+		asm("1: idivl %[divisor]\n"
+		    "2: xor %%edx, %%edx\n"
+		    "   movl $0, %[faulted]\n"
+		    "3:\n"
+		    ".section .fixup,\"ax\"\n"
+		    "4: movl $1, %[faulted]\n"
+		    "   jmp  3b\n"
+		    ".previous\n"
+
+		_ASM_EXTABLE(1b, 4b)
+
+		: "=A"(usdiff), [faulted] "=r" (faulted)
+		: "A"(usdiff * 1000), [divisor] "rm"(vcpu->arch.virtual_tsc_khz));
+
 #endif
 		do_div(elapsed, 1000);
 		usdiff -= elapsed;
 		if (usdiff < 0)
 			usdiff = -usdiff;
+
+		/* idivl overflow => difference is larger than USEC_PER_SEC */
+		if (faulted)
+			usdiff = USEC_PER_SEC;
 	} else
 		usdiff = USEC_PER_SEC; /* disable TSC match window below */
 
@@ -1587,6 +1604,30 @@ static int kvm_guest_time_update(struct
 	return 0;
 }
 
+/*
+ * kvmclock updates which are isolated to a given vcpu, such as
+ * vcpu->cpu migration, should not allow system_timestamp from
+ * the rest of the vcpus to remain static. Otherwise ntp frequency
+ * correction applies to one vcpu's system_timestamp but not
+ * the others.
+ *
+ * So in those cases, request a kvmclock update for all vcpus.
+ * The worst case for a remote vcpu to update its kvmclock
+ * is then bounded by maximum nohz sleep latency.
+ */
+
+static void kvm_gen_kvmclock_update(struct kvm_vcpu *v)
+{
+	int i;
+	struct kvm *kvm = v->kvm;
+	struct kvm_vcpu *vcpu;
+
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		set_bit(KVM_REQ_CLOCK_UPDATE, &vcpu->requests);
+		kvm_vcpu_kick(vcpu);
+	}
+}
+
 static bool msr_mtrr_valid(unsigned msr)
 {
 	switch (msr) {
@@ -1984,7 +2025,7 @@ int kvm_set_msr_common(struct kvm_vcpu *
 		kvmclock_reset(vcpu);
 
 		vcpu->arch.time = data;
-		kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+		kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu);
 
 		/* we verify if the enable bit is set... */
 		if (!(data & 1))
@@ -2701,7 +2742,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu
 		 * kvmclock on vcpu->cpu migration
 		 */
 		if (!vcpu->kvm->arch.use_master_clock || vcpu->cpu == -1)
-			kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+			kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu);
 		if (vcpu->cpu != cpu)
 			kvm_migrate_timers(vcpu);
 		vcpu->cpu = cpu;
@@ -5238,7 +5279,13 @@ static void kvm_set_mmio_spte_mask(void)
 	 * Set the reserved bits and the present bit of an paging-structure
 	 * entry to generate page fault with PFER.RSV = 1.
 	 */
-	mask = ((1ull << (62 - maxphyaddr + 1)) - 1) << maxphyaddr;
+	 /* Mask the reserved physical address bits. */
+	mask = ((1ull << (51 - maxphyaddr + 1)) - 1) << maxphyaddr;
+
+	/* Bit 62 is always reserved for 32bit host. */
+	mask |= 0x3ull << 62;
+
+	/* Set the present bit. */
 	mask |= 1ull;
 
 #ifdef CONFIG_X86_64
@@ -5498,13 +5545,6 @@ static int emulator_fix_hypercall(struct
 	char instruction[3];
 	unsigned long rip = kvm_rip_read(vcpu);
 
-	/*
-	 * Blow out the MMU to ensure that no other VCPU has an active mapping
-	 * to ensure that the updated hypercall appears atomically across all
-	 * VCPUs.
-	 */
-	kvm_mmu_zap_all(vcpu->kvm);
-
 	kvm_x86_ops->patch_hypercall(vcpu, instruction);
 
 	return emulator_write_emulated(ctxt, rip, instruction, 3, NULL);
@@ -5702,6 +5742,8 @@ static int vcpu_enter_guest(struct kvm_v
 			__kvm_migrate_timers(vcpu);
 		if (kvm_check_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu))
 			kvm_gen_update_masterclock(vcpu->kvm);
+		if (kvm_check_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu))
+			kvm_gen_kvmclock_update(vcpu);
 		if (kvm_check_request(KVM_REQ_CLOCK_UPDATE, vcpu)) {
 			r = kvm_guest_time_update(vcpu);
 			if (unlikely(r))
@@ -6812,6 +6854,7 @@ int kvm_arch_init_vm(struct kvm *kvm, un
 		return -EINVAL;
 
 	INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
+	INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages);
 	INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
 
 	/* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
@@ -7040,22 +7083,18 @@ void kvm_arch_commit_memory_region(struc
 	 * If memory slot is created, or moved, we need to clear all
 	 * mmio sptes.
 	 */
-	if ((change == KVM_MR_CREATE) || (change == KVM_MR_MOVE)) {
-		kvm_mmu_zap_mmio_sptes(kvm);
-		kvm_reload_remote_mmus(kvm);
-	}
+	kvm_mmu_invalidate_mmio_sptes(kvm);
 }
 
 void kvm_arch_flush_shadow_all(struct kvm *kvm)
 {
-	kvm_mmu_zap_all(kvm);
-	kvm_reload_remote_mmus(kvm);
+	kvm_mmu_invalidate_zap_all_pages(kvm);
 }
 
 void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 				   struct kvm_memory_slot *slot)
 {
-	kvm_arch_flush_shadow_all(kvm);
+	kvm_mmu_invalidate_zap_all_pages(kvm);
 }
 
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
@@ -7263,3 +7302,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_invlpga);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_skinit);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intercepts);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_write_tsc_offset);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/lguest/boot.c linux-libre-3.11-rc7-gnu/arch/x86/lguest/boot.c
--- linux-libre-3.10-gnu/arch/x86/lguest/boot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/lguest/boot.c	2013-08-25 20:43:22.000000000 -0400
@@ -882,9 +882,9 @@ int lguest_setup_irq(unsigned int irq)
  * It would be far better for everyone if the Guest had its own clock, but
  * until then the Host gives us the time on every interrupt.
  */
-static unsigned long lguest_get_wallclock(void)
+static void lguest_get_wallclock(struct timespec *now)
 {
-	return lguest_data.time.tv_sec;
+	*now = lguest_data.time;
 }
 
 /*
@@ -1410,7 +1410,7 @@ __init void lguest_init(void)
 	new_cpu_data.x86_capability[0] = cpuid_edx(1);
 
 	/* Math is always hard! */
-	new_cpu_data.hard_math = 1;
+	set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU);
 
 	/* We don't have features.  We have puppies!  Puppies! */
 #ifdef CONFIG_X86_MCE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/lguest/head_32.S linux-libre-3.11-rc7-gnu/arch/x86/lguest/head_32.S
--- linux-libre-3.10-gnu/arch/x86/lguest/head_32.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/x86/lguest/head_32.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,196 @@
+#include <linux/linkage.h>
+#include <linux/lguest.h>
+#include <asm/lguest_hcall.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/processor-flags.h>
+
+/*G:020
+
+ * Our story starts with the bzImage: booting starts at startup_32 in
+ * arch/x86/boot/compressed/head_32.S.  This merely uncompresses the real
+ * kernel in place and then jumps into it: startup_32 in
+ * arch/x86/kernel/head_32.S.  Both routines expects a boot header in the %esi
+ * register, which is created by the bootloader (the Launcher in our case).
+ *
+ * The startup_32 function does very little: it clears the uninitialized global
+ * C variables which we expect to be zero (ie. BSS) and then copies the boot
+ * header and kernel command line somewhere safe, and populates some initial
+ * page tables.  Finally it checks the 'hardware_subarch' field.  This was
+ * introduced in 2.6.24 for lguest and Xen: if it's set to '1' (lguest's
+ * assigned number), then it calls us here.
+ *
+ * WARNING: be very careful here!  We're running at addresses equal to physical
+ * addresses (around 0), not above PAGE_OFFSET as most code expects
+ * (eg. 0xC0000000).  Jumps are relative, so they're OK, but we can't touch any
+ * data without remembering to subtract __PAGE_OFFSET!
+ *
+ * The .section line puts this code in .init.text so it will be discarded after
+ * boot.
+ */
+.section .init.text, "ax", @progbits
+ENTRY(lguest_entry)
+	/*
+	 * We make the "initialization" hypercall now to tell the Host where
+	 * our lguest_data struct is.
+	 */
+	movl $LHCALL_LGUEST_INIT, %eax
+	movl $lguest_data - __PAGE_OFFSET, %ebx
+	int $LGUEST_TRAP_ENTRY
+
+	/* Now turn our pagetables on; setup by arch/x86/kernel/head_32.S. */
+	movl $LHCALL_NEW_PGTABLE, %eax
+	movl $(initial_page_table - __PAGE_OFFSET), %ebx
+	int $LGUEST_TRAP_ENTRY
+
+	/* Set up the initial stack so we can run C code. */
+	movl $(init_thread_union+THREAD_SIZE),%esp
+
+	/* Jumps are relative: we're running __PAGE_OFFSET too low. */
+	jmp lguest_init+__PAGE_OFFSET
+
+/*G:055
+ * We create a macro which puts the assembler code between lgstart_ and lgend_
+ * markers.  These templates are put in the .text section: they can't be
+ * discarded after boot as we may need to patch modules, too.
+ */
+.text
+#define LGUEST_PATCH(name, insns...)			\
+	lgstart_##name:	insns; lgend_##name:;		\
+	.globl lgstart_##name; .globl lgend_##name
+
+LGUEST_PATCH(cli, movl $0, lguest_data+LGUEST_DATA_irq_enabled)
+LGUEST_PATCH(pushf, movl lguest_data+LGUEST_DATA_irq_enabled, %eax)
+
+/*G:033
+ * But using those wrappers is inefficient (we'll see why that doesn't matter
+ * for save_fl and irq_disable later).  If we write our routines carefully in
+ * assembler, we can avoid clobbering any registers and avoid jumping through
+ * the wrapper functions.
+ *
+ * I skipped over our first piece of assembler, but this one is worth studying
+ * in a bit more detail so I'll describe in easy stages.  First, the routine to
+ * enable interrupts:
+ */
+ENTRY(lg_irq_enable)
+	/*
+	 * The reverse of irq_disable, this sets lguest_data.irq_enabled to
+	 * X86_EFLAGS_IF (ie. "Interrupts enabled").
+	 */
+	movl $X86_EFLAGS_IF, lguest_data+LGUEST_DATA_irq_enabled
+	/*
+	 * But now we need to check if the Host wants to know: there might have
+	 * been interrupts waiting to be delivered, in which case it will have
+	 * set lguest_data.irq_pending to X86_EFLAGS_IF.  If it's not zero, we
+	 * jump to send_interrupts, otherwise we're done.
+	 */
+	testl $0, lguest_data+LGUEST_DATA_irq_pending
+	jnz send_interrupts
+	/*
+	 * One cool thing about x86 is that you can do many things without using
+	 * a register.  In this case, the normal path hasn't needed to save or
+	 * restore any registers at all!
+	 */
+	ret
+send_interrupts:
+	/*
+	 * OK, now we need a register: eax is used for the hypercall number,
+	 * which is LHCALL_SEND_INTERRUPTS.
+	 *
+	 * We used not to bother with this pending detection at all, which was
+	 * much simpler.  Sooner or later the Host would realize it had to
+	 * send us an interrupt.  But that turns out to make performance 7
+	 * times worse on a simple tcp benchmark.  So now we do this the hard
+	 * way.
+	 */
+	pushl %eax
+	movl $LHCALL_SEND_INTERRUPTS, %eax
+	/* This is the actual hypercall trap. */
+	int  $LGUEST_TRAP_ENTRY
+	/* Put eax back the way we found it. */
+	popl %eax
+	ret
+
+/*
+ * Finally, the "popf" or "restore flags" routine.  The %eax register holds the
+ * flags (in practice, either X86_EFLAGS_IF or 0): if it's X86_EFLAGS_IF we're
+ * enabling interrupts again, if it's 0 we're leaving them off.
+ */
+ENTRY(lg_restore_fl)
+	/* This is just "lguest_data.irq_enabled = flags;" */
+	movl %eax, lguest_data+LGUEST_DATA_irq_enabled
+	/*
+	 * Now, if the %eax value has enabled interrupts and
+	 * lguest_data.irq_pending is set, we want to tell the Host so it can
+	 * deliver any outstanding interrupts.  Fortunately, both values will
+	 * be X86_EFLAGS_IF (ie. 512) in that case, and the "testl"
+	 * instruction will AND them together for us.  If both are set, we
+	 * jump to send_interrupts.
+	 */
+	testl lguest_data+LGUEST_DATA_irq_pending, %eax
+	jnz send_interrupts
+	/* Again, the normal path has used no extra registers.  Clever, huh? */
+	ret
+/*:*/
+
+/* These demark the EIP range where host should never deliver interrupts. */
+.global lguest_noirq_start
+.global lguest_noirq_end
+
+/*M:004
+ * When the Host reflects a trap or injects an interrupt into the Guest, it
+ * sets the eflags interrupt bit on the stack based on lguest_data.irq_enabled,
+ * so the Guest iret logic does the right thing when restoring it.  However,
+ * when the Host sets the Guest up for direct traps, such as system calls, the
+ * processor is the one to push eflags onto the stack, and the interrupt bit
+ * will be 1 (in reality, interrupts are always enabled in the Guest).
+ *
+ * This turns out to be harmless: the only trap which should happen under Linux
+ * with interrupts disabled is Page Fault (due to our lazy mapping of vmalloc
+ * regions), which has to be reflected through the Host anyway.  If another
+ * trap *does* go off when interrupts are disabled, the Guest will panic, and
+ * we'll never get to this iret!
+:*/
+
+/*G:045
+ * There is one final paravirt_op that the Guest implements, and glancing at it
+ * you can see why I left it to last.  It's *cool*!  It's in *assembler*!
+ *
+ * The "iret" instruction is used to return from an interrupt or trap.  The
+ * stack looks like this:
+ *   old address
+ *   old code segment & privilege level
+ *   old processor flags ("eflags")
+ *
+ * The "iret" instruction pops those values off the stack and restores them all
+ * at once.  The only problem is that eflags includes the Interrupt Flag which
+ * the Guest can't change: the CPU will simply ignore it when we do an "iret".
+ * So we have to copy eflags from the stack to lguest_data.irq_enabled before
+ * we do the "iret".
+ *
+ * There are two problems with this: firstly, we need to use a register to do
+ * the copy and secondly, the whole thing needs to be atomic.  The first
+ * problem is easy to solve: push %eax on the stack so we can use it, and then
+ * restore it at the end just before the real "iret".
+ *
+ * The second is harder: copying eflags to lguest_data.irq_enabled will turn
+ * interrupts on before we're finished, so we could be interrupted before we
+ * return to userspace or wherever.  Our solution to this is to surround the
+ * code with lguest_noirq_start: and lguest_noirq_end: labels.  We tell the
+ * Host that it is *never* to interrupt us there, even if interrupts seem to be
+ * enabled.
+ */
+ENTRY(lguest_iret)
+	pushl	%eax
+	movl	12(%esp), %eax
+lguest_noirq_start:
+	/*
+	 * Note the %ss: segment prefix here.  Normal data accesses use the
+	 * "ds" segment, but that will have already been restored for whatever
+	 * we're returning to (such as userspace): we can't trust it.  The %ss:
+	 * prefix makes sure we use the stack segment, which is still valid.
+	 */
+	movl	%eax,%ss:lguest_data+LGUEST_DATA_irq_enabled
+	popl	%eax
+	iret
+lguest_noirq_end:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/lguest/i386_head.S linux-libre-3.11-rc7-gnu/arch/x86/lguest/i386_head.S
--- linux-libre-3.10-gnu/arch/x86/lguest/i386_head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/lguest/i386_head.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,196 +0,0 @@
-#include <linux/linkage.h>
-#include <linux/lguest.h>
-#include <asm/lguest_hcall.h>
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-#include <asm/processor-flags.h>
-
-/*G:020
-
- * Our story starts with the bzImage: booting starts at startup_32 in
- * arch/x86/boot/compressed/head_32.S.  This merely uncompresses the real
- * kernel in place and then jumps into it: startup_32 in
- * arch/x86/kernel/head_32.S.  Both routines expects a boot header in the %esi
- * register, which is created by the bootloader (the Launcher in our case).
- *
- * The startup_32 function does very little: it clears the uninitialized global
- * C variables which we expect to be zero (ie. BSS) and then copies the boot
- * header and kernel command line somewhere safe, and populates some initial
- * page tables.  Finally it checks the 'hardware_subarch' field.  This was
- * introduced in 2.6.24 for lguest and Xen: if it's set to '1' (lguest's
- * assigned number), then it calls us here.
- *
- * WARNING: be very careful here!  We're running at addresses equal to physical
- * addresses (around 0), not above PAGE_OFFSET as most code expects
- * (eg. 0xC0000000).  Jumps are relative, so they're OK, but we can't touch any
- * data without remembering to subtract __PAGE_OFFSET!
- *
- * The .section line puts this code in .init.text so it will be discarded after
- * boot.
- */
-.section .init.text, "ax", @progbits
-ENTRY(lguest_entry)
-	/*
-	 * We make the "initialization" hypercall now to tell the Host where
-	 * our lguest_data struct is.
-	 */
-	movl $LHCALL_LGUEST_INIT, %eax
-	movl $lguest_data - __PAGE_OFFSET, %ebx
-	int $LGUEST_TRAP_ENTRY
-
-	/* Now turn our pagetables on; setup by arch/x86/kernel/head_32.S. */
-	movl $LHCALL_NEW_PGTABLE, %eax
-	movl $(initial_page_table - __PAGE_OFFSET), %ebx
-	int $LGUEST_TRAP_ENTRY
-
-	/* Set up the initial stack so we can run C code. */
-	movl $(init_thread_union+THREAD_SIZE),%esp
-
-	/* Jumps are relative: we're running __PAGE_OFFSET too low. */
-	jmp lguest_init+__PAGE_OFFSET
-
-/*G:055
- * We create a macro which puts the assembler code between lgstart_ and lgend_
- * markers.  These templates are put in the .text section: they can't be
- * discarded after boot as we may need to patch modules, too.
- */
-.text
-#define LGUEST_PATCH(name, insns...)			\
-	lgstart_##name:	insns; lgend_##name:;		\
-	.globl lgstart_##name; .globl lgend_##name
-
-LGUEST_PATCH(cli, movl $0, lguest_data+LGUEST_DATA_irq_enabled)
-LGUEST_PATCH(pushf, movl lguest_data+LGUEST_DATA_irq_enabled, %eax)
-
-/*G:033
- * But using those wrappers is inefficient (we'll see why that doesn't matter
- * for save_fl and irq_disable later).  If we write our routines carefully in
- * assembler, we can avoid clobbering any registers and avoid jumping through
- * the wrapper functions.
- *
- * I skipped over our first piece of assembler, but this one is worth studying
- * in a bit more detail so I'll describe in easy stages.  First, the routine to
- * enable interrupts:
- */
-ENTRY(lg_irq_enable)
-	/*
-	 * The reverse of irq_disable, this sets lguest_data.irq_enabled to
-	 * X86_EFLAGS_IF (ie. "Interrupts enabled").
-	 */
-	movl $X86_EFLAGS_IF, lguest_data+LGUEST_DATA_irq_enabled
-	/*
-	 * But now we need to check if the Host wants to know: there might have
-	 * been interrupts waiting to be delivered, in which case it will have
-	 * set lguest_data.irq_pending to X86_EFLAGS_IF.  If it's not zero, we
-	 * jump to send_interrupts, otherwise we're done.
-	 */
-	testl $0, lguest_data+LGUEST_DATA_irq_pending
-	jnz send_interrupts
-	/*
-	 * One cool thing about x86 is that you can do many things without using
-	 * a register.  In this case, the normal path hasn't needed to save or
-	 * restore any registers at all!
-	 */
-	ret
-send_interrupts:
-	/*
-	 * OK, now we need a register: eax is used for the hypercall number,
-	 * which is LHCALL_SEND_INTERRUPTS.
-	 *
-	 * We used not to bother with this pending detection at all, which was
-	 * much simpler.  Sooner or later the Host would realize it had to
-	 * send us an interrupt.  But that turns out to make performance 7
-	 * times worse on a simple tcp benchmark.  So now we do this the hard
-	 * way.
-	 */
-	pushl %eax
-	movl $LHCALL_SEND_INTERRUPTS, %eax
-	/* This is the actual hypercall trap. */
-	int  $LGUEST_TRAP_ENTRY
-	/* Put eax back the way we found it. */
-	popl %eax
-	ret
-
-/*
- * Finally, the "popf" or "restore flags" routine.  The %eax register holds the
- * flags (in practice, either X86_EFLAGS_IF or 0): if it's X86_EFLAGS_IF we're
- * enabling interrupts again, if it's 0 we're leaving them off.
- */
-ENTRY(lg_restore_fl)
-	/* This is just "lguest_data.irq_enabled = flags;" */
-	movl %eax, lguest_data+LGUEST_DATA_irq_enabled
-	/*
-	 * Now, if the %eax value has enabled interrupts and
-	 * lguest_data.irq_pending is set, we want to tell the Host so it can
-	 * deliver any outstanding interrupts.  Fortunately, both values will
-	 * be X86_EFLAGS_IF (ie. 512) in that case, and the "testl"
-	 * instruction will AND them together for us.  If both are set, we
-	 * jump to send_interrupts.
-	 */
-	testl lguest_data+LGUEST_DATA_irq_pending, %eax
-	jnz send_interrupts
-	/* Again, the normal path has used no extra registers.  Clever, huh? */
-	ret
-/*:*/
-
-/* These demark the EIP range where host should never deliver interrupts. */
-.global lguest_noirq_start
-.global lguest_noirq_end
-
-/*M:004
- * When the Host reflects a trap or injects an interrupt into the Guest, it
- * sets the eflags interrupt bit on the stack based on lguest_data.irq_enabled,
- * so the Guest iret logic does the right thing when restoring it.  However,
- * when the Host sets the Guest up for direct traps, such as system calls, the
- * processor is the one to push eflags onto the stack, and the interrupt bit
- * will be 1 (in reality, interrupts are always enabled in the Guest).
- *
- * This turns out to be harmless: the only trap which should happen under Linux
- * with interrupts disabled is Page Fault (due to our lazy mapping of vmalloc
- * regions), which has to be reflected through the Host anyway.  If another
- * trap *does* go off when interrupts are disabled, the Guest will panic, and
- * we'll never get to this iret!
-:*/
-
-/*G:045
- * There is one final paravirt_op that the Guest implements, and glancing at it
- * you can see why I left it to last.  It's *cool*!  It's in *assembler*!
- *
- * The "iret" instruction is used to return from an interrupt or trap.  The
- * stack looks like this:
- *   old address
- *   old code segment & privilege level
- *   old processor flags ("eflags")
- *
- * The "iret" instruction pops those values off the stack and restores them all
- * at once.  The only problem is that eflags includes the Interrupt Flag which
- * the Guest can't change: the CPU will simply ignore it when we do an "iret".
- * So we have to copy eflags from the stack to lguest_data.irq_enabled before
- * we do the "iret".
- *
- * There are two problems with this: firstly, we need to use a register to do
- * the copy and secondly, the whole thing needs to be atomic.  The first
- * problem is easy to solve: push %eax on the stack so we can use it, and then
- * restore it at the end just before the real "iret".
- *
- * The second is harder: copying eflags to lguest_data.irq_enabled will turn
- * interrupts on before we're finished, so we could be interrupted before we
- * return to userspace or wherever.  Our solution to this is to surround the
- * code with lguest_noirq_start: and lguest_noirq_end: labels.  We tell the
- * Host that it is *never* to interrupt us there, even if interrupts seem to be
- * enabled.
- */
-ENTRY(lguest_iret)
-	pushl	%eax
-	movl	12(%esp), %eax
-lguest_noirq_start:
-	/*
-	 * Note the %ss: segment prefix here.  Normal data accesses use the
-	 * "ds" segment, but that will have already been restored for whatever
-	 * we're returning to (such as userspace): we can't trust it.  The %ss:
-	 * prefix makes sure we use the stack segment, which is still valid.
-	 */
-	movl	%eax,%ss:lguest_data+LGUEST_DATA_irq_enabled
-	popl	%eax
-	iret
-lguest_noirq_end:
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/lguest/Makefile linux-libre-3.11-rc7-gnu/arch/x86/lguest/Makefile
--- linux-libre-3.10-gnu/arch/x86/lguest/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/lguest/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,2 +1,2 @@
-obj-y		:= i386_head.o boot.o
+obj-y		:= head_32.o boot.o
 CFLAGS_boot.o	:= $(call cc-option, -fno-stack-protector)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/Makefile linux-libre-3.11-rc7-gnu/arch/x86/Makefile
--- linux-libre-3.10-gnu/arch/x86/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -220,6 +220,12 @@ archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
 	$(Q)$(MAKE) $(clean)=arch/x86/tools
 
+PHONY += kvmconfig
+kvmconfig:
+	$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target))
+	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config arch/x86/configs/kvm_guest.config
+	$(Q)yes "" | $(MAKE) oldconfig
+
 define archhelp
   echo  '* bzImage      - Compressed kernel image (arch/x86/boot/bzImage)'
   echo  '  install      - Install kernel using'
@@ -233,4 +239,5 @@ define archhelp
   echo  '                  bzdisk/fdimage*/isoimage also accept:'
   echo  '                  FDARGS="..."  arguments for the booted kernel'
   echo  '                  FDINITRD=file initrd for the booted kernel'
+  echo  '  kvmconfig	- Enable additional options for guest kernel support'
 endef
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/highmem_32.c linux-libre-3.11-rc7-gnu/arch/x86/mm/highmem_32.c
--- linux-libre-3.10-gnu/arch/x86/mm/highmem_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/highmem_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,7 @@
 #include <linux/highmem.h>
 #include <linux/module.h>
 #include <linux/swap.h> /* for totalram_pages */
+#include <linux/bootmem.h>
 
 void *kmap(struct page *page)
 {
@@ -121,6 +122,11 @@ void __init set_highmem_pages_init(void)
 	struct zone *zone;
 	int nid;
 
+	/*
+	 * Explicitly reset zone->managed_pages because set_highmem_pages_init()
+	 * is invoked before free_all_bootmem()
+	 */
+	reset_all_zones_managed_pages();
 	for_each_zone(zone) {
 		unsigned long zone_start_pfn, zone_end_pfn;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/hugetlbpage.c linux-libre-3.11-rc7-gnu/arch/x86/mm/hugetlbpage.c
--- linux-libre-3.10-gnu/arch/x86/mm/hugetlbpage.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/hugetlbpage.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,169 +16,6 @@
 #include <asm/tlbflush.h>
 #include <asm/pgalloc.h>
 
-static unsigned long page_table_shareable(struct vm_area_struct *svma,
-				struct vm_area_struct *vma,
-				unsigned long addr, pgoff_t idx)
-{
-	unsigned long saddr = ((idx - svma->vm_pgoff) << PAGE_SHIFT) +
-				svma->vm_start;
-	unsigned long sbase = saddr & PUD_MASK;
-	unsigned long s_end = sbase + PUD_SIZE;
-
-	/* Allow segments to share if only one is marked locked */
-	unsigned long vm_flags = vma->vm_flags & ~VM_LOCKED;
-	unsigned long svm_flags = svma->vm_flags & ~VM_LOCKED;
-
-	/*
-	 * match the virtual addresses, permission and the alignment of the
-	 * page table page.
-	 */
-	if (pmd_index(addr) != pmd_index(saddr) ||
-	    vm_flags != svm_flags ||
-	    sbase < svma->vm_start || svma->vm_end < s_end)
-		return 0;
-
-	return saddr;
-}
-
-static int vma_shareable(struct vm_area_struct *vma, unsigned long addr)
-{
-	unsigned long base = addr & PUD_MASK;
-	unsigned long end = base + PUD_SIZE;
-
-	/*
-	 * check on proper vm_flags and page table alignment
-	 */
-	if (vma->vm_flags & VM_MAYSHARE &&
-	    vma->vm_start <= base && end <= vma->vm_end)
-		return 1;
-	return 0;
-}
-
-/*
- * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc()
- * and returns the corresponding pte. While this is not necessary for the
- * !shared pmd case because we can allocate the pmd later as well, it makes the
- * code much cleaner. pmd allocation is essential for the shared case because
- * pud has to be populated inside the same i_mmap_mutex section - otherwise
- * racing tasks could either miss the sharing (see huge_pte_offset) or select a
- * bad pmd for sharing.
- */
-static pte_t *
-huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
-{
-	struct vm_area_struct *vma = find_vma(mm, addr);
-	struct address_space *mapping = vma->vm_file->f_mapping;
-	pgoff_t idx = ((addr - vma->vm_start) >> PAGE_SHIFT) +
-			vma->vm_pgoff;
-	struct vm_area_struct *svma;
-	unsigned long saddr;
-	pte_t *spte = NULL;
-	pte_t *pte;
-
-	if (!vma_shareable(vma, addr))
-		return (pte_t *)pmd_alloc(mm, pud, addr);
-
-	mutex_lock(&mapping->i_mmap_mutex);
-	vma_interval_tree_foreach(svma, &mapping->i_mmap, idx, idx) {
-		if (svma == vma)
-			continue;
-
-		saddr = page_table_shareable(svma, vma, addr, idx);
-		if (saddr) {
-			spte = huge_pte_offset(svma->vm_mm, saddr);
-			if (spte) {
-				get_page(virt_to_page(spte));
-				break;
-			}
-		}
-	}
-
-	if (!spte)
-		goto out;
-
-	spin_lock(&mm->page_table_lock);
-	if (pud_none(*pud))
-		pud_populate(mm, pud, (pmd_t *)((unsigned long)spte & PAGE_MASK));
-	else
-		put_page(virt_to_page(spte));
-	spin_unlock(&mm->page_table_lock);
-out:
-	pte = (pte_t *)pmd_alloc(mm, pud, addr);
-	mutex_unlock(&mapping->i_mmap_mutex);
-	return pte;
-}
-
-/*
- * unmap huge page backed by shared pte.
- *
- * Hugetlb pte page is ref counted at the time of mapping.  If pte is shared
- * indicated by page_count > 1, unmap is achieved by clearing pud and
- * decrementing the ref count. If count == 1, the pte page is not shared.
- *
- * called with vma->vm_mm->page_table_lock held.
- *
- * returns: 1 successfully unmapped a shared pte page
- *	    0 the underlying pte page is not shared, or it is the last user
- */
-int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
-{
-	pgd_t *pgd = pgd_offset(mm, *addr);
-	pud_t *pud = pud_offset(pgd, *addr);
-
-	BUG_ON(page_count(virt_to_page(ptep)) == 0);
-	if (page_count(virt_to_page(ptep)) == 1)
-		return 0;
-
-	pud_clear(pud);
-	put_page(virt_to_page(ptep));
-	*addr = ALIGN(*addr, HPAGE_SIZE * PTRS_PER_PTE) - HPAGE_SIZE;
-	return 1;
-}
-
-pte_t *huge_pte_alloc(struct mm_struct *mm,
-			unsigned long addr, unsigned long sz)
-{
-	pgd_t *pgd;
-	pud_t *pud;
-	pte_t *pte = NULL;
-
-	pgd = pgd_offset(mm, addr);
-	pud = pud_alloc(mm, pgd, addr);
-	if (pud) {
-		if (sz == PUD_SIZE) {
-			pte = (pte_t *)pud;
-		} else {
-			BUG_ON(sz != PMD_SIZE);
-			if (pud_none(*pud))
-				pte = huge_pmd_share(mm, addr, pud);
-			else
-				pte = (pte_t *)pmd_alloc(mm, pud, addr);
-		}
-	}
-	BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte));
-
-	return pte;
-}
-
-pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
-{
-	pgd_t *pgd;
-	pud_t *pud;
-	pmd_t *pmd = NULL;
-
-	pgd = pgd_offset(mm, addr);
-	if (pgd_present(*pgd)) {
-		pud = pud_offset(pgd, addr);
-		if (pud_present(*pud)) {
-			if (pud_large(*pud))
-				return (pte_t *)pud;
-			pmd = pmd_offset(pud, addr);
-		}
-	}
-	return (pte_t *) pmd;
-}
-
 #if 0	/* This is just for testing */
 struct page *
 follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
@@ -240,30 +77,6 @@ int pud_huge(pud_t pud)
 	return !!(pud_val(pud) & _PAGE_PSE);
 }
 
-struct page *
-follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-		pmd_t *pmd, int write)
-{
-	struct page *page;
-
-	page = pte_page(*(pte_t *)pmd);
-	if (page)
-		page += ((address & ~PMD_MASK) >> PAGE_SHIFT);
-	return page;
-}
-
-struct page *
-follow_huge_pud(struct mm_struct *mm, unsigned long address,
-		pud_t *pud, int write)
-{
-	struct page *page;
-
-	page = pte_page(*(pte_t *)pud);
-	if (page)
-		page += ((address & ~PUD_MASK) >> PAGE_SHIFT);
-	return page;
-}
-
 #endif
 
 /* x86_64 also uses this file */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/init_32.c linux-libre-3.11-rc7-gnu/arch/x86/mm/init_32.c
--- linux-libre-3.10-gnu/arch/x86/mm/init_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/init_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -660,10 +660,8 @@ void __init initmem_init(void)
 		highstart_pfn = max_low_pfn;
 	printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
 		pages_to_mb(highend_pfn - highstart_pfn));
-	num_physpages = highend_pfn;
 	high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
 #else
-	num_physpages = max_low_pfn;
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
 #endif
 
@@ -671,7 +669,7 @@ void __init initmem_init(void)
 	sparse_memory_present_with_active_regions(0);
 
 #ifdef CONFIG_FLATMEM
-	max_mapnr = num_physpages;
+	max_mapnr = IS_ENABLED(CONFIG_HIGHMEM) ? highend_pfn : max_low_pfn;
 #endif
 	__vmalloc_start_set = true;
 
@@ -739,9 +737,6 @@ static void __init test_wp_bit(void)
 
 void __init mem_init(void)
 {
-	int codesize, reservedpages, datasize, initsize;
-	int tmp;
-
 	pci_iommu_alloc();
 
 #ifdef CONFIG_FLATMEM
@@ -759,32 +754,11 @@ void __init mem_init(void)
 	set_highmem_pages_init();
 
 	/* this will put all low memory onto the freelists */
-	totalram_pages += free_all_bootmem();
-
-	reservedpages = 0;
-	for (tmp = 0; tmp < max_low_pfn; tmp++)
-		/*
-		 * Only count reserved RAM pages:
-		 */
-		if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
-			reservedpages++;
+	free_all_bootmem();
 
 	after_bootmem = 1;
 
-	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
-	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
-			"%dk reserved, %dk data, %dk init, %ldk highmem)\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		num_physpages << (PAGE_SHIFT-10),
-		codesize >> 10,
-		reservedpages << (PAGE_SHIFT-10),
-		datasize >> 10,
-		initsize >> 10,
-		totalhigh_pages << (PAGE_SHIFT-10));
-
+	mem_init_print_info(NULL);
 	printk(KERN_INFO "virtual kernel memory layout:\n"
 		"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
 #ifdef CONFIG_HIGHMEM
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/init_64.c linux-libre-3.11-rc7-gnu/arch/x86/mm/init_64.c
--- linux-libre-3.10-gnu/arch/x86/mm/init_64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/init_64.c	2013-08-25 20:43:22.000000000 -0400
@@ -368,7 +368,7 @@ void __init init_extra_mapping_uc(unsign
  *
  *   from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text)
  *
- * phys_addr holds the negative offset to the kernel, which is added
+ * phys_base holds the negative offset to the kernel, which is added
  * to the compile time generated pmds. This results in invalid pmds up
  * to the point where we hit the physaddr 0 mapping.
  *
@@ -712,36 +712,22 @@ EXPORT_SYMBOL_GPL(arch_add_memory);
 
 static void __meminit free_pagetable(struct page *page, int order)
 {
-	struct zone *zone;
-	bool bootmem = false;
 	unsigned long magic;
 	unsigned int nr_pages = 1 << order;
 
 	/* bootmem page has reserved flag */
 	if (PageReserved(page)) {
 		__ClearPageReserved(page);
-		bootmem = true;
 
 		magic = (unsigned long)page->lru.next;
 		if (magic == SECTION_INFO || magic == MIX_SECTION_INFO) {
 			while (nr_pages--)
 				put_page_bootmem(page++);
 		} else
-			__free_pages_bootmem(page, order);
+			while (nr_pages--)
+				free_reserved_page(page++);
 	} else
 		free_pages((unsigned long)page_address(page), order);
-
-	/*
-	 * SECTION_INFO pages and MIX_SECTION_INFO pages
-	 * are all allocated by bootmem.
-	 */
-	if (bootmem) {
-		zone = page_zone(page);
-		zone_span_writelock(zone);
-		zone->present_pages += nr_pages;
-		zone_span_writeunlock(zone);
-		totalram_pages += nr_pages;
-	}
 }
 
 static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
@@ -1058,9 +1044,6 @@ static void __init register_page_bootmem
 
 void __init mem_init(void)
 {
-	long codesize, reservedpages, datasize, initsize;
-	unsigned long absent_pages;
-
 	pci_iommu_alloc();
 
 	/* clear_bss() already clear the empty_zero_page */
@@ -1068,29 +1051,14 @@ void __init mem_init(void)
 	register_page_bootmem_info();
 
 	/* this will put all memory onto the freelists */
-	totalram_pages = free_all_bootmem();
-
-	absent_pages = absent_pages_in_range(0, max_pfn);
-	reservedpages = max_pfn - totalram_pages - absent_pages;
+	free_all_bootmem();
 	after_bootmem = 1;
 
-	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
-	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
-
 	/* Register memory areas for /proc/kcore */
 	kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START,
 			 VSYSCALL_END - VSYSCALL_START, KCORE_OTHER);
 
-	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
-			 "%ldk absent, %ldk reserved, %ldk data, %ldk init)\n",
-		nr_free_pages() << (PAGE_SHIFT-10),
-		max_pfn << (PAGE_SHIFT-10),
-		codesize >> 10,
-		absent_pages << (PAGE_SHIFT-10),
-		reservedpages << (PAGE_SHIFT-10),
-		datasize >> 10,
-		initsize >> 10);
+	mem_init_print_info(NULL);
 }
 
 #ifdef CONFIG_DEBUG_RODATA
@@ -1166,11 +1134,10 @@ void mark_rodata_ro(void)
 	set_memory_ro(start, (end-start) >> PAGE_SHIFT);
 #endif
 
-	free_init_pages("unused kernel memory",
+	free_init_pages("unused kernel",
 			(unsigned long) __va(__pa_symbol(text_end)),
 			(unsigned long) __va(__pa_symbol(rodata_start)));
-
-	free_init_pages("unused kernel memory",
+	free_init_pages("unused kernel",
 			(unsigned long) __va(__pa_symbol(rodata_end)),
 			(unsigned long) __va(__pa_symbol(_sdata)));
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/init.c linux-libre-3.11-rc7-gnu/arch/x86/mm/init.c
--- linux-libre-3.10-gnu/arch/x86/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -494,7 +494,6 @@ int devmem_is_allowed(unsigned long page
 
 void free_init_pages(char *what, unsigned long begin, unsigned long end)
 {
-	unsigned long addr;
 	unsigned long begin_aligned, end_aligned;
 
 	/* Make sure boundaries are page aligned */
@@ -509,8 +508,6 @@ void free_init_pages(char *what, unsigne
 	if (begin >= end)
 		return;
 
-	addr = begin;
-
 	/*
 	 * If debugging page accesses then do not free this memory but
 	 * mark them not present - any buggy init-section access will
@@ -529,18 +526,13 @@ void free_init_pages(char *what, unsigne
 	set_memory_nx(begin, (end - begin) >> PAGE_SHIFT);
 	set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
 
-	printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
-
-	for (; addr < end; addr += PAGE_SIZE) {
-		memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
-		free_reserved_page(virt_to_page(addr));
-	}
+	free_reserved_area((void *)begin, (void *)end, POISON_FREE_INITMEM, what);
 #endif
 }
 
 void free_initmem(void)
 {
-	free_init_pages("unused kernel memory",
+	free_init_pages("unused kernel",
 			(unsigned long)(&__init_begin),
 			(unsigned long)(&__init_end));
 }
@@ -566,7 +558,7 @@ void __init free_initrd_mem(unsigned lon
 	 *   - relocate_initrd()
 	 * So here We can do PAGE_ALIGN() safely to get partial page to be freed
 	 */
-	free_init_pages("initrd memory", start, PAGE_ALIGN(end));
+	free_init_pages("initrd", start, PAGE_ALIGN(end));
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/ioremap.c linux-libre-3.11-rc7-gnu/arch/x86/mm/ioremap.c
--- linux-libre-3.10-gnu/arch/x86/mm/ioremap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/ioremap.c	2013-08-25 20:43:22.000000000 -0400
@@ -501,15 +501,15 @@ __early_ioremap(resource_size_t phys_add
 	}
 
 	if (slot < 0) {
-		printk(KERN_INFO "early_iomap(%08llx, %08lx) not found slot\n",
-			 (u64)phys_addr, size);
+		printk(KERN_INFO "%s(%08llx, %08lx) not found slot\n",
+		       __func__, (u64)phys_addr, size);
 		WARN_ON(1);
 		return NULL;
 	}
 
 	if (early_ioremap_debug) {
-		printk(KERN_INFO "early_ioremap(%08llx, %08lx) [%d] => ",
-		       (u64)phys_addr, size, slot);
+		printk(KERN_INFO "%s(%08llx, %08lx) [%d] => ",
+		       __func__, (u64)phys_addr, size, slot);
 		dump_stack();
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/mmap.c linux-libre-3.11-rc7-gnu/arch/x86/mm/mmap.c
--- linux-libre-3.10-gnu/arch/x86/mm/mmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/mmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -112,13 +112,13 @@ static unsigned long mmap_legacy_base(vo
  */
 void arch_pick_mmap_layout(struct mm_struct *mm)
 {
+	mm->mmap_legacy_base = mmap_legacy_base();
+	mm->mmap_base = mmap_base();
+
 	if (mmap_is_legacy()) {
-		mm->mmap_base = mmap_legacy_base();
+		mm->mmap_base = mm->mmap_legacy_base;
 		mm->get_unmapped_area = arch_get_unmapped_area;
-		mm->unmap_area = arch_unmap_area;
 	} else {
-		mm->mmap_base = mmap_base();
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-		mm->unmap_area = arch_unmap_area_topdown;
 	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/mmio-mod.c linux-libre-3.11-rc7-gnu/arch/x86/mm/mmio-mod.c
--- linux-libre-3.10-gnu/arch/x86/mm/mmio-mod.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/mmio-mod.c	2013-08-25 20:43:22.000000000 -0400
@@ -410,9 +410,7 @@ out:
 		pr_warning("multiple CPUs still online, may miss events.\n");
 }
 
-/* __ref because leave_uniprocessor calls cpu_up which is __cpuinit,
-   but this whole function is ifdefed CONFIG_HOTPLUG_CPU */
-static void __ref leave_uniprocessor(void)
+static void leave_uniprocessor(void)
 {
 	int cpu;
 	int err;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/numa_32.c linux-libre-3.11-rc7-gnu/arch/x86/mm/numa_32.c
--- linux-libre-3.10-gnu/arch/x86/mm/numa_32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/numa_32.c	2013-08-25 20:43:22.000000000 -0400
@@ -83,10 +83,8 @@ void __init initmem_init(void)
 		highstart_pfn = max_low_pfn;
 	printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
 	       pages_to_mb(highend_pfn - highstart_pfn));
-	num_physpages = highend_pfn;
 	high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
 #else
-	num_physpages = max_low_pfn;
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
 #endif
 	printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/numa.c linux-libre-3.11-rc7-gnu/arch/x86/mm/numa.c
--- linux-libre-3.10-gnu/arch/x86/mm/numa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/numa.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,7 +60,7 @@ s16 __apicid_to_node[MAX_LOCAL_APIC] = {
 	[0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
 };
 
-int __cpuinit numa_cpu_node(int cpu)
+int numa_cpu_node(int cpu)
 {
 	int apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
 
@@ -691,12 +691,12 @@ void __init init_cpu_to_node(void)
 #ifndef CONFIG_DEBUG_PER_CPU_MAPS
 
 # ifndef CONFIG_NUMA_EMU
-void __cpuinit numa_add_cpu(int cpu)
+void numa_add_cpu(int cpu)
 {
 	cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
 }
 
-void __cpuinit numa_remove_cpu(int cpu)
+void numa_remove_cpu(int cpu)
 {
 	cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
 }
@@ -763,17 +763,17 @@ void debug_cpumask_set_cpu(int cpu, int
 }
 
 # ifndef CONFIG_NUMA_EMU
-static void __cpuinit numa_set_cpumask(int cpu, bool enable)
+static void numa_set_cpumask(int cpu, bool enable)
 {
 	debug_cpumask_set_cpu(cpu, early_cpu_to_node(cpu), enable);
 }
 
-void __cpuinit numa_add_cpu(int cpu)
+void numa_add_cpu(int cpu)
 {
 	numa_set_cpumask(cpu, true);
 }
 
-void __cpuinit numa_remove_cpu(int cpu)
+void numa_remove_cpu(int cpu)
 {
 	numa_set_cpumask(cpu, false);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/numa_emulation.c linux-libre-3.11-rc7-gnu/arch/x86/mm/numa_emulation.c
--- linux-libre-3.10-gnu/arch/x86/mm/numa_emulation.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/numa_emulation.c	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@
 
 #include "numa_internal.h"
 
-static int emu_nid_to_phys[MAX_NUMNODES] __cpuinitdata;
+static int emu_nid_to_phys[MAX_NUMNODES];
 static char *emu_cmdline __initdata;
 
 void __init numa_emu_cmdline(char *str)
@@ -444,7 +444,7 @@ no_emu:
 }
 
 #ifndef CONFIG_DEBUG_PER_CPU_MAPS
-void __cpuinit numa_add_cpu(int cpu)
+void numa_add_cpu(int cpu)
 {
 	int physnid, nid;
 
@@ -462,7 +462,7 @@ void __cpuinit numa_add_cpu(int cpu)
 			cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
 }
 
-void __cpuinit numa_remove_cpu(int cpu)
+void numa_remove_cpu(int cpu)
 {
 	int i;
 
@@ -470,7 +470,7 @@ void __cpuinit numa_remove_cpu(int cpu)
 		cpumask_clear_cpu(cpu, node_to_cpumask_map[i]);
 }
 #else	/* !CONFIG_DEBUG_PER_CPU_MAPS */
-static void __cpuinit numa_set_cpumask(int cpu, bool enable)
+static void numa_set_cpumask(int cpu, bool enable)
 {
 	int nid, physnid;
 
@@ -490,12 +490,12 @@ static void __cpuinit numa_set_cpumask(i
 	}
 }
 
-void __cpuinit numa_add_cpu(int cpu)
+void numa_add_cpu(int cpu)
 {
 	numa_set_cpumask(cpu, true);
 }
 
-void __cpuinit numa_remove_cpu(int cpu)
+void numa_remove_cpu(int cpu)
 {
 	numa_set_cpumask(cpu, false);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/pgtable.c linux-libre-3.11-rc7-gnu/arch/x86/mm/pgtable.c
--- linux-libre-3.10-gnu/arch/x86/mm/pgtable.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/pgtable.c	2013-08-25 20:43:22.000000000 -0400
@@ -240,7 +240,6 @@ static void pgd_mop_up_pmds(struct mm_st
 static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
 {
 	pud_t *pud;
-	unsigned long addr;
 	int i;
 
 	if (PREALLOCATED_PMDS == 0) /* Work around gcc-3.4.x bug */
@@ -248,8 +247,7 @@ static void pgd_prepopulate_pmd(struct m
 
 	pud = pud_offset(pgd, 0);
 
- 	for (addr = i = 0; i < PREALLOCATED_PMDS;
-	     i++, pud++, addr += PUD_SIZE) {
+	for (i = 0; i < PREALLOCATED_PMDS; i++, pud++) {
 		pmd_t *pmd = pmds[i];
 
 		if (i >= KERNEL_PGD_BOUNDARY)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/mm/setup_nx.c linux-libre-3.11-rc7-gnu/arch/x86/mm/setup_nx.c
--- linux-libre-3.10-gnu/arch/x86/mm/setup_nx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/mm/setup_nx.c	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,7 @@
 #include <asm/pgtable.h>
 #include <asm/proto.h>
 
-static int disable_nx __cpuinitdata;
+static int disable_nx;
 
 /*
  * noexec = on|off
@@ -29,7 +29,7 @@ static int __init noexec_setup(char *str
 }
 early_param("noexec", noexec_setup);
 
-void __cpuinit x86_configure_nx(void)
+void x86_configure_nx(void)
 {
 	if (cpu_has_nx && !disable_nx)
 		__supported_pte_mask |= _PAGE_NX;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/net/bpf_jit_comp.c linux-libre-3.11-rc7-gnu/arch/x86/net/bpf_jit_comp.c
--- linux-libre-3.10-gnu/arch/x86/net/bpf_jit_comp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/net/bpf_jit_comp.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/netdevice.h>
 #include <linux/filter.h>
 #include <linux/if_vlan.h>
+#include <linux/random.h>
 
 /*
  * Conventions :
@@ -144,6 +145,39 @@ static int pkt_type_offset(void)
 	return -1;
 }
 
+struct bpf_binary_header {
+	unsigned int	pages;
+	/* Note : for security reasons, bpf code will follow a randomly
+	 * sized amount of int3 instructions
+	 */
+	u8		image[];
+};
+
+static struct bpf_binary_header *bpf_alloc_binary(unsigned int proglen,
+						  u8 **image_ptr)
+{
+	unsigned int sz, hole;
+	struct bpf_binary_header *header;
+
+	/* Most of BPF filters are really small,
+	 * but if some of them fill a page, allow at least
+	 * 128 extra bytes to insert a random section of int3
+	 */
+	sz = round_up(proglen + sizeof(*header) + 128, PAGE_SIZE);
+	header = module_alloc(sz);
+	if (!header)
+		return NULL;
+
+	memset(header, 0xcc, sz); /* fill whole space with int3 instructions */
+
+	header->pages = sz / PAGE_SIZE;
+	hole = sz - (proglen + sizeof(*header));
+
+	/* insert a random number of int3 instructions before BPF code */
+	*image_ptr = &header->image[prandom_u32() % hole];
+	return header;
+}
+
 void bpf_jit_compile(struct sk_filter *fp)
 {
 	u8 temp[64];
@@ -153,6 +187,7 @@ void bpf_jit_compile(struct sk_filter *f
 	int t_offset, f_offset;
 	u8 t_op, f_op, seen = 0, pass;
 	u8 *image = NULL;
+	struct bpf_binary_header *header = NULL;
 	u8 *func;
 	int pc_ret0 = -1; /* bpf index of first RET #0 instruction (if any) */
 	unsigned int cleanup_addr; /* epilogue code offset */
@@ -693,7 +728,7 @@ cond_branch:			f_offset = addrs[i + filt
 				if (unlikely(proglen + ilen > oldproglen)) {
 					pr_err("bpb_jit_compile fatal error\n");
 					kfree(addrs);
-					module_free(NULL, image);
+					module_free(NULL, header);
 					return;
 				}
 				memcpy(image + proglen, temp, ilen);
@@ -717,10 +752,8 @@ cond_branch:			f_offset = addrs[i + filt
 			break;
 		}
 		if (proglen == oldproglen) {
-			image = module_alloc(max_t(unsigned int,
-						   proglen,
-						   sizeof(struct work_struct)));
-			if (!image)
+			header = bpf_alloc_binary(proglen, &image);
+			if (!header)
 				goto out;
 		}
 		oldproglen = proglen;
@@ -730,7 +763,8 @@ cond_branch:			f_offset = addrs[i + filt
 		bpf_jit_dump(flen, proglen, pass, image);
 
 	if (image) {
-		bpf_flush_icache(image, image + proglen);
+		bpf_flush_icache(header, image + proglen);
+		set_memory_ro((unsigned long)header, header->pages);
 		fp->bpf_func = (void *)image;
 	}
 out:
@@ -738,20 +772,13 @@ out:
 	return;
 }
 
-static void jit_free_defer(struct work_struct *arg)
-{
-	module_free(NULL, arg);
-}
-
-/* run from softirq, we must use a work_struct to call
- * module_free() from process context
- */
 void bpf_jit_free(struct sk_filter *fp)
 {
 	if (fp->bpf_func != sk_run_filter) {
-		struct work_struct *work = (struct work_struct *)fp->bpf_func;
+		unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK;
+		struct bpf_binary_header *header = (void *)addr;
 
-		INIT_WORK(work, jit_free_defer);
-		schedule_work(work);
+		set_memory_rw(addr, header->pages);
+		module_free(NULL, header);
 	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/pci/acpi.c linux-libre-3.11-rc7-gnu/arch/x86/pci/acpi.c
--- linux-libre-3.10-gnu/arch/x86/pci/acpi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/pci/acpi.c	2013-08-25 20:43:22.000000000 -0400
@@ -324,14 +324,11 @@ setup_resource(struct acpi_resource *acp
 	res->start = start;
 	res->end = end;
 	info->res_offset[info->res_num] = addr.translation_offset;
+	info->res_num++;
 
-	if (!pci_use_crs) {
+	if (!pci_use_crs)
 		dev_printk(KERN_DEBUG, &info->bridge->dev,
 			   "host bridge window %pR (ignored)\n", res);
-		return AE_OK;
-	}
-
-	info->res_num++;
 
 	return AE_OK;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/pci/amd_bus.c linux-libre-3.11-rc7-gnu/arch/x86/pci/amd_bus.c
--- linux-libre-3.10-gnu/arch/x86/pci/amd_bus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/pci/amd_bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -312,7 +312,7 @@ static int __init early_fill_mp_bus_info
 
 #define ENABLE_CF8_EXT_CFG      (1ULL << 46)
 
-static void __cpuinit enable_pci_io_ecs(void *unused)
+static void enable_pci_io_ecs(void *unused)
 {
 	u64 reg;
 	rdmsrl(MSR_AMD64_NB_CFG, reg);
@@ -322,8 +322,8 @@ static void __cpuinit enable_pci_io_ecs(
 	}
 }
 
-static int __cpuinit amd_cpu_notify(struct notifier_block *self,
-				    unsigned long action, void *hcpu)
+static int amd_cpu_notify(struct notifier_block *self, unsigned long action,
+			  void *hcpu)
 {
 	int cpu = (long)hcpu;
 	switch (action) {
@@ -337,7 +337,7 @@ static int __cpuinit amd_cpu_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata amd_cpu_notifier = {
+static struct notifier_block amd_cpu_notifier = {
 	.notifier_call	= amd_cpu_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/platform/ce4100/ce4100.c linux-libre-3.11-rc7-gnu/arch/x86/platform/ce4100/ce4100.c
--- linux-libre-3.10-gnu/arch/x86/platform/ce4100/ce4100.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/platform/ce4100/ce4100.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,8 +12,10 @@
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/reboot.h>
 #include <linux/serial_reg.h>
 #include <linux/serial_8250.h>
+#include <linux/reboot.h>
 
 #include <asm/ce4100.h>
 #include <asm/prom.h>
@@ -134,7 +136,7 @@ static void __init sdv_arch_setup(void)
 }
 
 #ifdef CONFIG_X86_IO_APIC
-static void __cpuinit sdv_pci_init(void)
+static void sdv_pci_init(void)
 {
 	x86_of_pci_init();
 	/* We can't set this earlier, because we need to calibrate the timer */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/platform/efi/efi.c linux-libre-3.11-rc7-gnu/arch/x86/platform/efi/efi.c
--- linux-libre-3.10-gnu/arch/x86/platform/efi/efi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/platform/efi/efi.c	2013-08-25 20:43:22.000000000 -0400
@@ -274,8 +274,9 @@ static efi_status_t __init phys_efi_get_
 	return status;
 }
 
-int efi_set_rtc_mmss(unsigned long nowtime)
+int efi_set_rtc_mmss(const struct timespec *now)
 {
+	unsigned long nowtime = now->tv_sec;
 	efi_status_t 	status;
 	efi_time_t 	eft;
 	efi_time_cap_t 	cap;
@@ -310,7 +311,7 @@ int efi_set_rtc_mmss(unsigned long nowti
 	return 0;
 }
 
-unsigned long efi_get_time(void)
+void efi_get_time(struct timespec *now)
 {
 	efi_status_t status;
 	efi_time_t eft;
@@ -320,8 +321,9 @@ unsigned long efi_get_time(void)
 	if (status != EFI_SUCCESS)
 		pr_err("Oops: efitime: can't read time!\n");
 
-	return mktime(eft.year, eft.month, eft.day, eft.hour,
-		      eft.minute, eft.second);
+	now->tv_sec = mktime(eft.year, eft.month, eft.day, eft.hour,
+			     eft.minute, eft.second);
+	now->tv_nsec = 0;
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/platform/mrst/mrst.c linux-libre-3.11-rc7-gnu/arch/x86/platform/mrst/mrst.c
--- linux-libre-3.10-gnu/arch/x86/platform/mrst/mrst.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/platform/mrst/mrst.c	2013-08-25 20:43:22.000000000 -0400
@@ -65,7 +65,7 @@
  * lapic (always-on,ARAT) ------ 150
  */
 
-__cpuinitdata enum mrst_timer_options mrst_timer_options;
+enum mrst_timer_options mrst_timer_options;
 
 static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
 static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
@@ -248,7 +248,7 @@ static void __init mrst_time_init(void)
 	apbt_time_init();
 }
 
-static void __cpuinit mrst_arch_setup(void)
+static void mrst_arch_setup(void)
 {
 	if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x27)
 		__mrst_cpu_chip = MRST_CPU_CHIP_PENWELL;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/platform/mrst/vrtc.c linux-libre-3.11-rc7-gnu/arch/x86/platform/mrst/vrtc.c
--- linux-libre-3.10-gnu/arch/x86/platform/mrst/vrtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/platform/mrst/vrtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,7 +56,7 @@ void vrtc_cmos_write(unsigned char val,
 }
 EXPORT_SYMBOL_GPL(vrtc_cmos_write);
 
-unsigned long vrtc_get_time(void)
+void vrtc_get_time(struct timespec *now)
 {
 	u8 sec, min, hour, mday, mon;
 	unsigned long flags;
@@ -82,17 +82,18 @@ unsigned long vrtc_get_time(void)
 	printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d "
 		"mon: %d year: %d\n", sec, min, hour, mday, mon, year);
 
-	return mktime(year, mon, mday, hour, min, sec);
+	now->tv_sec = mktime(year, mon, mday, hour, min, sec);
+	now->tv_nsec = 0;
 }
 
-int vrtc_set_mmss(unsigned long nowtime)
+int vrtc_set_mmss(const struct timespec *now)
 {
 	unsigned long flags;
 	struct rtc_time tm;
 	int year;
 	int retval = 0;
 
-	rtc_time_to_tm(nowtime, &tm);
+	rtc_time_to_tm(now->tv_sec, &tm);
 	if (!rtc_valid_tm(&tm) && tm.tm_year >= 72) {
 		/*
 		 * tm.year is the number of years since 1900, and the
@@ -110,7 +111,7 @@ int vrtc_set_mmss(unsigned long nowtime)
 	} else {
 		printk(KERN_ERR
 		       "%s: Invalid vRTC value: write of %lx to vRTC failed\n",
-			__FUNCTION__, nowtime);
+			__FUNCTION__, now->tv_sec);
 		retval = -EINVAL;
 	}
 	return retval;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/um/signal.c linux-libre-3.11-rc7-gnu/arch/x86/um/signal.c
--- linux-libre-3.10-gnu/arch/x86/um/signal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/um/signal.c	2013-08-25 20:43:22.000000000 -0400
@@ -508,7 +508,6 @@ int setup_signal_stack_si(unsigned long
 {
 	struct rt_sigframe __user *frame;
 	int err = 0;
-	struct task_struct *me = current;
 
 	frame = (struct rt_sigframe __user *)
 		round_down(stack_top - sizeof(struct rt_sigframe), 16);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/vdso/vdso32-setup.c linux-libre-3.11-rc7-gnu/arch/x86/vdso/vdso32-setup.c
--- linux-libre-3.10-gnu/arch/x86/vdso/vdso32-setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/vdso/vdso32-setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -372,7 +372,7 @@ subsys_initcall(sysenter_setup);
 /* Register vsyscall32 into the ABI table */
 #include <linux/sysctl.h>
 
-static ctl_table abi_table2[] = {
+static struct ctl_table abi_table2[] = {
 	{
 		.procname	= "vsyscall32",
 		.data		= &sysctl_vsyscall32,
@@ -383,7 +383,7 @@ static ctl_table abi_table2[] = {
 	{}
 };
 
-static ctl_table abi_root_table2[] = {
+static struct ctl_table abi_root_table2[] = {
 	{
 		.procname = "abi",
 		.mode = 0555,
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/xen/enlighten.c linux-libre-3.11-rc7-gnu/arch/x86/xen/enlighten.c
--- linux-libre-3.10-gnu/arch/x86/xen/enlighten.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/xen/enlighten.c	2013-08-25 20:43:22.000000000 -0400
@@ -1557,7 +1557,7 @@ asmlinkage void __init xen_start_kernel(
 #ifdef CONFIG_X86_32
 	/* set up basic CPUID stuff */
 	cpu_detect(&new_cpu_data);
-	new_cpu_data.hard_math = 1;
+	set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU);
 	new_cpu_data.wp_works_ok = 1;
 	new_cpu_data.x86_capability[0] = cpuid_edx(1);
 #endif
@@ -1681,8 +1681,8 @@ static void __init init_hvm_pv_info(void
 	xen_domain_type = XEN_HVM_DOMAIN;
 }
 
-static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
-				    unsigned long action, void *hcpu)
+static int xen_hvm_cpu_notify(struct notifier_block *self, unsigned long action,
+			      void *hcpu)
 {
 	int cpu = (long)hcpu;
 	switch (action) {
@@ -1700,7 +1700,7 @@ static int __cpuinit xen_hvm_cpu_notify(
 	return NOTIFY_OK;
 }
 
-static struct notifier_block xen_hvm_cpu_notifier __cpuinitdata = {
+static struct notifier_block xen_hvm_cpu_notifier = {
 	.notifier_call	= xen_hvm_cpu_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/xen/setup.c linux-libre-3.11-rc7-gnu/arch/x86/xen/setup.c
--- linux-libre-3.10-gnu/arch/x86/xen/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/xen/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -313,6 +313,17 @@ static void xen_align_and_add_e820_regio
 	e820_add_region(start, end - start, type);
 }
 
+void xen_ignore_unusable(struct e820entry *list, size_t map_size)
+{
+	struct e820entry *entry;
+	unsigned int i;
+
+	for (i = 0, entry = list; i < map_size; i++, entry++) {
+		if (entry->type == E820_UNUSABLE)
+			entry->type = E820_RAM;
+	}
+}
+
 /**
  * machine_specific_memory_setup - Hook for machine specific memory setup.
  **/
@@ -353,6 +364,17 @@ char * __init xen_memory_setup(void)
 	}
 	BUG_ON(rc);
 
+	/*
+	 * Xen won't allow a 1:1 mapping to be created to UNUSABLE
+	 * regions, so if we're using the machine memory map leave the
+	 * region as RAM as it is in the pseudo-physical map.
+	 *
+	 * UNUSABLE regions in domUs are not handled and will need
+	 * a patch in the future.
+	 */
+	if (xen_initial_domain())
+		xen_ignore_unusable(map, memmap.nr_entries);
+
 	/* Make sure the Xen-supplied memory map is well-ordered. */
 	sanitize_e820_map(map, memmap.nr_entries, &memmap.nr_entries);
 
@@ -475,7 +497,7 @@ static void __init fiddle_vdso(void)
 #endif
 }
 
-static int __cpuinit register_callback(unsigned type, const void *func)
+static int register_callback(unsigned type, const void *func)
 {
 	struct callback_register callback = {
 		.type = type,
@@ -486,7 +508,7 @@ static int __cpuinit register_callback(u
 	return HYPERVISOR_callback_op(CALLBACKOP_register, &callback);
 }
 
-void __cpuinit xen_enable_sysenter(void)
+void xen_enable_sysenter(void)
 {
 	int ret;
 	unsigned sysenter_feature;
@@ -505,7 +527,7 @@ void __cpuinit xen_enable_sysenter(void)
 		setup_clear_cpu_cap(sysenter_feature);
 }
 
-void __cpuinit xen_enable_syscall(void)
+void xen_enable_syscall(void)
 {
 #ifdef CONFIG_X86_64
 	int ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/xen/smp.c linux-libre-3.11-rc7-gnu/arch/x86/xen/smp.c
--- linux-libre-3.10-gnu/arch/x86/xen/smp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/xen/smp.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,11 +40,15 @@
 
 cpumask_var_t xen_cpu_initialized_map;
 
-static DEFINE_PER_CPU(int, xen_resched_irq);
-static DEFINE_PER_CPU(int, xen_callfunc_irq);
-static DEFINE_PER_CPU(int, xen_callfuncsingle_irq);
-static DEFINE_PER_CPU(int, xen_irq_work);
-static DEFINE_PER_CPU(int, xen_debug_irq) = -1;
+struct xen_common_irq {
+	int irq;
+	char *name;
+};
+static DEFINE_PER_CPU(struct xen_common_irq, xen_resched_irq) = { .irq = -1 };
+static DEFINE_PER_CPU(struct xen_common_irq, xen_callfunc_irq) = { .irq = -1 };
+static DEFINE_PER_CPU(struct xen_common_irq, xen_callfuncsingle_irq) = { .irq = -1 };
+static DEFINE_PER_CPU(struct xen_common_irq, xen_irq_work) = { .irq = -1 };
+static DEFINE_PER_CPU(struct xen_common_irq, xen_debug_irq) = { .irq = -1 };
 
 static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id);
 static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id);
@@ -61,7 +65,7 @@ static irqreturn_t xen_reschedule_interr
 	return IRQ_HANDLED;
 }
 
-static void __cpuinit cpu_bringup(void)
+static void cpu_bringup(void)
 {
 	int cpu;
 
@@ -93,16 +97,53 @@ static void __cpuinit cpu_bringup(void)
 	wmb();			/* make sure everything is out */
 }
 
-static void __cpuinit cpu_bringup_and_idle(void)
+static void cpu_bringup_and_idle(void)
 {
 	cpu_bringup();
 	cpu_startup_entry(CPUHP_ONLINE);
 }
 
+static void xen_smp_intr_free(unsigned int cpu)
+{
+	if (per_cpu(xen_resched_irq, cpu).irq >= 0) {
+		unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu).irq, NULL);
+		per_cpu(xen_resched_irq, cpu).irq = -1;
+		kfree(per_cpu(xen_resched_irq, cpu).name);
+		per_cpu(xen_resched_irq, cpu).name = NULL;
+	}
+	if (per_cpu(xen_callfunc_irq, cpu).irq >= 0) {
+		unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu).irq, NULL);
+		per_cpu(xen_callfunc_irq, cpu).irq = -1;
+		kfree(per_cpu(xen_callfunc_irq, cpu).name);
+		per_cpu(xen_callfunc_irq, cpu).name = NULL;
+	}
+	if (per_cpu(xen_debug_irq, cpu).irq >= 0) {
+		unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu).irq, NULL);
+		per_cpu(xen_debug_irq, cpu).irq = -1;
+		kfree(per_cpu(xen_debug_irq, cpu).name);
+		per_cpu(xen_debug_irq, cpu).name = NULL;
+	}
+	if (per_cpu(xen_callfuncsingle_irq, cpu).irq >= 0) {
+		unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu).irq,
+				       NULL);
+		per_cpu(xen_callfuncsingle_irq, cpu).irq = -1;
+		kfree(per_cpu(xen_callfuncsingle_irq, cpu).name);
+		per_cpu(xen_callfuncsingle_irq, cpu).name = NULL;
+	}
+	if (xen_hvm_domain())
+		return;
+
+	if (per_cpu(xen_irq_work, cpu).irq >= 0) {
+		unbind_from_irqhandler(per_cpu(xen_irq_work, cpu).irq, NULL);
+		per_cpu(xen_irq_work, cpu).irq = -1;
+		kfree(per_cpu(xen_irq_work, cpu).name);
+		per_cpu(xen_irq_work, cpu).name = NULL;
+	}
+};
 static int xen_smp_intr_init(unsigned int cpu)
 {
 	int rc;
-	const char *resched_name, *callfunc_name, *debug_name;
+	char *resched_name, *callfunc_name, *debug_name;
 
 	resched_name = kasprintf(GFP_KERNEL, "resched%d", cpu);
 	rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR,
@@ -113,7 +154,8 @@ static int xen_smp_intr_init(unsigned in
 				    NULL);
 	if (rc < 0)
 		goto fail;
-	per_cpu(xen_resched_irq, cpu) = rc;
+	per_cpu(xen_resched_irq, cpu).irq = rc;
+	per_cpu(xen_resched_irq, cpu).name = resched_name;
 
 	callfunc_name = kasprintf(GFP_KERNEL, "callfunc%d", cpu);
 	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR,
@@ -124,7 +166,8 @@ static int xen_smp_intr_init(unsigned in
 				    NULL);
 	if (rc < 0)
 		goto fail;
-	per_cpu(xen_callfunc_irq, cpu) = rc;
+	per_cpu(xen_callfunc_irq, cpu).irq = rc;
+	per_cpu(xen_callfunc_irq, cpu).name = callfunc_name;
 
 	debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu);
 	rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu, xen_debug_interrupt,
@@ -132,7 +175,8 @@ static int xen_smp_intr_init(unsigned in
 				     debug_name, NULL);
 	if (rc < 0)
 		goto fail;
-	per_cpu(xen_debug_irq, cpu) = rc;
+	per_cpu(xen_debug_irq, cpu).irq = rc;
+	per_cpu(xen_debug_irq, cpu).name = debug_name;
 
 	callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu);
 	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR,
@@ -143,7 +187,8 @@ static int xen_smp_intr_init(unsigned in
 				    NULL);
 	if (rc < 0)
 		goto fail;
-	per_cpu(xen_callfuncsingle_irq, cpu) = rc;
+	per_cpu(xen_callfuncsingle_irq, cpu).irq = rc;
+	per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name;
 
 	/*
 	 * The IRQ worker on PVHVM goes through the native path and uses the
@@ -161,26 +206,13 @@ static int xen_smp_intr_init(unsigned in
 				    NULL);
 	if (rc < 0)
 		goto fail;
-	per_cpu(xen_irq_work, cpu) = rc;
+	per_cpu(xen_irq_work, cpu).irq = rc;
+	per_cpu(xen_irq_work, cpu).name = callfunc_name;
 
 	return 0;
 
  fail:
-	if (per_cpu(xen_resched_irq, cpu) >= 0)
-		unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu), NULL);
-	if (per_cpu(xen_callfunc_irq, cpu) >= 0)
-		unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL);
-	if (per_cpu(xen_debug_irq, cpu) >= 0)
-		unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL);
-	if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0)
-		unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu),
-				       NULL);
-	if (xen_hvm_domain())
-		return rc;
-
-	if (per_cpu(xen_irq_work, cpu) >= 0)
-		unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
-
+	xen_smp_intr_free(cpu);
 	return rc;
 }
 
@@ -294,7 +326,7 @@ static void __init xen_smp_prepare_cpus(
 		set_cpu_present(cpu, true);
 }
 
-static int __cpuinit
+static int
 cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 {
 	struct vcpu_guest_context *ctxt;
@@ -365,7 +397,7 @@ cpu_initialize_context(unsigned int cpu,
 	return 0;
 }
 
-static int __cpuinit xen_cpu_up(unsigned int cpu, struct task_struct *idle)
+static int xen_cpu_up(unsigned int cpu, struct task_struct *idle)
 {
 	int rc;
 
@@ -433,17 +465,12 @@ static void xen_cpu_die(unsigned int cpu
 		current->state = TASK_UNINTERRUPTIBLE;
 		schedule_timeout(HZ/10);
 	}
-	unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu), NULL);
-	unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL);
-	unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL);
-	unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL);
-	if (!xen_hvm_domain())
-		unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
+	xen_smp_intr_free(cpu);
 	xen_uninit_lock_cpu(cpu);
 	xen_teardown_timer(cpu);
 }
 
-static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */
+static void xen_play_dead(void) /* used only with HOTPLUG_CPU */
 {
 	play_dead_common();
 	HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
@@ -664,11 +691,18 @@ static void __init xen_hvm_smp_prepare_c
 	xen_init_lock_cpu(0);
 }
 
-static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)
+static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
 	int rc;
-	rc = native_cpu_up(cpu, tidle);
-	WARN_ON (xen_smp_intr_init(cpu));
+	/*
+	 * xen_smp_intr_init() needs to run before native_cpu_up()
+	 * so that IPI vectors are set up on the booting CPU before
+	 * it is marked online in native_cpu_up().
+	*/
+	rc = xen_smp_intr_init(cpu);
+	WARN_ON(rc);
+	if (!rc)
+		rc =  native_cpu_up(cpu, tidle);
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/xen/spinlock.c linux-libre-3.11-rc7-gnu/arch/x86/xen/spinlock.c
--- linux-libre-3.10-gnu/arch/x86/xen/spinlock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/xen/spinlock.c	2013-08-25 20:43:22.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/debugfs.h>
 #include <linux/log2.h>
 #include <linux/gfp.h>
+#include <linux/slab.h>
 
 #include <asm/paravirt.h>
 
@@ -165,6 +166,7 @@ static int xen_spin_trylock(struct arch_
 	return old == 0;
 }
 
+static DEFINE_PER_CPU(char *, irq_name);
 static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
 static DEFINE_PER_CPU(struct xen_spinlock *, lock_spinners);
 
@@ -359,10 +361,10 @@ static irqreturn_t dummy_handler(int irq
 	return IRQ_HANDLED;
 }
 
-void __cpuinit xen_init_lock_cpu(int cpu)
+void xen_init_lock_cpu(int cpu)
 {
 	int irq;
-	const char *name;
+	char *name;
 
 	WARN(per_cpu(lock_kicker_irq, cpu) >= 0, "spinlock on CPU%d exists on IRQ%d!\n",
 	     cpu, per_cpu(lock_kicker_irq, cpu));
@@ -385,6 +387,7 @@ void __cpuinit xen_init_lock_cpu(int cpu
 	if (irq >= 0) {
 		disable_irq(irq); /* make sure it's never delivered */
 		per_cpu(lock_kicker_irq, cpu) = irq;
+		per_cpu(irq_name, cpu) = name;
 	}
 
 	printk("cpu %d spinlock event irq %d\n", cpu, irq);
@@ -401,6 +404,8 @@ void xen_uninit_lock_cpu(int cpu)
 
 	unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL);
 	per_cpu(lock_kicker_irq, cpu) = -1;
+	kfree(per_cpu(irq_name, cpu));
+	per_cpu(irq_name, cpu) = NULL;
 }
 
 void __init xen_init_spinlocks(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/xen/time.c linux-libre-3.11-rc7-gnu/arch/x86/xen/time.c
--- linux-libre-3.10-gnu/arch/x86/xen/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/xen/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,8 @@
 #include <linux/kernel_stat.h>
 #include <linux/math64.h>
 #include <linux/gfp.h>
+#include <linux/slab.h>
+#include <linux/pvclock_gtod.h>
 
 #include <asm/pvclock.h>
 #include <asm/xen/hypervisor.h>
@@ -36,9 +38,8 @@ static DEFINE_PER_CPU(struct vcpu_runsta
 /* snapshots of runstate info */
 static DEFINE_PER_CPU(struct vcpu_runstate_info, xen_runstate_snapshot);
 
-/* unused ns of stolen and blocked time */
+/* unused ns of stolen time */
 static DEFINE_PER_CPU(u64, xen_residual_stolen);
-static DEFINE_PER_CPU(u64, xen_residual_blocked);
 
 /* return an consistent snapshot of 64-bit time/counter value */
 static u64 get64(const u64 *p)
@@ -115,7 +116,7 @@ static void do_stolen_accounting(void)
 {
 	struct vcpu_runstate_info state;
 	struct vcpu_runstate_info *snap;
-	s64 blocked, runnable, offline, stolen;
+	s64 runnable, offline, stolen;
 	cputime_t ticks;
 
 	get_runstate_snapshot(&state);
@@ -125,7 +126,6 @@ static void do_stolen_accounting(void)
 	snap = &__get_cpu_var(xen_runstate_snapshot);
 
 	/* work out how much time the VCPU has not been runn*ing*  */
-	blocked = state.time[RUNSTATE_blocked] - snap->time[RUNSTATE_blocked];
 	runnable = state.time[RUNSTATE_runnable] - snap->time[RUNSTATE_runnable];
 	offline = state.time[RUNSTATE_offline] - snap->time[RUNSTATE_offline];
 
@@ -141,17 +141,6 @@ static void do_stolen_accounting(void)
 	ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen);
 	__this_cpu_write(xen_residual_stolen, stolen);
 	account_steal_ticks(ticks);
-
-	/* Add the appropriate number of ticks of blocked time,
-	   including any left-overs from last time. */
-	blocked += __this_cpu_read(xen_residual_blocked);
-
-	if (blocked < 0)
-		blocked = 0;
-
-	ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked);
-	__this_cpu_write(xen_residual_blocked, blocked);
-	account_idle_ticks(ticks);
 }
 
 /* Get the TSC speed from Xen */
@@ -191,34 +180,56 @@ static void xen_read_wallclock(struct ti
 	put_cpu_var(xen_vcpu);
 }
 
-static unsigned long xen_get_wallclock(void)
+static void xen_get_wallclock(struct timespec *now)
 {
-	struct timespec ts;
+	xen_read_wallclock(now);
+}
 
-	xen_read_wallclock(&ts);
-	return ts.tv_sec;
+static int xen_set_wallclock(const struct timespec *now)
+{
+	return -1;
 }
 
-static int xen_set_wallclock(unsigned long now)
+static int xen_pvclock_gtod_notify(struct notifier_block *nb,
+				   unsigned long was_set, void *priv)
 {
+	/* Protected by the calling core code serialization */
+	static struct timespec next_sync;
+
 	struct xen_platform_op op;
-	int rc;
+	struct timespec now;
 
-	/* do nothing for domU */
-	if (!xen_initial_domain())
-		return -1;
+	now = __current_kernel_time();
+
+	/*
+	 * We only take the expensive HV call when the clock was set
+	 * or when the 11 minutes RTC synchronization time elapsed.
+	 */
+	if (!was_set && timespec_compare(&now, &next_sync) < 0)
+		return NOTIFY_OK;
 
 	op.cmd = XENPF_settime;
-	op.u.settime.secs = now;
-	op.u.settime.nsecs = 0;
+	op.u.settime.secs = now.tv_sec;
+	op.u.settime.nsecs = now.tv_nsec;
 	op.u.settime.system_time = xen_clocksource_read();
 
-	rc = HYPERVISOR_dom0_op(&op);
-	WARN(rc != 0, "XENPF_settime failed: now=%ld\n", now);
+	(void)HYPERVISOR_dom0_op(&op);
 
-	return rc;
+	/*
+	 * Move the next drift compensation time 11 minutes
+	 * ahead. That's emulating the sync_cmos_clock() update for
+	 * the hardware RTC.
+	 */
+	next_sync = now;
+	next_sync.tv_sec += 11 * 60;
+
+	return NOTIFY_OK;
 }
 
+static struct notifier_block xen_pvclock_gtod_notifier = {
+	.notifier_call = xen_pvclock_gtod_notify,
+};
+
 static struct clocksource xen_clocksource __read_mostly = {
 	.name = "xen",
 	.rating = 400,
@@ -377,11 +388,16 @@ static const struct clock_event_device x
 
 static const struct clock_event_device *xen_clockevent =
 	&xen_timerop_clockevent;
-static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events) = { .irq = -1 };
+
+struct xen_clock_event_device {
+	struct clock_event_device evt;
+	char *name;
+};
+static DEFINE_PER_CPU(struct xen_clock_event_device, xen_clock_events) = { .evt.irq = -1 };
 
 static irqreturn_t xen_timer_interrupt(int irq, void *dev_id)
 {
-	struct clock_event_device *evt = &__get_cpu_var(xen_clock_events);
+	struct clock_event_device *evt = &__get_cpu_var(xen_clock_events).evt;
 	irqreturn_t ret;
 
 	ret = IRQ_NONE;
@@ -395,14 +411,30 @@ static irqreturn_t xen_timer_interrupt(i
 	return ret;
 }
 
+void xen_teardown_timer(int cpu)
+{
+	struct clock_event_device *evt;
+	BUG_ON(cpu == 0);
+	evt = &per_cpu(xen_clock_events, cpu).evt;
+
+	if (evt->irq >= 0) {
+		unbind_from_irqhandler(evt->irq, NULL);
+		evt->irq = -1;
+		kfree(per_cpu(xen_clock_events, cpu).name);
+		per_cpu(xen_clock_events, cpu).name = NULL;
+	}
+}
+
 void xen_setup_timer(int cpu)
 {
-	const char *name;
+	char *name;
 	struct clock_event_device *evt;
 	int irq;
 
-	evt = &per_cpu(xen_clock_events, cpu);
+	evt = &per_cpu(xen_clock_events, cpu).evt;
 	WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu);
+	if (evt->irq >= 0)
+		xen_teardown_timer(cpu);
 
 	printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu);
 
@@ -420,22 +452,15 @@ void xen_setup_timer(int cpu)
 
 	evt->cpumask = cpumask_of(cpu);
 	evt->irq = irq;
+	per_cpu(xen_clock_events, cpu).name = name;
 }
 
-void xen_teardown_timer(int cpu)
-{
-	struct clock_event_device *evt;
-	BUG_ON(cpu == 0);
-	evt = &per_cpu(xen_clock_events, cpu);
-	unbind_from_irqhandler(evt->irq, NULL);
-	evt->irq = -1;
-}
 
 void xen_setup_cpu_clockevents(void)
 {
 	BUG_ON(preemptible());
 
-	clockevents_register_device(&__get_cpu_var(xen_clock_events));
+	clockevents_register_device(&__get_cpu_var(xen_clock_events).evt);
 }
 
 void xen_timer_resume(void)
@@ -480,6 +505,9 @@ static void __init xen_time_init(void)
 	xen_setup_runstate_info(cpu);
 	xen_setup_timer(cpu);
 	xen_setup_cpu_clockevents();
+
+	if (xen_initial_domain())
+		pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier);
 }
 
 void __init xen_init_time_ops(void)
@@ -492,7 +520,9 @@ void __init xen_init_time_ops(void)
 
 	x86_platform.calibrate_tsc = xen_tsc_khz;
 	x86_platform.get_wallclock = xen_get_wallclock;
-	x86_platform.set_wallclock = xen_set_wallclock;
+	/* Dom0 uses the native method to set the hardware RTC. */
+	if (!xen_initial_domain())
+		x86_platform.set_wallclock = xen_set_wallclock;
 }
 
 #ifdef CONFIG_XEN_PVHVM
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/x86/xen/xen-ops.h linux-libre-3.11-rc7-gnu/arch/x86/xen/xen-ops.h
--- linux-libre-3.10-gnu/arch/x86/xen/xen-ops.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/x86/xen/xen-ops.h	2013-08-25 20:43:22.000000000 -0400
@@ -73,7 +73,7 @@ static inline void xen_hvm_smp_init(void
 
 #ifdef CONFIG_PARAVIRT_SPINLOCKS
 void __init xen_init_spinlocks(void);
-void __cpuinit xen_init_lock_cpu(int cpu);
+void xen_init_lock_cpu(int cpu);
 void xen_uninit_lock_cpu(int cpu);
 #else
 static inline void xen_init_spinlocks(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/boot/boot-elf/.gitignore linux-libre-3.11-rc7-gnu/arch/xtensa/boot/boot-elf/.gitignore
--- linux-libre-3.10-gnu/arch/xtensa/boot/boot-elf/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/boot/boot-elf/.gitignore	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+boot.lds
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/boot/.gitignore linux-libre-3.11-rc7-gnu/arch/xtensa/boot/.gitignore
--- linux-libre-3.10-gnu/arch/xtensa/boot/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/boot/.gitignore	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3 @@
+uImage
+zImage.redboot
+*.dtb
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/boot/lib/.gitignore linux-libre-3.11-rc7-gnu/arch/xtensa/boot/lib/.gitignore
--- linux-libre-3.10-gnu/arch/xtensa/boot/lib/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/boot/lib/.gitignore	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3 @@
+inffast.c
+inflate.c
+inftrees.c
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/boot/lib/Makefile linux-libre-3.11-rc7-gnu/arch/xtensa/boot/lib/Makefile
--- linux-libre-3.10-gnu/arch/xtensa/boot/lib/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/boot/lib/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -7,6 +7,13 @@ zlib	:= inffast.c inflate.c inftrees.c
 lib-y	+= $(zlib:.c=.o) zmem.o
 
 ccflags-y	:= -Ilib/zlib_inflate
+ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_REMOVE_inflate.o = -pg
+CFLAGS_REMOVE_zmem.o = -pg
+CFLAGS_REMOVE_inftrees.o = -pg
+CFLAGS_REMOVE_inffast.o = -pg
+endif
+
 
 quiet_cmd_copy_zlib = COPY    $@
       cmd_copy_zlib = cat $< > $@
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/include/asm/bootparam.h linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/bootparam.h
--- linux-libre-3.10-gnu/arch/xtensa/include/asm/bootparam.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/bootparam.h	2013-08-25 20:43:22.000000000 -0400
@@ -20,7 +20,7 @@
 #define BP_TAG_COMMAND_LINE	0x1001	/* command line (0-terminated string)*/
 #define BP_TAG_INITRD		0x1002	/* ramdisk addr and size (bp_meminfo) */
 #define BP_TAG_MEMORY		0x1003	/* memory addr and size (bp_meminfo) */
-#define BP_TAG_SERIAL_BAUSRATE	0x1004	/* baud rate of current console. */
+#define BP_TAG_SERIAL_BAUDRATE	0x1004	/* baud rate of current console. */
 #define BP_TAG_SERIAL_PORT	0x1005	/* serial device of current console */
 #define BP_TAG_FDT		0x1006	/* flat device tree addr */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/include/asm/cmpxchg.h linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/cmpxchg.h
--- linux-libre-3.10-gnu/arch/xtensa/include/asm/cmpxchg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/cmpxchg.h	2013-08-25 20:43:22.000000000 -0400
@@ -93,6 +93,7 @@ static inline unsigned long __cmpxchg_lo
 	((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
 			(unsigned long)(n), sizeof(*(ptr))))
 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+#define cmpxchg64(ptr, o, n)    cmpxchg64_local((ptr), (o), (n))
 
 /*
  * xchg_u32
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/include/asm/delay.h linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/delay.h
--- linux-libre-3.10-gnu/arch/xtensa/include/asm/delay.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/delay.h	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,7 @@
 #ifndef _XTENSA_DELAY_H
 #define _XTENSA_DELAY_H
 
-#include <asm/processor.h>
+#include <asm/timex.h>
 #include <asm/param.h>
 
 extern unsigned long loops_per_jiffy;
@@ -24,24 +24,17 @@ static inline void __delay(unsigned long
 			      : "=r" (loops) : "0" (loops));
 }
 
-static __inline__ u32 xtensa_get_ccount(void)
-{
-	u32 ccount;
-	asm volatile ("rsr %0, ccount\n" : "=r" (ccount));
-	return ccount;
-}
-
 /* For SMP/NUMA systems, change boot_cpu_data to something like
  * local_cpu_data->... where local_cpu_data points to the current
  * cpu. */
 
 static __inline__ void udelay (unsigned long usecs)
 {
-	unsigned long start = xtensa_get_ccount();
+	unsigned long start = get_ccount();
 	unsigned long cycles = usecs * (loops_per_jiffy / (1000000UL / HZ));
 
 	/* Note: all variables are unsigned (can wrap around)! */
-	while (((unsigned long)xtensa_get_ccount()) - start < cycles)
+	while (((unsigned long)get_ccount()) - start < cycles)
 		;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/include/asm/ftrace.h linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/ftrace.h
--- linux-libre-3.10-gnu/arch/xtensa/include/asm/ftrace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/ftrace.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
 #include <asm/processor.h>
 
 #define HAVE_ARCH_CALLER_ADDR
+#ifndef __ASSEMBLY__
 #define CALLER_ADDR0 ({ unsigned long a0, a1; \
 		__asm__ __volatile__ ( \
 			"mov %0, a0\n" \
@@ -24,10 +25,22 @@ extern unsigned long return_address(unsi
 #define CALLER_ADDR1 return_address(1)
 #define CALLER_ADDR2 return_address(2)
 #define CALLER_ADDR3 return_address(3)
-#else
+#else /* CONFIG_FRAME_POINTER */
 #define CALLER_ADDR1 (0)
 #define CALLER_ADDR2 (0)
 #define CALLER_ADDR3 (0)
-#endif
+#endif /* CONFIG_FRAME_POINTER */
+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_FUNCTION_TRACER
+
+#define MCOUNT_ADDR ((unsigned long)(_mcount))
+#define MCOUNT_INSN_SIZE 3
+
+#ifndef __ASSEMBLY__
+extern void _mcount(void);
+#define mcount _mcount
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_FUNCTION_TRACER */
 
 #endif /* _XTENSA_FTRACE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/include/asm/pgtable.h linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/pgtable.h
--- linux-libre-3.10-gnu/arch/xtensa/include/asm/pgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/pgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * Copyright (C) 2001 - 2007 Tensilica Inc.
+ * Copyright (C) 2001 - 2013 Tensilica Inc.
  */
 
 #ifndef _XTENSA_PGTABLE_H
@@ -64,41 +64,82 @@
  * Virtual memory area. We keep a distance to other memory regions to be
  * on the safe side. We also use this area for cache aliasing.
  */
-
 #define VMALLOC_START		0xC0000000
 #define VMALLOC_END		0xC7FEFFFF
 #define TLBTEMP_BASE_1		0xC7FF0000
 #define TLBTEMP_BASE_2		0xC7FF8000
 
 /*
- * Xtensa Linux config PTE layout (when present):
- *	31-12:	PPN
- *	11-6:	Software
- *	5-4:	RING
- *	3-0:	CA
+ * For the Xtensa architecture, the PTE layout is as follows:
  *
- * Similar to the Alpha and MIPS ports, we need to keep track of the ref
- * and mod bits in software.  We have a software "you can read
- * from this page" bit, and a hardware one which actually lets the
- * process read from the page.  On the same token we have a software
- * writable bit and the real hardware one which actually lets the
- * process write to the page.
+ *		31------12  11  10-9   8-6  5-4  3-2  1-0
+ *		+-----------------------------------------+
+ *		|           |   Software   |   HARDWARE   |
+ *		|    PPN    |          ADW | RI |Attribute|
+ *		+-----------------------------------------+
+ *   pte_none	|             MBZ          | 01 | 11 | 00 |
+ *		+-----------------------------------------+
+ *   present	|    PPN    | 0 | 00 | ADW | RI | CA | wx |
+ *		+- - - - - - - - - - - - - - - - - - - - -+
+ *   (PAGE_NONE)|    PPN    | 0 | 00 | ADW | 01 | 11 | 11 |
+ *		+-----------------------------------------+
+ *   swap	|     index     |   type   | 01 | 11 | 00 |
+ *		+- - - - - - - - - - - - - - - - - - - - -+
+ *   file	|        file offset       | 01 | 11 | 10 |
+ *		+-----------------------------------------+
  *
- * See further below for PTE layout for swapped-out pages.
+ * For T1050 hardware and earlier the layout differs for present and (PAGE_NONE)
+ *		+-----------------------------------------+
+ *   present	|    PPN    | 0 | 00 | ADW | RI | CA | w1 |
+ *		+-----------------------------------------+
+ *   (PAGE_NONE)|    PPN    | 0 | 00 | ADW | 01 | 01 | 00 |
+ *		+-----------------------------------------+
+ *
+ *  Legend:
+ *   PPN        Physical Page Number
+ *   ADW	software: accessed (young) / dirty / writable
+ *   RI         ring (0=privileged, 1=user, 2 and 3 are unused)
+ *   CA		cache attribute: 00 bypass, 01 writeback, 10 writethrough
+ *		(11 is invalid and used to mark pages that are not present)
+ *   w		page is writable (hw)
+ *   x		page is executable (hw)
+ *   index      swap offset / PAGE_SIZE (bit 11-31: 21 bits -> 8 GB)
+ *		(note that the index is always non-zero)
+ *   type       swap type (5 bits -> 32 types)
+ *   file offset 26-bit offset into the file, in increments of PAGE_SIZE
+ *
+ *  Notes:
+ *   - (PROT_NONE) is a special case of 'present' but causes an exception for
+ *     any access (read, write, and execute).
+ *   - 'multihit-exception' has the highest priority of all MMU exceptions,
+ *     so the ring must be set to 'RING_USER' even for 'non-present' pages.
+ *   - on older hardware, the exectuable flag was not supported and
+ *     used as a 'valid' flag, so it needs to be always set.
+ *   - we need to keep track of certain flags in software (dirty and young)
+ *     to do this, we use write exceptions and have a separate software w-flag.
+ *   - attribute value 1101 (and 1111 on T1050 and earlier) is reserved
  */
 
+#define _PAGE_ATTRIB_MASK	0xf
+
 #define _PAGE_HW_EXEC		(1<<0)	/* hardware: page is executable */
 #define _PAGE_HW_WRITE		(1<<1)	/* hardware: page is writable */
 
-#define _PAGE_FILE		(1<<1)	/* non-linear mapping, if !present */
-#define _PAGE_PROTNONE		(3<<0)	/* special case for VM_PROT_NONE */
-
-/* None of these cache modes include MP coherency:  */
 #define _PAGE_CA_BYPASS		(0<<2)	/* bypass, non-speculative */
 #define _PAGE_CA_WB		(1<<2)	/* write-back */
 #define _PAGE_CA_WT		(2<<2)	/* write-through */
 #define _PAGE_CA_MASK		(3<<2)
-#define _PAGE_INVALID		(3<<2)
+#define _PAGE_CA_INVALID	(3<<2)
+
+/* We use invalid attribute values to distinguish special pte entries */
+#if XCHAL_HW_VERSION_MAJOR < 2000
+#define _PAGE_HW_VALID		0x01	/* older HW needed this bit set */
+#define _PAGE_NONE		0x04
+#else
+#define _PAGE_HW_VALID		0x00
+#define _PAGE_NONE		0x0f
+#endif
+#define _PAGE_FILE		(1<<1)	/* file mapped page, only if !present */
 
 #define _PAGE_USER		(1<<4)	/* user access (ring=1) */
 
@@ -108,19 +149,12 @@
 #define _PAGE_DIRTY		(1<<7)	/* software: page dirty */
 #define _PAGE_ACCESSED		(1<<8)	/* software: page accessed (read) */
 
-/* On older HW revisions, we always have to set bit 0 */
-#if XCHAL_HW_VERSION_MAJOR < 2000
-# define _PAGE_VALID		(1<<0)
-#else
-# define _PAGE_VALID		0
-#endif
-
-#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
-#define _PAGE_PRESENT	(_PAGE_VALID | _PAGE_CA_WB | _PAGE_ACCESSED)
-
 #ifdef CONFIG_MMU
 
-#define PAGE_NONE	   __pgprot(_PAGE_INVALID | _PAGE_USER | _PAGE_PROTNONE)
+#define _PAGE_CHG_MASK	   (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_PRESENT	   (_PAGE_HW_VALID | _PAGE_CA_WB | _PAGE_ACCESSED)
+
+#define PAGE_NONE	   __pgprot(_PAGE_NONE | _PAGE_USER)
 #define PAGE_COPY	   __pgprot(_PAGE_PRESENT | _PAGE_USER)
 #define PAGE_COPY_EXEC	   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_HW_EXEC)
 #define PAGE_READONLY	   __pgprot(_PAGE_PRESENT | _PAGE_USER)
@@ -132,9 +166,9 @@
 #define PAGE_KERNEL_EXEC   __pgprot(_PAGE_PRESENT|_PAGE_HW_WRITE|_PAGE_HW_EXEC)
 
 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
-# define _PAGE_DIRECTORY (_PAGE_VALID | _PAGE_ACCESSED)
+# define _PAGE_DIRECTORY   (_PAGE_HW_VALID | _PAGE_ACCESSED | _PAGE_CA_BYPASS)
 #else
-# define _PAGE_DIRECTORY (_PAGE_VALID | _PAGE_ACCESSED | _PAGE_CA_WB)
+# define _PAGE_DIRECTORY   (_PAGE_HW_VALID | _PAGE_ACCESSED | _PAGE_CA_WB)
 #endif
 
 #else /* no mmu */
@@ -202,12 +236,16 @@ static inline void pgtable_cache_init(vo
 /*
  * pte status.
  */
-#define pte_none(pte)	 (pte_val(pte) == _PAGE_INVALID)
-#define pte_present(pte)						\
-	(((pte_val(pte) & _PAGE_CA_MASK) != _PAGE_INVALID)		\
-	 || ((pte_val(pte) & _PAGE_PROTNONE) == _PAGE_PROTNONE))
+# define pte_none(pte)	 (pte_val(pte) == (_PAGE_CA_INVALID | _PAGE_USER))
+#if XCHAL_HW_VERSION_MAJOR < 2000
+# define pte_present(pte) ((pte_val(pte) & _PAGE_CA_MASK) != _PAGE_CA_INVALID)
+#else
+# define pte_present(pte)						\
+	(((pte_val(pte) & _PAGE_CA_MASK) != _PAGE_CA_INVALID)		\
+	 || ((pte_val(pte) & _PAGE_ATTRIB_MASK) == _PAGE_NONE))
+#endif
 #define pte_clear(mm,addr,ptep)						\
-	do { update_pte(ptep, __pte(_PAGE_INVALID)); } while(0)
+	do { update_pte(ptep, __pte(_PAGE_CA_INVALID | _PAGE_USER)); } while (0)
 
 #define pmd_none(pmd)	 (!pmd_val(pmd))
 #define pmd_present(pmd) (pmd_val(pmd) & PAGE_MASK)
@@ -328,35 +366,23 @@ ptep_set_wrprotect(struct mm_struct *mm,
 
 
 /*
- * Encode and decode a swap entry.
- *
- * Format of swap pte:
- *  bit	   0	   MBZ
- *  bit	   1	   page-file (must be zero)
- *  bits   2 -  3  page hw access mode (must be 11: _PAGE_INVALID)
- *  bits   4 -  5  ring protection (must be 01: _PAGE_USER)
- *  bits   6 - 10  swap type (5 bits -> 32 types)
- *  bits  11 - 31  swap offset / PAGE_SIZE (21 bits -> 8GB)
- 
- * Format of file pte:
- *  bit	   0	   MBZ
- *  bit	   1	   page-file (must be one: _PAGE_FILE)
- *  bits   2 -  3  page hw access mode (must be 11: _PAGE_INVALID)
- *  bits   4 -  5  ring protection (must be 01: _PAGE_USER)
- *  bits   6 - 31  file offset / PAGE_SIZE
+ * Encode and decode a swap and file entry.
  */
+#define SWP_TYPE_BITS		5
+#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
 
 #define __swp_type(entry)	(((entry).val >> 6) & 0x1f)
 #define __swp_offset(entry)	((entry).val >> 11)
 #define __swp_entry(type,offs)	\
-	((swp_entry_t) {((type) << 6) | ((offs) << 11) | _PAGE_INVALID})
+	((swp_entry_t){((type) << 6) | ((offs) << 11) | \
+	 _PAGE_CA_INVALID | _PAGE_USER})
 #define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
 #define __swp_entry_to_pte(x)	((pte_t) { (x).val })
 
-#define PTE_FILE_MAX_BITS	28
-#define pte_to_pgoff(pte)	(pte_val(pte) >> 4)
+#define PTE_FILE_MAX_BITS	26
+#define pte_to_pgoff(pte)	(pte_val(pte) >> 6)
 #define pgoff_to_pte(off)	\
-	((pte_t) { ((off) << 4) | _PAGE_INVALID | _PAGE_FILE })
+	((pte_t) { ((off) << 6) | _PAGE_CA_INVALID | _PAGE_FILE | _PAGE_USER })
 
 #endif /*  !defined (__ASSEMBLY__) */
 
@@ -393,14 +419,6 @@ ptep_set_wrprotect(struct mm_struct *mm,
 extern  void update_mmu_cache(struct vm_area_struct * vma,
 			      unsigned long address, pte_t *ptep);
 
-/*
- * remap a physical page `pfn' of size `size' with page protection `prot'
- * into virtual address `from'
- */
-
-#define io_remap_pfn_range(vma,from,pfn,size,prot) \
-	remap_pfn_range(vma, from, pfn, size, prot)
-
 typedef pte_t *pte_addr_t;
 
 #endif /* !defined (__ASSEMBLY__) */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/include/asm/platform.h linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/platform.h
--- linux-libre-3.10-gnu/arch/xtensa/include/asm/platform.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/platform.h	2013-08-25 20:43:22.000000000 -0400
@@ -30,11 +30,6 @@ extern void platform_init(bp_tag_t*);
 extern void platform_setup (char **);
 
 /*
- * platform_init_irq is called from init_IRQ.
- */
-extern void platform_init_irq (void);
-
-/*
  * platform_restart is called to restart the system.
  */
 extern void platform_restart (void);
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/include/asm/timex.h linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/timex.h
--- linux-libre-3.10-gnu/arch/xtensa/include/asm/timex.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/include/asm/timex.h	2013-08-25 20:43:22.000000000 -0400
@@ -35,19 +35,11 @@
 # error "Bad timer number for Linux configurations!"
 #endif
 
-#define LINUX_TIMER_MASK        (1L << LINUX_TIMER_INT)
-
-#define CLOCK_TICK_RATE 	1193180	/* (everyone is using this value) */
-#define CLOCK_TICK_FACTOR       20 /* Factor of both 10^6 and CLOCK_TICK_RATE */
-
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
-extern unsigned long ccount_per_jiffy;
-extern unsigned long nsec_per_ccount;
-#define CCOUNT_PER_JIFFY ccount_per_jiffy
-#define NSEC_PER_CCOUNT  nsec_per_ccount
+extern unsigned long ccount_freq;
+#define CCOUNT_PER_JIFFY (ccount_freq / HZ)
 #else
 #define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ))
-#define NSEC_PER_CCOUNT (1000UL / CONFIG_XTENSA_CPU_CLOCK)
 #endif
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/include/uapi/asm/socket.h linux-libre-3.11-rc7-gnu/arch/xtensa/include/uapi/asm/socket.h
--- linux-libre-3.10-gnu/arch/xtensa/include/uapi/asm/socket.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/include/uapi/asm/socket.h	2013-08-25 20:43:22.000000000 -0400
@@ -85,4 +85,6 @@
 
 #define SO_SELECT_ERR_QUEUE	45
 
+#define SO_BUSY_POLL		46
+
 #endif	/* _XTENSA_SOCKET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/Kconfig linux-libre-3.11-rc7-gnu/arch/xtensa/Kconfig
--- linux-libre-3.10-gnu/arch/xtensa/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -6,10 +6,12 @@ config XTENSA
 	select ARCH_WANT_FRAME_POINTERS
 	select HAVE_IDE
 	select GENERIC_ATOMIC64
+	select GENERIC_CLOCKEVENTS
 	select HAVE_GENERIC_HARDIRQS
 	select VIRT_TO_BUS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_CPU_DEVICES
+	select GENERIC_SCHED_CLOCK
 	select MODULES_USE_ELF_RELA
 	select GENERIC_PCI_IOMAP
 	select ARCH_WANT_IPC_PARSE_VERSION
@@ -17,6 +19,7 @@ config XTENSA
 	select CLONE_BACKWARDS
 	select IRQ_DOMAIN
 	select HAVE_OPROFILE
+	select HAVE_FUNCTION_TRACER
 	help
 	  Xtensa processors are 32-bit RISC machines designed by Tensilica
 	  primarily for embedded systems.  These processors are both
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/Kconfig.debug linux-libre-3.11-rc7-gnu/arch/xtensa/Kconfig.debug
--- linux-libre-3.10-gnu/arch/xtensa/Kconfig.debug	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/Kconfig.debug	2013-08-25 20:43:22.000000000 -0400
@@ -2,6 +2,16 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
+config DEBUG_TLB_SANITY
+	bool "Debug TLB sanity"
+	depends on DEBUG_KERNEL
+	help
+	  Enable this to turn on TLB sanity check on each entry to userspace.
+	  This check can spot missing TLB invalidation/wrong PTE permissions/
+	  premature page freeing.
+
+	  If unsure, say N.
+
 config LD_NO_RELAX
 	bool "Disable linker relaxation"
 	default n
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/entry.S linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/entry.S
--- linux-libre-3.10-gnu/arch/xtensa/kernel/entry.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/entry.S	2013-08-25 20:43:22.000000000 -0400
@@ -458,7 +458,7 @@ common_exception_return:
 
 	_bbsi.l	a4, TIF_NEED_RESCHED, 3f
 	_bbsi.l	a4, TIF_NOTIFY_RESUME, 2f
-	_bbci.l	a4, TIF_SIGPENDING, 4f
+	_bbci.l	a4, TIF_SIGPENDING, 5f
 
 2:	l32i	a4, a1, PT_DEPC
 	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
@@ -476,6 +476,13 @@ common_exception_return:
 	callx4	a4
 	j	1b
 
+5:
+#ifdef CONFIG_DEBUG_TLB_SANITY
+	l32i	a4, a1, PT_DEPC
+	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
+	movi	a4, check_tlb_sanity
+	callx4	a4
+#endif
 4:	/* Restore optional registers. */
 
 	load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
@@ -1792,10 +1799,15 @@ ENTRY(fast_store_prohibited)
 	l32i	a0, a0, 0
 	beqz	a0, 2f
 
-	/* Note that we assume _PAGE_WRITABLE_BIT is only set if pte is valid.*/
+	/*
+	 * Note that we test _PAGE_WRITABLE_BIT only if PTE is present
+	 * and is not PAGE_NONE. See pgtable.h for possible PTE layouts.
+	 */
 
 	_PTE_OFFSET(a0, a1, a4)
 	l32i	a4, a0, 0		# read pteval
+	movi	a1, _PAGE_CA_INVALID
+	ball	a4, a1, 2f
 	bbci.l	a4, _PAGE_WRITABLE_BIT, 2f
 
 	movi	a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HW_WRITE
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/.gitignore linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/.gitignore
--- linux-libre-3.10-gnu/arch/xtensa/kernel/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/.gitignore	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+vmlinux.lds
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/head.S linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/head.S
--- linux-libre-3.10-gnu/arch/xtensa/kernel/head.S	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/head.S	2013-08-25 20:43:22.000000000 -0400
@@ -68,6 +68,15 @@ _SetupMMU:
 
 #ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
 	initialize_mmu
+#if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
+	rsr	a2, excsave1
+	movi	a3, 0x08000000
+	bgeu	a2, a3, 1f
+	movi	a3, 0xd0000000
+	add	a2, a2, a3
+	wsr	a2, excsave1
+1:
+#endif
 #endif
 	.end	no-absolute-literals
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/Makefile linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/Makefile
--- linux-libre-3.10-gnu/arch/xtensa/kernel/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,7 @@ obj-y := align.o coprocessor.o entry.o i
 obj-$(CONFIG_KGDB) += xtensa-stub.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
+obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
 
 AFLAGS_head.o += -mtext-section-literals
 
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/mcount.S linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/mcount.S
--- linux-libre-3.10-gnu/arch/xtensa/kernel/mcount.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/mcount.S	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,50 @@
+/*
+ * arch/xtensa/kernel/mcount.S
+ *
+ * Xtensa specific mcount support
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Tensilica Inc.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ftrace.h>
+
+/*
+ * Entry condition:
+ *
+ *   a2:	a0 of the caller
+ */
+
+ENTRY(_mcount)
+
+	entry	a1, 16
+
+	movi	a4, ftrace_trace_function
+	l32i	a4, a4, 0
+	movi	a3, ftrace_stub
+	bne	a3, a4, 1f
+	retw
+
+1: 	xor	a7, a2, a1
+	movi	a3, 0x3fffffff
+	and	a7, a7, a3
+	xor	a7, a7, a1
+
+	xor	a6, a0, a1
+	and	a6, a6, a3
+	xor	a6, a6, a1
+	addi	a6, a6, -MCOUNT_INSN_SIZE
+	callx4	a4
+
+	retw
+
+ENDPROC(_mcount)
+
+ENTRY(ftrace_stub)
+	entry	a1, 16
+	retw
+ENDPROC(ftrace_stub)
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/pci.c linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/pci.c
--- linux-libre-3.10-gnu/arch/xtensa/kernel/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -77,9 +77,9 @@ pcibios_align_resource(void *data, const
 
 	if (res->flags & IORESOURCE_IO) {
 		if (size > 0x100) {
-			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
-			       " (%ld bytes)\n", pci_name(dev),
-			       dev->resource - res, size);
+			pr_err("PCI: I/O Region %s/%d too large (%u bytes)\n",
+					pci_name(dev), dev->resource - res,
+					size);
 		}
 
 		if (start & 0x300)
@@ -174,7 +174,7 @@ static int __init pcibios_init(void)
 	struct pci_controller *pci_ctrl;
 	struct list_head resources;
 	struct pci_bus *bus;
-	int next_busno = 0, i;
+	int next_busno = 0;
 
 	printk("PCI: Probing PCI hardware\n");
 
@@ -197,7 +197,7 @@ static int __init pcibios_init(void)
 
 subsys_initcall(pcibios_init);
 
-void __init pcibios_fixup_bus(struct pci_bus *bus)
+void pcibios_fixup_bus(struct pci_bus *bus)
 {
 	if (bus->parent) {
 		/* This is a subordinate bridge */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/platform.c linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/platform.c
--- linux-libre-3.10-gnu/arch/xtensa/kernel/platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
  */
 
 _F(void, setup, (char** cmd), { });
-_F(void, init_irq, (void), { });
 _F(void, restart, (void), { while(1); });
 _F(void, halt, (void), { while(1); });
 _F(void, power_off, (void), { while(1); });
@@ -42,6 +41,6 @@ _F(void, pcibios_init, (void), { });
 _F(void, calibrate_ccount, (void),
 {
 	pr_err("ERROR: Cannot calibrate cpu frequency! Assuming 10MHz.\n");
-	ccount_per_jiffy = 10 * (1000000UL/HZ);
+	ccount_freq = 10 * 1000000UL;
 });
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/setup.c linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/setup.c
--- linux-libre-3.10-gnu/arch/xtensa/kernel/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -152,8 +152,8 @@ static int __init parse_tag_initrd(const
 {
 	meminfo_t* mi;
 	mi = (meminfo_t*)(tag->data);
-	initrd_start = (void*)(mi->start);
-	initrd_end = (void*)(mi->end);
+	initrd_start = __va(mi->start);
+	initrd_end = __va(mi->end);
 
 	return 0;
 }
@@ -164,7 +164,7 @@ __tagtable(BP_TAG_INITRD, parse_tag_init
 
 static int __init parse_tag_fdt(const bp_tag_t *tag)
 {
-	dtb_start = (void *)(tag->data[0]);
+	dtb_start = __va(tag->data[0]);
 	return 0;
 }
 
@@ -256,7 +256,7 @@ void __init early_init_devtree(void *par
 static void __init copy_devtree(void)
 {
 	void *alloc = early_init_dt_alloc_memory_arch(
-			be32_to_cpu(initial_boot_params->totalsize), 0);
+			be32_to_cpu(initial_boot_params->totalsize), 8);
 	if (alloc) {
 		memcpy(alloc, initial_boot_params,
 				be32_to_cpu(initial_boot_params->totalsize));
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/time.c linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/time.c
--- linux-libre-3.10-gnu/arch/xtensa/kernel/time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/time.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/clocksource.h>
+#include <linux/clockchips.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -23,13 +24,13 @@
 #include <linux/profile.h>
 #include <linux/delay.h>
 #include <linux/irqdomain.h>
+#include <linux/sched_clock.h>
 
 #include <asm/timex.h>
 #include <asm/platform.h>
 
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
-unsigned long ccount_per_jiffy;		/* per 1/HZ */
-unsigned long nsec_per_ccount;		/* nsec per ccount increment */
+unsigned long ccount_freq;		/* ccount Hz */
 #endif
 
 static cycle_t ccount_read(struct clocksource *cs)
@@ -37,6 +38,11 @@ static cycle_t ccount_read(struct clocks
 	return (cycle_t)get_ccount();
 }
 
+static u32 notrace ccount_sched_clock_read(void)
+{
+	return get_ccount();
+}
+
 static struct clocksource ccount_clocksource = {
 	.name = "ccount",
 	.rating = 200,
@@ -44,29 +50,98 @@ static struct clocksource ccount_clockso
 	.mask = CLOCKSOURCE_MASK(32),
 };
 
+static int ccount_timer_set_next_event(unsigned long delta,
+		struct clock_event_device *dev);
+static void ccount_timer_set_mode(enum clock_event_mode mode,
+		struct clock_event_device *evt);
+static struct ccount_timer_t {
+	struct clock_event_device evt;
+	int irq_enabled;
+} ccount_timer = {
+	.evt = {
+		.name		= "ccount_clockevent",
+		.features	= CLOCK_EVT_FEAT_ONESHOT,
+		.rating		= 300,
+		.set_next_event	= ccount_timer_set_next_event,
+		.set_mode	= ccount_timer_set_mode,
+	},
+};
+
+static int ccount_timer_set_next_event(unsigned long delta,
+		struct clock_event_device *dev)
+{
+	unsigned long flags, next;
+	int ret = 0;
+
+	local_irq_save(flags);
+	next = get_ccount() + delta;
+	set_linux_timer(next);
+	if (next - get_ccount() > delta)
+		ret = -ETIME;
+	local_irq_restore(flags);
+
+	return ret;
+}
+
+static void ccount_timer_set_mode(enum clock_event_mode mode,
+		struct clock_event_device *evt)
+{
+	struct ccount_timer_t *timer =
+		container_of(evt, struct ccount_timer_t, evt);
+
+	/*
+	 * There is no way to disable the timer interrupt at the device level,
+	 * only at the intenable register itself. Since enable_irq/disable_irq
+	 * calls are nested, we need to make sure that these calls are
+	 * balanced.
+	 */
+	switch (mode) {
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+		if (timer->irq_enabled) {
+			disable_irq(evt->irq);
+			timer->irq_enabled = 0;
+		}
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+	case CLOCK_EVT_MODE_ONESHOT:
+		if (!timer->irq_enabled) {
+			enable_irq(evt->irq);
+			timer->irq_enabled = 1;
+		}
+	default:
+		break;
+	}
+}
+
 static irqreturn_t timer_interrupt(int irq, void *dev_id);
 static struct irqaction timer_irqaction = {
 	.handler =	timer_interrupt,
-	.flags =	IRQF_DISABLED,
+	.flags =	IRQF_TIMER,
 	.name =		"timer",
+	.dev_id =	&ccount_timer,
 };
 
 void __init time_init(void)
 {
-	unsigned int irq;
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 	printk("Calibrating CPU frequency ");
 	platform_calibrate_ccount();
-	printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
-			(int)(ccount_per_jiffy/(10000/HZ))%100);
+	printk("%d.%02d MHz\n", (int)ccount_freq/1000000,
+			(int)(ccount_freq/10000)%100);
 #endif
 	clocksource_register_hz(&ccount_clocksource, CCOUNT_PER_JIFFY * HZ);
 
-	/* Initialize the linux timer interrupt. */
+	ccount_timer.evt.cpumask = cpumask_of(0);
+	ccount_timer.evt.irq = irq_create_mapping(NULL, LINUX_TIMER_INT);
+	if (WARN(!ccount_timer.evt.irq, "error: can't map timer irq"))
+		return;
+	clockevents_config_and_register(&ccount_timer.evt, ccount_freq, 0xf,
+			0xffffffff);
+	setup_irq(ccount_timer.evt.irq, &timer_irqaction);
+	ccount_timer.irq_enabled = 1;
 
-	irq = irq_create_mapping(NULL, LINUX_TIMER_INT);
-	setup_irq(irq, &timer_irqaction);
-	set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
+	setup_sched_clock(ccount_sched_clock_read, 32, ccount_freq);
 }
 
 /*
@@ -75,41 +150,19 @@ void __init time_init(void)
 
 irqreturn_t timer_interrupt (int irq, void *dev_id)
 {
+	struct ccount_timer_t *timer = dev_id;
+	struct clock_event_device *evt = &timer->evt;
 
-	unsigned long next;
-
-	next = get_linux_timer();
-
-again:
-	while ((signed long)(get_ccount() - next) > 0) {
-
-		profile_tick(CPU_PROFILING);
-#ifndef CONFIG_SMP
-		update_process_times(user_mode(get_irq_regs()));
-#endif
-
-		xtime_update(1); /* Linux handler in kernel/time/timekeeping */
-
-		/* Note that writing CCOMPARE clears the interrupt. */
-
-		next += CCOUNT_PER_JIFFY;
-		set_linux_timer(next);
-	}
+	evt->event_handler(evt);
 
 	/* Allow platform to do something useful (Wdog). */
-
 	platform_heartbeat();
 
-	/* Make sure we didn't miss any tick... */
-
-	if ((signed long)(get_ccount() - next) > 0)
-		goto again;
-
 	return IRQ_HANDLED;
 }
 
 #ifndef CONFIG_GENERIC_CALIBRATE_DELAY
-void __cpuinit calibrate_delay(void)
+void calibrate_delay(void)
 {
 	loops_per_jiffy = CCOUNT_PER_JIFFY;
 	printk("Calibrating delay loop (skipped)... "
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/kernel/xtensa_ksyms.c linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/xtensa_ksyms.c
--- linux-libre-3.10-gnu/arch/xtensa/kernel/xtensa_ksyms.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/kernel/xtensa_ksyms.c	2013-08-25 20:43:22.000000000 -0400
@@ -124,3 +124,7 @@ extern long common_exception_return;
 extern long _spill_registers;
 EXPORT_SYMBOL(common_exception_return);
 EXPORT_SYMBOL(_spill_registers);
+
+#ifdef CONFIG_FUNCTION_TRACER
+EXPORT_SYMBOL(_mcount);
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/mm/init.c linux-libre-3.11-rc7-gnu/arch/xtensa/mm/init.c
--- linux-libre-3.10-gnu/arch/xtensa/mm/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/mm/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -173,39 +173,16 @@ void __init zones_init(void)
 
 void __init mem_init(void)
 {
-	unsigned long codesize, reservedpages, datasize, initsize;
-	unsigned long highmemsize, tmp, ram;
-
-	max_mapnr = num_physpages = max_low_pfn - ARCH_PFN_OFFSET;
+	max_mapnr = max_low_pfn - ARCH_PFN_OFFSET;
 	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
-	highmemsize = 0;
 
 #ifdef CONFIG_HIGHMEM
 #error HIGHGMEM not implemented in init.c
 #endif
 
-	totalram_pages += free_all_bootmem();
-
-	reservedpages = ram = 0;
-	for (tmp = 0; tmp < max_mapnr; tmp++) {
-		ram++;
-		if (PageReserved(mem_map+tmp))
-			reservedpages++;
-	}
-
-	codesize =  (unsigned long) _etext - (unsigned long) _stext;
-	datasize =  (unsigned long) _edata - (unsigned long) _sdata;
-	initsize =  (unsigned long) __init_end - (unsigned long) __init_begin;
+	free_all_bootmem();
 
-	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
-	       "%ldk data, %ldk init %ldk highmem)\n",
-	       nr_free_pages() << (PAGE_SHIFT-10),
-	       ram << (PAGE_SHIFT-10),
-	       codesize >> 10,
-	       reservedpages << (PAGE_SHIFT-10),
-	       datasize >> 10,
-	       initsize >> 10,
-	       highmemsize >> 10);
+	mem_init_print_info(NULL);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -214,11 +191,11 @@ extern int initrd_is_mapped;
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
 	if (initrd_is_mapped)
-		free_reserved_area(start, end, 0, "initrd");
+		free_reserved_area((void *)start, (void *)end, -1, "initrd");
 }
 #endif
 
 void free_initmem(void)
 {
-	free_initmem_default(0);
+	free_initmem_default(-1);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/mm/tlb.c linux-libre-3.11-rc7-gnu/arch/xtensa/mm/tlb.c
--- linux-libre-3.10-gnu/arch/xtensa/mm/tlb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/mm/tlb.c	2013-08-25 20:43:22.000000000 -0400
@@ -64,7 +64,7 @@ void flush_tlb_mm(struct mm_struct *mm)
 {
 	if (mm == current->active_mm) {
 		unsigned long flags;
-		local_save_flags(flags);
+		local_irq_save(flags);
 		__get_new_mmu_context(mm);
 		__load_mmu_context(mm);
 		local_irq_restore(flags);
@@ -94,7 +94,7 @@ void flush_tlb_range (struct vm_area_str
 	printk("[tlbrange<%02lx,%08lx,%08lx>]\n",
 			(unsigned long)mm->context, start, end);
 #endif
-	local_save_flags(flags);
+	local_irq_save(flags);
 
 	if (end-start + (PAGE_SIZE-1) <= _TLB_ENTRIES << PAGE_SHIFT) {
 		int oldpid = get_rasid_register();
@@ -128,9 +128,10 @@ void flush_tlb_page (struct vm_area_stru
 	if(mm->context == NO_CONTEXT)
 		return;
 
-	local_save_flags(flags);
+	local_irq_save(flags);
 
 	oldpid = get_rasid_register();
+	set_rasid_register(ASID_INSERT(mm->context));
 
 	if (vma->vm_flags & VM_EXEC)
 		invalidate_itlb_mapping(page);
@@ -140,3 +141,116 @@ void flush_tlb_page (struct vm_area_stru
 
 	local_irq_restore(flags);
 }
+
+#ifdef CONFIG_DEBUG_TLB_SANITY
+
+static unsigned get_pte_for_vaddr(unsigned vaddr)
+{
+	struct task_struct *task = get_current();
+	struct mm_struct *mm = task->mm;
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	if (!mm)
+		mm = task->active_mm;
+	pgd = pgd_offset(mm, vaddr);
+	if (pgd_none_or_clear_bad(pgd))
+		return 0;
+	pmd = pmd_offset(pgd, vaddr);
+	if (pmd_none_or_clear_bad(pmd))
+		return 0;
+	pte = pte_offset_map(pmd, vaddr);
+	if (!pte)
+		return 0;
+	return pte_val(*pte);
+}
+
+enum {
+	TLB_SUSPICIOUS	= 1,
+	TLB_INSANE	= 2,
+};
+
+static void tlb_insane(void)
+{
+	BUG_ON(1);
+}
+
+static void tlb_suspicious(void)
+{
+	WARN_ON(1);
+}
+
+/*
+ * Check that TLB entries with kernel ASID (1) have kernel VMA (>= TASK_SIZE),
+ * and TLB entries with user ASID (>=4) have VMA < TASK_SIZE.
+ *
+ * Check that valid TLB entries either have the same PA as the PTE, or PTE is
+ * marked as non-present. Non-present PTE and the page with non-zero refcount
+ * and zero mapcount is normal for batched TLB flush operation. Zero refcount
+ * means that the page was freed prematurely. Non-zero mapcount is unusual,
+ * but does not necessary means an error, thus marked as suspicious.
+ */
+static int check_tlb_entry(unsigned w, unsigned e, bool dtlb)
+{
+	unsigned tlbidx = w | (e << PAGE_SHIFT);
+	unsigned r0 = dtlb ?
+		read_dtlb_virtual(tlbidx) : read_itlb_virtual(tlbidx);
+	unsigned vpn = (r0 & PAGE_MASK) | (e << PAGE_SHIFT);
+	unsigned pte = get_pte_for_vaddr(vpn);
+	unsigned mm_asid = (get_rasid_register() >> 8) & ASID_MASK;
+	unsigned tlb_asid = r0 & ASID_MASK;
+	bool kernel = tlb_asid == 1;
+	int rc = 0;
+
+	if (tlb_asid > 0 && ((vpn < TASK_SIZE) == kernel)) {
+		pr_err("%cTLB: way: %u, entry: %u, VPN %08x in %s PTE\n",
+				dtlb ? 'D' : 'I', w, e, vpn,
+				kernel ? "kernel" : "user");
+		rc |= TLB_INSANE;
+	}
+
+	if (tlb_asid == mm_asid) {
+		unsigned r1 = dtlb ? read_dtlb_translation(tlbidx) :
+			read_itlb_translation(tlbidx);
+		if ((pte ^ r1) & PAGE_MASK) {
+			pr_err("%cTLB: way: %u, entry: %u, mapping: %08x->%08x, PTE: %08x\n",
+					dtlb ? 'D' : 'I', w, e, r0, r1, pte);
+			if (pte == 0 || !pte_present(__pte(pte))) {
+				struct page *p = pfn_to_page(r1 >> PAGE_SHIFT);
+				pr_err("page refcount: %d, mapcount: %d\n",
+						page_count(p),
+						page_mapcount(p));
+				if (!page_count(p))
+					rc |= TLB_INSANE;
+				else if (page_mapped(p))
+					rc |= TLB_SUSPICIOUS;
+			} else {
+				rc |= TLB_INSANE;
+			}
+		}
+	}
+	return rc;
+}
+
+void check_tlb_sanity(void)
+{
+	unsigned long flags;
+	unsigned w, e;
+	int bug = 0;
+
+	local_irq_save(flags);
+	for (w = 0; w < DTLB_ARF_WAYS; ++w)
+		for (e = 0; e < (1 << XCHAL_DTLB_ARF_ENTRIES_LOG2); ++e)
+			bug |= check_tlb_entry(w, e, true);
+	for (w = 0; w < ITLB_ARF_WAYS; ++w)
+		for (e = 0; e < (1 << XCHAL_ITLB_ARF_ENTRIES_LOG2); ++e)
+			bug |= check_tlb_entry(w, e, false);
+	if (bug & TLB_INSANE)
+		tlb_insane();
+	if (bug & TLB_SUSPICIOUS)
+		tlb_suspicious();
+	local_irq_restore(flags);
+}
+
+#endif /* CONFIG_DEBUG_TLB_SANITY */
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/platforms/iss/network.c linux-libre-3.11-rc7-gnu/arch/xtensa/platforms/iss/network.c
--- linux-libre-3.10-gnu/arch/xtensa/platforms/iss/network.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/platforms/iss/network.c	2013-08-25 20:43:22.000000000 -0400
@@ -700,7 +700,7 @@ struct iss_net_init {
 
 #define ERR KERN_ERR "iss_net_setup: "
 
-static int iss_net_setup(char *str)
+static int __init iss_net_setup(char *str)
 {
 	struct iss_net_private *device = NULL;
 	struct iss_net_init *new;
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/platforms/iss/simdisk.c linux-libre-3.11-rc7-gnu/arch/xtensa/platforms/iss/simdisk.c
--- linux-libre-3.10-gnu/arch/xtensa/platforms/iss/simdisk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/platforms/iss/simdisk.c	2013-08-25 20:43:22.000000000 -0400
@@ -108,13 +108,13 @@ static int simdisk_xfer_bio(struct simdi
 	sector_t sector = bio->bi_sector;
 
 	bio_for_each_segment(bvec, bio, i) {
-		char *buffer = __bio_kmap_atomic(bio, i, KM_USER0);
+		char *buffer = __bio_kmap_atomic(bio, i);
 		unsigned len = bvec->bv_len >> SECTOR_SHIFT;
 
 		simdisk_transfer(dev, sector, len, buffer,
 				bio_data_dir(bio) == WRITE);
 		sector += len;
-		__bio_kunmap_atomic(bio, KM_USER0);
+		__bio_kunmap_atomic(bio);
 	}
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/platforms/xtfpga/setup.c linux-libre-3.11-rc7-gnu/arch/xtensa/platforms/xtfpga/setup.c
--- linux-libre-3.10-gnu/arch/xtensa/platforms/xtfpga/setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/platforms/xtfpga/setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -163,7 +163,7 @@ void platform_heartbeat(void)
 
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 
-void platform_calibrate_ccount(void)
+void __init platform_calibrate_ccount(void)
 {
 	long clk_freq = 0;
 #ifdef CONFIG_OF
@@ -179,8 +179,7 @@ void platform_calibrate_ccount(void)
 	if (!clk_freq)
 		clk_freq = *(long *)XTFPGA_CLKFRQ_VADDR;
 
-	ccount_per_jiffy = clk_freq / HZ;
-	nsec_per_ccount = 1000000000UL / clk_freq;
+	ccount_freq = clk_freq;
 }
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/arch/xtensa/variants/s6000/delay.c linux-libre-3.11-rc7-gnu/arch/xtensa/variants/s6000/delay.c
--- linux-libre-3.10-gnu/arch/xtensa/variants/s6000/delay.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/arch/xtensa/variants/s6000/delay.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,3 @@
-#include <asm/delay.h>
 #include <asm/timex.h>
 #include <asm/io.h>
 #include <variant/hardware.h>
@@ -17,11 +16,10 @@ void platform_calibrate_ccount(void)
 		"1:	l32i %0, %2, 0 ;"
 		"	beq %0, %1, 1b ;"
 		: "=&a"(u) : "a"(t), "a"(tstamp));
-		b = xtensa_get_ccount();
+		b = get_ccount();
 		if (i == LOOPS)
 			a = b;
 	} while (--i >= 0);
 	b -= a;
-	nsec_per_ccount = (LOOPS * 10000) / b;
-	ccount_per_jiffy = b * (100000UL / (LOOPS * HZ));
+	ccount_freq = b * (100000UL / LOOPS);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/block/blk-cgroup.c linux-libre-3.11-rc7-gnu/block/blk-cgroup.c
--- linux-libre-3.10-gnu/block/blk-cgroup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/blk-cgroup.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,26 +32,6 @@ EXPORT_SYMBOL_GPL(blkcg_root);
 
 static struct blkcg_policy *blkcg_policy[BLKCG_MAX_POLS];
 
-static struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
-				      struct request_queue *q, bool update_hint);
-
-/**
- * blkg_for_each_descendant_pre - pre-order walk of a blkg's descendants
- * @d_blkg: loop cursor pointing to the current descendant
- * @pos_cgrp: used for iteration
- * @p_blkg: target blkg to walk descendants of
- *
- * Walk @c_blkg through the descendants of @p_blkg.  Must be used with RCU
- * read locked.  If called under either blkcg or queue lock, the iteration
- * is guaranteed to include all and only online blkgs.  The caller may
- * update @pos_cgrp by calling cgroup_rightmost_descendant() to skip
- * subtree.
- */
-#define blkg_for_each_descendant_pre(d_blkg, pos_cgrp, p_blkg)		\
-	cgroup_for_each_descendant_pre((pos_cgrp), (p_blkg)->blkcg->css.cgroup) \
-		if (((d_blkg) = __blkg_lookup(cgroup_to_blkcg(pos_cgrp), \
-					      (p_blkg)->q, false)))
-
 static bool blkcg_policy_enabled(struct request_queue *q,
 				 const struct blkcg_policy *pol)
 {
@@ -71,18 +51,8 @@ static void blkg_free(struct blkcg_gq *b
 	if (!blkg)
 		return;
 
-	for (i = 0; i < BLKCG_MAX_POLS; i++) {
-		struct blkcg_policy *pol = blkcg_policy[i];
-		struct blkg_policy_data *pd = blkg->pd[i];
-
-		if (!pd)
-			continue;
-
-		if (pol && pol->pd_exit_fn)
-			pol->pd_exit_fn(blkg);
-
-		kfree(pd);
-	}
+	for (i = 0; i < BLKCG_MAX_POLS; i++)
+		kfree(blkg->pd[i]);
 
 	blk_exit_rl(&blkg->rl);
 	kfree(blkg);
@@ -134,10 +104,6 @@ static struct blkcg_gq *blkg_alloc(struc
 		blkg->pd[i] = pd;
 		pd->blkg = blkg;
 		pd->plid = i;
-
-		/* invoke per-policy init */
-		if (pol->pd_init_fn)
-			pol->pd_init_fn(blkg);
 	}
 
 	return blkg;
@@ -158,8 +124,8 @@ err_free:
  * @q's bypass state.  If @update_hint is %true, the caller should be
  * holding @q->queue_lock and lookup hint is updated on success.
  */
-static struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
-				      struct request_queue *q, bool update_hint)
+struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg, struct request_queue *q,
+			       bool update_hint)
 {
 	struct blkcg_gq *blkg;
 
@@ -234,16 +200,25 @@ static struct blkcg_gq *blkg_create(stru
 	}
 	blkg = new_blkg;
 
-	/* link parent and insert */
+	/* link parent */
 	if (blkcg_parent(blkcg)) {
 		blkg->parent = __blkg_lookup(blkcg_parent(blkcg), q, false);
 		if (WARN_ON_ONCE(!blkg->parent)) {
-			blkg = ERR_PTR(-EINVAL);
+			ret = -EINVAL;
 			goto err_put_css;
 		}
 		blkg_get(blkg->parent);
 	}
 
+	/* invoke per-policy init */
+	for (i = 0; i < BLKCG_MAX_POLS; i++) {
+		struct blkcg_policy *pol = blkcg_policy[i];
+
+		if (blkg->pd[i] && pol->pd_init_fn)
+			pol->pd_init_fn(blkg);
+	}
+
+	/* insert */
 	spin_lock(&blkcg->lock);
 	ret = radix_tree_insert(&blkcg->blkg_tree, q->id, blkg);
 	if (likely(!ret)) {
@@ -394,30 +369,38 @@ static void blkg_destroy_all(struct requ
 	q->root_rl.blkg = NULL;
 }
 
-static void blkg_rcu_free(struct rcu_head *rcu_head)
+/*
+ * A group is RCU protected, but having an rcu lock does not mean that one
+ * can access all the fields of blkg and assume these are valid.  For
+ * example, don't try to follow throtl_data and request queue links.
+ *
+ * Having a reference to blkg under an rcu allows accesses to only values
+ * local to groups like group stats and group rate limits.
+ */
+void __blkg_release_rcu(struct rcu_head *rcu_head)
 {
-	blkg_free(container_of(rcu_head, struct blkcg_gq, rcu_head));
-}
+	struct blkcg_gq *blkg = container_of(rcu_head, struct blkcg_gq, rcu_head);
+	int i;
+
+	/* tell policies that this one is being freed */
+	for (i = 0; i < BLKCG_MAX_POLS; i++) {
+		struct blkcg_policy *pol = blkcg_policy[i];
+
+		if (blkg->pd[i] && pol->pd_exit_fn)
+			pol->pd_exit_fn(blkg);
+	}
 
-void __blkg_release(struct blkcg_gq *blkg)
-{
 	/* release the blkcg and parent blkg refs this blkg has been holding */
 	css_put(&blkg->blkcg->css);
-	if (blkg->parent)
+	if (blkg->parent) {
+		spin_lock_irq(blkg->q->queue_lock);
 		blkg_put(blkg->parent);
+		spin_unlock_irq(blkg->q->queue_lock);
+	}
 
-	/*
-	 * A group is freed in rcu manner. But having an rcu lock does not
-	 * mean that one can access all the fields of blkg and assume these
-	 * are valid. For example, don't try to follow throtl_data and
-	 * request queue links.
-	 *
-	 * Having a reference to blkg under an rcu allows acess to only
-	 * values local to groups like group stats and group rate limits
-	 */
-	call_rcu(&blkg->rcu_head, blkg_rcu_free);
+	blkg_free(blkg);
 }
-EXPORT_SYMBOL_GPL(__blkg_release);
+EXPORT_SYMBOL_GPL(__blkg_release_rcu);
 
 /*
  * The next function used by blk_queue_for_each_rl().  It's a bit tricky
@@ -928,14 +911,6 @@ struct cgroup_subsys blkio_subsys = {
 	.subsys_id = blkio_subsys_id,
 	.base_cftypes = blkcg_files,
 	.module = THIS_MODULE,
-
-	/*
-	 * blkio subsystem is utterly broken in terms of hierarchy support.
-	 * It treats all cgroups equally regardless of where they're
-	 * located in the hierarchy - all cgroups are treated as if they're
-	 * right below the root.  Fix it and remove the following.
-	 */
-	.broken_hierarchy = true,
 };
 EXPORT_SYMBOL_GPL(blkio_subsys);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/block/blk-cgroup.h linux-libre-3.11-rc7-gnu/block/blk-cgroup.h
--- linux-libre-3.10-gnu/block/blk-cgroup.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/blk-cgroup.h	2013-08-25 20:43:22.000000000 -0400
@@ -266,7 +266,7 @@ static inline void blkg_get(struct blkcg
 	blkg->refcnt++;
 }
 
-void __blkg_release(struct blkcg_gq *blkg);
+void __blkg_release_rcu(struct rcu_head *rcu);
 
 /**
  * blkg_put - put a blkg reference
@@ -279,9 +279,43 @@ static inline void blkg_put(struct blkcg
 	lockdep_assert_held(blkg->q->queue_lock);
 	WARN_ON_ONCE(blkg->refcnt <= 0);
 	if (!--blkg->refcnt)
-		__blkg_release(blkg);
+		call_rcu(&blkg->rcu_head, __blkg_release_rcu);
 }
 
+struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg, struct request_queue *q,
+			       bool update_hint);
+
+/**
+ * blkg_for_each_descendant_pre - pre-order walk of a blkg's descendants
+ * @d_blkg: loop cursor pointing to the current descendant
+ * @pos_cgrp: used for iteration
+ * @p_blkg: target blkg to walk descendants of
+ *
+ * Walk @c_blkg through the descendants of @p_blkg.  Must be used with RCU
+ * read locked.  If called under either blkcg or queue lock, the iteration
+ * is guaranteed to include all and only online blkgs.  The caller may
+ * update @pos_cgrp by calling cgroup_rightmost_descendant() to skip
+ * subtree.
+ */
+#define blkg_for_each_descendant_pre(d_blkg, pos_cgrp, p_blkg)		\
+	cgroup_for_each_descendant_pre((pos_cgrp), (p_blkg)->blkcg->css.cgroup) \
+		if (((d_blkg) = __blkg_lookup(cgroup_to_blkcg(pos_cgrp), \
+					      (p_blkg)->q, false)))
+
+/**
+ * blkg_for_each_descendant_post - post-order walk of a blkg's descendants
+ * @d_blkg: loop cursor pointing to the current descendant
+ * @pos_cgrp: used for iteration
+ * @p_blkg: target blkg to walk descendants of
+ *
+ * Similar to blkg_for_each_descendant_pre() but performs post-order
+ * traversal instead.  Synchronization rules are the same.
+ */
+#define blkg_for_each_descendant_post(d_blkg, pos_cgrp, p_blkg)		\
+	cgroup_for_each_descendant_post((pos_cgrp), (p_blkg)->blkcg->css.cgroup) \
+		if (((d_blkg) = __blkg_lookup(cgroup_to_blkcg(pos_cgrp), \
+					      (p_blkg)->q, false)))
+
 /**
  * blk_get_rl - get request_list to use
  * @q: request_queue of interest
diff -druNp --no-dereference linux-libre-3.10-gnu/block/blk-core.c linux-libre-3.11-rc7-gnu/block/blk-core.c
--- linux-libre-3.10-gnu/block/blk-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/blk-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -2315,6 +2315,9 @@ bool blk_update_request(struct request *
 		case -EBADE:
 			error_type = "critical nexus";
 			break;
+		case -ETIMEDOUT:
+			error_type = "timeout";
+			break;
 		case -EIO:
 		default:
 			error_type = "I/O";
@@ -3180,7 +3183,8 @@ int __init blk_dev_init(void)
 
 	/* used for unplugging and affects IO latency/throughput - HIGHPRI */
 	kblockd_workqueue = alloc_workqueue("kblockd",
-					    WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
+					    WQ_MEM_RECLAIM | WQ_HIGHPRI |
+					    WQ_POWER_EFFICIENT, 0);
 	if (!kblockd_workqueue)
 		panic("Failed to create kblockd\n");
 
diff -druNp --no-dereference linux-libre-3.10-gnu/block/blk-ioc.c linux-libre-3.11-rc7-gnu/block/blk-ioc.c
--- linux-libre-3.10-gnu/block/blk-ioc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/blk-ioc.c	2013-08-25 20:43:22.000000000 -0400
@@ -144,7 +144,8 @@ void put_io_context(struct io_context *i
 	if (atomic_long_dec_and_test(&ioc->refcount)) {
 		spin_lock_irqsave(&ioc->lock, flags);
 		if (!hlist_empty(&ioc->icq_list))
-			schedule_work(&ioc->release_work);
+			queue_work(system_power_efficient_wq,
+					&ioc->release_work);
 		else
 			free_ioc = true;
 		spin_unlock_irqrestore(&ioc->lock, flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/block/blk-iopoll.c linux-libre-3.11-rc7-gnu/block/blk-iopoll.c
--- linux-libre-3.10-gnu/block/blk-iopoll.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/blk-iopoll.c	2013-08-25 20:43:22.000000000 -0400
@@ -189,8 +189,8 @@ void blk_iopoll_init(struct blk_iopoll *
 }
 EXPORT_SYMBOL(blk_iopoll_init);
 
-static int __cpuinit blk_iopoll_cpu_notify(struct notifier_block *self,
-					  unsigned long action, void *hcpu)
+static int blk_iopoll_cpu_notify(struct notifier_block *self,
+				 unsigned long action, void *hcpu)
 {
 	/*
 	 * If a CPU goes away, splice its entries to the current CPU
@@ -209,7 +209,7 @@ static int __cpuinit blk_iopoll_cpu_noti
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata blk_iopoll_cpu_notifier = {
+static struct notifier_block blk_iopoll_cpu_notifier = {
 	.notifier_call	= blk_iopoll_cpu_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/block/blk-softirq.c linux-libre-3.11-rc7-gnu/block/blk-softirq.c
--- linux-libre-3.10-gnu/block/blk-softirq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/blk-softirq.c	2013-08-25 20:43:22.000000000 -0400
@@ -78,8 +78,8 @@ static int raise_blk_irq(int cpu, struct
 }
 #endif
 
-static int __cpuinit blk_cpu_notify(struct notifier_block *self,
-				    unsigned long action, void *hcpu)
+static int blk_cpu_notify(struct notifier_block *self, unsigned long action,
+			  void *hcpu)
 {
 	/*
 	 * If a CPU goes away, splice its entries to the current CPU
@@ -98,7 +98,7 @@ static int __cpuinit blk_cpu_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata blk_cpu_notifier = {
+static struct notifier_block blk_cpu_notifier = {
 	.notifier_call	= blk_cpu_notify,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/block/blk-tag.c linux-libre-3.11-rc7-gnu/block/blk-tag.c
--- linux-libre-3.10-gnu/block/blk-tag.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/blk-tag.c	2013-08-25 20:43:22.000000000 -0400
@@ -348,9 +348,16 @@ int blk_queue_start_tag(struct request_q
 	 */
 	max_depth = bqt->max_depth;
 	if (!rq_is_sync(rq) && max_depth > 1) {
-		max_depth -= 2;
-		if (!max_depth)
+		switch (max_depth) {
+		case 2:
 			max_depth = 1;
+			break;
+		case 3:
+			max_depth = 2;
+			break;
+		default:
+			max_depth -= 2;
+		}
 		if (q->in_flight[BLK_RW_ASYNC] > max_depth)
 			return 1;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/block/blk-throttle.c linux-libre-3.11-rc7-gnu/block/blk-throttle.c
--- linux-libre-3.10-gnu/block/blk-throttle.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/blk-throttle.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,18 +25,61 @@ static struct blkcg_policy blkcg_policy_
 
 /* A workqueue to queue throttle related work */
 static struct workqueue_struct *kthrotld_workqueue;
-static void throtl_schedule_delayed_work(struct throtl_data *td,
-				unsigned long delay);
 
-struct throtl_rb_root {
-	struct rb_root rb;
-	struct rb_node *left;
-	unsigned int count;
-	unsigned long min_disptime;
+/*
+ * To implement hierarchical throttling, throtl_grps form a tree and bios
+ * are dispatched upwards level by level until they reach the top and get
+ * issued.  When dispatching bios from the children and local group at each
+ * level, if the bios are dispatched into a single bio_list, there's a risk
+ * of a local or child group which can queue many bios at once filling up
+ * the list starving others.
+ *
+ * To avoid such starvation, dispatched bios are queued separately
+ * according to where they came from.  When they are again dispatched to
+ * the parent, they're popped in round-robin order so that no single source
+ * hogs the dispatch window.
+ *
+ * throtl_qnode is used to keep the queued bios separated by their sources.
+ * Bios are queued to throtl_qnode which in turn is queued to
+ * throtl_service_queue and then dispatched in round-robin order.
+ *
+ * It's also used to track the reference counts on blkg's.  A qnode always
+ * belongs to a throtl_grp and gets queued on itself or the parent, so
+ * incrementing the reference of the associated throtl_grp when a qnode is
+ * queued and decrementing when dequeued is enough to keep the whole blkg
+ * tree pinned while bios are in flight.
+ */
+struct throtl_qnode {
+	struct list_head	node;		/* service_queue->queued[] */
+	struct bio_list		bios;		/* queued bios */
+	struct throtl_grp	*tg;		/* tg this qnode belongs to */
 };
 
-#define THROTL_RB_ROOT	(struct throtl_rb_root) { .rb = RB_ROOT, .left = NULL, \
-			.count = 0, .min_disptime = 0}
+struct throtl_service_queue {
+	struct throtl_service_queue *parent_sq;	/* the parent service_queue */
+
+	/*
+	 * Bios queued directly to this service_queue or dispatched from
+	 * children throtl_grp's.
+	 */
+	struct list_head	queued[2];	/* throtl_qnode [READ/WRITE] */
+	unsigned int		nr_queued[2];	/* number of queued bios */
+
+	/*
+	 * RB tree of active children throtl_grp's, which are sorted by
+	 * their ->disptime.
+	 */
+	struct rb_root		pending_tree;	/* RB tree of active tgs */
+	struct rb_node		*first_pending;	/* first node in the tree */
+	unsigned int		nr_pending;	/* # queued in the tree */
+	unsigned long		first_pending_disptime;	/* disptime of the first tg */
+	struct timer_list	pending_timer;	/* fires on first_pending_disptime */
+};
+
+enum tg_state_flags {
+	THROTL_TG_PENDING	= 1 << 0,	/* on parent's pending tree */
+	THROTL_TG_WAS_EMPTY	= 1 << 1,	/* bio_lists[] became non-empty */
+};
 
 #define rb_entry_tg(node)	rb_entry((node), struct throtl_grp, rb_node)
 
@@ -52,9 +95,26 @@ struct throtl_grp {
 	/* must be the first member */
 	struct blkg_policy_data pd;
 
-	/* active throtl group service_tree member */
+	/* active throtl group service_queue member */
 	struct rb_node rb_node;
 
+	/* throtl_data this group belongs to */
+	struct throtl_data *td;
+
+	/* this group's service queue */
+	struct throtl_service_queue service_queue;
+
+	/*
+	 * qnode_on_self is used when bios are directly queued to this
+	 * throtl_grp so that local bios compete fairly with bios
+	 * dispatched from children.  qnode_on_parent is used when bios are
+	 * dispatched from this throtl_grp into its parent and will compete
+	 * with the sibling qnode_on_parents and the parent's
+	 * qnode_on_self.
+	 */
+	struct throtl_qnode qnode_on_self[2];
+	struct throtl_qnode qnode_on_parent[2];
+
 	/*
 	 * Dispatch time in jiffies. This is the estimated time when group
 	 * will unthrottle and is ready to dispatch more bio. It is used as
@@ -64,11 +124,8 @@ struct throtl_grp {
 
 	unsigned int flags;
 
-	/* Two lists for READ and WRITE */
-	struct bio_list bio_lists[2];
-
-	/* Number of queued bios on READ and WRITE lists */
-	unsigned int nr_queued[2];
+	/* are there any throtl rules between this group and td? */
+	bool has_rules[2];
 
 	/* bytes per second rate limits */
 	uint64_t bps[2];
@@ -85,9 +142,6 @@ struct throtl_grp {
 	unsigned long slice_start[2];
 	unsigned long slice_end[2];
 
-	/* Some throttle limits got updated for the group */
-	int limits_changed;
-
 	/* Per cpu stats pointer */
 	struct tg_stats_cpu __percpu *stats_cpu;
 
@@ -98,7 +152,7 @@ struct throtl_grp {
 struct throtl_data
 {
 	/* service tree for active throtl groups */
-	struct throtl_rb_root tg_service_tree;
+	struct throtl_service_queue service_queue;
 
 	struct request_queue *queue;
 
@@ -111,9 +165,7 @@ struct throtl_data
 	unsigned int nr_undestroyed_grps;
 
 	/* Work for dispatching throttled bios */
-	struct delayed_work throtl_work;
-
-	int limits_changed;
+	struct work_struct dispatch_work;
 };
 
 /* list and work item to allocate percpu group stats */
@@ -123,6 +175,8 @@ static LIST_HEAD(tg_stats_alloc_list);
 static void tg_stats_alloc_fn(struct work_struct *);
 static DECLARE_DELAYED_WORK(tg_stats_alloc_work, tg_stats_alloc_fn);
 
+static void throtl_pending_timer_fn(unsigned long arg);
+
 static inline struct throtl_grp *pd_to_tg(struct blkg_policy_data *pd)
 {
 	return pd ? container_of(pd, struct throtl_grp, pd) : NULL;
@@ -143,41 +197,65 @@ static inline struct throtl_grp *td_root
 	return blkg_to_tg(td->queue->root_blkg);
 }
 
-enum tg_state_flags {
-	THROTL_TG_FLAG_on_rr = 0,	/* on round-robin busy list */
-};
-
-#define THROTL_TG_FNS(name)						\
-static inline void throtl_mark_tg_##name(struct throtl_grp *tg)		\
-{									\
-	(tg)->flags |= (1 << THROTL_TG_FLAG_##name);			\
-}									\
-static inline void throtl_clear_tg_##name(struct throtl_grp *tg)	\
-{									\
-	(tg)->flags &= ~(1 << THROTL_TG_FLAG_##name);			\
-}									\
-static inline int throtl_tg_##name(const struct throtl_grp *tg)		\
-{									\
-	return ((tg)->flags & (1 << THROTL_TG_FLAG_##name)) != 0;	\
+/**
+ * sq_to_tg - return the throl_grp the specified service queue belongs to
+ * @sq: the throtl_service_queue of interest
+ *
+ * Return the throtl_grp @sq belongs to.  If @sq is the top-level one
+ * embedded in throtl_data, %NULL is returned.
+ */
+static struct throtl_grp *sq_to_tg(struct throtl_service_queue *sq)
+{
+	if (sq && sq->parent_sq)
+		return container_of(sq, struct throtl_grp, service_queue);
+	else
+		return NULL;
 }
 
-THROTL_TG_FNS(on_rr);
+/**
+ * sq_to_td - return throtl_data the specified service queue belongs to
+ * @sq: the throtl_service_queue of interest
+ *
+ * A service_queue can be embeded in either a throtl_grp or throtl_data.
+ * Determine the associated throtl_data accordingly and return it.
+ */
+static struct throtl_data *sq_to_td(struct throtl_service_queue *sq)
+{
+	struct throtl_grp *tg = sq_to_tg(sq);
 
-#define throtl_log_tg(td, tg, fmt, args...)	do {			\
-	char __pbuf[128];						\
+	if (tg)
+		return tg->td;
+	else
+		return container_of(sq, struct throtl_data, service_queue);
+}
+
+/**
+ * throtl_log - log debug message via blktrace
+ * @sq: the service_queue being reported
+ * @fmt: printf format string
+ * @args: printf args
+ *
+ * The messages are prefixed with "throtl BLKG_NAME" if @sq belongs to a
+ * throtl_grp; otherwise, just "throtl".
+ *
+ * TODO: this should be made a function and name formatting should happen
+ * after testing whether blktrace is enabled.
+ */
+#define throtl_log(sq, fmt, args...)	do {				\
+	struct throtl_grp *__tg = sq_to_tg((sq));			\
+	struct throtl_data *__td = sq_to_td((sq));			\
 									\
-	blkg_path(tg_to_blkg(tg), __pbuf, sizeof(__pbuf));		\
-	blk_add_trace_msg((td)->queue, "throtl %s " fmt, __pbuf, ##args); \
+	(void)__td;							\
+	if ((__tg)) {							\
+		char __pbuf[128];					\
+									\
+		blkg_path(tg_to_blkg(__tg), __pbuf, sizeof(__pbuf));	\
+		blk_add_trace_msg(__td->queue, "throtl %s " fmt, __pbuf, ##args); \
+	} else {							\
+		blk_add_trace_msg(__td->queue, "throtl " fmt, ##args);	\
+	}								\
 } while (0)
 
-#define throtl_log(td, fmt, args...)	\
-	blk_add_trace_msg((td)->queue, "throtl " fmt, ##args)
-
-static inline unsigned int total_nr_queued(struct throtl_data *td)
-{
-	return td->nr_queued[0] + td->nr_queued[1];
-}
-
 /*
  * Worker for allocating per cpu stat for tgs. This is scheduled on the
  * system_wq once there are some groups on the alloc_list waiting for
@@ -215,15 +293,141 @@ alloc_stats:
 		goto alloc_stats;
 }
 
+static void throtl_qnode_init(struct throtl_qnode *qn, struct throtl_grp *tg)
+{
+	INIT_LIST_HEAD(&qn->node);
+	bio_list_init(&qn->bios);
+	qn->tg = tg;
+}
+
+/**
+ * throtl_qnode_add_bio - add a bio to a throtl_qnode and activate it
+ * @bio: bio being added
+ * @qn: qnode to add bio to
+ * @queued: the service_queue->queued[] list @qn belongs to
+ *
+ * Add @bio to @qn and put @qn on @queued if it's not already on.
+ * @qn->tg's reference count is bumped when @qn is activated.  See the
+ * comment on top of throtl_qnode definition for details.
+ */
+static void throtl_qnode_add_bio(struct bio *bio, struct throtl_qnode *qn,
+				 struct list_head *queued)
+{
+	bio_list_add(&qn->bios, bio);
+	if (list_empty(&qn->node)) {
+		list_add_tail(&qn->node, queued);
+		blkg_get(tg_to_blkg(qn->tg));
+	}
+}
+
+/**
+ * throtl_peek_queued - peek the first bio on a qnode list
+ * @queued: the qnode list to peek
+ */
+static struct bio *throtl_peek_queued(struct list_head *queued)
+{
+	struct throtl_qnode *qn = list_first_entry(queued, struct throtl_qnode, node);
+	struct bio *bio;
+
+	if (list_empty(queued))
+		return NULL;
+
+	bio = bio_list_peek(&qn->bios);
+	WARN_ON_ONCE(!bio);
+	return bio;
+}
+
+/**
+ * throtl_pop_queued - pop the first bio form a qnode list
+ * @queued: the qnode list to pop a bio from
+ * @tg_to_put: optional out argument for throtl_grp to put
+ *
+ * Pop the first bio from the qnode list @queued.  After popping, the first
+ * qnode is removed from @queued if empty or moved to the end of @queued so
+ * that the popping order is round-robin.
+ *
+ * When the first qnode is removed, its associated throtl_grp should be put
+ * too.  If @tg_to_put is NULL, this function automatically puts it;
+ * otherwise, *@tg_to_put is set to the throtl_grp to put and the caller is
+ * responsible for putting it.
+ */
+static struct bio *throtl_pop_queued(struct list_head *queued,
+				     struct throtl_grp **tg_to_put)
+{
+	struct throtl_qnode *qn = list_first_entry(queued, struct throtl_qnode, node);
+	struct bio *bio;
+
+	if (list_empty(queued))
+		return NULL;
+
+	bio = bio_list_pop(&qn->bios);
+	WARN_ON_ONCE(!bio);
+
+	if (bio_list_empty(&qn->bios)) {
+		list_del_init(&qn->node);
+		if (tg_to_put)
+			*tg_to_put = qn->tg;
+		else
+			blkg_put(tg_to_blkg(qn->tg));
+	} else {
+		list_move_tail(&qn->node, queued);
+	}
+
+	return bio;
+}
+
+/* init a service_queue, assumes the caller zeroed it */
+static void throtl_service_queue_init(struct throtl_service_queue *sq,
+				      struct throtl_service_queue *parent_sq)
+{
+	INIT_LIST_HEAD(&sq->queued[0]);
+	INIT_LIST_HEAD(&sq->queued[1]);
+	sq->pending_tree = RB_ROOT;
+	sq->parent_sq = parent_sq;
+	setup_timer(&sq->pending_timer, throtl_pending_timer_fn,
+		    (unsigned long)sq);
+}
+
+static void throtl_service_queue_exit(struct throtl_service_queue *sq)
+{
+	del_timer_sync(&sq->pending_timer);
+}
+
 static void throtl_pd_init(struct blkcg_gq *blkg)
 {
 	struct throtl_grp *tg = blkg_to_tg(blkg);
+	struct throtl_data *td = blkg->q->td;
+	struct throtl_service_queue *parent_sq;
 	unsigned long flags;
+	int rw;
+
+	/*
+	 * If sane_hierarchy is enabled, we switch to properly hierarchical
+	 * behavior where limits on a given throtl_grp are applied to the
+	 * whole subtree rather than just the group itself.  e.g. If 16M
+	 * read_bps limit is set on the root group, the whole system can't
+	 * exceed 16M for the device.
+	 *
+	 * If sane_hierarchy is not enabled, the broken flat hierarchy
+	 * behavior is retained where all throtl_grps are treated as if
+	 * they're all separate root groups right below throtl_data.
+	 * Limits of a group don't interact with limits of other groups
+	 * regardless of the position of the group in the hierarchy.
+	 */
+	parent_sq = &td->service_queue;
+
+	if (cgroup_sane_behavior(blkg->blkcg->css.cgroup) && blkg->parent)
+		parent_sq = &blkg_to_tg(blkg->parent)->service_queue;
+
+	throtl_service_queue_init(&tg->service_queue, parent_sq);
+
+	for (rw = READ; rw <= WRITE; rw++) {
+		throtl_qnode_init(&tg->qnode_on_self[rw], tg);
+		throtl_qnode_init(&tg->qnode_on_parent[rw], tg);
+	}
 
 	RB_CLEAR_NODE(&tg->rb_node);
-	bio_list_init(&tg->bio_lists[0]);
-	bio_list_init(&tg->bio_lists[1]);
-	tg->limits_changed = false;
+	tg->td = td;
 
 	tg->bps[READ] = -1;
 	tg->bps[WRITE] = -1;
@@ -241,6 +445,30 @@ static void throtl_pd_init(struct blkcg_
 	spin_unlock_irqrestore(&tg_stats_alloc_lock, flags);
 }
 
+/*
+ * Set has_rules[] if @tg or any of its parents have limits configured.
+ * This doesn't require walking up to the top of the hierarchy as the
+ * parent's has_rules[] is guaranteed to be correct.
+ */
+static void tg_update_has_rules(struct throtl_grp *tg)
+{
+	struct throtl_grp *parent_tg = sq_to_tg(tg->service_queue.parent_sq);
+	int rw;
+
+	for (rw = READ; rw <= WRITE; rw++)
+		tg->has_rules[rw] = (parent_tg && parent_tg->has_rules[rw]) ||
+				    (tg->bps[rw] != -1 || tg->iops[rw] != -1);
+}
+
+static void throtl_pd_online(struct blkcg_gq *blkg)
+{
+	/*
+	 * We don't want new groups to escape the limits of its ancestors.
+	 * Update has_rules[] after a new group is brought online.
+	 */
+	tg_update_has_rules(blkg_to_tg(blkg));
+}
+
 static void throtl_pd_exit(struct blkcg_gq *blkg)
 {
 	struct throtl_grp *tg = blkg_to_tg(blkg);
@@ -251,6 +479,8 @@ static void throtl_pd_exit(struct blkcg_
 	spin_unlock_irqrestore(&tg_stats_alloc_lock, flags);
 
 	free_percpu(tg->stats_cpu);
+
+	throtl_service_queue_exit(&tg->service_queue);
 }
 
 static void throtl_pd_reset_stats(struct blkcg_gq *blkg)
@@ -309,17 +539,18 @@ static struct throtl_grp *throtl_lookup_
 	return tg;
 }
 
-static struct throtl_grp *throtl_rb_first(struct throtl_rb_root *root)
+static struct throtl_grp *
+throtl_rb_first(struct throtl_service_queue *parent_sq)
 {
 	/* Service tree is empty */
-	if (!root->count)
+	if (!parent_sq->nr_pending)
 		return NULL;
 
-	if (!root->left)
-		root->left = rb_first(&root->rb);
+	if (!parent_sq->first_pending)
+		parent_sq->first_pending = rb_first(&parent_sq->pending_tree);
 
-	if (root->left)
-		return rb_entry_tg(root->left);
+	if (parent_sq->first_pending)
+		return rb_entry_tg(parent_sq->first_pending);
 
 	return NULL;
 }
@@ -330,29 +561,30 @@ static void rb_erase_init(struct rb_node
 	RB_CLEAR_NODE(n);
 }
 
-static void throtl_rb_erase(struct rb_node *n, struct throtl_rb_root *root)
+static void throtl_rb_erase(struct rb_node *n,
+			    struct throtl_service_queue *parent_sq)
 {
-	if (root->left == n)
-		root->left = NULL;
-	rb_erase_init(n, &root->rb);
-	--root->count;
+	if (parent_sq->first_pending == n)
+		parent_sq->first_pending = NULL;
+	rb_erase_init(n, &parent_sq->pending_tree);
+	--parent_sq->nr_pending;
 }
 
-static void update_min_dispatch_time(struct throtl_rb_root *st)
+static void update_min_dispatch_time(struct throtl_service_queue *parent_sq)
 {
 	struct throtl_grp *tg;
 
-	tg = throtl_rb_first(st);
+	tg = throtl_rb_first(parent_sq);
 	if (!tg)
 		return;
 
-	st->min_disptime = tg->disptime;
+	parent_sq->first_pending_disptime = tg->disptime;
 }
 
-static void
-tg_service_tree_add(struct throtl_rb_root *st, struct throtl_grp *tg)
+static void tg_service_queue_add(struct throtl_grp *tg)
 {
-	struct rb_node **node = &st->rb.rb_node;
+	struct throtl_service_queue *parent_sq = tg->service_queue.parent_sq;
+	struct rb_node **node = &parent_sq->pending_tree.rb_node;
 	struct rb_node *parent = NULL;
 	struct throtl_grp *__tg;
 	unsigned long key = tg->disptime;
@@ -371,89 +603,135 @@ tg_service_tree_add(struct throtl_rb_roo
 	}
 
 	if (left)
-		st->left = &tg->rb_node;
+		parent_sq->first_pending = &tg->rb_node;
 
 	rb_link_node(&tg->rb_node, parent, node);
-	rb_insert_color(&tg->rb_node, &st->rb);
+	rb_insert_color(&tg->rb_node, &parent_sq->pending_tree);
 }
 
-static void __throtl_enqueue_tg(struct throtl_data *td, struct throtl_grp *tg)
+static void __throtl_enqueue_tg(struct throtl_grp *tg)
 {
-	struct throtl_rb_root *st = &td->tg_service_tree;
+	tg_service_queue_add(tg);
+	tg->flags |= THROTL_TG_PENDING;
+	tg->service_queue.parent_sq->nr_pending++;
+}
 
-	tg_service_tree_add(st, tg);
-	throtl_mark_tg_on_rr(tg);
-	st->count++;
+static void throtl_enqueue_tg(struct throtl_grp *tg)
+{
+	if (!(tg->flags & THROTL_TG_PENDING))
+		__throtl_enqueue_tg(tg);
 }
 
-static void throtl_enqueue_tg(struct throtl_data *td, struct throtl_grp *tg)
+static void __throtl_dequeue_tg(struct throtl_grp *tg)
 {
-	if (!throtl_tg_on_rr(tg))
-		__throtl_enqueue_tg(td, tg);
+	throtl_rb_erase(&tg->rb_node, tg->service_queue.parent_sq);
+	tg->flags &= ~THROTL_TG_PENDING;
 }
 
-static void __throtl_dequeue_tg(struct throtl_data *td, struct throtl_grp *tg)
+static void throtl_dequeue_tg(struct throtl_grp *tg)
 {
-	throtl_rb_erase(&tg->rb_node, &td->tg_service_tree);
-	throtl_clear_tg_on_rr(tg);
+	if (tg->flags & THROTL_TG_PENDING)
+		__throtl_dequeue_tg(tg);
 }
 
-static void throtl_dequeue_tg(struct throtl_data *td, struct throtl_grp *tg)
+/* Call with queue lock held */
+static void throtl_schedule_pending_timer(struct throtl_service_queue *sq,
+					  unsigned long expires)
 {
-	if (throtl_tg_on_rr(tg))
-		__throtl_dequeue_tg(td, tg);
+	mod_timer(&sq->pending_timer, expires);
+	throtl_log(sq, "schedule timer. delay=%lu jiffies=%lu",
+		   expires - jiffies, jiffies);
 }
 
-static void throtl_schedule_next_dispatch(struct throtl_data *td)
+/**
+ * throtl_schedule_next_dispatch - schedule the next dispatch cycle
+ * @sq: the service_queue to schedule dispatch for
+ * @force: force scheduling
+ *
+ * Arm @sq->pending_timer so that the next dispatch cycle starts on the
+ * dispatch time of the first pending child.  Returns %true if either timer
+ * is armed or there's no pending child left.  %false if the current
+ * dispatch window is still open and the caller should continue
+ * dispatching.
+ *
+ * If @force is %true, the dispatch timer is always scheduled and this
+ * function is guaranteed to return %true.  This is to be used when the
+ * caller can't dispatch itself and needs to invoke pending_timer
+ * unconditionally.  Note that forced scheduling is likely to induce short
+ * delay before dispatch starts even if @sq->first_pending_disptime is not
+ * in the future and thus shouldn't be used in hot paths.
+ */
+static bool throtl_schedule_next_dispatch(struct throtl_service_queue *sq,
+					  bool force)
 {
-	struct throtl_rb_root *st = &td->tg_service_tree;
+	/* any pending children left? */
+	if (!sq->nr_pending)
+		return true;
 
-	/*
-	 * If there are more bios pending, schedule more work.
-	 */
-	if (!total_nr_queued(td))
-		return;
+	update_min_dispatch_time(sq);
 
-	BUG_ON(!st->count);
+	/* is the next dispatch time in the future? */
+	if (force || time_after(sq->first_pending_disptime, jiffies)) {
+		throtl_schedule_pending_timer(sq, sq->first_pending_disptime);
+		return true;
+	}
 
-	update_min_dispatch_time(st);
+	/* tell the caller to continue dispatching */
+	return false;
+}
 
-	if (time_before_eq(st->min_disptime, jiffies))
-		throtl_schedule_delayed_work(td, 0);
-	else
-		throtl_schedule_delayed_work(td, (st->min_disptime - jiffies));
+static inline void throtl_start_new_slice_with_credit(struct throtl_grp *tg,
+		bool rw, unsigned long start)
+{
+	tg->bytes_disp[rw] = 0;
+	tg->io_disp[rw] = 0;
+
+	/*
+	 * Previous slice has expired. We must have trimmed it after last
+	 * bio dispatch. That means since start of last slice, we never used
+	 * that bandwidth. Do try to make use of that bandwidth while giving
+	 * credit.
+	 */
+	if (time_after_eq(start, tg->slice_start[rw]))
+		tg->slice_start[rw] = start;
+
+	tg->slice_end[rw] = jiffies + throtl_slice;
+	throtl_log(&tg->service_queue,
+		   "[%c] new slice with credit start=%lu end=%lu jiffies=%lu",
+		   rw == READ ? 'R' : 'W', tg->slice_start[rw],
+		   tg->slice_end[rw], jiffies);
 }
 
-static inline void
-throtl_start_new_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw)
+static inline void throtl_start_new_slice(struct throtl_grp *tg, bool rw)
 {
 	tg->bytes_disp[rw] = 0;
 	tg->io_disp[rw] = 0;
 	tg->slice_start[rw] = jiffies;
 	tg->slice_end[rw] = jiffies + throtl_slice;
-	throtl_log_tg(td, tg, "[%c] new slice start=%lu end=%lu jiffies=%lu",
-			rw == READ ? 'R' : 'W', tg->slice_start[rw],
-			tg->slice_end[rw], jiffies);
+	throtl_log(&tg->service_queue,
+		   "[%c] new slice start=%lu end=%lu jiffies=%lu",
+		   rw == READ ? 'R' : 'W', tg->slice_start[rw],
+		   tg->slice_end[rw], jiffies);
 }
 
-static inline void throtl_set_slice_end(struct throtl_data *td,
-		struct throtl_grp *tg, bool rw, unsigned long jiffy_end)
+static inline void throtl_set_slice_end(struct throtl_grp *tg, bool rw,
+					unsigned long jiffy_end)
 {
 	tg->slice_end[rw] = roundup(jiffy_end, throtl_slice);
 }
 
-static inline void throtl_extend_slice(struct throtl_data *td,
-		struct throtl_grp *tg, bool rw, unsigned long jiffy_end)
+static inline void throtl_extend_slice(struct throtl_grp *tg, bool rw,
+				       unsigned long jiffy_end)
 {
 	tg->slice_end[rw] = roundup(jiffy_end, throtl_slice);
-	throtl_log_tg(td, tg, "[%c] extend slice start=%lu end=%lu jiffies=%lu",
-			rw == READ ? 'R' : 'W', tg->slice_start[rw],
-			tg->slice_end[rw], jiffies);
+	throtl_log(&tg->service_queue,
+		   "[%c] extend slice start=%lu end=%lu jiffies=%lu",
+		   rw == READ ? 'R' : 'W', tg->slice_start[rw],
+		   tg->slice_end[rw], jiffies);
 }
 
 /* Determine if previously allocated or extended slice is complete or not */
-static bool
-throtl_slice_used(struct throtl_data *td, struct throtl_grp *tg, bool rw)
+static bool throtl_slice_used(struct throtl_grp *tg, bool rw)
 {
 	if (time_in_range(jiffies, tg->slice_start[rw], tg->slice_end[rw]))
 		return 0;
@@ -462,8 +740,7 @@ throtl_slice_used(struct throtl_data *td
 }
 
 /* Trim the used slices and adjust slice start accordingly */
-static inline void
-throtl_trim_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw)
+static inline void throtl_trim_slice(struct throtl_grp *tg, bool rw)
 {
 	unsigned long nr_slices, time_elapsed, io_trim;
 	u64 bytes_trim, tmp;
@@ -475,7 +752,7 @@ throtl_trim_slice(struct throtl_data *td
 	 * renewed. Don't try to trim the slice if slice is used. A new
 	 * slice will start when appropriate.
 	 */
-	if (throtl_slice_used(td, tg, rw))
+	if (throtl_slice_used(tg, rw))
 		return;
 
 	/*
@@ -486,7 +763,7 @@ throtl_trim_slice(struct throtl_data *td
 	 * is bad because it does not allow new slice to start.
 	 */
 
-	throtl_set_slice_end(td, tg, rw, jiffies + throtl_slice);
+	throtl_set_slice_end(tg, rw, jiffies + throtl_slice);
 
 	time_elapsed = jiffies - tg->slice_start[rw];
 
@@ -515,14 +792,14 @@ throtl_trim_slice(struct throtl_data *td
 
 	tg->slice_start[rw] += nr_slices * throtl_slice;
 
-	throtl_log_tg(td, tg, "[%c] trim slice nr=%lu bytes=%llu io=%lu"
-			" start=%lu end=%lu jiffies=%lu",
-			rw == READ ? 'R' : 'W', nr_slices, bytes_trim, io_trim,
-			tg->slice_start[rw], tg->slice_end[rw], jiffies);
+	throtl_log(&tg->service_queue,
+		   "[%c] trim slice nr=%lu bytes=%llu io=%lu start=%lu end=%lu jiffies=%lu",
+		   rw == READ ? 'R' : 'W', nr_slices, bytes_trim, io_trim,
+		   tg->slice_start[rw], tg->slice_end[rw], jiffies);
 }
 
-static bool tg_with_in_iops_limit(struct throtl_data *td, struct throtl_grp *tg,
-		struct bio *bio, unsigned long *wait)
+static bool tg_with_in_iops_limit(struct throtl_grp *tg, struct bio *bio,
+				  unsigned long *wait)
 {
 	bool rw = bio_data_dir(bio);
 	unsigned int io_allowed;
@@ -571,8 +848,8 @@ static bool tg_with_in_iops_limit(struct
 	return 0;
 }
 
-static bool tg_with_in_bps_limit(struct throtl_data *td, struct throtl_grp *tg,
-		struct bio *bio, unsigned long *wait)
+static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio,
+				 unsigned long *wait)
 {
 	bool rw = bio_data_dir(bio);
 	u64 bytes_allowed, extra_bytes, tmp;
@@ -613,18 +890,12 @@ static bool tg_with_in_bps_limit(struct
 	return 0;
 }
 
-static bool tg_no_rule_group(struct throtl_grp *tg, bool rw) {
-	if (tg->bps[rw] == -1 && tg->iops[rw] == -1)
-		return 1;
-	return 0;
-}
-
 /*
  * Returns whether one can dispatch a bio or not. Also returns approx number
  * of jiffies to wait before this bio is with-in IO rate and can be dispatched
  */
-static bool tg_may_dispatch(struct throtl_data *td, struct throtl_grp *tg,
-				struct bio *bio, unsigned long *wait)
+static bool tg_may_dispatch(struct throtl_grp *tg, struct bio *bio,
+			    unsigned long *wait)
 {
 	bool rw = bio_data_dir(bio);
 	unsigned long bps_wait = 0, iops_wait = 0, max_wait = 0;
@@ -635,7 +906,8 @@ static bool tg_may_dispatch(struct throt
 	 * this function with a different bio if there are other bios
 	 * queued.
 	 */
-	BUG_ON(tg->nr_queued[rw] && bio != bio_list_peek(&tg->bio_lists[rw]));
+	BUG_ON(tg->service_queue.nr_queued[rw] &&
+	       bio != throtl_peek_queued(&tg->service_queue.queued[rw]));
 
 	/* If tg->bps = -1, then BW is unlimited */
 	if (tg->bps[rw] == -1 && tg->iops[rw] == -1) {
@@ -649,15 +921,15 @@ static bool tg_may_dispatch(struct throt
 	 * existing slice to make sure it is at least throtl_slice interval
 	 * long since now.
 	 */
-	if (throtl_slice_used(td, tg, rw))
-		throtl_start_new_slice(td, tg, rw);
+	if (throtl_slice_used(tg, rw))
+		throtl_start_new_slice(tg, rw);
 	else {
 		if (time_before(tg->slice_end[rw], jiffies + throtl_slice))
-			throtl_extend_slice(td, tg, rw, jiffies + throtl_slice);
+			throtl_extend_slice(tg, rw, jiffies + throtl_slice);
 	}
 
-	if (tg_with_in_bps_limit(td, tg, bio, &bps_wait)
-	    && tg_with_in_iops_limit(td, tg, bio, &iops_wait)) {
+	if (tg_with_in_bps_limit(tg, bio, &bps_wait) &&
+	    tg_with_in_iops_limit(tg, bio, &iops_wait)) {
 		if (wait)
 			*wait = 0;
 		return 1;
@@ -669,7 +941,7 @@ static bool tg_may_dispatch(struct throt
 		*wait = max_wait;
 
 	if (time_before(tg->slice_end[rw], jiffies + max_wait))
-		throtl_extend_slice(td, tg, rw, jiffies + max_wait);
+		throtl_extend_slice(tg, rw, jiffies + max_wait);
 
 	return 0;
 }
@@ -708,65 +980,136 @@ static void throtl_charge_bio(struct thr
 	tg->bytes_disp[rw] += bio->bi_size;
 	tg->io_disp[rw]++;
 
-	throtl_update_dispatch_stats(tg_to_blkg(tg), bio->bi_size, bio->bi_rw);
+	/*
+	 * REQ_THROTTLED is used to prevent the same bio to be throttled
+	 * more than once as a throttled bio will go through blk-throtl the
+	 * second time when it eventually gets issued.  Set it when a bio
+	 * is being charged to a tg.
+	 *
+	 * Dispatch stats aren't recursive and each @bio should only be
+	 * accounted by the @tg it was originally associated with.  Let's
+	 * update the stats when setting REQ_THROTTLED for the first time
+	 * which is guaranteed to be for the @bio's original tg.
+	 */
+	if (!(bio->bi_rw & REQ_THROTTLED)) {
+		bio->bi_rw |= REQ_THROTTLED;
+		throtl_update_dispatch_stats(tg_to_blkg(tg), bio->bi_size,
+					     bio->bi_rw);
+	}
 }
 
-static void throtl_add_bio_tg(struct throtl_data *td, struct throtl_grp *tg,
-			struct bio *bio)
+/**
+ * throtl_add_bio_tg - add a bio to the specified throtl_grp
+ * @bio: bio to add
+ * @qn: qnode to use
+ * @tg: the target throtl_grp
+ *
+ * Add @bio to @tg's service_queue using @qn.  If @qn is not specified,
+ * tg->qnode_on_self[] is used.
+ */
+static void throtl_add_bio_tg(struct bio *bio, struct throtl_qnode *qn,
+			      struct throtl_grp *tg)
 {
+	struct throtl_service_queue *sq = &tg->service_queue;
 	bool rw = bio_data_dir(bio);
 
-	bio_list_add(&tg->bio_lists[rw], bio);
-	/* Take a bio reference on tg */
-	blkg_get(tg_to_blkg(tg));
-	tg->nr_queued[rw]++;
-	td->nr_queued[rw]++;
-	throtl_enqueue_tg(td, tg);
+	if (!qn)
+		qn = &tg->qnode_on_self[rw];
+
+	/*
+	 * If @tg doesn't currently have any bios queued in the same
+	 * direction, queueing @bio can change when @tg should be
+	 * dispatched.  Mark that @tg was empty.  This is automatically
+	 * cleaered on the next tg_update_disptime().
+	 */
+	if (!sq->nr_queued[rw])
+		tg->flags |= THROTL_TG_WAS_EMPTY;
+
+	throtl_qnode_add_bio(bio, qn, &sq->queued[rw]);
+
+	sq->nr_queued[rw]++;
+	throtl_enqueue_tg(tg);
 }
 
-static void tg_update_disptime(struct throtl_data *td, struct throtl_grp *tg)
+static void tg_update_disptime(struct throtl_grp *tg)
 {
+	struct throtl_service_queue *sq = &tg->service_queue;
 	unsigned long read_wait = -1, write_wait = -1, min_wait = -1, disptime;
 	struct bio *bio;
 
-	if ((bio = bio_list_peek(&tg->bio_lists[READ])))
-		tg_may_dispatch(td, tg, bio, &read_wait);
+	if ((bio = throtl_peek_queued(&sq->queued[READ])))
+		tg_may_dispatch(tg, bio, &read_wait);
 
-	if ((bio = bio_list_peek(&tg->bio_lists[WRITE])))
-		tg_may_dispatch(td, tg, bio, &write_wait);
+	if ((bio = throtl_peek_queued(&sq->queued[WRITE])))
+		tg_may_dispatch(tg, bio, &write_wait);
 
 	min_wait = min(read_wait, write_wait);
 	disptime = jiffies + min_wait;
 
 	/* Update dispatch time */
-	throtl_dequeue_tg(td, tg);
+	throtl_dequeue_tg(tg);
 	tg->disptime = disptime;
-	throtl_enqueue_tg(td, tg);
+	throtl_enqueue_tg(tg);
+
+	/* see throtl_add_bio_tg() */
+	tg->flags &= ~THROTL_TG_WAS_EMPTY;
 }
 
-static void tg_dispatch_one_bio(struct throtl_data *td, struct throtl_grp *tg,
-				bool rw, struct bio_list *bl)
+static void start_parent_slice_with_credit(struct throtl_grp *child_tg,
+					struct throtl_grp *parent_tg, bool rw)
 {
-	struct bio *bio;
+	if (throtl_slice_used(parent_tg, rw)) {
+		throtl_start_new_slice_with_credit(parent_tg, rw,
+				child_tg->slice_start[rw]);
+	}
 
-	bio = bio_list_pop(&tg->bio_lists[rw]);
-	tg->nr_queued[rw]--;
-	/* Drop bio reference on blkg */
-	blkg_put(tg_to_blkg(tg));
+}
 
-	BUG_ON(td->nr_queued[rw] <= 0);
-	td->nr_queued[rw]--;
+static void tg_dispatch_one_bio(struct throtl_grp *tg, bool rw)
+{
+	struct throtl_service_queue *sq = &tg->service_queue;
+	struct throtl_service_queue *parent_sq = sq->parent_sq;
+	struct throtl_grp *parent_tg = sq_to_tg(parent_sq);
+	struct throtl_grp *tg_to_put = NULL;
+	struct bio *bio;
+
+	/*
+	 * @bio is being transferred from @tg to @parent_sq.  Popping a bio
+	 * from @tg may put its reference and @parent_sq might end up
+	 * getting released prematurely.  Remember the tg to put and put it
+	 * after @bio is transferred to @parent_sq.
+	 */
+	bio = throtl_pop_queued(&sq->queued[rw], &tg_to_put);
+	sq->nr_queued[rw]--;
 
 	throtl_charge_bio(tg, bio);
-	bio_list_add(bl, bio);
-	bio->bi_rw |= REQ_THROTTLED;
 
-	throtl_trim_slice(td, tg, rw);
+	/*
+	 * If our parent is another tg, we just need to transfer @bio to
+	 * the parent using throtl_add_bio_tg().  If our parent is
+	 * @td->service_queue, @bio is ready to be issued.  Put it on its
+	 * bio_lists[] and decrease total number queued.  The caller is
+	 * responsible for issuing these bios.
+	 */
+	if (parent_tg) {
+		throtl_add_bio_tg(bio, &tg->qnode_on_parent[rw], parent_tg);
+		start_parent_slice_with_credit(tg, parent_tg, rw);
+	} else {
+		throtl_qnode_add_bio(bio, &tg->qnode_on_parent[rw],
+				     &parent_sq->queued[rw]);
+		BUG_ON(tg->td->nr_queued[rw] <= 0);
+		tg->td->nr_queued[rw]--;
+	}
+
+	throtl_trim_slice(tg, rw);
+
+	if (tg_to_put)
+		blkg_put(tg_to_blkg(tg_to_put));
 }
 
-static int throtl_dispatch_tg(struct throtl_data *td, struct throtl_grp *tg,
-				struct bio_list *bl)
+static int throtl_dispatch_tg(struct throtl_grp *tg)
 {
+	struct throtl_service_queue *sq = &tg->service_queue;
 	unsigned int nr_reads = 0, nr_writes = 0;
 	unsigned int max_nr_reads = throtl_grp_quantum*3/4;
 	unsigned int max_nr_writes = throtl_grp_quantum - max_nr_reads;
@@ -774,20 +1117,20 @@ static int throtl_dispatch_tg(struct thr
 
 	/* Try to dispatch 75% READS and 25% WRITES */
 
-	while ((bio = bio_list_peek(&tg->bio_lists[READ]))
-		&& tg_may_dispatch(td, tg, bio, NULL)) {
+	while ((bio = throtl_peek_queued(&sq->queued[READ])) &&
+	       tg_may_dispatch(tg, bio, NULL)) {
 
-		tg_dispatch_one_bio(td, tg, bio_data_dir(bio), bl);
+		tg_dispatch_one_bio(tg, bio_data_dir(bio));
 		nr_reads++;
 
 		if (nr_reads >= max_nr_reads)
 			break;
 	}
 
-	while ((bio = bio_list_peek(&tg->bio_lists[WRITE]))
-		&& tg_may_dispatch(td, tg, bio, NULL)) {
+	while ((bio = throtl_peek_queued(&sq->queued[WRITE])) &&
+	       tg_may_dispatch(tg, bio, NULL)) {
 
-		tg_dispatch_one_bio(td, tg, bio_data_dir(bio), bl);
+		tg_dispatch_one_bio(tg, bio_data_dir(bio));
 		nr_writes++;
 
 		if (nr_writes >= max_nr_writes)
@@ -797,14 +1140,13 @@ static int throtl_dispatch_tg(struct thr
 	return nr_reads + nr_writes;
 }
 
-static int throtl_select_dispatch(struct throtl_data *td, struct bio_list *bl)
+static int throtl_select_dispatch(struct throtl_service_queue *parent_sq)
 {
 	unsigned int nr_disp = 0;
-	struct throtl_grp *tg;
-	struct throtl_rb_root *st = &td->tg_service_tree;
 
 	while (1) {
-		tg = throtl_rb_first(st);
+		struct throtl_grp *tg = throtl_rb_first(parent_sq);
+		struct throtl_service_queue *sq = &tg->service_queue;
 
 		if (!tg)
 			break;
@@ -812,14 +1154,12 @@ static int throtl_select_dispatch(struct
 		if (time_before(jiffies, tg->disptime))
 			break;
 
-		throtl_dequeue_tg(td, tg);
+		throtl_dequeue_tg(tg);
 
-		nr_disp += throtl_dispatch_tg(td, tg, bl);
+		nr_disp += throtl_dispatch_tg(tg);
 
-		if (tg->nr_queued[0] || tg->nr_queued[1]) {
-			tg_update_disptime(td, tg);
-			throtl_enqueue_tg(td, tg);
-		}
+		if (sq->nr_queued[0] || sq->nr_queued[1])
+			tg_update_disptime(tg);
 
 		if (nr_disp >= throtl_quantum)
 			break;
@@ -828,111 +1168,111 @@ static int throtl_select_dispatch(struct
 	return nr_disp;
 }
 
-static void throtl_process_limit_change(struct throtl_data *td)
+/**
+ * throtl_pending_timer_fn - timer function for service_queue->pending_timer
+ * @arg: the throtl_service_queue being serviced
+ *
+ * This timer is armed when a child throtl_grp with active bio's become
+ * pending and queued on the service_queue's pending_tree and expires when
+ * the first child throtl_grp should be dispatched.  This function
+ * dispatches bio's from the children throtl_grps to the parent
+ * service_queue.
+ *
+ * If the parent's parent is another throtl_grp, dispatching is propagated
+ * by either arming its pending_timer or repeating dispatch directly.  If
+ * the top-level service_tree is reached, throtl_data->dispatch_work is
+ * kicked so that the ready bio's are issued.
+ */
+static void throtl_pending_timer_fn(unsigned long arg)
 {
+	struct throtl_service_queue *sq = (void *)arg;
+	struct throtl_grp *tg = sq_to_tg(sq);
+	struct throtl_data *td = sq_to_td(sq);
 	struct request_queue *q = td->queue;
-	struct blkcg_gq *blkg, *n;
-
-	if (!td->limits_changed)
-		return;
-
-	xchg(&td->limits_changed, false);
+	struct throtl_service_queue *parent_sq;
+	bool dispatched;
+	int ret;
 
-	throtl_log(td, "limits changed");
+	spin_lock_irq(q->queue_lock);
+again:
+	parent_sq = sq->parent_sq;
+	dispatched = false;
 
-	list_for_each_entry_safe(blkg, n, &q->blkg_list, q_node) {
-		struct throtl_grp *tg = blkg_to_tg(blkg);
+	while (true) {
+		throtl_log(sq, "dispatch nr_queued=%u read=%u write=%u",
+			   sq->nr_queued[READ] + sq->nr_queued[WRITE],
+			   sq->nr_queued[READ], sq->nr_queued[WRITE]);
 
-		if (!tg->limits_changed)
-			continue;
+		ret = throtl_select_dispatch(sq);
+		if (ret) {
+			throtl_log(sq, "bios disp=%u", ret);
+			dispatched = true;
+		}
 
-		if (!xchg(&tg->limits_changed, false))
-			continue;
+		if (throtl_schedule_next_dispatch(sq, false))
+			break;
 
-		throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu"
-			" riops=%u wiops=%u", tg->bps[READ], tg->bps[WRITE],
-			tg->iops[READ], tg->iops[WRITE]);
+		/* this dispatch windows is still open, relax and repeat */
+		spin_unlock_irq(q->queue_lock);
+		cpu_relax();
+		spin_lock_irq(q->queue_lock);
+	}
 
-		/*
-		 * Restart the slices for both READ and WRITES. It
-		 * might happen that a group's limit are dropped
-		 * suddenly and we don't want to account recently
-		 * dispatched IO with new low rate
-		 */
-		throtl_start_new_slice(td, tg, 0);
-		throtl_start_new_slice(td, tg, 1);
+	if (!dispatched)
+		goto out_unlock;
 
-		if (throtl_tg_on_rr(tg))
-			tg_update_disptime(td, tg);
+	if (parent_sq) {
+		/* @parent_sq is another throl_grp, propagate dispatch */
+		if (tg->flags & THROTL_TG_WAS_EMPTY) {
+			tg_update_disptime(tg);
+			if (!throtl_schedule_next_dispatch(parent_sq, false)) {
+				/* window is already open, repeat dispatching */
+				sq = parent_sq;
+				tg = sq_to_tg(sq);
+				goto again;
+			}
+		}
+	} else {
+		/* reached the top-level, queue issueing */
+		queue_work(kthrotld_workqueue, &td->dispatch_work);
 	}
+out_unlock:
+	spin_unlock_irq(q->queue_lock);
 }
 
-/* Dispatch throttled bios. Should be called without queue lock held. */
-static int throtl_dispatch(struct request_queue *q)
+/**
+ * blk_throtl_dispatch_work_fn - work function for throtl_data->dispatch_work
+ * @work: work item being executed
+ *
+ * This function is queued for execution when bio's reach the bio_lists[]
+ * of throtl_data->service_queue.  Those bio's are ready and issued by this
+ * function.
+ */
+void blk_throtl_dispatch_work_fn(struct work_struct *work)
 {
-	struct throtl_data *td = q->td;
-	unsigned int nr_disp = 0;
+	struct throtl_data *td = container_of(work, struct throtl_data,
+					      dispatch_work);
+	struct throtl_service_queue *td_sq = &td->service_queue;
+	struct request_queue *q = td->queue;
 	struct bio_list bio_list_on_stack;
 	struct bio *bio;
 	struct blk_plug plug;
-
-	spin_lock_irq(q->queue_lock);
-
-	throtl_process_limit_change(td);
-
-	if (!total_nr_queued(td))
-		goto out;
+	int rw;
 
 	bio_list_init(&bio_list_on_stack);
 
-	throtl_log(td, "dispatch nr_queued=%u read=%u write=%u",
-			total_nr_queued(td), td->nr_queued[READ],
-			td->nr_queued[WRITE]);
-
-	nr_disp = throtl_select_dispatch(td, &bio_list_on_stack);
-
-	if (nr_disp)
-		throtl_log(td, "bios disp=%u", nr_disp);
-
-	throtl_schedule_next_dispatch(td);
-out:
+	spin_lock_irq(q->queue_lock);
+	for (rw = READ; rw <= WRITE; rw++)
+		while ((bio = throtl_pop_queued(&td_sq->queued[rw], NULL)))
+			bio_list_add(&bio_list_on_stack, bio);
 	spin_unlock_irq(q->queue_lock);
 
-	/*
-	 * If we dispatched some requests, unplug the queue to make sure
-	 * immediate dispatch
-	 */
-	if (nr_disp) {
+	if (!bio_list_empty(&bio_list_on_stack)) {
 		blk_start_plug(&plug);
 		while((bio = bio_list_pop(&bio_list_on_stack)))
 			generic_make_request(bio);
 		blk_finish_plug(&plug);
 	}
-	return nr_disp;
-}
-
-void blk_throtl_work(struct work_struct *work)
-{
-	struct throtl_data *td = container_of(work, struct throtl_data,
-					throtl_work.work);
-	struct request_queue *q = td->queue;
-
-	throtl_dispatch(q);
-}
-
-/* Call with queue lock held */
-static void
-throtl_schedule_delayed_work(struct throtl_data *td, unsigned long delay)
-{
-
-	struct delayed_work *dwork = &td->throtl_work;
-
-	/* schedule work if limits changed even if no bio is queued */
-	if (total_nr_queued(td) || td->limits_changed) {
-		mod_delayed_work(kthrotld_workqueue, dwork, delay);
-		throtl_log(td, "schedule work. delay=%lu jiffies=%lu",
-				delay, jiffies);
-	}
 }
 
 static u64 tg_prfill_cpu_rwstat(struct seq_file *sf,
@@ -1007,7 +1347,9 @@ static int tg_set_conf(struct cgroup *cg
 	struct blkcg *blkcg = cgroup_to_blkcg(cgrp);
 	struct blkg_conf_ctx ctx;
 	struct throtl_grp *tg;
-	struct throtl_data *td;
+	struct throtl_service_queue *sq;
+	struct blkcg_gq *blkg;
+	struct cgroup *pos_cgrp;
 	int ret;
 
 	ret = blkg_conf_prep(blkcg, &blkcg_policy_throtl, buf, &ctx);
@@ -1015,7 +1357,7 @@ static int tg_set_conf(struct cgroup *cg
 		return ret;
 
 	tg = blkg_to_tg(ctx.blkg);
-	td = ctx.blkg->q->td;
+	sq = &tg->service_queue;
 
 	if (!ctx.v)
 		ctx.v = -1;
@@ -1025,10 +1367,37 @@ static int tg_set_conf(struct cgroup *cg
 	else
 		*(unsigned int *)((void *)tg + cft->private) = ctx.v;
 
-	/* XXX: we don't need the following deferred processing */
-	xchg(&tg->limits_changed, true);
-	xchg(&td->limits_changed, true);
-	throtl_schedule_delayed_work(td, 0);
+	throtl_log(&tg->service_queue,
+		   "limit change rbps=%llu wbps=%llu riops=%u wiops=%u",
+		   tg->bps[READ], tg->bps[WRITE],
+		   tg->iops[READ], tg->iops[WRITE]);
+
+	/*
+	 * Update has_rules[] flags for the updated tg's subtree.  A tg is
+	 * considered to have rules if either the tg itself or any of its
+	 * ancestors has rules.  This identifies groups without any
+	 * restrictions in the whole hierarchy and allows them to bypass
+	 * blk-throttle.
+	 */
+	tg_update_has_rules(tg);
+	blkg_for_each_descendant_pre(blkg, pos_cgrp, ctx.blkg)
+		tg_update_has_rules(blkg_to_tg(blkg));
+
+	/*
+	 * We're already holding queue_lock and know @tg is valid.  Let's
+	 * apply the new config directly.
+	 *
+	 * Restart the slices for both READ and WRITES. It might happen
+	 * that a group's limit are dropped suddenly and we don't want to
+	 * account recently dispatched IO with new low rate.
+	 */
+	throtl_start_new_slice(tg, 0);
+	throtl_start_new_slice(tg, 1);
+
+	if (tg->flags & THROTL_TG_PENDING) {
+		tg_update_disptime(tg);
+		throtl_schedule_next_dispatch(sq->parent_sq, true);
+	}
 
 	blkg_conf_finish(&ctx);
 	return 0;
@@ -1092,7 +1461,7 @@ static void throtl_shutdown_wq(struct re
 {
 	struct throtl_data *td = q->td;
 
-	cancel_delayed_work_sync(&td->throtl_work);
+	cancel_work_sync(&td->dispatch_work);
 }
 
 static struct blkcg_policy blkcg_policy_throtl = {
@@ -1100,6 +1469,7 @@ static struct blkcg_policy blkcg_policy_
 	.cftypes		= throtl_files,
 
 	.pd_init_fn		= throtl_pd_init,
+	.pd_online_fn		= throtl_pd_online,
 	.pd_exit_fn		= throtl_pd_exit,
 	.pd_reset_stats_fn	= throtl_pd_reset_stats,
 };
@@ -1107,15 +1477,16 @@ static struct blkcg_policy blkcg_policy_
 bool blk_throtl_bio(struct request_queue *q, struct bio *bio)
 {
 	struct throtl_data *td = q->td;
+	struct throtl_qnode *qn = NULL;
 	struct throtl_grp *tg;
-	bool rw = bio_data_dir(bio), update_disptime = true;
+	struct throtl_service_queue *sq;
+	bool rw = bio_data_dir(bio);
 	struct blkcg *blkcg;
 	bool throttled = false;
 
-	if (bio->bi_rw & REQ_THROTTLED) {
-		bio->bi_rw &= ~REQ_THROTTLED;
+	/* see throtl_charge_bio() */
+	if (bio->bi_rw & REQ_THROTTLED)
 		goto out;
-	}
 
 	/*
 	 * A throtl_grp pointer retrieved under rcu can be used to access
@@ -1126,7 +1497,7 @@ bool blk_throtl_bio(struct request_queue
 	blkcg = bio_blkcg(bio);
 	tg = throtl_lookup_tg(td, blkcg);
 	if (tg) {
-		if (tg_no_rule_group(tg, rw)) {
+		if (!tg->has_rules[rw]) {
 			throtl_update_dispatch_stats(tg_to_blkg(tg),
 						     bio->bi_size, bio->bi_rw);
 			goto out_unlock_rcu;
@@ -1142,18 +1513,18 @@ bool blk_throtl_bio(struct request_queue
 	if (unlikely(!tg))
 		goto out_unlock;
 
-	if (tg->nr_queued[rw]) {
-		/*
-		 * There is already another bio queued in same dir. No
-		 * need to update dispatch time.
-		 */
-		update_disptime = false;
-		goto queue_bio;
+	sq = &tg->service_queue;
 
-	}
+	while (true) {
+		/* throtl is FIFO - if bios are already queued, should queue */
+		if (sq->nr_queued[rw])
+			break;
 
-	/* Bio is with-in rate limit of group */
-	if (tg_may_dispatch(td, tg, bio, NULL)) {
+		/* if above limits, break to queue */
+		if (!tg_may_dispatch(tg, bio, NULL))
+			break;
+
+		/* within limits, let's charge and dispatch directly */
 		throtl_charge_bio(tg, bio);
 
 		/*
@@ -1167,25 +1538,41 @@ bool blk_throtl_bio(struct request_queue
 		 *
 		 * So keep on trimming slice even if bio is not queued.
 		 */
-		throtl_trim_slice(td, tg, rw);
-		goto out_unlock;
+		throtl_trim_slice(tg, rw);
+
+		/*
+		 * @bio passed through this layer without being throttled.
+		 * Climb up the ladder.  If we''re already at the top, it
+		 * can be executed directly.
+		 */
+		qn = &tg->qnode_on_parent[rw];
+		sq = sq->parent_sq;
+		tg = sq_to_tg(sq);
+		if (!tg)
+			goto out_unlock;
 	}
 
-queue_bio:
-	throtl_log_tg(td, tg, "[%c] bio. bdisp=%llu sz=%u bps=%llu"
-			" iodisp=%u iops=%u queued=%d/%d",
-			rw == READ ? 'R' : 'W',
-			tg->bytes_disp[rw], bio->bi_size, tg->bps[rw],
-			tg->io_disp[rw], tg->iops[rw],
-			tg->nr_queued[READ], tg->nr_queued[WRITE]);
+	/* out-of-limit, queue to @tg */
+	throtl_log(sq, "[%c] bio. bdisp=%llu sz=%u bps=%llu iodisp=%u iops=%u queued=%d/%d",
+		   rw == READ ? 'R' : 'W',
+		   tg->bytes_disp[rw], bio->bi_size, tg->bps[rw],
+		   tg->io_disp[rw], tg->iops[rw],
+		   sq->nr_queued[READ], sq->nr_queued[WRITE]);
 
 	bio_associate_current(bio);
-	throtl_add_bio_tg(q->td, tg, bio);
+	tg->td->nr_queued[rw]++;
+	throtl_add_bio_tg(bio, qn, tg);
 	throttled = true;
 
-	if (update_disptime) {
-		tg_update_disptime(td, tg);
-		throtl_schedule_next_dispatch(td);
+	/*
+	 * Update @tg's dispatch time and force schedule dispatch if @tg
+	 * was empty before @bio.  The forced scheduling isn't likely to
+	 * cause undue delay as @bio is likely to be dispatched directly if
+	 * its @tg's disptime is not in the future.
+	 */
+	if (tg->flags & THROTL_TG_WAS_EMPTY) {
+		tg_update_disptime(tg);
+		throtl_schedule_next_dispatch(tg->service_queue.parent_sq, true);
 	}
 
 out_unlock:
@@ -1193,9 +1580,38 @@ out_unlock:
 out_unlock_rcu:
 	rcu_read_unlock();
 out:
+	/*
+	 * As multiple blk-throtls may stack in the same issue path, we
+	 * don't want bios to leave with the flag set.  Clear the flag if
+	 * being issued.
+	 */
+	if (!throttled)
+		bio->bi_rw &= ~REQ_THROTTLED;
 	return throttled;
 }
 
+/*
+ * Dispatch all bios from all children tg's queued on @parent_sq.  On
+ * return, @parent_sq is guaranteed to not have any active children tg's
+ * and all bios from previously active tg's are on @parent_sq->bio_lists[].
+ */
+static void tg_drain_bios(struct throtl_service_queue *parent_sq)
+{
+	struct throtl_grp *tg;
+
+	while ((tg = throtl_rb_first(parent_sq))) {
+		struct throtl_service_queue *sq = &tg->service_queue;
+		struct bio *bio;
+
+		throtl_dequeue_tg(tg);
+
+		while ((bio = throtl_peek_queued(&sq->queued[READ])))
+			tg_dispatch_one_bio(tg, bio_data_dir(bio));
+		while ((bio = throtl_peek_queued(&sq->queued[WRITE])))
+			tg_dispatch_one_bio(tg, bio_data_dir(bio));
+	}
+}
+
 /**
  * blk_throtl_drain - drain throttled bios
  * @q: request_queue to drain throttled bios for
@@ -1206,27 +1622,36 @@ void blk_throtl_drain(struct request_que
 	__releases(q->queue_lock) __acquires(q->queue_lock)
 {
 	struct throtl_data *td = q->td;
-	struct throtl_rb_root *st = &td->tg_service_tree;
-	struct throtl_grp *tg;
-	struct bio_list bl;
+	struct blkcg_gq *blkg;
+	struct cgroup *pos_cgrp;
 	struct bio *bio;
+	int rw;
 
 	queue_lockdep_assert_held(q);
+	rcu_read_lock();
 
-	bio_list_init(&bl);
+	/*
+	 * Drain each tg while doing post-order walk on the blkg tree, so
+	 * that all bios are propagated to td->service_queue.  It'd be
+	 * better to walk service_queue tree directly but blkg walk is
+	 * easier.
+	 */
+	blkg_for_each_descendant_post(blkg, pos_cgrp, td->queue->root_blkg)
+		tg_drain_bios(&blkg_to_tg(blkg)->service_queue);
 
-	while ((tg = throtl_rb_first(st))) {
-		throtl_dequeue_tg(td, tg);
+	tg_drain_bios(&td_root_tg(td)->service_queue);
 
-		while ((bio = bio_list_peek(&tg->bio_lists[READ])))
-			tg_dispatch_one_bio(td, tg, bio_data_dir(bio), &bl);
-		while ((bio = bio_list_peek(&tg->bio_lists[WRITE])))
-			tg_dispatch_one_bio(td, tg, bio_data_dir(bio), &bl);
-	}
+	/* finally, transfer bios from top-level tg's into the td */
+	tg_drain_bios(&td->service_queue);
+
+	rcu_read_unlock();
 	spin_unlock_irq(q->queue_lock);
 
-	while ((bio = bio_list_pop(&bl)))
-		generic_make_request(bio);
+	/* all bios now should be in td->service_queue, issue them */
+	for (rw = READ; rw <= WRITE; rw++)
+		while ((bio = throtl_pop_queued(&td->service_queue.queued[rw],
+						NULL)))
+			generic_make_request(bio);
 
 	spin_lock_irq(q->queue_lock);
 }
@@ -1240,9 +1665,8 @@ int blk_throtl_init(struct request_queue
 	if (!td)
 		return -ENOMEM;
 
-	td->tg_service_tree = THROTL_RB_ROOT;
-	td->limits_changed = false;
-	INIT_DELAYED_WORK(&td->throtl_work, blk_throtl_work);
+	INIT_WORK(&td->dispatch_work, blk_throtl_dispatch_work_fn);
+	throtl_service_queue_init(&td->service_queue, NULL);
 
 	q->td = td;
 	td->queue = q;
diff -druNp --no-dereference linux-libre-3.10-gnu/block/blk-timeout.c linux-libre-3.11-rc7-gnu/block/blk-timeout.c
--- linux-libre-3.10-gnu/block/blk-timeout.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/blk-timeout.c	2013-08-25 20:43:22.000000000 -0400
@@ -82,9 +82,10 @@ void blk_delete_timer(struct request *re
 static void blk_rq_timed_out(struct request *req)
 {
 	struct request_queue *q = req->q;
-	enum blk_eh_timer_return ret;
+	enum blk_eh_timer_return ret = BLK_EH_RESET_TIMER;
 
-	ret = q->rq_timed_out_fn(req);
+	if (q->rq_timed_out_fn)
+		ret = q->rq_timed_out_fn(req);
 	switch (ret) {
 	case BLK_EH_HANDLED:
 		__blk_complete_request(req);
diff -druNp --no-dereference linux-libre-3.10-gnu/block/cfq-iosched.c linux-libre-3.11-rc7-gnu/block/cfq-iosched.c
--- linux-libre-3.10-gnu/block/cfq-iosched.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/cfq-iosched.c	2013-08-25 20:43:22.000000000 -0400
@@ -4347,18 +4347,28 @@ static void cfq_exit_queue(struct elevat
 	kfree(cfqd);
 }
 
-static int cfq_init_queue(struct request_queue *q)
+static int cfq_init_queue(struct request_queue *q, struct elevator_type *e)
 {
 	struct cfq_data *cfqd;
 	struct blkcg_gq *blkg __maybe_unused;
 	int i, ret;
+	struct elevator_queue *eq;
+
+	eq = elevator_alloc(q, e);
+	if (!eq)
+		return -ENOMEM;
 
 	cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
-	if (!cfqd)
+	if (!cfqd) {
+		kobject_put(&eq->kobj);
 		return -ENOMEM;
+	}
+	eq->elevator_data = cfqd;
 
 	cfqd->queue = q;
-	q->elevator->elevator_data = cfqd;
+	spin_lock_irq(q->queue_lock);
+	q->elevator = eq;
+	spin_unlock_irq(q->queue_lock);
 
 	/* Init root service tree */
 	cfqd->grp_service_tree = CFQ_RB_ROOT;
@@ -4433,6 +4443,7 @@ static int cfq_init_queue(struct request
 
 out_free:
 	kfree(cfqd);
+	kobject_put(&eq->kobj);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/block/compat_ioctl.c linux-libre-3.11-rc7-gnu/block/compat_ioctl.c
--- linux-libre-3.10-gnu/block/compat_ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/compat_ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -59,6 +59,7 @@ static int compat_hdio_getgeo(struct gen
 	if (!disk->fops->getgeo)
 		return -ENOTTY;
 
+	memset(&geo, 0, sizeof(geo));
 	/*
 	 * We need to set the startsect first, the driver may
 	 * want to override it.
diff -druNp --no-dereference linux-libre-3.10-gnu/block/deadline-iosched.c linux-libre-3.11-rc7-gnu/block/deadline-iosched.c
--- linux-libre-3.10-gnu/block/deadline-iosched.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/deadline-iosched.c	2013-08-25 20:43:22.000000000 -0400
@@ -337,13 +337,21 @@ static void deadline_exit_queue(struct e
 /*
  * initialize elevator private data (deadline_data).
  */
-static int deadline_init_queue(struct request_queue *q)
+static int deadline_init_queue(struct request_queue *q, struct elevator_type *e)
 {
 	struct deadline_data *dd;
+	struct elevator_queue *eq;
+
+	eq = elevator_alloc(q, e);
+	if (!eq)
+		return -ENOMEM;
 
 	dd = kmalloc_node(sizeof(*dd), GFP_KERNEL | __GFP_ZERO, q->node);
-	if (!dd)
+	if (!dd) {
+		kobject_put(&eq->kobj);
 		return -ENOMEM;
+	}
+	eq->elevator_data = dd;
 
 	INIT_LIST_HEAD(&dd->fifo_list[READ]);
 	INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
@@ -355,7 +363,9 @@ static int deadline_init_queue(struct re
 	dd->front_merges = 1;
 	dd->fifo_batch = fifo_batch;
 
-	q->elevator->elevator_data = dd;
+	spin_lock_irq(q->queue_lock);
+	q->elevator = eq;
+	spin_unlock_irq(q->queue_lock);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/block/elevator.c linux-libre-3.11-rc7-gnu/block/elevator.c
--- linux-libre-3.10-gnu/block/elevator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/elevator.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,7 +150,7 @@ void __init load_default_elevator_module
 
 static struct kobj_type elv_ktype;
 
-static struct elevator_queue *elevator_alloc(struct request_queue *q,
+struct elevator_queue *elevator_alloc(struct request_queue *q,
 				  struct elevator_type *e)
 {
 	struct elevator_queue *eq;
@@ -170,6 +170,7 @@ err:
 	elevator_put(e);
 	return NULL;
 }
+EXPORT_SYMBOL(elevator_alloc);
 
 static void elevator_release(struct kobject *kobj)
 {
@@ -221,16 +222,7 @@ int elevator_init(struct request_queue *
 		}
 	}
 
-	q->elevator = elevator_alloc(q, e);
-	if (!q->elevator)
-		return -ENOMEM;
-
-	err = e->ops.elevator_init_fn(q);
-	if (err) {
-		kobject_put(&q->elevator->kobj);
-		return err;
-	}
-
+	err = e->ops.elevator_init_fn(q, e);
 	return 0;
 }
 EXPORT_SYMBOL(elevator_init);
@@ -935,16 +927,9 @@ static int elevator_switch(struct reques
 	spin_unlock_irq(q->queue_lock);
 
 	/* allocate, init and register new elevator */
-	err = -ENOMEM;
-	q->elevator = elevator_alloc(q, new_e);
-	if (!q->elevator)
-		goto fail_init;
-
-	err = new_e->ops.elevator_init_fn(q);
-	if (err) {
-		kobject_put(&q->elevator->kobj);
+	err = new_e->ops.elevator_init_fn(q, new_e);
+	if (err)
 		goto fail_init;
-	}
 
 	if (registered) {
 		err = elv_register_queue(q);
diff -druNp --no-dereference linux-libre-3.10-gnu/block/genhd.c linux-libre-3.11-rc7-gnu/block/genhd.c
--- linux-libre-3.10-gnu/block/genhd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/genhd.c	2013-08-25 20:43:22.000000000 -0400
@@ -512,7 +512,7 @@ static void register_disk(struct gendisk
 
 	ddev->parent = disk->driverfs_dev;
 
-	dev_set_name(ddev, disk->disk_name);
+	dev_set_name(ddev, "%s", disk->disk_name);
 
 	/* delay uevents, until we scanned partition table */
 	dev_set_uevent_suppress(ddev, 1);
@@ -1489,9 +1489,11 @@ static void __disk_unblock_events(struct
 	intv = disk_events_poll_jiffies(disk);
 	set_timer_slack(&ev->dwork.timer, intv / 4);
 	if (check_now)
-		queue_delayed_work(system_freezable_wq, &ev->dwork, 0);
+		queue_delayed_work(system_freezable_power_efficient_wq,
+				&ev->dwork, 0);
 	else if (intv)
-		queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
+		queue_delayed_work(system_freezable_power_efficient_wq,
+				&ev->dwork, intv);
 out_unlock:
 	spin_unlock_irqrestore(&ev->lock, flags);
 }
@@ -1534,7 +1536,8 @@ void disk_flush_events(struct gendisk *d
 	spin_lock_irq(&ev->lock);
 	ev->clearing |= mask;
 	if (!ev->block)
-		mod_delayed_work(system_freezable_wq, &ev->dwork, 0);
+		mod_delayed_work(system_freezable_power_efficient_wq,
+				&ev->dwork, 0);
 	spin_unlock_irq(&ev->lock);
 }
 
@@ -1627,7 +1630,8 @@ static void disk_check_events(struct dis
 
 	intv = disk_events_poll_jiffies(disk);
 	if (!ev->block && intv)
-		queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
+		queue_delayed_work(system_freezable_power_efficient_wq,
+				&ev->dwork, intv);
 
 	spin_unlock_irq(&ev->lock);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/block/noop-iosched.c linux-libre-3.11-rc7-gnu/block/noop-iosched.c
--- linux-libre-3.10-gnu/block/noop-iosched.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/noop-iosched.c	2013-08-25 20:43:22.000000000 -0400
@@ -59,16 +59,27 @@ noop_latter_request(struct request_queue
 	return list_entry(rq->queuelist.next, struct request, queuelist);
 }
 
-static int noop_init_queue(struct request_queue *q)
+static int noop_init_queue(struct request_queue *q, struct elevator_type *e)
 {
 	struct noop_data *nd;
+	struct elevator_queue *eq;
+
+	eq = elevator_alloc(q, e);
+	if (!eq)
+		return -ENOMEM;
 
 	nd = kmalloc_node(sizeof(*nd), GFP_KERNEL, q->node);
-	if (!nd)
+	if (!nd) {
+		kobject_put(&eq->kobj);
 		return -ENOMEM;
+	}
+	eq->elevator_data = nd;
 
 	INIT_LIST_HEAD(&nd->queue);
-	q->elevator->elevator_data = nd;
+
+	spin_lock_irq(q->queue_lock);
+	q->elevator = eq;
+	spin_unlock_irq(q->queue_lock);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/block/partitions/aix.c linux-libre-3.11-rc7-gnu/block/partitions/aix.c
--- linux-libre-3.10-gnu/block/partitions/aix.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/block/partitions/aix.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,293 @@
+/*
+ *  fs/partitions/aix.c
+ *
+ *  Copyright (C) 2012-2013 Philippe De Muyter <phdm@macqel.be>
+ */
+
+#include "check.h"
+#include "aix.h"
+
+struct lvm_rec {
+	char lvm_id[4]; /* "_LVM" */
+	char reserved4[16];
+	__be32 lvmarea_len;
+	__be32 vgda_len;
+	__be32 vgda_psn[2];
+	char reserved36[10];
+	__be16 pp_size; /* log2(pp_size) */
+	char reserved46[12];
+	__be16 version;
+	};
+
+struct vgda {
+	__be32 secs;
+	__be32 usec;
+	char reserved8[16];
+	__be16 numlvs;
+	__be16 maxlvs;
+	__be16 pp_size;
+	__be16 numpvs;
+	__be16 total_vgdas;
+	__be16 vgda_size;
+	};
+
+struct lvd {
+	__be16 lv_ix;
+	__be16 res2;
+	__be16 res4;
+	__be16 maxsize;
+	__be16 lv_state;
+	__be16 mirror;
+	__be16 mirror_policy;
+	__be16 num_lps;
+	__be16 res10[8];
+	};
+
+struct lvname {
+	char name[64];
+	};
+
+struct ppe {
+	__be16 lv_ix;
+	unsigned short res2;
+	unsigned short res4;
+	__be16 lp_ix;
+	unsigned short res8[12];
+	};
+
+struct pvd {
+	char reserved0[16];
+	__be16 pp_count;
+	char reserved18[2];
+	__be32 psn_part1;
+	char reserved24[8];
+	struct ppe ppe[1016];
+	};
+
+#define LVM_MAXLVS 256
+
+/**
+ * last_lba(): return number of last logical block of device
+ * @bdev: block device
+ *
+ * Description: Returns last LBA value on success, 0 on error.
+ * This is stored (by sd and ide-geometry) in
+ *  the part[0] entry for this disk, and is the number of
+ *  physical sectors available on the disk.
+ */
+static u64 last_lba(struct block_device *bdev)
+{
+	if (!bdev || !bdev->bd_inode)
+		return 0;
+	return (bdev->bd_inode->i_size >> 9) - 1ULL;
+}
+
+/**
+ * read_lba(): Read bytes from disk, starting at given LBA
+ * @state
+ * @lba
+ * @buffer
+ * @count
+ *
+ * Description:  Reads @count bytes from @state->bdev into @buffer.
+ * Returns number of bytes read on success, 0 on error.
+ */
+static size_t read_lba(struct parsed_partitions *state, u64 lba, u8 *buffer,
+			size_t count)
+{
+	size_t totalreadcount = 0;
+
+	if (!buffer || lba + count / 512 > last_lba(state->bdev))
+		return 0;
+
+	while (count) {
+		int copied = 512;
+		Sector sect;
+		unsigned char *data = read_part_sector(state, lba++, &sect);
+		if (!data)
+			break;
+		if (copied > count)
+			copied = count;
+		memcpy(buffer, data, copied);
+		put_dev_sector(sect);
+		buffer += copied;
+		totalreadcount += copied;
+		count -= copied;
+	}
+	return totalreadcount;
+}
+
+/**
+ * alloc_pvd(): reads physical volume descriptor
+ * @state
+ * @lba
+ *
+ * Description: Returns pvd on success,  NULL on error.
+ * Allocates space for pvd and fill it with disk blocks at @lba
+ * Notes: remember to free pvd when you're done!
+ */
+static struct pvd *alloc_pvd(struct parsed_partitions *state, u32 lba)
+{
+	size_t count = sizeof(struct pvd);
+	struct pvd *p;
+
+	p = kmalloc(count, GFP_KERNEL);
+	if (!p)
+		return NULL;
+
+	if (read_lba(state, lba, (u8 *) p, count) < count) {
+		kfree(p);
+		return NULL;
+	}
+	return p;
+}
+
+/**
+ * alloc_lvn(): reads logical volume names
+ * @state
+ * @lba
+ *
+ * Description: Returns lvn on success,  NULL on error.
+ * Allocates space for lvn and fill it with disk blocks at @lba
+ * Notes: remember to free lvn when you're done!
+ */
+static struct lvname *alloc_lvn(struct parsed_partitions *state, u32 lba)
+{
+	size_t count = sizeof(struct lvname) * LVM_MAXLVS;
+	struct lvname *p;
+
+	p = kmalloc(count, GFP_KERNEL);
+	if (!p)
+		return NULL;
+
+	if (read_lba(state, lba, (u8 *) p, count) < count) {
+		kfree(p);
+		return NULL;
+	}
+	return p;
+}
+
+int aix_partition(struct parsed_partitions *state)
+{
+	int ret = 0;
+	Sector sect;
+	unsigned char *d;
+	u32 pp_bytes_size;
+	u32 pp_blocks_size = 0;
+	u32 vgda_sector = 0;
+	u32 vgda_len = 0;
+	int numlvs = 0;
+	struct pvd *pvd;
+	struct lv_info {
+		unsigned short pps_per_lv;
+		unsigned short pps_found;
+		unsigned char lv_is_contiguous;
+	} *lvip;
+	struct lvname *n = NULL;
+
+	d = read_part_sector(state, 7, &sect);
+	if (d) {
+		struct lvm_rec *p = (struct lvm_rec *)d;
+		u16 lvm_version = be16_to_cpu(p->version);
+		char tmp[64];
+
+		if (lvm_version == 1) {
+			int pp_size_log2 = be16_to_cpu(p->pp_size);
+
+			pp_bytes_size = 1 << pp_size_log2;
+			pp_blocks_size = pp_bytes_size / 512;
+			snprintf(tmp, sizeof(tmp),
+				" AIX LVM header version %u found\n",
+				lvm_version);
+			vgda_len = be32_to_cpu(p->vgda_len);
+			vgda_sector = be32_to_cpu(p->vgda_psn[0]);
+		} else {
+			snprintf(tmp, sizeof(tmp),
+				" unsupported AIX LVM version %d found\n",
+				lvm_version);
+		}
+		strlcat(state->pp_buf, tmp, PAGE_SIZE);
+		put_dev_sector(sect);
+	}
+	if (vgda_sector && (d = read_part_sector(state, vgda_sector, &sect))) {
+		struct vgda *p = (struct vgda *)d;
+
+		numlvs = be16_to_cpu(p->numlvs);
+		put_dev_sector(sect);
+	}
+	lvip = kzalloc(sizeof(struct lv_info) * state->limit, GFP_KERNEL);
+	if (!lvip)
+		return 0;
+	if (numlvs && (d = read_part_sector(state, vgda_sector + 1, &sect))) {
+		struct lvd *p = (struct lvd *)d;
+		int i;
+
+		n = alloc_lvn(state, vgda_sector + vgda_len - 33);
+		if (n) {
+			int foundlvs = 0;
+
+			for (i = 0; foundlvs < numlvs && i < state->limit; i += 1) {
+				lvip[i].pps_per_lv = be16_to_cpu(p[i].num_lps);
+				if (lvip[i].pps_per_lv)
+					foundlvs += 1;
+			}
+		}
+		put_dev_sector(sect);
+	}
+	pvd = alloc_pvd(state, vgda_sector + 17);
+	if (pvd) {
+		int numpps = be16_to_cpu(pvd->pp_count);
+		int psn_part1 = be32_to_cpu(pvd->psn_part1);
+		int i;
+		int cur_lv_ix = -1;
+		int next_lp_ix = 1;
+		int lp_ix;
+
+		for (i = 0; i < numpps; i += 1) {
+			struct ppe *p = pvd->ppe + i;
+			unsigned int lv_ix;
+
+			lp_ix = be16_to_cpu(p->lp_ix);
+			if (!lp_ix) {
+				next_lp_ix = 1;
+				continue;
+			}
+			lv_ix = be16_to_cpu(p->lv_ix) - 1;
+			if (lv_ix > state->limit) {
+				cur_lv_ix = -1;
+				continue;
+			}
+			lvip[lv_ix].pps_found += 1;
+			if (lp_ix == 1) {
+				cur_lv_ix = lv_ix;
+				next_lp_ix = 1;
+			} else if (lv_ix != cur_lv_ix || lp_ix != next_lp_ix) {
+				next_lp_ix = 1;
+				continue;
+			}
+			if (lp_ix == lvip[lv_ix].pps_per_lv) {
+				char tmp[70];
+
+				put_partition(state, lv_ix + 1,
+				  (i + 1 - lp_ix) * pp_blocks_size + psn_part1,
+				  lvip[lv_ix].pps_per_lv * pp_blocks_size);
+				snprintf(tmp, sizeof(tmp), " <%s>\n",
+					 n[lv_ix].name);
+				strlcat(state->pp_buf, tmp, PAGE_SIZE);
+				lvip[lv_ix].lv_is_contiguous = 1;
+				ret = 1;
+				next_lp_ix = 1;
+			} else
+				next_lp_ix += 1;
+		}
+		for (i = 0; i < state->limit; i += 1)
+			if (lvip[i].pps_found && !lvip[i].lv_is_contiguous)
+				pr_warn("partition %s (%u pp's found) is "
+					"not contiguous\n",
+					n[i].name, lvip[i].pps_found);
+		kfree(pvd);
+	}
+	kfree(n);
+	kfree(lvip);
+	return ret;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/block/partitions/aix.h linux-libre-3.11-rc7-gnu/block/partitions/aix.h
--- linux-libre-3.10-gnu/block/partitions/aix.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/block/partitions/aix.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+extern int aix_partition(struct parsed_partitions *state);
diff -druNp --no-dereference linux-libre-3.10-gnu/block/partitions/Kconfig linux-libre-3.11-rc7-gnu/block/partitions/Kconfig
--- linux-libre-3.10-gnu/block/partitions/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/partitions/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -68,6 +68,17 @@ config ACORN_PARTITION_RISCIX
 	  of machines called RISCiX.  If you say 'Y' here, Linux will be able
 	  to read disks partitioned under RISCiX.
 
+config AIX_PARTITION
+	bool "AIX basic partition table support" if PARTITION_ADVANCED
+	help
+	  Say Y here if you would like to be able to read the hard disk
+	  partition table format used by IBM or Motorola PowerPC machines
+	  running AIX.  AIX actually uses a Logical Volume Manager, where
+	  "logical volumes" can be spread across one or multiple disks,
+	  but this driver works only for the simple case of partitions which
+	  are contiguous.
+	  Otherwise, say N.
+
 config OSF_PARTITION
 	bool "Alpha OSF partition support" if PARTITION_ADVANCED
 	default y if ALPHA
diff -druNp --no-dereference linux-libre-3.10-gnu/block/partitions/Makefile linux-libre-3.11-rc7-gnu/block/partitions/Makefile
--- linux-libre-3.10-gnu/block/partitions/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/partitions/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -7,6 +7,7 @@ obj-$(CONFIG_BLOCK) := check.o
 obj-$(CONFIG_ACORN_PARTITION) += acorn.o
 obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
 obj-$(CONFIG_ATARI_PARTITION) += atari.o
+obj-$(CONFIG_AIX_PARTITION) += aix.o
 obj-$(CONFIG_MAC_PARTITION) += mac.o
 obj-$(CONFIG_LDM_PARTITION) += ldm.o
 obj-$(CONFIG_MSDOS_PARTITION) += msdos.o
diff -druNp --no-dereference linux-libre-3.10-gnu/block/partitions/msdos.c linux-libre-3.11-rc7-gnu/block/partitions/msdos.c
--- linux-libre-3.10-gnu/block/partitions/msdos.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/block/partitions/msdos.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,7 @@
 #include "check.h"
 #include "msdos.h"
 #include "efi.h"
+#include "aix.h"
 
 /*
  * Many architectures don't like unaligned accesses, while
@@ -90,7 +91,7 @@ static int aix_magic_present(struct pars
 		if (d[0] == '_' && d[1] == 'L' && d[2] == 'V' && d[3] == 'M')
 			ret = 1;
 		put_dev_sector(sect);
-	};
+	}
 	return ret;
 }
 
@@ -142,7 +143,7 @@ static void parse_extended(struct parsed
 			return;
 
 		if (!msdos_magic_present(data + 510))
-			goto done; 
+			goto done;
 
 		p = (struct partition *) (data + 0x1be);
 
@@ -155,7 +156,7 @@ static void parse_extended(struct parsed
 		 * and OS/2 seems to use all four entries.
 		 */
 
-		/* 
+		/*
 		 * First process the data partition(s)
 		 */
 		for (i=0; i<4; i++, p++) {
@@ -263,7 +264,7 @@ static void parse_solaris_x86(struct par
 }
 
 #if defined(CONFIG_BSD_DISKLABEL)
-/* 
+/*
  * Create devices for BSD partitions listed in a disklabel, under a
  * dos-like partition. See parse_extended() for more information.
  */
@@ -294,7 +295,7 @@ static void parse_bsd(struct parsed_part
 
 		if (state->next == state->limit)
 			break;
-		if (p->p_fstype == BSD_FS_UNUSED) 
+		if (p->p_fstype == BSD_FS_UNUSED)
 			continue;
 		bsd_start = le32_to_cpu(p->p_offset);
 		bsd_size = le32_to_cpu(p->p_size);
@@ -441,7 +442,7 @@ static struct {
 	{NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
 	{0, NULL},
 };
- 
+
 int msdos_partition(struct parsed_partitions *state)
 {
 	sector_t sector_size = bdev_logical_block_size(state->bdev) / 512;
@@ -462,8 +463,12 @@ int msdos_partition(struct parsed_partit
 	 */
 	if (aix_magic_present(state, data)) {
 		put_dev_sector(sect);
+#ifdef CONFIG_AIX_PARTITION
+		return aix_partition(state);
+#else
 		strlcat(state->pp_buf, " [AIX]", PAGE_SIZE);
 		return 0;
+#endif
 	}
 
 	if (!msdos_magic_present(data + 510)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/algapi.c linux-libre-3.11-rc7-gnu/crypto/algapi.c
--- linux-libre-3.10-gnu/crypto/algapi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/crypto/algapi.c	2013-08-25 20:43:22.000000000 -0400
@@ -495,7 +495,8 @@ static struct crypto_template *__crypto_
 
 struct crypto_template *crypto_lookup_template(const char *name)
 {
-	return try_then_request_module(__crypto_lookup_template(name), name);
+	return try_then_request_module(__crypto_lookup_template(name), "%s",
+				       name);
 }
 EXPORT_SYMBOL_GPL(crypto_lookup_template);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/async_tx/async_memset.c linux-libre-3.11-rc7-gnu/crypto/async_tx/async_memset.c
--- linux-libre-3.10-gnu/crypto/async_tx/async_memset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/crypto/async_tx/async_memset.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,89 +0,0 @@
-/*
- * memory fill offload engine support
- *
- * Copyright © 2006, Intel Corporation.
- *
- *      Dan Williams <dan.j.williams@intel.com>
- *
- *      with architecture considerations by:
- *      Neil Brown <neilb@suse.de>
- *      Jeff Garzik <jeff@garzik.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/dma-mapping.h>
-#include <linux/async_tx.h>
-
-/**
- * async_memset - attempt to fill memory with a dma engine.
- * @dest: destination page
- * @val: fill value
- * @offset: offset in pages to start transaction
- * @len: length in bytes
- *
- * honored flags: ASYNC_TX_ACK
- */
-struct dma_async_tx_descriptor *
-async_memset(struct page *dest, int val, unsigned int offset, size_t len,
-	     struct async_submit_ctl *submit)
-{
-	struct dma_chan *chan = async_tx_find_channel(submit, DMA_MEMSET,
-						      &dest, 1, NULL, 0, len);
-	struct dma_device *device = chan ? chan->device : NULL;
-	struct dma_async_tx_descriptor *tx = NULL;
-
-	if (device && is_dma_fill_aligned(device, offset, 0, len)) {
-		dma_addr_t dma_dest;
-		unsigned long dma_prep_flags = 0;
-
-		if (submit->cb_fn)
-			dma_prep_flags |= DMA_PREP_INTERRUPT;
-		if (submit->flags & ASYNC_TX_FENCE)
-			dma_prep_flags |= DMA_PREP_FENCE;
-		dma_dest = dma_map_page(device->dev, dest, offset, len,
-					DMA_FROM_DEVICE);
-
-		tx = device->device_prep_dma_memset(chan, dma_dest, val, len,
-						    dma_prep_flags);
-	}
-
-	if (tx) {
-		pr_debug("%s: (async) len: %zu\n", __func__, len);
-		async_tx_submit(chan, tx, submit);
-	} else { /* run the memset synchronously */
-		void *dest_buf;
-		pr_debug("%s: (sync) len: %zu\n", __func__, len);
-
-		dest_buf = page_address(dest) + offset;
-
-		/* wait for any prerequisite operations */
-		async_tx_quiesce(&submit->depend_tx);
-
-		memset(dest_buf, val, len);
-
-		async_tx_sync_epilog(submit);
-	}
-
-	return tx;
-}
-EXPORT_SYMBOL_GPL(async_memset);
-
-MODULE_AUTHOR("Intel Corporation");
-MODULE_DESCRIPTION("asynchronous memset api");
-MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/async_tx/Kconfig linux-libre-3.11-rc7-gnu/crypto/async_tx/Kconfig
--- linux-libre-3.10-gnu/crypto/async_tx/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/crypto/async_tx/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -10,10 +10,6 @@ config ASYNC_XOR
 	select ASYNC_CORE
 	select XOR_BLOCKS
 
-config ASYNC_MEMSET
-	tristate
-	select ASYNC_CORE
-
 config ASYNC_PQ
 	tristate
 	select ASYNC_CORE
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/async_tx/Makefile linux-libre-3.11-rc7-gnu/crypto/async_tx/Makefile
--- linux-libre-3.10-gnu/crypto/async_tx/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/crypto/async_tx/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,5 @@
 obj-$(CONFIG_ASYNC_CORE) += async_tx.o
 obj-$(CONFIG_ASYNC_MEMCPY) += async_memcpy.o
-obj-$(CONFIG_ASYNC_MEMSET) += async_memset.o
 obj-$(CONFIG_ASYNC_XOR) += async_xor.o
 obj-$(CONFIG_ASYNC_PQ) += async_pq.o
 obj-$(CONFIG_ASYNC_RAID6_RECOV) += async_raid6_recov.o
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/Kconfig linux-libre-3.11-rc7-gnu/crypto/Kconfig
--- linux-libre-3.10-gnu/crypto/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/crypto/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -820,25 +820,6 @@ config CRYPTO_BLOWFISH_X86_64
 	  See also:
 	  <http://www.schneier.com/blowfish.html>
 
-config CRYPTO_BLOWFISH_AVX2_X86_64
-	tristate "Blowfish cipher algorithm (x86_64/AVX2)"
-	depends on X86 && 64BIT
-	depends on BROKEN
-	select CRYPTO_ALGAPI
-	select CRYPTO_CRYPTD
-	select CRYPTO_ABLK_HELPER_X86
-	select CRYPTO_BLOWFISH_COMMON
-	select CRYPTO_BLOWFISH_X86_64
-	help
-	  Blowfish cipher algorithm (x86_64/AVX2), by Bruce Schneier.
-
-	  This is a variable key length cipher which can use keys from 32
-	  bits to 448 bits in length.  It's fast, simple and specifically
-	  designed for use on "large microprocessors".
-
-	  See also:
-	  <http://www.schneier.com/blowfish.html>
-
 config CRYPTO_CAMELLIA
 	tristate "Camellia cipher algorithms"
 	depends on CRYPTO
@@ -1297,31 +1278,6 @@ config CRYPTO_TWOFISH_AVX_X86_64
 	  See also:
 	  <http://www.schneier.com/twofish.html>
 
-config CRYPTO_TWOFISH_AVX2_X86_64
-	tristate "Twofish cipher algorithm (x86_64/AVX2)"
-	depends on X86 && 64BIT
-	depends on BROKEN
-	select CRYPTO_ALGAPI
-	select CRYPTO_CRYPTD
-	select CRYPTO_ABLK_HELPER_X86
-	select CRYPTO_GLUE_HELPER_X86
-	select CRYPTO_TWOFISH_COMMON
-	select CRYPTO_TWOFISH_X86_64
-	select CRYPTO_TWOFISH_X86_64_3WAY
-	select CRYPTO_TWOFISH_AVX_X86_64
-	select CRYPTO_LRW
-	select CRYPTO_XTS
-	help
-	  Twofish cipher algorithm (x86_64/AVX2).
-
-	  Twofish was submitted as an AES (Advanced Encryption Standard)
-	  candidate cipher by researchers at CounterPane Systems.  It is a
-	  16 round block cipher supporting key sizes of 128, 192, and 256
-	  bits.
-
-	  See also:
-	  <http://www.schneier.com/twofish.html>
-
 comment "Compression"
 
 config CRYPTO_DEFLATE
@@ -1361,6 +1317,22 @@ config CRYPTO_842
 	help
 	  This is the 842 algorithm.
 
+config CRYPTO_LZ4
+	tristate "LZ4 compression algorithm"
+	select CRYPTO_ALGAPI
+	select LZ4_COMPRESS
+	select LZ4_DECOMPRESS
+	help
+	  This is the LZ4 algorithm.
+
+config CRYPTO_LZ4HC
+	tristate "LZ4HC compression algorithm"
+	select CRYPTO_ALGAPI
+	select LZ4HC_COMPRESS
+	select LZ4_DECOMPRESS
+	help
+	  This is the LZ4 high compression mode algorithm.
+
 comment "Random Number Generation"
 
 config CRYPTO_ANSI_CPRNG
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/lz4.c linux-libre-3.11-rc7-gnu/crypto/lz4.c
--- linux-libre-3.10-gnu/crypto/lz4.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/crypto/lz4.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,106 @@
+/*
+ * Cryptographic API.
+ *
+ * Copyright (c) 2013 Chanho Min <chanho.min@lge.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/vmalloc.h>
+#include <linux/lz4.h>
+
+struct lz4_ctx {
+	void *lz4_comp_mem;
+};
+
+static int lz4_init(struct crypto_tfm *tfm)
+{
+	struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	ctx->lz4_comp_mem = vmalloc(LZ4_MEM_COMPRESS);
+	if (!ctx->lz4_comp_mem)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void lz4_exit(struct crypto_tfm *tfm)
+{
+	struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
+	vfree(ctx->lz4_comp_mem);
+}
+
+static int lz4_compress_crypto(struct crypto_tfm *tfm, const u8 *src,
+			    unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+	struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
+	size_t tmp_len = *dlen;
+	int err;
+
+	err = lz4_compress(src, slen, dst, &tmp_len, ctx->lz4_comp_mem);
+
+	if (err < 0)
+		return -EINVAL;
+
+	*dlen = tmp_len;
+	return 0;
+}
+
+static int lz4_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
+			      unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+	int err;
+	size_t tmp_len = *dlen;
+	size_t __slen = slen;
+
+	err = lz4_decompress(src, &__slen, dst, tmp_len);
+	if (err < 0)
+		return -EINVAL;
+
+	*dlen = tmp_len;
+	return err;
+}
+
+static struct crypto_alg alg_lz4 = {
+	.cra_name		= "lz4",
+	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
+	.cra_ctxsize		= sizeof(struct lz4_ctx),
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(alg_lz4.cra_list),
+	.cra_init		= lz4_init,
+	.cra_exit		= lz4_exit,
+	.cra_u			= { .compress = {
+	.coa_compress		= lz4_compress_crypto,
+	.coa_decompress		= lz4_decompress_crypto } }
+};
+
+static int __init lz4_mod_init(void)
+{
+	return crypto_register_alg(&alg_lz4);
+}
+
+static void __exit lz4_mod_fini(void)
+{
+	crypto_unregister_alg(&alg_lz4);
+}
+
+module_init(lz4_mod_init);
+module_exit(lz4_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LZ4 Compression Algorithm");
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/lz4hc.c linux-libre-3.11-rc7-gnu/crypto/lz4hc.c
--- linux-libre-3.10-gnu/crypto/lz4hc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/crypto/lz4hc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,106 @@
+/*
+ * Cryptographic API.
+ *
+ * Copyright (c) 2013 Chanho Min <chanho.min@lge.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/vmalloc.h>
+#include <linux/lz4.h>
+
+struct lz4hc_ctx {
+	void *lz4hc_comp_mem;
+};
+
+static int lz4hc_init(struct crypto_tfm *tfm)
+{
+	struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	ctx->lz4hc_comp_mem = vmalloc(LZ4HC_MEM_COMPRESS);
+	if (!ctx->lz4hc_comp_mem)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void lz4hc_exit(struct crypto_tfm *tfm)
+{
+	struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	vfree(ctx->lz4hc_comp_mem);
+}
+
+static int lz4hc_compress_crypto(struct crypto_tfm *tfm, const u8 *src,
+			    unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+	struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
+	size_t tmp_len = *dlen;
+	int err;
+
+	err = lz4hc_compress(src, slen, dst, &tmp_len, ctx->lz4hc_comp_mem);
+
+	if (err < 0)
+		return -EINVAL;
+
+	*dlen = tmp_len;
+	return 0;
+}
+
+static int lz4hc_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
+			      unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+	int err;
+	size_t tmp_len = *dlen;
+	size_t __slen = slen;
+
+	err = lz4_decompress(src, &__slen, dst, tmp_len);
+	if (err < 0)
+		return -EINVAL;
+
+	*dlen = tmp_len;
+	return err;
+}
+
+static struct crypto_alg alg_lz4hc = {
+	.cra_name		= "lz4hc",
+	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
+	.cra_ctxsize		= sizeof(struct lz4hc_ctx),
+	.cra_module		= THIS_MODULE,
+	.cra_list		= LIST_HEAD_INIT(alg_lz4hc.cra_list),
+	.cra_init		= lz4hc_init,
+	.cra_exit		= lz4hc_exit,
+	.cra_u			= { .compress = {
+	.coa_compress		= lz4hc_compress_crypto,
+	.coa_decompress		= lz4hc_decompress_crypto } }
+};
+
+static int __init lz4hc_mod_init(void)
+{
+	return crypto_register_alg(&alg_lz4hc);
+}
+
+static void __exit lz4hc_mod_fini(void)
+{
+	crypto_unregister_alg(&alg_lz4hc);
+}
+
+module_init(lz4hc_mod_init);
+module_exit(lz4hc_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LZ4HC Compression Algorithm");
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/Makefile linux-libre-3.11-rc7-gnu/crypto/Makefile
--- linux-libre-3.10-gnu/crypto/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/crypto/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -85,6 +85,8 @@ obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
 obj-$(CONFIG_CRYPTO_CRC32) += crc32.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
 obj-$(CONFIG_CRYPTO_LZO) += lzo.o
+obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
+obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o
 obj-$(CONFIG_CRYPTO_842) += 842.o
 obj-$(CONFIG_CRYPTO_RNG2) += rng.o
 obj-$(CONFIG_CRYPTO_RNG2) += krng.o
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/pcrypt.c linux-libre-3.11-rc7-gnu/crypto/pcrypt.c
--- linux-libre-3.10-gnu/crypto/pcrypt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/crypto/pcrypt.c	2013-08-25 20:43:22.000000000 -0400
@@ -455,8 +455,8 @@ static int pcrypt_init_padata(struct pad
 
 	get_online_cpus();
 
-	pcrypt->wq = alloc_workqueue(name,
-				     WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1);
+	pcrypt->wq = alloc_workqueue("%s", WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE,
+				     1, name);
 	if (!pcrypt->wq)
 		goto err;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/sha512_generic.c linux-libre-3.11-rc7-gnu/crypto/sha512_generic.c
--- linux-libre-3.10-gnu/crypto/sha512_generic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/crypto/sha512_generic.c	2013-08-25 20:43:22.000000000 -0400
@@ -251,6 +251,7 @@ static struct shash_alg sha512_algs[2] =
 	.descsize	=	sizeof(struct sha512_state),
 	.base		=	{
 		.cra_name	=	"sha512",
+		.cra_driver_name =	"sha512-generic",
 		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize	=	SHA512_BLOCK_SIZE,
 		.cra_module	=	THIS_MODULE,
@@ -263,6 +264,7 @@ static struct shash_alg sha512_algs[2] =
 	.descsize	=	sizeof(struct sha512_state),
 	.base		=	{
 		.cra_name	=	"sha384",
+		.cra_driver_name =	"sha384-generic",
 		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
 		.cra_blocksize	=	SHA384_BLOCK_SIZE,
 		.cra_module	=	THIS_MODULE,
diff -druNp --no-dereference linux-libre-3.10-gnu/crypto/testmgr.c linux-libre-3.11-rc7-gnu/crypto/testmgr.c
--- linux-libre-3.10-gnu/crypto/testmgr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/crypto/testmgr.c	2013-08-25 20:43:22.000000000 -0400
@@ -184,8 +184,9 @@ static int do_one_async_hash_op(struct a
 	return ret;
 }
 
-static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
-		     unsigned int tcount, bool use_digest)
+static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
+		       unsigned int tcount, bool use_digest,
+		       const int align_offset)
 {
 	const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
 	unsigned int i, j, k, temp;
@@ -216,10 +217,15 @@ static int test_hash(struct crypto_ahash
 		if (template[i].np)
 			continue;
 
+		ret = -EINVAL;
+		if (WARN_ON(align_offset + template[i].psize > PAGE_SIZE))
+			goto out;
+
 		j++;
 		memset(result, 0, 64);
 
 		hash_buff = xbuf[0];
+		hash_buff += align_offset;
 
 		memcpy(hash_buff, template[i].plaintext, template[i].psize);
 		sg_init_one(&sg[0], hash_buff, template[i].psize);
@@ -281,6 +287,10 @@ static int test_hash(struct crypto_ahash
 
 	j = 0;
 	for (i = 0; i < tcount; i++) {
+		/* alignment tests are only done with continuous buffers */
+		if (align_offset != 0)
+			break;
+
 		if (template[i].np) {
 			j++;
 			memset(result, 0, 64);
@@ -358,9 +368,36 @@ out_nobuf:
 	return ret;
 }
 
+static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
+		     unsigned int tcount, bool use_digest)
+{
+	unsigned int alignmask;
+	int ret;
+
+	ret = __test_hash(tfm, template, tcount, use_digest, 0);
+	if (ret)
+		return ret;
+
+	/* test unaligned buffers, check with one byte offset */
+	ret = __test_hash(tfm, template, tcount, use_digest, 1);
+	if (ret)
+		return ret;
+
+	alignmask = crypto_tfm_alg_alignmask(&tfm->base);
+	if (alignmask) {
+		/* Check if alignment mask for tfm is correctly set. */
+		ret = __test_hash(tfm, template, tcount, use_digest,
+				  alignmask + 1);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int __test_aead(struct crypto_aead *tfm, int enc,
 		       struct aead_testvec *template, unsigned int tcount,
-		       const bool diff_dst)
+		       const bool diff_dst, const int align_offset)
 {
 	const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
 	unsigned int i, j, k, n, temp;
@@ -423,15 +460,16 @@ static int __test_aead(struct crypto_aea
 		if (!template[i].np) {
 			j++;
 
-			/* some tepmplates have no input data but they will
+			/* some templates have no input data but they will
 			 * touch input
 			 */
 			input = xbuf[0];
+			input += align_offset;
 			assoc = axbuf[0];
 
 			ret = -EINVAL;
-			if (WARN_ON(template[i].ilen > PAGE_SIZE ||
-				    template[i].alen > PAGE_SIZE))
+			if (WARN_ON(align_offset + template[i].ilen >
+				    PAGE_SIZE || template[i].alen > PAGE_SIZE))
 				goto out;
 
 			memcpy(input, template[i].input, template[i].ilen);
@@ -470,6 +508,7 @@ static int __test_aead(struct crypto_aea
 
 			if (diff_dst) {
 				output = xoutbuf[0];
+				output += align_offset;
 				sg_init_one(&sgout[0], output,
 					    template[i].ilen +
 						(enc ? authsize : 0));
@@ -530,6 +569,10 @@ static int __test_aead(struct crypto_aea
 	}
 
 	for (i = 0, j = 0; i < tcount; i++) {
+		/* alignment tests are only done with continuous buffers */
+		if (align_offset != 0)
+			break;
+
 		if (template[i].np) {
 			j++;
 
@@ -732,15 +775,34 @@ out_noxbuf:
 static int test_aead(struct crypto_aead *tfm, int enc,
 		     struct aead_testvec *template, unsigned int tcount)
 {
+	unsigned int alignmask;
 	int ret;
 
 	/* test 'dst == src' case */
-	ret = __test_aead(tfm, enc, template, tcount, false);
+	ret = __test_aead(tfm, enc, template, tcount, false, 0);
 	if (ret)
 		return ret;
 
 	/* test 'dst != src' case */
-	return __test_aead(tfm, enc, template, tcount, true);
+	ret = __test_aead(tfm, enc, template, tcount, true, 0);
+	if (ret)
+		return ret;
+
+	/* test unaligned buffers, check with one byte offset */
+	ret = __test_aead(tfm, enc, template, tcount, true, 1);
+	if (ret)
+		return ret;
+
+	alignmask = crypto_tfm_alg_alignmask(&tfm->base);
+	if (alignmask) {
+		/* Check if alignment mask for tfm is correctly set. */
+		ret = __test_aead(tfm, enc, template, tcount, true,
+				  alignmask + 1);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 static int test_cipher(struct crypto_cipher *tfm, int enc,
@@ -820,7 +882,7 @@ out_nobuf:
 
 static int __test_skcipher(struct crypto_ablkcipher *tfm, int enc,
 			   struct cipher_testvec *template, unsigned int tcount,
-			   const bool diff_dst)
+			   const bool diff_dst, const int align_offset)
 {
 	const char *algo =
 		crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
@@ -876,10 +938,12 @@ static int __test_skcipher(struct crypto
 			j++;
 
 			ret = -EINVAL;
-			if (WARN_ON(template[i].ilen > PAGE_SIZE))
+			if (WARN_ON(align_offset + template[i].ilen >
+				    PAGE_SIZE))
 				goto out;
 
 			data = xbuf[0];
+			data += align_offset;
 			memcpy(data, template[i].input, template[i].ilen);
 
 			crypto_ablkcipher_clear_flags(tfm, ~0);
@@ -900,6 +964,7 @@ static int __test_skcipher(struct crypto
 			sg_init_one(&sg[0], data, template[i].ilen);
 			if (diff_dst) {
 				data = xoutbuf[0];
+				data += align_offset;
 				sg_init_one(&sgout[0], data, template[i].ilen);
 			}
 
@@ -941,6 +1006,9 @@ static int __test_skcipher(struct crypto
 
 	j = 0;
 	for (i = 0; i < tcount; i++) {
+		/* alignment tests are only done with continuous buffers */
+		if (align_offset != 0)
+			break;
 
 		if (template[i].iv)
 			memcpy(iv, template[i].iv, MAX_IVLEN);
@@ -1075,15 +1143,34 @@ out_nobuf:
 static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
 			 struct cipher_testvec *template, unsigned int tcount)
 {
+	unsigned int alignmask;
 	int ret;
 
 	/* test 'dst == src' case */
-	ret = __test_skcipher(tfm, enc, template, tcount, false);
+	ret = __test_skcipher(tfm, enc, template, tcount, false, 0);
 	if (ret)
 		return ret;
 
 	/* test 'dst != src' case */
-	return __test_skcipher(tfm, enc, template, tcount, true);
+	ret = __test_skcipher(tfm, enc, template, tcount, true, 0);
+	if (ret)
+		return ret;
+
+	/* test unaligned buffers, check with one byte offset */
+	ret = __test_skcipher(tfm, enc, template, tcount, true, 1);
+	if (ret)
+		return ret;
+
+	alignmask = crypto_tfm_alg_alignmask(&tfm->base);
+	if (alignmask) {
+		/* Check if alignment mask for tfm is correctly set. */
+		ret = __test_skcipher(tfm, enc, template, tcount, true,
+				      alignmask + 1);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate,
@@ -1654,16 +1741,10 @@ static const struct alg_test_desc alg_te
 		.alg = "__cbc-twofish-avx",
 		.test = alg_test_null,
 	}, {
-		.alg = "__cbc-twofish-avx2",
-		.test = alg_test_null,
-	}, {
 		.alg = "__driver-cbc-aes-aesni",
 		.test = alg_test_null,
 		.fips_allowed = 1,
 	}, {
-		.alg = "__driver-cbc-blowfish-avx2",
-		.test = alg_test_null,
-	}, {
 		.alg = "__driver-cbc-camellia-aesni",
 		.test = alg_test_null,
 	}, {
@@ -1688,16 +1769,10 @@ static const struct alg_test_desc alg_te
 		.alg = "__driver-cbc-twofish-avx",
 		.test = alg_test_null,
 	}, {
-		.alg = "__driver-cbc-twofish-avx2",
-		.test = alg_test_null,
-	}, {
 		.alg = "__driver-ecb-aes-aesni",
 		.test = alg_test_null,
 		.fips_allowed = 1,
 	}, {
-		.alg = "__driver-ecb-blowfish-avx2",
-		.test = alg_test_null,
-	}, {
 		.alg = "__driver-ecb-camellia-aesni",
 		.test = alg_test_null,
 	}, {
@@ -1722,9 +1797,6 @@ static const struct alg_test_desc alg_te
 		.alg = "__driver-ecb-twofish-avx",
 		.test = alg_test_null,
 	}, {
-		.alg = "__driver-ecb-twofish-avx2",
-		.test = alg_test_null,
-	}, {
 		.alg = "__ghash-pclmulqdqni",
 		.test = alg_test_null,
 		.fips_allowed = 1,
@@ -1978,9 +2050,6 @@ static const struct alg_test_desc alg_te
 		.test = alg_test_null,
 		.fips_allowed = 1,
 	}, {
-		.alg = "cryptd(__driver-cbc-blowfish-avx2)",
-		.test = alg_test_null,
-	}, {
 		.alg = "cryptd(__driver-cbc-camellia-aesni)",
 		.test = alg_test_null,
 	}, {
@@ -1994,9 +2063,6 @@ static const struct alg_test_desc alg_te
 		.test = alg_test_null,
 		.fips_allowed = 1,
 	}, {
-		.alg = "cryptd(__driver-ecb-blowfish-avx2)",
-		.test = alg_test_null,
-	}, {
 		.alg = "cryptd(__driver-ecb-camellia-aesni)",
 		.test = alg_test_null,
 	}, {
@@ -2021,9 +2087,6 @@ static const struct alg_test_desc alg_te
 		.alg = "cryptd(__driver-ecb-twofish-avx)",
 		.test = alg_test_null,
 	}, {
-		.alg = "cryptd(__driver-ecb-twofish-avx2)",
-		.test = alg_test_null,
-	}, {
 		.alg = "cryptd(__driver-gcm-aes-aesni)",
 		.test = alg_test_null,
 		.fips_allowed = 1,
@@ -3068,6 +3131,35 @@ static const struct alg_test_desc alg_te
 	}
 };
 
+static bool alg_test_descs_checked;
+
+static void alg_test_descs_check_order(void)
+{
+	int i;
+
+	/* only check once */
+	if (alg_test_descs_checked)
+		return;
+
+	alg_test_descs_checked = true;
+
+	for (i = 1; i < ARRAY_SIZE(alg_test_descs); i++) {
+		int diff = strcmp(alg_test_descs[i - 1].alg,
+				  alg_test_descs[i].alg);
+
+		if (WARN_ON(diff > 0)) {
+			pr_warn("testmgr: alg_test_descs entries in wrong order: '%s' before '%s'\n",
+				alg_test_descs[i - 1].alg,
+				alg_test_descs[i].alg);
+		}
+
+		if (WARN_ON(diff == 0)) {
+			pr_warn("testmgr: duplicate alg_test_descs entry: '%s'\n",
+				alg_test_descs[i].alg);
+		}
+	}
+}
+
 static int alg_find_test(const char *alg)
 {
 	int start = 0;
@@ -3099,6 +3191,8 @@ int alg_test(const char *driver, const c
 	int j;
 	int rc;
 
+	alg_test_descs_check_order();
+
 	if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
 		char nalg[CRYPTO_MAX_ALG_NAME];
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/00-INDEX linux-libre-3.11-rc7-gnu/Documentation/00-INDEX
--- linux-libre-3.10-gnu/Documentation/00-INDEX	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/00-INDEX	2013-08-25 20:43:22.000000000 -0400
@@ -187,6 +187,8 @@ firmware_class/
 	- request_firmware() hotplug interface info.
 flexible-arrays.txt
 	- how to make use of flexible sized arrays in linux
+fmc/
+	- information about the FMC bus abstraction
 frv/
 	- Fujitsu FR-V Linux documentation.
 futex-requeue-pi.txt
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/stable/sysfs-driver-ib_srp linux-libre-3.11-rc7-gnu/Documentation/ABI/stable/sysfs-driver-ib_srp
--- linux-libre-3.10-gnu/Documentation/ABI/stable/sysfs-driver-ib_srp	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/stable/sysfs-driver-ib_srp	2013-08-25 20:43:22.000000000 -0400
@@ -54,6 +54,13 @@ Description:	Interface for making ib_srp
 		  ib_srp. Specifying a value that exceeds cmd_sg_entries is
 		  only safe with partial memory descriptor list support enabled
 		  (allow_ext_sg=1).
+		* comp_vector, a number in the range 0..n-1 specifying the
+		  MSI-X completion vector. Some HCA's allocate multiple (n)
+		  MSI-X vectors per HCA port. If the IRQ affinity masks of
+		  these interrupts have been configured such that each MSI-X
+		  interrupt is handled by a different CPU then the comp_vector
+		  parameter can be used to spread the SRP completion workload
+		  over multiple CPU's.
 
 What:		/sys/class/infiniband_srp/srp-<hca>-<port_number>/ibdev
 Date:		January 2, 2006
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/stable/sysfs-module linux-libre-3.11-rc7-gnu/Documentation/ABI/stable/sysfs-module
--- linux-libre-3.10-gnu/Documentation/ABI/stable/sysfs-module	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/stable/sysfs-module	2013-08-25 20:43:22.000000000 -0400
@@ -4,9 +4,13 @@ Description:
 
 	/sys/module/MODULENAME
 		The name of the module that is in the kernel.  This
-		module name will show up either if the module is built
-		directly into the kernel, or if it is loaded as a
-		dynamic module.
+		module name will always show up if the module is loaded as a
+		dynamic module.  If it is built directly into the kernel, it
+		will only show up if it has a version or at least one
+		parameter.
+
+		Note: The conditions of creation in the built-in case are not
+		by design and may be removed in the future.
 
 	/sys/module/MODULENAME/parameters
 		This directory contains individual files that are each
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,81 @@
+What:		/config/usb-gadget
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		This group contains sub-groups corresponding to created
+		USB gadgets.
+
+What:		/config/usb-gadget/gadget
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+
+		The attributes of a gadget:
+
+		UDC		- bind a gadget to UDC/unbind a gadget;
+				write UDC's name found in /sys/class/udc/*
+				to bind a gadget, empty string "" to unbind.
+
+		bDeviceClass	- USB device class code
+		bDeviceSubClass	- USB device subclass code
+		bDeviceProtocol	- USB device protocol code
+		bMaxPacketSize0	- maximum endpoint 0 packet size
+		bcdDevice	- bcd device release number
+		bcdUSB		- bcd USB specification version number
+		idProduct	- product ID
+		idVendor	- vendor ID
+
+What:		/config/usb-gadget/gadget/configs
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		This group contains a USB gadget's configurations
+
+What:		/config/usb-gadget/gadget/configs/config
+Date:		Jun 2013
+KernelVersion:	3.11
+Description:
+		The attributes of a configuration:
+
+		bmAttributes	- configuration characteristics
+		MaxPower	- maximum power consumption from the bus
+
+What:		/config/usb-gadget/gadget/configs/config/strings
+Date:		Jun 2013
+KernelVersion:	3.11
+Description:
+		This group contains subdirectories for language-specific
+		strings for this configuration.
+
+What:		/config/usb-gadget/gadget/configs/config/strings/language
+Date:		Jun 2013
+KernelVersion:	3.11
+Description:
+		The attributes:
+
+		configuration	- configuration description
+
+
+What:		/config/usb-gadget/gadget/functions
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		This group contains functions available to this USB gadget.
+
+What:		/config/usb-gadget/gadget/strings
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		This group contains subdirectories for language-specific
+		strings for this gadget.
+
+What:		/config/usb-gadget/gadget/strings/language
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		The attributes:
+
+		serialnumber	- gadget's serial number (string)
+		product		- gadget's product description
+		manufacturer	- gadget's manufacturer description
+
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-acm linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-acm
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-acm	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-acm	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,8 @@
+What:		/config/usb-gadget/gadget/functions/acm.name
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+
+		This item contains just one readonly attribute: port_num.
+		It contains the port number of the /dev/ttyGS<n> device
+		associated with acm function's instance "name".
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-ecm linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-ecm
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-ecm	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-ecm	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,16 @@
+What:		/config/usb-gadget/gadget/functions/ecm.name
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		The attributes:
+
+		ifname		- network device interface name associated with
+				this function instance
+		qmult		- queue length multiplier for high and
+				super speed
+		host_addr	- MAC address of host's end of this
+				Ethernet over USB link
+		dev_addr	- MAC address of device's end of this
+				Ethernet over USB link
+
+
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-eem linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-eem
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-eem	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-eem	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,14 @@
+What:		/config/usb-gadget/gadget/functions/eem.name
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		The attributes:
+
+		ifname		- network device interface name associated with
+				this function instance
+		qmult		- queue length multiplier for high and
+				super speed
+		host_addr	- MAC address of host's end of this
+				Ethernet over USB link
+		dev_addr	- MAC address of device's end of this
+				Ethernet over USB link
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-ncm linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-ncm
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-ncm	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-ncm	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,15 @@
+What:		/config/usb-gadget/gadget/functions/ncm.name
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		The attributes:
+
+		ifname		- network device interface name associated with
+				this function instance
+		qmult		- queue length multiplier for high and
+				super speed
+		host_addr	- MAC address of host's end of this
+				Ethernet over USB link
+		dev_addr	- MAC address of device's end of this
+				Ethernet over USB link
+
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-obex linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-obex
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-obex	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-obex	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,9 @@
+What:		/config/usb-gadget/gadget/functions/obex.name
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+
+		This item contains just one readonly attribute: port_num.
+		It contains the port number of the /dev/ttyGS<n> device
+		associated with obex function's instance "name".
+
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-phonet linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-phonet
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-phonet	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-phonet	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,8 @@
+What:		/config/usb-gadget/gadget/functions/phonet.name
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+
+		This item contains just one readonly attribute: ifname.
+		It contains the network interface name assigned during
+		network device registration.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-rndis linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-rndis
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-rndis	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-rndis	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,14 @@
+What:		/config/usb-gadget/gadget/functions/rndis.name
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		The attributes:
+
+		ifname		- network device interface name associated with
+				this function instance
+		qmult		- queue length multiplier for high and
+				super speed
+		host_addr	- MAC address of host's end of this
+				Ethernet over USB link
+		dev_addr	- MAC address of device's end of this
+				Ethernet over USB link
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-serial linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-serial
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-serial	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-serial	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,9 @@
+What:		/config/usb-gadget/gadget/functions/gser.name
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+
+		This item contains just one readonly attribute: port_num.
+		It contains the port number of the /dev/ttyGS<n> device
+		associated with gser function's instance "name".
+
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-subset linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-subset
--- linux-libre-3.10-gnu/Documentation/ABI/testing/configfs-usb-gadget-subset	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/configfs-usb-gadget-subset	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,14 @@
+What:		/config/usb-gadget/gadget/functions/geth.name
+Date:		Jun 2013
+KenelVersion:	3.11
+Description:
+		The attributes:
+
+		ifname		- network device interface name associated with
+				this function instance
+		qmult		- queue length multiplier for high and
+				super speed
+		host_addr	- MAC address of host's end of this
+				Ethernet over USB link
+		dev_addr	- MAC address of device's end of this
+				Ethernet over USB link
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-acpi linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-acpi
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-acpi	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-acpi	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,58 @@
+What:		/sys/bus/acpi/devices/.../path
+Date:		December 2006
+Contact:	Rafael J. Wysocki <rjw@rjwysocki.net>
+Description:
+		This attribute indicates the full path of ACPI namespace
+		object associated with the device object.  For example,
+		\_SB_.PCI0.
+		This file is not present for device objects representing
+		fixed ACPI hardware features (like power and sleep
+		buttons).
+
+What:		/sys/bus/acpi/devices/.../modalias
+Date:		July 2007
+Contact:	Rafael J. Wysocki <rjw@rjwysocki.net>
+Description:
+		This attribute indicates the PNP IDs of the device object.
+		That is acpi:HHHHHHHH:[CCCCCCC:].  Where each HHHHHHHH or
+		CCCCCCCC contains device object's PNPID (_HID or _CID).
+
+What:		/sys/bus/acpi/devices/.../hid
+Date:		April 2005
+Contact:	Rafael J. Wysocki <rjw@rjwysocki.net>
+Description:
+		This attribute indicates the hardware ID (_HID) of the
+		device object.  For example, PNP0103.
+		This file is present for device objects having the _HID
+		control method.
+
+What:		/sys/bus/acpi/devices/.../description
+Date:		October 2012
+Contact:	Rafael J. Wysocki <rjw@rjwysocki.net>
+Description:
+		This attribute contains the output of the device object's
+		_STR control method, if present.
+
+What:		/sys/bus/acpi/devices/.../adr
+Date:		October 2012
+Contact:	Rafael J. Wysocki <rjw@rjwysocki.net>
+Description:
+		This attribute contains the output of the device object's
+		_ADR control method, which is present for ACPI device
+		objects representing devices having standard enumeration
+		algorithms, such as PCI.
+
+What:		/sys/bus/acpi/devices/.../uid
+Date:		October 2012
+Contact:	Rafael J. Wysocki <rjw@rjwysocki.net>
+Description:
+		This attribute contains the output of the device object's
+		_UID control method, if present.
+
+What:		/sys/bus/acpi/devices/.../eject
+Date:		December 2006
+Contact:	Rafael J. Wysocki <rjw@rjwysocki.net>
+Description:
+		Writing 1 to this attribute will trigger hot removal of
+		this device object.  This file exists for every device
+		object that has _EJ0 method.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-event_source-devices-events linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-event_source-devices-events
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-event_source-devices-events	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-event_source-devices-events	2013-08-25 20:43:22.000000000 -0400
@@ -27,14 +27,36 @@ Description:	Generic performance monitor
 		"basename".
 
 
-What: 		/sys/devices/cpu/events/PM_LD_MISS_L1
-		/sys/devices/cpu/events/PM_LD_REF_L1
-		/sys/devices/cpu/events/PM_CYC
+What: 		/sys/devices/cpu/events/PM_1PLUS_PPC_CMPL
 		/sys/devices/cpu/events/PM_BRU_FIN
+		/sys/devices/cpu/events/PM_BR_MPRED
+		/sys/devices/cpu/events/PM_CMPLU_STALL
+		/sys/devices/cpu/events/PM_CMPLU_STALL_BRU
+		/sys/devices/cpu/events/PM_CMPLU_STALL_DCACHE_MISS
+		/sys/devices/cpu/events/PM_CMPLU_STALL_DFU
+		/sys/devices/cpu/events/PM_CMPLU_STALL_DIV
+		/sys/devices/cpu/events/PM_CMPLU_STALL_ERAT_MISS
+		/sys/devices/cpu/events/PM_CMPLU_STALL_FXU
+		/sys/devices/cpu/events/PM_CMPLU_STALL_IFU
+		/sys/devices/cpu/events/PM_CMPLU_STALL_LSU
+		/sys/devices/cpu/events/PM_CMPLU_STALL_REJECT
+		/sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR
+		/sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR_LONG
+		/sys/devices/cpu/events/PM_CMPLU_STALL_STORE
+		/sys/devices/cpu/events/PM_CMPLU_STALL_THRD
+		/sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR
+		/sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR_LONG
+		/sys/devices/cpu/events/PM_CYC
+		/sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED
+		/sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED_IC_MISS
 		/sys/devices/cpu/events/PM_GCT_NOSLOT_CYC
-		/sys/devices/cpu/events/PM_BRU_MPRED
+		/sys/devices/cpu/events/PM_GCT_NOSLOT_IC_MISS
+		/sys/devices/cpu/events/PM_GRP_CMPL
 		/sys/devices/cpu/events/PM_INST_CMPL
-		/sys/devices/cpu/events/PM_CMPLU_STALL
+		/sys/devices/cpu/events/PM_LD_MISS_L1
+		/sys/devices/cpu/events/PM_LD_REF_L1
+		/sys/devices/cpu/events/PM_RUN_CYC
+		/sys/devices/cpu/events/PM_RUN_INST_CMPL
 
 Date:		2013/01/08
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-event_source-devices-format linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-event_source-devices-format
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-event_source-devices-format	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-event_source-devices-format	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,12 @@ Description:
 		we want to export, so that userspace can deal with sane
 		name/value pairs.
 
+		Userspace must be prepared for the possibility that attributes
+		define overlapping bit ranges. For example:
+			attr1 = 'config:0-23'
+			attr2 = 'config:0-7'
+			attr3 = 'config:12-35'
+
 		Example: 'config1:1,6-10,44'
 		Defines contents of attribute that occupies bits 1,6-10,44 of
 		perf_event_attr::config1.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-iio linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-iio
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-iio	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-iio	2013-08-25 20:43:22.000000000 -0400
@@ -690,45 +690,45 @@ Description:
 		Actually start the buffer capture up.  Will start trigger
 		if first device and appropriate.
 
-What:		/sys/bus/iio/devices/iio:deviceX/buffer/scan_elements
+What:		/sys/bus/iio/devices/iio:deviceX/scan_elements
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
 		Directory containing interfaces for elements that will be
 		captured for a single triggered sample set in the buffer.
 
-What:		/sys/.../buffer/scan_elements/in_accel_x_en
-What:		/sys/.../buffer/scan_elements/in_accel_y_en
-What:		/sys/.../buffer/scan_elements/in_accel_z_en
-What:		/sys/.../buffer/scan_elements/in_anglvel_x_en
-What:		/sys/.../buffer/scan_elements/in_anglvel_y_en
-What:		/sys/.../buffer/scan_elements/in_anglvel_z_en
-What:		/sys/.../buffer/scan_elements/in_magn_x_en
-What:		/sys/.../buffer/scan_elements/in_magn_y_en
-What:		/sys/.../buffer/scan_elements/in_magn_z_en
-What:		/sys/.../buffer/scan_elements/in_timestamp_en
-What:		/sys/.../buffer/scan_elements/in_voltageY_supply_en
-What:		/sys/.../buffer/scan_elements/in_voltageY_en
-What:		/sys/.../buffer/scan_elements/in_voltageY-voltageZ_en
-What:		/sys/.../buffer/scan_elements/in_incli_x_en
-What:		/sys/.../buffer/scan_elements/in_incli_y_en
-What:		/sys/.../buffer/scan_elements/in_pressureY_en
-What:		/sys/.../buffer/scan_elements/in_pressure_en
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_x_en
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_y_en
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_z_en
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_x_en
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_y_en
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_z_en
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_x_en
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_y_en
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_z_en
+What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_en
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_en
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_en
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY-voltageZ_en
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_x_en
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_y_en
+What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_en
+What:		/sys/.../iio:deviceX/scan_elements/in_pressure_en
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
 		Scan element control for triggered data capture.
 
-What:		/sys/.../buffer/scan_elements/in_accel_type
-What:		/sys/.../buffer/scan_elements/in_anglvel_type
-What:		/sys/.../buffer/scan_elements/in_magn_type
-What:		/sys/.../buffer/scan_elements/in_incli_type
-What:		/sys/.../buffer/scan_elements/in_voltageY_type
-What:		/sys/.../buffer/scan_elements/in_voltage_type
-What:		/sys/.../buffer/scan_elements/in_voltageY_supply_type
-What:		/sys/.../buffer/scan_elements/in_timestamp_type
-What:		/sys/.../buffer/scan_elements/in_pressureY_type
-What:		/sys/.../buffer/scan_elements/in_pressure_type
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_type
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_type
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_type
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_type
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_type
+What:		/sys/.../iio:deviceX/scan_elements/in_voltage_type
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_type
+What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_type
+What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_type
+What:		/sys/.../iio:deviceX/scan_elements/in_pressure_type
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
@@ -752,29 +752,29 @@ Description:
 		For other storage combinations this attribute will be extended
 		appropriately.
 
-What:		/sys/.../buffer/scan_elements/in_accel_type_available
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_type_available
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
 		If the type parameter can take one of a small set of values,
 		this attribute lists them.
 
-What:		/sys/.../buffer/scan_elements/in_voltageY_index
-What:		/sys/.../buffer/scan_elements/in_voltageY_supply_index
-What:		/sys/.../buffer/scan_elements/in_accel_x_index
-What:		/sys/.../buffer/scan_elements/in_accel_y_index
-What:		/sys/.../buffer/scan_elements/in_accel_z_index
-What:		/sys/.../buffer/scan_elements/in_anglvel_x_index
-What:		/sys/.../buffer/scan_elements/in_anglvel_y_index
-What:		/sys/.../buffer/scan_elements/in_anglvel_z_index
-What:		/sys/.../buffer/scan_elements/in_magn_x_index
-What:		/sys/.../buffer/scan_elements/in_magn_y_index
-What:		/sys/.../buffer/scan_elements/in_magn_z_index
-What:		/sys/.../buffer/scan_elements/in_incli_x_index
-What:		/sys/.../buffer/scan_elements/in_incli_y_index
-What:		/sys/.../buffer/scan_elements/in_timestamp_index
-What:		/sys/.../buffer/scan_elements/in_pressureY_index
-What:		/sys/.../buffer/scan_elements/in_pressure_index
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_index
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_index
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_x_index
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_y_index
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_z_index
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_x_index
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_y_index
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_z_index
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_x_index
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_y_index
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_z_index
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_x_index
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_y_index
+What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_index
+What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_index
+What:		/sys/.../iio:deviceX/scan_elements/in_pressure_index
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-pci linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-pci
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-pci	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-pci	2013-08-25 20:43:22.000000000 -0400
@@ -64,7 +64,6 @@ Description:
 		Writing a non-zero value to this attribute will
 		force a rescan of all PCI buses in the system, and
 		re-discover previously removed devices.
-		Depends on CONFIG_HOTPLUG.
 
 What:		/sys/bus/pci/devices/.../msi_irqs/
 Date:		September, 2011
@@ -90,7 +89,6 @@ Contact:	Linux PCI developers <linux-pci
 Description:
 		Writing a non-zero value to this attribute will
 		hot-remove the PCI device and any of its children.
-		Depends on CONFIG_HOTPLUG.
 
 What:		/sys/bus/pci/devices/.../pci_bus/.../rescan
 Date:		May 2011
@@ -99,7 +97,7 @@ Description:
 		Writing a non-zero value to this attribute will
 		force a rescan of the bus and all child buses,
 		and re-discover devices removed earlier from this
-		part of the device tree.  Depends on CONFIG_HOTPLUG.
+		part of the device tree.
 
 What:		/sys/bus/pci/devices/.../rescan
 Date:		January 2009
@@ -109,7 +107,6 @@ Description:
 		force a rescan of the device's parent bus and all
 		child buses, and re-discover devices removed earlier
 		from this part of the device tree.
-		Depends on CONFIG_HOTPLUG.
 
 What:		/sys/bus/pci/devices/.../reset
 Date:		July 2009
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-usb linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-usb
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-bus-usb	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-bus-usb	2013-08-25 20:43:22.000000000 -0400
@@ -236,3 +236,30 @@ Description:
 		This attribute is to expose these information to user space.
 		The file will read "hotplug", "wired" and "not used" if the
 		information is available, and "unknown" otherwise.
+
+What:		/sys/bus/usb/devices/.../power/usb2_lpm_l1_timeout
+Date:		May 2013
+Contact:	Mathias Nyman <mathias.nyman@linux.intel.com>
+Description:
+		USB 2.0 devices may support hardware link power management (LPM)
+		L1 sleep state. The usb2_lpm_l1_timeout attribute allows
+		tuning the timeout for L1 inactivity timer (LPM timer), e.g.
+		needed inactivity time before host requests the device to go to L1 sleep.
+		Useful for power management tuning.
+		Supported values are 0 - 65535 microseconds.
+
+What:		/sys/bus/usb/devices/.../power/usb2_lpm_besl
+Date:		May 2013
+Contact:	Mathias Nyman <mathias.nyman@linux.intel.com>
+Description:
+		USB 2.0 devices that support hardware link power management (LPM)
+		L1 sleep state now use a best effort service latency value (BESL) to
+		indicate the best effort to resumption of service to the device after the
+		initiation of the resume event.
+		If the device does not have a preferred besl value then the host can select
+		one instead. This usb2_lpm_besl attribute allows to tune the host selected besl
+		value in order to tune power saving and service latency.
+
+		Supported values are 0 - 15.
+		More information on how besl values map to microseconds can be found in
+		USB 2.0 ECN Errata for Link Power Management, section 4.10)
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-class-devfreq linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-class-devfreq
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-class-devfreq	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-class-devfreq	2013-08-25 20:43:22.000000000 -0400
@@ -78,3 +78,23 @@ Contact:	Nishanth Menon <nm@ti.com>
 Description:
 		The /sys/class/devfreq/.../available_governors shows
 		currently available governors in the system.
+
+What:		/sys/class/devfreq/.../min_freq
+Date:		January 2013
+Contact:	MyungJoo Ham <myungjoo.ham@samsung.com>
+Description:
+		The /sys/class/devfreq/.../min_freq shows and stores
+		the minimum frequency requested by users. It is 0 if
+		the user does not care. min_freq overrides the
+		frequency requested by governors.
+
+What:		/sys/class/devfreq/.../max_freq
+Date:		January 2013
+Contact:	MyungJoo Ham <myungjoo.ham@samsung.com>
+Description:
+		The /sys/class/devfreq/.../max_freq shows and stores
+		the maximum frequency requested by users. It is 0 if
+		the user does not care. max_freq overrides the
+		frequency requested by governors and min_freq.
+		The max_freq overrides min_freq because max_freq may be
+		used to throttle devices to avoid overheating.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-class-pwm linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-class-pwm
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-class-pwm	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-class-pwm	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,79 @@
+What:		/sys/class/pwm/
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		The pwm/ class sub-directory belongs to the Generic PWM
+		Framework and provides a sysfs interface for using PWM
+		channels.
+
+What:		/sys/class/pwm/pwmchipN/
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		A /sys/class/pwm/pwmchipN directory is created for each
+		probed PWM controller/chip where N is the base of the
+		PWM chip.
+
+What:		/sys/class/pwm/pwmchipN/npwm
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		The number of PWM channels supported by the PWM chip.
+
+What:		/sys/class/pwm/pwmchipN/export
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		Exports a PWM channel from the PWM chip for sysfs control.
+		Value is between 0 and /sys/class/pwm/pwmchipN/npwm - 1.
+
+What:		/sys/class/pwm/pwmchipN/unexport
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		Unexports a PWM channel.
+
+What:		/sys/class/pwm/pwmchipN/pwmX
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		A /sys/class/pwm/pwmchipN/pwmX directory is created for
+		each exported PWM channel where X is the exported PWM
+		channel number.
+
+What:		/sys/class/pwm/pwmchipN/pwmX/period
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		Sets the PWM signal period in nanoseconds.
+
+What:		/sys/class/pwm/pwmchipN/pwmX/duty_cycle
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		Sets the PWM signal duty cycle in nanoseconds.
+
+What:		/sys/class/pwm/pwmchipN/pwmX/polarity
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		Sets the output polarity of the PWM signal to "normal" or
+		"inversed".
+
+What:		/sys/class/pwm/pwmchipN/pwmX/enable
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	H Hartley Sweeten <hsweeten@visionengravers.com>
+Description:
+		Enable/disable the PWM signal.
+		0 is disabled
+		1 is enabled
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc	2013-08-25 20:43:22.000000000 -0400
@@ -36,3 +36,22 @@ Description:
 
                 Refer to [ECMA-368] section 10.3.1.1 for the value to
                 use.
+
+What:           /sys/class/uwb_rc/uwbN/wusbhc/wusb_dnts
+Date:           June 2013
+KernelVersion:  3.11
+Contact:        Thomas Pugliese <thomas.pugliese@gmail.com>
+Description:
+                The device notification time slot (DNTS) count and inverval in
+                milliseconds that the WUSB host should use.  This controls how
+                often the devices will have the opportunity to send
+                notifications to the host.
+
+What:           /sys/class/uwb_rc/uwbN/wusbhc/wusb_retry_count
+Date:           June 2013
+KernelVersion:  3.11
+Contact:        Thomas Pugliese <thomas.pugliese@gmail.com>
+Description:
+                The number of retries that the WUSB host should attempt
+                before reporting an error for a bus transaction.  The range of
+                valid values is [0..15], where 0 indicates infinite retries.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-devices-edac linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-devices-edac
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-devices-edac	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-devices-edac	2013-08-25 20:43:22.000000000 -0400
@@ -77,7 +77,7 @@ Description:	Read/Write attribute file t
 
 What:		/sys/devices/system/edac/mc/mc*/max_location
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file displays the information about the last
 		available memory slot in this memory controller. It is used by
@@ -85,7 +85,7 @@ Description:	This attribute file display
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/size
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display the size of dimm or rank.
 		For dimm*/size, this is the size, in MB of the DIMM memory
@@ -96,14 +96,14 @@ Description:	This attribute file will di
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_dev_type
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display what type of DRAM device is
 		being utilized on this DIMM (x1, x2, x4, x8, ...).
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_edac_mode
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display what type of Error detection
 		and correction is being utilized. For example: S4ECD4ED would
@@ -111,7 +111,7 @@ Description:	This attribute file will di
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_label
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This control file allows this DIMM to have a label assigned
 		to it. With this label in the module, when errors occur
@@ -126,14 +126,14 @@ Description:	This control file allows th
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_location
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display the location (csrow/channel,
 		branch/channel/slot or channel/slot) of the dimm or rank.
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_mem_type
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display what type of memory is
 		currently on this csrow. Normally, either buffered or
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-devices-online linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-devices-online
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-devices-online	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-devices-online	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,20 @@
+What:		/sys/devices/.../online
+Date:		April 2013
+Contact:	Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Description:
+		The /sys/devices/.../online attribute is only present for
+		devices whose bus types provide .online() and .offline()
+		callbacks.  The number read from it (0 or 1) reflects the value
+		of the device's 'offline' field.  If that number is 1 and '0'
+		(or 'n', or 'N') is written to this file, the device bus type's
+		.offline() callback is executed for the device and (if
+		successful) its 'offline' field is updated accordingly.  In
+		turn, if that number is 0 and '1' (or 'y', or 'Y') is written to
+		this file, the device bus type's .online() callback is executed
+		for the device and (if successful) its 'offline' field is
+		updated as appropriate.
+
+		After a successful execution of the bus type's .offline()
+		callback the device cannot be used for any purpose until either
+		it is removed (i.e. device_del() is called for it), or its bus
+		type's .online() is exeucted successfully.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-devices-sun linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-devices-sun
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-devices-sun	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-devices-sun	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-Whatt:		/sys/devices/.../sun
+What:		/sys/devices/.../sun
 Date:		October 2012
 Contact:	Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
 Description:
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-devices-system-cpu linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-devices-system-cpu
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-devices-system-cpu	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-devices-system-cpu	2013-08-25 20:43:22.000000000 -0400
@@ -144,6 +144,21 @@ Description:	Discover and change clock s
 		to learn how to control the knobs.
 
 
+What:		/sys/devices/system/cpu/cpu#/cpufreq/freqdomain_cpus
+Date:		June 2013
+Contact:	cpufreq@vger.kernel.org
+Description:	Discover CPUs in the same CPU frequency coordination domain
+
+		freqdomain_cpus is the list of CPUs (online+offline) that share
+		the same clock/freq domain (possibly at the hardware level).
+		That information may be hidden from the cpufreq core and the
+		value of related_cpus may be different from freqdomain_cpus. This
+		attribute is useful for user space DVFS controllers to get better
+		power/performance results for platforms using acpi-cpufreq.
+
+		This file is only present if the acpi-cpufreq driver is in use.
+
+
 What:		/sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
 Date:		August 2008
 KernelVersion:	2.6.27
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-driver-hid-wiimote linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-driver-hid-wiimote
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-driver-hid-wiimote	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-driver-hid-wiimote	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,7 @@ Description:	Make it possible to set/get
 What:		/sys/bus/hid/drivers/wiimote/<dev>/extension
 Date:		August 2011
 KernelVersion:	3.2
-Contact:	David Herrmann <dh.herrmann@googlemail.com>
+Contact:	David Herrmann <dh.herrmann@gmail.com>
 Description:	This file contains the currently connected and initialized
 		extensions. It can be one of: none, motionp, nunchuck, classic,
 		motionp+nunchuck, motionp+classic
@@ -20,3 +20,40 @@ Description:	This file contains the curr
 		the official Nintendo Nunchuck extension and classic is the
 		Nintendo Classic Controller extension. The motionp extension can
 		be combined with the other two.
+		Starting with kernel-version 3.11 Motion Plus hotplugging is
+		supported and if detected, it's no longer reported as static
+		extension. You will get uevent notifications for the motion-plus
+		device then.
+
+What:		/sys/bus/hid/drivers/wiimote/<dev>/devtype
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	David Herrmann <dh.herrmann@gmail.com>
+Description:	While a device is initialized by the wiimote driver, we perform
+		a device detection and signal a "change" uevent after it is
+		done. This file shows the detected device type. "pending" means
+		that the detection is still ongoing, "unknown" means, that the
+		device couldn't be detected or loaded. "generic" means, that the
+		device couldn't be detected but supports basic Wii Remote
+		features and can be used.
+		Other strings for each device-type are available and may be
+		added if new device-specific detections are added.
+		Currently supported are:
+			gen10: First Wii Remote generation
+			gen20: Second Wii Remote Plus generation (builtin MP)
+			balanceboard: Wii Balance Board
+
+What:		/sys/bus/hid/drivers/wiimote/<dev>/bboard_calib
+Date:		May 2013
+KernelVersion:	3.11
+Contact:	David Herrmann <dh.herrmann@gmail.com>
+Description:	This attribute is only provided if the device was detected as a
+		balance board. It provides a single line with 3 calibration
+		values for all 4 sensors. The values are separated by colons and
+		are each 2 bytes long (encoded as 4 digit hexadecimal value).
+		First, 0kg values for all 4 sensors are written, followed by the
+		17kg values for all 4 sensors and last the 34kg values for all 4
+		sensors.
+		Calibration data is already applied by the kernel to all input
+		values but may be used by user-space to perform other
+		transformations.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-driver-intel-rapid-start linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-driver-intel-rapid-start
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-driver-intel-rapid-start	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-driver-intel-rapid-start	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,21 @@
+What:		/sys/bus/acpi/intel-rapid-start/wakeup_events
+Date:		July 2, 2013
+KernelVersion:	3.11
+Contact:	Matthew Garrett <mjg59@srcf.ucam.org>
+Description:	An integer representing a set of wakeup events as follows:
+		1: Wake to enter hibernation when the wakeup timer expires
+		2: Wake to enter hibernation when the battery reaches a
+		critical level
+
+		These values are ORed together. For example, a value of 3
+		indicates that the system will wake to enter hibernation when
+		either the wakeup timer expires or the battery reaches a
+		critical level.
+
+What:		/sys/bus/acpi/intel-rapid-start/wakeup_time
+Date:		July 2, 2013
+KernelVersion:	3.11
+Contact:	Matthew Garrett <mjg59@srcf.ucam.org>
+Description:	An integer representing the length of time the system will
+		remain asleep before waking up to enter hibernation.
+		This value is in minutes.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-driver-xen-blkback linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-driver-xen-blkback
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-driver-xen-blkback	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-driver-xen-blkback	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,17 @@
+What:           /sys/module/xen_blkback/parameters/max_buffer_pages
+Date:           March 2013
+KernelVersion:  3.11
+Contact:        Roger Pau Monné <roger.pau@citrix.com>
+Description:
+                Maximum number of free pages to keep in each block
+                backend buffer.
+
+What:           /sys/module/xen_blkback/parameters/max_persistent_grants
+Date:           March 2013
+KernelVersion:  3.11
+Contact:        Roger Pau Monné <roger.pau@citrix.com>
+Description:
+                Maximum number of grants to map persistently in
+                blkback. If the frontend tries to use more than
+                max_persistent_grants, the LRU kicks in and starts
+                removing 5% of max_persistent_grants every 100ms.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-driver-xen-blkfront linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-driver-xen-blkfront
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-driver-xen-blkfront	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-driver-xen-blkfront	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+What:           /sys/module/xen_blkfront/parameters/max
+Date:           June 2013
+KernelVersion:  3.11
+Contact:        Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Description:
+                Maximum number of segments that the frontend will negotiate
+                with the backend for indirect descriptors. The default value
+                is 32 - higher value means more potential throughput but more
+                memory usage. The backend picks the minimum of the frontend
+                and its default backend value.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-firmware-acpi linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-firmware-acpi
--- linux-libre-3.10-gnu/Documentation/ABI/testing/sysfs-firmware-acpi	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ABI/testing/sysfs-firmware-acpi	2013-08-25 20:43:22.000000000 -0400
@@ -44,6 +44,16 @@ Description:
 		or 0 (unset).  Attempts to write any other values to it will
 		cause -EINVAL to be returned.
 
+What:		/sys/firmware/acpi/hotplug/force_remove
+Date:		May 2013
+Contact:	Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Description:
+		The number in this file (0 or 1) determines whether (1) or not
+		(0) the ACPI subsystem will allow devices to be hot-removed even
+		if they cannot be put offline gracefully (from the kernel's
+		viewpoint).  That number can be changed by writing a boolean
+		value to this file.
+
 What:		/sys/firmware/acpi/interrupts/
 Date:		February 2008
 Contact:	Len Brown <lenb@kernel.org>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/accounting/getdelays.c linux-libre-3.11-rc7-gnu/Documentation/accounting/getdelays.c
--- linux-libre-3.10-gnu/Documentation/accounting/getdelays.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/accounting/getdelays.c	2013-08-25 20:43:22.000000000 -0400
@@ -272,7 +272,7 @@ int main(int argc, char *argv[])
 	char *logfile = NULL;
 	int loop = 0;
 	int containerset = 0;
-	char containerpath[1024];
+	char *containerpath = NULL;
 	int cfd = 0;
 	int forking = 0;
 	sigset_t sigset;
@@ -299,7 +299,7 @@ int main(int argc, char *argv[])
 			break;
 		case 'C':
 			containerset = 1;
-			strncpy(containerpath, optarg, strlen(optarg) + 1);
+			containerpath = optarg;
 			break;
 		case 'w':
 			logfile = strdup(optarg);
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/acpi/apei/einj.txt linux-libre-3.11-rc7-gnu/Documentation/acpi/apei/einj.txt
--- linux-libre-3.10-gnu/Documentation/acpi/apei/einj.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/acpi/apei/einj.txt	2013-08-25 20:43:22.000000000 -0400
@@ -47,11 +47,16 @@ directory apei/einj. The following files
 
 - param1
   This file is used to set the first error parameter value. Effect of
-  parameter depends on error_type specified.
+  parameter depends on error_type specified. For example, if error
+  type is memory related type, the param1 should be a valid physical
+  memory address.
 
 - param2
   This file is used to set the second error parameter value. Effect of
-  parameter depends on error_type specified.
+  parameter depends on error_type specified. For example, if error
+  type is memory related type, the param2 should be a physical memory
+  address mask. Linux requires page or narrower granularity, say,
+  0xfffffffffffff000.
 
 - notrigger
   The EINJ mechanism is a two step process. First inject the error, then
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/acpi/namespace.txt linux-libre-3.11-rc7-gnu/Documentation/acpi/namespace.txt
--- linux-libre-3.10-gnu/Documentation/acpi/namespace.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/acpi/namespace.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,395 @@
+ACPI Device Tree - Representation of ACPI Namespace
+
+Copyright (C) 2013, Intel Corporation
+Author: Lv Zheng <lv.zheng@intel.com>
+
+
+Abstract:
+
+The Linux ACPI subsystem converts ACPI namespace objects into a Linux
+device tree under the /sys/devices/LNXSYSTEM:00 and updates it upon
+receiving ACPI hotplug notification events.  For each device object in this
+hierarchy there is a corresponding symbolic link in the
+/sys/bus/acpi/devices.
+This document illustrates the structure of the ACPI device tree.
+
+
+Credit:
+
+Thanks for the help from Zhang Rui <rui.zhang@intel.com> and Rafael J.
+Wysocki <rafael.j.wysocki@intel.com>.
+
+
+1. ACPI Definition Blocks
+
+   The ACPI firmware sets up RSDP (Root System Description Pointer) in the
+   system memory address space pointing to the XSDT (Extended System
+   Description Table).  The XSDT always points to the FADT (Fixed ACPI
+   Description Table) using its first entry, the data within the FADT
+   includes various fixed-length entries that describe fixed ACPI features
+   of the hardware.  The FADT contains a pointer to the DSDT
+   (Differentiated System Descripition Table).  The XSDT also contains
+   entries pointing to possibly multiple SSDTs (Secondary System
+   Description Table).
+
+   The DSDT and SSDT data is organized in data structures called definition
+   blocks that contain definitions of various objects, including ACPI
+   control methods, encoded in AML (ACPI Machine Language).  The data block
+   of the DSDT along with the contents of SSDTs represents a hierarchical
+   data structure called the ACPI namespace whose topology reflects the
+   structure of the underlying hardware platform.
+
+   The relationships between ACPI System Definition Tables described above
+   are illustrated in the following diagram.
+
+     +---------+    +-------+    +--------+    +------------------------+
+     |  RSDP   | +->| XSDT  | +->|  FADT  |    |  +-------------------+ |
+     +---------+ |  +-------+ |  +--------+  +-|->|       DSDT        | |
+     | Pointer | |  | Entry |-+  | ...... |  | |  +-------------------+ |
+     +---------+ |  +-------+    | X_DSDT |--+ |  | Definition Blocks | |
+     | Pointer |-+  | ..... |    | ...... |    |  +-------------------+ |
+     +---------+    +-------+    +--------+    |  +-------------------+ |
+                    | Entry |------------------|->|       SSDT        | |
+                    +- - - -+                  |  +-------------------| |
+                    | Entry | - - - - - - - -+ |  | Definition Blocks | |
+                    +- - - -+                | |  +-------------------+ |
+                                             | |  +- - - - - - - - - -+ |
+                                             +-|->|       SSDT        | |
+                                               |  +-------------------+ |
+                                               |  | Definition Blocks | |
+                                               |  +- - - - - - - - - -+ |
+                                               +------------------------+
+                                                           |
+                                              OSPM Loading |
+                                                          \|/
+                                                    +----------------+
+                                                    | ACPI Namespace |
+                                                    +----------------+
+
+                     Figure 1. ACPI Definition Blocks
+
+   NOTE: RSDP can also contain a pointer to the RSDT (Root System
+         Description Table).  Platforms provide RSDT to enable
+         compatibility with ACPI 1.0 operating systems.  The OS is expected
+         to use XSDT, if present.
+
+
+2. Example ACPI Namespace
+
+   All definition blocks are loaded into a single namespace.  The namespace
+   is a hierarchy of objects identified by names and paths.
+   The following naming conventions apply to object names in the ACPI
+   namespace:
+   1. All names are 32 bits long.
+   2. The first byte of a name must be one of 'A' - 'Z', '_'.
+   3. Each of the remaining bytes of a name must be one of 'A' - 'Z', '0'
+      - '9', '_'.
+   4. Names starting with '_' are reserved by the ACPI specification.
+   5. The '\' symbol represents the root of the namespace (i.e. names
+      prepended with '\' are relative to the namespace root).
+   6. The '^' symbol represents the parent of the current namespace node
+      (i.e. names prepended with '^' are relative to the parent of the
+      current namespace node).
+
+   The figure below shows an example ACPI namespace.
+
+   +------+
+   | \    |                     Root
+   +------+
+     |
+     | +------+
+     +-| _PR  |                 Scope(_PR): the processor namespace
+     | +------+
+     |   |
+     |   | +------+
+     |   +-| CPU0 |             Processor(CPU0): the first processor
+     |     +------+
+     |
+     | +------+
+     +-| _SB  |                 Scope(_SB): the system bus namespace
+     | +------+
+     |   |
+     |   | +------+
+     |   +-| LID0 |             Device(LID0); the lid device
+     |   | +------+
+     |   |   |
+     |   |   | +------+
+     |   |   +-| _HID |         Name(_HID, "PNP0C0D"): the hardware ID
+     |   |   | +------+
+     |   |   |
+     |   |   | +------+
+     |   |   +-| _STA |         Method(_STA): the status control method
+     |   |     +------+
+     |   |
+     |   | +------+
+     |   +-| PCI0 |             Device(PCI0); the PCI root bridge
+     |     +------+
+     |       |
+     |       | +------+
+     |       +-| _HID |         Name(_HID, "PNP0A08"): the hardware ID
+     |       | +------+
+     |       |
+     |       | +------+
+     |       +-| _CID |         Name(_CID, "PNP0A03"): the compatible ID
+     |       | +------+
+     |       |
+     |       | +------+
+     |       +-| RP03 |         Scope(RP03): the PCI0 power scope
+     |       | +------+
+     |       |   |
+     |       |   | +------+
+     |       |   +-| PXP3 |     PowerResource(PXP3): the PCI0 power resource
+     |       |     +------+
+     |       |
+     |       | +------+
+     |       +-| GFX0 |         Device(GFX0): the graphics adapter
+     |         +------+
+     |           |
+     |           | +------+
+     |           +-| _ADR |     Name(_ADR, 0x00020000): the PCI bus address
+     |           | +------+
+     |           |
+     |           | +------+
+     |           +-| DD01 |     Device(DD01): the LCD output device
+     |             +------+
+     |               |
+     |               | +------+
+     |               +-| _BCL | Method(_BCL): the backlight control method
+     |                 +------+
+     |
+     | +------+
+     +-| _TZ  |                 Scope(_TZ): the thermal zone namespace
+     | +------+
+     |   |
+     |   | +------+
+     |   +-| FN00 |             PowerResource(FN00): the FAN0 power resource
+     |   | +------+
+     |   |
+     |   | +------+
+     |   +-| FAN0 |             Device(FAN0): the FAN0 cooling device
+     |   | +------+
+     |   |   |
+     |   |   | +------+
+     |   |   +-| _HID |         Name(_HID, "PNP0A0B"): the hardware ID
+     |   |     +------+
+     |   |
+     |   | +------+
+     |   +-| TZ00 |             ThermalZone(TZ00); the FAN thermal zone
+     |     +------+
+     |
+     | +------+
+     +-| _GPE |                 Scope(_GPE): the GPE namespace
+       +------+
+
+                     Figure 2. Example ACPI Namespace
+
+
+3. Linux ACPI Device Objects
+
+   The Linux kernel's core ACPI subsystem creates struct acpi_device
+   objects for ACPI namespace objects representing devices, power resources
+   processors, thermal zones.  Those objects are exported to user space via
+   sysfs as directories in the subtree under /sys/devices/LNXSYSTM:00.  The
+   format of their names is <bus_id:instance>, where 'bus_id' refers to the
+   ACPI namespace representation of the given object and 'instance' is used
+   for distinguishing different object of the same 'bus_id' (it is
+   two-digit decimal representation of an unsigned integer).
+
+   The value of 'bus_id' depends on the type of the object whose name it is
+   part of as listed in the table below.
+
+                +---+-----------------+-------+----------+
+                |   | Object/Feature  | Table | bus_id   |
+                +---+-----------------+-------+----------+
+                | N | Root            | xSDT  | LNXSYSTM |
+                +---+-----------------+-------+----------+
+                | N | Device          | xSDT  | _HID     |
+                +---+-----------------+-------+----------+
+                | N | Processor       | xSDT  | LNXCPU   |
+                +---+-----------------+-------+----------+
+                | N | ThermalZone     | xSDT  | LNXTHERM |
+                +---+-----------------+-------+----------+
+                | N | PowerResource   | xSDT  | LNXPOWER |
+                +---+-----------------+-------+----------+
+                | N | Other Devices   | xSDT  | device   |
+                +---+-----------------+-------+----------+
+                | F | PWR_BUTTON      | FADT  | LNXPWRBN |
+                +---+-----------------+-------+----------+
+                | F | SLP_BUTTON      | FADT  | LNXSLPBN |
+                +---+-----------------+-------+----------+
+                | M | Video Extension | xSDT  | LNXVIDEO |
+                +---+-----------------+-------+----------+
+                | M | ATA Controller  | xSDT  | LNXIOBAY |
+                +---+-----------------+-------+----------+
+                | M | Docking Station | xSDT  | LNXDOCK  |
+                +---+-----------------+-------+----------+
+
+                 Table 1. ACPI Namespace Objects Mapping
+
+   The following rules apply when creating struct acpi_device objects on
+   the basis of the contents of ACPI System Description Tables (as
+   indicated by the letter in the first column and the notation in the
+   second column of the table above):
+   N:
+      The object's source is an ACPI namespace node (as indicated by the
+      named object's type in the second column).  In that case the object's
+      directory in sysfs will contain the 'path' attribute whose value is
+      the full path to the node from the namespace root.
+      struct acpi_device objects are created for the ACPI namespace nodes
+      whose _STA control methods return PRESENT or FUNCTIONING.  The power
+      resource nodes or nodes without _STA are assumed to be both PRESENT
+      and FUNCTIONING.
+   F:
+      The struct acpi_device object is created for a fixed hardware
+      feature (as indicated by the fixed feature flag's name in the second
+      column), so its sysfs directory will not contain the 'path'
+      attribute.
+   M:
+      The struct acpi_device object is created for an ACPI namespace node
+      with specific control methods (as indicated by the ACPI defined
+      device's type in the second column).  The 'path' attribute containing
+      its namespace path will be present in its sysfs directory.  For
+      example, if the _BCL method is present for an ACPI namespace node, a
+      struct acpi_device object with LNXVIDEO 'bus_id' will be created for
+      it.
+
+   The third column of the above table indicates which ACPI System
+   Description Tables contain information used for the creation of the
+   struct acpi_device objects represented by the given row (xSDT means DSDT
+   or SSDT).
+
+   The forth column of the above table indicates the 'bus_id' generation
+   rule of the struct acpi_device object:
+   _HID:
+      _HID in the last column of the table means that the object's bus_id
+      is derived from the _HID/_CID identification objects present under
+      the corresponding ACPI namespace node. The object's sysfs directory
+      will then contain the 'hid' and 'modalias' attributes that can be
+      used to retrieve the _HID and _CIDs of that object.
+   LNXxxxxx:
+      The 'modalias' attribute is also present for struct acpi_device
+      objects having bus_id of the "LNXxxxxx" form (pseudo devices), in
+      which cases it contains the bus_id string itself.
+   device:
+      'device' in the last column of the table indicates that the object's
+      bus_id cannot be determined from _HID/_CID of the corresponding
+      ACPI namespace node, although that object represents a device (for
+      example, it may be a PCI device with _ADR defined and without _HID
+      or _CID).  In that case the string 'device' will be used as the
+      object's bus_id.
+
+
+4. Linux ACPI Physical Device Glue
+
+   ACPI device (i.e. struct acpi_device) objects may be linked to other
+   objects in the Linux' device hierarchy that represent "physical" devices
+   (for example, devices on the PCI bus).  If that happens, it means that
+   the ACPI device object is a "companion" of a device otherwise
+   represented in a different way and is used (1) to provide configuration
+   information on that device which cannot be obtained by other means and
+   (2) to do specific things to the device with the help of its ACPI
+   control methods.  One ACPI device object may be linked this way to
+   multiple "physical" devices.
+
+   If an ACPI device object is linked to a "physical" device, its sysfs
+   directory contains the "physical_node" symbolic link to the sysfs
+   directory of the target device object.  In turn, the target device's
+   sysfs directory will then contain the "firmware_node" symbolic link to
+   the sysfs directory of the companion ACPI device object.
+   The linking mechanism relies on device identification provided by the
+   ACPI namespace.  For example, if there's an ACPI namespace object
+   representing a PCI device (i.e. a device object under an ACPI namespace
+   object representing a PCI bridge) whose _ADR returns 0x00020000 and the
+   bus number of the parent PCI bridge is 0, the sysfs directory
+   representing the struct acpi_device object created for that ACPI
+   namespace object will contain the 'physical_node' symbolic link to the
+   /sys/devices/pci0000:00/0000:00:02:0/ sysfs directory of the
+   corresponding PCI device.
+
+   The linking mechanism is generally bus-specific.  The core of its
+   implementation is located in the drivers/acpi/glue.c file, but there are
+   complementary parts depending on the bus types in question located
+   elsewhere.  For example, the PCI-specific part of it is located in
+   drivers/pci/pci-acpi.c.
+
+
+5. Example Linux ACPI Device Tree
+
+   The sysfs hierarchy of struct acpi_device objects corresponding to the
+   example ACPI namespace illustrated in Figure 2 with the addition of
+   fixed PWR_BUTTON/SLP_BUTTON devices is shown below.
+
+   +--------------+---+-----------------+
+   | LNXSYSTEM:00 | \ | acpi:LNXSYSTEM: |
+   +--------------+---+-----------------+
+     |
+     | +-------------+-----+----------------+
+     +-| LNXPWRBN:00 | N/A | acpi:LNXPWRBN: |
+     | +-------------+-----+----------------+
+     |
+     | +-------------+-----+----------------+
+     +-| LNXSLPBN:00 | N/A | acpi:LNXSLPBN: |
+     | +-------------+-----+----------------+
+     |
+     | +-----------+------------+--------------+
+     +-| LNXCPU:00 | \_PR_.CPU0 | acpi:LNXCPU: |
+     | +-----------+------------+--------------+
+     |
+     | +-------------+-------+----------------+
+     +-| LNXSYBUS:00 | \_SB_ | acpi:LNXSYBUS: |
+     | +-------------+-------+----------------+
+     |   |
+     |   | +- - - - - - - +- - - - - - +- - - - - - - -+
+     |   +-| * PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: |
+     |   | +- - - - - - - +- - - - - - +- - - - - - - -+
+     |   |
+     |   | +------------+------------+-----------------------+
+     |   +-| PNP0A08:00 | \_SB_.PCI0 | acpi:PNP0A08:PNP0A03: |
+     |     +------------+------------+-----------------------+
+     |       |
+     |       | +-----------+-----------------+-----+
+     |       +-| device:00 | \_SB_.PCI0.RP03 | N/A |
+     |       | +-----------+-----------------+-----+
+     |       |   |
+     |       |   | +-------------+----------------------+----------------+
+     |       |   +-| LNXPOWER:00 | \_SB_.PCI0.RP03.PXP3 | acpi:LNXPOWER: |
+     |       |     +-------------+----------------------+----------------+
+     |       |
+     |       | +-------------+-----------------+----------------+
+     |       +-| LNXVIDEO:00 | \_SB_.PCI0.GFX0 | acpi:LNXVIDEO: |
+     |         +-------------+-----------------+----------------+
+     |           |
+     |           | +-----------+-----------------+-----+
+     |           +-| device:01 | \_SB_.PCI0.DD01 | N/A |
+     |             +-----------+-----------------+-----+
+     |
+     | +-------------+-------+----------------+
+     +-| LNXSYBUS:01 | \_TZ_ | acpi:LNXSYBUS: |
+       +-------------+-------+----------------+
+         |
+         | +-------------+------------+----------------+
+         +-| LNXPOWER:0a | \_TZ_.FN00 | acpi:LNXPOWER: |
+         | +-------------+------------+----------------+
+         |
+         | +------------+------------+---------------+
+         +-| PNP0C0B:00 | \_TZ_.FAN0 | acpi:PNP0C0B: |
+         | +------------+------------+---------------+
+         |
+         | +-------------+------------+----------------+
+         +-| LNXTHERM:00 | \_TZ_.TZ00 | acpi:LNXTHERM: |
+           +-------------+------------+----------------+
+
+                  Figure 3. Example Linux ACPI Device Tree
+
+   NOTE: Each node is represented as "object/path/modalias", where:
+         1. 'object' is the name of the object's directory in sysfs.
+         2. 'path' is the ACPI namespace path of the corresponding
+            ACPI namespace object, as returned by the object's 'path'
+            sysfs attribute.
+         3. 'modalias' is the value of the object's 'modalias' sysfs
+            attribute (as described earlier in this document).
+   NOTE: N/A indicates the device object does not have the 'path' or the
+         'modalias' attribute.
+   NOTE: The PNP0C0D device listed above is highlighted (marked by "*")
+         to indicate it will be created only when its _STA methods return
+         PRESENT or FUNCTIONING.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/acpi/video_extension.txt linux-libre-3.11-rc7-gnu/Documentation/acpi/video_extension.txt
--- linux-libre-3.10-gnu/Documentation/acpi/video_extension.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/acpi/video_extension.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,106 @@
+ACPI video extensions
+~~~~~~~~~~~~~~~~~~~~~
+
+This driver implement the ACPI Extensions For Display Adapters for
+integrated graphics devices on motherboard, as specified in ACPI 2.0
+Specification, Appendix B, allowing to perform some basic control like
+defining the video POST device, retrieving EDID information or to
+setup a video output, etc.  Note that this is an ref. implementation
+only.  It may or may not work for your integrated video device.
+
+The ACPI video driver does 3 things regarding backlight control:
+
+1 Export a sysfs interface for user space to control backlight level
+
+If the ACPI table has a video device, and acpi_backlight=vendor kernel
+command line is not present, the driver will register a backlight device
+and set the required backlight operation structure for it for the sysfs
+interface control. For every registered class device, there will be a
+directory named acpi_videoX under /sys/class/backlight.
+
+The backlight sysfs interface has a standard definition here:
+Documentation/ABI/stable/sysfs-class-backlight.
+
+And what ACPI video driver does is:
+actual_brightness: on read, control method _BQC will be evaluated to
+get the brightness level the firmware thinks it is at;
+bl_power: not implemented, will set the current brightness instead;
+brightness: on write, control method _BCM will run to set the requested
+brightness level;
+max_brightness: Derived from the _BCL package(see below);
+type: firmware
+
+Note that ACPI video backlight driver will always use index for
+brightness, actual_brightness and max_brightness. So if we have
+the following _BCL package:
+
+Method (_BCL, 0, NotSerialized)
+{
+	Return (Package (0x0C)
+	{
+		0x64,
+		0x32,
+		0x0A,
+		0x14,
+		0x1E,
+		0x28,
+		0x32,
+		0x3C,
+		0x46,
+		0x50,
+		0x5A,
+		0x64
+	})
+}
+
+The first two levels are for when laptop are on AC or on battery and are
+not used by Linux currently. The remaining 10 levels are supported levels
+that we can choose from. The applicable index values are from 0 (that
+corresponds to the 0x0A brightness value) to 9 (that corresponds to the
+0x64 brightness value) inclusive. Each of those index values is regarded
+as a "brightness level" indicator. Thus from the user space perspective
+the range of available brightness levels is from 0 to 9 (max_brightness)
+inclusive.
+
+2 Notify user space about hotkey event
+
+There are generally two cases for hotkey event reporting:
+i) For some laptops, when user presses the hotkey, a scancode will be
+   generated and sent to user space through the input device created by
+   the keyboard driver as a key type input event, with proper remap, the
+   following key code will appear to user space:
+
+	EV_KEY, KEY_BRIGHTNESSUP
+	EV_KEY, KEY_BRIGHTNESSDOWN
+	etc.
+
+For this case, ACPI video driver does not need to do anything(actually,
+it doesn't even know this happened).
+
+ii) For some laptops, the press of the hotkey will not generate the
+    scancode, instead, firmware will notify the video device ACPI node
+    about the event. The event value is defined in the ACPI spec. ACPI
+    video driver will generate an key type input event according to the
+    notify value it received and send the event to user space through the
+    input device it created:
+
+	event		keycode
+	0x86		KEY_BRIGHTNESSUP
+	0x87		KEY_BRIGHTNESSDOWN
+	etc.
+
+so this would lead to the same effect as case i) now.
+
+Once user space tool receives this event, it can modify the backlight
+level through the sysfs interface.
+
+3 Change backlight level in the kernel
+
+This works for machines covered by case ii) in Section 2. Once the driver
+received a notification, it will set the backlight level accordingly. This does
+not affect the sending of event to user space, they are always sent to user
+space regardless of whether or not the video module controls the backlight level
+directly. This behaviour can be controlled through the brightness_switch_enabled
+module parameter as documented in kernel-parameters.txt. It is recommended to
+disable this behaviour once a GUI environment starts up and wants to have full
+control of the backlight level.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/arm/sti/overview.txt linux-libre-3.11-rc7-gnu/Documentation/arm/sti/overview.txt
--- linux-libre-3.10-gnu/Documentation/arm/sti/overview.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/arm/sti/overview.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,33 @@
+			STi ARM Linux Overview
+			==========================
+
+Introduction
+------------
+
+  The ST Microelectronics Multimedia and Application Processors range of
+  CortexA9 System-on-Chip are supported by the 'STi' platform of
+  ARM Linux. Currently STiH415, STiH416 SOCs are supported with both
+  B2000 and B2020 Reference boards.
+
+
+  configuration
+  -------------
+
+  A generic configuration is provided for both STiH415/416, and can be used as the
+  default by
+	make stih41x_defconfig
+
+  Layout
+  ------
+  All the files for multiple machine families (STiH415, STiH416, and STiG125)
+  are located in the platform code contained in arch/arm/mach-sti
+
+  There is a generic board board-dt.c in the mach folder which support
+  Flattened Device Tree, which means, It works with any compatible board with
+  Device Trees.
+
+
+  Document Author
+  ---------------
+
+  Srinivas Kandagatla <srinivas.kandagatla@st.com>, (c) 2013 ST Microelectronics
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/arm/sti/stih415-overview.txt linux-libre-3.11-rc7-gnu/Documentation/arm/sti/stih415-overview.txt
--- linux-libre-3.10-gnu/Documentation/arm/sti/stih415-overview.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/arm/sti/stih415-overview.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,12 @@
+			STiH415 Overview
+			================
+
+Introduction
+------------
+
+    The STiH415 is the next generation of HD, AVC set-top box processors
+    for satellite, cable, terrestrial and IP-STB markets.
+
+    Features
+    - ARM Cortex-A9 1.0 GHz, dual-core CPU
+    - SATA2x2,USB 2.0x3, PCIe, Gbit Ethernet MACx2
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/arm/sti/stih416-overview.txt linux-libre-3.11-rc7-gnu/Documentation/arm/sti/stih416-overview.txt
--- linux-libre-3.10-gnu/Documentation/arm/sti/stih416-overview.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/arm/sti/stih416-overview.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,12 @@
+			STiH416 Overview
+			================
+
+Introduction
+------------
+
+    The STiH416 is the next generation of HD, AVC set-top box processors
+    for satellite, cable, terrestrial and IP-STB markets.
+
+    Features
+    - ARM Cortex-A9 1.2 GHz dual core CPU
+    - SATA2x2,USB 2.0x3, PCIe, Gbit Ethernet MACx2
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/arm/sunxi/README linux-libre-3.11-rc7-gnu/Documentation/arm/sunxi/README
--- linux-libre-3.10-gnu/Documentation/arm/sunxi/README	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/arm/sunxi/README	2013-08-25 20:43:22.000000000 -0400
@@ -3,17 +3,26 @@ ARM Allwinner SoCs
 
 This document lists all the ARM Allwinner SoCs that are currently
 supported in mainline by the Linux kernel. This document will also
-provide links to documentation and or datasheet for these SoCs.
+provide links to documentation and/or datasheet for these SoCs.
 
 SunXi family
 ------------
+  Linux kernel mach directory: arch/arm/mach-sunxi
 
   Flavors:
-        Allwinner A10 (sun4i)
-                Datasheet       : http://dl.linux-sunxi.org/A10/A10%20Datasheet%20-%20v1.21%20%282012-04-06%29.pdf
+    * ARM Cortex-A8 based SoCs
+      - Allwinner A10 (sun4i)
+        + Datasheet
+	  http://dl.linux-sunxi.org/A10/A10%20Datasheet%20-%20v1.21%20%282012-04-06%29.pdf
+	+ User Manual
+	  http://dl.linux-sunxi.org/A10/A10%20User%20Manual%20-%20v1.20%20%282012-04-09%2c%20DECRYPTED%29.pdf
 
-        Allwinner A13 (sun5i)
-                Datasheet       : http://dl.linux-sunxi.org/A13/A13%20Datasheet%20-%20v1.12%20%282012-03-29%29.pdf
+      - Allwinner A10s (sun5i)
+        + Datasheet
+          http://dl.linux-sunxi.org/A10s/A10s%20Datasheet%20-%20v1.20%20%282012-03-27%29.pdf
 
-  Core: Cortex A8
-  Linux kernel mach directory: arch/arm/mach-sunxi
\ No newline at end of file
+      - Allwinner A13 (sun5i)
+        + Datasheet
+	  http://dl.linux-sunxi.org/A13/A13%20Datasheet%20-%20v1.12%20%282012-03-29%29.pdf
+        + User Manual
+	  http://dl.linux-sunxi.org/A13/A13%20User%20Manual%20-%20v1.2%20%282013-08-08%29.pdf
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/arm64/memory.txt linux-libre-3.11-rc7-gnu/Documentation/arm64/memory.txt
--- linux-libre-3.10-gnu/Documentation/arm64/memory.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/arm64/memory.txt	2013-08-25 20:43:22.000000000 -0400
@@ -73,3 +73,10 @@ Translation table lookup with 64KB pages
  |                 |    +--------------------------> [41:29] L2 index (only 38:29 used)
  |                 +-------------------------------> [47:42] L1 index (not used)
  +-------------------------------------------------> [63] TTBR0/1
+
+When using KVM, the hypervisor maps kernel pages in EL2, at a fixed
+offset from the kernel VA (top 24bits of the kernel VA set to zero):
+
+Start			End			Size		Use
+-----------------------------------------------------------------------
+0000004000000000	0000007fffffffff	 256GB		kernel objects mapped in HYP
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/bcache.txt linux-libre-3.11-rc7-gnu/Documentation/bcache.txt
--- linux-libre-3.10-gnu/Documentation/bcache.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/bcache.txt	2013-08-25 20:43:22.000000000 -0400
@@ -46,29 +46,33 @@ you format your backing devices and cach
 have to manually attach:
   make-bcache -B /dev/sda /dev/sdb -C /dev/sdc
 
-To make bcache devices known to the kernel, echo them to /sys/fs/bcache/register:
+bcache-tools now ships udev rules, and bcache devices are known to the kernel
+immediately.  Without udev, you can manually register devices like this:
 
   echo /dev/sdb > /sys/fs/bcache/register
   echo /dev/sdc > /sys/fs/bcache/register
 
-To register your bcache devices automatically, you could add something like
-this to an init script:
+Registering the backing device makes the bcache device show up in /dev; you can
+now format it and use it as normal. But the first time using a new bcache
+device, it'll be running in passthrough mode until you attach it to a cache.
+See the section on attaching.
 
-  echo /dev/sd* > /sys/fs/bcache/register_quiet
+The devices show up as:
 
-It'll look for bcache superblocks and ignore everything that doesn't have one.
+  /dev/bcache<N>
 
-Registering the backing device makes the bcache show up in /dev; you can now
-format it and use it as normal. But the first time using a new bcache device,
-it'll be running in passthrough mode until you attach it to a cache. See the
-section on attaching.
+As well as (with udev):
 
-The devices show up at /dev/bcacheN, and can be controlled via sysfs from
-/sys/block/bcacheN/bcache:
+  /dev/bcache/by-uuid/<uuid>
+  /dev/bcache/by-label/<label>
+
+To get started:
 
   mkfs.ext4 /dev/bcache0
   mount /dev/bcache0 /mnt
 
+You can control bcache devices through sysfs at /sys/block/bcache<N>/bcache .
+
 Cache devices are managed as sets; multiple caches per set isn't supported yet
 but will allow for mirroring of metadata and dirty data in the future. Your new
 cache set shows up as /sys/fs/bcache/<UUID>
@@ -80,11 +84,11 @@ must be attached to your cache set to en
 device to a cache set is done thusly, with the UUID of the cache set in
 /sys/fs/bcache:
 
-  echo <UUID> > /sys/block/bcache0/bcache/attach
+  echo <CSET-UUID> > /sys/block/bcache0/bcache/attach
 
 This only has to be done once. The next time you reboot, just reregister all
 your bcache devices. If a backing device has data in a cache somewhere, the
-/dev/bcache# device won't be created until the cache shows up - particularly
+/dev/bcache<N> device won't be created until the cache shows up - particularly
 important if you have writeback caching turned on.
 
 If you're booting up and your cache device is gone and never coming back, you
@@ -181,7 +185,7 @@ want for getting the best possible numbe
 
    In practice this isn't an issue because as soon as a write comes along it'll
    cause the btree node to be split, and you need almost no write traffic for
-   this to not show up enough to be noticable (especially since bcache's btree
+   this to not show up enough to be noticeable (especially since bcache's btree
    nodes are huge and index large regions of the device). But when you're
    benchmarking, if you're trying to warm the cache by reading a bunch of data
    and there's no other traffic - that can be a problem.
@@ -191,6 +195,9 @@ want for getting the best possible numbe
 
 SYSFS - BACKING DEVICE:
 
+Available at /sys/block/<bdev>/bcache, /sys/block/bcache*/bcache and
+(if attached) /sys/fs/bcache/<cset-uuid>/bdev*
+
 attach
   Echo the UUID of a cache set to this file to enable caching.
 
@@ -222,7 +229,7 @@ running
   it's in passthrough mode or caching).
 
 sequential_cutoff
-  A sequential IO will bypass the cache once it passes this threshhold; the
+  A sequential IO will bypass the cache once it passes this threshold; the
   most recent 128 IOs are tracked so sequential IO can be detected even when
   it isn't all done at once.
 
@@ -296,10 +303,12 @@ cache_miss_collisions
   since the synchronization for cache misses was rewritten)
 
 cache_readaheads
-  Count of times readahead occured.
+  Count of times readahead occurred.
 
 SYSFS - CACHE SET:
 
+Available at /sys/fs/bcache/<cset-uuid>
+
 average_key_size
   Average data per key in the btree.
 
@@ -362,7 +371,7 @@ unregister
 SYSFS - CACHE SET INTERNAL:
 
 This directory also exposes timings for a number of internal operations, with
-separate files for average duration, average frequency, last occurence and max
+separate files for average duration, average frequency, last occurrence and max
 duration: garbage collection, btree read, btree node sorts and btree splits.
 
 active_journal_entries
@@ -390,6 +399,8 @@ trigger_gc
 
 SYSFS - CACHE DEVICE:
 
+Available at /sys/block/<cdev>/bcache
+
 block_size
   Minimum granularity of writes - should match hardware sector size.
 
@@ -417,7 +428,7 @@ freelist_percent
   space.
 
 io_errors
-  Number of errors that have occured, decayed by io_error_halflife.
+  Number of errors that have occurred, decayed by io_error_halflife.
 
 metadata_written
   Sum of all non data writes (btree writes and all other metadata).
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/block/queue-sysfs.txt linux-libre-3.11-rc7-gnu/Documentation/block/queue-sysfs.txt
--- linux-libre-3.10-gnu/Documentation/block/queue-sysfs.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/block/queue-sysfs.txt	2013-08-25 20:43:22.000000000 -0400
@@ -93,7 +93,7 @@ To avoid priority inversion through requ
 queue maintains a separate request pool per each cgroup when
 CONFIG_BLK_CGROUP is enabled, and this parameter applies to each such
 per-block-cgroup request pool.  IOW, if there are N block cgroups,
-each request queue may have upto N request pools, each independently
+each request queue may have up to N request pools, each independently
 regulated by nr_requests.
 
 optimal_io_size (RO)
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/cgroups/blkio-controller.txt linux-libre-3.11-rc7-gnu/Documentation/cgroups/blkio-controller.txt
--- linux-libre-3.10-gnu/Documentation/cgroups/blkio-controller.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/cgroups/blkio-controller.txt	2013-08-25 20:43:22.000000000 -0400
@@ -94,11 +94,13 @@ Throttling/Upper Limit policy
 
 Hierarchical Cgroups
 ====================
-- Currently only CFQ supports hierarchical groups. For throttling,
-  cgroup interface does allow creation of hierarchical cgroups and
-  internally it treats them as flat hierarchy.
 
-  If somebody created a hierarchy like as follows.
+Both CFQ and throttling implement hierarchy support; however,
+throttling's hierarchy support is enabled iff "sane_behavior" is
+enabled from cgroup side, which currently is a development option and
+not publicly available.
+
+If somebody created a hierarchy like as follows.
 
 			root
 			/  \
@@ -106,21 +108,20 @@ Hierarchical Cgroups
 			|
 		     test3
 
-  CFQ will handle the hierarchy correctly but and throttling will
-  practically treat all groups at same level. For details on CFQ
-  hierarchy support, refer to Documentation/block/cfq-iosched.txt.
-  Throttling will treat the hierarchy as if it looks like the
-  following.
+CFQ by default and throttling with "sane_behavior" will handle the
+hierarchy correctly.  For details on CFQ hierarchy support, refer to
+Documentation/block/cfq-iosched.txt.  For throttling, all limits apply
+to the whole subtree while all statistics are local to the IOs
+directly generated by tasks in that cgroup.
+
+Throttling without "sane_behavior" enabled from cgroup side will
+practically treat all groups at same level as if it looks like the
+following.
 
 				pivot
 			     /  /   \  \
 			root  test1 test2  test3
 
-  Nesting cgroups, while allowed, isn't officially supported and blkio
-  genereates warning when cgroups nest. Once throttling implements
-  hierarchy support, hierarchy will be supported and the warning will
-  be removed.
-
 Various user visible config options
 ===================================
 CONFIG_BLK_CGROUP
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/cgroups/cpusets.txt linux-libre-3.11-rc7-gnu/Documentation/cgroups/cpusets.txt
--- linux-libre-3.10-gnu/Documentation/cgroups/cpusets.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/cgroups/cpusets.txt	2013-08-25 20:43:22.000000000 -0400
@@ -373,7 +373,7 @@ can become very uneven.
 1.7 What is sched_load_balance ?
 --------------------------------
 
-The kernel scheduler (kernel/sched.c) automatically load balances
+The kernel scheduler (kernel/sched/core.c) automatically load balances
 tasks.  If one CPU is underutilized, kernel code running on that
 CPU will look for tasks on other more overloaded CPUs and move those
 tasks to itself, within the constraints of such placement mechanisms
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/cgroups/memory.txt linux-libre-3.11-rc7-gnu/Documentation/cgroups/memory.txt
--- linux-libre-3.10-gnu/Documentation/cgroups/memory.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/cgroups/memory.txt	2013-08-25 20:43:22.000000000 -0400
@@ -304,7 +304,7 @@ kernel memory, we prevent new processes
 memory usage is too high.
 
 * slab pages: pages allocated by the SLAB or SLUB allocator are tracked. A copy
-of each kmem_cache is created everytime the cache is touched by the first time
+of each kmem_cache is created every time the cache is touched by the first time
 from inside the memcg. The creation is done lazily, so some objects can still be
 skipped while the cache is being created. All objects in a slab page should
 belong to the same memcg. This only fails to hold when a task is migrated to a
@@ -490,10 +490,10 @@ pgpgin		- # of charging events to the me
 pgpgout		- # of uncharging events to the memory cgroup. The uncharging
 		event happens each time a page is unaccounted from the cgroup.
 swap		- # of bytes of swap usage
-inactive_anon	- # of bytes of anonymous memory and swap cache memory on
+inactive_anon	- # of bytes of anonymous and swap cache memory on inactive
 		LRU list.
 active_anon	- # of bytes of anonymous and swap cache memory on active
-		inactive LRU list.
+		LRU list.
 inactive_file	- # of bytes of file-backed memory on inactive LRU list.
 active_file	- # of bytes of file-backed memory on active LRU list.
 unevictable	- # of bytes of memory that cannot be reclaimed (mlocked etc).
@@ -834,10 +834,9 @@ Test:
 
 12. TODO
 
-1. Add support for accounting huge pages (as a separate controller)
-2. Make per-cgroup scanner reclaim not-shared pages first
-3. Teach controller to account for shared-pages
-4. Start reclamation in the background when the limit is
+1. Make per-cgroup scanner reclaim not-shared pages first
+2. Teach controller to account for shared-pages
+3. Start reclamation in the background when the limit is
    not yet hit but the usage is getting closer
 
 Summary
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/clk.txt linux-libre-3.11-rc7-gnu/Documentation/clk.txt
--- linux-libre-3.10-gnu/Documentation/clk.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/clk.txt	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,7 @@ hardware-specific bits for the hypotheti
 
 Tying the two halves of this interface together is struct clk_hw, which
 is defined in struct clk_foo and pointed to within struct clk.  This
-allows easy for navigation between the two discrete halves of the common
+allows for easy navigation between the two discrete halves of the common
 clock interface.
 
 	Part 2 - common data structures and api
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/coccinelle.txt linux-libre-3.11-rc7-gnu/Documentation/coccinelle.txt
--- linux-libre-3.10-gnu/Documentation/coccinelle.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/coccinelle.txt	2013-08-25 20:43:22.000000000 -0400
@@ -6,15 +6,17 @@ Copyright 2010 Gilles Muller <Gilles.Mul
  Getting Coccinelle
 ~~~~~~~~~~~~~~~~~~~~
 
-The semantic patches included in the kernel use the 'virtual rule'
-feature which was introduced in Coccinelle version 0.1.11.
+The semantic patches included in the kernel use features and options
+which are provided by Coccinelle version 1.0.0-rc11 and above.
+Using earlier versions will fail as the option names used by
+the Coccinelle files and coccicheck have been updated.
 
-Coccinelle (>=0.2.0) is available through the package manager
+Coccinelle is available through the package manager
 of many distributions, e.g. :
 
- - Debian (>=squeeze)
- - Fedora (>=13)
- - Ubuntu (>=10.04 Lucid Lynx)
+ - Debian
+ - Fedora
+ - Ubuntu
  - OpenSUSE
  - Arch Linux
  - NetBSD
@@ -36,11 +38,6 @@ as a regular user, and install it with
 
         sudo make install
 
-The semantic patches in the kernel will work best with Coccinelle version
-0.2.4 or later.  Using earlier versions may incur some parse errors in the
-semantic patch code, but any results that are obtained should still be
-correct.
-
  Using Coccinelle on the Linux kernel
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -48,7 +45,7 @@ A Coccinelle-specific target is defined
 Makefile. This target is named 'coccicheck' and calls the 'coccicheck'
 front-end in the 'scripts' directory.
 
-Four modes are defined: patch, report, context, and org. The mode to
+Four basic modes are defined: patch, report, context, and org. The mode to
 use is specified by setting the MODE variable with 'MODE=<mode>'.
 
 'patch' proposes a fix, when possible.
@@ -62,18 +59,24 @@ diff-like style.Lines of interest are in
 'org' generates a report in the Org mode format of Emacs.
 
 Note that not all semantic patches implement all modes. For easy use
-of Coccinelle, the default mode is "chain" which tries the previous
-modes in the order above until one succeeds.
+of Coccinelle, the default mode is "report".
 
-To make a report for every semantic patch, run the following command:
+Two other modes provide some common combinations of these modes.
 
-	make coccicheck MODE=report
+'chain' tries the previous modes in the order above until one succeeds.
 
-NB: The 'report' mode is the default one.
+'rep+ctxt' runs successively the report mode and the context mode.
+	   It should be used with the C option (described later)
+	   which checks the code on a file basis.
 
-To produce patches, run:
+Examples:
+	To make a report for every semantic patch, run the following command:
 
-	make coccicheck MODE=patch
+		make coccicheck MODE=report
+
+	To produce patches, run:
+
+		make coccicheck MODE=patch
 
 
 The coccicheck target applies every semantic patch available in the
@@ -91,6 +94,11 @@ To enable verbose messages set the V= va
 
    make coccicheck MODE=report V=1
 
+By default, coccicheck tries to run as parallel as possible. To change
+the parallelism, set the J= variable. For example, to run across 4 CPUs:
+
+   make coccicheck MODE=report J=4
+
 
  Using Coccinelle with a single semantic patch
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -124,26 +132,33 @@ To check only newly edited code, use the
 
     make C=2 CHECK="scripts/coccicheck"
 
+In these modes, which works on a file basis, there is no information
+about semantic patches displayed, and no commit message proposed.
+
 This runs every semantic patch in scripts/coccinelle by default. The
 COCCI variable may additionally be used to only apply a single
 semantic patch as shown in the previous section.
 
-The "chain" mode is the default. You can select another one with the
+The "report" mode is the default. You can select another one with the
 MODE variable explained above.
 
-In this mode, there is no information about semantic patches
-displayed, and no commit message proposed.
-
  Additional flags
 ~~~~~~~~~~~~~~~~~~
 
 Additional flags can be passed to spatch through the SPFLAGS
 variable.
 
-    make SPFLAGS=--use_glimpse coccicheck
+    make SPFLAGS=--use-glimpse coccicheck
+    make SPFLAGS=--use-idutils coccicheck
 
 See spatch --help to learn more about spatch options.
 
+Note that the '--use-glimpse' and '--use-idutils' options
+require external tools for indexing the code. None of them is
+thus active by default. However, by indexing the code with
+one of these tools, and according to the cocci file used,
+spatch could proceed the entire code base more quickly.
+
  Proposing new semantic patches
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/CodingStyle linux-libre-3.11-rc7-gnu/Documentation/CodingStyle
--- linux-libre-3.10-gnu/Documentation/CodingStyle	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/CodingStyle	2013-08-25 20:43:22.000000000 -0400
@@ -389,7 +389,8 @@ Albeit deprecated by some people, the eq
 used frequently by compilers in form of the unconditional jump instruction.
 
 The goto statement comes in handy when a function exits from multiple
-locations and some common work such as cleanup has to be done.
+locations and some common work such as cleanup has to be done.  If there is no
+cleanup needed then just return directly.
 
 The rationale is:
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/console/console.txt linux-libre-3.11-rc7-gnu/Documentation/console/console.txt
--- linux-libre-3.10-gnu/Documentation/console/console.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/console/console.txt	2013-08-25 20:43:22.000000000 -0400
@@ -12,20 +12,20 @@ The second type has to be explicitly loa
 any time with each driver sharing the console with other drivers including
 the system driver. However, modular drivers cannot take over the console
 that is currently occupied by another modular driver. (Exception: Drivers that
-call take_over_console() will succeed in the takeover regardless of the type
+call do_take_over_console() will succeed in the takeover regardless of the type
 of driver occupying the consoles.) They can only take over the console that is
 occupied by the system driver. In the same token, if the modular driver is
 released by the console, the system driver will take over.
 
 Modular drivers, from the programmer's point of view, has to call:
 
-	 take_over_console() - load and bind driver to console layer
-	 give_up_console() - unbind and unload driver
+	 do_take_over_console() - load and bind driver to console layer
+	 give_up_console() - unload driver, it will only work if driver is fully unbond
 
 In newer kernels, the following are also available:
 
-	 register_con_driver()
-	 unregister_con_driver()
+	 do_register_con_driver()
+	 do_unregister_con_driver()
 
 If sysfs is enabled, the contents of /sys/class/vtconsole can be
 examined. This shows the console backends currently registered by the
@@ -94,12 +94,12 @@ for more details).
 Notes for developers:
 =====================
 
-take_over_console() is now broken up into:
+do_take_over_console() is now broken up into:
 
-     register_con_driver()
-     bind_con_driver() - private function
+     do_register_con_driver()
+     do_bind_con_driver() - private function
 
-give_up_console() is a wrapper to unregister_con_driver(), and a driver must
+give_up_console() is a wrapper to do_unregister_con_driver(), and a driver must
 be fully unbound for this call to succeed. con_is_bound() will check if the
 driver is bound or not.
 
@@ -109,10 +109,10 @@ Guidelines for console driver writers:
 In order for binding to and unbinding from the console to properly work,
 console drivers must follow these guidelines:
 
-1. All drivers, except system drivers, must call either register_con_driver()
-   or take_over_console(). register_con_driver() will just add the driver to
+1. All drivers, except system drivers, must call either do_register_con_driver()
+   or do_take_over_console(). do_register_con_driver() will just add the driver to
    the console's internal list. It won't take over the
-   console. take_over_console(), as it name implies, will also take over (or
+   console. do_take_over_console(), as it name implies, will also take over (or
    bind to) the console.
 
 2. All resources allocated during con->con_init() must be released in
@@ -128,10 +128,10 @@ console drivers must follow these guidel
    rebind the driver to the console arrives.
 
 4. Upon exit of the driver, ensure that the driver is totally unbound. If the
-   condition is satisfied, then the driver must call unregister_con_driver()
+   condition is satisfied, then the driver must call do_unregister_con_driver()
    or give_up_console().
 
-5. unregister_con_driver() can also be called on conditions which make it
+5. do_unregister_con_driver() can also be called on conditions which make it
    impossible for the driver to service console requests.  This can happen
    with the framebuffer console that suddenly lost all of its drivers.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/cpu-freq/cpu-drivers.txt linux-libre-3.11-rc7-gnu/Documentation/cpu-freq/cpu-drivers.txt
--- linux-libre-3.10-gnu/Documentation/cpu-freq/cpu-drivers.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/cpu-freq/cpu-drivers.txt	2013-08-25 20:43:22.000000000 -0400
@@ -186,7 +186,7 @@ As most cpufreq processors only allow fo
 frequencies, a "frequency table" with some functions might assist in
 some work of the processor driver. Such a "frequency table" consists
 of an array of struct cpufreq_frequency_table entries, with any value in
-"index" you want to use, and the corresponding frequency in
+"driver_data" you want to use, and the corresponding frequency in
 "frequency". At the end of the table, you need to add a
 cpufreq_frequency_table entry with frequency set to CPUFREQ_TABLE_END. And
 if you want to skip one entry in the table, set the frequency to 
@@ -214,10 +214,4 @@ int cpufreq_frequency_table_target(struc
 is the corresponding frequency table helper for the ->target
 stage. Just pass the values to this function, and the unsigned int
 index returns the number of the frequency table entry which contains
-the frequency the CPU shall be set to. PLEASE NOTE: This is not the
-"index" which is in this cpufreq_table_entry.index, but instead
-cpufreq_table[index]. So, the new frequency is
-cpufreq_table[index].frequency, and the value you stored into the
-frequency table "index" field is
-cpufreq_table[index].index.
-
+the frequency the CPU shall be set to.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/cpu-hotplug.txt linux-libre-3.11-rc7-gnu/Documentation/cpu-hotplug.txt
--- linux-libre-3.10-gnu/Documentation/cpu-hotplug.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/cpu-hotplug.txt	2013-08-25 20:43:22.000000000 -0400
@@ -128,7 +128,7 @@ A: When doing make defconfig, Enable CPU
 
    "Processor type and Features" -> Support for Hotpluggable CPUs
 
-Make sure that you have CONFIG_HOTPLUG, and CONFIG_SMP turned on as well.
+Make sure that you have CONFIG_SMP turned on as well.
 
 You would need to enable CONFIG_HOTPLUG_CPU for SMP suspend/resume support
 as well.
@@ -267,8 +267,8 @@ Q: If i have some kernel code that needs
 A: This is what you would need in your kernel code to receive notifications.
 
 	#include <linux/cpu.h>
-	static int __cpuinit foobar_cpu_callback(struct notifier_block *nfb,
-					    unsigned long action, void *hcpu)
+	static int foobar_cpu_callback(struct notifier_block *nfb,
+				       unsigned long action, void *hcpu)
 	{
 		unsigned int cpu = (unsigned long)hcpu;
 
@@ -285,7 +285,7 @@ A: This is what you would need in your k
 		return NOTIFY_OK;
 	}
 
-	static struct notifier_block __cpuinitdata foobar_cpu_notifer =
+	static struct notifier_block foobar_cpu_notifer =
 	{
 	   .notifier_call = foobar_cpu_callback,
 	};
@@ -370,8 +370,10 @@ A: There is no clear spec defined way fr
    CPUs in MADT as hotpluggable CPUS.  In the case there are no disabled CPUS
    we assume 1/2 the number of CPUs currently present can be hotplugged.
 
-   Caveat: Today's ACPI MADT can only provide 256 entries since the apicid field
-   in MADT is only 8 bits.
+   Caveat: ACPI MADT can only provide 256 entries in systems with only ACPI 2.0c
+   or earlier ACPI version supported, because the apicid field in MADT is only
+   8 bits. From ACPI 3.0, this limitation was removed since the apicid field
+   was extended to 32 bits with x2APIC introduced.
 
 User Space Notification
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/crypto/async-tx-api.txt linux-libre-3.11-rc7-gnu/Documentation/crypto/async-tx-api.txt
--- linux-libre-3.10-gnu/Documentation/crypto/async-tx-api.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/crypto/async-tx-api.txt	2013-08-25 20:43:22.000000000 -0400
@@ -222,5 +222,4 @@ drivers/dma/: location for offload engin
 include/linux/async_tx.h: core header file for the async_tx api
 crypto/async_tx/async_tx.c: async_tx interface to dmaengine and common code
 crypto/async_tx/async_memcpy.c: copy offload
-crypto/async_tx/async_memset.c: memory fill offload
 crypto/async_tx/async_xor.c: xor and xor zero sum offload
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/device-mapper/cache.txt linux-libre-3.11-rc7-gnu/Documentation/device-mapper/cache.txt
--- linux-libre-3.10-gnu/Documentation/device-mapper/cache.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/device-mapper/cache.txt	2013-08-25 20:43:22.000000000 -0400
@@ -87,7 +87,7 @@ Migration throttling
 
 Migrating data between the origin and cache device uses bandwidth.
 The user can set a throttle to prevent more than a certain amount of
-migration occuring at any one time.  Currently we're not taking any
+migration occurring at any one time.  Currently we're not taking any
 account of normal io traffic going to the devices.  More work needs
 doing here to avoid migrating during those peak io moments.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/device-mapper/dm-raid.txt linux-libre-3.11-rc7-gnu/Documentation/device-mapper/dm-raid.txt
--- linux-libre-3.10-gnu/Documentation/device-mapper/dm-raid.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/device-mapper/dm-raid.txt	2013-08-25 20:43:22.000000000 -0400
@@ -222,3 +222,5 @@ Version History
 1.4.2   Add RAID10 "far" and "offset" algorithm support.
 1.5.0   Add message interface to allow manipulation of the sync_action.
 	New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt.
+1.5.1   Add ability to restore transiently failed devices on resume.
+1.5.2   'mismatch_cnt' is zero unless [last_]sync_action is "check".
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/device-mapper/switch.txt linux-libre-3.11-rc7-gnu/Documentation/device-mapper/switch.txt
--- linux-libre-3.10-gnu/Documentation/device-mapper/switch.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/device-mapper/switch.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,126 @@
+dm-switch
+=========
+
+The device-mapper switch target creates a device that supports an
+arbitrary mapping of fixed-size regions of I/O across a fixed set of
+paths.  The path used for any specific region can be switched
+dynamically by sending the target a message.
+
+It maps I/O to underlying block devices efficiently when there is a large
+number of fixed-sized address regions but there is no simple pattern
+that would allow for a compact representation of the mapping such as
+dm-stripe.
+
+Background
+----------
+
+Dell EqualLogic and some other iSCSI storage arrays use a distributed
+frameless architecture.  In this architecture, the storage group
+consists of a number of distinct storage arrays ("members") each having
+independent controllers, disk storage and network adapters.  When a LUN
+is created it is spread across multiple members.  The details of the
+spreading are hidden from initiators connected to this storage system.
+The storage group exposes a single target discovery portal, no matter
+how many members are being used.  When iSCSI sessions are created, each
+session is connected to an eth port on a single member.  Data to a LUN
+can be sent on any iSCSI session, and if the blocks being accessed are
+stored on another member the I/O will be forwarded as required.  This
+forwarding is invisible to the initiator.  The storage layout is also
+dynamic, and the blocks stored on disk may be moved from member to
+member as needed to balance the load.
+
+This architecture simplifies the management and configuration of both
+the storage group and initiators.  In a multipathing configuration, it
+is possible to set up multiple iSCSI sessions to use multiple network
+interfaces on both the host and target to take advantage of the
+increased network bandwidth.  An initiator could use a simple round
+robin algorithm to send I/O across all paths and let the storage array
+members forward it as necessary, but there is a performance advantage to
+sending data directly to the correct member.
+
+A device-mapper table already lets you map different regions of a
+device onto different targets.  However in this architecture the LUN is
+spread with an address region size on the order of 10s of MBs, which
+means the resulting table could have more than a million entries and
+consume far too much memory.
+
+Using this device-mapper switch target we can now build a two-layer
+device hierarchy:
+
+    Upper Tier – Determine which array member the I/O should be sent to.
+    Lower Tier – Load balance amongst paths to a particular member.
+
+The lower tier consists of a single dm multipath device for each member.
+Each of these multipath devices contains the set of paths directly to
+the array member in one priority group, and leverages existing path
+selectors to load balance amongst these paths.  We also build a
+non-preferred priority group containing paths to other array members for
+failover reasons.
+
+The upper tier consists of a single dm-switch device.  This device uses
+a bitmap to look up the location of the I/O and choose the appropriate
+lower tier device to route the I/O.  By using a bitmap we are able to
+use 4 bits for each address range in a 16 member group (which is very
+large for us).  This is a much denser representation than the dm table
+b-tree can achieve.
+
+Construction Parameters
+=======================
+
+    <num_paths> <region_size> <num_optional_args> [<optional_args>...]
+    [<dev_path> <offset>]+
+
+<num_paths>
+    The number of paths across which to distribute the I/O.
+
+<region_size>
+    The number of 512-byte sectors in a region. Each region can be redirected
+    to any of the available paths.
+
+<num_optional_args>
+    The number of optional arguments. Currently, no optional arguments
+    are supported and so this must be zero.
+
+<dev_path>
+    The block device that represents a specific path to the device.
+
+<offset>
+    The offset of the start of data on the specific <dev_path> (in units
+    of 512-byte sectors). This number is added to the sector number when
+    forwarding the request to the specific path. Typically it is zero.
+
+Messages
+========
+
+set_region_mappings <index>:<path_nr> [<index>]:<path_nr> [<index>]:<path_nr>...
+
+Modify the region table by specifying which regions are redirected to
+which paths.
+
+<index>
+    The region number (region size was specified in constructor parameters).
+    If index is omitted, the next region (previous index + 1) is used.
+    Expressed in hexadecimal (WITHOUT any prefix like 0x).
+
+<path_nr>
+    The path number in the range 0 ... (<num_paths> - 1).
+    Expressed in hexadecimal (WITHOUT any prefix like 0x).
+
+Status
+======
+
+No status line is reported.
+
+Example
+=======
+
+Assume that you have volumes vg1/switch0 vg1/switch1 vg1/switch2 with
+the same size.
+
+Create a switch device with 64kB region size:
+    dmsetup create switch --table "0 `blockdev --getsize /dev/vg1/switch0`
+	switch 3 128 0 /dev/vg1/switch0 0 /dev/vg1/switch1 0 /dev/vg1/switch2 0"
+
+Set mappings for the first 7 entries to point to devices switch0, switch1,
+switch2, switch0, switch1, switch2, switch1:
+    dmsetup message switch 0 set_region_mappings 0:0 :1 :2 :0 :1 :2 :1
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devices.txt linux-libre-3.11-rc7-gnu/Documentation/devices.txt
--- linux-libre-3.10-gnu/Documentation/devices.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devices.txt	2013-08-25 20:43:22.000000000 -0400
@@ -100,8 +100,7 @@ Your cooperation is appreciated.
 		 10 = /dev/aio		Asynchronous I/O notification interface
 		 11 = /dev/kmsg		Writes to this come out as printk's, reads
 					export the buffered printk records.
-		 12 = /dev/oldmem	Used by crashdump kernels to access
-					the memory of the kernel that crashed.
+		 12 = /dev/oldmem	OBSOLETE - replaced by /proc/vmcore
 
   1 block	RAM disk
 		  0 = /dev/ram0		First RAM disk
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/cci.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/cci.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/cci.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/cci.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,172 @@
+=======================================================
+ARM CCI cache coherent interconnect binding description
+=======================================================
+
+ARM multi-cluster systems maintain intra-cluster coherency through a
+cache coherent interconnect (CCI) that is capable of monitoring bus
+transactions and manage coherency, TLB invalidations and memory barriers.
+
+It allows snooping and distributed virtual memory message broadcast across
+clusters, through memory mapped interface, with a global control register
+space and multiple sets of interface control registers, one per slave
+interface.
+
+Bindings for the CCI node follow the ePAPR standard, available from:
+
+www.power.org/documentation/epapr-version-1-1/
+
+with the addition of the bindings described in this document which are
+specific to ARM.
+
+* CCI interconnect node
+
+	Description: Describes a CCI cache coherent Interconnect component
+
+	Node name must be "cci".
+	Node's parent must be the root node /, and the address space visible
+	through the CCI interconnect is the same as the one seen from the
+	root node (ie from CPUs perspective as per DT standard).
+	Every CCI node has to define the following properties:
+
+	- compatible
+		Usage: required
+		Value type: <string>
+		Definition: must be set to
+			    "arm,cci-400"
+
+	- reg
+		Usage: required
+		Value type: <prop-encoded-array>
+		Definition: A standard property. Specifies base physical
+			    address of CCI control registers common to all
+			    interfaces.
+
+	- ranges:
+		Usage: required
+		Value type: <prop-encoded-array>
+		Definition: A standard property. Follow rules in the ePAPR for
+			    hierarchical bus addressing. CCI interfaces
+			    addresses refer to the parent node addressing
+			    scheme to declare their register bases.
+
+	CCI interconnect node can define the following child nodes:
+
+	- CCI control interface nodes
+
+		Node name must be "slave-if".
+		Parent node must be CCI interconnect node.
+
+		A CCI control interface node must contain the following
+		properties:
+
+		- compatible
+			Usage: required
+			Value type: <string>
+			Definition: must be set to
+				    "arm,cci-400-ctrl-if"
+
+		- interface-type:
+			Usage: required
+			Value type: <string>
+			Definition: must be set to one of {"ace", "ace-lite"}
+				    depending on the interface type the node
+				    represents.
+
+		- reg:
+			Usage: required
+			Value type: <prop-encoded-array>
+			Definition: the base address and size of the
+				    corresponding interface programming
+				    registers.
+
+* CCI interconnect bus masters
+
+	Description: masters in the device tree connected to a CCI port
+		     (inclusive of CPUs and their cpu nodes).
+
+	A CCI interconnect bus master node must contain the following
+	properties:
+
+	- cci-control-port:
+		Usage: required
+		Value type: <phandle>
+		Definition: a phandle containing the CCI control interface node
+			    the master is connected to.
+
+Example:
+
+	cpus {
+		#size-cells = <0>;
+		#address-cells = <1>;
+
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			cci-control-port = <&cci_control1>;
+			reg = <0x0>;
+		};
+
+		CPU1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			cci-control-port = <&cci_control1>;
+			reg = <0x1>;
+		};
+
+		CPU2: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			cci-control-port = <&cci_control2>;
+			reg = <0x100>;
+		};
+
+		CPU3: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			cci-control-port = <&cci_control2>;
+			reg = <0x101>;
+		};
+
+	};
+
+	dma0: dma@3000000 {
+		compatible = "arm,pl330", "arm,primecell";
+		cci-control-port = <&cci_control0>;
+		reg = <0x0 0x3000000 0x0 0x1000>;
+		interrupts = <10>;
+		#dma-cells = <1>;
+		#dma-channels = <8>;
+		#dma-requests = <32>;
+	};
+
+	cci@2c090000 {
+		compatible = "arm,cci-400";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x0 0x2c090000 0 0x1000>;
+		ranges = <0x0 0x0 0x2c090000 0x6000>;
+
+		cci_control0: slave-if@1000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace-lite";
+			reg = <0x1000 0x1000>;
+		};
+
+		cci_control1: slave-if@4000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x4000 0x1000>;
+		};
+
+		cci_control2: slave-if@5000 {
+			compatible = "arm,cci-400-ctrl-if";
+			interface-type = "ace";
+			reg = <0x5000 0x1000>;
+		};
+	};
+
+This CCI node corresponds to a CCI component whose control registers sits
+at address 0x000000002c090000.
+CCI slave interface @0x000000002c091000 is connected to dma controller dma0.
+CCI slave interface @0x000000002c094000 is connected to CPUs {CPU0, CPU1};
+CCI slave interface @0x000000002c095000 is connected to CPUs {CPU2, CPU3};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/global_timer.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/global_timer.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/global_timer.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/global_timer.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,24 @@
+
+* ARM Global Timer
+	Cortex-A9 are often associated with a per-core Global timer.
+
+** Timer node required properties:
+
+- compatible : Should be "arm,cortex-a9-global-timer"
+		Driver supports versions r2p0 and above.
+
+- interrupts : One interrupt to each core
+
+- reg : Specify the base address and the size of the GT timer
+	register window.
+
+- clocks : Should be phandle to a clock.
+
+Example:
+
+	timer@2c000600 {
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0x2c000600 0x20>;
+		interrupts = <1 13 0xf01>;
+		clocks = <&arm_periph_clk>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/keystone/keystone.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/keystone/keystone.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/keystone/keystone.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/keystone/keystone.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+TI Keystone Platforms Device Tree Bindings
+-----------------------------------------------
+
+Boards with Keystone2 based devices (TCI66xxK2H) SOC shall have the
+following properties.
+
+Required properties:
+ - compatible: All TI specific devices present in Keystone SOC should be in
+   the form "ti,keystone-*". Generic devices like gic, arch_timers, ns16550
+   type UART should use the specified compatible for those devices.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/l2cc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/l2cc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/l2cc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/l2cc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,9 @@ Required properties:
      performs the same operation).
 	"marvell,"aurora-outer-cache: Marvell Controller designed to be
 	 compatible with the ARM one with outer cache mode.
+	"bcm,bcm11351-a2-pl310-cache": For Broadcom bcm11351 chipset where an
+	offset needs to be added to the address before passing down to the L2
+	cache controller
 - cache-unified : Specifies the cache is a unified cache.
 - cache-level : Should be set to 2 for a level 2 cache.
 - reg : Physical base address and size of cache controller's memory mapped
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/nspire.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/nspire.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/nspire.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/nspire.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,14 @@
+TI-NSPIRE calculators
+
+Required properties:
+- compatible: Compatible property value should contain "ti,nspire".
+	CX models should have "ti,nspire-cx"
+	Touchpad models should have "ti,nspire-tp"
+	Clickpad models should have "ti,nspire-clp"
+
+Example:
+
+/ {
+	model = "TI-NSPIRE CX";
+	compatible = "ti,nspire-cx";
+	...
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/omap/omap.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/omap/omap.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/omap/omap.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/omap/omap.txt	2013-08-25 20:43:22.000000000 -0400
@@ -56,3 +56,6 @@ Boards:
 
 - OMAP5 EVM : Evaluation Module
   compatible = "ti,omap5-evm", "ti,omap5"
+
+- AM43x EPOS EVM
+  compatible = "ti,am43x-epos-evm", "ti,am4372", "ti,am43"
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/rtsm-dcscb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/rtsm-dcscb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/rtsm-dcscb.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/rtsm-dcscb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,19 @@
+ARM Dual Cluster System Configuration Block
+-------------------------------------------
+
+The Dual Cluster System Configuration Block (DCSCB) provides basic
+functionality for controlling clocks, resets and configuration pins in
+the Dual Cluster System implemented by the Real-Time System Model (RTSM).
+
+Required properties:
+
+- compatible : should be "arm,rtsm,dcscb"
+
+- reg : physical base address and the size of the registers window
+
+Example:
+
+	dcscb@60000000 {
+		compatible = "arm,rtsm,dcscb";
+		reg = <0x60000000 0x1000>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/samsung/interrupt-combiner.txt	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,7 @@ can combine interrupt sources as a group
 for the group. The interrupt request from each group are connected to a parent
 interrupt controller, such as GIC in case of Exynos4210.
 
-The interrupt combiner controller consists of multiple combiners. Upto eight
+The interrupt combiner controller consists of multiple combiners. Up to eight
 interrupt sources can be connected to a combiner. The combiner outputs one
 combined interrupt for its eight interrupt sources. The combined interrupt
 is usually connected to a parent interrupt controller.
@@ -14,8 +14,8 @@ A single node in the device tree is used
 controller module (which includes multiple combiners). A combiner in the
 interrupt controller module shares config/control registers with other
 combiners. For example, a 32-bit interrupt enable/disable config register
-can accommodate upto 4 interrupt combiners (with each combiner supporting
-upto 8 interrupt sources).
+can accommodate up to 4 interrupt combiners (with each combiner supporting
+up to 8 interrupt sources).
 
 Required properties:
 - compatible: should be "samsung,exynos4210-combiner".
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/spear/shirq.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/spear/shirq.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/spear/shirq.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/spear/shirq.txt	2013-08-25 20:43:22.000000000 -0400
@@ -14,7 +14,7 @@ A single node in the device tree is used
 interrupt multiplexor (one node for all groups). A group in the
 interrupt controller shares config/control registers with other groups.
 For example, a 32-bit interrupt enable/disable config register can
-accommodate upto 4 interrupt groups.
+accommodate up to 4 interrupt groups.
 
 Required properties:
   - compatible: should be, either of
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/ste-nomadik.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/ste-nomadik.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/ste-nomadik.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/ste-nomadik.txt	2013-08-25 20:43:22.000000000 -0400
@@ -3,6 +3,11 @@ ST-Ericsson Nomadik Device Tree Bindings
 For various board the "board" node may contain specific properties
 that pertain to this particular board, such as board-specific GPIOs.
 
+Required root node property: src
+- Nomadik System and reset controller used for basic chip control, clock
+  and reset line control.
+- compatible: must be "stericsson,nomadik,src"
+
 Boards with the Nomadik SoC include:
 
 S8815 "MiniKit" manufactured by Calao Systems:
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/ste-u300.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/ste-u300.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/arm/ste-u300.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/arm/ste-u300.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,46 @@
+ST-Ericsson U300 Device Tree Bindings
+
+For various board the "board" node may contain specific properties
+that pertain to this particular board, such as board-specific GPIOs
+or board power regulator supplies.
+
+Required root node property:
+
+compatible="stericsson,u300";
+
+Required node: syscon
+This contains the system controller.
+- compatible: must be "stericsson,u300-syscon".
+- reg: the base address and size of the system controller.
+
+Boards with the U300 SoC include:
+
+S365 "Small Board U365":
+
+Required node: s365
+This contains the board-specific information.
+- compatible: must be "stericsson,s365".
+- vana15-supply: the regulator supplying the 1.5V to drive the
+  board.
+- syscon: a pointer to the syscon node so we can acccess the
+  syscon registers to set the board as self-powered.
+
+Example:
+
+/ {
+	model = "ST-Ericsson U300";
+	compatible = "stericsson,u300";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	s365 {
+		compatible = "stericsson,s365";
+		vana15-supply = <&ab3100_ldo_d_reg>;
+		syscon = <&syscon>;
+	};
+
+	syscon: syscon@c0011000 {
+		compatible = "stericsson,u300-syscon";
+		reg = <0xc0011000 0x1000>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/ata/ahci-platform.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/ata/ahci-platform.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/ata/ahci-platform.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/ata/ahci-platform.txt	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,11 @@ Optional properties:
 - calxeda,port-phys: phandle-combophy and lane assignment, which maps each
 			SATA port to a combophy and a lane within that
 			combophy
+- calxeda,sgpio-gpio: phandle-gpio bank, bit offset, and default on or off,
+			which indicates that the driver supports SGPIO
+			indicator lights using the indicated GPIOs
+- calxeda,led-order : a u32 array that map port numbers to offsets within the
+			SGPIO bitstream.
 - dma-coherent      : Present if dma operations are coherent
 
 Example:
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/ata/atmel-at91_cf.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,19 @@
+Atmel AT91RM9200 CompactFlash
+
+Required properties:
+- compatible : "atmel,at91rm9200-cf".
+- reg : should specify localbus address and size used.
+- gpios : specifies the gpio pins to control the CF device. Detect
+  and reset gpio's are mandatory while irq and vcc gpio's are
+  optional and may be set to 0 if not present.
+
+Example:
+compact-flash@50000000 {
+	compatible = "atmel,at91rm9200-cf";
+	reg = <0x50000000 0x30000000>;
+	gpios = <&pioC 13 0	/* irq */
+		 &pioC 15 0 	/* detect */
+		 0		/* vcc */
+		 &pioC  5 0	/* reset */
+		>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/bus/imx-weim.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/bus/imx-weim.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/bus/imx-weim.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/bus/imx-weim.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,49 @@
+Device tree bindings for i.MX Wireless External Interface Module (WEIM)
+
+The term "wireless" does not imply that the WEIM is literally an interface
+without wires. It simply means that this module was originally designed for
+wireless and mobile applications that use low-power technology.
+
+The actual devices are instantiated from the child nodes of a WEIM node.
+
+Required properties:
+
+ - compatible:		Should be set to "fsl,imx6q-weim"
+ - reg:			A resource specifier for the register space
+			(see the example below)
+ - clocks:		the clock, see the example below.
+ - #address-cells:	Must be set to 2 to allow memory address translation
+ - #size-cells:		Must be set to 1 to allow CS address passing
+ - ranges:		Must be set up to reflect the memory layout with four
+			integer values for each chip-select line in use:
+
+			   <cs-number> 0 <physical address of mapping> <size>
+
+Timing property for child nodes. It is mandatory, not optional.
+
+ - fsl,weim-cs-timing:	The timing array, contains 6 timing values for the
+			child node. We can get the CS index from the child
+			node's "reg" property. This property contains the values
+			for the registers EIM_CSnGCR1, EIM_CSnGCR2, EIM_CSnRCR1,
+			EIM_CSnRCR2, EIM_CSnWCR1, EIM_CSnWCR2 in this order.
+
+Example for an imx6q-sabreauto board, the NOR flash connected to the WEIM:
+
+	weim: weim@021b8000 {
+		compatible = "fsl,imx6q-weim";
+		reg = <0x021b8000 0x4000>;
+		clocks = <&clks 196>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0x08000000 0x08000000>;
+
+		nor@0,0 {
+			compatible = "cfi-flash";
+			reg = <0 0 0x02000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			bank-width = <2>;
+			fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000
+					0x0000c000 0x1404a38e 0x00000000>;
+		};
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/bus/ti-gpmc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/bus/ti-gpmc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/bus/ti-gpmc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/bus/ti-gpmc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -95,7 +95,6 @@ GPMC chip-select settings properties for
 - gpmc,burst-wrap	Enables wrap bursting
 - gpmc,burst-read	Enables read page/burst mode
 - gpmc,burst-write	Enables write page/burst mode
-- gpmc,device-nand	Device is NAND
 - gpmc,device-width	Total width of device(s) connected to a GPMC
 			chip-select in bytes. The GPMC supports 8-bit
 			and 16-bit devices and so this property must be
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/altr_socfpga.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/altr_socfpga.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/altr_socfpga.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/altr_socfpga.txt	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,9 @@ Required properties:
 	"altr,socfpga-pll-clock" - for a PLL clock
 	"altr,socfpga-perip-clock" - The peripheral clock divided from the
 		PLL clock.
+	"altr,socfpga-gate-clk" - Clocks that directly feed peripherals and
+		can get gated.
+
 - reg : shall be the control register offset from CLOCK_MANAGER's base for the clock.
 - clocks : shall be the input parent clock phandle for the clock. This is
 	either an oscillator or a pll output.
@@ -16,3 +19,7 @@ Required properties:
 
 Optional properties:
 - fixed-divider : If clocks have a fixed divider value, use this property.
+- clk-gate : For "socfpga-gate-clk", clk-gate contains the gating register
+        and the bit index.
+- div-reg : For "socfpga-gate-clk", div-reg contains the divider register, bit shift,
+        and width.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,64 @@
+* Samsung Audio Subsystem Clock Controller
+
+The Samsung Audio Subsystem clock controller generates and supplies clocks
+to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
+binding described here is applicable to all SoC's in Exynos family.
+
+Required Properties:
+
+- compatible: should be one of the following:
+  - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
+  - "samsung,exynos5250-audss-clock" - controller compatible with all Exynos5 SoCs.
+
+- reg: physical base address and length of the controller's register set.
+
+- #clock-cells: should be 1.
+
+The following is the list of clocks generated by the controller. Each clock is
+assigned an identifier and client nodes use this identifier to specify the
+clock which they consume. Some of the clocks are available only on a particular
+Exynos4 SoC and this is specified where applicable.
+
+Provided clocks:
+
+Clock           ID      SoC (if specific)
+-----------------------------------------------
+
+mout_audss      0
+mout_i2s        1
+dout_srp        2
+dout_aud_bus    3
+dout_i2s        4
+srp_clk         5
+i2s_bus         6
+sclk_i2s        7
+pcm_bus         8
+sclk_pcm        9
+
+Example 1: An example of a clock controller node is listed below.
+
+clock_audss: audss-clock-controller@3810000 {
+	compatible = "samsung,exynos5250-audss-clock";
+	reg = <0x03810000 0x0C>;
+	#clock-cells = <1>;
+};
+
+Example 2: I2S controller node that consumes the clock generated by the clock
+           controller. Refer to the standard clock bindings for information
+           about 'clocks' and 'clock-names' property.
+
+i2s0: i2s@03830000 {
+	compatible = "samsung,i2s-v5";
+	reg = <0x03830000 0x100>;
+	dmas = <&pdma0 10
+		&pdma0 9
+		&pdma0 8>;
+	dma-names = "tx", "rx", "tx-sec";
+	clocks = <&clock_audss EXYNOS_I2S_BUS>,
+		<&clock_audss EXYNOS_I2S_BUS>,
+		<&clock_audss EXYNOS_SCLK_I2S>,
+		<&clock_audss EXYNOS_MOUT_AUDSS>,
+		<&clock_audss EXYNOS_MOUT_I2S>;
+	clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
+	"mout_audss", "mout_i2s";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/exynos4-clock.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/exynos4-clock.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/exynos4-clock.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/exynos4-clock.txt	2013-08-25 20:43:22.000000000 -0400
@@ -102,6 +102,7 @@ Exynos4 SoC and this is specified where
   sclk_spi0_isp       174     Exynos4x12
   sclk_spi1_isp       175     Exynos4x12
   sclk_uart_isp       176     Exynos4x12
+  sclk_fimg2d         177
 
 	      [Peripheral Clock Gates]
 
@@ -129,7 +130,7 @@ Exynos4 SoC and this is specified where
   smmu_mfcl           274
   smmu_mfcr           275
   g3d                 276
-  g2d                 277     Exynos4210
+  g2d                 277
   rotator             278     Exynos4210
   mdma                279     Exynos4210
   smmu_g2d            280     Exynos4210
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/exynos5420-clock.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/exynos5420-clock.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/exynos5420-clock.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,201 @@
+* Samsung Exynos5420 Clock Controller
+
+The Exynos5420 clock controller generates and supplies clock to various
+controllers within the Exynos5420 SoC.
+
+Required Properties:
+
+- comptible: should be one of the following.
+  - "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+The following is the list of clocks generated by the controller. Each clock is
+assigned an identifier and client nodes use this identifier to specify the
+clock which they consume.
+
+
+       [Core Clocks]
+
+  Clock			ID
+  ----------------------------
+
+  fin_pll		1
+
+  [Clock Gate for Special Clocks]
+
+  Clock			ID
+  ----------------------------
+  sclk_uart0		128
+  sclk_uart1		129
+  sclk_uart2		130
+  sclk_uart3		131
+  sclk_mmc0		132
+  sclk_mmc1		133
+  sclk_mmc2		134
+  sclk_spi0		135
+  sclk_spi1		136
+  sclk_spi2		137
+  sclk_i2s1		138
+  sclk_i2s2		139
+  sclk_pcm1		140
+  sclk_pcm2		141
+  sclk_spdif		142
+  sclk_hdmi		143
+  sclk_pixel		144
+  sclk_dp1		145
+  sclk_mipi1		146
+  sclk_fimd1		147
+  sclk_maudio0		148
+  sclk_maupcm0		149
+  sclk_usbd300		150
+  sclk_usbd301		151
+  sclk_usbphy300	152
+  sclk_usbphy301	153
+  sclk_unipro		154
+  sclk_pwm		155
+  sclk_gscl_wa		156
+  sclk_gscl_wb		157
+
+   [Peripheral Clock Gates]
+
+  Clock			ID
+  ----------------------------
+
+  aclk66_peric		256
+  uart0			257
+  uart1			258
+  uart2			259
+  uart3			260
+  i2c0			261
+  i2c1			262
+  i2c2			263
+  i2c3			264
+  i2c4			265
+  i2c5			266
+  i2c6			267
+  i2c7			268
+  i2c_hdmi		269
+  tsadc			270
+  spi0			271
+  spi1			272
+  spi2			273
+  keyif			274
+  i2s1			275
+  i2s2			276
+  pcm1			277
+  pcm2			278
+  pwm			279
+  spdif			280
+  i2c8			281
+  i2c9			282
+  i2c10			283
+  aclk66_psgen		300
+  chipid		301
+  sysreg		302
+  tzpc0			303
+  tzpc1			304
+  tzpc2			305
+  tzpc3			306
+  tzpc4			307
+  tzpc5			308
+  tzpc6			309
+  tzpc7			310
+  tzpc8			311
+  tzpc9			312
+  hdmi_cec		313
+  seckey		314
+  mct			315
+  wdt			316
+  rtc			317
+  tmu			318
+  tmu_gpu		319
+  pclk66_gpio		330
+  aclk200_fsys2		350
+  mmc0			351
+  mmc1			352
+  mmc2			353
+  sromc			354
+  ufs			355
+  aclk200_fsys		360
+  tsi			361
+  pdma0			362
+  pdma1			363
+  rtic			364
+  usbh20		365
+  usbd300		366
+  usbd301		377
+  aclk400_mscl		380
+  mscl0			381
+  mscl1			382
+  mscl2			383
+  smmu_mscl0		384
+  smmu_mscl1		385
+  smmu_mscl2		386
+  aclk333		400
+  mfc			401
+  smmu_mfcl		402
+  smmu_mfcr		403
+  aclk200_disp1		410
+  dsim1			411
+  dp1			412
+  hdmi			413
+  aclk300_disp1		420
+  fimd1			421
+  smmu_fimd1		422
+  aclk166		430
+  mixer			431
+  aclk266		440
+  rotator		441
+  mdma1			442
+  smmu_rotator		443
+  smmu_mdma1		444
+  aclk300_jpeg		450
+  jpeg			451
+  jpeg2			452
+  smmu_jpeg		453
+  aclk300_gscl		460
+  smmu_gscl0		461
+  smmu_gscl1		462
+  gscl_wa		463
+  gscl_wb		464
+  gscl0			465
+  gscl1			466
+  clk_3aa		467
+  aclk266_g2d		470
+  sss			471
+  slim_sss		472
+  mdma0			473
+  aclk333_g2d		480
+  g2d			481
+  aclk333_432_gscl	490
+  smmu_3aa		491
+  smmu_fimcl0		492
+  smmu_fimcl1		493
+  smmu_fimcl3		494
+  fimc_lite3		495
+  aclk_g3d		500
+  g3d			501
+
+Example 1: An example of a clock controller node is listed below.
+
+	clock: clock-controller@0x10010000 {
+		compatible = "samsung,exynos5420-clock";
+		reg = <0x10010000 0x30000>;
+		#clock-cells = <1>;
+	};
+
+Example 2: UART controller node that consumes the clock generated by the clock
+	   controller. Refer to the standard clock bindings for information
+	   about 'clocks' and 'clock-names' property.
+
+	serial@13820000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x13820000 0x100>;
+		interrupts = <0 54 0>;
+		clocks = <&clock 259>, <&clock 130>;
+		clock-names = "uart", "clk_uart_baud0";
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/imx27-clock.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/imx27-clock.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/imx27-clock.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/imx27-clock.txt	2013-08-25 20:43:22.000000000 -0400
@@ -98,6 +98,7 @@ clocks and IDs.
 	fpm                  83
 	mpll_osc_sel         84
 	mpll_sel             85
+	spll_gate	     86
 
 Examples:
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/imx5-clock.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/imx5-clock.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/imx5-clock.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/imx5-clock.txt	2013-08-25 20:43:22.000000000 -0400
@@ -184,6 +184,19 @@ clocks and IDs.
 	cko2			170
 	srtc_gate		171
 	pata_gate		172
+	sata_gate		173
+	spdif_xtal_sel		174
+	spdif0_sel		175
+	spdif1_sel		176
+	spdif0_pred		177
+	spdif0_podf		178
+	spdif1_pred		179
+	spdif1_podf		180
+	spdif0_com_sel		181
+	spdif1_com_sel		182
+	spdif0_gate		183
+	spdif1_gate		184
+	spdif_ipg_gate		185
 
 Examples (for mx53):
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/imx6q-clock.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/imx6q-clock.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/imx6q-clock.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/imx6q-clock.txt	2013-08-25 20:43:22.000000000 -0400
@@ -208,6 +208,7 @@ clocks and IDs.
 	pll4_post_div		193
 	pll5_post_div		194
 	pll5_video_div		195
+	eim_slow      		196
 
 Examples:
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/imx6sl-clock.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/imx6sl-clock.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/imx6sl-clock.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/imx6sl-clock.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+* Clock bindings for Freescale i.MX6 SoloLite
+
+Required properties:
+- compatible: Should be "fsl,imx6sl-ccm"
+- reg: Address and length of the register set
+- #clock-cells: Should be <1>
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell.  See include/dt-bindings/clock/imx6sl-clock.h
+for the full list of i.MX6 SoloLite clock IDs.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/nspire-clock.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/nspire-clock.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/nspire-clock.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/nspire-clock.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,24 @@
+TI-NSPIRE Clocks
+
+Required properties:
+- compatible: Valid compatible properties include:
+	"lsi,nspire-cx-ahb-divider" for the AHB divider in the CX model
+	"lsi,nspire-classic-ahb-divider" for the AHB divider in the older model
+	"lsi,nspire-cx-clock" for the base clock in the CX model
+	"lsi,nspire-classic-clock" for the base clock in the older model
+
+- reg: Physical base address of the controller and length of memory mapped
+	region.
+
+Optional:
+- clocks: For the "nspire-*-ahb-divider" compatible clocks, this is the parent
+	clock where it divides the rate from.
+
+Example:
+
+ahb_clk {
+	#clock-cells = <0>;
+	compatible = "lsi,nspire-cx-clock";
+	reg = <0x900B0000 0x4>;
+	clocks = <&base_clk>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt	2013-08-25 20:43:22.000000000 -0400
@@ -12,253 +12,9 @@ Required properties :
 - clocks : Should contain phandle and clock specifiers for two clocks:
   the 32 KHz "32k_in", and the board-specific oscillator "osc".
 - #clock-cells : Should be 1.
-  In clock consumers, this cell represents the clock ID exposed by the CAR.
-
-  The first 160 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
-  registers. These IDs often match those in the CAR's RST_DEVICES registers,
-  but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
-  this case, those clocks are assigned IDs above 160 in order to highlight
-  this issue. Implementations that interpret these clock IDs as bit values
-  within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
-  explicitly handle these special cases.
-
-  The balance of the clocks controlled by the CAR are assigned IDs of 160 and
-  above.
-
-  0	unassigned
-  1	unassigned
-  2	unassigned
-  3	unassigned
-  4	rtc
-  5	timer
-  6	uarta
-  7	unassigned	(register bit affects uartb and vfir)
-  8	unassigned
-  9	sdmmc2
-  10	unassigned	(register bit affects spdif_in and spdif_out)
-  11	i2s1
-  12	i2c1
-  13	ndflash
-  14	sdmmc1
-  15	sdmmc4
-  16	unassigned
-  17	pwm
-  18	i2s2
-  19	epp
-  20	unassigned	(register bit affects vi and vi_sensor)
-  21	2d
-  22	usbd
-  23	isp
-  24	3d
-  25	unassigned
-  26	disp2
-  27	disp1
-  28	host1x
-  29	vcp
-  30	i2s0
-  31	unassigned
-
-  32	unassigned
-  33	unassigned
-  34	apbdma
-  35	unassigned
-  36	kbc
-  37	unassigned
-  38	unassigned
-  39	unassigned	(register bit affects fuse and fuse_burn)
-  40	kfuse
-  41	sbc1
-  42	nor
-  43	unassigned
-  44	sbc2
-  45	unassigned
-  46	sbc3
-  47	i2c5
-  48	dsia
-  49	unassigned
-  50	mipi
-  51	hdmi
-  52	csi
-  53	unassigned
-  54	i2c2
-  55	uartc
-  56	mipi-cal
-  57	emc
-  58	usb2
-  59	usb3
-  60	msenc
-  61	vde
-  62	bsea
-  63	bsev
-
-  64	unassigned
-  65	uartd
-  66	unassigned
-  67	i2c3
-  68	sbc4
-  69	sdmmc3
-  70	unassigned
-  71	owr
-  72	afi
-  73	csite
-  74	unassigned
-  75	unassigned
-  76	la
-  77	trace
-  78	soc_therm
-  79	dtv
-  80	ndspeed
-  81	i2cslow
-  82	dsib
-  83	tsec
-  84	unassigned
-  85	unassigned
-  86	unassigned
-  87	unassigned
-  88	unassigned
-  89	xusb_host
-  90	unassigned
-  91	msenc
-  92	csus
-  93	unassigned
-  94	unassigned
-  95	unassigned	(bit affects xusb_dev and xusb_dev_src)
-
-  96	unassigned
-  97	unassigned
-  98	unassigned
-  99	mselect
-  100	tsensor
-  101	i2s3
-  102	i2s4
-  103	i2c4
-  104	sbc5
-  105	sbc6
-  106	d_audio
-  107	apbif
-  108	dam0
-  109	dam1
-  110	dam2
-  111	hda2codec_2x
-  112	unassigned
-  113	audio0_2x
-  114	audio1_2x
-  115	audio2_2x
-  116	audio3_2x
-  117	audio4_2x
-  118	spdif_2x
-  119	actmon
-  120	extern1
-  121	extern2
-  122	extern3
-  123	unassigned
-  124	unassigned
-  125	hda
-  126	unassigned
-  127	se
-
-  128	hda2hdmi
-  129	unassigned
-  130	unassigned
-  131	unassigned
-  132	unassigned
-  133	unassigned
-  134	unassigned
-  135	unassigned
-  136	unassigned
-  137	unassigned
-  138	unassigned
-  139	unassigned
-  140	unassigned
-  141	unassigned
-  142	unassigned
-  143	unassigned	(bit affects xusb_falcon_src, xusb_fs_src,
-			 xusb_host_src and xusb_ss_src)
-  144	cilab
-  145	cilcd
-  146	cile
-  147	dsialp
-  148	dsiblp
-  149	unassigned
-  150	dds
-  151	unassigned
-  152	dp2
-  153	amx
-  154	adx
-  155	unassigned	(bit affects dfll_ref and dfll_soc)
-  156	xusb_ss
-
-  192	uartb
-  193	vfir
-  194	spdif_in
-  195	spdif_out
-  196	vi
-  197	vi_sensor
-  198	fuse
-  199	fuse_burn
-  200	clk_32k
-  201	clk_m
-  202	clk_m_div2
-  203	clk_m_div4
-  204	pll_ref
-  205	pll_c
-  206	pll_c_out1
-  207	pll_c2
-  208	pll_c3
-  209	pll_m
-  210	pll_m_out1
-  211	pll_p
-  212	pll_p_out1
-  213	pll_p_out2
-  214	pll_p_out3
-  215	pll_p_out4
-  216	pll_a
-  217	pll_a_out0
-  218	pll_d
-  219	pll_d_out0
-  220	pll_d2
-  221	pll_d2_out0
-  222	pll_u
-  223	pll_u_480M
-  224	pll_u_60M
-  225	pll_u_48M
-  226	pll_u_12M
-  227	pll_x
-  228	pll_x_out0
-  229	pll_re_vco
-  230	pll_re_out
-  231	pll_e_out0
-  232	spdif_in_sync
-  233	i2s0_sync
-  234	i2s1_sync
-  235	i2s2_sync
-  236	i2s3_sync
-  237	i2s4_sync
-  238	vimclk_sync
-  239	audio0
-  240	audio1
-  241	audio2
-  242	audio3
-  243	audio4
-  244	spdif
-  245	clk_out_1
-  246	clk_out_2
-  247	clk_out_3
-  248	blink
-  252	xusb_host_src
-  253	xusb_falcon_src
-  254	xusb_fs_src
-  255	xusb_ss_src
-  256	xusb_dev_src
-  257	xusb_dev
-  258	xusb_hs_src
-  259	sclk
-  260	hclk
-  261	pclk
-  262	cclk_g
-  263	cclk_lp
-  264	dfll_ref
-  265	dfll_soc
+  In clock consumers, this cell represents the clock ID exposed by the
+  CAR. The assignments may be found in header file
+  <dt-bindings/clock/tegra114-car.h>.
 
 Example SoC include file:
 
@@ -270,7 +26,7 @@ Example SoC include file:
 	};
 
 	usb@c5004000 {
-		clocks = <&tegra_car 58>; /* usb2 */
+		clocks = <&tegra_car TEGRA114_CLK_USB2>;
 	};
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt	2013-08-25 20:43:22.000000000 -0400
@@ -12,155 +12,9 @@ Required properties :
 - clocks : Should contain phandle and clock specifiers for two clocks:
   the 32 KHz "32k_in", and the board-specific oscillator "osc".
 - #clock-cells : Should be 1.
-  In clock consumers, this cell represents the clock ID exposed by the CAR.
-
-  The first 96 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
-  registers. These IDs often match those in the CAR's RST_DEVICES registers,
-  but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
-  this case, those clocks are assigned IDs above 95 in order to highlight
-  this issue. Implementations that interpret these clock IDs as bit values
-  within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
-  explicitly handle these special cases.
-
-  The balance of the clocks controlled by the CAR are assigned IDs of 96 and
-  above.
-
-  0	cpu
-  1	unassigned
-  2	unassigned
-  3	ac97
-  4	rtc
-  5	tmr
-  6	uart1
-  7	unassigned	(register bit affects uart2 and vfir)
-  8	gpio
-  9	sdmmc2
-  10	unassigned	(register bit affects spdif_in and spdif_out)
-  11	i2s1
-  12	i2c1
-  13	ndflash
-  14	sdmmc1
-  15	sdmmc4
-  16	twc
-  17	pwm
-  18	i2s2
-  19	epp
-  20	unassigned	(register bit affects vi and vi_sensor)
-  21	2d
-  22	usbd
-  23	isp
-  24	3d
-  25	ide
-  26	disp2
-  27	disp1
-  28	host1x
-  29	vcp
-  30	unassigned
-  31	cache2
-
-  32	mem
-  33	ahbdma
-  34	apbdma
-  35	unassigned
-  36	kbc
-  37	stat_mon
-  38	pmc
-  39	fuse
-  40	kfuse
-  41	sbc1
-  42	snor
-  43	spi1
-  44	sbc2
-  45	xio
-  46	sbc3
-  47	dvc
-  48	dsi
-  49	unassigned	(register bit affects tvo and cve)
-  50	mipi
-  51	hdmi
-  52	csi
-  53	tvdac
-  54	i2c2
-  55	uart3
-  56	unassigned
-  57	emc
-  58	usb2
-  59	usb3
-  60	mpe
-  61	vde
-  62	bsea
-  63	bsev
-
-  64	speedo
-  65	uart4
-  66	uart5
-  67	i2c3
-  68	sbc4
-  69	sdmmc3
-  70	pcie
-  71	owr
-  72	afi
-  73	csite
-  74	unassigned
-  75	avpucq
-  76	la
-  77	unassigned
-  78	unassigned
-  79	unassigned
-  80	unassigned
-  81	unassigned
-  82	unassigned
-  83	unassigned
-  84	irama
-  85	iramb
-  86	iramc
-  87	iramd
-  88	cram2
-  89	audio_2x	a/k/a audio_2x_sync_clk
-  90	clk_d
-  91	unassigned
-  92	sus
-  93	cdev2
-  94	cdev1
-  95	unassigned
-
-  96	uart2
-  97	vfir
-  98	spdif_in
-  99	spdif_out
-  100	vi
-  101	vi_sensor
-  102	tvo
-  103	cve
-  104	osc
-  105	clk_32k		a/k/a clk_s
-  106	clk_m
-  107	sclk
-  108	cclk
-  109	hclk
-  110	pclk
-  111	blink
-  112	pll_a
-  113	pll_a_out0
-  114	pll_c
-  115	pll_c_out1
-  116	pll_d
-  117	pll_d_out0
-  118	pll_e
-  119	pll_m
-  120	pll_m_out1
-  121	pll_p
-  122	pll_p_out1
-  123	pll_p_out2
-  124	pll_p_out3
-  125	pll_p_out4
-  126	pll_s
-  127	pll_u
-  128	pll_x
-  129	cop		a/k/a avp
-  130	audio		a/k/a audio_sync_clk
-  131	pll_ref
-  132	twd
+  In clock consumers, this cell represents the clock ID exposed by the
+  CAR. The assignments may be found in header file
+  <dt-bindings/clock/tegra20-car.h>.
 
 Example SoC include file:
 
@@ -172,7 +26,7 @@ Example SoC include file:
 	};
 
 	usb@c5004000 {
-		clocks = <&tegra_car 58>; /* usb2 */
+		clocks = <&tegra_car TEGRA20_CLK_USB2>;
 	};
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt	2013-08-25 20:43:22.000000000 -0400
@@ -12,212 +12,9 @@ Required properties :
 - clocks : Should contain phandle and clock specifiers for two clocks:
   the 32 KHz "32k_in", and the board-specific oscillator "osc".
 - #clock-cells : Should be 1.
-  In clock consumers, this cell represents the clock ID exposed by the CAR.
-
-  The first 130 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
-  registers. These IDs often match those in the CAR's RST_DEVICES registers,
-  but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
-  this case, those clocks are assigned IDs above 160 in order to highlight
-  this issue. Implementations that interpret these clock IDs as bit values
-  within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
-  explicitly handle these special cases.
-
-  The balance of the clocks controlled by the CAR are assigned IDs of 160 and
-  above.
-
-  0	cpu
-  1	unassigned
-  2	unassigned
-  3	unassigned
-  4	rtc
-  5	timer
-  6	uarta
-  7	unassigned	(register bit affects uartb and vfir)
-  8	gpio
-  9	sdmmc2
-  10	unassigned	(register bit affects spdif_in and spdif_out)
-  11	i2s1
-  12	i2c1
-  13	ndflash
-  14	sdmmc1
-  15	sdmmc4
-  16	unassigned
-  17	pwm
-  18	i2s2
-  19	epp
-  20	unassigned	(register bit affects vi and vi_sensor)
-  21	2d
-  22	usbd
-  23	isp
-  24	3d
-  25	unassigned
-  26	disp2
-  27	disp1
-  28	host1x
-  29	vcp
-  30	i2s0
-  31	cop_cache
-
-  32	mc
-  33	ahbdma
-  34	apbdma
-  35	unassigned
-  36	kbc
-  37	statmon
-  38	pmc
-  39	unassigned	(register bit affects fuse and fuse_burn)
-  40	kfuse
-  41	sbc1
-  42	nor
-  43	unassigned
-  44	sbc2
-  45	unassigned
-  46	sbc3
-  47	i2c5
-  48	dsia
-  49	unassigned	(register bit affects cve and tvo)
-  50	mipi
-  51	hdmi
-  52	csi
-  53	tvdac
-  54	i2c2
-  55	uartc
-  56	unassigned
-  57	emc
-  58	usb2
-  59	usb3
-  60	mpe
-  61	vde
-  62	bsea
-  63	bsev
-
-  64	speedo
-  65	uartd
-  66	uarte
-  67	i2c3
-  68	sbc4
-  69	sdmmc3
-  70	pcie
-  71	owr
-  72	afi
-  73	csite
-  74	pciex
-  75	avpucq
-  76	la
-  77	unassigned
-  78	unassigned
-  79	dtv
-  80	ndspeed
-  81	i2cslow
-  82	dsib
-  83	unassigned
-  84	irama
-  85	iramb
-  86	iramc
-  87	iramd
-  88	cram2
-  89	unassigned
-  90	audio_2x	a/k/a audio_2x_sync_clk
-  91	unassigned
-  92	csus
-  93	cdev2
-  94	cdev1
-  95	unassigned
-
-  96	cpu_g
-  97	cpu_lp
-  98	3d2
-  99	mselect
-  100	tsensor
-  101	i2s3
-  102	i2s4
-  103	i2c4
-  104	sbc5
-  105	sbc6
-  106	d_audio
-  107	apbif
-  108	dam0
-  109	dam1
-  110	dam2
-  111	hda2codec_2x
-  112	atomics
-  113	audio0_2x
-  114	audio1_2x
-  115	audio2_2x
-  116	audio3_2x
-  117	audio4_2x
-  118	audio5_2x
-  119	actmon
-  120	extern1
-  121	extern2
-  122	extern3
-  123	sata_oob
-  124	sata
-  125	hda
-  127	se
-  128	hda2hdmi
-  129	sata_cold
-
-  160	uartb
-  161	vfir
-  162	spdif_in
-  163	spdif_out
-  164	vi
-  165	vi_sensor
-  166	fuse
-  167	fuse_burn
-  168	cve
-  169	tvo
-
-  170	clk_32k
-  171	clk_m
-  172	clk_m_div2
-  173	clk_m_div4
-  174	pll_ref
-  175	pll_c
-  176	pll_c_out1
-  177	pll_m
-  178	pll_m_out1
-  179	pll_p
-  180	pll_p_out1
-  181	pll_p_out2
-  182	pll_p_out3
-  183	pll_p_out4
-  184	pll_a
-  185	pll_a_out0
-  186	pll_d
-  187	pll_d_out0
-  188	pll_d2
-  189	pll_d2_out0
-  190	pll_u
-  191	pll_x
-  192	pll_x_out0
-  193	pll_e
-  194	spdif_in_sync
-  195	i2s0_sync
-  196	i2s1_sync
-  197	i2s2_sync
-  198	i2s3_sync
-  199	i2s4_sync
-  200	vimclk
-  201	audio0
-  202	audio1
-  203	audio2
-  204	audio3
-  205	audio4
-  206	audio5
-  207	clk_out_1 (extern1)
-  208	clk_out_2 (extern2)
-  209	clk_out_3 (extern3)
-  210	sclk
-  211	blink
-  212	cclk_g
-  213	cclk_lp
-  214	twd
-  215	cml0
-  216	cml1
-  217	hclk
-  218	pclk
+  In clock consumers, this cell represents the clock ID exposed by the
+  CAR. The assignments may be found in header file
+  <dt-bindings/clock/tegra30-car.h>.
 
 Example SoC include file:
 
@@ -229,7 +26,7 @@ Example SoC include file:
 	};
 
 	usb@c5004000 {
-		clocks = <&tegra_car 58>; /* usb2 */
+		clocks = <&tegra_car TEGRA30_CLK_USB2>;
 	};
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/rockchip.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/rockchip.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/rockchip.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/rockchip.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,74 @@
+Device Tree Clock bindings for arch-rockchip
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+== Gate clocks ==
+
+The gate registers form a continuos block which makes the dt node
+structure a matter of taste, as either all gates can be put into
+one gate clock spanning all registers or they can be divided into
+the 10 individual gates containing 16 clocks each.
+The code supports both approaches.
+
+Required properties:
+- compatible : "rockchip,rk2928-gate-clk"
+- reg : shall be the control register address(es) for the clock.
+- #clock-cells : from common clock binding; shall be set to 1
+- clock-output-names : the corresponding gate names that the clock controls
+- clocks : should contain the parent clock for each individual gate,
+  therefore the number of clocks elements should match the number of
+  clock-output-names
+
+Example using multiple gate clocks:
+
+		clk_gates0: gate-clk@200000d0 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d0 0x4>;
+			clocks = <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>,
+				 <&dummy>, <&dummy>;
+
+			clock-output-names =
+				"gate_core_periph", "gate_cpu_gpll",
+				"gate_ddrphy", "gate_aclk_cpu",
+				"gate_hclk_cpu", "gate_pclk_cpu",
+				"gate_atclk_cpu", "gate_i2s0",
+				"gate_i2s0_frac", "gate_i2s1",
+				"gate_i2s1_frac", "gate_i2s2",
+				"gate_i2s2_frac", "gate_spdif",
+				"gate_spdif_frac", "gate_testclk";
+
+			#clock-cells = <1>;
+		};
+
+		clk_gates1: gate-clk@200000d4 {
+			compatible = "rockchip,rk2928-gate-clk";
+			reg = <0x200000d4 0x4>;
+			clocks = <&xin24m>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&dummy>, <&xin24m>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>,
+				 <&xin24m>, <&dummy>;
+
+			clock-output-names =
+				"gate_timer0", "gate_timer1",
+				"gate_timer2", "gate_jtag",
+				"gate_aclk_lcdc1_src", "gate_otgphy0",
+				"gate_otgphy1", "gate_ddr_gpll",
+				"gate_uart0", "gate_frac_uart0",
+				"gate_uart1", "gate_frac_uart1",
+				"gate_uart2", "gate_frac_uart2",
+				"gate_uart3", "gate_frac_uart3";
+
+			#clock-cells = <1>;
+		};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/silabs,si5351.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/silabs,si5351.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/silabs,si5351.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/silabs,si5351.txt	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,7 @@ Reference
 [1] Si5351A/B/C Data Sheet
     http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf
 
-The Si5351a/b/c are programmable i2c clock generators with upto 8 output
+The Si5351a/b/c are programmable i2c clock generators with up to 8 output
 clocks. Si5351a also has a reduced pin-count package (MSOP10) where only
 3 output clocks are accessible. The internal structure of the clock
 generators can be found in [1].
@@ -44,6 +44,11 @@ Optional child node properties:
 - silabs,multisynth-source: source pll A(0) or B(1) of corresponding multisynth
   divider.
 - silabs,pll-master: boolean, multisynth can change pll frequency.
+- silabs,disable-state : clock output disable state, shall be
+  0 = clock output is driven LOW when disabled
+  1 = clock output is driven HIGH when disabled
+  2 = clock output is FLOATING (HIGH-Z) when disabled
+  3 = clock output is NEVER disabled
 
 ==Example==
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/ste-u300-syscon-clock.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/ste-u300-syscon-clock.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/ste-u300-syscon-clock.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/ste-u300-syscon-clock.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,80 @@
+Clock bindings for ST-Ericsson U300 System Controller Clocks
+
+Bindings for the gated system controller clocks:
+
+Required properties:
+- compatible: must be "stericsson,u300-syscon-clk"
+- #clock-cells: must be <0>
+- clock-type: specifies the type of clock:
+  0 = slow clock
+  1 = fast clock
+  2 = rest/remaining clock
+- clock-id: specifies the clock in the type range
+
+Optional properties:
+- clocks: parent clock(s)
+
+The available clocks per type are as follows:
+
+Type:  ID:   Clock:
+-------------------
+0      0     Slow peripheral bridge clock
+0      1     UART0 clock
+0      4     GPIO clock
+0      6     RTC clock
+0      7     Application timer clock
+0      8     Access timer clock
+
+1      0     Fast peripheral bridge clock
+1      1     I2C bus 0 clock
+1      2     I2C bus 1 clock
+1      5     MMC interface peripheral (silicon) clock
+1      6     SPI clock
+
+2      3     CPU clock
+2      4     DMA controller clock
+2      5     External Memory Interface (EMIF) clock
+2      6     NAND flask interface clock
+2      8     XGAM graphics engine clock
+2      9     Shared External Memory Interface (SEMI) clock
+2      10    AHB Subsystem Bridge clock
+2      12    Interrupt controller clock
+
+Example:
+
+gpio_clk: gpio_clk@13M {
+	#clock-cells = <0>;
+	compatible = "stericsson,u300-syscon-clk";
+	clock-type = <0>; /* Slow */
+	clock-id = <4>;
+	clocks = <&slow_clk>;
+};
+
+gpio: gpio@c0016000 {
+	compatible = "stericsson,gpio-coh901";
+	(...)
+	clocks = <&gpio_clk>;
+};
+
+
+Bindings for the MMC/SD card clock:
+
+Required properties:
+- compatible: must be "stericsson,u300-syscon-mclk"
+- #clock-cells: must be <0>
+
+Optional properties:
+- clocks: parent clock(s)
+
+mmc_mclk: mmc_mclk {
+	#clock-cells = <0>;
+	compatible = "stericsson,u300-syscon-mclk";
+	clocks = <&mmc_pclk>;
+};
+
+mmcsd: mmcsd@c0001000 {
+	compatible = "arm,pl18x", "arm,primecell";
+	clocks = <&mmc_pclk>, <&mmc_mclk>;
+	clock-names = "apb_pclk", "mclk";
+	(...)
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/st,nomadik.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/st,nomadik.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/st,nomadik.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/st,nomadik.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,104 @@
+ST Microelectronics Nomadik SRC System Reset and Control
+
+This binding uses the common clock binding:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+The Nomadik SRC controller is responsible of controlling chrystals,
+PLLs and clock gates.
+
+Required properties for the SRC node:
+- compatible: must be "stericsson,nomadik-src"
+- reg: must contain the SRC register base and size
+
+Optional properties for the SRC node:
+- disable-sxtalo: if present this will disable the SXTALO
+  i.e. the driver output for the slow 32kHz chrystal, if the
+  board has its own circuitry for providing this oscillator
+- disable-mxtal: if present this will disable the MXTALO,
+  i.e. the driver output for the main (~19.2 MHz) chrystal,
+  if the board has its own circuitry for providing this
+  osciallator
+
+
+PLL nodes: these nodes represent the two PLLs on the system,
+which should both have the main chrystal, represented as a
+fixed frequency clock, as parent.
+
+Required properties for the two PLL nodes:
+- compatible: must be "st,nomadik-pll-clock"
+- clock-cells: must be 0
+- clock-id: must be 1 or 2 for PLL1 and PLL2 respectively
+- clocks: this clock will have main chrystal as parent
+
+
+HCLK nodes: these represent the clock gates on individual
+lines from the HCLK clock tree and the gate for individual
+lines from the PCLK clock tree.
+
+Requires properties for the HCLK nodes:
+- compatible: must be "st,nomadik-hclk-clock"
+- clock-cells: must be 0
+- clock-id: must be the clock ID from 0 to 63 according to
+  this table:
+
+	0:  HCLKDMA0
+	1:  HCLKSMC
+	2:  HCLKSDRAM
+	3:  HCLKDMA1
+	4:  HCLKCLCD
+	5:  PCLKIRDA
+	6:  PCLKSSP
+	7:  PCLKUART0
+	8:  PCLKSDI
+	9:  PCLKI2C0
+	10: PCLKI2C1
+	11: PCLKUART1
+	12: PCLMSP0
+	13: HCLKUSB
+	14: HCLKDIF
+	15: HCLKSAA
+	16: HCLKSVA
+	17: PCLKHSI
+	18: PCLKXTI
+	19: PCLKUART2
+	20: PCLKMSP1
+	21: PCLKMSP2
+	22: PCLKOWM
+	23: HCLKHPI
+	24: PCLKSKE
+	25: PCLKHSEM
+	26: HCLK3D
+	27: HCLKHASH
+	28: HCLKCRYP
+	29: PCLKMSHC
+	30: HCLKUSBM
+	31: HCLKRNG
+	(32, 33, 34, 35 RESERVED)
+	36: CLDCLK
+	37: IRDACLK
+	38: SSPICLK
+	39: UART0CLK
+	40: SDICLK
+	41: I2C0CLK
+	42: I2C1CLK
+	43: UART1CLK
+	44: MSPCLK0
+	45: USBCLK
+	46: DIFCLK
+	47: IPI2CCLK
+	48: IPBMCCLK
+	49: HSICLKRX
+	50: HSICLKTX
+	51: UART2CLK
+	52: MSPCLK1
+	53: MSPCLK2
+	54: OWMCLK
+	(55 RESERVED)
+	56: SKECLK
+	(57 RESERVED)
+	58: 3DCLK
+	59: PCLKMSP3
+	60: MSPCLK3
+	61: MSHCCLK
+	62: USBMCLK
+	63: RNGCCLK
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/sunxi/sun4i-a10-gates.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/sunxi/sun4i-a10-gates.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/sunxi/sun4i-a10-gates.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/sunxi/sun4i-a10-gates.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,93 @@
+Gate clock outputs
+------------------
+
+  * AXI gates ("allwinner,sun4i-axi-gates-clk")
+
+    DRAM					0
+
+  * AHB gates ("allwinner,sun4i-ahb-gates-clk")
+
+    USB0					0
+    EHCI0					1
+    OHCI0					2*
+    EHCI1					3
+    OHCI1					4*
+    SS						5
+    DMA						6
+    BIST					7
+    MMC0					8
+    MMC1					9
+    MMC2					10
+    MMC3					11
+    MS						12**
+    NAND					13
+    SDRAM					14
+
+    ACE						16
+    EMAC					17
+    TS						18
+
+    SPI0					20
+    SPI1					21
+    SPI2					22
+    SPI3					23
+    PATA					24
+    SATA					25**
+    GPS						26*
+
+    VE						32
+    TVD						33
+    TVE0					34
+    TVE1					35
+    LCD0					36
+    LCD1					37
+
+    CSI0					40
+    CSI1					41
+
+    HDMI					43
+    DE_BE0					44
+    DE_BE1					45
+    DE_FE1					46
+    DE_FE1					47
+
+    MP						50
+
+    MALI400					52
+
+  * APB0 gates ("allwinner,sun4i-apb0-gates-clk")
+
+    CODEC					0
+    SPDIF					1*
+    AC97					2
+    IIS						3
+
+    PIO						5
+    IR0						6
+    IR1						7
+
+    KEYPAD					10
+
+  * APB1 gates ("allwinner,sun4i-apb1-gates-clk")
+
+    I2C0					0
+    I2C1					1
+    I2C2					2
+
+    CAN						4
+    SCR						5
+    PS20					6
+    PS21					7
+
+    UART0					16
+    UART1					17
+    UART2					18
+    UART3					19
+    UART4					20
+    UART5					21
+    UART6					22
+    UART7					23
+
+Notation:
+ [*]:  The datasheet didn't mention these, but they are present on AW code
+ [**]: The datasheet had this marked as "NC" but they are used on AW code
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/sunxi/sun5i-a13-gates.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/sunxi/sun5i-a13-gates.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/sunxi/sun5i-a13-gates.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/sunxi/sun5i-a13-gates.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,58 @@
+Gate clock outputs
+------------------
+
+  * AXI gates ("allwinner,sun4i-axi-gates-clk")
+
+    DRAM					0
+
+  * AHB gates ("allwinner,sun5i-a13-ahb-gates-clk")
+
+    USBOTG					0
+    EHCI					1
+    OHCI					2
+
+    SS						5
+    DMA						6
+    BIST					7
+    MMC0					8
+    MMC1					9
+    MMC2					10
+
+    NAND					13
+    SDRAM					14
+
+    SPI0					20
+    SPI1					21
+    SPI2					22
+
+    STIMER					28
+
+    VE						32
+
+    LCD						36
+
+    CSI						40
+
+    DE_BE					44
+
+    DE_FE					46
+
+    IEP						51
+    MALI400					52
+
+  * APB0 gates ("allwinner,sun5i-a13-apb0-gates-clk")
+
+    CODEC					0
+
+    PIO						5
+    IR						6
+
+  * APB1 gates ("allwinner,sun5i-a13-apb1-gates-clk")
+
+    I2C0					0
+    I2C1					1
+    I2C2					2
+
+    UART1					17
+
+    UART3					19
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/sunxi.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/sunxi.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/sunxi.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/sunxi.txt	2013-08-25 20:43:22.000000000 -0400
@@ -12,22 +12,30 @@ Required properties:
 	"allwinner,sun4i-axi-clk" - for the AXI clock
 	"allwinner,sun4i-axi-gates-clk" - for the AXI gates
 	"allwinner,sun4i-ahb-clk" - for the AHB clock
-	"allwinner,sun4i-ahb-gates-clk" - for the AHB gates
+	"allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10
+	"allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13
 	"allwinner,sun4i-apb0-clk" - for the APB0 clock
-	"allwinner,sun4i-apb0-gates-clk" - for the APB0 gates
+	"allwinner,sun4i-apb0-gates-clk" - for the APB0 gates on A10
+	"allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13
 	"allwinner,sun4i-apb1-clk" - for the APB1 clock
 	"allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing
-	"allwinner,sun4i-apb1-gates-clk" - for the APB1 gates
+	"allwinner,sun4i-apb1-gates-clk" - for the APB1 gates on A10
+	"allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13
 
 Required properties for all clocks:
 - reg : shall be the control register address for the clock.
 - clocks : shall be the input parent clock(s) phandle for the clock
 - #clock-cells : from common clock binding; shall be set to 0 except for
-	"allwinner,sun4i-*-gates-clk" where it shall be set to 1
+	"allwinner,*-gates-clk" where it shall be set to 1
 
-Additionally, "allwinner,sun4i-*-gates-clk" clocks require:
+Additionally, "allwinner,*-gates-clk" clocks require:
 - clock-output-names : the corresponding gate names that the clock controls
 
+Clock consumers should specify the desired clocks they use with a
+"clocks" phandle cell. Consumers that are using a gated clock should
+provide an additional ID in their clock property. The values of this
+ID are documented in sunxi/<soc>-gates.txt.
+
 For example:
 
 osc24M: osc24M@01c20050 {
@@ -50,102 +58,3 @@ cpu: cpu@01c20054 {
 	reg = <0x01c20054 0x4>;
 	clocks = <&osc32k>, <&osc24M>, <&pll1>;
 };
-
-
-
-Gate clock outputs
-
-The "allwinner,sun4i-*-gates-clk" clocks provide several gatable outputs;
-their corresponding offsets as present on sun4i are listed below. Note that
-some of these gates are not present on sun5i.
-
-  * AXI gates ("allwinner,sun4i-axi-gates-clk")
-
-    DRAM                                                                0
-
-  * AHB gates ("allwinner,sun4i-ahb-gates-clk")
-
-    USB0                                                                0
-    EHCI0                                                               1
-    OHCI0                                                               2*
-    EHCI1                                                               3
-    OHCI1                                                               4*
-    SS                                                                  5
-    DMA                                                                 6
-    BIST                                                                7
-    MMC0                                                                8
-    MMC1                                                                9
-    MMC2                                                                10
-    MMC3                                                                11
-    MS                                                                  12**
-    NAND                                                                13
-    SDRAM                                                               14
-
-    ACE                                                                 16
-    EMAC                                                                17
-    TS                                                                  18
-
-    SPI0                                                                20
-    SPI1                                                                21
-    SPI2                                                                22
-    SPI3                                                                23
-    PATA                                                                24
-    SATA                                                                25**
-    GPS                                                                 26*
-
-    VE                                                                  32
-    TVD                                                                 33
-    TVE0                                                                34
-    TVE1                                                                35
-    LCD0                                                                36
-    LCD1                                                                37
-
-    CSI0                                                                40
-    CSI1                                                                41
-
-    HDMI                                                                43
-    DE_BE0                                                              44
-    DE_BE1                                                              45
-    DE_FE0                                                              46
-    DE_FE1                                                              47
-
-    MP                                                                  50
-
-    MALI400                                                             52
-
-  * APB0 gates ("allwinner,sun4i-apb0-gates-clk")
-
-    CODEC                                                               0
-    SPDIF                                                               1*
-    AC97                                                                2
-    IIS                                                                 3
-
-    PIO                                                                 5
-    IR0                                                                 6
-    IR1                                                                 7
-
-    KEYPAD                                                              10
-
-  * APB1 gates ("allwinner,sun4i-apb1-gates-clk")
-
-    I2C0                                                                0
-    I2C1                                                                1
-    I2C2                                                                2
-
-    CAN                                                                 4
-    SCR                                                                 5
-    PS20                                                                6
-    PS21                                                                7
-
-    UART0                                                               16
-    UART1                                                               17
-    UART2                                                               18
-    UART3                                                               19
-    UART4                                                               20
-    UART5                                                               21
-    UART6                                                               22
-    UART7                                                               23
-
-Notation:
- [*]:  The datasheet didn't mention these, but they are present on AW code
- [**]: The datasheet had this marked as "NC" but they are used on AW code
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/vf610-clock.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/vf610-clock.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/vf610-clock.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/vf610-clock.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,26 @@
+* Clock bindings for Freescale Vybrid VF610 SOC
+
+Required properties:
+- compatible: Should be "fsl,vf610-ccm"
+- reg: Address and length of the register set
+- #clock-cells: Should be <1>
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell. See include/dt-bindings/clock/vf610-clock.h
+for the full list of VF610 clock IDs.
+
+Examples:
+
+clks: ccm@4006b000 {
+	compatible = "fsl,vf610-ccm";
+	reg = <0x4006b000 0x1000>;
+	#clock-cells = <1>;
+};
+
+uart1: serial@40028000 {
+	compatible = "fsl,vf610-uart";
+	reg = <0x40028000 0x1000>;
+	interrupts = <0 62 0x04>;
+	clocks = <&clks VF610_CLK_UART1>;
+	clock-names = "ipg";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/vt8500.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/vt8500.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/vt8500.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/vt8500.txt	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,8 @@ Required properties:
 - compatible : shall be one of the following:
 	"via,vt8500-pll-clock" - for a VT8500/WM8505 PLL clock
 	"wm,wm8650-pll-clock" - for a WM8650 PLL clock
+	"wm,wm8750-pll-clock" - for a WM8750 PLL clock
+	"wm,wm8850-pll-clock" - for a WM8850 PLL clock
 	"via,vt8500-device-clock" - for a VT/WM device clock
 
 Required properties for PLL clocks:
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/zynq-7000.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/zynq-7000.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/clock/zynq-7000.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/clock/zynq-7000.txt	2013-08-25 20:43:22.000000000 -0400
@@ -6,50 +6,99 @@ The purpose of this document is to docum
 See clock_bindings.txt for more information on the generic clock bindings.
 See Chapter 25 of Zynq TRM for more information about Zynq clocks.
 
-== PLLs ==
-
-Used to describe the ARM_PLL, DDR_PLL, and IO_PLL.
+== Clock Controller ==
+The clock controller is a logical abstraction of Zynq's clock tree. It reads
+required input clock frequencies from the devicetree and acts as clock provider
+for all clock consumers of PS clocks.
 
 Required properties:
-- #clock-cells : shall be 0 (only one clock is output from this node)
-- compatible : "xlnx,zynq-pll"
-- reg : pair of u32 values, which are the address offsets within the SLCR
-        of the relevant PLL_CTRL register and PLL_CFG register respectively
-- clocks : phandle for parent clock.  should be the phandle for ps_clk
+ - #clock-cells : Must be 1
+ - compatible : "xlnx,ps7-clkc"
+ - ps-clk-frequency : Frequency of the oscillator providing ps_clk in HZ
+		      (usually 33 MHz oscillators are used for Zynq platforms)
+ - clock-output-names : List of strings used to name the clock outputs. Shall be
+			a list of the outputs given below.
 
 Optional properties:
-- clock-output-names : name of the output clock
-
-Example:
-	armpll: armpll {
-		#clock-cells = <0>;
-		compatible = "xlnx,zynq-pll";
-		clocks = <&ps_clk>;
-		reg = <0x100 0x110>;
-		clock-output-names = "armpll";
-	};
-
-== Peripheral clocks ==
+ - clocks : as described in the clock bindings
+ - clock-names : as described in the clock bindings
 
-Describes clock node for the SDIO, SMC, SPI, QSPI, and UART clocks.
+Clock inputs:
+The following strings are optional parameters to the 'clock-names' property in
+order to provide an optional (E)MIO clock source.
+ - swdt_ext_clk
+ - gem0_emio_clk
+ - gem1_emio_clk
+ - mio_clk_XX		# with XX = 00..53
+...
 
-Required properties:
-- #clock-cells : shall be 1
-- compatible : "xlnx,zynq-periph-clock"
-- reg : a single u32 value, describing the offset within the SLCR where
-        the CLK_CTRL register is found for this peripheral
-- clocks : phandle for parent clocks.  should hold phandles for
-           the IO_PLL, ARM_PLL, and DDR_PLL in order
-- clock-output-names : names of the output clock(s).  For peripherals that have
-                       two output clocks (for example, the UART), two clocks
-                       should be listed.
+Clock outputs:
+ 0:  armpll
+ 1:  ddrpll
+ 2:  iopll
+ 3:  cpu_6or4x
+ 4:  cpu_3or2x
+ 5:  cpu_2x
+ 6:  cpu_1x
+ 7:  ddr2x
+ 8:  ddr3x
+ 9:  dci
+ 10: lqspi
+ 11: smc
+ 12: pcap
+ 13: gem0
+ 14: gem1
+ 15: fclk0
+ 16: fclk1
+ 17: fclk2
+ 18: fclk3
+ 19: can0
+ 20: can1
+ 21: sdio0
+ 22: sdio1
+ 23: uart0
+ 24: uart1
+ 25: spi0
+ 26: spi1
+ 27: dma
+ 28: usb0_aper
+ 29: usb1_aper
+ 30: gem0_aper
+ 31: gem1_aper
+ 32: sdio0_aper
+ 33: sdio1_aper
+ 34: spi0_aper
+ 35: spi1_aper
+ 36: can0_aper
+ 37: can1_aper
+ 38: i2c0_aper
+ 39: i2c1_aper
+ 40: uart0_aper
+ 41: uart1_aper
+ 42: gpio_aper
+ 43: lqspi_aper
+ 44: smc_aper
+ 45: swdt
+ 46: dbg_trc
+ 47: dbg_apb
 
 Example:
-	uart_clk: uart_clk {
+	clkc: clkc {
 		#clock-cells = <1>;
-		compatible = "xlnx,zynq-periph-clock";
-		clocks = <&iopll &armpll &ddrpll>;
-		reg = <0x154>;
-		clock-output-names = "uart0_ref_clk",
-				     "uart1_ref_clk";
+		compatible = "xlnx,ps7-clkc";
+		ps-clk-frequency = <33333333>;
+		clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
+				"cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
+				"dci", "lqspi", "smc", "pcap", "gem0", "gem1",
+				"fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
+				"sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
+				"dma", "usb0_aper", "usb1_aper", "gem0_aper",
+				"gem1_aper", "sdio0_aper", "sdio1_aper",
+				"spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
+				"i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
+				"gpio_aper", "lqspi_aper", "smc_aper", "swdt",
+				"dbg_trc", "dbg_apb";
+		# optional props
+		clocks = <&clkc 16>, <&clk_foo>;
+		clock-names = "gem1_emio_clk", "can_mio_clk_23";
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/atmel-dma.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/atmel-dma.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/atmel-dma.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/atmel-dma.txt	2013-08-25 20:43:22.000000000 -0400
@@ -24,8 +24,11 @@ The three cells in order are:
 1. A phandle pointing to the DMA controller.
 2. The memory interface (16 most significant bits), the peripheral interface
 (16 less significant bits).
-3. The peripheral identifier for the hardware handshaking interface. The
-identifier can be different for tx and rx.
+3. Parameters for the at91 DMA configuration register which are device
+dependant:
+  - bit 7-0: peripheral identifier for the hardware handshaking interface. The
+  identifier can be different for tx and rx.
+  - bit 11-8: FIFO configuration. 0 for half FIFO, 1 for ALAP, 1 for ASAP.
 
 Example:
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/fsl-imx-dma.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/fsl-imx-dma.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/fsl-imx-dma.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/fsl-imx-dma.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,48 @@
+* Freescale Direct Memory Access (DMA) Controller for i.MX
+
+This document will only describe differences to the generic DMA Controller and
+DMA request bindings as described in dma/dma.txt .
+
+* DMA controller
+
+Required properties:
+- compatible : Should be "fsl,<chip>-dma". chip can be imx1, imx21 or imx27
+- reg : Should contain DMA registers location and length
+- interrupts : First item should be DMA interrupt, second one is optional and
+    should contain DMA Error interrupt
+- #dma-cells : Has to be 1. imx-dma does not support anything else.
+
+Optional properties:
+- #dma-channels : Number of DMA channels supported. Should be 16.
+- #dma-requests : Number of DMA requests supported.
+
+Example:
+
+	dma: dma@10001000 {
+		compatible = "fsl,imx27-dma";
+		reg = <0x10001000 0x1000>;
+		interrupts = <32 33>;
+		#dma-cells = <1>;
+		#dma-channels = <16>;
+	};
+
+
+* DMA client
+
+Clients have to specify the DMA requests with phandles in a list.
+
+Required properties:
+- dmas: List of one or more DMA request specifiers. One DMA request specifier
+    consists of a phandle to the DMA controller followed by the integer
+    specifiying the request line.
+- dma-names: List of string identifiers for the DMA requests. For the correct
+    names, have a look at the specific client driver.
+
+Example:
+
+	sdhci1: sdhci@10013000 {
+		...
+		dmas = <&dma 7>;
+		dma-names = "rx-tx";
+		...
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt	2013-07-01 10:32:41.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt	2013-08-31 17:52:10.000000000 -0400
@@ -4,14 +4,70 @@ Required properties:
 - compatible : Should be "fsl,<chip>-sdma"
 - reg : Should contain SDMA registers location and length
 - interrupts : Should contain SDMA interrupt
+- #dma-cells : Must be <3>.
+  The first cell specifies the DMA request/event ID.  See details below
+  about the second and third cell.
 - fsl,sdma-ram-script-name : Should contain the full path of SDMA RAM
   scripts firmware
 
+The second cell of dma phandle specifies the peripheral type of DMA transfer.
+The full ID of peripheral types can be found below.
+
+	ID	transfer type
+	---------------------
+	0	MCU domain SSI
+	1	Shared SSI
+	2	MMC
+	3	SDHC
+	4	MCU domain UART
+	5	Shared UART
+	6	FIRI
+	7	MCU domain CSPI
+	8	Shared CSPI
+	9	SIM
+	10	ATA
+	11	CCM
+	12	External peripheral
+	13	Memory Stick Host Controller
+	14	Shared Memory Stick Host Controller
+	15	DSP
+	16	Memory
+	17	FIFO type Memory
+	18	SPDIF
+	19	IPU Memory
+	20	ASRC
+	21	ESAI
+
+The third cell specifies the transfer priority as below.
+
+	ID	transfer priority
+	-------------------------
+	0	High
+	1	Medium
+	2	Low
+
 Examples:
 
 sdma@83fb0000 {
 	compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
 	reg = <0x83fb0000 0x4000>;
 	interrupts = <6>;
+	#dma-cells = <3>;
 	fsl,sdma-ram-script-name = "/*(DEBLOBBED)*/";
 };
+
+DMA clients connected to the i.MX SDMA controller must use the format
+described in the dma.txt file.
+
+Examples:
+
+ssi2: ssi@70014000 {
+	compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+	reg = <0x70014000 0x4000>;
+	interrupts = <30>;
+	clocks = <&clks 49>;
+	dmas = <&sdma 24 1 0>,
+	       <&sdma 25 1 0>;
+	dma-names = "rx", "tx";
+	fsl,fifo-depth = <15>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/shdma.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/shdma.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/shdma.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/shdma.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,75 @@
+* SHDMA Device Tree bindings
+
+Sh-/r-mobile and r-car systems often have multiple identical DMA controller
+instances, capable of serving any of a common set of DMA slave devices, using
+the same configuration. To describe this topology we require all compatible
+SHDMA DT nodes to be placed under a DMA multiplexer node. All such compatible
+DMAC instances have the same number of channels and use the same DMA
+descriptors. Therefore respective DMA DT bindings can also all be placed in the
+multiplexer node. Even if there is only one such DMAC instance on a system, it
+still has to be placed under such a multiplexer node.
+
+* DMA multiplexer
+
+Required properties:
+- compatible:	should be "renesas,shdma-mux"
+- #dma-cells:	should be <1>, see "dmas" property below
+
+Optional properties (currently unused):
+- dma-channels:	number of DMA channels
+- dma-requests:	number of DMA request signals
+
+* DMA controller
+
+Required properties:
+- compatible:	should be "renesas,shdma"
+
+Example:
+	dmac: dma-mux0 {
+		compatible = "renesas,shdma-mux";
+		#dma-cells = <1>;
+		dma-channels = <6>;
+		dma-requests = <256>;
+		reg = <0 0>;	/* Needed for AUXDATA */
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		dma0: shdma@fe008020 {
+			compatible = "renesas,shdma";
+			reg = <0xfe008020 0x270>,
+				<0xfe009000 0xc>;
+			interrupt-parent = <&gic>;
+			interrupts = <0 34 4
+					0 28 4
+					0 29 4
+					0 30 4
+					0 31 4
+					0 32 4
+					0 33 4>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5";
+		};
+
+		dma1: shdma@fe018020 {
+			...
+		};
+
+		dma2: shdma@fe028020 {
+			...
+		};
+	};
+
+* DMA client
+
+Required properties:
+- dmas:		a list of <[DMA multiplexer phandle] [MID/RID value]> pairs,
+		where MID/RID values are fixed handles, specified in the SoC
+		manual
+- dma-names:	a list of DMA channel names, one per "dmas" entry
+
+Example:
+	dmas = <&dmac 0xd1
+		&dmac 0xd2>;
+	dma-names = "tx", "rx";
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/ste-coh901318.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/ste-coh901318.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/ste-coh901318.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/ste-coh901318.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,32 @@
+ST-Ericsson COH 901 318 DMA Controller
+
+This is a DMA controller which has begun as a fork of the
+ARM PL08x PrimeCell VHDL code.
+
+Required properties:
+- compatible: should be "stericsson,coh901318"
+- reg: register locations and length
+- interrupts: the single DMA IRQ
+- #dma-cells: must be set to <1>, as the channels on the
+  COH 901 318 are simple and identified by a single number
+- dma-channels: the number of DMA channels handled
+
+Example:
+
+dmac: dma-controller@c00020000 {
+	compatible = "stericsson,coh901318";
+	reg = <0xc0020000 0x1000>;
+	interrupt-parent = <&vica>;
+	interrupts = <2>;
+	#dma-cells = <1>;
+	dma-channels = <40>;
+};
+
+Consumers example:
+
+uart0: serial@c0013000 {
+	compatible = "...";
+	(...)
+	dmas = <&dmac 17 &dmac 18>;
+	dma-names = "tx", "rx";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/ste-dma40.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/ste-dma40.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/ste-dma40.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/ste-dma40.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,66 @@
+* DMA40 DMA Controller
+
+Required properties:
+- compatible: "stericsson,dma40"
+- reg: Address range of the DMAC registers
+- reg-names: Names of the above areas to use during resource look-up
+- interrupt: Should contain the DMAC interrupt number
+- #dma-cells: must be <3>
+- memcpy-channels: Channels to be used for memcpy
+
+Optional properties:
+- dma-channels: Number of channels supported by hardware - if not present
+		the driver will attempt to obtain the information from H/W
+- disabled-channels: Channels which can not be used
+
+Example:
+
+	dma: dma-controller@801C0000 {
+		compatible = "stericsson,db8500-dma40", "stericsson,dma40";
+		reg = <0x801C0000 0x1000  0x40010000 0x800>;
+		reg-names = "base", "lcpa";
+		interrupt-parent = <&intc>;
+		interrupts = <0 25 0x4>;
+
+		#dma-cells = <2>;
+		memcpy-channels  = <56 57 58 59 60>;
+		disabled-channels  = <12>;
+		dma-channels = <8>;
+	};
+
+Clients
+Required properties:
+- dmas: Comma separated list of dma channel requests
+- dma-names: Names of the aforementioned requested channels
+
+Each dmas request consists of 4 cells:
+  1. A phandle pointing to the DMA controller
+  2. Device Type
+  3. The DMA request line number (only when 'use fixed channel' is set)
+  4. A 32bit mask specifying; mode, direction and endianess [NB: This list will grow]
+        0x00000001: Mode:
+                Logical channel when unset
+                Physical channel when set
+        0x00000002: Direction:
+                Memory to Device when unset
+                Device to Memory when set
+        0x00000004: Endianess:
+                Little endian when unset
+                Big endian when set
+        0x00000008: Use fixed channel:
+                Use automatic channel selection when unset
+                Use DMA request line number when set
+
+Example:
+
+	uart@80120000 {
+		compatible = "arm,pl011", "arm,primecell";
+		reg = <0x80120000 0x1000>;
+		interrupts = <0 11 0x4>;
+
+		dmas = <&dma 13 0 0x2>, /* Logical - DevToMem */
+		       <&dma 13 0 0x0>; /* Logical - MemToDev */
+		dma-names = "rx", "rx";
+
+		status = "disabled";
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/ti-edma.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/ti-edma.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/dma/ti-edma.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/dma/ti-edma.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,34 @@
+TI EDMA
+
+Required properties:
+- compatible : "ti,edma3"
+- ti,edma-regions: Number of regions
+- ti,edma-slots: Number of slots
+- #dma-cells: Should be set to <1>
+              Clients should use a single channel number per DMA request.
+- dma-channels: Specify total DMA channels per CC
+- reg: Memory map for accessing module
+- interrupt-parent: Interrupt controller the interrupt is routed through
+- interrupts: Exactly 3 interrupts need to be specified in the order:
+              1. Transfer completion interrupt.
+              2. Memory protection interrupt.
+              3. Error interrupt.
+Optional properties:
+- ti,hwmods: Name of the hwmods associated to the EDMA
+- ti,edma-xbar-event-map: Crossbar event to channel map
+
+Example:
+
+edma: edma@49000000 {
+	reg = <0x49000000 0x10000>;
+	interrupt-parent = <&intc>;
+	interrupts = <12 13 14>;
+	compatible = "ti,edma3";
+	ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
+	#dma-cells = <1>;
+	dma-channels = <64>;
+	ti,edma-regions = <4>;
+	ti,edma-slots = <256>;
+	ti,edma-xbar-event-map = <1 12
+				  2 13>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,14 @@ Recommended properties:
    services interrupts for this device.
  - ti,hwmods: Name of the hwmod associated to the LCDC
 
+Optional properties:
+ - max-bandwidth: The maximum pixels per second that the memory
+   interface / lcd controller combination can sustain
+ - max-width: The maximum horizontal pixel width supported by
+   the lcd controller.
+ - max-pixelclock: The maximum pixel clock that can be supported
+   by the lcd controller in KHz.
+
 Example:
 
 	fb: fb@4830e000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/extcon/extcon-twl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/extcon/extcon-twl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/extcon/extcon-twl.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/extcon/extcon-twl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,15 @@
+EXTCON FOR TWL CHIPS
+
+PALMAS USB COMPARATOR
+Required Properties:
+ - compatible : Should be "ti,palmas-usb" or "ti,twl6035-usb"
+ - vbus-supply : phandle to the regulator device tree node.
+
+Optional Properties:
+ - ti,wakeup : To enable the wakeup comparator in probe
+
+palmas-usb {
+       compatible = "ti,twl6035-usb", "ti,palmas-usb";
+       vbus-supply = <&smps10_reg>;
+       ti,wakeup;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-clps711x.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-clps711x.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-clps711x.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-clps711x.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,28 @@
+Cirrus Logic CLPS711X GPIO controller
+
+Required properties:
+- compatible: Should be "cirrus,clps711x-gpio"
+- reg: Physical base GPIO controller registers location and length.
+  There should be two registers, first is DATA register, the second
+  is DIRECTION.
+- gpio-controller: Marks the device node as a gpio controller.
+- #gpio-cells: Should be two. The first cell is the pin number and
+  the second cell is used to specify the gpio polarity:
+    0 = active high
+    1 = active low
+
+Note: Each GPIO port should have an alias correctly numbered in "aliases"
+node.
+
+Example:
+
+aliases {
+	gpio0 = &porta;
+};
+
+porta: gpio@80000000 {
+	compatible = "cirrus,clps711x-gpio";
+	reg = <0x80000000 0x1>, <0x80000040 0x1>;
+	gpio-controller;
+	#gpio-cells = <2>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-msm.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-msm.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-msm.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-msm.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,26 @@
+MSM GPIO controller bindings
+
+Required properties:
+- compatible:
+  - "qcom,msm-gpio" for MSM controllers
+- #gpio-cells : Should be two.
+  - first cell is the pin number
+  - second cell is used to specify optional parameters (unused)
+- gpio-controller : Marks the device node as a GPIO controller.
+- #interrupt-cells : Should be 2.
+- interrupt-controller: Mark the device node as an interrupt controller
+- interrupts : Specify the TLMM summary interrupt number
+- ngpio : Specify the number of MSM GPIOs
+
+Example:
+
+	msmgpio: gpio@fd510000 {
+		compatible = "qcom,msm-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		reg = <0xfd510000 0x4000>;
+		interrupts = <0 208 0>;
+		ngpio = <150>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-samsung.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-samsung.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-samsung.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-samsung.txt	2013-08-25 20:43:22.000000000 -0400
@@ -39,46 +39,3 @@ Example:
 		#gpio-cells = <4>;
 		gpio-controller;
 	};
-
-
-Samsung S3C24XX GPIO Controller
-
-Required properties:
-- compatible: Compatible property value should be "samsung,s3c24xx-gpio".
-
-- reg: Physical base address of the controller and length of memory mapped
-  region.
-
-- #gpio-cells: Should be 3. The syntax of the gpio specifier used by client nodes
-  should be the following with values derived from the SoC user manual.
-     <[phandle of the gpio controller node]
-      [pin number within the gpio controller]
-      [mux function]
-      [flags and pull up/down]
-
-  Values for gpio specifier:
-  - Pin number: depending on the controller a number from 0 up to 15.
-  - Mux function: Depending on the SoC and the gpio bank the gpio can be set
-                  as input, output or a special function
-  - Flags and Pull Up/Down: the values to use differ for the individual SoCs
-                    example S3C2416/S3C2450:
-                            0 - Pull Up/Down Disabled.
-                            1 - Pull Down Enabled.
-                            2 - Pull Up Enabled.
-          Bit 16 (0x00010000) - Input is active low.
-  Consult the user manual for the correct values of Mux and Pull Up/Down.
-
-- gpio-controller: Specifies that the node is a gpio controller.
-- #address-cells: should be 1.
-- #size-cells: should be 1.
-
-Example:
-
-	gpa: gpio-controller@56000000 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		compatible = "samsung,s3c24xx-gpio";
-		reg = <0x56000000 0x10>;
-		#gpio-cells = <3>;
-		gpio-controller;
-	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-stericsson-coh901.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,7 @@
+ST-Ericsson COH 901 571/3 GPIO controller
+
+Required properties:
+- compatible: Compatible property value should be "stericsson,gpio-coh901"
+- reg: Physical base address of the controller and length of memory mapped
+  region.
+- interrupts: the 0...n interrupts assigned to the different GPIO ports/banks.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/gpio-xilinx.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,48 @@
+Xilinx plb/axi GPIO controller
+
+Dual channel GPIO controller with configurable number of pins
+(from 1 to 32 per channel). Every pin can be configured as
+input/output/tristate. Both channels share the same global IRQ but
+local interrupts can be enabled on channel basis.
+
+Required properties:
+- compatible : Should be "xlnx,xps-gpio-1.00.a"
+- reg : Address and length of the register set for the device
+- #gpio-cells : Should be two. The first cell is the pin number and the
+  second cell is used to specify optional parameters (currently unused).
+- gpio-controller : Marks the device node as a GPIO controller.
+
+Optional properties:
+- interrupts : Interrupt mapping for GPIO IRQ.
+- interrupt-parent : Phandle for the interrupt controller that
+  services interrupts for this device.
+- xlnx,all-inputs : if n-th bit is setup, GPIO-n is input
+- xlnx,dout-default : if n-th bit is 1, GPIO-n default value is 1
+- xlnx,gpio-width : gpio width
+- xlnx,tri-default : if n-th bit is 1, GPIO-n is in tristate mode
+- xlnx,is-dual : if 1, controller also uses the second channel
+- xlnx,all-inputs-2 : as above but for the second channel
+- xlnx,dout-default-2 : as above but the second channel
+- xlnx,gpio2-width : as above but for the second channel
+- xlnx,tri-default-2 : as above but for the second channel
+
+
+Example:
+gpio: gpio@40000000 {
+	#gpio-cells = <2>;
+	compatible = "xlnx,xps-gpio-1.00.a";
+	gpio-controller ;
+	interrupt-parent = <&microblaze_0_intc>;
+	interrupts = < 6 2 >;
+	reg = < 0x40000000 0x10000 >;
+	xlnx,all-inputs = <0x0>;
+	xlnx,all-inputs-2 = <0x0>;
+	xlnx,dout-default = <0x0>;
+	xlnx,dout-default-2 = <0x0>;
+	xlnx,gpio-width = <0x2>;
+	xlnx,gpio2-width = <0x2>;
+	xlnx,interrupt-present = <0x1>;
+	xlnx,is-dual = <0x1>;
+	xlnx,tri-default = <0xffffffff>;
+	xlnx,tri-default-2 = <0xffffffff>;
+} ;
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/men-a021-wdt.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/men-a021-wdt.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/men-a021-wdt.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/men-a021-wdt.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,25 @@
+Bindings for MEN A21 Watchdog device connected to GPIO lines
+
+Required properties:
+- compatible: "men,a021-wdt"
+- gpios: Specifies the pins that control the Watchdog, order:
+  1: Watchdog enable
+  2: Watchdog fast-mode
+  3: Watchdog trigger
+  4: Watchdog reset cause bit 0
+  5: Watchdog reset cause bit 1
+  6: Watchdog reset cause bit 2
+
+Optional properties:
+- None
+
+Example:
+	watchdog {
+		compatible ="men,a021-wdt";
+		gpios = <&gpio3 9  1	/* WD_EN */
+			 &gpio3 10 1	/* WD_FAST */
+			 &gpio3 11 1	/* WD_TRIG */
+			 &gpio3 6  1	/* RST_CAUSE[0] */
+			 &gpio3 7  1	/* RST_CAUSE[1] */
+			 &gpio3 8  1>;	/* RST_CAUSE[2] */
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,46 @@
+* Renesas R-Car GPIO Controller
+
+Required Properties:
+
+  - compatible: should be one of the following.
+    - "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller.
+    - "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller.
+    - "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller.
+    - "renesas,gpio-rcar": for generic R-Car GPIO controller.
+
+  - reg: Base address and length of each memory resource used by the GPIO
+    controller hardware module.
+
+  - interrupt-parent: phandle of the parent interrupt controller.
+  - interrupts: Interrupt specifier for the controllers interrupt.
+
+  - gpio-controller: Marks the device node as a gpio controller.
+  - #gpio-cells: Should be 2. The first cell is the GPIO number and the second
+    cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
+    GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
+  - gpio-ranges: Range of pins managed by the GPIO controller.
+
+Please refer to gpio.txt in this directory for details of gpio-ranges property
+and the common GPIO bindings used by client devices.
+
+Example: R8A7779 (R-Car H1) GPIO controller nodes
+
+	gpio0: gpio@ffc40000 {
+		compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
+		reg = <0xffc40000 0x2c>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 141 0x4>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 0 32>;
+	};
+	...
+	gpio6: gpio@ffc46000 {
+		compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar";
+		reg = <0xffc46000 0x2c>;
+		interrupt-parent = <&gic>;
+		interrupts = <0 147 0x4>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 192 9>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpu/samsung-g2d.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpu/samsung-g2d.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/gpu/samsung-g2d.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/gpu/samsung-g2d.txt	2013-08-25 20:43:22.000000000 -0400
@@ -10,11 +10,16 @@ Required properties:
 	  mapped region.
 
   - interrupts : G2D interrupt number to the CPU.
+  - clocks : from common clock binding: handle to G2D clocks.
+  - clock-names : from common clock binding: must contain "sclk_fimg2d" and
+		  "fimg2d", corresponding to entries in the clocks property.
 
 Example:
 	g2d@12800000 {
 		compatible = "samsung,s5pv210-g2d";
 		reg = <0x12800000 0x1000>;
 		interrupts = <0 89 0>;
+		clocks = <&clock 177>, <&clock 277>;
+		clock-names = "sclk_fimg2d", "fimg2d";
 		status = "disabled";
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/hwmon/g762.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/hwmon/g762.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/hwmon/g762.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/hwmon/g762.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,47 @@
+GMT G762/G763 PWM Fan controller
+
+Required node properties:
+
+ - "compatible": must be either "gmt,g762" or "gmt,g763"
+ - "reg": I2C bus address of the device
+ - "clocks": a fixed clock providing input clock frequency
+	     on CLK pin of the chip.
+
+Optional properties:
+
+ - "fan_startv": fan startup voltage. Accepted values are 0, 1, 2 and 3.
+	       The higher the more.
+
+ - "pwm_polarity": pwm polarity. Accepted values are 0 (positive duty)
+	       and 1 (negative duty).
+
+ - "fan_gear_mode": fan gear mode. Supported values are 0, 1 and 2.
+
+If an optional property is not set in .dts file, then current value is kept
+unmodified (e.g. u-boot installed value).
+
+Additional information on operational parameters for the device is available
+in Documentation/hwmon/g762. A detailed datasheet for the device is available
+at http://natisbad.org/NAS/refs/GMT_EDS-762_763-080710-0.2.pdf.
+
+Example g762 node:
+
+   clocks {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	g762_clk: fixedclk {
+		 compatible = "fixed-clock";
+		 #clock-cells = <0>;
+		 clock-frequency = <8192>;
+	}
+   }
+
+   g762: g762@3e {
+	compatible = "gmt,g762";
+	reg = <0x3e>;
+	clocks = <&g762_clk>
+	fan_gear_mode = <0>; /* chip default */
+	fan_startv = <1>;    /* chip default */
+	pwm_polarity = <0>;  /* chip default */
+   };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/i2c-designware.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/i2c-designware.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/i2c-designware.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/i2c-designware.txt	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,10 @@ Recommended properties :
 
  - clock-frequency : desired I2C bus clock frequency in Hz.
 
+Optional properties :
+ - i2c-sda-hold-time-ns : should contain the SDA hold time in nanoseconds.
+   This option is only supported in hardware blocks version 1.11a or newer.
+
 Example :
 
 	i2c@f0000 {
@@ -20,3 +24,14 @@ Example :
 		interrupts = <11>;
 		clock-frequency = <400000>;
 	};
+
+	i2c@1120000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,designware-i2c";
+		reg = <0x1120000 0x1000>;
+		interrupt-parent = <&ictl>;
+		interrupts = <12 1>;
+		clock-frequency = <400000>;
+		i2c-sda-hold-time-ns = <300>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt	2013-08-25 20:43:22.000000000 -0400
@@ -4,9 +4,13 @@
 Required properties :
 
  - reg             : Offset and length of the register set for the device
- - compatible      : Should be "marvell,mv64xxx-i2c"
+ - compatible      : Should be "marvell,mv64xxx-i2c" or "allwinner,sun4i-i2c"
  - interrupts      : The interrupt number
- - clock-frequency : Desired I2C bus clock frequency in Hz.
+
+Optional properties :
+
+ - clock-frequency : Desired I2C bus clock frequency in Hz. If not set the
+default frequency is 100kHz
 
 Examples:
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/i2c-st-ddci2c.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/i2c-st-ddci2c.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/i2c-st-ddci2c.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/i2c-st-ddci2c.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,15 @@
+ST Microelectronics DDC I2C
+
+Required properties :
+- compatible : Must be "st,ddci2c"
+- reg: physical base address of the controller and length of memory mapped
+     region.
+- interrupts: interrupt number to the cpu.
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Optional properties:
+- Child nodes conforming to i2c bus binding
+
+Examples :
+
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/i2c-vt8500.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/i2c-vt8500.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/i2c-vt8500.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/i2c-vt8500.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,24 @@
+* Wondermedia I2C Controller
+
+Required properties :
+
+ - compatible : should be "wm,wm8505-i2c"
+ - reg : Offset and length of the register set for the device
+ - interrupts : <IRQ> where IRQ is the interrupt number
+ - clocks : phandle to the I2C clock source
+
+Optional properties :
+
+ - clock-frequency : desired I2C bus clock frequency in Hz.
+	Valid values are 100000 and 400000.
+	Default to 100000 if not specified, or invalid value.
+
+Example :
+
+	i2c_0: i2c@d8280000 {
+		compatible = "wm,wm8505-i2c";
+		reg = <0xd8280000 0x1000>;
+		interrupts = <19>;
+		clocks = <&clki2c0>;
+		clock-frequency = <400000>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/ina2xx.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/ina2xx.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/i2c/ina2xx.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/i2c/ina2xx.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,22 @@
+ina2xx properties
+
+Required properties:
+- compatible: Must be one of the following:
+	- "ti,ina219" for ina219
+	- "ti,ina220" for ina220
+	- "ti,ina226" for ina226
+	- "ti,ina230" for ina230
+- reg: I2C address
+
+Optional properties:
+
+- shunt-resistor
+	Shunt resistor value in micro-Ohm
+
+Example:
+
+ina220@44 {
+	compatible = "ti,ina220";
+	reg = <0x44>;
+	shunt-resistor = <1000>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/iio/dac/ad7303.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/iio/dac/ad7303.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/iio/dac/ad7303.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/iio/dac/ad7303.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,23 @@
+Analog Devices AD7303 DAC device driver
+
+Required properties:
+	- compatible: Must be "adi,ad7303"
+	- reg: SPI chip select number for the device
+	- spi-max-frequency: Max SPI frequency to use (< 30000000)
+	- Vdd-supply: Phandle to the Vdd power supply
+
+Optional properties:
+	- REF-supply: Phandle to the external reference voltage supply. This should
+	  only be set if there is an external reference voltage connected to the REF
+	  pin. If the property is not set Vdd/2 is used as the reference voltage.
+
+Example:
+
+		ad7303@4 {
+			compatible = "adi,ad7303";
+			reg = <4>;
+			spi-max-frequency = <10000000>;
+			Vdd-supply = <&vdd_supply>;
+			adi,use-external-reference;
+			REF-supply = <&vref_supply>;
+		};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/iio/frequency/adf4350.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/iio/frequency/adf4350.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/iio/frequency/adf4350.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/iio/frequency/adf4350.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,86 @@
+Analog Devices ADF4350/ADF4351 device driver
+
+Required properties:
+	- compatible: Should be one of
+		* "adi,adf4350": When using the ADF4350 device
+		* "adi,adf4351": When using the ADF4351 device
+	- reg: SPI chip select numbert for the device
+	- spi-max-frequency: Max SPI frequency to use (< 20000000)
+	- clocks: From common clock binding. Clock is phandle to clock for
+		ADF435x Reference Clock (CLKIN).
+
+Optional properties:
+	- gpios:	 GPIO Lock detect - If set with a valid phandle and GPIO number,
+			pll lock state is tested upon read.
+	- adi,channel-spacing: Channel spacing in Hz (influences MODULUS).
+	- adi,power-up-frequency:	If set in Hz the PLL tunes to
+			the desired frequency on probe.
+	- adi,reference-div-factor: If set the driver skips dynamic calculation
+			and uses this default value instead.
+	- adi,reference-doubler-enable: Enables reference doubler.
+	- adi,reference-div2-enable: Enables reference divider.
+	- adi,phase-detector-polarity-positive-enable: Enables positive phase
+			detector polarity. Default = negative.
+	- adi,lock-detect-precision-6ns-enable: Enables 6ns lock detect precision.
+			Default = 10ns.
+	- adi,lock-detect-function-integer-n-enable: Enables lock detect
+			for integer-N mode. Default = factional-N mode.
+	- adi,charge-pump-current: Charge pump current in mA.
+			Default = 2500mA.
+	- adi,muxout-select: On chip multiplexer output selection.
+			Valid values for the multiplexer output are:
+			0: Three-State Output (default)
+			1: DVDD
+			2: DGND
+			3: R-Counter output
+			4: N-Divider output
+			5: Analog lock detect
+			6: Digital lock detect
+	- adi,low-spur-mode-enable: Enables low spur mode.
+			Default = Low noise mode.
+	- adi,cycle-slip-reduction-enable: Enables cycle slip reduction.
+	- adi,charge-cancellation-enable: Enabled charge pump
+			charge cancellation for integer-N modes.
+	- adi,anti-backlash-3ns-enable: Enables 3ns antibacklash pulse width
+			 for integer-N modes.
+	- adi,band-select-clock-mode-high-enable: Enables faster band
+			selection logic.
+	- adi,12bit-clk-divider: Clock divider value used when
+			adi,12bit-clkdiv-mode != 0
+	- adi,clk-divider-mode:
+			Valid values for the clkdiv mode are:
+			0: Clock divider off (default)
+			1: Fast lock enable
+			2: Phase resync enable
+	- adi,aux-output-enable: Enables auxiliary RF output.
+	- adi,aux-output-fundamental-enable: Selects fundamental VCO output on
+			the auxiliary RF output. Default = Output of RF dividers.
+	- adi,mute-till-lock-enable: Enables Mute-Till-Lock-Detect function.
+	- adi,output-power: Output power selection.
+			Valid values for the power mode are:
+			0: -4dBm (default)
+			1: -1dBm
+			2: +2dBm
+			3: +5dBm
+	- adi,aux-output-power: Auxiliary output power selection.
+			Valid values for the power mode are:
+			0: -4dBm (default)
+			1: -1dBm
+			2: +2dBm
+			3: +5dBm
+
+
+Example:
+		lo_pll0_rx_adf4351: adf4351-rx-lpc@4 {
+			compatible = "adi,adf4351";
+			reg = <4>;
+			spi-max-frequency = <10000000>;
+			clocks = <&clk0_ad9523 9>;
+			clock-names = "clkin";
+			adi,channel-spacing = <10000>;
+			adi,power-up-frequency = <2400000000>;
+			adi,phase-detector-polarity-positive-enable;
+			adi,charge-pump-current = <2500>;
+			adi,output-power = <3>;
+			adi,mute-till-lock-enable;
+		};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,18 @@
+* AsahiKASEI AK8975 magnetometer sensor
+
+Required properties:
+
+  - compatible : should be "asahi-kasei,ak8975"
+  - reg : the I2C address of the magnetometer
+
+Optional properties:
+
+  - gpios : should be device tree identifier of the magnetometer DRDY pin
+
+Example:
+
+ak8975@0c {
+        compatible = "asahi-kasei,ak8975";
+        reg = <0x0c>;
+        gpios = <&gpj0 7 0>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/ads7846.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/ads7846.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/ads7846.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/ads7846.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,91 @@
+Device tree bindings for TI's ADS7843, ADS7845, ADS7846, ADS7873, TSC2046
+SPI driven touch screen controllers.
+
+The node for this driver must be a child node of a SPI controller, hence
+all mandatory properties described in
+
+	Documentation/devicetree/bindings/spi/spi-bus.txt
+
+must be specified.
+
+Additional required properties:
+
+	compatible		Must be one of the following, depending on the
+				model:
+					"ti,tsc2046"
+					"ti,ads7843"
+					"ti,ads7845"
+					"ti,ads7846"
+					"ti,ads7873"
+
+	interrupt-parent
+	interrupts		An interrupt node describing the IRQ line the chip's
+				!PENIRQ pin is connected to.
+	vcc-supply		A regulator node for the supply voltage.
+
+
+Optional properties:
+
+	ti,vref-delay-usecs		vref supply delay in usecs, 0 for
+					external vref (u16).
+	ti,vref-mv			The VREF voltage, in millivolts (u16).
+	ti,keep-vref-on			set to keep vref on for differential
+					measurements as well
+	ti,swap-xy			swap x and y axis
+	ti,settle-delay-usec		Settling time of the analog signals;
+					a function of Vcc and the capacitance
+					on the X/Y drivers.  If set to non-zero,
+					two samples are taken with settle_delay
+					us apart, and the second one is used.
+					~150 uSec with 0.01uF caps (u16).
+	ti,penirq-recheck-delay-usecs	If set to non-zero, after samples are
+					taken this delay is applied and penirq
+					is rechecked, to help avoid false
+					events.  This value is affected by the
+					material used to build the touch layer
+					(u16).
+	ti,x-plate-ohms			Resistance of the X-plate,
+					in Ohms (u16).
+	ti,y-plate-ohms			Resistance of the Y-plate,
+					in Ohms (u16).
+	ti,x-min			Minimum value on the X axis (u16).
+	ti,y-min			Minimum value on the Y axis (u16).
+	ti,x-max			Maximum value on the X axis (u16).
+	ti,y-max			Minimum value on the Y axis (u16).
+	ti,pressure-min			Minimum reported pressure value
+					(threshold) - u16.
+	ti,pressure-max			Maximum reported pressure value (u16).
+	ti,debounce-max			Max number of additional readings per
+					sample (u16).
+	ti,debounce-tol			Tolerance used for filtering (u16).
+	ti,debounce-rep			Additional consecutive good readings
+					required after the first two (u16).
+	ti,pendown-gpio-debounce	Platform specific debounce time for the
+					pendown-gpio (u32).
+	pendown-gpio			GPIO handle describing the pin the !PENIRQ
+					line is connected to.
+	linux,wakeup			use any event on touchscreen as wakeup event.
+
+
+Example for a TSC2046 chip connected to an McSPI controller of an OMAP SoC::
+
+	spi_controller {
+		tsc2046@0 {
+			reg = <0>;	/* CS0 */
+			compatible = "ti,tsc2046";
+			interrupt-parent = <&gpio1>;
+			interrupts = <8 0>;	/* BOOT6 / GPIO 8 */
+			spi-max-frequency = <1000000>;
+			pendown-gpio = <&gpio1 8 0>;
+			vcc-supply = <&reg_vcc3>;
+
+			ti,x-min = /bits/ 16 <0>;
+			ti,x-max = /bits/ 16 <8000>;
+			ti,y-min = /bits/ 16 <0>;
+			ti,y-max = /bits/ 16 <4800>;
+			ti,x-plate-ohms = /bits/ 16 <40>;
+			ti,pressure-max = /bits/ 16 <255>;
+
+			linux,wakeup;
+		};
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/pxa27x-keypad.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/pxa27x-keypad.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/pxa27x-keypad.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/pxa27x-keypad.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,60 @@
+* Marvell PXA Keypad controller
+
+Required Properties
+- compatible : should be "marvell,pxa27x-keypad"
+- reg : Address and length of the register set for the device
+- interrupts : The interrupt for the keypad controller
+- marvell,debounce-interval : How long time the key will be
+  recognized when it is pressed. It is a u32 value, and bit[31:16]
+  is debounce interval for direct key and bit[15:0] is debounce
+  interval for matrix key. The value is in binary number of 2ms
+
+Optional Properties For Matrix Keyes
+Please refer to matrix-keymap.txt
+
+Optional Properties for Direct Keyes
+- marvell,direct-key-count : How many direct keyes are used.
+- marvell,direct-key-mask : The mask indicates which keyes
+  are used. If bit[X] of the mask is set, the direct key X
+  is used.
+- marvell,direct-key-low-active : Direct key status register
+  tells the level of pins that connects to the direct keyes.
+  When this property is set, it means that when the pin level
+  is low, the key is pressed(active).
+- marvell,direct-key-map : It is a u16 array. Each item indicates
+  the linux key-code for the direct key.
+
+Optional Properties For Rotary
+- marvell,rotary0 : It is a u32 value. Bit[31:16] is the
+  linux key-code for rotary up. Bit[15:0] is the linux key-code
+  for rotary down. It is for rotary 0.
+- marvell,rotary1 : Same as marvell,rotary0. It is for rotary 1.
+- marvell,rotary-rel-key : When rotary is used for relative axes
+  in the device, the value indicates the key-code for relative
+  axes measurement in the device. It is a u32 value. Bit[31:16]
+  is for rotary 1, and Bit[15:0] is for rotary 0.
+
+Examples:
+	keypad: keypad@d4012000 {
+		keypad,num-rows = <3>;
+		keypad,num-columns = <5>;
+		linux,keymap = <0x0000000e	/* KEY_BACKSPACE */
+				0x0001006b	/* KEY_END */
+				0x00020061	/* KEY_RIGHTCTRL */
+				0x0003000b	/* KEY_0 */
+				0x00040002	/* KEY_1 */
+				0x0100008b	/* KEY_MENU */
+				0x01010066	/* KEY_HOME */
+				0x010200e7	/* KEY_SEND */
+				0x01030009	/* KEY_8 */
+				0x0104000a	/* KEY_9 */
+				0x02000160	/* KEY_OK */
+				0x02010003	/* KEY_2 */
+				0x02020004	/* KEY_3 */
+				0x02030005	/* KEY_4 */
+				0x02040006>;	/* KEY_5 */
+		marvell,rotary0 = <0x006c0067>;	/* KEY_UP & KEY_DOWN */
+		marvell,direct-key-count = <1>;
+		marvell,direct-key-map = <0x001c>;
+		marvell,debounce-interval = <0x001e001e>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/samsung-keypad.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/samsung-keypad.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/samsung-keypad.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/samsung-keypad.txt	2013-08-25 20:43:22.000000000 -0400
@@ -25,14 +25,6 @@ Required Board Specific Properties:
 - samsung,keypad-num-columns: Number of column lines connected to the
   keypad controller.
 
-- row-gpios: List of gpios used as row lines. The gpio specifier for
-  this property depends on the gpio controller to which these row lines
-  are connected.
-
-- col-gpios: List of gpios used as column lines. The gpio specifier for
-  this property depends on the gpio controller to which these column
-  lines are connected.
-
 - Keys represented as child nodes: Each key connected to the keypad
   controller is represented as a child node to the keypad controller
   device node and should include the following properties.
@@ -41,6 +33,9 @@ Required Board Specific Properties:
   - linux,code: the key-code to be reported when the key is pressed
     and released.
 
+- pinctrl-0: Should specify pin control groups used for this controller.
+- pinctrl-names: Should contain only one value - "default".
+
 Optional Properties specific to linux:
 - linux,keypad-no-autorepeat: do no enable autorepeat feature.
 - linux,keypad-wakeup: use any event on keypad as wakeup event.
@@ -56,17 +51,8 @@ Example:
 		linux,input-no-autorepeat;
 		linux,input-wakeup;
 
-		row-gpios = <&gpx2 0 3 3 0
-			     &gpx2 1 3 3 0>;
-
-		col-gpios = <&gpx1 0 3 0 0
-			     &gpx1 1 3 0 0
-			     &gpx1 2 3 0 0
-			     &gpx1 3 3 0 0
-			     &gpx1 4 3 0 0
-			     &gpx1 5 3 0 0
-			     &gpx1 6 3 0 0
-			     &gpx1 7 3 0 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&keypad_rows &keypad_columns>;
 
 		key_1 {
 			keypad,row = <0>;
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/ti,nspire-keypad.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/ti,nspire-keypad.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/ti,nspire-keypad.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/ti,nspire-keypad.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,60 @@
+TI-NSPIRE Keypad
+
+Required properties:
+- compatible: Compatible property value should be "ti,nspire-keypad".
+
+- reg: Physical base address of the peripheral and length of memory mapped
+  region.
+
+- interrupts: The interrupt number for the peripheral.
+
+- scan-interval: How often to scan in us. Based on a APB speed of 33MHz, the
+	maximum and minimum delay time is ~2000us and ~500us respectively
+
+- row-delay: How long to wait before scanning each row.
+
+- clocks: The clock this peripheral is attached to.
+
+- linux,keymap: The keymap to use
+	(see Documentation/devicetree/bindings/input/matrix-keymap.txt)
+
+Optional properties:
+- active-low: Specify that the keypad is active low (i.e. logical low signifies
+	a key press).
+
+Example:
+
+input {
+	compatible = "ti,nspire-keypad";
+	reg = <0x900E0000 0x1000>;
+	interrupts = <16>;
+
+	scan-interval = <1000>;
+	row-delay = <200>;
+
+	clocks = <&apb_pclk>;
+
+	linux,keymap = <
+	0x0000001c	0x0001001c	0x00040039
+	0x0005002c	0x00060015	0x0007000b
+	0x0008000f	0x0100002d	0x01010011
+	0x0102002f	0x01030004	0x01040016
+	0x01050014	0x0106001f	0x01070002
+	0x010a006a	0x02000013	0x02010010
+	0x02020019	0x02030007	0x02040018
+	0x02050031	0x02060032	0x02070005
+	0x02080028	0x0209006c	0x03000026
+	0x03010025	0x03020024	0x0303000a
+	0x03040017	0x03050023	0x03060022
+	0x03070008	0x03080035	0x03090069
+	0x04000021	0x04010012	0x04020020
+	0x0404002e	0x04050030	0x0406001e
+	0x0407000d	0x04080037	0x04090067
+	0x05010038	0x0502000c	0x0503001b
+	0x05040034	0x0505001a	0x05060006
+	0x05080027	0x0509000e	0x050a006f
+	0x0600002b	0x0602004e	0x06030068
+	0x06040003	0x0605006d	0x06060009
+	0x06070001	0x0609000f	0x0708002a
+	0x0709001d	0x070a0033	>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,44 @@
+* TI - TSC ADC (Touschscreen and analog digital converter)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Required properties:
+- child "tsc"
+	ti,wires: Wires refer to application modes i.e. 4/5/8 wire touchscreen
+		  support on the platform.
+	ti,x-plate-resistance: X plate resistance
+	ti,coordiante-readouts: The sequencer supports a total of 16
+				programmable steps each step is used to
+				read a single coordinate. A single
+                                readout is enough but multiple reads can
+				increase the quality.
+				A value of 5 means, 5 reads for X, 5 for
+				Y and 2 for Z (always). This utilises 12
+				of the 16 software steps available. The
+				remaining 4 can be used by the ADC.
+	ti,wire-config: Different boards could have a different order for
+			connecting wires on touchscreen. We need to provide an
+			8 bit number where in the 1st four bits represent the
+			analog lines and the next 4 bits represent positive/
+			negative terminal on that input line. Notations to
+			represent the input lines and terminals resoectively
+			is as follows:
+			AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7.
+			XP  = 0, XN = 1, YP = 2, YN = 3.
+- child "adc"
+	ti,adc-channels: List of analog inputs available for ADC.
+			 AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7.
+
+Example:
+	tscadc: tscadc@44e0d000 {
+		compatible = "ti,am3359-tscadc";
+		tsc {
+			ti,wires = <4>;
+			ti,x-plate-resistance = <200>;
+			ti,coordiante-readouts = <5>;
+			ti,wire-config = <0x00 0x11 0x22 0x33>;
+		};
+
+		adc {
+			ti,adc-channels = <4 5 6 7>;
+		};
+	}
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/abilis,tb10x-ictl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/abilis,tb10x-ictl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/abilis,tb10x-ictl.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/abilis,tb10x-ictl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,38 @@
+TB10x Top Level Interrupt Controller
+====================================
+
+The Abilis TB10x SOC contains a custom interrupt controller. It performs
+one-to-one mapping of external interrupt sources to CPU interrupts and
+provides support for reconfigurable trigger modes.
+
+Required properties
+-------------------
+
+- compatible: Should be "abilis,tb10x-ictl"
+- reg: specifies physical base address and size of register range.
+- interrupt-congroller: Identifies the node as an interrupt controller.
+- #interrupt cells: Specifies the number of cells used to encode an interrupt
+  source connected to this controller. The value shall be 2.
+- interrupt-parent: Specifies the parent interrupt controller.
+- interrupts: Specifies the list of interrupt lines which are handled by
+  the interrupt controller in the parent controller's notation. Interrupts
+  are mapped one-to-one to parent interrupts.
+
+Example
+-------
+
+intc: interrupt-controller {	/* Parent interrupt controller */
+	interrupt-controller;
+	#interrupt-cells = <1>;	/* For example below */
+	/* ... */
+};
+
+tb10x_ictl: pic@2000 {		/* TB10x interrupt controller */
+	compatible = "abilis,tb10x-ictl";
+	reg = <0x2000 0x20>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+	interrupt-parent = <&intc>;
+	interrupts = <5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+			20 21 22 23 24 25 26 27 28 29 30 31>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt	2013-08-25 20:43:22.000000000 -0400
@@ -8,91 +8,8 @@ Required properties:
 - #interrupt-cells : Specifies the number of cells needed to encode an
   interrupt source. The value shall be 1.
 
-The interrupt sources are as follows:
-
-0: ENMI
-1: UART0
-2: UART1
-3: UART2
-4: UART3
-5: IR0
-6: IR1
-7: I2C0
-8: I2C1
-9: I2C2
-10: SPI0
-11: SPI1
-12: SPI2
-13: SPDIF
-14: AC97
-15: TS
-16: I2S
-17: UART4
-18: UART5
-19: UART6
-20: UART7
-21: KEYPAD
-22: TIMER0
-23: TIMER1
-24: TIMER2
-25: TIMER3
-26: CAN
-27: DMA
-28: PIO
-29: TOUCH_PANEL
-30: AUDIO_CODEC
-31: LRADC
-32: SDMC0
-33: SDMC1
-34: SDMC2
-35: SDMC3
-36: MEMSTICK
-37: NAND
-38: USB0
-39: USB1
-40: USB2
-41: SCR
-42: CSI0
-43: CSI1
-44: LCDCTRL0
-45: LCDCTRL1
-46: MP
-47: DEFEBE0
-48: DEFEBE1
-49: PMU
-50: SPI3
-51: TZASC
-52: PATA
-53: VE
-54: SS
-55: EMAC
-56: SATA
-57: GPS
-58: HDMI
-59: TVE
-60: ACE
-61: TVD
-62: PS2_0
-63: PS2_1
-64: USB3
-65: USB4
-66: PLE_PFM
-67: TIMER4
-68: TIMER5
-69: GPU_GP
-70: GPU_GPMMU
-71: GPU_PP0
-72: GPU_PPMMU0
-73: GPU_PMU
-74: GPU_RSV0
-75: GPU_RSV1
-76: GPU_RSV2
-77: GPU_RSV3
-78: GPU_RSV4
-79: GPU_RSV5
-80: GPU_RSV6
-82: SYNC_TIMER0
-83: SYNC_TIMER1
+For the valid interrupt sources for your SoC, see the documentation in
+sunxi/<soc>.txt
 
 Example:
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/marvell,orion-intc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/marvell,orion-intc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/marvell,orion-intc.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/marvell,orion-intc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,48 @@
+Marvell Orion SoC interrupt controllers
+
+* Main interrupt controller
+
+Required properties:
+- compatible: shall be "marvell,orion-intc"
+- reg: base address(es) of interrupt registers starting with CAUSE register
+- interrupt-controller: identifies the node as an interrupt controller
+- #interrupt-cells: number of cells to encode an interrupt source, shall be 1
+
+The interrupt sources map to the corresponding bits in the interrupt
+registers, i.e.
+- 0 maps to bit 0 of first base address,
+- 1 maps to bit 1 of first base address,
+- 32 maps to bit 0 of second base address, and so on.
+
+Example:
+	intc: interrupt-controller {
+		compatible = "marvell,orion-intc";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		 /* Dove has 64 first level interrupts */
+		reg = <0x20200 0x10>, <0x20210 0x10>;
+	};
+
+* Bridge interrupt controller
+
+Required properties:
+- compatible: shall be "marvell,orion-bridge-intc"
+- reg: base address of bridge interrupt registers starting with CAUSE register
+- interrupts: bridge interrupt of the main interrupt controller
+- interrupt-controller: identifies the node as an interrupt controller
+- #interrupt-cells: number of cells to encode an interrupt source, shall be 1
+
+Optional properties:
+- marvell,#interrupts: number of interrupts provided by bridge interrupt
+      controller, defaults to 32 if not set
+
+Example:
+	bridge_intc: interrupt-controller {
+		compatible = "marvell,orion-bridge-intc";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		reg = <0x20110 0x8>;
+		interrupts = <0>;
+		/* Dove bridge provides 5 interrupts */
+		marvell,#interrupts = <5>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/renesas,intc-irqpin.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,16 @@
+DT bindings for the R-/SH-Mobile irqpin controller
+
+Required properties:
+
+- compatible: has to be "renesas,intc-irqpin"
+- #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
+  interrupts.txt in this directory
+
+Optional properties:
+
+- any properties, listed in interrupts.txt, and any standard resource allocation
+  properties
+- sense-bitfield-width: width of a single sense bitfield in the SENSE register,
+  if different from the default 4 bits
+- control-parent: disable and enable interrupts on the parent interrupt
+  controller, needed for some broken implementations
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun4i-a10.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun4i-a10.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun4i-a10.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun4i-a10.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,89 @@
+Allwinner A10 (sun4i) interrupt sources
+---------------------------------------
+
+The interrupt sources available for the Allwinner A10 SoC are the
+following one:
+
+0: ENMI
+1: UART0
+2: UART1
+3: UART2
+4: UART3
+5: IR0
+6: IR1
+7: I2C0
+8: I2C1
+9: I2C2
+10: SPI0
+11: SPI1
+12: SPI2
+13: SPDIF
+14: AC97
+15: TS
+16: I2S
+17: UART4
+18: UART5
+19: UART6
+20: UART7
+21: KEYPAD
+22: TIMER0
+23: TIMER1
+24: TIMER2
+25: TIMER3
+26: CAN
+27: DMA
+28: PIO
+29: TOUCH_PANEL
+30: AUDIO_CODEC
+31: LRADC
+32: MMC0
+33: MMC1
+34: MMC2
+35: MMC3
+36: MEMSTICK
+37: NAND
+38: USB0
+39: USB1
+40: USB2
+41: SCR
+42: CSI0
+43: CSI1
+44: LCDCTRL0
+45: LCDCTRL1
+46: MP
+47: DEFEBE0
+48: DEFEBE1
+49: PMU
+50: SPI3
+51: TZASC
+52: PATA
+53: VE
+54: SS
+55: EMAC
+56: SATA
+57: GPS
+58: HDMI
+59: TVE
+60: ACE
+61: TVD
+62: PS2_0
+63: PS2_1
+64: USB3
+65: USB4
+66: PLE_PFM
+67: TIMER4
+68: TIMER5
+69: GPU_GP
+70: GPU_GPMMU
+71: GPU_PP0
+72: GPU_PPMMU0
+73: GPU_PMU
+74: GPU_RSV0
+75: GPU_RSV1
+76: GPU_RSV2
+77: GPU_RSV3
+78: GPU_RSV4
+79: GPU_RSV5
+80: GPU_RSV6
+82: SYNC_TIMER0
+83: SYNC_TIMER1
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun5i-a13.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun5i-a13.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun5i-a13.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/interrupt-controller/sunxi/sun5i-a13.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,55 @@
+Allwinner A13 (sun5i) interrupt sources
+---------------------------------------
+
+The interrupt sources available for the Allwinner A13 SoC are the
+following one:
+
+0: ENMI
+2: UART1
+4: UART3
+5: IR
+7: I2C0
+8: I2C1
+9: I2C2
+10: SPI0
+11: SPI1
+12: SPI2
+22: TIMER0
+23: TIMER1
+24: TIMER2
+25: TIMER3
+27: DMA
+28: PIO
+29: TOUCH_PANEL
+30: AUDIO_CODEC
+31: LRADC
+32: MMC0
+33: MMC1
+34: MMC2
+37: NAND
+38: USB OTG
+39: USB EHCI
+40: USB OHCI
+42: CSI
+44: LCDCTRL
+47: DEFEBE
+49: PMU
+53: VE
+54: SS
+66: PLE_PFM
+67: TIMER4
+68: TIMER5
+69: GPU_GP
+70: GPU_GPMMU
+71: GPU_PP0
+72: GPU_PPMMU0
+73: GPU_PMU
+74: GPU_RSV0
+75: GPU_RSV1
+76: GPU_RSV2
+77: GPU_RSV3
+78: GPU_RSV4
+79: GPU_RSV5
+80: GPU_RSV6
+82: SYNC_TIMER0
+83: SYNC_TIMER1
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/iommu/arm,smmu.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/iommu/arm,smmu.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/iommu/arm,smmu.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/iommu/arm,smmu.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,70 @@
+* ARM System MMU Architecture Implementation
+
+ARM SoCs may contain an implementation of the ARM System Memory
+Management Unit Architecture, which can be used to provide 1 or 2 stages
+of address translation to bus masters external to the CPU.
+
+The SMMU may also raise interrupts in response to various fault
+conditions.
+
+** System MMU required properties:
+
+- compatible    : Should be one of:
+
+                        "arm,smmu-v1"
+                        "arm,smmu-v2"
+                        "arm,mmu-400"
+                        "arm,mmu-500"
+
+                  depending on the particular implementation and/or the
+                  version of the architecture implemented.
+
+- reg           : Base address and size of the SMMU.
+
+- #global-interrupts : The number of global interrupts exposed by the
+                       device.
+
+- interrupts    : Interrupt list, with the first #global-irqs entries
+                  corresponding to the global interrupts and any
+                  following entries corresponding to context interrupts,
+                  specified in order of their indexing by the SMMU.
+
+                  For SMMUv2 implementations, there must be exactly one
+                  interrupt per context bank. In the case of a single,
+                  combined interrupt, it must be listed multiple times.
+
+- mmu-masters   : A list of phandles to device nodes representing bus
+                  masters for which the SMMU can provide a translation
+                  and their corresponding StreamIDs (see example below).
+                  Each device node linked from this list must have a
+                  "#stream-id-cells" property, indicating the number of
+                  StreamIDs associated with it.
+
+** System MMU optional properties:
+
+- smmu-parent   : When multiple SMMUs are chained together, this
+                  property can be used to provide a phandle to the
+                  parent SMMU (that is the next SMMU on the path going
+                  from the mmu-masters towards memory) node for this
+                  SMMU.
+
+Example:
+
+        smmu {
+                compatible = "arm,smmu-v1";
+                reg = <0xba5e0000 0x10000>;
+                #global-interrupts = <2>;
+                interrupts = <0 32 4>,
+                             <0 33 4>,
+                             <0 34 4>, /* This is the first context interrupt */
+                             <0 35 4>,
+                             <0 36 4>,
+                             <0 37 4>;
+
+                /*
+                 * Two DMA controllers, the first with two StreamIDs (0xd01d
+                 * and 0xd01e) and the second with only one (0xd11c).
+                 */
+                mmu-masters = <&dma0 0xd01d 0xd01e>,
+                              <&dma1 0xd11c>;
+        };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/leds/leds-lp55xx.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/leds/leds-lp55xx.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/leds/leds-lp55xx.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/leds/leds-lp55xx.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,147 @@
+Binding for TI/National Semiconductor LP55xx Led Drivers
+
+Required properties:
+- compatible: "national,lp5521" or "national,lp5523" or "ti,lp5562"
+- reg: I2C slave address
+- clock-mode: Input clock mode, (0: automode, 1: internal, 2: external)
+
+Each child has own specific current settings
+- led-cur: Current setting at each led channel (mA x10, 0 if led is not connected)
+- max-cur: Maximun current at each led channel.
+
+Optional properties:
+- label: Used for naming LEDs
+
+Alternatively, each child can have specific channel name
+- chan-name: Name of each channel name
+
+example 1) LP5521
+3 LED channels, external clock used. Channel names are 'lp5521_pri:channel0',
+'lp5521_pri:channel1' and 'lp5521_pri:channel2'
+
+lp5521@32 {
+	compatible = "national,lp5521";
+	reg = <0x32>;
+	label = "lp5521_pri";
+	clock-mode = /bits/ 8 <2>;
+
+	chan0 {
+		led-cur = /bits/ 8 <0x2f>;
+		max-cur = /bits/ 8 <0x5f>;
+	};
+
+	chan1 {
+		led-cur = /bits/ 8 <0x2f>;
+		max-cur = /bits/ 8 <0x5f>;
+	};
+
+	chan2 {
+		led-cur = /bits/ 8 <0x2f>;
+		max-cur = /bits/ 8 <0x5f>;
+	};
+};
+
+example 2) LP5523
+9 LED channels with specific name. Internal clock used.
+The I2C slave address is configurable with ASEL1 and ASEL0 pins.
+Available addresses are 32/33/34/35h.
+
+ASEL1    ASEL0    Address
+-------------------------
+ GND      GND       32h
+ GND      VEN       33h
+ VEN      GND       34h
+ VEN      VEN       35h
+
+lp5523@32 {
+	compatible = "national,lp5523";
+	reg = <0x32>;
+	clock-mode = /bits/ 8 <1>;
+
+	chan0 {
+		chan-name = "d1";
+		led-cur = /bits/ 8 <0x14>;
+		max-cur = /bits/ 8 <0x20>;
+	};
+
+	chan1 {
+		chan-name = "d2";
+		led-cur = /bits/ 8 <0x14>;
+		max-cur = /bits/ 8 <0x20>;
+	};
+
+	chan2 {
+		chan-name = "d3";
+		led-cur = /bits/ 8 <0x14>;
+		max-cur = /bits/ 8 <0x20>;
+	};
+
+	chan3 {
+		chan-name = "d4";
+		led-cur = /bits/ 8 <0x14>;
+		max-cur = /bits/ 8 <0x20>;
+	};
+
+	chan4 {
+		chan-name = "d5";
+		led-cur = /bits/ 8 <0x14>;
+		max-cur = /bits/ 8 <0x20>;
+	};
+
+	chan5 {
+		chan-name = "d6";
+		led-cur = /bits/ 8 <0x14>;
+		max-cur = /bits/ 8 <0x20>;
+	};
+
+	chan6 {
+		chan-name = "d7";
+		led-cur = /bits/ 8 <0x14>;
+		max-cur = /bits/ 8 <0x20>;
+	};
+
+	chan7 {
+		chan-name = "d8";
+		led-cur = /bits/ 8 <0x14>;
+		max-cur = /bits/ 8 <0x20>;
+	};
+
+	chan8 {
+		chan-name = "d9";
+		led-cur = /bits/ 8 <0x14>;
+		max-cur = /bits/ 8 <0x20>;
+	};
+};
+
+example 3) LP5562
+4 channels are defined.
+
+lp5562@30 {
+	compatible = "ti,lp5562";
+	reg = <0x30>;
+	clock-mode = /bits/8 <2>;
+
+	chan0 {
+		chan-name = "R";
+		led-cur = /bits/ 8 <0x20>;
+		max-cur = /bits/ 8 <0x60>;
+	};
+
+	chan1 {
+		chan-name = "G";
+		led-cur = /bits/ 8 <0x20>;
+		max-cur = /bits/ 8 <0x60>;
+	};
+
+	chan2 {
+		chan-name = "B";
+		led-cur = /bits/ 8 <0x20>;
+		max-cur = /bits/ 8 <0x60>;
+	};
+
+	chan3 {
+		chan-name = "W";
+		led-cur = /bits/ 8 <0x20>;
+		max-cur = /bits/ 8 <0x60>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt	2013-08-25 20:43:22.000000000 -0400
@@ -2,8 +2,10 @@ Exynos4x12/Exynos5 SoC series camera hos
 
 Required properties:
 
-- compatible	: should be "samsung,exynos4212-fimc-lite" for Exynos4212 and
-		  Exynos4412 SoCs;
+- compatible	: should be one of:
+		  "samsung,exynos4212-fimc-lite" for Exynos4212/4412 SoCs,
+		  "samsung,exynos5250-fimc-lite" for Exynos5250 compatible
+		   devices;
 - reg		: physical base address and size of the device memory mapped
 		  registers;
 - interrupts	: should contain FIMC-LITE interrupt;
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/i2c/mt9p031.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/i2c/mt9p031.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/i2c/mt9p031.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/i2c/mt9p031.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,40 @@
+* Aptina 1/2.5-Inch 5Mp CMOS Digital Image Sensor
+
+The Aptina MT9P031 is a 1/2.5-inch CMOS active pixel digital image sensor with
+an active array size of 2592H x 1944V. It is programmable through a simple
+two-wire serial interface.
+
+Required Properties:
+- compatible: value should be either one among the following
+	(a) "aptina,mt9p031" for mt9p031 sensor
+	(b) "aptina,mt9p031m" for mt9p031m sensor
+
+- input-clock-frequency: Input clock frequency.
+
+- pixel-clock-frequency: Pixel clock frequency.
+
+Optional Properties:
+- reset-gpios: Chip reset GPIO
+
+For further reading on port node refer to
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example:
+
+	i2c0@1c22000 {
+		...
+		...
+		mt9p031@5d {
+			compatible = "aptina,mt9p031";
+			reg = <0x5d>;
+			reset-gpios = <&gpio3 30 0>;
+
+			port {
+				mt9p031_1: endpoint {
+					input-clock-frequency = <6000000>;
+					pixel-clock-frequency = <96000000>;
+				};
+			};
+		};
+		...
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/i2c/tvp514x.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/i2c/tvp514x.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/i2c/tvp514x.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/i2c/tvp514x.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,44 @@
+* Texas Instruments TVP514x video decoder
+
+The TVP5146/TVP5146m2/TVP5147/TVP5147m1 device is high quality, single-chip
+digital video decoder that digitizes and decodes all popular baseband analog
+video formats into digital video component. The tvp514x decoder supports analog-
+to-digital (A/D) conversion of component RGB and YPbPr signals as well as A/D
+conversion and decoding of NTSC, PAL and SECAM composite and S-video into
+component YCbCr.
+
+Required Properties :
+- compatible : value should be either one among the following
+	(a) "ti,tvp5146" for tvp5146 decoder.
+	(b) "ti,tvp5146m2" for tvp5146m2 decoder.
+	(c) "ti,tvp5147" for tvp5147 decoder.
+	(d) "ti,tvp5147m1" for tvp5147m1 decoder.
+
+- hsync-active: HSYNC Polarity configuration for endpoint.
+
+- vsync-active: VSYNC Polarity configuration for endpoint.
+
+- pclk-sample: Clock polarity of the endpoint.
+
+For further reading on port node refer to Documentation/devicetree/bindings/
+media/video-interfaces.txt.
+
+Example:
+
+	i2c0@1c22000 {
+		...
+		...
+		tvp514x@5c {
+			compatible = "ti,tvp5146";
+			reg = <0x5c>;
+
+			port {
+				tvp514x_1: endpoint {
+					hsync-active = <1>;
+					vsync-active = <1>;
+					pclk-sample = <0>;
+				};
+			};
+		};
+		...
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/s5p-mfc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/s5p-mfc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/s5p-mfc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/s5p-mfc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,9 @@ Required properties:
 	  mapped region.
 
   - interrupts : MFC interrupt number to the CPU.
+  - clocks : from common clock binding: handle to mfc clocks.
+  - clock-names : from common clock binding: must contain "sclk_mfc" and "mfc",
+		  corresponding to entries in the clocks property.
 
   - samsung,mfc-r : Base address of the first memory bank used by MFC
 		    for DMA contiguous memory allocation and its size.
@@ -34,6 +37,8 @@ mfc: codec@13400000 {
 	reg = <0x13400000 0x10000>;
 	interrupts = <0 94 0>;
 	samsung,power-domain = <&pd_mfc>;
+	clocks = <&clock 170>, <&clock 273>;
+	clock-names = "sclk_mfc", "mfc";
 };
 
 Board specific DT entry:
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/samsung-fimc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/samsung-fimc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/samsung-fimc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/samsung-fimc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -127,22 +127,22 @@ Example:
 				};
 			};
 		};
-	};
 
-	/* MIPI CSI-2 bus IF sensor */
-	s5c73m3: sensor@0x1a {
-		compatible = "samsung,s5c73m3";
-		reg = <0x1a>;
-		vddio-supply = <...>;
+		/* MIPI CSI-2 bus IF sensor */
+		s5c73m3: sensor@0x1a {
+			compatible = "samsung,s5c73m3";
+			reg = <0x1a>;
+			vddio-supply = <...>;
 
-		clock-frequency = <24000000>;
-		clocks = <...>;
-		clock-names = "mclk";
+			clock-frequency = <24000000>;
+			clocks = <...>;
+			clock-names = "mclk";
 
-		port {
-			s5c73m3_1: endpoint {
-				data-lanes = <1 2 3 4>;
-				remote-endpoint = <&csis0_ep>;
+			port {
+				s5c73m3_1: endpoint {
+					data-lanes = <1 2 3 4>;
+					remote-endpoint = <&csis0_ep>;
+				};
 			};
 		};
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt	2013-08-25 20:43:22.000000000 -0400
@@ -5,8 +5,8 @@ Required properties:
 
 - compatible	  : "samsung,s5pv210-csis" for S5PV210 (S5PC110),
 		    "samsung,exynos4210-csis" for Exynos4210 (S5PC210),
-		    "samsung,exynos4212-csis" for Exynos4212/Exynos4412
-		    SoC series;
+		    "samsung,exynos4212-csis" for Exynos4212/Exynos4412,
+		    "samsung,exynos5250-csis" for Exynos5250;
 - reg		  : offset and length of the register set for the device;
 - interrupts      : should contain MIPI CSIS interrupt; the format of the
 		    interrupt specifier depends on the interrupt controller;
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,18 @@
+Bindings, specific for the sh_mobile_ceu_camera.c driver:
+ - compatible: Should be "renesas,sh-mobile-ceu"
+ - reg: register base and size
+ - interrupts: the interrupt number
+ - interrupt-parent: the interrupt controller
+ - renesas,max-width: maximum image width, supported on this SoC
+ - renesas,max-height: maximum image height, supported on this SoC
+
+Example:
+
+ceu0: ceu@0xfe910000 {
+	compatible = "renesas,sh-mobile-ceu";
+	reg = <0xfe910000 0xa0>;
+	interrupt-parent = <&intcs>;
+	interrupts = <0x880>;
+	renesas,max-width = <8188>;
+	renesas,max-height = <8188>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,156 @@
+Device tree bindings for MVEBU Device Bus controllers
+
+The Device Bus controller available in some Marvell's SoC allows to control
+different types of standard memory and I/O devices such as NOR, NAND, and FPGA.
+The actual devices are instantiated from the child nodes of a Device Bus node.
+
+Required properties:
+
+ - compatible:          Currently only Armada 370/XP SoC are supported,
+                        with this compatible string:
+
+                        marvell,mvebu-devbus
+
+ - reg:                 A resource specifier for the register space.
+                        This is the base address of a chip select within
+			the controller's register space.
+                        (see the example below)
+
+ - #address-cells:      Must be set to 1
+ - #size-cells:         Must be set to 1
+ - ranges:              Must be set up to reflect the memory layout with four
+                        integer values for each chip-select line in use:
+                        0 <physical address of mapping> <size>
+
+Mandatory timing properties for child nodes:
+
+Read parameters:
+
+ - devbus,turn-off-ps:  Defines the time during which the controller does not
+                        drive the AD bus after the completion of a device read.
+                        This prevents contentions on the Device Bus after a read
+                        cycle from a slow device.
+
+ - devbus,bus-width:    Defines the bus width (e.g. <16>)
+
+ - devbus,badr-skew-ps: Defines the time delay from from A[2:0] toggle,
+                        to read data sample. This parameter is useful for
+                        synchronous pipelined devices, where the address
+                        precedes the read data by one or two cycles.
+
+ - devbus,acc-first-ps: Defines the time delay from the negation of
+                        ALE[0] to the cycle that the first read data is sampled
+                        by the controller.
+
+ - devbus,acc-next-ps:  Defines the time delay between the cycle that
+                        samples data N and the cycle that samples data N+1
+                        (in burst accesses).
+
+ - devbus,rd-setup-ps:  Defines the time delay between DEV_CSn assertion to
+			DEV_OEn assertion. If set to 0 (default),
+                        DEV_OEn and DEV_CSn are asserted at the same cycle.
+                        This parameter has no affect on <acc-first-ps> parameter
+                        (no affect on first data sample). Set <rd-setup-ps>
+                        to a value smaller than <acc-first-ps>.
+
+ - devbus,rd-hold-ps:   Defines the time between the last data sample to the
+			de-assertion of DEV_CSn. If set to 0 (default),
+			DEV_OEn and DEV_CSn are de-asserted at the same cycle
+			(the cycle of the last data sample).
+                        This parameter has no affect on DEV_OEn de-assertion.
+                        DEV_OEn is always de-asserted the next cycle after
+                        last data sampled. Also this parameter has no
+                        affect on <turn-off-ps> parameter.
+                        Set <rd-hold-ps> to a value smaller than <turn-off-ps>.
+
+Write parameters:
+
+ - devbus,ale-wr-ps:    Defines the time delay from the ALE[0] negation cycle
+			to the DEV_WEn assertion.
+
+ - devbus,wr-low-ps:    Defines the time during which DEV_WEn is active.
+                        A[2:0] and Data are kept valid as long as DEV_WEn
+                        is active. This parameter defines the setup time of
+                        address and data to DEV_WEn rise.
+
+ - devbus,wr-high-ps:   Defines the time during which DEV_WEn is kept
+                        inactive (high) between data beats of a burst write.
+                        DEV_A[2:0] and Data are kept valid (do not toggle) for
+                        <wr-high-ps> - <tick> ps.
+			This parameter defines the hold time of address and
+			data after DEV_WEn rise.
+
+ - devbus,sync-enable: Synchronous device enable.
+                       1: True
+                       0: False
+
+An example for an Armada XP GP board, with a 16 MiB NOR device as child
+is showed below. Note that the Device Bus driver is in charge of allocating
+the mbus address decoding window for each of its child devices.
+The window is created using the chip select specified in the child
+device node together with the base address and size specified in the ranges
+property. For instance, in the example below the allocated decoding window
+will start at base address 0xf0000000, with a size 0x1000000 (16 MiB)
+for chip select 0 (a.k.a DEV_BOOTCS).
+
+This address window handling is done in this mvebu-devbus only as a temporary
+solution. It will be removed when the support for mbus device tree binding is
+added.
+
+The reg property implicitly specifies the chip select as this:
+
+  0x10400: DEV_BOOTCS
+  0x10408: DEV_CS0
+  0x10410: DEV_CS1
+  0x10418: DEV_CS2
+  0x10420: DEV_CS3
+
+Example:
+
+	devbus-bootcs@d0010400 {
+		status = "okay";
+		ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf0000000, size 0x1000000 */
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* Device Bus parameters are required */
+
+		/* Read parameters */
+		devbus,bus-width    = <8>;
+		devbus,turn-off-ps  = <60000>;
+		devbus,badr-skew-ps = <0>;
+		devbus,acc-first-ps = <124000>;
+		devbus,acc-next-ps  = <248000>;
+		devbus,rd-setup-ps  = <0>;
+		devbus,rd-hold-ps   = <0>;
+
+		/* Write parameters */
+		devbus,sync-enable = <0>;
+		devbus,wr-high-ps  = <60000>;
+		devbus,wr-low-ps   = <60000>;
+		devbus,ale-wr-ps   = <60000>;
+
+		flash@0 {
+			compatible = "cfi-flash";
+
+			/* 16 MiB */
+			reg = <0 0x1000000>;
+			bank-width = <2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			/*
+			 * We split the 16 MiB in two partitions,
+			 * just as an example.
+			 */
+			partition@0 {
+				label = "First";
+				reg = <0 0x800000>;
+			};
+
+			partition@800000 {
+				label = "Second";
+				reg = <0x800000 0x800000>;
+			};
+		};
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/metag/meta.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/metag/meta.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/metag/meta.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/metag/meta.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,30 @@
+* Meta Processor Binding
+
+This binding specifies what properties must be available in the device tree
+representation of a Meta Processor Core, which is the root node in the tree.
+
+Required properties:
+
+    - compatible: Specifies the compatibility list for the Meta processor.
+      The type shall be <string> and the value shall include "img,meta".
+
+Optional properties:
+
+    - clocks: Clock consumer specifiers as described in
+      Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+    - clock-names: Clock consumer names as described in
+      Documentation/devicetree/bindings/clock/clock-bindings.txt.
+
+Clocks are identified by name. Valid clocks are:
+
+    - "core": The Meta core clock from which the Meta timers are derived.
+
+* Examples
+
+/ {
+	compatible = "toumaz,tz1090", "img,meta";
+
+	clocks = <&meta_core_clk>;
+	clock-names = "core";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/ab8500.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/ab8500.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/ab8500.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/ab8500.txt	2013-08-25 20:43:22.000000000 -0400
@@ -120,7 +120,7 @@ ab8500 {
                                   "USB_LINK_STATUS",
                                   "USB_ADP_PROBE_PLUG",
                                   "USB_ADP_PROBE_UNPLUG";
-                vddulpivio18-supply = <&ab8500_ldo_initcore_reg>;
+                vddulpivio18-supply = <&ab8500_ldo_intcore_reg>;
                 v-ape-supply = <&db8500_vape_reg>;
                 musb_1v8-supply = <&db8500_vsmps2_reg>;
         };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/arizona.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/arizona.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/arizona.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/arizona.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,62 @@
+Wolfson Arizona class audio SoCs
+
+These devices are audio SoCs with extensive digital capabilites and a range
+of analogue I/O.
+
+Required properties:
+
+  - compatible : one of the following chip-specific strings:
+	"wlf,wm5102"
+	"wlf,wm5110"
+  - reg : I2C slave address when connected using I2C, chip select number when
+    using SPI.
+
+  - interrupts : The interrupt line the /IRQ signal for the device is
+    connected to.
+  - interrupt-controller : Arizona class devices contain interrupt controllers
+    and may provide interrupt services to other devices.
+  - interrupt-parent : The parent interrupt controller.
+  - #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
+    The first cell is the IRQ number.
+    The second cell is the flags, encoded as the trigger masks from
+    Documentation/devicetree/bindings/interrupts.txt
+
+  - gpio-controller : Indicates this device is a GPIO controller.
+  - #gpio-cells : Must be 2. The first cell is the pin number and the
+    second cell is used to specify optional parameters (currently unused).
+
+  - AVDD1-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
+    SPKVDDL-supply, SPKVDDR-supply : power supplies for the device, as covered
+    in Documentation/devicetree/bindings/regulator/regulator.txt
+
+Optional properties:
+
+  - wlf,reset : GPIO specifier for the GPIO controlling /RESET
+  - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
+
+  - wlf,gpio-defaults : A list of GPIO configuration register values. If
+    absent, no configuration of these registers is performed. If any
+    entry has a value that is out of range for a 16 bit register then
+    the chip default will be used.  If present exactly five values must
+    be specified.
+
+Example:
+
+codec: wm5102@1a {
+	compatible = "wlf,wm5102";
+	reg = <0x1a>;
+	interrupts = <347>;
+	#interrupt-cells = <2>;
+        interrupt-parent = <&gic>;
+
+	gpio-controller;
+	#gpio-cells = <2>;
+
+	wlf,gpio-defaults = <
+		0x00000000, /* AIF1TXLRCLK */
+		0xffffffff,
+		0xffffffff,
+		0xffffffff,
+		0xffffffff,
+	>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/max77693.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/max77693.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/max77693.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/max77693.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,55 @@
+Maxim MAX77693 multi-function device
+
+MAX77693 is a Multifunction device with the following submodules:
+- PMIC,
+- CHARGER,
+- LED,
+- MUIC,
+- HAPTIC
+
+It is interfaced to host controller using i2c.
+This document describes the bindings for the mfd device.
+
+Required properties:
+- compatible : Must be "maxim,max77693".
+- reg : Specifies the i2c slave address of PMIC block.
+- interrupts : This i2c device has an IRQ line connected to the main SoC.
+- interrupt-parent :  The parent interrupt controller.
+
+Optional properties:
+- regulators : The regulators of max77693 have to be instantiated under subnod
+  named "regulators" using the following format.
+
+	regulators {
+		regualtor-compatible = ESAFEOUT1/ESAFEOUT2/CHARGER
+		standard regulator constratints[*].
+	};
+
+	[*] refer Documentation/devicetree/bindings/regulator/regulator.txt
+
+Example:
+	max77693@66 {
+		compatible = "maxim,max77693";
+		reg = <0x66>;
+		interrupt-parent = <&gpx1>;
+		interrupts = <5 2>;
+
+		regulators {
+			esafeout@1 {
+				regulator-compatible = "ESAFEOUT1";
+				regulator-name = "ESAFEOUT1";
+				regulator-boot-on;
+			};
+			esafeout@2 {
+				regulator-compatible = "ESAFEOUT2";
+				regulator-name = "ESAFEOUT2";
+				};
+			charger@0 {
+				regulator-compatible = "CHARGER";
+				regulator-name = "CHARGER";
+				regulator-min-microamp = <60000>;
+				regulator-max-microamp = <2580000>;
+					regulator-boot-on;
+			};
+		};
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/max8998.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/max8998.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/max8998.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/max8998.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,119 @@
+* Maxim MAX8998, National/TI LP3974 multi-function device
+
+The Maxim MAX8998 is a multi-function device which includes voltage/current
+regulators, real time clock, battery charging controller and several
+other sub-blocks. It is interfaced using an I2C interface. Each sub-block
+is addressed by the host system using different i2c slave address.
+
+PMIC sub-block
+--------------
+
+The PMIC sub-block contains a number of voltage and current regulators,
+with controllable parameters and dynamic voltage scaling capability.
+In addition, it includes a real time clock and battery charging controller
+as well. It is accessible at I2C address 0x66.
+
+Required properties:
+- compatible: Should be one of the following:
+    - "maxim,max8998" for Maxim MAX8998
+    - "national,lp3974" or "ti,lp3974" for National/TI LP3974.
+- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
+
+Optional properties:
+- interrupt-parent: Specifies the phandle of the interrupt controller to which
+  the interrupts from MAX8998 are routed to.
+- interrupts: Interrupt specifiers for two interrupt sources.
+  - First interrupt specifier is for main interrupt.
+  - Second interrupt specifier is for power-on/-off interrupt.
+- max8998,pmic-buck1-dvs-gpios: GPIO specifiers for two host gpios used
+  for buck 1 dvs. The format of the gpio specifier depends on the gpio
+  controller.
+- max8998,pmic-buck2-dvs-gpio: GPIO specifier for host gpio used
+  for buck 2 dvs. The format of the gpio specifier depends on the gpio
+  controller.
+- max8998,pmic-buck1-default-dvs-idx: Default voltage setting selected from
+  the possible 4 options selectable by the dvs gpios. The value of this
+  property should be 0, 1, 2 or 3. If not specified or out of range,
+  a default value of 0 is taken.
+- max8998,pmic-buck2-default-dvs-idx: Default voltage setting selected from
+  the possible 2 options selectable by the dvs gpios. The value of this
+  property should be 0 or 1. If not specified or out of range, a default
+  value of 0 is taken.
+- max8998,pmic-buck-voltage-lock: If present, disallows changing of
+  preprogrammed buck dvfs voltages.
+
+Additional properties required if max8998,pmic-buck1-dvs-gpios is defined:
+- max8998,pmic-buck1-dvs-voltage: An array of 4 voltage values in microvolts
+  for buck1 regulator that can be selected using dvs gpio.
+
+Additional properties required if max8998,pmic-buck2-dvs-gpio is defined:
+- max8998,pmic-buck2-dvs-voltage: An array of 2 voltage values in microvolts
+  for buck2 regulator that can be selected using dvs gpio.
+
+Regulators: All the regulators of MAX8998 to be instantiated shall be
+listed in a child node named 'regulators'. Each regulator is represented
+by a child node of the 'regulators' node.
+
+	regulator-name {
+		/* standard regulator bindings here */
+	};
+
+Following regulators of the MAX8998 PMIC block are supported. Note that
+the 'n' in regulator name, as in LDOn or BUCKn, represents the LDO or BUCK
+number as described in MAX8998 datasheet.
+
+	- LDOn
+		  - valid values for n are 2 to 17
+		  - Example: LDO2, LDO10, LDO17
+	- BUCKn
+		  - valid values for n are 1 to 4.
+		  - Example: BUCK1, BUCK2, BUCK3, BUCK4
+
+	- ENVICHG: Battery Charging Current Monitor Output. This is a fixed
+		   voltage type regulator
+
+	- ESAFEOUT1: (ldo19)
+	- ESAFEOUT2: (ld020)
+
+Standard regulator bindings are used inside regulator subnodes. Check
+  Documentation/devicetree/bindings/regulator/regulator.txt
+for more details.
+
+Example:
+
+	pmic@66 {
+		compatible = "maxim,max8998-pmic";
+		reg = <0x66>;
+		interrupt-parent = <&wakeup_eint>;
+		interrupts = <4 0>, <3 0>;
+
+		/* Buck 1 DVS settings */
+		max8998,pmic-buck1-default-dvs-idx = <0>;
+		max8998,pmic-buck1-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */
+					       <&gpx0 1 1 0 0>; /* SET2 */
+		max8998,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
+						 <1000000>, <950000>;
+
+		/* Buck 2 DVS settings */
+		max8998,pmic-buck2-default-dvs-idx = <0>;
+		max8998,pmic-buck2-dvs-gpio = <&gpx0 0 3 0 0>; /* SET3 */
+		max8998,pmic-buck2-dvs-voltage = <1350000>, <1300000>;
+
+		/* Regulators to instantiate */
+		regulators {
+			ldo2_reg: LDO2 {
+				regulator-name = "VDD_ALIVE_1.1V";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			buck1_reg: BUCK1 {
+				regulator-name = "VDD_ARM_1.2V";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/palmas.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/palmas.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/palmas.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/palmas.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,49 @@
+* palmas device tree bindings
+
+The TI palmas family current members :-
+twl6035 (palmas)
+twl6037 (palmas)
+tps65913 (palmas)
+tps65914 (palmas)
+
+Required properties:
+- compatible : Should be from the list
+  ti,twl6035
+  ti,twl6036
+  ti,twl6037
+  ti,tps65913
+  ti,tps65914
+  ti,tps80036
+and also the generic series names
+  ti,palmas
+- interrupt-controller : palmas has its own internal IRQs
+- #interrupt-cells : should be set to 2 for IRQ number and flags
+  The first cell is the IRQ number.
+  The second cell is the flags, encoded as the trigger masks from
+  Documentation/devicetree/bindings/interrupts.txt
+- interrupt-parent : The parent interrupt controller.
+
+Optional properties:
+  ti,mux-padX : set the pad register X (1-2) to the correct muxing for the
+		hardware, if not set will use muxing in OTP.
+
+Example:
+
+palmas {
+	compatible = "ti,twl6035", "ti,palmas";
+	reg = <0x48>
+	interrupt-parent = <&intc>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+
+	ti,mux-pad1 = <0>;
+	ti,mux-pad2 = <0>;
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	pmic {
+		compatible = "ti,twl6035-pmic", "ti,palmas-pmic";
+		....
+	};
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/twl4030-power.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/twl4030-power.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mfd/twl4030-power.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mfd/twl4030-power.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,28 @@
+Texas Instruments TWL family (twl4030) reset and power management module
+
+The power management module inside the TWL family provides several facilities
+to control the power resources, including power scripts. For now, the
+binding only supports the complete shutdown of the system after poweroff.
+
+Required properties:
+- compatible : must be "ti,twl4030-power"
+
+Optional properties:
+- ti,use_poweroff: With this flag, the chip will initiates an ACTIVE-to-OFF or
+		   SLEEP-to-OFF transition when the system poweroffs.
+
+Example:
+&i2c1 {
+	clock-frequency = <2600000>;
+
+	twl: twl@48 {
+		reg = <0x48>;
+		interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+		interrupt-parent = <&intc>;
+
+		twl_power: power {
+			compatible = "ti,twl4030-power";
+			ti,use_poweroff;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mmc/bcm,kona-sdhci.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,16 @@
+Broadcom BCM281xx SDHCI
+
+This file documents differences between the core properties in mmc.txt
+and the properties present in the bcm281xx SDHCI
+
+Required properties:
+- compatible : Should be "bcm,kona-sdhci"
+
+Example:
+
+sdio2: sdio@0x3f1a0000 {
+	compatible = "bcm,kona-sdhci";
+	reg = <0x3f1a0000 0x10000>;
+	interrupts = <0x0 74 0x4>;
+};
+
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mmc/mmc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mmc/mmc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mmc/mmc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mmc/mmc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,7 @@ Optional properties:
 - cap-mmc-highspeed: MMC high-speed timing is supported
 - cap-power-off-card: powering off the card is safe
 - cap-sdio-irq: enable SDIO IRQ signalling on this interface
+- full-pwr-cycle: full power cycle of the card is supported
 
 *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
 polarity properties, we have to fix the meaning of the "normal" and "inverted"
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,23 @@
+* Rockchip specific extensions to the Synopsis Designware Mobile
+  Storage Host Controller
+
+The Synopsis designware mobile storage host controller is used to interface
+a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
+differences between the core Synopsis dw mshc controller properties described
+by synopsis-dw-mshc.txt and the properties used by the Rockchip specific
+extensions to the Synopsis Designware Mobile Storage Host Controller.
+
+Required Properties:
+
+* compatible: should be
+	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following
+
+Example:
+
+	rkdwmmc0@12200000 {
+		compatible = "rockchip,rk2928-dw-mshc";
+		reg = <0x12200000 0x1000>;
+		interrupts = <0 75 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,19 @@ Required Properties:
 
 Optional properties:
 
+* clocks: from common clock binding: handle to biu and ciu clocks for the
+  bus interface unit clock and the card interface unit clock.
+
+* clock-names: from common clock binding: Shall be "biu" and "ciu".
+  If the biu clock is missing we'll simply skip enabling it.  If the
+  ciu clock is missing we'll just assume that the clock is running at
+  clock-frequency.  It is an error to omit both the ciu clock and the
+  clock-frequency.
+
+* clock-frequency: should be the frequency (in Hz) of the ciu clock.  If this
+  is specified and the ciu clock is specified then we'll try to set the ciu
+  clock to this at probe time.
+
 * num-slots: specifies the number of slots supported by the controller.
   The number of physical slots actually used could be equal or less than the
   value specified by num-slots. If this property is not specified, the value
@@ -51,10 +64,13 @@ Optional properties:
 * card-detect-delay: Delay in milli-seconds before detecting card after card
   insert event. The default value is 0.
 
-* supports-highspeed: Enables support for high speed cards (upto 50MHz)
+* supports-highspeed: Enables support for high speed cards (up to 50MHz)
 
 * broken-cd: as documented in mmc core bindings.
 
+* vmmc-supply: The phandle to the regulator to use for vmmc.  If this is
+  specified we'll defer probe until we can find this regulator.
+
 Aliases:
 
 - All the MSHC controller nodes should be represented in the aliases node using
@@ -67,6 +83,8 @@ board specific portions as listed below.
 
 	dwmmc0@12200000 {
 		compatible = "snps,dw-mshc";
+		clocks = <&clock 351>, <&clock 132>;
+		clock-names = "biu", "ciu";
 		reg = <0x12200000 0x1000>;
 		interrupts = <0 75 0>;
 		#address-cells = <1>;
@@ -74,11 +92,13 @@ board specific portions as listed below.
 	};
 
 	dwmmc0@12200000 {
+		clock-frequency = <400000000>;
 		num-slots = <1>;
 		supports-highspeed;
 		broken-cd;
 		fifo-depth = <0x80>;
 		card-detect-delay = <200>;
+		vmmc-supply = <&buck8>;
 
 		slot@0 {
 			reg = <0>;
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/mtd/gpmc-nand.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/mtd/gpmc-nand.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/mtd/gpmc-nand.txt	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,13 @@ Optional properties:
 		"bch4"		4-bit BCH ecc code
 		"bch8"		8-bit BCH ecc code
 
+ - ti,nand-xfer-type:		A string setting the data transfer type. One of:
+
+		"prefetch-polled"	Prefetch polled mode (default)
+		"polled"		Polled mode, without prefetch
+		"prefetch-dma"		Prefetch enabled sDMA mode
+		"prefetch-irq"		Prefetch enabled irq mode
+
  - elm_id:	Specifies elm device node. This is required to support BCH
  		error correction using ELM module.
 
@@ -55,6 +62,7 @@ Example for an AM33xx board:
 			reg = <0 0 0>; /* CS0, offset 0 */
 			nand-bus-width = <16>;
 			ti,nand-ecc-opt = "bch8";
+			ti,nand-xfer-type = "polled";
 
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,22 @@
+* Allwinner EMAC ethernet controller
+
+Required properties:
+- compatible: should be "allwinner,sun4i-emac".
+- reg: address and length of the register set for the device.
+- interrupts: interrupt for the device
+- phy: A phandle to a phy node defining the PHY address (as the reg
+  property, a single integer).
+- clocks: A phandle to the reference clock for this device
+
+Optional properties:
+- (local-)mac-address: mac address to be used by this driver
+
+Example:
+
+emac: ethernet@01c0b000 {
+       compatible = "allwinner,sun4i-emac";
+       reg = <0x01c0b000 0x1000>;
+       interrupts = <55>;
+       clocks = <&ahb_gates 17>;
+       phy = <&phy0>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,26 @@
+* Allwinner A10 MDIO Ethernet Controller interface
+
+Required properties:
+- compatible: should be "allwinner,sun4i-mdio".
+- reg: address and length of the register set for the device.
+
+Optional properties:
+- phy-supply: phandle to a regulator if the PHY needs one
+
+Example at the SoC level:
+mdio@01c0b080 {
+	compatible = "allwinner,sun4i-mdio";
+	reg = <0x01c0b080 0x14>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+};
+
+And at the board level:
+
+mdio@01c0b080 {
+	phy-supply = <&reg_emac_3v3>;
+
+	phy0: ethernet-phy@0 {
+		reg = <0>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/arc_emac.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/arc_emac.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/arc_emac.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/arc_emac.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,38 @@
+* Synopsys ARC EMAC 10/100 Ethernet driver (EMAC)
+
+Required properties:
+- compatible: Should be "snps,arc-emac"
+- reg: Address and length of the register set for the device
+- interrupts: Should contain the EMAC interrupts
+- clock-frequency: CPU frequency. It is needed to calculate and set polling
+period of EMAC.
+- max-speed: Maximum supported data-rate in Mbit/s. In some HW configurations
+bandwidth of external memory controller might be a limiting factor. That's why
+it's required to specify which data-rate is supported on current SoC or FPGA.
+For example if only 10 Mbit/s is supported (10BASE-T) set "10". If 100 Mbit/s is
+supported (100BASE-TX) set "100".
+- phy: PHY device attached to the EMAC via MDIO bus
+
+Child nodes of the driver are the individual PHY devices connected to the
+MDIO bus. They must have a "reg" property given the PHY address on the MDIO bus.
+
+Optional properties:
+- mac-address: 6 bytes, mac address
+
+Examples:
+
+	ethernet@c0fc2000 {
+		compatible = "snps,arc-emac";
+		reg = <0xc0fc2000 0x3c>;
+		interrupts = <6>;
+		mac-address = [ 00 11 22 33 44 55 ];
+		clock-frequency = <80000000>;
+		max-speed = <100>;
+		phy = <&phy0>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+		phy0: ethernet-phy@0 {
+			reg = <1>;
+		};
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,8 @@ Optional properties:
 
 - clock-frequency : The oscillator frequency driving the flexcan device
 
+- xceiver-supply: Regulator that powers the CAN transceiver
+
 Example:
 
 	can@1c000 {
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/cpsw.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/cpsw.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/cpsw.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/cpsw.txt	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,8 @@ Optional properties:
 Slave Properties:
 Required properties:
 - phy_id		: Specifies slave phy id
+- phy-mode		: The interface between the SoC and the PHY (a string
+			  that of_get_phy_mode() can understand)
 - mac-address		: Specifies slave MAC address
 
 Optional properties:
@@ -58,11 +60,13 @@ Examples:
 		cpts_clock_shift = <29>;
 		cpsw_emac0: slave@0 {
 			phy_id = <&davinci_mdio>, <0>;
+			phy-mode = "rgmii-txid";
 			/* Filled in by U-Boot */
 			mac-address = [ 00 00 00 00 00 00 ];
 		};
 		cpsw_emac1: slave@1 {
 			phy_id = <&davinci_mdio>, <1>;
+			phy-mode = "rgmii-txid";
 			/* Filled in by U-Boot */
 			mac-address = [ 00 00 00 00 00 00 ];
 		};
@@ -84,11 +88,13 @@ Examples:
 		cpts_clock_shift = <29>;
 		cpsw_emac0: slave@0 {
 			phy_id = <&davinci_mdio>, <0>;
+			phy-mode = "rgmii-txid";
 			/* Filled in by U-Boot */
 			mac-address = [ 00 00 00 00 00 00 ];
 		};
 		cpsw_emac1: slave@1 {
 			phy_id = <&davinci_mdio>, <1>;
+			phy-mode = "rgmii-txid";
 			/* Filled in by U-Boot */
 			mac-address = [ 00 00 00 00 00 00 ];
 		};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/davicom-dm9000.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/davicom-dm9000.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/davicom-dm9000.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/davicom-dm9000.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,26 @@
+Davicom DM9000 Fast Ethernet controller
+
+Required properties:
+- compatible = "davicom,dm9000";
+- reg : physical addresses and sizes of registers, must contain 2 entries:
+    first entry : address register,
+    second entry : data register.
+- interrupt-parent : interrupt controller to which the device is connected
+- interrupts : interrupt specifier specific to interrupt controller
+
+Optional properties:
+- local-mac-address : A bytestring of 6 bytes specifying Ethernet MAC address
+    to use (from firmware or bootloader)
+- davicom,no-eeprom : Configuration EEPROM is not available
+- davicom,ext-phy : Use external PHY
+
+Example:
+
+	ethernet@18000000 {
+		compatible = "davicom,dm9000";
+		reg = <0x18000000 0x2 0x18000004 0x2>;
+		interrupt-parent = <&gpn>;
+		interrupts = <7 4>;
+		local-mac-address = [00 00 de ad be ef];
+		davicom,no-eeprom;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/marvell-orion-net.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/marvell-orion-net.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/marvell-orion-net.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/marvell-orion-net.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,85 @@
+Marvell Orion/Discovery ethernet controller
+=============================================
+
+The Marvell Discovery ethernet controller can be found on Marvell Orion SoCs
+(Kirkwood, Dove, Orion5x, and Discovery Innovation) and as part of Marvell
+Discovery system controller chips (mv64[345]60).
+
+The Discovery ethernet controller is described with two levels of nodes. The
+first level describes the ethernet controller itself and the second level
+describes up to 3 ethernet port nodes within that controller. The reason for
+the multiple levels is that the port registers are interleaved within a single
+set of controller registers. Each port node describes port-specific properties.
+
+Note: The above separation is only true for Discovery system controllers.
+For Orion SoCs we stick to the separation, although there each controller has
+only one port associated. Multiple ports are implemented as multiple single-port
+controllers. As Kirkwood has some issues with proper initialization after reset,
+an extra compatible string is added for it.
+
+* Ethernet controller node
+
+Required controller properties:
+ - #address-cells: shall be 1.
+ - #size-cells: shall be 0.
+ - compatible: shall be one of "marvell,orion-eth", "marvell,kirkwood-eth".
+ - reg: address and length of the controller registers.
+
+Optional controller properties:
+ - clocks: phandle reference to the controller clock.
+ - marvell,tx-checksum-limit: max tx packet size for hardware checksum.
+
+* Ethernet port node
+
+Required port properties:
+ - device_type: shall be "network".
+ - compatible: shall be one of "marvell,orion-eth-port",
+      "marvell,kirkwood-eth-port".
+ - reg: port number relative to ethernet controller, shall be 0, 1, or 2.
+ - interrupts: port interrupt.
+ - local-mac-address: 6 bytes MAC address.
+
+Optional port properties:
+ - marvell,tx-queue-size: size of the transmit ring buffer.
+ - marvell,tx-sram-addr: address of transmit descriptor buffer located in SRAM.
+ - marvell,tx-sram-size: size of transmit descriptor buffer located in SRAM.
+ - marvell,rx-queue-size: size of the receive ring buffer.
+ - marvell,rx-sram-addr: address of receive descriptor buffer located in SRAM.
+ - marvell,rx-sram-size: size of receive descriptor buffer located in SRAM.
+
+and
+
+ - phy-handle: phandle reference to ethernet PHY.
+
+or
+
+ - speed: port speed if no PHY connected.
+ - duplex: port mode if no PHY connected.
+
+* Node example:
+
+mdio-bus {
+	...
+	ethphy: ethernet-phy@8 {
+		device_type = "ethernet-phy";
+		...
+	};
+};
+
+eth: ethernet-controller@72000 {
+	compatible = "marvell,orion-eth";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0x72000 0x2000>;
+	clocks = <&gate_clk 2>;
+	marvell,tx-checksum-limit = <1600>;
+
+	ethernet@0 {
+		device_type = "network";
+		compatible = "marvell,orion-eth-port";
+		reg = <0>;
+		interrupts = <29>;
+		phy-handle = <&ethphy>;
+		local-mac-address = [00 00 00 00 00 00];
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/micrel-ks8851.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/micrel-ks8851.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/micrel-ks8851.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/micrel-ks8851.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,9 @@
+Micrel KS8851 Ethernet mac
+
+Required properties:
+- compatible = "micrel,ks8851-ml" of parallel interface
+- reg : 2 physical address and size of registers for data and command
+- interrupts : interrupt connection
+
+Optional properties:
+- local-mac-address : Ethernet mac address to use
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/stmmac.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/stmmac.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/stmmac.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/stmmac.txt	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,16 @@ Required properties:
   property
 - phy-mode: String, operation mode of the PHY interface.
   Supported values are: "mii", "rmii", "gmii", "rgmii".
+- snps,phy-addr		phy address to connect to.
+- snps,reset-gpio 	gpio number for phy reset.
+- snps,reset-active-low boolean flag to indicate if phy reset is active low.
+- snps,reset-delays-us  is triplet of delays
+	The 1st cell is reset pre-delay in micro seconds.
+	The 2nd cell is reset pulse in micro seconds.
+	The 3rd cell is reset post-delay in micro seconds.
+- snps,pbl		Programmable Burst Length
+- snps,fixed-burst	Program the DMA to use the fixed burst mode
+- snps,mixed-burst	Program the DMA to use the mixed burst mode
 
 Optional properties:
 - mac-address: 6 bytes, mac address
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/via-velocity.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/via-velocity.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/net/via-velocity.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/net/via-velocity.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,20 @@
+* VIA Velocity 10/100/1000 Network Controller
+
+Required properties:
+- compatible : Should be "via,velocity-vt6110"
+- reg : Address and length of the io space
+- interrupts : Should contain the controller interrupt line
+
+Optional properties:
+- no-eeprom : PCI network cards use an external EEPROM to store data. Embedded
+	devices quite often set this data in uboot and do not provide an eeprom.
+	Specify this option if you have no external eeprom.
+
+Examples:
+
+eth0@d8004000 {
+	compatible = "via,velocity-vt6110";
+	reg = <0xd8004000 0x400>;
+	interrupts = <10>;
+	no-eeprom;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pci/designware-pcie.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pci/designware-pcie.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pci/designware-pcie.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pci/designware-pcie.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,73 @@
+* Synopsis Designware PCIe interface
+
+Required properties:
+- compatible: should contain "snps,dw-pcie" to identify the
+	core, plus an identifier for the specific instance, such
+	as "samsung,exynos5440-pcie".
+- reg: base addresses and lengths of the pcie controller,
+	the phy controller, additional register for the phy controller.
+- interrupts: interrupt values for level interrupt,
+	pulse interrupt, special interrupt.
+- clocks: from common clock binding: handle to pci clock.
+- clock-names: from common clock binding: should be "pcie" and "pcie_bus".
+- #address-cells: set to <3>
+- #size-cells: set to <2>
+- device_type: set to "pci"
+- ranges: ranges for the PCI memory and I/O regions
+- #interrupt-cells: set to <1>
+- interrupt-map-mask and interrupt-map: standard PCI properties
+	to define the mapping of the PCIe interface to interrupt
+	numbers.
+- reset-gpio: gpio pin number of power good signal
+
+Example:
+
+SoC specific DT Entry:
+
+	pcie@290000 {
+		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+		reg = <0x290000 0x1000
+			0x270000 0x1000
+			0x271000 0x40>;
+		interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
+		clocks = <&clock 28>, <&clock 27>;
+		clock-names = "pcie", "pcie_bus";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000   /* configuration space */
+			  0x81000000 0 0	  0x40001000 0 0x00010000   /* downstream I/O */
+			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0x0 0 &gic 53>;
+	};
+
+	pcie@2a0000 {
+		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
+		reg = <0x2a0000 0x1000
+			0x272000 0x1000
+			0x271040 0x40>;
+		interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
+		clocks = <&clock 29>, <&clock 27>;
+		clock-names = "pcie", "pcie_bus";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000   /* configuration space */
+			  0x81000000 0 0	  0x60001000 0 0x00010000   /* downstream I/O */
+			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0x0 0 &gic 56>;
+	};
+
+Board specific DT Entry:
+
+	pcie@290000 {
+		reset-gpio = <&pin_ctrl 5 0>;
+	};
+
+	pcie@2a0000 {
+		reset-gpio = <&pin_ctrl 22 0>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pci/mvebu-pci.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pci/mvebu-pci.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pci/mvebu-pci.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pci/mvebu-pci.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,221 @@
+* Marvell EBU PCIe interfaces
+
+Mandatory properties:
+- compatible: one of the following values:
+    marvell,armada-370-pcie
+    marvell,armada-xp-pcie
+    marvell,kirkwood-pcie
+- #address-cells, set to <3>
+- #size-cells, set to <2>
+- #interrupt-cells, set to <1>
+- bus-range: PCI bus numbers covered
+- device_type, set to "pci"
+- ranges: ranges for the PCI memory and I/O regions, as well as the
+  MMIO registers to control the PCIe interfaces.
+
+In addition, the Device Tree node must have sub-nodes describing each
+PCIe interface, having the following mandatory properties:
+- reg: used only for interrupt mapping, so only the first four bytes
+  are used to refer to the correct bus number and device number.
+- assigned-addresses: reference to the MMIO registers used to control
+  this PCIe interface.
+- clocks: the clock associated to this PCIe interface
+- marvell,pcie-port: the physical PCIe port number
+- status: either "disabled" or "okay"
+- device_type, set to "pci"
+- #address-cells, set to <3>
+- #size-cells, set to <2>
+- #interrupt-cells, set to <1>
+- ranges, empty property.
+- interrupt-map-mask and interrupt-map, standard PCI properties to
+  define the mapping of the PCIe interface to interrupt numbers.
+
+and the following optional properties:
+- marvell,pcie-lane: the physical PCIe lane number, for ports having
+  multiple lanes. If this property is not found, we assume that the
+  value is 0.
+
+Example:
+
+pcie-controller {
+	compatible = "marvell,armada-xp-pcie";
+	status = "disabled";
+	device_type = "pci";
+
+	#address-cells = <3>;
+	#size-cells = <2>;
+
+	bus-range = <0x00 0xff>;
+
+	ranges = <0x82000000 0 0xd0040000 0xd0040000 0 0x00002000   /* Port 0.0 registers */
+		  0x82000000 0 0xd0042000 0xd0042000 0 0x00002000   /* Port 2.0 registers */
+		  0x82000000 0 0xd0044000 0xd0044000 0 0x00002000   /* Port 0.1 registers */
+		  0x82000000 0 0xd0048000 0xd0048000 0 0x00002000   /* Port 0.2 registers */
+		  0x82000000 0 0xd004c000 0xd004c000 0 0x00002000   /* Port 0.3 registers */
+		  0x82000000 0 0xd0080000 0xd0080000 0 0x00002000   /* Port 1.0 registers */
+		  0x82000000 0 0xd0082000 0xd0082000 0 0x00002000   /* Port 3.0 registers */
+		  0x82000000 0 0xd0084000 0xd0084000 0 0x00002000   /* Port 1.1 registers */
+		  0x82000000 0 0xd0088000 0xd0088000 0 0x00002000   /* Port 1.2 registers */
+		  0x82000000 0 0xd008c000 0xd008c000 0 0x00002000   /* Port 1.3 registers */
+		  0x82000000 0 0xe0000000 0xe0000000 0 0x08000000   /* non-prefetchable memory */
+		  0x81000000 0 0	  0xe8000000 0 0x00100000>; /* downstream I/O */
+
+	pcie@1,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82000800 0 0xd0040000 0 0x2000>;
+		reg = <0x0800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 58>;
+		marvell,pcie-port = <0>;
+		marvell,pcie-lane = <0>;
+		clocks = <&gateclk 5>;
+		status = "disabled";
+	};
+
+	pcie@2,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82001000 0 0xd0044000 0 0x2000>;
+		reg = <0x1000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 59>;
+		marvell,pcie-port = <0>;
+		marvell,pcie-lane = <1>;
+		clocks = <&gateclk 6>;
+		status = "disabled";
+	};
+
+	pcie@3,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82001800 0 0xd0048000 0 0x2000>;
+		reg = <0x1800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 60>;
+		marvell,pcie-port = <0>;
+		marvell,pcie-lane = <2>;
+		clocks = <&gateclk 7>;
+		status = "disabled";
+	};
+
+	pcie@4,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82002000 0 0xd004c000 0 0x2000>;
+		reg = <0x2000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 61>;
+		marvell,pcie-port = <0>;
+		marvell,pcie-lane = <3>;
+		clocks = <&gateclk 8>;
+		status = "disabled";
+	};
+
+	pcie@5,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82002800 0 0xd0080000 0 0x2000>;
+		reg = <0x2800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 62>;
+		marvell,pcie-port = <1>;
+		marvell,pcie-lane = <0>;
+		clocks = <&gateclk 9>;
+		status = "disabled";
+	};
+
+	pcie@6,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82003000 0 0xd0084000 0 0x2000>;
+		reg = <0x3000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 63>;
+		marvell,pcie-port = <1>;
+		marvell,pcie-lane = <1>;
+		clocks = <&gateclk 10>;
+		status = "disabled";
+	};
+
+	pcie@7,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82003800 0 0xd0088000 0 0x2000>;
+		reg = <0x3800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 64>;
+		marvell,pcie-port = <1>;
+		marvell,pcie-lane = <2>;
+		clocks = <&gateclk 11>;
+		status = "disabled";
+	};
+
+	pcie@8,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82004000 0 0xd008c000 0 0x2000>;
+		reg = <0x4000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 65>;
+		marvell,pcie-port = <1>;
+		marvell,pcie-lane = <3>;
+		clocks = <&gateclk 12>;
+		status = "disabled";
+	};
+	pcie@9,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82004800 0 0xd0042000 0 0x2000>;
+		reg = <0x4800 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 99>;
+		marvell,pcie-port = <2>;
+		marvell,pcie-lane = <0>;
+		clocks = <&gateclk 26>;
+		status = "disabled";
+	};
+
+	pcie@10,0 {
+		device_type = "pci";
+		assigned-addresses = <0x82005000 0 0xd0082000 0 0x2000>;
+		reg = <0x5000 0 0 0 0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		ranges;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &mpic 103>;
+		marvell,pcie-port = <3>;
+		marvell,pcie-lane = <0>;
+		clocks = <&gateclk 27>;
+		status = "disabled";
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pci/pci.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pci/pci.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pci/pci.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pci/pci.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,9 @@
+PCI bus bridges have standardized Device Tree bindings:
+
+PCI Bus Binding to: IEEE Std 1275-1994
+http://www.openfirmware.org/ofwg/bindings/pci/pci2_1.pdf
+
+And for the interrupt mapping part:
+
+Open Firmware Recommended Practice: Interrupt Mapping
+http://www.openfirmware.org/1275/practice/imap/imap0_9d.pdf
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pci/v3-v360epc-pci.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pci/v3-v360epc-pci.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pci/v3-v360epc-pci.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pci/v3-v360epc-pci.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,15 @@
+V3 Semiconductor V360 EPC PCI bridge
+
+This bridge is found in the ARM Integrator/AP (Application Platform)
+
+Integrator-specific notes:
+
+- syscon: should contain a link to the syscon device node (since
+  on the Integrator, some registers in the syscon are required to
+  operate the V3).
+
+V360 EPC specific notes:
+
+- reg: should contain the base address of the V3 adapter.
+- interrupts: should contain a reference to the V3 error interrupt
+  as routed on the system.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -58,7 +58,7 @@ Some requirements for using fsl,imx-pinc
 
 Examples:
 usdhc@0219c000 { /* uSDHC4 */
-	fsl,card-wired;
+	non-removable;
 	vmmc-supply = <&reg_3p3v>;
 	status = "okay";
 	pinctrl-names = "default";
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/fsl,vf610-pinctrl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/fsl,vf610-pinctrl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/fsl,vf610-pinctrl.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/fsl,vf610-pinctrl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,41 @@
+Freescale Vybrid VF610 IOMUX Controller
+
+Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
+and usage.
+
+Required properties:
+- compatible: "fsl,vf610-iomuxc"
+- fsl,pins: two integers array, represents a group of pins mux and config
+  setting. The format is fsl,pins = <PIN_FUNC_ID CONFIG>, PIN_FUNC_ID is
+  a pin working on a specific function, CONFIG is the pad setting value
+  such as pull-up, speed, ode for this pin. Please refer to Vybrid VF610
+  datasheet for the valid pad config settings.
+
+CONFIG bits definition:
+PAD_CTL_SPEED_LOW		(1 << 12)
+PAD_CTL_SPEED_MED		(2 << 12)
+PAD_CTL_SPEED_HIGH		(3 << 12)
+PAD_CTL_SRE_FAST		(1 << 11)
+PAD_CTL_SRE_SLOW		(0 << 11)
+PAD_CTL_ODE			(1 << 10)
+PAD_CTL_HYS			(1 << 9)
+PAD_CTL_DSE_DISABLE		(0 << 6)
+PAD_CTL_DSE_150ohm		(1 << 6)
+PAD_CTL_DSE_75ohm		(2 << 6)
+PAD_CTL_DSE_50ohm		(3 << 6)
+PAD_CTL_DSE_37ohm		(4 << 6)
+PAD_CTL_DSE_30ohm		(5 << 6)
+PAD_CTL_DSE_25ohm		(6 << 6)
+PAD_CTL_DSE_20ohm		(7 << 6)
+PAD_CTL_PUS_100K_DOWN		(0 << 4)
+PAD_CTL_PUS_47K_UP		(1 << 4)
+PAD_CTL_PUS_100K_UP		(2 << 4)
+PAD_CTL_PUS_22K_UP		(3 << 4)
+PAD_CTL_PKE			(1 << 3)
+PAD_CTL_PUE			(1 << 2)
+PAD_CTL_OBE_ENABLE		(1 << 1)
+PAD_CTL_IBE_ENABLE		(1 << 0)
+PAD_CTL_OBE_IBE_ENABLE		(3 << 0)
+
+Please refer to vf610-pinfunc.h in device tree source folder
+for all available PIN_FUNC_ID for Vybrid VF610.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,127 @@
+ImgTec TZ1090 PDC pin controller
+
+Required properties:
+- compatible: "img,tz1090-pdc-pinctrl"
+- reg: Should contain the register physical address and length of the
+  SOC_GPIO_CONTROL registers in the PDC register region.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+TZ1090-PDC's pin configuration nodes act as a container for an abitrary number
+of subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function. For this reason, even seemingly boolean
+values are actually tristates in this binding: unspecified, off, or on.
+Unspecified is represented as an absent property, and off/on are represented as
+integer values 0 and 1.
+
+Required subnode-properties:
+- tz1090,pins : An array of strings. Each string contains the name of a pin or
+  group. Valid values for these names are listed below.
+
+Optional subnode-properties:
+- tz1090,function: A string containing the name of the function to mux to the
+  pin or group. Valid values for function names are listed below, including
+  which pingroups can be muxed to them.
+- supported generic pinconfig properties (for further details see
+  Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt):
+  - bias-disable
+  - bias-high-impedance
+  - bias-bus-hold
+  - bias-pull-up
+  - bias-pull-down
+  - input-schmitt-enable
+  - input-schmitt-disable
+  - drive-strength: Integer, control drive strength of pins in mA.
+      2: 2mA
+      4: 4mA
+      8: 8mA
+      12: 12mA
+  - low-power-enable: Flag, power-on-start weak pull-down for invalid power.
+  - low-power-disable: Flag, power-on-start weak pull-down disabled.
+
+Note that many of these properties are only valid for certain specific pins
+or groups. See the TZ1090 TRM for complete details regarding which groups
+support which functionality. The Linux pinctrl driver may also be a useful
+reference.
+
+Valid values for pin and group names are:
+
+  pins:
+
+    These all support bias-high-impediance, bias-pull-up, bias-pull-down, and
+    bias-bus-hold (which can also be provided to any of the groups below to set
+    it for all gpio pins in that group).
+
+    gpio0, gpio1, sys_wake0, sys_wake1, sys_wake2, ir_data, ext_power.
+
+  mux groups:
+
+    These all support function.
+
+    gpio0
+        pins:       gpio0.
+        function:   ir_mod_stable_out.
+    gpio1
+        pins:       gpio1.
+        function:   ir_mod_power_out.
+
+  drive groups:
+
+    These support input-schmitt-enable, input-schmitt-disable,
+    drive-strength, low-power-enable, and low-power-disable.
+
+    pdc
+        pins:   gpio0, gpio1, sys_wake0, sys_wake1, sys_wake2, ir_data,
+                ext_power.
+
+Example:
+
+	pinctrl_pdc: pinctrl@02006500 {
+		#gpio-range-cells = <3>;
+		compatible = "img,tz1090-pdc-pinctrl";
+		reg = <0x02006500 0x100>;
+	};
+
+Example board file extracts:
+
+	&pinctrl_pdc {
+		pinctrl-names = "default";
+		pinctrl-0 = <&syswake_default>;
+
+		syswake_default: syswakes {
+			syswake_cfg {
+				tz1090,pins =	"sys_wake0",
+						"sys_wake1",
+						"sys_wake2";
+				pull-up;
+			};
+		};
+		irmod_default: irmod {
+			gpio0_cfg {
+				tz1090,pins =	"gpio0";
+				tz1090,function = "ir_mod_stable_out";
+			};
+			gpio1_cfg {
+				tz1090,pins =	"gpio1";
+				tz1090,function = "ir_mod_power_out";
+			};
+		};
+	};
+
+	ir: ir@02006200 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&irmod_default>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,227 @@
+ImgTec TZ1090 pin controller
+
+Required properties:
+- compatible: "img,tz1090-pinctrl"
+- reg: Should contain the register physical address and length of the pad
+  configuration registers (CR_PADS_* and CR_IF_CTL0).
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+TZ1090's pin configuration nodes act as a container for an abitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function. For this reason, even seemingly boolean
+values are actually tristates in this binding: unspecified, off, or on.
+Unspecified is represented as an absent property, and off/on are represented as
+integer values 0 and 1.
+
+Required subnode-properties:
+- tz1090,pins : An array of strings. Each string contains the name of a pin or
+  group. Valid values for these names are listed below.
+
+Optional subnode-properties:
+- tz1090,function: A string containing the name of the function to mux to the
+  pin or group. Valid values for function names are listed below, including
+  which pingroups can be muxed to them.
+- supported generic pinconfig properties (for further details see
+  Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt):
+  - bias-disable
+  - bias-high-impedance
+  - bias-bus-hold
+  - bias-pull-up
+  - bias-pull-down
+  - input-schmitt-enable
+  - input-schmitt-disable
+  - drive-strength: Integer, control drive strength of pins in mA.
+      2: 2mA
+      4: 4mA
+      8: 8mA
+      12: 12mA
+
+
+Note that many of these properties are only valid for certain specific pins
+or groups. See the TZ1090 TRM for complete details regarding which groups
+support which functionality. The Linux pinctrl driver may also be a useful
+reference.
+
+Valid values for pin and group names are:
+
+  gpio pins:
+
+    These all support bias-high-impediance, bias-pull-up, bias-pull-down, and
+    bias-bus-hold (which can also be provided to any of the groups below to set
+    it for all pins in that group).
+
+    They also all support the some form of muxing. Any pins which are contained
+    in one of the mux groups (see below) can be muxed only to the functions
+    supported by the mux group. All other pins can be muxed to the "perip"
+    function which which enables them with their intended peripheral.
+
+    Different pins in the same mux group cannot be muxed to different functions,
+    however it is possible to mux only a subset of the pins in a mux group to a
+    particular function and leave the remaining pins unmuxed. This is useful if
+    the board connects certain pins in a group to other devices to be controlled
+    by GPIO, and you don't want the usual peripheral to have any control of the
+    pin.
+
+    ant_sel0, ant_sel1, gain0, gain1, gain2, gain3, gain4, gain5, gain6, gain7,
+    i2s_bclk_out, i2s_din, i2s_dout0, i2s_dout1, i2s_dout2, i2s_lrclk_out,
+    i2s_mclk, pa_on, pdm_a, pdm_b, pdm_c, pdm_d, pll_on, rx_hp, rx_on,
+    scb0_sclk, scb0_sdat, scb1_sclk, scb1_sdat, scb2_sclk, scb2_sdat, sdh_cd,
+    sdh_clk_in, sdh_wp, sdio_clk, sdio_cmd, sdio_d0, sdio_d1, sdio_d2, sdio_d3,
+    spi0_cs0, spi0_cs1, spi0_cs2, spi0_din, spi0_dout, spi0_mclk, spi1_cs0,
+    spi1_cs1, spi1_cs2, spi1_din, spi1_dout, spi1_mclk, tft_blank_ls, tft_blue0,
+    tft_blue1, tft_blue2, tft_blue3, tft_blue4, tft_blue5, tft_blue6, tft_blue7,
+    tft_green0, tft_green1, tft_green2, tft_green3, tft_green4, tft_green5,
+    tft_green6, tft_green7, tft_hsync_nr, tft_panelclk, tft_pwrsave, tft_red0,
+    tft_red1, tft_red2, tft_red3, tft_red4, tft_red5, tft_red6, tft_red7,
+    tft_vd12acb, tft_vdden_gd, tft_vsync_ns, tx_on, uart0_cts, uart0_rts,
+    uart0_rxd, uart0_txd, uart1_rxd, uart1_txd.
+
+        bias-high-impediance:  supported.
+        bias-pull-up:          supported.
+        bias-pull-down:        supported.
+        bias-bus-hold:         supported.
+        function:              perip or those supported by pin's mux group.
+
+  other pins:
+
+    These other pins are part of various pin groups below, but can't be
+    controlled as GPIOs. They do however support bias-high-impediance,
+    bias-pull-up, bias-pull-down, and bias-bus-hold (which can also be provided
+    to any of the groups below to set it for all pins in that group).
+
+    clk_out0, clk_out1, tck, tdi, tdo, tms, trst.
+
+        bias-high-impediance:  supported.
+        bias-pull-up:          supported.
+        bias-pull-down:        supported.
+        bias-bus-hold:         supported.
+
+  mux groups:
+
+    These all support function, and some support drive configs.
+
+    afe
+        pins:                  tx_on, rx_on, pll_on, pa_on, rx_hp, ant_sel0,
+                               ant_sel1, gain0, gain1, gain2, gain3, gain4,
+                               gain5, gain6, gain7.
+        function:              afe, ts_out_0.
+        input-schmitt-enable:  supported.
+        input-schmitt-disable: supported.
+        drive-strength:        supported.
+    pdm_d
+        pins:                  pdm_d.
+        function:              pdm_dac, usb_vbus.
+    sdh
+        pins:                  sdh_cd, sdh_wp, sdh_clk_in.
+        function:              sdh, sdio.
+    sdio
+        pins:                  sdio_clk, sdio_cmd, sdio_d0, sdio_d1, sdio_d2,
+                               sdio_d3.
+        function:              sdio, sdh.
+    spi1_cs2
+        pins:                  spi1_cs2.
+        function:              spi1_cs2, usb_vbus.
+    tft
+        pins:                  tft_red0, tft_red1, tft_red2, tft_red3,
+                               tft_red4, tft_red5, tft_red6, tft_red7,
+                               tft_green0, tft_green1, tft_green2, tft_green3,
+                               tft_green4, tft_green5, tft_green6, tft_green7,
+                               tft_blue0, tft_blue1, tft_blue2, tft_blue3,
+                               tft_blue4, tft_blue5, tft_blue6, tft_blue7,
+                               tft_vdden_gd, tft_panelclk, tft_blank_ls,
+                               tft_vsync_ns, tft_hsync_nr, tft_vd12acb,
+                               tft_pwrsave.
+        function:              tft, ext_dac, not_iqadc_stb, iqdac_stb, ts_out_1,
+                               lcd_trace, phy_ringosc.
+        input-schmitt-enable:  supported.
+        input-schmitt-disable: supported.
+        drive-strength:        supported.
+
+  drive groups:
+
+    These all support input-schmitt-enable, input-schmitt-disable,
+    and drive-strength.
+
+    jtag
+        pins:   tck, trst, tdi, tdo, tms.
+    scb1
+        pins:   scb1_sdat, scb1_sclk.
+    scb2
+        pins:   scb2_sdat, scb2_sclk.
+    spi0
+        pins:   spi0_mclk, spi0_cs0, spi0_cs1, spi0_cs2, spi0_dout, spi0_din.
+    spi1
+        pins:   spi1_mclk, spi1_cs0, spi1_cs1, spi1_cs2, spi1_dout, spi1_din.
+    uart
+        pins:   uart0_txd, uart0_rxd, uart0_rts, uart0_cts,
+                uart1_txd, uart1_rxd.
+    drive_i2s
+        pins:   clk_out1, i2s_din, i2s_dout0, i2s_dout1, i2s_dout2,
+                i2s_lrclk_out, i2s_bclk_out, i2s_mclk.
+    drive_pdm
+        pins:   clk_out0, pdm_b, pdm_a.
+    drive_scb0
+        pins:   scb0_sclk, scb0_sdat, pdm_d, pdm_c.
+    drive_sdio
+        pins:   sdio_clk, sdio_cmd, sdio_d0, sdio_d1, sdio_d2, sdio_d3,
+                sdh_wp, sdh_cd, sdh_clk_in.
+
+  convenience groups:
+
+    These are just convenient groupings of pins and don't support any drive
+    configs.
+
+    uart0
+        pins:   uart0_cts, uart0_rts, uart0_rxd, uart0_txd.
+    uart1
+        pins:   uart1_rxd, uart1_txd.
+    scb0
+        pins:   scb0_sclk, scb0_sdat.
+    i2s
+        pins:   i2s_bclk_out, i2s_din, i2s_dout0, i2s_dout1, i2s_dout2,
+                i2s_lrclk_out, i2s_mclk.
+
+Example:
+
+	pinctrl: pinctrl@02005800 {
+		#gpio-range-cells = <3>;
+		compatible = "img,tz1090-pinctrl";
+		reg = <0x02005800 0xe4>;
+	};
+
+Example board file extract:
+
+	&pinctrl {
+		uart0_default: uart0 {
+			uart0_cfg {
+				tz1090,pins =	"uart0_rxd",
+						"uart0_txd";
+				tz1090,function = "perip";
+			};
+		};
+		tft_default: tft {
+			tft_cfg {
+				tz1090,pins =	"tft";
+				tz1090,function = "tft";
+			};
+		};
+	};
+
+	uart@02004b00 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_default>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/marvell,dove-pinctrl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -10,29 +10,31 @@ Required properties:
 Available mpp pins/groups and functions:
 Note: brackets (x) are not part of the mpp name for marvell,function and given
 only for more detailed description in this document.
+Note: pmu* also allows for Power Management functions listed below
 
 name          pins     functions
 ================================================================================
-mpp0          0        gpio, pmu, uart2(rts), sdio0(cd), lcd0(pwm)
-mpp1          1        gpio, pmu, uart2(cts), sdio0(wp), lcd1(pwm)
+mpp0          0        gpio, pmu, uart2(rts), sdio0(cd), lcd0(pwm), pmu*
+mpp1          1        gpio, pmu, uart2(cts), sdio0(wp), lcd1(pwm), pmu*
 mpp2          2        gpio, pmu, uart2(txd), sdio0(buspwr), sata(prsnt),
-                       uart1(rts)
+                       uart1(rts), pmu*
 mpp3          3        gpio, pmu, uart2(rxd), sdio0(ledctrl), sata(act),
-                       uart1(cts), lcd-spi(cs1)
-mpp4          4        gpio, pmu, uart3(rts), sdio1(cd), spi1(miso)
-mpp5          5        gpio, pmu, uart3(cts), sdio1(wp), spi1(cs)
-mpp6          6        gpio, pmu, uart3(txd), sdio1(buspwr), spi1(mosi)
-mpp7          7        gpio, pmu, uart3(rxd), sdio1(ledctrl), spi1(sck)
-mpp8          8        gpio, pmu, watchdog(rstout)
-mpp9          9        gpio, pmu, pex1(clkreq)
-mpp10         10       gpio, pmu, ssp(sclk)
+                       uart1(cts), lcd-spi(cs1), pmu*
+mpp4          4        gpio, pmu, uart3(rts), sdio1(cd), spi1(miso), pmu*
+mpp5          5        gpio, pmu, uart3(cts), sdio1(wp), spi1(cs), pmu*
+mpp6          6        gpio, pmu, uart3(txd), sdio1(buspwr), spi1(mosi), pmu*
+mpp7          7        gpio, pmu, uart3(rxd), sdio1(ledctrl), spi1(sck), pmu*
+mpp8          8        gpio, pmu, watchdog(rstout), pmu*
+mpp9          9        gpio, pmu, pex1(clkreq), pmu*
+mpp10         10       gpio, pmu, ssp(sclk), pmu*
 mpp11         11       gpio, pmu, sata(prsnt), sata-1(act), sdio0(ledctrl),
-                       sdio1(ledctrl), pex0(clkreq)
-mpp12         12       gpio, pmu, uart2(rts), audio0(extclk), sdio1(cd), sata(act)
+                       sdio1(ledctrl), pex0(clkreq), pmu*
+mpp12         12       gpio, pmu, uart2(rts), audio0(extclk), sdio1(cd),
+                       sata(act), pmu*
 mpp13         13       gpio, pmu, uart2(cts), audio1(extclk), sdio1(wp),
-                       ssp(extclk)
-mpp14         14       gpio, pmu, uart2(txd), sdio1(buspwr), ssp(rxd)
-mpp15         15       gpio, pmu, uart2(rxd), sdio1(ledctrl), ssp(sfrm)
+                       ssp(extclk), pmu*
+mpp14         14       gpio, pmu, uart2(txd), sdio1(buspwr), ssp(rxd), pmu*
+mpp15         15       gpio, pmu, uart2(rxd), sdio1(ledctrl), ssp(sfrm), pmu*
 mpp16         16       gpio, uart3(rts), sdio0(cd), ac97(sdi1), lcd-spi(cs1)
 mpp17         17       gpio, uart3(cts), sdio0(wp), ac97(sdi2), twsi(sda),
                        ac97-1(sysclko)
@@ -57,6 +59,21 @@ mpp_nand      64-71    gpo, nand
 audio0        -        i2s, ac97
 twsi          -        none, opt1, opt2, opt3
 
+Power Management functions (pmu*):
+pmu-nc               Pin not driven by any PM function
+pmu-low              Pin driven low (0)
+pmu-high             Pin driven high (1)
+pmic(sdi)            Pin is used for PMIC SDI
+cpu-pwr-down         Pin is used for CPU_PWRDWN
+standby-pwr-down     Pin is used for STBY_PWRDWN
+core-pwr-good        Pin is used for CORE_PWR_GOOD (Pins 0-7 only)
+cpu-pwr-good         Pin is used for CPU_PWR_GOOD (Pins 8-15 only)
+bat-fault            Pin is used for BATTERY_FAULT
+ext0-wakeup          Pin is used for EXT0_WU
+ext1-wakeup          Pin is used for EXT0_WU
+ext2-wakeup          Pin is used for EXT0_WU
+pmu-blink            Pin is used for blink function
+
 Notes:
 * group "mpp_audio1" allows the following functions and gpio pins:
   - gpio          : gpio on pins 52-57
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt	2013-08-25 20:43:22.000000000 -0400
@@ -126,3 +126,51 @@ device; they may be grandchildren, for e
 whether there is any interaction between the child and intermediate parent
 nodes, is again defined entirely by the binding for the individual pin
 controller device.
+
+== Using generic pinconfig options ==
+
+Generic pinconfig parameters can be used by defining a separate node containing
+the applicable parameters (and optional values), like:
+
+pcfg_pull_up: pcfg_pull_up {
+	bias-pull-up;
+	drive-strength = <20>;
+};
+
+This node should then be referenced in the appropriate pinctrl node as a phandle
+and parsed in the driver using the pinconf_generic_parse_dt_config function.
+
+Supported configuration parameters are:
+
+bias-disable		- disable any pin bias
+bias-high-impedance	- high impedance mode ("third-state", "floating")
+bias-bus-hold		- latch weakly
+bias-pull-up		- pull up the pin
+bias-pull-down		- pull down the pin
+bias-pull-pin-default	- use pin-default pull state
+drive-push-pull		- drive actively high and low
+drive-open-drain	- drive with open drain
+drive-open-source	- drive with open source
+drive-strength		- sink or source at most X mA
+input-schmitt-enable	- enable schmitt-trigger mode
+input-schmitt-disable	- disable schmitt-trigger mode
+input-debounce		- debounce mode with debound time X
+low-power-enable	- enable low power mode
+low-power-disable	- disable low power mode
+output-low		- set the pin to output mode with low level
+output-high		- set the pin to output mode with high level
+
+Arguments for parameters:
+
+- bias-pull-up, -down and -pin-default take as optional argument on hardware
+  supporting it the pull strength in Ohm. bias-disable will disable the pull.
+
+- drive-strength takes as argument the target strength in mA.
+
+- input-debounce takes the debounce time in usec as argument
+  or 0 to disable debouncing
+
+All parameters not listed here, do not take an argument.
+
+More in-depth documentation on these parameters can be found in
+<include/linux/pinctrl/pinconfig-generic.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,8 @@ Optional properties:
   pin functions is ignored
 
 - pinctrl-single,bit-per-mux : boolean to indicate that one register controls
-  more than one pin
+  more than one pin, for which "pinctrl-single,function-mask" property specifies
+ position mask of pin.
 
 - pinctrl-single,drive-strength : array of value that are used to configure
   drive strength in the pinmux register. They're value of drive strength
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,110 @@
+*ST pin controller.
+
+Each multi-function pin is controlled, driven and routed through the
+PIO multiplexing block. Each pin supports GPIO functionality (ALT0)
+and multiple alternate functions(ALT1 - ALTx) that directly connect
+the pin to different hardware blocks.
+
+When a pin is in GPIO mode, Output Enable (OE), Open Drain(OD), and
+Pull Up (PU) are driven by the related PIO block.
+
+ST pinctrl driver controls PIO multiplexing block and also interacts with
+gpio driver to configure a pin.
+
+Required properties: (PIO multiplexing block)
+- compatible	: should be "st,<SOC>-<pio-block>-pinctrl"
+	like st,stih415-sbc-pinctrl, st,stih415-front-pinctrl and so on.
+- gpio-controller : Indicates this device is a GPIO controller
+- #gpio-cells	  : Should be one. The first cell is the pin number.
+- st,retime-pin-mask	: Should be mask to specify which pins can be retimed.
+	If the property is not present, it is assumed that all the pins in the
+	bank are capable of retiming. Retiming is mainly used to improve the
+	IO timing margins of external synchronous interfaces.
+- st,bank-name		: Should be a name string for this bank as
+			specified in datasheet.
+- st,syscfg		: Should be a phandle of the syscfg node.
+
+Example:
+	pin-controller-sbc {
+		#address-cells	= <1>;
+		#size-cells	= <1>;
+		compatible	= "st,stih415-sbc-pinctrl";
+		st,syscfg	= <&syscfg_sbc>;
+		ranges 		= <0 0xfe610000 0x5000>;
+		PIO0: gpio@fe610000 {
+			gpio-controller;
+			#gpio-cells	= <1>;
+			reg		= <0 0x100>;
+			st,bank-name	= "PIO0";
+		};
+		...
+		pin-functions nodes follow...
+	};
+
+
+Contents of function subnode node:
+----------------------
+Required properties for pin configuration node:
+- st,pins	: Child node with list of pins with configuration.
+
+Below is the format of how each pin conf should look like.
+
+<bank offset mux mode rt_type rt_delay rt_clk>
+
+Every PIO is represented with 4-7 parameters depending on retime configuration.
+Each parameter is explained as below.
+
+-bank		: Should be bank phandle to which this PIO belongs.
+-offset		: Offset in the PIO bank.
+-mux		: Should be alternate function number associated this pin.
+		Use same numbers from datasheet.
+-mode		:pin configuration is selected from one of the below values.
+		IN
+		IN_PU
+		OUT
+		BIDIR
+		BIDIR_PU
+
+-rt_type	Retiming Configuration for the pin.
+		Possible retime configuration are:
+
+		-------		-------------
+		value		args
+		-------		-------------
+		NICLK		<delay> <clk>
+		ICLK_IO		<delay> <clk>
+		BYPASS		<delay>
+		DE_IO		<delay> <clk>
+		SE_ICLK_IO	<delay> <clk>
+		SE_NICLK_IO	<delay> <clk>
+
+- delay	is retime delay in pico seconds as mentioned in data sheet.
+
+- rt_clk	:clk to be use for retime.
+		Possible values are:
+		CLK_A
+		CLK_B
+		CLK_C
+		CLK_D
+
+Example of mmcclk pin which is a bi-direction pull pu with retime config
+as non inverted clock retimed with CLK_B and delay of 0 pico seconds:
+
+pin-controller {
+	...
+	mmc0 {
+		pinctrl_mmc: mmc {
+			st,pins {
+				mmcclk = <&PIO13 4 ALT4 BIDIR_PU NICLK 0 CLK_B>;
+				...
+			};
+		};
+	...
+	};
+};
+
+sdhci0:sdhci@fe810000{
+	...
+	pinctrl-names = "default";
+	pinctrl-0	= <&pinctrl_mmc>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,153 @@
+* Renesas Pin Function Controller (GPIO and Pin Mux/Config)
+
+The Pin Function Controller (PFC) is a Pin Mux/Config controller. On SH7372,
+SH73A0, R8A73A4 and R8A7740 it also acts as a GPIO controller.
+
+
+Pin Control
+-----------
+
+Required Properties:
+
+  - compatible: should be one of the following.
+    - "renesas,pfc-r8a73a4": for R8A73A4 (R-Mobile APE6) compatible pin-controller.
+    - "renesas,pfc-r8a7740": for R8A7740 (R-Mobile A1) compatible pin-controller.
+    - "renesas,pfc-r8a7778": for R8A7778 (R-Mobile M1) compatible pin-controller.
+    - "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller.
+    - "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller.
+    - "renesas,pfc-sh7372": for SH7372 (SH-Mobile AP4) compatible pin-controller.
+    - "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller.
+
+  - reg: Base address and length of each memory resource used by the pin
+    controller hardware module.
+
+Optional properties:
+
+  - #gpio-range-cells: Mandatory when the PFC doesn't handle GPIO, forbidden
+    otherwise. Should be 3.
+
+The PFC node also acts as a container for pin configuration nodes. Please refer
+to pinctrl-bindings.txt in this directory for the definition of the term "pin
+configuration node" and for the common pinctrl bindings used by client devices.
+
+Each pin configuration node represents a desired configuration for a pin, a
+pin group, or a list of pins or pin groups. The configuration can include the
+function to select on those pin(s) and pin configuration parameters (such as
+pull-up and pull-down).
+
+Pin configuration nodes contain pin configuration properties, either directly
+or grouped in child subnodes. Both pin muxing and configuration parameters can
+be grouped in that way and referenced as a single pin configuration node by
+client devices.
+
+A configuration node or subnode must reference at least one pin (through the
+pins or pin groups properties) and contain at least a function or one
+configuration parameter. When the function is present only pin groups can be
+used to reference pins.
+
+All pin configuration nodes and subnodes names are ignored. All of those nodes
+are parsed through phandles and processed purely based on their content.
+
+Pin Configuration Node Properties:
+
+- renesas,pins : An array of strings, each string containing the name of a pin.
+- renesas,groups : An array of strings, each string containing the name of a pin
+  group.
+
+- renesas,function: A string containing the name of the function to mux to the
+  pin group(s) specified by the renesas,groups property
+
+  Valid values for pin, group and function names can be found in the group and
+  function arrays of the PFC data file corresponding to the SoC
+  (drivers/pinctrl/sh-pfc/pfc-*.c)
+
+The pin configuration parameters use the generic pinconf bindings defined in
+pinctrl-bindings.txt in this directory. The supported parameters are
+bias-disable, bias-pull-up and bias-pull-down.
+
+
+GPIO
+----
+
+On SH7372, SH73A0, R8A73A4 and R8A7740 the PFC node is also a GPIO controller
+node.
+
+Required Properties:
+
+  - gpio-controller: Marks the device node as a gpio controller.
+
+  - #gpio-cells: Should be 2. The first cell is the GPIO number and the second
+    cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>. Only the
+    GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported.
+
+The syntax of the gpio specifier used by client nodes should be the following
+with values derived from the SoC user manual.
+
+  <[phandle of the gpio controller node]
+   [pin number within the gpio controller]
+   [flags]>
+
+On other mach-shmobile platforms GPIO is handled by the gpio-rcar driver.
+Please refer to Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt
+for documentation of the GPIO device tree bindings on those platforms.
+
+
+Examples
+--------
+
+Example 1: SH73A0 (SH-Mobile AG5) pin controller node
+
+	pfc: pfc@e6050000 {
+		compatible = "renesas,pfc-sh73a0";
+		reg = <0xe6050000 0x8000>,
+		      <0xe605801c 0x1c>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+Example 2: A GPIO LED node that references a GPIO
+
+	#include <dt-bindings/gpio/gpio.h>
+
+	leds {
+		compatible = "gpio-leds";
+		led1 {
+			gpios = <&pfc 20 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+Example 3: KZM-A9-GT (SH-Mobile AG5) default pin state hog and pin control maps
+           for the MMCIF and SCIFA4 devices
+
+	&pfc {
+		pinctrl-0 = <&scifa4_pins>;
+		pinctrl-names = "default";
+
+		mmcif_pins: mmcif {
+			mux {
+				renesas,groups = "mmc0_data8_0", "mmc0_ctrl_0";
+				renesas,function = "mmc0";
+			};
+			cfg {
+				renesas,groups = "mmc0_data8_0";
+				renesas,pins = "PORT279";
+				bias-pull-up;
+			};
+		};
+
+		scifa4_pins: scifa4 {
+			renesas,groups = "scifa4_data", "scifa4_ctrl";
+			renesas,function = "scifa4";
+		};
+	};
+
+Example 4: KZM-A9-GT (SH-Mobile AG5) default pin state for the MMCIF device
+
+	&mmcif {
+		pinctrl-0 = <&mmcif_pins>;
+		pinctrl-names = "default";
+
+		bus-width = <8>;
+		vmmc-supply = <&reg_1p8v>;
+		status = "okay";
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,97 @@
+* Rockchip Pinmux Controller
+
+The Rockchip Pinmux Controller, enables the IC
+to share one PAD to several functional blocks. The sharing is done by
+multiplexing the PAD input/output signals. For each PAD there are up to
+4 muxing options with option 0 being the use as a GPIO.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The Rockchip pin configuration node is a node of a group of pins which can be
+used for a specific device or function. This node represents both mux and
+config of the pins in that group. The 'pins' selects the function mode(also
+named pin mode) this pin can work on and the 'config' configures various pad
+settings such as pull-up, etc.
+
+The pins are grouped into up to 5 individual pin banks which need to be
+defined as gpio sub-nodes of the pinmux controller.
+
+Required properties for iomux controller:
+  - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl"
+		       "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl"
+
+Required properties for gpio sub nodes:
+  - compatible: "rockchip,gpio-bank"
+  - reg: register of the gpio bank (different than the iomux registerset)
+  - interrupts: base interrupt of the gpio bank in the interrupt controller
+  - clocks: clock that drives this bank
+  - gpio-controller: identifies the node as a gpio controller and pin bank.
+  - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
+    binding is used, the amount of cells must be specified as 2. See generic
+    GPIO binding documentation for description of particular cells.
+  - interrupt-controller: identifies the controller node as interrupt-parent.
+  - #interrupt-cells: the value of this property should be 2 and the interrupt
+    cells should use the standard two-cell scheme described in
+    bindings/interrupt-controller/interrupts.txt
+
+Required properties for pin configuration node:
+  - rockchip,pins: 3 integers array, represents a group of pins mux and config
+    setting. The format is rockchip,pins = <PIN_BANK PIN_BANK_IDX MUX &phandle>.
+    The MUX 0 means gpio and MUX 1 to 3 mean the specific device function.
+    The phandle of a node containing the generic pinconfig options
+    to use, as described in pinctrl-bindings.txt in this directory.
+
+Examples:
+
+#include <dt-bindings/pinctrl/rockchip.h>
+
+...
+
+pinctrl@20008000 {
+	compatible = "rockchip,rk3066a-pinctrl";
+	reg = <0x20008000 0x150>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges;
+
+	gpio0: gpio0@20034000 {
+		compatible = "rockchip,gpio-bank";
+		reg = <0x20034000 0x100>;
+		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk_gates8 9>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	...
+
+	pcfg_pull_default: pcfg_pull_default {
+		bias-pull-pin-default
+	};
+
+	uart2 {
+		uart2_xfer: uart2-xfer {
+			rockchip,pins = <RK_GPIO1 8 1 &pcfg_pull_default>,
+					<RK_GPIO1 9 1 &pcfg_pull_default>;
+		};
+	};
+};
+
+uart2: serial@20064000 {
+	compatible = "snps,dw-apb-uart";
+	reg = <0x20064000 0x400>;
+	interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+	reg-shift = <2>;
+	reg-io-width = <1>;
+	clocks = <&mux_uart2>;
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_xfer>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -7,10 +7,15 @@ on-chip controllers onto these pads.
 
 Required Properties:
 - compatible: should be one of the following.
+  - "samsung,s3c2412-pinctrl": for S3C2412-compatible pin-controller,
+  - "samsung,s3c2416-pinctrl": for S3C2416-compatible pin-controller,
+  - "samsung,s3c2440-pinctrl": for S3C2440-compatible pin-controller,
+  - "samsung,s3c2450-pinctrl": for S3C2450-compatible pin-controller,
   - "samsung,s3c64xx-pinctrl": for S3C64xx-compatible pin-controller,
   - "samsung,exynos4210-pinctrl": for Exynos4210 compatible pin-controller.
   - "samsung,exynos4x12-pinctrl": for Exynos4x12 compatible pin-controller.
   - "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller.
+  - "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
 
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
@@ -21,8 +26,18 @@ Required Properties:
 
   - gpio-controller: identifies the node as a gpio controller and pin bank.
   - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
-    binding is used, the amount of cells must be specified as 2. See generic
-    GPIO binding documentation for description of particular cells.
+    binding is used, the amount of cells must be specified as 2. See the below
+    mentioned gpio binding representation for description of particular cells.
+
+	Eg: <&gpx2 6 0>
+	<[phandle of the gpio controller node]
+	[pin number within the gpio controller]
+	[flags]>
+
+	Values for gpio specifier:
+	- Pin number: is a value between 0 to 7.
+	- Flags: 0 - Active High
+		 1 - Active Low
 
 - Pin mux/config groups as child nodes: The pin mux (selecting pin function
   mode) and pin config (pull up/down, driver strength) settings are represented
@@ -106,6 +121,10 @@ B. External Wakeup Interrupts: For suppo
 
    - compatible: identifies the type of the external wakeup interrupt controller
      The possible values are:
+     - samsung,s3c2410-wakeup-eint: represents wakeup interrupt controller
+       found on Samsung S3C24xx SoCs except S3C2412 and S3C2413,
+     - samsung,s3c2412-wakeup-eint: represents wakeup interrupt controller
+       found on Samsung S3C2412 and S3C2413 SoCs,
      - samsung,s3c64xx-wakeup-eint: represents wakeup interrupt controller
        found on Samsung S3C64xx SoCs,
      - samsung,exynos4210-wakeup-eint: represents wakeup interrupt controller
@@ -266,3 +285,33 @@ Example 4: Set up the default pin state
 
 		pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
 	}
+
+Example 5: A display port client node that supports 'default' pinctrl state
+	   and gpio binding.
+
+	display-port-controller {
+		/* ... */
+
+		samsung,hpd-gpio = <&gpx2 6 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&dp_hpd>;
+	};
+
+Example 6: Request the gpio for display port controller
+
+	static int exynos_dp_probe(struct platform_device *pdev)
+	{
+		int hpd_gpio, ret;
+		struct device *dev = &pdev->dev;
+		struct device_node *dp_node = dev->of_node;
+
+		/* ... */
+
+		hpd_gpio = of_get_named_gpio(dp_node, "samsung,hpd-gpio", 0);
+
+		/* ... */
+
+		ret = devm_gpio_request_one(&pdev->dev, hpd_gpio, GPIOF_IN,
+					    "hpd_gpio");
+		/* ... */
+	}
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/ste,abx500.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/ste,abx500.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pinctrl/ste,abx500.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pinctrl/ste,abx500.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,352 @@
+ST Ericsson abx500 pinmux controller
+
+Required properties:
+- compatible: "stericsson,ab8500-gpio",  "stericsson,ab8540-gpio",
+	      "stericsson,ab8505-gpio", "stericsson,ab9540-gpio",
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+ST Ericsson's pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as input, output, pull up, pull down...
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Required subnode-properties:
+- ste,pins : An array of strings. Each string contains the name of a pin or
+    group.
+
+Optional subnode-properties:
+- ste,function: A string containing the name of the function to mux to the
+  pin or group.
+
+- generic pin configuration option to use. Example :
+
+	default_cfg {
+		ste,pins = "GPIO1";
+		bias-disable;
+	};
+
+- ste,config: Handle of pin configuration node containing the generic
+  pinconfig options to use, as described in pinctrl-bindings.txt in
+  this directory. Example :
+
+	pcfg_bias_disable: pcfg_bias_disable {
+		bias-disable;
+	};
+
+	default_cfg {
+		ste,pins = "GPIO1";
+		ste.config = <&pcfg_bias_disable>;
+	};
+
+Example board file extract:
+
+&pinctrl_abx500 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sysclkreq2_default_mode>, <&sysclkreq3_default_mode>, <&gpio3_default_mode>, <&sysclkreq6_default_mode>, <&pwmout1_default_mode>, <&pwmout2_default_mode>, <&pwmout3_default_mode>, <&adi1_default_mode>, <&dmic12_default_mode>, <&dmic34_default_mode>, <&dmic56_default_mode>, <&sysclkreq5_default_mode>, <&batremn_default_mode>, <&service_default_mode>, <&pwrctrl0_default_mode>, <&pwrctrl1_default_mode>, <&pwmextvibra1_default_mode>, <&pwmextvibra2_default_mode>, <&gpio51_default_mode>, <&gpio52_default_mode>, <&gpio53_default_mode>, <&gpio54_default_mode>, <&pdmclkdat_default_mode>;
+
+	sysclkreq2 {
+		sysclkreq2_default_mode: sysclkreq2_default {
+			default_mux {
+				ste,function = "sysclkreq";
+				ste,pins = "sysclkreq2_d_1";
+			};
+			default_cfg {
+				ste,pins = "GPIO1";
+				bias-disable;
+			};
+		};
+	};
+	sysclkreq3 {
+		sysclkreq3_default_mode: sysclkreq3_default {
+			default_mux {
+				ste,function = "sysclkreq";
+				ste,pins = "sysclkreq3_d_1";
+			};
+			default_cfg {
+				ste,pins = "GPIO2";
+				output-low;
+			};
+		};
+	};
+	gpio3 {
+		gpio3_default_mode: gpio3_default {
+			default_mux {
+				ste,function = "gpio";
+				ste,pins = "gpio3_a_1";
+			};
+			default_cfg {
+				ste,pins = "GPIO3";
+				output-low;
+			};
+		};
+	};
+	sysclkreq6 {
+		sysclkreq6_default_mode: sysclkreq6_default {
+			default_mux {
+				ste,function = "sysclkreq";
+				ste,pins = "sysclkreq6_d_1";
+			};
+			default_cfg {
+				ste,pins = "GPIO4";
+				bias-disable;
+			};
+		};
+	};
+	pwmout1 {
+		pwmout1_default_mode: pwmout1_default {
+			default_mux {
+				ste,function = "pwmout";
+				ste,pins = "pwmout1_d_1";
+			};
+			default_cfg {
+				ste,pins = "GPIO14";
+				output-low;
+			};
+		};
+	};
+	pwmout2 {
+		pwmout2_default_mode: pwmout2_default {
+			pwmout2_default_mux {
+				ste,function = "pwmout";
+				ste,pins = "pwmout2_d_1";
+			};
+			pwmout2_default_cfg {
+				ste,pins = "GPIO15";
+				output-low;
+			};
+		};
+	};
+	pwmout3 {
+		pwmout3_default_mode: pwmout3_default {
+			pwmout3_default_mux {
+				ste,function = "pwmout";
+				ste,pins = "pwmout3_d_1";
+			};
+			pwmout3_default_cfg {
+				ste,pins = "GPIO16";
+				output-low;
+			};
+		};
+	};
+	adi1 {
+
+		adi1_default_mode: adi1_default {
+			adi1_default_mux {
+				ste,function = "adi1";
+				ste,pins = "adi1_d_1";
+			};
+			adi1_default_cfg1 {
+				ste,pins = "GPIO17","GPIO19","GPIO20";
+				bias-disable;
+			};
+			adi1_default_cfg2 {
+				ste,pins = "GPIO18";
+				output-low;
+			};
+		};
+	};
+	dmic12 {
+		dmic12_default_mode: dmic12_default {
+			dmic12_default_mux {
+				ste,function = "dmic";
+				ste,pins = "dmic12_d_1";
+			};
+			dmic12_default_cfg1 {
+				ste,pins = "GPIO27";
+				output-low;
+			};
+			dmic12_default_cfg2 {
+				ste,pins = "GPIO28";
+				bias-disable;
+			};
+		};
+	};
+	dmic34 {
+		dmic34_default_mode: dmic34_default {
+			dmic34_default_mux {
+				ste,function = "dmic";
+				ste,pins = "dmic34_d_1";
+			};
+			dmic34_default_cfg1 {
+				ste,pins = "GPIO29";
+				output-low;
+			};
+			dmic34_default_cfg2 {
+				ste,pins = "GPIO30";
+				bias-disable;{
+
+			};
+		};
+	};
+	dmic56 {
+		dmic56_default_mode: dmic56_default {
+			dmic56_default_mux {
+				ste,function = "dmic";
+				ste,pins = "dmic56_d_1";
+			};
+			dmic56_default_cfg1 {
+				ste,pins = "GPIO31";
+				output-low;
+			};
+			dmic56_default_cfg2 {
+				ste,pins = "GPIO32";
+				bias-disable;
+			};
+		};
+	};
+	sysclkreq5 {
+		sysclkreq5_default_mode: sysclkreq5_default {
+			sysclkreq5_default_mux {
+				ste,function = "sysclkreq";
+				ste,pins = "sysclkreq5_d_1";
+			};
+			sysclkreq5_default_cfg {
+				ste,pins = "GPIO42";
+				output-low;
+			};
+		};
+	};
+	batremn {
+		batremn_default_mode: batremn_default {
+			batremn_default_mux {
+				ste,function = "batremn";
+				ste,pins = "batremn_d_1";
+			};
+			batremn_default_cfg {
+				ste,pins = "GPIO43";
+				bias-disable;
+			};
+		};
+	};
+	service {
+		service_default_mode: service_default {
+			service_default_mux {
+				ste,function = "service";
+				ste,pins = "service_d_1";
+			};
+			service_default_cfg {
+				ste,pins = "GPIO44";
+				bias-disable;
+			};
+		};
+	};
+	pwrctrl0 {
+		pwrctrl0_default_mux: pwrctrl0_mux {
+			pwrctrl0_default_mux {
+				ste,function = "pwrctrl";
+				ste,pins = "pwrctrl0_d_1";
+			};
+		};
+		pwrctrl0_default_mode: pwrctrl0_default {
+			pwrctrl0_default_cfg {
+				ste,pins = "GPIO45";
+				bias-disable;
+			};
+		};
+	};
+	pwrctrl1 {
+		pwrctrl1_default_mux: pwrctrl1_mux {
+			pwrctrl1_default_mux {
+				ste,function = "pwrctrl";
+				ste,pins = "pwrctrl1_d_1";
+			};
+		};
+		pwrctrl1_default_mode: pwrctrl1_default {
+			pwrctrl1_default_cfg {
+				ste,pins = "GPIO46";
+				bias-disable;
+			};
+		};
+	};
+	pwmextvibra1 {
+		pwmextvibra1_default_mode: pwmextvibra1_default {
+			pwmextvibra1_default_mux {
+				ste,function = "pwmextvibra";
+				ste,pins = "pwmextvibra1_d_1";
+			};
+			pwmextvibra1_default_cfg {
+				ste,pins = "GPIO47";
+				bias-disable;
+			};
+		};
+	};
+	pwmextvibra2 {
+		pwmextvibra2_default_mode: pwmextvibra2_default {
+			pwmextvibra2_default_mux {
+				ste,function = "pwmextvibra";
+				ste,pins = "pwmextvibra2_d_1";
+			};
+			pwmextvibra1_default_cfg {
+				ste,pins = "GPIO48";
+				bias-disable;
+			};
+		};
+	};
+	gpio51 {
+		gpio51_default_mode: gpio51_default {
+				gpio51_default_mux {
+				ste,function = "gpio";
+				ste,pins = "gpio51_a_1";
+			};
+			gpio51_default_cfg {
+				ste,pins = "GPIO51";
+				output-low;
+			};
+		};
+	};
+	gpio52 {
+		gpio52_default_mode: gpio52_default {
+			gpio52_default_mux {
+				ste,function = "gpio";
+				ste,pins = "gpio52_a_1";
+			};
+			gpio52_default_cfg {
+				ste,pins = "GPIO52";
+				bias-pull-down;
+			};
+		};
+	};
+	gpio53 {
+		gpio53_default_mode: gpio53_default {
+			gpio53_default_mux {
+				ste,function = "gpio";
+				ste,pins = "gpio53_a_1";
+			};
+			gpio53_default_cfg {
+				ste,pins = "GPIO53";
+				bias-pull-down;
+			};
+		};
+	};
+	gpio54 {
+		gpio54_default_mode: gpio54_default {
+			gpio54_default_mux {
+				ste,function = "gpio";
+				ste,pins = "gpio54_a_1";
+			};
+			gpio54_default_cfg {
+				ste,pins = "GPIO54";
+				output-low;
+			};
+		};
+	};
+	pdmclkdat {
+		pdmclkdat_default_mode: pdmclkdat_default {
+			pdmclkdat_default_mux {
+				ste,function = "pdm";
+				ste,pins = "pdmclkdat_d_1";
+			};
+			pdmclkdat_default_cfg {
+				ste,pins = "GPIO55", "GPIO56";
+				bias-disable;
+			};
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/powerpc/4xx/emac.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/powerpc/4xx/emac.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/powerpc/4xx/emac.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
     4xx/Axon EMAC ethernet nodes
 
     The EMAC ethernet controller in IBM and AMCC 4xx chips, and also
-    the Axon bridge.  To operate this needs to interact with a ths
+    the Axon bridge.  To operate this needs to interact with a this
     special McMAL DMA controller, and sometimes an RGMII or ZMII
     interface.  In addition to the nodes and properties described
     below, the node for the OPB bus on which the EMAC sits must have a
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/powerpc/fsl/interlaken-lac.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/powerpc/fsl/interlaken-lac.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/powerpc/fsl/interlaken-lac.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/powerpc/fsl/interlaken-lac.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,309 @@
+===============================================================================
+Freescale Interlaken Look-Aside Controller Device Bindings
+Copyright 2012 Freescale Semiconductor Inc.
+
+CONTENTS
+  - Interlaken Look-Aside Controller (LAC) Node
+  - Example LAC Node
+  - Interlaken Look-Aside Controller (LAC) Software Portal Node
+  - Interlaken Look-Aside Controller (LAC) Software Portal Child Nodes
+  - Example LAC SWP Node with Child Nodes
+
+==============================================================================
+Interlaken Look-Aside Controller (LAC) Node
+
+DESCRIPTION
+
+The Interlaken is a narrow, high speed channelized chip-to-chip interface. To
+facilitate interoperability between a data path device and a look-aside
+co-processor, the Interlaken Look-Aside protocol is defined for short
+transaction-related transfers. Although based on the Interlaken protocol,
+Interlaken Look-Aside is not directly compatible with Interlaken and can be
+considered a different operation mode.
+
+The Interlaken LA controller connects internal platform to Interlaken serial
+interface. It accepts LA command through software portals, which are system
+memory mapped 4KB spaces. The LA commands are then translated into the
+Interlaken control words and data words, which are sent on TX side to TCAM
+through SerDes lanes.
+
+There are two 4KiB spaces defined within the LAC global register memory map.
+There is a full register set at 0x0000-0x0FFF (also known as the "hypervisor"
+version), and a subset at 0x1000-0x1FFF.  The former is a superset of the
+latter, and includes certain registers that should not be accessible to
+partitioned software.  Separate nodes are used for each region, with a phandle
+linking the hypervisor node to the normal operating node.
+
+PROPERTIES
+
+  - compatible
+	Usage: required
+	Value type: <string>
+	Definition: Must include "fsl,interlaken-lac". This represents only
+		those LAC CCSR registers not protected in partitioned
+		software. The version of the device is determined by the LAC
+		IP Block Revision Register (IPBRR0) at offset 0x0BF8.
+
+		Table of correspondences between IPBRR0 values and example
+		chips:
+			Value		Device
+			-----------	-------
+			0x02000100	T4240
+
+		The Hypervisor node has a different compatible. It must include
+		"fsl,interlaken-lac-hv". This node represents the protected
+		LAC register space and is required except inside a partition
+		where access to the hypervisor node is to be denied.
+
+  - fsl,non-hv-node
+	Usage: required in "fsl,interlaken-lac-hv"
+	Value type: <phandle>
+	Definition: Points to the non-protected LAC CCSR mapped register space
+		node.
+
+  - reg
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: A standard property. The first resource represents the
+		Interlaken LAC configuration registers.
+
+  - interrupts:
+	Usage: required in non-hv node only
+	Value type: <prop-encoded-array>
+	Definition: Interrupt mapping for Interlaken LAC error IRQ.
+
+EXAMPLE
+	lac: lac@229000 {
+		compatible = "fsl,interlaken-lac"
+		reg = <0x229000 0x1000>;
+		interrupts = <16 2 1 18>;
+	};
+
+	lac-hv@228000 {
+		compatible = "fsl,interlaken-lac-hv"
+		reg = <0x228000 0x1000>;
+		fsl,non-hv-node = <&lac>;
+	};
+
+===============================================================================
+Interlaken Look-Aside Controller (LAC) Software Portal Container Node
+
+DESCRIPTION
+The Interlaken Look-Aside Controller (LAC) utilizes Software Portals to accept
+Interlaken Look-Aside (ILA) commands. The Interlaken LAC software portal
+memory map occupies 128KB of memory space. The software portal memory space is
+intended to be cache-enabled. WIMG for each software space is required to be
+0010 if stashing is enabled; otherwise, WIMG can be 0000 or 0010.
+
+PROPERTIES
+
+  - #address-cells
+	Usage: required
+	Value type: <u32>
+	Definition: A standard property. Must have a value of 1.
+
+  - #size-cells
+	Usage: required
+	Value type: <u32>
+	Definition: A standard property. Must have a value of 1.
+
+  - compatible
+	Usage: required
+	Value type: <string>
+	Definition: Must include "fsl,interlaken-lac-portals"
+
+  - ranges
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: A standard property. Specifies the address and length
+		of the LAC portal memory space.
+
+===============================================================================
+Interlaken Look-Aside Controller (LAC) Software Portals Child Nodes
+
+DESCRIPTION
+There are up to 24 available software portals with each software portal
+requiring 4KB of consecutive memory within the software portal memory mapped
+space.
+
+PROPERTIES
+
+  - compatible
+	Usage: required
+	Value type: <string>
+	Definition: Must include "fsl,interlaken-lac-portal-vX.Y" where X is
+		the Major version (IP_MJ) found in the LAC IP Block Revision
+		Register (IPBRR0), at offset 0x0BF8, and Y is the Minor version
+		(IP_MN).
+
+		Table of correspondences between version values and example chips:
+		    Value	Device
+		    ------	-------
+		      1.0	T4240
+
+  - reg
+	Usage: required
+	Value type: <prop-encoded-array>
+	Definition: A standard property.  The first resource represents the
+		Interlaken LAC software portal registers.
+
+  - fsl,liodn
+	Value type: <u32>
+	Definition: The logical I/O device number (LIODN) for this device.  The
+		LIODN is a number expressed by this device and used to perform
+		look-ups in the IOMMU (PAMU) address table when performing
+		DMAs. This property is automatically added by u-boot.
+
+===============================================================================
+EXAMPLE
+
+lac-portals {
+	#address-cells = <0x1>;
+	#size-cells = <0x1>;
+	compatible = "fsl,interlaken-lac-portals";
+	ranges = <0x0 0xf 0xf4400000 0x20000>;
+
+	lportal0: lac-portal@0 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x204>;
+		reg = <0x0 0x1000>;
+	};
+
+	lportal1: lac-portal@1000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x205>;
+		reg = <0x1000 0x1000>;
+	};
+
+	lportal2: lac-portal@2000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x206>;
+		reg = <0x2000 0x1000>;
+	};
+
+	lportal3: lac-portal@3000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x207>;
+		reg = <0x3000 0x1000>;
+	};
+
+	lportal4: lac-portal@4000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x208>;
+		reg = <0x4000 0x1000>;
+	};
+
+	lportal5: lac-portal@5000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x209>;
+		reg = <0x5000 0x1000>;
+	};
+
+	lportal6: lac-portal@6000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x20A>;
+		reg = <0x6000 0x1000>;
+	};
+
+	lportal7: lac-portal@7000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x20B>;
+		reg = <0x7000 0x1000>;
+	};
+
+	lportal8: lac-portal@8000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x20C>;
+		reg = <0x8000 0x1000>;
+	};
+
+	lportal9: lac-portal@9000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x20D>;
+		reg = <0x9000 0x1000>;
+	};
+
+	lportal10: lac-portal@A000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x20E>;
+		reg = <0xA000 0x1000>;
+	};
+
+	lportal11: lac-portal@B000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x20F>;
+		reg = <0xB000 0x1000>;
+	};
+
+	lportal12: lac-portal@C000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x210>;
+		reg = <0xC000 0x1000>;
+	};
+
+	lportal13: lac-portal@D000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x211>;
+		reg = <0xD000 0x1000>;
+	};
+
+	lportal14: lac-portal@E000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x212>;
+		reg = <0xE000 0x1000>;
+	};
+
+	lportal15: lac-portal@F000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x213>;
+		reg = <0xF000 0x1000>;
+	};
+
+	lportal16: lac-portal@10000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x214>;
+		reg = <0x10000 0x1000>;
+	};
+
+	lportal17: lac-portal@11000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x215>;
+		reg = <0x11000 0x1000>;
+	};
+
+	lportal8: lac-portal@1200 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x216>;
+		reg = <0x12000 0x1000>;
+	};
+
+	lportal19: lac-portal@13000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x217>;
+		reg = <0x13000 0x1000>;
+	};
+
+	lportal20: lac-portal@14000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x218>;
+		reg = <0x14000 0x1000>;
+	};
+
+	lportal21: lac-portal@15000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x219>;
+		reg = <0x15000 0x1000>;
+	};
+
+	lportal22: lac-portal@16000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x21A>;
+		reg = <0x16000 0x1000>;
+	};
+
+	lportal23: lac-portal@17000 {
+		compatible = "fsl,interlaken-lac-portal-v1.0";
+		fsl,liodn = <0x21B>;
+		reg = <0x17000 0x1000>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,44 @@
+Binding for TI/National Semiconductor LP8727 Charger
+
+Required properties:
+- compatible: "ti,lp8727"
+- reg: I2C slave address 27h
+
+Optional properties:
+- interrupt-parent: interrupt controller node (see interrupt binding[0])
+- interrupts: interrupt specifier (see interrupt binding[0])
+- debounce-ms: interrupt debounce time. (u32)
+
+AC and USB charging parameters
+- charger-type: "ac" or "usb" (string)
+- eoc-level: value of 'enum lp8727_eoc_level' (u8)
+- charging-current: value of 'enum lp8727_ichg' (u8)
+
+[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example)
+
+lp8727@27 {
+	compatible = "ti,lp8727";
+	reg = <0x27>;
+
+	/* GPIO 134 is used for LP8728 interrupt pin */
+	interrupt-parent = <&gpio5>; 	/* base = 128 */
+	interrupts = <6 0x2>;		/* offset = 6, falling edge type */
+
+	debounce-ms = <300>;
+
+	/* AC charger: 5% EOC and 500mA charging current */
+	ac {
+		charger-type = "ac";
+		eoc-level = /bits/ 8 <0>;
+		charging-current = /bits/ 8 <4>;
+	};
+
+	/* USB charger: 10% EOC and 400mA charging current */
+	usb {
+		charger-type = "usb";
+		eoc-level = /bits/ 8 <1>;
+		charging-current = /bits/ 8 <2>;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pps/pps-gpio.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pps/pps-gpio.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pps/pps-gpio.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pps/pps-gpio.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,20 @@
+Device-Tree Bindings for a PPS Signal on GPIO
+
+These properties describe a PPS (pulse-per-second) signal connected to
+a GPIO pin.
+
+Required properties:
+- compatible: should be "pps-gpio"
+- gpios: one PPS GPIO in the format described by ../gpio/gpio.txt
+
+Optional properties:
+- assert-falling-edge: when present, assert is indicated by a falling edge
+                       (instead of by a rising edge)
+
+Example:
+	pps {
+		compatible = "pps-gpio";
+		gpios = <&gpio2 6 0>;
+
+		assert-falling-edge;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/pwm/nxp,pca9685-pwm.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pwm/nxp,pca9685-pwm.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/pwm/nxp,pca9685-pwm.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/pwm/nxp,pca9685-pwm.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,27 @@
+NXP PCA9685 16-channel 12-bit PWM LED controller
+================================================
+
+Required properties:
+  - compatible: "nxp,pca9685-pwm"
+  - #pwm-cells: should be 2. The first cell specifies the per-chip index
+    of the PWM to use and the second cell is the period in nanoseconds.
+    The index 16 is the ALLCALL channel, that sets all PWM channels at the same
+    time.
+
+Optional properties:
+  - invert (bool): boolean to enable inverted logic
+  - open-drain (bool): boolean to configure outputs with open-drain structure;
+		       if omitted use totem-pole structure
+
+Example:
+
+For LEDs that are directly connected to the PCA, the following setting is
+applicable:
+
+pca: pca@41 {
+	compatible = "nxp,pca9685-pwm";
+	#pwm-cells = <2>;
+	reg = <0x41>;
+	invert;
+	open-drain;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/lp872x.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/lp872x.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/lp872x.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/lp872x.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,160 @@
+Binding for TI/National Semiconductor LP872x Driver
+
+Required properties:
+  - compatible: "ti,lp8720" or "ti,lp8725"
+  - reg: I2C slave address. 0x7d = LP8720, 0x7a = LP8725
+
+Optional properties:
+  - ti,general-config: the value of LP872X_GENERAL_CFG register (u8)
+    (LP8720)
+    bit[2]: BUCK output voltage control by external DVS pin or register
+            1 = external pin, 0 = bit7 of register 08h
+    bit[1]: sleep control by external DVS pin or register
+            1 = external pin, 0 = bit6 of register 08h
+    bit[0]: time step unit(usec). 1 = 25, 0 = 50
+
+    (LP8725)
+    bit[7:6]: time step unit(usec). 00 = 32, 01 = 64, 10 = 128, 11 = 256
+    bit[4]:   BUCK2 enable control. 1 = enable, 0 = disable
+    bit[3]:   BUCK2 output voltage register address. 1 = 0Ah, 0 = 0Bh
+    bit[2]:   BUCK1 output voltage control by external DVS pin or register
+              1 = register 08h, 0 = DVS
+    bit[1]:   LDO sleep control. 1 = sleep mode, 0 = normal
+    bit[0]:   BUCK1 enable control, 1 = enable, 0 = disable
+
+    For more details, please see the datasheet.
+
+  - ti,update-config: define it when LP872X_GENERAL_CFG register should be set
+  - ti,dvs-gpio: GPIO specifier for external DVS pin control of LP872x devices.
+  - ti,dvs-vsel: DVS selector. 0 = SEL_V1, 1 = SEL_V2.
+  - ti,dvs-state: initial DVS pin state. 0 = DVS_LOW, 1 = DVS_HIGH.
+
+  Sub nodes for regulator_init_data
+    LP8720 has maximum 6 nodes. (child name: ldo1 ~ 5 and buck)
+    LP8725 has maximum 9 nodes. (child name: ldo1 ~ 5, lilo1,2 and buck1,2)
+    For more details, please see the following binding document.
+    (Documentation/devicetree/bindings/regulator/regulator.txt)
+
+Datasheet
+  - LP8720: http://www.ti.com/lit/ds/symlink/lp8720.pdf
+  - LP8725: http://www.ti.com/lit/ds/symlink/lp8725.pdf
+
+Example 1) LP8720
+
+lp8720@7d {
+	compatible = "ti,lp8720";
+	reg = <0x7d>;
+
+	/* external DVS pin used, timestep is 25usec */
+	ti,general-config = /bits/ 8 <0x03>;
+	ti,update-config;
+
+	/*
+	 * The dvs-gpio depends on the processor environment.
+	 * For example, following GPIO specifier means GPIO134 in OMAP4.
+	 */
+	ti,dvs-gpio = <&gpio5 6 0>;
+	ti,dvs-vsel = /bits/ 8 <1>;		/* SEL_V2 */
+	ti,dvs-state = /bits/ 8 <1>;		/* DVS_HIGH */
+
+	vaf: ldo1 {
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vmmc: ldo2 {
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcam_io: ldo3 {
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+	};
+
+	vcam_core: ldo4 {
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <2850000>;
+		regulator-boot-on;
+	};
+
+	vcam: ldo5 {
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcc: buck {
+		regulator-name = "VBUCK";
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <2300000>;
+	};
+};
+
+Example 2) LP8725
+
+lp8725@7a {
+	compatible = "ti,lp8725";
+	reg = <0x7a>;
+
+	/* Enable BUCK1,2, no DVS, normal LDO mode, timestep is 256usec */
+	ti,general-config = /bits/ 8 <0xdd>;
+	ti,update-config;
+
+	vcam_io: ldo1 {
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcam_core: ldo2 {
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcam: ldo3 {
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcmmb_io: ldo4 {
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+	};
+
+	vcmmb_core: ldo5 {
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+	};
+
+	vaux1: lilo1 {
+		regulator-name = "VAUX1";
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vaux2: lilo2 {
+		regulator-name = "VAUX2";
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	vcc1: buck1 {
+		regulator-name = "VBUCK1";
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <3000000>;
+		regulator-min-microamp  = <460000>;
+		regulator-max-microamp  = <1370000>;
+		regulator-boot-on;
+	};
+
+	vcc2: buck2 {
+		regulator-name = "VBUCK2";
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <3000000>;
+		regulator-min-microamp  = <460000>;
+		regulator-max-microamp  = <1370000>;
+		regulator-boot-on;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/max8973-regulator.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/max8973-regulator.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/max8973-regulator.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,21 @@
+* Maxim MAX8973 Voltage Regulator
+
+Required properties:
+
+- compatible:	must be "maxim,max8973"
+- reg:		the i2c slave address of the regulator. It should be 0x1b.
+
+Any standard regulator properties can be used to configure the single max8973
+DCDC.
+
+Example:
+
+	max8973@1b {
+		compatible = "maxim,max8973";
+		reg = <0x1b>;
+
+		regulator-min-microvolt = <935000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/max8997-regulator.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/max8997-regulator.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/max8997-regulator.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/max8997-regulator.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 * Maxim MAX8997 Voltage and Current Regulator
 
-The Maxim MAX8997 is a multi-function device which includes volatage and
+The Maxim MAX8997 is a multi-function device which includes voltage and
 current regulators, rtc, charger controller and other sub-blocks. It is
 interfaced to the host controller using a i2c interface. Each sub-block is
 addressed by the host system using different i2c slave address. This document
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/palmas-pmic.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/palmas-pmic.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/palmas-pmic.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/palmas-pmic.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,70 @@
+* palmas regulator IP block devicetree bindings
+
+Required properties:
+- compatible : Should be from the list
+  ti,twl6035-pmic
+  ti,twl6036-pmic
+  ti,twl6037-pmic
+  ti,tps65913-pmic
+  ti,tps65914-pmic
+and also the generic series names
+  ti,palmas-pmic
+- interrupt-parent : The parent interrupt controller which is palmas.
+- interrupts : The interrupt number and the type which can be looked up here:
+	       arch/arm/boot/dts/include/dt-bindings/interrupt-controller/irq.h
+- interrupts-name: The names of the individual interrupts.
+
+Optional properties:
+- ti,ldo6-vibrator : ldo6 is in vibrator mode
+
+Optional nodes:
+- regulators : Must contain a sub-node per regulator from the list below.
+	       Each sub-node should contain the constraints and initialization
+	       information for that regulator. See regulator.txt for a
+	       description of standard properties for these sub-nodes.
+	       Additional custom properties  are listed below.
+
+	       For ti,palmas-pmic - smps12, smps123, smps3 depending on OTP,
+	       smps45, smps457, smps7 depending on variant, smps6, smps[8-10],
+	       ldo[1-9], ldoln, ldousb.
+
+	       Optional sub-node properties:
+	       ti,warm-reset - maintain voltage during warm reset(boolean)
+	       ti,roof-floor - control voltage selection by pin(boolean)
+	       ti,mode-sleep - mode to adopt in pmic sleep 0 - off, 1 - auto,
+	       2 - eco, 3 - forced pwm
+	       ti,smps-range - OTP has the wrong range set for the hardware so override
+	       0 - low range, 1 - high range.
+
+Example:
+
+#include <dt-bindings/interrupt-controller/irq.h>
+
+pmic {
+	compatible = "ti,twl6035-pmic", "ti,palmas-pmic";
+	interrupt-parent = <&palmas>;
+	interrupts = <14 IRQ_TYPE_NONE>;
+	interrupts-name = "short-irq";
+
+	ti,ldo6-vibrator;
+
+	regulators {
+		smps12_reg : smps12 {
+			regulator-name = "smps12";
+			regulator-min-microvolt = < 600000>;
+			regulator-max-microvolt = <1500000>;
+			regulator-always-on;
+			regulator-boot-on;
+			ti,warm-reset;
+			ti,roof-floor;
+			ti,mode-sleep = <0>;
+			ti,smps-range = <1>;
+		};
+
+		ldo1_reg: ldo1 {
+			regulator-name = "ldo1";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/regulator.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/regulator.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/regulator.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/regulator.txt	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,7 @@ Optional properties:
 - regulator-max-microamp: largest current consumers may set
 - regulator-always-on: boolean, regulator should never be disabled
 - regulator-boot-on: bootloader/firmware enabled regulator
+- regulator-allow-bypass: allow the regulator to go into bypass mode
 - <name>-supply: phandle to the parent supply/regulator node
 - regulator-ramp-delay: ramp delay for regulator(in uV/uS)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 * Samsung S5M8767 Voltage and Current Regulator
 
-The Samsung S5M8767 is a multi-function device which includes volatage and
+The Samsung S5M8767 is a multi-function device which includes voltage and
 current regulators, rtc, charger controller and other sub-blocks. It is
 interfaced to the host controller using a i2c interface. Each sub-block is
 addressed by the host system using different i2c slave address. This document
@@ -103,13 +103,13 @@ Example:
 
 		s5m8767,pmic-buck-default-dvs-idx = <0>;
 
-		s5m8767,pmic-buck-dvs-gpios = <&gpx0 0 1 0 0>, /* DVS1 */
-						 <&gpx0 1 1 0 0>, /* DVS2 */
-						 <&gpx0 2 1 0 0>; /* DVS3 */
+		s5m8767,pmic-buck-dvs-gpios = <&gpx0 0 0>, /* DVS1 */
+						 <&gpx0 1 0>, /* DVS2 */
+						 <&gpx0 2 0>; /* DVS3 */
 
-		s5m8767,pmic-buck-ds-gpios = <&gpx2 3 1 0 0>, /* SET1 */
-						<&gpx2 4 1 0 0>, /* SET2 */
-						<&gpx2 5 1 0 0>; /* SET3 */
+		s5m8767,pmic-buck-ds-gpios = <&gpx2 3 0>, /* SET1 */
+						<&gpx2 4 0>, /* SET2 */
+						<&gpx2 5 0>; /* SET3 */
 
 		s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>,
 						 <1250000>, <1200000>,
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/ti-abb-regulator.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,128 @@
+Adaptive Body Bias(ABB) SoC internal LDO regulator for Texas Instruments SoCs
+
+Required Properties:
+- compatible: Should be one of:
+  - "ti,abb-v1" for older SoCs like OMAP3
+  - "ti,abb-v2" for newer SoCs like OMAP4, OMAP5
+- reg: Address and length of the register set for the device. It contains
+  the information of registers in the same order as described by reg-names
+- reg-names: Should contain the reg names
+  - "base-address"	- contains base address of ABB module
+  - "int-address"	- contains address of interrupt register for ABB module
+  (also see Optional properties)
+- #address-cell: should be 0
+- #size-cell: should be 0
+- clocks: should point to the clock node used by ABB module
+- ti,settling-time: Settling time in uSecs from SoC documentation for ABB module
+	to settle down(target time for SR2_WTCNT_VALUE).
+- ti,clock-cycles: SoC specific data about count of system ti,clock-cycles used for
+	computing settling time from SoC Documentation for ABB module(clock
+	cycles for SR2_WTCNT_VALUE).
+- ti,tranxdone-status-mask: Mask to the int-register to write-to-clear mask
+	indicating LDO tranxdone (operation complete).
+- ti,abb_info: An array of 6-tuples u32 items providing information about ABB
+	configuration needed per operational voltage of the device.
+	Each item consists of the following in the same order:
+	volt: voltage in uV - Only used to index ABB information.
+	ABB mode: one of the following:
+		0-bypass
+		1-Forward Body Bias(FBB)
+		3-Reverse Body Bias(RBB)
+	efuse:	(see Optional properties)
+	RBB enable efuse Mask:	(See Optional properties)
+	FBB enable efuse Mask:	(See Optional properties)
+	Vset value efuse Mask:	(See Optional properties)
+
+	NOTE: If more than 1 entry is present, then regulator is setup to change
+	      voltage, allowing for various modes to be selected indexed off
+	      the regulator. Further, ABB LDOs are considered always-on by
+	      default.
+
+Optional Properties:
+- reg-names: In addition to the required properties, the following are optional
+  - "efuse-address"	- Contains efuse base address used to pick up ABB info.
+  - "ldo-address"	- Contains address of ABB LDO overide register address.
+	"efuse-address" is required for this.
+- ti,ldovbb-vset-mask	- Required if ldo-address is set, mask for LDO override
+	register to provide override vset value.
+- ti,ldovbb-override-mask - Required if ldo-address is set, mask for LDO
+	override register to enable override vset value.
+- ti,abb_opp_sel: Addendum to the description in required properties
+	efuse: Mandatory if 'efuse-address' register is defined. Provides offset
+	       from efuse-address to pick up ABB characteristics. Set to 0 if
+	       'efuse-address' is not defined.
+	RBB enable efuse Mask:	Optional if 'efuse-address' register is defined.
+		'ABB mode' is force set to RBB mode if value at "efuse-address"
+		+ efuse maps to RBB mask. Set to 0 to ignore this.
+	FBB enable efuse Mask:	Optional if 'efuse-address' register is defined.
+		'ABB mode' is force set to FBB mode if value at "efuse-address"
+		+ efuse maps to FBB mask (valid only if RBB mask does not match)
+		Set to 0 to ignore this.
+	Vset value efuse Mask:	Mandatory if ldo-address is set. Picks up from
+		efuse the value to set in 'ti,ldovbb-vset-mask' at ldo-address.
+
+Example #1: Simplest configuration (no efuse data, hard coded ABB table):
+abb_x: regulator-abb-x {
+	compatible = "ti,abb-v1";
+	regulator-name = "abb_x";
+	#address-cell = <0>;
+	#size-cells = <0>;
+	reg = <0x483072f0 0x8>, <0x48306818 0x4>;
+	reg-names = "base-address", "int-address";
+	ti,tranxdone-status-mask = <0x4000000>;
+	clocks = <&sysclk>;
+	ti,settling-time = <30>;
+	ti,clock-cycles = <8>;
+	ti,abb_info = <
+	/* uV		ABB	efuse	rbb_m	fbb_m	vset_m */
+	1012500		0	0	0	0	0 /* Bypass */
+	1200000		3	0	0	0	0 /* RBB mandatory */
+	1320000		1	0	0	0	0 /* FBB mandatory */
+	>;
+};
+
+Example #2: Efuse bits contain ABB mode setting (no LDO override capability)
+abb_y: regulator-abb-y {
+	compatible = "ti,abb-v2";
+	regulator-name = "abb_y";
+	#address-cell = <0>;
+	#size-cells = <0>;
+	reg = <0x4a307bd0 0x8>, <0x4a306014 0x4>, <0x4A002268 0x8>;
+	reg-names = "base-address", "int-address", "efuse-address";
+	ti,tranxdone-status-mask = <0x4000000>;
+	clocks = <&sysclk>;
+	ti,settling-time = <50>;
+	ti,clock-cycles = <16>;
+	ti,abb_info = <
+	/* uV		ABB	efuse	rbb_m	fbb_m	vset_m */
+	975000		0	0	0	0	0 /* Bypass */
+	1012500		0	0	0x40000	0	0 /* RBB optional */
+	1200000		0	0x4	0	0x40000	0 /* FBB optional */
+	1320000		1	0	0	0	0 /* FBB mandatory */
+	>;
+};
+
+Example #3: Efuse bits contain ABB mode setting and LDO override capability
+abb_z: regulator-abb-z {
+	compatible = "ti,abb-v2";
+	regulator-name = "abb_z";
+	#address-cell = <0>;
+	#size-cells = <0>;
+	reg = <0x4ae07ce4 0x8>, <0x4ae06010 0x4>,
+	      <0x4a002194 0x8>, <0x4ae0C314 0x4>;
+	reg-names = "base-address", "int-address",
+		    "efuse-address", "ldo-address";
+	ti,tranxdone-status-mask = <0x8000000>;
+	/* LDOVBBMM_MUX_CTRL */
+	ti,ldovbb-override-mask = <0x400>;
+	/* LDOVBBMM_VSET_OUT */
+	ti,ldovbb-vset-mask = <0x1F>;
+	clocks = <&sysclk>;
+	ti,settling-time = <50>;
+	ti,clock-cycles = <16>;
+	ti,abb_info = <
+	/* uV	ABB	efuse	rbb_m	fbb_m	vset_m */
+	975000	0	0	0	0	0	/* Bypass */
+	1200000	0	0x4	0	0x40000	0x1f00	/* FBB optional, vset */
+	>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/twl-regulator.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/twl-regulator.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/regulator/twl-regulator.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/regulator/twl-regulator.txt	2013-08-25 20:43:22.000000000 -0400
@@ -18,20 +18,20 @@ For twl6030 regulators/LDOs
   - "ti,twl6030-vdd1" for VDD1 SMPS
   - "ti,twl6030-vdd2" for VDD2 SMPS
   - "ti,twl6030-vdd3" for VDD3 SMPS
-For twl6025 regulators/LDOs
+For twl6032 regulators/LDOs
 - compatible:
-  - "ti,twl6025-ldo1" for LDO1 LDO
-  - "ti,twl6025-ldo2" for LDO2 LDO
-  - "ti,twl6025-ldo3" for LDO3 LDO
-  - "ti,twl6025-ldo4" for LDO4 LDO
-  - "ti,twl6025-ldo5" for LDO5 LDO
-  - "ti,twl6025-ldo6" for LDO6 LDO
-  - "ti,twl6025-ldo7" for LDO7 LDO
-  - "ti,twl6025-ldoln" for LDOLN LDO
-  - "ti,twl6025-ldousb" for LDOUSB LDO
-  - "ti,twl6025-smps3" for SMPS3 SMPS
-  - "ti,twl6025-smps4" for SMPS4 SMPS
-  - "ti,twl6025-vio" for VIO SMPS
+  - "ti,twl6032-ldo1" for LDO1 LDO
+  - "ti,twl6032-ldo2" for LDO2 LDO
+  - "ti,twl6032-ldo3" for LDO3 LDO
+  - "ti,twl6032-ldo4" for LDO4 LDO
+  - "ti,twl6032-ldo5" for LDO5 LDO
+  - "ti,twl6032-ldo6" for LDO6 LDO
+  - "ti,twl6032-ldo7" for LDO7 LDO
+  - "ti,twl6032-ldoln" for LDOLN LDO
+  - "ti,twl6032-ldousb" for LDOUSB LDO
+  - "ti,twl6032-smps3" for SMPS3 SMPS
+  - "ti,twl6032-smps4" for SMPS4 SMPS
+  - "ti,twl6032-vio" for VIO SMPS
 For twl4030 regulators/LDOs
 - compatible:
   - "ti,twl4030-vaux1" for VAUX1 LDO
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/rtc/dw-apb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/rtc/dw-apb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/rtc/dw-apb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/rtc/dw-apb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -5,9 +5,20 @@ Required properties:
 - reg: physical base address of the controller and length of memory mapped
   region.
 - interrupts: IRQ line for the timer.
+- either clocks+clock-names or clock-frequency properties
+
+Optional properties:
+- clocks	: list of clock specifiers, corresponding to entries in
+		  the clock-names property;
+- clock-names	: should contain "timer" and "pclk" entries, matching entries
+		  in the clocks property.
 - clock-frequency: The frequency in HZ of the timer.
 - clock-freq: For backwards compatibility with picoxcell
 
+If using the clock specifiers, the pclk clock is optional, as not all
+systems may use one.
+
+
 Example:
 
 		timer1: timer@ffc09000 {
@@ -23,3 +34,11 @@ Example:
 				clock-frequency = <200000000>;
 				reg = <0xffd00000 0x1000>;
 			};
+
+		timer3: timer@ffe00000 {
+				compatible = "snps,dw-apb-timer-osc";
+				interrupts = <0 170 4>;
+				reg = <0xffe00000 0x1000>;
+				clocks = <&timer_clk>, <&timer_pclk>;
+				clock-names = "timer", "pclk";
+			};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/serio/olpc,ap-sp.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/serio/olpc,ap-sp.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/serio/olpc,ap-sp.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/serio/olpc,ap-sp.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,13 @@
+OLPC AP-SP serio interface
+
+Required properties:
+- compatible : "olpc,ap-sp"
+- reg : base address and length of SoC's WTM registers
+- interrupts : SP-AP interrupt
+
+Example:
+	ap-sp@d4290000 {
+		compatible = "olpc,ap-sp";
+		reg = <0xd4290000 0x1000>;
+		interrupts = <40>;
+	}
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/adi,adau1701.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/adi,adau1701.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/adi,adau1701.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/adi,adau1701.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,35 @@
+Analog Devices ADAU1701
+
+Required properties:
+
+ - compatible:		Should contain "adi,adau1701"
+ - reg:			The i2c address. Value depends on the state of ADDR0
+			and ADDR1, as wired in hardware.
+
+Optional properties:
+
+ - reset-gpio: 		A GPIO spec to define which pin is connected to the
+			chip's !RESET pin. If specified, the driver will
+			assert a hardware reset at probe time.
+ - adi,pll-mode-gpios:	An array of two GPIO specs to describe the GPIOs
+			the ADAU's PLL config pins are connected to.
+			The state of the pins are set according to the
+			configured clock divider on ASoC side before the
+			firmware is loaded.
+ - adi,pin-config:	An array of 12 numerical values selecting one of the
+			pin configurations as described in the datasheet,
+			table 53. Note that the value of this property has
+			to be prefixed with '/bits/ 8'.
+
+Examples:
+
+	i2c_bus {
+		adau1701@34 {
+			compatible = "adi,adau1701";
+			reg = <0x34>;
+			reset-gpio = <&gpio 23 0>;
+			adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>;
+			adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4
+                                                   0x4 0x4 0x4 0x4 0x4 0x4>;
+		};
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,46 @@
+Freescale i.MX audio complex with WM8962 codec
+
+Required properties:
+- compatible : "fsl,imx-audio-wm8962"
+- model : The user-visible name of this sound complex
+- ssi-controller : The phandle of the i.MX SSI controller
+- audio-codec : The phandle of the WM8962 audio codec
+- audio-routing : A list of the connections between audio components.
+  Each entry is a pair of strings, the first being the connection's sink,
+  the second being the connection's source. Valid names could be power
+  supplies, WM8962 pins, and the jacks on the board:
+
+  Power supplies:
+   * Mic Bias
+
+  Board connectors:
+   * Mic Jack
+   * Headphone Jack
+   * Ext Spk
+
+- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
+- mux-ext-port : The external port of the i.MX audio muxer
+
+Note: The AUDMUX port numbering should start at 1, which is consistent with
+hardware manual.
+
+Example:
+
+sound {
+	compatible = "fsl,imx6q-sabresd-wm8962",
+		     "fsl,imx-audio-wm8962";
+	model = "wm8962-audio";
+	ssi-controller = <&ssi2>;
+	audio-codec = <&codec>;
+		audio-routing =
+		"Headphone Jack", "HPOUTL",
+		"Headphone Jack", "HPOUTR",
+		"Ext Spk", "SPKOUTL",
+		"Ext Spk", "SPKOUTR",
+		"MICBIAS", "AMIC",
+		"IN3R", "MICBIAS",
+		"DMIC", "MICBIAS",
+		"DMICDAT", "DMIC";
+	mux-int-port = <2>;
+	mux-ext-port = <3>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/mxs-saif.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/mxs-saif.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/mxs-saif.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/mxs-saif.txt	2013-08-25 20:43:22.000000000 -0400
@@ -3,8 +3,11 @@
 Required properties:
 - compatible: Should be "fsl,<chip>-saif"
 - reg: Should contain registers location and length
-- interrupts: Should contain ERROR and DMA interrupts
-- fsl,saif-dma-channel: APBX DMA channel for the SAIF
+- interrupts: Should contain ERROR interrupt number
+- dmas: DMA specifier, consisting of a phandle to DMA controller node
+  and SAIF DMA channel ID.
+  Refer to dma.txt and fsl-mxs-dma.txt for details.
+- dma-names: Must be "rx-tx".
 
 Optional properties:
 - fsl,saif-master: phandle to the master SAIF.  It's only required for
@@ -23,14 +26,16 @@ aliases {
 saif0: saif@80042000 {
 	compatible = "fsl,imx28-saif";
 	reg = <0x80042000 2000>;
-	interrupts = <59 80>;
-	fsl,saif-dma-channel = <4>;
+	interrupts = <59>;
+	dmas = <&dma_apbx 4>;
+	dma-names = "rx-tx";
 };
 
 saif1: saif@80046000 {
 	compatible = "fsl,imx28-saif";
 	reg = <0x80046000 2000>;
-	interrupts = <58 81>;
-	fsl,saif-dma-channel = <5>;
+	interrupts = <58>;
+	dmas = <&dma_apbx 5>;
+	dma-names = "rx-tx";
 	fsl,saif-master = <&saif0>;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,71 @@
+NVIDIA Tegra audio complex, with RT5640 CODEC
+
+Required properties:
+- compatible : "nvidia,tegra-audio-rt5640"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+  "pll_a" (The Tegra clock of that name),
+  "pll_a_out0" (The Tegra clock of that name),
+  "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
+- nvidia,model : The user-visible name of this sound complex.
+- nvidia,audio-routing : A list of the connections between audio components.
+  Each entry is a pair of strings, the first being the connection's sink,
+  the second being the connection's source. Valid names for sources and
+  sinks are the RT5640's pins, and the jacks on the board:
+
+  RT5640 pins:
+
+  * DMIC1
+  * DMIC2
+  * MICBIAS1
+  * IN1P
+  * IN1R
+  * IN2P
+  * IN2R
+  * HPOL
+  * HPOR
+  * LOUTL
+  * LOUTR
+  * MONOP
+  * MONON
+  * SPOLP
+  * SPOLN
+  * SPORP
+  * SPORN
+
+  Board connectors:
+
+  * Headphones
+  * Speakers
+
+- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's
+  connected to the CODEC.
+- nvidia,audio-codec : The phandle of the RT5640 audio codec. This binding
+  assumes that AIF1 on the CODEC is connected to Tegra.
+
+Optional properties:
+- nvidia,hp-det-gpios : The GPIO that detects headphones are plugged in
+
+Example:
+
+sound {
+	compatible = "nvidia,tegra-audio-rt5640-dalmore",
+			"nvidia,tegra-audio-rt5640";
+	nvidia,model = "NVIDIA Tegra Dalmore";
+
+	nvidia,audio-routing =
+		"Headphones", "HPOR",
+		"Headphones", "HPOL",
+		"Speakers", "SPORP",
+		"Speakers", "SPORN",
+		"Speakers", "SPOLP",
+		"Speakers", "SPOLN";
+
+	nvidia,i2s-controller = <&tegra_i2s1>;
+	nvidia,audio-codec = <&rt5640>;
+
+	nvidia,hp-det-gpios = <&gpio 143 0>; /* GPIO PR7 */
+
+	clocks = <&tegra_car 216>, <&tegra_car 217>, <&tegra_car 120>;
+	clock-names = "pll_a", "pll_a_out0", "mclk";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/rt5640.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/rt5640.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/rt5640.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/rt5640.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,30 @@
+RT5640 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+- compatible : "realtek,rt5640".
+
+- reg : The I2C address of the device.
+
+- interrupts : The CODEC's interrupt output.
+
+Optional properties:
+
+- realtek,in1-differential
+- realtek,in2-differential
+  Boolean. Indicate MIC1/2 input are differential, rather than single-ended.
+
+- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
+
+Example:
+
+rt5640 {
+	compatible = "realtek,rt5640";
+	reg = <0x1c>;
+	interrupt-parent = <&gpio>;
+	interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
+	realtek,ldo1-en-gpios =
+		<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/samsung-i2s.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/samsung-i2s.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/samsung-i2s.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/samsung-i2s.txt	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,16 @@ Required SoC Specific Properties:
 - dmas: list of DMA controller phandle and DMA request line ordered pairs.
 - dma-names: identifier string for each DMA request line in the dmas property.
   These strings correspond 1:1 with the ordered pairs in dmas.
+- clocks: Handle to iis clock and RCLK source clk.
+- clock-names:
+  i2s0 uses some base clks from CMU and some are from audio subsystem internal
+  clock controller. The clock names for i2s0 should be "iis", "i2s_opclk0" and
+  "i2s_opclk1" as shown in the example below.
+  i2s1 and i2s2 uses clocks from CMU. The clock names for i2s1 and i2s2 should
+  be "iis" and "i2s_opclk0".
+  "iis" is the i2s bus clock and i2s_opclk0, i2s_opclk1 are sources of the root
+  clk. i2s0 has internal mux to select the source of root clk and i2s1 and i2s2
+  doesn't have any such mux.
 
 Optional SoC Specific Properties:
 
@@ -20,44 +30,26 @@ Optional SoC Specific Properties:
   then this flag is enabled.
 - samsung,idma-addr: Internal DMA register base address of the audio
   sub system(used in secondary sound source).
-
-Required Board Specific Properties:
-
-- gpios: The gpio specifier for data out,data in, LRCLK, CDCLK and SCLK
-  interface lines. The format of the gpio specifier depends on the gpio
-  controller.
-  The syntax of samsung gpio specifier is
-	<[phandle of the gpio controller node]
-	 [pin number within the gpio controller]
-	 [mux function]
-	 [flags and pull up/down]
-	 [drive strength]>
+- pinctrl-0: Should specify pin control groups used for this controller.
+- pinctrl-names: Should contain only one value - "default".
 
 Example:
 
-- SoC Specific Portion:
-
-i2s@03830000 {
+i2s0: i2s@03830000 {
 	compatible = "samsung,i2s-v5";
 	reg = <0x03830000 0x100>;
 	dmas = <&pdma0 10
 		&pdma0 9
 		&pdma0 8>;
 	dma-names = "tx", "rx", "tx-sec";
+	clocks = <&clock_audss EXYNOS_I2S_BUS>,
+		<&clock_audss EXYNOS_I2S_BUS>,
+		<&clock_audss EXYNOS_SCLK_I2S>;
+	clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
 	samsung,supports-6ch;
 	samsung,supports-rstclr;
 	samsung,supports-secdai;
 	samsung,idma-addr = <0x03000000>;
-};
-
-- Board Specific Portion:
-
-i2s@03830000 {
-	gpios = <&gpz 0 2 0 0>, /* I2S_0_SCLK */
-		<&gpz 1 2 0 0>, /* I2S_0_CDCLK */
-		<&gpz 2 2 0 0>, /* I2S_0_LRCK */
-		<&gpz 3 2 0 0>, /* I2S_0_SDI */
-		<&gpz 4 2 0 0>, /* I2S_0_SDO[1] */
-		<&gpz 5 2 0 0>, /* I2S_0_SDO[2] */
-		<&gpz 6 2 0 0>; /* I2S_0_SDO[3] */
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s0_bus>;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/sgtl5000.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/sgtl5000.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/sgtl5000.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/sgtl5000.txt	2013-08-25 20:43:22.000000000 -0400
@@ -5,9 +5,12 @@ Required properties:
 
 - reg : the I2C address of the device
 
+- clocks : the clock provider of SYS_MCLK
+
 Example:
 
 codec: sgtl5000@0a {
 	compatible = "fsl,sgtl5000";
 	reg = <0x0a>;
+	clocks = <&clks 150>;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/spdif-receiver.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/spdif-receiver.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/spdif-receiver.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/spdif-receiver.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+Device-Tree bindings for dummy spdif receiver
+
+Required properties:
+	- compatible: should be "linux,spdif-dir".
+
+Example node:
+
+	codec: spdif-receiver {
+		compatible = "linux,spdif-dir";
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/spdif-transmitter.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/spdif-transmitter.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/spdif-transmitter.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/spdif-transmitter.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+Device-Tree bindings for dummy spdif transmitter
+
+Required properties:
+	- compatible: should be "linux,spdif-dit".
+
+Example node:
+
+	codec: spdif-transmitter {
+		compatible = "linux,spdif-dit";
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/ssm2518.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/ssm2518.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/ssm2518.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/ssm2518.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,20 @@
+SSM2518 audio amplifier
+
+This device supports I2C only.
+
+Required properties:
+  - compatible : Must be "adi,ssm2518"
+  - reg : the I2C address of the device. This will either be 0x34 (ADDR pin low)
+	or 0x35 (ADDR pin high)
+
+Optional properties:
+  - gpios : GPIO connected to the nSD pin. If the property is not present it is
+	        assumed that the nSD pin is hardwired to always on.
+
+Example:
+
+	ssm2518: ssm2518@34 {
+		compatible = "adi,ssm2518";
+		reg = <0x34>;
+		gpios = <&gpio 5 0>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/ti,tas5086.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/ti,tas5086.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/ti,tas5086.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/ti,tas5086.txt	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,17 @@ Optional properties:
 			When not specified, the hardware default of 1300ms
 			is retained.
 
+ - ti,mid-z-channel-X:	Boolean properties, X being a number from 1 to 6.
+			If given, channel X will start with the Mid-Z start
+			sequence, otherwise the default Low-Z scheme is used.
+
+			The correct configuration depends on how the power
+			stages connected to the PWM output pins work. Not all
+			power stages are compatible to Mid-Z - please refer
+			to the datasheets for more details.
+
+			Most systems should not set any of these properties.
+
 Examples:
 
 	i2c_bus {
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/wm8962.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/wm8962.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/sound/wm8962.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/sound/wm8962.txt	2013-08-25 20:43:22.000000000 -0400
@@ -8,9 +8,32 @@ Required properties:
 
   - reg : the I2C address of the device.
 
+Optional properties:
+  - spk-mono: This is a boolean property. If present, the SPK_MONO bit
+    of R51 (Class D Control 2) gets set, indicating that the speaker is
+    in mono mode.
+
+  - mic-cfg : Default register value for R48 (Additional Control 4).
+    If absent, the default should be the register default.
+
+  - gpio-cfg : A list of GPIO configuration register values. The list must
+    be 6 entries long. If absent, no configuration of these registers is
+    performed. And note that only the value within [0x0, 0xffff] is valid.
+    Any other value is regarded as setting the GPIO register by its reset
+    value 0x0.
+
 Example:
 
 codec: wm8962@1a {
 	compatible = "wlf,wm8962";
 	reg = <0x1a>;
+
+	gpio-cfg = <
+		0x0000 /* 0:Default */
+		0x0000 /* 1:Default */
+		0x0013 /* 2:FN_DMICCLK */
+		0x0000 /* 3:Default */
+		0x8014 /* 4:FN_DMICCDAT */
+		0x0000 /* 5:Default */
+	>;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/spi/brcm,bcm2835-spi.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/spi/brcm,bcm2835-spi.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/spi/brcm,bcm2835-spi.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/spi/brcm,bcm2835-spi.txt	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,7 @@ Broadcom BCM2835 SPI0 controller
 
 The BCM2835 contains two forms of SPI master controller, one known simply as
 SPI0, and the other known as the "Universal SPI Master"; part of the
-auxilliary block. This binding applies to the SPI0 controller.
+auxiliary block. This binding applies to the SPI0 controller.
 
 Required properties:
 - compatible: Should be "brcm,bcm2835-spi".
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/spi/omap-spi.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/spi/omap-spi.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/spi/omap-spi.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/spi/omap-spi.txt	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,18 @@ Required properties:
 			  input. The default is D0 as input and
 			  D1 as output.
 
-Example:
+Optional properties:
+- dmas: List of DMA specifiers with the controller specific format
+	as described in the generic DMA client binding. A tx and rx
+	specifier is required for each chip select.
+- dma-names: List of DMA request names. These strings correspond
+	1:1 with the DMA specifiers listed in dmas. The string naming
+	is to be "rxN" and "txN" for RX and TX requests,
+	respectively, where N equals the chip select number.
+
+Examples:
+
+[hwmod populated DMA resources]
 
 mcspi1: mcspi@1 {
     #address-cells = <1>;
@@ -20,3 +31,17 @@ mcspi1: mcspi@1 {
     ti,spi-num-cs = <4>;
 };
 
+[generic DMA request binding]
+
+mcspi1: mcspi@1 {
+    #address-cells = <1>;
+    #size-cells = <0>;
+    compatible = "ti,omap4-mcspi";
+    ti,hwmods = "mcspi1";
+    ti,spi-num-cs = <2>;
+    dmas = <&edma 42
+	    &edma 43
+	    &edma 44
+	    &edma 45>;
+    dma-names = "tx0", "rx0", "tx1", "rx1";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,99 @@
+Device-Tree bindings for LVDS Display Bridge (ldb)
+
+LVDS Display Bridge
+===================
+
+The LVDS Display Bridge device tree node contains up to two lvds-channel
+nodes describing each of the two LVDS encoder channels of the bridge.
+
+Required properties:
+ - #address-cells : should be <1>
+ - #size-cells : should be <0>
+ - compatible : should be "fsl,imx53-ldb" or "fsl,imx6q-ldb".
+                Both LDB versions are similar, but i.MX6 has an additional
+                multiplexer in the front to select any of the four IPU display
+                interfaces as input for each LVDS channel.
+ - gpr : should be <&gpr> on i.MX53 and i.MX6q.
+         The phandle points to the iomuxc-gpr region containing the LVDS
+         control register.
+- clocks, clock-names : phandles to the LDB divider and selector clocks and to
+                        the display interface selector clocks, as described in
+                        Documentation/devicetree/bindings/clock/clock-bindings.txt
+        The following clocks are expected on i.MX53:
+                "di0_pll" - LDB LVDS channel 0 mux
+                "di1_pll" - LDB LVDS channel 1 mux
+                "di0" - LDB LVDS channel 0 gate
+                "di1" - LDB LVDS channel 1 gate
+                "di0_sel" - IPU1 DI0 mux
+                "di1_sel" - IPU1 DI1 mux
+        On i.MX6q the following additional clocks are needed:
+                "di2_sel" - IPU2 DI0 mux
+                "di3_sel" - IPU2 DI1 mux
+        The needed clock numbers for each are documented in
+        Documentation/devicetree/bindings/clock/imx5-clock.txt, and in
+        Documentation/devicetree/bindings/clock/imx6q-clock.txt.
+
+Optional properties:
+ - pinctrl-names : should be "default" on i.MX53, not used on i.MX6q
+ - pinctrl-0 : a phandle pointing to LVDS pin settings on i.MX53,
+               not used on i.MX6q
+ - fsl,dual-channel : boolean. if it exists, only LVDS channel 0 should
+   be configured - one input will be distributed on both outputs in dual
+   channel mode
+
+LVDS Channel
+============
+
+Each LVDS Channel has to contain a display-timings node that describes the
+video timings for the connected LVDS display. For detailed information, also
+have a look at Documentation/devicetree/bindings/video/display-timing.txt.
+
+Required properties:
+ - reg : should be <0> or <1>
+ - crtcs : a list of phandles with index pointing to the IPU display interfaces
+           that can be used as video source for this channel.
+ - fsl,data-mapping : should be "spwg" or "jeida"
+                      This describes how the color bits are laid out in the
+                      serialized LVDS signal.
+ - fsl,data-width : should be <18> or <24>
+
+example:
+
+gpr: iomuxc-gpr@53fa8000 {
+	/* ... */
+};
+
+ldb: ldb@53fa8008 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "fsl,imx53-ldb";
+	gpr = <&gpr>;
+	clocks = <&clks 122>, <&clks 120>,
+		 <&clks 115>, <&clks 116>,
+		 <&clks 123>, <&clks 85>;
+	clock-names = "di0_pll", "di1_pll",
+		      "di0_sel", "di1_sel",
+		      "di0", "di1";
+
+	lvds-channel@0 {
+		reg = <0>;
+		crtcs = <&ipu 0>;
+		fsl,data-mapping = "spwg";
+		fsl,data-width = <24>;
+
+		display-timings {
+			/* ... */
+		};
+	};
+
+	lvds-channel@1 {
+		reg = <1>;
+		crtcs = <&ipu 1>;
+		fsl,data-mapping = "spwg";
+		fsl,data-width = <24>;
+
+		display-timings {
+			/* ... */
+		};
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/thermal/ti_soc_thermal.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/thermal/ti_soc_thermal.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/thermal/ti_soc_thermal.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/thermal/ti_soc_thermal.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,74 @@
+* Texas Instrument OMAP SCM bandgap bindings
+
+In the System Control Module, OMAP supplies a voltage reference
+and a temperature sensor feature that are gathered in the band
+gap voltage and temperature sensor (VBGAPTS) module. The band
+gap provides current and voltage reference for its internal
+circuits and other analog IP blocks. The analog-to-digital
+converter (ADC) produces an output value that is proportional
+to the silicon temperature.
+
+Required properties:
+- compatible : Should be:
+  - "ti,omap4430-bandgap" : for OMAP4430 bandgap
+  - "ti,omap4460-bandgap" : for OMAP4460 bandgap
+  - "ti,omap4470-bandgap" : for OMAP4470 bandgap
+  - "ti,omap5430-bandgap" : for OMAP5430 bandgap
+- interrupts : this entry should indicate which interrupt line
+the talert signal is routed to;
+Specific:
+- gpios : this entry should be used to inform which GPIO
+line the tshut signal is routed to. The informed GPIO will
+be treated as an IRQ;
+- regs : this entry must also be specified and it is specific
+to each bandgap version, because the mapping may change from
+soc to soc, apart of depending on available features.
+
+Example:
+OMAP4430:
+bandgap {
+	reg = <0x4a002260 0x4 0x4a00232C 0x4>;
+	compatible = "ti,omap4430-bandgap";
+};
+
+OMAP4460:
+bandgap {
+	reg = <0x4a002260 0x4
+		0x4a00232C 0x4
+		0x4a002378 0x18>;
+	compatible = "ti,omap4460-bandgap";
+	interrupts = <0 126 4>; /* talert */
+	gpios = <&gpio3 22 0>; /* tshut */
+};
+
+OMAP4470:
+bandgap {
+	reg = <0x4a002260 0x4
+		0x4a00232C 0x4
+		0x4a002378 0x18>;
+	compatible = "ti,omap4470-bandgap";
+	interrupts = <0 126 4>; /* talert */
+	gpios = <&gpio3 22 0>; /* tshut */
+};
+
+OMAP5430:
+bandgap {
+	reg = <0x4a0021e0 0xc
+		0x4a00232c 0xc
+		0x4a002380 0x2c
+		0x4a0023C0 0x3c>;
+	compatible = "ti,omap5430-bandgap";
+	interrupts = <0 126 4>; /* talert */
+};
+
+DRA752:
+bandgap {
+	reg = <0x4a0021e0 0xc
+		0x4a00232c 0xc
+		0x4a002380 0x2c
+		0x4a0023C0 0x3c
+		0x4a002564 0x8
+		0x4a002574 0x50>;
+	compatible = "ti,dra752-bandgap";
+	interrupts = <0 126 4>; /* talert */
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/timer/lsi,zevio-timer.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/timer/lsi,zevio-timer.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/timer/lsi,zevio-timer.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/timer/lsi,zevio-timer.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,33 @@
+TI-NSPIRE timer
+
+Required properties:
+
+- compatible : should be "lsi,zevio-timer".
+- reg : The physical base address and size of the timer (always first).
+- clocks: phandle to the source clock.
+
+Optional properties:
+
+- interrupts : The interrupt number of the first timer.
+- reg : The interrupt acknowledgement registers
+	(always after timer base address)
+
+If any of the optional properties are not given, the timer is added as a
+clock-source only.
+
+Example:
+
+timer {
+	compatible = "lsi,zevio-timer";
+	reg = <0x900D0000 0x1000>, <0x900A0020 0x8>;
+	interrupts = <19>;
+	clocks = <&timer_clk>;
+};
+
+Example (no clock-events):
+
+timer {
+	compatible = "lsi,zevio-timer";
+	reg = <0x900D0000 0x1000>;
+	clocks = <&timer_clk>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/timer/marvell,orion-timer.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,17 @@
+Marvell Orion SoC timer
+
+Required properties:
+- compatible: shall be "marvell,orion-timer"
+- reg: base address of the timer register starting with TIMERS CONTROL register
+- interrupt-parent: phandle of the bridge interrupt controller
+- interrupts: should contain the interrupts for Timer0 and Timer1
+- clocks: phandle of timer reference clock (tclk)
+
+Example:
+	timer: timer {
+		compatible = "marvell,orion-timer";
+		reg = <0x20300 0x20>;
+		interrupt-parent = <&bridge_intc>;
+		interrupts = <1>, <2>;
+		clocks = <&core_clk 0>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt	2013-08-25 20:43:22.000000000 -0400
@@ -44,7 +44,7 @@ Example 1: In this example, the system u
 	};
 
 Example 2: In this example, the MCT global and local timer interrupts are
-	   connected to two seperate interrupt controllers. Hence, an
+	   connected to two separate interrupt controllers. Hence, an
 	   interrupt-map is created to map the interrupts to the respective
 	   interrupt controllers.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/timer/stericsson-u300-apptimer.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,18 @@
+ST-Ericsson U300 apptimer
+
+Required properties:
+
+- compatible : should be "stericsson,u300-apptimer"
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 4 interrupts; one for each subtimer. These
+  are, in order: OS (operating system), DD (device driver) both
+  adopted for EPOC/Symbian with two specific IRQs for these tasks,
+  then GP1 and GP2, which are general-purpose timers.
+
+Example:
+
+timer {
+	compatible = "stericsson,u300-apptimer";
+	reg = <0xc0014000 0x1000>;
+	interrupts = <24 25 26 27>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,8 @@ Required properties:
 Optional properties:
 - fsl,uart-has-rtscts : Indicate the uart has rts and cts
 - fsl,irda-mode : Indicate the uart supports irda mode
+- fsl,dte-mode : Indicate the uart works in DTE mode. The uart works
+                  is DCE mode by default.
 
 Example:
 
@@ -16,4 +18,5 @@ serial@73fbc000 {
 	reg = <0x73fbc000 0x4000>;
 	interrupts = <31>;
 	fsl,uart-has-rtscts;
+	fsl,dte-mode;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/tty/serial/fsl-lpuart.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/tty/serial/fsl-lpuart.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/tty/serial/fsl-lpuart.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/tty/serial/fsl-lpuart.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,14 @@
+* Freescale low power universal asynchronous receiver/transmitter (lpuart)
+
+Required properties:
+- compatible : Should be "fsl,<soc>-lpuart"
+- reg : Address and length of the register set for the device
+- interrupts : Should contain uart interrupt
+
+Example:
+
+uart0: serial@40027000 {
+	       compatible = "fsl,vf610-lpuart";
+	       reg = <0x40027000 0x1000>;
+	       interrupts = <0 61 0x00>;
+       };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,16 @@
+* Universal Flash Storage (UFS) Host Controller
+
+UFSHC nodes are defined to describe on-chip UFS host controllers.
+Each UFS controller instance should have its own node.
+
+Required properties:
+- compatible        : compatible list, contains "jedec,ufs-1.1"
+- interrupts        : <interrupt mapping for UFS host controller IRQ>
+- reg               : <registers mapping>
+
+Example:
+	ufshc@0xfc598000 {
+		compatible = "jedec,ufs-1.1";
+		reg = <0xfc598000 0x800>;
+		interrupts = <0 28 0>;
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/am33xx-usb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/am33xx-usb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/am33xx-usb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/am33xx-usb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,7 @@ AM33XX MUSB GLUE
    represents PERIPHERAL.
  - port1-mode : Should be "1" to represent HOST. "3" signifies OTG and "2"
    represents PERIPHERAL.
- - power : Should be "250". This signifies the controller can supply upto
+ - power : Should be "250". This signifies the controller can supply up to
    500mA when operating in host mode.
 
 Example:
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/atmel-usb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/atmel-usb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/atmel-usb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/atmel-usb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -47,3 +47,85 @@ usb1: gadget@fffa4000 {
 	interrupts = <10 4>;
 	atmel,vbus-gpio = <&pioC 5 0>;
 };
+
+Atmel High-Speed USB device controller
+
+Required properties:
+ - compatible: Should be "atmel,at91sam9rl-udc"
+ - reg: Address and length of the register set for the device
+ - interrupts: Should contain usba interrupt
+ - ep childnode: To specify the number of endpoints and their properties.
+
+Optional properties:
+ - atmel,vbus-gpio: If present, specifies a gpio that needs to be
+   activated for the bus to be powered.
+
+Required child node properties:
+ - name: Name of the endpoint.
+ - reg: Num of the endpoint.
+ - atmel,fifo-size: Size of the fifo.
+ - atmel,nb-banks: Number of banks.
+ - atmel,can-dma: Boolean to specify if the endpoint support DMA.
+ - atmel,can-isoc: Boolean to specify if the endpoint support ISOC.
+
+usb2: gadget@fff78000 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	compatible = "atmel,at91sam9rl-udc";
+	reg = <0x00600000 0x80000
+	       0xfff78000 0x400>;
+	interrupts = <27 4 0>;
+	atmel,vbus-gpio = <&pioB 19 0>;
+
+	ep0 {
+		reg = <0>;
+		atmel,fifo-size = <64>;
+		atmel,nb-banks = <1>;
+	};
+
+	ep1 {
+		reg = <1>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <2>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+
+	ep2 {
+		reg = <2>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <2>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+
+	ep3 {
+		reg = <3>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+	};
+
+	ep4 {
+		reg = <4>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+	};
+
+	ep5 {
+		reg = <5>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+
+	ep6 {
+		reg = <6>;
+		atmel,fifo-size = <1024>;
+		atmel,nb-banks = <3>;
+		atmel,can-dma;
+		atmel,can-isoc;
+	};
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt	2013-08-25 20:43:22.000000000 -0400
@@ -5,6 +5,12 @@ Required properties:
 - reg: Should contain registers location and length
 - interrupts: Should contain controller interrupt
 
+Recommended properies:
+- phy_type: the type of the phy connected to the core. Should be one
+  of "utmi", "utmi_wide", "ulpi", "serial" or "hsic". Without this
+  property the PORTSC register won't be touched
+- dr_mode: One of "host", "peripheral" or "otg". Defaults to "otg"
+
 Optional properties:
 - fsl,usbphy: phandler of usb phy that connects to the only one port
 - fsl,usbmisc: phandler of non-core register device, with one argument
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/exynos-usb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/exynos-usb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/exynos-usb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/exynos-usb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -48,3 +48,37 @@ Example:
 		clocks = <&clock 285>;
 		clock-names = "usbhost";
 	};
+
+DWC3
+Required properties:
+ - compatible: should be "samsung,exynos5250-dwusb3" for USB 3.0 DWC3
+	       controller.
+ - #address-cells, #size-cells : should be '1' if the device has sub-nodes
+				 with 'reg' property.
+ - ranges: allows valid 1:1 translation between child's address space and
+	   parent's address space
+ - clocks: Clock IDs array as required by the controller.
+ - clock-names: names of clocks correseponding to IDs in the clock property
+
+Sub-nodes:
+The dwc3 core should be added as subnode to Exynos dwc3 glue.
+- dwc3 :
+   The binding details of dwc3 can be found in:
+   Documentation/devicetree/bindings/usb/dwc3.txt
+
+Example:
+	usb@12000000 {
+		compatible = "samsung,exynos5250-dwusb3";
+		clocks = <&clock 286>;
+		clock-names = "usbdrd30";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		dwc3 {
+			compatible = "synopsys,dwc3";
+			reg = <0x12000000 0x10000>;
+			interrupts = <0 72 0>;
+			usb-phy = <&usb2_phy &usb3_phy>;
+		};
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt	2013-08-25 20:43:22.000000000 -0400
@@ -6,27 +6,10 @@ Practice : Universal Serial Bus" with th
 and additions :
 
 Required properties :
- - compatible : Should be "nvidia,tegra20-ehci" for USB controllers
-   used in host mode.
- - phy_type : Should be one of "ulpi" or "utmi".
- - nvidia,vbus-gpio : If present, specifies a gpio that needs to be
-   activated for the bus to be powered.
- - nvidia,phy : phandle of the PHY instance, the controller is connected to.
-
-Required properties for phy_type == ulpi:
-  - nvidia,phy-reset-gpio : The GPIO used to reset the PHY.
+ - compatible : Should be "nvidia,tegra20-ehci".
+ - nvidia,phy : phandle of the PHY that the controller is connected to.
+ - clocks : Contains a single entry which defines the USB controller's clock.
 
 Optional properties:
-  - dr_mode : dual role mode. Indicates the working mode for
-   nvidia,tegra20-ehci compatible controllers.  Can be "host", "peripheral",
-   or "otg".  Default to "host" if not defined for backward compatibility.
-      host means this is a host controller
-      peripheral means it is device controller
-      otg means it can operate as either ("on the go")
-  - nvidia,has-legacy-mode : boolean indicates whether this controller can
-    operate in legacy mode (as APX 2500 / 2600). In legacy mode some
-    registers are accessed through the APB_MISC base address instead of
-    the USB controller. Since this is a legacy issue it probably does not
-    warrant a compatible string of its own.
-  - nvidia,needs-double-reset : boolean is to be set for some of the Tegra2
-    USB ports, which need reset twice due to hardware issues.
+ - nvidia,needs-double-reset : boolean is to be set for some of the Tegra20
+   USB ports, which need reset twice due to hardware issues.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt	2013-08-25 20:43:22.000000000 -0400
@@ -4,14 +4,49 @@ The device node for Tegra SOC USB PHY:
 
 Required properties :
  - compatible : Should be "nvidia,tegra20-usb-phy".
- - reg : Address and length of the register set for the USB PHY interface.
- - phy_type : Should be one of "ulpi" or "utmi".
+ - reg : Defines the following set of registers, in the order listed:
+   - The PHY's own register set.
+     Always present.
+   - The register set of the PHY containing the UTMI pad control registers.
+     Present if-and-only-if phy_type == utmi.
+ - phy_type : Should be one of "utmi", "ulpi" or "hsic".
+ - clocks : Defines the clocks listed in the clock-names property.
+ - clock-names : The following clock names must be present:
+   - reg: The clock needed to access the PHY's own registers. This is the
+     associated EHCI controller's clock. Always present.
+   - pll_u: PLL_U. Always present.
+   - timer: The timeout clock (clk_m). Present if phy_type == utmi.
+   - utmi-pads: The clock needed to access the UTMI pad control registers.
+     Present if phy_type == utmi.
+   - ulpi-link: The clock Tegra provides to the ULPI PHY (cdev2).
+     Present if phy_type == ulpi, and ULPI link mode is in use.
 
 Required properties for phy_type == ulpi:
   - nvidia,phy-reset-gpio : The GPIO used to reset the PHY.
 
+Required PHY timing params for utmi phy:
+  - nvidia,hssync-start-delay : Number of 480 Mhz clock cycles to wait before
+    start of sync launches RxActive
+  - nvidia,elastic-limit : Variable FIFO Depth of elastic input store
+  - nvidia,idle-wait-delay : Number of 480 Mhz clock cycles of idle to wait
+    before declare IDLE.
+  - nvidia,term-range-adj : Range adjusment on terminations
+  - nvidia,xcvr-setup : HS driver output control
+  - nvidia,xcvr-lsfslew : LS falling slew rate control.
+  - nvidia,xcvr-lsrslew :  LS rising slew rate control.
+
 Optional properties:
   - nvidia,has-legacy-mode : boolean indicates whether this controller can
     operate in legacy mode (as APX 2500 / 2600). In legacy mode some
     registers are accessed through the APB_MISC base address instead of
-    the USB controller.
\ No newline at end of file
+    the USB controller.
+  - nvidia,is-wired : boolean. Indicates whether we can do certain kind of power
+    optimizations for the devices that are always connected. e.g. modem.
+  - dr_mode : dual role mode. Indicates the working mode for the PHY. Can be
+    "host", "peripheral", or "otg". Defaults to "host" if not defined.
+      host means this is a host controller
+      peripheral means it is device controller
+      otg means it can operate as either ("on the go")
+
+Required properties for dr_mode == otg:
+  - vbus-supply: regulator for VBUS
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/omap-usb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/omap-usb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/omap-usb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/omap-usb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,7 @@ OMAP MUSB GLUE
    specifying ULPI and UTMI respectively.
  - mode : Should be "3" to represent OTG. "1" signifies HOST and "2"
    represents PERIPHERAL.
- - power : Should be "50". This signifies the controller can supply upto
+ - power : Should be "50". This signifies the controller can supply up to
    100mA when operating in host mode.
  - usb-phy : the phandle for the PHY device
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@ TWL6030 USB COMPARATOR
    usb interrupt number that raises VBUS interrupts when the controller has to
    act as device
  - usb-supply : phandle to the regulator device tree node. It should be vusb
-   if it is twl6030 or ldousb if it is twl6025 subclass.
+   if it is twl6030 or ldousb if it is twl6032 subclass.
 
 twl6030-usb {
 	compatible = "ti,twl6030-usb";
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/usb3503.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/usb3503.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/usb3503.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/usb3503.txt	2013-08-25 20:43:22.000000000 -0400
@@ -4,6 +4,10 @@ Required properties:
 - compatible: Should be "smsc,usb3503".
 - reg: Specifies the i2c slave address, it should be 0x08.
 - connect-gpios: Should specify GPIO for connect.
+- disabled-ports: Should specify the ports unused.
+	'1' or '2' or '3' are availe for this property to describe the port
+	number. 1~3 property values are possible to be desribed.
+	Do not describe this property if all ports have to be enabled.
 - intn-gpios: Should specify GPIO for interrupt.
 - reset-gpios: Should specify GPIO for reset.
 - initial-mode: Should specify initial mode.
@@ -14,6 +18,7 @@ Examples:
 		compatible = "smsc,usb3503";
 		reg = <0x08>;
 		connect-gpios = <&gpx3 0 1>;
+		disabled-ports = <2 3>;
 		intn-gpios = <&gpx3 4 1>;
 		reset-gpios = <&gpx3 5 1>;
 		initial-mode = <1>;
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/ux500-usb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/ux500-usb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/usb/ux500-usb.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/usb/ux500-usb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,50 @@
+Ux500 MUSB
+
+Required properties:
+ - compatible : Should be "stericsson,db8500-musb"
+ - reg        : Offset and length of registers
+ - interrupts : Interrupt; mode, number and trigger
+ - dr_mode    : Dual-role; either host mode "host", peripheral mode "peripheral"
+                or both "otg"
+
+Optional properties:
+ - dmas       : A list of dma channels;
+                dma-controller, event-line, fixed-channel, flags
+ - dma-names  : An ordered list of channel names affiliated to the above
+
+Example:
+
+usb_per5@a03e0000 {
+	compatible = "stericsson,db8500-musb", "mentor,musb";
+	reg = <0xa03e0000 0x10000>;
+	interrupts = <0 23 0x4>;
+	interrupt-names = "mc";
+
+	dr_mode = "otg";
+
+	dmas = <&dma 38 0 0x2>, /* Logical - DevToMem */
+	       <&dma 38 0 0x0>, /* Logical - MemToDev */
+	       <&dma 37 0 0x2>, /* Logical - DevToMem */
+	       <&dma 37 0 0x0>, /* Logical - MemToDev */
+	       <&dma 36 0 0x2>, /* Logical - DevToMem */
+	       <&dma 36 0 0x0>, /* Logical - MemToDev */
+	       <&dma 19 0 0x2>, /* Logical - DevToMem */
+	       <&dma 19 0 0x0>, /* Logical - MemToDev */
+	       <&dma 18 0 0x2>, /* Logical - DevToMem */
+	       <&dma 18 0 0x0>, /* Logical - MemToDev */
+	       <&dma 17 0 0x2>, /* Logical - DevToMem */
+	       <&dma 17 0 0x0>, /* Logical - MemToDev */
+	       <&dma 16 0 0x2>, /* Logical - DevToMem */
+	       <&dma 16 0 0x0>, /* Logical - MemToDev */
+	       <&dma 39 0 0x2>, /* Logical - DevToMem */
+	       <&dma 39 0 0x0>; /* Logical - MemToDev */
+
+	dma-names = "iep_1_9",  "oep_1_9",
+		    "iep_2_10", "oep_2_10",
+		    "iep_3_11", "oep_3_11",
+		    "iep_4_12", "oep_4_12",
+		    "iep_5_13", "oep_5_13",
+		    "iep_6_14", "oep_6_14",
+		    "iep_7_15", "oep_7_15",
+		    "iep_8",    "oep_8";
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/vendor-prefixes.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/vendor-prefixes.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/vendor-prefixes.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/vendor-prefixes.txt	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@ chrp	Common Hardware Reference Platform
 cirrus	Cirrus Logic, Inc.
 cortina	Cortina Systems, Inc.
 dallas	Maxim Integrated Products (formerly Dallas Semiconductor)
+davicom	DAVICOM Semiconductor, Inc.
 denx	Denx Software Engineering
 emmicro	EM Microelectronic
 epson	Seiko Epson Corp.
@@ -25,12 +26,14 @@ est	ESTeem Wireless Modems
 fsl	Freescale Semiconductor
 GEFanuc	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 gef	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+hisilicon	Hisilicon Limited.
 hp	Hewlett Packard
 ibm	International Business Machines (IBM)
 idt	Integrated Device Technologies, Inc.
 img	Imagination Technologies Ltd.
 intercontrol	Inter Control Group
 linux	Linux-specific binding
+lsi	LSI Corp. (LSI Logic)
 marvell	Marvell Technology Group Ltd.
 maxim	Maxim Integrated Products
 mosaixtech	Mosaix Technologies, Inc.
@@ -41,6 +44,7 @@ nxp	NXP Semiconductors
 onnn	ON Semiconductor Corp.
 picochip	Picochip Ltd
 powervr	PowerVR (deprecated, use img)
+qca	Qualcomm Atheros, Inc.
 qcom	Qualcomm, Inc.
 ralink	Mediatek/Ralink Technology Corp.
 ramtron	Ramtron International
@@ -57,8 +61,10 @@ snps 	Synopsys, Inc.
 st	STMicroelectronics
 ste	ST-Ericsson
 stericsson	ST-Ericsson
+toumaz	Toumaz
 ti	Texas Instruments
 toshiba	Toshiba Corporation
+v3	V3 Semiconductor
 via	VIA Technologies, Inc.
 wlf	Wolfson Microelectronics
 wm	Wondermedia Technologies, Inc.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/display-timing.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/display-timing.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/display-timing.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/display-timing.txt	2013-08-25 20:43:22.000000000 -0400
@@ -34,6 +34,7 @@ optional properties:
 			- ignored     = ignored
  - interlaced (bool): boolean to enable interlaced mode
  - doublescan (bool): boolean to enable doublescan mode
+ - doubleclk (bool): boolean to enable doubleclock mode
 
 All the optional properties that are not bool follow the following logic:
     <1>: high active
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_dp.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_dp.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_dp.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_dp.txt	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,10 @@ Required properties for dp-controller:
 		of memory mapped region.
 	-interrupts:
 		interrupt combiner values.
+	-clocks:
+		from common clock binding: handle to dp clock.
+	-clock-names:
+		from common clock binding: Shall be "dp".
 	-interrupt-parent:
 		phandle to Interrupt combiner node.
 	-samsung,color-space:
@@ -61,6 +65,8 @@ SOC specific portion:
 		reg = <0x145b0000 0x10000>;
 		interrupts = <10 3>;
 		interrupt-parent = <&combiner>;
+		clocks = <&clock 342>;
+		clock-names = "dp";
 
 		dptx-phy {
 			reg = <0x10040720>;
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,12 +1,15 @@
 Device-Tree bindings for hdmiddc driver
 
 Required properties:
-- compatible: value should be "samsung,exynos5-hdmiddc".
+- compatible: value should be one of the following
+	1) "samsung,exynos5-hdmiddc" <DEPRECATED>
+	2) "samsung,exynos4210-hdmiddc"
+
 - reg: I2C address of the hdmiddc device.
 
 Example:
 
 	hdmiddc {
-		compatible = "samsung,exynos5-hdmiddc";
+		compatible = "samsung,exynos4210-hdmiddc";
 		reg = <0x50>;
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,12 +1,15 @@
 Device-Tree bindings for hdmiphy driver
 
 Required properties:
-- compatible: value should be "samsung,exynos5-hdmiphy".
+- compatible: value should be one of the following:
+	1) "samsung,exynos5-hdmiphy" <DEPRECATED>
+	2) "samsung,exynos4210-hdmiphy".
+	3) "samsung,exynos4212-hdmiphy".
 - reg: I2C address of the hdmiphy device.
 
 Example:
 
 	hdmiphy {
-		compatible = "samsung,exynos5-hdmiphy";
+		compatible = "samsung,exynos4210-hdmiphy";
 		reg = <0x38>;
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_hdmi.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_hdmi.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_hdmi.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_hdmi.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,22 +1,23 @@
 Device-Tree bindings for drm hdmi driver
 
 Required properties:
-- compatible: value should be "samsung,exynos5-hdmi".
+- compatible: value should be one among the following:
+	1) "samsung,exynos5-hdmi" <DEPRECATED>
+	2) "samsung,exynos4210-hdmi"
+	3) "samsung,exynos4212-hdmi"
 - reg: physical base address of the hdmi and length of memory mapped
 	region.
 - interrupts: interrupt number to the cpu.
 - hpd-gpio: following information about the hotplug gpio pin.
 	a) phandle of the gpio controller node.
 	b) pin number within the gpio controller.
-	c) pin function mode.
-	d) optional flags and pull up/down.
-	e) drive strength.
+	c) optional flags and pull up/down.
 
 Example:
 
 	hdmi {
-		compatible = "samsung,exynos5-hdmi";
+		compatible = "samsung,exynos4212-hdmi";
 		reg = <0x14530000 0x100000>;
 		interrupts = <0 95 0>;
-		hpd-gpio = <&gpx3 7 0xf 1 3>;
+		hpd-gpio = <&gpx3 7 1>;
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_mixer.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_mixer.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/exynos_mixer.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/exynos_mixer.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,12 @@
 Device-Tree bindings for mixer driver
 
 Required properties:
-- compatible: value should be "samsung,exynos5-mixer".
+- compatible: value should be one of the following:
+	1) "samsung,exynos5-mixer" <DEPRECATED>
+	2) "samsung,exynos4210-mixer"
+	3) "samsung,exynos5250-mixer"
+	4) "samsung,exynos5420-mixer"
+
 - reg: physical base address of the mixer and length of memory mapped
 	region.
 - interrupts: interrupt number to the cpu.
@@ -9,7 +14,7 @@ Required properties:
 Example:
 
 	mixer {
-		compatible = "samsung,exynos5-mixer";
+		compatible = "samsung,exynos5250-mixer";
 		reg = <0x14450000 0x10000>;
 		interrupts = <0 94 0>;
 	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/fsl,imx-fb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/fsl,imx-fb.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/fsl,imx-fb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,51 @@
+Freescale imx21 Framebuffer
+
+This framebuffer driver supports devices imx1, imx21, imx25, and imx27.
+
+Required properties:
+- compatible : "fsl,<chip>-fb", chip should be imx1 or imx21
+- reg : Should contain 1 register ranges(address and length)
+- interrupts : One interrupt of the fb dev
+
+Required nodes:
+- display: Phandle to a display node as described in
+	Documentation/devicetree/bindings/video/display-timing.txt
+	Additional, the display node has to define properties:
+	- bits-per-pixel: Bits per pixel
+	- fsl,pcr: LCDC PCR value
+
+Optional properties:
+- fsl,dmacr: DMA Control Register value. This is optional. By default, the
+	register is not modified as recommended by the datasheet.
+- fsl,lscr1: LCDC Sharp Configuration Register value.
+
+Example:
+
+	imxfb: fb@10021000 {
+		compatible = "fsl,imx21-fb";
+		interrupts = <61>;
+		reg = <0x10021000 0x1000>;
+		display = <&display0>;
+	};
+
+	...
+
+	display0: display0 {
+		model = "Primeview-PD050VL1";
+		native-mode = <&timing_disp0>;
+		bits-per-pixel = <16>;
+		fsl,pcr = <0xf0c88080>;	/* non-standard but required */
+		display-timings {
+			timing_disp0: 640x480 {
+				hactive = <640>;
+				vactive = <480>;
+				hback-porch = <112>;
+				hfront-porch = <36>;
+				hsync-len = <32>;
+				vback-porch = <33>;
+				vfront-porch = <33>;
+				vsync-len = <2>;
+				clock-frequency = <25000000>;
+			};
+		};
+	};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/ssd1307fb.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/ssd1307fb.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/video/ssd1307fb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/video/ssd1307fb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,13 +1,17 @@
 * Solomon SSD1307 Framebuffer Driver
 
 Required properties:
-  - compatible: Should be "solomon,ssd1307fb-<bus>". The only supported bus for
-    now is i2c.
+  - compatible: Should be "solomon,<chip>fb-<bus>". The only supported bus for
+    now is i2c, and the supported chips are ssd1306 and ssd1307.
   - reg: Should contain address of the controller on the I2C bus. Most likely
          0x3c or 0x3d
   - pwm: Should contain the pwm to use according to the OF device tree PWM
-         specification [0]
+         specification [0]. Only required for the ssd1307.
   - reset-gpios: Should contain the GPIO used to reset the OLED display
+  - solomon,height: Height in pixel of the screen driven by the controller
+  - solomon,width: Width in pixel of the screen driven by the controller
+  - solomon,page-offset: Offset of pages (band of 8 pixels) that the screen is
+    mapped to.
 
 Optional properties:
   - reset-active-low: Is the reset gpio is active on physical low?
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/watchdog/brcm,bcm2835-pm-wdog.txt	2013-08-25 20:43:22.000000000 -0400
@@ -5,9 +5,14 @@ Required properties:
 - compatible : should be "brcm,bcm2835-pm-wdt"
 - reg : Specifies base physical address and size of the registers.
 
+Optional properties:
+
+- timeout-sec   : Contains the watchdog timeout in seconds
+
 Example:
 
 watchdog {
 	compatible = "brcm,bcm2835-pm-wdt";
 	reg = <0x7e100000 0x28>;
+	timeout-sec = <10>;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/bindings/watchdog/stericsson-coh901327.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,19 @@
+ST-Ericsson COH 901 327 Watchdog timer
+
+Required properties:
+- compatible: must be "stericsson,coh901327".
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: the interrupt used for the watchdog timeout warning.
+
+Optional properties:
+- timeout-sec: contains the watchdog timeout in seconds.
+
+Example:
+
+watchdog: watchdog@c0012000 {
+	compatible = "stericsson,coh901327";
+	reg = <0xc0012000 0x1000>;
+	interrupts = <3>;
+	timeout-sec = <60>;
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/devicetree/usage-model.txt linux-libre-3.11-rc7-gnu/Documentation/devicetree/usage-model.txt
--- linux-libre-3.10-gnu/Documentation/devicetree/usage-model.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/devicetree/usage-model.txt	2013-08-25 20:43:22.000000000 -0400
@@ -106,17 +106,18 @@ In the majority of cases, the machine id
 kernel will instead select setup code based on the machine's core
 CPU or SoC.  On ARM for example, setup_arch() in
 arch/arm/kernel/setup.c will call setup_machine_fdt() in
-arch/arm/kernel/devicetree.c which searches through the machine_desc
+arch/arm/kernel/devtree.c which searches through the machine_desc
 table and selects the machine_desc which best matches the device tree
 data.  It determines the best match by looking at the 'compatible'
 property in the root device tree node, and comparing it with the
-dt_compat list in struct machine_desc.
+dt_compat list in struct machine_desc (which is defined in
+arch/arm/include/asm/mach/arch.h if you're curious).
 
 The 'compatible' property contains a sorted list of strings starting
 with the exact name of the machine, followed by an optional list of
 boards it is compatible with sorted from most compatible to least.  For
 example, the root compatible properties for the TI BeagleBoard and its
-successor, the BeagleBoard xM board might look like:
+successor, the BeagleBoard xM board might look like, respectively:
 
 	compatible = "ti,omap3-beagleboard", "ti,omap3450", "ti,omap3";
 	compatible = "ti,omap3-beagleboard-xm", "ti,omap3450", "ti,omap3";
@@ -161,7 +162,7 @@ cases.
 
 Instead, the compatible list allows a generic machine_desc to provide
 support for a wide common set of boards by specifying "less
-compatible" value in the dt_compat list.  In the example above,
+compatible" values in the dt_compat list.  In the example above,
 generic board support can claim compatibility with "ti,omap3" or
 "ti,omap3450".  If a bug was discovered on the original beagleboard
 that required special workaround code during early boot, then a new
@@ -377,7 +378,7 @@ platform_devices as more platform_device
 device tree support code reflects that and makes the above example
 simpler.  The second argument to of_platform_populate() is an
 of_device_id table, and any node that matches an entry in that table
-will also get its child nodes registered.  In the tegra case, the code
+will also get its child nodes registered.  In the Tegra case, the code
 can look something like this:
 
 static void __init harmony_init_machine(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/80211.tmpl linux-libre-3.11-rc7-gnu/Documentation/DocBook/80211.tmpl
--- linux-libre-3.10-gnu/Documentation/DocBook/80211.tmpl	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/80211.tmpl	2013-08-25 20:43:22.000000000 -0400
@@ -127,14 +127,11 @@
 !Finclude/net/cfg80211.h cfg80211_ibss_params
 !Finclude/net/cfg80211.h cfg80211_connect_params
 !Finclude/net/cfg80211.h cfg80211_pmksa
-!Finclude/net/cfg80211.h cfg80211_send_rx_auth
-!Finclude/net/cfg80211.h cfg80211_send_auth_timeout
-!Finclude/net/cfg80211.h cfg80211_send_rx_assoc
-!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout
-!Finclude/net/cfg80211.h cfg80211_send_deauth
-!Finclude/net/cfg80211.h __cfg80211_send_deauth
-!Finclude/net/cfg80211.h cfg80211_send_disassoc
-!Finclude/net/cfg80211.h __cfg80211_send_disassoc
+!Finclude/net/cfg80211.h cfg80211_rx_mlme_mgmt
+!Finclude/net/cfg80211.h cfg80211_auth_timeout
+!Finclude/net/cfg80211.h cfg80211_rx_assoc_resp
+!Finclude/net/cfg80211.h cfg80211_assoc_timeout
+!Finclude/net/cfg80211.h cfg80211_tx_mlme_mgmt
 !Finclude/net/cfg80211.h cfg80211_ibss_joined
 !Finclude/net/cfg80211.h cfg80211_connect_result
 !Finclude/net/cfg80211.h cfg80211_roamed
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/device-drivers.tmpl linux-libre-3.11-rc7-gnu/Documentation/DocBook/device-drivers.tmpl
--- linux-libre-3.10-gnu/Documentation/DocBook/device-drivers.tmpl	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/device-drivers.tmpl	2013-08-25 20:43:22.000000000 -0400
@@ -84,7 +84,7 @@ X!Iinclude/linux/kobject.h
 
      <sect1><title>Kernel utility functions</title>
 !Iinclude/linux/kernel.h
-!Ekernel/printk.c
+!Ekernel/printk/printk.c
 !Ekernel/panic.c
 !Ekernel/sys.c
 !Ekernel/rcupdate.c
@@ -126,6 +126,8 @@ X!Edrivers/base/interface.c
      </sect1>
      <sect1><title>Device Drivers DMA Management</title>
 !Edrivers/base/dma-buf.c
+!Edrivers/base/reservation.c
+!Iinclude/linux/reservation.h
 !Edrivers/base/dma-coherent.c
 !Edrivers/base/dma-mapping.c
      </sect1>
@@ -297,10 +299,10 @@ KAO -->
      </sect1>
      <sect1><title>Frame Buffer Fonts</title>
         <para>
-           Refer to the file drivers/video/console/fonts.c for more information.
+           Refer to the file lib/fonts/fonts.c for more information.
         </para>
 <!-- FIXME: Removed for now since no structured comments in source
-X!Idrivers/video/console/fonts.c
+X!Ilib/fonts/fonts.c
 -->
      </sect1>
   </chapter>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/drm.tmpl linux-libre-3.11-rc7-gnu/Documentation/DocBook/drm.tmpl
--- linux-libre-3.10-gnu/Documentation/DocBook/drm.tmpl	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/drm.tmpl	2013-08-25 20:43:22.000000000 -0400
@@ -186,11 +186,12 @@
           <varlistentry>
             <term>DRIVER_HAVE_IRQ</term><term>DRIVER_IRQ_SHARED</term>
             <listitem><para>
-              DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler. The
-              DRM core will automatically register an interrupt handler when the
-              flag is set. DRIVER_IRQ_SHARED indicates whether the device &amp;
-              handler support shared IRQs (note that this is required of PCI
-              drivers).
+              DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler
+              managed by the DRM Core. The core will support simple IRQ handler
+              installation when the flag is set. The installation process is
+              described in <xref linkend="drm-irq-registration"/>.</para>
+              <para>DRIVER_IRQ_SHARED indicates whether the device &amp; handler
+              support shared IRQs (note that this is required of PCI  drivers).
             </para></listitem>
           </varlistentry>
           <varlistentry>
@@ -344,50 +345,71 @@ char *date;</synopsis>
           The DRM core tries to facilitate IRQ handler registration and
           unregistration by providing <function>drm_irq_install</function> and
           <function>drm_irq_uninstall</function> functions. Those functions only
-          support a single interrupt per device.
-        </para>
-  <!--!Fdrivers/char/drm/drm_irq.c drm_irq_install-->
-        <para>
-          Both functions get the device IRQ by calling
-          <function>drm_dev_to_irq</function>. This inline function will call a
-          bus-specific operation to retrieve the IRQ number. For platform devices,
-          <function>platform_get_irq</function>(..., 0) is used to retrieve the
-          IRQ number.
-        </para>
-        <para>
-          <function>drm_irq_install</function> starts by calling the
-          <methodname>irq_preinstall</methodname> driver operation. The operation
-          is optional and must make sure that the interrupt will not get fired by
-          clearing all pending interrupt flags or disabling the interrupt.
-        </para>
-        <para>
-          The IRQ will then be requested by a call to
-          <function>request_irq</function>. If the DRIVER_IRQ_SHARED driver
-          feature flag is set, a shared (IRQF_SHARED) IRQ handler will be
-          requested.
-        </para>
-        <para>
-          The IRQ handler function must be provided as the mandatory irq_handler
-          driver operation. It will get passed directly to
-          <function>request_irq</function> and thus has the same prototype as all
-          IRQ handlers. It will get called with a pointer to the DRM device as the
-          second argument.
-        </para>
-        <para>
-          Finally the function calls the optional
-          <methodname>irq_postinstall</methodname> driver operation. The operation
-          usually enables interrupts (excluding the vblank interrupt, which is
-          enabled separately), but drivers may choose to enable/disable interrupts
-          at a different time.
-        </para>
-        <para>
-          <function>drm_irq_uninstall</function> is similarly used to uninstall an
-          IRQ handler. It starts by waking up all processes waiting on a vblank
-          interrupt to make sure they don't hang, and then calls the optional
-          <methodname>irq_uninstall</methodname> driver operation. The operation
-          must disable all hardware interrupts. Finally the function frees the IRQ
-          by calling <function>free_irq</function>.
+          support a single interrupt per device, devices that use more than one
+          IRQs need to be handled manually.
         </para>
+        <sect4>
+          <title>Managed IRQ Registration</title>
+          <para>
+            Both the <function>drm_irq_install</function> and
+	    <function>drm_irq_uninstall</function> functions get the device IRQ by
+	    calling <function>drm_dev_to_irq</function>. This inline function will
+	    call a bus-specific operation to retrieve the IRQ number. For platform
+	    devices, <function>platform_get_irq</function>(..., 0) is used to
+	    retrieve the IRQ number.
+          </para>
+          <para>
+            <function>drm_irq_install</function> starts by calling the
+            <methodname>irq_preinstall</methodname> driver operation. The operation
+            is optional and must make sure that the interrupt will not get fired by
+            clearing all pending interrupt flags or disabling the interrupt.
+          </para>
+          <para>
+            The IRQ will then be requested by a call to
+            <function>request_irq</function>. If the DRIVER_IRQ_SHARED driver
+            feature flag is set, a shared (IRQF_SHARED) IRQ handler will be
+            requested.
+          </para>
+          <para>
+            The IRQ handler function must be provided as the mandatory irq_handler
+            driver operation. It will get passed directly to
+            <function>request_irq</function> and thus has the same prototype as all
+            IRQ handlers. It will get called with a pointer to the DRM device as the
+            second argument.
+          </para>
+          <para>
+            Finally the function calls the optional
+            <methodname>irq_postinstall</methodname> driver operation. The operation
+            usually enables interrupts (excluding the vblank interrupt, which is
+            enabled separately), but drivers may choose to enable/disable interrupts
+            at a different time.
+          </para>
+          <para>
+            <function>drm_irq_uninstall</function> is similarly used to uninstall an
+            IRQ handler. It starts by waking up all processes waiting on a vblank
+            interrupt to make sure they don't hang, and then calls the optional
+            <methodname>irq_uninstall</methodname> driver operation. The operation
+            must disable all hardware interrupts. Finally the function frees the IRQ
+            by calling <function>free_irq</function>.
+          </para>
+        </sect4>
+        <sect4>
+          <title>Manual IRQ Registration</title>
+          <para>
+            Drivers that require multiple interrupt handlers can't use the managed
+            IRQ registration functions. In that case IRQs must be registered and
+            unregistered manually (usually with the <function>request_irq</function>
+            and <function>free_irq</function> functions, or their devm_* equivalent).
+          </para>
+          <para>
+            When manually registering IRQs, drivers must not set the DRIVER_HAVE_IRQ
+            driver feature flag, and must not provide the
+	    <methodname>irq_handler</methodname> driver operation. They must set the
+	    <structname>drm_device</structname> <structfield>irq_enabled</structfield>
+	    field to 1 upon registration of the IRQs, and clear it to 0 after
+	    unregistering the IRQs.
+          </para>
+        </sect4>
       </sect3>
       <sect3>
         <title>Memory Manager Initialization</title>
@@ -434,7 +456,7 @@ char *date;</synopsis>
       The DRM core includes two memory managers, namely Translation Table Maps
       (TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory
       manager to be developed and tried to be a one-size-fits-them all
-      solution. It provides a single userspace API to accomodate the need of
+      solution. It provides a single userspace API to accommodate the need of
       all hardware, supporting both Unified Memory Architecture (UMA) devices
       and devices with dedicated video RAM (i.e. most discrete video cards).
       This resulted in a large, complex piece of code that turned out to be
@@ -701,7 +723,7 @@ char *date;</synopsis>
         <para>
           Similar to global names, GEM file descriptors are also used to share GEM
           objects across processes. They offer additional security: as file
-          descriptors must be explictly sent over UNIX domain sockets to be shared
+          descriptors must be explicitly sent over UNIX domain sockets to be shared
           between applications, they can't be guessed like the globally unique GEM
           names.
         </para>
@@ -1154,7 +1176,7 @@ int max_width, max_height;</synopsis>
           </para>
           <para>
             The <methodname>page_flip</methodname> operation schedules a page flip.
-            Once any pending rendering targetting the new frame buffer has
+            Once any pending rendering targeting the new frame buffer has
             completed, the CRTC will be reprogrammed to display that frame buffer
             after the next vertical refresh. The operation must return immediately
             without waiting for rendering or page flip to complete and must block
@@ -1214,6 +1236,15 @@ int max_width, max_height;</synopsis>
           <title>Miscellaneous</title>
           <itemizedlist>
             <listitem>
+              <synopsis>void (*set_property)(struct drm_crtc *crtc,
+                     struct drm_property *property, uint64_t value);</synopsis>
+              <para>
+                Set the value of the given CRTC property to
+                <parameter>value</parameter>. See <xref linkend="drm-kms-properties"/>
+                for more information about properties.
+              </para>
+            </listitem>
+            <listitem>
               <synopsis>void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
                         uint32_t start, uint32_t size);</synopsis>
               <para>
@@ -1363,6 +1394,15 @@ int max_width, max_height;</synopsis>
               <xref linkend="drm-kms-init"/>.
             </para>
           </listitem>
+          <listitem>
+            <synopsis>void (*set_property)(struct drm_plane *plane,
+                     struct drm_property *property, uint64_t value);</synopsis>
+            <para>
+              Set the value of the given plane property to
+              <parameter>value</parameter>. See <xref linkend="drm-kms-properties"/>
+              for more information about properties.
+            </para>
+          </listitem>
         </itemizedlist>
       </sect3>
     </sect2>
@@ -1572,6 +1612,15 @@ int max_width, max_height;</synopsis>
           <title>Miscellaneous</title>
           <itemizedlist>
             <listitem>
+              <synopsis>void (*set_property)(struct drm_connector *connector,
+                     struct drm_property *property, uint64_t value);</synopsis>
+              <para>
+                Set the value of the given connector property to
+                <parameter>value</parameter>. See <xref linkend="drm-kms-properties"/>
+                for more information about properties.
+              </para>
+            </listitem>
+            <listitem>
               <synopsis>void (*destroy)(struct drm_connector *connector);</synopsis>
               <para>
                 Destroy the connector when not needed anymore. See
@@ -1846,10 +1895,6 @@ void intel_crt_init(struct drm_device *d
           <synopsis>bool (*mode_fixup)(struct drm_encoder *encoder,
                        const struct drm_display_mode *mode,
                        struct drm_display_mode *adjusted_mode);</synopsis>
-          <note><para>
-            FIXME: The mode argument be const, but the i915 driver modifies
-            mode-&gt;clock in <function>intel_dp_mode_fixup</function>.
-          </para></note>
           <para>
             Let encoders adjust the requested mode or reject it completely. This
             operation returns true if the mode is accepted (possibly after being
@@ -2161,6 +2206,128 @@ void intel_crt_init(struct drm_device *d
       <title>EDID Helper Functions Reference</title>
 !Edrivers/gpu/drm/drm_edid.c
     </sect2>
+    <sect2>
+      <title>Rectangle Utilities Reference</title>
+!Pinclude/drm/drm_rect.h rect utils
+!Iinclude/drm/drm_rect.h
+!Edrivers/gpu/drm/drm_rect.c
+    </sect2>
+  </sect1>
+
+  <!-- Internals: kms properties -->
+
+  <sect1 id="drm-kms-properties">
+    <title>KMS Properties</title>
+    <para>
+      Drivers may need to expose additional parameters to applications than
+      those described in the previous sections. KMS supports attaching
+      properties to CRTCs, connectors and planes and offers a userspace API to
+      list, get and set the property values.
+    </para>
+    <para>
+      Properties are identified by a name that uniquely defines the property
+      purpose, and store an associated value. For all property types except blob
+      properties the value is a 64-bit unsigned integer.
+    </para>
+    <para>
+      KMS differentiates between properties and property instances. Drivers
+      first create properties and then create and associate individual instances
+      of those properties to objects. A property can be instantiated multiple
+      times and associated with different objects. Values are stored in property
+      instances, and all other property information are stored in the propery
+      and shared between all instances of the property.
+    </para>
+    <para>
+      Every property is created with a type that influences how the KMS core
+      handles the property. Supported property types are
+      <variablelist>
+        <varlistentry>
+          <term>DRM_MODE_PROP_RANGE</term>
+          <listitem><para>Range properties report their minimum and maximum
+            admissible values. The KMS core verifies that values set by
+            application fit in that range.</para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>DRM_MODE_PROP_ENUM</term>
+          <listitem><para>Enumerated properties take a numerical value that
+            ranges from 0 to the number of enumerated values defined by the
+            property minus one, and associate a free-formed string name to each
+            value. Applications can retrieve the list of defined value-name pairs
+            and use the numerical value to get and set property instance values.
+            </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>DRM_MODE_PROP_BITMASK</term>
+          <listitem><para>Bitmask properties are enumeration properties that
+            additionally restrict all enumerated values to the 0..63 range.
+            Bitmask property instance values combine one or more of the
+            enumerated bits defined by the property.</para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term>DRM_MODE_PROP_BLOB</term>
+          <listitem><para>Blob properties store a binary blob without any format
+            restriction. The binary blobs are created as KMS standalone objects,
+            and blob property instance values store the ID of their associated
+            blob object.</para>
+	    <para>Blob properties are only used for the connector EDID property
+	    and cannot be created by drivers.</para></listitem>
+        </varlistentry>
+      </variablelist>
+    </para>
+    <para>
+      To create a property drivers call one of the following functions depending
+      on the property type. All property creation functions take property flags
+      and name, as well as type-specific arguments.
+      <itemizedlist>
+        <listitem>
+          <synopsis>struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
+                                               const char *name,
+                                               uint64_t min, uint64_t max);</synopsis>
+          <para>Create a range property with the given minimum and maximum
+            values.</para>
+        </listitem>
+        <listitem>
+          <synopsis>struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
+                                              const char *name,
+                                              const struct drm_prop_enum_list *props,
+                                              int num_values);</synopsis>
+          <para>Create an enumerated property. The <parameter>props</parameter>
+            argument points to an array of <parameter>num_values</parameter>
+            value-name pairs.</para>
+        </listitem>
+        <listitem>
+          <synopsis>struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
+                                                 int flags, const char *name,
+                                                 const struct drm_prop_enum_list *props,
+                                                 int num_values);</synopsis>
+          <para>Create a bitmask property. The <parameter>props</parameter>
+            argument points to an array of <parameter>num_values</parameter>
+            value-name pairs.</para>
+        </listitem>
+      </itemizedlist>
+    </para>
+    <para>
+      Properties can additionally be created as immutable, in which case they
+      will be read-only for applications but can be modified by the driver. To
+      create an immutable property drivers must set the DRM_MODE_PROP_IMMUTABLE
+      flag at property creation time.
+    </para>
+    <para>
+      When no array of value-name pairs is readily available at property
+      creation time for enumerated or range properties, drivers can create
+      the property using the <function>drm_property_create</function> function
+      and manually add enumeration value-name pairs by calling the
+      <function>drm_property_add_enum</function> function. Care must be taken to
+      properly specify the property type through the <parameter>flags</parameter>
+      argument.
+    </para>
+    <para>
+      After creating properties drivers can attach property instances to CRTC,
+      connector and plane objects by calling the
+      <function>drm_object_attach_property</function>. The function takes a
+      pointer to the target object, a pointer to the previously created property
+      and an initial instance value.
+    </para>
   </sect1>
 
   <!-- Internals: vertical blanking -->
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/genericirq.tmpl linux-libre-3.11-rc7-gnu/Documentation/DocBook/genericirq.tmpl
--- linux-libre-3.10-gnu/Documentation/DocBook/genericirq.tmpl	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/genericirq.tmpl	2013-08-25 20:43:22.000000000 -0400
@@ -464,6 +464,19 @@ if (desc->irq_data.chip->irq_eoi)
 	protected via desc->lock, by the generic layer.
      </para>
   </chapter>
+
+  <chapter id="genericchip">
+     <title>Generic interrupt chip</title>
+     <para>
+       To avoid copies of identical implementations of irq chips the
+       core provides a configurable generic interrupt chip
+       implementation. Developers should check carefuly whether the
+       generic chip fits their needs before implementing the same
+       functionality slightly different themself.
+     </para>
+!Ekernel/irq/generic-chip.c
+  </chapter>
+
   <chapter id="structs">
      <title>Structures</title>
      <para>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/kernel-locking.tmpl linux-libre-3.11-rc7-gnu/Documentation/DocBook/kernel-locking.tmpl
--- linux-libre-3.10-gnu/Documentation/DocBook/kernel-locking.tmpl	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/kernel-locking.tmpl	2013-08-25 20:43:22.000000000 -0400
@@ -1955,12 +1955,17 @@ machines due to caching.
    </sect1>
   </chapter>
 
-  <chapter id="apiref">
+  <chapter id="apiref-mutex">
    <title>Mutex API reference</title>
 !Iinclude/linux/mutex.h
 !Ekernel/mutex.c
   </chapter>
 
+  <chapter id="apiref-futex">
+   <title>Futex API reference</title>
+!Ikernel/futex.c
+  </chapter>
+
   <chapter id="references">
    <title>Further reading</title>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media/dvb/frontend.xml linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/dvb/frontend.xml
--- linux-libre-3.10-gnu/Documentation/DocBook/media/dvb/frontend.xml	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/dvb/frontend.xml	2013-08-25 20:43:22.000000000 -0400
@@ -233,7 +233,7 @@ typedef enum fe_status {
 <entry align="char">The frontend FEC inner coding (Viterbi, LDPC or other inner code) is stable</entry>
 </row><row>
 <entry align="char">FE_HAS_SYNC</entry>
-<entry align="char">Syncronization bytes was found</entry>
+<entry align="char">Synchronization bytes was found</entry>
 </row><row>
 <entry align="char">FE_HAS_LOCK</entry>
 <entry align="char">The DVB were locked and everything is working</entry>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/compat.xml linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/compat.xml
--- linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/compat.xml	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/compat.xml	2013-08-25 20:43:22.000000000 -0400
@@ -2254,7 +2254,7 @@ video encoding.</para>
       <orderedlist>
 	<listitem>
 	  <para>The <constant>VIDIOC_G_CHIP_IDENT</constant> ioctl was renamed
-to <constant>VIDIOC_G_CHIP_IDENT_OLD</constant> and &VIDIOC-DBG-G-CHIP-IDENT;
+to <constant>VIDIOC_G_CHIP_IDENT_OLD</constant> and <constant>VIDIOC_DBG_G_CHIP_IDENT</constant>
 was introduced in its place. The old struct <structname>v4l2_chip_ident</structname>
 was renamed to <structname id="v4l2-chip-ident-old">v4l2_chip_ident_old</structname>.</para>
 	</listitem>
@@ -2513,6 +2513,16 @@ that used it. It was originally schedule
       </orderedlist>
     </section>
 
+    <section>
+      <title>V4L2 in Linux 3.11</title>
+      <orderedlist>
+        <listitem>
+	  <para>Remove obsolete <constant>VIDIOC_DBG_G_CHIP_IDENT</constant> ioctl.
+	  </para>
+        </listitem>
+      </orderedlist>
+    </section>
+
     <section id="other">
       <title>Relation of V4L2 to other Linux multimedia APIs</title>
 
@@ -2596,7 +2606,7 @@ and may change in the future.</para>
 ioctls.</para>
         </listitem>
         <listitem>
-	  <para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
+	  <para>&VIDIOC-DBG-G-CHIP-INFO; ioctl.</para>
         </listitem>
         <listitem>
 	  <para>&VIDIOC-ENUM-DV-TIMINGS;, &VIDIOC-QUERY-DV-TIMINGS; and
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/controls.xml linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/controls.xml
--- linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/controls.xml	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/controls.xml	2013-08-25 20:43:22.000000000 -0400
@@ -3147,7 +3147,7 @@ giving priority to the center of the met
 		  <entry>A multi-zone metering. The light intensity is measured
 in several points of the frame and the the results are combined. The
 algorithm of the zones selection and their significance in calculating the
-final value is device dependant.</entry>
+final value is device dependent.</entry>
 		</row>
 	      </tbody>
 	    </entrytbl>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml
--- linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@ into 64x32 macroblocks. The CbCr plane h
 plane (and the image), but is half as tall in pixels. The chroma plane is also
 grouped into 64x32 macroblocks.</para>
 	<para>Width of the buffer has to be aligned to the multiple of 128, and
-height alignment is 32. Every four adjactent buffers - two horizontally and two
+height alignment is 32. Every four adjacent buffers - two horizontally and two
 vertically are grouped together and are located in memory in Z or flipped Z
 order. </para>
 	<para>Layout of macroblocks in memory is presented in the following
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/v4l2.xml linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/v4l2.xml
--- linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/v4l2.xml	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/v4l2.xml	2013-08-25 20:43:22.000000000 -0400
@@ -141,6 +141,14 @@ structs, ioctls) must be noted in more d
 applications. -->
 
       <revision>
+	<revnumber>3.11</revnumber>
+	<date>2013-05-26</date>
+	<authorinitials>hv</authorinitials>
+	<revremark>Remove obsolete VIDIOC_DBG_G_CHIP_IDENT ioctl.
+	</revremark>
+      </revision>
+
+      <revision>
 	<revnumber>3.10</revnumber>
 	<date>2013-03-25</date>
 	<authorinitials>hv</authorinitials>
@@ -493,7 +501,7 @@ and discussions on the V4L mailing list.
 </partinfo>
 
 <title>Video for Linux Two API Specification</title>
- <subtitle>Revision 3.10</subtitle>
+ <subtitle>Revision 3.11</subtitle>
 
   <chapter id="common">
     &sub-common;
@@ -547,7 +555,6 @@ and discussions on the V4L mailing list.
     <!-- All ioctls go here. -->
     &sub-create-bufs;
     &sub-cropcap;
-    &sub-dbg-g-chip-ident;
     &sub-dbg-g-chip-info;
     &sub-dbg-g-register;
     &sub-decoder-cmd;
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml
--- linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml	1969-12-31 19:00:00.000000000 -0500
@@ -1,271 +0,0 @@
-<refentry id="vidioc-dbg-g-chip-ident">
-  <refmeta>
-    <refentrytitle>ioctl VIDIOC_DBG_G_CHIP_IDENT</refentrytitle>
-    &manvol;
-  </refmeta>
-
-  <refnamediv>
-    <refname>VIDIOC_DBG_G_CHIP_IDENT</refname>
-    <refpurpose>Identify the chips on a TV card</refpurpose>
-  </refnamediv>
-
-  <refsynopsisdiv>
-    <funcsynopsis>
-      <funcprototype>
-	<funcdef>int <function>ioctl</function></funcdef>
-	<paramdef>int <parameter>fd</parameter></paramdef>
-	<paramdef>int <parameter>request</parameter></paramdef>
-	<paramdef>struct v4l2_dbg_chip_ident
-*<parameter>argp</parameter></paramdef>
-      </funcprototype>
-    </funcsynopsis>
-  </refsynopsisdiv>
-
-  <refsect1>
-    <title>Arguments</title>
-
-    <variablelist>
-      <varlistentry>
-	<term><parameter>fd</parameter></term>
-	<listitem>
-	  <para>&fd;</para>
-	</listitem>
-      </varlistentry>
-      <varlistentry>
-	<term><parameter>request</parameter></term>
-	<listitem>
-	  <para>VIDIOC_DBG_G_CHIP_IDENT</para>
-	</listitem>
-      </varlistentry>
-      <varlistentry>
-	<term><parameter>argp</parameter></term>
-	<listitem>
-	  <para></para>
-	</listitem>
-      </varlistentry>
-    </variablelist>
-  </refsect1>
-
-  <refsect1>
-    <title>Description</title>
-
-    <note>
-      <title>Experimental</title>
-
-      <para>This is an <link
-linkend="experimental">experimental</link> interface and may change in
-the future.</para>
-    </note>
-
-    <para>For driver debugging purposes this ioctl allows test
-applications to query the driver about the chips present on the TV
-card. Regular applications must not use it. When you found a chip
-specific bug, please contact the linux-media mailing list (&v4l-ml;)
-so it can be fixed.</para>
-
-    <para>To query the driver applications must initialize the
-<structfield>match.type</structfield> and
-<structfield>match.addr</structfield> or <structfield>match.name</structfield>
-fields of a &v4l2-dbg-chip-ident;
-and call <constant>VIDIOC_DBG_G_CHIP_IDENT</constant> with a pointer to
-this structure. On success the driver stores information about the
-selected chip in the <structfield>ident</structfield> and
-<structfield>revision</structfield> fields. On failure the structure
-remains unchanged.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_HOST</constant>,
-<structfield>match.addr</structfield> selects the nth non-&i2c; chip
-on the TV card. You can enumerate all chips by starting at zero and
-incrementing <structfield>match.addr</structfield> by one until
-<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.
-The number zero always selects the host chip, &eg; the chip connected
-to the PCI or USB bus.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
-<structfield>match.name</structfield> contains the I2C driver name.
-For instance
-<constant>"saa7127"</constant> will match any chip
-supported by the saa7127 driver, regardless of its &i2c; bus address.
-When multiple chips supported by the same driver are present, the
-ioctl will return <constant>V4L2_IDENT_AMBIGUOUS</constant> in the
-<structfield>ident</structfield> field.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
-<structfield>match.addr</structfield> selects a chip by its 7 bit
-&i2c; bus address.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_AC97</constant>,
-<structfield>match.addr</structfield> selects the nth AC97 chip
-on the TV card. You can enumerate all chips by starting at zero and
-incrementing <structfield>match.addr</structfield> by one until
-<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.</para>
-
-    <para>On success, the <structfield>ident</structfield> field will
-contain a chip ID from the Linux
-<filename>media/v4l2-chip-ident.h</filename> header file, and the
-<structfield>revision</structfield> field will contain a driver
-specific value, or zero if no particular revision is associated with
-this chip.</para>
-
-    <para>When the driver could not identify the selected chip,
-<structfield>ident</structfield> will contain
-<constant>V4L2_IDENT_UNKNOWN</constant>. When no chip matched
-the ioctl will succeed but the
-<structfield>ident</structfield> field will contain
-<constant>V4L2_IDENT_NONE</constant>. If multiple chips matched,
-<structfield>ident</structfield> will contain
-<constant>V4L2_IDENT_AMBIGUOUS</constant>. In all these cases the
-<structfield>revision</structfield> field remains unchanged.</para>
-
-    <para>This ioctl is optional, not all drivers may support it. It
-was introduced in Linux 2.6.21, but the API was changed to the
-one described here in 2.6.29.</para>
-
-    <para>We recommended the <application>v4l2-dbg</application>
-utility over calling this ioctl directly. It is available from the
-LinuxTV v4l-dvb repository; see <ulink
-url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
-access instructions.</para>
-
-    <!-- Note for convenience vidioc-dbg-g-register.sgml
-	 contains a duplicate of this table. -->
-    <table pgwide="1" frame="none" id="ident-v4l2-dbg-match">
-      <title>struct <structname>v4l2_dbg_match</structname></title>
-      <tgroup cols="4">
-	&cs-ustr;
-	<tbody valign="top">
-	  <row>
-	    <entry>__u32</entry>
-	    <entry><structfield>type</structfield></entry>
-	    <entry>See <xref linkend="ident-chip-match-types" /> for a list of
-possible types.</entry>
-	  </row>
-	  <row>
-	    <entry>union</entry>
-	    <entry>(anonymous)</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry>__u32</entry>
-	    <entry><structfield>addr</structfield></entry>
-	    <entry>Match a chip by this number, interpreted according
-to the <structfield>type</structfield> field.</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry>char</entry>
-	    <entry><structfield>name[32]</structfield></entry>
-	    <entry>Match a chip by this name, interpreted according
-to the <structfield>type</structfield> field.</entry>
-	  </row>
-	</tbody>
-      </tgroup>
-    </table>
-
-    <table pgwide="1" frame="none" id="v4l2-dbg-chip-ident">
-      <title>struct <structname>v4l2_dbg_chip_ident</structname></title>
-      <tgroup cols="3">
-	&cs-str;
-	<tbody valign="top">
-	  <row>
-	    <entry>struct v4l2_dbg_match</entry>
-	    <entry><structfield>match</structfield></entry>
-	    <entry>How to match the chip, see <xref linkend="ident-v4l2-dbg-match" />.</entry>
-	  </row>
-	  <row>
-	    <entry>__u32</entry>
-	    <entry><structfield>ident</structfield></entry>
-	    <entry>A chip identifier as defined in the Linux
-<filename>media/v4l2-chip-ident.h</filename> header file, or one of
-the values from <xref linkend="chip-ids" />.</entry>
-	  </row>
-	  <row>
-	    <entry>__u32</entry>
-	    <entry><structfield>revision</structfield></entry>
-	    <entry>A chip revision, chip and driver specific.</entry>
-	  </row>
-	</tbody>
-      </tgroup>
-    </table>
-
-    <!-- Note for convenience vidioc-dbg-g-register.sgml
-	 contains a duplicate of this table. -->
-    <table pgwide="1" frame="none" id="ident-chip-match-types">
-      <title>Chip Match Types</title>
-      <tgroup cols="3">
-	&cs-def;
-	<tbody valign="top">
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_BRIDGE</constant></entry>
-	    <entry>0</entry>
-	    <entry>Match the nth chip on the card, zero for the
-	    bridge chip. Does not match sub-devices.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
-	    <entry>1</entry>
-	    <entry>Match an &i2c; chip by its driver name.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
-	    <entry>2</entry>
-	    <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
-	    <entry>3</entry>
-	    <entry>Match the nth anciliary AC97 chip.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
-	    <entry>4</entry>
-	    <entry>Match the nth sub-device. Can't be used with this ioctl.</entry>
-	  </row>
-	</tbody>
-      </tgroup>
-    </table>
-
-    <!-- This is an anonymous enum in media/v4l2-chip-ident.h. -->
-    <table pgwide="1" frame="none" id="chip-ids">
-      <title>Chip Identifiers</title>
-      <tgroup cols="3">
-	&cs-def;
-	<tbody valign="top">
-	  <row>
-	    <entry><constant>V4L2_IDENT_NONE</constant></entry>
-	    <entry>0</entry>
-	    <entry>No chip matched.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_IDENT_AMBIGUOUS</constant></entry>
-	    <entry>1</entry>
-	    <entry>Multiple chips matched.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_IDENT_UNKNOWN</constant></entry>
-	    <entry>2</entry>
-	    <entry>A chip is present at this address, but the driver
-could not identify it.</entry>
-	  </row>
-	</tbody>
-      </tgroup>
-    </table>
-  </refsect1>
-
-  <refsect1>
-    &return-value;
-
-    <variablelist>
-      <varlistentry>
-	<term><errorcode>EINVAL</errorcode></term>
-	<listitem>
-	  <para>The <structfield>match_type</structfield> is invalid.</para>
-	</listitem>
-      </varlistentry>
-     </variablelist>
-  </refsect1>
-</refentry>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml
--- linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml	2013-08-25 20:43:22.000000000 -0400
@@ -73,8 +73,7 @@ fields of a &v4l2-dbg-chip-info;
 and call <constant>VIDIOC_DBG_G_CHIP_INFO</constant> with a pointer to
 this structure. On success the driver stores information about the
 selected chip in the <structfield>name</structfield> and
-<structfield>flags</structfield> fields. On failure the structure
-remains unchanged.</para>
+<structfield>flags</structfield> fields.</para>
 
     <para>When <structfield>match.type</structfield> is
 <constant>V4L2_CHIP_MATCH_BRIDGE</constant>,
@@ -132,7 +131,7 @@ to the <structfield>type</structfield> f
 	    <entry>char</entry>
 	    <entry><structfield>name[32]</structfield></entry>
 	    <entry>Match a chip by this name, interpreted according
-to the <structfield>type</structfield> field.</entry>
+to the <structfield>type</structfield> field. Currently unused.</entry>
 	  </row>
 	</tbody>
       </tgroup>
@@ -183,21 +182,6 @@ is set, then the driver supports reading
 	    bridge chip. Does not match sub-devices.</entry>
 	  </row>
 	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
-	    <entry>1</entry>
-	    <entry>Match an &i2c; chip by its driver name. Can't be used with this ioctl.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
-	    <entry>2</entry>
-	    <entry>Match a chip by its 7 bit &i2c; bus address. Can't be used with this ioctl.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
-	    <entry>3</entry>
-	    <entry>Match the nth anciliary AC97 chip. Can't be used with this ioctl.</entry>
-	  </row>
-	  <row>
 	    <entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
 	    <entry>4</entry>
 	    <entry>Match the nth sub-device.</entry>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml
--- linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml	2013-08-25 20:43:22.000000000 -0400
@@ -76,7 +76,7 @@ compiled with the <constant>CONFIG_VIDEO
 to enable these ioctls.</para>
 
     <para>To write a register applications must initialize all fields
-of a &v4l2-dbg-register; and call
+of a &v4l2-dbg-register; except for <structfield>size</structfield> and call
 <constant>VIDIOC_DBG_S_REGISTER</constant> with a pointer to this
 structure. The <structfield>match.type</structfield> and
 <structfield>match.addr</structfield> or <structfield>match.name</structfield>
@@ -91,8 +91,8 @@ written into the register.</para>
 <structfield>reg</structfield> fields, and call
 <constant>VIDIOC_DBG_G_REGISTER</constant> with a pointer to this
 structure. On success the driver stores the register value in the
-<structfield>val</structfield> field. On failure the structure remains
-unchanged.</para>
+<structfield>val</structfield> field and the size (in bytes) of the
+value in <structfield>size</structfield>.</para>
 
     <para>When <structfield>match.type</structfield> is
 <constant>V4L2_CHIP_MATCH_BRIDGE</constant>,
@@ -102,39 +102,9 @@ chip connected to the PCI or USB bus. Yo
 present with the &VIDIOC-DBG-G-CHIP-INFO; ioctl.</para>
 
     <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
-<structfield>match.name</structfield> contains the I2C driver name.
-For instance
-<constant>"saa7127"</constant> will match any chip
-supported by the saa7127 driver, regardless of its &i2c; bus address.
-When multiple chips supported by the same driver are present, the
-effect of these ioctls is undefined. Again with the
-&VIDIOC-DBG-G-CHIP-INFO; ioctl you can find out which &i2c; chips are
-present.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
-<structfield>match.addr</structfield> selects a chip by its 7 bit &i2c;
-bus address.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_AC97</constant>,
-<structfield>match.addr</structfield> selects the nth AC97 chip
-on the TV card.</para>
-
-    <para>When <structfield>match.type</structfield> is
 <constant>V4L2_CHIP_MATCH_SUBDEV</constant>,
 <structfield>match.addr</structfield> selects the nth sub-device.</para>
 
-    <note>
-      <title>Success not guaranteed</title>
-
-      <para>Due to a flaw in the Linux &i2c; bus driver these ioctls may
-return successfully without actually reading or writing a register. To
-catch the most likely failure we recommend a &VIDIOC-DBG-G-CHIP-INFO;
-call confirming the presence of the selected &i2c; chip.</para>
-    </note>
-
     <para>These ioctls are optional, not all drivers may support them.
 However when a driver supports these ioctls it must also support
 &VIDIOC-DBG-G-CHIP-INFO;. Conversely it may support
@@ -150,7 +120,7 @@ LinuxTV v4l-dvb repository; see <ulink
 url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
 access instructions.</para>
 
-    <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+    <!-- Note for convenience vidioc-dbg-g-chip-info.sgml
 	 contains a duplicate of this table. -->
     <table pgwide="1" frame="none" id="v4l2-dbg-match">
       <title>struct <structname>v4l2_dbg_match</structname></title>
@@ -160,7 +130,7 @@ access instructions.</para>
 	  <row>
 	    <entry>__u32</entry>
 	    <entry><structfield>type</structfield></entry>
-	    <entry>See <xref linkend="ident-chip-match-types" /> for a list of
+	    <entry>See <xref linkend="chip-match-types" /> for a list of
 possible types.</entry>
 	  </row>
 	  <row>
@@ -179,7 +149,7 @@ to the <structfield>type</structfield> f
 	    <entry>char</entry>
 	    <entry><structfield>name[32]</structfield></entry>
 	    <entry>Match a chip by this name, interpreted according
-to the <structfield>type</structfield> field.</entry>
+to the <structfield>type</structfield> field. Currently unused.</entry>
 	  </row>
 	</tbody>
       </tgroup>
@@ -199,6 +169,11 @@ to the <structfield>type</structfield> f
 	    <entry>How to match the chip, see <xref linkend="v4l2-dbg-match" />.</entry>
 	  </row>
 	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>size</structfield></entry>
+	    <entry>The register size in bytes.</entry>
+	  </row>
+	  <row>
 	    <entry>__u64</entry>
 	    <entry><structfield>reg</structfield></entry>
 	    <entry>A register number.</entry>
@@ -213,7 +188,7 @@ register.</entry>
       </tgroup>
     </table>
 
-    <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+    <!-- Note for convenience vidioc-dbg-g-chip-info.sgml
 	 contains a duplicate of this table. -->
     <table pgwide="1" frame="none" id="chip-match-types">
       <title>Chip Match Types</title>
@@ -227,21 +202,6 @@ register.</entry>
 	    bridge chip. Does not match sub-devices.</entry>
 	  </row>
 	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
-	    <entry>1</entry>
-	    <entry>Match an &i2c; chip by its driver name.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
-	    <entry>2</entry>
-	    <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
-	    <entry>3</entry>
-	    <entry>Match the nth anciliary AC97 chip.</entry>
-	  </row>
-	  <row>
 	    <entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
 	    <entry>4</entry>
 	    <entry>Match the nth sub-device.</entry>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/vidioc-querystd.xml linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/vidioc-querystd.xml
--- linux-libre-3.10-gnu/Documentation/DocBook/media/v4l/vidioc-querystd.xml	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media/v4l/vidioc-querystd.xml	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,8 @@ standard automatically. To do so, applic
 VIDIOC_QUERYSTD</constant> with a pointer to a &v4l2-std-id; type. The
 driver stores here a set of candidates, this can be a single flag or a
 set of supported standards if for example the hardware can only
-distinguish between 50 and 60 Hz systems. When detection is not
+distinguish between 50 and 60 Hz systems. If no signal was detected,
+then the driver will return V4L2_STD_UNKNOWN. When detection is not
 possible or fails, the set must contain all standards supported by the
 current video input or output.</para>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/media_api.tmpl linux-libre-3.11-rc7-gnu/Documentation/DocBook/media_api.tmpl
--- linux-libre-3.10-gnu/Documentation/DocBook/media_api.tmpl	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/media_api.tmpl	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+	"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
 <!ENTITY % media-entities SYSTEM "./media-entities.tmpl"> %media-entities;
 <!ENTITY media-indices SYSTEM "./media-indices.tmpl">
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/DocBook/writing_usb_driver.tmpl linux-libre-3.11-rc7-gnu/Documentation/DocBook/writing_usb_driver.tmpl
--- linux-libre-3.10-gnu/Documentation/DocBook/writing_usb_driver.tmpl	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/DocBook/writing_usb_driver.tmpl	2013-08-25 20:43:22.000000000 -0400
@@ -83,7 +83,7 @@
   </para>
   <para>
       Because each different protocol causes a new driver to be created, I have
-      written a generic USB driver skeleton, modeled after the pci-skeleton.c
+      written a generic USB driver skeleton, modelled after the pci-skeleton.c
       file in the kernel source tree upon which many PCI network drivers have
       been based. This USB skeleton can be found at drivers/usb/usb-skeleton.c
       in the kernel source tree. In this article I will walk through the basics
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/dynamic-debug-howto.txt linux-libre-3.11-rc7-gnu/Documentation/dynamic-debug-howto.txt
--- linux-libre-3.10-gnu/Documentation/dynamic-debug-howto.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/dynamic-debug-howto.txt	2013-08-25 20:43:22.000000000 -0400
@@ -279,7 +279,7 @@ The dyndbg option is a "fake" module par
 
 - modules do not need to define it explicitly
 - every module gets it tacitly, whether they use pr_debug or not
-- it doesnt appear in /sys/module/$module/parameters/
+- it doesn't appear in /sys/module/$module/parameters/
   To see it, grep the control file, or inspect /proc/cmdline.
 
 For CONFIG_DYNAMIC_DEBUG kernels, any settings given at boot-time (or
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/early-userspace/README linux-libre-3.11-rc7-gnu/Documentation/early-userspace/README
--- linux-libre-3.10-gnu/Documentation/early-userspace/README	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/early-userspace/README	2013-08-25 20:43:22.000000000 -0400
@@ -71,7 +71,7 @@ can really be interpreted as any legal a
 gen_initramfs_list.sh.  If a directory is specified as an argument then
 the contents are scanned, uid/gid translation is performed, and
 usr/gen_init_cpio file directives are output.  If a directory is
-specified as an arugemnt to scripts/gen_initramfs_list.sh then the
+specified as an argument to scripts/gen_initramfs_list.sh then the
 contents of the file are simply copied to the output.  All of the output
 directives from directory scanning and file contents copying are
 processed by usr/gen_init_cpio.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fb/cirrusfb.txt linux-libre-3.11-rc7-gnu/Documentation/fb/cirrusfb.txt
--- linux-libre-3.10-gnu/Documentation/fb/cirrusfb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/fb/cirrusfb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -55,7 +55,7 @@ Version 1.9.4.4
 * Overhaul color register routines.
 * Associated with the above, console colors are now obtained from a LUT
   called 'palette' instead of from the VGA registers.  This code was
-  modeled after that in atyfb and matroxfb.
+  modelled after that in atyfb and matroxfb.
 * Code cleanup, add comments.
 * Overhaul SR07 handling.
 * Bug fixes.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fb/uvesafb.txt linux-libre-3.11-rc7-gnu/Documentation/fb/uvesafb.txt
--- linux-libre-3.10-gnu/Documentation/fb/uvesafb.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/fb/uvesafb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -81,17 +81,11 @@ pmipal  Use the protected mode interface
 
 mtrr:n  Setup memory type range registers for the framebuffer
         where n:
-              0 - disabled (equivalent to nomtrr) (default)
-              1 - uncachable
-              2 - write-back
-              3 - write-combining
-              4 - write-through
+              0 - disabled (equivalent to nomtrr)
+              3 - write-combining (default)
 
-        If you see the following in dmesg, choose the type that matches
-        the old one.  In this example, use "mtrr:2".
-...
-mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
-...
+	Values other than 0 and 3 will result in a warning and will be
+	treated just like 3.
 
 nomtrr  Do not use memory type range registers.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/filesystems/f2fs.txt linux-libre-3.11-rc7-gnu/Documentation/filesystems/f2fs.txt
--- linux-libre-3.10-gnu/Documentation/filesystems/f2fs.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/filesystems/f2fs.txt	2013-08-25 20:43:22.000000000 -0400
@@ -98,8 +98,13 @@ Cleaning Overhead
 MOUNT OPTIONS
 ================================================================================
 
-background_gc_off      Turn off cleaning operations, namely garbage collection,
-		       triggered in background when I/O subsystem is idle.
+background_gc=%s       Turn on/off cleaning operations, namely garbage
+                       collection, triggered in background when I/O subsystem is
+                       idle. If background_gc=on, it will turn on the garbage
+                       collection and if background_gc=off, garbage collection
+                       will be truned off.
+                       Default value for this option is on. So garbage
+                       collection is on by default.
 disable_roll_forward   Disable the roll-forward recovery routine
 discard                Issue discard/TRIM commands when a segment is cleaned.
 no_heap                Disable heap-style segment allocation which finds free
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/filesystems/jfs.txt linux-libre-3.11-rc7-gnu/Documentation/filesystems/jfs.txt
--- linux-libre-3.10-gnu/Documentation/filesystems/jfs.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/filesystems/jfs.txt	2013-08-25 20:43:22.000000000 -0400
@@ -42,7 +42,7 @@ nodiscard(*)	block device when blocks ar
 		devices and sparse/thinly-provisioned LUNs.  The FITRIM ioctl
 		command is also available together with the nodiscard option.
 		The value of minlen specifies the minimum blockcount, when
-		a TRIM command to the block device is considered usefull.
+		a TRIM command to the block device is considered useful.
 		When no value is given to the discard option, it defaults to
 		64 blocks, which means 256KiB in JFS.
 		The minlen value of discard overrides the minlen value given
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/filesystems/Locking linux-libre-3.11-rc7-gnu/Documentation/filesystems/Locking
--- linux-libre-3.10-gnu/Documentation/filesystems/Locking	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/filesystems/Locking	2013-08-25 20:43:22.000000000 -0400
@@ -11,10 +11,8 @@ be able to use diff(1).
 prototypes:
 	int (*d_revalidate)(struct dentry *, unsigned int);
 	int (*d_weak_revalidate)(struct dentry *, unsigned int);
-	int (*d_hash)(const struct dentry *, const struct inode *,
-			struct qstr *);
-	int (*d_compare)(const struct dentry *, const struct inode *,
-			const struct dentry *, const struct inode *,
+	int (*d_hash)(const struct dentry *, struct qstr *);
+	int (*d_compare)(const struct dentry *, const struct dentry *,
 			unsigned int, const char *, const struct qstr *);
 	int (*d_delete)(struct dentry *);
 	void (*d_release)(struct dentry *);
@@ -66,6 +64,7 @@ prototypes:
 	int (*atomic_open)(struct inode *, struct dentry *,
 				struct file *, unsigned open_flag,
 				umode_t create_mode, int *opened);
+	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
 
 locking rules:
 	all may block
@@ -93,6 +92,7 @@ removexattr:	yes
 fiemap:		no
 update_time:	no
 atomic_open:	yes
+tmpfile:	no
 
 	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
 victim.
@@ -189,7 +189,7 @@ prototypes:
 				loff_t pos, unsigned len, unsigned copied,
 				struct page *page, void *fsdata);
 	sector_t (*bmap)(struct address_space *, sector_t);
-	int (*invalidatepage) (struct page *, unsigned long);
+	void (*invalidatepage) (struct page *, unsigned int, unsigned int);
 	int (*releasepage) (struct page *, int);
 	void (*freepage)(struct page *);
 	int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
@@ -310,8 +310,8 @@ filesystems and by the swapper. The latt
 keep it that way and don't breed new callers.
 
 	->invalidatepage() is called when the filesystem must attempt to drop
-some or all of the buffers from the page when it is being truncated.  It
-returns zero on success.  If ->invalidatepage is zero, the kernel uses
+some or all of the buffers from the page when it is being truncated. It
+returns zero on success. If ->invalidatepage is zero, the kernel uses
 block_invalidatepage() instead.
 
 	->releasepage() is called when the kernel is about to try to drop the
@@ -344,25 +344,38 @@ prototypes:
 
 
 locking rules:
-			file_lock_lock	may block
+			inode->i_lock	may block
 fl_copy_lock:		yes		no
 fl_release_private:	maybe		no
 
 ----------------------- lock_manager_operations ---------------------------
 prototypes:
 	int (*lm_compare_owner)(struct file_lock *, struct file_lock *);
+	unsigned long (*lm_owner_key)(struct file_lock *);
 	void (*lm_notify)(struct file_lock *);  /* unblock callback */
 	int (*lm_grant)(struct file_lock *, struct file_lock *, int);
 	void (*lm_break)(struct file_lock *); /* break_lease callback */
 	int (*lm_change)(struct file_lock **, int);
 
 locking rules:
-			file_lock_lock	may block
-lm_compare_owner:	yes		no
-lm_notify:		yes		no
-lm_grant:		no		no
-lm_break:		yes		no
-lm_change		yes		no
+
+			inode->i_lock	blocked_lock_lock	may block
+lm_compare_owner:	yes[1]		maybe			no
+lm_owner_key		yes[1]		yes			no
+lm_notify:		yes		yes			no
+lm_grant:		no		no			no
+lm_break:		yes		no			no
+lm_change		yes		no			no
+
+[1]:	->lm_compare_owner and ->lm_owner_key are generally called with
+*an* inode->i_lock held. It may not be the i_lock of the inode
+associated with either file_lock argument! This is the case with deadlock
+detection, since the code has to chase down the owners of locks that may
+be entirely unrelated to the one on which the lock is being acquired.
+For deadlock detection however, the blocked_lock_lock is also held. The
+fact that these locks are held ensures that the file_locks do not
+disappear out from under you while doing the comparison or generating an
+owner key.
 
 --------------------------- buffer_head -----------------------------------
 prototypes:
@@ -414,7 +427,7 @@ prototypes:
 	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
 	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
 	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
-	int (*readdir) (struct file *, void *, filldir_t);
+	int (*iterate) (struct file *, struct dir_context *);
 	unsigned int (*poll) (struct file *, struct poll_table_struct *);
 	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
 	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/filesystems/porting linux-libre-3.11-rc7-gnu/Documentation/filesystems/porting
--- linux-libre-3.10-gnu/Documentation/filesystems/porting	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/filesystems/porting	2013-08-25 20:43:22.000000000 -0400
@@ -445,3 +445,9 @@ object doesn't exist.  It's remote/distr
 [mandatory]
 	FS_REVAL_DOT is gone; if you used to have it, add ->d_weak_revalidate()
 in your dentry operations instead.
+--
+[mandatory]
+	vfs_readdir() is gone; switch to iterate_dir() instead
+--
+[mandatory]
+	->readdir() is gone now; switch to ->iterate()
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/filesystems/proc.txt linux-libre-3.11-rc7-gnu/Documentation/filesystems/proc.txt
--- linux-libre-3.10-gnu/Documentation/filesystems/proc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/filesystems/proc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -473,7 +473,8 @@ This file is only present if the CONFIG_
 enabled.
 
 The /proc/PID/clear_refs is used to reset the PG_Referenced and ACCESSED/YOUNG
-bits on both physical and virtual pages associated with a process.
+bits on both physical and virtual pages associated with a process, and the
+soft-dirty bit on pte (see Documentation/vm/soft-dirty.txt for details).
 To clear the bits for all the pages associated with the process
     > echo 1 > /proc/PID/clear_refs
 
@@ -482,6 +483,10 @@ To clear the bits for the anonymous page
 
 To clear the bits for the file mapped pages associated with the process
     > echo 3 > /proc/PID/clear_refs
+
+To clear the soft-dirty bit
+    > echo 4 > /proc/PID/clear_refs
+
 Any other value written to /proc/PID/clear_refs will have no effect.
 
 The /proc/pid/pagemap gives the PFN, which can be used to find the pageflags
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/filesystems/qnx6.txt linux-libre-3.11-rc7-gnu/Documentation/filesystems/qnx6.txt
--- linux-libre-3.10-gnu/Documentation/filesystems/qnx6.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/filesystems/qnx6.txt	2013-08-25 20:43:22.000000000 -0400
@@ -148,7 +148,7 @@ smaller than addressing space in the bit
 Bitmap system area
 ------------------
 
-The bitmap itself is devided into three parts.
+The bitmap itself is divided into three parts.
 First the system area, that is split into two halfs.
 Then userspace.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/filesystems/vfat.txt linux-libre-3.11-rc7-gnu/Documentation/filesystems/vfat.txt
--- linux-libre-3.10-gnu/Documentation/filesystems/vfat.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/filesystems/vfat.txt	2013-08-25 20:43:22.000000000 -0400
@@ -307,7 +307,7 @@ the following:
 
                 <proceeding files...>
                 <slot #3, id = 0x43, characters = "h is long">
-                <slot #2, id = 0x02, characters = "xtension whic">
+                <slot #2, id = 0x02, characters = "xtension which">
                 <slot #1, id = 0x01, characters = "My Big File.E">
                 <directory entry, name = "MYBIGFIL.EXT">
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/filesystems/vfs.txt linux-libre-3.11-rc7-gnu/Documentation/filesystems/vfs.txt
--- linux-libre-3.10-gnu/Documentation/filesystems/vfs.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/filesystems/vfs.txt	2013-08-25 20:43:22.000000000 -0400
@@ -360,6 +360,8 @@ struct inode_operations {
 	int (*removexattr) (struct dentry *, const char *);
 	void (*update_time)(struct inode *, struct timespec *, int);
 	int (*atomic_open)(struct inode *, struct dentry *,
+	int (*tmpfile) (struct inode *, struct dentry *, umode_t);
+} ____cacheline_aligned;
 				struct file *, unsigned open_flag,
 				umode_t create_mode, int *opened);
 };
@@ -472,6 +474,9 @@ otherwise noted.
   	component is negative or needs lookup.  Cached positive dentries are
   	still handled by f_op->open().
 
+  tmpfile: called in the end of O_TMPFILE open().  Optional, equivalent to
+	atomically creating, opening and unlinking a file in given directory.
+
 The Address Space Object
 ========================
 
@@ -549,12 +554,11 @@ struct address_space_operations
 -------------------------------
 
 This describes how the VFS can manipulate mapping of a file to page cache in
-your filesystem. As of kernel 2.6.22, the following members are defined:
+your filesystem. The following members are defined:
 
 struct address_space_operations {
 	int (*writepage)(struct page *page, struct writeback_control *wbc);
 	int (*readpage)(struct file *, struct page *);
-	int (*sync_page)(struct page *);
 	int (*writepages)(struct address_space *, struct writeback_control *);
 	int (*set_page_dirty)(struct page *page);
 	int (*readpages)(struct file *filp, struct address_space *mapping,
@@ -566,7 +570,7 @@ struct address_space_operations {
 				loff_t pos, unsigned len, unsigned copied,
 				struct page *page, void *fsdata);
 	sector_t (*bmap)(struct address_space *, sector_t);
-	int (*invalidatepage) (struct page *, unsigned long);
+	void (*invalidatepage) (struct page *, unsigned int, unsigned int);
 	int (*releasepage) (struct page *, int);
 	void (*freepage)(struct page *);
 	ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
@@ -576,6 +580,9 @@ struct address_space_operations {
 	/* migrate the contents of a page to the specified target */
 	int (*migratepage) (struct page *, struct page *);
 	int (*launder_page) (struct page *);
+	int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
+					unsigned long);
+	void (*is_dirty_writeback) (struct page *, bool *, bool *);
 	int (*error_remove_page) (struct mapping *mapping, struct page *page);
 	int (*swap_activate)(struct file *);
 	int (*swap_deactivate)(struct file *);
@@ -607,13 +614,6 @@ struct address_space_operations {
        In this case, the page will be relocated, relocked and if
        that all succeeds, ->readpage will be called again.
 
-  sync_page: called by the VM to notify the backing store to perform all
-  	queued I/O operations for a page. I/O operations for other pages
-	associated with this address_space object may also be performed.
-
-	This function is optional and is called only for pages with
-  	PG_Writeback set while waiting for the writeback to complete.
-
   writepages: called by the VM to write out pages associated with the
   	address_space object.  If wbc->sync_mode is WBC_SYNC_ALL, then
   	the writeback_control will specify a range of pages that must be
@@ -685,14 +685,14 @@ struct address_space_operations {
   invalidatepage: If a page has PagePrivate set, then invalidatepage
         will be called when part or all of the page is to be removed
 	from the address space.  This generally corresponds to either a
-	truncation or a complete invalidation of the address space
-	(in the latter case 'offset' will always be 0).
-	Any private data associated with the page should be updated
-	to reflect this truncation.  If offset is 0, then
-	the private data should be released, because the page
-	must be able to be completely discarded.  This may be done by
-        calling the ->releasepage function, but in this case the
-        release MUST succeed.
+	truncation, punch hole  or a complete invalidation of the address
+	space (in the latter case 'offset' will always be 0 and 'length'
+	will be PAGE_CACHE_SIZE). Any private data associated with the page
+	should be updated to reflect this truncation.  If offset is 0 and
+	length is PAGE_CACHE_SIZE, then the private data should be released,
+	because the page must be able to be completely discarded.  This may
+	be done by calling the ->releasepage function, but in this case the
+	release MUST succeed.
 
   releasepage: releasepage is called on PagePrivate pages to indicate
         that the page should be freed if possible.  ->releasepage
@@ -742,6 +742,20 @@ struct address_space_operations {
   	prevent redirtying the page, it is kept locked during the whole
 	operation.
 
+  is_partially_uptodate: Called by the VM when reading a file through the
+	pagecache when the underlying blocksize != pagesize. If the required
+	block is up to date then the read can complete without needing the IO
+	to bring the whole page up to date.
+
+  is_dirty_writeback: Called by the VM when attempting to reclaim a page.
+	The VM uses dirty and writeback information to determine if it needs
+	to stall to allow flushers a chance to complete some IO. Ordinarily
+	it can use PageDirty and PageWriteback but some filesystems have
+	more complex state (unstable pages in NFS prevent reclaim) or
+	do not set those flags due to locking problems (jbd). This callback
+	allows a filesystem to indicate to the VM if a page should be
+	treated as dirty or writeback for the purposes of stalling.
+
   error_remove_page: normally set to generic_error_remove_page if truncation
 	is ok for this address space. Used for memory failure handling.
 	Setting this implies you deal with pages going away under you,
@@ -777,7 +791,7 @@ struct file_operations {
 	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
 	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
 	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
-	int (*readdir) (struct file *, void *, filldir_t);
+	int (*iterate) (struct file *, struct dir_context *);
 	unsigned int (*poll) (struct file *, struct poll_table_struct *);
 	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
 	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
@@ -815,7 +829,7 @@ otherwise noted.
 
   aio_write: called by io_submit(2) and other asynchronous I/O operations
 
-  readdir: called when the VFS needs to read the directory contents
+  iterate: called when the VFS needs to read the directory contents
 
   poll: called by the VFS when a process wants to check if there is
 	activity on this file and (optionally) go to sleep until there
@@ -901,10 +915,8 @@ defined:
 struct dentry_operations {
 	int (*d_revalidate)(struct dentry *, unsigned int);
 	int (*d_weak_revalidate)(struct dentry *, unsigned int);
-	int (*d_hash)(const struct dentry *, const struct inode *,
-			struct qstr *);
-	int (*d_compare)(const struct dentry *, const struct inode *,
-			const struct dentry *, const struct inode *,
+	int (*d_hash)(const struct dentry *, struct qstr *);
+	int (*d_compare)(const struct dentry *, const struct dentry *,
 			unsigned int, const char *, const struct qstr *);
 	int (*d_delete)(const struct dentry *);
 	void (*d_release)(struct dentry *);
@@ -949,25 +961,24 @@ struct dentry_operations {
 
   d_hash: called when the VFS adds a dentry to the hash table. The first
 	dentry passed to d_hash is the parent directory that the name is
-	to be hashed into. The inode is the dentry's inode.
+	to be hashed into.
 
 	Same locking and synchronisation rules as d_compare regarding
 	what is safe to dereference etc.
 
   d_compare: called to compare a dentry name with a given name. The first
 	dentry is the parent of the dentry to be compared, the second is
-	the parent's inode, then the dentry and inode (may be NULL) of the
-	child dentry. len and name string are properties of the dentry to be
-	compared. qstr is the name to compare it with.
+	the child dentry. len and name string are properties of the dentry
+	to be compared. qstr is the name to compare it with.
 
 	Must be constant and idempotent, and should not take locks if
-	possible, and should not or store into the dentry or inodes.
-	Should not dereference pointers outside the dentry or inodes without
+	possible, and should not or store into the dentry.
+	Should not dereference pointers outside the dentry without
 	lots of care (eg.  d_parent, d_inode, d_name should not be used).
 
 	However, our vfsmount is pinned, and RCU held, so the dentries and
 	inodes won't disappear, neither will our sb or filesystem module.
-	->i_sb and ->d_sb may be used.
+	->d_sb may be used.
 
 	It is a tricky calling convention because it needs to be called under
 	"rcu-walk", ie. without any locks or references on things.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/filesystems/xfs.txt linux-libre-3.11-rc7-gnu/Documentation/filesystems/xfs.txt
--- linux-libre-3.10-gnu/Documentation/filesystems/xfs.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/filesystems/xfs.txt	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,8 @@ Mount Options
 =============
 
 When mounting an XFS filesystem, the following options are accepted.
+For boolean mount options, the names with the (*) suffix is the
+default behaviour.
 
   allocsize=size
 	Sets the buffered I/O end-of-file preallocation size when
@@ -25,97 +27,128 @@ When mounting an XFS filesystem, the fol
 	Valid values for this option are page size (typically 4KiB)
 	through to 1GiB, inclusive, in power-of-2 increments.
 
-  attr2/noattr2
-	The options enable/disable (default is disabled for backward
-	compatibility on-disk) an "opportunistic" improvement to be
-	made in the way inline extended attributes are stored on-disk.
-	When the new form is used for the first time (by setting or
-	removing extended attributes) the on-disk superblock feature
-	bit field will be updated to reflect this format being in use.
+	The default behaviour is for dynamic end-of-file
+	preallocation size, which uses a set of heuristics to
+	optimise the preallocation size based on the current
+	allocation patterns within the file and the access patterns
+	to the file. Specifying a fixed allocsize value turns off
+	the dynamic behaviour.
+
+  attr2
+  noattr2
+	The options enable/disable an "opportunistic" improvement to
+	be made in the way inline extended attributes are stored
+	on-disk.  When the new form is used for the first time when
+	attr2 is selected (either when setting or removing extended
+	attributes) the on-disk superblock feature bit field will be
+	updated to reflect this format being in use.
+
+	The default behaviour is determined by the on-disk feature
+	bit indicating that attr2 behaviour is active. If either
+	mount option it set, then that becomes the new default used
+	by the filesystem.
 
 	CRC enabled filesystems always use the attr2 format, and so
 	will reject the noattr2 mount option if it is set.
 
-  barrier
-	Enables the use of block layer write barriers for writes into
-	the journal and unwritten extent conversion.  This allows for
-	drive level write caching to be enabled, for devices that
-	support write barriers.
+  barrier (*)
+  nobarrier
+	Enables/disables the use of block layer write barriers for
+	writes into the journal and for data integrity operations.
+	This allows for drive level write caching to be enabled, for
+	devices that support write barriers.
 
   discard
-	Issue command to let the block device reclaim space freed by the
-	filesystem.  This is useful for SSD devices, thinly provisioned
-	LUNs and virtual machine images, but may have a performance
-	impact.
-
-  dmapi
-	Enable the DMAPI (Data Management API) event callouts.
-	Use with the "mtpt" option.
+  nodiscard (*)
+	Enable/disable the issuing of commands to let the block
+	device reclaim space freed by the filesystem.  This is
+	useful for SSD devices, thinly provisioned LUNs and virtual
+	machine images, but may have a performance impact.
 
-  grpid/bsdgroups and nogrpid/sysvgroups
-	These options define what group ID a newly created file gets.
-	When grpid is set, it takes the group ID of the directory in
-	which it is created; otherwise (the default) it takes the fsgid
-	of the current process, unless the directory has the setgid bit
-	set, in which case it takes the gid from the parent directory,
-	and also gets the setgid bit set if it is a directory itself.
+	Note: It is currently recommended that you use the fstrim
+	application to discard unused blocks rather than the discard
+	mount option because the performance impact of this option
+	is quite severe.
 
-  ihashsize=value
-	In memory inode hashes have been removed, so this option has
-	no function as of August 2007. Option is deprecated.
+  grpid/bsdgroups
+  nogrpid/sysvgroups (*)
+	These options define what group ID a newly created file
+	gets.  When grpid is set, it takes the group ID of the
+	directory in which it is created; otherwise it takes the
+	fsgid of the current process, unless the directory has the
+	setgid bit set, in which case it takes the gid from the
+	parent directory, and also gets the setgid bit set if it is
+	a directory itself.
 
-  ikeep/noikeep
-	When ikeep is specified, XFS does not delete empty inode clusters
-	and keeps them around on disk. ikeep is the traditional XFS
-	behaviour. When noikeep is specified, empty inode clusters
-	are returned to the free space pool. The default is noikeep for
-	non-DMAPI mounts, while ikeep is the default when DMAPI is in use.
+  filestreams
+	Make the data allocator use the filestreams allocation mode
+	across the entire filesystem rather than just on directories
+	configured to use it.
 
-  inode64
-	Indicates that XFS is allowed to create inodes at any location
-	in the filesystem, including those which will result in inode
-	numbers occupying more than 32 bits of significance.  This is
-	the default allocation option. Applications which do not handle
-	inode numbers bigger than 32 bits, should use inode32 option.
+  ikeep
+  noikeep (*)
+	When ikeep is specified, XFS does not delete empty inode
+	clusters and keeps them around on disk.  When noikeep is
+	specified, empty inode clusters are returned to the free
+	space pool.
 
   inode32
-	Indicates that XFS is limited to create inodes at locations which
-	will not result in inode numbers with more than 32 bits of
-	significance. This is provided for backwards compatibility, since
-	64 bits inode numbers might cause problems for some applications
-	that cannot handle large inode numbers.
+  inode64 (*)
+	When inode32 is specified, it indicates that XFS limits
+	inode creation to locations which will not result in inode
+	numbers with more than 32 bits of significance.
 
-  largeio/nolargeio
+	When inode64 is specified, it indicates that XFS is allowed
+	to create inodes at any location in the filesystem,
+	including those which will result in inode numbers occupying
+	more than 32 bits of significance. 
+
+	inode32 is provided for backwards compatibility with older
+	systems and applications, since 64 bits inode numbers might
+	cause problems for some applications that cannot handle
+	large inode numbers.  If applications are in use which do
+	not handle inode numbers bigger than 32 bits, the inode32
+	option should be specified.
+
+
+  largeio
+  nolargeio (*)
 	If "nolargeio" is specified, the optimal I/O reported in
-	st_blksize by stat(2) will be as small as possible to allow user
-	applications to avoid inefficient read/modify/write I/O.
-	If "largeio" specified, a filesystem that has a "swidth" specified
-	will return the "swidth" value (in bytes) in st_blksize. If the
-	filesystem does not have a "swidth" specified but does specify
-	an "allocsize" then "allocsize" (in bytes) will be returned
-	instead.
-	If neither of these two options are specified, then filesystem
-	will behave as if "nolargeio" was specified.
+	st_blksize by stat(2) will be as small as possible to allow
+	user applications to avoid inefficient read/modify/write
+	I/O.  This is typically the page size of the machine, as
+	this is the granularity of the page cache.
+
+	If "largeio" specified, a filesystem that was created with a
+	"swidth" specified will return the "swidth" value (in bytes)
+	in st_blksize. If the filesystem does not have a "swidth"
+	specified but does specify an "allocsize" then "allocsize"
+	(in bytes) will be returned instead. Otherwise the behaviour
+	is the same as if "nolargeio" was specified.
 
   logbufs=value
-	Set the number of in-memory log buffers.  Valid numbers range
-	from 2-8 inclusive.
-	The default value is 8 buffers for filesystems with a
-	blocksize of 64KiB, 4 buffers for filesystems with a blocksize
-	of 32KiB, 3 buffers for filesystems with a blocksize of 16KiB
-	and 2 buffers for all other configurations.  Increasing the
-	number of buffers may increase performance on some workloads
-	at the cost of the memory used for the additional log buffers
-	and their associated control structures.
+	Set the number of in-memory log buffers.  Valid numbers
+	range from 2-8 inclusive.
+
+	The default value is 8 buffers.
+
+	If the memory cost of 8 log buffers is too high on small
+	systems, then it may be reduced at some cost to performance
+	on metadata intensive workloads. The logbsize option below
+	controls the size of each buffer and so is also relevent to
+	this case.
 
   logbsize=value
-	Set the size of each in-memory log buffer.
-	Size may be specified in bytes, or in kilobytes with a "k" suffix.
-	Valid sizes for version 1 and version 2 logs are 16384 (16k) and
-	32768 (32k).  Valid sizes for version 2 logs also include
-	65536 (64k), 131072 (128k) and 262144 (256k).
-	The default value for machines with more than 32MiB of memory
-	is 32768, machines with less memory use 16384 by default.
+	Set the size of each in-memory log buffer.  The size may be
+	specified in bytes, or in kilobytes with a "k" suffix.
+	Valid sizes for version 1 and version 2 logs are 16384 (16k)
+	and 32768 (32k).  Valid sizes for version 2 logs also
+	include 65536 (64k), 131072 (128k) and 262144 (256k). The
+	logbsize must be an integer multiple of the log
+	stripe unit configured at mkfs time.
+
+	The default value for for version 1 logs is 32768, while the
+	default value for version 2 logs is MAX(32768, log_sunit).
 
   logdev=device and rtdev=device
 	Use an external log (metadata journal) and/or real-time device.
@@ -124,16 +157,11 @@ When mounting an XFS filesystem, the fol
 	optional, and the log section can be separate from the data
 	section or contained within it.
 
-  mtpt=mountpoint
-	Use with the "dmapi" option.  The value specified here will be
-	included in the DMAPI mount event, and should be the path of
-	the actual mountpoint that is used.
-
   noalign
-	Data allocations will not be aligned at stripe unit boundaries.
-
-  noatime
-	Access timestamps are not updated when a file is read.
+	Data allocations will not be aligned at stripe unit
+	boundaries. This is only relevant to filesystems created
+	with non-zero data alignment parameters (sunit, swidth) by
+	mkfs.
 
   norecovery
 	The filesystem will be mounted without running log recovery.
@@ -144,8 +172,14 @@ When mounting an XFS filesystem, the fol
 	the mount will fail.
 
   nouuid
-	Don't check for double mounted file systems using the file system uuid.
-	This is useful to mount LVM snapshot volumes.
+	Don't check for double mounted file systems using the file
+	system uuid.  This is useful to mount LVM snapshot volumes,
+	and often used in combination with "norecovery" for mounting
+	read-only snapshots.
+
+  noquota
+	Forcibly turns off all quota accounting and enforcement
+	within the filesystem.
 
   uquota/usrquota/uqnoenforce/quota
 	User disk quota accounting enabled, and limits (optionally)
@@ -160,24 +194,64 @@ When mounting an XFS filesystem, the fol
 	enforced.  Refer to xfs_quota(8) for further details.
 
   sunit=value and swidth=value
-	Used to specify the stripe unit and width for a RAID device or
-	a stripe volume.  "value" must be specified in 512-byte block
-	units.
-	If this option is not specified and the filesystem was made on
-	a stripe volume or the stripe width or unit were specified for
-	the RAID device at mkfs time, then the mount system call will
-	restore the value from the superblock.  For filesystems that
-	are made directly on RAID devices, these options can be used
-	to override the information in the superblock if the underlying
-	disk layout changes after the filesystem has been created.
-	The "swidth" option is required if the "sunit" option has been
-	specified, and must be a multiple of the "sunit" value.
+	Used to specify the stripe unit and width for a RAID device
+	or a stripe volume.  "value" must be specified in 512-byte
+	block units. These options are only relevant to filesystems
+	that were created with non-zero data alignment parameters.
+
+	The sunit and swidth parameters specified must be compatible
+	with the existing filesystem alignment characteristics.  In
+	general, that means the only valid changes to sunit are
+	increasing it by a power-of-2 multiple. Valid swidth values
+	are any integer multiple of a valid sunit value.
+
+	Typically the only time these mount options are necessary if
+	after an underlying RAID device has had it's geometry
+	modified, such as adding a new disk to a RAID5 lun and
+	reshaping it.
 
   swalloc
 	Data allocations will be rounded up to stripe width boundaries
 	when the current end of file is being extended and the file
 	size is larger than the stripe width size.
 
+  wsync
+	When specified, all filesystem namespace operations are
+	executed synchronously. This ensures that when the namespace
+	operation (create, unlink, etc) completes, the change to the
+	namespace is on stable storage. This is useful in HA setups
+	where failover must not result in clients seeing
+	inconsistent namespace presentation during or after a
+	failover event.
+
+
+Deprecated Mount Options
+========================
+
+  delaylog/nodelaylog
+	Delayed logging is the only logging method that XFS supports
+	now, so these mount options are now ignored.
+
+	Due for removal in 3.12.
+
+  ihashsize=value
+	In memory inode hashes have been removed, so this option has
+	no function as of August 2007. Option is deprecated.
+
+	Due for removal in 3.12.
+
+  irixsgid
+	This behaviour is now controlled by a sysctl, so the mount
+	option is ignored.
+
+	Due for removal in 3.12.
+
+  osyncisdsync
+  osyncisosync
+	O_SYNC and O_DSYNC are fully supported, so there is no need
+	for these options any more.
+
+	Due for removal in 3.12.
 
 sysctls
 =======
@@ -189,15 +263,20 @@ The following sysctls are available for
 	in /proc/fs/xfs/stat.  It then immediately resets to "0".
 
   fs.xfs.xfssyncd_centisecs	(Min: 100  Default: 3000  Max: 720000)
-  	The interval at which the xfssyncd thread flushes metadata
-  	out to disk.  This thread will flush log activity out, and
-  	do some processing on unlinked inodes.
+	The interval at which the filesystem flushes metadata
+	out to disk and runs internal cache cleanup routines.
 
-  fs.xfs.xfsbufd_centisecs	(Min: 50  Default: 100	Max: 3000)
-	The interval at which xfsbufd scans the dirty metadata buffers list.
+  fs.xfs.filestream_centisecs	(Min: 1  Default: 3000  Max: 360000)
+	The interval at which the filesystem ages filestreams cache
+	references and returns timed-out AGs back to the free stream
+	pool.
 
-  fs.xfs.age_buffer_centisecs	(Min: 100  Default: 1500  Max: 720000)
-	The age at which xfsbufd flushes dirty metadata buffers to disk.
+  fs.xfs.speculative_prealloc_lifetime
+		(Units: seconds   Min: 1  Default: 300  Max: 86400)
+	The interval at which the background scanning for inodes
+	with unused speculative preallocation runs. The scan
+	removes unused preallocation from clean inodes and releases
+	the unused space back to the free pool.
 
   fs.xfs.error_level		(Min: 0  Default: 3  Max: 11)
 	A volume knob for error reporting when internal errors occur.
@@ -254,9 +333,31 @@ The following sysctls are available for
 	by the xfs_io(8) chattr command on a directory to be
 	inherited by files in that directory.
 
+  fs.xfs.inherit_nodefrag	(Min: 0  Default: 1  Max: 1)
+	Setting this to "1" will cause the "nodefrag" flag set
+	by the xfs_io(8) chattr command on a directory to be
+	inherited by files in that directory.
+
   fs.xfs.rotorstep		(Min: 1  Default: 1  Max: 256)
 	In "inode32" allocation mode, this option determines how many
 	files the allocator attempts to allocate in the same allocation
 	group before moving to the next allocation group.  The intent
 	is to control the rate at which the allocator moves between
 	allocation groups when allocating extents for new files.
+
+Deprecated Sysctls
+==================
+
+  fs.xfs.xfsbufd_centisecs	(Min: 50  Default: 100	Max: 3000)
+	Dirty metadata is now tracked by the log subsystem and
+	flushing is driven by log space and idling demands. The
+	xfsbufd no longer exists, so this syctl does nothing.
+
+	Due for removal in 3.14.
+
+  fs.xfs.age_buffer_centisecs	(Min: 100  Default: 1500  Max: 720000)
+	Dirty metadata is now tracked by the log subsystem and
+	flushing is driven by log space and idling demands. The
+	xfsbufd no longer exists, so this syctl does nothing.
+
+	Due for removal in 3.14.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/00-INDEX linux-libre-3.11-rc7-gnu/Documentation/fmc/00-INDEX
--- linux-libre-3.10-gnu/Documentation/fmc/00-INDEX	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/00-INDEX	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,38 @@
+
+Documentation in this directory comes from sections of the manual we
+wrote for the externally-developed fmc-bus package. The complete
+manual as of today (2013-02) is available in PDF format at
+http://www.ohwr.org/projects/fmc-bus/files
+
+00-INDEX
+	- this file.
+
+FMC-and-SDB.txt
+	- What are FMC and SDB, basic concepts for this framework
+
+API.txt
+	- The functions that are exported by the bus driver
+
+parameters.txt
+	- The module parameters
+
+carrier.txt
+	- writing a carrier (a device)
+
+mezzanine.txt
+	- writing code for your mezzanine (a driver)
+
+identifiers.txt
+	- how identification and matching works
+
+fmc-fakedev.txt
+	- about drivers/fmc/fmc-fakedev.ko
+
+fmc-trivial.txt
+	- about drivers/fmc/fmc-trivial.ko
+
+fmc-write-eeprom.txt
+	- about drivers/fmc/fmc-write-eeprom.ko
+
+fmc-chardev.txt
+	- about drivers/fmc/fmc-chardev.ko
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/API.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/API.txt
--- linux-libre-3.10-gnu/Documentation/fmc/API.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/API.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,47 @@
+Functions Exported by fmc.ko
+****************************
+
+The FMC core exports the usual 4 functions that are needed for a bus to
+work, and a few more:
+
+        int fmc_driver_register(struct fmc_driver *drv);
+        void fmc_driver_unregister(struct fmc_driver *drv);
+        int fmc_device_register(struct fmc_device *fmc);
+        void fmc_device_unregister(struct fmc_device *fmc);
+
+        int fmc_device_register_n(struct fmc_device **fmc, int n);
+        void fmc_device_unregister_n(struct fmc_device **fmc, int n);
+
+        uint32_t fmc_readl(struct fmc_device *fmc, int offset);
+        void fmc_writel(struct fmc_device *fmc, uint32_t val, int off);
+        void *fmc_get_drvdata(struct fmc_device *fmc);
+        void fmc_set_drvdata(struct fmc_device *fmc, void *data);
+
+        int fmc_reprogram(struct fmc_device *f, struct fmc_driver *d, char *gw,
+                          int sdb_entry);
+
+The data structure that describe a device is detailed in *note FMC
+Device::, the one that describes a driver is detailed in *note FMC
+Driver::.  Please note that structures of type fmc_device must be
+allocated by the caller, but must not be released after unregistering.
+The fmc-bus itself takes care of releasing the structure when their use
+count reaches zero - actually, the device model does that in lieu of us.
+
+The functions to register and unregister n devices are meant to be used
+by carriers that host more than one mezzanine. The devices must all be
+registered at the same time because if the FPGA is reprogrammed, all
+devices in the array are affected. Usually, the driver matching the
+first device will reprogram the FPGA, so other devices must know they
+are already driven by a reprogrammed FPGA.
+
+If a carrier hosts slots that are driven by different FPGA devices, it
+should register as a group only mezzanines that are driven by the same
+FPGA, for the reason outlined above.
+
+Finally, the fmc_reprogram function calls the reprogram method (see
+*note The API Offered by Carriers:: and also scans the memory area for
+an SDB tree. You can pass -1 as sdb_entry to disable such scan.
+Otherwise, the function fails if no tree is found at the specified
+entry point.  The function is meant to factorize common code, and by
+the time you read this it is already used by the spec-sw and fine-delay
+modules.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/carrier.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/carrier.txt
--- linux-libre-3.10-gnu/Documentation/fmc/carrier.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/carrier.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,311 @@
+FMC Device
+**********
+
+Within the Linux bus framework, the FMC device is created and
+registered by the carrier driver. For example, the PCI driver for the
+SPEC card fills a data structure for each SPEC that it drives, and
+registers an associated FMC device for each card.  The SVEC driver can
+do exactly the same for the VME carrier (actually, it should do it
+twice, because the SVEC carries two FMC mezzanines).  Similarly, an
+Etherbone driver will be able to register its own FMC devices, offering
+communication primitives through frame exchange.
+
+The contents of the EEPROM within the FMC are used for identification
+purposes, i.e. for matching the device with its own driver. For this
+reason the device structure includes a complete copy of the EEPROM
+(actually, the carrier driver may choose whether or not to return it -
+for example we most likely won't have the whole EEPROM available for
+Etherbone devices.
+
+The following listing shows the current structure defining a device.
+Please note that all the machinery is in place but some details may
+still change in the future.  For this reason, there is a version field
+at the beginning of the structure.  As usual, the minor number will
+change for compatible changes (like a new flag) and the major number
+will increase when an incompatible change happens (for example, a
+change in layout of some fmc data structures).  Device writers should
+just set it to the value FMC_VERSION, and be ready to get back -EINVAL
+at registration time.
+
+     struct fmc_device {
+             unsigned long version;
+             unsigned long flags;
+             struct module *owner;           /* char device must pin it */
+             struct fmc_fru_id id;           /* for EEPROM-based match */
+             struct fmc_operations *op;      /* carrier-provided */
+             int irq;                        /* according to host bus. 0 == none */
+             int eeprom_len;                 /* Usually 8kB, may be less */
+             int eeprom_addr;                /* 0x50, 0x52 etc */
+             uint8_t *eeprom;                /* Full contents or leading part */
+             char *carrier_name;             /* "SPEC" or similar, for special use */
+             void *carrier_data;             /* "struct spec *" or equivalent */
+             __iomem void *fpga_base;        /* May be NULL (Etherbone) */
+             __iomem void *slot_base;        /* Set by the driver */
+             struct fmc_device **devarray;   /* Allocated by the bus */
+             int slot_id;                    /* Index in the slot array */
+             int nr_slots;                   /* Number of slots in this carrier */
+             unsigned long memlen;           /* Used for the char device */
+             struct device dev;              /* For Linux use */
+             struct device *hwdev;           /* The underlying hardware device */
+             unsigned long sdbfs_entry;
+             struct sdb_array *sdb;
+             uint32_t device_id;             /* Filled by the device */
+             char *mezzanine_name;           /* Defaults to ``fmc'' */
+             void *mezzanine_data;
+     };
+
+The meaning of most fields is summarized in the code comment above.
+
+The following fields must be filled by the carrier driver before
+registration:
+
+   * version: must be set to FMC_VERSION.
+
+   * owner: set to MODULE_OWNER.
+
+   * op: the operations to act on the device.
+
+   * irq: number for the mezzanine; may be zero.
+
+   * eeprom_len: length of the following array.
+
+   * eeprom_addr: 0x50 for first mezzanine and so on.
+
+   * eeprom: the full content of the I2C EEPROM.
+
+   * carrier_name.
+
+   * carrier_data: a unique pointer for the carrier.
+
+   * fpga_base: the I/O memory address (may be NULL).
+
+   * slot_id: the index of this slot (starting from zero).
+
+   * memlen: if fpga_base is valid, the length of I/O memory.
+
+   * hwdev: to be used in some dev_err() calls.
+
+   * device_id: a slot-specific unique integer number.
+
+
+Please note that the carrier should read its own EEPROM memory before
+registering the device, as well as fill all other fields listed above.
+
+The following fields should not be assigned, because they are filled
+later by either the bus or the device driver:
+
+   * flags.
+
+   * fru_id: filled by the bus, parsing the eeprom.
+
+   * slot_base: filled and used by the driver, if useful to it.
+
+   * devarray: an array og all mezzanines driven by a singe FPGA.
+
+   * nr_slots: set by the core at registration time.
+
+   * dev: used by Linux.
+
+   * sdb: FPGA contents, scanned according to driver's directions.
+
+   * sdbfs_entry: SDB entry point in EEPROM: autodetected.
+
+   * mezzanine_data: available for the driver.
+
+   * mezzanine_name: filled by fmc-bus during identification.
+
+
+Note: mezzanine_data may be redundant, because Linux offers the drvdata
+approach, so the field may be removed in later versions of this bus
+implementation.
+
+As I write this, she SPEC carrier is already completely functional in
+the fmc-bus environment, and is a good reference to look at.
+
+
+The API Offered by Carriers
+===========================
+
+The carrier provides a number of methods by means of the
+`fmc_operations' structure, which currently is defined like this
+(again, it is a moving target, please refer to the header rather than
+this document):
+
+     struct fmc_operations {
+             uint32_t (*readl)(struct fmc_device *fmc, int offset);
+             void (*writel)(struct fmc_device *fmc, uint32_t value, int offset);
+             int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw);
+             int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv);
+             int (*irq_request)(struct fmc_device *fmc, irq_handler_t h,
+                                char *name, int flags);
+             void (*irq_ack)(struct fmc_device *fmc);
+             int (*irq_free)(struct fmc_device *fmc);
+             int (*gpio_config)(struct fmc_device *fmc, struct fmc_gpio *gpio,
+                                int ngpio);
+             int (*read_ee)(struct fmc_device *fmc, int pos, void *d, int l);
+             int (*write_ee)(struct fmc_device *fmc, int pos, const void *d, int l);
+     };
+
+The individual methods perform the following tasks:
+
+`readl'
+`writel'
+     These functions access FPGA registers by whatever means the
+     carrier offers. They are not expected to fail, and most of the time
+     they will just make a memory access to the host bus. If the
+     carrier provides a fpga_base pointer, the driver may use direct
+     access through that pointer. For this reason the header offers the
+     inline functions fmc_readl and fmc_writel that access fpga_base if
+     the respective method is NULL. A driver that wants to be portable
+     and efficient should use fmc_readl and fmc_writel.  For Etherbone,
+     or other non-local carriers, error-management is still to be
+     defined.
+
+`validate'
+     Module parameters are used to manage different applications for
+     two or more boards of the same kind. Validation is based on the
+     busid module parameter, if provided, and returns the matching
+     index in the associated array. See *note Module Parameters:: in in
+     doubt. If no match is found, `-ENOENT' is returned; if the user
+     didn't pass `busid=', all devices will pass validation.  The value
+     returned by the validate method can be used as index into other
+     parameters (for example, some drivers use the `lm32=' parameter in
+     this way). Such "generic parameters" are documented in *note
+     Module Parameters::, below. The validate method is used by
+     `fmc-trivial.ko', described in *note fmc-trivial::.
+
+`reprogram'
+     The carrier enumerates FMC devices by loading a standard (or
+     golden) FPGA binary that allows EEPROM access. Each driver, then,
+     will need to reprogram the FPGA by calling this function.  If the
+     name argument is NULL, the carrier should reprogram the golden
+     binary. If the gateware name has been overridden through module
+     parameters (in a carrier-specific way) the file loaded will match
+     the parameters. Per-device gateware names can be specified using
+     the `gateware=' parameter, see *note Module Parameters::.  Note:
+     Clients should call rhe new helper, fmc_reprogram, which both
+     calls this method and parse the SDB tree of the FPGA.
+
+`irq_request'
+`irq_ack'
+`irq_free'
+     Interrupt management is carrier-specific, so it is abstracted as
+     operations. The interrupt number is listed in the device
+     structure, and for the mezzanine driver the number is only
+     informative.  The handler will receive the fmc pointer as dev_id;
+     the flags argument is passed to the Linux request_irq function,
+     but fmc-specific flags may be added in the future. You'll most
+     likely want to pass the `IRQF_SHARED' flag.
+
+`gpio_config'
+     The method allows to configure a GPIO pin in the carrier, and read
+     its current value if it is configured as input. See *note The GPIO
+     Abstraction:: for details.
+
+`read_ee'
+`write_ee'
+     Read or write the EEPROM. The functions are expected to be only
+     called before reprogramming and the carrier should refuse them
+     with `ENODEV' after reprogramming.  The offset is expected to be
+     within 8kB (the current size), but addresses up to 1MB are
+     reserved to fit bigger I2C devices in the future. Carriers may
+     offer access to other internal flash memories using these same
+     methods: for example the SPEC driver may define that its carrier
+     I2C memory is seen at offset 1M and the internal SPI flash is seen
+     at offset 16M.  This multiplexing of several flash memories in the
+     same address space is is carrier-specific and should only be used
+     by a driver that has verified the `carrier_name' field.
+
+
+
+The GPIO Abstraction
+====================
+
+Support for GPIO pins in the fmc-bus environment is not very
+straightforward and deserves special discussion.
+
+While the general idea of a carrier-independent driver seems to fly,
+configuration of specific signals within the carrier needs at least
+some knowledge of the carrier itself.  For this reason, the specific
+driver can request to configure carrier-specific GPIO pins, numbered
+from 0 to at most 4095.  Configuration is performed by passing a
+pointer to an array of struct fmc_gpio items, as well as the length of
+the array. This is the data structure:
+
+        struct fmc_gpio {
+                char *carrier_name;
+                int gpio;
+                int _gpio;      /* internal use by the carrier */
+                int mode;       /* GPIOF_DIR_OUT etc, from <linux/gpio.h> */
+                int irqmode;    /* IRQF_TRIGGER_LOW and so on */
+        };
+
+By specifying a carrier_name for each pin, the driver may access
+different pins in different carriers.  The gpio_config method is
+expected to return the number of pins successfully configured, ignoring
+requests for other carriers. However, if no pin is configured (because
+no structure at all refers to the current carrier_name), the operation
+returns an error so the caller will know that it is running under a
+yet-unsupported carrier.
+
+So, for example, a driver that has been developed and tested on both
+the SPEC and the SVEC may request configuration of two different GPIO
+pins, and expect one such configuration to succeed - if none succeeds
+it most likely means that the current carrier is a still-unknown one.
+
+If, however, your GPIO pin has a specific known role, you can pass a
+special number in the gpio field, using one of the following macros:
+
+        #define FMC_GPIO_RAW(x)         (x)             /* 4096 of them */
+        #define FMC_GPIO_IRQ(x)         ((x) + 0x1000)  /*  256 of them */
+        #define FMC_GPIO_LED(x)         ((x) + 0x1100)  /*  256 of them */
+        #define FMC_GPIO_KEY(x)         ((x) + 0x1200)  /*  256 of them */
+        #define FMC_GPIO_TP(x)          ((x) + 0x1300)  /*  256 of them */
+        #define FMC_GPIO_USER(x)        ((x) + 0x1400)  /*  256 of them */
+
+Use of virtual GPIO numbers (anything but FMC_GPIO_RAW) is allowed
+provided the carrier_name field in the data structure is left
+unspecified (NULL). Each carrier is responsible for providing a mapping
+between virtual and physical GPIO numbers. The carrier may then use the
+_gpio field to cache the result of this mapping.
+
+All carriers must map their I/O lines to the sets above starting from
+zero.  The SPEC, for example, maps interrupt pins 0 and 1, and test
+points 0 through 3 (even if the test points on the PCB are called
+5,6,7,8).
+
+If, for example, a driver requires a free LED and a test point (for a
+scope probe to be plugged at some point during development) it may ask
+for FMC_GPIO_LED(0) and FMC_GPIO_TP(0). Each carrier will provide
+suitable GPIO pins.  Clearly, the person running the drivers will know
+the order used by the specific carrier driver in assigning leds and
+testpoints, so to make a carrier-dependent use of the diagnostic tools.
+
+In theory, some form of autodetection should be possible: a driver like
+the wr-nic (which uses IRQ(1) on the SPEC card) should configure
+IRQ(0), make a test with software-generated interrupts and configure
+IRQ(1) if the test fails. This probing step should be used because even
+if the wr-nic gateware is known to use IRQ1 on the SPEC, the driver
+should be carrier-independent and thus use IRQ(0) as a first bet -
+actually, the knowledge that IRQ0 may fail is carrier-dependent
+information, but using it doesn't make the driver unsuitable for other
+carriers.
+
+The return value of gpio_config is defined as follows:
+
+   * If no pin in the array can be used by the carrier, `-ENODEV'.
+
+   * If at least one virtual GPIO number cannot be mapped, `-ENOENT'.
+
+   * On success, 0 or positive. The value returned is the number of
+     high input bits (if no input is configured, the value for success
+     is 0).
+
+While I admit the procedure is not completely straightforward, it
+allows configuration, input and output with a single carrier operation.
+Given the typical use case of FMC devices, GPIO operations are not
+expected to ever by in hot paths, and GPIO access so fare has only been
+used to configure the interrupt pin, mode and polarity. Especially
+reading inputs is not expected to be common. If your device has GPIO
+capabilities in the hot path, you should consider using the kernel's
+GPIO mechanisms.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/FMC-and-SDB.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/FMC-and-SDB.txt
--- linux-libre-3.10-gnu/Documentation/fmc/FMC-and-SDB.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/FMC-and-SDB.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,88 @@
+
+FMC (FPGA Mezzanine Card) is the standard we use for our I/O devices,
+in the context of White Rabbit and related hardware.
+
+In our I/O environments we need to write drivers for each mezzanine
+card, and such drivers must work regardless of the carrier being used.
+To achieve this, we abstract the FMC interface.
+
+We have a carrier for PCI-E called SPEC and one for VME called SVEC,
+but more are planned.  Also, we support stand-alone devices (usually
+plugged on a SPEC card), controlled through Etherbone, developed by GSI.
+
+Code and documentation for the FMC bus was born as part of the spec-sw
+project, but now it lives in its own project. Other projects, i.e.
+software support for the various carriers, should include this as a
+submodule.
+
+The most up to date version of code and documentation is always
+available from the repository you can clone from:
+
+        git://ohwr.org/fmc-projects/fmc-bus.git (read-only)
+        git@ohwr.org:fmc-projects/fmc-bus.git (read-write for developers)
+
+Selected versions of the documentation, as well as complete tar
+archives for selected revisions are placed to the Files section of the
+project: `http://www.ohwr.org/projects/fmc-bus/files'
+
+
+What is FMC
+***********
+
+FMC, as said, stands for "FPGA Mezzanine Card". It is a standard
+developed by the VME consortium called VITA (VMEbus International Trade
+Association and ratified by ANSI, the American National Standard
+Institute.  The official documentation is called "ANSI-VITA 57.1".
+
+The FMC card is an almost square PCB, around 70x75 millimeters, that is
+called mezzanine in this document.  It usually lives plugged into
+another PCB for power supply and control; such bigger circuit board is
+called carrier from now on, and a single carrier may host more than one
+mezzanine.
+
+In the typical application the mezzanine is mostly analog while the
+carrier is mostly digital, and hosts an FPGA that must be configured to
+match the specific mezzanine and the desired application. Thus, you may
+need to load different FPGA images to drive different instances of the
+same mezzanine.
+
+FMC, as such, is not a bus in the usual meaning of the term, because
+most carriers have only one connector, and carriers with several
+connectors have completely separate electrical connections to them.
+This package, however, implements a bus as a software abstraction.
+
+
+What is SDB
+***********
+
+SDB (Self Describing Bus) is a set of data structures that we use for
+enumerating the internal structure of an FPGA image. We also use it as
+a filesystem inside the FMC EEPROM.
+
+SDB is not mandatory for use of this FMC kernel bus, but if you have SDB
+this package can make good use of it.  SDB itself is developed in the
+fpga-config-space OHWR project. The link to the repository is
+`git://ohwr.org/hdl-core-lib/fpga-config-space.git' and what is used in
+this project lives in the sdbfs subdirectory in there.
+
+SDB support for FMC is described in *note FMC Identification:: and
+*note SDB Support::
+
+
+SDB Support
+***********
+
+The fmc.ko bus driver exports a few functions to help drivers taking
+advantage of the SDB information that may be present in your own FPGA
+memory image.
+
+The module exports the following functions, in the special header
+<linux/fmc-sdb.h>. The linux/ prefix in the name is there because we
+plan to submit it upstream in the future, and don't want to force
+changes on our drivers if that happens.
+
+         int fmc_scan_sdb_tree(struct fmc_device *fmc, unsigned long address);
+         void fmc_show_sdb_tree(struct fmc_device *fmc);
+         signed long fmc_find_sdb_device(struct sdb_array *tree, uint64_t vendor,
+                                         uint32_t device, unsigned long *sz);
+         int fmc_free_sdb_tree(struct fmc_device *fmc);
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/fmc-chardev.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/fmc-chardev.txt
--- linux-libre-3.10-gnu/Documentation/fmc/fmc-chardev.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/fmc-chardev.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,64 @@
+fmc-chardev
+===========
+
+This is a simple generic driver, that allows user access by means of a
+character device (actually, one for each mezzanine it takes hold of).
+
+The char device is created as a misc device. Its name in /dev (as
+created by udev) is the same name as the underlying FMC device. Thus,
+the name can be a silly fmc-0000 look-alike if the device has no
+identifiers nor bus_id, a more specific fmc-0400 if the device has a
+bus-specific address but no associated name, or something like
+fdelay-0400 if the FMC core can rely on both a mezzanine name and a bus
+address.
+
+Currently the driver only supports read and write: you can lseek to the
+desired address and read or write a register.
+
+The driver assumes all registers are 32-bit in size, and only accepts a
+single read or write per system call. However, as a result of Unix read
+and write semantics, users can simply fread or fwrite bigger areas in
+order to dump or store bigger memory areas.
+
+There is currently no support for mmap, user-space interrupt management
+and DMA buffers. They may be added in later versions, if the need
+arises.
+
+The example below shows raw access to a SPEC card programmed with its
+golden FPGA file, that features an SDB structure at offset 256 - i.e.
+64 words.  The mezzanine's EEPROM in this case is not programmed, so the
+default name is fmc-<bus><devfn>, and there are two cards in the system:
+
+  spusa.root# insmod fmc-chardev.ko
+  [ 1073.339332] spec 0000:02:00.0: Driver has no ID: matches all
+  [ 1073.345051] spec 0000:02:00.0: Created misc device "fmc-0200"
+  [ 1073.350821] spec 0000:04:00.0: Driver has no ID: matches all
+  [ 1073.356525] spec 0000:04:00.0: Created misc device "fmc-0400"
+  spusa.root# ls -l /dev/fmc*
+  crw------- 1 root root 10, 58 Nov 20 19:23 /dev/fmc-0200
+  crw------- 1 root root 10, 57 Nov 20 19:23 /dev/fmc-0400
+  spusa.root# dd bs=4 skip=64 count=1 if=/dev/fmc-0200 2> /dev/null | od -t x1z
+  0000000 2d 42 44 53                                      >-BDS<
+  0000004
+
+The simple program tools/fmc-mem in this package can access an FMC char
+device and read or write a word or a whole area.  Actually, the program
+is not specific to FMC at all, it just uses lseek, read and write.
+
+Its first argument is the device name, the second the offset, the third
+(if any) the value to write and the optional last argument that must
+begin with "+" is the number of bytes to read or write.  In case of
+repeated reading data is written to stdout; repeated writes read from
+stdin and the value argument is ignored.
+
+The following examples show reading the SDB magic number and the first
+SDB record from a SPEC device programmed with its golden image:
+
+     spusa.root# ./fmc-mem /dev/fmc-0200 100
+     5344422d
+     spusa.root# ./fmc-mem /dev/fmc-0200 100 +40 | od -Ax -t x1z
+     000000 2d 42 44 53 00 01 02 00 00 00 00 00 00 00 00 00  >-BDS............<
+     000010 00 00 00 00 ff 01 00 00 00 00 00 00 51 06 00 00  >............Q...<
+     000020 c9 42 a5 e6 02 00 00 00 11 05 12 20 2d 34 42 57  >.B......... -4BW<
+     000030 73 6f 72 43 72 61 62 73 49 53 47 2d 00 20 20 20  >sorCrabsISG-.   <
+     000040
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/fmc-fakedev.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/fmc-fakedev.txt
--- linux-libre-3.10-gnu/Documentation/fmc/fmc-fakedev.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/fmc-fakedev.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,36 @@
+fmc-fakedev
+===========
+
+This package includes a software-only device, called fmc-fakedev, which
+is able to register up to 4 mezzanines (by default it registers one).
+Unlike the SPEC driver, which creates an FMC device for each PCI cards
+it manages, this module creates a single instance of its set of
+mezzanines.
+
+It is meant as the simplest possible example of how a driver should be
+written, and it includes a fake EEPROM image (built using the tools
+described in *note FMC Identification::),, which by default is
+replicated for each fake mezzanine.
+
+You can also use this device to verify the match algorithms, by asking
+it to test your own EEPROM image. You can provide the image by means of
+the eeprom= module parameter: the new EEPROM image is loaded, as usual,
+by means of the firmware loader.  This example shows the defaults and a
+custom EEPROM image:
+
+     spusa.root# insmod fmc-fakedev.ko
+     [   99.971247]  fake-fmc-carrier: mezzanine 0
+     [   99.975393]       Manufacturer: fake-vendor
+     [   99.979624]       Product name: fake-design-for-testing
+     spusa.root# rmmod fmc-fakedev
+     spusa.root# insmod fmc-fakedev.ko eeprom=fdelay-eeprom.bin
+     [  121.447464]  fake-fmc-carrier: Mezzanine 0: eeprom "fdelay-eeprom.bin"
+     [  121.462725]  fake-fmc-carrier: mezzanine 0
+     [  121.466858]       Manufacturer: CERN
+     [  121.470477]       Product name: FmcDelay1ns4cha
+     spusa.root# rmmod fmc-fakedev
+
+After loading the device, you can use the write_ee method do modify its
+own internal fake EEPROM: whenever the image is overwritten starting at
+offset 0, the module will unregister and register again the FMC device.
+This is shown in fmc-write-eeprom.txt
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/fmc-trivial.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/fmc-trivial.txt
--- linux-libre-3.10-gnu/Documentation/fmc/fmc-trivial.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/fmc-trivial.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,17 @@
+fmc-trivial
+===========
+
+The simple module fmc-trivial is just a simple client that registers an
+interrupt handler. I used it to verify the basic mechanism of the FMC
+bus and how interrupts worked.
+
+The module implements the generic FMC parameters, so it can program a
+different gateware file in each card. The whole list of parameters it
+accepts are:
+
+`busid='
+`gateware='
+     Generic parameters. See mezzanine.txt
+
+
+This driver is worth reading, in my opinion.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/fmc-write-eeprom.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/fmc-write-eeprom.txt
--- linux-libre-3.10-gnu/Documentation/fmc/fmc-write-eeprom.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/fmc-write-eeprom.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,125 @@
+fmc-write-eeprom
+================
+
+This module is designed to load a binary file from /lib/firmware and to
+write it to the internal EEPROM of the mezzanine card. This driver uses
+the `busid' generic parameter.
+
+Overwriting the EEPROM is not something you should do daily, and it is
+expected to only happen during manufacturing. For this reason, the
+module makes it unlikely for the random user to change a working EEPROM.
+
+The module takes the following measures:
+
+   * It accepts a `file=' argument (within /lib/firmware) and if no
+     such argument is received, it doesn't write anything to EEPROM
+     (i.e. there is no default file name).
+
+   * If the file name ends with `.bin' it is written verbatim starting
+     at offset 0.
+
+   * If the file name ends with `.tlv' it is interpreted as
+     type-length-value (i.e., it allows writev(2)-like operation).
+
+   * If the file name doesn't match any of the patterns above, it is
+     ignored and no write is performed.
+
+   * Only cards listed with `busid=' are written to. If no busid is
+     specified, no programming is done (and the probe function of the
+     driver will fail).
+
+
+Each TLV tuple is formatted in this way: the header is 5 bytes,
+followed by data. The first byte is `w' for write, the next two bytes
+represent the address, in little-endian byte order, and the next two
+represent the data length, in little-endian order. The length does not
+include the header (it is the actual number of bytes to be written).
+
+This is a real example: that writes 5 bytes at position 0x110:
+
+        spusa.root# od -t x1 -Ax /lib/firmware/try.tlv
+        000000 77 10 01 05 00 30 31 32 33 34
+        00000a
+        spusa.root# insmod /tmp/fmc-write-eeprom.ko busid=0x0200 file=try.tlv
+        [19983.391498] spec 0000:03:00.0: write 5 bytes at 0x0110
+        [19983.414615] spec 0000:03:00.0: write_eeprom: success
+
+Please note that you'll most likely want to use SDBFS to build your
+EEPROM image, at least if your mezzanines are being used in the White
+Rabbit environment. For this reason the TLV format is not expected to
+be used much and is not expected to be developed further.
+
+If you want to try reflashing fake EEPROM devices, you can use the
+fmc-fakedev.ko module (see *note fmc-fakedev::).  Whenever you change
+the image starting at offset 0, it will deregister and register again
+after two seconds.  Please note, however, that if fmc-write-eeprom is
+still loaded, the system will associate it to the new device, which
+will be reprogrammed and thus will be unloaded after two seconds.  The
+following example removes the module after it reflashed fakedev the
+first time.
+
+     spusa.root# insmod fmc-fakedev.ko
+        [   72.984733]  fake-fmc: Manufacturer: fake-vendor
+        [   72.989434]  fake-fmc: Product name: fake-design-for-testing
+        spusa.root# insmod fmc-write-eeprom.ko busid=0 file=fdelay-eeprom.bin; \
+            rmmod fmc-write-eeprom
+        [  130.874098]  fake-fmc: Matching a generic driver (no ID)
+        [  130.887845]  fake-fmc: programming 6155 bytes
+        [  130.894567]  fake-fmc: write_eeprom: success
+        [  132.895794]  fake-fmc: Manufacturer: CERN
+        [  132.899872]  fake-fmc: Product name: FmcDelay1ns4cha
+
+
+Writing to the EEPROM
+=====================
+
+Once you have created a binary file for your EEPROM, you can write it
+to the storage medium using the fmc-write-eeprom (See *note
+fmc-write-eeprom::, while relying on a carrier driver.  The procedure
+here shown here uses the SPEC driver
+(`http://www.ohwr.org/projects/spec-sw').
+
+The example assumes no driver is already loaded (actually, I unloaded
+them by hand as everything loads automatically at boot time after you
+installed the modules), and shows kernel messages together with
+commands. Here the prompt is spusa.root# and two SPEC cards are plugged
+in the system.
+
+     spusa.root# insmod fmc.ko
+     spusa.root# insmod spec.ko
+     [13972.382818] spec 0000:02:00.0:  probe for device 0002:0000
+     [13972.392773] spec 0000:02:00.0: got file "fmc/spec-init.bin", 1484404 (0x16a674) bytes
+     [13972.591388] spec 0000:02:00.0: FPGA programming successful
+     [13972.883011] spec 0000:02:00.0: EEPROM has no FRU information
+     [13972.888719] spec 0000:02:00.0: No device_id filled, using index
+     [13972.894676] spec 0000:02:00.0: No mezzanine_name found
+     [13972.899863] /home/rubini/wip/spec-sw/kernel/spec-gpio.c - spec_gpio_init
+     [13972.906578] spec 0000:04:00.0:  probe for device 0004:0000
+     [13972.916509] spec 0000:04:00.0: got file "fmc/spec-init.bin", 1484404 (0x16a674) bytes
+     [13973.115096] spec 0000:04:00.0: FPGA programming successful
+     [13973.401798] spec 0000:04:00.0: EEPROM has no FRU information
+     [13973.407474] spec 0000:04:00.0: No device_id filled, using index
+     [13973.413417] spec 0000:04:00.0: No mezzanine_name found
+     [13973.418600] /home/rubini/wip/spec-sw/kernel/spec-gpio.c - spec_gpio_init
+     spusa.root# ls /sys/bus/fmc/devices
+     fmc-0000  fmc-0001
+     spusa.root# insmod fmc-write-eeprom.ko busid=0x0200 file=fdelay-eeprom.bin
+     [14103.966259] spec 0000:02:00.0: Matching an generic driver (no ID)
+     [14103.975519] spec 0000:02:00.0: programming 6155 bytes
+     [14126.373762] spec 0000:02:00.0: write_eeprom: success
+     [14126.378770] spec 0000:04:00.0: Matching an generic driver (no ID)
+     [14126.384903] spec 0000:04:00.0: fmc_write_eeprom: no filename given: not programming
+     [14126.392600] fmc_write_eeprom: probe of fmc-0001 failed with error -2
+
+Reading back the EEPROM
+=======================
+
+In order to read back the binary content of the EEPROM of your
+mezzanine device, the bus creates a read-only sysfs file called eeprom
+for each mezzanine it knows about:
+
+   spusa.root# cd /sys/bus/fmc/devices; ls -l */eeprom
+   -r--r--r-- 1 root root 8192 Apr  9 16:53 FmcDelay1ns4cha-f001/eeprom
+   -r--r--r-- 1 root root 8192 Apr  9 17:19 fake-design-for-testing-f002/eeprom
+   -r--r--r-- 1 root root 8192 Apr  9 17:19 fake-design-for-testing-f003/eeprom
+   -r--r--r-- 1 root root 8192 Apr  9 17:19 fmc-f004/eeprom
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/identifiers.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/identifiers.txt
--- linux-libre-3.10-gnu/Documentation/fmc/identifiers.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/identifiers.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,168 @@
+FMC Identification
+******************
+
+The FMC standard requires every compliant mezzanine to carry
+identification information in an I2C EEPROM.  The information must be
+laid out according to the "IPMI Platform Management FRU Information",
+where IPMI is a lie I'd better not expand, and FRU means "Field
+Replaceable Unit".
+
+The FRU information is an intricate unreadable binary blob that must
+live at offset 0 of the EEPROM, and typically extends for a few hundred
+bytes. The standard allows the application to use all the remaining
+storage area of the EEPROM as it wants.
+
+This chapter explains how to create your own EEPROM image and how to
+write it in your mezzanine, as well as how devices and drivers are
+paired at run time.  EEPROM programming uses tools that are part of this
+package and SDB (part of the fpga-config-space package).
+
+The first sections are only interesting for manufacturers who need to
+write the EEPROM. If you are just a software developer writing an FMC
+device or driver, you may jump straight to *note SDB Support::.
+
+
+Building the FRU Structure
+==========================
+
+If you want to know the internals of the FRU structure and despair, you
+can retrieve the document from
+`http://download.intel.com/design/servers/ipmi/FRU1011.pdf' .  The
+standard is awful and difficult without reason, so we only support the
+minimum mandatory subset - we create a simple structure and parse it
+back at run time, but we are not able to either generate or parse more
+arcane features like non-english languages and 6-bit text.  If you need
+more items of the FRU standard for your boards, please submit patches.
+
+This package includes the Python script that Matthieu Cattin wrote to
+generate the FRU binary blob, based on an helper libipmi by Manohar
+Vanga and Matthieu himself.  I changed the test script to receive
+parameters from the command line or from the environment (the command
+line takes precedence)
+
+To make a long story short, in order to build a standard-compliant
+binary file to be burned in your EEPROM, you need the following items:
+
+        Environment    Opt     Official Name          Default
+---------------------------------------------------------------------
+        FRU_VENDOR     -v      "Board Manufacturer"   fmc-example
+        FRU_NAME       -n      "Board Product Name"   mezzanine
+        FRU_SERIAL     -s      `Board Serial Number"  0001
+        FRU_PART       -p      "Board Part Number"    sample-part
+        FRU_OUTPUT     -o      not applicable         /dev/stdout
+
+The "Official Name" above is what you find in the FRU official
+documentation, chapter 11, page 7 ("Board Info Area Format").  The
+output option is used to save the generated binary to a specific file
+name instead of stdout.
+
+You can pass the items to the FRU generator either in the environment
+or on the command line.  This package has currently no support for
+specifying power consumption or such stuff, but I plan to add it as
+soon as I find some time for that.
+
+FIXME: consumption etc for FRU are here or in PTS?
+
+The following example creates a binary image for a specific board:
+
+        ./tools/fru-generator -v CERN -n FmcAdc100m14b4cha \
+               -s HCCFFIA___-CR000003 -p EDA-02063-V5-0 > eeprom.bin
+
+The following example shows a script that builds several binary EEPROM
+images for a series of boards, changing the serial number for each of
+them. The script uses a mix of environment variables and command line
+options, and uses the same string patterns shown above.
+
+        #!/bin/sh
+
+        export FRU_VENDOR="CERN"
+        export FRU_NAME="FmcAdc100m14b4cha"
+        export FRU_PART="EDA-02063-V5-0"
+
+        serial="HCCFFIA___-CR"
+
+        for number in $(seq 1 50); do
+           # build number-string "ns"
+           ns="$(printf %06d $number)"
+           ./fru-generator -s "${serial}${ns}" > eeprom-${ns}.bin
+        done
+
+
+Using SDB-FS in the EEPROM
+==========================
+
+If you want to use SDB as a filesystem in the EEPROM device within the
+mezzanine, you should create one such filesystem using gensdbfs, from
+the fpga-config-space package on OHWR.
+
+By using an SBD filesystem you can cluster several files in a single
+EEPROM, so both the host system and a soft-core running in the FPGA (if
+any) can access extra production-time information.
+
+We chose to use SDB as a storage filesystem because the format is very
+simple, and both the host system and the soft-core will likely already
+include support code for such format. The SDB library offered by the
+fpga-config-space is less than 1kB under LM32, so it proves quite up to
+the task.
+
+The SDB entry point (which acts as a directory listing) cannot live at
+offset zero in the flash device, because the FRU information must live
+there.  To avoid wasting precious storage space while still allowing
+for more-than-minimal FRU structures, the fmc.ko will look for the SDB
+record at address 256, 512 and 1024.
+
+In order to generate the complete EEPROM image you'll need a
+configuration file for gensdbfs: you tell the program where to place
+the sdb entry point, and you must force the FRU data file to be placed
+at the beginning of the storage device. If needed, you can also place
+other files at a special offset (we sometimes do it for backward
+compatibility with drivers we wrote before implementing SDB for flash
+memory).
+
+The directory tools/sdbfs of this package includes a well-commented
+example that you may want to use as a starting point (the comments are
+in the file called -SDB-CONFIG-).  Reading documentation for gensdbfs
+is a suggested first step anyways.
+
+This package (generic FMC bus support) only accesses two files in the
+EEPROM: the FRU information, at offset zero, with a suggested filename
+of IPMI-FRU and the short name for the mezzanine, in a file called
+name. The IPMI-FRU name is not mandatory, but a strongly suggested
+choice; the name filename is mandatory, because this is the preferred
+short name used by the FMC core.  For example, a name of "fdelay" may
+supplement a Product Name like "FmcDelay1ns4cha" - exactly as
+demonstrated in `tools/sdbfs'.
+
+Note: SDB access to flash memory is not yet supported, so the short
+name currently in use is just the "Product Name" FRU string.
+
+The example in tools/sdbfs includes an extra file, that is needed by
+the fine-delay driver, and must live at a known address of 0x1800.  By
+running gensdbfs on that directory you can output your binary EEPROM
+image (here below spusa$ is the shell prompt):
+
+        spusa$ ../fru-generator -v CERN -n FmcDelay1ns4cha -s proto-0 \
+                      -p EDA-02267-V3 > IPMI-FRU
+        spusa$ ls -l
+        total 16
+        -rw-rw-r-- 1 rubini staff 975 Nov 19 18:08 --SDB-CONFIG--
+        -rw-rw-r-- 1 rubini staff 216 Nov 19 18:13 IPMI-FRU
+        -rw-rw-r-- 1 rubini staff  11 Nov 19 18:04 fd-calib
+        -rw-rw-r-- 1 rubini staff   7 Nov 19 18:04 name
+        spusa$ sudo gensdbfs . /lib/firmware/fdelay-eeprom.bin
+        spusa$ sdb-read -l -e 0x100 /lib/firmware/fdelay-eeprom.bin
+        /home/rubini/wip/sdbfs/userspace/sdb-read: listing format is to be defined
+        46696c6544617461:2e202020  00000100-000018ff .
+        46696c6544617461:6e616d65  00000200-00000206 name
+        46696c6544617461:66642d63  00001800-000018ff fd-calib
+        46696c6544617461:49504d49  00000000-000000d7 IPMI-FRU
+        spusa$ ../fru-dump /lib/firmware/fdelay-eeprom.bin
+        /lib/firmware/fdelay-eeprom.bin: manufacturer: CERN
+        /lib/firmware/fdelay-eeprom.bin: product-name: FmcDelay1ns4cha
+        /lib/firmware/fdelay-eeprom.bin: serial-number: proto-0
+        /lib/firmware/fdelay-eeprom.bin: part-number: EDA-02267-V3
+
+As expected, the output file is both a proper sdbfs object and an IPMI
+FRU information blob. The fd-calib file lives at offset 0x1800 and is
+over-allocated to 256 bytes, according to the configuration file for
+gensdbfs.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/mezzanine.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/mezzanine.txt
--- linux-libre-3.10-gnu/Documentation/fmc/mezzanine.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/mezzanine.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,123 @@
+FMC Driver
+**********
+
+An FMC driver is concerned with the specific mezzanine and associated
+gateware. As such, it is expected to be independent of the carrier
+being used: it will perform I/O accesses only by means of
+carrier-provided functions.
+
+The matching between device and driver is based on the content of the
+EEPROM (as mandated by the FMC standard) or by the actual cores
+configured in the FPGA; the latter technique is used when the FPGA is
+already programmed when the device is registered to the bus core.
+
+In some special cases it is possible for a driver to directly access
+FPGA registers, by means of the `fpga_base' field of the device
+structure. This may be needed for high-bandwidth peripherals like fast
+ADC cards. If the device module registered a remote device (for example
+by means of Etherbone), the `fpga_base' pointer will be NULL.
+Therefore, drivers must be ready to deal with NULL base pointers, and
+fail gracefully.  Most driver, however, are not expected to access the
+pointer directly but run fmc_readl and fmc_writel instead, which will
+work in any case.
+
+In even more special cases, the driver may access carrier-specific
+functionality: the `carrier_name' string allows the driver to check
+which is the current carrier and make use of the `carrier_data'
+pointer.  We chose to use carrier names rather than numeric identifiers
+for greater flexibility, but also to avoid a central registry within
+the `fmc.h' file - we hope other users will exploit our framework with
+their own carriers.  An example use of carrier names is in GPIO setup
+(see *note The GPIO Abstraction::), although the name match is not
+expected to be performed by the driver.  If you depend on specific
+carriers, please check the carrier name and fail gracefully if your
+driver finds it is running in a yet-unknown-to-it environment.
+
+
+ID Table
+========
+
+Like most other Linux drivers, and FMC driver must list all the devices
+which it is able to drive.  This is usually done by means of a device
+table, but in FMC we can match hardware based either on the contents of
+their EEPROM or on the actual FPGA cores that can be enumerated.
+Therefore, we have two tables of identifiers.
+
+Matching of FRU information depends on two names, the manufacturer (or
+vendor) and the device (see *note FMC Identification::); for
+flexibility during production (i.e. before writing to the EEPROM) the
+bus supports a catch-all driver that specifies NULL strings. For this
+reason, the table is specified as pointer-and-length, not a a
+null-terminated array - the entry with NULL names can be a valid entry.
+
+Matching on FPGA cores depends on two numeric fields: the 64-bit vendor
+number and the 32-bit device number. Support for matching based on
+class is not yet implemented.  Each device is expected to be uniquely
+identified by an array of cores (it matches if all of the cores are
+instantiated), and for consistency the list is passed as
+pointer-and-length.  Several similar devices can be driven by the same
+driver, and thus the driver specifies and array of such arrays.
+
+The complete set of involved data structures is thus the following:
+
+        struct fmc_fru_id { char *manufacturer; char *product_name; };
+        struct fmc_sdb_one_id { uint64_t vendor; uint32_t device; };
+        struct fmc_sdb_id { struct fmc_sdb_one_id *cores; int cores_nr; };
+
+        struct fmc_device_id {
+                struct fmc_fru_id *fru_id; int fru_id_nr;
+                struct fmc_sdb_id *sdb_id; int sdb_id_nr;
+        };
+
+A better reference, with full explanation, is the <linux/fmc.h> header.
+
+
+Module Parameters
+=================
+
+Most of the FMC drivers need the same set of kernel parameters. This
+package includes support to implement common parameters by means of
+fields in the `fmc_driver' structure and simple macro definitions.
+
+The parameters are carrier-specific, in that they rely on the busid
+concept, that varies among carriers. For the SPEC, the identifier is a
+PCI bus and devfn number, 16 bits wide in total; drivers for other
+carriers will most likely offer something similar but not identical,
+and some code duplication is unavoidable.
+
+This is the list of parameters that are common to several modules to
+see how they are actually used, please look at spec-trivial.c.
+
+`busid='
+     This is an array of integers, listing carrier-specific
+     identification numbers. For PIC, for example, `0x0400' represents
+     bus 4, slot 0.  If any such ID is specified, the driver will only
+     accept to drive cards that appear in the list (even if the FMC ID
+     matches). This is accomplished by the validate carrier method.
+
+`gateware='
+     The argument is an array of strings. If no busid= is specified,
+     the first string of gateware= is used for all cards; otherwise the
+     identifiers and gateware names are paired one by one, in the order
+     specified.
+
+`show_sdb='
+     For modules supporting it, this parameter asks to show the SDB
+     internal structure by means of kernel messages. It is disabled by
+     default because those lines tend to hide more important messages,
+     if you look at the system console while loading the drivers.
+     Note: the parameter is being obsoleted, because fmc.ko itself now
+     supports dump_sdb= that applies to every client driver.
+
+
+For example, if you are using the trivial driver to load two different
+gateware files to two different cards, you can use the following
+parameters to load different binaries to the cards, after looking up
+the PCI identifiers. This has been tested with a SPEC carrier.
+
+        insmod fmc-trivial.ko \
+                              busid=0x0200,0x0400 \
+                              gateware=fmc/fine-delay.bin,fmc/simple-dio.bin
+
+Please note that not all sub-modules support all of those parameters.
+You can use modinfo to check what is supported by each module.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/fmc/parameters.txt linux-libre-3.11-rc7-gnu/Documentation/fmc/parameters.txt
--- linux-libre-3.10-gnu/Documentation/fmc/parameters.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/fmc/parameters.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,56 @@
+Module Parameters in fmc.ko
+***************************
+
+The core driver receives two module parameters, meant to help debugging
+client modules. Both parameters can be modified by writing to
+/sys/module/fmc/parameters/, because they are used when client drivers
+are devices are registered, not when fmc.ko is loaded.
+
+`dump_eeprom='
+     If not zero, the parameter asks the bus controller to dump the
+     EEPROM of any device that is registered, using printk.
+
+`dump_sdb='
+     If not zero, the parameter prints the SDB tree of every FPGA it is
+     loaded by fmc_reprogram(). If greater than one, it asks to dump
+     the binary content of SDB records.  This currently only dumps the
+     top-level SDB array, though.
+
+
+EEPROM dumping avoids repeating lines, since most of the contents is
+usually empty and all bits are one or zero. This is an example of the
+output:
+
+        [ 6625.850480] spec 0000:02:00.0: FPGA programming successful
+        [ 6626.139949] spec 0000:02:00.0: Manufacturer: CERN
+        [ 6626.144666] spec 0000:02:00.0: Product name: FmcDelay1ns4cha
+        [ 6626.150370] FMC: mezzanine 0: 0000:02:00.0 on SPEC
+        [ 6626.155179] FMC: dumping eeprom 0x2000 (8192) bytes
+        [ 6626.160087] 0000: 01 00 00 01  00 0b 00 f3  01 0a 00 a5  85 87 c4 43
+        [ 6626.167069] 0010: 45 52 4e cf  46 6d 63 44  65 6c 61 79  31 6e 73 34
+        [ 6626.174019] 0020: 63 68 61 c7  70 72 6f 74  6f 2d 30 cc  45 44 41 2d
+        [ 6626.180975] 0030: 30 32 32 36  37 2d 56 33  da 32 30 31  32 2d 31 31
+        [...]
+        [ 6626.371366] 0200: 66 64 65 6c  61 79 0a 00  00 00 00 00  00 00 00 00
+        [ 6626.378359] 0210: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
+        [ 6626.385361] [...]
+        [ 6626.387308] 1800: 70 6c 61 63  65 68 6f 6c  64 65 72 ff  ff ff ff ff
+        [ 6626.394259] 1810: ff ff ff ff  ff ff ff ff  ff ff ff ff  ff ff ff ff
+        [ 6626.401250] [...]
+
+The dump of SDB looks like the following; the example shows the simple
+golden gateware for the SPEC card, removing the leading timestamps to
+fit the page:
+
+        spec 0000:02:00.0: SDB: 00000651:e6a542c9 WB4-Crossbar-GSI
+        spec 0000:02:00.0: SDB: 0000ce42:ff07fc47 WR-Periph-Syscon (00000000-000000ff)
+        FMC: mezzanine 0: 0000:02:00.0 on SPEC
+        FMC: poor dump of sdb first level:
+        0000: 53 44 42 2d  00 02 01 00  00 00 00 00  00 00 00 00
+        0010: 00 00 00 00  00 00 01 ff  00 00 00 00  00 00 06 51
+        0020: e6 a5 42 c9  00 00 00 02  20 12 05 11  57 42 34 2d
+        0030: 43 72 6f 73  73 62 61 72  2d 47 53 49  20 20 20 00
+        0040: 00 00 01 01  00 00 00 07  00 00 00 00  00 00 00 00
+        0050: 00 00 00 00  00 00 00 ff  00 00 00 00  00 00 ce 42
+        0060: ff 07 fc 47  00 00 00 01  20 12 03 05  57 52 2d 50
+        0070: 65 72 69 70  68 2d 53 79  73 63 6f 6e  20 20 20 01
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/HOWTO linux-libre-3.11-rc7-gnu/Documentation/HOWTO
--- linux-libre-3.10-gnu/Documentation/HOWTO	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/HOWTO	2013-08-25 20:43:22.000000000 -0400
@@ -112,7 +112,7 @@ required reading:
 
     Other excellent descriptions of how to create patches properly are:
 	"The Perfect Patch"
-		http://userweb.kernel.org/~akpm/stuff/tpp.txt
+		http://kerneltrap.org/node/3737
 	"Linux kernel patch submission format"
 		http://linux.yyz.us/patch-format.html
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/hwmon/ds1621 linux-libre-3.11-rc7-gnu/Documentation/hwmon/ds1621
--- linux-libre-3.10-gnu/Documentation/hwmon/ds1621	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/hwmon/ds1621	2013-08-25 20:43:22.000000000 -0400
@@ -2,16 +2,30 @@ Kernel driver ds1621
 ====================
 
 Supported chips:
-  * Dallas Semiconductor DS1621
+  * Dallas Semiconductor / Maxim Integrated DS1621
     Prefix: 'ds1621'
-    Addresses scanned: I2C 0x48 - 0x4f
-    Datasheet: Publicly available at the Dallas Semiconductor website
-               http://www.dalsemi.com/
+    Addresses scanned: none
+    Datasheet: Publicly available from www.maximintegrated.com
+
   * Dallas Semiconductor DS1625
-    Prefix: 'ds1621'
-    Addresses scanned: I2C 0x48 - 0x4f
-    Datasheet: Publicly available at the Dallas Semiconductor website
-               http://www.dalsemi.com/
+    Prefix: 'ds1625'
+    Addresses scanned: none
+    Datasheet: Publicly available from www.datasheetarchive.com
+
+  * Maxim Integrated DS1631
+    Prefix: 'ds1631'
+    Addresses scanned: none
+    Datasheet: Publicly available from www.maximintegrated.com
+
+  * Maxim Integrated DS1721
+    Prefix: 'ds1721'
+    Addresses scanned: none
+    Datasheet: Publicly available from www.maximintegrated.com
+
+  * Maxim Integrated DS1731
+    Prefix: 'ds1731'
+    Addresses scanned: none
+    Datasheet: Publicly available from www.maximintegrated.com
 
 Authors:
         Christian W. Zuckschwerdt <zany@triq.net>
@@ -59,5 +73,115 @@ any of the limits have ever been met or
 reset. Be aware: When testing, it showed that the status of Tout can change
 with neither of the alarms set.
 
-Temperature conversion of the DS1621 takes up to 1000ms; internal access to
-non-volatile registers may last for 10ms or below.
+Since there is no version or vendor identification register, there is
+no unique identification for these devices. Therefore, explicit device
+instantiation is required for correct device identification and functionality
+(one device per address in this address range: 0x48..0x4f).
+
+The DS1625 is pin compatible and functionally equivalent with the DS1621,
+but the DS1621 is meant to replace it. The DS1631, DS1721, and DS1731 are
+also pin compatible with the DS1621 and provide multi-resolution support.
+
+Additionally, the DS1721 data sheet says the temperature flags (THF and TLF)
+are used internally, however, these flags do get set and cleared as the actual
+temperature crosses the min or max settings (which by default are set to 75
+and 80 degrees respectively).
+
+Temperature Conversion:
+-----------------------
+DS1621 - 750ms (older devices may take up to 1000ms)
+DS1625 - 500ms
+DS1631 - 93ms..750ms for 9..12 bits resolution, respectively.
+DS1721 - 93ms..750ms for 9..12 bits resolution, respectively.
+DS1731 - 93ms..750ms for 9..12 bits resolution, respectively.
+
+Note:
+On the DS1621, internal access to non-volatile registers may last for 10ms
+or less (unverified on the other devices).
+
+Temperature Accuracy:
+---------------------
+DS1621: +/- 0.5 degree Celsius (from 0 to +70 degrees)
+DS1625: +/- 0.5 degree Celsius (from 0 to +70 degrees)
+DS1631: +/- 0.5 degree Celsius (from 0 to +70 degrees)
+DS1721: +/- 1.0 degree Celsius (from -10 to +85 degrees)
+DS1731: +/- 1.0 degree Celsius (from -10 to +85 degrees)
+
+Note:
+Please refer to the device datasheets for accuracy at other temperatures.
+
+Temperature Resolution:
+-----------------------
+As mentioned above, the DS1631, DS1721, and DS1731 provide multi-resolution
+support, which is achieved via the R0 and R1 config register bits, where:
+
+R0..R1
+------
+ 0  0 => 9 bits, 0.5 degrees Celcius
+ 1  0 => 10 bits, 0.25 degrees Celcius
+ 0  1 => 11 bits, 0.125 degrees Celcius
+ 1  1 => 12 bits, 0.0625 degrees Celcius
+
+Note:
+At initial device power-on, the default resolution is set to 12-bits.
+
+The resolution mode for the DS1631, DS1721, or DS1731 can be changed from
+userspace, via the device 'update_interval' sysfs attribute. This attribute
+will normalize the range of input values to the device maximum resolution
+values defined in the datasheet as follows:
+
+Resolution    Conversion Time    Input Range
+ (C/LSB)       (msec)             (msec)
+------------------------------------------------
+0.5             93.75              0....94
+0.25            187.5              95...187
+0.125           375                188..375
+0.0625          750                376..infinity
+------------------------------------------------
+
+The following examples show how the 'update_interval' attribute can be
+used to change the conversion time:
+
+$ cat update_interval
+750
+$ cat temp1_input
+22062
+$
+$ echo 300 > update_interval
+$ cat update_interval
+375
+$ cat temp1_input
+22125
+$
+$ echo 150 > update_interval
+$ cat update_interval
+188
+$ cat temp1_input
+22250
+$
+$ echo 1 > update_interval
+$ cat update_interval
+94
+$ cat temp1_input
+22000
+$
+$ echo 1000 > update_interval
+$ cat update_interval
+750
+$ cat temp1_input
+22062
+$
+
+As shown, the ds1621 driver automatically adjusts the 'update_interval'
+user input, via a step function. Reading back the 'update_interval' value
+after a write operation provides the conversion time used by the device.
+
+Mathematically, the resolution can be derived from the conversion time
+via the following function:
+
+   g(x) = 0.5 * [minimum_conversion_time/x]
+
+where:
+ -> 'x' = the output from 'update_interval'
+ -> 'g(x)' = the resolution in degrees C per LSB.
+ -> 93.75ms = minimum conversion time
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/hwmon/g762 linux-libre-3.11-rc7-gnu/Documentation/hwmon/g762
--- linux-libre-3.10-gnu/Documentation/hwmon/g762	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/hwmon/g762	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,65 @@
+Kernel driver g762
+==================
+
+The GMT G762 Fan Speed PWM Controller is connected directly to a fan
+and performs closed-loop or open-loop control of the fan speed. Two
+modes - PWM or DC - are supported by the device.
+
+For additional information, a detailed datasheet is available at
+http://natisbad.org/NAS/ref/GMT_EDS-762_763-080710-0.2.pdf. sysfs
+bindings are described in Documentation/hwmon/sysfs-interface.
+
+The following entries are available to the user in a subdirectory of
+/sys/bus/i2c/drivers/g762/ to control the operation of the device.
+This can be done manually using the following entries but is usually
+done via a userland daemon like fancontrol.
+
+Note that those entries do not provide ways to setup the specific
+hardware characteristics of the system (reference clock, pulses per
+fan revolution, ...); Those can be modified via devicetree bindings
+documented in Documentation/devicetree/bindings/hwmon/g762.txt or
+using a specific platform_data structure in board initialization
+file (see include/linux/platform_data/g762.h).
+
+  fan1_target: set desired fan speed. This only makes sense in closed-loop
+            fan speed control (i.e. when pwm1_enable is set to 2).
+
+  fan1_input: provide current fan rotation value in RPM as reported by
+            the fan to the device.
+
+  fan1_div: fan clock divisor. Supported value are 1, 2, 4 and 8.
+
+  fan1_pulses: number of pulses per fan revolution. Supported values
+            are 2 and 4.
+
+  fan1_fault: reports fan failure, i.e. no transition on fan gear pin for
+            about 0.7s (if the fan is not voluntarily set off).
+
+  fan1_alarm: in closed-loop control mode, if fan RPM value is 25% out
+            of the programmed value for over 6 seconds 'fan1_alarm' is
+            set to 1.
+
+  pwm1_enable: set current fan speed control mode i.e. 1 for manual fan
+            speed control (open-loop) via pwm1 described below, 2 for
+            automatic fan speed control (closed-loop) via fan1_target
+            above.
+
+  pwm1_mode: set or get fan driving mode: 1 for PWM mode, 0 for DC mode.
+
+  pwm1: get or set PWM fan control value in open-loop mode. This is an
+            integer value between 0 and 255. 0 stops the fan, 255 makes
+            it run at full speed.
+
+Both in PWM mode ('pwm1_mode' set to 1) and DC mode ('pwm1_mode' set to 0),
+when current fan speed control mode is open-loop ('pwm1_enable' set to 1),
+the fan speed is programmed by setting a value between 0 and 255 via 'pwm1'
+entry (0 stops the fan, 255 makes it run at full speed). In closed-loop mode
+('pwm1_enable' set to 2), the expected rotation speed in RPM can be passed to
+the chip via 'fan1_target'. In closed-loop mode, the target speed is compared
+with current speed (available via 'fan1_input') by the device and a feedback
+is performed to match that target value. The fan speed value is computed
+based on the parameters associated with the physical characteristics of the
+system: a reference clock source frequency, a number of pulses per fan
+revolution, etc.
+
+Note that the driver will update its values at most once per second.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/hwmon/ina2xx linux-libre-3.11-rc7-gnu/Documentation/hwmon/ina2xx
--- linux-libre-3.10-gnu/Documentation/hwmon/ina2xx	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/hwmon/ina2xx	2013-08-25 20:43:22.000000000 -0400
@@ -44,4 +44,6 @@ The INA226 monitors both a shunt voltage
 The INA230 is a high or low side current shunt and power monitor with an I2C
 interface. The INA230 monitors both a shunt voltage drop and bus supply voltage.
 
-The shunt value in micro-ohms can be set via platform data.
+The shunt value in micro-ohms can be set via platform data or device tree.
+Please refer to the Documentation/devicetree/bindings/i2c/ina2xx.txt for bindings
+if the device tree is used.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/hwmon/submitting-patches linux-libre-3.11-rc7-gnu/Documentation/hwmon/submitting-patches
--- linux-libre-3.10-gnu/Documentation/hwmon/submitting-patches	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/hwmon/submitting-patches	2013-08-25 20:43:22.000000000 -0400
@@ -27,8 +27,7 @@ increase the chances of your change bein
   explicitly below the patch header.
 
 * If your patch (or the driver) is affected by configuration options such as
-  CONFIG_SMP or CONFIG_HOTPLUG, make sure it compiles for all configuration
-  variants.
+  CONFIG_SMP, make sure it compiles for all configuration variants.
 
 
 2. Adding functionality to existing drivers
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/i2c/busses/i2c-i801 linux-libre-3.11-rc7-gnu/Documentation/i2c/busses/i2c-i801
--- linux-libre-3.10-gnu/Documentation/i2c/busses/i2c-i801	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/i2c/busses/i2c-i801	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@ Supported adapters:
   * Intel Lynx Point-LP (PCH)
   * Intel Avoton (SOC)
   * Intel Wellsburg (PCH)
+  * Intel Coleto Creek (PCH)
    Datasheets: Publicly available at the Intel website
 
 On Intel Patsburg and later chipsets, both the normal host SMBus controller
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/i2c/busses/i2c-piix4 linux-libre-3.11-rc7-gnu/Documentation/i2c/busses/i2c-piix4
--- linux-libre-3.10-gnu/Documentation/i2c/busses/i2c-piix4	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/i2c/busses/i2c-piix4	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@ Supported adapters:
   * AMD SP5100 (SB700 derivative found on some server mainboards)
     Datasheet: Publicly available at the AMD website
     http://support.amd.com/us/Embedded_TechDocs/44413.pdf
-  * AMD Hudson-2
+  * AMD Hudson-2, CZ
     Datasheet: Not publicly available
   * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
     Datasheet: Publicly available at the SMSC website http://www.smsc.com
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/input/multi-touch-protocol.txt linux-libre-3.11-rc7-gnu/Documentation/input/multi-touch-protocol.txt
--- linux-libre-3.10-gnu/Documentation/input/multi-touch-protocol.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/input/multi-touch-protocol.txt	2013-08-25 20:43:22.000000000 -0400
@@ -80,6 +80,8 @@ Userspace can detect that a driver can r
 by noting that the largest supported BTN_TOOL_*TAP event is larger than the
 total number of type B slots reported in the absinfo for the ABS_MT_SLOT axis.
 
+The minimum value of the ABS_MT_SLOT axis must be 0.
+
 Protocol Example A
 ------------------
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ioctl/ioctl-number.txt linux-libre-3.11-rc7-gnu/Documentation/ioctl/ioctl-number.txt
--- linux-libre-3.10-gnu/Documentation/ioctl/ioctl-number.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ioctl/ioctl-number.txt	2013-08-25 20:43:22.000000000 -0400
@@ -72,6 +72,7 @@ Code  Seq#(hex)	Include File		Comments
 0x06	all	linux/lp.h
 0x09	all	linux/raid/md_u.h
 0x10	00-0F	drivers/char/s390/vmcp.h
+0x10	10-1F	arch/s390/include/uapi/sclp_ctl.h
 0x12	all	linux/fs.h
 		linux/blkpg.h
 0x1b	all	InfiniBand Subsystem	<http://infiniband.sourceforge.net/>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ja_JP/HOWTO linux-libre-3.11-rc7-gnu/Documentation/ja_JP/HOWTO
--- linux-libre-3.10-gnu/Documentation/ja_JP/HOWTO	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/ja_JP/HOWTO	2013-08-25 20:43:22.000000000 -0400
@@ -11,14 +11,14 @@ for non English (read: Japanese) speaker
 fork. So if you have any comments or updates for this file, please try
 to update the original English file first.
 
-Last Updated: 2011/03/31
+Last Updated: 2013/07/19
 ==================================
 これは、
-linux-2.6.38/Documentation/HOWTO
+linux-3.10/Documentation/HOWTO
 の和訳です。
 
-翻訳団体： JF プロジェクト < http://www.linux.or.jp/JF/ >
-翻訳日： 2011/3/28
+翻訳団体： JF プロジェクト < http://linuxjf.sourceforge.jp/ >
+翻訳日： 2013/7/19
 翻訳者： Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com>
 校正者： 松倉さん <nbh--mats at nifty dot com>
          小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp>
@@ -245,7 +245,7 @@ 特におすすめなのは、Linux ク�
 自己参照方式で、索引がついた web 形式で、ソースコードを参照することが
 できます。この最新の素晴しいカーネルコードのリポジトリは以下で見つかり
 ます-
-	http://sosdg.org/~qiyong/lxr/
+	http://lxr.linux.no/+trees
 
 開発プロセス
 -----------------------
@@ -253,24 +253,24 @@ 開発プロセス
 Linux カーネルの開発プロセスは現在幾つかの異なるメインカーネル「ブラン
 チ」と多数のサブシステム毎のカーネルブランチから構成されます。
 これらのブランチとは-
-  - メインの 2.6.x カーネルツリー
-  - 2.6.x.y -stable カーネルツリー
-  - 2.6.x -git カーネルパッチ
+  - メインの 3.x カーネルツリー
+  - 3.x.y -stable カーネルツリー
+  - 3.x -git カーネルパッチ
   - サブシステム毎のカーネルツリーとパッチ
-  - 統合テストのための 2.6.x -next カーネルツリー
+  - 統合テストのための 3.x -next カーネルツリー
 
-2.6.x カーネルツリー
+3.x カーネルツリー
 -----------------
 
-2.6.x カーネルは Linus Torvalds によってメンテナンスされ、kernel.org
-の pub/linux/kernel/v2.6/ ディレクトリに存在します。この開発プロセスは
+3.x カーネルは Linus Torvalds によってメンテナンスされ、kernel.org
+の pub/linux/kernel/v3.x/ ディレクトリに存在します。この開発プロセスは
 以下のとおり-
 
   - 新しいカーネルがリリースされた直後に、2週間の特別期間が設けられ、
     この期間中に、メンテナ達は Linus に大きな差分を送ることができます。
     このような差分は通常 -next カーネルに数週間含まれてきたパッチです。
     大きな変更は git(カーネルのソース管理ツール、詳細は
-    http://git-scm.com/  参照) を使って送るのが好ましいやり方ですが、パッ
+    http://git-scm.com/ 参照) を使って送るのが好ましいやり方ですが、パッ
     チファイルの形式のまま送るのでも十分です。
 
   - 2週間後、-rc1 カーネルがリリースされ、この後にはカーネル全体の安定
@@ -302,20 +302,20 @@ て書いたことをここで言って�
   実に認識されたバグの状況によりリリースされるのであり、前もって決めら
   れた計画によってリリースされるものではないからです。」
 
-2.6.x.y -stable カーネルツリー
+3.x.y -stable カーネルツリー
 ---------------------------
 
-バージョン番号が4つの数字に分かれているカーネルは -stable カーネルです。
-これには、2.6.x カーネルで見つかったセキュリティ問題や重大な後戻りに対
+バージョン番号が3つの数字に分かれているカーネルは -stable カーネルです。
+これには、3.x カーネルで見つかったセキュリティ問題や重大な後戻りに対
 する比較的小さい重要な修正が含まれます。
 
 これは、開発/実験的バージョンのテストに協力することに興味が無く、
 最新の安定したカーネルを使いたいユーザに推奨するブランチです。
 
-もし、2.6.x.y カーネルが存在しない場合には、番号が一番大きい 2.6.x が
+もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が
 最新の安定版カーネルです。
 
-2.6.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
+3.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
 要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
 た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
 の場合はこれに対してだいたいの場合、すぐにリリースがされます。
@@ -324,7 +324,7 @@ カーネルツリーに入っている�
 イルにはどのような種類の変更が -stable ツリーに受け入れ可能か、またリ
 リースプロセスがどう動くかが記述されています。
 
-2.6.x -git パッチ
+3.x -git パッチ
 ------------------
 
 git リポジトリで管理されているLinus のカーネルツリーの毎日のスナップ
@@ -358,14 +358,14 @@ メンテナはパッチに対して、�
 をつけることができます。大部分のこれらの patchwork のサイトは
 http://patchwork.kernel.org/ でリストされています。
 
-統合テストのための 2.6.x -next カーネルツリー
+統合テストのための 3.x -next カーネルツリー
 ---------------------------------------------
 
-サブシステムツリーの更新内容がメインラインの 2.6.x ツリーにマージされ
+サブシステムツリーの更新内容がメインラインの 3.x ツリーにマージされ
 る前に、それらは統合テストされる必要があります。この目的のため、実質的
 に全サブシステムツリーからほぼ毎日プルされてできる特別なテスト用のリ
 ポジトリが存在します-
-       http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git
+       http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
        http://linux.f-seidel.de/linux-next/pmwiki/
 
 このやり方によって、-next カーネルは次のマージ機会でどんなものがメイン
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/kbuild/kconfig.txt linux-libre-3.11-rc7-gnu/Documentation/kbuild/kconfig.txt
--- linux-libre-3.10-gnu/Documentation/kbuild/kconfig.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/kbuild/kconfig.txt	2013-08-25 20:43:22.000000000 -0400
@@ -165,7 +165,7 @@ Searching in menuconfig:
 	Example:
 		/hotplug
 		This lists all config symbols that contain "hotplug",
-		e.g., HOTPLUG, HOTPLUG_CPU, MEMORY_HOTPLUG.
+		e.g., HOTPLUG_CPU, MEMORY_HOTPLUG.
 
 	For search help, enter / followed TAB-TAB-TAB (to highlight
 	<Help>) and Enter.  This will tell you that you can also use
@@ -174,6 +174,19 @@ Searching in menuconfig:
 
 		/^hotplug
 
+	When searching, symbols are sorted thus:
+	  - exact match first: an exact match is when the search matches
+	    the complete symbol name;
+	  - alphabetical order: when two symbols do not match exactly,
+	    they are sorted in alphabetical order (in the user's current
+	    locale).
+	For example: ^ATH.K matches:
+	    ATH5K ATH9K ATH5K_AHB ATH5K_DEBUG [...] ATH6KL ATH6KL_DEBUG
+	    [...] ATH9K_AHB ATH9K_BTCOEX_SUPPORT ATH9K_COMMON [...]
+	of which only ATH5K and ATH9K match exactly and so are sorted
+	first (and in alphabetical order), then come all other symbols,
+	sorted in alphabetical order.
+
 ______________________________________________________________________
 User interface options for 'menuconfig'
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/kdump/kdump.txt linux-libre-3.11-rc7-gnu/Documentation/kdump/kdump.txt
--- linux-libre-3.10-gnu/Documentation/kdump/kdump.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/kdump/kdump.txt	2013-08-25 20:43:22.000000000 -0400
@@ -47,19 +47,12 @@ parameter. Optionally the size of the EL
 when using the elfcorehdr=[size[KMG]@]offset[KMG] syntax.
 
 
-With the dump-capture kernel, you can access the memory image, or "old
-memory," in two ways:
-
-- Through a /dev/oldmem device interface. A capture utility can read the
-  device file and write out the memory in raw format. This is a raw dump
-  of memory. Analysis and capture tools must be intelligent enough to
-  determine where to look for the right information.
-
-- Through /proc/vmcore. This exports the dump as an ELF-format file that
-  you can write out using file copy commands such as cp or scp. Further,
-  you can use analysis tools such as the GNU Debugger (GDB) and the Crash
-  tool to debug the dump file. This method ensures that the dump pages are
-  correctly ordered.
+With the dump-capture kernel, you can access the memory image through
+/proc/vmcore. This exports the dump as an ELF-format file that you can
+write out using file copy commands such as cp or scp. Further, you can
+use analysis tools such as the GNU Debugger (GDB) and the Crash tool to
+debug the dump file. This method ensures that the dump pages are correctly
+ordered.
 
 
 Setup and Installation
@@ -423,18 +416,6 @@ the following command:
 
    cp /proc/vmcore <dump-file>
 
-You can also access dumped memory as a /dev/oldmem device for a linear
-and raw view. To create the device, use the following command:
-
-    mknod /dev/oldmem c 1 12
-
-Use the dd command with suitable options for count, bs, and skip to
-access specific portions of the dump.
-
-To see the entire memory, use the following command:
-
-   dd if=/dev/oldmem of=oldmem.001
-
 
 Analysis
 ========
@@ -461,14 +442,6 @@ format. Crash is available on Dave Ander
    http://people.redhat.com/~anderson/
 
 
-To Do
-=====
-
-1) Provide relocatable kernels for all architectures to help in maintaining
-   multiple kernels for crash_dump, and the same kernel as the system kernel
-   can be used to capture the dump.
-
-
 Contact
 =======
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/kernel-doc-nano-HOWTO.txt linux-libre-3.11-rc7-gnu/Documentation/kernel-doc-nano-HOWTO.txt
--- linux-libre-3.10-gnu/Documentation/kernel-doc-nano-HOWTO.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/kernel-doc-nano-HOWTO.txt	2013-08-25 20:43:22.000000000 -0400
@@ -142,9 +142,10 @@ are:
 
 - Makefile
 
-  The targets 'sgmldocs', 'psdocs', 'pdfdocs', and 'htmldocs' are used
-  to build DocBook files, PostScript files, PDF files, and html files
-  in Documentation/DocBook.
+  The targets 'xmldocs', 'psdocs', 'pdfdocs', and 'htmldocs' are used
+  to build XML DocBook files, PostScript files, PDF files, and html files
+  in Documentation/DocBook. The older target 'sgmldocs' is equivalent
+  to 'xmldocs'.
 
 - Documentation/DocBook/Makefile
 
@@ -158,8 +159,8 @@ If you just want to read the ready-made
 subsystems (see Documentation/DocBook/*.tmpl), just type 'make
 psdocs', or 'make pdfdocs', or 'make htmldocs', depending on your
 preference.  If you would rather read a different format, you can type
-'make sgmldocs' and then use DocBook tools to convert
-Documentation/DocBook/*.sgml to a format of your choice (for example,
+'make xmldocs' and then use DocBook tools to convert
+Documentation/DocBook/*.xml to a format of your choice (for example,
 'db2html ...' if 'make htmldocs' was not defined).
 
 If you want to see man pages instead, you can do this:
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/kernel-parameters.txt linux-libre-3.11-rc7-gnu/Documentation/kernel-parameters.txt
--- linux-libre-3.10-gnu/Documentation/kernel-parameters.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/kernel-parameters.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1129,11 +1129,6 @@ bytes respectively. Such letter suffixes
 			The builtin appraise policy appraises all files
 			owned by uid=0.
 
-	ima_audit=	[IMA]
-			Format: { "0" | "1" }
-			0 -- integrity auditing messages. (Default)
-			1 -- enable informational integrity auditing messages.
-
 	ima_hash=	[IMA]
 			Format: { "sha1" | "md5" }
 			default: "sha1"
@@ -1158,6 +1153,13 @@ bytes respectively. Such letter suffixes
 	inport.irq=	[HW] Inport (ATI XL and Microsoft) busmouse driver
 			Format: <irq>
 
+	int_pln_enable  [x86] Enable power limit notification interrupt
+
+	integrity_audit=[IMA]
+			Format: { "0" | "1" }
+			0 -- basic integrity auditing messages. (Default)
+			1 -- additional integrity auditing messages.
+
 	intel_iommu=	[DMAR] Intel IOMMU driver (DMAR) option
 		on
 			Enable intel iommu driver.
@@ -1456,6 +1458,8 @@ bytes respectively. Such letter suffixes
 
 			* dump_id: dump IDENTIFY data.
 
+			* atapi_dmadir: Enable ATAPI DMADIR bridge support
+
 			If there are multiple matching configurations changing
 			the same attribute, the last one is used.
 
@@ -2677,9 +2681,17 @@ bytes respectively. Such letter suffixes
 			Run specified binary instead of /init from the ramdisk,
 			used for early userspace startup. See initrd.
 
-	reboot=		[BUGS=X86-32,BUGS=ARM,BUGS=IA-64] Rebooting mode
-			Format: <reboot_mode>[,<reboot_mode2>[,...]]
-			See arch/*/kernel/reboot.c or arch/*/kernel/process.c
+	reboot=		[KNL]
+			Format (x86 or x86_64):
+				[w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \
+				[[,]s[mp]#### \
+				[[,]b[ios] | a[cpi] | k[bd] | t[riple] | e[fi] | p[ci]] \
+				[[,]f[orce]
+			Where reboot_mode is one of warm (soft) or cold (hard) or gpio,
+			      reboot_type is one of bios, acpi, kbd, triple, efi, or pci,
+			      reboot_force is either force or not specified,
+			      reboot_cpu is s[mp]#### with #### being the processor
+					to be used for rebooting.
 
 	relax_domain_level=
 			[KNL, SMP] Set scheduler's default relax_domain_level.
@@ -2941,7 +2953,7 @@ bytes respectively. Such letter suffixes
 			improve throughput, but will also increase the
 			amount of memory reserved for use by the client.
 
-	swapaccount[=0|1]
+	swapaccount=[0|1]
 			[KNL] Enable accounting of swap in memory resource
 			controller if no parameter or 1 is given or disable
 			it if 0 is given (See Documentation/cgroups/memory.txt)
@@ -3069,6 +3081,19 @@ bytes respectively. Such letter suffixes
 			See also Documentation/trace/ftrace.txt "trace options"
 			section.
 
+	traceoff_on_warning
+			[FTRACE] enable this option to disable tracing when a
+			warning is hit. This turns off "tracing_on". Tracing can
+			be enabled again by echoing '1' into the "tracing_on"
+			file located in /sys/kernel/debug/tracing/
+
+			This option is useful, as it disables the trace before
+			the WARNING dump is called, which prevents the trace to
+			be filled with content caused by the warning output.
+
+			This option can also be set at run time via the sysctl
+			option:  kernel/traceoff_on_warning
+
 	transparent_hugepage=
 			[KNL]
 			Format: [always|madvise|never]
@@ -3229,6 +3254,15 @@ bytes respectively. Such letter suffixes
 	video=		[FB] Frame buffer configuration
 			See Documentation/fb/modedb.txt.
 
+	video.brightness_switch_enabled= [0,1]
+			If set to 1, on receiving an ACPI notify event
+			generated by hotkey, video driver will adjust brightness
+			level and then send out the event to user space through
+			the allocated input device; If set to 0, video driver
+			will only send out the event without touching backlight
+			brightness level.
+			default: 1
+
 	virtio_mmio.device=
 			[VMMIO] Memory mapped virtio (platform) device.
 
@@ -3341,6 +3375,21 @@ bytes respectively. Such letter suffixes
 			that this also can be controlled per-workqueue for
 			workqueues visible under /sys/bus/workqueue/.
 
+	workqueue.power_efficient
+			Per-cpu workqueues are generally preferred because
+			they show better performance thanks to cache
+			locality; unfortunately, per-cpu workqueues tend to
+			be more power hungry than unbound workqueues.
+
+			Enabling this makes the per-cpu workqueues which
+			were observed to contribute significantly to power
+			consumption unbound, leading to measurably lower
+			power usage at the cost of small performance
+			overhead.
+
+			The default value of this parameter is determined by
+			the config option CONFIG_WQ_POWER_EFFICIENT_DEFAULT.
+
 	x2apic_phys	[X86-64,APIC] Use x2apic physical mode instead of
 			default x2apic cluster mode on platforms
 			supporting x2apic.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/kernel-per-CPU-kthreads.txt linux-libre-3.11-rc7-gnu/Documentation/kernel-per-CPU-kthreads.txt
--- linux-libre-3.10-gnu/Documentation/kernel-per-CPU-kthreads.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/kernel-per-CPU-kthreads.txt	2013-08-25 20:43:22.000000000 -0400
@@ -157,6 +157,53 @@ RCU_SOFTIRQ:  Do at least one of the fol
 		calls and by forcing both kernel threads and interrupts
 		to execute elsewhere.
 
+Name: kworker/%u:%d%s (cpu, id, priority)
+Purpose: Execute workqueue requests
+To reduce its OS jitter, do any of the following:
+1.	Run your workload at a real-time priority, which will allow
+	preempting the kworker daemons.
+2.	Do any of the following needed to avoid jitter that your
+	application cannot tolerate:
+	a.	Build your kernel with CONFIG_SLUB=y rather than
+		CONFIG_SLAB=y, thus avoiding the slab allocator's periodic
+		use of each CPU's workqueues to run its cache_reap()
+		function.
+	b.	Avoid using oprofile, thus avoiding OS jitter from
+		wq_sync_buffer().
+	c.	Limit your CPU frequency so that a CPU-frequency
+		governor is not required, possibly enlisting the aid of
+		special heatsinks or other cooling technologies.  If done
+		correctly, and if you CPU architecture permits, you should
+		be able to build your kernel with CONFIG_CPU_FREQ=n to
+		avoid the CPU-frequency governor periodically running
+		on each CPU, including cs_dbs_timer() and od_dbs_timer().
+		WARNING:  Please check your CPU specifications to
+		make sure that this is safe on your particular system.
+	d.	It is not possible to entirely get rid of OS jitter
+		from vmstat_update() on CONFIG_SMP=y systems, but you
+		can decrease its frequency by writing a large value to
+		/proc/sys/vm/stat_interval.  The default value is HZ,
+		for an interval of one second.  Of course, larger values
+		will make your virtual-memory statistics update more
+		slowly.  Of course, you can also run your workload at
+		a real-time priority, thus preempting vmstat_update().
+	e.	If running on high-end powerpc servers, build with
+		CONFIG_PPC_RTAS_DAEMON=n.  This prevents the RTAS
+		daemon from running on each CPU every second or so.
+		(This will require editing Kconfig files and will defeat
+		this platform's RAS functionality.)  This avoids jitter
+		due to the rtas_event_scan() function.
+		WARNING:  Please check your CPU specifications to
+		make sure that this is safe on your particular system.
+	f.	If running on Cell Processor, build your kernel with
+		CBE_CPUFREQ_SPU_GOVERNOR=n to avoid OS jitter from
+		spu_gov_work().
+		WARNING:  Please check your CPU specifications to
+		make sure that this is safe on your particular system.
+	g.	If running on PowerMAC, build your kernel with
+		CONFIG_PMAC_RACKMETER=n to disable the CPU-meter,
+		avoiding OS jitter from rackmeter_do_timer().
+
 Name: rcuc/%u
 Purpose: Execute RCU callbacks in CONFIG_RCU_BOOST=y kernels.
 To reduce its OS jitter, do at least one of the following:
@@ -185,7 +232,7 @@ Purpose: Offload RCU callbacks from the
 To reduce its OS jitter, do at least one of the following:
 1.	Use affinity, cgroups, or other mechanism to force these kthreads
 	to execute on some other CPU.
-2.	Build with CONFIG_RCU_NOCB_CPUS=n, which will prevent these
+2.	Build with CONFIG_RCU_NOCB_CPU=n, which will prevent these
 	kthreads from being created in the first place.  However, please
 	note that this will not eliminate OS jitter, but will instead
 	shift it to RCU_SOFTIRQ.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/laptops/dslm.c linux-libre-3.11-rc7-gnu/Documentation/laptops/dslm.c
--- linux-libre-3.10-gnu/Documentation/laptops/dslm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/laptops/dslm.c	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,7 @@
  * dslm.c
  * Simple Disk Sleep Monitor
  *  by Bartek Kania
- * Licenced under the GPL
+ * Licensed under the GPL
  */
 #include <unistd.h>
 #include <stdlib.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/md.txt linux-libre-3.11-rc7-gnu/Documentation/md.txt
--- linux-libre-3.10-gnu/Documentation/md.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/md.txt	2013-08-25 20:43:22.000000000 -0400
@@ -566,13 +566,6 @@ also have
      when it reaches the current sync_max (below) and possibly at
      other times.
 
-   sync_max
-     This is a number of sectors at which point a resync/recovery
-     process will pause.  When a resync is active, the value can
-     only ever be increased, never decreased.  The value of 'max'
-     effectively disables the limit.
-
-
    sync_speed
      This shows the current actual speed, in K/sec, of the current
      sync_action.  It is averaged over the last 30 seconds.
@@ -593,6 +586,12 @@ also have
      that number to reach sync_max.  Then you can either increase
      "sync_max", or can write 'idle' to "sync_action".
 
+     The value of 'max' for "sync_max" effectively disables the limit.
+     When a resync is active, the value can only ever be increased,
+     never decreased.
+     The value of '0' is the minimum for "sync_min".
+
+
 
 Each active md device may also have attributes specific to the
 personality module that manages it.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/media-framework.txt linux-libre-3.11-rc7-gnu/Documentation/media-framework.txt
--- linux-libre-3.10-gnu/Documentation/media-framework.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/media-framework.txt	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,7 @@ Abstract media device model
 
 Discovering a device internal topology, and configuring it at runtime, is one
 of the goals of the media framework. To achieve this, hardware devices are
-modeled as an oriented graph of building blocks called entities connected
+modelled as an oriented graph of building blocks called entities connected
 through pads.
 
 An entity is a basic media hardware building block. It can correspond to
@@ -265,7 +265,7 @@ connected to another pad through an enab
 	media_entity_find_link(struct media_pad *source,
 			       struct media_pad *sink);
 
-	media_entity_remote_source(struct media_pad *pad);
+	media_entity_remote_pad(struct media_pad *pad);
 
 Refer to the kerneldoc documentation for more information.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/metag/kernel-ABI.txt linux-libre-3.11-rc7-gnu/Documentation/metag/kernel-ABI.txt
--- linux-libre-3.10-gnu/Documentation/metag/kernel-ABI.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/metag/kernel-ABI.txt	2013-08-25 20:43:22.000000000 -0400
@@ -189,7 +189,7 @@ call:
 
 64-bit arguments are placed in matching pairs of registers (i.e. the same
 register number in both D0 and D1 units), with the least significant half in D0
-and the most significant half in D1, leaving a gap where necessary. Futher
+and the most significant half in D1, leaving a gap where necessary. Further
 arguments are stored on the stack in reverse order (earlier arguments at higher
 addresses):
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/misc-devices/mei/mei.txt linux-libre-3.11-rc7-gnu/Documentation/misc-devices/mei/mei.txt
--- linux-libre-3.10-gnu/Documentation/misc-devices/mei/mei.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/misc-devices/mei/mei.txt	2013-08-25 20:43:22.000000000 -0400
@@ -120,7 +120,7 @@ The Intel MEI Driver supports the follow
 	Notes:
         max_msg_length (MTU) in client properties describes the maximum
         data that can be sent or received. (e.g. if MTU=2K, can send
-        requests up to bytes 2k and received responses upto 2k bytes).
+        requests up to bytes 2k and received responses up to 2k bytes).
 
 Intel ME Applications:
 ==============
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/00-INDEX linux-libre-3.11-rc7-gnu/Documentation/networking/00-INDEX
--- linux-libre-3.10-gnu/Documentation/networking/00-INDEX	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/00-INDEX	2013-08-25 20:43:22.000000000 -0400
@@ -88,8 +88,6 @@ gianfar.txt
 	- Gianfar Ethernet Driver.
 ieee802154.txt
 	- Linux IEEE 802.15.4 implementation, API and drivers
-ifenslave.c
-	- Configure network interfaces for parallel routing (bonding).
 igb.txt
 	- README for the Intel Gigabit Ethernet Driver (igb).
 igbvf.txt
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/arcnet.txt linux-libre-3.11-rc7-gnu/Documentation/networking/arcnet.txt
--- linux-libre-3.10-gnu/Documentation/networking/arcnet.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/arcnet.txt	2013-08-25 20:43:22.000000000 -0400
@@ -70,9 +70,10 @@ list, mail to linux-arcnet@tichy.ch.uj.e
 There are archives of the mailing list at:
 	http://epistolary.org/mailman/listinfo.cgi/arcnet
 
-The people on linux-net@vger.kernel.org have also been known to be very
-helpful, especially when we're talking about ALPHA Linux kernels that may or
-may not work right in the first place.
+The people on linux-net@vger.kernel.org (now defunct, replaced by
+netdev@vger.kernel.org) have also been known to be very helpful, especially
+when we're talking about ALPHA Linux kernels that may or may not work right
+in the first place.
 
 
 Other Drivers and Info
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/bonding.txt linux-libre-3.11-rc7-gnu/Documentation/networking/bonding.txt
--- linux-libre-3.10-gnu/Documentation/networking/bonding.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/bonding.txt	2013-08-25 20:43:22.000000000 -0400
@@ -104,8 +104,7 @@ Table of Contents
 ==============================
 
 	Most popular distro kernels ship with the bonding driver
-already available as a module and the ifenslave user level control
-program installed and ready for use. If your distro does not, or you
+already available as a module. If your distro does not, or you
 have need to compile bonding from source (e.g., configuring and
 installing a mainline kernel from kernel.org), you'll need to perform
 the following steps:
@@ -124,46 +123,13 @@ device support" section.  It is recommen
 driver as module since it is currently the only way to pass parameters
 to the driver or configure more than one bonding device.
 
-	Build and install the new kernel and modules, then continue
-below to install ifenslave.
+	Build and install the new kernel and modules.
 
-1.2 Install ifenslave Control Utility
+1.2 Bonding Control Utility
 -------------------------------------
 
-	The ifenslave user level control program is included in the
-kernel source tree, in the file Documentation/networking/ifenslave.c.
-It is generally recommended that you use the ifenslave that
-corresponds to the kernel that you are using (either from the same
-source tree or supplied with the distro), however, ifenslave
-executables from older kernels should function (but features newer
-than the ifenslave release are not supported).  Running an ifenslave
-that is newer than the kernel is not supported, and may or may not
-work.
-
-	To install ifenslave, do the following:
-
-# gcc -Wall -O -I/usr/src/linux/include ifenslave.c -o ifenslave
-# cp ifenslave /sbin/ifenslave
-
-	If your kernel source is not in "/usr/src/linux," then replace
-"/usr/src/linux/include" in the above with the location of your kernel
-source include directory.
-
-	You may wish to back up any existing /sbin/ifenslave, or, for
-testing or informal use, tag the ifenslave to the kernel version
-(e.g., name the ifenslave executable /sbin/ifenslave-2.6.10).
-
-IMPORTANT NOTE:
-
-	If you omit the "-I" or specify an incorrect directory, you
-may end up with an ifenslave that is incompatible with the kernel
-you're trying to build it for.  Some distros (e.g., Red Hat from 7.1
-onwards) do not have /usr/include/linux symbolically linked to the
-default kernel source include directory.
-
-SECOND IMPORTANT NOTE:
-	If you plan to configure bonding using sysfs or using the
-/etc/network/interfaces file, you do not need to use ifenslave.
+	 It is recommended to configure bonding via iproute2 (netlink)
+or sysfs, the old ifenslave control utility is obsolete.
 
 2. Bonding Driver Options
 =========================
@@ -337,6 +303,12 @@ arp_validate
 	such a situation, validation of backup slaves must be
 	disabled.
 
+	The validation of ARP requests on backup slaves is mainly
+	helping bonding to decide which slaves are more likely to
+	work in case of the active slave failure, it doesn't really
+	guarantee that the backup slave will work if it's selected
+	as the next active slave.
+
 	This option is useful in network configurations in which
 	multiple bonding hosts are concurrently issuing ARPs to one or
 	more targets beyond a common switch.  Should the link between
@@ -349,6 +321,25 @@ arp_validate
 
 	This option was added in bonding version 3.1.0.
 
+arp_all_targets
+
+	Specifies the quantity of arp_ip_targets that must be reachable
+	in order for the ARP monitor to consider a slave as being up.
+	This option affects only active-backup mode for slaves with
+	arp_validation enabled.
+
+	Possible values are:
+
+	any or 0
+
+		consider the slave up only when any of the arp_ip_targets
+		is reachable
+
+	all or 1
+
+		consider the slave up only when all of the arp_ip_targets
+		are reachable
+
 downdelay
 
 	Specifies the time, in milliseconds, to wait before disabling
@@ -851,7 +842,7 @@ resend_igmp
 ==============================
 
 	You can configure bonding using either your distro's network
-initialization scripts, or manually using either ifenslave or the
+initialization scripts, or manually using either iproute2 or the
 sysfs interface.  Distros generally use one of three packages for the
 network initialization scripts: initscripts, sysconfig or interfaces.
 Recent versions of these packages have support for bonding, while older
@@ -1160,7 +1151,7 @@ not support this method for specifying m
 those instances, see the "Configuring Multiple Bonds Manually" section,
 below.
 
-3.3 Configuring Bonding Manually with Ifenslave
+3.3 Configuring Bonding Manually with iproute2
 -----------------------------------------------
 
 	This section applies to distros whose network initialization
@@ -1171,7 +1162,7 @@ version 8.
 	The general method for these systems is to place the bonding
 module parameters into a config file in /etc/modprobe.d/ (as
 appropriate for the installed distro), then add modprobe and/or
-ifenslave commands to the system's global init script.  The name of
+`ip link` commands to the system's global init script.  The name of
 the global init script differs; for sysconfig, it is
 /etc/init.d/boot.local and for initscripts it is /etc/rc.d/rc.local.
 
@@ -1183,8 +1174,8 @@ reboots, edit the appropriate file (/etc
 modprobe bonding mode=balance-alb miimon=100
 modprobe e100
 ifconfig bond0 192.168.1.1 netmask 255.255.255.0 up
-ifenslave bond0 eth0
-ifenslave bond0 eth1
+ip link set eth0 master bond0
+ip link set eth1 master bond0
 
 	Replace the example bonding module parameters and bond0
 network configuration (IP address, netmask, etc) with the appropriate
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/.gitignore linux-libre-3.11-rc7-gnu/Documentation/networking/.gitignore
--- linux-libre-3.10-gnu/Documentation/networking/.gitignore	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/.gitignore	2013-08-25 20:43:22.000000000 -0400
@@ -1 +0,0 @@
-ifenslave
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/ieee802154.txt linux-libre-3.11-rc7-gnu/Documentation/networking/ieee802154.txt
--- linux-libre-3.10-gnu/Documentation/networking/ieee802154.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/ieee802154.txt	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,7 @@
 Introduction
 ============
 The IEEE 802.15.4 working group focuses on standartization of bottom
-two layers: Medium Accsess Control (MAC) and Physical (PHY). And there
+two layers: Medium Access Control (MAC) and Physical (PHY). And there
 are mainly two options available for upper layers:
  - ZigBee - proprietary protocol from ZigBee Alliance
  - 6LowPAN - IPv6 networking over low rate personal area networks
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/ifenslave.c linux-libre-3.11-rc7-gnu/Documentation/networking/ifenslave.c
--- linux-libre-3.10-gnu/Documentation/networking/ifenslave.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/ifenslave.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1105 +0,0 @@
-/* Mode: C;
- * ifenslave.c: Configure network interfaces for parallel routing.
- *
- *	This program controls the Linux implementation of running multiple
- *	network interfaces in parallel.
- *
- * Author:	Donald Becker <becker@cesdis.gsfc.nasa.gov>
- *		Copyright 1994-1996 Donald Becker
- *
- *		This program is free software; you can redistribute it
- *		and/or modify it under the terms of the GNU General Public
- *		License as published by the Free Software Foundation.
- *
- *	The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- *	Center of Excellence in Space Data and Information Sciences
- *	   Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
- *
- *  Changes :
- *    - 2000/10/02 Willy Tarreau <willy at meta-x.org> :
- *       - few fixes. Master's MAC address is now correctly taken from
- *         the first device when not previously set ;
- *       - detach support : call BOND_RELEASE to detach an enslaved interface.
- *       - give a mini-howto from command-line help : # ifenslave -h
- *
- *    - 2001/02/16 Chad N. Tindel <ctindel at ieee dot org> :
- *       - Master is now brought down before setting the MAC address.  In
- *         the 2.4 kernel you can't change the MAC address while the device is
- *         up because you get EBUSY.
- *
- *    - 2001/09/13 Takao Indoh <indou dot takao at jp dot fujitsu dot com>
- *       - Added the ability to change the active interface on a mode 1 bond
- *         at runtime.
- *
- *    - 2001/10/23 Chad N. Tindel <ctindel at ieee dot org> :
- *       - No longer set the MAC address of the master.  The bond device will
- *         take care of this itself
- *       - Try the SIOC*** versions of the bonding ioctls before using the
- *         old versions
- *    - 2002/02/18 Erik Habbinga <erik_habbinga @ hp dot com> :
- *       - ifr2.ifr_flags was not initialized in the hwaddr_notset case,
- *         SIOCGIFFLAGS now called before hwaddr_notset test
- *
- *    - 2002/10/31 Tony Cureington <tony.cureington * hp_com> :
- *       - If the master does not have a hardware address when the first slave
- *         is enslaved, the master is assigned the hardware address of that
- *         slave - there is a comment in bonding.c stating "ifenslave takes
- *         care of this now." This corrects the problem of slaves having
- *         different hardware addresses in active-backup mode when
- *         multiple interfaces are specified on a single ifenslave command
- *         (ifenslave bond0 eth0 eth1).
- *
- *    - 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *                   Shmulik Hen <shmulik.hen at intel dot com>
- *       - Moved setting the slave's mac address and openning it, from
- *         the application to the driver. This enables support of modes
- *         that need to use the unique mac address of each slave.
- *         The driver also takes care of closing the slave and restoring its
- *         original mac address upon release.
- *         In addition, block possibility of enslaving before the master is up.
- *         This prevents putting the system in an undefined state.
- *
- *    - 2003/05/01 - Amir Noam <amir.noam at intel dot com>
- *       - Added ABI version control to restore compatibility between
- *         new/old ifenslave and new/old bonding.
- *       - Prevent adding an adapter that is already a slave.
- *         Fixes the problem of stalling the transmission and leaving
- *         the slave in a down state.
- *
- *    - 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *       - Prevent enslaving if the bond device is down.
- *         Fixes the problem of leaving the system in unstable state and
- *         halting when trying to remove the module.
- *       - Close socket on all abnormal exists.
- *       - Add versioning scheme that follows that of the bonding driver.
- *         current version is 1.0.0 as a base line.
- *
- *    - 2003/05/22 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	 - ifenslave -c was broken; it's now fixed
- *	 - Fixed problem with routes vanishing from master during enslave
- *	   processing.
- *
- *    - 2003/05/27 - Amir Noam <amir.noam at intel dot com>
- *	 - Fix backward compatibility issues:
- *	   For drivers not using ABI versions, slave was set down while
- *	   it should be left up before enslaving.
- *	   Also, master was not set down and the default set_mac_address()
- *	   would fail and generate an error message in the system log.
- * 	 - For opt_c: slave should not be set to the master's setting
- *	   while it is running. It was already set during enslave. To
- *	   simplify things, it is now handled separately.
- *
- *    - 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	 - Code cleanup and style changes
- *	   set version to 1.1.0
- */
-
-#define APP_VERSION	"1.1.0"
-#define APP_RELDATE	"December 1, 2003"
-#define APP_NAME	"ifenslave"
-
-static char *version =
-APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ")\n"
-"o Donald Becker (becker@cesdis.gsfc.nasa.gov).\n"
-"o Detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n"
-"o 2.4 kernel support added on 2001/02/16 by Chad N. Tindel\n"
-"  (ctindel at ieee dot org).\n";
-
-static const char *usage_msg =
-"Usage: ifenslave [-f] <master-if> <slave-if> [<slave-if>...]\n"
-"       ifenslave -d   <master-if> <slave-if> [<slave-if>...]\n"
-"       ifenslave -c   <master-if> <slave-if>\n"
-"       ifenslave --help\n";
-
-static const char *help_msg =
-"\n"
-"       To create a bond device, simply follow these three steps :\n"
-"       - ensure that the required drivers are properly loaded :\n"
-"         # modprobe bonding ; modprobe <3c59x|eepro100|pcnet32|tulip|...>\n"
-"       - assign an IP address to the bond device :\n"
-"         # ifconfig bond0 <addr> netmask <mask> broadcast <bcast>\n"
-"       - attach all the interfaces you need to the bond device :\n"
-"         # ifenslave [{-f|--force}] bond0 eth0 [eth1 [eth2]...]\n"
-"         If bond0 didn't have a MAC address, it will take eth0's. Then, all\n"
-"         interfaces attached AFTER this assignment will get the same MAC addr.\n"
-"         (except for ALB/TLB modes)\n"
-"\n"
-"       To set the bond device down and automatically release all the slaves :\n"
-"         # ifconfig bond0 down\n"
-"\n"
-"       To detach a dead interface without setting the bond device down :\n"
-"         # ifenslave {-d|--detach} bond0 eth0 [eth1 [eth2]...]\n"
-"\n"
-"       To change active slave :\n"
-"         # ifenslave {-c|--change-active} bond0 eth0\n"
-"\n"
-"       To show master interface info\n"
-"         # ifenslave bond0\n"
-"\n"
-"       To show all interfaces info\n"
-"       # ifenslave {-a|--all-interfaces}\n"
-"\n"
-"       To be more verbose\n"
-"       # ifenslave {-v|--verbose} ...\n"
-"\n"
-"       # ifenslave {-u|--usage}   Show usage\n"
-"       # ifenslave {-V|--version} Show version\n"
-"       # ifenslave {-h|--help}    This message\n"
-"\n";
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <linux/if.h>
-#include <net/if_arp.h>
-#include <linux/if_ether.h>
-#include <linux/if_bonding.h>
-#include <linux/sockios.h>
-
-typedef unsigned long long u64;	/* hack, so we may include kernel's ethtool.h */
-typedef __uint32_t u32;		/* ditto */
-typedef __uint16_t u16;		/* ditto */
-typedef __uint8_t u8;		/* ditto */
-#include <linux/ethtool.h>
-
-struct option longopts[] = {
-	/* { name  has_arg  *flag  val } */
-	{"all-interfaces",	0, 0, 'a'},	/* Show all interfaces. */
-	{"change-active",	0, 0, 'c'},	/* Change the active slave.  */
-	{"detach",		0, 0, 'd'},	/* Detach a slave interface. */
-	{"force",		0, 0, 'f'},	/* Force the operation. */
-	{"help",		0, 0, 'h'},	/* Give help */
-	{"usage",		0, 0, 'u'},	/* Give usage */
-	{"verbose",		0, 0, 'v'},	/* Report each action taken. */
-	{"version",		0, 0, 'V'},	/* Emit version information. */
-	{ 0, 0, 0, 0}
-};
-
-/* Command-line flags. */
-unsigned int
-opt_a = 0,	/* Show-all-interfaces flag. */
-opt_c = 0,	/* Change-active-slave flag. */
-opt_d = 0,	/* Detach a slave interface. */
-opt_f = 0,	/* Force the operation. */
-opt_h = 0,	/* Help */
-opt_u = 0,	/* Usage */
-opt_v = 0,	/* Verbose flag. */
-opt_V = 0;	/* Version */
-
-int skfd = -1;		/* AF_INET socket for ioctl() calls.*/
-int abi_ver = 0;	/* userland - kernel ABI version */
-int hwaddr_set = 0;	/* Master's hwaddr is set */
-int saved_errno;
-
-struct ifreq master_mtu, master_flags, master_hwaddr;
-struct ifreq slave_mtu, slave_flags, slave_hwaddr;
-
-struct dev_ifr {
-	struct ifreq *req_ifr;
-	char *req_name;
-	int req_type;
-};
-
-struct dev_ifr master_ifra[] = {
-	{&master_mtu,     "SIOCGIFMTU",     SIOCGIFMTU},
-	{&master_flags,   "SIOCGIFFLAGS",   SIOCGIFFLAGS},
-	{&master_hwaddr,  "SIOCGIFHWADDR",  SIOCGIFHWADDR},
-	{NULL, "", 0}
-};
-
-struct dev_ifr slave_ifra[] = {
-	{&slave_mtu,     "SIOCGIFMTU",     SIOCGIFMTU},
-	{&slave_flags,   "SIOCGIFFLAGS",   SIOCGIFFLAGS},
-	{&slave_hwaddr,  "SIOCGIFHWADDR",  SIOCGIFHWADDR},
-	{NULL, "", 0}
-};
-
-static void if_print(char *ifname);
-static int get_drv_info(char *master_ifname);
-static int get_if_settings(char *ifname, struct dev_ifr ifra[]);
-static int get_slave_flags(char *slave_ifname);
-static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr);
-static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr);
-static int set_slave_mtu(char *slave_ifname, int mtu);
-static int set_if_flags(char *ifname, short flags);
-static int set_if_up(char *ifname, short flags);
-static int set_if_down(char *ifname, short flags);
-static int clear_if_addr(char *ifname);
-static int set_if_addr(char *master_ifname, char *slave_ifname);
-static int change_active(char *master_ifname, char *slave_ifname);
-static int enslave(char *master_ifname, char *slave_ifname);
-static int release(char *master_ifname, char *slave_ifname);
-#define v_print(fmt, args...)	\
-	if (opt_v)		\
-		fprintf(stderr, fmt, ## args )
-
-int main(int argc, char *argv[])
-{
-	char **spp, *master_ifname, *slave_ifname;
-	int c, i, rv;
-	int res = 0;
-	int exclusive = 0;
-
-	while ((c = getopt_long(argc, argv, "acdfhuvV", longopts, 0)) != EOF) {
-		switch (c) {
-		case 'a': opt_a++; exclusive++; break;
-		case 'c': opt_c++; exclusive++; break;
-		case 'd': opt_d++; exclusive++; break;
-		case 'f': opt_f++; exclusive++; break;
-		case 'h': opt_h++; exclusive++; break;
-		case 'u': opt_u++; exclusive++; break;
-		case 'v': opt_v++; break;
-		case 'V': opt_V++; exclusive++; break;
-
-		case '?':
-			fprintf(stderr, "%s", usage_msg);
-			res = 2;
-			goto out;
-		}
-	}
-
-	/* options check */
-	if (exclusive > 1) {
-		fprintf(stderr, "%s", usage_msg);
-		res = 2;
-		goto out;
-	}
-
-	if (opt_v || opt_V) {
-		printf("%s", version);
-		if (opt_V) {
-			res = 0;
-			goto out;
-		}
-	}
-
-	if (opt_u) {
-		printf("%s", usage_msg);
-		res = 0;
-		goto out;
-	}
-
-	if (opt_h) {
-		printf("%s", usage_msg);
-		printf("%s", help_msg);
-		res = 0;
-		goto out;
-	}
-
-	/* Open a basic socket */
-	if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-		perror("socket");
-		res = 1;
-		goto out;
-	}
-
-	if (opt_a) {
-		if (optind == argc) {
-			/* No remaining args */
-			/* show all interfaces */
-			if_print((char *)NULL);
-			goto out;
-		} else {
-			/* Just show usage */
-			fprintf(stderr, "%s", usage_msg);
-			res = 2;
-			goto out;
-		}
-	}
-
-	/* Copy the interface name */
-	spp = argv + optind;
-	master_ifname = *spp++;
-
-	if (master_ifname == NULL) {
-		fprintf(stderr, "%s", usage_msg);
-		res = 2;
-		goto out;
-	}
-
-	/* exchange abi version with bonding module */
-	res = get_drv_info(master_ifname);
-	if (res) {
-		fprintf(stderr,
-			"Master '%s': Error: handshake with driver failed. "
-			"Aborting\n",
-			master_ifname);
-		goto out;
-	}
-
-	slave_ifname = *spp++;
-
-	if (slave_ifname == NULL) {
-		if (opt_d || opt_c) {
-			fprintf(stderr, "%s", usage_msg);
-			res = 2;
-			goto out;
-		}
-
-		/* A single arg means show the
-		 * configuration for this interface
-		 */
-		if_print(master_ifname);
-		goto out;
-	}
-
-	res = get_if_settings(master_ifname, master_ifra);
-	if (res) {
-		/* Probably a good reason not to go on */
-		fprintf(stderr,
-			"Master '%s': Error: get settings failed: %s. "
-			"Aborting\n",
-			master_ifname, strerror(res));
-		goto out;
-	}
-
-	/* check if master is indeed a master;
-	 * if not then fail any operation
-	 */
-	if (!(master_flags.ifr_flags & IFF_MASTER)) {
-		fprintf(stderr,
-			"Illegal operation; the specified interface '%s' "
-			"is not a master. Aborting\n",
-			master_ifname);
-		res = 1;
-		goto out;
-	}
-
-	/* check if master is up; if not then fail any operation */
-	if (!(master_flags.ifr_flags & IFF_UP)) {
-		fprintf(stderr,
-			"Illegal operation; the specified master interface "
-			"'%s' is not up.\n",
-			master_ifname);
-		res = 1;
-		goto out;
-	}
-
-	/* Only for enslaving */
-	if (!opt_c && !opt_d) {
-		sa_family_t master_family = master_hwaddr.ifr_hwaddr.sa_family;
-		unsigned char *hwaddr =
-			(unsigned char *)master_hwaddr.ifr_hwaddr.sa_data;
-
-		/* The family '1' is ARPHRD_ETHER for ethernet. */
-		if (master_family != 1 && !opt_f) {
-			fprintf(stderr,
-				"Illegal operation: The specified master "
-				"interface '%s' is not ethernet-like.\n "
-				"This program is designed to work with "
-				"ethernet-like network interfaces.\n "
-				"Use the '-f' option to force the "
-				"operation.\n",
-				master_ifname);
-			res = 1;
-			goto out;
-		}
-
-		/* Check master's hw addr */
-		for (i = 0; i < 6; i++) {
-			if (hwaddr[i] != 0) {
-				hwaddr_set = 1;
-				break;
-			}
-		}
-
-		if (hwaddr_set) {
-			v_print("current hardware address of master '%s' "
-				"is %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
-				"type %d\n",
-				master_ifname,
-				hwaddr[0], hwaddr[1],
-				hwaddr[2], hwaddr[3],
-				hwaddr[4], hwaddr[5],
-				master_family);
-		}
-	}
-
-	/* Accepts only one slave */
-	if (opt_c) {
-		/* change active slave */
-		res = get_slave_flags(slave_ifname);
-		if (res) {
-			fprintf(stderr,
-				"Slave '%s': Error: get flags failed. "
-				"Aborting\n",
-				slave_ifname);
-			goto out;
-		}
-		res = change_active(master_ifname, slave_ifname);
-		if (res) {
-			fprintf(stderr,
-				"Master '%s', Slave '%s': Error: "
-				"Change active failed\n",
-				master_ifname, slave_ifname);
-		}
-	} else {
-		/* Accept multiple slaves */
-		do {
-			if (opt_d) {
-				/* detach a slave interface from the master */
-				rv = get_slave_flags(slave_ifname);
-				if (rv) {
-					/* Can't work with this slave. */
-					/* remember the error and skip it*/
-					fprintf(stderr,
-						"Slave '%s': Error: get flags "
-						"failed. Skipping\n",
-						slave_ifname);
-					res = rv;
-					continue;
-				}
-				rv = release(master_ifname, slave_ifname);
-				if (rv) {
-					fprintf(stderr,
-						"Master '%s', Slave '%s': Error: "
-						"Release failed\n",
-						master_ifname, slave_ifname);
-					res = rv;
-				}
-			} else {
-				/* attach a slave interface to the master */
-				rv = get_if_settings(slave_ifname, slave_ifra);
-				if (rv) {
-					/* Can't work with this slave. */
-					/* remember the error and skip it*/
-					fprintf(stderr,
-						"Slave '%s': Error: get "
-						"settings failed: %s. "
-						"Skipping\n",
-						slave_ifname, strerror(rv));
-					res = rv;
-					continue;
-				}
-				rv = enslave(master_ifname, slave_ifname);
-				if (rv) {
-					fprintf(stderr,
-						"Master '%s', Slave '%s': Error: "
-						"Enslave failed\n",
-						master_ifname, slave_ifname);
-					res = rv;
-				}
-			}
-		} while ((slave_ifname = *spp++) != NULL);
-	}
-
-out:
-	if (skfd >= 0) {
-		close(skfd);
-	}
-
-	return res;
-}
-
-static short mif_flags;
-
-/* Get the inteface configuration from the kernel. */
-static int if_getconfig(char *ifname)
-{
-	struct ifreq ifr;
-	int metric, mtu;	/* Parameters of the master interface. */
-	struct sockaddr dstaddr, broadaddr, netmask;
-	unsigned char *hwaddr;
-
-	strcpy(ifr.ifr_name, ifname);
-	if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
-		return -1;
-	mif_flags = ifr.ifr_flags;
-	printf("The result of SIOCGIFFLAGS on %s is %x.\n",
-	       ifname, ifr.ifr_flags);
-
-	strcpy(ifr.ifr_name, ifname);
-	if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0)
-		return -1;
-	printf("The result of SIOCGIFADDR is %2.2x.%2.2x.%2.2x.%2.2x.\n",
-	       ifr.ifr_addr.sa_data[0], ifr.ifr_addr.sa_data[1],
-	       ifr.ifr_addr.sa_data[2], ifr.ifr_addr.sa_data[3]);
-
-	strcpy(ifr.ifr_name, ifname);
-	if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
-		return -1;
-
-	/* Gotta convert from 'char' to unsigned for printf(). */
-	hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data;
-	printf("The result of SIOCGIFHWADDR is type %d  "
-	       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
-	       ifr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
-	       hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
-
-	strcpy(ifr.ifr_name, ifname);
-	if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) {
-		metric = 0;
-	} else
-		metric = ifr.ifr_metric;
-	printf("The result of SIOCGIFMETRIC is %d\n", metric);
-
-	strcpy(ifr.ifr_name, ifname);
-	if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0)
-		mtu = 0;
-	else
-		mtu = ifr.ifr_mtu;
-	printf("The result of SIOCGIFMTU is %d\n", mtu);
-
-	strcpy(ifr.ifr_name, ifname);
-	if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) < 0) {
-		memset(&dstaddr, 0, sizeof(struct sockaddr));
-	} else
-		dstaddr = ifr.ifr_dstaddr;
-
-	strcpy(ifr.ifr_name, ifname);
-	if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) < 0) {
-		memset(&broadaddr, 0, sizeof(struct sockaddr));
-	} else
-		broadaddr = ifr.ifr_broadaddr;
-
-	strcpy(ifr.ifr_name, ifname);
-	if (ioctl(skfd, SIOCGIFNETMASK, &ifr) < 0) {
-		memset(&netmask, 0, sizeof(struct sockaddr));
-	} else
-		netmask = ifr.ifr_netmask;
-
-	return 0;
-}
-
-static void if_print(char *ifname)
-{
-	char buff[1024];
-	struct ifconf ifc;
-	struct ifreq *ifr;
-	int i;
-
-	if (ifname == (char *)NULL) {
-		ifc.ifc_len = sizeof(buff);
-		ifc.ifc_buf = buff;
-		if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
-			perror("SIOCGIFCONF failed");
-			return;
-		}
-
-		ifr = ifc.ifc_req;
-		for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
-			if (if_getconfig(ifr->ifr_name) < 0) {
-				fprintf(stderr,
-					"%s: unknown interface.\n",
-					ifr->ifr_name);
-				continue;
-			}
-
-			if (((mif_flags & IFF_UP) == 0) && !opt_a) continue;
-			/*ife_print(&ife);*/
-		}
-	} else {
-		if (if_getconfig(ifname) < 0) {
-			fprintf(stderr,
-				"%s: unknown interface.\n", ifname);
-		}
-	}
-}
-
-static int get_drv_info(char *master_ifname)
-{
-	struct ifreq ifr;
-	struct ethtool_drvinfo info;
-	char *endptr;
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
-	ifr.ifr_data = (caddr_t)&info;
-
-	info.cmd = ETHTOOL_GDRVINFO;
-	strncpy(info.driver, "ifenslave", 32);
-	snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
-
-	if (ioctl(skfd, SIOCETHTOOL, &ifr) < 0) {
-		if (errno == EOPNOTSUPP) {
-			goto out;
-		}
-
-		saved_errno = errno;
-		v_print("Master '%s': Error: get bonding info failed %s\n",
-			master_ifname, strerror(saved_errno));
-		return 1;
-	}
-
-	abi_ver = strtoul(info.fw_version, &endptr, 0);
-	if (*endptr) {
-                v_print("Master '%s': Error: got invalid string as an ABI "
-			"version from the bonding module\n",
-			master_ifname);
-		return 1;
-	}
-
-out:
-	v_print("ABI ver is %d\n", abi_ver);
-
-	return 0;
-}
-
-static int change_active(char *master_ifname, char *slave_ifname)
-{
-	struct ifreq ifr;
-	int res = 0;
-
-	if (!(slave_flags.ifr_flags & IFF_SLAVE)) {
-		fprintf(stderr,
-			"Illegal operation: The specified slave interface "
-			"'%s' is not a slave\n",
-			slave_ifname);
-		return 1;
-	}
-
-	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
-	strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
-	if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &ifr) < 0) &&
-	    (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &ifr) < 0)) {
-		saved_errno = errno;
-		v_print("Master '%s': Error: SIOCBONDCHANGEACTIVE failed: "
-			"%s\n",
-			master_ifname, strerror(saved_errno));
-		res = 1;
-	}
-
-	return res;
-}
-
-static int enslave(char *master_ifname, char *slave_ifname)
-{
-	struct ifreq ifr;
-	int res = 0;
-
-	if (slave_flags.ifr_flags & IFF_SLAVE) {
-		fprintf(stderr,
-			"Illegal operation: The specified slave interface "
-			"'%s' is already a slave\n",
-			slave_ifname);
-		return 1;
-	}
-
-	res = set_if_down(slave_ifname, slave_flags.ifr_flags);
-	if (res) {
-		fprintf(stderr,
-			"Slave '%s': Error: bring interface down failed\n",
-			slave_ifname);
-		return res;
-	}
-
-	if (abi_ver < 2) {
-		/* Older bonding versions would panic if the slave has no IP
-		 * address, so get the IP setting from the master.
-		 */
-		set_if_addr(master_ifname, slave_ifname);
-	} else {
-		res = clear_if_addr(slave_ifname);
-		if (res) {
-			fprintf(stderr,
-				"Slave '%s': Error: clear address failed\n",
-				slave_ifname);
-			return res;
-		}
-	}
-
-	if (master_mtu.ifr_mtu != slave_mtu.ifr_mtu) {
-		res = set_slave_mtu(slave_ifname, master_mtu.ifr_mtu);
-		if (res) {
-			fprintf(stderr,
-				"Slave '%s': Error: set MTU failed\n",
-				slave_ifname);
-			return res;
-		}
-	}
-
-	if (hwaddr_set) {
-		/* Master already has an hwaddr
-		 * so set it's hwaddr to the slave
-		 */
-		if (abi_ver < 1) {
-			/* The driver is using an old ABI, so
-			 * the application sets the slave's
-			 * hwaddr
-			 */
-			res = set_slave_hwaddr(slave_ifname,
-					       &(master_hwaddr.ifr_hwaddr));
-			if (res) {
-				fprintf(stderr,
-					"Slave '%s': Error: set hw address "
-					"failed\n",
-					slave_ifname);
-				goto undo_mtu;
-			}
-
-			/* For old ABI the application needs to bring the
-			 * slave back up
-			 */
-			res = set_if_up(slave_ifname, slave_flags.ifr_flags);
-			if (res) {
-				fprintf(stderr,
-					"Slave '%s': Error: bring interface "
-					"down failed\n",
-					slave_ifname);
-				goto undo_slave_mac;
-			}
-		}
-		/* The driver is using a new ABI,
-		 * so the driver takes care of setting
-		 * the slave's hwaddr and bringing
-		 * it up again
-		 */
-	} else {
-		/* No hwaddr for master yet, so
-		 * set the slave's hwaddr to it
-		 */
-		if (abi_ver < 1) {
-			/* For old ABI, the master needs to be
-			 * down before setting its hwaddr
-			 */
-			res = set_if_down(master_ifname, master_flags.ifr_flags);
-			if (res) {
-				fprintf(stderr,
-					"Master '%s': Error: bring interface "
-					"down failed\n",
-					master_ifname);
-				goto undo_mtu;
-			}
-		}
-
-		res = set_master_hwaddr(master_ifname,
-					&(slave_hwaddr.ifr_hwaddr));
-		if (res) {
-			fprintf(stderr,
-				"Master '%s': Error: set hw address "
-				"failed\n",
-				master_ifname);
-			goto undo_mtu;
-		}
-
-		if (abi_ver < 1) {
-			/* For old ABI, bring the master
-			 * back up
-			 */
-			res = set_if_up(master_ifname, master_flags.ifr_flags);
-			if (res) {
-				fprintf(stderr,
-					"Master '%s': Error: bring interface "
-					"up failed\n",
-					master_ifname);
-				goto undo_master_mac;
-			}
-		}
-
-		hwaddr_set = 1;
-	}
-
-	/* Do the real thing */
-	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
-	strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
-	if ((ioctl(skfd, SIOCBONDENSLAVE, &ifr) < 0) &&
-	    (ioctl(skfd, BOND_ENSLAVE_OLD, &ifr) < 0)) {
-		saved_errno = errno;
-		v_print("Master '%s': Error: SIOCBONDENSLAVE failed: %s\n",
-			master_ifname, strerror(saved_errno));
-		res = 1;
-	}
-
-	if (res) {
-		goto undo_master_mac;
-	}
-
-	return 0;
-
-/* rollback (best effort) */
-undo_master_mac:
-	set_master_hwaddr(master_ifname, &(master_hwaddr.ifr_hwaddr));
-	hwaddr_set = 0;
-	goto undo_mtu;
-undo_slave_mac:
-	set_slave_hwaddr(slave_ifname, &(slave_hwaddr.ifr_hwaddr));
-undo_mtu:
-	set_slave_mtu(slave_ifname, slave_mtu.ifr_mtu);
-	return res;
-}
-
-static int release(char *master_ifname, char *slave_ifname)
-{
-	struct ifreq ifr;
-	int res = 0;
-
-	if (!(slave_flags.ifr_flags & IFF_SLAVE)) {
-		fprintf(stderr,
-			"Illegal operation: The specified slave interface "
-			"'%s' is not a slave\n",
-			slave_ifname);
-		return 1;
-	}
-
-	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
-	strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
-	if ((ioctl(skfd, SIOCBONDRELEASE, &ifr) < 0) &&
-	    (ioctl(skfd, BOND_RELEASE_OLD, &ifr) < 0)) {
-		saved_errno = errno;
-		v_print("Master '%s': Error: SIOCBONDRELEASE failed: %s\n",
-			master_ifname, strerror(saved_errno));
-		return 1;
-	} else if (abi_ver < 1) {
-		/* The driver is using an old ABI, so we'll set the interface
-		 * down to avoid any conflicts due to same MAC/IP
-		 */
-		res = set_if_down(slave_ifname, slave_flags.ifr_flags);
-		if (res) {
-			fprintf(stderr,
-				"Slave '%s': Error: bring interface "
-				"down failed\n",
-				slave_ifname);
-		}
-	}
-
-	/* set to default mtu */
-	set_slave_mtu(slave_ifname, 1500);
-
-	return res;
-}
-
-static int get_if_settings(char *ifname, struct dev_ifr ifra[])
-{
-	int i;
-	int res = 0;
-
-	for (i = 0; ifra[i].req_ifr; i++) {
-		strncpy(ifra[i].req_ifr->ifr_name, ifname, IFNAMSIZ);
-		res = ioctl(skfd, ifra[i].req_type, ifra[i].req_ifr);
-		if (res < 0) {
-			saved_errno = errno;
-			v_print("Interface '%s': Error: %s failed: %s\n",
-				ifname, ifra[i].req_name,
-				strerror(saved_errno));
-
-			return saved_errno;
-		}
-	}
-
-	return 0;
-}
-
-static int get_slave_flags(char *slave_ifname)
-{
-	int res = 0;
-
-	strncpy(slave_flags.ifr_name, slave_ifname, IFNAMSIZ);
-	res = ioctl(skfd, SIOCGIFFLAGS, &slave_flags);
-	if (res < 0) {
-		saved_errno = errno;
-		v_print("Slave '%s': Error: SIOCGIFFLAGS failed: %s\n",
-			slave_ifname, strerror(saved_errno));
-	} else {
-		v_print("Slave %s: flags %04X.\n",
-			slave_ifname, slave_flags.ifr_flags);
-	}
-
-	return res;
-}
-
-static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr)
-{
-	unsigned char *addr = (unsigned char *)hwaddr->sa_data;
-	struct ifreq ifr;
-	int res = 0;
-
-	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
-	memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));
-	res = ioctl(skfd, SIOCSIFHWADDR, &ifr);
-	if (res < 0) {
-		saved_errno = errno;
-		v_print("Master '%s': Error: SIOCSIFHWADDR failed: %s\n",
-			master_ifname, strerror(saved_errno));
-		return res;
-	} else {
-		v_print("Master '%s': hardware address set to "
-			"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
-			master_ifname, addr[0], addr[1], addr[2],
-			addr[3], addr[4], addr[5]);
-	}
-
-	return res;
-}
-
-static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr)
-{
-	unsigned char *addr = (unsigned char *)hwaddr->sa_data;
-	struct ifreq ifr;
-	int res = 0;
-
-	strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
-	memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));
-	res = ioctl(skfd, SIOCSIFHWADDR, &ifr);
-	if (res < 0) {
-		saved_errno = errno;
-
-		v_print("Slave '%s': Error: SIOCSIFHWADDR failed: %s\n",
-			slave_ifname, strerror(saved_errno));
-
-		if (saved_errno == EBUSY) {
-			v_print("  The device is busy: it must be idle "
-				"before running this command.\n");
-		} else if (saved_errno == EOPNOTSUPP) {
-			v_print("  The device does not support setting "
-				"the MAC address.\n"
-				"  Your kernel likely does not support slave "
-				"devices.\n");
-		} else if (saved_errno == EINVAL) {
-			v_print("  The device's address type does not match "
-				"the master's address type.\n");
-		}
-		return res;
-	} else {
-		v_print("Slave '%s': hardware address set to "
-			"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
-			slave_ifname, addr[0], addr[1], addr[2],
-			addr[3], addr[4], addr[5]);
-	}
-
-	return res;
-}
-
-static int set_slave_mtu(char *slave_ifname, int mtu)
-{
-	struct ifreq ifr;
-	int res = 0;
-
-	ifr.ifr_mtu = mtu;
-	strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
-
-	res = ioctl(skfd, SIOCSIFMTU, &ifr);
-	if (res < 0) {
-		saved_errno = errno;
-		v_print("Slave '%s': Error: SIOCSIFMTU failed: %s\n",
-			slave_ifname, strerror(saved_errno));
-	} else {
-		v_print("Slave '%s': MTU set to %d.\n", slave_ifname, mtu);
-	}
-
-	return res;
-}
-
-static int set_if_flags(char *ifname, short flags)
-{
-	struct ifreq ifr;
-	int res = 0;
-
-	ifr.ifr_flags = flags;
-	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-
-	res = ioctl(skfd, SIOCSIFFLAGS, &ifr);
-	if (res < 0) {
-		saved_errno = errno;
-		v_print("Interface '%s': Error: SIOCSIFFLAGS failed: %s\n",
-			ifname, strerror(saved_errno));
-	} else {
-		v_print("Interface '%s': flags set to %04X.\n", ifname, flags);
-	}
-
-	return res;
-}
-
-static int set_if_up(char *ifname, short flags)
-{
-	return set_if_flags(ifname, flags | IFF_UP);
-}
-
-static int set_if_down(char *ifname, short flags)
-{
-	return set_if_flags(ifname, flags & ~IFF_UP);
-}
-
-static int clear_if_addr(char *ifname)
-{
-	struct ifreq ifr;
-	int res = 0;
-
-	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-	ifr.ifr_addr.sa_family = AF_INET;
-	memset(ifr.ifr_addr.sa_data, 0, sizeof(ifr.ifr_addr.sa_data));
-
-	res = ioctl(skfd, SIOCSIFADDR, &ifr);
-	if (res < 0) {
-		saved_errno = errno;
-		v_print("Interface '%s': Error: SIOCSIFADDR failed: %s\n",
-			ifname, strerror(saved_errno));
-	} else {
-		v_print("Interface '%s': address cleared\n", ifname);
-	}
-
-	return res;
-}
-
-static int set_if_addr(char *master_ifname, char *slave_ifname)
-{
-	struct ifreq ifr;
-	int res;
-	unsigned char *ipaddr;
-	int i;
-	struct {
-		char *req_name;
-		char *desc;
-		int g_ioctl;
-		int s_ioctl;
-	} ifra[] = {
-		{"IFADDR", "addr", SIOCGIFADDR, SIOCSIFADDR},
-		{"DSTADDR", "destination addr", SIOCGIFDSTADDR, SIOCSIFDSTADDR},
-		{"BRDADDR", "broadcast addr", SIOCGIFBRDADDR, SIOCSIFBRDADDR},
-		{"NETMASK", "netmask", SIOCGIFNETMASK, SIOCSIFNETMASK},
-		{NULL, NULL, 0, 0},
-	};
-
-	for (i = 0; ifra[i].req_name; i++) {
-		strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
-		res = ioctl(skfd, ifra[i].g_ioctl, &ifr);
-		if (res < 0) {
-			int saved_errno = errno;
-
-			v_print("Interface '%s': Error: SIOCG%s failed: %s\n",
-				master_ifname, ifra[i].req_name,
-				strerror(saved_errno));
-
-			ifr.ifr_addr.sa_family = AF_INET;
-			memset(ifr.ifr_addr.sa_data, 0,
-			       sizeof(ifr.ifr_addr.sa_data));
-		}
-
-		strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
-		res = ioctl(skfd, ifra[i].s_ioctl, &ifr);
-		if (res < 0) {
-			int saved_errno = errno;
-
-			v_print("Interface '%s': Error: SIOCS%s failed: %s\n",
-				slave_ifname, ifra[i].req_name,
-				strerror(saved_errno));
-
-		}
-
-		ipaddr = (unsigned char *)ifr.ifr_addr.sa_data;
-		v_print("Interface '%s': set IP %s to %d.%d.%d.%d\n",
-			slave_ifname, ifra[i].desc,
-			ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
-	}
-
-	return 0;
-}
-
-/*
- * Local variables:
- *  version-control: t
- *  kept-new-versions: 5
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 4
- *  compile-command: "gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave"
- * End:
- */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/ip-sysctl.txt linux-libre-3.11-rc7-gnu/Documentation/networking/ip-sysctl.txt
--- linux-libre-3.10-gnu/Documentation/networking/ip-sysctl.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/ip-sysctl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -183,7 +183,7 @@ tcp_early_retrans - INTEGER
 	for triggering fast retransmit when the amount of outstanding data is
 	small and when no previously unsent data can be transmitted (such
 	that limited transmit could be used). Also controls the use of
-	Tail loss probe (TLP) that converts RTOs occuring due to tail
+	Tail loss probe (TLP) that converts RTOs occurring due to tail
 	losses into fast recovery (draft-dukkipati-tcpm-tcp-loss-probe-01).
 	Possible values:
 		0 disables ER
@@ -685,6 +685,15 @@ ip_dynaddr - BOOLEAN
 	occurs.
 	Default: 0
 
+ip_early_demux - BOOLEAN
+	Optimize input packet processing down to one demux for
+	certain kinds of local sockets.  Currently we only do this
+	for established TCP sockets.
+
+	It may add an additional cost for pure routing workloads that
+	reduces overall throughput, in such case you should disable it.
+	Default: 1
+
 icmp_echo_ignore_all - BOOLEAN
 	If set non-zero, then the kernel will ignore all ICMP ECHO
 	requests sent to it.
@@ -729,7 +738,7 @@ icmp_ignore_bogus_error_responses - BOOL
 	frames.  Such violations are normally logged via a kernel warning.
 	If this is set to TRUE, the kernel will not give such warnings, which
 	will avoid log file clutter.
-	Default: FALSE
+	Default: 1
 
 icmp_errors_use_inbound_ifaddr - BOOLEAN
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/ipvs-sysctl.txt linux-libre-3.11-rc7-gnu/Documentation/networking/ipvs-sysctl.txt
--- linux-libre-3.10-gnu/Documentation/networking/ipvs-sysctl.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/ipvs-sysctl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -181,6 +181,19 @@ snat_reroute - BOOLEAN
 	always be the same as the original route so it is an optimisation
 	to disable snat_reroute and avoid the recalculation.
 
+sync_persist_mode - INTEGER
+	default 0
+
+	Controls the synchronisation of connections when using persistence
+
+	0: All types of connections are synchronised
+	1: Attempt to reduce the synchronisation traffic depending on
+	the connection type. For persistent services avoid synchronisation
+	for normal connections, do it only for persistence templates.
+	In such case, for TCP and SCTP it may need enabling sloppy_tcp and
+	sloppy_sctp flags on backup servers. For non-persistent services
+	such optimization is not applied, mode 0 is assumed.
+
 sync_version - INTEGER
 	default 1
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/Makefile linux-libre-3.11-rc7-gnu/Documentation/networking/Makefile
--- linux-libre-3.10-gnu/Documentation/networking/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,11 +1,6 @@
 # kbuild trick to avoid linker error. Can be omitted if a module is built.
 obj- := dummy.o
 
-# List of programs to build
-hostprogs-y := ifenslave
-
-HOSTCFLAGS_ifenslave.o += -I$(objtree)/usr/include
-
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/netlink_mmap.txt linux-libre-3.11-rc7-gnu/Documentation/networking/netlink_mmap.txt
--- linux-libre-3.10-gnu/Documentation/networking/netlink_mmap.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/netlink_mmap.txt	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ it will use an allocated socket buffer a
  copied to the ring on transmission, nullifying most of the performance gains.
 Dumps of kernel databases automatically support memory mapped I/O.
 
-Conversion of the transmit path involves changing message contruction to
+Conversion of the transmit path involves changing message construction to
 use memory from the TX ring instead of (usually) a buffer declared on the
 stack and setting up the frame header approriately. Optionally poll() can
 be used to wait for free frames in the TX ring.
@@ -65,8 +65,8 @@ Structured and definitions for using mem
 RX and TX rings
 ----------------
 
-Each ring contains a number of continous memory blocks, containing frames of
-fixed size dependant on the parameters used for ring setup.
+Each ring contains a number of continuous memory blocks, containing frames of
+fixed size dependent on the parameters used for ring setup.
 
 Ring:	[ block 0 ]
 		[ frame 0 ]
@@ -80,7 +80,7 @@ Ring:	[ block 0 ]
 		[ frame 2 * n + 1 ]
 
 The blocks are only visible to the kernel, from the point of view of user-space
-the ring just contains the frames in a continous memory zone.
+the ring just contains the frames in a continuous memory zone.
 
 The ring parameters used for setting up the ring are defined as follows:
 
@@ -91,7 +91,7 @@ struct nl_mmap_req {
 	unsigned int	nm_frame_nr;
 };
 
-Frames are grouped into blocks, where each block is a continous region of memory
+Frames are grouped into blocks, where each block is a continuous region of memory
 and holds nm_block_size / nm_frame_size frames. The total number of frames in
 the ring is nm_frame_nr. The following invariants hold:
 
@@ -113,8 +113,8 @@ Some parameters are constrained, specifi
 
 - nm_frame_nr must equal the actual number of frames as specified above.
 
-When the kernel can't allocate phsyically continous memory for a ring block,
-it will fall back to use physically discontinous memory. This might affect
+When the kernel can't allocate physically continuous memory for a ring block,
+it will fall back to use physically discontinuous memory. This might affect
 performance negatively, in order to avoid this the nm_frame_size parameter
 should be chosen to be as small as possible for the required frame size and
 the number of blocks should be increased instead.
@@ -274,9 +274,9 @@ This example assumes some ring parameter
 			/* Get next frame header */
 			hdr = rx_ring + frame_offset;
 
-			if (hdr->nm_status == NL_MMAP_STATUS_VALID)
+			if (hdr->nm_status == NL_MMAP_STATUS_VALID) {
 				/* Regular memory mapped frame */
-				nlh = (void *hdr) + NL_MMAP_HDRLEN;
+				nlh = (void *)hdr + NL_MMAP_HDRLEN;
 				len = hdr->nm_len;
 
 				/* Release empty message immediately. May happen
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/packet_mmap.txt linux-libre-3.11-rc7-gnu/Documentation/networking/packet_mmap.txt
--- linux-libre-3.10-gnu/Documentation/networking/packet_mmap.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/packet_mmap.txt	2013-08-25 20:43:22.000000000 -0400
@@ -704,6 +704,12 @@ So it seems to be a good candidate to be
 Minimal example code by Daniel Borkmann based on Chetan Loke's lolpcap (compile
 it with gcc -Wall -O2 blob.c, and try things like "./a.out eth0", etc.):
 
+/* Written from scratch, but kernel-to-user space API usage
+ * dissected from lolpcap:
+ *  Copyright 2011, Chetan Loke <loke.chetan@gmail.com>
+ *  License: GPL, version 2.0
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -722,27 +728,6 @@ it with gcc -Wall -O2 blob.c, and try th
 #include <linux/if_ether.h>
 #include <linux/ip.h>
 
-#define BLOCK_SIZE		(1 << 22)
-#define FRAME_SIZE		2048
-
-#define NUM_BLOCKS		64
-#define NUM_FRAMES		((BLOCK_SIZE * NUM_BLOCKS) / FRAME_SIZE)
-
-#define BLOCK_RETIRE_TOV_IN_MS	64
-#define BLOCK_PRIV_AREA_SZ	13
-
-#define ALIGN_8(x)		(((x) + 8 - 1) & ~(8 - 1))
-
-#define BLOCK_STATUS(x)		((x)->h1.block_status)
-#define BLOCK_NUM_PKTS(x)	((x)->h1.num_pkts)
-#define BLOCK_O2FP(x)		((x)->h1.offset_to_first_pkt)
-#define BLOCK_LEN(x)		((x)->h1.blk_len)
-#define BLOCK_SNUM(x)		((x)->h1.seq_num)
-#define BLOCK_O2PRIV(x)		((x)->offset_to_priv)
-#define BLOCK_PRIV(x)		((void *) ((uint8_t *) (x) + BLOCK_O2PRIV(x)))
-#define BLOCK_HDR_LEN		(ALIGN_8(sizeof(struct block_desc)))
-#define BLOCK_PLUS_PRIV(sz_pri)	(BLOCK_HDR_LEN + ALIGN_8((sz_pri)))
-
 #ifndef likely
 # define likely(x)		__builtin_expect(!!(x), 1)
 #endif
@@ -765,7 +750,7 @@ struct ring {
 static unsigned long packets_total = 0, bytes_total = 0;
 static sig_atomic_t sigint = 0;
 
-void sighandler(int num)
+static void sighandler(int num)
 {
 	sigint = 1;
 }
@@ -774,6 +759,8 @@ static int setup_socket(struct ring *rin
 {
 	int err, i, fd, v = TPACKET_V3;
 	struct sockaddr_ll ll;
+	unsigned int blocksiz = 1 << 22, framesiz = 1 << 11;
+	unsigned int blocknum = 64;
 
 	fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
 	if (fd < 0) {
@@ -788,13 +775,12 @@ static int setup_socket(struct ring *rin
 	}
 
 	memset(&ring->req, 0, sizeof(ring->req));
-	ring->req.tp_block_size = BLOCK_SIZE;
-	ring->req.tp_frame_size = FRAME_SIZE;
-	ring->req.tp_block_nr = NUM_BLOCKS;
-	ring->req.tp_frame_nr = NUM_FRAMES;
-	ring->req.tp_retire_blk_tov = BLOCK_RETIRE_TOV_IN_MS;
-	ring->req.tp_sizeof_priv = BLOCK_PRIV_AREA_SZ;
-	ring->req.tp_feature_req_word |= TP_FT_REQ_FILL_RXHASH;
+	ring->req.tp_block_size = blocksiz;
+	ring->req.tp_frame_size = framesiz;
+	ring->req.tp_block_nr = blocknum;
+	ring->req.tp_frame_nr = (blocksiz * blocknum) / framesiz;
+	ring->req.tp_retire_blk_tov = 60;
+	ring->req.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
 
 	err = setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &ring->req,
 			 sizeof(ring->req));
@@ -804,8 +790,7 @@ static int setup_socket(struct ring *rin
 	}
 
 	ring->map = mmap(NULL, ring->req.tp_block_size * ring->req.tp_block_nr,
-			 PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED,
-			 fd, 0);
+			 PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, fd, 0);
 	if (ring->map == MAP_FAILED) {
 		perror("mmap");
 		exit(1);
@@ -835,58 +820,6 @@ static int setup_socket(struct ring *rin
 	return fd;
 }
 
-#ifdef __checked
-static uint64_t prev_block_seq_num = 0;
-
-void assert_block_seq_num(struct block_desc *pbd)
-{
-	if (unlikely(prev_block_seq_num + 1 != BLOCK_SNUM(pbd))) {
-		printf("prev_block_seq_num:%"PRIu64", expected seq:%"PRIu64" != "
-		       "actual seq:%"PRIu64"\n", prev_block_seq_num,
-		       prev_block_seq_num + 1, (uint64_t) BLOCK_SNUM(pbd));
-		exit(1);
-	}
-
-	prev_block_seq_num = BLOCK_SNUM(pbd);
-}
-
-static void assert_block_len(struct block_desc *pbd, uint32_t bytes, int block_num)
-{
-	if (BLOCK_NUM_PKTS(pbd)) {
-		if (unlikely(bytes != BLOCK_LEN(pbd))) {
-			printf("block:%u with %upackets, expected len:%u != actual len:%u\n",
-			       block_num, BLOCK_NUM_PKTS(pbd), bytes, BLOCK_LEN(pbd));
-			exit(1);
-		}
-	} else {
-		if (unlikely(BLOCK_LEN(pbd) != BLOCK_PLUS_PRIV(BLOCK_PRIV_AREA_SZ))) {
-			printf("block:%u, expected len:%lu != actual len:%u\n",
-			       block_num, BLOCK_HDR_LEN, BLOCK_LEN(pbd));
-			exit(1);
-		}
-	}
-}
-
-static void assert_block_header(struct block_desc *pbd, const int block_num)
-{
-	uint32_t block_status = BLOCK_STATUS(pbd);
-
-	if (unlikely((block_status & TP_STATUS_USER) == 0)) {
-		printf("block:%u, not in TP_STATUS_USER\n", block_num);
-		exit(1);
-	}
-
-	assert_block_seq_num(pbd);
-}
-#else
-static inline void assert_block_header(struct block_desc *pbd, const int block_num)
-{
-}
-static void assert_block_len(struct block_desc *pbd, uint32_t bytes, int block_num)
-{
-}
-#endif
-
 static void display(struct tpacket3_hdr *ppd)
 {
 	struct ethhdr *eth = (struct ethhdr *) ((uint8_t *) ppd + ppd->tp_mac);
@@ -916,37 +849,27 @@ static void display(struct tpacket3_hdr
 
 static void walk_block(struct block_desc *pbd, const int block_num)
 {
-	int num_pkts = BLOCK_NUM_PKTS(pbd), i;
+	int num_pkts = pbd->h1.num_pkts, i;
 	unsigned long bytes = 0;
-	unsigned long bytes_with_padding = BLOCK_PLUS_PRIV(BLOCK_PRIV_AREA_SZ);
 	struct tpacket3_hdr *ppd;
 
-	assert_block_header(pbd, block_num);
-
-	ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd + BLOCK_O2FP(pbd));
+	ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd +
+				       pbd->h1.offset_to_first_pkt);
 	for (i = 0; i < num_pkts; ++i) {
 		bytes += ppd->tp_snaplen;
-		if (ppd->tp_next_offset)
-			bytes_with_padding += ppd->tp_next_offset;
-		else
-			bytes_with_padding += ALIGN_8(ppd->tp_snaplen + ppd->tp_mac);
-
 		display(ppd);
 
-		ppd = (struct tpacket3_hdr *) ((uint8_t *) ppd + ppd->tp_next_offset);
-		__sync_synchronize();
+		ppd = (struct tpacket3_hdr *) ((uint8_t *) ppd +
+					       ppd->tp_next_offset);
 	}
 
-	assert_block_len(pbd, bytes_with_padding, block_num);
-
 	packets_total += num_pkts;
 	bytes_total += bytes;
 }
 
-void flush_block(struct block_desc *pbd)
+static void flush_block(struct block_desc *pbd)
 {
-	BLOCK_STATUS(pbd) = TP_STATUS_KERNEL;
-	__sync_synchronize();
+	pbd->h1.block_status = TP_STATUS_KERNEL;
 }
 
 static void teardown_socket(struct ring *ring, int fd)
@@ -962,7 +885,7 @@ int main(int argc, char **argp)
 	socklen_t len;
 	struct ring ring;
 	struct pollfd pfd;
-	unsigned int block_num = 0;
+	unsigned int block_num = 0, blocks = 64;
 	struct block_desc *pbd;
 	struct tpacket_stats_v3 stats;
 
@@ -984,15 +907,15 @@ int main(int argc, char **argp)
 
 	while (likely(!sigint)) {
 		pbd = (struct block_desc *) ring.rd[block_num].iov_base;
-retry_block:
-		if ((BLOCK_STATUS(pbd) & TP_STATUS_USER) == 0) {
+
+		if ((pbd->h1.block_status & TP_STATUS_USER) == 0) {
 			poll(&pfd, 1, -1);
-			goto retry_block;
+			continue;
 		}
 
 		walk_block(pbd, block_num);
 		flush_block(pbd);
-		block_num = (block_num + 1) % NUM_BLOCKS;
+		block_num = (block_num + 1) % blocks;
 	}
 
 	len = sizeof(stats);
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/scaling.txt linux-libre-3.11-rc7-gnu/Documentation/networking/scaling.txt
--- linux-libre-3.10-gnu/Documentation/networking/scaling.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/scaling.txt	2013-08-25 20:43:22.000000000 -0400
@@ -163,6 +163,64 @@ and unnecessary. If there are fewer hard
 RPS might be beneficial if the rps_cpus for each queue are the ones that
 share the same memory domain as the interrupting CPU for that queue.
 
+==== RPS Flow Limit
+
+RPS scales kernel receive processing across CPUs without introducing
+reordering. The trade-off to sending all packets from the same flow
+to the same CPU is CPU load imbalance if flows vary in packet rate.
+In the extreme case a single flow dominates traffic. Especially on
+common server workloads with many concurrent connections, such
+behavior indicates a problem such as a misconfiguration or spoofed
+source Denial of Service attack.
+
+Flow Limit is an optional RPS feature that prioritizes small flows
+during CPU contention by dropping packets from large flows slightly
+ahead of those from small flows. It is active only when an RPS or RFS
+destination CPU approaches saturation.  Once a CPU's input packet
+queue exceeds half the maximum queue length (as set by sysctl
+net.core.netdev_max_backlog), the kernel starts a per-flow packet
+count over the last 256 packets. If a flow exceeds a set ratio (by
+default, half) of these packets when a new packet arrives, then the
+new packet is dropped. Packets from other flows are still only
+dropped once the input packet queue reaches netdev_max_backlog.
+No packets are dropped when the input packet queue length is below
+the threshold, so flow limit does not sever connections outright:
+even large flows maintain connectivity.
+
+== Interface
+
+Flow limit is compiled in by default (CONFIG_NET_FLOW_LIMIT), but not
+turned on. It is implemented for each CPU independently (to avoid lock
+and cache contention) and toggled per CPU by setting the relevant bit
+in sysctl net.core.flow_limit_cpu_bitmap. It exposes the same CPU
+bitmap interface as rps_cpus (see above) when called from procfs:
+
+ /proc/sys/net/core/flow_limit_cpu_bitmap
+
+Per-flow rate is calculated by hashing each packet into a hashtable
+bucket and incrementing a per-bucket counter. The hash function is
+the same that selects a CPU in RPS, but as the number of buckets can
+be much larger than the number of CPUs, flow limit has finer-grained
+identification of large flows and fewer false positives. The default
+table has 4096 buckets. This value can be modified through sysctl
+
+ net.core.flow_limit_table_len
+
+The value is only consulted when a new table is allocated. Modifying
+it does not update active tables.
+
+== Suggested Configuration
+
+Flow limit is useful on systems with many concurrent connections,
+where a single connection taking up 50% of a CPU indicates a problem.
+In such environments, enable the feature on all CPUs that handle
+network rx interrupts (as set in /proc/irq/N/smp_affinity).
+
+The feature depends on the input packet queue length to exceed
+the flow limit threshold (50%) + the flow history length (256).
+Setting net.core.netdev_max_backlog to either 1000 or 10000
+performed well in experiments.
+
 
 RFS: Receive Flow Steering
 ==========================
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/networking/vortex.txt linux-libre-3.11-rc7-gnu/Documentation/networking/vortex.txt
--- linux-libre-3.10-gnu/Documentation/networking/vortex.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/networking/vortex.txt	2013-08-25 20:43:22.000000000 -0400
@@ -359,7 +359,7 @@ steps you should take:
 - OK, it's a driver problem.
 
    You need to generate a report.  Typically this is an email to the
-   maintainer and/or linux-net@vger.kernel.org.  The maintainer's
+   maintainer and/or netdev@vger.kernel.org.  The maintainer's
    email address will be in the driver source or in the MAINTAINERS file.
 
 - The contents of your report will vary a lot depending upon the
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/parisc/registers linux-libre-3.11-rc7-gnu/Documentation/parisc/registers
--- linux-libre-3.10-gnu/Documentation/parisc/registers	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/parisc/registers	2013-08-25 20:43:22.000000000 -0400
@@ -78,6 +78,14 @@ Shadow Registers		used by interruption h
 TOC enable bit			1
 
 =========================================================================
+
+The PA-RISC architecture defines 7 registers as "shadow registers".
+Those are used in RETURN FROM INTERRUPTION AND RESTORE instruction to reduce
+the state save and restore time by eliminating the need for general register
+(GR) saves and restores in interruption handlers.
+Shadow registers are the GRs 1, 8, 9, 16, 17, 24, and 25.
+
+=========================================================================
 Register usage notes, originally from John Marvin, with some additional
 notes from Randolph Chung.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/pinctrl.txt linux-libre-3.11-rc7-gnu/Documentation/pinctrl.txt
--- linux-libre-3.10-gnu/Documentation/pinctrl.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/pinctrl.txt	2013-08-25 20:43:22.000000000 -0400
@@ -203,15 +203,8 @@ using a certain resistor value - pull up
 stable value when nothing is driving the rail it is connected to, or when it's
 unconnected.
 
-Pin configuration can be programmed either using the explicit APIs described
-immediately below, or by adding configuration entries into the mapping table;
-see section "Board/machine configuration" below.
-
-For example, a platform may do the following to pull up a pin to VDD:
-
-#include <linux/pinctrl/consumer.h>
-
-ret = pin_config_set("foo-dev", "FOO_GPIO_PIN", PLATFORM_X_PULL_UP);
+Pin configuration can be programmed by adding configuration entries into the
+mapping table; see section "Board/machine configuration" below.
 
 The format and meaning of the configuration parameter, PLATFORM_X_PULL_UP
 above, is entirely defined by the pin controller driver.
@@ -298,7 +291,7 @@ Since the pin controller subsystem have
 controller we need a mapping so that the pin control subsystem can figure out
 which pin controller handles control of a certain GPIO pin. Since a single
 pin controller may be muxing several GPIO ranges (typically SoCs that have
-one set of pins but internally several GPIO silicon blocks, each modeled as
+one set of pins but internally several GPIO silicon blocks, each modelled as
 a struct gpio_chip) any number of GPIO ranges can be added to a pin controller
 instance like this:
 
@@ -350,6 +343,23 @@ chip b:
  - GPIO range : [48 .. 55]
  - pin range  : [64 .. 71]
 
+The above examples assume the mapping between the GPIOs and pins is
+linear. If the mapping is sparse or haphazard, an array of arbitrary pin
+numbers can be encoded in the range like this:
+
+static const unsigned range_pins[] = { 14, 1, 22, 17, 10, 8, 6, 2 };
+
+static struct pinctrl_gpio_range gpio_range = {
+	.name = "chip",
+	.id = 0,
+	.base = 32,
+	.pins = &range_pins,
+	.npins = ARRAY_SIZE(range_pins),
+	.gc = &chip;
+};
+
+In this case the pin_base property will be ignored.
+
 When GPIO-specific functions in the pin control subsystem are called, these
 ranges will be used to look up the appropriate pin controller by inspecting
 and matching the pin to the pin ranges across all controllers. When a
@@ -357,9 +367,9 @@ pin controller handling the matching ran
 will be called on that specific pin controller.
 
 For all functionalities dealing with pin biasing, pin muxing etc, the pin
-controller subsystem will subtract the range's .base offset from the passed
-in gpio number, and add the ranges's .pin_base offset to retrive a pin number.
-After that, the subsystem passes it on to the pin control driver, so the driver
+controller subsystem will look up the corresponding pin number from the passed
+in gpio number, and use the range's internals to retrive a pin number. After
+that, the subsystem passes it on to the pin control driver, so the driver
 will get an pin number into its handled number range. Further it is also passed
 the range ID value, so that the pin controller knows which range it should
 deal with.
@@ -368,6 +378,7 @@ Calling pinctrl_add_gpio_range from pinc
 section 2.1 of Documentation/devicetree/bindings/gpio/gpio.txt on how to bind
 pinctrl and gpio drivers.
 
+
 PINMUX interfaces
 =================
 
@@ -1226,8 +1237,8 @@ setting up the config and muxing for the
 probing, nevertheless orthogonal to the GPIO subsystem.
 
 But there are also situations where it makes sense for the GPIO subsystem
-to communicate directly with with the pinctrl subsystem, using the latter
-as a back-end. This is when the GPIO driver may call out to the functions
+to communicate directly with the pinctrl subsystem, using the latter as a
+back-end. This is when the GPIO driver may call out to the functions
 described in the section "Pin control interaction with the GPIO subsystem"
 above. This only involves per-pin multiplexing, and will be completely
 hidden behind the gpio_*() function namespace. In this case, the driver
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/power/pm_qos_interface.txt linux-libre-3.11-rc7-gnu/Documentation/power/pm_qos_interface.txt
--- linux-libre-3.10-gnu/Documentation/power/pm_qos_interface.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/power/pm_qos_interface.txt	2013-08-25 20:43:22.000000000 -0400
@@ -7,7 +7,7 @@ one of the parameters.
 Two different PM QoS frameworks are available:
 1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput.
 2. the per-device PM QoS framework provides the API to manage the per-device latency
-constraints.
+constraints and PM QoS flags.
 
 Each parameters have defined units:
  * latency: usec
@@ -86,13 +86,17 @@ To remove the user mode request for a ta
 node.
 
 
-2. PM QoS per-device latency framework
+2. PM QoS per-device latency and flags framework
+
+For each device, there are two lists of PM QoS requests. One is maintained
+along with the aggregated target of latency value and the other is for PM QoS
+flags. Values are updated in response to changes of the request list.
+
+Target latency value is simply the minimum of the request values held in the
+parameter list elements.  The PM QoS flags aggregate value is a gather (bitwise
+OR) of all list elements' values. Two device PM QoS flags are defined currently:
+PM_QOS_FLAG_NO_POWER_OFF and PM_QOS_FLAG_REMOTE_WAKEUP.
 
-For each device a list of performance requests is maintained along with
-an aggregated target value.  The aggregated target value is updated with
-changes to the request list or elements of the list.  Typically the
-aggregated target value is simply the max or min of the request values held
-in the parameter list elements.
 Note: the aggregated target value is implemented as an atomic variable so that
 reading the aggregated value does not require any locking mechanism.
 
@@ -119,6 +123,38 @@ the request.
 s32 dev_pm_qos_read_value(device):
 Returns the aggregated value for a given device's constraints list.
 
+enum pm_qos_flags_status dev_pm_qos_flags(device, mask)
+Check PM QoS flags of the given device against the given mask of flags.
+The meaning of the return values is as follows:
+	PM_QOS_FLAGS_ALL: All flags from the mask are set
+	PM_QOS_FLAGS_SOME: Some flags from the mask are set
+	PM_QOS_FLAGS_NONE: No flags from the mask are set
+	PM_QOS_FLAGS_UNDEFINED: The device's PM QoS structure has not been
+			initialized or the list of requests is empty.
+
+int dev_pm_qos_add_ancestor_request(dev, handle, value)
+Add a PM QoS request for the first direct ancestor of the given device whose
+power.ignore_children flag is unset.
+
+int dev_pm_qos_expose_latency_limit(device, value)
+Add a request to the device's PM QoS list of latency constraints and create
+a sysfs attribute pm_qos_resume_latency_us under the device's power directory
+allowing user space to manipulate that request.
+
+void dev_pm_qos_hide_latency_limit(device)
+Drop the request added by dev_pm_qos_expose_latency_limit() from the device's
+PM QoS list of latency constraints and remove sysfs attribute pm_qos_resume_latency_us
+from the device's power directory.
+
+int dev_pm_qos_expose_flags(device, value)
+Add a request to the device's PM QoS list of flags and create sysfs attributes
+pm_qos_no_power_off and pm_qos_remote_wakeup under the device's power directory
+allowing user space to change these flags' value.
+
+void dev_pm_qos_hide_flags(device)
+Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS list
+of flags and remove sysfs attributes pm_qos_no_power_off and pm_qos_remote_wakeup
+under the device's power directory.
 
 Notification mechanisms:
 The per-device PM QoS framework has 2 different and distinct notification trees:
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/power/runtime_pm.txt linux-libre-3.11-rc7-gnu/Documentation/power/runtime_pm.txt
--- linux-libre-3.10-gnu/Documentation/power/runtime_pm.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/power/runtime_pm.txt	2013-08-25 20:43:22.000000000 -0400
@@ -144,8 +144,12 @@ The action performed by the idle callbac
 (or driver) in question, but the expected and recommended action is to check
 if the device can be suspended (i.e. if all of the conditions necessary for
 suspending the device are satisfied) and to queue up a suspend request for the
-device in that case.  The value returned by this callback is ignored by the PM
-core.
+device in that case.  If there is no idle callback, or if the callback returns
+0, then the PM core will attempt to carry out a runtime suspend of the device;
+in essence, it will call pm_runtime_suspend() directly.  To prevent this (for
+example, if the callback routine has started a delayed suspend), the routine
+should return a non-zero value.  Negative error return codes are ignored by the
+PM core.
 
 The helper functions provided by the PM core, described in Section 4, guarantee
 that the following constraints are met with respect to runtime PM callbacks for
@@ -301,9 +305,10 @@ drivers/base/power/runtime.c and include
       removing the device from device hierarchy
 
   int pm_runtime_idle(struct device *dev);
-    - execute the subsystem-level idle callback for the device; returns 0 on
-      success or error code on failure, where -EINPROGRESS means that
-      ->runtime_idle() is already being executed
+    - execute the subsystem-level idle callback for the device; returns an
+      error code on failure, where -EINPROGRESS means that ->runtime_idle() is
+      already being executed; if there is no callback or the callback returns 0
+      then run pm_runtime_suspend(dev) and return its result
 
   int pm_runtime_suspend(struct device *dev);
     - execute the subsystem-level suspend callback for the device; returns 0 on
@@ -660,11 +665,6 @@ Subsystems may wish to conserve code spa
 management callbacks provided by the PM core, defined in
 driver/base/power/generic_ops.c:
 
-  int pm_generic_runtime_idle(struct device *dev);
-    - invoke the ->runtime_idle() callback provided by the driver of this
-      device, if defined, and call pm_runtime_suspend() for this device if the
-      return value is 0 or the callback is not defined
-
   int pm_generic_runtime_suspend(struct device *dev);
     - invoke the ->runtime_suspend() callback provided by the driver of this
       device and return its result, or return -EINVAL if not defined
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/power/video_extension.txt linux-libre-3.11-rc7-gnu/Documentation/power/video_extension.txt
--- linux-libre-3.10-gnu/Documentation/power/video_extension.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/power/video_extension.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-ACPI video extensions
-~~~~~~~~~~~~~~~~~~~~~
-
-This driver implement the ACPI Extensions For Display Adapters for
-integrated graphics devices on motherboard, as specified in ACPI 2.0
-Specification, Appendix B, allowing to perform some basic control like
-defining the video POST device, retrieving EDID information or to
-setup a video output, etc.  Note that this is an ref. implementation
-only.  It may or may not work for your integrated video device.
-
-Interfaces exposed to userland through /proc/acpi/video:
-
-VGA/info : display the supported video bus device capability like Video ROM, CRT/LCD/TV.
-VGA/ROM :  Used to get a copy of the display devices' ROM data (up to 4k).
-VGA/POST_info : Used to determine what options are implemented.
-VGA/POST : Used to get/set POST device.
-VGA/DOS : Used to get/set ownership of output switching:
-	Please refer ACPI spec B.4.1 _DOS
-VGA/CRT : CRT output
-VGA/LCD : LCD output
-VGA/TVO : TV output
-VGA/*/brightness : Used to get/set brightness of output device
-
-Notify event through /proc/acpi/event:
-
-#define ACPI_VIDEO_NOTIFY_SWITCH        0x80
-#define ACPI_VIDEO_NOTIFY_PROBE         0x81
-#define ACPI_VIDEO_NOTIFY_CYCLE         0x82
-#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT   0x83
-#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT   0x84
-
-#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS      0x82
-#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS        0x83
-#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS        0x84
-#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS       0x85
-#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF           0x86
-
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/powerpc/00-INDEX linux-libre-3.11-rc7-gnu/Documentation/powerpc/00-INDEX
--- linux-libre-3.10-gnu/Documentation/powerpc/00-INDEX	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/powerpc/00-INDEX	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,8 @@ hvcs.txt
 	- IBM "Hypervisor Virtual Console Server" Installation Guide
 mpc52xx.txt
 	- Linux 2.6.x on MPC52xx family
+pmu-ebb.txt
+	- Description of the API for using the PMU with Event Based Branches.
 qe_firmware.txt
 	- describes the layout of firmware binaries for the Freescale QUICC
 	  Engine and the code that parses and uploads the microcode therein.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/powerpc/pmu-ebb.txt linux-libre-3.11-rc7-gnu/Documentation/powerpc/pmu-ebb.txt
--- linux-libre-3.10-gnu/Documentation/powerpc/pmu-ebb.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/powerpc/pmu-ebb.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,137 @@
+PMU Event Based Branches
+========================
+
+Event Based Branches (EBBs) are a feature which allows the hardware to
+branch directly to a specified user space address when certain events occur.
+
+The full specification is available in Power ISA v2.07:
+
+  https://www.power.org/documentation/power-isa-version-2-07/
+
+One type of event for which EBBs can be configured is PMU exceptions. This
+document describes the API for configuring the Power PMU to generate EBBs,
+using the Linux perf_events API.
+
+
+Terminology
+-----------
+
+Throughout this document we will refer to an "EBB event" or "EBB events". This
+just refers to a struct perf_event which has set the "EBB" flag in its
+attr.config. All events which can be configured on the hardware PMU are
+possible "EBB events".
+
+
+Background
+----------
+
+When a PMU EBB occurs it is delivered to the currently running process. As such
+EBBs can only sensibly be used by programs for self-monitoring.
+
+It is a feature of the perf_events API that events can be created on other
+processes, subject to standard permission checks. This is also true of EBB
+events, however unless the target process enables EBBs (via mtspr(BESCR)) no
+EBBs will ever be delivered.
+
+This makes it possible for a process to enable EBBs for itself, but not
+actually configure any events. At a later time another process can come along
+and attach an EBB event to the process, which will then cause EBBs to be
+delivered to the first process. It's not clear if this is actually useful.
+
+
+When the PMU is configured for EBBs, all PMU interrupts are delivered to the
+user process. This means once an EBB event is scheduled on the PMU, no non-EBB
+events can be configured. This means that EBB events can not be run
+concurrently with regular 'perf' commands, or any other perf events.
+
+It is however safe to run 'perf' commands on a process which is using EBBs. The
+kernel will in general schedule the EBB event, and perf will be notified that
+its events could not run.
+
+The exclusion between EBB events and regular events is implemented using the
+existing "pinned" and "exclusive" attributes of perf_events. This means EBB
+events will be given priority over other events, unless they are also pinned.
+If an EBB event and a regular event are both pinned, then whichever is enabled
+first will be scheduled and the other will be put in error state. See the
+section below titled "Enabling an EBB event" for more information.
+
+
+Creating an EBB event
+---------------------
+
+To request that an event is counted using EBB, the event code should have bit
+63 set.
+
+EBB events must be created with a particular, and restrictive, set of
+attributes - this is so that they interoperate correctly with the rest of the
+perf_events subsystem.
+
+An EBB event must be created with the "pinned" and "exclusive" attributes set.
+Note that if you are creating a group of EBB events, only the leader can have
+these attributes set.
+
+An EBB event must NOT set any of the "inherit", "sample_period", "freq" or
+"enable_on_exec" attributes.
+
+An EBB event must be attached to a task. This is specified to perf_event_open()
+by passing a pid value, typically 0 indicating the current task.
+
+All events in a group must agree on whether they want EBB. That is all events
+must request EBB, or none may request EBB.
+
+EBB events must specify the PMC they are to be counted on. This ensures
+userspace is able to reliably determine which PMC the event is scheduled on.
+
+
+Enabling an EBB event
+---------------------
+
+Once an EBB event has been successfully opened, it must be enabled with the
+perf_events API. This can be achieved either via the ioctl() interface, or the
+prctl() interface.
+
+However, due to the design of the perf_events API, enabling an event does not
+guarantee that it has been scheduled on the PMU. To ensure that the EBB event
+has been scheduled on the PMU, you must perform a read() on the event. If the
+read() returns EOF, then the event has not been scheduled and EBBs are not
+enabled.
+
+This behaviour occurs because the EBB event is pinned and exclusive. When the
+EBB event is enabled it will force all other non-pinned events off the PMU. In
+this case the enable will be successful. However if there is already an event
+pinned on the PMU then the enable will not be successful.
+
+
+Reading an EBB event
+--------------------
+
+It is possible to read() from an EBB event. However the results are
+meaningless. Because interrupts are being delivered to the user process the
+kernel is not able to count the event, and so will return a junk value.
+
+
+Closing an EBB event
+--------------------
+
+When an EBB event is finished with, you can close it using close() as for any
+regular event. If this is the last EBB event the PMU will be deconfigured and
+no further PMU EBBs will be delivered.
+
+
+EBB Handler
+-----------
+
+The EBB handler is just regular userspace code, however it must be written in
+the style of an interrupt handler. When the handler is entered all registers
+are live (possibly) and so must be saved somehow before the handler can invoke
+other code.
+
+It's up to the program how to handle this. For C programs a relatively simple
+option is to create an interrupt frame on the stack and save registers there.
+
+Fork
+----
+
+EBB events are not inherited across fork. If the child process wishes to use
+EBBs it should open a new event for itself. Similarly the EBB state in
+BESCR/EBBHR/EBBRR is cleared across fork().
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/printk-formats.txt linux-libre-3.11-rc7-gnu/Documentation/printk-formats.txt
--- linux-libre-3.10-gnu/Documentation/printk-formats.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/printk-formats.txt	2013-08-25 20:43:22.000000000 -0400
@@ -121,6 +121,38 @@ IPv6 addresses:
 	print a compressed IPv6 address as described by
 	http://tools.ietf.org/html/rfc5952
 
+IPv4/IPv6 addresses (generic, with port, flowinfo, scope):
+
+	%pIS	1.2.3.4		or 0001:0002:0003:0004:0005:0006:0007:0008
+	%piS	001.002.003.004	or 00010002000300040005000600070008
+	%pISc	1.2.3.4		or 1:2:3:4:5:6:7:8
+	%pISpc	1.2.3.4:12345	or [1:2:3:4:5:6:7:8]:12345
+	%p[Ii]S[pfschnbl]
+
+	For printing an IP address without the need to distinguish whether it's
+	of type AF_INET or AF_INET6, a pointer to a valid 'struct sockaddr',
+	specified through 'IS' or 'iS', can be passed to this format specifier.
+
+	The additional 'p', 'f', and 's' specifiers are used to specify port
+	(IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ':' prefix,
+	flowinfo a '/' and scope a '%', each followed by the actual value.
+
+	In case of an IPv6 address the compressed IPv6 address as described by
+	http://tools.ietf.org/html/rfc5952 is being used if the additional
+	specifier 'c' is given. The IPv6 address is surrounded by '[', ']' in
+	case of additional specifiers 'p', 'f' or 's' as suggested by
+	https://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-07
+
+	In case of IPv4 addresses, the additional 'h', 'n', 'b', and 'l'
+	specifiers can be used as well and are ignored in case of an IPv6
+	address.
+
+	Further examples:
+
+	%pISfc		1.2.3.4		or [1:2:3:4:5:6:7:8]/123456789
+	%pISsc		1.2.3.4		or [1:2:3:4:5:6:7:8]%1234567890
+	%pISpfc		1.2.3.4:12345	or [1:2:3:4:5:6:7:8]:12345/123456789
+
 UUID/GUID addresses:
 
 	%pUb	00010203-0405-0607-0809-0a0b0c0d0e0f
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/pwm.txt linux-libre-3.11-rc7-gnu/Documentation/pwm.txt
--- linux-libre-3.10-gnu/Documentation/pwm.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/pwm.txt	2013-08-25 20:43:22.000000000 -0400
@@ -45,6 +45,43 @@ int pwm_config(struct pwm_device *pwm, i
 
 To start/stop toggling the PWM output use pwm_enable()/pwm_disable().
 
+Using PWMs with the sysfs interface
+-----------------------------------
+
+If CONFIG_SYSFS is enabled in your kernel configuration a simple sysfs
+interface is provided to use the PWMs from userspace. It is exposed at
+/sys/class/pwm/. Each probed PWM controller/chip will be exported as
+pwmchipN, where N is the base of the PWM chip. Inside the directory you
+will find:
+
+npwm - The number of PWM channels this chip supports (read-only).
+
+export - Exports a PWM channel for use with sysfs (write-only).
+
+unexport - Unexports a PWM channel from sysfs (write-only).
+
+The PWM channels are numbered using a per-chip index from 0 to npwm-1.
+
+When a PWM channel is exported a pwmX directory will be created in the
+pwmchipN directory it is associated with, where X is the number of the
+channel that was exported. The following properties will then be available:
+
+period - The total period of the PWM signal (read/write).
+	Value is in nanoseconds and is the sum of the active and inactive
+	time of the PWM.
+
+duty_cycle - The active time of the PWM signal (read/write).
+	Value is in nanoseconds and must be less than the period.
+
+polarity - Changes the polarity of the PWM signal (read/write).
+	Writes to this property only work if the PWM chip supports changing
+	the polarity. The polarity can only be changed if the PWM is not
+	enabled. Value is the string "normal" or "inversed".
+
+enable - Enable/disable the PWM signal (read/write).
+	0 - disabled
+	1 - enabled
+
 Implementing a PWM driver
 -------------------------
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/rapidio/rapidio.txt linux-libre-3.11-rc7-gnu/Documentation/rapidio/rapidio.txt
--- linux-libre-3.10-gnu/Documentation/rapidio/rapidio.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/rapidio/rapidio.txt	2013-08-25 20:43:22.000000000 -0400
@@ -73,28 +73,44 @@ data structure. This structure includes
 ports that form the same network. It also contains a pointer to the default
 master port that is used to communicate with devices within the network.
 
+2.5 Device Drivers
+
+RapidIO device-specific drivers follow Linux Kernel Driver Model and are
+intended to support specific RapidIO devices attached to the RapidIO network.
+
+2.6 Subsystem Interfaces
+
+RapidIO interconnect specification defines features that may be used to provide
+one or more common service layers for all participating RapidIO devices. These
+common services may act separately from device-specific drivers or be used by
+device-specific drivers. Example of such service provider is the RIONET driver
+which implements Ethernet-over-RapidIO interface. Because only one driver can be
+registered for a device, all common RapidIO services have to be registered as
+subsystem interfaces. This allows to have multiple common services attached to
+the same device without blocking attachment of a device-specific driver.
+
 3. Subsystem Initialization
 ---------------------------
 
 In order to initialize the RapidIO subsystem, a platform must initialize and
 register at least one master port within the RapidIO network. To register mport
-within the subsystem controller driver initialization code calls function
+within the subsystem controller driver's initialization code calls function
 rio_register_mport() for each available master port.
 
-RapidIO subsystem uses subsys_initcall() or device_initcall() to perform
-controller initialization (depending on controller device type).
-
 After all active master ports are registered with a RapidIO subsystem,
 an enumeration and/or discovery routine may be called automatically or
 by user-space command.
 
+RapidIO subsystem can be configured to be built as a statically linked or
+modular component of the kernel (see details below).
+
 4. Enumeration and Discovery
 ----------------------------
 
 4.1 Overview
 ------------
 
-RapidIO subsystem configuration options allow users to specify enumeration and
+RapidIO subsystem configuration options allow users to build enumeration and
 discovery methods as statically linked components or loadable modules.
 An enumeration/discovery method implementation and available input parameters
 define how any given method can be attached to available RapidIO mports:
@@ -115,8 +131,8 @@ several methods to initiate an enumerati
   endpoint waits for enumeration to be completed. If the specified timeout
   expires the discovery process is terminated without obtaining RapidIO network
   information. NOTE: a timed out discovery process may be restarted later using
-  a user-space command as it is described later if the given endpoint was
-  enumerated successfully.
+  a user-space command as it is described below (if the given endpoint was
+  enumerated successfully).
 
   (b) Statically linked enumeration and discovery process can be started by
   a command from user space. This initiation method provides more flexibility
@@ -138,15 +154,42 @@ When a network scan process is started i
 routine depending on the configured role of a master port: host or agent.
 
 Enumeration is performed by a master port if it is configured as a host port by
-assigning a host device ID greater than or equal to zero. A host device ID is
-assigned to a master port through the kernel command line parameter "riohdid=",
-or can be configured in a platform-specific manner. If the host device ID for
-a specific master port is set to -1, the discovery process will be performed
-for it.
+assigning a host destination ID greater than or equal to zero. The host
+destination ID can be assigned to a master port using various methods depending
+on RapidIO subsystem build configuration:
+
+  (a) For a statically linked RapidIO subsystem core use command line parameter
+  "rapidio.hdid=" with a list of destination ID assignments in order of mport
+  device registration. For example, in a system with two RapidIO controllers
+  the command line parameter "rapidio.hdid=-1,7" will result in assignment of
+  the host destination ID=7 to the second RapidIO controller, while the first
+  one will be assigned destination ID=-1.
+
+  (b) If the RapidIO subsystem core is built as a loadable module, in addition
+  to the method shown above, the host destination ID(s) can be specified using
+  traditional methods of passing module parameter "hdid=" during its loading:
+  - from command line: "modprobe rapidio hdid=-1,7", or
+  - from modprobe configuration file using configuration command "options",
+    like in this example: "options rapidio hdid=-1,7". An example of modprobe
+    configuration file is provided in the section below.
+
+  NOTES:
+  (i) if "hdid=" parameter is omitted all available mport will be assigned
+  destination ID = -1;
+  (ii) the "hdid=" parameter in systems with multiple mports can have
+  destination ID assignments omitted from the end of list (default = -1).
+
+If the host device ID for a specific master port is set to -1, the discovery
+process will be performed for it.
 
 The enumeration and discovery routines use RapidIO maintenance transactions
 to access the configuration space of devices.
 
+NOTE: If RapidIO switch-specific device drivers are built as loadable modules
+they must be loaded before enumeration/discovery process starts.
+This requirement is cased by the fact that enumeration/discovery methods invoke
+vendor-specific callbacks on early stages.
+
 4.2 Automatic Start of Enumeration and Discovery
 ------------------------------------------------
 
@@ -266,7 +309,36 @@ method's module initialization routine c
 an enumerator to a specified mport device (or devices). The basic enumerator
 implementation demonstrates this process.
 
-5. References
+4.6 Using Loadable RapidIO Switch Drivers
+-----------------------------------------
+
+In the case when RapidIO switch drivers are built as loadable modules a user
+must ensure that they are loaded before the enumeration/discovery starts.
+This process can be automated by specifying pre- or post- dependencies in the
+RapidIO-specific modprobe configuration file as shown in the example below.
+
+  File /etc/modprobe.d/rapidio.conf:
+  ----------------------------------
+
+  # Configure RapidIO subsystem modules
+
+  # Set enumerator host destination ID (overrides kernel command line option)
+  options rapidio hdid=-1,2
+
+  # Load RapidIO switch drivers immediately after rapidio core module was loaded
+  softdep rapidio post: idt_gen2 idtcps tsi57x
+
+  # OR :
+
+  # Load RapidIO switch drivers just before rio-scan enumerator module is loaded
+  softdep rio-scan pre: idt_gen2 idtcps tsi57x
+
+  --------------------------
+
+NOTE: In the example above, one of "softdep" commands must be removed or
+commented out to keep required module loading sequence.
+
+A. References
 -------------
 
 [1] RapidIO Trade Association. RapidIO Interconnect Specifications.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/rapidio/sysfs.txt linux-libre-3.11-rc7-gnu/Documentation/rapidio/sysfs.txt
--- linux-libre-3.10-gnu/Documentation/rapidio/sysfs.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/rapidio/sysfs.txt	2013-08-25 20:43:22.000000000 -0400
@@ -40,6 +40,7 @@ device_rev - returns the device revision
              (see 4.1 for switch specific details)
    lprev   - returns name of previous device (switch) on the path to the device
              that that owns this attribute
+  modalias - returns the device modalias
 
 In addition to the files listed above, each device has a binary attribute file
 that allows read/write access to the device configuration registers using
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/RCU/checklist.txt linux-libre-3.11-rc7-gnu/Documentation/RCU/checklist.txt
--- linux-libre-3.10-gnu/Documentation/RCU/checklist.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/RCU/checklist.txt	2013-08-25 20:43:22.000000000 -0400
@@ -354,12 +354,6 @@ over a rather long period of time, but i
 	using RCU rather than SRCU, because RCU is almost always faster
 	and easier to use than is SRCU.
 
-	If you need to enter your read-side critical section in a
-	hardirq or exception handler, and then exit that same read-side
-	critical section in the task that was interrupted, then you need
-	to srcu_read_lock_raw() and srcu_read_unlock_raw(), which avoid
-	the lockdep checking that would otherwise this practice illegal.
-
 	Also unlike other forms of RCU, explicit initialization
 	and cleanup is required via init_srcu_struct() and
 	cleanup_srcu_struct().	These are passed a "struct srcu_struct"
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/RCU/torture.txt linux-libre-3.11-rc7-gnu/Documentation/RCU/torture.txt
--- linux-libre-3.10-gnu/Documentation/RCU/torture.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/RCU/torture.txt	2013-08-25 20:43:22.000000000 -0400
@@ -182,12 +182,6 @@ torture_type	The type of RCU to test, wi
 		"srcu_expedited": srcu_read_lock(), srcu_read_unlock() and
 			synchronize_srcu_expedited().
 
-		"srcu_raw": srcu_read_lock_raw(), srcu_read_unlock_raw(),
-			and call_srcu().
-
-		"srcu_raw_sync": srcu_read_lock_raw(), srcu_read_unlock_raw(),
-			and synchronize_srcu().
-
 		"sched": preempt_disable(), preempt_enable(), and
 			call_rcu_sched().
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/RCU/trace.txt linux-libre-3.11-rc7-gnu/Documentation/RCU/trace.txt
--- linux-libre-3.10-gnu/Documentation/RCU/trace.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/RCU/trace.txt	2013-08-25 20:43:22.000000000 -0400
@@ -530,113 +530,21 @@ o	"nos" counts the number of times we ba
 	reasons, e.g., the grace period ended first.
 
 
-CONFIG_TINY_RCU and CONFIG_TINY_PREEMPT_RCU debugfs Files and Formats
+CONFIG_TINY_RCU debugfs Files and Formats
 
 These implementations of RCU provides a single debugfs file under the
 top-level directory RCU, namely rcu/rcudata, which displays fields in
-rcu_bh_ctrlblk, rcu_sched_ctrlblk and, for CONFIG_TINY_PREEMPT_RCU,
-rcu_preempt_ctrlblk.
+rcu_bh_ctrlblk and rcu_sched_ctrlblk.
 
 The output of "cat rcu/rcudata" is as follows:
 
-rcu_preempt: qlen=24 gp=1097669 g197/p197/c197 tasks=...
-             ttb=. btg=no ntb=184 neb=0 nnb=183 j=01f7 bt=0274
-             normal balk: nt=1097669 gt=0 bt=371 b=0 ny=25073378 nos=0
-             exp balk: bt=0 nos=0
 rcu_sched: qlen: 0
 rcu_bh: qlen: 0
 
-This is split into rcu_preempt, rcu_sched, and rcu_bh sections, with the
-rcu_preempt section appearing only in CONFIG_TINY_PREEMPT_RCU builds.
-The last three lines of the rcu_preempt section appear only in
-CONFIG_RCU_BOOST kernel builds.  The fields are as follows:
+This is split into rcu_sched and rcu_bh sections.  The field is as
+follows:
 
 o	"qlen" is the number of RCU callbacks currently waiting either
 	for an RCU grace period or waiting to be invoked.  This is the
 	only field present for rcu_sched and rcu_bh, due to the
 	short-circuiting of grace period in those two cases.
-
-o	"gp" is the number of grace periods that have completed.
-
-o	"g197/p197/c197" displays the grace-period state, with the
-	"g" number being the number of grace periods that have started
-	(mod 256), the "p" number being the number of grace periods
-	that the CPU has responded to (also mod 256), and the "c"
-	number being the number of grace periods that have completed
-	(once again mode 256).
-
-	Why have both "gp" and "g"?  Because the data flowing into
-	"gp" is only present in a CONFIG_RCU_TRACE kernel.
-
-o	"tasks" is a set of bits.  The first bit is "T" if there are
-	currently tasks that have recently blocked within an RCU
-	read-side critical section, the second bit is "N" if any of the
-	aforementioned tasks are blocking the current RCU grace period,
-	and the third bit is "E" if any of the aforementioned tasks are
-	blocking the current expedited grace period.  Each bit is "."
-	if the corresponding condition does not hold.
-
-o	"ttb" is a single bit.  It is "B" if any of the blocked tasks
-	need to be priority boosted and "." otherwise.
-
-o	"btg" indicates whether boosting has been carried out during
-	the current grace period, with "exp" indicating that boosting
-	is in progress for an expedited grace period, "no" indicating
-	that boosting has not yet started for a normal grace period,
-	"begun" indicating that boosting has bebug for a normal grace
-	period, and "done" indicating that boosting has completed for
-	a normal grace period.
-
-o	"ntb" is the total number of tasks subjected to RCU priority boosting
-	periods since boot.
-
-o	"neb" is the number of expedited grace periods that have had
-	to resort to RCU priority boosting since boot.
-
-o	"nnb" is the number of normal grace periods that have had
-	to resort to RCU priority boosting since boot.
-
-o	"j" is the low-order 16 bits of the jiffies counter in hexadecimal.
-
-o	"bt" is the low-order 16 bits of the value that the jiffies counter
-	will have at the next time that boosting is scheduled to begin.
-
-o	In the line beginning with "normal balk", the fields are as follows:
-
-	o	"nt" is the number of times that the system balked from
-		boosting because there were no blocked tasks to boost.
-		Note that the system will balk from boosting even if the
-		grace period is overdue when the currently running task
-		is looping within an RCU read-side critical section.
-		There is no point in boosting in this case, because
-		boosting a running task won't make it run any faster.
-
-	o	"gt" is the number of times that the system balked
-		from boosting because, although there were blocked tasks,
-		none of them were preventing the current grace period
-		from completing.
-
-	o	"bt" is the number of times that the system balked
-		from boosting because boosting was already in progress.
-
-	o	"b" is the number of times that the system balked from
-		boosting because boosting had already completed for
-		the grace period in question.
-
-	o	"ny" is the number of times that the system balked from
-		boosting because it was not yet time to start boosting
-		the grace period in question.
-
-	o	"nos" is the number of times that the system balked from
-		boosting for inexplicable ("not otherwise specified")
-		reasons.  This can actually happen due to races involving
-		increments of the jiffies counter.
-
-o	In the line beginning with "exp balk", the fields are as follows:
-
-	o	"bt" is the number of times that the system balked from
-		boosting because there were no blocked tasks to boost.
-
-	o	"nos" is the number of times that the system balked from
-		 boosting for inexplicable ("not otherwise specified")
-		 reasons.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/RCU/whatisRCU.txt linux-libre-3.11-rc7-gnu/Documentation/RCU/whatisRCU.txt
--- linux-libre-3.10-gnu/Documentation/RCU/whatisRCU.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/RCU/whatisRCU.txt	2013-08-25 20:43:22.000000000 -0400
@@ -842,9 +842,7 @@ SRCU:	Critical sections	Grace period		Ba
 
 	srcu_read_lock		synchronize_srcu	srcu_barrier
 	srcu_read_unlock	call_srcu
-	srcu_read_lock_raw	synchronize_srcu_expedited
-	srcu_read_unlock_raw
-	srcu_dereference
+	srcu_dereference	synchronize_srcu_expedited
 
 SRCU:	Initialization/cleanup
 	init_srcu_struct
@@ -865,38 +863,32 @@ list can be helpful:
 
 a.	Will readers need to block?  If so, you need SRCU.
 
-b.	Is it necessary to start a read-side critical section in a
-	hardirq handler or exception handler, and then to complete
-	this read-side critical section in the task that was
-	interrupted?  If so, you need SRCU's srcu_read_lock_raw() and
-	srcu_read_unlock_raw() primitives.
-
-c.	What about the -rt patchset?  If readers would need to block
+b.	What about the -rt patchset?  If readers would need to block
 	in an non-rt kernel, you need SRCU.  If readers would block
 	in a -rt kernel, but not in a non-rt kernel, SRCU is not
 	necessary.
 
-d.	Do you need to treat NMI handlers, hardirq handlers,
+c.	Do you need to treat NMI handlers, hardirq handlers,
 	and code segments with preemption disabled (whether
 	via preempt_disable(), local_irq_save(), local_bh_disable(),
 	or some other mechanism) as if they were explicit RCU readers?
 	If so, RCU-sched is the only choice that will work for you.
 
-e.	Do you need RCU grace periods to complete even in the face
+d.	Do you need RCU grace periods to complete even in the face
 	of softirq monopolization of one or more of the CPUs?  For
 	example, is your code subject to network-based denial-of-service
 	attacks?  If so, you need RCU-bh.
 
-f.	Is your workload too update-intensive for normal use of
+e.	Is your workload too update-intensive for normal use of
 	RCU, but inappropriate for other synchronization mechanisms?
 	If so, consider SLAB_DESTROY_BY_RCU.  But please be careful!
 
-g.	Do you need read-side critical sections that are respected
+f.	Do you need read-side critical sections that are respected
 	even though they are in the middle of the idle loop, during
 	user-mode execution, or on an offlined CPU?  If so, SRCU is the
 	only choice that will work for you.
 
-h.	Otherwise, use RCU.
+g.	Otherwise, use RCU.
 
 Of course, this all assumes that you have determined that RCU is in fact
 the right tool for your job.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/rtc.txt linux-libre-3.11-rc7-gnu/Documentation/rtc.txt
--- linux-libre-3.10-gnu/Documentation/rtc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/rtc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -153,9 +153,10 @@ since_epoch:	 The number of seconds sinc
 time:		 RTC-provided time
 wakealarm:	 The time at which the clock will generate a system wakeup
 		 event. This is a one shot wakeup event, so must be reset
-		 after wake if a daily wakeup is required. Format is either
-		 seconds since the epoch or, if there's a leading +, seconds
-		 in the future.
+		 after wake if a daily wakeup is required. Format is seconds since
+		 the epoch by default, or if there's a leading +, seconds in the
+		 future, or if there is a leading +=, seconds ahead of the current
+		 alarm.
 
 IOCTL INTERFACE
 ---------------
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/rt-mutex-design.txt linux-libre-3.11-rc7-gnu/Documentation/rt-mutex-design.txt
--- linux-libre-3.10-gnu/Documentation/rt-mutex-design.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/rt-mutex-design.txt	2013-08-25 20:43:22.000000000 -0400
@@ -384,7 +384,7 @@ priority back.
 __rt_mutex_adjust_prio examines the result of rt_mutex_getprio, and if the
 result does not equal the task's current priority, then rt_mutex_setprio
 is called to adjust the priority of the task to the new priority.
-Note that rt_mutex_setprio is defined in kernel/sched.c to implement the
+Note that rt_mutex_setprio is defined in kernel/sched/core.c to implement the
 actual change in priority.
 
 It is interesting to note that __rt_mutex_adjust_prio can either increase
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/scheduler/sched-domains.txt linux-libre-3.11-rc7-gnu/Documentation/scheduler/sched-domains.txt
--- linux-libre-3.10-gnu/Documentation/scheduler/sched-domains.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/scheduler/sched-domains.txt	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@ is treated as one entity. The load of a
 load of each of its member CPUs, and only when the load of a group becomes
 out of balance are tasks moved between groups.
 
-In kernel/sched.c, trigger_load_balance() is run periodically on each CPU
+In kernel/sched/core.c, trigger_load_balance() is run periodically on each CPU
 through scheduler_tick(). It raises a softirq after the next regularly scheduled
 rebalancing event for the current runqueue has arrived. The actual load
 balancing workhorse, run_rebalance_domains()->rebalance_domains(), is then run
@@ -62,7 +62,7 @@ struct sched_domain fields, SD_FLAG_*, S
 the specifics and what to tune.
 
 Architectures may retain the regular override the default SD_*_INIT flags
-while using the generic domain builder in kernel/sched.c if they wish to
+while using the generic domain builder in kernel/sched/core.c if they wish to
 retain the traditional SMT->SMP->NUMA topology (or some subset of that). This
 can be done by #define'ing ARCH_HASH_SCHED_TUNE.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/scsi/ChangeLog.megaraid_sas linux-libre-3.11-rc7-gnu/Documentation/scsi/ChangeLog.megaraid_sas
--- linux-libre-3.10-gnu/Documentation/scsi/ChangeLog.megaraid_sas	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/scsi/ChangeLog.megaraid_sas	2013-08-25 20:43:22.000000000 -0400
@@ -1,3 +1,25 @@
+Release Date    : Wed. May 15, 2013 17:00:00 PST 2013 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Adam Radford
+			Kashyap Desai
+			Sumit Saxena
+Current Version : 06.600.18.00-rc1
+Old Version     : 06.506.00.00-rc1
+    1. Return DID_ERROR for scsi io, when controller is in critical h/w error.
+    2. Fix the interrupt mask for Gen2 controller.
+    3. Update balance count in driver to be in sync of firmware.
+    4. Free event detail memory without device ID check.
+    5. Set IO request timeout value provided by OS timeout for Tape devices.
+    6. Add support for MegaRAID Fury (device ID-0x005f) 12Gb/s controllers.
+    7. Add support to display Customer branding details in syslog.
+    8. Set IoFlags to enable Fast Path for JBODs for Invader/Fury(12 Gb/s)
+    controllers.
+    9. Add support for Extended MSI-x vectors for Invader and Fury(12Gb/s
+    HBA).
+    10.Add support for Uneven Span PRL11.
+    11.Add support to differentiate between iMR and MR Firmware.
+    12.Version and Changelog update.
+-------------------------------------------------------------------------------
 Release Date    : Sat. Feb 9, 2013 17:00:00 PST 2013 -
 			(emaild-id:megaraidlinux@lsi.com)
 			Adam Radford
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/serial/00-INDEX linux-libre-3.11-rc7-gnu/Documentation/serial/00-INDEX
--- linux-libre-3.10-gnu/Documentation/serial/00-INDEX	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/serial/00-INDEX	2013-08-25 20:43:22.000000000 -0400
@@ -16,8 +16,6 @@ serial-rs485.txt
 	- info about RS485 structures and support in the kernel.
 specialix.txt
 	- info on hardware/driver for specialix IO8+ multiport serial card.
-stallion.txt
-	- info on using the Stallion multiport serial driver.
 sx.txt
 	- info on the Specialix SX/SI multiport serial driver.
 tty.txt
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/serial/stallion.txt linux-libre-3.11-rc7-gnu/Documentation/serial/stallion.txt
--- linux-libre-3.10-gnu/Documentation/serial/stallion.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/serial/stallion.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,392 +0,0 @@
-* NOTE - This is an unmaintained driver.  Lantronix, which bought Stallion
-technologies, is not active in driver maintenance, and they have no information
-on when or if they will have a 2.6 driver.
-
-James Nelson <james4765@gmail.com> - 12-12-2004
-
-Stallion Multiport Serial Driver Readme
----------------------------------------
-
-Copyright (C) 1994-1999,  Stallion Technologies.
-
-Version:   5.5.1
-Date:      28MAR99
-
-
-
-1. INTRODUCTION
-
-There are two drivers that work with the different families of Stallion
-multiport serial boards. One is for the Stallion smart boards - that is
-EasyIO, EasyConnection 8/32 and EasyConnection 8/64-PCI, the other for
-the true Stallion intelligent multiport boards - EasyConnection 8/64
-(ISA, EISA), EasyConnection/RA-PCI, ONboard and Brumby.
-
-If you are using any of the Stallion intelligent multiport boards (Brumby,
-ONboard, EasyConnection 8/64 (ISA, EISA), EasyConnection/RA-PCI) with
-Linux you will need to get the driver utility package.  This contains a
-firmware loader and the firmware images necessary to make the devices operate.
-
-The Stallion Technologies ftp site, ftp.stallion.com, will always have
-the latest version of the driver utility package.
-
-ftp://ftp.stallion.com/drivers/ata5/Linux/ata-linux-550.tar.gz
-
-As of the printing of this document the latest version of the driver
-utility package is 5.5.0. If a later version is now available then you
-should use the latest version.
-
-If you are using the EasyIO, EasyConnection 8/32 or EasyConnection 8/64-PCI
-boards then you don't need this package, although it does have a serial stats
-display program.
-
-If you require DIP switch settings, or EISA configuration files, or any
-other information related to Stallion boards then have a look at Stallion's
-web pages at http://www.stallion.com.
-
-
-
-2. INSTALLATION
-
-The drivers can be used as loadable modules or compiled into the kernel.
-You can choose which when doing a "config" on the kernel.
-
-All ISA, and EISA boards that you want to use need to be configured into
-the driver(s). All PCI boards will be automatically detected when you load
-the driver - so they do not need to be entered into the driver(s)
-configuration structure. Note that kernel PCI support is required to use PCI
-boards.
-
-There are two methods of configuring ISA and EISA boards into the drivers.
-If using the driver as a loadable module then the simplest method is to pass
-the driver configuration as module arguments. The other method is to modify
-the driver source to add configuration lines for each board in use.
-
-If you have pre-built Stallion driver modules then the module argument
-configuration method should be used. A lot of Linux distributions come with
-pre-built driver modules in /lib/modules/X.Y.Z/misc for the kernel in use.
-That makes things pretty simple to get going.
-
-
-2.1 MODULE DRIVER CONFIGURATION:
-
-The simplest configuration for modules is to use the module load arguments
-to configure any ISA or EISA boards. PCI boards are automatically
-detected, so do not need any additional configuration at all.
-
-If using EasyIO, EasyConnection 8/32 ISA, or EasyConnection 8/63-PCI
-boards then use the "stallion" driver module, Otherwise if you are using
-an EasyConnection 8/64 ISA or EISA, EasyConnection/RA-PCI, ONboard,
-Brumby or original Stallion board then use the "istallion" driver module.
-
-Typically to load up the smart board driver use:
-
-    modprobe stallion
-
-This will load the EasyIO and EasyConnection 8/32 driver. It will output a
-message to say that it loaded and print the driver version number. It will
-also print out whether it found the configured boards or not. These messages
-may not appear on the console, but typically are always logged to
-/var/adm/messages or /var/log/syslog files - depending on how the klogd and
-syslogd daemons are setup on your system.
-
-To load the intelligent board driver use:
-
-    modprobe istallion
-
-It will output similar messages to the smart board driver.
-
-If not using an auto-detectable board type (that is a PCI board) then you
-will also need to supply command line arguments to the modprobe command
-when loading the driver. The general form of the configuration argument is
-
-    board?=<name>[,<ioaddr>[,<addr>][,<irq>]]
-
-where:
-
-    board?  -- specifies the arbitrary board number of this board,
-               can be in the range 0 to 3.
-
-    name    -- textual name of this board. The board name is the common
-               board name, or any "shortened" version of that. The board
-               type number may also be used here.
-
-    ioaddr  -- specifies the I/O address of this board. This argument is
-               optional, but should generally be specified.
-
-    addr    -- optional second address argument. Some board types require
-               a second I/O address, some require a memory address. The
-               exact meaning of this argument depends on the board type.
-
-    irq     -- optional IRQ line used by this board.
-
-Up to 4 board configuration arguments can be specified on the load line.
-Here is some examples:
-
-    modprobe stallion board0=easyio,0x2a0,5
-
-This configures an EasyIO board as board 0 at I/O address 0x2a0 and IRQ 5.
-
-    modprobe istallion board3=ec8/64,0x2c0,0xcc000
-
-This configures an EasyConnection 8/64 ISA as board 3 at I/O address 0x2c0 at
-memory address 0xcc000.
-
-    modprobe stallion board1=ec8/32-at,0x2a0,0x280,10
-
-This configures an EasyConnection 8/32 ISA board at primary I/O address 0x2a0,
-secondary address 0x280 and IRQ 10.
-
-You will probably want to enter this module load and configuration information
-into your system startup scripts so that the drivers are loaded and configured
-on each system boot. Typically configuration files are put in the
-/etc/modprobe.d/ directory.
-
-
-2.2 STATIC DRIVER CONFIGURATION:
-
-For static driver configuration you need to modify the driver source code.
-Entering ISA and EISA boards into the driver(s) configuration structure
-involves editing the driver(s) source file. It's pretty easy if you follow
-the instructions below. Both drivers can support up to 4 boards. The smart
-card driver (the stallion.c driver) supports any combination of EasyIO and
-EasyConnection 8/32 boards (up to a total of 4). The intelligent driver
-supports any combination of ONboards, Brumbys, Stallions and EasyConnection
-8/64 (ISA and EISA) boards (up to a total of 4).
-
-To set up the driver(s) for the boards that you want to use you need to
-edit the appropriate driver file and add configuration entries.
-
-If using EasyIO or EasyConnection 8/32 ISA boards,
-   In drivers/char/stallion.c:
-      - find the definition of the stl_brdconf array (of structures)
-        near the top of the file
-      - modify this to match the boards you are going to install
-	(the comments before this structure should help)
-      - save and exit
-
-If using ONboard, Brumby, Stallion or EasyConnection 8/64 (ISA or EISA)
-boards,
-   In drivers/char/istallion.c:
-      - find the definition of the stli_brdconf array (of structures)
-        near the top of the file
-      - modify this to match the boards you are going to install
-	(the comments before this structure should help)
-      - save and exit
-
-Once you have set up the board configurations then you are ready to build
-the kernel or modules.
-
-When the new kernel is booted, or the loadable module loaded then the
-driver will emit some kernel trace messages about whether the configured
-boards were detected or not. Depending on how your system logger is set
-up these may come out on the console, or just be logged to
-/var/adm/messages or /var/log/syslog. You should check the messages to
-confirm that all is well.
-
-
-2.3 SHARING INTERRUPTS
-
-It is possible to share interrupts between multiple EasyIO and
-EasyConnection 8/32 boards in an EISA system. To do this you must be using
-static driver configuration, modifying the driver source code to add driver
-configuration. Then a couple of extra things are required:
-
-1. When entering the board resources into the stallion.c file you need to
-   mark the boards as using level triggered interrupts. Do this by replacing
-   the "0" entry at field position 6 (the last field) in the board
-   configuration structure with a "1". (This is the structure that defines
-   the board type, I/O locations, etc. for each board). All boards that are
-   sharing an interrupt must be set this way, and each board should have the
-   same interrupt number specified here as well. Now build the module or
-   kernel as you would normally.
-
-2. When physically installing the boards into the system you must enter
-   the system EISA configuration utility. You will need to install the EISA
-   configuration files for *all* the EasyIO and EasyConnection 8/32 boards
-   that are sharing interrupts. The Stallion EasyIO and EasyConnection 8/32
-   EISA configuration files required are supplied by Stallion Technologies
-   on the EASY Utilities floppy diskette (usually supplied in the box with
-   the board when purchased. If not, you can pick it up from Stallion's FTP
-   site, ftp.stallion.com). You will need to edit the board resources to
-   choose level triggered interrupts, and make sure to set each board's
-   interrupt to the same IRQ number.
-
-You must complete both the above steps for this to work. When you reboot
-or load the driver your EasyIO and EasyConnection 8/32 boards will be
-sharing interrupts.
-
-
-2.4 USING HIGH SHARED MEMORY
-
-The EasyConnection 8/64-EI, ONboard and Stallion boards are capable of
-using shared memory addresses above the usual 640K - 1Mb range. The ONboard
-ISA and the Stallion boards can be programmed to use memory addresses up to
-16Mb (the ISA bus addressing limit), and the EasyConnection 8/64-EI and
-ONboard/E can be programmed for memory addresses up to 4Gb (the EISA bus
-addressing limit).
-
-The higher than 1Mb memory addresses are fully supported by this driver.
-Just enter the address as you normally would for a lower than 1Mb address
-(in the driver's board configuration structure).
-
-
-
-2.5 TROUBLE SHOOTING
-
-If a board is not found by the driver but is actually in the system then the
-most likely problem is that the I/O address is wrong. Change the module load
-argument for the loadable module form. Or change it in the driver stallion.c
-or istallion.c configuration structure and rebuild the kernel or modules, or
-change it on the board.
-
-On EasyIO and EasyConnection 8/32 boards the IRQ is software programmable, so
-if there is a conflict you may need to change the IRQ used for a board. There
-are no interrupts to worry about for ONboard, Brumby or EasyConnection 8/64
-(ISA and EISA) boards. The memory region on EasyConnection 8/64 and
-ONboard boards is software programmable, but not on the Brumby boards.
-
-
-
-3. USING THE DRIVERS
-
-3.1 INTELLIGENT DRIVER OPERATION
-
-The intelligent boards also need to have their "firmware" code downloaded
-to them. This is done via a user level application supplied in the driver
-utility package called "stlload". Compile this program wherever you dropped
-the package files, by typing "make". In its simplest form you can then type
-
-    ./stlload -i cdk.sys
-
-in this directory and that will download board 0 (assuming board 0 is an
-EasyConnection 8/64 or EasyConnection/RA board). To download to an
-ONboard, Brumby or Stallion do:
-
-    ./stlload -i 2681.sys
-
-Normally you would want all boards to be downloaded as part of the standard
-system startup. To achieve this, add one of the lines above into the
-/etc/rc.d/rc.S or /etc/rc.d/rc.serial file. To download each board just add
-the "-b <brd-number>" option to the line. You will need to download code for
-every board. You should probably move the stlload program into a system
-directory, such as /usr/sbin. Also, the default location of the cdk.sys image
-file in the stlload down-loader is /usr/lib/stallion. Create that directory
-and put the cdk.sys and 2681.sys files in it. (It's a convenient place to put
-them anyway). As an example your /etc/rc.d/rc.S file might have the
-following lines added to it (if you had 3 boards):
-
-    /usr/sbin/stlload -b 0 -i /usr/lib/stallion/cdk.sys
-    /usr/sbin/stlload -b 1 -i /usr/lib/stallion/2681.sys
-    /usr/sbin/stlload -b 2 -i /usr/lib/stallion/2681.sys
-
-The image files cdk.sys and 2681.sys are specific to the board types. The
-cdk.sys will only function correctly on an EasyConnection 8/64 board. Similarly
-the 2681.sys image fill only operate on ONboard, Brumby and Stallion boards.
-If you load the wrong image file into a board it will fail to start up, and
-of course the ports will not be operational!
-
-If you are using the modularized version of the driver you might want to put
-the modprobe calls in the startup script as well (before the download lines
-obviously).
-
-
-3.2 USING THE SERIAL PORTS
-
-Once the driver is installed you will need to setup some device nodes to
-access the serial ports. The simplest method is to use the /dev/MAKEDEV program.
-It will automatically create device entries for Stallion boards. This will
-create the normal serial port devices as /dev/ttyE# where# is the port number
-starting from 0. A bank of 64 minor device numbers is allocated to each board,
-so the first port on the second board is port 64,etc. A set of callout type
-devices may also be created. They are created as the devices /dev/cue# where #
-is the same as for the ttyE devices.
-
-For the most part the Stallion driver tries to emulate the standard PC system
-COM ports and the standard Linux serial driver. The idea is that you should
-be able to use Stallion board ports and COM ports interchangeably without
-modifying anything but the device name. Anything that doesn't work like that
-should be considered a bug in this driver!
-
-If you look at the driver code you will notice that it is fairly closely
-based on the Linux serial driver (linux/drivers/char/serial.c). This is
-intentional, obviously this is the easiest way to emulate its behavior!
-
-Since this driver tries to emulate the standard serial ports as much as
-possible, most system utilities should work as they do for the standard
-COM ports. Most importantly "stty" works as expected and "setserial" can
-also be used (excepting the ability to auto-configure the I/O and IRQ
-addresses of boards). Higher baud rates are supported in the usual fashion
-through setserial or using the CBAUDEX extensions. Note that the EasyIO and
-EasyConnection (all types) support at least 57600 and 115200 baud. The newer
-EasyConnection XP modules and new EasyIO boards support 230400 and 460800
-baud as well. The older boards including ONboard and Brumby support a
-maximum baud rate of 38400.
-
-If you are unfamiliar with how to use serial ports, then get the Serial-HOWTO
-by Greg Hankins. It will explain everything you need to know!
-
-
-
-4. NOTES
-
-You can use both drivers at once if you have a mix of board types installed
-in a system. However to do this you will need to change the major numbers
-used by one of the drivers. Currently both drivers use major numbers 24, 25
-and 28 for their devices. Change one driver to use some other major numbers,
-and then modify the mkdevnods script to make device nodes based on those new
-major numbers. For example, you could change the istallion.c driver to use
-major numbers 60, 61 and 62. You will also need to create device nodes with
-different names for the ports, for example ttyF# and cuf#.
-
-The original Stallion board is no longer supported by Stallion Technologies.
-Although it is known to work with the istallion driver.
-
-Finding a free physical memory address range can be a problem. The older
-boards like the Stallion and ONboard need large areas (64K or even 128K), so
-they can be very difficult to get into a system. If you have 16 Mb of RAM
-then you have no choice but to put them somewhere in the 640K -> 1Mb range.
-ONboards require 64K, so typically 0xd0000 is good, or 0xe0000 on some
-systems. If you have an original Stallion board, "V4.0" or Rev.O, then you
-need a 64K memory address space, so again 0xd0000 and 0xe0000 are good.
-Older Stallion boards are a much bigger problem. They need 128K of address
-space and must be on a 128K boundary. If you don't have a VGA card then
-0xc0000 might be usable - there is really no other place you can put them
-below 1Mb.
-
-Both the ONboard and old Stallion boards can use higher memory addresses as
-well, but you must have less than 16Mb of RAM to be able to use them. Usual
-high memory addresses used include 0xec0000 and 0xf00000.
-
-The Brumby boards only require 16Kb of address space, so you can usually
-squeeze them in somewhere. Common addresses are 0xc8000, 0xcc000, or in
-the 0xd0000 range. EasyConnection 8/64 boards are even better, they only
-require 4Kb of address space, again usually 0xc8000, 0xcc000 or 0xd0000
-are good.
-
-If you are using an EasyConnection 8/64-EI or ONboard/E then usually the
-0xd0000 or 0xe0000 ranges are the best options below 1Mb. If neither of
-them can be used then the high memory support to use the really high address
-ranges is the best option. Typically the 2Gb range is convenient for them,
-and gets them well out of the way.
-
-The ports of the EasyIO-8M board do not have DCD or DTR signals. So these
-ports cannot be used as real modem devices. Generally, when using these
-ports you should only use the cueX devices.
-
-The driver utility package contains a couple of very useful programs. One 
-is a serial port statistics collection and display program - very handy
-for solving serial port problems. The other is an extended option setting
-program that works with the intelligent boards.
-
-
-
-5. DISCLAIMER
-
-The information contained in this document is believed to be accurate and
-reliable. However, no responsibility is assumed by Stallion Technologies
-Pty. Ltd. for its use, nor any infringements of patents or other rights
-of third parties resulting from its use. Stallion Technologies reserves
-the right to modify the design of its products and will endeavour to change
-the information in manuals and accompanying documentation accordingly.
-
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/sound/alsa/HD-Audio-Models.txt linux-libre-3.11-rc7-gnu/Documentation/sound/alsa/HD-Audio-Models.txt
--- linux-libre-3.10-gnu/Documentation/sound/alsa/HD-Audio-Models.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/sound/alsa/HD-Audio-Models.txt	2013-08-25 20:43:22.000000000 -0400
@@ -21,41 +21,41 @@ ALC267/268
 ==========
   inv-dmic	Inverted internal mic workaround
 
-ALC269/270/275/276/280/282
+ALC269/270/275/276/28x/29x
 ======
-  laptop-amic	Laptops with analog-mic input
-  laptop-dmic	Laptops with digital-mic input
-  alc269-dmic	Enable ALC269(VA) digital mic workaround
-  alc271-dmic	Enable ALC271X digital mic workaround
-  inv-dmic	Inverted internal mic workaround
-  lenovo-dock   Enables docking station I/O for some Lenovos
+  laptop-amic		Laptops with analog-mic input
+  laptop-dmic		Laptops with digital-mic input
+  alc269-dmic		Enable ALC269(VA) digital mic workaround
+  alc271-dmic		Enable ALC271X digital mic workaround
+  inv-dmic		Inverted internal mic workaround
+  lenovo-dock   	Enables docking station I/O for some Lenovos
   dell-headset-multi	Headset jack, which can also be used as mic-in
   dell-headset-dock	Headset jack (without mic-in), and also dock I/O
 
-ALC662/663/272
+ALC66x/67x/892
 ==============
-  mario		Chromebook mario model fixup
-  asus-mode1	ASUS
-  asus-mode2	ASUS
-  asus-mode3	ASUS
-  asus-mode4	ASUS
-  asus-mode5	ASUS
-  asus-mode6	ASUS
-  asus-mode7	ASUS
-  asus-mode8	ASUS
-  inv-dmic	Inverted internal mic workaround
+  mario			Chromebook mario model fixup
+  asus-mode1		ASUS
+  asus-mode2		ASUS
+  asus-mode3		ASUS
+  asus-mode4		ASUS
+  asus-mode5		ASUS
+  asus-mode6		ASUS
+  asus-mode7		ASUS
+  asus-mode8		ASUS
+  inv-dmic		Inverted internal mic workaround
   dell-headset-multi	Headset jack, which can also be used as mic-in
 
 ALC680
 ======
   N/A
 
-ALC882/883/885/888/889
+ALC88x/898/1150
 ======================
   acer-aspire-4930g	Acer Aspire 4930G/5930G/6530G/6930G/7730G
   acer-aspire-8930g	Acer Aspire 8330G/6935G
   acer-aspire		Acer Aspire others
-  inv-dmic	Inverted internal mic workaround
+  inv-dmic		Inverted internal mic workaround
   no-primary-hp		VAIO Z/VGC-LN51JGB workaround (for fixed speaker DAC)
 
 ALC861/660
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/spinlocks.txt linux-libre-3.11-rc7-gnu/Documentation/spinlocks.txt
--- linux-libre-3.10-gnu/Documentation/spinlocks.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/spinlocks.txt	2013-08-25 20:43:22.000000000 -0400
@@ -137,7 +137,7 @@ don't block on each other (and thus ther
 But when you do the write-lock, you have to use the irq-safe version. 
 
 For an example of being clever with rw-locks, see the "waitqueue_lock" 
-handling in kernel/sched.c - nothing ever _changes_ a wait-queue from
+handling in kernel/sched/core.c - nothing ever _changes_ a wait-queue from
 within an interrupt, they only read the queue in order to know whom to
 wake up. So read-locks are safe (which is good: they are very common
 indeed), while write-locks need to protect themselves against interrupts.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/SubmitChecklist linux-libre-3.11-rc7-gnu/Documentation/SubmitChecklist
--- linux-libre-3.10-gnu/Documentation/SubmitChecklist	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/SubmitChecklist	2013-08-25 20:43:22.000000000 -0400
@@ -105,5 +105,5 @@ kernel patches.
     same time, just various/random combinations of them]:
 
     CONFIG_SMP, CONFIG_SYSFS, CONFIG_PROC_FS, CONFIG_INPUT, CONFIG_PCI,
-    CONFIG_BLOCK, CONFIG_PM, CONFIG_HOTPLUG, CONFIG_MAGIC_SYSRQ,
+    CONFIG_BLOCK, CONFIG_PM, CONFIG_MAGIC_SYSRQ,
     CONFIG_NET, CONFIG_INET=n (but latter with CONFIG_NET=y)
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/sysctl/kernel.txt linux-libre-3.11-rc7-gnu/Documentation/sysctl/kernel.txt
--- linux-libre-3.10-gnu/Documentation/sysctl/kernel.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/sysctl/kernel.txt	2013-08-25 20:43:22.000000000 -0400
@@ -70,12 +70,12 @@ show up in /proc/sys/kernel:
 - shmall
 - shmmax                      [ sysv ipc ]
 - shmmni
-- softlockup_thresh
 - stop-a                      [ SPARC only ]
 - sysrq                       ==> Documentation/sysrq.txt
 - tainted
 - threads-max
 - unknown_nmi_panic
+- watchdog_thresh
 - version
 
 ==============================================================
@@ -427,6 +427,32 @@ This file shows up if CONFIG_DEBUG_STACK
 
 ==============================================================
 
+perf_cpu_time_max_percent:
+
+Hints to the kernel how much CPU time it should be allowed to
+use to handle perf sampling events.  If the perf subsystem
+is informed that its samples are exceeding this limit, it
+will drop its sampling frequency to attempt to reduce its CPU
+usage.
+
+Some perf sampling happens in NMIs.  If these samples
+unexpectedly take too long to execute, the NMIs can become
+stacked up next to each other so much that nothing else is
+allowed to execute.
+
+0: disable the mechanism.  Do not monitor or correct perf's
+   sampling rate no matter how CPU time it takes.
+
+1-100: attempt to throttle perf's sample rate to this
+   percentage of CPU.  Note: the kernel calculates an
+   "expected" length of each sample event.  100 here means
+   100% of that expected length.  Even if this is set to
+   100, you may still see sample throttling if this
+   length is exceeded.  Set to 0 if you truly do not care
+   how much CPU is consumed.
+
+==============================================================
+
 
 pid_max:
 
@@ -604,15 +630,6 @@ without users and with a dead originativ
 
 ==============================================================
 
-softlockup_thresh:
-
-This value can be used to lower the softlockup tolerance threshold.  The
-default threshold is 60 seconds.  If a cpu is locked up for 60 seconds,
-the kernel complains.  Valid values are 1-60 seconds.  Setting this
-tunable to zero will disable the softlockup detection altogether.
-
-==============================================================
-
 tainted:
 
 Non-zero if the kernel has been tainted.  Numeric values, which
@@ -648,3 +665,16 @@ that time, kernel debugging information
 
 NMI switch that most IA32 servers have fires unknown NMI up, for
 example.  If a system hangs up, try pressing the NMI switch.
+
+==============================================================
+
+watchdog_thresh:
+
+This value can be used to control the frequency of hrtimer and NMI
+events and the soft and hard lockup thresholds. The default threshold
+is 10 seconds.
+
+The softlockup threshold is (2 * watchdog_thresh). Setting this
+tunable to zero will disable lockup detection altogether.
+
+==============================================================
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/sysctl/net.txt linux-libre-3.11-rc7-gnu/Documentation/sysctl/net.txt
--- linux-libre-3.10-gnu/Documentation/sysctl/net.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/sysctl/net.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-Documentation for /proc/sys/net/*	kernel version 2.4.0-test11-pre4
+Documentation for /proc/sys/net/*
 	(c) 1999		Terrehon Bowden <terrehon@pacbell.net>
 				Bodo Bauer <bb@ricochet.net>
 	(c) 2000		Jorge Nerin <comandante@zaralinux.com>
@@ -9,10 +9,10 @@ For general info and legal blurb, please
 ==============================================================
 
 This file contains the documentation for the sysctl files in
-/proc/sys/net and is valid for Linux kernel version 2.4.0-test11-pre4.
+/proc/sys/net
 
 The interface  to  the  networking  parts  of  the  kernel  is  located  in
-/proc/sys/net. The following table shows all possible subdirectories.You may
+/proc/sys/net. The following table shows all possible subdirectories.  You may
 see only some of them, depending on your kernel's configuration.
 
 
@@ -26,7 +26,7 @@ Table : Subdirectories in /proc/sys/net
  ipv4      IP version 4        x25        X.25 protocol
  ipx       IPX                 token-ring IBM token ring
  bridge    Bridging            decnet     DEC net
- ipv6      IP version 6
+ ipv6      IP version 6        tipc       TIPC
 ..............................................................................
 
 1. /proc/sys/net/core - Network core options
@@ -50,6 +50,30 @@ The maximum number of packets that kerne
 it's a Per-CPU variable.
 Default: 64
 
+busy_read
+----------------
+Low latency busy poll timeout for socket reads. (needs CONFIG_NET_RX_BUSY_POLL)
+Approximate time in us to busy loop waiting for packets on the device queue.
+This sets the default value of the SO_BUSY_POLL socket option.
+Can be set or overridden per socket by setting socket option SO_BUSY_POLL,
+which is the preferred method of enabling. If you need to enable the feature
+globally via sysctl, a value of 50 is recommended.
+Will increase power usage.
+Default: 0 (off)
+
+busy_poll
+----------------
+Low latency busy poll timeout for poll and select. (needs CONFIG_NET_RX_BUSY_POLL)
+Approximate time in us to busy loop waiting for events.
+Recommended value depends on the number of sockets you poll on.
+For several sockets 50, for several hundreds 100.
+For more than that you probably want to use epoll.
+Note that only sockets with SO_BUSY_POLL set will be busy polled,
+so you want to either selectively set SO_BUSY_POLL on those sockets or set
+sysctl.net.busy_read globally.
+Will increase power usage.
+Default: 0 (off)
+
 rmem_default
 ------------
 
@@ -93,8 +117,7 @@ netdev_budget
 
 Maximum number of packets taken from all interfaces in one polling cycle (NAPI
 poll). In one polling cycle interfaces which are registered to polling are
-probed in a round-robin manner. The limit of packets in one such probe can be
-set per-device via sysfs class/net/<device>/weight .
+probed in a round-robin manner.
 
 netdev_max_backlog
 ------------------
@@ -201,3 +224,18 @@ IPX.
 The /proc/net/ipx_route  table  holds  a list of IPX routes. For each route it
 gives the  destination  network, the router node (or Directly) and the network
 address of the router (or Connected) for internal networks.
+
+6. TIPC
+-------------------------------------------------------
+
+The TIPC protocol now has a tunable for the receive memory, similar to the
+tcp_rmem - i.e. a vector of 3 INTEGERs: (min, default, max)
+
+    # cat /proc/sys/net/tipc/tipc_rmem
+    4252725 34021800        68043600
+    #
+
+The max value is set to CONN_OVERLOAD_LIMIT, and the default and min values
+are scaled (shifted) versions of that same value.  Note that the min value
+is not at this point in time used in any meaningful way, but the triplet is
+preserved in order to be consistent with things like tcp_rmem.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/sysctl/vm.txt linux-libre-3.11-rc7-gnu/Documentation/sysctl/vm.txt
--- linux-libre-3.10-gnu/Documentation/sysctl/vm.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/sysctl/vm.txt	2013-08-25 20:43:22.000000000 -0400
@@ -510,7 +510,7 @@ Specify "[Dd]efault" to request automati
 will select "node" order in following case.
 (1) if the DMA zone does not exist or
 (2) if the DMA zone comprises greater than 50% of the available memory or
-(3) if any node's DMA zone comprises greater than 60% of its local memory and
+(3) if any node's DMA zone comprises greater than 70% of its local memory and
     the amount of local memory is big enough.
 
 Otherwise, "zone" order will be selected. Default order is recommended unless
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/thermal/exynos_thermal_emulation linux-libre-3.11-rc7-gnu/Documentation/thermal/exynos_thermal_emulation
--- linux-libre-3.10-gnu/Documentation/thermal/exynos_thermal_emulation	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/thermal/exynos_thermal_emulation	2013-08-25 20:43:22.000000000 -0400
@@ -20,7 +20,7 @@ When it's enabled, sysfs node will be cr
 The sysfs node, 'emul_node', will contain value 0 for the initial state. When you input any
 temperature you want to update to sysfs node, it automatically enable emulation mode and
 current temperature will be changed into it.
-(Exynos also supports user changable delay time which would be used to delay of
+(Exynos also supports user changeable delay time which would be used to delay of
  changing temperature. However, this node only uses same delay of real sensing time, 938us.)
 
 Exynos emulation mode requires synchronous of value changing and enabling. It means when you
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/thermal/x86_pkg_temperature_thermal linux-libre-3.11-rc7-gnu/Documentation/thermal/x86_pkg_temperature_thermal
--- linux-libre-3.10-gnu/Documentation/thermal/x86_pkg_temperature_thermal	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/thermal/x86_pkg_temperature_thermal	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,47 @@
+Kernel driver: x86_pkg_temp_thermal
+===================
+
+Supported chips:
+* x86: with package level thermal management
+(Verify using: CPUID.06H:EAX[bit 6] =1)
+
+Authors: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+Reference
+---
+Intel® 64 and IA-32 Architectures Software Developer’s Manual (Jan, 2013):
+Chapter 14.6: PACKAGE LEVEL THERMAL MANAGEMENT
+
+Description
+---------
+
+This driver register CPU digital temperature package level sensor as a thermal
+zone with maximum two user mode configurable trip points. Number of trip points
+depends on the capability of the package. Once the trip point is violated,
+user mode can receive notification via thermal notification mechanism and can
+take any action to control temperature.
+
+
+Threshold management
+--------------------
+Each package will register as a thermal zone under /sys/class/thermal.
+Example:
+/sys/class/thermal/thermal_zone1
+
+This contains two trip points:
+- trip_point_0_temp
+- trip_point_1_temp
+
+User can set any temperature between 0 to TJ-Max temperature. Temperature units
+are in milli-degree Celsius. Refer to "Documentation/thermal/sysfs-api.txt" for
+thermal sys-fs details.
+
+Any value other than 0 in these trip points, can trigger thermal notifications.
+Setting 0, stops sending thermal notifications.
+
+Thermal notifications: To get kobject-uevent notifications, set the thermal zone
+policy to "user_space". For example: echo -n "user_space" > policy
+
+
+
+
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/timers/NO_HZ.txt linux-libre-3.11-rc7-gnu/Documentation/timers/NO_HZ.txt
--- linux-libre-3.10-gnu/Documentation/timers/NO_HZ.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/timers/NO_HZ.txt	2013-08-25 20:43:22.000000000 -0400
@@ -7,21 +7,59 @@ efficiency and reducing OS jitter.  Redu
 some types of computationally intensive high-performance computing (HPC)
 applications and for real-time applications.
 
-There are two main contexts in which the number of scheduling-clock
-interrupts can be reduced compared to the old-school approach of sending
-a scheduling-clock interrupt to all CPUs every jiffy whether they need
-it or not (CONFIG_HZ_PERIODIC=y or CONFIG_NO_HZ=n for older kernels):
+There are three main ways of managing scheduling-clock interrupts
+(also known as "scheduling-clock ticks" or simply "ticks"):
 
-1.	Idle CPUs (CONFIG_NO_HZ_IDLE=y or CONFIG_NO_HZ=y for older kernels).
+1.	Never omit scheduling-clock ticks (CONFIG_HZ_PERIODIC=y or
+	CONFIG_NO_HZ=n for older kernels).  You normally will -not-
+	want to choose this option.
 
-2.	CPUs having only one runnable task (CONFIG_NO_HZ_FULL=y).
+2.	Omit scheduling-clock ticks on idle CPUs (CONFIG_NO_HZ_IDLE=y or
+	CONFIG_NO_HZ=y for older kernels).  This is the most common
+	approach, and should be the default.
 
-These two cases are described in the following two sections, followed
+3.	Omit scheduling-clock ticks on CPUs that are either idle or that
+	have only one runnable task (CONFIG_NO_HZ_FULL=y).  Unless you
+	are running realtime applications or certain types of HPC
+	workloads, you will normally -not- want this option.
+
+These three cases are described in the following three sections, followed
 by a third section on RCU-specific considerations and a fourth and final
 section listing known issues.
 
 
-IDLE CPUs
+NEVER OMIT SCHEDULING-CLOCK TICKS
+
+Very old versions of Linux from the 1990s and the very early 2000s
+are incapable of omitting scheduling-clock ticks.  It turns out that
+there are some situations where this old-school approach is still the
+right approach, for example, in heavy workloads with lots of tasks
+that use short bursts of CPU, where there are very frequent idle
+periods, but where these idle periods are also quite short (tens or
+hundreds of microseconds).  For these types of workloads, scheduling
+clock interrupts will normally be delivered any way because there
+will frequently be multiple runnable tasks per CPU.  In these cases,
+attempting to turn off the scheduling clock interrupt will have no effect
+other than increasing the overhead of switching to and from idle and
+transitioning between user and kernel execution.
+
+This mode of operation can be selected using CONFIG_HZ_PERIODIC=y (or
+CONFIG_NO_HZ=n for older kernels).
+
+However, if you are instead running a light workload with long idle
+periods, failing to omit scheduling-clock interrupts will result in
+excessive power consumption.  This is especially bad on battery-powered
+devices, where it results in extremely short battery lifetimes.  If you
+are running light workloads, you should therefore read the following
+section.
+
+In addition, if you are running either a real-time workload or an HPC
+workload with short iterations, the scheduling-clock interrupts can
+degrade your applications performance.  If this describes your workload,
+you should read the following two sections.
+
+
+OMIT SCHEDULING-CLOCK TICKS FOR IDLE CPUs
 
 If a CPU is idle, there is little point in sending it a scheduling-clock
 interrupt.  After all, the primary purpose of a scheduling-clock interrupt
@@ -59,10 +97,12 @@ By default, CONFIG_NO_HZ_IDLE=y kernels
 dyntick-idle mode.
 
 
-CPUs WITH ONLY ONE RUNNABLE TASK
+OMIT SCHEDULING-CLOCK TICKS FOR CPUs WITH ONLY ONE RUNNABLE TASK
 
 If a CPU has only one runnable task, there is little point in sending it
 a scheduling-clock interrupt because there is no other task to switch to.
+Note that omitting scheduling-clock ticks for CPUs with only one runnable
+task implies also omitting them for idle CPUs.
 
 The CONFIG_NO_HZ_FULL=y Kconfig option causes the kernel to avoid
 sending scheduling-clock interrupts to CPUs with a single runnable task,
@@ -238,6 +278,11 @@ o	Adaptive-ticks does not do anything un
 	single runnable SCHED_FIFO task and multiple runnable SCHED_OTHER
 	tasks, even though these interrupts are unnecessary.
 
+	And even when there are multiple runnable tasks on a given CPU,
+	there is little point in interrupting that CPU until the current
+	running task's timeslice expires, which is almost always way
+	longer than the time of the next scheduling-clock interrupt.
+
 	Better handling of these sorts of situations is future work.
 
 o	A reboot is required to reconfigure both adaptive idle and RCU
@@ -268,6 +313,16 @@ o	Unless all CPUs are idle, at least one
 	scheduling-clock interrupt going in order to support accurate
 	timekeeping.
 
-o	If there are adaptive-ticks CPUs, there will be at least one
-	CPU keeping the scheduling-clock interrupt going, even if all
-	CPUs are otherwise idle.
+o	If there might potentially be some adaptive-ticks CPUs, there
+	will be at least one CPU keeping the scheduling-clock interrupt
+	going, even if all CPUs are otherwise idle.
+
+	Better handling of this situation is ongoing work.
+
+o	Some process-handling operations still require the occasional
+	scheduling-clock tick.	These operations include calculating CPU
+	load, maintaining sched average, computing CFS entity vruntime,
+	computing avenrun, and carrying out load balancing.  They are
+	currently accommodated by scheduling-clock tick every second
+	or so.	On-going work will eliminate the need even for these
+	infrequent scheduling-clock ticks.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/trace/events-nmi.txt linux-libre-3.11-rc7-gnu/Documentation/trace/events-nmi.txt
--- linux-libre-3.10-gnu/Documentation/trace/events-nmi.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/trace/events-nmi.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,43 @@
+NMI Trace Events
+
+These events normally show up here:
+
+	/sys/kernel/debug/tracing/events/nmi
+
+--
+
+nmi_handler:
+
+You might want to use this tracepoint if you suspect that your
+NMI handlers are hogging large amounts of CPU time.  The kernel
+will warn if it sees long-running handlers:
+
+	INFO: NMI handler took too long to run: 9.207 msecs
+
+and this tracepoint will allow you to drill down and get some
+more details.
+
+Let's say you suspect that perf_event_nmi_handler() is causing
+you some problems and you only want to trace that handler
+specifically.  You need to find its address:
+
+	$ grep perf_event_nmi_handler /proc/kallsyms
+	ffffffff81625600 t perf_event_nmi_handler
+
+Let's also say you are only interested in when that function is
+really hogging a lot of CPU time, like a millisecond at a time.
+Note that the kernel's output is in milliseconds, but the input
+to the filter is in nanoseconds!  You can filter on 'delta_ns':
+
+cd /sys/kernel/debug/tracing/events/nmi/nmi_handler
+echo 'handler==0xffffffff81625600 && delta_ns>1000000' > filter
+echo 1 > enable
+
+Your output would then look like:
+
+$ cat /sys/kernel/debug/tracing/trace_pipe
+<idle>-0     [000] d.h3   505.397558: nmi_handler: perf_event_nmi_handler() delta_ns: 3236765 handled: 1
+<idle>-0     [000] d.h3   505.805893: nmi_handler: perf_event_nmi_handler() delta_ns: 3174234 handled: 1
+<idle>-0     [000] d.h3   506.158206: nmi_handler: perf_event_nmi_handler() delta_ns: 3084642 handled: 1
+<idle>-0     [000] d.h3   506.334346: nmi_handler: perf_event_nmi_handler() delta_ns: 3080351 handled: 1
+
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/trace/events-power.txt linux-libre-3.11-rc7-gnu/Documentation/trace/events-power.txt
--- linux-libre-3.10-gnu/Documentation/trace/events-power.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/trace/events-power.txt	2013-08-25 20:43:22.000000000 -0400
@@ -63,3 +63,34 @@ power_domain_target	"%s state=%lu cpu_id
 The first parameter gives the power domain name (e.g. "mpu_pwrdm").
 The second parameter is the power domain target state.
 
+4. PM QoS events
+================
+The PM QoS events are used for QoS add/update/remove request and for
+target/flags update.
+
+pm_qos_add_request                 "pm_qos_class=%s value=%d"
+pm_qos_update_request              "pm_qos_class=%s value=%d"
+pm_qos_remove_request              "pm_qos_class=%s value=%d"
+pm_qos_update_request_timeout      "pm_qos_class=%s value=%d, timeout_us=%ld"
+
+The first parameter gives the QoS class name (e.g. "CPU_DMA_LATENCY").
+The second parameter is value to be added/updated/removed.
+The third parameter is timeout value in usec.
+
+pm_qos_update_target               "action=%s prev_value=%d curr_value=%d"
+pm_qos_update_flags                "action=%s prev_value=0x%x curr_value=0x%x"
+
+The first parameter gives the QoS action name (e.g. "ADD_REQ").
+The second parameter is the previous QoS value.
+The third parameter is the current QoS value to update.
+
+And, there are also events used for device PM QoS add/update/remove request.
+
+dev_pm_qos_add_request             "device=%s type=%s new_value=%d"
+dev_pm_qos_update_request          "device=%s type=%s new_value=%d"
+dev_pm_qos_remove_request          "device=%s type=%s new_value=%d"
+
+The first parameter gives the device name which tries to add/update/remove
+QoS requests.
+The second parameter gives the request type (e.g. "DEV_PM_QOS_LATENCY").
+The third parameter is value to be added/updated/removed.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/trace/events.txt linux-libre-3.11-rc7-gnu/Documentation/trace/events.txt
--- linux-libre-3.10-gnu/Documentation/trace/events.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/trace/events.txt	2013-08-25 20:43:22.000000000 -0400
@@ -183,13 +183,22 @@ The relational-operators depend on the t
 
 The operators available for numeric fields are:
 
-==, !=, <, <=, >, >=
+==, !=, <, <=, >, >=, &
 
 And for string fields they are:
 
-==, !=
+==, !=, ~
 
-Currently, only exact string matches are supported.
+The glob (~) only accepts a wild card character (*) at the start and or
+end of the string. For example:
+
+  prev_comm ~ "*sh"
+  prev_comm ~ "sh*"
+  prev_comm ~ "*sh*"
+
+But does not allow for it to be within the string:
+
+  prev_comm ~ "ba*sh"   <-- is invalid
 
 5.2 Setting filters
 -------------------
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/trace/ftrace.txt linux-libre-3.11-rc7-gnu/Documentation/trace/ftrace.txt
--- linux-libre-3.10-gnu/Documentation/trace/ftrace.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/trace/ftrace.txt	2013-08-25 20:43:22.000000000 -0400
@@ -2430,6 +2430,19 @@ The following commands are supported:
    echo '!schedule:disable_event:sched:sched_switch' > \
    	 set_ftrace_filter
 
+- dump
+  When the function is hit, it will dump the contents of the ftrace
+  ring buffer to the console. This is useful if you need to debug
+  something, and want to dump the trace when a certain function
+  is hit. Perhaps its a function that is called before a tripple
+  fault happens and does not allow you to get a regular dump.
+
+- cpudump
+  When the function is hit, it will dump the contents of the ftrace
+  ring buffer for the current CPU to the console. Unlike the "dump"
+  command, it only prints out the contents of the ring buffer for the
+  CPU that executed the function that triggered the dump.
+
 trace_pipe
 ----------
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/usb/gadget_configfs.txt linux-libre-3.11-rc7-gnu/Documentation/usb/gadget_configfs.txt
--- linux-libre-3.10-gnu/Documentation/usb/gadget_configfs.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/usb/gadget_configfs.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,384 @@
+
+
+
+
+		Linux USB gadget configured through configfs
+
+
+			     25th April 2013
+
+
+
+
+Overview
+========
+
+A USB Linux Gadget is a device which has a UDC (USB Device Controller) and can
+be connected to a USB Host to extend it with additional functions like a serial
+port or a mass storage capability.
+
+A gadget is seen by its host as a set of configurations, each of which contains
+a number of interfaces which, from the gadget's perspective, are known as
+functions, each function representing e.g. a serial connection or a SCSI disk.
+
+Linux provides a number of functions for gadgets to use.
+
+Creating a gadget means deciding what configurations there will be
+and which functions each configuration will provide.
+
+Configfs (please see Documentation/filesystems/configfs/*) lends itslef nicely
+for the purpose of telling the kernel about the above mentioned decision.
+This document is about how to do it.
+
+It also describes how configfs integration into gadget is designed.
+
+
+
+
+Requirements
+============
+
+In order for this to work configfs must be available, so CONFIGFS_FS must be
+'y' or 'm' in .config. As of this writing USB_LIBCOMPOSITE selects CONFIGFS_FS.
+
+
+
+
+Usage
+=====
+
+(The original post describing the first function
+made available through configfs can be seen here:
+http://www.spinics.net/lists/linux-usb/msg76388.html)
+
+$ modprobe libcomposite
+$ mount none $CONFIGFS_HOME -t configfs
+
+where CONFIGFS_HOME is the mount point for configfs
+
+1. Creating the gadgets
+-----------------------
+
+For each gadget to be created its corresponding directory must be created:
+
+$ mkdir $CONFIGFS_HOME/usb_gadget/<gadget name>
+
+e.g.:
+
+$ mkdir $CONFIGFS_HOME/usb_gadget/g1
+
+...
+...
+...
+
+$ cd $CONFIGFS_HOME/usb_gadget/g1
+
+Each gadget needs to have its vendor id <VID> and product id <PID> specified:
+
+$ echo <VID> > idVendor
+$ echo <PID> > idProduct
+
+A gadget also needs its serial number, manufacturer and product strings.
+In order to have a place to store them, a strings subdirectory must be created
+for each language, e.g.:
+
+$ mkdir strings/0x409
+
+Then the strings can be specified:
+
+$ echo <serial number> > strings/0x409/serialnumber
+$ echo <manufacturer> > strings/0x409/manufacturer
+$ echo <product> > strings/0x409/product
+
+2. Creating the configurations
+------------------------------
+
+Each gadget will consist of a number of configurations, their corresponding
+directories must be created:
+
+$ mkdir configs/<name>.<number>
+
+where <name> can be any string which is legal in a filesystem and the
+<numebr> is the configuration's number, e.g.:
+
+$ mkdir configs/c.1
+
+...
+...
+...
+
+Each configuration also needs its strings, so a subdirectory must be created
+for each language, e.g.:
+
+$ mkdir configs/c.1/strings/0x409
+
+Then the configuration string can be specified:
+
+$ echo <configuration> > configs/c.1/strings/0x409/configuration
+
+Some attributes can also be set for a configuration, e.g.:
+
+$ echo 120 > configs/c.1/MaxPower
+
+3. Creating the functions
+-------------------------
+
+The gadget will provide some functions, for each function its corresponding
+directory must be created:
+
+$ mkdir functions/<name>.<instance name>
+
+where <name> corresponds to one of allowed function names and instance name
+is an arbitrary string allowed in a filesystem, e.g.:
+
+$ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module()
+
+...
+...
+...
+
+Each function provides its specific set of attributes, with either read-only
+or read-write access. Where applicable they need to be written to as
+appropriate.
+Please refer to Documentation/ABI/*/configfs-usb-gadget* for more information.
+
+4. Associating the functions with their configurations
+------------------------------------------------------
+
+At this moment a number of gadgets is created, each of which has a number of
+configurations specified and a number of functions available. What remains
+is specifying which function is available in which configuration (the same
+function can be used in multiple configurations). This is achieved with
+creating symbolic links:
+
+$ ln -s functions/<name>.<instance name> configs/<name>.<number>
+
+e.g.:
+
+$ ln -s functions/ncm.usb0 configs/c.1
+
+...
+...
+...
+
+5. Enabling the gadget
+----------------------
+
+All the above steps serve the purpose of composing the gadget of
+configurations and functions.
+
+An example directory structure might look like this:
+
+.
+./strings
+./strings/0x409
+./strings/0x409/serialnumber
+./strings/0x409/product
+./strings/0x409/manufacturer
+./configs
+./configs/c.1
+./configs/c.1/ncm.usb0 -> ../../../../usb_gadget/g1/functions/ncm.usb0
+./configs/c.1/strings
+./configs/c.1/strings/0x409
+./configs/c.1/strings/0x409/configuration
+./configs/c.1/bmAttributes
+./configs/c.1/MaxPower
+./functions
+./functions/ncm.usb0
+./functions/ncm.usb0/ifname
+./functions/ncm.usb0/qmult
+./functions/ncm.usb0/host_addr
+./functions/ncm.usb0/dev_addr
+./UDC
+./bcdUSB
+./bcdDevice
+./idProduct
+./idVendor
+./bMaxPacketSize0
+./bDeviceProtocol
+./bDeviceSubClass
+./bDeviceClass
+
+
+Such a gadget must be finally enabled so that the USB host can enumerate it.
+In order to enable the gadget it must be bound to a UDC (USB Device Controller).
+
+$ echo <udc name> > UDC
+
+where <udc name> is one of those found in /sys/class/udc/*
+e.g.:
+
+$ echo s3c-hsotg > UDC
+
+
+6. Disabling the gadget
+-----------------------
+
+$ echo "" > UDC
+
+7. Cleaning up
+--------------
+
+Remove functions from configurations:
+
+$ rm configs/<config name>.<number>/<function>
+
+where <config name>.<number> specify the configuration and <function> is
+a symlink to a function being removed from the configuration, e.g.:
+
+$ rm configfs/c.1/ncm.usb0
+
+...
+...
+...
+
+Remove strings directories in configurations
+
+$ rmdir configs/<config name>.<number>/strings/<lang>
+
+e.g.:
+
+$ rmdir configs/c.1/strings/0x409
+
+...
+...
+...
+
+and remove the configurations
+
+$ rmdir configs/<config name>.<number>
+
+e.g.:
+
+rmdir configs/c.1
+
+...
+...
+...
+
+Remove functions (function modules are not unloaded, though)
+
+$ rmdir functions/<name>.<instance name>
+
+e.g.:
+
+$ rmdir functions/ncm.usb0
+
+...
+...
+...
+
+Remove strings directories in the gadget
+
+$ rmdir strings/<lang>
+
+e.g.:
+
+$ rmdir strings/0x409
+
+and finally remove the gadget:
+
+$ cd ..
+$ rmdir <gadget name>
+
+e.g.:
+
+$ rmdir g1
+
+
+
+
+Implementation design
+=====================
+
+Below the idea of how configfs works is presented.
+In configfs there are items and groups, both represented as directories.
+The difference between an item and a group is that a group can contain
+other groups. In the picture below only an item is shown.
+Both items and groups can have attributes, which are represented as files.
+The user can create and remove directories, but cannot remove files,
+which can be read-only or read-write, depending on what they represent.
+
+The filesystem part of configfs operates on config_items/groups and
+configfs_attributes which are generic and of the same type for all
+configured elements. However, they are embedded in usage-specific
+larger structures. In the picture below there is a "cs" which contains
+a config_item and an "sa" which contains a configfs_attribute.
+
+The filesystem view would be like this:
+
+./
+./cs        (directory)
+   |
+   +--sa    (file)
+   |
+   .
+   .
+   .
+
+Whenever a user reads/writes the "sa" file, a function is called
+which accepts a struct config_item and a struct configfs_attribute.
+In the said function the "cs" and "sa" are retrieved using the well
+known container_of technique and an appropriate sa's function (show or
+store) is called and passed the "cs" and a character buffer. The "show"
+is for displaying the file's contents (copy data from the cs to the
+buffer), while the "store" is for modifying the file's contents (copy data
+from the buffer to the cs), but it is up to the implementer of the
+two functions to decide what they actually do.
+
+typedef struct configured_structure cs;
+typedef struc specific_attribute sa;
+
+                                       sa
+                       +----------------------------------+
+        cs             |  (*show)(cs *, buffer);          |
++-----------------+    |  (*store)(cs *, buffer, length); |
+|                 |    |                                  |
+| +-------------+ |    |       +------------------+       |
+| | struct      |-|----|------>|struct            |       |
+| | config_item | |    |       |configfs_attribute|       |
+| +-------------+ |    |       +------------------+       |
+|                 |    +----------------------------------+
+| data to be set  |                .
+|                 |                .
++-----------------+                .
+
+The file names are decided by the config item/group designer, while
+the directories in general can be named at will. A group can have
+a number of its default sub-groups created automatically.
+
+For more information on configfs please see
+Documentation/filesystems/configfs/*.
+
+The concepts described above translate to USB gadgets like this:
+
+1. A gadget has its config group, which has some attributes (idVendor,
+idProduct etc) and default sub-groups (configs, functions, strings).
+Writing to the attributes causes the information to be stored in
+appropriate locations. In the configs, functions and strings sub-groups
+a user can create their sub-groups to represent configurations, functions,
+and groups of strings in a given language.
+
+2. The user creates configurations and functions, in the configurations
+creates symbolic links to functions. This information is used when the
+gadget's UDC attribute is written to, which means binding the gadget
+to the UDC. The code in drivers/usb/gadget/configfs.c iterates over
+all configurations, and in each configuration it iterates over all
+functions and binds them. This way the whole gadget is bound.
+
+3. The file drivers/usb/gadget/configfs.c contains code for
+
+	- gadget's config_group
+	- gadget's default groups (configs, functions, strings)
+	- associating functions with configurations (symlinks)
+
+4. Each USB function naturally has its own view of what it wants
+configured, so config_groups for particular functions are defined
+in the functions implementation files drivers/usb/gadget/f_*.c.
+
+5. Funciton's code is written in such a way that it uses
+
+usb_get_function_instance(), which, in turn, calls request_module.
+So, provided that modprobe works, modules for particular functions
+are loaded automatically. Please note that the converse is not true:
+after a gadget is disabled and torn down, the modules remain loaded.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/usb/hotplug.txt linux-libre-3.11-rc7-gnu/Documentation/usb/hotplug.txt
--- linux-libre-3.10-gnu/Documentation/usb/hotplug.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/usb/hotplug.txt	2013-08-25 20:43:22.000000000 -0400
@@ -33,9 +33,9 @@ you get the best hotplugging when you co
 
 KERNEL HOTPLUG HELPER (/sbin/hotplug)
 
-When you compile with CONFIG_HOTPLUG, you get a new kernel parameter:
-/proc/sys/kernel/hotplug, which normally holds the pathname "/sbin/hotplug".
-That parameter names a program which the kernel may invoke at various times.
+There is a kernel parameter: /proc/sys/kernel/hotplug, which normally
+holds the pathname "/sbin/hotplug".  That parameter names a program
+which the kernel may invoke at various times.
 
 The /sbin/hotplug program can be invoked by any subsystem as part of its
 reaction to a configuration change, from a thread in that subsystem.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/vfio.txt linux-libre-3.11-rc7-gnu/Documentation/vfio.txt
--- linux-libre-3.10-gnu/Documentation/vfio.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/vfio.txt	2013-08-25 20:43:22.000000000 -0400
@@ -172,12 +172,12 @@ group and can access them as follows:
 	struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
 
 	/* Create a new container */
-	container = open("/dev/vfio/vfio, O_RDWR);
+	container = open("/dev/vfio/vfio", O_RDWR);
 
 	if (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION)
 		/* Unknown API version */
 
-	if (!ioctl(container, VFIO_CHECK_EXTENSION, VFIO_X86_IOMMU))
+	if (!ioctl(container, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU))
 		/* Doesn't support the IOMMU driver we want. */
 
 	/* Open the group */
@@ -193,7 +193,7 @@ group and can access them as follows:
 	ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
 
 	/* Enable the IOMMU model we want */
-	ioctl(container, VFIO_SET_IOMMU, VFIO_X86_IOMMU)
+	ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU)
 
 	/* Get addition IOMMU info */
 	ioctl(container, VFIO_IOMMU_GET_INFO, &iommu_info);
@@ -283,6 +283,69 @@ a direct pass through for VFIO_DEVICE_*
 interfaces implement the device region access defined by the device's
 own VFIO_DEVICE_GET_REGION_INFO ioctl.
 
+
+PPC64 sPAPR implementation note
+-------------------------------------------------------------------------------
+
+This implementation has some specifics:
+
+1) Only one IOMMU group per container is supported as an IOMMU group
+represents the minimal entity which isolation can be guaranteed for and
+groups are allocated statically, one per a Partitionable Endpoint (PE)
+(PE is often a PCI domain but not always).
+
+2) The hardware supports so called DMA windows - the PCI address range
+within which DMA transfer is allowed, any attempt to access address space
+out of the window leads to the whole PE isolation.
+
+3) PPC64 guests are paravirtualized but not fully emulated. There is an API
+to map/unmap pages for DMA, and it normally maps 1..32 pages per call and
+currently there is no way to reduce the number of calls. In order to make things
+faster, the map/unmap handling has been implemented in real mode which provides
+an excellent performance which has limitations such as inability to do
+locked pages accounting in real time.
+
+So 3 additional ioctls have been added:
+
+	VFIO_IOMMU_SPAPR_TCE_GET_INFO - returns the size and the start
+		of the DMA window on the PCI bus.
+
+	VFIO_IOMMU_ENABLE - enables the container. The locked pages accounting
+		is done at this point. This lets user first to know what
+		the DMA window is and adjust rlimit before doing any real job.
+
+	VFIO_IOMMU_DISABLE - disables the container.
+
+
+The code flow from the example above should be slightly changed:
+
+	.....
+	/* Add the group to the container */
+	ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
+
+	/* Enable the IOMMU model we want */
+	ioctl(container, VFIO_SET_IOMMU, VFIO_SPAPR_TCE_IOMMU)
+
+	/* Get addition sPAPR IOMMU info */
+	vfio_iommu_spapr_tce_info spapr_iommu_info;
+	ioctl(container, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &spapr_iommu_info);
+
+	if (ioctl(container, VFIO_IOMMU_ENABLE))
+		/* Cannot enable container, may be low rlimit */
+
+	/* Allocate some space and setup a DMA mapping */
+	dma_map.vaddr = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
+			     MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+
+	dma_map.size = 1024 * 1024;
+	dma_map.iova = 0; /* 1MB starting at 0x0 from device view */
+	dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
+
+	/* Check here is .iova/.size are within DMA window from spapr_iommu_info */
+
+	ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
+	.....
+
 -------------------------------------------------------------------------------
 
 [1] VFIO was originally an acronym for "Virtual Function I/O" in its
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/video4linux/CARDLIST.bttv linux-libre-3.11-rc7-gnu/Documentation/video4linux/CARDLIST.bttv
--- linux-libre-3.10-gnu/Documentation/video4linux/CARDLIST.bttv	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/video4linux/CARDLIST.bttv	2013-08-25 20:43:22.000000000 -0400
@@ -160,3 +160,6 @@
 159 -> ProVideo PV183                                      [1830:1540,1831:1540,1832:1540,1833:1540,1834:1540,1835:1540,1836:1540,1837:1540]
 160 -> Tongwei Video Technology TD-3116                    [f200:3116]
 161 -> Aposonic W-DVR                                      [0279:0228]
+162 -> Adlink MPG24
+163 -> Bt848 Capture 14MHz
+164 -> CyberVision CV06 (SV)
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/video4linux/CARDLIST.saa7134 linux-libre-3.11-rc7-gnu/Documentation/video4linux/CARDLIST.saa7134
--- linux-libre-3.10-gnu/Documentation/video4linux/CARDLIST.saa7134	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/video4linux/CARDLIST.saa7134	2013-08-25 20:43:22.000000000 -0400
@@ -190,3 +190,4 @@
 189 -> Kworld PC150-U                           [17de:a134]
 190 -> Asus My Cinema PS3-100                   [1043:48cd]
 191 -> Hawell HW-9004V1
+192 -> AverMedia AverTV Satellite Hybrid+FM A706 [1461:2055]
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/video4linux/CARDLIST.tuner linux-libre-3.11-rc7-gnu/Documentation/video4linux/CARDLIST.tuner
--- linux-libre-3.10-gnu/Documentation/video4linux/CARDLIST.tuner	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/video4linux/CARDLIST.tuner	2013-08-25 20:43:22.000000000 -0400
@@ -86,6 +86,6 @@ tuner=85 - Philips FQ1236 MK5
 tuner=86 - Tena TNF5337 MFD
 tuner=87 - Xceive 4000 tuner
 tuner=88 - Xceive 5000C tuner
-tuner=89 - Sony PAL+SECAM (BTF-PG472Z)
-tuner=90 - Sony NTSC-M-JP (BTF-PK467Z)
-tuner=91 - Sony NTSC-M (BTF-PB463Z)
+tuner=89 - Sony BTF-PG472Z PAL/SECAM
+tuner=90 - Sony BTF-PK467Z NTSC-M-JP
+tuner=91 - Sony BTF-PB463Z NTSC-M
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/video4linux/fimc.txt linux-libre-3.11-rc7-gnu/Documentation/video4linux/fimc.txt
--- linux-libre-3.10-gnu/Documentation/video4linux/fimc.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/video4linux/fimc.txt	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 Samsung S5P/EXYNOS4 FIMC driver
 
-Copyright (C) 2012 Samsung Electronics Co., Ltd.
+Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
 ---------------------------------------------------------------------------
 
 The FIMC (Fully Interactive Mobile Camera) device available in Samsung
@@ -10,7 +10,7 @@ data from LCD controller (FIMD) through
 path.  There are multiple FIMC instances in the SoCs (up to 4), having
 slightly different capabilities, like pixel alignment constraints, rotator
 availability, LCD writeback support, etc. The driver is located at
-drivers/media/platform/s5p-fimc directory.
+drivers/media/platform/exynos4-is directory.
 
 1. Supported SoCs
 =================
@@ -36,21 +36,21 @@ Not currently supported:
 =====================
 
 - media device driver
-  drivers/media/platform/s5p-fimc/fimc-mdevice.[ch]
+  drivers/media/platform/exynos4-is/media-dev.[ch]
 
  - camera capture video device driver
-  drivers/media/platform/s5p-fimc/fimc-capture.c
+  drivers/media/platform/exynos4-is/fimc-capture.c
 
  - MIPI-CSI2 receiver subdev
-  drivers/media/platform/s5p-fimc/mipi-csis.[ch]
+  drivers/media/platform/exynos4-is/mipi-csis.[ch]
 
  - video post-processor (mem-to-mem)
-  drivers/media/platform/s5p-fimc/fimc-core.c
+  drivers/media/platform/exynos4-is/fimc-core.c
 
  - common files
-  drivers/media/platform/s5p-fimc/fimc-core.h
-  drivers/media/platform/s5p-fimc/fimc-reg.h
-  drivers/media/platform/s5p-fimc/regs-fimc.h
+  drivers/media/platform/exynos4-is/fimc-core.h
+  drivers/media/platform/exynos4-is/fimc-reg.h
+  drivers/media/platform/exynos4-is/regs-fimc.h
 
 4. User space interfaces
 ========================
@@ -143,7 +143,8 @@ or retrieve the information from /dev/me
 6. Platform support
 ===================
 
-The machine code (plat-s5p and arch/arm/mach-*) must select following options
+The machine code (arch/arm/plat-samsung and arch/arm/mach-*) must select
+following options:
 
 CONFIG_S5P_DEV_FIMC0       mandatory
 CONFIG_S5P_DEV_FIMC1  \
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/video4linux/si476x.txt linux-libre-3.11-rc7-gnu/Documentation/video4linux/si476x.txt
--- linux-libre-3.10-gnu/Documentation/video4linux/si476x.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/video4linux/si476x.txt	2013-08-25 20:43:22.000000000 -0400
@@ -166,7 +166,7 @@ The drivers exposes following files:
   --------------------------------------------------------------------
   0x21		| dev		| Frequency deviation
   --------------------------------------------------------------------
-  0x24		| assi		| Adjascent channel SSI
+  0x24		| assi		| Adjacent channel SSI
   --------------------------------------------------------------------
   0x25		| usn		| Ultrasonic noise indicator
   --------------------------------------------------------------------
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/video4linux/soc-camera.txt linux-libre-3.11-rc7-gnu/Documentation/video4linux/soc-camera.txt
--- linux-libre-3.10-gnu/Documentation/video4linux/soc-camera.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/video4linux/soc-camera.txt	2013-08-25 20:43:22.000000000 -0400
@@ -116,7 +116,7 @@ VIDIOC_S_FMT: sets user window. Should p
 much as possible by modifying scaling factors. If the sensor window cannot be
 preserved precisely, it may be changed too.
 
-In soc-camera there are two locations, where scaling and cropping can taks
+In soc-camera there are two locations, where scaling and cropping can take
 place: in the camera driver and in the host driver. User ioctls are first passed
 to the host driver, which then generally passes them down to the camera driver.
 It is more efficient to perform scaling and cropping in the camera driver to
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/video4linux/v4l2-framework.txt linux-libre-3.11-rc7-gnu/Documentation/video4linux/v4l2-framework.txt
--- linux-libre-3.10-gnu/Documentation/video4linux/v4l2-framework.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/video4linux/v4l2-framework.txt	2013-08-25 20:43:22.000000000 -0400
@@ -246,7 +246,6 @@ may be NULL if the subdev driver does no
 It looks like this:
 
 struct v4l2_subdev_core_ops {
-	int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
 	int (*log_status)(struct v4l2_subdev *sd);
 	int (*init)(struct v4l2_subdev *sd, u32 val);
 	...
@@ -326,8 +325,27 @@ that width, height and the media bus pix
 sink of the link. Subdev drivers are also free to use this function to
 perform the checks mentioned above in addition to their own checks.
 
-A device (bridge) driver needs to register the v4l2_subdev with the
-v4l2_device:
+There are currently two ways to register subdevices with the V4L2 core. The
+first (traditional) possibility is to have subdevices registered by bridge
+drivers. This can be done when the bridge driver has the complete information
+about subdevices connected to it and knows exactly when to register them. This
+is typically the case for internal subdevices, like video data processing units
+within SoCs or complex PCI(e) boards, camera sensors in USB cameras or connected
+to SoCs, which pass information about them to bridge drivers, usually in their
+platform data.
+
+There are however also situations where subdevices have to be registered
+asynchronously to bridge devices. An example of such a configuration is a Device
+Tree based system where information about subdevices is made available to the
+system independently from the bridge devices, e.g. when subdevices are defined
+in DT as I2C device nodes. The API used in this second case is described further
+below.
+
+Using one or the other registration method only affects the probing process, the
+run-time bridge-subdevice interaction is in both cases the same.
+
+In the synchronous case a device (bridge) driver needs to register the
+v4l2_subdev with the v4l2_device:
 
 	int err = v4l2_device_register_subdev(v4l2_dev, sd);
 
@@ -346,24 +364,24 @@ Afterwards the subdev module can be unlo
 
 You can call an ops function either directly:
 
-	err = sd->ops->core->g_chip_ident(sd, &chip);
+	err = sd->ops->core->g_std(sd, &norm);
 
 but it is better and easier to use this macro:
 
-	err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
+	err = v4l2_subdev_call(sd, core, g_std, &norm);
 
 The macro will to the right NULL pointer checks and returns -ENODEV if subdev
-is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_chip_ident is
-NULL, or the actual result of the subdev->ops->core->g_chip_ident ops.
+is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_std is
+NULL, or the actual result of the subdev->ops->core->g_std ops.
 
 It is also possible to call all or a subset of the sub-devices:
 
-	v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
+	v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm);
 
 Any subdev that does not support this ops is skipped and error results are
 ignored. If you want to check for errors use this:
 
-	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
+	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm);
 
 Any error except -ENOIOCTLCMD will exit the loop with that error. If no
 errors (except -ENOIOCTLCMD) occurred, then 0 is returned.
@@ -394,6 +412,30 @@ controlled through GPIO pins. This disti
 up the device, but once the subdev is registered it is completely transparent.
 
 
+In the asynchronous case subdevice probing can be invoked independently of the
+bridge driver availability. The subdevice driver then has to verify whether all
+the requirements for a successful probing are satisfied. This can include a
+check for a master clock availability. If any of the conditions aren't satisfied
+the driver might decide to return -EPROBE_DEFER to request further reprobing
+attempts. Once all conditions are met the subdevice shall be registered using
+the v4l2_async_register_subdev() function. Unregistration is performed using
+the v4l2_async_unregister_subdev() call. Subdevices registered this way are
+stored in a global list of subdevices, ready to be picked up by bridge drivers.
+
+Bridge drivers in turn have to register a notifier object with an array of
+subdevice descriptors that the bridge device needs for its operation. This is
+performed using the v4l2_async_notifier_register() call. To unregister the
+notifier the driver has to call v4l2_async_notifier_unregister(). The former of
+the two functions takes two arguments: a pointer to struct v4l2_device and a
+pointer to struct v4l2_async_notifier. The latter contains a pointer to an array
+of pointers to subdevice descriptors of type struct v4l2_async_subdev type. The
+V4L2 core will then use these descriptors to match asynchronously registered
+subdevices to them. If a match is detected the .bound() notifier callback is
+called. After all subdevices have been located the .complete() callback is
+called. When a subdevice is removed from the system the .unbind() method is
+called. All three callbacks are optional.
+
+
 V4L2 sub-device userspace API
 -----------------------------
 
@@ -575,9 +617,13 @@ of the video device exits.
 The default video_device_release() callback just calls kfree to free the
 allocated memory.
 
+There is also a video_device_release_empty() function that does nothing
+(is empty) and can be used if the struct is embedded and there is nothing
+to do when it is released.
+
 You should also set these fields:
 
-- v4l2_dev: set to the v4l2_device parent device.
+- v4l2_dev: must be set to the v4l2_device parent device.
 
 - name: set to something descriptive and unique.
 
@@ -614,15 +660,16 @@ You should also set these fields:
   If you want to have a separate priority state per (group of) device node(s),
   then you can point it to your own struct v4l2_prio_state.
 
-- parent: you only set this if v4l2_device was registered with NULL as
+- dev_parent: you only set this if v4l2_device was registered with NULL as
   the parent device struct. This only happens in cases where one hardware
   device has multiple PCI devices that all share the same v4l2_device core.
 
   The cx88 driver is an example of this: one core v4l2_device struct, but
-  it is used by both an raw video PCI device (cx8800) and a MPEG PCI device
-  (cx8802). Since the v4l2_device cannot be associated with a particular
-  PCI device it is setup without a parent device. But when the struct
-  video_device is setup you do know which parent PCI device to use.
+  it is used by both a raw video PCI device (cx8800) and a MPEG PCI device
+  (cx8802). Since the v4l2_device cannot be associated with two PCI devices
+  at the same time it is setup without a parent device. But when the struct
+  video_device is initialized you *do* know which parent PCI device to use and
+  so you set dev_device to the correct PCI device.
 
 - flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
   handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
@@ -1061,3 +1108,29 @@ available event type is 'class base + 1'
 
 An example on how the V4L2 events may be used can be found in the OMAP
 3 ISP driver (drivers/media/platform/omap3isp).
+
+
+V4L2 clocks
+-----------
+
+Many subdevices, like camera sensors, TV decoders and encoders, need a clock
+signal to be supplied by the system. Often this clock is supplied by the
+respective bridge device. The Linux kernel provides a Common Clock Framework for
+this purpose. However, it is not (yet) available on all architectures. Besides,
+the nature of the multi-functional (clock, data + synchronisation, I2C control)
+connection of subdevices to the system might impose special requirements on the
+clock API usage. E.g. V4L2 has to support clock provider driver unregistration
+while a subdevice driver is holding a reference to the clock. For these reasons
+a V4L2 clock helper API has been developed and is provided to bridge and
+subdevice drivers.
+
+The API consists of two parts: two functions to register and unregister a V4L2
+clock source: v4l2_clk_register() and v4l2_clk_unregister() and calls to control
+a clock object, similar to the respective generic clock API calls:
+v4l2_clk_get(), v4l2_clk_put(), v4l2_clk_enable(), v4l2_clk_disable(),
+v4l2_clk_get_rate(), and v4l2_clk_set_rate(). Clock suppliers have to provide
+clock operations that will be called when clock users invoke respective API
+methods.
+
+It is expected that once the CCF becomes available on all relevant
+architectures this API will be removed.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/virtual/kvm/api.txt linux-libre-3.11-rc7-gnu/Documentation/virtual/kvm/api.txt
--- linux-libre-3.10-gnu/Documentation/virtual/kvm/api.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/virtual/kvm/api.txt	2013-08-25 20:43:22.000000000 -0400
@@ -280,7 +280,7 @@ kvm_run' (see below).
 4.11 KVM_GET_REGS
 
 Capability: basic
-Architectures: all except ARM
+Architectures: all except ARM, arm64
 Type: vcpu ioctl
 Parameters: struct kvm_regs (out)
 Returns: 0 on success, -1 on error
@@ -301,7 +301,7 @@ struct kvm_regs {
 4.12 KVM_SET_REGS
 
 Capability: basic
-Architectures: all except ARM
+Architectures: all except ARM, arm64
 Type: vcpu ioctl
 Parameters: struct kvm_regs (in)
 Returns: 0 on success, -1 on error
@@ -587,7 +587,7 @@ struct kvm_fpu {
 4.24 KVM_CREATE_IRQCHIP
 
 Capability: KVM_CAP_IRQCHIP
-Architectures: x86, ia64, ARM
+Architectures: x86, ia64, ARM, arm64
 Type: vm ioctl
 Parameters: none
 Returns: 0 on success, -1 on error
@@ -595,14 +595,14 @@ Returns: 0 on success, -1 on error
 Creates an interrupt controller model in the kernel.  On x86, creates a virtual
 ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a
 local APIC.  IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23
-only go to the IOAPIC.  On ia64, a IOSAPIC is created. On ARM, a GIC is
+only go to the IOAPIC.  On ia64, a IOSAPIC is created. On ARM/arm64, a GIC is
 created.
 
 
 4.25 KVM_IRQ_LINE
 
 Capability: KVM_CAP_IRQCHIP
-Architectures: x86, ia64, arm
+Architectures: x86, ia64, arm, arm64
 Type: vm ioctl
 Parameters: struct kvm_irq_level
 Returns: 0 on success, -1 on error
@@ -612,9 +612,10 @@ On some architectures it is required tha
 been previously created with KVM_CREATE_IRQCHIP.  Note that edge-triggered
 interrupts require the level to be set to 1 and then back to 0.
 
-ARM can signal an interrupt either at the CPU level, or at the in-kernel irqchip
-(GIC), and for in-kernel irqchip can tell the GIC to use PPIs designated for
-specific cpus.  The irq field is interpreted like this:
+ARM/arm64 can signal an interrupt either at the CPU level, or at the
+in-kernel irqchip (GIC), and for in-kernel irqchip can tell the GIC to
+use PPIs designated for specific cpus.  The irq field is interpreted
+like this:
 
   bits:  | 31 ... 24 | 23  ... 16 | 15    ...    0 |
   field: | irq_type  | vcpu_index |     irq_id     |
@@ -1683,7 +1684,7 @@ The parameter is defined like this:
 
 This ioctl maps the memory at "user_addr" with the length "length" to
 the vcpu's address space starting at "vcpu_addr". All parameters need to
-be alligned by 1 megabyte.
+be aligned by 1 megabyte.
 
 
 4.66 KVM_S390_UCAS_UNMAP
@@ -1703,7 +1704,7 @@ The parameter is defined like this:
 
 This ioctl unmaps the memory in the vcpu's address space starting at
 "vcpu_addr" with the length "length". The field "user_addr" is ignored.
-All parameters need to be alligned by 1 megabyte.
+All parameters need to be aligned by 1 megabyte.
 
 
 4.67 KVM_S390_VCPU_FAULT
@@ -1831,6 +1832,22 @@ ARM 32-bit VFP control registers have th
 ARM 64-bit FP registers have the following id bit patterns:
   0x4030 0000 0012 0 <regno:12>
 
+
+arm64 registers are mapped using the lower 32 bits. The upper 16 of
+that is the register group type, or coprocessor number:
+
+arm64 core/FP-SIMD registers have the following id bit patterns. Note
+that the size of the access is variable, as the kvm_regs structure
+contains elements ranging from 32 to 128 bits. The index is a 32bit
+value in the kvm_regs structure seen as a 32bit array.
+  0x60x0 0000 0010 <index into the kvm_regs struct:16>
+
+arm64 CCSIDR registers are demultiplexed by CSSELR value:
+  0x6020 0000 0011 00 <csselr:8>
+
+arm64 system registers have the following id bit patterns:
+  0x6030 0000 0013 <op0:2> <op1:3> <crn:4> <crm:4> <op2:3>
+
 4.69 KVM_GET_ONE_REG
 
 Capability: KVM_CAP_ONE_REG
@@ -1972,7 +1989,7 @@ Returns: 0 on success, -1 on error
 
 This populates and returns a structure describing the features of
 the "Server" class MMU emulation supported by KVM.
-This can in turn be used by userspace to generate the appropariate
+This can in turn be used by userspace to generate the appropriate
 device-tree properties for the guest operating system.
 
 The structure contains some global informations, followed by an
@@ -2019,7 +2036,7 @@ be OR'ed into the "vsid" argument of the
 The "enc" array is a list which for each of those segment base page
 size provides the list of supported actual page sizes (which can be
 only larger or equal to the base page size), along with the
-corresponding encoding in the hash PTE. Similarily, the array is
+corresponding encoding in the hash PTE. Similarly, the array is
 8 entries sorted by increasing sizes and an entry with a "0" shift
 is an empty entry and a terminator:
 
@@ -2261,10 +2278,10 @@ return indicates the attribute is implem
 indicate that the attribute can be read or written in the device's
 current state.  "addr" is ignored.
 
-4.77 KVM_ARM_VCPU_INIT
+4.82 KVM_ARM_VCPU_INIT
 
 Capability: basic
-Architectures: arm
+Architectures: arm, arm64
 Type: vcpu ioctl
 Parameters: struct struct kvm_vcpu_init (in)
 Returns: 0 on success; -1 on error
@@ -2283,12 +2300,14 @@ should be created before this ioctl is i
 Possible features:
 	- KVM_ARM_VCPU_POWER_OFF: Starts the CPU in a power-off state.
 	  Depends on KVM_CAP_ARM_PSCI.
+	- KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode.
+	  Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only).
 
 
-4.78 KVM_GET_REG_LIST
+4.83 KVM_GET_REG_LIST
 
 Capability: basic
-Architectures: arm
+Architectures: arm, arm64
 Type: vcpu ioctl
 Parameters: struct kvm_reg_list (in/out)
 Returns: 0 on success; -1 on error
@@ -2305,10 +2324,10 @@ This ioctl returns the guest registers t
 KVM_GET_ONE_REG/KVM_SET_ONE_REG calls.
 
 
-4.80 KVM_ARM_SET_DEVICE_ADDR
+4.84 KVM_ARM_SET_DEVICE_ADDR
 
 Capability: KVM_CAP_ARM_SET_DEVICE_ADDR
-Architectures: arm
+Architectures: arm, arm64
 Type: vm ioctl
 Parameters: struct kvm_arm_device_address (in)
 Returns: 0 on success, -1 on error
@@ -2329,20 +2348,21 @@ can access emulated or directly exposed
 to know about. The id field is an architecture specific identifier for a
 specific device.
 
-ARM divides the id field into two parts, a device id and an address type id
-specific to the individual device.
+ARM/arm64 divides the id field into two parts, a device id and an
+address type id specific to the individual device.
 
   bits:  | 63        ...       32 | 31    ...    16 | 15    ...    0 |
   field: |        0x00000000      |     device id   |  addr type id  |
 
-ARM currently only require this when using the in-kernel GIC support for the
-hardware VGIC features, using KVM_ARM_DEVICE_VGIC_V2 as the device id.  When
-setting the base address for the guest's mapping of the VGIC virtual CPU
-and distributor interface, the ioctl must be called after calling
-KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs.  Calling
-this ioctl twice for any of the base addresses will return -EEXIST.
+ARM/arm64 currently only require this when using the in-kernel GIC
+support for the hardware VGIC features, using KVM_ARM_DEVICE_VGIC_V2
+as the device id.  When setting the base address for the guest's
+mapping of the VGIC virtual CPU and distributor interface, the ioctl
+must be called after calling KVM_CREATE_IRQCHIP, but before calling
+KVM_RUN on any of the VCPUs.  Calling this ioctl twice for any of the
+base addresses will return -EEXIST.
 
-4.82 KVM_PPC_RTAS_DEFINE_TOKEN
+4.85 KVM_PPC_RTAS_DEFINE_TOKEN
 
 Capability: KVM_CAP_PPC_RTAS
 Architectures: ppc
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/virtual/kvm/mmu.txt linux-libre-3.11-rc7-gnu/Documentation/virtual/kvm/mmu.txt
--- linux-libre-3.10-gnu/Documentation/virtual/kvm/mmu.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/virtual/kvm/mmu.txt	2013-08-25 20:43:22.000000000 -0400
@@ -191,12 +191,12 @@ Shadow pages contain the following infor
     A counter keeping track of how many hardware registers (guest cr3 or
     pdptrs) are now pointing at the page.  While this counter is nonzero, the
     page cannot be destroyed.  See role.invalid.
-  multimapped:
-    Whether there exist multiple sptes pointing at this page.
-  parent_pte/parent_ptes:
-    If multimapped is zero, parent_pte points at the single spte that points at
-    this page's spt.  Otherwise, parent_ptes points at a data structure
-    with a list of parent_ptes.
+  parent_ptes:
+    The reverse mapping for the pte/ptes pointing at this page's spt. If
+    parent_ptes bit 0 is zero, only one spte points at this pages and
+    parent_ptes points at this single spte, otherwise, there exists multiple
+    sptes pointing at this page and (parent_ptes & ~0x1) points at a data
+    structure with a list of parent_ptes.
   unsync:
     If true, then the translations in this page may not match the guest's
     translation.  This is equivalent to the state of the tlb when a pte is
@@ -210,6 +210,24 @@ Shadow pages contain the following infor
     A bitmap indicating which sptes in spt point (directly or indirectly) at
     pages that may be unsynchronized.  Used to quickly locate all unsychronized
     pages reachable from a given page.
+  mmu_valid_gen:
+    Generation number of the page.  It is compared with kvm->arch.mmu_valid_gen
+    during hash table lookup, and used to skip invalidated shadow pages (see
+    "Zapping all pages" below.)
+  clear_spte_count:
+    Only present on 32-bit hosts, where a 64-bit spte cannot be written
+    atomically.  The reader uses this while running out of the MMU lock
+    to detect in-progress updates and retry them until the writer has
+    finished the write.
+  write_flooding_count:
+    A guest may write to a page table many times, causing a lot of
+    emulations if the page needs to be write-protected (see "Synchronized
+    and unsynchronized pages" below).  Leaf pages can be unsynchronized
+    so that they do not trigger frequent emulation, but this is not
+    possible for non-leafs.  This field counts the number of emulations
+    since the last time the page table was actually used; if emulation
+    is triggered too frequently on this page, KVM will unmap the page
+    to avoid emulation in the future.
 
 Reverse map
 ===========
@@ -258,14 +276,26 @@ This is the most complicated event.  The
 
 Handling a page fault is performed as follows:
 
+ - if the RSV bit of the error code is set, the page fault is caused by guest
+   accessing MMIO and cached MMIO information is available.
+   - walk shadow page table
+   - check for valid generation number in the spte (see "Fast invalidation of
+     MMIO sptes" below)
+   - cache the information to vcpu->arch.mmio_gva, vcpu->arch.access and
+     vcpu->arch.mmio_gfn, and call the emulator
+ - If both P bit and R/W bit of error code are set, this could possibly
+   be handled as a "fast page fault" (fixed without taking the MMU lock).  See
+   the description in Documentation/virtual/kvm/locking.txt.
  - if needed, walk the guest page tables to determine the guest translation
    (gva->gpa or ngpa->gpa)
    - if permissions are insufficient, reflect the fault back to the guest
  - determine the host page
-   - if this is an mmio request, there is no host page; call the emulator
-     to emulate the instruction instead
+   - if this is an mmio request, there is no host page; cache the info to
+     vcpu->arch.mmio_gva, vcpu->arch.access and vcpu->arch.mmio_gfn
  - walk the shadow page table to find the spte for the translation,
    instantiating missing intermediate page tables as necessary
+   - If this is an mmio request, cache the mmio info to the spte and set some
+     reserved bit on the spte (see callers of kvm_mmu_set_mmio_spte_mask)
  - try to unsynchronize the page
    - if successful, we can let the guest continue and modify the gpte
  - emulate the instruction
@@ -351,6 +381,51 @@ causes its write_count to be incremented
 a large spte.  The frames at the end of an unaligned memory slot have
 artificially inflated ->write_counts so they can never be instantiated.
 
+Zapping all pages (page generation count)
+=========================================
+
+For the large memory guests, walking and zapping all pages is really slow
+(because there are a lot of pages), and also blocks memory accesses of
+all VCPUs because it needs to hold the MMU lock.
+
+To make it be more scalable, kvm maintains a global generation number
+which is stored in kvm->arch.mmu_valid_gen.  Every shadow page stores
+the current global generation-number into sp->mmu_valid_gen when it
+is created.  Pages with a mismatching generation number are "obsolete".
+
+When KVM need zap all shadow pages sptes, it just simply increases the global
+generation-number then reload root shadow pages on all vcpus.  As the VCPUs
+create new shadow page tables, the old pages are not used because of the
+mismatching generation number.
+
+KVM then walks through all pages and zaps obsolete pages.  While the zap
+operation needs to take the MMU lock, the lock can be released periodically
+so that the VCPUs can make progress.
+
+Fast invalidation of MMIO sptes
+===============================
+
+As mentioned in "Reaction to events" above, kvm will cache MMIO
+information in leaf sptes.  When a new memslot is added or an existing
+memslot is changed, this information may become stale and needs to be
+invalidated.  This also needs to hold the MMU lock while walking all
+shadow pages, and is made more scalable with a similar technique.
+
+MMIO sptes have a few spare bits, which are used to store a
+generation number.  The global generation number is stored in
+kvm_memslots(kvm)->generation, and increased whenever guest memory info
+changes.  This generation number is distinct from the one described in
+the previous section.
+
+When KVM finds an MMIO spte, it checks the generation number of the spte.
+If the generation number of the spte does not equal the global generation
+number, it will ignore the cached MMIO information and handle the page
+fault through the slow path.
+
+Since only 19 bits are used to store generation-number on mmio spte, all
+pages are zapped when there is an overflow.
+
+
 Further reading
 ===============
 
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/virtual/uml/UserModeLinux-HOWTO.txt linux-libre-3.11-rc7-gnu/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
--- linux-libre-3.10-gnu/Documentation/virtual/uml/UserModeLinux-HOWTO.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/virtual/uml/UserModeLinux-HOWTO.txt	2013-08-25 20:43:22.000000000 -0400
@@ -3127,7 +3127,7 @@
            at process_kern.c:156
        #3  0x1006a052 in switch_to (prev=0x50072000, next=0x507e8000, last=0x50072000)
            at process_kern.c:161
-       #4  0x10001d12 in schedule () at sched.c:777
+       #4  0x10001d12 in schedule () at core.c:777
        #5  0x1006a744 in __down (sem=0x507d241c) at semaphore.c:71
        #6  0x1006aa10 in __down_failed () at semaphore.c:157
        #7  0x1006c5d8 in segv_handler (sc=0x5006e940) at trap_user.c:174
@@ -3191,7 +3191,7 @@
            at process_kern.c:161
        161       _switch_to(prev, next);
        (gdb)
-       #4  0x10001d12 in schedule () at sched.c:777
+       #4  0x10001d12 in schedule () at core.c:777
        777             switch_to(prev, next, prev);
        (gdb)
        #5  0x1006a744 in __down (sem=0x507d241c) at semaphore.c:71
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/vm/pagemap.txt linux-libre-3.11-rc7-gnu/Documentation/vm/pagemap.txt
--- linux-libre-3.10-gnu/Documentation/vm/pagemap.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/vm/pagemap.txt	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,8 @@ There are three components to pagemap:
     * Bits 0-54  page frame number (PFN) if present
     * Bits 0-4   swap type if swapped
     * Bits 5-54  swap offset if swapped
-    * Bits 55-60 page shift (page size = 1<<page shift)
+    * Bit  55    pte is soft-dirty (see Documentation/vm/soft-dirty.txt)
+    * Bits 56-60 zero
     * Bit  61    page is file-page or shared-anon
     * Bit  62    page swapped
     * Bit  63    page present
@@ -147,5 +148,5 @@ once.
 Other notes:
 
 Reading from any of the files will return -EINVAL if you are not starting
-the read on an 8-byte boundary (e.g., if you seeked an odd number of bytes
+the read on an 8-byte boundary (e.g., if you sought an odd number of bytes
 into the file), or if the size of the read is not a multiple of 8 bytes.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/vm/soft-dirty.txt linux-libre-3.11-rc7-gnu/Documentation/vm/soft-dirty.txt
--- linux-libre-3.10-gnu/Documentation/vm/soft-dirty.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/vm/soft-dirty.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,36 @@
+                            SOFT-DIRTY PTEs
+
+  The soft-dirty is a bit on a PTE which helps to track which pages a task
+writes to. In order to do this tracking one should
+
+  1. Clear soft-dirty bits from the task's PTEs.
+
+     This is done by writing "4" into the /proc/PID/clear_refs file of the
+     task in question.
+
+  2. Wait some time.
+
+  3. Read soft-dirty bits from the PTEs.
+
+     This is done by reading from the /proc/PID/pagemap. The bit 55 of the
+     64-bit qword is the soft-dirty one. If set, the respective PTE was
+     written to since step 1.
+
+
+  Internally, to do this tracking, the writable bit is cleared from PTEs
+when the soft-dirty bit is cleared. So, after this, when the task tries to
+modify a page at some virtual address the #PF occurs and the kernel sets
+the soft-dirty bit on the respective PTE.
+
+  Note, that although all the task's address space is marked as r/o after the
+soft-dirty bits clear, the #PF-s that occur after that are processed fast.
+This is so, since the pages are still mapped to physical memory, and thus all
+the kernel does is finds this fact out and puts both writable and soft-dirty
+bits on the PTE.
+
+
+  This feature is actively used by the checkpoint-restore project. You
+can find more details about it on http://criu.org
+
+
+-- Pavel Emelyanov, Apr 9, 2013
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/vm/transhuge.txt linux-libre-3.11-rc7-gnu/Documentation/vm/transhuge.txt
--- linux-libre-3.10-gnu/Documentation/vm/transhuge.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/vm/transhuge.txt	2013-08-25 20:43:22.000000000 -0400
@@ -120,8 +120,8 @@ By default kernel tries to use huge zero
 It's possible to disable huge zero page by writing 0 or enable it
 back by writing 1:
 
-echo 0 >/sys/kernel/mm/transparent_hugepage/khugepaged/use_zero_page
-echo 1 >/sys/kernel/mm/transparent_hugepage/khugepaged/use_zero_page
+echo 0 >/sys/kernel/mm/transparent_hugepage/use_zero_page
+echo 1 >/sys/kernel/mm/transparent_hugepage/use_zero_page
 
 khugepaged will be automatically started when
 transparent_hugepage/enabled is set to "always" or "madvise, and it'll
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/vm/zswap.txt linux-libre-3.11-rc7-gnu/Documentation/vm/zswap.txt
--- linux-libre-3.10-gnu/Documentation/vm/zswap.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/vm/zswap.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,68 @@
+Overview:
+
+Zswap is a lightweight compressed cache for swap pages. It takes pages that are
+in the process of being swapped out and attempts to compress them into a
+dynamically allocated RAM-based memory pool.  zswap basically trades CPU cycles
+for potentially reduced swap I/O.  This trade-off can also result in a
+significant performance improvement if reads from the compressed cache are
+faster than reads from a swap device.
+
+NOTE: Zswap is a new feature as of v3.11 and interacts heavily with memory
+reclaim.  This interaction has not be fully explored on the large set of
+potential configurations and workloads that exist.  For this reason, zswap
+is a work in progress and should be considered experimental.
+
+Some potential benefits:
+* Desktop/laptop users with limited RAM capacities can mitigate the
+    performance impact of swapping.
+* Overcommitted guests that share a common I/O resource can
+    dramatically reduce their swap I/O pressure, avoiding heavy handed I/O
+    throttling by the hypervisor. This allows more work to get done with less
+    impact to the guest workload and guests sharing the I/O subsystem
+* Users with SSDs as swap devices can extend the life of the device by
+    drastically reducing life-shortening writes.
+
+Zswap evicts pages from compressed cache on an LRU basis to the backing swap
+device when the compressed pool reaches it size limit.  This requirement had
+been identified in prior community discussions.
+
+To enabled zswap, the "enabled" attribute must be set to 1 at boot time.  e.g.
+zswap.enabled=1
+
+Design:
+
+Zswap receives pages for compression through the Frontswap API and is able to
+evict pages from its own compressed pool on an LRU basis and write them back to
+the backing swap device in the case that the compressed pool is full.
+
+Zswap makes use of zbud for the managing the compressed memory pool.  Each
+allocation in zbud is not directly accessible by address.  Rather, a handle is
+return by the allocation routine and that handle must be mapped before being
+accessed.  The compressed memory pool grows on demand and shrinks as compressed
+pages are freed.  The pool is not preallocated.
+
+When a swap page is passed from frontswap to zswap, zswap maintains a mapping
+of the swap entry, a combination of the swap type and swap offset, to the zbud
+handle that references that compressed swap page.  This mapping is achieved
+with a red-black tree per swap type.  The swap offset is the search key for the
+tree nodes.
+
+During a page fault on a PTE that is a swap entry, frontswap calls the zswap
+load function to decompress the page into the page allocated by the page fault
+handler.
+
+Once there are no PTEs referencing a swap page stored in zswap (i.e. the count
+in the swap_map goes to 0) the swap code calls the zswap invalidate function,
+via frontswap, to free the compressed entry.
+
+Zswap seeks to be simple in its policies.  Sysfs attributes allow for one user
+controlled policies:
+* max_pool_percent - The maximum percentage of memory that the compressed
+    pool can occupy.
+
+Zswap allows the compressor to be selected at kernel boot time by setting the
+“compressor” attribute.  The default compressor is lzo.  e.g.
+zswap.compressor=deflate
+
+A debugfs interface is provided for various statistic about pool size, number
+of pages stored, and various counters for the reasons pages are rejected.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/w1/slaves/w1_ds28e04 linux-libre-3.11-rc7-gnu/Documentation/w1/slaves/w1_ds28e04
--- linux-libre-3.10-gnu/Documentation/w1/slaves/w1_ds28e04	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/w1/slaves/w1_ds28e04	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@ Memory Access
 
 	A write operation on the "eeprom" file writes the given byte sequence
 	to the EEPROM of the DS28E04. If CRC checking mode is enabled only
-	fully alligned blocks of 32 bytes with valid CRC16 values (in bytes 30
+	fully aligned blocks of 32 bytes with valid CRC16 values (in bytes 30
 	and 31) are allowed to be written.
 
 PIO Access
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/w1/w1.generic linux-libre-3.11-rc7-gnu/Documentation/w1/w1.generic
--- linux-libre-3.10-gnu/Documentation/w1/w1.generic	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/w1/w1.generic	2013-08-25 20:43:22.000000000 -0400
@@ -25,8 +25,8 @@ When a w1 master driver registers with t
  - sysfs entries for that w1 master are created
  - the w1 bus is periodically searched for new slave devices
 
-When a device is found on the bus, w1 core checks if driver for its family is
-loaded. If so, the family driver is attached to the slave.
+When a device is found on the bus, w1 core tries to load the driver for its family
+and check if it is loaded. If so, the family driver is attached to the slave.
 If there is no driver for the family, default one is assigned, which allows to perform
 almost any kind of operations. Each logical operation is a transaction
 in nature, which can contain several (two or one) low-level operations.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/watchdog/watchdog-parameters.txt linux-libre-3.11-rc7-gnu/Documentation/watchdog/watchdog-parameters.txt
--- linux-libre-3.10-gnu/Documentation/watchdog/watchdog-parameters.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/watchdog/watchdog-parameters.txt	2013-08-25 20:43:22.000000000 -0400
@@ -194,14 +194,6 @@ reset: Watchdog Interrupt/Reset Mode. 0
 nowayout: Watchdog cannot be stopped once started
 	(default=kernel config parameter)
 -------------------------------------------------
-mpcore_wdt:
-mpcore_margin: MPcore timer margin in seconds.
-	(0 < mpcore_margin < 65536, default=60)
-nowayout: Watchdog cannot be stopped once started
-	(default=kernel config parameter)
-mpcore_noboot: MPcore watchdog action, set to 1 to ignore reboots,
-	0 to reboot (default=0
--------------------------------------------------
 mv64x60_wdt:
 nowayout: Watchdog cannot be stopped once started
 	(default=kernel config parameter)
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/ww-mutex-design.txt linux-libre-3.11-rc7-gnu/Documentation/ww-mutex-design.txt
--- linux-libre-3.10-gnu/Documentation/ww-mutex-design.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/Documentation/ww-mutex-design.txt	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,344 @@
+Wait/Wound Deadlock-Proof Mutex Design
+======================================
+
+Please read mutex-design.txt first, as it applies to wait/wound mutexes too.
+
+Motivation for WW-Mutexes
+-------------------------
+
+GPU's do operations that commonly involve many buffers.  Those buffers
+can be shared across contexts/processes, exist in different memory
+domains (for example VRAM vs system memory), and so on.  And with
+PRIME / dmabuf, they can even be shared across devices.  So there are
+a handful of situations where the driver needs to wait for buffers to
+become ready.  If you think about this in terms of waiting on a buffer
+mutex for it to become available, this presents a problem because
+there is no way to guarantee that buffers appear in a execbuf/batch in
+the same order in all contexts.  That is directly under control of
+userspace, and a result of the sequence of GL calls that an application
+makes.	Which results in the potential for deadlock.  The problem gets
+more complex when you consider that the kernel may need to migrate the
+buffer(s) into VRAM before the GPU operates on the buffer(s), which
+may in turn require evicting some other buffers (and you don't want to
+evict other buffers which are already queued up to the GPU), but for a
+simplified understanding of the problem you can ignore this.
+
+The algorithm that the TTM graphics subsystem came up with for dealing with
+this problem is quite simple.  For each group of buffers (execbuf) that need
+to be locked, the caller would be assigned a unique reservation id/ticket,
+from a global counter.  In case of deadlock while locking all the buffers
+associated with a execbuf, the one with the lowest reservation ticket (i.e.
+the oldest task) wins, and the one with the higher reservation id (i.e. the
+younger task) unlocks all of the buffers that it has already locked, and then
+tries again.
+
+In the RDBMS literature this deadlock handling approach is called wait/wound:
+The older tasks waits until it can acquire the contended lock. The younger tasks
+needs to back off and drop all the locks it is currently holding, i.e. the
+younger task is wounded.
+
+Concepts
+--------
+
+Compared to normal mutexes two additional concepts/objects show up in the lock
+interface for w/w mutexes:
+
+Acquire context: To ensure eventual forward progress it is important the a task
+trying to acquire locks doesn't grab a new reservation id, but keeps the one it
+acquired when starting the lock acquisition. This ticket is stored in the
+acquire context. Furthermore the acquire context keeps track of debugging state
+to catch w/w mutex interface abuse.
+
+W/w class: In contrast to normal mutexes the lock class needs to be explicit for
+w/w mutexes, since it is required to initialize the acquire context.
+
+Furthermore there are three different class of w/w lock acquire functions:
+
+* Normal lock acquisition with a context, using ww_mutex_lock.
+
+* Slowpath lock acquisition on the contending lock, used by the wounded task
+  after having dropped all already acquired locks. These functions have the
+  _slow postfix.
+
+  From a simple semantics point-of-view the _slow functions are not strictly
+  required, since simply calling the normal ww_mutex_lock functions on the
+  contending lock (after having dropped all other already acquired locks) will
+  work correctly. After all if no other ww mutex has been acquired yet there's
+  no deadlock potential and hence the ww_mutex_lock call will block and not
+  prematurely return -EDEADLK. The advantage of the _slow functions is in
+  interface safety:
+  - ww_mutex_lock has a __must_check int return type, whereas ww_mutex_lock_slow
+    has a void return type. Note that since ww mutex code needs loops/retries
+    anyway the __must_check doesn't result in spurious warnings, even though the
+    very first lock operation can never fail.
+  - When full debugging is enabled ww_mutex_lock_slow checks that all acquired
+    ww mutex have been released (preventing deadlocks) and makes sure that we
+    block on the contending lock (preventing spinning through the -EDEADLK
+    slowpath until the contended lock can be acquired).
+
+* Functions to only acquire a single w/w mutex, which results in the exact same
+  semantics as a normal mutex. This is done by calling ww_mutex_lock with a NULL
+  context.
+
+  Again this is not strictly required. But often you only want to acquire a
+  single lock in which case it's pointless to set up an acquire context (and so
+  better to avoid grabbing a deadlock avoidance ticket).
+
+Of course, all the usual variants for handling wake-ups due to signals are also
+provided.
+
+Usage
+-----
+
+Three different ways to acquire locks within the same w/w class. Common
+definitions for methods #1 and #2:
+
+static DEFINE_WW_CLASS(ww_class);
+
+struct obj {
+	struct ww_mutex lock;
+	/* obj data */
+};
+
+struct obj_entry {
+	struct list_head head;
+	struct obj *obj;
+};
+
+Method 1, using a list in execbuf->buffers that's not allowed to be reordered.
+This is useful if a list of required objects is already tracked somewhere.
+Furthermore the lock helper can use propagate the -EALREADY return code back to
+the caller as a signal that an object is twice on the list. This is useful if
+the list is constructed from userspace input and the ABI requires userspace to
+not have duplicate entries (e.g. for a gpu commandbuffer submission ioctl).
+
+int lock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
+{
+	struct obj *res_obj = NULL;
+	struct obj_entry *contended_entry = NULL;
+	struct obj_entry *entry;
+
+	ww_acquire_init(ctx, &ww_class);
+
+retry:
+	list_for_each_entry (entry, list, head) {
+		if (entry->obj == res_obj) {
+			res_obj = NULL;
+			continue;
+		}
+		ret = ww_mutex_lock(&entry->obj->lock, ctx);
+		if (ret < 0) {
+			contended_entry = entry;
+			goto err;
+		}
+	}
+
+	ww_acquire_done(ctx);
+	return 0;
+
+err:
+	list_for_each_entry_continue_reverse (entry, list, head)
+		ww_mutex_unlock(&entry->obj->lock);
+
+	if (res_obj)
+		ww_mutex_unlock(&res_obj->lock);
+
+	if (ret == -EDEADLK) {
+		/* we lost out in a seqno race, lock and retry.. */
+		ww_mutex_lock_slow(&contended_entry->obj->lock, ctx);
+		res_obj = contended_entry->obj;
+		goto retry;
+	}
+	ww_acquire_fini(ctx);
+
+	return ret;
+}
+
+Method 2, using a list in execbuf->buffers that can be reordered. Same semantics
+of duplicate entry detection using -EALREADY as method 1 above. But the
+list-reordering allows for a bit more idiomatic code.
+
+int lock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
+{
+	struct obj_entry *entry, *entry2;
+
+	ww_acquire_init(ctx, &ww_class);
+
+	list_for_each_entry (entry, list, head) {
+		ret = ww_mutex_lock(&entry->obj->lock, ctx);
+		if (ret < 0) {
+			entry2 = entry;
+
+			list_for_each_entry_continue_reverse (entry2, list, head)
+				ww_mutex_unlock(&entry2->obj->lock);
+
+			if (ret != -EDEADLK) {
+				ww_acquire_fini(ctx);
+				return ret;
+			}
+
+			/* we lost out in a seqno race, lock and retry.. */
+			ww_mutex_lock_slow(&entry->obj->lock, ctx);
+
+			/*
+			 * Move buf to head of the list, this will point
+			 * buf->next to the first unlocked entry,
+			 * restarting the for loop.
+			 */
+			list_del(&entry->head);
+			list_add(&entry->head, list);
+		}
+	}
+
+	ww_acquire_done(ctx);
+	return 0;
+}
+
+Unlocking works the same way for both methods #1 and #2:
+
+void unlock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
+{
+	struct obj_entry *entry;
+
+	list_for_each_entry (entry, list, head)
+		ww_mutex_unlock(&entry->obj->lock);
+
+	ww_acquire_fini(ctx);
+}
+
+Method 3 is useful if the list of objects is constructed ad-hoc and not upfront,
+e.g. when adjusting edges in a graph where each node has its own ww_mutex lock,
+and edges can only be changed when holding the locks of all involved nodes. w/w
+mutexes are a natural fit for such a case for two reasons:
+- They can handle lock-acquisition in any order which allows us to start walking
+  a graph from a starting point and then iteratively discovering new edges and
+  locking down the nodes those edges connect to.
+- Due to the -EALREADY return code signalling that a given objects is already
+  held there's no need for additional book-keeping to break cycles in the graph
+  or keep track off which looks are already held (when using more than one node
+  as a starting point).
+
+Note that this approach differs in two important ways from the above methods:
+- Since the list of objects is dynamically constructed (and might very well be
+  different when retrying due to hitting the -EDEADLK wound condition) there's
+  no need to keep any object on a persistent list when it's not locked. We can
+  therefore move the list_head into the object itself.
+- On the other hand the dynamic object list construction also means that the -EALREADY return
+  code can't be propagated.
+
+Note also that methods #1 and #2 and method #3 can be combined, e.g. to first lock a
+list of starting nodes (passed in from userspace) using one of the above
+methods. And then lock any additional objects affected by the operations using
+method #3 below. The backoff/retry procedure will be a bit more involved, since
+when the dynamic locking step hits -EDEADLK we also need to unlock all the
+objects acquired with the fixed list. But the w/w mutex debug checks will catch
+any interface misuse for these cases.
+
+Also, method 3 can't fail the lock acquisition step since it doesn't return
+-EALREADY. Of course this would be different when using the _interruptible
+variants, but that's outside of the scope of these examples here.
+
+struct obj {
+	struct ww_mutex ww_mutex;
+	struct list_head locked_list;
+};
+
+static DEFINE_WW_CLASS(ww_class);
+
+void __unlock_objs(struct list_head *list)
+{
+	struct obj *entry, *temp;
+
+	list_for_each_entry_safe (entry, temp, list, locked_list) {
+		/* need to do that before unlocking, since only the current lock holder is
+		allowed to use object */
+		list_del(&entry->locked_list);
+		ww_mutex_unlock(entry->ww_mutex)
+	}
+}
+
+void lock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
+{
+	struct obj *obj;
+
+	ww_acquire_init(ctx, &ww_class);
+
+retry:
+	/* re-init loop start state */
+	loop {
+		/* magic code which walks over a graph and decides which objects
+		 * to lock */
+
+		ret = ww_mutex_lock(obj->ww_mutex, ctx);
+		if (ret == -EALREADY) {
+			/* we have that one already, get to the next object */
+			continue;
+		}
+		if (ret == -EDEADLK) {
+			__unlock_objs(list);
+
+			ww_mutex_lock_slow(obj, ctx);
+			list_add(&entry->locked_list, list);
+			goto retry;
+		}
+
+		/* locked a new object, add it to the list */
+		list_add_tail(&entry->locked_list, list);
+	}
+
+	ww_acquire_done(ctx);
+	return 0;
+}
+
+void unlock_objs(struct list_head *list, struct ww_acquire_ctx *ctx)
+{
+	__unlock_objs(list);
+	ww_acquire_fini(ctx);
+}
+
+Method 4: Only lock one single objects. In that case deadlock detection and
+prevention is obviously overkill, since with grabbing just one lock you can't
+produce a deadlock within just one class. To simplify this case the w/w mutex
+api can be used with a NULL context.
+
+Implementation Details
+----------------------
+
+Design:
+  ww_mutex currently encapsulates a struct mutex, this means no extra overhead for
+  normal mutex locks, which are far more common. As such there is only a small
+  increase in code size if wait/wound mutexes are not used.
+
+  In general, not much contention is expected. The locks are typically used to
+  serialize access to resources for devices. The only way to make wakeups
+  smarter would be at the cost of adding a field to struct mutex_waiter. This
+  would add overhead to all cases where normal mutexes are used, and
+  ww_mutexes are generally less performance sensitive.
+
+Lockdep:
+  Special care has been taken to warn for as many cases of api abuse
+  as possible. Some common api abuses will be caught with
+  CONFIG_DEBUG_MUTEXES, but CONFIG_PROVE_LOCKING is recommended.
+
+  Some of the errors which will be warned about:
+   - Forgetting to call ww_acquire_fini or ww_acquire_init.
+   - Attempting to lock more mutexes after ww_acquire_done.
+   - Attempting to lock the wrong mutex after -EDEADLK and
+     unlocking all mutexes.
+   - Attempting to lock the right mutex after -EDEADLK,
+     before unlocking all mutexes.
+
+   - Calling ww_mutex_lock_slow before -EDEADLK was returned.
+
+   - Unlocking mutexes with the wrong unlock function.
+   - Calling one of the ww_acquire_* twice on the same context.
+   - Using a different ww_class for the mutex than for the ww_acquire_ctx.
+   - Normal lockdep errors that can result in deadlocks.
+
+  Some of the lockdep errors that can result in deadlocks:
+   - Calling ww_acquire_init to initialize a second ww_acquire_ctx before
+     having called ww_acquire_fini on the first.
+   - 'normal' deadlocks that can occur.
+
+FIXME: Update this section once we have the TASK_DEADLOCK task state flag magic
+implemented.
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/x86/boot.txt linux-libre-3.11-rc7-gnu/Documentation/x86/boot.txt
--- linux-libre-3.10-gnu/Documentation/x86/boot.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/x86/boot.txt	2013-08-25 20:43:22.000000000 -0400
@@ -657,9 +657,10 @@ Protocol:	2.08+
   uncompressed data should be determined using the standard magic
   numbers.  The currently supported compression formats are gzip
   (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), LZMA
-  (magic number 5D 00), and XZ (magic number FD 37).  The uncompressed
-  payload is currently always ELF (magic number 7F 45 4C 46).
-  
+  (magic number 5D 00), XZ (magic number FD 37), and LZ4 (magic number
+  02 21).  The uncompressed payload is currently always ELF (magic
+  number 7F 45 4C 46).
+
 Field name:	payload_length
 Type:		read
 Offset/size:	0x24c/4
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/x86/early-microcode.txt linux-libre-3.11-rc7-gnu/Documentation/x86/early-microcode.txt
--- linux-libre-3.10-gnu/Documentation/x86/early-microcode.txt	2013-07-01 10:31:23.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/x86/early-microcode.txt	2013-08-31 17:50:42.000000000 -0400
@@ -11,7 +11,8 @@ file and loaded to CPUs during boot time
 The format of the combined initrd image is microcode in cpio format followed by
 the initrd image (maybe compressed). Kernel parses the combined initrd image
 during boot time. The microcode file in cpio name space is:
-/*(DEBLOBBED)*/
+on Intel: /*(DEBLOBBED)*/
+on AMD  : /*(DEBLOBBED)*/
 
 During BSP boot (before SMP starts), if the kernel finds the microcode file in
 the initrd file, it parses the microcode and saves matching microcode in memory.
@@ -34,10 +35,8 @@ original initrd image /boot/initrd-3.5.0
 
 mkdir initrd
 cd initrd
-mkdir kernel
-mkdir kernel/x86
-mkdir kernel/x86/microcode
-cp ../microcode.bin /*(DEBLOBBED)*/
-find .|cpio -oc >../ucode.cpio
+mkdir -p kernel/x86/microcode
+cp ../microcode.bin /*(DEBLOBBED)*/ (or /*(DEBLOBBED)*/)
+find . | cpio -o -H newc >../ucode.cpio
 cd ..
 cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img
diff -druNp --no-dereference linux-libre-3.10-gnu/Documentation/zh_CN/video4linux/v4l2-framework.txt linux-libre-3.11-rc7-gnu/Documentation/zh_CN/video4linux/v4l2-framework.txt
--- linux-libre-3.10-gnu/Documentation/zh_CN/video4linux/v4l2-framework.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/Documentation/zh_CN/video4linux/v4l2-framework.txt	2013-08-25 20:43:22.000000000 -0400
@@ -247,7 +247,6 @@ 不支持该类函数中的任何一个�
 这些结构体定义如下：
 
 struct v4l2_subdev_core_ops {
-	int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
 	int (*log_status)(struct v4l2_subdev *sd);
 	int (*init)(struct v4l2_subdev *sd, u32 val);
 	...
@@ -337,24 +336,24 @@ 此后，子设备模块就可卸载，�
 
 注册之设备后，可通过以下方式直接调用其操作函数：
 
-	err = sd->ops->core->g_chip_ident(sd, &chip);
+	err = sd->ops->core->g_std(sd, &norm);
 
 但使用如下宏会比较容易且合适：
 
-	err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
+	err = v4l2_subdev_call(sd, core, g_std, &norm);
 
 这个宏将会做 NULL 指针检查，如果 subdev 为 NULL，则返回-ENODEV；如果
-subdev->core 或 subdev->core->g_chip_ident 为 NULL，则返回 -ENOIOCTLCMD；
-否则将返回 subdev->ops->core->g_chip_ident ops 调用的实际结果。
+subdev->core 或 subdev->core->g_std 为 NULL，则返回 -ENOIOCTLCMD；
+否则将返回 subdev->ops->core->g_std ops 调用的实际结果。
 
 有时也可能同时调用所有或一系列子设备的某个操作函数：
 
-	v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
+	v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm);
 
 任何不支持此操作的子设备都会被跳过，并忽略错误返回值。但如果你需要
 检查出错码，则可使用如下函数：
 
-	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
+	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm);
 
 除 -ENOIOCTLCMD 外的任何错误都会跳出循环并返回错误值。如果（除 -ENOIOCTLCMD
 外）没有错误发生，则返回 0。
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/accessibility/braille/braille_console.c linux-libre-3.11-rc7-gnu/drivers/accessibility/braille/braille_console.c
--- linux-libre-3.10-gnu/drivers/accessibility/braille/braille_console.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/accessibility/braille/braille_console.c	2013-08-25 20:43:22.000000000 -0400
@@ -359,6 +359,9 @@ int braille_register_console(struct cons
 		char *console_options, char *braille_options)
 {
 	int ret;
+
+	if (!(console->flags & CON_BRL))
+		return 0;
 	if (!console_options)
 		/* Only support VisioBraille for now */
 		console_options = "57600o8";
@@ -374,15 +377,17 @@ int braille_register_console(struct cons
 	braille_co = console;
 	register_keyboard_notifier(&keyboard_notifier_block);
 	register_vt_notifier(&vt_notifier_block);
-	return 0;
+	return 1;
 }
 
 int braille_unregister_console(struct console *console)
 {
 	if (braille_co != console)
 		return -EINVAL;
+	if (!(console->flags & CON_BRL))
+		return 0;
 	unregister_keyboard_notifier(&keyboard_notifier_block);
 	unregister_vt_notifier(&vt_notifier_block);
 	braille_co = NULL;
-	return 0;
+	return 1;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/acglobal.h linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acglobal.h
--- linux-libre-3.10-gnu/drivers/acpi/acpica/acglobal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acglobal.h	2013-08-25 20:43:22.000000000 -0400
@@ -132,6 +132,12 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io
  */
 u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_auto_repair, FALSE);
 
+/*
+ * Optionally do not load any SSDTs from the RSDT/XSDT during initialization.
+ * This can be useful for debugging ACPI problems on some machines.
+ */
+u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_ssdt_table_load, FALSE);
+
 /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */
 
 struct acpi_table_fadt acpi_gbl_FADT;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/aclocal.h linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/aclocal.h
--- linux-libre-3.10-gnu/drivers/acpi/acpica/aclocal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/aclocal.h	2013-08-25 20:43:22.000000000 -0400
@@ -362,23 +362,6 @@ union acpi_predefined_info {
 
 #pragma pack()
 
-/* Data block used during object validation */
-
-struct acpi_predefined_data {
-	char *pathname;
-	const union acpi_predefined_info *predefined;
-	union acpi_operand_object *parent_package;
-	struct acpi_namespace_node *node;
-	u32 flags;
-	u32 return_btype;
-	u8 node_flags;
-};
-
-/* Defines for Flags field above */
-
-#define ACPI_OBJECT_REPAIRED    1
-#define ACPI_OBJECT_WRAPPED     2
-
 /* Return object auto-repair info */
 
 typedef acpi_status(*acpi_object_converter) (union acpi_operand_object
@@ -948,19 +931,6 @@ struct acpi_bit_register_info {
 
 /* Structs and definitions for _OSI support and I/O port validation */
 
-#define ACPI_OSI_WIN_2000               0x01
-#define ACPI_OSI_WIN_XP                 0x02
-#define ACPI_OSI_WIN_XP_SP1             0x03
-#define ACPI_OSI_WINSRV_2003            0x04
-#define ACPI_OSI_WIN_XP_SP2             0x05
-#define ACPI_OSI_WINSRV_2003_SP1        0x06
-#define ACPI_OSI_WIN_VISTA              0x07
-#define ACPI_OSI_WINSRV_2008            0x08
-#define ACPI_OSI_WIN_VISTA_SP1          0x09
-#define ACPI_OSI_WIN_VISTA_SP2          0x0A
-#define ACPI_OSI_WIN_7                  0x0B
-#define ACPI_OSI_WIN_8                  0x0C
-
 #define ACPI_ALWAYS_ILLEGAL             0x00
 
 struct acpi_interface_info {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/acmacros.h linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acmacros.h
--- linux-libre-3.10-gnu/drivers/acpi/acpica/acmacros.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acmacros.h	2013-08-25 20:43:22.000000000 -0400
@@ -374,10 +374,11 @@
  * the plist contains a set of parens to allow variable-length lists.
  * These macros are used for both the debug and non-debug versions of the code.
  */
-#define ACPI_ERROR_NAMESPACE(s, e)      acpi_ut_namespace_error (AE_INFO, s, e);
-#define ACPI_ERROR_METHOD(s, n, p, e)   acpi_ut_method_error (AE_INFO, s, n, p, e);
-#define ACPI_WARN_PREDEFINED(plist)     acpi_ut_predefined_warning plist
-#define ACPI_INFO_PREDEFINED(plist)     acpi_ut_predefined_info plist
+#define ACPI_ERROR_NAMESPACE(s, e)          acpi_ut_namespace_error (AE_INFO, s, e);
+#define ACPI_ERROR_METHOD(s, n, p, e)       acpi_ut_method_error (AE_INFO, s, n, p, e);
+#define ACPI_WARN_PREDEFINED(plist)         acpi_ut_predefined_warning plist
+#define ACPI_INFO_PREDEFINED(plist)         acpi_ut_predefined_info plist
+#define ACPI_BIOS_ERROR_PREDEFINED(plist)   acpi_ut_predefined_bios_error plist
 
 #else
 
@@ -387,6 +388,7 @@
 #define ACPI_ERROR_METHOD(s, n, p, e)
 #define ACPI_WARN_PREDEFINED(plist)
 #define ACPI_INFO_PREDEFINED(plist)
+#define ACPI_BIOS_ERROR_PREDEFINED(plist)
 
 #endif				/* ACPI_NO_ERROR_MESSAGES */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/acnamesp.h linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acnamesp.h
--- linux-libre-3.10-gnu/drivers/acpi/acpica/acnamesp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acnamesp.h	2013-08-25 20:43:22.000000000 -0400
@@ -223,22 +223,33 @@ acpi_status acpi_ns_evaluate(struct acpi
 void acpi_ns_exec_module_code_list(void);
 
 /*
- * nspredef - Support for predefined/reserved names
+ * nsarguments - Argument count/type checking for predefined/reserved names
  */
-acpi_status
-acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
-			       u32 user_param_count,
-			       acpi_status return_status,
-			       union acpi_operand_object **return_object);
+void
+acpi_ns_check_argument_count(char *pathname,
+			     struct acpi_namespace_node *node,
+			     u32 user_param_count,
+			     const union acpi_predefined_info *info);
 
 void
-acpi_ns_check_parameter_count(char *pathname,
+acpi_ns_check_acpi_compliance(char *pathname,
 			      struct acpi_namespace_node *node,
-			      u32 user_param_count,
-			      const union acpi_predefined_info *info);
+			      const union acpi_predefined_info *predefined);
 
+void acpi_ns_check_argument_types(struct acpi_evaluate_info *info);
+
+/*
+ * nspredef - Return value checking for predefined/reserved names
+ */
 acpi_status
-acpi_ns_check_object_type(struct acpi_predefined_data *data,
+acpi_ns_check_return_value(struct acpi_namespace_node *node,
+			   struct acpi_evaluate_info *info,
+			   u32 user_param_count,
+			   acpi_status return_status,
+			   union acpi_operand_object **return_object);
+
+acpi_status
+acpi_ns_check_object_type(struct acpi_evaluate_info *info,
 			  union acpi_operand_object **return_object_ptr,
 			  u32 expected_btypes, u32 package_index);
 
@@ -246,7 +257,7 @@ acpi_ns_check_object_type(struct acpi_pr
  * nsprepkg - Validation of predefined name packages
  */
 acpi_status
-acpi_ns_check_package(struct acpi_predefined_data *data,
+acpi_ns_check_package(struct acpi_evaluate_info *info,
 		      union acpi_operand_object **return_object_ptr);
 
 /*
@@ -308,24 +319,24 @@ acpi_ns_get_attached_data(struct acpi_na
  * predefined methods/objects
  */
 acpi_status
-acpi_ns_simple_repair(struct acpi_predefined_data *data,
+acpi_ns_simple_repair(struct acpi_evaluate_info *info,
 		      u32 expected_btypes,
 		      u32 package_index,
 		      union acpi_operand_object **return_object_ptr);
 
 acpi_status
-acpi_ns_wrap_with_package(struct acpi_predefined_data *data,
+acpi_ns_wrap_with_package(struct acpi_evaluate_info *info,
 			  union acpi_operand_object *original_object,
 			  union acpi_operand_object **obj_desc_ptr);
 
 acpi_status
-acpi_ns_repair_null_element(struct acpi_predefined_data *data,
+acpi_ns_repair_null_element(struct acpi_evaluate_info *info,
 			    u32 expected_btypes,
 			    u32 package_index,
 			    union acpi_operand_object **return_object_ptr);
 
 void
-acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
+acpi_ns_remove_null_elements(struct acpi_evaluate_info *info,
 			     u8 package_type,
 			     union acpi_operand_object *obj_desc);
 
@@ -334,7 +345,7 @@ acpi_ns_remove_null_elements(struct acpi
  * predefined methods/objects
  */
 acpi_status
-acpi_ns_complex_repairs(struct acpi_predefined_data *data,
+acpi_ns_complex_repairs(struct acpi_evaluate_info *info,
 			struct acpi_namespace_node *node,
 			acpi_status validate_status,
 			union acpi_operand_object **return_object_ptr);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/acpredef.h linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acpredef.h
--- linux-libre-3.10-gnu/drivers/acpi/acpica/acpredef.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acpredef.h	2013-08-25 20:43:22.000000000 -0400
@@ -128,8 +128,8 @@ enum acpi_return_package_types {
 #define ARG_COUNT_IS_MINIMUM            0x8000
 #define METHOD_MAX_ARG_TYPE             ACPI_TYPE_PACKAGE
 
-#define METHOD_GET_COUNT(arg_list)      (arg_list & METHOD_ARG_MASK)
-#define METHOD_GET_NEXT_ARG(arg_list)   (arg_list >> METHOD_ARG_BIT_WIDTH)
+#define METHOD_GET_ARG_COUNT(arg_list)  ((arg_list) & METHOD_ARG_MASK)
+#define METHOD_GET_NEXT_TYPE(arg_list)  (((arg_list) >>= METHOD_ARG_BIT_WIDTH) & METHOD_ARG_MASK)
 
 /* Macros used to build the predefined info table */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/acstruct.h linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acstruct.h
--- linux-libre-3.10-gnu/drivers/acpi/acpica/acstruct.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acstruct.h	2013-08-25 20:43:22.000000000 -0400
@@ -178,25 +178,41 @@ union acpi_aml_operands {
 };
 
 /*
- * Structure used to pass object evaluation parameters.
+ * Structure used to pass object evaluation information and parameters.
  * Purpose is to reduce CPU stack use.
  */
 struct acpi_evaluate_info {
-	struct acpi_namespace_node *prefix_node;
-	char *pathname;
-	union acpi_operand_object *obj_desc;
-	union acpi_operand_object **parameters;
-	struct acpi_namespace_node *resolved_node;
-	union acpi_operand_object *return_object;
-	u8 param_count;
-	u8 pass_number;
-	u8 return_object_type;
-	u8 flags;
+	/* The first 3 elements are passed by the caller to acpi_ns_evaluate */
+
+	struct acpi_namespace_node *prefix_node;	/* Input: starting node */
+	char *relative_pathname;	/* Input: path relative to prefix_node */
+	union acpi_operand_object **parameters;	/* Input: argument list */
+
+	struct acpi_namespace_node *node;	/* Resolved node (prefix_node:relative_pathname) */
+	union acpi_operand_object *obj_desc;	/* Object attached to the resolved node */
+	char *full_pathname;	/* Full pathname of the resolved node */
+
+	const union acpi_predefined_info *predefined;	/* Used if Node is a predefined name */
+	union acpi_operand_object *return_object;	/* Object returned from the evaluation */
+	union acpi_operand_object *parent_package;	/* Used if return object is a Package */
+
+	u32 return_flags;	/* Used for return value analysis */
+	u32 return_btype;	/* Bitmapped type of the returned object */
+	u16 param_count;	/* Count of the input argument list */
+	u8 pass_number;		/* Parser pass number */
+	u8 return_object_type;	/* Object type of the returned object */
+	u8 node_flags;		/* Same as Node->Flags */
+	u8 flags;		/* General flags */
 };
 
 /* Values for Flags above */
 
-#define ACPI_IGNORE_RETURN_VALUE        1
+#define ACPI_IGNORE_RETURN_VALUE    1
+
+/* Defines for return_flags field above */
+
+#define ACPI_OBJECT_REPAIRED        1
+#define ACPI_OBJECT_WRAPPED         2
 
 /* Info used by acpi_ns_initialize_devices */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/acutils.h linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acutils.h
--- linux-libre-3.10-gnu/drivers/acpi/acpica/acutils.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/acutils.h	2013-08-25 20:43:22.000000000 -0400
@@ -87,6 +87,48 @@ extern const char *acpi_gbl_fc_decode[];
 extern const char *acpi_gbl_pt_decode[];
 #endif
 
+/*
+ * For the iASL compiler case, the output is redirected to stderr so that
+ * any of the various ACPI errors and warnings do not appear in the output
+ * files, for either the compiler or disassembler portions of the tool.
+ */
+#ifdef ACPI_ASL_COMPILER
+
+#include <stdio.h>
+extern FILE *acpi_gbl_output_file;
+
+#define ACPI_MSG_REDIRECT_BEGIN \
+	FILE                            *output_file = acpi_gbl_output_file; \
+	acpi_os_redirect_output (stderr);
+
+#define ACPI_MSG_REDIRECT_END \
+	acpi_os_redirect_output (output_file);
+
+#else
+/*
+ * non-iASL case - no redirection, nothing to do
+ */
+#define ACPI_MSG_REDIRECT_BEGIN
+#define ACPI_MSG_REDIRECT_END
+#endif
+
+/*
+ * Common error message prefixes
+ */
+#define ACPI_MSG_ERROR          "ACPI Error: "
+#define ACPI_MSG_EXCEPTION      "ACPI Exception: "
+#define ACPI_MSG_WARNING        "ACPI Warning: "
+#define ACPI_MSG_INFO           "ACPI: "
+
+#define ACPI_MSG_BIOS_ERROR     "ACPI BIOS Error (bug): "
+#define ACPI_MSG_BIOS_WARNING   "ACPI BIOS Warning (bug): "
+
+/*
+ * Common message suffix
+ */
+#define ACPI_MSG_SUFFIX \
+	acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number)
+
 /* Types for Resource descriptor entries */
 
 #define ACPI_INVALID_RESOURCE           0
@@ -578,7 +620,7 @@ void acpi_ut_print_string(char *string,
 
 void ut_convert_backslashes(char *pathname);
 
-u8 acpi_ut_valid_acpi_name(u32 name);
+u8 acpi_ut_valid_acpi_name(char *name);
 
 u8 acpi_ut_valid_acpi_char(char character, u32 position);
 
@@ -670,6 +712,12 @@ acpi_ut_predefined_info(const char *modu
 			u32 line_number,
 			char *pathname, u8 node_flags, const char *format, ...);
 
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_predefined_bios_error(const char *module_name,
+			      u32 line_number,
+			      char *pathname,
+			      u8 node_flags, const char *format, ...);
+
 void
 acpi_ut_namespace_error(const char *module_name,
 			u32 line_number,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dscontrol.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dscontrol.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dscontrol.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dscontrol.c	2013-08-25 20:43:22.000000000 -0400
@@ -78,7 +78,6 @@ acpi_ds_exec_begin_control_op(struct acp
 
 	switch (op->common.aml_opcode) {
 	case AML_WHILE_OP:
-
 		/*
 		 * If this is an additional iteration of a while loop, continue.
 		 * There is no need to allocate a new control state.
@@ -99,7 +98,6 @@ acpi_ds_exec_begin_control_op(struct acp
 		/*lint -fallthrough */
 
 	case AML_IF_OP:
-
 		/*
 		 * IF/WHILE: Create a new control state to manage these
 		 * constructs. We need to manage these as a stack, in order
@@ -142,6 +140,7 @@ acpi_ds_exec_begin_control_op(struct acp
 		break;
 
 	default:
+
 		break;
 	}
 
@@ -344,6 +343,7 @@ acpi_ds_exec_end_control_op(struct acpi_
 	case AML_NOOP_OP:
 
 		/* Just do nothing! */
+
 		break;
 
 	case AML_BREAK_POINT_OP:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dsfield.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsfield.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dsfield.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsfield.c	2013-08-25 20:43:22.000000000 -0400
@@ -563,21 +563,25 @@ acpi_ds_init_field_objects(union acpi_pa
 	 */
 	switch (walk_state->opcode) {
 	case AML_FIELD_OP:
+
 		arg = acpi_ps_get_arg(op, 2);
 		type = ACPI_TYPE_LOCAL_REGION_FIELD;
 		break;
 
 	case AML_BANK_FIELD_OP:
+
 		arg = acpi_ps_get_arg(op, 4);
 		type = ACPI_TYPE_LOCAL_BANK_FIELD;
 		break;
 
 	case AML_INDEX_FIELD_OP:
+
 		arg = acpi_ps_get_arg(op, 3);
 		type = ACPI_TYPE_LOCAL_INDEX_FIELD;
 		break;
 
 	default:
+
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dsinit.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsinit.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dsinit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsinit.c	2013-08-25 20:43:22.000000000 -0400
@@ -127,6 +127,7 @@ acpi_ds_init_one_object(acpi_handle obj_
 		break;
 
 	default:
+
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dsmthdat.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsmthdat.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dsmthdat.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsmthdat.c	2013-08-25 20:43:22.000000000 -0400
@@ -285,6 +285,7 @@ acpi_ds_method_data_get_node(u8 type,
 		break;
 
 	default:
+
 		ACPI_ERROR((AE_INFO, "Type %u is invalid", type));
 		return_ACPI_STATUS(AE_TYPE);
 	}
@@ -428,7 +429,6 @@ acpi_ds_method_data_get_value(u8 type,
 				return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG);
 
 			case ACPI_REFCLASS_LOCAL:
-
 				/*
 				 * No error message for this case, will be trapped again later to
 				 * detect and ignore cases of Store(local_x,local_x)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dsobject.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsobject.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dsobject.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsobject.c	2013-08-25 20:43:22.000000000 -0400
@@ -648,7 +648,6 @@ acpi_ds_init_object_from_op(struct acpi_
 
 	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
-
 		/*
 		 * Defer evaluation of Buffer term_arg operand
 		 */
@@ -660,7 +659,6 @@ acpi_ds_init_object_from_op(struct acpi_
 		break;
 
 	case ACPI_TYPE_PACKAGE:
-
 		/*
 		 * Defer evaluation of Package term_arg operand
 		 */
@@ -741,6 +739,7 @@ acpi_ds_init_object_from_op(struct acpi_
 			break;
 
 		default:
+
 			ACPI_ERROR((AE_INFO, "Unknown Integer type 0x%X",
 				    op_info->type));
 			status = AE_AML_OPERAND_TYPE;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dsopcode.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsopcode.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dsopcode.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsopcode.c	2013-08-25 20:43:22.000000000 -0400
@@ -636,6 +636,7 @@ acpi_ds_eval_data_object_operands(struct
 		break;
 
 	default:
+
 		return_ACPI_STATUS(AE_AML_BAD_OPCODE);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dsutils.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsutils.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dsutils.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dsutils.c	2013-08-25 20:43:22.000000000 -0400
@@ -240,7 +240,6 @@ acpi_ds_is_result_used(union acpi_parse_
 
 		case AML_IF_OP:
 		case AML_WHILE_OP:
-
 			/*
 			 * If we are executing the predicate AND this is the predicate op,
 			 * we will use the return value
@@ -254,7 +253,9 @@ acpi_ds_is_result_used(union acpi_parse_
 			break;
 
 		default:
+
 			/* Ignore other control opcodes */
+
 			break;
 		}
 
@@ -263,7 +264,6 @@ acpi_ds_is_result_used(union acpi_parse_
 		goto result_not_used;
 
 	case AML_CLASS_CREATE:
-
 		/*
 		 * These opcodes allow term_arg(s) as operands and therefore
 		 * the operands can be method calls. The result is used.
@@ -292,7 +292,6 @@ acpi_ds_is_result_used(union acpi_parse_
 		goto result_not_used;
 
 	default:
-
 		/*
 		 * In all other cases. the parent will actually use the return
 		 * object, so keep it.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dswexec.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dswexec.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dswexec.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dswexec.c	2013-08-25 20:43:22.000000000 -0400
@@ -327,6 +327,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_s
 		break;
 
 	default:
+
 		break;
 	}
 
@@ -488,7 +489,6 @@ acpi_status acpi_ds_exec_end_op(struct a
 			break;
 
 		case AML_TYPE_METHOD_CALL:
-
 			/*
 			 * If the method is referenced from within a package
 			 * declaration, it is not a invocation of the method, just
@@ -582,7 +582,6 @@ acpi_status acpi_ds_exec_end_op(struct a
 
 			switch (op->common.parent->common.aml_opcode) {
 			case AML_NAME_OP:
-
 				/*
 				 * Put the Node on the object stack (Contains the ACPI Name
 				 * of this object)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dswload2.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dswload2.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dswload2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dswload2.c	2013-08-25 20:43:22.000000000 -0400
@@ -509,6 +509,7 @@ acpi_status acpi_ds_load2_end_op(struct
 			break;
 
 		default:
+
 			/* All NAMED_FIELD opcodes must be handled above */
 			break;
 		}
@@ -548,6 +549,7 @@ acpi_status acpi_ds_load2_end_op(struct
 			break;
 
 		default:
+
 			/* Unknown opcode */
 
 			status = AE_OK;
@@ -674,6 +676,7 @@ acpi_status acpi_ds_load2_end_op(struct
 #endif				/* ACPI_NO_METHOD_EXECUTION */
 
 		default:
+
 			/* All NAMED_COMPLEX opcodes must be handled above */
 			break;
 		}
@@ -721,6 +724,7 @@ acpi_status acpi_ds_load2_end_op(struct
 		break;
 
 	default:
+
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/dswload.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dswload.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/dswload.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/dswload.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,6 +74,7 @@ acpi_ds_init_callbacks(struct acpi_walk_
 
 	switch (pass_number) {
 	case 1:
+
 		walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
 		    ACPI_PARSE_DELETE_TREE;
 		walk_state->descending_callback = acpi_ds_load1_begin_op;
@@ -81,6 +82,7 @@ acpi_ds_init_callbacks(struct acpi_walk_
 		break;
 
 	case 2:
+
 		walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
 		    ACPI_PARSE_DELETE_TREE;
 		walk_state->descending_callback = acpi_ds_load2_begin_op;
@@ -88,6 +90,7 @@ acpi_ds_init_callbacks(struct acpi_walk_
 		break;
 
 	case 3:
+
 #ifndef ACPI_NO_METHOD_EXECUTION
 		walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
 		    ACPI_PARSE_DELETE_TREE;
@@ -97,6 +100,7 @@ acpi_ds_init_callbacks(struct acpi_walk_
 		break;
 
 	default:
+
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -161,7 +165,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 
 	switch (walk_state->opcode) {
 	case AML_SCOPE_OP:
-
 		/*
 		 * The target name of the Scope() operator must exist at this point so
 		 * that we can actually open the scope to enter new names underneath it.
@@ -210,7 +213,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 		case ACPI_TYPE_INTEGER:
 		case ACPI_TYPE_STRING:
 		case ACPI_TYPE_BUFFER:
-
 			/*
 			 * These types we will allow, but we will change the type.
 			 * This enables some existing code of the form:
@@ -232,7 +234,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_
 			break;
 
 		case ACPI_TYPE_METHOD:
-
 			/*
 			 * Allow scope change to root during execution of module-level
 			 * code. Root is typed METHOD during this time.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evglock.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evglock.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evglock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evglock.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,6 +128,7 @@ acpi_status acpi_ev_remove_global_lock_h
 	status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
 						 acpi_ev_global_lock_handler);
 
+	acpi_os_delete_lock(acpi_gbl_global_lock_pending_lock);
 	return_ACPI_STATUS(status);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evgpeblk.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evgpeblk.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evgpeblk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evgpeblk.c	2013-08-25 20:43:22.000000000 -0400
@@ -382,6 +382,8 @@ acpi_ev_create_gpe_block(struct acpi_nam
 
 	status = acpi_ev_install_gpe_block(gpe_block, interrupt_number);
 	if (ACPI_FAILURE(status)) {
+		ACPI_FREE(gpe_block->register_info);
+		ACPI_FREE(gpe_block->event_info);
 		ACPI_FREE(gpe_block);
 		return_ACPI_STATUS(status);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evgpe.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evgpe.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evgpe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evgpe.c	2013-08-25 20:43:22.000000000 -0400
@@ -529,7 +529,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_as
 
 	switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
 	case ACPI_GPE_DISPATCH_NOTIFY:
-
 		/*
 		 * Implicit notify.
 		 * Dispatch a DEVICE_WAKE notify to the appropriate handler.
@@ -579,11 +578,11 @@ static void ACPI_SYSTEM_XFACE acpi_ev_as
 					(local_gpe_event_info->dispatch.
 					 method_node)));
 		}
-
 		break;
 
 	default:
-		return_VOID;    /* Should never happen */
+
+		return_VOID;	/* Should never happen */
 	}
 
 	/* Defer enabling of GPE until all notify handlers are done */
@@ -755,7 +754,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespa
 
 	case ACPI_GPE_DISPATCH_METHOD:
 	case ACPI_GPE_DISPATCH_NOTIFY:
-
 		/*
 		 * Execute the method associated with the GPE
 		 * NOTE: Level-triggered GPEs are cleared after the method completes.
@@ -771,7 +769,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespa
 		break;
 
 	default:
-
 		/*
 		 * No handler or method to run!
 		 * 03/2010: This case should no longer be possible. We will not allow
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evgpeinit.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evgpeinit.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evgpeinit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evgpeinit.c	2013-08-25 20:43:22.000000000 -0400
@@ -363,14 +363,17 @@ acpi_ev_match_gpe_method(acpi_handle obj
 	 */
 	switch (name[1]) {
 	case 'L':
+
 		type = ACPI_GPE_LEVEL_TRIGGERED;
 		break;
 
 	case 'E':
+
 		type = ACPI_GPE_EDGE_TRIGGERED;
 		break;
 
 	default:
+
 		/* Unknown method type, just ignore it */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evhandler.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evhandler.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evhandler.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evhandler.c	2013-08-25 20:43:22.000000000 -0400
@@ -354,36 +354,43 @@ acpi_ev_install_space_handler(struct acp
 
 		switch (space_id) {
 		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+
 			handler = acpi_ex_system_memory_space_handler;
 			setup = acpi_ev_system_memory_region_setup;
 			break;
 
 		case ACPI_ADR_SPACE_SYSTEM_IO:
+
 			handler = acpi_ex_system_io_space_handler;
 			setup = acpi_ev_io_space_region_setup;
 			break;
 
 		case ACPI_ADR_SPACE_PCI_CONFIG:
+
 			handler = acpi_ex_pci_config_space_handler;
 			setup = acpi_ev_pci_config_region_setup;
 			break;
 
 		case ACPI_ADR_SPACE_CMOS:
+
 			handler = acpi_ex_cmos_space_handler;
 			setup = acpi_ev_cmos_region_setup;
 			break;
 
 		case ACPI_ADR_SPACE_PCI_BAR_TARGET:
+
 			handler = acpi_ex_pci_bar_space_handler;
 			setup = acpi_ev_pci_bar_region_setup;
 			break;
 
 		case ACPI_ADR_SPACE_DATA_TABLE:
+
 			handler = acpi_ex_data_table_space_handler;
 			setup = NULL;
 			break;
 
 		default:
+
 			status = AE_BAD_PARAMETER;
 			goto unlock_and_exit;
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evmisc.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evmisc.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evmisc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evmisc.c	2013-08-25 20:43:22.000000000 -0400
@@ -78,6 +78,7 @@ u8 acpi_ev_is_notify_object(struct acpi_
 		return (TRUE);
 
 	default:
+
 		return (FALSE);
 	}
 }
@@ -275,6 +276,8 @@ void acpi_ev_terminate(void)
 			ACPI_ERROR((AE_INFO,
 				    "Could not remove Global Lock handler"));
 		}
+
+		acpi_gbl_events_initialized = FALSE;
 	}
 
 	/* Deallocate all handler objects installed within GPE info structs */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evregion.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evregion.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evregion.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evregion.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,8 @@ extern u8 acpi_gbl_default_address_space
 
 /* Local prototypes */
 
-static void acpi_ev_orphan_ec_reg_method(void);
+static void
+acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node);
 
 static acpi_status
 acpi_ev_reg_run(acpi_handle obj_handle,
@@ -532,7 +533,7 @@ acpi_ev_execute_reg_method(union acpi_op
 	}
 
 	info->prefix_node = region_obj2->extra.method_REG;
-	info->pathname = NULL;
+	info->relative_pathname = NULL;
 	info->parameters = args;
 	info->flags = ACPI_IGNORE_RETURN_VALUE;
 
@@ -612,7 +613,7 @@ acpi_ev_execute_reg_methods(struct acpi_
 	/* Special case for EC: handle "orphan" _REG methods with no region */
 
 	if (space_id == ACPI_ADR_SPACE_EC) {
-		acpi_ev_orphan_ec_reg_method();
+		acpi_ev_orphan_ec_reg_method(node);
 	}
 
 	return_ACPI_STATUS(status);
@@ -681,7 +682,7 @@ acpi_ev_reg_run(acpi_handle obj_handle,
  *
  * FUNCTION:    acpi_ev_orphan_ec_reg_method
  *
- * PARAMETERS:  None
+ * PARAMETERS:  ec_device_node      - Namespace node for an EC device
  *
  * RETURN:      None
  *
@@ -693,37 +694,27 @@ acpi_ev_reg_run(acpi_handle obj_handle,
  *              detected by providing a _REG method object underneath the
  *              Embedded Controller device."
  *
- *              To quickly access the EC device, we use the EC_ID that appears
- *              within the ECDT. Otherwise, we would need to perform a time-
- *              consuming namespace walk, executing _HID methods to find the
- *              EC device.
+ *              To quickly access the EC device, we use the ec_device_node used
+ *              during EC handler installation. Otherwise, we would need to
+ *              perform a time consuming namespace walk, executing _HID
+ *              methods to find the EC device.
+ *
+ *  MUTEX:      Assumes the namespace is locked
  *
  ******************************************************************************/
 
-static void acpi_ev_orphan_ec_reg_method(void)
+static void
+acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node)
 {
-	struct acpi_table_ecdt *table;
+	acpi_handle reg_method;
+	struct acpi_namespace_node *next_node;
 	acpi_status status;
 	struct acpi_object_list args;
 	union acpi_object objects[2];
-	struct acpi_namespace_node *ec_device_node;
-	struct acpi_namespace_node *reg_method;
-	struct acpi_namespace_node *next_node;
 
 	ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
 
-	/* Get the ECDT (if present in system) */
-
-	status = acpi_get_table(ACPI_SIG_ECDT, 0,
-				ACPI_CAST_INDIRECT_PTR(struct acpi_table_header,
-						       &table));
-	if (ACPI_FAILURE(status)) {
-		return_VOID;
-	}
-
-	/* We need a valid EC_ID string */
-
-	if (!(*table->id)) {
+	if (!ec_device_node) {
 		return_VOID;
 	}
 
@@ -731,22 +722,11 @@ static void acpi_ev_orphan_ec_reg_method
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
-	/* Get a handle to the EC device referenced in the ECDT */
-
-	status = acpi_get_handle(NULL,
-				 ACPI_CAST_PTR(char, table->id),
-				 ACPI_CAST_PTR(acpi_handle, &ec_device_node));
-	if (ACPI_FAILURE(status)) {
-		goto exit;
-	}
-
 	/* Get a handle to a _REG method immediately under the EC device */
 
-	status = acpi_get_handle(ec_device_node,
-				 METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle,
-								 &reg_method));
+	status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, &reg_method);
 	if (ACPI_FAILURE(status)) {
-		goto exit;
+		goto exit;	/* There is no _REG method present */
 	}
 
 	/*
@@ -754,19 +734,20 @@ static void acpi_ev_orphan_ec_reg_method
 	 * this scope with the Embedded Controller space ID. Otherwise, it
 	 * will already have been executed. Note, this allows for Regions
 	 * with other space IDs to be present; but the code below will then
-	 * execute the _REG method with the EC space ID argument.
+	 * execute the _REG method with the embedded_control space_ID argument.
 	 */
 	next_node = acpi_ns_get_next_node(ec_device_node, NULL);
 	while (next_node) {
 		if ((next_node->type == ACPI_TYPE_REGION) &&
 		    (next_node->object) &&
 		    (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
-			goto exit;	/* Do not execute _REG */
+			goto exit;	/* Do not execute the _REG */
 		}
+
 		next_node = acpi_ns_get_next_node(ec_device_node, next_node);
 	}
 
-	/* Evaluate the _REG(EC,Connect) method */
+	/* Evaluate the _REG(embedded_control,Connect) method */
 
 	args.count = 2;
 	args.pointer = objects;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evrgnini.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evrgnini.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evrgnini.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evrgnini.c	2013-08-25 20:43:22.000000000 -0400
@@ -596,7 +596,9 @@ acpi_ev_initialize_region(union acpi_ope
 				break;
 
 			default:
+
 				/* Ignore other objects */
+
 				break;
 			}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evxfgpe.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evxfgpe.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evxfgpe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evxfgpe.c	2013-08-25 20:43:22.000000000 -0400
@@ -366,16 +366,19 @@ acpi_set_gpe_wake_mask(acpi_handle gpe_d
 
 	switch (action) {
 	case ACPI_GPE_ENABLE:
+
 		ACPI_SET_BIT(gpe_register_info->enable_for_wake,
 			     (u8)register_bit);
 		break;
 
 	case ACPI_GPE_DISABLE:
+
 		ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
 			       (u8)register_bit);
 		break;
 
 	default:
+
 		ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
 		status = AE_BAD_PARAMETER;
 		break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/evxfregn.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evxfregn.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/evxfregn.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/evxfregn.c	2013-08-25 20:43:22.000000000 -0400
@@ -139,6 +139,7 @@ acpi_install_address_space_handler(acpi_
 		break;
 
 	default:
+
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exconfig.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exconfig.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exconfig.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exconfig.c	2013-08-25 20:43:22.000000000 -0400
@@ -480,6 +480,7 @@ acpi_ex_load_op(union acpi_operand_objec
 		break;
 
 	default:
+
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 	}
 
@@ -588,7 +589,7 @@ acpi_status acpi_ex_unload_table(union a
 	    (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
 	    (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) ||
 	    (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) {
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
+		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 	}
 
 	/* Get the table index from the ddb_handle */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exconvrt.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exconvrt.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exconvrt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exconvrt.c	2013-08-25 20:43:22.000000000 -0400
@@ -99,6 +99,7 @@ acpi_ex_convert_to_integer(union acpi_op
 		break;
 
 	default:
+
 		return_ACPI_STATUS(AE_TYPE);
 	}
 
@@ -117,7 +118,6 @@ acpi_ex_convert_to_integer(union acpi_op
 
 	switch (obj_desc->common.type) {
 	case ACPI_TYPE_STRING:
-
 		/*
 		 * Convert string to an integer - for most cases, the string must be
 		 * hexadecimal as per the ACPI specification. The only exception (as
@@ -161,6 +161,7 @@ acpi_ex_convert_to_integer(union acpi_op
 	default:
 
 		/* No other types can get here */
+
 		break;
 	}
 
@@ -213,7 +214,6 @@ acpi_ex_convert_to_buffer(union acpi_ope
 		return_ACPI_STATUS(AE_OK);
 
 	case ACPI_TYPE_INTEGER:
-
 		/*
 		 * Create a new Buffer object.
 		 * Need enough space for one integer
@@ -233,7 +233,6 @@ acpi_ex_convert_to_buffer(union acpi_ope
 		break;
 
 	case ACPI_TYPE_STRING:
-
 		/*
 		 * Create a new Buffer object
 		 * Size will be the string length
@@ -258,6 +257,7 @@ acpi_ex_convert_to_buffer(union acpi_ope
 		break;
 
 	default:
+
 		return_ACPI_STATUS(AE_TYPE);
 	}
 
@@ -304,15 +304,18 @@ acpi_ex_convert_to_ascii(u64 integer, u1
 
 		switch (data_width) {
 		case 1:
+
 			decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
 			break;
 
 		case 4:
+
 			decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
 			break;
 
 		case 8:
 		default:
+
 			decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
 			break;
 		}
@@ -546,6 +549,7 @@ acpi_ex_convert_to_string(union acpi_ope
 		break;
 
 	default:
+
 		return_ACPI_STATUS(AE_TYPE);
 	}
 
@@ -599,6 +603,7 @@ acpi_ex_convert_to_target_type(acpi_obje
 			break;
 
 		default:
+
 			/* No conversion allowed for these types */
 
 			if (destination_type != source_desc->common.type) {
@@ -649,6 +654,7 @@ acpi_ex_convert_to_target_type(acpi_obje
 			break;
 
 		default:
+
 			ACPI_ERROR((AE_INFO,
 				    "Bad destination type during conversion: 0x%X",
 				    destination_type));
@@ -664,6 +670,7 @@ acpi_ex_convert_to_target_type(acpi_obje
 		break;
 
 	default:
+
 		ACPI_ERROR((AE_INFO,
 			    "Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
 			    GET_CURRENT_ARG_TYPE(walk_state->op_info->
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/excreate.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/excreate.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/excreate.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/excreate.c	2013-08-25 20:43:22.000000000 -0400
@@ -103,7 +103,6 @@ acpi_status acpi_ex_create_alias(struct
 	case ACPI_TYPE_BUFFER:
 	case ACPI_TYPE_PACKAGE:
 	case ACPI_TYPE_BUFFER_FIELD:
-
 		/*
 		 * These types open a new scope, so we need the NS node in order to access
 		 * any children.
@@ -113,7 +112,6 @@ acpi_status acpi_ex_create_alias(struct
 	case ACPI_TYPE_PROCESSOR:
 	case ACPI_TYPE_THERMAL:
 	case ACPI_TYPE_LOCAL_SCOPE:
-
 		/*
 		 * The new alias has the type ALIAS and points to the original
 		 * NS node, not the object itself.
@@ -124,7 +122,6 @@ acpi_status acpi_ex_create_alias(struct
 		break;
 
 	case ACPI_TYPE_METHOD:
-
 		/*
 		 * Control method aliases need to be differentiated
 		 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exdebug.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exdebug.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exdebug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exdebug.c	2013-08-25 20:43:22.000000000 -0400
@@ -193,6 +193,7 @@ acpi_ex_do_debug_object(union acpi_opera
 			return_VOID;
 
 		default:
+
 			break;
 		}
 
@@ -226,6 +227,7 @@ acpi_ex_do_debug_object(union acpi_opera
 					break;
 
 				default:
+
 					acpi_ex_do_debug_object((source_desc->
 								 reference.
 								 node)->object,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exdump.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exdump.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exdump.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exdump.c	2013-08-25 20:43:22.000000000 -0400
@@ -357,6 +357,7 @@ acpi_ex_dump_object(union acpi_operand_o
 
 		switch (info->opcode) {
 		case ACPI_EXD_INIT:
+
 			break;
 
 		case ACPI_EXD_TYPE:
@@ -718,6 +719,7 @@ void acpi_ex_dump_operand(union acpi_ope
 		break;
 
 	default:
+
 		/* Unknown Type */
 
 		acpi_os_printf("Unknown Type %X\n", obj_desc->common.type);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exfield.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exfield.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exfield.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exfield.c	2013-08-25 20:43:22.000000000 -0400
@@ -331,21 +331,25 @@ acpi_ex_write_data_to_field(union acpi_o
 
 	switch (source_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
+
 		buffer = &source_desc->integer.value;
 		length = sizeof(source_desc->integer.value);
 		break;
 
 	case ACPI_TYPE_BUFFER:
+
 		buffer = source_desc->buffer.pointer;
 		length = source_desc->buffer.length;
 		break;
 
 	case ACPI_TYPE_STRING:
+
 		buffer = source_desc->string.pointer;
 		length = source_desc->string.length;
 		break;
 
 	default:
+
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exfldio.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exfldio.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exfldio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exfldio.c	2013-08-25 20:43:22.000000000 -0400
@@ -446,7 +446,6 @@ acpi_ex_field_datum_io(union acpi_operan
 		break;
 
 	case ACPI_TYPE_LOCAL_BANK_FIELD:
-
 		/*
 		 * Ensure that the bank_value is not beyond the capacity of
 		 * the register
@@ -488,7 +487,6 @@ acpi_ex_field_datum_io(union acpi_operan
 		break;
 
 	case ACPI_TYPE_LOCAL_INDEX_FIELD:
-
 		/*
 		 * Ensure that the index_value is not beyond the capacity of
 		 * the register
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exmisc.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exmisc.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exmisc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exmisc.c	2013-08-25 20:43:22.000000000 -0400
@@ -105,7 +105,6 @@ acpi_ex_get_object_reference(union acpi_
 		break;
 
 	case ACPI_DESC_TYPE_NAMED:
-
 		/*
 		 * A named reference that has already been resolved to a Node
 		 */
@@ -261,20 +260,24 @@ acpi_ex_do_concatenate(union acpi_operan
 	 */
 	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
+
 		status =
 		    acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
 		break;
 
 	case ACPI_TYPE_STRING:
+
 		status = acpi_ex_convert_to_string(operand1, &local_operand1,
 						   ACPI_IMPLICIT_CONVERT_HEX);
 		break;
 
 	case ACPI_TYPE_BUFFER:
+
 		status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
 		break;
 
 	default:
+
 		ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
 			    operand0->common.type));
 		status = AE_AML_INTERNAL;
@@ -519,6 +522,7 @@ acpi_ex_do_logical_numeric_op(u16 opcode
 		break;
 
 	default:
+
 		status = AE_AML_INTERNAL;
 		break;
 	}
@@ -580,20 +584,24 @@ acpi_ex_do_logical_op(u16 opcode,
 	 */
 	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
+
 		status =
 		    acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
 		break;
 
 	case ACPI_TYPE_STRING:
+
 		status = acpi_ex_convert_to_string(operand1, &local_operand1,
 						   ACPI_IMPLICIT_CONVERT_HEX);
 		break;
 
 	case ACPI_TYPE_BUFFER:
+
 		status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
 		break;
 
 	default:
+
 		status = AE_AML_INTERNAL;
 		break;
 	}
@@ -636,6 +644,7 @@ acpi_ex_do_logical_op(u16 opcode,
 			break;
 
 		default:
+
 			status = AE_AML_INTERNAL;
 			break;
 		}
@@ -703,6 +712,7 @@ acpi_ex_do_logical_op(u16 opcode,
 			break;
 
 		default:
+
 			status = AE_AML_INTERNAL;
 			break;
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exoparg1.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exoparg1.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exoparg1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exoparg1.c	2013-08-25 20:43:22.000000000 -0400
@@ -327,7 +327,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 			break;
 
 		case AML_FROM_BCD_OP:	/* from_bcd (BCDValue, Result) */
-
 			/*
 			 * The 64-bit ACPI integer can hold 16 4-bit BCD characters
 			 * (if table is 32-bit, integer can hold 8 BCD characters)
@@ -407,7 +406,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 			break;
 
 		case AML_COND_REF_OF_OP:	/* cond_ref_of (source_object, Result) */
-
 			/*
 			 * This op is a little strange because the internal return value is
 			 * different than the return value stored in the result descriptor
@@ -442,13 +440,14 @@ acpi_status acpi_ex_opcode_1A_1T_1R(stru
 			goto cleanup;
 
 		default:
+
 			/* No other opcodes get here */
+
 			break;
 		}
 		break;
 
 	case AML_STORE_OP:	/* Store (Source, Target) */
-
 		/*
 		 * A store operand is typically a number, string, buffer or lvalue
 		 * Be careful about deleting the source object,
@@ -615,7 +614,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 
 	case AML_DECREMENT_OP:	/* Decrement (Operand)  */
 	case AML_INCREMENT_OP:	/* Increment (Operand)  */
-
 		/*
 		 * Create a new integer. Can't just get the base integer and
 		 * increment it because it may be an Arg or Field.
@@ -682,7 +680,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 		break;
 
 	case AML_TYPE_OP:	/* object_type (source_object) */
-
 		/*
 		 * Note: The operand is not resolved at this point because we want to
 		 * get the associated object, not its value. For example, we don't
@@ -709,7 +706,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 		break;
 
 	case AML_SIZE_OF_OP:	/* size_of (source_object) */
-
 		/*
 		 * Note: The operand is not resolved at this point because we want to
 		 * get the associated object, not its value.
@@ -735,10 +731,12 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 		 */
 		switch (type) {
 		case ACPI_TYPE_INTEGER:
+
 			value = acpi_gbl_integer_byte_width;
 			break;
 
 		case ACPI_TYPE_STRING:
+
 			value = temp_desc->string.length;
 			break;
 
@@ -759,6 +757,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 			break;
 
 		default:
+
 			ACPI_ERROR((AE_INFO,
 				    "Operand must be Buffer/Integer/String/Package - found type %s",
 				    acpi_ut_get_type_name(type)));
@@ -860,9 +859,11 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 				break;
 
 			case ACPI_TYPE_STRING:
+
 				break;
 
 			default:
+
 				status = AE_AML_OPERAND_TYPE;
 				goto cleanup;
 			}
@@ -923,7 +924,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 			 */
 			switch (operand[0]->reference.class) {
 			case ACPI_REFCLASS_INDEX:
-
 				/*
 				 * The target type for the Index operator must be
 				 * either a Buffer or a Package
@@ -956,7 +956,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 					break;
 
 				case ACPI_TYPE_PACKAGE:
-
 					/*
 					 * Return the referenced element of the package. We must
 					 * add another reference to the referenced object, however.
@@ -999,6 +998,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(stru
 				break;
 
 			default:
+
 				ACPI_ERROR((AE_INFO,
 					    "Unknown class in reference(%p) - 0x%2.2X",
 					    operand[0],
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exoparg2.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exoparg2.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exoparg2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exoparg2.c	2013-08-25 20:43:22.000000000 -0400
@@ -304,7 +304,6 @@ acpi_status acpi_ex_opcode_2A_1T_1R(stru
 		break;
 
 	case AML_TO_STRING_OP:	/* to_string (Buffer, Length, Result) (ACPI 2.0) */
-
 		/*
 		 * Input object is guaranteed to be a buffer at this point (it may have
 		 * been converted.)  Copy the raw buffer data to a new object of
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exoparg3.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exoparg3.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exoparg3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exoparg3.c	2013-08-25 20:43:22.000000000 -0400
@@ -155,7 +155,6 @@ acpi_status acpi_ex_opcode_3A_1T_1R(stru
 
 	switch (walk_state->opcode) {
 	case AML_MID_OP:	/* Mid (Source[0], Index[1], Length[2], Result[3]) */
-
 		/*
 		 * Create the return object. The Source operand is guaranteed to be
 		 * either a String or a Buffer, so just use its type.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exoparg6.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exoparg6.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exoparg6.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exoparg6.c	2013-08-25 20:43:22.000000000 -0400
@@ -119,7 +119,6 @@ acpi_ex_do_match(u32 match_op,
 		break;
 
 	case MATCH_MEQ:
-
 		/*
 		 * True if equal: (P[i] == M)
 		 * Change to:     (M == P[i])
@@ -133,7 +132,6 @@ acpi_ex_do_match(u32 match_op,
 		break;
 
 	case MATCH_MLE:
-
 		/*
 		 * True if less than or equal: (P[i] <= M) (P[i] not_greater than M)
 		 * Change to:                  (M >= P[i]) (M not_less than P[i])
@@ -148,7 +146,6 @@ acpi_ex_do_match(u32 match_op,
 		break;
 
 	case MATCH_MLT:
-
 		/*
 		 * True if less than: (P[i] < M)
 		 * Change to:         (M > P[i])
@@ -162,7 +159,6 @@ acpi_ex_do_match(u32 match_op,
 		break;
 
 	case MATCH_MGE:
-
 		/*
 		 * True if greater than or equal: (P[i] >= M) (P[i] not_less than M)
 		 * Change to:                     (M <= P[i]) (M not_greater than P[i])
@@ -177,7 +173,6 @@ acpi_ex_do_match(u32 match_op,
 		break;
 
 	case MATCH_MGT:
-
 		/*
 		 * True if greater than: (P[i] > M)
 		 * Change to:            (M < P[i])
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exprep.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exprep.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exprep.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exprep.c	2013-08-25 20:43:22.000000000 -0400
@@ -253,26 +253,31 @@ acpi_ex_decode_field_access(union acpi_o
 
 	case AML_FIELD_ACCESS_BYTE:
 	case AML_FIELD_ACCESS_BUFFER:	/* ACPI 2.0 (SMBus Buffer) */
+
 		byte_alignment = 1;
 		bit_length = 8;
 		break;
 
 	case AML_FIELD_ACCESS_WORD:
+
 		byte_alignment = 2;
 		bit_length = 16;
 		break;
 
 	case AML_FIELD_ACCESS_DWORD:
+
 		byte_alignment = 4;
 		bit_length = 32;
 		break;
 
 	case AML_FIELD_ACCESS_QWORD:	/* ACPI 2.0 */
+
 		byte_alignment = 8;
 		bit_length = 64;
 		break;
 
 	default:
+
 		/* Invalid field access type */
 
 		ACPI_ERROR((AE_INFO, "Unknown field access type 0x%X", access));
@@ -598,7 +603,9 @@ acpi_status acpi_ex_prep_field_value(str
 		break;
 
 	default:
+
 		/* No other types should get here */
+
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exregion.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exregion.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exregion.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exregion.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,22 +88,27 @@ acpi_ex_system_memory_space_handler(u32
 
 	switch (bit_width) {
 	case 8:
+
 		length = 1;
 		break;
 
 	case 16:
+
 		length = 2;
 		break;
 
 	case 32:
+
 		length = 4;
 		break;
 
 	case 64:
+
 		length = 8;
 		break;
 
 	default:
+
 		ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %u",
 			    bit_width));
 		return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
@@ -214,23 +219,29 @@ acpi_ex_system_memory_space_handler(u32
 		*value = 0;
 		switch (bit_width) {
 		case 8:
-			*value = (u64) ACPI_GET8(logical_addr_ptr);
+
+			*value = (u64)ACPI_GET8(logical_addr_ptr);
 			break;
 
 		case 16:
-			*value = (u64) ACPI_GET16(logical_addr_ptr);
+
+			*value = (u64)ACPI_GET16(logical_addr_ptr);
 			break;
 
 		case 32:
-			*value = (u64) ACPI_GET32(logical_addr_ptr);
+
+			*value = (u64)ACPI_GET32(logical_addr_ptr);
 			break;
 
 		case 64:
-			*value = (u64) ACPI_GET64(logical_addr_ptr);
+
+			*value = (u64)ACPI_GET64(logical_addr_ptr);
 			break;
 
 		default:
+
 			/* bit_width was already validated */
+
 			break;
 		}
 		break;
@@ -239,28 +250,35 @@ acpi_ex_system_memory_space_handler(u32
 
 		switch (bit_width) {
 		case 8:
+
 			ACPI_SET8(logical_addr_ptr, *value);
 			break;
 
 		case 16:
+
 			ACPI_SET16(logical_addr_ptr, *value);
 			break;
 
 		case 32:
+
 			ACPI_SET32(logical_addr_ptr, *value);
 			break;
 
 		case 64:
+
 			ACPI_SET64(logical_addr_ptr, *value);
 			break;
 
 		default:
+
 			/* bit_width was already validated */
+
 			break;
 		}
 		break;
 
 	default:
+
 		status = AE_BAD_PARAMETER;
 		break;
 	}
@@ -320,6 +338,7 @@ acpi_ex_system_io_space_handler(u32 func
 		break;
 
 	default:
+
 		status = AE_BAD_PARAMETER;
 		break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exresnte.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exresnte.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exresnte.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exresnte.c	2013-08-25 20:43:22.000000000 -0400
@@ -248,6 +248,7 @@ acpi_ex_resolve_node_to_value(struct acp
 			break;
 
 		default:
+
 			/* No named references are allowed here */
 
 			ACPI_ERROR((AE_INFO,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exresolv.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exresolv.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exresolv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exresolv.c	2013-08-25 20:43:22.000000000 -0400
@@ -156,7 +156,6 @@ acpi_ex_resolve_object_to_value(union ac
 		switch (ref_type) {
 		case ACPI_REFCLASS_LOCAL:
 		case ACPI_REFCLASS_ARG:
-
 			/*
 			 * Get the local from the method's state info
 			 * Note: this increments the local's object reference count
@@ -309,6 +308,7 @@ acpi_ex_resolve_object_to_value(union ac
 		break;
 
 	default:
+
 		break;
 	}
 
@@ -348,10 +348,12 @@ acpi_ex_resolve_multiple(struct acpi_wal
 
 	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
 	case ACPI_DESC_TYPE_OPERAND:
+
 		type = obj_desc->common.type;
 		break;
 
 	case ACPI_DESC_TYPE_NAMED:
+
 		type = ((struct acpi_namespace_node *)obj_desc)->type;
 		obj_desc =
 		    acpi_ns_get_attached_object((struct acpi_namespace_node *)
@@ -538,7 +540,9 @@ acpi_ex_resolve_multiple(struct acpi_wal
 		break;
 
 	default:
+
 		/* No change to Type required */
+
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exresop.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exresop.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exresop.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exresop.c	2013-08-25 20:43:22.000000000 -0400
@@ -307,7 +307,6 @@ acpi_ex_resolve_operands(u16 opcode,
 		case ARGI_TARGETREF:	/* Allows implicit conversion rules before store */
 		case ARGI_FIXED_TARGET:	/* No implicit conversion before store to target */
 		case ARGI_SIMPLE_TARGET:	/* Name, Local, or arg - no implicit conversion  */
-
 			/*
 			 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
 			 * A Namespace Node is OK as-is
@@ -326,7 +325,6 @@ acpi_ex_resolve_operands(u16 opcode,
 			goto next_operand;
 
 		case ARGI_DATAREFOBJ:	/* Store operator only */
-
 			/*
 			 * We don't want to resolve index_op reference objects during
 			 * a store because this would be an implicit de_ref_of operation.
@@ -343,7 +341,9 @@ acpi_ex_resolve_operands(u16 opcode,
 			break;
 
 		default:
+
 			/* All cases covered above */
+
 			break;
 		}
 
@@ -433,7 +433,6 @@ acpi_ex_resolve_operands(u16 opcode,
 			goto next_operand;
 
 		case ARGI_BUFFER:
-
 			/*
 			 * Need an operand of type ACPI_TYPE_BUFFER,
 			 * But we can implicitly convert from a STRING or INTEGER
@@ -459,7 +458,6 @@ acpi_ex_resolve_operands(u16 opcode,
 			goto next_operand;
 
 		case ARGI_STRING:
-
 			/*
 			 * Need an operand of type ACPI_TYPE_STRING,
 			 * But we can implicitly convert from a BUFFER or INTEGER
@@ -562,6 +560,7 @@ acpi_ex_resolve_operands(u16 opcode,
 				break;
 
 			default:
+
 				ACPI_ERROR((AE_INFO,
 					    "Needed [Buffer/String/Package/Reference], found [%s] %p",
 					    acpi_ut_get_object_type_name
@@ -584,6 +583,7 @@ acpi_ex_resolve_operands(u16 opcode,
 				break;
 
 			default:
+
 				ACPI_ERROR((AE_INFO,
 					    "Needed [Buffer/String/Package], found [%s] %p",
 					    acpi_ut_get_object_type_name
@@ -605,6 +605,7 @@ acpi_ex_resolve_operands(u16 opcode,
 				break;
 
 			default:
+
 				ACPI_ERROR((AE_INFO,
 					    "Needed [Region/Buffer], found [%s] %p",
 					    acpi_ut_get_object_type_name
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exstore.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exstore.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exstore.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exstore.c	2013-08-25 20:43:22.000000000 -0400
@@ -114,6 +114,7 @@ acpi_ex_store(union acpi_operand_object
 
 	switch (dest_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
+
 		break;
 
 	case ACPI_TYPE_INTEGER:
@@ -178,7 +179,6 @@ acpi_ex_store(union acpi_operand_object
 		break;
 
 	case ACPI_REFCLASS_DEBUG:
-
 		/*
 		 * Storing to the Debug object causes the value stored to be
 		 * displayed and otherwise has no effect -- see ACPI Specification
@@ -291,7 +291,6 @@ acpi_ex_store_object_to_index(union acpi
 		break;
 
 	case ACPI_TYPE_BUFFER_FIELD:
-
 		/*
 		 * Store into a Buffer or String (not actually a real buffer_field)
 		 * at a location defined by an Index.
@@ -447,7 +446,6 @@ acpi_ex_store_object_to_node(union acpi_
 	case ACPI_TYPE_INTEGER:
 	case ACPI_TYPE_STRING:
 	case ACPI_TYPE_BUFFER:
-
 		/*
 		 * These target types are all of type Integer/String/Buffer, and
 		 * therefore support implicit conversion before the store.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/exstoren.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exstoren.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/exstoren.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/exstoren.c	2013-08-25 20:43:22.000000000 -0400
@@ -85,11 +85,9 @@ acpi_ex_resolve_object(union acpi_operan
 		 * These cases all require only Integers or values that
 		 * can be converted to Integers (Strings or Buffers)
 		 */
-
 	case ACPI_TYPE_INTEGER:
 	case ACPI_TYPE_STRING:
 	case ACPI_TYPE_BUFFER:
-
 		/*
 		 * Stores into a Field/Region or into a Integer/Buffer/String
 		 * are all essentially the same. This case handles the
@@ -133,7 +131,6 @@ acpi_ex_resolve_object(union acpi_operan
 
 	case ACPI_TYPE_LOCAL_ALIAS:
 	case ACPI_TYPE_LOCAL_METHOD_ALIAS:
-
 		/*
 		 * All aliases should have been resolved earlier, during the
 		 * operand resolution phase.
@@ -144,7 +141,6 @@ acpi_ex_resolve_object(union acpi_operan
 
 	case ACPI_TYPE_PACKAGE:
 	default:
-
 		/*
 		 * All other types than Alias and the various Fields come here,
 		 * including the untyped case - ACPI_TYPE_ANY.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/hwacpi.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwacpi.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/hwacpi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwacpi.c	2013-08-25 20:43:22.000000000 -0400
@@ -108,7 +108,6 @@ acpi_status acpi_hw_set_mode(u32 mode)
 		break;
 
 	case ACPI_SYS_MODE_LEGACY:
-
 		/*
 		 * BIOS should clear all fixed status bits and restore fixed event
 		 * enable bits to default
@@ -120,6 +119,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
 		break;
 
 	default:
+
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/hwgpe.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwgpe.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/hwgpe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwgpe.c	2013-08-25 20:43:22.000000000 -0400
@@ -127,14 +127,17 @@ acpi_hw_low_set_gpe(struct acpi_gpe_even
 		/*lint -fallthrough */
 
 	case ACPI_GPE_ENABLE:
+
 		ACPI_SET_BIT(enable_mask, register_bit);
 		break;
 
 	case ACPI_GPE_DISABLE:
+
 		ACPI_CLEAR_BIT(enable_mask, register_bit);
 		break;
 
 	default:
+
 		ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u", action));
 		return (AE_BAD_PARAMETER);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/hwregs.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwregs.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/hwregs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwregs.c	2013-08-25 20:43:22.000000000 -0400
@@ -419,6 +419,7 @@ acpi_status acpi_hw_register_read(u32 re
 		break;
 
 	default:
+
 		ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id));
 		status = AE_BAD_PARAMETER;
 		break;
@@ -491,7 +492,6 @@ acpi_status acpi_hw_register_write(u32 r
 		break;
 
 	case ACPI_REGISTER_PM1_CONTROL:	/* PM1 A/B: 16-bit access each */
-
 		/*
 		 * Perform a read first to preserve certain bits (per ACPI spec)
 		 * Note: This includes SCI_EN, we never want to change this bit
@@ -520,7 +520,6 @@ acpi_status acpi_hw_register_write(u32 r
 		break;
 
 	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
-
 		/*
 		 * For control registers, all reserved bits must be preserved,
 		 * as per the ACPI spec.
@@ -555,6 +554,7 @@ acpi_status acpi_hw_register_write(u32 r
 		break;
 
 	default:
+
 		ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id));
 		status = AE_BAD_PARAMETER;
 		break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/hwxface.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwxface.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/hwxface.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwxface.c	2013-08-25 20:43:22.000000000 -0400
@@ -495,7 +495,7 @@ acpi_get_sleep_type_data(u8 sleep_state,
 	 * Evaluate the \_Sx namespace object containing the register values
 	 * for this state
 	 */
-	info->pathname =
+	info->relative_pathname =
 	    ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
 	status = acpi_ns_evaluate(info);
 	if (ACPI_FAILURE(status)) {
@@ -506,7 +506,7 @@ acpi_get_sleep_type_data(u8 sleep_state,
 
 	if (!info->return_object) {
 		ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
-			    info->pathname));
+			    info->relative_pathname));
 		status = AE_AML_NO_RETURN_VALUE;
 		goto cleanup;
 	}
@@ -528,10 +528,12 @@ acpi_get_sleep_type_data(u8 sleep_state,
 	elements = info->return_object->package.elements;
 	switch (info->return_object->package.count) {
 	case 0:
+
 		status = AE_AML_PACKAGE_LIMIT;
 		break;
 
 	case 1:
+
 		if (elements[0]->common.type != ACPI_TYPE_INTEGER) {
 			status = AE_AML_OPERAND_TYPE;
 			break;
@@ -545,6 +547,7 @@ acpi_get_sleep_type_data(u8 sleep_state,
 
 	case 2:
 	default:
+
 		if ((elements[0]->common.type != ACPI_TYPE_INTEGER) ||
 		    (elements[1]->common.type != ACPI_TYPE_INTEGER)) {
 			status = AE_AML_OPERAND_TYPE;
@@ -565,7 +568,7 @@ acpi_get_sleep_type_data(u8 sleep_state,
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status,
 				"While evaluating Sleep State [%s]",
-				info->pathname));
+				info->relative_pathname));
 	}
 
 	ACPI_FREE(info);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/hwxfsleep.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwxfsleep.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/hwxfsleep.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/hwxfsleep.c	2013-08-25 20:43:22.000000000 -0400
@@ -240,12 +240,14 @@ static acpi_status acpi_hw_sleep_dispatc
 	    &acpi_sleep_dispatch[function_id];
 
 #if (!ACPI_REDUCED_HARDWARE)
-
 	/*
 	 * If the Hardware Reduced flag is set (from the FADT), we must
-	 * use the extended sleep registers
+	 * use the extended sleep registers (FADT). Note: As per the ACPI
+	 * specification, these extended registers are to be used for HW-reduced
+	 * platforms only. They are not general-purpose replacements for the
+	 * legacy PM register sleep support.
 	 */
-	if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) {
+	if (acpi_gbl_reduced_hardware) {
 		status = sleep_functions->extended_function(sleep_state);
 	} else {
 		/* Legacy sleep */
@@ -314,20 +316,24 @@ acpi_status acpi_enter_sleep_state_prep(
 
 	switch (sleep_state) {
 	case ACPI_STATE_S0:
+
 		sst_value = ACPI_SST_WORKING;
 		break;
 
 	case ACPI_STATE_S1:
 	case ACPI_STATE_S2:
 	case ACPI_STATE_S3:
+
 		sst_value = ACPI_SST_SLEEPING;
 		break;
 
 	case ACPI_STATE_S4:
+
 		sst_value = ACPI_SST_SLEEP_CONTEXT;
 		break;
 
 	default:
+
 		sst_value = ACPI_SST_INDICATOR_OFF;	/* Default is off */
 		break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/Makefile linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/Makefile
--- linux-libre-3.10-gnu/drivers/acpi/acpica/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -83,6 +83,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
 acpi-y +=		\
 	nsaccess.o	\
 	nsalloc.o	\
+	nsarguments.o	\
 	nsconvert.o	\
 	nsdump.o	\
 	nseval.o	\
@@ -137,6 +138,7 @@ acpi-y +=		\
 	tbfadt.o	\
 	tbfind.o	\
 	tbinstal.o	\
+	tbprint.o	\
 	tbutils.o	\
 	tbxface.o	\
 	tbxfload.o	\
@@ -145,11 +147,13 @@ acpi-y +=		\
 acpi-y +=		\
 	utaddress.o	\
 	utalloc.o	\
+	utbuffer.o	\
 	utcopy.o	\
 	utexcep.o	\
 	utdebug.o	\
 	utdecode.o	\
 	utdelete.o	\
+	uterror.o	\
 	uteval.o	\
 	utglobal.o	\
 	utids.o		\
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsaccess.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsaccess.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsaccess.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsaccess.c	2013-08-25 20:43:22.000000000 -0400
@@ -151,6 +151,7 @@ acpi_status acpi_ns_root_initialize(void
 			 */
 			switch (init_val->type) {
 			case ACPI_TYPE_METHOD:
+
 				obj_desc->method.param_count =
 				    (u8) ACPI_TO_INTEGER(val);
 				obj_desc->common.flags |= AOPOBJ_DATA_VALID;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsarguments.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsarguments.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsarguments.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsarguments.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,294 @@
+/******************************************************************************
+ *
+ * Module Name: nsarguments - Validation of args for ACPI predefined methods
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acnamesp.h"
+#include "acpredef.h"
+
+#define _COMPONENT          ACPI_NAMESPACE
+ACPI_MODULE_NAME("nsarguments")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_argument_types
+ *
+ * PARAMETERS:  info            - Method execution information block
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Check the incoming argument count and all argument types
+ *              against the argument type list for a predefined name.
+ *
+ ******************************************************************************/
+void acpi_ns_check_argument_types(struct acpi_evaluate_info *info)
+{
+	u16 arg_type_list;
+	u8 arg_count;
+	u8 arg_type;
+	u8 user_arg_type;
+	u32 i;
+
+	/* If not a predefined name, cannot typecheck args */
+
+	if (!info->predefined) {
+		return;
+	}
+
+	arg_type_list = info->predefined->info.argument_list;
+	arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
+
+	/* Typecheck all arguments */
+
+	for (i = 0; ((i < arg_count) && (i < info->param_count)); i++) {
+		arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
+		user_arg_type = info->parameters[i]->common.type;
+
+		if (user_arg_type != arg_type) {
+			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+					      ACPI_WARN_ALWAYS,
+					      "Argument #%u type mismatch - "
+					      "Found [%s], ACPI requires [%s]",
+					      (i + 1),
+					      acpi_ut_get_type_name
+					      (user_arg_type),
+					      acpi_ut_get_type_name(arg_type)));
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_acpi_compliance
+ *
+ * PARAMETERS:  pathname        - Full pathname to the node (for error msgs)
+ *              node            - Namespace node for the method/object
+ *              predefined      - Pointer to entry in predefined name table
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a
+ *              predefined name is what is expected (matches what is defined in
+ *              the ACPI specification for this predefined name.)
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_check_acpi_compliance(char *pathname,
+			      struct acpi_namespace_node *node,
+			      const union acpi_predefined_info *predefined)
+{
+	u32 aml_param_count;
+	u32 required_param_count;
+
+	if (!predefined) {
+		return;
+	}
+
+	/* Get the ACPI-required arg count from the predefined info table */
+
+	required_param_count =
+	    METHOD_GET_ARG_COUNT(predefined->info.argument_list);
+
+	/*
+	 * If this object is not a control method, we can check if the ACPI
+	 * spec requires that it be a method.
+	 */
+	if (node->type != ACPI_TYPE_METHOD) {
+		if (required_param_count > 0) {
+
+			/* Object requires args, must be implemented as a method */
+
+			ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,
+						    ACPI_WARN_ALWAYS,
+						    "Object (%s) must be a control method with %u arguments",
+						    acpi_ut_get_type_name(node->
+									  type),
+						    required_param_count));
+		} else if (!required_param_count
+			   && !predefined->info.expected_btypes) {
+
+			/* Object requires no args and no return value, must be a method */
+
+			ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,
+						    ACPI_WARN_ALWAYS,
+						    "Object (%s) must be a control method "
+						    "with no arguments and no return value",
+						    acpi_ut_get_type_name(node->
+									  type)));
+		}
+
+		return;
+	}
+
+	/*
+	 * This is a control method.
+	 * Check that the ASL/AML-defined parameter count for this method
+	 * matches the ACPI-required parameter count
+	 *
+	 * Some methods are allowed to have a "minimum" number of args (_SCP)
+	 * because their definition in ACPI has changed over time.
+	 *
+	 * Note: These are BIOS errors in the declaration of the object
+	 */
+	aml_param_count = node->object->method.param_count;
+
+	if (aml_param_count < required_param_count) {
+		ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
+					    "Insufficient arguments - "
+					    "ASL declared %u, ACPI requires %u",
+					    aml_param_count,
+					    required_param_count));
+	} else if ((aml_param_count > required_param_count)
+		   && !(predefined->info.
+			argument_list & ARG_COUNT_IS_MINIMUM)) {
+		ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
+					    "Excess arguments - "
+					    "ASL declared %u, ACPI requires %u",
+					    aml_param_count,
+					    required_param_count));
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_check_argument_count
+ *
+ * PARAMETERS:  pathname        - Full pathname to the node (for error msgs)
+ *              node            - Namespace node for the method/object
+ *              user_param_count - Number of args passed in by the caller
+ *              predefined      - Pointer to entry in predefined name table
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Check that incoming argument count matches the declared
+ *              parameter count (in the ASL/AML) for an object.
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_check_argument_count(char *pathname,
+			     struct acpi_namespace_node *node,
+			     u32 user_param_count,
+			     const union acpi_predefined_info *predefined)
+{
+	u32 aml_param_count;
+	u32 required_param_count;
+
+	if (!predefined) {
+		/*
+		 * Not a predefined name. Check the incoming user argument count
+		 * against the count that is specified in the method/object.
+		 */
+		if (node->type != ACPI_TYPE_METHOD) {
+			if (user_param_count) {
+				ACPI_INFO_PREDEFINED((AE_INFO, pathname,
+						      ACPI_WARN_ALWAYS,
+						      "%u arguments were passed to a non-method ACPI object (%s)",
+						      user_param_count,
+						      acpi_ut_get_type_name
+						      (node->type)));
+			}
+
+			return;
+		}
+
+		/*
+		 * This is a control method. Check the parameter count.
+		 * We can only check the incoming argument count against the
+		 * argument count declared for the method in the ASL/AML.
+		 *
+		 * Emit a message if too few or too many arguments have been passed
+		 * by the caller.
+		 *
+		 * Note: Too many arguments will not cause the method to
+		 * fail. However, the method will fail if there are too few
+		 * arguments and the method attempts to use one of the missing ones.
+		 */
+		aml_param_count = node->object->method.param_count;
+
+		if (user_param_count < aml_param_count) {
+			ACPI_WARN_PREDEFINED((AE_INFO, pathname,
+					      ACPI_WARN_ALWAYS,
+					      "Insufficient arguments - "
+					      "Caller passed %u, method requires %u",
+					      user_param_count,
+					      aml_param_count));
+		} else if (user_param_count > aml_param_count) {
+			ACPI_INFO_PREDEFINED((AE_INFO, pathname,
+					      ACPI_WARN_ALWAYS,
+					      "Excess arguments - "
+					      "Caller passed %u, method requires %u",
+					      user_param_count,
+					      aml_param_count));
+		}
+
+		return;
+	}
+
+	/*
+	 * This is a predefined name. Validate the user-supplied parameter
+	 * count against the ACPI specification. We don't validate against
+	 * the method itself because what is important here is that the
+	 * caller is in conformance with the spec. (The arg count for the
+	 * method was checked against the ACPI spec earlier.)
+	 *
+	 * Some methods are allowed to have a "minimum" number of args (_SCP)
+	 * because their definition in ACPI has changed over time.
+	 */
+	required_param_count =
+	    METHOD_GET_ARG_COUNT(predefined->info.argument_list);
+
+	if (user_param_count < required_param_count) {
+		ACPI_WARN_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
+				      "Insufficient arguments - "
+				      "Caller passed %u, ACPI requires %u",
+				      user_param_count, required_param_count));
+	} else if ((user_param_count > required_param_count) &&
+		   !(predefined->info.argument_list & ARG_COUNT_IS_MINIMUM)) {
+		ACPI_INFO_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
+				      "Excess arguments - "
+				      "Caller passed %u, ACPI requires %u",
+				      user_param_count, required_param_count));
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsconvert.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsconvert.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsconvert.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsconvert.c	2013-08-25 20:43:22.000000000 -0400
@@ -103,6 +103,7 @@ acpi_ns_convert_to_integer(union acpi_op
 		break;
 
 	default:
+
 		return (AE_AML_OPERAND_TYPE);
 	}
 
@@ -191,6 +192,7 @@ acpi_ns_convert_to_string(union acpi_ope
 		break;
 
 	default:
+
 		return (AE_AML_OPERAND_TYPE);
 	}
 
@@ -294,6 +296,7 @@ acpi_ns_convert_to_buffer(union acpi_ope
 		break;
 
 	default:
+
 		return (AE_AML_OPERAND_TYPE);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsdump.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsdump.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsdump.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsdump.c	2013-08-25 20:43:22.000000000 -0400
@@ -244,10 +244,12 @@ acpi_ns_dump_one_object(acpi_handle obj_
 			case ACPI_TYPE_BUFFER:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_METHOD:
+
 				acpi_os_printf("<No attached object>");
 				break;
 
 			default:
+
 				break;
 			}
 
@@ -433,6 +435,7 @@ acpi_ns_dump_one_object(acpi_handle obj_
 			break;
 
 		default:
+
 			break;
 		}
 		break;
@@ -567,32 +570,39 @@ acpi_ns_dump_one_object(acpi_handle obj_
 			goto cleanup;
 
 		case ACPI_TYPE_BUFFER_FIELD:
+
 			obj_desc =
 			    (union acpi_operand_object *)obj_desc->buffer_field.
 			    buffer_obj;
 			break;
 
 		case ACPI_TYPE_PACKAGE:
+
 			obj_desc = (void *)obj_desc->package.elements;
 			break;
 
 		case ACPI_TYPE_METHOD:
+
 			obj_desc = (void *)obj_desc->method.aml_start;
 			break;
 
 		case ACPI_TYPE_LOCAL_REGION_FIELD:
+
 			obj_desc = (void *)obj_desc->field.region_obj;
 			break;
 
 		case ACPI_TYPE_LOCAL_BANK_FIELD:
+
 			obj_desc = (void *)obj_desc->bank_field.region_obj;
 			break;
 
 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
+
 			obj_desc = (void *)obj_desc->index_field.index_obj;
 			break;
 
 		default:
+
 			goto cleanup;
 		}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nseval.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nseval.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nseval.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nseval.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,7 +61,7 @@ acpi_ns_exec_module_code(union acpi_oper
  *
  * PARAMETERS:  info            - Evaluation info block, contains:
  *                  prefix_node     - Prefix or Method/Object Node to execute
- *                  pathname        - Name of method to execute, If NULL, the
+ *                  relative_path   - Name of method to execute, If NULL, the
  *                                    Node is the object to execute
  *                  parameters      - List of parameters to pass to the method,
  *                                    terminated by NULL. Params itself may be
@@ -82,10 +82,9 @@ acpi_ns_exec_module_code(union acpi_oper
  *
  ******************************************************************************/
 
-acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
+acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
 {
 	acpi_status status;
-	struct acpi_namespace_node *node;
 
 	ACPI_FUNCTION_TRACE(ns_evaluate);
 
@@ -93,83 +92,138 @@ acpi_status acpi_ns_evaluate(struct acpi
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Initialize the return value to an invalid object */
-
-	info->return_object = NULL;
-	info->param_count = 0;
-
-	if (!info->resolved_node) {
+	if (!info->node) {
 		/*
-		 * Get the actual namespace node for the target object if we need to.
-		 * Handles these cases:
+		 * Get the actual namespace node for the target object if we
+		 * need to. Handles these cases:
 		 *
-		 * 1) Null node, Pathname (absolute path)
-		 * 2) Node, Pathname (path relative to Node)
-		 * 3) Node, Null Pathname
+		 * 1) Null node, valid pathname from root (absolute path)
+		 * 2) Node and valid pathname (path relative to Node)
+		 * 3) Node, Null pathname
 		 */
-		status = acpi_ns_get_node(info->prefix_node, info->pathname,
-					  ACPI_NS_NO_UPSEARCH,
-					  &info->resolved_node);
+		status =
+		    acpi_ns_get_node(info->prefix_node, info->relative_pathname,
+				     ACPI_NS_NO_UPSEARCH, &info->node);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
 	}
 
 	/*
-	 * For a method alias, we must grab the actual method node so that proper
-	 * scoping context will be established before execution.
+	 * For a method alias, we must grab the actual method node so that
+	 * proper scoping context will be established before execution.
 	 */
-	if (acpi_ns_get_type(info->resolved_node) ==
-	    ACPI_TYPE_LOCAL_METHOD_ALIAS) {
-		info->resolved_node =
+	if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
+		info->node =
 		    ACPI_CAST_PTR(struct acpi_namespace_node,
-				  info->resolved_node->object);
+				  info->node->object);
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->pathname,
-			  info->resolved_node,
-			  acpi_ns_get_attached_object(info->resolved_node)));
+	/* Complete the info block initialization */
 
-	node = info->resolved_node;
+	info->return_object = NULL;
+	info->node_flags = info->node->flags;
+	info->obj_desc = acpi_ns_get_attached_object(info->node);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
+			  info->relative_pathname, info->node,
+			  acpi_ns_get_attached_object(info->node)));
+
+	/* Get info if we have a predefined name (_HID, etc.) */
+
+	info->predefined =
+	    acpi_ut_match_predefined_method(info->node->name.ascii);
+
+	/* Get the full pathname to the object, for use in warning messages */
+
+	info->full_pathname = acpi_ns_get_external_pathname(info->node);
+	if (!info->full_pathname) {
+		return_ACPI_STATUS(AE_NO_MEMORY);
+	}
+
+	/* Count the number of arguments being passed in */
+
+	info->param_count = 0;
+	if (info->parameters) {
+		while (info->parameters[info->param_count]) {
+			info->param_count++;
+		}
+
+		/* Warn on impossible argument count */
+
+		if (info->param_count > ACPI_METHOD_NUM_ARGS) {
+			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+					      ACPI_WARN_ALWAYS,
+					      "Excess arguments (%u) - using only %u",
+					      info->param_count,
+					      ACPI_METHOD_NUM_ARGS));
+
+			info->param_count = ACPI_METHOD_NUM_ARGS;
+		}
+	}
 
 	/*
-	 * Two major cases here:
+	 * For predefined names: Check that the declared argument count
+	 * matches the ACPI spec -- otherwise this is a BIOS error.
+	 */
+	acpi_ns_check_acpi_compliance(info->full_pathname, info->node,
+				      info->predefined);
+
+	/*
+	 * For all names: Check that the incoming argument count for
+	 * this method/object matches the actual ASL/AML definition.
+	 */
+	acpi_ns_check_argument_count(info->full_pathname, info->node,
+				     info->param_count, info->predefined);
+
+	/* For predefined names: Typecheck all incoming arguments */
+
+	acpi_ns_check_argument_types(info);
+
+	/*
+	 * Three major evaluation cases:
 	 *
-	 * 1) The object is a control method -- execute it
-	 * 2) The object is not a method -- just return it's current value
+	 * 1) Object types that cannot be evaluated by definition
+	 * 2) The object is a control method -- execute it
+	 * 3) The object is not a method -- just return it's current value
 	 */
-	if (acpi_ns_get_type(info->resolved_node) == ACPI_TYPE_METHOD) {
+	switch (acpi_ns_get_type(info->node)) {
+	case ACPI_TYPE_DEVICE:
+	case ACPI_TYPE_EVENT:
+	case ACPI_TYPE_MUTEX:
+	case ACPI_TYPE_REGION:
+	case ACPI_TYPE_THERMAL:
+	case ACPI_TYPE_LOCAL_SCOPE:
 		/*
-		 * 1) Object is a control method - execute it
+		 * 1) Disallow evaluation of certain object types. For these,
+		 *    object evaluation is undefined and not supported.
+		 */
+		ACPI_ERROR((AE_INFO,
+			    "%s: Evaluation of object type [%s] is not supported",
+			    info->full_pathname,
+			    acpi_ut_get_type_name(info->node->type)));
+
+		status = AE_TYPE;
+		goto cleanup;
+
+	case ACPI_TYPE_METHOD:
+		/*
+		 * 2) Object is a control method - execute it
 		 */
 
 		/* Verify that there is a method object associated with this node */
 
-		info->obj_desc =
-		    acpi_ns_get_attached_object(info->resolved_node);
 		if (!info->obj_desc) {
 			ACPI_ERROR((AE_INFO,
-				    "Control method has no attached sub-object"));
-			return_ACPI_STATUS(AE_NULL_OBJECT);
-		}
-
-		/* Count the number of arguments being passed to the method */
-
-		if (info->parameters) {
-			while (info->parameters[info->param_count]) {
-				if (info->param_count > ACPI_METHOD_MAX_ARG) {
-					return_ACPI_STATUS(AE_LIMIT);
-				}
-				info->param_count++;
-			}
+				    "%s: Method has no attached sub-object",
+				    info->full_pathname));
+			status = AE_NULL_OBJECT;
+			goto cleanup;
 		}
 
-
-		ACPI_DUMP_PATHNAME(info->resolved_node, "ACPI: Execute Method",
-				   ACPI_LV_INFO, _COMPONENT);
-
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "Method at AML address %p Length %X\n",
+				  "**** Execute method [%s] at AML address %p length %X\n",
+				  info->full_pathname,
 				  info->obj_desc->method.aml_start + 1,
 				  info->obj_desc->method.aml_length - 1));
 
@@ -184,81 +238,61 @@ acpi_status acpi_ns_evaluate(struct acpi
 		acpi_ex_enter_interpreter();
 		status = acpi_ps_execute_method(info);
 		acpi_ex_exit_interpreter();
-	} else {
+		break;
+
+	default:
 		/*
-		 * 2) Object is not a method, return its current value
-		 *
-		 * Disallow certain object types. For these, "evaluation" is undefined.
+		 * 3) All other non-method objects -- get the current object value
 		 */
-		switch (info->resolved_node->type) {
-		case ACPI_TYPE_DEVICE:
-		case ACPI_TYPE_EVENT:
-		case ACPI_TYPE_MUTEX:
-		case ACPI_TYPE_REGION:
-		case ACPI_TYPE_THERMAL:
-		case ACPI_TYPE_LOCAL_SCOPE:
-
-			ACPI_ERROR((AE_INFO,
-				    "[%4.4s] Evaluation of object type [%s] is not supported",
-				    info->resolved_node->name.ascii,
-				    acpi_ut_get_type_name(info->resolved_node->
-							  type)));
-
-			return_ACPI_STATUS(AE_TYPE);
-
-		default:
-			break;
-		}
 
 		/*
-		 * Objects require additional resolution steps (e.g., the Node may be
-		 * a field that must be read, etc.) -- we can't just grab the object
-		 * out of the node.
+		 * Some objects require additional resolution steps (e.g., the Node
+		 * may be a field that must be read, etc.) -- we can't just grab
+		 * the object out of the node.
 		 *
 		 * Use resolve_node_to_value() to get the associated value.
 		 *
 		 * NOTE: we can get away with passing in NULL for a walk state because
-		 * resolved_node is guaranteed to not be a reference to either a method
+		 * the Node is guaranteed to not be a reference to either a method
 		 * local or a method argument (because this interface is never called
 		 * from a running method.)
 		 *
 		 * Even though we do not directly invoke the interpreter for object
-		 * resolution, we must lock it because we could access an opregion.
-		 * The opregion access code assumes that the interpreter is locked.
+		 * resolution, we must lock it because we could access an op_region.
+		 * The op_region access code assumes that the interpreter is locked.
 		 */
 		acpi_ex_enter_interpreter();
 
-		/* Function has a strange interface */
+		/* TBD: resolve_node_to_value has a strange interface, fix */
+
+		info->return_object =
+		    ACPI_CAST_PTR(union acpi_operand_object, info->node);
 
 		status =
-		    acpi_ex_resolve_node_to_value(&info->resolved_node, NULL);
+		    acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
+						  (struct acpi_namespace_node,
+						   &info->return_object), NULL);
 		acpi_ex_exit_interpreter();
 
-		/*
-		 * If acpi_ex_resolve_node_to_value() succeeded, the return value was placed
-		 * in resolved_node.
-		 */
-		if (ACPI_SUCCESS(status)) {
-			status = AE_CTRL_RETURN_VALUE;
-			info->return_object =
-			    ACPI_CAST_PTR(union acpi_operand_object,
-					  info->resolved_node);
-
-			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-					  "Returning object %p [%s]\n",
-					  info->return_object,
-					  acpi_ut_get_object_type_name(info->
-								       return_object)));
+		if (ACPI_FAILURE(status)) {
+			goto cleanup;
 		}
+
+		ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Returned object %p [%s]\n",
+				  info->return_object,
+				  acpi_ut_get_object_type_name(info->
+							       return_object)));
+
+		status = AE_CTRL_RETURN_VALUE;	/* Always has a "return value" */
+		break;
 	}
 
 	/*
-	 * Check input argument count against the ASL-defined count for a method.
-	 * Also check predefined names: argument count and return value against
-	 * the ACPI specification. Some incorrect return value types are repaired.
+	 * For predefined names, check the return value against the ACPI
+	 * specification. Some incorrect return value types are repaired.
 	 */
-	(void)acpi_ns_check_predefined_names(node, info->param_count,
-		status, &info->return_object);
+	(void)acpi_ns_check_return_value(info->node, info, info->param_count,
+					 status, &info->return_object);
 
 	/* Check if there is a return value that must be dealt with */
 
@@ -278,12 +312,15 @@ acpi_status acpi_ns_evaluate(struct acpi
 
 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 			  "*** Completed evaluation of object %s ***\n",
-			  info->pathname));
+			  info->relative_pathname));
 
+ cleanup:
 	/*
 	 * Namespace was unlocked by the handling acpi_ns* function, so we
-	 * just return
+	 * just free the pathname and return
 	 */
+	ACPI_FREE(info->full_pathname);
+	info->full_pathname = NULL;
 	return_ACPI_STATUS(status);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsinit.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsinit.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsinit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsinit.c	2013-08-25 20:43:22.000000000 -0400
@@ -176,7 +176,7 @@ acpi_status acpi_ns_initialize_devices(v
 	 * part of the ACPI specification.
 	 */
 	info.evaluate_info->prefix_node = acpi_gbl_root_node;
-	info.evaluate_info->pathname = METHOD_NAME__INI;
+	info.evaluate_info->relative_pathname = METHOD_NAME__INI;
 	info.evaluate_info->parameters = NULL;
 	info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
 
@@ -266,28 +266,34 @@ acpi_ns_init_one_object(acpi_handle obj_
 
 	switch (type) {
 	case ACPI_TYPE_REGION:
+
 		info->op_region_count++;
 		break;
 
 	case ACPI_TYPE_BUFFER_FIELD:
+
 		info->field_count++;
 		break;
 
 	case ACPI_TYPE_LOCAL_BANK_FIELD:
+
 		info->field_count++;
 		break;
 
 	case ACPI_TYPE_BUFFER:
+
 		info->buffer_count++;
 		break;
 
 	case ACPI_TYPE_PACKAGE:
+
 		info->package_count++;
 		break;
 
 	default:
 
 		/* No init required, just exit now */
+
 		return (AE_OK);
 	}
 
@@ -337,7 +343,9 @@ acpi_ns_init_one_object(acpi_handle obj_
 		break;
 
 	default:
+
 		/* No other types can get here */
+
 		break;
 	}
 
@@ -416,6 +424,7 @@ acpi_ns_find_ini_methods(acpi_handle obj
 		break;
 
 	default:
+
 		break;
 	}
 
@@ -560,7 +569,7 @@ acpi_ns_init_one_device(acpi_handle obj_
 
 	ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info));
 	info->prefix_node = device_node;
-	info->pathname = METHOD_NAME__INI;
+	info->relative_pathname = METHOD_NAME__INI;
 	info->parameters = NULL;
 	info->flags = ACPI_IGNORE_RETURN_VALUE;
 
@@ -574,8 +583,7 @@ acpi_ns_init_one_device(acpi_handle obj_
 
 		/* Ignore error and move on to next device */
 
-		char *scope_name =
-		    acpi_ns_get_external_pathname(info->resolved_node);
+		char *scope_name = acpi_ns_get_external_pathname(info->node);
 
 		ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution",
 				scope_name));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nspredef.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nspredef.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nspredef.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nspredef.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,28 +61,29 @@ ACPI_MODULE_NAME("nspredef")
  * There are several areas that are validated:
  *
  *  1) The number of input arguments as defined by the method/object in the
- *      ASL is validated against the ACPI specification.
+ *     ASL is validated against the ACPI specification.
  *  2) The type of the return object (if any) is validated against the ACPI
- *      specification.
+ *     specification.
  *  3) For returned package objects, the count of package elements is
- *      validated, as well as the type of each package element. Nested
- *      packages are supported.
+ *     validated, as well as the type of each package element. Nested
+ *     packages are supported.
  *
  * For any problems found, a warning message is issued.
  *
  ******************************************************************************/
 /* Local prototypes */
 static acpi_status
-acpi_ns_check_reference(struct acpi_predefined_data *data,
+acpi_ns_check_reference(struct acpi_evaluate_info *info,
 			union acpi_operand_object *return_object);
 
 static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object);
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ns_check_predefined_names
+ * FUNCTION:    acpi_ns_check_return_value
  *
  * PARAMETERS:  node            - Namespace node for the method/object
+ *              info            - Method execution information block
  *              user_param_count - Number of parameters actually passed
  *              return_status   - Status from the object evaluation
  *              return_object_ptr - Pointer to the object returned from the
@@ -90,44 +91,25 @@ static u32 acpi_ns_get_bitmapped_type(un
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
+ * DESCRIPTION: Check the value returned from a predefined name.
  *
  ******************************************************************************/
 
 acpi_status
-acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
-			       u32 user_param_count,
-			       acpi_status return_status,
-			       union acpi_operand_object **return_object_ptr)
+acpi_ns_check_return_value(struct acpi_namespace_node *node,
+			   struct acpi_evaluate_info *info,
+			   u32 user_param_count,
+			   acpi_status return_status,
+			   union acpi_operand_object **return_object_ptr)
 {
-	acpi_status status = AE_OK;
+	acpi_status status;
 	const union acpi_predefined_info *predefined;
-	char *pathname;
-	struct acpi_predefined_data *data;
-
-	/* Match the name for this method/object against the predefined list */
-
-	predefined = acpi_ut_match_predefined_method(node->name.ascii);
-
-	/* Get the full pathname to the object, for use in warning messages */
-
-	pathname = acpi_ns_get_external_pathname(node);
-	if (!pathname) {
-		return (AE_OK);	/* Could not get pathname, ignore */
-	}
-
-	/*
-	 * Check that the parameter count for this method matches the ASL
-	 * definition. For predefined names, ensure that both the caller and
-	 * the method itself are in accordance with the ACPI specification.
-	 */
-	acpi_ns_check_parameter_count(pathname, node, user_param_count,
-				      predefined);
 
 	/* If not a predefined name, we cannot validate the return object */
 
+	predefined = info->predefined;
 	if (!predefined) {
-		goto cleanup;
+		return (AE_OK);
 	}
 
 	/*
@@ -135,7 +117,7 @@ acpi_ns_check_predefined_names(struct ac
 	 * validate the return object
 	 */
 	if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) {
-		goto cleanup;
+		return (AE_OK);
 	}
 
 	/*
@@ -154,25 +136,14 @@ acpi_ns_check_predefined_names(struct ac
 	if (acpi_gbl_disable_auto_repair ||
 	    (!predefined->info.expected_btypes) ||
 	    (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) {
-		goto cleanup;
-	}
-
-	/* Create the parameter data block for object validation */
-
-	data = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_predefined_data));
-	if (!data) {
-		goto cleanup;
+		return (AE_OK);
 	}
-	data->predefined = predefined;
-	data->node = node;
-	data->node_flags = node->flags;
-	data->pathname = pathname;
 
 	/*
 	 * Check that the type of the main return object is what is expected
 	 * for this predefined name
 	 */
-	status = acpi_ns_check_object_type(data, return_object_ptr,
+	status = acpi_ns_check_object_type(info, return_object_ptr,
 					   predefined->info.expected_btypes,
 					   ACPI_NOT_PACKAGE_ELEMENT);
 	if (ACPI_FAILURE(status)) {
@@ -184,10 +155,16 @@ acpi_ns_check_predefined_names(struct ac
 	 * Note: Package may have been newly created by call above.
 	 */
 	if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) {
-		data->parent_package = *return_object_ptr;
-		status = acpi_ns_check_package(data, return_object_ptr);
+		info->parent_package = *return_object_ptr;
+		status = acpi_ns_check_package(info, return_object_ptr);
 		if (ACPI_FAILURE(status)) {
-			goto exit;
+
+			/* We might be able to fix some errors */
+
+			if ((status != AE_AML_OPERAND_TYPE) &&
+			    (status != AE_AML_OPERAND_VALUE)) {
+				goto exit;
+			}
 		}
 	}
 
@@ -199,7 +176,7 @@ acpi_ns_check_predefined_names(struct ac
 	 * performed on a per-name basis, i.e., the code is specific to
 	 * particular predefined names.
 	 */
-	status = acpi_ns_complex_repairs(data, node, status, return_object_ptr);
+	status = acpi_ns_complex_repairs(info, node, status, return_object_ptr);
 
 exit:
 	/*
@@ -207,112 +184,18 @@ exit:
 	 * or more objects, mark the parent node to suppress further warning
 	 * messages during the next evaluation of the same method/object.
 	 */
-	if (ACPI_FAILURE(status) || (data->flags & ACPI_OBJECT_REPAIRED)) {
+	if (ACPI_FAILURE(status) || (info->return_flags & ACPI_OBJECT_REPAIRED)) {
 		node->flags |= ANOBJ_EVALUATED;
 	}
-	ACPI_FREE(data);
 
-cleanup:
-	ACPI_FREE(pathname);
 	return (status);
 }
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ns_check_parameter_count
- *
- * PARAMETERS:  pathname        - Full pathname to the node (for error msgs)
- *              node            - Namespace node for the method/object
- *              user_param_count - Number of args passed in by the caller
- *              predefined      - Pointer to entry in predefined name table
- *
- * RETURN:      None
- *
- * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a
- *              predefined name is what is expected (i.e., what is defined in
- *              the ACPI specification for this predefined name.)
- *
- ******************************************************************************/
-
-void
-acpi_ns_check_parameter_count(char *pathname,
-			      struct acpi_namespace_node *node,
-			      u32 user_param_count,
-			      const union acpi_predefined_info *predefined)
-{
-	u32 param_count;
-	u32 required_params_current;
-	u32 required_params_old;
-
-	/* Methods have 0-7 parameters. All other types have zero. */
-
-	param_count = 0;
-	if (node->type == ACPI_TYPE_METHOD) {
-		param_count = node->object->method.param_count;
-	}
-
-	if (!predefined) {
-		/*
-		 * Check the parameter count for non-predefined methods/objects.
-		 *
-		 * Warning if too few or too many arguments have been passed by the
-		 * caller. An incorrect number of arguments may not cause the method
-		 * to fail. However, the method will fail if there are too few
-		 * arguments and the method attempts to use one of the missing ones.
-		 */
-		if (user_param_count < param_count) {
-			ACPI_WARN_PREDEFINED((AE_INFO, pathname,
-					      ACPI_WARN_ALWAYS,
-					      "Insufficient arguments - needs %u, found %u",
-					      param_count, user_param_count));
-		} else if (user_param_count > param_count) {
-			ACPI_WARN_PREDEFINED((AE_INFO, pathname,
-					      ACPI_WARN_ALWAYS,
-					      "Excess arguments - needs %u, found %u",
-					      param_count, user_param_count));
-		}
-		return;
-	}
-
-	/*
-	 * Validate the user-supplied parameter count.
-	 * Allow two different legal argument counts (_SCP, etc.)
-	 */
-	required_params_current =
-	    predefined->info.argument_list & METHOD_ARG_MASK;
-	required_params_old =
-	    predefined->info.argument_list >> METHOD_ARG_BIT_WIDTH;
-
-	if (user_param_count != ACPI_UINT32_MAX) {
-		if ((user_param_count != required_params_current) &&
-		    (user_param_count != required_params_old)) {
-			ACPI_WARN_PREDEFINED((AE_INFO, pathname,
-					      ACPI_WARN_ALWAYS,
-					      "Parameter count mismatch - "
-					      "caller passed %u, ACPI requires %u",
-					      user_param_count,
-					      required_params_current));
-		}
-	}
-
-	/*
-	 * Check that the ASL-defined parameter count is what is expected for
-	 * this predefined name (parameter count as defined by the ACPI
-	 * specification)
-	 */
-	if ((param_count != required_params_current) &&
-	    (param_count != required_params_old)) {
-		ACPI_WARN_PREDEFINED((AE_INFO, pathname, node->flags,
-				      "Parameter count mismatch - ASL declared %u, ACPI requires %u",
-				      param_count, required_params_current));
-	}
-}
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ns_check_object_type
  *
- * PARAMETERS:  data            - Pointer to validation data structure
+ * PARAMETERS:  info            - Method execution information block
  *              return_object_ptr - Pointer to the object returned from the
  *                                evaluation of a method or object
  *              expected_btypes - Bitmap of expected return type(s)
@@ -328,7 +211,7 @@ acpi_ns_check_parameter_count(char *path
  ******************************************************************************/
 
 acpi_status
-acpi_ns_check_object_type(struct acpi_predefined_data *data,
+acpi_ns_check_object_type(struct acpi_evaluate_info *info,
 			  union acpi_operand_object **return_object_ptr,
 			  u32 expected_btypes, u32 package_index)
 {
@@ -340,7 +223,8 @@ acpi_ns_check_object_type(struct acpi_pr
 
 	if (return_object &&
 	    ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
-		ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+				      info->node_flags,
 				      "Invalid return type - Found a Namespace node [%4.4s] type %s",
 				      return_object->node.name.ascii,
 				      acpi_ut_get_type_name(return_object->node.
@@ -356,8 +240,8 @@ acpi_ns_check_object_type(struct acpi_pr
 	 * from all of the predefined names (including elements of returned
 	 * packages)
 	 */
-	data->return_btype = acpi_ns_get_bitmapped_type(return_object);
-	if (data->return_btype == ACPI_RTYPE_ANY) {
+	info->return_btype = acpi_ns_get_bitmapped_type(return_object);
+	if (info->return_btype == ACPI_RTYPE_ANY) {
 
 		/* Not one of the supported objects, must be incorrect */
 		goto type_error_exit;
@@ -365,16 +249,18 @@ acpi_ns_check_object_type(struct acpi_pr
 
 	/* For reference objects, check that the reference type is correct */
 
-	if ((data->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) {
-		status = acpi_ns_check_reference(data, return_object);
+	if ((info->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) {
+		status = acpi_ns_check_reference(info, return_object);
 		return (status);
 	}
 
 	/* Attempt simple repair of the returned object if necessary */
 
-	status = acpi_ns_simple_repair(data, expected_btypes,
+	status = acpi_ns_simple_repair(info, expected_btypes,
 				       package_index, return_object_ptr);
-	return (status);
+	if (ACPI_SUCCESS(status)) {
+		return (AE_OK);	/* Successful repair */
+	}
 
       type_error_exit:
 
@@ -383,12 +269,14 @@ acpi_ns_check_object_type(struct acpi_pr
 	acpi_ut_get_expected_return_types(type_buffer, expected_btypes);
 
 	if (package_index == ACPI_NOT_PACKAGE_ELEMENT) {
-		ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+				      info->node_flags,
 				      "Return type mismatch - found %s, expected %s",
 				      acpi_ut_get_object_type_name
 				      (return_object), type_buffer));
 	} else {
-		ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+				      info->node_flags,
 				      "Return Package type mismatch at index %u - "
 				      "found %s, expected %s", package_index,
 				      acpi_ut_get_object_type_name
@@ -402,7 +290,7 @@ acpi_ns_check_object_type(struct acpi_pr
  *
  * FUNCTION:    acpi_ns_check_reference
  *
- * PARAMETERS:  data            - Pointer to validation data structure
+ * PARAMETERS:  info            - Method execution information block
  *              return_object   - Object returned from the evaluation of a
  *                                method or object
  *
@@ -415,7 +303,7 @@ acpi_ns_check_object_type(struct acpi_pr
  ******************************************************************************/
 
 static acpi_status
-acpi_ns_check_reference(struct acpi_predefined_data *data,
+acpi_ns_check_reference(struct acpi_evaluate_info *info,
 			union acpi_operand_object *return_object)
 {
 
@@ -428,7 +316,7 @@ acpi_ns_check_reference(struct acpi_pred
 		return (AE_OK);
 	}
 
-	ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+	ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
 			      "Return type mismatch - unexpected reference object type [%s] %2.2X",
 			      acpi_ut_get_reference_name(return_object),
 			      return_object->reference.class));
@@ -462,26 +350,32 @@ static u32 acpi_ns_get_bitmapped_type(un
 
 	switch (return_object->common.type) {
 	case ACPI_TYPE_INTEGER:
+
 		return_btype = ACPI_RTYPE_INTEGER;
 		break;
 
 	case ACPI_TYPE_BUFFER:
+
 		return_btype = ACPI_RTYPE_BUFFER;
 		break;
 
 	case ACPI_TYPE_STRING:
+
 		return_btype = ACPI_RTYPE_STRING;
 		break;
 
 	case ACPI_TYPE_PACKAGE:
+
 		return_btype = ACPI_RTYPE_PACKAGE;
 		break;
 
 	case ACPI_TYPE_LOCAL_REFERENCE:
+
 		return_btype = ACPI_RTYPE_REFERENCE;
 		break;
 
 	default:
+
 		/* Not one of the supported objects, must be incorrect */
 
 		return_btype = ACPI_RTYPE_ANY;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsprepkg.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsprepkg.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsprepkg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsprepkg.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,12 +51,12 @@ ACPI_MODULE_NAME("nsprepkg")
 
 /* Local prototypes */
 static acpi_status
-acpi_ns_check_package_list(struct acpi_predefined_data *data,
+acpi_ns_check_package_list(struct acpi_evaluate_info *info,
 			   const union acpi_predefined_info *package,
 			   union acpi_operand_object **elements, u32 count);
 
 static acpi_status
-acpi_ns_check_package_elements(struct acpi_predefined_data *data,
+acpi_ns_check_package_elements(struct acpi_evaluate_info *info,
 			       union acpi_operand_object **elements,
 			       u8 type1,
 			       u32 count1,
@@ -66,7 +66,7 @@ acpi_ns_check_package_elements(struct ac
  *
  * FUNCTION:    acpi_ns_check_package
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -78,7 +78,7 @@ acpi_ns_check_package_elements(struct ac
  ******************************************************************************/
 
 acpi_status
-acpi_ns_check_package(struct acpi_predefined_data *data,
+acpi_ns_check_package(struct acpi_evaluate_info *info,
 		      union acpi_operand_object **return_object_ptr)
 {
 	union acpi_operand_object *return_object = *return_object_ptr;
@@ -93,18 +93,18 @@ acpi_ns_check_package(struct acpi_predef
 
 	/* The package info for this name is in the next table entry */
 
-	package = data->predefined + 1;
+	package = info->predefined + 1;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 			  "%s Validating return Package of Type %X, Count %X\n",
-			  data->pathname, package->ret_info.type,
+			  info->full_pathname, package->ret_info.type,
 			  return_object->package.count));
 
 	/*
 	 * For variable-length Packages, we can safely remove all embedded
 	 * and trailing NULL package elements
 	 */
-	acpi_ns_remove_null_elements(data, package->ret_info.type,
+	acpi_ns_remove_null_elements(info, package->ret_info.type,
 				     return_object);
 
 	/* Extract package count and elements array */
@@ -121,7 +121,8 @@ acpi_ns_check_package(struct acpi_predef
 			return (AE_OK);
 		}
 
-		ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+				      info->node_flags,
 				      "Return Package has no elements (empty)"));
 
 		return (AE_AML_OPERAND_VALUE);
@@ -135,7 +136,6 @@ acpi_ns_check_package(struct acpi_predef
 	 */
 	switch (package->ret_info.type) {
 	case ACPI_PTYPE1_FIXED:
-
 		/*
 		 * The package count is fixed and there are no sub-packages
 		 *
@@ -150,13 +150,13 @@ acpi_ns_check_package(struct acpi_predef
 			ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 					  "%s: Return Package is larger than needed - "
 					  "found %u, expected %u\n",
-					  data->pathname, count,
+					  info->full_pathname, count,
 					  expected_count));
 		}
 
 		/* Validate all elements of the returned package */
 
-		status = acpi_ns_check_package_elements(data, elements,
+		status = acpi_ns_check_package_elements(info, elements,
 							package->ret_info.
 							object_type1,
 							package->ret_info.
@@ -168,13 +168,12 @@ acpi_ns_check_package(struct acpi_predef
 		break;
 
 	case ACPI_PTYPE1_VAR:
-
 		/*
 		 * The package count is variable, there are no sub-packages, and all
 		 * elements must be of the same type
 		 */
 		for (i = 0; i < count; i++) {
-			status = acpi_ns_check_object_type(data, elements,
+			status = acpi_ns_check_object_type(info, elements,
 							   package->ret_info.
 							   object_type1, i);
 			if (ACPI_FAILURE(status)) {
@@ -185,7 +184,6 @@ acpi_ns_check_package(struct acpi_predef
 		break;
 
 	case ACPI_PTYPE1_OPTION:
-
 		/*
 		 * The package count is variable, there are no sub-packages. There are
 		 * a fixed number of required elements, and a variable number of
@@ -206,7 +204,7 @@ acpi_ns_check_package(struct acpi_predef
 				/* These are the required package elements (0, 1, or 2) */
 
 				status =
-				    acpi_ns_check_object_type(data, elements,
+				    acpi_ns_check_object_type(info, elements,
 							      package->
 							      ret_info3.
 							      object_type[i],
@@ -218,7 +216,7 @@ acpi_ns_check_package(struct acpi_predef
 				/* These are the optional package elements */
 
 				status =
-				    acpi_ns_check_object_type(data, elements,
+				    acpi_ns_check_object_type(info, elements,
 							      package->
 							      ret_info3.
 							      tail_object_type,
@@ -235,7 +233,7 @@ acpi_ns_check_package(struct acpi_predef
 
 		/* First element is the (Integer) revision */
 
-		status = acpi_ns_check_object_type(data, elements,
+		status = acpi_ns_check_object_type(info, elements,
 						   ACPI_RTYPE_INTEGER, 0);
 		if (ACPI_FAILURE(status)) {
 			return (status);
@@ -247,14 +245,14 @@ acpi_ns_check_package(struct acpi_predef
 		/* Examine the sub-packages */
 
 		status =
-		    acpi_ns_check_package_list(data, package, elements, count);
+		    acpi_ns_check_package_list(info, package, elements, count);
 		break;
 
 	case ACPI_PTYPE2_PKG_COUNT:
 
 		/* First element is the (Integer) count of sub-packages to follow */
 
-		status = acpi_ns_check_object_type(data, elements,
+		status = acpi_ns_check_object_type(info, elements,
 						   ACPI_RTYPE_INTEGER, 0);
 		if (ACPI_FAILURE(status)) {
 			return (status);
@@ -275,7 +273,7 @@ acpi_ns_check_package(struct acpi_predef
 		/* Examine the sub-packages */
 
 		status =
-		    acpi_ns_check_package_list(data, package, elements, count);
+		    acpi_ns_check_package_list(info, package, elements, count);
 		break;
 
 	case ACPI_PTYPE2:
@@ -283,7 +281,6 @@ acpi_ns_check_package(struct acpi_predef
 	case ACPI_PTYPE2_MIN:
 	case ACPI_PTYPE2_COUNT:
 	case ACPI_PTYPE2_FIX_VAR:
-
 		/*
 		 * These types all return a single Package that consists of a
 		 * variable number of sub-Packages.
@@ -300,7 +297,7 @@ acpi_ns_check_package(struct acpi_predef
 			/* Create the new outer package and populate it */
 
 			status =
-			    acpi_ns_wrap_with_package(data, return_object,
+			    acpi_ns_wrap_with_package(info, return_object,
 						      return_object_ptr);
 			if (ACPI_FAILURE(status)) {
 				return (status);
@@ -316,14 +313,15 @@ acpi_ns_check_package(struct acpi_predef
 		/* Examine the sub-packages */
 
 		status =
-		    acpi_ns_check_package_list(data, package, elements, count);
+		    acpi_ns_check_package_list(info, package, elements, count);
 		break;
 
 	default:
 
 		/* Should not get here if predefined info table is correct */
 
-		ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+				      info->node_flags,
 				      "Invalid internal return type in table entry: %X",
 				      package->ret_info.type));
 
@@ -336,7 +334,7 @@ acpi_ns_check_package(struct acpi_predef
 
 	/* Error exit for the case with an incorrect package count */
 
-	ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+	ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
 			      "Return Package is too small - found %u elements, expected %u",
 			      count, expected_count));
 
@@ -347,7 +345,7 @@ acpi_ns_check_package(struct acpi_predef
  *
  * FUNCTION:    acpi_ns_check_package_list
  *
- * PARAMETERS:  data            - Pointer to validation data structure
+ * PARAMETERS:  info            - Method execution information block
  *              package         - Pointer to package-specific info for method
  *              elements        - Element list of parent package. All elements
  *                                of this list should be of type Package.
@@ -360,7 +358,7 @@ acpi_ns_check_package(struct acpi_predef
  ******************************************************************************/
 
 static acpi_status
-acpi_ns_check_package_list(struct acpi_predefined_data *data,
+acpi_ns_check_package_list(struct acpi_evaluate_info *info,
 			   const union acpi_predefined_info *package,
 			   union acpi_operand_object **elements, u32 count)
 {
@@ -381,11 +379,11 @@ acpi_ns_check_package_list(struct acpi_p
 	for (i = 0; i < count; i++) {
 		sub_package = *elements;
 		sub_elements = sub_package->package.elements;
-		data->parent_package = sub_package;
+		info->parent_package = sub_package;
 
 		/* Each sub-object must be of type Package */
 
-		status = acpi_ns_check_object_type(data, &sub_package,
+		status = acpi_ns_check_object_type(info, &sub_package,
 						   ACPI_RTYPE_PACKAGE, i);
 		if (ACPI_FAILURE(status)) {
 			return (status);
@@ -393,7 +391,7 @@ acpi_ns_check_package_list(struct acpi_p
 
 		/* Examine the different types of expected sub-packages */
 
-		data->parent_package = sub_package;
+		info->parent_package = sub_package;
 		switch (package->ret_info.type) {
 		case ACPI_PTYPE2:
 		case ACPI_PTYPE2_PKG_COUNT:
@@ -408,7 +406,7 @@ acpi_ns_check_package_list(struct acpi_p
 			}
 
 			status =
-			    acpi_ns_check_package_elements(data, sub_elements,
+			    acpi_ns_check_package_elements(info, sub_elements,
 							   package->ret_info.
 							   object_type1,
 							   package->ret_info.
@@ -434,7 +432,7 @@ acpi_ns_check_package_list(struct acpi_p
 			}
 
 			status =
-			    acpi_ns_check_package_elements(data, sub_elements,
+			    acpi_ns_check_package_elements(info, sub_elements,
 							   package->ret_info.
 							   object_type1,
 							   package->ret_info.
@@ -463,7 +461,7 @@ acpi_ns_check_package_list(struct acpi_p
 
 			for (j = 0; j < expected_count; j++) {
 				status =
-				    acpi_ns_check_object_type(data,
+				    acpi_ns_check_object_type(info,
 							      &sub_elements[j],
 							      package->
 							      ret_info2.
@@ -487,7 +485,7 @@ acpi_ns_check_package_list(struct acpi_p
 			/* Check the type of each sub-package element */
 
 			status =
-			    acpi_ns_check_package_elements(data, sub_elements,
+			    acpi_ns_check_package_elements(info, sub_elements,
 							   package->ret_info.
 							   object_type1,
 							   sub_package->package.
@@ -498,12 +496,11 @@ acpi_ns_check_package_list(struct acpi_p
 			break;
 
 		case ACPI_PTYPE2_COUNT:
-
 			/*
 			 * First element is the (Integer) count of elements, including
 			 * the count field (the ACPI name is num_elements)
 			 */
-			status = acpi_ns_check_object_type(data, sub_elements,
+			status = acpi_ns_check_object_type(info, sub_elements,
 							   ACPI_RTYPE_INTEGER,
 							   0);
 			if (ACPI_FAILURE(status)) {
@@ -537,7 +534,7 @@ acpi_ns_check_package_list(struct acpi_p
 			/* Check the type of each sub-package element */
 
 			status =
-			    acpi_ns_check_package_elements(data,
+			    acpi_ns_check_package_elements(info,
 							   (sub_elements + 1),
 							   package->ret_info.
 							   object_type1,
@@ -562,7 +559,7 @@ acpi_ns_check_package_list(struct acpi_p
 
 	/* The sub-package count was smaller than required */
 
-	ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+	ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
 			      "Return Sub-Package[%u] is too small - found %u elements, expected %u",
 			      i, sub_package->package.count, expected_count));
 
@@ -573,7 +570,7 @@ acpi_ns_check_package_list(struct acpi_p
  *
  * FUNCTION:    acpi_ns_check_package_elements
  *
- * PARAMETERS:  data            - Pointer to validation data structure
+ * PARAMETERS:  info            - Method execution information block
  *              elements        - Pointer to the package elements array
  *              type1           - Object type for first group
  *              count1          - Count for first group
@@ -589,7 +586,7 @@ acpi_ns_check_package_list(struct acpi_p
  ******************************************************************************/
 
 static acpi_status
-acpi_ns_check_package_elements(struct acpi_predefined_data *data,
+acpi_ns_check_package_elements(struct acpi_evaluate_info *info,
 			       union acpi_operand_object **elements,
 			       u8 type1,
 			       u32 count1,
@@ -605,7 +602,7 @@ acpi_ns_check_package_elements(struct ac
 	 * The second group can have a count of zero.
 	 */
 	for (i = 0; i < count1; i++) {
-		status = acpi_ns_check_object_type(data, this_element,
+		status = acpi_ns_check_object_type(info, this_element,
 						   type1, i + start_index);
 		if (ACPI_FAILURE(status)) {
 			return (status);
@@ -614,7 +611,7 @@ acpi_ns_check_package_elements(struct ac
 	}
 
 	for (i = 0; i < count2; i++) {
-		status = acpi_ns_check_object_type(data, this_element,
+		status = acpi_ns_check_object_type(info, this_element,
 						   type2,
 						   (i + count1 + start_index));
 		if (ACPI_FAILURE(status)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsrepair2.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsrepair2.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsrepair2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsrepair2.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ ACPI_MODULE_NAME("nsrepair2")
  * be repaired on a per-name basis.
  */
 typedef
-acpi_status(*acpi_repair_function) (struct acpi_predefined_data *data,
+acpi_status(*acpi_repair_function) (struct acpi_evaluate_info * info,
 				    union acpi_operand_object
 				    **return_object_ptr);
 
@@ -71,45 +71,57 @@ static const struct acpi_repair_info *ac
 								   *node);
 
 static acpi_status
-acpi_ns_repair_ALR(struct acpi_predefined_data *data,
+acpi_ns_repair_ALR(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_CID(struct acpi_predefined_data *data,
+acpi_ns_repair_CID(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_FDE(struct acpi_predefined_data *data,
+acpi_ns_repair_CST(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_HID(struct acpi_predefined_data *data,
+acpi_ns_repair_FDE(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_PSS(struct acpi_predefined_data *data,
+acpi_ns_repair_HID(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_TSS(struct acpi_predefined_data *data,
+acpi_ns_repair_PRT(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
+acpi_ns_repair_PSS(struct acpi_evaluate_info *info,
+		   union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_repair_TSS(struct acpi_evaluate_info *info,
+		   union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_check_sorted_list(struct acpi_evaluate_info *info,
 			  union acpi_operand_object *return_object,
+			  u32 start_index,
 			  u32 expected_count,
 			  u32 sort_index,
 			  u8 sort_direction, char *sort_key_name);
 
-static void
-acpi_ns_sort_list(union acpi_operand_object **elements,
-		  u32 count, u32 index, u8 sort_direction);
-
 /* Values for sort_direction above */
 
 #define ACPI_SORT_ASCENDING     0
 #define ACPI_SORT_DESCENDING    1
 
+static void
+acpi_ns_remove_element(union acpi_operand_object *obj_desc, u32 index);
+
+static void
+acpi_ns_sort_list(union acpi_operand_object **elements,
+		  u32 count, u32 index, u8 sort_direction);
+
 /*
  * This table contains the names of the predefined methods for which we can
  * perform more complex repairs.
@@ -118,9 +130,11 @@ acpi_ns_sort_list(union acpi_operand_obj
  *
  * _ALR: Sort the list ascending by ambient_illuminance
  * _CID: Strings: uppercase all, remove any leading asterisk
+ * _CST: Sort the list ascending by C state type
  * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
  * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
  * _HID: Strings: uppercase all, remove any leading asterisk
+ * _PRT: Fix reversed source_name and source_index
  * _PSS: Sort the list descending by Power
  * _TSS: Sort the list descending by Power
  *
@@ -134,9 +148,11 @@ acpi_ns_sort_list(union acpi_operand_obj
 static const struct acpi_repair_info acpi_ns_repairable_names[] = {
 	{"_ALR", acpi_ns_repair_ALR},
 	{"_CID", acpi_ns_repair_CID},
+	{"_CST", acpi_ns_repair_CST},
 	{"_FDE", acpi_ns_repair_FDE},
 	{"_GTM", acpi_ns_repair_FDE},	/* _GTM has same repair as _FDE */
 	{"_HID", acpi_ns_repair_HID},
+	{"_PRT", acpi_ns_repair_PRT},
 	{"_PSS", acpi_ns_repair_PSS},
 	{"_TSS", acpi_ns_repair_TSS},
 	{{0, 0, 0, 0}, NULL}	/* Table terminator */
@@ -150,7 +166,7 @@ static const struct acpi_repair_info acp
  *
  * FUNCTION:    acpi_ns_complex_repairs
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              node                - Namespace node for the method/object
  *              validate_status     - Original status of earlier validation
  *              return_object_ptr   - Pointer to the object returned from the
@@ -165,7 +181,7 @@ static const struct acpi_repair_info acp
  *****************************************************************************/
 
 acpi_status
-acpi_ns_complex_repairs(struct acpi_predefined_data *data,
+acpi_ns_complex_repairs(struct acpi_evaluate_info *info,
 			struct acpi_namespace_node *node,
 			acpi_status validate_status,
 			union acpi_operand_object **return_object_ptr)
@@ -180,7 +196,7 @@ acpi_ns_complex_repairs(struct acpi_pred
 		return (validate_status);
 	}
 
-	status = predefined->repair_function(data, return_object_ptr);
+	status = predefined->repair_function(info, return_object_ptr);
 	return (status);
 }
 
@@ -219,7 +235,7 @@ static const struct acpi_repair_info *ac
  *
  * FUNCTION:    acpi_ns_repair_ALR
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -231,13 +247,13 @@ static const struct acpi_repair_info *ac
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_ALR(struct acpi_predefined_data *data,
+acpi_ns_repair_ALR(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr)
 {
 	union acpi_operand_object *return_object = *return_object_ptr;
 	acpi_status status;
 
-	status = acpi_ns_check_sorted_list(data, return_object, 2, 1,
+	status = acpi_ns_check_sorted_list(info, return_object, 0, 2, 1,
 					   ACPI_SORT_ASCENDING,
 					   "AmbientIlluminance");
 
@@ -248,7 +264,7 @@ acpi_ns_repair_ALR(struct acpi_predefine
  *
  * FUNCTION:    acpi_ns_repair_FDE
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -262,7 +278,7 @@ acpi_ns_repair_ALR(struct acpi_predefine
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_FDE(struct acpi_predefined_data *data,
+acpi_ns_repair_FDE(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr)
 {
 	union acpi_operand_object *return_object = *return_object_ptr;
@@ -285,8 +301,8 @@ acpi_ns_repair_FDE(struct acpi_predefine
 		/* We can only repair if we have exactly 5 BYTEs */
 
 		if (return_object->buffer.length != ACPI_FDE_BYTE_BUFFER_SIZE) {
-			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
-					      data->node_flags,
+			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+					      info->node_flags,
 					      "Incorrect return buffer length %u, expected %u",
 					      return_object->buffer.length,
 					      ACPI_FDE_DWORD_BUFFER_SIZE));
@@ -316,10 +332,11 @@ acpi_ns_repair_FDE(struct acpi_predefine
 
 		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 				  "%s Expanded Byte Buffer to expected DWord Buffer\n",
-				  data->pathname));
+				  info->full_pathname));
 		break;
 
 	default:
+
 		return (AE_AML_OPERAND_TYPE);
 	}
 
@@ -328,7 +345,7 @@ acpi_ns_repair_FDE(struct acpi_predefine
 	acpi_ut_remove_reference(return_object);
 	*return_object_ptr = buffer_object;
 
-	data->flags |= ACPI_OBJECT_REPAIRED;
+	info->return_flags |= ACPI_OBJECT_REPAIRED;
 	return (AE_OK);
 }
 
@@ -336,7 +353,7 @@ acpi_ns_repair_FDE(struct acpi_predefine
  *
  * FUNCTION:    acpi_ns_repair_CID
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -349,7 +366,7 @@ acpi_ns_repair_FDE(struct acpi_predefine
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_CID(struct acpi_predefined_data *data,
+acpi_ns_repair_CID(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr)
 {
 	acpi_status status;
@@ -362,7 +379,7 @@ acpi_ns_repair_CID(struct acpi_predefine
 	/* Check for _CID as a simple string */
 
 	if (return_object->common.type == ACPI_TYPE_STRING) {
-		status = acpi_ns_repair_HID(data, return_object_ptr);
+		status = acpi_ns_repair_HID(info, return_object_ptr);
 		return (status);
 	}
 
@@ -379,7 +396,7 @@ acpi_ns_repair_CID(struct acpi_predefine
 		original_element = *element_ptr;
 		original_ref_count = original_element->common.reference_count;
 
-		status = acpi_ns_repair_HID(data, element_ptr);
+		status = acpi_ns_repair_HID(info, element_ptr);
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -404,9 +421,95 @@ acpi_ns_repair_CID(struct acpi_predefine
 
 /******************************************************************************
  *
+ * FUNCTION:    acpi_ns_repair_CST
+ *
+ * PARAMETERS:  info                - Method execution information block
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _CST object:
+ *              1. Sort the list ascending by C state type
+ *              2. Ensure type cannot be zero
+ *              3. A sub-package count of zero means _CST is meaningless
+ *              4. Count must match the number of C state sub-packages
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_CST(struct acpi_evaluate_info *info,
+		   union acpi_operand_object **return_object_ptr)
+{
+	union acpi_operand_object *return_object = *return_object_ptr;
+	union acpi_operand_object **outer_elements;
+	u32 outer_element_count;
+	union acpi_operand_object *obj_desc;
+	acpi_status status;
+	u8 removing;
+	u32 i;
+
+	ACPI_FUNCTION_NAME(ns_repair_CST);
+
+	/*
+	 * Check if the C-state type values are proportional.
+	 */
+	outer_element_count = return_object->package.count - 1;
+	i = 0;
+	while (i < outer_element_count) {
+		outer_elements = &return_object->package.elements[i + 1];
+		removing = FALSE;
+
+		if ((*outer_elements)->package.count == 0) {
+			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+					      info->node_flags,
+					      "SubPackage[%u] - removing entry due to zero count",
+					      i));
+			removing = TRUE;
+			goto remove_element;
+		}
+
+		obj_desc = (*outer_elements)->package.elements[1];	/* Index1 = Type */
+		if ((u32)obj_desc->integer.value == 0) {
+			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+					      info->node_flags,
+					      "SubPackage[%u] - removing entry due to invalid Type(0)",
+					      i));
+			removing = TRUE;
+		}
+
+	      remove_element:
+		if (removing) {
+			acpi_ns_remove_element(return_object, i + 1);
+			outer_element_count--;
+		} else {
+			i++;
+		}
+	}
+
+	/* Update top-level package count, Type "Integer" checked elsewhere */
+
+	obj_desc = return_object->package.elements[0];
+	obj_desc->integer.value = outer_element_count;
+
+	/*
+	 * Entries (subpackages) in the _CST Package must be sorted by the
+	 * C-state type, in ascending order.
+	 */
+	status = acpi_ns_check_sorted_list(info, return_object, 1, 4, 1,
+					   ACPI_SORT_ASCENDING, "C-State Type");
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
  * FUNCTION:    acpi_ns_repair_HID
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -418,7 +521,7 @@ acpi_ns_repair_CID(struct acpi_predefine
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_HID(struct acpi_predefined_data *data,
+acpi_ns_repair_HID(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr)
 {
 	union acpi_operand_object *return_object = *return_object_ptr;
@@ -435,12 +538,13 @@ acpi_ns_repair_HID(struct acpi_predefine
 	}
 
 	if (return_object->string.length == 0) {
-		ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+				      info->node_flags,
 				      "Invalid zero-length _HID or _CID string"));
 
 		/* Return AE_OK anyway, let driver handle it */
 
-		data->flags |= ACPI_OBJECT_REPAIRED;
+		info->return_flags |= ACPI_OBJECT_REPAIRED;
 		return (AE_OK);
 	}
 
@@ -464,7 +568,7 @@ acpi_ns_repair_HID(struct acpi_predefine
 
 		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 				  "%s: Removed invalid leading asterisk\n",
-				  data->pathname));
+				  info->full_pathname));
 	}
 
 	/*
@@ -486,53 +590,69 @@ acpi_ns_repair_HID(struct acpi_predefine
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_ns_repair_TSS
+ * FUNCTION:    acpi_ns_repair_PRT
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  *
- * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
- *              descending by the power dissipation values.
+ * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
+ *              source_name and source_index field, a common BIOS bug.
  *
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_TSS(struct acpi_predefined_data *data,
+acpi_ns_repair_PRT(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr)
 {
-	union acpi_operand_object *return_object = *return_object_ptr;
-	acpi_status status;
-	struct acpi_namespace_node *node;
+	union acpi_operand_object *package_object = *return_object_ptr;
+	union acpi_operand_object **top_object_list;
+	union acpi_operand_object **sub_object_list;
+	union acpi_operand_object *obj_desc;
+	u32 element_count;
+	u32 index;
 
-	/*
-	 * We can only sort the _TSS return package if there is no _PSS in the
-	 * same scope. This is because if _PSS is present, the ACPI specification
-	 * dictates that the _TSS Power Dissipation field is to be ignored, and
-	 * therefore some BIOSs leave garbage values in the _TSS Power field(s).
-	 * In this case, it is best to just return the _TSS package as-is.
-	 * (May, 2011)
-	 */
-	status =
-	    acpi_ns_get_node(data->node, "^_PSS", ACPI_NS_NO_UPSEARCH, &node);
-	if (ACPI_SUCCESS(status)) {
-		return (AE_OK);
-	}
+	/* Each element in the _PRT package is a subpackage */
 
-	status = acpi_ns_check_sorted_list(data, return_object, 5, 1,
-					   ACPI_SORT_DESCENDING,
-					   "PowerDissipation");
+	top_object_list = package_object->package.elements;
+	element_count = package_object->package.count;
 
-	return (status);
+	for (index = 0; index < element_count; index++) {
+		sub_object_list = (*top_object_list)->package.elements;
+
+		/*
+		 * If the BIOS has erroneously reversed the _PRT source_name (index 2)
+		 * and the source_index (index 3), fix it. _PRT is important enough to
+		 * workaround this BIOS error. This also provides compatibility with
+		 * other ACPI implementations.
+		 */
+		obj_desc = sub_object_list[3];
+		if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
+			sub_object_list[3] = sub_object_list[2];
+			sub_object_list[2] = obj_desc;
+			info->return_flags |= ACPI_OBJECT_REPAIRED;
+
+			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+					      info->node_flags,
+					      "PRT[%X]: Fixed reversed SourceName and SourceIndex",
+					      index));
+		}
+
+		/* Point to the next union acpi_operand_object in the top level package */
+
+		top_object_list++;
+	}
+
+	return (AE_OK);
 }
 
 /******************************************************************************
  *
  * FUNCTION:    acpi_ns_repair_PSS
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -546,7 +666,7 @@ acpi_ns_repair_TSS(struct acpi_predefine
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_PSS(struct acpi_predefined_data *data,
+acpi_ns_repair_PSS(struct acpi_evaluate_info *info,
 		   union acpi_operand_object **return_object_ptr)
 {
 	union acpi_operand_object *return_object = *return_object_ptr;
@@ -564,7 +684,7 @@ acpi_ns_repair_PSS(struct acpi_predefine
 	 * incorrectly sorted, sort it. We sort by cpu_frequency, since this
 	 * should be proportional to the power.
 	 */
-	status = acpi_ns_check_sorted_list(data, return_object, 6, 0,
+	status = acpi_ns_check_sorted_list(info, return_object, 0, 6, 0,
 					   ACPI_SORT_DESCENDING,
 					   "CpuFrequency");
 	if (ACPI_FAILURE(status)) {
@@ -584,8 +704,8 @@ acpi_ns_repair_PSS(struct acpi_predefine
 		obj_desc = elements[1];	/* Index1 = power_dissipation */
 
 		if ((u32) obj_desc->integer.value > previous_value) {
-			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
-					      data->node_flags,
+			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+					      info->node_flags,
 					      "SubPackage[%u,%u] - suspicious power dissipation values",
 					      i - 1, i));
 		}
@@ -599,10 +719,55 @@ acpi_ns_repair_PSS(struct acpi_predefine
 
 /******************************************************************************
  *
+ * FUNCTION:    acpi_ns_repair_TSS
+ *
+ * PARAMETERS:  info                - Method execution information block
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
+ *              descending by the power dissipation values.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_TSS(struct acpi_evaluate_info *info,
+		   union acpi_operand_object **return_object_ptr)
+{
+	union acpi_operand_object *return_object = *return_object_ptr;
+	acpi_status status;
+	struct acpi_namespace_node *node;
+
+	/*
+	 * We can only sort the _TSS return package if there is no _PSS in the
+	 * same scope. This is because if _PSS is present, the ACPI specification
+	 * dictates that the _TSS Power Dissipation field is to be ignored, and
+	 * therefore some BIOSs leave garbage values in the _TSS Power field(s).
+	 * In this case, it is best to just return the _TSS package as-is.
+	 * (May, 2011)
+	 */
+	status = acpi_ns_get_node(info->node, "^_PSS",
+				  ACPI_NS_NO_UPSEARCH, &node);
+	if (ACPI_SUCCESS(status)) {
+		return (AE_OK);
+	}
+
+	status = acpi_ns_check_sorted_list(info, return_object, 0, 5, 1,
+					   ACPI_SORT_DESCENDING,
+					   "PowerDissipation");
+
+	return (status);
+}
+
+/******************************************************************************
+ *
  * FUNCTION:    acpi_ns_check_sorted_list
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object       - Pointer to the top-level returned object
+ *              start_index         - Index of the first sub-package
  *              expected_count      - Minimum length of each sub-package
  *              sort_index          - Sub-package entry to sort on
  *              sort_direction      - Ascending or descending
@@ -617,8 +782,9 @@ acpi_ns_repair_PSS(struct acpi_predefine
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
+acpi_ns_check_sorted_list(struct acpi_evaluate_info *info,
 			  union acpi_operand_object *return_object,
+			  u32 start_index,
 			  u32 expected_count,
 			  u32 sort_index,
 			  u8 sort_direction, char *sort_key_name)
@@ -643,12 +809,14 @@ acpi_ns_check_sorted_list(struct acpi_pr
 	 * Any NULL elements should have been removed by earlier call
 	 * to acpi_ns_remove_null_elements.
 	 */
-	outer_elements = return_object->package.elements;
 	outer_element_count = return_object->package.count;
-	if (!outer_element_count) {
+	if (!outer_element_count || start_index >= outer_element_count) {
 		return (AE_AML_PACKAGE_LIMIT);
 	}
 
+	outer_elements = &return_object->package.elements[start_index];
+	outer_element_count -= start_index;
+
 	previous_value = 0;
 	if (sort_direction == ACPI_SORT_DESCENDING) {
 		previous_value = ACPI_UINT32_MAX;
@@ -685,15 +853,16 @@ acpi_ns_check_sorted_list(struct acpi_pr
 		     (obj_desc->integer.value < previous_value)) ||
 		    ((sort_direction == ACPI_SORT_DESCENDING) &&
 		     (obj_desc->integer.value > previous_value))) {
-			acpi_ns_sort_list(return_object->package.elements,
+			acpi_ns_sort_list(&return_object->package.
+					  elements[start_index],
 					  outer_element_count, sort_index,
 					  sort_direction);
 
-			data->flags |= ACPI_OBJECT_REPAIRED;
+			info->return_flags |= ACPI_OBJECT_REPAIRED;
 
 			ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 					  "%s: Repaired unsorted list - now sorted by %s\n",
-					  data->pathname, sort_key_name));
+					  info->full_pathname, sort_key_name));
 			return (AE_OK);
 		}
 
@@ -752,3 +921,52 @@ acpi_ns_sort_list(union acpi_operand_obj
 		}
 	}
 }
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_remove_element
+ *
+ * PARAMETERS:  obj_desc            - Package object element list
+ *              index               - Index of element to remove
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Remove the requested element of a package and delete it.
+ *
+ *****************************************************************************/
+
+static void
+acpi_ns_remove_element(union acpi_operand_object *obj_desc, u32 index)
+{
+	union acpi_operand_object **source;
+	union acpi_operand_object **dest;
+	u32 count;
+	u32 new_count;
+	u32 i;
+
+	ACPI_FUNCTION_NAME(ns_remove_element);
+
+	count = obj_desc->package.count;
+	new_count = count - 1;
+
+	source = obj_desc->package.elements;
+	dest = source;
+
+	/* Examine all elements of the package object, remove matched index */
+
+	for (i = 0; i < count; i++) {
+		if (i == index) {
+			acpi_ut_remove_reference(*source);	/* Remove one ref for being in pkg */
+			acpi_ut_remove_reference(*source);
+		} else {
+			*dest = *source;
+			dest++;
+		}
+		source++;
+	}
+
+	/* NULL terminate list and update the package count */
+
+	*dest = NULL;
+	obj_desc->package.count = new_count;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsrepair.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsrepair.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsrepair.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsrepair.c	2013-08-25 20:43:22.000000000 -0400
@@ -130,7 +130,7 @@ static const struct acpi_simple_repair_i
  *
  * FUNCTION:    acpi_ns_simple_repair
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              expected_btypes     - Object types expected
  *              package_index       - Index of object within parent package (if
  *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
@@ -146,7 +146,7 @@ static const struct acpi_simple_repair_i
  ******************************************************************************/
 
 acpi_status
-acpi_ns_simple_repair(struct acpi_predefined_data *data,
+acpi_ns_simple_repair(struct acpi_evaluate_info *info,
 		      u32 expected_btypes,
 		      u32 package_index,
 		      union acpi_operand_object **return_object_ptr)
@@ -162,12 +162,12 @@ acpi_ns_simple_repair(struct acpi_predef
 	 * Special repairs for certain names that are in the repair table.
 	 * Check if this name is in the list of repairable names.
 	 */
-	predefined = acpi_ns_match_simple_repair(data->node,
-						 data->return_btype,
+	predefined = acpi_ns_match_simple_repair(info->node,
+						 info->return_btype,
 						 package_index);
 	if (predefined) {
 		if (!return_object) {
-			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
+			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
 					      ACPI_WARN_ALWAYS,
 					      "Missing expected return value"));
 		}
@@ -191,7 +191,7 @@ acpi_ns_simple_repair(struct acpi_predef
 	 * Do not perform simple object repair unless the return type is not
 	 * expected.
 	 */
-	if (data->return_btype & expected_btypes) {
+	if (info->return_btype & expected_btypes) {
 		return (AE_OK);
 	}
 
@@ -211,7 +211,7 @@ acpi_ns_simple_repair(struct acpi_predef
 	 */
 	if (!return_object) {
 		if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
-			ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
+			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
 					      ACPI_WARN_ALWAYS,
 					      "Missing expected return value"));
 
@@ -247,14 +247,14 @@ acpi_ns_simple_repair(struct acpi_predef
 		 * for correct contents (expected object type or types).
 		 */
 		status =
-		    acpi_ns_wrap_with_package(data, return_object, &new_object);
+		    acpi_ns_wrap_with_package(info, return_object, &new_object);
 		if (ACPI_SUCCESS(status)) {
 			/*
 			 * The original object just had its reference count
 			 * incremented for being inserted into the new package.
 			 */
 			*return_object_ptr = new_object;	/* New Package object */
-			data->flags |= ACPI_OBJECT_REPAIRED;
+			info->return_flags |= ACPI_OBJECT_REPAIRED;
 			return (AE_OK);
 		}
 	}
@@ -277,7 +277,7 @@ acpi_ns_simple_repair(struct acpi_predef
 		 * package object as part of the repair, we don't need to
 		 * change the reference count.
 		 */
-		if (!(data->flags & ACPI_OBJECT_WRAPPED)) {
+		if (!(info->return_flags & ACPI_OBJECT_WRAPPED)) {
 			new_object->common.reference_count =
 			    return_object->common.reference_count;
 
@@ -288,14 +288,14 @@ acpi_ns_simple_repair(struct acpi_predef
 
 		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 				  "%s: Converted %s to expected %s at Package index %u\n",
-				  data->pathname,
+				  info->full_pathname,
 				  acpi_ut_get_object_type_name(return_object),
 				  acpi_ut_get_object_type_name(new_object),
 				  package_index));
 	} else {
 		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 				  "%s: Converted %s to expected %s\n",
-				  data->pathname,
+				  info->full_pathname,
 				  acpi_ut_get_object_type_name(return_object),
 				  acpi_ut_get_object_type_name(new_object)));
 	}
@@ -304,7 +304,7 @@ acpi_ns_simple_repair(struct acpi_predef
 
 	acpi_ut_remove_reference(return_object);
 	*return_object_ptr = new_object;
-	data->flags |= ACPI_OBJECT_REPAIRED;
+	info->return_flags |= ACPI_OBJECT_REPAIRED;
 	return (AE_OK);
 }
 
@@ -359,7 +359,7 @@ static const struct acpi_simple_repair_i
  *
  * FUNCTION:    acpi_ns_repair_null_element
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              expected_btypes     - Object types expected
  *              package_index       - Index of object within parent package (if
  *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
@@ -374,7 +374,7 @@ static const struct acpi_simple_repair_i
  ******************************************************************************/
 
 acpi_status
-acpi_ns_repair_null_element(struct acpi_predefined_data *data,
+acpi_ns_repair_null_element(struct acpi_evaluate_info * info,
 			    u32 expected_btypes,
 			    u32 package_index,
 			    union acpi_operand_object **return_object_ptr)
@@ -424,16 +424,16 @@ acpi_ns_repair_null_element(struct acpi_
 	/* Set the reference count according to the parent Package object */
 
 	new_object->common.reference_count =
-	    data->parent_package->common.reference_count;
+	    info->parent_package->common.reference_count;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 			  "%s: Converted NULL package element to expected %s at index %u\n",
-			  data->pathname,
+			  info->full_pathname,
 			  acpi_ut_get_object_type_name(new_object),
 			  package_index));
 
 	*return_object_ptr = new_object;
-	data->flags |= ACPI_OBJECT_REPAIRED;
+	info->return_flags |= ACPI_OBJECT_REPAIRED;
 	return (AE_OK);
 }
 
@@ -441,7 +441,7 @@ acpi_ns_repair_null_element(struct acpi_
  *
  * FUNCTION:    acpi_ns_remove_null_elements
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              package_type        - An acpi_return_package_types value
  *              obj_desc            - A Package object
  *
@@ -454,7 +454,7 @@ acpi_ns_repair_null_element(struct acpi_
  *****************************************************************************/
 
 void
-acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
+acpi_ns_remove_null_elements(struct acpi_evaluate_info *info,
 			     u8 package_type,
 			     union acpi_operand_object *obj_desc)
 {
@@ -480,6 +480,7 @@ acpi_ns_remove_null_elements(struct acpi
 	case ACPI_PTYPE2_MIN:
 	case ACPI_PTYPE2_REV_FIXED:
 	case ACPI_PTYPE2_FIX_VAR:
+
 		break;
 
 	default:
@@ -511,7 +512,7 @@ acpi_ns_remove_null_elements(struct acpi
 	if (new_count < count) {
 		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 				  "%s: Found and removed %u NULL elements\n",
-				  data->pathname, (count - new_count)));
+				  info->full_pathname, (count - new_count)));
 
 		/* NULL terminate list and update the package count */
 
@@ -524,7 +525,7 @@ acpi_ns_remove_null_elements(struct acpi
  *
  * FUNCTION:    acpi_ns_wrap_with_package
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              original_object     - Pointer to the object to repair.
  *              obj_desc_ptr        - The new package object is returned here
  *
@@ -545,7 +546,7 @@ acpi_ns_remove_null_elements(struct acpi
  ******************************************************************************/
 
 acpi_status
-acpi_ns_wrap_with_package(struct acpi_predefined_data *data,
+acpi_ns_wrap_with_package(struct acpi_evaluate_info *info,
 			  union acpi_operand_object *original_object,
 			  union acpi_operand_object **obj_desc_ptr)
 {
@@ -566,12 +567,12 @@ acpi_ns_wrap_with_package(struct acpi_pr
 
 	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 			  "%s: Wrapped %s with expected Package object\n",
-			  data->pathname,
+			  info->full_pathname,
 			  acpi_ut_get_object_type_name(original_object)));
 
 	/* Return the new object in the object pointer */
 
 	*obj_desc_ptr = pkg_obj_desc;
-	data->flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
+	info->return_flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
 	return (AE_OK);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsutils.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsutils.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsutils.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsutils.c	2013-08-25 20:43:22.000000000 -0400
@@ -419,10 +419,12 @@ acpi_ns_externalize_name(u32 internal_na
 
 	switch (internal_name[0]) {
 	case AML_ROOT_PREFIX:
+
 		prefix_length = 1;
 		break;
 
 	case AML_PARENT_PREFIX:
+
 		for (i = 0; i < internal_name_length; i++) {
 			if (ACPI_IS_PARENT_PREFIX(internal_name[i])) {
 				prefix_length = i + 1;
@@ -438,6 +440,7 @@ acpi_ns_externalize_name(u32 internal_na
 		break;
 
 	default:
+
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/nsxfeval.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsxfeval.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/nsxfeval.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/nsxfeval.c	2013-08-25 20:43:22.000000000 -0400
@@ -187,8 +187,6 @@ acpi_evaluate_object(acpi_handle handle,
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	info->pathname = pathname;
-
 	/* Convert and validate the device handle */
 
 	info->prefix_node = acpi_ns_validate_handle(handle);
@@ -198,17 +196,64 @@ acpi_evaluate_object(acpi_handle handle,
 	}
 
 	/*
-	 * If there are parameters to be passed to a control method, the external
-	 * objects must all be converted to internal objects
+	 * Get the actual namespace node for the target object.
+	 * Handles these cases:
+	 *
+	 * 1) Null node, valid pathname from root (absolute path)
+	 * 2) Node and valid pathname (path relative to Node)
+	 * 3) Node, Null pathname
+	 */
+	if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {
+
+		/* The path is fully qualified, just evaluate by name */
+
+		info->prefix_node = NULL;
+	} else if (!handle) {
+		/*
+		 * A handle is optional iff a fully qualified pathname is specified.
+		 * Since we've already handled fully qualified names above, this is
+		 * an error.
+		 */
+		if (!pathname) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					  "Both Handle and Pathname are NULL"));
+		} else {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					  "Null Handle with relative pathname [%s]",
+					  pathname));
+		}
+
+		status = AE_BAD_PARAMETER;
+		goto cleanup;
+	}
+
+	info->relative_pathname = pathname;
+
+	/*
+	 * Convert all external objects passed as arguments to the
+	 * internal version(s).
 	 */
 	if (external_params && external_params->count) {
+		info->param_count = (u16)external_params->count;
+
+		/* Warn on impossible argument count */
+
+		if (info->param_count > ACPI_METHOD_NUM_ARGS) {
+			ACPI_WARN_PREDEFINED((AE_INFO, pathname,
+					      ACPI_WARN_ALWAYS,
+					      "Excess arguments (%u) - using only %u",
+					      info->param_count,
+					      ACPI_METHOD_NUM_ARGS));
+
+			info->param_count = ACPI_METHOD_NUM_ARGS;
+		}
+
 		/*
 		 * Allocate a new parameter block for the internal objects
 		 * Add 1 to count to allow for null terminated internal list
 		 */
-		info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
-							 external_params->
-							 count +
+		info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) info->
+							 param_count +
 							 1) * sizeof(void *));
 		if (!info->parameters) {
 			status = AE_NO_MEMORY;
@@ -217,7 +262,7 @@ acpi_evaluate_object(acpi_handle handle,
 
 		/* Convert each external object in the list to an internal object */
 
-		for (i = 0; i < external_params->count; i++) {
+		for (i = 0; i < info->param_count; i++) {
 			status =
 			    acpi_ut_copy_eobject_to_iobject(&external_params->
 							    pointer[i],
@@ -227,43 +272,96 @@ acpi_evaluate_object(acpi_handle handle,
 				goto cleanup;
 			}
 		}
-		info->parameters[external_params->count] = NULL;
+
+		info->parameters[info->param_count] = NULL;
 	}
 
+#if 0
+
 	/*
-	 * Three major cases:
-	 * 1) Fully qualified pathname
-	 * 2) No handle, not fully qualified pathname (error)
-	 * 3) Valid handle
+	 * Begin incoming argument count analysis. Check for too few args
+	 * and too many args.
 	 */
-	if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {
 
-		/* The path is fully qualified, just evaluate by name */
+	switch (acpi_ns_get_type(info->node)) {
+	case ACPI_TYPE_METHOD:
+
+		/* Check incoming argument count against the method definition */
+
+		if (info->obj_desc->method.param_count > info->param_count) {
+			ACPI_ERROR((AE_INFO,
+				    "Insufficient arguments (%u) - %u are required",
+				    info->param_count,
+				    info->obj_desc->method.param_count));
+
+			status = AE_MISSING_ARGUMENTS;
+			goto cleanup;
+		}
+
+		else if (info->obj_desc->method.param_count < info->param_count) {
+			ACPI_WARNING((AE_INFO,
+				      "Excess arguments (%u) - only %u are required",
+				      info->param_count,
+				      info->obj_desc->method.param_count));
+
+			/* Just pass the required number of arguments */
+
+			info->param_count = info->obj_desc->method.param_count;
+		}
 
-		info->prefix_node = NULL;
-		status = acpi_ns_evaluate(info);
-	} else if (!handle) {
 		/*
-		 * A handle is optional iff a fully qualified pathname is specified.
-		 * Since we've already handled fully qualified names above, this is
-		 * an error
+		 * Any incoming external objects to be passed as arguments to the
+		 * method must be converted to internal objects
 		 */
-		if (!pathname) {
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Both Handle and Pathname are NULL"));
-		} else {
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Null Handle with relative pathname [%s]",
-					  pathname));
+		if (info->param_count) {
+			/*
+			 * Allocate a new parameter block for the internal objects
+			 * Add 1 to count to allow for null terminated internal list
+			 */
+			info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
+								 info->
+								 param_count +
+								 1) *
+								sizeof(void *));
+			if (!info->parameters) {
+				status = AE_NO_MEMORY;
+				goto cleanup;
+			}
+
+			/* Convert each external object in the list to an internal object */
+
+			for (i = 0; i < info->param_count; i++) {
+				status =
+				    acpi_ut_copy_eobject_to_iobject
+				    (&external_params->pointer[i],
+				     &info->parameters[i]);
+				if (ACPI_FAILURE(status)) {
+					goto cleanup;
+				}
+			}
+
+			info->parameters[info->param_count] = NULL;
 		}
+		break;
 
-		status = AE_BAD_PARAMETER;
-	} else {
-		/* We have a namespace a node and a possible relative path */
+	default:
 
-		status = acpi_ns_evaluate(info);
+		/* Warn if arguments passed to an object that is not a method */
+
+		if (info->param_count) {
+			ACPI_WARNING((AE_INFO,
+				      "%u arguments were passed to a non-method ACPI object",
+				      info->param_count));
+		}
+		break;
 	}
 
+#endif
+
+	/* Now we can evaluate the object */
+
+	status = acpi_ns_evaluate(info);
+
 	/*
 	 * If we are expecting a return value, and all went well above,
 	 * copy the return value to an external object.
@@ -413,6 +511,7 @@ static void acpi_ns_resolve_references(s
 		break;
 
 	default:
+
 		return;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/psargs.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psargs.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/psargs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psargs.c	2013-08-25 20:43:22.000000000 -0400
@@ -629,24 +629,28 @@ static union acpi_parse_object *acpi_ps_
 
 				switch (opcode) {
 				case AML_BYTE_OP:	/* AML_BYTEDATA_ARG */
+
 					buffer_length =
 					    ACPI_GET8(parser_state->aml);
 					parser_state->aml += 1;
 					break;
 
 				case AML_WORD_OP:	/* AML_WORDDATA_ARG */
+
 					buffer_length =
 					    ACPI_GET16(parser_state->aml);
 					parser_state->aml += 2;
 					break;
 
 				case AML_DWORD_OP:	/* AML_DWORDATA_ARG */
+
 					buffer_length =
 					    ACPI_GET32(parser_state->aml);
 					parser_state->aml += 4;
 					break;
 
 				default:
+
 					buffer_length = 0;
 					break;
 				}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/psloop.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psloop.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/psloop.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psloop.c	2013-08-25 20:43:22.000000000 -0400
@@ -164,7 +164,6 @@ acpi_ps_get_arguments(struct acpi_walk_s
 			case AML_IF_OP:
 			case AML_ELSE_OP:
 			case AML_WHILE_OP:
-
 				/*
 				 * Currently supported module-level opcodes are:
 				 * IF/ELSE/WHILE. These appear to be the most common,
@@ -289,6 +288,7 @@ acpi_ps_get_arguments(struct acpi_walk_s
 		default:
 
 			/* No action for all other opcodes */
+
 			break;
 		}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/psobject.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psobject.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/psobject.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psobject.c	2013-08-25 20:43:22.000000000 -0400
@@ -402,6 +402,7 @@ acpi_ps_complete_op(struct acpi_walk_sta
 
 	switch (status) {
 	case AE_OK:
+
 		break;
 
 	case AE_CTRL_TRANSFER:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/psparse.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psparse.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/psparse.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psparse.c	2013-08-25 20:43:22.000000000 -0400
@@ -176,10 +176,10 @@ acpi_ps_complete_this_op(struct acpi_wal
 
 		switch (parent_info->class) {
 		case AML_CLASS_CONTROL:
+
 			break;
 
 		case AML_CLASS_CREATE:
-
 			/*
 			 * These opcodes contain term_arg operands. The current
 			 * op must be replaced by a placeholder return op
@@ -192,7 +192,6 @@ acpi_ps_complete_this_op(struct acpi_wal
 			break;
 
 		case AML_CLASS_NAMED_OBJECT:
-
 			/*
 			 * These opcodes contain term_arg operands. The current
 			 * op must be replaced by a placeholder return op
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/pstree.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/pstree.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/pstree.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/pstree.c	2013-08-25 20:43:22.000000000 -0400
@@ -308,7 +308,9 @@ union acpi_parse_object *acpi_ps_get_chi
 		break;
 
 	default:
+
 		/* All others have no children */
+
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/psxface.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psxface.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/psxface.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/psxface.c	2013-08-25 20:43:22.000000000 -0400
@@ -125,7 +125,7 @@ static void acpi_ps_start_trace(struct a
 	}
 
 	if ((!acpi_gbl_trace_method_name) ||
-	    (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) {
+	    (acpi_gbl_trace_method_name != info->node->name.integer)) {
 		goto exit;
 	}
 
@@ -170,7 +170,7 @@ static void acpi_ps_stop_trace(struct ac
 	}
 
 	if ((!acpi_gbl_trace_method_name) ||
-	    (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) {
+	    (acpi_gbl_trace_method_name != info->node->name.integer)) {
 		goto exit;
 	}
 
@@ -226,15 +226,14 @@ acpi_status acpi_ps_execute_method(struc
 
 	/* Validate the Info and method Node */
 
-	if (!info || !info->resolved_node) {
+	if (!info || !info->node) {
 		return_ACPI_STATUS(AE_NULL_ENTRY);
 	}
 
 	/* Init for new method, wait on concurrency semaphore */
 
 	status =
-	    acpi_ds_begin_method_execution(info->resolved_node, info->obj_desc,
-					   NULL);
+	    acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -253,8 +252,7 @@ acpi_status acpi_ps_execute_method(struc
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 			  "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
-			  info->resolved_node->name.ascii, info->resolved_node,
-			  info->obj_desc));
+			  info->node->name.ascii, info->node, info->obj_desc));
 
 	/* Create and init a Root Node */
 
@@ -275,7 +273,7 @@ acpi_status acpi_ps_execute_method(struc
 		goto cleanup;
 	}
 
-	status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
+	status = acpi_ds_init_aml_walk(walk_state, op, info->node,
 				       info->obj_desc->method.aml_start,
 				       info->obj_desc->method.aml_length, info,
 				       info->pass_number);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/rscalc.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rscalc.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/rscalc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rscalc.c	2013-08-25 20:43:22.000000000 -0400
@@ -352,6 +352,7 @@ acpi_rs_get_aml_length(struct acpi_resou
 			break;
 
 		default:
+
 			break;
 		}
 
@@ -539,6 +540,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,
 			break;
 
 		default:
+
 			break;
 		}
 
@@ -650,8 +652,9 @@ acpi_rs_get_pci_routing_table_length(uni
 
 		name_found = FALSE;
 
-		for (table_index = 0; table_index < 4 && !name_found;
-		     table_index++) {
+		for (table_index = 0;
+		     table_index < package_element->package.count
+		     && !name_found; table_index++) {
 			if (*sub_object_list &&	/* Null object allowed */
 			    ((ACPI_TYPE_STRING ==
 			      (*sub_object_list)->common.type) ||
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/rscreate.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rscreate.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/rscreate.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rscreate.c	2013-08-25 20:43:22.000000000 -0400
@@ -273,17 +273,6 @@ acpi_rs_create_pci_routing_table(union a
 		 */
 		user_prt->length = (sizeof(struct acpi_pci_routing_table) - 4);
 
-		/* Each element of the top-level package must also be a package */
-
-		if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) {
-			ACPI_ERROR((AE_INFO,
-				    "(PRT[%u]) Need sub-package, found %s",
-				    index,
-				    acpi_ut_get_object_type_name
-				    (*top_object_list)));
-			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
-		}
-
 		/* Each sub-package must be of length 4 */
 
 		if ((*top_object_list)->package.count != 4) {
@@ -327,22 +316,6 @@ acpi_rs_create_pci_routing_table(union a
 		user_prt->pin = (u32) obj_desc->integer.value;
 
 		/*
-		 * If the BIOS has erroneously reversed the _PRT source_name (index 2)
-		 * and the source_index (index 3), fix it. _PRT is important enough to
-		 * workaround this BIOS error. This also provides compatibility with
-		 * other ACPI implementations.
-		 */
-		obj_desc = sub_object_list[3];
-		if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
-			sub_object_list[3] = sub_object_list[2];
-			sub_object_list[2] = obj_desc;
-
-			ACPI_WARNING((AE_INFO,
-				      "(PRT[%X].Source) SourceName and SourceIndex are reversed, fixed",
-				      index));
-		}
-
-		/*
 		 * 3) Third subobject: Dereference the PRT.source_name
 		 * The name may be unresolved (slack mode), so allow a null object
 		 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/rsdump.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rsdump.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/rsdump.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rsdump.c	2013-08-25 20:43:22.000000000 -0400
@@ -120,17 +120,20 @@ acpi_rs_dump_descriptor(void *resource,
 			/* Strings */
 
 		case ACPI_RSD_LITERAL:
+
 			acpi_rs_out_string(name,
 					   ACPI_CAST_PTR(char, table->pointer));
 			break;
 
 		case ACPI_RSD_STRING:
+
 			acpi_rs_out_string(name, ACPI_CAST_PTR(char, target));
 			break;
 
 			/* Data items, 8/16/32/64 bit */
 
 		case ACPI_RSD_UINT8:
+
 			if (table->pointer) {
 				acpi_rs_out_string(name, ACPI_CAST_PTR(char,
 								       table->
@@ -142,20 +145,24 @@ acpi_rs_dump_descriptor(void *resource,
 			break;
 
 		case ACPI_RSD_UINT16:
+
 			acpi_rs_out_integer16(name, ACPI_GET16(target));
 			break;
 
 		case ACPI_RSD_UINT32:
+
 			acpi_rs_out_integer32(name, ACPI_GET32(target));
 			break;
 
 		case ACPI_RSD_UINT64:
+
 			acpi_rs_out_integer64(name, ACPI_GET64(target));
 			break;
 
 			/* Flags: 1-bit and 2-bit flags supported */
 
 		case ACPI_RSD_1BITFLAG:
+
 			acpi_rs_out_string(name, ACPI_CAST_PTR(char,
 							       table->
 							       pointer[*target &
@@ -163,6 +170,7 @@ acpi_rs_dump_descriptor(void *resource,
 			break;
 
 		case ACPI_RSD_2BITFLAG:
+
 			acpi_rs_out_string(name, ACPI_CAST_PTR(char,
 							       table->
 							       pointer[*target &
@@ -170,6 +178,7 @@ acpi_rs_dump_descriptor(void *resource,
 			break;
 
 		case ACPI_RSD_3BITFLAG:
+
 			acpi_rs_out_string(name, ACPI_CAST_PTR(char,
 							       table->
 							       pointer[*target &
@@ -258,6 +267,7 @@ acpi_rs_dump_descriptor(void *resource,
 			break;
 
 		default:
+
 			acpi_os_printf("**** Invalid table opcode [%X] ****\n",
 				       table->opcode);
 			return;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/rsmisc.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rsmisc.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/rsmisc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rsmisc.c	2013-08-25 20:43:22.000000000 -0400
@@ -194,7 +194,6 @@ acpi_rs_convert_aml_to_resource(struct a
 			break;
 
 		case ACPI_RSC_COUNT_GPIO_RES:
-
 			/*
 			 * Vendor data is optional (length/offset may both be zero)
 			 * Examine vendor data length field first
@@ -410,12 +409,14 @@ acpi_rs_convert_aml_to_resource(struct a
 			 */
 			switch (info->resource_offset) {
 			case ACPI_RSC_COMPARE_AML_LENGTH:
+
 				if (aml_resource_length != info->value) {
 					goto exit;
 				}
 				break;
 
 			case ACPI_RSC_COMPARE_VALUE:
+
 				if (ACPI_GET8(source) != info->value) {
 					goto exit;
 				}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/rsutils.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rsutils.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/rsutils.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rsutils.c	2013-08-25 20:43:22.000000000 -0400
@@ -147,6 +147,7 @@ acpi_rs_move_data(void *destination, voi
 		case ACPI_RSC_MOVE_GPIO_RES:
 		case ACPI_RSC_MOVE_SERIAL_VEN:
 		case ACPI_RSC_MOVE_SERIAL_RES:
+
 			ACPI_MEMCPY(destination, source, item_count);
 			return;
 
@@ -157,21 +158,25 @@ acpi_rs_move_data(void *destination, voi
 			 */
 		case ACPI_RSC_MOVE16:
 		case ACPI_RSC_MOVE_GPIO_PIN:
+
 			ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
 					   &ACPI_CAST_PTR(u16, source)[i]);
 			break;
 
 		case ACPI_RSC_MOVE32:
+
 			ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
 					   &ACPI_CAST_PTR(u32, source)[i]);
 			break;
 
 		case ACPI_RSC_MOVE64:
+
 			ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
 					   &ACPI_CAST_PTR(u64, source)[i]);
 			break;
 
 		default:
+
 			return;
 		}
 	}
@@ -736,7 +741,7 @@ acpi_rs_set_srs_method_data(struct acpi_
 	}
 
 	info->prefix_node = node;
-	info->pathname = METHOD_NAME__SRS;
+	info->relative_pathname = METHOD_NAME__SRS;
 	info->parameters = args;
 	info->flags = ACPI_IGNORE_RETURN_VALUE;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/rsxface.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rsxface.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/rsxface.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/rsxface.c	2013-08-25 20:43:22.000000000 -0400
@@ -402,6 +402,7 @@ acpi_resource_to_address64(struct acpi_r
 		break;
 
 	default:
+
 		return (AE_BAD_PARAMETER);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/tbinstal.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/tbinstal.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/tbinstal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/tbinstal.c	2013-08-25 20:43:22.000000000 -0400
@@ -141,8 +141,7 @@ acpi_tb_add_table(struct acpi_table_desc
 		ACPI_BIOS_ERROR((AE_INFO,
 				 "Table has invalid signature [%4.4s] (0x%8.8X), "
 				 "must be SSDT or OEMx",
-				 acpi_ut_valid_acpi_name(*(u32 *)table_desc->
-							 pointer->
+				 acpi_ut_valid_acpi_name(table_desc->pointer->
 							 signature) ?
 				 table_desc->pointer->signature : "????",
 				 *(u32 *)table_desc->pointer->signature));
@@ -471,15 +470,19 @@ void acpi_tb_delete_table(struct acpi_ta
 	}
 	switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
 	case ACPI_TABLE_ORIGIN_MAPPED:
+
 		acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
 		break;
+
 	case ACPI_TABLE_ORIGIN_ALLOCATED:
+
 		ACPI_FREE(table_desc->pointer);
 		break;
 
 		/* Not mapped or allocated, there is nothing we can do */
 
 	default:
+
 		return;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/tbprint.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/tbprint.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/tbprint.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/tbprint.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,237 @@
+/******************************************************************************
+ *
+ * Module Name: tbprint - Table output utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "actables.h"
+
+#define _COMPONENT          ACPI_TABLES
+ACPI_MODULE_NAME("tbprint")
+
+/* Local prototypes */
+static void acpi_tb_fix_string(char *string, acpi_size length);
+
+static void
+acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
+			     struct acpi_table_header *header);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_fix_string
+ *
+ * PARAMETERS:  string              - String to be repaired
+ *              length              - Maximum length
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
+ *              with a question mark '?'.
+ *
+ ******************************************************************************/
+
+static void acpi_tb_fix_string(char *string, acpi_size length)
+{
+
+	while (length && *string) {
+		if (!ACPI_IS_PRINT(*string)) {
+			*string = '?';
+		}
+		string++;
+		length--;
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_cleanup_table_header
+ *
+ * PARAMETERS:  out_header          - Where the cleaned header is returned
+ *              header              - Input ACPI table header
+ *
+ * RETURN:      Returns the cleaned header in out_header
+ *
+ * DESCRIPTION: Copy the table header and ensure that all "string" fields in
+ *              the header consist of printable characters.
+ *
+ ******************************************************************************/
+
+static void
+acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
+			     struct acpi_table_header *header)
+{
+
+	ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header));
+
+	acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE);
+	acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
+	acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
+	acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_print_table_header
+ *
+ * PARAMETERS:  address             - Table physical address
+ *              header              - Table header
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
+ *
+ ******************************************************************************/
+
+void
+acpi_tb_print_table_header(acpi_physical_address address,
+			   struct acpi_table_header *header)
+{
+	struct acpi_table_header local_header;
+
+	/*
+	 * The reason that the Address is cast to a void pointer is so that we
+	 * can use %p which will work properly on both 32-bit and 64-bit hosts.
+	 */
+	if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
+
+		/* FACS only has signature and length fields */
+
+		ACPI_INFO((AE_INFO, "%4.4s %p %05X",
+			   header->signature, ACPI_CAST_PTR(void, address),
+			   header->length));
+	} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
+
+		/* RSDP has no common fields */
+
+		ACPI_MEMCPY(local_header.oem_id,
+			    ACPI_CAST_PTR(struct acpi_table_rsdp,
+					  header)->oem_id, ACPI_OEM_ID_SIZE);
+		acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
+
+		ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
+			   ACPI_CAST_PTR(void, address),
+			   (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
+			    revision >
+			    0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
+					       header)->length : 20,
+			   ACPI_CAST_PTR(struct acpi_table_rsdp,
+					 header)->revision,
+			   local_header.oem_id));
+	} else {
+		/* Standard ACPI table with full common header */
+
+		acpi_tb_cleanup_table_header(&local_header, header);
+
+		ACPI_INFO((AE_INFO,
+			   "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
+			   local_header.signature, ACPI_CAST_PTR(void, address),
+			   local_header.length, local_header.revision,
+			   local_header.oem_id, local_header.oem_table_id,
+			   local_header.oem_revision,
+			   local_header.asl_compiler_id,
+			   local_header.asl_compiler_revision));
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_validate_checksum
+ *
+ * PARAMETERS:  table               - ACPI table to verify
+ *              length              - Length of entire table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
+ *              exception on bad checksum.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
+{
+	u8 checksum;
+
+	/* Compute the checksum on the table */
+
+	checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
+
+	/* Checksum ok? (should be zero) */
+
+	if (checksum) {
+		ACPI_BIOS_WARNING((AE_INFO,
+				   "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
+				   "should be 0x%2.2X",
+				   table->signature, table->checksum,
+				   (u8)(table->checksum - checksum)));
+
+#if (ACPI_CHECKSUM_ABORT)
+		return (AE_BAD_CHECKSUM);
+#endif
+	}
+
+	return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_checksum
+ *
+ * PARAMETERS:  buffer          - Pointer to memory region to be checked
+ *              length          - Length of this memory region
+ *
+ * RETURN:      Checksum (u8)
+ *
+ * DESCRIPTION: Calculates circular checksum of memory region.
+ *
+ ******************************************************************************/
+
+u8 acpi_tb_checksum(u8 *buffer, u32 length)
+{
+	u8 sum = 0;
+	u8 *end = buffer + length;
+
+	while (buffer < end) {
+		sum = (u8)(sum + *(buffer++));
+	}
+
+	return (sum);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/tbutils.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/tbutils.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/tbutils.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/tbutils.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Module Name: tbutils   - table utilities
+ * Module Name: tbutils - ACPI Table utilities
  *
  *****************************************************************************/
 
@@ -49,12 +49,6 @@
 ACPI_MODULE_NAME("tbutils")
 
 /* Local prototypes */
-static void acpi_tb_fix_string(char *string, acpi_size length);
-
-static void
-acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
-			     struct acpi_table_header *header);
-
 static acpi_physical_address
 acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
 
@@ -175,189 +169,6 @@ u8 acpi_tb_tables_loaded(void)
 }
 
 /*******************************************************************************
- *
- * FUNCTION:    acpi_tb_fix_string
- *
- * PARAMETERS:  string              - String to be repaired
- *              length              - Maximum length
- *
- * RETURN:      None
- *
- * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
- *              with a question mark '?'.
- *
- ******************************************************************************/
-
-static void acpi_tb_fix_string(char *string, acpi_size length)
-{
-
-	while (length && *string) {
-		if (!ACPI_IS_PRINT(*string)) {
-			*string = '?';
-		}
-		string++;
-		length--;
-	}
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_cleanup_table_header
- *
- * PARAMETERS:  out_header          - Where the cleaned header is returned
- *              header              - Input ACPI table header
- *
- * RETURN:      Returns the cleaned header in out_header
- *
- * DESCRIPTION: Copy the table header and ensure that all "string" fields in
- *              the header consist of printable characters.
- *
- ******************************************************************************/
-
-static void
-acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
-			     struct acpi_table_header *header)
-{
-
-	ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header));
-
-	acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE);
-	acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
-	acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
-	acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_print_table_header
- *
- * PARAMETERS:  address             - Table physical address
- *              header              - Table header
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
- *
- ******************************************************************************/
-
-void
-acpi_tb_print_table_header(acpi_physical_address address,
-			   struct acpi_table_header *header)
-{
-	struct acpi_table_header local_header;
-
-	/*
-	 * The reason that the Address is cast to a void pointer is so that we
-	 * can use %p which will work properly on both 32-bit and 64-bit hosts.
-	 */
-	if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
-
-		/* FACS only has signature and length fields */
-
-		ACPI_INFO((AE_INFO, "%4.4s %p %05X",
-			   header->signature, ACPI_CAST_PTR(void, address),
-			   header->length));
-	} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
-
-		/* RSDP has no common fields */
-
-		ACPI_MEMCPY(local_header.oem_id,
-			    ACPI_CAST_PTR(struct acpi_table_rsdp,
-					  header)->oem_id, ACPI_OEM_ID_SIZE);
-		acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
-
-		ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
-			   ACPI_CAST_PTR (void, address),
-			   (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
-			    revision >
-			    0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
-					       header)->length : 20,
-			   ACPI_CAST_PTR(struct acpi_table_rsdp,
-					 header)->revision,
-			   local_header.oem_id));
-	} else {
-		/* Standard ACPI table with full common header */
-
-		acpi_tb_cleanup_table_header(&local_header, header);
-
-		ACPI_INFO((AE_INFO,
-			   "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
-			   local_header.signature, ACPI_CAST_PTR(void, address),
-			   local_header.length, local_header.revision,
-			   local_header.oem_id, local_header.oem_table_id,
-			   local_header.oem_revision,
-			   local_header.asl_compiler_id,
-			   local_header.asl_compiler_revision));
-
-	}
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_validate_checksum
- *
- * PARAMETERS:  table               - ACPI table to verify
- *              length              - Length of entire table
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
- *              exception on bad checksum.
- *
- ******************************************************************************/
-
-acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
-{
-	u8 checksum;
-
-	/* Compute the checksum on the table */
-
-	checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
-
-	/* Checksum ok? (should be zero) */
-
-	if (checksum) {
-		ACPI_BIOS_WARNING((AE_INFO,
-				   "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
-				   "should be 0x%2.2X",
-				   table->signature, table->checksum,
-				   (u8)(table->checksum - checksum)));
-
-#if (ACPI_CHECKSUM_ABORT)
-
-		return (AE_BAD_CHECKSUM);
-#endif
-	}
-
-	return (AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_checksum
- *
- * PARAMETERS:  buffer          - Pointer to memory region to be checked
- *              length          - Length of this memory region
- *
- * RETURN:      Checksum (u8)
- *
- * DESCRIPTION: Calculates circular checksum of memory region.
- *
- ******************************************************************************/
-
-u8 acpi_tb_checksum(u8 *buffer, u32 length)
-{
-	u8 sum = 0;
-	u8 *end = buffer + length;
-
-	while (buffer < end) {
-		sum = (u8) (sum + *(buffer++));
-	}
-
-	return (sum);
-}
-
-/*******************************************************************************
  *
  * FUNCTION:    acpi_tb_check_dsdt_header
  *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/tbxfload.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/tbxfload.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/tbxfload.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/tbxfload.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,8 +53,6 @@ ACPI_MODULE_NAME("tbxfload")
 /* Local prototypes */
 static acpi_status acpi_tb_load_namespace(void);
 
-static int no_auto_ssdt;
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_load_tables
@@ -180,8 +178,16 @@ static acpi_status acpi_tb_load_namespac
 			continue;
 		}
 
-		if (no_auto_ssdt) {
-			printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n");
+		/*
+		 * Optionally do not load any SSDTs from the RSDT/XSDT. This can
+		 * be useful for debugging ACPI problems on some machines.
+		 */
+		if (acpi_gbl_disable_ssdt_table_load) {
+			ACPI_INFO((AE_INFO, "Ignoring %4.4s at %p",
+				   acpi_gbl_root_table_list.tables[i].signature.
+				   ascii, ACPI_CAST_PTR(void,
+							acpi_gbl_root_table_list.
+							tables[i].address)));
 			continue;
 		}
 
@@ -376,14 +382,3 @@ acpi_status acpi_unload_parent_table(acp
 }
 
 ACPI_EXPORT_SYMBOL(acpi_unload_parent_table)
-
-static int __init acpi_no_auto_ssdt_setup(char *s) {
-
-        printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n");
-
-        no_auto_ssdt = 1;
-
-        return 1;
-}
-
-__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utbuffer.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utbuffer.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utbuffer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utbuffer.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,201 @@
+/******************************************************************************
+ *
+ * Module Name: utbuffer - Buffer dump routines
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utbuffer")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_dump_buffer
+ *
+ * PARAMETERS:  buffer              - Buffer to dump
+ *              count               - Amount to dump, in bytes
+ *              display             - BYTE, WORD, DWORD, or QWORD display:
+ *                                      DB_BYTE_DISPLAY
+ *                                      DB_WORD_DISPLAY
+ *                                      DB_DWORD_DISPLAY
+ *                                      DB_QWORD_DISPLAY
+ *              base_offset         - Beginning buffer offset (display only)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Generic dump buffer in both hex and ascii.
+ *
+ ******************************************************************************/
+void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 base_offset)
+{
+	u32 i = 0;
+	u32 j;
+	u32 temp32;
+	u8 buf_char;
+
+	if (!buffer) {
+		acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
+		return;
+	}
+
+	if ((count < 4) || (count & 0x01)) {
+		display = DB_BYTE_DISPLAY;
+	}
+
+	/* Nasty little dump buffer routine! */
+
+	while (i < count) {
+
+		/* Print current offset */
+
+		acpi_os_printf("%6.4X: ", (base_offset + i));
+
+		/* Print 16 hex chars */
+
+		for (j = 0; j < 16;) {
+			if (i + j >= count) {
+
+				/* Dump fill spaces */
+
+				acpi_os_printf("%*s", ((display * 2) + 1), " ");
+				j += display;
+				continue;
+			}
+
+			switch (display) {
+			case DB_BYTE_DISPLAY:
+			default:	/* Default is BYTE display */
+
+				acpi_os_printf("%02X ",
+					       buffer[(acpi_size) i + j]);
+				break;
+
+			case DB_WORD_DISPLAY:
+
+				ACPI_MOVE_16_TO_32(&temp32,
+						   &buffer[(acpi_size) i + j]);
+				acpi_os_printf("%04X ", temp32);
+				break;
+
+			case DB_DWORD_DISPLAY:
+
+				ACPI_MOVE_32_TO_32(&temp32,
+						   &buffer[(acpi_size) i + j]);
+				acpi_os_printf("%08X ", temp32);
+				break;
+
+			case DB_QWORD_DISPLAY:
+
+				ACPI_MOVE_32_TO_32(&temp32,
+						   &buffer[(acpi_size) i + j]);
+				acpi_os_printf("%08X", temp32);
+
+				ACPI_MOVE_32_TO_32(&temp32,
+						   &buffer[(acpi_size) i + j +
+							   4]);
+				acpi_os_printf("%08X ", temp32);
+				break;
+			}
+
+			j += display;
+		}
+
+		/*
+		 * Print the ASCII equivalent characters but watch out for the bad
+		 * unprintable ones (printable chars are 0x20 through 0x7E)
+		 */
+		acpi_os_printf(" ");
+		for (j = 0; j < 16; j++) {
+			if (i + j >= count) {
+				acpi_os_printf("\n");
+				return;
+			}
+
+			buf_char = buffer[(acpi_size) i + j];
+			if (ACPI_IS_PRINT(buf_char)) {
+				acpi_os_printf("%c", buf_char);
+			} else {
+				acpi_os_printf(".");
+			}
+		}
+
+		/* Done with that line. */
+
+		acpi_os_printf("\n");
+		i += 16;
+	}
+
+	return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_debug_dump_buffer
+ *
+ * PARAMETERS:  buffer              - Buffer to dump
+ *              count               - Amount to dump, in bytes
+ *              display             - BYTE, WORD, DWORD, or QWORD display:
+ *                                      DB_BYTE_DISPLAY
+ *                                      DB_WORD_DISPLAY
+ *                                      DB_DWORD_DISPLAY
+ *                                      DB_QWORD_DISPLAY
+ *              component_ID        - Caller's component ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Generic dump buffer in both hex and ascii.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)
+{
+
+	/* Only dump the buffer if tracing is enabled */
+
+	if (!((ACPI_LV_TABLES & acpi_dbg_level) &&
+	      (component_id & acpi_dbg_layer))) {
+		return;
+	}
+
+	acpi_ut_dump_buffer(buffer, count, display, 0);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utcopy.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utcopy.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utcopy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utcopy.c	2013-08-25 20:43:22.000000000 -0400
@@ -178,7 +178,6 @@ acpi_ut_copy_isimple_to_esimple(union ac
 
 		switch (internal_object->reference.class) {
 		case ACPI_REFCLASS_NAME:
-
 			/*
 			 * For namepath, return the object handle ("reference")
 			 * We are referring to the namespace node
@@ -264,7 +263,6 @@ acpi_ut_copy_ielement_to_eelement(u8 obj
 
 	switch (object_type) {
 	case ACPI_COPY_TYPE_SIMPLE:
-
 		/*
 		 * This is a simple or null object
 		 */
@@ -278,7 +276,6 @@ acpi_ut_copy_ielement_to_eelement(u8 obj
 		break;
 
 	case ACPI_COPY_TYPE_PACKAGE:
-
 		/*
 		 * Build the package object
 		 */
@@ -304,6 +301,7 @@ acpi_ut_copy_ielement_to_eelement(u8 obj
 		break;
 
 	default:
+
 		return (AE_BAD_PARAMETER);
 	}
 
@@ -481,6 +479,7 @@ acpi_ut_copy_esimple_to_isimple(union ac
 		return_ACPI_STATUS(AE_OK);
 
 	default:
+
 		/* All other types are not supported */
 
 		ACPI_ERROR((AE_INFO,
@@ -544,7 +543,9 @@ acpi_ut_copy_esimple_to_isimple(union ac
 		break;
 
 	default:
+
 		/* Other types can't get here */
+
 		break;
 	}
 
@@ -800,7 +801,9 @@ acpi_ut_copy_simple_object(union acpi_op
 		break;
 
 	default:
+
 		/* Nothing to do for other simple objects */
+
 		break;
 	}
 
@@ -868,7 +871,6 @@ acpi_ut_copy_ielement_to_ielement(u8 obj
 		break;
 
 	case ACPI_COPY_TYPE_PACKAGE:
-
 		/*
 		 * This object is a package - go down another nesting level
 		 * Create and build the package object
@@ -891,6 +893,7 @@ acpi_ut_copy_ielement_to_ielement(u8 obj
 		break;
 
 	default:
+
 		return (AE_BAD_PARAMETER);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utdebug.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utdebug.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utdebug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utdebug.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Module Name: utdebug - Debug print routines
+ * Module Name: utdebug - Debug print/trace routines
  *
  *****************************************************************************/
 
@@ -543,149 +543,3 @@ acpi_ut_ptr_exit(u32 line_number,
 }
 
 #endif
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_dump_buffer
- *
- * PARAMETERS:  buffer              - Buffer to dump
- *              count               - Amount to dump, in bytes
- *              display             - BYTE, WORD, DWORD, or QWORD display
- *              offset              - Beginning buffer offset (display only)
- *
- * RETURN:      None
- *
- * DESCRIPTION: Generic dump buffer in both hex and ascii.
- *
- ******************************************************************************/
-
-void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 base_offset)
-{
-	u32 i = 0;
-	u32 j;
-	u32 temp32;
-	u8 buf_char;
-
-	if (!buffer) {
-		acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
-		return;
-	}
-
-	if ((count < 4) || (count & 0x01)) {
-		display = DB_BYTE_DISPLAY;
-	}
-
-	/* Nasty little dump buffer routine! */
-
-	while (i < count) {
-
-		/* Print current offset */
-
-		acpi_os_printf("%6.4X: ", (base_offset + i));
-
-		/* Print 16 hex chars */
-
-		for (j = 0; j < 16;) {
-			if (i + j >= count) {
-
-				/* Dump fill spaces */
-
-				acpi_os_printf("%*s", ((display * 2) + 1), " ");
-				j += display;
-				continue;
-			}
-
-			switch (display) {
-			case DB_BYTE_DISPLAY:
-			default:	/* Default is BYTE display */
-
-				acpi_os_printf("%02X ",
-					       buffer[(acpi_size) i + j]);
-				break;
-
-			case DB_WORD_DISPLAY:
-
-				ACPI_MOVE_16_TO_32(&temp32,
-						   &buffer[(acpi_size) i + j]);
-				acpi_os_printf("%04X ", temp32);
-				break;
-
-			case DB_DWORD_DISPLAY:
-
-				ACPI_MOVE_32_TO_32(&temp32,
-						   &buffer[(acpi_size) i + j]);
-				acpi_os_printf("%08X ", temp32);
-				break;
-
-			case DB_QWORD_DISPLAY:
-
-				ACPI_MOVE_32_TO_32(&temp32,
-						   &buffer[(acpi_size) i + j]);
-				acpi_os_printf("%08X", temp32);
-
-				ACPI_MOVE_32_TO_32(&temp32,
-						   &buffer[(acpi_size) i + j +
-							   4]);
-				acpi_os_printf("%08X ", temp32);
-				break;
-			}
-
-			j += display;
-		}
-
-		/*
-		 * Print the ASCII equivalent characters but watch out for the bad
-		 * unprintable ones (printable chars are 0x20 through 0x7E)
-		 */
-		acpi_os_printf(" ");
-		for (j = 0; j < 16; j++) {
-			if (i + j >= count) {
-				acpi_os_printf("\n");
-				return;
-			}
-
-			buf_char = buffer[(acpi_size) i + j];
-			if (ACPI_IS_PRINT(buf_char)) {
-				acpi_os_printf("%c", buf_char);
-			} else {
-				acpi_os_printf(".");
-			}
-		}
-
-		/* Done with that line. */
-
-		acpi_os_printf("\n");
-		i += 16;
-	}
-
-	return;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_debug_dump_buffer
- *
- * PARAMETERS:  buffer              - Buffer to dump
- *              count               - Amount to dump, in bytes
- *              display             - BYTE, WORD, DWORD, or QWORD display
- *              component_ID        - Caller's component ID
- *
- * RETURN:      None
- *
- * DESCRIPTION: Generic dump buffer in both hex and ascii.
- *
- ******************************************************************************/
-
-void
-acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)
-{
-
-	/* Only dump the buffer if tracing is enabled */
-
-	if (!((ACPI_LV_TABLES & acpi_dbg_level) &&
-	      (component_id & acpi_dbg_layer))) {
-		return;
-	}
-
-	acpi_ut_dump_buffer(buffer, count, display, 0);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utdelete.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utdelete.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utdelete.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utdelete.c	2013-08-25 20:43:22.000000000 -0400
@@ -303,6 +303,7 @@ static void acpi_ut_delete_internal_obj(
 		break;
 
 	default:
+
 		break;
 	}
 
@@ -508,7 +509,6 @@ acpi_ut_update_object_reference(union ac
 		case ACPI_TYPE_PROCESSOR:
 		case ACPI_TYPE_POWER:
 		case ACPI_TYPE_THERMAL:
-
 			/*
 			 * Update the notify objects for these types (if present)
 			 * Two lists, system and device notify handlers.
@@ -623,6 +623,7 @@ acpi_ut_update_object_reference(union ac
 
 		case ACPI_TYPE_REGION:
 		default:
+
 			break;	/* No subobjects for all other types */
 		}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/uterror.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/uterror.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/uterror.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/uterror.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ *
+ * Module Name: uterror - Various internal error/warning output functions
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acnamesp.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("uterror")
+
+/*
+ * This module contains internal error functions that may
+ * be configured out.
+ */
+#if !defined (ACPI_NO_ERROR_MESSAGES)
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_predefined_warning
+ *
+ * PARAMETERS:  module_name     - Caller's module name (for error output)
+ *              line_number     - Caller's line number (for error output)
+ *              pathname        - Full pathname to the node
+ *              node_flags      - From Namespace node for the method/object
+ *              format          - Printf format string + additional args
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Warnings for the predefined validation module. Messages are
+ *              only emitted the first time a problem with a particular
+ *              method/object is detected. This prevents a flood of error
+ *              messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_predefined_warning(const char *module_name,
+			   u32 line_number,
+			   char *pathname,
+			   u8 node_flags, const char *format, ...)
+{
+	va_list arg_list;
+
+	/*
+	 * Warning messages for this method/object will be disabled after the
+	 * first time a validation fails or an object is successfully repaired.
+	 */
+	if (node_flags & ANOBJ_EVALUATED) {
+		return;
+	}
+
+	acpi_os_printf(ACPI_MSG_WARNING "%s: ", pathname);
+
+	va_start(arg_list, format);
+	acpi_os_vprintf(format, arg_list);
+	ACPI_MSG_SUFFIX;
+	va_end(arg_list);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_predefined_info
+ *
+ * PARAMETERS:  module_name     - Caller's module name (for error output)
+ *              line_number     - Caller's line number (for error output)
+ *              pathname        - Full pathname to the node
+ *              node_flags      - From Namespace node for the method/object
+ *              format          - Printf format string + additional args
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Info messages for the predefined validation module. Messages
+ *              are only emitted the first time a problem with a particular
+ *              method/object is detected. This prevents a flood of
+ *              messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_predefined_info(const char *module_name,
+			u32 line_number,
+			char *pathname, u8 node_flags, const char *format, ...)
+{
+	va_list arg_list;
+
+	/*
+	 * Warning messages for this method/object will be disabled after the
+	 * first time a validation fails or an object is successfully repaired.
+	 */
+	if (node_flags & ANOBJ_EVALUATED) {
+		return;
+	}
+
+	acpi_os_printf(ACPI_MSG_INFO "%s: ", pathname);
+
+	va_start(arg_list, format);
+	acpi_os_vprintf(format, arg_list);
+	ACPI_MSG_SUFFIX;
+	va_end(arg_list);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_predefined_bios_error
+ *
+ * PARAMETERS:  module_name     - Caller's module name (for error output)
+ *              line_number     - Caller's line number (for error output)
+ *              pathname        - Full pathname to the node
+ *              node_flags      - From Namespace node for the method/object
+ *              format          - Printf format string + additional args
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: BIOS error message for predefined names. Messages
+ *              are only emitted the first time a problem with a particular
+ *              method/object is detected. This prevents a flood of
+ *              messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_predefined_bios_error(const char *module_name,
+			      u32 line_number,
+			      char *pathname,
+			      u8 node_flags, const char *format, ...)
+{
+	va_list arg_list;
+
+	/*
+	 * Warning messages for this method/object will be disabled after the
+	 * first time a validation fails or an object is successfully repaired.
+	 */
+	if (node_flags & ANOBJ_EVALUATED) {
+		return;
+	}
+
+	acpi_os_printf(ACPI_MSG_BIOS_ERROR "%s: ", pathname);
+
+	va_start(arg_list, format);
+	acpi_os_vprintf(format, arg_list);
+	ACPI_MSG_SUFFIX;
+	va_end(arg_list);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_namespace_error
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              internal_name       - Name or path of the namespace node
+ *              lookup_status       - Exception code from NS lookup
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message with the full pathname for the NS node.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_namespace_error(const char *module_name,
+			u32 line_number,
+			const char *internal_name, acpi_status lookup_status)
+{
+	acpi_status status;
+	u32 bad_name;
+	char *name = NULL;
+
+	ACPI_MSG_REDIRECT_BEGIN;
+	acpi_os_printf(ACPI_MSG_ERROR);
+
+	if (lookup_status == AE_BAD_CHARACTER) {
+
+		/* There is a non-ascii character in the name */
+
+		ACPI_MOVE_32_TO_32(&bad_name,
+				   ACPI_CAST_PTR(u32, internal_name));
+		acpi_os_printf("[0x%.8X] (NON-ASCII)", bad_name);
+	} else {
+		/* Convert path to external format */
+
+		status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
+						  internal_name, NULL, &name);
+
+		/* Print target name */
+
+		if (ACPI_SUCCESS(status)) {
+			acpi_os_printf("[%s]", name);
+		} else {
+			acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
+		}
+
+		if (name) {
+			ACPI_FREE(name);
+		}
+	}
+
+	acpi_os_printf(" Namespace lookup failure, %s",
+		       acpi_format_exception(lookup_status));
+
+	ACPI_MSG_SUFFIX;
+	ACPI_MSG_REDIRECT_END;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_method_error
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              message             - Error message to use on failure
+ *              prefix_node         - Prefix relative to the path
+ *              path                - Path to the node (optional)
+ *              method_status       - Execution status
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message with the full pathname for the method.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_method_error(const char *module_name,
+		     u32 line_number,
+		     const char *message,
+		     struct acpi_namespace_node *prefix_node,
+		     const char *path, acpi_status method_status)
+{
+	acpi_status status;
+	struct acpi_namespace_node *node = prefix_node;
+
+	ACPI_MSG_REDIRECT_BEGIN;
+	acpi_os_printf(ACPI_MSG_ERROR);
+
+	if (path) {
+		status =
+		    acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
+				     &node);
+		if (ACPI_FAILURE(status)) {
+			acpi_os_printf("[Could not get node by pathname]");
+		}
+	}
+
+	acpi_ns_print_node_pathname(node, message);
+	acpi_os_printf(", %s", acpi_format_exception(method_status));
+
+	ACPI_MSG_SUFFIX;
+	ACPI_MSG_REDIRECT_END;
+}
+
+#endif				/* ACPI_NO_ERROR_MESSAGES */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/uteval.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/uteval.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/uteval.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/uteval.c	2013-08-25 20:43:22.000000000 -0400
@@ -68,7 +68,7 @@ ACPI_MODULE_NAME("uteval")
  ******************************************************************************/
 
 acpi_status
-acpi_ut_evaluate_object(struct acpi_namespace_node * prefix_node,
+acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
 			char *path,
 			u32 expected_return_btypes,
 			union acpi_operand_object **return_desc)
@@ -87,7 +87,7 @@ acpi_ut_evaluate_object(struct acpi_name
 	}
 
 	info->prefix_node = prefix_node;
-	info->pathname = path;
+	info->relative_pathname = path;
 
 	/* Evaluate the object/method */
 
@@ -123,22 +123,27 @@ acpi_ut_evaluate_object(struct acpi_name
 
 	switch ((info->return_object)->common.type) {
 	case ACPI_TYPE_INTEGER:
+
 		return_btype = ACPI_BTYPE_INTEGER;
 		break;
 
 	case ACPI_TYPE_BUFFER:
+
 		return_btype = ACPI_BTYPE_BUFFER;
 		break;
 
 	case ACPI_TYPE_STRING:
+
 		return_btype = ACPI_BTYPE_STRING;
 		break;
 
 	case ACPI_TYPE_PACKAGE:
+
 		return_btype = ACPI_BTYPE_PACKAGE;
 		break;
 
 	default:
+
 		return_btype = 0;
 		break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utexcep.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utexcep.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utexcep.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utexcep.c	2013-08-25 20:43:22.000000000 -0400
@@ -146,6 +146,7 @@ const struct acpi_exception_info *acpi_u
 		break;
 
 	default:
+
 		break;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utids.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utids.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utids.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utids.c	2013-08-25 20:43:22.000000000 -0400
@@ -341,14 +341,17 @@ acpi_ut_execute_CID(struct acpi_namespac
 
 		switch (cid_objects[i]->common.type) {
 		case ACPI_TYPE_INTEGER:
+
 			string_area_size += ACPI_EISAID_STRING_SIZE;
 			break;
 
 		case ACPI_TYPE_STRING:
+
 			string_area_size += cid_objects[i]->string.length + 1;
 			break;
 
 		default:
+
 			status = AE_TYPE;
 			goto cleanup;
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utmisc.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utmisc.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utmisc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utmisc.c	2013-08-25 20:43:22.000000000 -0400
@@ -382,10 +382,12 @@ acpi_ut_display_init_pathname(u8 type,
 
 	switch (type) {
 	case ACPI_TYPE_METHOD:
+
 		acpi_os_printf("Executing  ");
 		break;
 
 	default:
+
 		acpi_os_printf("Initializing ");
 		break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utobject.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utobject.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utobject.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utobject.c	2013-08-25 20:43:22.000000000 -0400
@@ -129,6 +129,7 @@ union acpi_operand_object *acpi_ut_creat
 		break;
 
 	default:
+
 		/* All others have no secondary object */
 		break;
 	}
@@ -353,6 +354,7 @@ u8 acpi_ut_valid_internal_object(void *o
 		return (TRUE);
 
 	default:
+
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "%p is not not an ACPI operand obj [%s]\n",
 				  object, acpi_ut_get_descriptor_name(object)));
@@ -509,7 +511,6 @@ acpi_ut_get_simple_object_size(union acp
 
 		switch (internal_object->reference.class) {
 		case ACPI_REFCLASS_NAME:
-
 			/*
 			 * Get the actual length of the full pathname to this object.
 			 * The reference will be converted to the pathname to the object
@@ -525,7 +526,6 @@ acpi_ut_get_simple_object_size(union acp
 			break;
 
 		default:
-
 			/*
 			 * No other reference opcodes are supported.
 			 * Notably, Locals and Args are not supported, but this may be
@@ -585,7 +585,6 @@ acpi_ut_get_element_length(u8 object_typ
 
 	switch (object_type) {
 	case ACPI_COPY_TYPE_SIMPLE:
-
 		/*
 		 * Simple object - just get the size (Null object/entry is handled
 		 * here also) and sum it into the running package length
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utpredef.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utpredef.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utpredef.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utpredef.c	2013-08-25 20:43:22.000000000 -0400
@@ -147,6 +147,11 @@ void acpi_ut_get_expected_return_types(c
 	u32 i;
 	u32 j;
 
+	if (!expected_btypes) {
+		ACPI_STRCPY(buffer, "NONE");
+		return;
+	}
+
 	j = 1;
 	buffer[0] = 0;
 	this_rtype = ACPI_RTYPE_INTEGER;
@@ -328,9 +333,7 @@ static u32 acpi_ut_get_argument_types(ch
 
 	/* First field in the types list is the count of args to follow */
 
-	arg_count = (argument_types & METHOD_ARG_MASK);
-	argument_types >>= METHOD_ARG_BIT_WIDTH;
-
+	arg_count = METHOD_GET_ARG_COUNT(argument_types);
 	if (arg_count > METHOD_PREDEF_ARGS_MAX) {
 		printf("**** Invalid argument count (%u) "
 		       "in predefined info structure\n", arg_count);
@@ -340,7 +343,8 @@ static u32 acpi_ut_get_argument_types(ch
 	/* Get each argument from the list, convert to ascii, store to buffer */
 
 	for (i = 0; i < arg_count; i++) {
-		this_argument_type = (argument_types & METHOD_ARG_MASK);
+		this_argument_type = METHOD_GET_NEXT_TYPE(argument_types);
+
 		if (!this_argument_type
 		    || (this_argument_type > METHOD_MAX_ARG_TYPE)) {
 			printf("**** Invalid argument type (%u) "
@@ -351,10 +355,6 @@ static u32 acpi_ut_get_argument_types(ch
 
 		strcat(buffer,
 		       ut_external_type_names[this_argument_type] + sub_index);
-
-		/* Shift to next argument type field */
-
-		argument_types >>= METHOD_ARG_BIT_WIDTH;
 		sub_index = 0;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utstring.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utstring.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utstring.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utstring.c	2013-08-25 20:43:22.000000000 -0400
@@ -186,10 +186,13 @@ acpi_status acpi_ut_strtoul64(char *stri
 	switch (base) {
 	case ACPI_ANY_BASE:
 	case 16:
+
 		break;
 
 	default:
+
 		/* Invalid Base */
+
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -355,36 +358,44 @@ void acpi_ut_print_string(char *string,
 
 		switch (string[i]) {
 		case 0x07:
+
 			acpi_os_printf("\\a");	/* BELL */
 			break;
 
 		case 0x08:
+
 			acpi_os_printf("\\b");	/* BACKSPACE */
 			break;
 
 		case 0x0C:
+
 			acpi_os_printf("\\f");	/* FORMFEED */
 			break;
 
 		case 0x0A:
+
 			acpi_os_printf("\\n");	/* LINEFEED */
 			break;
 
 		case 0x0D:
+
 			acpi_os_printf("\\r");	/* CARRIAGE RETURN */
 			break;
 
 		case 0x09:
+
 			acpi_os_printf("\\t");	/* HORIZONTAL TAB */
 			break;
 
 		case 0x0B:
+
 			acpi_os_printf("\\v");	/* VERTICAL TAB */
 			break;
 
 		case '\'':	/* Single Quote */
 		case '\"':	/* Double Quote */
 		case '\\':	/* Backslash */
+
 			acpi_os_printf("\\%c", (int)string[i]);
 			break;
 
@@ -451,7 +462,8 @@ u8 acpi_ut_valid_acpi_char(char characte
  *
  * FUNCTION:    acpi_ut_valid_acpi_name
  *
- * PARAMETERS:  name            - The name to be examined
+ * PARAMETERS:  name            - The name to be examined. Does not have to
+ *                                be NULL terminated string.
  *
  * RETURN:      TRUE if the name is valid, FALSE otherwise
  *
@@ -462,15 +474,14 @@ u8 acpi_ut_valid_acpi_char(char characte
  *
  ******************************************************************************/
 
-u8 acpi_ut_valid_acpi_name(u32 name)
+u8 acpi_ut_valid_acpi_name(char *name)
 {
 	u32 i;
 
 	ACPI_FUNCTION_ENTRY();
 
 	for (i = 0; i < ACPI_NAME_SIZE; i++) {
-		if (!acpi_ut_valid_acpi_char
-		    ((ACPI_CAST_PTR(char, &name))[i], i)) {
+		if (!acpi_ut_valid_acpi_char(name[i], i)) {
 			return (FALSE);
 		}
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/uttrack.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/uttrack.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/uttrack.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/uttrack.c	2013-08-25 20:43:22.000000000 -0400
@@ -603,6 +603,7 @@ void acpi_ut_dump_allocations(u32 compon
 					switch (ACPI_GET_DESCRIPTOR_TYPE
 						(descriptor)) {
 					case ACPI_DESC_TYPE_OPERAND:
+
 						if (element->size ==
 						    sizeof(union
 							   acpi_operand_object))
@@ -613,6 +614,7 @@ void acpi_ut_dump_allocations(u32 compon
 						break;
 
 					case ACPI_DESC_TYPE_PARSER:
+
 						if (element->size ==
 						    sizeof(union
 							   acpi_parse_object)) {
@@ -622,6 +624,7 @@ void acpi_ut_dump_allocations(u32 compon
 						break;
 
 					case ACPI_DESC_TYPE_NAMED:
+
 						if (element->size ==
 						    sizeof(struct
 							   acpi_namespace_node))
@@ -632,6 +635,7 @@ void acpi_ut_dump_allocations(u32 compon
 						break;
 
 					default:
+
 						break;
 					}
 
@@ -639,6 +643,7 @@ void acpi_ut_dump_allocations(u32 compon
 
 					switch (descriptor_type) {
 					case ACPI_DESC_TYPE_OPERAND:
+
 						acpi_os_printf
 						    ("%12.12s RefCount 0x%04X\n",
 						     acpi_ut_get_type_name
@@ -649,6 +654,7 @@ void acpi_ut_dump_allocations(u32 compon
 						break;
 
 					case ACPI_DESC_TYPE_PARSER:
+
 						acpi_os_printf
 						    ("AmlOpcode 0x%04hX\n",
 						     descriptor->op.asl.
@@ -656,6 +662,7 @@ void acpi_ut_dump_allocations(u32 compon
 						break;
 
 					case ACPI_DESC_TYPE_NAMED:
+
 						acpi_os_printf("%4.4s\n",
 							       acpi_ut_get_node_name
 							       (&descriptor->
@@ -663,6 +670,7 @@ void acpi_ut_dump_allocations(u32 compon
 						break;
 
 					default:
+
 						acpi_os_printf("\n");
 						break;
 					}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpica/utxferror.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utxferror.c
--- linux-libre-3.10-gnu/drivers/acpi/acpica/utxferror.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpica/utxferror.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,7 +44,6 @@
 #include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
-#include "acnamesp.h"
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utxferror")
@@ -52,43 +51,7 @@ ACPI_MODULE_NAME("utxferror")
 /*
  * This module is used for the in-kernel ACPICA as well as the ACPICA
  * tools/applications.
- *
- * For the iASL compiler case, the output is redirected to stderr so that
- * any of the various ACPI errors and warnings do not appear in the output
- * files, for either the compiler or disassembler portions of the tool.
- */
-#ifdef ACPI_ASL_COMPILER
-#include <stdio.h>
-extern FILE *acpi_gbl_output_file;
-
-#define ACPI_MSG_REDIRECT_BEGIN \
-	FILE                            *output_file = acpi_gbl_output_file; \
-	acpi_os_redirect_output (stderr);
-
-#define ACPI_MSG_REDIRECT_END \
-	acpi_os_redirect_output (output_file);
-
-#else
-/*
- * non-iASL case - no redirection, nothing to do
  */
-#define ACPI_MSG_REDIRECT_BEGIN
-#define ACPI_MSG_REDIRECT_END
-#endif
-/*
- * Common message prefixes
- */
-#define ACPI_MSG_ERROR          "ACPI Error: "
-#define ACPI_MSG_EXCEPTION      "ACPI Exception: "
-#define ACPI_MSG_WARNING        "ACPI Warning: "
-#define ACPI_MSG_INFO           "ACPI: "
-#define ACPI_MSG_BIOS_ERROR     "ACPI BIOS Bug: Error: "
-#define ACPI_MSG_BIOS_WARNING   "ACPI BIOS Bug: Warning: "
-/*
- * Common message suffix
- */
-#define ACPI_MSG_SUFFIX \
-	acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number)
 /*******************************************************************************
  *
  * FUNCTION:    acpi_error
@@ -285,200 +248,3 @@ acpi_bios_warning(const char *module_nam
 }
 
 ACPI_EXPORT_SYMBOL(acpi_bios_warning)
-
-/*
- * The remainder of this module contains internal error functions that may
- * be configured out.
- */
-#if !defined (ACPI_NO_ERROR_MESSAGES) && !defined (ACPI_BIN_APP)
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_predefined_warning
- *
- * PARAMETERS:  module_name     - Caller's module name (for error output)
- *              line_number     - Caller's line number (for error output)
- *              pathname        - Full pathname to the node
- *              node_flags      - From Namespace node for the method/object
- *              format          - Printf format string + additional args
- *
- * RETURN:      None
- *
- * DESCRIPTION: Warnings for the predefined validation module. Messages are
- *              only emitted the first time a problem with a particular
- *              method/object is detected. This prevents a flood of error
- *              messages for methods that are repeatedly evaluated.
- *
- ******************************************************************************/
-void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_predefined_warning(const char *module_name,
-			   u32 line_number,
-			   char *pathname,
-			   u8 node_flags, const char *format, ...)
-{
-	va_list arg_list;
-
-	/*
-	 * Warning messages for this method/object will be disabled after the
-	 * first time a validation fails or an object is successfully repaired.
-	 */
-	if (node_flags & ANOBJ_EVALUATED) {
-		return;
-	}
-
-	acpi_os_printf(ACPI_MSG_WARNING "For %s: ", pathname);
-
-	va_start(arg_list, format);
-	acpi_os_vprintf(format, arg_list);
-	ACPI_MSG_SUFFIX;
-	va_end(arg_list);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_predefined_info
- *
- * PARAMETERS:  module_name     - Caller's module name (for error output)
- *              line_number     - Caller's line number (for error output)
- *              pathname        - Full pathname to the node
- *              node_flags      - From Namespace node for the method/object
- *              format          - Printf format string + additional args
- *
- * RETURN:      None
- *
- * DESCRIPTION: Info messages for the predefined validation module. Messages
- *              are only emitted the first time a problem with a particular
- *              method/object is detected. This prevents a flood of
- *              messages for methods that are repeatedly evaluated.
- *
- ******************************************************************************/
-
-void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_predefined_info(const char *module_name,
-			u32 line_number,
-			char *pathname, u8 node_flags, const char *format, ...)
-{
-	va_list arg_list;
-
-	/*
-	 * Warning messages for this method/object will be disabled after the
-	 * first time a validation fails or an object is successfully repaired.
-	 */
-	if (node_flags & ANOBJ_EVALUATED) {
-		return;
-	}
-
-	acpi_os_printf(ACPI_MSG_INFO "For %s: ", pathname);
-
-	va_start(arg_list, format);
-	acpi_os_vprintf(format, arg_list);
-	ACPI_MSG_SUFFIX;
-	va_end(arg_list);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_namespace_error
- *
- * PARAMETERS:  module_name         - Caller's module name (for error output)
- *              line_number         - Caller's line number (for error output)
- *              internal_name       - Name or path of the namespace node
- *              lookup_status       - Exception code from NS lookup
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print error message with the full pathname for the NS node.
- *
- ******************************************************************************/
-
-void
-acpi_ut_namespace_error(const char *module_name,
-			u32 line_number,
-			const char *internal_name, acpi_status lookup_status)
-{
-	acpi_status status;
-	u32 bad_name;
-	char *name = NULL;
-
-	ACPI_MSG_REDIRECT_BEGIN;
-	acpi_os_printf(ACPI_MSG_ERROR);
-
-	if (lookup_status == AE_BAD_CHARACTER) {
-
-		/* There is a non-ascii character in the name */
-
-		ACPI_MOVE_32_TO_32(&bad_name,
-				   ACPI_CAST_PTR(u32, internal_name));
-		acpi_os_printf("[0x%.8X] (NON-ASCII)", bad_name);
-	} else {
-		/* Convert path to external format */
-
-		status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
-						  internal_name, NULL, &name);
-
-		/* Print target name */
-
-		if (ACPI_SUCCESS(status)) {
-			acpi_os_printf("[%s]", name);
-		} else {
-			acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
-		}
-
-		if (name) {
-			ACPI_FREE(name);
-		}
-	}
-
-	acpi_os_printf(" Namespace lookup failure, %s",
-		       acpi_format_exception(lookup_status));
-
-	ACPI_MSG_SUFFIX;
-	ACPI_MSG_REDIRECT_END;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_method_error
- *
- * PARAMETERS:  module_name         - Caller's module name (for error output)
- *              line_number         - Caller's line number (for error output)
- *              message             - Error message to use on failure
- *              prefix_node         - Prefix relative to the path
- *              path                - Path to the node (optional)
- *              method_status       - Execution status
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print error message with the full pathname for the method.
- *
- ******************************************************************************/
-
-void
-acpi_ut_method_error(const char *module_name,
-		     u32 line_number,
-		     const char *message,
-		     struct acpi_namespace_node *prefix_node,
-		     const char *path, acpi_status method_status)
-{
-	acpi_status status;
-	struct acpi_namespace_node *node = prefix_node;
-
-	ACPI_MSG_REDIRECT_BEGIN;
-	acpi_os_printf(ACPI_MSG_ERROR);
-
-	if (path) {
-		status =
-		    acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
-				     &node);
-		if (ACPI_FAILURE(status)) {
-			acpi_os_printf("[Could not get node by pathname]");
-		}
-	}
-
-	acpi_ns_print_node_pathname(node, message);
-	acpi_os_printf(", %s", acpi_format_exception(method_status));
-
-	ACPI_MSG_SUFFIX;
-	ACPI_MSG_REDIRECT_END;
-}
-
-#endif				/* ACPI_NO_ERROR_MESSAGES */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpi_cmos_rtc.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpi_cmos_rtc.c
--- linux-libre-3.10-gnu/drivers/acpi/acpi_cmos_rtc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpi_cmos_rtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * ACPI support for CMOS RTC Address Space access
+ *
+ * Copyright (C) 2013, Intel Corporation
+ * Authors: Lan Tianyu <tianyu.lan@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm-generic/rtc.h>
+
+#include "internal.h"
+
+#define PREFIX "ACPI: "
+
+ACPI_MODULE_NAME("cmos rtc");
+
+static const struct acpi_device_id acpi_cmos_rtc_ids[] = {
+	{ "PNP0B00" },
+	{ "PNP0B01" },
+	{ "PNP0B02" },
+	{}
+};
+
+static acpi_status
+acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
+		      u32 bits, u64 *value64,
+		      void *handler_context, void *region_context)
+{
+	int i;
+	u8 *value = (u8 *)&value64;
+
+	if (address > 0xff || !value64)
+		return AE_BAD_PARAMETER;
+
+	if (function != ACPI_WRITE && function != ACPI_READ)
+		return AE_BAD_PARAMETER;
+
+	spin_lock_irq(&rtc_lock);
+
+	for (i = 0; i < DIV_ROUND_UP(bits, 8); ++i, ++address, ++value)
+		if (function == ACPI_READ)
+			*value = CMOS_READ(address);
+		else
+			CMOS_WRITE(*value, address);
+
+	spin_unlock_irq(&rtc_lock);
+
+	return AE_OK;
+}
+
+static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
+		const struct acpi_device_id *id)
+{
+	acpi_status status;
+
+	status = acpi_install_address_space_handler(adev->handle,
+			ACPI_ADR_SPACE_CMOS,
+			&acpi_cmos_rtc_space_handler,
+			NULL, NULL);
+	if (ACPI_FAILURE(status)) {
+		pr_err(PREFIX "Error installing CMOS-RTC region handler\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
+{
+	if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle,
+			ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
+		pr_err(PREFIX "Error removing CMOS-RTC region handler\n");
+}
+
+static struct acpi_scan_handler cmos_rtc_handler = {
+	.ids = acpi_cmos_rtc_ids,
+	.attach = acpi_install_cmos_rtc_space_handler,
+	.detach = acpi_remove_cmos_rtc_space_handler,
+};
+
+void __init acpi_cmos_rtc_init(void)
+{
+	acpi_scan_add_handler(&cmos_rtc_handler);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpi_lpss.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpi_lpss.c
--- linux-libre-3.10-gnu/drivers/acpi/acpi_lpss.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpi_lpss.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,12 +32,26 @@ ACPI_MODULE_NAME("acpi_lpss");
 #define LPSS_GENERAL_LTR_MODE_SW	BIT(2)
 #define LPSS_SW_LTR			0x10
 #define LPSS_AUTO_LTR			0x14
+#define LPSS_TX_INT			0x20
+#define LPSS_TX_INT_MASK		BIT(1)
+
+struct lpss_shared_clock {
+	const char *name;
+	unsigned long rate;
+	struct clk *clk;
+};
+
+struct lpss_private_data;
 
 struct lpss_device_desc {
 	bool clk_required;
 	const char *clkdev_name;
 	bool ltr_required;
 	unsigned int prv_offset;
+	size_t prv_size_override;
+	bool clk_gate;
+	struct lpss_shared_clock *shared_clock;
+	void (*setup)(struct lpss_private_data *pdata);
 };
 
 static struct lpss_device_desc lpss_dma_desc = {
@@ -52,17 +66,76 @@ struct lpss_private_data {
 	const struct lpss_device_desc *dev_desc;
 };
 
+static void lpss_uart_setup(struct lpss_private_data *pdata)
+{
+	unsigned int tx_int_offset = pdata->dev_desc->prv_offset + LPSS_TX_INT;
+	u32 reg;
+
+	reg = readl(pdata->mmio_base + tx_int_offset);
+	writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + tx_int_offset);
+}
+
 static struct lpss_device_desc lpt_dev_desc = {
 	.clk_required = true,
 	.prv_offset = 0x800,
 	.ltr_required = true,
+	.clk_gate = true,
+};
+
+static struct lpss_device_desc lpt_uart_dev_desc = {
+	.clk_required = true,
+	.prv_offset = 0x800,
+	.ltr_required = true,
+	.clk_gate = true,
+	.setup = lpss_uart_setup,
 };
 
 static struct lpss_device_desc lpt_sdio_dev_desc = {
 	.prv_offset = 0x1000,
+	.prv_size_override = 0x1018,
 	.ltr_required = true,
 };
 
+static struct lpss_shared_clock uart_clock = {
+	.name = "uart_clk",
+	.rate = 44236800,
+};
+
+static struct lpss_device_desc byt_uart_dev_desc = {
+	.clk_required = true,
+	.prv_offset = 0x800,
+	.clk_gate = true,
+	.shared_clock = &uart_clock,
+	.setup = lpss_uart_setup,
+};
+
+static struct lpss_shared_clock spi_clock = {
+	.name = "spi_clk",
+	.rate = 50000000,
+};
+
+static struct lpss_device_desc byt_spi_dev_desc = {
+	.clk_required = true,
+	.prv_offset = 0x400,
+	.clk_gate = true,
+	.shared_clock = &spi_clock,
+};
+
+static struct lpss_device_desc byt_sdio_dev_desc = {
+	.clk_required = true,
+};
+
+static struct lpss_shared_clock i2c_clock = {
+	.name = "i2c_clk",
+	.rate = 100000000,
+};
+
+static struct lpss_device_desc byt_i2c_dev_desc = {
+	.clk_required = true,
+	.prv_offset = 0x800,
+	.shared_clock = &i2c_clock,
+};
+
 static const struct acpi_device_id acpi_lpss_device_ids[] = {
 	/* Generic LPSS devices */
 	{ "INTL9C60", (unsigned long)&lpss_dma_desc },
@@ -72,11 +145,18 @@ static const struct acpi_device_id acpi_
 	{ "INT33C1", (unsigned long)&lpt_dev_desc },
 	{ "INT33C2", (unsigned long)&lpt_dev_desc },
 	{ "INT33C3", (unsigned long)&lpt_dev_desc },
-	{ "INT33C4", (unsigned long)&lpt_dev_desc },
-	{ "INT33C5", (unsigned long)&lpt_dev_desc },
+	{ "INT33C4", (unsigned long)&lpt_uart_dev_desc },
+	{ "INT33C5", (unsigned long)&lpt_uart_dev_desc },
 	{ "INT33C6", (unsigned long)&lpt_sdio_dev_desc },
 	{ "INT33C7", },
 
+	/* BayTrail LPSS devices */
+	{ "80860F0A", (unsigned long)&byt_uart_dev_desc },
+	{ "80860F0E", (unsigned long)&byt_spi_dev_desc },
+	{ "80860F14", (unsigned long)&byt_sdio_dev_desc },
+	{ "80860F41", (unsigned long)&byt_i2c_dev_desc },
+	{ "INT33B2", },
+
 	{ }
 };
 
@@ -98,7 +178,10 @@ static int register_device_clock(struct
 				 struct lpss_private_data *pdata)
 {
 	const struct lpss_device_desc *dev_desc = pdata->dev_desc;
+	struct lpss_shared_clock *shared_clock = dev_desc->shared_clock;
+	struct clk *clk = ERR_PTR(-ENODEV);
 	struct lpss_clk_data *clk_data;
+	const char *parent;
 
 	if (!lpss_clk_dev)
 		lpt_register_clock_device();
@@ -117,14 +200,30 @@ static int register_device_clock(struct
 	    || pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE)
 		return -ENODATA;
 
-	pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev),
-				       clk_data->name, 0,
-				       pdata->mmio_base + dev_desc->prv_offset,
-				       0, 0, NULL);
-	if (IS_ERR(pdata->clk))
-		return PTR_ERR(pdata->clk);
+	parent = clk_data->name;
 
-	clk_register_clkdev(pdata->clk, NULL, dev_name(&adev->dev));
+	if (shared_clock) {
+		clk = shared_clock->clk;
+		if (!clk) {
+			clk = clk_register_fixed_rate(NULL, shared_clock->name,
+						      "lpss_clk", 0,
+						      shared_clock->rate);
+			shared_clock->clk = clk;
+		}
+		parent = shared_clock->name;
+	}
+
+	if (dev_desc->clk_gate) {
+		clk = clk_register_gate(NULL, dev_name(&adev->dev), parent, 0,
+					pdata->mmio_base + dev_desc->prv_offset,
+					0, 0, NULL);
+		pdata->clk = clk;
+	}
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	clk_register_clkdev(clk, NULL, dev_name(&adev->dev));
 	return 0;
 }
 
@@ -152,7 +251,10 @@ static int acpi_lpss_create_device(struc
 
 	list_for_each_entry(rentry, &resource_list, node)
 		if (resource_type(&rentry->res) == IORESOURCE_MEM) {
-			pdata->mmio_size = resource_size(&rentry->res);
+			if (dev_desc->prv_size_override)
+				pdata->mmio_size = dev_desc->prv_size_override;
+			else
+				pdata->mmio_size = resource_size(&rentry->res);
 			pdata->mmio_base = ioremap(rentry->res.start,
 						   pdata->mmio_size);
 			pdata->dev_desc = dev_desc;
@@ -182,6 +284,9 @@ static int acpi_lpss_create_device(struc
 		goto err_out;
 	}
 
+	if (dev_desc->setup)
+		dev_desc->setup(pdata);
+
 	adev->driver_data = pdata;
 	ret = acpi_create_platform_device(adev, id);
 	if (ret > 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpi_memhotplug.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpi_memhotplug.c
--- linux-libre-3.10-gnu/drivers/acpi/acpi_memhotplug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpi_memhotplug.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/memory.h>
 #include <linux/memory_hotplug.h>
 
 #include "internal.h"
@@ -166,13 +167,50 @@ static int acpi_memory_check_device(stru
 	return 0;
 }
 
+static unsigned long acpi_meminfo_start_pfn(struct acpi_memory_info *info)
+{
+	return PFN_DOWN(info->start_addr);
+}
+
+static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info)
+{
+	return PFN_UP(info->start_addr + info->length-1);
+}
+
+static int acpi_bind_memblk(struct memory_block *mem, void *arg)
+{
+	return acpi_bind_one(&mem->dev, (acpi_handle)arg);
+}
+
+static int acpi_bind_memory_blocks(struct acpi_memory_info *info,
+				   acpi_handle handle)
+{
+	return walk_memory_range(acpi_meminfo_start_pfn(info),
+				 acpi_meminfo_end_pfn(info), (void *)handle,
+				 acpi_bind_memblk);
+}
+
+static int acpi_unbind_memblk(struct memory_block *mem, void *arg)
+{
+	acpi_unbind_one(&mem->dev);
+	return 0;
+}
+
+static void acpi_unbind_memory_blocks(struct acpi_memory_info *info,
+				      acpi_handle handle)
+{
+	walk_memory_range(acpi_meminfo_start_pfn(info),
+			  acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk);
+}
+
 static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
 {
+	acpi_handle handle = mem_device->device->handle;
 	int result, num_enabled = 0;
 	struct acpi_memory_info *info;
 	int node;
 
-	node = acpi_get_node(mem_device->device->handle);
+	node = acpi_get_node(handle);
 	/*
 	 * Tell the VM there is more memory here...
 	 * Note: Assume that this function returns zero on success
@@ -203,6 +241,12 @@ static int acpi_memory_enable_device(str
 		if (result && result != -EEXIST)
 			continue;
 
+		result = acpi_bind_memory_blocks(info, handle);
+		if (result) {
+			acpi_unbind_memory_blocks(info, handle);
+			return -ENODEV;
+		}
+
 		info->enabled = 1;
 
 		/*
@@ -227,12 +271,11 @@ static int acpi_memory_enable_device(str
 	return 0;
 }
 
-static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
+static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
 {
-	int result = 0, nid;
+	acpi_handle handle = mem_device->device->handle;
 	struct acpi_memory_info *info, *n;
-
-	nid = acpi_get_node(mem_device->device->handle);
+	int nid = acpi_get_node(handle);
 
 	list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
 		if (!info->enabled)
@@ -240,15 +283,12 @@ static int acpi_memory_remove_memory(str
 
 		if (nid < 0)
 			nid = memory_add_physaddr_to_nid(info->start_addr);
-		result = remove_memory(nid, info->start_addr, info->length);
-		if (result)
-			return result;
 
+		acpi_unbind_memory_blocks(info, handle);
+		remove_memory(nid, info->start_addr, info->length);
 		list_del(&info->list);
 		kfree(info);
 	}
-
-	return result;
 }
 
 static void acpi_memory_device_free(struct acpi_memory_device *mem_device)
@@ -283,6 +323,7 @@ static int acpi_memory_device_add(struct
 	/* Get the range from the _CRS */
 	result = acpi_memory_get_device_resources(mem_device);
 	if (result) {
+		device->driver_data = NULL;
 		kfree(mem_device);
 		return result;
 	}
@@ -300,7 +341,7 @@ static int acpi_memory_device_add(struct
 	if (result) {
 		dev_err(&device->dev, "acpi_memory_enable_device() error\n");
 		acpi_memory_device_free(mem_device);
-		return -ENODEV;
+		return result;
 	}
 
 	dev_dbg(&device->dev, "Memory device configured by ACPI\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/acpi_processor.c linux-libre-3.11-rc7-gnu/drivers/acpi/acpi_processor.c
--- linux-libre-3.10-gnu/drivers/acpi/acpi_processor.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/acpi_processor.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,495 @@
+/*
+ * acpi_processor.c - ACPI processor enumeration support
+ *
+ * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ * Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
+ * Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ * Copyright (C) 2013, Intel Corporation
+ *                     Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include <acpi/processor.h>
+
+#include <asm/cpu.h>
+
+#include "internal.h"
+
+#define _COMPONENT	ACPI_PROCESSOR_COMPONENT
+
+ACPI_MODULE_NAME("processor");
+
+DEFINE_PER_CPU(struct acpi_processor *, processors);
+EXPORT_PER_CPU_SYMBOL(processors);
+
+/* --------------------------------------------------------------------------
+                                Errata Handling
+   -------------------------------------------------------------------------- */
+
+struct acpi_processor_errata errata __read_mostly;
+EXPORT_SYMBOL_GPL(errata);
+
+static int acpi_processor_errata_piix4(struct pci_dev *dev)
+{
+	u8 value1 = 0;
+	u8 value2 = 0;
+
+
+	if (!dev)
+		return -EINVAL;
+
+	/*
+	 * Note that 'dev' references the PIIX4 ACPI Controller.
+	 */
+
+	switch (dev->revision) {
+	case 0:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
+		break;
+	case 1:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
+		break;
+	case 2:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
+		break;
+	case 3:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
+		break;
+	}
+
+	switch (dev->revision) {
+
+	case 0:		/* PIIX4 A-step */
+	case 1:		/* PIIX4 B-step */
+		/*
+		 * See specification changes #13 ("Manual Throttle Duty Cycle")
+		 * and #14 ("Enabling and Disabling Manual Throttle"), plus
+		 * erratum #5 ("STPCLK# Deassertion Time") from the January
+		 * 2002 PIIX4 specification update.  Applies to only older
+		 * PIIX4 models.
+		 */
+		errata.piix4.throttle = 1;
+
+	case 2:		/* PIIX4E */
+	case 3:		/* PIIX4M */
+		/*
+		 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
+		 * Livelock") from the January 2002 PIIX4 specification update.
+		 * Applies to all PIIX4 models.
+		 */
+
+		/*
+		 * BM-IDE
+		 * ------
+		 * Find the PIIX4 IDE Controller and get the Bus Master IDE
+		 * Status register address.  We'll use this later to read
+		 * each IDE controller's DMA status to make sure we catch all
+		 * DMA activity.
+		 */
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+				     PCI_DEVICE_ID_INTEL_82371AB,
+				     PCI_ANY_ID, PCI_ANY_ID, NULL);
+		if (dev) {
+			errata.piix4.bmisx = pci_resource_start(dev, 4);
+			pci_dev_put(dev);
+		}
+
+		/*
+		 * Type-F DMA
+		 * ----------
+		 * Find the PIIX4 ISA Controller and read the Motherboard
+		 * DMA controller's status to see if Type-F (Fast) DMA mode
+		 * is enabled (bit 7) on either channel.  Note that we'll
+		 * disable C3 support if this is enabled, as some legacy
+		 * devices won't operate well if fast DMA is disabled.
+		 */
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+				     PCI_DEVICE_ID_INTEL_82371AB_0,
+				     PCI_ANY_ID, PCI_ANY_ID, NULL);
+		if (dev) {
+			pci_read_config_byte(dev, 0x76, &value1);
+			pci_read_config_byte(dev, 0x77, &value2);
+			if ((value1 & 0x80) || (value2 & 0x80))
+				errata.piix4.fdma = 1;
+			pci_dev_put(dev);
+		}
+
+		break;
+	}
+
+	if (errata.piix4.bmisx)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Bus master activity detection (BM-IDE) erratum enabled\n"));
+	if (errata.piix4.fdma)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Type-F DMA livelock erratum (C3 disabled)\n"));
+
+	return 0;
+}
+
+static int acpi_processor_errata(struct acpi_processor *pr)
+{
+	int result = 0;
+	struct pci_dev *dev = NULL;
+
+
+	if (!pr)
+		return -EINVAL;
+
+	/*
+	 * PIIX4
+	 */
+	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+			     PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
+			     PCI_ANY_ID, NULL);
+	if (dev) {
+		result = acpi_processor_errata_piix4(dev);
+		pci_dev_put(dev);
+	}
+
+	return result;
+}
+
+/* --------------------------------------------------------------------------
+                                Initialization
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+static int acpi_processor_hotadd_init(struct acpi_processor *pr)
+{
+	unsigned long long sta;
+	acpi_status status;
+	int ret;
+
+	status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta);
+	if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
+		return -ENODEV;
+
+	ret = acpi_map_lsapic(pr->handle, &pr->id);
+	if (ret)
+		return ret;
+
+	ret = arch_register_cpu(pr->id);
+	if (ret) {
+		acpi_unmap_lsapic(pr->id);
+		return ret;
+	}
+
+	/*
+	 * CPU got hot-added, but cpu_data is not initialized yet.  Set a flag
+	 * to delay cpu_idle/throttling initialization and do it when the CPU
+	 * gets online for the first time.
+	 */
+	pr_info("CPU%d has been hot-added\n", pr->id);
+	pr->flags.need_hotplug_init = 1;
+	return 0;
+}
+#else
+static inline int acpi_processor_hotadd_init(struct acpi_processor *pr)
+{
+	return -ENODEV;
+}
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
+static int acpi_processor_get_info(struct acpi_device *device)
+{
+	union acpi_object object = { 0 };
+	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
+	struct acpi_processor *pr = acpi_driver_data(device);
+	int cpu_index, device_declaration = 0;
+	acpi_status status = AE_OK;
+	static int cpu0_initialized;
+
+	if (num_online_cpus() > 1)
+		errata.smp = TRUE;
+
+	acpi_processor_errata(pr);
+
+	/*
+	 * Check to see if we have bus mastering arbitration control.  This
+	 * is required for proper C3 usage (to maintain cache coherency).
+	 */
+	if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
+		pr->flags.bm_control = 1;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Bus mastering arbitration control present\n"));
+	} else
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "No bus mastering arbitration control\n"));
+
+	if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
+		/* Declared with "Processor" statement; match ProcessorID */
+		status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
+		if (ACPI_FAILURE(status)) {
+			dev_err(&device->dev,
+				"Failed to evaluate processor object (0x%x)\n",
+				status);
+			return -ENODEV;
+		}
+
+		/*
+		 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
+		 *      >>> 'acpi_get_processor_id(acpi_id, &id)' in
+		 *      arch/xxx/acpi.c
+		 */
+		pr->acpi_id = object.processor.proc_id;
+	} else {
+		/*
+		 * Declared with "Device" statement; match _UID.
+		 * Note that we don't handle string _UIDs yet.
+		 */
+		unsigned long long value;
+		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
+						NULL, &value);
+		if (ACPI_FAILURE(status)) {
+			dev_err(&device->dev,
+				"Failed to evaluate processor _UID (0x%x)\n",
+				status);
+			return -ENODEV;
+		}
+		device_declaration = 1;
+		pr->acpi_id = value;
+	}
+	cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id);
+
+	/* Handle UP system running SMP kernel, with no LAPIC in MADT */
+	if (!cpu0_initialized && (cpu_index == -1) &&
+	    (num_online_cpus() == 1)) {
+		cpu_index = 0;
+	}
+
+	cpu0_initialized = 1;
+
+	pr->id = cpu_index;
+
+	/*
+	 *  Extra Processor objects may be enumerated on MP systems with
+	 *  less than the max # of CPUs. They should be ignored _iff
+	 *  they are physically not present.
+	 */
+	if (pr->id == -1) {
+		int ret = acpi_processor_hotadd_init(pr);
+		if (ret)
+			return ret;
+	}
+	/*
+	 * On some boxes several processors use the same processor bus id.
+	 * But they are located in different scope. For example:
+	 * \_SB.SCK0.CPU0
+	 * \_SB.SCK1.CPU0
+	 * Rename the processor device bus id. And the new bus id will be
+	 * generated as the following format:
+	 * CPU+CPU ID.
+	 */
+	sprintf(acpi_device_bid(device), "CPU%X", pr->id);
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
+			  pr->acpi_id));
+
+	if (!object.processor.pblk_address)
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
+	else if (object.processor.pblk_length != 6)
+		dev_err(&device->dev, "Invalid PBLK length [%d]\n",
+			    object.processor.pblk_length);
+	else {
+		pr->throttling.address = object.processor.pblk_address;
+		pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
+		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
+
+		pr->pblk = object.processor.pblk_address;
+
+		/*
+		 * We don't care about error returns - we just try to mark
+		 * these reserved so that nobody else is confused into thinking
+		 * that this region might be unused..
+		 *
+		 * (In particular, allocating the IO range for Cardbus)
+		 */
+		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
+	}
+
+	/*
+	 * If ACPI describes a slot number for this CPU, we can use it to
+	 * ensure we get the right value in the "physical id" field
+	 * of /proc/cpuinfo
+	 */
+	status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
+	if (ACPI_SUCCESS(status))
+		arch_fix_phys_package_id(pr->id, object.integer.value);
+
+	return 0;
+}
+
+/*
+ * Do not put anything in here which needs the core to be online.
+ * For example MSR access or setting up things which check for cpuinfo_x86
+ * (cpu_data(cpu)) values, like CPU feature flags, family, model, etc.
+ * Such things have to be put in and set up by the processor driver's .probe().
+ */
+static DEFINE_PER_CPU(void *, processor_device_array);
+
+static int acpi_processor_add(struct acpi_device *device,
+					const struct acpi_device_id *id)
+{
+	struct acpi_processor *pr;
+	struct device *dev;
+	int result = 0;
+
+	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
+	if (!pr)
+		return -ENOMEM;
+
+	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
+		result = -ENOMEM;
+		goto err_free_pr;
+	}
+
+	pr->handle = device->handle;
+	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
+	device->driver_data = pr;
+
+	result = acpi_processor_get_info(device);
+	if (result) /* Processor is not physically present or unavailable */
+		return 0;
+
+#ifdef CONFIG_SMP
+	if (pr->id >= setup_max_cpus && pr->id != 0)
+		return 0;
+#endif
+
+	BUG_ON(pr->id >= nr_cpu_ids);
+
+	/*
+	 * Buggy BIOS check.
+	 * ACPI id of processors can be reported wrongly by the BIOS.
+	 * Don't trust it blindly
+	 */
+	if (per_cpu(processor_device_array, pr->id) != NULL &&
+	    per_cpu(processor_device_array, pr->id) != device) {
+		dev_warn(&device->dev,
+			"BIOS reported wrong ACPI id %d for the processor\n",
+			pr->id);
+		/* Give up, but do not abort the namespace scan. */
+		goto err;
+	}
+	/*
+	 * processor_device_array is not cleared on errors to allow buggy BIOS
+	 * checks.
+	 */
+	per_cpu(processor_device_array, pr->id) = device;
+	per_cpu(processors, pr->id) = pr;
+
+	dev = get_cpu_device(pr->id);
+	if (!dev) {
+		result = -ENODEV;
+		goto err;
+	}
+
+	result = acpi_bind_one(dev, pr->handle);
+	if (result)
+		goto err;
+
+	pr->dev = dev;
+	dev->offline = pr->flags.need_hotplug_init;
+
+	/* Trigger the processor driver's .probe() if present. */
+	if (device_attach(dev) >= 0)
+		return 1;
+
+	dev_err(dev, "Processor driver could not be attached\n");
+	acpi_unbind_one(dev);
+
+ err:
+	free_cpumask_var(pr->throttling.shared_cpu_map);
+	device->driver_data = NULL;
+	per_cpu(processors, pr->id) = NULL;
+ err_free_pr:
+	kfree(pr);
+	return result;
+}
+
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+/* --------------------------------------------------------------------------
+                                    Removal
+   -------------------------------------------------------------------------- */
+
+static void acpi_processor_remove(struct acpi_device *device)
+{
+	struct acpi_processor *pr;
+
+	if (!device || !acpi_driver_data(device))
+		return;
+
+	pr = acpi_driver_data(device);
+	if (pr->id >= nr_cpu_ids)
+		goto out;
+
+	/*
+	 * The only reason why we ever get here is CPU hot-removal.  The CPU is
+	 * already offline and the ACPI device removal locking prevents it from
+	 * being put back online at this point.
+	 *
+	 * Unbind the driver from the processor device and detach it from the
+	 * ACPI companion object.
+	 */
+	device_release_driver(pr->dev);
+	acpi_unbind_one(pr->dev);
+
+	/* Clean up. */
+	per_cpu(processor_device_array, pr->id) = NULL;
+	per_cpu(processors, pr->id) = NULL;
+
+	/* Remove the CPU. */
+	get_online_cpus();
+	arch_unregister_cpu(pr->id);
+	acpi_unmap_lsapic(pr->id);
+	put_online_cpus();
+
+	try_offline_node(cpu_to_node(pr->id));
+
+ out:
+	free_cpumask_var(pr->throttling.shared_cpu_map);
+	kfree(pr);
+}
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+
+/*
+ * The following ACPI IDs are known to be suitable for representing as
+ * processor devices.
+ */
+static const struct acpi_device_id processor_device_ids[] = {
+
+	{ ACPI_PROCESSOR_OBJECT_HID, },
+	{ ACPI_PROCESSOR_DEVICE_HID, },
+
+	{ }
+};
+
+static struct acpi_scan_handler __refdata processor_handler = {
+	.ids = processor_device_ids,
+	.attach = acpi_processor_add,
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+	.detach = acpi_processor_remove,
+#endif
+	.hotplug = {
+		.enabled = true,
+	},
+};
+
+void __init acpi_processor_init(void)
+{
+	acpi_scan_add_handler_with_hotplug(&processor_handler, "processor");
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/apei/einj.c linux-libre-3.11-rc7-gnu/drivers/acpi/apei/einj.c
--- linux-libre-3.10-gnu/drivers/acpi/apei/einj.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/apei/einj.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/seq_file.h>
 #include <linux/nmi.h>
 #include <linux/delay.h>
+#include <linux/mm.h>
 #include <acpi/acpi.h>
 
 #include "apei-internal.h"
@@ -41,6 +42,10 @@
 #define SPIN_UNIT		100			/* 100ns */
 /* Firmware should respond within 1 milliseconds */
 #define FIRMWARE_TIMEOUT	(1 * NSEC_PER_MSEC)
+#define ACPI5_VENDOR_BIT	BIT(31)
+#define MEM_ERROR_MASK		(ACPI_EINJ_MEMORY_CORRECTABLE | \
+				ACPI_EINJ_MEMORY_UNCORRECTABLE | \
+				ACPI_EINJ_MEMORY_FATAL)
 
 /*
  * ACPI version 5 provides a SET_ERROR_TYPE_WITH_ADDRESS action.
@@ -367,7 +372,7 @@ static int __einj_error_trigger(u64 trig
 	 * This will cause resource conflict with regular memory.  So
 	 * remove it from trigger table resources.
 	 */
-	if ((param_extension || acpi5) && (type & 0x0038) && param2) {
+	if ((param_extension || acpi5) && (type & MEM_ERROR_MASK) && param2) {
 		struct apei_resources addr_resources;
 		apei_resources_init(&addr_resources);
 		trigger_param_region = einj_get_trigger_parameter_region(
@@ -427,7 +432,7 @@ static int __einj_error_inject(u32 type,
 		struct set_error_type_with_address *v5param = einj_param;
 
 		v5param->type = type;
-		if (type & 0x80000000) {
+		if (type & ACPI5_VENDOR_BIT) {
 			switch (vendor_flags) {
 			case SETWA_FLAGS_APICID:
 				v5param->apicid = param1;
@@ -512,7 +517,34 @@ static int __einj_error_inject(u32 type,
 static int einj_error_inject(u32 type, u64 param1, u64 param2)
 {
 	int rc;
+	unsigned long pfn;
 
+	/*
+	 * We need extra sanity checks for memory errors.
+	 * Other types leap directly to injection.
+	 */
+
+	/* ensure param1/param2 existed */
+	if (!(param_extension || acpi5))
+		goto inject;
+
+	/* ensure injection is memory related */
+	if (type & ACPI5_VENDOR_BIT) {
+		if (vendor_flags != SETWA_FLAGS_MEM)
+			goto inject;
+	} else if (!(type & MEM_ERROR_MASK))
+		goto inject;
+
+	/*
+	 * Disallow crazy address masks that give BIOS leeway to pick
+	 * injection address almost anywhere. Insist on page or
+	 * better granularity and that target address is normal RAM.
+	 */
+	pfn = PFN_DOWN(param1 & param2);
+	if (!page_is_ram(pfn) || ((param2 & PAGE_MASK) != PAGE_MASK))
+		return -EINVAL;
+
+inject:
 	mutex_lock(&einj_mutex);
 	rc = __einj_error_inject(type, param1, param2);
 	mutex_unlock(&einj_mutex);
@@ -590,7 +622,7 @@ static int error_type_set(void *data, u6
 	 * Vendor defined types have 0x80000000 bit set, and
 	 * are not enumerated by ACPI_EINJ_GET_ERROR_TYPE
 	 */
-	vendor = val & 0x80000000;
+	vendor = val & ACPI5_VENDOR_BIT;
 	tval = val & 0x7fffffff;
 
 	/* Only one error type can be specified */
@@ -694,6 +726,7 @@ static int __init einj_init(void)
 	if (rc)
 		goto err_release;
 
+	rc = -ENOMEM;
 	einj_param = einj_get_parameter_address();
 	if ((param_extension || acpi5) && einj_param) {
 		fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/apei/erst.c linux-libre-3.11-rc7-gnu/drivers/acpi/apei/erst.c
--- linux-libre-3.10-gnu/drivers/acpi/apei/erst.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/apei/erst.c	2013-08-25 20:43:22.000000000 -0400
@@ -935,7 +935,7 @@ static ssize_t erst_reader(u64 *id, enum
 			   struct timespec *time, char **buf,
 			   struct pstore_info *psi);
 static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
-		       u64 *id, unsigned int part, int count,
+		       u64 *id, unsigned int part, int count, size_t hsize,
 		       size_t size, struct pstore_info *psi);
 static int erst_clearer(enum pstore_type_id type, u64 id, int count,
 			struct timespec time, struct pstore_info *psi);
@@ -1055,7 +1055,7 @@ out:
 }
 
 static int erst_writer(enum pstore_type_id type, enum kmsg_dump_reason reason,
-		       u64 *id, unsigned int part, int count,
+		       u64 *id, unsigned int part, int count, size_t hsize,
 		       size_t size, struct pstore_info *psi)
 {
 	struct cper_pstore_record *rcd = (struct cper_pstore_record *)
@@ -1180,20 +1180,28 @@ static int __init erst_init(void)
 	if (!erst_erange.vaddr)
 		goto err_release_erange;
 
+	pr_info(ERST_PFX
+	"Error Record Serialization Table (ERST) support is initialized.\n");
+
 	buf = kmalloc(erst_erange.size, GFP_KERNEL);
 	spin_lock_init(&erst_info.buf_lock);
 	if (buf) {
 		erst_info.buf = buf + sizeof(struct cper_pstore_record);
 		erst_info.bufsize = erst_erange.size -
 				    sizeof(struct cper_pstore_record);
-		if (pstore_register(&erst_info)) {
-			pr_info(ERST_PFX "Could not register with persistent store\n");
+		rc = pstore_register(&erst_info);
+		if (rc) {
+			if (rc != -EPERM)
+				pr_info(ERST_PFX
+				"Could not register with persistent store\n");
+			erst_info.buf = NULL;
+			erst_info.bufsize = 0;
 			kfree(buf);
 		}
-	}
-
-	pr_info(ERST_PFX
-	"Error Record Serialization Table (ERST) support is initialized.\n");
+	} else
+		pr_err(ERST_PFX
+		"Failed to allocate %lld bytes for persistent store error log\n",
+		erst_erange.size);
 
 	return 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/apei/ghes.c linux-libre-3.11-rc7-gnu/drivers/acpi/apei/ghes.c
--- linux-libre-3.10-gnu/drivers/acpi/apei/ghes.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/apei/ghes.c	2013-08-25 20:43:22.000000000 -0400
@@ -449,9 +449,19 @@ static void ghes_do_proc(struct ghes *gh
 			    pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
 				unsigned int devfn;
 				int aer_severity;
+
 				devfn = PCI_DEVFN(pcie_err->device_id.device,
 						  pcie_err->device_id.function);
 				aer_severity = cper_severity_to_aer(sev);
+
+				/*
+				 * If firmware reset the component to contain
+				 * the error, we must reinitialize it before
+				 * use, so treat it as a fatal AER error.
+				 */
+				if (gdata->flags & CPER_SEC_RESET)
+					aer_severity = AER_FATAL;
+
 				aer_recover_queue(pcie_err->device_id.segment,
 						  pcie_err->device_id.bus,
 						  devfn, aer_severity,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/battery.c linux-libre-3.11-rc7-gnu/drivers/acpi/battery.c
--- linux-libre-3.10-gnu/drivers/acpi/battery.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/battery.c	2013-08-25 20:43:22.000000000 -0400
@@ -117,6 +117,7 @@ struct acpi_battery {
 	struct acpi_device *device;
 	struct notifier_block pm_nb;
 	unsigned long update_time;
+	int revision;
 	int rate_now;
 	int capacity_now;
 	int voltage_now;
@@ -359,6 +360,7 @@ static struct acpi_offsets info_offsets[
 };
 
 static struct acpi_offsets extended_info_offsets[] = {
+	{offsetof(struct acpi_battery, revision), 0},
 	{offsetof(struct acpi_battery, power_unit), 0},
 	{offsetof(struct acpi_battery, design_capacity), 0},
 	{offsetof(struct acpi_battery, full_charge_capacity), 0},
@@ -425,7 +427,7 @@ static int acpi_battery_get_info(struct
 {
 	int result = -EFAULT;
 	acpi_status status = 0;
-	char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
+	char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags) ?
 			"_BIX" : "_BIF";
 
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -661,11 +663,11 @@ static void find_battery(const struct dm
 static void acpi_battery_quirks(struct acpi_battery *battery)
 {
 	if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
-		return ;
+		return;
 
-        if (battery->full_charge_capacity == 100 &&
-            battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
-            battery->capacity_now >=0 && battery->capacity_now <= 100) {
+	if (battery->full_charge_capacity == 100 &&
+		battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
+		battery->capacity_now >= 0 && battery->capacity_now <= 100) {
 		set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
 		battery->full_charge_capacity = battery->design_capacity;
 		battery->capacity_now = (battery->capacity_now *
@@ -673,7 +675,7 @@ static void acpi_battery_quirks(struct a
 	}
 
 	if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
-		return ;
+		return;
 
 	if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
 		const char *s;
@@ -761,7 +763,7 @@ static int acpi_battery_print_info(struc
 		goto end;
 
 	seq_printf(seq, "present:                 %s\n",
-		   acpi_battery_present(battery)?"yes":"no");
+		   acpi_battery_present(battery) ? "yes" : "no");
 	if (!acpi_battery_present(battery))
 		goto end;
 	if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
@@ -817,12 +819,12 @@ static int acpi_battery_print_state(stru
 		goto end;
 
 	seq_printf(seq, "present:                 %s\n",
-		   acpi_battery_present(battery)?"yes":"no");
+		   acpi_battery_present(battery) ? "yes" : "no");
 	if (!acpi_battery_present(battery))
 		goto end;
 
 	seq_printf(seq, "capacity state:          %s\n",
-			(battery->state & 0x04)?"critical":"ok");
+			(battery->state & 0x04) ? "critical" : "ok");
 	if ((battery->state & 0x01) && (battery->state & 0x02))
 		seq_printf(seq,
 			   "charging state:          charging/discharging\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/bus.c linux-libre-3.11-rc7-gnu/drivers/acpi/bus.c
--- linux-libre-3.10-gnu/drivers/acpi/bus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -91,8 +91,7 @@ static struct dmi_system_id dsdt_dmi_tab
 
 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
 {
-	acpi_status status = AE_OK;
-
+	acpi_status status;
 
 	if (!device)
 		return -EINVAL;
@@ -162,7 +161,7 @@ EXPORT_SYMBOL(acpi_bus_private_data_hand
 
 int acpi_bus_get_private_data(acpi_handle handle, void **data)
 {
-	acpi_status status = AE_OK;
+	acpi_status status;
 
 	if (!*data)
 		return -EINVAL;
@@ -361,7 +360,7 @@ extern int event_is_open;
 int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
 {
 	struct acpi_bus_event *event;
-	unsigned long flags = 0;
+	unsigned long flags;
 
 	/* drop event on the floor if no one's listening */
 	if (!event_is_open)
@@ -400,7 +399,7 @@ EXPORT_SYMBOL(acpi_bus_generate_proc_eve
 
 int acpi_bus_receive_event(struct acpi_bus_event *event)
 {
-	unsigned long flags = 0;
+	unsigned long flags;
 	struct acpi_bus_event *entry = NULL;
 
 	DECLARE_WAITQUEUE(wait, current);
@@ -593,7 +592,7 @@ static void acpi_bus_notify(acpi_handle
 
 static int __init acpi_bus_init_irq(void)
 {
-	acpi_status status = AE_OK;
+	acpi_status status;
 	union acpi_object arg = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list arg_list = { 1, &arg };
 	char *message = NULL;
@@ -640,7 +639,7 @@ u8 acpi_gbl_permanent_mmap;
 
 void __init acpi_early_init(void)
 {
-	acpi_status status = AE_OK;
+	acpi_status status;
 
 	if (acpi_disabled)
 		return;
@@ -714,8 +713,8 @@ void __init acpi_early_init(void)
 
 static int __init acpi_bus_init(void)
 {
-	int result = 0;
-	acpi_status status = AE_OK;
+	int result;
+	acpi_status status;
 	extern acpi_status acpi_os_initialize1(void);
 
 	acpi_os_initialize1();
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/device_pm.c linux-libre-3.11-rc7-gnu/drivers/acpi/device_pm.c
--- linux-libre-3.10-gnu/drivers/acpi/device_pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/device_pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -324,14 +324,27 @@ int acpi_bus_update_power(acpi_handle ha
 	if (result)
 		return result;
 
-	if (state == ACPI_STATE_UNKNOWN)
+	if (state == ACPI_STATE_UNKNOWN) {
 		state = ACPI_STATE_D0;
-
-	result = acpi_device_set_power(device, state);
-	if (!result && state_p)
+		result = acpi_device_set_power(device, state);
+		if (result)
+			return result;
+	} else {
+		if (device->power.flags.power_resources) {
+			/*
+			 * We don't need to really switch the state, bu we need
+			 * to update the power resources' reference counters.
+			 */
+			result = acpi_power_transition(device, state);
+			if (result)
+				return result;
+		}
+		device->power.state = state;
+	}
+	if (state_p)
 		*state_p = state;
 
-	return result;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_bus_update_power);
 
@@ -419,62 +432,73 @@ bool acpi_bus_can_wakeup(acpi_handle han
 EXPORT_SYMBOL(acpi_bus_can_wakeup);
 
 /**
- * acpi_device_power_state - Get preferred power state of ACPI device.
+ * acpi_dev_pm_get_state - Get preferred power state of ACPI device.
  * @dev: Device whose preferred target power state to return.
  * @adev: ACPI device node corresponding to @dev.
  * @target_state: System state to match the resultant device state.
- * @d_max_in: Deepest low-power state to take into consideration.
- * @d_min_p: Location to store the upper limit of the allowed states range.
- * Return value: Preferred power state of the device on success, -ENODEV
- * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure
+ * @d_min_p: Location to store the highest power state available to the device.
+ * @d_max_p: Location to store the lowest power state available to the device.
  *
- * Find the lowest power (highest number) ACPI device power state that the
- * device can be in while the system is in the state represented by
- * @target_state.  If @d_min_p is set, the highest power (lowest number) device
- * power state that @dev can be in for the given system sleep state is stored
- * at the location pointed to by it.
+ * Find the lowest power (highest number) and highest power (lowest number) ACPI
+ * device power states that the device can be in while the system is in the
+ * state represented by @target_state.  Store the integer numbers representing
+ * those stats in the memory locations pointed to by @d_max_p and @d_min_p,
+ * respectively.
  *
  * Callers must ensure that @dev and @adev are valid pointers and that @adev
  * actually corresponds to @dev before using this function.
+ *
+ * Returns 0 on success or -ENODATA when one of the ACPI methods fails or
+ * returns a value that doesn't make sense.  The memory locations pointed to by
+ * @d_max_p and @d_min_p are only modified on success.
  */
-int acpi_device_power_state(struct device *dev, struct acpi_device *adev,
-			    u32 target_state, int d_max_in, int *d_min_p)
+static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev,
+				 u32 target_state, int *d_min_p, int *d_max_p)
 {
-	char acpi_method[] = "_SxD";
-	unsigned long long d_min, d_max;
+	char method[] = { '_', 'S', '0' + target_state, 'D', '\0' };
+	acpi_handle handle = adev->handle;
+	unsigned long long ret;
+	int d_min, d_max;
 	bool wakeup = false;
+	acpi_status status;
 
-	if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3)
-		return -EINVAL;
-
-	if (d_max_in > ACPI_STATE_D3_HOT) {
-		enum pm_qos_flags_status stat;
-
-		stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF);
-		if (stat == PM_QOS_FLAGS_ALL)
-			d_max_in = ACPI_STATE_D3_HOT;
-	}
-
-	acpi_method[2] = '0' + target_state;
 	/*
-	 * If the sleep state is S0, the lowest limit from ACPI is D3,
-	 * but if the device has _S0W, we will use the value from _S0W
-	 * as the lowest limit from ACPI.  Finally, we will constrain
-	 * the lowest limit with the specified one.
+	 * If the system state is S0, the lowest power state the device can be
+	 * in is D3cold, unless the device has _S0W and is supposed to signal
+	 * wakeup, in which case the return value of _S0W has to be used as the
+	 * lowest power state available to the device.
 	 */
 	d_min = ACPI_STATE_D0;
-	d_max = ACPI_STATE_D3;
+	d_max = ACPI_STATE_D3_COLD;
 
 	/*
 	 * If present, _SxD methods return the minimum D-state (highest power
 	 * state) we can use for the corresponding S-states.  Otherwise, the
 	 * minimum D-state is D0 (ACPI 3.x).
-	 *
-	 * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer
-	 * provided -- that's our fault recovery, we ignore retval.
 	 */
 	if (target_state > ACPI_STATE_S0) {
-		acpi_evaluate_integer(adev->handle, acpi_method, NULL, &d_min);
+		/*
+		 * We rely on acpi_evaluate_integer() not clobbering the integer
+		 * provided if AE_NOT_FOUND is returned.
+		 */
+		ret = d_min;
+		status = acpi_evaluate_integer(handle, method, NULL, &ret);
+		if ((ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+		    || ret > ACPI_STATE_D3_COLD)
+			return -ENODATA;
+
+		/*
+		 * We need to handle legacy systems where D3hot and D3cold are
+		 * the same and 3 is returned in both cases, so fall back to
+		 * D3cold if D3hot is not a valid state.
+		 */
+		if (!adev->power.states[ret].flags.valid) {
+			if (ret == ACPI_STATE_D3_HOT)
+				ret = ACPI_STATE_D3_COLD;
+			else
+				return -ENODATA;
+		}
+		d_min = ret;
 		wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid
 			&& adev->wakeup.sleep_state >= target_state;
 	} else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) !=
@@ -490,38 +514,30 @@ int acpi_device_power_state(struct devic
 	 * can wake the system.  _S0W may be valid, too.
 	 */
 	if (wakeup) {
-		acpi_status status;
-
-		acpi_method[3] = 'W';
-		status = acpi_evaluate_integer(adev->handle, acpi_method, NULL,
-						&d_max);
-		if (ACPI_FAILURE(status)) {
-			if (target_state != ACPI_STATE_S0 ||
-			    status != AE_NOT_FOUND)
+		method[3] = 'W';
+		status = acpi_evaluate_integer(handle, method, NULL, &ret);
+		if (status == AE_NOT_FOUND) {
+			if (target_state > ACPI_STATE_S0)
 				d_max = d_min;
-		} else if (d_max < d_min) {
-			/* Warn the user of the broken DSDT */
-			printk(KERN_WARNING "ACPI: Wrong value from %s\n",
-				acpi_method);
-			/* Sanitize it */
-			d_min = d_max;
+		} else if (ACPI_SUCCESS(status) && ret <= ACPI_STATE_D3_COLD) {
+			/* Fall back to D3cold if ret is not a valid state. */
+			if (!adev->power.states[ret].flags.valid)
+				ret = ACPI_STATE_D3_COLD;
+
+			d_max = ret > d_min ? ret : d_min;
+		} else {
+			return -ENODATA;
 		}
 	}
 
-	if (d_max_in < d_min)
-		return -EINVAL;
 	if (d_min_p)
 		*d_min_p = d_min;
-	/* constrain d_max with specified lowest limit (max number) */
-	if (d_max > d_max_in) {
-		for (d_max = d_max_in; d_max > d_min; d_max--) {
-			if (adev->power.states[d_max].flags.valid)
-				break;
-		}
-	}
-	return d_max;
+
+	if (d_max_p)
+		*d_max_p = d_max;
+
+	return 0;
 }
-EXPORT_SYMBOL_GPL(acpi_device_power_state);
 
 /**
  * acpi_pm_device_sleep_state - Get preferred power state of ACPI device.
@@ -529,7 +545,8 @@ EXPORT_SYMBOL_GPL(acpi_device_power_stat
  * @d_min_p: Location to store the upper limit of the allowed states range.
  * @d_max_in: Deepest low-power state to take into consideration.
  * Return value: Preferred power state of the device on success, -ENODEV
- * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure
+ * if there's no 'struct acpi_device' for @dev, -EINVAL if @d_max_in is
+ * incorrect, or -ENODATA on ACPI method failure.
  *
  * The caller must ensure that @dev is valid before using this function.
  */
@@ -537,14 +554,43 @@ int acpi_pm_device_sleep_state(struct de
 {
 	acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
 	struct acpi_device *adev;
+	int ret, d_min, d_max;
+
+	if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3_COLD)
+		return -EINVAL;
+
+	if (d_max_in > ACPI_STATE_D3_HOT) {
+		enum pm_qos_flags_status stat;
+
+		stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF);
+		if (stat == PM_QOS_FLAGS_ALL)
+			d_max_in = ACPI_STATE_D3_HOT;
+	}
 
 	if (!handle || acpi_bus_get_device(handle, &adev)) {
 		dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
 		return -ENODEV;
 	}
 
-	return acpi_device_power_state(dev, adev, acpi_target_system_state(),
-				       d_max_in, d_min_p);
+	ret = acpi_dev_pm_get_state(dev, adev, acpi_target_system_state(),
+				    &d_min, &d_max);
+	if (ret)
+		return ret;
+
+	if (d_max_in < d_min)
+		return -EINVAL;
+
+	if (d_max > d_max_in) {
+		for (d_max = d_max_in; d_max > d_min; d_max--) {
+			if (adev->power.states[d_max].flags.valid)
+				break;
+		}
+	}
+
+	if (d_min_p)
+		*d_min_p = d_min;
+
+	return d_max;
 }
 EXPORT_SYMBOL(acpi_pm_device_sleep_state);
 
@@ -695,17 +741,13 @@ struct acpi_device *acpi_dev_pm_get_node
 static int acpi_dev_pm_low_power(struct device *dev, struct acpi_device *adev,
 				 u32 system_state)
 {
-	int power_state;
+	int ret, state;
 
 	if (!acpi_device_power_manageable(adev))
 		return 0;
 
-	power_state = acpi_device_power_state(dev, adev, system_state,
-					      ACPI_STATE_D3, NULL);
-	if (power_state < ACPI_STATE_D0 || power_state > ACPI_STATE_D3)
-		return -EIO;
-
-	return acpi_device_set_power(adev, power_state);
+	ret = acpi_dev_pm_get_state(dev, adev, system_state, NULL, &state);
+	return ret ? ret : acpi_device_set_power(adev, state);
 }
 
 /**
@@ -908,7 +950,6 @@ static struct dev_pm_domain acpi_general
 #ifdef CONFIG_PM_RUNTIME
 		.runtime_suspend = acpi_subsys_runtime_suspend,
 		.runtime_resume = acpi_subsys_runtime_resume,
-		.runtime_idle = pm_generic_runtime_idle,
 #endif
 #ifdef CONFIG_PM_SLEEP
 		.prepare = acpi_subsys_prepare,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/dock.c linux-libre-3.11-rc7-gnu/drivers/acpi/dock.c
--- linux-libre-3.10-gnu/drivers/acpi/dock.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/dock.c	2013-08-25 20:43:22.000000000 -0400
@@ -1064,10 +1064,10 @@ find_dock_and_bay(acpi_handle handle, u3
 	return AE_OK;
 }
 
-int __init acpi_dock_init(void)
+void __init acpi_dock_init(void)
 {
 	if (acpi_disabled)
-		return 0;
+		return;
 
 	/* look for dock stations and bays */
 	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
@@ -1075,11 +1075,10 @@ int __init acpi_dock_init(void)
 
 	if (!dock_station_count) {
 		pr_info(PREFIX "No dock devices found.\n");
-		return 0;
+		return;
 	}
 
 	register_acpi_bus_notifier(&dock_acpi_notifier);
 	pr_info(PREFIX "%s: %d docks/bays found\n",
 		ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
-	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/ec.c linux-libre-3.11-rc7-gnu/drivers/acpi/ec.c
--- linux-libre-3.10-gnu/drivers/acpi/ec.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/ec.c	2013-08-25 20:43:22.000000000 -0400
@@ -983,6 +983,10 @@ static struct dmi_system_id __initdata e
 	ec_enlarge_storm_threshold, "CLEVO hardware", {
 	DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
 	DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL},
+	{
+	ec_skip_dsdt_scan, "HP Folio 13", {
+	DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+	DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL},
 	{},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/ec_sys.c linux-libre-3.11-rc7-gnu/drivers/acpi/ec_sys.c
--- linux-libre-3.10-gnu/drivers/acpi/ec_sys.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/ec_sys.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/acpi.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
 #include "internal.h"
 
 MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
@@ -34,7 +35,6 @@ static ssize_t acpi_ec_read_io(struct fi
 	 * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
 	 */
 	unsigned int size = EC_SPACE_SIZE;
-	u8 *data = (u8 *) buf;
 	loff_t init_off = *off;
 	int err = 0;
 
@@ -47,9 +47,15 @@ static ssize_t acpi_ec_read_io(struct fi
 		size = count;
 
 	while (size) {
-		err = ec_read(*off, &data[*off - init_off]);
+		u8 byte_read;
+		err = ec_read(*off, &byte_read);
 		if (err)
 			return err;
+		if (put_user(byte_read, buf + *off - init_off)) {
+			if (*off - init_off)
+				return *off - init_off; /* partial read */
+			return -EFAULT;
+		}
 		*off += 1;
 		size--;
 	}
@@ -65,7 +71,6 @@ static ssize_t acpi_ec_write_io(struct f
 
 	unsigned int size = count;
 	loff_t init_off = *off;
-	u8 *data = (u8 *) buf;
 	int err = 0;
 
 	if (*off >= EC_SPACE_SIZE)
@@ -76,7 +81,12 @@ static ssize_t acpi_ec_write_io(struct f
 	}
 
 	while (size) {
-		u8 byte_write = data[*off - init_off];
+		u8 byte_write;
+		if (get_user(byte_write, buf + *off - init_off)) {
+			if (*off - init_off)
+				return *off - init_off; /* partial write */
+			return -EFAULT;
+		}
 		err = ec_write(*off, byte_write);
 		if (err)
 			return err;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/fan.c linux-libre-3.11-rc7-gnu/drivers/acpi/fan.c
--- linux-libre-3.10-gnu/drivers/acpi/fan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/fan.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,7 +84,7 @@ static int fan_get_cur_state(struct ther
 {
 	struct acpi_device *device = cdev->devdata;
 	int result;
-	int acpi_state;
+	int acpi_state = ACPI_STATE_D0;
 
 	if (!device)
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/glue.c linux-libre-3.11-rc7-gnu/drivers/acpi/glue.c
--- linux-libre-3.10-gnu/drivers/acpi/glue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/glue.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,7 @@ static LIST_HEAD(bus_type_list);
 static DECLARE_RWSEM(bus_type_sem);
 
 #define PHYSICAL_NODE_STRING "physical_node"
+#define PHYSICAL_NODE_NAME_SIZE (sizeof(PHYSICAL_NODE_STRING) + 10)
 
 int register_acpi_bus_type(struct acpi_bus_type *type)
 {
@@ -78,39 +79,108 @@ static struct acpi_bus_type *acpi_get_bu
 	return ret;
 }
 
-static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
-				      void *addr_p, void **ret_p)
+static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used,
+				  void *not_used, void **ret_p)
+{
+	struct acpi_device *adev = NULL;
+
+	acpi_bus_get_device(handle, &adev);
+	if (adev) {
+		*ret_p = handle;
+		return AE_CTRL_TERMINATE;
+	}
+	return AE_OK;
+}
+
+static bool acpi_extra_checks_passed(acpi_handle handle, bool is_bridge)
 {
+	unsigned long long sta;
+	acpi_status status;
+
+	status = acpi_bus_get_status_handle(handle, &sta);
+	if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED))
+		return false;
+
+	if (is_bridge) {
+		void *test = NULL;
+
+		/* Check if this object has at least one child device. */
+		acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+				    acpi_dev_present, NULL, NULL, &test);
+		return !!test;
+	}
+	return true;
+}
+
+struct find_child_context {
+	u64 addr;
+	bool is_bridge;
+	acpi_handle ret;
+	bool ret_checked;
+};
+
+static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
+				 void *data, void **not_used)
+{
+	struct find_child_context *context = data;
 	unsigned long long addr;
 	acpi_status status;
 
 	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
-	if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) {
-		*ret_p = handle;
+	if (ACPI_FAILURE(status) || addr != context->addr)
+		return AE_OK;
+
+	if (!context->ret) {
+		/* This is the first matching object.  Save its handle. */
+		context->ret = handle;
+		return AE_OK;
+	}
+	/*
+	 * There is more than one matching object with the same _ADR value.
+	 * That really is unexpected, so we are kind of beyond the scope of the
+	 * spec here.  We have to choose which one to return, though.
+	 *
+	 * First, check if the previously found object is good enough and return
+	 * its handle if so.  Second, check the same for the object that we've
+	 * just found.
+	 */
+	if (!context->ret_checked) {
+		if (acpi_extra_checks_passed(context->ret, context->is_bridge))
+			return AE_CTRL_TERMINATE;
+		else
+			context->ret_checked = true;
+	}
+	if (acpi_extra_checks_passed(handle, context->is_bridge)) {
+		context->ret = handle;
 		return AE_CTRL_TERMINATE;
 	}
 	return AE_OK;
 }
 
-acpi_handle acpi_get_child(acpi_handle parent, u64 address)
+acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge)
 {
-	void *ret = NULL;
-
-	if (!parent)
-		return NULL;
+	if (parent) {
+		struct find_child_context context = {
+			.addr = addr,
+			.is_bridge = is_bridge,
+		};
 
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, NULL,
-			    do_acpi_find_child, &address, &ret);
-	return (acpi_handle)ret;
+		acpi_walk_namespace(ACPI_TYPE_DEVICE, parent, 1, do_find_child,
+				    NULL, &context, NULL);
+		return context.ret;
+	}
+	return NULL;
 }
-EXPORT_SYMBOL(acpi_get_child);
+EXPORT_SYMBOL_GPL(acpi_find_child);
 
-static int acpi_bind_one(struct device *dev, acpi_handle handle)
+int acpi_bind_one(struct device *dev, acpi_handle handle)
 {
 	struct acpi_device *acpi_dev;
 	acpi_status status;
 	struct acpi_device_physical_node *physical_node, *pn;
-	char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
+	char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
+	struct list_head *physnode_list;
+	unsigned int node_id;
 	int retval = -EINVAL;
 
 	if (ACPI_HANDLE(dev)) {
@@ -137,25 +207,27 @@ static int acpi_bind_one(struct device *
 
 	mutex_lock(&acpi_dev->physical_node_lock);
 
-	/* Sanity check. */
-	list_for_each_entry(pn, &acpi_dev->physical_node_list, node)
+	/*
+	 * Keep the list sorted by node_id so that the IDs of removed nodes can
+	 * be recycled easily.
+	 */
+	physnode_list = &acpi_dev->physical_node_list;
+	node_id = 0;
+	list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
+		/* Sanity check. */
 		if (pn->dev == dev) {
 			dev_warn(dev, "Already associated with ACPI node\n");
 			goto err_free;
 		}
-
-	/* allocate physical node id according to physical_node_id_bitmap */
-	physical_node->node_id =
-		find_first_zero_bit(acpi_dev->physical_node_id_bitmap,
-		ACPI_MAX_PHYSICAL_NODE);
-	if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
-		retval = -ENOSPC;
-		goto err_free;
+		if (pn->node_id == node_id) {
+			physnode_list = &pn->node;
+			node_id++;
+		}
 	}
 
-	set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap);
+	physical_node->node_id = node_id;
 	physical_node->dev = dev;
-	list_add_tail(&physical_node->node, &acpi_dev->physical_node_list);
+	list_add(&physical_node->node, physnode_list);
 	acpi_dev->physical_node_count++;
 
 	mutex_unlock(&acpi_dev->physical_node_lock);
@@ -188,8 +260,9 @@ static int acpi_bind_one(struct device *
 	kfree(physical_node);
 	goto err;
 }
+EXPORT_SYMBOL_GPL(acpi_bind_one);
 
-static int acpi_unbind_one(struct device *dev)
+int acpi_unbind_one(struct device *dev)
 {
 	struct acpi_device_physical_node *entry;
 	struct acpi_device *acpi_dev;
@@ -205,7 +278,7 @@ static int acpi_unbind_one(struct device
 
 	mutex_lock(&acpi_dev->physical_node_lock);
 	list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
-		char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
+		char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
 
 		entry = list_entry(node, struct acpi_device_physical_node,
 			node);
@@ -213,7 +286,6 @@ static int acpi_unbind_one(struct device
 			continue;
 
 		list_del(node);
-		clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap);
 
 		acpi_dev->physical_node_count--;
 
@@ -238,6 +310,7 @@ err:
 	dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
 	return -EINVAL;
 }
+EXPORT_SYMBOL_GPL(acpi_unbind_one);
 
 static int acpi_platform_notify(struct device *dev)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/internal.h linux-libre-3.11-rc7-gnu/drivers/acpi/internal.h
--- linux-libre-3.10-gnu/drivers/acpi/internal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -33,6 +33,7 @@ static inline void acpi_pci_slot_init(vo
 void acpi_pci_root_init(void);
 void acpi_pci_link_init(void);
 void acpi_pci_root_hp_init(void);
+void acpi_processor_init(void);
 void acpi_platform_init(void);
 int acpi_sysfs_init(void);
 #ifdef CONFIG_ACPI_CONTAINER
@@ -50,6 +51,13 @@ void acpi_memory_hotplug_init(void);
 #else
 static inline void acpi_memory_hotplug_init(void) {}
 #endif
+#ifdef CONFIG_X86
+void acpi_cmos_rtc_init(void);
+#else
+static inline void acpi_cmos_rtc_init(void) {}
+#endif
+
+extern bool acpi_force_hot_remove;
 
 void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
 				    const char *name);
@@ -81,6 +89,8 @@ void acpi_init_device_object(struct acpi
 			     int type, unsigned long long sta);
 void acpi_device_add_finalize(struct acpi_device *device);
 void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
+int acpi_bind_one(struct device *dev, acpi_handle handle);
+int acpi_unbind_one(struct device *dev);
 
 /* --------------------------------------------------------------------------
                                   Power Resource
@@ -154,4 +164,13 @@ struct platform_device;
 int acpi_create_platform_device(struct acpi_device *adev,
 				const struct acpi_device_id *id);
 
+/*--------------------------------------------------------------------------
+					Video
+  -------------------------------------------------------------------------- */
+#if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE)
+bool acpi_video_backlight_quirks(void);
+#else
+static inline bool acpi_video_backlight_quirks(void) { return false; }
+#endif
+
 #endif /* _ACPI_INTERNAL_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/Makefile linux-libre-3.11-rc7-gnu/drivers/acpi/Makefile
--- linux-libre-3.10-gnu/drivers/acpi/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -34,6 +34,7 @@ acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 acpi-y				+= bus.o glue.o
 acpi-y				+= scan.o
 acpi-y				+= resource.o
+acpi-y				+= acpi_processor.o
 acpi-y				+= processor_core.o
 acpi-y				+= ec.o
 acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
@@ -43,6 +44,7 @@ acpi-y				+= acpi_platform.o
 acpi-y				+= power.o
 acpi-y				+= event.o
 acpi-y				+= sysfs.o
+acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
 acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
 acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
 acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/osl.c linux-libre-3.11-rc7-gnu/drivers/acpi/osl.c
--- linux-libre-3.10-gnu/drivers/acpi/osl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/osl.c	2013-08-25 20:43:22.000000000 -0400
@@ -835,19 +835,9 @@ void acpi_os_stall(u32 us)
  */
 u64 acpi_os_get_timer(void)
 {
-	static u64 t;
-
-#ifdef	CONFIG_HPET
-	/* TBD: use HPET if available */
-#endif
-
-#ifdef	CONFIG_X86_PM_TIMER
-	/* TBD: default to PM timer if HPET was not available */
-#endif
-	if (!t)
-		printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n");
-
-	return ++t;
+	u64 time_ns = ktime_to_ns(ktime_get());
+	do_div(time_ns, 100);
+	return time_ns;
 }
 
 acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
@@ -1715,6 +1705,17 @@ acpi_status acpi_os_release_object(acpi_
 }
 #endif
 
+static int __init acpi_no_auto_ssdt_setup(char *s)
+{
+        printk(KERN_NOTICE PREFIX "SSDT auto-load disabled\n");
+
+        acpi_gbl_disable_ssdt_table_load = TRUE;
+
+        return 1;
+}
+
+__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
+
 acpi_status __init acpi_os_initialize(void)
 {
 	acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/pci_root.c linux-libre-3.11-rc7-gnu/drivers/acpi/pci_root.c
--- linux-libre-3.10-gnu/drivers/acpi/pci_root.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/pci_root.c	2013-08-25 20:43:22.000000000 -0400
@@ -65,10 +65,6 @@ static struct acpi_scan_handler pci_root
 	.detach = acpi_pci_root_remove,
 };
 
-/* Lock to protect both acpi_pci_roots lists */
-static DEFINE_MUTEX(acpi_pci_root_lock);
-static LIST_HEAD(acpi_pci_roots);
-
 static DEFINE_MUTEX(osc_lock);
 
 /**
@@ -100,13 +96,12 @@ get_root_bridge_busnr_callback(struct ac
 {
 	struct resource *res = data;
 	struct acpi_resource_address64 address;
+	acpi_status status;
 
-	if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
-	    resource->type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
-	    resource->type != ACPI_RESOURCE_TYPE_ADDRESS64)
+	status = acpi_resource_to_address64(resource, &address);
+	if (ACPI_FAILURE(status))
 		return AE_OK;
 
-	acpi_resource_to_address64(resource, &address);
 	if ((address.address_length > 0) &&
 	    (address.resource_type == ACPI_BUS_NUMBER_RANGE)) {
 		res->start = address.minimum;
@@ -382,23 +377,24 @@ static int acpi_pci_root_add(struct acpi
 	int result;
 	struct acpi_pci_root *root;
 	u32 flags, base_flags;
+	acpi_handle handle = device->handle;
 
 	root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
 	if (!root)
 		return -ENOMEM;
 
 	segment = 0;
-	status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
+	status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL,
 				       &segment);
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
+		dev_err(&device->dev,  "can't evaluate _SEG\n");
 		result = -ENODEV;
 		goto end;
 	}
 
 	/* Check _CRS first, then _BBN.  If no _BBN, default to zero. */
 	root->secondary.flags = IORESOURCE_BUS;
-	status = try_get_root_bridge_busnr(device->handle, &root->secondary);
+	status = try_get_root_bridge_busnr(handle, &root->secondary);
 	if (ACPI_FAILURE(status)) {
 		/*
 		 * We need both the start and end of the downstream bus range
@@ -407,33 +403,32 @@ static int acpi_pci_root_add(struct acpi
 		 * can do is assume [_BBN-0xFF] or [0-0xFF].
 		 */
 		root->secondary.end = 0xFF;
-		printk(KERN_WARNING FW_BUG PREFIX
-		       "no secondary bus range in _CRS\n");
-		status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN,
+		dev_warn(&device->dev,
+			 FW_BUG "no secondary bus range in _CRS\n");
+		status = acpi_evaluate_integer(handle, METHOD_NAME__BBN,
 					       NULL, &bus);
 		if (ACPI_SUCCESS(status))
 			root->secondary.start = bus;
 		else if (status == AE_NOT_FOUND)
 			root->secondary.start = 0;
 		else {
-			printk(KERN_ERR PREFIX "can't evaluate _BBN\n");
+			dev_err(&device->dev, "can't evaluate _BBN\n");
 			result = -ENODEV;
 			goto end;
 		}
 	}
 
-	INIT_LIST_HEAD(&root->node);
 	root->device = device;
 	root->segment = segment & 0xFFFF;
 	strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
 	device->driver_data = root;
 
-	printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
+	pr_info(PREFIX "%s [%s] (domain %04x %pR)\n",
 	       acpi_device_name(device), acpi_device_bid(device),
 	       root->segment, &root->secondary);
 
-	root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle);
+	root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle);
 
 	/*
 	 * All supported architectures that use ACPI have support for
@@ -446,10 +441,6 @@ static int acpi_pci_root_add(struct acpi
 	 * TBD: Need PCI interface for enumeration/configuration of roots.
 	 */
 
-	mutex_lock(&acpi_pci_root_lock);
-	list_add_tail(&root->node, &acpi_pci_roots);
-	mutex_unlock(&acpi_pci_root_lock);
-
 	/*
 	 * Scan the Root Bridge
 	 * --------------------
@@ -459,11 +450,11 @@ static int acpi_pci_root_add(struct acpi
 	 */
 	root->bus = pci_acpi_scan_root(root);
 	if (!root->bus) {
-		printk(KERN_ERR PREFIX
-			    "Bus %04x:%02x not present in PCI namespace\n",
-			    root->segment, (unsigned int)root->secondary.start);
+		dev_err(&device->dev,
+			"Bus %04x:%02x not present in PCI namespace\n",
+			root->segment, (unsigned int)root->secondary.start);
 		result = -ENODEV;
-		goto out_del_root;
+		goto end;
 	}
 
 	/* Indicate support for various _OSC capabilities. */
@@ -502,7 +493,7 @@ static int acpi_pci_root_add(struct acpi
 		dev_info(&device->dev,
 			"Requesting ACPI _OSC control (0x%02x)\n", flags);
 
-		status = acpi_pci_osc_control_set(device->handle, &flags,
+		status = acpi_pci_osc_control_set(handle, &flags,
 				       OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
 		if (ACPI_SUCCESS(status)) {
 			dev_info(&device->dev,
@@ -519,8 +510,8 @@ static int acpi_pci_root_add(struct acpi
 				"ACPI _OSC request failed (%s), "
 				"returned control mask: 0x%02x\n",
 				acpi_format_exception(status), flags);
-			pr_info("ACPI _OSC control for PCIe not granted, "
-				"disabling ASPM\n");
+			dev_info(&device->dev,
+				 "ACPI _OSC control for PCIe not granted, disabling ASPM\n");
 			pcie_no_aspm();
 		}
 	} else {
@@ -536,20 +527,14 @@ static int acpi_pci_root_add(struct acpi
 	if (system_state != SYSTEM_BOOTING) {
 		pcibios_resource_survey_bus(root->bus);
 		pci_assign_unassigned_bus_resources(root->bus);
-	}
 
-	/* need to after hot-added ioapic is registered */
-	if (system_state != SYSTEM_BOOTING)
+		/* need to after hot-added ioapic is registered */
 		pci_enable_bridges(root->bus);
+	}
 
 	pci_bus_add_devices(root->bus);
 	return 1;
 
-out_del_root:
-	mutex_lock(&acpi_pci_root_lock);
-	list_del(&root->node);
-	mutex_unlock(&acpi_pci_root_lock);
-
 end:
 	kfree(root);
 	return result;
@@ -566,9 +551,6 @@ static void acpi_pci_root_remove(struct
 
 	pci_remove_root_bus(root->bus);
 
-	mutex_lock(&acpi_pci_root_lock);
-	list_del(&root->node);
-	mutex_unlock(&acpi_pci_root_lock);
 	kfree(root);
 }
 
@@ -588,12 +570,13 @@ static void handle_root_bridge_insertion
 	struct acpi_device *device;
 
 	if (!acpi_bus_get_device(handle, &device)) {
-		printk(KERN_DEBUG "acpi device exists...\n");
+		dev_printk(KERN_DEBUG, &device->dev,
+			   "acpi device already exists; ignoring notify\n");
 		return;
 	}
 
 	if (acpi_bus_scan(handle))
-		printk(KERN_ERR "cannot add bridge to acpi list\n");
+		acpi_handle_err(handle, "cannot add bridge to acpi list\n");
 }
 
 static void handle_root_bridge_removal(struct acpi_device *device)
@@ -622,7 +605,6 @@ static void handle_root_bridge_removal(s
 static void _handle_hotplug_event_root(struct work_struct *work)
 {
 	struct acpi_pci_root *root;
-	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER };
 	struct acpi_hp_work *hp_work;
 	acpi_handle handle;
 	u32 type;
@@ -634,13 +616,12 @@ static void _handle_hotplug_event_root(s
 	acpi_scan_lock_acquire();
 
 	root = acpi_pci_find_root(handle);
-	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
 	switch (type) {
 	case ACPI_NOTIFY_BUS_CHECK:
 		/* bus enumerate */
-		printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
-				 (char *)buffer.pointer);
+		acpi_handle_printk(KERN_DEBUG, handle,
+				   "Bus check notify on %s\n", __func__);
 		if (root)
 			acpiphp_check_host_bridge(handle);
 		else
@@ -650,28 +631,28 @@ static void _handle_hotplug_event_root(s
 
 	case ACPI_NOTIFY_DEVICE_CHECK:
 		/* device check */
-		printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__,
-				 (char *)buffer.pointer);
+		acpi_handle_printk(KERN_DEBUG, handle,
+				   "Device check notify on %s\n", __func__);
 		if (!root)
 			handle_root_bridge_insertion(handle);
 		break;
 
 	case ACPI_NOTIFY_EJECT_REQUEST:
 		/* request device eject */
-		printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__,
-				 (char *)buffer.pointer);
+		acpi_handle_printk(KERN_DEBUG, handle,
+				   "Device eject notify on %s\n", __func__);
 		if (root)
 			handle_root_bridge_removal(root->device);
 		break;
 	default:
-		printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
-				 type, (char *)buffer.pointer);
+		acpi_handle_warn(handle,
+				 "notify_handler: unknown event type 0x%x\n",
+				 type);
 		break;
 	}
 
 	acpi_scan_lock_release();
 	kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
-	kfree(buffer.pointer);
 }
 
 static void handle_hotplug_event_root(acpi_handle handle, u32 type,
@@ -685,9 +666,6 @@ static acpi_status __init
 find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
 	acpi_status status;
-	char objname[64];
-	struct acpi_buffer buffer = { .length = sizeof(objname),
-				      .pointer = objname };
 	int *count = (int *)context;
 
 	if (!acpi_is_root_bridge(handle))
@@ -695,16 +673,15 @@ find_root_bridges(acpi_handle handle, u3
 
 	(*count)++;
 
-	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
-
 	status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
 					handle_hotplug_event_root, NULL);
 	if (ACPI_FAILURE(status))
-		printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n",
-				  objname, (unsigned int)status);
+		acpi_handle_printk(KERN_DEBUG, handle,
+			"notify handler is not installed, exit status: %u\n",
+			 (unsigned int)status);
 	else
-		printk(KERN_DEBUG "acpi root: %s notify handler is installed\n",
-				 objname);
+		acpi_handle_printk(KERN_DEBUG, handle,
+				   "notify handler is installed\n");
 
 	return AE_OK;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/power.c linux-libre-3.11-rc7-gnu/drivers/acpi/power.c
--- linux-libre-3.10-gnu/drivers/acpi/power.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/power.c	2013-08-25 20:43:22.000000000 -0400
@@ -279,7 +279,7 @@ static int acpi_power_on_unlocked(struct
 
 	if (resource->ref_count++) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Power resource [%s] already on",
+				  "Power resource [%s] already on\n",
 				  resource->name));
 	} else {
 		result = __acpi_power_on(resource);
@@ -325,7 +325,7 @@ static int acpi_power_off_unlocked(struc
 
 	if (!resource->ref_count) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Power resource [%s] already off",
+				  "Power resource [%s] already off\n",
 				  resource->name));
 		return 0;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/proc.c linux-libre-3.11-rc7-gnu/drivers/acpi/proc.c
--- linux-libre-3.10-gnu/drivers/acpi/proc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/proc.c	2013-08-25 20:43:22.000000000 -0400
@@ -311,6 +311,8 @@ acpi_system_wakeup_device_seq_show(struc
 			   dev->pnp.bus_id,
 			   (u32) dev->wakeup.sleep_state);
 
+		mutex_lock(&dev->physical_node_lock);
+
 		if (!dev->physical_node_count) {
 			seq_printf(seq, "%c%-8s\n",
 				dev->wakeup.flags.run_wake ? '*' : ' ',
@@ -338,6 +340,8 @@ acpi_system_wakeup_device_seq_show(struc
 				put_device(ldev);
 			}
 		}
+
+		mutex_unlock(&dev->physical_node_lock);
 	}
 	mutex_unlock(&acpi_device_lock);
 	return 0;
@@ -347,12 +351,16 @@ static void physical_device_enable_wakeu
 {
 	struct acpi_device_physical_node *entry;
 
+	mutex_lock(&adev->physical_node_lock);
+
 	list_for_each_entry(entry,
 		&adev->physical_node_list, node)
 		if (entry->dev && device_can_wakeup(entry->dev)) {
 			bool enable = !device_may_wakeup(entry->dev);
 			device_set_wakeup_enable(entry->dev, enable);
 		}
+
+	mutex_unlock(&adev->physical_node_lock);
 }
 
 static ssize_t
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/processor_core.c linux-libre-3.11-rc7-gnu/drivers/acpi/processor_core.c
--- linux-libre-3.10-gnu/drivers/acpi/processor_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/processor_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -253,7 +253,7 @@ static bool __init processor_physically_
 	return true;
 }
 
-static void __cpuinit acpi_set_pdc_bits(u32 *buf)
+static void acpi_set_pdc_bits(u32 *buf)
 {
 	buf[0] = ACPI_PDC_REVISION_ID;
 	buf[1] = 1;
@@ -265,7 +265,7 @@ static void __cpuinit acpi_set_pdc_bits(
 	arch_acpi_set_pdc_bits(buf);
 }
 
-static struct acpi_object_list *__cpuinit acpi_processor_alloc_pdc(void)
+static struct acpi_object_list *acpi_processor_alloc_pdc(void)
 {
 	struct acpi_object_list *obj_list;
 	union acpi_object *obj;
@@ -308,7 +308,7 @@ static struct acpi_object_list *__cpuini
  * _PDC is required for a BIOS-OS handshake for most of the newer
  * ACPI processor features.
  */
-static int __cpuinit
+static int
 acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
 {
 	acpi_status status = AE_OK;
@@ -336,7 +336,7 @@ acpi_processor_eval_pdc(acpi_handle hand
 	return status;
 }
 
-void __cpuinit acpi_processor_set_pdc(acpi_handle handle)
+void acpi_processor_set_pdc(acpi_handle handle)
 {
 	struct acpi_object_list *obj_list;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/processor_driver.c linux-libre-3.11-rc7-gnu/drivers/acpi/processor_driver.c
--- linux-libre-3.10-gnu/drivers/acpi/processor_driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/processor_driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,11 +1,13 @@
 /*
- * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
+ * processor_driver.c - ACPI Processor Driver
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
  *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
  *  			- Added processor hotplug support
+ *  Copyright (C) 2013, Intel Corporation
+ *                      Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
@@ -24,55 +26,26 @@
  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *  TBD:
- *	1. Make # power states dynamic.
- *	2. Support duty_cycle values that span bit 4.
- *	3. Optimize by having scheduler determine business instead of
- *	   having us try to calculate it here.
- *	4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
  */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
 #include <linux/cpufreq.h>
 #include <linux/cpu.h>
-#include <linux/dmi.h>
-#include <linux/moduleparam.h>
 #include <linux/cpuidle.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
-#include <linux/memory_hotplug.h>
 
-#include <asm/io.h>
-#include <asm/cpu.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/smp.h>
-#include <asm/acpi.h>
-
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
 #include <acpi/processor.h>
 
+#include "internal.h"
+
 #define PREFIX "ACPI: "
 
-#define ACPI_PROCESSOR_CLASS		"processor"
-#define ACPI_PROCESSOR_DEVICE_NAME	"Processor"
-#define ACPI_PROCESSOR_FILE_INFO	"info"
-#define ACPI_PROCESSOR_FILE_THROTTLING	"throttling"
-#define ACPI_PROCESSOR_FILE_LIMIT	"limit"
 #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
 #define ACPI_PROCESSOR_NOTIFY_POWER	0x81
 #define ACPI_PROCESSOR_NOTIFY_THROTTLING	0x82
-#define ACPI_PROCESSOR_DEVICE_HID	"ACPI0007"
-
-#define ACPI_PROCESSOR_LIMIT_USER	0
-#define ACPI_PROCESSOR_LIMIT_THERMAL	1
 
 #define _COMPONENT		ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_driver");
@@ -81,12 +54,8 @@ MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION("ACPI Processor Driver");
 MODULE_LICENSE("GPL");
 
-static int acpi_processor_add(struct acpi_device *device);
-static int acpi_processor_remove(struct acpi_device *device);
-static void acpi_processor_notify(struct acpi_device *device, u32 event);
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr);
-static int acpi_processor_handle_eject(struct acpi_processor *pr);
-static int acpi_processor_start(struct acpi_processor *pr);
+static int acpi_processor_start(struct device *dev);
+static int acpi_processor_stop(struct device *dev);
 
 static const struct acpi_device_id processor_device_ids[] = {
 	{ACPI_PROCESSOR_OBJECT_HID, 0},
@@ -95,295 +64,24 @@ static const struct acpi_device_id proce
 };
 MODULE_DEVICE_TABLE(acpi, processor_device_ids);
 
-static struct acpi_driver acpi_processor_driver = {
+static struct device_driver acpi_processor_driver = {
 	.name = "processor",
-	.class = ACPI_PROCESSOR_CLASS,
-	.ids = processor_device_ids,
-	.ops = {
-		.add = acpi_processor_add,
-		.remove = acpi_processor_remove,
-		.notify = acpi_processor_notify,
-		},
+	.bus = &cpu_subsys,
+	.acpi_match_table = processor_device_ids,
+	.probe = acpi_processor_start,
+	.remove = acpi_processor_stop,
 };
 
-#define INSTALL_NOTIFY_HANDLER		1
-#define UNINSTALL_NOTIFY_HANDLER	2
-
-DEFINE_PER_CPU(struct acpi_processor *, processors);
-EXPORT_PER_CPU_SYMBOL(processors);
-
-struct acpi_processor_errata errata __read_mostly;
-
-/* --------------------------------------------------------------------------
-                                Errata Handling
-   -------------------------------------------------------------------------- */
-
-static int acpi_processor_errata_piix4(struct pci_dev *dev)
-{
-	u8 value1 = 0;
-	u8 value2 = 0;
-
-
-	if (!dev)
-		return -EINVAL;
-
-	/*
-	 * Note that 'dev' references the PIIX4 ACPI Controller.
-	 */
-
-	switch (dev->revision) {
-	case 0:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
-		break;
-	case 1:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
-		break;
-	case 2:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
-		break;
-	case 3:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
-		break;
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
-		break;
-	}
-
-	switch (dev->revision) {
-
-	case 0:		/* PIIX4 A-step */
-	case 1:		/* PIIX4 B-step */
-		/*
-		 * See specification changes #13 ("Manual Throttle Duty Cycle")
-		 * and #14 ("Enabling and Disabling Manual Throttle"), plus
-		 * erratum #5 ("STPCLK# Deassertion Time") from the January
-		 * 2002 PIIX4 specification update.  Applies to only older
-		 * PIIX4 models.
-		 */
-		errata.piix4.throttle = 1;
-
-	case 2:		/* PIIX4E */
-	case 3:		/* PIIX4M */
-		/*
-		 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
-		 * Livelock") from the January 2002 PIIX4 specification update.
-		 * Applies to all PIIX4 models.
-		 */
-
-		/*
-		 * BM-IDE
-		 * ------
-		 * Find the PIIX4 IDE Controller and get the Bus Master IDE
-		 * Status register address.  We'll use this later to read
-		 * each IDE controller's DMA status to make sure we catch all
-		 * DMA activity.
-		 */
-		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-				     PCI_DEVICE_ID_INTEL_82371AB,
-				     PCI_ANY_ID, PCI_ANY_ID, NULL);
-		if (dev) {
-			errata.piix4.bmisx = pci_resource_start(dev, 4);
-			pci_dev_put(dev);
-		}
-
-		/*
-		 * Type-F DMA
-		 * ----------
-		 * Find the PIIX4 ISA Controller and read the Motherboard
-		 * DMA controller's status to see if Type-F (Fast) DMA mode
-		 * is enabled (bit 7) on either channel.  Note that we'll
-		 * disable C3 support if this is enabled, as some legacy
-		 * devices won't operate well if fast DMA is disabled.
-		 */
-		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-				     PCI_DEVICE_ID_INTEL_82371AB_0,
-				     PCI_ANY_ID, PCI_ANY_ID, NULL);
-		if (dev) {
-			pci_read_config_byte(dev, 0x76, &value1);
-			pci_read_config_byte(dev, 0x77, &value2);
-			if ((value1 & 0x80) || (value2 & 0x80))
-				errata.piix4.fdma = 1;
-			pci_dev_put(dev);
-		}
-
-		break;
-	}
-
-	if (errata.piix4.bmisx)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Bus master activity detection (BM-IDE) erratum enabled\n"));
-	if (errata.piix4.fdma)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Type-F DMA livelock erratum (C3 disabled)\n"));
-
-	return 0;
-}
-
-static int acpi_processor_errata(struct acpi_processor *pr)
-{
-	int result = 0;
-	struct pci_dev *dev = NULL;
-
-
-	if (!pr)
-		return -EINVAL;
-
-	/*
-	 * PIIX4
-	 */
-	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-			     PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
-			     PCI_ANY_ID, NULL);
-	if (dev) {
-		result = acpi_processor_errata_piix4(dev);
-		pci_dev_put(dev);
-	}
-
-	return result;
-}
-
-/* --------------------------------------------------------------------------
-                                 Driver Interface
-   -------------------------------------------------------------------------- */
-
-static int acpi_processor_get_info(struct acpi_device *device)
+static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
 {
-	acpi_status status = 0;
-	union acpi_object object = { 0 };
-	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
+	struct acpi_device *device = data;
 	struct acpi_processor *pr;
-	int cpu_index, device_declaration = 0;
-	static int cpu0_initialized;
-
-	pr = acpi_driver_data(device);
-	if (!pr)
-		return -EINVAL;
-
-	if (num_online_cpus() > 1)
-		errata.smp = TRUE;
-
-	acpi_processor_errata(pr);
-
-	/*
-	 * Check to see if we have bus mastering arbitration control.  This
-	 * is required for proper C3 usage (to maintain cache coherency).
-	 */
-	if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
-		pr->flags.bm_control = 1;
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Bus mastering arbitration control present\n"));
-	} else
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "No bus mastering arbitration control\n"));
-
-	if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
-		/* Declared with "Processor" statement; match ProcessorID */
-		status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
-		if (ACPI_FAILURE(status)) {
-			dev_err(&device->dev,
-				"Failed to evaluate processor object (0x%x)\n",
-				status);
-			return -ENODEV;
-		}
-
-		/*
-		 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
-		 *      >>> 'acpi_get_processor_id(acpi_id, &id)' in
-		 *      arch/xxx/acpi.c
-		 */
-		pr->acpi_id = object.processor.proc_id;
-	} else {
-		/*
-		 * Declared with "Device" statement; match _UID.
-		 * Note that we don't handle string _UIDs yet.
-		 */
-		unsigned long long value;
-		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
-						NULL, &value);
-		if (ACPI_FAILURE(status)) {
-			dev_err(&device->dev,
-				"Failed to evaluate processor _UID (0x%x)\n",
-				status);
-			return -ENODEV;
-		}
-		device_declaration = 1;
-		pr->acpi_id = value;
-	}
-	cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id);
-
-	/* Handle UP system running SMP kernel, with no LAPIC in MADT */
-	if (!cpu0_initialized && (cpu_index == -1) &&
-	    (num_online_cpus() == 1)) {
-		cpu_index = 0;
-	}
-
-	cpu0_initialized = 1;
-
-	pr->id = cpu_index;
-
-	/*
-	 *  Extra Processor objects may be enumerated on MP systems with
-	 *  less than the max # of CPUs. They should be ignored _iff
-	 *  they are physically not present.
-	 */
-	if (pr->id == -1) {
-		if (ACPI_FAILURE(acpi_processor_hotadd_init(pr)))
-			return -ENODEV;
-	}
-	/*
-	 * On some boxes several processors use the same processor bus id.
-	 * But they are located in different scope. For example:
-	 * \_SB.SCK0.CPU0
-	 * \_SB.SCK1.CPU0
-	 * Rename the processor device bus id. And the new bus id will be
-	 * generated as the following format:
-	 * CPU+CPU ID.
-	 */
-	sprintf(acpi_device_bid(device), "CPU%X", pr->id);
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
-			  pr->acpi_id));
-
-	if (!object.processor.pblk_address)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
-	else if (object.processor.pblk_length != 6)
-		dev_err(&device->dev, "Invalid PBLK length [%d]\n",
-			    object.processor.pblk_length);
-	else {
-		pr->throttling.address = object.processor.pblk_address;
-		pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
-		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
-
-		pr->pblk = object.processor.pblk_address;
-
-		/*
-		 * We don't care about error returns - we just try to mark
-		 * these reserved so that nobody else is confused into thinking
-		 * that this region might be unused..
-		 *
-		 * (In particular, allocating the IO range for Cardbus)
-		 */
-		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
-	}
-
-	/*
-	 * If ACPI describes a slot number for this CPU, we can use it
-	 * ensure we get the right value in the "physical id" field
-	 * of /proc/cpuinfo
-	 */
-	status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
-	if (ACPI_SUCCESS(status))
-		arch_fix_phys_package_id(pr->id, object.integer.value);
-
-	return 0;
-}
-
-static DEFINE_PER_CPU(void *, processor_device_array);
-
-static void acpi_processor_notify(struct acpi_device *device, u32 event)
-{
-	struct acpi_processor *pr = acpi_driver_data(device);
 	int saved;
 
+	if (device->handle != handle)
+		return;
+
+	pr = acpi_driver_data(device);
 	if (!pr)
 		return;
 
@@ -420,55 +118,62 @@ static void acpi_processor_notify(struct
 	return;
 }
 
+static int __acpi_processor_start(struct acpi_device *device);
+
 static int acpi_cpu_soft_notify(struct notifier_block *nfb,
-		unsigned long action, void *hcpu)
+					  unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
 	struct acpi_processor *pr = per_cpu(processors, cpu);
+	struct acpi_device *device;
 
-	if (action == CPU_ONLINE && pr) {
-		/* CPU got physically hotplugged and onlined the first time:
-		 * Initialize missing things
+	if (!pr || acpi_bus_get_device(pr->handle, &device))
+		return NOTIFY_DONE;
+
+	if (action == CPU_ONLINE) {
+		/*
+		 * CPU got physically hotplugged and onlined for the first time:
+		 * Initialize missing things.
 		 */
 		if (pr->flags.need_hotplug_init) {
+			int ret;
+
 			pr_info("Will online and init hotplugged CPU: %d\n",
 				pr->id);
-			WARN(acpi_processor_start(pr), "Failed to start CPU:"
-				" %d\n", pr->id);
 			pr->flags.need_hotplug_init = 0;
-		/* Normal CPU soft online event */
+			ret = __acpi_processor_start(device);
+			WARN(ret, "Failed to start CPU: %d\n", pr->id);
 		} else {
+			/* Normal CPU soft online event. */
 			acpi_processor_ppc_has_changed(pr, 0);
 			acpi_processor_hotplug(pr);
 			acpi_processor_reevaluate_tstate(pr, action);
 			acpi_processor_tstate_has_changed(pr);
 		}
-	}
-	if (action == CPU_DEAD && pr) {
-		/* invalidate the flag.throttling after one CPU is offline */
+	} else if (action == CPU_DEAD) {
+		/* Invalidate flag.throttling after the CPU is offline. */
 		acpi_processor_reevaluate_tstate(pr, action);
 	}
 	return NOTIFY_OK;
 }
 
-static struct notifier_block acpi_cpu_notifier =
+static struct notifier_block __refdata acpi_cpu_notifier =
 {
 	    .notifier_call = acpi_cpu_soft_notify,
 };
 
-/*
- * acpi_processor_start() is called by the cpu_hotplug_notifier func:
- * acpi_cpu_soft_notify(). Getting it __cpuinit{data} is difficult, the
- * root cause seem to be that acpi_processor_uninstall_hotplug_notify()
- * is in the module_exit (__exit) func. Allowing acpi_processor_start()
- * to not be in __cpuinit section, but being called from __cpuinit funcs
- * via __ref looks like the right thing to do here.
- */
-static __ref int acpi_processor_start(struct acpi_processor *pr)
+static int __acpi_processor_start(struct acpi_device *device)
 {
-	struct acpi_device *device = per_cpu(processor_device_array, pr->id);
+	struct acpi_processor *pr = acpi_driver_data(device);
+	acpi_status status;
 	int result = 0;
 
+	if (!pr)
+		return -ENODEV;
+
+	if (pr->flags.need_hotplug_init)
+		return 0;
+
 #ifdef CONFIG_CPU_FREQ
 	acpi_processor_ppc_has_changed(pr, 0);
 	acpi_processor_load_module(pr);
@@ -506,462 +211,95 @@ static __ref int acpi_processor_start(st
 		goto err_remove_sysfs_thermal;
 	}
 
-	return 0;
+	status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+					     acpi_processor_notify, device);
+	if (ACPI_SUCCESS(status))
+		return 0;
 
-err_remove_sysfs_thermal:
+	sysfs_remove_link(&pr->cdev->device.kobj, "device");
+ err_remove_sysfs_thermal:
 	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
-err_thermal_unregister:
+ err_thermal_unregister:
 	thermal_cooling_device_unregister(pr->cdev);
-err_power_exit:
+ err_power_exit:
 	acpi_processor_power_exit(pr);
-
 	return result;
 }
 
-/*
- * Do not put anything in here which needs the core to be online.
- * For example MSR access or setting up things which check for cpuinfo_x86
- * (cpu_data(cpu)) values, like CPU feature flags, family, model, etc.
- * Such things have to be put in and set up above in acpi_processor_start()
- */
-static int __cpuinit acpi_processor_add(struct acpi_device *device)
+static int acpi_processor_start(struct device *dev)
 {
-	struct acpi_processor *pr = NULL;
-	int result = 0;
-	struct device *dev;
-
-	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
-	if (!pr)
-		return -ENOMEM;
-
-	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
-		result = -ENOMEM;
-		goto err_free_pr;
-	}
-
-	pr->handle = device->handle;
-	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
-	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
-	device->driver_data = pr;
-
-	result = acpi_processor_get_info(device);
-	if (result) {
-		/* Processor is physically not present */
-		return 0;
-	}
-
-#ifdef CONFIG_SMP
-	if (pr->id >= setup_max_cpus && pr->id != 0)
-		return 0;
-#endif
-
-	BUG_ON(pr->id >= nr_cpu_ids);
-
-	/*
-	 * Buggy BIOS check
-	 * ACPI id of processors can be reported wrongly by the BIOS.
-	 * Don't trust it blindly
-	 */
-	if (per_cpu(processor_device_array, pr->id) != NULL &&
-	    per_cpu(processor_device_array, pr->id) != device) {
-		dev_warn(&device->dev,
-			"BIOS reported wrong ACPI id %d for the processor\n",
-			pr->id);
-		result = -ENODEV;
-		goto err_free_cpumask;
-	}
-	per_cpu(processor_device_array, pr->id) = device;
-
-	per_cpu(processors, pr->id) = pr;
-
-	dev = get_cpu_device(pr->id);
-	if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) {
-		result = -EFAULT;
-		goto err_clear_processor;
-	}
-
-	/*
-	 * Do not start hotplugged CPUs now, but when they
-	 * are onlined the first time
-	 */
-	if (pr->flags.need_hotplug_init)
-		return 0;
-
-	result = acpi_processor_start(pr);
-	if (result)
-		goto err_remove_sysfs;
+	struct acpi_device *device;
 
-	return 0;
+	if (acpi_bus_get_device(ACPI_HANDLE(dev), &device))
+		return -ENODEV;
 
-err_remove_sysfs:
-	sysfs_remove_link(&device->dev.kobj, "sysdev");
-err_clear_processor:
-	/*
-	 * processor_device_array is not cleared to allow checks for buggy BIOS
-	 */ 
-	per_cpu(processors, pr->id) = NULL;
-err_free_cpumask:
-	free_cpumask_var(pr->throttling.shared_cpu_map);
-err_free_pr:
-	kfree(pr);
-	return result;
+	return __acpi_processor_start(device);
 }
 
-static int acpi_processor_remove(struct acpi_device *device)
+static int acpi_processor_stop(struct device *dev)
 {
-	struct acpi_processor *pr = NULL;
+	struct acpi_device *device;
+	struct acpi_processor *pr;
 
+	if (acpi_bus_get_device(ACPI_HANDLE(dev), &device))
+		return 0;
 
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
+	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+				   acpi_processor_notify);
 
 	pr = acpi_driver_data(device);
-
-	if (pr->id >= nr_cpu_ids)
-		goto free;
-
-	if (device->removal_type == ACPI_BUS_REMOVAL_EJECT) {
-		if (acpi_processor_handle_eject(pr))
-			return -EINVAL;
-	}
+	if (!pr)
+		return 0;
 
 	acpi_processor_power_exit(pr);
 
-	sysfs_remove_link(&device->dev.kobj, "sysdev");
-
 	if (pr->cdev) {
 		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
 		sysfs_remove_link(&pr->cdev->device.kobj, "device");
 		thermal_cooling_device_unregister(pr->cdev);
 		pr->cdev = NULL;
 	}
-
-	per_cpu(processors, pr->id) = NULL;
-	per_cpu(processor_device_array, pr->id) = NULL;
-	try_offline_node(cpu_to_node(pr->id));
-
-free:
-	free_cpumask_var(pr->throttling.shared_cpu_map);
-	kfree(pr);
-
 	return 0;
 }
 
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-/****************************************************************************
- * 	Acpi processor hotplug support 				       	    *
- ****************************************************************************/
-
-static int is_processor_present(acpi_handle handle)
-{
-	acpi_status status;
-	unsigned long long sta = 0;
-
-
-	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-
-	if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
-		return 1;
-
-	/*
-	 * _STA is mandatory for a processor that supports hot plug
-	 */
-	if (status == AE_NOT_FOUND)
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				"Processor does not support hot plug\n"));
-	else
-		ACPI_EXCEPTION((AE_INFO, status,
-				"Processor Device is not present"));
-	return 0;
-}
-
-static void acpi_processor_hotplug_notify(acpi_handle handle,
-					  u32 event, void *data)
-{
-	struct acpi_device *device = NULL;
-	struct acpi_eject_event *ej_event = NULL;
-	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
-	acpi_status status;
-	int result;
-
-	acpi_scan_lock_acquire();
-
-	switch (event) {
-	case ACPI_NOTIFY_BUS_CHECK:
-	case ACPI_NOTIFY_DEVICE_CHECK:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-		"Processor driver received %s event\n",
-		       (event == ACPI_NOTIFY_BUS_CHECK) ?
-		       "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
-
-		if (!is_processor_present(handle))
-			break;
-
-		if (!acpi_bus_get_device(handle, &device))
-			break;
-
-		result = acpi_bus_scan(handle);
-		if (result) {
-			acpi_handle_err(handle, "Unable to add the device\n");
-			break;
-		}
-		result = acpi_bus_get_device(handle, &device);
-		if (result) {
-			acpi_handle_err(handle, "Missing device object\n");
-			break;
-		}
-		ost_code = ACPI_OST_SC_SUCCESS;
-		break;
-
-	case ACPI_NOTIFY_EJECT_REQUEST:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "received ACPI_NOTIFY_EJECT_REQUEST\n"));
-
-		if (acpi_bus_get_device(handle, &device)) {
-			acpi_handle_err(handle,
-				"Device don't exist, dropping EJECT\n");
-			break;
-		}
-		if (!acpi_driver_data(device)) {
-			acpi_handle_err(handle,
-				"Driver data is NULL, dropping EJECT\n");
-			break;
-		}
-
-		ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
-		if (!ej_event) {
-			acpi_handle_err(handle, "No memory, dropping EJECT\n");
-			break;
-		}
-
-		get_device(&device->dev);
-		ej_event->device = device;
-		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
-		/* The eject is carried out asynchronously. */
-		status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
-						 ej_event);
-		if (ACPI_FAILURE(status)) {
-			put_device(&device->dev);
-			kfree(ej_event);
-			break;
-		}
-		goto out;
-
-	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Unsupported event [0x%x]\n", event));
-
-		/* non-hotplug event; possibly handled by other handler */
-		goto out;
-	}
-
-	/* Inform firmware that the hotplug operation has completed */
-	(void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
-
- out:
-	acpi_scan_lock_release();
-}
-
-static acpi_status is_processor_device(acpi_handle handle)
-{
-	struct acpi_device_info *info;
-	char *hid;
-	acpi_status status;
-
-	status = acpi_get_object_info(handle, &info);
-	if (ACPI_FAILURE(status))
-		return status;
-
-	if (info->type == ACPI_TYPE_PROCESSOR) {
-		kfree(info);
-		return AE_OK;	/* found a processor object */
-	}
-
-	if (!(info->valid & ACPI_VALID_HID)) {
-		kfree(info);
-		return AE_ERROR;
-	}
-
-	hid = info->hardware_id.string;
-	if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) {
-		kfree(info);
-		return AE_ERROR;
-	}
-
-	kfree(info);
-	return AE_OK;	/* found a processor device object */
-}
-
-static acpi_status
-processor_walk_namespace_cb(acpi_handle handle,
-			    u32 lvl, void *context, void **rv)
-{
-	acpi_status status;
-	int *action = context;
-
-	status = is_processor_device(handle);
-	if (ACPI_FAILURE(status))
-		return AE_OK;	/* not a processor; continue to walk */
-
-	switch (*action) {
-	case INSTALL_NOTIFY_HANDLER:
-		acpi_install_notify_handler(handle,
-					    ACPI_SYSTEM_NOTIFY,
-					    acpi_processor_hotplug_notify,
-					    NULL);
-		break;
-	case UNINSTALL_NOTIFY_HANDLER:
-		acpi_remove_notify_handler(handle,
-					   ACPI_SYSTEM_NOTIFY,
-					   acpi_processor_hotplug_notify);
-		break;
-	default:
-		break;
-	}
-
-	/* found a processor; skip walking underneath */
-	return AE_CTRL_DEPTH;
-}
-
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
-{
-	acpi_handle handle = pr->handle;
-
-	if (!is_processor_present(handle)) {
-		return AE_ERROR;
-	}
-
-	if (acpi_map_lsapic(handle, &pr->id))
-		return AE_ERROR;
-
-	if (arch_register_cpu(pr->id)) {
-		acpi_unmap_lsapic(pr->id);
-		return AE_ERROR;
-	}
-
-	/* CPU got hot-plugged, but cpu_data is not initialized yet
-	 * Set flag to delay cpu_idle/throttling initialization
-	 * in:
-	 * acpi_processor_add()
-	 *   acpi_processor_get_info()
-	 * and do it when the CPU gets online the first time
-	 * TBD: Cleanup above functions and try to do this more elegant.
-	 */
-	pr_info("CPU %d got hotplugged\n", pr->id);
-	pr->flags.need_hotplug_init = 1;
-
-	return AE_OK;
-}
-
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
-{
-	if (cpu_online(pr->id))
-		cpu_down(pr->id);
-
-	get_online_cpus();
-	/*
-	 * The cpu might become online again at this point. So we check whether
-	 * the cpu has been onlined or not. If the cpu became online, it means
-	 * that someone wants to use the cpu. So acpi_processor_handle_eject()
-	 * returns -EAGAIN.
-	 */
-	if (unlikely(cpu_online(pr->id))) {
-		put_online_cpus();
-		pr_warn("Failed to remove CPU %d, because other task "
-			"brought the CPU back online\n", pr->id);
-		return -EAGAIN;
-	}
-	arch_unregister_cpu(pr->id);
-	acpi_unmap_lsapic(pr->id);
-	put_online_cpus();
-	return (0);
-}
-#else
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
-{
-	return AE_ERROR;
-}
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
-{
-	return (-EINVAL);
-}
-#endif
-
-static
-void acpi_processor_install_hotplug_notify(void)
-{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-	int action = INSTALL_NOTIFY_HANDLER;
-	acpi_walk_namespace(ACPI_TYPE_ANY,
-			    ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX,
-			    processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
-	register_hotcpu_notifier(&acpi_cpu_notifier);
-}
-
-static
-void acpi_processor_uninstall_hotplug_notify(void)
-{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-	int action = UNINSTALL_NOTIFY_HANDLER;
-	acpi_walk_namespace(ACPI_TYPE_ANY,
-			    ACPI_ROOT_OBJECT,
-			    ACPI_UINT32_MAX,
-			    processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
-	unregister_hotcpu_notifier(&acpi_cpu_notifier);
-}
-
 /*
  * We keep the driver loaded even when ACPI is not running.
  * This is needed for the powernow-k8 driver, that works even without
  * ACPI, but needs symbols from this driver
  */
 
-static int __init acpi_processor_init(void)
+static int __init acpi_processor_driver_init(void)
 {
 	int result = 0;
 
 	if (acpi_disabled)
 		return 0;
 
-	result = acpi_bus_register_driver(&acpi_processor_driver);
+	result = driver_register(&acpi_processor_driver);
 	if (result < 0)
 		return result;
 
 	acpi_processor_syscore_init();
-
-	acpi_processor_install_hotplug_notify();
-
+	register_hotcpu_notifier(&acpi_cpu_notifier);
 	acpi_thermal_cpufreq_init();
-
 	acpi_processor_ppc_init();
-
 	acpi_processor_throttling_init();
-
 	return 0;
 }
 
-static void __exit acpi_processor_exit(void)
+static void __exit acpi_processor_driver_exit(void)
 {
 	if (acpi_disabled)
 		return;
 
 	acpi_processor_ppc_exit();
-
 	acpi_thermal_cpufreq_exit();
-
-	acpi_processor_uninstall_hotplug_notify();
-
+	unregister_hotcpu_notifier(&acpi_cpu_notifier);
 	acpi_processor_syscore_exit();
-
-	acpi_bus_unregister_driver(&acpi_processor_driver);
-
-	return;
+	driver_unregister(&acpi_processor_driver);
 }
 
-module_init(acpi_processor_init);
-module_exit(acpi_processor_exit);
+module_init(acpi_processor_driver_init);
+module_exit(acpi_processor_driver_exit);
 
 MODULE_ALIAS("processor");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/processor_idle.c linux-libre-3.11-rc7-gnu/drivers/acpi/processor_idle.c
--- linux-libre-3.10-gnu/drivers/acpi/processor_idle.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/processor_idle.c	2013-08-25 20:43:22.000000000 -0400
@@ -96,9 +96,7 @@ static int set_max_cstate(const struct d
 	return 0;
 }
 
-/* Actually this shouldn't be __cpuinitdata, would be better to fix the
-   callers to only run once -AK */
-static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
+static struct dmi_system_id processor_power_dmi_table[] = {
 	{ set_max_cstate, "Clevo 5600D", {
 	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
 	  DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
@@ -214,13 +212,13 @@ static void lapic_timer_state_broadcast(
 #ifdef CONFIG_PM_SLEEP
 static u32 saved_bm_rld;
 
-int acpi_processor_suspend(void)
+static int acpi_processor_suspend(void)
 {
 	acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
 	return 0;
 }
 
-void acpi_processor_resume(void)
+static void acpi_processor_resume(void)
 {
 	u32 resumed_bm_rld;
 
@@ -1165,7 +1163,7 @@ int acpi_processor_cst_has_changed(struc
 
 static int acpi_processor_registered;
 
-int __cpuinit acpi_processor_power_init(struct acpi_processor *pr)
+int acpi_processor_power_init(struct acpi_processor *pr)
 {
 	acpi_status status = 0;
 	int retval;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/processor_perflib.c linux-libre-3.11-rc7-gnu/drivers/acpi/processor_perflib.c
--- linux-libre-3.10-gnu/drivers/acpi/processor_perflib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/processor_perflib.c	2013-08-25 20:43:22.000000000 -0400
@@ -639,7 +639,7 @@ end:
 int acpi_processor_preregister_performance(
 		struct acpi_processor_performance __percpu *performance)
 {
-	int count, count_target;
+	int count_target;
 	int retval = 0;
 	unsigned int i, j;
 	cpumask_var_t covered_cpus;
@@ -711,7 +711,6 @@ int acpi_processor_preregister_performan
 
 		/* Validate the Domain info */
 		count_target = pdomain->num_processors;
-		count = 1;
 		if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
 			pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL;
 		else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
@@ -745,7 +744,6 @@ int acpi_processor_preregister_performan
 
 			cpumask_set_cpu(j, covered_cpus);
 			cpumask_set_cpu(j, pr->performance->shared_cpu_map);
-			count++;
 		}
 
 		for_each_possible_cpu(j) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/scan.c linux-libre-3.11-rc7-gnu/drivers/acpi/scan.c
--- linux-libre-3.10-gnu/drivers/acpi/scan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/scan.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,9 +27,14 @@ extern struct acpi_device *acpi_root;
 
 #define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
 
+/*
+ * If set, devices will be hot-removed even if they cannot be put offline
+ * gracefully (from the kernel's standpoint).
+ */
+bool acpi_force_hot_remove;
+
 static const char *dummy_hid = "device";
 
-static LIST_HEAD(acpi_device_list);
 static LIST_HEAD(acpi_bus_id_list);
 static DEFINE_MUTEX(acpi_scan_lock);
 static LIST_HEAD(acpi_scan_handlers_list);
@@ -120,12 +125,78 @@ acpi_device_modalias_show(struct device
 }
 static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
 
+static acpi_status acpi_bus_offline_companions(acpi_handle handle, u32 lvl,
+					       void *data, void **ret_p)
+{
+	struct acpi_device *device = NULL;
+	struct acpi_device_physical_node *pn;
+	bool second_pass = (bool)data;
+	acpi_status status = AE_OK;
+
+	if (acpi_bus_get_device(handle, &device))
+		return AE_OK;
+
+	mutex_lock(&device->physical_node_lock);
+
+	list_for_each_entry(pn, &device->physical_node_list, node) {
+		int ret;
+
+		if (second_pass) {
+			/* Skip devices offlined by the first pass. */
+			if (pn->put_online)
+				continue;
+		} else {
+			pn->put_online = false;
+		}
+		ret = device_offline(pn->dev);
+		if (acpi_force_hot_remove)
+			continue;
+
+		if (ret >= 0) {
+			pn->put_online = !ret;
+		} else {
+			*ret_p = pn->dev;
+			if (second_pass) {
+				status = AE_ERROR;
+				break;
+			}
+		}
+	}
+
+	mutex_unlock(&device->physical_node_lock);
+
+	return status;
+}
+
+static acpi_status acpi_bus_online_companions(acpi_handle handle, u32 lvl,
+					      void *data, void **ret_p)
+{
+	struct acpi_device *device = NULL;
+	struct acpi_device_physical_node *pn;
+
+	if (acpi_bus_get_device(handle, &device))
+		return AE_OK;
+
+	mutex_lock(&device->physical_node_lock);
+
+	list_for_each_entry(pn, &device->physical_node_list, node)
+		if (pn->put_online) {
+			device_online(pn->dev);
+			pn->put_online = false;
+		}
+
+	mutex_unlock(&device->physical_node_lock);
+
+	return AE_OK;
+}
+
 static int acpi_scan_hot_remove(struct acpi_device *device)
 {
 	acpi_handle handle = device->handle;
 	acpi_handle not_used;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
+	struct device *errdev;
 	acpi_status status;
 	unsigned long long sta;
 
@@ -136,10 +207,53 @@ static int acpi_scan_hot_remove(struct a
 		return -EINVAL;
 	}
 
+	lock_device_hotplug();
+
+	/*
+	 * Carry out two passes here and ignore errors in the first pass,
+	 * because if the devices in question are memory blocks and
+	 * CONFIG_MEMCG is set, one of the blocks may hold data structures
+	 * that the other blocks depend on, but it is not known in advance which
+	 * block holds them.
+	 *
+	 * If the first pass is successful, the second one isn't needed, though.
+	 */
+	errdev = NULL;
+	acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+			    NULL, acpi_bus_offline_companions,
+			    (void *)false, (void **)&errdev);
+	acpi_bus_offline_companions(handle, 0, (void *)false, (void **)&errdev);
+	if (errdev) {
+		errdev = NULL;
+		acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+				    NULL, acpi_bus_offline_companions,
+				    (void *)true , (void **)&errdev);
+		if (!errdev || acpi_force_hot_remove)
+			acpi_bus_offline_companions(handle, 0, (void *)true,
+						    (void **)&errdev);
+
+		if (errdev && !acpi_force_hot_remove) {
+			dev_warn(errdev, "Offline failed.\n");
+			acpi_bus_online_companions(handle, 0, NULL, NULL);
+			acpi_walk_namespace(ACPI_TYPE_ANY, handle,
+					    ACPI_UINT32_MAX,
+					    acpi_bus_online_companions, NULL,
+					    NULL, NULL);
+
+			unlock_device_hotplug();
+
+			put_device(&device->dev);
+			return -EBUSY;
+		}
+	}
+
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 		"Hot-removing device %s...\n", dev_name(&device->dev)));
 
 	acpi_bus_trim(device);
+
+	unlock_device_hotplug();
+
 	/* Device node has been unregistered. */
 	put_device(&device->dev);
 	device = NULL;
@@ -236,11 +350,14 @@ static void acpi_scan_bus_device_check(a
 	int error;
 
 	mutex_lock(&acpi_scan_lock);
+	lock_device_hotplug();
 
-	acpi_bus_get_device(handle, &device);
-	if (device) {
-		dev_warn(&device->dev, "Attempt to re-insert\n");
-		goto out;
+	if (ost_source != ACPI_NOTIFY_BUS_CHECK) {
+		acpi_bus_get_device(handle, &device);
+		if (device) {
+			dev_warn(&device->dev, "Attempt to re-insert\n");
+			goto out;
+		}
 	}
 	acpi_evaluate_hotplug_ost(handle, ost_source,
 				  ACPI_OST_SC_INSERT_IN_PROGRESS, NULL);
@@ -259,6 +376,7 @@ static void acpi_scan_bus_device_check(a
 		kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
 
  out:
+	unlock_device_hotplug();
 	acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL);
 	mutex_unlock(&acpi_scan_lock);
 }
@@ -816,32 +934,43 @@ static void acpi_device_remove_notify_ha
 					   acpi_device_notify);
 }
 
-static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
-static int acpi_device_probe(struct device * dev)
+static int acpi_device_probe(struct device *dev)
 {
 	struct acpi_device *acpi_dev = to_acpi_device(dev);
 	struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
 	int ret;
 
-	ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
-	if (!ret) {
-		if (acpi_drv->ops.notify) {
-			ret = acpi_device_install_notify_handler(acpi_dev);
-			if (ret) {
-				if (acpi_drv->ops.remove)
-					acpi_drv->ops.remove(acpi_dev);
-				acpi_dev->driver = NULL;
-				acpi_dev->driver_data = NULL;
-				return ret;
-			}
-		}
+	if (acpi_dev->handler)
+		return -EINVAL;
 
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			"Found driver [%s] for device [%s]\n",
-			acpi_drv->name, acpi_dev->pnp.bus_id));
-		get_device(dev);
+	if (!acpi_drv->ops.add)
+		return -ENOSYS;
+
+	ret = acpi_drv->ops.add(acpi_dev);
+	if (ret)
+		return ret;
+
+	acpi_dev->driver = acpi_drv;
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			  "Driver [%s] successfully bound to device [%s]\n",
+			  acpi_drv->name, acpi_dev->pnp.bus_id));
+
+	if (acpi_drv->ops.notify) {
+		ret = acpi_device_install_notify_handler(acpi_dev);
+		if (ret) {
+			if (acpi_drv->ops.remove)
+				acpi_drv->ops.remove(acpi_dev);
+
+			acpi_dev->driver = NULL;
+			acpi_dev->driver_data = NULL;
+			return ret;
+		}
 	}
-	return ret;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
+			  acpi_drv->name, acpi_dev->pnp.bus_id));
+	get_device(dev);
+	return 0;
 }
 
 static int acpi_device_remove(struct device * dev)
@@ -952,7 +1081,6 @@ int acpi_device_add(struct acpi_device *
 		printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n",
 		       dev_name(&device->dev));
 
-	device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
 	return 0;
 
  err:
@@ -998,41 +1126,6 @@ static void acpi_device_unregister(struc
                                  Driver Management
    -------------------------------------------------------------------------- */
 /**
- * acpi_bus_driver_init - add a device to a driver
- * @device: the device to add and initialize
- * @driver: driver for the device
- *
- * Used to initialize a device via its device driver.  Called whenever a
- * driver is bound to a device.  Invokes the driver's add() ops.
- */
-static int
-acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
-{
-	int result = 0;
-
-	if (!device || !driver)
-		return -EINVAL;
-
-	if (!driver->ops.add)
-		return -ENOSYS;
-
-	result = driver->ops.add(device);
-	if (result)
-		return result;
-
-	device->driver = driver;
-
-	/*
-	 * TBD - Configuration Management: Assign resources to device based
-	 * upon possible configuration and currently allocated resources.
-	 */
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "Driver successfully bound to device\n"));
-	return 0;
-}
-
-/**
  * acpi_bus_register_driver - register a driver with the ACPI bus
  * @driver: driver being registered
  *
@@ -1890,6 +1983,9 @@ static acpi_status acpi_bus_device_attac
 	if (acpi_bus_get_device(handle, &device))
 		return AE_CTRL_DEPTH;
 
+	if (device->handler)
+		return AE_OK;
+
 	ret = acpi_scan_attach_handler(device);
 	if (ret)
 		return ret > 0 ? AE_OK : AE_CTRL_DEPTH;
@@ -1939,7 +2035,6 @@ static acpi_status acpi_bus_device_detac
 	if (!acpi_bus_get_device(handle, &device)) {
 		struct acpi_scan_handler *dev_handler = device->handler;
 
-		device->removal_type = ACPI_BUS_REMOVAL_EJECT;
 		if (dev_handler) {
 			if (dev_handler->detach)
 				dev_handler->detach(device);
@@ -2038,8 +2133,10 @@ int __init acpi_scan_init(void)
 
 	acpi_pci_root_init();
 	acpi_pci_link_init();
+	acpi_processor_init();
 	acpi_platform_init();
 	acpi_lpss_init();
+	acpi_cmos_rtc_init();
 	acpi_container_init();
 	acpi_memory_hotplug_init();
 	acpi_dock_init();
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/sleep.c linux-libre-3.11-rc7-gnu/drivers/acpi/sleep.c
--- linux-libre-3.10-gnu/drivers/acpi/sleep.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/sleep.c	2013-08-25 20:43:22.000000000 -0400
@@ -494,6 +494,8 @@ static int acpi_suspend_enter(suspend_st
 		break;
 
 	case ACPI_STATE_S3:
+		if (!acpi_suspend_lowlevel)
+			return -ENOSYS;
 		error = acpi_suspend_lowlevel();
 		if (error)
 			return error;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/sysfs.c linux-libre-3.11-rc7-gnu/drivers/acpi/sysfs.c
--- linux-libre-3.10-gnu/drivers/acpi/sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -677,10 +677,9 @@ void acpi_irq_stats_init(void)
 		else
 			sprintf(buffer, "bug%02X", i);
 
-		name = kzalloc(strlen(buffer) + 1, GFP_KERNEL);
+		name = kstrdup(buffer, GFP_KERNEL);
 		if (name == NULL)
 			goto fail;
-		strncpy(name, buffer, strlen(buffer) + 1);
 
 		sysfs_attr_init(&counter_attrs[i].attr);
 		counter_attrs[i].attr.name = name;
@@ -780,6 +779,33 @@ void acpi_sysfs_add_hotplug_profile(stru
 	pr_err(PREFIX "Unable to add hotplug profile '%s'\n", name);
 }
 
+static ssize_t force_remove_show(struct kobject *kobj,
+				 struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", !!acpi_force_hot_remove);
+}
+
+static ssize_t force_remove_store(struct kobject *kobj,
+				  struct kobj_attribute *attr,
+				  const char *buf, size_t size)
+{
+	bool val;
+	int ret;
+
+	ret = strtobool(buf, &val);
+	if (ret < 0)
+		return ret;
+
+	lock_device_hotplug();
+	acpi_force_hot_remove = val;
+	unlock_device_hotplug();
+	return size;
+}
+
+static const struct kobj_attribute force_remove_attr =
+	__ATTR(force_remove, S_IRUGO | S_IWUSR, force_remove_show,
+	       force_remove_store);
+
 int __init acpi_sysfs_init(void)
 {
 	int result;
@@ -789,6 +815,10 @@ int __init acpi_sysfs_init(void)
 		return result;
 
 	hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj);
+	result = sysfs_create_file(hotplug_kobj, &force_remove_attr.attr);
+	if (result)
+		return result;
+
 	result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr);
 	return result;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/video.c linux-libre-3.11-rc7-gnu/drivers/acpi/video.c
--- linux-libre-3.10-gnu/drivers/acpi/video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/video.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,6 +44,8 @@
 #include <linux/suspend.h>
 #include <acpi/video.h>
 
+#include "internal.h"
+
 #define PREFIX "ACPI: "
 
 #define ACPI_VIDEO_BUS_NAME		"Video Bus"
@@ -450,6 +452,14 @@ static struct dmi_system_id video_dmi_ta
 	},
 	{
 	 .callback = video_ignore_initial_backlight,
+	 .ident = "Fujitsu E753",
+	 .matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR, "FUJITSU"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E753"),
+		},
+	},
+	{
+	 .callback = video_ignore_initial_backlight,
 	 .ident = "HP Pavilion dm4",
 	 .matches = {
 		DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
@@ -679,7 +689,7 @@ static int acpi_video_bqc_quirk(struct a
 	 * Some systems always report current brightness level as maximum
 	 * through _BQC, we need to test another value for them.
 	 */
-	test_level = current_level == max_level ? br->levels[2] : max_level;
+	test_level = current_level == max_level ? br->levels[3] : max_level;
 
 	result = acpi_video_device_lcd_set_level(device, test_level);
 	if (result)
@@ -1532,14 +1542,20 @@ static int acpi_video_bus_put_devices(st
 
 /* acpi_video interface */
 
+/*
+ * Win8 requires setting bit2 of _DOS to let firmware know it shouldn't
+ * preform any automatic brightness change on receiving a notification.
+ */
 static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
 {
-	return acpi_video_bus_DOS(video, 0, 0);
+	return acpi_video_bus_DOS(video, 0,
+				  acpi_video_backlight_quirks() ? 1 : 0);
 }
 
 static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
 {
-	return acpi_video_bus_DOS(video, 0, 1);
+	return acpi_video_bus_DOS(video, 0,
+				  acpi_video_backlight_quirks() ? 0 : 1);
 }
 
 static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
@@ -1722,9 +1738,6 @@ static int acpi_video_bus_add(struct acp
 	int error;
 	acpi_status status;
 
-	if (device->handler)
-		return -EINVAL;
-
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
 				device->parent->handle, 1,
 				acpi_video_bus_match, NULL,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/acpi/video_detect.c linux-libre-3.11-rc7-gnu/drivers/acpi/video_detect.c
--- linux-libre-3.10-gnu/drivers/acpi/video_detect.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/acpi/video_detect.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,6 +38,8 @@
 #include <linux/dmi.h>
 #include <linux/pci.h>
 
+#include "internal.h"
+
 #define PREFIX "ACPI: "
 
 ACPI_MODULE_NAME("video");
@@ -234,6 +236,12 @@ static void acpi_video_caps_check(void)
 		acpi_video_get_capabilities(NULL);
 }
 
+bool acpi_video_backlight_quirks(void)
+{
+	return acpi_gbl_osi_data >= ACPI_OSI_WIN_8;
+}
+EXPORT_SYMBOL(acpi_video_backlight_quirks);
+
 /* Promote the vendor interface instead of the generic video module.
  * This function allow DMI blacklists to be implemented by externals
  * platform drivers instead of putting a big blacklist in video_detect.c
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/amba/bus.c linux-libre-3.11-rc7-gnu/drivers/amba/bus.c
--- linux-libre-3.10-gnu/drivers/amba/bus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/amba/bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -284,7 +284,7 @@ static const struct dev_pm_ops amba_pm =
 	SET_RUNTIME_PM_OPS(
 		amba_pm_runtime_suspend,
 		amba_pm_runtime_resume,
-		pm_generic_runtime_idle
+		NULL
 	)
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/acard-ahci.c linux-libre-3.11-rc7-gnu/drivers/ata/acard-ahci.c
--- linux-libre-3.10-gnu/drivers/ata/acard-ahci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/acard-ahci.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,7 +128,7 @@ static struct pci_driver acard_ahci_pci_
 #ifdef CONFIG_PM
 static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	struct ahci_host_priv *hpriv = host->private_data;
 	void __iomem *mmio = hpriv->mmio;
 	u32 ctl;
@@ -156,7 +156,7 @@ static int acard_ahci_pci_device_suspend
 
 static int acard_ahci_pci_device_resume(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/ahci.c linux-libre-3.11-rc7-gnu/drivers/ata/ahci.c
--- linux-libre-3.10-gnu/drivers/ata/ahci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/ahci.c	2013-08-25 20:43:22.000000000 -0400
@@ -291,6 +291,7 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
 	{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
+	{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -310,6 +311,7 @@ static const struct pci_device_id ahci_p
 
 	/* AMD */
 	{ PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
+	{ PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */
 	/* AMD is using RAID class only for ahci controllers */
 	{ PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
 	  PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
@@ -585,7 +587,7 @@ static int ahci_p5wdh_hardreset(struct a
 
 	/* clear D2H reception area to properly wait for D2H FIS */
 	ata_tf_init(link->device, &tf);
-	tf.command = 0x80;
+	tf.command = ATA_BUSY;
 	ata_tf_to_fis(&tf, 0, 0, d2h_fis);
 
 	rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
@@ -618,7 +620,7 @@ static int ahci_p5wdh_hardreset(struct a
 #ifdef CONFIG_PM
 static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	struct ahci_host_priv *hpriv = host->private_data;
 	void __iomem *mmio = hpriv->mmio;
 	u32 ctl;
@@ -646,7 +648,7 @@ static int ahci_pci_device_suspend(struc
 
 static int ahci_pci_device_resume(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
@@ -1144,9 +1146,18 @@ int ahci_host_activate(struct ata_host *
 		return rc;
 
 	for (i = 0; i < host->n_ports; i++) {
+		const char* desc;
+		struct ahci_port_priv *pp = host->ports[i]->private_data;
+
+		/* pp is NULL for dummy ports */
+		if (pp)
+			desc = pp->irq_desc;
+		else
+			desc = dev_driver_string(host->dev);
+
 		rc = devm_request_threaded_irq(host->dev,
 			irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED,
-			dev_driver_string(host->dev), host->ports[i]);
+			desc, host->ports[i]);
 		if (rc)
 			goto out_free_irqs;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/ahci.h linux-libre-3.11-rc7-gnu/drivers/ata/ahci.h
--- linux-libre-3.10-gnu/drivers/ata/ahci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/ahci.h	2013-08-25 20:43:22.000000000 -0400
@@ -306,6 +306,7 @@ struct ahci_port_priv {
 	int			fbs_last_dev;	/* save FBS.DEV of last FIS */
 	/* enclosure management info per PM slot */
 	struct ahci_em_priv	em_priv[EM_MAX_SLOTS];
+	char			*irq_desc;	/* desc in /proc/interrupts */
 };
 
 struct ahci_host_priv {
@@ -321,6 +322,7 @@ struct ahci_host_priv {
 	u32			em_buf_sz;	/* EM buffer size in byte */
 	u32			em_msg_type;	/* EM message type */
 	struct clk		*clk;		/* Only for platforms supporting clk */
+	void			*plat_data;	/* Other platform data */
 };
 
 extern int ahci_ignore_sss;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/ahci_imx.c linux-libre-3.11-rc7-gnu/drivers/ata/ahci_imx.c
--- linux-libre-3.10-gnu/drivers/ata/ahci_imx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/ata/ahci_imx.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,236 @@
+/*
+ * Freescale IMX AHCI SATA platform driver
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/ahci_platform.h>
+#include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include "ahci.h"
+
+enum {
+	HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
+};
+
+struct imx_ahci_priv {
+	struct platform_device *ahci_pdev;
+	struct clk *sata_ref_clk;
+	struct clk *ahb_clk;
+	struct regmap *gpr;
+};
+
+static int imx6q_sata_init(struct device *dev, void __iomem *mmio)
+{
+	int ret = 0;
+	unsigned int reg_val;
+	struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
+
+	imxpriv->gpr =
+		syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+	if (IS_ERR(imxpriv->gpr)) {
+		dev_err(dev, "failed to find fsl,imx6q-iomux-gpr regmap\n");
+		return PTR_ERR(imxpriv->gpr);
+	}
+
+	ret = clk_prepare_enable(imxpriv->sata_ref_clk);
+	if (ret < 0) {
+		dev_err(dev, "prepare-enable sata_ref clock err:%d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * set PHY Paremeters, two steps to configure the GPR13,
+	 * one write for rest of parameters, mask of first write
+	 * is 0x07fffffd, and the other one write for setting
+	 * the mpll_clk_en.
+	 */
+	regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK
+			| IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK
+			| IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK
+			| IMX6Q_GPR13_SATA_SPD_MODE_MASK
+			| IMX6Q_GPR13_SATA_MPLL_SS_EN
+			| IMX6Q_GPR13_SATA_TX_ATTEN_MASK
+			| IMX6Q_GPR13_SATA_TX_BOOST_MASK
+			| IMX6Q_GPR13_SATA_TX_LVL_MASK
+			| IMX6Q_GPR13_SATA_TX_EDGE_RATE
+			, IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB
+			| IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M
+			| IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F
+			| IMX6Q_GPR13_SATA_SPD_MODE_3P0G
+			| IMX6Q_GPR13_SATA_MPLL_SS_EN
+			| IMX6Q_GPR13_SATA_TX_ATTEN_9_16
+			| IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB
+			| IMX6Q_GPR13_SATA_TX_LVL_1_025_V);
+	regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_MPLL_CLK_EN,
+			IMX6Q_GPR13_SATA_MPLL_CLK_EN);
+	usleep_range(100, 200);
+
+	/*
+	 * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
+	 * and IP vendor specific register HOST_TIMER1MS.
+	 * Configure CAP_SSS (support stagered spin up).
+	 * Implement the port0.
+	 * Get the ahb clock rate, and configure the TIMER1MS register.
+	 */
+	reg_val = readl(mmio + HOST_CAP);
+	if (!(reg_val & HOST_CAP_SSS)) {
+		reg_val |= HOST_CAP_SSS;
+		writel(reg_val, mmio + HOST_CAP);
+	}
+	reg_val = readl(mmio + HOST_PORTS_IMPL);
+	if (!(reg_val & 0x1)) {
+		reg_val |= 0x1;
+		writel(reg_val, mmio + HOST_PORTS_IMPL);
+	}
+
+	reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
+	writel(reg_val, mmio + HOST_TIMER1MS);
+
+	return 0;
+}
+
+static void imx6q_sata_exit(struct device *dev)
+{
+	struct imx_ahci_priv *imxpriv =  dev_get_drvdata(dev->parent);
+
+	regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_MPLL_CLK_EN,
+			!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
+	clk_disable_unprepare(imxpriv->sata_ref_clk);
+}
+
+static struct ahci_platform_data imx6q_sata_pdata = {
+	.init = imx6q_sata_init,
+	.exit = imx6q_sata_exit,
+};
+
+static const struct of_device_id imx_ahci_of_match[] = {
+	{ .compatible = "fsl,imx6q-ahci", .data = &imx6q_sata_pdata},
+	{},
+};
+MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
+
+static int imx_ahci_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *mem, *irq, res[2];
+	const struct of_device_id *of_id;
+	const struct ahci_platform_data *pdata = NULL;
+	struct imx_ahci_priv *imxpriv;
+	struct device *ahci_dev;
+	struct platform_device *ahci_pdev;
+	int ret;
+
+	imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
+	if (!imxpriv) {
+		dev_err(dev, "can't alloc ahci_host_priv\n");
+		return -ENOMEM;
+	}
+
+	ahci_pdev = platform_device_alloc("ahci", -1);
+	if (!ahci_pdev)
+		return -ENODEV;
+
+	ahci_dev = &ahci_pdev->dev;
+	ahci_dev->parent = dev;
+
+	imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
+	if (IS_ERR(imxpriv->ahb_clk)) {
+		dev_err(dev, "can't get ahb clock.\n");
+		ret = PTR_ERR(imxpriv->ahb_clk);
+		goto err_out;
+	}
+
+	imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
+	if (IS_ERR(imxpriv->sata_ref_clk)) {
+		dev_err(dev, "can't get sata_ref clock.\n");
+		ret = PTR_ERR(imxpriv->sata_ref_clk);
+		goto err_out;
+	}
+
+	imxpriv->ahci_pdev = ahci_pdev;
+	platform_set_drvdata(pdev, imxpriv);
+
+	of_id = of_match_device(imx_ahci_of_match, dev);
+	if (of_id) {
+		pdata = of_id->data;
+	} else {
+		ret = -EINVAL;
+		goto err_out;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!mem || !irq) {
+		dev_err(dev, "no mmio/irq resource\n");
+		ret = -ENOMEM;
+		goto err_out;
+	}
+
+	res[0] = *mem;
+	res[1] = *irq;
+
+	ahci_dev->coherent_dma_mask = DMA_BIT_MASK(32);
+	ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask;
+	ahci_dev->of_node = dev->of_node;
+
+	ret = platform_device_add_resources(ahci_pdev, res, 2);
+	if (ret)
+		goto err_out;
+
+	ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata));
+	if (ret)
+		goto err_out;
+
+	ret = platform_device_add(ahci_pdev);
+	if (ret) {
+err_out:
+		platform_device_put(ahci_pdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int imx_ahci_remove(struct platform_device *pdev)
+{
+	struct imx_ahci_priv *imxpriv = platform_get_drvdata(pdev);
+	struct platform_device *ahci_pdev = imxpriv->ahci_pdev;
+
+	platform_device_unregister(ahci_pdev);
+	return 0;
+}
+
+static struct platform_driver imx_ahci_driver = {
+	.probe = imx_ahci_probe,
+	.remove = imx_ahci_remove,
+	.driver = {
+		.name = "ahci-imx",
+		.owner = THIS_MODULE,
+		.of_match_table = imx_ahci_of_match,
+	},
+};
+module_platform_driver(imx_ahci_driver);
+
+MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver");
+MODULE_AUTHOR("Richard Zhu <Hong-Xing.Zhu@freescale.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ahci:imx");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/ahci_platform.c linux-libre-3.11-rc7-gnu/drivers/ata/ahci_platform.c
--- linux-libre-3.10-gnu/drivers/ata/ahci_platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/ahci_platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -327,6 +327,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ah
 
 static const struct of_device_id ahci_of_match[] = {
 	{ .compatible = "snps,spear-ahci", },
+	{ .compatible = "snps,exynos5440-ahci", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, ahci_of_match);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/ata_piix.c linux-libre-3.11-rc7-gnu/drivers/ata/ata_piix.c
--- linux-libre-3.10-gnu/drivers/ata/ata_piix.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/ata_piix.c	2013-08-25 20:43:22.000000000 -0400
@@ -330,7 +330,7 @@ static const struct pci_device_id piix_p
 	/* SATA Controller IDE (Wellsburg) */
 	{ 0x8086, 0x8d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
 	/* SATA Controller IDE (Wellsburg) */
-	{ 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+	{ 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
 	/* SATA Controller IDE (Wellsburg) */
 	{ 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
 	/* SATA Controller IDE (Wellsburg) */
@@ -338,6 +338,8 @@ static const struct pci_device_id piix_p
 	/* SATA Controller IDE (BayTrail) */
 	{ 0x8086, 0x0F20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
 	{ 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
+	/* SATA Controller IDE (Coleto Creek) */
+	{ 0x8086, 0x23a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
 
 	{ }	/* terminate list */
 };
@@ -993,7 +995,7 @@ static int piix_broken_suspend(void)
 
 static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	unsigned long flags;
 	int rc = 0;
 
@@ -1028,7 +1030,7 @@ static int piix_pci_device_suspend(struc
 
 static int piix_pci_device_resume(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	unsigned long flags;
 	int rc;
 
@@ -1751,7 +1753,7 @@ static int piix_init_one(struct pci_dev
 
 static void piix_remove_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	struct piix_host_priv *hpriv = host->private_data;
 
 	pci_write_config_dword(pdev, PIIX_IOCFG, hpriv->saved_iocfg);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/Kconfig linux-libre-3.11-rc7-gnu/drivers/ata/Kconfig
--- linux-libre-3.10-gnu/drivers/ata/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -97,6 +97,15 @@ config SATA_AHCI_PLATFORM
 
 	  If unsure, say N.
 
+config AHCI_IMX
+	tristate "Freescale i.MX AHCI SATA support"
+	depends on SATA_AHCI_PLATFORM && MFD_SYSCON
+	help
+	  This option enables support for the Freescale i.MX SoC's
+	  onboard AHCI SATA.
+
+	  If unsure, say N.
+
 config SATA_FSL
 	tristate "Freescale 3.0Gbps SATA support"
 	depends on FSL_SOC
@@ -107,7 +116,7 @@ config SATA_FSL
 	  If unsure, say N.
 
 config SATA_INIC162X
-	tristate "Initio 162x SATA support"
+	tristate "Initio 162x SATA support (Very Experimental)"
 	depends on PCI
 	help
 	  This option enables support for Initio 162x Serial ATA.
@@ -160,7 +169,7 @@ config PDC_ADMA
 
 config PATA_OCTEON_CF
 	tristate "OCTEON Boot Bus Compact Flash support"
-	depends on CPU_CAVIUM_OCTEON
+	depends on CAVIUM_OCTEON_SOC
 	help
 	  This option enables a polled compact flash driver for use with
 	  compact flash cards attached to the OCTEON boot bus.
@@ -263,7 +272,6 @@ config SATA_PROMISE
 
 config SATA_RCAR
 	tristate "Renesas R-Car SATA support"
-	depends on ARCH_SHMOBILE && ARCH_R8A7779
 	help
 	  This option enables support for Renesas R-Car Serial ATA.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/libahci.c linux-libre-3.11-rc7-gnu/drivers/ata/libahci.c
--- linux-libre-3.10-gnu/drivers/ata/libahci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/libahci.c	2013-08-25 20:43:22.000000000 -0400
@@ -173,6 +173,7 @@ struct ata_port_operations ahci_ops = {
 	.em_store		= ahci_led_store,
 	.sw_activity_show	= ahci_activity_show,
 	.sw_activity_store	= ahci_activity_store,
+	.transmit_led_message	= ahci_transmit_led_message,
 #ifdef CONFIG_PM
 	.port_suspend		= ahci_port_suspend,
 	.port_resume		= ahci_port_resume,
@@ -774,7 +775,7 @@ static void ahci_start_port(struct ata_p
 
 			/* EM Transmit bit maybe busy during init */
 			for (i = 0; i < EM_MAX_RETRY; i++) {
-				rc = ahci_transmit_led_message(ap,
+				rc = ap->ops->transmit_led_message(ap,
 							       emp->led_state,
 							       4);
 				if (rc == -EBUSY)
@@ -915,7 +916,7 @@ static void ahci_sw_activity_blink(unsig
 			led_message |= (1 << 16);
 	}
 	spin_unlock_irqrestore(ap->lock, flags);
-	ahci_transmit_led_message(ap, led_message, 4);
+	ap->ops->transmit_led_message(ap, led_message, 4);
 }
 
 static void ahci_init_sw_activity(struct ata_link *link)
@@ -1044,7 +1045,7 @@ static ssize_t ahci_led_store(struct ata
 	if (emp->blink_policy)
 		state &= ~EM_MSG_LED_VALUE_ACTIVITY;
 
-	return ahci_transmit_led_message(ap, state, size);
+	return ap->ops->transmit_led_message(ap, state, size);
 }
 
 static ssize_t ahci_activity_store(struct ata_device *dev, enum sw_activity val)
@@ -1063,7 +1064,7 @@ static ssize_t ahci_activity_store(struc
 		/* set the LED to OFF */
 		port_led_state &= EM_MSG_LED_VALUE_OFF;
 		port_led_state |= (ap->port_no | (link->pmp << 8));
-		ahci_transmit_led_message(ap, port_led_state, 4);
+		ap->ops->transmit_led_message(ap, port_led_state, 4);
 	} else {
 		link->flags |= ATA_LFLAG_SW_ACTIVITY;
 		if (val == BLINK_OFF) {
@@ -1071,7 +1072,7 @@ static ssize_t ahci_activity_store(struc
 			port_led_state &= EM_MSG_LED_VALUE_OFF;
 			port_led_state |= (ap->port_no | (link->pmp << 8));
 			port_led_state |= EM_MSG_LED_VALUE_ON; /* check this */
-			ahci_transmit_led_message(ap, port_led_state, 4);
+			ap->ops->transmit_led_message(ap, port_led_state, 4);
 		}
 	}
 	emp->blink_policy = val;
@@ -1412,7 +1413,7 @@ static int ahci_hardreset(struct ata_lin
 
 	/* clear D2H reception area to properly wait for D2H FIS */
 	ata_tf_init(link->device, &tf);
-	tf.command = 0x80;
+	tf.command = ATA_BUSY;
 	ata_tf_to_fis(&tf, 0, 0, d2h_fis);
 
 	rc = sata_link_hardreset(link, timing, deadline, &online,
@@ -1560,8 +1561,7 @@ static void ahci_error_intr(struct ata_p
 		u32 fbs = readl(port_mmio + PORT_FBS);
 		int pmp = fbs >> PORT_FBS_DWE_OFFSET;
 
-		if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links) &&
-		    ata_link_online(&ap->pmp_link[pmp])) {
+		if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links)) {
 			link = &ap->pmp_link[pmp];
 			fbs_need_dec = true;
 		}
@@ -2234,6 +2234,16 @@ static int ahci_port_start(struct ata_po
 	if (!pp)
 		return -ENOMEM;
 
+	if (ap->host->n_ports > 1) {
+		pp->irq_desc = devm_kzalloc(dev, 8, GFP_KERNEL);
+		if (!pp->irq_desc) {
+			devm_kfree(dev, pp);
+			return -ENOMEM;
+		}
+		snprintf(pp->irq_desc, 8,
+			 "%s%d", dev_driver_string(dev), ap->port_no);
+	}
+
 	/* check FBS capability */
 	if ((hpriv->cap & HOST_CAP_FBS) && sata_pmp_supported(ap)) {
 		void __iomem *port_mmio = ahci_port_base(ap);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/libata-core.c linux-libre-3.11-rc7-gnu/drivers/ata/libata-core.c
--- linux-libre-3.10-gnu/drivers/ata/libata-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/libata-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -2401,7 +2401,7 @@ int ata_dev_configure(struct ata_device
 			cdb_intr_string = ", CDB intr";
 		}
 
-		if (atapi_dmadir || atapi_id_dmadir(dev->id)) {
+		if (atapi_dmadir || (dev->horkage & ATA_HORKAGE_ATAPI_DMADIR) || atapi_id_dmadir(dev->id)) {
 			dev->flags |= ATA_DFLAG_DMADIR;
 			dma_dir_string = ", DMADIR";
 		}
@@ -5436,7 +5436,7 @@ static int ata_port_runtime_idle(struct
 				return -EBUSY;
 	}
 
-	return pm_runtime_suspend(dev);
+	return 0;
 }
 
 static int ata_port_runtime_suspend(struct device *dev)
@@ -5642,6 +5642,7 @@ struct ata_port *ata_port_alloc(struct a
 	ap->pflags |= ATA_PFLAG_INITIALIZING | ATA_PFLAG_FROZEN;
 	ap->lock = &host->lock;
 	ap->print_id = -1;
+	ap->local_port_no = -1;
 	ap->host = host;
 	ap->dev = host->dev;
 
@@ -6132,9 +6133,10 @@ int ata_host_register(struct ata_host *h
 		kfree(host->ports[i]);
 
 	/* give ports names and add SCSI hosts */
-	for (i = 0; i < host->n_ports; i++)
+	for (i = 0; i < host->n_ports; i++) {
 		host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
-
+		host->ports[i]->local_port_no = i + 1;
+	}
 
 	/* Create associated sysfs transport objects  */
 	for (i = 0; i < host->n_ports; i++) {
@@ -6502,6 +6504,7 @@ static int __init ata_parse_force_one(ch
 		{ "nosrst",	.lflags		= ATA_LFLAG_NO_SRST },
 		{ "norst",	.lflags		= ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
 		{ "rstonce",	.lflags		= ATA_LFLAG_RST_ONCE },
+		{ "atapi_dmadir", .horkage_on	= ATA_HORKAGE_ATAPI_DMADIR },
 	};
 	char *start = *cur, *p = *cur;
 	char *id, *val, *endp;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/libata-pmp.c linux-libre-3.11-rc7-gnu/drivers/ata/libata-pmp.c
--- linux-libre-3.10-gnu/drivers/ata/libata-pmp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/libata-pmp.c	2013-08-25 20:43:22.000000000 -0400
@@ -289,24 +289,24 @@ static int sata_pmp_configure(struct ata
 
 	/* Disable sending Early R_OK.
 	 * With "cached read" HDD testing and multiple ports busy on a SATA
-	 * host controller, 3726 PMP will very rarely drop a deferred
+	 * host controller, 3x26 PMP will very rarely drop a deferred
 	 * R_OK that was intended for the host. Symptom will be all
 	 * 5 drives under test will timeout, get reset, and recover.
 	 */
-	if (vendor == 0x1095 && devid == 0x3726) {
+	if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) {
 		u32 reg;
 
 		err_mask = sata_pmp_read(&ap->link, PMP_GSCR_SII_POL, &reg);
 		if (err_mask) {
 			rc = -EIO;
-			reason = "failed to read Sil3726 Private Register";
+			reason = "failed to read Sil3x26 Private Register";
 			goto fail;
 		}
 		reg &= ~0x1;
 		err_mask = sata_pmp_write(&ap->link, PMP_GSCR_SII_POL, reg);
 		if (err_mask) {
 			rc = -EIO;
-			reason = "failed to write Sil3726 Private Register";
+			reason = "failed to write Sil3x26 Private Register";
 			goto fail;
 		}
 	}
@@ -383,15 +383,19 @@ static void sata_pmp_quirks(struct ata_p
 	u16 devid = sata_pmp_gscr_devid(gscr);
 	struct ata_link *link;
 
-	if (vendor == 0x1095 && devid == 0x3726) {
-		/* sil3726 quirks */
+	if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) {
+		/* sil3x26 quirks */
 		ata_for_each_link(link, ap, EDGE) {
 			/* link reports offline after LPM */
 			link->flags |= ATA_LFLAG_NO_LPM;
 
-			/* Class code report is unreliable. */
+			/*
+			 * Class code report is unreliable and SRST times
+			 * out under certain configurations.
+			 */
 			if (link->pmp < 5)
-				link->flags |= ATA_LFLAG_ASSUME_ATA;
+				link->flags |= ATA_LFLAG_NO_SRST |
+					       ATA_LFLAG_ASSUME_ATA;
 
 			/* port 5 is for SEMB device and it doesn't like SRST */
 			if (link->pmp == 5)
@@ -399,20 +403,17 @@ static void sata_pmp_quirks(struct ata_p
 					       ATA_LFLAG_ASSUME_SEMB;
 		}
 	} else if (vendor == 0x1095 && devid == 0x4723) {
-		/* sil4723 quirks */
-		ata_for_each_link(link, ap, EDGE) {
-			/* link reports offline after LPM */
-			link->flags |= ATA_LFLAG_NO_LPM;
-
-			/* class code report is unreliable */
-			if (link->pmp < 2)
-				link->flags |= ATA_LFLAG_ASSUME_ATA;
-
-			/* the config device at port 2 locks up on SRST */
-			if (link->pmp == 2)
-				link->flags |= ATA_LFLAG_NO_SRST |
-					       ATA_LFLAG_ASSUME_ATA;
-		}
+		/*
+		 * sil4723 quirks
+		 *
+		 * Link reports offline after LPM.  Class code report is
+		 * unreliable.  SIMG PMPs never got SRST reliable and the
+		 * config device at port 2 locks up on SRST.
+		 */
+		ata_for_each_link(link, ap, EDGE)
+			link->flags |= ATA_LFLAG_NO_LPM |
+				       ATA_LFLAG_NO_SRST |
+				       ATA_LFLAG_ASSUME_ATA;
 	} else if (vendor == 0x1095 && devid == 0x4726) {
 		/* sil4726 quirks */
 		ata_for_each_link(link, ap, EDGE) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/libata-scsi.c linux-libre-3.11-rc7-gnu/drivers/ata/libata-scsi.c
--- linux-libre-3.10-gnu/drivers/ata/libata-scsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/libata-scsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -206,8 +206,10 @@ static ssize_t ata_scsi_park_store(struc
 	unsigned long flags;
 	int rc;
 
-	rc = strict_strtol(buf, 10, &input);
-	if (rc || input < -2)
+	rc = kstrtol(buf, 10, &input);
+	if (rc)
+		return rc;
+	if (input < -2)
 		return -EINVAL;
 	if (input > ATA_TMOUT_MAX_PARK) {
 		rc = -EOVERFLOW;
@@ -849,25 +851,24 @@ static void ata_to_sense_error(unsigned
 		/*  Bad address mark */
 		{0x01, 		MEDIUM_ERROR, 0x13, 0x00}, 	// Address mark not found       Address mark not found for data field
 		/* TRK0 */
-		{0x02, 		HARDWARE_ERROR, 0x00, 0x00}, 	// Track 0 not found		  Hardware error
-		/* Abort & !ICRC */
-		{0x04, 		ABORTED_COMMAND, 0x00, 0x00}, 	// Aborted command              Aborted command
+		{0x02, 		HARDWARE_ERROR, 0x00, 0x00}, 	// Track 0 not found		Hardware error
+		/* Abort: 0x04 is not translated here, see below */
 		/* Media change request */
 		{0x08, 		NOT_READY, 0x04, 0x00}, 	// Media change request	  FIXME: faking offline
-		/* SRV */
-		{0x10, 		ABORTED_COMMAND, 0x14, 0x00}, 	// ID not found                 Recorded entity not found
-		/* Media change */
-		{0x08,  	NOT_READY, 0x04, 0x00}, 	// Media change		  FIXME: faking offline
+		/* SRV/IDNF */
+		{0x10, 		ILLEGAL_REQUEST, 0x21, 0x00}, 	// ID not found                 Logical address out of range
+		/* MC */
+		{0x20, 		UNIT_ATTENTION, 0x28, 0x00}, 	// Media Changed		Not ready to ready change, medium may have changed
 		/* ECC */
 		{0x40, 		MEDIUM_ERROR, 0x11, 0x04}, 	// Uncorrectable ECC error      Unrecovered read error
 		/* BBD - block marked bad */
-		{0x80, 		MEDIUM_ERROR, 0x11, 0x04}, 	// Block marked bad		  Medium error, unrecovered read error
+		{0x80, 		MEDIUM_ERROR, 0x11, 0x04}, 	// Block marked bad		Medium error, unrecovered read error
 		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
 	};
 	static const unsigned char stat_table[][4] = {
 		/* Must be first because BUSY means no other bits valid */
 		{0x80, 		ABORTED_COMMAND, 0x47, 0x00},	// Busy, fake parity for now
-		{0x20, 		HARDWARE_ERROR,  0x00, 0x00}, 	// Device fault
+		{0x20, 		HARDWARE_ERROR,  0x44, 0x00}, 	// Device fault, internal target failure
 		{0x08, 		ABORTED_COMMAND, 0x47, 0x00},	// Timed out in xfer, fake parity for now
 		{0x04, 		RECOVERED_ERROR, 0x11, 0x00},	// Recovered ECC error	  Medium error, recovered
 		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
@@ -892,13 +893,13 @@ static void ata_to_sense_error(unsigned
 				goto translate_done;
 			}
 		}
-		/* No immediate match */
-		if (verbose)
-			printk(KERN_WARNING "ata%u: no sense translation for "
-			       "error 0x%02x\n", id, drv_err);
 	}
 
-	/* Fall back to interpreting status bits */
+	/*
+	 * Fall back to interpreting status bits.  Note that if the drv_err
+	 * has only the ABRT bit set, we decode drv_stat.  ABRT by itself
+	 * is not descriptive enough.
+	 */
 	for (i = 0; stat_table[i][0] != 0xFF; i++) {
 		if (stat_table[i][0] & drv_stat) {
 			*sk = stat_table[i][1];
@@ -907,13 +908,11 @@ static void ata_to_sense_error(unsigned
 			goto translate_done;
 		}
 	}
-	/* No error?  Undecoded? */
-	if (verbose)
-		printk(KERN_WARNING "ata%u: no sense translation for "
-		       "status: 0x%02x\n", id, drv_stat);
 
-	/* We need a sensible error return here, which is tricky, and one
-	   that won't cause people to do things like return a disk wrongly */
+	/*
+	 * We need a sensible error return here, which is tricky, and one
+	 * that won't cause people to do things like return a disk wrongly.
+	 */
 	*sk = ABORTED_COMMAND;
 	*asc = 0x00;
 	*ascq = 0x00;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/libata-transport.c linux-libre-3.11-rc7-gnu/drivers/ata/libata-transport.c
--- linux-libre-3.10-gnu/drivers/ata/libata-transport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/libata-transport.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,7 @@
 #include "libata.h"
 #include "libata-transport.h"
 
-#define ATA_PORT_ATTRS		2
+#define ATA_PORT_ATTRS		3
 #define ATA_LINK_ATTRS		3
 #define ATA_DEV_ATTRS		9
 
@@ -216,6 +216,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_a
 
 ata_port_simple_attr(nr_pmp_links, nr_pmp_links, "%d\n", int);
 ata_port_simple_attr(stats.idle_irq, idle_irq, "%ld\n", unsigned long);
+ata_port_simple_attr(local_port_no, port_no, "%u\n", unsigned int);
 
 static DECLARE_TRANSPORT_CLASS(ata_port_class,
 			       "ata_port", NULL, NULL, NULL);
@@ -709,6 +710,7 @@ struct scsi_transport_template *ata_atta
 	count = 0;
 	SETUP_PORT_ATTRIBUTE(nr_pmp_links);
 	SETUP_PORT_ATTRIBUTE(idle_irq);
+	SETUP_PORT_ATTRIBUTE(port_no);
 	BUG_ON(count > ATA_PORT_ATTRS);
 	i->port_attrs[count] = NULL;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/libata-zpodd.c linux-libre-3.11-rc7-gnu/drivers/ata/libata-zpodd.c
--- linux-libre-3.10-gnu/drivers/ata/libata-zpodd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/libata-zpodd.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,13 +32,14 @@ struct zpodd {
 
 static int eject_tray(struct ata_device *dev)
 {
-	struct ata_taskfile tf = {};
+	struct ata_taskfile tf;
 	const char cdb[] = {  GPCMD_START_STOP_UNIT,
 		0, 0, 0,
 		0x02,     /* LoEj */
 		0, 0, 0, 0, 0, 0, 0,
 	};
 
+	ata_tf_init(dev, &tf);
 	tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 	tf.command = ATA_CMD_PACKET;
 	tf.protocol = ATAPI_PROT_NODATA;
@@ -52,8 +53,7 @@ static enum odd_mech_type zpodd_get_mech
 	char buf[16];
 	unsigned int ret;
 	struct rm_feature_desc *desc = (void *)(buf + 8);
-	struct ata_taskfile tf = {};
-
+	struct ata_taskfile tf;
 	char cdb[] = {  GPCMD_GET_CONFIGURATION,
 			2,      /* only 1 feature descriptor requested */
 			0, 3,   /* 3, removable medium feature */
@@ -62,6 +62,7 @@ static enum odd_mech_type zpodd_get_mech
 			0, 0, 0,
 	};
 
+	ata_tf_init(dev, &tf);
 	tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 	tf.command = ATA_CMD_PACKET;
 	tf.protocol = ATAPI_PROT_PIO;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/Makefile linux-libre-3.11-rc7-gnu/drivers/ata/Makefile
--- linux-libre-3.10-gnu/drivers/ata/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,7 @@ obj-$(CONFIG_SATA_INIC162X)	+= sata_inic
 obj-$(CONFIG_SATA_SIL24)	+= sata_sil24.o
 obj-$(CONFIG_SATA_DWC)		+= sata_dwc_460ex.o
 obj-$(CONFIG_SATA_HIGHBANK)	+= sata_highbank.o libahci.o
+obj-$(CONFIG_AHCI_IMX)		+= ahci_imx.o
 
 # SFF w/ custom DMA
 obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_ali.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_ali.c
--- linux-libre-3.10-gnu/drivers/ata/pata_ali.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_ali.c	2013-08-25 20:43:22.000000000 -0400
@@ -592,7 +592,7 @@ static int ali_init_one(struct pci_dev *
 #ifdef CONFIG_PM
 static int ali_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_amd.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_amd.c
--- linux-libre-3.10-gnu/drivers/ata/pata_amd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_amd.c	2013-08-25 20:43:22.000000000 -0400
@@ -578,7 +578,7 @@ static int amd_init_one(struct pci_dev *
 #ifdef CONFIG_PM
 static int amd_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_arasan_cf.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_arasan_cf.c
--- linux-libre-3.10-gnu/drivers/ata/pata_arasan_cf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_arasan_cf.c	2013-08-25 20:43:22.000000000 -0400
@@ -908,7 +908,7 @@ free_clk:
 
 static int arasan_cf_remove(struct platform_device *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = platform_get_drvdata(pdev);
 	struct arasan_cf_dev *acdev = host->ports[0]->private_data;
 
 	ata_host_detach(host);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_artop.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_artop.c
--- linux-libre-3.10-gnu/drivers/ata/pata_artop.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_artop.c	2013-08-25 20:43:22.000000000 -0400
@@ -426,7 +426,7 @@ static const struct pci_device_id artop_
 #ifdef CONFIG_PM
 static int atp8xx_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_at91.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_at91.c
--- linux-libre-3.10-gnu/drivers/ata/pata_at91.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_at91.c	2013-08-25 20:43:22.000000000 -0400
@@ -422,7 +422,7 @@ err_put:
 
 static int pata_at91_remove(struct platform_device *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = platform_get_drvdata(pdev);
 	struct at91_ide_info *info;
 
 	if (!host)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_atp867x.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_atp867x.c
--- linux-libre-3.10-gnu/drivers/ata/pata_atp867x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_atp867x.c	2013-08-25 20:43:22.000000000 -0400
@@ -534,7 +534,7 @@ err_out:
 #ifdef CONFIG_PM
 static int atp867x_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_bf54x.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_bf54x.c
--- linux-libre-3.10-gnu/drivers/ata/pata_bf54x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_bf54x.c	2013-08-25 20:43:22.000000000 -0400
@@ -1596,7 +1596,7 @@ static int bfin_atapi_probe(struct platf
 		return -ENODEV;
 	}
 
-	dev_set_drvdata(&pdev->dev, host);
+	platform_set_drvdata(pdev, host);
 
 	return 0;
 }
@@ -1610,11 +1610,9 @@ static int bfin_atapi_probe(struct platf
  */
 static int bfin_atapi_remove(struct platform_device *pdev)
 {
-	struct device *dev = &pdev->dev;
-	struct ata_host *host = dev_get_drvdata(dev);
+	struct ata_host *host = platform_get_drvdata(pdev);
 
 	ata_host_detach(host);
-	dev_set_drvdata(&pdev->dev, NULL);
 
 	peripheral_free_list(atapi_io_port);
 
@@ -1624,7 +1622,7 @@ static int bfin_atapi_remove(struct plat
 #ifdef CONFIG_PM
 static int bfin_atapi_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = platform_get_drvdata(pdev);
 	if (host)
 		return ata_host_suspend(host, state);
 	else
@@ -1633,7 +1631,7 @@ static int bfin_atapi_suspend(struct pla
 
 static int bfin_atapi_resume(struct platform_device *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = platform_get_drvdata(pdev);
 	int ret;
 
 	if (host) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_cmd640.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_cmd640.c
--- linux-libre-3.10-gnu/drivers/ata/pata_cmd640.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_cmd640.c	2013-08-25 20:43:22.000000000 -0400
@@ -235,7 +235,7 @@ static int cmd640_init_one(struct pci_de
 #ifdef CONFIG_PM
 static int cmd640_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_cmd64x.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_cmd64x.c
--- linux-libre-3.10-gnu/drivers/ata/pata_cmd64x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_cmd64x.c	2013-08-25 20:43:22.000000000 -0400
@@ -491,7 +491,7 @@ static int cmd64x_init_one(struct pci_de
 #ifdef CONFIG_PM
 static int cmd64x_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_cs5520.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_cs5520.c
--- linux-libre-3.10-gnu/drivers/ata/pata_cs5520.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_cs5520.c	2013-08-25 20:43:22.000000000 -0400
@@ -241,7 +241,7 @@ static int cs5520_init_one(struct pci_de
 
 static int cs5520_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	u8 pcicfg;
 	int rc;
 
@@ -269,7 +269,7 @@ static int cs5520_reinit_one(struct pci_
 
 static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc = 0;
 
 	rc = ata_host_suspend(host, mesg);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_cs5530.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_cs5530.c
--- linux-libre-3.10-gnu/drivers/ata/pata_cs5530.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_cs5530.c	2013-08-25 20:43:22.000000000 -0400
@@ -330,7 +330,7 @@ static int cs5530_init_one(struct pci_de
 #ifdef CONFIG_PM
 static int cs5530_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_hpt366.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_hpt366.c
--- linux-libre-3.10-gnu/drivers/ata/pata_hpt366.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_hpt366.c	2013-08-25 20:43:22.000000000 -0400
@@ -390,7 +390,7 @@ static int hpt36x_init_one(struct pci_de
 #ifdef CONFIG_PM
 static int hpt36x_reinit_one(struct pci_dev *dev)
 {
-	struct ata_host *host = dev_get_drvdata(&dev->dev);
+	struct ata_host *host = pci_get_drvdata(dev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_hpt3x3.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_hpt3x3.c
--- linux-libre-3.10-gnu/drivers/ata/pata_hpt3x3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_hpt3x3.c	2013-08-25 20:43:22.000000000 -0400
@@ -253,7 +253,7 @@ static int hpt3x3_init_one(struct pci_de
 #ifdef CONFIG_PM
 static int hpt3x3_reinit_one(struct pci_dev *dev)
 {
-	struct ata_host *host = dev_get_drvdata(&dev->dev);
+	struct ata_host *host = pci_get_drvdata(dev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_imx.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_imx.c
--- linux-libre-3.10-gnu/drivers/ata/pata_imx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_imx.c	2013-08-25 20:43:22.000000000 -0400
@@ -177,7 +177,7 @@ err:
 
 static int pata_imx_remove(struct platform_device *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = platform_get_drvdata(pdev);
 	struct pata_imx_priv *priv = host->private_data;
 
 	ata_host_detach(host);
@@ -237,6 +237,7 @@ static const struct of_device_id imx_pat
 		/* sentinel */
 	}
 };
+MODULE_DEVICE_TABLE(of, imx_pata_dt_ids);
 
 static struct platform_driver pata_imx_driver = {
 	.probe		= pata_imx_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_it821x.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_it821x.c
--- linux-libre-3.10-gnu/drivers/ata/pata_it821x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_it821x.c	2013-08-25 20:43:22.000000000 -0400
@@ -939,7 +939,7 @@ static int it821x_init_one(struct pci_de
 #ifdef CONFIG_PM
 static int it821x_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_macio.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_macio.c
--- linux-libre-3.10-gnu/drivers/ata/pata_macio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_macio.c	2013-08-25 20:43:22.000000000 -0400
@@ -1311,7 +1311,7 @@ static int pata_macio_pci_attach(struct
 
 static void pata_macio_pci_detach(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 
 	ata_host_detach(host);
 }
@@ -1320,14 +1320,14 @@ static void pata_macio_pci_detach(struct
 
 static int pata_macio_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 
 	return pata_macio_do_suspend(host->private_data, mesg);
 }
 
 static int pata_macio_pci_resume(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 
 	return pata_macio_do_resume(host->private_data);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_mpc52xx.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_mpc52xx.c
--- linux-libre-3.10-gnu/drivers/ata/pata_mpc52xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_mpc52xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -825,7 +825,7 @@ mpc52xx_ata_remove(struct platform_devic
 static int
 mpc52xx_ata_suspend(struct platform_device *op, pm_message_t state)
 {
-	struct ata_host *host = dev_get_drvdata(&op->dev);
+	struct ata_host *host = platform_get_drvdata(op);
 
 	return ata_host_suspend(host, state);
 }
@@ -833,7 +833,7 @@ mpc52xx_ata_suspend(struct platform_devi
 static int
 mpc52xx_ata_resume(struct platform_device *op)
 {
-	struct ata_host *host = dev_get_drvdata(&op->dev);
+	struct ata_host *host = platform_get_drvdata(op);
 	struct mpc52xx_ata_priv *priv = host->private_data;
 	int rv;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_ninja32.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_ninja32.c
--- linux-libre-3.10-gnu/drivers/ata/pata_ninja32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_ninja32.c	2013-08-25 20:43:22.000000000 -0400
@@ -157,7 +157,7 @@ static int ninja32_init_one(struct pci_d
 
 static int ninja32_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_ns87415.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_ns87415.c
--- linux-libre-3.10-gnu/drivers/ata/pata_ns87415.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_ns87415.c	2013-08-25 20:43:22.000000000 -0400
@@ -389,7 +389,7 @@ static const struct pci_device_id ns8741
 #ifdef CONFIG_PM
 static int ns87415_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_pdc2027x.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_pdc2027x.c
--- linux-libre-3.10-gnu/drivers/ata/pata_pdc2027x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_pdc2027x.c	2013-08-25 20:43:22.000000000 -0400
@@ -765,7 +765,7 @@ static int pdc2027x_init_one(struct pci_
 #ifdef CONFIG_PM
 static int pdc2027x_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	unsigned int board_idx;
 	int rc;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_pxa.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_pxa.c
--- linux-libre-3.10-gnu/drivers/ata/pata_pxa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_pxa.c	2013-08-25 20:43:22.000000000 -0400
@@ -371,7 +371,7 @@ static int pxa_ata_probe(struct platform
 
 static int pxa_ata_remove(struct platform_device *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = platform_get_drvdata(pdev);
 	struct pata_pxa_data *data = host->ports[0]->private_data;
 
 	pxa_free_dma(data->dma_channel);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_rdc.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_rdc.c
--- linux-libre-3.10-gnu/drivers/ata/pata_rdc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_rdc.c	2013-08-25 20:43:22.000000000 -0400
@@ -364,7 +364,7 @@ static int rdc_init_one(struct pci_dev *
 
 static void rdc_remove_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	struct rdc_host_priv *hpriv = host->private_data;
 
 	pci_write_config_dword(pdev, 0x54, hpriv->saved_iocfg);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_rz1000.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_rz1000.c
--- linux-libre-3.10-gnu/drivers/ata/pata_rz1000.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_rz1000.c	2013-08-25 20:43:22.000000000 -0400
@@ -105,7 +105,7 @@ static int rz1000_init_one (struct pci_d
 #ifdef CONFIG_PM
 static int rz1000_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_serverworks.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_serverworks.c
--- linux-libre-3.10-gnu/drivers/ata/pata_serverworks.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_serverworks.c	2013-08-25 20:43:22.000000000 -0400
@@ -440,7 +440,7 @@ static int serverworks_init_one(struct p
 #ifdef CONFIG_PM
 static int serverworks_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_sil680.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_sil680.c
--- linux-libre-3.10-gnu/drivers/ata/pata_sil680.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_sil680.c	2013-08-25 20:43:22.000000000 -0400
@@ -407,7 +407,7 @@ use_ioports:
 #ifdef CONFIG_PM
 static int sil680_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int try_mmio, rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_sis.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_sis.c
--- linux-libre-3.10-gnu/drivers/ata/pata_sis.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_sis.c	2013-08-25 20:43:22.000000000 -0400
@@ -873,7 +873,7 @@ static int sis_init_one (struct pci_dev
 #ifdef CONFIG_PM
 static int sis_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_sl82c105.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_sl82c105.c
--- linux-libre-3.10-gnu/drivers/ata/pata_sl82c105.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_sl82c105.c	2013-08-25 20:43:22.000000000 -0400
@@ -341,7 +341,7 @@ static int sl82c105_init_one(struct pci_
 #ifdef CONFIG_PM
 static int sl82c105_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_triflex.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_triflex.c
--- linux-libre-3.10-gnu/drivers/ata/pata_triflex.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_triflex.c	2013-08-25 20:43:22.000000000 -0400
@@ -211,7 +211,7 @@ static const struct pci_device_id trifle
 #ifdef CONFIG_PM
 static int triflex_ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc = 0;
 
 	rc = ata_host_suspend(host, mesg);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/pata_via.c linux-libre-3.11-rc7-gnu/drivers/ata/pata_via.c
--- linux-libre-3.10-gnu/drivers/ata/pata_via.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/pata_via.c	2013-08-25 20:43:22.000000000 -0400
@@ -673,7 +673,7 @@ static int via_init_one(struct pci_dev *
 
 static int via_reinit_one(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/sata_fsl.c linux-libre-3.11-rc7-gnu/drivers/ata/sata_fsl.c
--- linux-libre-3.10-gnu/drivers/ata/sata_fsl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/sata_fsl.c	2013-08-25 20:43:22.000000000 -0400
@@ -293,6 +293,7 @@ static void fsl_sata_set_irq_coalescing(
 {
 	struct sata_fsl_host_priv *host_priv = host->private_data;
 	void __iomem *hcr_base = host_priv->hcr_base;
+	unsigned long flags;
 
 	if (count > ICC_MAX_INT_COUNT_THRESHOLD)
 		count = ICC_MAX_INT_COUNT_THRESHOLD;
@@ -305,12 +306,12 @@ static void fsl_sata_set_irq_coalescing(
 			(count > ICC_MIN_INT_COUNT_THRESHOLD))
 		ticks = ICC_SAFE_INT_TICKS;
 
-	spin_lock(&host->lock);
+	spin_lock_irqsave(&host->lock, flags);
 	iowrite32((count << 24 | ticks), hcr_base + ICC);
 
 	intr_coalescing_count = count;
 	intr_coalescing_ticks = ticks;
-	spin_unlock(&host->lock);
+	spin_unlock_irqrestore(&host->lock, flags);
 
 	DPRINTK("interrupt coalescing, count = 0x%x, ticks = %x\n",
 			intr_coalescing_count, intr_coalescing_ticks);
@@ -1532,7 +1533,7 @@ static int sata_fsl_probe(struct platfor
 	ata_host_activate(host, irq, sata_fsl_interrupt, SATA_FSL_IRQ_FLAG,
 			  &sata_fsl_sht);
 
-	dev_set_drvdata(&ofdev->dev, host);
+	platform_set_drvdata(ofdev, host);
 
 	host_priv->intr_coalescing.show = fsl_sata_intr_coalescing_show;
 	host_priv->intr_coalescing.store = fsl_sata_intr_coalescing_store;
@@ -1558,10 +1559,8 @@ static int sata_fsl_probe(struct platfor
 
 error_exit_with_cleanup:
 
-	if (host) {
-		dev_set_drvdata(&ofdev->dev, NULL);
+	if (host)
 		ata_host_detach(host);
-	}
 
 	if (hcr_base)
 		iounmap(hcr_base);
@@ -1572,7 +1571,7 @@ error_exit_with_cleanup:
 
 static int sata_fsl_remove(struct platform_device *ofdev)
 {
-	struct ata_host *host = dev_get_drvdata(&ofdev->dev);
+	struct ata_host *host = platform_get_drvdata(ofdev);
 	struct sata_fsl_host_priv *host_priv = host->private_data;
 
 	device_remove_file(&ofdev->dev, &host_priv->intr_coalescing);
@@ -1580,8 +1579,6 @@ static int sata_fsl_remove(struct platfo
 
 	ata_host_detach(host);
 
-	dev_set_drvdata(&ofdev->dev, NULL);
-
 	irq_dispose_mapping(host_priv->irq);
 	iounmap(host_priv->hcr_base);
 	kfree(host_priv);
@@ -1592,13 +1589,13 @@ static int sata_fsl_remove(struct platfo
 #ifdef CONFIG_PM
 static int sata_fsl_suspend(struct platform_device *op, pm_message_t state)
 {
-	struct ata_host *host = dev_get_drvdata(&op->dev);
+	struct ata_host *host = platform_get_drvdata(op);
 	return ata_host_suspend(host, state);
 }
 
 static int sata_fsl_resume(struct platform_device *op)
 {
-	struct ata_host *host = dev_get_drvdata(&op->dev);
+	struct ata_host *host = platform_get_drvdata(op);
 	struct sata_fsl_host_priv *host_priv = host->private_data;
 	int ret;
 	void __iomem *hcr_base = host_priv->hcr_base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/sata_highbank.c linux-libre-3.11-rc7-gnu/drivers/ata/sata_highbank.c
--- linux-libre-3.10-gnu/drivers/ata/sata_highbank.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/sata_highbank.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,6 +33,9 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+
 #include "ahci.h"
 
 #define CPHY_MAP(dev, addr) ((((dev) & 0x1f) << 7) | (((addr) >> 9) & 0x7f))
@@ -66,6 +69,146 @@ struct phy_lane_info {
 };
 static struct phy_lane_info port_data[CPHY_PORT_COUNT];
 
+static DEFINE_SPINLOCK(sgpio_lock);
+#define SCLOCK				0
+#define SLOAD				1
+#define SDATA				2
+#define SGPIO_PINS			3
+#define SGPIO_PORTS			8
+
+/* can be cast as an ahci_host_priv for compatibility with most functions */
+struct ecx_plat_data {
+	u32		n_ports;
+	unsigned	sgpio_gpio[SGPIO_PINS];
+	u32		sgpio_pattern;
+	u32		port_to_sgpio[SGPIO_PORTS];
+};
+
+#define SGPIO_SIGNALS			3
+#define ECX_ACTIVITY_BITS		0x300000
+#define ECX_ACTIVITY_SHIFT		0
+#define ECX_LOCATE_BITS			0x80000
+#define ECX_LOCATE_SHIFT		1
+#define ECX_FAULT_BITS			0x400000
+#define ECX_FAULT_SHIFT			2
+static inline int sgpio_bit_shift(struct ecx_plat_data *pdata, u32 port,
+				u32 shift)
+{
+	return 1 << (3 * pdata->port_to_sgpio[port] + shift);
+}
+
+static void ecx_parse_sgpio(struct ecx_plat_data *pdata, u32 port, u32 state)
+{
+	if (state & ECX_ACTIVITY_BITS)
+		pdata->sgpio_pattern |= sgpio_bit_shift(pdata, port,
+						ECX_ACTIVITY_SHIFT);
+	else
+		pdata->sgpio_pattern &= ~sgpio_bit_shift(pdata, port,
+						ECX_ACTIVITY_SHIFT);
+	if (state & ECX_LOCATE_BITS)
+		pdata->sgpio_pattern |= sgpio_bit_shift(pdata, port,
+						ECX_LOCATE_SHIFT);
+	else
+		pdata->sgpio_pattern &= ~sgpio_bit_shift(pdata, port,
+						ECX_LOCATE_SHIFT);
+	if (state & ECX_FAULT_BITS)
+		pdata->sgpio_pattern |= sgpio_bit_shift(pdata, port,
+						ECX_FAULT_SHIFT);
+	else
+		pdata->sgpio_pattern &= ~sgpio_bit_shift(pdata, port,
+						ECX_FAULT_SHIFT);
+}
+
+/*
+ * Tell the LED controller that the signal has changed by raising the clock
+ * line for 50 uS and then lowering it for 50 uS.
+ */
+static void ecx_led_cycle_clock(struct ecx_plat_data *pdata)
+{
+	gpio_set_value(pdata->sgpio_gpio[SCLOCK], 1);
+	udelay(50);
+	gpio_set_value(pdata->sgpio_gpio[SCLOCK], 0);
+	udelay(50);
+}
+
+static ssize_t ecx_transmit_led_message(struct ata_port *ap, u32 state,
+					ssize_t size)
+{
+	struct ahci_host_priv *hpriv =  ap->host->private_data;
+	struct ecx_plat_data *pdata = (struct ecx_plat_data *) hpriv->plat_data;
+	struct ahci_port_priv *pp = ap->private_data;
+	unsigned long flags;
+	int pmp, i;
+	struct ahci_em_priv *emp;
+	u32 sgpio_out;
+
+	/* get the slot number from the message */
+	pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8;
+	if (pmp < EM_MAX_SLOTS)
+		emp = &pp->em_priv[pmp];
+	else
+		return -EINVAL;
+
+	if (!(hpriv->em_msg_type & EM_MSG_TYPE_LED))
+		return size;
+
+	spin_lock_irqsave(&sgpio_lock, flags);
+	ecx_parse_sgpio(pdata, ap->port_no, state);
+	sgpio_out = pdata->sgpio_pattern;
+	gpio_set_value(pdata->sgpio_gpio[SLOAD], 1);
+	ecx_led_cycle_clock(pdata);
+	gpio_set_value(pdata->sgpio_gpio[SLOAD], 0);
+	/*
+	 * bit-bang out the SGPIO pattern, by consuming a bit and then
+	 * clocking it out.
+	 */
+	for (i = 0; i < (SGPIO_SIGNALS * pdata->n_ports); i++) {
+		gpio_set_value(pdata->sgpio_gpio[SDATA], sgpio_out & 1);
+		sgpio_out >>= 1;
+		ecx_led_cycle_clock(pdata);
+	}
+
+	/* save off new led state for port/slot */
+	emp->led_state = state;
+
+	spin_unlock_irqrestore(&sgpio_lock, flags);
+	return size;
+}
+
+static void highbank_set_em_messages(struct device *dev,
+					struct ahci_host_priv *hpriv,
+					struct ata_port_info *pi)
+{
+	struct device_node *np = dev->of_node;
+	struct ecx_plat_data *pdata = hpriv->plat_data;
+	int i;
+	int err;
+
+	for (i = 0; i < SGPIO_PINS; i++) {
+		err = of_get_named_gpio(np, "calxeda,sgpio-gpio", i);
+		if (IS_ERR_VALUE(err))
+			return;
+
+		pdata->sgpio_gpio[i] = err;
+		err = gpio_request(pdata->sgpio_gpio[i], "CX SGPIO");
+		if (err) {
+			pr_err("sata_highbank gpio_request %d failed: %d\n",
+					i, err);
+			return;
+		}
+		gpio_direction_output(pdata->sgpio_gpio[i], 1);
+	}
+	of_property_read_u32_array(np, "calxeda,led-order",
+						pdata->port_to_sgpio,
+						pdata->n_ports);
+
+	/* store em_loc */
+	hpriv->em_loc = 0;
+	hpriv->em_buf_sz = 4;
+	hpriv->em_msg_type = EM_MSG_TYPE_LED;
+	pi->flags |= ATA_FLAG_EM | ATA_FLAG_SW_ACTIVITY;
+}
+
 static u32 __combo_phy_reg_read(u8 sata_port, u32 addr)
 {
 	u32 data;
@@ -196,10 +339,26 @@ static int highbank_initialize_phys(stru
 	return 0;
 }
 
+/*
+ * The Calxeda SATA phy intermittently fails to bring up a link with Gen3
+ * Retrying the phy hard reset can work around the issue, but the drive
+ * may fail again. In less than 150 out of 15000 test runs, it took more
+ * than 10 tries for the link to be established (but never more than 35).
+ * Triple the maximum observed retry count to provide plenty of margin for
+ * rare events and to guarantee that the link is established.
+ *
+ * Also, the default 2 second time-out on a failed drive is too long in
+ * this situation. The uboot implementation of the same driver function
+ * uses a much shorter time-out period and never experiences a time out
+ * issue. Reducing the time-out to 500ms improves the responsiveness.
+ * The other timing constants were kept the same as the stock AHCI driver.
+ * This change was also tested 15000 times on 24 drives and none of them
+ * experienced a time out.
+ */
 static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class,
 				unsigned long deadline)
 {
-	const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
+	static const unsigned long timing[] = { 5, 100, 500};
 	struct ata_port *ap = link->ap;
 	struct ahci_port_priv *pp = ap->private_data;
 	u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
@@ -207,7 +366,7 @@ static int ahci_highbank_hardreset(struc
 	bool online;
 	u32 sstatus;
 	int rc;
-	int retry = 10;
+	int retry = 100;
 
 	ahci_stop_engine(ap);
 
@@ -241,6 +400,7 @@ static int ahci_highbank_hardreset(struc
 static struct ata_port_operations ahci_highbank_ops = {
 	.inherits		= &ahci_ops,
 	.hardreset		= ahci_highbank_hardreset,
+	.transmit_led_message   = ecx_transmit_led_message,
 };
 
 static const struct ata_port_info ahci_highbank_port_info = {
@@ -264,12 +424,13 @@ static int ahci_highbank_probe(struct pl
 {
 	struct device *dev = &pdev->dev;
 	struct ahci_host_priv *hpriv;
+	struct ecx_plat_data *pdata;
 	struct ata_host *host;
 	struct resource *mem;
 	int irq;
-	int n_ports;
 	int i;
 	int rc;
+	u32 n_ports;
 	struct ata_port_info pi = ahci_highbank_port_info;
 	const struct ata_port_info *ppi[] = { &pi, NULL };
 
@@ -290,6 +451,11 @@ static int ahci_highbank_probe(struct pl
 		dev_err(dev, "can't alloc ahci_host_priv\n");
 		return -ENOMEM;
 	}
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "can't alloc ecx_plat_data\n");
+		return -ENOMEM;
+	}
 
 	hpriv->flags |= (unsigned long)pi.private_data;
 
@@ -313,8 +479,6 @@ static int ahci_highbank_probe(struct pl
 	if (hpriv->cap & HOST_CAP_PMP)
 		pi.flags |= ATA_FLAG_PMP;
 
-	ahci_set_em_messages(hpriv, &pi);
-
 	/* CAP.NP sometimes indicate the index of the last enabled
 	 * port, at other times, that of the last possible port, so
 	 * determining the maximum port number requires looking at
@@ -322,6 +486,10 @@ static int ahci_highbank_probe(struct pl
 	 */
 	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
 
+	pdata->n_ports = n_ports;
+	hpriv->plat_data = pdata;
+	highbank_set_em_messages(dev, hpriv, &pi);
+
 	host = ata_host_alloc_pinfo(dev, ppi, n_ports);
 	if (!host) {
 		rc = -ENOMEM;
@@ -333,9 +501,6 @@ static int ahci_highbank_probe(struct pl
 	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
 		host->flags |= ATA_HOST_PARALLEL_SCAN;
 
-	if (pi.flags & ATA_FLAG_EM)
-		ahci_reset_em(host);
-
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/sata_inic162x.c linux-libre-3.11-rc7-gnu/drivers/ata/sata_inic162x.c
--- linux-libre-3.10-gnu/drivers/ata/sata_inic162x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/sata_inic162x.c	2013-08-25 20:43:22.000000000 -0400
@@ -6,6 +6,18 @@
  *
  * This file is released under GPL v2.
  *
+ * **** WARNING ****
+ *
+ * This driver never worked properly and unfortunately data corruption is
+ * relatively common.  There isn't anyone working on the driver and there's
+ * no support from the vendor.  Do not use this driver in any production
+ * environment.
+ *
+ * http://thread.gmane.org/gmane.linux.debian.devel.bugs.rc/378525/focus=54491
+ * https://bugzilla.kernel.org/show_bug.cgi?id=60565
+ *
+ * *****************
+ *
  * This controller is eccentric and easily locks up if something isn't
  * right.  Documentation is available at initio's website but it only
  * documents registers (not programming model).
@@ -776,7 +788,7 @@ static int init_controller(void __iomem
 #ifdef CONFIG_PM
 static int inic_pci_device_resume(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	struct inic_host_priv *hpriv = host->private_data;
 	int rc;
 
@@ -807,6 +819,8 @@ static int inic_init_one(struct pci_dev
 
 	ata_print_version_once(&pdev->dev, DRV_VERSION);
 
+	dev_alert(&pdev->dev, "inic162x support is broken with common data corruption issues and will be disabled by default, contact linux-ide@vger.kernel.org if in production use\n");
+
 	/* alloc host */
 	host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS);
 	hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/sata_nv.c linux-libre-3.11-rc7-gnu/drivers/ata/sata_nv.c
--- linux-libre-3.10-gnu/drivers/ata/sata_nv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/sata_nv.c	2013-08-25 20:43:22.000000000 -0400
@@ -2435,7 +2435,7 @@ static int nv_init_one(struct pci_dev *p
 #ifdef CONFIG_PM
 static int nv_pci_device_resume(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	struct nv_host_priv *hpriv = host->private_data;
 	int rc;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/sata_rcar.c linux-libre-3.11-rc7-gnu/drivers/ata/sata_rcar.c
--- linux-libre-3.10-gnu/drivers/ata/sata_rcar.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/sata_rcar.c	2013-08-25 20:43:22.000000000 -0400
@@ -121,6 +121,8 @@
 /* Descriptor table word 0 bit (when DTA32M = 1) */
 #define SATA_RCAR_DTEND			BIT(0)
 
+#define SATA_RCAR_DMA_BOUNDARY		0x1FFFFFFEUL
+
 struct sata_rcar_priv {
 	void __iomem *base;
 	struct clk *clk;
@@ -128,41 +130,44 @@ struct sata_rcar_priv {
 
 static void sata_rcar_phy_initialize(struct sata_rcar_priv *priv)
 {
+	void __iomem *base = priv->base;
+
 	/* idle state */
-	iowrite32(0, priv->base + SATAPHYADDR_REG);
+	iowrite32(0, base + SATAPHYADDR_REG);
 	/* reset */
-	iowrite32(SATAPHYRESET_PHYRST, priv->base + SATAPHYRESET_REG);
+	iowrite32(SATAPHYRESET_PHYRST, base + SATAPHYRESET_REG);
 	udelay(10);
 	/* deassert reset */
-	iowrite32(0, priv->base + SATAPHYRESET_REG);
+	iowrite32(0, base + SATAPHYRESET_REG);
 }
 
 static void sata_rcar_phy_write(struct sata_rcar_priv *priv, u16 reg, u32 val,
 				int group)
 {
+	void __iomem *base = priv->base;
 	int timeout;
 
 	/* deassert reset */
-	iowrite32(0, priv->base + SATAPHYRESET_REG);
+	iowrite32(0, base + SATAPHYRESET_REG);
 	/* lane 1 */
-	iowrite32(SATAPHYACCEN_PHYLANE, priv->base + SATAPHYACCEN_REG);
+	iowrite32(SATAPHYACCEN_PHYLANE, base + SATAPHYACCEN_REG);
 	/* write phy register value */
-	iowrite32(val, priv->base + SATAPHYWDATA_REG);
+	iowrite32(val, base + SATAPHYWDATA_REG);
 	/* set register group */
 	if (group)
 		reg |= SATAPHYADDR_PHYRATEMODE;
 	/* write command */
-	iowrite32(SATAPHYADDR_PHYCMD_WRITE | reg, priv->base + SATAPHYADDR_REG);
+	iowrite32(SATAPHYADDR_PHYCMD_WRITE | reg, base + SATAPHYADDR_REG);
 	/* wait for ack */
 	for (timeout = 0; timeout < 100; timeout++) {
-		val = ioread32(priv->base + SATAPHYACK_REG);
+		val = ioread32(base + SATAPHYACK_REG);
 		if (val & SATAPHYACK_PHYACK)
 			break;
 	}
 	if (timeout >= 100)
 		pr_err("%s timeout\n", __func__);
 	/* idle state */
-	iowrite32(0, priv->base + SATAPHYADDR_REG);
+	iowrite32(0, base + SATAPHYADDR_REG);
 }
 
 static void sata_rcar_freeze(struct ata_port *ap)
@@ -178,14 +183,15 @@ static void sata_rcar_freeze(struct ata_
 static void sata_rcar_thaw(struct ata_port *ap)
 {
 	struct sata_rcar_priv *priv = ap->host->private_data;
+	void __iomem *base = priv->base;
 
 	/* ack */
-	iowrite32(~SATA_RCAR_INT_MASK, priv->base + SATAINTSTAT_REG);
+	iowrite32(~(u32)SATA_RCAR_INT_MASK, base + SATAINTSTAT_REG);
 
 	ata_sff_thaw(ap);
 
 	/* unmask */
-	iowrite32(0x7ff & ~SATA_RCAR_INT_MASK, priv->base + SATAINTMASK_REG);
+	iowrite32(0x7ff & ~SATA_RCAR_INT_MASK, base + SATAINTMASK_REG);
 }
 
 static void sata_rcar_ioread16_rep(void __iomem *reg, void *buffer, int count)
@@ -474,11 +480,10 @@ static void sata_rcar_bmdma_fill_sg(stru
 	struct ata_port *ap = qc->ap;
 	struct ata_bmdma_prd *prd = ap->bmdma_prd;
 	struct scatterlist *sg;
-	unsigned int si, pi;
+	unsigned int si;
 
-	pi = 0;
 	for_each_sg(qc->sg, sg, qc->n_elem, si) {
-		u32 addr, sg_len, len;
+		u32 addr, sg_len;
 
 		/*
 		 * Note: h/w doesn't support 64-bit, so we unconditionally
@@ -487,24 +492,13 @@ static void sata_rcar_bmdma_fill_sg(stru
 		addr = (u32)sg_dma_address(sg);
 		sg_len = sg_dma_len(sg);
 
-		/* H/w transfer count is only 29 bits long, let's be careful */
-		while (sg_len) {
-			len = sg_len;
-			if (len > 0x1ffffffe)
-				len = 0x1ffffffe;
-
-			prd[pi].addr = cpu_to_le32(addr);
-			prd[pi].flags_len = cpu_to_le32(len);
-			VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
-
-			pi++;
-			sg_len -= len;
-			addr += len;
-		}
+		prd[si].addr = cpu_to_le32(addr);
+		prd[si].flags_len = cpu_to_le32(sg_len);
+		VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len);
 	}
 
 	/* end-of-table flag */
-	prd[pi - 1].addr |= cpu_to_le32(SATA_RCAR_DTEND);
+	prd[si - 1].addr |= cpu_to_le32(SATA_RCAR_DTEND);
 }
 
 static void sata_rcar_qc_prep(struct ata_queued_cmd *qc)
@@ -519,15 +513,16 @@ static void sata_rcar_bmdma_setup(struct
 {
 	struct ata_port *ap = qc->ap;
 	unsigned int rw = qc->tf.flags & ATA_TFLAG_WRITE;
-	u32 dmactl;
 	struct sata_rcar_priv *priv = ap->host->private_data;
+	void __iomem *base = priv->base;
+	u32 dmactl;
 
 	/* load PRD table addr. */
 	mb();   /* make sure PRD table writes are visible to controller */
-	iowrite32(ap->bmdma_prd_dma, priv->base + ATAPI_DTB_ADR_REG);
+	iowrite32(ap->bmdma_prd_dma, base + ATAPI_DTB_ADR_REG);
 
 	/* specify data direction, triple-check start bit is clear */
-	dmactl = ioread32(priv->base + ATAPI_CONTROL1_REG);
+	dmactl = ioread32(base + ATAPI_CONTROL1_REG);
 	dmactl &= ~(ATAPI_CONTROL1_RW | ATAPI_CONTROL1_STOP);
 	if (dmactl & ATAPI_CONTROL1_START) {
 		dmactl &= ~ATAPI_CONTROL1_START;
@@ -535,7 +530,7 @@ static void sata_rcar_bmdma_setup(struct
 	}
 	if (!rw)
 		dmactl |= ATAPI_CONTROL1_RW;
-	iowrite32(dmactl, priv->base + ATAPI_CONTROL1_REG);
+	iowrite32(dmactl, base + ATAPI_CONTROL1_REG);
 
 	/* issue r/w command */
 	ap->ops->sff_exec_command(ap, &qc->tf);
@@ -544,28 +539,30 @@ static void sata_rcar_bmdma_setup(struct
 static void sata_rcar_bmdma_start(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
-	u32 dmactl;
 	struct sata_rcar_priv *priv = ap->host->private_data;
+	void __iomem *base = priv->base;
+	u32 dmactl;
 
 	/* start host DMA transaction */
-	dmactl = ioread32(priv->base + ATAPI_CONTROL1_REG);
+	dmactl = ioread32(base + ATAPI_CONTROL1_REG);
 	dmactl &= ~ATAPI_CONTROL1_STOP;
 	dmactl |= ATAPI_CONTROL1_START;
-	iowrite32(dmactl, priv->base + ATAPI_CONTROL1_REG);
+	iowrite32(dmactl, base + ATAPI_CONTROL1_REG);
 }
 
 static void sata_rcar_bmdma_stop(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
 	struct sata_rcar_priv *priv = ap->host->private_data;
+	void __iomem *base = priv->base;
 	u32 dmactl;
 
 	/* force termination of DMA transfer if active */
-	dmactl = ioread32(priv->base + ATAPI_CONTROL1_REG);
+	dmactl = ioread32(base + ATAPI_CONTROL1_REG);
 	if (dmactl & ATAPI_CONTROL1_START) {
 		dmactl &= ~ATAPI_CONTROL1_START;
 		dmactl |= ATAPI_CONTROL1_STOP;
-		iowrite32(dmactl, priv->base + ATAPI_CONTROL1_REG);
+		iowrite32(dmactl, base + ATAPI_CONTROL1_REG);
 	}
 
 	/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
@@ -575,8 +572,8 @@ static void sata_rcar_bmdma_stop(struct
 static u8 sata_rcar_bmdma_status(struct ata_port *ap)
 {
 	struct sata_rcar_priv *priv = ap->host->private_data;
-	u32 status;
 	u8 host_stat = 0;
+	u32 status;
 
 	status = ioread32(priv->base + ATAPI_STATUS_REG);
 	if (status & ATAPI_STATUS_DEVINT)
@@ -588,7 +585,14 @@ static u8 sata_rcar_bmdma_status(struct
 }
 
 static struct scsi_host_template sata_rcar_sht = {
-	ATA_BMDMA_SHT(DRV_NAME),
+	ATA_BASE_SHT(DRV_NAME),
+	/*
+	 * This controller allows transfer chunks up to 512MB which cross 64KB
+	 * boundaries, therefore the DMA limits are more relaxed than standard
+	 * ATA SFF.
+	 */
+	.sg_tablesize		= ATA_MAX_PRD,
+	.dma_boundary		= SATA_RCAR_DMA_BOUNDARY,
 };
 
 static struct ata_port_operations sata_rcar_port_ops = {
@@ -668,19 +672,20 @@ static irqreturn_t sata_rcar_interrupt(i
 {
 	struct ata_host *host = dev_instance;
 	struct sata_rcar_priv *priv = host->private_data;
-	struct ata_port *ap;
+	void __iomem *base = priv->base;
 	unsigned int handled = 0;
+	struct ata_port *ap;
 	u32 sataintstat;
 	unsigned long flags;
 
 	spin_lock_irqsave(&host->lock, flags);
 
-	sataintstat = ioread32(priv->base + SATAINTSTAT_REG);
+	sataintstat = ioread32(base + SATAINTSTAT_REG);
 	sataintstat &= SATA_RCAR_INT_MASK;
 	if (!sataintstat)
 		goto done;
 	/* ack */
-	iowrite32(~sataintstat & 0x7ff, priv->base + SATAINTSTAT_REG);
+	iowrite32(~sataintstat & 0x7ff, base + SATAINTSTAT_REG);
 
 	ap = host->ports[0];
 
@@ -702,15 +707,16 @@ static void sata_rcar_setup_port(struct
 	struct ata_port *ap = host->ports[0];
 	struct ata_ioports *ioaddr = &ap->ioaddr;
 	struct sata_rcar_priv *priv = host->private_data;
+	void __iomem *base = priv->base;
 
 	ap->ops		= &sata_rcar_port_ops;
 	ap->pio_mask	= ATA_PIO4;
 	ap->udma_mask	= ATA_UDMA6;
 	ap->flags	|= ATA_FLAG_SATA;
 
-	ioaddr->cmd_addr = priv->base + SDATA_REG;
-	ioaddr->ctl_addr = priv->base + SSDEVCON_REG;
-	ioaddr->scr_addr = priv->base + SCRSSTS_REG;
+	ioaddr->cmd_addr = base + SDATA_REG;
+	ioaddr->ctl_addr = base + SSDEVCON_REG;
+	ioaddr->scr_addr = base + SCRSSTS_REG;
 	ioaddr->altstatus_addr = ioaddr->ctl_addr;
 
 	ioaddr->data_addr	= ioaddr->cmd_addr + (ATA_REG_DATA << 2);
@@ -728,6 +734,7 @@ static void sata_rcar_setup_port(struct
 static void sata_rcar_init_controller(struct ata_host *host)
 {
 	struct sata_rcar_priv *priv = host->private_data;
+	void __iomem *base = priv->base;
 	u32 val;
 
 	/* reset and setup phy */
@@ -740,27 +747,27 @@ static void sata_rcar_init_controller(st
 	sata_rcar_phy_write(priv, SATAPCTLR4_REG, 0x28E80000, 0);
 
 	/* SATA-IP reset state */
-	val = ioread32(priv->base + ATAPI_CONTROL1_REG);
+	val = ioread32(base + ATAPI_CONTROL1_REG);
 	val |= ATAPI_CONTROL1_RESET;
-	iowrite32(val, priv->base + ATAPI_CONTROL1_REG);
+	iowrite32(val, base + ATAPI_CONTROL1_REG);
 
 	/* ISM mode, PRD mode, DTEND flag at bit 0 */
-	val = ioread32(priv->base + ATAPI_CONTROL1_REG);
+	val = ioread32(base + ATAPI_CONTROL1_REG);
 	val |= ATAPI_CONTROL1_ISM;
 	val |= ATAPI_CONTROL1_DESE;
 	val |= ATAPI_CONTROL1_DTA32M;
-	iowrite32(val, priv->base + ATAPI_CONTROL1_REG);
+	iowrite32(val, base + ATAPI_CONTROL1_REG);
 
 	/* Release the SATA-IP from the reset state */
-	val = ioread32(priv->base + ATAPI_CONTROL1_REG);
+	val = ioread32(base + ATAPI_CONTROL1_REG);
 	val &= ~ATAPI_CONTROL1_RESET;
-	iowrite32(val, priv->base + ATAPI_CONTROL1_REG);
+	iowrite32(val, base + ATAPI_CONTROL1_REG);
 
 	/* ack and mask */
-	iowrite32(0, priv->base + SATAINTSTAT_REG);
-	iowrite32(0x7ff, priv->base + SATAINTMASK_REG);
+	iowrite32(0, base + SATAINTSTAT_REG);
+	iowrite32(0x7ff, base + SATAINTMASK_REG);
 	/* enable interrupts */
-	iowrite32(ATAPI_INT_ENABLE_SATAINT, priv->base + ATAPI_INT_ENABLE_REG);
+	iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
 }
 
 static int sata_rcar_probe(struct platform_device *pdev)
@@ -825,16 +832,17 @@ cleanup:
 
 static int sata_rcar_remove(struct platform_device *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = platform_get_drvdata(pdev);
 	struct sata_rcar_priv *priv = host->private_data;
+	void __iomem *base = priv->base;
 
 	ata_host_detach(host);
 
 	/* disable interrupts */
-	iowrite32(0, priv->base + ATAPI_INT_ENABLE_REG);
+	iowrite32(0, base + ATAPI_INT_ENABLE_REG);
 	/* ack and mask */
-	iowrite32(0, priv->base + SATAINTSTAT_REG);
-	iowrite32(0x7ff, priv->base + SATAINTMASK_REG);
+	iowrite32(0, base + SATAINTSTAT_REG);
+	iowrite32(0x7ff, base + SATAINTMASK_REG);
 
 	clk_disable(priv->clk);
 
@@ -846,14 +854,15 @@ static int sata_rcar_suspend(struct devi
 {
 	struct ata_host *host = dev_get_drvdata(dev);
 	struct sata_rcar_priv *priv = host->private_data;
+	void __iomem *base = priv->base;
 	int ret;
 
 	ret = ata_host_suspend(host, PMSG_SUSPEND);
 	if (!ret) {
 		/* disable interrupts */
-		iowrite32(0, priv->base + ATAPI_INT_ENABLE_REG);
+		iowrite32(0, base + ATAPI_INT_ENABLE_REG);
 		/* mask */
-		iowrite32(0x7ff, priv->base + SATAINTMASK_REG);
+		iowrite32(0x7ff, base + SATAINTMASK_REG);
 
 		clk_disable(priv->clk);
 	}
@@ -865,14 +874,15 @@ static int sata_rcar_resume(struct devic
 {
 	struct ata_host *host = dev_get_drvdata(dev);
 	struct sata_rcar_priv *priv = host->private_data;
+	void __iomem *base = priv->base;
 
 	clk_enable(priv->clk);
 
 	/* ack and mask */
-	iowrite32(0, priv->base + SATAINTSTAT_REG);
-	iowrite32(0x7ff, priv->base + SATAINTMASK_REG);
+	iowrite32(0, base + SATAINTSTAT_REG);
+	iowrite32(0x7ff, base + SATAINTMASK_REG);
 	/* enable interrupts */
-	iowrite32(ATAPI_INT_ENABLE_SATAINT, priv->base + ATAPI_INT_ENABLE_REG);
+	iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
 
 	ata_host_resume(host);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/sata_sil24.c linux-libre-3.11-rc7-gnu/drivers/ata/sata_sil24.c
--- linux-libre-3.10-gnu/drivers/ata/sata_sil24.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/sata_sil24.c	2013-08-25 20:43:22.000000000 -0400
@@ -1353,7 +1353,7 @@ static int sil24_init_one(struct pci_dev
 #ifdef CONFIG_PM
 static int sil24_pci_device_resume(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
 	int rc;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ata/sata_sil.c linux-libre-3.11-rc7-gnu/drivers/ata/sata_sil.c
--- linux-libre-3.10-gnu/drivers/ata/sata_sil.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ata/sata_sil.c	2013-08-25 20:43:22.000000000 -0400
@@ -805,7 +805,7 @@ static int sil_init_one(struct pci_dev *
 #ifdef CONFIG_PM
 static int sil_pci_device_resume(struct pci_dev *pdev)
 {
-	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
 	rc = ata_pci_device_do_resume(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/atm/ambassador.c linux-libre-3.11-rc7-gnu/drivers/atm/ambassador.c
--- linux-libre-3.10-gnu/drivers/atm/ambassador.c	2013-07-01 10:31:34.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/atm/ambassador.c	2013-08-31 17:50:53.000000000 -0400
@@ -1403,7 +1403,7 @@ static void amb_free_rx_skb (struct atm_
   rx.host_address = cpu_to_be32 (virt_to_bus (skb->data));
   
   skb->data = skb->head;
-  skb->tail = skb->head;
+  skb_reset_tail_pointer(skb);
   skb->len = 0;
   
   if (!rx_give (dev, &rx, pool)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/attribute_container.c linux-libre-3.11-rc7-gnu/drivers/base/attribute_container.c
--- linux-libre-3.10-gnu/drivers/base/attribute_container.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/attribute_container.c	2013-08-25 20:43:22.000000000 -0400
@@ -167,7 +167,7 @@ attribute_container_add_device(struct de
 		ic->classdev.parent = get_device(dev);
 		ic->classdev.class = cont->class;
 		cont->class->dev_release = attribute_container_release;
-		dev_set_name(&ic->classdev, dev_name(dev));
+		dev_set_name(&ic->classdev, "%s", dev_name(dev));
 		if (fn)
 			fn(cont, dev, &ic->classdev);
 		else
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/core.c linux-libre-3.11-rc7-gnu/drivers/base/core.c
--- linux-libre-3.10-gnu/drivers/base/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -193,12 +193,12 @@ ssize_t device_show_bool(struct device *
 EXPORT_SYMBOL_GPL(device_show_bool);
 
 /**
- *	device_release - free device structure.
- *	@kobj:	device's kobject.
+ * device_release - free device structure.
+ * @kobj: device's kobject.
  *
- *	This is called once the reference count for the object
- *	reaches 0. We forward the call to the device's release
- *	method, which should handle actually freeing the structure.
+ * This is called once the reference count for the object
+ * reaches 0. We forward the call to the device's release
+ * method, which should handle actually freeing the structure.
  */
 static void device_release(struct kobject *kobj)
 {
@@ -403,6 +403,36 @@ static ssize_t store_uevent(struct devic
 static struct device_attribute uevent_attr =
 	__ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
 
+static ssize_t show_online(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	bool val;
+
+	lock_device_hotplug();
+	val = !dev->offline;
+	unlock_device_hotplug();
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t store_online(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	bool val;
+	int ret;
+
+	ret = strtobool(buf, &val);
+	if (ret < 0)
+		return ret;
+
+	lock_device_hotplug();
+	ret = val ? device_online(dev) : device_offline(dev);
+	unlock_device_hotplug();
+	return ret < 0 ? ret : count;
+}
+
+static struct device_attribute online_attr =
+	__ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online);
+
 static int device_add_attributes(struct device *dev,
 				 struct device_attribute *attrs)
 {
@@ -498,9 +528,12 @@ static int device_add_attrs(struct devic
 	int error;
 
 	if (class) {
-		error = device_add_attributes(dev, class->dev_attrs);
+		error = device_add_groups(dev, class->dev_groups);
 		if (error)
 			return error;
+		error = device_add_attributes(dev, class->dev_attrs);
+		if (error)
+			goto err_remove_class_groups;
 		error = device_add_bin_attributes(dev, class->dev_bin_attrs);
 		if (error)
 			goto err_remove_class_attrs;
@@ -516,6 +549,12 @@ static int device_add_attrs(struct devic
 	if (error)
 		goto err_remove_type_groups;
 
+	if (device_supports_offline(dev) && !dev->offline_disabled) {
+		error = device_create_file(dev, &online_attr);
+		if (error)
+			goto err_remove_type_groups;
+	}
+
 	return 0;
 
  err_remove_type_groups:
@@ -527,6 +566,9 @@ static int device_add_attrs(struct devic
  err_remove_class_attrs:
 	if (class)
 		device_remove_attributes(dev, class->dev_attrs);
+ err_remove_class_groups:
+	if (class)
+		device_remove_groups(dev, class->dev_groups);
 
 	return error;
 }
@@ -536,6 +578,7 @@ static void device_remove_attrs(struct d
 	struct class *class = dev->class;
 	const struct device_type *type = dev->type;
 
+	device_remove_file(dev, &online_attr);
 	device_remove_groups(dev, dev->groups);
 
 	if (type)
@@ -544,6 +587,7 @@ static void device_remove_attrs(struct d
 	if (class) {
 		device_remove_attributes(dev, class->dev_attrs);
 		device_remove_bin_attributes(dev, class->dev_bin_attrs);
+		device_remove_groups(dev, class->dev_groups);
 	}
 }
 
@@ -1334,8 +1378,8 @@ const char *device_get_devnode(struct de
 /**
  * device_for_each_child - device child iterator.
  * @parent: parent struct device.
- * @data: data for the callback.
  * @fn: function to be called for each device.
+ * @data: data for the callback.
  *
  * Iterate over @parent's child devices, and call @fn for each,
  * passing it @data.
@@ -1363,8 +1407,8 @@ int device_for_each_child(struct device
 /**
  * device_find_child - device iterator for locating a particular device.
  * @parent: parent struct device
- * @data: Data to pass to match function
  * @match: Callback function to check device
+ * @data: Data to pass to match function
  *
  * This is similar to the device_for_each_child() function above, but it
  * returns a reference to a device that is 'found' for later use, as
@@ -1374,6 +1418,8 @@ int device_for_each_child(struct device
  * if it does.  If the callback returns non-zero and a reference to the
  * current device can be obtained, this function will return to the caller
  * and not iterate over any more devices.
+ *
+ * NOTE: you will need to drop the reference with put_device() after use.
  */
 struct device *device_find_child(struct device *parent, void *data,
 				 int (*match)(struct device *dev, void *data))
@@ -1433,6 +1479,99 @@ EXPORT_SYMBOL_GPL(put_device);
 EXPORT_SYMBOL_GPL(device_create_file);
 EXPORT_SYMBOL_GPL(device_remove_file);
 
+static DEFINE_MUTEX(device_hotplug_lock);
+
+void lock_device_hotplug(void)
+{
+	mutex_lock(&device_hotplug_lock);
+}
+
+void unlock_device_hotplug(void)
+{
+	mutex_unlock(&device_hotplug_lock);
+}
+
+static int device_check_offline(struct device *dev, void *not_used)
+{
+	int ret;
+
+	ret = device_for_each_child(dev, NULL, device_check_offline);
+	if (ret)
+		return ret;
+
+	return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0;
+}
+
+/**
+ * device_offline - Prepare the device for hot-removal.
+ * @dev: Device to be put offline.
+ *
+ * Execute the device bus type's .offline() callback, if present, to prepare
+ * the device for a subsequent hot-removal.  If that succeeds, the device must
+ * not be used until either it is removed or its bus type's .online() callback
+ * is executed.
+ *
+ * Call under device_hotplug_lock.
+ */
+int device_offline(struct device *dev)
+{
+	int ret;
+
+	if (dev->offline_disabled)
+		return -EPERM;
+
+	ret = device_for_each_child(dev, NULL, device_check_offline);
+	if (ret)
+		return ret;
+
+	device_lock(dev);
+	if (device_supports_offline(dev)) {
+		if (dev->offline) {
+			ret = 1;
+		} else {
+			ret = dev->bus->offline(dev);
+			if (!ret) {
+				kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
+				dev->offline = true;
+			}
+		}
+	}
+	device_unlock(dev);
+
+	return ret;
+}
+
+/**
+ * device_online - Put the device back online after successful device_offline().
+ * @dev: Device to be put back online.
+ *
+ * If device_offline() has been successfully executed for @dev, but the device
+ * has not been removed subsequently, execute its bus type's .online() callback
+ * to indicate that the device can be used again.
+ *
+ * Call under device_hotplug_lock.
+ */
+int device_online(struct device *dev)
+{
+	int ret = 0;
+
+	device_lock(dev);
+	if (device_supports_offline(dev)) {
+		if (dev->offline) {
+			ret = dev->bus->online(dev);
+			if (!ret) {
+				kobject_uevent(&dev->kobj, KOBJ_ONLINE);
+				dev->offline = false;
+			}
+		} else {
+			ret = 1;
+		}
+	}
+	device_unlock(dev);
+
+	return ret;
+}
+
 struct root_device {
 	struct device dev;
 	struct module *owner;
@@ -1535,34 +1674,11 @@ static void device_create_release(struct
 	kfree(dev);
 }
 
-/**
- * device_create_vargs - creates a device and registers it with sysfs
- * @class: pointer to the struct class that this device should be registered to
- * @parent: pointer to the parent struct device of this new device, if any
- * @devt: the dev_t for the char device to be added
- * @drvdata: the data to be added to the device for callbacks
- * @fmt: string for the device's name
- * @args: va_list for the device's name
- *
- * This function can be used by char device classes.  A struct device
- * will be created in sysfs, registered to the specified class.
- *
- * A "dev" file will be created, showing the dev_t for the device, if
- * the dev_t is not 0,0.
- * If a pointer to a parent struct device is passed in, the newly created
- * struct device will be a child of that device in sysfs.
- * The pointer to the struct device will be returned from the call.
- * Any further sysfs files that might be required can be created using this
- * pointer.
- *
- * Returns &struct device pointer on success, or ERR_PTR() on error.
- *
- * Note: the struct class passed to this function must have previously
- * been created with a call to class_create().
- */
-struct device *device_create_vargs(struct class *class, struct device *parent,
-				   dev_t devt, void *drvdata, const char *fmt,
-				   va_list args)
+static struct device *
+device_create_groups_vargs(struct class *class, struct device *parent,
+			   dev_t devt, void *drvdata,
+			   const struct attribute_group **groups,
+			   const char *fmt, va_list args)
 {
 	struct device *dev = NULL;
 	int retval = -ENODEV;
@@ -1579,6 +1695,7 @@ struct device *device_create_vargs(struc
 	dev->devt = devt;
 	dev->class = class;
 	dev->parent = parent;
+	dev->groups = groups;
 	dev->release = device_create_release;
 	dev_set_drvdata(dev, drvdata);
 
@@ -1596,6 +1713,39 @@ error:
 	put_device(dev);
 	return ERR_PTR(retval);
 }
+
+/**
+ * device_create_vargs - creates a device and registers it with sysfs
+ * @class: pointer to the struct class that this device should be registered to
+ * @parent: pointer to the parent struct device of this new device, if any
+ * @devt: the dev_t for the char device to be added
+ * @drvdata: the data to be added to the device for callbacks
+ * @fmt: string for the device's name
+ * @args: va_list for the device's name
+ *
+ * This function can be used by char device classes.  A struct device
+ * will be created in sysfs, registered to the specified class.
+ *
+ * A "dev" file will be created, showing the dev_t for the device, if
+ * the dev_t is not 0,0.
+ * If a pointer to a parent struct device is passed in, the newly created
+ * struct device will be a child of that device in sysfs.
+ * The pointer to the struct device will be returned from the call.
+ * Any further sysfs files that might be required can be created using this
+ * pointer.
+ *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
+ * Note: the struct class passed to this function must have previously
+ * been created with a call to class_create().
+ */
+struct device *device_create_vargs(struct class *class, struct device *parent,
+				   dev_t devt, void *drvdata, const char *fmt,
+				   va_list args)
+{
+	return device_create_groups_vargs(class, parent, devt, drvdata, NULL,
+					  fmt, args);
+}
 EXPORT_SYMBOL_GPL(device_create_vargs);
 
 /**
@@ -1635,6 +1785,50 @@ struct device *device_create(struct clas
 }
 EXPORT_SYMBOL_GPL(device_create);
 
+/**
+ * device_create_with_groups - creates a device and registers it with sysfs
+ * @class: pointer to the struct class that this device should be registered to
+ * @parent: pointer to the parent struct device of this new device, if any
+ * @devt: the dev_t for the char device to be added
+ * @drvdata: the data to be added to the device for callbacks
+ * @groups: NULL-terminated list of attribute groups to be created
+ * @fmt: string for the device's name
+ *
+ * This function can be used by char device classes.  A struct device
+ * will be created in sysfs, registered to the specified class.
+ * Additional attributes specified in the groups parameter will also
+ * be created automatically.
+ *
+ * A "dev" file will be created, showing the dev_t for the device, if
+ * the dev_t is not 0,0.
+ * If a pointer to a parent struct device is passed in, the newly created
+ * struct device will be a child of that device in sysfs.
+ * The pointer to the struct device will be returned from the call.
+ * Any further sysfs files that might be required can be created using this
+ * pointer.
+ *
+ * Returns &struct device pointer on success, or ERR_PTR() on error.
+ *
+ * Note: the struct class passed to this function must have previously
+ * been created with a call to class_create().
+ */
+struct device *device_create_with_groups(struct class *class,
+					 struct device *parent, dev_t devt,
+					 void *drvdata,
+					 const struct attribute_group **groups,
+					 const char *fmt, ...)
+{
+	va_list vargs;
+	struct device *dev;
+
+	va_start(vargs, fmt);
+	dev = device_create_groups_vargs(class, parent, devt, drvdata, groups,
+					 fmt, vargs);
+	va_end(vargs);
+	return dev;
+}
+EXPORT_SYMBOL_GPL(device_create_with_groups);
+
 static int __match_devt(struct device *dev, const void *data)
 {
 	const dev_t *devt = data;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/cpu.c linux-libre-3.11-rc7-gnu/drivers/base/cpu.c
--- linux-libre-3.10-gnu/drivers/base/cpu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/cpu.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,17 +13,21 @@
 #include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/percpu.h>
+#include <linux/acpi.h>
 
 #include "base.h"
 
-struct bus_type cpu_subsys = {
-	.name = "cpu",
-	.dev_name = "cpu",
-};
-EXPORT_SYMBOL_GPL(cpu_subsys);
-
 static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
 
+static int cpu_subsys_match(struct device *dev, struct device_driver *drv)
+{
+	/* ACPI style match is the only one that may succeed. */
+	if (acpi_driver_match_device(dev, drv))
+		return 1;
+
+	return 0;
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 static void change_cpu_under_node(struct cpu *cpu,
 			unsigned int from_nid, unsigned int to_nid)
@@ -34,69 +38,45 @@ static void change_cpu_under_node(struct
 	cpu->node_id = to_nid;
 }
 
-static ssize_t show_online(struct device *dev,
-			   struct device_attribute *attr,
-			   char *buf)
-{
-	struct cpu *cpu = container_of(dev, struct cpu, dev);
-
-	return sprintf(buf, "%u\n", !!cpu_online(cpu->dev.id));
-}
-
-static ssize_t __ref store_online(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf, size_t count)
+static int __ref cpu_subsys_online(struct device *dev)
 {
 	struct cpu *cpu = container_of(dev, struct cpu, dev);
-	int cpuid = cpu->dev.id;
+	int cpuid = dev->id;
 	int from_nid, to_nid;
-	ssize_t ret;
+	int ret;
 
 	cpu_hotplug_driver_lock();
-	switch (buf[0]) {
-	case '0':
-		ret = cpu_down(cpuid);
-		if (!ret)
-			kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
-		break;
-	case '1':
-		from_nid = cpu_to_node(cpuid);
-		ret = cpu_up(cpuid);
 
-		/*
-		 * When hot adding memory to memoryless node and enabling a cpu
-		 * on the node, node number of the cpu may internally change.
-		 */
-		to_nid = cpu_to_node(cpuid);
-		if (from_nid != to_nid)
-			change_cpu_under_node(cpu, from_nid, to_nid);
+	from_nid = cpu_to_node(cpuid);
+	ret = cpu_up(cpuid);
+	/*
+	 * When hot adding memory to memoryless node and enabling a cpu
+	 * on the node, node number of the cpu may internally change.
+	 */
+	to_nid = cpu_to_node(cpuid);
+	if (from_nid != to_nid)
+		change_cpu_under_node(cpu, from_nid, to_nid);
 
-		if (!ret)
-			kobject_uevent(&dev->kobj, KOBJ_ONLINE);
-		break;
-	default:
-		ret = -EINVAL;
-	}
 	cpu_hotplug_driver_unlock();
-
-	if (ret >= 0)
-		ret = count;
 	return ret;
 }
-static DEVICE_ATTR(online, 0644, show_online, store_online);
 
-static void __cpuinit register_cpu_control(struct cpu *cpu)
+static int cpu_subsys_offline(struct device *dev)
 {
-	device_create_file(&cpu->dev, &dev_attr_online);
+	int ret;
+
+	cpu_hotplug_driver_lock();
+	ret = cpu_down(dev->id);
+	cpu_hotplug_driver_unlock();
+	return ret;
 }
+
 void unregister_cpu(struct cpu *cpu)
 {
 	int logical_cpu = cpu->dev.id;
 
 	unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
 
-	device_remove_file(&cpu->dev, &dev_attr_online);
-
 	device_unregister(&cpu->dev);
 	per_cpu(cpu_sys_devices, logical_cpu) = NULL;
 	return;
@@ -122,13 +102,19 @@ static ssize_t cpu_release_store(struct
 static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
 static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
-
-#else /* ... !CONFIG_HOTPLUG_CPU */
-static inline void register_cpu_control(struct cpu *cpu)
-{
-}
 #endif /* CONFIG_HOTPLUG_CPU */
 
+struct bus_type cpu_subsys = {
+	.name = "cpu",
+	.dev_name = "cpu",
+	.match = cpu_subsys_match,
+#ifdef CONFIG_HOTPLUG_CPU
+	.online = cpu_subsys_online,
+	.offline = cpu_subsys_offline,
+#endif
+};
+EXPORT_SYMBOL_GPL(cpu_subsys);
+
 #ifdef CONFIG_KEXEC
 #include <linux/kexec.h>
 
@@ -164,7 +150,31 @@ static ssize_t show_crash_notes_size(str
 	return rc;
 }
 static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL);
+
+static struct attribute *crash_note_cpu_attrs[] = {
+	&dev_attr_crash_notes.attr,
+	&dev_attr_crash_notes_size.attr,
+	NULL
+};
+
+static struct attribute_group crash_note_cpu_attr_group = {
+	.attrs = crash_note_cpu_attrs,
+};
+#endif
+
+static const struct attribute_group *common_cpu_attr_groups[] = {
+#ifdef CONFIG_KEXEC
+	&crash_note_cpu_attr_group,
 #endif
+	NULL
+};
+
+static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
+#ifdef CONFIG_KEXEC
+	&crash_note_cpu_attr_group,
+#endif
+	NULL
+};
 
 /*
  * Print cpu online, possible, present, and system maps
@@ -268,7 +278,7 @@ static void cpu_device_release(struct de
  *
  * Initialize and register the CPU device.
  */
-int __cpuinit register_cpu(struct cpu *cpu, int num)
+int register_cpu(struct cpu *cpu, int num)
 {
 	int error;
 
@@ -277,24 +287,20 @@ int __cpuinit register_cpu(struct cpu *c
 	cpu->dev.id = num;
 	cpu->dev.bus = &cpu_subsys;
 	cpu->dev.release = cpu_device_release;
+	cpu->dev.offline_disabled = !cpu->hotpluggable;
+	cpu->dev.offline = !cpu_online(num);
 #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
 	cpu->dev.bus->uevent = arch_cpu_uevent;
 #endif
+	cpu->dev.groups = common_cpu_attr_groups;
+	if (cpu->hotpluggable)
+		cpu->dev.groups = hotplugable_cpu_attr_groups;
 	error = device_register(&cpu->dev);
-	if (!error && cpu->hotpluggable)
-		register_cpu_control(cpu);
 	if (!error)
 		per_cpu(cpu_sys_devices, num) = &cpu->dev;
 	if (!error)
 		register_cpu_under_node(num, cpu_to_node(num));
 
-#ifdef CONFIG_KEXEC
-	if (!error)
-		error = device_create_file(&cpu->dev, &dev_attr_crash_notes);
-	if (!error)
-		error = device_create_file(&cpu->dev,
-					   &dev_attr_crash_notes_size);
-#endif
 	return error;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/dma-buf.c linux-libre-3.11-rc7-gnu/drivers/base/dma-buf.c
--- linux-libre-3.10-gnu/drivers/base/dma-buf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/dma-buf.c	2013-08-25 20:43:22.000000000 -0400
@@ -680,10 +680,7 @@ int dma_buf_debugfs_create_file(const ch
 	d = debugfs_create_file(name, S_IRUGO, dma_buf_debugfs_dir,
 			write, &dma_buf_debug_fops);
 
-	if (IS_ERR(d))
-		return PTR_ERR(d);
-
-	return 0;
+	return PTR_RET(d);
 }
 #else
 static inline int dma_buf_init_debugfs(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/firmware_class.c linux-libre-3.11-rc7-gnu/drivers/base/firmware_class.c
--- linux-libre-3.10-gnu/drivers/base/firmware_class.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/firmware_class.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/pm.h>
 #include <linux/suspend.h>
 #include <linux/syscore_ops.h>
+#include <linux/reboot.h>
 
 #include <generated/utsrelease.h>
 
@@ -127,9 +128,11 @@ struct firmware_buf {
 	size_t size;
 #ifdef CONFIG_FW_LOADER_USER_HELPER
 	bool is_paged_buf;
+	bool need_uevent;
 	struct page **pages;
 	int nr_pages;
 	int page_array_size;
+	struct list_head pending_list;
 #endif
 	char fw_id[];
 };
@@ -171,6 +174,9 @@ static struct firmware_buf *__allocate_f
 	strcpy(buf->fw_id, fw_name);
 	buf->fwc = fwc;
 	init_completion(&buf->completion);
+#ifdef CONFIG_FW_LOADER_USER_HELPER
+	INIT_LIST_HEAD(&buf->pending_list);
+#endif
 
 	pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf);
 
@@ -212,18 +218,6 @@ static int fw_lookup_and_allocate_buf(co
 	return tmp ? 0 : -ENOMEM;
 }
 
-static struct firmware_buf *fw_lookup_buf(const char *fw_name)
-{
-	struct firmware_buf *tmp;
-	struct firmware_cache *fwc = &fw_cache;
-
-	spin_lock(&fwc->lock);
-	tmp = __fw_lookup_buf(fw_name);
-	spin_unlock(&fwc->lock);
-
-	return tmp;
-}
-
 static void __fw_free_buf(struct kref *ref)
 {
 	struct firmware_buf *buf = to_fwbuf(ref);
@@ -446,10 +440,8 @@ static struct firmware_priv *to_firmware
 	return container_of(dev, struct firmware_priv, dev);
 }
 
-static void fw_load_abort(struct firmware_priv *fw_priv)
+static void __fw_load_abort(struct firmware_buf *buf)
 {
-	struct firmware_buf *buf = fw_priv->buf;
-
 	/*
 	 * There is a small window in which user can write to 'loading'
 	 * between loading done and disappearance of 'loading'
@@ -457,8 +449,16 @@ static void fw_load_abort(struct firmwar
 	if (test_bit(FW_STATUS_DONE, &buf->status))
 		return;
 
+	list_del_init(&buf->pending_list);
 	set_bit(FW_STATUS_ABORT, &buf->status);
 	complete_all(&buf->completion);
+}
+
+static void fw_load_abort(struct firmware_priv *fw_priv)
+{
+	struct firmware_buf *buf = fw_priv->buf;
+
+	__fw_load_abort(buf);
 
 	/* avoid user action after loading abort */
 	fw_priv->buf = NULL;
@@ -467,6 +467,25 @@ static void fw_load_abort(struct firmwar
 #define is_fw_load_aborted(buf)	\
 	test_bit(FW_STATUS_ABORT, &(buf)->status)
 
+static LIST_HEAD(pending_fw_head);
+
+/* reboot notifier for avoid deadlock with usermode_lock */
+static int fw_shutdown_notify(struct notifier_block *unused1,
+			      unsigned long unused2, void *unused3)
+{
+	mutex_lock(&fw_lock);
+	while (!list_empty(&pending_fw_head))
+		__fw_load_abort(list_first_entry(&pending_fw_head,
+					       struct firmware_buf,
+					       pending_list));
+	mutex_unlock(&fw_lock);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block fw_shutdown_nb = {
+	.notifier_call = fw_shutdown_notify,
+};
+
 static ssize_t firmware_timeout_show(struct class *class,
 				     struct class_attribute *attr,
 				     char *buf)
@@ -509,8 +528,6 @@ static void fw_dev_release(struct device
 	struct firmware_priv *fw_priv = to_firmware_priv(dev);
 
 	kfree(fw_priv);
-
-	module_put(THIS_MODULE);
 }
 
 static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
@@ -619,6 +636,7 @@ static ssize_t firmware_loading_store(st
 			 * is completed.
 			 * */
 			fw_map_pages_buf(fw_buf);
+			list_del_init(&fw_buf->pending_list);
 			complete_all(&fw_buf->completion);
 			break;
 		}
@@ -838,9 +856,6 @@ static int _request_firmware_load(struct
 
 	dev_set_uevent_suppress(f_dev, true);
 
-	/* Need to pin this module until class device is destroyed */
-	__module_get(THIS_MODULE);
-
 	retval = device_add(f_dev);
 	if (retval) {
 		dev_err(f_dev, "%s: device_register failed\n", __func__);
@@ -860,6 +875,7 @@ static int _request_firmware_load(struct
 	}
 
 	if (uevent) {
+		buf->need_uevent = true;
 		dev_set_uevent_suppress(f_dev, false);
 		dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id);
 		if (timeout != MAX_SCHEDULE_TIMEOUT)
@@ -868,6 +884,10 @@ static int _request_firmware_load(struct
 		kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
 	}
 
+	mutex_lock(&fw_lock);
+	list_add(&buf->pending_list, &pending_fw_head);
+	mutex_unlock(&fw_lock);
+
 	wait_for_completion(&buf->completion);
 
 	cancel_delayed_work_sync(&fw_priv->timeout_work);
@@ -895,6 +915,23 @@ static int fw_load_from_user_helper(stru
 	fw_priv->buf = firmware->priv;
 	return _request_firmware_load(fw_priv, uevent, timeout);
 }
+
+#ifdef CONFIG_PM_SLEEP
+/* kill pending requests without uevent to avoid blocking suspend */
+static void kill_requests_without_uevent(void)
+{
+	struct firmware_buf *buf;
+	struct firmware_buf *next;
+
+	mutex_lock(&fw_lock);
+	list_for_each_entry_safe(buf, next, &pending_fw_head, pending_list) {
+		if (!buf->need_uevent)
+			 __fw_load_abort(buf);
+	}
+	mutex_unlock(&fw_lock);
+}
+#endif
+
 #else /* CONFIG_FW_LOADER_USER_HELPER */
 static inline int
 fw_load_from_user_helper(struct firmware *firmware, const char *name,
@@ -907,6 +944,10 @@ fw_load_from_user_helper(struct firmware
 /* No abort during direct loading */
 #define is_fw_load_aborted(buf) false
 
+#ifdef CONFIG_PM_SLEEP
+static inline void kill_requests_without_uevent(void) { }
+#endif
+
 #endif /* CONFIG_FW_LOADER_USER_HELPER */
 
 
@@ -974,7 +1015,8 @@ _request_firmware_prepare(struct firmwar
 	return 1; /* need to load */
 }
 
-static int assign_firmware_buf(struct firmware *fw, struct device *device)
+static int assign_firmware_buf(struct firmware *fw, struct device *device,
+				bool skip_cache)
 {
 	struct firmware_buf *buf = fw->priv;
 
@@ -991,7 +1033,7 @@ static int assign_firmware_buf(struct fi
 	 * device may has been deleted already, but the problem
 	 * should be fixed in devres or driver core.
 	 */
-	if (device)
+	if (device && !skip_cache)
 		fw_add_devm_name(device, buf->fw_id);
 
 	/*
@@ -1047,8 +1089,10 @@ _request_firmware(const struct firmware
 	if (!fw_get_filesystem_firmware(device, fw->priv))
 		ret = fw_load_from_user_helper(fw, name, device,
 					       uevent, nowait, timeout);
+
+	/* don't cache firmware handled without uevent */
 	if (!ret)
-		ret = assign_firmware_buf(fw, device);
+		ret = assign_firmware_buf(fw, device, !uevent);
 
 	usermodehelper_read_unlock();
 
@@ -1086,8 +1130,15 @@ int
 request_firmware(const struct firmware **firmware_p, const char *name,
                  struct device *device)
 {
-	return _request_firmware(firmware_p, name, device, true, false);
+	int ret;
+
+	/* Need to pin this module until return */
+	__module_get(THIS_MODULE);
+	ret = _request_firmware(firmware_p, name, device, true, false);
+	module_put(THIS_MODULE);
+	return ret;
 }
+EXPORT_SYMBOL(request_firmware);
 
 /**
  * release_firmware: - release the resource associated with a firmware image
@@ -1101,6 +1152,7 @@ void release_firmware(const struct firmw
 		kfree(fw);
 	}
 }
+EXPORT_SYMBOL(release_firmware);
 
 /* Async support */
 struct firmware_work {
@@ -1181,6 +1233,10 @@ request_firmware_nowait(
 	schedule_work(&fw_work->work);
 	return 0;
 }
+EXPORT_SYMBOL(request_firmware_nowait);
+
+#ifdef CONFIG_PM_SLEEP
+static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
 
 /**
  * cache_firmware - cache one firmware image in kernel memory space
@@ -1196,7 +1252,7 @@ request_firmware_nowait(
  * Return !0 otherwise
  *
  */
-int cache_firmware(const char *fw_name)
+static int cache_firmware(const char *fw_name)
 {
 	int ret;
 	const struct firmware *fw;
@@ -1212,6 +1268,18 @@ int cache_firmware(const char *fw_name)
 	return ret;
 }
 
+static struct firmware_buf *fw_lookup_buf(const char *fw_name)
+{
+	struct firmware_buf *tmp;
+	struct firmware_cache *fwc = &fw_cache;
+
+	spin_lock(&fwc->lock);
+	tmp = __fw_lookup_buf(fw_name);
+	spin_unlock(&fwc->lock);
+
+	return tmp;
+}
+
 /**
  * uncache_firmware - remove one cached firmware image
  * @fw_name: the firmware image name
@@ -1223,7 +1291,7 @@ int cache_firmware(const char *fw_name)
  * Return !0 otherwise
  *
  */
-int uncache_firmware(const char *fw_name)
+static int uncache_firmware(const char *fw_name)
 {
 	struct firmware_buf *buf;
 	struct firmware fw;
@@ -1242,9 +1310,6 @@ int uncache_firmware(const char *fw_name
 	return -EINVAL;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
-
 static struct fw_cache_entry *alloc_fw_cache_entry(const char *name)
 {
 	struct fw_cache_entry *fce;
@@ -1464,6 +1529,7 @@ static int fw_pm_notify(struct notifier_
 	switch (mode) {
 	case PM_HIBERNATION_PREPARE:
 	case PM_SUSPEND_PREPARE:
+		kill_requests_without_uevent();
 		device_cache_fw_images();
 		break;
 
@@ -1526,6 +1592,7 @@ static int __init firmware_class_init(vo
 {
 	fw_cache_init();
 #ifdef CONFIG_FW_LOADER_USER_HELPER
+	register_reboot_notifier(&fw_shutdown_nb);
 	return class_register(&firmware_class);
 #else
 	return 0;
@@ -1539,15 +1606,10 @@ static void __exit firmware_class_exit(v
 	unregister_pm_notifier(&fw_cache.pm_notify);
 #endif
 #ifdef CONFIG_FW_LOADER_USER_HELPER
+	unregister_reboot_notifier(&fw_shutdown_nb);
 	class_unregister(&firmware_class);
 #endif
 }
 
 fs_initcall(firmware_class_init);
 module_exit(firmware_class_exit);
-
-EXPORT_SYMBOL(release_firmware);
-EXPORT_SYMBOL(request_firmware);
-EXPORT_SYMBOL(request_firmware_nowait);
-EXPORT_SYMBOL_GPL(cache_firmware);
-EXPORT_SYMBOL_GPL(uncache_firmware);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/Kconfig linux-libre-3.11-rc7-gnu/drivers/base/Kconfig
--- linux-libre-3.10-gnu/drivers/base/Kconfig	2013-07-01 10:45:40.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/Kconfig	2013-08-31 18:05:29.000000000 -0400
@@ -2,7 +2,6 @@ menu "Generic Driver Options"
 
 config UEVENT_HELPER_PATH
 	string "path to uevent helper"
-	depends on HOTPLUG
 	default ""
 	help
 	  Path to uevent helper program forked by the kernel for
@@ -23,7 +22,6 @@ config UEVENT_HELPER_PATH
 
 config DEVTMPFS
 	bool "Maintain a devtmpfs filesystem to mount at /dev"
-	depends on HOTPLUG
 	help
 	  This creates a tmpfs/ramfs filesystem instance early at bootup.
 	  In this filesystem, the kernel driver core maintains device
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/Makefile linux-libre-3.11-rc7-gnu/drivers/base/Makefile
--- linux-libre-3.10-gnu/drivers/base/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,7 @@ obj-$(CONFIG_CMA) += dma-contiguous.o
 obj-y			+= power/
 obj-$(CONFIG_HAS_DMA)	+= dma-mapping.o
 obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
-obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o
+obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf.o reservation.o
 obj-$(CONFIG_ISA)	+= isa.o
 obj-$(CONFIG_FW_LOADER)	+= firmware_class.o
 obj-$(CONFIG_NUMA)	+= node.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/memory.c linux-libre-3.11-rc7-gnu/drivers/base/memory.c
--- linux-libre-3.10-gnu/drivers/base/memory.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/memory.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,9 +37,14 @@ static inline int base_memory_block_id(i
 	return section_nr / sections_per_block;
 }
 
+static int memory_subsys_online(struct device *dev);
+static int memory_subsys_offline(struct device *dev);
+
 static struct bus_type memory_subsys = {
 	.name = MEMORY_CLASS_NAME,
 	.dev_name = MEMORY_CLASS_NAME,
+	.online = memory_subsys_online,
+	.offline = memory_subsys_offline,
 };
 
 static BLOCKING_NOTIFIER_HEAD(memory_chain);
@@ -77,22 +82,6 @@ static void memory_block_release(struct
 	kfree(mem);
 }
 
-/*
- * register_memory - Setup a sysfs device for a memory block
- */
-static
-int register_memory(struct memory_block *memory)
-{
-	int error;
-
-	memory->dev.bus = &memory_subsys;
-	memory->dev.id = memory->start_section_nr / sections_per_block;
-	memory->dev.release = memory_block_release;
-
-	error = device_register(&memory->dev);
-	return error;
-}
-
 unsigned long __weak memory_block_size_bytes(void)
 {
 	return MIN_MEMORY_BLOCK_SIZE;
@@ -278,33 +267,64 @@ static int __memory_block_change_state(s
 {
 	int ret = 0;
 
-	if (mem->state != from_state_req) {
-		ret = -EINVAL;
-		goto out;
-	}
+	if (mem->state != from_state_req)
+		return -EINVAL;
 
 	if (to_state == MEM_OFFLINE)
 		mem->state = MEM_GOING_OFFLINE;
 
 	ret = memory_block_action(mem->start_section_nr, to_state, online_type);
+	mem->state = ret ? from_state_req : to_state;
+	return ret;
+}
 
-	if (ret) {
-		mem->state = from_state_req;
-		goto out;
-	}
+static int memory_subsys_online(struct device *dev)
+{
+	struct memory_block *mem = container_of(dev, struct memory_block, dev);
+	int ret;
 
-	mem->state = to_state;
-	switch (mem->state) {
-	case MEM_OFFLINE:
-		kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE);
-		break;
-	case MEM_ONLINE:
-		kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE);
-		break;
-	default:
-		break;
+	mutex_lock(&mem->state_mutex);
+
+	ret = mem->state == MEM_ONLINE ? 0 :
+		__memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE,
+					    ONLINE_KEEP);
+
+	mutex_unlock(&mem->state_mutex);
+	return ret;
+}
+
+static int memory_subsys_offline(struct device *dev)
+{
+	struct memory_block *mem = container_of(dev, struct memory_block, dev);
+	int ret;
+
+	mutex_lock(&mem->state_mutex);
+
+	ret = mem->state == MEM_OFFLINE ? 0 :
+		__memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
+
+	mutex_unlock(&mem->state_mutex);
+	return ret;
+}
+
+static int __memory_block_change_state_uevent(struct memory_block *mem,
+		unsigned long to_state, unsigned long from_state_req,
+		int online_type)
+{
+	int ret = __memory_block_change_state(mem, to_state, from_state_req,
+					      online_type);
+	if (!ret) {
+		switch (mem->state) {
+		case MEM_OFFLINE:
+			kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE);
+			break;
+		case MEM_ONLINE:
+			kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE);
+			break;
+		default:
+			break;
+		}
 	}
-out:
 	return ret;
 }
 
@@ -315,8 +335,8 @@ static int memory_block_change_state(str
 	int ret;
 
 	mutex_lock(&mem->state_mutex);
-	ret = __memory_block_change_state(mem, to_state, from_state_req,
-					  online_type);
+	ret = __memory_block_change_state_uevent(mem, to_state, from_state_req,
+						 online_type);
 	mutex_unlock(&mem->state_mutex);
 
 	return ret;
@@ -326,22 +346,34 @@ store_mem_state(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct memory_block *mem;
+	bool offline;
 	int ret = -EINVAL;
 
 	mem = container_of(dev, struct memory_block, dev);
 
-	if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
+	lock_device_hotplug();
+
+	if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) {
+		offline = false;
 		ret = memory_block_change_state(mem, MEM_ONLINE,
 						MEM_OFFLINE, ONLINE_KERNEL);
-	else if (!strncmp(buf, "online_movable", min_t(int, count, 14)))
+	} else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) {
+		offline = false;
 		ret = memory_block_change_state(mem, MEM_ONLINE,
 						MEM_OFFLINE, ONLINE_MOVABLE);
-	else if (!strncmp(buf, "online", min_t(int, count, 6)))
+	} else if (!strncmp(buf, "online", min_t(int, count, 6))) {
+		offline = false;
 		ret = memory_block_change_state(mem, MEM_ONLINE,
 						MEM_OFFLINE, ONLINE_KEEP);
-	else if(!strncmp(buf, "offline", min_t(int, count, 7)))
+	} else if(!strncmp(buf, "offline", min_t(int, count, 7))) {
+		offline = true;
 		ret = memory_block_change_state(mem, MEM_OFFLINE,
 						MEM_ONLINE, -1);
+	}
+	if (!ret)
+		dev->offline = offline;
+
+	unlock_device_hotplug();
 
 	if (ret)
 		return ret;
@@ -371,11 +403,6 @@ static DEVICE_ATTR(state, 0644, show_mem
 static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL);
 static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL);
 
-#define mem_create_simple_file(mem, attr_name)	\
-	device_create_file(&mem->dev, &dev_attr_##attr_name)
-#define mem_remove_simple_file(mem, attr_name)	\
-	device_remove_file(&mem->dev, &dev_attr_##attr_name)
-
 /*
  * Block size attribute stuff
  */
@@ -388,12 +415,6 @@ print_block_size(struct device *dev, str
 
 static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL);
 
-static int block_size_init(void)
-{
-	return device_create_file(memory_subsys.dev_root,
-				  &dev_attr_block_size_bytes);
-}
-
 /*
  * Some architectures will have custom drivers to do this, and
  * will not need to do it from userspace.  The fake hot-add code
@@ -429,17 +450,8 @@ memory_probe_store(struct device *dev, s
 out:
 	return ret;
 }
-static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
 
-static int memory_probe_init(void)
-{
-	return device_create_file(memory_subsys.dev_root, &dev_attr_probe);
-}
-#else
-static inline int memory_probe_init(void)
-{
-	return 0;
-}
+static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
 #endif
 
 #ifdef CONFIG_MEMORY_FAILURE
@@ -485,23 +497,6 @@ store_hard_offline_page(struct device *d
 
 static DEVICE_ATTR(soft_offline_page, S_IWUSR, NULL, store_soft_offline_page);
 static DEVICE_ATTR(hard_offline_page, S_IWUSR, NULL, store_hard_offline_page);
-
-static __init int memory_fail_init(void)
-{
-	int err;
-
-	err = device_create_file(memory_subsys.dev_root,
-				&dev_attr_soft_offline_page);
-	if (!err)
-		err = device_create_file(memory_subsys.dev_root,
-				&dev_attr_hard_offline_page);
-	return err;
-}
-#else
-static inline int memory_fail_init(void)
-{
-	return 0;
-}
 #endif
 
 /*
@@ -546,6 +541,42 @@ struct memory_block *find_memory_block(s
 	return find_memory_block_hinted(section, NULL);
 }
 
+static struct attribute *memory_memblk_attrs[] = {
+	&dev_attr_phys_index.attr,
+	&dev_attr_end_phys_index.attr,
+	&dev_attr_state.attr,
+	&dev_attr_phys_device.attr,
+	&dev_attr_removable.attr,
+	NULL
+};
+
+static struct attribute_group memory_memblk_attr_group = {
+	.attrs = memory_memblk_attrs,
+};
+
+static const struct attribute_group *memory_memblk_attr_groups[] = {
+	&memory_memblk_attr_group,
+	NULL,
+};
+
+/*
+ * register_memory - Setup a sysfs device for a memory block
+ */
+static
+int register_memory(struct memory_block *memory)
+{
+	int error;
+
+	memory->dev.bus = &memory_subsys;
+	memory->dev.id = memory->start_section_nr / sections_per_block;
+	memory->dev.release = memory_block_release;
+	memory->dev.groups = memory_memblk_attr_groups;
+	memory->dev.offline = memory->state == MEM_OFFLINE;
+
+	error = device_register(&memory->dev);
+	return error;
+}
+
 static int init_memory_block(struct memory_block **memory,
 			     struct mem_section *section, unsigned long state)
 {
@@ -569,16 +600,6 @@ static int init_memory_block(struct memo
 	mem->phys_device = arch_get_memory_phys_device(start_pfn);
 
 	ret = register_memory(mem);
-	if (!ret)
-		ret = mem_create_simple_file(mem, phys_index);
-	if (!ret)
-		ret = mem_create_simple_file(mem, end_phys_index);
-	if (!ret)
-		ret = mem_create_simple_file(mem, state);
-	if (!ret)
-		ret = mem_create_simple_file(mem, phys_device);
-	if (!ret)
-		ret = mem_create_simple_file(mem, removable);
 
 	*memory = mem;
 	return ret;
@@ -656,14 +677,9 @@ static int remove_memory_block(unsigned
 	unregister_mem_sect_under_nodes(mem, __section_nr(section));
 
 	mem->section_count--;
-	if (mem->section_count == 0) {
-		mem_remove_simple_file(mem, phys_index);
-		mem_remove_simple_file(mem, end_phys_index);
-		mem_remove_simple_file(mem, state);
-		mem_remove_simple_file(mem, phys_device);
-		mem_remove_simple_file(mem, removable);
+	if (mem->section_count == 0)
 		unregister_memory(mem);
-	} else
+	else
 		kobject_put(&mem->dev.kobj);
 
 	mutex_unlock(&mem_sysfs_mutex);
@@ -679,27 +695,35 @@ int unregister_memory_section(struct mem
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
-/*
- * offline one memory block. If the memory block has been offlined, do nothing.
- */
-int offline_memory_block(struct memory_block *mem)
-{
-	int ret = 0;
-
-	mutex_lock(&mem->state_mutex);
-	if (mem->state != MEM_OFFLINE)
-		ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
-	mutex_unlock(&mem->state_mutex);
-
-	return ret;
-}
-
 /* return true if the memory block is offlined, otherwise, return false */
 bool is_memblock_offlined(struct memory_block *mem)
 {
 	return mem->state == MEM_OFFLINE;
 }
 
+static struct attribute *memory_root_attrs[] = {
+#ifdef CONFIG_ARCH_MEMORY_PROBE
+	&dev_attr_probe.attr,
+#endif
+
+#ifdef CONFIG_MEMORY_FAILURE
+	&dev_attr_soft_offline_page.attr,
+	&dev_attr_hard_offline_page.attr,
+#endif
+
+	&dev_attr_block_size_bytes.attr,
+	NULL
+};
+
+static struct attribute_group memory_root_attr_group = {
+	.attrs = memory_root_attrs,
+};
+
+static const struct attribute_group *memory_root_attr_groups[] = {
+	&memory_root_attr_group,
+	NULL,
+};
+
 /*
  * Initialize the sysfs support for memory devices...
  */
@@ -711,7 +735,7 @@ int __init memory_dev_init(void)
 	unsigned long block_sz;
 	struct memory_block *mem = NULL;
 
-	ret = subsys_system_register(&memory_subsys, NULL);
+	ret = subsys_system_register(&memory_subsys, memory_root_attr_groups);
 	if (ret)
 		goto out;
 
@@ -734,15 +758,6 @@ int __init memory_dev_init(void)
 			ret = err;
 	}
 
-	err = memory_probe_init();
-	if (!ret)
-		ret = err;
-	err = memory_fail_init();
-	if (!ret)
-		ret = err;
-	err = block_size_init();
-	if (!ret)
-		ret = err;
 out:
 	if (ret)
 		printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/pinctrl.c linux-libre-3.11-rc7-gnu/drivers/base/pinctrl.c
--- linux-libre-3.10-gnu/drivers/base/pinctrl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/pinctrl.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,6 +48,25 @@ int pinctrl_bind_pins(struct device *dev
 		goto cleanup_get;
 	}
 
+#ifdef CONFIG_PM
+	/*
+	 * If power management is enabled, we also look for the optional
+	 * sleep and idle pin states, with semantics as defined in
+	 * <linux/pinctrl/pinctrl-state.h>
+	 */
+	dev->pins->sleep_state = pinctrl_lookup_state(dev->pins->p,
+					PINCTRL_STATE_SLEEP);
+	if (IS_ERR(dev->pins->sleep_state))
+		/* Not supplying this state is perfectly legal */
+		dev_dbg(dev, "no sleep pinctrl state\n");
+
+	dev->pins->idle_state = pinctrl_lookup_state(dev->pins->p,
+					PINCTRL_STATE_IDLE);
+	if (IS_ERR(dev->pins->idle_state))
+		/* Not supplying this state is perfectly legal */
+		dev_dbg(dev, "no idle pinctrl state\n");
+#endif
+
 	return 0;
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/platform.c linux-libre-3.11-rc7-gnu/drivers/base/platform.c
--- linux-libre-3.10-gnu/drivers/base/platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,9 +29,6 @@
 /* For automatically allocated device IDs */
 static DEFINE_IDA(platform_devid_ida);
 
-#define to_platform_driver(drv)	(container_of((drv), struct platform_driver, \
-				 driver))
-
 struct device platform_bus = {
 	.init_name	= "platform",
 };
@@ -523,11 +520,14 @@ static void platform_drv_shutdown(struct
 }
 
 /**
- * platform_driver_register - register a driver for platform-level devices
+ * __platform_driver_register - register a driver for platform-level devices
  * @drv: platform driver structure
+ * @owner: owning module/driver
  */
-int platform_driver_register(struct platform_driver *drv)
+int __platform_driver_register(struct platform_driver *drv,
+				struct module *owner)
 {
+	drv->driver.owner = owner;
 	drv->driver.bus = &platform_bus_type;
 	if (drv->probe)
 		drv->driver.probe = platform_drv_probe;
@@ -538,7 +538,7 @@ int platform_driver_register(struct plat
 
 	return driver_register(&drv->driver);
 }
-EXPORT_SYMBOL_GPL(platform_driver_register);
+EXPORT_SYMBOL_GPL(__platform_driver_register);
 
 /**
  * platform_driver_unregister - unregister a driver for platform-level devices
@@ -888,7 +888,6 @@ int platform_pm_restore(struct device *d
 static const struct dev_pm_ops platform_dev_pm_ops = {
 	.runtime_suspend = pm_generic_runtime_suspend,
 	.runtime_resume = pm_generic_runtime_resume,
-	.runtime_idle = pm_generic_runtime_idle,
 	USE_PLATFORM_PM_SLEEP_OPS
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/power/domain.c linux-libre-3.11-rc7-gnu/drivers/base/power/domain.c
--- linux-libre-3.10-gnu/drivers/base/power/domain.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/power/domain.c	2013-08-25 20:43:22.000000000 -0400
@@ -2143,7 +2143,6 @@ void pm_genpd_init(struct generic_pm_dom
 	genpd->max_off_time_changed = true;
 	genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
 	genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
-	genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
 	genpd->domain.ops.prepare = pm_genpd_prepare;
 	genpd->domain.ops.suspend = pm_genpd_suspend;
 	genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/power/generic_ops.c linux-libre-3.11-rc7-gnu/drivers/base/power/generic_ops.c
--- linux-libre-3.10-gnu/drivers/base/power/generic_ops.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/power/generic_ops.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,29 +12,6 @@
 
 #ifdef CONFIG_PM_RUNTIME
 /**
- * pm_generic_runtime_idle - Generic runtime idle callback for subsystems.
- * @dev: Device to handle.
- *
- * If PM operations are defined for the @dev's driver and they include
- * ->runtime_idle(), execute it and return its error code, if nonzero.
- * Otherwise, execute pm_runtime_suspend() for the device and return 0.
- */
-int pm_generic_runtime_idle(struct device *dev)
-{
-	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
-	if (pm && pm->runtime_idle) {
-		int ret = pm->runtime_idle(dev);
-		if (ret)
-			return ret;
-	}
-
-	pm_runtime_suspend(dev);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);
-
-/**
  * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
  * @dev: Device to suspend.
  *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/power/opp.c linux-libre-3.11-rc7-gnu/drivers/base/power/opp.c
--- linux-libre-3.10-gnu/drivers/base/power/opp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/power/opp.c	2013-08-25 20:43:22.000000000 -0400
@@ -648,14 +648,14 @@ int opp_init_cpufreq_table(struct device
 
 	list_for_each_entry(opp, &dev_opp->opp_list, node) {
 		if (opp->available) {
-			freq_table[i].index = i;
+			freq_table[i].driver_data = i;
 			freq_table[i].frequency = opp->rate / 1000;
 			i++;
 		}
 	}
 	mutex_unlock(&dev_opp_list_lock);
 
-	freq_table[i].index = i;
+	freq_table[i].driver_data = i;
 	freq_table[i].frequency = CPUFREQ_TABLE_END;
 
 	*table = &freq_table[0];
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/power/qos.c linux-libre-3.11-rc7-gnu/drivers/base/power/qos.c
--- linux-libre-3.10-gnu/drivers/base/power/qos.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/power/qos.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/export.h>
 #include <linux/pm_runtime.h>
 #include <linux/err.h>
+#include <trace/events/power.h>
 
 #include "power.h"
 
@@ -305,6 +306,7 @@ int dev_pm_qos_add_request(struct device
 	else if (!dev->power.qos)
 		ret = dev_pm_qos_constraints_allocate(dev);
 
+	trace_dev_pm_qos_add_request(dev_name(dev), type, value);
 	if (!ret) {
 		req->dev = dev;
 		req->type = type;
@@ -349,6 +351,8 @@ static int __dev_pm_qos_update_request(s
 		return -EINVAL;
 	}
 
+	trace_dev_pm_qos_update_request(dev_name(req->dev), req->type,
+					new_value);
 	if (curr_value != new_value)
 		ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value);
 
@@ -398,6 +402,8 @@ static int __dev_pm_qos_remove_request(s
 	if (IS_ERR_OR_NULL(req->dev->power.qos))
 		return -ENODEV;
 
+	trace_dev_pm_qos_remove_request(dev_name(req->dev), req->type,
+					PM_QOS_DEFAULT_VALUE);
 	ret = apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
 	memset(req, 0, sizeof(*req));
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/power/runtime.c linux-libre-3.11-rc7-gnu/drivers/base/power/runtime.c
--- linux-libre-3.10-gnu/drivers/base/power/runtime.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/power/runtime.c	2013-08-25 20:43:22.000000000 -0400
@@ -293,11 +293,8 @@ static int rpm_idle(struct device *dev,
 	/* Pending requests need to be canceled. */
 	dev->power.request = RPM_REQ_NONE;
 
-	if (dev->power.no_callbacks) {
-		/* Assume ->runtime_idle() callback would have suspended. */
-		retval = rpm_suspend(dev, rpmflags);
+	if (dev->power.no_callbacks)
 		goto out;
-	}
 
 	/* Carry out an asynchronous or a synchronous idle notification. */
 	if (rpmflags & RPM_ASYNC) {
@@ -306,7 +303,8 @@ static int rpm_idle(struct device *dev,
 			dev->power.request_pending = true;
 			queue_work(pm_wq, &dev->power.work);
 		}
-		goto out;
+		trace_rpm_return_int(dev, _THIS_IP_, 0);
+		return 0;
 	}
 
 	dev->power.idle_notification = true;
@@ -326,14 +324,14 @@ static int rpm_idle(struct device *dev,
 		callback = dev->driver->pm->runtime_idle;
 
 	if (callback)
-		__rpm_callback(callback, dev);
+		retval = __rpm_callback(callback, dev);
 
 	dev->power.idle_notification = false;
 	wake_up_all(&dev->power.wait_queue);
 
  out:
 	trace_rpm_return_int(dev, _THIS_IP_, retval);
-	return retval;
+	return retval ? retval : rpm_suspend(dev, rpmflags);
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/power/wakeup.c linux-libre-3.11-rc7-gnu/drivers/base/power/wakeup.c
--- linux-libre-3.10-gnu/drivers/base/power/wakeup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/power/wakeup.c	2013-08-25 20:43:22.000000000 -0400
@@ -659,7 +659,7 @@ void pm_wakeup_event(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(pm_wakeup_event);
 
-static void print_active_wakeup_sources(void)
+void pm_print_active_wakeup_sources(void)
 {
 	struct wakeup_source *ws;
 	int active = 0;
@@ -683,6 +683,7 @@ static void print_active_wakeup_sources(
 			last_activity_ws->name);
 	rcu_read_unlock();
 }
+EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources);
 
 /**
  * pm_wakeup_pending - Check if power transition in progress should be aborted.
@@ -707,8 +708,10 @@ bool pm_wakeup_pending(void)
 	}
 	spin_unlock_irqrestore(&events_lock, flags);
 
-	if (ret)
-		print_active_wakeup_sources();
+	if (ret) {
+		pr_info("PM: Wakeup pending, aborting suspend\n");
+		pm_print_active_wakeup_sources();
+	}
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/regmap/internal.h linux-libre-3.11-rc7-gnu/drivers/base/regmap/internal.h
--- linux-libre-3.10-gnu/drivers/base/regmap/internal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/regmap/internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -52,6 +52,7 @@ struct regmap_async {
 struct regmap {
 	struct mutex mutex;
 	spinlock_t spinlock;
+	unsigned long spinlock_flags;
 	regmap_lock lock;
 	regmap_unlock unlock;
 	void *lock_arg; /* This is passed to lock/unlock functions */
@@ -148,6 +149,7 @@ struct regcache_ops {
 	int (*read)(struct regmap *map, unsigned int reg, unsigned int *value);
 	int (*write)(struct regmap *map, unsigned int reg, unsigned int value);
 	int (*sync)(struct regmap *map, unsigned int min, unsigned int max);
+	int (*drop)(struct regmap *map, unsigned int min, unsigned int max);
 };
 
 bool regmap_writeable(struct regmap *map, unsigned int reg);
@@ -174,6 +176,14 @@ struct regmap_range_node {
 	unsigned int window_len;
 };
 
+struct regmap_field {
+	struct regmap *regmap;
+	unsigned int mask;
+	/* lsb */
+	unsigned int shift;
+	unsigned int reg;
+};
+
 #ifdef CONFIG_DEBUG_FS
 extern void regmap_debugfs_initcall(void);
 extern void regmap_debugfs_init(struct regmap *map, const char *name);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/regmap/regcache.c linux-libre-3.11-rc7-gnu/drivers/base/regmap/regcache.c
--- linux-libre-3.10-gnu/drivers/base/regmap/regcache.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/regmap/regcache.c	2013-08-25 20:43:22.000000000 -0400
@@ -250,6 +250,38 @@ int regcache_write(struct regmap *map,
 	return 0;
 }
 
+static int regcache_default_sync(struct regmap *map, unsigned int min,
+				 unsigned int max)
+{
+	unsigned int reg;
+
+	for (reg = min; reg <= max; reg++) {
+		unsigned int val;
+		int ret;
+
+		if (regmap_volatile(map, reg))
+			continue;
+
+		ret = regcache_read(map, reg, &val);
+		if (ret)
+			return ret;
+
+		/* Is this the hardware default?  If so skip. */
+		ret = regcache_lookup_reg(map, reg);
+		if (ret >= 0 && val == map->reg_defaults[ret].def)
+			continue;
+
+		map->cache_bypass = 1;
+		ret = _regmap_write(map, reg, val);
+		map->cache_bypass = 0;
+		if (ret)
+			return ret;
+		dev_dbg(map->dev, "Synced register %#x, value %#x\n", reg, val);
+	}
+
+	return 0;
+}
+
 /**
  * regcache_sync: Sync the register cache with the hardware.
  *
@@ -268,7 +300,7 @@ int regcache_sync(struct regmap *map)
 	const char *name;
 	unsigned int bypass;
 
-	BUG_ON(!map->cache_ops || !map->cache_ops->sync);
+	BUG_ON(!map->cache_ops);
 
 	map->lock(map->lock_arg);
 	/* Remember the initial bypass state */
@@ -297,7 +329,10 @@ int regcache_sync(struct regmap *map)
 	}
 	map->cache_bypass = 0;
 
-	ret = map->cache_ops->sync(map, 0, map->max_register);
+	if (map->cache_ops->sync)
+		ret = map->cache_ops->sync(map, 0, map->max_register);
+	else
+		ret = regcache_default_sync(map, 0, map->max_register);
 
 	if (ret == 0)
 		map->cache_dirty = false;
@@ -331,7 +366,7 @@ int regcache_sync_region(struct regmap *
 	const char *name;
 	unsigned int bypass;
 
-	BUG_ON(!map->cache_ops || !map->cache_ops->sync);
+	BUG_ON(!map->cache_ops);
 
 	map->lock(map->lock_arg);
 
@@ -346,7 +381,10 @@ int regcache_sync_region(struct regmap *
 	if (!map->cache_dirty)
 		goto out;
 
-	ret = map->cache_ops->sync(map, min, max);
+	if (map->cache_ops->sync)
+		ret = map->cache_ops->sync(map, min, max);
+	else
+		ret = regcache_default_sync(map, min, max);
 
 out:
 	trace_regcache_sync(map->dev, name, "stop region");
@@ -359,6 +397,43 @@ out:
 EXPORT_SYMBOL_GPL(regcache_sync_region);
 
 /**
+ * regcache_drop_region: Discard part of the register cache
+ *
+ * @map: map to operate on
+ * @min: first register to discard
+ * @max: last register to discard
+ *
+ * Discard part of the register cache.
+ *
+ * Return a negative value on failure, 0 on success.
+ */
+int regcache_drop_region(struct regmap *map, unsigned int min,
+			 unsigned int max)
+{
+	unsigned int reg;
+	int ret = 0;
+
+	if (!map->cache_present && !(map->cache_ops && map->cache_ops->drop))
+		return -EINVAL;
+
+	map->lock(map->lock_arg);
+
+	trace_regcache_drop_region(map->dev, min, max);
+
+	if (map->cache_present)
+		for (reg = min; reg < max + 1; reg++)
+			clear_bit(reg, map->cache_present);
+
+	if (map->cache_ops && map->cache_ops->drop)
+		ret = map->cache_ops->drop(map, min, max);
+
+	map->unlock(map->lock_arg);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regcache_drop_region);
+
+/**
  * regcache_cache_only: Put a register map into cache only mode
  *
  * @map: map to configure
@@ -644,7 +719,8 @@ static int regcache_sync_block_raw(struc
 		}
 	}
 
-	return regcache_sync_block_raw_flush(map, &data, base, regtmp);
+	return regcache_sync_block_raw_flush(map, &data, base, regtmp +
+			map->reg_stride);
 }
 
 int regcache_sync_block(struct regmap *map, void *block,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/regmap/regcache-rbtree.c linux-libre-3.11-rc7-gnu/drivers/base/regmap/regcache-rbtree.c
--- linux-libre-3.10-gnu/drivers/base/regmap/regcache-rbtree.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/regmap/regcache-rbtree.c	2013-08-25 20:43:22.000000000 -0400
@@ -304,6 +304,48 @@ static int regcache_rbtree_insert_to_blo
 	return 0;
 }
 
+static struct regcache_rbtree_node *
+regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
+{
+	struct regcache_rbtree_node *rbnode;
+	const struct regmap_range *range;
+	int i;
+
+	rbnode = kzalloc(sizeof(*rbnode), GFP_KERNEL);
+	if (!rbnode)
+		return NULL;
+
+	/* If there is a read table then use it to guess at an allocation */
+	if (map->rd_table) {
+		for (i = 0; i < map->rd_table->n_yes_ranges; i++) {
+			if (regmap_reg_in_range(reg,
+						&map->rd_table->yes_ranges[i]))
+				break;
+		}
+
+		if (i != map->rd_table->n_yes_ranges) {
+			range = &map->rd_table->yes_ranges[i];
+			rbnode->blklen = range->range_max - range->range_min
+				+ 1;
+			rbnode->base_reg = range->range_min;
+		}
+	}
+
+	if (!rbnode->blklen) {
+		rbnode->blklen = sizeof(*rbnode);
+		rbnode->base_reg = reg;
+	}
+
+	rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size,
+				GFP_KERNEL);
+	if (!rbnode->block) {
+		kfree(rbnode);
+		return NULL;
+	}
+
+	return rbnode;
+}
+
 static int regcache_rbtree_write(struct regmap *map, unsigned int reg,
 				 unsigned int value)
 {
@@ -354,23 +396,15 @@ static int regcache_rbtree_write(struct
 				return 0;
 			}
 		}
-		/* we did not manage to find a place to insert it in an existing
-		 * block so create a new rbnode with a single register in its block.
-		 * This block will get populated further if any other adjacent
-		 * registers get modified in the future.
+
+		/* We did not manage to find a place to insert it in
+		 * an existing block so create a new rbnode.
 		 */
-		rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
+		rbnode = regcache_rbtree_node_alloc(map, reg);
 		if (!rbnode)
 			return -ENOMEM;
-		rbnode->blklen = sizeof(*rbnode);
-		rbnode->base_reg = reg;
-		rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size,
-					GFP_KERNEL);
-		if (!rbnode->block) {
-			kfree(rbnode);
-			return -ENOMEM;
-		}
-		regcache_rbtree_set_register(map, rbnode, 0, value);
+		regcache_rbtree_set_register(map, rbnode,
+					     reg - rbnode->base_reg, value);
 		regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode);
 		rbtree_ctx->cached_rbnode = rbnode;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/regmap/regmap.c linux-libre-3.11-rc7-gnu/drivers/base/regmap/regmap.c
--- linux-libre-3.10-gnu/drivers/base/regmap/regmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/regmap/regmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -65,9 +65,8 @@ bool regmap_reg_in_ranges(unsigned int r
 }
 EXPORT_SYMBOL_GPL(regmap_reg_in_ranges);
 
-static bool _regmap_check_range_table(struct regmap *map,
-				      unsigned int reg,
-				      const struct regmap_access_table *table)
+bool regmap_check_range_table(struct regmap *map, unsigned int reg,
+			      const struct regmap_access_table *table)
 {
 	/* Check "no ranges" first */
 	if (regmap_reg_in_ranges(reg, table->no_ranges, table->n_no_ranges))
@@ -80,6 +79,7 @@ static bool _regmap_check_range_table(st
 	return regmap_reg_in_ranges(reg, table->yes_ranges,
 				    table->n_yes_ranges);
 }
+EXPORT_SYMBOL_GPL(regmap_check_range_table);
 
 bool regmap_writeable(struct regmap *map, unsigned int reg)
 {
@@ -90,7 +90,7 @@ bool regmap_writeable(struct regmap *map
 		return map->writeable_reg(map->dev, reg);
 
 	if (map->wr_table)
-		return _regmap_check_range_table(map, reg, map->wr_table);
+		return regmap_check_range_table(map, reg, map->wr_table);
 
 	return true;
 }
@@ -107,7 +107,7 @@ bool regmap_readable(struct regmap *map,
 		return map->readable_reg(map->dev, reg);
 
 	if (map->rd_table)
-		return _regmap_check_range_table(map, reg, map->rd_table);
+		return regmap_check_range_table(map, reg, map->rd_table);
 
 	return true;
 }
@@ -121,9 +121,12 @@ bool regmap_volatile(struct regmap *map,
 		return map->volatile_reg(map->dev, reg);
 
 	if (map->volatile_table)
-		return _regmap_check_range_table(map, reg, map->volatile_table);
+		return regmap_check_range_table(map, reg, map->volatile_table);
 
-	return true;
+	if (map->cache_ops)
+		return false;
+	else
+		return true;
 }
 
 bool regmap_precious(struct regmap *map, unsigned int reg)
@@ -135,7 +138,7 @@ bool regmap_precious(struct regmap *map,
 		return map->precious_reg(map->dev, reg);
 
 	if (map->precious_table)
-		return _regmap_check_range_table(map, reg, map->precious_table);
+		return regmap_check_range_table(map, reg, map->precious_table);
 
 	return false;
 }
@@ -302,13 +305,16 @@ static void regmap_unlock_mutex(void *__
 static void regmap_lock_spinlock(void *__map)
 {
 	struct regmap *map = __map;
-	spin_lock(&map->spinlock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&map->spinlock, flags);
+	map->spinlock_flags = flags;
 }
 
 static void regmap_unlock_spinlock(void *__map)
 {
 	struct regmap *map = __map;
-	spin_unlock(&map->spinlock);
+	spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags);
 }
 
 static void dev_get_regmap_release(struct device *dev, void *res)
@@ -801,6 +807,95 @@ struct regmap *devm_regmap_init(struct d
 }
 EXPORT_SYMBOL_GPL(devm_regmap_init);
 
+static void regmap_field_init(struct regmap_field *rm_field,
+	struct regmap *regmap, struct reg_field reg_field)
+{
+	int field_bits = reg_field.msb - reg_field.lsb + 1;
+	rm_field->regmap = regmap;
+	rm_field->reg = reg_field.reg;
+	rm_field->shift = reg_field.lsb;
+	rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
+}
+
+/**
+ * devm_regmap_field_alloc(): Allocate and initialise a register field
+ * in a register map.
+ *
+ * @dev: Device that will be interacted with
+ * @regmap: regmap bank in which this register field is located.
+ * @reg_field: Register field with in the bank.
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap_field. The regmap_field will be automatically freed
+ * by the device management code.
+ */
+struct regmap_field *devm_regmap_field_alloc(struct device *dev,
+		struct regmap *regmap, struct reg_field reg_field)
+{
+	struct regmap_field *rm_field = devm_kzalloc(dev,
+					sizeof(*rm_field), GFP_KERNEL);
+	if (!rm_field)
+		return ERR_PTR(-ENOMEM);
+
+	regmap_field_init(rm_field, regmap, reg_field);
+
+	return rm_field;
+
+}
+EXPORT_SYMBOL_GPL(devm_regmap_field_alloc);
+
+/**
+ * devm_regmap_field_free(): Free register field allocated using
+ * devm_regmap_field_alloc. Usally drivers need not call this function,
+ * as the memory allocated via devm will be freed as per device-driver
+ * life-cyle.
+ *
+ * @dev: Device that will be interacted with
+ * @field: regmap field which should be freed.
+ */
+void devm_regmap_field_free(struct device *dev,
+	struct regmap_field *field)
+{
+	devm_kfree(dev, field);
+}
+EXPORT_SYMBOL_GPL(devm_regmap_field_free);
+
+/**
+ * regmap_field_alloc(): Allocate and initialise a register field
+ * in a register map.
+ *
+ * @regmap: regmap bank in which this register field is located.
+ * @reg_field: Register field with in the bank.
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap_field. The regmap_field should be freed by the
+ * user once its finished working with it using regmap_field_free().
+ */
+struct regmap_field *regmap_field_alloc(struct regmap *regmap,
+		struct reg_field reg_field)
+{
+	struct regmap_field *rm_field = kzalloc(sizeof(*rm_field), GFP_KERNEL);
+
+	if (!rm_field)
+		return ERR_PTR(-ENOMEM);
+
+	regmap_field_init(rm_field, regmap, reg_field);
+
+	return rm_field;
+}
+EXPORT_SYMBOL_GPL(regmap_field_alloc);
+
+/**
+ * regmap_field_free(): Free register field allocated using regmap_field_alloc
+ *
+ * @field: regmap field which should be freed.
+ */
+void regmap_field_free(struct regmap_field *field)
+{
+	kfree(field);
+}
+EXPORT_SYMBOL_GPL(regmap_field_free);
+
 /**
  * regmap_reinit_cache(): Reinitialise the current register cache
  *
@@ -1249,6 +1344,22 @@ int regmap_raw_write(struct regmap *map,
 }
 EXPORT_SYMBOL_GPL(regmap_raw_write);
 
+/**
+ * regmap_field_write(): Write a value to a single register field
+ *
+ * @field: Register field to write to
+ * @val: Value to be written
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+int regmap_field_write(struct regmap_field *field, unsigned int val)
+{
+	return regmap_update_bits(field->regmap, field->reg,
+				field->mask, val << field->shift);
+}
+EXPORT_SYMBOL_GPL(regmap_field_write);
+
 /*
  * regmap_bulk_write(): Write multiple registers to the device
  *
@@ -1532,6 +1643,31 @@ int regmap_raw_read(struct regmap *map,
 EXPORT_SYMBOL_GPL(regmap_raw_read);
 
 /**
+ * regmap_field_read(): Read a value to a single register field
+ *
+ * @field: Register field to read from
+ * @val: Pointer to store read value
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+int regmap_field_read(struct regmap_field *field, unsigned int *val)
+{
+	int ret;
+	unsigned int reg_val;
+	ret = regmap_read(field->regmap, field->reg, &reg_val);
+	if (ret != 0)
+		return ret;
+
+	reg_val &= field->mask;
+	reg_val >>= field->shift;
+	*val = reg_val;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_field_read);
+
+/**
  * regmap_bulk_read(): Read multiple registers from the device
  *
  * @map: Register map to write to
@@ -1717,7 +1853,7 @@ int regmap_async_complete(struct regmap
 	int ret;
 
 	/* Nothing to do with no async support */
-	if (!map->bus->async_write)
+	if (!map->bus || !map->bus->async_write)
 		return 0;
 
 	trace_regmap_async_complete_start(map->dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/regmap/regmap-debugfs.c linux-libre-3.11-rc7-gnu/drivers/base/regmap/regmap-debugfs.c
--- linux-libre-3.10-gnu/drivers/base/regmap/regmap-debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/regmap/regmap-debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,6 +84,10 @@ static unsigned int regmap_debugfs_get_d
 	unsigned int fpos_offset;
 	unsigned int reg_offset;
 
+	/* Suppress the cache if we're using a subrange */
+	if (from)
+		return from;
+
 	/*
 	 * If we don't have a cache build one so we don't have to do a
 	 * linear scan each time.
@@ -145,7 +149,7 @@ static unsigned int regmap_debugfs_get_d
 			reg_offset = fpos_offset / map->debugfs_tot_len;
 			*pos = c->min + (reg_offset * map->debugfs_tot_len);
 			mutex_unlock(&map->cache_lock);
-			return c->base_reg + reg_offset;
+			return c->base_reg + (reg_offset * map->reg_stride);
 		}
 
 		*pos = c->max;
@@ -281,7 +285,7 @@ static ssize_t regmap_map_write_file(str
 		return -EINVAL;
 
 	/* Userspace has been fiddling around behind the kernel's back */
-	add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
+	add_taint(TAINT_USER, LOCKDEP_STILL_OK);
 
 	ret = regmap_write(map, reg, value);
 	if (ret < 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/reservation.c linux-libre-3.11-rc7-gnu/drivers/base/reservation.c
--- linux-libre-3.10-gnu/drivers/base/reservation.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/base/reservation.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012-2013 Canonical Ltd
+ *
+ * Based on bo.c which bears the following copyright notice,
+ * but is dual licensed:
+ *
+ * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
+ */
+
+#include <linux/reservation.h>
+#include <linux/export.h>
+
+DEFINE_WW_CLASS(reservation_ww_class);
+EXPORT_SYMBOL(reservation_ww_class);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/base/topology.c linux-libre-3.11-rc7-gnu/drivers/base/topology.c
--- linux-libre-3.10-gnu/drivers/base/topology.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/base/topology.c	2013-08-25 20:43:22.000000000 -0400
@@ -143,22 +143,22 @@ static struct attribute_group topology_a
 };
 
 /* Add/Remove cpu_topology interface for CPU device */
-static int __cpuinit topology_add_dev(unsigned int cpu)
+static int topology_add_dev(unsigned int cpu)
 {
 	struct device *dev = get_cpu_device(cpu);
 
 	return sysfs_create_group(&dev->kobj, &topology_attr_group);
 }
 
-static void __cpuinit topology_remove_dev(unsigned int cpu)
+static void topology_remove_dev(unsigned int cpu)
 {
 	struct device *dev = get_cpu_device(cpu);
 
 	sysfs_remove_group(&dev->kobj, &topology_attr_group);
 }
 
-static int __cpuinit topology_cpu_callback(struct notifier_block *nfb,
-					   unsigned long action, void *hcpu)
+static int topology_cpu_callback(struct notifier_block *nfb,
+				 unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
 	int rc = 0;
@@ -178,7 +178,7 @@ static int __cpuinit topology_cpu_callba
 	return notifier_from_errno(rc);
 }
 
-static int __cpuinit topology_sysfs_init(void)
+static int topology_sysfs_init(void)
 {
 	int cpu;
 	int rc;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bcma/bcma_private.h linux-libre-3.11-rc7-gnu/drivers/bcma/bcma_private.h
--- linux-libre-3.10-gnu/drivers/bcma/bcma_private.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bcma/bcma_private.h	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,8 @@
 struct bcma_bus;
 
 /* main.c */
+bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
+		     int timeout);
 int bcma_bus_register(struct bcma_bus *bus);
 void bcma_bus_unregister(struct bcma_bus *bus);
 int __init bcma_bus_early_register(struct bcma_bus *bus,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bcma/core.c linux-libre-3.11-rc7-gnu/drivers/bcma/core.c
--- linux-libre-3.10-gnu/drivers/bcma/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bcma/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,25 @@
 #include <linux/export.h>
 #include <linux/bcma/bcma.h>
 
+static bool bcma_core_wait_value(struct bcma_device *core, u16 reg, u32 mask,
+				 u32 value, int timeout)
+{
+	unsigned long deadline = jiffies + timeout;
+	u32 val;
+
+	do {
+		val = bcma_aread32(core, reg);
+		if ((val & mask) == value)
+			return true;
+		cpu_relax();
+		udelay(10);
+	} while (!time_after_eq(jiffies, deadline));
+
+	bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
+
+	return false;
+}
+
 bool bcma_core_is_enabled(struct bcma_device *core)
 {
 	if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
@@ -25,13 +44,15 @@ void bcma_core_disable(struct bcma_devic
 	if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
 		return;
 
-	bcma_awrite32(core, BCMA_IOCTL, flags);
-	bcma_aread32(core, BCMA_IOCTL);
-	udelay(10);
+	bcma_core_wait_value(core, BCMA_RESET_ST, ~0, 0, 300);
 
 	bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
 	bcma_aread32(core, BCMA_RESET_CTL);
 	udelay(1);
+
+	bcma_awrite32(core, BCMA_IOCTL, flags);
+	bcma_aread32(core, BCMA_IOCTL);
+	udelay(10);
 }
 EXPORT_SYMBOL_GPL(bcma_core_disable);
 
@@ -43,6 +64,7 @@ int bcma_core_enable(struct bcma_device
 	bcma_aread32(core, BCMA_IOCTL);
 
 	bcma_awrite32(core, BCMA_RESET_CTL, 0);
+	bcma_aread32(core, BCMA_RESET_CTL);
 	udelay(1);
 
 	bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bcma/driver_chipcommon.c linux-libre-3.11-rc7-gnu/drivers/bcma/driver_chipcommon.c
--- linux-libre-3.10-gnu/drivers/bcma/driver_chipcommon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bcma/driver_chipcommon.c	2013-08-25 20:43:22.000000000 -0400
@@ -140,8 +140,15 @@ void bcma_core_chipcommon_init(struct bc
 	bcma_core_chipcommon_early_init(cc);
 
 	if (cc->core->id.rev >= 20) {
-		bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
-		bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
+		u32 pullup = 0, pulldown = 0;
+
+		if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) {
+			pullup = 0x402e0;
+			pulldown = 0x20500;
+		}
+
+		bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup);
+		bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown);
 	}
 
 	if (cc->capabilities & BCMA_CC_CAP_PMU)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bcma/driver_chipcommon_pmu.c linux-libre-3.11-rc7-gnu/drivers/bcma/driver_chipcommon_pmu.c
--- linux-libre-3.10-gnu/drivers/bcma/driver_chipcommon_pmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bcma/driver_chipcommon_pmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct b
 }
 EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
 
+static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc)
+{
+	u32 ilp_ctl, alp_hz;
+
+	if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) &
+	      BCMA_CC_PMU_STAT_EXT_LPO_AVAIL))
+		return 0;
+
+	bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
+			BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
+	usleep_range(1000, 2000);
+
+	ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
+	ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK;
+
+	bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
+
+	alp_hz = ilp_ctl * 32768 / 4;
+	return (alp_hz + 50000) / 100000 * 100;
+}
+
+static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq)
+{
+	struct bcma_bus *bus = cc->core->bus;
+	u32 freq_tgt_target = 0, freq_tgt_current;
+	u32 pll0, mask;
+
+	switch (bus->chipinfo.id) {
+	case BCMA_CHIP_ID_BCM43142:
+		/* pmu2_xtaltab0_adfll_485 */
+		switch (xtalfreq) {
+		case 12000:
+			freq_tgt_target = 0x50D52;
+			break;
+		case 20000:
+			freq_tgt_target = 0x307FE;
+			break;
+		case 26000:
+			freq_tgt_target = 0x254EA;
+			break;
+		case 37400:
+			freq_tgt_target = 0x19EF8;
+			break;
+		case 52000:
+			freq_tgt_target = 0x12A75;
+			break;
+		}
+		break;
+	}
+
+	if (!freq_tgt_target) {
+		bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n",
+			 xtalfreq);
+		return;
+	}
+
+	pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0);
+	freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >>
+		BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
+
+	if (freq_tgt_current == freq_tgt_target) {
+		bcma_debug(bus, "Target TGT frequency already set\n");
+		return;
+	}
+
+	/* Turn off PLL */
+	switch (bus->chipinfo.id) {
+	case BCMA_CHIP_ID_BCM43142:
+		mask = (u32)~(BCMA_RES_4314_HT_AVAIL |
+			      BCMA_RES_4314_MACPHY_CLK_AVAIL);
+
+		bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
+		bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
+		bcma_wait_value(cc->core, BCMA_CLKCTLST,
+				BCMA_CLKCTLST_HAVEHT, 0, 20000);
+		break;
+	}
+
+	pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK;
+	pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
+	bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0);
+
+	/* Flush */
+	if (cc->pmu.rev >= 2)
+		bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
+
+	/* TODO: Do we need to update OTP? */
+}
+
+static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
+{
+	struct bcma_bus *bus = cc->core->bus;
+	u32 xtalfreq = bcma_pmu_xtalfreq(cc);
+
+	switch (bus->chipinfo.id) {
+	case BCMA_CHIP_ID_BCM43142:
+		if (xtalfreq == 0)
+			xtalfreq = 20000;
+		bcma_pmu2_pll_init0(cc, xtalfreq);
+		break;
+	}
+}
+
 static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
 {
 	struct bcma_bus *bus = cc->core->bus;
@@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(stru
 		min_msk = 0x200D;
 		max_msk = 0xFFFF;
 		break;
+	case BCMA_CHIP_ID_BCM43142:
+		min_msk = BCMA_RES_4314_LPLDO_PU |
+			  BCMA_RES_4314_PMU_SLEEP_DIS |
+			  BCMA_RES_4314_PMU_BG_PU |
+			  BCMA_RES_4314_CBUCK_LPOM_PU |
+			  BCMA_RES_4314_CBUCK_PFM_PU |
+			  BCMA_RES_4314_CLDO_PU |
+			  BCMA_RES_4314_LPLDO2_LVM |
+			  BCMA_RES_4314_WL_PMU_PU |
+			  BCMA_RES_4314_LDO3P3_PU |
+			  BCMA_RES_4314_OTP_PU |
+			  BCMA_RES_4314_WL_PWRSW_PU |
+			  BCMA_RES_4314_LQ_AVAIL |
+			  BCMA_RES_4314_LOGIC_RET |
+			  BCMA_RES_4314_MEM_SLEEP |
+			  BCMA_RES_4314_MACPHY_RET |
+			  BCMA_RES_4314_WL_CORE_READY;
+		max_msk = 0x3FFFFFFF;
+		break;
 	default:
 		bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n",
 			   bus->chipinfo.id);
@@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *c
 		bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
 			     BCMA_CC_PMU_CTL_NOILPONW);
 
+	bcma_pmu_pll_init(cc);
 	bcma_pmu_resources_init(cc);
 	bcma_pmu_workarounds(cc);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bcma/driver_chipcommon_sflash.c linux-libre-3.11-rc7-gnu/drivers/bcma/driver_chipcommon_sflash.c
--- linux-libre-3.10-gnu/drivers/bcma/driver_chipcommon_sflash.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bcma/driver_chipcommon_sflash.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,7 @@ struct bcma_sflash_tbl_e {
 	u16 numblocks;
 };
 
-static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
+static const struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
 	{ "M25P20", 0x11, 0x10000, 4, },
 	{ "M25P40", 0x12, 0x10000, 8, },
 
@@ -41,7 +41,7 @@ static struct bcma_sflash_tbl_e bcma_sfl
 	{ 0 },
 };
 
-static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
+static const struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
 	{ "SST25WF512", 1, 0x1000, 16, },
 	{ "SST25VF512", 0x48, 0x1000, 16, },
 	{ "SST25WF010", 2, 0x1000, 32, },
@@ -59,7 +59,7 @@ static struct bcma_sflash_tbl_e bcma_sfl
 	{ 0 },
 };
 
-static struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
+static const struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
 	{ "AT45DB011", 0xc, 256, 512, },
 	{ "AT45DB021", 0x14, 256, 1024, },
 	{ "AT45DB041", 0x1c, 256, 2048, },
@@ -89,7 +89,7 @@ int bcma_sflash_init(struct bcma_drv_cc
 {
 	struct bcma_bus *bus = cc->core->bus;
 	struct bcma_sflash *sflash = &cc->sflash;
-	struct bcma_sflash_tbl_e *e;
+	const struct bcma_sflash_tbl_e *e;
 	u32 id, id2;
 
 	switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bcma/host_pci.c linux-libre-3.11-rc7-gnu/drivers/bcma/host_pci.c
--- linux-libre-3.10-gnu/drivers/bcma/host_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bcma/host_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -275,6 +275,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
 	{ 0, },
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bcma/Kconfig linux-libre-3.11-rc7-gnu/drivers/bcma/Kconfig
--- linux-libre-3.10-gnu/drivers/bcma/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bcma/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,7 @@ config BCMA_HOST_PCI_POSSIBLE
 config BCMA_HOST_PCI
 	bool "Support for BCMA on PCI-host bus"
 	depends on BCMA_HOST_PCI_POSSIBLE
+	default y
 
 config BCMA_DRIVER_PCI_HOSTMODE
 	bool "Driver for PCI core working in hostmode"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bcma/main.c linux-libre-3.11-rc7-gnu/drivers/bcma/main.c
--- linux-libre-3.10-gnu/drivers/bcma/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bcma/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -93,6 +93,25 @@ struct bcma_device *bcma_find_core_unit(
 	return NULL;
 }
 
+bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
+		     int timeout)
+{
+	unsigned long deadline = jiffies + timeout;
+	u32 val;
+
+	do {
+		val = bcma_read32(core, reg);
+		if ((val & mask) == value)
+			return true;
+		cpu_relax();
+		udelay(10);
+	} while (!time_after_eq(jiffies, deadline));
+
+	bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
+
+	return false;
+}
+
 static void bcma_release_core_dev(struct device *dev)
 {
 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bcma/sprom.c linux-libre-3.11-rc7-gnu/drivers/bcma/sprom.c
--- linux-libre-3.10-gnu/drivers/bcma/sprom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bcma/sprom.c	2013-08-25 20:43:22.000000000 -0400
@@ -72,12 +72,12 @@ fail:
  * R/W ops.
  **************************************************/
 
-static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
+static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom,
+			    size_t words)
 {
 	int i;
-	for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
-		sprom[i] = bcma_read16(bus->drv_cc.core,
-				       offset + (i * 2));
+	for (i = 0; i < words; i++)
+		sprom[i] = bcma_read16(bus->drv_cc.core, offset + (i * 2));
 }
 
 /**************************************************
@@ -124,29 +124,29 @@ static inline u8 bcma_crc8(u8 crc, u8 da
 	return t[crc ^ data];
 }
 
-static u8 bcma_sprom_crc(const u16 *sprom)
+static u8 bcma_sprom_crc(const u16 *sprom, size_t words)
 {
 	int word;
 	u8 crc = 0xFF;
 
-	for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
+	for (word = 0; word < words - 1; word++) {
 		crc = bcma_crc8(crc, sprom[word] & 0x00FF);
 		crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
 	}
-	crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
+	crc = bcma_crc8(crc, sprom[words - 1] & 0x00FF);
 	crc ^= 0xFF;
 
 	return crc;
 }
 
-static int bcma_sprom_check_crc(const u16 *sprom)
+static int bcma_sprom_check_crc(const u16 *sprom, size_t words)
 {
 	u8 crc;
 	u8 expected_crc;
 	u16 tmp;
 
-	crc = bcma_sprom_crc(sprom);
-	tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
+	crc = bcma_sprom_crc(sprom, words);
+	tmp = sprom[words - 1] & SSB_SPROM_REVISION_CRC;
 	expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
 	if (crc != expected_crc)
 		return -EPROTO;
@@ -154,21 +154,25 @@ static int bcma_sprom_check_crc(const u1
 	return 0;
 }
 
-static int bcma_sprom_valid(const u16 *sprom)
+static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
+			    size_t words)
 {
 	u16 revision;
 	int err;
 
-	err = bcma_sprom_check_crc(sprom);
+	err = bcma_sprom_check_crc(sprom, words);
 	if (err)
 		return err;
 
-	revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
-	if (revision != 8 && revision != 9) {
+	revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
+	if (revision != 8 && revision != 9 && revision != 10) {
 		pr_err("Unsupported SPROM revision: %d\n", revision);
 		return -ENOENT;
 	}
 
+	bus->sprom.revision = revision;
+	bcma_debug(bus, "Found SPROM revision %d\n", revision);
+
 	return 0;
 }
 
@@ -208,9 +212,6 @@ static void bcma_sprom_extract_r8(struct
 	BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
 			ARRAY_SIZE(bus->sprom.core_pwr_info));
 
-	bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
-		SSB_SPROM_REVISION_REV;
-
 	for (i = 0; i < 3; i++) {
 		v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
 		*(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
@@ -502,7 +503,7 @@ static bool bcma_sprom_onchip_available(
 	case BCMA_CHIP_ID_BCM4331:
 		present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
 		break;
-
+	case BCMA_CHIP_ID_BCM43142:
 	case BCMA_CHIP_ID_BCM43224:
 	case BCMA_CHIP_ID_BCM43225:
 		/* for these chips OTP is always available */
@@ -550,7 +551,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
 {
 	u16 offset = BCMA_CC_SPROM;
 	u16 *sprom;
-	int err = 0;
+	size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4,
+				 SSB_SPROMSIZE_WORDS_R10, };
+	int i, err = 0;
 
 	if (!bus->drv_cc.core)
 		return -EOPNOTSUPP;
@@ -579,32 +582,37 @@ int bcma_sprom_get(struct bcma_bus *bus)
 		}
 	}
 
-	sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
-			GFP_KERNEL);
-	if (!sprom)
-		return -ENOMEM;
-
 	if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
 	    bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
 		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
 
 	bcma_debug(bus, "SPROM offset 0x%x\n", offset);
-	bcma_sprom_read(bus, offset, sprom);
+	for (i = 0; i < ARRAY_SIZE(sprom_sizes); i++) {
+		size_t words = sprom_sizes[i];
+
+		sprom = kcalloc(words, sizeof(u16), GFP_KERNEL);
+		if (!sprom)
+			return -ENOMEM;
+
+		bcma_sprom_read(bus, offset, sprom, words);
+		err = bcma_sprom_valid(bus, sprom, words);
+		if (!err)
+			break;
+
+		kfree(sprom);
+	}
 
 	if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
 	    bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
 		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
 
-	err = bcma_sprom_valid(sprom);
 	if (err) {
-		bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n");
+		bcma_warn(bus, "Invalid SPROM read from the PCIe card, trying to use fallback SPROM\n");
 		err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
-		goto out;
+	} else {
+		bcma_sprom_extract_r8(bus, sprom);
+		kfree(sprom);
 	}
 
-	bcma_sprom_extract_r8(bus, sprom);
-
-out:
-	kfree(sprom);
 	return err;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/aoe/aoecmd.c linux-libre-3.11-rc7-gnu/drivers/block/aoe/aoecmd.c
--- linux-libre-3.10-gnu/drivers/block/aoe/aoecmd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/aoe/aoecmd.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Coraid, Inc.  See COPYING for GPL terms. */
+/* Copyright (c) 2013 Coraid, Inc.  See COPYING for GPL terms. */
 /*
  * aoecmd.c
  * Filesystem request handling methods
@@ -35,14 +35,27 @@ module_param(aoe_maxout, int, 0644);
 MODULE_PARM_DESC(aoe_maxout,
 	"Only aoe_maxout outstanding packets for every MAC on eX.Y.");
 
-static wait_queue_head_t ktiowq;
-static struct ktstate kts;
+/* The number of online cpus during module initialization gives us a
+ * convenient heuristic cap on the parallelism used for ktio threads
+ * doing I/O completion.  It is not important that the cap equal the
+ * actual number of running CPUs at any given time, but because of CPU
+ * hotplug, we take care to use ncpus instead of using
+ * num_online_cpus() after module initialization.
+ */
+static int ncpus;
+
+/* mutex lock used for synchronization while thread spawning */
+static DEFINE_MUTEX(ktio_spawn_lock);
+
+static wait_queue_head_t *ktiowq;
+static struct ktstate *kts;
 
 /* io completion queue */
-static struct {
+struct iocq_ktio {
 	struct list_head head;
 	spinlock_t lock;
-} iocq;
+};
+static struct iocq_ktio *iocq;
 
 static struct page *empty_page;
 
@@ -893,16 +906,10 @@ bio_pageinc(struct bio *bio)
 	int i;
 
 	bio_for_each_segment(bv, bio, i) {
-		page = bv->bv_page;
 		/* Non-zero page count for non-head members of
-		 * compound pages is no longer allowed by the kernel,
-		 * but this has never been seen here.
+		 * compound pages is no longer allowed by the kernel.
 		 */
-		if (unlikely(PageCompound(page)))
-			if (compound_trans_head(page) != page) {
-				pr_crit("page tail used for block I/O\n");
-				BUG();
-			}
+		page = compound_trans_head(bv->bv_page);
 		atomic_inc(&page->_count);
 	}
 }
@@ -911,10 +918,13 @@ static void
 bio_pagedec(struct bio *bio)
 {
 	struct bio_vec *bv;
+	struct page *page;
 	int i;
 
-	bio_for_each_segment(bv, bio, i)
-		atomic_dec(&bv->bv_page->_count);
+	bio_for_each_segment(bv, bio, i) {
+		page = compound_trans_head(bv->bv_page);
+		atomic_dec(&page->_count);
+	}
 }
 
 static void
@@ -1278,23 +1288,36 @@ out:
  * Returns true iff responses needing processing remain.
  */
 static int
-ktio(void)
+ktio(int id)
 {
 	struct frame *f;
 	struct list_head *pos;
 	int i;
+	int actual_id;
 
 	for (i = 0; ; ++i) {
 		if (i == MAXIOC)
 			return 1;
-		if (list_empty(&iocq.head))
+		if (list_empty(&iocq[id].head))
 			return 0;
-		pos = iocq.head.next;
+		pos = iocq[id].head.next;
 		list_del(pos);
-		spin_unlock_irq(&iocq.lock);
 		f = list_entry(pos, struct frame, head);
+		spin_unlock_irq(&iocq[id].lock);
 		ktiocomplete(f);
-		spin_lock_irq(&iocq.lock);
+
+		/* Figure out if extra threads are required. */
+		actual_id = f->t->d->aoeminor % ncpus;
+
+		if (!kts[actual_id].active) {
+			BUG_ON(id != 0);
+			mutex_lock(&ktio_spawn_lock);
+			if (!kts[actual_id].active
+				&& aoe_ktstart(&kts[actual_id]) == 0)
+				kts[actual_id].active = 1;
+			mutex_unlock(&ktio_spawn_lock);
+		}
+		spin_lock_irq(&iocq[id].lock);
 	}
 }
 
@@ -1311,7 +1334,7 @@ kthread(void *vp)
 	complete(&k->rendez);	/* tell spawner we're running */
 	do {
 		spin_lock_irq(k->lock);
-		more = k->fn();
+		more = k->fn(k->id);
 		if (!more) {
 			add_wait_queue(k->waitq, &wait);
 			__set_current_state(TASK_INTERRUPTIBLE);
@@ -1340,7 +1363,7 @@ aoe_ktstart(struct ktstate *k)
 	struct task_struct *task;
 
 	init_completion(&k->rendez);
-	task = kthread_run(kthread, k, k->name);
+	task = kthread_run(kthread, k, "%s", k->name);
 	if (task == NULL || IS_ERR(task))
 		return -ENOMEM;
 	k->task = task;
@@ -1353,13 +1376,24 @@ aoe_ktstart(struct ktstate *k)
 static void
 ktcomplete(struct frame *f, struct sk_buff *skb)
 {
+	int id;
 	ulong flags;
 
 	f->r_skb = skb;
-	spin_lock_irqsave(&iocq.lock, flags);
-	list_add_tail(&f->head, &iocq.head);
-	spin_unlock_irqrestore(&iocq.lock, flags);
-	wake_up(&ktiowq);
+	id = f->t->d->aoeminor % ncpus;
+	spin_lock_irqsave(&iocq[id].lock, flags);
+	if (!kts[id].active) {
+		spin_unlock_irqrestore(&iocq[id].lock, flags);
+		/* The thread with id has not been spawned yet,
+		 * so delegate the work to the main thread and
+		 * try spawning a new thread.
+		 */
+		id = 0;
+		spin_lock_irqsave(&iocq[id].lock, flags);
+	}
+	list_add_tail(&f->head, &iocq[id].head);
+	spin_unlock_irqrestore(&iocq[id].lock, flags);
+	wake_up(&ktiowq[id]);
 }
 
 struct sk_buff *
@@ -1706,6 +1740,17 @@ aoe_failbuf(struct aoedev *d, struct buf
 void
 aoe_flush_iocq(void)
 {
+	int i;
+
+	for (i = 0; i < ncpus; i++) {
+		if (kts[i].active)
+			aoe_flush_iocq_by_index(i);
+	}
+}
+
+void
+aoe_flush_iocq_by_index(int id)
+{
 	struct frame *f;
 	struct aoedev *d;
 	LIST_HEAD(flist);
@@ -1713,9 +1758,9 @@ aoe_flush_iocq(void)
 	struct sk_buff *skb;
 	ulong flags;
 
-	spin_lock_irqsave(&iocq.lock, flags);
-	list_splice_init(&iocq.head, &flist);
-	spin_unlock_irqrestore(&iocq.lock, flags);
+	spin_lock_irqsave(&iocq[id].lock, flags);
+	list_splice_init(&iocq[id].head, &flist);
+	spin_unlock_irqrestore(&iocq[id].lock, flags);
 	while (!list_empty(&flist)) {
 		pos = flist.next;
 		list_del(pos);
@@ -1738,6 +1783,8 @@ int __init
 aoecmd_init(void)
 {
 	void *p;
+	int i;
+	int ret;
 
 	/* get_zeroed_page returns page with ref count 1 */
 	p = (void *) get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
@@ -1745,22 +1792,72 @@ aoecmd_init(void)
 		return -ENOMEM;
 	empty_page = virt_to_page(p);
 
-	INIT_LIST_HEAD(&iocq.head);
-	spin_lock_init(&iocq.lock);
-	init_waitqueue_head(&ktiowq);
-	kts.name = "aoe_ktio";
-	kts.fn = ktio;
-	kts.waitq = &ktiowq;
-	kts.lock = &iocq.lock;
-	return aoe_ktstart(&kts);
+	ncpus = num_online_cpus();
+
+	iocq = kcalloc(ncpus, sizeof(struct iocq_ktio), GFP_KERNEL);
+	if (!iocq)
+		return -ENOMEM;
+
+	kts = kcalloc(ncpus, sizeof(struct ktstate), GFP_KERNEL);
+	if (!kts) {
+		ret = -ENOMEM;
+		goto kts_fail;
+	}
+
+	ktiowq = kcalloc(ncpus, sizeof(wait_queue_head_t), GFP_KERNEL);
+	if (!ktiowq) {
+		ret = -ENOMEM;
+		goto ktiowq_fail;
+	}
+
+	mutex_init(&ktio_spawn_lock);
+
+	for (i = 0; i < ncpus; i++) {
+		INIT_LIST_HEAD(&iocq[i].head);
+		spin_lock_init(&iocq[i].lock);
+		init_waitqueue_head(&ktiowq[i]);
+		snprintf(kts[i].name, sizeof(kts[i].name), "aoe_ktio%d", i);
+		kts[i].fn = ktio;
+		kts[i].waitq = &ktiowq[i];
+		kts[i].lock = &iocq[i].lock;
+		kts[i].id = i;
+		kts[i].active = 0;
+	}
+	kts[0].active = 1;
+	if (aoe_ktstart(&kts[0])) {
+		ret = -ENOMEM;
+		goto ktstart_fail;
+	}
+	return 0;
+
+ktstart_fail:
+	kfree(ktiowq);
+ktiowq_fail:
+	kfree(kts);
+kts_fail:
+	kfree(iocq);
+
+	return ret;
 }
 
 void
 aoecmd_exit(void)
 {
-	aoe_ktstop(&kts);
+	int i;
+
+	for (i = 0; i < ncpus; i++)
+		if (kts[i].active)
+			aoe_ktstop(&kts[i]);
+
 	aoe_flush_iocq();
 
+	/* Free up the iocq and thread speicific configuration
+	* allocated during startup.
+	*/
+	kfree(iocq);
+	kfree(kts);
+	kfree(ktiowq);
+
 	free_page((unsigned long) page_address(empty_page));
 	empty_page = NULL;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/aoe/aoedev.c linux-libre-3.11-rc7-gnu/drivers/block/aoe/aoedev.c
--- linux-libre-3.10-gnu/drivers/block/aoe/aoedev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/aoe/aoedev.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Coraid, Inc.  See COPYING for GPL terms. */
+/* Copyright (c) 2013 Coraid, Inc.  See COPYING for GPL terms. */
 /*
  * aoedev.c
  * AoE device utility functions; maintains device list.
@@ -518,7 +518,6 @@ void
 aoedev_exit(void)
 {
 	flush_scheduled_work();
-	aoe_flush_iocq();
 	flush(NULL, 0, EXITING);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/aoe/aoe.h linux-libre-3.11-rc7-gnu/drivers/block/aoe/aoe.h
--- linux-libre-3.10-gnu/drivers/block/aoe/aoe.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/aoe/aoe.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
-/* Copyright (c) 2012 Coraid, Inc.  See COPYING for GPL terms. */
-#define VERSION "81"
+/* Copyright (c) 2013 Coraid, Inc.  See COPYING for GPL terms. */
+#define VERSION "83"
 #define AOE_MAJOR 152
 #define DEVICE_NAME "aoe"
 
@@ -196,9 +196,11 @@ struct ktstate {
 	struct completion rendez;
 	struct task_struct *task;
 	wait_queue_head_t *waitq;
-	int (*fn) (void);
-	char *name;
+	int (*fn) (int);
+	char name[12];
 	spinlock_t *lock;
+	int id;
+	int active;
 };
 
 int aoeblk_init(void);
@@ -222,6 +224,7 @@ int aoecmd_init(void);
 struct sk_buff *aoecmd_ata_id(struct aoedev *);
 void aoe_freetframe(struct frame *);
 void aoe_flush_iocq(void);
+void aoe_flush_iocq_by_index(int);
 void aoe_end_request(struct aoedev *, struct request *, int);
 int aoe_ktstart(struct ktstate *k);
 void aoe_ktstop(struct ktstate *k);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/aoe/aoenet.c linux-libre-3.11-rc7-gnu/drivers/block/aoe/aoenet.c
--- linux-libre-3.10-gnu/drivers/block/aoe/aoenet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/aoe/aoenet.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 Coraid, Inc.  See COPYING for GPL terms. */
+/* Copyright (c) 2013 Coraid, Inc.  See COPYING for GPL terms. */
 /*
  * aoenet.c
  * Ethernet portion of AoE driver
@@ -52,7 +52,7 @@ static struct sk_buff_head skbtxq;
 
 /* enters with txlock held */
 static int
-tx(void) __must_hold(&txlock)
+tx(int id) __must_hold(&txlock)
 {
 	struct sk_buff *skb;
 	struct net_device *ifp;
@@ -205,7 +205,8 @@ aoenet_init(void)
 	kts.lock = &txlock;
 	kts.fn = tx;
 	kts.waitq = &txwq;
-	kts.name = "aoe_tx";
+	kts.id = 0;
+	snprintf(kts.name, sizeof(kts.name), "aoe_tx%d", kts.id);
 	if (aoe_ktstart(&kts))
 		return -EAGAIN;
 	dev_add_pack(&aoe_pt);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/cryptoloop.c linux-libre-3.11-rc7-gnu/drivers/block/cryptoloop.c
--- linux-libre-3.10-gnu/drivers/block/cryptoloop.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/cryptoloop.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,9 +25,9 @@
 #include <linux/string.h>
 #include <linux/crypto.h>
 #include <linux/blkdev.h>
-#include <linux/loop.h>
 #include <linux/scatterlist.h>
 #include <asm/uaccess.h>
+#include "loop.h"
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("loop blockdevice transferfunction adaptor / CryptoAPI");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/drbd/drbd_actlog.c linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_actlog.c
--- linux-libre-3.10-gnu/drivers/block/drbd/drbd_actlog.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_actlog.c	2013-08-25 20:43:22.000000000 -0400
@@ -659,6 +659,27 @@ void drbd_al_shrink(struct drbd_conf *md
 	wake_up(&mdev->al_wait);
 }
 
+int drbd_initialize_al(struct drbd_conf *mdev, void *buffer)
+{
+	struct al_transaction_on_disk *al = buffer;
+	struct drbd_md *md = &mdev->ldev->md;
+	sector_t al_base = md->md_offset + md->al_offset;
+	int al_size_4k = md->al_stripes * md->al_stripe_size_4k;
+	int i;
+
+	memset(al, 0, 4096);
+	al->magic = cpu_to_be32(DRBD_AL_MAGIC);
+	al->transaction_type = cpu_to_be16(AL_TR_INITIALIZED);
+	al->crc32c = cpu_to_be32(crc32c(0, al, 4096));
+
+	for (i = 0; i < al_size_4k; i++) {
+		int err = drbd_md_sync_page_io(mdev, mdev->ldev, al_base + i * 8, WRITE);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
 static int w_update_odbm(struct drbd_work *w, int unused)
 {
 	struct update_odbm_work *udw = container_of(w, struct update_odbm_work, w);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/drbd/drbd_int.h linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_int.h
--- linux-libre-3.10-gnu/drivers/block/drbd/drbd_int.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_int.h	2013-08-25 20:43:22.000000000 -0400
@@ -832,6 +832,7 @@ struct drbd_tconn {			/* is a resource f
 	unsigned susp_nod:1;		/* IO suspended because no data */
 	unsigned susp_fen:1;		/* IO suspended because fence peer handler runs */
 	struct mutex cstate_mutex;	/* Protects graceful disconnects */
+	unsigned int connect_cnt;	/* Inc each time a connection is established */
 
 	unsigned long flags;
 	struct net_conf *net_conf;	/* content protected by rcu */
@@ -1132,6 +1133,7 @@ extern void drbd_mdev_cleanup(struct drb
 void drbd_print_uuids(struct drbd_conf *mdev, const char *text);
 
 extern void conn_md_sync(struct drbd_tconn *tconn);
+extern void drbd_md_write(struct drbd_conf *mdev, void *buffer);
 extern void drbd_md_sync(struct drbd_conf *mdev);
 extern int  drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev);
 extern void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local);
@@ -1466,8 +1468,16 @@ extern void drbd_suspend_io(struct drbd_
 extern void drbd_resume_io(struct drbd_conf *mdev);
 extern char *ppsize(char *buf, unsigned long long size);
 extern sector_t drbd_new_dev_size(struct drbd_conf *, struct drbd_backing_dev *, sector_t, int);
-enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 };
-extern enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local);
+enum determine_dev_size {
+	DS_ERROR_SHRINK = -3,
+	DS_ERROR_SPACE_MD = -2,
+	DS_ERROR = -1,
+	DS_UNCHANGED = 0,
+	DS_SHRUNK = 1,
+	DS_GREW = 2
+};
+extern enum determine_dev_size
+drbd_determine_dev_size(struct drbd_conf *, enum dds_flags, struct resize_parms *) __must_hold(local);
 extern void resync_after_online_grow(struct drbd_conf *);
 extern void drbd_reconsider_max_bio_size(struct drbd_conf *mdev);
 extern enum drbd_state_rv drbd_set_role(struct drbd_conf *mdev,
@@ -1633,6 +1643,7 @@ extern int __drbd_set_out_of_sync(struct
 #define drbd_set_out_of_sync(mdev, sector, size) \
 	__drbd_set_out_of_sync(mdev, sector, size, __FILE__, __LINE__)
 extern void drbd_al_shrink(struct drbd_conf *mdev);
+extern int drbd_initialize_al(struct drbd_conf *, void *);
 
 /* drbd_nl.c */
 /* state info broadcast */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/drbd/drbd_main.c linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_main.c
--- linux-libre-3.10-gnu/drivers/block/drbd/drbd_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -2762,8 +2762,6 @@ int __init drbd_init(void)
 	/*
 	 * allocate all necessary structs
 	 */
-	err = -ENOMEM;
-
 	init_waitqueue_head(&drbd_pp_wait);
 
 	drbd_proc = NULL; /* play safe for drbd_cleanup */
@@ -2773,6 +2771,7 @@ int __init drbd_init(void)
 	if (err)
 		goto fail;
 
+	err = -ENOMEM;
 	drbd_proc = proc_create_data("drbd", S_IFREG | S_IRUGO , NULL, &drbd_proc_fops, NULL);
 	if (!drbd_proc)	{
 		printk(KERN_ERR "drbd: unable to register proc file\n");
@@ -2803,7 +2802,6 @@ int __init drbd_init(void)
 fail:
 	drbd_cleanup();
 	if (err == -ENOMEM)
-		/* currently always the case */
 		printk(KERN_ERR "drbd: ran out of memory\n");
 	else
 		printk(KERN_ERR "drbd: initialization failure\n");
@@ -2881,34 +2879,14 @@ struct meta_data_on_disk {
 	u8 reserved_u8[4096 - (7*8 + 10*4)];
 } __packed;
 
-/**
- * drbd_md_sync() - Writes the meta data super block if the MD_DIRTY flag bit is set
- * @mdev:	DRBD device.
- */
-void drbd_md_sync(struct drbd_conf *mdev)
+
+
+void drbd_md_write(struct drbd_conf *mdev, void *b)
 {
-	struct meta_data_on_disk *buffer;
+	struct meta_data_on_disk *buffer = b;
 	sector_t sector;
 	int i;
 
-	/* Don't accidentally change the DRBD meta data layout. */
-	BUILD_BUG_ON(UI_SIZE != 4);
-	BUILD_BUG_ON(sizeof(struct meta_data_on_disk) != 4096);
-
-	del_timer(&mdev->md_sync_timer);
-	/* timer may be rearmed by drbd_md_mark_dirty() now. */
-	if (!test_and_clear_bit(MD_DIRTY, &mdev->flags))
-		return;
-
-	/* We use here D_FAILED and not D_ATTACHING because we try to write
-	 * metadata even if we detach due to a disk failure! */
-	if (!get_ldev_if_state(mdev, D_FAILED))
-		return;
-
-	buffer = drbd_md_get_buffer(mdev);
-	if (!buffer)
-		goto out;
-
 	memset(buffer, 0, sizeof(*buffer));
 
 	buffer->la_size_sect = cpu_to_be64(drbd_get_capacity(mdev->this_bdev));
@@ -2937,6 +2915,35 @@ void drbd_md_sync(struct drbd_conf *mdev
 		dev_err(DEV, "meta data update failed!\n");
 		drbd_chk_io_error(mdev, 1, DRBD_META_IO_ERROR);
 	}
+}
+
+/**
+ * drbd_md_sync() - Writes the meta data super block if the MD_DIRTY flag bit is set
+ * @mdev:	DRBD device.
+ */
+void drbd_md_sync(struct drbd_conf *mdev)
+{
+	struct meta_data_on_disk *buffer;
+
+	/* Don't accidentally change the DRBD meta data layout. */
+	BUILD_BUG_ON(UI_SIZE != 4);
+	BUILD_BUG_ON(sizeof(struct meta_data_on_disk) != 4096);
+
+	del_timer(&mdev->md_sync_timer);
+	/* timer may be rearmed by drbd_md_mark_dirty() now. */
+	if (!test_and_clear_bit(MD_DIRTY, &mdev->flags))
+		return;
+
+	/* We use here D_FAILED and not D_ATTACHING because we try to write
+	 * metadata even if we detach due to a disk failure! */
+	if (!get_ldev_if_state(mdev, D_FAILED))
+		return;
+
+	buffer = drbd_md_get_buffer(mdev);
+	if (!buffer)
+		goto out;
+
+	drbd_md_write(mdev, buffer);
 
 	/* Update mdev->ldev->md.la_size_sect,
 	 * since we updated it on metadata. */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/drbd/drbd_nl.c linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_nl.c
--- linux-libre-3.10-gnu/drivers/block/drbd/drbd_nl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_nl.c	2013-08-25 20:43:22.000000000 -0400
@@ -417,6 +417,7 @@ static enum drbd_fencing_p highest_fenci
 
 bool conn_try_outdate_peer(struct drbd_tconn *tconn)
 {
+	unsigned int connect_cnt;
 	union drbd_state mask = { };
 	union drbd_state val = { };
 	enum drbd_fencing_p fp;
@@ -428,6 +429,10 @@ bool conn_try_outdate_peer(struct drbd_t
 		return false;
 	}
 
+	spin_lock_irq(&tconn->req_lock);
+	connect_cnt = tconn->connect_cnt;
+	spin_unlock_irq(&tconn->req_lock);
+
 	fp = highest_fencing_policy(tconn);
 	switch (fp) {
 	case FP_NOT_AVAIL:
@@ -492,8 +497,14 @@ bool conn_try_outdate_peer(struct drbd_t
 	   here, because we might were able to re-establish the connection in the
 	   meantime. */
 	spin_lock_irq(&tconn->req_lock);
-	if (tconn->cstate < C_WF_REPORT_PARAMS && !test_bit(STATE_SENT, &tconn->flags))
-		_conn_request_state(tconn, mask, val, CS_VERBOSE);
+	if (tconn->cstate < C_WF_REPORT_PARAMS && !test_bit(STATE_SENT, &tconn->flags)) {
+		if (tconn->connect_cnt != connect_cnt)
+			/* In case the connection was established and droped
+			   while the fence-peer handler was running, ignore it */
+			conn_info(tconn, "Ignoring fence-peer exit code\n");
+		else
+			_conn_request_state(tconn, mask, val, CS_VERBOSE);
+	}
 	spin_unlock_irq(&tconn->req_lock);
 
 	return conn_highest_pdsk(tconn) <= D_OUTDATED;
@@ -816,15 +827,20 @@ void drbd_resume_io(struct drbd_conf *md
  * Returns 0 on success, negative return values indicate errors.
  * You should call drbd_md_sync() after calling this function.
  */
-enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds_flags flags) __must_hold(local)
+enum determine_dev_size
+drbd_determine_dev_size(struct drbd_conf *mdev, enum dds_flags flags, struct resize_parms *rs) __must_hold(local)
 {
 	sector_t prev_first_sect, prev_size; /* previous meta location */
 	sector_t la_size_sect, u_size;
+	struct drbd_md *md = &mdev->ldev->md;
+	u32 prev_al_stripe_size_4k;
+	u32 prev_al_stripes;
 	sector_t size;
 	char ppb[10];
+	void *buffer;
 
 	int md_moved, la_size_changed;
-	enum determine_dev_size rv = unchanged;
+	enum determine_dev_size rv = DS_UNCHANGED;
 
 	/* race:
 	 * application request passes inc_ap_bio,
@@ -836,6 +852,11 @@ enum determine_dev_size drbd_determine_d
 	 * still lock the act_log to not trigger ASSERTs there.
 	 */
 	drbd_suspend_io(mdev);
+	buffer = drbd_md_get_buffer(mdev); /* Lock meta-data IO */
+	if (!buffer) {
+		drbd_resume_io(mdev);
+		return DS_ERROR;
+	}
 
 	/* no wait necessary anymore, actually we could assert that */
 	wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
@@ -844,7 +865,17 @@ enum determine_dev_size drbd_determine_d
 	prev_size = mdev->ldev->md.md_size_sect;
 	la_size_sect = mdev->ldev->md.la_size_sect;
 
-	/* TODO: should only be some assert here, not (re)init... */
+	if (rs) {
+		/* rs is non NULL if we should change the AL layout only */
+
+		prev_al_stripes = md->al_stripes;
+		prev_al_stripe_size_4k = md->al_stripe_size_4k;
+
+		md->al_stripes = rs->al_stripes;
+		md->al_stripe_size_4k = rs->al_stripe_size / 4;
+		md->al_size_4k = (u64)rs->al_stripes * rs->al_stripe_size / 4;
+	}
+
 	drbd_md_set_sector_offsets(mdev, mdev->ldev);
 
 	rcu_read_lock();
@@ -852,6 +883,21 @@ enum determine_dev_size drbd_determine_d
 	rcu_read_unlock();
 	size = drbd_new_dev_size(mdev, mdev->ldev, u_size, flags & DDSF_FORCED);
 
+	if (size < la_size_sect) {
+		if (rs && u_size == 0) {
+			/* Remove "rs &&" later. This check should always be active, but
+			   right now the receiver expects the permissive behavior */
+			dev_warn(DEV, "Implicit shrink not allowed. "
+				 "Use --size=%llus for explicit shrink.\n",
+				 (unsigned long long)size);
+			rv = DS_ERROR_SHRINK;
+		}
+		if (u_size > size)
+			rv = DS_ERROR_SPACE_MD;
+		if (rv != DS_UNCHANGED)
+			goto err_out;
+	}
+
 	if (drbd_get_capacity(mdev->this_bdev) != size ||
 	    drbd_bm_capacity(mdev) != size) {
 		int err;
@@ -867,7 +913,7 @@ enum determine_dev_size drbd_determine_d
 				    "Leaving size unchanged at size = %lu KB\n",
 				    (unsigned long)size);
 			}
-			rv = dev_size_error;
+			rv = DS_ERROR;
 		}
 		/* racy, see comments above. */
 		drbd_set_my_capacity(mdev, size);
@@ -875,38 +921,57 @@ enum determine_dev_size drbd_determine_d
 		dev_info(DEV, "size = %s (%llu KB)\n", ppsize(ppb, size>>1),
 		     (unsigned long long)size>>1);
 	}
-	if (rv == dev_size_error)
-		goto out;
+	if (rv <= DS_ERROR)
+		goto err_out;
 
 	la_size_changed = (la_size_sect != mdev->ldev->md.la_size_sect);
 
 	md_moved = prev_first_sect != drbd_md_first_sector(mdev->ldev)
 		|| prev_size	   != mdev->ldev->md.md_size_sect;
 
-	if (la_size_changed || md_moved) {
-		int err;
+	if (la_size_changed || md_moved || rs) {
+		u32 prev_flags;
 
 		drbd_al_shrink(mdev); /* All extents inactive. */
+
+		prev_flags = md->flags;
+		md->flags &= ~MDF_PRIMARY_IND;
+		drbd_md_write(mdev, buffer);
+
 		dev_info(DEV, "Writing the whole bitmap, %s\n",
 			 la_size_changed && md_moved ? "size changed and md moved" :
 			 la_size_changed ? "size changed" : "md moved");
 		/* next line implicitly does drbd_suspend_io()+drbd_resume_io() */
-		err = drbd_bitmap_io(mdev, md_moved ? &drbd_bm_write_all : &drbd_bm_write,
-				     "size changed", BM_LOCKED_MASK);
-		if (err) {
-			rv = dev_size_error;
-			goto out;
-		}
-		drbd_md_mark_dirty(mdev);
+		drbd_bitmap_io(mdev, md_moved ? &drbd_bm_write_all : &drbd_bm_write,
+			       "size changed", BM_LOCKED_MASK);
+		drbd_initialize_al(mdev, buffer);
+
+		md->flags = prev_flags;
+		drbd_md_write(mdev, buffer);
+
+		if (rs)
+			dev_info(DEV, "Changed AL layout to al-stripes = %d, al-stripe-size-kB = %d\n",
+				 md->al_stripes, md->al_stripe_size_4k * 4);
 	}
 
 	if (size > la_size_sect)
-		rv = grew;
+		rv = DS_GREW;
 	if (size < la_size_sect)
-		rv = shrunk;
-out:
+		rv = DS_SHRUNK;
+
+	if (0) {
+	err_out:
+		if (rs) {
+			md->al_stripes = prev_al_stripes;
+			md->al_stripe_size_4k = prev_al_stripe_size_4k;
+			md->al_size_4k = (u64)prev_al_stripes * prev_al_stripe_size_4k;
+
+			drbd_md_set_sector_offsets(mdev, mdev->ldev);
+		}
+	}
 	lc_unlock(mdev->act_log);
 	wake_up(&mdev->al_wait);
+	drbd_md_put_buffer(mdev);
 	drbd_resume_io(mdev);
 
 	return rv;
@@ -1607,11 +1672,11 @@ int drbd_adm_attach(struct sk_buff *skb,
 	    !drbd_md_test_flag(mdev->ldev, MDF_CONNECTED_IND))
 		set_bit(USE_DEGR_WFC_T, &mdev->flags);
 
-	dd = drbd_determine_dev_size(mdev, 0);
-	if (dd == dev_size_error) {
+	dd = drbd_determine_dev_size(mdev, 0, NULL);
+	if (dd <= DS_ERROR) {
 		retcode = ERR_NOMEM_BITMAP;
 		goto force_diskless_dec;
-	} else if (dd == grew)
+	} else if (dd == DS_GREW)
 		set_bit(RESYNC_AFTER_NEG, &mdev->flags);
 
 	if (drbd_md_test_flag(mdev->ldev, MDF_FULL_SYNC) ||
@@ -2305,6 +2370,7 @@ int drbd_adm_resize(struct sk_buff *skb,
 	struct drbd_conf *mdev;
 	enum drbd_ret_code retcode;
 	enum determine_dev_size dd;
+	bool change_al_layout = false;
 	enum dds_flags ddsf;
 	sector_t u_size;
 	int err;
@@ -2315,31 +2381,33 @@ int drbd_adm_resize(struct sk_buff *skb,
 	if (retcode != NO_ERROR)
 		goto fail;
 
+	mdev = adm_ctx.mdev;
+	if (!get_ldev(mdev)) {
+		retcode = ERR_NO_DISK;
+		goto fail;
+	}
+
 	memset(&rs, 0, sizeof(struct resize_parms));
+	rs.al_stripes = mdev->ldev->md.al_stripes;
+	rs.al_stripe_size = mdev->ldev->md.al_stripe_size_4k * 4;
 	if (info->attrs[DRBD_NLA_RESIZE_PARMS]) {
 		err = resize_parms_from_attrs(&rs, info);
 		if (err) {
 			retcode = ERR_MANDATORY_TAG;
 			drbd_msg_put_info(from_attrs_err_to_txt(err));
-			goto fail;
+			goto fail_ldev;
 		}
 	}
 
-	mdev = adm_ctx.mdev;
 	if (mdev->state.conn > C_CONNECTED) {
 		retcode = ERR_RESIZE_RESYNC;
-		goto fail;
+		goto fail_ldev;
 	}
 
 	if (mdev->state.role == R_SECONDARY &&
 	    mdev->state.peer == R_SECONDARY) {
 		retcode = ERR_NO_PRIMARY;
-		goto fail;
-	}
-
-	if (!get_ldev(mdev)) {
-		retcode = ERR_NO_DISK;
-		goto fail;
+		goto fail_ldev;
 	}
 
 	if (rs.no_resync && mdev->tconn->agreed_pro_version < 93) {
@@ -2358,6 +2426,28 @@ int drbd_adm_resize(struct sk_buff *skb,
 		}
 	}
 
+	if (mdev->ldev->md.al_stripes != rs.al_stripes ||
+	    mdev->ldev->md.al_stripe_size_4k != rs.al_stripe_size / 4) {
+		u32 al_size_k = rs.al_stripes * rs.al_stripe_size;
+
+		if (al_size_k > (16 * 1024 * 1024)) {
+			retcode = ERR_MD_LAYOUT_TOO_BIG;
+			goto fail_ldev;
+		}
+
+		if (al_size_k < MD_32kB_SECT/2) {
+			retcode = ERR_MD_LAYOUT_TOO_SMALL;
+			goto fail_ldev;
+		}
+
+		if (mdev->state.conn != C_CONNECTED) {
+			retcode = ERR_MD_LAYOUT_CONNECTED;
+			goto fail_ldev;
+		}
+
+		change_al_layout = true;
+	}
+
 	if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev))
 		mdev->ldev->known_size = drbd_get_capacity(mdev->ldev->backing_bdev);
 
@@ -2373,16 +2463,22 @@ int drbd_adm_resize(struct sk_buff *skb,
 	}
 
 	ddsf = (rs.resize_force ? DDSF_FORCED : 0) | (rs.no_resync ? DDSF_NO_RESYNC : 0);
-	dd = drbd_determine_dev_size(mdev, ddsf);
+	dd = drbd_determine_dev_size(mdev, ddsf, change_al_layout ? &rs : NULL);
 	drbd_md_sync(mdev);
 	put_ldev(mdev);
-	if (dd == dev_size_error) {
+	if (dd == DS_ERROR) {
 		retcode = ERR_NOMEM_BITMAP;
 		goto fail;
+	} else if (dd == DS_ERROR_SPACE_MD) {
+		retcode = ERR_MD_LAYOUT_NO_FIT;
+		goto fail;
+	} else if (dd == DS_ERROR_SHRINK) {
+		retcode = ERR_IMPLICIT_SHRINK;
+		goto fail;
 	}
 
 	if (mdev->state.conn == C_CONNECTED) {
-		if (dd == grew)
+		if (dd == DS_GREW)
 			set_bit(RESIZE_PENDING, &mdev->flags);
 
 		drbd_send_uuids(mdev);
@@ -2658,7 +2754,6 @@ int nla_put_status_info(struct sk_buff *
 		const struct sib_info *sib)
 {
 	struct state_info *si = NULL; /* for sizeof(si->member); */
-	struct net_conf *nc;
 	struct nlattr *nla;
 	int got_ldev;
 	int err = 0;
@@ -2688,13 +2783,19 @@ int nla_put_status_info(struct sk_buff *
 		goto nla_put_failure;
 
 	rcu_read_lock();
-	if (got_ldev)
-		if (disk_conf_to_skb(skb, rcu_dereference(mdev->ldev->disk_conf), exclude_sensitive))
-			goto nla_put_failure;
+	if (got_ldev) {
+		struct disk_conf *disk_conf;
 
-	nc = rcu_dereference(mdev->tconn->net_conf);
-	if (nc)
-		err = net_conf_to_skb(skb, nc, exclude_sensitive);
+		disk_conf = rcu_dereference(mdev->ldev->disk_conf);
+		err = disk_conf_to_skb(skb, disk_conf, exclude_sensitive);
+	}
+	if (!err) {
+		struct net_conf *nc;
+
+		nc = rcu_dereference(mdev->tconn->net_conf);
+		if (nc)
+			err = net_conf_to_skb(skb, nc, exclude_sensitive);
+	}
 	rcu_read_unlock();
 	if (err)
 		goto nla_put_failure;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/drbd/drbd_receiver.c linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_receiver.c
--- linux-libre-3.10-gnu/drivers/block/drbd/drbd_receiver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_receiver.c	2013-08-25 20:43:22.000000000 -0400
@@ -1039,6 +1039,8 @@ randomize:
 	rcu_read_lock();
 	idr_for_each_entry(&tconn->volumes, mdev, vnr) {
 		kref_get(&mdev->kref);
+		rcu_read_unlock();
+
 		/* Prevent a race between resync-handshake and
 		 * being promoted to Primary.
 		 *
@@ -1049,8 +1051,6 @@ randomize:
 		mutex_lock(mdev->state_mutex);
 		mutex_unlock(mdev->state_mutex);
 
-		rcu_read_unlock();
-
 		if (discard_my_data)
 			set_bit(DISCARD_MY_DATA, &mdev->flags);
 		else
@@ -3545,7 +3545,7 @@ static int receive_sizes(struct drbd_tco
 {
 	struct drbd_conf *mdev;
 	struct p_sizes *p = pi->data;
-	enum determine_dev_size dd = unchanged;
+	enum determine_dev_size dd = DS_UNCHANGED;
 	sector_t p_size, p_usize, my_usize;
 	int ldsc = 0; /* local disk size changed */
 	enum dds_flags ddsf;
@@ -3617,9 +3617,9 @@ static int receive_sizes(struct drbd_tco
 
 	ddsf = be16_to_cpu(p->dds_flags);
 	if (get_ldev(mdev)) {
-		dd = drbd_determine_dev_size(mdev, ddsf);
+		dd = drbd_determine_dev_size(mdev, ddsf, NULL);
 		put_ldev(mdev);
-		if (dd == dev_size_error)
+		if (dd == DS_ERROR)
 			return -EIO;
 		drbd_md_sync(mdev);
 	} else {
@@ -3647,7 +3647,7 @@ static int receive_sizes(struct drbd_tco
 			drbd_send_sizes(mdev, 0, ddsf);
 		}
 		if (test_and_clear_bit(RESIZE_PENDING, &mdev->flags) ||
-		    (dd == grew && mdev->state.conn == C_CONNECTED)) {
+		    (dd == DS_GREW && mdev->state.conn == C_CONNECTED)) {
 			if (mdev->state.pdsk >= D_INCONSISTENT &&
 			    mdev->state.disk >= D_INCONSISTENT) {
 				if (ddsf & DDSF_NO_RESYNC)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/drbd/drbd_state.c linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_state.c
--- linux-libre-3.10-gnu/drivers/block/drbd/drbd_state.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/drbd/drbd_state.c	2013-08-25 20:43:22.000000000 -0400
@@ -1115,8 +1115,10 @@ __drbd_set_state(struct drbd_conf *mdev,
 		drbd_thread_restart_nowait(&mdev->tconn->receiver);
 
 	/* Resume AL writing if we get a connection */
-	if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)
+	if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
 		drbd_resume_al(mdev);
+		mdev->tconn->connect_cnt++;
+	}
 
 	/* remember last attach time so request_timer_fn() won't
 	 * kill newly established sessions while we are still trying to thaw
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/Kconfig linux-libre-3.11-rc7-gnu/drivers/block/Kconfig
--- linux-libre-3.10-gnu/drivers/block/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -532,11 +532,11 @@ config BLK_DEV_RBD
 	  If unsure, say N.
 
 config BLK_DEV_RSXX
-	tristate "IBM FlashSystem 70/80 PCIe SSD Device Driver"
+	tristate "IBM Flash Adapter 900GB Full Height PCIe Device Driver"
 	depends on PCI
 	help
 	  Device driver for IBM's high speed PCIe SSD
-	  storage devices: FlashSystem-70 and FlashSystem-80.
+	  storage device: Flash Adapter 900GB Full Height.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called rsxx.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/loop.c linux-libre-3.11-rc7-gnu/drivers/block/loop.c
--- linux-libre-3.10-gnu/drivers/block/loop.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/loop.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,7 +63,6 @@
 #include <linux/init.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
-#include <linux/loop.h>
 #include <linux/compat.h>
 #include <linux/suspend.h>
 #include <linux/freezer.h>
@@ -76,6 +75,7 @@
 #include <linux/sysfs.h>
 #include <linux/miscdevice.h>
 #include <linux/falloc.h>
+#include "loop.h"
 
 #include <asm/uaccess.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/loop.h linux-libre-3.11-rc7-gnu/drivers/block/loop.h
--- linux-libre-3.10-gnu/drivers/block/loop.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/block/loop.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,85 @@
+/*
+ * loop.h
+ *
+ * Written by Theodore Ts'o, 3/29/93.
+ *
+ * Copyright 1993 by Theodore Ts'o.  Redistribution of this file is
+ * permitted under the GNU General Public License.
+ */
+#ifndef _LINUX_LOOP_H
+#define _LINUX_LOOP_H
+
+#include <linux/bio.h>
+#include <linux/blkdev.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <uapi/linux/loop.h>
+
+/* Possible states of device */
+enum {
+	Lo_unbound,
+	Lo_bound,
+	Lo_rundown,
+};
+
+struct loop_func_table;
+
+struct loop_device {
+	int		lo_number;
+	int		lo_refcnt;
+	loff_t		lo_offset;
+	loff_t		lo_sizelimit;
+	int		lo_flags;
+	int		(*transfer)(struct loop_device *, int cmd,
+				    struct page *raw_page, unsigned raw_off,
+				    struct page *loop_page, unsigned loop_off,
+				    int size, sector_t real_block);
+	char		lo_file_name[LO_NAME_SIZE];
+	char		lo_crypt_name[LO_NAME_SIZE];
+	char		lo_encrypt_key[LO_KEY_SIZE];
+	int		lo_encrypt_key_size;
+	struct loop_func_table *lo_encryption;
+	__u32           lo_init[2];
+	kuid_t		lo_key_owner;	/* Who set the key */
+	int		(*ioctl)(struct loop_device *, int cmd, 
+				 unsigned long arg); 
+
+	struct file *	lo_backing_file;
+	struct block_device *lo_device;
+	unsigned	lo_blocksize;
+	void		*key_data; 
+
+	gfp_t		old_gfp_mask;
+
+	spinlock_t		lo_lock;
+	struct bio_list		lo_bio_list;
+	unsigned int		lo_bio_count;
+	int			lo_state;
+	struct mutex		lo_ctl_mutex;
+	struct task_struct	*lo_thread;
+	wait_queue_head_t	lo_event;
+	/* wait queue for incoming requests */
+	wait_queue_head_t	lo_req_wait;
+
+	struct request_queue	*lo_queue;
+	struct gendisk		*lo_disk;
+};
+
+/* Support for loadable transfer modules */
+struct loop_func_table {
+	int number;	/* filter type */ 
+	int (*transfer)(struct loop_device *lo, int cmd,
+			struct page *raw_page, unsigned raw_off,
+			struct page *loop_page, unsigned loop_off,
+			int size, sector_t real_block);
+	int (*init)(struct loop_device *, const struct loop_info64 *); 
+	/* release is called from loop_unregister_transfer or clr_fd */
+	int (*release)(struct loop_device *); 
+	int (*ioctl)(struct loop_device *, int cmd, unsigned long arg);
+	struct module *owner;
+}; 
+
+int loop_register_transfer(struct loop_func_table *funcs);
+int loop_unregister_transfer(int number); 
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/mtip32xx/mtip32xx.c linux-libre-3.11-rc7-gnu/drivers/block/mtip32xx/mtip32xx.c
--- linux-libre-3.10-gnu/drivers/block/mtip32xx/mtip32xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/mtip32xx/mtip32xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -4087,7 +4087,8 @@ skip_create_disk:
 start_service_thread:
 	sprintf(thd_name, "mtip_svc_thd_%02d", index);
 	dd->mtip_svc_handler = kthread_create_on_node(mtip_service_thread,
-						dd, dd->numa_node, thd_name);
+						dd, dd->numa_node, "%s",
+						thd_name);
 
 	if (IS_ERR(dd->mtip_svc_handler)) {
 		dev_err(&dd->pdev->dev, "service thread failed to start\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/nbd.c linux-libre-3.11-rc7-gnu/drivers/block/nbd.c
--- linux-libre-3.10-gnu/drivers/block/nbd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/nbd.c	2013-08-25 20:43:22.000000000 -0400
@@ -623,8 +623,10 @@ static int __nbd_ioctl(struct block_devi
 		if (!nbd->sock)
 			return -EINVAL;
 
+		nbd->disconnect = 1;
+
 		nbd_send_req(nbd, &sreq);
-                return 0;
+		return 0;
 	}
  
 	case NBD_CLEAR_SOCK: {
@@ -654,6 +656,7 @@ static int __nbd_ioctl(struct block_devi
 				nbd->sock = SOCKET_I(inode);
 				if (max_part > 0)
 					bdev->bd_invalidated = 1;
+				nbd->disconnect = 0; /* we're connected now */
 				return 0;
 			} else {
 				fput(file);
@@ -714,7 +717,8 @@ static int __nbd_ioctl(struct block_devi
 		else
 			blk_queue_flush(nbd->disk->queue, 0);
 
-		thread = kthread_create(nbd_thread, nbd, nbd->disk->disk_name);
+		thread = kthread_create(nbd_thread, nbd, "%s",
+					nbd->disk->disk_name);
 		if (IS_ERR(thread)) {
 			mutex_lock(&nbd->tx_lock);
 			return PTR_ERR(thread);
@@ -742,6 +746,8 @@ static int __nbd_ioctl(struct block_devi
 		set_capacity(nbd->disk, 0);
 		if (max_part > 0)
 			ioctl_by_bdev(bdev, BLKRRPART, 0);
+		if (nbd->disconnect) /* user requested, ignore socket errors */
+			return 0;
 		return nbd->harderror;
 	}
 
@@ -750,7 +756,6 @@ static int __nbd_ioctl(struct block_devi
 		 * This is for compatibility only.  The queue is always cleared
 		 * by NBD_DO_IT or NBD_CLEAR_SOCK.
 		 */
-		BUG_ON(!nbd->sock && !list_empty(&nbd->queue_head));
 		return 0;
 
 	case NBD_PRINT_DEBUG:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/rbd.c linux-libre-3.11-rc7-gnu/drivers/block/rbd.c
--- linux-libre-3.10-gnu/drivers/block/rbd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/rbd.c	2013-08-25 20:43:22.000000000 -0400
@@ -372,7 +372,7 @@ enum rbd_dev_flags {
 	RBD_DEV_FLAG_REMOVING,	/* this mapping is being removed */
 };
 
-static DEFINE_MUTEX(ctl_mutex);	  /* Serialize open/close/setup/teardown */
+static DEFINE_MUTEX(client_mutex);	/* Serialize client creation */
 
 static LIST_HEAD(rbd_dev_list);    /* devices */
 static DEFINE_SPINLOCK(rbd_dev_list_lock);
@@ -489,10 +489,8 @@ static int rbd_open(struct block_device
 	if (removing)
 		return -ENOENT;
 
-	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 	(void) get_device(&rbd_dev->dev);
 	set_device_ro(bdev, rbd_dev->mapping.read_only);
-	mutex_unlock(&ctl_mutex);
 
 	return 0;
 }
@@ -507,9 +505,7 @@ static void rbd_release(struct gendisk *
 	spin_unlock_irq(&rbd_dev->lock);
 	rbd_assert(open_count_before > 0);
 
-	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 	put_device(&rbd_dev->dev);
-	mutex_unlock(&ctl_mutex);
 }
 
 static const struct block_device_operations rbd_bd_ops = {
@@ -520,7 +516,7 @@ static const struct block_device_operati
 
 /*
  * Initialize an rbd client instance.  Success or not, this function
- * consumes ceph_opts.
+ * consumes ceph_opts.  Caller holds client_mutex.
  */
 static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts)
 {
@@ -535,30 +531,25 @@ static struct rbd_client *rbd_client_cre
 	kref_init(&rbdc->kref);
 	INIT_LIST_HEAD(&rbdc->node);
 
-	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
 	rbdc->client = ceph_create_client(ceph_opts, rbdc, 0, 0);
 	if (IS_ERR(rbdc->client))
-		goto out_mutex;
+		goto out_rbdc;
 	ceph_opts = NULL; /* Now rbdc->client is responsible for ceph_opts */
 
 	ret = ceph_open_session(rbdc->client);
 	if (ret < 0)
-		goto out_err;
+		goto out_client;
 
 	spin_lock(&rbd_client_list_lock);
 	list_add_tail(&rbdc->node, &rbd_client_list);
 	spin_unlock(&rbd_client_list_lock);
 
-	mutex_unlock(&ctl_mutex);
 	dout("%s: rbdc %p\n", __func__, rbdc);
 
 	return rbdc;
-
-out_err:
+out_client:
 	ceph_destroy_client(rbdc->client);
-out_mutex:
-	mutex_unlock(&ctl_mutex);
+out_rbdc:
 	kfree(rbdc);
 out_opt:
 	if (ceph_opts)
@@ -682,11 +673,13 @@ static struct rbd_client *rbd_get_client
 {
 	struct rbd_client *rbdc;
 
+	mutex_lock_nested(&client_mutex, SINGLE_DEPTH_NESTING);
 	rbdc = rbd_client_find(ceph_opts);
 	if (rbdc)	/* using an existing client */
 		ceph_destroy_options(ceph_opts);
 	else
 		rbdc = rbd_client_create(ceph_opts);
+	mutex_unlock(&client_mutex);
 
 	return rbdc;
 }
@@ -840,7 +833,6 @@ static int rbd_header_from_disk(struct r
 
 	/* We won't fail any more, fill in the header */
 
-	down_write(&rbd_dev->header_rwsem);
 	if (first_time) {
 		header->object_prefix = object_prefix;
 		header->obj_order = ondisk->options.order;
@@ -869,8 +861,6 @@ static int rbd_header_from_disk(struct r
 		if (rbd_dev->mapping.size != header->image_size)
 			rbd_dev->mapping.size = header->image_size;
 
-	up_write(&rbd_dev->header_rwsem);
-
 	return 0;
 out_2big:
 	ret = -EIO;
@@ -1126,6 +1116,7 @@ static void zero_bio_chain(struct bio *c
 				buf = bvec_kmap_irq(bv, &flags);
 				memset(buf + remainder, 0,
 				       bv->bv_len - remainder);
+				flush_dcache_page(bv->bv_page);
 				bvec_kunmap_irq(buf, &flags);
 			}
 			pos += bv->bv_len;
@@ -1153,11 +1144,12 @@ static void zero_pages(struct page **pag
 		unsigned long flags;
 		void *kaddr;
 
-		page_offset = (size_t)(offset & ~PAGE_MASK);
-		length = min(PAGE_SIZE - page_offset, (size_t)(end - offset));
+		page_offset = offset & ~PAGE_MASK;
+		length = min_t(size_t, PAGE_SIZE - page_offset, end - offset);
 		local_irq_save(flags);
 		kaddr = kmap_atomic(*page);
 		memset(kaddr + page_offset, 0, length);
+		flush_dcache_page(*page);
 		kunmap_atomic(kaddr);
 		local_irq_restore(flags);
 
@@ -2171,9 +2163,9 @@ static int rbd_img_request_fill(struct r
 	struct rbd_obj_request *obj_request = NULL;
 	struct rbd_obj_request *next_obj_request;
 	bool write_request = img_request_write_test(img_request);
-	struct bio *bio_list;
+	struct bio *bio_list = 0;
 	unsigned int bio_offset = 0;
-	struct page **pages;
+	struct page **pages = 0;
 	u64 img_offset;
 	u64 resid;
 	u16 opcode;
@@ -2535,6 +2527,7 @@ static void rbd_img_obj_exists_callback(
 	 */
 	orig_request = obj_request->obj_request;
 	obj_request->obj_request = NULL;
+	rbd_obj_request_put(orig_request);
 	rbd_assert(orig_request);
 	rbd_assert(orig_request->img_request);
 
@@ -2555,7 +2548,6 @@ static void rbd_img_obj_exists_callback(
 	if (!rbd_dev->parent_overlap) {
 		struct ceph_osd_client *osdc;
 
-		rbd_obj_request_put(orig_request);
 		osdc = &rbd_dev->rbd_client->client->osdc;
 		result = rbd_obj_request_submit(osdc, orig_request);
 		if (!result)
@@ -2585,7 +2577,6 @@ static void rbd_img_obj_exists_callback(
 out:
 	if (orig_request->result)
 		rbd_obj_request_complete(orig_request);
-	rbd_obj_request_put(orig_request);
 }
 
 static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)
@@ -2859,7 +2850,7 @@ static void rbd_watch_cb(u64 ver, u64 no
 		(unsigned int)opcode);
 	ret = rbd_dev_refresh(rbd_dev);
 	if (ret)
-		rbd_warn(rbd_dev, ": header refresh error (%d)\n", ret);
+		rbd_warn(rbd_dev, "header refresh error (%d)\n", ret);
 
 	rbd_obj_notify_ack(rbd_dev, notify_id);
 }
@@ -3339,8 +3330,8 @@ static int rbd_dev_refresh(struct rbd_de
 	int ret;
 
 	rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
+	down_write(&rbd_dev->header_rwsem);
 	mapping_size = rbd_dev->mapping.size;
-	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 	if (rbd_dev->image_format == 1)
 		ret = rbd_dev_v1_header_info(rbd_dev);
 	else
@@ -3349,7 +3340,8 @@ static int rbd_dev_refresh(struct rbd_de
 	/* If it's a mapped snapshot, validate its EXISTS flag */
 
 	rbd_exists_validate(rbd_dev);
-	mutex_unlock(&ctl_mutex);
+	up_write(&rbd_dev->header_rwsem);
+
 	if (mapping_size != rbd_dev->mapping.size) {
 		sector_t size;
 
@@ -3813,6 +3805,7 @@ static int rbd_dev_v2_parent_info(struct
 	void *end;
 	u64 pool_id;
 	char *image_id;
+	u64 snap_id;
 	u64 overlap;
 	int ret;
 
@@ -3872,24 +3865,56 @@ static int rbd_dev_v2_parent_info(struct
 			(unsigned long long)pool_id, U32_MAX);
 		goto out_err;
 	}
-	parent_spec->pool_id = pool_id;
 
 	image_id = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL);
 	if (IS_ERR(image_id)) {
 		ret = PTR_ERR(image_id);
 		goto out_err;
 	}
-	parent_spec->image_id = image_id;
-	ceph_decode_64_safe(&p, end, parent_spec->snap_id, out_err);
+	ceph_decode_64_safe(&p, end, snap_id, out_err);
 	ceph_decode_64_safe(&p, end, overlap, out_err);
 
-	if (overlap) {
-		rbd_spec_put(rbd_dev->parent_spec);
+	/*
+	 * The parent won't change (except when the clone is
+	 * flattened, already handled that).  So we only need to
+	 * record the parent spec we have not already done so.
+	 */
+	if (!rbd_dev->parent_spec) {
+		parent_spec->pool_id = pool_id;
+		parent_spec->image_id = image_id;
+		parent_spec->snap_id = snap_id;
 		rbd_dev->parent_spec = parent_spec;
 		parent_spec = NULL;	/* rbd_dev now owns this */
-		rbd_dev->parent_overlap = overlap;
-	} else {
-		rbd_warn(rbd_dev, "ignoring parent of clone with overlap 0\n");
+	}
+
+	/*
+	 * We always update the parent overlap.  If it's zero we
+	 * treat it specially.
+	 */
+	rbd_dev->parent_overlap = overlap;
+	smp_mb();
+	if (!overlap) {
+
+		/* A null parent_spec indicates it's the initial probe */
+
+		if (parent_spec) {
+			/*
+			 * The overlap has become zero, so the clone
+			 * must have been resized down to 0 at some
+			 * point.  Treat this the same as a flatten.
+			 */
+			rbd_dev_parent_put(rbd_dev);
+			pr_info("%s: clone image now standalone\n",
+				rbd_dev->disk->disk_name);
+		} else {
+			/*
+			 * For the initial probe, if we find the
+			 * overlap is zero we just pretend there was
+			 * no parent image.
+			 */
+			rbd_warn(rbd_dev, "ignoring parent of "
+						"clone with overlap 0\n");
+		}
 	}
 out:
 	ret = 0;
@@ -4245,16 +4270,14 @@ static int rbd_dev_v2_header_info(struct
 	bool first_time = rbd_dev->header.object_prefix == NULL;
 	int ret;
 
-	down_write(&rbd_dev->header_rwsem);
-
 	ret = rbd_dev_v2_image_size(rbd_dev);
 	if (ret)
-		goto out;
+		return ret;
 
 	if (first_time) {
 		ret = rbd_dev_v2_header_onetime(rbd_dev);
 		if (ret)
-			goto out;
+			return ret;
 	}
 
 	/*
@@ -4269,7 +4292,7 @@ static int rbd_dev_v2_header_info(struct
 
 		ret = rbd_dev_v2_parent_info(rbd_dev);
 		if (ret)
-			goto out;
+			return ret;
 
 		/*
 		 * Print a warning if this is the initial probe and
@@ -4290,8 +4313,6 @@ static int rbd_dev_v2_header_info(struct
 
 	ret = rbd_dev_v2_snap_context(rbd_dev);
 	dout("rbd_dev_v2_snap_context returned %d\n", ret);
-out:
-	up_write(&rbd_dev->header_rwsem);
 
 	return ret;
 }
@@ -4301,8 +4322,6 @@ static int rbd_bus_add_dev(struct rbd_de
 	struct device *dev;
 	int ret;
 
-	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
 	dev = &rbd_dev->dev;
 	dev->bus = &rbd_bus_type;
 	dev->type = &rbd_device_type;
@@ -4311,8 +4330,6 @@ static int rbd_bus_add_dev(struct rbd_de
 	dev_set_name(dev, "%d", rbd_dev->dev_id);
 	ret = device_register(dev);
 
-	mutex_unlock(&ctl_mutex);
-
 	return ret;
 }
 
@@ -5059,23 +5076,6 @@ err_out_module:
 	return (ssize_t)rc;
 }
 
-static struct rbd_device *__rbd_get_dev(unsigned long dev_id)
-{
-	struct list_head *tmp;
-	struct rbd_device *rbd_dev;
-
-	spin_lock(&rbd_dev_list_lock);
-	list_for_each(tmp, &rbd_dev_list) {
-		rbd_dev = list_entry(tmp, struct rbd_device, node);
-		if (rbd_dev->dev_id == dev_id) {
-			spin_unlock(&rbd_dev_list_lock);
-			return rbd_dev;
-		}
-	}
-	spin_unlock(&rbd_dev_list_lock);
-	return NULL;
-}
-
 static void rbd_dev_device_release(struct device *dev)
 {
 	struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
@@ -5120,8 +5120,10 @@ static ssize_t rbd_remove(struct bus_typ
 			  size_t count)
 {
 	struct rbd_device *rbd_dev = NULL;
-	int target_id;
+	struct list_head *tmp;
+	int dev_id;
 	unsigned long ul;
+	bool already = false;
 	int ret;
 
 	ret = strict_strtoul(buf, 10, &ul);
@@ -5129,37 +5131,40 @@ static ssize_t rbd_remove(struct bus_typ
 		return ret;
 
 	/* convert to int; abort if we lost anything in the conversion */
-	target_id = (int) ul;
-	if (target_id != ul)
+	dev_id = (int)ul;
+	if (dev_id != ul)
 		return -EINVAL;
 
-	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
-	rbd_dev = __rbd_get_dev(target_id);
-	if (!rbd_dev) {
-		ret = -ENOENT;
-		goto done;
+	ret = -ENOENT;
+	spin_lock(&rbd_dev_list_lock);
+	list_for_each(tmp, &rbd_dev_list) {
+		rbd_dev = list_entry(tmp, struct rbd_device, node);
+		if (rbd_dev->dev_id == dev_id) {
+			ret = 0;
+			break;
+		}
 	}
+	if (!ret) {
+		spin_lock_irq(&rbd_dev->lock);
+		if (rbd_dev->open_count)
+			ret = -EBUSY;
+		else
+			already = test_and_set_bit(RBD_DEV_FLAG_REMOVING,
+							&rbd_dev->flags);
+		spin_unlock_irq(&rbd_dev->lock);
+	}
+	spin_unlock(&rbd_dev_list_lock);
+	if (ret < 0 || already)
+		return ret;
 
-	spin_lock_irq(&rbd_dev->lock);
-	if (rbd_dev->open_count)
-		ret = -EBUSY;
-	else
-		set_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags);
-	spin_unlock_irq(&rbd_dev->lock);
-	if (ret < 0)
-		goto done;
 	rbd_bus_del_dev(rbd_dev);
 	ret = rbd_dev_header_watch_sync(rbd_dev, false);
 	if (ret)
 		rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret);
 	rbd_dev_image_release(rbd_dev);
 	module_put(THIS_MODULE);
-	ret = count;
-done:
-	mutex_unlock(&ctl_mutex);
 
-	return ret;
+	return count;
 }
 
 /*
@@ -5267,6 +5272,7 @@ static void __exit rbd_exit(void)
 module_init(rbd_init);
 module_exit(rbd_exit);
 
+MODULE_AUTHOR("Alex Elder <elder@inktank.com>");
 MODULE_AUTHOR("Sage Weil <sage@newdream.net>");
 MODULE_AUTHOR("Yehuda Sadeh <yehuda@hq.newdream.net>");
 MODULE_DESCRIPTION("rados block device");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/rsxx/core.c linux-libre-3.11-rc7-gnu/drivers/block/rsxx/core.c
--- linux-libre-3.10-gnu/drivers/block/rsxx/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/rsxx/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,8 @@
 #include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
 #include <linux/genhd.h>
 #include <linux/idr.h>
@@ -39,8 +41,9 @@
 #include "rsxx_cfg.h"
 
 #define NO_LEGACY 0
+#define SYNC_START_TIMEOUT (10 * 60) /* 10 minutes */
 
-MODULE_DESCRIPTION("IBM FlashSystem 70/80 PCIe SSD Device Driver");
+MODULE_DESCRIPTION("IBM Flash Adapter 900GB Full Height Device Driver");
 MODULE_AUTHOR("Joshua Morris/Philip Kelleher, IBM");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRIVER_VERSION);
@@ -49,9 +52,282 @@ static unsigned int force_legacy = NO_LE
 module_param(force_legacy, uint, 0444);
 MODULE_PARM_DESC(force_legacy, "Force the use of legacy type PCI interrupts");
 
+static unsigned int sync_start = 1;
+module_param(sync_start, uint, 0444);
+MODULE_PARM_DESC(sync_start, "On by Default: Driver load will not complete "
+			     "until the card startup has completed.");
+
 static DEFINE_IDA(rsxx_disk_ida);
 static DEFINE_SPINLOCK(rsxx_ida_lock);
 
+/* --------------------Debugfs Setup ------------------- */
+
+struct rsxx_cram {
+	u32 f_pos;
+	u32 offset;
+	void *i_private;
+};
+
+static int rsxx_attr_pci_regs_show(struct seq_file *m, void *p)
+{
+	struct rsxx_cardinfo *card = m->private;
+
+	seq_printf(m, "HWID		0x%08x\n",
+					ioread32(card->regmap + HWID));
+	seq_printf(m, "SCRATCH		0x%08x\n",
+					ioread32(card->regmap + SCRATCH));
+	seq_printf(m, "IER		0x%08x\n",
+					ioread32(card->regmap + IER));
+	seq_printf(m, "IPR		0x%08x\n",
+					ioread32(card->regmap + IPR));
+	seq_printf(m, "CREG_CMD		0x%08x\n",
+					ioread32(card->regmap + CREG_CMD));
+	seq_printf(m, "CREG_ADD		0x%08x\n",
+					ioread32(card->regmap + CREG_ADD));
+	seq_printf(m, "CREG_CNT		0x%08x\n",
+					ioread32(card->regmap + CREG_CNT));
+	seq_printf(m, "CREG_STAT	0x%08x\n",
+					ioread32(card->regmap + CREG_STAT));
+	seq_printf(m, "CREG_DATA0	0x%08x\n",
+					ioread32(card->regmap + CREG_DATA0));
+	seq_printf(m, "CREG_DATA1	0x%08x\n",
+					ioread32(card->regmap + CREG_DATA1));
+	seq_printf(m, "CREG_DATA2	0x%08x\n",
+					ioread32(card->regmap + CREG_DATA2));
+	seq_printf(m, "CREG_DATA3	0x%08x\n",
+					ioread32(card->regmap + CREG_DATA3));
+	seq_printf(m, "CREG_DATA4	0x%08x\n",
+					ioread32(card->regmap + CREG_DATA4));
+	seq_printf(m, "CREG_DATA5	0x%08x\n",
+					ioread32(card->regmap + CREG_DATA5));
+	seq_printf(m, "CREG_DATA6	0x%08x\n",
+					ioread32(card->regmap + CREG_DATA6));
+	seq_printf(m, "CREG_DATA7	0x%08x\n",
+					ioread32(card->regmap + CREG_DATA7));
+	seq_printf(m, "INTR_COAL	0x%08x\n",
+					ioread32(card->regmap + INTR_COAL));
+	seq_printf(m, "HW_ERROR		0x%08x\n",
+					ioread32(card->regmap + HW_ERROR));
+	seq_printf(m, "DEBUG0		0x%08x\n",
+					ioread32(card->regmap + PCI_DEBUG0));
+	seq_printf(m, "DEBUG1		0x%08x\n",
+					ioread32(card->regmap + PCI_DEBUG1));
+	seq_printf(m, "DEBUG2		0x%08x\n",
+					ioread32(card->regmap + PCI_DEBUG2));
+	seq_printf(m, "DEBUG3		0x%08x\n",
+					ioread32(card->regmap + PCI_DEBUG3));
+	seq_printf(m, "DEBUG4		0x%08x\n",
+					ioread32(card->regmap + PCI_DEBUG4));
+	seq_printf(m, "DEBUG5		0x%08x\n",
+					ioread32(card->regmap + PCI_DEBUG5));
+	seq_printf(m, "DEBUG6		0x%08x\n",
+					ioread32(card->regmap + PCI_DEBUG6));
+	seq_printf(m, "DEBUG7		0x%08x\n",
+					ioread32(card->regmap + PCI_DEBUG7));
+	seq_printf(m, "RECONFIG		0x%08x\n",
+					ioread32(card->regmap + PCI_RECONFIG));
+
+	return 0;
+}
+
+static int rsxx_attr_stats_show(struct seq_file *m, void *p)
+{
+	struct rsxx_cardinfo *card = m->private;
+	int i;
+
+	for (i = 0; i < card->n_targets; i++) {
+		seq_printf(m, "Ctrl %d CRC Errors	= %d\n",
+				i, card->ctrl[i].stats.crc_errors);
+		seq_printf(m, "Ctrl %d Hard Errors	= %d\n",
+				i, card->ctrl[i].stats.hard_errors);
+		seq_printf(m, "Ctrl %d Soft Errors	= %d\n",
+				i, card->ctrl[i].stats.soft_errors);
+		seq_printf(m, "Ctrl %d Writes Issued	= %d\n",
+				i, card->ctrl[i].stats.writes_issued);
+		seq_printf(m, "Ctrl %d Writes Failed	= %d\n",
+				i, card->ctrl[i].stats.writes_failed);
+		seq_printf(m, "Ctrl %d Reads Issued	= %d\n",
+				i, card->ctrl[i].stats.reads_issued);
+		seq_printf(m, "Ctrl %d Reads Failed	= %d\n",
+				i, card->ctrl[i].stats.reads_failed);
+		seq_printf(m, "Ctrl %d Reads Retried	= %d\n",
+				i, card->ctrl[i].stats.reads_retried);
+		seq_printf(m, "Ctrl %d Discards Issued	= %d\n",
+				i, card->ctrl[i].stats.discards_issued);
+		seq_printf(m, "Ctrl %d Discards Failed	= %d\n",
+				i, card->ctrl[i].stats.discards_failed);
+		seq_printf(m, "Ctrl %d DMA SW Errors	= %d\n",
+				i, card->ctrl[i].stats.dma_sw_err);
+		seq_printf(m, "Ctrl %d DMA HW Faults	= %d\n",
+				i, card->ctrl[i].stats.dma_hw_fault);
+		seq_printf(m, "Ctrl %d DMAs Cancelled	= %d\n",
+				i, card->ctrl[i].stats.dma_cancelled);
+		seq_printf(m, "Ctrl %d SW Queue Depth	= %d\n",
+				i, card->ctrl[i].stats.sw_q_depth);
+		seq_printf(m, "Ctrl %d HW Queue Depth	= %d\n",
+			i, atomic_read(&card->ctrl[i].stats.hw_q_depth));
+	}
+
+	return 0;
+}
+
+static int rsxx_attr_stats_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, rsxx_attr_stats_show, inode->i_private);
+}
+
+static int rsxx_attr_pci_regs_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, rsxx_attr_pci_regs_show, inode->i_private);
+}
+
+static ssize_t rsxx_cram_read(struct file *fp, char __user *ubuf,
+			      size_t cnt, loff_t *ppos)
+{
+	struct rsxx_cram *info = fp->private_data;
+	struct rsxx_cardinfo *card = info->i_private;
+	char *buf;
+	int st;
+
+	buf = kzalloc(sizeof(*buf) * cnt, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	info->f_pos = (u32)*ppos + info->offset;
+
+	st = rsxx_creg_read(card, CREG_ADD_CRAM + info->f_pos, cnt, buf, 1);
+	if (st)
+		return st;
+
+	st = copy_to_user(ubuf, buf, cnt);
+	if (st)
+		return st;
+
+	info->offset += cnt;
+
+	kfree(buf);
+
+	return cnt;
+}
+
+static ssize_t rsxx_cram_write(struct file *fp, const char __user *ubuf,
+			       size_t cnt, loff_t *ppos)
+{
+	struct rsxx_cram *info = fp->private_data;
+	struct rsxx_cardinfo *card = info->i_private;
+	char *buf;
+	int st;
+
+	buf = kzalloc(sizeof(*buf) * cnt, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	st = copy_from_user(buf, ubuf, cnt);
+	if (st)
+		return st;
+
+	info->f_pos = (u32)*ppos + info->offset;
+
+	st = rsxx_creg_write(card, CREG_ADD_CRAM + info->f_pos, cnt, buf, 1);
+	if (st)
+		return st;
+
+	info->offset += cnt;
+
+	kfree(buf);
+
+	return cnt;
+}
+
+static int rsxx_cram_open(struct inode *inode, struct file *file)
+{
+	struct rsxx_cram *info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->i_private = inode->i_private;
+	info->f_pos = file->f_pos;
+	file->private_data = info;
+
+	return 0;
+}
+
+static int rsxx_cram_release(struct inode *inode, struct file *file)
+{
+	struct rsxx_cram *info = file->private_data;
+
+	if (!info)
+		return 0;
+
+	kfree(info);
+	file->private_data = NULL;
+
+	return 0;
+}
+
+static const struct file_operations debugfs_cram_fops = {
+	.owner		= THIS_MODULE,
+	.open		= rsxx_cram_open,
+	.read		= rsxx_cram_read,
+	.write		= rsxx_cram_write,
+	.release	= rsxx_cram_release,
+};
+
+static const struct file_operations debugfs_stats_fops = {
+	.owner		= THIS_MODULE,
+	.open		= rsxx_attr_stats_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations debugfs_pci_regs_fops = {
+	.owner		= THIS_MODULE,
+	.open		= rsxx_attr_pci_regs_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static void rsxx_debugfs_dev_new(struct rsxx_cardinfo *card)
+{
+	struct dentry *debugfs_stats;
+	struct dentry *debugfs_pci_regs;
+	struct dentry *debugfs_cram;
+
+	card->debugfs_dir = debugfs_create_dir(card->gendisk->disk_name, NULL);
+	if (IS_ERR_OR_NULL(card->debugfs_dir))
+		goto failed_debugfs_dir;
+
+	debugfs_stats = debugfs_create_file("stats", S_IRUGO,
+					    card->debugfs_dir, card,
+					    &debugfs_stats_fops);
+	if (IS_ERR_OR_NULL(debugfs_stats))
+		goto failed_debugfs_stats;
+
+	debugfs_pci_regs = debugfs_create_file("pci_regs", S_IRUGO,
+					       card->debugfs_dir, card,
+					       &debugfs_pci_regs_fops);
+	if (IS_ERR_OR_NULL(debugfs_pci_regs))
+		goto failed_debugfs_pci_regs;
+
+	debugfs_cram = debugfs_create_file("cram", S_IRUGO | S_IWUSR,
+					   card->debugfs_dir, card,
+					   &debugfs_cram_fops);
+	if (IS_ERR_OR_NULL(debugfs_cram))
+		goto failed_debugfs_cram;
+
+	return;
+failed_debugfs_cram:
+	debugfs_remove(debugfs_pci_regs);
+failed_debugfs_pci_regs:
+	debugfs_remove(debugfs_stats);
+failed_debugfs_stats:
+	debugfs_remove(card->debugfs_dir);
+failed_debugfs_dir:
+	card->debugfs_dir = NULL;
+}
+
 /*----------------- Interrupt Control & Handling -------------------*/
 
 static void rsxx_mask_interrupts(struct rsxx_cardinfo *card)
@@ -163,12 +439,13 @@ static irqreturn_t rsxx_isr(int irq, voi
 		}
 
 		if (isr & CR_INTR_CREG) {
-			schedule_work(&card->creg_ctrl.done_work);
+			queue_work(card->creg_ctrl.creg_wq,
+				   &card->creg_ctrl.done_work);
 			handled++;
 		}
 
 		if (isr & CR_INTR_EVENT) {
-			schedule_work(&card->event_work);
+			queue_work(card->event_wq, &card->event_work);
 			rsxx_disable_ier_and_isr(card, CR_INTR_EVENT);
 			handled++;
 		}
@@ -329,7 +606,7 @@ static int rsxx_eeh_frozen(struct pci_de
 	int i;
 	int st;
 
-	dev_warn(&dev->dev, "IBM FlashSystem PCI: preparing for slot reset.\n");
+	dev_warn(&dev->dev, "IBM Flash Adapter PCI: preparing for slot reset.\n");
 
 	card->eeh_state = 1;
 	rsxx_mask_interrupts(card);
@@ -367,15 +644,26 @@ static void rsxx_eeh_failure(struct pci_
 {
 	struct rsxx_cardinfo *card = pci_get_drvdata(dev);
 	int i;
+	int cnt = 0;
 
-	dev_err(&dev->dev, "IBM FlashSystem PCI: disabling failed card.\n");
+	dev_err(&dev->dev, "IBM Flash Adapter PCI: disabling failed card.\n");
 
 	card->eeh_state = 1;
+	card->halt = 1;
 
-	for (i = 0; i < card->n_targets; i++)
-		del_timer_sync(&card->ctrl[i].activity_timer);
+	for (i = 0; i < card->n_targets; i++) {
+		spin_lock_bh(&card->ctrl[i].queue_lock);
+		cnt = rsxx_cleanup_dma_queue(&card->ctrl[i],
+					     &card->ctrl[i].queue);
+		spin_unlock_bh(&card->ctrl[i].queue_lock);
 
-	rsxx_eeh_cancel_dmas(card);
+		cnt += rsxx_dma_cancel(&card->ctrl[i]);
+
+		if (cnt)
+			dev_info(CARD_TO_DEV(card),
+				"Freed %d queued DMAs on channel %d\n",
+				cnt, card->ctrl[i].id);
+	}
 }
 
 static int rsxx_eeh_fifo_flush_poll(struct rsxx_cardinfo *card)
@@ -432,7 +720,7 @@ static pci_ers_result_t rsxx_slot_reset(
 	int st;
 
 	dev_warn(&dev->dev,
-		"IBM FlashSystem PCI: recovering from slot reset.\n");
+		"IBM Flash Adapter PCI: recovering from slot reset.\n");
 
 	st = pci_enable_device(dev);
 	if (st)
@@ -485,7 +773,7 @@ static pci_ers_result_t rsxx_slot_reset(
 				&card->ctrl[i].issue_dma_work);
 	}
 
-	dev_info(&dev->dev, "IBM FlashSystem PCI: recovery complete.\n");
+	dev_info(&dev->dev, "IBM Flash Adapter PCI: recovery complete.\n");
 
 	return PCI_ERS_RESULT_RECOVERED;
 
@@ -528,6 +816,7 @@ static int rsxx_pci_probe(struct pci_dev
 {
 	struct rsxx_cardinfo *card;
 	int st;
+	unsigned int sync_timeout;
 
 	dev_info(&dev->dev, "PCI-Flash SSD discovered\n");
 
@@ -610,7 +899,11 @@ static int rsxx_pci_probe(struct pci_dev
 	}
 
 	/************* Setup Processor Command Interface *************/
-	rsxx_creg_setup(card);
+	st = rsxx_creg_setup(card);
+	if (st) {
+		dev_err(CARD_TO_DEV(card), "Failed to setup creg interface.\n");
+		goto failed_creg_setup;
+	}
 
 	spin_lock_irq(&card->irq_lock);
 	rsxx_enable_ier_and_isr(card, CR_INTR_CREG);
@@ -650,6 +943,12 @@ static int rsxx_pci_probe(struct pci_dev
 	}
 
 	/************* Setup Card Event Handler *************/
+	card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event");
+	if (!card->event_wq) {
+		dev_err(CARD_TO_DEV(card), "Failed card event setup.\n");
+		goto failed_event_handler;
+	}
+
 	INIT_WORK(&card->event_work, card_event_handler);
 
 	st = rsxx_setup_dev(card);
@@ -676,6 +975,33 @@ static int rsxx_pci_probe(struct pci_dev
 		if (st)
 			dev_crit(CARD_TO_DEV(card),
 				"Failed issuing card startup\n");
+		if (sync_start) {
+			sync_timeout = SYNC_START_TIMEOUT;
+
+			dev_info(CARD_TO_DEV(card),
+				 "Waiting for card to startup\n");
+
+			do {
+				ssleep(1);
+				sync_timeout--;
+
+				rsxx_get_card_state(card, &card->state);
+			} while (sync_timeout &&
+				(card->state == CARD_STATE_STARTING));
+
+			if (card->state == CARD_STATE_STARTING) {
+				dev_warn(CARD_TO_DEV(card),
+					 "Card startup timed out\n");
+				card->size8 = 0;
+			} else {
+				dev_info(CARD_TO_DEV(card),
+					"card state: %s\n",
+					rsxx_card_state_to_str(card->state));
+				st = rsxx_get_card_size8(card, &card->size8);
+				if (st)
+					card->size8 = 0;
+			}
+		}
 	} else if (card->state == CARD_STATE_GOOD ||
 		   card->state == CARD_STATE_RD_ONLY_FAULT) {
 		st = rsxx_get_card_size8(card, &card->size8);
@@ -685,12 +1011,21 @@ static int rsxx_pci_probe(struct pci_dev
 
 	rsxx_attach_dev(card);
 
+	/************* Setup Debugfs *************/
+	rsxx_debugfs_dev_new(card);
+
 	return 0;
 
 failed_create_dev:
+	destroy_workqueue(card->event_wq);
+	card->event_wq = NULL;
+failed_event_handler:
 	rsxx_dma_destroy(card);
 failed_dma_setup:
 failed_compatiblity_check:
+	destroy_workqueue(card->creg_ctrl.creg_wq);
+	card->creg_ctrl.creg_wq = NULL;
+failed_creg_setup:
 	spin_lock_irq(&card->irq_lock);
 	rsxx_disable_ier_and_isr(card, CR_INTR_ALL);
 	spin_unlock_irq(&card->irq_lock);
@@ -756,6 +1091,8 @@ static void rsxx_pci_remove(struct pci_d
 	/* Prevent work_structs from re-queuing themselves. */
 	card->halt = 1;
 
+	debugfs_remove_recursive(card->debugfs_dir);
+
 	free_irq(dev->irq, card);
 
 	if (!force_legacy)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/rsxx/cregs.c linux-libre-3.11-rc7-gnu/drivers/block/rsxx/cregs.c
--- linux-libre-3.10-gnu/drivers/block/rsxx/cregs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/rsxx/cregs.c	2013-08-25 20:43:22.000000000 -0400
@@ -431,6 +431,15 @@ static int __issue_creg_rw(struct rsxx_c
 	*hw_stat = completion.creg_status;
 
 	if (completion.st) {
+		/*
+		* This read is needed to verify that there has not been any
+		* extreme errors that might have occurred, i.e. EEH. The
+		* function iowrite32 will not detect EEH errors, so it is
+		* necessary that we recover if such an error is the reason
+		* for the timeout. This is a dummy read.
+		*/
+		ioread32(card->regmap + SCRATCH);
+
 		dev_warn(CARD_TO_DEV(card),
 			"creg command failed(%d x%08x)\n",
 			completion.st, addr);
@@ -727,6 +736,11 @@ int rsxx_creg_setup(struct rsxx_cardinfo
 {
 	card->creg_ctrl.active_cmd = NULL;
 
+	card->creg_ctrl.creg_wq =
+			create_singlethread_workqueue(DRIVER_NAME"_creg");
+	if (!card->creg_ctrl.creg_wq)
+		return -ENOMEM;
+
 	INIT_WORK(&card->creg_ctrl.done_work, creg_cmd_done);
 	mutex_init(&card->creg_ctrl.reset_lock);
 	INIT_LIST_HEAD(&card->creg_ctrl.queue);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/rsxx/dev.c linux-libre-3.11-rc7-gnu/drivers/block/rsxx/dev.c
--- linux-libre-3.10-gnu/drivers/block/rsxx/dev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/rsxx/dev.c	2013-08-25 20:43:22.000000000 -0400
@@ -155,7 +155,8 @@ static void bio_dma_done_cb(struct rsxx_
 		atomic_set(&meta->error, 1);
 
 	if (atomic_dec_and_test(&meta->pending_dmas)) {
-		disk_stats_complete(card, meta->bio, meta->start_time);
+		if (!card->eeh_state && card->gendisk)
+			disk_stats_complete(card, meta->bio, meta->start_time);
 
 		bio_endio(meta->bio, atomic_read(&meta->error) ? -EIO : 0);
 		kmem_cache_free(bio_meta_pool, meta);
@@ -170,6 +171,12 @@ static void rsxx_make_request(struct req
 
 	might_sleep();
 
+	if (!card)
+		goto req_err;
+
+	if (bio->bi_sector + (bio->bi_size >> 9) > get_capacity(card->gendisk))
+		goto req_err;
+
 	if (unlikely(card->halt)) {
 		st = -EFAULT;
 		goto req_err;
@@ -196,7 +203,8 @@ static void rsxx_make_request(struct req
 	atomic_set(&bio_meta->pending_dmas, 0);
 	bio_meta->start_time = jiffies;
 
-	disk_stats_start(card, bio);
+	if (!unlikely(card->halt))
+		disk_stats_start(card, bio);
 
 	dev_dbg(CARD_TO_DEV(card), "BIO[%c]: meta: %p addr8: x%llx size: %d\n",
 		 bio_data_dir(bio) ? 'W' : 'R', bio_meta,
@@ -225,24 +233,6 @@ static bool rsxx_discard_supported(struc
 	return (pci_rev >= RSXX_DISCARD_SUPPORT);
 }
 
-static unsigned short rsxx_get_logical_block_size(
-					struct rsxx_cardinfo *card)
-{
-	u32 capabilities = 0;
-	int st;
-
-	st = rsxx_get_card_capabilities(card, &capabilities);
-	if (st)
-		dev_warn(CARD_TO_DEV(card),
-			"Failed reading card capabilities register\n");
-
-	/* Earlier firmware did not have support for 512 byte accesses */
-	if (capabilities & CARD_CAP_SUBPAGE_WRITES)
-		return 512;
-	else
-		return RSXX_HW_BLK_SIZE;
-}
-
 int rsxx_attach_dev(struct rsxx_cardinfo *card)
 {
 	mutex_lock(&card->dev_lock);
@@ -305,7 +295,7 @@ int rsxx_setup_dev(struct rsxx_cardinfo
 		return -ENOMEM;
 	}
 
-	blk_size = rsxx_get_logical_block_size(card);
+	blk_size = card->config.data.block_size;
 
 	blk_queue_make_request(card->queue, rsxx_make_request);
 	blk_queue_bounce_limit(card->queue, BLK_BOUNCE_ANY);
@@ -347,6 +337,7 @@ void rsxx_destroy_dev(struct rsxx_cardin
 	card->gendisk = NULL;
 
 	blk_cleanup_queue(card->queue);
+	card->queue->queuedata = NULL;
 	unregister_blkdev(card->major, DRIVER_NAME);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/rsxx/dma.c linux-libre-3.11-rc7-gnu/drivers/block/rsxx/dma.c
--- linux-libre-3.10-gnu/drivers/block/rsxx/dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/rsxx/dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -245,6 +245,22 @@ static void rsxx_complete_dma(struct rsx
 	kmem_cache_free(rsxx_dma_pool, dma);
 }
 
+int rsxx_cleanup_dma_queue(struct rsxx_dma_ctrl *ctrl,
+			   struct list_head *q)
+{
+	struct rsxx_dma *dma;
+	struct rsxx_dma *tmp;
+	int cnt = 0;
+
+	list_for_each_entry_safe(dma, tmp, q, list) {
+		list_del(&dma->list);
+		rsxx_complete_dma(ctrl, dma, DMA_CANCELLED);
+		cnt++;
+	}
+
+	return cnt;
+}
+
 static void rsxx_requeue_dma(struct rsxx_dma_ctrl *ctrl,
 				 struct rsxx_dma *dma)
 {
@@ -252,9 +268,10 @@ static void rsxx_requeue_dma(struct rsxx
 	 * Requeued DMAs go to the front of the queue so they are issued
 	 * first.
 	 */
-	spin_lock(&ctrl->queue_lock);
+	spin_lock_bh(&ctrl->queue_lock);
+	ctrl->stats.sw_q_depth++;
 	list_add(&dma->list, &ctrl->queue);
-	spin_unlock(&ctrl->queue_lock);
+	spin_unlock_bh(&ctrl->queue_lock);
 }
 
 static void rsxx_handle_dma_error(struct rsxx_dma_ctrl *ctrl,
@@ -329,6 +346,7 @@ static void rsxx_handle_dma_error(struct
 static void dma_engine_stalled(unsigned long data)
 {
 	struct rsxx_dma_ctrl *ctrl = (struct rsxx_dma_ctrl *)data;
+	int cnt;
 
 	if (atomic_read(&ctrl->stats.hw_q_depth) == 0 ||
 	    unlikely(ctrl->card->eeh_state))
@@ -349,18 +367,28 @@ static void dma_engine_stalled(unsigned
 			"DMA channel %d has stalled, faulting interface.\n",
 			ctrl->id);
 		ctrl->card->dma_fault = 1;
+
+		/* Clean up the DMA queue */
+		spin_lock(&ctrl->queue_lock);
+		cnt = rsxx_cleanup_dma_queue(ctrl, &ctrl->queue);
+		spin_unlock(&ctrl->queue_lock);
+
+		cnt += rsxx_dma_cancel(ctrl);
+
+		if (cnt)
+			dev_info(CARD_TO_DEV(ctrl->card),
+				"Freed %d queued DMAs on channel %d\n",
+				cnt, ctrl->id);
 	}
 }
 
-static void rsxx_issue_dmas(struct work_struct *work)
+static void rsxx_issue_dmas(struct rsxx_dma_ctrl *ctrl)
 {
-	struct rsxx_dma_ctrl *ctrl;
 	struct rsxx_dma *dma;
 	int tag;
 	int cmds_pending = 0;
 	struct hw_cmd *hw_cmd_buf;
 
-	ctrl = container_of(work, struct rsxx_dma_ctrl, issue_dma_work);
 	hw_cmd_buf = ctrl->cmd.buf;
 
 	if (unlikely(ctrl->card->halt) ||
@@ -368,22 +396,22 @@ static void rsxx_issue_dmas(struct work_
 		return;
 
 	while (1) {
-		spin_lock(&ctrl->queue_lock);
+		spin_lock_bh(&ctrl->queue_lock);
 		if (list_empty(&ctrl->queue)) {
-			spin_unlock(&ctrl->queue_lock);
+			spin_unlock_bh(&ctrl->queue_lock);
 			break;
 		}
-		spin_unlock(&ctrl->queue_lock);
+		spin_unlock_bh(&ctrl->queue_lock);
 
 		tag = pop_tracker(ctrl->trackers);
 		if (tag == -1)
 			break;
 
-		spin_lock(&ctrl->queue_lock);
+		spin_lock_bh(&ctrl->queue_lock);
 		dma = list_entry(ctrl->queue.next, struct rsxx_dma, list);
 		list_del(&dma->list);
 		ctrl->stats.sw_q_depth--;
-		spin_unlock(&ctrl->queue_lock);
+		spin_unlock_bh(&ctrl->queue_lock);
 
 		/*
 		 * This will catch any DMAs that slipped in right before the
@@ -440,9 +468,8 @@ static void rsxx_issue_dmas(struct work_
 	}
 }
 
-static void rsxx_dma_done(struct work_struct *work)
+static void rsxx_dma_done(struct rsxx_dma_ctrl *ctrl)
 {
-	struct rsxx_dma_ctrl *ctrl;
 	struct rsxx_dma *dma;
 	unsigned long flags;
 	u16 count;
@@ -450,7 +477,6 @@ static void rsxx_dma_done(struct work_st
 	u8 tag;
 	struct hw_status *hw_st_buf;
 
-	ctrl = container_of(work, struct rsxx_dma_ctrl, dma_done_work);
 	hw_st_buf = ctrl->status.buf;
 
 	if (unlikely(ctrl->card->halt) ||
@@ -520,33 +546,32 @@ static void rsxx_dma_done(struct work_st
 	rsxx_enable_ier(ctrl->card, CR_INTR_DMA(ctrl->id));
 	spin_unlock_irqrestore(&ctrl->card->irq_lock, flags);
 
-	spin_lock(&ctrl->queue_lock);
+	spin_lock_bh(&ctrl->queue_lock);
 	if (ctrl->stats.sw_q_depth)
 		queue_work(ctrl->issue_wq, &ctrl->issue_dma_work);
-	spin_unlock(&ctrl->queue_lock);
+	spin_unlock_bh(&ctrl->queue_lock);
 }
 
-static int rsxx_cleanup_dma_queue(struct rsxx_cardinfo *card,
-				      struct list_head *q)
+static void rsxx_schedule_issue(struct work_struct *work)
 {
-	struct rsxx_dma *dma;
-	struct rsxx_dma *tmp;
-	int cnt = 0;
+	struct rsxx_dma_ctrl *ctrl;
 
-	list_for_each_entry_safe(dma, tmp, q, list) {
-		list_del(&dma->list);
+	ctrl = container_of(work, struct rsxx_dma_ctrl, issue_dma_work);
 
-		if (dma->dma_addr)
-			pci_unmap_page(card->dev, dma->dma_addr,
-				       get_dma_size(dma),
-				       (dma->cmd == HW_CMD_BLK_WRITE) ?
-				       PCI_DMA_TODEVICE :
-				       PCI_DMA_FROMDEVICE);
-		kmem_cache_free(rsxx_dma_pool, dma);
-		cnt++;
-	}
+	mutex_lock(&ctrl->work_lock);
+	rsxx_issue_dmas(ctrl);
+	mutex_unlock(&ctrl->work_lock);
+}
 
-	return cnt;
+static void rsxx_schedule_done(struct work_struct *work)
+{
+	struct rsxx_dma_ctrl *ctrl;
+
+	ctrl = container_of(work, struct rsxx_dma_ctrl, dma_done_work);
+
+	mutex_lock(&ctrl->work_lock);
+	rsxx_dma_done(ctrl);
+	mutex_unlock(&ctrl->work_lock);
 }
 
 static int rsxx_queue_discard(struct rsxx_cardinfo *card,
@@ -698,10 +723,10 @@ int rsxx_dma_queue_bio(struct rsxx_cardi
 
 	for (i = 0; i < card->n_targets; i++) {
 		if (!list_empty(&dma_list[i])) {
-			spin_lock(&card->ctrl[i].queue_lock);
+			spin_lock_bh(&card->ctrl[i].queue_lock);
 			card->ctrl[i].stats.sw_q_depth += dma_cnt[i];
 			list_splice_tail(&dma_list[i], &card->ctrl[i].queue);
-			spin_unlock(&card->ctrl[i].queue_lock);
+			spin_unlock_bh(&card->ctrl[i].queue_lock);
 
 			queue_work(card->ctrl[i].issue_wq,
 				   &card->ctrl[i].issue_dma_work);
@@ -711,8 +736,11 @@ int rsxx_dma_queue_bio(struct rsxx_cardi
 	return 0;
 
 bvec_err:
-	for (i = 0; i < card->n_targets; i++)
-		rsxx_cleanup_dma_queue(card, &dma_list[i]);
+	for (i = 0; i < card->n_targets; i++) {
+		spin_lock_bh(&card->ctrl[i].queue_lock);
+		rsxx_cleanup_dma_queue(&card->ctrl[i], &dma_list[i]);
+		spin_unlock_bh(&card->ctrl[i].queue_lock);
+	}
 
 	return st;
 }
@@ -780,6 +808,7 @@ static int rsxx_dma_ctrl_init(struct pci
 	spin_lock_init(&ctrl->trackers->lock);
 
 	spin_lock_init(&ctrl->queue_lock);
+	mutex_init(&ctrl->work_lock);
 	INIT_LIST_HEAD(&ctrl->queue);
 
 	setup_timer(&ctrl->activity_timer, dma_engine_stalled,
@@ -793,8 +822,8 @@ static int rsxx_dma_ctrl_init(struct pci
 	if (!ctrl->done_wq)
 		return -ENOMEM;
 
-	INIT_WORK(&ctrl->issue_dma_work, rsxx_issue_dmas);
-	INIT_WORK(&ctrl->dma_done_work, rsxx_dma_done);
+	INIT_WORK(&ctrl->issue_dma_work, rsxx_schedule_issue);
+	INIT_WORK(&ctrl->dma_done_work, rsxx_schedule_done);
 
 	st = rsxx_hw_buffers_init(dev, ctrl);
 	if (st)
@@ -918,13 +947,30 @@ failed_dma_setup:
 	return st;
 }
 
+int rsxx_dma_cancel(struct rsxx_dma_ctrl *ctrl)
+{
+	struct rsxx_dma *dma;
+	int i;
+	int cnt = 0;
+
+	/* Clean up issued DMAs */
+	for (i = 0; i < RSXX_MAX_OUTSTANDING_CMDS; i++) {
+		dma = get_tracker_dma(ctrl->trackers, i);
+		if (dma) {
+			atomic_dec(&ctrl->stats.hw_q_depth);
+			rsxx_complete_dma(ctrl, dma, DMA_CANCELLED);
+			push_tracker(ctrl->trackers, i);
+			cnt++;
+		}
+	}
+
+	return cnt;
+}
 
 void rsxx_dma_destroy(struct rsxx_cardinfo *card)
 {
 	struct rsxx_dma_ctrl *ctrl;
-	struct rsxx_dma *dma;
-	int i, j;
-	int cnt = 0;
+	int i;
 
 	for (i = 0; i < card->n_targets; i++) {
 		ctrl = &card->ctrl[i];
@@ -943,33 +989,11 @@ void rsxx_dma_destroy(struct rsxx_cardin
 			del_timer_sync(&ctrl->activity_timer);
 
 		/* Clean up the DMA queue */
-		spin_lock(&ctrl->queue_lock);
-		cnt = rsxx_cleanup_dma_queue(card, &ctrl->queue);
-		spin_unlock(&ctrl->queue_lock);
-
-		if (cnt)
-			dev_info(CARD_TO_DEV(card),
-				"Freed %d queued DMAs on channel %d\n",
-				cnt, i);
-
-		/* Clean up issued DMAs */
-		for (j = 0; j < RSXX_MAX_OUTSTANDING_CMDS; j++) {
-			dma = get_tracker_dma(ctrl->trackers, j);
-			if (dma) {
-				pci_unmap_page(card->dev, dma->dma_addr,
-					       get_dma_size(dma),
-					       (dma->cmd == HW_CMD_BLK_WRITE) ?
-					       PCI_DMA_TODEVICE :
-					       PCI_DMA_FROMDEVICE);
-				kmem_cache_free(rsxx_dma_pool, dma);
-				cnt++;
-			}
-		}
+		spin_lock_bh(&ctrl->queue_lock);
+		rsxx_cleanup_dma_queue(ctrl, &ctrl->queue);
+		spin_unlock_bh(&ctrl->queue_lock);
 
-		if (cnt)
-			dev_info(CARD_TO_DEV(card),
-				"Freed %d pending DMAs on channel %d\n",
-				cnt, i);
+		rsxx_dma_cancel(ctrl);
 
 		vfree(ctrl->trackers);
 
@@ -1013,7 +1037,7 @@ int rsxx_eeh_save_issued_dmas(struct rsx
 			cnt++;
 		}
 
-		spin_lock(&card->ctrl[i].queue_lock);
+		spin_lock_bh(&card->ctrl[i].queue_lock);
 		list_splice(&issued_dmas[i], &card->ctrl[i].queue);
 
 		atomic_sub(cnt, &card->ctrl[i].stats.hw_q_depth);
@@ -1028,7 +1052,7 @@ int rsxx_eeh_save_issued_dmas(struct rsx
 					       PCI_DMA_TODEVICE :
 					       PCI_DMA_FROMDEVICE);
 		}
-		spin_unlock(&card->ctrl[i].queue_lock);
+		spin_unlock_bh(&card->ctrl[i].queue_lock);
 	}
 
 	kfree(issued_dmas);
@@ -1036,30 +1060,13 @@ int rsxx_eeh_save_issued_dmas(struct rsx
 	return 0;
 }
 
-void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card)
-{
-	struct rsxx_dma *dma;
-	struct rsxx_dma *tmp;
-	int i;
-
-	for (i = 0; i < card->n_targets; i++) {
-		spin_lock(&card->ctrl[i].queue_lock);
-		list_for_each_entry_safe(dma, tmp, &card->ctrl[i].queue, list) {
-			list_del(&dma->list);
-
-			rsxx_complete_dma(&card->ctrl[i], dma, DMA_CANCELLED);
-		}
-		spin_unlock(&card->ctrl[i].queue_lock);
-	}
-}
-
 int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card)
 {
 	struct rsxx_dma *dma;
 	int i;
 
 	for (i = 0; i < card->n_targets; i++) {
-		spin_lock(&card->ctrl[i].queue_lock);
+		spin_lock_bh(&card->ctrl[i].queue_lock);
 		list_for_each_entry(dma, &card->ctrl[i].queue, list) {
 			dma->dma_addr = pci_map_page(card->dev, dma->page,
 					dma->pg_off, get_dma_size(dma),
@@ -1067,12 +1074,12 @@ int rsxx_eeh_remap_dmas(struct rsxx_card
 					PCI_DMA_TODEVICE :
 					PCI_DMA_FROMDEVICE);
 			if (!dma->dma_addr) {
-				spin_unlock(&card->ctrl[i].queue_lock);
+				spin_unlock_bh(&card->ctrl[i].queue_lock);
 				kmem_cache_free(rsxx_dma_pool, dma);
 				return -ENOMEM;
 			}
 		}
-		spin_unlock(&card->ctrl[i].queue_lock);
+		spin_unlock_bh(&card->ctrl[i].queue_lock);
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/rsxx/rsxx_priv.h linux-libre-3.11-rc7-gnu/drivers/block/rsxx/rsxx_priv.h
--- linux-libre-3.10-gnu/drivers/block/rsxx/rsxx_priv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/rsxx/rsxx_priv.h	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/vmalloc.h>
 #include <linux/timer.h>
 #include <linux/ioctl.h>
+#include <linux/delay.h>
 
 #include "rsxx.h"
 #include "rsxx_cfg.h"
@@ -114,6 +115,7 @@ struct rsxx_dma_ctrl {
 	struct timer_list		activity_timer;
 	struct dma_tracker_list		*trackers;
 	struct rsxx_dma_stats		stats;
+	struct mutex			work_lock;
 };
 
 struct rsxx_cardinfo {
@@ -134,6 +136,7 @@ struct rsxx_cardinfo {
 		spinlock_t		lock;
 		bool			active;
 		struct creg_cmd		*active_cmd;
+		struct workqueue_struct	*creg_wq;
 		struct work_struct	done_work;
 		struct list_head	queue;
 		unsigned int		q_depth;
@@ -154,6 +157,7 @@ struct rsxx_cardinfo {
 		int buf_len;
 	} log;
 
+	struct workqueue_struct	*event_wq;
 	struct work_struct	event_work;
 	unsigned int		state;
 	u64			size8;
@@ -181,6 +185,8 @@ struct rsxx_cardinfo {
 
 	int			n_targets;
 	struct rsxx_dma_ctrl	*ctrl;
+
+	struct dentry		*debugfs_dir;
 };
 
 enum rsxx_pci_regmap {
@@ -283,6 +289,7 @@ enum rsxx_creg_addr {
 	CREG_ADD_CAPABILITIES		= 0x80001050,
 	CREG_ADD_LOG			= 0x80002000,
 	CREG_ADD_NUM_TARGETS		= 0x80003000,
+	CREG_ADD_CRAM			= 0xA0000000,
 	CREG_ADD_CONFIG			= 0xB0000000,
 };
 
@@ -372,6 +379,8 @@ typedef void (*rsxx_dma_cb)(struct rsxx_
 int rsxx_dma_setup(struct rsxx_cardinfo *card);
 void rsxx_dma_destroy(struct rsxx_cardinfo *card);
 int rsxx_dma_init(void);
+int rsxx_cleanup_dma_queue(struct rsxx_dma_ctrl *ctrl, struct list_head *q);
+int rsxx_dma_cancel(struct rsxx_dma_ctrl *ctrl);
 void rsxx_dma_cleanup(void);
 void rsxx_dma_queue_reset(struct rsxx_cardinfo *card);
 int rsxx_dma_configure(struct rsxx_cardinfo *card);
@@ -382,7 +391,6 @@ int rsxx_dma_queue_bio(struct rsxx_cardi
 			   void *cb_data);
 int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl);
 int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card);
-void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card);
 int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card);
 
 /***** cregs.c *****/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/swim.c linux-libre-3.11-rc7-gnu/drivers/block/swim.c
--- linux-libre-3.10-gnu/drivers/block/swim.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/swim.c	2013-08-25 20:43:22.000000000 -0400
@@ -893,7 +893,7 @@ static int swim_probe(struct platform_de
 
 	swim_base = ioremap(res->start, resource_size(res));
 	if (!swim_base) {
-		return -ENOMEM;
+		ret = -ENOMEM;
 		goto out_release_io;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/virtio_blk.c linux-libre-3.11-rc7-gnu/drivers/block/virtio_blk.c
--- linux-libre-3.10-gnu/drivers/block/virtio_blk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/virtio_blk.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,7 +20,7 @@ module_param(use_bio, bool, S_IRUGO);
 static int major;
 static DEFINE_IDA(vd_index_ida);
 
-struct workqueue_struct *virtblk_wq;
+static struct workqueue_struct *virtblk_wq;
 
 struct virtio_blk
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/xen-blkback/blkback.c linux-libre-3.11-rc7-gnu/drivers/block/xen-blkback/blkback.c
--- linux-libre-3.10-gnu/drivers/block/xen-blkback/blkback.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/xen-blkback/blkback.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,110 +50,118 @@
 #include "common.h"
 
 /*
- * These are rather arbitrary. They are fairly large because adjacent requests
- * pulled from a communication ring are quite likely to end up being part of
- * the same scatter/gather request at the disc.
- *
- * ** TRY INCREASING 'xen_blkif_reqs' IF WRITE SPEEDS SEEM TOO LOW **
+ * Maximum number of unused free pages to keep in the internal buffer.
+ * Setting this to a value too low will reduce memory used in each backend,
+ * but can have a performance penalty.
  *
- * This will increase the chances of being able to write whole tracks.
- * 64 should be enough to keep us competitive with Linux.
+ * A sane value is xen_blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST, but can
+ * be set to a lower value that might degrade performance on some intensive
+ * IO workloads.
  */
-static int xen_blkif_reqs = 64;
-module_param_named(reqs, xen_blkif_reqs, int, 0);
-MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate");
 
-/* Run-time switchable: /sys/module/blkback/parameters/ */
-static unsigned int log_stats;
-module_param(log_stats, int, 0644);
+static int xen_blkif_max_buffer_pages = 1024;
+module_param_named(max_buffer_pages, xen_blkif_max_buffer_pages, int, 0644);
+MODULE_PARM_DESC(max_buffer_pages,
+"Maximum number of free pages to keep in each block backend buffer");
 
 /*
- * Each outstanding request that we've passed to the lower device layers has a
- * 'pending_req' allocated to it. Each buffer_head that completes decrements
- * the pendcnt towards zero. When it hits zero, the specified domain has a
- * response queued for it, with the saved 'id' passed back.
+ * Maximum number of grants to map persistently in blkback. For maximum
+ * performance this should be the total numbers of grants that can be used
+ * to fill the ring, but since this might become too high, specially with
+ * the use of indirect descriptors, we set it to a value that provides good
+ * performance without using too much memory.
+ *
+ * When the list of persistent grants is full we clean it up using a LRU
+ * algorithm.
  */
-struct pending_req {
-	struct xen_blkif	*blkif;
-	u64			id;
-	int			nr_pages;
-	atomic_t		pendcnt;
-	unsigned short		operation;
-	int			status;
-	struct list_head	free_list;
-	DECLARE_BITMAP(unmap_seg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
-};
 
-#define BLKBACK_INVALID_HANDLE (~0)
-
-struct xen_blkbk {
-	struct pending_req	*pending_reqs;
-	/* List of all 'pending_req' available */
-	struct list_head	pending_free;
-	/* And its spinlock. */
-	spinlock_t		pending_free_lock;
-	wait_queue_head_t	pending_free_wq;
-	/* The list of all pages that are available. */
-	struct page		**pending_pages;
-	/* And the grant handles that are available. */
-	grant_handle_t		*pending_grant_handles;
-};
+static int xen_blkif_max_pgrants = 1056;
+module_param_named(max_persistent_grants, xen_blkif_max_pgrants, int, 0644);
+MODULE_PARM_DESC(max_persistent_grants,
+                 "Maximum number of grants to map persistently");
 
-static struct xen_blkbk *blkbk;
+/*
+ * The LRU mechanism to clean the lists of persistent grants needs to
+ * be executed periodically. The time interval between consecutive executions
+ * of the purge mechanism is set in ms.
+ */
+#define LRU_INTERVAL 100
 
 /*
- * Maximum number of grant pages that can be mapped in blkback.
- * BLKIF_MAX_SEGMENTS_PER_REQUEST * RING_SIZE is the maximum number of
- * pages that blkback will persistently map.
- * Currently, this is:
- * RING_SIZE = 32 (for all known ring types)
- * BLKIF_MAX_SEGMENTS_PER_REQUEST = 11
- * sizeof(struct persistent_gnt) = 48
- * So the maximum memory used to store the grants is:
- * 32 * 11 * 48 = 16896 bytes
+ * When the persistent grants list is full we will remove unused grants
+ * from the list. The percent number of grants to be removed at each LRU
+ * execution.
  */
-static inline unsigned int max_mapped_grant_pages(enum blkif_protocol protocol)
+#define LRU_PERCENT_CLEAN 5
+
+/* Run-time switchable: /sys/module/blkback/parameters/ */
+static unsigned int log_stats;
+module_param(log_stats, int, 0644);
+
+#define BLKBACK_INVALID_HANDLE (~0)
+
+/* Number of free pages to remove on each call to free_xenballooned_pages */
+#define NUM_BATCH_FREE_PAGES 10
+
+static inline int get_free_page(struct xen_blkif *blkif, struct page **page)
 {
-	switch (protocol) {
-	case BLKIF_PROTOCOL_NATIVE:
-		return __CONST_RING_SIZE(blkif, PAGE_SIZE) *
-			   BLKIF_MAX_SEGMENTS_PER_REQUEST;
-	case BLKIF_PROTOCOL_X86_32:
-		return __CONST_RING_SIZE(blkif_x86_32, PAGE_SIZE) *
-			   BLKIF_MAX_SEGMENTS_PER_REQUEST;
-	case BLKIF_PROTOCOL_X86_64:
-		return __CONST_RING_SIZE(blkif_x86_64, PAGE_SIZE) *
-			   BLKIF_MAX_SEGMENTS_PER_REQUEST;
-	default:
-		BUG();
+	unsigned long flags;
+
+	spin_lock_irqsave(&blkif->free_pages_lock, flags);
+	if (list_empty(&blkif->free_pages)) {
+		BUG_ON(blkif->free_pages_num != 0);
+		spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+		return alloc_xenballooned_pages(1, page, false);
 	}
+	BUG_ON(blkif->free_pages_num == 0);
+	page[0] = list_first_entry(&blkif->free_pages, struct page, lru);
+	list_del(&page[0]->lru);
+	blkif->free_pages_num--;
+	spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+
 	return 0;
 }
 
-
-/*
- * Little helpful macro to figure out the index and virtual address of the
- * pending_pages[..]. For each 'pending_req' we have have up to
- * BLKIF_MAX_SEGMENTS_PER_REQUEST (11) pages. The seg would be from 0 through
- * 10 and would index in the pending_pages[..].
- */
-static inline int vaddr_pagenr(struct pending_req *req, int seg)
+static inline void put_free_pages(struct xen_blkif *blkif, struct page **page,
+                                  int num)
 {
-	return (req - blkbk->pending_reqs) *
-		BLKIF_MAX_SEGMENTS_PER_REQUEST + seg;
-}
+	unsigned long flags;
+	int i;
 
-#define pending_page(req, seg) pending_pages[vaddr_pagenr(req, seg)]
+	spin_lock_irqsave(&blkif->free_pages_lock, flags);
+	for (i = 0; i < num; i++)
+		list_add(&page[i]->lru, &blkif->free_pages);
+	blkif->free_pages_num += num;
+	spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+}
 
-static inline unsigned long vaddr(struct pending_req *req, int seg)
+static inline void shrink_free_pagepool(struct xen_blkif *blkif, int num)
 {
-	unsigned long pfn = page_to_pfn(blkbk->pending_page(req, seg));
-	return (unsigned long)pfn_to_kaddr(pfn);
-}
+	/* Remove requested pages in batches of NUM_BATCH_FREE_PAGES */
+	struct page *page[NUM_BATCH_FREE_PAGES];
+	unsigned int num_pages = 0;
+	unsigned long flags;
 
-#define pending_handle(_req, _seg) \
-	(blkbk->pending_grant_handles[vaddr_pagenr(_req, _seg)])
+	spin_lock_irqsave(&blkif->free_pages_lock, flags);
+	while (blkif->free_pages_num > num) {
+		BUG_ON(list_empty(&blkif->free_pages));
+		page[num_pages] = list_first_entry(&blkif->free_pages,
+		                                   struct page, lru);
+		list_del(&page[num_pages]->lru);
+		blkif->free_pages_num--;
+		if (++num_pages == NUM_BATCH_FREE_PAGES) {
+			spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+			free_xenballooned_pages(num_pages, page);
+			spin_lock_irqsave(&blkif->free_pages_lock, flags);
+			num_pages = 0;
+		}
+	}
+	spin_unlock_irqrestore(&blkif->free_pages_lock, flags);
+	if (num_pages != 0)
+		free_xenballooned_pages(num_pages, page);
+}
 
+#define vaddr(page) ((unsigned long)pfn_to_kaddr(page_to_pfn(page)))
 
 static int do_block_io_op(struct xen_blkif *blkif);
 static int dispatch_rw_block_io(struct xen_blkif *blkif,
@@ -170,13 +178,29 @@ static void make_response(struct xen_blk
 	     (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL)
 
 
-static void add_persistent_gnt(struct rb_root *root,
+/*
+ * We don't need locking around the persistent grant helpers
+ * because blkback uses a single-thread for each backed, so we
+ * can be sure that this functions will never be called recursively.
+ *
+ * The only exception to that is put_persistent_grant, that can be called
+ * from interrupt context (by xen_blkbk_unmap), so we have to use atomic
+ * bit operations to modify the flags of a persistent grant and to count
+ * the number of used grants.
+ */
+static int add_persistent_gnt(struct xen_blkif *blkif,
 			       struct persistent_gnt *persistent_gnt)
 {
-	struct rb_node **new = &(root->rb_node), *parent = NULL;
+	struct rb_node **new = NULL, *parent = NULL;
 	struct persistent_gnt *this;
 
+	if (blkif->persistent_gnt_c >= xen_blkif_max_pgrants) {
+		if (!blkif->vbd.overflow_max_grants)
+			blkif->vbd.overflow_max_grants = 1;
+		return -EBUSY;
+	}
 	/* Figure out where to put new node */
+	new = &blkif->persistent_gnts.rb_node;
 	while (*new) {
 		this = container_of(*new, struct persistent_gnt, node);
 
@@ -186,22 +210,28 @@ static void add_persistent_gnt(struct rb
 		else if (persistent_gnt->gnt > this->gnt)
 			new = &((*new)->rb_right);
 		else {
-			pr_alert(DRV_PFX " trying to add a gref that's already in the tree\n");
-			BUG();
+			pr_alert_ratelimited(DRV_PFX " trying to add a gref that's already in the tree\n");
+			return -EINVAL;
 		}
 	}
 
+	bitmap_zero(persistent_gnt->flags, PERSISTENT_GNT_FLAGS_SIZE);
+	set_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
 	/* Add new node and rebalance tree. */
 	rb_link_node(&(persistent_gnt->node), parent, new);
-	rb_insert_color(&(persistent_gnt->node), root);
+	rb_insert_color(&(persistent_gnt->node), &blkif->persistent_gnts);
+	blkif->persistent_gnt_c++;
+	atomic_inc(&blkif->persistent_gnt_in_use);
+	return 0;
 }
 
-static struct persistent_gnt *get_persistent_gnt(struct rb_root *root,
+static struct persistent_gnt *get_persistent_gnt(struct xen_blkif *blkif,
 						 grant_ref_t gref)
 {
 	struct persistent_gnt *data;
-	struct rb_node *node = root->rb_node;
+	struct rb_node *node = NULL;
 
+	node = blkif->persistent_gnts.rb_node;
 	while (node) {
 		data = container_of(node, struct persistent_gnt, node);
 
@@ -209,13 +239,31 @@ static struct persistent_gnt *get_persis
 			node = node->rb_left;
 		else if (gref > data->gnt)
 			node = node->rb_right;
-		else
+		else {
+			if(test_bit(PERSISTENT_GNT_ACTIVE, data->flags)) {
+				pr_alert_ratelimited(DRV_PFX " requesting a grant already in use\n");
+				return NULL;
+			}
+			set_bit(PERSISTENT_GNT_ACTIVE, data->flags);
+			atomic_inc(&blkif->persistent_gnt_in_use);
 			return data;
+		}
 	}
 	return NULL;
 }
 
-static void free_persistent_gnts(struct rb_root *root, unsigned int num)
+static void put_persistent_gnt(struct xen_blkif *blkif,
+                               struct persistent_gnt *persistent_gnt)
+{
+	if(!test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
+	          pr_alert_ratelimited(DRV_PFX " freeing a grant already unused");
+	set_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
+	clear_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
+	atomic_dec(&blkif->persistent_gnt_in_use);
+}
+
+static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root,
+                                 unsigned int num)
 {
 	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 	struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
@@ -240,7 +288,7 @@ static void free_persistent_gnts(struct
 			ret = gnttab_unmap_refs(unmap, NULL, pages,
 				segs_to_unmap);
 			BUG_ON(ret);
-			free_xenballooned_pages(segs_to_unmap, pages);
+			put_free_pages(blkif, pages, segs_to_unmap);
 			segs_to_unmap = 0;
 		}
 
@@ -251,21 +299,148 @@ static void free_persistent_gnts(struct
 	BUG_ON(num != 0);
 }
 
+static void unmap_purged_grants(struct work_struct *work)
+{
+	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	struct persistent_gnt *persistent_gnt;
+	int ret, segs_to_unmap = 0;
+	struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work);
+
+	while(!list_empty(&blkif->persistent_purge_list)) {
+		persistent_gnt = list_first_entry(&blkif->persistent_purge_list,
+		                                  struct persistent_gnt,
+		                                  remove_node);
+		list_del(&persistent_gnt->remove_node);
+
+		gnttab_set_unmap_op(&unmap[segs_to_unmap],
+			vaddr(persistent_gnt->page),
+			GNTMAP_host_map,
+			persistent_gnt->handle);
+
+		pages[segs_to_unmap] = persistent_gnt->page;
+
+		if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+			ret = gnttab_unmap_refs(unmap, NULL, pages,
+				segs_to_unmap);
+			BUG_ON(ret);
+			put_free_pages(blkif, pages, segs_to_unmap);
+			segs_to_unmap = 0;
+		}
+		kfree(persistent_gnt);
+	}
+	if (segs_to_unmap > 0) {
+		ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap);
+		BUG_ON(ret);
+		put_free_pages(blkif, pages, segs_to_unmap);
+	}
+}
+
+static void purge_persistent_gnt(struct xen_blkif *blkif)
+{
+	struct persistent_gnt *persistent_gnt;
+	struct rb_node *n;
+	unsigned int num_clean, total;
+	bool scan_used = false, clean_used = false;
+	struct rb_root *root;
+
+	if (blkif->persistent_gnt_c < xen_blkif_max_pgrants ||
+	    (blkif->persistent_gnt_c == xen_blkif_max_pgrants &&
+	    !blkif->vbd.overflow_max_grants)) {
+		return;
+	}
+
+	if (work_pending(&blkif->persistent_purge_work)) {
+		pr_alert_ratelimited(DRV_PFX "Scheduled work from previous purge is still pending, cannot purge list\n");
+		return;
+	}
+
+	num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
+	num_clean = blkif->persistent_gnt_c - xen_blkif_max_pgrants + num_clean;
+	num_clean = min(blkif->persistent_gnt_c, num_clean);
+	if ((num_clean == 0) ||
+	    (num_clean > (blkif->persistent_gnt_c - atomic_read(&blkif->persistent_gnt_in_use))))
+		return;
+
+	/*
+	 * At this point, we can assure that there will be no calls
+         * to get_persistent_grant (because we are executing this code from
+         * xen_blkif_schedule), there can only be calls to put_persistent_gnt,
+         * which means that the number of currently used grants will go down,
+         * but never up, so we will always be able to remove the requested
+         * number of grants.
+	 */
+
+	total = num_clean;
+
+	pr_debug(DRV_PFX "Going to purge %u persistent grants\n", num_clean);
+
+	INIT_LIST_HEAD(&blkif->persistent_purge_list);
+	root = &blkif->persistent_gnts;
+purge_list:
+	foreach_grant_safe(persistent_gnt, n, root, node) {
+		BUG_ON(persistent_gnt->handle ==
+			BLKBACK_INVALID_HANDLE);
+
+		if (clean_used) {
+			clear_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
+			continue;
+		}
+
+		if (test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
+			continue;
+		if (!scan_used &&
+		    (test_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags)))
+			continue;
+
+		rb_erase(&persistent_gnt->node, root);
+		list_add(&persistent_gnt->remove_node,
+		         &blkif->persistent_purge_list);
+		if (--num_clean == 0)
+			goto finished;
+	}
+	/*
+	 * If we get here it means we also need to start cleaning
+	 * grants that were used since last purge in order to cope
+	 * with the requested num
+	 */
+	if (!scan_used && !clean_used) {
+		pr_debug(DRV_PFX "Still missing %u purged frames\n", num_clean);
+		scan_used = true;
+		goto purge_list;
+	}
+finished:
+	if (!clean_used) {
+		pr_debug(DRV_PFX "Finished scanning for grants to clean, removing used flag\n");
+		clean_used = true;
+		goto purge_list;
+	}
+
+	blkif->persistent_gnt_c -= (total - num_clean);
+	blkif->vbd.overflow_max_grants = 0;
+
+	/* We can defer this work */
+	INIT_WORK(&blkif->persistent_purge_work, unmap_purged_grants);
+	schedule_work(&blkif->persistent_purge_work);
+	pr_debug(DRV_PFX "Purged %u/%u\n", (total - num_clean), total);
+	return;
+}
+
 /*
  * Retrieve from the 'pending_reqs' a free pending_req structure to be used.
  */
-static struct pending_req *alloc_req(void)
+static struct pending_req *alloc_req(struct xen_blkif *blkif)
 {
 	struct pending_req *req = NULL;
 	unsigned long flags;
 
-	spin_lock_irqsave(&blkbk->pending_free_lock, flags);
-	if (!list_empty(&blkbk->pending_free)) {
-		req = list_entry(blkbk->pending_free.next, struct pending_req,
+	spin_lock_irqsave(&blkif->pending_free_lock, flags);
+	if (!list_empty(&blkif->pending_free)) {
+		req = list_entry(blkif->pending_free.next, struct pending_req,
 				 free_list);
 		list_del(&req->free_list);
 	}
-	spin_unlock_irqrestore(&blkbk->pending_free_lock, flags);
+	spin_unlock_irqrestore(&blkif->pending_free_lock, flags);
 	return req;
 }
 
@@ -273,17 +448,17 @@ static struct pending_req *alloc_req(voi
  * Return the 'pending_req' structure back to the freepool. We also
  * wake up the thread if it was waiting for a free page.
  */
-static void free_req(struct pending_req *req)
+static void free_req(struct xen_blkif *blkif, struct pending_req *req)
 {
 	unsigned long flags;
 	int was_empty;
 
-	spin_lock_irqsave(&blkbk->pending_free_lock, flags);
-	was_empty = list_empty(&blkbk->pending_free);
-	list_add(&req->free_list, &blkbk->pending_free);
-	spin_unlock_irqrestore(&blkbk->pending_free_lock, flags);
+	spin_lock_irqsave(&blkif->pending_free_lock, flags);
+	was_empty = list_empty(&blkif->pending_free);
+	list_add(&req->free_list, &blkif->pending_free);
+	spin_unlock_irqrestore(&blkif->pending_free_lock, flags);
 	if (was_empty)
-		wake_up(&blkbk->pending_free_wq);
+		wake_up(&blkif->pending_free_wq);
 }
 
 /*
@@ -382,10 +557,12 @@ irqreturn_t xen_blkif_be_int(int irq, vo
 static void print_stats(struct xen_blkif *blkif)
 {
 	pr_info("xen-blkback (%s): oo %3llu  |  rd %4llu  |  wr %4llu  |  f %4llu"
-		 "  |  ds %4llu\n",
+		 "  |  ds %4llu | pg: %4u/%4d\n",
 		 current->comm, blkif->st_oo_req,
 		 blkif->st_rd_req, blkif->st_wr_req,
-		 blkif->st_f_req, blkif->st_ds_req);
+		 blkif->st_f_req, blkif->st_ds_req,
+		 blkif->persistent_gnt_c,
+		 xen_blkif_max_pgrants);
 	blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
 	blkif->st_rd_req = 0;
 	blkif->st_wr_req = 0;
@@ -397,6 +574,8 @@ int xen_blkif_schedule(void *arg)
 {
 	struct xen_blkif *blkif = arg;
 	struct xen_vbd *vbd = &blkif->vbd;
+	unsigned long timeout;
+	int ret;
 
 	xen_blkif_get(blkif);
 
@@ -406,27 +585,52 @@ int xen_blkif_schedule(void *arg)
 		if (unlikely(vbd->size != vbd_sz(vbd)))
 			xen_vbd_resize(blkif);
 
-		wait_event_interruptible(
+		timeout = msecs_to_jiffies(LRU_INTERVAL);
+
+		timeout = wait_event_interruptible_timeout(
 			blkif->wq,
-			blkif->waiting_reqs || kthread_should_stop());
-		wait_event_interruptible(
-			blkbk->pending_free_wq,
-			!list_empty(&blkbk->pending_free) ||
-			kthread_should_stop());
+			blkif->waiting_reqs || kthread_should_stop(),
+			timeout);
+		if (timeout == 0)
+			goto purge_gnt_list;
+		timeout = wait_event_interruptible_timeout(
+			blkif->pending_free_wq,
+			!list_empty(&blkif->pending_free) ||
+			kthread_should_stop(),
+			timeout);
+		if (timeout == 0)
+			goto purge_gnt_list;
 
 		blkif->waiting_reqs = 0;
 		smp_mb(); /* clear flag *before* checking for work */
 
-		if (do_block_io_op(blkif))
+		ret = do_block_io_op(blkif);
+		if (ret > 0)
 			blkif->waiting_reqs = 1;
+		if (ret == -EACCES)
+			wait_event_interruptible(blkif->shutdown_wq,
+						 kthread_should_stop());
+
+purge_gnt_list:
+		if (blkif->vbd.feature_gnt_persistent &&
+		    time_after(jiffies, blkif->next_lru)) {
+			purge_persistent_gnt(blkif);
+			blkif->next_lru = jiffies + msecs_to_jiffies(LRU_INTERVAL);
+		}
+
+		/* Shrink if we have more than xen_blkif_max_buffer_pages */
+		shrink_free_pagepool(blkif, xen_blkif_max_buffer_pages);
 
 		if (log_stats && time_after(jiffies, blkif->st_print))
 			print_stats(blkif);
 	}
 
+	/* Since we are shutting down remove all pages from the buffer */
+	shrink_free_pagepool(blkif, 0 /* All */);
+
 	/* Free all persistent grant pages */
 	if (!RB_EMPTY_ROOT(&blkif->persistent_gnts))
-		free_persistent_gnts(&blkif->persistent_gnts,
+		free_persistent_gnts(blkif, &blkif->persistent_gnts,
 			blkif->persistent_gnt_c);
 
 	BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts));
@@ -441,148 +645,98 @@ int xen_blkif_schedule(void *arg)
 	return 0;
 }
 
-struct seg_buf {
-	unsigned int offset;
-	unsigned int nsec;
-};
 /*
  * Unmap the grant references, and also remove the M2P over-rides
  * used in the 'pending_req'.
  */
-static void xen_blkbk_unmap(struct pending_req *req)
+static void xen_blkbk_unmap(struct xen_blkif *blkif,
+                            struct grant_page *pages[],
+                            int num)
 {
 	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-	struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	struct page *unmap_pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 	unsigned int i, invcount = 0;
-	grant_handle_t handle;
 	int ret;
 
-	for (i = 0; i < req->nr_pages; i++) {
-		if (!test_bit(i, req->unmap_seg))
+	for (i = 0; i < num; i++) {
+		if (pages[i]->persistent_gnt != NULL) {
+			put_persistent_gnt(blkif, pages[i]->persistent_gnt);
 			continue;
-		handle = pending_handle(req, i);
-		if (handle == BLKBACK_INVALID_HANDLE)
+		}
+		if (pages[i]->handle == BLKBACK_INVALID_HANDLE)
 			continue;
-		gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),
-				    GNTMAP_host_map, handle);
-		pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
-		pages[invcount] = virt_to_page(vaddr(req, i));
-		invcount++;
+		unmap_pages[invcount] = pages[i]->page;
+		gnttab_set_unmap_op(&unmap[invcount], vaddr(pages[i]->page),
+				    GNTMAP_host_map, pages[i]->handle);
+		pages[i]->handle = BLKBACK_INVALID_HANDLE;
+		if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+			ret = gnttab_unmap_refs(unmap, NULL, unmap_pages,
+			                        invcount);
+			BUG_ON(ret);
+			put_free_pages(blkif, unmap_pages, invcount);
+			invcount = 0;
+		}
+	}
+	if (invcount) {
+		ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount);
+		BUG_ON(ret);
+		put_free_pages(blkif, unmap_pages, invcount);
 	}
-
-	ret = gnttab_unmap_refs(unmap, NULL, pages, invcount);
-	BUG_ON(ret);
 }
 
-static int xen_blkbk_map(struct blkif_request *req,
-			 struct pending_req *pending_req,
-			 struct seg_buf seg[],
-			 struct page *pages[])
+static int xen_blkbk_map(struct xen_blkif *blkif,
+			 struct grant_page *pages[],
+			 int num, bool ro)
 {
 	struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST];
-	struct persistent_gnt *persistent_gnts[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 	struct page *pages_to_gnt[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 	struct persistent_gnt *persistent_gnt = NULL;
-	struct xen_blkif *blkif = pending_req->blkif;
 	phys_addr_t addr = 0;
-	int i, j;
-	bool new_map;
-	int nseg = req->u.rw.nr_segments;
+	int i, seg_idx, new_map_idx;
 	int segs_to_map = 0;
 	int ret = 0;
+	int last_map = 0, map_until = 0;
 	int use_persistent_gnts;
 
 	use_persistent_gnts = (blkif->vbd.feature_gnt_persistent);
 
-	BUG_ON(blkif->persistent_gnt_c >
-		   max_mapped_grant_pages(pending_req->blkif->blk_protocol));
-
 	/*
 	 * Fill out preq.nr_sects with proper amount of sectors, and setup
 	 * assign map[..] with the PFN of the page in our domain with the
 	 * corresponding grant reference for each page.
 	 */
-	for (i = 0; i < nseg; i++) {
+again:
+	for (i = map_until; i < num; i++) {
 		uint32_t flags;
 
 		if (use_persistent_gnts)
 			persistent_gnt = get_persistent_gnt(
-				&blkif->persistent_gnts,
-				req->u.rw.seg[i].gref);
+				blkif,
+				pages[i]->gref);
 
 		if (persistent_gnt) {
 			/*
 			 * We are using persistent grants and
 			 * the grant is already mapped
 			 */
-			new_map = false;
-		} else if (use_persistent_gnts &&
-			   blkif->persistent_gnt_c <
-			   max_mapped_grant_pages(blkif->blk_protocol)) {
-			/*
-			 * We are using persistent grants, the grant is
-			 * not mapped but we have room for it
-			 */
-			new_map = true;
-			persistent_gnt = kmalloc(
-				sizeof(struct persistent_gnt),
-				GFP_KERNEL);
-			if (!persistent_gnt)
-				return -ENOMEM;
-			if (alloc_xenballooned_pages(1, &persistent_gnt->page,
-			    false)) {
-				kfree(persistent_gnt);
-				return -ENOMEM;
-			}
-			persistent_gnt->gnt = req->u.rw.seg[i].gref;
-			persistent_gnt->handle = BLKBACK_INVALID_HANDLE;
-
-			pages_to_gnt[segs_to_map] =
-				persistent_gnt->page;
-			addr = (unsigned long) pfn_to_kaddr(
-				page_to_pfn(persistent_gnt->page));
-
-			add_persistent_gnt(&blkif->persistent_gnts,
-				persistent_gnt);
-			blkif->persistent_gnt_c++;
-			pr_debug(DRV_PFX " grant %u added to the tree of persistent grants, using %u/%u\n",
-				 persistent_gnt->gnt, blkif->persistent_gnt_c,
-				 max_mapped_grant_pages(blkif->blk_protocol));
-		} else {
-			/*
-			 * We are either using persistent grants and
-			 * hit the maximum limit of grants mapped,
-			 * or we are not using persistent grants.
-			 */
-			if (use_persistent_gnts &&
-				!blkif->vbd.overflow_max_grants) {
-				blkif->vbd.overflow_max_grants = 1;
-				pr_alert(DRV_PFX " domain %u, device %#x is using maximum number of persistent grants\n",
-					 blkif->domid, blkif->vbd.handle);
-			}
-			new_map = true;
-			pages[i] = blkbk->pending_page(pending_req, i);
-			addr = vaddr(pending_req, i);
-			pages_to_gnt[segs_to_map] =
-				blkbk->pending_page(pending_req, i);
-		}
-
-		if (persistent_gnt) {
-			pages[i] = persistent_gnt->page;
-			persistent_gnts[i] = persistent_gnt;
+			pages[i]->page = persistent_gnt->page;
+			pages[i]->persistent_gnt = persistent_gnt;
 		} else {
-			persistent_gnts[i] = NULL;
-		}
-
-		if (new_map) {
+			if (get_free_page(blkif, &pages[i]->page))
+				goto out_of_memory;
+			addr = vaddr(pages[i]->page);
+			pages_to_gnt[segs_to_map] = pages[i]->page;
+			pages[i]->persistent_gnt = NULL;
 			flags = GNTMAP_host_map;
-			if (!persistent_gnt &&
-			    (pending_req->operation != BLKIF_OP_READ))
+			if (!use_persistent_gnts && ro)
 				flags |= GNTMAP_readonly;
 			gnttab_set_map_op(&map[segs_to_map++], addr,
-					  flags, req->u.rw.seg[i].gref,
+					  flags, pages[i]->gref,
 					  blkif->domid);
 		}
+		map_until = i + 1;
+		if (segs_to_map == BLKIF_MAX_SEGMENTS_PER_REQUEST)
+			break;
 	}
 
 	if (segs_to_map) {
@@ -595,49 +749,133 @@ static int xen_blkbk_map(struct blkif_re
 	 * so that when we access vaddr(pending_req,i) it has the contents of
 	 * the page from the other domain.
 	 */
-	bitmap_zero(pending_req->unmap_seg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
-	for (i = 0, j = 0; i < nseg; i++) {
-		if (!persistent_gnts[i] ||
-		    persistent_gnts[i]->handle == BLKBACK_INVALID_HANDLE) {
+	for (seg_idx = last_map, new_map_idx = 0; seg_idx < map_until; seg_idx++) {
+		if (!pages[seg_idx]->persistent_gnt) {
 			/* This is a newly mapped grant */
-			BUG_ON(j >= segs_to_map);
-			if (unlikely(map[j].status != 0)) {
+			BUG_ON(new_map_idx >= segs_to_map);
+			if (unlikely(map[new_map_idx].status != 0)) {
 				pr_debug(DRV_PFX "invalid buffer -- could not remap it\n");
-				map[j].handle = BLKBACK_INVALID_HANDLE;
+				pages[seg_idx]->handle = BLKBACK_INVALID_HANDLE;
 				ret |= 1;
-				if (persistent_gnts[i]) {
-					rb_erase(&persistent_gnts[i]->node,
-						 &blkif->persistent_gnts);
-					blkif->persistent_gnt_c--;
-					kfree(persistent_gnts[i]);
-					persistent_gnts[i] = NULL;
-				}
+				goto next;
 			}
+			pages[seg_idx]->handle = map[new_map_idx].handle;
+		} else {
+			continue;
 		}
-		if (persistent_gnts[i]) {
-			if (persistent_gnts[i]->handle ==
-			    BLKBACK_INVALID_HANDLE) {
+		if (use_persistent_gnts &&
+		    blkif->persistent_gnt_c < xen_blkif_max_pgrants) {
+			/*
+			 * We are using persistent grants, the grant is
+			 * not mapped but we might have room for it.
+			 */
+			persistent_gnt = kmalloc(sizeof(struct persistent_gnt),
+				                 GFP_KERNEL);
+			if (!persistent_gnt) {
 				/*
-				 * If this is a new persistent grant
-				 * save the handler
+				 * If we don't have enough memory to
+				 * allocate the persistent_gnt struct
+				 * map this grant non-persistenly
 				 */
-				persistent_gnts[i]->handle = map[j++].handle;
+				goto next;
 			}
-			pending_handle(pending_req, i) =
-				persistent_gnts[i]->handle;
+			persistent_gnt->gnt = map[new_map_idx].ref;
+			persistent_gnt->handle = map[new_map_idx].handle;
+			persistent_gnt->page = pages[seg_idx]->page;
+			if (add_persistent_gnt(blkif,
+			                       persistent_gnt)) {
+				kfree(persistent_gnt);
+				persistent_gnt = NULL;
+				goto next;
+			}
+			pages[seg_idx]->persistent_gnt = persistent_gnt;
+			pr_debug(DRV_PFX " grant %u added to the tree of persistent grants, using %u/%u\n",
+				 persistent_gnt->gnt, blkif->persistent_gnt_c,
+				 xen_blkif_max_pgrants);
+			goto next;
+		}
+		if (use_persistent_gnts && !blkif->vbd.overflow_max_grants) {
+			blkif->vbd.overflow_max_grants = 1;
+			pr_debug(DRV_PFX " domain %u, device %#x is using maximum number of persistent grants\n",
+			         blkif->domid, blkif->vbd.handle);
+		}
+		/*
+		 * We could not map this grant persistently, so use it as
+		 * a non-persistent grant.
+		 */
+next:
+		new_map_idx++;
+	}
+	segs_to_map = 0;
+	last_map = map_until;
+	if (map_until != num)
+		goto again;
 
-			if (ret)
-				continue;
-		} else {
-			pending_handle(pending_req, i) = map[j++].handle;
-			bitmap_set(pending_req->unmap_seg, i, 1);
+	return ret;
 
-			if (ret)
-				continue;
+out_of_memory:
+	pr_alert(DRV_PFX "%s: out of memory\n", __func__);
+	put_free_pages(blkif, pages_to_gnt, segs_to_map);
+	return -ENOMEM;
+}
+
+static int xen_blkbk_map_seg(struct pending_req *pending_req)
+{
+	int rc;
+
+	rc = xen_blkbk_map(pending_req->blkif, pending_req->segments,
+			   pending_req->nr_pages,
+	                   (pending_req->operation != BLKIF_OP_READ));
+
+	return rc;
+}
+
+static int xen_blkbk_parse_indirect(struct blkif_request *req,
+				    struct pending_req *pending_req,
+				    struct seg_buf seg[],
+				    struct phys_req *preq)
+{
+	struct grant_page **pages = pending_req->indirect_pages;
+	struct xen_blkif *blkif = pending_req->blkif;
+	int indirect_grefs, rc, n, nseg, i;
+	struct blkif_request_segment_aligned *segments = NULL;
+
+	nseg = pending_req->nr_pages;
+	indirect_grefs = INDIRECT_PAGES(nseg);
+	BUG_ON(indirect_grefs > BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST);
+
+	for (i = 0; i < indirect_grefs; i++)
+		pages[i]->gref = req->u.indirect.indirect_grefs[i];
+
+	rc = xen_blkbk_map(blkif, pages, indirect_grefs, true);
+	if (rc)
+		goto unmap;
+
+	for (n = 0, i = 0; n < nseg; n++) {
+		if ((n % SEGS_PER_INDIRECT_FRAME) == 0) {
+			/* Map indirect segments */
+			if (segments)
+				kunmap_atomic(segments);
+			segments = kmap_atomic(pages[n/SEGS_PER_INDIRECT_FRAME]->page);
 		}
-		seg[i].offset = (req->u.rw.seg[i].first_sect << 9);
+		i = n % SEGS_PER_INDIRECT_FRAME;
+		pending_req->segments[n]->gref = segments[i].gref;
+		seg[n].nsec = segments[i].last_sect -
+			segments[i].first_sect + 1;
+		seg[n].offset = (segments[i].first_sect << 9);
+		if ((segments[i].last_sect >= (PAGE_SIZE >> 9)) ||
+		    (segments[i].last_sect < segments[i].first_sect)) {
+			rc = -EINVAL;
+			goto unmap;
+		}
+		preq->nr_sects += seg[n].nsec;
 	}
-	return ret;
+
+unmap:
+	if (segments)
+		kunmap_atomic(segments);
+	xen_blkbk_unmap(blkif, pages, indirect_grefs);
+	return rc;
 }
 
 static int dispatch_discard_io(struct xen_blkif *blkif,
@@ -647,7 +885,18 @@ static int dispatch_discard_io(struct xe
 	int status = BLKIF_RSP_OKAY;
 	struct block_device *bdev = blkif->vbd.bdev;
 	unsigned long secure;
+	struct phys_req preq;
 
+	preq.sector_number = req->u.discard.sector_number;
+	preq.nr_sects      = req->u.discard.nr_sectors;
+
+	err = xen_vbd_translate(&preq, blkif, WRITE);
+	if (err) {
+		pr_warn(DRV_PFX "access denied: DISCARD [%llu->%llu] on dev=%04x\n",
+			preq.sector_number,
+			preq.sector_number + preq.nr_sects, blkif->vbd.pdevice);
+		goto fail_response;
+	}
 	blkif->st_ds_req++;
 
 	xen_blkif_get(blkif);
@@ -658,7 +907,7 @@ static int dispatch_discard_io(struct xe
 	err = blkdev_issue_discard(bdev, req->u.discard.sector_number,
 				   req->u.discard.nr_sectors,
 				   GFP_KERNEL, secure);
-
+fail_response:
 	if (err == -EOPNOTSUPP) {
 		pr_debug(DRV_PFX "discard op failed, not supported\n");
 		status = BLKIF_RSP_EOPNOTSUPP;
@@ -674,7 +923,7 @@ static int dispatch_other_io(struct xen_
 			     struct blkif_request *req,
 			     struct pending_req *pending_req)
 {
-	free_req(pending_req);
+	free_req(blkif, pending_req);
 	make_response(blkif, req->u.other.id, req->operation,
 		      BLKIF_RSP_EOPNOTSUPP);
 	return -EIO;
@@ -726,7 +975,9 @@ static void __end_block_io_op(struct pen
 	 * the proper response on the ring.
 	 */
 	if (atomic_dec_and_test(&pending_req->pendcnt)) {
-		xen_blkbk_unmap(pending_req);
+		xen_blkbk_unmap(pending_req->blkif,
+		                pending_req->segments,
+		                pending_req->nr_pages);
 		make_response(pending_req->blkif, pending_req->id,
 			      pending_req->operation, pending_req->status);
 		xen_blkif_put(pending_req->blkif);
@@ -734,7 +985,7 @@ static void __end_block_io_op(struct pen
 			if (atomic_read(&pending_req->blkif->drain))
 				complete(&pending_req->blkif->drain_complete);
 		}
-		free_req(pending_req);
+		free_req(pending_req->blkif, pending_req);
 	}
 }
 
@@ -767,6 +1018,12 @@ __do_block_io_op(struct xen_blkif *blkif
 	rp = blk_rings->common.sring->req_prod;
 	rmb(); /* Ensure we see queued requests up to 'rp'. */
 
+	if (RING_REQUEST_PROD_OVERFLOW(&blk_rings->common, rp)) {
+		rc = blk_rings->common.rsp_prod_pvt;
+		pr_warn(DRV_PFX "Frontend provided bogus ring requests (%d - %d = %d). Halting ring processing on dev=%04x\n",
+			rp, rc, rp - rc, blkif->vbd.pdevice);
+		return -EACCES;
+	}
 	while (rc != rp) {
 
 		if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
@@ -777,7 +1034,7 @@ __do_block_io_op(struct xen_blkif *blkif
 			break;
 		}
 
-		pending_req = alloc_req();
+		pending_req = alloc_req(blkif);
 		if (NULL == pending_req) {
 			blkif->st_oo_req++;
 			more_to_do = 1;
@@ -807,11 +1064,12 @@ __do_block_io_op(struct xen_blkif *blkif
 		case BLKIF_OP_WRITE:
 		case BLKIF_OP_WRITE_BARRIER:
 		case BLKIF_OP_FLUSH_DISKCACHE:
+		case BLKIF_OP_INDIRECT:
 			if (dispatch_rw_block_io(blkif, &req, pending_req))
 				goto done;
 			break;
 		case BLKIF_OP_DISCARD:
-			free_req(pending_req);
+			free_req(blkif, pending_req);
 			if (dispatch_discard_io(blkif, &req))
 				goto done;
 			break;
@@ -853,17 +1111,28 @@ static int dispatch_rw_block_io(struct x
 				struct pending_req *pending_req)
 {
 	struct phys_req preq;
-	struct seg_buf seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	struct seg_buf *seg = pending_req->seg;
 	unsigned int nseg;
 	struct bio *bio = NULL;
-	struct bio *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	struct bio **biolist = pending_req->biolist;
 	int i, nbio = 0;
 	int operation;
 	struct blk_plug plug;
 	bool drain = false;
-	struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	struct grant_page **pages = pending_req->segments;
+	unsigned short req_operation;
 
-	switch (req->operation) {
+	req_operation = req->operation == BLKIF_OP_INDIRECT ?
+			req->u.indirect.indirect_op : req->operation;
+	if ((req->operation == BLKIF_OP_INDIRECT) &&
+	    (req_operation != BLKIF_OP_READ) &&
+	    (req_operation != BLKIF_OP_WRITE)) {
+		pr_debug(DRV_PFX "Invalid indirect operation (%u)\n",
+			 req_operation);
+		goto fail_response;
+	}
+
+	switch (req_operation) {
 	case BLKIF_OP_READ:
 		blkif->st_rd_req++;
 		operation = READ;
@@ -885,33 +1154,47 @@ static int dispatch_rw_block_io(struct x
 	}
 
 	/* Check that the number of segments is sane. */
-	nseg = req->u.rw.nr_segments;
+	nseg = req->operation == BLKIF_OP_INDIRECT ?
+	       req->u.indirect.nr_segments : req->u.rw.nr_segments;
 
 	if (unlikely(nseg == 0 && operation != WRITE_FLUSH) ||
-	    unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
+	    unlikely((req->operation != BLKIF_OP_INDIRECT) &&
+		     (nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) ||
+	    unlikely((req->operation == BLKIF_OP_INDIRECT) &&
+		     (nseg > MAX_INDIRECT_SEGMENTS))) {
 		pr_debug(DRV_PFX "Bad number of segments in request (%d)\n",
 			 nseg);
 		/* Haven't submitted any bio's yet. */
 		goto fail_response;
 	}
 
-	preq.sector_number = req->u.rw.sector_number;
 	preq.nr_sects      = 0;
 
 	pending_req->blkif     = blkif;
 	pending_req->id        = req->u.rw.id;
-	pending_req->operation = req->operation;
+	pending_req->operation = req_operation;
 	pending_req->status    = BLKIF_RSP_OKAY;
 	pending_req->nr_pages  = nseg;
 
-	for (i = 0; i < nseg; i++) {
-		seg[i].nsec = req->u.rw.seg[i].last_sect -
-			req->u.rw.seg[i].first_sect + 1;
-		if ((req->u.rw.seg[i].last_sect >= (PAGE_SIZE >> 9)) ||
-		    (req->u.rw.seg[i].last_sect < req->u.rw.seg[i].first_sect))
+	if (req->operation != BLKIF_OP_INDIRECT) {
+		preq.dev               = req->u.rw.handle;
+		preq.sector_number     = req->u.rw.sector_number;
+		for (i = 0; i < nseg; i++) {
+			pages[i]->gref = req->u.rw.seg[i].gref;
+			seg[i].nsec = req->u.rw.seg[i].last_sect -
+				req->u.rw.seg[i].first_sect + 1;
+			seg[i].offset = (req->u.rw.seg[i].first_sect << 9);
+			if ((req->u.rw.seg[i].last_sect >= (PAGE_SIZE >> 9)) ||
+			    (req->u.rw.seg[i].last_sect <
+			     req->u.rw.seg[i].first_sect))
+				goto fail_response;
+			preq.nr_sects += seg[i].nsec;
+		}
+	} else {
+		preq.dev               = req->u.indirect.handle;
+		preq.sector_number     = req->u.indirect.sector_number;
+		if (xen_blkbk_parse_indirect(req, pending_req, seg, &preq))
 			goto fail_response;
-		preq.nr_sects += seg[i].nsec;
-
 	}
 
 	if (xen_vbd_translate(&preq, blkif, operation) != 0) {
@@ -948,7 +1231,7 @@ static int dispatch_rw_block_io(struct x
 	 * the hypercall to unmap the grants - that is all done in
 	 * xen_blkbk_unmap.
 	 */
-	if (xen_blkbk_map(req, pending_req, seg, pages))
+	if (xen_blkbk_map_seg(pending_req))
 		goto fail_flush;
 
 	/*
@@ -960,11 +1243,12 @@ static int dispatch_rw_block_io(struct x
 	for (i = 0; i < nseg; i++) {
 		while ((bio == NULL) ||
 		       (bio_add_page(bio,
-				     pages[i],
+				     pages[i]->page,
 				     seg[i].nsec << 9,
 				     seg[i].offset) == 0)) {
 
-			bio = bio_alloc(GFP_KERNEL, nseg-i);
+			int nr_iovecs = min_t(int, (nseg-i), BIO_MAX_PAGES);
+			bio = bio_alloc(GFP_KERNEL, nr_iovecs);
 			if (unlikely(bio == NULL))
 				goto fail_put_bio;
 
@@ -1009,11 +1293,12 @@ static int dispatch_rw_block_io(struct x
 	return 0;
 
  fail_flush:
-	xen_blkbk_unmap(pending_req);
+	xen_blkbk_unmap(blkif, pending_req->segments,
+	                pending_req->nr_pages);
  fail_response:
 	/* Haven't submitted any bio's yet. */
-	make_response(blkif, req->u.rw.id, req->operation, BLKIF_RSP_ERROR);
-	free_req(pending_req);
+	make_response(blkif, req->u.rw.id, req_operation, BLKIF_RSP_ERROR);
+	free_req(blkif, pending_req);
 	msleep(1); /* back off a bit */
 	return -EIO;
 
@@ -1070,73 +1355,20 @@ static void make_response(struct xen_blk
 
 static int __init xen_blkif_init(void)
 {
-	int i, mmap_pages;
 	int rc = 0;
 
 	if (!xen_domain())
 		return -ENODEV;
 
-	blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL);
-	if (!blkbk) {
-		pr_alert(DRV_PFX "%s: out of memory!\n", __func__);
-		return -ENOMEM;
-	}
-
-	mmap_pages = xen_blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
-
-	blkbk->pending_reqs          = kzalloc(sizeof(blkbk->pending_reqs[0]) *
-					xen_blkif_reqs, GFP_KERNEL);
-	blkbk->pending_grant_handles = kmalloc(sizeof(blkbk->pending_grant_handles[0]) *
-					mmap_pages, GFP_KERNEL);
-	blkbk->pending_pages         = kzalloc(sizeof(blkbk->pending_pages[0]) *
-					mmap_pages, GFP_KERNEL);
-
-	if (!blkbk->pending_reqs || !blkbk->pending_grant_handles ||
-	    !blkbk->pending_pages) {
-		rc = -ENOMEM;
-		goto out_of_memory;
-	}
-
-	for (i = 0; i < mmap_pages; i++) {
-		blkbk->pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
-		blkbk->pending_pages[i] = alloc_page(GFP_KERNEL);
-		if (blkbk->pending_pages[i] == NULL) {
-			rc = -ENOMEM;
-			goto out_of_memory;
-		}
-	}
 	rc = xen_blkif_interface_init();
 	if (rc)
 		goto failed_init;
 
-	INIT_LIST_HEAD(&blkbk->pending_free);
-	spin_lock_init(&blkbk->pending_free_lock);
-	init_waitqueue_head(&blkbk->pending_free_wq);
-
-	for (i = 0; i < xen_blkif_reqs; i++)
-		list_add_tail(&blkbk->pending_reqs[i].free_list,
-			      &blkbk->pending_free);
-
 	rc = xen_blkif_xenbus_init();
 	if (rc)
 		goto failed_init;
 
-	return 0;
-
- out_of_memory:
-	pr_alert(DRV_PFX "%s: out of memory\n", __func__);
  failed_init:
-	kfree(blkbk->pending_reqs);
-	kfree(blkbk->pending_grant_handles);
-	if (blkbk->pending_pages) {
-		for (i = 0; i < mmap_pages; i++) {
-			if (blkbk->pending_pages[i])
-				__free_page(blkbk->pending_pages[i]);
-		}
-		kfree(blkbk->pending_pages);
-	}
-	kfree(blkbk);
-	blkbk = NULL;
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/xen-blkback/common.h linux-libre-3.11-rc7-gnu/drivers/block/xen-blkback/common.h
--- linux-libre-3.10-gnu/drivers/block/xen-blkback/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/xen-blkback/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -50,6 +50,19 @@
 		 __func__, __LINE__, ##args)
 
 
+/*
+ * This is the maximum number of segments that would be allowed in indirect
+ * requests. This value will also be passed to the frontend.
+ */
+#define MAX_INDIRECT_SEGMENTS 256
+
+#define SEGS_PER_INDIRECT_FRAME \
+	(PAGE_SIZE/sizeof(struct blkif_request_segment_aligned))
+#define MAX_INDIRECT_PAGES \
+	((MAX_INDIRECT_SEGMENTS + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
+#define INDIRECT_PAGES(_segs) \
+	((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
+
 /* Not a real protocol.  Used to generate ring structs which contain
  * the elements common to all protocols only.  This way we get a
  * compiler-checkable way to use common struct elements, so we can
@@ -83,12 +96,31 @@ struct blkif_x86_32_request_other {
 	uint64_t       id;           /* private guest value, echoed in resp  */
 } __attribute__((__packed__));
 
+struct blkif_x86_32_request_indirect {
+	uint8_t        indirect_op;
+	uint16_t       nr_segments;
+	uint64_t       id;
+	blkif_sector_t sector_number;
+	blkif_vdev_t   handle;
+	uint16_t       _pad1;
+	grant_ref_t    indirect_grefs[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST];
+	/*
+	 * The maximum number of indirect segments (and pages) that will
+	 * be used is determined by MAX_INDIRECT_SEGMENTS, this value
+	 * is also exported to the guest (via xenstore
+	 * feature-max-indirect-segments entry), so the frontend knows how
+	 * many indirect segments the backend supports.
+	 */
+	uint64_t       _pad2;        /* make it 64 byte aligned */
+} __attribute__((__packed__));
+
 struct blkif_x86_32_request {
 	uint8_t        operation;    /* BLKIF_OP_???                         */
 	union {
 		struct blkif_x86_32_request_rw rw;
 		struct blkif_x86_32_request_discard discard;
 		struct blkif_x86_32_request_other other;
+		struct blkif_x86_32_request_indirect indirect;
 	} u;
 } __attribute__((__packed__));
 
@@ -127,12 +159,32 @@ struct blkif_x86_64_request_other {
 	uint64_t       id;           /* private guest value, echoed in resp  */
 } __attribute__((__packed__));
 
+struct blkif_x86_64_request_indirect {
+	uint8_t        indirect_op;
+	uint16_t       nr_segments;
+	uint32_t       _pad1;        /* offsetof(blkif_..,u.indirect.id)==8   */
+	uint64_t       id;
+	blkif_sector_t sector_number;
+	blkif_vdev_t   handle;
+	uint16_t       _pad2;
+	grant_ref_t    indirect_grefs[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST];
+	/*
+	 * The maximum number of indirect segments (and pages) that will
+	 * be used is determined by MAX_INDIRECT_SEGMENTS, this value
+	 * is also exported to the guest (via xenstore
+	 * feature-max-indirect-segments entry), so the frontend knows how
+	 * many indirect segments the backend supports.
+	 */
+	uint32_t       _pad3;        /* make it 64 byte aligned */
+} __attribute__((__packed__));
+
 struct blkif_x86_64_request {
 	uint8_t        operation;    /* BLKIF_OP_???                         */
 	union {
 		struct blkif_x86_64_request_rw rw;
 		struct blkif_x86_64_request_discard discard;
 		struct blkif_x86_64_request_other other;
+		struct blkif_x86_64_request_indirect indirect;
 	} u;
 } __attribute__((__packed__));
 
@@ -182,12 +234,26 @@ struct xen_vbd {
 
 struct backend_info;
 
+/* Number of available flags */
+#define PERSISTENT_GNT_FLAGS_SIZE	2
+/* This persistent grant is currently in use */
+#define PERSISTENT_GNT_ACTIVE		0
+/*
+ * This persistent grant has been used, this flag is set when we remove the
+ * PERSISTENT_GNT_ACTIVE, to know that this grant has been used recently.
+ */
+#define PERSISTENT_GNT_WAS_ACTIVE	1
+
+/* Number of requests that we can fit in a ring */
+#define XEN_BLKIF_REQS			32
 
 struct persistent_gnt {
 	struct page *page;
 	grant_ref_t gnt;
 	grant_handle_t handle;
+	DECLARE_BITMAP(flags, PERSISTENT_GNT_FLAGS_SIZE);
 	struct rb_node node;
+	struct list_head remove_node;
 };
 
 struct xen_blkif {
@@ -219,6 +285,23 @@ struct xen_blkif {
 	/* tree to store persistent grants */
 	struct rb_root		persistent_gnts;
 	unsigned int		persistent_gnt_c;
+	atomic_t		persistent_gnt_in_use;
+	unsigned long           next_lru;
+
+	/* used by the kworker that offload work from the persistent purge */
+	struct list_head	persistent_purge_list;
+	struct work_struct	persistent_purge_work;
+
+	/* buffer of free pages to map grant refs */
+	spinlock_t		free_pages_lock;
+	int			free_pages_num;
+	struct list_head	free_pages;
+
+	/* List of all 'pending_req' available */
+	struct list_head	pending_free;
+	/* And its spinlock. */
+	spinlock_t		pending_free_lock;
+	wait_queue_head_t	pending_free_wq;
 
 	/* statistics */
 	unsigned long		st_print;
@@ -231,6 +314,41 @@ struct xen_blkif {
 	unsigned long long			st_wr_sect;
 
 	wait_queue_head_t	waiting_to_free;
+	/* Thread shutdown wait queue. */
+	wait_queue_head_t	shutdown_wq;
+};
+
+struct seg_buf {
+	unsigned long offset;
+	unsigned int nsec;
+};
+
+struct grant_page {
+	struct page 		*page;
+	struct persistent_gnt	*persistent_gnt;
+	grant_handle_t		handle;
+	grant_ref_t		gref;
+};
+
+/*
+ * Each outstanding request that we've passed to the lower device layers has a
+ * 'pending_req' allocated to it. Each buffer_head that completes decrements
+ * the pendcnt towards zero. When it hits zero, the specified domain has a
+ * response queued for it, with the saved 'id' passed back.
+ */
+struct pending_req {
+	struct xen_blkif	*blkif;
+	u64			id;
+	int			nr_pages;
+	atomic_t		pendcnt;
+	unsigned short		operation;
+	int			status;
+	struct list_head	free_list;
+	struct grant_page	*segments[MAX_INDIRECT_SEGMENTS];
+	/* Indirect descriptors */
+	struct grant_page	*indirect_pages[MAX_INDIRECT_PAGES];
+	struct seg_buf		seg[MAX_INDIRECT_SEGMENTS];
+	struct bio		*biolist[MAX_INDIRECT_SEGMENTS];
 };
 
 
@@ -257,6 +375,7 @@ int xen_blkif_xenbus_init(void);
 
 irqreturn_t xen_blkif_be_int(int irq, void *dev_id);
 int xen_blkif_schedule(void *arg);
+int xen_blkif_purge_persistent(void *arg);
 
 int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
 			      struct backend_info *be, int state);
@@ -268,7 +387,7 @@ struct xenbus_device *xen_blkbk_xenbus(s
 static inline void blkif_get_x86_32_req(struct blkif_request *dst,
 					struct blkif_x86_32_request *src)
 {
-	int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+	int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
 	dst->operation = src->operation;
 	switch (src->operation) {
 	case BLKIF_OP_READ:
@@ -291,6 +410,18 @@ static inline void blkif_get_x86_32_req(
 		dst->u.discard.sector_number = src->u.discard.sector_number;
 		dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
 		break;
+	case BLKIF_OP_INDIRECT:
+		dst->u.indirect.indirect_op = src->u.indirect.indirect_op;
+		dst->u.indirect.nr_segments = src->u.indirect.nr_segments;
+		dst->u.indirect.handle = src->u.indirect.handle;
+		dst->u.indirect.id = src->u.indirect.id;
+		dst->u.indirect.sector_number = src->u.indirect.sector_number;
+		barrier();
+		j = min(MAX_INDIRECT_PAGES, INDIRECT_PAGES(dst->u.indirect.nr_segments));
+		for (i = 0; i < j; i++)
+			dst->u.indirect.indirect_grefs[i] =
+				src->u.indirect.indirect_grefs[i];
+		break;
 	default:
 		/*
 		 * Don't know how to translate this op. Only get the
@@ -304,7 +435,7 @@ static inline void blkif_get_x86_32_req(
 static inline void blkif_get_x86_64_req(struct blkif_request *dst,
 					struct blkif_x86_64_request *src)
 {
-	int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+	int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
 	dst->operation = src->operation;
 	switch (src->operation) {
 	case BLKIF_OP_READ:
@@ -327,6 +458,18 @@ static inline void blkif_get_x86_64_req(
 		dst->u.discard.sector_number = src->u.discard.sector_number;
 		dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
 		break;
+	case BLKIF_OP_INDIRECT:
+		dst->u.indirect.indirect_op = src->u.indirect.indirect_op;
+		dst->u.indirect.nr_segments = src->u.indirect.nr_segments;
+		dst->u.indirect.handle = src->u.indirect.handle;
+		dst->u.indirect.id = src->u.indirect.id;
+		dst->u.indirect.sector_number = src->u.indirect.sector_number;
+		barrier();
+		j = min(MAX_INDIRECT_PAGES, INDIRECT_PAGES(dst->u.indirect.nr_segments));
+		for (i = 0; i < j; i++)
+			dst->u.indirect.indirect_grefs[i] =
+				src->u.indirect.indirect_grefs[i];
+		break;
 	default:
 		/*
 		 * Don't know how to translate this op. Only get the
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/xen-blkback/xenbus.c linux-libre-3.11-rc7-gnu/drivers/block/xen-blkback/xenbus.c
--- linux-libre-3.10-gnu/drivers/block/xen-blkback/xenbus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/xen-blkback/xenbus.c	2013-08-25 20:43:22.000000000 -0400
@@ -93,17 +93,22 @@ static void xen_update_blkif_status(stru
 	}
 	invalidate_inode_pages2(blkif->vbd.bdev->bd_inode->i_mapping);
 
-	blkif->xenblkd = kthread_run(xen_blkif_schedule, blkif, name);
+	blkif->xenblkd = kthread_run(xen_blkif_schedule, blkif, "%s", name);
 	if (IS_ERR(blkif->xenblkd)) {
 		err = PTR_ERR(blkif->xenblkd);
 		blkif->xenblkd = NULL;
 		xenbus_dev_error(blkif->be->dev, err, "start xenblkd");
+		return;
 	}
 }
 
 static struct xen_blkif *xen_blkif_alloc(domid_t domid)
 {
 	struct xen_blkif *blkif;
+	struct pending_req *req, *n;
+	int i, j;
+
+	BUILD_BUG_ON(MAX_INDIRECT_PAGES > BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST);
 
 	blkif = kmem_cache_zalloc(xen_blkif_cachep, GFP_KERNEL);
 	if (!blkif)
@@ -118,8 +123,57 @@ static struct xen_blkif *xen_blkif_alloc
 	blkif->st_print = jiffies;
 	init_waitqueue_head(&blkif->waiting_to_free);
 	blkif->persistent_gnts.rb_node = NULL;
+	spin_lock_init(&blkif->free_pages_lock);
+	INIT_LIST_HEAD(&blkif->free_pages);
+	blkif->free_pages_num = 0;
+	atomic_set(&blkif->persistent_gnt_in_use, 0);
+
+	INIT_LIST_HEAD(&blkif->pending_free);
+
+	for (i = 0; i < XEN_BLKIF_REQS; i++) {
+		req = kzalloc(sizeof(*req), GFP_KERNEL);
+		if (!req)
+			goto fail;
+		list_add_tail(&req->free_list,
+		              &blkif->pending_free);
+		for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++) {
+			req->segments[j] = kzalloc(sizeof(*req->segments[0]),
+			                           GFP_KERNEL);
+			if (!req->segments[j])
+				goto fail;
+		}
+		for (j = 0; j < MAX_INDIRECT_PAGES; j++) {
+			req->indirect_pages[j] = kzalloc(sizeof(*req->indirect_pages[0]),
+			                                 GFP_KERNEL);
+			if (!req->indirect_pages[j])
+				goto fail;
+		}
+	}
+	spin_lock_init(&blkif->pending_free_lock);
+	init_waitqueue_head(&blkif->pending_free_wq);
+	init_waitqueue_head(&blkif->shutdown_wq);
 
 	return blkif;
+
+fail:
+	list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) {
+		list_del(&req->free_list);
+		for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++) {
+			if (!req->segments[j])
+				break;
+			kfree(req->segments[j]);
+		}
+		for (j = 0; j < MAX_INDIRECT_PAGES; j++) {
+			if (!req->indirect_pages[j])
+				break;
+			kfree(req->indirect_pages[j]);
+		}
+		kfree(req);
+	}
+
+	kmem_cache_free(xen_blkif_cachep, blkif);
+
+	return ERR_PTR(-ENOMEM);
 }
 
 static int xen_blkif_map(struct xen_blkif *blkif, unsigned long shared_page,
@@ -178,6 +232,7 @@ static void xen_blkif_disconnect(struct
 {
 	if (blkif->xenblkd) {
 		kthread_stop(blkif->xenblkd);
+		wake_up(&blkif->shutdown_wq);
 		blkif->xenblkd = NULL;
 	}
 
@@ -198,8 +253,28 @@ static void xen_blkif_disconnect(struct
 
 static void xen_blkif_free(struct xen_blkif *blkif)
 {
+	struct pending_req *req, *n;
+	int i = 0, j;
+
 	if (!atomic_dec_and_test(&blkif->refcnt))
 		BUG();
+
+	/* Check that there is no request in use */
+	list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) {
+		list_del(&req->free_list);
+
+		for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++)
+			kfree(req->segments[j]);
+
+		for (j = 0; j < MAX_INDIRECT_PAGES; j++)
+			kfree(req->indirect_pages[j]);
+
+		kfree(req);
+		i++;
+	}
+
+	WARN_ON(i != XEN_BLKIF_REQS);
+
 	kmem_cache_free(xen_blkif_cachep, blkif);
 }
 
@@ -678,6 +753,11 @@ again:
 				 dev->nodename);
 		goto abort;
 	}
+	err = xenbus_printf(xbt, dev->nodename, "feature-max-indirect-segments", "%u",
+			    MAX_INDIRECT_SEGMENTS);
+	if (err)
+		dev_warn(&dev->dev, "writing %s/feature-max-indirect-segments (%d)",
+			 dev->nodename, err);
 
 	err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
 			    (unsigned long long)vbd_sz(&be->blkif->vbd));
@@ -704,6 +784,11 @@ again:
 				 dev->nodename);
 		goto abort;
 	}
+	err = xenbus_printf(xbt, dev->nodename, "physical-sector-size", "%u",
+			    bdev_physical_block_size(be->blkif->vbd.bdev));
+	if (err)
+		xenbus_dev_error(dev, err, "writing %s/physical-sector-size",
+				 dev->nodename);
 
 	err = xenbus_transaction_end(xbt, 0);
 	if (err == -EAGAIN)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/xen-blkfront.c linux-libre-3.11-rc7-gnu/drivers/block/xen-blkfront.c
--- linux-libre-3.10-gnu/drivers/block/xen-blkfront.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/xen-blkfront.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,12 +74,30 @@ struct grant {
 struct blk_shadow {
 	struct blkif_request req;
 	struct request *request;
-	struct grant *grants_used[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	struct grant **grants_used;
+	struct grant **indirect_grants;
+	struct scatterlist *sg;
+};
+
+struct split_bio {
+	struct bio *bio;
+	atomic_t pending;
+	int err;
 };
 
 static DEFINE_MUTEX(blkfront_mutex);
 static const struct block_device_operations xlvbd_block_fops;
 
+/*
+ * Maximum number of segments in indirect requests, the actual value used by
+ * the frontend driver is the minimum of this value and the value provided
+ * by the backend driver.
+ */
+
+static unsigned int xen_blkif_max_segments = 32;
+module_param_named(max, xen_blkif_max_segments, int, S_IRUGO);
+MODULE_PARM_DESC(max, "Maximum amount of segments in indirect requests (default is 32)");
+
 #define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
 
 /*
@@ -98,7 +116,6 @@ struct blkfront_info
 	enum blkif_state connected;
 	int ring_ref;
 	struct blkif_front_ring ring;
-	struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 	unsigned int evtchn, irq;
 	struct request_queue *rq;
 	struct work_struct work;
@@ -114,6 +131,7 @@ struct blkfront_info
 	unsigned int discard_granularity;
 	unsigned int discard_alignment;
 	unsigned int feature_persistent:1;
+	unsigned int max_indirect_segments;
 	int is_ready;
 };
 
@@ -142,6 +160,13 @@ static DEFINE_SPINLOCK(minor_lock);
 
 #define DEV_NAME	"xvd"	/* name in /dev */
 
+#define SEGS_PER_INDIRECT_FRAME \
+	(PAGE_SIZE/sizeof(struct blkif_request_segment_aligned))
+#define INDIRECT_GREFS(_segs) \
+	((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
+
+static int blkfront_setup_indirect(struct blkfront_info *info);
+
 static int get_id_from_freelist(struct blkfront_info *info)
 {
 	unsigned long free = info->shadow_free;
@@ -358,7 +383,8 @@ static int blkif_queue_request(struct re
 	struct blkif_request *ring_req;
 	unsigned long id;
 	unsigned int fsect, lsect;
-	int i, ref;
+	int i, ref, n;
+	struct blkif_request_segment_aligned *segments = NULL;
 
 	/*
 	 * Used to store if we are able to queue the request by just using
@@ -369,21 +395,27 @@ static int blkif_queue_request(struct re
 	grant_ref_t gref_head;
 	struct grant *gnt_list_entry = NULL;
 	struct scatterlist *sg;
+	int nseg, max_grefs;
 
 	if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
 		return 1;
 
-	/* Check if we have enought grants to allocate a requests */
-	if (info->persistent_gnts_c < BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+	max_grefs = info->max_indirect_segments ?
+		    info->max_indirect_segments +
+		    INDIRECT_GREFS(info->max_indirect_segments) :
+		    BLKIF_MAX_SEGMENTS_PER_REQUEST;
+
+	/* Check if we have enough grants to allocate a requests */
+	if (info->persistent_gnts_c < max_grefs) {
 		new_persistent_gnts = 1;
 		if (gnttab_alloc_grant_references(
-		    BLKIF_MAX_SEGMENTS_PER_REQUEST - info->persistent_gnts_c,
+		    max_grefs - info->persistent_gnts_c,
 		    &gref_head) < 0) {
 			gnttab_request_free_callback(
 				&info->callback,
 				blkif_restart_queue_callback,
 				info,
-				BLKIF_MAX_SEGMENTS_PER_REQUEST);
+				max_grefs);
 			return 1;
 		}
 	} else
@@ -394,42 +426,67 @@ static int blkif_queue_request(struct re
 	id = get_id_from_freelist(info);
 	info->shadow[id].request = req;
 
-	ring_req->u.rw.id = id;
-	ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
-	ring_req->u.rw.handle = info->handle;
-
-	ring_req->operation = rq_data_dir(req) ?
-		BLKIF_OP_WRITE : BLKIF_OP_READ;
-
-	if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) {
-		/*
-		 * Ideally we can do an unordered flush-to-disk. In case the
-		 * backend onlysupports barriers, use that. A barrier request
-		 * a superset of FUA, so we can implement it the same
-		 * way.  (It's also a FLUSH+FUA, since it is
-		 * guaranteed ordered WRT previous writes.)
-		 */
-		ring_req->operation = info->flush_op;
-	}
-
 	if (unlikely(req->cmd_flags & (REQ_DISCARD | REQ_SECURE))) {
-		/* id, sector_number and handle are set above. */
 		ring_req->operation = BLKIF_OP_DISCARD;
 		ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
+		ring_req->u.discard.id = id;
+		ring_req->u.discard.sector_number = (blkif_sector_t)blk_rq_pos(req);
 		if ((req->cmd_flags & REQ_SECURE) && info->feature_secdiscard)
 			ring_req->u.discard.flag = BLKIF_DISCARD_SECURE;
 		else
 			ring_req->u.discard.flag = 0;
 	} else {
-		ring_req->u.rw.nr_segments = blk_rq_map_sg(req->q, req,
-							   info->sg);
-		BUG_ON(ring_req->u.rw.nr_segments >
-		       BLKIF_MAX_SEGMENTS_PER_REQUEST);
-
-		for_each_sg(info->sg, sg, ring_req->u.rw.nr_segments, i) {
+		BUG_ON(info->max_indirect_segments == 0 &&
+		       req->nr_phys_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
+		BUG_ON(info->max_indirect_segments &&
+		       req->nr_phys_segments > info->max_indirect_segments);
+		nseg = blk_rq_map_sg(req->q, req, info->shadow[id].sg);
+		ring_req->u.rw.id = id;
+		if (nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+			/*
+			 * The indirect operation can only be a BLKIF_OP_READ or
+			 * BLKIF_OP_WRITE
+			 */
+			BUG_ON(req->cmd_flags & (REQ_FLUSH | REQ_FUA));
+			ring_req->operation = BLKIF_OP_INDIRECT;
+			ring_req->u.indirect.indirect_op = rq_data_dir(req) ?
+				BLKIF_OP_WRITE : BLKIF_OP_READ;
+			ring_req->u.indirect.sector_number = (blkif_sector_t)blk_rq_pos(req);
+			ring_req->u.indirect.handle = info->handle;
+			ring_req->u.indirect.nr_segments = nseg;
+		} else {
+			ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
+			ring_req->u.rw.handle = info->handle;
+			ring_req->operation = rq_data_dir(req) ?
+				BLKIF_OP_WRITE : BLKIF_OP_READ;
+			if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) {
+				/*
+				 * Ideally we can do an unordered flush-to-disk. In case the
+				 * backend onlysupports barriers, use that. A barrier request
+				 * a superset of FUA, so we can implement it the same
+				 * way.  (It's also a FLUSH+FUA, since it is
+				 * guaranteed ordered WRT previous writes.)
+				 */
+				ring_req->operation = info->flush_op;
+			}
+			ring_req->u.rw.nr_segments = nseg;
+		}
+		for_each_sg(info->shadow[id].sg, sg, nseg, i) {
 			fsect = sg->offset >> 9;
 			lsect = fsect + (sg->length >> 9) - 1;
 
+			if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
+			    (i % SEGS_PER_INDIRECT_FRAME == 0)) {
+				if (segments)
+					kunmap_atomic(segments);
+
+				n = i / SEGS_PER_INDIRECT_FRAME;
+				gnt_list_entry = get_grant(&gref_head, info);
+				info->shadow[id].indirect_grants[n] = gnt_list_entry;
+				segments = kmap_atomic(pfn_to_page(gnt_list_entry->pfn));
+				ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
+			}
+
 			gnt_list_entry = get_grant(&gref_head, info);
 			ref = gnt_list_entry->gref;
 
@@ -441,8 +498,7 @@ static int blkif_queue_request(struct re
 
 				BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 
-				shared_data = kmap_atomic(
-					pfn_to_page(gnt_list_entry->pfn));
+				shared_data = kmap_atomic(pfn_to_page(gnt_list_entry->pfn));
 				bvec_data = kmap_atomic(sg_page(sg));
 
 				/*
@@ -461,13 +517,23 @@ static int blkif_queue_request(struct re
 				kunmap_atomic(bvec_data);
 				kunmap_atomic(shared_data);
 			}
-
-			ring_req->u.rw.seg[i] =
-					(struct blkif_request_segment) {
-						.gref       = ref,
-						.first_sect = fsect,
-						.last_sect  = lsect };
+			if (ring_req->operation != BLKIF_OP_INDIRECT) {
+				ring_req->u.rw.seg[i] =
+						(struct blkif_request_segment) {
+							.gref       = ref,
+							.first_sect = fsect,
+							.last_sect  = lsect };
+			} else {
+				n = i % SEGS_PER_INDIRECT_FRAME;
+				segments[n] =
+					(struct blkif_request_segment_aligned) {
+							.gref       = ref,
+							.first_sect = fsect,
+							.last_sect  = lsect };
+			}
 		}
+		if (segments)
+			kunmap_atomic(segments);
 	}
 
 	info->ring.req_prod_pvt++;
@@ -542,7 +608,9 @@ wait:
 		flush_requests(info);
 }
 
-static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
+static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
+				unsigned int physical_sector_size,
+				unsigned int segments)
 {
 	struct request_queue *rq;
 	struct blkfront_info *info = gd->private_data;
@@ -564,14 +632,15 @@ static int xlvbd_init_blk_queue(struct g
 
 	/* Hard sector size and max sectors impersonate the equiv. hardware. */
 	blk_queue_logical_block_size(rq, sector_size);
-	blk_queue_max_hw_sectors(rq, 512);
+	blk_queue_physical_block_size(rq, physical_sector_size);
+	blk_queue_max_hw_sectors(rq, (segments * PAGE_SIZE) / 512);
 
 	/* Each segment in a request is up to an aligned page in size. */
 	blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
 	blk_queue_max_segment_size(rq, PAGE_SIZE);
 
 	/* Ensure a merged request will fit in a single I/O ring slot. */
-	blk_queue_max_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST);
+	blk_queue_max_segments(rq, segments);
 
 	/* Make sure buffer addresses are sector-aligned. */
 	blk_queue_dma_alignment(rq, 511);
@@ -588,13 +657,16 @@ static int xlvbd_init_blk_queue(struct g
 static void xlvbd_flush(struct blkfront_info *info)
 {
 	blk_queue_flush(info->rq, info->feature_flush);
-	printk(KERN_INFO "blkfront: %s: %s: %s %s\n",
+	printk(KERN_INFO "blkfront: %s: %s: %s %s %s %s %s\n",
 	       info->gd->disk_name,
 	       info->flush_op == BLKIF_OP_WRITE_BARRIER ?
 		"barrier" : (info->flush_op == BLKIF_OP_FLUSH_DISKCACHE ?
 		"flush diskcache" : "barrier or flush"),
-	       info->feature_flush ? "enabled" : "disabled",
-	       info->feature_persistent ? "using persistent grants" : "");
+	       info->feature_flush ? "enabled;" : "disabled;",
+	       "persistent grants:",
+	       info->feature_persistent ? "enabled;" : "disabled;",
+	       "indirect descriptors:",
+	       info->max_indirect_segments ? "enabled;" : "disabled;");
 }
 
 static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset)
@@ -667,7 +739,8 @@ static char *encode_disk_name(char *ptr,
 
 static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
 			       struct blkfront_info *info,
-			       u16 vdisk_info, u16 sector_size)
+			       u16 vdisk_info, u16 sector_size,
+			       unsigned int physical_sector_size)
 {
 	struct gendisk *gd;
 	int nr_minors = 1;
@@ -734,7 +807,9 @@ static int xlvbd_alloc_gendisk(blkif_sec
 	gd->driverfs_dev = &(info->xbdev->dev);
 	set_capacity(gd, capacity);
 
-	if (xlvbd_init_blk_queue(gd, sector_size)) {
+	if (xlvbd_init_blk_queue(gd, sector_size, physical_sector_size,
+				 info->max_indirect_segments ? :
+				 BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
 		del_gendisk(gd);
 		goto release;
 	}
@@ -818,6 +893,7 @@ static void blkif_free(struct blkfront_i
 {
 	struct grant *persistent_gnt;
 	struct grant *n;
+	int i, j, segs;
 
 	/* Prevent new requests being issued until we fix things up. */
 	spin_lock_irq(&info->io_lock);
@@ -843,6 +919,47 @@ static void blkif_free(struct blkfront_i
 	}
 	BUG_ON(info->persistent_gnts_c != 0);
 
+	for (i = 0; i < BLK_RING_SIZE; i++) {
+		/*
+		 * Clear persistent grants present in requests already
+		 * on the shared ring
+		 */
+		if (!info->shadow[i].request)
+			goto free_shadow;
+
+		segs = info->shadow[i].req.operation == BLKIF_OP_INDIRECT ?
+		       info->shadow[i].req.u.indirect.nr_segments :
+		       info->shadow[i].req.u.rw.nr_segments;
+		for (j = 0; j < segs; j++) {
+			persistent_gnt = info->shadow[i].grants_used[j];
+			gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
+			__free_page(pfn_to_page(persistent_gnt->pfn));
+			kfree(persistent_gnt);
+		}
+
+		if (info->shadow[i].req.operation != BLKIF_OP_INDIRECT)
+			/*
+			 * If this is not an indirect operation don't try to
+			 * free indirect segments
+			 */
+			goto free_shadow;
+
+		for (j = 0; j < INDIRECT_GREFS(segs); j++) {
+			persistent_gnt = info->shadow[i].indirect_grants[j];
+			gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
+			__free_page(pfn_to_page(persistent_gnt->pfn));
+			kfree(persistent_gnt);
+		}
+
+free_shadow:
+		kfree(info->shadow[i].grants_used);
+		info->shadow[i].grants_used = NULL;
+		kfree(info->shadow[i].indirect_grants);
+		info->shadow[i].indirect_grants = NULL;
+		kfree(info->shadow[i].sg);
+		info->shadow[i].sg = NULL;
+	}
+
 	/* No more gnttab callback work. */
 	gnttab_cancel_free_callback(&info->callback);
 	spin_unlock_irq(&info->io_lock);
@@ -867,12 +984,13 @@ static void blkif_completion(struct blk_
 			     struct blkif_response *bret)
 {
 	int i = 0;
-	struct bio_vec *bvec;
-	struct req_iterator iter;
-	unsigned long flags;
+	struct scatterlist *sg;
 	char *bvec_data;
 	void *shared_data;
-	unsigned int offset = 0;
+	int nseg;
+
+	nseg = s->req.operation == BLKIF_OP_INDIRECT ?
+		s->req.u.indirect.nr_segments : s->req.u.rw.nr_segments;
 
 	if (bret->operation == BLKIF_OP_READ) {
 		/*
@@ -881,26 +999,29 @@ static void blkif_completion(struct blk_
 		 * than PAGE_SIZE, we have to keep track of the current offset,
 		 * to be sure we are copying the data from the right shared page.
 		 */
-		rq_for_each_segment(bvec, s->request, iter) {
-			BUG_ON((bvec->bv_offset + bvec->bv_len) > PAGE_SIZE);
-			if (bvec->bv_offset < offset)
-				i++;
-			BUG_ON(i >= s->req.u.rw.nr_segments);
+		for_each_sg(s->sg, sg, nseg, i) {
+			BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 			shared_data = kmap_atomic(
 				pfn_to_page(s->grants_used[i]->pfn));
-			bvec_data = bvec_kmap_irq(bvec, &flags);
-			memcpy(bvec_data, shared_data + bvec->bv_offset,
-				bvec->bv_len);
-			bvec_kunmap_irq(bvec_data, &flags);
+			bvec_data = kmap_atomic(sg_page(sg));
+			memcpy(bvec_data   + sg->offset,
+			       shared_data + sg->offset,
+			       sg->length);
+			kunmap_atomic(bvec_data);
 			kunmap_atomic(shared_data);
-			offset = bvec->bv_offset + bvec->bv_len;
 		}
 	}
 	/* Add the persistent grant into the list of free grants */
-	for (i = 0; i < s->req.u.rw.nr_segments; i++) {
+	for (i = 0; i < nseg; i++) {
 		list_add(&s->grants_used[i]->node, &info->persistent_gnts);
 		info->persistent_gnts_c++;
 	}
+	if (s->req.operation == BLKIF_OP_INDIRECT) {
+		for (i = 0; i < INDIRECT_GREFS(nseg); i++) {
+			list_add(&s->indirect_grants[i]->node, &info->persistent_gnts);
+			info->persistent_gnts_c++;
+		}
+	}
 }
 
 static irqreturn_t blkif_interrupt(int irq, void *dev_id)
@@ -1034,14 +1155,6 @@ static int setup_blkring(struct xenbus_d
 	SHARED_RING_INIT(sring);
 	FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
 
-	sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
-
-	/* Allocate memory for grants */
-	err = fill_grant_buffer(info, BLK_RING_SIZE *
-	                              BLKIF_MAX_SEGMENTS_PER_REQUEST);
-	if (err)
-		goto fail;
-
 	err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
 	if (err < 0) {
 		free_page((unsigned long)sring);
@@ -1223,13 +1336,84 @@ static int blkfront_probe(struct xenbus_
 	return 0;
 }
 
+/*
+ * This is a clone of md_trim_bio, used to split a bio into smaller ones
+ */
+static void trim_bio(struct bio *bio, int offset, int size)
+{
+	/* 'bio' is a cloned bio which we need to trim to match
+	 * the given offset and size.
+	 * This requires adjusting bi_sector, bi_size, and bi_io_vec
+	 */
+	int i;
+	struct bio_vec *bvec;
+	int sofar = 0;
+
+	size <<= 9;
+	if (offset == 0 && size == bio->bi_size)
+		return;
+
+	bio->bi_sector += offset;
+	bio->bi_size = size;
+	offset <<= 9;
+	clear_bit(BIO_SEG_VALID, &bio->bi_flags);
+
+	while (bio->bi_idx < bio->bi_vcnt &&
+	       bio->bi_io_vec[bio->bi_idx].bv_len <= offset) {
+		/* remove this whole bio_vec */
+		offset -= bio->bi_io_vec[bio->bi_idx].bv_len;
+		bio->bi_idx++;
+	}
+	if (bio->bi_idx < bio->bi_vcnt) {
+		bio->bi_io_vec[bio->bi_idx].bv_offset += offset;
+		bio->bi_io_vec[bio->bi_idx].bv_len -= offset;
+	}
+	/* avoid any complications with bi_idx being non-zero*/
+	if (bio->bi_idx) {
+		memmove(bio->bi_io_vec, bio->bi_io_vec+bio->bi_idx,
+			(bio->bi_vcnt - bio->bi_idx) * sizeof(struct bio_vec));
+		bio->bi_vcnt -= bio->bi_idx;
+		bio->bi_idx = 0;
+	}
+	/* Make sure vcnt and last bv are not too big */
+	bio_for_each_segment(bvec, bio, i) {
+		if (sofar + bvec->bv_len > size)
+			bvec->bv_len = size - sofar;
+		if (bvec->bv_len == 0) {
+			bio->bi_vcnt = i;
+			break;
+		}
+		sofar += bvec->bv_len;
+	}
+}
+
+static void split_bio_end(struct bio *bio, int error)
+{
+	struct split_bio *split_bio = bio->bi_private;
+
+	if (error)
+		split_bio->err = error;
+
+	if (atomic_dec_and_test(&split_bio->pending)) {
+		split_bio->bio->bi_phys_segments = 0;
+		bio_endio(split_bio->bio, split_bio->err);
+		kfree(split_bio);
+	}
+	bio_put(bio);
+}
 
 static int blkif_recover(struct blkfront_info *info)
 {
 	int i;
-	struct blkif_request *req;
+	struct request *req, *n;
 	struct blk_shadow *copy;
-	int j;
+	int rc;
+	struct bio *bio, *cloned_bio;
+	struct bio_list bio_list, merge_bio;
+	unsigned int segs, offset;
+	int pending, size;
+	struct split_bio *split_bio;
+	struct list_head requests;
 
 	/* Stage 1: Make a safe copy of the shadow state. */
 	copy = kmemdup(info->shadow, sizeof(info->shadow),
@@ -1244,36 +1428,64 @@ static int blkif_recover(struct blkfront
 	info->shadow_free = info->ring.req_prod_pvt;
 	info->shadow[BLK_RING_SIZE-1].req.u.rw.id = 0x0fffffff;
 
-	/* Stage 3: Find pending requests and requeue them. */
+	rc = blkfront_setup_indirect(info);
+	if (rc) {
+		kfree(copy);
+		return rc;
+	}
+
+	segs = info->max_indirect_segments ? : BLKIF_MAX_SEGMENTS_PER_REQUEST;
+	blk_queue_max_segments(info->rq, segs);
+	bio_list_init(&bio_list);
+	INIT_LIST_HEAD(&requests);
 	for (i = 0; i < BLK_RING_SIZE; i++) {
 		/* Not in use? */
 		if (!copy[i].request)
 			continue;
 
-		/* Grab a request slot and copy shadow state into it. */
-		req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
-		*req = copy[i].req;
-
-		/* We get a new request id, and must reset the shadow state. */
-		req->u.rw.id = get_id_from_freelist(info);
-		memcpy(&info->shadow[req->u.rw.id], &copy[i], sizeof(copy[i]));
-
-		if (req->operation != BLKIF_OP_DISCARD) {
-		/* Rewrite any grant references invalidated by susp/resume. */
-			for (j = 0; j < req->u.rw.nr_segments; j++)
-				gnttab_grant_foreign_access_ref(
-					req->u.rw.seg[j].gref,
-					info->xbdev->otherend_id,
-					pfn_to_mfn(copy[i].grants_used[j]->pfn),
-					0);
+		/*
+		 * Get the bios in the request so we can re-queue them.
+		 */
+		if (copy[i].request->cmd_flags &
+		    (REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
+			/*
+			 * Flush operations don't contain bios, so
+			 * we need to requeue the whole request
+			 */
+			list_add(&copy[i].request->queuelist, &requests);
+			continue;
 		}
-		info->shadow[req->u.rw.id].req = *req;
-
-		info->ring.req_prod_pvt++;
+		merge_bio.head = copy[i].request->bio;
+		merge_bio.tail = copy[i].request->biotail;
+		bio_list_merge(&bio_list, &merge_bio);
+		copy[i].request->bio = NULL;
+		blk_put_request(copy[i].request);
 	}
 
 	kfree(copy);
 
+	/*
+	 * Empty the queue, this is important because we might have
+	 * requests in the queue with more segments than what we
+	 * can handle now.
+	 */
+	spin_lock_irq(&info->io_lock);
+	while ((req = blk_fetch_request(info->rq)) != NULL) {
+		if (req->cmd_flags &
+		    (REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
+			list_add(&req->queuelist, &requests);
+			continue;
+		}
+		merge_bio.head = req->bio;
+		merge_bio.tail = req->biotail;
+		bio_list_merge(&bio_list, &merge_bio);
+		req->bio = NULL;
+		if (req->cmd_flags & (REQ_FLUSH | REQ_FUA))
+			pr_alert("diskcache flush request found!\n");
+		__blk_put_request(info->rq, req);
+	}
+	spin_unlock_irq(&info->io_lock);
+
 	xenbus_switch_state(info->xbdev, XenbusStateConnected);
 
 	spin_lock_irq(&info->io_lock);
@@ -1281,14 +1493,50 @@ static int blkif_recover(struct blkfront
 	/* Now safe for us to use the shared ring */
 	info->connected = BLKIF_STATE_CONNECTED;
 
-	/* Send off requeued requests */
-	flush_requests(info);
-
 	/* Kick any other new requests queued since we resumed */
 	kick_pending_request_queues(info);
 
+	list_for_each_entry_safe(req, n, &requests, queuelist) {
+		/* Requeue pending requests (flush or discard) */
+		list_del_init(&req->queuelist);
+		BUG_ON(req->nr_phys_segments > segs);
+		blk_requeue_request(info->rq, req);
+	}
 	spin_unlock_irq(&info->io_lock);
 
+	while ((bio = bio_list_pop(&bio_list)) != NULL) {
+		/* Traverse the list of pending bios and re-queue them */
+		if (bio_segments(bio) > segs) {
+			/*
+			 * This bio has more segments than what we can
+			 * handle, we have to split it.
+			 */
+			pending = (bio_segments(bio) + segs - 1) / segs;
+			split_bio = kzalloc(sizeof(*split_bio), GFP_NOIO);
+			BUG_ON(split_bio == NULL);
+			atomic_set(&split_bio->pending, pending);
+			split_bio->bio = bio;
+			for (i = 0; i < pending; i++) {
+				offset = (i * segs * PAGE_SIZE) >> 9;
+				size = min((unsigned int)(segs * PAGE_SIZE) >> 9,
+					   (unsigned int)(bio->bi_size >> 9) - offset);
+				cloned_bio = bio_clone(bio, GFP_NOIO);
+				BUG_ON(cloned_bio == NULL);
+				trim_bio(cloned_bio, offset, size);
+				cloned_bio->bi_private = split_bio;
+				cloned_bio->bi_end_io = split_bio_end;
+				submit_bio(cloned_bio->bi_rw, cloned_bio);
+			}
+			/*
+			 * Now we have to wait for all those smaller bios to
+			 * end, so we can also end the "parent" bio.
+			 */
+			continue;
+		}
+		/* We don't need to split this bio */
+		submit_bio(bio->bi_rw, bio);
+	}
+
 	return 0;
 }
 
@@ -1308,8 +1556,12 @@ static int blkfront_resume(struct xenbus
 	blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
 
 	err = talk_to_blkback(dev, info);
-	if (info->connected == BLKIF_STATE_SUSPENDED && !err)
-		err = blkif_recover(info);
+
+	/*
+	 * We have to wait for the backend to switch to
+	 * connected state, since we want to read which
+	 * features it supports.
+	 */
 
 	return err;
 }
@@ -1387,6 +1639,60 @@ static void blkfront_setup_discard(struc
 	kfree(type);
 }
 
+static int blkfront_setup_indirect(struct blkfront_info *info)
+{
+	unsigned int indirect_segments, segs;
+	int err, i;
+
+	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+			    "feature-max-indirect-segments", "%u", &indirect_segments,
+			    NULL);
+	if (err) {
+		info->max_indirect_segments = 0;
+		segs = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+	} else {
+		info->max_indirect_segments = min(indirect_segments,
+						  xen_blkif_max_segments);
+		segs = info->max_indirect_segments;
+	}
+
+	err = fill_grant_buffer(info, (segs + INDIRECT_GREFS(segs)) * BLK_RING_SIZE);
+	if (err)
+		goto out_of_memory;
+
+	for (i = 0; i < BLK_RING_SIZE; i++) {
+		info->shadow[i].grants_used = kzalloc(
+			sizeof(info->shadow[i].grants_used[0]) * segs,
+			GFP_NOIO);
+		info->shadow[i].sg = kzalloc(sizeof(info->shadow[i].sg[0]) * segs, GFP_NOIO);
+		if (info->max_indirect_segments)
+			info->shadow[i].indirect_grants = kzalloc(
+				sizeof(info->shadow[i].indirect_grants[0]) *
+				INDIRECT_GREFS(segs),
+				GFP_NOIO);
+		if ((info->shadow[i].grants_used == NULL) ||
+			(info->shadow[i].sg == NULL) ||
+		     (info->max_indirect_segments &&
+		     (info->shadow[i].indirect_grants == NULL)))
+			goto out_of_memory;
+		sg_init_table(info->shadow[i].sg, segs);
+	}
+
+
+	return 0;
+
+out_of_memory:
+	for (i = 0; i < BLK_RING_SIZE; i++) {
+		kfree(info->shadow[i].grants_used);
+		info->shadow[i].grants_used = NULL;
+		kfree(info->shadow[i].sg);
+		info->shadow[i].sg = NULL;
+		kfree(info->shadow[i].indirect_grants);
+		info->shadow[i].indirect_grants = NULL;
+	}
+	return -ENOMEM;
+}
+
 /*
  * Invoked when the backend is finally 'ready' (and has told produced
  * the details about the physical device - #sectors, size, etc).
@@ -1395,6 +1701,7 @@ static void blkfront_connect(struct blkf
 {
 	unsigned long long sectors;
 	unsigned long sector_size;
+	unsigned int physical_sector_size;
 	unsigned int binfo;
 	int err;
 	int barrier, flush, discard, persistent;
@@ -1414,8 +1721,15 @@ static void blkfront_connect(struct blkf
 		set_capacity(info->gd, sectors);
 		revalidate_disk(info->gd);
 
-		/* fall through */
+		return;
 	case BLKIF_STATE_SUSPENDED:
+		/*
+		 * If we are recovering from suspension, we need to wait
+		 * for the backend to announce it's features before
+		 * reconnecting, at least we need to know if the backend
+		 * supports indirect descriptors, and how many.
+		 */
+		blkif_recover(info);
 		return;
 
 	default:
@@ -1437,6 +1751,16 @@ static void blkfront_connect(struct blkf
 		return;
 	}
 
+	/*
+	 * physcial-sector-size is a newer field, so old backends may not
+	 * provide this. Assume physical sector size to be the same as
+	 * sector_size in that case.
+	 */
+	err = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
+			   "physical-sector-size", "%u", &physical_sector_size);
+	if (err != 1)
+		physical_sector_size = sector_size;
+
 	info->feature_flush = 0;
 	info->flush_op = 0;
 
@@ -1483,7 +1807,15 @@ static void blkfront_connect(struct blkf
 	else
 		info->feature_persistent = persistent;
 
-	err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
+	err = blkfront_setup_indirect(info);
+	if (err) {
+		xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s",
+				 info->xbdev->otherend);
+		return;
+	}
+
+	err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size,
+				  physical_sector_size);
 	if (err) {
 		xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
 				 info->xbdev->otherend);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/block/xsysace.c linux-libre-3.11-rc7-gnu/drivers/block/xsysace.c
--- linux-libre-3.10-gnu/drivers/block/xsysace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/block/xsysace.c	2013-08-25 20:43:22.000000000 -0400
@@ -407,7 +407,7 @@ static void ace_dump_regs(struct ace_dev
 		 ace_in32(ace, ACE_CFGLBA), ace_in(ace, ACE_FATSTAT));
 }
 
-void ace_fix_driveid(u16 *id)
+static void ace_fix_driveid(u16 *id)
 {
 #if defined(__BIG_ENDIAN)
 	int i;
@@ -463,7 +463,7 @@ static inline void ace_fsm_yieldirq(stru
 }
 
 /* Get the next read/write request; ending requests that we don't handle */
-struct request *ace_get_next_request(struct request_queue * q)
+static struct request *ace_get_next_request(struct request_queue *q)
 {
 	struct request *req;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bluetooth/ath3k.c linux-libre-3.11-rc7-gnu/drivers/bluetooth/ath3k.c
--- linux-libre-3.10-gnu/drivers/bluetooth/ath3k.c	2013-07-01 10:41:09.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bluetooth/ath3k.c	2013-08-31 18:00:54.000000000 -0400
@@ -91,6 +91,10 @@ static struct usb_device_id ath3k_table[
 	{ USB_DEVICE(0x0489, 0xe04e) },
 	{ USB_DEVICE(0x0489, 0xe056) },
 	{ USB_DEVICE(0x0489, 0xe04d) },
+	{ USB_DEVICE(0x04c5, 0x1330) },
+	{ USB_DEVICE(0x13d3, 0x3402) },
+	{ USB_DEVICE(0x0cf3, 0x3121) },
+	{ USB_DEVICE(0x0cf3, 0xe003) },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE02C) },
@@ -128,6 +132,10 @@ static struct usb_device_id ath3k_blist_
 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU22 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
@@ -193,24 +201,44 @@ error:
 
 static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
 {
-	int pipe = 0;
+	int ret, pipe = 0;
+	char *buf;
+
+	buf = kmalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
 	pipe = usb_rcvctrlpipe(udev, 0);
-	return usb_control_msg(udev, pipe, ATH3K_GETSTATE,
-			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-			state, 0x01, USB_CTRL_SET_TIMEOUT);
+	ret = usb_control_msg(udev, pipe, ATH3K_GETSTATE,
+			      USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+			      buf, sizeof(*buf), USB_CTRL_SET_TIMEOUT);
+
+	*state = *buf;
+	kfree(buf);
+
+	return ret;
 }
 
 static int ath3k_get_version(struct usb_device *udev,
 			struct ath3k_version *version)
 {
-	int pipe = 0;
+	int ret, pipe = 0;
+	struct ath3k_version *buf;
+	const int size = sizeof(*buf);
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
 	pipe = usb_rcvctrlpipe(udev, 0);
-	return usb_control_msg(udev, pipe, ATH3K_GETVERSION,
-			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version,
-			sizeof(struct ath3k_version),
-			USB_CTRL_SET_TIMEOUT);
+	ret = usb_control_msg(udev, pipe, ATH3K_GETVERSION,
+			      USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+			      buf, size, USB_CTRL_SET_TIMEOUT);
+
+	memcpy(version, buf, size);
+	kfree(buf);
+
+	return ret;
 }
 
 static int ath3k_load_fwfile(struct usb_device *udev,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bluetooth/btmrvl_sdio.c linux-libre-3.11-rc7-gnu/drivers/bluetooth/btmrvl_sdio.c
--- linux-libre-3.10-gnu/drivers/bluetooth/btmrvl_sdio.c	2013-07-01 10:41:20.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bluetooth/btmrvl_sdio.c	2013-08-31 18:01:05.000000000 -0400
@@ -554,6 +554,7 @@ static int btmrvl_sdio_card_to_host(stru
 	skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_ATOMIC);
 	if (skb == NULL) {
 		BT_ERR("No free skb");
+		ret = -ENOMEM;
 		goto exit;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bluetooth/btusb.c linux-libre-3.11-rc7-gnu/drivers/bluetooth/btusb.c
--- linux-libre-3.10-gnu/drivers/bluetooth/btusb.c	2013-07-01 10:41:17.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bluetooth/btusb.c	2013-08-31 18:01:02.000000000 -0400
@@ -57,6 +57,9 @@ static struct usb_device_id btusb_table[
 	/* Apple-specific (Broadcom) devices */
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) },
 
+	/* MediaTek MT76x0E */
+	{ USB_DEVICE(0x0e8d, 0x763f) },
+
 	/* Broadcom SoftSailing reporting vendor specific */
 	{ USB_DEVICE(0x0a5c, 0x21e1) },
 
@@ -151,6 +154,10 @@ static struct usb_device_id blacklist_ta
 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
 
 	/* Atheros AR5BBU12 with sflash firmware */
 	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -1092,7 +1099,7 @@ static int btusb_setup_intel_patching(st
 	if (IS_ERR(skb)) {
 		BT_ERR("%s sending Intel patch command (0x%4.4x) failed (%ld)",
 		       hdev->name, cmd->opcode, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 
 	/* It ensures that the returned event matches the event data read from
@@ -1144,7 +1151,7 @@ static int btusb_setup_intel(struct hci_
 	if (IS_ERR(skb)) {
 		BT_ERR("%s sending initial HCI reset command failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 	kfree_skb(skb);
 
@@ -1158,7 +1165,7 @@ static int btusb_setup_intel(struct hci_
 	if (IS_ERR(skb)) {
 		BT_ERR("%s reading Intel fw version command failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 
 	if (skb->len != sizeof(*ver)) {
@@ -1216,7 +1223,7 @@ static int btusb_setup_intel(struct hci_
 		BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
 		release_firmware(fw);
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 
 	if (skb->data[0]) {
@@ -1273,7 +1280,7 @@ static int btusb_setup_intel(struct hci_
 	if (IS_ERR(skb)) {
 		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 	kfree_skb(skb);
 
@@ -1289,7 +1296,7 @@ exit_mfg_disable:
 	if (IS_ERR(skb)) {
 		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 	kfree_skb(skb);
 
@@ -1307,7 +1314,7 @@ exit_mfg_deactivate:
 	if (IS_ERR(skb)) {
 		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
 		       hdev->name, PTR_ERR(skb));
-		return -PTR_ERR(skb);
+		return PTR_ERR(skb);
 	}
 	kfree_skb(skb);
 
@@ -1616,6 +1623,7 @@ static struct usb_driver btusb_driver =
 #ifdef CONFIG_PM
 	.suspend	= btusb_suspend,
 	.resume		= btusb_resume,
+	.reset_resume	= btusb_resume,
 #endif
 	.id_table	= btusb_table,
 	.supports_autosuspend = 1,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bus/arm-cci.c linux-libre-3.11-rc7-gnu/drivers/bus/arm-cci.c
--- linux-libre-3.10-gnu/drivers/bus/arm-cci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/bus/arm-cci.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,533 @@
+/*
+ * CCI cache coherent interconnect driver
+ *
+ * Copyright (C) 2013 ARM Ltd.
+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/arm-cci.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+
+#define CCI_PORT_CTRL		0x0
+#define CCI_CTRL_STATUS		0xc
+
+#define CCI_ENABLE_SNOOP_REQ	0x1
+#define CCI_ENABLE_DVM_REQ	0x2
+#define CCI_ENABLE_REQ		(CCI_ENABLE_SNOOP_REQ | CCI_ENABLE_DVM_REQ)
+
+struct cci_nb_ports {
+	unsigned int nb_ace;
+	unsigned int nb_ace_lite;
+};
+
+enum cci_ace_port_type {
+	ACE_INVALID_PORT = 0x0,
+	ACE_PORT,
+	ACE_LITE_PORT,
+};
+
+struct cci_ace_port {
+	void __iomem *base;
+	unsigned long phys;
+	enum cci_ace_port_type type;
+	struct device_node *dn;
+};
+
+static struct cci_ace_port *ports;
+static unsigned int nb_cci_ports;
+
+static void __iomem *cci_ctrl_base;
+static unsigned long cci_ctrl_phys;
+
+struct cpu_port {
+	u64 mpidr;
+	u32 port;
+};
+
+/*
+ * Use the port MSB as valid flag, shift can be made dynamic
+ * by computing number of bits required for port indexes.
+ * Code disabling CCI cpu ports runs with D-cache invalidated
+ * and SCTLR bit clear so data accesses must be kept to a minimum
+ * to improve performance; for now shift is left static to
+ * avoid one more data access while disabling the CCI port.
+ */
+#define PORT_VALID_SHIFT	31
+#define PORT_VALID		(0x1 << PORT_VALID_SHIFT)
+
+static inline void init_cpu_port(struct cpu_port *port, u32 index, u64 mpidr)
+{
+	port->port = PORT_VALID | index;
+	port->mpidr = mpidr;
+}
+
+static inline bool cpu_port_is_valid(struct cpu_port *port)
+{
+	return !!(port->port & PORT_VALID);
+}
+
+static inline bool cpu_port_match(struct cpu_port *port, u64 mpidr)
+{
+	return port->mpidr == (mpidr & MPIDR_HWID_BITMASK);
+}
+
+static struct cpu_port cpu_port[NR_CPUS];
+
+/**
+ * __cci_ace_get_port - Function to retrieve the port index connected to
+ *			a cpu or device.
+ *
+ * @dn: device node of the device to look-up
+ * @type: port type
+ *
+ * Return value:
+ *	- CCI port index if success
+ *	- -ENODEV if failure
+ */
+static int __cci_ace_get_port(struct device_node *dn, int type)
+{
+	int i;
+	bool ace_match;
+	struct device_node *cci_portn;
+
+	cci_portn = of_parse_phandle(dn, "cci-control-port", 0);
+	for (i = 0; i < nb_cci_ports; i++) {
+		ace_match = ports[i].type == type;
+		if (ace_match && cci_portn == ports[i].dn)
+			return i;
+	}
+	return -ENODEV;
+}
+
+int cci_ace_get_port(struct device_node *dn)
+{
+	return __cci_ace_get_port(dn, ACE_LITE_PORT);
+}
+EXPORT_SYMBOL_GPL(cci_ace_get_port);
+
+static void __init cci_ace_init_ports(void)
+{
+	int port, ac, cpu;
+	u64 hwid;
+	const u32 *cell;
+	struct device_node *cpun, *cpus;
+
+	cpus = of_find_node_by_path("/cpus");
+	if (WARN(!cpus, "Missing cpus node, bailing out\n"))
+		return;
+
+	if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
+		ac = of_n_addr_cells(cpus);
+
+	/*
+	 * Port index look-up speeds up the function disabling ports by CPU,
+	 * since the logical to port index mapping is done once and does
+	 * not change after system boot.
+	 * The stashed index array is initialized for all possible CPUs
+	 * at probe time.
+	 */
+	for_each_child_of_node(cpus, cpun) {
+		if (of_node_cmp(cpun->type, "cpu"))
+			continue;
+		cell = of_get_property(cpun, "reg", NULL);
+		if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
+			continue;
+
+		hwid = of_read_number(cell, ac);
+		cpu = get_logical_index(hwid & MPIDR_HWID_BITMASK);
+
+		if (cpu < 0 || !cpu_possible(cpu))
+			continue;
+		port = __cci_ace_get_port(cpun, ACE_PORT);
+		if (port < 0)
+			continue;
+
+		init_cpu_port(&cpu_port[cpu], port, cpu_logical_map(cpu));
+	}
+
+	for_each_possible_cpu(cpu) {
+		WARN(!cpu_port_is_valid(&cpu_port[cpu]),
+			"CPU %u does not have an associated CCI port\n",
+			cpu);
+	}
+}
+/*
+ * Functions to enable/disable a CCI interconnect slave port
+ *
+ * They are called by low-level power management code to disable slave
+ * interfaces snoops and DVM broadcast.
+ * Since they may execute with cache data allocation disabled and
+ * after the caches have been cleaned and invalidated the functions provide
+ * no explicit locking since they may run with D-cache disabled, so normal
+ * cacheable kernel locks based on ldrex/strex may not work.
+ * Locking has to be provided by BSP implementations to ensure proper
+ * operations.
+ */
+
+/**
+ * cci_port_control() - function to control a CCI port
+ *
+ * @port: index of the port to setup
+ * @enable: if true enables the port, if false disables it
+ */
+static void notrace cci_port_control(unsigned int port, bool enable)
+{
+	void __iomem *base = ports[port].base;
+
+	writel_relaxed(enable ? CCI_ENABLE_REQ : 0, base + CCI_PORT_CTRL);
+	/*
+	 * This function is called from power down procedures
+	 * and must not execute any instruction that might
+	 * cause the processor to be put in a quiescent state
+	 * (eg wfi). Hence, cpu_relax() can not be added to this
+	 * read loop to optimize power, since it might hide possibly
+	 * disruptive operations.
+	 */
+	while (readl_relaxed(cci_ctrl_base + CCI_CTRL_STATUS) & 0x1)
+			;
+}
+
+/**
+ * cci_disable_port_by_cpu() - function to disable a CCI port by CPU
+ *			       reference
+ *
+ * @mpidr: mpidr of the CPU whose CCI port should be disabled
+ *
+ * Disabling a CCI port for a CPU implies disabling the CCI port
+ * controlling that CPU cluster. Code disabling CPU CCI ports
+ * must make sure that the CPU running the code is the last active CPU
+ * in the cluster ie all other CPUs are quiescent in a low power state.
+ *
+ * Return:
+ *	0 on success
+ *	-ENODEV on port look-up failure
+ */
+int notrace cci_disable_port_by_cpu(u64 mpidr)
+{
+	int cpu;
+	bool is_valid;
+	for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
+		is_valid = cpu_port_is_valid(&cpu_port[cpu]);
+		if (is_valid && cpu_port_match(&cpu_port[cpu], mpidr)) {
+			cci_port_control(cpu_port[cpu].port, false);
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(cci_disable_port_by_cpu);
+
+/**
+ * cci_enable_port_for_self() - enable a CCI port for calling CPU
+ *
+ * Enabling a CCI port for the calling CPU implies enabling the CCI
+ * port controlling that CPU's cluster. Caller must make sure that the
+ * CPU running the code is the first active CPU in the cluster and all
+ * other CPUs are quiescent in a low power state  or waiting for this CPU
+ * to complete the CCI initialization.
+ *
+ * Because this is called when the MMU is still off and with no stack,
+ * the code must be position independent and ideally rely on callee
+ * clobbered registers only.  To achieve this we must code this function
+ * entirely in assembler.
+ *
+ * On success this returns with the proper CCI port enabled.  In case of
+ * any failure this never returns as the inability to enable the CCI is
+ * fatal and there is no possible recovery at this stage.
+ */
+asmlinkage void __naked cci_enable_port_for_self(void)
+{
+	asm volatile ("\n"
+"	.arch armv7-a\n"
+"	mrc	p15, 0, r0, c0, c0, 5	@ get MPIDR value \n"
+"	and	r0, r0, #"__stringify(MPIDR_HWID_BITMASK)" \n"
+"	adr	r1, 5f \n"
+"	ldr	r2, [r1] \n"
+"	add	r1, r1, r2		@ &cpu_port \n"
+"	add	ip, r1, %[sizeof_cpu_port] \n"
+
+	/* Loop over the cpu_port array looking for a matching MPIDR */
+"1:	ldr	r2, [r1, %[offsetof_cpu_port_mpidr_lsb]] \n"
+"	cmp	r2, r0 			@ compare MPIDR \n"
+"	bne	2f \n"
+
+	/* Found a match, now test port validity */
+"	ldr	r3, [r1, %[offsetof_cpu_port_port]] \n"
+"	tst	r3, #"__stringify(PORT_VALID)" \n"
+"	bne	3f \n"
+
+	/* no match, loop with the next cpu_port entry */
+"2:	add	r1, r1, %[sizeof_struct_cpu_port] \n"
+"	cmp	r1, ip			@ done? \n"
+"	blo	1b \n"
+
+	/* CCI port not found -- cheaply try to stall this CPU */
+"cci_port_not_found: \n"
+"	wfi \n"
+"	wfe \n"
+"	b	cci_port_not_found \n"
+
+	/* Use matched port index to look up the corresponding ports entry */
+"3:	bic	r3, r3, #"__stringify(PORT_VALID)" \n"
+"	adr	r0, 6f \n"
+"	ldmia	r0, {r1, r2} \n"
+"	sub	r1, r1, r0 		@ virt - phys \n"
+"	ldr	r0, [r0, r2] 		@ *(&ports) \n"
+"	mov	r2, %[sizeof_struct_ace_port] \n"
+"	mla	r0, r2, r3, r0		@ &ports[index] \n"
+"	sub	r0, r0, r1		@ virt_to_phys() \n"
+
+	/* Enable the CCI port */
+"	ldr	r0, [r0, %[offsetof_port_phys]] \n"
+"	mov	r3, #"__stringify(CCI_ENABLE_REQ)" \n"
+"	str	r3, [r0, #"__stringify(CCI_PORT_CTRL)"] \n"
+
+	/* poll the status reg for completion */
+"	adr	r1, 7f \n"
+"	ldr	r0, [r1] \n"
+"	ldr	r0, [r0, r1]		@ cci_ctrl_base \n"
+"4:	ldr	r1, [r0, #"__stringify(CCI_CTRL_STATUS)"] \n"
+"	tst	r1, #1 \n"
+"	bne	4b \n"
+
+"	mov	r0, #0 \n"
+"	bx	lr \n"
+
+"	.align	2 \n"
+"5:	.word	cpu_port - . \n"
+"6:	.word	. \n"
+"	.word	ports - 6b \n"
+"7:	.word	cci_ctrl_phys - . \n"
+	: :
+	[sizeof_cpu_port] "i" (sizeof(cpu_port)),
+#ifndef __ARMEB__
+	[offsetof_cpu_port_mpidr_lsb] "i" (offsetof(struct cpu_port, mpidr)),
+#else
+	[offsetof_cpu_port_mpidr_lsb] "i" (offsetof(struct cpu_port, mpidr)+4),
+#endif
+	[offsetof_cpu_port_port] "i" (offsetof(struct cpu_port, port)),
+	[sizeof_struct_cpu_port] "i" (sizeof(struct cpu_port)),
+	[sizeof_struct_ace_port] "i" (sizeof(struct cci_ace_port)),
+	[offsetof_port_phys] "i" (offsetof(struct cci_ace_port, phys)) );
+
+	unreachable();
+}
+
+/**
+ * __cci_control_port_by_device() - function to control a CCI port by device
+ *				    reference
+ *
+ * @dn: device node pointer of the device whose CCI port should be
+ *      controlled
+ * @enable: if true enables the port, if false disables it
+ *
+ * Return:
+ *	0 on success
+ *	-ENODEV on port look-up failure
+ */
+int notrace __cci_control_port_by_device(struct device_node *dn, bool enable)
+{
+	int port;
+
+	if (!dn)
+		return -ENODEV;
+
+	port = __cci_ace_get_port(dn, ACE_LITE_PORT);
+	if (WARN_ONCE(port < 0, "node %s ACE lite port look-up failure\n",
+				dn->full_name))
+		return -ENODEV;
+	cci_port_control(port, enable);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__cci_control_port_by_device);
+
+/**
+ * __cci_control_port_by_index() - function to control a CCI port by port index
+ *
+ * @port: port index previously retrieved with cci_ace_get_port()
+ * @enable: if true enables the port, if false disables it
+ *
+ * Return:
+ *	0 on success
+ *	-ENODEV on port index out of range
+ *	-EPERM if operation carried out on an ACE PORT
+ */
+int notrace __cci_control_port_by_index(u32 port, bool enable)
+{
+	if (port >= nb_cci_ports || ports[port].type == ACE_INVALID_PORT)
+		return -ENODEV;
+	/*
+	 * CCI control for ports connected to CPUS is extremely fragile
+	 * and must be made to go through a specific and controlled
+	 * interface (ie cci_disable_port_by_cpu(); control by general purpose
+	 * indexing is therefore disabled for ACE ports.
+	 */
+	if (ports[port].type == ACE_PORT)
+		return -EPERM;
+
+	cci_port_control(port, enable);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__cci_control_port_by_index);
+
+static const struct cci_nb_ports cci400_ports = {
+	.nb_ace = 2,
+	.nb_ace_lite = 3
+};
+
+static const struct of_device_id arm_cci_matches[] = {
+	{.compatible = "arm,cci-400", .data = &cci400_ports },
+	{},
+};
+
+static const struct of_device_id arm_cci_ctrl_if_matches[] = {
+	{.compatible = "arm,cci-400-ctrl-if", },
+	{},
+};
+
+static int __init cci_probe(void)
+{
+	struct cci_nb_ports const *cci_config;
+	int ret, i, nb_ace = 0, nb_ace_lite = 0;
+	struct device_node *np, *cp;
+	struct resource res;
+	const char *match_str;
+	bool is_ace;
+
+	np = of_find_matching_node(NULL, arm_cci_matches);
+	if (!np)
+		return -ENODEV;
+
+	cci_config = of_match_node(arm_cci_matches, np)->data;
+	if (!cci_config)
+		return -ENODEV;
+
+	nb_cci_ports = cci_config->nb_ace + cci_config->nb_ace_lite;
+
+	ports = kcalloc(sizeof(*ports), nb_cci_ports, GFP_KERNEL);
+	if (!ports)
+		return -ENOMEM;
+
+	ret = of_address_to_resource(np, 0, &res);
+	if (!ret) {
+		cci_ctrl_base = ioremap(res.start, resource_size(&res));
+		cci_ctrl_phys =	res.start;
+	}
+	if (ret || !cci_ctrl_base) {
+		WARN(1, "unable to ioremap CCI ctrl\n");
+		ret = -ENXIO;
+		goto memalloc_err;
+	}
+
+	for_each_child_of_node(np, cp) {
+		if (!of_match_node(arm_cci_ctrl_if_matches, cp))
+			continue;
+
+		i = nb_ace + nb_ace_lite;
+
+		if (i >= nb_cci_ports)
+			break;
+
+		if (of_property_read_string(cp, "interface-type",
+					&match_str)) {
+			WARN(1, "node %s missing interface-type property\n",
+				  cp->full_name);
+			continue;
+		}
+		is_ace = strcmp(match_str, "ace") == 0;
+		if (!is_ace && strcmp(match_str, "ace-lite")) {
+			WARN(1, "node %s containing invalid interface-type property, skipping it\n",
+					cp->full_name);
+			continue;
+		}
+
+		ret = of_address_to_resource(cp, 0, &res);
+		if (!ret) {
+			ports[i].base = ioremap(res.start, resource_size(&res));
+			ports[i].phys = res.start;
+		}
+		if (ret || !ports[i].base) {
+			WARN(1, "unable to ioremap CCI port %d\n", i);
+			continue;
+		}
+
+		if (is_ace) {
+			if (WARN_ON(nb_ace >= cci_config->nb_ace))
+				continue;
+			ports[i].type = ACE_PORT;
+			++nb_ace;
+		} else {
+			if (WARN_ON(nb_ace_lite >= cci_config->nb_ace_lite))
+				continue;
+			ports[i].type = ACE_LITE_PORT;
+			++nb_ace_lite;
+		}
+		ports[i].dn = cp;
+	}
+
+	 /* initialize a stashed array of ACE ports to speed-up look-up */
+	cci_ace_init_ports();
+
+	/*
+	 * Multi-cluster systems may need this data when non-coherent, during
+	 * cluster power-up/power-down. Make sure it reaches main memory.
+	 */
+	sync_cache_w(&cci_ctrl_base);
+	sync_cache_w(&cci_ctrl_phys);
+	sync_cache_w(&ports);
+	sync_cache_w(&cpu_port);
+	__sync_cache_range_w(ports, sizeof(*ports) * nb_cci_ports);
+	pr_info("ARM CCI driver probed\n");
+	return 0;
+
+memalloc_err:
+
+	kfree(ports);
+	return ret;
+}
+
+static int cci_init_status = -EAGAIN;
+static DEFINE_MUTEX(cci_probing);
+
+static int __init cci_init(void)
+{
+	if (cci_init_status != -EAGAIN)
+		return cci_init_status;
+
+	mutex_lock(&cci_probing);
+	if (cci_init_status == -EAGAIN)
+		cci_init_status = cci_probe();
+	mutex_unlock(&cci_probing);
+	return cci_init_status;
+}
+
+/*
+ * To sort out early init calls ordering a helper function is provided to
+ * check if the CCI driver has beed initialized. Function check if the driver
+ * has been initialized, if not it calls the init function that probes
+ * the driver and updates the return value.
+ */
+bool __init cci_probed(void)
+{
+	return cci_init() == 0;
+}
+EXPORT_SYMBOL_GPL(cci_probed);
+
+early_initcall(cci_init);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ARM CCI support");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bus/imx-weim.c linux-libre-3.11-rc7-gnu/drivers/bus/imx-weim.c
--- linux-libre-3.10-gnu/drivers/bus/imx-weim.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/bus/imx-weim.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,138 @@
+/*
+ * EIM driver for Freescale's i.MX chips
+ *
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/of_device.h>
+
+struct imx_weim {
+	void __iomem *base;
+	struct clk *clk;
+};
+
+static const struct of_device_id weim_id_table[] = {
+	{ .compatible = "fsl,imx6q-weim", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, weim_id_table);
+
+#define CS_TIMING_LEN 6
+#define CS_REG_RANGE  0x18
+
+/* Parse and set the timing for this device. */
+static int
+weim_timing_setup(struct platform_device *pdev, struct device_node *np)
+{
+	struct imx_weim *weim = platform_get_drvdata(pdev);
+	u32 value[CS_TIMING_LEN];
+	u32 cs_idx;
+	int ret;
+	int i;
+
+	/* get the CS index from this child node's "reg" property. */
+	ret = of_property_read_u32(np, "reg", &cs_idx);
+	if (ret)
+		return ret;
+
+	/* The weim has four chip selects. */
+	if (cs_idx > 3)
+		return -EINVAL;
+
+	ret = of_property_read_u32_array(np, "fsl,weim-cs-timing",
+					value, CS_TIMING_LEN);
+	if (ret)
+		return ret;
+
+	/* set the timing for WEIM */
+	for (i = 0; i < CS_TIMING_LEN; i++)
+		writel(value[i], weim->base + cs_idx * CS_REG_RANGE + i * 4);
+	return 0;
+}
+
+static int weim_parse_dt(struct platform_device *pdev)
+{
+	struct device_node *child;
+	int ret;
+
+	for_each_child_of_node(pdev->dev.of_node, child) {
+		if (!child->name)
+			continue;
+
+		ret = weim_timing_setup(pdev, child);
+		if (ret) {
+			dev_err(&pdev->dev, "%s set timing failed.\n",
+				child->full_name);
+			return ret;
+		}
+	}
+
+	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+	if (ret)
+		dev_err(&pdev->dev, "%s fail to create devices.\n",
+			pdev->dev.of_node->full_name);
+	return ret;
+}
+
+static int weim_probe(struct platform_device *pdev)
+{
+	struct imx_weim *weim;
+	struct resource *res;
+	int ret = -EINVAL;
+
+	weim = devm_kzalloc(&pdev->dev, sizeof(*weim), GFP_KERNEL);
+	if (!weim) {
+		ret = -ENOMEM;
+		goto weim_err;
+	}
+	platform_set_drvdata(pdev, weim);
+
+	/* get the resource */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	weim->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(weim->base)) {
+		ret = PTR_ERR(weim->base);
+		goto weim_err;
+	}
+
+	/* get the clock */
+	weim->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(weim->clk))
+		goto weim_err;
+
+	ret = clk_prepare_enable(weim->clk);
+	if (ret)
+		goto weim_err;
+
+	/* parse the device node */
+	ret = weim_parse_dt(pdev);
+	if (ret) {
+		clk_disable_unprepare(weim->clk);
+		goto weim_err;
+	}
+
+	dev_info(&pdev->dev, "WEIM driver registered.\n");
+	return 0;
+
+weim_err:
+	return ret;
+}
+
+static struct platform_driver weim_driver = {
+	.driver = {
+		.name = "imx-weim",
+		.of_match_table = weim_id_table,
+	},
+	.probe   = weim_probe,
+};
+
+module_platform_driver(weim_driver);
+MODULE_AUTHOR("Freescale Semiconductor Inc.");
+MODULE_DESCRIPTION("i.MX EIM Controller Driver");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bus/Kconfig linux-libre-3.11-rc7-gnu/drivers/bus/Kconfig
--- linux-libre-3.10-gnu/drivers/bus/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bus/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -4,6 +4,15 @@
 
 menu "Bus devices"
 
+config IMX_WEIM
+	bool "Freescale EIM DRIVER"
+	depends on ARCH_MXC
+	help
+	  Driver for i.MX6 WEIM controller.
+	  The WEIM(Wireless External Interface Module) works like a bus.
+	  You can attach many different devices on it, such as NOR, onenand.
+	  But now, we only support the Parallel NOR.
+
 config MVEBU_MBUS
 	bool
 	depends on PLAT_ORION
@@ -26,4 +35,11 @@ config OMAP_INTERCONNECT
 
 	help
 	  Driver to enable OMAP interconnect error handling driver.
+
+config ARM_CCI
+	bool "ARM CCI driver support"
+	depends on ARM
+	help
+	  Driver supporting the CCI cache coherent interconnect for ARM
+	  platforms.
 endmenu
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bus/Makefile linux-libre-3.11-rc7-gnu/drivers/bus/Makefile
--- linux-libre-3.10-gnu/drivers/bus/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bus/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -2,8 +2,11 @@
 # Makefile for the bus drivers.
 #
 
+obj-$(CONFIG_IMX_WEIM)	+= imx-weim.o
 obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
 obj-$(CONFIG_OMAP_OCP2SCP)	+= omap-ocp2scp.o
 
 # Interconnect bus driver for OMAP SoCs.
 obj-$(CONFIG_OMAP_INTERCONNECT)	+= omap_l3_smx.o omap_l3_noc.o
+# CCI cache coherent interconnect for ARM platforms
+obj-$(CONFIG_ARM_CCI)		+= arm-cci.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bus/mvebu-mbus.c linux-libre-3.11-rc7-gnu/drivers/bus/mvebu-mbus.c
--- linux-libre-3.10-gnu/drivers/bus/mvebu-mbus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bus/mvebu-mbus.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,6 +49,8 @@
  *   configuration (file 'devices').
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -762,7 +764,7 @@ int mvebu_mbus_add_window_remap_flags(co
 			break;
 
 	if (!s->soc->map[i].name) {
-		pr_err("mvebu-mbus: unknown device '%s'\n", devname);
+		pr_err("unknown device '%s'\n", devname);
 		return -ENODEV;
 	}
 
@@ -775,7 +777,7 @@ int mvebu_mbus_add_window_remap_flags(co
 		attr |= 0x28;
 
 	if (!mvebu_mbus_window_conflicts(s, base, size, target, attr)) {
-		pr_err("mvebu-mbus: cannot add window '%s', conflicts with another window\n",
+		pr_err("cannot add window '%s', conflicts with another window\n",
 		       devname);
 		return -EINVAL;
 	}
@@ -842,7 +844,7 @@ int __init mvebu_mbus_init(const char *s
 			break;
 
 	if (!of_id->compatible) {
-		pr_err("mvebu-mbus: could not find a matching SoC family\n");
+		pr_err("could not find a matching SoC family\n");
 		return -ENODEV;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/bus/omap-ocp2scp.c linux-libre-3.11-rc7-gnu/drivers/bus/omap-ocp2scp.c
--- linux-libre-3.10-gnu/drivers/bus/omap-ocp2scp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/bus/omap-ocp2scp.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,26 +22,6 @@
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
-#include <linux/platform_data/omap_ocp2scp.h>
-
-/**
- * _count_resources - count for the number of resources
- * @res: struct resource *
- *
- * Count and return the number of resources populated for the device that is
- * connected to ocp2scp.
- */
-static unsigned _count_resources(struct resource *res)
-{
-	int cnt	= 0;
-
-	while (res->start != res->end) {
-		cnt++;
-		res++;
-	}
-
-	return cnt;
-}
 
 static int ocp2scp_remove_devices(struct device *dev, void *c)
 {
@@ -55,11 +35,7 @@ static int ocp2scp_remove_devices(struct
 static int omap_ocp2scp_probe(struct platform_device *pdev)
 {
 	int ret;
-	unsigned res_cnt, i;
 	struct device_node *np = pdev->dev.of_node;
-	struct platform_device *pdev_child;
-	struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data;
-	struct omap_ocp2scp_dev *dev;
 
 	if (np) {
 		ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
@@ -68,48 +44,12 @@ static int omap_ocp2scp_probe(struct pla
 			    "failed to add resources for ocp2scp child\n");
 			goto err0;
 		}
-	} else if (pdata) {
-		for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++,
-		    dev++) {
-			res_cnt = _count_resources(dev->res);
-
-			pdev_child = platform_device_alloc(dev->drv_name,
-			    PLATFORM_DEVID_AUTO);
-			if (!pdev_child) {
-				dev_err(&pdev->dev,
-				  "failed to allocate mem for ocp2scp child\n");
-				goto err0;
-			}
-
-			ret = platform_device_add_resources(pdev_child,
-			    dev->res, res_cnt);
-			if (ret) {
-				dev_err(&pdev->dev,
-				 "failed to add resources for ocp2scp child\n");
-				goto err1;
-			}
-
-			pdev_child->dev.parent	= &pdev->dev;
-
-			ret = platform_device_add(pdev_child);
-			if (ret) {
-				dev_err(&pdev->dev,
-				   "failed to register ocp2scp child device\n");
-				goto err1;
-			}
-		}
-	} else {
-		dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n");
-		return -EINVAL;
 	}
 
 	pm_runtime_enable(&pdev->dev);
 
 	return 0;
 
-err1:
-	platform_device_put(pdev_child);
-
 err0:
 	device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cdrom/cdrom.c linux-libre-3.11-rc7-gnu/drivers/cdrom/cdrom.c
--- linux-libre-3.10-gnu/drivers/cdrom/cdrom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cdrom/cdrom.c	2013-08-25 20:43:22.000000000 -0400
@@ -2882,7 +2882,7 @@ static noinline int mmc_ioctl_cdrom_read
 	if (lba < 0)
 		return -EINVAL;
 
-	cgc->buffer = kmalloc(blocksize, GFP_KERNEL);
+	cgc->buffer = kzalloc(blocksize, GFP_KERNEL);
 	if (cgc->buffer == NULL)
 		return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cdrom/gdrom.c linux-libre-3.11-rc7-gnu/drivers/cdrom/gdrom.c
--- linux-libre-3.10-gnu/drivers/cdrom/gdrom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cdrom/gdrom.c	2013-08-25 20:43:22.000000000 -0400
@@ -830,9 +830,9 @@ probe_fail_cdrom_register:
 	del_gendisk(gd.disk);
 probe_fail_no_disk:
 	kfree(gd.cd_info);
+probe_fail_no_mem:
 	unregister_blkdev(gdrom_major, GDROM_DEV_NAME);
 	gdrom_major = 0;
-probe_fail_no_mem:
 	pr_warning("Probe failed - error is 0x%X\n", err);
 	return err;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/agp/alpha-agp.c linux-libre-3.11-rc7-gnu/drivers/char/agp/alpha-agp.c
--- linux-libre-3.10-gnu/drivers/char/agp/alpha-agp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/agp/alpha-agp.c	2013-08-25 20:43:22.000000000 -0400
@@ -174,7 +174,7 @@ alpha_core_agp_setup(void)
 	/*
 	 * Build a fake pci_dev struct
 	 */
-	pdev = alloc_pci_dev();
+	pdev = pci_alloc_dev(NULL);
 	if (!pdev)
 		return -ENOMEM;
 	pdev->vendor = 0xffff;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/agp/ati-agp.c linux-libre-3.11-rc7-gnu/drivers/char/agp/ati-agp.c
--- linux-libre-3.10-gnu/drivers/char/agp/ati-agp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/agp/ati-agp.c	2013-08-25 20:43:22.000000000 -0400
@@ -236,14 +236,14 @@ static int ati_configure(void)
 static int agp_ati_suspend(struct pci_dev *dev, pm_message_t state)
 {
 	pci_save_state(dev);
-	pci_set_power_state(dev, 3);
+	pci_set_power_state(dev, PCI_D3hot);
 
 	return 0;
 }
 
 static int agp_ati_resume(struct pci_dev *dev)
 {
-	pci_set_power_state(dev, 0);
+	pci_set_power_state(dev, PCI_D0);
 	pci_restore_state(dev);
 
 	return ati_configure();
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/agp/frontend.c linux-libre-3.11-rc7-gnu/drivers/char/agp/frontend.c
--- linux-libre-3.10-gnu/drivers/char/agp/frontend.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/agp/frontend.c	2013-08-25 20:43:22.000000000 -0400
@@ -603,7 +603,8 @@ static int agp_mmap(struct file *file, s
 			vma->vm_ops = kerninfo.vm_ops;
 		} else if (io_remap_pfn_range(vma, vma->vm_start,
 				(kerninfo.aper_base + offset) >> PAGE_SHIFT,
-					    size, vma->vm_page_prot)) {
+				size,
+				pgprot_writecombine(vma->vm_page_prot))) {
 			goto out_again;
 		}
 		mutex_unlock(&(agp_fe.agp_mutex));
@@ -618,8 +619,9 @@ static int agp_mmap(struct file *file, s
 		if (kerninfo.vm_ops) {
 			vma->vm_ops = kerninfo.vm_ops;
 		} else if (io_remap_pfn_range(vma, vma->vm_start,
-					    kerninfo.aper_base >> PAGE_SHIFT,
-					    size, vma->vm_page_prot)) {
+				kerninfo.aper_base >> PAGE_SHIFT,
+				size,
+				pgprot_writecombine(vma->vm_page_prot))) {
 			goto out_again;
 		}
 		mutex_unlock(&(agp_fe.agp_mutex));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/agp/nvidia-agp.c linux-libre-3.11-rc7-gnu/drivers/char/agp/nvidia-agp.c
--- linux-libre-3.10-gnu/drivers/char/agp/nvidia-agp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/agp/nvidia-agp.c	2013-08-25 20:43:22.000000000 -0400
@@ -399,8 +399,8 @@ static void agp_nvidia_remove(struct pci
 #ifdef CONFIG_PM
 static int agp_nvidia_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	pci_save_state (pdev);
-	pci_set_power_state (pdev, 3);
+	pci_save_state(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
 
 	return 0;
 }
@@ -408,7 +408,7 @@ static int agp_nvidia_suspend(struct pci
 static int agp_nvidia_resume(struct pci_dev *pdev)
 {
 	/* set power state 0 and restore PCI space */
-	pci_set_power_state (pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
 	/* reconfigure AGP hardware again */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/agp/parisc-agp.c linux-libre-3.11-rc7-gnu/drivers/char/agp/parisc-agp.c
--- linux-libre-3.10-gnu/drivers/char/agp/parisc-agp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/agp/parisc-agp.c	2013-08-25 20:43:22.000000000 -0400
@@ -129,7 +129,8 @@ parisc_agp_insert_memory(struct agp_memo
 	off_t j, io_pg_start;
 	int io_pg_count;
 
-	if (type != 0 || mem->type != 0) {
+	if (type != mem->type ||
+		agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
 		return -EINVAL;
 	}
 
@@ -175,7 +176,8 @@ parisc_agp_remove_memory(struct agp_memo
 	struct _parisc_agp_info *info = &parisc_agp_info;
 	int i, io_pg_start, io_pg_count;
 
-	if (type != 0 || mem->type != 0) {
+	if (type != mem->type ||
+		agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) {
 		return -EINVAL;
 	}
 
@@ -333,7 +335,7 @@ parisc_agp_setup(void __iomem *ioc_hpa,
 	struct agp_bridge_data *bridge;
 	int error = 0;
 
-	fake_bridge_dev = alloc_pci_dev();
+	fake_bridge_dev = pci_alloc_dev(NULL);
 	if (!fake_bridge_dev) {
 		error = -ENOMEM;
 		goto fail;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hpet.c linux-libre-3.11-rc7-gnu/drivers/char/hpet.c
--- linux-libre-3.10-gnu/drivers/char/hpet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hpet.c	2013-08-25 20:43:22.000000000 -0400
@@ -725,7 +725,7 @@ static int hpet_is_known(struct hpet_dat
 	return 0;
 }
 
-static ctl_table hpet_table[] = {
+static struct ctl_table hpet_table[] = {
 	{
 	 .procname = "max-user-freq",
 	 .data = &hpet_max_freq,
@@ -736,7 +736,7 @@ static ctl_table hpet_table[] = {
 	{}
 };
 
-static ctl_table hpet_root[] = {
+static struct ctl_table hpet_root[] = {
 	{
 	 .procname = "hpet",
 	 .maxlen = 0,
@@ -746,7 +746,7 @@ static ctl_table hpet_root[] = {
 	{}
 };
 
-static ctl_table dev_root[] = {
+static struct ctl_table dev_root[] = {
 	{
 	 .procname = "dev",
 	 .maxlen = 0,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/atmel-rng.c linux-libre-3.11-rc7-gnu/drivers/char/hw_random/atmel-rng.c
--- linux-libre-3.10-gnu/drivers/char/hw_random/atmel-rng.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/atmel-rng.c	2013-08-25 20:43:22.000000000 -0400
@@ -108,8 +108,6 @@ static int atmel_trng_remove(struct plat
 	clk_disable(trng->clk);
 	clk_put(trng->clk);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/bcm2835-rng.c linux-libre-3.11-rc7-gnu/drivers/char/hw_random/bcm2835-rng.c
--- linux-libre-3.10-gnu/drivers/char/hw_random/bcm2835-rng.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/bcm2835-rng.c	2013-08-25 20:43:22.000000000 -0400
@@ -110,4 +110,4 @@ module_platform_driver(bcm2835_rng_drive
 
 MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
 MODULE_DESCRIPTION("BCM2835 Random Number Generator (RNG) driver");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/bcm63xx-rng.c linux-libre-3.11-rc7-gnu/drivers/char/hw_random/bcm63xx-rng.c
--- linux-libre-3.10-gnu/drivers/char/hw_random/bcm63xx-rng.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/bcm63xx-rng.c	2013-08-25 20:43:22.000000000 -0400
@@ -137,7 +137,6 @@ static int bcm63xx_rng_probe(struct plat
 out_clk_disable:
 	clk_disable(clk);
 out_free_rng:
-	platform_set_drvdata(pdev, NULL);
 	kfree(rng);
 out_free_priv:
 	kfree(priv);
@@ -154,7 +153,6 @@ static int bcm63xx_rng_remove(struct pla
 	clk_disable(priv->clk);
 	kfree(priv);
 	kfree(rng);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/Kconfig linux-libre-3.11-rc7-gnu/drivers/char/hw_random/Kconfig
--- linux-libre-3.10-gnu/drivers/char/hw_random/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -167,7 +167,7 @@ config HW_RANDOM_OMAP
 
 config HW_RANDOM_OCTEON
 	tristate "Octeon Random Number Generator support"
-	depends on HW_RANDOM && CPU_CAVIUM_OCTEON
+	depends on HW_RANDOM && CAVIUM_OCTEON_SOC
 	default HW_RANDOM
 	---help---
 	  This driver provides kernel-side support for the Random Number
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/n2-drv.c linux-libre-3.11-rc7-gnu/drivers/char/hw_random/n2-drv.c
--- linux-libre-3.10-gnu/drivers/char/hw_random/n2-drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/n2-drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -700,7 +700,7 @@ static int n2rng_probe(struct platform_d
 	if (err)
 		goto out_free_units;
 
-	dev_set_drvdata(&op->dev, np);
+	platform_set_drvdata(op, np);
 
 	schedule_delayed_work(&np->work, 0);
 
@@ -721,7 +721,7 @@ out:
 
 static int n2rng_remove(struct platform_device *op)
 {
-	struct n2rng *np = dev_get_drvdata(&op->dev);
+	struct n2rng *np = platform_get_drvdata(op);
 
 	np->flags |= N2RNG_FLAG_SHUTDOWN;
 
@@ -736,8 +736,6 @@ static int n2rng_remove(struct platform_
 
 	kfree(np);
 
-	dev_set_drvdata(&op->dev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/nomadik-rng.c linux-libre-3.11-rc7-gnu/drivers/char/hw_random/nomadik-rng.c
--- linux-libre-3.10-gnu/drivers/char/hw_random/nomadik-rng.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/nomadik-rng.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,7 +51,7 @@ static int nmk_rng_probe(struct amba_dev
 		return ret;
 	}
 
-	clk_enable(rng_clk);
+	clk_prepare_enable(rng_clk);
 
 	ret = amba_request_regions(dev, dev->dev.init_name);
 	if (ret)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/octeon-rng.c linux-libre-3.11-rc7-gnu/drivers/char/hw_random/octeon-rng.c
--- linux-libre-3.10-gnu/drivers/char/hw_random/octeon-rng.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/octeon-rng.c	2013-08-25 20:43:22.000000000 -0400
@@ -96,7 +96,7 @@ static int octeon_rng_probe(struct platf
 
 	rng->ops = ops;
 
-	dev_set_drvdata(&pdev->dev, &rng->ops);
+	platform_set_drvdata(pdev, &rng->ops);
 	ret = hwrng_register(&rng->ops);
 	if (ret)
 		return -ENOENT;
@@ -108,7 +108,7 @@ static int octeon_rng_probe(struct platf
 
 static int __exit octeon_rng_remove(struct platform_device *pdev)
 {
-	struct hwrng *rng = dev_get_drvdata(&pdev->dev);
+	struct hwrng *rng = platform_get_drvdata(pdev);
 
 	hwrng_unregister(rng);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/omap-rng.c linux-libre-3.11-rc7-gnu/drivers/char/hw_random/omap-rng.c
--- linux-libre-3.10-gnu/drivers/char/hw_random/omap-rng.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/omap-rng.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,7 +116,7 @@ static int omap_rng_probe(struct platfor
 	};
 
 	omap_rng_ops.priv = (unsigned long)priv;
-	dev_set_drvdata(&pdev->dev, priv);
+	platform_set_drvdata(pdev, priv);
 
 	priv->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	priv->base = devm_ioremap_resource(&pdev->dev, priv->mem_res);
@@ -124,7 +124,7 @@ static int omap_rng_probe(struct platfor
 		ret = PTR_ERR(priv->base);
 		goto err_ioremap;
 	}
-	dev_set_drvdata(&pdev->dev, priv);
+	platform_set_drvdata(pdev, priv);
 
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
@@ -151,7 +151,7 @@ err_ioremap:
 
 static int __exit omap_rng_remove(struct platform_device *pdev)
 {
-	struct omap_rng_private_data *priv = dev_get_drvdata(&pdev->dev);
+	struct omap_rng_private_data *priv = platform_get_drvdata(pdev);
 
 	hwrng_unregister(&omap_rng_ops);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/timeriomem-rng.c linux-libre-3.11-rc7-gnu/drivers/char/hw_random/timeriomem-rng.c
--- linux-libre-3.10-gnu/drivers/char/hw_random/timeriomem-rng.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/timeriomem-rng.c	2013-08-25 20:43:22.000000000 -0400
@@ -192,7 +192,6 @@ out_release_io:
 out_timer:
 	del_timer_sync(&priv->timer);
 out_free:
-	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
 	return err;
 }
@@ -209,7 +208,6 @@ static int timeriomem_rng_remove(struct
 	del_timer_sync(&priv->timer);
 	iounmap(priv->io_base);
 	release_mem_region(res->start, resource_size(res));
-	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/hw_random/tx4939-rng.c linux-libre-3.11-rc7-gnu/drivers/char/hw_random/tx4939-rng.c
--- linux-libre-3.10-gnu/drivers/char/hw_random/tx4939-rng.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/hw_random/tx4939-rng.c	2013-08-25 20:43:22.000000000 -0400
@@ -154,7 +154,6 @@ static int __exit tx4939_rng_remove(stru
 	struct tx4939_rng *rngdev = platform_get_drvdata(dev);
 
 	hwrng_unregister(&rngdev->rng);
-	platform_set_drvdata(dev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/ipmi/ipmi_poweroff.c linux-libre-3.11-rc7-gnu/drivers/char/ipmi/ipmi_poweroff.c
--- linux-libre-3.10-gnu/drivers/char/ipmi/ipmi_poweroff.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/ipmi/ipmi_poweroff.c	2013-08-25 20:43:22.000000000 -0400
@@ -659,7 +659,7 @@ static struct ipmi_smi_watcher smi_watch
 #ifdef CONFIG_PROC_FS
 #include <linux/sysctl.h>
 
-static ctl_table ipmi_table[] = {
+static struct ctl_table ipmi_table[] = {
 	{ .procname	= "poweroff_powercycle",
 	  .data		= &poweroff_powercycle,
 	  .maxlen	= sizeof(poweroff_powercycle),
@@ -668,14 +668,14 @@ static ctl_table ipmi_table[] = {
 	{ }
 };
 
-static ctl_table ipmi_dir_table[] = {
+static struct ctl_table ipmi_dir_table[] = {
 	{ .procname	= "ipmi",
 	  .mode		= 0555,
 	  .child	= ipmi_table },
 	{ }
 };
 
-static ctl_table ipmi_root_table[] = {
+static struct ctl_table ipmi_root_table[] = {
 	{ .procname	= "dev",
 	  .mode		= 0555,
 	  .child	= ipmi_dir_table },
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/Kconfig linux-libre-3.11-rc7-gnu/drivers/char/Kconfig
--- linux-libre-3.10-gnu/drivers/char/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -15,18 +15,6 @@ config DEVKMEM
 	  kind of kernel debugging operations.
 	  When in doubt, say "N".
 
-config STALDRV
-	bool "Stallion multiport serial support"
-	depends on SERIAL_NONSTANDARD
-	help
-	  Stallion cards give you many serial ports.  You would need something
-	  like this to connect more than two modems to your Linux box, for
-	  instance in order to become a dial-in server.  If you say Y here,
-	  you will be asked for your specific card model in the next
-	  questions.  Make sure to read <file:Documentation/serial/stallion.txt>
-	  in this case.  If you have never heard about all this, it's safe to
-	  say N.
-
 config SGI_SNSC
 	bool "SGI Altix system controller communication support"
 	depends on (IA64_SGI_SN2 || IA64_GENERIC)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/mem.c linux-libre-3.11-rc7-gnu/drivers/char/mem.c
--- linux-libre-3.10-gnu/drivers/char/mem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/mem.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/ptrace.h>
 #include <linux/device.h>
 #include <linux/highmem.h>
-#include <linux/crash_dump.h>
 #include <linux/backing-dev.h>
 #include <linux/bootmem.h>
 #include <linux/splice.h>
@@ -357,40 +356,6 @@ static int mmap_kmem(struct file *file,
 }
 #endif
 
-#ifdef CONFIG_CRASH_DUMP
-/*
- * Read memory corresponding to the old kernel.
- */
-static ssize_t read_oldmem(struct file *file, char __user *buf,
-				size_t count, loff_t *ppos)
-{
-	unsigned long pfn, offset;
-	size_t read = 0, csize;
-	int rc = 0;
-
-	while (count) {
-		pfn = *ppos / PAGE_SIZE;
-		if (pfn > saved_max_pfn)
-			return read;
-
-		offset = (unsigned long)(*ppos % PAGE_SIZE);
-		if (count > PAGE_SIZE - offset)
-			csize = PAGE_SIZE - offset;
-		else
-			csize = count;
-
-		rc = copy_oldmem_page(pfn, buf, csize, offset, 1);
-		if (rc < 0)
-			return rc;
-		buf += csize;
-		*ppos += csize;
-		read += csize;
-		count -= csize;
-	}
-	return read;
-}
-#endif
-
 #ifdef CONFIG_DEVKMEM
 /*
  * This function reads the *virtual* memory as seen by the kernel.
@@ -745,7 +710,7 @@ static loff_t memory_lseek(struct file *
 		offset += file->f_pos;
 	case SEEK_SET:
 		/* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */
-		if ((unsigned long long)offset >= ~0xFFFULL) {
+		if (IS_ERR_VALUE((unsigned long long)offset)) {
 			ret = -EOVERFLOW;
 			break;
 		}
@@ -772,7 +737,6 @@ static int open_port(struct inode *inode
 #define aio_write_zero	aio_write_null
 #define open_mem	open_port
 #define open_kmem	open_mem
-#define open_oldmem	open_mem
 
 static const struct file_operations mem_fops = {
 	.llseek		= memory_lseek,
@@ -837,14 +801,6 @@ static const struct file_operations full
 	.write		= write_full,
 };
 
-#ifdef CONFIG_CRASH_DUMP
-static const struct file_operations oldmem_fops = {
-	.read	= read_oldmem,
-	.open	= open_oldmem,
-	.llseek = default_llseek,
-};
-#endif
-
 static const struct memdev {
 	const char *name;
 	umode_t mode;
@@ -866,9 +822,6 @@ static const struct memdev {
 #ifdef CONFIG_PRINTK
 	[11] = { "kmsg", 0644, &kmsg_fops, NULL },
 #endif
-#ifdef CONFIG_CRASH_DUMP
-	[12] = { "oldmem", 0, &oldmem_fops, NULL },
-#endif
 };
 
 static int memory_open(struct inode *inode, struct file *filp)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/mspec.c linux-libre-3.11-rc7-gnu/drivers/char/mspec.c
--- linux-libre-3.10-gnu/drivers/char/mspec.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/mspec.c	2013-08-25 20:43:22.000000000 -0400
@@ -267,7 +267,7 @@ mspec_mmap(struct file *file, struct vm_
 	if ((vma->vm_flags & VM_WRITE) == 0)
 		return -EPERM;
 
-	pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+	pages = vma_pages(vma);
 	vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
 	if (vdata_size <= PAGE_SIZE)
 		vdata = kzalloc(vdata_size, GFP_KERNEL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/mwave/tp3780i.c linux-libre-3.11-rc7-gnu/drivers/char/mwave/tp3780i.c
--- linux-libre-3.10-gnu/drivers/char/mwave/tp3780i.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/mwave/tp3780i.c	2013-08-25 20:43:22.000000000 -0400
@@ -479,6 +479,7 @@ int tp3780I_QueryAbilities(THINKPAD_BD_D
 	PRINTK_2(TRACE_TP3780I,
 		"tp3780i::tp3780I_QueryAbilities entry pBDData %p\n", pBDData);
 
+	memset(pAbilities, 0, sizeof(*pAbilities));
 	/* fill out standard constant fields */
 	pAbilities->instr_per_sec = pBDData->rDspSettings.uIps;
 	pAbilities->data_size = pBDData->rDspSettings.uDStoreSize;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/pcmcia/Kconfig linux-libre-3.11-rc7-gnu/drivers/char/pcmcia/Kconfig
--- linux-libre-3.10-gnu/drivers/char/pcmcia/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/pcmcia/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
 #
 
 menu "PCMCIA character devices"
-	depends on HOTPLUG && PCMCIA!=n
+	depends on PCMCIA!=n
 
 config SYNCLINK_CS
 	tristate "SyncLink PC Card support"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/ps3flash.c linux-libre-3.11-rc7-gnu/drivers/char/ps3flash.c
--- linux-libre-3.10-gnu/drivers/char/ps3flash.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/ps3flash.c	2013-08-25 20:43:22.000000000 -0400
@@ -98,32 +98,8 @@ static int ps3flash_fetch(struct ps3_sto
 static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
 {
 	struct ps3_storage_device *dev = ps3flash_dev;
-	loff_t res;
-
-	mutex_lock(&file->f_mapping->host->i_mutex);
-	switch (origin) {
-	case 0:
-		break;
-	case 1:
-		offset += file->f_pos;
-		break;
-	case 2:
-		offset += dev->regions[dev->region_idx].size*dev->blk_size;
-		break;
-	default:
-		offset = -1;
-	}
-	if (offset < 0) {
-		res = -EINVAL;
-		goto out;
-	}
-
-	file->f_pos = offset;
-	res = file->f_pos;
-
-out:
-	mutex_unlock(&file->f_mapping->host->i_mutex);
-	return res;
+	return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
+			dev->regions[dev->region_idx].size*dev->blk_size);
 }
 
 static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/random.c linux-libre-3.11-rc7-gnu/drivers/char/random.c
--- linux-libre-3.10-gnu/drivers/char/random.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/random.c	2013-08-25 20:43:22.000000000 -0400
@@ -1381,10 +1381,10 @@ static char sysctl_bootid[16];
  * as an ASCII string in the standard UUID format.  If accesses via the
  * sysctl system call, it is returned as 16 bytes of binary data.
  */
-static int proc_do_uuid(ctl_table *table, int write,
+static int proc_do_uuid(struct ctl_table *table, int write,
 			void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-	ctl_table fake_table;
+	struct ctl_table fake_table;
 	unsigned char buf[64], tmp_uuid[16], *uuid;
 
 	uuid = table->data;
@@ -1409,8 +1409,8 @@ static int proc_do_uuid(ctl_table *table
 }
 
 static int sysctl_poolsize = INPUT_POOL_WORDS * 32;
-extern ctl_table random_table[];
-ctl_table random_table[] = {
+extern struct ctl_table random_table[];
+struct ctl_table random_table[] = {
 	{
 		.procname	= "poolsize",
 		.data		= &sysctl_poolsize,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/rtc.c linux-libre-3.11-rc7-gnu/drivers/char/rtc.c
--- linux-libre-3.10-gnu/drivers/char/rtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/rtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -280,7 +280,7 @@ static irqreturn_t rtc_interrupt(int irq
 /*
  * sysctl-tuning infrastructure.
  */
-static ctl_table rtc_table[] = {
+static struct ctl_table rtc_table[] = {
 	{
 		.procname	= "max-user-freq",
 		.data		= &rtc_max_user_freq,
@@ -291,7 +291,7 @@ static ctl_table rtc_table[] = {
 	{ }
 };
 
-static ctl_table rtc_root[] = {
+static struct ctl_table rtc_root[] = {
 	{
 		.procname	= "rtc",
 		.mode		= 0555,
@@ -300,7 +300,7 @@ static ctl_table rtc_root[] = {
 	{ }
 };
 
-static ctl_table dev_root[] = {
+static struct ctl_table dev_root[] = {
 	{
 		.procname	= "dev",
 		.mode		= 0555,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/tile-srom.c linux-libre-3.11-rc7-gnu/drivers/char/tile-srom.c
--- linux-libre-3.10-gnu/drivers/char/tile-srom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/tile-srom.c	2013-08-25 20:43:22.000000000 -0400
@@ -273,32 +273,10 @@ static ssize_t srom_write(struct file *f
 }
 
 /* Provide our own implementation so we can use srom->total_size. */
-loff_t srom_llseek(struct file *filp, loff_t offset, int origin)
+loff_t srom_llseek(struct file *file, loff_t offset, int origin)
 {
-	struct srom_dev *srom = filp->private_data;
-
-	if (mutex_lock_interruptible(&srom->lock))
-		return -ERESTARTSYS;
-
-	switch (origin) {
-	case SEEK_END:
-		offset += srom->total_size;
-		break;
-	case SEEK_CUR:
-		offset += filp->f_pos;
-		break;
-	}
-
-	if (offset < 0 || offset > srom->total_size) {
-		offset = -EINVAL;
-	} else {
-		filp->f_pos = offset;
-		filp->f_version = 0;
-	}
-
-	mutex_unlock(&srom->lock);
-
-	return offset;
+	struct srom_dev *srom = file->private_data;
+	return fixed_size_llseek(file, offset, origin, srom->total_size);
 }
 
 static ssize_t total_show(struct device *dev,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/tpm/tpm.c linux-libre-3.11-rc7-gnu/drivers/char/tpm/tpm.c
--- linux-libre-3.10-gnu/drivers/char/tpm/tpm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/tpm/tpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -1472,7 +1472,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_vendor_release
  * Once all references to platform device are down to 0,
  * release all allocated structures.
  */
-static void tpm_dev_release(struct device *dev)
+void tpm_dev_release(struct device *dev)
 {
 	struct tpm_chip *chip = dev_get_drvdata(dev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/tpm/tpm.h linux-libre-3.11-rc7-gnu/drivers/char/tpm/tpm.h
--- linux-libre-3.10-gnu/drivers/char/tpm/tpm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/tpm/tpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -272,7 +272,6 @@ typedef union {
 	struct	tpm_output_header out;
 } tpm_cmd_header;
 
-#define TPM_DIGEST_SIZE 20
 struct tpm_pcrread_out {
 	u8	pcr_result[TPM_DIGEST_SIZE];
 } __packed;
@@ -333,6 +332,7 @@ extern struct tpm_chip* tpm_register_har
 				 const struct tpm_vendor_specific *);
 extern int tpm_open(struct inode *, struct file *);
 extern int tpm_release(struct inode *, struct file *);
+extern void tpm_dev_release(struct device *dev);
 extern void tpm_dev_vendor_release(struct tpm_chip *);
 extern ssize_t tpm_write(struct file *, const char __user *, size_t,
 			 loff_t *);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/tpm/tpm_i2c_infineon.c linux-libre-3.11-rc7-gnu/drivers/char/tpm/tpm_i2c_infineon.c
--- linux-libre-3.10-gnu/drivers/char/tpm/tpm_i2c_infineon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/tpm/tpm_i2c_infineon.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/wait.h>
 #include "tpm.h"
 
@@ -74,7 +73,6 @@ struct tpm_inf_dev {
 };
 
 static struct tpm_inf_dev tpm_dev;
-static struct i2c_driver tpm_tis_i2c_driver;
 
 /*
  * iic_tpm_read() - read from TPM register
@@ -744,11 +742,9 @@ static int tpm_tis_i2c_probe(struct i2c_
 		return -ENODEV;
 	}
 
-	client->driver = &tpm_tis_i2c_driver;
 	tpm_dev.client = client;
 	rc = tpm_tis_i2c_init(&client->dev);
 	if (rc != 0) {
-		client->driver = NULL;
 		tpm_dev.client = NULL;
 		rc = -ENODEV;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/tpm/tpm_tis.c linux-libre-3.11-rc7-gnu/drivers/char/tpm/tpm_tis.c
--- linux-libre-3.10-gnu/drivers/char/tpm/tpm_tis.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/tpm/tpm_tis.c	2013-08-25 20:43:22.000000000 -0400
@@ -884,12 +884,19 @@ static int __init init_tis(void)
 	rc = platform_driver_register(&tis_drv);
 	if (rc < 0)
 		return rc;
-	if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
-		return PTR_ERR(pdev);
-	if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
-		platform_device_unregister(pdev);
-		platform_driver_unregister(&tis_drv);
+	pdev = platform_device_register_simple("tpm_tis", -1, NULL, 0);
+	if (IS_ERR(pdev)) {
+		rc = PTR_ERR(pdev);
+		goto err_dev;
 	}
+	rc = tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0);
+	if (rc)
+		goto err_init;
+	return 0;
+err_init:
+	platform_device_unregister(pdev);
+err_dev:
+	platform_driver_unregister(&tis_drv);
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/virtio_console.c linux-libre-3.11-rc7-gnu/drivers/char/virtio_console.c
--- linux-libre-3.10-gnu/drivers/char/virtio_console.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/virtio_console.c	2013-08-25 20:43:22.000000000 -0400
@@ -272,9 +272,12 @@ static struct port *find_port_by_devt_in
 	unsigned long flags;
 
 	spin_lock_irqsave(&portdev->ports_lock, flags);
-	list_for_each_entry(port, &portdev->ports, list)
-		if (port->cdev->dev == dev)
+	list_for_each_entry(port, &portdev->ports, list) {
+		if (port->cdev->dev == dev) {
+			kref_get(&port->kref);
 			goto out;
+		}
+	}
 	port = NULL;
 out:
 	spin_unlock_irqrestore(&portdev->ports_lock, flags);
@@ -746,6 +749,10 @@ static ssize_t port_fops_read(struct fil
 
 	port = filp->private_data;
 
+	/* Port is hot-unplugged. */
+	if (!port->guest_connected)
+		return -ENODEV;
+
 	if (!port_has_data(port)) {
 		/*
 		 * If nothing's connected on the host just return 0 in
@@ -762,7 +769,7 @@ static ssize_t port_fops_read(struct fil
 		if (ret < 0)
 			return ret;
 	}
-	/* Port got hot-unplugged. */
+	/* Port got hot-unplugged while we were waiting above. */
 	if (!port->guest_connected)
 		return -ENODEV;
 	/*
@@ -932,13 +939,25 @@ static ssize_t port_fops_splice_write(st
 	if (is_rproc_serial(port->out_vq->vdev))
 		return -EINVAL;
 
+	/*
+	 * pipe->nrbufs == 0 means there are no data to transfer,
+	 * so this returns just 0 for no data.
+	 */
+	pipe_lock(pipe);
+	if (!pipe->nrbufs) {
+		ret = 0;
+		goto error_out;
+	}
+
 	ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
 	if (ret < 0)
-		return ret;
+		goto error_out;
 
 	buf = alloc_buf(port->out_vq, 0, pipe->nrbufs);
-	if (!buf)
-		return -ENOMEM;
+	if (!buf) {
+		ret = -ENOMEM;
+		goto error_out;
+	}
 
 	sgl.n = 0;
 	sgl.len = 0;
@@ -946,12 +965,17 @@ static ssize_t port_fops_splice_write(st
 	sgl.sg = buf->sg;
 	sg_init_table(sgl.sg, sgl.size);
 	ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
+	pipe_unlock(pipe);
 	if (likely(ret > 0))
 		ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true);
 
 	if (unlikely(ret <= 0))
 		free_buf(buf, true);
 	return ret;
+
+error_out:
+	pipe_unlock(pipe);
+	return ret;
 }
 
 static unsigned int port_fops_poll(struct file *filp, poll_table *wait)
@@ -1019,14 +1043,14 @@ static int port_fops_open(struct inode *
 	struct port *port;
 	int ret;
 
+	/* We get the port with a kref here */
 	port = find_port_by_devt(cdev->dev);
+	if (!port) {
+		/* Port was unplugged before we could proceed */
+		return -ENXIO;
+	}
 	filp->private_data = port;
 
-	/* Prevent against a port getting hot-unplugged at the same time */
-	spin_lock_irq(&port->portdev->ports_lock);
-	kref_get(&port->kref);
-	spin_unlock_irq(&port->portdev->ports_lock);
-
 	/*
 	 * Don't allow opening of console port devices -- that's done
 	 * via /dev/hvc
@@ -1498,14 +1522,6 @@ static void remove_port(struct kref *kre
 
 	port = container_of(kref, struct port, kref);
 
-	sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
-	device_destroy(pdrvdata.class, port->dev->devt);
-	cdev_del(port->cdev);
-
-	kfree(port->name);
-
-	debugfs_remove(port->debugfs_file);
-
 	kfree(port);
 }
 
@@ -1539,12 +1555,14 @@ static void unplug_port(struct port *por
 	spin_unlock_irq(&port->portdev->ports_lock);
 
 	if (port->guest_connected) {
+		/* Let the app know the port is going down. */
+		send_sigio_to_port(port);
+
+		/* Do this after sigio is actually sent */
 		port->guest_connected = false;
 		port->host_connected = false;
-		wake_up_interruptible(&port->waitqueue);
 
-		/* Let the app know the port is going down. */
-		send_sigio_to_port(port);
+		wake_up_interruptible(&port->waitqueue);
 	}
 
 	if (is_console_port(port)) {
@@ -1563,6 +1581,14 @@ static void unplug_port(struct port *por
 	 */
 	port->portdev = NULL;
 
+	sysfs_remove_group(&port->dev->kobj, &port_attribute_group);
+	device_destroy(pdrvdata.class, port->dev->devt);
+	cdev_del(port->cdev);
+
+	kfree(port->name);
+
+	debugfs_remove(port->debugfs_file);
+
 	/*
 	 * Locks around here are not necessary - a port can't be
 	 * opened after we removed the port struct from ports_list
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/char/xilinx_hwicap/xilinx_hwicap.h linux-libre-3.11-rc7-gnu/drivers/char/xilinx_hwicap/xilinx_hwicap.h
--- linux-libre-3.10-gnu/drivers/char/xilinx_hwicap/xilinx_hwicap.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/char/xilinx_hwicap/xilinx_hwicap.h	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,7 @@
 #include <linux/cdev.h>
 #include <linux/platform_device.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 
 struct hwicap_drvdata {
 	u32 write_buffer_in_use;  /* Always in [0,3] */
@@ -85,7 +85,13 @@ struct hwicap_driver_config {
 	void (*reset)(struct hwicap_drvdata *drvdata);
 };
 
-/* Number of times to poll the done regsiter */
+/* Number of times to poll the done register. This has to be large
+ * enough to allow an entire configuration to complete. If an entire
+ * page (4kb) is configured at once, that could take up to 4k cycles
+ * with a byte-wide icap interface. In most cases, this driver is
+ * used with a much smaller fifo, but this should be sufficient in the
+ * worst case.
+ */
 #define XHI_MAX_RETRIES     5000
 
 /************ Constant Definitions *************/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk.c linux-libre-3.11-rc7-gnu/drivers/clk/clk.c
--- linux-libre-3.10-gnu/drivers/clk/clk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,7 +107,7 @@ static void clk_summary_show_one(struct
 	seq_printf(s, "%*s%-*s %-11d %-12d %-10lu",
 		   level * 3 + 1, "",
 		   30 - level * 3, c->name,
-		   c->enable_count, c->prepare_count, c->rate);
+		   c->enable_count, c->prepare_count, clk_get_rate(c));
 	seq_printf(s, "\n");
 }
 
@@ -166,7 +166,7 @@ static void clk_dump_one(struct seq_file
 	seq_printf(s, "\"%s\": { ", c->name);
 	seq_printf(s, "\"enable_count\": %d,", c->enable_count);
 	seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
-	seq_printf(s, "\"rate\": %lu", c->rate);
+	seq_printf(s, "\"rate\": %lu", clk_get_rate(c));
 }
 
 static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
@@ -534,7 +534,7 @@ static int clk_disable_unused(void)
 
 	return 0;
 }
-late_initcall(clk_disable_unused);
+late_initcall_sync(clk_disable_unused);
 
 /***    helper functions   ***/
 
@@ -1216,7 +1216,7 @@ int clk_set_rate(struct clk *clk, unsign
 	clk_prepare_lock();
 
 	/* bail early if nothing to do */
-	if (rate == clk->rate)
+	if (rate == clk_get_rate(clk))
 		goto out;
 
 	if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) {
@@ -1377,23 +1377,33 @@ static int __clk_set_parent(struct clk *
 	unsigned long flags;
 	int ret = 0;
 	struct clk *old_parent = clk->parent;
-	bool migrated_enable = false;
 
-	/* migrate prepare */
-	if (clk->prepare_count)
+	/*
+	 * Migrate prepare state between parents and prevent race with
+	 * clk_enable().
+	 *
+	 * If the clock is not prepared, then a race with
+	 * clk_enable/disable() is impossible since we already have the
+	 * prepare lock (future calls to clk_enable() need to be preceded by
+	 * a clk_prepare()).
+	 *
+	 * If the clock is prepared, migrate the prepared state to the new
+	 * parent and also protect against a race with clk_enable() by
+	 * forcing the clock and the new parent on.  This ensures that all
+	 * future calls to clk_enable() are practically NOPs with respect to
+	 * hardware and software states.
+	 *
+	 * See also: Comment for clk_set_parent() below.
+	 */
+	if (clk->prepare_count) {
 		__clk_prepare(parent);
-
-	flags = clk_enable_lock();
-
-	/* migrate enable */
-	if (clk->enable_count) {
-		__clk_enable(parent);
-		migrated_enable = true;
+		clk_enable(parent);
+		clk_enable(clk);
 	}
 
 	/* update the clk tree topology */
+	flags = clk_enable_lock();
 	clk_reparent(clk, parent);
-
 	clk_enable_unlock(flags);
 
 	/* change clock input source */
@@ -1401,43 +1411,27 @@ static int __clk_set_parent(struct clk *
 		ret = clk->ops->set_parent(clk->hw, p_index);
 
 	if (ret) {
-		/*
-		 * The error handling is tricky due to that we need to release
-		 * the spinlock while issuing the .set_parent callback. This
-		 * means the new parent might have been enabled/disabled in
-		 * between, which must be considered when doing rollback.
-		 */
 		flags = clk_enable_lock();
-
 		clk_reparent(clk, old_parent);
-
-		if (migrated_enable && clk->enable_count) {
-			__clk_disable(parent);
-		} else if (migrated_enable && (clk->enable_count == 0)) {
-			__clk_disable(old_parent);
-		} else if (!migrated_enable && clk->enable_count) {
-			__clk_disable(parent);
-			__clk_enable(old_parent);
-		}
-
 		clk_enable_unlock(flags);
 
-		if (clk->prepare_count)
+		if (clk->prepare_count) {
+			clk_disable(clk);
+			clk_disable(parent);
 			__clk_unprepare(parent);
-
+		}
 		return ret;
 	}
 
-	/* clean up enable for old parent if migration was done */
-	if (migrated_enable) {
-		flags = clk_enable_lock();
-		__clk_disable(old_parent);
-		clk_enable_unlock(flags);
-	}
-
-	/* clean up prepare for old parent if migration was done */
-	if (clk->prepare_count)
+	/*
+	 * Finish the migration of prepare state and undo the changes done
+	 * for preventing a race with clk_enable().
+	 */
+	if (clk->prepare_count) {
+		clk_disable(clk);
+		clk_disable(old_parent);
 		__clk_unprepare(old_parent);
+	}
 
 	/* update debugfs with new clk tree topology */
 	clk_debug_reparent(clk, parent);
@@ -1449,12 +1443,17 @@ static int __clk_set_parent(struct clk *
  * @clk: the mux clk whose input we are switching
  * @parent: the new input to clk
  *
- * Re-parent clk to use parent as it's new input source.  If clk has the
- * CLK_SET_PARENT_GATE flag set then clk must be gated for this
- * operation to succeed.  After successfully changing clk's parent
- * clk_set_parent will update the clk topology, sysfs topology and
- * propagate rate recalculation via __clk_recalc_rates.  Returns 0 on
- * success, -EERROR otherwise.
+ * Re-parent clk to use parent as its new input source.  If clk is in
+ * prepared state, the clk will get enabled for the duration of this call. If
+ * that's not acceptable for a specific clk (Eg: the consumer can't handle
+ * that, the reparenting is glitchy in hardware, etc), use the
+ * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
+ *
+ * After successfully changing clk's parent clk_set_parent will update the
+ * clk topology, sysfs topology and propagate rate recalculation via
+ * __clk_recalc_rates.
+ *
+ * Returns 0 on success, -EERROR otherwise.
  */
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
@@ -1494,8 +1493,7 @@ int clk_set_parent(struct clk *clk, stru
 	}
 
 	/* propagate PRE_RATE_CHANGE notifications */
-	if (clk->notifier_count)
-		ret = __clk_speculate_rates(clk, p_rate);
+	ret = __clk_speculate_rates(clk, p_rate);
 
 	/* abort if a driver objects */
 	if (ret & NOTIFY_STOP_MASK)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-divider.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-divider.c
--- linux-libre-3.10-gnu/drivers/clk/clk-divider.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-divider.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,6 +150,7 @@ static int clk_divider_bestdiv(struct cl
 	struct clk_divider *divider = to_clk_divider(hw);
 	int i, bestdiv = 0;
 	unsigned long parent_rate, best = 0, now, maxdiv;
+	unsigned long parent_rate_saved = *best_parent_rate;
 
 	if (!rate)
 		rate = 1;
@@ -173,6 +174,15 @@ static int clk_divider_bestdiv(struct cl
 	for (i = 1; i <= maxdiv; i++) {
 		if (!_is_valid_div(divider, i))
 			continue;
+		if (rate * i == parent_rate_saved) {
+			/*
+			 * It's the most ideal case if the requested rate can be
+			 * divided from parent clock without needing to change
+			 * parent rate, so return the divider immediately.
+			 */
+			*best_parent_rate = parent_rate_saved;
+			return i;
+		}
 		parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
 				MULT_ROUND_UP(rate, i));
 		now = parent_rate / i;
@@ -217,8 +227,12 @@ static int clk_divider_set_rate(struct c
 	if (divider->lock)
 		spin_lock_irqsave(divider->lock, flags);
 
-	val = readl(divider->reg);
-	val &= ~(div_mask(divider) << divider->shift);
+	if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
+		val = div_mask(divider) << (divider->shift + 16);
+	} else {
+		val = readl(divider->reg);
+		val &= ~(div_mask(divider) << divider->shift);
+	}
 	val |= value << divider->shift;
 	writel(val, divider->reg);
 
@@ -245,6 +259,13 @@ static struct clk *_register_divider(str
 	struct clk *clk;
 	struct clk_init_data init;
 
+	if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
+		if (width + shift > 16) {
+			pr_warn("divider value exceeds LOWORD field\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
 	/* allocate the divider */
 	div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
 	if (!div) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-gate.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-gate.c
--- linux-libre-3.10-gnu/drivers/clk/clk-gate.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-gate.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,12 +53,18 @@ static void clk_gate_endisable(struct cl
 	if (gate->lock)
 		spin_lock_irqsave(gate->lock, flags);
 
-	reg = readl(gate->reg);
+	if (gate->flags & CLK_GATE_HIWORD_MASK) {
+		reg = BIT(gate->bit_idx + 16);
+		if (set)
+			reg |= BIT(gate->bit_idx);
+	} else {
+		reg = readl(gate->reg);
 
-	if (set)
-		reg |= BIT(gate->bit_idx);
-	else
-		reg &= ~BIT(gate->bit_idx);
+		if (set)
+			reg |= BIT(gate->bit_idx);
+		else
+			reg &= ~BIT(gate->bit_idx);
+	}
 
 	writel(reg, gate->reg);
 
@@ -121,6 +127,13 @@ struct clk *clk_register_gate(struct dev
 	struct clk *clk;
 	struct clk_init_data init;
 
+	if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
+		if (bit_idx > 16) {
+			pr_err("gate bit exceeds LOWORD field\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
 	/* allocate the gate */
 	gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
 	if (!gate) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-mux.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-mux.c
--- linux-libre-3.10-gnu/drivers/clk/clk-mux.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-mux.c	2013-08-25 20:43:22.000000000 -0400
@@ -86,8 +86,12 @@ static int clk_mux_set_parent(struct clk
 	if (mux->lock)
 		spin_lock_irqsave(mux->lock, flags);
 
-	val = readl(mux->reg);
-	val &= ~(mux->mask << mux->shift);
+	if (mux->flags & CLK_MUX_HIWORD_MASK) {
+		val = mux->mask << (mux->shift + 16);
+	} else {
+		val = readl(mux->reg);
+		val &= ~(mux->mask << mux->shift);
+	}
 	val |= index << mux->shift;
 	writel(val, mux->reg);
 
@@ -111,6 +115,15 @@ struct clk *clk_register_mux_table(struc
 	struct clk_mux *mux;
 	struct clk *clk;
 	struct clk_init_data init;
+	u8 width = 0;
+
+	if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
+		width = fls(mask) - ffs(mask) + 1;
+		if (width + shift > 16) {
+			pr_err("mux value exceeds LOWORD field\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
 
 	/* allocate the mux */
 	mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-nomadik.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-nomadik.c
--- linux-libre-3.10-gnu/drivers/clk/clk-nomadik.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-nomadik.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,48 +1,566 @@
+/*
+ * Nomadik clock implementation
+ * Copyright (C) 2013 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ */
+
+#define pr_fmt(fmt) "Nomadik SRC clocks: " fmt
+
+#include <linux/bitops.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/reboot.h>
 
 /*
  * The Nomadik clock tree is described in the STN8815A12 DB V4.2
  * reference manual for the chip, page 94 ff.
+ * Clock IDs are in the STn8815 Reference Manual table 3, page 27.
  */
 
-void __init nomadik_clk_init(void)
+#define SRC_CR			0x00U
+#define SRC_XTALCR		0x0CU
+#define SRC_XTALCR_XTALTIMEN	BIT(20)
+#define SRC_XTALCR_SXTALDIS	BIT(19)
+#define SRC_XTALCR_MXTALSTAT	BIT(2)
+#define SRC_XTALCR_MXTALEN	BIT(1)
+#define SRC_XTALCR_MXTALOVER	BIT(0)
+#define SRC_PLLCR		0x10U
+#define SRC_PLLCR_PLLTIMEN	BIT(29)
+#define SRC_PLLCR_PLL2EN	BIT(28)
+#define SRC_PLLCR_PLL1STAT	BIT(2)
+#define SRC_PLLCR_PLL1EN	BIT(1)
+#define SRC_PLLCR_PLL1OVER	BIT(0)
+#define SRC_PLLFR		0x14U
+#define SRC_PCKEN0		0x24U
+#define SRC_PCKDIS0		0x28U
+#define SRC_PCKENSR0		0x2CU
+#define SRC_PCKSR0		0x30U
+#define SRC_PCKEN1		0x34U
+#define SRC_PCKDIS1		0x38U
+#define SRC_PCKENSR1		0x3CU
+#define SRC_PCKSR1		0x40U
+
+/* Lock protecting the SRC_CR register */
+static DEFINE_SPINLOCK(src_lock);
+/* Base address of the SRC */
+static void __iomem *src_base;
+
+/**
+ * struct clk_pll1 - Nomadik PLL1 clock
+ * @hw: corresponding clock hardware entry
+ * @id: PLL instance: 1 or 2
+ */
+struct clk_pll {
+	struct clk_hw hw;
+	int id;
+};
+
+/**
+ * struct clk_src - Nomadik src clock
+ * @hw: corresponding clock hardware entry
+ * @id: the clock ID
+ * @group1: true if the clock is in group1, else it is in group0
+ * @clkbit: bit 0...31 corresponding to the clock in each clock register
+ */
+struct clk_src {
+	struct clk_hw hw;
+	int id;
+	bool group1;
+	u32 clkbit;
+};
+
+#define to_pll(_hw) container_of(_hw, struct clk_pll, hw)
+#define to_src(_hw) container_of(_hw, struct clk_src, hw)
+
+static int pll_clk_enable(struct clk_hw *hw)
+{
+	struct clk_pll *pll = to_pll(hw);
+	u32 val;
+
+	spin_lock(&src_lock);
+	val = readl(src_base + SRC_PLLCR);
+	if (pll->id == 1) {
+		if (val & SRC_PLLCR_PLL1OVER) {
+			val |= SRC_PLLCR_PLL1EN;
+			writel(val, src_base + SRC_PLLCR);
+		}
+	} else if (pll->id == 2) {
+		val |= SRC_PLLCR_PLL2EN;
+		writel(val, src_base + SRC_PLLCR);
+	}
+	spin_unlock(&src_lock);
+	return 0;
+}
+
+static void pll_clk_disable(struct clk_hw *hw)
+{
+	struct clk_pll *pll = to_pll(hw);
+	u32 val;
+
+	spin_lock(&src_lock);
+	val = readl(src_base + SRC_PLLCR);
+	if (pll->id == 1) {
+		if (val & SRC_PLLCR_PLL1OVER) {
+			val &= ~SRC_PLLCR_PLL1EN;
+			writel(val, src_base + SRC_PLLCR);
+		}
+	} else if (pll->id == 2) {
+		val &= ~SRC_PLLCR_PLL2EN;
+		writel(val, src_base + SRC_PLLCR);
+	}
+	spin_unlock(&src_lock);
+}
+
+static int pll_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_pll *pll = to_pll(hw);
+	u32 val;
+
+	val = readl(src_base + SRC_PLLCR);
+	if (pll->id == 1) {
+		if (val & SRC_PLLCR_PLL1OVER)
+			return !!(val & SRC_PLLCR_PLL1EN);
+	} else if (pll->id == 2) {
+		return !!(val & SRC_PLLCR_PLL2EN);
+	}
+	return 1;
+}
+
+static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct clk_pll *pll = to_pll(hw);
+	u32 val;
+
+	val = readl(src_base + SRC_PLLFR);
+
+	if (pll->id == 1) {
+		u8 mul;
+		u8 div;
+
+		mul = (val >> 8) & 0x3FU;
+		mul += 2;
+		div = val & 0x07U;
+		return (parent_rate * mul) >> div;
+	}
+
+	if (pll->id == 2) {
+		u8 mul;
+
+		mul = (val >> 24) & 0x3FU;
+		mul += 2;
+		return (parent_rate * mul);
+	}
+
+	/* Unknown PLL */
+	return 0;
+}
+
+
+static const struct clk_ops pll_clk_ops = {
+	.enable = pll_clk_enable,
+	.disable = pll_clk_disable,
+	.is_enabled = pll_clk_is_enabled,
+	.recalc_rate = pll_clk_recalc_rate,
+};
+
+static struct clk * __init
+pll_clk_register(struct device *dev, const char *name,
+		 const char *parent_name, u32 id)
 {
 	struct clk *clk;
+	struct clk_pll *pll;
+	struct clk_init_data init;
 
-	clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
-	clk_register_clkdev(clk, "apb_pclk", NULL);
-	clk_register_clkdev(clk, NULL, "gpio.0");
-	clk_register_clkdev(clk, NULL, "gpio.1");
-	clk_register_clkdev(clk, NULL, "gpio.2");
-	clk_register_clkdev(clk, NULL, "gpio.3");
-	clk_register_clkdev(clk, NULL, "rng");
-	clk_register_clkdev(clk, NULL, "fsmc-nand");
+	if (id != 1 && id != 2) {
+		pr_err("%s: the Nomadik has only PLL 1 & 2\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
 
-	/*
-	 * The 2.4 MHz TIMCLK reference clock is active at boot time, this is
-	 * actually the MXTALCLK @19.2 MHz divided by 8. This clock is used
-	 * by the timers and watchdog. See page 105 ff.
-	 */
-	clk = clk_register_fixed_rate(NULL, "TIMCLK", NULL, CLK_IS_ROOT,
-				      2400000);
-	clk_register_clkdev(clk, NULL, "mtu0");
-	clk_register_clkdev(clk, NULL, "mtu1");
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll) {
+		pr_err("%s: could not allocate PLL clk\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	init.name = name;
+	init.ops = &pll_clk_ops;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+	pll->hw.init = &init;
+	pll->id = id;
+
+	pr_debug("register PLL1 clock \"%s\"\n", name);
+
+	clk = clk_register(dev, &pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*
+ * The Nomadik SRC clocks are gated, but not in the sense that
+ * you read-modify-write a register. Instead there are separate
+ * clock enable and clock disable registers. Writing a '1' bit in
+ * the enable register for a certain clock ungates that clock without
+ * affecting the other clocks. The disable register works the opposite
+ * way.
+ */
+
+static int src_clk_enable(struct clk_hw *hw)
+{
+	struct clk_src *sclk = to_src(hw);
+	u32 enreg = sclk->group1 ? SRC_PCKEN1 : SRC_PCKEN0;
+	u32 sreg = sclk->group1 ? SRC_PCKSR1 : SRC_PCKSR0;
+
+	writel(sclk->clkbit, src_base + enreg);
+	/* spin until enabled */
+	while (!(readl(src_base + sreg) & sclk->clkbit))
+		cpu_relax();
+	return 0;
+}
+
+static void src_clk_disable(struct clk_hw *hw)
+{
+	struct clk_src *sclk = to_src(hw);
+	u32 disreg = sclk->group1 ? SRC_PCKDIS1 : SRC_PCKDIS0;
+	u32 sreg = sclk->group1 ? SRC_PCKSR1 : SRC_PCKSR0;
+
+	writel(sclk->clkbit, src_base + disreg);
+	/* spin until disabled */
+	while (readl(src_base + sreg) & sclk->clkbit)
+		cpu_relax();
+}
+
+static int src_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_src *sclk = to_src(hw);
+	u32 sreg = sclk->group1 ? SRC_PCKSR1 : SRC_PCKSR0;
+	u32 val = readl(src_base + sreg);
+
+	return !!(val & sclk->clkbit);
+}
+
+static unsigned long
+src_clk_recalc_rate(struct clk_hw *hw,
+		    unsigned long parent_rate)
+{
+	return parent_rate;
+}
+
+static const struct clk_ops src_clk_ops = {
+	.enable = src_clk_enable,
+	.disable = src_clk_disable,
+	.is_enabled = src_clk_is_enabled,
+	.recalc_rate = src_clk_recalc_rate,
+};
+
+static struct clk * __init
+src_clk_register(struct device *dev, const char *name,
+		 const char *parent_name, u8 id)
+{
+	struct clk *clk;
+	struct clk_src *sclk;
+	struct clk_init_data init;
+
+	sclk = kzalloc(sizeof(*sclk), GFP_KERNEL);
+	if (!sclk) {
+		pr_err("could not allocate SRC clock %s\n",
+			name);
+		return ERR_PTR(-ENOMEM);
+	}
+	init.name = name;
+	init.ops = &src_clk_ops;
+	/* Do not force-disable the static SDRAM controller */
+	if (id == 2)
+		init.flags = CLK_IGNORE_UNUSED;
+	else
+		init.flags = 0;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+	sclk->hw.init = &init;
+	sclk->id = id;
+	sclk->group1 = (id > 31);
+	sclk->clkbit = BIT(id & 0x1f);
+
+	pr_debug("register clock \"%s\" ID: %d group: %d bits: %08x\n",
+		 name, id, sclk->group1, sclk->clkbit);
+
+	clk = clk_register(dev, &sclk->hw);
+	if (IS_ERR(clk))
+		kfree(sclk);
+
+	return clk;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static u32 src_pcksr0_boot;
+static u32 src_pcksr1_boot;
+
+static const char * const src_clk_names[] = {
+	"HCLKDMA0  ",
+	"HCLKSMC   ",
+	"HCLKSDRAM ",
+	"HCLKDMA1  ",
+	"HCLKCLCD  ",
+	"PCLKIRDA  ",
+	"PCLKSSP   ",
+	"PCLKUART0 ",
+	"PCLKSDI   ",
+	"PCLKI2C0  ",
+	"PCLKI2C1  ",
+	"PCLKUART1 ",
+	"PCLMSP0   ",
+	"HCLKUSB   ",
+	"HCLKDIF   ",
+	"HCLKSAA   ",
+	"HCLKSVA   ",
+	"PCLKHSI   ",
+	"PCLKXTI   ",
+	"PCLKUART2 ",
+	"PCLKMSP1  ",
+	"PCLKMSP2  ",
+	"PCLKOWM   ",
+	"HCLKHPI   ",
+	"PCLKSKE   ",
+	"PCLKHSEM  ",
+	"HCLK3D    ",
+	"HCLKHASH  ",
+	"HCLKCRYP  ",
+	"PCLKMSHC  ",
+	"HCLKUSBM  ",
+	"HCLKRNG   ",
+	"RESERVED  ",
+	"RESERVED  ",
+	"RESERVED  ",
+	"RESERVED  ",
+	"CLDCLK    ",
+	"IRDACLK   ",
+	"SSPICLK   ",
+	"UART0CLK  ",
+	"SDICLK    ",
+	"I2C0CLK   ",
+	"I2C1CLK   ",
+	"UART1CLK  ",
+	"MSPCLK0   ",
+	"USBCLK    ",
+	"DIFCLK    ",
+	"IPI2CCLK  ",
+	"IPBMCCLK  ",
+	"HSICLKRX  ",
+	"HSICLKTX  ",
+	"UART2CLK  ",
+	"MSPCLK1   ",
+	"MSPCLK2   ",
+	"OWMCLK    ",
+	"RESERVED  ",
+	"SKECLK    ",
+	"RESERVED  ",
+	"3DCLK     ",
+	"PCLKMSP3  ",
+	"MSPCLK3   ",
+	"MSHCCLK   ",
+	"USBMCLK   ",
+	"RNGCCLK   ",
+};
+
+static int nomadik_src_clk_show(struct seq_file *s, void *what)
+{
+	int i;
+	u32 src_pcksr0 = readl(src_base + SRC_PCKSR0);
+	u32 src_pcksr1 = readl(src_base + SRC_PCKSR1);
+	u32 src_pckensr0 = readl(src_base + SRC_PCKENSR0);
+	u32 src_pckensr1 = readl(src_base + SRC_PCKENSR1);
+
+	seq_printf(s, "Clock:      Boot:   Now:    Request: ASKED:\n");
+	for (i = 0; i < ARRAY_SIZE(src_clk_names); i++) {
+		u32 pcksrb = (i < 0x20) ? src_pcksr0_boot : src_pcksr1_boot;
+		u32 pcksr = (i < 0x20) ? src_pcksr0 : src_pcksr1;
+		u32 pckreq = (i < 0x20) ? src_pckensr0 : src_pckensr1;
+		u32 mask = BIT(i & 0x1f);
+
+		seq_printf(s, "%s  %s     %s     %s\n",
+			   src_clk_names[i],
+			   (pcksrb & mask) ? "on " : "off",
+			   (pcksr & mask) ? "on " : "off",
+			   (pckreq & mask) ? "on " : "off");
+	}
+	return 0;
+}
+
+static int nomadik_src_clk_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, nomadik_src_clk_show, NULL);
+}
+
+static const struct file_operations nomadik_src_clk_debugfs_ops = {
+	.open           = nomadik_src_clk_open,
+	.read           = seq_read,
+        .llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static int __init nomadik_src_clk_init_debugfs(void)
+{
+	src_pcksr0_boot = readl(src_base + SRC_PCKSR0);
+	src_pcksr1_boot = readl(src_base + SRC_PCKSR1);
+	debugfs_create_file("nomadik-src-clk", S_IFREG | S_IRUGO,
+			    NULL, NULL, &nomadik_src_clk_debugfs_ops);
+	return 0;
+}
+
+module_init(nomadik_src_clk_init_debugfs);
+
+#endif
+
+static void __init of_nomadik_pll_setup(struct device_node *np)
+{
+	struct clk *clk = ERR_PTR(-EINVAL);
+	const char *clk_name = np->name;
+	const char *parent_name;
+	u32 pll_id;
+
+	if (of_property_read_u32(np, "pll-id", &pll_id)) {
+		pr_err("%s: PLL \"%s\" missing pll-id property\n",
+			__func__, clk_name);
+		return;
+	}
+	parent_name = of_clk_get_parent_name(np, 0);
+	clk = pll_clk_register(NULL, clk_name, parent_name, pll_id);
+	if (!IS_ERR(clk))
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static void __init of_nomadik_hclk_setup(struct device_node *np)
+{
+	struct clk *clk = ERR_PTR(-EINVAL);
+	const char *clk_name = np->name;
+	const char *parent_name;
 
+	parent_name = of_clk_get_parent_name(np, 0);
 	/*
-	 * At boot time, PLL2 is set to generate a set of fixed clocks,
-	 * one of them is CLK48, the 48 MHz clock, routed to the UART, MMC/SD
-	 * I2C, IrDA, USB and SSP blocks.
+	 * The HCLK divides PLL1 with 1 (passthru), 2, 3 or 4.
 	 */
-	clk = clk_register_fixed_rate(NULL, "CLK48", NULL, CLK_IS_ROOT,
-				      48000000);
-	clk_register_clkdev(clk, NULL, "uart0");
-	clk_register_clkdev(clk, NULL, "uart1");
-	clk_register_clkdev(clk, NULL, "mmci");
-	clk_register_clkdev(clk, NULL, "ssp");
-	clk_register_clkdev(clk, NULL, "nmk-i2c.0");
-	clk_register_clkdev(clk, NULL, "nmk-i2c.1");
+	clk = clk_register_divider(NULL, clk_name, parent_name,
+			   0, src_base + SRC_CR,
+			   13, 2,
+			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+			   &src_lock);
+	if (!IS_ERR(clk))
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static void __init of_nomadik_src_clk_setup(struct device_node *np)
+{
+	struct clk *clk = ERR_PTR(-EINVAL);
+	const char *clk_name = np->name;
+	const char *parent_name;
+	u32 clk_id;
+
+	if (of_property_read_u32(np, "clock-id", &clk_id)) {
+		pr_err("%s: SRC clock \"%s\" missing clock-id property\n",
+			__func__, clk_name);
+		return;
+	}
+	parent_name = of_clk_get_parent_name(np, 0);
+	clk = src_clk_register(NULL, clk_name, parent_name, clk_id);
+	if (!IS_ERR(clk))
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static const __initconst struct of_device_id nomadik_src_match[] = {
+	{ .compatible = "stericsson,nomadik-src" },
+	{ /* sentinel */ }
+};
+
+static const __initconst struct of_device_id nomadik_src_clk_match[] = {
+	{
+		.compatible = "fixed-clock",
+		.data = of_fixed_clk_setup,
+	},
+	{
+		.compatible = "fixed-factor-clock",
+		.data = of_fixed_factor_clk_setup,
+	},
+	{
+		.compatible = "st,nomadik-pll-clock",
+		.data = of_nomadik_pll_setup,
+	},
+	{
+		.compatible = "st,nomadik-hclk-clock",
+		.data = of_nomadik_hclk_setup,
+	},
+	{
+		.compatible = "st,nomadik-src-clock",
+		.data = of_nomadik_src_clk_setup,
+	},
+	{ /* sentinel */ }
+};
+
+static int nomadik_clk_reboot_handler(struct notifier_block *this,
+				unsigned long code,
+				void *unused)
+{
+	u32 val;
+
+	/* The main chrystal need to be enabled for reboot to work */
+	val = readl(src_base + SRC_XTALCR);
+	val &= ~SRC_XTALCR_MXTALOVER;
+	val |= SRC_XTALCR_MXTALEN;
+	pr_crit("force-enabling MXTALO\n");
+	writel(val, src_base + SRC_XTALCR);
+	return NOTIFY_OK;
+}
+
+static struct notifier_block nomadik_clk_reboot_notifier = {
+	.notifier_call = nomadik_clk_reboot_handler,
+};
+
+void __init nomadik_clk_init(void)
+{
+	struct device_node *np;
+	u32 val;
+
+	np = of_find_matching_node(NULL, nomadik_src_match);
+	if (!np) {
+		pr_crit("no matching node for SRC, aborting clock init\n");
+		return;
+	}
+	src_base = of_iomap(np, 0);
+	if (!src_base) {
+		pr_err("%s: must have src parent node with REGS (%s)\n",
+		       __func__, np->name);
+		return;
+	}
+	val = readl(src_base + SRC_XTALCR);
+	pr_info("SXTALO is %s\n",
+		(val & SRC_XTALCR_SXTALDIS) ? "disabled" : "enabled");
+	pr_info("MXTAL is %s\n",
+		(val & SRC_XTALCR_MXTALSTAT) ? "enabled" : "disabled");
+	if (of_property_read_bool(np, "disable-sxtalo")) {
+		/* The machine uses an external oscillator circuit */
+		val |= SRC_XTALCR_SXTALDIS;
+		pr_info("disabling SXTALO\n");
+	}
+	if (of_property_read_bool(np, "disable-mxtalo")) {
+		/* Disable this too: also run by external oscillator */
+		val |= SRC_XTALCR_MXTALOVER;
+		val &= ~SRC_XTALCR_MXTALEN;
+		pr_info("disabling MXTALO\n");
+	}
+	writel(val, src_base + SRC_XTALCR);
+	register_reboot_notifier(&nomadik_clk_reboot_notifier);
+
+	of_clk_init(nomadik_src_clk_match);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-nspire.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-nspire.c
--- linux-libre-3.10-gnu/drivers/clk/clk-nspire.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-nspire.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,153 @@
+/*
+ *
+ *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define MHZ (1000 * 1000)
+
+#define BASE_CPU_SHIFT		1
+#define BASE_CPU_MASK		0x7F
+
+#define CPU_AHB_SHIFT		12
+#define CPU_AHB_MASK		0x07
+
+#define FIXED_BASE_SHIFT	8
+#define FIXED_BASE_MASK		0x01
+
+#define CLASSIC_BASE_SHIFT	16
+#define CLASSIC_BASE_MASK	0x1F
+
+#define CX_BASE_SHIFT		15
+#define CX_BASE_MASK		0x3F
+
+#define CX_UNKNOWN_SHIFT	21
+#define CX_UNKNOWN_MASK		0x03
+
+struct nspire_clk_info {
+	u32 base_clock;
+	u16 base_cpu_ratio;
+	u16 base_ahb_ratio;
+};
+
+
+#define EXTRACT(var, prop) (((var)>>prop##_SHIFT) & prop##_MASK)
+static void nspire_clkinfo_cx(u32 val, struct nspire_clk_info *clk)
+{
+	if (EXTRACT(val, FIXED_BASE))
+		clk->base_clock = 48 * MHZ;
+	else
+		clk->base_clock = 6 * EXTRACT(val, CX_BASE) * MHZ;
+
+	clk->base_cpu_ratio = EXTRACT(val, BASE_CPU) * EXTRACT(val, CX_UNKNOWN);
+	clk->base_ahb_ratio = clk->base_cpu_ratio * (EXTRACT(val, CPU_AHB) + 1);
+}
+
+static void nspire_clkinfo_classic(u32 val, struct nspire_clk_info *clk)
+{
+	if (EXTRACT(val, FIXED_BASE))
+		clk->base_clock = 27 * MHZ;
+	else
+		clk->base_clock = (300 - 6 * EXTRACT(val, CLASSIC_BASE)) * MHZ;
+
+	clk->base_cpu_ratio = EXTRACT(val, BASE_CPU) * 2;
+	clk->base_ahb_ratio = clk->base_cpu_ratio * (EXTRACT(val, CPU_AHB) + 1);
+}
+
+static void __init nspire_ahbdiv_setup(struct device_node *node,
+		void (*get_clkinfo)(u32, struct nspire_clk_info *))
+{
+	u32 val;
+	void __iomem *io;
+	struct clk *clk;
+	const char *clk_name = node->name;
+	const char *parent_name;
+	struct nspire_clk_info info;
+
+	io = of_iomap(node, 0);
+	if (!io)
+		return;
+	val = readl(io);
+	iounmap(io);
+
+	get_clkinfo(val, &info);
+
+	of_property_read_string(node, "clock-output-names", &clk_name);
+	parent_name = of_clk_get_parent_name(node, 0);
+
+	clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0,
+					1, info.base_ahb_ratio);
+	if (!IS_ERR(clk))
+		of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+
+static void __init nspire_ahbdiv_setup_cx(struct device_node *node)
+{
+	nspire_ahbdiv_setup(node, nspire_clkinfo_cx);
+}
+
+static void __init nspire_ahbdiv_setup_classic(struct device_node *node)
+{
+	nspire_ahbdiv_setup(node, nspire_clkinfo_classic);
+}
+
+CLK_OF_DECLARE(nspire_ahbdiv_cx, "lsi,nspire-cx-ahb-divider",
+		nspire_ahbdiv_setup_cx);
+CLK_OF_DECLARE(nspire_ahbdiv_classic, "lsi,nspire-classic-ahb-divider",
+		nspire_ahbdiv_setup_classic);
+
+static void __init nspire_clk_setup(struct device_node *node,
+		void (*get_clkinfo)(u32, struct nspire_clk_info *))
+{
+	u32 val;
+	void __iomem *io;
+	struct clk *clk;
+	const char *clk_name = node->name;
+	struct nspire_clk_info info;
+
+	io = of_iomap(node, 0);
+	if (!io)
+		return;
+	val = readl(io);
+	iounmap(io);
+
+	get_clkinfo(val, &info);
+
+	of_property_read_string(node, "clock-output-names", &clk_name);
+
+	clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT,
+			info.base_clock);
+	if (!IS_ERR(clk))
+		of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	else
+		return;
+
+	pr_info("TI-NSPIRE Base: %uMHz CPU: %uMHz AHB: %uMHz\n",
+		info.base_clock / MHZ,
+		info.base_clock / info.base_cpu_ratio / MHZ,
+		info.base_clock / info.base_ahb_ratio / MHZ);
+}
+
+static void __init nspire_clk_setup_cx(struct device_node *node)
+{
+	nspire_clk_setup(node, nspire_clkinfo_cx);
+}
+
+static void __init nspire_clk_setup_classic(struct device_node *node)
+{
+	nspire_clk_setup(node, nspire_clkinfo_classic);
+}
+
+CLK_OF_DECLARE(nspire_clk_cx, "lsi,nspire-cx-clock", nspire_clk_setup_cx);
+CLK_OF_DECLARE(nspire_clk_classic, "lsi,nspire-classic-clock",
+		nspire_clk_setup_classic);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-ppc-corenet.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-ppc-corenet.c
--- linux-libre-3.10-gnu/drivers/clk/clk-ppc-corenet.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-ppc-corenet.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * clock driver for Freescale PowerPC corenet SoCs.
+ */
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+struct cmux_clk {
+	struct clk_hw hw;
+	void __iomem *reg;
+	u32 flags;
+};
+
+#define PLL_KILL			BIT(31)
+#define	CLKSEL_SHIFT		27
+#define CLKSEL_ADJUST		BIT(0)
+#define to_cmux_clk(p)		container_of(p, struct cmux_clk, hw)
+
+static void __iomem *base;
+static unsigned int clocks_per_pll;
+
+static int cmux_set_parent(struct clk_hw *hw, u8 idx)
+{
+	struct cmux_clk *clk = to_cmux_clk(hw);
+	u32 clksel;
+
+	clksel = ((idx / clocks_per_pll) << 2) + idx % clocks_per_pll;
+	if (clk->flags & CLKSEL_ADJUST)
+		clksel += 8;
+	clksel = (clksel & 0xf) << CLKSEL_SHIFT;
+	iowrite32be(clksel, clk->reg);
+
+	return 0;
+}
+
+static u8 cmux_get_parent(struct clk_hw *hw)
+{
+	struct cmux_clk *clk = to_cmux_clk(hw);
+	u32 clksel;
+
+	clksel = ioread32be(clk->reg);
+	clksel = (clksel >> CLKSEL_SHIFT) & 0xf;
+	if (clk->flags & CLKSEL_ADJUST)
+		clksel -= 8;
+	clksel = (clksel >> 2) * clocks_per_pll + clksel % 4;
+
+	return clksel;
+}
+
+const struct clk_ops cmux_ops = {
+	.get_parent = cmux_get_parent,
+	.set_parent = cmux_set_parent,
+};
+
+static void __init core_mux_init(struct device_node *np)
+{
+	struct clk *clk;
+	struct clk_init_data init;
+	struct cmux_clk *cmux_clk;
+	struct device_node *node;
+	int rc, count, i;
+	u32	offset;
+	const char *clk_name;
+	const char **parent_names;
+
+	rc = of_property_read_u32(np, "reg", &offset);
+	if (rc) {
+		pr_err("%s: could not get reg property\n", np->name);
+		return;
+	}
+
+	/* get the input clock source count */
+	count = of_property_count_strings(np, "clock-names");
+	if (count < 0) {
+		pr_err("%s: get clock count error\n", np->name);
+		return;
+	}
+	parent_names = kzalloc((sizeof(char *) * count), GFP_KERNEL);
+	if (!parent_names) {
+		pr_err("%s: could not allocate parent_names\n", __func__);
+		return;
+	}
+
+	for (i = 0; i < count; i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+
+	cmux_clk = kzalloc(sizeof(struct cmux_clk), GFP_KERNEL);
+	if (!cmux_clk) {
+		pr_err("%s: could not allocate cmux_clk\n", __func__);
+		goto err_name;
+	}
+	cmux_clk->reg = base + offset;
+
+	node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen");
+	if (node && (offset >= 0x80))
+		cmux_clk->flags = CLKSEL_ADJUST;
+
+	rc = of_property_read_string_index(np, "clock-output-names",
+			0, &clk_name);
+	if (rc) {
+		pr_err("%s: read clock names error\n", np->name);
+		goto err_clk;
+	}
+
+	init.name = clk_name;
+	init.ops = &cmux_ops;
+	init.parent_names = parent_names;
+	init.num_parents = count;
+	init.flags = 0;
+	cmux_clk->hw.init = &init;
+
+	clk = clk_register(NULL, &cmux_clk->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: could not register clock\n", clk_name);
+		goto err_clk;
+	}
+
+	rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	if (rc) {
+		pr_err("Could not register clock provider for node:%s\n",
+			 np->name);
+		goto err_clk;
+	}
+	goto err_name;
+
+err_clk:
+	kfree(cmux_clk);
+err_name:
+	/* free *_names because they are reallocated when registered */
+	kfree(parent_names);
+}
+
+static void __init core_pll_init(struct device_node *np)
+{
+	u32 offset, mult;
+	int i, rc, count;
+	const char *clk_name, *parent_name;
+	struct clk_onecell_data *onecell_data;
+	struct clk      **subclks;
+
+	rc = of_property_read_u32(np, "reg", &offset);
+	if (rc) {
+		pr_err("%s: could not get reg property\n", np->name);
+		return;
+	}
+
+	/* get the multiple of PLL */
+	mult = ioread32be(base + offset);
+
+	/* check if this PLL is disabled */
+	if (mult & PLL_KILL) {
+		pr_debug("PLL:%s is disabled\n", np->name);
+		return;
+	}
+	mult = (mult >> 1) & 0x3f;
+
+	parent_name = of_clk_get_parent_name(np, 0);
+	if (!parent_name) {
+		pr_err("PLL: %s must have a parent\n", np->name);
+		return;
+	}
+
+	count = of_property_count_strings(np, "clock-output-names");
+	if (count < 0 || count > 4) {
+		pr_err("%s: clock is not supported\n", np->name);
+		return;
+	}
+
+	/* output clock number per PLL */
+	clocks_per_pll = count;
+
+	subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);
+	if (!subclks) {
+		pr_err("%s: could not allocate subclks\n", __func__);
+		return;
+	}
+
+	onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+	if (!onecell_data) {
+		pr_err("%s: could not allocate onecell_data\n", __func__);
+		goto err_clks;
+	}
+
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(np, "clock-output-names",
+				i, &clk_name);
+		if (rc) {
+			pr_err("%s: could not get clock names\n", np->name);
+			goto err_cell;
+		}
+
+		/*
+		 * when count == 4, there are 4 output clocks:
+		 * /1, /2, /3, /4 respectively
+		 * when count < 4, there are at least 2 output clocks:
+		 * /1, /2, (/4, if count == 3) respectively.
+		 */
+		if (count == 4)
+			subclks[i] = clk_register_fixed_factor(NULL, clk_name,
+					parent_name, 0, mult, 1 + i);
+		else
+
+			subclks[i] = clk_register_fixed_factor(NULL, clk_name,
+					parent_name, 0, mult, 1 << i);
+
+		if (IS_ERR(subclks[i])) {
+			pr_err("%s: could not register clock\n", clk_name);
+			goto err_cell;
+		}
+	}
+
+	onecell_data->clks = subclks;
+	onecell_data->clk_num = count;
+
+	rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data);
+	if (rc) {
+		pr_err("Could not register clk provider for node:%s\n",
+			 np->name);
+		goto err_cell;
+	}
+
+	return;
+err_cell:
+	kfree(onecell_data);
+err_clks:
+	kfree(subclks);
+}
+
+static const struct of_device_id clk_match[] __initconst = {
+	{ .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
+	{ .compatible = "fsl,core-pll-clock", .data = core_pll_init, },
+	{ .compatible = "fsl,core-mux-clock", .data = core_mux_init, },
+	{}
+};
+
+static int __init ppc_corenet_clk_probe(struct platform_device *pdev)
+{
+	struct device_node *np;
+
+	np = pdev->dev.of_node;
+	base = of_iomap(np, 0);
+	if (!base) {
+		dev_err(&pdev->dev, "iomap error\n");
+		return -ENOMEM;
+	}
+	of_clk_init(clk_match);
+
+	return 0;
+}
+
+static const struct of_device_id ppc_clk_ids[] __initconst = {
+	{ .compatible = "fsl,qoriq-clockgen-1.0", },
+	{ .compatible = "fsl,qoriq-clockgen-2.0", },
+	{}
+};
+
+static struct platform_driver ppc_corenet_clk_driver = {
+	.driver = {
+		.name = "ppc_corenet_clock",
+		.owner = THIS_MODULE,
+		.of_match_table = ppc_clk_ids,
+	},
+	.probe = ppc_corenet_clk_probe,
+};
+
+static int __init ppc_corenet_clk_init(void)
+{
+	return platform_driver_register(&ppc_corenet_clk_driver);
+}
+subsys_initcall(ppc_corenet_clk_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-si5351.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-si5351.c
--- linux-libre-3.10-gnu/drivers/clk/clk-si5351.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-si5351.c	2013-08-25 20:43:22.000000000 -0400
@@ -851,6 +851,41 @@ static int _si5351_clkout_set_drive_stre
 	return 0;
 }
 
+static int _si5351_clkout_set_disable_state(
+	struct si5351_driver_data *drvdata, int num,
+	enum si5351_disable_state state)
+{
+	u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
+		SI5351_CLK7_4_DISABLE_STATE;
+	u8 shift = (num < 4) ? (2 * num) : (2 * (num-4));
+	u8 mask = SI5351_CLK_DISABLE_STATE_MASK << shift;
+	u8 val;
+
+	if (num > 8)
+		return -EINVAL;
+
+	switch (state) {
+	case SI5351_DISABLE_LOW:
+		val = SI5351_CLK_DISABLE_STATE_LOW;
+		break;
+	case SI5351_DISABLE_HIGH:
+		val = SI5351_CLK_DISABLE_STATE_HIGH;
+		break;
+	case SI5351_DISABLE_FLOATING:
+		val = SI5351_CLK_DISABLE_STATE_FLOAT;
+		break;
+	case SI5351_DISABLE_NEVER:
+		val = SI5351_CLK_DISABLE_STATE_NEVER;
+		break;
+	default:
+		return 0;
+	}
+
+	si5351_set_bits(drvdata, reg, mask, val << shift);
+
+	return 0;
+}
+
 static int si5351_clkout_prepare(struct clk_hw *hw)
 {
 	struct si5351_hw_data *hwdata =
@@ -1225,6 +1260,33 @@ static int si5351_dt_parse(struct i2c_cl
 			}
 		}
 
+		if (!of_property_read_u32(child, "silabs,disable-state",
+					  &val)) {
+			switch (val) {
+			case 0:
+				pdata->clkout[num].disable_state =
+					SI5351_DISABLE_LOW;
+				break;
+			case 1:
+				pdata->clkout[num].disable_state =
+					SI5351_DISABLE_HIGH;
+				break;
+			case 2:
+				pdata->clkout[num].disable_state =
+					SI5351_DISABLE_FLOATING;
+				break;
+			case 3:
+				pdata->clkout[num].disable_state =
+					SI5351_DISABLE_NEVER;
+				break;
+			default:
+				dev_err(&client->dev,
+					"invalid disable state %d for clkout %d\n",
+					val, num);
+				return -EINVAL;
+			}
+		}
+
 		if (!of_property_read_u32(child, "clock-frequency", &val))
 			pdata->clkout[num].rate = val;
 
@@ -1281,9 +1343,6 @@ static int si5351_i2c_probe(struct i2c_c
 
 	/* Disable interrupts */
 	si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0);
-	/* Set disabled output drivers to drive low */
-	si5351_reg_write(drvdata, SI5351_CLK3_0_DISABLE_STATE, 0x00);
-	si5351_reg_write(drvdata, SI5351_CLK7_4_DISABLE_STATE, 0x00);
 	/* Ensure pll select is on XTAL for Si5351A/B */
 	if (drvdata->variant != SI5351_VARIANT_C)
 		si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
@@ -1327,6 +1386,15 @@ static int si5351_i2c_probe(struct i2c_c
 				n, pdata->clkout[n].drive);
 			return ret;
 		}
+
+		ret = _si5351_clkout_set_disable_state(drvdata, n,
+						pdata->clkout[n].disable_state);
+		if (ret) {
+			dev_err(&client->dev,
+				"failed set disable state of clkout%d to %d\n",
+				n, pdata->clkout[n].disable_state);
+			return ret;
+		}
 	}
 
 	/* register xtal input clock gate */
@@ -1500,7 +1568,10 @@ static int si5351_i2c_probe(struct i2c_c
 }
 
 static const struct i2c_device_id si5351_i2c_ids[] = {
-	{ "silabs,si5351", 0 },
+	{ "si5351a", 0 },
+	{ "si5351a-msop", 0 },
+	{ "si5351b", 0 },
+	{ "si5351c", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-si5351.h linux-libre-3.11-rc7-gnu/drivers/clk/clk-si5351.h
--- linux-libre-3.10-gnu/drivers/clk/clk-si5351.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-si5351.h	2013-08-25 20:43:22.000000000 -0400
@@ -81,6 +81,7 @@
 
 #define SI5351_CLK3_0_DISABLE_STATE		24
 #define SI5351_CLK7_4_DISABLE_STATE		25
+#define  SI5351_CLK_DISABLE_STATE_MASK		3
 #define  SI5351_CLK_DISABLE_STATE_LOW		0
 #define  SI5351_CLK_DISABLE_STATE_HIGH		1
 #define  SI5351_CLK_DISABLE_STATE_FLOAT		2
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-twl6040.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-twl6040.c
--- linux-libre-3.10-gnu/drivers/clk/clk-twl6040.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-twl6040.c	2013-08-25 20:43:22.000000000 -0400
@@ -95,14 +95,14 @@ static int twl6040_clk_probe(struct plat
 	if (IS_ERR(clkdata->clk))
 		return PTR_ERR(clkdata->clk);
 
-	dev_set_drvdata(&pdev->dev, clkdata);
+	platform_set_drvdata(pdev, clkdata);
 
 	return 0;
 }
 
 static int twl6040_clk_remove(struct platform_device *pdev)
 {
-	struct twl6040_clk *clkdata = dev_get_drvdata(&pdev->dev);
+	struct twl6040_clk *clkdata = platform_get_drvdata(pdev);
 
 	clk_unregister(clkdata->clk);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-u300.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-u300.c
--- linux-libre-3.10-gnu/drivers/clk/clk-u300.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-u300.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,349 @@
 #include <linux/io.h>
 #include <linux/clk-provider.h>
 #include <linux/spinlock.h>
-#include <mach/syscon.h>
+#include <linux/of.h>
+
+/* APP side SYSCON registers */
+/* CLK Control Register 16bit (R/W) */
+#define U300_SYSCON_CCR						(0x0000)
+#define U300_SYSCON_CCR_I2S1_USE_VCXO				(0x0040)
+#define U300_SYSCON_CCR_I2S0_USE_VCXO				(0x0020)
+#define U300_SYSCON_CCR_TURN_VCXO_ON				(0x0008)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK			(0x0007)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER		(0x04)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW			(0x03)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE		(0x02)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH			(0x01)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST			(0x00)
+/* CLK Status Register 16bit (R/W) */
+#define U300_SYSCON_CSR						(0x0004)
+#define U300_SYSCON_CSR_PLL208_LOCK_IND				(0x0002)
+#define U300_SYSCON_CSR_PLL13_LOCK_IND				(0x0001)
+/* Reset lines for SLOW devices 16bit (R/W) */
+#define U300_SYSCON_RSR						(0x0014)
+#define U300_SYSCON_RSR_PPM_RESET_EN				(0x0200)
+#define U300_SYSCON_RSR_ACC_TMR_RESET_EN			(0x0100)
+#define U300_SYSCON_RSR_APP_TMR_RESET_EN			(0x0080)
+#define U300_SYSCON_RSR_RTC_RESET_EN				(0x0040)
+#define U300_SYSCON_RSR_KEYPAD_RESET_EN				(0x0020)
+#define U300_SYSCON_RSR_GPIO_RESET_EN				(0x0010)
+#define U300_SYSCON_RSR_EH_RESET_EN				(0x0008)
+#define U300_SYSCON_RSR_BTR_RESET_EN				(0x0004)
+#define U300_SYSCON_RSR_UART_RESET_EN				(0x0002)
+#define U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN			(0x0001)
+/* Reset lines for FAST devices 16bit (R/W) */
+#define U300_SYSCON_RFR						(0x0018)
+#define U300_SYSCON_RFR_UART1_RESET_ENABLE			(0x0080)
+#define U300_SYSCON_RFR_SPI_RESET_ENABLE			(0x0040)
+#define U300_SYSCON_RFR_MMC_RESET_ENABLE			(0x0020)
+#define U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE			(0x0010)
+#define U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE			(0x0008)
+#define U300_SYSCON_RFR_I2C1_RESET_ENABLE			(0x0004)
+#define U300_SYSCON_RFR_I2C0_RESET_ENABLE			(0x0002)
+#define U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE		(0x0001)
+/* Reset lines for the rest of the peripherals 16bit (R/W) */
+#define U300_SYSCON_RRR						(0x001c)
+#define U300_SYSCON_RRR_CDS_RESET_EN				(0x4000)
+#define U300_SYSCON_RRR_ISP_RESET_EN				(0x2000)
+#define U300_SYSCON_RRR_INTCON_RESET_EN				(0x1000)
+#define U300_SYSCON_RRR_MSPRO_RESET_EN				(0x0800)
+#define U300_SYSCON_RRR_XGAM_RESET_EN				(0x0100)
+#define U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN			(0x0080)
+#define U300_SYSCON_RRR_NANDIF_RESET_EN				(0x0040)
+#define U300_SYSCON_RRR_EMIF_RESET_EN				(0x0020)
+#define U300_SYSCON_RRR_DMAC_RESET_EN				(0x0010)
+#define U300_SYSCON_RRR_CPU_RESET_EN				(0x0008)
+#define U300_SYSCON_RRR_APEX_RESET_EN				(0x0004)
+#define U300_SYSCON_RRR_AHB_RESET_EN				(0x0002)
+#define U300_SYSCON_RRR_AAIF_RESET_EN				(0x0001)
+/* Clock enable for SLOW peripherals 16bit (R/W) */
+#define U300_SYSCON_CESR					(0x0020)
+#define U300_SYSCON_CESR_PPM_CLK_EN				(0x0200)
+#define U300_SYSCON_CESR_ACC_TMR_CLK_EN				(0x0100)
+#define U300_SYSCON_CESR_APP_TMR_CLK_EN				(0x0080)
+#define U300_SYSCON_CESR_KEYPAD_CLK_EN				(0x0040)
+#define U300_SYSCON_CESR_GPIO_CLK_EN				(0x0010)
+#define U300_SYSCON_CESR_EH_CLK_EN				(0x0008)
+#define U300_SYSCON_CESR_BTR_CLK_EN				(0x0004)
+#define U300_SYSCON_CESR_UART_CLK_EN				(0x0002)
+#define U300_SYSCON_CESR_SLOW_BRIDGE_CLK_EN			(0x0001)
+/* Clock enable for FAST peripherals 16bit (R/W) */
+#define U300_SYSCON_CEFR					(0x0024)
+#define U300_SYSCON_CEFR_UART1_CLK_EN				(0x0200)
+#define U300_SYSCON_CEFR_I2S1_CORE_CLK_EN			(0x0100)
+#define U300_SYSCON_CEFR_I2S0_CORE_CLK_EN			(0x0080)
+#define U300_SYSCON_CEFR_SPI_CLK_EN				(0x0040)
+#define U300_SYSCON_CEFR_MMC_CLK_EN				(0x0020)
+#define U300_SYSCON_CEFR_I2S1_CLK_EN				(0x0010)
+#define U300_SYSCON_CEFR_I2S0_CLK_EN				(0x0008)
+#define U300_SYSCON_CEFR_I2C1_CLK_EN				(0x0004)
+#define U300_SYSCON_CEFR_I2C0_CLK_EN				(0x0002)
+#define U300_SYSCON_CEFR_FAST_BRIDGE_CLK_EN			(0x0001)
+/* Clock enable for the rest of the peripherals 16bit (R/W) */
+#define U300_SYSCON_CERR					(0x0028)
+#define U300_SYSCON_CERR_CDS_CLK_EN				(0x2000)
+#define U300_SYSCON_CERR_ISP_CLK_EN				(0x1000)
+#define U300_SYSCON_CERR_MSPRO_CLK_EN				(0x0800)
+#define U300_SYSCON_CERR_AHB_SUBSYS_BRIDGE_CLK_EN		(0x0400)
+#define U300_SYSCON_CERR_SEMI_CLK_EN				(0x0200)
+#define U300_SYSCON_CERR_XGAM_CLK_EN				(0x0100)
+#define U300_SYSCON_CERR_VIDEO_ENC_CLK_EN			(0x0080)
+#define U300_SYSCON_CERR_NANDIF_CLK_EN				(0x0040)
+#define U300_SYSCON_CERR_EMIF_CLK_EN				(0x0020)
+#define U300_SYSCON_CERR_DMAC_CLK_EN				(0x0010)
+#define U300_SYSCON_CERR_CPU_CLK_EN				(0x0008)
+#define U300_SYSCON_CERR_APEX_CLK_EN				(0x0004)
+#define U300_SYSCON_CERR_AHB_CLK_EN				(0x0002)
+#define U300_SYSCON_CERR_AAIF_CLK_EN				(0x0001)
+/* Single block clock enable 16bit (-/W) */
+#define U300_SYSCON_SBCER					(0x002c)
+#define U300_SYSCON_SBCER_PPM_CLK_EN				(0x0009)
+#define U300_SYSCON_SBCER_ACC_TMR_CLK_EN			(0x0008)
+#define U300_SYSCON_SBCER_APP_TMR_CLK_EN			(0x0007)
+#define U300_SYSCON_SBCER_KEYPAD_CLK_EN				(0x0006)
+#define U300_SYSCON_SBCER_GPIO_CLK_EN				(0x0004)
+#define U300_SYSCON_SBCER_EH_CLK_EN				(0x0003)
+#define U300_SYSCON_SBCER_BTR_CLK_EN				(0x0002)
+#define U300_SYSCON_SBCER_UART_CLK_EN				(0x0001)
+#define U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN			(0x0000)
+#define U300_SYSCON_SBCER_UART1_CLK_EN				(0x0019)
+#define U300_SYSCON_SBCER_I2S1_CORE_CLK_EN			(0x0018)
+#define U300_SYSCON_SBCER_I2S0_CORE_CLK_EN			(0x0017)
+#define U300_SYSCON_SBCER_SPI_CLK_EN				(0x0016)
+#define U300_SYSCON_SBCER_MMC_CLK_EN				(0x0015)
+#define U300_SYSCON_SBCER_I2S1_CLK_EN				(0x0014)
+#define U300_SYSCON_SBCER_I2S0_CLK_EN				(0x0013)
+#define U300_SYSCON_SBCER_I2C1_CLK_EN				(0x0012)
+#define U300_SYSCON_SBCER_I2C0_CLK_EN				(0x0011)
+#define U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN			(0x0010)
+#define U300_SYSCON_SBCER_CDS_CLK_EN				(0x002D)
+#define U300_SYSCON_SBCER_ISP_CLK_EN				(0x002C)
+#define U300_SYSCON_SBCER_MSPRO_CLK_EN				(0x002B)
+#define U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN		(0x002A)
+#define U300_SYSCON_SBCER_SEMI_CLK_EN				(0x0029)
+#define U300_SYSCON_SBCER_XGAM_CLK_EN				(0x0028)
+#define U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN			(0x0027)
+#define U300_SYSCON_SBCER_NANDIF_CLK_EN				(0x0026)
+#define U300_SYSCON_SBCER_EMIF_CLK_EN				(0x0025)
+#define U300_SYSCON_SBCER_DMAC_CLK_EN				(0x0024)
+#define U300_SYSCON_SBCER_CPU_CLK_EN				(0x0023)
+#define U300_SYSCON_SBCER_APEX_CLK_EN				(0x0022)
+#define U300_SYSCON_SBCER_AHB_CLK_EN				(0x0021)
+#define U300_SYSCON_SBCER_AAIF_CLK_EN				(0x0020)
+/* Single block clock disable 16bit (-/W) */
+#define U300_SYSCON_SBCDR					(0x0030)
+/* Same values as above for SBCER */
+/* Clock force SLOW peripherals 16bit (R/W) */
+#define U300_SYSCON_CFSR					(0x003c)
+#define U300_SYSCON_CFSR_PPM_CLK_FORCE_EN			(0x0200)
+#define U300_SYSCON_CFSR_ACC_TMR_CLK_FORCE_EN			(0x0100)
+#define U300_SYSCON_CFSR_APP_TMR_CLK_FORCE_EN			(0x0080)
+#define U300_SYSCON_CFSR_KEYPAD_CLK_FORCE_EN			(0x0020)
+#define U300_SYSCON_CFSR_GPIO_CLK_FORCE_EN			(0x0010)
+#define U300_SYSCON_CFSR_EH_CLK_FORCE_EN			(0x0008)
+#define U300_SYSCON_CFSR_BTR_CLK_FORCE_EN			(0x0004)
+#define U300_SYSCON_CFSR_UART_CLK_FORCE_EN			(0x0002)
+#define U300_SYSCON_CFSR_SLOW_BRIDGE_CLK_FORCE_EN		(0x0001)
+/* Clock force FAST peripherals 16bit (R/W) */
+#define U300_SYSCON_CFFR					(0x40)
+/* Values not defined. Define if you want to use them. */
+/* Clock force the rest of the peripherals 16bit (R/W) */
+#define U300_SYSCON_CFRR					(0x44)
+#define U300_SYSCON_CFRR_CDS_CLK_FORCE_EN			(0x2000)
+#define U300_SYSCON_CFRR_ISP_CLK_FORCE_EN			(0x1000)
+#define U300_SYSCON_CFRR_MSPRO_CLK_FORCE_EN			(0x0800)
+#define U300_SYSCON_CFRR_AHB_SUBSYS_BRIDGE_CLK_FORCE_EN		(0x0400)
+#define U300_SYSCON_CFRR_SEMI_CLK_FORCE_EN			(0x0200)
+#define U300_SYSCON_CFRR_XGAM_CLK_FORCE_EN			(0x0100)
+#define U300_SYSCON_CFRR_VIDEO_ENC_CLK_FORCE_EN			(0x0080)
+#define U300_SYSCON_CFRR_NANDIF_CLK_FORCE_EN			(0x0040)
+#define U300_SYSCON_CFRR_EMIF_CLK_FORCE_EN			(0x0020)
+#define U300_SYSCON_CFRR_DMAC_CLK_FORCE_EN			(0x0010)
+#define U300_SYSCON_CFRR_CPU_CLK_FORCE_EN			(0x0008)
+#define U300_SYSCON_CFRR_APEX_CLK_FORCE_EN			(0x0004)
+#define U300_SYSCON_CFRR_AHB_CLK_FORCE_EN			(0x0002)
+#define U300_SYSCON_CFRR_AAIF_CLK_FORCE_EN			(0x0001)
+/* PLL208 Frequency Control 16bit (R/W) */
+#define U300_SYSCON_PFCR					(0x48)
+#define U300_SYSCON_PFCR_DPLL_MULT_NUM				(0x000F)
+/* Power Management Control 16bit (R/W) */
+#define U300_SYSCON_PMCR					(0x50)
+#define U300_SYSCON_PMCR_DCON_ENABLE				(0x0002)
+#define U300_SYSCON_PMCR_PWR_MGNT_ENABLE			(0x0001)
+/* Reset Out 16bit (R/W) */
+#define U300_SYSCON_RCR						(0x6c)
+#define U300_SYSCON_RCR_RESOUT0_RST_N_DISABLE			(0x0001)
+/* EMIF Slew Rate Control 16bit (R/W) */
+#define U300_SYSCON_SRCLR					(0x70)
+#define U300_SYSCON_SRCLR_MASK					(0x03FF)
+#define U300_SYSCON_SRCLR_VALUE					(0x03FF)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_B			(0x0200)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_A			(0x0100)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_B			(0x0080)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_A			(0x0040)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_B			(0x0020)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_A			(0x0010)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_B			(0x0008)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_A			(0x0004)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_B			(0x0002)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_A			(0x0001)
+/* EMIF Clock Control Register 16bit (R/W) */
+#define U300_SYSCON_ECCR					(0x0078)
+#define U300_SYSCON_ECCR_MASK					(0x000F)
+#define U300_SYSCON_ECCR_EMIF_1_STATIC_CLK_EN_N_DISABLE		(0x0008)
+#define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE	(0x0004)
+#define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE		(0x0002)
+#define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE		(0x0001)
+/* MMC/MSPRO frequency divider register 0 16bit (R/W) */
+#define U300_SYSCON_MMF0R					(0x90)
+#define U300_SYSCON_MMF0R_MASK					(0x00FF)
+#define U300_SYSCON_MMF0R_FREQ_0_HIGH_MASK			(0x00F0)
+#define U300_SYSCON_MMF0R_FREQ_0_LOW_MASK			(0x000F)
+/* MMC/MSPRO frequency divider register 1 16bit (R/W) */
+#define U300_SYSCON_MMF1R					(0x94)
+#define U300_SYSCON_MMF1R_MASK					(0x00FF)
+#define U300_SYSCON_MMF1R_FREQ_1_HIGH_MASK			(0x00F0)
+#define U300_SYSCON_MMF1R_FREQ_1_LOW_MASK			(0x000F)
+/* Clock control for the MMC and MSPRO blocks 16bit (R/W) */
+#define U300_SYSCON_MMCR					(0x9C)
+#define U300_SYSCON_MMCR_MASK					(0x0003)
+#define U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE			(0x0002)
+#define U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE			(0x0001)
+/* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */
+#define U300_SYSCON_S0CCR					(0x120)
+#define U300_SYSCON_S0CCR_FIELD_MASK				(0x43FF)
+#define U300_SYSCON_S0CCR_CLOCK_REQ				(0x4000)
+#define U300_SYSCON_S0CCR_CLOCK_REQ_MONITOR			(0x2000)
+#define U300_SYSCON_S0CCR_CLOCK_INV				(0x0200)
+#define U300_SYSCON_S0CCR_CLOCK_FREQ_MASK			(0x01E0)
+#define U300_SYSCON_S0CCR_CLOCK_SELECT_MASK			(0x001E)
+#define U300_SYSCON_S0CCR_CLOCK_ENABLE				(0x0001)
+#define U300_SYSCON_S0CCR_SEL_MCLK				(0x8<<1)
+#define U300_SYSCON_S0CCR_SEL_ACC_FSM_CLK			(0xA<<1)
+#define U300_SYSCON_S0CCR_SEL_PLL60_48_CLK			(0xC<<1)
+#define U300_SYSCON_S0CCR_SEL_PLL60_60_CLK			(0xD<<1)
+#define U300_SYSCON_S0CCR_SEL_ACC_PLL208_CLK			(0xE<<1)
+#define U300_SYSCON_S0CCR_SEL_APP_PLL13_CLK			(0x0<<1)
+#define U300_SYSCON_S0CCR_SEL_APP_FSM_CLK			(0x2<<1)
+#define U300_SYSCON_S0CCR_SEL_RTC_CLK				(0x4<<1)
+#define U300_SYSCON_S0CCR_SEL_APP_PLL208_CLK			(0x6<<1)
+/* SYS_1_CLK_CONTROL second clock control 16 bit (R/W) */
+#define U300_SYSCON_S1CCR					(0x124)
+#define U300_SYSCON_S1CCR_FIELD_MASK				(0x43FF)
+#define U300_SYSCON_S1CCR_CLOCK_REQ				(0x4000)
+#define U300_SYSCON_S1CCR_CLOCK_REQ_MONITOR			(0x2000)
+#define U300_SYSCON_S1CCR_CLOCK_INV				(0x0200)
+#define U300_SYSCON_S1CCR_CLOCK_FREQ_MASK			(0x01E0)
+#define U300_SYSCON_S1CCR_CLOCK_SELECT_MASK			(0x001E)
+#define U300_SYSCON_S1CCR_CLOCK_ENABLE				(0x0001)
+#define U300_SYSCON_S1CCR_SEL_MCLK				(0x8<<1)
+#define U300_SYSCON_S1CCR_SEL_ACC_FSM_CLK			(0xA<<1)
+#define U300_SYSCON_S1CCR_SEL_PLL60_48_CLK			(0xC<<1)
+#define U300_SYSCON_S1CCR_SEL_PLL60_60_CLK			(0xD<<1)
+#define U300_SYSCON_S1CCR_SEL_ACC_PLL208_CLK			(0xE<<1)
+#define U300_SYSCON_S1CCR_SEL_ACC_PLL13_CLK			(0x0<<1)
+#define U300_SYSCON_S1CCR_SEL_APP_FSM_CLK			(0x2<<1)
+#define U300_SYSCON_S1CCR_SEL_RTC_CLK				(0x4<<1)
+#define U300_SYSCON_S1CCR_SEL_APP_PLL208_CLK			(0x6<<1)
+/* SYS_2_CLK_CONTROL third clock contol 16 bit (R/W) */
+#define U300_SYSCON_S2CCR					(0x128)
+#define U300_SYSCON_S2CCR_FIELD_MASK				(0xC3FF)
+#define U300_SYSCON_S2CCR_CLK_STEAL				(0x8000)
+#define U300_SYSCON_S2CCR_CLOCK_REQ				(0x4000)
+#define U300_SYSCON_S2CCR_CLOCK_REQ_MONITOR			(0x2000)
+#define U300_SYSCON_S2CCR_CLOCK_INV				(0x0200)
+#define U300_SYSCON_S2CCR_CLOCK_FREQ_MASK			(0x01E0)
+#define U300_SYSCON_S2CCR_CLOCK_SELECT_MASK			(0x001E)
+#define U300_SYSCON_S2CCR_CLOCK_ENABLE				(0x0001)
+#define U300_SYSCON_S2CCR_SEL_MCLK				(0x8<<1)
+#define U300_SYSCON_S2CCR_SEL_ACC_FSM_CLK			(0xA<<1)
+#define U300_SYSCON_S2CCR_SEL_PLL60_48_CLK			(0xC<<1)
+#define U300_SYSCON_S2CCR_SEL_PLL60_60_CLK			(0xD<<1)
+#define U300_SYSCON_S2CCR_SEL_ACC_PLL208_CLK			(0xE<<1)
+#define U300_SYSCON_S2CCR_SEL_ACC_PLL13_CLK			(0x0<<1)
+#define U300_SYSCON_S2CCR_SEL_APP_FSM_CLK			(0x2<<1)
+#define U300_SYSCON_S2CCR_SEL_RTC_CLK				(0x4<<1)
+#define U300_SYSCON_S2CCR_SEL_APP_PLL208_CLK			(0x6<<1)
+/* SC_PLL_IRQ_CONTROL 16bit (R/W) */
+#define U300_SYSCON_PICR					(0x0130)
+#define U300_SYSCON_PICR_MASK					(0x00FF)
+#define U300_SYSCON_PICR_FORCE_PLL208_LOCK_LOW_ENABLE		(0x0080)
+#define U300_SYSCON_PICR_FORCE_PLL208_LOCK_HIGH_ENABLE		(0x0040)
+#define U300_SYSCON_PICR_FORCE_PLL13_LOCK_LOW_ENABLE		(0x0020)
+#define U300_SYSCON_PICR_FORCE_PLL13_LOCK_HIGH_ENABLE		(0x0010)
+#define U300_SYSCON_PICR_IRQMASK_PLL13_UNLOCK_ENABLE		(0x0008)
+#define U300_SYSCON_PICR_IRQMASK_PLL13_LOCK_ENABLE		(0x0004)
+#define U300_SYSCON_PICR_IRQMASK_PLL208_UNLOCK_ENABLE		(0x0002)
+#define U300_SYSCON_PICR_IRQMASK_PLL208_LOCK_ENABLE		(0x0001)
+/* SC_PLL_IRQ_STATUS 16 bit (R/-) */
+#define U300_SYSCON_PISR					(0x0134)
+#define U300_SYSCON_PISR_MASK					(0x000F)
+#define U300_SYSCON_PISR_PLL13_UNLOCK_IND			(0x0008)
+#define U300_SYSCON_PISR_PLL13_LOCK_IND				(0x0004)
+#define U300_SYSCON_PISR_PLL208_UNLOCK_IND			(0x0002)
+#define U300_SYSCON_PISR_PLL208_LOCK_IND			(0x0001)
+/* SC_PLL_IRQ_CLEAR 16 bit (-/W) */
+#define U300_SYSCON_PICLR					(0x0138)
+#define U300_SYSCON_PICLR_MASK					(0x000F)
+#define U300_SYSCON_PICLR_RWMASK				(0x0000)
+#define U300_SYSCON_PICLR_PLL13_UNLOCK_SC			(0x0008)
+#define U300_SYSCON_PICLR_PLL13_LOCK_SC				(0x0004)
+#define U300_SYSCON_PICLR_PLL208_UNLOCK_SC			(0x0002)
+#define U300_SYSCON_PICLR_PLL208_LOCK_SC			(0x0001)
+/* Clock activity observability register 0 */
+#define U300_SYSCON_C0OAR					(0x140)
+#define U300_SYSCON_C0OAR_MASK					(0xFFFF)
+#define U300_SYSCON_C0OAR_VALUE					(0xFFFF)
+#define U300_SYSCON_C0OAR_BT_H_CLK				(0x8000)
+#define U300_SYSCON_C0OAR_ASPB_P_CLK				(0x4000)
+#define U300_SYSCON_C0OAR_APP_SEMI_H_CLK			(0x2000)
+#define U300_SYSCON_C0OAR_APP_SEMI_CLK				(0x1000)
+#define U300_SYSCON_C0OAR_APP_MMC_MSPRO_CLK			(0x0800)
+#define U300_SYSCON_C0OAR_APP_I2S1_CLK				(0x0400)
+#define U300_SYSCON_C0OAR_APP_I2S0_CLK				(0x0200)
+#define U300_SYSCON_C0OAR_APP_CPU_CLK				(0x0100)
+#define U300_SYSCON_C0OAR_APP_52_CLK				(0x0080)
+#define U300_SYSCON_C0OAR_APP_208_CLK				(0x0040)
+#define U300_SYSCON_C0OAR_APP_104_CLK				(0x0020)
+#define U300_SYSCON_C0OAR_APEX_CLK				(0x0010)
+#define U300_SYSCON_C0OAR_AHPB_M_H_CLK				(0x0008)
+#define U300_SYSCON_C0OAR_AHB_CLK				(0x0004)
+#define U300_SYSCON_C0OAR_AFPB_P_CLK				(0x0002)
+#define U300_SYSCON_C0OAR_AAIF_CLK				(0x0001)
+/* Clock activity observability register 1 */
+#define U300_SYSCON_C1OAR					(0x144)
+#define U300_SYSCON_C1OAR_MASK					(0x3FFE)
+#define U300_SYSCON_C1OAR_VALUE					(0x3FFE)
+#define U300_SYSCON_C1OAR_NFIF_F_CLK				(0x2000)
+#define U300_SYSCON_C1OAR_MSPRO_CLK				(0x1000)
+#define U300_SYSCON_C1OAR_MMC_P_CLK				(0x0800)
+#define U300_SYSCON_C1OAR_MMC_CLK				(0x0400)
+#define U300_SYSCON_C1OAR_KP_P_CLK				(0x0200)
+#define U300_SYSCON_C1OAR_I2C1_P_CLK				(0x0100)
+#define U300_SYSCON_C1OAR_I2C0_P_CLK				(0x0080)
+#define U300_SYSCON_C1OAR_GPIO_CLK				(0x0040)
+#define U300_SYSCON_C1OAR_EMIF_MPMC_CLK				(0x0020)
+#define U300_SYSCON_C1OAR_EMIF_H_CLK				(0x0010)
+#define U300_SYSCON_C1OAR_EVHIST_CLK				(0x0008)
+#define U300_SYSCON_C1OAR_PPM_CLK				(0x0004)
+#define U300_SYSCON_C1OAR_DMA_CLK				(0x0002)
+/* Clock activity observability register 2 */
+#define U300_SYSCON_C2OAR					(0x148)
+#define U300_SYSCON_C2OAR_MASK					(0x0FFF)
+#define U300_SYSCON_C2OAR_VALUE					(0x0FFF)
+#define U300_SYSCON_C2OAR_XGAM_CDI_CLK				(0x0800)
+#define U300_SYSCON_C2OAR_XGAM_CLK				(0x0400)
+#define U300_SYSCON_C2OAR_VC_H_CLK				(0x0200)
+#define U300_SYSCON_C2OAR_VC_CLK				(0x0100)
+#define U300_SYSCON_C2OAR_UA_P_CLK				(0x0080)
+#define U300_SYSCON_C2OAR_TMR1_CLK				(0x0040)
+#define U300_SYSCON_C2OAR_TMR0_CLK				(0x0020)
+#define U300_SYSCON_C2OAR_SPI_P_CLK				(0x0010)
+#define U300_SYSCON_C2OAR_PCM_I2S1_CORE_CLK			(0x0008)
+#define U300_SYSCON_C2OAR_PCM_I2S1_CLK				(0x0004)
+#define U300_SYSCON_C2OAR_PCM_I2S0_CORE_CLK			(0x0002)
+#define U300_SYSCON_C2OAR_PCM_I2S0_CLK				(0x0001)
+
 
 /*
  * The clocking hierarchy currently looks like this.
@@ -386,6 +728,213 @@ syscon_clk_register(struct device *dev,
 	return clk;
 }
 
+#define U300_CLK_TYPE_SLOW 0
+#define U300_CLK_TYPE_FAST 1
+#define U300_CLK_TYPE_REST 2
+
+/**
+ * struct u300_clock - defines the bits and pieces for a certain clock
+ * @type: the clock type, slow fast or rest
+ * @id: the bit in the slow/fast/rest register for this clock
+ * @hw_ctrld: whether the clock is hardware controlled
+ * @clk_val: a value to poke in the one-write enable/disable registers
+ */
+struct u300_clock {
+	u8 type;
+	u8 id;
+	bool hw_ctrld;
+	u16 clk_val;
+};
+
+struct u300_clock const __initconst u300_clk_lookup[] = {
+	{
+		.type = U300_CLK_TYPE_REST,
+		.id = 3,
+		.hw_ctrld = true,
+		.clk_val = U300_SYSCON_SBCER_CPU_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_REST,
+		.id = 4,
+		.hw_ctrld = true,
+		.clk_val = U300_SYSCON_SBCER_DMAC_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_REST,
+		.id = 5,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_EMIF_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_REST,
+		.id = 6,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_NANDIF_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_REST,
+		.id = 8,
+		.hw_ctrld = true,
+		.clk_val = U300_SYSCON_SBCER_XGAM_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_REST,
+		.id = 9,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_SEMI_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_REST,
+		.id = 10,
+		.hw_ctrld = true,
+		.clk_val = U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_REST,
+		.id = 12,
+		.hw_ctrld = false,
+		/* INTCON: cannot be enabled, just taken out of reset */
+		.clk_val = 0xFFFFU,
+	},
+	{
+		.type = U300_CLK_TYPE_FAST,
+		.id = 0,
+		.hw_ctrld = true,
+		.clk_val = U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_FAST,
+		.id = 1,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_I2C0_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_FAST,
+		.id = 2,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_I2C1_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_FAST,
+		.id = 5,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_MMC_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_FAST,
+		.id = 6,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_SPI_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_SLOW,
+		.id = 0,
+		.hw_ctrld = true,
+		.clk_val = U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_SLOW,
+		.id = 1,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_UART_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_SLOW,
+		.id = 4,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_GPIO_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_SLOW,
+		.id = 6,
+		.hw_ctrld = true,
+		/* No clock enable register bit */
+		.clk_val = 0xFFFFU,
+	},
+	{
+		.type = U300_CLK_TYPE_SLOW,
+		.id = 7,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_APP_TMR_CLK_EN,
+	},
+	{
+		.type = U300_CLK_TYPE_SLOW,
+		.id = 8,
+		.hw_ctrld = false,
+		.clk_val = U300_SYSCON_SBCER_ACC_TMR_CLK_EN,
+	},
+};
+
+static void __init of_u300_syscon_clk_init(struct device_node *np)
+{
+	struct clk *clk = ERR_PTR(-EINVAL);
+	const char *clk_name = np->name;
+	const char *parent_name;
+	void __iomem *res_reg;
+	void __iomem *en_reg;
+	u32 clk_type;
+	u32 clk_id;
+	int i;
+
+	if (of_property_read_u32(np, "clock-type", &clk_type)) {
+		pr_err("%s: syscon clock \"%s\" missing clock-type property\n",
+		       __func__, clk_name);
+		return;
+	}
+	if (of_property_read_u32(np, "clock-id", &clk_id)) {
+		pr_err("%s: syscon clock \"%s\" missing clock-id property\n",
+		       __func__, clk_name);
+		return;
+	}
+	parent_name = of_clk_get_parent_name(np, 0);
+
+	switch (clk_type) {
+	case U300_CLK_TYPE_SLOW:
+		res_reg = syscon_vbase + U300_SYSCON_RSR;
+		en_reg = syscon_vbase + U300_SYSCON_CESR;
+		break;
+	case U300_CLK_TYPE_FAST:
+		res_reg = syscon_vbase + U300_SYSCON_RFR;
+		en_reg = syscon_vbase + U300_SYSCON_CEFR;
+		break;
+	case U300_CLK_TYPE_REST:
+		res_reg = syscon_vbase + U300_SYSCON_RRR;
+		en_reg = syscon_vbase + U300_SYSCON_CERR;
+		break;
+	default:
+		pr_err("unknown clock type %x specified\n", clk_type);
+		return;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(u300_clk_lookup); i++) {
+		const struct u300_clock *u3clk = &u300_clk_lookup[i];
+
+		if (u3clk->type == clk_type && u3clk->id == clk_id)
+			clk = syscon_clk_register(NULL,
+						  clk_name, parent_name,
+						  0, u3clk->hw_ctrld,
+						  res_reg, u3clk->id,
+						  en_reg, u3clk->id,
+						  u3clk->clk_val);
+	}
+
+	if (!IS_ERR(clk)) {
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
+
+		/*
+		 * Some few system clocks - device tree does not
+		 * represent clocks without a corresponding device node.
+		 * for now we add these three clocks here.
+		 */
+		if (clk_type == U300_CLK_TYPE_REST && clk_id == 5)
+			clk_register_clkdev(clk, NULL, "pl172");
+		if (clk_type == U300_CLK_TYPE_REST && clk_id == 9)
+			clk_register_clkdev(clk, NULL, "semi");
+		if (clk_type == U300_CLK_TYPE_REST && clk_id == 12)
+			clk_register_clkdev(clk, NULL, "intcon");
+	}
+}
+
 /**
  * struct clk_mclk - U300 MCLK clock (MMC/SD clock)
  * @hw: corresponding clock hardware entry
@@ -590,10 +1139,41 @@ mclk_clk_register(struct device *dev, co
 	return clk;
 }
 
+static void __init of_u300_syscon_mclk_init(struct device_node *np)
+{
+	struct clk *clk = ERR_PTR(-EINVAL);
+	const char *clk_name = np->name;
+	const char *parent_name;
+
+	parent_name = of_clk_get_parent_name(np, 0);
+	clk = mclk_clk_register(NULL, clk_name, parent_name, false);
+	if (!IS_ERR(clk))
+		of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+
+static const __initconst struct of_device_id u300_clk_match[] = {
+	{
+		.compatible = "fixed-clock",
+		.data = of_fixed_clk_setup,
+	},
+	{
+		.compatible = "fixed-factor-clock",
+		.data = of_fixed_factor_clk_setup,
+	},
+	{
+		.compatible = "stericsson,u300-syscon-clk",
+		.data = of_u300_syscon_clk_init,
+	},
+	{
+		.compatible = "stericsson,u300-syscon-mclk",
+		.data = of_u300_syscon_mclk_init,
+	},
+};
+
+
 void __init u300_clk_init(void __iomem *base)
 {
 	u16 val;
-	struct clk *clk;
 
 	syscon_vbase = base;
 
@@ -610,137 +1190,5 @@ void __init u300_clk_init(void __iomem *
 	val |= U300_SYSCON_PMCR_PWR_MGNT_ENABLE;
 	writew(val, syscon_vbase + U300_SYSCON_PMCR);
 
-	/* These are always available (RTC and PLL13) */
-	clk = clk_register_fixed_rate(NULL, "app_32_clk", NULL,
-				      CLK_IS_ROOT, 32768);
-	/* The watchdog sits directly on the 32 kHz clock */
-	clk_register_clkdev(clk, NULL, "coh901327_wdog");
-	clk = clk_register_fixed_rate(NULL, "pll13", NULL,
-				      CLK_IS_ROOT, 13000000);
-
-	/* These derive from PLL208 */
-	clk = clk_register_fixed_rate(NULL, "pll208", NULL,
-				      CLK_IS_ROOT, 208000000);
-	clk = clk_register_fixed_factor(NULL, "app_208_clk", "pll208",
-					0, 1, 1);
-	clk = clk_register_fixed_factor(NULL, "app_104_clk", "pll208",
-					0, 1, 2);
-	clk = clk_register_fixed_factor(NULL, "app_52_clk", "pll208",
-					0, 1, 4);
-	/* The 52 MHz is divided down to 26 MHz */
-	clk = clk_register_fixed_factor(NULL, "app_26_clk", "app_52_clk",
-					0, 1, 2);
-
-	/* Directly on the AMBA interconnect */
-	clk = syscon_clk_register(NULL, "cpu_clk", "app_208_clk", 0, true,
-				  syscon_vbase + U300_SYSCON_RRR, 3,
-				  syscon_vbase + U300_SYSCON_CERR, 3,
-				  U300_SYSCON_SBCER_CPU_CLK_EN);
-	clk = syscon_clk_register(NULL, "dmac_clk", "app_52_clk", 0, true,
-				  syscon_vbase + U300_SYSCON_RRR, 4,
-				  syscon_vbase + U300_SYSCON_CERR, 4,
-				  U300_SYSCON_SBCER_DMAC_CLK_EN);
-	clk_register_clkdev(clk, NULL, "dma");
-	clk = syscon_clk_register(NULL, "fsmc_clk", "app_52_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RRR, 6,
-				  syscon_vbase + U300_SYSCON_CERR, 6,
-				  U300_SYSCON_SBCER_NANDIF_CLK_EN);
-	clk_register_clkdev(clk, NULL, "fsmc-nand");
-	clk = syscon_clk_register(NULL, "xgam_clk", "app_52_clk", 0, true,
-				  syscon_vbase + U300_SYSCON_RRR, 8,
-				  syscon_vbase + U300_SYSCON_CERR, 8,
-				  U300_SYSCON_SBCER_XGAM_CLK_EN);
-	clk_register_clkdev(clk, NULL, "xgam");
-	clk = syscon_clk_register(NULL, "semi_clk", "app_104_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RRR, 9,
-				  syscon_vbase + U300_SYSCON_CERR, 9,
-				  U300_SYSCON_SBCER_SEMI_CLK_EN);
-	clk_register_clkdev(clk, NULL, "semi");
-
-	/* AHB bridge clocks */
-	clk = syscon_clk_register(NULL, "ahb_subsys_clk", "app_52_clk", 0, true,
-				  syscon_vbase + U300_SYSCON_RRR, 10,
-				  syscon_vbase + U300_SYSCON_CERR, 10,
-				  U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN);
-	clk = syscon_clk_register(NULL, "intcon_clk", "ahb_subsys_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RRR, 12,
-				  syscon_vbase + U300_SYSCON_CERR, 12,
-				  /* Cannot be enabled, just taken out of reset */
-				  0xFFFFU);
-	clk_register_clkdev(clk, NULL, "intcon");
-	clk = syscon_clk_register(NULL, "emif_clk", "ahb_subsys_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RRR, 5,
-				  syscon_vbase + U300_SYSCON_CERR, 5,
-				  U300_SYSCON_SBCER_EMIF_CLK_EN);
-	clk_register_clkdev(clk, NULL, "pl172");
-
-	/* FAST bridge clocks */
-	clk = syscon_clk_register(NULL, "fast_clk", "app_26_clk", 0, true,
-				  syscon_vbase + U300_SYSCON_RFR, 0,
-				  syscon_vbase + U300_SYSCON_CEFR, 0,
-				  U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN);
-	clk = syscon_clk_register(NULL, "i2c0_p_clk", "fast_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RFR, 1,
-				  syscon_vbase + U300_SYSCON_CEFR, 1,
-				  U300_SYSCON_SBCER_I2C0_CLK_EN);
-	clk_register_clkdev(clk, NULL, "stu300.0");
-	clk = syscon_clk_register(NULL, "i2c1_p_clk", "fast_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RFR, 2,
-				  syscon_vbase + U300_SYSCON_CEFR, 2,
-				  U300_SYSCON_SBCER_I2C1_CLK_EN);
-	clk_register_clkdev(clk, NULL, "stu300.1");
-	clk = syscon_clk_register(NULL, "mmc_p_clk", "fast_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RFR, 5,
-				  syscon_vbase + U300_SYSCON_CEFR, 5,
-				  U300_SYSCON_SBCER_MMC_CLK_EN);
-	clk_register_clkdev(clk, "apb_pclk", "mmci");
-	clk = syscon_clk_register(NULL, "spi_p_clk", "fast_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RFR, 6,
-				  syscon_vbase + U300_SYSCON_CEFR, 6,
-				  U300_SYSCON_SBCER_SPI_CLK_EN);
-	/* The SPI has no external clock for the outward bus, uses the pclk */
-	clk_register_clkdev(clk, NULL, "pl022");
-	clk_register_clkdev(clk, "apb_pclk", "pl022");
-
-	/* SLOW bridge clocks */
-	clk = syscon_clk_register(NULL, "slow_clk", "pll13", 0, true,
-				  syscon_vbase + U300_SYSCON_RSR, 0,
-				  syscon_vbase + U300_SYSCON_CESR, 0,
-				  U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN);
-	clk = syscon_clk_register(NULL, "uart0_clk", "slow_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RSR, 1,
-				  syscon_vbase + U300_SYSCON_CESR, 1,
-				  U300_SYSCON_SBCER_UART_CLK_EN);
-	/* Same clock is used for APB and outward bus */
-	clk_register_clkdev(clk, NULL, "uart0");
-	clk_register_clkdev(clk, "apb_pclk", "uart0");
-	clk = syscon_clk_register(NULL, "gpio_clk", "slow_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RSR, 4,
-				  syscon_vbase + U300_SYSCON_CESR, 4,
-				  U300_SYSCON_SBCER_GPIO_CLK_EN);
-	clk_register_clkdev(clk, NULL, "u300-gpio");
-	clk = syscon_clk_register(NULL, "keypad_clk", "slow_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RSR, 5,
-				  syscon_vbase + U300_SYSCON_CESR, 6,
-				  U300_SYSCON_SBCER_KEYPAD_CLK_EN);
-	clk_register_clkdev(clk, NULL, "coh901461-keypad");
-	clk = syscon_clk_register(NULL, "rtc_clk", "slow_clk", 0, true,
-				  syscon_vbase + U300_SYSCON_RSR, 6,
-				  /* No clock enable register bit */
-				  NULL, 0, 0xFFFFU);
-	clk_register_clkdev(clk, NULL, "rtc-coh901331");
-	clk = syscon_clk_register(NULL, "app_tmr_clk", "slow_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RSR, 7,
-				  syscon_vbase + U300_SYSCON_CESR, 7,
-				  U300_SYSCON_SBCER_APP_TMR_CLK_EN);
-	clk_register_clkdev(clk, NULL, "apptimer");
-	clk = syscon_clk_register(NULL, "acc_tmr_clk", "slow_clk", 0, false,
-				  syscon_vbase + U300_SYSCON_RSR, 8,
-				  syscon_vbase + U300_SYSCON_CESR, 8,
-				  U300_SYSCON_SBCER_ACC_TMR_CLK_EN);
-	clk_register_clkdev(clk, NULL, "timer");
-
-	/* Then this special MMC/SD clock */
-	clk = mclk_clk_register(NULL, "mmc_clk", "mmc_p_clk", false);
-	clk_register_clkdev(clk, NULL, "mmci");
+	of_clk_init(u300_clk_match);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-vt8500.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-vt8500.c
--- linux-libre-3.10-gnu/drivers/clk/clk-vt8500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-vt8500.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,6 +42,7 @@ struct clk_device {
 #define PLL_TYPE_VT8500		0
 #define PLL_TYPE_WM8650		1
 #define PLL_TYPE_WM8750		2
+#define PLL_TYPE_WM8850		3
 
 struct clk_pll {
 	struct clk_hw	hw;
@@ -156,10 +157,6 @@ static int vt8500_dclk_set_rate(struct c
 
 	divisor =  parent_rate / rate;
 
-	/* If prate / rate would be decimal, incr the divisor */
-	if (rate * divisor < parent_rate)
-		divisor++;
-
 	if (divisor == cdev->div_mask + 1)
 		divisor = 0;
 
@@ -327,6 +324,15 @@ CLK_OF_DECLARE(vt8500_device, "via,vt850
 #define WM8750_BITS_TO_VAL(f, m, d1, d2)				\
 		((f << 24) | ((m - 1) << 16) | ((d1 - 1) << 8) | d2)
 
+/* Helper macros for PLL_WM8850 */
+#define WM8850_PLL_MUL(x)	((((x >> 16) & 0x7F) + 1) * 2)
+#define WM8850_PLL_DIV(x)	((((x >> 8) & 1) + 1) * (1 << (x & 3)))
+
+#define WM8850_BITS_TO_FREQ(r, m, d1, d2)				\
+				(r * ((m + 1) * 2) / ((d1+1) * (1 << d2)))
+
+#define WM8850_BITS_TO_VAL(m, d1, d2)					\
+		((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2)
 
 static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
 				u32 *multiplier, u32 *prediv)
@@ -466,6 +472,49 @@ static void wm8750_find_pll_bits(unsigne
 	*divisor2 = best_div2;
 }
 
+static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
+				u32 *multiplier, u32 *divisor1, u32 *divisor2)
+{
+	u32 mul, div1, div2;
+	u32 best_mul, best_div1, best_div2;
+	unsigned long tclk, rate_err, best_err;
+
+	best_err = (unsigned long)-1;
+
+	/* Find the closest match (lower or equal to requested) */
+	for (div1 = 1; div1 >= 0; div1--)
+		for (div2 = 3; div2 >= 0; div2--)
+			for (mul = 0; mul <= 127; mul++) {
+				tclk = parent_rate * ((mul + 1) * 2) /
+						((div1 + 1) * (1 << div2));
+				if (tclk > rate)
+					continue;
+				/* error will always be +ve */
+				rate_err = rate - tclk;
+				if (rate_err == 0) {
+					*multiplier = mul;
+					*divisor1 = div1;
+					*divisor2 = div2;
+					return;
+				}
+
+				if (rate_err < best_err) {
+					best_err = rate_err;
+					best_mul = mul;
+					best_div1 = div1;
+					best_div2 = div2;
+				}
+			}
+
+	/* if we got here, it wasn't an exact match */
+	pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
+							rate - best_err);
+
+	*multiplier = best_mul;
+	*divisor1 = best_div1;
+	*divisor2 = best_div2;
+}
+
 static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate)
 {
@@ -489,6 +538,10 @@ static int vtwm_pll_set_rate(struct clk_
 		wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2);
 		pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2);
 		break;
+	case PLL_TYPE_WM8850:
+		wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
+		pll_val = WM8850_BITS_TO_VAL(mul, div1, div2);
+		break;
 	default:
 		pr_err("%s: invalid pll type\n", __func__);
 		return 0;
@@ -525,6 +578,10 @@ static long vtwm_pll_round_rate(struct c
 		wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2);
 		round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2);
 		break;
+	case PLL_TYPE_WM8850:
+		wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2);
+		round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2);
+		break;
 	default:
 		round_rate = 0;
 	}
@@ -552,6 +609,10 @@ static unsigned long vtwm_pll_recalc_rat
 		pll_freq = parent_rate * WM8750_PLL_MUL(pll_val);
 		pll_freq /= WM8750_PLL_DIV(pll_val);
 		break;
+	case PLL_TYPE_WM8850:
+		pll_freq = parent_rate * WM8850_PLL_MUL(pll_val);
+		pll_freq /= WM8850_PLL_DIV(pll_val);
+		break;
 	default:
 		pll_freq = 0;
 	}
@@ -628,6 +689,12 @@ static void __init wm8750_pll_init(struc
 }
 CLK_OF_DECLARE(wm8750_pll, "wm,wm8750-pll-clock", wm8750_pll_init);
 
+static void __init wm8850_pll_init(struct device_node *node)
+{
+	vtwm_pll_clk_init(node, PLL_TYPE_WM8850);
+}
+CLK_OF_DECLARE(wm8850_pll, "wm,wm8850-pll-clock", wm8850_pll_init);
+
 void __init vtwm_clk_init(void __iomem *base)
 {
 	if (!base)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-wm831x.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-wm831x.c
--- linux-libre-3.10-gnu/drivers/clk/clk-wm831x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-wm831x.c	2013-08-25 20:43:22.000000000 -0400
@@ -97,7 +97,7 @@ static int wm831x_fll_prepare(struct clk
 	struct wm831x *wm831x = clkdata->wm831x;
 	int ret;
 
-	ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_2,
+	ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_1,
 			      WM831X_FLL_ENA, WM831X_FLL_ENA);
 	if (ret != 0)
 		dev_crit(wm831x->dev, "Failed to enable FLL: %d\n", ret);
@@ -114,9 +114,9 @@ static void wm831x_fll_unprepare(struct
 	struct wm831x *wm831x = clkdata->wm831x;
 	int ret;
 
-	ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_2, WM831X_FLL_ENA, 0);
+	ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_1, WM831X_FLL_ENA, 0);
 	if (ret != 0)
-		dev_crit(wm831x->dev, "Failed to disaable FLL: %d\n", ret);
+		dev_crit(wm831x->dev, "Failed to disable FLL: %d\n", ret);
 }
 
 static unsigned long wm831x_fll_recalc_rate(struct clk_hw *hw,
@@ -299,8 +299,8 @@ static void wm831x_clkout_unprepare(stru
 }
 
 static const char *wm831x_clkout_parents[] = {
-	"xtal",
 	"fll",
+	"xtal",
 };
 
 static u8 wm831x_clkout_get_parent(struct clk_hw *hw)
@@ -318,9 +318,9 @@ static u8 wm831x_clkout_get_parent(struc
 	}
 
 	if (ret & WM831X_CLKOUT_SRC)
-		return 0;
-	else
 		return 1;
+	else
+		return 0;
 }
 
 static int wm831x_clkout_set_parent(struct clk_hw *hw, u8 parent)
@@ -384,7 +384,7 @@ static int wm831x_clk_probe(struct platf
 	if (IS_ERR(clkdata->clkout))
 		return PTR_ERR(clkdata->clkout);
 
-	dev_set_drvdata(&pdev->dev, clkdata);
+	platform_set_drvdata(pdev, clkdata);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/clk-zynq.c linux-libre-3.11-rc7-gnu/drivers/clk/clk-zynq.c
--- linux-libre-3.10-gnu/drivers/clk/clk-zynq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/clk-zynq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,378 +0,0 @@
-/*
- * Copyright (c) 2012 National Instruments
- *
- * Josh Cartwright <josh.cartwright@ni.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/clk-provider.h>
-#include <linux/clk/zynq.h>
-
-static void __iomem *slcr_base;
-
-struct zynq_pll_clk {
-	struct clk_hw	hw;
-	void __iomem	*pll_ctrl;
-	void __iomem	*pll_cfg;
-};
-
-#define to_zynq_pll_clk(hw)	container_of(hw, struct zynq_pll_clk, hw)
-
-#define CTRL_PLL_FDIV(x)	((x) >> 12)
-
-static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
-					  unsigned long parent_rate)
-{
-	struct zynq_pll_clk *pll = to_zynq_pll_clk(hw);
-	return parent_rate * CTRL_PLL_FDIV(ioread32(pll->pll_ctrl));
-}
-
-static const struct clk_ops zynq_pll_clk_ops = {
-	.recalc_rate	= zynq_pll_recalc_rate,
-};
-
-static void __init zynq_pll_clk_setup(struct device_node *np)
-{
-	struct clk_init_data init;
-	struct zynq_pll_clk *pll;
-	const char *parent_name;
-	struct clk *clk;
-	u32 regs[2];
-	int ret;
-
-	ret = of_property_read_u32_array(np, "reg", regs, ARRAY_SIZE(regs));
-	if (WARN_ON(ret))
-		return;
-
-	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-	if (WARN_ON(!pll))
-		return;
-
-	pll->pll_ctrl = slcr_base + regs[0];
-	pll->pll_cfg  = slcr_base + regs[1];
-
-	of_property_read_string(np, "clock-output-names", &init.name);
-
-	init.ops = &zynq_pll_clk_ops;
-	parent_name = of_clk_get_parent_name(np, 0);
-	init.parent_names = &parent_name;
-	init.num_parents = 1;
-
-	pll->hw.init = &init;
-
-	clk = clk_register(NULL, &pll->hw);
-	if (WARN_ON(IS_ERR(clk)))
-		return;
-
-	ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
-	if (WARN_ON(ret))
-		return;
-}
-CLK_OF_DECLARE(zynq_pll, "xlnx,zynq-pll", zynq_pll_clk_setup);
-
-struct zynq_periph_clk {
-	struct clk_hw		hw;
-	struct clk_onecell_data	onecell_data;
-	struct clk		*gates[2];
-	void __iomem		*clk_ctrl;
-	spinlock_t		clkact_lock;
-};
-
-#define to_zynq_periph_clk(hw)	container_of(hw, struct zynq_periph_clk, hw)
-
-static const u8 periph_clk_parent_map[] = {
-	0, 0, 1, 2
-};
-#define PERIPH_CLK_CTRL_SRC(x)	(periph_clk_parent_map[((x) & 0x30) >> 4])
-#define PERIPH_CLK_CTRL_DIV(x)	(((x) & 0x3F00) >> 8)
-
-static unsigned long zynq_periph_recalc_rate(struct clk_hw *hw,
-					     unsigned long parent_rate)
-{
-	struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
-	return parent_rate / PERIPH_CLK_CTRL_DIV(ioread32(periph->clk_ctrl));
-}
-
-static u8 zynq_periph_get_parent(struct clk_hw *hw)
-{
-	struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
-	return PERIPH_CLK_CTRL_SRC(ioread32(periph->clk_ctrl));
-}
-
-static const struct clk_ops zynq_periph_clk_ops = {
-	.recalc_rate	= zynq_periph_recalc_rate,
-	.get_parent	= zynq_periph_get_parent,
-};
-
-static void __init zynq_periph_clk_setup(struct device_node *np)
-{
-	struct zynq_periph_clk *periph;
-	const char *parent_names[3];
-	struct clk_init_data init;
-	int clk_num = 0, err;
-	const char *name;
-	struct clk *clk;
-	u32 reg;
-	int i;
-
-	err = of_property_read_u32(np, "reg", &reg);
-	if (WARN_ON(err))
-		return;
-
-	periph = kzalloc(sizeof(*periph), GFP_KERNEL);
-	if (WARN_ON(!periph))
-		return;
-
-	periph->clk_ctrl = slcr_base + reg;
-	spin_lock_init(&periph->clkact_lock);
-
-	init.name = np->name;
-	init.ops = &zynq_periph_clk_ops;
-	for (i = 0; i < ARRAY_SIZE(parent_names); i++)
-		parent_names[i] = of_clk_get_parent_name(np, i);
-	init.parent_names = parent_names;
-	init.num_parents = ARRAY_SIZE(parent_names);
-
-	periph->hw.init = &init;
-
-	clk = clk_register(NULL, &periph->hw);
-	if (WARN_ON(IS_ERR(clk)))
-		return;
-
-	err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
-	if (WARN_ON(err))
-		return;
-
-	err = of_property_read_string_index(np, "clock-output-names", 0,
-					    &name);
-	if (WARN_ON(err))
-		return;
-
-	periph->gates[0] = clk_register_gate(NULL, name, np->name, 0,
-					     periph->clk_ctrl, 0, 0,
-					     &periph->clkact_lock);
-	if (WARN_ON(IS_ERR(periph->gates[0])))
-		return;
-	clk_num++;
-
-	/* some periph clks have 2 downstream gates */
-	err = of_property_read_string_index(np, "clock-output-names", 1,
-					    &name);
-	if (err != -ENODATA) {
-		periph->gates[1] = clk_register_gate(NULL, name, np->name, 0,
-						     periph->clk_ctrl, 1, 0,
-						     &periph->clkact_lock);
-		if (WARN_ON(IS_ERR(periph->gates[1])))
-			return;
-		clk_num++;
-	}
-
-	periph->onecell_data.clks = periph->gates;
-	periph->onecell_data.clk_num = clk_num;
-
-	err = of_clk_add_provider(np, of_clk_src_onecell_get,
-				  &periph->onecell_data);
-	if (WARN_ON(err))
-		return;
-}
-CLK_OF_DECLARE(zynq_periph, "xlnx,zynq-periph-clock", zynq_periph_clk_setup);
-
-/* CPU Clock domain is modelled as a mux with 4 children subclks, whose
- * derivative rates depend on CLK_621_TRUE
- */
-
-struct zynq_cpu_clk {
-	struct clk_hw		hw;
-	struct clk_onecell_data	onecell_data;
-	struct clk		*subclks[4];
-	void __iomem		*clk_ctrl;
-	spinlock_t		clkact_lock;
-};
-
-#define to_zynq_cpu_clk(hw)	container_of(hw, struct zynq_cpu_clk, hw)
-
-static const u8 zynq_cpu_clk_parent_map[] = {
-	1, 1, 2, 0
-};
-#define CPU_CLK_SRCSEL(x)	(zynq_cpu_clk_parent_map[(((x) & 0x30) >> 4)])
-#define CPU_CLK_CTRL_DIV(x)	(((x) & 0x3F00) >> 8)
-
-static u8 zynq_cpu_clk_get_parent(struct clk_hw *hw)
-{
-	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
-	return CPU_CLK_SRCSEL(ioread32(cpuclk->clk_ctrl));
-}
-
-static unsigned long zynq_cpu_clk_recalc_rate(struct clk_hw *hw,
-					      unsigned long parent_rate)
-{
-	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
-	return parent_rate / CPU_CLK_CTRL_DIV(ioread32(cpuclk->clk_ctrl));
-}
-
-static const struct clk_ops zynq_cpu_clk_ops = {
-	.get_parent	= zynq_cpu_clk_get_parent,
-	.recalc_rate	= zynq_cpu_clk_recalc_rate,
-};
-
-struct zynq_cpu_subclk {
-	struct clk_hw	hw;
-	void __iomem	*clk_621;
-	enum {
-		CPU_SUBCLK_6X4X,
-		CPU_SUBCLK_3X2X,
-		CPU_SUBCLK_2X,
-		CPU_SUBCLK_1X,
-	} which;
-};
-
-#define CLK_621_TRUE(x)	((x) & 1)
-
-#define to_zynq_cpu_subclk(hw)	container_of(hw, struct zynq_cpu_subclk, hw);
-
-static unsigned long zynq_cpu_subclk_recalc_rate(struct clk_hw *hw,
-						 unsigned long parent_rate)
-{
-	unsigned long uninitialized_var(rate);
-	struct zynq_cpu_subclk *subclk;
-	bool is_621;
-
-	subclk = to_zynq_cpu_subclk(hw)
-	is_621 = CLK_621_TRUE(ioread32(subclk->clk_621));
-
-	switch (subclk->which) {
-	case CPU_SUBCLK_6X4X:
-		rate = parent_rate;
-		break;
-	case CPU_SUBCLK_3X2X:
-		rate = parent_rate / 2;
-		break;
-	case CPU_SUBCLK_2X:
-		rate = parent_rate / (is_621 ? 3 : 2);
-		break;
-	case CPU_SUBCLK_1X:
-		rate = parent_rate / (is_621 ? 6 : 4);
-		break;
-	};
-
-	return rate;
-}
-
-static const struct clk_ops zynq_cpu_subclk_ops = {
-	.recalc_rate	= zynq_cpu_subclk_recalc_rate,
-};
-
-static struct clk *zynq_cpu_subclk_setup(struct device_node *np, u8 which,
-					 void __iomem *clk_621)
-{
-	struct zynq_cpu_subclk *subclk;
-	struct clk_init_data init;
-	struct clk *clk;
-	int err;
-
-	err = of_property_read_string_index(np, "clock-output-names",
-					    which, &init.name);
-	if (WARN_ON(err))
-		goto err_read_output_name;
-
-	subclk = kzalloc(sizeof(*subclk), GFP_KERNEL);
-	if (!subclk)
-		goto err_subclk_alloc;
-
-	subclk->clk_621 = clk_621;
-	subclk->which = which;
-
-	init.ops = &zynq_cpu_subclk_ops;
-	init.parent_names = &np->name;
-	init.num_parents = 1;
-
-	subclk->hw.init = &init;
-
-	clk = clk_register(NULL, &subclk->hw);
-	if (WARN_ON(IS_ERR(clk)))
-		goto err_clk_register;
-
-	return clk;
-
-err_clk_register:
-	kfree(subclk);
-err_subclk_alloc:
-err_read_output_name:
-	return ERR_PTR(-EINVAL);
-}
-
-static void __init zynq_cpu_clk_setup(struct device_node *np)
-{
-	struct zynq_cpu_clk *cpuclk;
-	const char *parent_names[3];
-	struct clk_init_data init;
-	void __iomem *clk_621;
-	struct clk *clk;
-	u32 reg[2];
-	int err;
-	int i;
-
-	err = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
-	if (WARN_ON(err))
-		return;
-
-	cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
-	if (WARN_ON(!cpuclk))
-		return;
-
-	cpuclk->clk_ctrl = slcr_base + reg[0];
-	clk_621 = slcr_base + reg[1];
-	spin_lock_init(&cpuclk->clkact_lock);
-
-	init.name = np->name;
-	init.ops = &zynq_cpu_clk_ops;
-	for (i = 0; i < ARRAY_SIZE(parent_names); i++)
-		parent_names[i] = of_clk_get_parent_name(np, i);
-	init.parent_names = parent_names;
-	init.num_parents = ARRAY_SIZE(parent_names);
-
-	cpuclk->hw.init = &init;
-
-	clk = clk_register(NULL, &cpuclk->hw);
-	if (WARN_ON(IS_ERR(clk)))
-		return;
-
-	err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
-	if (WARN_ON(err))
-		return;
-
-	for (i = 0; i < 4; i++) {
-		cpuclk->subclks[i] = zynq_cpu_subclk_setup(np, i, clk_621);
-		if (WARN_ON(IS_ERR(cpuclk->subclks[i])))
-			return;
-	}
-
-	cpuclk->onecell_data.clks = cpuclk->subclks;
-	cpuclk->onecell_data.clk_num = i;
-
-	err = of_clk_add_provider(np, of_clk_src_onecell_get,
-				  &cpuclk->onecell_data);
-	if (WARN_ON(err))
-		return;
-}
-CLK_OF_DECLARE(zynq_cpu, "xlnx,zynq-cpu-clock", zynq_cpu_clk_setup);
-
-void __init xilinx_zynq_clocks_init(void __iomem *slcr)
-{
-	slcr_base = slcr;
-	of_clk_init(NULL);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/Kconfig linux-libre-3.11-rc7-gnu/drivers/clk/Kconfig
--- linux-libre-3.10-gnu/drivers/clk/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -42,7 +42,7 @@ config COMMON_CLK_WM831X
 
 config COMMON_CLK_VERSATILE
 	bool "Clock driver for ARM Reference designs"
-	depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS
+	depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64
 	---help---
           Supports clocking on ARM Reference designs:
 	  - Integrator/AP and Integrator/CP
@@ -58,7 +58,6 @@ config COMMON_CLK_MAX77686
 config COMMON_CLK_SI5351
 	tristate "Clock driver for SiLabs 5351A/B/C"
 	depends on I2C
-	depends on OF
 	select REGMAP_I2C
 	select RATIONAL
 	---help---
@@ -81,6 +80,13 @@ config COMMON_CLK_AXI_CLKGEN
 	  Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
 	  FPGAs. It is commonly used in Analog Devices' reference designs.
 
+config CLK_PPC_CORENET
+	bool "Clock driver for PowerPC corenet platforms"
+	depends on PPC_E500MC && OF
+	---help---
+	  This adds the clock driver support for Freescale PowerPC corenet
+	  platforms using common clock framework.
+
 endmenu
 
 source "drivers/clk/mvebu/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/Makefile linux-libre-3.11-rc7-gnu/drivers/clk/Makefile
--- linux-libre-3.10-gnu/drivers/clk/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -13,21 +13,23 @@ obj-$(CONFIG_COMMON_CLK)	+= clk-composit
 obj-$(CONFIG_ARCH_BCM2835)	+= clk-bcm2835.o
 obj-$(CONFIG_ARCH_NOMADIK)	+= clk-nomadik.o
 obj-$(CONFIG_ARCH_HIGHBANK)	+= clk-highbank.o
+obj-$(CONFIG_ARCH_NSPIRE)	+= clk-nspire.o
 obj-$(CONFIG_ARCH_MXS)		+= mxs/
 obj-$(CONFIG_ARCH_SOCFPGA)	+= socfpga/
 obj-$(CONFIG_PLAT_SPEAR)	+= spear/
 obj-$(CONFIG_ARCH_U300)		+= clk-u300.o
 obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
-obj-$(CONFIG_ARCH_PRIMA2)	+= clk-prima2.o
+obj-$(CONFIG_ARCH_SIRF)		+= clk-prima2.o
 obj-$(CONFIG_PLAT_ORION)	+= mvebu/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)		+= mmp/
 endif
 obj-$(CONFIG_MACH_LOONGSON1)	+= clk-ls1x.o
+obj-$(CONFIG_ARCH_ROCKCHIP)	+= rockchip/
 obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/
 obj-$(CONFIG_ARCH_U8500)	+= ux500/
 obj-$(CONFIG_ARCH_VT8500)	+= clk-vt8500.o
-obj-$(CONFIG_ARCH_ZYNQ)		+= clk-zynq.o
+obj-$(CONFIG_ARCH_ZYNQ)		+= zynq/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_PLAT_SAMSUNG)	+= samsung/
 
@@ -39,3 +41,4 @@ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-w
 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
 obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
 obj-$(CONFIG_CLK_TWL6040)	+= clk-twl6040.o
+obj-$(CONFIG_CLK_PPC_CORENET)	+= clk-ppc-corenet.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/armada-370.c linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/armada-370.c
--- linux-libre-3.10-gnu/drivers/clk/mvebu/armada-370.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/armada-370.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,176 @@
+/*
+ * Marvell Armada 370 SoC clocks
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include "common.h"
+
+/*
+ * Core Clocks
+ */
+
+#define SARL				0	/* Low part [0:31] */
+#define	 SARL_A370_PCLK_FREQ_OPT	11
+#define	 SARL_A370_PCLK_FREQ_OPT_MASK	0xF
+#define	 SARL_A370_FAB_FREQ_OPT		15
+#define	 SARL_A370_FAB_FREQ_OPT_MASK	0x1F
+#define	 SARL_A370_TCLK_FREQ_OPT	20
+#define	 SARL_A370_TCLK_FREQ_OPT_MASK	0x1
+
+enum { A370_CPU_TO_NBCLK, A370_CPU_TO_HCLK, A370_CPU_TO_DRAMCLK };
+
+static const struct coreclk_ratio __initconst a370_coreclk_ratios[] = {
+	{ .id = A370_CPU_TO_NBCLK, .name = "nbclk" },
+	{ .id = A370_CPU_TO_HCLK, .name = "hclk" },
+	{ .id = A370_CPU_TO_DRAMCLK, .name = "dramclk" },
+};
+
+static const u32 __initconst a370_tclk_freqs[] = {
+	16600000,
+	20000000,
+};
+
+static u32 __init a370_get_tclk_freq(void __iomem *sar)
+{
+	u8 tclk_freq_select = 0;
+
+	tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) &
+			    SARL_A370_TCLK_FREQ_OPT_MASK);
+	return a370_tclk_freqs[tclk_freq_select];
+}
+
+static const u32 __initconst a370_cpu_freqs[] = {
+	400000000,
+	533000000,
+	667000000,
+	800000000,
+	1000000000,
+	1067000000,
+	1200000000,
+};
+
+static u32 __init a370_get_cpu_freq(void __iomem *sar)
+{
+	u32 cpu_freq;
+	u8 cpu_freq_select = 0;
+
+	cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) &
+			   SARL_A370_PCLK_FREQ_OPT_MASK);
+	if (cpu_freq_select >= ARRAY_SIZE(a370_cpu_freqs)) {
+		pr_err("CPU freq select unsupported %d\n", cpu_freq_select);
+		cpu_freq = 0;
+	} else
+		cpu_freq = a370_cpu_freqs[cpu_freq_select];
+
+	return cpu_freq;
+}
+
+static const int __initconst a370_nbclk_ratios[32][2] = {
+	{0, 1}, {1, 2}, {2, 2}, {2, 2},
+	{1, 2}, {1, 2}, {1, 1}, {2, 3},
+	{0, 1}, {1, 2}, {2, 4}, {0, 1},
+	{1, 2}, {0, 1}, {0, 1}, {2, 2},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{2, 3}, {0, 1}, {0, 1}, {0, 1},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int __initconst a370_hclk_ratios[32][2] = {
+	{0, 1}, {1, 2}, {2, 6}, {2, 3},
+	{1, 3}, {1, 4}, {1, 2}, {2, 6},
+	{0, 1}, {1, 6}, {2, 10}, {0, 1},
+	{1, 4}, {0, 1}, {0, 1}, {2, 5},
+	{0, 1}, {0, 1}, {0, 1}, {1, 2},
+	{2, 6}, {0, 1}, {0, 1}, {0, 1},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int __initconst a370_dramclk_ratios[32][2] = {
+	{0, 1}, {1, 2}, {2, 3}, {2, 3},
+	{1, 3}, {1, 2}, {1, 2}, {2, 6},
+	{0, 1}, {1, 3}, {2, 5}, {0, 1},
+	{1, 4}, {0, 1}, {0, 1}, {2, 5},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{2, 3}, {0, 1}, {0, 1}, {0, 1},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static void __init a370_get_clk_ratio(
+	void __iomem *sar, int id, int *mult, int *div)
+{
+	u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) &
+		SARL_A370_FAB_FREQ_OPT_MASK);
+
+	switch (id) {
+	case A370_CPU_TO_NBCLK:
+		*mult = a370_nbclk_ratios[opt][0];
+		*div = a370_nbclk_ratios[opt][1];
+		break;
+	case A370_CPU_TO_HCLK:
+		*mult = a370_hclk_ratios[opt][0];
+		*div = a370_hclk_ratios[opt][1];
+		break;
+	case A370_CPU_TO_DRAMCLK:
+		*mult = a370_dramclk_ratios[opt][0];
+		*div = a370_dramclk_ratios[opt][1];
+		break;
+	}
+}
+
+static const struct coreclk_soc_desc a370_coreclks = {
+	.get_tclk_freq = a370_get_tclk_freq,
+	.get_cpu_freq = a370_get_cpu_freq,
+	.get_clk_ratio = a370_get_clk_ratio,
+	.ratios = a370_coreclk_ratios,
+	.num_ratios = ARRAY_SIZE(a370_coreclk_ratios),
+};
+
+static void __init a370_coreclk_init(struct device_node *np)
+{
+	mvebu_coreclk_setup(np, &a370_coreclks);
+}
+CLK_OF_DECLARE(a370_core_clk, "marvell,armada-370-core-clock",
+	       a370_coreclk_init);
+
+/*
+ * Clock Gating Control
+ */
+
+static const struct clk_gating_soc_desc __initconst a370_gating_desc[] = {
+	{ "audio", NULL, 0, 0 },
+	{ "pex0_en", NULL, 1, 0 },
+	{ "pex1_en", NULL,  2, 0 },
+	{ "ge1", NULL, 3, 0 },
+	{ "ge0", NULL, 4, 0 },
+	{ "pex0", "pex0_en", 5, 0 },
+	{ "pex1", "pex1_en", 9, 0 },
+	{ "sata0", NULL, 15, 0 },
+	{ "sdio", NULL, 17, 0 },
+	{ "tdm", NULL, 25, 0 },
+	{ "ddr", NULL, 28, CLK_IGNORE_UNUSED },
+	{ "sata1", NULL, 30, 0 },
+	{ }
+};
+
+static void __init a370_clk_gating_init(struct device_node *np)
+{
+	mvebu_clk_gating_setup(np, a370_gating_desc);
+}
+CLK_OF_DECLARE(a370_clk_gating, "marvell,armada-370-gating-clock",
+	       a370_clk_gating_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/armada-xp.c linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/armada-xp.c
--- linux-libre-3.10-gnu/drivers/clk/mvebu/armada-xp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/armada-xp.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,210 @@
+/*
+ * Marvell Armada XP SoC clocks
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include "common.h"
+
+/*
+ * Core Clocks
+ *
+ * Armada XP Sample At Reset is a 64 bit bitfiled split in two
+ * register of 32 bits
+ */
+
+#define SARL				0	/* Low part [0:31] */
+#define	 SARL_AXP_PCLK_FREQ_OPT		21
+#define	 SARL_AXP_PCLK_FREQ_OPT_MASK	0x7
+#define	 SARL_AXP_FAB_FREQ_OPT		24
+#define	 SARL_AXP_FAB_FREQ_OPT_MASK	0xF
+#define SARH				4	/* High part [32:63] */
+#define	 SARH_AXP_PCLK_FREQ_OPT		(52-32)
+#define	 SARH_AXP_PCLK_FREQ_OPT_MASK	0x1
+#define	 SARH_AXP_PCLK_FREQ_OPT_SHIFT	3
+#define	 SARH_AXP_FAB_FREQ_OPT		(51-32)
+#define	 SARH_AXP_FAB_FREQ_OPT_MASK	0x1
+#define	 SARH_AXP_FAB_FREQ_OPT_SHIFT	4
+
+enum { AXP_CPU_TO_NBCLK, AXP_CPU_TO_HCLK, AXP_CPU_TO_DRAMCLK };
+
+static const struct coreclk_ratio __initconst axp_coreclk_ratios[] = {
+	{ .id = AXP_CPU_TO_NBCLK, .name = "nbclk" },
+	{ .id = AXP_CPU_TO_HCLK, .name = "hclk" },
+	{ .id = AXP_CPU_TO_DRAMCLK, .name = "dramclk" },
+};
+
+/* Armada XP TCLK frequency is fixed to 250MHz */
+static u32 __init axp_get_tclk_freq(void __iomem *sar)
+{
+	return 250000000;
+}
+
+static const u32 __initconst axp_cpu_freqs[] = {
+	1000000000,
+	1066000000,
+	1200000000,
+	1333000000,
+	1500000000,
+	1666000000,
+	1800000000,
+	2000000000,
+	667000000,
+	0,
+	800000000,
+	1600000000,
+};
+
+static u32 __init axp_get_cpu_freq(void __iomem *sar)
+{
+	u32 cpu_freq;
+	u8 cpu_freq_select = 0;
+
+	cpu_freq_select = ((readl(sar + SARL) >> SARL_AXP_PCLK_FREQ_OPT) &
+			   SARL_AXP_PCLK_FREQ_OPT_MASK);
+	/*
+	 * The upper bit is not contiguous to the other ones and
+	 * located in the high part of the SAR registers
+	 */
+	cpu_freq_select |= (((readl(sar + SARH) >> SARH_AXP_PCLK_FREQ_OPT) &
+	     SARH_AXP_PCLK_FREQ_OPT_MASK) << SARH_AXP_PCLK_FREQ_OPT_SHIFT);
+	if (cpu_freq_select >= ARRAY_SIZE(axp_cpu_freqs)) {
+		pr_err("CPU freq select unsupported: %d\n", cpu_freq_select);
+		cpu_freq = 0;
+	} else
+		cpu_freq = axp_cpu_freqs[cpu_freq_select];
+
+	return cpu_freq;
+}
+
+static const int __initconst axp_nbclk_ratios[32][2] = {
+	{0, 1}, {1, 2}, {2, 2}, {2, 2},
+	{1, 2}, {1, 2}, {1, 1}, {2, 3},
+	{0, 1}, {1, 2}, {2, 4}, {0, 1},
+	{1, 2}, {0, 1}, {0, 1}, {2, 2},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{2, 3}, {0, 1}, {0, 1}, {0, 1},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int __initconst axp_hclk_ratios[32][2] = {
+	{0, 1}, {1, 2}, {2, 6}, {2, 3},
+	{1, 3}, {1, 4}, {1, 2}, {2, 6},
+	{0, 1}, {1, 6}, {2, 10}, {0, 1},
+	{1, 4}, {0, 1}, {0, 1}, {2, 5},
+	{0, 1}, {0, 1}, {0, 1}, {1, 2},
+	{2, 6}, {0, 1}, {0, 1}, {0, 1},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static const int __initconst axp_dramclk_ratios[32][2] = {
+	{0, 1}, {1, 2}, {2, 3}, {2, 3},
+	{1, 3}, {1, 2}, {1, 2}, {2, 6},
+	{0, 1}, {1, 3}, {2, 5}, {0, 1},
+	{1, 4}, {0, 1}, {0, 1}, {2, 5},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{2, 3}, {0, 1}, {0, 1}, {0, 1},
+	{0, 1}, {0, 1}, {0, 1}, {1, 1},
+	{0, 1}, {0, 1}, {0, 1}, {0, 1},
+};
+
+static void __init axp_get_clk_ratio(
+	void __iomem *sar, int id, int *mult, int *div)
+{
+	u32 opt = ((readl(sar + SARL) >> SARL_AXP_FAB_FREQ_OPT) &
+	      SARL_AXP_FAB_FREQ_OPT_MASK);
+	/*
+	 * The upper bit is not contiguous to the other ones and
+	 * located in the high part of the SAR registers
+	 */
+	opt |= (((readl(sar + SARH) >> SARH_AXP_FAB_FREQ_OPT) &
+		 SARH_AXP_FAB_FREQ_OPT_MASK) << SARH_AXP_FAB_FREQ_OPT_SHIFT);
+
+	switch (id) {
+	case AXP_CPU_TO_NBCLK:
+		*mult = axp_nbclk_ratios[opt][0];
+		*div = axp_nbclk_ratios[opt][1];
+		break;
+	case AXP_CPU_TO_HCLK:
+		*mult = axp_hclk_ratios[opt][0];
+		*div = axp_hclk_ratios[opt][1];
+		break;
+	case AXP_CPU_TO_DRAMCLK:
+		*mult = axp_dramclk_ratios[opt][0];
+		*div = axp_dramclk_ratios[opt][1];
+		break;
+	}
+}
+
+static const struct coreclk_soc_desc axp_coreclks = {
+	.get_tclk_freq = axp_get_tclk_freq,
+	.get_cpu_freq = axp_get_cpu_freq,
+	.get_clk_ratio = axp_get_clk_ratio,
+	.ratios = axp_coreclk_ratios,
+	.num_ratios = ARRAY_SIZE(axp_coreclk_ratios),
+};
+
+static void __init axp_coreclk_init(struct device_node *np)
+{
+	mvebu_coreclk_setup(np, &axp_coreclks);
+}
+CLK_OF_DECLARE(axp_core_clk, "marvell,armada-xp-core-clock",
+	       axp_coreclk_init);
+
+/*
+ * Clock Gating Control
+ */
+
+static const struct clk_gating_soc_desc __initconst axp_gating_desc[] = {
+	{ "audio", NULL, 0, 0 },
+	{ "ge3", NULL, 1, 0 },
+	{ "ge2", NULL,  2, 0 },
+	{ "ge1", NULL, 3, 0 },
+	{ "ge0", NULL, 4, 0 },
+	{ "pex00", NULL, 5, 0 },
+	{ "pex01", NULL, 6, 0 },
+	{ "pex02", NULL, 7, 0 },
+	{ "pex03", NULL, 8, 0 },
+	{ "pex10", NULL, 9, 0 },
+	{ "pex11", NULL, 10, 0 },
+	{ "pex12", NULL, 11, 0 },
+	{ "pex13", NULL, 12, 0 },
+	{ "bp", NULL, 13, 0 },
+	{ "sata0lnk", NULL, 14, 0 },
+	{ "sata0", "sata0lnk", 15, 0 },
+	{ "lcd", NULL, 16, 0 },
+	{ "sdio", NULL, 17, 0 },
+	{ "usb0", NULL, 18, 0 },
+	{ "usb1", NULL, 19, 0 },
+	{ "usb2", NULL, 20, 0 },
+	{ "xor0", NULL, 22, 0 },
+	{ "crypto", NULL, 23, 0 },
+	{ "tdm", NULL, 25, 0 },
+	{ "pex20", NULL, 26, 0 },
+	{ "pex30", NULL, 27, 0 },
+	{ "xor1", NULL, 28, 0 },
+	{ "sata1lnk", NULL, 29, 0 },
+	{ "sata1", "sata1lnk", 30, 0 },
+	{ }
+};
+
+static void __init axp_clk_gating_init(struct device_node *np)
+{
+	mvebu_clk_gating_setup(np, axp_gating_desc);
+}
+CLK_OF_DECLARE(axp_clk_gating, "marvell,armada-xp-gating-clock",
+	       axp_clk_gating_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/clk.c linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk.c
--- linux-libre-3.10-gnu/drivers/clk/mvebu/clk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * Marvell EBU SoC clock handling.
- *
- * Copyright (C) 2012 Marvell
- *
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <linux/kernel.h>
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include "clk-core.h"
-#include "clk-gating-ctrl.h"
-
-void __init mvebu_clocks_init(void)
-{
-	mvebu_core_clk_init();
-	mvebu_gating_clk_init();
-	of_clk_init(NULL);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/clk-core.c linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk-core.c
--- linux-libre-3.10-gnu/drivers/clk/mvebu/clk-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk-core.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,675 +0,0 @@
-/*
- * Marvell EBU clock core handling defined at reset
- *
- * Copyright (C) 2012 Marvell
- *
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include <linux/clk-provider.h>
-#include <linux/of_address.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include "clk-core.h"
-
-struct core_ratio {
-	int id;
-	const char *name;
-};
-
-struct core_clocks {
-	u32 (*get_tclk_freq)(void __iomem *sar);
-	u32 (*get_cpu_freq)(void __iomem *sar);
-	void (*get_clk_ratio)(void __iomem *sar, int id, int *mult, int *div);
-	const struct core_ratio *ratios;
-	int num_ratios;
-};
-
-static struct clk_onecell_data clk_data;
-
-static void __init mvebu_clk_core_setup(struct device_node *np,
-				 struct core_clocks *coreclk)
-{
-	const char *tclk_name = "tclk";
-	const char *cpuclk_name = "cpuclk";
-	void __iomem *base;
-	unsigned long rate;
-	int n;
-
-	base = of_iomap(np, 0);
-	if (WARN_ON(!base))
-		return;
-
-	/*
-	 * Allocate struct for TCLK, cpu clk, and core ratio clocks
-	 */
-	clk_data.clk_num = 2 + coreclk->num_ratios;
-	clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
-				GFP_KERNEL);
-	if (WARN_ON(!clk_data.clks))
-		return;
-
-	/*
-	 * Register TCLK
-	 */
-	of_property_read_string_index(np, "clock-output-names", 0,
-				      &tclk_name);
-	rate = coreclk->get_tclk_freq(base);
-	clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL,
-						   CLK_IS_ROOT, rate);
-	WARN_ON(IS_ERR(clk_data.clks[0]));
-
-	/*
-	 * Register CPU clock
-	 */
-	of_property_read_string_index(np, "clock-output-names", 1,
-				      &cpuclk_name);
-	rate = coreclk->get_cpu_freq(base);
-	clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL,
-						   CLK_IS_ROOT, rate);
-	WARN_ON(IS_ERR(clk_data.clks[1]));
-
-	/*
-	 * Register fixed-factor clocks derived from CPU clock
-	 */
-	for (n = 0; n < coreclk->num_ratios; n++) {
-		const char *rclk_name = coreclk->ratios[n].name;
-		int mult, div;
-
-		of_property_read_string_index(np, "clock-output-names",
-					      2+n, &rclk_name);
-		coreclk->get_clk_ratio(base, coreclk->ratios[n].id,
-				       &mult, &div);
-		clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
-				       cpuclk_name, 0, mult, div);
-		WARN_ON(IS_ERR(clk_data.clks[2+n]));
-	};
-
-	/*
-	 * SAR register isn't needed anymore
-	 */
-	iounmap(base);
-
-	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-}
-
-#ifdef CONFIG_MACH_ARMADA_370_XP
-/*
- * Armada 370/XP Sample At Reset is a 64 bit bitfiled split in two
- * register of 32 bits
- */
-
-#define SARL				    0	/* Low part [0:31] */
-#define	    SARL_AXP_PCLK_FREQ_OPT	    21
-#define	    SARL_AXP_PCLK_FREQ_OPT_MASK	    0x7
-#define	    SARL_A370_PCLK_FREQ_OPT	    11
-#define	    SARL_A370_PCLK_FREQ_OPT_MASK    0xF
-#define	    SARL_AXP_FAB_FREQ_OPT	    24
-#define	    SARL_AXP_FAB_FREQ_OPT_MASK	    0xF
-#define	    SARL_A370_FAB_FREQ_OPT	    15
-#define	    SARL_A370_FAB_FREQ_OPT_MASK	    0x1F
-#define	    SARL_A370_TCLK_FREQ_OPT	    20
-#define	    SARL_A370_TCLK_FREQ_OPT_MASK    0x1
-#define SARH				    4	/* High part [32:63] */
-#define	    SARH_AXP_PCLK_FREQ_OPT	    (52-32)
-#define	    SARH_AXP_PCLK_FREQ_OPT_MASK	    0x1
-#define	    SARH_AXP_PCLK_FREQ_OPT_SHIFT    3
-#define	    SARH_AXP_FAB_FREQ_OPT	    (51-32)
-#define	    SARH_AXP_FAB_FREQ_OPT_MASK	    0x1
-#define	    SARH_AXP_FAB_FREQ_OPT_SHIFT	    4
-
-static const u32 __initconst armada_370_tclk_frequencies[] = {
-	16600000,
-	20000000,
-};
-
-static u32 __init armada_370_get_tclk_freq(void __iomem *sar)
-{
-	u8 tclk_freq_select = 0;
-
-	tclk_freq_select = ((readl(sar) >> SARL_A370_TCLK_FREQ_OPT) &
-			    SARL_A370_TCLK_FREQ_OPT_MASK);
-	return armada_370_tclk_frequencies[tclk_freq_select];
-}
-
-static const u32 __initconst armada_370_cpu_frequencies[] = {
-	400000000,
-	533000000,
-	667000000,
-	800000000,
-	1000000000,
-	1067000000,
-	1200000000,
-};
-
-static u32 __init armada_370_get_cpu_freq(void __iomem *sar)
-{
-	u32 cpu_freq;
-	u8 cpu_freq_select = 0;
-
-	cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) &
-			   SARL_A370_PCLK_FREQ_OPT_MASK);
-	if (cpu_freq_select >= ARRAY_SIZE(armada_370_cpu_frequencies)) {
-		pr_err("CPU freq select unsupported %d\n", cpu_freq_select);
-		cpu_freq = 0;
-	} else
-		cpu_freq = armada_370_cpu_frequencies[cpu_freq_select];
-
-	return cpu_freq;
-}
-
-enum { A370_XP_NBCLK, A370_XP_HCLK, A370_XP_DRAMCLK };
-
-static const struct core_ratio __initconst armada_370_xp_core_ratios[] = {
-	{ .id = A370_XP_NBCLK,	 .name = "nbclk" },
-	{ .id = A370_XP_HCLK,	 .name = "hclk" },
-	{ .id = A370_XP_DRAMCLK, .name = "dramclk" },
-};
-
-static const int __initconst armada_370_xp_nbclk_ratios[32][2] = {
-	{0, 1}, {1, 2}, {2, 2}, {2, 2},
-	{1, 2}, {1, 2}, {1, 1}, {2, 3},
-	{0, 1}, {1, 2}, {2, 4}, {0, 1},
-	{1, 2}, {0, 1}, {0, 1}, {2, 2},
-	{0, 1}, {0, 1}, {0, 1}, {1, 1},
-	{2, 3}, {0, 1}, {0, 1}, {0, 1},
-	{0, 1}, {0, 1}, {0, 1}, {1, 1},
-	{0, 1}, {0, 1}, {0, 1}, {0, 1},
-};
-
-static const int __initconst armada_370_xp_hclk_ratios[32][2] = {
-	{0, 1}, {1, 2}, {2, 6}, {2, 3},
-	{1, 3}, {1, 4}, {1, 2}, {2, 6},
-	{0, 1}, {1, 6}, {2, 10}, {0, 1},
-	{1, 4}, {0, 1}, {0, 1}, {2, 5},
-	{0, 1}, {0, 1}, {0, 1}, {1, 2},
-	{2, 6}, {0, 1}, {0, 1}, {0, 1},
-	{0, 1}, {0, 1}, {0, 1}, {1, 1},
-	{0, 1}, {0, 1}, {0, 1}, {0, 1},
-};
-
-static const int __initconst armada_370_xp_dramclk_ratios[32][2] = {
-	{0, 1}, {1, 2}, {2, 3}, {2, 3},
-	{1, 3}, {1, 2}, {1, 2}, {2, 6},
-	{0, 1}, {1, 3}, {2, 5}, {0, 1},
-	{1, 4}, {0, 1}, {0, 1}, {2, 5},
-	{0, 1}, {0, 1}, {0, 1}, {1, 1},
-	{2, 3}, {0, 1}, {0, 1}, {0, 1},
-	{0, 1}, {0, 1}, {0, 1}, {1, 1},
-	{0, 1}, {0, 1}, {0, 1}, {0, 1},
-};
-
-static void __init armada_370_xp_get_clk_ratio(u32 opt,
-	void __iomem *sar, int id, int *mult, int *div)
-{
-	switch (id) {
-	case A370_XP_NBCLK:
-		*mult = armada_370_xp_nbclk_ratios[opt][0];
-		*div = armada_370_xp_nbclk_ratios[opt][1];
-		break;
-	case A370_XP_HCLK:
-		*mult = armada_370_xp_hclk_ratios[opt][0];
-		*div = armada_370_xp_hclk_ratios[opt][1];
-		break;
-	case A370_XP_DRAMCLK:
-		*mult = armada_370_xp_dramclk_ratios[opt][0];
-		*div = armada_370_xp_dramclk_ratios[opt][1];
-		break;
-	}
-}
-
-static void __init armada_370_get_clk_ratio(
-	void __iomem *sar, int id, int *mult, int *div)
-{
-	u32 opt = ((readl(sar) >> SARL_A370_FAB_FREQ_OPT) &
-		SARL_A370_FAB_FREQ_OPT_MASK);
-
-	armada_370_xp_get_clk_ratio(opt, sar, id, mult, div);
-}
-
-
-static const struct core_clocks armada_370_core_clocks = {
-	.get_tclk_freq = armada_370_get_tclk_freq,
-	.get_cpu_freq = armada_370_get_cpu_freq,
-	.get_clk_ratio = armada_370_get_clk_ratio,
-	.ratios = armada_370_xp_core_ratios,
-	.num_ratios = ARRAY_SIZE(armada_370_xp_core_ratios),
-};
-
-static const u32 __initconst armada_xp_cpu_frequencies[] = {
-	1000000000,
-	1066000000,
-	1200000000,
-	1333000000,
-	1500000000,
-	1666000000,
-	1800000000,
-	2000000000,
-	667000000,
-	0,
-	800000000,
-	1600000000,
-};
-
-/* For Armada XP TCLK frequency is fix: 250MHz */
-static u32 __init armada_xp_get_tclk_freq(void __iomem *sar)
-{
-	return 250 * 1000 * 1000;
-}
-
-static u32 __init armada_xp_get_cpu_freq(void __iomem *sar)
-{
-	u32 cpu_freq;
-	u8 cpu_freq_select = 0;
-
-	cpu_freq_select = ((readl(sar) >> SARL_AXP_PCLK_FREQ_OPT) &
-			   SARL_AXP_PCLK_FREQ_OPT_MASK);
-	/*
-	 * The upper bit is not contiguous to the other ones and
-	 * located in the high part of the SAR registers
-	 */
-	cpu_freq_select |= (((readl(sar+4) >> SARH_AXP_PCLK_FREQ_OPT) &
-			     SARH_AXP_PCLK_FREQ_OPT_MASK)
-			    << SARH_AXP_PCLK_FREQ_OPT_SHIFT);
-	if (cpu_freq_select >= ARRAY_SIZE(armada_xp_cpu_frequencies)) {
-		pr_err("CPU freq select unsupported: %d\n", cpu_freq_select);
-		cpu_freq = 0;
-	} else
-		cpu_freq = armada_xp_cpu_frequencies[cpu_freq_select];
-
-	return cpu_freq;
-}
-
-static void __init armada_xp_get_clk_ratio(
-	void __iomem *sar, int id, int *mult, int *div)
-{
-
-	u32 opt = ((readl(sar) >> SARL_AXP_FAB_FREQ_OPT) &
-	      SARL_AXP_FAB_FREQ_OPT_MASK);
-	/*
-	 * The upper bit is not contiguous to the other ones and
-	 * located in the high part of the SAR registers
-	 */
-	opt |= (((readl(sar+4) >> SARH_AXP_FAB_FREQ_OPT) &
-		SARH_AXP_FAB_FREQ_OPT_MASK)
-	       << SARH_AXP_FAB_FREQ_OPT_SHIFT);
-
-	armada_370_xp_get_clk_ratio(opt, sar, id, mult, div);
-}
-
-static const struct core_clocks armada_xp_core_clocks = {
-	.get_tclk_freq = armada_xp_get_tclk_freq,
-	.get_cpu_freq = armada_xp_get_cpu_freq,
-	.get_clk_ratio = armada_xp_get_clk_ratio,
-	.ratios = armada_370_xp_core_ratios,
-	.num_ratios = ARRAY_SIZE(armada_370_xp_core_ratios),
-};
-
-#endif /* CONFIG_MACH_ARMADA_370_XP */
-
-/*
- * Dove PLL sample-at-reset configuration
- *
- * SAR0[8:5]   : CPU frequency
- *		 5  = 1000 MHz
- *		 6  =  933 MHz
- *		 7  =  933 MHz
- *		 8  =  800 MHz
- *		 9  =  800 MHz
- *		 10 =  800 MHz
- *		 11 = 1067 MHz
- *		 12 =  667 MHz
- *		 13 =  533 MHz
- *		 14 =  400 MHz
- *		 15 =  333 MHz
- *		 others reserved.
- *
- * SAR0[11:9]  : CPU to L2 Clock divider ratio
- *		 0 = (1/1) * CPU
- *		 2 = (1/2) * CPU
- *		 4 = (1/3) * CPU
- *		 6 = (1/4) * CPU
- *		 others reserved.
- *
- * SAR0[15:12] : CPU to DDR DRAM Clock divider ratio
- *		 0  = (1/1) * CPU
- *		 2  = (1/2) * CPU
- *		 3  = (2/5) * CPU
- *		 4  = (1/3) * CPU
- *		 6  = (1/4) * CPU
- *		 8  = (1/5) * CPU
- *		 10 = (1/6) * CPU
- *		 12 = (1/7) * CPU
- *		 14 = (1/8) * CPU
- *		 15 = (1/10) * CPU
- *		 others reserved.
- *
- * SAR0[24:23] : TCLK frequency
- *		 0 = 166 MHz
- *		 1 = 125 MHz
- *		 others reserved.
- */
-#ifdef CONFIG_ARCH_DOVE
-#define SAR_DOVE_CPU_FREQ		5
-#define SAR_DOVE_CPU_FREQ_MASK		0xf
-#define SAR_DOVE_L2_RATIO		9
-#define SAR_DOVE_L2_RATIO_MASK		0x7
-#define SAR_DOVE_DDR_RATIO		12
-#define SAR_DOVE_DDR_RATIO_MASK		0xf
-#define SAR_DOVE_TCLK_FREQ		23
-#define SAR_DOVE_TCLK_FREQ_MASK		0x3
-
-static const u32 __initconst dove_tclk_frequencies[] = {
-	166666667,
-	125000000,
-	0, 0
-};
-
-static u32 __init dove_get_tclk_freq(void __iomem *sar)
-{
-	u32 opt = (readl(sar) >> SAR_DOVE_TCLK_FREQ) &
-		SAR_DOVE_TCLK_FREQ_MASK;
-	return dove_tclk_frequencies[opt];
-}
-
-static const u32 __initconst dove_cpu_frequencies[] = {
-	0, 0, 0, 0, 0,
-	1000000000,
-	933333333, 933333333,
-	800000000, 800000000, 800000000,
-	1066666667,
-	666666667,
-	533333333,
-	400000000,
-	333333333
-};
-
-static u32 __init dove_get_cpu_freq(void __iomem *sar)
-{
-	u32 opt = (readl(sar) >> SAR_DOVE_CPU_FREQ) &
-		SAR_DOVE_CPU_FREQ_MASK;
-	return dove_cpu_frequencies[opt];
-}
-
-enum { DOVE_CPU_TO_L2, DOVE_CPU_TO_DDR };
-
-static const struct core_ratio __initconst dove_core_ratios[] = {
-	{ .id = DOVE_CPU_TO_L2, .name = "l2clk", },
-	{ .id = DOVE_CPU_TO_DDR, .name = "ddrclk", }
-};
-
-static const int __initconst dove_cpu_l2_ratios[8][2] = {
-	{ 1, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
-	{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 }
-};
-
-static const int __initconst dove_cpu_ddr_ratios[16][2] = {
-	{ 1, 1 }, { 0, 1 }, { 1, 2 }, { 2, 5 },
-	{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 },
-	{ 1, 5 }, { 0, 1 }, { 1, 6 }, { 0, 1 },
-	{ 1, 7 }, { 0, 1 }, { 1, 8 }, { 1, 10 }
-};
-
-static void __init dove_get_clk_ratio(
-	void __iomem *sar, int id, int *mult, int *div)
-{
-	switch (id) {
-	case DOVE_CPU_TO_L2:
-	{
-		u32 opt = (readl(sar) >> SAR_DOVE_L2_RATIO) &
-			SAR_DOVE_L2_RATIO_MASK;
-		*mult = dove_cpu_l2_ratios[opt][0];
-		*div = dove_cpu_l2_ratios[opt][1];
-		break;
-	}
-	case DOVE_CPU_TO_DDR:
-	{
-		u32 opt = (readl(sar) >> SAR_DOVE_DDR_RATIO) &
-			SAR_DOVE_DDR_RATIO_MASK;
-		*mult = dove_cpu_ddr_ratios[opt][0];
-		*div = dove_cpu_ddr_ratios[opt][1];
-		break;
-	}
-	}
-}
-
-static const struct core_clocks dove_core_clocks = {
-	.get_tclk_freq = dove_get_tclk_freq,
-	.get_cpu_freq = dove_get_cpu_freq,
-	.get_clk_ratio = dove_get_clk_ratio,
-	.ratios = dove_core_ratios,
-	.num_ratios = ARRAY_SIZE(dove_core_ratios),
-};
-#endif /* CONFIG_ARCH_DOVE */
-
-/*
- * Kirkwood PLL sample-at-reset configuration
- * (6180 has different SAR layout than other Kirkwood SoCs)
- *
- * SAR0[4:3,22,1] : CPU frequency (6281,6292,6282)
- *	4  =  600 MHz
- *	6  =  800 MHz
- *	7  = 1000 MHz
- *	9  = 1200 MHz
- *	12 = 1500 MHz
- *	13 = 1600 MHz
- *	14 = 1800 MHz
- *	15 = 2000 MHz
- *	others reserved.
- *
- * SAR0[19,10:9] : CPU to L2 Clock divider ratio (6281,6292,6282)
- *	1 = (1/2) * CPU
- *	3 = (1/3) * CPU
- *	5 = (1/4) * CPU
- *	others reserved.
- *
- * SAR0[8:5] : CPU to DDR DRAM Clock divider ratio (6281,6292,6282)
- *	2 = (1/2) * CPU
- *	4 = (1/3) * CPU
- *	6 = (1/4) * CPU
- *	7 = (2/9) * CPU
- *	8 = (1/5) * CPU
- *	9 = (1/6) * CPU
- *	others reserved.
- *
- * SAR0[4:2] : Kirkwood 6180 cpu/l2/ddr clock configuration (6180 only)
- *	5 = [CPU =  600 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/3) * CPU]
- *	6 = [CPU =  800 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/4) * CPU]
- *	7 = [CPU = 1000 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/5) * CPU]
- *	others reserved.
- *
- * SAR0[21] : TCLK frequency
- *	0 = 200 MHz
- *	1 = 166 MHz
- *	others reserved.
- */
-#ifdef CONFIG_ARCH_KIRKWOOD
-#define SAR_KIRKWOOD_CPU_FREQ(x)	\
-	(((x & (1 <<  1)) >>  1) |	\
-	 ((x & (1 << 22)) >> 21) |	\
-	 ((x & (3 <<  3)) >>  1))
-#define SAR_KIRKWOOD_L2_RATIO(x)	\
-	(((x & (3 <<  9)) >> 9) |	\
-	 (((x & (1 << 19)) >> 17)))
-#define SAR_KIRKWOOD_DDR_RATIO		5
-#define SAR_KIRKWOOD_DDR_RATIO_MASK	0xf
-#define SAR_MV88F6180_CLK		2
-#define SAR_MV88F6180_CLK_MASK		0x7
-#define SAR_KIRKWOOD_TCLK_FREQ		21
-#define SAR_KIRKWOOD_TCLK_FREQ_MASK	0x1
-
-enum { KIRKWOOD_CPU_TO_L2, KIRKWOOD_CPU_TO_DDR };
-
-static const struct core_ratio __initconst kirkwood_core_ratios[] = {
-	{ .id = KIRKWOOD_CPU_TO_L2, .name = "l2clk", },
-	{ .id = KIRKWOOD_CPU_TO_DDR, .name = "ddrclk", }
-};
-
-static u32 __init kirkwood_get_tclk_freq(void __iomem *sar)
-{
-	u32 opt = (readl(sar) >> SAR_KIRKWOOD_TCLK_FREQ) &
-		SAR_KIRKWOOD_TCLK_FREQ_MASK;
-	return (opt) ? 166666667 : 200000000;
-}
-
-static const u32 __initconst kirkwood_cpu_frequencies[] = {
-	0, 0, 0, 0,
-	600000000,
-	0,
-	800000000,
-	1000000000,
-	0,
-	1200000000,
-	0, 0,
-	1500000000,
-	1600000000,
-	1800000000,
-	2000000000
-};
-
-static u32 __init kirkwood_get_cpu_freq(void __iomem *sar)
-{
-	u32 opt = SAR_KIRKWOOD_CPU_FREQ(readl(sar));
-	return kirkwood_cpu_frequencies[opt];
-}
-
-static const int __initconst kirkwood_cpu_l2_ratios[8][2] = {
-	{ 0, 1 }, { 1, 2 }, { 0, 1 }, { 1, 3 },
-	{ 0, 1 }, { 1, 4 }, { 0, 1 }, { 0, 1 }
-};
-
-static const int __initconst kirkwood_cpu_ddr_ratios[16][2] = {
-	{ 0, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
-	{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 2, 9 },
-	{ 1, 5 }, { 1, 6 }, { 0, 1 }, { 0, 1 },
-	{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }
-};
-
-static void __init kirkwood_get_clk_ratio(
-	void __iomem *sar, int id, int *mult, int *div)
-{
-	switch (id) {
-	case KIRKWOOD_CPU_TO_L2:
-	{
-		u32 opt = SAR_KIRKWOOD_L2_RATIO(readl(sar));
-		*mult = kirkwood_cpu_l2_ratios[opt][0];
-		*div = kirkwood_cpu_l2_ratios[opt][1];
-		break;
-	}
-	case KIRKWOOD_CPU_TO_DDR:
-	{
-		u32 opt = (readl(sar) >> SAR_KIRKWOOD_DDR_RATIO) &
-			SAR_KIRKWOOD_DDR_RATIO_MASK;
-		*mult = kirkwood_cpu_ddr_ratios[opt][0];
-		*div = kirkwood_cpu_ddr_ratios[opt][1];
-		break;
-	}
-	}
-}
-
-static const struct core_clocks kirkwood_core_clocks = {
-	.get_tclk_freq = kirkwood_get_tclk_freq,
-	.get_cpu_freq = kirkwood_get_cpu_freq,
-	.get_clk_ratio = kirkwood_get_clk_ratio,
-	.ratios = kirkwood_core_ratios,
-	.num_ratios = ARRAY_SIZE(kirkwood_core_ratios),
-};
-
-static const u32 __initconst mv88f6180_cpu_frequencies[] = {
-	0, 0, 0, 0, 0,
-	600000000,
-	800000000,
-	1000000000
-};
-
-static u32 __init mv88f6180_get_cpu_freq(void __iomem *sar)
-{
-	u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) & SAR_MV88F6180_CLK_MASK;
-	return mv88f6180_cpu_frequencies[opt];
-}
-
-static const int __initconst mv88f6180_cpu_ddr_ratios[8][2] = {
-	{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 },
-	{ 0, 1 }, { 1, 3 }, { 1, 4 }, { 1, 5 }
-};
-
-static void __init mv88f6180_get_clk_ratio(
-	void __iomem *sar, int id, int *mult, int *div)
-{
-	switch (id) {
-	case KIRKWOOD_CPU_TO_L2:
-	{
-		/* mv88f6180 has a fixed 1:2 CPU-to-L2 ratio */
-		*mult = 1;
-		*div = 2;
-		break;
-	}
-	case KIRKWOOD_CPU_TO_DDR:
-	{
-		u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) &
-			SAR_MV88F6180_CLK_MASK;
-		*mult = mv88f6180_cpu_ddr_ratios[opt][0];
-		*div = mv88f6180_cpu_ddr_ratios[opt][1];
-		break;
-	}
-	}
-}
-
-static const struct core_clocks mv88f6180_core_clocks = {
-	.get_tclk_freq = kirkwood_get_tclk_freq,
-	.get_cpu_freq = mv88f6180_get_cpu_freq,
-	.get_clk_ratio = mv88f6180_get_clk_ratio,
-	.ratios = kirkwood_core_ratios,
-	.num_ratios = ARRAY_SIZE(kirkwood_core_ratios),
-};
-#endif /* CONFIG_ARCH_KIRKWOOD */
-
-static const __initdata struct of_device_id clk_core_match[] = {
-#ifdef CONFIG_MACH_ARMADA_370_XP
-	{
-		.compatible = "marvell,armada-370-core-clock",
-		.data = &armada_370_core_clocks,
-	},
-	{
-		.compatible = "marvell,armada-xp-core-clock",
-		.data = &armada_xp_core_clocks,
-	},
-#endif
-#ifdef CONFIG_ARCH_DOVE
-	{
-		.compatible = "marvell,dove-core-clock",
-		.data = &dove_core_clocks,
-	},
-#endif
-
-#ifdef CONFIG_ARCH_KIRKWOOD
-	{
-		.compatible = "marvell,kirkwood-core-clock",
-		.data = &kirkwood_core_clocks,
-	},
-	{
-		.compatible = "marvell,mv88f6180-core-clock",
-		.data = &mv88f6180_core_clocks,
-	},
-#endif
-
-	{ }
-};
-
-void __init mvebu_core_clk_init(void)
-{
-	struct device_node *np;
-
-	for_each_matching_node(np, clk_core_match) {
-		const struct of_device_id *match =
-			of_match_node(clk_core_match, np);
-		mvebu_clk_core_setup(np, (struct core_clocks *)match->data);
-	}
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/clk-core.h linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk-core.h
--- linux-libre-3.10-gnu/drivers/clk/mvebu/clk-core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk-core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-/*
- *  * Marvell EBU clock core handling defined at reset
- *
- * Copyright (C) 2012 Marvell
- *
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __MVEBU_CLK_CORE_H
-#define __MVEBU_CLK_CORE_H
-
-void __init mvebu_core_clk_init(void);
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/clk-gating-ctrl.c linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk-gating-ctrl.c
--- linux-libre-3.10-gnu/drivers/clk/mvebu/clk-gating-ctrl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk-gating-ctrl.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,250 +0,0 @@
-/*
- * Marvell MVEBU clock gating control.
- *
- * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
- * Andrew Lunn <andrew@lunn.ch>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <linux/kernel.h>
-#include <linux/bitops.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include <linux/clk-provider.h>
-#include <linux/clk/mvebu.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-
-struct mvebu_gating_ctrl {
-	spinlock_t lock;
-	struct clk **gates;
-	int num_gates;
-};
-
-struct mvebu_soc_descr {
-	const char *name;
-	const char *parent;
-	int bit_idx;
-};
-
-#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
-
-static struct clk *mvebu_clk_gating_get_src(
-	struct of_phandle_args *clkspec, void *data)
-{
-	struct mvebu_gating_ctrl *ctrl = (struct mvebu_gating_ctrl *)data;
-	int n;
-
-	if (clkspec->args_count < 1)
-		return ERR_PTR(-EINVAL);
-
-	for (n = 0; n < ctrl->num_gates; n++) {
-		struct clk_gate *gate =
-			to_clk_gate(__clk_get_hw(ctrl->gates[n]));
-		if (clkspec->args[0] == gate->bit_idx)
-			return ctrl->gates[n];
-	}
-	return ERR_PTR(-ENODEV);
-}
-
-static void __init mvebu_clk_gating_setup(
-	struct device_node *np, const struct mvebu_soc_descr *descr)
-{
-	struct mvebu_gating_ctrl *ctrl;
-	struct clk *clk;
-	void __iomem *base;
-	const char *default_parent = NULL;
-	int n;
-
-	base = of_iomap(np, 0);
-
-	clk = of_clk_get(np, 0);
-	if (!IS_ERR(clk)) {
-		default_parent = __clk_get_name(clk);
-		clk_put(clk);
-	}
-
-	ctrl = kzalloc(sizeof(struct mvebu_gating_ctrl), GFP_KERNEL);
-	if (WARN_ON(!ctrl))
-		return;
-
-	spin_lock_init(&ctrl->lock);
-
-	/*
-	 * Count, allocate, and register clock gates
-	 */
-	for (n = 0; descr[n].name;)
-		n++;
-
-	ctrl->num_gates = n;
-	ctrl->gates = kzalloc(ctrl->num_gates * sizeof(struct clk *),
-			      GFP_KERNEL);
-	if (WARN_ON(!ctrl->gates)) {
-		kfree(ctrl);
-		return;
-	}
-
-	for (n = 0; n < ctrl->num_gates; n++) {
-		u8 flags = 0;
-		const char *parent =
-			(descr[n].parent) ? descr[n].parent : default_parent;
-
-		/*
-		 * On Armada 370, the DDR clock is a special case: it
-		 * isn't taken by any driver, but should anyway be
-		 * kept enabled, so we mark it as IGNORE_UNUSED for
-		 * now.
-		 */
-		if (!strcmp(descr[n].name, "ddr"))
-			flags |= CLK_IGNORE_UNUSED;
-
-		ctrl->gates[n] = clk_register_gate(NULL, descr[n].name, parent,
-				   flags, base, descr[n].bit_idx, 0, &ctrl->lock);
-		WARN_ON(IS_ERR(ctrl->gates[n]));
-	}
-	of_clk_add_provider(np, mvebu_clk_gating_get_src, ctrl);
-}
-
-/*
- * SoC specific clock gating control
- */
-
-#ifdef CONFIG_MACH_ARMADA_370
-static const struct mvebu_soc_descr __initconst armada_370_gating_descr[] = {
-	{ "audio", NULL, 0 },
-	{ "pex0_en", NULL, 1 },
-	{ "pex1_en", NULL,  2 },
-	{ "ge1", NULL, 3 },
-	{ "ge0", NULL, 4 },
-	{ "pex0", NULL, 5 },
-	{ "pex1", NULL, 9 },
-	{ "sata0", NULL, 15 },
-	{ "sdio", NULL, 17 },
-	{ "tdm", NULL, 25 },
-	{ "ddr", NULL, 28 },
-	{ "sata1", NULL, 30 },
-	{ }
-};
-#endif
-
-#ifdef CONFIG_MACH_ARMADA_XP
-static const struct mvebu_soc_descr __initconst armada_xp_gating_descr[] = {
-	{ "audio", NULL, 0 },
-	{ "ge3", NULL, 1 },
-	{ "ge2", NULL,  2 },
-	{ "ge1", NULL, 3 },
-	{ "ge0", NULL, 4 },
-	{ "pex0", NULL, 5 },
-	{ "pex1", NULL, 6 },
-	{ "pex2", NULL, 7 },
-	{ "pex3", NULL, 8 },
-	{ "bp", NULL, 13 },
-	{ "sata0lnk", NULL, 14 },
-	{ "sata0", "sata0lnk", 15 },
-	{ "lcd", NULL, 16 },
-	{ "sdio", NULL, 17 },
-	{ "usb0", NULL, 18 },
-	{ "usb1", NULL, 19 },
-	{ "usb2", NULL, 20 },
-	{ "xor0", NULL, 22 },
-	{ "crypto", NULL, 23 },
-	{ "tdm", NULL, 25 },
-	{ "xor1", NULL, 28 },
-	{ "sata1lnk", NULL, 29 },
-	{ "sata1", "sata1lnk", 30 },
-	{ }
-};
-#endif
-
-#ifdef CONFIG_ARCH_DOVE
-static const struct mvebu_soc_descr __initconst dove_gating_descr[] = {
-	{ "usb0", NULL, 0 },
-	{ "usb1", NULL, 1 },
-	{ "ge", "gephy", 2 },
-	{ "sata", NULL, 3 },
-	{ "pex0", NULL, 4 },
-	{ "pex1", NULL, 5 },
-	{ "sdio0", NULL, 8 },
-	{ "sdio1", NULL, 9 },
-	{ "nand", NULL, 10 },
-	{ "camera", NULL, 11 },
-	{ "i2s0", NULL, 12 },
-	{ "i2s1", NULL, 13 },
-	{ "crypto", NULL, 15 },
-	{ "ac97", NULL, 21 },
-	{ "pdma", NULL, 22 },
-	{ "xor0", NULL, 23 },
-	{ "xor1", NULL, 24 },
-	{ "gephy", NULL, 30 },
-	{ }
-};
-#endif
-
-#ifdef CONFIG_ARCH_KIRKWOOD
-static const struct mvebu_soc_descr __initconst kirkwood_gating_descr[] = {
-	{ "ge0", NULL, 0 },
-	{ "pex0", NULL, 2 },
-	{ "usb0", NULL, 3 },
-	{ "sdio", NULL, 4 },
-	{ "tsu", NULL, 5 },
-	{ "runit", NULL, 7 },
-	{ "xor0", NULL, 8 },
-	{ "audio", NULL, 9 },
-	{ "powersave", "cpuclk", 11 },
-	{ "sata0", NULL, 14 },
-	{ "sata1", NULL, 15 },
-	{ "xor1", NULL, 16 },
-	{ "crypto", NULL, 17 },
-	{ "pex1", NULL, 18 },
-	{ "ge1", NULL, 19 },
-	{ "tdm", NULL, 20 },
-	{ }
-};
-#endif
-
-static const __initdata struct of_device_id clk_gating_match[] = {
-#ifdef CONFIG_MACH_ARMADA_370
-	{
-		.compatible = "marvell,armada-370-gating-clock",
-		.data = armada_370_gating_descr,
-	},
-#endif
-
-#ifdef CONFIG_MACH_ARMADA_XP
-	{
-		.compatible = "marvell,armada-xp-gating-clock",
-		.data = armada_xp_gating_descr,
-	},
-#endif
-
-#ifdef CONFIG_ARCH_DOVE
-	{
-		.compatible = "marvell,dove-gating-clock",
-		.data = dove_gating_descr,
-	},
-#endif
-
-#ifdef CONFIG_ARCH_KIRKWOOD
-	{
-		.compatible = "marvell,kirkwood-gating-clock",
-		.data = kirkwood_gating_descr,
-	},
-#endif
-
-	{ }
-};
-
-void __init mvebu_gating_clk_init(void)
-{
-	struct device_node *np;
-
-	for_each_matching_node(np, clk_gating_match) {
-		const struct of_device_id *match =
-			of_match_node(clk_gating_match, np);
-		mvebu_clk_gating_setup(np,
-		       (const struct mvebu_soc_descr *)match->data);
-	}
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/clk-gating-ctrl.h linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk-gating-ctrl.h
--- linux-libre-3.10-gnu/drivers/clk/mvebu/clk-gating-ctrl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/clk-gating-ctrl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-/*
- * Marvell EBU gating clock handling
- *
- * Copyright (C) 2012 Marvell
- *
- * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __MVEBU_CLK_GATING_H
-#define __MVEBU_CLK_GATING_H
-
-#ifdef CONFIG_MVEBU_CLK_GATING
-void __init mvebu_gating_clk_init(void);
-#else
-void mvebu_gating_clk_init(void) {}
-#endif
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/common.c linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/common.c
--- linux-libre-3.10-gnu/drivers/clk/mvebu/common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ * Marvell EBU SoC common clock handling
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "common.h"
+
+/*
+ * Core Clocks
+ */
+
+static struct clk_onecell_data clk_data;
+
+void __init mvebu_coreclk_setup(struct device_node *np,
+				const struct coreclk_soc_desc *desc)
+{
+	const char *tclk_name = "tclk";
+	const char *cpuclk_name = "cpuclk";
+	void __iomem *base;
+	unsigned long rate;
+	int n;
+
+	base = of_iomap(np, 0);
+	if (WARN_ON(!base))
+		return;
+
+	/* Allocate struct for TCLK, cpu clk, and core ratio clocks */
+	clk_data.clk_num = 2 + desc->num_ratios;
+	clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
+				GFP_KERNEL);
+	if (WARN_ON(!clk_data.clks))
+		return;
+
+	/* Register TCLK */
+	of_property_read_string_index(np, "clock-output-names", 0,
+				      &tclk_name);
+	rate = desc->get_tclk_freq(base);
+	clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL,
+						   CLK_IS_ROOT, rate);
+	WARN_ON(IS_ERR(clk_data.clks[0]));
+
+	/* Register CPU clock */
+	of_property_read_string_index(np, "clock-output-names", 1,
+				      &cpuclk_name);
+	rate = desc->get_cpu_freq(base);
+	clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL,
+						   CLK_IS_ROOT, rate);
+	WARN_ON(IS_ERR(clk_data.clks[1]));
+
+	/* Register fixed-factor clocks derived from CPU clock */
+	for (n = 0; n < desc->num_ratios; n++) {
+		const char *rclk_name = desc->ratios[n].name;
+		int mult, div;
+
+		of_property_read_string_index(np, "clock-output-names",
+					      2+n, &rclk_name);
+		desc->get_clk_ratio(base, desc->ratios[n].id, &mult, &div);
+		clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
+				       cpuclk_name, 0, mult, div);
+		WARN_ON(IS_ERR(clk_data.clks[2+n]));
+	};
+
+	/* SAR register isn't needed anymore */
+	iounmap(base);
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+/*
+ * Clock Gating Control
+ */
+
+struct clk_gating_ctrl {
+	spinlock_t lock;
+	struct clk **gates;
+	int num_gates;
+};
+
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+
+static struct clk *clk_gating_get_src(
+	struct of_phandle_args *clkspec, void *data)
+{
+	struct clk_gating_ctrl *ctrl = (struct clk_gating_ctrl *)data;
+	int n;
+
+	if (clkspec->args_count < 1)
+		return ERR_PTR(-EINVAL);
+
+	for (n = 0; n < ctrl->num_gates; n++) {
+		struct clk_gate *gate =
+			to_clk_gate(__clk_get_hw(ctrl->gates[n]));
+		if (clkspec->args[0] == gate->bit_idx)
+			return ctrl->gates[n];
+	}
+	return ERR_PTR(-ENODEV);
+}
+
+void __init mvebu_clk_gating_setup(struct device_node *np,
+				   const struct clk_gating_soc_desc *desc)
+{
+	struct clk_gating_ctrl *ctrl;
+	struct clk *clk;
+	void __iomem *base;
+	const char *default_parent = NULL;
+	int n;
+
+	base = of_iomap(np, 0);
+	if (WARN_ON(!base))
+		return;
+
+	clk = of_clk_get(np, 0);
+	if (!IS_ERR(clk)) {
+		default_parent = __clk_get_name(clk);
+		clk_put(clk);
+	}
+
+	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
+	if (WARN_ON(!ctrl))
+		return;
+
+	spin_lock_init(&ctrl->lock);
+
+	/* Count, allocate, and register clock gates */
+	for (n = 0; desc[n].name;)
+		n++;
+
+	ctrl->num_gates = n;
+	ctrl->gates = kzalloc(ctrl->num_gates * sizeof(struct clk *),
+			      GFP_KERNEL);
+	if (WARN_ON(!ctrl->gates)) {
+		kfree(ctrl);
+		return;
+	}
+
+	for (n = 0; n < ctrl->num_gates; n++) {
+		const char *parent =
+			(desc[n].parent) ? desc[n].parent : default_parent;
+		ctrl->gates[n] = clk_register_gate(NULL, desc[n].name, parent,
+					desc[n].flags, base, desc[n].bit_idx,
+					0, &ctrl->lock);
+		WARN_ON(IS_ERR(ctrl->gates[n]));
+	}
+
+	of_clk_add_provider(np, clk_gating_get_src, ctrl);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/common.h linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/common.h
--- linux-libre-3.10-gnu/drivers/clk/mvebu/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * Marvell EBU SoC common clock handling
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __CLK_MVEBU_COMMON_H_
+#define __CLK_MVEBU_COMMON_H_
+
+#include <linux/kernel.h>
+
+struct device_node;
+
+struct coreclk_ratio {
+	int id;
+	const char *name;
+};
+
+struct coreclk_soc_desc {
+	u32 (*get_tclk_freq)(void __iomem *sar);
+	u32 (*get_cpu_freq)(void __iomem *sar);
+	void (*get_clk_ratio)(void __iomem *sar, int id, int *mult, int *div);
+	const struct coreclk_ratio *ratios;
+	int num_ratios;
+};
+
+struct clk_gating_soc_desc {
+	const char *name;
+	const char *parent;
+	int bit_idx;
+	unsigned long flags;
+};
+
+void __init mvebu_coreclk_setup(struct device_node *np,
+				const struct coreclk_soc_desc *desc);
+
+void __init mvebu_clk_gating_setup(struct device_node *np,
+				   const struct clk_gating_soc_desc *desc);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/dove.c linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/dove.c
--- linux-libre-3.10-gnu/drivers/clk/mvebu/dove.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/dove.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,194 @@
+/*
+ * Marvell Dove SoC clocks
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include "common.h"
+
+/*
+ * Core Clocks
+ *
+ * Dove PLL sample-at-reset configuration
+ *
+ * SAR0[8:5]   : CPU frequency
+ *		 5  = 1000 MHz
+ *		 6  =  933 MHz
+ *		 7  =  933 MHz
+ *		 8  =  800 MHz
+ *		 9  =  800 MHz
+ *		 10 =  800 MHz
+ *		 11 = 1067 MHz
+ *		 12 =  667 MHz
+ *		 13 =  533 MHz
+ *		 14 =  400 MHz
+ *		 15 =  333 MHz
+ *		 others reserved.
+ *
+ * SAR0[11:9]  : CPU to L2 Clock divider ratio
+ *		 0 = (1/1) * CPU
+ *		 2 = (1/2) * CPU
+ *		 4 = (1/3) * CPU
+ *		 6 = (1/4) * CPU
+ *		 others reserved.
+ *
+ * SAR0[15:12] : CPU to DDR DRAM Clock divider ratio
+ *		 0  = (1/1) * CPU
+ *		 2  = (1/2) * CPU
+ *		 3  = (2/5) * CPU
+ *		 4  = (1/3) * CPU
+ *		 6  = (1/4) * CPU
+ *		 8  = (1/5) * CPU
+ *		 10 = (1/6) * CPU
+ *		 12 = (1/7) * CPU
+ *		 14 = (1/8) * CPU
+ *		 15 = (1/10) * CPU
+ *		 others reserved.
+ *
+ * SAR0[24:23] : TCLK frequency
+ *		 0 = 166 MHz
+ *		 1 = 125 MHz
+ *		 others reserved.
+ */
+
+#define SAR_DOVE_CPU_FREQ		5
+#define SAR_DOVE_CPU_FREQ_MASK		0xf
+#define SAR_DOVE_L2_RATIO		9
+#define SAR_DOVE_L2_RATIO_MASK		0x7
+#define SAR_DOVE_DDR_RATIO		12
+#define SAR_DOVE_DDR_RATIO_MASK		0xf
+#define SAR_DOVE_TCLK_FREQ		23
+#define SAR_DOVE_TCLK_FREQ_MASK		0x3
+
+enum { DOVE_CPU_TO_L2, DOVE_CPU_TO_DDR };
+
+static const struct coreclk_ratio __initconst dove_coreclk_ratios[] = {
+	{ .id = DOVE_CPU_TO_L2, .name = "l2clk", },
+	{ .id = DOVE_CPU_TO_DDR, .name = "ddrclk", }
+};
+
+static const u32 __initconst dove_tclk_freqs[] = {
+	166666667,
+	125000000,
+	0, 0
+};
+
+static u32 __init dove_get_tclk_freq(void __iomem *sar)
+{
+	u32 opt = (readl(sar) >> SAR_DOVE_TCLK_FREQ) &
+		SAR_DOVE_TCLK_FREQ_MASK;
+	return dove_tclk_freqs[opt];
+}
+
+static const u32 __initconst dove_cpu_freqs[] = {
+	0, 0, 0, 0, 0,
+	1000000000,
+	933333333, 933333333,
+	800000000, 800000000, 800000000,
+	1066666667,
+	666666667,
+	533333333,
+	400000000,
+	333333333
+};
+
+static u32 __init dove_get_cpu_freq(void __iomem *sar)
+{
+	u32 opt = (readl(sar) >> SAR_DOVE_CPU_FREQ) &
+		SAR_DOVE_CPU_FREQ_MASK;
+	return dove_cpu_freqs[opt];
+}
+
+static const int __initconst dove_cpu_l2_ratios[8][2] = {
+	{ 1, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
+	{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 }
+};
+
+static const int __initconst dove_cpu_ddr_ratios[16][2] = {
+	{ 1, 1 }, { 0, 1 }, { 1, 2 }, { 2, 5 },
+	{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 },
+	{ 1, 5 }, { 0, 1 }, { 1, 6 }, { 0, 1 },
+	{ 1, 7 }, { 0, 1 }, { 1, 8 }, { 1, 10 }
+};
+
+static void __init dove_get_clk_ratio(
+	void __iomem *sar, int id, int *mult, int *div)
+{
+	switch (id) {
+	case DOVE_CPU_TO_L2:
+	{
+		u32 opt = (readl(sar) >> SAR_DOVE_L2_RATIO) &
+			SAR_DOVE_L2_RATIO_MASK;
+		*mult = dove_cpu_l2_ratios[opt][0];
+		*div = dove_cpu_l2_ratios[opt][1];
+		break;
+	}
+	case DOVE_CPU_TO_DDR:
+	{
+		u32 opt = (readl(sar) >> SAR_DOVE_DDR_RATIO) &
+			SAR_DOVE_DDR_RATIO_MASK;
+		*mult = dove_cpu_ddr_ratios[opt][0];
+		*div = dove_cpu_ddr_ratios[opt][1];
+		break;
+	}
+	}
+}
+
+static const struct coreclk_soc_desc dove_coreclks = {
+	.get_tclk_freq = dove_get_tclk_freq,
+	.get_cpu_freq = dove_get_cpu_freq,
+	.get_clk_ratio = dove_get_clk_ratio,
+	.ratios = dove_coreclk_ratios,
+	.num_ratios = ARRAY_SIZE(dove_coreclk_ratios),
+};
+
+static void __init dove_coreclk_init(struct device_node *np)
+{
+	mvebu_coreclk_setup(np, &dove_coreclks);
+}
+CLK_OF_DECLARE(dove_core_clk, "marvell,dove-core-clock", dove_coreclk_init);
+
+/*
+ * Clock Gating Control
+ */
+
+static const struct clk_gating_soc_desc __initconst dove_gating_desc[] = {
+	{ "usb0", NULL, 0, 0 },
+	{ "usb1", NULL, 1, 0 },
+	{ "ge",	"gephy", 2, 0 },
+	{ "sata", NULL, 3, 0 },
+	{ "pex0", NULL, 4, 0 },
+	{ "pex1", NULL, 5, 0 },
+	{ "sdio0", NULL, 8, 0 },
+	{ "sdio1", NULL, 9, 0 },
+	{ "nand", NULL, 10, 0 },
+	{ "camera", NULL, 11, 0 },
+	{ "i2s0", NULL, 12, 0 },
+	{ "i2s1", NULL, 13, 0 },
+	{ "crypto", NULL, 15, 0 },
+	{ "ac97", NULL, 21, 0 },
+	{ "pdma", NULL, 22, 0 },
+	{ "xor0", NULL, 23, 0 },
+	{ "xor1", NULL, 24, 0 },
+	{ "gephy", NULL, 30, 0 },
+	{ }
+};
+
+static void __init dove_clk_gating_init(struct device_node *np)
+{
+	mvebu_clk_gating_setup(np, dove_gating_desc);
+}
+CLK_OF_DECLARE(dove_clk_gating, "marvell,dove-gating-clock",
+	       dove_clk_gating_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/Kconfig linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/Kconfig
--- linux-libre-3.10-gnu/drivers/clk/mvebu/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,8 +1,23 @@
-config MVEBU_CLK_CORE
-       bool
+config MVEBU_CLK_COMMON
+	bool
 
 config MVEBU_CLK_CPU
-       bool
+	bool
 
-config MVEBU_CLK_GATING
-       bool
+config ARMADA_370_CLK
+	bool
+	select MVEBU_CLK_COMMON
+	select MVEBU_CLK_CPU
+
+config ARMADA_XP_CLK
+	bool
+	select MVEBU_CLK_COMMON
+	select MVEBU_CLK_CPU
+
+config DOVE_CLK
+	bool
+	select MVEBU_CLK_COMMON
+
+config KIRKWOOD_CLK
+	bool
+	select MVEBU_CLK_COMMON
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/kirkwood.c linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/kirkwood.c
--- linux-libre-3.10-gnu/drivers/clk/mvebu/kirkwood.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/kirkwood.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,247 @@
+/*
+ * Marvell Kirkwood SoC clocks
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include "common.h"
+
+/*
+ * Core Clocks
+ *
+ * Kirkwood PLL sample-at-reset configuration
+ * (6180 has different SAR layout than other Kirkwood SoCs)
+ *
+ * SAR0[4:3,22,1] : CPU frequency (6281,6292,6282)
+ *	4  =  600 MHz
+ *	6  =  800 MHz
+ *	7  = 1000 MHz
+ *	9  = 1200 MHz
+ *	12 = 1500 MHz
+ *	13 = 1600 MHz
+ *	14 = 1800 MHz
+ *	15 = 2000 MHz
+ *	others reserved.
+ *
+ * SAR0[19,10:9] : CPU to L2 Clock divider ratio (6281,6292,6282)
+ *	1 = (1/2) * CPU
+ *	3 = (1/3) * CPU
+ *	5 = (1/4) * CPU
+ *	others reserved.
+ *
+ * SAR0[8:5] : CPU to DDR DRAM Clock divider ratio (6281,6292,6282)
+ *	2 = (1/2) * CPU
+ *	4 = (1/3) * CPU
+ *	6 = (1/4) * CPU
+ *	7 = (2/9) * CPU
+ *	8 = (1/5) * CPU
+ *	9 = (1/6) * CPU
+ *	others reserved.
+ *
+ * SAR0[4:2] : Kirkwood 6180 cpu/l2/ddr clock configuration (6180 only)
+ *	5 = [CPU =  600 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/3) * CPU]
+ *	6 = [CPU =  800 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/4) * CPU]
+ *	7 = [CPU = 1000 MHz, L2 = (1/2) * CPU, DDR = 200 MHz = (1/5) * CPU]
+ *	others reserved.
+ *
+ * SAR0[21] : TCLK frequency
+ *	0 = 200 MHz
+ *	1 = 166 MHz
+ *	others reserved.
+ */
+
+#define SAR_KIRKWOOD_CPU_FREQ(x)	\
+	(((x & (1 <<  1)) >>  1) |	\
+	 ((x & (1 << 22)) >> 21) |	\
+	 ((x & (3 <<  3)) >>  1))
+#define SAR_KIRKWOOD_L2_RATIO(x)	\
+	(((x & (3 <<  9)) >> 9) |	\
+	 (((x & (1 << 19)) >> 17)))
+#define SAR_KIRKWOOD_DDR_RATIO		5
+#define SAR_KIRKWOOD_DDR_RATIO_MASK	0xf
+#define SAR_MV88F6180_CLK		2
+#define SAR_MV88F6180_CLK_MASK		0x7
+#define SAR_KIRKWOOD_TCLK_FREQ		21
+#define SAR_KIRKWOOD_TCLK_FREQ_MASK	0x1
+
+enum { KIRKWOOD_CPU_TO_L2, KIRKWOOD_CPU_TO_DDR };
+
+static const struct coreclk_ratio __initconst kirkwood_coreclk_ratios[] = {
+	{ .id = KIRKWOOD_CPU_TO_L2, .name = "l2clk", },
+	{ .id = KIRKWOOD_CPU_TO_DDR, .name = "ddrclk", }
+};
+
+static u32 __init kirkwood_get_tclk_freq(void __iomem *sar)
+{
+	u32 opt = (readl(sar) >> SAR_KIRKWOOD_TCLK_FREQ) &
+		SAR_KIRKWOOD_TCLK_FREQ_MASK;
+	return (opt) ? 166666667 : 200000000;
+}
+
+static const u32 __initconst kirkwood_cpu_freqs[] = {
+	0, 0, 0, 0,
+	600000000,
+	0,
+	800000000,
+	1000000000,
+	0,
+	1200000000,
+	0, 0,
+	1500000000,
+	1600000000,
+	1800000000,
+	2000000000
+};
+
+static u32 __init kirkwood_get_cpu_freq(void __iomem *sar)
+{
+	u32 opt = SAR_KIRKWOOD_CPU_FREQ(readl(sar));
+	return kirkwood_cpu_freqs[opt];
+}
+
+static const int __initconst kirkwood_cpu_l2_ratios[8][2] = {
+	{ 0, 1 }, { 1, 2 }, { 0, 1 }, { 1, 3 },
+	{ 0, 1 }, { 1, 4 }, { 0, 1 }, { 0, 1 }
+};
+
+static const int __initconst kirkwood_cpu_ddr_ratios[16][2] = {
+	{ 0, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
+	{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 2, 9 },
+	{ 1, 5 }, { 1, 6 }, { 0, 1 }, { 0, 1 },
+	{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 }
+};
+
+static void __init kirkwood_get_clk_ratio(
+	void __iomem *sar, int id, int *mult, int *div)
+{
+	switch (id) {
+	case KIRKWOOD_CPU_TO_L2:
+	{
+		u32 opt = SAR_KIRKWOOD_L2_RATIO(readl(sar));
+		*mult = kirkwood_cpu_l2_ratios[opt][0];
+		*div = kirkwood_cpu_l2_ratios[opt][1];
+		break;
+	}
+	case KIRKWOOD_CPU_TO_DDR:
+	{
+		u32 opt = (readl(sar) >> SAR_KIRKWOOD_DDR_RATIO) &
+			SAR_KIRKWOOD_DDR_RATIO_MASK;
+		*mult = kirkwood_cpu_ddr_ratios[opt][0];
+		*div = kirkwood_cpu_ddr_ratios[opt][1];
+		break;
+	}
+	}
+}
+
+static const u32 __initconst mv88f6180_cpu_freqs[] = {
+	0, 0, 0, 0, 0,
+	600000000,
+	800000000,
+	1000000000
+};
+
+static u32 __init mv88f6180_get_cpu_freq(void __iomem *sar)
+{
+	u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) & SAR_MV88F6180_CLK_MASK;
+	return mv88f6180_cpu_freqs[opt];
+}
+
+static const int __initconst mv88f6180_cpu_ddr_ratios[8][2] = {
+	{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 },
+	{ 0, 1 }, { 1, 3 }, { 1, 4 }, { 1, 5 }
+};
+
+static void __init mv88f6180_get_clk_ratio(
+	void __iomem *sar, int id, int *mult, int *div)
+{
+	switch (id) {
+	case KIRKWOOD_CPU_TO_L2:
+	{
+		/* mv88f6180 has a fixed 1:2 CPU-to-L2 ratio */
+		*mult = 1;
+		*div = 2;
+		break;
+	}
+	case KIRKWOOD_CPU_TO_DDR:
+	{
+		u32 opt = (readl(sar) >> SAR_MV88F6180_CLK) &
+			SAR_MV88F6180_CLK_MASK;
+		*mult = mv88f6180_cpu_ddr_ratios[opt][0];
+		*div = mv88f6180_cpu_ddr_ratios[opt][1];
+		break;
+	}
+	}
+}
+
+static const struct coreclk_soc_desc kirkwood_coreclks = {
+	.get_tclk_freq = kirkwood_get_tclk_freq,
+	.get_cpu_freq = kirkwood_get_cpu_freq,
+	.get_clk_ratio = kirkwood_get_clk_ratio,
+	.ratios = kirkwood_coreclk_ratios,
+	.num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios),
+};
+
+static void __init kirkwood_coreclk_init(struct device_node *np)
+{
+	mvebu_coreclk_setup(np, &kirkwood_coreclks);
+}
+CLK_OF_DECLARE(kirkwood_core_clk, "marvell,kirkwood-core-clock",
+	       kirkwood_coreclk_init);
+
+static const struct coreclk_soc_desc mv88f6180_coreclks = {
+	.get_tclk_freq = kirkwood_get_tclk_freq,
+	.get_cpu_freq = mv88f6180_get_cpu_freq,
+	.get_clk_ratio = mv88f6180_get_clk_ratio,
+	.ratios = kirkwood_coreclk_ratios,
+	.num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios),
+};
+
+static void __init mv88f6180_coreclk_init(struct device_node *np)
+{
+	mvebu_coreclk_setup(np, &mv88f6180_coreclks);
+}
+CLK_OF_DECLARE(mv88f6180_core_clk, "marvell,mv88f6180-core-clock",
+	       mv88f6180_coreclk_init);
+
+/*
+ * Clock Gating Control
+ */
+
+static const struct clk_gating_soc_desc __initconst kirkwood_gating_desc[] = {
+	{ "ge0", NULL, 0, 0 },
+	{ "pex0", NULL, 2, 0 },
+	{ "usb0", NULL, 3, 0 },
+	{ "sdio", NULL, 4, 0 },
+	{ "tsu", NULL, 5, 0 },
+	{ "runit", NULL, 7, 0 },
+	{ "xor0", NULL, 8, 0 },
+	{ "audio", NULL, 9, 0 },
+	{ "powersave", "cpuclk", 11, 0 },
+	{ "sata0", NULL, 14, 0 },
+	{ "sata1", NULL, 15, 0 },
+	{ "xor1", NULL, 16, 0 },
+	{ "crypto", NULL, 17, 0 },
+	{ "pex1", NULL, 18, 0 },
+	{ "ge1", NULL, 19, 0 },
+	{ "tdm", NULL, 20, 0 },
+	{ }
+};
+
+static void __init kirkwood_clk_gating_init(struct device_node *np)
+{
+	mvebu_clk_gating_setup(np, kirkwood_gating_desc);
+}
+CLK_OF_DECLARE(kirkwood_clk_gating, "marvell,kirkwood-gating-clock",
+	       kirkwood_clk_gating_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/mvebu/Makefile linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/Makefile
--- linux-libre-3.10-gnu/drivers/clk/mvebu/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/mvebu/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,3 +1,7 @@
-obj-$(CONFIG_MVEBU_CLK_CORE) 	+= clk.o clk-core.o
+obj-$(CONFIG_MVEBU_CLK_COMMON)	+= common.o
 obj-$(CONFIG_MVEBU_CLK_CPU) 	+= clk-cpu.o
-obj-$(CONFIG_MVEBU_CLK_GATING) 	+= clk-gating-ctrl.o
+
+obj-$(CONFIG_ARMADA_370_CLK)	+= armada-370.o
+obj-$(CONFIG_ARMADA_XP_CLK)	+= armada-xp.o
+obj-$(CONFIG_DOVE_CLK)		+= dove.o
+obj-$(CONFIG_KIRKWOOD_CLK)	+= kirkwood.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/rockchip/clk-rockchip.c linux-libre-3.11-rc7-gnu/drivers/clk/rockchip/clk-rockchip.c
--- linux-libre-3.10-gnu/drivers/clk/rockchip/clk-rockchip.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/rockchip/clk-rockchip.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+static DEFINE_SPINLOCK(clk_lock);
+
+/*
+ * Gate clocks
+ */
+
+static void __init rk2928_gate_clk_init(struct device_node *node,
+					 void *data)
+{
+	struct clk_onecell_data *clk_data;
+	const char *clk_parent;
+	const char *clk_name;
+	void __iomem *reg;
+	void __iomem *reg_idx;
+	int flags;
+	int qty;
+	int reg_bit;
+	int clkflags = CLK_SET_RATE_PARENT;
+	int i;
+
+	qty = of_property_count_strings(node, "clock-output-names");
+	if (qty < 0) {
+		pr_err("%s: error in clock-output-names %d\n", __func__, qty);
+		return;
+	}
+
+	if (qty == 0) {
+		pr_info("%s: nothing to do\n", __func__);
+		return;
+	}
+
+	reg = of_iomap(node, 0);
+
+	clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+	if (!clk_data)
+		return;
+
+	clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL);
+	if (!clk_data->clks) {
+		kfree(clk_data);
+		return;
+	}
+
+	flags = CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE;
+
+	for (i = 0; i < qty; i++) {
+		of_property_read_string_index(node, "clock-output-names",
+					      i, &clk_name);
+
+		/* ignore empty slots */
+		if (!strcmp("reserved", clk_name))
+			continue;
+
+		clk_parent = of_clk_get_parent_name(node, i);
+
+		/* keep all gates untouched for now */
+		clkflags |= CLK_IGNORE_UNUSED;
+
+		reg_idx = reg + (4 * (i / 16));
+		reg_bit = (i % 16);
+
+		clk_data->clks[i] = clk_register_gate(NULL, clk_name,
+						      clk_parent, clkflags,
+						      reg_idx, reg_bit,
+						      flags,
+						      &clk_lock);
+		WARN_ON(IS_ERR(clk_data->clks[i]));
+	}
+
+	clk_data->clk_num = qty;
+
+	of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+CLK_OF_DECLARE(rk2928_gate, "rockchip,rk2928-gate-clk", rk2928_gate_clk_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/rockchip/Makefile linux-libre-3.11-rc7-gnu/drivers/clk/rockchip/Makefile
--- linux-libre-3.10-gnu/drivers/clk/rockchip/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/rockchip/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,5 @@
+#
+# Rockchip Clock specific Makefile
+#
+
+obj-y	+= clk-rockchip.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/samsung/clk-exynos4.c linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk-exynos4.c
--- linux-libre-3.10-gnu/drivers/clk/samsung/clk-exynos4.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk-exynos4.c	2013-08-25 20:43:22.000000000 -0400
@@ -151,7 +151,7 @@ enum exynos4_clks {
 	sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
 	sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1,
 	sclk_i2s2, sclk_mipihsi, sclk_mfc, sclk_pcm0, sclk_g3d, sclk_pwm_isp,
-	sclk_spi0_isp, sclk_spi1_isp, sclk_uart_isp,
+	sclk_spi0_isp, sclk_spi1_isp, sclk_uart_isp, sclk_fimg2d,
 
 	/* gate clocks */
 	fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
@@ -356,8 +356,8 @@ struct samsung_fixed_rate_clock exynos42
 
 /* list of mux clocks supported in all exynos4 soc's */
 struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
-	MUX_F(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
-			CLK_SET_RATE_PARENT, 0),
+	MUX_FA(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
+			CLK_SET_RATE_PARENT, 0, "mout_apll"),
 	MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1),
 	MUX(none, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1),
 	MUX(none, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1),
@@ -385,9 +385,9 @@ struct samsung_mux_clock exynos4210_mux_
 	MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1),
 	MUX(none, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4),
 	MUX(none, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4),
-	MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "sclk_mpll"),
+	MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "mout_mpll"),
 	MUX_A(mout_core, "mout_core", mout_core_p4210,
-			SRC_CPU, 16, 1, "mout_core"),
+			SRC_CPU, 16, 1, "moutcore"),
 	MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210,
 			SRC_TOP0, 8, 1, "sclk_vpll"),
 	MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4),
@@ -424,8 +424,8 @@ struct samsung_mux_clock exynos4210_mux_
 
 /* list of mux clocks supported in exynos4x12 soc */
 struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
-	MUX(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12,
-			SRC_CPU, 24, 1),
+	MUX_A(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12,
+			SRC_CPU, 24, 1, "mout_mpll"),
 	MUX(none, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1),
 	MUX(none, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1),
 	MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12,
@@ -449,7 +449,8 @@ struct samsung_mux_clock exynos4x12_mux_
 			SRC_DMC, 12, 1, "sclk_mpll"),
 	MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p,
 			SRC_TOP0, 8, 1, "sclk_vpll"),
-	MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1),
+	MUX_A(mout_core, "mout_core", mout_core_p4x12,
+			SRC_CPU, 16, 1, "moutcore"),
 	MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4),
 	MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4),
 	MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4),
@@ -484,6 +485,9 @@ struct samsung_mux_clock exynos4x12_mux_
 	MUX(none, "mout_spi0_isp", group1_p4x12, E4X12_SRC_ISP, 4, 4),
 	MUX(none, "mout_spi1_isp", group1_p4x12, E4X12_SRC_ISP, 8, 4),
 	MUX(none, "mout_uart_isp", group1_p4x12, E4X12_SRC_ISP, 12, 4),
+	MUX(none, "mout_g2d0", sclk_ampll_p4210, SRC_DMC, 20, 1),
+	MUX(none, "mout_g2d1", sclk_evpll_p, SRC_DMC, 24, 1),
+	MUX(none, "mout_g2d", mout_g2d_p, SRC_DMC, 28, 1),
 };
 
 /* list of divider clocks supported in all exynos4 soc's */
@@ -534,7 +538,7 @@ struct samsung_div_clock exynos4_div_clk
 	DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8),
 	DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4),
 	DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
-	DIV_A(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3, "arm_clk"),
+	DIV_A(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3, "armclk"),
 	DIV_A(sclk_apll, "sclk_apll", "mout_apll",
 			DIV_CPU0, 24, 3, "sclk_apll"),
 	DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4,
@@ -552,7 +556,7 @@ struct samsung_div_clock exynos4_div_clk
 /* list of divider clocks supported in exynos4210 soc */
 struct samsung_div_clock exynos4210_div_clks[] __initdata = {
 	DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3),
-	DIV(none, "div_g2d", "mout_g2d", DIV_IMAGE, 0, 4),
+	DIV(sclk_fimg2d, "sclk_fimg2d", "mout_g2d", DIV_IMAGE, 0, 4),
 	DIV(none, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4),
 	DIV(none, "div_mipi1", "mout_mipi1", E4210_DIV_LCD1, 16, 4),
 	DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4),
@@ -577,11 +581,16 @@ struct samsung_div_clock exynos4x12_div_
 	DIV(none, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4),
 	DIV(none, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8),
 	DIV(none, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4),
-	DIV(div_isp0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3),
-	DIV(div_isp1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3),
+	DIV_F(div_isp0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3,
+						CLK_GET_RATE_NOCACHE, 0),
+	DIV_F(div_isp1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3,
+						CLK_GET_RATE_NOCACHE, 0),
 	DIV(none, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
-	DIV(div_mcuisp0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, 4, 3),
-	DIV(div_mcuisp1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, 8, 3),
+	DIV_F(div_mcuisp0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1,
+						4, 3, CLK_GET_RATE_NOCACHE, 0),
+	DIV_F(div_mcuisp1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
+						8, 3, CLK_GET_RATE_NOCACHE, 0),
+	DIV(sclk_fimg2d, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
 };
 
 /* list of gate clocks supported in all exynos4 soc's */
@@ -858,57 +867,58 @@ struct samsung_gate_clock exynos4x12_gat
 	GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100",
 			E4X12_GATE_IP_MAUDIO, 3, 0, 0, "iis"),
 	GATE(fimc_isp, "isp", "aclk200", E4X12_GATE_ISP0, 0,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(fimc_fd, "fd", "aclk200", E4X12_GATE_ISP0, 2,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(fimc_lite0, "lite0", "aclk200", E4X12_GATE_ISP0, 3,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(fimc_lite1, "lite1", "aclk200", E4X12_GATE_ISP0, 4,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(mcuisp, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(gicisp, "gicisp", "aclk200", E4X12_GATE_ISP0, 7,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(smmu_isp, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(smmu_drc, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(smmu_fd, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(smmu_lite0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(smmu_lite1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(ppmuispmx, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(ppmuispx, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(mcuctl_isp, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(mpwm_isp, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(i2c0_isp, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(i2c1_isp, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(mtcadc_isp, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(pwm_isp, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(wdt_isp, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(uart_isp, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(asyncaxim, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(smmu_ispcx, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(spi0_isp, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
 	GATE(spi1_isp, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
-			CLK_IGNORE_UNUSED, 0),
+			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
+	GATE(g2d, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0),
 };
 
 /*
@@ -1065,9 +1075,9 @@ void __init exynos4_clk_init(struct devi
 	pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
 		"\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
 		exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
-		_get_rate("sclk_apll"),	_get_rate("sclk_mpll"),
+		_get_rate("sclk_apll"),	_get_rate("mout_mpll"),
 		_get_rate("sclk_epll"), _get_rate("sclk_vpll"),
-		_get_rate("arm_clk"));
+		_get_rate("armclk"));
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/samsung/clk-exynos5250.c linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk-exynos5250.c
--- linux-libre-3.10-gnu/drivers/clk/samsung/clk-exynos5250.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk-exynos5250.c	2013-08-25 20:43:22.000000000 -0400
@@ -87,6 +87,7 @@ enum exynos5250_clks {
 	sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_sata, sclk_usb3,
 	sclk_jpeg, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_pwm,
 	sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
+	div_i2s1, div_i2s2,
 
 	/* gate clocks */
 	gscl0 = 256, gscl1, gscl2, gscl3, gscl_wa, gscl_wb, smmu_gscl0,
@@ -291,8 +292,8 @@ struct samsung_div_clock exynos5250_div_
 	DIV(none, "div_pcm1", "sclk_audio1", DIV_PERIC4, 4, 8),
 	DIV(none, "div_audio2", "mout_audio2", DIV_PERIC4, 16, 4),
 	DIV(none, "div_pcm2", "sclk_audio2", DIV_PERIC4, 20, 8),
-	DIV(none, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6),
-	DIV(none, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6),
+	DIV(div_i2s1, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6),
+	DIV(div_i2s2, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6),
 	DIV(sclk_pixel, "div_hdmi_pixel", "sclk_vpll", DIV_DISP1_0, 28, 4),
 	DIV_A(none, "armclk", "div_arm", DIV_CPU0, 28, 3, "armclk"),
 	DIV_F(none, "div_mipi1_pre", "div_mipi1",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/samsung/clk-exynos5420.c linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk-exynos5420.c
--- linux-libre-3.10-gnu/drivers/clk/samsung/clk-exynos5420.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk-exynos5420.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,762 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Authors: Thomas Abraham <thomas.ab@samsung.com>
+ *	    Chander Kashyap <k.chander@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for Exynos5420 SoC.
+*/
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "clk.h"
+#include "clk-pll.h"
+
+#define SRC_CPU			0x200
+#define DIV_CPU0		0x500
+#define DIV_CPU1		0x504
+#define GATE_BUS_CPU		0x700
+#define GATE_SCLK_CPU		0x800
+#define SRC_TOP0		0x10200
+#define SRC_TOP1		0x10204
+#define SRC_TOP2		0x10208
+#define SRC_TOP3		0x1020c
+#define SRC_TOP4		0x10210
+#define SRC_TOP5		0x10214
+#define SRC_TOP6		0x10218
+#define SRC_TOP7		0x1021c
+#define SRC_DISP10		0x1022c
+#define SRC_MAU			0x10240
+#define SRC_FSYS		0x10244
+#define SRC_PERIC0		0x10250
+#define SRC_PERIC1		0x10254
+#define SRC_TOP10		0x10280
+#define SRC_TOP11		0x10284
+#define SRC_TOP12		0x10288
+#define	SRC_MASK_DISP10		0x1032c
+#define SRC_MASK_FSYS		0x10340
+#define SRC_MASK_PERIC0		0x10350
+#define SRC_MASK_PERIC1		0x10354
+#define DIV_TOP0		0x10500
+#define DIV_TOP1		0x10504
+#define DIV_TOP2		0x10508
+#define DIV_DISP10		0x1052c
+#define DIV_MAU			0x10544
+#define DIV_FSYS0		0x10548
+#define DIV_FSYS1		0x1054c
+#define DIV_FSYS2		0x10550
+#define DIV_PERIC0		0x10558
+#define DIV_PERIC1		0x1055c
+#define DIV_PERIC2		0x10560
+#define DIV_PERIC3		0x10564
+#define DIV_PERIC4		0x10568
+#define GATE_BUS_TOP		0x10700
+#define GATE_BUS_FSYS0		0x10740
+#define GATE_BUS_PERIC		0x10750
+#define GATE_BUS_PERIC1		0x10754
+#define GATE_BUS_PERIS0		0x10760
+#define GATE_BUS_PERIS1		0x10764
+#define GATE_IP_GSCL0		0x10910
+#define GATE_IP_GSCL1		0x10920
+#define GATE_IP_MFC		0x1092c
+#define GATE_IP_DISP1		0x10928
+#define GATE_IP_G3D		0x10930
+#define GATE_IP_GEN		0x10934
+#define GATE_IP_MSCL		0x10970
+#define GATE_TOP_SCLK_GSCL	0x10820
+#define GATE_TOP_SCLK_DISP1	0x10828
+#define GATE_TOP_SCLK_MAU	0x1083c
+#define GATE_TOP_SCLK_FSYS	0x10840
+#define GATE_TOP_SCLK_PERIC	0x10850
+#define SRC_CDREX		0x20200
+#define SRC_KFC			0x28200
+#define DIV_KFC0		0x28500
+
+enum exynos5420_clks {
+	none,
+
+	/* core clocks */
+	fin_pll,
+
+	/* gate for special clocks (sclk) */
+	sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0,
+	sclk_mmc1, sclk_mmc2, sclk_spi0, sclk_spi1, sclk_spi2, sclk_i2s1,
+	sclk_i2s2, sclk_pcm1, sclk_pcm2, sclk_spdif, sclk_hdmi, sclk_pixel,
+	sclk_dp1, sclk_mipi1, sclk_fimd1, sclk_maudio0, sclk_maupcm0,
+	sclk_usbd300, sclk_usbd301, sclk_usbphy300, sclk_usbphy301, sclk_unipro,
+	sclk_pwm, sclk_gscl_wa, sclk_gscl_wb,
+
+	/* gate clocks */
+	aclk66_peric = 256, uart0, uart1, uart2, uart3, i2c0, i2c1, i2c2, i2c3,
+	i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc, spi0, spi1, spi2, keyif, i2s1,
+	i2s2, pcm1, pcm2, pwm, spdif, i2c8, i2c9, i2c10, aclk66_psgen = 300,
+	chipid, sysreg, tzpc0, tzpc1, tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7,
+	tzpc8, tzpc9, hdmi_cec, seckey, mct, wdt, rtc, tmu, tmu_gpu,
+	pclk66_gpio = 330, aclk200_fsys2 = 350, mmc0, mmc1, mmc2, sromc, ufs,
+	aclk200_fsys = 360, tsi, pdma0, pdma1, rtic, usbh20, usbd300, usbd301,
+	aclk400_mscl = 380, mscl0, mscl1, mscl2, smmu_mscl0, smmu_mscl1,
+	smmu_mscl2, aclk333 = 400, mfc, smmu_mfcl, smmu_mfcr,
+	aclk200_disp1 = 410, dsim1, dp1, hdmi, aclk300_disp1 = 420, fimd1,
+	smmu_fimd1, aclk166 = 430, mixer, aclk266 = 440, rotator, mdma1,
+	smmu_rotator, smmu_mdma1, aclk300_jpeg = 450, jpeg, jpeg2, smmu_jpeg,
+	aclk300_gscl = 460, smmu_gscl0, smmu_gscl1, gscl_wa, gscl_wb, gscl0,
+	gscl1, clk_3aa, aclk266_g2d = 470, sss, slim_sss, mdma0,
+	aclk333_g2d = 480, g2d, aclk333_432_gscl = 490, smmu_3aa, smmu_fimcl0,
+	smmu_fimcl1, smmu_fimcl3, fimc_lite3, aclk_g3d = 500, g3d,
+
+	nr_clks,
+};
+
+/*
+ * list of controller registers to be saved and restored during a
+ * suspend/resume cycle.
+ */
+static __initdata unsigned long exynos5420_clk_regs[] = {
+	SRC_CPU,
+	DIV_CPU0,
+	DIV_CPU1,
+	GATE_BUS_CPU,
+	GATE_SCLK_CPU,
+	SRC_TOP0,
+	SRC_TOP1,
+	SRC_TOP2,
+	SRC_TOP3,
+	SRC_TOP4,
+	SRC_TOP5,
+	SRC_TOP6,
+	SRC_TOP7,
+	SRC_DISP10,
+	SRC_MAU,
+	SRC_FSYS,
+	SRC_PERIC0,
+	SRC_PERIC1,
+	SRC_TOP10,
+	SRC_TOP11,
+	SRC_TOP12,
+	SRC_MASK_DISP10,
+	SRC_MASK_FSYS,
+	SRC_MASK_PERIC0,
+	SRC_MASK_PERIC1,
+	DIV_TOP0,
+	DIV_TOP1,
+	DIV_TOP2,
+	DIV_DISP10,
+	DIV_MAU,
+	DIV_FSYS0,
+	DIV_FSYS1,
+	DIV_FSYS2,
+	DIV_PERIC0,
+	DIV_PERIC1,
+	DIV_PERIC2,
+	DIV_PERIC3,
+	DIV_PERIC4,
+	GATE_BUS_TOP,
+	GATE_BUS_FSYS0,
+	GATE_BUS_PERIC,
+	GATE_BUS_PERIC1,
+	GATE_BUS_PERIS0,
+	GATE_BUS_PERIS1,
+	GATE_IP_GSCL0,
+	GATE_IP_GSCL1,
+	GATE_IP_MFC,
+	GATE_IP_DISP1,
+	GATE_IP_G3D,
+	GATE_IP_GEN,
+	GATE_IP_MSCL,
+	GATE_TOP_SCLK_GSCL,
+	GATE_TOP_SCLK_DISP1,
+	GATE_TOP_SCLK_MAU,
+	GATE_TOP_SCLK_FSYS,
+	GATE_TOP_SCLK_PERIC,
+	SRC_CDREX,
+	SRC_KFC,
+	DIV_KFC0,
+};
+
+/* list of all parent clocks */
+PNAME(mspll_cpu_p)	= { "sclk_cpll", "sclk_dpll",
+				"sclk_mpll", "sclk_spll" };
+PNAME(cpu_p)		= { "mout_apll" , "mout_mspll_cpu" };
+PNAME(kfc_p)		= { "mout_kpll" , "mout_mspll_kfc" };
+PNAME(apll_p)		= { "fin_pll", "fout_apll", };
+PNAME(bpll_p)		= { "fin_pll", "fout_bpll", };
+PNAME(cpll_p)		= { "fin_pll", "fout_cpll", };
+PNAME(dpll_p)		= { "fin_pll", "fout_dpll", };
+PNAME(epll_p)		= { "fin_pll", "fout_epll", };
+PNAME(ipll_p)		= { "fin_pll", "fout_ipll", };
+PNAME(kpll_p)		= { "fin_pll", "fout_kpll", };
+PNAME(mpll_p)		= { "fin_pll", "fout_mpll", };
+PNAME(rpll_p)		= { "fin_pll", "fout_rpll", };
+PNAME(spll_p)		= { "fin_pll", "fout_spll", };
+PNAME(vpll_p)		= { "fin_pll", "fout_vpll", };
+
+PNAME(group1_p)		= { "sclk_cpll", "sclk_dpll", "sclk_mpll" };
+PNAME(group2_p)		= { "fin_pll", "sclk_cpll", "sclk_dpll", "sclk_mpll",
+			  "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" };
+PNAME(group3_p)		= { "sclk_rpll", "sclk_spll" };
+PNAME(group4_p)		= { "sclk_ipll", "sclk_dpll", "sclk_mpll" };
+PNAME(group5_p)		= { "sclk_vpll", "sclk_dpll" };
+
+PNAME(sw_aclk66_p)	= { "dout_aclk66", "sclk_spll" };
+PNAME(aclk66_peric_p)	= { "fin_pll", "mout_sw_aclk66" };
+
+PNAME(sw_aclk200_fsys_p) = { "dout_aclk200_fsys", "sclk_spll"};
+PNAME(user_aclk200_fsys_p)	= { "fin_pll", "mout_sw_aclk200_fsys" };
+
+PNAME(sw_aclk200_fsys2_p) = { "dout_aclk200_fsys2", "sclk_spll"};
+PNAME(user_aclk200_fsys2_p)	= { "fin_pll", "mout_sw_aclk200_fsys2" };
+
+PNAME(sw_aclk200_p) = { "dout_aclk200", "sclk_spll"};
+PNAME(aclk200_disp1_p)	= { "fin_pll", "mout_sw_aclk200" };
+
+PNAME(sw_aclk400_mscl_p) = { "dout_aclk400_mscl", "sclk_spll"};
+PNAME(user_aclk400_mscl_p)	= { "fin_pll", "mout_sw_aclk400_mscl" };
+
+PNAME(sw_aclk333_p) = { "dout_aclk333", "sclk_spll"};
+PNAME(user_aclk333_p)	= { "fin_pll", "mout_sw_aclk333" };
+
+PNAME(sw_aclk166_p) = { "dout_aclk166", "sclk_spll"};
+PNAME(user_aclk166_p)	= { "fin_pll", "mout_sw_aclk166" };
+
+PNAME(sw_aclk266_p) = { "dout_aclk266", "sclk_spll"};
+PNAME(user_aclk266_p)	= { "fin_pll", "mout_sw_aclk266" };
+
+PNAME(sw_aclk333_432_gscl_p) = { "dout_aclk333_432_gscl", "sclk_spll"};
+PNAME(user_aclk333_432_gscl_p)	= { "fin_pll", "mout_sw_aclk333_432_gscl" };
+
+PNAME(sw_aclk300_gscl_p) = { "dout_aclk300_gscl", "sclk_spll"};
+PNAME(user_aclk300_gscl_p)	= { "fin_pll", "mout_sw_aclk300_gscl" };
+
+PNAME(sw_aclk300_disp1_p) = { "dout_aclk300_disp1", "sclk_spll"};
+PNAME(user_aclk300_disp1_p)	= { "fin_pll", "mout_sw_aclk300_disp1" };
+
+PNAME(sw_aclk300_jpeg_p) = { "dout_aclk300_jpeg", "sclk_spll"};
+PNAME(user_aclk300_jpeg_p)	= { "fin_pll", "mout_sw_aclk300_jpeg" };
+
+PNAME(sw_aclk_g3d_p) = { "dout_aclk_g3d", "sclk_spll"};
+PNAME(user_aclk_g3d_p)	= { "fin_pll", "mout_sw_aclk_g3d" };
+
+PNAME(sw_aclk266_g2d_p) = { "dout_aclk266_g2d", "sclk_spll"};
+PNAME(user_aclk266_g2d_p)	= { "fin_pll", "mout_sw_aclk266_g2d" };
+
+PNAME(sw_aclk333_g2d_p) = { "dout_aclk333_g2d", "sclk_spll"};
+PNAME(user_aclk333_g2d_p)	= { "fin_pll", "mout_sw_aclk333_g2d" };
+
+PNAME(audio0_p)	= { "fin_pll", "cdclk0", "sclk_dpll", "sclk_mpll",
+		  "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" };
+PNAME(audio1_p)	= { "fin_pll", "cdclk1", "sclk_dpll", "sclk_mpll",
+		  "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" };
+PNAME(audio2_p)	= { "fin_pll", "cdclk2", "sclk_dpll", "sclk_mpll",
+		  "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" };
+PNAME(spdif_p)	= { "fin_pll", "dout_audio0", "dout_audio1", "dout_audio2",
+		  "spdif_extclk", "sclk_ipll", "sclk_epll", "sclk_rpll" };
+PNAME(hdmi_p)	= { "sclk_hdmiphy", "dout_hdmi_pixel" };
+PNAME(maudio0_p)	= { "fin_pll", "maudio_clk", "sclk_dpll", "sclk_mpll",
+			  "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" };
+
+/* fixed rate clocks generated outside the soc */
+struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = {
+	FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0),
+};
+
+/* fixed rate clocks generated inside the soc */
+struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = {
+	FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
+	FRATE(none, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000),
+	FRATE(none, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000),
+	FRATE(none, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000),
+	FRATE(none, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000),
+};
+
+struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = {
+	FFACTOR(none, "sclk_hsic_12m", "fin_pll", 1, 2, 0),
+};
+
+struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
+	MUX(none, "mout_mspll_kfc", mspll_cpu_p, SRC_TOP7, 8, 2),
+	MUX(none, "mout_mspll_cpu", mspll_cpu_p, SRC_TOP7, 12, 2),
+	MUX(none, "mout_apll", apll_p, SRC_CPU, 0, 1),
+	MUX(none, "mout_cpu", cpu_p, SRC_CPU, 16, 1),
+	MUX(none, "mout_kpll", kpll_p, SRC_KFC, 0, 1),
+	MUX(none, "mout_cpu_kfc", kfc_p, SRC_KFC, 16, 1),
+
+	MUX(none, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1),
+
+	MUX_A(none, "mout_aclk400_mscl", group1_p,
+			SRC_TOP0, 4, 2, "aclk400_mscl"),
+	MUX(none, "mout_aclk200", group1_p, SRC_TOP0, 8, 2),
+	MUX(none, "mout_aclk200_fsys2", group1_p, SRC_TOP0, 12, 2),
+	MUX(none, "mout_aclk200_fsys", group1_p, SRC_TOP0, 28, 2),
+
+	MUX(none, "mout_aclk333_432_gscl", group4_p, SRC_TOP1, 0, 2),
+	MUX(none, "mout_aclk66", group1_p, SRC_TOP1, 8, 2),
+	MUX(none, "mout_aclk266", group1_p, SRC_TOP1, 20, 2),
+	MUX(none, "mout_aclk166", group1_p, SRC_TOP1, 24, 2),
+	MUX(none, "mout_aclk333", group1_p, SRC_TOP1, 28, 2),
+
+	MUX(none, "mout_aclk333_g2d", group1_p, SRC_TOP2, 8, 2),
+	MUX(none, "mout_aclk266_g2d", group1_p, SRC_TOP2, 12, 2),
+	MUX(none, "mout_aclk_g3d", group5_p, SRC_TOP2, 16, 1),
+	MUX(none, "mout_aclk300_jpeg", group1_p, SRC_TOP2, 20, 2),
+	MUX(none, "mout_aclk300_disp1", group1_p, SRC_TOP2, 24, 2),
+	MUX(none, "mout_aclk300_gscl", group1_p, SRC_TOP2, 28, 2),
+
+	MUX(none, "mout_user_aclk400_mscl", user_aclk400_mscl_p,
+			SRC_TOP3, 4, 1),
+	MUX_A(none, "mout_aclk200_disp1", aclk200_disp1_p,
+			SRC_TOP3, 8, 1, "aclk200_disp1"),
+	MUX(none, "mout_user_aclk200_fsys2", user_aclk200_fsys2_p,
+			SRC_TOP3, 12, 1),
+	MUX(none, "mout_user_aclk200_fsys", user_aclk200_fsys_p,
+			SRC_TOP3, 28, 1),
+
+	MUX(none, "mout_user_aclk333_432_gscl", user_aclk333_432_gscl_p,
+			SRC_TOP4, 0, 1),
+	MUX(none, "mout_aclk66_peric", aclk66_peric_p, SRC_TOP4, 8, 1),
+	MUX(none, "mout_user_aclk266", user_aclk266_p, SRC_TOP4, 20, 1),
+	MUX(none, "mout_user_aclk166", user_aclk166_p, SRC_TOP4, 24, 1),
+	MUX(none, "mout_user_aclk333", user_aclk333_p, SRC_TOP4, 28, 1),
+
+	MUX(none, "mout_aclk66_psgen", aclk66_peric_p, SRC_TOP5, 4, 1),
+	MUX(none, "mout_user_aclk333_g2d", user_aclk333_g2d_p, SRC_TOP5, 8, 1),
+	MUX(none, "mout_user_aclk266_g2d", user_aclk266_g2d_p, SRC_TOP5, 12, 1),
+	MUX_A(none, "mout_user_aclk_g3d", user_aclk_g3d_p,
+			SRC_TOP5, 16, 1, "aclkg3d"),
+	MUX(none, "mout_user_aclk300_jpeg", user_aclk300_jpeg_p,
+			SRC_TOP5, 20, 1),
+	MUX(none, "mout_user_aclk300_disp1", user_aclk300_disp1_p,
+			SRC_TOP5, 24, 1),
+	MUX(none, "mout_user_aclk300_gscl", user_aclk300_gscl_p,
+			SRC_TOP5, 28, 1),
+
+	MUX(none, "sclk_mpll", mpll_p, SRC_TOP6, 0, 1),
+	MUX(none, "sclk_vpll", vpll_p, SRC_TOP6, 4, 1),
+	MUX(none, "sclk_spll", spll_p, SRC_TOP6, 8, 1),
+	MUX(none, "sclk_ipll", ipll_p, SRC_TOP6, 12, 1),
+	MUX(none, "sclk_rpll", rpll_p, SRC_TOP6, 16, 1),
+	MUX(none, "sclk_epll", epll_p, SRC_TOP6, 20, 1),
+	MUX(none, "sclk_dpll", dpll_p, SRC_TOP6, 24, 1),
+	MUX(none, "sclk_cpll", cpll_p, SRC_TOP6, 28, 1),
+
+	MUX(none, "mout_sw_aclk400_mscl", sw_aclk400_mscl_p, SRC_TOP10, 4, 1),
+	MUX(none, "mout_sw_aclk200", sw_aclk200_p, SRC_TOP10, 8, 1),
+	MUX(none, "mout_sw_aclk200_fsys2", sw_aclk200_fsys2_p,
+			SRC_TOP10, 12, 1),
+	MUX(none, "mout_sw_aclk200_fsys", sw_aclk200_fsys_p, SRC_TOP10, 28, 1),
+
+	MUX(none, "mout_sw_aclk333_432_gscl", sw_aclk333_432_gscl_p,
+			SRC_TOP11, 0, 1),
+	MUX(none, "mout_sw_aclk66", sw_aclk66_p, SRC_TOP11, 8, 1),
+	MUX(none, "mout_sw_aclk266", sw_aclk266_p, SRC_TOP11, 20, 1),
+	MUX(none, "mout_sw_aclk166", sw_aclk166_p, SRC_TOP11, 24, 1),
+	MUX(none, "mout_sw_aclk333", sw_aclk333_p, SRC_TOP11, 28, 1),
+
+	MUX(none, "mout_sw_aclk333_g2d", sw_aclk333_g2d_p, SRC_TOP12, 8, 1),
+	MUX(none, "mout_sw_aclk266_g2d", sw_aclk266_g2d_p, SRC_TOP12, 12, 1),
+	MUX(none, "mout_sw_aclk_g3d", sw_aclk_g3d_p, SRC_TOP12, 16, 1),
+	MUX(none, "mout_sw_aclk300_jpeg", sw_aclk300_jpeg_p, SRC_TOP12, 20, 1),
+	MUX(none, "mout_sw_aclk300_disp1", sw_aclk300_disp1_p,
+			SRC_TOP12, 24, 1),
+	MUX(none, "mout_sw_aclk300_gscl", sw_aclk300_gscl_p, SRC_TOP12, 28, 1),
+
+	/* DISP1 Block */
+	MUX(none, "mout_fimd1", group3_p, SRC_DISP10, 4, 1),
+	MUX(none, "mout_mipi1", group2_p, SRC_DISP10, 16, 3),
+	MUX(none, "mout_dp1", group2_p, SRC_DISP10, 20, 3),
+	MUX(none, "mout_pixel", group2_p, SRC_DISP10, 24, 3),
+	MUX(none, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1),
+
+	/* MAU Block */
+	MUX(none, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3),
+
+	/* FSYS Block */
+	MUX(none, "mout_usbd301", group2_p, SRC_FSYS, 4, 3),
+	MUX(none, "mout_mmc0", group2_p, SRC_FSYS, 8, 3),
+	MUX(none, "mout_mmc1", group2_p, SRC_FSYS, 12, 3),
+	MUX(none, "mout_mmc2", group2_p, SRC_FSYS, 16, 3),
+	MUX(none, "mout_usbd300", group2_p, SRC_FSYS, 20, 3),
+	MUX(none, "mout_unipro", group2_p, SRC_FSYS, 24, 3),
+
+	/* PERIC Block */
+	MUX(none, "mout_uart0", group2_p, SRC_PERIC0, 4, 3),
+	MUX(none, "mout_uart1", group2_p, SRC_PERIC0, 8, 3),
+	MUX(none, "mout_uart2", group2_p, SRC_PERIC0, 12, 3),
+	MUX(none, "mout_uart3", group2_p, SRC_PERIC0, 16, 3),
+	MUX(none, "mout_pwm", group2_p, SRC_PERIC0, 24, 3),
+	MUX(none, "mout_spdif", spdif_p, SRC_PERIC0, 28, 3),
+	MUX(none, "mout_audio0", audio0_p, SRC_PERIC1, 8, 3),
+	MUX(none, "mout_audio1", audio1_p, SRC_PERIC1, 12, 3),
+	MUX(none, "mout_audio2", audio2_p, SRC_PERIC1, 16, 3),
+	MUX(none, "mout_spi0", group2_p, SRC_PERIC1, 20, 3),
+	MUX(none, "mout_spi1", group2_p, SRC_PERIC1, 24, 3),
+	MUX(none, "mout_spi2", group2_p, SRC_PERIC1, 28, 3),
+};
+
+struct samsung_div_clock exynos5420_div_clks[] __initdata = {
+	DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
+	DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
+	DIV(none, "armclk2", "div_arm", DIV_CPU0, 28, 3),
+	DIV(none, "div_kfc", "mout_cpu_kfc", DIV_KFC0, 0, 3),
+	DIV(none, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3),
+
+	DIV(none, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3),
+	DIV(none, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3),
+	DIV(none, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3),
+	DIV(none, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3),
+	DIV(none, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3),
+
+	DIV(none, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl",
+			DIV_TOP1, 0, 3),
+	DIV(none, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6),
+	DIV(none, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3),
+	DIV(none, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3),
+	DIV(none, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3),
+
+	DIV(none, "dout_aclk333_g2d", "mout_aclk333_g2d", DIV_TOP2, 8, 3),
+	DIV(none, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3),
+	DIV(none, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3),
+	DIV(none, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3),
+	DIV_A(none, "dout_aclk300_disp1", "mout_aclk300_disp1",
+			DIV_TOP2, 24, 3, "aclk300_disp1"),
+	DIV(none, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3),
+
+	/* DISP1 Block */
+	DIV(none, "dout_fimd1", "mout_fimd1", DIV_DISP10, 0, 4),
+	DIV(none, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8),
+	DIV(none, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4),
+	DIV(none, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
+
+	/* Audio Block */
+	DIV(none, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4),
+	DIV(none, "dout_maupcm0", "dout_maudio0", DIV_MAU, 24, 8),
+
+	/* USB3.0 */
+	DIV(none, "dout_usbphy301", "mout_usbd301", DIV_FSYS0, 12, 4),
+	DIV(none, "dout_usbphy300", "mout_usbd300", DIV_FSYS0, 16, 4),
+	DIV(none, "dout_usbd301", "mout_usbd301", DIV_FSYS0, 20, 4),
+	DIV(none, "dout_usbd300", "mout_usbd300", DIV_FSYS0, 24, 4),
+
+	/* MMC */
+	DIV(none, "dout_mmc0", "mout_mmc0", DIV_FSYS1, 0, 10),
+	DIV(none, "dout_mmc1", "mout_mmc1", DIV_FSYS1, 10, 10),
+	DIV(none, "dout_mmc2", "mout_mmc2", DIV_FSYS1, 20, 10),
+
+	DIV(none, "dout_unipro", "mout_unipro", DIV_FSYS2, 24, 8),
+
+	/* UART and PWM */
+	DIV(none, "dout_uart0", "mout_uart0", DIV_PERIC0, 8, 4),
+	DIV(none, "dout_uart1", "mout_uart1", DIV_PERIC0, 12, 4),
+	DIV(none, "dout_uart2", "mout_uart2", DIV_PERIC0, 16, 4),
+	DIV(none, "dout_uart3", "mout_uart3", DIV_PERIC0, 20, 4),
+	DIV(none, "dout_pwm", "mout_pwm", DIV_PERIC0, 28, 4),
+
+	/* SPI */
+	DIV(none, "dout_spi0", "mout_spi0", DIV_PERIC1, 20, 4),
+	DIV(none, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4),
+	DIV(none, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4),
+
+	/* PCM */
+	DIV(none, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8),
+	DIV(none, "dout_pcm2", "dout_audio2", DIV_PERIC2, 24, 8),
+
+	/* Audio - I2S */
+	DIV(none, "dout_i2s1", "dout_audio1", DIV_PERIC3, 6, 6),
+	DIV(none, "dout_i2s2", "dout_audio2", DIV_PERIC3, 12, 6),
+	DIV(none, "dout_audio0", "mout_audio0", DIV_PERIC3, 20, 4),
+	DIV(none, "dout_audio1", "mout_audio1", DIV_PERIC3, 24, 4),
+	DIV(none, "dout_audio2", "mout_audio2", DIV_PERIC3, 28, 4),
+
+	/* SPI Pre-Ratio */
+	DIV(none, "dout_pre_spi0", "dout_spi0", DIV_PERIC4, 8, 8),
+	DIV(none, "dout_pre_spi1", "dout_spi1", DIV_PERIC4, 16, 8),
+	DIV(none, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8),
+};
+
+struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
+	/* TODO: Re-verify the CG bits for all the gate clocks */
+	GATE_A(mct, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0, "mct"),
+
+	GATE(0, "aclk200_fsys", "mout_user_aclk200_fsys",
+			GATE_BUS_FSYS0, 9, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "aclk200_fsys2", "mout_user_aclk200_fsys2",
+			GATE_BUS_FSYS0, 10, CLK_IGNORE_UNUSED, 0),
+
+	GATE(0, "aclk333_g2d", "mout_user_aclk333_g2d",
+			GATE_BUS_TOP, 0, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "aclk266_g2d", "mout_user_aclk266_g2d",
+			GATE_BUS_TOP, 1, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "aclk300_jpeg", "mout_user_aclk300_jpeg",
+			GATE_BUS_TOP, 4, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "aclk300_gscl", "mout_user_aclk300_gscl",
+			GATE_BUS_TOP, 6, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "aclk333_432_gscl", "mout_user_aclk333_432_gscl",
+			GATE_BUS_TOP, 7, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "pclk66_gpio", "mout_sw_aclk66",
+			GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "aclk66_psgen", "mout_aclk66_psgen",
+			GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "aclk66_peric", "mout_aclk66_peric",
+			GATE_BUS_TOP, 11, 0, 0),
+	GATE(0, "aclk166", "mout_user_aclk166",
+			GATE_BUS_TOP, 14, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "aclk333", "mout_aclk333",
+			GATE_BUS_TOP, 15, CLK_IGNORE_UNUSED, 0),
+
+	/* sclk */
+	GATE(sclk_uart0, "sclk_uart0", "dout_uart0",
+		GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_uart1, "sclk_uart1", "dout_uart1",
+		GATE_TOP_SCLK_PERIC, 1, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_uart2, "sclk_uart2", "dout_uart2",
+		GATE_TOP_SCLK_PERIC, 2, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_uart3, "sclk_uart3", "dout_uart3",
+		GATE_TOP_SCLK_PERIC, 3, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_spi0, "sclk_spi0", "dout_pre_spi0",
+		GATE_TOP_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_spi1, "sclk_spi1", "dout_pre_spi1",
+		GATE_TOP_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_spi2, "sclk_spi2", "dout_pre_spi2",
+		GATE_TOP_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_spdif, "sclk_spdif", "mout_spdif",
+		GATE_TOP_SCLK_PERIC, 9, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_pwm, "sclk_pwm", "dout_pwm",
+		GATE_TOP_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_pcm1, "sclk_pcm1", "dout_pcm1",
+		GATE_TOP_SCLK_PERIC, 15, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_pcm2, "sclk_pcm2", "dout_pcm2",
+		GATE_TOP_SCLK_PERIC, 16, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_i2s1, "sclk_i2s1", "dout_i2s1",
+		GATE_TOP_SCLK_PERIC, 17, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_i2s2, "sclk_i2s2", "dout_i2s2",
+		GATE_TOP_SCLK_PERIC, 18, CLK_SET_RATE_PARENT, 0),
+
+	GATE(sclk_mmc0, "sclk_mmc0", "dout_mmc0",
+		GATE_TOP_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_mmc1, "sclk_mmc1", "dout_mmc1",
+		GATE_TOP_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_mmc2, "sclk_mmc2", "dout_mmc2",
+		GATE_TOP_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_usbphy301, "sclk_usbphy301", "dout_usbphy301",
+		GATE_TOP_SCLK_FSYS, 7, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_usbphy300, "sclk_usbphy300", "dout_usbphy300",
+		GATE_TOP_SCLK_FSYS, 8, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_usbd300, "sclk_usbd300", "dout_usbd300",
+		GATE_TOP_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_usbd301, "sclk_usbd301", "dout_usbd301",
+		GATE_TOP_SCLK_FSYS, 10, CLK_SET_RATE_PARENT, 0),
+
+	GATE(sclk_usbd301, "sclk_unipro", "dout_unipro",
+		SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
+
+	GATE(sclk_gscl_wa, "sclk_gscl_wa", "aclK333_432_gscl",
+		GATE_TOP_SCLK_GSCL, 6, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_gscl_wb, "sclk_gscl_wb", "aclk333_432_gscl",
+		GATE_TOP_SCLK_GSCL, 7, CLK_SET_RATE_PARENT, 0),
+
+	/* Display */
+	GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1",
+		GATE_TOP_SCLK_DISP1, 0, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_mipi1, "sclk_mipi1", "dout_mipi1",
+		GATE_TOP_SCLK_DISP1, 3, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi",
+		GATE_TOP_SCLK_DISP1, 9, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_pixel, "sclk_pixel", "dout_hdmi_pixel",
+		GATE_TOP_SCLK_DISP1, 10, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_dp1, "sclk_dp1", "dout_dp1",
+		GATE_TOP_SCLK_DISP1, 20, CLK_SET_RATE_PARENT, 0),
+
+	/* Maudio Block */
+	GATE(sclk_maudio0, "sclk_maudio0", "dout_maudio0",
+		GATE_TOP_SCLK_MAU, 0, CLK_SET_RATE_PARENT, 0),
+	GATE(sclk_maupcm0, "sclk_maupcm0", "dout_maupcm0",
+		GATE_TOP_SCLK_MAU, 1, CLK_SET_RATE_PARENT, 0),
+	/* FSYS */
+	GATE(tsi, "tsi", "aclk200_fsys", GATE_BUS_FSYS0, 0, 0, 0),
+	GATE(pdma0, "pdma0", "aclk200_fsys", GATE_BUS_FSYS0, 1, 0, 0),
+	GATE(pdma1, "pdma1", "aclk200_fsys", GATE_BUS_FSYS0, 2, 0, 0),
+	GATE(ufs, "ufs", "aclk200_fsys2", GATE_BUS_FSYS0, 3, 0, 0),
+	GATE(rtic, "rtic", "aclk200_fsys", GATE_BUS_FSYS0, 5, 0, 0),
+	GATE(mmc0, "mmc0", "aclk200_fsys2", GATE_BUS_FSYS0, 12, 0, 0),
+	GATE(mmc1, "mmc1", "aclk200_fsys2", GATE_BUS_FSYS0, 13, 0, 0),
+	GATE(mmc2, "mmc2", "aclk200_fsys2", GATE_BUS_FSYS0, 14, 0, 0),
+	GATE(sromc, "sromc", "aclk200_fsys2",
+			GATE_BUS_FSYS0, 19, CLK_IGNORE_UNUSED, 0),
+	GATE(usbh20, "usbh20", "aclk200_fsys", GATE_BUS_FSYS0, 20, 0, 0),
+	GATE(usbd300, "usbd300", "aclk200_fsys", GATE_BUS_FSYS0, 21, 0, 0),
+	GATE(usbd301, "usbd301", "aclk200_fsys", GATE_BUS_FSYS0, 28, 0, 0),
+
+	/* UART */
+	GATE(uart0, "uart0", "aclk66_peric", GATE_BUS_PERIC, 4, 0, 0),
+	GATE(uart1, "uart1", "aclk66_peric", GATE_BUS_PERIC, 5, 0, 0),
+	GATE_A(uart2, "uart2", "aclk66_peric",
+		GATE_BUS_PERIC, 6, CLK_IGNORE_UNUSED, 0, "uart2"),
+	GATE(uart3, "uart3", "aclk66_peric", GATE_BUS_PERIC, 7, 0, 0),
+	/* I2C */
+	GATE(i2c0, "i2c0", "aclk66_peric", GATE_BUS_PERIC, 9, 0, 0),
+	GATE(i2c1, "i2c1", "aclk66_peric", GATE_BUS_PERIC, 10, 0, 0),
+	GATE(i2c2, "i2c2", "aclk66_peric", GATE_BUS_PERIC, 11, 0, 0),
+	GATE(i2c3, "i2c3", "aclk66_peric", GATE_BUS_PERIC, 12, 0, 0),
+	GATE(i2c4, "i2c4", "aclk66_peric", GATE_BUS_PERIC, 13, 0, 0),
+	GATE(i2c5, "i2c5", "aclk66_peric", GATE_BUS_PERIC, 14, 0, 0),
+	GATE(i2c6, "i2c6", "aclk66_peric", GATE_BUS_PERIC, 15, 0, 0),
+	GATE(i2c7, "i2c7", "aclk66_peric", GATE_BUS_PERIC, 16, 0, 0),
+	GATE(i2c_hdmi, "i2c_hdmi", "aclk66_peric", GATE_BUS_PERIC, 17, 0, 0),
+	GATE(tsadc, "tsadc", "aclk66_peric", GATE_BUS_PERIC, 18, 0, 0),
+	/* SPI */
+	GATE(spi0, "spi0", "aclk66_peric", GATE_BUS_PERIC, 19, 0, 0),
+	GATE(spi1, "spi1", "aclk66_peric", GATE_BUS_PERIC, 20, 0, 0),
+	GATE(spi2, "spi2", "aclk66_peric", GATE_BUS_PERIC, 21, 0, 0),
+	GATE(keyif, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0),
+	/* I2S */
+	GATE(i2s1, "i2s1", "aclk66_peric", GATE_BUS_PERIC, 23, 0, 0),
+	GATE(i2s2, "i2s2", "aclk66_peric", GATE_BUS_PERIC, 24, 0, 0),
+	/* PCM */
+	GATE(pcm1, "pcm1", "aclk66_peric", GATE_BUS_PERIC, 25, 0, 0),
+	GATE(pcm2, "pcm2", "aclk66_peric", GATE_BUS_PERIC, 26, 0, 0),
+	/* PWM */
+	GATE(pwm, "pwm", "aclk66_peric", GATE_BUS_PERIC, 27, 0, 0),
+	/* SPDIF */
+	GATE(spdif, "spdif", "aclk66_peric", GATE_BUS_PERIC, 29, 0, 0),
+
+	GATE(i2c8, "i2c8", "aclk66_peric", GATE_BUS_PERIC1, 0, 0, 0),
+	GATE(i2c9, "i2c9", "aclk66_peric", GATE_BUS_PERIC1, 1, 0, 0),
+	GATE(i2c10, "i2c10", "aclk66_peric", GATE_BUS_PERIC1, 2, 0, 0),
+
+	GATE(chipid, "chipid", "aclk66_psgen",
+			GATE_BUS_PERIS0, 12, CLK_IGNORE_UNUSED, 0),
+	GATE(sysreg, "sysreg", "aclk66_psgen",
+			GATE_BUS_PERIS0, 13, CLK_IGNORE_UNUSED, 0),
+	GATE(tzpc0, "tzpc0", "aclk66_psgen", GATE_BUS_PERIS0, 18, 0, 0),
+	GATE(tzpc1, "tzpc1", "aclk66_psgen", GATE_BUS_PERIS0, 19, 0, 0),
+	GATE(tzpc2, "tzpc2", "aclk66_psgen", GATE_BUS_PERIS0, 20, 0, 0),
+	GATE(tzpc3, "tzpc3", "aclk66_psgen", GATE_BUS_PERIS0, 21, 0, 0),
+	GATE(tzpc4, "tzpc4", "aclk66_psgen", GATE_BUS_PERIS0, 22, 0, 0),
+	GATE(tzpc5, "tzpc5", "aclk66_psgen", GATE_BUS_PERIS0, 23, 0, 0),
+	GATE(tzpc6, "tzpc6", "aclk66_psgen", GATE_BUS_PERIS0, 24, 0, 0),
+	GATE(tzpc7, "tzpc7", "aclk66_psgen", GATE_BUS_PERIS0, 25, 0, 0),
+	GATE(tzpc8, "tzpc8", "aclk66_psgen", GATE_BUS_PERIS0, 26, 0, 0),
+	GATE(tzpc9, "tzpc9", "aclk66_psgen", GATE_BUS_PERIS0, 27, 0, 0),
+
+	GATE(hdmi_cec, "hdmi_cec", "aclk66_psgen", GATE_BUS_PERIS1, 0, 0, 0),
+	GATE(seckey, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0),
+	GATE(wdt, "wdt", "aclk66_psgen", GATE_BUS_PERIS1, 3, 0, 0),
+	GATE(rtc, "rtc", "aclk66_psgen", GATE_BUS_PERIS1, 4, 0, 0),
+	GATE(tmu, "tmu", "aclk66_psgen", GATE_BUS_PERIS1, 5, 0, 0),
+	GATE(tmu_gpu, "tmu_gpu", "aclk66_psgen", GATE_BUS_PERIS1, 6, 0, 0),
+
+	GATE(gscl0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0),
+	GATE(gscl1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0),
+	GATE(clk_3aa, "clk_3aa", "aclk300_gscl", GATE_IP_GSCL0, 4, 0, 0),
+
+	GATE(smmu_3aa, "smmu_3aa", "aclk333_432_gscl", GATE_IP_GSCL1, 2, 0, 0),
+	GATE(smmu_fimcl0, "smmu_fimcl0", "aclk333_432_gscl",
+			GATE_IP_GSCL1, 3, 0, 0),
+	GATE(smmu_fimcl1, "smmu_fimcl1", "aclk333_432_gscl",
+			GATE_IP_GSCL1, 4, 0, 0),
+	GATE(smmu_gscl0, "smmu_gscl0", "aclk300_gscl", GATE_IP_GSCL1, 6, 0, 0),
+	GATE(smmu_gscl1, "smmu_gscl1", "aclk300_gscl", GATE_IP_GSCL1, 7, 0, 0),
+	GATE(gscl_wa, "gscl_wa", "aclk300_gscl", GATE_IP_GSCL1, 12, 0, 0),
+	GATE(gscl_wb, "gscl_wb", "aclk300_gscl", GATE_IP_GSCL1, 13, 0, 0),
+	GATE(smmu_fimcl3, "smmu_fimcl3,", "aclk333_432_gscl",
+			GATE_IP_GSCL1, 16, 0, 0),
+	GATE(fimc_lite3, "fimc_lite3", "aclk333_432_gscl",
+			GATE_IP_GSCL1, 17, 0, 0),
+
+	GATE(fimd1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0),
+	GATE(dsim1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0),
+	GATE(dp1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0),
+	GATE(mixer, "mixer", "aclk166", GATE_IP_DISP1, 5, 0, 0),
+	GATE(hdmi, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0),
+	GATE(smmu_fimd1, "smmu_fimd1", "aclk300_disp1", GATE_IP_DISP1, 8, 0, 0),
+
+	GATE(mfc, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0),
+	GATE(smmu_mfcl, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0),
+	GATE(smmu_mfcr, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0),
+
+	GATE(g3d, "g3d", "aclkg3d", GATE_IP_G3D, 9, 0, 0),
+
+	GATE(rotator, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0),
+	GATE(jpeg, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0),
+	GATE(jpeg2, "jpeg2", "aclk300_jpeg", GATE_IP_GEN, 3, 0, 0),
+	GATE(mdma1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0),
+	GATE(smmu_rotator, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0),
+	GATE(smmu_jpeg, "smmu_jpeg", "aclk300_jpeg", GATE_IP_GEN, 7, 0, 0),
+	GATE(smmu_mdma1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0),
+
+	GATE(mscl0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0),
+	GATE(mscl1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0),
+	GATE(mscl2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0),
+	GATE(smmu_mscl0, "smmu_mscl0", "aclk400_mscl", GATE_IP_MSCL, 8, 0, 0),
+	GATE(smmu_mscl1, "smmu_mscl1", "aclk400_mscl", GATE_IP_MSCL, 9, 0, 0),
+	GATE(smmu_mscl2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0, 0),
+};
+
+static __initdata struct of_device_id ext_clk_match[] = {
+	{ .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
+	{ },
+};
+
+/* register exynos5420 clocks */
+void __init exynos5420_clk_init(struct device_node *np)
+{
+	void __iomem *reg_base;
+	struct clk *apll, *bpll, *cpll, *dpll, *epll, *ipll, *kpll, *mpll;
+	struct clk *rpll, *spll, *vpll;
+
+	if (np) {
+		reg_base = of_iomap(np, 0);
+		if (!reg_base)
+			panic("%s: failed to map registers\n", __func__);
+	} else {
+		panic("%s: unable to determine soc\n", __func__);
+	}
+
+	samsung_clk_init(np, reg_base, nr_clks,
+			exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
+			NULL, 0);
+	samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
+			ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
+			ext_clk_match);
+
+	apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
+			reg_base + 0x100);
+	bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
+			reg_base + 0x20110);
+	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
+			reg_base + 0x10120);
+	dpll = samsung_clk_register_pll35xx("fout_dpll", "fin_pll",
+			reg_base + 0x10128);
+	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
+			reg_base + 0x10130);
+	ipll = samsung_clk_register_pll35xx("fout_ipll", "fin_pll",
+			reg_base + 0x10150);
+	kpll = samsung_clk_register_pll35xx("fout_kpll", "fin_pll",
+			reg_base + 0x28100);
+	mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
+			reg_base + 0x10180);
+	rpll = samsung_clk_register_pll36xx("fout_rpll", "fin_pll",
+			reg_base + 0x10140);
+	spll = samsung_clk_register_pll35xx("fout_spll", "fin_pll",
+			reg_base + 0x10160);
+	vpll = samsung_clk_register_pll35xx("fout_vpll", "fin_pll",
+			reg_base + 0x10170);
+
+	samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
+			ARRAY_SIZE(exynos5420_fixed_rate_clks));
+	samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
+			ARRAY_SIZE(exynos5420_fixed_factor_clks));
+	samsung_clk_register_mux(exynos5420_mux_clks,
+			ARRAY_SIZE(exynos5420_mux_clks));
+	samsung_clk_register_div(exynos5420_div_clks,
+			ARRAY_SIZE(exynos5420_div_clks));
+	samsung_clk_register_gate(exynos5420_gate_clks,
+			ARRAY_SIZE(exynos5420_gate_clks));
+}
+CLK_OF_DECLARE(exynos5420_clk, "samsung,exynos5420-clock", exynos5420_clk_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/samsung/clk-exynos-audss.c linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk-exynos-audss.c
--- linux-libre-3.10-gnu/drivers/clk/samsung/clk-exynos-audss.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk-exynos-audss.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Author: Padmavathi Venna <padma.v@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for Audio Subsystem Clock Controller.
+*/
+
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+
+#include <dt-bindings/clk/exynos-audss-clk.h>
+
+static DEFINE_SPINLOCK(lock);
+static struct clk **clk_table;
+static void __iomem *reg_base;
+static struct clk_onecell_data clk_data;
+
+#define ASS_CLK_SRC 0x0
+#define ASS_CLK_DIV 0x4
+#define ASS_CLK_GATE 0x8
+
+static unsigned long reg_save[][2] = {
+	{ASS_CLK_SRC,  0},
+	{ASS_CLK_DIV,  0},
+	{ASS_CLK_GATE, 0},
+};
+
+/* list of all parent clock list */
+static const char *mout_audss_p[] = { "fin_pll", "fout_epll" };
+static const char *mout_i2s_p[] = { "mout_audss", "cdclk0", "sclk_audio0" };
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos_audss_clk_suspend(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(reg_save); i++)
+		reg_save[i][1] = readl(reg_base + reg_save[i][0]);
+
+	return 0;
+}
+
+static void exynos_audss_clk_resume(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(reg_save); i++)
+		writel(reg_save[i][1], reg_base + reg_save[i][0]);
+}
+
+static struct syscore_ops exynos_audss_clk_syscore_ops = {
+	.suspend	= exynos_audss_clk_suspend,
+	.resume		= exynos_audss_clk_resume,
+};
+#endif /* CONFIG_PM_SLEEP */
+
+/* register exynos_audss clocks */
+void __init exynos_audss_clk_init(struct device_node *np)
+{
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: failed to map audss registers\n", __func__);
+		return;
+	}
+
+	clk_table = kzalloc(sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS,
+				GFP_KERNEL);
+	if (!clk_table) {
+		pr_err("%s: could not allocate clk lookup table\n", __func__);
+		return;
+	}
+
+	clk_data.clks = clk_table;
+	clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS;
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+	clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
+				mout_audss_p, ARRAY_SIZE(mout_audss_p), 0,
+				reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
+
+	clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s",
+				mout_i2s_p, ARRAY_SIZE(mout_i2s_p), 0,
+				reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
+
+	clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(NULL, "dout_srp",
+				"mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4,
+				0, &lock);
+
+	clk_table[EXYNOS_DOUT_AUD_BUS] = clk_register_divider(NULL,
+				"dout_aud_bus", "dout_srp", 0,
+				reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);
+
+	clk_table[EXYNOS_DOUT_I2S] = clk_register_divider(NULL, "dout_i2s",
+				"mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0,
+				&lock);
+
+	clk_table[EXYNOS_SRP_CLK] = clk_register_gate(NULL, "srp_clk",
+				"dout_srp", CLK_SET_RATE_PARENT,
+				reg_base + ASS_CLK_GATE, 0, 0, &lock);
+
+	clk_table[EXYNOS_I2S_BUS] = clk_register_gate(NULL, "i2s_bus",
+				"dout_aud_bus", CLK_SET_RATE_PARENT,
+				reg_base + ASS_CLK_GATE, 2, 0, &lock);
+
+	clk_table[EXYNOS_SCLK_I2S] = clk_register_gate(NULL, "sclk_i2s",
+				"dout_i2s", CLK_SET_RATE_PARENT,
+				reg_base + ASS_CLK_GATE, 3, 0, &lock);
+
+	clk_table[EXYNOS_PCM_BUS] = clk_register_gate(NULL, "pcm_bus",
+				 "sclk_pcm", CLK_SET_RATE_PARENT,
+				reg_base + ASS_CLK_GATE, 4, 0, &lock);
+
+	clk_table[EXYNOS_SCLK_PCM] = clk_register_gate(NULL, "sclk_pcm",
+				"div_pcm0", CLK_SET_RATE_PARENT,
+				reg_base + ASS_CLK_GATE, 5, 0, &lock);
+
+#ifdef CONFIG_PM_SLEEP
+	register_syscore_ops(&exynos_audss_clk_syscore_ops);
+#endif
+
+	pr_info("Exynos: Audss: clock setup completed\n");
+}
+CLK_OF_DECLARE(exynos4210_audss_clk, "samsung,exynos4210-audss-clock",
+		exynos_audss_clk_init);
+CLK_OF_DECLARE(exynos5250_audss_clk, "samsung,exynos5250-audss-clock",
+		exynos_audss_clk_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/samsung/clk.h linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk.h
--- linux-libre-3.10-gnu/drivers/clk/samsung/clk.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/samsung/clk.h	2013-08-25 20:43:22.000000000 -0400
@@ -144,6 +144,9 @@ struct samsung_mux_clock {
 #define MUX_F(_id, cname, pnames, o, s, w, f, mf)		\
 	__MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
 
+#define MUX_FA(_id, cname, pnames, o, s, w, f, mf, a)		\
+	__MUX(_id, NULL, cname, pnames, o, s, w, f, mf, a)
+
 /**
  * @id: platform specific id of the clock.
  * struct samsung_div_clock: information about div clock
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/samsung/Makefile linux-libre-3.11-rc7-gnu/drivers/clk/samsung/Makefile
--- linux-libre-3.10-gnu/drivers/clk/samsung/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/samsung/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,4 +5,6 @@
 obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-pll.o
 obj-$(CONFIG_ARCH_EXYNOS4)	+= clk-exynos4.o
 obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
+obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
+obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/socfpga/clk.c linux-libre-3.11-rc7-gnu/drivers/clk/socfpga/clk.c
--- linux-libre-3.10-gnu/drivers/clk/socfpga/clk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/socfpga/clk.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,15 +24,17 @@
 #include <linux/of.h>
 
 /* Clock Manager offsets */
-#define CLKMGR_CTRL    0x0
-#define CLKMGR_BYPASS 0x4
+#define CLKMGR_CTRL	0x0
+#define CLKMGR_BYPASS	0x4
+#define CLKMGR_L4SRC	0x70
+#define CLKMGR_PERPLL_SRC	0xAC
 
 /* Clock bypass bits */
-#define MAINPLL_BYPASS (1<<0)
-#define SDRAMPLL_BYPASS (1<<1)
-#define SDRAMPLL_SRC_BYPASS (1<<2)
-#define PERPLL_BYPASS (1<<3)
-#define PERPLL_SRC_BYPASS (1<<4)
+#define MAINPLL_BYPASS		(1<<0)
+#define SDRAMPLL_BYPASS		(1<<1)
+#define SDRAMPLL_SRC_BYPASS	(1<<2)
+#define PERPLL_BYPASS		(1<<3)
+#define PERPLL_SRC_BYPASS	(1<<4)
 
 #define SOCFPGA_PLL_BG_PWRDWN		0
 #define SOCFPGA_PLL_EXT_ENA		1
@@ -41,6 +43,17 @@
 #define SOCFPGA_PLL_DIVF_SHIFT	3
 #define SOCFPGA_PLL_DIVQ_MASK		0x003F0000
 #define SOCFPGA_PLL_DIVQ_SHIFT	16
+#define SOCFGPA_MAX_PARENTS	3
+
+#define SOCFPGA_L4_MP_CLK		"l4_mp_clk"
+#define SOCFPGA_L4_SP_CLK		"l4_sp_clk"
+#define SOCFPGA_NAND_CLK		"nand_clk"
+#define SOCFPGA_NAND_X_CLK		"nand_x_clk"
+#define SOCFPGA_MMC_CLK			"mmc_clk"
+#define SOCFPGA_DB_CLK			"gpio_db_clk"
+
+#define div_mask(width)	((1 << (width)) - 1)
+#define streq(a, b) (strcmp((a), (b)) == 0)
 
 extern void __iomem *clk_mgr_base_addr;
 
@@ -49,6 +62,9 @@ struct socfpga_clk {
 	char *parent_name;
 	char *clk_name;
 	u32 fixed_div;
+	void __iomem *div_reg;
+	u32 width;	/* only valid if div_reg != 0 */
+	u32 shift;	/* only valid if div_reg != 0 */
 };
 #define to_socfpga_clk(p) container_of(p, struct socfpga_clk, hw.hw)
 
@@ -132,8 +148,9 @@ static __init struct clk *socfpga_clk_in
 
 	socfpga_clk->hw.hw.init = &init;
 
-	if (strcmp(clk_name, "main_pll") || strcmp(clk_name, "periph_pll") ||
-			strcmp(clk_name, "sdram_pll")) {
+	if (streq(clk_name, "main_pll") ||
+		streq(clk_name, "periph_pll") ||
+		streq(clk_name, "sdram_pll")) {
 		socfpga_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
 		clk_pll_ops.enable = clk_gate_ops.enable;
 		clk_pll_ops.disable = clk_gate_ops.disable;
@@ -148,6 +165,159 @@ static __init struct clk *socfpga_clk_in
 	return clk;
 }
 
+static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
+{
+	u32 l4_src;
+	u32 perpll_src;
+
+	if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
+		l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
+		return l4_src &= 0x1;
+	}
+	if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
+		l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
+		return !!(l4_src & 2);
+	}
+
+	perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
+	if (streq(hwclk->init->name, SOCFPGA_MMC_CLK))
+		return perpll_src &= 0x3;
+	if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
+			streq(hwclk->init->name, SOCFPGA_NAND_X_CLK))
+			return (perpll_src >> 2) & 3;
+
+	/* QSPI clock */
+	return (perpll_src >> 4) & 3;
+
+}
+
+static int socfpga_clk_set_parent(struct clk_hw *hwclk, u8 parent)
+{
+	u32 src_reg;
+
+	if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
+		src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
+		src_reg &= ~0x1;
+		src_reg |= parent;
+		writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
+	} else if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
+		src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
+		src_reg &= ~0x2;
+		src_reg |= (parent << 1);
+		writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
+	} else {
+		src_reg = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
+		if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) {
+			src_reg &= ~0x3;
+			src_reg |= parent;
+		} else if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
+			streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) {
+			src_reg &= ~0xC;
+			src_reg |= (parent << 2);
+		} else {/* QSPI clock */
+			src_reg &= ~0x30;
+			src_reg |= (parent << 4);
+		}
+		writel(src_reg, clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
+	}
+
+	return 0;
+}
+
+static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
+	unsigned long parent_rate)
+{
+	struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
+	u32 div = 1, val;
+
+	if (socfpgaclk->fixed_div)
+		div = socfpgaclk->fixed_div;
+	else if (socfpgaclk->div_reg) {
+		val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
+		val &= div_mask(socfpgaclk->width);
+		if (streq(hwclk->init->name, SOCFPGA_DB_CLK))
+			div = val + 1;
+		else
+			div = (1 << val);
+	}
+
+	return parent_rate / div;
+}
+
+static struct clk_ops gateclk_ops = {
+	.recalc_rate = socfpga_clk_recalc_rate,
+	.get_parent = socfpga_clk_get_parent,
+	.set_parent = socfpga_clk_set_parent,
+};
+
+static void __init socfpga_gate_clk_init(struct device_node *node,
+	const struct clk_ops *ops)
+{
+	u32 clk_gate[2];
+	u32 div_reg[3];
+	u32 fixed_div;
+	struct clk *clk;
+	struct socfpga_clk *socfpga_clk;
+	const char *clk_name = node->name;
+	const char *parent_name[SOCFGPA_MAX_PARENTS];
+	struct clk_init_data init;
+	int rc;
+	int i = 0;
+
+	socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
+	if (WARN_ON(!socfpga_clk))
+		return;
+
+	rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
+	if (rc)
+		clk_gate[0] = 0;
+
+	if (clk_gate[0]) {
+		socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
+		socfpga_clk->hw.bit_idx = clk_gate[1];
+
+		gateclk_ops.enable = clk_gate_ops.enable;
+		gateclk_ops.disable = clk_gate_ops.disable;
+	}
+
+	rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
+	if (rc)
+		socfpga_clk->fixed_div = 0;
+	else
+		socfpga_clk->fixed_div = fixed_div;
+
+	rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
+	if (!rc) {
+		socfpga_clk->div_reg = clk_mgr_base_addr + div_reg[0];
+		socfpga_clk->shift = div_reg[1];
+		socfpga_clk->width = div_reg[2];
+	} else {
+		socfpga_clk->div_reg = 0;
+	}
+
+	of_property_read_string(node, "clock-output-names", &clk_name);
+
+	init.name = clk_name;
+	init.ops = ops;
+	init.flags = 0;
+	while (i < SOCFGPA_MAX_PARENTS && (parent_name[i] =
+			of_clk_get_parent_name(node, i)) != NULL)
+		i++;
+
+	init.parent_names = parent_name;
+	init.num_parents = i;
+	socfpga_clk->hw.hw.init = &init;
+
+	clk = clk_register(NULL, &socfpga_clk->hw.hw);
+	if (WARN_ON(IS_ERR(clk))) {
+		kfree(socfpga_clk);
+		return;
+	}
+	rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	if (WARN_ON(rc))
+		return;
+}
+
 static void __init socfpga_pll_init(struct device_node *node)
 {
 	socfpga_clk_init(node, &clk_pll_ops);
@@ -160,6 +330,12 @@ static void __init socfpga_periph_init(s
 }
 CLK_OF_DECLARE(socfpga_periph, "altr,socfpga-perip-clk", socfpga_periph_init);
 
+static void __init socfpga_gate_init(struct device_node *node)
+{
+	socfpga_gate_clk_init(node, &gateclk_ops);
+}
+CLK_OF_DECLARE(socfpga_gate, "altr,socfpga-gate-clk", socfpga_gate_init);
+
 void __init socfpga_init_clocks(void)
 {
 	struct clk *clk;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/sunxi/clk-sunxi.c linux-libre-3.11-rc7-gnu/drivers/clk/sunxi/clk-sunxi.c
--- linux-libre-3.10-gnu/drivers/clk/sunxi/clk-sunxi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/sunxi/clk-sunxi.c	2013-08-25 20:43:22.000000000 -0400
@@ -239,7 +239,7 @@ struct mux_data {
 	u8 shift;
 };
 
-static const __initconst struct mux_data cpu_data = {
+static const __initconst struct mux_data cpu_mux_data = {
 	.shift = 16,
 };
 
@@ -333,22 +333,34 @@ struct gates_data {
 	DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
 };
 
-static const __initconst struct gates_data axi_gates_data = {
+static const __initconst struct gates_data sun4i_axi_gates_data = {
 	.mask = {1},
 };
 
-static const __initconst struct gates_data ahb_gates_data = {
+static const __initconst struct gates_data sun4i_ahb_gates_data = {
 	.mask = {0x7F77FFF, 0x14FB3F},
 };
 
-static const __initconst struct gates_data apb0_gates_data = {
+static const __initconst struct gates_data sun5i_a13_ahb_gates_data = {
+	.mask = {0x107067e7, 0x185111},
+};
+
+static const __initconst struct gates_data sun4i_apb0_gates_data = {
 	.mask = {0x4EF},
 };
 
-static const __initconst struct gates_data apb1_gates_data = {
+static const __initconst struct gates_data sun5i_a13_apb0_gates_data = {
+	.mask = {0x61},
+};
+
+static const __initconst struct gates_data sun4i_apb1_gates_data = {
 	.mask = {0xFF00F7},
 };
 
+static const __initconst struct gates_data sun5i_a13_apb1_gates_data = {
+	.mask = {0xa0007},
+};
+
 static void __init sunxi_gates_clk_setup(struct device_node *node,
 					 struct gates_data *data)
 {
@@ -421,17 +433,20 @@ static const __initconst struct of_devic
 
 /* Matches for mux clocks */
 static const __initconst struct of_device_id clk_mux_match[] = {
-	{.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_data,},
+	{.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_mux_data,},
 	{.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &apb1_mux_data,},
 	{}
 };
 
 /* Matches for gate clocks */
 static const __initconst struct of_device_id clk_gates_match[] = {
-	{.compatible = "allwinner,sun4i-axi-gates-clk", .data = &axi_gates_data,},
-	{.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &ahb_gates_data,},
-	{.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &apb0_gates_data,},
-	{.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &apb1_gates_data,},
+	{.compatible = "allwinner,sun4i-axi-gates-clk", .data = &sun4i_axi_gates_data,},
+	{.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &sun4i_ahb_gates_data,},
+	{.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
+	{.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
+	{.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,},
+	{.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &sun4i_apb1_gates_data,},
+	{.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,},
 	{}
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/tegra/clk.c linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk.c
--- linux-libre-3.10-gnu/drivers/clk/tegra/clk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,18 +74,6 @@ void __init tegra_init_from_table(struct
 	}
 }
 
-static const struct of_device_id tegra_dt_clk_match[] = {
-	{ .compatible = "nvidia,tegra20-car", .data = tegra20_clock_init },
-	{ .compatible = "nvidia,tegra30-car", .data = tegra30_clock_init },
-	{ .compatible = "nvidia,tegra114-car", .data = tegra114_clock_init },
-	{ }
-};
-
-void __init tegra_clocks_init(void)
-{
-	of_clk_init(tegra_dt_clk_match);
-}
-
 tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
 
 void __init tegra_clocks_apply_init_table(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/tegra/clk.h linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk.h
--- linux-libre-3.10-gnu/drivers/clk/tegra/clk.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk.h	2013-08-25 20:43:22.000000000 -0400
@@ -128,6 +128,31 @@ struct pdiv_map {
 };
 
 /**
+ * struct div_nmp - offset and width of m,n and p fields
+ *
+ * @divn_shift:	shift to the feedback divider bit field
+ * @divn_width:	width of the feedback divider bit field
+ * @divm_shift:	shift to the input divider bit field
+ * @divm_width:	width of the input divider bit field
+ * @divp_shift:	shift to the post divider bit field
+ * @divp_width:	width of the post divider bit field
+ * @override_divn_shift: shift to the feedback divider bitfield in override reg
+ * @override_divm_shift: shift to the input divider bitfield in override reg
+ * @override_divp_shift: shift to the post divider bitfield in override reg
+ */
+struct div_nmp {
+	u8		divn_shift;
+	u8		divn_width;
+	u8		divm_shift;
+	u8		divm_width;
+	u8		divp_shift;
+	u8		divp_width;
+	u8		override_divn_shift;
+	u8		override_divm_shift;
+	u8		override_divp_shift;
+};
+
+/**
  * struct clk_pll_params - PLL parameters
  *
  * @input_min:			Minimum input frequency
@@ -161,11 +186,14 @@ struct tegra_clk_pll_params {
 	u32		aux_reg;
 	u32		dyn_ramp_reg;
 	u32		ext_misc_reg[3];
+	u32		pmc_divnm_reg;
+	u32		pmc_divp_reg;
 	int		stepa_shift;
 	int		stepb_shift;
 	int		lock_delay;
 	int		max_p;
 	struct pdiv_map *pdiv_tohw;
+	struct div_nmp	*div_nmp;
 };
 
 /**
@@ -179,12 +207,6 @@ struct tegra_clk_pll_params {
  * @flags:	PLL flags
  * @fixed_rate:	PLL rate if it is fixed
  * @lock:	register lock
- * @divn_shift:	shift to the feedback divider bit field
- * @divn_width:	width of the feedback divider bit field
- * @divm_shift:	shift to the input divider bit field
- * @divm_width:	width of the input divider bit field
- * @divp_shift:	shift to the post divider bit field
- * @divp_width:	width of the post divider bit field
  *
  * Flags:
  * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
@@ -214,12 +236,6 @@ struct tegra_clk_pll {
 	u32		flags;
 	unsigned long	fixed_rate;
 	spinlock_t	*lock;
-	u8		divn_shift;
-	u8		divn_width;
-	u8		divm_shift;
-	u8		divm_width;
-	u8		divp_shift;
-	u8		divp_width;
 	struct tegra_clk_pll_freq_table	*freq_table;
 	struct tegra_clk_pll_params	*params;
 };
@@ -571,23 +587,11 @@ void tegra_init_from_table(struct tegra_
 void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
 		struct clk *clks[], int clk_max);
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void tegra20_clock_init(struct device_node *np);
-#else
-static inline void tegra20_clock_init(struct device_node *np) {}
-#endif /* CONFIG_ARCH_TEGRA_2x_SOC */
-
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-void tegra30_clock_init(struct device_node *np);
-#else
-static inline void tegra30_clock_init(struct device_node *np) {}
-#endif /* CONFIG_ARCH_TEGRA_3x_SOC */
-
-#ifdef CONFIG_ARCH_TEGRA_114_SOC
-void tegra114_clock_init(struct device_node *np);
-#else
-static inline void tegra114_clock_init(struct device_node *np) {}
-#endif /* CONFIG_ARCH_TEGRA114_SOC */
+void tegra114_clock_tune_cpu_trimmers_high(void);
+void tegra114_clock_tune_cpu_trimmers_low(void);
+void tegra114_clock_tune_cpu_trimmers_init(void);
+void tegra114_clock_assert_dfll_dvco_reset(void);
+void tegra114_clock_deassert_dfll_dvco_reset(void);
 
 typedef void (*tegra_clk_apply_init_table_func)(void);
 extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/tegra/clk-pll.c linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk-pll.c
--- linux-libre-3.10-gnu/drivers/clk/tegra/clk-pll.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk-pll.c	2013-08-25 20:43:22.000000000 -0400
@@ -117,10 +117,6 @@
 #define PLLCX_MISC2_DEFAULT 0x30211200
 #define PLLCX_MISC3_DEFAULT 0x200
 
-#define PMC_PLLM_WB0_OVERRIDE	0x1dc
-#define PMC_PLLM_WB0_OVERRIDE_2	0x2b0
-#define PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK BIT(27)
-
 #define PMC_SATA_PWRGT 0x1ac
 #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
 #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
@@ -128,38 +124,31 @@
 #define pll_readl(offset, p) readl_relaxed(p->clk_base + offset)
 #define pll_readl_base(p) pll_readl(p->params->base_reg, p)
 #define pll_readl_misc(p) pll_readl(p->params->misc_reg, p)
+#define pll_override_readl(offset, p) readl_relaxed(p->pmc + offset)
 
 #define pll_writel(val, offset, p) writel_relaxed(val, p->clk_base + offset)
 #define pll_writel_base(val, p) pll_writel(val, p->params->base_reg, p)
 #define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p)
+#define pll_override_writel(val, offset, p) writel(val, p->pmc + offset)
 
 #define mask(w) ((1 << (w)) - 1)
-#define divm_mask(p) mask(p->divm_width)
-#define divn_mask(p) mask(p->divn_width)
+#define divm_mask(p) mask(p->params->div_nmp->divm_width)
+#define divn_mask(p) mask(p->params->div_nmp->divn_width)
 #define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK :	\
-		      mask(p->divp_width))
+		      mask(p->params->div_nmp->divp_width))
 
 #define divm_max(p) (divm_mask(p))
 #define divn_max(p) (divn_mask(p))
 #define divp_max(p) (1 << (divp_mask(p)))
 
-
-#ifdef CONFIG_ARCH_TEGRA_114_SOC
-/* PLLXC has 4-bit PDIV, but entry 15 is not allowed in h/w */
-#define PLLXC_PDIV_MAX			14
-
-/* non-monotonic mapping below is not a typo */
-static u8 pllxc_p[PLLXC_PDIV_MAX + 1] = {
-	/* PDIV: 0, 1, 2, 3, 4, 5, 6,  7,  8,  9, 10, 11, 12, 13, 14 */
-	/* p: */ 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 12, 16, 20, 24, 32
-};
-
-#define PLLCX_PDIV_MAX 7
-static u8 pllcx_p[PLLCX_PDIV_MAX + 1] = {
-	/* PDIV: 0, 1, 2, 3, 4, 5,  6,  7 */
-	/* p: */ 1, 2, 3, 4, 6, 8, 12, 16
+static struct div_nmp default_nmp = {
+	.divn_shift = PLL_BASE_DIVN_SHIFT,
+	.divn_width = PLL_BASE_DIVN_WIDTH,
+	.divm_shift = PLL_BASE_DIVM_SHIFT,
+	.divm_width = PLL_BASE_DIVM_WIDTH,
+	.divp_shift = PLL_BASE_DIVP_SHIFT,
+	.divp_width = PLL_BASE_DIVP_WIDTH,
 };
-#endif
 
 static void clk_pll_enable_lock(struct tegra_clk_pll *pll)
 {
@@ -297,6 +286,39 @@ static void clk_pll_disable(struct clk_h
 		spin_unlock_irqrestore(pll->lock, flags);
 }
 
+static int _p_div_to_hw(struct clk_hw *hw, u8 p_div)
+{
+	struct tegra_clk_pll *pll = to_clk_pll(hw);
+	struct pdiv_map *p_tohw = pll->params->pdiv_tohw;
+
+	if (p_tohw) {
+		while (p_tohw->pdiv) {
+			if (p_div <= p_tohw->pdiv)
+				return p_tohw->hw_val;
+			p_tohw++;
+		}
+		return -EINVAL;
+	}
+	return -EINVAL;
+}
+
+static int _hw_to_p_div(struct clk_hw *hw, u8 p_div_hw)
+{
+	struct tegra_clk_pll *pll = to_clk_pll(hw);
+	struct pdiv_map *p_tohw = pll->params->pdiv_tohw;
+
+	if (p_tohw) {
+		while (p_tohw->pdiv) {
+			if (p_div_hw == p_tohw->hw_val)
+				return p_tohw->pdiv;
+			p_tohw++;
+		}
+		return -EINVAL;
+	}
+
+	return 1 << p_div_hw;
+}
+
 static int _get_table_rate(struct clk_hw *hw,
 			   struct tegra_clk_pll_freq_table *cfg,
 			   unsigned long rate, unsigned long parent_rate)
@@ -326,9 +348,9 @@ static int _calc_rate(struct clk_hw *hw,
 		      unsigned long rate, unsigned long parent_rate)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
-	struct pdiv_map *p_tohw = pll->params->pdiv_tohw;
 	unsigned long cfreq;
 	u32 p_div = 0;
+	int ret;
 
 	switch (parent_rate) {
 	case 12000000:
@@ -369,20 +391,16 @@ static int _calc_rate(struct clk_hw *hw,
 	    || cfg->output_rate > pll->params->vco_max) {
 		pr_err("%s: Failed to set %s rate %lu\n",
 		       __func__, __clk_get_name(hw->clk), rate);
+		WARN_ON(1);
 		return -EINVAL;
 	}
 
-	if (p_tohw) {
-		p_div = 1 << p_div;
-		while (p_tohw->pdiv) {
-			if (p_div <= p_tohw->pdiv) {
-				cfg->p = p_tohw->hw_val;
-				break;
-			}
-			p_tohw++;
-		}
-		if (!p_tohw->pdiv)
-			return -EINVAL;
+	if (pll->params->pdiv_tohw) {
+		ret = _p_div_to_hw(hw, 1 << p_div);
+		if (ret < 0)
+			return ret;
+		else
+			cfg->p = ret;
 	} else
 		cfg->p = p_div;
 
@@ -393,29 +411,61 @@ static void _update_pll_mnp(struct tegra
 			    struct tegra_clk_pll_freq_table *cfg)
 {
 	u32 val;
+	struct tegra_clk_pll_params *params = pll->params;
+	struct div_nmp *div_nmp = params->div_nmp;
 
-	val = pll_readl_base(pll);
+	if ((pll->flags & TEGRA_PLLM) &&
+		(pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) &
+			PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) {
+		val = pll_override_readl(params->pmc_divp_reg, pll);
+		val &= ~(divp_mask(pll) << div_nmp->override_divp_shift);
+		val |= cfg->p << div_nmp->override_divp_shift;
+		pll_override_writel(val, params->pmc_divp_reg, pll);
 
-	val &= ~((divm_mask(pll) << pll->divm_shift) |
-		 (divn_mask(pll) << pll->divn_shift) |
-		 (divp_mask(pll) << pll->divp_shift));
-	val |= ((cfg->m << pll->divm_shift) |
-		(cfg->n << pll->divn_shift) |
-		(cfg->p << pll->divp_shift));
+		val = pll_override_readl(params->pmc_divnm_reg, pll);
+		val &= ~(divm_mask(pll) << div_nmp->override_divm_shift) |
+			~(divn_mask(pll) << div_nmp->override_divn_shift);
+		val |= (cfg->m << div_nmp->override_divm_shift) |
+			(cfg->n << div_nmp->override_divn_shift);
+		pll_override_writel(val, params->pmc_divnm_reg, pll);
+	} else {
+		val = pll_readl_base(pll);
 
-	pll_writel_base(val, pll);
+		val &= ~((divm_mask(pll) << div_nmp->divm_shift) |
+		 (divn_mask(pll) << div_nmp->divn_shift) |
+		 (divp_mask(pll) << div_nmp->divp_shift));
+
+		val |= ((cfg->m << div_nmp->divm_shift) |
+			(cfg->n << div_nmp->divn_shift) |
+			(cfg->p << div_nmp->divp_shift));
+
+		pll_writel_base(val, pll);
+	}
 }
 
 static void _get_pll_mnp(struct tegra_clk_pll *pll,
 			 struct tegra_clk_pll_freq_table *cfg)
 {
 	u32 val;
+	struct tegra_clk_pll_params *params = pll->params;
+	struct div_nmp *div_nmp = params->div_nmp;
 
-	val = pll_readl_base(pll);
+	if ((pll->flags & TEGRA_PLLM) &&
+		(pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) &
+			PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) {
+		val = pll_override_readl(params->pmc_divp_reg, pll);
+		cfg->p = (val >> div_nmp->override_divp_shift) & divp_mask(pll);
 
-	cfg->m = (val >> pll->divm_shift) & (divm_mask(pll));
-	cfg->n = (val >> pll->divn_shift) & (divn_mask(pll));
-	cfg->p = (val >> pll->divp_shift) & (divp_mask(pll));
+		val = pll_override_readl(params->pmc_divnm_reg, pll);
+		cfg->m = (val >> div_nmp->override_divm_shift) & divm_mask(pll);
+		cfg->n = (val >> div_nmp->override_divn_shift) & divn_mask(pll);
+	}  else {
+		val = pll_readl_base(pll);
+
+		cfg->m = (val >> div_nmp->divm_shift) & divm_mask(pll);
+		cfg->n = (val >> div_nmp->divn_shift) & divn_mask(pll);
+		cfg->p = (val >> div_nmp->divp_shift) & divp_mask(pll);
+	}
 }
 
 static void _update_pll_cpcon(struct tegra_clk_pll *pll,
@@ -485,9 +535,10 @@ static int clk_pll_set_rate(struct clk_h
 	}
 
 	if (_get_table_rate(hw, &cfg, rate, parent_rate) &&
-	    _calc_rate(hw, &cfg, rate, parent_rate))
+	    _calc_rate(hw, &cfg, rate, parent_rate)) {
+		WARN_ON(1);
 		return -EINVAL;
-
+	}
 	if (pll->lock)
 		spin_lock_irqsave(pll->lock, flags);
 
@@ -507,7 +558,6 @@ static long clk_pll_round_rate(struct cl
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
 	struct tegra_clk_pll_freq_table cfg;
-	u64 output_rate = *prate;
 
 	if (pll->flags & TEGRA_PLL_FIXED)
 		return pll->fixed_rate;
@@ -517,13 +567,12 @@ static long clk_pll_round_rate(struct cl
 		return __clk_get_rate(hw->clk);
 
 	if (_get_table_rate(hw, &cfg, rate, *prate) &&
-	    _calc_rate(hw, &cfg, rate, *prate))
+	    _calc_rate(hw, &cfg, rate, *prate)) {
+		WARN_ON(1);
 		return -EINVAL;
+	}
 
-	output_rate *= cfg.n;
-	do_div(output_rate, cfg.m * (1 << cfg.p));
-
-	return output_rate;
+	return cfg.output_rate;
 }
 
 static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
@@ -531,7 +580,6 @@ static unsigned long clk_pll_recalc_rate
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
 	struct tegra_clk_pll_freq_table cfg;
-	struct pdiv_map *p_tohw = pll->params->pdiv_tohw;
 	u32 val;
 	u64 rate = parent_rate;
 	int pdiv;
@@ -553,21 +601,11 @@ static unsigned long clk_pll_recalc_rate
 
 	_get_pll_mnp(pll, &cfg);
 
-	if (p_tohw) {
-		while (p_tohw->pdiv) {
-			if (cfg.p == p_tohw->hw_val) {
-				pdiv = p_tohw->pdiv;
-				break;
-			}
-			p_tohw++;
-		}
-
-		if (!p_tohw->pdiv) {
-			WARN_ON(1);
-			pdiv = 1;
-		}
-	} else
-		pdiv = 1 << cfg.p;
+	pdiv = _hw_to_p_div(hw, cfg.p);
+	if (pdiv < 0) {
+		WARN_ON(1);
+		pdiv = 1;
+	}
 
 	cfg.m *= pdiv;
 
@@ -647,9 +685,9 @@ static int clk_plle_enable(struct clk_hw
 		val = pll_readl_base(pll);
 		val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
 		val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
-		val |= sel.m << pll->divm_shift;
-		val |= sel.n << pll->divn_shift;
-		val |= sel.p << pll->divp_shift;
+		val |= sel.m << pll->params->div_nmp->divm_shift;
+		val |= sel.n << pll->params->div_nmp->divn_shift;
+		val |= sel.p << pll->params->div_nmp->divp_shift;
 		val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
 		pll_writel_base(val, pll);
 	}
@@ -680,9 +718,9 @@ static unsigned long clk_plle_recalc_rat
 	u32 divn = 0, divm = 0, divp = 0;
 	u64 rate = parent_rate;
 
-	divp = (val >> pll->divp_shift) & (divp_mask(pll));
-	divn = (val >> pll->divn_shift) & (divn_mask(pll));
-	divm = (val >> pll->divm_shift) & (divm_mask(pll));
+	divp = (val >> pll->params->div_nmp->divp_shift) & (divp_mask(pll));
+	divn = (val >> pll->params->div_nmp->divn_shift) & (divn_mask(pll));
+	divm = (val >> pll->params->div_nmp->divm_shift) & (divm_mask(pll));
 	divm *= divp;
 
 	rate *= divn;
@@ -769,16 +807,22 @@ static int _calc_dynamic_ramp_rate(struc
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
 	unsigned int p;
+	int p_div;
 
 	if (!rate)
 		return -EINVAL;
 
 	p = DIV_ROUND_UP(pll->params->vco_min, rate);
 	cfg->m = _pll_fixed_mdiv(pll->params, parent_rate);
-	cfg->p = p;
-	cfg->output_rate = rate * cfg->p;
+	cfg->output_rate = rate * p;
 	cfg->n = cfg->output_rate * cfg->m / parent_rate;
 
+	p_div = _p_div_to_hw(hw, p);
+	if (p_div < 0)
+		return p_div;
+	else
+		cfg->p = p_div;
+
 	if (cfg->n > divn_max(pll) || cfg->output_rate > pll->params->vco_max)
 		return -EINVAL;
 
@@ -790,18 +834,25 @@ static int _pll_ramp_calc_pll(struct clk
 			      unsigned long rate, unsigned long parent_rate)
 {
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
-	int err = 0;
+	int err = 0, p_div;
 
 	err = _get_table_rate(hw, cfg, rate, parent_rate);
 	if (err < 0)
 		err = _calc_dynamic_ramp_rate(hw, cfg, rate, parent_rate);
-	else if (cfg->m != _pll_fixed_mdiv(pll->params, parent_rate)) {
+	else {
+		if (cfg->m != _pll_fixed_mdiv(pll->params, parent_rate)) {
 			WARN_ON(1);
 			err = -EINVAL;
 			goto out;
+		}
+		p_div = _p_div_to_hw(hw, cfg->p);
+		if (p_div < 0)
+			return p_div;
+		else
+			cfg->p = p_div;
 	}
 
-	if (!cfg->p || (cfg->p >  pll->params->max_p))
+	if (cfg->p >  pll->params->max_p)
 		err = -EINVAL;
 
 out:
@@ -815,7 +866,6 @@ static int clk_pllxc_set_rate(struct clk
 	struct tegra_clk_pll_freq_table cfg, old_cfg;
 	unsigned long flags = 0;
 	int ret = 0;
-	u8 old_p;
 
 	ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate);
 	if (ret < 0)
@@ -826,11 +876,8 @@ static int clk_pllxc_set_rate(struct clk
 
 	_get_pll_mnp(pll, &old_cfg);
 
-	old_p = pllxc_p[old_cfg.p];
-	if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_p != cfg.p) {
-		cfg.p -= 1;
+	if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p)
 		ret = _program_pll(hw, &cfg, rate);
-	}
 
 	if (pll->lock)
 		spin_unlock_irqrestore(pll->lock, flags);
@@ -842,15 +889,19 @@ static long clk_pll_ramp_round_rate(stru
 				unsigned long *prate)
 {
 	struct tegra_clk_pll_freq_table cfg;
-	int ret = 0;
+	int ret = 0, p_div;
 	u64 output_rate = *prate;
 
 	ret = _pll_ramp_calc_pll(hw, &cfg, rate, *prate);
 	if (ret < 0)
 		return ret;
 
+	p_div = _hw_to_p_div(hw, cfg.p);
+	if (p_div < 0)
+		return p_div;
+
 	output_rate *= cfg.n;
-	do_div(output_rate, cfg.m * cfg.p);
+	do_div(output_rate, cfg.m * p_div);
 
 	return output_rate;
 }
@@ -862,7 +913,6 @@ static int clk_pllm_set_rate(struct clk_
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
 	unsigned long flags = 0;
 	int state, ret = 0;
-	u32 val;
 
 	if (pll->lock)
 		spin_lock_irqsave(pll->lock, flags);
@@ -881,22 +931,7 @@ static int clk_pllm_set_rate(struct clk_
 	if (ret < 0)
 		goto out;
 
-	cfg.p -= 1;
-
-	val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE);
-	if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) {
-		val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE_2);
-		val = cfg.p ? (val | PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK) :
-			(val & ~PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK);
-		writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE_2);
-
-		val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE);
-		val &= ~(divn_mask(pll) | divm_mask(pll));
-		val |= (cfg.m << pll->divm_shift) | (cfg.n << pll->divn_shift);
-		writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE);
-	} else
-		_update_pll_mnp(pll, &cfg);
-
+	_update_pll_mnp(pll, &cfg);
 
 out:
 	if (pll->lock)
@@ -1010,13 +1045,10 @@ static int _pllcx_update_dynamic_coef(st
 static int clk_pllc_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate)
 {
-	struct tegra_clk_pll_freq_table cfg;
+	struct tegra_clk_pll_freq_table cfg, old_cfg;
 	struct tegra_clk_pll *pll = to_clk_pll(hw);
 	unsigned long flags = 0;
 	int state, ret = 0;
-	u32 val;
-	u16 old_m, old_n;
-	u8 old_p;
 
 	if (pll->lock)
 		spin_lock_irqsave(pll->lock, flags);
@@ -1025,21 +1057,16 @@ static int clk_pllc_set_rate(struct clk_
 	if (ret < 0)
 		goto out;
 
-	val = pll_readl_base(pll);
-	old_m = (val >> pll->divm_shift) & (divm_mask(pll));
-	old_n = (val >> pll->divn_shift) & (divn_mask(pll));
-	old_p = pllcx_p[(val >> pll->divp_shift) & (divp_mask(pll))];
+	_get_pll_mnp(pll, &old_cfg);
 
-	if (cfg.m != old_m) {
+	if (cfg.m != old_cfg.m) {
 		WARN_ON(1);
 		goto out;
 	}
 
-	if (old_n == cfg.n && old_p == cfg.p)
+	if (old_cfg.n == cfg.n && old_cfg.p == cfg.p)
 		goto out;
 
-	cfg.p -= 1;
-
 	state = clk_pll_is_enabled(hw);
 	if (state)
 		_clk_pllc_disable(hw);
@@ -1178,8 +1205,8 @@ static int clk_plle_tegra114_enable(stru
 	val = pll_readl_base(pll);
 	val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
 	val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
-	val |= sel.m << pll->divm_shift;
-	val |= sel.n << pll->divn_shift;
+	val |= sel.m << pll->params->div_nmp->divm_shift;
+	val |= sel.n << pll->params->div_nmp->divn_shift;
 	val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
 	pll_writel_base(val, pll);
 	udelay(1);
@@ -1240,12 +1267,8 @@ static struct tegra_clk_pll *_tegra_init
 	pll->flags = pll_flags;
 	pll->lock = lock;
 
-	pll->divp_shift = PLL_BASE_DIVP_SHIFT;
-	pll->divp_width = PLL_BASE_DIVP_WIDTH;
-	pll->divn_shift = PLL_BASE_DIVN_SHIFT;
-	pll->divn_width = PLL_BASE_DIVN_WIDTH;
-	pll->divm_shift = PLL_BASE_DIVM_SHIFT;
-	pll->divm_width = PLL_BASE_DIVM_WIDTH;
+	if (!pll_params->div_nmp)
+		pll_params->div_nmp = &default_nmp;
 
 	return pll;
 }
@@ -1401,7 +1424,7 @@ struct clk *tegra_clk_register_pllre(con
 	struct tegra_clk_pll *pll;
 	struct clk *clk;
 
-	pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+	pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE | TEGRA_PLL_LOCK_MISC;
 	pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
 			      freq_table, lock);
 	if (IS_ERR(pll))
@@ -1428,7 +1451,6 @@ struct clk *tegra_clk_register_pllre(con
 	val &= ~BIT(29);
 	pll_writel_misc(val, pll);
 
-	pll_flags |= TEGRA_PLL_LOCK_MISC;
 	clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
 				      &tegra_clk_pllre_ops);
 	if (IS_ERR(clk))
@@ -1453,6 +1475,7 @@ struct clk *tegra_clk_register_pllm(cons
 
 	pll_flags |= TEGRA_PLL_BYPASS;
 	pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+	pll_flags |= TEGRA_PLLM;
 	pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
 			      freq_table, lock);
 	if (IS_ERR(pll))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/tegra/clk-tegra114.c linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk-tegra114.c
--- linux-libre-3.10-gnu/drivers/clk/tegra/clk-tegra114.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk-tegra114.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/clk/tegra.h>
 
 #include "clk.h"
@@ -28,6 +29,7 @@
 #define RST_DEVICES_L			0x004
 #define RST_DEVICES_H			0x008
 #define RST_DEVICES_U			0x00C
+#define RST_DFLL_DVCO			0x2F4
 #define RST_DEVICES_V			0x358
 #define RST_DEVICES_W			0x35C
 #define RST_DEVICES_X			0x28C
@@ -41,8 +43,36 @@
 #define RST_DEVICES_CLR_V		0x434
 #define RST_DEVICES_SET_W		0x438
 #define RST_DEVICES_CLR_W		0x43c
+#define CPU_FINETRIM_SELECT		0x4d4	/* override default prop dlys */
+#define CPU_FINETRIM_DR			0x4d8	/* rise->rise prop dly A */
+#define CPU_FINETRIM_R			0x4e4	/* rise->rise prop dly inc A */
 #define RST_DEVICES_NUM			5
 
+/* RST_DFLL_DVCO bitfields */
+#define DVFS_DFLL_RESET_SHIFT		0
+
+/* CPU_FINETRIM_SELECT and CPU_FINETRIM_DR bitfields */
+#define CPU_FINETRIM_1_FCPU_1		BIT(0)	/* fcpu0 */
+#define CPU_FINETRIM_1_FCPU_2		BIT(1)	/* fcpu1 */
+#define CPU_FINETRIM_1_FCPU_3		BIT(2)	/* fcpu2 */
+#define CPU_FINETRIM_1_FCPU_4		BIT(3)	/* fcpu3 */
+#define CPU_FINETRIM_1_FCPU_5		BIT(4)	/* fl2 */
+#define CPU_FINETRIM_1_FCPU_6		BIT(5)	/* ftop */
+
+/* CPU_FINETRIM_R bitfields */
+#define CPU_FINETRIM_R_FCPU_1_SHIFT	0		/* fcpu0 */
+#define CPU_FINETRIM_R_FCPU_1_MASK	(0x3 << CPU_FINETRIM_R_FCPU_1_SHIFT)
+#define CPU_FINETRIM_R_FCPU_2_SHIFT	2		/* fcpu1 */
+#define CPU_FINETRIM_R_FCPU_2_MASK	(0x3 << CPU_FINETRIM_R_FCPU_2_SHIFT)
+#define CPU_FINETRIM_R_FCPU_3_SHIFT	4		/* fcpu2 */
+#define CPU_FINETRIM_R_FCPU_3_MASK	(0x3 << CPU_FINETRIM_R_FCPU_3_SHIFT)
+#define CPU_FINETRIM_R_FCPU_4_SHIFT	6		/* fcpu3 */
+#define CPU_FINETRIM_R_FCPU_4_MASK	(0x3 << CPU_FINETRIM_R_FCPU_4_SHIFT)
+#define CPU_FINETRIM_R_FCPU_5_SHIFT	8		/* fl2 */
+#define CPU_FINETRIM_R_FCPU_5_MASK	(0x3 << CPU_FINETRIM_R_FCPU_5_SHIFT)
+#define CPU_FINETRIM_R_FCPU_6_SHIFT	10		/* ftop */
+#define CPU_FINETRIM_R_FCPU_6_MASK	(0x3 << CPU_FINETRIM_R_FCPU_6_SHIFT)
+
 #define CLK_OUT_ENB_L			0x010
 #define CLK_OUT_ENB_H			0x014
 #define CLK_OUT_ENB_U			0x018
@@ -127,6 +157,7 @@
 #define PMC_DPD_PADS_ORIDE_BLINK_ENB 20
 #define PMC_CTRL 0
 #define PMC_CTRL_BLINK_ENB 7
+#define PMC_BLINK_TIMER 0x40
 
 #define OSC_CTRL			0x50
 #define OSC_CTRL_OSC_FREQ_SHIFT		28
@@ -242,6 +273,8 @@
 #define CLK_SOURCE_I2CSLOW 0x3fc
 #define CLK_SOURCE_SE 0x42c
 #define CLK_SOURCE_MSELECT 0x3b4
+#define CLK_SOURCE_DFLL_REF 0x62c
+#define CLK_SOURCE_DFLL_SOC 0x630
 #define CLK_SOURCE_SOC_THERM 0x644
 #define CLK_SOURCE_XUSB_HOST_SRC 0x600
 #define CLK_SOURCE_XUSB_FALCON_SRC 0x604
@@ -250,6 +283,13 @@
 #define CLK_SOURCE_XUSB_DEV_SRC 0x60c
 #define CLK_SOURCE_EMC 0x19c
 
+/* PLLM override registers */
+#define PMC_PLLM_WB0_OVERRIDE 0x1dc
+#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
+
+/* Tegra CPU clock and reset control regs */
+#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS	0x470
+
 static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
 
 static void __iomem *clk_base;
@@ -264,6 +304,15 @@ static DEFINE_SPINLOCK(clk_doubler_lock)
 static DEFINE_SPINLOCK(clk_out_lock);
 static DEFINE_SPINLOCK(sysrate_lock);
 
+static struct div_nmp pllxc_nmp = {
+	.divm_shift = 0,
+	.divm_width = 8,
+	.divn_shift = 8,
+	.divn_width = 8,
+	.divp_shift = 20,
+	.divp_width = 4,
+};
+
 static struct pdiv_map pllxc_p[] = {
 	{ .pdiv = 1, .hw_val = 0 },
 	{ .pdiv = 2, .hw_val = 1 },
@@ -312,6 +361,16 @@ static struct tegra_clk_pll_params pll_c
 	.stepa_shift = 17,
 	.stepb_shift = 9,
 	.pdiv_tohw = pllxc_p,
+	.div_nmp = &pllxc_nmp,
+};
+
+static struct div_nmp pllcx_nmp = {
+	.divm_shift = 0,
+	.divm_width = 2,
+	.divn_shift = 8,
+	.divn_width = 8,
+	.divp_shift = 20,
+	.divp_width = 3,
 };
 
 static struct pdiv_map pllc_p[] = {
@@ -345,6 +404,8 @@ static struct tegra_clk_pll_params pll_c
 	.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 	.lock_delay = 300,
 	.pdiv_tohw = pllc_p,
+	.div_nmp = &pllcx_nmp,
+	.max_p = 7,
 	.ext_misc_reg[0] = 0x4f0,
 	.ext_misc_reg[1] = 0x4f4,
 	.ext_misc_reg[2] = 0x4f8,
@@ -363,11 +424,25 @@ static struct tegra_clk_pll_params pll_c
 	.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 	.lock_delay = 300,
 	.pdiv_tohw = pllc_p,
+	.div_nmp = &pllcx_nmp,
+	.max_p = 7,
 	.ext_misc_reg[0] = 0x504,
 	.ext_misc_reg[1] = 0x508,
 	.ext_misc_reg[2] = 0x50c,
 };
 
+static struct div_nmp pllm_nmp = {
+	.divm_shift = 0,
+	.divm_width = 8,
+	.override_divm_shift = 0,
+	.divn_shift = 8,
+	.divn_width = 8,
+	.override_divn_shift = 8,
+	.divp_shift = 20,
+	.divp_width = 1,
+	.override_divp_shift = 27,
+};
+
 static struct pdiv_map pllm_p[] = {
 	{ .pdiv = 1, .hw_val = 0 },
 	{ .pdiv = 2, .hw_val = 1 },
@@ -397,6 +472,18 @@ static struct tegra_clk_pll_params pll_m
 	.lock_delay = 300,
 	.max_p = 2,
 	.pdiv_tohw = pllm_p,
+	.div_nmp = &pllm_nmp,
+	.pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE,
+	.pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2,
+};
+
+static struct div_nmp pllp_nmp = {
+	.divm_shift = 0,
+	.divm_width = 5,
+	.divn_shift = 8,
+	.divn_width = 10,
+	.divp_shift = 20,
+	.divp_width = 3,
 };
 
 static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
@@ -420,6 +507,7 @@ static struct tegra_clk_pll_params pll_p
 	.lock_mask = PLL_BASE_LOCK,
 	.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 	.lock_delay = 300,
+	.div_nmp = &pllp_nmp,
 };
 
 static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
@@ -446,6 +534,7 @@ static struct tegra_clk_pll_params pll_a
 	.lock_mask = PLL_BASE_LOCK,
 	.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 	.lock_delay = 300,
+	.div_nmp = &pllp_nmp,
 };
 
 static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
@@ -481,6 +570,7 @@ static struct tegra_clk_pll_params pll_d
 	.lock_mask = PLL_BASE_LOCK,
 	.lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
 	.lock_delay = 1000,
+	.div_nmp = &pllp_nmp,
 };
 
 static struct tegra_clk_pll_params pll_d2_params = {
@@ -495,6 +585,7 @@ static struct tegra_clk_pll_params pll_d
 	.lock_mask = PLL_BASE_LOCK,
 	.lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
 	.lock_delay = 1000,
+	.div_nmp = &pllp_nmp,
 };
 
 static struct pdiv_map pllu_p[] = {
@@ -503,6 +594,15 @@ static struct pdiv_map pllu_p[] = {
 	{ .pdiv = 0, .hw_val = 0 },
 };
 
+static struct div_nmp pllu_nmp = {
+	.divm_shift = 0,
+	.divm_width = 5,
+	.divn_shift = 8,
+	.divn_width = 10,
+	.divp_shift = 20,
+	.divp_width = 1,
+};
+
 static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
 	{12000000, 480000000, 960, 12, 0, 12},
 	{13000000, 480000000, 960, 13, 0, 12},
@@ -525,6 +625,7 @@ static struct tegra_clk_pll_params pll_u
 	.lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
 	.lock_delay = 1000,
 	.pdiv_tohw = pllu_p,
+	.div_nmp = &pllu_nmp,
 };
 
 static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
@@ -557,6 +658,7 @@ static struct tegra_clk_pll_params pll_x
 	.stepa_shift = 16,
 	.stepb_shift = 24,
 	.pdiv_tohw = pllxc_p,
+	.div_nmp = &pllxc_nmp,
 };
 
 static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
@@ -566,6 +668,15 @@ static struct tegra_clk_pll_freq_table p
 	{0, 0, 0, 0, 0, 0},
 };
 
+static struct div_nmp plle_nmp = {
+	.divm_shift = 0,
+	.divm_width = 8,
+	.divn_shift = 8,
+	.divn_width = 8,
+	.divp_shift = 24,
+	.divp_width = 4,
+};
+
 static struct tegra_clk_pll_params pll_e_params = {
 	.input_min = 12000000,
 	.input_max = 1000000000,
@@ -579,6 +690,16 @@ static struct tegra_clk_pll_params pll_e
 	.lock_mask = PLLE_MISC_LOCK,
 	.lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
 	.lock_delay = 300,
+	.div_nmp = &plle_nmp,
+};
+
+static struct div_nmp pllre_nmp = {
+	.divm_shift = 0,
+	.divm_width = 8,
+	.divn_shift = 8,
+	.divn_width = 8,
+	.divp_shift = 16,
+	.divp_width = 4,
 };
 
 static struct tegra_clk_pll_params pll_re_vco_params = {
@@ -595,6 +716,7 @@ static struct tegra_clk_pll_params pll_r
 	.lock_delay = 300,
 	.iddq_reg = PLLRE_MISC,
 	.iddq_bit_idx = PLLRE_IDDQ_BIT,
+	.div_nmp = &pllre_nmp,
 };
 
 /* Peripheral clock registers */
@@ -762,6 +884,7 @@ enum tegra114_clk {
 	audio1, audio2, audio3, audio4, spdif, clk_out_1, clk_out_2, clk_out_3,
 	blink, xusb_host_src = 252, xusb_falcon_src, xusb_fs_src, xusb_ss_src,
 	xusb_dev_src, xusb_dev, xusb_hs_src, sclk, hclk, pclk, cclk_g, cclk_lp,
+	dfll_ref = 264, dfll_soc,
 
 	/* Mux clocks */
 
@@ -1199,8 +1322,8 @@ static void __init tegra114_pll_init(voi
 	/* PLLP_OUT2 */
 	clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p",
 				clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED |
-				TEGRA_DIVIDER_ROUND_UP, 24, 8, 1,
-				&pll_div_lock);
+				TEGRA_DIVIDER_ROUND_UP | TEGRA_DIVIDER_INT, 24,
+				8, 1, &pll_div_lock);
 	clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div",
 				clk_base + PLLP_OUTA, 17, 16,
 				CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
@@ -1602,7 +1725,7 @@ static void __init tegra114_pmc_clk_init
 
 	/* clk_out_2 */
 	clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents,
-			       ARRAY_SIZE(clk_out1_parents), 0,
+			       ARRAY_SIZE(clk_out2_parents), 0,
 			       pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0,
 			       &clk_out_lock);
 	clks[clk_out_2_mux] = clk;
@@ -1614,7 +1737,7 @@ static void __init tegra114_pmc_clk_init
 
 	/* clk_out_3 */
 	clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents,
-			       ARRAY_SIZE(clk_out1_parents), 0,
+			       ARRAY_SIZE(clk_out3_parents), 0,
 			       pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0,
 			       &clk_out_lock);
 	clks[clk_out_3_mux] = clk;
@@ -1625,6 +1748,8 @@ static void __init tegra114_pmc_clk_init
 	clks[clk_out_3] = clk;
 
 	/* blink */
+	/* clear the blink timer register to directly output clk_32k */
+	writel_relaxed(0, pmc_base + PMC_BLINK_TIMER);
 	clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0,
 				pmc_base + PMC_DPD_PADS_ORIDE,
 				PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL);
@@ -1637,7 +1762,7 @@ static void __init tegra114_pmc_clk_init
 }
 
 static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
-			       "pll_p_out3", "pll_p_out2", "unused",
+			       "pll_p", "pll_p_out2", "unused",
 			       "clk_32k", "pll_m_out1" };
 
 static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
@@ -1747,7 +1872,7 @@ static struct tegra_periph_init_data teg
 	TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor),
 	TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi),
 	TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp),
-	TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_h_regs, TEGRA_PERIPH_WAR_1005168, msenc),
+	TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_u_regs, TEGRA_PERIPH_WAR_1005168, msenc),
 	TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, tsec),
 	TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x),
 	TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi),
@@ -1764,6 +1889,8 @@ static struct tegra_periph_init_data teg
 	TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow),
 	TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, se),
 	TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect, CLK_IGNORE_UNUSED),
+	TEGRA_INIT_DATA_MUX("dfll_ref", "ref", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_REF, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, dfll_ref),
+	TEGRA_INIT_DATA_MUX("dfll_soc", "soc", "t114_dfll", mux_pllp_clkm, CLK_SOURCE_DFLL_SOC, 155, &periph_w_regs, TEGRA_PERIPH_ON_APB, dfll_soc),
 	TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, soc_therm),
 	TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_host_src),
 	TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_falcon_src),
@@ -2000,13 +2127,35 @@ static __init void tegra114_periph_clk_i
 	}
 }
 
-static struct tegra_cpu_car_ops tegra114_cpu_car_ops;
+/* Tegra114 CPU clock and reset control functions */
+static void tegra114_wait_cpu_in_reset(u32 cpu)
+{
+	unsigned int reg;
+
+	do {
+		reg = readl(clk_base + CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
+		cpu_relax();
+	} while (!(reg & (1 << cpu)));  /* check CPU been reset or not */
+}
+static void tegra114_disable_cpu_clock(u32 cpu)
+{
+	/* flow controller would take care in the power sequence. */
+}
+
+static struct tegra_cpu_car_ops tegra114_cpu_car_ops = {
+	.wait_for_reset	= tegra114_wait_cpu_in_reset,
+	.disable_clock	= tegra114_disable_cpu_clock,
+};
 
 static const struct of_device_id pmc_match[] __initconst = {
 	{ .compatible = "nvidia,tegra114-pmc" },
 	{},
 };
 
+/*
+ * dfll_soc/dfll_ref apparently must be kept enabled, otherwise I2C5
+ * breaks
+ */
 static __initdata struct tegra_clk_init_table init_table[] = {
 	{uarta, pll_p, 408000000, 0},
 	{uartb, pll_p, 408000000, 0},
@@ -2022,6 +2171,8 @@ static __initdata struct tegra_clk_init_
 	{i2s2, pll_a_out0, 11289600, 0},
 	{i2s3, pll_a_out0, 11289600, 0},
 	{i2s4, pll_a_out0, 11289600, 0},
+	{dfll_soc, pll_p, 51000000, 1},
+	{dfll_ref, pll_p, 51000000, 1},
 	{clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */
 };
 
@@ -2030,7 +2181,132 @@ static void __init tegra114_clock_apply_
 	tegra_init_from_table(init_table, clks, clk_max);
 }
 
-void __init tegra114_clock_init(struct device_node *np)
+
+/**
+ * tegra114_car_barrier - wait for pending writes to the CAR to complete
+ *
+ * Wait for any outstanding writes to the CAR MMIO space from this CPU
+ * to complete before continuing execution.  No return value.
+ */
+static void tegra114_car_barrier(void)
+{
+	wmb();		/* probably unnecessary */
+	readl_relaxed(clk_base + CPU_FINETRIM_SELECT);
+}
+
+/**
+ * tegra114_clock_tune_cpu_trimmers_high - use high-voltage propagation delays
+ *
+ * When the CPU rail voltage is in the high-voltage range, use the
+ * built-in hardwired clock propagation delays in the CPU clock
+ * shaper.  No return value.
+ */
+void tegra114_clock_tune_cpu_trimmers_high(void)
+{
+	u32 select = 0;
+
+	/* Use hardwired rise->rise & fall->fall clock propagation delays */
+	select |= ~(CPU_FINETRIM_1_FCPU_1 | CPU_FINETRIM_1_FCPU_2 |
+		    CPU_FINETRIM_1_FCPU_3 | CPU_FINETRIM_1_FCPU_4 |
+		    CPU_FINETRIM_1_FCPU_5 | CPU_FINETRIM_1_FCPU_6);
+	writel_relaxed(select, clk_base + CPU_FINETRIM_SELECT);
+
+	tegra114_car_barrier();
+}
+EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_high);
+
+/**
+ * tegra114_clock_tune_cpu_trimmers_low - use low-voltage propagation delays
+ *
+ * When the CPU rail voltage is in the low-voltage range, use the
+ * extended clock propagation delays set by
+ * tegra114_clock_tune_cpu_trimmers_init().  The intention is to
+ * maintain the input clock duty cycle that the FCPU subsystem
+ * expects.  No return value.
+ */
+void tegra114_clock_tune_cpu_trimmers_low(void)
+{
+	u32 select = 0;
+
+	/*
+	 * Use software-specified rise->rise & fall->fall clock
+	 * propagation delays (from
+	 * tegra114_clock_tune_cpu_trimmers_init()
+	 */
+	select |= (CPU_FINETRIM_1_FCPU_1 | CPU_FINETRIM_1_FCPU_2 |
+		   CPU_FINETRIM_1_FCPU_3 | CPU_FINETRIM_1_FCPU_4 |
+		   CPU_FINETRIM_1_FCPU_5 | CPU_FINETRIM_1_FCPU_6);
+	writel_relaxed(select, clk_base + CPU_FINETRIM_SELECT);
+
+	tegra114_car_barrier();
+}
+EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_low);
+
+/**
+ * tegra114_clock_tune_cpu_trimmers_init - set up and enable clk prop delays
+ *
+ * Program extended clock propagation delays into the FCPU clock
+ * shaper and enable them.  XXX Define the purpose - peak current
+ * reduction?  No return value.
+ */
+/* XXX Initial voltage rail state assumption issues? */
+void tegra114_clock_tune_cpu_trimmers_init(void)
+{
+	u32 dr = 0, r = 0;
+
+	/* Increment the rise->rise clock delay by four steps */
+	r |= (CPU_FINETRIM_R_FCPU_1_MASK | CPU_FINETRIM_R_FCPU_2_MASK |
+	      CPU_FINETRIM_R_FCPU_3_MASK | CPU_FINETRIM_R_FCPU_4_MASK |
+	      CPU_FINETRIM_R_FCPU_5_MASK | CPU_FINETRIM_R_FCPU_6_MASK);
+	writel_relaxed(r, clk_base + CPU_FINETRIM_R);
+
+	/*
+	 * Use the rise->rise clock propagation delay specified in the
+	 * r field
+	 */
+	dr |= (CPU_FINETRIM_1_FCPU_1 | CPU_FINETRIM_1_FCPU_2 |
+	       CPU_FINETRIM_1_FCPU_3 | CPU_FINETRIM_1_FCPU_4 |
+	       CPU_FINETRIM_1_FCPU_5 | CPU_FINETRIM_1_FCPU_6);
+	writel_relaxed(dr, clk_base + CPU_FINETRIM_DR);
+
+	tegra114_clock_tune_cpu_trimmers_low();
+}
+EXPORT_SYMBOL(tegra114_clock_tune_cpu_trimmers_init);
+
+/**
+ * tegra114_clock_assert_dfll_dvco_reset - assert the DFLL's DVCO reset
+ *
+ * Assert the reset line of the DFLL's DVCO.  No return value.
+ */
+void tegra114_clock_assert_dfll_dvco_reset(void)
+{
+	u32 v;
+
+	v = readl_relaxed(clk_base + RST_DFLL_DVCO);
+	v |= (1 << DVFS_DFLL_RESET_SHIFT);
+	writel_relaxed(v, clk_base + RST_DFLL_DVCO);
+	tegra114_car_barrier();
+}
+EXPORT_SYMBOL(tegra114_clock_assert_dfll_dvco_reset);
+
+/**
+ * tegra114_clock_deassert_dfll_dvco_reset - deassert the DFLL's DVCO reset
+ *
+ * Deassert the reset line of the DFLL's DVCO, allowing the DVCO to
+ * operate.  No return value.
+ */
+void tegra114_clock_deassert_dfll_dvco_reset(void)
+{
+	u32 v;
+
+	v = readl_relaxed(clk_base + RST_DFLL_DVCO);
+	v &= ~(1 << DVFS_DFLL_RESET_SHIFT);
+	writel_relaxed(v, clk_base + RST_DFLL_DVCO);
+	tegra114_car_barrier();
+}
+EXPORT_SYMBOL(tegra114_clock_deassert_dfll_dvco_reset);
+
+static void __init tegra114_clock_init(struct device_node *np)
 {
 	struct device_node *node;
 	int i;
@@ -2083,3 +2359,4 @@ void __init tegra114_clock_init(struct d
 
 	tegra_cpu_car_ops = &tegra114_cpu_car_ops;
 }
+CLK_OF_DECLARE(tegra114, "nvidia,tegra114-car", tegra114_clock_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/tegra/clk-tegra20.c linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk-tegra20.c
--- linux-libre-3.10-gnu/drivers/clk/tegra/clk-tegra20.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk-tegra20.c	2013-08-25 20:43:22.000000000 -0400
@@ -1287,7 +1287,7 @@ static const struct of_device_id pmc_mat
 	{},
 };
 
-void __init tegra20_clock_init(struct device_node *np)
+static void __init tegra20_clock_init(struct device_node *np)
 {
 	int i;
 	struct device_node *node;
@@ -1339,3 +1339,4 @@ void __init tegra20_clock_init(struct de
 
 	tegra_cpu_car_ops = &tegra20_cpu_car_ops;
 }
+CLK_OF_DECLARE(tegra20, "nvidia,tegra20-car", tegra20_clock_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/tegra/clk-tegra30.c linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk-tegra30.c
--- linux-libre-3.10-gnu/drivers/clk/tegra/clk-tegra30.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/tegra/clk-tegra30.c	2013-08-25 20:43:22.000000000 -0400
@@ -252,6 +252,9 @@
 #define CLK_RESET_CCLK_RUN_POLICY		2
 #define CLK_RESET_CCLK_BURST_POLICY_PLLX	8
 
+/* PLLM override registers */
+#define PMC_PLLM_WB0_OVERRIDE 0x1dc
+
 #ifdef CONFIG_PM_SLEEP
 static struct cpu_clk_suspend_context {
 	u32 pllx_misc;
@@ -563,6 +566,18 @@ static struct tegra_clk_pll_params pll_c
 	.lock_delay = 300,
 };
 
+static struct div_nmp pllm_nmp = {
+	.divn_shift = 8,
+	.divn_width = 10,
+	.override_divn_shift = 5,
+	.divm_shift = 0,
+	.divm_width = 5,
+	.override_divm_shift = 0,
+	.divp_shift = 20,
+	.divp_width = 3,
+	.override_divp_shift = 15,
+};
+
 static struct tegra_clk_pll_params pll_m_params = {
 	.input_min = 2000000,
 	.input_max = 31000000,
@@ -575,6 +590,9 @@ static struct tegra_clk_pll_params pll_m
 	.lock_mask = PLL_BASE_LOCK,
 	.lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
 	.lock_delay = 300,
+	.div_nmp = &pllm_nmp,
+	.pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE,
+	.pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE,
 };
 
 static struct tegra_clk_pll_params pll_p_params = {
@@ -1223,7 +1241,7 @@ static void __init tegra30_pmc_clk_init(
 
 	/* clk_out_2 */
 	clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents,
-			       ARRAY_SIZE(clk_out1_parents), 0,
+			       ARRAY_SIZE(clk_out2_parents), 0,
 			       pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0,
 			       &clk_out_lock);
 	clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0,
@@ -1234,7 +1252,7 @@ static void __init tegra30_pmc_clk_init(
 
 	/* clk_out_3 */
 	clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents,
-			       ARRAY_SIZE(clk_out1_parents), 0,
+			       ARRAY_SIZE(clk_out3_parents), 0,
 			       pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0,
 			       &clk_out_lock);
 	clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0,
@@ -1954,7 +1972,7 @@ static const struct of_device_id pmc_mat
 	{},
 };
 
-void __init tegra30_clock_init(struct device_node *np)
+static void __init tegra30_clock_init(struct device_node *np)
 {
 	struct device_node *node;
 	int i;
@@ -2005,3 +2023,4 @@ void __init tegra30_clock_init(struct de
 
 	tegra_cpu_car_ops = &tegra30_cpu_car_ops;
 }
+CLK_OF_DECLARE(tegra30, "nvidia,tegra30-car", tegra30_clock_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/ux500/abx500-clk.c linux-libre-3.11-rc7-gnu/drivers/clk/ux500/abx500-clk.c
--- linux-libre-3.10-gnu/drivers/clk/ux500/abx500-clk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/ux500/abx500-clk.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,7 +45,7 @@ static int ab8500_reg_clks(struct device
 				CLK_IS_ROOT);
 	clk_register_clkdev(clk, "sysclk", "ab8500-usb.0");
 	clk_register_clkdev(clk, "sysclk", "ab-iddet.0");
-	clk_register_clkdev(clk, "sysclk", "ab85xx-codec.0");
+	clk_register_clkdev(clk, "sysclk", "snd-soc-mop500.0");
 	clk_register_clkdev(clk, "sysclk", "shrm_bus");
 
 	/* ab8500_sysclk2 */
@@ -70,19 +70,19 @@ static int ab8500_reg_clks(struct device
 		AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ,
 		AB8500_SYSULPCLKCTRL1_ULPCLKREQ,
 		38400000, 9000, CLK_IS_ROOT);
-	clk_register_clkdev(clk, "ulpclk", "ab85xx-codec.0");
+	clk_register_clkdev(clk, "ulpclk", "snd-soc-mop500.0");
 
 	/* ab8500_intclk */
 	clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2,
 		intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0);
-	clk_register_clkdev(clk, "intclk", "ab85xx-codec.0");
+	clk_register_clkdev(clk, "intclk", "snd-soc-mop500.0");
 	clk_register_clkdev(clk, NULL, "ab8500-pwm.1");
 
 	/* ab8500_audioclk */
 	clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk",
 		AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA,
 		AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0);
-	clk_register_clkdev(clk, "audioclk", "ab85xx-codec.0");
+	clk_register_clkdev(clk, "audioclk", "ab8500-codec.0");
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/ux500/u8540_clk.c linux-libre-3.11-rc7-gnu/drivers/clk/ux500/u8540_clk.c
--- linux-libre-3.10-gnu/drivers/clk/ux500/u8540_clk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/ux500/u8540_clk.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,10 +12,568 @@
 #include <linux/clk-provider.h>
 #include <linux/mfd/dbx500-prcmu.h>
 #include <linux/platform_data/clk-ux500.h>
-
 #include "clk.h"
 
-void u8540_clk_init(void)
+void u8540_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
+		    u32 clkrst5_base, u32 clkrst6_base)
 {
-	/* register clocks here */
+	struct clk *clk;
+
+	/* Clock sources. */
+	/* Fixed ClockGen */
+	clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0,
+				CLK_IS_ROOT|CLK_IGNORE_UNUSED);
+	clk_register_clkdev(clk, "soc0_pll", NULL);
+
+	clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1,
+				CLK_IS_ROOT|CLK_IGNORE_UNUSED);
+	clk_register_clkdev(clk, "soc1_pll", NULL);
+
+	clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR,
+				CLK_IS_ROOT|CLK_IGNORE_UNUSED);
+	clk_register_clkdev(clk, "ddr_pll", NULL);
+
+	clk = clk_register_fixed_rate(NULL, "rtc32k", NULL,
+				CLK_IS_ROOT|CLK_IGNORE_UNUSED,
+				32768);
+	clk_register_clkdev(clk, "clk32k", NULL);
+	clk_register_clkdev(clk, "apb_pclk", "rtc-pl031");
+
+	clk = clk_register_fixed_rate(NULL, "ulp38m4", NULL,
+				CLK_IS_ROOT|CLK_IGNORE_UNUSED,
+				38400000);
+
+	clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "UART");
+
+	/* msp02clk needs a abx500 clk as parent. Handle by abx500 clk driver */
+	clk = clk_reg_prcmu_gate("msp02clk", "ab9540_sysclk12_b1",
+			PRCMU_MSP02CLK, 0);
+	clk_register_clkdev(clk, NULL, "MSP02");
+
+	clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "MSP1");
+
+	clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "I2C");
+
+	clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "slim");
+
+	clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "PERIPH1");
+
+	clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "PERIPH2");
+
+	clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "PERIPH3");
+
+	clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "PERIPH5");
+
+	clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "PERIPH6");
+
+	clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "PERIPH7");
+
+	clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0,
+				CLK_IS_ROOT|CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "lcd");
+	clk_register_clkdev(clk, "lcd", "mcde");
+
+	clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BML8580CLK,
+				CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "bml");
+
+	clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0,
+				CLK_IS_ROOT|CLK_SET_RATE_GATE);
+
+	clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0,
+				CLK_IS_ROOT|CLK_SET_RATE_GATE);
+
+	clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0,
+				CLK_IS_ROOT|CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "hdmi");
+	clk_register_clkdev(clk, "hdmi", "mcde");
+
+	clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "apeat");
+
+	clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK,
+				CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "apetrace");
+
+	clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "mcde");
+	clk_register_clkdev(clk, "mcde", "mcde");
+	clk_register_clkdev(clk, NULL, "dsilink.0");
+	clk_register_clkdev(clk, NULL, "dsilink.1");
+	clk_register_clkdev(clk, NULL, "dsilink.2");
+
+	clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK,
+				CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "ipi2");
+
+	clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK,
+				CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "dsialt");
+
+	clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "dma40.0");
+
+	clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "b2r2");
+	clk_register_clkdev(clk, NULL, "b2r2_core");
+	clk_register_clkdev(clk, NULL, "U8500-B2R2.0");
+	clk_register_clkdev(clk, NULL, "b2r2_1_core");
+
+	clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0,
+				CLK_IS_ROOT|CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "tv");
+	clk_register_clkdev(clk, "tv", "mcde");
+
+	clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "SSP");
+
+	clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "rngclk");
+
+	clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "uicc");
+
+	clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "mtu0");
+	clk_register_clkdev(clk, NULL, "mtu1");
+
+	clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL,
+					PRCMU_SDMMCCLK, 100000000,
+					CLK_IS_ROOT|CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "sdmmc");
+
+	clk = clk_reg_prcmu_opp_volt_scalable("sdmmchclk", NULL,
+					PRCMU_SDMMCHCLK, 400000000,
+					CLK_IS_ROOT|CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "sdmmchclk");
+
+	clk = clk_reg_prcmu_gate("hvaclk", NULL, PRCMU_HVACLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "hva");
+
+	clk = clk_reg_prcmu_gate("g1clk", NULL, PRCMU_G1CLK, CLK_IS_ROOT);
+	clk_register_clkdev(clk, NULL, "g1");
+
+	clk = clk_reg_prcmu_scalable("spare1clk", NULL, PRCMU_SPARE1CLK, 0,
+				CLK_IS_ROOT|CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "dsilcd", "mcde");
+
+	clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk",
+				PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "dsihs2", "mcde");
+	clk_register_clkdev(clk, "hs_clk", "dsilink.2");
+
+	clk = clk_reg_prcmu_scalable("dsilcd_pll", "spare1clk",
+				PRCMU_PLLDSI_LCD, 0, CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "dsilcd_pll", "mcde");
+
+	clk = clk_reg_prcmu_scalable("dsi0clk", "dsi_pll",
+				PRCMU_DSI0CLK, 0, CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "dsihs0", "mcde");
+
+	clk = clk_reg_prcmu_scalable("dsi0lcdclk", "dsilcd_pll",
+				PRCMU_DSI0CLK_LCD, 0, CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "dsihs0", "mcde");
+	clk_register_clkdev(clk, "hs_clk", "dsilink.0");
+
+	clk = clk_reg_prcmu_scalable("dsi1clk", "dsi_pll",
+				PRCMU_DSI1CLK, 0, CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "dsihs1", "mcde");
+
+	clk = clk_reg_prcmu_scalable("dsi1lcdclk", "dsilcd_pll",
+				PRCMU_DSI1CLK_LCD, 0, CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "dsihs1", "mcde");
+	clk_register_clkdev(clk, "hs_clk", "dsilink.1");
+
+	clk = clk_reg_prcmu_scalable("dsi0escclk", "tvclk",
+				PRCMU_DSI0ESCCLK, 0, CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "lp_clk", "dsilink.0");
+	clk_register_clkdev(clk, "dsilp0", "mcde");
+
+	clk = clk_reg_prcmu_scalable("dsi1escclk", "tvclk",
+				PRCMU_DSI1ESCCLK, 0, CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "lp_clk", "dsilink.1");
+	clk_register_clkdev(clk, "dsilp1", "mcde");
+
+	clk = clk_reg_prcmu_scalable("dsi2escclk", "tvclk",
+				PRCMU_DSI2ESCCLK, 0, CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, "lp_clk", "dsilink.2");
+	clk_register_clkdev(clk, "dsilp2", "mcde");
+
+	clk = clk_reg_prcmu_scalable_rate("armss", NULL,
+				PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED);
+	clk_register_clkdev(clk, "armss", NULL);
+
+	clk = clk_register_fixed_factor(NULL, "smp_twd", "armss",
+				CLK_IGNORE_UNUSED, 1, 2);
+	clk_register_clkdev(clk, NULL, "smp_twd");
+
+	/* PRCC P-clocks */
+	/* Peripheral 1 : PRCC P-clocks */
+	clk = clk_reg_prcc_pclk("p1_pclk0", "per1clk", clkrst1_base,
+				BIT(0), 0);
+	clk_register_clkdev(clk, "apb_pclk", "uart0");
+
+	clk = clk_reg_prcc_pclk("p1_pclk1", "per1clk", clkrst1_base,
+				BIT(1), 0);
+	clk_register_clkdev(clk, "apb_pclk", "uart1");
+
+	clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", clkrst1_base,
+				BIT(2), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1");
+
+	clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", clkrst1_base,
+				BIT(3), 0);
+	clk_register_clkdev(clk, "apb_pclk", "msp0");
+	clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.0");
+
+	clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", clkrst1_base,
+				BIT(4), 0);
+	clk_register_clkdev(clk, "apb_pclk", "msp1");
+	clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.1");
+
+	clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", clkrst1_base,
+				BIT(5), 0);
+	clk_register_clkdev(clk, "apb_pclk", "sdi0");
+
+	clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", clkrst1_base,
+				BIT(6), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2");
+
+	clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", clkrst1_base,
+				BIT(7), 0);
+	clk_register_clkdev(clk, NULL, "spi3");
+
+	clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", clkrst1_base,
+				BIT(8), 0);
+	clk_register_clkdev(clk, "apb_pclk", "slimbus0");
+
+	clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", clkrst1_base,
+				BIT(9), 0);
+	clk_register_clkdev(clk, NULL, "gpio.0");
+	clk_register_clkdev(clk, NULL, "gpio.1");
+	clk_register_clkdev(clk, NULL, "gpioblock0");
+	clk_register_clkdev(clk, "apb_pclk", "ab85xx-codec.0");
+
+	clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", clkrst1_base,
+				BIT(10), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4");
+
+	clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", clkrst1_base,
+				BIT(11), 0);
+	clk_register_clkdev(clk, "apb_pclk", "msp3");
+	clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.3");
+
+	/* Peripheral 2 : PRCC P-clocks */
+	clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", clkrst2_base,
+				BIT(0), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3");
+
+	clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", clkrst2_base,
+				BIT(1), 0);
+	clk_register_clkdev(clk, NULL, "spi2");
+
+	clk = clk_reg_prcc_pclk("p2_pclk2", "per2clk", clkrst2_base,
+				BIT(2), 0);
+	clk_register_clkdev(clk, NULL, "spi1");
+
+	clk = clk_reg_prcc_pclk("p2_pclk3", "per2clk", clkrst2_base,
+				BIT(3), 0);
+	clk_register_clkdev(clk, NULL, "pwl");
+
+	clk = clk_reg_prcc_pclk("p2_pclk4", "per2clk", clkrst2_base,
+				BIT(4), 0);
+	clk_register_clkdev(clk, "apb_pclk", "sdi4");
+
+	clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", clkrst2_base,
+				BIT(5), 0);
+	clk_register_clkdev(clk, "apb_pclk", "msp2");
+	clk_register_clkdev(clk, "apb_pclk", "dbx5x0-msp-i2s.2");
+
+	clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", clkrst2_base,
+				BIT(6), 0);
+	clk_register_clkdev(clk, "apb_pclk", "sdi1");
+
+	clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", clkrst2_base,
+				BIT(7), 0);
+	clk_register_clkdev(clk, "apb_pclk", "sdi3");
+
+	clk = clk_reg_prcc_pclk("p2_pclk8", "per2clk", clkrst2_base,
+				BIT(8), 0);
+	clk_register_clkdev(clk, NULL, "spi0");
+
+	clk = clk_reg_prcc_pclk("p2_pclk9", "per2clk", clkrst2_base,
+				BIT(9), 0);
+	clk_register_clkdev(clk, "hsir_hclk", "ste_hsi.0");
+
+	clk = clk_reg_prcc_pclk("p2_pclk10", "per2clk", clkrst2_base,
+				BIT(10), 0);
+	clk_register_clkdev(clk, "hsit_hclk", "ste_hsi.0");
+
+	clk = clk_reg_prcc_pclk("p2_pclk11", "per2clk", clkrst2_base,
+				BIT(11), 0);
+	clk_register_clkdev(clk, NULL, "gpio.6");
+	clk_register_clkdev(clk, NULL, "gpio.7");
+	clk_register_clkdev(clk, NULL, "gpioblock1");
+
+	clk = clk_reg_prcc_pclk("p2_pclk12", "per2clk", clkrst2_base,
+				BIT(12), 0);
+	clk_register_clkdev(clk, "msp4-pclk", "ab85xx-codec.0");
+
+	/* Peripheral 3 : PRCC P-clocks */
+	clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", clkrst3_base,
+				BIT(0), 0);
+	clk_register_clkdev(clk, NULL, "fsmc");
+
+	clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", clkrst3_base,
+				BIT(1), 0);
+	clk_register_clkdev(clk, "apb_pclk", "ssp0");
+
+	clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", clkrst3_base,
+				BIT(2), 0);
+	clk_register_clkdev(clk, "apb_pclk", "ssp1");
+
+	clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", clkrst3_base,
+				BIT(3), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0");
+
+	clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", clkrst3_base,
+				BIT(4), 0);
+	clk_register_clkdev(clk, "apb_pclk", "sdi2");
+
+	clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", clkrst3_base,
+				BIT(5), 0);
+	clk_register_clkdev(clk, "apb_pclk", "ske");
+	clk_register_clkdev(clk, "apb_pclk", "nmk-ske-keypad");
+
+	clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", clkrst3_base,
+				BIT(6), 0);
+	clk_register_clkdev(clk, "apb_pclk", "uart2");
+
+	clk = clk_reg_prcc_pclk("p3_pclk7", "per3clk", clkrst3_base,
+				BIT(7), 0);
+	clk_register_clkdev(clk, "apb_pclk", "sdi5");
+
+	clk = clk_reg_prcc_pclk("p3_pclk8", "per3clk", clkrst3_base,
+				BIT(8), 0);
+	clk_register_clkdev(clk, NULL, "gpio.2");
+	clk_register_clkdev(clk, NULL, "gpio.3");
+	clk_register_clkdev(clk, NULL, "gpio.4");
+	clk_register_clkdev(clk, NULL, "gpio.5");
+	clk_register_clkdev(clk, NULL, "gpioblock2");
+
+	clk = clk_reg_prcc_pclk("p3_pclk9", "per3clk", clkrst3_base,
+				BIT(9), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.5");
+
+	clk = clk_reg_prcc_pclk("p3_pclk10", "per3clk", clkrst3_base,
+				BIT(10), 0);
+	clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.6");
+
+	clk = clk_reg_prcc_pclk("p3_pclk11", "per3clk", clkrst3_base,
+				BIT(11), 0);
+	clk_register_clkdev(clk, "apb_pclk", "uart3");
+
+	clk = clk_reg_prcc_pclk("p3_pclk12", "per3clk", clkrst3_base,
+				BIT(12), 0);
+	clk_register_clkdev(clk, "apb_pclk", "uart4");
+
+	/* Peripheral 5 : PRCC P-clocks */
+	clk = clk_reg_prcc_pclk("p5_pclk0", "per5clk", clkrst5_base,
+				BIT(0), 0);
+	clk_register_clkdev(clk, "usb", "musb-ux500.0");
+	clk_register_clkdev(clk, "usbclk", "ab-iddet.0");
+
+	clk = clk_reg_prcc_pclk("p5_pclk1", "per5clk", clkrst5_base,
+				BIT(1), 0);
+	clk_register_clkdev(clk, NULL, "gpio.8");
+	clk_register_clkdev(clk, NULL, "gpioblock3");
+
+	/* Peripheral 6 : PRCC P-clocks */
+	clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", clkrst6_base,
+				BIT(0), 0);
+	clk_register_clkdev(clk, "apb_pclk", "rng");
+
+	clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", clkrst6_base,
+				BIT(1), 0);
+	clk_register_clkdev(clk, NULL, "cryp0");
+	clk_register_clkdev(clk, NULL, "cryp1");
+
+	clk = clk_reg_prcc_pclk("p6_pclk2", "per6clk", clkrst6_base,
+				BIT(2), 0);
+	clk_register_clkdev(clk, NULL, "hash0");
+
+	clk = clk_reg_prcc_pclk("p6_pclk3", "per6clk", clkrst6_base,
+				BIT(3), 0);
+	clk_register_clkdev(clk, NULL, "pka");
+
+	clk = clk_reg_prcc_pclk("p6_pclk4", "per6clk", clkrst6_base,
+				BIT(4), 0);
+	clk_register_clkdev(clk, NULL, "db8540-hash1");
+
+	clk = clk_reg_prcc_pclk("p6_pclk5", "per6clk", clkrst6_base,
+				BIT(5), 0);
+	clk_register_clkdev(clk, NULL, "cfgreg");
+
+	clk = clk_reg_prcc_pclk("p6_pclk6", "per6clk", clkrst6_base,
+				BIT(6), 0);
+	clk_register_clkdev(clk, "apb_pclk", "mtu0");
+
+	clk = clk_reg_prcc_pclk("p6_pclk7", "per6clk", clkrst6_base,
+				BIT(7), 0);
+	clk_register_clkdev(clk, "apb_pclk", "mtu1");
+
+	/*
+	 * PRCC K-clocks  ==> see table PRCC_PCKEN/PRCC_KCKEN
+	 * This differs from the internal implementation:
+	 * We don't use the PERPIH[n| clock as parent, since those _should_
+	 * only be used as parents for the P-clocks.
+	 * TODO: "parentjoin" with corresponding P-clocks for all K-clocks.
+	 */
+
+	/* Peripheral 1 : PRCC K-clocks */
+	clk = clk_reg_prcc_kclk("p1_uart0_kclk", "uartclk",
+			clkrst1_base, BIT(0), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "uart0");
+
+	clk = clk_reg_prcc_kclk("p1_uart1_kclk", "uartclk",
+			clkrst1_base, BIT(1), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "uart1");
+
+	clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk",
+			clkrst1_base, BIT(2), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.1");
+
+	clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk",
+			clkrst1_base, BIT(3), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "msp0");
+	clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.0");
+
+	clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk",
+			clkrst1_base, BIT(4), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "msp1");
+	clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.1");
+
+	clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmchclk",
+			clkrst1_base, BIT(5), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "sdi0");
+
+	clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk",
+			clkrst1_base, BIT(6), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.2");
+
+	clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk",
+			clkrst1_base, BIT(8), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "slimbus0");
+
+	clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk",
+			clkrst1_base, BIT(9), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.4");
+
+	clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk",
+			clkrst1_base, BIT(10), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "msp3");
+	clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.3");
+
+	/* Peripheral 2 : PRCC K-clocks */
+	clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk",
+			clkrst2_base, BIT(0), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.3");
+
+	clk = clk_reg_prcc_kclk("p2_pwl_kclk", "rtc32k",
+			clkrst2_base, BIT(1), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "pwl");
+
+	clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmchclk",
+			clkrst2_base, BIT(2), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "sdi4");
+
+	clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk",
+			clkrst2_base, BIT(3), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "msp2");
+	clk_register_clkdev(clk, NULL, "dbx5x0-msp-i2s.2");
+
+	clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmchclk",
+			clkrst2_base, BIT(4), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "sdi1");
+
+	clk = clk_reg_prcc_kclk("p2_sdi3_kclk", "sdmmcclk",
+			clkrst2_base, BIT(5), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "sdi3");
+
+	clk = clk_reg_prcc_kclk("p2_ssirx_kclk", "hsirxclk",
+			clkrst2_base, BIT(6),
+			CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT);
+	clk_register_clkdev(clk, "hsir_hsirxclk", "ste_hsi.0");
+
+	clk = clk_reg_prcc_kclk("p2_ssitx_kclk", "hsitxclk",
+			clkrst2_base, BIT(7),
+			CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT);
+	clk_register_clkdev(clk, "hsit_hsitxclk", "ste_hsi.0");
+
+	/* Should only be 9540, but might be added for 85xx as well */
+	clk = clk_reg_prcc_kclk("p2_msp4_kclk", "msp02clk",
+			clkrst2_base, BIT(9), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "msp4");
+	clk_register_clkdev(clk, "msp4", "ab85xx-codec.0");
+
+	/* Peripheral 3 : PRCC K-clocks */
+	clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk",
+			clkrst3_base, BIT(1), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "ssp0");
+
+	clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk",
+			clkrst3_base, BIT(2), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "ssp1");
+
+	clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk",
+			clkrst3_base, BIT(3), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.0");
+
+	clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmchclk",
+			clkrst3_base, BIT(4), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "sdi2");
+
+	clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k",
+			clkrst3_base, BIT(5), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "ske");
+	clk_register_clkdev(clk, NULL, "nmk-ske-keypad");
+
+	clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk",
+			clkrst3_base, BIT(6), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "uart2");
+
+	clk = clk_reg_prcc_kclk("p3_sdi5_kclk", "sdmmcclk",
+			clkrst3_base, BIT(7), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "sdi5");
+
+	clk = clk_reg_prcc_kclk("p3_i2c5_kclk", "i2cclk",
+			clkrst3_base, BIT(8), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.5");
+
+	clk = clk_reg_prcc_kclk("p3_i2c6_kclk", "i2cclk",
+			clkrst3_base, BIT(9), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "nmk-i2c.6");
+
+	clk = clk_reg_prcc_kclk("p3_uart3_kclk", "uartclk",
+			clkrst3_base, BIT(10), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "uart3");
+
+	clk = clk_reg_prcc_kclk("p3_uart4_kclk", "uartclk",
+			clkrst3_base, BIT(11), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "uart4");
+
+	/* Peripheral 6 : PRCC K-clocks */
+	clk = clk_reg_prcc_kclk("p6_rng_kclk", "rngclk",
+			clkrst6_base, BIT(0), CLK_SET_RATE_GATE);
+	clk_register_clkdev(clk, NULL, "rng");
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/ux500/u9540_clk.c linux-libre-3.11-rc7-gnu/drivers/clk/ux500/u9540_clk.c
--- linux-libre-3.10-gnu/drivers/clk/ux500/u9540_clk.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/ux500/u9540_clk.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,10 +12,10 @@
 #include <linux/clk-provider.h>
 #include <linux/mfd/dbx500-prcmu.h>
 #include <linux/platform_data/clk-ux500.h>
-
 #include "clk.h"
 
-void u9540_clk_init(void)
+void u9540_clk_init(u32 clkrst1_base, u32 clkrst2_base, u32 clkrst3_base,
+		    u32 clkrst5_base, u32 clkrst6_base)
 {
 	/* register clocks here */
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/versatile/clk-vexpress-osc.c linux-libre-3.11-rc7-gnu/drivers/clk/versatile/clk-vexpress-osc.c
--- linux-libre-3.10-gnu/drivers/clk/versatile/clk-vexpress-osc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/versatile/clk-vexpress-osc.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,7 +107,7 @@ void __init vexpress_osc_of_setup(struct
 	osc->func = vexpress_config_func_get_by_node(node);
 	if (!osc->func) {
 		pr_err("Failed to obtain config func for node '%s'!\n",
-				node->name);
+				node->full_name);
 		goto error;
 	}
 
@@ -119,7 +119,7 @@ void __init vexpress_osc_of_setup(struct
 
 	of_property_read_string(node, "clock-output-names", &init.name);
 	if (!init.name)
-		init.name = node->name;
+		init.name = node->full_name;
 
 	init.ops = &vexpress_osc_ops;
 	init.flags = CLK_IS_ROOT;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/x86/clk-lpt.c linux-libre-3.11-rc7-gnu/drivers/clk/x86/clk-lpt.c
--- linux-libre-3.10-gnu/drivers/clk/x86/clk-lpt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clk/x86/clk-lpt.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Intel Lynxpoint LPSS clocks.
+ * Intel Low Power Subsystem clocks.
  *
  * Copyright (C) 2013, Intel Corporation
  * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
@@ -18,8 +18,6 @@
 #include <linux/platform_data/clk-lpss.h>
 #include <linux/platform_device.h>
 
-#define PRV_CLOCK_PARAMS 0x800
-
 static int lpt_clk_probe(struct platform_device *pdev)
 {
 	struct lpss_clk_data *drvdata;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/zynq/clkc.c linux-libre-3.11-rc7-gnu/drivers/clk/zynq/clkc.c
--- linux-libre-3.10-gnu/drivers/clk/zynq/clkc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/zynq/clkc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,536 @@
+/*
+ * Zynq clock controller
+ *
+ *  Copyright (C) 2012 - 2013 Xilinx
+ *
+ *  Sören Brinkmann <soren.brinkmann@xilinx.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk/zynq.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/io.h>
+
+static void __iomem *zynq_slcr_base_priv;
+
+#define SLCR_ARMPLL_CTRL		(zynq_slcr_base_priv + 0x100)
+#define SLCR_DDRPLL_CTRL		(zynq_slcr_base_priv + 0x104)
+#define SLCR_IOPLL_CTRL			(zynq_slcr_base_priv + 0x108)
+#define SLCR_PLL_STATUS			(zynq_slcr_base_priv + 0x10c)
+#define SLCR_ARM_CLK_CTRL		(zynq_slcr_base_priv + 0x120)
+#define SLCR_DDR_CLK_CTRL		(zynq_slcr_base_priv + 0x124)
+#define SLCR_DCI_CLK_CTRL		(zynq_slcr_base_priv + 0x128)
+#define SLCR_APER_CLK_CTRL		(zynq_slcr_base_priv + 0x12c)
+#define SLCR_GEM0_CLK_CTRL		(zynq_slcr_base_priv + 0x140)
+#define SLCR_GEM1_CLK_CTRL		(zynq_slcr_base_priv + 0x144)
+#define SLCR_SMC_CLK_CTRL		(zynq_slcr_base_priv + 0x148)
+#define SLCR_LQSPI_CLK_CTRL		(zynq_slcr_base_priv + 0x14c)
+#define SLCR_SDIO_CLK_CTRL		(zynq_slcr_base_priv + 0x150)
+#define SLCR_UART_CLK_CTRL		(zynq_slcr_base_priv + 0x154)
+#define SLCR_SPI_CLK_CTRL		(zynq_slcr_base_priv + 0x158)
+#define SLCR_CAN_CLK_CTRL		(zynq_slcr_base_priv + 0x15c)
+#define SLCR_CAN_MIOCLK_CTRL		(zynq_slcr_base_priv + 0x160)
+#define SLCR_DBG_CLK_CTRL		(zynq_slcr_base_priv + 0x164)
+#define SLCR_PCAP_CLK_CTRL		(zynq_slcr_base_priv + 0x168)
+#define SLCR_FPGA0_CLK_CTRL		(zynq_slcr_base_priv + 0x170)
+#define SLCR_621_TRUE			(zynq_slcr_base_priv + 0x1c4)
+#define SLCR_SWDT_CLK_SEL		(zynq_slcr_base_priv + 0x304)
+
+#define NUM_MIO_PINS	54
+
+enum zynq_clk {
+	armpll, ddrpll, iopll,
+	cpu_6or4x, cpu_3or2x, cpu_2x, cpu_1x,
+	ddr2x, ddr3x, dci,
+	lqspi, smc, pcap, gem0, gem1, fclk0, fclk1, fclk2, fclk3, can0, can1,
+	sdio0, sdio1, uart0, uart1, spi0, spi1, dma,
+	usb0_aper, usb1_aper, gem0_aper, gem1_aper,
+	sdio0_aper, sdio1_aper, spi0_aper, spi1_aper, can0_aper, can1_aper,
+	i2c0_aper, i2c1_aper, uart0_aper, uart1_aper, gpio_aper, lqspi_aper,
+	smc_aper, swdt, dbg_trc, dbg_apb, clk_max};
+
+static struct clk *ps_clk;
+static struct clk *clks[clk_max];
+static struct clk_onecell_data clk_data;
+
+static DEFINE_SPINLOCK(armpll_lock);
+static DEFINE_SPINLOCK(ddrpll_lock);
+static DEFINE_SPINLOCK(iopll_lock);
+static DEFINE_SPINLOCK(armclk_lock);
+static DEFINE_SPINLOCK(swdtclk_lock);
+static DEFINE_SPINLOCK(ddrclk_lock);
+static DEFINE_SPINLOCK(dciclk_lock);
+static DEFINE_SPINLOCK(gem0clk_lock);
+static DEFINE_SPINLOCK(gem1clk_lock);
+static DEFINE_SPINLOCK(canclk_lock);
+static DEFINE_SPINLOCK(canmioclk_lock);
+static DEFINE_SPINLOCK(dbgclk_lock);
+static DEFINE_SPINLOCK(aperclk_lock);
+
+static const char dummy_nm[] __initconst = "dummy_name";
+
+static const char *armpll_parents[] __initdata = {"armpll_int", "ps_clk"};
+static const char *ddrpll_parents[] __initdata = {"ddrpll_int", "ps_clk"};
+static const char *iopll_parents[] __initdata = {"iopll_int", "ps_clk"};
+static const char *gem0_mux_parents[] __initdata = {"gem0_div1", dummy_nm};
+static const char *gem1_mux_parents[] __initdata = {"gem1_div1", dummy_nm};
+static const char *can0_mio_mux2_parents[] __initdata = {"can0_gate",
+	"can0_mio_mux"};
+static const char *can1_mio_mux2_parents[] __initdata = {"can1_gate",
+	"can1_mio_mux"};
+static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div",
+	dummy_nm};
+
+static const char *dbgtrc_emio_input_names[] __initdata = {"trace_emio_clk"};
+static const char *gem0_emio_input_names[] __initdata = {"gem0_emio_clk"};
+static const char *gem1_emio_input_names[] __initdata = {"gem1_emio_clk"};
+static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"};
+
+static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
+		const char *clk_name, void __iomem *fclk_ctrl_reg,
+		const char **parents)
+{
+	struct clk *clk;
+	char *mux_name;
+	char *div0_name;
+	char *div1_name;
+	spinlock_t *fclk_lock;
+	spinlock_t *fclk_gate_lock;
+	void __iomem *fclk_gate_reg = fclk_ctrl_reg + 8;
+
+	fclk_lock = kmalloc(sizeof(*fclk_lock), GFP_KERNEL);
+	if (!fclk_lock)
+		goto err;
+	fclk_gate_lock = kmalloc(sizeof(*fclk_gate_lock), GFP_KERNEL);
+	if (!fclk_gate_lock)
+		goto err;
+	spin_lock_init(fclk_lock);
+	spin_lock_init(fclk_gate_lock);
+
+	mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name);
+	div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name);
+	div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name);
+
+	clk = clk_register_mux(NULL, mux_name, parents, 4, 0,
+			fclk_ctrl_reg, 4, 2, 0, fclk_lock);
+
+	clk = clk_register_divider(NULL, div0_name, mux_name,
+			0, fclk_ctrl_reg, 8, 6, CLK_DIVIDER_ONE_BASED |
+			CLK_DIVIDER_ALLOW_ZERO, fclk_lock);
+
+	clk = clk_register_divider(NULL, div1_name, div0_name,
+			CLK_SET_RATE_PARENT, fclk_ctrl_reg, 20, 6,
+			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+			fclk_lock);
+
+	clks[fclk] = clk_register_gate(NULL, clk_name,
+			div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg,
+			0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock);
+	kfree(mux_name);
+	kfree(div0_name);
+	kfree(div1_name);
+
+	return;
+
+err:
+	clks[fclk] = ERR_PTR(-ENOMEM);
+}
+
+static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0,
+		enum zynq_clk clk1, const char *clk_name0,
+		const char *clk_name1, void __iomem *clk_ctrl,
+		const char **parents, unsigned int two_gates)
+{
+	struct clk *clk;
+	char *mux_name;
+	char *div_name;
+	spinlock_t *lock;
+
+	lock = kmalloc(sizeof(*lock), GFP_KERNEL);
+	if (!lock)
+		goto err;
+	spin_lock_init(lock);
+
+	mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0);
+	div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0);
+
+	clk = clk_register_mux(NULL, mux_name, parents, 4, 0,
+			clk_ctrl, 4, 2, 0, lock);
+
+	clk = clk_register_divider(NULL, div_name, mux_name, 0, clk_ctrl, 8, 6,
+			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, lock);
+
+	clks[clk0] = clk_register_gate(NULL, clk_name0, div_name,
+			CLK_SET_RATE_PARENT, clk_ctrl, 0, 0, lock);
+	if (two_gates)
+		clks[clk1] = clk_register_gate(NULL, clk_name1, div_name,
+				CLK_SET_RATE_PARENT, clk_ctrl, 1, 0, lock);
+
+	kfree(mux_name);
+	kfree(div_name);
+
+	return;
+
+err:
+	clks[clk0] = ERR_PTR(-ENOMEM);
+	if (two_gates)
+		clks[clk1] = ERR_PTR(-ENOMEM);
+}
+
+static void __init zynq_clk_setup(struct device_node *np)
+{
+	int i;
+	u32 tmp;
+	int ret;
+	struct clk *clk;
+	char *clk_name;
+	const char *clk_output_name[clk_max];
+	const char *cpu_parents[4];
+	const char *periph_parents[4];
+	const char *swdt_ext_clk_mux_parents[2];
+	const char *can_mio_mux_parents[NUM_MIO_PINS];
+
+	pr_info("Zynq clock init\n");
+
+	/* get clock output names from DT */
+	for (i = 0; i < clk_max; i++) {
+		if (of_property_read_string_index(np, "clock-output-names",
+				  i, &clk_output_name[i])) {
+			pr_err("%s: clock output name not in DT\n", __func__);
+			BUG();
+		}
+	}
+	cpu_parents[0] = clk_output_name[armpll];
+	cpu_parents[1] = clk_output_name[armpll];
+	cpu_parents[2] = clk_output_name[ddrpll];
+	cpu_parents[3] = clk_output_name[iopll];
+	periph_parents[0] = clk_output_name[iopll];
+	periph_parents[1] = clk_output_name[iopll];
+	periph_parents[2] = clk_output_name[armpll];
+	periph_parents[3] = clk_output_name[ddrpll];
+
+	/* ps_clk */
+	ret = of_property_read_u32(np, "ps-clk-frequency", &tmp);
+	if (ret) {
+		pr_warn("ps_clk frequency not specified, using 33 MHz.\n");
+		tmp = 33333333;
+	}
+	ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, CLK_IS_ROOT,
+			tmp);
+
+	/* PLLs */
+	clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL,
+			SLCR_PLL_STATUS, 0, &armpll_lock);
+	clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll],
+			armpll_parents, 2, 0, SLCR_ARMPLL_CTRL, 4, 1, 0,
+			&armpll_lock);
+
+	clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL,
+			SLCR_PLL_STATUS, 1, &ddrpll_lock);
+	clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll],
+			ddrpll_parents, 2, 0, SLCR_DDRPLL_CTRL, 4, 1, 0,
+			&ddrpll_lock);
+
+	clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL,
+			SLCR_PLL_STATUS, 2, &iopll_lock);
+	clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll],
+			iopll_parents, 2, 0, SLCR_IOPLL_CTRL, 4, 1, 0,
+			&iopll_lock);
+
+	/* CPU clocks */
+	tmp = readl(SLCR_621_TRUE) & 1;
+	clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 0,
+			SLCR_ARM_CLK_CTRL, 4, 2, 0, &armclk_lock);
+	clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0,
+			SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
+			CLK_DIVIDER_ALLOW_ZERO, &armclk_lock);
+
+	clks[cpu_6or4x] = clk_register_gate(NULL, clk_output_name[cpu_6or4x],
+			"cpu_div", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			SLCR_ARM_CLK_CTRL, 24, 0, &armclk_lock);
+
+	clk = clk_register_fixed_factor(NULL, "cpu_3or2x_div", "cpu_div", 0,
+			1, 2);
+	clks[cpu_3or2x] = clk_register_gate(NULL, clk_output_name[cpu_3or2x],
+			"cpu_3or2x_div", CLK_IGNORE_UNUSED,
+			SLCR_ARM_CLK_CTRL, 25, 0, &armclk_lock);
+
+	clk = clk_register_fixed_factor(NULL, "cpu_2x_div", "cpu_div", 0, 1,
+			2 + tmp);
+	clks[cpu_2x] = clk_register_gate(NULL, clk_output_name[cpu_2x],
+			"cpu_2x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL,
+			26, 0, &armclk_lock);
+
+	clk = clk_register_fixed_factor(NULL, "cpu_1x_div", "cpu_div", 0, 1,
+			4 + 2 * tmp);
+	clks[cpu_1x] = clk_register_gate(NULL, clk_output_name[cpu_1x],
+			"cpu_1x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, 27,
+			0, &armclk_lock);
+
+	/* Timers */
+	swdt_ext_clk_mux_parents[0] = clk_output_name[cpu_1x];
+	for (i = 0; i < ARRAY_SIZE(swdt_ext_clk_input_names); i++) {
+		int idx = of_property_match_string(np, "clock-names",
+				swdt_ext_clk_input_names[i]);
+		if (idx >= 0)
+			swdt_ext_clk_mux_parents[i + 1] =
+				of_clk_get_parent_name(np, idx);
+		else
+			swdt_ext_clk_mux_parents[i + 1] = dummy_nm;
+	}
+	clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt],
+			swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT,
+			SLCR_SWDT_CLK_SEL, 0, 1, 0, &swdtclk_lock);
+
+	/* DDR clocks */
+	clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0,
+			SLCR_DDR_CLK_CTRL, 26, 6, CLK_DIVIDER_ONE_BASED |
+			CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock);
+	clks[ddr2x] = clk_register_gate(NULL, clk_output_name[ddr2x],
+			"ddr2x_div", 0, SLCR_DDR_CLK_CTRL, 1, 0, &ddrclk_lock);
+	clk_prepare_enable(clks[ddr2x]);
+	clk = clk_register_divider(NULL, "ddr3x_div", "ddrpll", 0,
+			SLCR_DDR_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED |
+			CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock);
+	clks[ddr3x] = clk_register_gate(NULL, clk_output_name[ddr3x],
+			"ddr3x_div", 0, SLCR_DDR_CLK_CTRL, 0, 0, &ddrclk_lock);
+	clk_prepare_enable(clks[ddr3x]);
+
+	clk = clk_register_divider(NULL, "dci_div0", "ddrpll", 0,
+			SLCR_DCI_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
+			CLK_DIVIDER_ALLOW_ZERO, &dciclk_lock);
+	clk = clk_register_divider(NULL, "dci_div1", "dci_div0",
+			CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 20, 6,
+			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+			&dciclk_lock);
+	clks[dci] = clk_register_gate(NULL, clk_output_name[dci], "dci_div1",
+			CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 0, 0,
+			&dciclk_lock);
+	clk_prepare_enable(clks[dci]);
+
+	/* Peripheral clocks */
+	for (i = fclk0; i <= fclk3; i++)
+		zynq_clk_register_fclk(i, clk_output_name[i],
+				SLCR_FPGA0_CLK_CTRL + 0x10 * (i - fclk0),
+				periph_parents);
+
+	zynq_clk_register_periph_clk(lqspi, 0, clk_output_name[lqspi], NULL,
+			SLCR_LQSPI_CLK_CTRL, periph_parents, 0);
+
+	zynq_clk_register_periph_clk(smc, 0, clk_output_name[smc], NULL,
+			SLCR_SMC_CLK_CTRL, periph_parents, 0);
+
+	zynq_clk_register_periph_clk(pcap, 0, clk_output_name[pcap], NULL,
+			SLCR_PCAP_CLK_CTRL, periph_parents, 0);
+
+	zynq_clk_register_periph_clk(sdio0, sdio1, clk_output_name[sdio0],
+			clk_output_name[sdio1], SLCR_SDIO_CLK_CTRL,
+			periph_parents, 1);
+
+	zynq_clk_register_periph_clk(uart0, uart1, clk_output_name[uart0],
+			clk_output_name[uart1], SLCR_UART_CLK_CTRL,
+			periph_parents, 1);
+
+	zynq_clk_register_periph_clk(spi0, spi1, clk_output_name[spi0],
+			clk_output_name[spi1], SLCR_SPI_CLK_CTRL,
+			periph_parents, 1);
+
+	for (i = 0; i < ARRAY_SIZE(gem0_emio_input_names); i++) {
+		int idx = of_property_match_string(np, "clock-names",
+				gem0_emio_input_names[i]);
+		if (idx >= 0)
+			gem0_mux_parents[i + 1] = of_clk_get_parent_name(np,
+					idx);
+	}
+	clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, 0,
+			SLCR_GEM0_CLK_CTRL, 4, 2, 0, &gem0clk_lock);
+	clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0,
+			SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
+			CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock);
+	clk = clk_register_divider(NULL, "gem0_div1", "gem0_div0",
+			CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6,
+			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+			&gem0clk_lock);
+	clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2,
+			CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 6, 1, 0,
+			&gem0clk_lock);
+	clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0],
+			"gem0_emio_mux", CLK_SET_RATE_PARENT,
+			SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock);
+
+	for (i = 0; i < ARRAY_SIZE(gem1_emio_input_names); i++) {
+		int idx = of_property_match_string(np, "clock-names",
+				gem1_emio_input_names[i]);
+		if (idx >= 0)
+			gem1_mux_parents[i + 1] = of_clk_get_parent_name(np,
+					idx);
+	}
+	clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, 0,
+			SLCR_GEM1_CLK_CTRL, 4, 2, 0, &gem1clk_lock);
+	clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0,
+			SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
+			CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock);
+	clk = clk_register_divider(NULL, "gem1_div1", "gem1_div0",
+			CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6,
+			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+			&gem1clk_lock);
+	clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2,
+			CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 6, 1, 0,
+			&gem1clk_lock);
+	clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1],
+			"gem1_emio_mux", CLK_SET_RATE_PARENT,
+			SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock);
+
+	tmp = strlen("mio_clk_00x");
+	clk_name = kmalloc(tmp, GFP_KERNEL);
+	for (i = 0; i < NUM_MIO_PINS; i++) {
+		int idx;
+
+		snprintf(clk_name, tmp, "mio_clk_%2.2d", i);
+		idx = of_property_match_string(np, "clock-names", clk_name);
+		if (idx >= 0)
+			can_mio_mux_parents[i] = of_clk_get_parent_name(np,
+						idx);
+		else
+			can_mio_mux_parents[i] = dummy_nm;
+	}
+	kfree(clk_name);
+	clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, 0,
+			SLCR_CAN_CLK_CTRL, 4, 2, 0, &canclk_lock);
+	clk = clk_register_divider(NULL, "can_div0", "can_mux", 0,
+			SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
+			CLK_DIVIDER_ALLOW_ZERO, &canclk_lock);
+	clk = clk_register_divider(NULL, "can_div1", "can_div0",
+			CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 20, 6,
+			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+			&canclk_lock);
+	clk = clk_register_gate(NULL, "can0_gate", "can_div1",
+			CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 0, 0,
+			&canclk_lock);
+	clk = clk_register_gate(NULL, "can1_gate", "can_div1",
+			CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0,
+			&canclk_lock);
+	clk = clk_register_mux(NULL, "can0_mio_mux",
+			can_mio_mux_parents, 54, CLK_SET_RATE_PARENT,
+			SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, &canmioclk_lock);
+	clk = clk_register_mux(NULL, "can1_mio_mux",
+			can_mio_mux_parents, 54, CLK_SET_RATE_PARENT,
+			SLCR_CAN_MIOCLK_CTRL, 16, 6, 0, &canmioclk_lock);
+	clks[can0] = clk_register_mux(NULL, clk_output_name[can0],
+			can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT,
+			SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, &canmioclk_lock);
+	clks[can1] = clk_register_mux(NULL, clk_output_name[can1],
+			can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT,
+			SLCR_CAN_MIOCLK_CTRL, 22, 1, 0, &canmioclk_lock);
+
+	for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) {
+		int idx = of_property_match_string(np, "clock-names",
+				dbgtrc_emio_input_names[i]);
+		if (idx >= 0)
+			dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np,
+					idx);
+	}
+	clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, 0,
+			SLCR_DBG_CLK_CTRL, 4, 2, 0, &dbgclk_lock);
+	clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0,
+			SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
+			CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock);
+	clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, 0,
+			SLCR_DBG_CLK_CTRL, 6, 1, 0, &dbgclk_lock);
+	clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc],
+			"dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL,
+			0, 0, &dbgclk_lock);
+	clks[dbg_apb] = clk_register_gate(NULL, clk_output_name[dbg_apb],
+			clk_output_name[cpu_1x], 0, SLCR_DBG_CLK_CTRL, 1, 0,
+			&dbgclk_lock);
+
+	/* One gated clock for all APER clocks. */
+	clks[dma] = clk_register_gate(NULL, clk_output_name[dma],
+			clk_output_name[cpu_2x], 0, SLCR_APER_CLK_CTRL, 0, 0,
+			&aperclk_lock);
+	clks[usb0_aper] = clk_register_gate(NULL, clk_output_name[usb0_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 2, 0,
+			&aperclk_lock);
+	clks[usb1_aper] = clk_register_gate(NULL, clk_output_name[usb1_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 3, 0,
+			&aperclk_lock);
+	clks[gem0_aper] = clk_register_gate(NULL, clk_output_name[gem0_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 6, 0,
+			&aperclk_lock);
+	clks[gem1_aper] = clk_register_gate(NULL, clk_output_name[gem1_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 7, 0,
+			&aperclk_lock);
+	clks[sdio0_aper] = clk_register_gate(NULL, clk_output_name[sdio0_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 10, 0,
+			&aperclk_lock);
+	clks[sdio1_aper] = clk_register_gate(NULL, clk_output_name[sdio1_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 11, 0,
+			&aperclk_lock);
+	clks[spi0_aper] = clk_register_gate(NULL, clk_output_name[spi0_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 14, 0,
+			&aperclk_lock);
+	clks[spi1_aper] = clk_register_gate(NULL, clk_output_name[spi1_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 15, 0,
+			&aperclk_lock);
+	clks[can0_aper] = clk_register_gate(NULL, clk_output_name[can0_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 16, 0,
+			&aperclk_lock);
+	clks[can1_aper] = clk_register_gate(NULL, clk_output_name[can1_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 17, 0,
+			&aperclk_lock);
+	clks[i2c0_aper] = clk_register_gate(NULL, clk_output_name[i2c0_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 18, 0,
+			&aperclk_lock);
+	clks[i2c1_aper] = clk_register_gate(NULL, clk_output_name[i2c1_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 19, 0,
+			&aperclk_lock);
+	clks[uart0_aper] = clk_register_gate(NULL, clk_output_name[uart0_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 20, 0,
+			&aperclk_lock);
+	clks[uart1_aper] = clk_register_gate(NULL, clk_output_name[uart1_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 21, 0,
+			&aperclk_lock);
+	clks[gpio_aper] = clk_register_gate(NULL, clk_output_name[gpio_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 22, 0,
+			&aperclk_lock);
+	clks[lqspi_aper] = clk_register_gate(NULL, clk_output_name[lqspi_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 23, 0,
+			&aperclk_lock);
+	clks[smc_aper] = clk_register_gate(NULL, clk_output_name[smc_aper],
+			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 24, 0,
+			&aperclk_lock);
+
+	for (i = 0; i < ARRAY_SIZE(clks); i++) {
+		if (IS_ERR(clks[i])) {
+			pr_err("Zynq clk %d: register failed with %ld\n",
+			       i, PTR_ERR(clks[i]));
+			BUG();
+		}
+	}
+
+	clk_data.clks = clks;
+	clk_data.clk_num = ARRAY_SIZE(clks);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+CLK_OF_DECLARE(zynq_clkc, "xlnx,ps7-clkc", zynq_clk_setup);
+
+void __init zynq_clock_init(void __iomem *slcr_base)
+{
+	zynq_slcr_base_priv = slcr_base;
+	of_clk_init(NULL);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/zynq/Makefile linux-libre-3.11-rc7-gnu/drivers/clk/zynq/Makefile
--- linux-libre-3.10-gnu/drivers/clk/zynq/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/zynq/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3 @@
+# Zynq clock specific Makefile
+
+obj-$(CONFIG_ARCH_ZYNQ)	+= clkc.o pll.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clk/zynq/pll.c linux-libre-3.11-rc7-gnu/drivers/clk/zynq/pll.c
--- linux-libre-3.10-gnu/drivers/clk/zynq/pll.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clk/zynq/pll.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,235 @@
+/*
+ * Zynq PLL driver
+ *
+ *  Copyright (C) 2013 Xilinx
+ *
+ *  Sören Brinkmann <soren.brinkmann@xilinx.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <linux/clk/zynq.h>
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+/**
+ * struct zynq_pll
+ * @hw:		Handle between common and hardware-specific interfaces
+ * @pll_ctrl:	PLL control register
+ * @pll_status:	PLL status register
+ * @lock:	Register lock
+ * @lockbit:	Indicates the associated PLL_LOCKED bit in the PLL status
+ *		register.
+ */
+struct zynq_pll {
+	struct clk_hw	hw;
+	void __iomem	*pll_ctrl;
+	void __iomem	*pll_status;
+	spinlock_t	*lock;
+	u8		lockbit;
+};
+#define to_zynq_pll(_hw)	container_of(_hw, struct zynq_pll, hw)
+
+/* Register bitfield defines */
+#define PLLCTRL_FBDIV_MASK	0x7f000
+#define PLLCTRL_FBDIV_SHIFT	12
+#define PLLCTRL_BPQUAL_MASK	(1 << 3)
+#define PLLCTRL_PWRDWN_MASK	2
+#define PLLCTRL_PWRDWN_SHIFT	1
+#define PLLCTRL_RESET_MASK	1
+#define PLLCTRL_RESET_SHIFT	0
+
+/**
+ * zynq_pll_round_rate() - Round a clock frequency
+ * @hw:		Handle between common and hardware-specific interfaces
+ * @rate:	Desired clock frequency
+ * @prate:	Clock frequency of parent clock
+ * Returns frequency closest to @rate the hardware can generate.
+ */
+static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long *prate)
+{
+	u32 fbdiv;
+
+	fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
+	if (fbdiv < 13)
+		fbdiv = 13;
+	else if (fbdiv > 66)
+		fbdiv = 66;
+
+	return *prate * fbdiv;
+}
+
+/**
+ * zynq_pll_recalc_rate() - Recalculate clock frequency
+ * @hw:			Handle between common and hardware-specific interfaces
+ * @parent_rate:	Clock frequency of parent clock
+ * Returns current clock frequency.
+ */
+static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct zynq_pll *clk = to_zynq_pll(hw);
+	u32 fbdiv;
+
+	/*
+	 * makes probably sense to redundantly save fbdiv in the struct
+	 * zynq_pll to save the IO access.
+	 */
+	fbdiv = (readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >>
+			PLLCTRL_FBDIV_SHIFT;
+
+	return parent_rate * fbdiv;
+}
+
+/**
+ * zynq_pll_is_enabled - Check if a clock is enabled
+ * @hw:		Handle between common and hardware-specific interfaces
+ * Returns 1 if the clock is enabled, 0 otherwise.
+ *
+ * Not sure this is a good idea, but since disabled means bypassed for
+ * this clock implementation we say we are always enabled.
+ */
+static int zynq_pll_is_enabled(struct clk_hw *hw)
+{
+	unsigned long flags = 0;
+	u32 reg;
+	struct zynq_pll *clk = to_zynq_pll(hw);
+
+	spin_lock_irqsave(clk->lock, flags);
+
+	reg = readl(clk->pll_ctrl);
+
+	spin_unlock_irqrestore(clk->lock, flags);
+
+	return !(reg & (PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK));
+}
+
+/**
+ * zynq_pll_enable - Enable clock
+ * @hw:		Handle between common and hardware-specific interfaces
+ * Returns 0 on success
+ */
+static int zynq_pll_enable(struct clk_hw *hw)
+{
+	unsigned long flags = 0;
+	u32 reg;
+	struct zynq_pll *clk = to_zynq_pll(hw);
+
+	if (zynq_pll_is_enabled(hw))
+		return 0;
+
+	pr_info("PLL: enable\n");
+
+	/* Power up PLL and wait for lock */
+	spin_lock_irqsave(clk->lock, flags);
+
+	reg = readl(clk->pll_ctrl);
+	reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
+	writel(reg, clk->pll_ctrl);
+	while (!(readl(clk->pll_status) & (1 << clk->lockbit)))
+		;
+
+	spin_unlock_irqrestore(clk->lock, flags);
+
+	return 0;
+}
+
+/**
+ * zynq_pll_disable - Disable clock
+ * @hw:		Handle between common and hardware-specific interfaces
+ * Returns 0 on success
+ */
+static void zynq_pll_disable(struct clk_hw *hw)
+{
+	unsigned long flags = 0;
+	u32 reg;
+	struct zynq_pll *clk = to_zynq_pll(hw);
+
+	if (!zynq_pll_is_enabled(hw))
+		return;
+
+	pr_info("PLL: shutdown\n");
+
+	/* shut down PLL */
+	spin_lock_irqsave(clk->lock, flags);
+
+	reg = readl(clk->pll_ctrl);
+	reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK;
+	writel(reg, clk->pll_ctrl);
+
+	spin_unlock_irqrestore(clk->lock, flags);
+}
+
+static const struct clk_ops zynq_pll_ops = {
+	.enable = zynq_pll_enable,
+	.disable = zynq_pll_disable,
+	.is_enabled = zynq_pll_is_enabled,
+	.round_rate = zynq_pll_round_rate,
+	.recalc_rate = zynq_pll_recalc_rate
+};
+
+/**
+ * clk_register_zynq_pll() - Register PLL with the clock framework
+ * @np	Pointer to the DT device node
+ */
+struct clk *clk_register_zynq_pll(const char *name, const char *parent,
+		void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
+		spinlock_t *lock)
+{
+	struct zynq_pll *pll;
+	struct clk *clk;
+	u32 reg;
+	const char *parent_arr[1] = {parent};
+	unsigned long flags = 0;
+	struct clk_init_data initd = {
+		.name = name,
+		.parent_names = parent_arr,
+		.ops = &zynq_pll_ops,
+		.num_parents = 1,
+		.flags = 0
+	};
+
+	pll = kmalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll) {
+		pr_err("%s: Could not allocate Zynq PLL clk.\n", __func__);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* Populate the struct */
+	pll->hw.init = &initd;
+	pll->pll_ctrl = pll_ctrl;
+	pll->pll_status = pll_status;
+	pll->lockbit = lock_index;
+	pll->lock = lock;
+
+	spin_lock_irqsave(pll->lock, flags);
+
+	reg = readl(pll->pll_ctrl);
+	reg &= ~PLLCTRL_BPQUAL_MASK;
+	writel(reg, pll->pll_ctrl);
+
+	spin_unlock_irqrestore(pll->lock, flags);
+
+	clk = clk_register(NULL, &pll->hw);
+	if (WARN_ON(IS_ERR(clk)))
+		goto free_pll;
+
+	return clk;
+
+free_pll:
+	kfree(pll);
+
+	return clk;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/arm_arch_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/arm_arch_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/arm_arch_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/arm_arch_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -123,7 +123,7 @@ static int arch_timer_set_next_event_phy
 	return 0;
 }
 
-static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
+static int arch_timer_setup(struct clock_event_device *clk)
 {
 	clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP;
 	clk->name = "arch_sys_timer";
@@ -186,27 +186,19 @@ u32 arch_timer_get_rate(void)
 	return arch_timer_rate;
 }
 
-/*
- * Some external users of arch_timer_read_counter (e.g. sched_clock) may try to
- * call it before it has been initialised. Rather than incur a performance
- * penalty checking for initialisation, provide a default implementation that
- * won't lead to time appearing to jump backwards.
- */
-static u64 arch_timer_read_zero(void)
+u64 arch_timer_read_counter(void)
 {
-	return 0;
+	return arch_counter_get_cntvct();
 }
 
-u64 (*arch_timer_read_counter)(void) = arch_timer_read_zero;
-
 static cycle_t arch_counter_read(struct clocksource *cs)
 {
-	return arch_timer_read_counter();
+	return arch_counter_get_cntvct();
 }
 
 static cycle_t arch_counter_read_cc(const struct cyclecounter *cc)
 {
-	return arch_timer_read_counter();
+	return arch_counter_get_cntvct();
 }
 
 static struct clocksource clocksource_counter = {
@@ -229,7 +221,7 @@ struct timecounter *arch_timer_get_timec
 	return &timecounter;
 }
 
-static void __cpuinit arch_timer_stop(struct clock_event_device *clk)
+static void arch_timer_stop(struct clock_event_device *clk)
 {
 	pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
 		 clk->irq, smp_processor_id());
@@ -245,7 +237,7 @@ static void __cpuinit arch_timer_stop(st
 	clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk);
 }
 
-static int __cpuinit arch_timer_cpu_notify(struct notifier_block *self,
+static int arch_timer_cpu_notify(struct notifier_block *self,
 					   unsigned long action, void *hcpu)
 {
 	/*
@@ -264,7 +256,7 @@ static int __cpuinit arch_timer_cpu_noti
 	return NOTIFY_OK;
 }
 
-static struct notifier_block arch_timer_cpu_nb __cpuinitdata = {
+static struct notifier_block arch_timer_cpu_nb = {
 	.notifier_call = arch_timer_cpu_notify,
 };
 
@@ -287,7 +279,7 @@ static int __init arch_timer_register(vo
 	cyclecounter.mult = clocksource_counter.mult;
 	cyclecounter.shift = clocksource_counter.shift;
 	timecounter_init(&timecounter, &cyclecounter,
-			 arch_counter_get_cntpct());
+			 arch_counter_get_cntvct());
 
 	if (arch_timer_use_virtual) {
 		ppi = arch_timer_ppi[VIRT_PPI];
@@ -376,11 +368,6 @@ static void __init arch_timer_init(struc
 		}
 	}
 
-	if (arch_timer_use_virtual)
-		arch_timer_read_counter = arch_counter_get_cntvct;
-	else
-		arch_timer_read_counter = arch_counter_get_cntpct;
-
 	arch_timer_register();
 	arch_timer_arch_init();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/arm_global_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/arm_global_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/arm_global_timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/arm_global_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,321 @@
+/*
+ * drivers/clocksource/arm_global_timer.c
+ *
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Author: Stuart Menefy <stuart.menefy@st.com>
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/cpu.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/sched_clock.h>
+
+#include <asm/cputype.h>
+
+#define GT_COUNTER0	0x00
+#define GT_COUNTER1	0x04
+
+#define GT_CONTROL	0x08
+#define GT_CONTROL_TIMER_ENABLE		BIT(0)  /* this bit is NOT banked */
+#define GT_CONTROL_COMP_ENABLE		BIT(1)	/* banked */
+#define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
+#define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
+
+#define GT_INT_STATUS	0x0c
+#define GT_INT_STATUS_EVENT_FLAG	BIT(0)
+
+#define GT_COMP0	0x10
+#define GT_COMP1	0x14
+#define GT_AUTO_INC	0x18
+
+/*
+ * We are expecting to be clocked by the ARM peripheral clock.
+ *
+ * Note: it is assumed we are using a prescaler value of zero, so this is
+ * the units for all operations.
+ */
+static void __iomem *gt_base;
+static unsigned long gt_clk_rate;
+static int gt_ppi;
+static struct clock_event_device __percpu *gt_evt;
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ *  different to the 32-bit upper value read previously, go back to step 2.
+ *  Otherwise the 64-bit timer counter value is correct.
+ */
+static u64 gt_counter_read(void)
+{
+	u64 counter;
+	u32 lower;
+	u32 upper, old_upper;
+
+	upper = readl_relaxed(gt_base + GT_COUNTER1);
+	do {
+		old_upper = upper;
+		lower = readl_relaxed(gt_base + GT_COUNTER0);
+		upper = readl_relaxed(gt_base + GT_COUNTER1);
+	} while (upper != old_upper);
+
+	counter = upper;
+	counter <<= 32;
+	counter |= lower;
+	return counter;
+}
+
+/**
+ * To ensure that updates to comparator value register do not set the
+ * Interrupt Status Register proceed as follows:
+ * 1. Clear the Comp Enable bit in the Timer Control Register.
+ * 2. Write the lower 32-bit Comparator Value Register.
+ * 3. Write the upper 32-bit Comparator Value Register.
+ * 4. Set the Comp Enable bit and, if necessary, the IRQ enable bit.
+ */
+static void gt_compare_set(unsigned long delta, int periodic)
+{
+	u64 counter = gt_counter_read();
+	unsigned long ctrl;
+
+	counter += delta;
+	ctrl = GT_CONTROL_TIMER_ENABLE;
+	writel(ctrl, gt_base + GT_CONTROL);
+	writel(lower_32_bits(counter), gt_base + GT_COMP0);
+	writel(upper_32_bits(counter), gt_base + GT_COMP1);
+
+	if (periodic) {
+		writel(delta, gt_base + GT_AUTO_INC);
+		ctrl |= GT_CONTROL_AUTO_INC;
+	}
+
+	ctrl |= GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE;
+	writel(ctrl, gt_base + GT_CONTROL);
+}
+
+static void gt_clockevent_set_mode(enum clock_event_mode mode,
+				   struct clock_event_device *clk)
+{
+	unsigned long ctrl;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		ctrl = readl(gt_base + GT_CONTROL);
+		ctrl &= ~(GT_CONTROL_COMP_ENABLE |
+				GT_CONTROL_IRQ_ENABLE | GT_CONTROL_AUTO_INC);
+		writel(ctrl, gt_base + GT_CONTROL);
+		break;
+	default:
+		break;
+	}
+}
+
+static int gt_clockevent_set_next_event(unsigned long evt,
+					struct clock_event_device *unused)
+{
+	gt_compare_set(evt, 0);
+	return 0;
+}
+
+static irqreturn_t gt_clockevent_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	if (!(readl_relaxed(gt_base + GT_INT_STATUS) &
+				GT_INT_STATUS_EVENT_FLAG))
+		return IRQ_NONE;
+
+	/**
+	 * ERRATA 740657( Global Timer can send 2 interrupts for
+	 * the same event in single-shot mode)
+	 * Workaround:
+	 *	Either disable single-shot mode.
+	 *	Or
+	 *	Modify the Interrupt Handler to avoid the
+	 *	offending sequence. This is achieved by clearing
+	 *	the Global Timer flag _after_ having incremented
+	 *	the Comparator register	value to a higher value.
+	 */
+	if (evt->mode == CLOCK_EVT_MODE_ONESHOT)
+		gt_compare_set(ULONG_MAX, 0);
+
+	writel_relaxed(GT_INT_STATUS_EVENT_FLAG, gt_base + GT_INT_STATUS);
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static int gt_clockevents_init(struct clock_event_device *clk)
+{
+	int cpu = smp_processor_id();
+
+	clk->name = "arm_global_timer";
+	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	clk->set_mode = gt_clockevent_set_mode;
+	clk->set_next_event = gt_clockevent_set_next_event;
+	clk->cpumask = cpumask_of(cpu);
+	clk->rating = 300;
+	clk->irq = gt_ppi;
+	clockevents_config_and_register(clk, gt_clk_rate,
+					1, 0xffffffff);
+	enable_percpu_irq(clk->irq, IRQ_TYPE_NONE);
+	return 0;
+}
+
+static void gt_clockevents_stop(struct clock_event_device *clk)
+{
+	gt_clockevent_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
+	disable_percpu_irq(clk->irq);
+}
+
+static cycle_t gt_clocksource_read(struct clocksource *cs)
+{
+	return gt_counter_read();
+}
+
+static struct clocksource gt_clocksource = {
+	.name	= "arm_global_timer",
+	.rating	= 300,
+	.read	= gt_clocksource_read,
+	.mask	= CLOCKSOURCE_MASK(64),
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+static u32 notrace gt_sched_clock_read(void)
+{
+	return gt_counter_read();
+}
+#endif
+
+static void __init gt_clocksource_init(void)
+{
+	writel(0, gt_base + GT_CONTROL);
+	writel(0, gt_base + GT_COUNTER0);
+	writel(0, gt_base + GT_COUNTER1);
+	/* enables timer on all the cores */
+	writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
+
+#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	setup_sched_clock(gt_sched_clock_read, 32, gt_clk_rate);
+#endif
+	clocksource_register_hz(&gt_clocksource, gt_clk_rate);
+}
+
+static int gt_cpu_notify(struct notifier_block *self, unsigned long action,
+			 void *hcpu)
+{
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_STARTING:
+		gt_clockevents_init(this_cpu_ptr(gt_evt));
+		break;
+	case CPU_DYING:
+		gt_clockevents_stop(this_cpu_ptr(gt_evt));
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+static struct notifier_block gt_cpu_nb = {
+	.notifier_call = gt_cpu_notify,
+};
+
+static void __init global_timer_of_register(struct device_node *np)
+{
+	struct clk *gt_clk;
+	int err = 0;
+
+	/*
+	 * In r2p0 the comparators for each processor with the global timer
+	 * fire when the timer value is greater than or equal to. In previous
+	 * revisions the comparators fired when the timer value was equal to.
+	 */
+	if ((read_cpuid_id() & 0xf0000f) < 0x200000) {
+		pr_warn("global-timer: non support for this cpu version.\n");
+		return;
+	}
+
+	gt_ppi = irq_of_parse_and_map(np, 0);
+	if (!gt_ppi) {
+		pr_warn("global-timer: unable to parse irq\n");
+		return;
+	}
+
+	gt_base = of_iomap(np, 0);
+	if (!gt_base) {
+		pr_warn("global-timer: invalid base address\n");
+		return;
+	}
+
+	gt_clk = of_clk_get(np, 0);
+	if (!IS_ERR(gt_clk)) {
+		err = clk_prepare_enable(gt_clk);
+		if (err)
+			goto out_unmap;
+	} else {
+		pr_warn("global-timer: clk not found\n");
+		err = -EINVAL;
+		goto out_unmap;
+	}
+
+	gt_clk_rate = clk_get_rate(gt_clk);
+	gt_evt = alloc_percpu(struct clock_event_device);
+	if (!gt_evt) {
+		pr_warn("global-timer: can't allocate memory\n");
+		err = -ENOMEM;
+		goto out_clk;
+	}
+
+	err = request_percpu_irq(gt_ppi, gt_clockevent_interrupt,
+				 "gt", gt_evt);
+	if (err) {
+		pr_warn("global-timer: can't register interrupt %d (%d)\n",
+			gt_ppi, err);
+		goto out_free;
+	}
+
+	err = register_cpu_notifier(&gt_cpu_nb);
+	if (err) {
+		pr_warn("global-timer: unable to register cpu notifier.\n");
+		goto out_irq;
+	}
+
+	/* Immediately configure the timer on the boot CPU */
+	gt_clocksource_init();
+	gt_clockevents_init(this_cpu_ptr(gt_evt));
+
+	return;
+
+out_irq:
+	free_percpu_irq(gt_ppi, gt_evt);
+out_free:
+	free_percpu(gt_evt);
+out_clk:
+	clk_disable_unprepare(gt_clk);
+out_unmap:
+	iounmap(gt_base);
+	WARN(err, "ARM Global timer register failed (%d)\n", err);
+}
+
+/* Only tested on r2p2 and r3p0  */
+CLOCKSOURCE_OF_DECLARE(arm_gt, "arm,cortex-a9-global-timer",
+			global_timer_of_register);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/bcm2835_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/bcm2835_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/bcm2835_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/bcm2835_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,8 +28,8 @@
 #include <linux/of_platform.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/sched_clock.h>
 
-#include <asm/sched_clock.h>
 #include <asm/irq.h>
 
 #define REG_CONTROL	0x00
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/bcm_kona_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/bcm_kona_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/bcm_kona_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/bcm_kona_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -103,16 +103,10 @@ static const struct of_device_id bcm_tim
 	{},
 };
 
-static void __init kona_timers_init(void)
+static void __init kona_timers_init(struct device_node *node)
 {
-	struct device_node *node;
 	u32 freq;
 
-	node = of_find_matching_node(NULL, bcm_timer_ids);
-
-	if (!node)
-		panic("No timer");
-
 	if (!of_property_read_u32(node, "clock-frequency", &freq))
 		arch_timer_rate = freq;
 	else
@@ -199,13 +193,12 @@ static struct irqaction kona_timer_irq =
 	.handler = kona_timer_interrupt,
 };
 
-static void __init kona_timer_init(void)
+static void __init kona_timer_init(struct device_node *node)
 {
-	kona_timers_init();
+	kona_timers_init(node);
 	kona_timer_clockevents_init();
 	setup_irq(timers.tmr_irq, &kona_timer_irq);
 	kona_timer_set_next_event((arch_timer_rate / HZ), NULL);
 }
 
-CLOCKSOURCE_OF_DECLARE(bcm_kona, "bcm,kona-timer",
-	kona_timer_init);
+CLOCKSOURCE_OF_DECLARE(bcm_kona, "bcm,kona-timer", kona_timer_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/cadence_ttc_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/cadence_ttc_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/cadence_ttc_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/cadence_ttc_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,6 +51,8 @@
 
 #define TTC_CNT_CNTRL_DISABLE_MASK	0x1
 
+#define TTC_CLK_CNTRL_CSRC_MASK		(1 << 5)	/* clock source */
+
 /*
  * Setup the timers to use pre-scaling, using a fixed value for now that will
  * work across most input frequency, but it may need to be more dynamic
@@ -396,8 +398,9 @@ static void __init ttc_timer_init(struct
 {
 	unsigned int irq;
 	void __iomem *timer_baseaddr;
-	struct clk *clk;
+	struct clk *clk_cs, *clk_ce;
 	static int initialized;
+	int clksel;
 
 	if (initialized)
 		return;
@@ -421,14 +424,24 @@ static void __init ttc_timer_init(struct
 		BUG();
 	}
 
-	clk = of_clk_get_by_name(timer, "cpu_1x");
-	if (IS_ERR(clk)) {
+	clksel = __raw_readl(timer_baseaddr + TTC_CLK_CNTRL_OFFSET);
+	clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK);
+	clk_cs = of_clk_get(timer, clksel);
+	if (IS_ERR(clk_cs)) {
 		pr_err("ERROR: timer input clock not found\n");
 		BUG();
 	}
 
-	ttc_setup_clocksource(clk, timer_baseaddr);
-	ttc_setup_clockevent(clk, timer_baseaddr + 4, irq);
+	clksel = __raw_readl(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET);
+	clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK);
+	clk_ce = of_clk_get(timer, clksel);
+	if (IS_ERR(clk_ce)) {
+		pr_err("ERROR: timer input clock not found\n");
+		BUG();
+	}
+
+	ttc_setup_clocksource(clk_cs, timer_baseaddr);
+	ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq);
 
 	pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/clksrc-dbx500-prcmu.c linux-libre-3.11-rc7-gnu/drivers/clocksource/clksrc-dbx500-prcmu.c
--- linux-libre-3.10-gnu/drivers/clocksource/clksrc-dbx500-prcmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/clksrc-dbx500-prcmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -10,12 +10,11 @@
  * DBx500-PRCMU Timer
  * The PRCMU has 5 timers which are available in a always-on
  * power domain.  We use the Timer 4 for our always-on clock
- * source on DB8500 and Timer 3 on DB5500.
+ * source on DB8500.
  */
 #include <linux/clockchips.h>
 #include <linux/clksrc-dbx500-prcmu.h>
-
-#include <asm/sched_clock.h>
+#include <linux/sched_clock.h>
 
 #define RATE_32K		32768
 
@@ -30,15 +29,14 @@
 
 static void __iomem *clksrc_dbx500_timer_base;
 
-static cycle_t clksrc_dbx500_prcmu_read(struct clocksource *cs)
+static cycle_t notrace clksrc_dbx500_prcmu_read(struct clocksource *cs)
 {
+	void __iomem *base = clksrc_dbx500_timer_base;
 	u32 count, count2;
 
 	do {
-		count = readl(clksrc_dbx500_timer_base +
-			      PRCMU_TIMER_DOWNCOUNT);
-		count2 = readl(clksrc_dbx500_timer_base +
-			       PRCMU_TIMER_DOWNCOUNT);
+		count = readl_relaxed(base + PRCMU_TIMER_DOWNCOUNT);
+		count2 = readl_relaxed(base + PRCMU_TIMER_DOWNCOUNT);
 	} while (count2 != count);
 
 	/* Negate because the timer is a decrementing counter */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/dummy_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/dummy_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/dummy_timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/dummy_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ *  linux/drivers/clocksource/dummy_timer.c
+ *
+ *  Copyright (C) 2013 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clockchips.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/percpu.h>
+#include <linux/cpumask.h>
+
+static DEFINE_PER_CPU(struct clock_event_device, dummy_timer_evt);
+
+static void dummy_timer_set_mode(enum clock_event_mode mode,
+			   struct clock_event_device *evt)
+{
+	/*
+	 * Core clockevents code will call this when exchanging timer devices.
+	 * We don't need to do anything here.
+	 */
+}
+
+static void dummy_timer_setup(void)
+{
+	int cpu = smp_processor_id();
+	struct clock_event_device *evt = __this_cpu_ptr(&dummy_timer_evt);
+
+	evt->name	= "dummy_timer";
+	evt->features	= CLOCK_EVT_FEAT_PERIODIC |
+			  CLOCK_EVT_FEAT_ONESHOT |
+			  CLOCK_EVT_FEAT_DUMMY;
+	evt->rating	= 100;
+	evt->set_mode	= dummy_timer_set_mode;
+	evt->cpumask	= cpumask_of(cpu);
+
+	clockevents_register_device(evt);
+}
+
+static int dummy_timer_cpu_notify(struct notifier_block *self,
+				      unsigned long action, void *hcpu)
+{
+	if ((action & ~CPU_TASKS_FROZEN) == CPU_STARTING)
+		dummy_timer_setup();
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block dummy_timer_cpu_nb = {
+	.notifier_call = dummy_timer_cpu_notify,
+};
+
+static int __init dummy_timer_register(void)
+{
+	int err = register_cpu_notifier(&dummy_timer_cpu_nb);
+	if (err)
+		return err;
+
+	/* We won't get a call on the boot CPU, so register immediately */
+	if (num_possible_cpus() > 1)
+		dummy_timer_setup();
+
+	return 0;
+}
+early_initcall(dummy_timer_register);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/dw_apb_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/dw_apb_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/dw_apb_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/dw_apb_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -387,15 +387,3 @@ cycle_t dw_apb_clocksource_read(struct d
 {
 	return (cycle_t)~apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE);
 }
-
-/**
- * dw_apb_clocksource_unregister() - unregister and free a clocksource.
- *
- * @dw_cs:	The clocksource to unregister/free.
- */
-void dw_apb_clocksource_unregister(struct dw_apb_clocksource *dw_cs)
-{
-	clocksource_unregister(&dw_cs->cs);
-
-	kfree(dw_cs);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/dw_apb_timer_of.c linux-libre-3.11-rc7-gnu/drivers/clocksource/dw_apb_timer_of.c
--- linux-libre-3.10-gnu/drivers/clocksource/dw_apb_timer_of.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/dw_apb_timer_of.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,21 +20,43 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
-
-#include <asm/mach/time.h>
-#include <asm/sched_clock.h>
+#include <linux/clk.h>
+#include <linux/sched_clock.h>
 
 static void timer_get_base_and_rate(struct device_node *np,
 				    void __iomem **base, u32 *rate)
 {
+	struct clk *timer_clk;
+	struct clk *pclk;
+
 	*base = of_iomap(np, 0);
 
 	if (!*base)
 		panic("Unable to map regs for %s", np->name);
 
+	/*
+	 * Not all implementations use a periphal clock, so don't panic
+	 * if it's not present
+	 */
+	pclk = of_clk_get_by_name(np, "pclk");
+	if (!IS_ERR(pclk))
+		if (clk_prepare_enable(pclk))
+			pr_warn("pclk for %s is present, but could not be activated\n",
+				np->name);
+
+	timer_clk = of_clk_get_by_name(np, "timer");
+	if (IS_ERR(timer_clk))
+		goto try_clock_freq;
+
+	if (!clk_prepare_enable(timer_clk)) {
+		*rate = clk_get_rate(timer_clk);
+		return;
+	}
+
+try_clock_freq:
 	if (of_property_read_u32(np, "clock-freq", rate) &&
 		of_property_read_u32(np, "clock-frequency", rate))
-		panic("No clock-frequency property for %s", np->name);
+		panic("No clock nor clock-frequency property for %s", np->name);
 }
 
 static void add_clockevent(struct device_node *event_timer)
@@ -44,7 +66,7 @@ static void add_clockevent(struct device
 	u32 irq, rate;
 
 	irq = irq_of_parse_and_map(event_timer, 0);
-	if (irq == NO_IRQ)
+	if (irq == 0)
 		panic("No IRQ for clock event timer");
 
 	timer_get_base_and_rate(event_timer, &iobase, &rate);
@@ -57,6 +79,9 @@ static void add_clockevent(struct device
 	dw_apb_clockevent_register(ced);
 }
 
+static void __iomem *sched_io_base;
+static u32 sched_rate;
+
 static void add_clocksource(struct device_node *source_timer)
 {
 	void __iomem *iobase;
@@ -71,9 +96,15 @@ static void add_clocksource(struct devic
 
 	dw_apb_clocksource_start(cs);
 	dw_apb_clocksource_register(cs);
-}
 
-static void __iomem *sched_io_base;
+	/*
+	 * Fallback to use the clocksource as sched_clock if no separate
+	 * timer is found. sched_io_base then points to the current_value
+	 * register of the clocksource timer.
+	 */
+	sched_io_base = iobase + 0x04;
+	sched_rate = rate;
+}
 
 static u32 read_sched_clock(void)
 {
@@ -89,39 +120,37 @@ static const struct of_device_id sptimer
 static void init_sched_clock(void)
 {
 	struct device_node *sched_timer;
-	u32 rate;
 
 	sched_timer = of_find_matching_node(NULL, sptimer_ids);
-	if (!sched_timer)
-		panic("No RTC for sched clock to use");
-
-	timer_get_base_and_rate(sched_timer, &sched_io_base, &rate);
-	of_node_put(sched_timer);
+	if (sched_timer) {
+		timer_get_base_and_rate(sched_timer, &sched_io_base,
+					&sched_rate);
+		of_node_put(sched_timer);
+	}
 
-	setup_sched_clock(read_sched_clock, 32, rate);
+	setup_sched_clock(read_sched_clock, 32, sched_rate);
 }
 
-static const struct of_device_id osctimer_ids[] __initconst = {
-	{ .compatible = "picochip,pc3x2-timer" },
-	{ .compatible = "snps,dw-apb-timer-osc" },
-	{},
-};
-
-void __init dw_apb_timer_init(void)
+static int num_called;
+static void __init dw_apb_timer_init(struct device_node *timer)
 {
-	struct device_node *event_timer, *source_timer;
-
-	event_timer = of_find_matching_node(NULL, osctimer_ids);
-	if (!event_timer)
-		panic("No timer for clockevent");
-	add_clockevent(event_timer);
-
-	source_timer = of_find_matching_node(event_timer, osctimer_ids);
-	if (!source_timer)
-		panic("No timer for clocksource");
-	add_clocksource(source_timer);
-
-	of_node_put(source_timer);
+	switch (num_called) {
+	case 0:
+		pr_debug("%s: found clockevent timer\n", __func__);
+		add_clockevent(timer);
+		of_node_put(timer);
+		break;
+	case 1:
+		pr_debug("%s: found clocksource timer\n", __func__);
+		add_clocksource(timer);
+		of_node_put(timer);
+		init_sched_clock();
+		break;
+	default:
+		break;
+	}
 
-	init_sched_clock();
+	num_called++;
 }
+CLOCKSOURCE_OF_DECLARE(pc3x2_timer, "picochip,pc3x2-timer", dw_apb_timer_init);
+CLOCKSOURCE_OF_DECLARE(apb_timer, "snps,dw-apb-timer-osc", dw_apb_timer_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/exynos_mct.c linux-libre-3.11-rc7-gnu/drivers/clocksource/exynos_mct.c
--- linux-libre-3.10-gnu/drivers/clocksource/exynos_mct.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/exynos_mct.c	2013-08-25 20:43:22.000000000 -0400
@@ -400,19 +400,7 @@ static irqreturn_t exynos4_mct_tick_isr(
 	return IRQ_HANDLED;
 }
 
-static struct irqaction mct_tick0_event_irq = {
-	.name		= "mct_tick0_irq",
-	.flags		= IRQF_TIMER | IRQF_NOBALANCING,
-	.handler	= exynos4_mct_tick_isr,
-};
-
-static struct irqaction mct_tick1_event_irq = {
-	.name		= "mct_tick1_irq",
-	.flags		= IRQF_TIMER | IRQF_NOBALANCING,
-	.handler	= exynos4_mct_tick_isr,
-};
-
-static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
+static int exynos4_local_timer_setup(struct clock_event_device *evt)
 {
 	struct mct_clock_event_device *mevt;
 	unsigned int cpu = smp_processor_id();
@@ -435,16 +423,15 @@ static int __cpuinit exynos4_local_timer
 	exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
 
 	if (mct_int_type == MCT_INT_SPI) {
-		if (cpu == 0) {
-			mct_tick0_event_irq.dev_id = mevt;
-			evt->irq = mct_irqs[MCT_L0_IRQ];
-			setup_irq(evt->irq, &mct_tick0_event_irq);
-		} else {
-			mct_tick1_event_irq.dev_id = mevt;
-			evt->irq = mct_irqs[MCT_L1_IRQ];
-			setup_irq(evt->irq, &mct_tick1_event_irq);
-			irq_set_affinity(evt->irq, cpumask_of(1));
+		evt->irq = mct_irqs[MCT_L0_IRQ + cpu];
+		if (request_irq(evt->irq, exynos4_mct_tick_isr,
+				IRQF_TIMER | IRQF_NOBALANCING,
+				evt->name, mevt)) {
+			pr_err("exynos-mct: cannot register IRQ %d\n",
+				evt->irq);
+			return -EIO;
 		}
+		irq_set_affinity(evt->irq, cpumask_of(cpu));
 	} else {
 		enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
 	}
@@ -454,18 +441,14 @@ static int __cpuinit exynos4_local_timer
 
 static void exynos4_local_timer_stop(struct clock_event_device *evt)
 {
-	unsigned int cpu = smp_processor_id();
 	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
 	if (mct_int_type == MCT_INT_SPI)
-		if (cpu == 0)
-			remove_irq(evt->irq, &mct_tick0_event_irq);
-		else
-			remove_irq(evt->irq, &mct_tick1_event_irq);
+		free_irq(evt->irq, this_cpu_ptr(&percpu_mct_tick));
 	else
 		disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
 }
 
-static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
+static struct local_timer_ops exynos4_mct_tick_ops = {
 	.setup	= exynos4_local_timer_setup,
 	.stop	= exynos4_local_timer_stop,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/Kconfig linux-libre-3.11-rc7-gnu/drivers/clocksource/Kconfig
--- linux-libre-3.10-gnu/drivers/clocksource/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -21,10 +21,17 @@ config DW_APB_TIMER
 
 config DW_APB_TIMER_OF
 	bool
+	select DW_APB_TIMER
+	select CLKSRC_OF
 
 config ARMADA_370_XP_TIMER
 	bool
 
+config ORION_TIMER
+	select CLKSRC_OF
+	select CLKSRC_MMIO
+	bool
+
 config SUN4I_TIMER
 	bool
 
@@ -67,6 +74,19 @@ config ARM_ARCH_TIMER
 	bool
 	select CLKSRC_OF if OF
 
+config ARM_GLOBAL_TIMER
+	bool
+	select CLKSRC_OF if OF
+	help
+	  This options enables support for the ARM global timer unit
+
+config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	bool
+	depends on ARM_GLOBAL_TIMER
+	default y
+	help
+	 Use ARM global timer clock source as sched_clock
+
 config CLKSRC_METAG_GENERIC
 	def_bool y if METAG
 	help
@@ -85,3 +105,8 @@ config CLKSRC_SAMSUNG_PWM
 	  Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver
 	  for all devicetree enabled platforms. This driver will be
 	  needed only on systems that do not have the Exynos MCT available.
+
+config VF_PIT_TIMER
+	bool
+	help
+	  Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/Makefile linux-libre-3.11-rc7-gnu/drivers/clocksource/Makefile
--- linux-libre-3.10-gnu/drivers/clocksource/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@ obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_
 obj-$(CONFIG_CLKSRC_NOMADIK_MTU)	+= nomadik-mtu.o
 obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
 obj-$(CONFIG_ARMADA_370_XP_TIMER)	+= time-armada-370-xp.o
+obj-$(CONFIG_ORION_TIMER)	+= time-orion.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835_timer.o
 obj-$(CONFIG_ARCH_MARCO)	+= timer-marco.o
 obj-$(CONFIG_ARCH_MXS)		+= mxs_timer.o
@@ -22,10 +23,14 @@ obj-$(CONFIG_ARCH_PRIMA2)	+= timer-prima
 obj-$(CONFIG_SUN4I_TIMER)	+= sun4i_timer.o
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra20_timer.o
 obj-$(CONFIG_VT8500_TIMER)	+= vt8500_timer.o
+obj-$(CONFIG_ARCH_NSPIRE)	+= zevio-timer.o
 obj-$(CONFIG_ARCH_BCM)		+= bcm_kona_timer.o
 obj-$(CONFIG_CADENCE_TTC_TIMER)	+= cadence_ttc_timer.o
 obj-$(CONFIG_CLKSRC_EXYNOS_MCT)	+= exynos_mct.o
 obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
+obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
+obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
 obj-$(CONFIG_CLKSRC_METAG_GENERIC)	+= metag_generic.o
+obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST)	+= dummy_timer.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/metag_generic.c linux-libre-3.11-rc7-gnu/drivers/clocksource/metag_generic.c
--- linux-libre-3.10-gnu/drivers/clocksource/metag_generic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/metag_generic.c	2013-08-25 20:43:22.000000000 -0400
@@ -109,7 +109,7 @@ unsigned long long sched_clock(void)
 	return ticks << HARDWARE_TO_NS_SHIFT;
 }
 
-static void __cpuinit arch_timer_setup(unsigned int cpu)
+static void arch_timer_setup(unsigned int cpu)
 {
 	unsigned int txdivtime;
 	struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
@@ -154,7 +154,7 @@ static void __cpuinit arch_timer_setup(u
 	}
 }
 
-static int __cpuinit arch_timer_cpu_notify(struct notifier_block *self,
+static int arch_timer_cpu_notify(struct notifier_block *self,
 					   unsigned long action, void *hcpu)
 {
 	int cpu = (long)hcpu;
@@ -169,7 +169,7 @@ static int __cpuinit arch_timer_cpu_noti
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata arch_timer_cpu_nb = {
+static struct notifier_block arch_timer_cpu_nb = {
 	.notifier_call = arch_timer_cpu_notify,
 };
 
@@ -184,6 +184,8 @@ int __init metag_generic_timer_init(void
 #ifdef CONFIG_METAG_META21
 	hwtimer_freq = get_coreclock() / (metag_in32(EXPAND_TIMER_DIV) + 1);
 #endif
+	pr_info("Timer frequency: %u Hz\n", hwtimer_freq);
+
 	clocksource_register_hz(&clocksource_metag, hwtimer_freq);
 
 	setup_irq(tbisig_map(TBID_SIGNUM_TRT), &metag_timer_irq);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/mxs_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/mxs_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/mxs_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/mxs_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,9 +29,9 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/stmp_device.h>
+#include <linux/sched_clock.h>
 
 #include <asm/mach/time.h>
-#include <asm/sched_clock.h>
 
 /*
  * There are 2 versions of the timrot on Freescale MXS-based SoCs.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/nomadik-mtu.c linux-libre-3.11-rc7-gnu/drivers/clocksource/nomadik-mtu.c
--- linux-libre-3.10-gnu/drivers/clocksource/nomadik-mtu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/nomadik-mtu.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,13 +13,16 @@
 #include <linux/io.h>
 #include <linux/clockchips.h>
 #include <linux/clocksource.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
 #include <linux/clk.h>
 #include <linux/jiffies.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/platform_data/clocksource-nomadik-mtu.h>
+#include <linux/sched_clock.h>
 #include <asm/mach/time.h>
-#include <asm/sched_clock.h>
 
 /*
  * The MTU device hosts four different counters, with 4 set of
@@ -188,22 +191,15 @@ static struct irqaction nmdk_timer_irq =
 	.dev_id		= &nmdk_clkevt,
 };
 
-void __init nmdk_timer_init(void __iomem *base, int irq)
+static void __init __nmdk_timer_init(void __iomem *base, int irq,
+				     struct clk *pclk, struct clk *clk)
 {
 	unsigned long rate;
-	struct clk *clk0, *pclk0;
 
 	mtu_base = base;
 
-	pclk0 = clk_get_sys("mtu0", "apb_pclk");
-	BUG_ON(IS_ERR(pclk0));
-	BUG_ON(clk_prepare(pclk0) < 0);
-	BUG_ON(clk_enable(pclk0) < 0);
-
-	clk0 = clk_get_sys("mtu0", NULL);
-	BUG_ON(IS_ERR(clk0));
-	BUG_ON(clk_prepare(clk0) < 0);
-	BUG_ON(clk_enable(clk0) < 0);
+	BUG_ON(clk_prepare_enable(pclk));
+	BUG_ON(clk_prepare_enable(clk));
 
 	/*
 	 * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz
@@ -213,7 +209,7 @@ void __init nmdk_timer_init(void __iomem
 	 * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer
 	 * with 16 gives too low timer resolution.
 	 */
-	rate = clk_get_rate(clk0);
+	rate = clk_get_rate(clk);
 	if (rate > 32000000) {
 		rate /= 16;
 		clk_prescale = MTU_CRn_PRESCALE_16;
@@ -247,3 +243,43 @@ void __init nmdk_timer_init(void __iomem
 	mtu_delay_timer.freq = rate;
 	register_current_timer_delay(&mtu_delay_timer);
 }
+
+void __init nmdk_timer_init(void __iomem *base, int irq)
+{
+	struct clk *clk0, *pclk0;
+
+	pclk0 = clk_get_sys("mtu0", "apb_pclk");
+	BUG_ON(IS_ERR(pclk0));
+	clk0 = clk_get_sys("mtu0", NULL);
+	BUG_ON(IS_ERR(clk0));
+
+	__nmdk_timer_init(base, irq, pclk0, clk0);
+}
+
+static void __init nmdk_timer_of_init(struct device_node *node)
+{
+	struct clk *pclk;
+	struct clk *clk;
+	void __iomem *base;
+	int irq;
+
+	base = of_iomap(node, 0);
+	if (!base)
+		panic("Can't remap registers");
+
+	pclk = of_clk_get_by_name(node, "apb_pclk");
+	if (IS_ERR(pclk))
+		panic("could not get apb_pclk");
+
+	clk = of_clk_get_by_name(node, "timclk");
+	if (IS_ERR(clk))
+		panic("could not get timclk");
+
+	irq = irq_of_parse_and_map(node, 0);
+	if (irq <= 0)
+		panic("Can't parse IRQ");
+
+	__nmdk_timer_init(base, irq, pclk, clk);
+}
+CLOCKSOURCE_OF_DECLARE(nomadik_mtu, "st,nomadik-mtu",
+		       nmdk_timer_of_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/samsung_pwm_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/samsung_pwm_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/samsung_pwm_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/samsung_pwm_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,10 +21,10 @@
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/sched_clock.h>
 
 #include <clocksource/samsung_pwm.h>
 
-#include <asm/sched_clock.h>
 
 /*
  * Clocksource driver
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/tegra20_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/tegra20_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/tegra20_timer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/tegra20_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,10 +26,10 @@
 #include <linux/io.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/sched_clock.h>
 
 #include <asm/mach/time.h>
 #include <asm/smp_twd.h>
-#include <asm/sched_clock.h>
 
 #define RTC_SECONDS            0x08
 #define RTC_SHADOW_SECONDS     0x0c
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/time-armada-370-xp.c linux-libre-3.11-rc7-gnu/drivers/clocksource/time-armada-370-xp.c
--- linux-libre-3.10-gnu/drivers/clocksource/time-armada-370-xp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/time-armada-370-xp.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,8 +27,8 @@
 #include <linux/of_address.h>
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/sched_clock.h>
 
-#include <asm/sched_clock.h>
 #include <asm/localtimer.h>
 #include <linux/percpu.h>
 /*
@@ -167,7 +167,7 @@ static irqreturn_t armada_370_xp_timer_i
 /*
  * Setup the local clock events for a CPU.
  */
-static int __cpuinit armada_370_xp_timer_setup(struct clock_event_device *evt)
+static int armada_370_xp_timer_setup(struct clock_event_device *evt)
 {
 	u32 u;
 	int cpu = smp_processor_id();
@@ -205,7 +205,7 @@ static void  armada_370_xp_timer_stop(st
 	disable_percpu_irq(evt->irq);
 }
 
-static struct local_timer_ops armada_370_xp_local_timer_ops __cpuinitdata = {
+static struct local_timer_ops armada_370_xp_local_timer_ops = {
 	.setup	= armada_370_xp_timer_setup,
 	.stop	=  armada_370_xp_timer_stop,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/time-orion.c linux-libre-3.11-rc7-gnu/drivers/clocksource/time-orion.c
--- linux-libre-3.10-gnu/drivers/clocksource/time-orion.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/time-orion.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,150 @@
+/*
+ * Marvell Orion SoC timer handling.
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * Timer 0 is used as free-running clocksource, while timer 1 is
+ * used as clock_event_device.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/spinlock.h>
+#include <asm/sched_clock.h>
+
+#define TIMER_CTRL		0x00
+#define  TIMER0_EN		BIT(0)
+#define  TIMER0_RELOAD_EN	BIT(1)
+#define  TIMER1_EN		BIT(2)
+#define  TIMER1_RELOAD_EN	BIT(3)
+#define TIMER0_RELOAD		0x10
+#define TIMER0_VAL		0x14
+#define TIMER1_RELOAD		0x18
+#define TIMER1_VAL		0x1c
+
+#define ORION_ONESHOT_MIN	1
+#define ORION_ONESHOT_MAX	0xfffffffe
+
+static void __iomem *timer_base;
+static DEFINE_SPINLOCK(timer_ctrl_lock);
+
+/*
+ * Thread-safe access to TIMER_CTRL register
+ * (shared with watchdog timer)
+ */
+void orion_timer_ctrl_clrset(u32 clr, u32 set)
+{
+	spin_lock(&timer_ctrl_lock);
+	writel((readl(timer_base + TIMER_CTRL) & ~clr) | set,
+		timer_base + TIMER_CTRL);
+	spin_unlock(&timer_ctrl_lock);
+}
+EXPORT_SYMBOL(orion_timer_ctrl_clrset);
+
+/*
+ * Free-running clocksource handling.
+ */
+static u32 notrace orion_read_sched_clock(void)
+{
+	return ~readl(timer_base + TIMER0_VAL);
+}
+
+/*
+ * Clockevent handling.
+ */
+static u32 ticks_per_jiffy;
+
+static int orion_clkevt_next_event(unsigned long delta,
+				   struct clock_event_device *dev)
+{
+	/* setup and enable one-shot timer */
+	writel(delta, timer_base + TIMER1_VAL);
+	orion_timer_ctrl_clrset(TIMER1_RELOAD_EN, TIMER1_EN);
+
+	return 0;
+}
+
+static void orion_clkevt_mode(enum clock_event_mode mode,
+			      struct clock_event_device *dev)
+{
+	if (mode == CLOCK_EVT_MODE_PERIODIC) {
+		/* setup and enable periodic timer at 1/HZ intervals */
+		writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD);
+		writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL);
+		orion_timer_ctrl_clrset(0, TIMER1_RELOAD_EN | TIMER1_EN);
+	} else {
+		/* disable timer */
+		orion_timer_ctrl_clrset(TIMER1_RELOAD_EN | TIMER1_EN, 0);
+	}
+}
+
+static struct clock_event_device orion_clkevt = {
+	.name		= "orion_event",
+	.features	= CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+	.shift		= 32,
+	.rating		= 300,
+	.set_next_event	= orion_clkevt_next_event,
+	.set_mode	= orion_clkevt_mode,
+};
+
+static irqreturn_t orion_clkevt_irq_handler(int irq, void *dev_id)
+{
+	orion_clkevt.event_handler(&orion_clkevt);
+	return IRQ_HANDLED;
+}
+
+static struct irqaction orion_clkevt_irq = {
+	.name		= "orion_event",
+	.flags		= IRQF_TIMER,
+	.handler	= orion_clkevt_irq_handler,
+};
+
+static void __init orion_timer_init(struct device_node *np)
+{
+	struct clk *clk;
+	int irq;
+
+	/* timer registers are shared with watchdog timer */
+	timer_base = of_iomap(np, 0);
+	if (!timer_base)
+		panic("%s: unable to map resource\n", np->name);
+
+	clk = of_clk_get(np, 0);
+	if (IS_ERR(clk))
+		panic("%s: unable to get clk\n", np->name);
+	clk_prepare_enable(clk);
+
+	/* we are only interested in timer1 irq */
+	irq = irq_of_parse_and_map(np, 1);
+	if (irq <= 0)
+		panic("%s: unable to parse timer1 irq\n", np->name);
+
+	/* setup timer0 as free-running clocksource */
+	writel(~0, timer_base + TIMER0_VAL);
+	writel(~0, timer_base + TIMER0_RELOAD);
+	orion_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | TIMER0_EN);
+	clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource",
+			      clk_get_rate(clk), 300, 32,
+			      clocksource_mmio_readl_down);
+	setup_sched_clock(orion_read_sched_clock, 32, clk_get_rate(clk));
+
+	/* setup timer1 as clockevent timer */
+	if (setup_irq(irq, &orion_clkevt_irq))
+		panic("%s: unable to setup irq\n", np->name);
+
+	ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ;
+	orion_clkevt.cpumask = cpumask_of(0);
+	orion_clkevt.irq = irq;
+	clockevents_config_and_register(&orion_clkevt, clk_get_rate(clk),
+					ORION_ONESHOT_MIN, ORION_ONESHOT_MAX);
+}
+CLOCKSOURCE_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/timer-marco.c linux-libre-3.11-rc7-gnu/drivers/clocksource/timer-marco.c
--- linux-libre-3.10-gnu/drivers/clocksource/timer-marco.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/timer-marco.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
-#include <asm/sched_clock.h>
+#include <linux/sched_clock.h>
 #include <asm/localtimer.h>
 #include <asm/mach/time.h>
 
@@ -184,7 +184,7 @@ static struct irqaction sirfsoc_timer1_i
 	.handler = sirfsoc_timer_interrupt,
 };
 
-static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce)
+static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
 {
 	/* Use existing clock_event for cpu 0 */
 	if (!smp_processor_id())
@@ -216,7 +216,7 @@ static void sirfsoc_local_timer_stop(str
 	remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq);
 }
 
-static struct local_timer_ops sirfsoc_local_timer_ops __cpuinitdata = {
+static struct local_timer_ops sirfsoc_local_timer_ops = {
 	.setup	= sirfsoc_local_timer_setup,
 	.stop	= sirfsoc_local_timer_stop,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/timer-prima2.c linux-libre-3.11-rc7-gnu/drivers/clocksource/timer-prima2.c
--- linux-libre-3.10-gnu/drivers/clocksource/timer-prima2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/timer-prima2.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,7 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
-#include <asm/sched_clock.h>
+#include <linux/sched_clock.h>
 #include <asm/mach/time.h>
 
 #define SIRFSOC_TIMER_COUNTER_LO	0x0000
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/vf_pit_timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/vf_pit_timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/vf_pit_timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/vf_pit_timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2012-2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+/*
+ * Each pit takes 0x10 Bytes register space
+ */
+#define PITMCR		0x00
+#define PIT0_OFFSET	0x100
+#define PITn_OFFSET(n)	(PIT0_OFFSET + 0x10 * (n))
+#define PITLDVAL	0x00
+#define PITCVAL		0x04
+#define PITTCTRL	0x08
+#define PITTFLG		0x0c
+
+#define PITMCR_MDIS	(0x1 << 1)
+
+#define PITTCTRL_TEN	(0x1 << 0)
+#define PITTCTRL_TIE	(0x1 << 1)
+#define PITCTRL_CHN	(0x1 << 2)
+
+#define PITTFLG_TIF	0x1
+
+static void __iomem *clksrc_base;
+static void __iomem *clkevt_base;
+static unsigned long cycle_per_jiffy;
+
+static inline void pit_timer_enable(void)
+{
+	__raw_writel(PITTCTRL_TEN | PITTCTRL_TIE, clkevt_base + PITTCTRL);
+}
+
+static inline void pit_timer_disable(void)
+{
+	__raw_writel(0, clkevt_base + PITTCTRL);
+}
+
+static inline void pit_irq_acknowledge(void)
+{
+	__raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG);
+}
+
+static unsigned int pit_read_sched_clock(void)
+{
+	return __raw_readl(clksrc_base + PITCVAL);
+}
+
+static int __init pit_clocksource_init(unsigned long rate)
+{
+	/* set the max load value and start the clock source counter */
+	__raw_writel(0, clksrc_base + PITTCTRL);
+	__raw_writel(~0UL, clksrc_base + PITLDVAL);
+	__raw_writel(PITTCTRL_TEN, clksrc_base + PITTCTRL);
+
+	setup_sched_clock(pit_read_sched_clock, 32, rate);
+	return clocksource_mmio_init(clksrc_base + PITCVAL, "vf-pit", rate,
+			300, 32, clocksource_mmio_readl_down);
+}
+
+static int pit_set_next_event(unsigned long delta,
+				struct clock_event_device *unused)
+{
+	/*
+	 * set a new value to PITLDVAL register will not restart the timer,
+	 * to abort the current cycle and start a timer period with the new
+	 * value, the timer must be disabled and enabled again.
+	 * and the PITLAVAL should be set to delta minus one according to pit
+	 * hardware requirement.
+	 */
+	pit_timer_disable();
+	__raw_writel(delta - 1, clkevt_base + PITLDVAL);
+	pit_timer_enable();
+
+	return 0;
+}
+
+static void pit_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		pit_set_next_event(cycle_per_jiffy, evt);
+		break;
+	default:
+		break;
+	}
+}
+
+static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	pit_irq_acknowledge();
+
+	/*
+	 * pit hardware doesn't support oneshot, it will generate an interrupt
+	 * and reload the counter value from PITLDVAL when PITCVAL reach zero,
+	 * and start the counter again. So software need to disable the timer
+	 * to stop the counter loop in ONESHOT mode.
+	 */
+	if (likely(evt->mode == CLOCK_EVT_MODE_ONESHOT))
+		pit_timer_disable();
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct clock_event_device clockevent_pit = {
+	.name		= "VF pit timer",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode	= pit_set_mode,
+	.set_next_event	= pit_set_next_event,
+	.rating		= 300,
+};
+
+static struct irqaction pit_timer_irq = {
+	.name		= "VF pit timer",
+	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= pit_timer_interrupt,
+	.dev_id		= &clockevent_pit,
+};
+
+static int __init pit_clockevent_init(unsigned long rate, int irq)
+{
+	__raw_writel(0, clkevt_base + PITTCTRL);
+	__raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG);
+
+	BUG_ON(setup_irq(irq, &pit_timer_irq));
+
+	clockevent_pit.cpumask = cpumask_of(0);
+	clockevent_pit.irq = irq;
+	/*
+	 * The value for the LDVAL register trigger is calculated as:
+	 * LDVAL trigger = (period / clock period) - 1
+	 * The pit is a 32-bit down count timer, when the conter value
+	 * reaches 0, it will generate an interrupt, thus the minimal
+	 * LDVAL trigger value is 1. And then the min_delta is
+	 * minimal LDVAL trigger value + 1, and the max_delta is full 32-bit.
+	 */
+	clockevents_config_and_register(&clockevent_pit, rate, 2, 0xffffffff);
+
+	return 0;
+}
+
+static void __init pit_timer_init(struct device_node *np)
+{
+	struct clk *pit_clk;
+	void __iomem *timer_base;
+	unsigned long clk_rate;
+	int irq;
+
+	timer_base = of_iomap(np, 0);
+	BUG_ON(!timer_base);
+
+	/*
+	 * PIT0 and PIT1 can be chained to build a 64-bit timer,
+	 * so choose PIT2 as clocksource, PIT3 as clockevent device,
+	 * and leave PIT0 and PIT1 unused for anyone else who needs them.
+	 */
+	clksrc_base = timer_base + PITn_OFFSET(2);
+	clkevt_base = timer_base + PITn_OFFSET(3);
+
+	irq = irq_of_parse_and_map(np, 0);
+	BUG_ON(irq <= 0);
+
+	pit_clk = of_clk_get(np, 0);
+	BUG_ON(IS_ERR(pit_clk));
+
+	BUG_ON(clk_prepare_enable(pit_clk));
+
+	clk_rate = clk_get_rate(pit_clk);
+	cycle_per_jiffy = clk_rate / (HZ);
+
+	/* enable the pit module */
+	__raw_writel(~PITMCR_MDIS, timer_base + PITMCR);
+
+	BUG_ON(pit_clocksource_init(clk_rate));
+
+	pit_clockevent_init(clk_rate, irq);
+}
+CLOCKSOURCE_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/clocksource/zevio-timer.c linux-libre-3.11-rc7-gnu/drivers/clocksource/zevio-timer.c
--- linux-libre-3.10-gnu/drivers/clocksource/zevio-timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/clocksource/zevio-timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,215 @@
+/*
+ *  linux/drivers/clocksource/zevio-timer.c
+ *
+ *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+
+#define IO_CURRENT_VAL	0x00
+#define IO_DIVIDER	0x04
+#define IO_CONTROL	0x08
+
+#define IO_TIMER1	0x00
+#define IO_TIMER2	0x0C
+
+#define IO_MATCH_BEGIN	0x18
+#define IO_MATCH(x)	(IO_MATCH_BEGIN + ((x) << 2))
+
+#define IO_INTR_STS	0x00
+#define IO_INTR_ACK	0x00
+#define IO_INTR_MSK	0x04
+
+#define CNTL_STOP_TIMER	(1 << 4)
+#define CNTL_RUN_TIMER	(0 << 4)
+
+#define CNTL_INC	(1 << 3)
+#define CNTL_DEC	(0 << 3)
+
+#define CNTL_TOZERO	0
+#define CNTL_MATCH(x)	((x) + 1)
+#define CNTL_FOREVER	7
+
+/* There are 6 match registers but we only use one. */
+#define TIMER_MATCH	0
+
+#define TIMER_INTR_MSK	(1 << (TIMER_MATCH))
+#define TIMER_INTR_ALL	0x3F
+
+struct zevio_timer {
+	void __iomem *base;
+	void __iomem *timer1, *timer2;
+	void __iomem *interrupt_regs;
+
+	struct clk *clk;
+	struct clock_event_device clkevt;
+	struct irqaction clkevt_irq;
+
+	char clocksource_name[64];
+	char clockevent_name[64];
+};
+
+static int zevio_timer_set_event(unsigned long delta,
+				 struct clock_event_device *dev)
+{
+	struct zevio_timer *timer = container_of(dev, struct zevio_timer,
+						 clkevt);
+
+	writel(delta, timer->timer1 + IO_CURRENT_VAL);
+	writel(CNTL_RUN_TIMER | CNTL_DEC | CNTL_MATCH(TIMER_MATCH),
+			timer->timer1 + IO_CONTROL);
+
+	return 0;
+}
+
+static void zevio_timer_set_mode(enum clock_event_mode mode,
+				 struct clock_event_device *dev)
+{
+	struct zevio_timer *timer = container_of(dev, struct zevio_timer,
+						 clkevt);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_RESUME:
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* Enable timer interrupts */
+		writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_MSK);
+		writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK);
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+		/* Disable timer interrupts */
+		writel(0, timer->interrupt_regs + IO_INTR_MSK);
+		writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK);
+		/* Stop timer */
+		writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL);
+		break;
+	case CLOCK_EVT_MODE_PERIODIC:
+	default:
+		/* Unsupported */
+		break;
+	}
+}
+
+static irqreturn_t zevio_timer_interrupt(int irq, void *dev_id)
+{
+	struct zevio_timer *timer = dev_id;
+	u32 intr;
+
+	intr = readl(timer->interrupt_regs + IO_INTR_ACK);
+	if (!(intr & TIMER_INTR_MSK))
+		return IRQ_NONE;
+
+	writel(TIMER_INTR_MSK, timer->interrupt_regs + IO_INTR_ACK);
+	writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL);
+
+	if (timer->clkevt.event_handler)
+		timer->clkevt.event_handler(&timer->clkevt);
+
+	return IRQ_HANDLED;
+}
+
+static int __init zevio_timer_add(struct device_node *node)
+{
+	struct zevio_timer *timer;
+	struct resource res;
+	int irqnr, ret;
+
+	timer = kzalloc(sizeof(*timer), GFP_KERNEL);
+	if (!timer)
+		return -ENOMEM;
+
+	timer->base = of_iomap(node, 0);
+	if (!timer->base) {
+		ret = -EINVAL;
+		goto error_free;
+	}
+	timer->timer1 = timer->base + IO_TIMER1;
+	timer->timer2 = timer->base + IO_TIMER2;
+
+	timer->clk = of_clk_get(node, 0);
+	if (IS_ERR(timer->clk)) {
+		ret = PTR_ERR(timer->clk);
+		pr_err("Timer clock not found! (error %d)\n", ret);
+		goto error_unmap;
+	}
+
+	timer->interrupt_regs = of_iomap(node, 1);
+	irqnr = irq_of_parse_and_map(node, 0);
+
+	of_address_to_resource(node, 0, &res);
+	scnprintf(timer->clocksource_name, sizeof(timer->clocksource_name),
+			"%llx.%s_clocksource",
+			(unsigned long long)res.start, node->name);
+
+	scnprintf(timer->clockevent_name, sizeof(timer->clockevent_name),
+			"%llx.%s_clockevent",
+			(unsigned long long)res.start, node->name);
+
+	if (timer->interrupt_regs && irqnr) {
+		timer->clkevt.name		= timer->clockevent_name;
+		timer->clkevt.set_next_event	= zevio_timer_set_event;
+		timer->clkevt.set_mode		= zevio_timer_set_mode;
+		timer->clkevt.rating		= 200;
+		timer->clkevt.cpumask		= cpu_all_mask;
+		timer->clkevt.features		= CLOCK_EVT_FEAT_ONESHOT;
+		timer->clkevt.irq		= irqnr;
+
+		writel(CNTL_STOP_TIMER, timer->timer1 + IO_CONTROL);
+		writel(0, timer->timer1 + IO_DIVIDER);
+
+		/* Start with timer interrupts disabled */
+		writel(0, timer->interrupt_regs + IO_INTR_MSK);
+		writel(TIMER_INTR_ALL, timer->interrupt_regs + IO_INTR_ACK);
+
+		/* Interrupt to occur when timer value matches 0 */
+		writel(0, timer->base + IO_MATCH(TIMER_MATCH));
+
+		timer->clkevt_irq.name		= timer->clockevent_name;
+		timer->clkevt_irq.handler	= zevio_timer_interrupt;
+		timer->clkevt_irq.dev_id	= timer;
+		timer->clkevt_irq.flags		= IRQF_TIMER | IRQF_IRQPOLL;
+
+		setup_irq(irqnr, &timer->clkevt_irq);
+
+		clockevents_config_and_register(&timer->clkevt,
+				clk_get_rate(timer->clk), 0x0001, 0xffff);
+		pr_info("Added %s as clockevent\n", timer->clockevent_name);
+	}
+
+	writel(CNTL_STOP_TIMER, timer->timer2 + IO_CONTROL);
+	writel(0, timer->timer2 + IO_CURRENT_VAL);
+	writel(0, timer->timer2 + IO_DIVIDER);
+	writel(CNTL_RUN_TIMER | CNTL_FOREVER | CNTL_INC,
+			timer->timer2 + IO_CONTROL);
+
+	clocksource_mmio_init(timer->timer2 + IO_CURRENT_VAL,
+			timer->clocksource_name,
+			clk_get_rate(timer->clk),
+			200, 16,
+			clocksource_mmio_readw_up);
+
+	pr_info("Added %s as clocksource\n", timer->clocksource_name);
+
+	return 0;
+error_unmap:
+	iounmap(timer->base);
+error_free:
+	kfree(timer);
+	return ret;
+}
+
+CLOCKSOURCE_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_add);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/acpi-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/acpi-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/acpi-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/acpi-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -70,6 +70,7 @@ struct acpi_cpufreq_data {
 	struct cpufreq_frequency_table *freq_table;
 	unsigned int resume;
 	unsigned int cpu_feature;
+	cpumask_var_t freqdomain_cpus;
 };
 
 static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);
@@ -176,6 +177,15 @@ static struct global_attr global_boost =
 						show_global_boost,
 						store_global_boost);
 
+static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)
+{
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+
+	return cpufreq_show_cpus(data->freqdomain_cpus, buf);
+}
+
+cpufreq_freq_attr_ro(freqdomain_cpus);
+
 #ifdef CONFIG_X86_ACPI_CPUFREQ_CPB
 static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
 			 size_t count)
@@ -232,7 +242,7 @@ static unsigned extract_msr(u32 msr, str
 	perf = data->acpi_data;
 
 	for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-		if (msr == perf->states[data->freq_table[i].index].status)
+		if (msr == perf->states[data->freq_table[i].driver_data].status)
 			return data->freq_table[i].frequency;
 	}
 	return data->freq_table[0].frequency;
@@ -442,7 +452,7 @@ static int acpi_cpufreq_target(struct cp
 		goto out;
 	}
 
-	next_perf_state = data->freq_table[next_state].index;
+	next_perf_state = data->freq_table[next_state].driver_data;
 	if (perf->state == next_perf_state) {
 		if (unlikely(data->resume)) {
 			pr_debug("Called after resume, resetting to P%d\n",
@@ -494,12 +504,14 @@ static int acpi_cpufreq_target(struct cp
 			pr_debug("acpi_cpufreq_target failed (%d)\n",
 				policy->cpu);
 			result = -EAGAIN;
-			goto out;
+			freqs.new = freqs.old;
 		}
 	}
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-	perf->state = next_perf_state;
+
+	if (!result)
+		perf->state = next_perf_state;
 
 out:
 	return result;
@@ -702,6 +714,11 @@ static int acpi_cpufreq_cpu_init(struct
 	if (!data)
 		return -ENOMEM;
 
+	if (!zalloc_cpumask_var(&data->freqdomain_cpus, GFP_KERNEL)) {
+		result = -ENOMEM;
+		goto err_free;
+	}
+
 	data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);
 	per_cpu(acfreq_data, cpu) = data;
 
@@ -710,7 +727,7 @@ static int acpi_cpufreq_cpu_init(struct
 
 	result = acpi_processor_register_performance(data->acpi_data, cpu);
 	if (result)
-		goto err_free;
+		goto err_free_mask;
 
 	perf = data->acpi_data;
 	policy->shared_type = perf->shared_type;
@@ -723,6 +740,7 @@ static int acpi_cpufreq_cpu_init(struct
 	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
 		cpumask_copy(policy->cpus, perf->shared_cpu_map);
 	}
+	cpumask_copy(data->freqdomain_cpus, perf->shared_cpu_map);
 
 #ifdef CONFIG_SMP
 	dmi_check_system(sw_any_bug_dmi_table);
@@ -734,6 +752,7 @@ static int acpi_cpufreq_cpu_init(struct
 	if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) {
 		cpumask_clear(policy->cpus);
 		cpumask_set_cpu(cpu, policy->cpus);
+		cpumask_copy(data->freqdomain_cpus, cpu_sibling_mask(cpu));
 		policy->shared_type = CPUFREQ_SHARED_TYPE_HW;
 		pr_info_once(PFX "overriding BIOS provided _PSD data\n");
 	}
@@ -811,7 +830,7 @@ static int acpi_cpufreq_cpu_init(struct
 		    data->freq_table[valid_states-1].frequency / 1000)
 			continue;
 
-		data->freq_table[valid_states].index = i;
+		data->freq_table[valid_states].driver_data = i;
 		data->freq_table[valid_states].frequency =
 		    perf->states[i].core_frequency * 1000;
 		valid_states++;
@@ -868,6 +887,8 @@ err_freqfree:
 	kfree(data->freq_table);
 err_unreg:
 	acpi_processor_unregister_performance(perf, cpu);
+err_free_mask:
+	free_cpumask_var(data->freqdomain_cpus);
 err_free:
 	kfree(data);
 	per_cpu(acfreq_data, cpu) = NULL;
@@ -886,6 +907,7 @@ static int acpi_cpufreq_cpu_exit(struct
 		per_cpu(acfreq_data, policy->cpu) = NULL;
 		acpi_processor_unregister_performance(data->acpi_data,
 						      policy->cpu);
+		free_cpumask_var(data->freqdomain_cpus);
 		kfree(data->freq_table);
 		kfree(data);
 	}
@@ -906,6 +928,7 @@ static int acpi_cpufreq_resume(struct cp
 
 static struct freq_attr *acpi_cpufreq_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
+	&freqdomain_cpus,
 	NULL,	/* this is a placeholder for cpb, do not remove */
 	NULL,
 };
@@ -947,7 +970,7 @@ static void __init acpi_cpufreq_boost_in
 	/* We create the boost file in any case, though for systems without
 	 * hardware support it will be read-only and hardwired to return 0.
 	 */
-	if (sysfs_create_file(cpufreq_global_kobject, &(global_boost.attr)))
+	if (cpufreq_sysfs_create_file(&(global_boost.attr)))
 		pr_warn(PFX "could not register global boost sysfs file\n");
 	else
 		pr_debug("registered global boost sysfs file\n");
@@ -955,7 +978,7 @@ static void __init acpi_cpufreq_boost_in
 
 static void __exit acpi_cpufreq_boost_exit(void)
 {
-	sysfs_remove_file(cpufreq_global_kobject, &(global_boost.attr));
+	cpufreq_sysfs_remove_file(&(global_boost.attr));
 
 	if (msrs) {
 		unregister_cpu_notifier(&boost_nb);
@@ -1034,4 +1057,11 @@ static const struct x86_cpu_id acpi_cpuf
 };
 MODULE_DEVICE_TABLE(x86cpu, acpi_cpufreq_ids);
 
+static const struct acpi_device_id processor_device_ids[] = {
+	{ACPI_PROCESSOR_OBJECT_HID, },
+	{ACPI_PROCESSOR_DEVICE_HID, },
+	{},
+};
+MODULE_DEVICE_TABLE(acpi, processor_device_ids);
+
 MODULE_ALIAS("acpi");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/arm_big_little.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/arm_big_little.c
--- linux-libre-3.10-gnu/drivers/cpufreq/arm_big_little.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/arm_big_little.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,11 +84,9 @@ static int bL_cpufreq_set_target(struct
 	ret = clk_set_rate(clk[cur_cluster], freqs.new * 1000);
 	if (ret) {
 		pr_err("clk_set_rate failed: %d\n", ret);
-		return ret;
+		freqs.new = freqs.old;
 	}
 
-	policy->cur = freqs.new;
-
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/blackfin-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/blackfin-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/blackfin-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/blackfin-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,23 +20,23 @@
 
 
 /* this is the table of CCLK frequencies, in Hz */
-/* .index is the entry in the auxiliary dpm_state_table[] */
+/* .driver_data is the entry in the auxiliary dpm_state_table[] */
 static struct cpufreq_frequency_table bfin_freq_table[] = {
 	{
 		.frequency = CPUFREQ_TABLE_END,
-		.index = 0,
+		.driver_data = 0,
 	},
 	{
 		.frequency = CPUFREQ_TABLE_END,
-		.index = 1,
+		.driver_data = 1,
 	},
 	{
 		.frequency = CPUFREQ_TABLE_END,
-		.index = 2,
+		.driver_data = 2,
 	},
 	{
 		.frequency = CPUFREQ_TABLE_END,
-		.index = 0,
+		.driver_data = 0,
 	},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2001 Russell King
  *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *            (C) 2013 Viresh Kumar <viresh.kumar@linaro.org>
  *
  *  Oct 2005 - Ashok Raj <ashok.raj@intel.com>
  *	Added handling for CPU hotplug
@@ -12,12 +13,13 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- *
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <asm/cputime.h>
 #include <linux/kernel.h>
+#include <linux/kernel_stat.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/notifier.h>
@@ -25,6 +27,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/tick.h>
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/cpu.h>
@@ -41,11 +44,13 @@
  */
 static struct cpufreq_driver *cpufreq_driver;
 static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
+static DEFINE_RWLOCK(cpufreq_driver_lock);
+static DEFINE_MUTEX(cpufreq_governor_lock);
+
 #ifdef CONFIG_HOTPLUG_CPU
 /* This one keeps track of the previously set governor of a removed CPU */
 static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
 #endif
-static DEFINE_RWLOCK(cpufreq_driver_lock);
 
 /*
  * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
@@ -132,6 +137,51 @@ bool have_governor_per_policy(void)
 {
 	return cpufreq_driver->have_governor_per_policy;
 }
+EXPORT_SYMBOL_GPL(have_governor_per_policy);
+
+struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
+{
+	if (have_governor_per_policy())
+		return &policy->kobj;
+	else
+		return cpufreq_global_kobject;
+}
+EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
+
+static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
+{
+	u64 idle_time;
+	u64 cur_wall_time;
+	u64 busy_time;
+
+	cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
+
+	busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
+	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
+	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
+	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
+	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
+	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
+
+	idle_time = cur_wall_time - busy_time;
+	if (wall)
+		*wall = cputime_to_usecs(cur_wall_time);
+
+	return cputime_to_usecs(idle_time);
+}
+
+u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
+{
+	u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL);
+
+	if (idle_time == -1ULL)
+		return get_cpu_idle_time_jiffy(cpu, wall);
+	else if (!io_busy)
+		idle_time += get_cpu_iowait_time_us(cpu, wall);
+
+	return idle_time;
+}
+EXPORT_SYMBOL_GPL(get_cpu_idle_time);
 
 static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
 {
@@ -150,7 +200,6 @@ static struct cpufreq_policy *__cpufreq_
 	if (!try_module_get(cpufreq_driver->owner))
 		goto err_out_unlock;
 
-
 	/* get the CPU */
 	data = per_cpu(cpufreq_cpu_data, cpu);
 
@@ -220,7 +269,7 @@ static void cpufreq_cpu_put_sysfs(struct
  */
 #ifndef CONFIG_SMP
 static unsigned long l_p_j_ref;
-static unsigned int  l_p_j_ref_freq;
+static unsigned int l_p_j_ref_freq;
 
 static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
 {
@@ -233,7 +282,7 @@ static void adjust_jiffies(unsigned long
 		pr_debug("saving %lu as reference value for loops_per_jiffy; "
 			"freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
 	}
-	if ((val == CPUFREQ_POSTCHANGE  && ci->old != ci->new) ||
+	if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
 	    (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
 		loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
 								ci->new);
@@ -248,8 +297,7 @@ static inline void adjust_jiffies(unsign
 }
 #endif
 
-
-void __cpufreq_notify_transition(struct cpufreq_policy *policy,
+static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
 		struct cpufreq_freqs *freqs, unsigned int state)
 {
 	BUG_ON(irqs_disabled());
@@ -264,6 +312,13 @@ void __cpufreq_notify_transition(struct
 	switch (state) {
 
 	case CPUFREQ_PRECHANGE:
+		if (WARN(policy->transition_ongoing ==
+					cpumask_weight(policy->cpus),
+				"In middle of another frequency transition\n"))
+			return;
+
+		policy->transition_ongoing++;
+
 		/* detect if the driver reported a value as "old frequency"
 		 * which is not equal to what the cpufreq core thinks is
 		 * "old frequency".
@@ -283,6 +338,12 @@ void __cpufreq_notify_transition(struct
 		break;
 
 	case CPUFREQ_POSTCHANGE:
+		if (WARN(!policy->transition_ongoing,
+				"No frequency transition in progress\n"))
+			return;
+
+		policy->transition_ongoing--;
+
 		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
 		pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
 			(unsigned long)freqs->cpu);
@@ -294,6 +355,7 @@ void __cpufreq_notify_transition(struct
 		break;
 	}
 }
+
 /**
  * cpufreq_notify_transition - call notifier chain and adjust_jiffies
  * on frequency transition.
@@ -311,7 +373,6 @@ void cpufreq_notify_transition(struct cp
 EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
 
 
-
 /*********************************************************************
  *                          SYSFS INTERFACE                          *
  *********************************************************************/
@@ -376,7 +437,6 @@ out:
 	return err;
 }
 
-
 /**
  * cpufreq_per_cpu_attr_read() / show_##file_name() -
  * print out cpufreq information
@@ -441,7 +501,6 @@ static ssize_t show_cpuinfo_cur_freq(str
 	return sprintf(buf, "%u\n", cur_freq);
 }
 
-
 /**
  * show_scaling_governor - show the current policy for the specified CPU
  */
@@ -457,7 +516,6 @@ static ssize_t show_scaling_governor(str
 	return -EINVAL;
 }
 
-
 /**
  * store_scaling_governor - store policy for the specified CPU
  */
@@ -480,8 +538,10 @@ static ssize_t store_scaling_governor(st
 						&new_policy.governor))
 		return -EINVAL;
 
-	/* Do not use cpufreq_set_policy here or the user_policy.max
-	   will be wrongly overridden */
+	/*
+	 * Do not use cpufreq_set_policy here or the user_policy.max
+	 * will be wrongly overridden
+	 */
 	ret = __cpufreq_set_policy(policy, &new_policy);
 
 	policy->user_policy.policy = policy->policy;
@@ -526,7 +586,7 @@ out:
 	return i;
 }
 
-static ssize_t show_cpus(const struct cpumask *mask, char *buf)
+ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf)
 {
 	ssize_t i = 0;
 	unsigned int cpu;
@@ -541,6 +601,7 @@ static ssize_t show_cpus(const struct cp
 	i += sprintf(&buf[i], "\n");
 	return i;
 }
+EXPORT_SYMBOL_GPL(cpufreq_show_cpus);
 
 /**
  * show_related_cpus - show the CPUs affected by each transition even if
@@ -548,7 +609,7 @@ static ssize_t show_cpus(const struct cp
  */
 static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
 {
-	return show_cpus(policy->related_cpus, buf);
+	return cpufreq_show_cpus(policy->related_cpus, buf);
 }
 
 /**
@@ -556,7 +617,7 @@ static ssize_t show_related_cpus(struct
  */
 static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
 {
-	return show_cpus(policy->cpus, buf);
+	return cpufreq_show_cpus(policy->cpus, buf);
 }
 
 static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
@@ -630,9 +691,6 @@ static struct attribute *default_attrs[]
 	NULL
 };
 
-struct kobject *cpufreq_global_kobject;
-EXPORT_SYMBOL(cpufreq_global_kobject);
-
 #define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
 #define to_attr(a) container_of(a, struct freq_attr, attr)
 
@@ -703,6 +761,49 @@ static struct kobj_type ktype_cpufreq =
 	.release	= cpufreq_sysfs_release,
 };
 
+struct kobject *cpufreq_global_kobject;
+EXPORT_SYMBOL(cpufreq_global_kobject);
+
+static int cpufreq_global_kobject_usage;
+
+int cpufreq_get_global_kobject(void)
+{
+	if (!cpufreq_global_kobject_usage++)
+		return kobject_add(cpufreq_global_kobject,
+				&cpu_subsys.dev_root->kobj, "%s", "cpufreq");
+
+	return 0;
+}
+EXPORT_SYMBOL(cpufreq_get_global_kobject);
+
+void cpufreq_put_global_kobject(void)
+{
+	if (!--cpufreq_global_kobject_usage)
+		kobject_del(cpufreq_global_kobject);
+}
+EXPORT_SYMBOL(cpufreq_put_global_kobject);
+
+int cpufreq_sysfs_create_file(const struct attribute *attr)
+{
+	int ret = cpufreq_get_global_kobject();
+
+	if (!ret) {
+		ret = sysfs_create_file(cpufreq_global_kobject, attr);
+		if (ret)
+			cpufreq_put_global_kobject();
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(cpufreq_sysfs_create_file);
+
+void cpufreq_sysfs_remove_file(const struct attribute *attr)
+{
+	sysfs_remove_file(cpufreq_global_kobject, attr);
+	cpufreq_put_global_kobject();
+}
+EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
+
 /* symlink affected CPUs */
 static int cpufreq_add_dev_symlink(unsigned int cpu,
 				   struct cpufreq_policy *policy)
@@ -1005,7 +1106,8 @@ static void update_policy_cpu(struct cpu
  * Caller should already have policy_rwsem in write mode for this CPU.
  * This routine frees the rwsem before returning.
  */
-static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
+static int __cpufreq_remove_dev(struct device *dev,
+		struct subsys_interface *sif)
 {
 	unsigned int cpu = dev->id, ret, cpus;
 	unsigned long flags;
@@ -1075,14 +1177,11 @@ static int __cpufreq_remove_dev(struct d
 				__func__, cpu_dev->id, cpu);
 	}
 
-	if ((cpus == 1) && (cpufreq_driver->target))
-		__cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
-
-	pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
-	cpufreq_cpu_put(data);
-
 	/* If cpu is last user of policy, free policy */
 	if (cpus == 1) {
+		if (cpufreq_driver->target)
+			__cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
+
 		lock_policy_rwsem_read(cpu);
 		kobj = &data->kobj;
 		cmp = &data->kobj_unregister;
@@ -1103,16 +1202,19 @@ static int __cpufreq_remove_dev(struct d
 		free_cpumask_var(data->related_cpus);
 		free_cpumask_var(data->cpus);
 		kfree(data);
-	} else if (cpufreq_driver->target) {
-		__cpufreq_governor(data, CPUFREQ_GOV_START);
-		__cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
+	} else {
+		pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
+		cpufreq_cpu_put(data);
+		if (cpufreq_driver->target) {
+			__cpufreq_governor(data, CPUFREQ_GOV_START);
+			__cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
+		}
 	}
 
 	per_cpu(cpufreq_policy_cpu, cpu) = -1;
 	return 0;
 }
 
-
 static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
 {
 	unsigned int cpu = dev->id;
@@ -1125,7 +1227,6 @@ static int cpufreq_remove_dev(struct dev
 	return retval;
 }
 
-
 static void handle_update(struct work_struct *work)
 {
 	struct cpufreq_policy *policy =
@@ -1136,7 +1237,8 @@ static void handle_update(struct work_st
 }
 
 /**
- *	cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
+ *	cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're
+ *	in deep trouble.
  *	@cpu: cpu number
  *	@old_freq: CPU frequency the kernel thinks the CPU runs at
  *	@new_freq: CPU frequency the CPU actually runs at
@@ -1151,7 +1253,6 @@ static void cpufreq_out_of_sync(unsigned
 	struct cpufreq_freqs freqs;
 	unsigned long flags;
 
-
 	pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
 	       "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
 
@@ -1166,7 +1267,6 @@ static void cpufreq_out_of_sync(unsigned
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 }
 
-
 /**
  * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
  * @cpu: CPU number
@@ -1212,7 +1312,6 @@ unsigned int cpufreq_quick_get_max(unsig
 }
 EXPORT_SYMBOL(cpufreq_quick_get_max);
 
-
 static unsigned int __cpufreq_get(unsigned int cpu)
 {
 	struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
@@ -1271,7 +1370,6 @@ static struct subsys_interface cpufreq_i
 	.remove_dev	= cpufreq_remove_dev,
 };
 
-
 /**
  * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
  *
@@ -1408,11 +1506,10 @@ int cpufreq_register_notifier(struct not
 }
 EXPORT_SYMBOL(cpufreq_register_notifier);
 
-
 /**
  *	cpufreq_unregister_notifier - unregister a driver with cpufreq
  *	@nb: notifier block to be unregistered
- *      @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
+ *	@list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
  *
  *	Remove a driver from the CPU frequency notifier list.
  *
@@ -1448,7 +1545,6 @@ EXPORT_SYMBOL(cpufreq_unregister_notifie
  *                              GOVERNORS                            *
  *********************************************************************/
 
-
 int __cpufreq_driver_target(struct cpufreq_policy *policy,
 			    unsigned int target_freq,
 			    unsigned int relation)
@@ -1458,6 +1554,8 @@ int __cpufreq_driver_target(struct cpufr
 
 	if (cpufreq_disabled())
 		return -ENODEV;
+	if (policy->transition_ongoing)
+		return -EBUSY;
 
 	/* Make sure that target_freq is within supported range */
 	if (target_freq > policy->max)
@@ -1484,10 +1582,6 @@ int cpufreq_driver_target(struct cpufreq
 {
 	int ret = -EINVAL;
 
-	policy = cpufreq_cpu_get(policy->cpu);
-	if (!policy)
-		goto no_policy;
-
 	if (unlikely(lock_policy_rwsem_write(policy->cpu)))
 		goto fail;
 
@@ -1496,30 +1590,19 @@ int cpufreq_driver_target(struct cpufreq
 	unlock_policy_rwsem_write(policy->cpu);
 
 fail:
-	cpufreq_cpu_put(policy);
-no_policy:
 	return ret;
 }
 EXPORT_SYMBOL_GPL(cpufreq_driver_target);
 
 int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
 {
-	int ret = 0;
-
 	if (cpufreq_disabled())
-		return ret;
+		return 0;
 
 	if (!cpufreq_driver->getavg)
 		return 0;
 
-	policy = cpufreq_cpu_get(policy->cpu);
-	if (!policy)
-		return -EINVAL;
-
-	ret = cpufreq_driver->getavg(policy, cpu);
-
-	cpufreq_cpu_put(policy);
-	return ret;
+	return cpufreq_driver->getavg(policy, cpu);
 }
 EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
 
@@ -1562,6 +1645,21 @@ static int __cpufreq_governor(struct cpu
 
 	pr_debug("__cpufreq_governor for CPU %u, event %u\n",
 						policy->cpu, event);
+
+	mutex_lock(&cpufreq_governor_lock);
+	if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
+	    (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
+		mutex_unlock(&cpufreq_governor_lock);
+		return -EBUSY;
+	}
+
+	if (event == CPUFREQ_GOV_STOP)
+		policy->governor_enabled = false;
+	else if (event == CPUFREQ_GOV_START)
+		policy->governor_enabled = true;
+
+	mutex_unlock(&cpufreq_governor_lock);
+
 	ret = policy->governor->governor(policy, event);
 
 	if (!ret) {
@@ -1569,6 +1667,14 @@ static int __cpufreq_governor(struct cpu
 			policy->governor->initialized++;
 		else if (event == CPUFREQ_GOV_POLICY_EXIT)
 			policy->governor->initialized--;
+	} else {
+		/* Restore original values */
+		mutex_lock(&cpufreq_governor_lock);
+		if (event == CPUFREQ_GOV_STOP)
+			policy->governor_enabled = true;
+		else if (event == CPUFREQ_GOV_START)
+			policy->governor_enabled = false;
+		mutex_unlock(&cpufreq_governor_lock);
 	}
 
 	/* we keep one module reference alive for
@@ -1581,7 +1687,6 @@ static int __cpufreq_governor(struct cpu
 	return ret;
 }
 
-
 int cpufreq_register_governor(struct cpufreq_governor *governor)
 {
 	int err;
@@ -1606,7 +1711,6 @@ int cpufreq_register_governor(struct cpu
 }
 EXPORT_SYMBOL_GPL(cpufreq_register_governor);
 
-
 void cpufreq_unregister_governor(struct cpufreq_governor *governor)
 {
 #ifdef CONFIG_HOTPLUG_CPU
@@ -1636,7 +1740,6 @@ void cpufreq_unregister_governor(struct
 EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
 
 
-
 /*********************************************************************
  *                          POLICY INTERFACE                         *
  *********************************************************************/
@@ -1665,7 +1768,6 @@ int cpufreq_get_policy(struct cpufreq_po
 }
 EXPORT_SYMBOL(cpufreq_get_policy);
 
-
 /*
  * data   : current policy.
  * policy : policy to be set.
@@ -1699,8 +1801,10 @@ static int __cpufreq_set_policy(struct c
 	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
 			CPUFREQ_INCOMPATIBLE, policy);
 
-	/* verify the cpu speed can be set within this limit,
-	   which might be different to the first one */
+	/*
+	 * verify the cpu speed can be set within this limit, which might be
+	 * different to the first one
+	 */
 	ret = cpufreq_driver->verify(policy);
 	if (ret)
 		goto error_out;
@@ -1802,8 +1906,10 @@ int cpufreq_update_policy(unsigned int c
 	policy.policy = data->user_policy.policy;
 	policy.governor = data->user_policy.governor;
 
-	/* BIOS might change freq behind our back
-	  -> ask driver for current freq and notify governors about a change */
+	/*
+	 * BIOS might change freq behind our back
+	 * -> ask driver for current freq and notify governors about a change
+	 */
 	if (cpufreq_driver->get) {
 		policy.cur = cpufreq_driver->get(cpu);
 		if (!data->cur) {
@@ -1827,7 +1933,7 @@ no_policy:
 }
 EXPORT_SYMBOL(cpufreq_update_policy);
 
-static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
+static int cpufreq_cpu_callback(struct notifier_block *nfb,
 					unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long)hcpu;
@@ -1837,13 +1943,15 @@ static int __cpuinit cpufreq_cpu_callbac
 	if (dev) {
 		switch (action) {
 		case CPU_ONLINE:
+		case CPU_ONLINE_FROZEN:
 			cpufreq_add_dev(dev, NULL);
 			break;
 		case CPU_DOWN_PREPARE:
-		case CPU_UP_CANCELED_FROZEN:
+		case CPU_DOWN_PREPARE_FROZEN:
 			__cpufreq_remove_dev(dev, NULL);
 			break;
 		case CPU_DOWN_FAILED:
+		case CPU_DOWN_FAILED_FROZEN:
 			cpufreq_add_dev(dev, NULL);
 			break;
 		}
@@ -1852,7 +1960,7 @@ static int __cpuinit cpufreq_cpu_callbac
 }
 
 static struct notifier_block __refdata cpufreq_cpu_notifier = {
-    .notifier_call = cpufreq_cpu_callback,
+	.notifier_call = cpufreq_cpu_callback,
 };
 
 /*********************************************************************
@@ -1864,7 +1972,7 @@ static struct notifier_block __refdata c
  * @driver_data: A struct cpufreq_driver containing the values#
  * submitted by the CPU Frequency driver.
  *
- *   Registers a CPU Frequency driver to this core code. This code
+ * Registers a CPU Frequency driver to this core code. This code
  * returns zero on success, -EBUSY when another driver got here first
  * (and isn't unregistered in the meantime).
  *
@@ -1931,11 +2039,10 @@ err_null_driver:
 }
 EXPORT_SYMBOL_GPL(cpufreq_register_driver);
 
-
 /**
  * cpufreq_unregister_driver - unregister the current CPUFreq driver
  *
- *    Unregister the current CPUFreq driver. Only call this if you have
+ * Unregister the current CPUFreq driver. Only call this if you have
  * the right to do so, i.e. if you have succeeded in initialising before!
  * Returns zero if successful, and -EINVAL if the cpufreq_driver is
  * currently not initialised.
@@ -1972,7 +2079,7 @@ static int __init cpufreq_core_init(void
 		init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
 	}
 
-	cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
+	cpufreq_global_kobject = kobject_create();
 	BUG_ON(!cpufreq_global_kobject);
 	register_syscore_ops(&cpufreq_syscore_ops);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_conservative.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_conservative.c
--- linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_conservative.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_conservative.c	2013-08-25 20:43:22.000000000 -0400
@@ -221,8 +221,8 @@ static ssize_t store_down_threshold(stru
 	return count;
 }
 
-static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
-		size_t count)
+static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data,
+		const char *buf, size_t count)
 {
 	struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
 	unsigned int input, j;
@@ -235,10 +235,10 @@ static ssize_t store_ignore_nice(struct
 	if (input > 1)
 		input = 1;
 
-	if (input == cs_tuners->ignore_nice) /* nothing to do */
+	if (input == cs_tuners->ignore_nice_load) /* nothing to do */
 		return count;
 
-	cs_tuners->ignore_nice = input;
+	cs_tuners->ignore_nice_load = input;
 
 	/* we need to re-evaluate prev_cpu_idle */
 	for_each_online_cpu(j) {
@@ -246,7 +246,7 @@ static ssize_t store_ignore_nice(struct
 		dbs_info = &per_cpu(cs_cpu_dbs_info, j);
 		dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j,
 					&dbs_info->cdbs.prev_cpu_wall, 0);
-		if (cs_tuners->ignore_nice)
+		if (cs_tuners->ignore_nice_load)
 			dbs_info->cdbs.prev_cpu_nice =
 				kcpustat_cpu(j).cpustat[CPUTIME_NICE];
 	}
@@ -279,7 +279,7 @@ show_store_one(cs, sampling_rate);
 show_store_one(cs, sampling_down_factor);
 show_store_one(cs, up_threshold);
 show_store_one(cs, down_threshold);
-show_store_one(cs, ignore_nice);
+show_store_one(cs, ignore_nice_load);
 show_store_one(cs, freq_step);
 declare_show_sampling_rate_min(cs);
 
@@ -287,7 +287,7 @@ gov_sys_pol_attr_rw(sampling_rate);
 gov_sys_pol_attr_rw(sampling_down_factor);
 gov_sys_pol_attr_rw(up_threshold);
 gov_sys_pol_attr_rw(down_threshold);
-gov_sys_pol_attr_rw(ignore_nice);
+gov_sys_pol_attr_rw(ignore_nice_load);
 gov_sys_pol_attr_rw(freq_step);
 gov_sys_pol_attr_ro(sampling_rate_min);
 
@@ -297,7 +297,7 @@ static struct attribute *dbs_attributes_
 	&sampling_down_factor_gov_sys.attr,
 	&up_threshold_gov_sys.attr,
 	&down_threshold_gov_sys.attr,
-	&ignore_nice_gov_sys.attr,
+	&ignore_nice_load_gov_sys.attr,
 	&freq_step_gov_sys.attr,
 	NULL
 };
@@ -313,7 +313,7 @@ static struct attribute *dbs_attributes_
 	&sampling_down_factor_gov_pol.attr,
 	&up_threshold_gov_pol.attr,
 	&down_threshold_gov_pol.attr,
-	&ignore_nice_gov_pol.attr,
+	&ignore_nice_load_gov_pol.attr,
 	&freq_step_gov_pol.attr,
 	NULL
 };
@@ -338,7 +338,7 @@ static int cs_init(struct dbs_data *dbs_
 	tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
 	tuners->down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD;
 	tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
-	tuners->ignore_nice = 0;
+	tuners->ignore_nice_load = 0;
 	tuners->freq_step = DEF_FREQUENCY_STEP;
 
 	dbs_data->tuners = tuners;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_governor.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_governor.c
--- linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_governor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_governor.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,21 +23,11 @@
 #include <linux/kernel_stat.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
-#include <linux/tick.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
-#include <linux/cpu.h>
 
 #include "cpufreq_governor.h"
 
-static struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
-{
-	if (have_governor_per_policy())
-		return &policy->kobj;
-	else
-		return cpufreq_global_kobject;
-}
-
 static struct attribute_group *get_sysfs_attr(struct dbs_data *dbs_data)
 {
 	if (have_governor_per_policy())
@@ -46,41 +36,6 @@ static struct attribute_group *get_sysfs
 		return dbs_data->cdata->attr_group_gov_sys;
 }
 
-static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
-{
-	u64 idle_time;
-	u64 cur_wall_time;
-	u64 busy_time;
-
-	cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
-
-	busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
-	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
-	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
-	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
-	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
-	busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
-
-	idle_time = cur_wall_time - busy_time;
-	if (wall)
-		*wall = cputime_to_usecs(cur_wall_time);
-
-	return cputime_to_usecs(idle_time);
-}
-
-u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
-{
-	u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL);
-
-	if (idle_time == -1ULL)
-		return get_cpu_idle_time_jiffy(cpu, wall);
-	else if (!io_busy)
-		idle_time += get_cpu_iowait_time_us(cpu, wall);
-
-	return idle_time;
-}
-EXPORT_SYMBOL_GPL(get_cpu_idle_time);
-
 void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
 {
 	struct cpu_dbs_common_info *cdbs = dbs_data->cdata->get_cpu_cdbs(cpu);
@@ -92,9 +47,9 @@ void dbs_check_cpu(struct dbs_data *dbs_
 	unsigned int j;
 
 	if (dbs_data->cdata->governor == GOV_ONDEMAND)
-		ignore_nice = od_tuners->ignore_nice;
+		ignore_nice = od_tuners->ignore_nice_load;
 	else
-		ignore_nice = cs_tuners->ignore_nice;
+		ignore_nice = cs_tuners->ignore_nice_load;
 
 	policy = cdbs->cur_policy;
 
@@ -181,10 +136,8 @@ void gov_queue_work(struct dbs_data *dbs
 	if (!all_cpus) {
 		__gov_queue_work(smp_processor_id(), dbs_data, delay);
 	} else {
-		get_online_cpus();
 		for_each_cpu(i, policy->cpus)
 			__gov_queue_work(i, dbs_data, delay);
-		put_online_cpus();
 	}
 }
 EXPORT_SYMBOL_GPL(gov_queue_work);
@@ -278,6 +231,9 @@ int cpufreq_governor_dbs(struct cpufreq_
 			return rc;
 		}
 
+		if (!have_governor_per_policy())
+			WARN_ON(cpufreq_get_global_kobject());
+
 		rc = sysfs_create_group(get_governor_parent_kobj(policy),
 				get_sysfs_attr(dbs_data));
 		if (rc) {
@@ -316,6 +272,9 @@ int cpufreq_governor_dbs(struct cpufreq_
 			sysfs_remove_group(get_governor_parent_kobj(policy),
 					get_sysfs_attr(dbs_data));
 
+			if (!have_governor_per_policy())
+				cpufreq_put_global_kobject();
+
 			if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
 				(policy->governor->initialized == 1)) {
 				struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
@@ -339,12 +298,12 @@ int cpufreq_governor_dbs(struct cpufreq_
 		cs_tuners = dbs_data->tuners;
 		cs_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
 		sampling_rate = cs_tuners->sampling_rate;
-		ignore_nice = cs_tuners->ignore_nice;
+		ignore_nice = cs_tuners->ignore_nice_load;
 	} else {
 		od_tuners = dbs_data->tuners;
 		od_dbs_info = dbs_data->cdata->get_cpu_dbs_info_s(cpu);
 		sampling_rate = od_tuners->sampling_rate;
-		ignore_nice = od_tuners->ignore_nice;
+		ignore_nice = od_tuners->ignore_nice_load;
 		od_ops = dbs_data->cdata->gov_ops;
 		io_busy = od_tuners->io_is_busy;
 	}
@@ -404,6 +363,7 @@ int cpufreq_governor_dbs(struct cpufreq_
 
 		mutex_lock(&dbs_data->mutex);
 		mutex_destroy(&cpu_cdbs->timer_mutex);
+		cpu_cdbs->cur_policy = NULL;
 
 		mutex_unlock(&dbs_data->mutex);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_governor.h linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_governor.h
--- linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_governor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_governor.h	2013-08-25 20:43:22.000000000 -0400
@@ -81,7 +81,7 @@ static ssize_t show_##file_name##_gov_sy
 	return sprintf(buf, "%u\n", tuners->file_name);			\
 }									\
 									\
-static ssize_t show_##file_name##_gov_pol					\
+static ssize_t show_##file_name##_gov_pol				\
 (struct cpufreq_policy *policy, char *buf)				\
 {									\
 	struct dbs_data *dbs_data = policy->governor_data;		\
@@ -91,7 +91,7 @@ static ssize_t show_##file_name##_gov_po
 
 #define store_one(_gov, file_name)					\
 static ssize_t store_##file_name##_gov_sys				\
-(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count)	\
+(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) \
 {									\
 	struct dbs_data *dbs_data = _gov##_dbs_cdata.gdbs_data;		\
 	return store_##file_name(dbs_data, buf, count);			\
@@ -165,7 +165,7 @@ struct cs_cpu_dbs_info_s {
 
 /* Per policy Governers sysfs tunables */
 struct od_dbs_tuners {
-	unsigned int ignore_nice;
+	unsigned int ignore_nice_load;
 	unsigned int sampling_rate;
 	unsigned int sampling_down_factor;
 	unsigned int up_threshold;
@@ -175,7 +175,7 @@ struct od_dbs_tuners {
 };
 
 struct cs_dbs_tuners {
-	unsigned int ignore_nice;
+	unsigned int ignore_nice_load;
 	unsigned int sampling_rate;
 	unsigned int sampling_down_factor;
 	unsigned int up_threshold;
@@ -256,7 +256,6 @@ static ssize_t show_sampling_rate_min_go
 	return sprintf(buf, "%u\n", dbs_data->min_sampling_rate);	\
 }
 
-u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy);
 void dbs_check_cpu(struct dbs_data *dbs_data, int cpu);
 bool need_load_eval(struct cpu_dbs_common_info *cdbs,
 		unsigned int sampling_rate);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_ondemand.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_ondemand.c
--- linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_ondemand.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_ondemand.c	2013-08-25 20:43:22.000000000 -0400
@@ -403,8 +403,8 @@ static ssize_t store_sampling_down_facto
 	return count;
 }
 
-static ssize_t store_ignore_nice(struct dbs_data *dbs_data, const char *buf,
-		size_t count)
+static ssize_t store_ignore_nice_load(struct dbs_data *dbs_data,
+		const char *buf, size_t count)
 {
 	struct od_dbs_tuners *od_tuners = dbs_data->tuners;
 	unsigned int input;
@@ -419,10 +419,10 @@ static ssize_t store_ignore_nice(struct
 	if (input > 1)
 		input = 1;
 
-	if (input == od_tuners->ignore_nice) { /* nothing to do */
+	if (input == od_tuners->ignore_nice_load) { /* nothing to do */
 		return count;
 	}
-	od_tuners->ignore_nice = input;
+	od_tuners->ignore_nice_load = input;
 
 	/* we need to re-evaluate prev_cpu_idle */
 	for_each_online_cpu(j) {
@@ -430,7 +430,7 @@ static ssize_t store_ignore_nice(struct
 		dbs_info = &per_cpu(od_cpu_dbs_info, j);
 		dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j,
 			&dbs_info->cdbs.prev_cpu_wall, od_tuners->io_is_busy);
-		if (od_tuners->ignore_nice)
+		if (od_tuners->ignore_nice_load)
 			dbs_info->cdbs.prev_cpu_nice =
 				kcpustat_cpu(j).cpustat[CPUTIME_NICE];
 
@@ -461,7 +461,7 @@ show_store_one(od, sampling_rate);
 show_store_one(od, io_is_busy);
 show_store_one(od, up_threshold);
 show_store_one(od, sampling_down_factor);
-show_store_one(od, ignore_nice);
+show_store_one(od, ignore_nice_load);
 show_store_one(od, powersave_bias);
 declare_show_sampling_rate_min(od);
 
@@ -469,7 +469,7 @@ gov_sys_pol_attr_rw(sampling_rate);
 gov_sys_pol_attr_rw(io_is_busy);
 gov_sys_pol_attr_rw(up_threshold);
 gov_sys_pol_attr_rw(sampling_down_factor);
-gov_sys_pol_attr_rw(ignore_nice);
+gov_sys_pol_attr_rw(ignore_nice_load);
 gov_sys_pol_attr_rw(powersave_bias);
 gov_sys_pol_attr_ro(sampling_rate_min);
 
@@ -478,7 +478,7 @@ static struct attribute *dbs_attributes_
 	&sampling_rate_gov_sys.attr,
 	&up_threshold_gov_sys.attr,
 	&sampling_down_factor_gov_sys.attr,
-	&ignore_nice_gov_sys.attr,
+	&ignore_nice_load_gov_sys.attr,
 	&powersave_bias_gov_sys.attr,
 	&io_is_busy_gov_sys.attr,
 	NULL
@@ -494,7 +494,7 @@ static struct attribute *dbs_attributes_
 	&sampling_rate_gov_pol.attr,
 	&up_threshold_gov_pol.attr,
 	&sampling_down_factor_gov_pol.attr,
-	&ignore_nice_gov_pol.attr,
+	&ignore_nice_load_gov_pol.attr,
 	&powersave_bias_gov_pol.attr,
 	&io_is_busy_gov_pol.attr,
 	NULL
@@ -544,7 +544,7 @@ static int od_init(struct dbs_data *dbs_
 	}
 
 	tuners->sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR;
-	tuners->ignore_nice = 0;
+	tuners->ignore_nice_load = 0;
 	tuners->powersave_bias = default_powersave_bias;
 	tuners->io_is_busy = should_io_be_busy();
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_performance.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_performance.c
--- linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_performance.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_performance.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 
-
 static int cpufreq_governor_performance(struct cpufreq_policy *policy,
 					unsigned int event)
 {
@@ -44,19 +43,16 @@ struct cpufreq_governor cpufreq_gov_perf
 	.owner		= THIS_MODULE,
 };
 
-
 static int __init cpufreq_gov_performance_init(void)
 {
 	return cpufreq_register_governor(&cpufreq_gov_performance);
 }
 
-
 static void __exit cpufreq_gov_performance_exit(void)
 {
 	cpufreq_unregister_governor(&cpufreq_gov_performance);
 }
 
-
 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION("CPUfreq policy governor 'performance'");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_powersave.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_powersave.c
--- linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_powersave.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_powersave.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- *  linux/drivers/cpufreq/cpufreq_powersave.c
+ * linux/drivers/cpufreq/cpufreq_powersave.c
  *
- *  Copyright (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ * Copyright (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
  *
  *
  * This program is free software; you can redistribute it and/or modify
@@ -48,13 +48,11 @@ static int __init cpufreq_gov_powersave_
 	return cpufreq_register_governor(&cpufreq_gov_powersave);
 }
 
-
 static void __exit cpufreq_gov_powersave_exit(void)
 {
 	cpufreq_unregister_governor(&cpufreq_gov_powersave);
 }
 
-
 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION("CPUfreq policy governor 'powersave'");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_stats.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_stats.c
--- linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_stats.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_stats.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@ static spinlock_t cpufreq_stats_lock;
 struct cpufreq_stats {
 	unsigned int cpu;
 	unsigned int total_trans;
-	unsigned long long  last_time;
+	unsigned long long last_time;
 	unsigned int max_state;
 	unsigned int state_num;
 	unsigned int last_index;
@@ -116,7 +116,7 @@ static ssize_t show_trans_table(struct c
 		len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ",
 				stat->freq_table[i]);
 
-		for (j = 0; j < stat->state_num; j++)   {
+		for (j = 0; j < stat->state_num; j++) {
 			if (len >= PAGE_SIZE)
 				break;
 			len += snprintf(buf + len, PAGE_SIZE - len, "%9u ",
@@ -341,7 +341,7 @@ static int cpufreq_stat_notifier_trans(s
 	return 0;
 }
 
-static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb,
+static int cpufreq_stat_cpu_callback(struct notifier_block *nfb,
 					       unsigned long action,
 					       void *hcpu)
 {
@@ -349,16 +349,15 @@ static int __cpuinit cpufreq_stat_cpu_ca
 
 	switch (action) {
 	case CPU_ONLINE:
+	case CPU_ONLINE_FROZEN:
 		cpufreq_update_policy(cpu);
 		break;
 	case CPU_DOWN_PREPARE:
+	case CPU_DOWN_PREPARE_FROZEN:
 		cpufreq_stats_free_sysfs(cpu);
 		break;
 	case CPU_DEAD:
-		cpufreq_stats_free_table(cpu);
-		break;
-	case CPU_UP_CANCELED_FROZEN:
-		cpufreq_stats_free_sysfs(cpu);
+	case CPU_DEAD_FROZEN:
 		cpufreq_stats_free_table(cpu);
 		break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_userspace.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_userspace.c
--- linux-libre-3.10-gnu/drivers/cpufreq/cpufreq_userspace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/cpufreq_userspace.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,55 +13,13 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/smp.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
 #include <linux/cpufreq.h>
-#include <linux/cpu.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/sysfs.h>
+#include <linux/init.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 
-/**
- * A few values needed by the userspace governor
- */
-static DEFINE_PER_CPU(unsigned int, cpu_max_freq);
-static DEFINE_PER_CPU(unsigned int, cpu_min_freq);
-static DEFINE_PER_CPU(unsigned int, cpu_cur_freq); /* current CPU freq */
-static DEFINE_PER_CPU(unsigned int, cpu_set_freq); /* CPU freq desired by
-							userspace */
 static DEFINE_PER_CPU(unsigned int, cpu_is_managed);
-
 static DEFINE_MUTEX(userspace_mutex);
-static int cpus_using_userspace_governor;
-
-/* keep track of frequency transitions */
-static int
-userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
-	void *data)
-{
-	struct cpufreq_freqs *freq = data;
-
-	if (!per_cpu(cpu_is_managed, freq->cpu))
-		return 0;
-
-	if (val == CPUFREQ_POSTCHANGE) {
-		pr_debug("saving cpu_cur_freq of cpu %u to be %u kHz\n",
-				freq->cpu, freq->new);
-		per_cpu(cpu_cur_freq, freq->cpu) = freq->new;
-	}
-
-	return 0;
-}
-
-static struct notifier_block userspace_cpufreq_notifier_block = {
-	.notifier_call  = userspace_cpufreq_notifier
-};
-
 
 /**
  * cpufreq_set - set the CPU frequency
@@ -80,13 +38,6 @@ static int cpufreq_set(struct cpufreq_po
 	if (!per_cpu(cpu_is_managed, policy->cpu))
 		goto err;
 
-	per_cpu(cpu_set_freq, policy->cpu) = freq;
-
-	if (freq < per_cpu(cpu_min_freq, policy->cpu))
-		freq = per_cpu(cpu_min_freq, policy->cpu);
-	if (freq > per_cpu(cpu_max_freq, policy->cpu))
-		freq = per_cpu(cpu_max_freq, policy->cpu);
-
 	/*
 	 * We're safe from concurrent calls to ->target() here
 	 * as we hold the userspace_mutex lock. If we were calling
@@ -104,10 +55,9 @@ static int cpufreq_set(struct cpufreq_po
 	return ret;
 }
 
-
 static ssize_t show_speed(struct cpufreq_policy *policy, char *buf)
 {
-	return sprintf(buf, "%u\n", per_cpu(cpu_cur_freq, policy->cpu));
+	return sprintf(buf, "%u\n", policy->cur);
 }
 
 static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
@@ -119,73 +69,37 @@ static int cpufreq_governor_userspace(st
 	switch (event) {
 	case CPUFREQ_GOV_START:
 		BUG_ON(!policy->cur);
-		mutex_lock(&userspace_mutex);
-
-		if (cpus_using_userspace_governor == 0) {
-			cpufreq_register_notifier(
-					&userspace_cpufreq_notifier_block,
-					CPUFREQ_TRANSITION_NOTIFIER);
-		}
-		cpus_using_userspace_governor++;
+		pr_debug("started managing cpu %u\n", cpu);
 
+		mutex_lock(&userspace_mutex);
 		per_cpu(cpu_is_managed, cpu) = 1;
-		per_cpu(cpu_min_freq, cpu) = policy->min;
-		per_cpu(cpu_max_freq, cpu) = policy->max;
-		per_cpu(cpu_cur_freq, cpu) = policy->cur;
-		per_cpu(cpu_set_freq, cpu) = policy->cur;
-		pr_debug("managing cpu %u started "
-			"(%u - %u kHz, currently %u kHz)\n",
-				cpu,
-				per_cpu(cpu_min_freq, cpu),
-				per_cpu(cpu_max_freq, cpu),
-				per_cpu(cpu_cur_freq, cpu));
-
 		mutex_unlock(&userspace_mutex);
 		break;
 	case CPUFREQ_GOV_STOP:
-		mutex_lock(&userspace_mutex);
-		cpus_using_userspace_governor--;
-		if (cpus_using_userspace_governor == 0) {
-			cpufreq_unregister_notifier(
-					&userspace_cpufreq_notifier_block,
-					CPUFREQ_TRANSITION_NOTIFIER);
-		}
+		pr_debug("managing cpu %u stopped\n", cpu);
 
+		mutex_lock(&userspace_mutex);
 		per_cpu(cpu_is_managed, cpu) = 0;
-		per_cpu(cpu_min_freq, cpu) = 0;
-		per_cpu(cpu_max_freq, cpu) = 0;
-		per_cpu(cpu_set_freq, cpu) = 0;
-		pr_debug("managing cpu %u stopped\n", cpu);
 		mutex_unlock(&userspace_mutex);
 		break;
 	case CPUFREQ_GOV_LIMITS:
 		mutex_lock(&userspace_mutex);
-		pr_debug("limit event for cpu %u: %u - %u kHz, "
-			"currently %u kHz, last set to %u kHz\n",
+		pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz\n",
 			cpu, policy->min, policy->max,
-			per_cpu(cpu_cur_freq, cpu),
-			per_cpu(cpu_set_freq, cpu));
-		if (policy->max < per_cpu(cpu_set_freq, cpu)) {
+			policy->cur);
+
+		if (policy->max < policy->cur)
 			__cpufreq_driver_target(policy, policy->max,
 						CPUFREQ_RELATION_H);
-		} else if (policy->min > per_cpu(cpu_set_freq, cpu)) {
+		else if (policy->min > policy->cur)
 			__cpufreq_driver_target(policy, policy->min,
 						CPUFREQ_RELATION_L);
-		} else {
-			__cpufreq_driver_target(policy,
-						per_cpu(cpu_set_freq, cpu),
-						CPUFREQ_RELATION_L);
-		}
-		per_cpu(cpu_min_freq, cpu) = policy->min;
-		per_cpu(cpu_max_freq, cpu) = policy->max;
-		per_cpu(cpu_cur_freq, cpu) = policy->cur;
 		mutex_unlock(&userspace_mutex);
 		break;
 	}
 	return rc;
 }
 
-
 #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
 static
 #endif
@@ -202,13 +116,11 @@ static int __init cpufreq_gov_userspace_
 	return cpufreq_register_governor(&cpufreq_gov_userspace);
 }
 
-
 static void __exit cpufreq_gov_userspace_exit(void)
 {
 	cpufreq_unregister_governor(&cpufreq_gov_userspace);
 }
 
-
 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>, "
 		"Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/davinci-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/davinci-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/davinci-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/davinci-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -114,6 +114,9 @@ static int davinci_target(struct cpufreq
 		pdata->set_voltage(idx);
 
 out:
+	if (ret)
+		freqs.new = freqs.old;
+
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/dbx500-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/dbx500-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/dbx500-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/dbx500-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -57,13 +57,13 @@ static int dbx500_cpufreq_target(struct
 	if (ret) {
 		pr_err("dbx500-cpufreq: Failed to set armss_clk to %d Hz: error %d\n",
 		       freqs.new * 1000, ret);
-		return ret;
+		freqs.new = freqs.old;
 	}
 
 	/* post change notification */
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
-	return 0;
+	return ret;
 }
 
 static unsigned int dbx500_cpufreq_getspeed(unsigned int cpu)
@@ -82,7 +82,7 @@ static unsigned int dbx500_cpufreq_getsp
 	return freq_table[i].frequency;
 }
 
-static int __cpuinit dbx500_cpufreq_init(struct cpufreq_policy *policy)
+static int dbx500_cpufreq_init(struct cpufreq_policy *policy)
 {
 	int res;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/e_powersaver.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/e_powersaver.c
--- linux-libre-3.10-gnu/drivers/cpufreq/e_powersaver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/e_powersaver.c	2013-08-25 20:43:22.000000000 -0400
@@ -161,6 +161,9 @@ postchange:
 		current_multiplier);
 	}
 #endif
+	if (err)
+		freqs.new = freqs.old;
+
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 	return err;
 }
@@ -188,7 +191,7 @@ static int eps_target(struct cpufreq_pol
 	}
 
 	/* Make frequency transition */
-	dest_state = centaur->freq_table[newstate].index & 0xffff;
+	dest_state = centaur->freq_table[newstate].driver_data & 0xffff;
 	ret = eps_set_state(centaur, policy, dest_state);
 	if (ret)
 		printk(KERN_ERR "eps: Timeout!\n");
@@ -380,9 +383,9 @@ static int eps_cpu_init(struct cpufreq_p
 	f_table = &centaur->freq_table[0];
 	if (brand != EPS_BRAND_C7M) {
 		f_table[0].frequency = fsb * min_multiplier;
-		f_table[0].index = (min_multiplier << 8) | min_voltage;
+		f_table[0].driver_data = (min_multiplier << 8) | min_voltage;
 		f_table[1].frequency = fsb * max_multiplier;
-		f_table[1].index = (max_multiplier << 8) | max_voltage;
+		f_table[1].driver_data = (max_multiplier << 8) | max_voltage;
 		f_table[2].frequency = CPUFREQ_TABLE_END;
 	} else {
 		k = 0;
@@ -391,7 +394,7 @@ static int eps_cpu_init(struct cpufreq_p
 		for (i = min_multiplier; i <= max_multiplier; i++) {
 			voltage = (k * step) / 256 + min_voltage;
 			f_table[k].frequency = fsb * i;
-			f_table[k].index = (i << 8) | voltage;
+			f_table[k].driver_data = (i << 8) | voltage;
 			k++;
 		}
 		f_table[k].frequency = CPUFREQ_TABLE_END;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/exynos-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/exynos-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/exynos-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/exynos-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -113,7 +113,8 @@ static int exynos_cpufreq_scale(unsigned
 		if (ret) {
 			pr_err("%s: failed to set cpu voltage to %d\n",
 				__func__, arm_volt);
-			goto out;
+			freqs.new = freqs.old;
+			goto post_notify;
 		}
 	}
 
@@ -123,14 +124,19 @@ static int exynos_cpufreq_scale(unsigned
 		if (ret) {
 			pr_err("%s: failed to set cpu voltage to %d\n",
 				__func__, safe_arm_volt);
-			goto out;
+			freqs.new = freqs.old;
+			goto post_notify;
 		}
 	}
 
 	exynos_info->set_freq(old_index, index);
 
+post_notify:
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
+	if (ret)
+		goto out;
+
 	/* When the new frequency is lower than current frequency */
 	if ((freqs.new < freqs.old) ||
 	   ((freqs.new > freqs.old) && safe_arm_volt)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/freq_table.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/freq_table.c
--- linux-libre-3.10-gnu/drivers/cpufreq/freq_table.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/freq_table.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,8 +34,8 @@ int cpufreq_frequency_table_cpuinfo(stru
 
 			continue;
 		}
-		pr_debug("table entry %u: %u kHz, %u index\n",
-					i, freq, table[i].index);
+		pr_debug("table entry %u: %u kHz, %u driver_data\n",
+					i, freq, table[i].driver_data);
 		if (freq < min_freq)
 			min_freq = freq;
 		if (freq > max_freq)
@@ -97,11 +97,11 @@ int cpufreq_frequency_table_target(struc
 				   unsigned int *index)
 {
 	struct cpufreq_frequency_table optimal = {
-		.index = ~0,
+		.driver_data = ~0,
 		.frequency = 0,
 	};
 	struct cpufreq_frequency_table suboptimal = {
-		.index = ~0,
+		.driver_data = ~0,
 		.frequency = 0,
 	};
 	unsigned int i;
@@ -129,12 +129,12 @@ int cpufreq_frequency_table_target(struc
 			if (freq <= target_freq) {
 				if (freq >= optimal.frequency) {
 					optimal.frequency = freq;
-					optimal.index = i;
+					optimal.driver_data = i;
 				}
 			} else {
 				if (freq <= suboptimal.frequency) {
 					suboptimal.frequency = freq;
-					suboptimal.index = i;
+					suboptimal.driver_data = i;
 				}
 			}
 			break;
@@ -142,26 +142,26 @@ int cpufreq_frequency_table_target(struc
 			if (freq >= target_freq) {
 				if (freq <= optimal.frequency) {
 					optimal.frequency = freq;
-					optimal.index = i;
+					optimal.driver_data = i;
 				}
 			} else {
 				if (freq >= suboptimal.frequency) {
 					suboptimal.frequency = freq;
-					suboptimal.index = i;
+					suboptimal.driver_data = i;
 				}
 			}
 			break;
 		}
 	}
-	if (optimal.index > i) {
-		if (suboptimal.index > i)
+	if (optimal.driver_data > i) {
+		if (suboptimal.driver_data > i)
 			return -EINVAL;
-		*index = suboptimal.index;
+		*index = suboptimal.driver_data;
 	} else
-		*index = optimal.index;
+		*index = optimal.driver_data;
 
 	pr_debug("target is %u (%u kHz, %u)\n", *index, table[*index].frequency,
-		table[*index].index);
+		table[*index].driver_data);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/ia64-acpi-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/ia64-acpi-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/ia64-acpi-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/ia64-acpi-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -326,7 +326,7 @@ acpi_cpufreq_cpu_init (
 	/* table init */
 	for (i = 0; i <= data->acpi_data.state_count; i++)
 	{
-		data->freq_table[i].index = i;
+		data->freq_table[i].driver_data = i;
 		if (i < data->acpi_data.state_count) {
 			data->freq_table[i].frequency =
 			      data->acpi_data.states[i].core_frequency * 1000;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/imx6q-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/imx6q-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/imx6q-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/imx6q-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -68,8 +68,6 @@ static int imx6q_set_target(struct cpufr
 	if (freqs.old == freqs.new)
 		return 0;
 
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-
 	rcu_read_lock();
 	opp = opp_find_freq_ceil(cpu_dev, &freq_hz);
 	if (IS_ERR(opp)) {
@@ -86,13 +84,16 @@ static int imx6q_set_target(struct cpufr
 		freqs.old / 1000, volt_old / 1000,
 		freqs.new / 1000, volt / 1000);
 
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+
 	/* scaling up?  scale voltage before frequency */
 	if (freqs.new > freqs.old) {
 		ret = regulator_set_voltage_tol(arm_reg, volt, 0);
 		if (ret) {
 			dev_err(cpu_dev,
 				"failed to scale vddarm up: %d\n", ret);
-			return ret;
+			freqs.new = freqs.old;
+			goto post_notify;
 		}
 
 		/*
@@ -145,15 +146,18 @@ static int imx6q_set_target(struct cpufr
 	if (ret) {
 		dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
 		regulator_set_voltage_tol(arm_reg, volt_old, 0);
-		return ret;
+		freqs.new = freqs.old;
+		goto post_notify;
 	}
 
 	/* scaling down?  scale voltage after frequency */
 	if (freqs.new < freqs.old) {
 		ret = regulator_set_voltage_tol(arm_reg, volt, 0);
-		if (ret)
+		if (ret) {
 			dev_warn(cpu_dev,
 				 "failed to scale vddarm down: %d\n", ret);
+			ret = 0;
+		}
 
 		if (freqs.old == FREQ_1P2_GHZ / 1000) {
 			regulator_set_voltage_tol(pu_reg,
@@ -163,9 +167,10 @@ static int imx6q_set_target(struct cpufr
 		}
 	}
 
+post_notify:
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
-	return 0;
+	return ret;
 }
 
 static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/intel_pstate.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/intel_pstate.c
--- linux-libre-3.10-gnu/drivers/cpufreq/intel_pstate.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/intel_pstate.c	2013-08-25 20:43:22.000000000 -0400
@@ -103,10 +103,10 @@ struct pstate_adjust_policy {
 static struct pstate_adjust_policy default_policy = {
 	.sample_rate_ms = 10,
 	.deadband = 0,
-	.setpoint = 109,
-	.p_gain_pct = 17,
+	.setpoint = 97,
+	.p_gain_pct = 20,
 	.d_gain_pct = 0,
-	.i_gain_pct = 4,
+	.i_gain_pct = 0,
 };
 
 struct perf_limits {
@@ -468,12 +468,12 @@ static inline void intel_pstate_set_samp
 static inline int intel_pstate_get_scaled_busy(struct cpudata *cpu)
 {
 	int32_t busy_scaled;
-	int32_t core_busy, turbo_pstate, current_pstate;
+	int32_t core_busy, max_pstate, current_pstate;
 
 	core_busy = int_tofp(cpu->samples[cpu->sample_ptr].core_pct_busy);
-	turbo_pstate = int_tofp(cpu->pstate.turbo_pstate);
+	max_pstate = int_tofp(cpu->pstate.max_pstate);
 	current_pstate = int_tofp(cpu->pstate.current_pstate);
-	busy_scaled = mul_fp(core_busy, div_fp(turbo_pstate, current_pstate));
+	busy_scaled = mul_fp(core_busy, div_fp(max_pstate, current_pstate));
 
 	return fp_toint(busy_scaled);
 }
@@ -617,7 +617,7 @@ static int intel_pstate_verify_policy(st
 	return 0;
 }
 
-static int __cpuinit intel_pstate_cpu_exit(struct cpufreq_policy *policy)
+static int intel_pstate_cpu_exit(struct cpufreq_policy *policy)
 {
 	int cpu = policy->cpu;
 
@@ -627,7 +627,7 @@ static int __cpuinit intel_pstate_cpu_ex
 	return 0;
 }
 
-static int __cpuinit intel_pstate_cpu_init(struct cpufreq_policy *policy)
+static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
 {
 	int rc, min_pstate, max_pstate;
 	struct cpudata *cpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/Kconfig.arm linux-libre-3.11-rc7-gnu/drivers/cpufreq/Kconfig.arm
--- linux-libre-3.10-gnu/drivers/cpufreq/Kconfig.arm	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/Kconfig.arm	2013-08-25 20:43:22.000000000 -0400
@@ -5,6 +5,7 @@
 config ARM_BIG_LITTLE_CPUFREQ
 	tristate "Generic ARM big LITTLE CPUfreq driver"
 	depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK
+	select CPU_FREQ_TABLE
 	help
 	  This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
 
@@ -18,6 +19,7 @@ config ARM_DT_BL_CPUFREQ
 config ARM_EXYNOS_CPUFREQ
 	bool "SAMSUNG EXYNOS SoCs"
 	depends on ARCH_EXYNOS
+	select CPU_FREQ_TABLE
 	default y
 	help
 	  This adds the CPUFreq driver common part for Samsung
@@ -46,6 +48,7 @@ config ARM_EXYNOS5250_CPUFREQ
 config ARM_EXYNOS5440_CPUFREQ
 	def_bool SOC_EXYNOS5440
 	depends on HAVE_CLK && PM_OPP && OF
+	select CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for Samsung EXYNOS5440
 	  SoC. The nature of exynos5440 clock controller is
@@ -55,7 +58,6 @@ config ARM_EXYNOS5440_CPUFREQ
 config ARM_HIGHBANK_CPUFREQ
 	tristate "Calxeda Highbank-based"
 	depends on ARCH_HIGHBANK
-	select CPU_FREQ_TABLE
 	select GENERIC_CPUFREQ_CPU0
 	select PM_OPP
 	select REGULATOR
@@ -71,6 +73,7 @@ config ARM_IMX6Q_CPUFREQ
 	tristate "Freescale i.MX6Q cpufreq support"
 	depends on SOC_IMX6Q
 	depends on REGULATOR_ANATOP
+	select CPU_FREQ_TABLE
 	help
 	  This adds cpufreq driver support for Freescale i.MX6Q SOC.
 
@@ -86,6 +89,7 @@ config ARM_INTEGRATOR
 
 config ARM_KIRKWOOD_CPUFREQ
 	def_bool ARCH_KIRKWOOD && OF
+	select CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for Marvell Kirkwood
 	  SoCs.
@@ -96,9 +100,60 @@ config ARM_OMAP2PLUS_CPUFREQ
 	default ARCH_OMAP2PLUS
 	select CPU_FREQ_TABLE
 
+config ARM_S3C_CPUFREQ
+	bool
+	help
+	  Internal configuration node for common cpufreq on Samsung SoC
+
+config ARM_S3C24XX_CPUFREQ
+	bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
+	depends on ARCH_S3C24XX
+	select ARM_S3C_CPUFREQ
+	help
+	  This enables the CPUfreq driver for the Samsung S3C24XX family
+	  of CPUs.
+
+	  For details, take a look at <file:Documentation/cpu-freq>.
+
+	  If in doubt, say N.
+
+config ARM_S3C24XX_CPUFREQ_DEBUG
+	bool "Debug CPUfreq Samsung driver core"
+	depends on ARM_S3C24XX_CPUFREQ
+	help
+	  Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
+
+config ARM_S3C24XX_CPUFREQ_IODEBUG
+	bool "Debug CPUfreq Samsung driver IO timing"
+	depends on ARM_S3C24XX_CPUFREQ
+	help
+	  Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
+
+config ARM_S3C24XX_CPUFREQ_DEBUGFS
+	bool "Export debugfs for CPUFreq"
+	depends on ARM_S3C24XX_CPUFREQ && DEBUG_FS
+	help
+	  Export status information via debugfs.
+
+config ARM_S3C2410_CPUFREQ
+	bool
+	depends on ARM_S3C24XX_CPUFREQ && CPU_S3C2410
+	select S3C2410_CPUFREQ_UTILS
+	help
+	  CPU Frequency scaling support for S3C2410
+
+config ARM_S3C2412_CPUFREQ
+	bool
+	depends on ARM_S3C24XX_CPUFREQ && CPU_S3C2412
+	default y
+	select S3C2412_IOTIMING
+	help
+	  CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
+
 config ARM_S3C2416_CPUFREQ
 	bool "S3C2416 CPU Frequency scaling support"
 	depends on CPU_S3C2416
+	select CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for the Samsung S3C2416 and
 	  S3C2450 SoC. The S3C2416 supports changing the rate of the
@@ -118,9 +173,18 @@ config ARM_S3C2416_CPUFREQ_VCORESCALE
 
 	  If in doubt, say N.
 
+config ARM_S3C2440_CPUFREQ
+	bool "S3C2440/S3C2442 CPU Frequency scaling support"
+	depends on ARM_S3C24XX_CPUFREQ && (CPU_S3C2440 || CPU_S3C2442)
+	select S3C2410_CPUFREQ_UTILS
+	default y
+	help
+	  CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
+
 config ARM_S3C64XX_CPUFREQ
 	bool "Samsung S3C64XX"
 	depends on CPU_S3C6410
+	select CPU_FREQ_TABLE
 	default y
 	help
 	  This adds the CPUFreq driver for Samsung S3C6410 SoC.
@@ -147,6 +211,15 @@ config ARM_SA1110_CPUFREQ
 config ARM_SPEAR_CPUFREQ
 	bool "SPEAr CPUFreq support"
 	depends on PLAT_SPEAR
+	select CPU_FREQ_TABLE
 	default y
 	help
 	  This adds the CPUFreq driver support for SPEAr SOCs.
+
+config ARM_TEGRA_CPUFREQ
+	bool "TEGRA CPUFreq support"
+	depends on ARCH_TEGRA
+	select CPU_FREQ_TABLE
+	default y
+	help
+	  This adds the CPUFreq driver support for TEGRA SOCs.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/Kconfig.powerpc linux-libre-3.11-rc7-gnu/drivers/cpufreq/Kconfig.powerpc
--- linux-libre-3.10-gnu/drivers/cpufreq/Kconfig.powerpc	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/Kconfig.powerpc	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,7 @@
 config CPU_FREQ_CBE
 	tristate "CBE frequency scaling"
 	depends on CBE_RAS && PPC_CELL
+	select CPU_FREQ_TABLE
 	default m
 	help
 	  This adds the cpufreq driver for Cell BE processors.
@@ -23,3 +24,39 @@ config CPU_FREQ_MAPLE
 	help
 	  This adds support for frequency switching on Maple 970FX
 	  Evaluation Board and compatible boards (IBM JS2x blades).
+
+config PPC_CORENET_CPUFREQ
+	tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
+	depends on PPC_E500MC && OF && COMMON_CLK
+	select CPU_FREQ_TABLE
+	select CLK_PPC_CORENET
+	help
+	  This adds the CPUFreq driver support for Freescale e500mc,
+	  e5500 and e6500 series SoCs which are capable of changing
+	  the CPU's frequency dynamically.
+
+config CPU_FREQ_PMAC
+	bool "Support for Apple PowerBooks"
+	depends on ADB_PMU && PPC32
+	select CPU_FREQ_TABLE
+	help
+	  This adds support for frequency switching on Apple PowerBooks,
+	  this currently includes some models of iBook & Titanium
+	  PowerBook.
+
+config CPU_FREQ_PMAC64
+	bool "Support for some Apple G5s"
+	depends on PPC_PMAC && PPC64
+	select CPU_FREQ_TABLE
+	help
+	  This adds support for frequency switching on Apple iMac G5,
+	  and some of the more recent desktop G5 machines as well.
+
+config PPC_PASEMI_CPUFREQ
+	bool "Support for PA Semi PWRficient"
+	depends on PPC_PASEMI
+	select CPU_FREQ_TABLE
+	default y
+	help
+	  This adds the support for frequency switching on PA Semi
+	  PWRficient processors.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/Kconfig.x86 linux-libre-3.11-rc7-gnu/drivers/cpufreq/Kconfig.x86
--- linux-libre-3.10-gnu/drivers/cpufreq/Kconfig.x86	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/Kconfig.x86	2013-08-25 20:43:22.000000000 -0400
@@ -132,6 +132,7 @@ config X86_POWERNOW_K8
 config X86_AMD_FREQ_SENSITIVITY
 	tristate "AMD frequency sensitivity feedback powersave bias"
 	depends on CPU_FREQ_GOV_ONDEMAND && X86_ACPI_CPUFREQ && CPU_SUP_AMD
+	select CPU_FREQ_TABLE
 	help
 	  This adds AMD-specific powersave bias function to the ondemand
 	  governor, which allows it to make more power-conscious frequency
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/kirkwood-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/kirkwood-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/kirkwood-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/kirkwood-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -59,7 +59,7 @@ static void kirkwood_cpufreq_set_cpu_sta
 		unsigned int index)
 {
 	struct cpufreq_freqs freqs;
-	unsigned int state = kirkwood_freq_table[index].index;
+	unsigned int state = kirkwood_freq_table[index].driver_data;
 	unsigned long reg;
 
 	freqs.old = kirkwood_cpufreq_get_cpu_frequency(0);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/longhaul.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/longhaul.c
--- linux-libre-3.10-gnu/drivers/cpufreq/longhaul.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/longhaul.c	2013-08-25 20:43:22.000000000 -0400
@@ -254,7 +254,7 @@ static void longhaul_setstate(struct cpu
 	u32 bm_timeout = 1000;
 	unsigned int dir = 0;
 
-	mults_index = longhaul_table[table_index].index;
+	mults_index = longhaul_table[table_index].driver_data;
 	/* Safety precautions */
 	mult = mults[mults_index & 0x1f];
 	if (mult == -1)
@@ -422,7 +422,7 @@ static int guess_fsb(int mult)
 }
 
 
-static int __cpuinit longhaul_get_ranges(void)
+static int longhaul_get_ranges(void)
 {
 	unsigned int i, j, k = 0;
 	unsigned int ratio;
@@ -487,7 +487,7 @@ static int __cpuinit longhaul_get_ranges
 		if (ratio > maxmult || ratio < minmult)
 			continue;
 		longhaul_table[k].frequency = calc_speed(ratio);
-		longhaul_table[k].index	= j;
+		longhaul_table[k].driver_data	= j;
 		k++;
 	}
 	if (k <= 1) {
@@ -508,8 +508,8 @@ static int __cpuinit longhaul_get_ranges
 		if (min_i != j) {
 			swap(longhaul_table[j].frequency,
 			     longhaul_table[min_i].frequency);
-			swap(longhaul_table[j].index,
-			     longhaul_table[min_i].index);
+			swap(longhaul_table[j].driver_data,
+			     longhaul_table[min_i].driver_data);
 		}
 	}
 
@@ -517,7 +517,7 @@ static int __cpuinit longhaul_get_ranges
 
 	/* Find index we are running on */
 	for (j = 0; j < k; j++) {
-		if (mults[longhaul_table[j].index & 0x1f] == mult) {
+		if (mults[longhaul_table[j].driver_data & 0x1f] == mult) {
 			longhaul_index = j;
 			break;
 		}
@@ -526,7 +526,7 @@ static int __cpuinit longhaul_get_ranges
 }
 
 
-static void __cpuinit longhaul_setup_voltagescaling(void)
+static void longhaul_setup_voltagescaling(void)
 {
 	union msr_longhaul longhaul;
 	struct mV_pos minvid, maxvid, vid;
@@ -613,7 +613,7 @@ static void __cpuinit longhaul_setup_vol
 			pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
 		else
 			pos = minvid.pos;
-		longhaul_table[j].index |= mV_vrm_table[pos] << 8;
+		longhaul_table[j].driver_data |= mV_vrm_table[pos] << 8;
 		vid = vrm_mV_table[mV_vrm_table[pos]];
 		printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
 				speed, j, vid.mV);
@@ -656,12 +656,12 @@ static int longhaul_target(struct cpufre
 		 * this in hardware, C3 is old and we need to do this
 		 * in software. */
 		i = longhaul_index;
-		current_vid = (longhaul_table[longhaul_index].index >> 8);
+		current_vid = (longhaul_table[longhaul_index].driver_data >> 8);
 		current_vid &= 0x1f;
 		if (table_index > longhaul_index)
 			dir = 1;
 		while (i != table_index) {
-			vid = (longhaul_table[i].index >> 8) & 0x1f;
+			vid = (longhaul_table[i].driver_data >> 8) & 0x1f;
 			if (vid != current_vid) {
 				longhaul_setstate(policy, i);
 				current_vid = vid;
@@ -780,7 +780,7 @@ static int longhaul_setup_southbridge(vo
 	return 0;
 }
 
-static int __cpuinit longhaul_cpu_init(struct cpufreq_policy *policy)
+static int longhaul_cpu_init(struct cpufreq_policy *policy)
 {
 	struct cpuinfo_x86 *c = &cpu_data(0);
 	char *cpuname = NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/longhaul.h linux-libre-3.11-rc7-gnu/drivers/cpufreq/longhaul.h
--- linux-libre-3.10-gnu/drivers/cpufreq/longhaul.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/longhaul.h	2013-08-25 20:43:22.000000000 -0400
@@ -56,7 +56,7 @@ union msr_longhaul {
 /*
  * VIA C3 Samuel 1  & Samuel 2 (stepping 0)
  */
-static const int __cpuinitconst samuel1_mults[16] = {
+static const int samuel1_mults[16] = {
 	-1, /* 0000 -> RESERVED */
 	30, /* 0001 ->  3.0x */
 	40, /* 0010 ->  4.0x */
@@ -75,7 +75,7 @@ static const int __cpuinitconst samuel1_
 	-1, /* 1111 -> RESERVED */
 };
 
-static const int __cpuinitconst samuel1_eblcr[16] = {
+static const int samuel1_eblcr[16] = {
 	50, /* 0000 -> RESERVED */
 	30, /* 0001 ->  3.0x */
 	40, /* 0010 ->  4.0x */
@@ -97,7 +97,7 @@ static const int __cpuinitconst samuel1_
 /*
  * VIA C3 Samuel2 Stepping 1->15
  */
-static const int __cpuinitconst samuel2_eblcr[16] = {
+static const int samuel2_eblcr[16] = {
 	50,  /* 0000 ->  5.0x */
 	30,  /* 0001 ->  3.0x */
 	40,  /* 0010 ->  4.0x */
@@ -119,7 +119,7 @@ static const int __cpuinitconst samuel2_
 /*
  * VIA C3 Ezra
  */
-static const int __cpuinitconst ezra_mults[16] = {
+static const int ezra_mults[16] = {
 	100, /* 0000 -> 10.0x */
 	30,  /* 0001 ->  3.0x */
 	40,  /* 0010 ->  4.0x */
@@ -138,7 +138,7 @@ static const int __cpuinitconst ezra_mul
 	120, /* 1111 -> 12.0x */
 };
 
-static const int __cpuinitconst ezra_eblcr[16] = {
+static const int ezra_eblcr[16] = {
 	50,  /* 0000 ->  5.0x */
 	30,  /* 0001 ->  3.0x */
 	40,  /* 0010 ->  4.0x */
@@ -160,7 +160,7 @@ static const int __cpuinitconst ezra_ebl
 /*
  * VIA C3 (Ezra-T) [C5M].
  */
-static const int __cpuinitconst ezrat_mults[32] = {
+static const int ezrat_mults[32] = {
 	100, /* 0000 -> 10.0x */
 	30,  /* 0001 ->  3.0x */
 	40,  /* 0010 ->  4.0x */
@@ -196,7 +196,7 @@ static const int __cpuinitconst ezrat_mu
 	-1,  /* 1111 -> RESERVED (12.0x) */
 };
 
-static const int __cpuinitconst ezrat_eblcr[32] = {
+static const int ezrat_eblcr[32] = {
 	50,  /* 0000 ->  5.0x */
 	30,  /* 0001 ->  3.0x */
 	40,  /* 0010 ->  4.0x */
@@ -235,7 +235,7 @@ static const int __cpuinitconst ezrat_eb
 /*
  * VIA C3 Nehemiah */
 
-static const int __cpuinitconst nehemiah_mults[32] = {
+static const int nehemiah_mults[32] = {
 	100, /* 0000 -> 10.0x */
 	-1, /* 0001 -> 16.0x */
 	40,  /* 0010 ->  4.0x */
@@ -270,7 +270,7 @@ static const int __cpuinitconst nehemiah
 	-1, /* 1111 -> 12.0x */
 };
 
-static const int __cpuinitconst nehemiah_eblcr[32] = {
+static const int nehemiah_eblcr[32] = {
 	50,  /* 0000 ->  5.0x */
 	160, /* 0001 -> 16.0x */
 	40,  /* 0010 ->  4.0x */
@@ -315,7 +315,7 @@ struct mV_pos {
 	unsigned short pos;
 };
 
-static const struct mV_pos __cpuinitconst vrm85_mV[32] = {
+static const struct mV_pos vrm85_mV[32] = {
 	{1250, 8},	{1200, 6},	{1150, 4},	{1100, 2},
 	{1050, 0},	{1800, 30},	{1750, 28},	{1700, 26},
 	{1650, 24},	{1600, 22},	{1550, 20},	{1500, 18},
@@ -326,14 +326,14 @@ static const struct mV_pos __cpuinitcons
 	{1475, 17},	{1425, 15},	{1375, 13},	{1325, 11}
 };
 
-static const unsigned char __cpuinitconst mV_vrm85[32] = {
+static const unsigned char mV_vrm85[32] = {
 	0x04,	0x14,	0x03,	0x13,	0x02,	0x12,	0x01,	0x11,
 	0x00,	0x10,	0x0f,	0x1f,	0x0e,	0x1e,	0x0d,	0x1d,
 	0x0c,	0x1c,	0x0b,	0x1b,	0x0a,	0x1a,	0x09,	0x19,
 	0x08,	0x18,	0x07,	0x17,	0x06,	0x16,	0x05,	0x15
 };
 
-static const struct mV_pos __cpuinitconst mobilevrm_mV[32] = {
+static const struct mV_pos mobilevrm_mV[32] = {
 	{1750, 31},	{1700, 30},	{1650, 29},	{1600, 28},
 	{1550, 27},	{1500, 26},	{1450, 25},	{1400, 24},
 	{1350, 23},	{1300, 22},	{1250, 21},	{1200, 20},
@@ -344,7 +344,7 @@ static const struct mV_pos __cpuinitcons
 	{675, 3},	{650, 2},	{625, 1},	{600, 0}
 };
 
-static const unsigned char __cpuinitconst mV_mobilevrm[32] = {
+static const unsigned char mV_mobilevrm[32] = {
 	0x1f,	0x1e,	0x1d,	0x1c,	0x1b,	0x1a,	0x19,	0x18,
 	0x17,	0x16,	0x15,	0x14,	0x13,	0x12,	0x11,	0x10,
 	0x0f,	0x0e,	0x0d,	0x0c,	0x0b,	0x0a,	0x09,	0x08,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/longrun.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/longrun.c
--- linux-libre-3.10-gnu/drivers/cpufreq/longrun.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/longrun.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,7 @@ static unsigned int longrun_low_freq, lo
  * Reads the current LongRun policy by access to MSR_TMTA_LONGRUN_FLAGS
  * and MSR_TMTA_LONGRUN_CTRL
  */
-static void __cpuinit longrun_get_policy(struct cpufreq_policy *policy)
+static void longrun_get_policy(struct cpufreq_policy *policy)
 {
 	u32 msr_lo, msr_hi;
 
@@ -163,7 +163,7 @@ static unsigned int longrun_get(unsigned
  * TMTA rules:
  * performance_pctg = (target_freq - low_freq)/(high_freq - low_freq)
  */
-static int __cpuinit longrun_determine_freqs(unsigned int *low_freq,
+static int longrun_determine_freqs(unsigned int *low_freq,
 						      unsigned int *high_freq)
 {
 	u32 msr_lo, msr_hi;
@@ -256,7 +256,7 @@ static int __cpuinit longrun_determine_f
 }
 
 
-static int __cpuinit longrun_cpu_init(struct cpufreq_policy *policy)
+static int longrun_cpu_init(struct cpufreq_policy *policy)
 {
 	int result = 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/loongson2_cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/loongson2_cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/loongson2_cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/loongson2_cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -72,7 +72,7 @@ static int loongson2_cpufreq_target(stru
 
 	freq =
 	    ((cpu_clock_freq / 1000) *
-	     loongson2_clockmod_table[newstate].index) / 8;
+	     loongson2_clockmod_table[newstate].driver_data) / 8;
 	if (freq < policy->min || freq > policy->max)
 		return -EINVAL;
 
@@ -118,11 +118,6 @@ static int loongson2_cpufreq_cpu_init(st
 		clk_put(cpuclk);
 		return -EINVAL;
 	}
-	ret = clk_set_rate(cpuclk, rate);
-	if (ret) {
-		clk_put(cpuclk);
-		return ret;
-	}
 
 	/* clock table init */
 	for (i = 2;
@@ -130,6 +125,12 @@ static int loongson2_cpufreq_cpu_init(st
 	     i++)
 		loongson2_clockmod_table[i].frequency = (rate * i) / 8;
 
+	ret = clk_set_rate(cpuclk, rate);
+	if (ret) {
+		clk_put(cpuclk);
+		return ret;
+	}
+
 	policy->cur = loongson2_cpufreq_get(policy->cpu);
 
 	cpufreq_frequency_table_get_attr(&loongson2_clockmod_table[0],
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/Makefile linux-libre-3.11-rc7-gnu/drivers/cpufreq/Makefile
--- linux-libre-3.10-gnu/drivers/cpufreq/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -65,13 +65,18 @@ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= o
 obj-$(CONFIG_PXA25x)			+= pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA27x)			+= pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA3xx)			+= pxa3xx-cpufreq.o
+obj-$(CONFIG_ARM_S3C24XX_CPUFREQ)	+= s3c24xx-cpufreq.o
+obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
+obj-$(CONFIG_ARM_S3C2410_CPUFREQ)	+= s3c2410-cpufreq.o
+obj-$(CONFIG_ARM_S3C2412_CPUFREQ)	+= s3c2412-cpufreq.o
 obj-$(CONFIG_ARM_S3C2416_CPUFREQ)	+= s3c2416-cpufreq.o
+obj-$(CONFIG_ARM_S3C2440_CPUFREQ)	+= s3c2440-cpufreq.o
 obj-$(CONFIG_ARM_S3C64XX_CPUFREQ)	+= s3c64xx-cpufreq.o
 obj-$(CONFIG_ARM_S5PV210_CPUFREQ)	+= s5pv210-cpufreq.o
 obj-$(CONFIG_ARM_SA1100_CPUFREQ)	+= sa1100-cpufreq.o
 obj-$(CONFIG_ARM_SA1110_CPUFREQ)	+= sa1110-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)		+= spear-cpufreq.o
-obj-$(CONFIG_ARCH_TEGRA)		+= tegra-cpufreq.o
+obj-$(CONFIG_ARM_TEGRA_CPUFREQ)		+= tegra-cpufreq.o
 
 ##################################################################################
 # PowerPC platform drivers
@@ -79,11 +84,15 @@ obj-$(CONFIG_CPU_FREQ_CBE)		+= ppc-cbe-c
 ppc-cbe-cpufreq-y			+= ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o
 obj-$(CONFIG_CPU_FREQ_CBE_PMI)		+= ppc_cbe_cpufreq_pmi.o
 obj-$(CONFIG_CPU_FREQ_MAPLE)		+= maple-cpufreq.o
+obj-$(CONFIG_PPC_CORENET_CPUFREQ)   += ppc-corenet-cpufreq.o
+obj-$(CONFIG_CPU_FREQ_PMAC)		+= pmac32-cpufreq.o
+obj-$(CONFIG_CPU_FREQ_PMAC64)		+= pmac64-cpufreq.o
+obj-$(CONFIG_PPC_PASEMI_CPUFREQ)	+= pasemi-cpufreq.o
 
 ##################################################################################
 # Other platform drivers
 obj-$(CONFIG_AVR32_AT32AP_CPUFREQ)	+= at32ap-cpufreq.o
-obj-$(CONFIG_BLACKFIN)			+= blackfin-cpufreq.o
+obj-$(CONFIG_BFIN_CPU_FREQ)		+= blackfin-cpufreq.o
 obj-$(CONFIG_CRIS_MACH_ARTPEC3)		+= cris-artpec3-cpufreq.o
 obj-$(CONFIG_ETRAXFS)			+= cris-etraxfs-cpufreq.o
 obj-$(CONFIG_IA64_ACPI_CPUFREQ)		+= ia64-acpi-cpufreq.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/omap-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/omap-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/omap-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/omap-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -93,9 +93,6 @@ static int omap_target(struct cpufreq_po
 	if (freqs.old == freqs.new && policy->cur == freqs.new)
 		return ret;
 
-	/* notifiers */
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-
 	freq = freqs.new * 1000;
 	ret = clk_round_rate(mpu_clk, freq);
 	if (IS_ERR_VALUE(ret)) {
@@ -125,6 +122,9 @@ static int omap_target(struct cpufreq_po
 		freqs.old / 1000, volt_old ? volt_old / 1000 : -1,
 		freqs.new / 1000, volt ? volt / 1000 : -1);
 
+	/* notifiers */
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+
 	/* scaling up?  scale voltage before frequency */
 	if (mpu_reg && (freqs.new > freqs.old)) {
 		r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol);
@@ -165,7 +165,7 @@ static inline void freq_table_free(void)
 		opp_free_cpufreq_table(mpu_dev, &freq_table);
 }
 
-static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+static int omap_cpu_init(struct cpufreq_policy *policy)
 {
 	int result = 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/p4-clockmod.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/p4-clockmod.c
--- linux-libre-3.10-gnu/drivers/cpufreq/p4-clockmod.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/p4-clockmod.c	2013-08-25 20:43:22.000000000 -0400
@@ -118,7 +118,7 @@ static int cpufreq_p4_target(struct cpuf
 		return -EINVAL;
 
 	freqs.old = cpufreq_p4_get(policy->cpu);
-	freqs.new = stock_freq * p4clockmod_table[newstate].index / 8;
+	freqs.new = stock_freq * p4clockmod_table[newstate].driver_data / 8;
 
 	if (freqs.new == freqs.old)
 		return 0;
@@ -131,7 +131,7 @@ static int cpufreq_p4_target(struct cpuf
 	 * Developer's Manual, Volume 3
 	 */
 	for_each_cpu(i, policy->cpus)
-		cpufreq_p4_setdc(i, p4clockmod_table[newstate].index);
+		cpufreq_p4_setdc(i, p4clockmod_table[newstate].driver_data);
 
 	/* notifiers */
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/pasemi-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/pasemi-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/pasemi-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/pasemi-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2007 PA Semi, Inc
+ *
+ * Authors: Egor Martovetsky <egor@pasemi.com>
+ *	    Olof Johansson <olof@lixom.net>
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * Based on arch/powerpc/platforms/cell/cbe_cpufreq.c:
+ * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/cpufreq.h>
+#include <linux/timer.h>
+#include <linux/module.h>
+
+#include <asm/hw_irq.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/smp.h>
+
+#define SDCASR_REG		0x0100
+#define SDCASR_REG_STRIDE	0x1000
+#define SDCPWR_CFGA0_REG	0x0100
+#define SDCPWR_PWST0_REG	0x0000
+#define SDCPWR_GIZTIME_REG	0x0440
+
+/* SDCPWR_GIZTIME_REG fields */
+#define SDCPWR_GIZTIME_GR	0x80000000
+#define SDCPWR_GIZTIME_LONGLOCK	0x000000ff
+
+/* Offset of ASR registers from SDC base */
+#define SDCASR_OFFSET		0x120000
+
+static void __iomem *sdcpwr_mapbase;
+static void __iomem *sdcasr_mapbase;
+
+static DEFINE_MUTEX(pas_switch_mutex);
+
+/* Current astate, is used when waking up from power savings on
+ * one core, in case the other core has switched states during
+ * the idle time.
+ */
+static int current_astate;
+
+/* We support 5(A0-A4) power states excluding turbo(A5-A6) modes */
+static struct cpufreq_frequency_table pas_freqs[] = {
+	{0,	0},
+	{1,	0},
+	{2,	0},
+	{3,	0},
+	{4,	0},
+	{0,	CPUFREQ_TABLE_END},
+};
+
+static struct freq_attr *pas_cpu_freqs_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+/*
+ * hardware specific functions
+ */
+
+static int get_astate_freq(int astate)
+{
+	u32 ret;
+	ret = in_le32(sdcpwr_mapbase + SDCPWR_CFGA0_REG + (astate * 0x10));
+
+	return ret & 0x3f;
+}
+
+static int get_cur_astate(int cpu)
+{
+	u32 ret;
+
+	ret = in_le32(sdcpwr_mapbase + SDCPWR_PWST0_REG);
+	ret = (ret >> (cpu * 4)) & 0x7;
+
+	return ret;
+}
+
+static int get_gizmo_latency(void)
+{
+	u32 giztime, ret;
+
+	giztime = in_le32(sdcpwr_mapbase + SDCPWR_GIZTIME_REG);
+
+	/* just provide the upper bound */
+	if (giztime & SDCPWR_GIZTIME_GR)
+		ret = (giztime & SDCPWR_GIZTIME_LONGLOCK) * 128000;
+	else
+		ret = (giztime & SDCPWR_GIZTIME_LONGLOCK) * 1000;
+
+	return ret;
+}
+
+static void set_astate(int cpu, unsigned int astate)
+{
+	unsigned long flags;
+
+	/* Return if called before init has run */
+	if (unlikely(!sdcasr_mapbase))
+		return;
+
+	local_irq_save(flags);
+
+	out_le32(sdcasr_mapbase + SDCASR_REG + SDCASR_REG_STRIDE*cpu, astate);
+
+	local_irq_restore(flags);
+}
+
+int check_astate(void)
+{
+	return get_cur_astate(hard_smp_processor_id());
+}
+
+void restore_astate(int cpu)
+{
+	set_astate(cpu, current_astate);
+}
+
+/*
+ * cpufreq functions
+ */
+
+static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	const u32 *max_freqp;
+	u32 max_freq;
+	int i, cur_astate;
+	struct resource res;
+	struct device_node *cpu, *dn;
+	int err = -ENODEV;
+
+	cpu = of_get_cpu_node(policy->cpu, NULL);
+
+	if (!cpu)
+		goto out;
+
+	dn = of_find_compatible_node(NULL, NULL, "1682m-sdc");
+	if (!dn)
+		dn = of_find_compatible_node(NULL, NULL,
+					     "pasemi,pwrficient-sdc");
+	if (!dn)
+		goto out;
+	err = of_address_to_resource(dn, 0, &res);
+	of_node_put(dn);
+	if (err)
+		goto out;
+	sdcasr_mapbase = ioremap(res.start + SDCASR_OFFSET, 0x2000);
+	if (!sdcasr_mapbase) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	dn = of_find_compatible_node(NULL, NULL, "1682m-gizmo");
+	if (!dn)
+		dn = of_find_compatible_node(NULL, NULL,
+					     "pasemi,pwrficient-gizmo");
+	if (!dn) {
+		err = -ENODEV;
+		goto out_unmap_sdcasr;
+	}
+	err = of_address_to_resource(dn, 0, &res);
+	of_node_put(dn);
+	if (err)
+		goto out_unmap_sdcasr;
+	sdcpwr_mapbase = ioremap(res.start, 0x1000);
+	if (!sdcpwr_mapbase) {
+		err = -EINVAL;
+		goto out_unmap_sdcasr;
+	}
+
+	pr_debug("init cpufreq on CPU %d\n", policy->cpu);
+
+	max_freqp = of_get_property(cpu, "clock-frequency", NULL);
+	if (!max_freqp) {
+		err = -EINVAL;
+		goto out_unmap_sdcpwr;
+	}
+
+	/* we need the freq in kHz */
+	max_freq = *max_freqp / 1000;
+
+	pr_debug("max clock-frequency is at %u kHz\n", max_freq);
+	pr_debug("initializing frequency table\n");
+
+	/* initialize frequency table */
+	for (i=0; pas_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
+		pas_freqs[i].frequency =
+			get_astate_freq(pas_freqs[i].driver_data) * 100000;
+		pr_debug("%d: %d\n", i, pas_freqs[i].frequency);
+	}
+
+	policy->cpuinfo.transition_latency = get_gizmo_latency();
+
+	cur_astate = get_cur_astate(policy->cpu);
+	pr_debug("current astate is at %d\n",cur_astate);
+
+	policy->cur = pas_freqs[cur_astate].frequency;
+	cpumask_copy(policy->cpus, cpu_online_mask);
+
+	ppc_proc_freq = policy->cur * 1000ul;
+
+	cpufreq_frequency_table_get_attr(pas_freqs, policy->cpu);
+
+	/* this ensures that policy->cpuinfo_min and policy->cpuinfo_max
+	 * are set correctly
+	 */
+	return cpufreq_frequency_table_cpuinfo(policy, pas_freqs);
+
+out_unmap_sdcpwr:
+	iounmap(sdcpwr_mapbase);
+
+out_unmap_sdcasr:
+	iounmap(sdcasr_mapbase);
+out:
+	return err;
+}
+
+static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+	/*
+	 * We don't support CPU hotplug. Don't unmap after the system
+	 * has already made it to a running state.
+	 */
+	if (system_state != SYSTEM_BOOTING)
+		return 0;
+
+	if (sdcasr_mapbase)
+		iounmap(sdcasr_mapbase);
+	if (sdcpwr_mapbase)
+		iounmap(sdcpwr_mapbase);
+
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static int pas_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, pas_freqs);
+}
+
+static int pas_cpufreq_target(struct cpufreq_policy *policy,
+			      unsigned int target_freq,
+			      unsigned int relation)
+{
+	struct cpufreq_freqs freqs;
+	int pas_astate_new;
+	int i;
+
+	cpufreq_frequency_table_target(policy,
+				       pas_freqs,
+				       target_freq,
+				       relation,
+				       &pas_astate_new);
+
+	freqs.old = policy->cur;
+	freqs.new = pas_freqs[pas_astate_new].frequency;
+
+	mutex_lock(&pas_switch_mutex);
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+
+	pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n",
+		 policy->cpu,
+		 pas_freqs[pas_astate_new].frequency,
+		 pas_freqs[pas_astate_new].driver_data);
+
+	current_astate = pas_astate_new;
+
+	for_each_online_cpu(i)
+		set_astate(i, pas_astate_new);
+
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+	mutex_unlock(&pas_switch_mutex);
+
+	ppc_proc_freq = freqs.new * 1000ul;
+	return 0;
+}
+
+static struct cpufreq_driver pas_cpufreq_driver = {
+	.name		= "pas-cpufreq",
+	.owner		= THIS_MODULE,
+	.flags		= CPUFREQ_CONST_LOOPS,
+	.init		= pas_cpufreq_cpu_init,
+	.exit		= pas_cpufreq_cpu_exit,
+	.verify		= pas_cpufreq_verify,
+	.target		= pas_cpufreq_target,
+	.attr		= pas_cpu_freqs_attr,
+};
+
+/*
+ * module init and destoy
+ */
+
+static int __init pas_cpufreq_init(void)
+{
+	if (!of_machine_is_compatible("PA6T-1682M") &&
+	    !of_machine_is_compatible("pasemi,pwrficient"))
+		return -ENODEV;
+
+	return cpufreq_register_driver(&pas_cpufreq_driver);
+}
+
+static void __exit pas_cpufreq_exit(void)
+{
+	cpufreq_unregister_driver(&pas_cpufreq_driver);
+}
+
+module_init(pas_cpufreq_init);
+module_exit(pas_cpufreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>, Olof Johansson <olof@lixom.net>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/pcc-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/pcc-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/pcc-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/pcc-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -243,6 +243,8 @@ static int pcc_cpufreq_target(struct cpu
 	return 0;
 
 cmd_incomplete:
+	freqs.new = freqs.old;
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 	iowrite16(0, &pcch_hdr->status);
 	spin_unlock(&pcc_lock);
 	return -EINVAL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/pmac32-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/pmac32-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/pmac32-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/pmac32-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,721 @@
+/*
+ *  Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *  Copyright (C) 2004        John Steele Scott <toojays@toojays.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * TODO: Need a big cleanup here. Basically, we need to have different
+ * cpufreq_driver structures for the different type of HW instead of the
+ * current mess. We also need to better deal with the detection of the
+ * type of machine.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/hardirq.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/pmac_feature.h>
+#include <asm/mmu_context.h>
+#include <asm/sections.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/mpic.h>
+#include <asm/keylargo.h>
+#include <asm/switch_to.h>
+
+/* WARNING !!! This will cause calibrate_delay() to be called,
+ * but this is an __init function ! So you MUST go edit
+ * init/main.c to make it non-init before enabling DEBUG_FREQ
+ */
+#undef DEBUG_FREQ
+
+extern void low_choose_7447a_dfs(int dfs);
+extern void low_choose_750fx_pll(int pll);
+extern void low_sleep_handler(void);
+
+/*
+ * Currently, PowerMac cpufreq supports only high & low frequencies
+ * that are set by the firmware
+ */
+static unsigned int low_freq;
+static unsigned int hi_freq;
+static unsigned int cur_freq;
+static unsigned int sleep_freq;
+static unsigned long transition_latency;
+
+/*
+ * Different models uses different mechanisms to switch the frequency
+ */
+static int (*set_speed_proc)(int low_speed);
+static unsigned int (*get_speed_proc)(void);
+
+/*
+ * Some definitions used by the various speedprocs
+ */
+static u32 voltage_gpio;
+static u32 frequency_gpio;
+static u32 slew_done_gpio;
+static int no_schedule;
+static int has_cpu_l2lve;
+static int is_pmu_based;
+
+/* There are only two frequency states for each processor. Values
+ * are in kHz for the time being.
+ */
+#define CPUFREQ_HIGH                  0
+#define CPUFREQ_LOW                   1
+
+static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
+	{CPUFREQ_HIGH, 		0},
+	{CPUFREQ_LOW,		0},
+	{0,			CPUFREQ_TABLE_END},
+};
+
+static struct freq_attr* pmac_cpu_freqs_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static inline void local_delay(unsigned long ms)
+{
+	if (no_schedule)
+		mdelay(ms);
+	else
+		msleep(ms);
+}
+
+#ifdef DEBUG_FREQ
+static inline void debug_calc_bogomips(void)
+{
+	/* This will cause a recalc of bogomips and display the
+	 * result. We backup/restore the value to avoid affecting the
+	 * core cpufreq framework's own calculation.
+	 */
+	unsigned long save_lpj = loops_per_jiffy;
+	calibrate_delay();
+	loops_per_jiffy = save_lpj;
+}
+#endif /* DEBUG_FREQ */
+
+/* Switch CPU speed under 750FX CPU control
+ */
+static int cpu_750fx_cpu_speed(int low_speed)
+{
+	u32 hid2;
+
+	if (low_speed == 0) {
+		/* ramping up, set voltage first */
+		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+		/* Make sure we sleep for at least 1ms */
+		local_delay(10);
+
+		/* tweak L2 for high voltage */
+		if (has_cpu_l2lve) {
+			hid2 = mfspr(SPRN_HID2);
+			hid2 &= ~0x2000;
+			mtspr(SPRN_HID2, hid2);
+		}
+	}
+#ifdef CONFIG_6xx
+	low_choose_750fx_pll(low_speed);
+#endif
+	if (low_speed == 1) {
+		/* tweak L2 for low voltage */
+		if (has_cpu_l2lve) {
+			hid2 = mfspr(SPRN_HID2);
+			hid2 |= 0x2000;
+			mtspr(SPRN_HID2, hid2);
+		}
+
+		/* ramping down, set voltage last */
+		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+		local_delay(10);
+	}
+
+	return 0;
+}
+
+static unsigned int cpu_750fx_get_cpu_speed(void)
+{
+	if (mfspr(SPRN_HID1) & HID1_PS)
+		return low_freq;
+	else
+		return hi_freq;
+}
+
+/* Switch CPU speed using DFS */
+static int dfs_set_cpu_speed(int low_speed)
+{
+	if (low_speed == 0) {
+		/* ramping up, set voltage first */
+		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+		/* Make sure we sleep for at least 1ms */
+		local_delay(1);
+	}
+
+	/* set frequency */
+#ifdef CONFIG_6xx
+	low_choose_7447a_dfs(low_speed);
+#endif
+	udelay(100);
+
+	if (low_speed == 1) {
+		/* ramping down, set voltage last */
+		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+		local_delay(1);
+	}
+
+	return 0;
+}
+
+static unsigned int dfs_get_cpu_speed(void)
+{
+	if (mfspr(SPRN_HID1) & HID1_DFS)
+		return low_freq;
+	else
+		return hi_freq;
+}
+
+
+/* Switch CPU speed using slewing GPIOs
+ */
+static int gpios_set_cpu_speed(int low_speed)
+{
+	int gpio, timeout = 0;
+
+	/* If ramping up, set voltage first */
+	if (low_speed == 0) {
+		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+		/* Delay is way too big but it's ok, we schedule */
+		local_delay(10);
+	}
+
+	/* Set frequency */
+	gpio = 	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
+	if (low_speed == ((gpio & 0x01) == 0))
+		goto skip;
+
+	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
+			  low_speed ? 0x04 : 0x05);
+	udelay(200);
+	do {
+		if (++timeout > 100)
+			break;
+		local_delay(1);
+		gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
+	} while((gpio & 0x02) == 0);
+ skip:
+	/* If ramping down, set voltage last */
+	if (low_speed == 1) {
+		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+		/* Delay is way too big but it's ok, we schedule */
+		local_delay(10);
+	}
+
+#ifdef DEBUG_FREQ
+	debug_calc_bogomips();
+#endif
+
+	return 0;
+}
+
+/* Switch CPU speed under PMU control
+ */
+static int pmu_set_cpu_speed(int low_speed)
+{
+	struct adb_request req;
+	unsigned long save_l2cr;
+	unsigned long save_l3cr;
+	unsigned int pic_prio;
+	unsigned long flags;
+
+	preempt_disable();
+
+#ifdef DEBUG_FREQ
+	printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
+#endif
+	pmu_suspend();
+
+	/* Disable all interrupt sources on openpic */
+ 	pic_prio = mpic_cpu_get_priority();
+	mpic_cpu_set_priority(0xf);
+
+	/* Make sure the decrementer won't interrupt us */
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+	/* Make sure any pending DEC interrupt occurring while we did
+	 * the above didn't re-enable the DEC */
+	mb();
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
+	/* We can now disable MSR_EE */
+	local_irq_save(flags);
+
+	/* Giveup the FPU & vec */
+	enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+	if (cpu_has_feature(CPU_FTR_ALTIVEC))
+		enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+	/* Save & disable L2 and L3 caches */
+	save_l3cr = _get_L3CR();	/* (returns -1 if not available) */
+	save_l2cr = _get_L2CR();	/* (returns -1 if not available) */
+
+	/* Send the new speed command. My assumption is that this command
+	 * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
+	 */
+	pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
+	while (!req.complete)
+		pmu_poll();
+
+	/* Prepare the northbridge for the speed transition */
+	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
+
+	/* Call low level code to backup CPU state and recover from
+	 * hardware reset
+	 */
+	low_sleep_handler();
+
+	/* Restore the northbridge */
+	pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
+
+	/* Restore L2 cache */
+	if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
+ 		_set_L2CR(save_l2cr);
+	/* Restore L3 cache */
+	if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
+ 		_set_L3CR(save_l3cr);
+
+	/* Restore userland MMU context */
+	switch_mmu_context(NULL, current->active_mm);
+
+#ifdef DEBUG_FREQ
+	printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
+#endif
+
+	/* Restore low level PMU operations */
+	pmu_unlock();
+
+	/*
+	 * Restore decrementer; we'll take a decrementer interrupt
+	 * as soon as interrupts are re-enabled and the generic
+	 * clockevents code will reprogram it with the right value.
+	 */
+	set_dec(1);
+
+	/* Restore interrupts */
+ 	mpic_cpu_set_priority(pic_prio);
+
+	/* Let interrupts flow again ... */
+	local_irq_restore(flags);
+
+#ifdef DEBUG_FREQ
+	debug_calc_bogomips();
+#endif
+
+	pmu_resume();
+
+	preempt_enable();
+
+	return 0;
+}
+
+static int do_set_cpu_speed(struct cpufreq_policy *policy, int speed_mode,
+		int notify)
+{
+	struct cpufreq_freqs freqs;
+	unsigned long l3cr;
+	static unsigned long prev_l3cr;
+
+	freqs.old = cur_freq;
+	freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
+
+	if (freqs.old == freqs.new)
+		return 0;
+
+	if (notify)
+		cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+	if (speed_mode == CPUFREQ_LOW &&
+	    cpu_has_feature(CPU_FTR_L3CR)) {
+		l3cr = _get_L3CR();
+		if (l3cr & L3CR_L3E) {
+			prev_l3cr = l3cr;
+			_set_L3CR(0);
+		}
+	}
+	set_speed_proc(speed_mode == CPUFREQ_LOW);
+	if (speed_mode == CPUFREQ_HIGH &&
+	    cpu_has_feature(CPU_FTR_L3CR)) {
+		l3cr = _get_L3CR();
+		if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
+			_set_L3CR(prev_l3cr);
+	}
+	if (notify)
+		cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+	cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
+
+	return 0;
+}
+
+static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
+{
+	return cur_freq;
+}
+
+static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
+}
+
+static int pmac_cpufreq_target(	struct cpufreq_policy *policy,
+					unsigned int target_freq,
+					unsigned int relation)
+{
+	unsigned int    newstate = 0;
+	int		rc;
+
+	if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
+			target_freq, relation, &newstate))
+		return -EINVAL;
+
+	rc = do_set_cpu_speed(policy, newstate, 1);
+
+	ppc_proc_freq = cur_freq * 1000ul;
+	return rc;
+}
+
+static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	policy->cpuinfo.transition_latency	= transition_latency;
+	policy->cur = cur_freq;
+
+	cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
+	return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
+}
+
+static u32 read_gpio(struct device_node *np)
+{
+	const u32 *reg = of_get_property(np, "reg", NULL);
+	u32 offset;
+
+	if (reg == NULL)
+		return 0;
+	/* That works for all keylargos but shall be fixed properly
+	 * some day... The problem is that it seems we can't rely
+	 * on the "reg" property of the GPIO nodes, they are either
+	 * relative to the base of KeyLargo or to the base of the
+	 * GPIO space, and the device-tree doesn't help.
+	 */
+	offset = *reg;
+	if (offset < KEYLARGO_GPIO_LEVELS0)
+		offset += KEYLARGO_GPIO_LEVELS0;
+	return offset;
+}
+
+static int pmac_cpufreq_suspend(struct cpufreq_policy *policy)
+{
+	/* Ok, this could be made a bit smarter, but let's be robust for now. We
+	 * always force a speed change to high speed before sleep, to make sure
+	 * we have appropriate voltage and/or bus speed for the wakeup process,
+	 * and to make sure our loops_per_jiffies are "good enough", that is will
+	 * not cause too short delays if we sleep in low speed and wake in high
+	 * speed..
+	 */
+	no_schedule = 1;
+	sleep_freq = cur_freq;
+	if (cur_freq == low_freq && !is_pmu_based)
+		do_set_cpu_speed(policy, CPUFREQ_HIGH, 0);
+	return 0;
+}
+
+static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
+{
+	/* If we resume, first check if we have a get() function */
+	if (get_speed_proc)
+		cur_freq = get_speed_proc();
+	else
+		cur_freq = 0;
+
+	/* We don't, hrm... we don't really know our speed here, best
+	 * is that we force a switch to whatever it was, which is
+	 * probably high speed due to our suspend() routine
+	 */
+	do_set_cpu_speed(policy, sleep_freq == low_freq ?
+			 CPUFREQ_LOW : CPUFREQ_HIGH, 0);
+
+	ppc_proc_freq = cur_freq * 1000ul;
+
+	no_schedule = 0;
+	return 0;
+}
+
+static struct cpufreq_driver pmac_cpufreq_driver = {
+	.verify 	= pmac_cpufreq_verify,
+	.target 	= pmac_cpufreq_target,
+	.get		= pmac_cpufreq_get_speed,
+	.init		= pmac_cpufreq_cpu_init,
+	.suspend	= pmac_cpufreq_suspend,
+	.resume		= pmac_cpufreq_resume,
+	.flags		= CPUFREQ_PM_NO_WARN,
+	.attr		= pmac_cpu_freqs_attr,
+	.name		= "powermac",
+	.owner		= THIS_MODULE,
+};
+
+
+static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
+{
+	struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
+								"voltage-gpio");
+	struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
+								"frequency-gpio");
+	struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
+								     "slewing-done");
+	const u32 *value;
+
+	/*
+	 * Check to see if it's GPIO driven or PMU only
+	 *
+	 * The way we extract the GPIO address is slightly hackish, but it
+	 * works well enough for now. We need to abstract the whole GPIO
+	 * stuff sooner or later anyway
+	 */
+
+	if (volt_gpio_np)
+		voltage_gpio = read_gpio(volt_gpio_np);
+	if (freq_gpio_np)
+		frequency_gpio = read_gpio(freq_gpio_np);
+	if (slew_done_gpio_np)
+		slew_done_gpio = read_gpio(slew_done_gpio_np);
+
+	/* If we use the frequency GPIOs, calculate the min/max speeds based
+	 * on the bus frequencies
+	 */
+	if (frequency_gpio && slew_done_gpio) {
+		int lenp, rc;
+		const u32 *freqs, *ratio;
+
+		freqs = of_get_property(cpunode, "bus-frequencies", &lenp);
+		lenp /= sizeof(u32);
+		if (freqs == NULL || lenp != 2) {
+			printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
+			return 1;
+		}
+		ratio = of_get_property(cpunode, "processor-to-bus-ratio*2",
+						NULL);
+		if (ratio == NULL) {
+			printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
+			return 1;
+		}
+
+		/* Get the min/max bus frequencies */
+		low_freq = min(freqs[0], freqs[1]);
+		hi_freq = max(freqs[0], freqs[1]);
+
+		/* Grrrr.. It _seems_ that the device-tree is lying on the low bus
+		 * frequency, it claims it to be around 84Mhz on some models while
+		 * it appears to be approx. 101Mhz on all. Let's hack around here...
+		 * fortunately, we don't need to be too precise
+		 */
+		if (low_freq < 98000000)
+			low_freq = 101000000;
+
+		/* Convert those to CPU core clocks */
+		low_freq = (low_freq * (*ratio)) / 2000;
+		hi_freq = (hi_freq * (*ratio)) / 2000;
+
+		/* Now we get the frequencies, we read the GPIO to see what is out current
+		 * speed
+		 */
+		rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
+		cur_freq = (rc & 0x01) ? hi_freq : low_freq;
+
+		set_speed_proc = gpios_set_cpu_speed;
+		return 1;
+	}
+
+	/* If we use the PMU, look for the min & max frequencies in the
+	 * device-tree
+	 */
+	value = of_get_property(cpunode, "min-clock-frequency", NULL);
+	if (!value)
+		return 1;
+	low_freq = (*value) / 1000;
+	/* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
+	 * here */
+	if (low_freq < 100000)
+		low_freq *= 10;
+
+	value = of_get_property(cpunode, "max-clock-frequency", NULL);
+	if (!value)
+		return 1;
+	hi_freq = (*value) / 1000;
+	set_speed_proc = pmu_set_cpu_speed;
+	is_pmu_based = 1;
+
+	return 0;
+}
+
+static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
+{
+	struct device_node *volt_gpio_np;
+
+	if (of_get_property(cpunode, "dynamic-power-step", NULL) == NULL)
+		return 1;
+
+	volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+	if (volt_gpio_np)
+		voltage_gpio = read_gpio(volt_gpio_np);
+	if (!voltage_gpio){
+		printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
+		return 1;
+	}
+
+	/* OF only reports the high frequency */
+	hi_freq = cur_freq;
+	low_freq = cur_freq/2;
+
+	/* Read actual frequency from CPU */
+	cur_freq = dfs_get_cpu_speed();
+	set_speed_proc = dfs_set_cpu_speed;
+	get_speed_proc = dfs_get_cpu_speed;
+
+	return 0;
+}
+
+static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
+{
+	struct device_node *volt_gpio_np;
+	u32 pvr;
+	const u32 *value;
+
+	if (of_get_property(cpunode, "dynamic-power-step", NULL) == NULL)
+		return 1;
+
+	hi_freq = cur_freq;
+	value = of_get_property(cpunode, "reduced-clock-frequency", NULL);
+	if (!value)
+		return 1;
+	low_freq = (*value) / 1000;
+
+	volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+	if (volt_gpio_np)
+		voltage_gpio = read_gpio(volt_gpio_np);
+
+	pvr = mfspr(SPRN_PVR);
+	has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
+
+	set_speed_proc = cpu_750fx_cpu_speed;
+	get_speed_proc = cpu_750fx_get_cpu_speed;
+	cur_freq = cpu_750fx_get_cpu_speed();
+
+	return 0;
+}
+
+/* Currently, we support the following machines:
+ *
+ *  - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
+ *  - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
+ *  - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
+ *  - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
+ *  - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
+ *  - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
+ *  - Recent MacRISC3 laptops
+ *  - All new machines with 7447A CPUs
+ */
+static int __init pmac_cpufreq_setup(void)
+{
+	struct device_node	*cpunode;
+	const u32		*value;
+
+	if (strstr(cmd_line, "nocpufreq"))
+		return 0;
+
+	/* Assume only one CPU */
+	cpunode = of_find_node_by_type(NULL, "cpu");
+	if (!cpunode)
+		goto out;
+
+	/* Get current cpu clock freq */
+	value = of_get_property(cpunode, "clock-frequency", NULL);
+	if (!value)
+		goto out;
+	cur_freq = (*value) / 1000;
+	transition_latency = CPUFREQ_ETERNAL;
+
+	/*  Check for 7447A based MacRISC3 */
+	if (of_machine_is_compatible("MacRISC3") &&
+	    of_get_property(cpunode, "dynamic-power-step", NULL) &&
+	    PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
+		pmac_cpufreq_init_7447A(cpunode);
+		transition_latency = 8000000;
+	/* Check for other MacRISC3 machines */
+	} else if (of_machine_is_compatible("PowerBook3,4") ||
+		   of_machine_is_compatible("PowerBook3,5") ||
+		   of_machine_is_compatible("MacRISC3")) {
+		pmac_cpufreq_init_MacRISC3(cpunode);
+	/* Else check for iBook2 500/600 */
+	} else if (of_machine_is_compatible("PowerBook4,1")) {
+		hi_freq = cur_freq;
+		low_freq = 400000;
+		set_speed_proc = pmu_set_cpu_speed;
+		is_pmu_based = 1;
+	}
+	/* Else check for TiPb 550 */
+	else if (of_machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
+		hi_freq = cur_freq;
+		low_freq = 500000;
+		set_speed_proc = pmu_set_cpu_speed;
+		is_pmu_based = 1;
+	}
+	/* Else check for TiPb 400 & 500 */
+	else if (of_machine_is_compatible("PowerBook3,2")) {
+		/* We only know about the 400 MHz and the 500Mhz model
+		 * they both have 300 MHz as low frequency
+		 */
+		if (cur_freq < 350000 || cur_freq > 550000)
+			goto out;
+		hi_freq = cur_freq;
+		low_freq = 300000;
+		set_speed_proc = pmu_set_cpu_speed;
+		is_pmu_based = 1;
+	}
+	/* Else check for 750FX */
+	else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
+		pmac_cpufreq_init_750FX(cpunode);
+out:
+	of_node_put(cpunode);
+	if (set_speed_proc == NULL)
+		return -ENODEV;
+
+	pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
+	pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
+	ppc_proc_freq = cur_freq * 1000ul;
+
+	printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
+	printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
+	       low_freq/1000, hi_freq/1000, cur_freq/1000);
+
+	return cpufreq_register_driver(&pmac_cpufreq_driver);
+}
+
+module_init(pmac_cpufreq_setup);
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/pmac64-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/pmac64-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/pmac64-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/pmac64-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,746 @@
+/*
+ *  Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *  and                       Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This driver adds basic cpufreq support for SMU & 970FX based G5 Macs,
+ * that is iMac G5 and latest single CPU desktop.
+ */
+
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/sections.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/smu.h>
+#include <asm/pmac_pfunc.h>
+
+#define DBG(fmt...) pr_debug(fmt)
+
+/* see 970FX user manual */
+
+#define SCOM_PCR 0x0aa001			/* PCR scom addr */
+
+#define PCR_HILO_SELECT		0x80000000U	/* 1 = PCR, 0 = PCRH */
+#define PCR_SPEED_FULL		0x00000000U	/* 1:1 speed value */
+#define PCR_SPEED_HALF		0x00020000U	/* 1:2 speed value */
+#define PCR_SPEED_QUARTER	0x00040000U	/* 1:4 speed value */
+#define PCR_SPEED_MASK		0x000e0000U	/* speed mask */
+#define PCR_SPEED_SHIFT		17
+#define PCR_FREQ_REQ_VALID	0x00010000U	/* freq request valid */
+#define PCR_VOLT_REQ_VALID	0x00008000U	/* volt request valid */
+#define PCR_TARGET_TIME_MASK	0x00006000U	/* target time */
+#define PCR_STATLAT_MASK	0x00001f00U	/* STATLAT value */
+#define PCR_SNOOPLAT_MASK	0x000000f0U	/* SNOOPLAT value */
+#define PCR_SNOOPACC_MASK	0x0000000fU	/* SNOOPACC value */
+
+#define SCOM_PSR 0x408001			/* PSR scom addr */
+/* warning: PSR is a 64 bits register */
+#define PSR_CMD_RECEIVED	0x2000000000000000U   /* command received */
+#define PSR_CMD_COMPLETED	0x1000000000000000U   /* command completed */
+#define PSR_CUR_SPEED_MASK	0x0300000000000000U   /* current speed */
+#define PSR_CUR_SPEED_SHIFT	(56)
+
+/*
+ * The G5 only supports two frequencies (Quarter speed is not supported)
+ */
+#define CPUFREQ_HIGH                  0
+#define CPUFREQ_LOW                   1
+
+static struct cpufreq_frequency_table g5_cpu_freqs[] = {
+	{CPUFREQ_HIGH, 		0},
+	{CPUFREQ_LOW,		0},
+	{0,			CPUFREQ_TABLE_END},
+};
+
+static struct freq_attr* g5_cpu_freqs_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+/* Power mode data is an array of the 32 bits PCR values to use for
+ * the various frequencies, retrieved from the device-tree
+ */
+static int g5_pmode_cur;
+
+static void (*g5_switch_volt)(int speed_mode);
+static int (*g5_switch_freq)(int speed_mode);
+static int (*g5_query_freq)(void);
+
+static DEFINE_MUTEX(g5_switch_mutex);
+
+static unsigned long transition_latency;
+
+#ifdef CONFIG_PMAC_SMU
+
+static const u32 *g5_pmode_data;
+static int g5_pmode_max;
+
+static struct smu_sdbp_fvt *g5_fvt_table;	/* table of op. points */
+static int g5_fvt_count;			/* number of op. points */
+static int g5_fvt_cur;				/* current op. point */
+
+/*
+ * SMU based voltage switching for Neo2 platforms
+ */
+
+static void g5_smu_switch_volt(int speed_mode)
+{
+	struct smu_simple_cmd	cmd;
+
+	DECLARE_COMPLETION_ONSTACK(comp);
+	smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, smu_done_complete,
+			 &comp, 'V', 'S', 'L', 'E', 'W',
+			 0xff, g5_fvt_cur+1, speed_mode);
+	wait_for_completion(&comp);
+}
+
+/*
+ * Platform function based voltage/vdnap switching for Neo2
+ */
+
+static struct pmf_function *pfunc_set_vdnap0;
+static struct pmf_function *pfunc_vdnap0_complete;
+
+static void g5_vdnap_switch_volt(int speed_mode)
+{
+	struct pmf_args args;
+	u32 slew, done = 0;
+	unsigned long timeout;
+
+	slew = (speed_mode == CPUFREQ_LOW) ? 1 : 0;
+	args.count = 1;
+	args.u[0].p = &slew;
+
+	pmf_call_one(pfunc_set_vdnap0, &args);
+
+	/* It's an irq GPIO so we should be able to just block here,
+	 * I'll do that later after I've properly tested the IRQ code for
+	 * platform functions
+	 */
+	timeout = jiffies + HZ/10;
+	while(!time_after(jiffies, timeout)) {
+		args.count = 1;
+		args.u[0].p = &done;
+		pmf_call_one(pfunc_vdnap0_complete, &args);
+		if (done)
+			break;
+		msleep(1);
+	}
+	if (done == 0)
+		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
+}
+
+
+/*
+ * SCOM based frequency switching for 970FX rev3
+ */
+static int g5_scom_switch_freq(int speed_mode)
+{
+	unsigned long flags;
+	int to;
+
+	/* If frequency is going up, first ramp up the voltage */
+	if (speed_mode < g5_pmode_cur)
+		g5_switch_volt(speed_mode);
+
+	local_irq_save(flags);
+
+	/* Clear PCR high */
+	scom970_write(SCOM_PCR, 0);
+	/* Clear PCR low */
+       	scom970_write(SCOM_PCR, PCR_HILO_SELECT | 0);
+	/* Set PCR low */
+	scom970_write(SCOM_PCR, PCR_HILO_SELECT |
+		      g5_pmode_data[speed_mode]);
+
+	/* Wait for completion */
+	for (to = 0; to < 10; to++) {
+		unsigned long psr = scom970_read(SCOM_PSR);
+
+		if ((psr & PSR_CMD_RECEIVED) == 0 &&
+		    (((psr >> PSR_CUR_SPEED_SHIFT) ^
+		      (g5_pmode_data[speed_mode] >> PCR_SPEED_SHIFT)) & 0x3)
+		    == 0)
+			break;
+		if (psr & PSR_CMD_COMPLETED)
+			break;
+		udelay(100);
+	}
+
+	local_irq_restore(flags);
+
+	/* If frequency is going down, last ramp the voltage */
+	if (speed_mode > g5_pmode_cur)
+		g5_switch_volt(speed_mode);
+
+	g5_pmode_cur = speed_mode;
+	ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;
+
+	return 0;
+}
+
+static int g5_scom_query_freq(void)
+{
+	unsigned long psr = scom970_read(SCOM_PSR);
+	int i;
+
+	for (i = 0; i <= g5_pmode_max; i++)
+		if ((((psr >> PSR_CUR_SPEED_SHIFT) ^
+		      (g5_pmode_data[i] >> PCR_SPEED_SHIFT)) & 0x3) == 0)
+			break;
+	return i;
+}
+
+/*
+ * Fake voltage switching for platforms with missing support
+ */
+
+static void g5_dummy_switch_volt(int speed_mode)
+{
+}
+
+#endif /* CONFIG_PMAC_SMU */
+
+/*
+ * Platform function based voltage switching for PowerMac7,2 & 7,3
+ */
+
+static struct pmf_function *pfunc_cpu0_volt_high;
+static struct pmf_function *pfunc_cpu0_volt_low;
+static struct pmf_function *pfunc_cpu1_volt_high;
+static struct pmf_function *pfunc_cpu1_volt_low;
+
+static void g5_pfunc_switch_volt(int speed_mode)
+{
+	if (speed_mode == CPUFREQ_HIGH) {
+		if (pfunc_cpu0_volt_high)
+			pmf_call_one(pfunc_cpu0_volt_high, NULL);
+		if (pfunc_cpu1_volt_high)
+			pmf_call_one(pfunc_cpu1_volt_high, NULL);
+	} else {
+		if (pfunc_cpu0_volt_low)
+			pmf_call_one(pfunc_cpu0_volt_low, NULL);
+		if (pfunc_cpu1_volt_low)
+			pmf_call_one(pfunc_cpu1_volt_low, NULL);
+	}
+	msleep(10); /* should be faster , to fix */
+}
+
+/*
+ * Platform function based frequency switching for PowerMac7,2 & 7,3
+ */
+
+static struct pmf_function *pfunc_cpu_setfreq_high;
+static struct pmf_function *pfunc_cpu_setfreq_low;
+static struct pmf_function *pfunc_cpu_getfreq;
+static struct pmf_function *pfunc_slewing_done;
+
+static int g5_pfunc_switch_freq(int speed_mode)
+{
+	struct pmf_args args;
+	u32 done = 0;
+	unsigned long timeout;
+	int rc;
+
+	DBG("g5_pfunc_switch_freq(%d)\n", speed_mode);
+
+	/* If frequency is going up, first ramp up the voltage */
+	if (speed_mode < g5_pmode_cur)
+		g5_switch_volt(speed_mode);
+
+	/* Do it */
+	if (speed_mode == CPUFREQ_HIGH)
+		rc = pmf_call_one(pfunc_cpu_setfreq_high, NULL);
+	else
+		rc = pmf_call_one(pfunc_cpu_setfreq_low, NULL);
+
+	if (rc)
+		printk(KERN_WARNING "cpufreq: pfunc switch error %d\n", rc);
+
+	/* It's an irq GPIO so we should be able to just block here,
+	 * I'll do that later after I've properly tested the IRQ code for
+	 * platform functions
+	 */
+	timeout = jiffies + HZ/10;
+	while(!time_after(jiffies, timeout)) {
+		args.count = 1;
+		args.u[0].p = &done;
+		pmf_call_one(pfunc_slewing_done, &args);
+		if (done)
+			break;
+		msleep(1);
+	}
+	if (done == 0)
+		printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
+
+	/* If frequency is going down, last ramp the voltage */
+	if (speed_mode > g5_pmode_cur)
+		g5_switch_volt(speed_mode);
+
+	g5_pmode_cur = speed_mode;
+	ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;
+
+	return 0;
+}
+
+static int g5_pfunc_query_freq(void)
+{
+	struct pmf_args args;
+	u32 val = 0;
+
+	args.count = 1;
+	args.u[0].p = &val;
+	pmf_call_one(pfunc_cpu_getfreq, &args);
+	return val ? CPUFREQ_HIGH : CPUFREQ_LOW;
+}
+
+
+/*
+ * Common interface to the cpufreq core
+ */
+
+static int g5_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, g5_cpu_freqs);
+}
+
+static int g5_cpufreq_target(struct cpufreq_policy *policy,
+	unsigned int target_freq, unsigned int relation)
+{
+	unsigned int newstate = 0;
+	struct cpufreq_freqs freqs;
+	int rc;
+
+	if (cpufreq_frequency_table_target(policy, g5_cpu_freqs,
+			target_freq, relation, &newstate))
+		return -EINVAL;
+
+	if (g5_pmode_cur == newstate)
+		return 0;
+
+	mutex_lock(&g5_switch_mutex);
+
+	freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
+	freqs.new = g5_cpu_freqs[newstate].frequency;
+
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+	rc = g5_switch_freq(newstate);
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+
+	mutex_unlock(&g5_switch_mutex);
+
+	return rc;
+}
+
+static unsigned int g5_cpufreq_get_speed(unsigned int cpu)
+{
+	return g5_cpu_freqs[g5_pmode_cur].frequency;
+}
+
+static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	policy->cpuinfo.transition_latency = transition_latency;
+	policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
+	/* secondary CPUs are tied to the primary one by the
+	 * cpufreq core if in the secondary policy we tell it that
+	 * it actually must be one policy together with all others. */
+	cpumask_copy(policy->cpus, cpu_online_mask);
+	cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);
+
+	return cpufreq_frequency_table_cpuinfo(policy,
+		g5_cpu_freqs);
+}
+
+
+static struct cpufreq_driver g5_cpufreq_driver = {
+	.name		= "powermac",
+	.owner		= THIS_MODULE,
+	.flags		= CPUFREQ_CONST_LOOPS,
+	.init		= g5_cpufreq_cpu_init,
+	.verify		= g5_cpufreq_verify,
+	.target		= g5_cpufreq_target,
+	.get		= g5_cpufreq_get_speed,
+	.attr 		= g5_cpu_freqs_attr,
+};
+
+
+#ifdef CONFIG_PMAC_SMU
+
+static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
+{
+	struct device_node *cpunode;
+	unsigned int psize, ssize;
+	unsigned long max_freq;
+	char *freq_method, *volt_method;
+	const u32 *valp;
+	u32 pvr_hi;
+	int use_volts_vdnap = 0;
+	int use_volts_smu = 0;
+	int rc = -ENODEV;
+
+	/* Check supported platforms */
+	if (of_machine_is_compatible("PowerMac8,1") ||
+	    of_machine_is_compatible("PowerMac8,2") ||
+	    of_machine_is_compatible("PowerMac9,1"))
+		use_volts_smu = 1;
+	else if (of_machine_is_compatible("PowerMac11,2"))
+		use_volts_vdnap = 1;
+	else
+		return -ENODEV;
+
+	/* Get first CPU node */
+	for (cpunode = NULL;
+	     (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
+		const u32 *reg = of_get_property(cpunode, "reg", NULL);
+		if (reg == NULL || (*reg) != 0)
+			continue;
+		if (!strcmp(cpunode->type, "cpu"))
+			break;
+	}
+	if (cpunode == NULL) {
+		printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
+		return -ENODEV;
+	}
+
+	/* Check 970FX for now */
+	valp = of_get_property(cpunode, "cpu-version", NULL);
+	if (!valp) {
+		DBG("No cpu-version property !\n");
+		goto bail_noprops;
+	}
+	pvr_hi = (*valp) >> 16;
+	if (pvr_hi != 0x3c && pvr_hi != 0x44) {
+		printk(KERN_ERR "cpufreq: Unsupported CPU version\n");
+		goto bail_noprops;
+	}
+
+	/* Look for the powertune data in the device-tree */
+	g5_pmode_data = of_get_property(cpunode, "power-mode-data",&psize);
+	if (!g5_pmode_data) {
+		DBG("No power-mode-data !\n");
+		goto bail_noprops;
+	}
+	g5_pmode_max = psize / sizeof(u32) - 1;
+
+	if (use_volts_smu) {
+		const struct smu_sdbp_header *shdr;
+
+		/* Look for the FVT table */
+		shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
+		if (!shdr)
+			goto bail_noprops;
+		g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1];
+		ssize = (shdr->len * sizeof(u32)) -
+			sizeof(struct smu_sdbp_header);
+		g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt);
+		g5_fvt_cur = 0;
+
+		/* Sanity checking */
+		if (g5_fvt_count < 1 || g5_pmode_max < 1)
+			goto bail_noprops;
+
+		g5_switch_volt = g5_smu_switch_volt;
+		volt_method = "SMU";
+	} else if (use_volts_vdnap) {
+		struct device_node *root;
+
+		root = of_find_node_by_path("/");
+		if (root == NULL) {
+			printk(KERN_ERR "cpufreq: Can't find root of "
+			       "device tree\n");
+			goto bail_noprops;
+		}
+		pfunc_set_vdnap0 = pmf_find_function(root, "set-vdnap0");
+		pfunc_vdnap0_complete =
+			pmf_find_function(root, "slewing-done");
+		if (pfunc_set_vdnap0 == NULL ||
+		    pfunc_vdnap0_complete == NULL) {
+			printk(KERN_ERR "cpufreq: Can't find required "
+			       "platform function\n");
+			goto bail_noprops;
+		}
+
+		g5_switch_volt = g5_vdnap_switch_volt;
+		volt_method = "GPIO";
+	} else {
+		g5_switch_volt = g5_dummy_switch_volt;
+		volt_method = "none";
+	}
+
+	/*
+	 * From what I see, clock-frequency is always the maximal frequency.
+	 * The current driver can not slew sysclk yet, so we really only deal
+	 * with powertune steps for now. We also only implement full freq and
+	 * half freq in this version. So far, I haven't yet seen a machine
+	 * supporting anything else.
+	 */
+	valp = of_get_property(cpunode, "clock-frequency", NULL);
+	if (!valp)
+		return -ENODEV;
+	max_freq = (*valp)/1000;
+	g5_cpu_freqs[0].frequency = max_freq;
+	g5_cpu_freqs[1].frequency = max_freq/2;
+
+	/* Set callbacks */
+	transition_latency = 12000;
+	g5_switch_freq = g5_scom_switch_freq;
+	g5_query_freq = g5_scom_query_freq;
+	freq_method = "SCOM";
+
+	/* Force apply current frequency to make sure everything is in
+	 * sync (voltage is right for example). Firmware may leave us with
+	 * a strange setting ...
+	 */
+	g5_switch_volt(CPUFREQ_HIGH);
+	msleep(10);
+	g5_pmode_cur = -1;
+	g5_switch_freq(g5_query_freq());
+
+	printk(KERN_INFO "Registering G5 CPU frequency driver\n");
+	printk(KERN_INFO "Frequency method: %s, Voltage method: %s\n",
+	       freq_method, volt_method);
+	printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
+		g5_cpu_freqs[1].frequency/1000,
+		g5_cpu_freqs[0].frequency/1000,
+		g5_cpu_freqs[g5_pmode_cur].frequency/1000);
+
+	rc = cpufreq_register_driver(&g5_cpufreq_driver);
+
+	/* We keep the CPU node on hold... hopefully, Apple G5 don't have
+	 * hotplug CPU with a dynamic device-tree ...
+	 */
+	return rc;
+
+ bail_noprops:
+	of_node_put(cpunode);
+
+	return rc;
+}
+
+#endif /* CONFIG_PMAC_SMU */
+
+
+static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
+{
+	struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
+	const u8 *eeprom = NULL;
+	const u32 *valp;
+	u64 max_freq, min_freq, ih, il;
+	int has_volt = 1, rc = 0;
+
+	DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and"
+	    " RackMac3,1...\n");
+
+	/* Get first CPU node */
+	for (cpunode = NULL;
+	     (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
+		if (!strcmp(cpunode->type, "cpu"))
+			break;
+	}
+	if (cpunode == NULL) {
+		printk(KERN_ERR "cpufreq: Can't find any CPU node\n");
+		return -ENODEV;
+	}
+
+	/* Lookup the cpuid eeprom node */
+        cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
+	if (cpuid != NULL)
+		eeprom = of_get_property(cpuid, "cpuid", NULL);
+	if (eeprom == NULL) {
+		printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n");
+		rc = -ENODEV;
+		goto bail;
+	}
+
+	/* Lookup the i2c hwclock */
+	for (hwclock = NULL;
+	     (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){
+		const char *loc = of_get_property(hwclock,
+				"hwctrl-location", NULL);
+		if (loc == NULL)
+			continue;
+		if (strcmp(loc, "CPU CLOCK"))
+			continue;
+		if (!of_get_property(hwclock, "platform-get-frequency", NULL))
+			continue;
+		break;
+	}
+	if (hwclock == NULL) {
+		printk(KERN_ERR "cpufreq: Can't find i2c clock chip !\n");
+		rc = -ENODEV;
+		goto bail;
+	}
+
+	DBG("cpufreq: i2c clock chip found: %s\n", hwclock->full_name);
+
+	/* Now get all the platform functions */
+	pfunc_cpu_getfreq =
+		pmf_find_function(hwclock, "get-frequency");
+	pfunc_cpu_setfreq_high =
+		pmf_find_function(hwclock, "set-frequency-high");
+	pfunc_cpu_setfreq_low =
+		pmf_find_function(hwclock, "set-frequency-low");
+	pfunc_slewing_done =
+		pmf_find_function(hwclock, "slewing-done");
+	pfunc_cpu0_volt_high =
+		pmf_find_function(hwclock, "set-voltage-high-0");
+	pfunc_cpu0_volt_low =
+		pmf_find_function(hwclock, "set-voltage-low-0");
+	pfunc_cpu1_volt_high =
+		pmf_find_function(hwclock, "set-voltage-high-1");
+	pfunc_cpu1_volt_low =
+		pmf_find_function(hwclock, "set-voltage-low-1");
+
+	/* Check we have minimum requirements */
+	if (pfunc_cpu_getfreq == NULL || pfunc_cpu_setfreq_high == NULL ||
+	    pfunc_cpu_setfreq_low == NULL || pfunc_slewing_done == NULL) {
+		printk(KERN_ERR "cpufreq: Can't find platform functions !\n");
+		rc = -ENODEV;
+		goto bail;
+	}
+
+	/* Check that we have complete sets */
+	if (pfunc_cpu0_volt_high == NULL || pfunc_cpu0_volt_low == NULL) {
+		pmf_put_function(pfunc_cpu0_volt_high);
+		pmf_put_function(pfunc_cpu0_volt_low);
+		pfunc_cpu0_volt_high = pfunc_cpu0_volt_low = NULL;
+		has_volt = 0;
+	}
+	if (!has_volt ||
+	    pfunc_cpu1_volt_high == NULL || pfunc_cpu1_volt_low == NULL) {
+		pmf_put_function(pfunc_cpu1_volt_high);
+		pmf_put_function(pfunc_cpu1_volt_low);
+		pfunc_cpu1_volt_high = pfunc_cpu1_volt_low = NULL;
+	}
+
+	/* Note: The device tree also contains a "platform-set-values"
+	 * function for which I haven't quite figured out the usage. It
+	 * might have to be called on init and/or wakeup, I'm not too sure
+	 * but things seem to work fine without it so far ...
+	 */
+
+	/* Get max frequency from device-tree */
+	valp = of_get_property(cpunode, "clock-frequency", NULL);
+	if (!valp) {
+		printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n");
+		rc = -ENODEV;
+		goto bail;
+	}
+
+	max_freq = (*valp)/1000;
+
+	/* Now calculate reduced frequency by using the cpuid input freq
+	 * ratio. This requires 64 bits math unless we are willing to lose
+	 * some precision
+	 */
+	ih = *((u32 *)(eeprom + 0x10));
+	il = *((u32 *)(eeprom + 0x20));
+
+	/* Check for machines with no useful settings */
+	if (il == ih) {
+		printk(KERN_WARNING "cpufreq: No low frequency mode available"
+		       " on this model !\n");
+		rc = -ENODEV;
+		goto bail;
+	}
+
+	min_freq = 0;
+	if (ih != 0 && il != 0)
+		min_freq = (max_freq * il) / ih;
+
+	/* Sanity check */
+	if (min_freq >= max_freq || min_freq < 1000) {
+		printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n");
+		rc = -ENXIO;
+		goto bail;
+	}
+	g5_cpu_freqs[0].frequency = max_freq;
+	g5_cpu_freqs[1].frequency = min_freq;
+
+	/* Set callbacks */
+	transition_latency = CPUFREQ_ETERNAL;
+	g5_switch_volt = g5_pfunc_switch_volt;
+	g5_switch_freq = g5_pfunc_switch_freq;
+	g5_query_freq = g5_pfunc_query_freq;
+
+	/* Force apply current frequency to make sure everything is in
+	 * sync (voltage is right for example). Firmware may leave us with
+	 * a strange setting ...
+	 */
+	g5_switch_volt(CPUFREQ_HIGH);
+	msleep(10);
+	g5_pmode_cur = -1;
+	g5_switch_freq(g5_query_freq());
+
+	printk(KERN_INFO "Registering G5 CPU frequency driver\n");
+	printk(KERN_INFO "Frequency method: i2c/pfunc, "
+	       "Voltage method: %s\n", has_volt ? "i2c/pfunc" : "none");
+	printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
+		g5_cpu_freqs[1].frequency/1000,
+		g5_cpu_freqs[0].frequency/1000,
+		g5_cpu_freqs[g5_pmode_cur].frequency/1000);
+
+	rc = cpufreq_register_driver(&g5_cpufreq_driver);
+ bail:
+	if (rc != 0) {
+		pmf_put_function(pfunc_cpu_getfreq);
+		pmf_put_function(pfunc_cpu_setfreq_high);
+		pmf_put_function(pfunc_cpu_setfreq_low);
+		pmf_put_function(pfunc_slewing_done);
+		pmf_put_function(pfunc_cpu0_volt_high);
+		pmf_put_function(pfunc_cpu0_volt_low);
+		pmf_put_function(pfunc_cpu1_volt_high);
+		pmf_put_function(pfunc_cpu1_volt_low);
+	}
+	of_node_put(hwclock);
+	of_node_put(cpuid);
+	of_node_put(cpunode);
+
+	return rc;
+}
+
+static int __init g5_cpufreq_init(void)
+{
+	struct device_node *cpus;
+	int rc = 0;
+
+	cpus = of_find_node_by_path("/cpus");
+	if (cpus == NULL) {
+		DBG("No /cpus node !\n");
+		return -ENODEV;
+	}
+
+	if (of_machine_is_compatible("PowerMac7,2") ||
+	    of_machine_is_compatible("PowerMac7,3") ||
+	    of_machine_is_compatible("RackMac3,1"))
+		rc = g5_pm72_cpufreq_init(cpus);
+#ifdef CONFIG_PMAC_SMU
+	else
+		rc = g5_neo2_cpufreq_init(cpus);
+#endif /* CONFIG_PMAC_SMU */
+
+	of_node_put(cpus);
+	return rc;
+}
+
+module_init(g5_cpufreq_init);
+
+
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/powernow-k6.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/powernow-k6.c
--- linux-libre-3.10-gnu/drivers/cpufreq/powernow-k6.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/powernow-k6.c	2013-08-25 20:43:22.000000000 -0400
@@ -58,7 +58,7 @@ static int powernow_k6_get_cpu_multiplie
 	msrval = POWERNOW_IOPORT + 0x0;
 	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
 
-	return clock_ratio[(invalue >> 5)&7].index;
+	return clock_ratio[(invalue >> 5)&7].driver_data;
 }
 
 
@@ -75,13 +75,13 @@ static void powernow_k6_set_state(struct
 	unsigned long msrval;
 	struct cpufreq_freqs freqs;
 
-	if (clock_ratio[best_i].index > max_multiplier) {
+	if (clock_ratio[best_i].driver_data > max_multiplier) {
 		printk(KERN_ERR PFX "invalid target frequency\n");
 		return;
 	}
 
 	freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
-	freqs.new = busfreq * clock_ratio[best_i].index;
+	freqs.new = busfreq * clock_ratio[best_i].driver_data;
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
@@ -156,7 +156,7 @@ static int powernow_k6_cpu_init(struct c
 
 	/* table init */
 	for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
-		f = clock_ratio[i].index;
+		f = clock_ratio[i].driver_data;
 		if (f > max_multiplier)
 			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
 		else
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/powernow-k7.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/powernow-k7.c
--- linux-libre-3.10-gnu/drivers/cpufreq/powernow-k7.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/powernow-k7.c	2013-08-25 20:43:22.000000000 -0400
@@ -186,7 +186,7 @@ static int get_ranges(unsigned char *pst
 		fid = *pst++;
 
 		powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10;
-		powernow_table[j].index = fid; /* lower 8 bits */
+		powernow_table[j].driver_data = fid; /* lower 8 bits */
 
 		speed = powernow_table[j].frequency;
 
@@ -203,7 +203,7 @@ static int get_ranges(unsigned char *pst
 			maximum_speed = speed;
 
 		vid = *pst++;
-		powernow_table[j].index |= (vid << 8); /* upper 8 bits */
+		powernow_table[j].driver_data |= (vid << 8); /* upper 8 bits */
 
 		pr_debug("   FID: 0x%x (%d.%dx [%dMHz])  "
 			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
@@ -212,7 +212,7 @@ static int get_ranges(unsigned char *pst
 			 mobile_vid_table[vid]%1000);
 	}
 	powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
-	powernow_table[number_scales].index = 0;
+	powernow_table[number_scales].driver_data = 0;
 
 	return 0;
 }
@@ -260,8 +260,8 @@ static void change_speed(struct cpufreq_
 	 * vid are the upper 8 bits.
 	 */
 
-	fid = powernow_table[index].index & 0xFF;
-	vid = (powernow_table[index].index & 0xFF00) >> 8;
+	fid = powernow_table[index].driver_data & 0xFF;
+	vid = (powernow_table[index].driver_data & 0xFF00) >> 8;
 
 	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 	cfid = fidvidstatus.bits.CFID;
@@ -373,8 +373,8 @@ static int powernow_acpi_init(void)
 		fid = pc.bits.fid;
 
 		powernow_table[i].frequency = fsb * fid_codes[fid] / 10;
-		powernow_table[i].index = fid; /* lower 8 bits */
-		powernow_table[i].index |= (vid << 8); /* upper 8 bits */
+		powernow_table[i].driver_data = fid; /* lower 8 bits */
+		powernow_table[i].driver_data |= (vid << 8); /* upper 8 bits */
 
 		speed = powernow_table[i].frequency;
 		speed_mhz = speed / 1000;
@@ -417,7 +417,7 @@ static int powernow_acpi_init(void)
 	}
 
 	powernow_table[i].frequency = CPUFREQ_TABLE_END;
-	powernow_table[i].index = 0;
+	powernow_table[i].driver_data = 0;
 
 	/* notify BIOS that we exist */
 	acpi_processor_notify_smm(THIS_MODULE);
@@ -563,7 +563,7 @@ static int powernow_verify(struct cpufre
  * We will then get the same kind of behaviour already tested under
  * the "well-known" other OS.
  */
-static int __cpuinit fixup_sgtc(void)
+static int fixup_sgtc(void)
 {
 	unsigned int sgtc;
 	unsigned int m;
@@ -597,7 +597,7 @@ static unsigned int powernow_get(unsigne
 }
 
 
-static int __cpuinit acer_cpufreq_pst(const struct dmi_system_id *d)
+static int acer_cpufreq_pst(const struct dmi_system_id *d)
 {
 	printk(KERN_WARNING PFX
 		"%s laptop with broken PST tables in BIOS detected.\n",
@@ -615,7 +615,7 @@ static int __cpuinit acer_cpufreq_pst(co
  * A BIOS update is all that can save them.
  * Mention this, and disable cpufreq.
  */
-static struct dmi_system_id __cpuinitdata powernow_dmi_table[] = {
+static struct dmi_system_id powernow_dmi_table[] = {
 	{
 		.callback = acer_cpufreq_pst,
 		.ident = "Acer Aspire",
@@ -627,7 +627,7 @@ static struct dmi_system_id __cpuinitdat
 	{ }
 };
 
-static int __cpuinit powernow_cpu_init(struct cpufreq_policy *policy)
+static int powernow_cpu_init(struct cpufreq_policy *policy)
 {
 	union msr_fidvidstatus fidvidstatus;
 	int result;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/powernow-k8.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/powernow-k8.c
--- linux-libre-3.10-gnu/drivers/cpufreq/powernow-k8.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/powernow-k8.c	2013-08-25 20:43:22.000000000 -0400
@@ -584,9 +584,9 @@ static void print_basics(struct powernow
 				CPUFREQ_ENTRY_INVALID) {
 				printk(KERN_INFO PFX
 					"fid 0x%x (%d MHz), vid 0x%x\n",
-					data->powernow_table[j].index & 0xff,
+					data->powernow_table[j].driver_data & 0xff,
 					data->powernow_table[j].frequency/1000,
-					data->powernow_table[j].index >> 8);
+					data->powernow_table[j].driver_data >> 8);
 		}
 	}
 	if (data->batps)
@@ -632,13 +632,13 @@ static int fill_powernow_table(struct po
 
 	for (j = 0; j < data->numps; j++) {
 		int freq;
-		powernow_table[j].index = pst[j].fid; /* lower 8 bits */
-		powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */
+		powernow_table[j].driver_data = pst[j].fid; /* lower 8 bits */
+		powernow_table[j].driver_data |= (pst[j].vid << 8); /* upper 8 bits */
 		freq = find_khz_freq_from_fid(pst[j].fid);
 		powernow_table[j].frequency = freq;
 	}
 	powernow_table[data->numps].frequency = CPUFREQ_TABLE_END;
-	powernow_table[data->numps].index = 0;
+	powernow_table[data->numps].driver_data = 0;
 
 	if (query_current_values_with_pending_wait(data)) {
 		kfree(powernow_table);
@@ -810,7 +810,7 @@ static int powernow_k8_cpu_init_acpi(str
 
 	powernow_table[data->acpi_data.state_count].frequency =
 		CPUFREQ_TABLE_END;
-	powernow_table[data->acpi_data.state_count].index = 0;
+	powernow_table[data->acpi_data.state_count].driver_data = 0;
 	data->powernow_table = powernow_table;
 
 	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
@@ -865,7 +865,7 @@ static int fill_powernow_table_fidvid(st
 		pr_debug("   %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
 
 		index = fid | (vid<<8);
-		powernow_table[i].index = index;
+		powernow_table[i].driver_data = index;
 
 		freq = find_khz_freq_from_fid(fid);
 		powernow_table[i].frequency = freq;
@@ -941,8 +941,8 @@ static int transition_frequency_fidvid(s
 	 * the cpufreq frequency table in find_psb_table, vid
 	 * are the upper 8 bits.
 	 */
-	fid = data->powernow_table[index].index & 0xFF;
-	vid = (data->powernow_table[index].index & 0xFF00) >> 8;
+	fid = data->powernow_table[index].driver_data & 0xFF;
+	vid = (data->powernow_table[index].driver_data & 0xFF00) >> 8;
 
 	pr_debug("table matched fid 0x%x, giving vid 0x%x\n", fid, vid);
 
@@ -967,9 +967,9 @@ static int transition_frequency_fidvid(s
 
 	res = transition_fid_vid(data, fid, vid);
 	if (res)
-		return res;
-
-	freqs.new = find_khz_freq_from_fid(data->currfid);
+		freqs.new = freqs.old;
+	else
+		freqs.new = find_khz_freq_from_fid(data->currfid);
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 	return res;
@@ -1069,7 +1069,7 @@ struct init_on_cpu {
 	int rc;
 };
 
-static void __cpuinit powernowk8_cpu_init_on_cpu(void *_init_on_cpu)
+static void powernowk8_cpu_init_on_cpu(void *_init_on_cpu)
 {
 	struct init_on_cpu *init_on_cpu = _init_on_cpu;
 
@@ -1096,7 +1096,7 @@ static const char missing_pss_msg[] =
 	FW_BUG PFX "If that doesn't help, try upgrading your BIOS.\n";
 
 /* per CPU init entry point to the driver */
-static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
+static int powernowk8_cpu_init(struct cpufreq_policy *pol)
 {
 	struct powernow_k8_data *data;
 	struct init_on_cpu init_on_cpu;
@@ -1263,7 +1263,7 @@ static void __request_acpi_cpufreq(void)
 }
 
 /* driver entry point for init */
-static int __cpuinit powernowk8_init(void)
+static int powernowk8_init(void)
 {
 	unsigned int i, supported_cpus = 0;
 	int ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/ppc_cbe_cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/ppc_cbe_cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/ppc_cbe_cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/ppc_cbe_cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -106,7 +106,7 @@ static int cbe_cpufreq_cpu_init(struct c
 
 	/* initialize frequency table */
 	for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
-		cbe_freqs[i].frequency = max_freq / cbe_freqs[i].index;
+		cbe_freqs[i].frequency = max_freq / cbe_freqs[i].driver_data;
 		pr_debug("%d: %d\n", i, cbe_freqs[i].frequency);
 	}
 
@@ -165,7 +165,7 @@ static int cbe_cpufreq_target(struct cpu
 		 "1/%d of max frequency\n",
 		 policy->cpu,
 		 cbe_freqs[cbe_pmode_new].frequency,
-		 cbe_freqs[cbe_pmode_new].index);
+		 cbe_freqs[cbe_pmode_new].driver_data);
 
 	rc = set_pmode(policy->cpu, cbe_pmode_new);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/ppc-corenet-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/ppc-corenet-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/ppc-corenet-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/ppc-corenet-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/errno.h>
+#include <sysdev/fsl_soc.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+
+/**
+ * struct cpu_data - per CPU data struct
+ * @clk: the clk of CPU
+ * @parent: the parent node of cpu clock
+ * @table: frequency table
+ */
+struct cpu_data {
+	struct clk *clk;
+	struct device_node *parent;
+	struct cpufreq_frequency_table *table;
+};
+
+/**
+ * struct soc_data - SoC specific data
+ * @freq_mask: mask the disallowed frequencies
+ * @flag: unique flags
+ */
+struct soc_data {
+	u32 freq_mask[4];
+	u32 flag;
+};
+
+#define FREQ_MASK	1
+/* see hardware specification for the allowed frqeuencies */
+static const struct soc_data sdata[] = {
+	{ /* used by p2041 and p3041 */
+		.freq_mask = {0x8, 0x8, 0x2, 0x2},
+		.flag = FREQ_MASK,
+	},
+	{ /* used by p5020 */
+		.freq_mask = {0x8, 0x2},
+		.flag = FREQ_MASK,
+	},
+	{ /* used by p4080, p5040 */
+		.freq_mask = {0},
+		.flag = 0,
+	},
+};
+
+/*
+ * the minimum allowed core frequency, in Hz
+ * for chassis v1.0, >= platform frequency
+ * for chassis v2.0, >= platform frequency / 2
+ */
+static u32 min_cpufreq;
+static const u32 *fmask;
+
+/* serialize frequency changes  */
+static DEFINE_MUTEX(cpufreq_lock);
+static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
+
+/* cpumask in a cluster */
+static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
+
+#ifndef CONFIG_SMP
+static inline const struct cpumask *cpu_core_mask(int cpu)
+{
+	return cpumask_of(0);
+}
+#endif
+
+static unsigned int corenet_cpufreq_get_speed(unsigned int cpu)
+{
+	struct cpu_data *data = per_cpu(cpu_data, cpu);
+
+	return clk_get_rate(data->clk) / 1000;
+}
+
+/* reduce the duplicated frequencies in frequency table */
+static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
+		int count)
+{
+	int i, j;
+
+	for (i = 1; i < count; i++) {
+		for (j = 0; j < i; j++) {
+			if (freq_table[j].frequency == CPUFREQ_ENTRY_INVALID ||
+					freq_table[j].frequency !=
+					freq_table[i].frequency)
+				continue;
+
+			freq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+			break;
+		}
+	}
+}
+
+/* sort the frequencies in frequency table in descenting order */
+static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
+		int count)
+{
+	int i, j, ind;
+	unsigned int freq, max_freq;
+	struct cpufreq_frequency_table table;
+	for (i = 0; i < count - 1; i++) {
+		max_freq = freq_table[i].frequency;
+		ind = i;
+		for (j = i + 1; j < count; j++) {
+			freq = freq_table[j].frequency;
+			if (freq == CPUFREQ_ENTRY_INVALID ||
+					freq <= max_freq)
+				continue;
+			ind = j;
+			max_freq = freq;
+		}
+
+		if (ind != i) {
+			/* exchange the frequencies */
+			table.driver_data = freq_table[i].driver_data;
+			table.frequency = freq_table[i].frequency;
+			freq_table[i].driver_data = freq_table[ind].driver_data;
+			freq_table[i].frequency = freq_table[ind].frequency;
+			freq_table[ind].driver_data = table.driver_data;
+			freq_table[ind].frequency = table.frequency;
+		}
+	}
+}
+
+static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	struct device_node *np;
+	int i, count, ret;
+	u32 freq, mask;
+	struct clk *clk;
+	struct cpufreq_frequency_table *table;
+	struct cpu_data *data;
+	unsigned int cpu = policy->cpu;
+
+	np = of_get_cpu_node(cpu, NULL);
+	if (!np)
+		return -ENODEV;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		pr_err("%s: no memory\n", __func__);
+		goto err_np;
+	}
+
+	data->clk = of_clk_get(np, 0);
+	if (IS_ERR(data->clk)) {
+		pr_err("%s: no clock information\n", __func__);
+		goto err_nomem2;
+	}
+
+	data->parent = of_parse_phandle(np, "clocks", 0);
+	if (!data->parent) {
+		pr_err("%s: could not get clock information\n", __func__);
+		goto err_nomem2;
+	}
+
+	count = of_property_count_strings(data->parent, "clock-names");
+	table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL);
+	if (!table) {
+		pr_err("%s: no memory\n", __func__);
+		goto err_node;
+	}
+
+	if (fmask)
+		mask = fmask[get_hard_smp_processor_id(cpu)];
+	else
+		mask = 0x0;
+
+	for (i = 0; i < count; i++) {
+		clk = of_clk_get(data->parent, i);
+		freq = clk_get_rate(clk);
+		/*
+		 * the clock is valid if its frequency is not masked
+		 * and large than minimum allowed frequency.
+		 */
+		if (freq < min_cpufreq || (mask & (1 << i)))
+			table[i].frequency = CPUFREQ_ENTRY_INVALID;
+		else
+			table[i].frequency = freq / 1000;
+		table[i].driver_data = i;
+	}
+	freq_table_redup(table, count);
+	freq_table_sort(table, count);
+	table[i].frequency = CPUFREQ_TABLE_END;
+
+	/* set the min and max frequency properly */
+	ret = cpufreq_frequency_table_cpuinfo(policy, table);
+	if (ret) {
+		pr_err("invalid frequency table: %d\n", ret);
+		goto err_nomem1;
+	}
+
+	data->table = table;
+	per_cpu(cpu_data, cpu) = data;
+
+	/* update ->cpus if we have cluster, no harm if not */
+	cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
+	for_each_cpu(i, per_cpu(cpu_mask, cpu))
+		per_cpu(cpu_data, i) = data;
+
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cur = corenet_cpufreq_get_speed(policy->cpu);
+
+	cpufreq_frequency_table_get_attr(table, cpu);
+	of_node_put(np);
+
+	return 0;
+
+err_nomem1:
+	kfree(table);
+err_node:
+	of_node_put(data->parent);
+err_nomem2:
+	per_cpu(cpu_data, cpu) = NULL;
+	kfree(data);
+err_np:
+	of_node_put(np);
+
+	return -ENODEV;
+}
+
+static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+	struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+	unsigned int cpu;
+
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	of_node_put(data->parent);
+	kfree(data->table);
+	kfree(data);
+
+	for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
+		per_cpu(cpu_data, cpu) = NULL;
+
+	return 0;
+}
+
+static int corenet_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	struct cpufreq_frequency_table *table =
+		per_cpu(cpu_data, policy->cpu)->table;
+
+	return cpufreq_frequency_table_verify(policy, table);
+}
+
+static int corenet_cpufreq_target(struct cpufreq_policy *policy,
+		unsigned int target_freq, unsigned int relation)
+{
+	struct cpufreq_freqs freqs;
+	unsigned int new;
+	struct clk *parent;
+	int ret;
+	struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+
+	cpufreq_frequency_table_target(policy, data->table,
+			target_freq, relation, &new);
+
+	if (policy->cur == data->table[new].frequency)
+		return 0;
+
+	freqs.old = policy->cur;
+	freqs.new = data->table[new].frequency;
+
+	mutex_lock(&cpufreq_lock);
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+
+	parent = of_clk_get(data->parent, data->table[new].driver_data);
+	ret = clk_set_parent(data->clk, parent);
+	if (ret)
+		freqs.new = freqs.old;
+
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+	mutex_unlock(&cpufreq_lock);
+
+	return ret;
+}
+
+static struct freq_attr *corenet_cpufreq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
+	.name		= "ppc_cpufreq",
+	.owner		= THIS_MODULE,
+	.flags		= CPUFREQ_CONST_LOOPS,
+	.init		= corenet_cpufreq_cpu_init,
+	.exit		= __exit_p(corenet_cpufreq_cpu_exit),
+	.verify		= corenet_cpufreq_verify,
+	.target		= corenet_cpufreq_target,
+	.get		= corenet_cpufreq_get_speed,
+	.attr		= corenet_cpufreq_attr,
+};
+
+static const struct of_device_id node_matches[] __initdata = {
+	{ .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
+	{ .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
+	{ .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
+	{ .compatible = "fsl,p4080-clockgen", .data = &sdata[2], },
+	{ .compatible = "fsl,p5040-clockgen", .data = &sdata[2], },
+	{ .compatible = "fsl,qoriq-clockgen-2.0", },
+	{}
+};
+
+static int __init ppc_corenet_cpufreq_init(void)
+{
+	int ret;
+	struct device_node  *np;
+	const struct of_device_id *match;
+	const struct soc_data *data;
+	unsigned int cpu;
+
+	np = of_find_matching_node(NULL, node_matches);
+	if (!np)
+		return -ENODEV;
+
+	for_each_possible_cpu(cpu) {
+		if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
+			goto err_mask;
+		cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
+	}
+
+	match = of_match_node(node_matches, np);
+	data = match->data;
+	if (data) {
+		if (data->flag)
+			fmask = data->freq_mask;
+		min_cpufreq = fsl_get_sys_freq();
+	} else {
+		min_cpufreq = fsl_get_sys_freq() / 2;
+	}
+
+	of_node_put(np);
+
+	ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
+	if (!ret)
+		pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
+
+	return ret;
+
+err_mask:
+	for_each_possible_cpu(cpu)
+		free_cpumask_var(per_cpu(cpu_mask, cpu));
+
+	return -ENOMEM;
+}
+module_init(ppc_corenet_cpufreq_init);
+
+static void __exit ppc_corenet_cpufreq_exit(void)
+{
+	unsigned int cpu;
+
+	for_each_possible_cpu(cpu)
+		free_cpumask_var(per_cpu(cpu_mask, cpu));
+
+	cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
+}
+module_exit(ppc_corenet_cpufreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
+MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/pxa2xx-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/pxa2xx-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/pxa2xx-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/pxa2xx-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -420,7 +420,7 @@ static int pxa_cpufreq_init(struct cpufr
 	/* Generate pxa25x the run cpufreq_frequency_table struct */
 	for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) {
 		pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
-		pxa255_run_freq_table[i].index = i;
+		pxa255_run_freq_table[i].driver_data = i;
 	}
 	pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
 
@@ -428,7 +428,7 @@ static int pxa_cpufreq_init(struct cpufr
 	for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) {
 		pxa255_turbo_freq_table[i].frequency =
 			pxa255_turbo_freqs[i].khz;
-		pxa255_turbo_freq_table[i].index = i;
+		pxa255_turbo_freq_table[i].driver_data = i;
 	}
 	pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
 
@@ -440,9 +440,9 @@ static int pxa_cpufreq_init(struct cpufr
 		if (freq > pxa27x_maxfreq)
 			break;
 		pxa27x_freq_table[i].frequency = freq;
-		pxa27x_freq_table[i].index = i;
+		pxa27x_freq_table[i].driver_data = i;
 	}
-	pxa27x_freq_table[i].index = i;
+	pxa27x_freq_table[i].driver_data = i;
 	pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/pxa3xx-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/pxa3xx-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/pxa3xx-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/pxa3xx-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -98,10 +98,10 @@ static int setup_freqs_table(struct cpuf
 		return -ENOMEM;
 
 	for (i = 0; i < num; i++) {
-		table[i].index = i;
+		table[i].driver_data = i;
 		table[i].frequency = freqs[i].cpufreq_mhz * 1000;
 	}
-	table[num].index = i;
+	table[num].driver_data = i;
 	table[num].frequency = CPUFREQ_TABLE_END;
 
 	pxa3xx_freqs = freqs;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/s3c2410-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c2410-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/s3c2410-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c2410-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2006-2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 CPU Frequency scaling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq-core.h>
+
+/* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */
+
+static void s3c2410_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+	u32 clkdiv = 0;
+
+	if (cfg->divs.h_divisor == 2)
+		clkdiv |= S3C2410_CLKDIVN_HDIVN;
+
+	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+		clkdiv |= S3C2410_CLKDIVN_PDIVN;
+
+	__raw_writel(clkdiv, S3C2410_CLKDIVN);
+}
+
+static int s3c2410_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long hclk, fclk, pclk;
+	unsigned int hdiv, pdiv;
+	unsigned long hclk_max;
+
+	fclk = cfg->freq.fclk;
+	hclk_max = cfg->max.hclk;
+
+	cfg->freq.armclk = fclk;
+
+	s3c_freq_dbg("%s: fclk is %lu, max hclk %lu\n",
+		      __func__, fclk, hclk_max);
+
+	hdiv = (fclk > cfg->max.hclk) ? 2 : 1;
+	hclk = fclk / hdiv;
+
+	if (hclk > cfg->max.hclk) {
+		s3c_freq_dbg("%s: hclk too big\n", __func__);
+		return -EINVAL;
+	}
+
+	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+	pclk = hclk / pdiv;
+
+	if (pclk > cfg->max.pclk) {
+		s3c_freq_dbg("%s: pclk too big\n", __func__);
+		return -EINVAL;
+	}
+
+	pdiv *= hdiv;
+
+	/* record the result */
+	cfg->divs.p_divisor = pdiv;
+	cfg->divs.h_divisor = hdiv;
+
+	return 0;
+}
+
+static struct s3c_cpufreq_info s3c2410_cpufreq_info = {
+	.max		= {
+		.fclk	= 200000000,
+		.hclk	= 100000000,
+		.pclk	=  50000000,
+	},
+
+	/* transition latency is about 5ms worst-case, so
+	 * set 10ms to be sure */
+	.latency	= 10000000,
+
+	.locktime_m	= 150,
+	.locktime_u	= 150,
+	.locktime_bits	= 12,
+
+	.need_pll	= 1,
+
+	.name		= "s3c2410",
+	.calc_iotiming	= s3c2410_iotiming_calc,
+	.set_iotiming	= s3c2410_iotiming_set,
+	.get_iotiming	= s3c2410_iotiming_get,
+	.resume_clocks	= s3c2410_setup_clocks,
+
+	.set_fvco	= s3c2410_set_fvco,
+	.set_refresh	= s3c2410_cpufreq_setrefresh,
+	.set_divs	= s3c2410_cpufreq_setdivs,
+	.calc_divs	= s3c2410_cpufreq_calcdivs,
+
+	.debug_io_show	= s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
+};
+
+static int s3c2410_cpufreq_add(struct device *dev,
+			       struct subsys_interface *sif)
+{
+	return s3c_cpufreq_register(&s3c2410_cpufreq_info);
+}
+
+static struct subsys_interface s3c2410_cpufreq_interface = {
+	.name		= "s3c2410_cpufreq",
+	.subsys		= &s3c2410_subsys,
+	.add_dev	= s3c2410_cpufreq_add,
+};
+
+static int __init s3c2410_cpufreq_init(void)
+{
+	return subsys_interface_register(&s3c2410_cpufreq_interface);
+}
+arch_initcall(s3c2410_cpufreq_init);
+
+static int s3c2410a_cpufreq_add(struct device *dev,
+				struct subsys_interface *sif)
+{
+	/* alter the maximum freq settings for S3C2410A. If a board knows
+	 * it only has a maximum of 200, then it should register its own
+	 * limits. */
+
+	s3c2410_cpufreq_info.max.fclk = 266000000;
+	s3c2410_cpufreq_info.max.hclk = 133000000;
+	s3c2410_cpufreq_info.max.pclk =  66500000;
+	s3c2410_cpufreq_info.name = "s3c2410a";
+
+	return s3c2410_cpufreq_add(dev, sif);
+}
+
+static struct subsys_interface s3c2410a_cpufreq_interface = {
+	.name		= "s3c2410a_cpufreq",
+	.subsys		= &s3c2410a_subsys,
+	.add_dev	= s3c2410a_cpufreq_add,
+};
+
+static int __init s3c2410a_cpufreq_init(void)
+{
+	return subsys_interface_register(&s3c2410a_cpufreq_interface);
+}
+arch_initcall(s3c2410a_cpufreq_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/s3c2412-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c2412-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/s3c2412-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c2412-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 CPU Frequency scalling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+#include <mach/s3c2412.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq-core.h>
+
+/* our clock resources. */
+static struct clk *xtal;
+static struct clk *fclk;
+static struct clk *hclk;
+static struct clk *armclk;
+
+/* HDIV: 1, 2, 3, 4, 6, 8 */
+
+static int s3c2412_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned int hdiv, pdiv, armdiv, dvs;
+	unsigned long hclk, fclk, armclk, armdiv_clk;
+	unsigned long hclk_max;
+
+	fclk = cfg->freq.fclk;
+	armclk = cfg->freq.armclk;
+	hclk_max = cfg->max.hclk;
+
+	/* We can't run hclk above armclk as at the best we have to
+	 * have armclk and hclk in dvs mode. */
+
+	if (hclk_max > armclk)
+		hclk_max = armclk;
+
+	s3c_freq_dbg("%s: fclk=%lu, armclk=%lu, hclk_max=%lu\n",
+		     __func__, fclk, armclk, hclk_max);
+	s3c_freq_dbg("%s: want f=%lu, arm=%lu, h=%lu, p=%lu\n",
+		     __func__, cfg->freq.fclk, cfg->freq.armclk,
+		     cfg->freq.hclk, cfg->freq.pclk);
+
+	armdiv = fclk / armclk;
+
+	if (armdiv < 1)
+		armdiv = 1;
+	if (armdiv > 2)
+		armdiv = 2;
+
+	cfg->divs.arm_divisor = armdiv;
+	armdiv_clk = fclk / armdiv;
+
+	hdiv = armdiv_clk / hclk_max;
+	if (hdiv < 1)
+		hdiv = 1;
+
+	cfg->freq.hclk = hclk = armdiv_clk / hdiv;
+
+	/* set dvs depending on whether we reached armclk or not. */
+	cfg->divs.dvs = dvs = armclk < armdiv_clk;
+
+	/* update the actual armclk we achieved. */
+	cfg->freq.armclk = dvs ? hclk : armdiv_clk;
+
+	s3c_freq_dbg("%s: armclk %lu, hclk %lu, armdiv %d, hdiv %d, dvs %d\n",
+		     __func__, armclk, hclk, armdiv, hdiv, cfg->divs.dvs);
+
+	if (hdiv > 4)
+		goto invalid;
+
+	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+
+	if ((hclk / pdiv) > cfg->max.pclk)
+		pdiv++;
+
+	cfg->freq.pclk = hclk / pdiv;
+
+	s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
+
+	if (pdiv > 2)
+		goto invalid;
+
+	pdiv *= hdiv;
+
+	/* store the result, and then return */
+
+	cfg->divs.h_divisor = hdiv * armdiv;
+	cfg->divs.p_divisor = pdiv * armdiv;
+
+	return 0;
+
+invalid:
+	return -EINVAL;
+}
+
+static void s3c2412_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long clkdiv;
+	unsigned long olddiv;
+
+	olddiv = clkdiv = __raw_readl(S3C2410_CLKDIVN);
+
+	/* clear off current clock info */
+
+	clkdiv &= ~S3C2412_CLKDIVN_ARMDIVN;
+	clkdiv &= ~S3C2412_CLKDIVN_HDIVN_MASK;
+	clkdiv &= ~S3C2412_CLKDIVN_PDIVN;
+
+	if (cfg->divs.arm_divisor == 2)
+		clkdiv |= S3C2412_CLKDIVN_ARMDIVN;
+
+	clkdiv |= ((cfg->divs.h_divisor / cfg->divs.arm_divisor) - 1);
+
+	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+		clkdiv |= S3C2412_CLKDIVN_PDIVN;
+
+	s3c_freq_dbg("%s: div %08lx => %08lx\n", __func__, olddiv, clkdiv);
+	__raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+	clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
+}
+
+static void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+	struct s3c_cpufreq_board *board = cfg->board;
+	unsigned long refresh;
+
+	s3c_freq_dbg("%s: refresh %u ns, hclk %lu\n", __func__,
+		     board->refresh, cfg->freq.hclk);
+
+	/* Reduce both the refresh time (in ns) and the frequency (in MHz)
+	 * by 10 each to ensure that we do not overflow 32 bit numbers. This
+	 * should work for HCLK up to 133MHz and refresh period up to 30usec.
+	 */
+
+	refresh = (board->refresh / 10);
+	refresh *= (cfg->freq.hclk / 100);
+	refresh /= (1 * 1000 * 1000);	/* 10^6 */
+
+	s3c_freq_dbg("%s: setting refresh 0x%08lx\n", __func__, refresh);
+	__raw_writel(refresh, S3C2412_REFRESH);
+}
+
+/* set the default cpu frequency information, based on an 200MHz part
+ * as we have no other way of detecting the speed rating in software.
+ */
+
+static struct s3c_cpufreq_info s3c2412_cpufreq_info = {
+	.max		= {
+		.fclk	= 200000000,
+		.hclk	= 100000000,
+		.pclk	=  50000000,
+	},
+
+	.latency	= 5000000, /* 5ms */
+
+	.locktime_m	= 150,
+	.locktime_u	= 150,
+	.locktime_bits	= 16,
+
+	.name		= "s3c2412",
+	.set_refresh	= s3c2412_cpufreq_setrefresh,
+	.set_divs	= s3c2412_cpufreq_setdivs,
+	.calc_divs	= s3c2412_cpufreq_calcdivs,
+
+	.calc_iotiming	= s3c2412_iotiming_calc,
+	.set_iotiming	= s3c2412_iotiming_set,
+	.get_iotiming	= s3c2412_iotiming_get,
+
+	.resume_clocks	= s3c2412_setup_clocks,
+
+	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs),
+};
+
+static int s3c2412_cpufreq_add(struct device *dev,
+			       struct subsys_interface *sif)
+{
+	unsigned long fclk_rate;
+
+	hclk = clk_get(NULL, "hclk");
+	if (IS_ERR(hclk)) {
+		printk(KERN_ERR "%s: cannot find hclk clock\n", __func__);
+		return -ENOENT;
+	}
+
+	fclk = clk_get(NULL, "fclk");
+	if (IS_ERR(fclk)) {
+		printk(KERN_ERR "%s: cannot find fclk clock\n", __func__);
+		goto err_fclk;
+	}
+
+	fclk_rate = clk_get_rate(fclk);
+	if (fclk_rate > 200000000) {
+		printk(KERN_INFO
+		       "%s: fclk %ld MHz, assuming 266MHz capable part\n",
+		       __func__, fclk_rate / 1000000);
+		s3c2412_cpufreq_info.max.fclk = 266000000;
+		s3c2412_cpufreq_info.max.hclk = 133000000;
+		s3c2412_cpufreq_info.max.pclk =  66000000;
+	}
+
+	armclk = clk_get(NULL, "armclk");
+	if (IS_ERR(armclk)) {
+		printk(KERN_ERR "%s: cannot find arm clock\n", __func__);
+		goto err_armclk;
+	}
+
+	xtal = clk_get(NULL, "xtal");
+	if (IS_ERR(xtal)) {
+		printk(KERN_ERR "%s: cannot find xtal clock\n", __func__);
+		goto err_xtal;
+	}
+
+	return s3c_cpufreq_register(&s3c2412_cpufreq_info);
+
+err_xtal:
+	clk_put(armclk);
+err_armclk:
+	clk_put(fclk);
+err_fclk:
+	clk_put(hclk);
+
+	return -ENOENT;
+}
+
+static struct subsys_interface s3c2412_cpufreq_interface = {
+	.name		= "s3c2412_cpufreq",
+	.subsys		= &s3c2412_subsys,
+	.add_dev	= s3c2412_cpufreq_add,
+};
+
+static int s3c2412_cpufreq_init(void)
+{
+	return subsys_interface_register(&s3c2412_cpufreq_interface);
+}
+arch_initcall(s3c2412_cpufreq_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/s3c2416-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c2416-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/s3c2416-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c2416-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -205,7 +205,7 @@ static int s3c2416_cpufreq_leave_dvs(str
 		ret = s3c2416_cpufreq_set_armdiv(s3c_freq,
 					clk_get_rate(s3c_freq->hclk) / 1000);
 		if (ret < 0) {
-			pr_err("cpufreq: Failed to to set the armdiv to %lukHz: %d\n",
+			pr_err("cpufreq: Failed to set the armdiv to %lukHz: %d\n",
 			       clk_get_rate(s3c_freq->hclk) / 1000, ret);
 			return ret;
 		}
@@ -244,7 +244,7 @@ static int s3c2416_cpufreq_set_target(st
 	if (ret != 0)
 		goto out;
 
-	idx = s3c_freq->freq_table[i].index;
+	idx = s3c_freq->freq_table[i].driver_data;
 
 	if (idx == SOURCE_HCLK)
 		to_dvs = 1;
@@ -312,7 +312,7 @@ static void __init s3c2416_cpufreq_cfg_r
 		if (freq->frequency == CPUFREQ_ENTRY_INVALID)
 			continue;
 
-		dvfs = &s3c2416_dvfs_table[freq->index];
+		dvfs = &s3c2416_dvfs_table[freq->driver_data];
 		found = 0;
 
 		/* Check only the min-voltage, more is always ok on S3C2416 */
@@ -462,7 +462,7 @@ static int __init s3c2416_cpufreq_driver
 	freq = s3c_freq->freq_table;
 	while (freq->frequency != CPUFREQ_TABLE_END) {
 		/* special handling for dvs mode */
-		if (freq->index == 0) {
+		if (freq->driver_data == 0) {
 			if (!s3c_freq->hclk) {
 				pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n",
 					 freq->frequency);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/s3c2440-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c2440-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/s3c2440-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c2440-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2006-2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	Vincent Sanders <vince@simtec.co.uk>
+ *
+ * S3C2440/S3C2442 CPU Frequency scaling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+#include <plat/clock.h>
+
+static struct clk *xtal;
+static struct clk *fclk;
+static struct clk *hclk;
+static struct clk *armclk;
+
+/* HDIV: 1, 2, 3, 4, 6, 8 */
+
+static inline int within_khz(unsigned long a, unsigned long b)
+{
+	long diff = a - b;
+
+	return (diff >= -1000 && diff <= 1000);
+}
+
+/**
+ * s3c2440_cpufreq_calcdivs - calculate divider settings
+ * @cfg: The cpu frequency settings.
+ *
+ * Calcualte the divider values for the given frequency settings
+ * specified in @cfg. The values are stored in @cfg for later use
+ * by the relevant set routine if the request settings can be reached.
+ */
+int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned int hdiv, pdiv;
+	unsigned long hclk, fclk, armclk;
+	unsigned long hclk_max;
+
+	fclk = cfg->freq.fclk;
+	armclk = cfg->freq.armclk;
+	hclk_max = cfg->max.hclk;
+
+	s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n",
+		     __func__, fclk, armclk, hclk_max);
+
+	if (armclk > fclk) {
+		printk(KERN_WARNING "%s: armclk > fclk\n", __func__);
+		armclk = fclk;
+	}
+
+	/* if we are in DVS, we need HCLK to be <= ARMCLK */
+	if (armclk < fclk && armclk < hclk_max)
+		hclk_max = armclk;
+
+	for (hdiv = 1; hdiv < 9; hdiv++) {
+		if (hdiv == 5 || hdiv == 7)
+			hdiv++;
+
+		hclk = (fclk / hdiv);
+		if (hclk <= hclk_max || within_khz(hclk, hclk_max))
+			break;
+	}
+
+	s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv);
+
+	if (hdiv > 8)
+		goto invalid;
+
+	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+
+	if ((hclk / pdiv) > cfg->max.pclk)
+		pdiv++;
+
+	s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
+
+	if (pdiv > 2)
+		goto invalid;
+
+	pdiv *= hdiv;
+
+	/* calculate a valid armclk */
+
+	if (armclk < hclk)
+		armclk = hclk;
+
+	/* if we're running armclk lower than fclk, this really means
+	 * that the system should go into dvs mode, which means that
+	 * armclk is connected to hclk. */
+	if (armclk < fclk) {
+		cfg->divs.dvs = 1;
+		armclk = hclk;
+	} else
+		cfg->divs.dvs = 0;
+
+	cfg->freq.armclk = armclk;
+
+	/* store the result, and then return */
+
+	cfg->divs.h_divisor = hdiv;
+	cfg->divs.p_divisor = pdiv;
+
+	return 0;
+
+ invalid:
+	return -EINVAL;
+}
+
+#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \
+			   S3C2440_CAMDIVN_HCLK4_HALF)
+
+/**
+ * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings
+ * @cfg: The cpu frequency settings.
+ *
+ * Set the divisors from the settings in @cfg, which where generated
+ * during the calculation phase by s3c2440_cpufreq_calcdivs().
+ */
+static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long clkdiv, camdiv;
+
+	s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__,
+		     cfg->divs.h_divisor, cfg->divs.p_divisor);
+
+	clkdiv = __raw_readl(S3C2410_CLKDIVN);
+	camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+	clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN);
+	camdiv &= ~CAMDIVN_HCLK_HALF;
+
+	switch (cfg->divs.h_divisor) {
+	case 1:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_1;
+		break;
+
+	case 2:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_2;
+		break;
+
+	case 6:
+		camdiv |= S3C2440_CAMDIVN_HCLK3_HALF;
+	case 3:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6;
+		break;
+
+	case 8:
+		camdiv |= S3C2440_CAMDIVN_HCLK4_HALF;
+	case 4:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8;
+		break;
+
+	default:
+		BUG();	/* we don't expect to get here. */
+	}
+
+	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+		clkdiv |= S3C2440_CLKDIVN_PDIVN;
+
+	/* todo - set pclk. */
+
+	/* Write the divisors first with hclk intentionally halved so that
+	 * when we write clkdiv we will under-frequency instead of over. We
+	 * then make a short delay and remove the hclk halving if necessary.
+	 */
+
+	__raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN);
+	__raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+	ndelay(20);
+	__raw_writel(camdiv, S3C2440_CAMDIVN);
+
+	clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
+}
+
+static int run_freq_for(unsigned long max_hclk, unsigned long fclk,
+			int *divs,
+			struct cpufreq_frequency_table *table,
+			size_t table_size)
+{
+	unsigned long freq;
+	int index = 0;
+	int div;
+
+	for (div = *divs; div > 0; div = *divs++) {
+		freq = fclk / div;
+
+		if (freq > max_hclk && div != 1)
+			continue;
+
+		freq /= 1000; /* table is in kHz */
+		index = s3c_cpufreq_addfreq(table, index, table_size, freq);
+		if (index < 0)
+			break;
+	}
+
+	return index;
+}
+
+static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 };
+
+static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg,
+				     struct cpufreq_frequency_table *table,
+				     size_t table_size)
+{
+	int ret;
+
+	WARN_ON(cfg->info == NULL);
+	WARN_ON(cfg->board == NULL);
+
+	ret = run_freq_for(cfg->info->max.hclk,
+			   cfg->info->max.fclk,
+			   hclk_divs,
+			   table, table_size);
+
+	s3c_freq_dbg("%s: returning %d\n", __func__, ret);
+
+	return ret;
+}
+
+struct s3c_cpufreq_info s3c2440_cpufreq_info = {
+	.max		= {
+		.fclk	= 400000000,
+		.hclk	= 133333333,
+		.pclk	=  66666666,
+	},
+
+	.locktime_m	= 300,
+	.locktime_u	= 300,
+	.locktime_bits	= 16,
+
+	.name		= "s3c244x",
+	.calc_iotiming	= s3c2410_iotiming_calc,
+	.set_iotiming	= s3c2410_iotiming_set,
+	.get_iotiming	= s3c2410_iotiming_get,
+	.set_fvco	= s3c2410_set_fvco,
+
+	.set_refresh	= s3c2410_cpufreq_setrefresh,
+	.set_divs	= s3c2440_cpufreq_setdivs,
+	.calc_divs	= s3c2440_cpufreq_calcdivs,
+	.calc_freqtable	= s3c2440_cpufreq_calctable,
+
+	.resume_clocks	= s3c244x_setup_clocks,
+
+	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
+};
+
+static int s3c2440_cpufreq_add(struct device *dev,
+			       struct subsys_interface *sif)
+{
+	xtal = s3c_cpufreq_clk_get(NULL, "xtal");
+	hclk = s3c_cpufreq_clk_get(NULL, "hclk");
+	fclk = s3c_cpufreq_clk_get(NULL, "fclk");
+	armclk = s3c_cpufreq_clk_get(NULL, "armclk");
+
+	if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) {
+		printk(KERN_ERR "%s: failed to get clocks\n", __func__);
+		return -ENOENT;
+	}
+
+	return s3c_cpufreq_register(&s3c2440_cpufreq_info);
+}
+
+static struct subsys_interface s3c2440_cpufreq_interface = {
+	.name		= "s3c2440_cpufreq",
+	.subsys		= &s3c2440_subsys,
+	.add_dev	= s3c2440_cpufreq_add,
+};
+
+static int s3c2440_cpufreq_init(void)
+{
+	return subsys_interface_register(&s3c2440_cpufreq_interface);
+}
+
+/* arch_initcall adds the clocks we need, so use subsys_initcall. */
+subsys_initcall(s3c2440_cpufreq_init);
+
+static struct subsys_interface s3c2442_cpufreq_interface = {
+	.name		= "s3c2442_cpufreq",
+	.subsys		= &s3c2442_subsys,
+	.add_dev	= s3c2440_cpufreq_add,
+};
+
+static int s3c2442_cpufreq_init(void)
+{
+	return subsys_interface_register(&s3c2442_cpufreq_interface);
+}
+subsys_initcall(s3c2442_cpufreq_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/s3c24xx-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c24xx-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/s3c24xx-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c24xx-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,711 @@
+/*
+ * Copyright (c) 2006-2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq-core.h>
+
+#include <mach/regs-clock.h>
+
+/* note, cpufreq support deals in kHz, no Hz */
+
+static struct cpufreq_driver s3c24xx_driver;
+static struct s3c_cpufreq_config cpu_cur;
+static struct s3c_iotimings s3c24xx_iotiming;
+static struct cpufreq_frequency_table *pll_reg;
+static unsigned int last_target = ~0;
+static unsigned int ftab_size;
+static struct cpufreq_frequency_table *ftab;
+
+static struct clk *_clk_mpll;
+static struct clk *_clk_xtal;
+static struct clk *clk_fclk;
+static struct clk *clk_hclk;
+static struct clk *clk_pclk;
+static struct clk *clk_arm;
+
+#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS
+struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void)
+{
+	return &cpu_cur;
+}
+
+struct s3c_iotimings *s3c_cpufreq_getiotimings(void)
+{
+	return &s3c24xx_iotiming;
+}
+#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS */
+
+static void s3c_cpufreq_getcur(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long fclk, pclk, hclk, armclk;
+
+	cfg->freq.fclk = fclk = clk_get_rate(clk_fclk);
+	cfg->freq.hclk = hclk = clk_get_rate(clk_hclk);
+	cfg->freq.pclk = pclk = clk_get_rate(clk_pclk);
+	cfg->freq.armclk = armclk = clk_get_rate(clk_arm);
+
+	cfg->pll.driver_data = __raw_readl(S3C2410_MPLLCON);
+	cfg->pll.frequency = fclk;
+
+	cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
+
+	cfg->divs.h_divisor = fclk / hclk;
+	cfg->divs.p_divisor = fclk / pclk;
+}
+
+static inline void s3c_cpufreq_calc(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long pll = cfg->pll.frequency;
+
+	cfg->freq.fclk = pll;
+	cfg->freq.hclk = pll / cfg->divs.h_divisor;
+	cfg->freq.pclk = pll / cfg->divs.p_divisor;
+
+	/* convert hclk into 10ths of nanoseconds for io calcs */
+	cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
+}
+
+static inline int closer(unsigned int target, unsigned int n, unsigned int c)
+{
+	int diff_cur = abs(target - c);
+	int diff_new = abs(target - n);
+
+	return (diff_new < diff_cur);
+}
+
+static void s3c_cpufreq_show(const char *pfx,
+				 struct s3c_cpufreq_config *cfg)
+{
+	s3c_freq_dbg("%s: Fvco=%u, F=%lu, A=%lu, H=%lu (%u), P=%lu (%u)\n",
+		     pfx, cfg->pll.frequency, cfg->freq.fclk, cfg->freq.armclk,
+		     cfg->freq.hclk, cfg->divs.h_divisor,
+		     cfg->freq.pclk, cfg->divs.p_divisor);
+}
+
+/* functions to wrapper the driver info calls to do the cpu specific work */
+
+static void s3c_cpufreq_setio(struct s3c_cpufreq_config *cfg)
+{
+	if (cfg->info->set_iotiming)
+		(cfg->info->set_iotiming)(cfg, &s3c24xx_iotiming);
+}
+
+static int s3c_cpufreq_calcio(struct s3c_cpufreq_config *cfg)
+{
+	if (cfg->info->calc_iotiming)
+		return (cfg->info->calc_iotiming)(cfg, &s3c24xx_iotiming);
+
+	return 0;
+}
+
+static void s3c_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+	(cfg->info->set_refresh)(cfg);
+}
+
+static void s3c_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+	(cfg->info->set_divs)(cfg);
+}
+
+static int s3c_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+	return (cfg->info->calc_divs)(cfg);
+}
+
+static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg)
+{
+	(cfg->info->set_fvco)(cfg);
+}
+
+static inline void s3c_cpufreq_resume_clocks(void)
+{
+	cpu_cur.info->resume_clocks();
+}
+
+static inline void s3c_cpufreq_updateclk(struct clk *clk,
+					 unsigned int freq)
+{
+	clk_set_rate(clk, freq);
+}
+
+static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
+				 unsigned int target_freq,
+				 struct cpufreq_frequency_table *pll)
+{
+	struct s3c_cpufreq_freqs freqs;
+	struct s3c_cpufreq_config cpu_new;
+	unsigned long flags;
+
+	cpu_new = cpu_cur;  /* copy new from current */
+
+	s3c_cpufreq_show("cur", &cpu_cur);
+
+	/* TODO - check for DMA currently outstanding */
+
+	cpu_new.pll = pll ? *pll : cpu_cur.pll;
+
+	if (pll)
+		freqs.pll_changing = 1;
+
+	/* update our frequencies */
+
+	cpu_new.freq.armclk = target_freq;
+	cpu_new.freq.fclk = cpu_new.pll.frequency;
+
+	if (s3c_cpufreq_calcdivs(&cpu_new) < 0) {
+		printk(KERN_ERR "no divisors for %d\n", target_freq);
+		goto err_notpossible;
+	}
+
+	s3c_freq_dbg("%s: got divs\n", __func__);
+
+	s3c_cpufreq_calc(&cpu_new);
+
+	s3c_freq_dbg("%s: calculated frequencies for new\n", __func__);
+
+	if (cpu_new.freq.hclk != cpu_cur.freq.hclk) {
+		if (s3c_cpufreq_calcio(&cpu_new) < 0) {
+			printk(KERN_ERR "%s: no IO timings\n", __func__);
+			goto err_notpossible;
+		}
+	}
+
+	s3c_cpufreq_show("new", &cpu_new);
+
+	/* setup our cpufreq parameters */
+
+	freqs.old = cpu_cur.freq;
+	freqs.new = cpu_new.freq;
+
+	freqs.freqs.old = cpu_cur.freq.armclk / 1000;
+	freqs.freqs.new = cpu_new.freq.armclk / 1000;
+
+	/* update f/h/p clock settings before we issue the change
+	 * notification, so that drivers do not need to do anything
+	 * special if they want to recalculate on CPUFREQ_PRECHANGE. */
+
+	s3c_cpufreq_updateclk(_clk_mpll, cpu_new.pll.frequency);
+	s3c_cpufreq_updateclk(clk_fclk, cpu_new.freq.fclk);
+	s3c_cpufreq_updateclk(clk_hclk, cpu_new.freq.hclk);
+	s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
+
+	/* start the frequency change */
+	cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_PRECHANGE);
+
+	/* If hclk is staying the same, then we do not need to
+	 * re-write the IO or the refresh timings whilst we are changing
+	 * speed. */
+
+	local_irq_save(flags);
+
+	/* is our memory clock slowing down? */
+	if (cpu_new.freq.hclk < cpu_cur.freq.hclk) {
+		s3c_cpufreq_setrefresh(&cpu_new);
+		s3c_cpufreq_setio(&cpu_new);
+	}
+
+	if (cpu_new.freq.fclk == cpu_cur.freq.fclk) {
+		/* not changing PLL, just set the divisors */
+
+		s3c_cpufreq_setdivs(&cpu_new);
+	} else {
+		if (cpu_new.freq.fclk < cpu_cur.freq.fclk) {
+			/* slow the cpu down, then set divisors */
+
+			s3c_cpufreq_setfvco(&cpu_new);
+			s3c_cpufreq_setdivs(&cpu_new);
+		} else {
+			/* set the divisors, then speed up */
+
+			s3c_cpufreq_setdivs(&cpu_new);
+			s3c_cpufreq_setfvco(&cpu_new);
+		}
+	}
+
+	/* did our memory clock speed up */
+	if (cpu_new.freq.hclk > cpu_cur.freq.hclk) {
+		s3c_cpufreq_setrefresh(&cpu_new);
+		s3c_cpufreq_setio(&cpu_new);
+	}
+
+	/* update our current settings */
+	cpu_cur = cpu_new;
+
+	local_irq_restore(flags);
+
+	/* notify everyone we've done this */
+	cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_POSTCHANGE);
+
+	s3c_freq_dbg("%s: finished\n", __func__);
+	return 0;
+
+ err_notpossible:
+	printk(KERN_ERR "no compatible settings for %d\n", target_freq);
+	return -EINVAL;
+}
+
+/* s3c_cpufreq_target
+ *
+ * called by the cpufreq core to adjust the frequency that the CPU
+ * is currently running at.
+ */
+
+static int s3c_cpufreq_target(struct cpufreq_policy *policy,
+			      unsigned int target_freq,
+			      unsigned int relation)
+{
+	struct cpufreq_frequency_table *pll;
+	unsigned int index;
+
+	/* avoid repeated calls which cause a needless amout of duplicated
+	 * logging output (and CPU time as the calculation process is
+	 * done) */
+	if (target_freq == last_target)
+		return 0;
+
+	last_target = target_freq;
+
+	s3c_freq_dbg("%s: policy %p, target %u, relation %u\n",
+		     __func__, policy, target_freq, relation);
+
+	if (ftab) {
+		if (cpufreq_frequency_table_target(policy, ftab,
+						   target_freq, relation,
+						   &index)) {
+			s3c_freq_dbg("%s: table failed\n", __func__);
+			return -EINVAL;
+		}
+
+		s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__,
+			     target_freq, index, ftab[index].frequency);
+		target_freq = ftab[index].frequency;
+	}
+
+	target_freq *= 1000;  /* convert target to Hz */
+
+	/* find the settings for our new frequency */
+
+	if (!pll_reg || cpu_cur.lock_pll) {
+		/* either we've not got any PLL values, or we've locked
+		 * to the current one. */
+		pll = NULL;
+	} else {
+		struct cpufreq_policy tmp_policy;
+		int ret;
+
+		/* we keep the cpu pll table in Hz, to ensure we get an
+		 * accurate value for the PLL output. */
+
+		tmp_policy.min = policy->min * 1000;
+		tmp_policy.max = policy->max * 1000;
+		tmp_policy.cpu = policy->cpu;
+
+		/* cpufreq_frequency_table_target uses a pointer to 'index'
+		 * which is the number of the table entry, not the value of
+		 * the table entry's index field. */
+
+		ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg,
+						     target_freq, relation,
+						     &index);
+
+		if (ret < 0) {
+			printk(KERN_ERR "%s: no PLL available\n", __func__);
+			goto err_notpossible;
+		}
+
+		pll = pll_reg + index;
+
+		s3c_freq_dbg("%s: target %u => %u\n",
+			     __func__, target_freq, pll->frequency);
+
+		target_freq = pll->frequency;
+	}
+
+	return s3c_cpufreq_settarget(policy, target_freq, pll);
+
+ err_notpossible:
+	printk(KERN_ERR "no compatible settings for %d\n", target_freq);
+	return -EINVAL;
+}
+
+static unsigned int s3c_cpufreq_get(unsigned int cpu)
+{
+	return clk_get_rate(clk_arm) / 1000;
+}
+
+struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
+{
+	struct clk *clk;
+
+	clk = clk_get(dev, name);
+	if (IS_ERR(clk))
+		printk(KERN_ERR "cpufreq: failed to get clock '%s'\n", name);
+
+	return clk;
+}
+
+static int s3c_cpufreq_init(struct cpufreq_policy *policy)
+{
+	printk(KERN_INFO "%s: initialising policy %p\n", __func__, policy);
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	policy->cur = s3c_cpufreq_get(0);
+	policy->min = policy->cpuinfo.min_freq = 0;
+	policy->max = policy->cpuinfo.max_freq = cpu_cur.info->max.fclk / 1000;
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+	/* feed the latency information from the cpu driver */
+	policy->cpuinfo.transition_latency = cpu_cur.info->latency;
+
+	if (ftab)
+		cpufreq_frequency_table_cpuinfo(policy, ftab);
+
+	return 0;
+}
+
+static __init int s3c_cpufreq_initclks(void)
+{
+	_clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll");
+	_clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal");
+	clk_fclk = s3c_cpufreq_clk_get(NULL, "fclk");
+	clk_hclk = s3c_cpufreq_clk_get(NULL, "hclk");
+	clk_pclk = s3c_cpufreq_clk_get(NULL, "pclk");
+	clk_arm = s3c_cpufreq_clk_get(NULL, "armclk");
+
+	if (IS_ERR(clk_fclk) || IS_ERR(clk_hclk) || IS_ERR(clk_pclk) ||
+	    IS_ERR(_clk_mpll) || IS_ERR(clk_arm) || IS_ERR(_clk_xtal)) {
+		printk(KERN_ERR "%s: could not get clock(s)\n", __func__);
+		return -ENOENT;
+	}
+
+	printk(KERN_INFO "%s: clocks f=%lu,h=%lu,p=%lu,a=%lu\n", __func__,
+	       clk_get_rate(clk_fclk) / 1000,
+	       clk_get_rate(clk_hclk) / 1000,
+	       clk_get_rate(clk_pclk) / 1000,
+	       clk_get_rate(clk_arm) / 1000);
+
+	return 0;
+}
+
+static int s3c_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static struct cpufreq_frequency_table suspend_pll;
+static unsigned int suspend_freq;
+
+static int s3c_cpufreq_suspend(struct cpufreq_policy *policy)
+{
+	suspend_pll.frequency = clk_get_rate(_clk_mpll);
+	suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON);
+	suspend_freq = s3c_cpufreq_get(0) * 1000;
+
+	return 0;
+}
+
+static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
+{
+	int ret;
+
+	s3c_freq_dbg("%s: resuming with policy %p\n", __func__, policy);
+
+	last_target = ~0;	/* invalidate last_target setting */
+
+	/* first, find out what speed we resumed at. */
+	s3c_cpufreq_resume_clocks();
+
+	/* whilst we will be called later on, we try and re-set the
+	 * cpu frequencies as soon as possible so that we do not end
+	 * up resuming devices and then immediately having to re-set
+	 * a number of settings once these devices have restarted.
+	 *
+	 * as a note, it is expected devices are not used until they
+	 * have been un-suspended and at that time they should have
+	 * used the updated clock settings.
+	 */
+
+	ret = s3c_cpufreq_settarget(NULL, suspend_freq, &suspend_pll);
+	if (ret) {
+		printk(KERN_ERR "%s: failed to reset pll/freq\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+#else
+#define s3c_cpufreq_resume NULL
+#define s3c_cpufreq_suspend NULL
+#endif
+
+static struct cpufreq_driver s3c24xx_driver = {
+	.flags		= CPUFREQ_STICKY,
+	.verify		= s3c_cpufreq_verify,
+	.target		= s3c_cpufreq_target,
+	.get		= s3c_cpufreq_get,
+	.init		= s3c_cpufreq_init,
+	.suspend	= s3c_cpufreq_suspend,
+	.resume		= s3c_cpufreq_resume,
+	.name		= "s3c24xx",
+};
+
+
+int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info)
+{
+	if (!info || !info->name) {
+		printk(KERN_ERR "%s: failed to pass valid information\n",
+		       __func__);
+		return -EINVAL;
+	}
+
+	printk(KERN_INFO "S3C24XX CPU Frequency driver, %s cpu support\n",
+	       info->name);
+
+	/* check our driver info has valid data */
+
+	BUG_ON(info->set_refresh == NULL);
+	BUG_ON(info->set_divs == NULL);
+	BUG_ON(info->calc_divs == NULL);
+
+	/* info->set_fvco is optional, depending on whether there
+	 * is a need to set the clock code. */
+
+	cpu_cur.info = info;
+
+	/* Note, driver registering should probably update locktime */
+
+	return 0;
+}
+
+int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
+{
+	struct s3c_cpufreq_board *ours;
+
+	if (!board) {
+		printk(KERN_INFO "%s: no board data\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Copy the board information so that each board can make this
+	 * initdata. */
+
+	ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL);
+	if (ours == NULL) {
+		printk(KERN_ERR "%s: no memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	*ours = *board;
+	cpu_cur.board = ours;
+
+	return 0;
+}
+
+int __init s3c_cpufreq_auto_io(void)
+{
+	int ret;
+
+	if (!cpu_cur.info->get_iotiming) {
+		printk(KERN_ERR "%s: get_iotiming undefined\n", __func__);
+		return -ENOENT;
+	}
+
+	printk(KERN_INFO "%s: working out IO settings\n", __func__);
+
+	ret = (cpu_cur.info->get_iotiming)(&cpu_cur, &s3c24xx_iotiming);
+	if (ret)
+		printk(KERN_ERR "%s: failed to get timings\n", __func__);
+
+	return ret;
+}
+
+/* if one or is zero, then return the other, otherwise return the min */
+#define do_min(_a, _b) ((_a) == 0 ? (_b) : (_b) == 0 ? (_a) : min(_a, _b))
+
+/**
+ * s3c_cpufreq_freq_min - find the minimum settings for the given freq.
+ * @dst: The destination structure
+ * @a: One argument.
+ * @b: The other argument.
+ *
+ * Create a minimum of each frequency entry in the 'struct s3c_freq',
+ * unless the entry is zero when it is ignored and the non-zero argument
+ * used.
+ */
+static void s3c_cpufreq_freq_min(struct s3c_freq *dst,
+				 struct s3c_freq *a, struct s3c_freq *b)
+{
+	dst->fclk = do_min(a->fclk, b->fclk);
+	dst->hclk = do_min(a->hclk, b->hclk);
+	dst->pclk = do_min(a->pclk, b->pclk);
+	dst->armclk = do_min(a->armclk, b->armclk);
+}
+
+static inline u32 calc_locktime(u32 freq, u32 time_us)
+{
+	u32 result;
+
+	result = freq * time_us;
+	result = DIV_ROUND_UP(result, 1000 * 1000);
+
+	return result;
+}
+
+static void s3c_cpufreq_update_loctkime(void)
+{
+	unsigned int bits = cpu_cur.info->locktime_bits;
+	u32 rate = (u32)clk_get_rate(_clk_xtal);
+	u32 val;
+
+	if (bits == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	val = calc_locktime(rate, cpu_cur.info->locktime_u) << bits;
+	val |= calc_locktime(rate, cpu_cur.info->locktime_m);
+
+	printk(KERN_INFO "%s: new locktime is 0x%08x\n", __func__, val);
+	__raw_writel(val, S3C2410_LOCKTIME);
+}
+
+static int s3c_cpufreq_build_freq(void)
+{
+	int size, ret;
+
+	if (!cpu_cur.info->calc_freqtable)
+		return -EINVAL;
+
+	kfree(ftab);
+	ftab = NULL;
+
+	size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
+	size++;
+
+	ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL);
+	if (!ftab) {
+		printk(KERN_ERR "%s: no memory for tables\n", __func__);
+		return -ENOMEM;
+	}
+
+	ftab_size = size;
+
+	ret = cpu_cur.info->calc_freqtable(&cpu_cur, ftab, size);
+	s3c_cpufreq_addfreq(ftab, ret, size, CPUFREQ_TABLE_END);
+
+	return 0;
+}
+
+static int __init s3c_cpufreq_initcall(void)
+{
+	int ret = 0;
+
+	if (cpu_cur.info && cpu_cur.board) {
+		ret = s3c_cpufreq_initclks();
+		if (ret)
+			goto out;
+
+		/* get current settings */
+		s3c_cpufreq_getcur(&cpu_cur);
+		s3c_cpufreq_show("cur", &cpu_cur);
+
+		if (cpu_cur.board->auto_io) {
+			ret = s3c_cpufreq_auto_io();
+			if (ret) {
+				printk(KERN_ERR "%s: failed to get io timing\n",
+				       __func__);
+				goto out;
+			}
+		}
+
+		if (cpu_cur.board->need_io && !cpu_cur.info->set_iotiming) {
+			printk(KERN_ERR "%s: no IO support registered\n",
+			       __func__);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (!cpu_cur.info->need_pll)
+			cpu_cur.lock_pll = 1;
+
+		s3c_cpufreq_update_loctkime();
+
+		s3c_cpufreq_freq_min(&cpu_cur.max, &cpu_cur.board->max,
+				     &cpu_cur.info->max);
+
+		if (cpu_cur.info->calc_freqtable)
+			s3c_cpufreq_build_freq();
+
+		ret = cpufreq_register_driver(&s3c24xx_driver);
+	}
+
+ out:
+	return ret;
+}
+
+late_initcall(s3c_cpufreq_initcall);
+
+/**
+ * s3c_plltab_register - register CPU PLL table.
+ * @plls: The list of PLL entries.
+ * @plls_no: The size of the PLL entries @plls.
+ *
+ * Register the given set of PLLs with the system.
+ */
+int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
+			       unsigned int plls_no)
+{
+	struct cpufreq_frequency_table *vals;
+	unsigned int size;
+
+	size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1);
+
+	vals = kmalloc(size, GFP_KERNEL);
+	if (vals) {
+		memcpy(vals, plls, size);
+		pll_reg = vals;
+
+		/* write a terminating entry, we don't store it in the
+		 * table that is stored in the kernel */
+		vals += plls_no;
+		vals->frequency = CPUFREQ_TABLE_END;
+
+		printk(KERN_INFO "cpufreq: %d PLL entries\n", plls_no);
+	} else
+		printk(KERN_ERR "cpufreq: no memory for PLL tables\n");
+
+	return vals ? 0 : -ENOMEM;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/s3c24xx-cpufreq-debugfs.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c24xx-cpufreq-debugfs.c
--- linux-libre-3.10-gnu/drivers/cpufreq/s3c24xx-cpufreq-debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c24xx-cpufreq-debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling - debugfs status support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/err.h>
+
+#include <plat/cpu-freq-core.h>
+
+static struct dentry *dbgfs_root;
+static struct dentry *dbgfs_file_io;
+static struct dentry *dbgfs_file_info;
+static struct dentry *dbgfs_file_board;
+
+#define print_ns(x) ((x) / 10), ((x) % 10)
+
+static void show_max(struct seq_file *seq, struct s3c_freq *f)
+{
+	seq_printf(seq, "MAX: F=%lu, H=%lu, P=%lu, A=%lu\n",
+		   f->fclk, f->hclk, f->pclk, f->armclk);
+}
+
+static int board_show(struct seq_file *seq, void *p)
+{
+	struct s3c_cpufreq_config *cfg;
+	struct s3c_cpufreq_board *brd;
+
+	cfg = s3c_cpufreq_getconfig();
+	if (!cfg) {
+		seq_printf(seq, "no configuration registered\n");
+		return 0;
+	}
+
+	brd = cfg->board;
+	if (!brd) {
+		seq_printf(seq, "no board definition set?\n");
+		return 0;
+	}
+
+	seq_printf(seq, "SDRAM refresh %u ns\n", brd->refresh);
+	seq_printf(seq, "auto_io=%u\n", brd->auto_io);
+	seq_printf(seq, "need_io=%u\n", brd->need_io);
+
+	show_max(seq, &brd->max);
+
+
+	return 0;
+}
+
+static int fops_board_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, board_show, NULL);
+}
+
+static const struct file_operations fops_board = {
+	.open		= fops_board_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static int info_show(struct seq_file *seq, void *p)
+{
+	struct s3c_cpufreq_config *cfg;
+
+	cfg = s3c_cpufreq_getconfig();
+	if (!cfg) {
+		seq_printf(seq, "no configuration registered\n");
+		return 0;
+	}
+
+	seq_printf(seq, "  FCLK %ld Hz\n", cfg->freq.fclk);
+	seq_printf(seq, "  HCLK %ld Hz (%lu.%lu ns)\n",
+		   cfg->freq.hclk, print_ns(cfg->freq.hclk_tns));
+	seq_printf(seq, "  PCLK %ld Hz\n", cfg->freq.hclk);
+	seq_printf(seq, "ARMCLK %ld Hz\n", cfg->freq.armclk);
+	seq_printf(seq, "\n");
+
+	show_max(seq, &cfg->max);
+
+	seq_printf(seq, "Divisors: P=%d, H=%d, A=%d, dvs=%s\n",
+		   cfg->divs.h_divisor, cfg->divs.p_divisor,
+		   cfg->divs.arm_divisor, cfg->divs.dvs ? "on" : "off");
+	seq_printf(seq, "\n");
+
+	seq_printf(seq, "lock_pll=%u\n", cfg->lock_pll);
+
+	return 0;
+}
+
+static int fops_info_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, info_show, NULL);
+}
+
+static const struct file_operations fops_info = {
+	.open		= fops_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static int io_show(struct seq_file *seq, void *p)
+{
+	void (*show_bank)(struct seq_file *, struct s3c_cpufreq_config *, union s3c_iobank *);
+	struct s3c_cpufreq_config *cfg;
+	struct s3c_iotimings *iot;
+	union s3c_iobank *iob;
+	int bank;
+
+	cfg = s3c_cpufreq_getconfig();
+	if (!cfg) {
+		seq_printf(seq, "no configuration registered\n");
+		return 0;
+	}
+
+	show_bank = cfg->info->debug_io_show;
+	if (!show_bank) {
+		seq_printf(seq, "no code to show bank timing\n");
+		return 0;
+	}
+
+	iot = s3c_cpufreq_getiotimings();
+	if (!iot) {
+		seq_printf(seq, "no io timings registered\n");
+		return 0;
+	}
+
+	seq_printf(seq, "hclk period is %lu.%lu ns\n", print_ns(cfg->freq.hclk_tns));
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		iob = &iot->bank[bank];
+
+		seq_printf(seq, "bank %d: ", bank);
+
+		if (!iob->io_2410) {
+			seq_printf(seq, "nothing set\n");
+			continue;
+		}
+
+		show_bank(seq, cfg, iob);
+	}
+
+	return 0;
+}
+
+static int fops_io_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, io_show, NULL);
+}
+
+static const struct file_operations fops_io = {
+	.open		= fops_io_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+
+static int __init s3c_freq_debugfs_init(void)
+{
+	dbgfs_root = debugfs_create_dir("s3c-cpufreq", NULL);
+	if (IS_ERR(dbgfs_root)) {
+		printk(KERN_ERR "%s: error creating debugfs root\n", __func__);
+		return PTR_ERR(dbgfs_root);
+	}
+
+	dbgfs_file_io = debugfs_create_file("io-timing", S_IRUGO, dbgfs_root,
+					    NULL, &fops_io);
+
+	dbgfs_file_info = debugfs_create_file("info", S_IRUGO, dbgfs_root,
+					      NULL, &fops_info);
+
+	dbgfs_file_board = debugfs_create_file("board", S_IRUGO, dbgfs_root,
+					       NULL, &fops_board);
+
+	return 0;
+}
+
+late_initcall(s3c_freq_debugfs_init);
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/s3c64xx-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c64xx-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/s3c64xx-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/s3c64xx-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -87,7 +87,7 @@ static int s3c64xx_cpufreq_set_target(st
 	freqs.old = clk_get_rate(armclk) / 1000;
 	freqs.new = s3c64xx_freq_table[i].frequency;
 	freqs.flags = 0;
-	dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].index];
+	dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].driver_data];
 
 	if (freqs.old == freqs.new)
 		return 0;
@@ -104,7 +104,8 @@ static int s3c64xx_cpufreq_set_target(st
 		if (ret != 0) {
 			pr_err("Failed to set VDDARM for %dkHz: %d\n",
 			       freqs.new, ret);
-			goto err;
+			freqs.new = freqs.old;
+			goto post_notify;
 		}
 	}
 #endif
@@ -113,10 +114,13 @@ static int s3c64xx_cpufreq_set_target(st
 	if (ret < 0) {
 		pr_err("Failed to set rate %dkHz: %d\n",
 		       freqs.new, ret);
-		goto err;
+		freqs.new = freqs.old;
 	}
 
+post_notify:
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+	if (ret)
+		goto err;
 
 #ifdef CONFIG_REGULATOR
 	if (vddarm && freqs.new < freqs.old) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/sc520_freq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/sc520_freq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/sc520_freq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/sc520_freq.c	2013-08-25 20:43:22.000000000 -0400
@@ -71,7 +71,7 @@ static void sc520_freq_set_cpu_state(str
 	local_irq_disable();
 
 	clockspeed_reg = *cpuctl & ~0x03;
-	*cpuctl = clockspeed_reg | sc520_freq_table[state].index;
+	*cpuctl = clockspeed_reg | sc520_freq_table[state].driver_data;
 
 	local_irq_enable();
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/sparc-us2e-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/sparc-us2e-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/sparc-us2e-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/sparc-us2e-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -308,17 +308,17 @@ static int __init us2e_freq_cpu_init(str
 	struct cpufreq_frequency_table *table =
 		&us2e_freq_table[cpu].table[0];
 
-	table[0].index = 0;
+	table[0].driver_data = 0;
 	table[0].frequency = clock_tick / 1;
-	table[1].index = 1;
+	table[1].driver_data = 1;
 	table[1].frequency = clock_tick / 2;
-	table[2].index = 2;
+	table[2].driver_data = 2;
 	table[2].frequency = clock_tick / 4;
-	table[2].index = 3;
+	table[2].driver_data = 3;
 	table[2].frequency = clock_tick / 6;
-	table[2].index = 4;
+	table[2].driver_data = 4;
 	table[2].frequency = clock_tick / 8;
-	table[2].index = 5;
+	table[2].driver_data = 5;
 	table[3].frequency = CPUFREQ_TABLE_END;
 
 	policy->cpuinfo.transition_latency = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/sparc-us3-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/sparc-us3-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/sparc-us3-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/sparc-us3-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -169,13 +169,13 @@ static int __init us3_freq_cpu_init(stru
 	struct cpufreq_frequency_table *table =
 		&us3_freq_table[cpu].table[0];
 
-	table[0].index = 0;
+	table[0].driver_data = 0;
 	table[0].frequency = clock_tick / 1;
-	table[1].index = 1;
+	table[1].driver_data = 1;
 	table[1].frequency = clock_tick / 2;
-	table[2].index = 2;
+	table[2].driver_data = 2;
 	table[2].frequency = clock_tick / 32;
-	table[3].index = 0;
+	table[3].driver_data = 0;
 	table[3].frequency = CPUFREQ_TABLE_END;
 
 	policy->cpuinfo.transition_latency = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/spear-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/spear-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/spear-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/spear-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -250,11 +250,11 @@ static int spear_cpufreq_driver_init(voi
 	}
 
 	for (i = 0; i < cnt; i++) {
-		freq_tbl[i].index = i;
+		freq_tbl[i].driver_data = i;
 		freq_tbl[i].frequency = be32_to_cpup(val++);
 	}
 
-	freq_tbl[i].index = i;
+	freq_tbl[i].driver_data = i;
 	freq_tbl[i].frequency = CPUFREQ_TABLE_END;
 
 	spear_cpufreq.freq_tbl = freq_tbl;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/speedstep-centrino.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/speedstep-centrino.c
--- linux-libre-3.10-gnu/drivers/cpufreq/speedstep-centrino.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/speedstep-centrino.c	2013-08-25 20:43:22.000000000 -0400
@@ -79,11 +79,11 @@ static struct cpufreq_driver centrino_dr
 
 /* Computes the correct form for IA32_PERF_CTL MSR for a particular
    frequency/voltage operating point; frequency in MHz, volts in mV.
-   This is stored as "index" in the structure. */
+   This is stored as "driver_data" in the structure. */
 #define OP(mhz, mv)							\
 	{								\
 		.frequency = (mhz) * 1000,				\
-		.index = (((mhz)/100) << 8) | ((mv - 700) / 16)		\
+		.driver_data = (((mhz)/100) << 8) | ((mv - 700) / 16)		\
 	}
 
 /*
@@ -307,7 +307,7 @@ static unsigned extract_clock(unsigned m
 		per_cpu(centrino_model, cpu)->op_points[i].frequency
 							!= CPUFREQ_TABLE_END;
 	     i++) {
-		if (msr == per_cpu(centrino_model, cpu)->op_points[i].index)
+		if (msr == per_cpu(centrino_model, cpu)->op_points[i].driver_data)
 			return per_cpu(centrino_model, cpu)->
 							op_points[i].frequency;
 	}
@@ -501,7 +501,7 @@ static int centrino_target (struct cpufr
 			break;
 		}
 
-		msr = per_cpu(centrino_model, cpu)->op_points[newstate].index;
+		msr = per_cpu(centrino_model, cpu)->op_points[newstate].driver_data;
 
 		if (first_cpu) {
 			rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpufreq/tegra-cpufreq.c linux-libre-3.11-rc7-gnu/drivers/cpufreq/tegra-cpufreq.c
--- linux-libre-3.10-gnu/drivers/cpufreq/tegra-cpufreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpufreq/tegra-cpufreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,17 +28,16 @@
 #include <linux/io.h>
 #include <linux/suspend.h>
 
-/* Frequency table index must be sequential starting at 0 */
 static struct cpufreq_frequency_table freq_table[] = {
-	{ 0, 216000 },
-	{ 1, 312000 },
-	{ 2, 456000 },
-	{ 3, 608000 },
-	{ 4, 760000 },
-	{ 5, 816000 },
-	{ 6, 912000 },
-	{ 7, 1000000 },
-	{ 8, CPUFREQ_TABLE_END },
+	{ .frequency = 216000 },
+	{ .frequency = 312000 },
+	{ .frequency = 456000 },
+	{ .frequency = 608000 },
+	{ .frequency = 760000 },
+	{ .frequency = 816000 },
+	{ .frequency = 912000 },
+	{ .frequency = 1000000 },
+	{ .frequency = CPUFREQ_TABLE_END },
 };
 
 #define NUM_CPUS	2
@@ -138,12 +137,12 @@ static int tegra_update_cpu_speed(struct
 	if (ret) {
 		pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n",
 			freqs.new);
-		return ret;
+		freqs.new = freqs.old;
 	}
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 
-	return 0;
+	return ret;
 }
 
 static unsigned long tegra_cpu_highest_speed(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpuidle/cpuidle.c linux-libre-3.11-rc7-gnu/drivers/cpuidle/cpuidle.c
--- linux-libre-3.10-gnu/drivers/cpuidle/cpuidle.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpuidle/cpuidle.c	2013-08-25 20:43:22.000000000 -0400
@@ -466,7 +466,7 @@ void cpuidle_unregister(struct cpuidle_d
 	int cpu;
 	struct cpuidle_device *device;
 
-	for_each_possible_cpu(cpu) {
+	for_each_cpu(cpu, drv->cpumask) {
 		device = &per_cpu(cpuidle_dev, cpu);
 		cpuidle_unregister_device(device);
 	}
@@ -498,7 +498,7 @@ int cpuidle_register(struct cpuidle_driv
 		return ret;
 	}
 
-	for_each_possible_cpu(cpu) {
+	for_each_cpu(cpu, drv->cpumask) {
 		device = &per_cpu(cpuidle_dev, cpu);
 		device->cpu = cpu;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpuidle/cpuidle-calxeda.c linux-libre-3.11-rc7-gnu/drivers/cpuidle/cpuidle-calxeda.c
--- linux-libre-3.10-gnu/drivers/cpuidle/cpuidle-calxeda.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpuidle/cpuidle-calxeda.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,20 +37,6 @@
 extern void highbank_set_cpu_jump(int cpu, void *jump_addr);
 extern void *scu_base_addr;
 
-static inline unsigned int get_auxcr(void)
-{
-	unsigned int val;
-	asm("mrc p15, 0, %0, c1, c0, 1	@ get AUXCR" : "=r" (val) : : "cc");
-	return val;
-}
-
-static inline void set_auxcr(unsigned int val)
-{
-	asm volatile("mcr p15, 0, %0, c1, c0, 1	@ set AUXCR"
-	  : : "r" (val) : "cc");
-	isb();
-}
-
 static noinline void calxeda_idle_restore(void)
 {
 	set_cr(get_cr() | CR_C);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpuidle/cpuidle-zynq.c linux-libre-3.11-rc7-gnu/drivers/cpuidle/cpuidle-zynq.c
--- linux-libre-3.10-gnu/drivers/cpuidle/cpuidle-zynq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/cpuidle/cpuidle-zynq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2012-2013 Xilinx
+ *
+ * CPU idle support for Xilinx Zynq
+ *
+ * based on arch/arm/mach-at91/cpuidle.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The cpu idle uses wait-for-interrupt and RAM self refresh in order
+ * to implement two idle states -
+ * #1 wait-for-interrupt
+ * #2 wait-for-interrupt and RAM self refresh
+ *
+ * Maintainer: Michal Simek <michal.simek@xilinx.com>
+ */
+
+#include <linux/init.h>
+#include <linux/cpu_pm.h>
+#include <linux/cpuidle.h>
+#include <linux/of.h>
+#include <asm/proc-fns.h>
+#include <asm/cpuidle.h>
+
+#define ZYNQ_MAX_STATES		2
+
+/* Actual code that puts the SoC in different idle states */
+static int zynq_enter_idle(struct cpuidle_device *dev,
+			   struct cpuidle_driver *drv, int index)
+{
+	/* Devices must be stopped here */
+	cpu_pm_enter();
+
+	/* Add code for DDR self refresh start */
+	cpu_do_idle();
+
+	/* Add code for DDR self refresh stop */
+	cpu_pm_exit();
+
+	return index;
+}
+
+static struct cpuidle_driver zynq_idle_driver = {
+	.name = "zynq_idle",
+	.owner = THIS_MODULE,
+	.states = {
+		ARM_CPUIDLE_WFI_STATE,
+		{
+			.enter			= zynq_enter_idle,
+			.exit_latency		= 10,
+			.target_residency	= 10000,
+			.flags			= CPUIDLE_FLAG_TIME_VALID |
+						  CPUIDLE_FLAG_TIMER_STOP,
+			.name			= "RAM_SR",
+			.desc			= "WFI and RAM Self Refresh",
+		},
+	},
+	.safe_state_index = 0,
+	.state_count = ZYNQ_MAX_STATES,
+};
+
+/* Initialize CPU idle by registering the idle states */
+static int __init zynq_cpuidle_init(void)
+{
+	if (!of_machine_is_compatible("xlnx,zynq-7000"))
+		return -ENODEV;
+
+	pr_info("Xilinx Zynq CpuIdle Driver started\n");
+
+	return cpuidle_register(&zynq_idle_driver, NULL);
+}
+
+device_initcall(zynq_cpuidle_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpuidle/driver.c linux-libre-3.11-rc7-gnu/drivers/cpuidle/driver.c
--- linux-libre-3.10-gnu/drivers/cpuidle/driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpuidle/driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,182 +18,249 @@
 
 DEFINE_SPINLOCK(cpuidle_driver_lock);
 
-static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu);
-static struct cpuidle_driver * __cpuidle_get_cpu_driver(int cpu);
+#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
 
-static void cpuidle_setup_broadcast_timer(void *arg)
+static DEFINE_PER_CPU(struct cpuidle_driver *, cpuidle_drivers);
+
+/**
+ * __cpuidle_get_cpu_driver - return the cpuidle driver tied to a CPU.
+ * @cpu: the CPU handled by the driver
+ *
+ * Returns a pointer to struct cpuidle_driver or NULL if no driver has been
+ * registered for @cpu.
+ */
+static struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
 {
-	int cpu = smp_processor_id();
-	clockevents_notify((long)(arg), &cpu);
+	return per_cpu(cpuidle_drivers, cpu);
 }
 
-static void __cpuidle_driver_init(struct cpuidle_driver *drv, int cpu)
+/**
+ * __cpuidle_unset_driver - unset per CPU driver variables.
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * For each CPU in the driver's CPU mask, unset the registered driver per CPU
+ * variable. If @drv is different from the registered driver, the corresponding
+ * variable is not cleared.
+ */
+static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
 {
-	int i;
-
-	drv->refcnt = 0;
+	int cpu;
 
-	for (i = drv->state_count - 1; i >= 0 ; i--) {
+	for_each_cpu(cpu, drv->cpumask) {
 
-		if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP))
+		if (drv != __cpuidle_get_cpu_driver(cpu))
 			continue;
 
-		drv->bctimer = 1;
-		on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer,
-				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
-		break;
+		per_cpu(cpuidle_drivers, cpu) = NULL;
 	}
 }
 
-static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu)
+/**
+ * __cpuidle_set_driver - set per CPU driver variables the the given driver.
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * For each CPU in the driver's cpumask, unset the registered driver per CPU
+ * to @drv.
+ *
+ * Returns 0 on success, -EBUSY if the CPUs have driver(s) already.
+ */
+static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
 {
-	if (!drv || !drv->state_count)
-		return -EINVAL;
-
-	if (cpuidle_disabled())
-		return -ENODEV;
+	int cpu;
 
-	if (__cpuidle_get_cpu_driver(cpu))
-		return -EBUSY;
+	for_each_cpu(cpu, drv->cpumask) {
 
-	__cpuidle_driver_init(drv, cpu);
+		if (__cpuidle_get_cpu_driver(cpu)) {
+			__cpuidle_unset_driver(drv);
+			return -EBUSY;
+		}
 
-	__cpuidle_set_cpu_driver(drv, cpu);
+		per_cpu(cpuidle_drivers, cpu) = drv;
+	}
 
 	return 0;
 }
 
-static void __cpuidle_unregister_driver(struct cpuidle_driver *drv, int cpu)
-{
-	if (drv != __cpuidle_get_cpu_driver(cpu))
-		return;
+#else
 
-	if (!WARN_ON(drv->refcnt > 0))
-		__cpuidle_set_cpu_driver(NULL, cpu);
+static struct cpuidle_driver *cpuidle_curr_driver;
 
-	if (drv->bctimer) {
-		drv->bctimer = 0;
-		on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer,
-				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
-	}
+/**
+ * __cpuidle_get_cpu_driver - return the global cpuidle driver pointer.
+ * @cpu: ignored without the multiple driver support
+ *
+ * Return a pointer to a struct cpuidle_driver object or NULL if no driver was
+ * previously registered.
+ */
+static inline struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
+{
+	return cpuidle_curr_driver;
 }
 
-#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
+/**
+ * __cpuidle_set_driver - assign the global cpuidle driver variable.
+ * @drv: pointer to a struct cpuidle_driver object
+ *
+ * Returns 0 on success, -EBUSY if the driver is already registered.
+ */
+static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
+{
+	if (cpuidle_curr_driver)
+		return -EBUSY;
 
-static DEFINE_PER_CPU(struct cpuidle_driver *, cpuidle_drivers);
+	cpuidle_curr_driver = drv;
 
-static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
-	per_cpu(cpuidle_drivers, cpu) = drv;
+	return 0;
 }
 
-static struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
+/**
+ * __cpuidle_unset_driver - unset the global cpuidle driver variable.
+ * @drv: a pointer to a struct cpuidle_driver
+ *
+ * Reset the global cpuidle variable to NULL.  If @drv does not match the
+ * registered driver, do nothing.
+ */
+static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
 {
-	return per_cpu(cpuidle_drivers, cpu);
+	if (drv == cpuidle_curr_driver)
+		cpuidle_curr_driver = NULL;
 }
 
-static void __cpuidle_unregister_all_cpu_driver(struct cpuidle_driver *drv)
+#endif
+
+/**
+ * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer
+ * @arg: a void pointer used to match the SMP cross call API
+ *
+ * @arg is used as a value of type 'long' with on of the two values:
+ * - CLOCK_EVT_NOTIFY_BROADCAST_ON
+ * - CLOCK_EVT_NOTIFY_BROADCAST_OFF
+ *
+ * Set the broadcast timer notification for the current CPU.  This function
+ * is executed per CPU by an SMP cross call.  It not supposed to be called
+ * directly.
+ */
+static void cpuidle_setup_broadcast_timer(void *arg)
 {
-	int cpu;
-	for_each_present_cpu(cpu)
-		__cpuidle_unregister_driver(drv, cpu);
+	int cpu = smp_processor_id();
+	clockevents_notify((long)(arg), &cpu);
 }
 
-static int __cpuidle_register_all_cpu_driver(struct cpuidle_driver *drv)
+/**
+ * __cpuidle_driver_init - initialize the driver's internal data
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ */
+static int __cpuidle_driver_init(struct cpuidle_driver *drv)
 {
-	int ret = 0;
-	int i, cpu;
-
-	for_each_present_cpu(cpu) {
-		ret = __cpuidle_register_driver(drv, cpu);
-		if (ret)
-			break;
-	}
-
-	if (ret)
-		for_each_present_cpu(i) {
-			if (i == cpu)
-				break;
-			__cpuidle_unregister_driver(drv, i);
-		}
+	int i;
 
+	drv->refcnt = 0;
 
-	return ret;
-}
+	/*
+	 * Use all possible CPUs as the default, because if the kernel boots
+	 * with some CPUs offline and then we online one of them, the CPU
+	 * notifier has to know which driver to assign.
+	 */
+	if (!drv->cpumask)
+		drv->cpumask = (struct cpumask *)cpu_possible_mask;
 
-int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
-	int ret;
+	/*
+	 * Look for the timer stop flag in the different states, so that we know
+	 * if the broadcast timer has to be set up.  The loop is in the reverse
+	 * order, because usually on of the the deeper states has this flag set.
+	 */
+	for (i = drv->state_count - 1; i >= 0 ; i--) {
 
-	spin_lock(&cpuidle_driver_lock);
-	ret = __cpuidle_register_driver(drv, cpu);
-	spin_unlock(&cpuidle_driver_lock);
+		if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP))
+			continue;
 
-	return ret;
-}
+		drv->bctimer = 1;
+		break;
+	}
 
-void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
-	spin_lock(&cpuidle_driver_lock);
-	__cpuidle_unregister_driver(drv, cpu);
-	spin_unlock(&cpuidle_driver_lock);
+	return 0;
 }
 
 /**
- * cpuidle_register_driver - registers a driver
- * @drv: the driver
+ * __cpuidle_register_driver: register the driver
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * Do some sanity checks, initialize the driver, assign the driver to the
+ * global cpuidle driver variable(s) and set up the broadcast timer if the
+ * cpuidle driver has some states that shut down the local timer.
+ *
+ * Returns 0 on success, a negative error code otherwise:
+ *  * -EINVAL if the driver pointer is NULL or no idle states are available
+ *  * -ENODEV if the cpuidle framework is disabled
+ *  * -EBUSY if the driver is already assigned to the global variable(s)
  */
-int cpuidle_register_driver(struct cpuidle_driver *drv)
+static int __cpuidle_register_driver(struct cpuidle_driver *drv)
 {
 	int ret;
 
-	spin_lock(&cpuidle_driver_lock);
-	ret = __cpuidle_register_all_cpu_driver(drv);
-	spin_unlock(&cpuidle_driver_lock);
+	if (!drv || !drv->state_count)
+		return -EINVAL;
 
-	return ret;
-}
-EXPORT_SYMBOL_GPL(cpuidle_register_driver);
+	if (cpuidle_disabled())
+		return -ENODEV;
 
-/**
- * cpuidle_unregister_driver - unregisters a driver
- * @drv: the driver
- */
-void cpuidle_unregister_driver(struct cpuidle_driver *drv)
-{
-	spin_lock(&cpuidle_driver_lock);
-	__cpuidle_unregister_all_cpu_driver(drv);
-	spin_unlock(&cpuidle_driver_lock);
-}
-EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
+	ret = __cpuidle_driver_init(drv);
+	if (ret)
+		return ret;
 
-#else
+	ret = __cpuidle_set_driver(drv);
+	if (ret)
+		return ret;
 
-static struct cpuidle_driver *cpuidle_curr_driver;
+	if (drv->bctimer)
+		on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
+				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
 
-static inline void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
-	cpuidle_curr_driver = drv;
+	return 0;
 }
 
-static inline struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
+/**
+ * __cpuidle_unregister_driver - unregister the driver
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * Check if the driver is no longer in use, reset the global cpuidle driver
+ * variable(s) and disable the timer broadcast notification mechanism if it was
+ * in use.
+ *
+ */
+static void __cpuidle_unregister_driver(struct cpuidle_driver *drv)
 {
-	return cpuidle_curr_driver;
+	if (WARN_ON(drv->refcnt > 0))
+		return;
+
+	if (drv->bctimer) {
+		drv->bctimer = 0;
+		on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
+				 (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
+	}
+
+	__cpuidle_unset_driver(drv);
 }
 
 /**
  * cpuidle_register_driver - registers a driver
- * @drv: the driver
+ * @drv: a pointer to a valid struct cpuidle_driver
+ *
+ * Register the driver under a lock to prevent concurrent attempts to
+ * [un]register the driver from occuring at the same time.
+ *
+ * Returns 0 on success, a negative error code (returned by
+ * __cpuidle_register_driver()) otherwise.
  */
 int cpuidle_register_driver(struct cpuidle_driver *drv)
 {
-	int ret, cpu;
+	int ret;
 
-	cpu = get_cpu();
 	spin_lock(&cpuidle_driver_lock);
-	ret = __cpuidle_register_driver(drv, cpu);
+	ret = __cpuidle_register_driver(drv);
 	spin_unlock(&cpuidle_driver_lock);
-	put_cpu();
 
 	return ret;
 }
@@ -201,23 +268,24 @@ EXPORT_SYMBOL_GPL(cpuidle_register_drive
 
 /**
  * cpuidle_unregister_driver - unregisters a driver
- * @drv: the driver
+ * @drv: a pointer to a valid struct cpuidle_driver
+ *
+ * Unregisters the cpuidle driver under a lock to prevent concurrent attempts
+ * to [un]register the driver from occuring at the same time.  @drv has to
+ * match the currently registered driver.
  */
 void cpuidle_unregister_driver(struct cpuidle_driver *drv)
 {
-	int cpu;
-
-	cpu = get_cpu();
 	spin_lock(&cpuidle_driver_lock);
-	__cpuidle_unregister_driver(drv, cpu);
+	__cpuidle_unregister_driver(drv);
 	spin_unlock(&cpuidle_driver_lock);
-	put_cpu();
 }
 EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
-#endif
 
 /**
- * cpuidle_get_driver - return the current driver
+ * cpuidle_get_driver - return the driver tied to the current CPU.
+ *
+ * Returns a struct cpuidle_driver pointer, or NULL if no driver is registered.
  */
 struct cpuidle_driver *cpuidle_get_driver(void)
 {
@@ -233,7 +301,11 @@ struct cpuidle_driver *cpuidle_get_drive
 EXPORT_SYMBOL_GPL(cpuidle_get_driver);
 
 /**
- * cpuidle_get_cpu_driver - return the driver tied with a cpu
+ * cpuidle_get_cpu_driver - return the driver registered for a CPU.
+ * @dev: a valid pointer to a struct cpuidle_device
+ *
+ * Returns a struct cpuidle_driver pointer, or NULL if no driver is registered
+ * for the CPU associated with @dev.
  */
 struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev)
 {
@@ -244,6 +316,14 @@ struct cpuidle_driver *cpuidle_get_cpu_d
 }
 EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver);
 
+/**
+ * cpuidle_driver_ref - get a reference to the driver.
+ *
+ * Increment the reference counter of the cpuidle driver associated with
+ * the current CPU.
+ *
+ * Returns a pointer to the driver, or NULL if the current CPU has no driver.
+ */
 struct cpuidle_driver *cpuidle_driver_ref(void)
 {
 	struct cpuidle_driver *drv;
@@ -257,6 +337,12 @@ struct cpuidle_driver *cpuidle_driver_re
 	return drv;
 }
 
+/**
+ * cpuidle_driver_unref - puts down the refcount for the driver
+ *
+ * Decrement the reference counter of the cpuidle driver associated with
+ * the current CPU.
+ */
 void cpuidle_driver_unref(void)
 {
 	struct cpuidle_driver *drv = cpuidle_get_driver();
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpuidle/governors/menu.c linux-libre-3.11-rc7-gnu/drivers/cpuidle/governors/menu.c
--- linux-libre-3.10-gnu/drivers/cpuidle/governors/menu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpuidle/governors/menu.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,13 +28,6 @@
 #define MAX_INTERESTING 50000
 #define STDDEV_THRESH 400
 
-/* 60 * 60 > STDDEV_THRESH * INTERVALS = 400 * 8 */
-#define MAX_DEVIATION 60
-
-static DEFINE_PER_CPU(struct hrtimer, menu_hrtimer);
-static DEFINE_PER_CPU(int, hrtimer_status);
-/* menu hrtimer mode */
-enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT, MENU_HRTIMER_GENERAL};
 
 /*
  * Concepts and ideas behind the menu governor
@@ -116,13 +109,6 @@ enum {MENU_HRTIMER_STOP, MENU_HRTIMER_RE
  *
  */
 
-/*
- * The C-state residency is so long that is is worthwhile to exit
- * from the shallow C-state and re-enter into a deeper C-state.
- */
-static unsigned int perfect_cstate_ms __read_mostly = 30;
-module_param(perfect_cstate_ms, uint, 0000);
-
 struct menu_device {
 	int		last_state_idx;
 	int             needs_update;
@@ -205,52 +191,17 @@ static u64 div_round64(u64 dividend, u32
 	return div_u64(dividend + (divisor / 2), divisor);
 }
 
-/* Cancel the hrtimer if it is not triggered yet */
-void menu_hrtimer_cancel(void)
-{
-	int cpu = smp_processor_id();
-	struct hrtimer *hrtmr = &per_cpu(menu_hrtimer, cpu);
-
-	/* The timer is still not time out*/
-	if (per_cpu(hrtimer_status, cpu)) {
-		hrtimer_cancel(hrtmr);
-		per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP;
-	}
-}
-EXPORT_SYMBOL_GPL(menu_hrtimer_cancel);
-
-/* Call back for hrtimer is triggered */
-static enum hrtimer_restart menu_hrtimer_notify(struct hrtimer *hrtimer)
-{
-	int cpu = smp_processor_id();
-	struct menu_device *data = &per_cpu(menu_devices, cpu);
-
-	/* In general case, the expected residency is much larger than
-	 *  deepest C-state target residency, but prediction logic still
-	 *  predicts a small predicted residency, so the prediction
-	 *  history is totally broken if the timer is triggered.
-	 *  So reset the correction factor.
-	 */
-	if (per_cpu(hrtimer_status, cpu) == MENU_HRTIMER_GENERAL)
-		data->correction_factor[data->bucket] = RESOLUTION * DECAY;
-
-	per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP;
-
-	return HRTIMER_NORESTART;
-}
-
 /*
  * Try detecting repeating patterns by keeping track of the last 8
  * intervals, and checking if the standard deviation of that set
  * of points is below a threshold. If it is... then use the
  * average of these 8 points as the estimated value.
  */
-static u32 get_typical_interval(struct menu_device *data)
+static void get_typical_interval(struct menu_device *data)
 {
 	int i = 0, divisor = 0;
 	uint64_t max = 0, avg = 0, stddev = 0;
 	int64_t thresh = LLONG_MAX; /* Discard outliers above this value. */
-	unsigned int ret = 0;
 
 again:
 
@@ -291,16 +242,13 @@ again:
 	if (((avg > stddev * 6) && (divisor * 4 >= INTERVALS * 3))
 							|| stddev <= 20) {
 		data->predicted_us = avg;
-		ret = 1;
-		return ret;
+		return;
 
 	} else if ((divisor * 4) > INTERVALS * 3) {
 		/* Exclude the max interval */
 		thresh = max - 1;
 		goto again;
 	}
-
-	return ret;
 }
 
 /**
@@ -315,9 +263,6 @@ static int menu_select(struct cpuidle_dr
 	int i;
 	int multiplier;
 	struct timespec t;
-	int repeat = 0, low_predicted = 0;
-	int cpu = smp_processor_id();
-	struct hrtimer *hrtmr = &per_cpu(menu_hrtimer, cpu);
 
 	if (data->needs_update) {
 		menu_update(drv, dev);
@@ -352,7 +297,7 @@ static int menu_select(struct cpuidle_dr
 	data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket],
 					 RESOLUTION * DECAY);
 
-	repeat = get_typical_interval(data);
+	get_typical_interval(data);
 
 	/*
 	 * We want to default to C1 (hlt), not to busy polling
@@ -373,10 +318,8 @@ static int menu_select(struct cpuidle_dr
 
 		if (s->disabled || su->disable)
 			continue;
-		if (s->target_residency > data->predicted_us) {
-			low_predicted = 1;
+		if (s->target_residency > data->predicted_us)
 			continue;
-		}
 		if (s->exit_latency > latency_req)
 			continue;
 		if (s->exit_latency * multiplier > data->predicted_us)
@@ -386,44 +329,6 @@ static int menu_select(struct cpuidle_dr
 		data->exit_us = s->exit_latency;
 	}
 
-	/* not deepest C-state chosen for low predicted residency */
-	if (low_predicted) {
-		unsigned int timer_us = 0;
-		unsigned int perfect_us = 0;
-
-		/*
-		 * Set a timer to detect whether this sleep is much
-		 * longer than repeat mode predicted.  If the timer
-		 * triggers, the code will evaluate whether to put
-		 * the CPU into a deeper C-state.
-		 * The timer is cancelled on CPU wakeup.
-		 */
-		timer_us = 2 * (data->predicted_us + MAX_DEVIATION);
-
-		perfect_us = perfect_cstate_ms * 1000;
-
-		if (repeat && (4 * timer_us < data->expected_us)) {
-			RCU_NONIDLE(hrtimer_start(hrtmr,
-				ns_to_ktime(1000 * timer_us),
-				HRTIMER_MODE_REL_PINNED));
-			/* In repeat case, menu hrtimer is started */
-			per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_REPEAT;
-		} else if (perfect_us < data->expected_us) {
-			/*
-			 * The next timer is long. This could be because
-			 * we did not make a useful prediction.
-			 * In that case, it makes sense to re-enter
-			 * into a deeper C-state after some time.
-			 */
-			RCU_NONIDLE(hrtimer_start(hrtmr,
-				ns_to_ktime(1000 * timer_us),
-				HRTIMER_MODE_REL_PINNED));
-			/* In general case, menu hrtimer is started */
-			per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_GENERAL;
-		}
-
-	}
-
 	return data->last_state_idx;
 }
 
@@ -514,9 +419,6 @@ static int menu_enable_device(struct cpu
 				struct cpuidle_device *dev)
 {
 	struct menu_device *data = &per_cpu(menu_devices, dev->cpu);
-	struct hrtimer *t = &per_cpu(menu_hrtimer, dev->cpu);
-	hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	t->function = menu_hrtimer_notify;
 
 	memset(data, 0, sizeof(struct menu_device));
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpuidle/Kconfig linux-libre-3.11-rc7-gnu/drivers/cpuidle/Kconfig
--- linux-libre-3.10-gnu/drivers/cpuidle/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpuidle/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,9 @@
 
-config CPU_IDLE
+menuconfig CPU_IDLE
 	bool "CPU idle PM support"
 	default y if ACPI || PPC_PSERIES
+	select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE)
+	select CPU_IDLE_GOV_MENU if (NO_HZ || NO_HZ_IDLE)
 	help
 	  CPU idle is a generic framework for supporting software-controlled
 	  idle processor power management.  It includes modular cross-platform
@@ -9,9 +11,10 @@ config CPU_IDLE
 
 	  If you're using an ACPI-enabled platform, you should say Y here.
 
+if CPU_IDLE
+
 config CPU_IDLE_MULTIPLE_DRIVERS
         bool "Support multiple cpuidle drivers"
-        depends on CPU_IDLE
         default n
         help
          Allows the cpuidle framework to use different drivers for each CPU.
@@ -19,24 +22,27 @@ config CPU_IDLE_MULTIPLE_DRIVERS
          states. If unsure say N.
 
 config CPU_IDLE_GOV_LADDER
-	bool
-	depends on CPU_IDLE
+	bool "Ladder governor (for periodic timer tick)"
 	default y
 
 config CPU_IDLE_GOV_MENU
-	bool
-	depends on CPU_IDLE && NO_HZ
+	bool "Menu governor (for tickless system)"
 	default y
 
-config ARCH_NEEDS_CPU_IDLE_COUPLED
-	def_bool n
-
-if CPU_IDLE
-
 config CPU_IDLE_CALXEDA
 	bool "CPU Idle Driver for Calxeda processors"
 	depends on ARCH_HIGHBANK
+	select ARM_CPU_SUSPEND
 	help
 	  Select this to enable cpuidle on Calxeda processors.
 
+config CPU_IDLE_ZYNQ
+	bool "CPU Idle Driver for Xilinx Zynq processors"
+	depends on ARCH_ZYNQ
+	help
+	  Select this to enable cpuidle on Xilinx Zynq processors.
+
 endif
+
+config ARCH_NEEDS_CPU_IDLE_COUPLED
+	def_bool n
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/cpuidle/Makefile linux-libre-3.11-rc7-gnu/drivers/cpuidle/Makefile
--- linux-libre-3.10-gnu/drivers/cpuidle/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/cpuidle/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -7,3 +7,4 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
 
 obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
 obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
+obj-$(CONFIG_CPU_IDLE_ZYNQ) += cpuidle-zynq.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/caam/caamhash.c linux-libre-3.11-rc7-gnu/drivers/crypto/caam/caamhash.c
--- linux-libre-3.10-gnu/drivers/crypto/caam/caamhash.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/caam/caamhash.c	2013-08-25 20:43:22.000000000 -0400
@@ -429,7 +429,7 @@ static int hash_digest_key(struct caam_h
 	dma_addr_t src_dma, dst_dma;
 	int ret = 0;
 
-	desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA);
+	desc = kmalloc(CAAM_CMD_SZ * 8 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA);
 	if (!desc) {
 		dev_err(jrdev, "unable to allocate key input memory\n");
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/caam/ctrl.c linux-libre-3.11-rc7-gnu/drivers/crypto/caam/ctrl.c
--- linux-libre-3.10-gnu/drivers/crypto/caam/ctrl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/caam/ctrl.c	2013-08-25 20:43:22.000000000 -0400
@@ -202,6 +202,7 @@ static int caam_probe(struct platform_de
 #ifdef CONFIG_DEBUG_FS
 	struct caam_perfmon *perfmon;
 #endif
+	u64 cha_vid;
 
 	ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL);
 	if (!ctrlpriv)
@@ -293,11 +294,14 @@ static int caam_probe(struct platform_de
 		return -ENOMEM;
 	}
 
+	cha_vid = rd_reg64(&topregs->ctrl.perfmon.cha_id);
+
 	/*
-	 * RNG4 based SECs (v5+) need special initialization prior
-	 * to executing any descriptors
+	 * If SEC has RNG version >= 4 and RNG state handle has not been
+	 * already instantiated ,do RNG instantiation
 	 */
-	if (of_device_is_compatible(nprop, "fsl,sec-v5.0")) {
+	if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 &&
+	    !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) {
 		kick_trng(pdev);
 		ret = instantiate_rng(ctrlpriv->jrdev[0]);
 		if (ret) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/caam/desc_constr.h linux-libre-3.11-rc7-gnu/drivers/crypto/caam/desc_constr.h
--- linux-libre-3.10-gnu/drivers/crypto/caam/desc_constr.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/caam/desc_constr.h	2013-08-25 20:43:22.000000000 -0400
@@ -110,6 +110,26 @@ static inline void append_cmd(u32 *desc,
 	(*desc)++;
 }
 
+#define append_u32 append_cmd
+
+static inline void append_u64(u32 *desc, u64 data)
+{
+	u32 *offset = desc_end(desc);
+
+	*offset = upper_32_bits(data);
+	*(++offset) = lower_32_bits(data);
+
+	(*desc) += 2;
+}
+
+/* Write command without affecting header, and return pointer to next word */
+static inline u32 *write_cmd(u32 *desc, u32 command)
+{
+	*desc = command;
+
+	return desc + 1;
+}
+
 static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len,
 				  u32 command)
 {
@@ -122,7 +142,8 @@ static inline void append_cmd_ptr_extlen
 					 unsigned int len, u32 command)
 {
 	append_cmd(desc, command);
-	append_ptr(desc, ptr);
+	if (!(command & (SQIN_RTO | SQIN_PRE)))
+		append_ptr(desc, ptr);
 	append_cmd(desc, len);
 }
 
@@ -176,17 +197,36 @@ static inline void append_##cmd(u32 *des
 }
 APPEND_CMD_PTR(key, KEY)
 APPEND_CMD_PTR(load, LOAD)
-APPEND_CMD_PTR(store, STORE)
 APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
 APPEND_CMD_PTR(fifo_store, FIFO_STORE)
 
+static inline void append_store(u32 *desc, dma_addr_t ptr, unsigned int len,
+				u32 options)
+{
+	u32 cmd_src;
+
+	cmd_src = options & LDST_SRCDST_MASK;
+
+	append_cmd(desc, CMD_STORE | options | len);
+
+	/* The following options do not require pointer */
+	if (!(cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED ||
+	      cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB    ||
+	      cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB_WE ||
+	      cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED_WE))
+		append_ptr(desc, ptr);
+}
+
 #define APPEND_SEQ_PTR_INTLEN(cmd, op) \
 static inline void append_seq_##cmd##_ptr_intlen(u32 *desc, dma_addr_t ptr, \
 						 unsigned int len, \
 						 u32 options) \
 { \
 	PRINT_POS; \
-	append_cmd_ptr(desc, ptr, len, CMD_SEQ_##op##_PTR | options); \
+	if (options & (SQIN_RTO | SQIN_PRE)) \
+		append_cmd(desc, CMD_SEQ_##op##_PTR | len | options); \
+	else \
+		append_cmd_ptr(desc, ptr, len, CMD_SEQ_##op##_PTR | options); \
 }
 APPEND_SEQ_PTR_INTLEN(in, IN)
 APPEND_SEQ_PTR_INTLEN(out, OUT)
@@ -259,7 +299,7 @@ APPEND_CMD_RAW_IMM(load, LOAD, u32);
  */
 #define APPEND_MATH(op, desc, dest, src_0, src_1, len) \
 append_cmd(desc, CMD_MATH | MATH_FUN_##op | MATH_DEST_##dest | \
-	   MATH_SRC0_##src_0 | MATH_SRC1_##src_1 | (u32) (len & MATH_LEN_MASK));
+	MATH_SRC0_##src_0 | MATH_SRC1_##src_1 | (u32)len);
 
 #define append_math_add(desc, dest, src0, src1, len) \
 	APPEND_MATH(ADD, desc, dest, src0, src1, len)
@@ -279,6 +319,8 @@ append_cmd(desc, CMD_MATH | MATH_FUN_##o
 	APPEND_MATH(LSHIFT, desc, dest, src0, src1, len)
 #define append_math_rshift(desc, dest, src0, src1, len) \
 	APPEND_MATH(RSHIFT, desc, dest, src0, src1, len)
+#define append_math_ldshift(desc, dest, src0, src1, len) \
+	APPEND_MATH(SHLD, desc, dest, src0, src1, len)
 
 /* Exactly one source is IMM. Data is passed in as u32 value */
 #define APPEND_MATH_IMM_u32(op, desc, dest, src_0, src_1, data) \
@@ -305,3 +347,34 @@ do { \
 	APPEND_MATH_IMM_u32(LSHIFT, desc, dest, src0, src1, data)
 #define append_math_rshift_imm_u32(desc, dest, src0, src1, data) \
 	APPEND_MATH_IMM_u32(RSHIFT, desc, dest, src0, src1, data)
+
+/* Exactly one source is IMM. Data is passed in as u64 value */
+#define APPEND_MATH_IMM_u64(op, desc, dest, src_0, src_1, data) \
+do { \
+	u32 upper = (data >> 16) >> 16; \
+	APPEND_MATH(op, desc, dest, src_0, src_1, CAAM_CMD_SZ * 2 | \
+		    (upper ? 0 : MATH_IFB)); \
+	if (upper) \
+		append_u64(desc, data); \
+	else \
+		append_u32(desc, data); \
+} while (0)
+
+#define append_math_add_imm_u64(desc, dest, src0, src1, data) \
+	APPEND_MATH_IMM_u64(ADD, desc, dest, src0, src1, data)
+#define append_math_sub_imm_u64(desc, dest, src0, src1, data) \
+	APPEND_MATH_IMM_u64(SUB, desc, dest, src0, src1, data)
+#define append_math_add_c_imm_u64(desc, dest, src0, src1, data) \
+	APPEND_MATH_IMM_u64(ADDC, desc, dest, src0, src1, data)
+#define append_math_sub_b_imm_u64(desc, dest, src0, src1, data) \
+	APPEND_MATH_IMM_u64(SUBB, desc, dest, src0, src1, data)
+#define append_math_and_imm_u64(desc, dest, src0, src1, data) \
+	APPEND_MATH_IMM_u64(AND, desc, dest, src0, src1, data)
+#define append_math_or_imm_u64(desc, dest, src0, src1, data) \
+	APPEND_MATH_IMM_u64(OR, desc, dest, src0, src1, data)
+#define append_math_xor_imm_u64(desc, dest, src0, src1, data) \
+	APPEND_MATH_IMM_u64(XOR, desc, dest, src0, src1, data)
+#define append_math_lshift_imm_u64(desc, dest, src0, src1, data) \
+	APPEND_MATH_IMM_u64(LSHIFT, desc, dest, src0, src1, data)
+#define append_math_rshift_imm_u64(desc, dest, src0, src1, data) \
+	APPEND_MATH_IMM_u64(RSHIFT, desc, dest, src0, src1, data)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/caam/desc.h linux-libre-3.11-rc7-gnu/drivers/crypto/caam/desc.h
--- linux-libre-3.10-gnu/drivers/crypto/caam/desc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/caam/desc.h	2013-08-25 20:43:22.000000000 -0400
@@ -231,7 +231,12 @@ struct sec4_sg_entry {
 #define LDST_SRCDST_WORD_PKHA_B_SZ	(0x11 << LDST_SRCDST_SHIFT)
 #define LDST_SRCDST_WORD_PKHA_N_SZ	(0x12 << LDST_SRCDST_SHIFT)
 #define LDST_SRCDST_WORD_PKHA_E_SZ	(0x13 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLASS_CTX	(0x20 << LDST_SRCDST_SHIFT)
 #define LDST_SRCDST_WORD_DESCBUF	(0x40 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_JOB	(0x41 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_SHARED	(0x42 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_JOB_WE	(0x45 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_SHARED_WE (0x46 << LDST_SRCDST_SHIFT)
 #define LDST_SRCDST_WORD_INFO_FIFO	(0x7a << LDST_SRCDST_SHIFT)
 
 /* Offset in source/destination */
@@ -366,6 +371,7 @@ struct sec4_sg_entry {
 #define FIFOLD_TYPE_LAST2FLUSH1 (0x05 << FIFOLD_TYPE_SHIFT)
 #define FIFOLD_TYPE_LASTBOTH	(0x06 << FIFOLD_TYPE_SHIFT)
 #define FIFOLD_TYPE_LASTBOTHFL	(0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_NOINFOFIFO	(0x0F << FIFOLD_TYPE_SHIFT)
 
 #define FIFOLDST_LEN_MASK	0xffff
 #define FIFOLDST_EXT_LEN_MASK	0xffffffff
@@ -1294,10 +1300,10 @@ struct sec4_sg_entry {
 #define SQOUT_SGF	0x01000000
 
 /* Appends to a previous pointer */
-#define SQOUT_PRE	0x00800000
+#define SQOUT_PRE	SQIN_PRE
 
 /* Restore sequence with pointer/length */
-#define SQOUT_RTO	0x00200000
+#define SQOUT_RTO	 SQIN_RTO
 
 /* Use extended length following pointer */
 #define SQOUT_EXT	0x00400000
@@ -1359,6 +1365,7 @@ struct sec4_sg_entry {
 #define MOVE_DEST_MATH3		(0x07 << MOVE_DEST_SHIFT)
 #define MOVE_DEST_CLASS1INFIFO	(0x08 << MOVE_DEST_SHIFT)
 #define MOVE_DEST_CLASS2INFIFO	(0x09 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_INFIFO_NOINFO (0x0a << MOVE_DEST_SHIFT)
 #define MOVE_DEST_PK_A		(0x0c << MOVE_DEST_SHIFT)
 #define MOVE_DEST_CLASS1KEY	(0x0d << MOVE_DEST_SHIFT)
 #define MOVE_DEST_CLASS2KEY	(0x0e << MOVE_DEST_SHIFT)
@@ -1411,6 +1418,7 @@ struct sec4_sg_entry {
 #define MATH_SRC0_REG2		(0x02 << MATH_SRC0_SHIFT)
 #define MATH_SRC0_REG3		(0x03 << MATH_SRC0_SHIFT)
 #define MATH_SRC0_IMM		(0x04 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_DPOVRD	(0x07 << MATH_SRC0_SHIFT)
 #define MATH_SRC0_SEQINLEN	(0x08 << MATH_SRC0_SHIFT)
 #define MATH_SRC0_SEQOUTLEN	(0x09 << MATH_SRC0_SHIFT)
 #define MATH_SRC0_VARSEQINLEN	(0x0a << MATH_SRC0_SHIFT)
@@ -1425,6 +1433,7 @@ struct sec4_sg_entry {
 #define MATH_SRC1_REG2		(0x02 << MATH_SRC1_SHIFT)
 #define MATH_SRC1_REG3		(0x03 << MATH_SRC1_SHIFT)
 #define MATH_SRC1_IMM		(0x04 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_DPOVRD	(0x07 << MATH_SRC0_SHIFT)
 #define MATH_SRC1_INFIFO	(0x0a << MATH_SRC1_SHIFT)
 #define MATH_SRC1_OUTFIFO	(0x0b << MATH_SRC1_SHIFT)
 #define MATH_SRC1_ONE		(0x0c << MATH_SRC1_SHIFT)
@@ -1600,4 +1609,13 @@ struct sec4_sg_entry {
 #define NFIFOENTRY_PLEN_SHIFT	0
 #define NFIFOENTRY_PLEN_MASK	(0xFF << NFIFOENTRY_PLEN_SHIFT)
 
+/* Append Load Immediate Command */
+#define FD_CMD_APPEND_LOAD_IMMEDIATE			0x80000000
+
+/* Set SEQ LIODN equal to the Non-SEQ LIODN for the job */
+#define FD_CMD_SET_SEQ_LIODN_EQUAL_NONSEQ_LIODN		0x40000000
+
+/* Frame Descriptor Command for Replacement Job Descriptor */
+#define FD_CMD_REPLACE_JOB_DESC				0x20000000
+
 #endif /* DESC_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/caam/pdb.h linux-libre-3.11-rc7-gnu/drivers/crypto/caam/pdb.h
--- linux-libre-3.10-gnu/drivers/crypto/caam/pdb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/caam/pdb.h	2013-08-25 20:43:22.000000000 -0400
@@ -44,6 +44,7 @@
 #define PDBOPTS_ESP_IPHDRSRC	0x08 /* IP header comes from PDB (encap) */
 #define PDBOPTS_ESP_INCIPHDR	0x04 /* Prepend IP header to output frame */
 #define PDBOPTS_ESP_IPVSN	0x02 /* process IPv6 header */
+#define PDBOPTS_ESP_AOFL	0x04 /* adjust out frame len (decap, SEC>=5.3)*/
 #define PDBOPTS_ESP_TUNNEL	0x01 /* tunnel mode next-header byte */
 #define PDBOPTS_ESP_IPV6	0x02 /* ip header version is V6 */
 #define PDBOPTS_ESP_DIFFSERV	0x40 /* copy TOS/TC from inner iphdr */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/caam/regs.h linux-libre-3.11-rc7-gnu/drivers/crypto/caam/regs.h
--- linux-libre-3.10-gnu/drivers/crypto/caam/regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/caam/regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -117,6 +117,43 @@ struct jr_outentry {
 #define CHA_NUM_DECONUM_SHIFT	56
 #define CHA_NUM_DECONUM_MASK	(0xfull << CHA_NUM_DECONUM_SHIFT)
 
+/* CHA Version IDs */
+#define CHA_ID_AES_SHIFT	0
+#define CHA_ID_AES_MASK		(0xfull << CHA_ID_AES_SHIFT)
+
+#define CHA_ID_DES_SHIFT	4
+#define CHA_ID_DES_MASK		(0xfull << CHA_ID_DES_SHIFT)
+
+#define CHA_ID_ARC4_SHIFT	8
+#define CHA_ID_ARC4_MASK	(0xfull << CHA_ID_ARC4_SHIFT)
+
+#define CHA_ID_MD_SHIFT		12
+#define CHA_ID_MD_MASK		(0xfull << CHA_ID_MD_SHIFT)
+
+#define CHA_ID_RNG_SHIFT	16
+#define CHA_ID_RNG_MASK		(0xfull << CHA_ID_RNG_SHIFT)
+
+#define CHA_ID_SNW8_SHIFT	20
+#define CHA_ID_SNW8_MASK	(0xfull << CHA_ID_SNW8_SHIFT)
+
+#define CHA_ID_KAS_SHIFT	24
+#define CHA_ID_KAS_MASK		(0xfull << CHA_ID_KAS_SHIFT)
+
+#define CHA_ID_PK_SHIFT		28
+#define CHA_ID_PK_MASK		(0xfull << CHA_ID_PK_SHIFT)
+
+#define CHA_ID_CRC_SHIFT	32
+#define CHA_ID_CRC_MASK		(0xfull << CHA_ID_CRC_SHIFT)
+
+#define CHA_ID_SNW9_SHIFT	36
+#define CHA_ID_SNW9_MASK	(0xfull << CHA_ID_SNW9_SHIFT)
+
+#define CHA_ID_DECO_SHIFT	56
+#define CHA_ID_DECO_MASK	(0xfull << CHA_ID_DECO_SHIFT)
+
+#define CHA_ID_JR_SHIFT		60
+#define CHA_ID_JR_MASK		(0xfull << CHA_ID_JR_SHIFT)
+
 struct sec_vid {
 	u16 ip_id;
 	u8 maj_rev;
@@ -228,7 +265,10 @@ struct rng4tst {
 		u32 rtfrqmax;	/* PRGM=1: freq. count max. limit register */
 		u32 rtfrqcnt;	/* PRGM=0: freq. count register */
 	};
-	u32 rsvd1[56];
+	u32 rsvd1[40];
+#define RDSTA_IF0 0x00000001
+	u32 rdsta;
+	u32 rsvd2[15];
 };
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/dcp.c linux-libre-3.11-rc7-gnu/drivers/crypto/dcp.c
--- linux-libre-3.10-gnu/drivers/crypto/dcp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/dcp.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,912 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for DCP cryptographic accelerator.
+ *
+ * Copyright (c) 2013
+ * Author: Tobias Rauter <tobias.rauter@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Based on tegra-aes.c, dcp.c (from freescale SDK) and sahara.c
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/crypto.h>
+#include <linux/miscdevice.h>
+
+#include <crypto/scatterwalk.h>
+#include <crypto/aes.h>
+
+
+/* IOCTL for DCP OTP Key AES - taken from Freescale's SDK*/
+#define DBS_IOCTL_BASE   'd'
+#define DBS_ENC	_IOW(DBS_IOCTL_BASE, 0x00, uint8_t[16])
+#define DBS_DEC _IOW(DBS_IOCTL_BASE, 0x01, uint8_t[16])
+
+/* DCP channel used for AES */
+#define USED_CHANNEL 1
+/* Ring Buffers' maximum size */
+#define DCP_MAX_PKG 20
+
+/* Control Register */
+#define DCP_REG_CTRL 0x000
+#define DCP_CTRL_SFRST (1<<31)
+#define DCP_CTRL_CLKGATE (1<<30)
+#define DCP_CTRL_CRYPTO_PRESENT (1<<29)
+#define DCP_CTRL_SHA_PRESENT (1<<28)
+#define DCP_CTRL_GATHER_RES_WRITE (1<<23)
+#define DCP_CTRL_ENABLE_CONTEXT_CACHE (1<<22)
+#define DCP_CTRL_ENABLE_CONTEXT_SWITCH (1<<21)
+#define DCP_CTRL_CH_IRQ_E_0 0x01
+#define DCP_CTRL_CH_IRQ_E_1 0x02
+#define DCP_CTRL_CH_IRQ_E_2 0x04
+#define DCP_CTRL_CH_IRQ_E_3 0x08
+
+/* Status register */
+#define DCP_REG_STAT 0x010
+#define DCP_STAT_OTP_KEY_READY (1<<28)
+#define DCP_STAT_CUR_CHANNEL(stat) ((stat>>24)&0x0F)
+#define DCP_STAT_READY_CHANNEL(stat) ((stat>>16)&0x0F)
+#define DCP_STAT_IRQ(stat) (stat&0x0F)
+#define DCP_STAT_CHAN_0 (0x01)
+#define DCP_STAT_CHAN_1 (0x02)
+#define DCP_STAT_CHAN_2 (0x04)
+#define DCP_STAT_CHAN_3 (0x08)
+
+/* Channel Control Register */
+#define DCP_REG_CHAN_CTRL 0x020
+#define DCP_CHAN_CTRL_CH0_IRQ_MERGED (1<<16)
+#define DCP_CHAN_CTRL_HIGH_PRIO_0 (0x0100)
+#define DCP_CHAN_CTRL_HIGH_PRIO_1 (0x0200)
+#define DCP_CHAN_CTRL_HIGH_PRIO_2 (0x0400)
+#define DCP_CHAN_CTRL_HIGH_PRIO_3 (0x0800)
+#define DCP_CHAN_CTRL_ENABLE_0 (0x01)
+#define DCP_CHAN_CTRL_ENABLE_1 (0x02)
+#define DCP_CHAN_CTRL_ENABLE_2 (0x04)
+#define DCP_CHAN_CTRL_ENABLE_3 (0x08)
+
+/*
+ * Channel Registers:
+ * The DCP has 4 channels. Each of this channels
+ * has 4 registers (command pointer, semaphore, status and options).
+ * The address of register REG of channel CHAN is obtained by
+ * dcp_chan_reg(REG, CHAN)
+ */
+#define DCP_REG_CHAN_PTR	0x00000100
+#define DCP_REG_CHAN_SEMA	0x00000110
+#define DCP_REG_CHAN_STAT	0x00000120
+#define DCP_REG_CHAN_OPT	0x00000130
+
+#define DCP_CHAN_STAT_NEXT_CHAIN_IS_0	0x010000
+#define DCP_CHAN_STAT_NO_CHAIN		0x020000
+#define DCP_CHAN_STAT_CONTEXT_ERROR	0x030000
+#define DCP_CHAN_STAT_PAYLOAD_ERROR	0x040000
+#define DCP_CHAN_STAT_INVALID_MODE	0x050000
+#define DCP_CHAN_STAT_PAGEFAULT		0x40
+#define DCP_CHAN_STAT_DST		0x20
+#define DCP_CHAN_STAT_SRC		0x10
+#define DCP_CHAN_STAT_PACKET		0x08
+#define DCP_CHAN_STAT_SETUP		0x04
+#define DCP_CHAN_STAT_MISMATCH		0x02
+
+/* hw packet control*/
+
+#define DCP_PKT_PAYLOAD_KEY	(1<<11)
+#define DCP_PKT_OTP_KEY		(1<<10)
+#define DCP_PKT_CIPHER_INIT	(1<<9)
+#define DCP_PKG_CIPHER_ENCRYPT	(1<<8)
+#define DCP_PKT_CIPHER_ENABLE	(1<<5)
+#define DCP_PKT_DECR_SEM	(1<<1)
+#define DCP_PKT_CHAIN		(1<<2)
+#define DCP_PKT_IRQ		1
+
+#define DCP_PKT_MODE_CBC	(1<<4)
+#define DCP_PKT_KEYSELECT_OTP	(0xFF<<8)
+
+/* cipher flags */
+#define DCP_ENC		0x0001
+#define DCP_DEC		0x0002
+#define DCP_ECB		0x0004
+#define DCP_CBC		0x0008
+#define DCP_CBC_INIT	0x0010
+#define DCP_NEW_KEY	0x0040
+#define DCP_OTP_KEY	0x0080
+#define DCP_AES		0x1000
+
+/* DCP Flags */
+#define DCP_FLAG_BUSY	0x01
+#define DCP_FLAG_PRODUCING	0x02
+
+/* clock defines */
+#define CLOCK_ON	1
+#define CLOCK_OFF	0
+
+struct dcp_dev_req_ctx {
+	int mode;
+};
+
+struct dcp_op {
+	unsigned int		flags;
+	u8			key[AES_KEYSIZE_128];
+	int			keylen;
+
+	struct ablkcipher_request	*req;
+	struct crypto_ablkcipher	*fallback;
+
+	uint32_t stat;
+	uint32_t pkt1;
+	uint32_t pkt2;
+	struct ablkcipher_walk walk;
+};
+
+struct dcp_dev {
+	struct device *dev;
+	void __iomem *dcp_regs_base;
+
+	int dcp_vmi_irq;
+	int dcp_irq;
+
+	spinlock_t queue_lock;
+	struct crypto_queue queue;
+
+	uint32_t pkt_produced;
+	uint32_t pkt_consumed;
+
+	struct dcp_hw_packet *hw_pkg[DCP_MAX_PKG];
+	dma_addr_t hw_phys_pkg;
+
+	/* [KEY][IV] Both with 16 Bytes */
+	u8 *payload_base;
+	dma_addr_t payload_base_dma;
+
+
+	struct tasklet_struct	done_task;
+	struct tasklet_struct	queue_task;
+	struct timer_list	watchdog;
+
+	unsigned long		flags;
+
+	struct dcp_op *ctx;
+
+	struct miscdevice dcp_bootstream_misc;
+};
+
+struct dcp_hw_packet {
+	uint32_t next;
+	uint32_t pkt1;
+	uint32_t pkt2;
+	uint32_t src;
+	uint32_t dst;
+	uint32_t size;
+	uint32_t payload;
+	uint32_t stat;
+};
+
+static struct dcp_dev *global_dev;
+
+static inline u32 dcp_chan_reg(u32 reg, int chan)
+{
+	return reg + (chan) * 0x40;
+}
+
+static inline void dcp_write(struct dcp_dev *dev, u32 data, u32 reg)
+{
+	writel(data, dev->dcp_regs_base + reg);
+}
+
+static inline void dcp_set(struct dcp_dev *dev, u32 data, u32 reg)
+{
+	writel(data, dev->dcp_regs_base + (reg | 0x04));
+}
+
+static inline void dcp_clear(struct dcp_dev *dev, u32 data, u32 reg)
+{
+	writel(data, dev->dcp_regs_base + (reg | 0x08));
+}
+
+static inline void dcp_toggle(struct dcp_dev *dev, u32 data, u32 reg)
+{
+	writel(data, dev->dcp_regs_base + (reg | 0x0C));
+}
+
+static inline unsigned int dcp_read(struct dcp_dev *dev, u32 reg)
+{
+	return readl(dev->dcp_regs_base + reg);
+}
+
+static void dcp_dma_unmap(struct dcp_dev *dev, struct dcp_hw_packet *pkt)
+{
+	dma_unmap_page(dev->dev, pkt->src, pkt->size, DMA_TO_DEVICE);
+	dma_unmap_page(dev->dev, pkt->dst, pkt->size, DMA_FROM_DEVICE);
+	dev_dbg(dev->dev, "unmap packet %x", (unsigned int) pkt);
+}
+
+static int dcp_dma_map(struct dcp_dev *dev,
+	struct ablkcipher_walk *walk, struct dcp_hw_packet *pkt)
+{
+	dev_dbg(dev->dev, "map packet %x", (unsigned int) pkt);
+	/* align to length = 16 */
+	pkt->size = walk->nbytes - (walk->nbytes % 16);
+
+	pkt->src = dma_map_page(dev->dev, walk->src.page, walk->src.offset,
+		pkt->size, DMA_TO_DEVICE);
+
+	if (pkt->src == 0) {
+		dev_err(dev->dev, "Unable to map src");
+		return -ENOMEM;
+	}
+
+	pkt->dst = dma_map_page(dev->dev, walk->dst.page, walk->dst.offset,
+		pkt->size, DMA_FROM_DEVICE);
+
+	if (pkt->dst == 0) {
+		dev_err(dev->dev, "Unable to map dst");
+		dma_unmap_page(dev->dev, pkt->src, pkt->size, DMA_TO_DEVICE);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void dcp_op_one(struct dcp_dev *dev, struct dcp_hw_packet *pkt,
+			uint8_t last)
+{
+	struct dcp_op *ctx = dev->ctx;
+	pkt->pkt1 = ctx->pkt1;
+	pkt->pkt2 = ctx->pkt2;
+
+	pkt->payload = (u32) dev->payload_base_dma;
+	pkt->stat = 0;
+
+	if (ctx->flags & DCP_CBC_INIT) {
+		pkt->pkt1 |= DCP_PKT_CIPHER_INIT;
+		ctx->flags &= ~DCP_CBC_INIT;
+	}
+
+	mod_timer(&dev->watchdog, jiffies + msecs_to_jiffies(500));
+	pkt->pkt1 |= DCP_PKT_IRQ;
+	if (!last)
+		pkt->pkt1 |= DCP_PKT_CHAIN;
+
+	dev->pkt_produced++;
+
+	dcp_write(dev, 1,
+		dcp_chan_reg(DCP_REG_CHAN_SEMA, USED_CHANNEL));
+}
+
+static void dcp_op_proceed(struct dcp_dev *dev)
+{
+	struct dcp_op *ctx = dev->ctx;
+	struct dcp_hw_packet *pkt;
+
+	while (ctx->walk.nbytes) {
+		int err = 0;
+
+		pkt = dev->hw_pkg[dev->pkt_produced % DCP_MAX_PKG];
+		err = dcp_dma_map(dev, &ctx->walk, pkt);
+		if (err) {
+			dev->ctx->stat |= err;
+			/* start timer to wait for already set up calls */
+			mod_timer(&dev->watchdog,
+				jiffies + msecs_to_jiffies(500));
+			break;
+		}
+
+
+		err = ctx->walk.nbytes - pkt->size;
+		ablkcipher_walk_done(dev->ctx->req, &dev->ctx->walk, err);
+
+		dcp_op_one(dev, pkt, ctx->walk.nbytes == 0);
+		/* we have to wait if no space is left in buffer */
+		if (dev->pkt_produced - dev->pkt_consumed == DCP_MAX_PKG)
+			break;
+	}
+	clear_bit(DCP_FLAG_PRODUCING, &dev->flags);
+}
+
+static void dcp_op_start(struct dcp_dev *dev, uint8_t use_walk)
+{
+	struct dcp_op *ctx = dev->ctx;
+
+	if (ctx->flags & DCP_NEW_KEY) {
+		memcpy(dev->payload_base, ctx->key, ctx->keylen);
+		ctx->flags &= ~DCP_NEW_KEY;
+	}
+
+	ctx->pkt1 = 0;
+	ctx->pkt1 |= DCP_PKT_CIPHER_ENABLE;
+	ctx->pkt1 |= DCP_PKT_DECR_SEM;
+
+	if (ctx->flags & DCP_OTP_KEY)
+		ctx->pkt1 |= DCP_PKT_OTP_KEY;
+	else
+		ctx->pkt1 |= DCP_PKT_PAYLOAD_KEY;
+
+	if (ctx->flags & DCP_ENC)
+		ctx->pkt1 |= DCP_PKG_CIPHER_ENCRYPT;
+
+	ctx->pkt2 = 0;
+	if (ctx->flags & DCP_CBC)
+		ctx->pkt2 |= DCP_PKT_MODE_CBC;
+
+	dev->pkt_produced = 0;
+	dev->pkt_consumed = 0;
+
+	ctx->stat = 0;
+	dcp_clear(dev, -1, dcp_chan_reg(DCP_REG_CHAN_STAT, USED_CHANNEL));
+	dcp_write(dev, (u32) dev->hw_phys_pkg,
+		dcp_chan_reg(DCP_REG_CHAN_PTR, USED_CHANNEL));
+
+	set_bit(DCP_FLAG_PRODUCING, &dev->flags);
+
+	if (use_walk) {
+		ablkcipher_walk_init(&ctx->walk, ctx->req->dst,
+				ctx->req->src, ctx->req->nbytes);
+		ablkcipher_walk_phys(ctx->req, &ctx->walk);
+		dcp_op_proceed(dev);
+	} else {
+		dcp_op_one(dev, dev->hw_pkg[0], 1);
+		clear_bit(DCP_FLAG_PRODUCING, &dev->flags);
+	}
+}
+
+static void dcp_done_task(unsigned long data)
+{
+	struct dcp_dev *dev = (struct dcp_dev *)data;
+	struct dcp_hw_packet *last_packet;
+	int fin;
+	fin = 0;
+
+	for (last_packet = dev->hw_pkg[(dev->pkt_consumed) % DCP_MAX_PKG];
+		last_packet->stat == 1;
+		last_packet =
+			dev->hw_pkg[++(dev->pkt_consumed) % DCP_MAX_PKG]) {
+
+		dcp_dma_unmap(dev, last_packet);
+		last_packet->stat = 0;
+		fin++;
+	}
+	/* the last call of this function already consumed this IRQ's packet */
+	if (fin == 0)
+		return;
+
+	dev_dbg(dev->dev,
+		"Packet(s) done with status %x; finished: %d, produced:%d, complete consumed: %d",
+		dev->ctx->stat, fin, dev->pkt_produced, dev->pkt_consumed);
+
+	last_packet = dev->hw_pkg[(dev->pkt_consumed - 1) % DCP_MAX_PKG];
+	if (!dev->ctx->stat && last_packet->pkt1 & DCP_PKT_CHAIN) {
+		if (!test_and_set_bit(DCP_FLAG_PRODUCING, &dev->flags))
+			dcp_op_proceed(dev);
+		return;
+	}
+
+	while (unlikely(dev->pkt_consumed < dev->pkt_produced)) {
+		dcp_dma_unmap(dev,
+			dev->hw_pkg[dev->pkt_consumed++ % DCP_MAX_PKG]);
+	}
+
+	if (dev->ctx->flags & DCP_OTP_KEY) {
+		/* we used the miscdevice, no walk to finish */
+		clear_bit(DCP_FLAG_BUSY, &dev->flags);
+		return;
+	}
+
+	ablkcipher_walk_complete(&dev->ctx->walk);
+	dev->ctx->req->base.complete(&dev->ctx->req->base,
+			dev->ctx->stat);
+	dev->ctx->req = NULL;
+	/* in case there are other requests in the queue */
+	tasklet_schedule(&dev->queue_task);
+}
+
+static void dcp_watchdog(unsigned long data)
+{
+	struct dcp_dev *dev = (struct dcp_dev *)data;
+	dev->ctx->stat |= dcp_read(dev,
+			dcp_chan_reg(DCP_REG_CHAN_STAT, USED_CHANNEL));
+
+	dev_err(dev->dev, "Timeout, Channel status: %x", dev->ctx->stat);
+
+	if (!dev->ctx->stat)
+		dev->ctx->stat = -ETIMEDOUT;
+
+	dcp_done_task(data);
+}
+
+
+static irqreturn_t dcp_common_irq(int irq, void *context)
+{
+	u32 msk;
+	struct dcp_dev *dev = (struct dcp_dev *) context;
+
+	del_timer(&dev->watchdog);
+
+	msk = DCP_STAT_IRQ(dcp_read(dev, DCP_REG_STAT));
+	dcp_clear(dev, msk, DCP_REG_STAT);
+	if (msk == 0)
+		return IRQ_NONE;
+
+	dev->ctx->stat |= dcp_read(dev,
+			dcp_chan_reg(DCP_REG_CHAN_STAT, USED_CHANNEL));
+
+	if (msk & DCP_STAT_CHAN_1)
+		tasklet_schedule(&dev->done_task);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t dcp_vmi_irq(int irq, void *context)
+{
+	return dcp_common_irq(irq, context);
+}
+
+static irqreturn_t dcp_irq(int irq, void *context)
+{
+	return dcp_common_irq(irq, context);
+}
+
+static void dcp_crypt(struct dcp_dev *dev, struct dcp_op *ctx)
+{
+	dev->ctx = ctx;
+
+	if ((ctx->flags & DCP_CBC) && ctx->req->info) {
+		ctx->flags |= DCP_CBC_INIT;
+		memcpy(dev->payload_base + AES_KEYSIZE_128,
+			ctx->req->info, AES_KEYSIZE_128);
+	}
+
+	dcp_op_start(dev, 1);
+}
+
+static void dcp_queue_task(unsigned long data)
+{
+	struct dcp_dev *dev = (struct dcp_dev *) data;
+	struct crypto_async_request *async_req, *backlog;
+	struct crypto_ablkcipher *tfm;
+	struct dcp_op *ctx;
+	struct dcp_dev_req_ctx *rctx;
+	struct ablkcipher_request *req;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->queue_lock, flags);
+
+	backlog = crypto_get_backlog(&dev->queue);
+	async_req = crypto_dequeue_request(&dev->queue);
+
+	spin_unlock_irqrestore(&dev->queue_lock, flags);
+
+	if (!async_req)
+		goto ret_nothing_done;
+
+	if (backlog)
+		backlog->complete(backlog, -EINPROGRESS);
+
+	req = ablkcipher_request_cast(async_req);
+	tfm = crypto_ablkcipher_reqtfm(req);
+	rctx = ablkcipher_request_ctx(req);
+	ctx = crypto_ablkcipher_ctx(tfm);
+
+	if (!req->src || !req->dst)
+		goto ret_nothing_done;
+
+	ctx->flags |= rctx->mode;
+	ctx->req = req;
+
+	dcp_crypt(dev, ctx);
+
+	return;
+
+ret_nothing_done:
+	clear_bit(DCP_FLAG_BUSY, &dev->flags);
+}
+
+
+static int dcp_cra_init(struct crypto_tfm *tfm)
+{
+	const char *name = tfm->__crt_alg->cra_name;
+	struct dcp_op *ctx = crypto_tfm_ctx(tfm);
+
+	tfm->crt_ablkcipher.reqsize = sizeof(struct dcp_dev_req_ctx);
+
+	ctx->fallback = crypto_alloc_ablkcipher(name, 0,
+				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
+
+	if (IS_ERR(ctx->fallback)) {
+		dev_err(global_dev->dev, "Error allocating fallback algo %s\n",
+			name);
+		return PTR_ERR(ctx->fallback);
+	}
+
+	return 0;
+}
+
+static void dcp_cra_exit(struct crypto_tfm *tfm)
+{
+	struct dcp_op *ctx = crypto_tfm_ctx(tfm);
+
+	if (ctx->fallback)
+		crypto_free_ablkcipher(ctx->fallback);
+
+	ctx->fallback = NULL;
+}
+
+/* async interface */
+static int dcp_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+		unsigned int len)
+{
+	struct dcp_op *ctx = crypto_ablkcipher_ctx(tfm);
+	unsigned int ret = 0;
+	ctx->keylen = len;
+	ctx->flags = 0;
+	if (len == AES_KEYSIZE_128) {
+		if (memcmp(ctx->key, key, AES_KEYSIZE_128)) {
+			memcpy(ctx->key, key, len);
+			ctx->flags |= DCP_NEW_KEY;
+		}
+		return 0;
+	}
+
+	ctx->fallback->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
+	ctx->fallback->base.crt_flags |=
+		(tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);
+
+	ret = crypto_ablkcipher_setkey(ctx->fallback, key, len);
+	if (ret) {
+		struct crypto_tfm *tfm_aux = crypto_ablkcipher_tfm(tfm);
+
+		tfm_aux->crt_flags &= ~CRYPTO_TFM_RES_MASK;
+		tfm_aux->crt_flags |=
+			(ctx->fallback->base.crt_flags & CRYPTO_TFM_RES_MASK);
+	}
+	return ret;
+}
+
+static int dcp_aes_cbc_crypt(struct ablkcipher_request *req, int mode)
+{
+	struct dcp_dev_req_ctx *rctx = ablkcipher_request_ctx(req);
+	struct dcp_dev *dev = global_dev;
+	unsigned long flags;
+	int err = 0;
+
+	if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE))
+		return -EINVAL;
+
+	rctx->mode = mode;
+
+	spin_lock_irqsave(&dev->queue_lock, flags);
+	err = ablkcipher_enqueue_request(&dev->queue, req);
+	spin_unlock_irqrestore(&dev->queue_lock, flags);
+
+	flags = test_and_set_bit(DCP_FLAG_BUSY, &dev->flags);
+
+	if (!(flags & DCP_FLAG_BUSY))
+		tasklet_schedule(&dev->queue_task);
+
+	return err;
+}
+
+static int dcp_aes_cbc_encrypt(struct ablkcipher_request *req)
+{
+	struct crypto_tfm *tfm =
+		crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
+	struct dcp_op *ctx = crypto_ablkcipher_ctx(
+		crypto_ablkcipher_reqtfm(req));
+
+	if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
+		int err = 0;
+		ablkcipher_request_set_tfm(req, ctx->fallback);
+		err = crypto_ablkcipher_encrypt(req);
+		ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
+		return err;
+	}
+
+	return dcp_aes_cbc_crypt(req, DCP_AES | DCP_ENC | DCP_CBC);
+}
+
+static int dcp_aes_cbc_decrypt(struct ablkcipher_request *req)
+{
+	struct crypto_tfm *tfm =
+		crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
+	struct dcp_op *ctx = crypto_ablkcipher_ctx(
+		crypto_ablkcipher_reqtfm(req));
+
+	if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
+		int err = 0;
+		ablkcipher_request_set_tfm(req, ctx->fallback);
+		err = crypto_ablkcipher_decrypt(req);
+		ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
+		return err;
+	}
+	return dcp_aes_cbc_crypt(req, DCP_AES | DCP_DEC | DCP_CBC);
+}
+
+static struct crypto_alg algs[] = {
+	{
+		.cra_name = "cbc(aes)",
+		.cra_driver_name = "dcp-cbc-aes",
+		.cra_alignmask = 3,
+		.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC |
+			  CRYPTO_ALG_NEED_FALLBACK,
+		.cra_blocksize = AES_KEYSIZE_128,
+		.cra_type = &crypto_ablkcipher_type,
+		.cra_priority = 300,
+		.cra_u.ablkcipher = {
+			.min_keysize =	AES_KEYSIZE_128,
+			.max_keysize = AES_KEYSIZE_128,
+			.setkey = dcp_aes_setkey,
+			.encrypt = dcp_aes_cbc_encrypt,
+			.decrypt = dcp_aes_cbc_decrypt,
+			.ivsize = AES_KEYSIZE_128,
+		}
+
+	},
+};
+
+/* DCP bootstream verification interface: uses OTP key for crypto */
+static int dcp_bootstream_open(struct inode *inode, struct file *file)
+{
+	file->private_data = container_of((file->private_data),
+			struct dcp_dev, dcp_bootstream_misc);
+	return 0;
+}
+
+static long dcp_bootstream_ioctl(struct file *file,
+					 unsigned int cmd, unsigned long arg)
+{
+	struct dcp_dev *dev = (struct dcp_dev *) file->private_data;
+	void __user *argp = (void __user *)arg;
+	int ret;
+
+	if (dev == NULL)
+		return -EBADF;
+
+	if (cmd != DBS_ENC && cmd != DBS_DEC)
+		return -EINVAL;
+
+	if (copy_from_user(dev->payload_base, argp, 16))
+		return -EFAULT;
+
+	if (test_and_set_bit(DCP_FLAG_BUSY, &dev->flags))
+		return -EAGAIN;
+
+	dev->ctx = kzalloc(sizeof(struct dcp_op), GFP_KERNEL);
+	if (!dev->ctx) {
+		dev_err(dev->dev,
+			"cannot allocate context for OTP crypto");
+		clear_bit(DCP_FLAG_BUSY, &dev->flags);
+		return -ENOMEM;
+	}
+
+	dev->ctx->flags = DCP_AES | DCP_ECB | DCP_OTP_KEY | DCP_CBC_INIT;
+	dev->ctx->flags |= (cmd == DBS_ENC) ? DCP_ENC : DCP_DEC;
+	dev->hw_pkg[0]->src = dev->payload_base_dma;
+	dev->hw_pkg[0]->dst = dev->payload_base_dma;
+	dev->hw_pkg[0]->size = 16;
+
+	dcp_op_start(dev, 0);
+
+	while (test_bit(DCP_FLAG_BUSY, &dev->flags))
+		cpu_relax();
+
+	ret = dev->ctx->stat;
+	if (!ret && copy_to_user(argp, dev->payload_base, 16))
+		ret =  -EFAULT;
+
+	kfree(dev->ctx);
+
+	return ret;
+}
+
+static const struct file_operations dcp_bootstream_fops = {
+	.owner =		THIS_MODULE,
+	.unlocked_ioctl =	dcp_bootstream_ioctl,
+	.open =			dcp_bootstream_open,
+};
+
+static int dcp_probe(struct platform_device *pdev)
+{
+	struct dcp_dev *dev = NULL;
+	struct resource *r;
+	int i, ret, j;
+
+	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	global_dev = dev;
+	dev->dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, dev);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		dev_err(&pdev->dev, "failed to get IORESOURCE_MEM\n");
+		return -ENXIO;
+	}
+	dev->dcp_regs_base = devm_ioremap(&pdev->dev, r->start,
+					  resource_size(r));
+
+	dcp_set(dev, DCP_CTRL_SFRST, DCP_REG_CTRL);
+	udelay(10);
+	dcp_clear(dev, DCP_CTRL_SFRST | DCP_CTRL_CLKGATE, DCP_REG_CTRL);
+
+	dcp_write(dev, DCP_CTRL_GATHER_RES_WRITE |
+		DCP_CTRL_ENABLE_CONTEXT_CACHE | DCP_CTRL_CH_IRQ_E_1,
+		DCP_REG_CTRL);
+
+	dcp_write(dev, DCP_CHAN_CTRL_ENABLE_1, DCP_REG_CHAN_CTRL);
+
+	for (i = 0; i < 4; i++)
+		dcp_clear(dev, -1, dcp_chan_reg(DCP_REG_CHAN_STAT, i));
+
+	dcp_clear(dev, -1, DCP_REG_STAT);
+
+
+	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!r) {
+		dev_err(&pdev->dev, "can't get IRQ resource (0)\n");
+		return -EIO;
+	}
+	dev->dcp_vmi_irq = r->start;
+	ret = request_irq(dev->dcp_vmi_irq, dcp_vmi_irq, 0, "dcp", dev);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "can't request_irq (0)\n");
+		return -EIO;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+	if (!r) {
+		dev_err(&pdev->dev, "can't get IRQ resource (1)\n");
+		ret = -EIO;
+		goto err_free_irq0;
+	}
+	dev->dcp_irq = r->start;
+	ret = request_irq(dev->dcp_irq, dcp_irq, 0, "dcp", dev);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "can't request_irq (1)\n");
+		ret = -EIO;
+		goto err_free_irq0;
+	}
+
+	dev->hw_pkg[0] = dma_alloc_coherent(&pdev->dev,
+			DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
+			&dev->hw_phys_pkg,
+			GFP_KERNEL);
+	if (!dev->hw_pkg[0]) {
+		dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
+		ret = -ENOMEM;
+		goto err_free_irq1;
+	}
+
+	for (i = 1; i < DCP_MAX_PKG; i++) {
+		dev->hw_pkg[i - 1]->next = dev->hw_phys_pkg
+				+ i * sizeof(struct dcp_hw_packet);
+		dev->hw_pkg[i] = dev->hw_pkg[i - 1] + 1;
+	}
+	dev->hw_pkg[i - 1]->next = dev->hw_phys_pkg;
+
+
+	dev->payload_base = dma_alloc_coherent(&pdev->dev, 2 * AES_KEYSIZE_128,
+			&dev->payload_base_dma, GFP_KERNEL);
+	if (!dev->payload_base) {
+		dev_err(&pdev->dev, "Could not allocate memory for key\n");
+		ret = -ENOMEM;
+		goto err_free_hw_packet;
+	}
+	tasklet_init(&dev->queue_task, dcp_queue_task,
+		(unsigned long) dev);
+	tasklet_init(&dev->done_task, dcp_done_task,
+		(unsigned long) dev);
+	spin_lock_init(&dev->queue_lock);
+
+	crypto_init_queue(&dev->queue, 10);
+
+	init_timer(&dev->watchdog);
+	dev->watchdog.function = &dcp_watchdog;
+	dev->watchdog.data = (unsigned long)dev;
+
+	dev->dcp_bootstream_misc.minor = MISC_DYNAMIC_MINOR,
+	dev->dcp_bootstream_misc.name = "dcpboot",
+	dev->dcp_bootstream_misc.fops = &dcp_bootstream_fops,
+	ret = misc_register(&dev->dcp_bootstream_misc);
+	if (ret != 0) {
+		dev_err(dev->dev, "Unable to register misc device\n");
+		goto err_free_key_iv;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(algs); i++) {
+		algs[i].cra_priority = 300;
+		algs[i].cra_ctxsize = sizeof(struct dcp_op);
+		algs[i].cra_module = THIS_MODULE;
+		algs[i].cra_init = dcp_cra_init;
+		algs[i].cra_exit = dcp_cra_exit;
+		if (crypto_register_alg(&algs[i])) {
+			dev_err(&pdev->dev, "register algorithm failed\n");
+			ret = -ENOMEM;
+			goto err_unregister;
+		}
+	}
+	dev_notice(&pdev->dev, "DCP crypto enabled.!\n");
+
+	return 0;
+
+err_unregister:
+	for (j = 0; j < i; j++)
+		crypto_unregister_alg(&algs[j]);
+err_free_key_iv:
+	dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
+			dev->payload_base_dma);
+err_free_hw_packet:
+	dma_free_coherent(&pdev->dev, DCP_MAX_PKG *
+		sizeof(struct dcp_hw_packet), dev->hw_pkg[0],
+		dev->hw_phys_pkg);
+err_free_irq1:
+	free_irq(dev->dcp_irq, dev);
+err_free_irq0:
+	free_irq(dev->dcp_vmi_irq, dev);
+
+	return ret;
+}
+
+static int dcp_remove(struct platform_device *pdev)
+{
+	struct dcp_dev *dev;
+	int j;
+	dev = platform_get_drvdata(pdev);
+
+	dma_free_coherent(&pdev->dev,
+			DCP_MAX_PKG * sizeof(struct dcp_hw_packet),
+			dev->hw_pkg[0],	dev->hw_phys_pkg);
+
+	dma_free_coherent(&pdev->dev, 2 * AES_KEYSIZE_128, dev->payload_base,
+			dev->payload_base_dma);
+
+	free_irq(dev->dcp_irq, dev);
+	free_irq(dev->dcp_vmi_irq, dev);
+
+	tasklet_kill(&dev->done_task);
+	tasklet_kill(&dev->queue_task);
+
+	for (j = 0; j < ARRAY_SIZE(algs); j++)
+		crypto_unregister_alg(&algs[j]);
+
+	misc_deregister(&dev->dcp_bootstream_misc);
+
+	return 0;
+}
+
+static struct of_device_id fs_dcp_of_match[] = {
+	{	.compatible = "fsl-dcp"},
+	{},
+};
+
+static struct platform_driver fs_dcp_driver = {
+	.probe = dcp_probe,
+	.remove = dcp_remove,
+	.driver = {
+		.name = "fsl-dcp",
+		.owner = THIS_MODULE,
+		.of_match_table = fs_dcp_of_match
+	}
+};
+
+module_platform_driver(fs_dcp_driver);
+
+
+MODULE_AUTHOR("Tobias Rauter <tobias.rauter@gmail.com>");
+MODULE_DESCRIPTION("Freescale DCP Crypto Driver");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/hifn_795x.c linux-libre-3.11-rc7-gnu/drivers/crypto/hifn_795x.c
--- linux-libre-3.10-gnu/drivers/crypto/hifn_795x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/hifn_795x.c	2013-08-25 20:43:22.000000000 -0400
@@ -2676,7 +2676,7 @@ err_out_stop_device:
 	hifn_reset_dma(dev, 1);
 	hifn_stop_device(dev);
 err_out_free_irq:
-	free_irq(dev->irq, dev->name);
+	free_irq(dev->irq, dev);
 	tasklet_kill(&dev->tasklet);
 err_out_free_desc:
 	pci_free_consistent(pdev, sizeof(struct hifn_dma),
@@ -2711,7 +2711,7 @@ static void hifn_remove(struct pci_dev *
 		hifn_reset_dma(dev, 1);
 		hifn_stop_device(dev);
 
-		free_irq(dev->irq, dev->name);
+		free_irq(dev->irq, dev);
 		tasklet_kill(&dev->tasklet);
 
 		hifn_flush(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/Kconfig linux-libre-3.11-rc7-gnu/drivers/crypto/Kconfig
--- linux-libre-3.10-gnu/drivers/crypto/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -278,7 +278,7 @@ config CRYPTO_DEV_PICOXCELL
 
 config CRYPTO_DEV_SAHARA
 	tristate "Support for SAHARA crypto accelerator"
-	depends on ARCH_MXC && EXPERIMENTAL && OF
+	depends on ARCH_MXC && OF
 	select CRYPTO_BLKCIPHER
 	select CRYPTO_AES
 	select CRYPTO_ECB
@@ -286,6 +286,16 @@ config CRYPTO_DEV_SAHARA
 	  This option enables support for the SAHARA HW crypto accelerator
 	  found in some Freescale i.MX chips.
 
+config CRYPTO_DEV_DCP
+	tristate "Support for the DCP engine"
+	depends on ARCH_MXS && OF
+	select CRYPTO_BLKCIPHER
+	select CRYPTO_AES
+	select CRYPTO_CBC
+	help
+	  This options enables support for the hardware crypto-acceleration
+	  capabilities of the DCP co-processor
+
 config CRYPTO_DEV_S5P
 	tristate "Support for Samsung S5PV210 crypto accelerator"
 	depends on ARCH_S5PV210
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/Makefile linux-libre-3.11-rc7-gnu/drivers/crypto/Makefile
--- linux-libre-3.10-gnu/drivers/crypto/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += om
 obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
 obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
 obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
+obj-$(CONFIG_CRYPTO_DEV_DCP) += dcp.o
 obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
 obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o
 obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/mv_cesa.c linux-libre-3.11-rc7-gnu/drivers/crypto/mv_cesa.c
--- linux-libre-3.10-gnu/drivers/crypto/mv_cesa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/mv_cesa.c	2013-08-25 20:43:22.000000000 -0400
@@ -1146,7 +1146,6 @@ err_unmap_reg:
 err:
 	kfree(cp);
 	cpg = NULL;
-	platform_set_drvdata(pdev, NULL);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/omap-aes.c linux-libre-3.11-rc7-gnu/drivers/crypto/omap-aes.c
--- linux-libre-3.10-gnu/drivers/crypto/omap-aes.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/omap-aes.c	2013-08-25 20:43:22.000000000 -0400
@@ -203,13 +203,6 @@ static void omap_aes_write_n(struct omap
 
 static int omap_aes_hw_init(struct omap_aes_dev *dd)
 {
-	/*
-	 * clocks are enabled when request starts and disabled when finished.
-	 * It may be long delays between requests.
-	 * Device might go to off mode to save power.
-	 */
-	pm_runtime_get_sync(dd->dev);
-
 	if (!(dd->flags & FLAGS_INIT)) {
 		dd->flags |= FLAGS_INIT;
 		dd->err = 0;
@@ -636,7 +629,6 @@ static void omap_aes_finish_req(struct o
 
 	pr_debug("err: %d\n", err);
 
-	pm_runtime_put(dd->dev);
 	dd->flags &= ~FLAGS_BUSY;
 
 	req->base.complete(&req->base, err);
@@ -837,8 +829,16 @@ static int omap_aes_ctr_decrypt(struct a
 
 static int omap_aes_cra_init(struct crypto_tfm *tfm)
 {
-	pr_debug("enter\n");
+	struct omap_aes_dev *dd = NULL;
 
+	/* Find AES device, currently picks the first device */
+	spin_lock_bh(&list_lock);
+	list_for_each_entry(dd, &dev_list, list) {
+		break;
+	}
+	spin_unlock_bh(&list_lock);
+
+	pm_runtime_get_sync(dd->dev);
 	tfm->crt_ablkcipher.reqsize = sizeof(struct omap_aes_reqctx);
 
 	return 0;
@@ -846,7 +846,16 @@ static int omap_aes_cra_init(struct cryp
 
 static void omap_aes_cra_exit(struct crypto_tfm *tfm)
 {
-	pr_debug("enter\n");
+	struct omap_aes_dev *dd = NULL;
+
+	/* Find AES device, currently picks the first device */
+	spin_lock_bh(&list_lock);
+	list_for_each_entry(dd, &dev_list, list) {
+		break;
+	}
+	spin_unlock_bh(&list_lock);
+
+	pm_runtime_put_sync(dd->dev);
 }
 
 /* ********************** ALGS ************************************ */
@@ -1125,10 +1134,9 @@ static int omap_aes_probe(struct platfor
 	if (err)
 		goto err_res;
 
-	dd->io_base = devm_request_and_ioremap(dev, &res);
-	if (!dd->io_base) {
-		dev_err(dev, "can't ioremap\n");
-		err = -ENOMEM;
+	dd->io_base = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(dd->io_base)) {
+		err = PTR_ERR(dd->io_base);
 		goto err_res;
 	}
 	dd->phys_base = res.start;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/omap-sham.c linux-libre-3.11-rc7-gnu/drivers/crypto/omap-sham.c
--- linux-libre-3.10-gnu/drivers/crypto/omap-sham.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/omap-sham.c	2013-08-25 20:43:22.000000000 -0400
@@ -1686,10 +1686,9 @@ static int omap_sham_probe(struct platfo
 	if (err)
 		goto res_err;
 
-	dd->io_base = devm_request_and_ioremap(dev, &res);
-	if (!dd->io_base) {
-		dev_err(dev, "can't ioremap\n");
-		err = -ENOMEM;
+	dd->io_base = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(dd->io_base)) {
+		err = PTR_ERR(dd->io_base);
 		goto res_err;
 	}
 	dd->phys_base = res.start;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/picoxcell_crypto.c linux-libre-3.11-rc7-gnu/drivers/crypto/picoxcell_crypto.c
--- linux-libre-3.10-gnu/drivers/crypto/picoxcell_crypto.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/picoxcell_crypto.c	2013-08-25 20:43:22.000000000 -0400
@@ -1298,7 +1298,7 @@ static ssize_t spacc_stat_irq_thresh_sto
 	struct spacc_engine *engine = spacc_dev_to_engine(dev);
 	unsigned long thresh;
 
-	if (strict_strtoul(buf, 0, &thresh))
+	if (kstrtoul(buf, 0, &thresh))
 		return -EINVAL;
 
 	thresh = clamp(thresh, 1UL, engine->fifo_sz - 1);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/s5p-sss.c linux-libre-3.11-rc7-gnu/drivers/crypto/s5p-sss.c
--- linux-libre-3.10-gnu/drivers/crypto/s5p-sss.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/s5p-sss.c	2013-08-25 20:43:22.000000000 -0400
@@ -647,7 +647,6 @@ static int s5p_aes_probe(struct platform
 	clk_disable(pdata->clk);
 
 	s5p_dev = NULL;
-	platform_set_drvdata(pdev, NULL);
 
 	return err;
 }
@@ -668,7 +667,6 @@ static int s5p_aes_remove(struct platfor
 	clk_disable(pdata->clk);
 
 	s5p_dev = NULL;
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/talitos.c linux-libre-3.11-rc7-gnu/drivers/crypto/talitos.c
--- linux-libre-3.10-gnu/drivers/crypto/talitos.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/talitos.c	2013-08-25 20:43:22.000000000 -0400
@@ -1112,64 +1112,6 @@ static int sg_count(struct scatterlist *
 	return sg_nents;
 }
 
-/**
- * sg_copy_end_to_buffer - Copy end data from SG list to a linear buffer
- * @sgl:		 The SG list
- * @nents:		 Number of SG entries
- * @buf:		 Where to copy to
- * @buflen:		 The number of bytes to copy
- * @skip:		 The number of bytes to skip before copying.
- *                       Note: skip + buflen should equal SG total size.
- *
- * Returns the number of copied bytes.
- *
- **/
-static size_t sg_copy_end_to_buffer(struct scatterlist *sgl, unsigned int nents,
-				    void *buf, size_t buflen, unsigned int skip)
-{
-	unsigned int offset = 0;
-	unsigned int boffset = 0;
-	struct sg_mapping_iter miter;
-	unsigned long flags;
-	unsigned int sg_flags = SG_MITER_ATOMIC;
-	size_t total_buffer = buflen + skip;
-
-	sg_flags |= SG_MITER_FROM_SG;
-
-	sg_miter_start(&miter, sgl, nents, sg_flags);
-
-	local_irq_save(flags);
-
-	while (sg_miter_next(&miter) && offset < total_buffer) {
-		unsigned int len;
-		unsigned int ignore;
-
-		if ((offset + miter.length) > skip) {
-			if (offset < skip) {
-				/* Copy part of this segment */
-				ignore = skip - offset;
-				len = miter.length - ignore;
-				if (boffset + len > buflen)
-					len = buflen - boffset;
-				memcpy(buf + boffset, miter.addr + ignore, len);
-			} else {
-				/* Copy all of this segment (up to buflen) */
-				len = miter.length;
-				if (boffset + len > buflen)
-					len = buflen - boffset;
-				memcpy(buf + boffset, miter.addr, len);
-			}
-			boffset += len;
-		}
-		offset += miter.length;
-	}
-
-	sg_miter_stop(&miter);
-
-	local_irq_restore(flags);
-	return boffset;
-}
-
 /*
  * allocate and map the extended descriptor
  */
@@ -1800,7 +1742,7 @@ static int ahash_process_req(struct ahas
 
 	if (to_hash_later) {
 		int nents = sg_count(areq->src, nbytes, &chained);
-		sg_copy_end_to_buffer(areq->src, nents,
+		sg_pcopy_to_buffer(areq->src, nents,
 				      req_ctx->bufnext,
 				      to_hash_later,
 				      nbytes - to_hash_later);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/ux500/cryp/cryp.c linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/cryp/cryp.c
--- linux-libre-3.10-gnu/drivers/crypto/ux500/cryp/cryp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/cryp/cryp.c	2013-08-25 20:43:22.000000000 -0400
@@ -291,7 +291,7 @@ void cryp_save_device_context(struct cry
 			      int cryp_mode)
 {
 	enum cryp_algo_mode algomode;
-	struct cryp_register *src_reg = device_data->base;
+	struct cryp_register __iomem *src_reg = device_data->base;
 	struct cryp_config *config =
 		(struct cryp_config *)device_data->current_ctx;
 
@@ -349,7 +349,7 @@ void cryp_save_device_context(struct cry
 void cryp_restore_device_context(struct cryp_device_data *device_data,
 				 struct cryp_device_context *ctx)
 {
-	struct cryp_register *reg = device_data->base;
+	struct cryp_register __iomem *reg = device_data->base;
 	struct cryp_config *config =
 		(struct cryp_config *)device_data->current_ctx;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/ux500/cryp/cryp_core.c linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/cryp/cryp_core.c
--- linux-libre-3.10-gnu/drivers/crypto/ux500/cryp/cryp_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/cryp/cryp_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -475,6 +475,19 @@ static int cryp_get_device_data(struct c
 static void cryp_dma_setup_channel(struct cryp_device_data *device_data,
 				   struct device *dev)
 {
+	struct dma_slave_config mem2cryp = {
+		.direction = DMA_MEM_TO_DEV,
+		.dst_addr = device_data->phybase + CRYP_DMA_TX_FIFO,
+		.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
+		.dst_maxburst = 4,
+        };
+	struct dma_slave_config cryp2mem = {
+		.direction = DMA_DEV_TO_MEM,
+		.src_addr = device_data->phybase + CRYP_DMA_RX_FIFO,
+		.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
+		.src_maxburst = 4,
+        };
+
 	dma_cap_zero(device_data->dma.mask);
 	dma_cap_set(DMA_SLAVE, device_data->dma.mask);
 
@@ -490,6 +503,9 @@ static void cryp_dma_setup_channel(struc
 				    stedma40_filter,
 				    device_data->dma.cfg_cryp2mem);
 
+	dmaengine_slave_config(device_data->dma.chan_mem2cryp, &mem2cryp);
+	dmaengine_slave_config(device_data->dma.chan_cryp2mem, &cryp2mem);
+
 	init_completion(&device_data->dma.cryp_dma_complete);
 }
 
@@ -537,10 +553,10 @@ static int cryp_set_dma_transfer(struct
 		dev_dbg(ctx->device->dev, "[%s]: Setting up DMA for buffer "
 			"(TO_DEVICE)", __func__);
 
-		desc = channel->device->device_prep_slave_sg(channel,
-					     ctx->device->dma.sg_src,
-					     ctx->device->dma.sg_src_len,
-					     direction, DMA_CTRL_ACK, NULL);
+		desc = dmaengine_prep_slave_sg(channel,
+				ctx->device->dma.sg_src,
+				ctx->device->dma.sg_src_len,
+				direction, DMA_CTRL_ACK);
 		break;
 
 	case DMA_FROM_DEVICE:
@@ -561,12 +577,12 @@ static int cryp_set_dma_transfer(struct
 		dev_dbg(ctx->device->dev, "[%s]: Setting up DMA for buffer "
 			"(FROM_DEVICE)", __func__);
 
-		desc = channel->device->device_prep_slave_sg(channel,
-					     ctx->device->dma.sg_dst,
-					     ctx->device->dma.sg_dst_len,
-					     direction,
-					     DMA_CTRL_ACK |
-					     DMA_PREP_INTERRUPT, NULL);
+		desc = dmaengine_prep_slave_sg(channel,
+				ctx->device->dma.sg_dst,
+				ctx->device->dma.sg_dst_len,
+				direction,
+				DMA_CTRL_ACK |
+				DMA_PREP_INTERRUPT);
 
 		desc->callback = cryp_dma_out_callback;
 		desc->callback_param = ctx;
@@ -578,7 +594,7 @@ static int cryp_set_dma_transfer(struct
 		return -EFAULT;
 	}
 
-	cookie = desc->tx_submit(desc);
+	cookie = dmaengine_submit(desc);
 	dma_async_issue_pending(channel);
 
 	return 0;
@@ -591,12 +607,12 @@ static void cryp_dma_done(struct cryp_ct
 	dev_dbg(ctx->device->dev, "[%s]: ", __func__);
 
 	chan = ctx->device->dma.chan_mem2cryp;
-	chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+	dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
 	dma_unmap_sg(chan->device->dev, ctx->device->dma.sg_src,
 		     ctx->device->dma.sg_src_len, DMA_TO_DEVICE);
 
 	chan = ctx->device->dma.chan_cryp2mem;
-	chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+	dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
 	dma_unmap_sg(chan->device->dev, ctx->device->dma.sg_dst,
 		     ctx->device->dma.sg_dst_len, DMA_FROM_DEVICE);
 }
@@ -1431,6 +1447,7 @@ static int ux500_cryp_probe(struct platf
 		goto out_kfree;
 	}
 
+	device_data->phybase = res->start;
 	device_data->base = ioremap(res->start, resource_size(res));
 	if (!device_data->base) {
 		dev_err(dev, "[%s]: ioremap failed!", __func__);
@@ -1458,11 +1475,17 @@ static int ux500_cryp_probe(struct platf
 		goto out_regulator;
 	}
 
+	ret = clk_prepare(device_data->clk);
+	if (ret) {
+		dev_err(dev, "[%s]: clk_prepare() failed!", __func__);
+		goto out_clk;
+	}
+
 	/* Enable device power (and clock) */
 	ret = cryp_enable_power(device_data->dev, device_data, false);
 	if (ret) {
 		dev_err(dev, "[%s]: cryp_enable_power() failed!", __func__);
-		goto out_clk;
+		goto out_clk_unprepare;
 	}
 
 	cryp_error = cryp_check(device_data);
@@ -1518,11 +1541,16 @@ static int ux500_cryp_probe(struct platf
 		goto out_power;
 	}
 
+	dev_info(dev, "successfully registered\n");
+
 	return 0;
 
 out_power:
 	cryp_disable_power(device_data->dev, device_data, false);
 
+out_clk_unprepare:
+	clk_unprepare(device_data->clk);
+
 out_clk:
 	clk_put(device_data->clk);
 
@@ -1593,6 +1621,7 @@ static int ux500_cryp_remove(struct plat
 		dev_err(&pdev->dev, "[%s]: cryp_disable_power() failed",
 			__func__);
 
+	clk_unprepare(device_data->clk);
 	clk_put(device_data->clk);
 	regulator_put(device_data->pwr_regulator);
 
@@ -1600,7 +1629,7 @@ static int ux500_cryp_remove(struct plat
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res)
-		release_mem_region(res->start, res->end - res->start + 1);
+		release_mem_region(res->start, resource_size(res));
 
 	kfree(device_data);
 
@@ -1743,6 +1772,11 @@ static int ux500_cryp_resume(struct devi
 
 static SIMPLE_DEV_PM_OPS(ux500_cryp_pm, ux500_cryp_suspend, ux500_cryp_resume);
 
+static const struct of_device_id ux500_cryp_match[] = {
+        { .compatible = "stericsson,ux500-cryp" },
+        { },
+};
+
 static struct platform_driver cryp_driver = {
 	.probe  = ux500_cryp_probe,
 	.remove = ux500_cryp_remove,
@@ -1750,6 +1784,7 @@ static struct platform_driver cryp_drive
 	.driver = {
 		.owner = THIS_MODULE,
 		.name  = "cryp1",
+		.of_match_table = ux500_cryp_match,
 		.pm    = &ux500_cryp_pm,
 	}
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/ux500/cryp/cryp.h linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/cryp/cryp.h
--- linux-libre-3.10-gnu/drivers/crypto/ux500/cryp/cryp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/cryp/cryp.h	2013-08-25 20:43:22.000000000 -0400
@@ -114,6 +114,9 @@ enum cryp_status_id {
 };
 
 /* Cryp DMA interface */
+#define CRYP_DMA_TX_FIFO	0x08
+#define CRYP_DMA_RX_FIFO	0x10
+
 enum cryp_dma_req_type {
 	CRYP_DMA_DISABLE_BOTH,
 	CRYP_DMA_ENABLE_IN_DATA,
@@ -217,7 +220,8 @@ struct cryp_dma {
 
 /**
  * struct cryp_device_data - structure for a cryp device.
- * @base: Pointer to the hardware base address.
+ * @base: Pointer to virtual base address of the cryp device.
+ * @phybase: Pointer to physical memory location of the cryp device.
  * @dev: Pointer to the devices dev structure.
  * @clk: Pointer to the device's clock control.
  * @pwr_regulator: Pointer to the device's power control.
@@ -232,6 +236,7 @@ struct cryp_dma {
  */
 struct cryp_device_data {
 	struct cryp_register __iomem *base;
+	phys_addr_t phybase;
 	struct device *dev;
 	struct clk *clk;
 	struct regulator *pwr_regulator;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/ux500/hash/hash_alg.h linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/hash/hash_alg.h
--- linux-libre-3.10-gnu/drivers/crypto/ux500/hash/hash_alg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/hash/hash_alg.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/bitops.h>
 
 #define HASH_BLOCK_SIZE			64
+#define HASH_DMA_FIFO			4
 #define HASH_DMA_ALIGN_SIZE		4
 #define HASH_DMA_PERFORMANCE_MIN_SIZE	1024
 #define HASH_BYTES_PER_WORD		4
@@ -347,7 +348,8 @@ struct hash_req_ctx {
 
 /**
  * struct hash_device_data - structure for a hash device.
- * @base:		Pointer to the hardware base address.
+ * @base:		Pointer to virtual base address of the hash device.
+ * @phybase:		Pointer to physical memory location of the hash device.
  * @list_node:		For inclusion in klist.
  * @dev:		Pointer to the device dev structure.
  * @ctx_lock:		Spinlock for current_ctx.
@@ -361,6 +363,7 @@ struct hash_req_ctx {
  */
 struct hash_device_data {
 	struct hash_register __iomem	*base;
+	phys_addr_t             phybase;
 	struct klist_node	list_node;
 	struct device		*dev;
 	struct spinlock		ctx_lock;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/crypto/ux500/hash/hash_core.c linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/hash/hash_core.c
--- linux-libre-3.10-gnu/drivers/crypto/ux500/hash/hash_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/crypto/ux500/hash/hash_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -122,6 +122,13 @@ static void hash_dma_setup_channel(struc
 				struct device *dev)
 {
 	struct hash_platform_data *platform_data = dev->platform_data;
+	struct dma_slave_config conf = {
+		.direction = DMA_MEM_TO_DEV,
+		.dst_addr = device_data->phybase + HASH_DMA_FIFO,
+		.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
+		.dst_maxburst = 16,
+        };
+
 	dma_cap_zero(device_data->dma.mask);
 	dma_cap_set(DMA_SLAVE, device_data->dma.mask);
 
@@ -131,6 +138,8 @@ static void hash_dma_setup_channel(struc
 				platform_data->dma_filter,
 				device_data->dma.cfg_mem2hash);
 
+	dmaengine_slave_config(device_data->dma.chan_mem2hash, &conf);
+
 	init_completion(&device_data->dma.complete);
 }
 
@@ -171,9 +180,9 @@ static int hash_set_dma_transfer(struct
 
 	dev_dbg(ctx->device->dev, "[%s]: Setting up DMA for buffer "
 			"(TO_DEVICE)", __func__);
-	desc = channel->device->device_prep_slave_sg(channel,
+	desc = dmaengine_prep_slave_sg(channel,
 			ctx->device->dma.sg, ctx->device->dma.sg_len,
-			direction, DMA_CTRL_ACK | DMA_PREP_INTERRUPT, NULL);
+			direction, DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
 	if (!desc) {
 		dev_err(ctx->device->dev,
 			"[%s]: device_prep_slave_sg() failed!", __func__);
@@ -183,7 +192,7 @@ static int hash_set_dma_transfer(struct
 	desc->callback = hash_dma_callback;
 	desc->callback_param = ctx;
 
-	cookie = desc->tx_submit(desc);
+	cookie = dmaengine_submit(desc);
 	dma_async_issue_pending(channel);
 
 	return 0;
@@ -194,7 +203,7 @@ static void hash_dma_done(struct hash_ct
 	struct dma_chan *chan;
 
 	chan = ctx->device->dma.chan_mem2hash;
-	chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+	dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
 	dma_unmap_sg(chan->device->dev, ctx->device->dma.sg,
 			ctx->device->dma.sg_len, DMA_TO_DEVICE);
 
@@ -464,12 +473,12 @@ static void hash_hw_write_key(struct has
 		HASH_SET_DIN(&word, nwords);
 	}
 
-	while (device_data->base->str & HASH_STR_DCAL_MASK)
+	while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
 		cpu_relax();
 
 	HASH_SET_DCAL;
 
-	while (device_data->base->str & HASH_STR_DCAL_MASK)
+	while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
 		cpu_relax();
 }
 
@@ -652,7 +661,7 @@ static void hash_messagepad(struct hash_
 	if (index_bytes)
 		HASH_SET_DIN(message, nwords);
 
-	while (device_data->base->str & HASH_STR_DCAL_MASK)
+	while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
 		cpu_relax();
 
 	/* num_of_bytes == 0 => NBLW <- 0 (32 bits valid in DATAIN) */
@@ -667,7 +676,7 @@ static void hash_messagepad(struct hash_
 			(int)(readl_relaxed(&device_data->base->str) &
 				HASH_STR_NBLW_MASK));
 
-	while (device_data->base->str & HASH_STR_DCAL_MASK)
+	while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
 		cpu_relax();
 }
 
@@ -767,7 +776,7 @@ void hash_begin(struct hash_device_data
 	/* HW and SW initializations */
 	/* Note: there is no need to initialize buffer and digest members */
 
-	while (device_data->base->str & HASH_STR_DCAL_MASK)
+	while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
 		cpu_relax();
 
 	/*
@@ -783,8 +792,7 @@ void hash_begin(struct hash_device_data
 	HASH_CLEAR_BITS(&device_data->base->str, HASH_STR_NBLW_MASK);
 }
 
-int hash_process_data(
-		struct hash_device_data *device_data,
+static int hash_process_data(struct hash_device_data *device_data,
 		struct hash_ctx *ctx, struct hash_req_ctx *req_ctx,
 		int msg_length, u8 *data_buffer, u8 *buffer, u8 *index)
 {
@@ -953,7 +961,7 @@ static int hash_dma_final(struct ahash_r
 	wait_for_completion(&ctx->device->dma.complete);
 	hash_dma_done(ctx);
 
-	while (device_data->base->str & HASH_STR_DCAL_MASK)
+	while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
 		cpu_relax();
 
 	if (ctx->config.oper_mode == HASH_OPER_MODE_HMAC && ctx->key) {
@@ -983,7 +991,7 @@ out:
  * hash_hw_final - The final hash calculation function
  * @req:	The hash request for the job.
  */
-int hash_hw_final(struct ahash_request *req)
+static int hash_hw_final(struct ahash_request *req)
 {
 	int ret = 0;
 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
@@ -1051,7 +1059,7 @@ int hash_hw_final(struct ahash_request *
 				req_ctx->state.index);
 	} else {
 		HASH_SET_DCAL;
-		while (device_data->base->str & HASH_STR_DCAL_MASK)
+		while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
 			cpu_relax();
 	}
 
@@ -1180,7 +1188,7 @@ int hash_resume_state(struct hash_device
 	temp_cr = device_state->temp_cr;
 	writel_relaxed(temp_cr & HASH_CR_RESUME_MASK, &device_data->base->cr);
 
-	if (device_data->base->cr & HASH_CR_MODE_MASK)
+	if (readl(&device_data->base->cr) & HASH_CR_MODE_MASK)
 		hash_mode = HASH_OPER_MODE_HMAC;
 	else
 		hash_mode = HASH_OPER_MODE_HASH;
@@ -1224,7 +1232,7 @@ int hash_save_state(struct hash_device_d
 	 * actually makes sure that there isn't any ongoing calculation in the
 	 * hardware.
 	 */
-	while (device_data->base->str & HASH_STR_DCAL_MASK)
+	while (readl(&device_data->base->str) & HASH_STR_DCAL_MASK)
 		cpu_relax();
 
 	temp_cr = readl_relaxed(&device_data->base->cr);
@@ -1233,7 +1241,7 @@ int hash_save_state(struct hash_device_d
 
 	device_state->din_reg = readl_relaxed(&device_data->base->din);
 
-	if (device_data->base->cr & HASH_CR_MODE_MASK)
+	if (readl(&device_data->base->cr) & HASH_CR_MODE_MASK)
 		hash_mode = HASH_OPER_MODE_HMAC;
 	else
 		hash_mode = HASH_OPER_MODE_HASH;
@@ -1699,6 +1707,7 @@ static int ux500_hash_probe(struct platf
 		goto out_kfree;
 	}
 
+	device_data->phybase = res->start;
 	device_data->base = ioremap(res->start, resource_size(res));
 	if (!device_data->base) {
 		dev_err(dev, "[%s] ioremap() failed!",
@@ -1726,11 +1735,17 @@ static int ux500_hash_probe(struct platf
 		goto out_regulator;
 	}
 
+	ret = clk_prepare(device_data->clk);
+	if (ret) {
+		dev_err(dev, "[%s] clk_prepare() failed!", __func__);
+		goto out_clk;
+	}
+
 	/* Enable device power (and clock) */
 	ret = hash_enable_power(device_data, false);
 	if (ret) {
 		dev_err(dev, "[%s]: hash_enable_power() failed!", __func__);
-		goto out_clk;
+		goto out_clk_unprepare;
 	}
 
 	ret = hash_check_hw(device_data);
@@ -1756,12 +1771,15 @@ static int ux500_hash_probe(struct platf
 		goto out_power;
 	}
 
-	dev_info(dev, "[%s] successfully probed\n", __func__);
+	dev_info(dev, "successfully registered\n");
 	return 0;
 
 out_power:
 	hash_disable_power(device_data, false);
 
+out_clk_unprepare:
+	clk_unprepare(device_data->clk);
+
 out_clk:
 	clk_put(device_data->clk);
 
@@ -1826,6 +1844,7 @@ static int ux500_hash_remove(struct plat
 		dev_err(dev, "[%s]: hash_disable_power() failed",
 			__func__);
 
+	clk_unprepare(device_data->clk);
 	clk_put(device_data->clk);
 	regulator_put(device_data->regulator);
 
@@ -1961,6 +1980,11 @@ static int ux500_hash_resume(struct devi
 
 static SIMPLE_DEV_PM_OPS(ux500_hash_pm, ux500_hash_suspend, ux500_hash_resume);
 
+static const struct of_device_id ux500_hash_match[] = {
+        { .compatible = "stericsson,ux500-hash" },
+        { },
+};
+
 static struct platform_driver hash_driver = {
 	.probe  = ux500_hash_probe,
 	.remove = ux500_hash_remove,
@@ -1968,6 +1992,7 @@ static struct platform_driver hash_drive
 	.driver = {
 		.owner = THIS_MODULE,
 		.name  = "hash1",
+		.of_match_table = ux500_hash_match,
 		.pm    = &ux500_hash_pm,
 	}
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/devfreq/devfreq.c linux-libre-3.11-rc7-gnu/drivers/devfreq/devfreq.c
--- linux-libre-3.10-gnu/drivers/devfreq/devfreq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/devfreq/devfreq.c	2013-08-25 20:43:22.000000000 -0400
@@ -271,6 +271,7 @@ void devfreq_monitor_suspend(struct devf
 		return;
 	}
 
+	devfreq_update_status(devfreq, devfreq->previous_freq);
 	devfreq->stop_polling = true;
 	mutex_unlock(&devfreq->lock);
 	cancel_delayed_work_sync(&devfreq->work);
@@ -287,6 +288,8 @@ EXPORT_SYMBOL(devfreq_monitor_suspend);
  */
 void devfreq_monitor_resume(struct devfreq *devfreq)
 {
+	unsigned long freq;
+
 	mutex_lock(&devfreq->lock);
 	if (!devfreq->stop_polling)
 		goto out;
@@ -295,8 +298,14 @@ void devfreq_monitor_resume(struct devfr
 			devfreq->profile->polling_ms)
 		queue_delayed_work(devfreq_wq, &devfreq->work,
 			msecs_to_jiffies(devfreq->profile->polling_ms));
+
+	devfreq->last_stat_updated = jiffies;
 	devfreq->stop_polling = false;
 
+	if (devfreq->profile->get_cur_freq &&
+		!devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq))
+		devfreq->previous_freq = freq;
+
 out:
 	mutex_unlock(&devfreq->lock);
 }
@@ -477,7 +486,7 @@ struct devfreq *devfreq_add_device(struc
 						GFP_KERNEL);
 	devfreq->last_stat_updated = jiffies;
 
-	dev_set_name(&devfreq->dev, dev_name(dev));
+	dev_set_name(&devfreq->dev, "%s", dev_name(dev));
 	err = device_register(&devfreq->dev);
 	if (err) {
 		put_device(&devfreq->dev);
@@ -518,6 +527,8 @@ EXPORT_SYMBOL(devfreq_add_device);
 /**
  * devfreq_remove_device() - Remove devfreq feature from a device.
  * @devfreq:	the devfreq instance to be removed
+ *
+ * The opposite of devfreq_add_device().
  */
 int devfreq_remove_device(struct devfreq *devfreq)
 {
@@ -533,6 +544,10 @@ EXPORT_SYMBOL(devfreq_remove_device);
 /**
  * devfreq_suspend_device() - Suspend devfreq of a device.
  * @devfreq: the devfreq instance to be suspended
+ *
+ * This function is intended to be called by the pm callbacks
+ * (e.g., runtime_suspend, suspend) of the device driver that
+ * holds the devfreq.
  */
 int devfreq_suspend_device(struct devfreq *devfreq)
 {
@@ -550,6 +565,10 @@ EXPORT_SYMBOL(devfreq_suspend_device);
 /**
  * devfreq_resume_device() - Resume devfreq of a device.
  * @devfreq: the devfreq instance to be resumed
+ *
+ * This function is intended to be called by the pm callbacks
+ * (e.g., runtime_resume, resume) of the device driver that
+ * holds the devfreq.
  */
 int devfreq_resume_device(struct devfreq *devfreq)
 {
@@ -905,11 +924,11 @@ static ssize_t show_trans_table(struct d
 {
 	struct devfreq *devfreq = to_devfreq(dev);
 	ssize_t len;
-	int i, j, err;
+	int i, j;
 	unsigned int max_state = devfreq->profile->max_state;
 
-	err = devfreq_update_status(devfreq, devfreq->previous_freq);
-	if (err)
+	if (!devfreq->stop_polling &&
+			devfreq_update_status(devfreq, devfreq->previous_freq))
 		return 0;
 
 	len = sprintf(buf, "   From  :   To\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/devfreq/exynos/exynos4_bus.c linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/exynos4_bus.c
--- linux-libre-3.10-gnu/drivers/devfreq/exynos/exynos4_bus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/exynos4_bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1154 @@
+/* drivers/devfreq/exynos4210_memorybus.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *	MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * EXYNOS4 - Memory/Bus clock frequency scaling support in DEVFREQ framework
+ *	This version supports EXYNOS4210 only. This changes bus frequencies
+ *	and vddint voltages. Exynos4412/4212 should be able to be supported
+ *	with minor modifications.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/suspend.h>
+#include <linux/opp.h>
+#include <linux/devfreq.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/module.h>
+
+/* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */
+#ifdef CONFIG_EXYNOS_ASV
+extern unsigned int exynos_result_of_asv;
+#endif
+
+#include <mach/regs-clock.h>
+
+#include <plat/map-s5p.h>
+
+#define MAX_SAFEVOLT	1200000 /* 1.2V */
+
+enum exynos4_busf_type {
+	TYPE_BUSF_EXYNOS4210,
+	TYPE_BUSF_EXYNOS4x12,
+};
+
+/* Assume that the bus is saturated if the utilization is 40% */
+#define BUS_SATURATION_RATIO	40
+
+enum ppmu_counter {
+	PPMU_PMNCNT0 = 0,
+	PPMU_PMCCNT1,
+	PPMU_PMNCNT2,
+	PPMU_PMNCNT3,
+	PPMU_PMNCNT_MAX,
+};
+struct exynos4_ppmu {
+	void __iomem *hw_base;
+	unsigned int ccnt;
+	unsigned int event;
+	unsigned int count[PPMU_PMNCNT_MAX];
+	bool ccnt_overflow;
+	bool count_overflow[PPMU_PMNCNT_MAX];
+};
+
+enum busclk_level_idx {
+	LV_0 = 0,
+	LV_1,
+	LV_2,
+	LV_3,
+	LV_4,
+	_LV_END
+};
+#define EX4210_LV_MAX	LV_2
+#define EX4x12_LV_MAX	LV_4
+#define EX4210_LV_NUM	(LV_2 + 1)
+#define EX4x12_LV_NUM	(LV_4 + 1)
+
+/**
+ * struct busfreq_opp_info - opp information for bus
+ * @rate:	Frequency in hertz
+ * @volt:	Voltage in microvolts corresponding to this OPP
+ */
+struct busfreq_opp_info {
+	unsigned long rate;
+	unsigned long volt;
+};
+
+struct busfreq_data {
+	enum exynos4_busf_type type;
+	struct device *dev;
+	struct devfreq *devfreq;
+	bool disabled;
+	struct regulator *vdd_int;
+	struct regulator *vdd_mif; /* Exynos4412/4212 only */
+	struct busfreq_opp_info curr_oppinfo;
+	struct exynos4_ppmu dmc[2];
+
+	struct notifier_block pm_notifier;
+	struct mutex lock;
+
+	/* Dividers calculated at boot/probe-time */
+	unsigned int dmc_divtable[_LV_END]; /* DMC0 */
+	unsigned int top_divtable[_LV_END];
+};
+
+struct bus_opp_table {
+	unsigned int idx;
+	unsigned long clk;
+	unsigned long volt;
+};
+
+/* 4210 controls clock of mif and voltage of int */
+static struct bus_opp_table exynos4210_busclk_table[] = {
+	{LV_0, 400000, 1150000},
+	{LV_1, 267000, 1050000},
+	{LV_2, 133000, 1025000},
+	{0, 0, 0},
+};
+
+/*
+ * MIF is the main control knob clock for exynox4x12 MIF/INT
+ * clock and voltage of both mif/int are controlled.
+ */
+static struct bus_opp_table exynos4x12_mifclk_table[] = {
+	{LV_0, 400000, 1100000},
+	{LV_1, 267000, 1000000},
+	{LV_2, 160000, 950000},
+	{LV_3, 133000, 950000},
+	{LV_4, 100000, 950000},
+	{0, 0, 0},
+};
+
+/*
+ * INT is not the control knob of 4x12. LV_x is not meant to represent
+ * the current performance. (MIF does)
+ */
+static struct bus_opp_table exynos4x12_intclk_table[] = {
+	{LV_0, 200000, 1000000},
+	{LV_1, 160000, 950000},
+	{LV_2, 133000, 925000},
+	{LV_3, 100000, 900000},
+	{0, 0, 0},
+};
+
+/* TODO: asv volt definitions are "__initdata"? */
+/* Some chips have different operating voltages */
+static unsigned int exynos4210_asv_volt[][EX4210_LV_NUM] = {
+	{1150000, 1050000, 1050000},
+	{1125000, 1025000, 1025000},
+	{1100000, 1000000, 1000000},
+	{1075000, 975000, 975000},
+	{1050000, 950000, 950000},
+};
+
+static unsigned int exynos4x12_mif_step_50[][EX4x12_LV_NUM] = {
+	/* 400      267     160     133     100 */
+	{1050000, 950000, 900000, 900000, 900000}, /* ASV0 */
+	{1050000, 950000, 900000, 900000, 900000}, /* ASV1 */
+	{1050000, 950000, 900000, 900000, 900000}, /* ASV2 */
+	{1050000, 900000, 900000, 900000, 900000}, /* ASV3 */
+	{1050000, 900000, 900000, 900000, 850000}, /* ASV4 */
+	{1050000, 900000, 900000, 850000, 850000}, /* ASV5 */
+	{1050000, 900000, 850000, 850000, 850000}, /* ASV6 */
+	{1050000, 900000, 850000, 850000, 850000}, /* ASV7 */
+	{1050000, 900000, 850000, 850000, 850000}, /* ASV8 */
+};
+
+static unsigned int exynos4x12_int_volt[][EX4x12_LV_NUM] = {
+	/* 200    160      133     100 */
+	{1000000, 950000, 925000, 900000}, /* ASV0 */
+	{975000,  925000, 925000, 900000}, /* ASV1 */
+	{950000,  925000, 900000, 875000}, /* ASV2 */
+	{950000,  900000, 900000, 875000}, /* ASV3 */
+	{925000,  875000, 875000, 875000}, /* ASV4 */
+	{900000,  850000, 850000, 850000}, /* ASV5 */
+	{900000,  850000, 850000, 850000}, /* ASV6 */
+	{900000,  850000, 850000, 850000}, /* ASV7 */
+	{900000,  850000, 850000, 850000}, /* ASV8 */
+};
+
+/*** Clock Divider Data for Exynos4210 ***/
+static unsigned int exynos4210_clkdiv_dmc0[][8] = {
+	/*
+	 * Clock divider value for following
+	 * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
+	 *		DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
+	 */
+
+	/* DMC L0: 400MHz */
+	{ 3, 1, 1, 1, 1, 1, 3, 1 },
+	/* DMC L1: 266.7MHz */
+	{ 4, 1, 1, 2, 1, 1, 3, 1 },
+	/* DMC L2: 133MHz */
+	{ 5, 1, 1, 5, 1, 1, 3, 1 },
+};
+static unsigned int exynos4210_clkdiv_top[][5] = {
+	/*
+	 * Clock divider value for following
+	 * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
+	 */
+	/* ACLK200 L0: 200MHz */
+	{ 3, 7, 4, 5, 1 },
+	/* ACLK200 L1: 160MHz */
+	{ 4, 7, 5, 6, 1 },
+	/* ACLK200 L2: 133MHz */
+	{ 5, 7, 7, 7, 1 },
+};
+static unsigned int exynos4210_clkdiv_lr_bus[][2] = {
+	/*
+	 * Clock divider value for following
+	 * { DIVGDL/R, DIVGPL/R }
+	 */
+	/* ACLK_GDL/R L1: 200MHz */
+	{ 3, 1 },
+	/* ACLK_GDL/R L2: 160MHz */
+	{ 4, 1 },
+	/* ACLK_GDL/R L3: 133MHz */
+	{ 5, 1 },
+};
+
+/*** Clock Divider Data for Exynos4212/4412 ***/
+static unsigned int exynos4x12_clkdiv_dmc0[][6] = {
+	/*
+	 * Clock divider value for following
+	 * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
+	 *              DIVDMCP}
+	 */
+
+	/* DMC L0: 400MHz */
+	{3, 1, 1, 1, 1, 1},
+	/* DMC L1: 266.7MHz */
+	{4, 1, 1, 2, 1, 1},
+	/* DMC L2: 160MHz */
+	{5, 1, 1, 4, 1, 1},
+	/* DMC L3: 133MHz */
+	{5, 1, 1, 5, 1, 1},
+	/* DMC L4: 100MHz */
+	{7, 1, 1, 7, 1, 1},
+};
+static unsigned int exynos4x12_clkdiv_dmc1[][6] = {
+	/*
+	 * Clock divider value for following
+	 * { G2DACP, DIVC2C, DIVC2C_ACLK }
+	 */
+
+	/* DMC L0: 400MHz */
+	{3, 1, 1},
+	/* DMC L1: 266.7MHz */
+	{4, 2, 1},
+	/* DMC L2: 160MHz */
+	{5, 4, 1},
+	/* DMC L3: 133MHz */
+	{5, 5, 1},
+	/* DMC L4: 100MHz */
+	{7, 7, 1},
+};
+static unsigned int exynos4x12_clkdiv_top[][5] = {
+	/*
+	 * Clock divider value for following
+	 * { DIVACLK266_GPS, DIVACLK100, DIVACLK160,
+		DIVACLK133, DIVONENAND }
+	 */
+
+	/* ACLK_GDL/R L0: 200MHz */
+	{2, 7, 4, 5, 1},
+	/* ACLK_GDL/R L1: 200MHz */
+	{2, 7, 4, 5, 1},
+	/* ACLK_GDL/R L2: 160MHz */
+	{4, 7, 5, 7, 1},
+	/* ACLK_GDL/R L3: 133MHz */
+	{4, 7, 5, 7, 1},
+	/* ACLK_GDL/R L4: 100MHz */
+	{7, 7, 7, 7, 1},
+};
+static unsigned int exynos4x12_clkdiv_lr_bus[][2] = {
+	/*
+	 * Clock divider value for following
+	 * { DIVGDL/R, DIVGPL/R }
+	 */
+
+	/* ACLK_GDL/R L0: 200MHz */
+	{3, 1},
+	/* ACLK_GDL/R L1: 200MHz */
+	{3, 1},
+	/* ACLK_GDL/R L2: 160MHz */
+	{4, 1},
+	/* ACLK_GDL/R L3: 133MHz */
+	{5, 1},
+	/* ACLK_GDL/R L4: 100MHz */
+	{7, 1},
+};
+static unsigned int exynos4x12_clkdiv_sclkip[][3] = {
+	/*
+	 * Clock divider value for following
+	 * { DIVMFC, DIVJPEG, DIVFIMC0~3}
+	 */
+
+	/* SCLK_MFC: 200MHz */
+	{3, 3, 4},
+	/* SCLK_MFC: 200MHz */
+	{3, 3, 4},
+	/* SCLK_MFC: 160MHz */
+	{4, 4, 5},
+	/* SCLK_MFC: 133MHz */
+	{5, 5, 5},
+	/* SCLK_MFC: 100MHz */
+	{7, 7, 7},
+};
+
+
+static int exynos4210_set_busclk(struct busfreq_data *data,
+				 struct busfreq_opp_info *oppi)
+{
+	unsigned int index;
+	unsigned int tmp;
+
+	for (index = LV_0; index < EX4210_LV_NUM; index++)
+		if (oppi->rate == exynos4210_busclk_table[index].clk)
+			break;
+
+	if (index == EX4210_LV_NUM)
+		return -EINVAL;
+
+	/* Change Divider - DMC0 */
+	tmp = data->dmc_divtable[index];
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
+	} while (tmp & 0x11111111);
+
+	/* Change Divider - TOP */
+	tmp = data->top_divtable[index];
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
+	} while (tmp & 0x11111);
+
+	/* Change Divider - LEFTBUS */
+	tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
+
+	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+	tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
+				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+		(exynos4210_clkdiv_lr_bus[index][1] <<
+				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
+	} while (tmp & 0x11);
+
+	/* Change Divider - RIGHTBUS */
+	tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
+
+	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+	tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
+				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+		(exynos4210_clkdiv_lr_bus[index][1] <<
+				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
+	} while (tmp & 0x11);
+
+	return 0;
+}
+
+static int exynos4x12_set_busclk(struct busfreq_data *data,
+				 struct busfreq_opp_info *oppi)
+{
+	unsigned int index;
+	unsigned int tmp;
+
+	for (index = LV_0; index < EX4x12_LV_NUM; index++)
+		if (oppi->rate == exynos4x12_mifclk_table[index].clk)
+			break;
+
+	if (index == EX4x12_LV_NUM)
+		return -EINVAL;
+
+	/* Change Divider - DMC0 */
+	tmp = data->dmc_divtable[index];
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
+	} while (tmp & 0x11111111);
+
+	/* Change Divider - DMC1 */
+	tmp = __raw_readl(EXYNOS4_CLKDIV_DMC1);
+
+	tmp &= ~(EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK |
+		EXYNOS4_CLKDIV_DMC1_C2C_MASK |
+		EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK);
+
+	tmp |= ((exynos4x12_clkdiv_dmc1[index][0] <<
+				EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT) |
+		(exynos4x12_clkdiv_dmc1[index][1] <<
+				EXYNOS4_CLKDIV_DMC1_C2C_SHIFT) |
+		(exynos4x12_clkdiv_dmc1[index][2] <<
+				EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT));
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_DMC1);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC1);
+	} while (tmp & 0x111111);
+
+	/* Change Divider - TOP */
+	tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
+
+	tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK |
+		EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
+		EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
+		EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
+		EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
+
+	tmp |= ((exynos4x12_clkdiv_top[index][0] <<
+				EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT) |
+		(exynos4x12_clkdiv_top[index][1] <<
+				EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
+		(exynos4x12_clkdiv_top[index][2] <<
+				EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
+		(exynos4x12_clkdiv_top[index][3] <<
+				EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
+		(exynos4x12_clkdiv_top[index][4] <<
+				EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
+	} while (tmp & 0x11111);
+
+	/* Change Divider - LEFTBUS */
+	tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
+
+	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+	tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
+				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+		(exynos4x12_clkdiv_lr_bus[index][1] <<
+				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
+	} while (tmp & 0x11);
+
+	/* Change Divider - RIGHTBUS */
+	tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
+
+	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+	tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
+				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+		(exynos4x12_clkdiv_lr_bus[index][1] <<
+				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
+	} while (tmp & 0x11);
+
+	/* Change Divider - MFC */
+	tmp = __raw_readl(EXYNOS4_CLKDIV_MFC);
+
+	tmp &= ~(EXYNOS4_CLKDIV_MFC_MASK);
+
+	tmp |= ((exynos4x12_clkdiv_sclkip[index][0] <<
+				EXYNOS4_CLKDIV_MFC_SHIFT));
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_MFC);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_MFC);
+	} while (tmp & 0x1);
+
+	/* Change Divider - JPEG */
+	tmp = __raw_readl(EXYNOS4_CLKDIV_CAM1);
+
+	tmp &= ~(EXYNOS4_CLKDIV_CAM1_JPEG_MASK);
+
+	tmp |= ((exynos4x12_clkdiv_sclkip[index][1] <<
+				EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT));
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_CAM1);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
+	} while (tmp & 0x1);
+
+	/* Change Divider - FIMC0~3 */
+	tmp = __raw_readl(EXYNOS4_CLKDIV_CAM);
+
+	tmp &= ~(EXYNOS4_CLKDIV_CAM_FIMC0_MASK | EXYNOS4_CLKDIV_CAM_FIMC1_MASK |
+		EXYNOS4_CLKDIV_CAM_FIMC2_MASK | EXYNOS4_CLKDIV_CAM_FIMC3_MASK);
+
+	tmp |= ((exynos4x12_clkdiv_sclkip[index][2] <<
+				EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT) |
+		(exynos4x12_clkdiv_sclkip[index][2] <<
+				EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT) |
+		(exynos4x12_clkdiv_sclkip[index][2] <<
+				EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT) |
+		(exynos4x12_clkdiv_sclkip[index][2] <<
+				EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT));
+
+	__raw_writel(tmp, EXYNOS4_CLKDIV_CAM);
+
+	do {
+		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
+	} while (tmp & 0x1111);
+
+	return 0;
+}
+
+
+static void busfreq_mon_reset(struct busfreq_data *data)
+{
+	unsigned int i;
+
+	for (i = 0; i < 2; i++) {
+		void __iomem *ppmu_base = data->dmc[i].hw_base;
+
+		/* Reset PPMU */
+		__raw_writel(0x8000000f, ppmu_base + 0xf010);
+		__raw_writel(0x8000000f, ppmu_base + 0xf050);
+		__raw_writel(0x6, ppmu_base + 0xf000);
+		__raw_writel(0x0, ppmu_base + 0xf100);
+
+		/* Set PPMU Event */
+		data->dmc[i].event = 0x6;
+		__raw_writel(((data->dmc[i].event << 12) | 0x1),
+			     ppmu_base + 0xfc);
+
+		/* Start PPMU */
+		__raw_writel(0x1, ppmu_base + 0xf000);
+	}
+}
+
+static void exynos4_read_ppmu(struct busfreq_data *data)
+{
+	int i, j;
+
+	for (i = 0; i < 2; i++) {
+		void __iomem *ppmu_base = data->dmc[i].hw_base;
+		u32 overflow;
+
+		/* Stop PPMU */
+		__raw_writel(0x0, ppmu_base + 0xf000);
+
+		/* Update local data from PPMU */
+		overflow = __raw_readl(ppmu_base + 0xf050);
+
+		data->dmc[i].ccnt = __raw_readl(ppmu_base + 0xf100);
+		data->dmc[i].ccnt_overflow = overflow & (1 << 31);
+
+		for (j = 0; j < PPMU_PMNCNT_MAX; j++) {
+			data->dmc[i].count[j] = __raw_readl(
+					ppmu_base + (0xf110 + (0x10 * j)));
+			data->dmc[i].count_overflow[j] = overflow & (1 << j);
+		}
+	}
+
+	busfreq_mon_reset(data);
+}
+
+static int exynos4x12_get_intspec(unsigned long mifclk)
+{
+	int i = 0;
+
+	while (exynos4x12_intclk_table[i].clk) {
+		if (exynos4x12_intclk_table[i].clk <= mifclk)
+			return i;
+		i++;
+	}
+
+	return -EINVAL;
+}
+
+static int exynos4_bus_setvolt(struct busfreq_data *data,
+			       struct busfreq_opp_info *oppi,
+			       struct busfreq_opp_info *oldoppi)
+{
+	int err = 0, tmp;
+	unsigned long volt = oppi->volt;
+
+	switch (data->type) {
+	case TYPE_BUSF_EXYNOS4210:
+		/* OPP represents DMC clock + INT voltage */
+		err = regulator_set_voltage(data->vdd_int, volt,
+					    MAX_SAFEVOLT);
+		break;
+	case TYPE_BUSF_EXYNOS4x12:
+		/* OPP represents MIF clock + MIF voltage */
+		err = regulator_set_voltage(data->vdd_mif, volt,
+					    MAX_SAFEVOLT);
+		if (err)
+			break;
+
+		tmp = exynos4x12_get_intspec(oppi->rate);
+		if (tmp < 0) {
+			err = tmp;
+			regulator_set_voltage(data->vdd_mif,
+					      oldoppi->volt,
+					      MAX_SAFEVOLT);
+			break;
+		}
+		err = regulator_set_voltage(data->vdd_int,
+					    exynos4x12_intclk_table[tmp].volt,
+					    MAX_SAFEVOLT);
+		/*  Try to recover */
+		if (err)
+			regulator_set_voltage(data->vdd_mif,
+					      oldoppi->volt,
+					      MAX_SAFEVOLT);
+		break;
+	default:
+		err = -EINVAL;
+	}
+
+	return err;
+}
+
+static int exynos4_bus_target(struct device *dev, unsigned long *_freq,
+			      u32 flags)
+{
+	int err = 0;
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data *data = platform_get_drvdata(pdev);
+	struct opp *opp;
+	unsigned long freq;
+	unsigned long old_freq = data->curr_oppinfo.rate;
+	struct busfreq_opp_info	new_oppinfo;
+
+	rcu_read_lock();
+	opp = devfreq_recommended_opp(dev, _freq, flags);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		return PTR_ERR(opp);
+	}
+	new_oppinfo.rate = opp_get_freq(opp);
+	new_oppinfo.volt = opp_get_voltage(opp);
+	rcu_read_unlock();
+	freq = new_oppinfo.rate;
+
+	if (old_freq == freq)
+		return 0;
+
+	dev_dbg(dev, "targeting %lukHz %luuV\n", freq, new_oppinfo.volt);
+
+	mutex_lock(&data->lock);
+
+	if (data->disabled)
+		goto out;
+
+	if (old_freq < freq)
+		err = exynos4_bus_setvolt(data, &new_oppinfo,
+					  &data->curr_oppinfo);
+	if (err)
+		goto out;
+
+	if (old_freq != freq) {
+		switch (data->type) {
+		case TYPE_BUSF_EXYNOS4210:
+			err = exynos4210_set_busclk(data, &new_oppinfo);
+			break;
+		case TYPE_BUSF_EXYNOS4x12:
+			err = exynos4x12_set_busclk(data, &new_oppinfo);
+			break;
+		default:
+			err = -EINVAL;
+		}
+	}
+	if (err)
+		goto out;
+
+	if (old_freq > freq)
+		err = exynos4_bus_setvolt(data, &new_oppinfo,
+					  &data->curr_oppinfo);
+	if (err)
+		goto out;
+
+	data->curr_oppinfo = new_oppinfo;
+out:
+	mutex_unlock(&data->lock);
+	return err;
+}
+
+static int exynos4_get_busier_dmc(struct busfreq_data *data)
+{
+	u64 p0 = data->dmc[0].count[0];
+	u64 p1 = data->dmc[1].count[0];
+
+	p0 *= data->dmc[1].ccnt;
+	p1 *= data->dmc[0].ccnt;
+
+	if (data->dmc[1].ccnt == 0)
+		return 0;
+
+	if (p0 > p1)
+		return 0;
+	return 1;
+}
+
+static int exynos4_bus_get_dev_status(struct device *dev,
+				      struct devfreq_dev_status *stat)
+{
+	struct busfreq_data *data = dev_get_drvdata(dev);
+	int busier_dmc;
+	int cycles_x2 = 2; /* 2 x cycles */
+	void __iomem *addr;
+	u32 timing;
+	u32 memctrl;
+
+	exynos4_read_ppmu(data);
+	busier_dmc = exynos4_get_busier_dmc(data);
+	stat->current_frequency = data->curr_oppinfo.rate;
+
+	if (busier_dmc)
+		addr = S5P_VA_DMC1;
+	else
+		addr = S5P_VA_DMC0;
+
+	memctrl = __raw_readl(addr + 0x04); /* one of DDR2/3/LPDDR2 */
+	timing = __raw_readl(addr + 0x38); /* CL or WL/RL values */
+
+	switch ((memctrl >> 8) & 0xf) {
+	case 0x4: /* DDR2 */
+		cycles_x2 = ((timing >> 16) & 0xf) * 2;
+		break;
+	case 0x5: /* LPDDR2 */
+	case 0x6: /* DDR3 */
+		cycles_x2 = ((timing >> 8) & 0xf) + ((timing >> 0) & 0xf);
+		break;
+	default:
+		pr_err("%s: Unknown Memory Type(%d).\n", __func__,
+		       (memctrl >> 8) & 0xf);
+		return -EINVAL;
+	}
+
+	/* Number of cycles spent on memory access */
+	stat->busy_time = data->dmc[busier_dmc].count[0] / 2 * (cycles_x2 + 2);
+	stat->busy_time *= 100 / BUS_SATURATION_RATIO;
+	stat->total_time = data->dmc[busier_dmc].ccnt;
+
+	/* If the counters have overflown, retry */
+	if (data->dmc[busier_dmc].ccnt_overflow ||
+	    data->dmc[busier_dmc].count_overflow[0])
+		return -EAGAIN;
+
+	return 0;
+}
+
+static void exynos4_bus_exit(struct device *dev)
+{
+	struct busfreq_data *data = dev_get_drvdata(dev);
+
+	devfreq_unregister_opp_notifier(dev, data->devfreq);
+}
+
+static struct devfreq_dev_profile exynos4_devfreq_profile = {
+	.initial_freq	= 400000,
+	.polling_ms	= 50,
+	.target		= exynos4_bus_target,
+	.get_dev_status	= exynos4_bus_get_dev_status,
+	.exit		= exynos4_bus_exit,
+};
+
+static int exynos4210_init_tables(struct busfreq_data *data)
+{
+	u32 tmp;
+	int mgrp;
+	int i, err = 0;
+
+	tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
+	for (i = LV_0; i < EX4210_LV_NUM; i++) {
+		tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
+			EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
+			EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
+			EXYNOS4_CLKDIV_DMC0_DMC_MASK |
+			EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
+			EXYNOS4_CLKDIV_DMC0_DMCP_MASK |
+			EXYNOS4_CLKDIV_DMC0_COPY2_MASK |
+			EXYNOS4_CLKDIV_DMC0_CORETI_MASK);
+
+		tmp |= ((exynos4210_clkdiv_dmc0[i][0] <<
+					EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
+			(exynos4210_clkdiv_dmc0[i][1] <<
+					EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
+			(exynos4210_clkdiv_dmc0[i][2] <<
+					EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
+			(exynos4210_clkdiv_dmc0[i][3] <<
+					EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
+			(exynos4210_clkdiv_dmc0[i][4] <<
+					EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
+			(exynos4210_clkdiv_dmc0[i][5] <<
+					EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) |
+			(exynos4210_clkdiv_dmc0[i][6] <<
+					EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) |
+			(exynos4210_clkdiv_dmc0[i][7] <<
+					EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT));
+
+		data->dmc_divtable[i] = tmp;
+	}
+
+	tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
+	for (i = LV_0; i <  EX4210_LV_NUM; i++) {
+		tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK200_MASK |
+			EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
+			EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
+			EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
+			EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
+
+		tmp |= ((exynos4210_clkdiv_top[i][0] <<
+					EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) |
+			(exynos4210_clkdiv_top[i][1] <<
+					EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
+			(exynos4210_clkdiv_top[i][2] <<
+					EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
+			(exynos4210_clkdiv_top[i][3] <<
+					EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
+			(exynos4210_clkdiv_top[i][4] <<
+					EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
+
+		data->top_divtable[i] = tmp;
+	}
+
+#ifdef CONFIG_EXYNOS_ASV
+	tmp = exynos4_result_of_asv;
+#else
+	tmp = 0; /* Max voltages for the reliability of the unknown */
+#endif
+
+	pr_debug("ASV Group of Exynos4 is %d\n", tmp);
+	/* Use merged grouping for voltage */
+	switch (tmp) {
+	case 0:
+		mgrp = 0;
+		break;
+	case 1:
+	case 2:
+		mgrp = 1;
+		break;
+	case 3:
+	case 4:
+		mgrp = 2;
+		break;
+	case 5:
+	case 6:
+		mgrp = 3;
+		break;
+	case 7:
+		mgrp = 4;
+		break;
+	default:
+		pr_warn("Unknown ASV Group. Use max voltage.\n");
+		mgrp = 0;
+	}
+
+	for (i = LV_0; i < EX4210_LV_NUM; i++)
+		exynos4210_busclk_table[i].volt = exynos4210_asv_volt[mgrp][i];
+
+	for (i = LV_0; i < EX4210_LV_NUM; i++) {
+		err = opp_add(data->dev, exynos4210_busclk_table[i].clk,
+			      exynos4210_busclk_table[i].volt);
+		if (err) {
+			dev_err(data->dev, "Cannot add opp entries.\n");
+			return err;
+		}
+	}
+
+
+	return 0;
+}
+
+static int exynos4x12_init_tables(struct busfreq_data *data)
+{
+	unsigned int i;
+	unsigned int tmp;
+	int ret;
+
+	/* Enable pause function for DREX2 DVFS */
+	tmp = __raw_readl(EXYNOS4_DMC_PAUSE_CTRL);
+	tmp |= EXYNOS4_DMC_PAUSE_ENABLE;
+	__raw_writel(tmp, EXYNOS4_DMC_PAUSE_CTRL);
+
+	tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
+
+	for (i = 0; i <  EX4x12_LV_NUM; i++) {
+		tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
+			EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
+			EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
+			EXYNOS4_CLKDIV_DMC0_DMC_MASK |
+			EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
+			EXYNOS4_CLKDIV_DMC0_DMCP_MASK);
+
+		tmp |= ((exynos4x12_clkdiv_dmc0[i][0] <<
+					EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
+			(exynos4x12_clkdiv_dmc0[i][1] <<
+					EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
+			(exynos4x12_clkdiv_dmc0[i][2] <<
+					EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
+			(exynos4x12_clkdiv_dmc0[i][3] <<
+					EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
+			(exynos4x12_clkdiv_dmc0[i][4] <<
+					EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
+			(exynos4x12_clkdiv_dmc0[i][5] <<
+					EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT));
+
+		data->dmc_divtable[i] = tmp;
+	}
+
+#ifdef CONFIG_EXYNOS_ASV
+	tmp = exynos4_result_of_asv;
+#else
+	tmp = 0; /* Max voltages for the reliability of the unknown */
+#endif
+
+	if (tmp > 8)
+		tmp = 0;
+	pr_debug("ASV Group of Exynos4x12 is %d\n", tmp);
+
+	for (i = 0; i < EX4x12_LV_NUM; i++) {
+		exynos4x12_mifclk_table[i].volt =
+			exynos4x12_mif_step_50[tmp][i];
+		exynos4x12_intclk_table[i].volt =
+			exynos4x12_int_volt[tmp][i];
+	}
+
+	for (i = 0; i < EX4x12_LV_NUM; i++) {
+		ret = opp_add(data->dev, exynos4x12_mifclk_table[i].clk,
+			      exynos4x12_mifclk_table[i].volt);
+		if (ret) {
+			dev_err(data->dev, "Fail to add opp entries.\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,
+		unsigned long event, void *ptr)
+{
+	struct busfreq_data *data = container_of(this, struct busfreq_data,
+						 pm_notifier);
+	struct opp *opp;
+	struct busfreq_opp_info	new_oppinfo;
+	unsigned long maxfreq = ULONG_MAX;
+	int err = 0;
+
+	switch (event) {
+	case PM_SUSPEND_PREPARE:
+		/* Set Fastest and Deactivate DVFS */
+		mutex_lock(&data->lock);
+
+		data->disabled = true;
+
+		rcu_read_lock();
+		opp = opp_find_freq_floor(data->dev, &maxfreq);
+		if (IS_ERR(opp)) {
+			rcu_read_unlock();
+			dev_err(data->dev, "%s: unable to find a min freq\n",
+				__func__);
+			mutex_unlock(&data->lock);
+			return PTR_ERR(opp);
+		}
+		new_oppinfo.rate = opp_get_freq(opp);
+		new_oppinfo.volt = opp_get_voltage(opp);
+		rcu_read_unlock();
+
+		err = exynos4_bus_setvolt(data, &new_oppinfo,
+					  &data->curr_oppinfo);
+		if (err)
+			goto unlock;
+
+		switch (data->type) {
+		case TYPE_BUSF_EXYNOS4210:
+			err = exynos4210_set_busclk(data, &new_oppinfo);
+			break;
+		case TYPE_BUSF_EXYNOS4x12:
+			err = exynos4x12_set_busclk(data, &new_oppinfo);
+			break;
+		default:
+			err = -EINVAL;
+		}
+		if (err)
+			goto unlock;
+
+		data->curr_oppinfo = new_oppinfo;
+unlock:
+		mutex_unlock(&data->lock);
+		if (err)
+			return err;
+		return NOTIFY_OK;
+	case PM_POST_RESTORE:
+	case PM_POST_SUSPEND:
+		/* Reactivate */
+		mutex_lock(&data->lock);
+		data->disabled = false;
+		mutex_unlock(&data->lock);
+		return NOTIFY_OK;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int exynos4_busfreq_probe(struct platform_device *pdev)
+{
+	struct busfreq_data *data;
+	struct opp *opp;
+	struct device *dev = &pdev->dev;
+	int err = 0;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data), GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(dev, "Cannot allocate memory.\n");
+		return -ENOMEM;
+	}
+
+	data->type = pdev->id_entry->driver_data;
+	data->dmc[0].hw_base = S5P_VA_DMC0;
+	data->dmc[1].hw_base = S5P_VA_DMC1;
+	data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event;
+	data->dev = dev;
+	mutex_init(&data->lock);
+
+	switch (data->type) {
+	case TYPE_BUSF_EXYNOS4210:
+		err = exynos4210_init_tables(data);
+		break;
+	case TYPE_BUSF_EXYNOS4x12:
+		err = exynos4x12_init_tables(data);
+		break;
+	default:
+		dev_err(dev, "Cannot determine the device id %d\n", data->type);
+		err = -EINVAL;
+	}
+	if (err)
+		return err;
+
+	data->vdd_int = devm_regulator_get(dev, "vdd_int");
+	if (IS_ERR(data->vdd_int)) {
+		dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
+		return PTR_ERR(data->vdd_int);
+	}
+	if (data->type == TYPE_BUSF_EXYNOS4x12) {
+		data->vdd_mif = devm_regulator_get(dev, "vdd_mif");
+		if (IS_ERR(data->vdd_mif)) {
+			dev_err(dev, "Cannot get the regulator \"vdd_mif\"\n");
+			return PTR_ERR(data->vdd_mif);
+		}
+	}
+
+	rcu_read_lock();
+	opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		dev_err(dev, "Invalid initial frequency %lu kHz.\n",
+			exynos4_devfreq_profile.initial_freq);
+		return PTR_ERR(opp);
+	}
+	data->curr_oppinfo.rate = opp_get_freq(opp);
+	data->curr_oppinfo.volt = opp_get_voltage(opp);
+	rcu_read_unlock();
+
+	platform_set_drvdata(pdev, data);
+
+	busfreq_mon_reset(data);
+
+	data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile,
+					   "simple_ondemand", NULL);
+	if (IS_ERR(data->devfreq))
+		return PTR_ERR(data->devfreq);
+
+	devfreq_register_opp_notifier(dev, data->devfreq);
+
+	err = register_pm_notifier(&data->pm_notifier);
+	if (err) {
+		dev_err(dev, "Failed to setup pm notifier\n");
+		devfreq_remove_device(data->devfreq);
+		return err;
+	}
+
+	return 0;
+}
+
+static int exynos4_busfreq_remove(struct platform_device *pdev)
+{
+	struct busfreq_data *data = platform_get_drvdata(pdev);
+
+	unregister_pm_notifier(&data->pm_notifier);
+	devfreq_remove_device(data->devfreq);
+
+	return 0;
+}
+
+static int exynos4_busfreq_resume(struct device *dev)
+{
+	struct busfreq_data *data = dev_get_drvdata(dev);
+
+	busfreq_mon_reset(data);
+	return 0;
+}
+
+static const struct dev_pm_ops exynos4_busfreq_pm = {
+	.resume	= exynos4_busfreq_resume,
+};
+
+static const struct platform_device_id exynos4_busfreq_id[] = {
+	{ "exynos4210-busfreq", TYPE_BUSF_EXYNOS4210 },
+	{ "exynos4412-busfreq", TYPE_BUSF_EXYNOS4x12 },
+	{ "exynos4212-busfreq", TYPE_BUSF_EXYNOS4x12 },
+	{ },
+};
+
+static struct platform_driver exynos4_busfreq_driver = {
+	.probe	= exynos4_busfreq_probe,
+	.remove	= exynos4_busfreq_remove,
+	.id_table = exynos4_busfreq_id,
+	.driver = {
+		.name	= "exynos4-busfreq",
+		.owner	= THIS_MODULE,
+		.pm	= &exynos4_busfreq_pm,
+	},
+};
+
+static int __init exynos4_busfreq_init(void)
+{
+	return platform_driver_register(&exynos4_busfreq_driver);
+}
+late_initcall(exynos4_busfreq_init);
+
+static void __exit exynos4_busfreq_exit(void)
+{
+	platform_driver_unregister(&exynos4_busfreq_driver);
+}
+module_exit(exynos4_busfreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EXYNOS4 busfreq driver with devfreq framework");
+MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/devfreq/exynos/exynos5_bus.c linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/exynos5_bus.c
--- linux-libre-3.10-gnu/drivers/devfreq/exynos/exynos5_bus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/exynos5_bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * EXYNOS5 INT clock frequency scaling support using DEVFREQ framework
+ * Based on work done by Jonghwan Choi <jhbird.choi@samsung.com>
+ * Support for only EXYNOS5250 is present.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/devfreq.h>
+#include <linux/io.h>
+#include <linux/opp.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <linux/opp.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#include "exynos_ppmu.h"
+
+#define MAX_SAFEVOLT			1100000 /* 1.10V */
+/* Assume that the bus is saturated if the utilization is 25% */
+#define INT_BUS_SATURATION_RATIO	25
+
+enum int_level_idx {
+	LV_0,
+	LV_1,
+	LV_2,
+	LV_3,
+	LV_4,
+	_LV_END
+};
+
+enum exynos_ppmu_list {
+	PPMU_RIGHT,
+	PPMU_END,
+};
+
+struct busfreq_data_int {
+	struct device *dev;
+	struct devfreq *devfreq;
+	struct regulator *vdd_int;
+	struct exynos_ppmu ppmu[PPMU_END];
+	unsigned long curr_freq;
+	bool disabled;
+
+	struct notifier_block pm_notifier;
+	struct mutex lock;
+	struct pm_qos_request int_req;
+	struct clk *int_clk;
+};
+
+struct int_bus_opp_table {
+	unsigned int idx;
+	unsigned long clk;
+	unsigned long volt;
+};
+
+static struct int_bus_opp_table exynos5_int_opp_table[] = {
+	{LV_0, 266000, 1025000},
+	{LV_1, 200000, 1025000},
+	{LV_2, 160000, 1025000},
+	{LV_3, 133000, 1025000},
+	{LV_4, 100000, 1025000},
+	{0, 0, 0},
+};
+
+static void busfreq_mon_reset(struct busfreq_data_int *data)
+{
+	unsigned int i;
+
+	for (i = PPMU_RIGHT; i < PPMU_END; i++) {
+		void __iomem *ppmu_base = data->ppmu[i].hw_base;
+
+		/* Reset the performance and cycle counters */
+		exynos_ppmu_reset(ppmu_base);
+
+		/* Setup count registers to monitor read/write transactions */
+		data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
+		exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
+					data->ppmu[i].event[PPMU_PMNCNT3]);
+
+		exynos_ppmu_start(ppmu_base);
+	}
+}
+
+static void exynos5_read_ppmu(struct busfreq_data_int *data)
+{
+	int i, j;
+
+	for (i = PPMU_RIGHT; i < PPMU_END; i++) {
+		void __iomem *ppmu_base = data->ppmu[i].hw_base;
+
+		exynos_ppmu_stop(ppmu_base);
+
+		/* Update local data from PPMU */
+		data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
+
+		for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
+			if (data->ppmu[i].event[j] == 0)
+				data->ppmu[i].count[j] = 0;
+			else
+				data->ppmu[i].count[j] =
+					exynos_ppmu_read(ppmu_base, j);
+		}
+	}
+
+	busfreq_mon_reset(data);
+}
+
+static int exynos5_int_setvolt(struct busfreq_data_int *data,
+				unsigned long volt)
+{
+	return regulator_set_voltage(data->vdd_int, volt, MAX_SAFEVOLT);
+}
+
+static int exynos5_busfreq_int_target(struct device *dev, unsigned long *_freq,
+			      u32 flags)
+{
+	int err = 0;
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+	struct opp *opp;
+	unsigned long old_freq, freq;
+	unsigned long volt;
+
+	rcu_read_lock();
+	opp = devfreq_recommended_opp(dev, _freq, flags);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		dev_err(dev, "%s: Invalid OPP.\n", __func__);
+		return PTR_ERR(opp);
+	}
+
+	freq = opp_get_freq(opp);
+	volt = opp_get_voltage(opp);
+	rcu_read_unlock();
+
+	old_freq = data->curr_freq;
+
+	if (old_freq == freq)
+		return 0;
+
+	dev_dbg(dev, "targetting %lukHz %luuV\n", freq, volt);
+
+	mutex_lock(&data->lock);
+
+	if (data->disabled)
+		goto out;
+
+	if (freq > exynos5_int_opp_table[0].clk)
+		pm_qos_update_request(&data->int_req, freq * 16 / 1000);
+	else
+		pm_qos_update_request(&data->int_req, -1);
+
+	if (old_freq < freq)
+		err = exynos5_int_setvolt(data, volt);
+	if (err)
+		goto out;
+
+	err = clk_set_rate(data->int_clk, freq * 1000);
+
+	if (err)
+		goto out;
+
+	if (old_freq > freq)
+		err = exynos5_int_setvolt(data, volt);
+	if (err)
+		goto out;
+
+	data->curr_freq = freq;
+out:
+	mutex_unlock(&data->lock);
+	return err;
+}
+
+static int exynos5_get_busier_dmc(struct busfreq_data_int *data)
+{
+	int i, j;
+	int busy = 0;
+	unsigned int temp = 0;
+
+	for (i = PPMU_RIGHT; i < PPMU_END; i++) {
+		for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
+			if (data->ppmu[i].count[j] > temp) {
+				temp = data->ppmu[i].count[j];
+				busy = i;
+			}
+		}
+	}
+
+	return busy;
+}
+
+static int exynos5_int_get_dev_status(struct device *dev,
+				      struct devfreq_dev_status *stat)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+	int busier_dmc;
+
+	exynos5_read_ppmu(data);
+	busier_dmc = exynos5_get_busier_dmc(data);
+
+	stat->current_frequency = data->curr_freq;
+
+	/* Number of cycles spent on memory access */
+	stat->busy_time = data->ppmu[busier_dmc].count[PPMU_PMNCNT3];
+	stat->busy_time *= 100 / INT_BUS_SATURATION_RATIO;
+	stat->total_time = data->ppmu[busier_dmc].ccnt;
+
+	return 0;
+}
+static void exynos5_int_exit(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+	devfreq_unregister_opp_notifier(dev, data->devfreq);
+}
+
+static struct devfreq_dev_profile exynos5_devfreq_int_profile = {
+	.initial_freq		= 160000,
+	.polling_ms		= 100,
+	.target			= exynos5_busfreq_int_target,
+	.get_dev_status		= exynos5_int_get_dev_status,
+	.exit			= exynos5_int_exit,
+};
+
+static int exynos5250_init_int_tables(struct busfreq_data_int *data)
+{
+	int i, err = 0;
+
+	for (i = LV_0; i < _LV_END; i++) {
+		err = opp_add(data->dev, exynos5_int_opp_table[i].clk,
+				exynos5_int_opp_table[i].volt);
+		if (err) {
+			dev_err(data->dev, "Cannot add opp entries.\n");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static int exynos5_busfreq_int_pm_notifier_event(struct notifier_block *this,
+		unsigned long event, void *ptr)
+{
+	struct busfreq_data_int *data = container_of(this,
+					struct busfreq_data_int, pm_notifier);
+	struct opp *opp;
+	unsigned long maxfreq = ULONG_MAX;
+	unsigned long freq;
+	unsigned long volt;
+	int err = 0;
+
+	switch (event) {
+	case PM_SUSPEND_PREPARE:
+		/* Set Fastest and Deactivate DVFS */
+		mutex_lock(&data->lock);
+
+		data->disabled = true;
+
+		rcu_read_lock();
+		opp = opp_find_freq_floor(data->dev, &maxfreq);
+		if (IS_ERR(opp)) {
+			rcu_read_unlock();
+			err = PTR_ERR(opp);
+			goto unlock;
+		}
+		freq = opp_get_freq(opp);
+		volt = opp_get_voltage(opp);
+		rcu_read_unlock();
+
+		err = exynos5_int_setvolt(data, volt);
+		if (err)
+			goto unlock;
+
+		err = clk_set_rate(data->int_clk, freq * 1000);
+
+		if (err)
+			goto unlock;
+
+		data->curr_freq = freq;
+unlock:
+		mutex_unlock(&data->lock);
+		if (err)
+			return NOTIFY_BAD;
+		return NOTIFY_OK;
+	case PM_POST_RESTORE:
+	case PM_POST_SUSPEND:
+		/* Reactivate */
+		mutex_lock(&data->lock);
+		data->disabled = false;
+		mutex_unlock(&data->lock);
+		return NOTIFY_OK;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int exynos5_busfreq_int_probe(struct platform_device *pdev)
+{
+	struct busfreq_data_int *data;
+	struct opp *opp;
+	struct device *dev = &pdev->dev;
+	struct device_node *np;
+	unsigned long initial_freq;
+	unsigned long initial_volt;
+	int err = 0;
+	int i;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data_int),
+				GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(dev, "Cannot allocate memory.\n");
+		return -ENOMEM;
+	}
+
+	np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-ppmu");
+	if (np == NULL) {
+		pr_err("Unable to find PPMU node\n");
+		return -ENOENT;
+	}
+
+	for (i = PPMU_RIGHT; i < PPMU_END; i++) {
+		/* map PPMU memory region */
+		data->ppmu[i].hw_base = of_iomap(np, i);
+		if (data->ppmu[i].hw_base == NULL) {
+			dev_err(&pdev->dev, "failed to map memory region\n");
+			return -ENOMEM;
+		}
+	}
+	data->pm_notifier.notifier_call = exynos5_busfreq_int_pm_notifier_event;
+	data->dev = dev;
+	mutex_init(&data->lock);
+
+	err = exynos5250_init_int_tables(data);
+	if (err)
+		goto err_regulator;
+
+	data->vdd_int = regulator_get(dev, "vdd_int");
+	if (IS_ERR(data->vdd_int)) {
+		dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
+		err = PTR_ERR(data->vdd_int);
+		goto err_regulator;
+	}
+
+	data->int_clk = clk_get(dev, "int_clk");
+	if (IS_ERR(data->int_clk)) {
+		dev_err(dev, "Cannot get clock \"int_clk\"\n");
+		err = PTR_ERR(data->int_clk);
+		goto err_clock;
+	}
+
+	rcu_read_lock();
+	opp = opp_find_freq_floor(dev,
+			&exynos5_devfreq_int_profile.initial_freq);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		dev_err(dev, "Invalid initial frequency %lu kHz.\n",
+		       exynos5_devfreq_int_profile.initial_freq);
+		err = PTR_ERR(opp);
+		goto err_opp_add;
+	}
+	initial_freq = opp_get_freq(opp);
+	initial_volt = opp_get_voltage(opp);
+	rcu_read_unlock();
+	data->curr_freq = initial_freq;
+
+	err = clk_set_rate(data->int_clk, initial_freq * 1000);
+	if (err) {
+		dev_err(dev, "Failed to set initial frequency\n");
+		goto err_opp_add;
+	}
+
+	err = exynos5_int_setvolt(data, initial_volt);
+	if (err)
+		goto err_opp_add;
+
+	platform_set_drvdata(pdev, data);
+
+	busfreq_mon_reset(data);
+
+	data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile,
+					   "simple_ondemand", NULL);
+
+	if (IS_ERR(data->devfreq)) {
+		err = PTR_ERR(data->devfreq);
+		goto err_devfreq_add;
+	}
+
+	devfreq_register_opp_notifier(dev, data->devfreq);
+
+	err = register_pm_notifier(&data->pm_notifier);
+	if (err) {
+		dev_err(dev, "Failed to setup pm notifier\n");
+		goto err_devfreq_add;
+	}
+
+	/* TODO: Add a new QOS class for int/mif bus */
+	pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1);
+
+	return 0;
+
+err_devfreq_add:
+	devfreq_remove_device(data->devfreq);
+	platform_set_drvdata(pdev, NULL);
+err_opp_add:
+	clk_put(data->int_clk);
+err_clock:
+	regulator_put(data->vdd_int);
+err_regulator:
+	return err;
+}
+
+static int exynos5_busfreq_int_remove(struct platform_device *pdev)
+{
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+	pm_qos_remove_request(&data->int_req);
+	unregister_pm_notifier(&data->pm_notifier);
+	devfreq_remove_device(data->devfreq);
+	regulator_put(data->vdd_int);
+	clk_put(data->int_clk);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static int exynos5_busfreq_int_resume(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+	busfreq_mon_reset(data);
+	return 0;
+}
+
+static const struct dev_pm_ops exynos5_busfreq_int_pm = {
+	.resume	= exynos5_busfreq_int_resume,
+};
+
+/* platform device pointer for exynos5 devfreq device. */
+static struct platform_device *exynos5_devfreq_pdev;
+
+static struct platform_driver exynos5_busfreq_int_driver = {
+	.probe		= exynos5_busfreq_int_probe,
+	.remove		= exynos5_busfreq_int_remove,
+	.driver		= {
+		.name		= "exynos5-bus-int",
+		.owner		= THIS_MODULE,
+		.pm		= &exynos5_busfreq_int_pm,
+	},
+};
+
+static int __init exynos5_busfreq_int_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&exynos5_busfreq_int_driver);
+	if (ret < 0)
+		goto out;
+
+	exynos5_devfreq_pdev =
+		platform_device_register_simple("exynos5-bus-int", -1, NULL, 0);
+	if (IS_ERR_OR_NULL(exynos5_devfreq_pdev)) {
+		ret = PTR_ERR(exynos5_devfreq_pdev);
+		goto out1;
+	}
+
+	return 0;
+out1:
+	platform_driver_unregister(&exynos5_busfreq_int_driver);
+out:
+	return ret;
+}
+late_initcall(exynos5_busfreq_int_init);
+
+static void __exit exynos5_busfreq_int_exit(void)
+{
+	platform_device_unregister(exynos5_devfreq_pdev);
+	platform_driver_unregister(&exynos5_busfreq_int_driver);
+}
+module_exit(exynos5_busfreq_int_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EXYNOS5 busfreq driver with devfreq framework");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/devfreq/exynos/exynos_ppmu.c linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/exynos_ppmu.c
--- linux-libre-3.10-gnu/drivers/devfreq/exynos/exynos_ppmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/exynos_ppmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * EXYNOS - PPMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+#include "exynos_ppmu.h"
+
+void exynos_ppmu_reset(void __iomem *ppmu_base)
+{
+	__raw_writel(PPMU_CYCLE_RESET | PPMU_COUNTER_RESET, ppmu_base);
+	__raw_writel(PPMU_ENABLE_CYCLE  |
+		     PPMU_ENABLE_COUNT0 |
+		     PPMU_ENABLE_COUNT1 |
+		     PPMU_ENABLE_COUNT2 |
+		     PPMU_ENABLE_COUNT3,
+		     ppmu_base + PPMU_CNTENS);
+}
+
+void exynos_ppmu_setevent(void __iomem *ppmu_base, unsigned int ch,
+			unsigned int evt)
+{
+	__raw_writel(evt, ppmu_base + PPMU_BEVTSEL(ch));
+}
+
+void exynos_ppmu_start(void __iomem *ppmu_base)
+{
+	__raw_writel(PPMU_ENABLE, ppmu_base);
+}
+
+void exynos_ppmu_stop(void __iomem *ppmu_base)
+{
+	__raw_writel(PPMU_DISABLE, ppmu_base);
+}
+
+unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch)
+{
+	unsigned int total;
+
+	if (ch == PPMU_PMNCNT3)
+		total = ((__raw_readl(ppmu_base + PMCNT_OFFSET(ch)) << 8) |
+			  __raw_readl(ppmu_base + PMCNT_OFFSET(ch + 1)));
+	else
+		total = __raw_readl(ppmu_base + PMCNT_OFFSET(ch));
+
+	return total;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/devfreq/exynos/exynos_ppmu.h linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/exynos_ppmu.h
--- linux-libre-3.10-gnu/drivers/devfreq/exynos/exynos_ppmu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/exynos_ppmu.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * EXYNOS PPMU header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __DEVFREQ_EXYNOS_PPMU_H
+#define __DEVFREQ_EXYNOS_PPMU_H __FILE__
+
+#include <linux/ktime.h>
+
+/* For PPMU Control */
+#define PPMU_ENABLE             BIT(0)
+#define PPMU_DISABLE            0x0
+#define PPMU_CYCLE_RESET        BIT(1)
+#define PPMU_COUNTER_RESET      BIT(2)
+
+#define PPMU_ENABLE_COUNT0      BIT(0)
+#define PPMU_ENABLE_COUNT1      BIT(1)
+#define PPMU_ENABLE_COUNT2      BIT(2)
+#define PPMU_ENABLE_COUNT3      BIT(3)
+#define PPMU_ENABLE_CYCLE       BIT(31)
+
+#define PPMU_CNTENS		0x10
+#define PPMU_FLAG		0x50
+#define PPMU_CCNT_OVERFLOW	BIT(31)
+#define PPMU_CCNT		0x100
+
+#define PPMU_PMCNT0		0x110
+#define PPMU_PMCNT_OFFSET	0x10
+#define PMCNT_OFFSET(x)		(PPMU_PMCNT0 + (PPMU_PMCNT_OFFSET * x))
+
+#define PPMU_BEVT0SEL		0x1000
+#define PPMU_BEVTSEL_OFFSET	0x100
+#define PPMU_BEVTSEL(x)		(PPMU_BEVT0SEL + (ch * PPMU_BEVTSEL_OFFSET))
+
+/* For Event Selection */
+#define RD_DATA_COUNT		0x5
+#define WR_DATA_COUNT		0x6
+#define RDWR_DATA_COUNT		0x7
+
+enum ppmu_counter {
+	PPMU_PMNCNT0,
+	PPMU_PMCCNT1,
+	PPMU_PMNCNT2,
+	PPMU_PMNCNT3,
+	PPMU_PMNCNT_MAX,
+};
+
+struct bus_opp_table {
+	unsigned int idx;
+	unsigned long clk;
+	unsigned long volt;
+};
+
+struct exynos_ppmu {
+	void __iomem *hw_base;
+	unsigned int ccnt;
+	unsigned int event[PPMU_PMNCNT_MAX];
+	unsigned int count[PPMU_PMNCNT_MAX];
+	unsigned long long ns;
+	ktime_t reset_time;
+	bool ccnt_overflow;
+	bool count_overflow[PPMU_PMNCNT_MAX];
+};
+
+void exynos_ppmu_reset(void __iomem *ppmu_base);
+void exynos_ppmu_setevent(void __iomem *ppmu_base, unsigned int ch,
+			unsigned int evt);
+void exynos_ppmu_start(void __iomem *ppmu_base);
+void exynos_ppmu_stop(void __iomem *ppmu_base);
+unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch);
+#endif /* __DEVFREQ_EXYNOS_PPMU_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/devfreq/exynos/Makefile linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/Makefile
--- linux-libre-3.10-gnu/drivers/devfreq/exynos/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3 @@
+# Exynos DEVFREQ Drivers
+obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos4_bus.o
+obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos_ppmu.o exynos5_bus.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/devfreq/exynos4_bus.c linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos4_bus.c
--- linux-libre-3.10-gnu/drivers/devfreq/exynos4_bus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/devfreq/exynos4_bus.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1153 +0,0 @@
-/* drivers/devfreq/exynos4210_memorybus.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *	MyungJoo Ham <myungjoo.ham@samsung.com>
- *
- * EXYNOS4 - Memory/Bus clock frequency scaling support in DEVFREQ framework
- *	This version supports EXYNOS4210 only. This changes bus frequencies
- *	and vddint voltages. Exynos4412/4212 should be able to be supported
- *	with minor modifications.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/suspend.h>
-#include <linux/opp.h>
-#include <linux/devfreq.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/module.h>
-
-/* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */
-#ifdef CONFIG_EXYNOS_ASV
-extern unsigned int exynos_result_of_asv;
-#endif
-
-#include <mach/regs-clock.h>
-
-#include <plat/map-s5p.h>
-
-#define MAX_SAFEVOLT	1200000 /* 1.2V */
-
-enum exynos4_busf_type {
-	TYPE_BUSF_EXYNOS4210,
-	TYPE_BUSF_EXYNOS4x12,
-};
-
-/* Assume that the bus is saturated if the utilization is 40% */
-#define BUS_SATURATION_RATIO	40
-
-enum ppmu_counter {
-	PPMU_PMNCNT0 = 0,
-	PPMU_PMCCNT1,
-	PPMU_PMNCNT2,
-	PPMU_PMNCNT3,
-	PPMU_PMNCNT_MAX,
-};
-struct exynos4_ppmu {
-	void __iomem *hw_base;
-	unsigned int ccnt;
-	unsigned int event;
-	unsigned int count[PPMU_PMNCNT_MAX];
-	bool ccnt_overflow;
-	bool count_overflow[PPMU_PMNCNT_MAX];
-};
-
-enum busclk_level_idx {
-	LV_0 = 0,
-	LV_1,
-	LV_2,
-	LV_3,
-	LV_4,
-	_LV_END
-};
-#define EX4210_LV_MAX	LV_2
-#define EX4x12_LV_MAX	LV_4
-#define EX4210_LV_NUM	(LV_2 + 1)
-#define EX4x12_LV_NUM	(LV_4 + 1)
-
-/**
- * struct busfreq_opp_info - opp information for bus
- * @rate:	Frequency in hertz
- * @volt:	Voltage in microvolts corresponding to this OPP
- */
-struct busfreq_opp_info {
-	unsigned long rate;
-	unsigned long volt;
-};
-
-struct busfreq_data {
-	enum exynos4_busf_type type;
-	struct device *dev;
-	struct devfreq *devfreq;
-	bool disabled;
-	struct regulator *vdd_int;
-	struct regulator *vdd_mif; /* Exynos4412/4212 only */
-	struct busfreq_opp_info curr_oppinfo;
-	struct exynos4_ppmu dmc[2];
-
-	struct notifier_block pm_notifier;
-	struct mutex lock;
-
-	/* Dividers calculated at boot/probe-time */
-	unsigned int dmc_divtable[_LV_END]; /* DMC0 */
-	unsigned int top_divtable[_LV_END];
-};
-
-struct bus_opp_table {
-	unsigned int idx;
-	unsigned long clk;
-	unsigned long volt;
-};
-
-/* 4210 controls clock of mif and voltage of int */
-static struct bus_opp_table exynos4210_busclk_table[] = {
-	{LV_0, 400000, 1150000},
-	{LV_1, 267000, 1050000},
-	{LV_2, 133000, 1025000},
-	{0, 0, 0},
-};
-
-/*
- * MIF is the main control knob clock for exynox4x12 MIF/INT
- * clock and voltage of both mif/int are controlled.
- */
-static struct bus_opp_table exynos4x12_mifclk_table[] = {
-	{LV_0, 400000, 1100000},
-	{LV_1, 267000, 1000000},
-	{LV_2, 160000, 950000},
-	{LV_3, 133000, 950000},
-	{LV_4, 100000, 950000},
-	{0, 0, 0},
-};
-
-/*
- * INT is not the control knob of 4x12. LV_x is not meant to represent
- * the current performance. (MIF does)
- */
-static struct bus_opp_table exynos4x12_intclk_table[] = {
-	{LV_0, 200000, 1000000},
-	{LV_1, 160000, 950000},
-	{LV_2, 133000, 925000},
-	{LV_3, 100000, 900000},
-	{0, 0, 0},
-};
-
-/* TODO: asv volt definitions are "__initdata"? */
-/* Some chips have different operating voltages */
-static unsigned int exynos4210_asv_volt[][EX4210_LV_NUM] = {
-	{1150000, 1050000, 1050000},
-	{1125000, 1025000, 1025000},
-	{1100000, 1000000, 1000000},
-	{1075000, 975000, 975000},
-	{1050000, 950000, 950000},
-};
-
-static unsigned int exynos4x12_mif_step_50[][EX4x12_LV_NUM] = {
-	/* 400      267     160     133     100 */
-	{1050000, 950000, 900000, 900000, 900000}, /* ASV0 */
-	{1050000, 950000, 900000, 900000, 900000}, /* ASV1 */
-	{1050000, 950000, 900000, 900000, 900000}, /* ASV2 */
-	{1050000, 900000, 900000, 900000, 900000}, /* ASV3 */
-	{1050000, 900000, 900000, 900000, 850000}, /* ASV4 */
-	{1050000, 900000, 900000, 850000, 850000}, /* ASV5 */
-	{1050000, 900000, 850000, 850000, 850000}, /* ASV6 */
-	{1050000, 900000, 850000, 850000, 850000}, /* ASV7 */
-	{1050000, 900000, 850000, 850000, 850000}, /* ASV8 */
-};
-
-static unsigned int exynos4x12_int_volt[][EX4x12_LV_NUM] = {
-	/* 200    160      133     100 */
-	{1000000, 950000, 925000, 900000}, /* ASV0 */
-	{975000,  925000, 925000, 900000}, /* ASV1 */
-	{950000,  925000, 900000, 875000}, /* ASV2 */
-	{950000,  900000, 900000, 875000}, /* ASV3 */
-	{925000,  875000, 875000, 875000}, /* ASV4 */
-	{900000,  850000, 850000, 850000}, /* ASV5 */
-	{900000,  850000, 850000, 850000}, /* ASV6 */
-	{900000,  850000, 850000, 850000}, /* ASV7 */
-	{900000,  850000, 850000, 850000}, /* ASV8 */
-};
-
-/*** Clock Divider Data for Exynos4210 ***/
-static unsigned int exynos4210_clkdiv_dmc0[][8] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
-	 *		DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
-	 */
-
-	/* DMC L0: 400MHz */
-	{ 3, 1, 1, 1, 1, 1, 3, 1 },
-	/* DMC L1: 266.7MHz */
-	{ 4, 1, 1, 2, 1, 1, 3, 1 },
-	/* DMC L2: 133MHz */
-	{ 5, 1, 1, 5, 1, 1, 3, 1 },
-};
-static unsigned int exynos4210_clkdiv_top[][5] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
-	 */
-	/* ACLK200 L0: 200MHz */
-	{ 3, 7, 4, 5, 1 },
-	/* ACLK200 L1: 160MHz */
-	{ 4, 7, 5, 6, 1 },
-	/* ACLK200 L2: 133MHz */
-	{ 5, 7, 7, 7, 1 },
-};
-static unsigned int exynos4210_clkdiv_lr_bus[][2] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVGDL/R, DIVGPL/R }
-	 */
-	/* ACLK_GDL/R L1: 200MHz */
-	{ 3, 1 },
-	/* ACLK_GDL/R L2: 160MHz */
-	{ 4, 1 },
-	/* ACLK_GDL/R L3: 133MHz */
-	{ 5, 1 },
-};
-
-/*** Clock Divider Data for Exynos4212/4412 ***/
-static unsigned int exynos4x12_clkdiv_dmc0[][6] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
-	 *              DIVDMCP}
-	 */
-
-	/* DMC L0: 400MHz */
-	{3, 1, 1, 1, 1, 1},
-	/* DMC L1: 266.7MHz */
-	{4, 1, 1, 2, 1, 1},
-	/* DMC L2: 160MHz */
-	{5, 1, 1, 4, 1, 1},
-	/* DMC L3: 133MHz */
-	{5, 1, 1, 5, 1, 1},
-	/* DMC L4: 100MHz */
-	{7, 1, 1, 7, 1, 1},
-};
-static unsigned int exynos4x12_clkdiv_dmc1[][6] = {
-	/*
-	 * Clock divider value for following
-	 * { G2DACP, DIVC2C, DIVC2C_ACLK }
-	 */
-
-	/* DMC L0: 400MHz */
-	{3, 1, 1},
-	/* DMC L1: 266.7MHz */
-	{4, 2, 1},
-	/* DMC L2: 160MHz */
-	{5, 4, 1},
-	/* DMC L3: 133MHz */
-	{5, 5, 1},
-	/* DMC L4: 100MHz */
-	{7, 7, 1},
-};
-static unsigned int exynos4x12_clkdiv_top[][5] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVACLK266_GPS, DIVACLK100, DIVACLK160,
-		DIVACLK133, DIVONENAND }
-	 */
-
-	/* ACLK_GDL/R L0: 200MHz */
-	{2, 7, 4, 5, 1},
-	/* ACLK_GDL/R L1: 200MHz */
-	{2, 7, 4, 5, 1},
-	/* ACLK_GDL/R L2: 160MHz */
-	{4, 7, 5, 7, 1},
-	/* ACLK_GDL/R L3: 133MHz */
-	{4, 7, 5, 7, 1},
-	/* ACLK_GDL/R L4: 100MHz */
-	{7, 7, 7, 7, 1},
-};
-static unsigned int exynos4x12_clkdiv_lr_bus[][2] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVGDL/R, DIVGPL/R }
-	 */
-
-	/* ACLK_GDL/R L0: 200MHz */
-	{3, 1},
-	/* ACLK_GDL/R L1: 200MHz */
-	{3, 1},
-	/* ACLK_GDL/R L2: 160MHz */
-	{4, 1},
-	/* ACLK_GDL/R L3: 133MHz */
-	{5, 1},
-	/* ACLK_GDL/R L4: 100MHz */
-	{7, 1},
-};
-static unsigned int exynos4x12_clkdiv_sclkip[][3] = {
-	/*
-	 * Clock divider value for following
-	 * { DIVMFC, DIVJPEG, DIVFIMC0~3}
-	 */
-
-	/* SCLK_MFC: 200MHz */
-	{3, 3, 4},
-	/* SCLK_MFC: 200MHz */
-	{3, 3, 4},
-	/* SCLK_MFC: 160MHz */
-	{4, 4, 5},
-	/* SCLK_MFC: 133MHz */
-	{5, 5, 5},
-	/* SCLK_MFC: 100MHz */
-	{7, 7, 7},
-};
-
-
-static int exynos4210_set_busclk(struct busfreq_data *data,
-				 struct busfreq_opp_info *oppi)
-{
-	unsigned int index;
-	unsigned int tmp;
-
-	for (index = LV_0; index < EX4210_LV_NUM; index++)
-		if (oppi->rate == exynos4210_busclk_table[index].clk)
-			break;
-
-	if (index == EX4210_LV_NUM)
-		return -EINVAL;
-
-	/* Change Divider - DMC0 */
-	tmp = data->dmc_divtable[index];
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
-	} while (tmp & 0x11111111);
-
-	/* Change Divider - TOP */
-	tmp = data->top_divtable[index];
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
-	} while (tmp & 0x11111);
-
-	/* Change Divider - LEFTBUS */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
-
-	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
-
-	tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
-				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
-		(exynos4210_clkdiv_lr_bus[index][1] <<
-				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
-	} while (tmp & 0x11);
-
-	/* Change Divider - RIGHTBUS */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
-
-	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
-
-	tmp |= ((exynos4210_clkdiv_lr_bus[index][0] <<
-				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
-		(exynos4210_clkdiv_lr_bus[index][1] <<
-				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
-	} while (tmp & 0x11);
-
-	return 0;
-}
-
-static int exynos4x12_set_busclk(struct busfreq_data *data,
-				 struct busfreq_opp_info *oppi)
-{
-	unsigned int index;
-	unsigned int tmp;
-
-	for (index = LV_0; index < EX4x12_LV_NUM; index++)
-		if (oppi->rate == exynos4x12_mifclk_table[index].clk)
-			break;
-
-	if (index == EX4x12_LV_NUM)
-		return -EINVAL;
-
-	/* Change Divider - DMC0 */
-	tmp = data->dmc_divtable[index];
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
-	} while (tmp & 0x11111111);
-
-	/* Change Divider - DMC1 */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_DMC1);
-
-	tmp &= ~(EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK |
-		EXYNOS4_CLKDIV_DMC1_C2C_MASK |
-		EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_dmc1[index][0] <<
-				EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT) |
-		(exynos4x12_clkdiv_dmc1[index][1] <<
-				EXYNOS4_CLKDIV_DMC1_C2C_SHIFT) |
-		(exynos4x12_clkdiv_dmc1[index][2] <<
-				EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_DMC1);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC1);
-	} while (tmp & 0x111111);
-
-	/* Change Divider - TOP */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
-
-	tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK |
-		EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
-		EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
-		EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
-		EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_top[index][0] <<
-				EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT) |
-		(exynos4x12_clkdiv_top[index][1] <<
-				EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
-		(exynos4x12_clkdiv_top[index][2] <<
-				EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
-		(exynos4x12_clkdiv_top[index][3] <<
-				EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
-		(exynos4x12_clkdiv_top[index][4] <<
-				EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
-	} while (tmp & 0x11111);
-
-	/* Change Divider - LEFTBUS */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
-
-	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
-				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
-		(exynos4x12_clkdiv_lr_bus[index][1] <<
-				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
-	} while (tmp & 0x11);
-
-	/* Change Divider - RIGHTBUS */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
-
-	tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_lr_bus[index][0] <<
-				EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
-		(exynos4x12_clkdiv_lr_bus[index][1] <<
-				EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
-	} while (tmp & 0x11);
-
-	/* Change Divider - MFC */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_MFC);
-
-	tmp &= ~(EXYNOS4_CLKDIV_MFC_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_sclkip[index][0] <<
-				EXYNOS4_CLKDIV_MFC_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_MFC);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_MFC);
-	} while (tmp & 0x1);
-
-	/* Change Divider - JPEG */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_CAM1);
-
-	tmp &= ~(EXYNOS4_CLKDIV_CAM1_JPEG_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_sclkip[index][1] <<
-				EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_CAM1);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
-	} while (tmp & 0x1);
-
-	/* Change Divider - FIMC0~3 */
-	tmp = __raw_readl(EXYNOS4_CLKDIV_CAM);
-
-	tmp &= ~(EXYNOS4_CLKDIV_CAM_FIMC0_MASK | EXYNOS4_CLKDIV_CAM_FIMC1_MASK |
-		EXYNOS4_CLKDIV_CAM_FIMC2_MASK | EXYNOS4_CLKDIV_CAM_FIMC3_MASK);
-
-	tmp |= ((exynos4x12_clkdiv_sclkip[index][2] <<
-				EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT) |
-		(exynos4x12_clkdiv_sclkip[index][2] <<
-				EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT) |
-		(exynos4x12_clkdiv_sclkip[index][2] <<
-				EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT) |
-		(exynos4x12_clkdiv_sclkip[index][2] <<
-				EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT));
-
-	__raw_writel(tmp, EXYNOS4_CLKDIV_CAM);
-
-	do {
-		tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
-	} while (tmp & 0x1111);
-
-	return 0;
-}
-
-
-static void busfreq_mon_reset(struct busfreq_data *data)
-{
-	unsigned int i;
-
-	for (i = 0; i < 2; i++) {
-		void __iomem *ppmu_base = data->dmc[i].hw_base;
-
-		/* Reset PPMU */
-		__raw_writel(0x8000000f, ppmu_base + 0xf010);
-		__raw_writel(0x8000000f, ppmu_base + 0xf050);
-		__raw_writel(0x6, ppmu_base + 0xf000);
-		__raw_writel(0x0, ppmu_base + 0xf100);
-
-		/* Set PPMU Event */
-		data->dmc[i].event = 0x6;
-		__raw_writel(((data->dmc[i].event << 12) | 0x1),
-			     ppmu_base + 0xfc);
-
-		/* Start PPMU */
-		__raw_writel(0x1, ppmu_base + 0xf000);
-	}
-}
-
-static void exynos4_read_ppmu(struct busfreq_data *data)
-{
-	int i, j;
-
-	for (i = 0; i < 2; i++) {
-		void __iomem *ppmu_base = data->dmc[i].hw_base;
-		u32 overflow;
-
-		/* Stop PPMU */
-		__raw_writel(0x0, ppmu_base + 0xf000);
-
-		/* Update local data from PPMU */
-		overflow = __raw_readl(ppmu_base + 0xf050);
-
-		data->dmc[i].ccnt = __raw_readl(ppmu_base + 0xf100);
-		data->dmc[i].ccnt_overflow = overflow & (1 << 31);
-
-		for (j = 0; j < PPMU_PMNCNT_MAX; j++) {
-			data->dmc[i].count[j] = __raw_readl(
-					ppmu_base + (0xf110 + (0x10 * j)));
-			data->dmc[i].count_overflow[j] = overflow & (1 << j);
-		}
-	}
-
-	busfreq_mon_reset(data);
-}
-
-static int exynos4x12_get_intspec(unsigned long mifclk)
-{
-	int i = 0;
-
-	while (exynos4x12_intclk_table[i].clk) {
-		if (exynos4x12_intclk_table[i].clk <= mifclk)
-			return i;
-		i++;
-	}
-
-	return -EINVAL;
-}
-
-static int exynos4_bus_setvolt(struct busfreq_data *data,
-			       struct busfreq_opp_info *oppi,
-			       struct busfreq_opp_info *oldoppi)
-{
-	int err = 0, tmp;
-	unsigned long volt = oppi->volt;
-
-	switch (data->type) {
-	case TYPE_BUSF_EXYNOS4210:
-		/* OPP represents DMC clock + INT voltage */
-		err = regulator_set_voltage(data->vdd_int, volt,
-					    MAX_SAFEVOLT);
-		break;
-	case TYPE_BUSF_EXYNOS4x12:
-		/* OPP represents MIF clock + MIF voltage */
-		err = regulator_set_voltage(data->vdd_mif, volt,
-					    MAX_SAFEVOLT);
-		if (err)
-			break;
-
-		tmp = exynos4x12_get_intspec(oppi->rate);
-		if (tmp < 0) {
-			err = tmp;
-			regulator_set_voltage(data->vdd_mif,
-					      oldoppi->volt,
-					      MAX_SAFEVOLT);
-			break;
-		}
-		err = regulator_set_voltage(data->vdd_int,
-					    exynos4x12_intclk_table[tmp].volt,
-					    MAX_SAFEVOLT);
-		/*  Try to recover */
-		if (err)
-			regulator_set_voltage(data->vdd_mif,
-					      oldoppi->volt,
-					      MAX_SAFEVOLT);
-		break;
-	default:
-		err = -EINVAL;
-	}
-
-	return err;
-}
-
-static int exynos4_bus_target(struct device *dev, unsigned long *_freq,
-			      u32 flags)
-{
-	int err = 0;
-	struct platform_device *pdev = container_of(dev, struct platform_device,
-						    dev);
-	struct busfreq_data *data = platform_get_drvdata(pdev);
-	struct opp *opp;
-	unsigned long freq;
-	unsigned long old_freq = data->curr_oppinfo.rate;
-	struct busfreq_opp_info	new_oppinfo;
-
-	rcu_read_lock();
-	opp = devfreq_recommended_opp(dev, _freq, flags);
-	if (IS_ERR(opp)) {
-		rcu_read_unlock();
-		return PTR_ERR(opp);
-	}
-	new_oppinfo.rate = opp_get_freq(opp);
-	new_oppinfo.volt = opp_get_voltage(opp);
-	rcu_read_unlock();
-	freq = new_oppinfo.rate;
-
-	if (old_freq == freq)
-		return 0;
-
-	dev_dbg(dev, "targeting %lukHz %luuV\n", freq, new_oppinfo.volt);
-
-	mutex_lock(&data->lock);
-
-	if (data->disabled)
-		goto out;
-
-	if (old_freq < freq)
-		err = exynos4_bus_setvolt(data, &new_oppinfo,
-					  &data->curr_oppinfo);
-	if (err)
-		goto out;
-
-	if (old_freq != freq) {
-		switch (data->type) {
-		case TYPE_BUSF_EXYNOS4210:
-			err = exynos4210_set_busclk(data, &new_oppinfo);
-			break;
-		case TYPE_BUSF_EXYNOS4x12:
-			err = exynos4x12_set_busclk(data, &new_oppinfo);
-			break;
-		default:
-			err = -EINVAL;
-		}
-	}
-	if (err)
-		goto out;
-
-	if (old_freq > freq)
-		err = exynos4_bus_setvolt(data, &new_oppinfo,
-					  &data->curr_oppinfo);
-	if (err)
-		goto out;
-
-	data->curr_oppinfo = new_oppinfo;
-out:
-	mutex_unlock(&data->lock);
-	return err;
-}
-
-static int exynos4_get_busier_dmc(struct busfreq_data *data)
-{
-	u64 p0 = data->dmc[0].count[0];
-	u64 p1 = data->dmc[1].count[0];
-
-	p0 *= data->dmc[1].ccnt;
-	p1 *= data->dmc[0].ccnt;
-
-	if (data->dmc[1].ccnt == 0)
-		return 0;
-
-	if (p0 > p1)
-		return 0;
-	return 1;
-}
-
-static int exynos4_bus_get_dev_status(struct device *dev,
-				      struct devfreq_dev_status *stat)
-{
-	struct busfreq_data *data = dev_get_drvdata(dev);
-	int busier_dmc;
-	int cycles_x2 = 2; /* 2 x cycles */
-	void __iomem *addr;
-	u32 timing;
-	u32 memctrl;
-
-	exynos4_read_ppmu(data);
-	busier_dmc = exynos4_get_busier_dmc(data);
-	stat->current_frequency = data->curr_oppinfo.rate;
-
-	if (busier_dmc)
-		addr = S5P_VA_DMC1;
-	else
-		addr = S5P_VA_DMC0;
-
-	memctrl = __raw_readl(addr + 0x04); /* one of DDR2/3/LPDDR2 */
-	timing = __raw_readl(addr + 0x38); /* CL or WL/RL values */
-
-	switch ((memctrl >> 8) & 0xf) {
-	case 0x4: /* DDR2 */
-		cycles_x2 = ((timing >> 16) & 0xf) * 2;
-		break;
-	case 0x5: /* LPDDR2 */
-	case 0x6: /* DDR3 */
-		cycles_x2 = ((timing >> 8) & 0xf) + ((timing >> 0) & 0xf);
-		break;
-	default:
-		pr_err("%s: Unknown Memory Type(%d).\n", __func__,
-		       (memctrl >> 8) & 0xf);
-		return -EINVAL;
-	}
-
-	/* Number of cycles spent on memory access */
-	stat->busy_time = data->dmc[busier_dmc].count[0] / 2 * (cycles_x2 + 2);
-	stat->busy_time *= 100 / BUS_SATURATION_RATIO;
-	stat->total_time = data->dmc[busier_dmc].ccnt;
-
-	/* If the counters have overflown, retry */
-	if (data->dmc[busier_dmc].ccnt_overflow ||
-	    data->dmc[busier_dmc].count_overflow[0])
-		return -EAGAIN;
-
-	return 0;
-}
-
-static void exynos4_bus_exit(struct device *dev)
-{
-	struct busfreq_data *data = dev_get_drvdata(dev);
-
-	devfreq_unregister_opp_notifier(dev, data->devfreq);
-}
-
-static struct devfreq_dev_profile exynos4_devfreq_profile = {
-	.initial_freq	= 400000,
-	.polling_ms	= 50,
-	.target		= exynos4_bus_target,
-	.get_dev_status	= exynos4_bus_get_dev_status,
-	.exit		= exynos4_bus_exit,
-};
-
-static int exynos4210_init_tables(struct busfreq_data *data)
-{
-	u32 tmp;
-	int mgrp;
-	int i, err = 0;
-
-	tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
-	for (i = LV_0; i < EX4210_LV_NUM; i++) {
-		tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
-			EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
-			EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMC_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMCP_MASK |
-			EXYNOS4_CLKDIV_DMC0_COPY2_MASK |
-			EXYNOS4_CLKDIV_DMC0_CORETI_MASK);
-
-		tmp |= ((exynos4210_clkdiv_dmc0[i][0] <<
-					EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][1] <<
-					EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][2] <<
-					EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][3] <<
-					EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][4] <<
-					EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][5] <<
-					EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][6] <<
-					EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) |
-			(exynos4210_clkdiv_dmc0[i][7] <<
-					EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT));
-
-		data->dmc_divtable[i] = tmp;
-	}
-
-	tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
-	for (i = LV_0; i <  EX4210_LV_NUM; i++) {
-		tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK200_MASK |
-			EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
-			EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
-			EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
-			EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
-
-		tmp |= ((exynos4210_clkdiv_top[i][0] <<
-					EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) |
-			(exynos4210_clkdiv_top[i][1] <<
-					EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
-			(exynos4210_clkdiv_top[i][2] <<
-					EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
-			(exynos4210_clkdiv_top[i][3] <<
-					EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
-			(exynos4210_clkdiv_top[i][4] <<
-					EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
-
-		data->top_divtable[i] = tmp;
-	}
-
-#ifdef CONFIG_EXYNOS_ASV
-	tmp = exynos4_result_of_asv;
-#else
-	tmp = 0; /* Max voltages for the reliability of the unknown */
-#endif
-
-	pr_debug("ASV Group of Exynos4 is %d\n", tmp);
-	/* Use merged grouping for voltage */
-	switch (tmp) {
-	case 0:
-		mgrp = 0;
-		break;
-	case 1:
-	case 2:
-		mgrp = 1;
-		break;
-	case 3:
-	case 4:
-		mgrp = 2;
-		break;
-	case 5:
-	case 6:
-		mgrp = 3;
-		break;
-	case 7:
-		mgrp = 4;
-		break;
-	default:
-		pr_warn("Unknown ASV Group. Use max voltage.\n");
-		mgrp = 0;
-	}
-
-	for (i = LV_0; i < EX4210_LV_NUM; i++)
-		exynos4210_busclk_table[i].volt = exynos4210_asv_volt[mgrp][i];
-
-	for (i = LV_0; i < EX4210_LV_NUM; i++) {
-		err = opp_add(data->dev, exynos4210_busclk_table[i].clk,
-			      exynos4210_busclk_table[i].volt);
-		if (err) {
-			dev_err(data->dev, "Cannot add opp entries.\n");
-			return err;
-		}
-	}
-
-
-	return 0;
-}
-
-static int exynos4x12_init_tables(struct busfreq_data *data)
-{
-	unsigned int i;
-	unsigned int tmp;
-	int ret;
-
-	/* Enable pause function for DREX2 DVFS */
-	tmp = __raw_readl(EXYNOS4_DMC_PAUSE_CTRL);
-	tmp |= EXYNOS4_DMC_PAUSE_ENABLE;
-	__raw_writel(tmp, EXYNOS4_DMC_PAUSE_CTRL);
-
-	tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
-
-	for (i = 0; i <  EX4x12_LV_NUM; i++) {
-		tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
-			EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
-			EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMC_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
-			EXYNOS4_CLKDIV_DMC0_DMCP_MASK);
-
-		tmp |= ((exynos4x12_clkdiv_dmc0[i][0] <<
-					EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][1] <<
-					EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][2] <<
-					EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][3] <<
-					EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][4] <<
-					EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
-			(exynos4x12_clkdiv_dmc0[i][5] <<
-					EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT));
-
-		data->dmc_divtable[i] = tmp;
-	}
-
-#ifdef CONFIG_EXYNOS_ASV
-	tmp = exynos4_result_of_asv;
-#else
-	tmp = 0; /* Max voltages for the reliability of the unknown */
-#endif
-
-	if (tmp > 8)
-		tmp = 0;
-	pr_debug("ASV Group of Exynos4x12 is %d\n", tmp);
-
-	for (i = 0; i < EX4x12_LV_NUM; i++) {
-		exynos4x12_mifclk_table[i].volt =
-			exynos4x12_mif_step_50[tmp][i];
-		exynos4x12_intclk_table[i].volt =
-			exynos4x12_int_volt[tmp][i];
-	}
-
-	for (i = 0; i < EX4x12_LV_NUM; i++) {
-		ret = opp_add(data->dev, exynos4x12_mifclk_table[i].clk,
-			      exynos4x12_mifclk_table[i].volt);
-		if (ret) {
-			dev_err(data->dev, "Fail to add opp entries.\n");
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,
-		unsigned long event, void *ptr)
-{
-	struct busfreq_data *data = container_of(this, struct busfreq_data,
-						 pm_notifier);
-	struct opp *opp;
-	struct busfreq_opp_info	new_oppinfo;
-	unsigned long maxfreq = ULONG_MAX;
-	int err = 0;
-
-	switch (event) {
-	case PM_SUSPEND_PREPARE:
-		/* Set Fastest and Deactivate DVFS */
-		mutex_lock(&data->lock);
-
-		data->disabled = true;
-
-		rcu_read_lock();
-		opp = opp_find_freq_floor(data->dev, &maxfreq);
-		if (IS_ERR(opp)) {
-			rcu_read_unlock();
-			dev_err(data->dev, "%s: unable to find a min freq\n",
-				__func__);
-			return PTR_ERR(opp);
-		}
-		new_oppinfo.rate = opp_get_freq(opp);
-		new_oppinfo.volt = opp_get_voltage(opp);
-		rcu_read_unlock();
-
-		err = exynos4_bus_setvolt(data, &new_oppinfo,
-					  &data->curr_oppinfo);
-		if (err)
-			goto unlock;
-
-		switch (data->type) {
-		case TYPE_BUSF_EXYNOS4210:
-			err = exynos4210_set_busclk(data, &new_oppinfo);
-			break;
-		case TYPE_BUSF_EXYNOS4x12:
-			err = exynos4x12_set_busclk(data, &new_oppinfo);
-			break;
-		default:
-			err = -EINVAL;
-		}
-		if (err)
-			goto unlock;
-
-		data->curr_oppinfo = new_oppinfo;
-unlock:
-		mutex_unlock(&data->lock);
-		if (err)
-			return err;
-		return NOTIFY_OK;
-	case PM_POST_RESTORE:
-	case PM_POST_SUSPEND:
-		/* Reactivate */
-		mutex_lock(&data->lock);
-		data->disabled = false;
-		mutex_unlock(&data->lock);
-		return NOTIFY_OK;
-	}
-
-	return NOTIFY_DONE;
-}
-
-static int exynos4_busfreq_probe(struct platform_device *pdev)
-{
-	struct busfreq_data *data;
-	struct opp *opp;
-	struct device *dev = &pdev->dev;
-	int err = 0;
-
-	data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data), GFP_KERNEL);
-	if (data == NULL) {
-		dev_err(dev, "Cannot allocate memory.\n");
-		return -ENOMEM;
-	}
-
-	data->type = pdev->id_entry->driver_data;
-	data->dmc[0].hw_base = S5P_VA_DMC0;
-	data->dmc[1].hw_base = S5P_VA_DMC1;
-	data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event;
-	data->dev = dev;
-	mutex_init(&data->lock);
-
-	switch (data->type) {
-	case TYPE_BUSF_EXYNOS4210:
-		err = exynos4210_init_tables(data);
-		break;
-	case TYPE_BUSF_EXYNOS4x12:
-		err = exynos4x12_init_tables(data);
-		break;
-	default:
-		dev_err(dev, "Cannot determine the device id %d\n", data->type);
-		err = -EINVAL;
-	}
-	if (err)
-		return err;
-
-	data->vdd_int = devm_regulator_get(dev, "vdd_int");
-	if (IS_ERR(data->vdd_int)) {
-		dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
-		return PTR_ERR(data->vdd_int);
-	}
-	if (data->type == TYPE_BUSF_EXYNOS4x12) {
-		data->vdd_mif = devm_regulator_get(dev, "vdd_mif");
-		if (IS_ERR(data->vdd_mif)) {
-			dev_err(dev, "Cannot get the regulator \"vdd_mif\"\n");
-			return PTR_ERR(data->vdd_mif);
-		}
-	}
-
-	rcu_read_lock();
-	opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq);
-	if (IS_ERR(opp)) {
-		rcu_read_unlock();
-		dev_err(dev, "Invalid initial frequency %lu kHz.\n",
-			exynos4_devfreq_profile.initial_freq);
-		return PTR_ERR(opp);
-	}
-	data->curr_oppinfo.rate = opp_get_freq(opp);
-	data->curr_oppinfo.volt = opp_get_voltage(opp);
-	rcu_read_unlock();
-
-	platform_set_drvdata(pdev, data);
-
-	busfreq_mon_reset(data);
-
-	data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile,
-					   "simple_ondemand", NULL);
-	if (IS_ERR(data->devfreq))
-		return PTR_ERR(data->devfreq);
-
-	devfreq_register_opp_notifier(dev, data->devfreq);
-
-	err = register_pm_notifier(&data->pm_notifier);
-	if (err) {
-		dev_err(dev, "Failed to setup pm notifier\n");
-		devfreq_remove_device(data->devfreq);
-		return err;
-	}
-
-	return 0;
-}
-
-static int exynos4_busfreq_remove(struct platform_device *pdev)
-{
-	struct busfreq_data *data = platform_get_drvdata(pdev);
-
-	unregister_pm_notifier(&data->pm_notifier);
-	devfreq_remove_device(data->devfreq);
-
-	return 0;
-}
-
-static int exynos4_busfreq_resume(struct device *dev)
-{
-	struct busfreq_data *data = dev_get_drvdata(dev);
-
-	busfreq_mon_reset(data);
-	return 0;
-}
-
-static const struct dev_pm_ops exynos4_busfreq_pm = {
-	.resume	= exynos4_busfreq_resume,
-};
-
-static const struct platform_device_id exynos4_busfreq_id[] = {
-	{ "exynos4210-busfreq", TYPE_BUSF_EXYNOS4210 },
-	{ "exynos4412-busfreq", TYPE_BUSF_EXYNOS4x12 },
-	{ "exynos4212-busfreq", TYPE_BUSF_EXYNOS4x12 },
-	{ },
-};
-
-static struct platform_driver exynos4_busfreq_driver = {
-	.probe	= exynos4_busfreq_probe,
-	.remove	= exynos4_busfreq_remove,
-	.id_table = exynos4_busfreq_id,
-	.driver = {
-		.name	= "exynos4-busfreq",
-		.owner	= THIS_MODULE,
-		.pm	= &exynos4_busfreq_pm,
-	},
-};
-
-static int __init exynos4_busfreq_init(void)
-{
-	return platform_driver_register(&exynos4_busfreq_driver);
-}
-late_initcall(exynos4_busfreq_init);
-
-static void __exit exynos4_busfreq_exit(void)
-{
-	platform_driver_unregister(&exynos4_busfreq_driver);
-}
-module_exit(exynos4_busfreq_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("EXYNOS4 busfreq driver with devfreq framework");
-MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/devfreq/Kconfig linux-libre-3.11-rc7-gnu/drivers/devfreq/Kconfig
--- linux-libre-3.10-gnu/drivers/devfreq/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/devfreq/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -67,7 +67,7 @@ comment "DEVFREQ Drivers"
 
 config ARM_EXYNOS4_BUS_DEVFREQ
 	bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
-	depends on CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
+	depends on CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412
 	select ARCH_HAS_OPP
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
 	help
@@ -78,4 +78,14 @@ config ARM_EXYNOS4_BUS_DEVFREQ
 	  To operate with optimal voltages, ASV support is required
 	  (CONFIG_EXYNOS_ASV).
 
+config ARM_EXYNOS5_BUS_DEVFREQ
+	bool "ARM Exynos5250 Bus DEVFREQ Driver"
+	depends on SOC_EXYNOS5250
+	select ARCH_HAS_OPP
+	select DEVFREQ_GOV_SIMPLE_ONDEMAND
+	help
+	  This adds the DEVFREQ driver for Exynos5250 bus interface (vdd_int).
+	  It reads PPMU counters of memory controllers and adjusts the
+	  operating frequencies and voltages with OPP support.
+
 endif # PM_DEVFREQ
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/devfreq/Makefile linux-libre-3.11-rc7-gnu/drivers/devfreq/Makefile
--- linux-libre-3.10-gnu/drivers/devfreq/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/devfreq/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,4 +5,5 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)	+= g
 obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)	+= governor_userspace.o
 
 # DEVFREQ Drivers
-obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos4_bus.o
+obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos/
+obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/amba-pl08x.c linux-libre-3.11-rc7-gnu/drivers/dma/amba-pl08x.c
--- linux-libre-3.10-gnu/drivers/dma/amba-pl08x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/amba-pl08x.c	2013-08-25 20:43:22.000000000 -0400
@@ -299,8 +299,8 @@ static int pl08x_request_mux(struct pl08
 	const struct pl08x_platform_data *pd = plchan->host->pd;
 	int ret;
 
-	if (plchan->mux_use++ == 0 && pd->get_signal) {
-		ret = pd->get_signal(plchan->cd);
+	if (plchan->mux_use++ == 0 && pd->get_xfer_signal) {
+		ret = pd->get_xfer_signal(plchan->cd);
 		if (ret < 0) {
 			plchan->mux_use = 0;
 			return ret;
@@ -318,8 +318,8 @@ static void pl08x_release_mux(struct pl0
 	if (plchan->signal >= 0) {
 		WARN_ON(plchan->mux_use == 0);
 
-		if (--plchan->mux_use == 0 && pd->put_signal) {
-			pd->put_signal(plchan->cd, plchan->signal);
+		if (--plchan->mux_use == 0 && pd->put_xfer_signal) {
+			pd->put_xfer_signal(plchan->cd, plchan->signal);
 			plchan->signal = -1;
 		}
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/at_hdmac.c linux-libre-3.11-rc7-gnu/drivers/dma/at_hdmac.c
--- linux-libre-3.10-gnu/drivers/dma/at_hdmac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/at_hdmac.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@
  * found on AT91SAM9263.
  */
 
+#include <dt-bindings/dma/at91.h>
 #include <linux/clk.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
@@ -54,6 +55,7 @@ MODULE_PARM_DESC(init_nr_desc_per_channe
 
 /* prototypes */
 static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx);
+static void atc_issue_pending(struct dma_chan *chan);
 
 
 /*----------------------------------------------------------------------*/
@@ -230,6 +232,95 @@ static void atc_dostart(struct at_dma_ch
 	vdbg_dump_regs(atchan);
 }
 
+/*
+ * atc_get_current_descriptors -
+ * locate the descriptor which equal to physical address in DSCR
+ * @atchan: the channel we want to start
+ * @dscr_addr: physical descriptor address in DSCR
+ */
+static struct at_desc *atc_get_current_descriptors(struct at_dma_chan *atchan,
+							u32 dscr_addr)
+{
+	struct at_desc  *desc, *_desc, *child, *desc_cur = NULL;
+
+	list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) {
+		if (desc->lli.dscr == dscr_addr) {
+			desc_cur = desc;
+			break;
+		}
+
+		list_for_each_entry(child, &desc->tx_list, desc_node) {
+			if (child->lli.dscr == dscr_addr) {
+				desc_cur = child;
+				break;
+			}
+		}
+	}
+
+	return desc_cur;
+}
+
+/*
+ * atc_get_bytes_left -
+ * Get the number of bytes residue in dma buffer,
+ * @chan: the channel we want to start
+ */
+static int atc_get_bytes_left(struct dma_chan *chan)
+{
+	struct at_dma_chan      *atchan = to_at_dma_chan(chan);
+	struct at_dma           *atdma = to_at_dma(chan->device);
+	int	chan_id = atchan->chan_common.chan_id;
+	struct at_desc *desc_first = atc_first_active(atchan);
+	struct at_desc *desc_cur;
+	int ret = 0, count = 0;
+
+	/*
+	 * Initialize necessary values in the first time.
+	 * remain_desc record remain desc length.
+	 */
+	if (atchan->remain_desc == 0)
+		/* First descriptor embedds the transaction length */
+		atchan->remain_desc = desc_first->len;
+
+	/*
+	 * This happens when current descriptor transfer complete.
+	 * The residual buffer size should reduce current descriptor length.
+	 */
+	if (unlikely(test_bit(ATC_IS_BTC, &atchan->status))) {
+		clear_bit(ATC_IS_BTC, &atchan->status);
+		desc_cur = atc_get_current_descriptors(atchan,
+						channel_readl(atchan, DSCR));
+		if (!desc_cur) {
+			ret = -EINVAL;
+			goto out;
+		}
+		atchan->remain_desc -= (desc_cur->lli.ctrla & ATC_BTSIZE_MAX)
+						<< (desc_first->tx_width);
+		if (atchan->remain_desc < 0) {
+			ret = -EINVAL;
+			goto out;
+		} else {
+			ret = atchan->remain_desc;
+		}
+	} else {
+		/*
+		 * Get residual bytes when current
+		 * descriptor transfer in progress.
+		 */
+		count = (channel_readl(atchan, CTRLA) & ATC_BTSIZE_MAX)
+				<< (desc_first->tx_width);
+		ret = atchan->remain_desc - count;
+	}
+	/*
+	 * Check fifo empty.
+	 */
+	if (!(dma_readl(atdma, CHSR) & AT_DMA_EMPT(chan_id)))
+		atc_issue_pending(chan);
+
+out:
+	return ret;
+}
+
 /**
  * atc_chain_complete - finish work for one transaction chain
  * @atchan: channel we work on
@@ -327,37 +418,6 @@ static void atc_complete_all(struct at_d
 }
 
 /**
- * atc_cleanup_descriptors - cleanup up finished descriptors in active_list
- * @atchan: channel to be cleaned up
- *
- * Called with atchan->lock held and bh disabled
- */
-static void atc_cleanup_descriptors(struct at_dma_chan *atchan)
-{
-	struct at_desc	*desc, *_desc;
-	struct at_desc	*child;
-
-	dev_vdbg(chan2dev(&atchan->chan_common), "cleanup descriptors\n");
-
-	list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) {
-		if (!(desc->lli.ctrla & ATC_DONE))
-			/* This one is currently in progress */
-			return;
-
-		list_for_each_entry(child, &desc->tx_list, desc_node)
-			if (!(child->lli.ctrla & ATC_DONE))
-				/* Currently in progress */
-				return;
-
-		/*
-		 * No descriptors so far seem to be in progress, i.e.
-		 * this chain must be done.
-		 */
-		atc_chain_complete(atchan, desc);
-	}
-}
-
-/**
  * atc_advance_work - at the end of a transaction, move forward
  * @atchan: channel where the transaction ended
  *
@@ -496,6 +556,8 @@ static irqreturn_t at_dma_interrupt(int
 					/* Give information to tasklet */
 					set_bit(ATC_IS_ERROR, &atchan->status);
 				}
+				if (pending & AT_DMA_BTC(i))
+					set_bit(ATC_IS_BTC, &atchan->status);
 				tasklet_schedule(&atchan->tasklet);
 				ret = IRQ_HANDLED;
 			}
@@ -615,6 +677,7 @@ atc_prep_dma_memcpy(struct dma_chan *cha
 	/* First descriptor of the chain embedds additional information */
 	first->txd.cookie = -EBUSY;
 	first->len = len;
+	first->tx_width = src_width;
 
 	/* set end-of-link to the last link descriptor of list*/
 	set_desc_eol(desc);
@@ -761,6 +824,7 @@ atc_prep_slave_sg(struct dma_chan *chan,
 	/* First descriptor of the chain embedds additional information */
 	first->txd.cookie = -EBUSY;
 	first->len = total_len;
+	first->tx_width = reg_width;
 
 	/* first link descriptor of list is responsible of flags */
 	first->txd.flags = flags; /* client is in control of this ack */
@@ -919,6 +983,7 @@ atc_prep_dma_cyclic(struct dma_chan *cha
 	/* First descriptor of the chain embedds additional information */
 	first->txd.cookie = -EBUSY;
 	first->len = buf_len;
+	first->tx_width = reg_width;
 
 	return &first->txd;
 
@@ -1032,34 +1097,36 @@ atc_tx_status(struct dma_chan *chan,
 		struct dma_tx_state *txstate)
 {
 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
-	dma_cookie_t		last_used;
-	dma_cookie_t		last_complete;
 	unsigned long		flags;
 	enum dma_status		ret;
-
-	spin_lock_irqsave(&atchan->lock, flags);
+	int bytes = 0;
 
 	ret = dma_cookie_status(chan, cookie, txstate);
-	if (ret != DMA_SUCCESS) {
-		atc_cleanup_descriptors(atchan);
+	if (ret == DMA_SUCCESS)
+		return ret;
+	/*
+	 * There's no point calculating the residue if there's
+	 * no txstate to store the value.
+	 */
+	if (!txstate)
+		return DMA_ERROR;
 
-		ret = dma_cookie_status(chan, cookie, txstate);
-	}
+	spin_lock_irqsave(&atchan->lock, flags);
 
-	last_complete = chan->completed_cookie;
-	last_used = chan->cookie;
+	/*  Get number of bytes left in the active transactions */
+	bytes = atc_get_bytes_left(chan);
 
 	spin_unlock_irqrestore(&atchan->lock, flags);
 
-	if (ret != DMA_SUCCESS)
-		dma_set_residue(txstate, atc_first_active(atchan)->len);
-
-	if (atc_chan_is_paused(atchan))
-		ret = DMA_PAUSED;
+	if (unlikely(bytes < 0)) {
+		dev_vdbg(chan2dev(chan), "get residual bytes error\n");
+		return DMA_ERROR;
+	} else {
+		dma_set_residue(txstate, bytes);
+	}
 
-	dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d (d%d, u%d)\n",
-		 ret, cookie, last_complete ? last_complete : 0,
-		 last_used ? last_used : 0);
+	dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d residue = %d\n",
+		 ret, cookie, bytes);
 
 	return ret;
 }
@@ -1120,7 +1187,7 @@ static int atc_alloc_chan_resources(stru
 		 */
 		BUG_ON(!atslave->dma_dev || atslave->dma_dev != atdma->dma_common.dev);
 
-		/* if cfg configuration specified take it instad of default */
+		/* if cfg configuration specified take it instead of default */
 		if (atslave->cfg)
 			cfg = atslave->cfg;
 	}
@@ -1143,6 +1210,7 @@ static int atc_alloc_chan_resources(stru
 
 	spin_lock_irqsave(&atchan->lock, flags);
 	atchan->descs_allocated = i;
+	atchan->remain_desc = 0;
 	list_splice(&tmp_list, &atchan->free_list);
 	dma_cookie_init(chan);
 	spin_unlock_irqrestore(&atchan->lock, flags);
@@ -1185,6 +1253,7 @@ static void atc_free_chan_resources(stru
 	list_splice_init(&atchan->free_list, &list);
 	atchan->descs_allocated = 0;
 	atchan->status = 0;
+	atchan->remain_desc = 0;
 
 	dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
 }
@@ -1223,14 +1292,31 @@ static struct dma_chan *at_dma_xlate(str
 	atslave = devm_kzalloc(&dmac_pdev->dev, sizeof(*atslave), GFP_KERNEL);
 	if (!atslave)
 		return NULL;
+
+	atslave->cfg = ATC_DST_H2SEL_HW | ATC_SRC_H2SEL_HW;
 	/*
 	 * We can fill both SRC_PER and DST_PER, one of these fields will be
 	 * ignored depending on DMA transfer direction.
 	 */
-	per_id = dma_spec->args[1];
-	atslave->cfg = ATC_FIFOCFG_HALFFIFO | ATC_DST_H2SEL_HW
-		      | ATC_SRC_H2SEL_HW | ATC_DST_PER(per_id)
-		      | ATC_SRC_PER(per_id);
+	per_id = dma_spec->args[1] & AT91_DMA_CFG_PER_ID_MASK;
+	atslave->cfg |= ATC_DST_PER_MSB(per_id) | ATC_DST_PER(per_id)
+		     | ATC_SRC_PER_MSB(per_id) | ATC_SRC_PER(per_id);
+	/*
+	 * We have to translate the value we get from the device tree since
+	 * the half FIFO configuration value had to be 0 to keep backward
+	 * compatibility.
+	 */
+	switch (dma_spec->args[1] & AT91_DMA_CFG_FIFOCFG_MASK) {
+	case AT91_DMA_CFG_FIFOCFG_ALAP:
+		atslave->cfg |= ATC_FIFOCFG_LARGESTBURST;
+		break;
+	case AT91_DMA_CFG_FIFOCFG_ASAP:
+		atslave->cfg |= ATC_FIFOCFG_ENOUGHSPACE;
+		break;
+	case AT91_DMA_CFG_FIFOCFG_HALF:
+	default:
+		atslave->cfg |= ATC_FIFOCFG_HALFFIFO;
+	}
 	atslave->dma_dev = &dmac_pdev->dev;
 
 	chan = dma_request_channel(mask, at_dma_filter, atslave);
@@ -1374,7 +1460,9 @@ static int __init at_dma_probe(struct pl
 		err = PTR_ERR(atdma->clk);
 		goto err_clk;
 	}
-	clk_enable(atdma->clk);
+	err = clk_prepare_enable(atdma->clk);
+	if (err)
+		goto err_clk_prepare;
 
 	/* force dma off, just in case */
 	at_dma_off(atdma);
@@ -1472,10 +1560,10 @@ err_of_dma_controller_register:
 	dma_async_device_unregister(&atdma->dma_common);
 	dma_pool_destroy(atdma->dma_desc_pool);
 err_pool_create:
-	platform_set_drvdata(pdev, NULL);
 	free_irq(platform_get_irq(pdev, 0), atdma);
 err_irq:
-	clk_disable(atdma->clk);
+	clk_disable_unprepare(atdma->clk);
+err_clk_prepare:
 	clk_put(atdma->clk);
 err_clk:
 	iounmap(atdma->regs);
@@ -1497,7 +1585,6 @@ static int at_dma_remove(struct platform
 	dma_async_device_unregister(&atdma->dma_common);
 
 	dma_pool_destroy(atdma->dma_desc_pool);
-	platform_set_drvdata(pdev, NULL);
 	free_irq(platform_get_irq(pdev, 0), atdma);
 
 	list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
@@ -1512,7 +1599,7 @@ static int at_dma_remove(struct platform
 		list_del(&chan->device_node);
 	}
 
-	clk_disable(atdma->clk);
+	clk_disable_unprepare(atdma->clk);
 	clk_put(atdma->clk);
 
 	iounmap(atdma->regs);
@@ -1531,7 +1618,7 @@ static void at_dma_shutdown(struct platf
 	struct at_dma	*atdma = platform_get_drvdata(pdev);
 
 	at_dma_off(platform_get_drvdata(pdev));
-	clk_disable(atdma->clk);
+	clk_disable_unprepare(atdma->clk);
 }
 
 static int at_dma_prepare(struct device *dev)
@@ -1588,7 +1675,7 @@ static int at_dma_suspend_noirq(struct d
 
 	/* disable DMA controller */
 	at_dma_off(atdma);
-	clk_disable(atdma->clk);
+	clk_disable_unprepare(atdma->clk);
 	return 0;
 }
 
@@ -1618,7 +1705,7 @@ static int at_dma_resume_noirq(struct de
 	struct dma_chan *chan, *_chan;
 
 	/* bring back DMA controller */
-	clk_enable(atdma->clk);
+	clk_prepare_enable(atdma->clk);
 	dma_writel(atdma, EN, AT_DMA_ENABLE);
 
 	/* clear any pending interrupt */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/at_hdmac_regs.h linux-libre-3.11-rc7-gnu/drivers/dma/at_hdmac_regs.h
--- linux-libre-3.10-gnu/drivers/dma/at_hdmac_regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/at_hdmac_regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -182,6 +182,7 @@ struct at_lli {
  * @txd: support for the async_tx api
  * @desc_node: node on the channed descriptors list
  * @len: total transaction bytecount
+ * @tx_width: transfer width
  */
 struct at_desc {
 	/* FIRST values the hardware uses */
@@ -192,6 +193,7 @@ struct at_desc {
 	struct dma_async_tx_descriptor	txd;
 	struct list_head		desc_node;
 	size_t				len;
+	u32				tx_width;
 };
 
 static inline struct at_desc *
@@ -211,6 +213,7 @@ txd_to_at_desc(struct dma_async_tx_descr
 enum atc_status {
 	ATC_IS_ERROR = 0,
 	ATC_IS_PAUSED = 1,
+	ATC_IS_BTC = 2,
 	ATC_IS_CYCLIC = 24,
 };
 
@@ -228,6 +231,7 @@ enum atc_status {
  * @save_cfg: configuration register that is saved on suspend/resume cycle
  * @save_dscr: for cyclic operations, preserve next descriptor address in
  *             the cyclic list on suspend/resume cycle
+ * @remain_desc: to save remain desc length
  * @dma_sconfig: configuration for slave transfers, passed via DMA_SLAVE_CONFIG
  * @lock: serializes enqueue/dequeue operations to descriptors lists
  * @active_list: list of descriptors dmaengine is being running on
@@ -246,6 +250,7 @@ struct at_dma_chan {
 	struct tasklet_struct	tasklet;
 	u32			save_cfg;
 	u32			save_dscr;
+	u32			remain_desc;
 	struct dma_slave_config dma_sconfig;
 
 	spinlock_t		lock;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/coh901318.c linux-libre-3.11-rc7-gnu/drivers/dma/coh901318.c
--- linux-libre-3.10-gnu/drivers/dma/coh901318.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/coh901318.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/uaccess.h>
 #include <linux/debugfs.h>
 #include <linux/platform_data/dma-coh901318.h>
+#include <linux/of_dma.h>
 
 #include "coh901318.h"
 #include "dmaengine.h"
@@ -1788,6 +1789,35 @@ bool coh901318_filter_id(struct dma_chan
 }
 EXPORT_SYMBOL(coh901318_filter_id);
 
+struct coh901318_filter_args {
+	struct coh901318_base *base;
+	unsigned int ch_nr;
+};
+
+static bool coh901318_filter_base_and_id(struct dma_chan *chan, void *data)
+{
+	struct coh901318_filter_args *args = data;
+
+	if (&args->base->dma_slave == chan->device &&
+	    args->ch_nr == to_coh901318_chan(chan)->id)
+		return true;
+
+	return false;
+}
+
+static struct dma_chan *coh901318_xlate(struct of_phandle_args *dma_spec,
+					struct of_dma *ofdma)
+{
+	struct coh901318_filter_args args = {
+		.base = ofdma->of_dma_data,
+		.ch_nr = dma_spec->args[0],
+	};
+	dma_cap_mask_t cap;
+	dma_cap_zero(cap);
+	dma_cap_set(DMA_SLAVE, cap);
+
+	return dma_request_channel(cap, coh901318_filter_base_and_id, &args);
+}
 /*
  * DMA channel allocation
  */
@@ -2735,12 +2765,19 @@ static int __init coh901318_probe(struct
 	if (err)
 		goto err_register_memcpy;
 
+	err = of_dma_controller_register(pdev->dev.of_node, coh901318_xlate,
+					 base);
+	if (err)
+		goto err_register_of_dma;
+
 	platform_set_drvdata(pdev, base);
 	dev_info(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n",
 		(u32) base->virtbase);
 
 	return err;
 
+ err_register_of_dma:
+	dma_async_device_unregister(&base->dma_memcpy);
  err_register_memcpy:
 	dma_async_device_unregister(&base->dma_slave);
  err_register_slave:
@@ -2752,17 +2789,23 @@ static int coh901318_remove(struct platf
 {
 	struct coh901318_base *base = platform_get_drvdata(pdev);
 
+	of_dma_controller_free(pdev->dev.of_node);
 	dma_async_device_unregister(&base->dma_memcpy);
 	dma_async_device_unregister(&base->dma_slave);
 	coh901318_pool_destroy(&base->pool);
 	return 0;
 }
 
+static const struct of_device_id coh901318_dt_match[] = {
+	{ .compatible = "stericsson,coh901318" },
+	{},
+};
 
 static struct platform_driver coh901318_driver = {
 	.remove = coh901318_remove,
 	.driver = {
 		.name	= "coh901318",
+		.of_match_table = coh901318_dt_match,
 	},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dmaengine.c linux-libre-3.11-rc7-gnu/drivers/dma/dmaengine.c
--- linux-libre-3.10-gnu/drivers/dma/dmaengine.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dmaengine.c	2013-08-25 20:43:22.000000000 -0400
@@ -663,11 +663,6 @@ static bool device_has_all_tx_types(stru
 		return false;
 	#endif
 
-	#if defined(CONFIG_ASYNC_MEMSET) || defined(CONFIG_ASYNC_MEMSET_MODULE)
-	if (!dma_has_cap(DMA_MEMSET, device->cap_mask))
-		return false;
-	#endif
-
 	#if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE)
 	if (!dma_has_cap(DMA_XOR, device->cap_mask))
 		return false;
@@ -729,8 +724,6 @@ int dma_async_device_register(struct dma
 		!device->device_prep_dma_pq);
 	BUG_ON(dma_has_cap(DMA_PQ_VAL, device->cap_mask) &&
 		!device->device_prep_dma_pq_val);
-	BUG_ON(dma_has_cap(DMA_MEMSET, device->cap_mask) &&
-		!device->device_prep_dma_memset);
 	BUG_ON(dma_has_cap(DMA_INTERRUPT, device->cap_mask) &&
 		!device->device_prep_dma_interrupt);
 	BUG_ON(dma_has_cap(DMA_SG, device->cap_mask) &&
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dma-jz4740.c linux-libre-3.11-rc7-gnu/drivers/dma/dma-jz4740.c
--- linux-libre-3.10-gnu/drivers/dma/dma-jz4740.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dma-jz4740.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,617 @@
+/*
+ *  Copyright (C) 2013, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 DMAC support
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under  the terms of the GNU General	 Public License as published by the
+ *  Free Software Foundation;  either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+
+#include <asm/mach-jz4740/dma.h>
+
+#include "virt-dma.h"
+
+#define JZ_DMA_NR_CHANS 6
+
+#define JZ_REG_DMA_SRC_ADDR(x)		(0x00 + (x) * 0x20)
+#define JZ_REG_DMA_DST_ADDR(x)		(0x04 + (x) * 0x20)
+#define JZ_REG_DMA_TRANSFER_COUNT(x)	(0x08 + (x) * 0x20)
+#define JZ_REG_DMA_REQ_TYPE(x)		(0x0C + (x) * 0x20)
+#define JZ_REG_DMA_STATUS_CTRL(x)	(0x10 + (x) * 0x20)
+#define JZ_REG_DMA_CMD(x)		(0x14 + (x) * 0x20)
+#define JZ_REG_DMA_DESC_ADDR(x)		(0x18 + (x) * 0x20)
+
+#define JZ_REG_DMA_CTRL			0x300
+#define JZ_REG_DMA_IRQ			0x304
+#define JZ_REG_DMA_DOORBELL		0x308
+#define JZ_REG_DMA_DOORBELL_SET		0x30C
+
+#define JZ_DMA_STATUS_CTRL_NO_DESC		BIT(31)
+#define JZ_DMA_STATUS_CTRL_DESC_INV		BIT(6)
+#define JZ_DMA_STATUS_CTRL_ADDR_ERR		BIT(4)
+#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE	BIT(3)
+#define JZ_DMA_STATUS_CTRL_HALT			BIT(2)
+#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE	BIT(1)
+#define JZ_DMA_STATUS_CTRL_ENABLE		BIT(0)
+
+#define JZ_DMA_CMD_SRC_INC			BIT(23)
+#define JZ_DMA_CMD_DST_INC			BIT(22)
+#define JZ_DMA_CMD_RDIL_MASK			(0xf << 16)
+#define JZ_DMA_CMD_SRC_WIDTH_MASK		(0x3 << 14)
+#define JZ_DMA_CMD_DST_WIDTH_MASK		(0x3 << 12)
+#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK		(0x7 << 8)
+#define JZ_DMA_CMD_BLOCK_MODE			BIT(7)
+#define JZ_DMA_CMD_DESC_VALID			BIT(4)
+#define JZ_DMA_CMD_DESC_VALID_MODE		BIT(3)
+#define JZ_DMA_CMD_VALID_IRQ_ENABLE		BIT(2)
+#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE		BIT(1)
+#define JZ_DMA_CMD_LINK_ENABLE			BIT(0)
+
+#define JZ_DMA_CMD_FLAGS_OFFSET 22
+#define JZ_DMA_CMD_RDIL_OFFSET 16
+#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
+#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
+#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
+#define JZ_DMA_CMD_MODE_OFFSET 7
+
+#define JZ_DMA_CTRL_PRIORITY_MASK		(0x3 << 8)
+#define JZ_DMA_CTRL_HALT			BIT(3)
+#define JZ_DMA_CTRL_ADDRESS_ERROR		BIT(2)
+#define JZ_DMA_CTRL_ENABLE			BIT(0)
+
+enum jz4740_dma_width {
+	JZ4740_DMA_WIDTH_32BIT	= 0,
+	JZ4740_DMA_WIDTH_8BIT	= 1,
+	JZ4740_DMA_WIDTH_16BIT	= 2,
+};
+
+enum jz4740_dma_transfer_size {
+	JZ4740_DMA_TRANSFER_SIZE_4BYTE	= 0,
+	JZ4740_DMA_TRANSFER_SIZE_1BYTE	= 1,
+	JZ4740_DMA_TRANSFER_SIZE_2BYTE	= 2,
+	JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3,
+	JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4,
+};
+
+enum jz4740_dma_flags {
+	JZ4740_DMA_SRC_AUTOINC = 0x2,
+	JZ4740_DMA_DST_AUTOINC = 0x1,
+};
+
+enum jz4740_dma_mode {
+	JZ4740_DMA_MODE_SINGLE	= 0,
+	JZ4740_DMA_MODE_BLOCK	= 1,
+};
+
+struct jz4740_dma_sg {
+	dma_addr_t addr;
+	unsigned int len;
+};
+
+struct jz4740_dma_desc {
+	struct virt_dma_desc vdesc;
+
+	enum dma_transfer_direction direction;
+	bool cyclic;
+
+	unsigned int num_sgs;
+	struct jz4740_dma_sg sg[];
+};
+
+struct jz4740_dmaengine_chan {
+	struct virt_dma_chan vchan;
+	unsigned int id;
+
+	dma_addr_t fifo_addr;
+	unsigned int transfer_shift;
+
+	struct jz4740_dma_desc *desc;
+	unsigned int next_sg;
+};
+
+struct jz4740_dma_dev {
+	struct dma_device ddev;
+	void __iomem *base;
+	struct clk *clk;
+
+	struct jz4740_dmaengine_chan chan[JZ_DMA_NR_CHANS];
+};
+
+static struct jz4740_dma_dev *jz4740_dma_chan_get_dev(
+	struct jz4740_dmaengine_chan *chan)
+{
+	return container_of(chan->vchan.chan.device, struct jz4740_dma_dev,
+		ddev);
+}
+
+static struct jz4740_dmaengine_chan *to_jz4740_dma_chan(struct dma_chan *c)
+{
+	return container_of(c, struct jz4740_dmaengine_chan, vchan.chan);
+}
+
+static struct jz4740_dma_desc *to_jz4740_dma_desc(struct virt_dma_desc *vdesc)
+{
+	return container_of(vdesc, struct jz4740_dma_desc, vdesc);
+}
+
+static inline uint32_t jz4740_dma_read(struct jz4740_dma_dev *dmadev,
+	unsigned int reg)
+{
+	return readl(dmadev->base + reg);
+}
+
+static inline void jz4740_dma_write(struct jz4740_dma_dev *dmadev,
+	unsigned reg, uint32_t val)
+{
+	writel(val, dmadev->base + reg);
+}
+
+static inline void jz4740_dma_write_mask(struct jz4740_dma_dev *dmadev,
+	unsigned int reg, uint32_t val, uint32_t mask)
+{
+	uint32_t tmp;
+
+	tmp = jz4740_dma_read(dmadev, reg);
+	tmp &= ~mask;
+	tmp |= val;
+	jz4740_dma_write(dmadev, reg, tmp);
+}
+
+static struct jz4740_dma_desc *jz4740_dma_alloc_desc(unsigned int num_sgs)
+{
+	return kzalloc(sizeof(struct jz4740_dma_desc) +
+		sizeof(struct jz4740_dma_sg) * num_sgs, GFP_ATOMIC);
+}
+
+static enum jz4740_dma_width jz4740_dma_width(enum dma_slave_buswidth width)
+{
+	switch (width) {
+	case DMA_SLAVE_BUSWIDTH_1_BYTE:
+		return JZ4740_DMA_WIDTH_8BIT;
+	case DMA_SLAVE_BUSWIDTH_2_BYTES:
+		return JZ4740_DMA_WIDTH_16BIT;
+	case DMA_SLAVE_BUSWIDTH_4_BYTES:
+		return JZ4740_DMA_WIDTH_32BIT;
+	default:
+		return JZ4740_DMA_WIDTH_32BIT;
+	}
+}
+
+static enum jz4740_dma_transfer_size jz4740_dma_maxburst(u32 maxburst)
+{
+	if (maxburst <= 1)
+		return JZ4740_DMA_TRANSFER_SIZE_1BYTE;
+	else if (maxburst <= 3)
+		return JZ4740_DMA_TRANSFER_SIZE_2BYTE;
+	else if (maxburst <= 15)
+		return JZ4740_DMA_TRANSFER_SIZE_4BYTE;
+	else if (maxburst <= 31)
+		return JZ4740_DMA_TRANSFER_SIZE_16BYTE;
+
+	return JZ4740_DMA_TRANSFER_SIZE_32BYTE;
+}
+
+static int jz4740_dma_slave_config(struct dma_chan *c,
+	const struct dma_slave_config *config)
+{
+	struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
+	struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
+	enum jz4740_dma_width src_width;
+	enum jz4740_dma_width dst_width;
+	enum jz4740_dma_transfer_size transfer_size;
+	enum jz4740_dma_flags flags;
+	uint32_t cmd;
+
+	switch (config->direction) {
+	case DMA_MEM_TO_DEV:
+		flags = JZ4740_DMA_SRC_AUTOINC;
+		transfer_size = jz4740_dma_maxburst(config->dst_maxburst);
+		chan->fifo_addr = config->dst_addr;
+		break;
+	case DMA_DEV_TO_MEM:
+		flags = JZ4740_DMA_DST_AUTOINC;
+		transfer_size = jz4740_dma_maxburst(config->src_maxburst);
+		chan->fifo_addr = config->src_addr;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	src_width = jz4740_dma_width(config->src_addr_width);
+	dst_width = jz4740_dma_width(config->dst_addr_width);
+
+	switch (transfer_size) {
+	case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
+		chan->transfer_shift = 1;
+		break;
+	case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
+		chan->transfer_shift = 2;
+		break;
+	case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
+		chan->transfer_shift = 4;
+		break;
+	case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
+		chan->transfer_shift = 5;
+		break;
+	default:
+		chan->transfer_shift = 0;
+		break;
+	}
+
+	cmd = flags << JZ_DMA_CMD_FLAGS_OFFSET;
+	cmd |= src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
+	cmd |= dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
+	cmd |= transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
+	cmd |= JZ4740_DMA_MODE_SINGLE << JZ_DMA_CMD_MODE_OFFSET;
+	cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
+
+	jz4740_dma_write(dmadev, JZ_REG_DMA_CMD(chan->id), cmd);
+	jz4740_dma_write(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0);
+	jz4740_dma_write(dmadev, JZ_REG_DMA_REQ_TYPE(chan->id),
+		config->slave_id);
+
+	return 0;
+}
+
+static int jz4740_dma_terminate_all(struct dma_chan *c)
+{
+	struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
+	struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
+	unsigned long flags;
+	LIST_HEAD(head);
+
+	spin_lock_irqsave(&chan->vchan.lock, flags);
+	jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0,
+			JZ_DMA_STATUS_CTRL_ENABLE);
+	chan->desc = NULL;
+	vchan_get_all_descriptors(&chan->vchan, &head);
+	spin_unlock_irqrestore(&chan->vchan.lock, flags);
+
+	vchan_dma_desc_free_list(&chan->vchan, &head);
+
+	return 0;
+}
+
+static int jz4740_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+	unsigned long arg)
+{
+	struct dma_slave_config *config = (struct dma_slave_config *)arg;
+
+	switch (cmd) {
+	case DMA_SLAVE_CONFIG:
+		return jz4740_dma_slave_config(chan, config);
+	case DMA_TERMINATE_ALL:
+		return jz4740_dma_terminate_all(chan);
+	default:
+		return -ENOSYS;
+	}
+}
+
+static int jz4740_dma_start_transfer(struct jz4740_dmaengine_chan *chan)
+{
+	struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
+	dma_addr_t src_addr, dst_addr;
+	struct virt_dma_desc *vdesc;
+	struct jz4740_dma_sg *sg;
+
+	jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0,
+			JZ_DMA_STATUS_CTRL_ENABLE);
+
+	if (!chan->desc) {
+		vdesc = vchan_next_desc(&chan->vchan);
+		if (!vdesc)
+			return 0;
+		chan->desc = to_jz4740_dma_desc(vdesc);
+		chan->next_sg = 0;
+	}
+
+	if (chan->next_sg == chan->desc->num_sgs)
+		chan->next_sg = 0;
+
+	sg = &chan->desc->sg[chan->next_sg];
+
+	if (chan->desc->direction == DMA_MEM_TO_DEV) {
+		src_addr = sg->addr;
+		dst_addr = chan->fifo_addr;
+	} else {
+		src_addr = chan->fifo_addr;
+		dst_addr = sg->addr;
+	}
+	jz4740_dma_write(dmadev, JZ_REG_DMA_SRC_ADDR(chan->id), src_addr);
+	jz4740_dma_write(dmadev, JZ_REG_DMA_DST_ADDR(chan->id), dst_addr);
+	jz4740_dma_write(dmadev, JZ_REG_DMA_TRANSFER_COUNT(chan->id),
+			sg->len >> chan->transfer_shift);
+
+	chan->next_sg++;
+
+	jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id),
+			JZ_DMA_STATUS_CTRL_NO_DESC | JZ_DMA_STATUS_CTRL_ENABLE,
+			JZ_DMA_STATUS_CTRL_HALT | JZ_DMA_STATUS_CTRL_NO_DESC |
+			JZ_DMA_STATUS_CTRL_ENABLE);
+
+	jz4740_dma_write_mask(dmadev, JZ_REG_DMA_CTRL,
+			JZ_DMA_CTRL_ENABLE,
+			JZ_DMA_CTRL_HALT | JZ_DMA_CTRL_ENABLE);
+
+	return 0;
+}
+
+static void jz4740_dma_chan_irq(struct jz4740_dmaengine_chan *chan)
+{
+	spin_lock(&chan->vchan.lock);
+	if (chan->desc) {
+		if (chan->desc && chan->desc->cyclic) {
+			vchan_cyclic_callback(&chan->desc->vdesc);
+		} else {
+			if (chan->next_sg == chan->desc->num_sgs) {
+				chan->desc = NULL;
+				vchan_cookie_complete(&chan->desc->vdesc);
+			}
+		}
+	}
+	jz4740_dma_start_transfer(chan);
+	spin_unlock(&chan->vchan.lock);
+}
+
+static irqreturn_t jz4740_dma_irq(int irq, void *devid)
+{
+	struct jz4740_dma_dev *dmadev = devid;
+	uint32_t irq_status;
+	unsigned int i;
+
+	irq_status = readl(dmadev->base + JZ_REG_DMA_IRQ);
+
+	for (i = 0; i < 6; ++i) {
+		if (irq_status & (1 << i)) {
+			jz4740_dma_write_mask(dmadev,
+				JZ_REG_DMA_STATUS_CTRL(i), 0,
+				JZ_DMA_STATUS_CTRL_ENABLE |
+				JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
+
+			jz4740_dma_chan_irq(&dmadev->chan[i]);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void jz4740_dma_issue_pending(struct dma_chan *c)
+{
+	struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->vchan.lock, flags);
+	if (vchan_issue_pending(&chan->vchan) && !chan->desc)
+		jz4740_dma_start_transfer(chan);
+	spin_unlock_irqrestore(&chan->vchan.lock, flags);
+}
+
+static struct dma_async_tx_descriptor *jz4740_dma_prep_slave_sg(
+	struct dma_chan *c, struct scatterlist *sgl,
+	unsigned int sg_len, enum dma_transfer_direction direction,
+	unsigned long flags, void *context)
+{
+	struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
+	struct jz4740_dma_desc *desc;
+	struct scatterlist *sg;
+	unsigned int i;
+
+	desc = jz4740_dma_alloc_desc(sg_len);
+	if (!desc)
+		return NULL;
+
+	for_each_sg(sgl, sg, sg_len, i) {
+		desc->sg[i].addr = sg_dma_address(sg);
+		desc->sg[i].len = sg_dma_len(sg);
+	}
+
+	desc->num_sgs = sg_len;
+	desc->direction = direction;
+	desc->cyclic = false;
+
+	return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
+}
+
+static struct dma_async_tx_descriptor *jz4740_dma_prep_dma_cyclic(
+	struct dma_chan *c, dma_addr_t buf_addr, size_t buf_len,
+	size_t period_len, enum dma_transfer_direction direction,
+	unsigned long flags, void *context)
+{
+	struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
+	struct jz4740_dma_desc *desc;
+	unsigned int num_periods, i;
+
+	if (buf_len % period_len)
+		return NULL;
+
+	num_periods = buf_len / period_len;
+
+	desc = jz4740_dma_alloc_desc(num_periods);
+	if (!desc)
+		return NULL;
+
+	for (i = 0; i < num_periods; i++) {
+		desc->sg[i].addr = buf_addr;
+		desc->sg[i].len = period_len;
+		buf_addr += period_len;
+	}
+
+	desc->num_sgs = num_periods;
+	desc->direction = direction;
+	desc->cyclic = true;
+
+	return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags);
+}
+
+static size_t jz4740_dma_desc_residue(struct jz4740_dmaengine_chan *chan,
+	struct jz4740_dma_desc *desc, unsigned int next_sg)
+{
+	struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan);
+	unsigned int residue, count;
+	unsigned int i;
+
+	residue = 0;
+
+	for (i = next_sg; i < desc->num_sgs; i++)
+		residue += desc->sg[i].len;
+
+	if (next_sg != 0) {
+		count = jz4740_dma_read(dmadev,
+			JZ_REG_DMA_TRANSFER_COUNT(chan->id));
+		residue += count << chan->transfer_shift;
+	}
+
+	return residue;
+}
+
+static enum dma_status jz4740_dma_tx_status(struct dma_chan *c,
+	dma_cookie_t cookie, struct dma_tx_state *state)
+{
+	struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c);
+	struct virt_dma_desc *vdesc;
+	enum dma_status status;
+	unsigned long flags;
+
+	status = dma_cookie_status(c, cookie, state);
+	if (status == DMA_SUCCESS || !state)
+		return status;
+
+	spin_lock_irqsave(&chan->vchan.lock, flags);
+	vdesc = vchan_find_desc(&chan->vchan, cookie);
+	if (cookie == chan->desc->vdesc.tx.cookie) {
+		state->residue = jz4740_dma_desc_residue(chan, chan->desc,
+				chan->next_sg);
+	} else if (vdesc) {
+		state->residue = jz4740_dma_desc_residue(chan,
+				to_jz4740_dma_desc(vdesc), 0);
+	} else {
+		state->residue = 0;
+	}
+	spin_unlock_irqrestore(&chan->vchan.lock, flags);
+
+	return status;
+}
+
+static int jz4740_dma_alloc_chan_resources(struct dma_chan *c)
+{
+	return 0;
+}
+
+static void jz4740_dma_free_chan_resources(struct dma_chan *c)
+{
+	vchan_free_chan_resources(to_virt_chan(c));
+}
+
+static void jz4740_dma_desc_free(struct virt_dma_desc *vdesc)
+{
+	kfree(container_of(vdesc, struct jz4740_dma_desc, vdesc));
+}
+
+static int jz4740_dma_probe(struct platform_device *pdev)
+{
+	struct jz4740_dmaengine_chan *chan;
+	struct jz4740_dma_dev *dmadev;
+	struct dma_device *dd;
+	unsigned int i;
+	struct resource *res;
+	int ret;
+	int irq;
+
+	dmadev = devm_kzalloc(&pdev->dev, sizeof(*dmadev), GFP_KERNEL);
+	if (!dmadev)
+		return -EINVAL;
+
+	dd = &dmadev->ddev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dmadev->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dmadev->base))
+		return PTR_ERR(dmadev->base);
+
+	dmadev->clk = clk_get(&pdev->dev, "dma");
+	if (IS_ERR(dmadev->clk))
+		return PTR_ERR(dmadev->clk);
+
+	clk_prepare_enable(dmadev->clk);
+
+	dma_cap_set(DMA_SLAVE, dd->cap_mask);
+	dma_cap_set(DMA_CYCLIC, dd->cap_mask);
+	dd->device_alloc_chan_resources = jz4740_dma_alloc_chan_resources;
+	dd->device_free_chan_resources = jz4740_dma_free_chan_resources;
+	dd->device_tx_status = jz4740_dma_tx_status;
+	dd->device_issue_pending = jz4740_dma_issue_pending;
+	dd->device_prep_slave_sg = jz4740_dma_prep_slave_sg;
+	dd->device_prep_dma_cyclic = jz4740_dma_prep_dma_cyclic;
+	dd->device_control = jz4740_dma_control;
+	dd->dev = &pdev->dev;
+	dd->chancnt = JZ_DMA_NR_CHANS;
+	INIT_LIST_HEAD(&dd->channels);
+
+	for (i = 0; i < dd->chancnt; i++) {
+		chan = &dmadev->chan[i];
+		chan->id = i;
+		chan->vchan.desc_free = jz4740_dma_desc_free;
+		vchan_init(&chan->vchan, dd);
+	}
+
+	ret = dma_async_device_register(dd);
+	if (ret)
+		return ret;
+
+	irq = platform_get_irq(pdev, 0);
+	ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev);
+	if (ret)
+		goto err_unregister;
+
+	platform_set_drvdata(pdev, dmadev);
+
+	return 0;
+
+err_unregister:
+	dma_async_device_unregister(dd);
+	return ret;
+}
+
+static int jz4740_dma_remove(struct platform_device *pdev)
+{
+	struct jz4740_dma_dev *dmadev = platform_get_drvdata(pdev);
+	int irq = platform_get_irq(pdev, 0);
+
+	free_irq(irq, dmadev);
+	dma_async_device_unregister(&dmadev->ddev);
+	clk_disable_unprepare(dmadev->clk);
+
+	return 0;
+}
+
+static struct platform_driver jz4740_dma_driver = {
+	.probe = jz4740_dma_probe,
+	.remove = jz4740_dma_remove,
+	.driver = {
+		.name = "jz4740-dma",
+		.owner = THIS_MODULE,
+	},
+};
+module_platform_driver(jz4740_dma_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("JZ4740 DMA driver");
+MODULE_LICENSE("GPLv2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dw/core.c linux-libre-3.11-rc7-gnu/drivers/dma/dw/core.c
--- linux-libre-3.10-gnu/drivers/dma/dw/core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dw/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1730 @@
+/*
+ * Core driver for the Synopsys DesignWare DMA Controller
+ *
+ * Copyright (C) 2007-2008 Atmel Corporation
+ * Copyright (C) 2010-2011 ST Microelectronics
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "../dmaengine.h"
+#include "internal.h"
+
+/*
+ * This supports the Synopsys "DesignWare AHB Central DMA Controller",
+ * (DW_ahb_dmac) which is used with various AMBA 2.0 systems (not all
+ * of which use ARM any more).  See the "Databook" from Synopsys for
+ * information beyond what licensees probably provide.
+ *
+ * The driver has currently been tested only with the Atmel AT32AP7000,
+ * which does not support descriptor writeback.
+ */
+
+static inline void dwc_set_masters(struct dw_dma_chan *dwc)
+{
+	struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+	struct dw_dma_slave *dws = dwc->chan.private;
+	unsigned char mmax = dw->nr_masters - 1;
+
+	if (dwc->request_line == ~0) {
+		dwc->src_master = min_t(unsigned char, mmax, dwc_get_sms(dws));
+		dwc->dst_master = min_t(unsigned char, mmax, dwc_get_dms(dws));
+	}
+}
+
+#define DWC_DEFAULT_CTLLO(_chan) ({				\
+		struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan);	\
+		struct dma_slave_config	*_sconfig = &_dwc->dma_sconfig;	\
+		bool _is_slave = is_slave_direction(_dwc->direction);	\
+		u8 _smsize = _is_slave ? _sconfig->src_maxburst :	\
+			DW_DMA_MSIZE_16;			\
+		u8 _dmsize = _is_slave ? _sconfig->dst_maxburst :	\
+			DW_DMA_MSIZE_16;			\
+								\
+		(DWC_CTLL_DST_MSIZE(_dmsize)			\
+		 | DWC_CTLL_SRC_MSIZE(_smsize)			\
+		 | DWC_CTLL_LLP_D_EN				\
+		 | DWC_CTLL_LLP_S_EN				\
+		 | DWC_CTLL_DMS(_dwc->dst_master)		\
+		 | DWC_CTLL_SMS(_dwc->src_master));		\
+	})
+
+/*
+ * Number of descriptors to allocate for each channel. This should be
+ * made configurable somehow; preferably, the clients (at least the
+ * ones using slave transfers) should be able to give us a hint.
+ */
+#define NR_DESCS_PER_CHANNEL	64
+
+/*----------------------------------------------------------------------*/
+
+static struct device *chan2dev(struct dma_chan *chan)
+{
+	return &chan->dev->device;
+}
+static struct device *chan2parent(struct dma_chan *chan)
+{
+	return chan->dev->device.parent;
+}
+
+static struct dw_desc *dwc_first_active(struct dw_dma_chan *dwc)
+{
+	return to_dw_desc(dwc->active_list.next);
+}
+
+static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
+{
+	struct dw_desc *desc, *_desc;
+	struct dw_desc *ret = NULL;
+	unsigned int i = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) {
+		i++;
+		if (async_tx_test_ack(&desc->txd)) {
+			list_del(&desc->desc_node);
+			ret = desc;
+			break;
+		}
+		dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc);
+	}
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i);
+
+	return ret;
+}
+
+/*
+ * Move a descriptor, including any children, to the free list.
+ * `desc' must not be on any lists.
+ */
+static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
+{
+	unsigned long flags;
+
+	if (desc) {
+		struct dw_desc *child;
+
+		spin_lock_irqsave(&dwc->lock, flags);
+		list_for_each_entry(child, &desc->tx_list, desc_node)
+			dev_vdbg(chan2dev(&dwc->chan),
+					"moving child desc %p to freelist\n",
+					child);
+		list_splice_init(&desc->tx_list, &dwc->free_list);
+		dev_vdbg(chan2dev(&dwc->chan), "moving desc %p to freelist\n", desc);
+		list_add(&desc->desc_node, &dwc->free_list);
+		spin_unlock_irqrestore(&dwc->lock, flags);
+	}
+}
+
+static void dwc_initialize(struct dw_dma_chan *dwc)
+{
+	struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+	struct dw_dma_slave *dws = dwc->chan.private;
+	u32 cfghi = DWC_CFGH_FIFO_MODE;
+	u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
+
+	if (dwc->initialized == true)
+		return;
+
+	if (dws) {
+		/*
+		 * We need controller-specific data to set up slave
+		 * transfers.
+		 */
+		BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
+
+		cfghi = dws->cfg_hi;
+		cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK;
+	} else {
+		if (dwc->direction == DMA_MEM_TO_DEV)
+			cfghi = DWC_CFGH_DST_PER(dwc->request_line);
+		else if (dwc->direction == DMA_DEV_TO_MEM)
+			cfghi = DWC_CFGH_SRC_PER(dwc->request_line);
+	}
+
+	channel_writel(dwc, CFG_LO, cfglo);
+	channel_writel(dwc, CFG_HI, cfghi);
+
+	/* Enable interrupts */
+	channel_set_bit(dw, MASK.XFER, dwc->mask);
+	channel_set_bit(dw, MASK.ERROR, dwc->mask);
+
+	dwc->initialized = true;
+}
+
+/*----------------------------------------------------------------------*/
+
+static inline unsigned int dwc_fast_fls(unsigned long long v)
+{
+	/*
+	 * We can be a lot more clever here, but this should take care
+	 * of the most common optimization.
+	 */
+	if (!(v & 7))
+		return 3;
+	else if (!(v & 3))
+		return 2;
+	else if (!(v & 1))
+		return 1;
+	return 0;
+}
+
+static inline void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
+{
+	dev_err(chan2dev(&dwc->chan),
+		"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+		channel_readl(dwc, SAR),
+		channel_readl(dwc, DAR),
+		channel_readl(dwc, LLP),
+		channel_readl(dwc, CTL_HI),
+		channel_readl(dwc, CTL_LO));
+}
+
+static inline void dwc_chan_disable(struct dw_dma *dw, struct dw_dma_chan *dwc)
+{
+	channel_clear_bit(dw, CH_EN, dwc->mask);
+	while (dma_readl(dw, CH_EN) & dwc->mask)
+		cpu_relax();
+}
+
+/*----------------------------------------------------------------------*/
+
+/* Perform single block transfer */
+static inline void dwc_do_single_block(struct dw_dma_chan *dwc,
+				       struct dw_desc *desc)
+{
+	struct dw_dma	*dw = to_dw_dma(dwc->chan.device);
+	u32		ctllo;
+
+	/* Software emulation of LLP mode relies on interrupts to continue
+	 * multi block transfer. */
+	ctllo = desc->lli.ctllo | DWC_CTLL_INT_EN;
+
+	channel_writel(dwc, SAR, desc->lli.sar);
+	channel_writel(dwc, DAR, desc->lli.dar);
+	channel_writel(dwc, CTL_LO, ctllo);
+	channel_writel(dwc, CTL_HI, desc->lli.ctlhi);
+	channel_set_bit(dw, CH_EN, dwc->mask);
+
+	/* Move pointer to next descriptor */
+	dwc->tx_node_active = dwc->tx_node_active->next;
+}
+
+/* Called with dwc->lock held and bh disabled */
+static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
+{
+	struct dw_dma	*dw = to_dw_dma(dwc->chan.device);
+	unsigned long	was_soft_llp;
+
+	/* ASSERT:  channel is idle */
+	if (dma_readl(dw, CH_EN) & dwc->mask) {
+		dev_err(chan2dev(&dwc->chan),
+			"BUG: Attempted to start non-idle channel\n");
+		dwc_dump_chan_regs(dwc);
+
+		/* The tasklet will hopefully advance the queue... */
+		return;
+	}
+
+	if (dwc->nollp) {
+		was_soft_llp = test_and_set_bit(DW_DMA_IS_SOFT_LLP,
+						&dwc->flags);
+		if (was_soft_llp) {
+			dev_err(chan2dev(&dwc->chan),
+				"BUG: Attempted to start new LLP transfer "
+				"inside ongoing one\n");
+			return;
+		}
+
+		dwc_initialize(dwc);
+
+		dwc->residue = first->total_len;
+		dwc->tx_node_active = &first->tx_list;
+
+		/* Submit first block */
+		dwc_do_single_block(dwc, first);
+
+		return;
+	}
+
+	dwc_initialize(dwc);
+
+	channel_writel(dwc, LLP, first->txd.phys);
+	channel_writel(dwc, CTL_LO,
+			DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
+	channel_writel(dwc, CTL_HI, 0);
+	channel_set_bit(dw, CH_EN, dwc->mask);
+}
+
+/*----------------------------------------------------------------------*/
+
+static void
+dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
+		bool callback_required)
+{
+	dma_async_tx_callback		callback = NULL;
+	void				*param = NULL;
+	struct dma_async_tx_descriptor	*txd = &desc->txd;
+	struct dw_desc			*child;
+	unsigned long			flags;
+
+	dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	dma_cookie_complete(txd);
+	if (callback_required) {
+		callback = txd->callback;
+		param = txd->callback_param;
+	}
+
+	/* async_tx_ack */
+	list_for_each_entry(child, &desc->tx_list, desc_node)
+		async_tx_ack(&child->txd);
+	async_tx_ack(&desc->txd);
+
+	list_splice_init(&desc->tx_list, &dwc->free_list);
+	list_move(&desc->desc_node, &dwc->free_list);
+
+	if (!is_slave_direction(dwc->direction)) {
+		struct device *parent = chan2parent(&dwc->chan);
+		if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+			if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
+				dma_unmap_single(parent, desc->lli.dar,
+					desc->total_len, DMA_FROM_DEVICE);
+			else
+				dma_unmap_page(parent, desc->lli.dar,
+					desc->total_len, DMA_FROM_DEVICE);
+		}
+		if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+			if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
+				dma_unmap_single(parent, desc->lli.sar,
+					desc->total_len, DMA_TO_DEVICE);
+			else
+				dma_unmap_page(parent, desc->lli.sar,
+					desc->total_len, DMA_TO_DEVICE);
+		}
+	}
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	if (callback)
+		callback(param);
+}
+
+static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
+{
+	struct dw_desc *desc, *_desc;
+	LIST_HEAD(list);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	if (dma_readl(dw, CH_EN) & dwc->mask) {
+		dev_err(chan2dev(&dwc->chan),
+			"BUG: XFER bit set, but channel not idle!\n");
+
+		/* Try to continue after resetting the channel... */
+		dwc_chan_disable(dw, dwc);
+	}
+
+	/*
+	 * Submit queued descriptors ASAP, i.e. before we go through
+	 * the completed ones.
+	 */
+	list_splice_init(&dwc->active_list, &list);
+	if (!list_empty(&dwc->queue)) {
+		list_move(dwc->queue.next, &dwc->active_list);
+		dwc_dostart(dwc, dwc_first_active(dwc));
+	}
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	list_for_each_entry_safe(desc, _desc, &list, desc_node)
+		dwc_descriptor_complete(dwc, desc, true);
+}
+
+/* Returns how many bytes were already received from source */
+static inline u32 dwc_get_sent(struct dw_dma_chan *dwc)
+{
+	u32 ctlhi = channel_readl(dwc, CTL_HI);
+	u32 ctllo = channel_readl(dwc, CTL_LO);
+
+	return (ctlhi & DWC_CTLH_BLOCK_TS_MASK) * (1 << (ctllo >> 4 & 7));
+}
+
+static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
+{
+	dma_addr_t llp;
+	struct dw_desc *desc, *_desc;
+	struct dw_desc *child;
+	u32 status_xfer;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	llp = channel_readl(dwc, LLP);
+	status_xfer = dma_readl(dw, RAW.XFER);
+
+	if (status_xfer & dwc->mask) {
+		/* Everything we've submitted is done */
+		dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+		if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
+			struct list_head *head, *active = dwc->tx_node_active;
+
+			/*
+			 * We are inside first active descriptor.
+			 * Otherwise something is really wrong.
+			 */
+			desc = dwc_first_active(dwc);
+
+			head = &desc->tx_list;
+			if (active != head) {
+				/* Update desc to reflect last sent one */
+				if (active != head->next)
+					desc = to_dw_desc(active->prev);
+
+				dwc->residue -= desc->len;
+
+				child = to_dw_desc(active);
+
+				/* Submit next block */
+				dwc_do_single_block(dwc, child);
+
+				spin_unlock_irqrestore(&dwc->lock, flags);
+				return;
+			}
+
+			/* We are done here */
+			clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+		}
+
+		dwc->residue = 0;
+
+		spin_unlock_irqrestore(&dwc->lock, flags);
+
+		dwc_complete_all(dw, dwc);
+		return;
+	}
+
+	if (list_empty(&dwc->active_list)) {
+		dwc->residue = 0;
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		return;
+	}
+
+	if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
+		dev_vdbg(chan2dev(&dwc->chan), "%s: soft LLP mode\n", __func__);
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		return;
+	}
+
+	dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__,
+			(unsigned long long)llp);
+
+	list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
+		/* Initial residue value */
+		dwc->residue = desc->total_len;
+
+		/* Check first descriptors addr */
+		if (desc->txd.phys == llp) {
+			spin_unlock_irqrestore(&dwc->lock, flags);
+			return;
+		}
+
+		/* Check first descriptors llp */
+		if (desc->lli.llp == llp) {
+			/* This one is currently in progress */
+			dwc->residue -= dwc_get_sent(dwc);
+			spin_unlock_irqrestore(&dwc->lock, flags);
+			return;
+		}
+
+		dwc->residue -= desc->len;
+		list_for_each_entry(child, &desc->tx_list, desc_node) {
+			if (child->lli.llp == llp) {
+				/* Currently in progress */
+				dwc->residue -= dwc_get_sent(dwc);
+				spin_unlock_irqrestore(&dwc->lock, flags);
+				return;
+			}
+			dwc->residue -= child->len;
+		}
+
+		/*
+		 * No descriptors so far seem to be in progress, i.e.
+		 * this one must be done.
+		 */
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		dwc_descriptor_complete(dwc, desc, true);
+		spin_lock_irqsave(&dwc->lock, flags);
+	}
+
+	dev_err(chan2dev(&dwc->chan),
+		"BUG: All descriptors done, but channel not idle!\n");
+
+	/* Try to continue after resetting the channel... */
+	dwc_chan_disable(dw, dwc);
+
+	if (!list_empty(&dwc->queue)) {
+		list_move(dwc->queue.next, &dwc->active_list);
+		dwc_dostart(dwc, dwc_first_active(dwc));
+	}
+	spin_unlock_irqrestore(&dwc->lock, flags);
+}
+
+static inline void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
+{
+	dev_crit(chan2dev(&dwc->chan), "  desc: s0x%x d0x%x l0x%x c0x%x:%x\n",
+		 lli->sar, lli->dar, lli->llp, lli->ctlhi, lli->ctllo);
+}
+
+static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
+{
+	struct dw_desc *bad_desc;
+	struct dw_desc *child;
+	unsigned long flags;
+
+	dwc_scan_descriptors(dw, dwc);
+
+	spin_lock_irqsave(&dwc->lock, flags);
+
+	/*
+	 * The descriptor currently at the head of the active list is
+	 * borked. Since we don't have any way to report errors, we'll
+	 * just have to scream loudly and try to carry on.
+	 */
+	bad_desc = dwc_first_active(dwc);
+	list_del_init(&bad_desc->desc_node);
+	list_move(dwc->queue.next, dwc->active_list.prev);
+
+	/* Clear the error flag and try to restart the controller */
+	dma_writel(dw, CLEAR.ERROR, dwc->mask);
+	if (!list_empty(&dwc->active_list))
+		dwc_dostart(dwc, dwc_first_active(dwc));
+
+	/*
+	 * WARN may seem harsh, but since this only happens
+	 * when someone submits a bad physical address in a
+	 * descriptor, we should consider ourselves lucky that the
+	 * controller flagged an error instead of scribbling over
+	 * random memory locations.
+	 */
+	dev_WARN(chan2dev(&dwc->chan), "Bad descriptor submitted for DMA!\n"
+				       "  cookie: %d\n", bad_desc->txd.cookie);
+	dwc_dump_lli(dwc, &bad_desc->lli);
+	list_for_each_entry(child, &bad_desc->tx_list, desc_node)
+		dwc_dump_lli(dwc, &child->lli);
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	/* Pretend the descriptor completed successfully */
+	dwc_descriptor_complete(dwc, bad_desc, true);
+}
+
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	return channel_readl(dwc, SAR);
+}
+EXPORT_SYMBOL(dw_dma_get_src_addr);
+
+dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	return channel_readl(dwc, DAR);
+}
+EXPORT_SYMBOL(dw_dma_get_dst_addr);
+
+/* Called with dwc->lock held and all DMAC interrupts disabled */
+static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
+		u32 status_err, u32 status_xfer)
+{
+	unsigned long flags;
+
+	if (dwc->mask) {
+		void (*callback)(void *param);
+		void *callback_param;
+
+		dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n",
+				channel_readl(dwc, LLP));
+
+		callback = dwc->cdesc->period_callback;
+		callback_param = dwc->cdesc->period_callback_param;
+
+		if (callback)
+			callback(callback_param);
+	}
+
+	/*
+	 * Error and transfer complete are highly unlikely, and will most
+	 * likely be due to a configuration error by the user.
+	 */
+	if (unlikely(status_err & dwc->mask) ||
+			unlikely(status_xfer & dwc->mask)) {
+		int i;
+
+		dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
+				"interrupt, stopping DMA transfer\n",
+				status_xfer ? "xfer" : "error");
+
+		spin_lock_irqsave(&dwc->lock, flags);
+
+		dwc_dump_chan_regs(dwc);
+
+		dwc_chan_disable(dw, dwc);
+
+		/* Make sure DMA does not restart by loading a new list */
+		channel_writel(dwc, LLP, 0);
+		channel_writel(dwc, CTL_LO, 0);
+		channel_writel(dwc, CTL_HI, 0);
+
+		dma_writel(dw, CLEAR.ERROR, dwc->mask);
+		dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+		for (i = 0; i < dwc->cdesc->periods; i++)
+			dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
+
+		spin_unlock_irqrestore(&dwc->lock, flags);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void dw_dma_tasklet(unsigned long data)
+{
+	struct dw_dma *dw = (struct dw_dma *)data;
+	struct dw_dma_chan *dwc;
+	u32 status_xfer;
+	u32 status_err;
+	int i;
+
+	status_xfer = dma_readl(dw, RAW.XFER);
+	status_err = dma_readl(dw, RAW.ERROR);
+
+	dev_vdbg(dw->dma.dev, "%s: status_err=%x\n", __func__, status_err);
+
+	for (i = 0; i < dw->dma.chancnt; i++) {
+		dwc = &dw->chan[i];
+		if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
+			dwc_handle_cyclic(dw, dwc, status_err, status_xfer);
+		else if (status_err & (1 << i))
+			dwc_handle_error(dw, dwc);
+		else if (status_xfer & (1 << i))
+			dwc_scan_descriptors(dw, dwc);
+	}
+
+	/*
+	 * Re-enable interrupts.
+	 */
+	channel_set_bit(dw, MASK.XFER, dw->all_chan_mask);
+	channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask);
+}
+
+static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
+{
+	struct dw_dma *dw = dev_id;
+	u32 status;
+
+	dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__,
+			dma_readl(dw, STATUS_INT));
+
+	/*
+	 * Just disable the interrupts. We'll turn them back on in the
+	 * softirq handler.
+	 */
+	channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
+
+	status = dma_readl(dw, STATUS_INT);
+	if (status) {
+		dev_err(dw->dma.dev,
+			"BUG: Unexpected interrupts pending: 0x%x\n",
+			status);
+
+		/* Try to recover */
+		channel_clear_bit(dw, MASK.XFER, (1 << 8) - 1);
+		channel_clear_bit(dw, MASK.SRC_TRAN, (1 << 8) - 1);
+		channel_clear_bit(dw, MASK.DST_TRAN, (1 << 8) - 1);
+		channel_clear_bit(dw, MASK.ERROR, (1 << 8) - 1);
+	}
+
+	tasklet_schedule(&dw->tasklet);
+
+	return IRQ_HANDLED;
+}
+
+/*----------------------------------------------------------------------*/
+
+static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct dw_desc		*desc = txd_to_dw_desc(tx);
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(tx->chan);
+	dma_cookie_t		cookie;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	cookie = dma_cookie_assign(tx);
+
+	/*
+	 * REVISIT: We should attempt to chain as many descriptors as
+	 * possible, perhaps even appending to those already submitted
+	 * for DMA. But this is hard to do in a race-free manner.
+	 */
+	if (list_empty(&dwc->active_list)) {
+		dev_vdbg(chan2dev(tx->chan), "%s: started %u\n", __func__,
+				desc->txd.cookie);
+		list_add_tail(&desc->desc_node, &dwc->active_list);
+		dwc_dostart(dwc, dwc_first_active(dwc));
+	} else {
+		dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", __func__,
+				desc->txd.cookie);
+
+		list_add_tail(&desc->desc_node, &dwc->queue);
+	}
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return cookie;
+}
+
+static struct dma_async_tx_descriptor *
+dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+		size_t len, unsigned long flags)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(chan->device);
+	struct dw_desc		*desc;
+	struct dw_desc		*first;
+	struct dw_desc		*prev;
+	size_t			xfer_count;
+	size_t			offset;
+	unsigned int		src_width;
+	unsigned int		dst_width;
+	unsigned int		data_width;
+	u32			ctllo;
+
+	dev_vdbg(chan2dev(chan),
+			"%s: d0x%llx s0x%llx l0x%zx f0x%lx\n", __func__,
+			(unsigned long long)dest, (unsigned long long)src,
+			len, flags);
+
+	if (unlikely(!len)) {
+		dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
+		return NULL;
+	}
+
+	dwc->direction = DMA_MEM_TO_MEM;
+
+	data_width = min_t(unsigned int, dw->data_width[dwc->src_master],
+			   dw->data_width[dwc->dst_master]);
+
+	src_width = dst_width = min_t(unsigned int, data_width,
+				      dwc_fast_fls(src | dest | len));
+
+	ctllo = DWC_DEFAULT_CTLLO(chan)
+			| DWC_CTLL_DST_WIDTH(dst_width)
+			| DWC_CTLL_SRC_WIDTH(src_width)
+			| DWC_CTLL_DST_INC
+			| DWC_CTLL_SRC_INC
+			| DWC_CTLL_FC_M2M;
+	prev = first = NULL;
+
+	for (offset = 0; offset < len; offset += xfer_count << src_width) {
+		xfer_count = min_t(size_t, (len - offset) >> src_width,
+					   dwc->block_size);
+
+		desc = dwc_desc_get(dwc);
+		if (!desc)
+			goto err_desc_get;
+
+		desc->lli.sar = src + offset;
+		desc->lli.dar = dest + offset;
+		desc->lli.ctllo = ctllo;
+		desc->lli.ctlhi = xfer_count;
+		desc->len = xfer_count << src_width;
+
+		if (!first) {
+			first = desc;
+		} else {
+			prev->lli.llp = desc->txd.phys;
+			list_add_tail(&desc->desc_node,
+					&first->tx_list);
+		}
+		prev = desc;
+	}
+
+	if (flags & DMA_PREP_INTERRUPT)
+		/* Trigger interrupt after last block */
+		prev->lli.ctllo |= DWC_CTLL_INT_EN;
+
+	prev->lli.llp = 0;
+	first->txd.flags = flags;
+	first->total_len = len;
+
+	return &first->txd;
+
+err_desc_get:
+	dwc_desc_put(dwc, first);
+	return NULL;
+}
+
+static struct dma_async_tx_descriptor *
+dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+		unsigned int sg_len, enum dma_transfer_direction direction,
+		unsigned long flags, void *context)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(chan->device);
+	struct dma_slave_config	*sconfig = &dwc->dma_sconfig;
+	struct dw_desc		*prev;
+	struct dw_desc		*first;
+	u32			ctllo;
+	dma_addr_t		reg;
+	unsigned int		reg_width;
+	unsigned int		mem_width;
+	unsigned int		data_width;
+	unsigned int		i;
+	struct scatterlist	*sg;
+	size_t			total_len = 0;
+
+	dev_vdbg(chan2dev(chan), "%s\n", __func__);
+
+	if (unlikely(!is_slave_direction(direction) || !sg_len))
+		return NULL;
+
+	dwc->direction = direction;
+
+	prev = first = NULL;
+
+	switch (direction) {
+	case DMA_MEM_TO_DEV:
+		reg_width = __fls(sconfig->dst_addr_width);
+		reg = sconfig->dst_addr;
+		ctllo = (DWC_DEFAULT_CTLLO(chan)
+				| DWC_CTLL_DST_WIDTH(reg_width)
+				| DWC_CTLL_DST_FIX
+				| DWC_CTLL_SRC_INC);
+
+		ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
+			DWC_CTLL_FC(DW_DMA_FC_D_M2P);
+
+		data_width = dw->data_width[dwc->src_master];
+
+		for_each_sg(sgl, sg, sg_len, i) {
+			struct dw_desc	*desc;
+			u32		len, dlen, mem;
+
+			mem = sg_dma_address(sg);
+			len = sg_dma_len(sg);
+
+			mem_width = min_t(unsigned int,
+					  data_width, dwc_fast_fls(mem | len));
+
+slave_sg_todev_fill_desc:
+			desc = dwc_desc_get(dwc);
+			if (!desc) {
+				dev_err(chan2dev(chan),
+					"not enough descriptors available\n");
+				goto err_desc_get;
+			}
+
+			desc->lli.sar = mem;
+			desc->lli.dar = reg;
+			desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
+			if ((len >> mem_width) > dwc->block_size) {
+				dlen = dwc->block_size << mem_width;
+				mem += dlen;
+				len -= dlen;
+			} else {
+				dlen = len;
+				len = 0;
+			}
+
+			desc->lli.ctlhi = dlen >> mem_width;
+			desc->len = dlen;
+
+			if (!first) {
+				first = desc;
+			} else {
+				prev->lli.llp = desc->txd.phys;
+				list_add_tail(&desc->desc_node,
+						&first->tx_list);
+			}
+			prev = desc;
+			total_len += dlen;
+
+			if (len)
+				goto slave_sg_todev_fill_desc;
+		}
+		break;
+	case DMA_DEV_TO_MEM:
+		reg_width = __fls(sconfig->src_addr_width);
+		reg = sconfig->src_addr;
+		ctllo = (DWC_DEFAULT_CTLLO(chan)
+				| DWC_CTLL_SRC_WIDTH(reg_width)
+				| DWC_CTLL_DST_INC
+				| DWC_CTLL_SRC_FIX);
+
+		ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
+			DWC_CTLL_FC(DW_DMA_FC_D_P2M);
+
+		data_width = dw->data_width[dwc->dst_master];
+
+		for_each_sg(sgl, sg, sg_len, i) {
+			struct dw_desc	*desc;
+			u32		len, dlen, mem;
+
+			mem = sg_dma_address(sg);
+			len = sg_dma_len(sg);
+
+			mem_width = min_t(unsigned int,
+					  data_width, dwc_fast_fls(mem | len));
+
+slave_sg_fromdev_fill_desc:
+			desc = dwc_desc_get(dwc);
+			if (!desc) {
+				dev_err(chan2dev(chan),
+						"not enough descriptors available\n");
+				goto err_desc_get;
+			}
+
+			desc->lli.sar = reg;
+			desc->lli.dar = mem;
+			desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
+			if ((len >> reg_width) > dwc->block_size) {
+				dlen = dwc->block_size << reg_width;
+				mem += dlen;
+				len -= dlen;
+			} else {
+				dlen = len;
+				len = 0;
+			}
+			desc->lli.ctlhi = dlen >> reg_width;
+			desc->len = dlen;
+
+			if (!first) {
+				first = desc;
+			} else {
+				prev->lli.llp = desc->txd.phys;
+				list_add_tail(&desc->desc_node,
+						&first->tx_list);
+			}
+			prev = desc;
+			total_len += dlen;
+
+			if (len)
+				goto slave_sg_fromdev_fill_desc;
+		}
+		break;
+	default:
+		return NULL;
+	}
+
+	if (flags & DMA_PREP_INTERRUPT)
+		/* Trigger interrupt after last block */
+		prev->lli.ctllo |= DWC_CTLL_INT_EN;
+
+	prev->lli.llp = 0;
+	first->total_len = total_len;
+
+	return &first->txd;
+
+err_desc_get:
+	dwc_desc_put(dwc, first);
+	return NULL;
+}
+
+/*
+ * Fix sconfig's burst size according to dw_dmac. We need to convert them as:
+ * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
+ *
+ * NOTE: burst size 2 is not supported by controller.
+ *
+ * This can be done by finding least significant bit set: n & (n - 1)
+ */
+static inline void convert_burst(u32 *maxburst)
+{
+	if (*maxburst > 1)
+		*maxburst = fls(*maxburst) - 2;
+	else
+		*maxburst = 0;
+}
+
+static int
+set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+
+	/* Check if chan will be configured for slave transfers */
+	if (!is_slave_direction(sconfig->direction))
+		return -EINVAL;
+
+	memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
+	dwc->direction = sconfig->direction;
+
+	/* Take the request line from slave_id member */
+	if (dwc->request_line == ~0)
+		dwc->request_line = sconfig->slave_id;
+
+	convert_burst(&dwc->dma_sconfig.src_maxburst);
+	convert_burst(&dwc->dma_sconfig.dst_maxburst);
+
+	return 0;
+}
+
+static inline void dwc_chan_pause(struct dw_dma_chan *dwc)
+{
+	u32 cfglo = channel_readl(dwc, CFG_LO);
+	unsigned int count = 20;	/* timeout iterations */
+
+	channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP);
+	while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY) && count--)
+		udelay(2);
+
+	dwc->paused = true;
+}
+
+static inline void dwc_chan_resume(struct dw_dma_chan *dwc)
+{
+	u32 cfglo = channel_readl(dwc, CFG_LO);
+
+	channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP);
+
+	dwc->paused = false;
+}
+
+static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+		       unsigned long arg)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(chan->device);
+	struct dw_desc		*desc, *_desc;
+	unsigned long		flags;
+	LIST_HEAD(list);
+
+	if (cmd == DMA_PAUSE) {
+		spin_lock_irqsave(&dwc->lock, flags);
+
+		dwc_chan_pause(dwc);
+
+		spin_unlock_irqrestore(&dwc->lock, flags);
+	} else if (cmd == DMA_RESUME) {
+		if (!dwc->paused)
+			return 0;
+
+		spin_lock_irqsave(&dwc->lock, flags);
+
+		dwc_chan_resume(dwc);
+
+		spin_unlock_irqrestore(&dwc->lock, flags);
+	} else if (cmd == DMA_TERMINATE_ALL) {
+		spin_lock_irqsave(&dwc->lock, flags);
+
+		clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+
+		dwc_chan_disable(dw, dwc);
+
+		dwc_chan_resume(dwc);
+
+		/* active_list entries will end up before queued entries */
+		list_splice_init(&dwc->queue, &list);
+		list_splice_init(&dwc->active_list, &list);
+
+		spin_unlock_irqrestore(&dwc->lock, flags);
+
+		/* Flush all pending and queued descriptors */
+		list_for_each_entry_safe(desc, _desc, &list, desc_node)
+			dwc_descriptor_complete(dwc, desc, false);
+	} else if (cmd == DMA_SLAVE_CONFIG) {
+		return set_runtime_config(chan, (struct dma_slave_config *)arg);
+	} else {
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static inline u32 dwc_get_residue(struct dw_dma_chan *dwc)
+{
+	unsigned long flags;
+	u32 residue;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+
+	residue = dwc->residue;
+	if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags) && residue)
+		residue -= dwc_get_sent(dwc);
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+	return residue;
+}
+
+static enum dma_status
+dwc_tx_status(struct dma_chan *chan,
+	      dma_cookie_t cookie,
+	      struct dma_tx_state *txstate)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	enum dma_status		ret;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret != DMA_SUCCESS) {
+		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
+
+		ret = dma_cookie_status(chan, cookie, txstate);
+	}
+
+	if (ret != DMA_SUCCESS)
+		dma_set_residue(txstate, dwc_get_residue(dwc));
+
+	if (dwc->paused)
+		return DMA_PAUSED;
+
+	return ret;
+}
+
+static void dwc_issue_pending(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+
+	if (!list_empty(&dwc->queue))
+		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
+}
+
+static int dwc_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(chan->device);
+	struct dw_desc		*desc;
+	int			i;
+	unsigned long		flags;
+
+	dev_vdbg(chan2dev(chan), "%s\n", __func__);
+
+	/* ASSERT:  channel is idle */
+	if (dma_readl(dw, CH_EN) & dwc->mask) {
+		dev_dbg(chan2dev(chan), "DMA channel not idle?\n");
+		return -EIO;
+	}
+
+	dma_cookie_init(chan);
+
+	/*
+	 * NOTE: some controllers may have additional features that we
+	 * need to initialize here, like "scatter-gather" (which
+	 * doesn't mean what you think it means), and status writeback.
+	 */
+
+	dwc_set_masters(dwc);
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	i = dwc->descs_allocated;
+	while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) {
+		dma_addr_t phys;
+
+		spin_unlock_irqrestore(&dwc->lock, flags);
+
+		desc = dma_pool_alloc(dw->desc_pool, GFP_ATOMIC, &phys);
+		if (!desc)
+			goto err_desc_alloc;
+
+		memset(desc, 0, sizeof(struct dw_desc));
+
+		INIT_LIST_HEAD(&desc->tx_list);
+		dma_async_tx_descriptor_init(&desc->txd, chan);
+		desc->txd.tx_submit = dwc_tx_submit;
+		desc->txd.flags = DMA_CTRL_ACK;
+		desc->txd.phys = phys;
+
+		dwc_desc_put(dwc, desc);
+
+		spin_lock_irqsave(&dwc->lock, flags);
+		i = ++dwc->descs_allocated;
+	}
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i);
+
+	return i;
+
+err_desc_alloc:
+	dev_info(chan2dev(chan), "only allocated %d descriptors\n", i);
+
+	return i;
+}
+
+static void dwc_free_chan_resources(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(chan->device);
+	struct dw_desc		*desc, *_desc;
+	unsigned long		flags;
+	LIST_HEAD(list);
+
+	dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__,
+			dwc->descs_allocated);
+
+	/* ASSERT:  channel is idle */
+	BUG_ON(!list_empty(&dwc->active_list));
+	BUG_ON(!list_empty(&dwc->queue));
+	BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask);
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	list_splice_init(&dwc->free_list, &list);
+	dwc->descs_allocated = 0;
+	dwc->initialized = false;
+	dwc->request_line = ~0;
+
+	/* Disable interrupts */
+	channel_clear_bit(dw, MASK.XFER, dwc->mask);
+	channel_clear_bit(dw, MASK.ERROR, dwc->mask);
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	list_for_each_entry_safe(desc, _desc, &list, desc_node) {
+		dev_vdbg(chan2dev(chan), "  freeing descriptor %p\n", desc);
+		dma_pool_free(dw->desc_pool, desc, desc->txd.phys);
+	}
+
+	dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
+}
+
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+/**
+ * dw_dma_cyclic_start - start the cyclic DMA transfer
+ * @chan: the DMA channel to start
+ *
+ * Must be called with soft interrupts disabled. Returns zero on success or
+ * -errno on failure.
+ */
+int dw_dma_cyclic_start(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+	unsigned long		flags;
+
+	if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
+		dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
+		return -ENODEV;
+	}
+
+	spin_lock_irqsave(&dwc->lock, flags);
+
+	/* Assert channel is idle */
+	if (dma_readl(dw, CH_EN) & dwc->mask) {
+		dev_err(chan2dev(&dwc->chan),
+			"BUG: Attempted to start non-idle channel\n");
+		dwc_dump_chan_regs(dwc);
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		return -EBUSY;
+	}
+
+	dma_writel(dw, CLEAR.ERROR, dwc->mask);
+	dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+	/* Setup DMAC channel registers */
+	channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
+	channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
+	channel_writel(dwc, CTL_HI, 0);
+
+	channel_set_bit(dw, CH_EN, dwc->mask);
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_start);
+
+/**
+ * dw_dma_cyclic_stop - stop the cyclic DMA transfer
+ * @chan: the DMA channel to stop
+ *
+ * Must be called with soft interrupts disabled.
+ */
+void dw_dma_cyclic_stop(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+	unsigned long		flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+
+	dwc_chan_disable(dw, dwc);
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_stop);
+
+/**
+ * dw_dma_cyclic_prep - prepare the cyclic DMA transfer
+ * @chan: the DMA channel to prepare
+ * @buf_addr: physical DMA address where the buffer starts
+ * @buf_len: total number of bytes for the entire buffer
+ * @period_len: number of bytes for each period
+ * @direction: transfer direction, to or from device
+ *
+ * Must be called before trying to start the transfer. Returns a valid struct
+ * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful.
+ */
+struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
+		dma_addr_t buf_addr, size_t buf_len, size_t period_len,
+		enum dma_transfer_direction direction)
+{
+	struct dw_dma_chan		*dwc = to_dw_dma_chan(chan);
+	struct dma_slave_config		*sconfig = &dwc->dma_sconfig;
+	struct dw_cyclic_desc		*cdesc;
+	struct dw_cyclic_desc		*retval = NULL;
+	struct dw_desc			*desc;
+	struct dw_desc			*last = NULL;
+	unsigned long			was_cyclic;
+	unsigned int			reg_width;
+	unsigned int			periods;
+	unsigned int			i;
+	unsigned long			flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	if (dwc->nollp) {
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		dev_dbg(chan2dev(&dwc->chan),
+				"channel doesn't support LLP transfers\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		dev_dbg(chan2dev(&dwc->chan),
+				"queue and/or active list are not empty\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+	spin_unlock_irqrestore(&dwc->lock, flags);
+	if (was_cyclic) {
+		dev_dbg(chan2dev(&dwc->chan),
+				"channel already prepared for cyclic DMA\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	retval = ERR_PTR(-EINVAL);
+
+	if (unlikely(!is_slave_direction(direction)))
+		goto out_err;
+
+	dwc->direction = direction;
+
+	if (direction == DMA_MEM_TO_DEV)
+		reg_width = __ffs(sconfig->dst_addr_width);
+	else
+		reg_width = __ffs(sconfig->src_addr_width);
+
+	periods = buf_len / period_len;
+
+	/* Check for too big/unaligned periods and unaligned DMA buffer. */
+	if (period_len > (dwc->block_size << reg_width))
+		goto out_err;
+	if (unlikely(period_len & ((1 << reg_width) - 1)))
+		goto out_err;
+	if (unlikely(buf_addr & ((1 << reg_width) - 1)))
+		goto out_err;
+
+	retval = ERR_PTR(-ENOMEM);
+
+	if (periods > NR_DESCS_PER_CHANNEL)
+		goto out_err;
+
+	cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL);
+	if (!cdesc)
+		goto out_err;
+
+	cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL);
+	if (!cdesc->desc)
+		goto out_err_alloc;
+
+	for (i = 0; i < periods; i++) {
+		desc = dwc_desc_get(dwc);
+		if (!desc)
+			goto out_err_desc_get;
+
+		switch (direction) {
+		case DMA_MEM_TO_DEV:
+			desc->lli.dar = sconfig->dst_addr;
+			desc->lli.sar = buf_addr + (period_len * i);
+			desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan)
+					| DWC_CTLL_DST_WIDTH(reg_width)
+					| DWC_CTLL_SRC_WIDTH(reg_width)
+					| DWC_CTLL_DST_FIX
+					| DWC_CTLL_SRC_INC
+					| DWC_CTLL_INT_EN);
+
+			desc->lli.ctllo |= sconfig->device_fc ?
+				DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
+				DWC_CTLL_FC(DW_DMA_FC_D_M2P);
+
+			break;
+		case DMA_DEV_TO_MEM:
+			desc->lli.dar = buf_addr + (period_len * i);
+			desc->lli.sar = sconfig->src_addr;
+			desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan)
+					| DWC_CTLL_SRC_WIDTH(reg_width)
+					| DWC_CTLL_DST_WIDTH(reg_width)
+					| DWC_CTLL_DST_INC
+					| DWC_CTLL_SRC_FIX
+					| DWC_CTLL_INT_EN);
+
+			desc->lli.ctllo |= sconfig->device_fc ?
+				DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
+				DWC_CTLL_FC(DW_DMA_FC_D_P2M);
+
+			break;
+		default:
+			break;
+		}
+
+		desc->lli.ctlhi = (period_len >> reg_width);
+		cdesc->desc[i] = desc;
+
+		if (last)
+			last->lli.llp = desc->txd.phys;
+
+		last = desc;
+	}
+
+	/* Let's make a cyclic list */
+	last->lli.llp = cdesc->desc[0]->txd.phys;
+
+	dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu "
+			"period %zu periods %d\n", (unsigned long long)buf_addr,
+			buf_len, period_len, periods);
+
+	cdesc->periods = periods;
+	dwc->cdesc = cdesc;
+
+	return cdesc;
+
+out_err_desc_get:
+	while (i--)
+		dwc_desc_put(dwc, cdesc->desc[i]);
+out_err_alloc:
+	kfree(cdesc);
+out_err:
+	clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+	return (struct dw_cyclic_desc *)retval;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_prep);
+
+/**
+ * dw_dma_cyclic_free - free a prepared cyclic DMA transfer
+ * @chan: the DMA channel to free
+ */
+void dw_dma_cyclic_free(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+	struct dw_cyclic_desc	*cdesc = dwc->cdesc;
+	int			i;
+	unsigned long		flags;
+
+	dev_dbg(chan2dev(&dwc->chan), "%s\n", __func__);
+
+	if (!cdesc)
+		return;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+
+	dwc_chan_disable(dw, dwc);
+
+	dma_writel(dw, CLEAR.ERROR, dwc->mask);
+	dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	for (i = 0; i < cdesc->periods; i++)
+		dwc_desc_put(dwc, cdesc->desc[i]);
+
+	kfree(cdesc->desc);
+	kfree(cdesc);
+
+	clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_free);
+
+/*----------------------------------------------------------------------*/
+
+static void dw_dma_off(struct dw_dma *dw)
+{
+	int i;
+
+	dma_writel(dw, CFG, 0);
+
+	channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+	channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
+	channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
+	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
+
+	while (dma_readl(dw, CFG) & DW_CFG_DMA_EN)
+		cpu_relax();
+
+	for (i = 0; i < dw->dma.chancnt; i++)
+		dw->chan[i].initialized = false;
+}
+
+int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
+{
+	struct dw_dma		*dw;
+	size_t			size;
+	bool			autocfg;
+	unsigned int		dw_params;
+	unsigned int		nr_channels;
+	unsigned int		max_blk_size = 0;
+	int			err;
+	int			i;
+
+	dw_params = dma_read_byaddr(chip->regs, DW_PARAMS);
+	autocfg = dw_params >> DW_PARAMS_EN & 0x1;
+
+	dev_dbg(chip->dev, "DW_PARAMS: 0x%08x\n", dw_params);
+
+	if (!pdata && autocfg) {
+		pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL);
+		if (!pdata)
+			return -ENOMEM;
+
+		/* Fill platform data with the default values */
+		pdata->is_private = true;
+		pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING;
+		pdata->chan_priority = CHAN_PRIORITY_ASCENDING;
+	} else if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS)
+		return -EINVAL;
+
+	if (autocfg)
+		nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1;
+	else
+		nr_channels = pdata->nr_channels;
+
+	size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan);
+	dw = devm_kzalloc(chip->dev, size, GFP_KERNEL);
+	if (!dw)
+		return -ENOMEM;
+
+	dw->clk = devm_clk_get(chip->dev, "hclk");
+	if (IS_ERR(dw->clk))
+		return PTR_ERR(dw->clk);
+	clk_prepare_enable(dw->clk);
+
+	dw->regs = chip->regs;
+	chip->dw = dw;
+
+	/* Get hardware configuration parameters */
+	if (autocfg) {
+		max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
+
+		dw->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
+		for (i = 0; i < dw->nr_masters; i++) {
+			dw->data_width[i] =
+				(dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
+		}
+	} else {
+		dw->nr_masters = pdata->nr_masters;
+		memcpy(dw->data_width, pdata->data_width, 4);
+	}
+
+	/* Calculate all channel mask before DMA setup */
+	dw->all_chan_mask = (1 << nr_channels) - 1;
+
+	/* Force dma off, just in case */
+	dw_dma_off(dw);
+
+	/* Disable BLOCK interrupts as well */
+	channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
+
+	err = devm_request_irq(chip->dev, chip->irq, dw_dma_interrupt, 0,
+			       "dw_dmac", dw);
+	if (err)
+		return err;
+
+	/* Create a pool of consistent memory blocks for hardware descriptors */
+	dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", chip->dev,
+					 sizeof(struct dw_desc), 4, 0);
+	if (!dw->desc_pool) {
+		dev_err(chip->dev, "No memory for descriptors dma pool\n");
+		return -ENOMEM;
+	}
+
+	tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
+
+	INIT_LIST_HEAD(&dw->dma.channels);
+	for (i = 0; i < nr_channels; i++) {
+		struct dw_dma_chan	*dwc = &dw->chan[i];
+		int			r = nr_channels - i - 1;
+
+		dwc->chan.device = &dw->dma;
+		dma_cookie_init(&dwc->chan);
+		if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
+			list_add_tail(&dwc->chan.device_node,
+					&dw->dma.channels);
+		else
+			list_add(&dwc->chan.device_node, &dw->dma.channels);
+
+		/* 7 is highest priority & 0 is lowest. */
+		if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING)
+			dwc->priority = r;
+		else
+			dwc->priority = i;
+
+		dwc->ch_regs = &__dw_regs(dw)->CHAN[i];
+		spin_lock_init(&dwc->lock);
+		dwc->mask = 1 << i;
+
+		INIT_LIST_HEAD(&dwc->active_list);
+		INIT_LIST_HEAD(&dwc->queue);
+		INIT_LIST_HEAD(&dwc->free_list);
+
+		channel_clear_bit(dw, CH_EN, dwc->mask);
+
+		dwc->direction = DMA_TRANS_NONE;
+		dwc->request_line = ~0;
+
+		/* Hardware configuration */
+		if (autocfg) {
+			unsigned int dwc_params;
+			void __iomem *addr = chip->regs + r * sizeof(u32);
+
+			dwc_params = dma_read_byaddr(addr, DWC_PARAMS);
+
+			dev_dbg(chip->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
+					   dwc_params);
+
+			/* Decode maximum block size for given channel. The
+			 * stored 4 bit value represents blocks from 0x00 for 3
+			 * up to 0x0a for 4095. */
+			dwc->block_size =
+				(4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
+			dwc->nollp =
+				(dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0;
+		} else {
+			dwc->block_size = pdata->block_size;
+
+			/* Check if channel supports multi block transfer */
+			channel_writel(dwc, LLP, 0xfffffffc);
+			dwc->nollp =
+				(channel_readl(dwc, LLP) & 0xfffffffc) == 0;
+			channel_writel(dwc, LLP, 0);
+		}
+	}
+
+	/* Clear all interrupts on all channels. */
+	dma_writel(dw, CLEAR.XFER, dw->all_chan_mask);
+	dma_writel(dw, CLEAR.BLOCK, dw->all_chan_mask);
+	dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask);
+	dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
+	dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
+
+	dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
+	dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
+	if (pdata->is_private)
+		dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask);
+	dw->dma.dev = chip->dev;
+	dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
+	dw->dma.device_free_chan_resources = dwc_free_chan_resources;
+
+	dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy;
+
+	dw->dma.device_prep_slave_sg = dwc_prep_slave_sg;
+	dw->dma.device_control = dwc_control;
+
+	dw->dma.device_tx_status = dwc_tx_status;
+	dw->dma.device_issue_pending = dwc_issue_pending;
+
+	dma_writel(dw, CFG, DW_CFG_DMA_EN);
+
+	dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n",
+		 nr_channels);
+
+	dma_async_device_register(&dw->dma);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dw_dma_probe);
+
+int dw_dma_remove(struct dw_dma_chip *chip)
+{
+	struct dw_dma		*dw = chip->dw;
+	struct dw_dma_chan	*dwc, *_dwc;
+
+	dw_dma_off(dw);
+	dma_async_device_unregister(&dw->dma);
+
+	tasklet_kill(&dw->tasklet);
+
+	list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels,
+			chan.device_node) {
+		list_del(&dwc->chan.device_node);
+		channel_clear_bit(dw, CH_EN, dwc->mask);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dw_dma_remove);
+
+void dw_dma_shutdown(struct dw_dma_chip *chip)
+{
+	struct dw_dma *dw = chip->dw;
+
+	dw_dma_off(dw);
+	clk_disable_unprepare(dw->clk);
+}
+EXPORT_SYMBOL_GPL(dw_dma_shutdown);
+
+#ifdef CONFIG_PM_SLEEP
+
+int dw_dma_suspend(struct dw_dma_chip *chip)
+{
+	struct dw_dma *dw = chip->dw;
+
+	dw_dma_off(dw);
+	clk_disable_unprepare(dw->clk);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dw_dma_suspend);
+
+int dw_dma_resume(struct dw_dma_chip *chip)
+{
+	struct dw_dma *dw = chip->dw;
+
+	clk_prepare_enable(dw->clk);
+	dma_writel(dw, CFG, DW_CFG_DMA_EN);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dw_dma_resume);
+
+#endif /* CONFIG_PM_SLEEP */
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller core driver");
+MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
+MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dw/internal.h linux-libre-3.11-rc7-gnu/drivers/dma/dw/internal.h
--- linux-libre-3.10-gnu/drivers/dma/dw/internal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dw/internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,70 @@
+/*
+ * Driver for the Synopsys DesignWare DMA Controller
+ *
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _DW_DMAC_INTERNAL_H
+#define _DW_DMAC_INTERNAL_H
+
+#include <linux/device.h>
+#include <linux/dw_dmac.h>
+
+#include "regs.h"
+
+/**
+ * struct dw_dma_chip - representation of DesignWare DMA controller hardware
+ * @dev:		struct device of the DMA controller
+ * @irq:		irq line
+ * @regs:		memory mapped I/O space
+ * @dw:			struct dw_dma that is filed by dw_dma_probe()
+ */
+struct dw_dma_chip {
+	struct device	*dev;
+	int		irq;
+	void __iomem	*regs;
+	struct dw_dma	*dw;
+};
+
+/* Export to the platform drivers */
+int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata);
+int dw_dma_remove(struct dw_dma_chip *chip);
+
+void dw_dma_shutdown(struct dw_dma_chip *chip);
+
+#ifdef CONFIG_PM_SLEEP
+
+int dw_dma_suspend(struct dw_dma_chip *chip);
+int dw_dma_resume(struct dw_dma_chip *chip);
+
+#endif /* CONFIG_PM_SLEEP */
+
+/**
+ * dwc_get_dms - get destination master
+ * @slave:	pointer to the custom slave configuration
+ *
+ * Returns destination master in the custom slave configuration if defined, or
+ * default value otherwise.
+ */
+static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
+{
+	return slave ? slave->dst_master : 0;
+}
+
+/**
+ * dwc_get_sms - get source master
+ * @slave:	pointer to the custom slave configuration
+ *
+ * Returns source master in the custom slave configuration if defined, or
+ * default value otherwise.
+ */
+static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
+{
+	return slave ? slave->src_master : 1;
+}
+
+#endif /* _DW_DMAC_INTERNAL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dw/Kconfig linux-libre-3.11-rc7-gnu/drivers/dma/dw/Kconfig
--- linux-libre-3.10-gnu/drivers/dma/dw/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dw/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,29 @@
+#
+# DMA engine configuration for dw
+#
+
+config DW_DMAC_CORE
+	tristate "Synopsys DesignWare AHB DMA support"
+	depends on GENERIC_HARDIRQS
+	select DMA_ENGINE
+
+config DW_DMAC
+	tristate "Synopsys DesignWare AHB DMA platform driver"
+	select DW_DMAC_CORE
+	select DW_DMAC_BIG_ENDIAN_IO if AVR32
+	default y if CPU_AT32AP7000
+	help
+	  Support the Synopsys DesignWare AHB DMA controller. This
+	  can be integrated in chips such as the Atmel AT32ap7000.
+
+config DW_DMAC_PCI
+	tristate "Synopsys DesignWare AHB DMA PCI driver"
+	depends on PCI
+	select DW_DMAC_CORE
+	help
+	  Support the Synopsys DesignWare AHB DMA controller on the
+	  platfroms that enumerate it as a PCI device. For example,
+	  Intel Medfield has integrated this GPDMA controller.
+
+config DW_DMAC_BIG_ENDIAN_IO
+	bool
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dw/Makefile linux-libre-3.11-rc7-gnu/drivers/dma/dw/Makefile
--- linux-libre-3.10-gnu/drivers/dma/dw/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dw/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,8 @@
+obj-$(CONFIG_DW_DMAC_CORE)	+= dw_dmac_core.o
+dw_dmac_core-objs	:= core.o
+
+obj-$(CONFIG_DW_DMAC)		+= dw_dmac.o
+dw_dmac-objs		:= platform.o
+
+obj-$(CONFIG_DW_DMAC_PCI)	+= dw_dmac_pci.o
+dw_dmac_pci-objs	:= pci.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dw/pci.c linux-libre-3.11-rc7-gnu/drivers/dma/dw/pci.c
--- linux-libre-3.10-gnu/drivers/dma/dw/pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dw/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,101 @@
+/*
+ * PCI driver for the Synopsys DesignWare DMA Controller
+ *
+ * Copyright (C) 2013 Intel Corporation
+ * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/device.h>
+
+#include "internal.h"
+
+static struct dw_dma_platform_data dw_pci_pdata = {
+	.is_private = 1,
+	.chan_allocation_order = CHAN_ALLOCATION_ASCENDING,
+	.chan_priority = CHAN_PRIORITY_ASCENDING,
+};
+
+static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
+{
+	struct dw_dma_chip *chip;
+	struct dw_dma_platform_data *pdata = (void *)pid->driver_data;
+	int ret;
+
+	ret = pcim_enable_device(pdev);
+	if (ret)
+		return ret;
+
+	ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
+	if (ret) {
+		dev_err(&pdev->dev, "I/O memory remapping failed\n");
+		return ret;
+	}
+
+	pci_set_master(pdev);
+	pci_try_set_mwi(pdev);
+
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->dev = &pdev->dev;
+	chip->regs = pcim_iomap_table(pdev)[0];
+	chip->irq = pdev->irq;
+
+	ret = dw_dma_probe(chip, pdata);
+	if (ret)
+		return ret;
+
+	pci_set_drvdata(pdev, chip);
+
+	return 0;
+}
+
+static void dw_pci_remove(struct pci_dev *pdev)
+{
+	struct dw_dma_chip *chip = pci_get_drvdata(pdev);
+	int ret;
+
+	ret = dw_dma_remove(chip);
+	if (ret)
+		dev_warn(&pdev->dev, "can't remove device properly: %d\n", ret);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(dw_pci_id_table) = {
+	/* Medfield */
+	{ PCI_VDEVICE(INTEL, 0x0827), (kernel_ulong_t)&dw_pci_pdata },
+	{ PCI_VDEVICE(INTEL, 0x0830), (kernel_ulong_t)&dw_pci_pdata },
+
+	/* BayTrail */
+	{ PCI_VDEVICE(INTEL, 0x0f06), (kernel_ulong_t)&dw_pci_pdata },
+	{ PCI_VDEVICE(INTEL, 0x0f40), (kernel_ulong_t)&dw_pci_pdata },
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, dw_pci_id_table);
+
+static struct pci_driver dw_pci_driver = {
+	.name		= "dw_dmac_pci",
+	.id_table	= dw_pci_id_table,
+	.probe		= dw_pci_probe,
+	.remove		= dw_pci_remove,
+};
+
+module_pci_driver(dw_pci_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller PCI driver");
+MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dw/platform.c linux-libre-3.11-rc7-gnu/drivers/dma/dw/platform.c
--- linux-libre-3.10-gnu/drivers/dma/dw/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dw/platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,317 @@
+/*
+ * Platform driver for the Synopsys DesignWare DMA Controller
+ *
+ * Copyright (C) 2007-2008 Atmel Corporation
+ * Copyright (C) 2010-2011 ST Microelectronics
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Some parts of this driver are derived from the original dw_dmac.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/acpi.h>
+#include <linux/acpi_dma.h>
+
+#include "internal.h"
+
+struct dw_dma_of_filter_args {
+	struct dw_dma *dw;
+	unsigned int req;
+	unsigned int src;
+	unsigned int dst;
+};
+
+static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	struct dw_dma_of_filter_args *fargs = param;
+
+	/* Ensure the device matches our channel */
+	if (chan->device != &fargs->dw->dma)
+		return false;
+
+	dwc->request_line = fargs->req;
+	dwc->src_master	= fargs->src;
+	dwc->dst_master	= fargs->dst;
+
+	return true;
+}
+
+static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
+					struct of_dma *ofdma)
+{
+	struct dw_dma *dw = ofdma->of_dma_data;
+	struct dw_dma_of_filter_args fargs = {
+		.dw = dw,
+	};
+	dma_cap_mask_t cap;
+
+	if (dma_spec->args_count != 3)
+		return NULL;
+
+	fargs.req = dma_spec->args[0];
+	fargs.src = dma_spec->args[1];
+	fargs.dst = dma_spec->args[2];
+
+	if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
+		    fargs.src >= dw->nr_masters ||
+		    fargs.dst >= dw->nr_masters))
+		return NULL;
+
+	dma_cap_zero(cap);
+	dma_cap_set(DMA_SLAVE, cap);
+
+	/* TODO: there should be a simpler way to do this */
+	return dma_request_channel(cap, dw_dma_of_filter, &fargs);
+}
+
+#ifdef CONFIG_ACPI
+static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	struct acpi_dma_spec *dma_spec = param;
+
+	if (chan->device->dev != dma_spec->dev ||
+	    chan->chan_id != dma_spec->chan_id)
+		return false;
+
+	dwc->request_line = dma_spec->slave_id;
+	dwc->src_master = dwc_get_sms(NULL);
+	dwc->dst_master = dwc_get_dms(NULL);
+
+	return true;
+}
+
+static void dw_dma_acpi_controller_register(struct dw_dma *dw)
+{
+	struct device *dev = dw->dma.dev;
+	struct acpi_dma_filter_info *info;
+	int ret;
+
+	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return;
+
+	dma_cap_zero(info->dma_cap);
+	dma_cap_set(DMA_SLAVE, info->dma_cap);
+	info->filter_fn = dw_dma_acpi_filter;
+
+	ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate,
+						info);
+	if (ret)
+		dev_err(dev, "could not register acpi_dma_controller\n");
+}
+#else /* !CONFIG_ACPI */
+static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {}
+#endif /* !CONFIG_ACPI */
+
+#ifdef CONFIG_OF
+static struct dw_dma_platform_data *
+dw_dma_parse_dt(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct dw_dma_platform_data *pdata;
+	u32 tmp, arr[4];
+
+	if (!np) {
+		dev_err(&pdev->dev, "Missing DT data\n");
+		return NULL;
+	}
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+
+	if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
+		return NULL;
+
+	if (of_property_read_bool(np, "is_private"))
+		pdata->is_private = true;
+
+	if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
+		pdata->chan_allocation_order = (unsigned char)tmp;
+
+	if (!of_property_read_u32(np, "chan_priority", &tmp))
+		pdata->chan_priority = tmp;
+
+	if (!of_property_read_u32(np, "block_size", &tmp))
+		pdata->block_size = tmp;
+
+	if (!of_property_read_u32(np, "dma-masters", &tmp)) {
+		if (tmp > 4)
+			return NULL;
+
+		pdata->nr_masters = tmp;
+	}
+
+	if (!of_property_read_u32_array(np, "data_width", arr,
+				pdata->nr_masters))
+		for (tmp = 0; tmp < pdata->nr_masters; tmp++)
+			pdata->data_width[tmp] = arr[tmp];
+
+	return pdata;
+}
+#else
+static inline struct dw_dma_platform_data *
+dw_dma_parse_dt(struct platform_device *pdev)
+{
+	return NULL;
+}
+#endif
+
+static int dw_probe(struct platform_device *pdev)
+{
+	struct dw_dma_chip *chip;
+	struct device *dev = &pdev->dev;
+	struct resource *mem;
+	struct dw_dma_platform_data *pdata;
+	int err;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->irq = platform_get_irq(pdev, 0);
+	if (chip->irq < 0)
+		return chip->irq;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	chip->regs = devm_ioremap_resource(dev, mem);
+	if (IS_ERR(chip->regs))
+		return PTR_ERR(chip->regs);
+
+	/* Apply default dma_mask if needed */
+	if (!dev->dma_mask) {
+		dev->dma_mask = &dev->coherent_dma_mask;
+		dev->coherent_dma_mask = DMA_BIT_MASK(32);
+	}
+
+	pdata = dev_get_platdata(dev);
+	if (!pdata)
+		pdata = dw_dma_parse_dt(pdev);
+
+	chip->dev = dev;
+
+	err = dw_dma_probe(chip, pdata);
+	if (err)
+		return err;
+
+	platform_set_drvdata(pdev, chip);
+
+	if (pdev->dev.of_node) {
+		err = of_dma_controller_register(pdev->dev.of_node,
+						 dw_dma_of_xlate, chip->dw);
+		if (err)
+			dev_err(&pdev->dev,
+				"could not register of_dma_controller\n");
+	}
+
+	if (ACPI_HANDLE(&pdev->dev))
+		dw_dma_acpi_controller_register(chip->dw);
+
+	return 0;
+}
+
+static int dw_remove(struct platform_device *pdev)
+{
+	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+
+	if (pdev->dev.of_node)
+		of_dma_controller_free(pdev->dev.of_node);
+
+	return dw_dma_remove(chip);
+}
+
+static void dw_shutdown(struct platform_device *pdev)
+{
+	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+
+	dw_dma_shutdown(chip);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id dw_dma_of_id_table[] = {
+	{ .compatible = "snps,dma-spear1340" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
+#endif
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id dw_dma_acpi_id_table[] = {
+	{ "INTL9C60", 0 },
+	{ }
+};
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+
+static int dw_suspend_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+
+	return dw_dma_suspend(chip);
+}
+
+static int dw_resume_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+
+	return dw_dma_resume(chip);
+}
+
+#else /* !CONFIG_PM_SLEEP */
+
+#define dw_suspend_noirq	NULL
+#define dw_resume_noirq		NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops dw_dev_pm_ops = {
+	.suspend_noirq = dw_suspend_noirq,
+	.resume_noirq = dw_resume_noirq,
+	.freeze_noirq = dw_suspend_noirq,
+	.thaw_noirq = dw_resume_noirq,
+	.restore_noirq = dw_resume_noirq,
+	.poweroff_noirq = dw_suspend_noirq,
+};
+
+static struct platform_driver dw_driver = {
+	.probe		= dw_probe,
+	.remove		= dw_remove,
+	.shutdown	= dw_shutdown,
+	.driver = {
+		.name	= "dw_dmac",
+		.pm	= &dw_dev_pm_ops,
+		.of_match_table = of_match_ptr(dw_dma_of_id_table),
+		.acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
+	},
+};
+
+static int __init dw_init(void)
+{
+	return platform_driver_register(&dw_driver);
+}
+subsys_initcall(dw_init);
+
+static void __exit dw_exit(void)
+{
+	platform_driver_unregister(&dw_driver);
+}
+module_exit(dw_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dw/regs.h linux-libre-3.11-rc7-gnu/drivers/dma/dw/regs.h
--- linux-libre-3.10-gnu/drivers/dma/dw/regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dw/regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,318 @@
+/*
+ * Driver for the Synopsys DesignWare AHB DMA Controller
+ *
+ * Copyright (C) 2005-2007 Atmel Corporation
+ * Copyright (C) 2010-2011 ST Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/dmaengine.h>
+#include <linux/dw_dmac.h>
+
+#define DW_DMA_MAX_NR_CHANNELS	8
+#define DW_DMA_MAX_NR_REQUESTS	16
+
+/* flow controller */
+enum dw_dma_fc {
+	DW_DMA_FC_D_M2M,
+	DW_DMA_FC_D_M2P,
+	DW_DMA_FC_D_P2M,
+	DW_DMA_FC_D_P2P,
+	DW_DMA_FC_P_P2M,
+	DW_DMA_FC_SP_P2P,
+	DW_DMA_FC_P_M2P,
+	DW_DMA_FC_DP_P2P,
+};
+
+/*
+ * Redefine this macro to handle differences between 32- and 64-bit
+ * addressing, big vs. little endian, etc.
+ */
+#define DW_REG(name)		u32 name; u32 __pad_##name
+
+/* Hardware register definitions. */
+struct dw_dma_chan_regs {
+	DW_REG(SAR);		/* Source Address Register */
+	DW_REG(DAR);		/* Destination Address Register */
+	DW_REG(LLP);		/* Linked List Pointer */
+	u32	CTL_LO;		/* Control Register Low */
+	u32	CTL_HI;		/* Control Register High */
+	DW_REG(SSTAT);
+	DW_REG(DSTAT);
+	DW_REG(SSTATAR);
+	DW_REG(DSTATAR);
+	u32	CFG_LO;		/* Configuration Register Low */
+	u32	CFG_HI;		/* Configuration Register High */
+	DW_REG(SGR);
+	DW_REG(DSR);
+};
+
+struct dw_dma_irq_regs {
+	DW_REG(XFER);
+	DW_REG(BLOCK);
+	DW_REG(SRC_TRAN);
+	DW_REG(DST_TRAN);
+	DW_REG(ERROR);
+};
+
+struct dw_dma_regs {
+	/* per-channel registers */
+	struct dw_dma_chan_regs	CHAN[DW_DMA_MAX_NR_CHANNELS];
+
+	/* irq handling */
+	struct dw_dma_irq_regs	RAW;		/* r */
+	struct dw_dma_irq_regs	STATUS;		/* r (raw & mask) */
+	struct dw_dma_irq_regs	MASK;		/* rw (set = irq enabled) */
+	struct dw_dma_irq_regs	CLEAR;		/* w (ack, affects "raw") */
+
+	DW_REG(STATUS_INT);			/* r */
+
+	/* software handshaking */
+	DW_REG(REQ_SRC);
+	DW_REG(REQ_DST);
+	DW_REG(SGL_REQ_SRC);
+	DW_REG(SGL_REQ_DST);
+	DW_REG(LAST_SRC);
+	DW_REG(LAST_DST);
+
+	/* miscellaneous */
+	DW_REG(CFG);
+	DW_REG(CH_EN);
+	DW_REG(ID);
+	DW_REG(TEST);
+
+	/* reserved */
+	DW_REG(__reserved0);
+	DW_REG(__reserved1);
+
+	/* optional encoded params, 0x3c8..0x3f7 */
+	u32	__reserved;
+
+	/* per-channel configuration registers */
+	u32	DWC_PARAMS[DW_DMA_MAX_NR_CHANNELS];
+	u32	MULTI_BLK_TYPE;
+	u32	MAX_BLK_SIZE;
+
+	/* top-level parameters */
+	u32	DW_PARAMS;
+};
+
+/*
+ * Big endian I/O access when reading and writing to the DMA controller
+ * registers.  This is needed on some platforms, like the Atmel AVR32
+ * architecture.
+ */
+
+#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
+#define dma_readl_native ioread32be
+#define dma_writel_native iowrite32be
+#else
+#define dma_readl_native readl
+#define dma_writel_native writel
+#endif
+
+/* To access the registers in early stage of probe */
+#define dma_read_byaddr(addr, name) \
+	dma_readl_native((addr) + offsetof(struct dw_dma_regs, name))
+
+/* Bitfields in DW_PARAMS */
+#define DW_PARAMS_NR_CHAN	8		/* number of channels */
+#define DW_PARAMS_NR_MASTER	11		/* number of AHB masters */
+#define DW_PARAMS_DATA_WIDTH(n)	(15 + 2 * (n))
+#define DW_PARAMS_DATA_WIDTH1	15		/* master 1 data width */
+#define DW_PARAMS_DATA_WIDTH2	17		/* master 2 data width */
+#define DW_PARAMS_DATA_WIDTH3	19		/* master 3 data width */
+#define DW_PARAMS_DATA_WIDTH4	21		/* master 4 data width */
+#define DW_PARAMS_EN		28		/* encoded parameters */
+
+/* Bitfields in DWC_PARAMS */
+#define DWC_PARAMS_MBLK_EN	11		/* multi block transfer */
+
+/* Bitfields in CTL_LO */
+#define DWC_CTLL_INT_EN		(1 << 0)	/* irqs enabled? */
+#define DWC_CTLL_DST_WIDTH(n)	((n)<<1)	/* bytes per element */
+#define DWC_CTLL_SRC_WIDTH(n)	((n)<<4)
+#define DWC_CTLL_DST_INC	(0<<7)		/* DAR update/not */
+#define DWC_CTLL_DST_DEC	(1<<7)
+#define DWC_CTLL_DST_FIX	(2<<7)
+#define DWC_CTLL_SRC_INC	(0<<7)		/* SAR update/not */
+#define DWC_CTLL_SRC_DEC	(1<<9)
+#define DWC_CTLL_SRC_FIX	(2<<9)
+#define DWC_CTLL_DST_MSIZE(n)	((n)<<11)	/* burst, #elements */
+#define DWC_CTLL_SRC_MSIZE(n)	((n)<<14)
+#define DWC_CTLL_S_GATH_EN	(1 << 17)	/* src gather, !FIX */
+#define DWC_CTLL_D_SCAT_EN	(1 << 18)	/* dst scatter, !FIX */
+#define DWC_CTLL_FC(n)		((n) << 20)
+#define DWC_CTLL_FC_M2M		(0 << 20)	/* mem-to-mem */
+#define DWC_CTLL_FC_M2P		(1 << 20)	/* mem-to-periph */
+#define DWC_CTLL_FC_P2M		(2 << 20)	/* periph-to-mem */
+#define DWC_CTLL_FC_P2P		(3 << 20)	/* periph-to-periph */
+/* plus 4 transfer types for peripheral-as-flow-controller */
+#define DWC_CTLL_DMS(n)		((n)<<23)	/* dst master select */
+#define DWC_CTLL_SMS(n)		((n)<<25)	/* src master select */
+#define DWC_CTLL_LLP_D_EN	(1 << 27)	/* dest block chain */
+#define DWC_CTLL_LLP_S_EN	(1 << 28)	/* src block chain */
+
+/* Bitfields in CTL_HI */
+#define DWC_CTLH_DONE		0x00001000
+#define DWC_CTLH_BLOCK_TS_MASK	0x00000fff
+
+/* Bitfields in CFG_LO. Platform-configurable bits are in <linux/dw_dmac.h> */
+#define DWC_CFGL_CH_PRIOR_MASK	(0x7 << 5)	/* priority mask */
+#define DWC_CFGL_CH_PRIOR(x)	((x) << 5)	/* priority */
+#define DWC_CFGL_CH_SUSP	(1 << 8)	/* pause xfer */
+#define DWC_CFGL_FIFO_EMPTY	(1 << 9)	/* pause xfer */
+#define DWC_CFGL_HS_DST		(1 << 10)	/* handshake w/dst */
+#define DWC_CFGL_HS_SRC		(1 << 11)	/* handshake w/src */
+#define DWC_CFGL_MAX_BURST(x)	((x) << 20)
+#define DWC_CFGL_RELOAD_SAR	(1 << 30)
+#define DWC_CFGL_RELOAD_DAR	(1 << 31)
+
+/* Bitfields in CFG_HI. Platform-configurable bits are in <linux/dw_dmac.h> */
+#define DWC_CFGH_DS_UPD_EN	(1 << 5)
+#define DWC_CFGH_SS_UPD_EN	(1 << 6)
+
+/* Bitfields in SGR */
+#define DWC_SGR_SGI(x)		((x) << 0)
+#define DWC_SGR_SGC(x)		((x) << 20)
+
+/* Bitfields in DSR */
+#define DWC_DSR_DSI(x)		((x) << 0)
+#define DWC_DSR_DSC(x)		((x) << 20)
+
+/* Bitfields in CFG */
+#define DW_CFG_DMA_EN		(1 << 0)
+
+enum dw_dmac_flags {
+	DW_DMA_IS_CYCLIC = 0,
+	DW_DMA_IS_SOFT_LLP = 1,
+};
+
+struct dw_dma_chan {
+	struct dma_chan			chan;
+	void __iomem			*ch_regs;
+	u8				mask;
+	u8				priority;
+	enum dma_transfer_direction	direction;
+	bool				paused;
+	bool				initialized;
+
+	/* software emulation of the LLP transfers */
+	struct list_head	*tx_node_active;
+
+	spinlock_t		lock;
+
+	/* these other elements are all protected by lock */
+	unsigned long		flags;
+	struct list_head	active_list;
+	struct list_head	queue;
+	struct list_head	free_list;
+	u32			residue;
+	struct dw_cyclic_desc	*cdesc;
+
+	unsigned int		descs_allocated;
+
+	/* hardware configuration */
+	unsigned int		block_size;
+	bool			nollp;
+
+	/* custom slave configuration */
+	unsigned int		request_line;
+	unsigned char		src_master;
+	unsigned char		dst_master;
+
+	/* configuration passed via DMA_SLAVE_CONFIG */
+	struct dma_slave_config dma_sconfig;
+};
+
+static inline struct dw_dma_chan_regs __iomem *
+__dwc_regs(struct dw_dma_chan *dwc)
+{
+	return dwc->ch_regs;
+}
+
+#define channel_readl(dwc, name) \
+	dma_readl_native(&(__dwc_regs(dwc)->name))
+#define channel_writel(dwc, name, val) \
+	dma_writel_native((val), &(__dwc_regs(dwc)->name))
+
+static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
+{
+	return container_of(chan, struct dw_dma_chan, chan);
+}
+
+struct dw_dma {
+	struct dma_device	dma;
+	void __iomem		*regs;
+	struct dma_pool		*desc_pool;
+	struct tasklet_struct	tasklet;
+	struct clk		*clk;
+
+	u8			all_chan_mask;
+
+	/* hardware configuration */
+	unsigned char		nr_masters;
+	unsigned char		data_width[4];
+
+	struct dw_dma_chan	chan[0];
+};
+
+static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
+{
+	return dw->regs;
+}
+
+#define dma_readl(dw, name) \
+	dma_readl_native(&(__dw_regs(dw)->name))
+#define dma_writel(dw, name, val) \
+	dma_writel_native((val), &(__dw_regs(dw)->name))
+
+#define channel_set_bit(dw, reg, mask) \
+	dma_writel(dw, reg, ((mask) << 8) | (mask))
+#define channel_clear_bit(dw, reg, mask) \
+	dma_writel(dw, reg, ((mask) << 8) | 0)
+
+static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
+{
+	return container_of(ddev, struct dw_dma, dma);
+}
+
+/* LLI == Linked List Item; a.k.a. DMA block descriptor */
+struct dw_lli {
+	/* values that are not changed by hardware */
+	u32		sar;
+	u32		dar;
+	u32		llp;		/* chain to next lli */
+	u32		ctllo;
+	/* values that may get written back: */
+	u32		ctlhi;
+	/* sstat and dstat can snapshot peripheral register state.
+	 * silicon config may discard either or both...
+	 */
+	u32		sstat;
+	u32		dstat;
+};
+
+struct dw_desc {
+	/* FIRST values the hardware uses */
+	struct dw_lli			lli;
+
+	/* THEN values for driver housekeeping */
+	struct list_head		desc_node;
+	struct list_head		tx_list;
+	struct dma_async_tx_descriptor	txd;
+	size_t				len;
+	size_t				total_len;
+};
+
+#define to_dw_desc(h)	list_entry(h, struct dw_desc, desc_node)
+
+static inline struct dw_desc *
+txd_to_dw_desc(struct dma_async_tx_descriptor *txd)
+{
+	return container_of(txd, struct dw_desc, txd);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dw_dmac.c linux-libre-3.11-rc7-gnu/drivers/dma/dw_dmac.c
--- linux-libre-3.10-gnu/drivers/dma/dw_dmac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dw_dmac.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1972 +0,0 @@
-/*
- * Core driver for the Synopsys DesignWare DMA Controller
- *
- * Copyright (C) 2007-2008 Atmel Corporation
- * Copyright (C) 2010-2011 ST Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/bitops.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
-#include <linux/dmapool.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_dma.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/acpi.h>
-#include <linux/acpi_dma.h>
-
-#include "dw_dmac_regs.h"
-#include "dmaengine.h"
-
-/*
- * This supports the Synopsys "DesignWare AHB Central DMA Controller",
- * (DW_ahb_dmac) which is used with various AMBA 2.0 systems (not all
- * of which use ARM any more).  See the "Databook" from Synopsys for
- * information beyond what licensees probably provide.
- *
- * The driver has currently been tested only with the Atmel AT32AP7000,
- * which does not support descriptor writeback.
- */
-
-static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
-{
-	return slave ? slave->dst_master : 0;
-}
-
-static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
-{
-	return slave ? slave->src_master : 1;
-}
-
-static inline void dwc_set_masters(struct dw_dma_chan *dwc)
-{
-	struct dw_dma *dw = to_dw_dma(dwc->chan.device);
-	struct dw_dma_slave *dws = dwc->chan.private;
-	unsigned char mmax = dw->nr_masters - 1;
-
-	if (dwc->request_line == ~0) {
-		dwc->src_master = min_t(unsigned char, mmax, dwc_get_sms(dws));
-		dwc->dst_master = min_t(unsigned char, mmax, dwc_get_dms(dws));
-	}
-}
-
-#define DWC_DEFAULT_CTLLO(_chan) ({				\
-		struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan);	\
-		struct dma_slave_config	*_sconfig = &_dwc->dma_sconfig;	\
-		bool _is_slave = is_slave_direction(_dwc->direction);	\
-		u8 _smsize = _is_slave ? _sconfig->src_maxburst :	\
-			DW_DMA_MSIZE_16;			\
-		u8 _dmsize = _is_slave ? _sconfig->dst_maxburst :	\
-			DW_DMA_MSIZE_16;			\
-								\
-		(DWC_CTLL_DST_MSIZE(_dmsize)			\
-		 | DWC_CTLL_SRC_MSIZE(_smsize)			\
-		 | DWC_CTLL_LLP_D_EN				\
-		 | DWC_CTLL_LLP_S_EN				\
-		 | DWC_CTLL_DMS(_dwc->dst_master)		\
-		 | DWC_CTLL_SMS(_dwc->src_master));		\
-	})
-
-/*
- * Number of descriptors to allocate for each channel. This should be
- * made configurable somehow; preferably, the clients (at least the
- * ones using slave transfers) should be able to give us a hint.
- */
-#define NR_DESCS_PER_CHANNEL	64
-
-/*----------------------------------------------------------------------*/
-
-static struct device *chan2dev(struct dma_chan *chan)
-{
-	return &chan->dev->device;
-}
-static struct device *chan2parent(struct dma_chan *chan)
-{
-	return chan->dev->device.parent;
-}
-
-static struct dw_desc *dwc_first_active(struct dw_dma_chan *dwc)
-{
-	return to_dw_desc(dwc->active_list.next);
-}
-
-static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
-{
-	struct dw_desc *desc, *_desc;
-	struct dw_desc *ret = NULL;
-	unsigned int i = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) {
-		i++;
-		if (async_tx_test_ack(&desc->txd)) {
-			list_del(&desc->desc_node);
-			ret = desc;
-			break;
-		}
-		dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc);
-	}
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i);
-
-	return ret;
-}
-
-/*
- * Move a descriptor, including any children, to the free list.
- * `desc' must not be on any lists.
- */
-static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
-{
-	unsigned long flags;
-
-	if (desc) {
-		struct dw_desc *child;
-
-		spin_lock_irqsave(&dwc->lock, flags);
-		list_for_each_entry(child, &desc->tx_list, desc_node)
-			dev_vdbg(chan2dev(&dwc->chan),
-					"moving child desc %p to freelist\n",
-					child);
-		list_splice_init(&desc->tx_list, &dwc->free_list);
-		dev_vdbg(chan2dev(&dwc->chan), "moving desc %p to freelist\n", desc);
-		list_add(&desc->desc_node, &dwc->free_list);
-		spin_unlock_irqrestore(&dwc->lock, flags);
-	}
-}
-
-static void dwc_initialize(struct dw_dma_chan *dwc)
-{
-	struct dw_dma *dw = to_dw_dma(dwc->chan.device);
-	struct dw_dma_slave *dws = dwc->chan.private;
-	u32 cfghi = DWC_CFGH_FIFO_MODE;
-	u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
-
-	if (dwc->initialized == true)
-		return;
-
-	if (dws) {
-		/*
-		 * We need controller-specific data to set up slave
-		 * transfers.
-		 */
-		BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
-
-		cfghi = dws->cfg_hi;
-		cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK;
-	} else {
-		if (dwc->direction == DMA_MEM_TO_DEV)
-			cfghi = DWC_CFGH_DST_PER(dwc->request_line);
-		else if (dwc->direction == DMA_DEV_TO_MEM)
-			cfghi = DWC_CFGH_SRC_PER(dwc->request_line);
-	}
-
-	channel_writel(dwc, CFG_LO, cfglo);
-	channel_writel(dwc, CFG_HI, cfghi);
-
-	/* Enable interrupts */
-	channel_set_bit(dw, MASK.XFER, dwc->mask);
-	channel_set_bit(dw, MASK.ERROR, dwc->mask);
-
-	dwc->initialized = true;
-}
-
-/*----------------------------------------------------------------------*/
-
-static inline unsigned int dwc_fast_fls(unsigned long long v)
-{
-	/*
-	 * We can be a lot more clever here, but this should take care
-	 * of the most common optimization.
-	 */
-	if (!(v & 7))
-		return 3;
-	else if (!(v & 3))
-		return 2;
-	else if (!(v & 1))
-		return 1;
-	return 0;
-}
-
-static inline void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
-{
-	dev_err(chan2dev(&dwc->chan),
-		"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
-		channel_readl(dwc, SAR),
-		channel_readl(dwc, DAR),
-		channel_readl(dwc, LLP),
-		channel_readl(dwc, CTL_HI),
-		channel_readl(dwc, CTL_LO));
-}
-
-static inline void dwc_chan_disable(struct dw_dma *dw, struct dw_dma_chan *dwc)
-{
-	channel_clear_bit(dw, CH_EN, dwc->mask);
-	while (dma_readl(dw, CH_EN) & dwc->mask)
-		cpu_relax();
-}
-
-/*----------------------------------------------------------------------*/
-
-/* Perform single block transfer */
-static inline void dwc_do_single_block(struct dw_dma_chan *dwc,
-				       struct dw_desc *desc)
-{
-	struct dw_dma	*dw = to_dw_dma(dwc->chan.device);
-	u32		ctllo;
-
-	/* Software emulation of LLP mode relies on interrupts to continue
-	 * multi block transfer. */
-	ctllo = desc->lli.ctllo | DWC_CTLL_INT_EN;
-
-	channel_writel(dwc, SAR, desc->lli.sar);
-	channel_writel(dwc, DAR, desc->lli.dar);
-	channel_writel(dwc, CTL_LO, ctllo);
-	channel_writel(dwc, CTL_HI, desc->lli.ctlhi);
-	channel_set_bit(dw, CH_EN, dwc->mask);
-
-	/* Move pointer to next descriptor */
-	dwc->tx_node_active = dwc->tx_node_active->next;
-}
-
-/* Called with dwc->lock held and bh disabled */
-static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
-{
-	struct dw_dma	*dw = to_dw_dma(dwc->chan.device);
-	unsigned long	was_soft_llp;
-
-	/* ASSERT:  channel is idle */
-	if (dma_readl(dw, CH_EN) & dwc->mask) {
-		dev_err(chan2dev(&dwc->chan),
-			"BUG: Attempted to start non-idle channel\n");
-		dwc_dump_chan_regs(dwc);
-
-		/* The tasklet will hopefully advance the queue... */
-		return;
-	}
-
-	if (dwc->nollp) {
-		was_soft_llp = test_and_set_bit(DW_DMA_IS_SOFT_LLP,
-						&dwc->flags);
-		if (was_soft_llp) {
-			dev_err(chan2dev(&dwc->chan),
-				"BUG: Attempted to start new LLP transfer "
-				"inside ongoing one\n");
-			return;
-		}
-
-		dwc_initialize(dwc);
-
-		dwc->residue = first->total_len;
-		dwc->tx_node_active = &first->tx_list;
-
-		/* Submit first block */
-		dwc_do_single_block(dwc, first);
-
-		return;
-	}
-
-	dwc_initialize(dwc);
-
-	channel_writel(dwc, LLP, first->txd.phys);
-	channel_writel(dwc, CTL_LO,
-			DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
-	channel_writel(dwc, CTL_HI, 0);
-	channel_set_bit(dw, CH_EN, dwc->mask);
-}
-
-/*----------------------------------------------------------------------*/
-
-static void
-dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
-		bool callback_required)
-{
-	dma_async_tx_callback		callback = NULL;
-	void				*param = NULL;
-	struct dma_async_tx_descriptor	*txd = &desc->txd;
-	struct dw_desc			*child;
-	unsigned long			flags;
-
-	dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	dma_cookie_complete(txd);
-	if (callback_required) {
-		callback = txd->callback;
-		param = txd->callback_param;
-	}
-
-	/* async_tx_ack */
-	list_for_each_entry(child, &desc->tx_list, desc_node)
-		async_tx_ack(&child->txd);
-	async_tx_ack(&desc->txd);
-
-	list_splice_init(&desc->tx_list, &dwc->free_list);
-	list_move(&desc->desc_node, &dwc->free_list);
-
-	if (!is_slave_direction(dwc->direction)) {
-		struct device *parent = chan2parent(&dwc->chan);
-		if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
-			if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
-				dma_unmap_single(parent, desc->lli.dar,
-					desc->total_len, DMA_FROM_DEVICE);
-			else
-				dma_unmap_page(parent, desc->lli.dar,
-					desc->total_len, DMA_FROM_DEVICE);
-		}
-		if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
-			if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
-				dma_unmap_single(parent, desc->lli.sar,
-					desc->total_len, DMA_TO_DEVICE);
-			else
-				dma_unmap_page(parent, desc->lli.sar,
-					desc->total_len, DMA_TO_DEVICE);
-		}
-	}
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	if (callback)
-		callback(param);
-}
-
-static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
-{
-	struct dw_desc *desc, *_desc;
-	LIST_HEAD(list);
-	unsigned long flags;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	if (dma_readl(dw, CH_EN) & dwc->mask) {
-		dev_err(chan2dev(&dwc->chan),
-			"BUG: XFER bit set, but channel not idle!\n");
-
-		/* Try to continue after resetting the channel... */
-		dwc_chan_disable(dw, dwc);
-	}
-
-	/*
-	 * Submit queued descriptors ASAP, i.e. before we go through
-	 * the completed ones.
-	 */
-	list_splice_init(&dwc->active_list, &list);
-	if (!list_empty(&dwc->queue)) {
-		list_move(dwc->queue.next, &dwc->active_list);
-		dwc_dostart(dwc, dwc_first_active(dwc));
-	}
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	list_for_each_entry_safe(desc, _desc, &list, desc_node)
-		dwc_descriptor_complete(dwc, desc, true);
-}
-
-/* Returns how many bytes were already received from source */
-static inline u32 dwc_get_sent(struct dw_dma_chan *dwc)
-{
-	u32 ctlhi = channel_readl(dwc, CTL_HI);
-	u32 ctllo = channel_readl(dwc, CTL_LO);
-
-	return (ctlhi & DWC_CTLH_BLOCK_TS_MASK) * (1 << (ctllo >> 4 & 7));
-}
-
-static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
-{
-	dma_addr_t llp;
-	struct dw_desc *desc, *_desc;
-	struct dw_desc *child;
-	u32 status_xfer;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	llp = channel_readl(dwc, LLP);
-	status_xfer = dma_readl(dw, RAW.XFER);
-
-	if (status_xfer & dwc->mask) {
-		/* Everything we've submitted is done */
-		dma_writel(dw, CLEAR.XFER, dwc->mask);
-
-		if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
-			struct list_head *head, *active = dwc->tx_node_active;
-
-			/*
-			 * We are inside first active descriptor.
-			 * Otherwise something is really wrong.
-			 */
-			desc = dwc_first_active(dwc);
-
-			head = &desc->tx_list;
-			if (active != head) {
-				/* Update desc to reflect last sent one */
-				if (active != head->next)
-					desc = to_dw_desc(active->prev);
-
-				dwc->residue -= desc->len;
-
-				child = to_dw_desc(active);
-
-				/* Submit next block */
-				dwc_do_single_block(dwc, child);
-
-				spin_unlock_irqrestore(&dwc->lock, flags);
-				return;
-			}
-
-			/* We are done here */
-			clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
-		}
-
-		dwc->residue = 0;
-
-		spin_unlock_irqrestore(&dwc->lock, flags);
-
-		dwc_complete_all(dw, dwc);
-		return;
-	}
-
-	if (list_empty(&dwc->active_list)) {
-		dwc->residue = 0;
-		spin_unlock_irqrestore(&dwc->lock, flags);
-		return;
-	}
-
-	if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
-		dev_vdbg(chan2dev(&dwc->chan), "%s: soft LLP mode\n", __func__);
-		spin_unlock_irqrestore(&dwc->lock, flags);
-		return;
-	}
-
-	dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__,
-			(unsigned long long)llp);
-
-	list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
-		/* Initial residue value */
-		dwc->residue = desc->total_len;
-
-		/* Check first descriptors addr */
-		if (desc->txd.phys == llp) {
-			spin_unlock_irqrestore(&dwc->lock, flags);
-			return;
-		}
-
-		/* Check first descriptors llp */
-		if (desc->lli.llp == llp) {
-			/* This one is currently in progress */
-			dwc->residue -= dwc_get_sent(dwc);
-			spin_unlock_irqrestore(&dwc->lock, flags);
-			return;
-		}
-
-		dwc->residue -= desc->len;
-		list_for_each_entry(child, &desc->tx_list, desc_node) {
-			if (child->lli.llp == llp) {
-				/* Currently in progress */
-				dwc->residue -= dwc_get_sent(dwc);
-				spin_unlock_irqrestore(&dwc->lock, flags);
-				return;
-			}
-			dwc->residue -= child->len;
-		}
-
-		/*
-		 * No descriptors so far seem to be in progress, i.e.
-		 * this one must be done.
-		 */
-		spin_unlock_irqrestore(&dwc->lock, flags);
-		dwc_descriptor_complete(dwc, desc, true);
-		spin_lock_irqsave(&dwc->lock, flags);
-	}
-
-	dev_err(chan2dev(&dwc->chan),
-		"BUG: All descriptors done, but channel not idle!\n");
-
-	/* Try to continue after resetting the channel... */
-	dwc_chan_disable(dw, dwc);
-
-	if (!list_empty(&dwc->queue)) {
-		list_move(dwc->queue.next, &dwc->active_list);
-		dwc_dostart(dwc, dwc_first_active(dwc));
-	}
-	spin_unlock_irqrestore(&dwc->lock, flags);
-}
-
-static inline void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
-{
-	dev_crit(chan2dev(&dwc->chan), "  desc: s0x%x d0x%x l0x%x c0x%x:%x\n",
-		 lli->sar, lli->dar, lli->llp, lli->ctlhi, lli->ctllo);
-}
-
-static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
-{
-	struct dw_desc *bad_desc;
-	struct dw_desc *child;
-	unsigned long flags;
-
-	dwc_scan_descriptors(dw, dwc);
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	/*
-	 * The descriptor currently at the head of the active list is
-	 * borked. Since we don't have any way to report errors, we'll
-	 * just have to scream loudly and try to carry on.
-	 */
-	bad_desc = dwc_first_active(dwc);
-	list_del_init(&bad_desc->desc_node);
-	list_move(dwc->queue.next, dwc->active_list.prev);
-
-	/* Clear the error flag and try to restart the controller */
-	dma_writel(dw, CLEAR.ERROR, dwc->mask);
-	if (!list_empty(&dwc->active_list))
-		dwc_dostart(dwc, dwc_first_active(dwc));
-
-	/*
-	 * WARN may seem harsh, but since this only happens
-	 * when someone submits a bad physical address in a
-	 * descriptor, we should consider ourselves lucky that the
-	 * controller flagged an error instead of scribbling over
-	 * random memory locations.
-	 */
-	dev_WARN(chan2dev(&dwc->chan), "Bad descriptor submitted for DMA!\n"
-				       "  cookie: %d\n", bad_desc->txd.cookie);
-	dwc_dump_lli(dwc, &bad_desc->lli);
-	list_for_each_entry(child, &bad_desc->tx_list, desc_node)
-		dwc_dump_lli(dwc, &child->lli);
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	/* Pretend the descriptor completed successfully */
-	dwc_descriptor_complete(dwc, bad_desc, true);
-}
-
-/* --------------------- Cyclic DMA API extensions -------------------- */
-
-inline dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan)
-{
-	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
-	return channel_readl(dwc, SAR);
-}
-EXPORT_SYMBOL(dw_dma_get_src_addr);
-
-inline dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan)
-{
-	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
-	return channel_readl(dwc, DAR);
-}
-EXPORT_SYMBOL(dw_dma_get_dst_addr);
-
-/* Called with dwc->lock held and all DMAC interrupts disabled */
-static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
-		u32 status_err, u32 status_xfer)
-{
-	unsigned long flags;
-
-	if (dwc->mask) {
-		void (*callback)(void *param);
-		void *callback_param;
-
-		dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n",
-				channel_readl(dwc, LLP));
-
-		callback = dwc->cdesc->period_callback;
-		callback_param = dwc->cdesc->period_callback_param;
-
-		if (callback)
-			callback(callback_param);
-	}
-
-	/*
-	 * Error and transfer complete are highly unlikely, and will most
-	 * likely be due to a configuration error by the user.
-	 */
-	if (unlikely(status_err & dwc->mask) ||
-			unlikely(status_xfer & dwc->mask)) {
-		int i;
-
-		dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
-				"interrupt, stopping DMA transfer\n",
-				status_xfer ? "xfer" : "error");
-
-		spin_lock_irqsave(&dwc->lock, flags);
-
-		dwc_dump_chan_regs(dwc);
-
-		dwc_chan_disable(dw, dwc);
-
-		/* Make sure DMA does not restart by loading a new list */
-		channel_writel(dwc, LLP, 0);
-		channel_writel(dwc, CTL_LO, 0);
-		channel_writel(dwc, CTL_HI, 0);
-
-		dma_writel(dw, CLEAR.ERROR, dwc->mask);
-		dma_writel(dw, CLEAR.XFER, dwc->mask);
-
-		for (i = 0; i < dwc->cdesc->periods; i++)
-			dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
-
-		spin_unlock_irqrestore(&dwc->lock, flags);
-	}
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void dw_dma_tasklet(unsigned long data)
-{
-	struct dw_dma *dw = (struct dw_dma *)data;
-	struct dw_dma_chan *dwc;
-	u32 status_xfer;
-	u32 status_err;
-	int i;
-
-	status_xfer = dma_readl(dw, RAW.XFER);
-	status_err = dma_readl(dw, RAW.ERROR);
-
-	dev_vdbg(dw->dma.dev, "%s: status_err=%x\n", __func__, status_err);
-
-	for (i = 0; i < dw->dma.chancnt; i++) {
-		dwc = &dw->chan[i];
-		if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
-			dwc_handle_cyclic(dw, dwc, status_err, status_xfer);
-		else if (status_err & (1 << i))
-			dwc_handle_error(dw, dwc);
-		else if (status_xfer & (1 << i))
-			dwc_scan_descriptors(dw, dwc);
-	}
-
-	/*
-	 * Re-enable interrupts.
-	 */
-	channel_set_bit(dw, MASK.XFER, dw->all_chan_mask);
-	channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask);
-}
-
-static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
-{
-	struct dw_dma *dw = dev_id;
-	u32 status;
-
-	dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__,
-			dma_readl(dw, STATUS_INT));
-
-	/*
-	 * Just disable the interrupts. We'll turn them back on in the
-	 * softirq handler.
-	 */
-	channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
-
-	status = dma_readl(dw, STATUS_INT);
-	if (status) {
-		dev_err(dw->dma.dev,
-			"BUG: Unexpected interrupts pending: 0x%x\n",
-			status);
-
-		/* Try to recover */
-		channel_clear_bit(dw, MASK.XFER, (1 << 8) - 1);
-		channel_clear_bit(dw, MASK.SRC_TRAN, (1 << 8) - 1);
-		channel_clear_bit(dw, MASK.DST_TRAN, (1 << 8) - 1);
-		channel_clear_bit(dw, MASK.ERROR, (1 << 8) - 1);
-	}
-
-	tasklet_schedule(&dw->tasklet);
-
-	return IRQ_HANDLED;
-}
-
-/*----------------------------------------------------------------------*/
-
-static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
-{
-	struct dw_desc		*desc = txd_to_dw_desc(tx);
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(tx->chan);
-	dma_cookie_t		cookie;
-	unsigned long		flags;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	cookie = dma_cookie_assign(tx);
-
-	/*
-	 * REVISIT: We should attempt to chain as many descriptors as
-	 * possible, perhaps even appending to those already submitted
-	 * for DMA. But this is hard to do in a race-free manner.
-	 */
-	if (list_empty(&dwc->active_list)) {
-		dev_vdbg(chan2dev(tx->chan), "%s: started %u\n", __func__,
-				desc->txd.cookie);
-		list_add_tail(&desc->desc_node, &dwc->active_list);
-		dwc_dostart(dwc, dwc_first_active(dwc));
-	} else {
-		dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", __func__,
-				desc->txd.cookie);
-
-		list_add_tail(&desc->desc_node, &dwc->queue);
-	}
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return cookie;
-}
-
-static struct dma_async_tx_descriptor *
-dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
-		size_t len, unsigned long flags)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma		*dw = to_dw_dma(chan->device);
-	struct dw_desc		*desc;
-	struct dw_desc		*first;
-	struct dw_desc		*prev;
-	size_t			xfer_count;
-	size_t			offset;
-	unsigned int		src_width;
-	unsigned int		dst_width;
-	unsigned int		data_width;
-	u32			ctllo;
-
-	dev_vdbg(chan2dev(chan),
-			"%s: d0x%llx s0x%llx l0x%zx f0x%lx\n", __func__,
-			(unsigned long long)dest, (unsigned long long)src,
-			len, flags);
-
-	if (unlikely(!len)) {
-		dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
-		return NULL;
-	}
-
-	dwc->direction = DMA_MEM_TO_MEM;
-
-	data_width = min_t(unsigned int, dw->data_width[dwc->src_master],
-			   dw->data_width[dwc->dst_master]);
-
-	src_width = dst_width = min_t(unsigned int, data_width,
-				      dwc_fast_fls(src | dest | len));
-
-	ctllo = DWC_DEFAULT_CTLLO(chan)
-			| DWC_CTLL_DST_WIDTH(dst_width)
-			| DWC_CTLL_SRC_WIDTH(src_width)
-			| DWC_CTLL_DST_INC
-			| DWC_CTLL_SRC_INC
-			| DWC_CTLL_FC_M2M;
-	prev = first = NULL;
-
-	for (offset = 0; offset < len; offset += xfer_count << src_width) {
-		xfer_count = min_t(size_t, (len - offset) >> src_width,
-					   dwc->block_size);
-
-		desc = dwc_desc_get(dwc);
-		if (!desc)
-			goto err_desc_get;
-
-		desc->lli.sar = src + offset;
-		desc->lli.dar = dest + offset;
-		desc->lli.ctllo = ctllo;
-		desc->lli.ctlhi = xfer_count;
-		desc->len = xfer_count << src_width;
-
-		if (!first) {
-			first = desc;
-		} else {
-			prev->lli.llp = desc->txd.phys;
-			list_add_tail(&desc->desc_node,
-					&first->tx_list);
-		}
-		prev = desc;
-	}
-
-	if (flags & DMA_PREP_INTERRUPT)
-		/* Trigger interrupt after last block */
-		prev->lli.ctllo |= DWC_CTLL_INT_EN;
-
-	prev->lli.llp = 0;
-	first->txd.flags = flags;
-	first->total_len = len;
-
-	return &first->txd;
-
-err_desc_get:
-	dwc_desc_put(dwc, first);
-	return NULL;
-}
-
-static struct dma_async_tx_descriptor *
-dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
-		unsigned int sg_len, enum dma_transfer_direction direction,
-		unsigned long flags, void *context)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma		*dw = to_dw_dma(chan->device);
-	struct dma_slave_config	*sconfig = &dwc->dma_sconfig;
-	struct dw_desc		*prev;
-	struct dw_desc		*first;
-	u32			ctllo;
-	dma_addr_t		reg;
-	unsigned int		reg_width;
-	unsigned int		mem_width;
-	unsigned int		data_width;
-	unsigned int		i;
-	struct scatterlist	*sg;
-	size_t			total_len = 0;
-
-	dev_vdbg(chan2dev(chan), "%s\n", __func__);
-
-	if (unlikely(!is_slave_direction(direction) || !sg_len))
-		return NULL;
-
-	dwc->direction = direction;
-
-	prev = first = NULL;
-
-	switch (direction) {
-	case DMA_MEM_TO_DEV:
-		reg_width = __fls(sconfig->dst_addr_width);
-		reg = sconfig->dst_addr;
-		ctllo = (DWC_DEFAULT_CTLLO(chan)
-				| DWC_CTLL_DST_WIDTH(reg_width)
-				| DWC_CTLL_DST_FIX
-				| DWC_CTLL_SRC_INC);
-
-		ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
-			DWC_CTLL_FC(DW_DMA_FC_D_M2P);
-
-		data_width = dw->data_width[dwc->src_master];
-
-		for_each_sg(sgl, sg, sg_len, i) {
-			struct dw_desc	*desc;
-			u32		len, dlen, mem;
-
-			mem = sg_dma_address(sg);
-			len = sg_dma_len(sg);
-
-			mem_width = min_t(unsigned int,
-					  data_width, dwc_fast_fls(mem | len));
-
-slave_sg_todev_fill_desc:
-			desc = dwc_desc_get(dwc);
-			if (!desc) {
-				dev_err(chan2dev(chan),
-					"not enough descriptors available\n");
-				goto err_desc_get;
-			}
-
-			desc->lli.sar = mem;
-			desc->lli.dar = reg;
-			desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
-			if ((len >> mem_width) > dwc->block_size) {
-				dlen = dwc->block_size << mem_width;
-				mem += dlen;
-				len -= dlen;
-			} else {
-				dlen = len;
-				len = 0;
-			}
-
-			desc->lli.ctlhi = dlen >> mem_width;
-			desc->len = dlen;
-
-			if (!first) {
-				first = desc;
-			} else {
-				prev->lli.llp = desc->txd.phys;
-				list_add_tail(&desc->desc_node,
-						&first->tx_list);
-			}
-			prev = desc;
-			total_len += dlen;
-
-			if (len)
-				goto slave_sg_todev_fill_desc;
-		}
-		break;
-	case DMA_DEV_TO_MEM:
-		reg_width = __fls(sconfig->src_addr_width);
-		reg = sconfig->src_addr;
-		ctllo = (DWC_DEFAULT_CTLLO(chan)
-				| DWC_CTLL_SRC_WIDTH(reg_width)
-				| DWC_CTLL_DST_INC
-				| DWC_CTLL_SRC_FIX);
-
-		ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
-			DWC_CTLL_FC(DW_DMA_FC_D_P2M);
-
-		data_width = dw->data_width[dwc->dst_master];
-
-		for_each_sg(sgl, sg, sg_len, i) {
-			struct dw_desc	*desc;
-			u32		len, dlen, mem;
-
-			mem = sg_dma_address(sg);
-			len = sg_dma_len(sg);
-
-			mem_width = min_t(unsigned int,
-					  data_width, dwc_fast_fls(mem | len));
-
-slave_sg_fromdev_fill_desc:
-			desc = dwc_desc_get(dwc);
-			if (!desc) {
-				dev_err(chan2dev(chan),
-						"not enough descriptors available\n");
-				goto err_desc_get;
-			}
-
-			desc->lli.sar = reg;
-			desc->lli.dar = mem;
-			desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
-			if ((len >> reg_width) > dwc->block_size) {
-				dlen = dwc->block_size << reg_width;
-				mem += dlen;
-				len -= dlen;
-			} else {
-				dlen = len;
-				len = 0;
-			}
-			desc->lli.ctlhi = dlen >> reg_width;
-			desc->len = dlen;
-
-			if (!first) {
-				first = desc;
-			} else {
-				prev->lli.llp = desc->txd.phys;
-				list_add_tail(&desc->desc_node,
-						&first->tx_list);
-			}
-			prev = desc;
-			total_len += dlen;
-
-			if (len)
-				goto slave_sg_fromdev_fill_desc;
-		}
-		break;
-	default:
-		return NULL;
-	}
-
-	if (flags & DMA_PREP_INTERRUPT)
-		/* Trigger interrupt after last block */
-		prev->lli.ctllo |= DWC_CTLL_INT_EN;
-
-	prev->lli.llp = 0;
-	first->total_len = total_len;
-
-	return &first->txd;
-
-err_desc_get:
-	dwc_desc_put(dwc, first);
-	return NULL;
-}
-
-/*
- * Fix sconfig's burst size according to dw_dmac. We need to convert them as:
- * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
- *
- * NOTE: burst size 2 is not supported by controller.
- *
- * This can be done by finding least significant bit set: n & (n - 1)
- */
-static inline void convert_burst(u32 *maxburst)
-{
-	if (*maxburst > 1)
-		*maxburst = fls(*maxburst) - 2;
-	else
-		*maxburst = 0;
-}
-
-static int
-set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
-{
-	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
-
-	/* Check if chan will be configured for slave transfers */
-	if (!is_slave_direction(sconfig->direction))
-		return -EINVAL;
-
-	memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
-	dwc->direction = sconfig->direction;
-
-	/* Take the request line from slave_id member */
-	if (dwc->request_line == ~0)
-		dwc->request_line = sconfig->slave_id;
-
-	convert_burst(&dwc->dma_sconfig.src_maxburst);
-	convert_burst(&dwc->dma_sconfig.dst_maxburst);
-
-	return 0;
-}
-
-static inline void dwc_chan_pause(struct dw_dma_chan *dwc)
-{
-	u32 cfglo = channel_readl(dwc, CFG_LO);
-	unsigned int count = 20;	/* timeout iterations */
-
-	channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP);
-	while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY) && count--)
-		udelay(2);
-
-	dwc->paused = true;
-}
-
-static inline void dwc_chan_resume(struct dw_dma_chan *dwc)
-{
-	u32 cfglo = channel_readl(dwc, CFG_LO);
-
-	channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP);
-
-	dwc->paused = false;
-}
-
-static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
-		       unsigned long arg)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma		*dw = to_dw_dma(chan->device);
-	struct dw_desc		*desc, *_desc;
-	unsigned long		flags;
-	LIST_HEAD(list);
-
-	if (cmd == DMA_PAUSE) {
-		spin_lock_irqsave(&dwc->lock, flags);
-
-		dwc_chan_pause(dwc);
-
-		spin_unlock_irqrestore(&dwc->lock, flags);
-	} else if (cmd == DMA_RESUME) {
-		if (!dwc->paused)
-			return 0;
-
-		spin_lock_irqsave(&dwc->lock, flags);
-
-		dwc_chan_resume(dwc);
-
-		spin_unlock_irqrestore(&dwc->lock, flags);
-	} else if (cmd == DMA_TERMINATE_ALL) {
-		spin_lock_irqsave(&dwc->lock, flags);
-
-		clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
-
-		dwc_chan_disable(dw, dwc);
-
-		dwc_chan_resume(dwc);
-
-		/* active_list entries will end up before queued entries */
-		list_splice_init(&dwc->queue, &list);
-		list_splice_init(&dwc->active_list, &list);
-
-		spin_unlock_irqrestore(&dwc->lock, flags);
-
-		/* Flush all pending and queued descriptors */
-		list_for_each_entry_safe(desc, _desc, &list, desc_node)
-			dwc_descriptor_complete(dwc, desc, false);
-	} else if (cmd == DMA_SLAVE_CONFIG) {
-		return set_runtime_config(chan, (struct dma_slave_config *)arg);
-	} else {
-		return -ENXIO;
-	}
-
-	return 0;
-}
-
-static inline u32 dwc_get_residue(struct dw_dma_chan *dwc)
-{
-	unsigned long flags;
-	u32 residue;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	residue = dwc->residue;
-	if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags) && residue)
-		residue -= dwc_get_sent(dwc);
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-	return residue;
-}
-
-static enum dma_status
-dwc_tx_status(struct dma_chan *chan,
-	      dma_cookie_t cookie,
-	      struct dma_tx_state *txstate)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	enum dma_status		ret;
-
-	ret = dma_cookie_status(chan, cookie, txstate);
-	if (ret != DMA_SUCCESS) {
-		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
-
-		ret = dma_cookie_status(chan, cookie, txstate);
-	}
-
-	if (ret != DMA_SUCCESS)
-		dma_set_residue(txstate, dwc_get_residue(dwc));
-
-	if (dwc->paused)
-		return DMA_PAUSED;
-
-	return ret;
-}
-
-static void dwc_issue_pending(struct dma_chan *chan)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-
-	if (!list_empty(&dwc->queue))
-		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
-}
-
-static int dwc_alloc_chan_resources(struct dma_chan *chan)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma		*dw = to_dw_dma(chan->device);
-	struct dw_desc		*desc;
-	int			i;
-	unsigned long		flags;
-
-	dev_vdbg(chan2dev(chan), "%s\n", __func__);
-
-	/* ASSERT:  channel is idle */
-	if (dma_readl(dw, CH_EN) & dwc->mask) {
-		dev_dbg(chan2dev(chan), "DMA channel not idle?\n");
-		return -EIO;
-	}
-
-	dma_cookie_init(chan);
-
-	/*
-	 * NOTE: some controllers may have additional features that we
-	 * need to initialize here, like "scatter-gather" (which
-	 * doesn't mean what you think it means), and status writeback.
-	 */
-
-	dwc_set_masters(dwc);
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	i = dwc->descs_allocated;
-	while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) {
-		dma_addr_t phys;
-
-		spin_unlock_irqrestore(&dwc->lock, flags);
-
-		desc = dma_pool_alloc(dw->desc_pool, GFP_ATOMIC, &phys);
-		if (!desc)
-			goto err_desc_alloc;
-
-		memset(desc, 0, sizeof(struct dw_desc));
-
-		INIT_LIST_HEAD(&desc->tx_list);
-		dma_async_tx_descriptor_init(&desc->txd, chan);
-		desc->txd.tx_submit = dwc_tx_submit;
-		desc->txd.flags = DMA_CTRL_ACK;
-		desc->txd.phys = phys;
-
-		dwc_desc_put(dwc, desc);
-
-		spin_lock_irqsave(&dwc->lock, flags);
-		i = ++dwc->descs_allocated;
-	}
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i);
-
-	return i;
-
-err_desc_alloc:
-	dev_info(chan2dev(chan), "only allocated %d descriptors\n", i);
-
-	return i;
-}
-
-static void dwc_free_chan_resources(struct dma_chan *chan)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma		*dw = to_dw_dma(chan->device);
-	struct dw_desc		*desc, *_desc;
-	unsigned long		flags;
-	LIST_HEAD(list);
-
-	dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__,
-			dwc->descs_allocated);
-
-	/* ASSERT:  channel is idle */
-	BUG_ON(!list_empty(&dwc->active_list));
-	BUG_ON(!list_empty(&dwc->queue));
-	BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask);
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	list_splice_init(&dwc->free_list, &list);
-	dwc->descs_allocated = 0;
-	dwc->initialized = false;
-	dwc->request_line = ~0;
-
-	/* Disable interrupts */
-	channel_clear_bit(dw, MASK.XFER, dwc->mask);
-	channel_clear_bit(dw, MASK.ERROR, dwc->mask);
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	list_for_each_entry_safe(desc, _desc, &list, desc_node) {
-		dev_vdbg(chan2dev(chan), "  freeing descriptor %p\n", desc);
-		dma_pool_free(dw->desc_pool, desc, desc->txd.phys);
-	}
-
-	dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
-}
-
-/*----------------------------------------------------------------------*/
-
-struct dw_dma_of_filter_args {
-	struct dw_dma *dw;
-	unsigned int req;
-	unsigned int src;
-	unsigned int dst;
-};
-
-static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
-{
-	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
-	struct dw_dma_of_filter_args *fargs = param;
-
-	/* Ensure the device matches our channel */
-        if (chan->device != &fargs->dw->dma)
-                return false;
-
-	dwc->request_line = fargs->req;
-	dwc->src_master	= fargs->src;
-	dwc->dst_master	= fargs->dst;
-
-	return true;
-}
-
-static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
-					struct of_dma *ofdma)
-{
-	struct dw_dma *dw = ofdma->of_dma_data;
-	struct dw_dma_of_filter_args fargs = {
-		.dw = dw,
-	};
-	dma_cap_mask_t cap;
-
-	if (dma_spec->args_count != 3)
-		return NULL;
-
-	fargs.req = dma_spec->args[0];
-	fargs.src = dma_spec->args[1];
-	fargs.dst = dma_spec->args[2];
-
-	if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
-		    fargs.src >= dw->nr_masters ||
-		    fargs.dst >= dw->nr_masters))
-		return NULL;
-
-	dma_cap_zero(cap);
-	dma_cap_set(DMA_SLAVE, cap);
-
-	/* TODO: there should be a simpler way to do this */
-	return dma_request_channel(cap, dw_dma_of_filter, &fargs);
-}
-
-#ifdef CONFIG_ACPI
-static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
-{
-	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
-	struct acpi_dma_spec *dma_spec = param;
-
-	if (chan->device->dev != dma_spec->dev ||
-	    chan->chan_id != dma_spec->chan_id)
-		return false;
-
-	dwc->request_line = dma_spec->slave_id;
-	dwc->src_master = dwc_get_sms(NULL);
-	dwc->dst_master = dwc_get_dms(NULL);
-
-	return true;
-}
-
-static void dw_dma_acpi_controller_register(struct dw_dma *dw)
-{
-	struct device *dev = dw->dma.dev;
-	struct acpi_dma_filter_info *info;
-	int ret;
-
-	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
-	if (!info)
-		return;
-
-	dma_cap_zero(info->dma_cap);
-	dma_cap_set(DMA_SLAVE, info->dma_cap);
-	info->filter_fn = dw_dma_acpi_filter;
-
-	ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate,
-						info);
-	if (ret)
-		dev_err(dev, "could not register acpi_dma_controller\n");
-}
-#else /* !CONFIG_ACPI */
-static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {}
-#endif /* !CONFIG_ACPI */
-
-/* --------------------- Cyclic DMA API extensions -------------------- */
-
-/**
- * dw_dma_cyclic_start - start the cyclic DMA transfer
- * @chan: the DMA channel to start
- *
- * Must be called with soft interrupts disabled. Returns zero on success or
- * -errno on failure.
- */
-int dw_dma_cyclic_start(struct dma_chan *chan)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
-	unsigned long		flags;
-
-	if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
-		dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
-		return -ENODEV;
-	}
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	/* Assert channel is idle */
-	if (dma_readl(dw, CH_EN) & dwc->mask) {
-		dev_err(chan2dev(&dwc->chan),
-			"BUG: Attempted to start non-idle channel\n");
-		dwc_dump_chan_regs(dwc);
-		spin_unlock_irqrestore(&dwc->lock, flags);
-		return -EBUSY;
-	}
-
-	dma_writel(dw, CLEAR.ERROR, dwc->mask);
-	dma_writel(dw, CLEAR.XFER, dwc->mask);
-
-	/* Setup DMAC channel registers */
-	channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
-	channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
-	channel_writel(dwc, CTL_HI, 0);
-
-	channel_set_bit(dw, CH_EN, dwc->mask);
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	return 0;
-}
-EXPORT_SYMBOL(dw_dma_cyclic_start);
-
-/**
- * dw_dma_cyclic_stop - stop the cyclic DMA transfer
- * @chan: the DMA channel to stop
- *
- * Must be called with soft interrupts disabled.
- */
-void dw_dma_cyclic_stop(struct dma_chan *chan)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
-	unsigned long		flags;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	dwc_chan_disable(dw, dwc);
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-}
-EXPORT_SYMBOL(dw_dma_cyclic_stop);
-
-/**
- * dw_dma_cyclic_prep - prepare the cyclic DMA transfer
- * @chan: the DMA channel to prepare
- * @buf_addr: physical DMA address where the buffer starts
- * @buf_len: total number of bytes for the entire buffer
- * @period_len: number of bytes for each period
- * @direction: transfer direction, to or from device
- *
- * Must be called before trying to start the transfer. Returns a valid struct
- * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful.
- */
-struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
-		dma_addr_t buf_addr, size_t buf_len, size_t period_len,
-		enum dma_transfer_direction direction)
-{
-	struct dw_dma_chan		*dwc = to_dw_dma_chan(chan);
-	struct dma_slave_config		*sconfig = &dwc->dma_sconfig;
-	struct dw_cyclic_desc		*cdesc;
-	struct dw_cyclic_desc		*retval = NULL;
-	struct dw_desc			*desc;
-	struct dw_desc			*last = NULL;
-	unsigned long			was_cyclic;
-	unsigned int			reg_width;
-	unsigned int			periods;
-	unsigned int			i;
-	unsigned long			flags;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-	if (dwc->nollp) {
-		spin_unlock_irqrestore(&dwc->lock, flags);
-		dev_dbg(chan2dev(&dwc->chan),
-				"channel doesn't support LLP transfers\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
-		spin_unlock_irqrestore(&dwc->lock, flags);
-		dev_dbg(chan2dev(&dwc->chan),
-				"queue and/or active list are not empty\n");
-		return ERR_PTR(-EBUSY);
-	}
-
-	was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
-	spin_unlock_irqrestore(&dwc->lock, flags);
-	if (was_cyclic) {
-		dev_dbg(chan2dev(&dwc->chan),
-				"channel already prepared for cyclic DMA\n");
-		return ERR_PTR(-EBUSY);
-	}
-
-	retval = ERR_PTR(-EINVAL);
-
-	if (unlikely(!is_slave_direction(direction)))
-		goto out_err;
-
-	dwc->direction = direction;
-
-	if (direction == DMA_MEM_TO_DEV)
-		reg_width = __ffs(sconfig->dst_addr_width);
-	else
-		reg_width = __ffs(sconfig->src_addr_width);
-
-	periods = buf_len / period_len;
-
-	/* Check for too big/unaligned periods and unaligned DMA buffer. */
-	if (period_len > (dwc->block_size << reg_width))
-		goto out_err;
-	if (unlikely(period_len & ((1 << reg_width) - 1)))
-		goto out_err;
-	if (unlikely(buf_addr & ((1 << reg_width) - 1)))
-		goto out_err;
-
-	retval = ERR_PTR(-ENOMEM);
-
-	if (periods > NR_DESCS_PER_CHANNEL)
-		goto out_err;
-
-	cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL);
-	if (!cdesc)
-		goto out_err;
-
-	cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL);
-	if (!cdesc->desc)
-		goto out_err_alloc;
-
-	for (i = 0; i < periods; i++) {
-		desc = dwc_desc_get(dwc);
-		if (!desc)
-			goto out_err_desc_get;
-
-		switch (direction) {
-		case DMA_MEM_TO_DEV:
-			desc->lli.dar = sconfig->dst_addr;
-			desc->lli.sar = buf_addr + (period_len * i);
-			desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan)
-					| DWC_CTLL_DST_WIDTH(reg_width)
-					| DWC_CTLL_SRC_WIDTH(reg_width)
-					| DWC_CTLL_DST_FIX
-					| DWC_CTLL_SRC_INC
-					| DWC_CTLL_INT_EN);
-
-			desc->lli.ctllo |= sconfig->device_fc ?
-				DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
-				DWC_CTLL_FC(DW_DMA_FC_D_M2P);
-
-			break;
-		case DMA_DEV_TO_MEM:
-			desc->lli.dar = buf_addr + (period_len * i);
-			desc->lli.sar = sconfig->src_addr;
-			desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan)
-					| DWC_CTLL_SRC_WIDTH(reg_width)
-					| DWC_CTLL_DST_WIDTH(reg_width)
-					| DWC_CTLL_DST_INC
-					| DWC_CTLL_SRC_FIX
-					| DWC_CTLL_INT_EN);
-
-			desc->lli.ctllo |= sconfig->device_fc ?
-				DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
-				DWC_CTLL_FC(DW_DMA_FC_D_P2M);
-
-			break;
-		default:
-			break;
-		}
-
-		desc->lli.ctlhi = (period_len >> reg_width);
-		cdesc->desc[i] = desc;
-
-		if (last)
-			last->lli.llp = desc->txd.phys;
-
-		last = desc;
-	}
-
-	/* Let's make a cyclic list */
-	last->lli.llp = cdesc->desc[0]->txd.phys;
-
-	dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu "
-			"period %zu periods %d\n", (unsigned long long)buf_addr,
-			buf_len, period_len, periods);
-
-	cdesc->periods = periods;
-	dwc->cdesc = cdesc;
-
-	return cdesc;
-
-out_err_desc_get:
-	while (i--)
-		dwc_desc_put(dwc, cdesc->desc[i]);
-out_err_alloc:
-	kfree(cdesc);
-out_err:
-	clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
-	return (struct dw_cyclic_desc *)retval;
-}
-EXPORT_SYMBOL(dw_dma_cyclic_prep);
-
-/**
- * dw_dma_cyclic_free - free a prepared cyclic DMA transfer
- * @chan: the DMA channel to free
- */
-void dw_dma_cyclic_free(struct dma_chan *chan)
-{
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
-	struct dw_cyclic_desc	*cdesc = dwc->cdesc;
-	int			i;
-	unsigned long		flags;
-
-	dev_dbg(chan2dev(&dwc->chan), "%s\n", __func__);
-
-	if (!cdesc)
-		return;
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	dwc_chan_disable(dw, dwc);
-
-	dma_writel(dw, CLEAR.ERROR, dwc->mask);
-	dma_writel(dw, CLEAR.XFER, dwc->mask);
-
-	spin_unlock_irqrestore(&dwc->lock, flags);
-
-	for (i = 0; i < cdesc->periods; i++)
-		dwc_desc_put(dwc, cdesc->desc[i]);
-
-	kfree(cdesc->desc);
-	kfree(cdesc);
-
-	clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
-}
-EXPORT_SYMBOL(dw_dma_cyclic_free);
-
-/*----------------------------------------------------------------------*/
-
-static void dw_dma_off(struct dw_dma *dw)
-{
-	int i;
-
-	dma_writel(dw, CFG, 0);
-
-	channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
-	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
-
-	while (dma_readl(dw, CFG) & DW_CFG_DMA_EN)
-		cpu_relax();
-
-	for (i = 0; i < dw->dma.chancnt; i++)
-		dw->chan[i].initialized = false;
-}
-
-#ifdef CONFIG_OF
-static struct dw_dma_platform_data *
-dw_dma_parse_dt(struct platform_device *pdev)
-{
-	struct device_node *np = pdev->dev.of_node;
-	struct dw_dma_platform_data *pdata;
-	u32 tmp, arr[4];
-
-	if (!np) {
-		dev_err(&pdev->dev, "Missing DT data\n");
-		return NULL;
-	}
-
-	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata)
-		return NULL;
-
-	if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
-		return NULL;
-
-	if (of_property_read_bool(np, "is_private"))
-		pdata->is_private = true;
-
-	if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
-		pdata->chan_allocation_order = (unsigned char)tmp;
-
-	if (!of_property_read_u32(np, "chan_priority", &tmp))
-		pdata->chan_priority = tmp;
-
-	if (!of_property_read_u32(np, "block_size", &tmp))
-		pdata->block_size = tmp;
-
-	if (!of_property_read_u32(np, "dma-masters", &tmp)) {
-		if (tmp > 4)
-			return NULL;
-
-		pdata->nr_masters = tmp;
-	}
-
-	if (!of_property_read_u32_array(np, "data_width", arr,
-				pdata->nr_masters))
-		for (tmp = 0; tmp < pdata->nr_masters; tmp++)
-			pdata->data_width[tmp] = arr[tmp];
-
-	return pdata;
-}
-#else
-static inline struct dw_dma_platform_data *
-dw_dma_parse_dt(struct platform_device *pdev)
-{
-	return NULL;
-}
-#endif
-
-static int dw_probe(struct platform_device *pdev)
-{
-	struct dw_dma_platform_data *pdata;
-	struct resource		*io;
-	struct dw_dma		*dw;
-	size_t			size;
-	void __iomem		*regs;
-	bool			autocfg;
-	unsigned int		dw_params;
-	unsigned int		nr_channels;
-	unsigned int		max_blk_size = 0;
-	int			irq;
-	int			err;
-	int			i;
-
-	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!io)
-		return -EINVAL;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
-	regs = devm_ioremap_resource(&pdev->dev, io);
-	if (IS_ERR(regs))
-		return PTR_ERR(regs);
-
-	/* Apply default dma_mask if needed */
-	if (!pdev->dev.dma_mask) {
-		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-	}
-
-	dw_params = dma_read_byaddr(regs, DW_PARAMS);
-	autocfg = dw_params >> DW_PARAMS_EN & 0x1;
-
-	dev_dbg(&pdev->dev, "DW_PARAMS: 0x%08x\n", dw_params);
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata)
-		pdata = dw_dma_parse_dt(pdev);
-
-	if (!pdata && autocfg) {
-		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-		if (!pdata)
-			return -ENOMEM;
-
-		/* Fill platform data with the default values */
-		pdata->is_private = true;
-		pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING;
-		pdata->chan_priority = CHAN_PRIORITY_ASCENDING;
-	} else if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS)
-		return -EINVAL;
-
-	if (autocfg)
-		nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1;
-	else
-		nr_channels = pdata->nr_channels;
-
-	size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan);
-	dw = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
-	if (!dw)
-		return -ENOMEM;
-
-	dw->clk = devm_clk_get(&pdev->dev, "hclk");
-	if (IS_ERR(dw->clk))
-		return PTR_ERR(dw->clk);
-	clk_prepare_enable(dw->clk);
-
-	dw->regs = regs;
-
-	/* Get hardware configuration parameters */
-	if (autocfg) {
-		max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
-
-		dw->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
-		for (i = 0; i < dw->nr_masters; i++) {
-			dw->data_width[i] =
-				(dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
-		}
-	} else {
-		dw->nr_masters = pdata->nr_masters;
-		memcpy(dw->data_width, pdata->data_width, 4);
-	}
-
-	/* Calculate all channel mask before DMA setup */
-	dw->all_chan_mask = (1 << nr_channels) - 1;
-
-	/* Force dma off, just in case */
-	dw_dma_off(dw);
-
-	/* Disable BLOCK interrupts as well */
-	channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
-
-	err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0,
-			       "dw_dmac", dw);
-	if (err)
-		return err;
-
-	platform_set_drvdata(pdev, dw);
-
-	/* Create a pool of consistent memory blocks for hardware descriptors */
-	dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", &pdev->dev,
-					 sizeof(struct dw_desc), 4, 0);
-	if (!dw->desc_pool) {
-		dev_err(&pdev->dev, "No memory for descriptors dma pool\n");
-		return -ENOMEM;
-	}
-
-	tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
-
-	INIT_LIST_HEAD(&dw->dma.channels);
-	for (i = 0; i < nr_channels; i++) {
-		struct dw_dma_chan	*dwc = &dw->chan[i];
-		int			r = nr_channels - i - 1;
-
-		dwc->chan.device = &dw->dma;
-		dma_cookie_init(&dwc->chan);
-		if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
-			list_add_tail(&dwc->chan.device_node,
-					&dw->dma.channels);
-		else
-			list_add(&dwc->chan.device_node, &dw->dma.channels);
-
-		/* 7 is highest priority & 0 is lowest. */
-		if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING)
-			dwc->priority = r;
-		else
-			dwc->priority = i;
-
-		dwc->ch_regs = &__dw_regs(dw)->CHAN[i];
-		spin_lock_init(&dwc->lock);
-		dwc->mask = 1 << i;
-
-		INIT_LIST_HEAD(&dwc->active_list);
-		INIT_LIST_HEAD(&dwc->queue);
-		INIT_LIST_HEAD(&dwc->free_list);
-
-		channel_clear_bit(dw, CH_EN, dwc->mask);
-
-		dwc->direction = DMA_TRANS_NONE;
-		dwc->request_line = ~0;
-
-		/* Hardware configuration */
-		if (autocfg) {
-			unsigned int dwc_params;
-
-			dwc_params = dma_read_byaddr(regs + r * sizeof(u32),
-						     DWC_PARAMS);
-
-			dev_dbg(&pdev->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
-					    dwc_params);
-
-			/* Decode maximum block size for given channel. The
-			 * stored 4 bit value represents blocks from 0x00 for 3
-			 * up to 0x0a for 4095. */
-			dwc->block_size =
-				(4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
-			dwc->nollp =
-				(dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0;
-		} else {
-			dwc->block_size = pdata->block_size;
-
-			/* Check if channel supports multi block transfer */
-			channel_writel(dwc, LLP, 0xfffffffc);
-			dwc->nollp =
-				(channel_readl(dwc, LLP) & 0xfffffffc) == 0;
-			channel_writel(dwc, LLP, 0);
-		}
-	}
-
-	/* Clear all interrupts on all channels. */
-	dma_writel(dw, CLEAR.XFER, dw->all_chan_mask);
-	dma_writel(dw, CLEAR.BLOCK, dw->all_chan_mask);
-	dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask);
-	dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
-	dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
-
-	dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
-	dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
-	if (pdata->is_private)
-		dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask);
-	dw->dma.dev = &pdev->dev;
-	dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
-	dw->dma.device_free_chan_resources = dwc_free_chan_resources;
-
-	dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy;
-
-	dw->dma.device_prep_slave_sg = dwc_prep_slave_sg;
-	dw->dma.device_control = dwc_control;
-
-	dw->dma.device_tx_status = dwc_tx_status;
-	dw->dma.device_issue_pending = dwc_issue_pending;
-
-	dma_writel(dw, CFG, DW_CFG_DMA_EN);
-
-	dev_info(&pdev->dev, "DesignWare DMA Controller, %d channels\n",
-		 nr_channels);
-
-	dma_async_device_register(&dw->dma);
-
-	if (pdev->dev.of_node) {
-		err = of_dma_controller_register(pdev->dev.of_node,
-						 dw_dma_of_xlate, dw);
-		if (err)
-			dev_err(&pdev->dev,
-				"could not register of_dma_controller\n");
-	}
-
-	if (ACPI_HANDLE(&pdev->dev))
-		dw_dma_acpi_controller_register(dw);
-
-	return 0;
-}
-
-static int dw_remove(struct platform_device *pdev)
-{
-	struct dw_dma		*dw = platform_get_drvdata(pdev);
-	struct dw_dma_chan	*dwc, *_dwc;
-
-	if (pdev->dev.of_node)
-		of_dma_controller_free(pdev->dev.of_node);
-	dw_dma_off(dw);
-	dma_async_device_unregister(&dw->dma);
-
-	tasklet_kill(&dw->tasklet);
-
-	list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels,
-			chan.device_node) {
-		list_del(&dwc->chan.device_node);
-		channel_clear_bit(dw, CH_EN, dwc->mask);
-	}
-
-	return 0;
-}
-
-static void dw_shutdown(struct platform_device *pdev)
-{
-	struct dw_dma	*dw = platform_get_drvdata(pdev);
-
-	dw_dma_off(dw);
-	clk_disable_unprepare(dw->clk);
-}
-
-static int dw_suspend_noirq(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct dw_dma	*dw = platform_get_drvdata(pdev);
-
-	dw_dma_off(dw);
-	clk_disable_unprepare(dw->clk);
-
-	return 0;
-}
-
-static int dw_resume_noirq(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct dw_dma	*dw = platform_get_drvdata(pdev);
-
-	clk_prepare_enable(dw->clk);
-	dma_writel(dw, CFG, DW_CFG_DMA_EN);
-
-	return 0;
-}
-
-static const struct dev_pm_ops dw_dev_pm_ops = {
-	.suspend_noirq = dw_suspend_noirq,
-	.resume_noirq = dw_resume_noirq,
-	.freeze_noirq = dw_suspend_noirq,
-	.thaw_noirq = dw_resume_noirq,
-	.restore_noirq = dw_resume_noirq,
-	.poweroff_noirq = dw_suspend_noirq,
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id dw_dma_of_id_table[] = {
-	{ .compatible = "snps,dma-spear1340" },
-	{}
-};
-MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
-#endif
-
-#ifdef CONFIG_ACPI
-static const struct acpi_device_id dw_dma_acpi_id_table[] = {
-	{ "INTL9C60", 0 },
-	{ }
-};
-#endif
-
-static struct platform_driver dw_driver = {
-	.probe		= dw_probe,
-	.remove		= dw_remove,
-	.shutdown	= dw_shutdown,
-	.driver = {
-		.name	= "dw_dmac",
-		.pm	= &dw_dev_pm_ops,
-		.of_match_table = of_match_ptr(dw_dma_of_id_table),
-		.acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
-	},
-};
-
-static int __init dw_init(void)
-{
-	return platform_driver_register(&dw_driver);
-}
-subsys_initcall(dw_init);
-
-static void __exit dw_exit(void)
-{
-	platform_driver_unregister(&dw_driver);
-}
-module_exit(dw_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver");
-MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
-MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/dw_dmac_regs.h linux-libre-3.11-rc7-gnu/drivers/dma/dw_dmac_regs.h
--- linux-libre-3.10-gnu/drivers/dma/dw_dmac_regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/dw_dmac_regs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,311 +0,0 @@
-/*
- * Driver for the Synopsys DesignWare AHB DMA Controller
- *
- * Copyright (C) 2005-2007 Atmel Corporation
- * Copyright (C) 2010-2011 ST Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/dmaengine.h>
-#include <linux/dw_dmac.h>
-
-#define DW_DMA_MAX_NR_CHANNELS	8
-#define DW_DMA_MAX_NR_REQUESTS	16
-
-/* flow controller */
-enum dw_dma_fc {
-	DW_DMA_FC_D_M2M,
-	DW_DMA_FC_D_M2P,
-	DW_DMA_FC_D_P2M,
-	DW_DMA_FC_D_P2P,
-	DW_DMA_FC_P_P2M,
-	DW_DMA_FC_SP_P2P,
-	DW_DMA_FC_P_M2P,
-	DW_DMA_FC_DP_P2P,
-};
-
-/*
- * Redefine this macro to handle differences between 32- and 64-bit
- * addressing, big vs. little endian, etc.
- */
-#define DW_REG(name)		u32 name; u32 __pad_##name
-
-/* Hardware register definitions. */
-struct dw_dma_chan_regs {
-	DW_REG(SAR);		/* Source Address Register */
-	DW_REG(DAR);		/* Destination Address Register */
-	DW_REG(LLP);		/* Linked List Pointer */
-	u32	CTL_LO;		/* Control Register Low */
-	u32	CTL_HI;		/* Control Register High */
-	DW_REG(SSTAT);
-	DW_REG(DSTAT);
-	DW_REG(SSTATAR);
-	DW_REG(DSTATAR);
-	u32	CFG_LO;		/* Configuration Register Low */
-	u32	CFG_HI;		/* Configuration Register High */
-	DW_REG(SGR);
-	DW_REG(DSR);
-};
-
-struct dw_dma_irq_regs {
-	DW_REG(XFER);
-	DW_REG(BLOCK);
-	DW_REG(SRC_TRAN);
-	DW_REG(DST_TRAN);
-	DW_REG(ERROR);
-};
-
-struct dw_dma_regs {
-	/* per-channel registers */
-	struct dw_dma_chan_regs	CHAN[DW_DMA_MAX_NR_CHANNELS];
-
-	/* irq handling */
-	struct dw_dma_irq_regs	RAW;		/* r */
-	struct dw_dma_irq_regs	STATUS;		/* r (raw & mask) */
-	struct dw_dma_irq_regs	MASK;		/* rw (set = irq enabled) */
-	struct dw_dma_irq_regs	CLEAR;		/* w (ack, affects "raw") */
-
-	DW_REG(STATUS_INT);			/* r */
-
-	/* software handshaking */
-	DW_REG(REQ_SRC);
-	DW_REG(REQ_DST);
-	DW_REG(SGL_REQ_SRC);
-	DW_REG(SGL_REQ_DST);
-	DW_REG(LAST_SRC);
-	DW_REG(LAST_DST);
-
-	/* miscellaneous */
-	DW_REG(CFG);
-	DW_REG(CH_EN);
-	DW_REG(ID);
-	DW_REG(TEST);
-
-	/* reserved */
-	DW_REG(__reserved0);
-	DW_REG(__reserved1);
-
-	/* optional encoded params, 0x3c8..0x3f7 */
-	u32	__reserved;
-
-	/* per-channel configuration registers */
-	u32	DWC_PARAMS[DW_DMA_MAX_NR_CHANNELS];
-	u32	MULTI_BLK_TYPE;
-	u32	MAX_BLK_SIZE;
-
-	/* top-level parameters */
-	u32	DW_PARAMS;
-};
-
-#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
-#define dma_readl_native ioread32be
-#define dma_writel_native iowrite32be
-#else
-#define dma_readl_native readl
-#define dma_writel_native writel
-#endif
-
-/* To access the registers in early stage of probe */
-#define dma_read_byaddr(addr, name) \
-	dma_readl_native((addr) + offsetof(struct dw_dma_regs, name))
-
-/* Bitfields in DW_PARAMS */
-#define DW_PARAMS_NR_CHAN	8		/* number of channels */
-#define DW_PARAMS_NR_MASTER	11		/* number of AHB masters */
-#define DW_PARAMS_DATA_WIDTH(n)	(15 + 2 * (n))
-#define DW_PARAMS_DATA_WIDTH1	15		/* master 1 data width */
-#define DW_PARAMS_DATA_WIDTH2	17		/* master 2 data width */
-#define DW_PARAMS_DATA_WIDTH3	19		/* master 3 data width */
-#define DW_PARAMS_DATA_WIDTH4	21		/* master 4 data width */
-#define DW_PARAMS_EN		28		/* encoded parameters */
-
-/* Bitfields in DWC_PARAMS */
-#define DWC_PARAMS_MBLK_EN	11		/* multi block transfer */
-
-/* Bitfields in CTL_LO */
-#define DWC_CTLL_INT_EN		(1 << 0)	/* irqs enabled? */
-#define DWC_CTLL_DST_WIDTH(n)	((n)<<1)	/* bytes per element */
-#define DWC_CTLL_SRC_WIDTH(n)	((n)<<4)
-#define DWC_CTLL_DST_INC	(0<<7)		/* DAR update/not */
-#define DWC_CTLL_DST_DEC	(1<<7)
-#define DWC_CTLL_DST_FIX	(2<<7)
-#define DWC_CTLL_SRC_INC	(0<<7)		/* SAR update/not */
-#define DWC_CTLL_SRC_DEC	(1<<9)
-#define DWC_CTLL_SRC_FIX	(2<<9)
-#define DWC_CTLL_DST_MSIZE(n)	((n)<<11)	/* burst, #elements */
-#define DWC_CTLL_SRC_MSIZE(n)	((n)<<14)
-#define DWC_CTLL_S_GATH_EN	(1 << 17)	/* src gather, !FIX */
-#define DWC_CTLL_D_SCAT_EN	(1 << 18)	/* dst scatter, !FIX */
-#define DWC_CTLL_FC(n)		((n) << 20)
-#define DWC_CTLL_FC_M2M		(0 << 20)	/* mem-to-mem */
-#define DWC_CTLL_FC_M2P		(1 << 20)	/* mem-to-periph */
-#define DWC_CTLL_FC_P2M		(2 << 20)	/* periph-to-mem */
-#define DWC_CTLL_FC_P2P		(3 << 20)	/* periph-to-periph */
-/* plus 4 transfer types for peripheral-as-flow-controller */
-#define DWC_CTLL_DMS(n)		((n)<<23)	/* dst master select */
-#define DWC_CTLL_SMS(n)		((n)<<25)	/* src master select */
-#define DWC_CTLL_LLP_D_EN	(1 << 27)	/* dest block chain */
-#define DWC_CTLL_LLP_S_EN	(1 << 28)	/* src block chain */
-
-/* Bitfields in CTL_HI */
-#define DWC_CTLH_DONE		0x00001000
-#define DWC_CTLH_BLOCK_TS_MASK	0x00000fff
-
-/* Bitfields in CFG_LO. Platform-configurable bits are in <linux/dw_dmac.h> */
-#define DWC_CFGL_CH_PRIOR_MASK	(0x7 << 5)	/* priority mask */
-#define DWC_CFGL_CH_PRIOR(x)	((x) << 5)	/* priority */
-#define DWC_CFGL_CH_SUSP	(1 << 8)	/* pause xfer */
-#define DWC_CFGL_FIFO_EMPTY	(1 << 9)	/* pause xfer */
-#define DWC_CFGL_HS_DST		(1 << 10)	/* handshake w/dst */
-#define DWC_CFGL_HS_SRC		(1 << 11)	/* handshake w/src */
-#define DWC_CFGL_MAX_BURST(x)	((x) << 20)
-#define DWC_CFGL_RELOAD_SAR	(1 << 30)
-#define DWC_CFGL_RELOAD_DAR	(1 << 31)
-
-/* Bitfields in CFG_HI. Platform-configurable bits are in <linux/dw_dmac.h> */
-#define DWC_CFGH_DS_UPD_EN	(1 << 5)
-#define DWC_CFGH_SS_UPD_EN	(1 << 6)
-
-/* Bitfields in SGR */
-#define DWC_SGR_SGI(x)		((x) << 0)
-#define DWC_SGR_SGC(x)		((x) << 20)
-
-/* Bitfields in DSR */
-#define DWC_DSR_DSI(x)		((x) << 0)
-#define DWC_DSR_DSC(x)		((x) << 20)
-
-/* Bitfields in CFG */
-#define DW_CFG_DMA_EN		(1 << 0)
-
-enum dw_dmac_flags {
-	DW_DMA_IS_CYCLIC = 0,
-	DW_DMA_IS_SOFT_LLP = 1,
-};
-
-struct dw_dma_chan {
-	struct dma_chan			chan;
-	void __iomem			*ch_regs;
-	u8				mask;
-	u8				priority;
-	enum dma_transfer_direction	direction;
-	bool				paused;
-	bool				initialized;
-
-	/* software emulation of the LLP transfers */
-	struct list_head	*tx_node_active;
-
-	spinlock_t		lock;
-
-	/* these other elements are all protected by lock */
-	unsigned long		flags;
-	struct list_head	active_list;
-	struct list_head	queue;
-	struct list_head	free_list;
-	u32			residue;
-	struct dw_cyclic_desc	*cdesc;
-
-	unsigned int		descs_allocated;
-
-	/* hardware configuration */
-	unsigned int		block_size;
-	bool			nollp;
-
-	/* custom slave configuration */
-	unsigned int		request_line;
-	unsigned char		src_master;
-	unsigned char		dst_master;
-
-	/* configuration passed via DMA_SLAVE_CONFIG */
-	struct dma_slave_config dma_sconfig;
-};
-
-static inline struct dw_dma_chan_regs __iomem *
-__dwc_regs(struct dw_dma_chan *dwc)
-{
-	return dwc->ch_regs;
-}
-
-#define channel_readl(dwc, name) \
-	dma_readl_native(&(__dwc_regs(dwc)->name))
-#define channel_writel(dwc, name, val) \
-	dma_writel_native((val), &(__dwc_regs(dwc)->name))
-
-static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
-{
-	return container_of(chan, struct dw_dma_chan, chan);
-}
-
-struct dw_dma {
-	struct dma_device	dma;
-	void __iomem		*regs;
-	struct dma_pool		*desc_pool;
-	struct tasklet_struct	tasklet;
-	struct clk		*clk;
-
-	u8			all_chan_mask;
-
-	/* hardware configuration */
-	unsigned char		nr_masters;
-	unsigned char		data_width[4];
-
-	struct dw_dma_chan	chan[0];
-};
-
-static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
-{
-	return dw->regs;
-}
-
-#define dma_readl(dw, name) \
-	dma_readl_native(&(__dw_regs(dw)->name))
-#define dma_writel(dw, name, val) \
-	dma_writel_native((val), &(__dw_regs(dw)->name))
-
-#define channel_set_bit(dw, reg, mask) \
-	dma_writel(dw, reg, ((mask) << 8) | (mask))
-#define channel_clear_bit(dw, reg, mask) \
-	dma_writel(dw, reg, ((mask) << 8) | 0)
-
-static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
-{
-	return container_of(ddev, struct dw_dma, dma);
-}
-
-/* LLI == Linked List Item; a.k.a. DMA block descriptor */
-struct dw_lli {
-	/* values that are not changed by hardware */
-	u32		sar;
-	u32		dar;
-	u32		llp;		/* chain to next lli */
-	u32		ctllo;
-	/* values that may get written back: */
-	u32		ctlhi;
-	/* sstat and dstat can snapshot peripheral register state.
-	 * silicon config may discard either or both...
-	 */
-	u32		sstat;
-	u32		dstat;
-};
-
-struct dw_desc {
-	/* FIRST values the hardware uses */
-	struct dw_lli			lli;
-
-	/* THEN values for driver housekeeping */
-	struct list_head		desc_node;
-	struct list_head		tx_list;
-	struct dma_async_tx_descriptor	txd;
-	size_t				len;
-	size_t				total_len;
-};
-
-#define to_dw_desc(h)	list_entry(h, struct dw_desc, desc_node)
-
-static inline struct dw_desc *
-txd_to_dw_desc(struct dma_async_tx_descriptor *txd)
-{
-	return container_of(txd, struct dw_desc, txd);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/edma.c linux-libre-3.11-rc7-gnu/drivers/dma/edma.c
--- linux-libre-3.10-gnu/drivers/dma/edma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/edma.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
-#include <mach/edma.h>
+#include <linux/platform_data/edma.h>
 
 #include "dmaengine.h"
 #include "virt-dma.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/fsldma.c linux-libre-3.11-rc7-gnu/drivers/dma/fsldma.c
--- linux-libre-3.10-gnu/drivers/dma/fsldma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/fsldma.c	2013-08-25 20:43:22.000000000 -0400
@@ -1368,7 +1368,7 @@ static int fsldma_of_probe(struct platfo
 
 	dma_set_mask(&(op->dev), DMA_BIT_MASK(36));
 
-	dev_set_drvdata(&op->dev, fdev);
+	platform_set_drvdata(op, fdev);
 
 	/*
 	 * We cannot use of_platform_bus_probe() because there is no
@@ -1417,7 +1417,7 @@ static int fsldma_of_remove(struct platf
 	struct fsldma_device *fdev;
 	unsigned int i;
 
-	fdev = dev_get_drvdata(&op->dev);
+	fdev = platform_get_drvdata(op);
 	dma_async_device_unregister(&fdev->common);
 
 	fsldma_free_irqs(fdev);
@@ -1428,7 +1428,6 @@ static int fsldma_of_remove(struct platf
 	}
 
 	iounmap(fdev->regs);
-	dev_set_drvdata(&op->dev, NULL);
 	kfree(fdev);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/imx-dma.c linux-libre-3.11-rc7-gnu/drivers/dma/imx-dma.c
--- linux-libre-3.10-gnu/drivers/dma/imx-dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/imx-dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,8 @@
 #include <linux/clk.h>
 #include <linux/dmaengine.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
 
 #include <asm/irq.h>
 #include <linux/platform_data/dma-imx.h>
@@ -186,6 +188,11 @@ struct imxdma_engine {
 	enum imx_dma_type		devtype;
 };
 
+struct imxdma_filter_data {
+	struct imxdma_engine	*imxdma;
+	int			 request;
+};
+
 static struct platform_device_id imx_dma_devtype[] = {
 	{
 		.name = "imx1-dma",
@@ -202,6 +209,22 @@ static struct platform_device_id imx_dma
 };
 MODULE_DEVICE_TABLE(platform, imx_dma_devtype);
 
+static const struct of_device_id imx_dma_of_dev_id[] = {
+	{
+		.compatible = "fsl,imx1-dma",
+		.data = &imx_dma_devtype[IMX1_DMA],
+	}, {
+		.compatible = "fsl,imx21-dma",
+		.data = &imx_dma_devtype[IMX21_DMA],
+	}, {
+		.compatible = "fsl,imx27-dma",
+		.data = &imx_dma_devtype[IMX27_DMA],
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, imx_dma_of_dev_id);
+
 static inline int is_imx1_dma(struct imxdma_engine *imxdma)
 {
 	return imxdma->devtype == IMX1_DMA;
@@ -996,17 +1019,55 @@ static void imxdma_issue_pending(struct
 	spin_unlock_irqrestore(&imxdma->lock, flags);
 }
 
+static bool imxdma_filter_fn(struct dma_chan *chan, void *param)
+{
+	struct imxdma_filter_data *fdata = param;
+	struct imxdma_channel *imxdma_chan = to_imxdma_chan(chan);
+
+	if (chan->device->dev != fdata->imxdma->dev)
+		return false;
+
+	imxdma_chan->dma_request = fdata->request;
+	chan->private = NULL;
+
+	return true;
+}
+
+static struct dma_chan *imxdma_xlate(struct of_phandle_args *dma_spec,
+						struct of_dma *ofdma)
+{
+	int count = dma_spec->args_count;
+	struct imxdma_engine *imxdma = ofdma->of_dma_data;
+	struct imxdma_filter_data fdata = {
+		.imxdma = imxdma,
+	};
+
+	if (count != 1)
+		return NULL;
+
+	fdata.request = dma_spec->args[0];
+
+	return dma_request_channel(imxdma->dma_device.cap_mask,
+					imxdma_filter_fn, &fdata);
+}
+
 static int __init imxdma_probe(struct platform_device *pdev)
 	{
 	struct imxdma_engine *imxdma;
 	struct resource *res;
+	const struct of_device_id *of_id;
 	int ret, i;
 	int irq, irq_err;
 
+	of_id = of_match_device(imx_dma_of_dev_id, &pdev->dev);
+	if (of_id)
+		pdev->id_entry = of_id->data;
+
 	imxdma = devm_kzalloc(&pdev->dev, sizeof(*imxdma), GFP_KERNEL);
 	if (!imxdma)
 		return -ENOMEM;
 
+	imxdma->dev = &pdev->dev;
 	imxdma->devtype = pdev->id_entry->driver_data;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1111,7 +1172,6 @@ static int __init imxdma_probe(struct pl
 			      &imxdma->dma_device.channels);
 	}
 
-	imxdma->dev = &pdev->dev;
 	imxdma->dma_device.dev = &pdev->dev;
 
 	imxdma->dma_device.device_alloc_chan_resources = imxdma_alloc_chan_resources;
@@ -1136,8 +1196,19 @@ static int __init imxdma_probe(struct pl
 		goto err;
 	}
 
+	if (pdev->dev.of_node) {
+		ret = of_dma_controller_register(pdev->dev.of_node,
+				imxdma_xlate, imxdma);
+		if (ret) {
+			dev_err(&pdev->dev, "unable to register of_dma_controller\n");
+			goto err_of_dma_controller;
+		}
+	}
+
 	return 0;
 
+err_of_dma_controller:
+	dma_async_device_unregister(&imxdma->dma_device);
 err:
 	clk_disable_unprepare(imxdma->dma_ipg);
 	clk_disable_unprepare(imxdma->dma_ahb);
@@ -1150,6 +1221,9 @@ static int imxdma_remove(struct platform
 
         dma_async_device_unregister(&imxdma->dma_device);
 
+	if (pdev->dev.of_node)
+		of_dma_controller_free(pdev->dev.of_node);
+
 	clk_disable_unprepare(imxdma->dma_ipg);
 	clk_disable_unprepare(imxdma->dma_ahb);
 
@@ -1159,6 +1233,7 @@ static int imxdma_remove(struct platform
 static struct platform_driver imxdma_driver = {
 	.driver		= {
 		.name	= "imx-dma",
+		.of_match_table = imx_dma_of_dev_id,
 	},
 	.id_table	= imx_dma_devtype,
 	.remove		= imxdma_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/imx-sdma.c linux-libre-3.11-rc7-gnu/drivers/dma/imx-sdma.c
--- linux-libre-3.10-gnu/drivers/dma/imx-sdma.c	2013-07-01 10:32:27.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/imx-sdma.c	2013-08-31 17:51:54.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/dmaengine.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_dma.h>
 
 #include <asm/irq.h>
 #include <linux/platform_data/dma-imx-sdma.h>
@@ -1296,6 +1297,35 @@ err_dma_alloc:
 	return ret;
 }
 
+static bool sdma_filter_fn(struct dma_chan *chan, void *fn_param)
+{
+	struct imx_dma_data *data = fn_param;
+
+	if (!imx_dma_is_general_purpose(chan))
+		return false;
+
+	chan->private = data;
+
+	return true;
+}
+
+static struct dma_chan *sdma_xlate(struct of_phandle_args *dma_spec,
+				   struct of_dma *ofdma)
+{
+	struct sdma_engine *sdma = ofdma->of_dma_data;
+	dma_cap_mask_t mask = sdma->dma_device.cap_mask;
+	struct imx_dma_data data;
+
+	if (dma_spec->args_count != 3)
+		return NULL;
+
+	data.dma_request = dma_spec->args[0];
+	data.peripheral_type = dma_spec->args[1];
+	data.priority = dma_spec->args[2];
+
+	return dma_request_channel(mask, sdma_filter_fn, &data);
+}
+
 static int __init sdma_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *of_id =
@@ -1443,10 +1473,20 @@ static int __init sdma_probe(struct plat
 		goto err_init;
 	}
 
+	if (np) {
+		ret = of_dma_controller_register(np, sdma_xlate, sdma);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to register controller\n");
+			goto err_register;
+		}
+	}
+
 	dev_info(sdma->dev, "initialized\n");
 
 	return 0;
 
+err_register:
+	dma_async_device_unregister(&sdma->dma_device);
 err_init:
 	kfree(sdma->script_addrs);
 err_alloc:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/intel_mid_dma.c linux-libre-3.11-rc7-gnu/drivers/dma/intel_mid_dma.c
--- linux-libre-3.10-gnu/drivers/dma/intel_mid_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/intel_mid_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -1405,7 +1405,7 @@ static int dma_runtime_idle(struct devic
 			return -EAGAIN;
 	}
 
-	return pm_schedule_suspend(dev, 0);
+	return 0;
 }
 
 /******************************************************************************
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/ioat/dma.c linux-libre-3.11-rc7-gnu/drivers/dma/ioat/dma.c
--- linux-libre-3.10-gnu/drivers/dma/ioat/dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/ioat/dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -1105,12 +1105,11 @@ static ssize_t cap_show(struct dma_chan
 {
 	struct dma_device *dma = c->device;
 
-	return sprintf(page, "copy%s%s%s%s%s%s\n",
+	return sprintf(page, "copy%s%s%s%s%s\n",
 		       dma_has_cap(DMA_PQ, dma->cap_mask) ? " pq" : "",
 		       dma_has_cap(DMA_PQ_VAL, dma->cap_mask) ? " pq_val" : "",
 		       dma_has_cap(DMA_XOR, dma->cap_mask) ? " xor" : "",
 		       dma_has_cap(DMA_XOR_VAL, dma->cap_mask) ? " xor_val" : "",
-		       dma_has_cap(DMA_MEMSET, dma->cap_mask)  ? " fill" : "",
 		       dma_has_cap(DMA_INTERRUPT, dma->cap_mask) ? " intr" : "");
 
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/ioat/dma_v2.h linux-libre-3.11-rc7-gnu/drivers/dma/ioat/dma_v2.h
--- linux-libre-3.10-gnu/drivers/dma/ioat/dma_v2.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/ioat/dma_v2.h	2013-08-25 20:43:22.000000000 -0400
@@ -123,7 +123,6 @@ static inline u16 ioat2_xferlen_to_descs
 struct ioat_ring_ent {
 	union {
 		struct ioat_dma_descriptor *hw;
-		struct ioat_fill_descriptor *fill;
 		struct ioat_xor_descriptor *xor;
 		struct ioat_xor_ext_descriptor *xor_ex;
 		struct ioat_pq_descriptor *pq;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/ioat/dma_v3.c linux-libre-3.11-rc7-gnu/drivers/dma/ioat/dma_v3.c
--- linux-libre-3.10-gnu/drivers/dma/ioat/dma_v3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/ioat/dma_v3.c	2013-08-25 20:43:22.000000000 -0400
@@ -311,14 +311,6 @@ static void ioat3_dma_unmap(struct ioat2
 		if (!desc->hw->ctl_f.null) /* skip 'interrupt' ops */
 			ioat_dma_unmap(chan, flags, len, desc->hw);
 		break;
-	case IOAT_OP_FILL: {
-		struct ioat_fill_descriptor *hw = desc->fill;
-
-		if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP))
-			ioat_unmap(pdev, hw->dst_addr - offset, len,
-				   PCI_DMA_FROMDEVICE, flags, 1);
-		break;
-	}
 	case IOAT_OP_XOR_VAL:
 	case IOAT_OP_XOR: {
 		struct ioat_xor_descriptor *xor = desc->xor;
@@ -824,51 +816,6 @@ ioat3_tx_status(struct dma_chan *c, dma_
 }
 
 static struct dma_async_tx_descriptor *
-ioat3_prep_memset_lock(struct dma_chan *c, dma_addr_t dest, int value,
-		       size_t len, unsigned long flags)
-{
-	struct ioat2_dma_chan *ioat = to_ioat2_chan(c);
-	struct ioat_ring_ent *desc;
-	size_t total_len = len;
-	struct ioat_fill_descriptor *fill;
-	u64 src_data = (0x0101010101010101ULL) * (value & 0xff);
-	int num_descs, idx, i;
-
-	num_descs = ioat2_xferlen_to_descs(ioat, len);
-	if (likely(num_descs) && ioat2_check_space_lock(ioat, num_descs) == 0)
-		idx = ioat->head;
-	else
-		return NULL;
-	i = 0;
-	do {
-		size_t xfer_size = min_t(size_t, len, 1 << ioat->xfercap_log);
-
-		desc = ioat2_get_ring_ent(ioat, idx + i);
-		fill = desc->fill;
-
-		fill->size = xfer_size;
-		fill->src_data = src_data;
-		fill->dst_addr = dest;
-		fill->ctl = 0;
-		fill->ctl_f.op = IOAT_OP_FILL;
-
-		len -= xfer_size;
-		dest += xfer_size;
-		dump_desc_dbg(ioat, desc);
-	} while (++i < num_descs);
-
-	desc->txd.flags = flags;
-	desc->len = total_len;
-	fill->ctl_f.int_en = !!(flags & DMA_PREP_INTERRUPT);
-	fill->ctl_f.fence = !!(flags & DMA_PREP_FENCE);
-	fill->ctl_f.compl_write = 1;
-	dump_desc_dbg(ioat, desc);
-
-	/* we leave the channel locked to ensure in order submission */
-	return &desc->txd;
-}
-
-static struct dma_async_tx_descriptor *
 __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result,
 		      dma_addr_t dest, dma_addr_t *src, unsigned int src_cnt,
 		      size_t len, unsigned long flags)
@@ -1431,7 +1378,7 @@ static int ioat_xor_val_self_test(struct
 	struct page *xor_srcs[IOAT_NUM_SRC_TEST];
 	struct page *xor_val_srcs[IOAT_NUM_SRC_TEST + 1];
 	dma_addr_t dma_srcs[IOAT_NUM_SRC_TEST + 1];
-	dma_addr_t dma_addr, dest_dma;
+	dma_addr_t dest_dma;
 	struct dma_async_tx_descriptor *tx;
 	struct dma_chan *dma_chan;
 	dma_cookie_t cookie;
@@ -1598,56 +1545,6 @@ static int ioat_xor_val_self_test(struct
 		goto free_resources;
 	}
 
-	/* skip memset if the capability is not present */
-	if (!dma_has_cap(DMA_MEMSET, dma_chan->device->cap_mask))
-		goto free_resources;
-
-	/* test memset */
-	op = IOAT_OP_FILL;
-
-	dma_addr = dma_map_page(dev, dest, 0,
-			PAGE_SIZE, DMA_FROM_DEVICE);
-	tx = dma->device_prep_dma_memset(dma_chan, dma_addr, 0, PAGE_SIZE,
-					 DMA_PREP_INTERRUPT |
-					 DMA_COMPL_SKIP_SRC_UNMAP |
-					 DMA_COMPL_SKIP_DEST_UNMAP);
-	if (!tx) {
-		dev_err(dev, "Self-test memset prep failed\n");
-		err = -ENODEV;
-		goto dma_unmap;
-	}
-
-	async_tx_ack(tx);
-	init_completion(&cmp);
-	tx->callback = ioat3_dma_test_callback;
-	tx->callback_param = &cmp;
-	cookie = tx->tx_submit(tx);
-	if (cookie < 0) {
-		dev_err(dev, "Self-test memset setup failed\n");
-		err = -ENODEV;
-		goto dma_unmap;
-	}
-	dma->device_issue_pending(dma_chan);
-
-	tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));
-
-	if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) {
-		dev_err(dev, "Self-test memset timed out\n");
-		err = -ENODEV;
-		goto dma_unmap;
-	}
-
-	dma_unmap_page(dev, dma_addr, PAGE_SIZE, DMA_FROM_DEVICE);
-
-	for (i = 0; i < PAGE_SIZE/sizeof(u32); i++) {
-		u32 *ptr = page_address(dest);
-		if (ptr[i]) {
-			dev_err(dev, "Self-test memset failed compare\n");
-			err = -ENODEV;
-			goto free_resources;
-		}
-	}
-
 	/* test for non-zero parity sum */
 	op = IOAT_OP_XOR_VAL;
 
@@ -1706,8 +1603,7 @@ dma_unmap:
 		for (i = 0; i < IOAT_NUM_SRC_TEST + 1; i++)
 			dma_unmap_page(dev, dma_srcs[i], PAGE_SIZE,
 				       DMA_TO_DEVICE);
-	} else if (op == IOAT_OP_FILL)
-		dma_unmap_page(dev, dma_addr, PAGE_SIZE, DMA_FROM_DEVICE);
+	}
 free_resources:
 	dma->device_free_chan_resources(dma_chan);
 out:
@@ -1944,12 +1840,6 @@ int ioat3_dma_probe(struct ioatdma_devic
 		}
 	}
 
-	if (is_raid_device && (device->cap & IOAT_CAP_FILL_BLOCK)) {
-		dma_cap_set(DMA_MEMSET, dma->cap_mask);
-		dma->device_prep_dma_memset = ioat3_prep_memset_lock;
-	}
-
-
 	dma->device_tx_status = ioat3_tx_status;
 	device->cleanup_fn = ioat3_cleanup_event;
 	device->timer_fn = ioat3_timer_event;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/ioat/hw.h linux-libre-3.11-rc7-gnu/drivers/dma/ioat/hw.h
--- linux-libre-3.10-gnu/drivers/dma/ioat/hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/ioat/hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -100,33 +100,6 @@ struct ioat_dma_descriptor {
 	uint64_t	user2;
 };
 
-struct ioat_fill_descriptor {
-	uint32_t	size;
-	union {
-		uint32_t ctl;
-		struct {
-			unsigned int int_en:1;
-			unsigned int rsvd:1;
-			unsigned int dest_snoop_dis:1;
-			unsigned int compl_write:1;
-			unsigned int fence:1;
-			unsigned int rsvd2:2;
-			unsigned int dest_brk:1;
-			unsigned int bundle:1;
-			unsigned int rsvd4:15;
-			#define IOAT_OP_FILL 0x01
-			unsigned int op:8;
-		} ctl_f;
-	};
-	uint64_t	src_data;
-	uint64_t	dst_addr;
-	uint64_t	next;
-	uint64_t	rsv1;
-	uint64_t	next_dst_addr;
-	uint64_t	user1;
-	uint64_t	user2;
-};
-
 struct ioat_xor_descriptor {
 	uint32_t	size;
 	union {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/iop-adma.c linux-libre-3.11-rc7-gnu/drivers/dma/iop-adma.c
--- linux-libre-3.10-gnu/drivers/dma/iop-adma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/iop-adma.c	2013-08-25 20:43:22.000000000 -0400
@@ -633,39 +633,6 @@ iop_adma_prep_dma_memcpy(struct dma_chan
 }
 
 static struct dma_async_tx_descriptor *
-iop_adma_prep_dma_memset(struct dma_chan *chan, dma_addr_t dma_dest,
-			 int value, size_t len, unsigned long flags)
-{
-	struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan);
-	struct iop_adma_desc_slot *sw_desc, *grp_start;
-	int slot_cnt, slots_per_op;
-
-	if (unlikely(!len))
-		return NULL;
-	BUG_ON(len > IOP_ADMA_MAX_BYTE_COUNT);
-
-	dev_dbg(iop_chan->device->common.dev, "%s len: %u\n",
-		__func__, len);
-
-	spin_lock_bh(&iop_chan->lock);
-	slot_cnt = iop_chan_memset_slot_count(len, &slots_per_op);
-	sw_desc = iop_adma_alloc_slots(iop_chan, slot_cnt, slots_per_op);
-	if (sw_desc) {
-		grp_start = sw_desc->group_head;
-		iop_desc_init_memset(grp_start, flags);
-		iop_desc_set_byte_count(grp_start, iop_chan, len);
-		iop_desc_set_block_fill_val(grp_start, value);
-		iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest);
-		sw_desc->unmap_src_cnt = 1;
-		sw_desc->unmap_len = len;
-		sw_desc->async_tx.flags = flags;
-	}
-	spin_unlock_bh(&iop_chan->lock);
-
-	return sw_desc ? &sw_desc->async_tx : NULL;
-}
-
-static struct dma_async_tx_descriptor *
 iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest,
 		      dma_addr_t *dma_src, unsigned int src_cnt, size_t len,
 		      unsigned long flags)
@@ -1050,7 +1017,7 @@ iop_adma_xor_val_self_test(struct iop_ad
 	struct page *xor_srcs[IOP_ADMA_NUM_SRC_TEST];
 	struct page *zero_sum_srcs[IOP_ADMA_NUM_SRC_TEST + 1];
 	dma_addr_t dma_srcs[IOP_ADMA_NUM_SRC_TEST + 1];
-	dma_addr_t dma_addr, dest_dma;
+	dma_addr_t dest_dma;
 	struct dma_async_tx_descriptor *tx;
 	struct dma_chan *dma_chan;
 	dma_cookie_t cookie;
@@ -1176,33 +1143,6 @@ iop_adma_xor_val_self_test(struct iop_ad
 		goto free_resources;
 	}
 
-	/* test memset */
-	dma_addr = dma_map_page(dma_chan->device->dev, dest, 0,
-			PAGE_SIZE, DMA_FROM_DEVICE);
-	tx = iop_adma_prep_dma_memset(dma_chan, dma_addr, 0, PAGE_SIZE,
-				      DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-
-	cookie = iop_adma_tx_submit(tx);
-	iop_adma_issue_pending(dma_chan);
-	msleep(8);
-
-	if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) {
-		dev_err(dma_chan->device->dev,
-			"Self-test memset timed out, disabling\n");
-		err = -ENODEV;
-		goto free_resources;
-	}
-
-	for (i = 0; i < PAGE_SIZE/sizeof(u32); i++) {
-		u32 *ptr = page_address(dest);
-		if (ptr[i]) {
-			dev_err(dma_chan->device->dev,
-				"Self-test memset failed compare, disabling\n");
-			err = -ENODEV;
-			goto free_resources;
-		}
-	}
-
 	/* test for non-zero parity sum */
 	zero_sum_result = 0;
 	for (i = 0; i < IOP_ADMA_NUM_SRC_TEST + 1; i++)
@@ -1487,8 +1427,6 @@ static int iop_adma_probe(struct platfor
 	/* set prep routines based on capability */
 	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask))
 		dma_dev->device_prep_dma_memcpy = iop_adma_prep_dma_memcpy;
-	if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask))
-		dma_dev->device_prep_dma_memset = iop_adma_prep_dma_memset;
 	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
 		dma_dev->max_xor = iop_adma_get_max_xor();
 		dma_dev->device_prep_dma_xor = iop_adma_prep_dma_xor;
@@ -1556,8 +1494,7 @@ static int iop_adma_probe(struct platfor
 			goto err_free_iop_chan;
 	}
 
-	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask) ||
-	    dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)) {
+	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
 		ret = iop_adma_xor_val_self_test(adev);
 		dev_dbg(&pdev->dev, "xor self test returned %d\n", ret);
 		if (ret)
@@ -1579,12 +1516,11 @@ static int iop_adma_probe(struct platfor
 			goto err_free_iop_chan;
 	}
 
-	dev_info(&pdev->dev, "Intel(R) IOP: ( %s%s%s%s%s%s%s)\n",
+	dev_info(&pdev->dev, "Intel(R) IOP: ( %s%s%s%s%s%s)\n",
 		 dma_has_cap(DMA_PQ, dma_dev->cap_mask) ? "pq " : "",
 		 dma_has_cap(DMA_PQ_VAL, dma_dev->cap_mask) ? "pq_val " : "",
 		 dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "",
 		 dma_has_cap(DMA_XOR_VAL, dma_dev->cap_mask) ? "xor_val " : "",
-		 dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)  ? "fill " : "",
 		 dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "",
 		 dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/Kconfig linux-libre-3.11-rc7-gnu/drivers/dma/Kconfig
--- linux-libre-3.10-gnu/drivers/dma/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -79,25 +79,7 @@ config INTEL_IOP_ADMA
 	help
 	  Enable support for the Intel(R) IOP Series RAID engines.
 
-config DW_DMAC
-	tristate "Synopsys DesignWare AHB DMA support"
-	depends on GENERIC_HARDIRQS
-	select DMA_ENGINE
-	default y if CPU_AT32AP7000
-	help
-	  Support the Synopsys DesignWare AHB DMA controller.  This
-	  can be integrated in chips such as the Atmel AT32ap7000.
-
-config DW_DMAC_BIG_ENDIAN_IO
-	bool "Use big endian I/O register access"
-	default y if AVR32
-	depends on DW_DMAC
-	help
-	  Say yes here to use big endian I/O access when reading and writing
-	  to the DMA controller registers. This is needed on some platforms,
-	  like the Atmel AVR32 architecture.
-
-	  If unsure, use the default setting.
+source "drivers/dma/dw/Kconfig"
 
 config AT_HDMAC
 	tristate "Atmel AHB DMA support"
@@ -213,7 +195,7 @@ config SIRF_DMA
 
 config TI_EDMA
 	tristate "TI EDMA support"
-	depends on ARCH_DAVINCI
+	depends on ARCH_DAVINCI || ARCH_OMAP
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
 	default n
@@ -312,6 +294,12 @@ config MMP_PDMA
 	help
 	  Support the MMP PDMA engine for PXA and MMP platfrom.
 
+config DMA_JZ4740
+	tristate "JZ4740 DMA support"
+	depends on MACH_JZ4740
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+
 config DMA_ENGINE
 	bool
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/Makefile linux-libre-3.11-rc7-gnu/drivers/dma/Makefile
--- linux-libre-3.10-gnu/drivers/dma/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,7 @@ obj-$(CONFIG_FSL_DMA) += fsldma.o
 obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o
 obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
 obj-$(CONFIG_MV_XOR) += mv_xor.o
-obj-$(CONFIG_DW_DMAC) += dw_dmac.o
+obj-$(CONFIG_DW_DMAC_CORE) += dw/
 obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
 obj-$(CONFIG_MX3_IPU) += ipu/
 obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
@@ -38,3 +38,4 @@ obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
+obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/mmp_tdma.c linux-libre-3.11-rc7-gnu/drivers/dma/mmp_tdma.c
--- linux-libre-3.10-gnu/drivers/dma/mmp_tdma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/mmp_tdma.c	2013-08-25 20:43:22.000000000 -0400
@@ -154,6 +154,10 @@ static void mmp_tdma_disable_chan(struct
 {
 	writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN,
 					tdmac->reg_base + TDCR);
+
+	/* disable irq */
+	writel(0, tdmac->reg_base + TDIMR);
+
 	tdmac->status = DMA_SUCCESS;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/mv_xor.c linux-libre-3.11-rc7-gnu/drivers/dma/mv_xor.c
--- linux-libre-3.10-gnu/drivers/dma/mv_xor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/mv_xor.c	2013-08-25 20:43:22.000000000 -0400
@@ -89,11 +89,6 @@ static void mv_desc_clear_next_desc(stru
 	hw_desc->phy_next_desc = 0;
 }
 
-static void mv_desc_set_block_fill_val(struct mv_xor_desc_slot *desc, u32 val)
-{
-	desc->value = val;
-}
-
 static void mv_desc_set_dest_addr(struct mv_xor_desc_slot *desc,
 				  dma_addr_t addr)
 {
@@ -128,22 +123,6 @@ static void mv_chan_set_next_descriptor(
 	__raw_writel(next_desc_addr, XOR_NEXT_DESC(chan));
 }
 
-static void mv_chan_set_dest_pointer(struct mv_xor_chan *chan, u32 desc_addr)
-{
-	__raw_writel(desc_addr, XOR_DEST_POINTER(chan));
-}
-
-static void mv_chan_set_block_size(struct mv_xor_chan *chan, u32 block_size)
-{
-	__raw_writel(block_size, XOR_BLOCK_SIZE(chan));
-}
-
-static void mv_chan_set_value(struct mv_xor_chan *chan, u32 value)
-{
-	__raw_writel(value, XOR_INIT_VALUE_LOW(chan));
-	__raw_writel(value, XOR_INIT_VALUE_HIGH(chan));
-}
-
 static void mv_chan_unmask_interrupts(struct mv_xor_chan *chan)
 {
 	u32 val = __raw_readl(XOR_INTR_MASK(chan));
@@ -186,8 +165,6 @@ static int mv_can_chain(struct mv_xor_de
 
 	if (chain_old_tail->type != desc->type)
 		return 0;
-	if (desc->type == DMA_MEMSET)
-		return 0;
 
 	return 1;
 }
@@ -205,9 +182,6 @@ static void mv_set_mode(struct mv_xor_ch
 	case DMA_MEMCPY:
 		op_mode = XOR_OPERATION_MODE_MEMCPY;
 		break;
-	case DMA_MEMSET:
-		op_mode = XOR_OPERATION_MODE_MEMSET;
-		break;
 	default:
 		dev_err(mv_chan_to_devp(chan),
 			"error: unsupported operation %d\n",
@@ -274,18 +248,9 @@ static void mv_xor_start_new_chain(struc
 	if (sw_desc->type != mv_chan->current_type)
 		mv_set_mode(mv_chan, sw_desc->type);
 
-	if (sw_desc->type == DMA_MEMSET) {
-		/* for memset requests we need to program the engine, no
-		 * descriptors used.
-		 */
-		struct mv_xor_desc *hw_desc = sw_desc->hw_desc;
-		mv_chan_set_dest_pointer(mv_chan, hw_desc->phy_dest_addr);
-		mv_chan_set_block_size(mv_chan, sw_desc->unmap_len);
-		mv_chan_set_value(mv_chan, sw_desc->value);
-	} else {
-		/* set the hardware chain */
-		mv_chan_set_next_descriptor(mv_chan, sw_desc->async_tx.phys);
-	}
+	/* set the hardware chain */
+	mv_chan_set_next_descriptor(mv_chan, sw_desc->async_tx.phys);
+
 	mv_chan->pending += sw_desc->slot_cnt;
 	mv_xor_issue_pending(&mv_chan->dmachan);
 }
@@ -688,43 +653,6 @@ mv_xor_prep_dma_memcpy(struct dma_chan *
 }
 
 static struct dma_async_tx_descriptor *
-mv_xor_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value,
-		       size_t len, unsigned long flags)
-{
-	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
-	struct mv_xor_desc_slot *sw_desc, *grp_start;
-	int slot_cnt;
-
-	dev_dbg(mv_chan_to_devp(mv_chan),
-		"%s dest: %x len: %u flags: %ld\n",
-		__func__, dest, len, flags);
-	if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
-		return NULL;
-
-	BUG_ON(len > MV_XOR_MAX_BYTE_COUNT);
-
-	spin_lock_bh(&mv_chan->lock);
-	slot_cnt = mv_chan_memset_slot_count(len);
-	sw_desc = mv_xor_alloc_slots(mv_chan, slot_cnt, 1);
-	if (sw_desc) {
-		sw_desc->type = DMA_MEMSET;
-		sw_desc->async_tx.flags = flags;
-		grp_start = sw_desc->group_head;
-		mv_desc_init(grp_start, flags);
-		mv_desc_set_byte_count(grp_start, len);
-		mv_desc_set_dest_addr(sw_desc->group_head, dest);
-		mv_desc_set_block_fill_val(grp_start, value);
-		sw_desc->unmap_src_cnt = 1;
-		sw_desc->unmap_len = len;
-	}
-	spin_unlock_bh(&mv_chan->lock);
-	dev_dbg(mv_chan_to_devp(mv_chan),
-		"%s sw_desc %p async_tx %p \n",
-		__func__, sw_desc, &sw_desc->async_tx);
-	return sw_desc ? &sw_desc->async_tx : NULL;
-}
-
-static struct dma_async_tx_descriptor *
 mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
 		    unsigned int src_cnt, size_t len, unsigned long flags)
 {
@@ -1137,8 +1065,6 @@ mv_xor_channel_add(struct mv_xor_device
 	/* set prep routines based on capability */
 	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask))
 		dma_dev->device_prep_dma_memcpy = mv_xor_prep_dma_memcpy;
-	if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask))
-		dma_dev->device_prep_dma_memset = mv_xor_prep_dma_memset;
 	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
 		dma_dev->max_xor = 8;
 		dma_dev->device_prep_dma_xor = mv_xor_prep_dma_xor;
@@ -1187,9 +1113,8 @@ mv_xor_channel_add(struct mv_xor_device
 			goto err_free_irq;
 	}
 
-	dev_info(&pdev->dev, "Marvell XOR: ( %s%s%s%s)\n",
+	dev_info(&pdev->dev, "Marvell XOR: ( %s%s%s)\n",
 		 dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "",
-		 dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)  ? "fill " : "",
 		 dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "",
 		 dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
 
@@ -1298,8 +1223,6 @@ static int mv_xor_probe(struct platform_
 				dma_cap_set(DMA_MEMCPY, cap_mask);
 			if (of_property_read_bool(np, "dmacap,xor"))
 				dma_cap_set(DMA_XOR, cap_mask);
-			if (of_property_read_bool(np, "dmacap,memset"))
-				dma_cap_set(DMA_MEMSET, cap_mask);
 			if (of_property_read_bool(np, "dmacap,interrupt"))
 				dma_cap_set(DMA_INTERRUPT, cap_mask);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/mv_xor.h linux-libre-3.11-rc7-gnu/drivers/dma/mv_xor.h
--- linux-libre-3.10-gnu/drivers/dma/mv_xor.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/mv_xor.h	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,6 @@
 
 #define XOR_OPERATION_MODE_XOR		0
 #define XOR_OPERATION_MODE_MEMCPY	2
-#define XOR_OPERATION_MODE_MEMSET	4
 
 #define XOR_CURR_DESC(chan)	(chan->mmr_base + 0x210 + (chan->idx * 4))
 #define XOR_NEXT_DESC(chan)	(chan->mmr_base + 0x200 + (chan->idx * 4))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/mxs-dma.c linux-libre-3.11-rc7-gnu/drivers/dma/mxs-dma.c
--- linux-libre-3.10-gnu/drivers/dma/mxs-dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/mxs-dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -693,7 +693,7 @@ static bool mxs_dma_filter_fn(struct dma
 	return true;
 }
 
-struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec,
+static struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec,
 			       struct of_dma *ofdma)
 {
 	struct mxs_dma_engine *mxs_dma = ofdma->of_dma_data;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/of-dma.c linux-libre-3.11-rc7-gnu/drivers/dma/of-dma.c
--- linux-libre-3.10-gnu/drivers/dma/of-dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/of-dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,8 +35,7 @@ static struct of_dma *of_dma_find_contro
 	struct of_dma *ofdma;
 
 	list_for_each_entry(ofdma, &of_dma_list, of_dma_controllers)
-		if ((ofdma->of_node == dma_spec->np) &&
-		    (ofdma->of_dma_nbcells == dma_spec->args_count))
+		if (ofdma->of_node == dma_spec->np)
 			return ofdma;
 
 	pr_debug("%s: can't find DMA controller %s\n", __func__,
@@ -64,8 +63,6 @@ int of_dma_controller_register(struct de
 				void *data)
 {
 	struct of_dma	*ofdma;
-	int		nbcells;
-	const __be32	*prop;
 
 	if (!np || !of_dma_xlate) {
 		pr_err("%s: not enough information provided\n", __func__);
@@ -76,19 +73,7 @@ int of_dma_controller_register(struct de
 	if (!ofdma)
 		return -ENOMEM;
 
-	prop = of_get_property(np, "#dma-cells", NULL);
-	if (prop)
-		nbcells = be32_to_cpup(prop);
-
-	if (!prop || !nbcells) {
-		pr_err("%s: #dma-cells property is missing or invalid\n",
-		       __func__);
-		kfree(ofdma);
-		return -EINVAL;
-	}
-
 	ofdma->of_node = np;
-	ofdma->of_dma_nbcells = nbcells;
 	ofdma->of_dma_xlate = of_dma_xlate;
 	ofdma->of_dma_data = data;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/pch_dma.c linux-libre-3.11-rc7-gnu/drivers/dma/pch_dma.c
--- linux-libre-3.10-gnu/drivers/dma/pch_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/pch_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -867,6 +867,7 @@ static int pch_dma_probe(struct pci_dev
 
 	if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
 		dev_err(&pdev->dev, "Cannot find proper base address\n");
+		err = -ENODEV;
 		goto err_disable_pdev;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/pl330.c linux-libre-3.11-rc7-gnu/drivers/dma/pl330.c
--- linux-libre-3.10-gnu/drivers/dma/pl330.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/pl330.c	2013-08-25 20:43:22.000000000 -0400
@@ -157,7 +157,6 @@ enum pl330_reqtype {
 #define PERIPH_REV_R0P0		0
 #define PERIPH_REV_R1P0		1
 #define PERIPH_REV_R1P1		2
-#define PCELL_ID		0xff0
 
 #define CR0_PERIPH_REQ_SET	(1 << 0)
 #define CR0_BOOT_EN_SET		(1 << 1)
@@ -193,8 +192,6 @@ enum pl330_reqtype {
 #define INTEG_CFG		0x0
 #define PERIPH_ID_VAL		((PART << 0) | (DESIGNER << 12))
 
-#define PCELL_ID_VAL		0xb105f00d
-
 #define PL330_STATE_STOPPED		(1 << 0)
 #define PL330_STATE_EXECUTING		(1 << 1)
 #define PL330_STATE_WFE			(1 << 2)
@@ -292,7 +289,6 @@ static unsigned cmd_line;
 /* Populated by the PL330 core driver for DMA API driver's info */
 struct pl330_config {
 	u32	periph_id;
-	u32	pcell_id;
 #define DMAC_MODE_NS	(1 << 0)
 	unsigned int	mode;
 	unsigned int	data_bus_width:10; /* In number of bits */
@@ -505,7 +501,7 @@ struct pl330_dmac {
 	/* Maximum possible events/irqs */
 	int			events[32];
 	/* BUS address of MicroCode buffer */
-	u32			mcode_bus;
+	dma_addr_t		mcode_bus;
 	/* CPU address of MicroCode buffer */
 	void			*mcode_cpu;
 	/* List of all Channel threads */
@@ -650,19 +646,6 @@ static inline bool _manager_ns(struct pl
 	return (pl330->pinfo->pcfg.mode & DMAC_MODE_NS) ? true : false;
 }
 
-static inline u32 get_id(struct pl330_info *pi, u32 off)
-{
-	void __iomem *regs = pi->base;
-	u32 id = 0;
-
-	id |= (readb(regs + off + 0x0) << 0);
-	id |= (readb(regs + off + 0x4) << 8);
-	id |= (readb(regs + off + 0x8) << 16);
-	id |= (readb(regs + off + 0xc) << 24);
-
-	return id;
-}
-
 static inline u32 get_revision(u32 periph_id)
 {
 	return (periph_id >> PERIPH_REV_SHIFT) & PERIPH_REV_MASK;
@@ -1986,9 +1969,6 @@ static void read_dmac_config(struct pl33
 	pi->pcfg.num_events = val;
 
 	pi->pcfg.irq_ns = readl(regs + CR3);
-
-	pi->pcfg.periph_id = get_id(pi, PERIPH_ID);
-	pi->pcfg.pcell_id = get_id(pi, PCELL_ID);
 }
 
 static inline void _reset_thread(struct pl330_thread *thrd)
@@ -2098,10 +2078,8 @@ static int pl330_add(struct pl330_info *
 	regs = pi->base;
 
 	/* Check if we can handle this DMAC */
-	if ((get_id(pi, PERIPH_ID) & 0xfffff) != PERIPH_ID_VAL
-	   || get_id(pi, PCELL_ID) != PCELL_ID_VAL) {
-		dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n",
-			get_id(pi, PERIPH_ID), get_id(pi, PCELL_ID));
+	if ((pi->pcfg.periph_id & 0xfffff) != PERIPH_ID_VAL) {
+		dev_err(pi->dev, "PERIPH_ID 0x%x !\n", pi->pcfg.periph_id);
 		return -EINVAL;
 	}
 
@@ -2485,10 +2463,10 @@ static void pl330_free_chan_resources(st
 	struct dma_pl330_chan *pch = to_pchan(chan);
 	unsigned long flags;
 
-	spin_lock_irqsave(&pch->lock, flags);
-
 	tasklet_kill(&pch->task);
 
+	spin_lock_irqsave(&pch->lock, flags);
+
 	pl330_release_channel(pch->pl330_chid);
 	pch->pl330_chid = NULL;
 
@@ -2527,6 +2505,10 @@ static dma_cookie_t pl330_tx_submit(stru
 	/* Assign cookies to all nodes */
 	while (!list_empty(&last->node)) {
 		desc = list_entry(last->node.next, struct dma_pl330_desc, node);
+		if (pch->cyclic) {
+			desc->txd.callback = last->txd.callback;
+			desc->txd.callback_param = last->txd.callback_param;
+		}
 
 		dma_cookie_assign(&desc->txd);
 
@@ -2710,45 +2692,82 @@ static struct dma_async_tx_descriptor *p
 		size_t period_len, enum dma_transfer_direction direction,
 		unsigned long flags, void *context)
 {
-	struct dma_pl330_desc *desc;
+	struct dma_pl330_desc *desc = NULL, *first = NULL;
 	struct dma_pl330_chan *pch = to_pchan(chan);
+	struct dma_pl330_dmac *pdmac = pch->dmac;
+	unsigned int i;
 	dma_addr_t dst;
 	dma_addr_t src;
 
-	desc = pl330_get_desc(pch);
-	if (!desc) {
-		dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
-			__func__, __LINE__);
+	if (len % period_len != 0)
 		return NULL;
-	}
 
-	switch (direction) {
-	case DMA_MEM_TO_DEV:
-		desc->rqcfg.src_inc = 1;
-		desc->rqcfg.dst_inc = 0;
-		desc->req.rqtype = MEMTODEV;
-		src = dma_addr;
-		dst = pch->fifo_addr;
-		break;
-	case DMA_DEV_TO_MEM:
-		desc->rqcfg.src_inc = 0;
-		desc->rqcfg.dst_inc = 1;
-		desc->req.rqtype = DEVTOMEM;
-		src = pch->fifo_addr;
-		dst = dma_addr;
-		break;
-	default:
+	if (!is_slave_direction(direction)) {
 		dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n",
 		__func__, __LINE__);
 		return NULL;
 	}
 
-	desc->rqcfg.brst_size = pch->burst_sz;
-	desc->rqcfg.brst_len = 1;
+	for (i = 0; i < len / period_len; i++) {
+		desc = pl330_get_desc(pch);
+		if (!desc) {
+			dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
+				__func__, __LINE__);
 
-	pch->cyclic = true;
+			if (!first)
+				return NULL;
 
-	fill_px(&desc->px, dst, src, period_len);
+			spin_lock_irqsave(&pdmac->pool_lock, flags);
+
+			while (!list_empty(&first->node)) {
+				desc = list_entry(first->node.next,
+						struct dma_pl330_desc, node);
+				list_move_tail(&desc->node, &pdmac->desc_pool);
+			}
+
+			list_move_tail(&first->node, &pdmac->desc_pool);
+
+			spin_unlock_irqrestore(&pdmac->pool_lock, flags);
+
+			return NULL;
+		}
+
+		switch (direction) {
+		case DMA_MEM_TO_DEV:
+			desc->rqcfg.src_inc = 1;
+			desc->rqcfg.dst_inc = 0;
+			desc->req.rqtype = MEMTODEV;
+			src = dma_addr;
+			dst = pch->fifo_addr;
+			break;
+		case DMA_DEV_TO_MEM:
+			desc->rqcfg.src_inc = 0;
+			desc->rqcfg.dst_inc = 1;
+			desc->req.rqtype = DEVTOMEM;
+			src = pch->fifo_addr;
+			dst = dma_addr;
+			break;
+		default:
+			break;
+		}
+
+		desc->rqcfg.brst_size = pch->burst_sz;
+		desc->rqcfg.brst_len = 1;
+		fill_px(&desc->px, dst, src, period_len);
+
+		if (!first)
+			first = desc;
+		else
+			list_add_tail(&desc->node, &first->node);
+
+		dma_addr += period_len;
+	}
+
+	if (!desc)
+		return NULL;
+
+	pch->cyclic = true;
+	desc->txd.flags = flags;
 
 	return &desc->txd;
 }
@@ -2916,6 +2935,7 @@ pl330_probe(struct amba_device *adev, co
 	if (ret)
 		return ret;
 
+	pi->pcfg.periph_id = adev->periphid;
 	ret = pl330_add(pi);
 	if (ret)
 		goto probe_err1;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/ppc4xx/adma.c linux-libre-3.11-rc7-gnu/drivers/dma/ppc4xx/adma.c
--- linux-libre-3.10-gnu/drivers/dma/ppc4xx/adma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/ppc4xx/adma.c	2013-08-25 20:43:22.000000000 -0400
@@ -2323,47 +2323,6 @@ static struct dma_async_tx_descriptor *p
 }
 
 /**
- * ppc440spe_adma_prep_dma_memset - prepare CDB for a MEMSET operation
- */
-static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_memset(
-		struct dma_chan *chan, dma_addr_t dma_dest, int value,
-		size_t len, unsigned long flags)
-{
-	struct ppc440spe_adma_chan *ppc440spe_chan;
-	struct ppc440spe_adma_desc_slot *sw_desc, *group_start;
-	int slot_cnt, slots_per_op;
-
-	ppc440spe_chan = to_ppc440spe_adma_chan(chan);
-
-	if (unlikely(!len))
-		return NULL;
-
-	BUG_ON(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT);
-
-	spin_lock_bh(&ppc440spe_chan->lock);
-
-	dev_dbg(ppc440spe_chan->device->common.dev,
-		"ppc440spe adma%d: %s cal: %u len: %u int_en %d\n",
-		ppc440spe_chan->device->id, __func__, value, len,
-		flags & DMA_PREP_INTERRUPT ? 1 : 0);
-
-	slot_cnt = slots_per_op = 1;
-	sw_desc = ppc440spe_adma_alloc_slots(ppc440spe_chan, slot_cnt,
-		slots_per_op);
-	if (sw_desc) {
-		group_start = sw_desc->group_head;
-		ppc440spe_desc_init_memset(group_start, value, flags);
-		ppc440spe_adma_set_dest(group_start, dma_dest, 0);
-		ppc440spe_desc_set_byte_count(group_start, ppc440spe_chan, len);
-		sw_desc->unmap_len = len;
-		sw_desc->async_tx.flags = flags;
-	}
-	spin_unlock_bh(&ppc440spe_chan->lock);
-
-	return sw_desc ? &sw_desc->async_tx : NULL;
-}
-
-/**
  * ppc440spe_adma_prep_dma_xor - prepare CDB for a XOR operation
  */
 static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_xor(
@@ -4125,7 +4084,6 @@ static void ppc440spe_adma_init_capabili
 	case PPC440SPE_DMA1_ID:
 		dma_cap_set(DMA_MEMCPY, adev->common.cap_mask);
 		dma_cap_set(DMA_INTERRUPT, adev->common.cap_mask);
-		dma_cap_set(DMA_MEMSET, adev->common.cap_mask);
 		dma_cap_set(DMA_PQ, adev->common.cap_mask);
 		dma_cap_set(DMA_PQ_VAL, adev->common.cap_mask);
 		dma_cap_set(DMA_XOR_VAL, adev->common.cap_mask);
@@ -4151,10 +4109,6 @@ static void ppc440spe_adma_init_capabili
 		adev->common.device_prep_dma_memcpy =
 			ppc440spe_adma_prep_dma_memcpy;
 	}
-	if (dma_has_cap(DMA_MEMSET, adev->common.cap_mask)) {
-		adev->common.device_prep_dma_memset =
-			ppc440spe_adma_prep_dma_memset;
-	}
 	if (dma_has_cap(DMA_XOR, adev->common.cap_mask)) {
 		adev->common.max_xor = XOR_MAX_OPS;
 		adev->common.device_prep_dma_xor =
@@ -4217,7 +4171,6 @@ static void ppc440spe_adma_init_capabili
 	  dma_has_cap(DMA_XOR, adev->common.cap_mask) ? "xor " : "",
 	  dma_has_cap(DMA_XOR_VAL, adev->common.cap_mask) ? "xor_val " : "",
 	  dma_has_cap(DMA_MEMCPY, adev->common.cap_mask) ? "memcpy " : "",
-	  dma_has_cap(DMA_MEMSET, adev->common.cap_mask)  ? "memset " : "",
 	  dma_has_cap(DMA_INTERRUPT, adev->common.cap_mask) ? "intr " : "");
 }
 
@@ -4481,7 +4434,7 @@ static int ppc440spe_adma_probe(struct p
 	adev->dev = &ofdev->dev;
 	adev->common.dev = &ofdev->dev;
 	INIT_LIST_HEAD(&adev->common.channels);
-	dev_set_drvdata(&ofdev->dev, adev);
+	platform_set_drvdata(ofdev, adev);
 
 	/* create a channel */
 	chan = kzalloc(sizeof(*chan), GFP_KERNEL);
@@ -4594,14 +4547,13 @@ out:
  */
 static int ppc440spe_adma_remove(struct platform_device *ofdev)
 {
-	struct ppc440spe_adma_device *adev = dev_get_drvdata(&ofdev->dev);
+	struct ppc440spe_adma_device *adev = platform_get_drvdata(ofdev);
 	struct device_node *np = ofdev->dev.of_node;
 	struct resource res;
 	struct dma_chan *chan, *_chan;
 	struct ppc_dma_chan_ref *ref, *_ref;
 	struct ppc440spe_adma_chan *ppc440spe_chan;
 
-	dev_set_drvdata(&ofdev->dev, NULL);
 	if (adev->id < PPC440SPE_ADMA_ENGINES_NUM)
 		ppc440spe_adma_devices[adev->id] = -1;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/sh/Makefile linux-libre-3.11-rc7-gnu/drivers/dma/sh/Makefile
--- linux-libre-3.10-gnu/drivers/dma/sh/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/sh/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,3 +1,3 @@
-obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o
+obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o
 obj-$(CONFIG_SH_DMAE) += shdma.o
 obj-$(CONFIG_SUDMAC) += sudmac.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/sh/shdma-base.c linux-libre-3.11-rc7-gnu/drivers/dma/sh/shdma-base.c
--- linux-libre-3.10-gnu/drivers/dma/sh/shdma-base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/sh/shdma-base.c	2013-08-25 20:43:22.000000000 -0400
@@ -175,7 +175,18 @@ static int shdma_setup_slave(struct shdm
 {
 	struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
 	const struct shdma_ops *ops = sdev->ops;
-	int ret;
+	int ret, match;
+
+	if (schan->dev->of_node) {
+		match = schan->hw_req;
+		ret = ops->set_slave(schan, match, true);
+		if (ret < 0)
+			return ret;
+
+		slave_id = schan->slave_id;
+	} else {
+		match = slave_id;
+	}
 
 	if (slave_id < 0 || slave_id >= slave_num)
 		return -EINVAL;
@@ -183,7 +194,7 @@ static int shdma_setup_slave(struct shdm
 	if (test_and_set_bit(slave_id, shdma_slave_used))
 		return -EBUSY;
 
-	ret = ops->set_slave(schan, slave_id, false);
+	ret = ops->set_slave(schan, match, false);
 	if (ret < 0) {
 		clear_bit(slave_id, shdma_slave_used);
 		return ret;
@@ -206,23 +217,26 @@ static int shdma_setup_slave(struct shdm
  * services would have to provide their own filters, which first would check
  * the device driver, similar to how other DMAC drivers, e.g., sa11x0-dma.c, do
  * this, and only then, in case of a match, call this common filter.
+ * NOTE 2: This filter function is also used in the DT case by shdma_of_xlate().
+ * In that case the MID-RID value is used for slave channel filtering and is
+ * passed to this function in the "arg" parameter.
  */
 bool shdma_chan_filter(struct dma_chan *chan, void *arg)
 {
 	struct shdma_chan *schan = to_shdma_chan(chan);
 	struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
 	const struct shdma_ops *ops = sdev->ops;
-	int slave_id = (int)arg;
+	int match = (int)arg;
 	int ret;
 
-	if (slave_id < 0)
+	if (match < 0)
 		/* No slave requested - arbitrary channel */
 		return true;
 
-	if (slave_id >= slave_num)
+	if (!schan->dev->of_node && match >= slave_num)
 		return false;
 
-	ret = ops->set_slave(schan, slave_id, true);
+	ret = ops->set_slave(schan, match, true);
 	if (ret < 0)
 		return false;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/sh/shdma.c linux-libre-3.11-rc7-gnu/drivers/dma/sh/shdma.c
--- linux-libre-3.10-gnu/drivers/dma/sh/shdma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/sh/shdma.c	2013-08-25 20:43:22.000000000 -0400
@@ -301,20 +301,32 @@ static void sh_dmae_setup_xfer(struct sh
 	}
 }
 
+/*
+ * Find a slave channel configuration from the contoller list by either a slave
+ * ID in the non-DT case, or by a MID/RID value in the DT case
+ */
 static const struct sh_dmae_slave_config *dmae_find_slave(
-	struct sh_dmae_chan *sh_chan, int slave_id)
+	struct sh_dmae_chan *sh_chan, int match)
 {
 	struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
 	struct sh_dmae_pdata *pdata = shdev->pdata;
 	const struct sh_dmae_slave_config *cfg;
 	int i;
 
-	if (slave_id >= SH_DMA_SLAVE_NUMBER)
-		return NULL;
+	if (!sh_chan->shdma_chan.dev->of_node) {
+		if (match >= SH_DMA_SLAVE_NUMBER)
+			return NULL;
 
-	for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++)
-		if (cfg->slave_id == slave_id)
-			return cfg;
+		for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++)
+			if (cfg->slave_id == match)
+				return cfg;
+	} else {
+		for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++)
+			if (cfg->mid_rid == match) {
+				sh_chan->shdma_chan.slave_id = cfg->slave_id;
+				return cfg;
+			}
+	}
 
 	return NULL;
 }
@@ -388,8 +400,8 @@ static size_t sh_dmae_get_partial(struct
 						    shdma_chan);
 	struct sh_dmae_desc *sh_desc = container_of(sdesc,
 					struct sh_dmae_desc, shdma_desc);
-	return (sh_desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
-		sh_chan->xmit_shift;
+	return sh_desc->hw.tcr -
+		(sh_dmae_readl(sh_chan, TCR) << sh_chan->xmit_shift);
 }
 
 /* Called from error IRQ or NMI */
@@ -729,7 +741,7 @@ static int sh_dmae_probe(struct platform
 		goto eshdma;
 
 	/* platform data */
-	shdev->pdata = pdev->dev.platform_data;
+	shdev->pdata = pdata;
 
 	if (pdata->chcr_offset)
 		shdev->chcr_offset = pdata->chcr_offset;
@@ -920,11 +932,18 @@ static int sh_dmae_remove(struct platfor
 	return 0;
 }
 
+static const struct of_device_id sh_dmae_of_match[] = {
+	{ .compatible = "renesas,shdma", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sh_dmae_of_match);
+
 static struct platform_driver sh_dmae_driver = {
 	.driver 	= {
 		.owner	= THIS_MODULE,
 		.pm	= &sh_dmae_pm,
 		.name	= SH_DMAE_DRV_NAME,
+		.of_match_table = sh_dmae_of_match,
 	},
 	.remove		= sh_dmae_remove,
 	.shutdown	= sh_dmae_shutdown,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/sh/shdma-of.c linux-libre-3.11-rc7-gnu/drivers/dma/sh/shdma-of.c
--- linux-libre-3.10-gnu/drivers/dma/sh/shdma-of.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/dma/sh/shdma-of.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,82 @@
+/*
+ * SHDMA Device Tree glue
+ *
+ * Copyright (C) 2013 Renesas Electronics Inc.
+ * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/dmaengine.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/shdma-base.h>
+
+#define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan)
+
+static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec,
+				       struct of_dma *ofdma)
+{
+	u32 id = dma_spec->args[0];
+	dma_cap_mask_t mask;
+	struct dma_chan *chan;
+
+	if (dma_spec->args_count != 1)
+		return NULL;
+
+	dma_cap_zero(mask);
+	/* Only slave DMA channels can be allocated via DT */
+	dma_cap_set(DMA_SLAVE, mask);
+
+	chan = dma_request_channel(mask, shdma_chan_filter, (void *)id);
+	if (chan)
+		to_shdma_chan(chan)->hw_req = id;
+
+	return chan;
+}
+
+static int shdma_of_probe(struct platform_device *pdev)
+{
+	const struct of_dev_auxdata *lookup = pdev->dev.platform_data;
+	int ret;
+
+	if (!lookup)
+		return -EINVAL;
+
+	ret = of_dma_controller_register(pdev->dev.of_node,
+					 shdma_of_xlate, pdev);
+	if (ret < 0)
+		return ret;
+
+	ret = of_platform_populate(pdev->dev.of_node, NULL, lookup, &pdev->dev);
+	if (ret < 0)
+		of_dma_controller_free(pdev->dev.of_node);
+
+	return ret;
+}
+
+static const struct of_device_id shdma_of_match[] = {
+	{ .compatible = "renesas,shdma-mux", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sh_dmae_of_match);
+
+static struct platform_driver shdma_of = {
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "shdma-of",
+		.of_match_table = shdma_of_match,
+	},
+	.probe		= shdma_of_probe,
+};
+
+module_platform_driver(shdma_of);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("SH-DMA driver DT glue");
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/sirf-dma.c linux-libre-3.11-rc7-gnu/drivers/dma/sirf-dma.c
--- linux-libre-3.10-gnu/drivers/dma/sirf-dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/sirf-dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -466,12 +466,29 @@ static enum dma_status
 sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
 	struct dma_tx_state *txstate)
 {
+	struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan);
 	struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
 	unsigned long flags;
 	enum dma_status ret;
+	struct sirfsoc_dma_desc *sdesc;
+	int cid = schan->chan.chan_id;
+	unsigned long dma_pos;
+	unsigned long dma_request_bytes;
+	unsigned long residue;
 
 	spin_lock_irqsave(&schan->lock, flags);
+
+	sdesc = list_first_entry(&schan->active, struct sirfsoc_dma_desc,
+			node);
+	dma_request_bytes = (sdesc->xlen + 1) * (sdesc->ylen + 1) *
+		(sdesc->width * SIRFSOC_DMA_WORD_LEN);
+
 	ret = dma_cookie_status(chan, cookie, txstate);
+	dma_pos = readl_relaxed(sdma->base + cid * 0x10 + SIRFSOC_DMA_CH_ADDR)
+		<< 2;
+	residue = dma_request_bytes - (dma_pos - sdesc->addr);
+	dma_set_residue(txstate, residue);
+
 	spin_unlock_irqrestore(&schan->lock, flags);
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/ste_dma40.c linux-libre-3.11-rc7-gnu/drivers/dma/ste_dma40.c
--- linux-libre-3.10-gnu/drivers/dma/ste_dma40.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/ste_dma40.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,8 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
 #include <linux/amba/bus.h>
 #include <linux/regulator/consumer.h>
 #include <linux/platform_data/dma-ste-dma40.h>
@@ -45,15 +47,63 @@
 #define D40_LCLA_LINK_PER_EVENT_GRP 128
 #define D40_LCLA_END D40_LCLA_LINK_PER_EVENT_GRP
 
+/* Max number of logical channels per physical channel */
+#define D40_MAX_LOG_CHAN_PER_PHY 32
+
 /* Attempts before giving up to trying to get pages that are aligned */
 #define MAX_LCLA_ALLOC_ATTEMPTS 256
 
 /* Bit markings for allocation map */
-#define D40_ALLOC_FREE		(1 << 31)
-#define D40_ALLOC_PHY		(1 << 30)
+#define D40_ALLOC_FREE		BIT(31)
+#define D40_ALLOC_PHY		BIT(30)
 #define D40_ALLOC_LOG_FREE	0
 
-#define MAX(a, b) (((a) < (b)) ? (b) : (a))
+#define D40_MEMCPY_MAX_CHANS	8
+
+/* Reserved event lines for memcpy only. */
+#define DB8500_DMA_MEMCPY_EV_0	51
+#define DB8500_DMA_MEMCPY_EV_1	56
+#define DB8500_DMA_MEMCPY_EV_2	57
+#define DB8500_DMA_MEMCPY_EV_3	58
+#define DB8500_DMA_MEMCPY_EV_4	59
+#define DB8500_DMA_MEMCPY_EV_5	60
+
+static int dma40_memcpy_channels[] = {
+	DB8500_DMA_MEMCPY_EV_0,
+	DB8500_DMA_MEMCPY_EV_1,
+	DB8500_DMA_MEMCPY_EV_2,
+	DB8500_DMA_MEMCPY_EV_3,
+	DB8500_DMA_MEMCPY_EV_4,
+	DB8500_DMA_MEMCPY_EV_5,
+};
+
+/* Default configuration for physcial memcpy */
+static struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
+	.mode = STEDMA40_MODE_PHYSICAL,
+	.dir = DMA_MEM_TO_MEM,
+
+	.src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+	.src_info.psize = STEDMA40_PSIZE_PHY_1,
+	.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+	.dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+	.dst_info.psize = STEDMA40_PSIZE_PHY_1,
+	.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+};
+
+/* Default configuration for logical memcpy */
+static struct stedma40_chan_cfg dma40_memcpy_conf_log = {
+	.mode = STEDMA40_MODE_LOGICAL,
+	.dir = DMA_MEM_TO_MEM,
+
+	.src_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+	.src_info.psize = STEDMA40_PSIZE_LOG_1,
+	.src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+	.dst_info.data_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
+	.dst_info.psize = STEDMA40_PSIZE_LOG_1,
+	.dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+};
 
 /**
  * enum 40_command - The different commands and/or statuses.
@@ -171,6 +221,9 @@ static u32 d40_backup_regs_chan[] = {
 	D40_CHAN_REG_SDLNK,
 };
 
+#define BACKUP_REGS_SZ_MAX ((BACKUP_REGS_SZ_V4A > BACKUP_REGS_SZ_V4B) ? \
+			     BACKUP_REGS_SZ_V4A : BACKUP_REGS_SZ_V4B)
+
 /**
  * struct d40_interrupt_lookup - lookup table for interrupt handler
  *
@@ -471,6 +524,8 @@ struct d40_gen_dmac {
  * @phy_start: Physical memory start of the DMA registers.
  * @phy_size: Size of the DMA register map.
  * @irq: The IRQ number.
+ * @num_memcpy_chans: The number of channels used for memcpy (mem-to-mem
+ * transfers).
  * @num_phy_chans: The number of physical channels. Read from HW. This
  * is the number of available channels for this driver, not counting "Secure
  * mode" allocated physical channels.
@@ -514,6 +569,7 @@ struct d40_base {
 	phys_addr_t			  phy_start;
 	resource_size_t			  phy_size;
 	int				  irq;
+	int				  num_memcpy_chans;
 	int				  num_phy_chans;
 	int				  num_log_chans;
 	struct device_dma_parameters	  dma_parms;
@@ -534,7 +590,7 @@ struct d40_base {
 	resource_size_t			  lcpa_size;
 	struct kmem_cache		 *desc_slab;
 	u32				  reg_val_backup[BACKUP_REGS_SZ];
-	u32				  reg_val_backup_v4[MAX(BACKUP_REGS_SZ_V4A, BACKUP_REGS_SZ_V4B)];
+	u32				  reg_val_backup_v4[BACKUP_REGS_SZ_MAX];
 	u32				 *reg_val_backup_chan;
 	u16				  gcc_pwr_off_mask;
 	bool				  initialized;
@@ -792,7 +848,7 @@ static void d40_log_lli_to_lcxa(struct d
 		 * that uses linked lists.
 		 */
 		if (!(chan->phy_chan->use_soft_lli &&
-			chan->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM))
+			chan->dma_cfg.dir == DMA_DEV_TO_MEM))
 			curr_lcla = d40_lcla_alloc_one(chan, desc);
 
 		first_lcla = curr_lcla;
@@ -954,20 +1010,21 @@ static int d40_psize_2_burst_size(bool i
 
 /*
  * The dma only supports transmitting packages up to
- * STEDMA40_MAX_SEG_SIZE << data_width. Calculate the total number of
- * dma elements required to send the entire sg list
+ * STEDMA40_MAX_SEG_SIZE * data_width, where data_width is stored in Bytes.
+ *
+ * Calculate the total number of dma elements required to send the entire sg list.
  */
 static int d40_size_2_dmalen(int size, u32 data_width1, u32 data_width2)
 {
 	int dmalen;
 	u32 max_w = max(data_width1, data_width2);
 	u32 min_w = min(data_width1, data_width2);
-	u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w);
+	u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w);
 
 	if (seg_max > STEDMA40_MAX_SEG_SIZE)
-		seg_max -= (1 << max_w);
+		seg_max -= max_w;
 
-	if (!IS_ALIGNED(size, 1 << max_w))
+	if (!IS_ALIGNED(size, max_w))
 		return -EINVAL;
 
 	if (size <= seg_max)
@@ -1257,21 +1314,17 @@ static void __d40_config_set_event(struc
 static void d40_config_set_event(struct d40_chan *d40c,
 				 enum d40_events event_type)
 {
-	/* Enable event line connected to device (or memcpy) */
-	if ((d40c->dma_cfg.dir ==  STEDMA40_PERIPH_TO_MEM) ||
-	    (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) {
-		u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type);
+	u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type);
 
+	/* Enable event line connected to device (or memcpy) */
+	if ((d40c->dma_cfg.dir == DMA_DEV_TO_MEM) ||
+	    (d40c->dma_cfg.dir == DMA_DEV_TO_DEV))
 		__d40_config_set_event(d40c, event_type, event,
 				       D40_CHAN_REG_SSLNK);
-	}
-
-	if (d40c->dma_cfg.dir !=  STEDMA40_PERIPH_TO_MEM) {
-		u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type);
 
+	if (d40c->dma_cfg.dir !=  DMA_DEV_TO_MEM)
 		__d40_config_set_event(d40c, event_type, event,
 				       D40_CHAN_REG_SDLNK);
-	}
 }
 
 static u32 d40_chan_has_events(struct d40_chan *d40c)
@@ -1417,7 +1470,7 @@ static u32 d40_residue(struct d40_chan *
 			  >> D40_SREG_ELEM_PHY_ECNT_POS;
 	}
 
-	return num_elt * (1 << d40c->dma_cfg.dst_info.data_width);
+	return num_elt * d40c->dma_cfg.dst_info.data_width;
 }
 
 static bool d40_tx_is_linked(struct d40_chan *d40c)
@@ -1693,7 +1746,7 @@ static irqreturn_t d40_handle_interrupt(
 		}
 
 		/* ACK interrupt */
-		writel(1 << idx, base->virtbase + il[row].clr);
+		writel(BIT(idx), base->virtbase + il[row].clr);
 
 		spin_lock(&d40c->lock);
 
@@ -1715,8 +1768,6 @@ static int d40_validate_conf(struct d40_
 			     struct stedma40_chan_cfg *conf)
 {
 	int res = 0;
-	u32 dst_event_group = D40_TYPE_TO_GROUP(conf->dst_dev_type);
-	u32 src_event_group = D40_TYPE_TO_GROUP(conf->src_dev_type);
 	bool is_log = conf->mode == STEDMA40_MODE_LOGICAL;
 
 	if (!conf->dir) {
@@ -1724,48 +1775,14 @@ static int d40_validate_conf(struct d40_
 		res = -EINVAL;
 	}
 
-	if (conf->dst_dev_type != STEDMA40_DEV_DST_MEMORY &&
-	    d40c->base->plat_data->dev_tx[conf->dst_dev_type] == 0 &&
-	    d40c->runtime_addr == 0) {
-
-		chan_err(d40c, "Invalid TX channel address (%d)\n",
-			 conf->dst_dev_type);
-		res = -EINVAL;
-	}
-
-	if (conf->src_dev_type != STEDMA40_DEV_SRC_MEMORY &&
-	    d40c->base->plat_data->dev_rx[conf->src_dev_type] == 0 &&
-	    d40c->runtime_addr == 0) {
-		chan_err(d40c, "Invalid RX channel address (%d)\n",
-			conf->src_dev_type);
-		res = -EINVAL;
-	}
-
-	if (conf->dir == STEDMA40_MEM_TO_PERIPH &&
-	    dst_event_group == STEDMA40_DEV_DST_MEMORY) {
-		chan_err(d40c, "Invalid dst\n");
-		res = -EINVAL;
-	}
-
-	if (conf->dir == STEDMA40_PERIPH_TO_MEM &&
-	    src_event_group == STEDMA40_DEV_SRC_MEMORY) {
-		chan_err(d40c, "Invalid src\n");
-		res = -EINVAL;
-	}
-
-	if (src_event_group == STEDMA40_DEV_SRC_MEMORY &&
-	    dst_event_group == STEDMA40_DEV_DST_MEMORY && is_log) {
-		chan_err(d40c, "No event line\n");
-		res = -EINVAL;
-	}
-
-	if (conf->dir == STEDMA40_PERIPH_TO_PERIPH &&
-	    (src_event_group != dst_event_group)) {
-		chan_err(d40c, "Invalid event group\n");
+	if ((is_log && conf->dev_type > d40c->base->num_log_chans)  ||
+	    (!is_log && conf->dev_type > d40c->base->num_phy_chans) ||
+	    (conf->dev_type < 0)) {
+		chan_err(d40c, "Invalid device type (%d)\n", conf->dev_type);
 		res = -EINVAL;
 	}
 
-	if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) {
+	if (conf->dir == DMA_DEV_TO_DEV) {
 		/*
 		 * DMAC HW supports it. Will be added to this driver,
 		 * in case any dma client requires it.
@@ -1775,9 +1792,9 @@ static int d40_validate_conf(struct d40_
 	}
 
 	if (d40_psize_2_burst_size(is_log, conf->src_info.psize) *
-	    (1 << conf->src_info.data_width) !=
+	    conf->src_info.data_width !=
 	    d40_psize_2_burst_size(is_log, conf->dst_info.psize) *
-	    (1 << conf->dst_info.data_width)) {
+	    conf->dst_info.data_width) {
 		/*
 		 * The DMAC hardware only supports
 		 * src (burst x width) == dst (burst x width)
@@ -1819,8 +1836,8 @@ static bool d40_alloc_mask_set(struct d4
 		if (phy->allocated_src == D40_ALLOC_FREE)
 			phy->allocated_src = D40_ALLOC_LOG_FREE;
 
-		if (!(phy->allocated_src & (1 << log_event_line))) {
-			phy->allocated_src |= 1 << log_event_line;
+		if (!(phy->allocated_src & BIT(log_event_line))) {
+			phy->allocated_src |= BIT(log_event_line);
 			goto found;
 		} else
 			goto not_found;
@@ -1831,8 +1848,8 @@ static bool d40_alloc_mask_set(struct d4
 		if (phy->allocated_dst == D40_ALLOC_FREE)
 			phy->allocated_dst = D40_ALLOC_LOG_FREE;
 
-		if (!(phy->allocated_dst & (1 << log_event_line))) {
-			phy->allocated_dst |= 1 << log_event_line;
+		if (!(phy->allocated_dst & BIT(log_event_line))) {
+			phy->allocated_dst |= BIT(log_event_line);
 			goto found;
 		} else
 			goto not_found;
@@ -1862,11 +1879,11 @@ static bool d40_alloc_mask_free(struct d
 
 	/* Logical channel */
 	if (is_src) {
-		phy->allocated_src &= ~(1 << log_event_line);
+		phy->allocated_src &= ~BIT(log_event_line);
 		if (phy->allocated_src == D40_ALLOC_LOG_FREE)
 			phy->allocated_src = D40_ALLOC_FREE;
 	} else {
-		phy->allocated_dst &= ~(1 << log_event_line);
+		phy->allocated_dst &= ~BIT(log_event_line);
 		if (phy->allocated_dst == D40_ALLOC_LOG_FREE)
 			phy->allocated_dst = D40_ALLOC_FREE;
 	}
@@ -1882,7 +1899,7 @@ out:
 
 static int d40_allocate_channel(struct d40_chan *d40c, bool *first_phy_user)
 {
-	int dev_type;
+	int dev_type = d40c->dma_cfg.dev_type;
 	int event_group;
 	int event_line;
 	struct d40_phy_res *phys;
@@ -1896,14 +1913,12 @@ static int d40_allocate_channel(struct d
 	phys = d40c->base->phy_res;
 	num_phy_chans = d40c->base->num_phy_chans;
 
-	if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) {
-		dev_type = d40c->dma_cfg.src_dev_type;
+	if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) {
 		log_num = 2 * dev_type;
 		is_src = true;
-	} else if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH ||
-		   d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
+	} else if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV ||
+		   d40c->dma_cfg.dir == DMA_MEM_TO_MEM) {
 		/* dst event lines are used for logical memcpy */
-		dev_type = d40c->dma_cfg.dst_dev_type;
 		log_num = 2 * dev_type + 1;
 		is_src = false;
 	} else
@@ -1913,7 +1928,7 @@ static int d40_allocate_channel(struct d
 	event_line = D40_TYPE_TO_EVENT(dev_type);
 
 	if (!is_log) {
-		if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
+		if (d40c->dma_cfg.dir == DMA_MEM_TO_MEM) {
 			/* Find physical half channel */
 			if (d40c->dma_cfg.use_fixed_channel) {
 				i = d40c->dma_cfg.phy_channel;
@@ -2014,14 +2029,23 @@ static int d40_config_memcpy(struct d40_
 	dma_cap_mask_t cap = d40c->chan.device->cap_mask;
 
 	if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) {
-		d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_log;
-		d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY;
-		d40c->dma_cfg.dst_dev_type = d40c->base->plat_data->
-			memcpy[d40c->chan.chan_id];
+		d40c->dma_cfg = dma40_memcpy_conf_log;
+		d40c->dma_cfg.dev_type = dma40_memcpy_channels[d40c->chan.chan_id];
+
+		d40_log_cfg(&d40c->dma_cfg,
+			    &d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
 
 	} else if (dma_has_cap(DMA_MEMCPY, cap) &&
 		   dma_has_cap(DMA_SLAVE, cap)) {
-		d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_phy;
+		d40c->dma_cfg = dma40_memcpy_conf_phy;
+
+		/* Generate interrrupt at end of transfer or relink. */
+		d40c->dst_def_cfg |= BIT(D40_SREG_CFG_TIM_POS);
+
+		/* Generate interrupt on error. */
+		d40c->src_def_cfg |= BIT(D40_SREG_CFG_EIM_POS);
+		d40c->dst_def_cfg |= BIT(D40_SREG_CFG_EIM_POS);
+
 	} else {
 		chan_err(d40c, "No memcpy\n");
 		return -EINVAL;
@@ -2034,7 +2058,7 @@ static int d40_free_dma(struct d40_chan
 {
 
 	int res = 0;
-	u32 event;
+	u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type);
 	struct d40_phy_res *phy = d40c->phy_chan;
 	bool is_src;
 
@@ -2052,14 +2076,12 @@ static int d40_free_dma(struct d40_chan
 		return -EINVAL;
 	}
 
-	if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH ||
-	    d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
-		event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type);
+	if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV ||
+	    d40c->dma_cfg.dir == DMA_MEM_TO_MEM)
 		is_src = false;
-	} else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) {
-		event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type);
+	else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM)
 		is_src = true;
-	} else {
+	else {
 		chan_err(d40c, "Unknown direction\n");
 		return -EINVAL;
 	}
@@ -2100,7 +2122,7 @@ static bool d40_is_paused(struct d40_cha
 	unsigned long flags;
 	void __iomem *active_reg;
 	u32 status;
-	u32 event;
+	u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dev_type);
 
 	spin_lock_irqsave(&d40c->lock, flags);
 
@@ -2119,12 +2141,10 @@ static bool d40_is_paused(struct d40_cha
 		goto _exit;
 	}
 
-	if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH ||
-	    d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) {
-		event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type);
+	if (d40c->dma_cfg.dir == DMA_MEM_TO_DEV ||
+	    d40c->dma_cfg.dir == DMA_MEM_TO_MEM) {
 		status = readl(chanbase + D40_CHAN_REG_SDLNK);
-	} else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) {
-		event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type);
+	} else if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM) {
 		status = readl(chanbase + D40_CHAN_REG_SSLNK);
 	} else {
 		chan_err(d40c, "Unknown direction\n");
@@ -2255,24 +2275,6 @@ err:
 	return NULL;
 }
 
-static dma_addr_t
-d40_get_dev_addr(struct d40_chan *chan, enum dma_transfer_direction direction)
-{
-	struct stedma40_platform_data *plat = chan->base->plat_data;
-	struct stedma40_chan_cfg *cfg = &chan->dma_cfg;
-	dma_addr_t addr = 0;
-
-	if (chan->runtime_addr)
-		return chan->runtime_addr;
-
-	if (direction == DMA_DEV_TO_MEM)
-		addr = plat->dev_rx[cfg->src_dev_type];
-	else if (direction == DMA_MEM_TO_DEV)
-		addr = plat->dev_tx[cfg->dst_dev_type];
-
-	return addr;
-}
-
 static struct dma_async_tx_descriptor *
 d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src,
 	    struct scatterlist *sg_dst, unsigned int sg_len,
@@ -2299,14 +2301,10 @@ d40_prep_sg(struct dma_chan *dchan, stru
 	if (sg_next(&sg_src[sg_len - 1]) == sg_src)
 		desc->cyclic = true;
 
-	if (direction != DMA_TRANS_NONE) {
-		dma_addr_t dev_addr = d40_get_dev_addr(chan, direction);
-
-		if (direction == DMA_DEV_TO_MEM)
-			src_dev_addr = dev_addr;
-		else if (direction == DMA_MEM_TO_DEV)
-			dst_dev_addr = dev_addr;
-	}
+	if (direction == DMA_DEV_TO_MEM)
+		src_dev_addr = chan->runtime_addr;
+	else if (direction == DMA_MEM_TO_DEV)
+		dst_dev_addr = chan->runtime_addr;
 
 	if (chan_is_logical(chan))
 		ret = d40_prep_sg_log(chan, desc, sg_src, sg_dst,
@@ -2366,7 +2364,7 @@ static void __d40_set_prio_rt(struct d40
 	u32 rtreg;
 	u32 event = D40_TYPE_TO_EVENT(dev_type);
 	u32 group = D40_TYPE_TO_GROUP(dev_type);
-	u32 bit = 1 << event;
+	u32 bit = BIT(event);
 	u32 prioreg;
 	struct d40_gen_dmac *dmac = &d40c->base->gen_dmac;
 
@@ -2397,13 +2395,57 @@ static void d40_set_prio_realtime(struct
 	if (d40c->base->rev < 3)
 		return;
 
-	if ((d40c->dma_cfg.dir ==  STEDMA40_PERIPH_TO_MEM) ||
-	    (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH))
-		__d40_set_prio_rt(d40c, d40c->dma_cfg.src_dev_type, true);
+	if ((d40c->dma_cfg.dir ==  DMA_DEV_TO_MEM) ||
+	    (d40c->dma_cfg.dir == DMA_DEV_TO_DEV))
+		__d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, true);
 
-	if ((d40c->dma_cfg.dir ==  STEDMA40_MEM_TO_PERIPH) ||
-	    (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH))
-		__d40_set_prio_rt(d40c, d40c->dma_cfg.dst_dev_type, false);
+	if ((d40c->dma_cfg.dir ==  DMA_MEM_TO_DEV) ||
+	    (d40c->dma_cfg.dir == DMA_DEV_TO_DEV))
+		__d40_set_prio_rt(d40c, d40c->dma_cfg.dev_type, false);
+}
+
+#define D40_DT_FLAGS_MODE(flags)       ((flags >> 0) & 0x1)
+#define D40_DT_FLAGS_DIR(flags)        ((flags >> 1) & 0x1)
+#define D40_DT_FLAGS_BIG_ENDIAN(flags) ((flags >> 2) & 0x1)
+#define D40_DT_FLAGS_FIXED_CHAN(flags) ((flags >> 3) & 0x1)
+
+static struct dma_chan *d40_xlate(struct of_phandle_args *dma_spec,
+				  struct of_dma *ofdma)
+{
+	struct stedma40_chan_cfg cfg;
+	dma_cap_mask_t cap;
+	u32 flags;
+
+	memset(&cfg, 0, sizeof(struct stedma40_chan_cfg));
+
+	dma_cap_zero(cap);
+	dma_cap_set(DMA_SLAVE, cap);
+
+	cfg.dev_type = dma_spec->args[0];
+	flags = dma_spec->args[2];
+
+	switch (D40_DT_FLAGS_MODE(flags)) {
+	case 0: cfg.mode = STEDMA40_MODE_LOGICAL; break;
+	case 1: cfg.mode = STEDMA40_MODE_PHYSICAL; break;
+	}
+
+	switch (D40_DT_FLAGS_DIR(flags)) {
+	case 0:
+		cfg.dir = DMA_MEM_TO_DEV;
+		cfg.dst_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags);
+		break;
+	case 1:
+		cfg.dir = DMA_DEV_TO_MEM;
+		cfg.src_info.big_endian = D40_DT_FLAGS_BIG_ENDIAN(flags);
+		break;
+	}
+
+	if (D40_DT_FLAGS_FIXED_CHAN(flags)) {
+		cfg.phy_channel = dma_spec->args[1];
+		cfg.use_fixed_channel = true;
+	}
+
+	return dma_request_channel(cap, stedma40_filter, &cfg);
 }
 
 /* DMA ENGINE functions */
@@ -2435,23 +2477,21 @@ static int d40_alloc_chan_resources(stru
 	}
 
 	pm_runtime_get_sync(d40c->base->dev);
-	/* Fill in basic CFG register values */
-	d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg,
-		    &d40c->dst_def_cfg, chan_is_logical(d40c));
 
 	d40_set_prio_realtime(d40c);
 
 	if (chan_is_logical(d40c)) {
-		d40_log_cfg(&d40c->dma_cfg,
-			    &d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
-
-		if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM)
+		if (d40c->dma_cfg.dir == DMA_DEV_TO_MEM)
 			d40c->lcpa = d40c->base->lcpa_base +
-				d40c->dma_cfg.src_dev_type * D40_LCPA_CHAN_SIZE;
+				d40c->dma_cfg.dev_type * D40_LCPA_CHAN_SIZE;
 		else
 			d40c->lcpa = d40c->base->lcpa_base +
-				d40c->dma_cfg.dst_dev_type *
+				d40c->dma_cfg.dev_type *
 				D40_LCPA_CHAN_SIZE + D40_LCPA_CHAN_DST_DELTA;
+
+		/* Unmask the Global Interrupt Mask. */
+		d40c->src_def_cfg |= BIT(D40_SREG_CFG_LOG_GIM_POS);
+		d40c->dst_def_cfg |= BIT(D40_SREG_CFG_LOG_GIM_POS);
 	}
 
 	dev_dbg(chan2dev(d40c), "allocated %s channel (phy %d%s)\n",
@@ -2641,33 +2681,10 @@ static void d40_terminate_all(struct dma
 static int
 dma40_config_to_halfchannel(struct d40_chan *d40c,
 			    struct stedma40_half_channel_info *info,
-			    enum dma_slave_buswidth width,
 			    u32 maxburst)
 {
-	enum stedma40_periph_data_width addr_width;
 	int psize;
 
-	switch (width) {
-	case DMA_SLAVE_BUSWIDTH_1_BYTE:
-		addr_width = STEDMA40_BYTE_WIDTH;
-		break;
-	case DMA_SLAVE_BUSWIDTH_2_BYTES:
-		addr_width = STEDMA40_HALFWORD_WIDTH;
-		break;
-	case DMA_SLAVE_BUSWIDTH_4_BYTES:
-		addr_width = STEDMA40_WORD_WIDTH;
-		break;
-	case DMA_SLAVE_BUSWIDTH_8_BYTES:
-		addr_width = STEDMA40_DOUBLEWORD_WIDTH;
-		break;
-	default:
-		dev_err(d40c->base->dev,
-			"illegal peripheral address width "
-			"requested (%d)\n",
-			width);
-		return -EINVAL;
-	}
-
 	if (chan_is_logical(d40c)) {
 		if (maxburst >= 16)
 			psize = STEDMA40_PSIZE_LOG_16;
@@ -2688,7 +2705,6 @@ dma40_config_to_halfchannel(struct d40_c
 			psize = STEDMA40_PSIZE_PHY_1;
 	}
 
-	info->data_width = addr_width;
 	info->psize = psize;
 	info->flow_ctrl = STEDMA40_NO_FLOW_CTRL;
 
@@ -2712,21 +2728,14 @@ static int d40_set_runtime_config(struct
 	dst_maxburst = config->dst_maxburst;
 
 	if (config->direction == DMA_DEV_TO_MEM) {
-		dma_addr_t dev_addr_rx =
-			d40c->base->plat_data->dev_rx[cfg->src_dev_type];
-
 		config_addr = config->src_addr;
-		if (dev_addr_rx)
-			dev_dbg(d40c->base->dev,
-				"channel has a pre-wired RX address %08x "
-				"overriding with %08x\n",
-				dev_addr_rx, config_addr);
-		if (cfg->dir != STEDMA40_PERIPH_TO_MEM)
+
+		if (cfg->dir != DMA_DEV_TO_MEM)
 			dev_dbg(d40c->base->dev,
 				"channel was not configured for peripheral "
 				"to memory transfer (%d) overriding\n",
 				cfg->dir);
-		cfg->dir = STEDMA40_PERIPH_TO_MEM;
+		cfg->dir = DMA_DEV_TO_MEM;
 
 		/* Configure the memory side */
 		if (dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
@@ -2735,21 +2744,14 @@ static int d40_set_runtime_config(struct
 			dst_maxburst = src_maxburst;
 
 	} else if (config->direction == DMA_MEM_TO_DEV) {
-		dma_addr_t dev_addr_tx =
-			d40c->base->plat_data->dev_tx[cfg->dst_dev_type];
-
 		config_addr = config->dst_addr;
-		if (dev_addr_tx)
-			dev_dbg(d40c->base->dev,
-				"channel has a pre-wired TX address %08x "
-				"overriding with %08x\n",
-				dev_addr_tx, config_addr);
-		if (cfg->dir != STEDMA40_MEM_TO_PERIPH)
+
+		if (cfg->dir != DMA_MEM_TO_DEV)
 			dev_dbg(d40c->base->dev,
 				"channel was not configured for memory "
 				"to peripheral transfer (%d) overriding\n",
 				cfg->dir);
-		cfg->dir = STEDMA40_MEM_TO_PERIPH;
+		cfg->dir = DMA_MEM_TO_DEV;
 
 		/* Configure the memory side */
 		if (src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
@@ -2763,6 +2765,11 @@ static int d40_set_runtime_config(struct
 		return -EINVAL;
 	}
 
+	if (config_addr <= 0) {
+		dev_err(d40c->base->dev, "no address supplied\n");
+		return -EINVAL;
+	}
+
 	if (src_maxburst * src_addr_width != dst_maxburst * dst_addr_width) {
 		dev_err(d40c->base->dev,
 			"src/dst width/maxburst mismatch: %d*%d != %d*%d\n",
@@ -2781,14 +2788,24 @@ static int d40_set_runtime_config(struct
 		src_maxburst = dst_maxburst * dst_addr_width / src_addr_width;
 	}
 
+	/* Only valid widths are; 1, 2, 4 and 8. */
+	if (src_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED ||
+	    src_addr_width >  DMA_SLAVE_BUSWIDTH_8_BYTES   ||
+	    dst_addr_width <= DMA_SLAVE_BUSWIDTH_UNDEFINED ||
+	    dst_addr_width >  DMA_SLAVE_BUSWIDTH_8_BYTES   ||
+	    ((src_addr_width > 1) && (src_addr_width & 1)) ||
+	    ((dst_addr_width > 1) && (dst_addr_width & 1)))
+		return -EINVAL;
+
+	cfg->src_info.data_width = src_addr_width;
+	cfg->dst_info.data_width = dst_addr_width;
+
 	ret = dma40_config_to_halfchannel(d40c, &cfg->src_info,
-					  src_addr_width,
 					  src_maxburst);
 	if (ret)
 		return ret;
 
 	ret = dma40_config_to_halfchannel(d40c, &cfg->dst_info,
-					  dst_addr_width,
 					  dst_maxburst);
 	if (ret)
 		return ret;
@@ -2797,8 +2814,7 @@ static int d40_set_runtime_config(struct
 	if (chan_is_logical(d40c))
 		d40_log_cfg(cfg, &d40c->log_def.lcsp1, &d40c->log_def.lcsp3);
 	else
-		d40_phy_cfg(cfg, &d40c->src_def_cfg,
-			    &d40c->dst_def_cfg, false);
+		d40_phy_cfg(cfg, &d40c->src_def_cfg, &d40c->dst_def_cfg);
 
 	/* These settings will take precedence later */
 	d40c->runtime_addr = config_addr;
@@ -2929,7 +2945,7 @@ static int __init d40_dmaengine_init(str
 	}
 
 	d40_chan_init(base, &base->dma_memcpy, base->log_chans,
-		      base->num_log_chans, base->plat_data->memcpy_len);
+		      base->num_log_chans, base->num_memcpy_chans);
 
 	dma_cap_zero(base->dma_memcpy.cap_mask);
 	dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask);
@@ -3123,13 +3139,14 @@ static int __init d40_phy_res_init(struc
 
 static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev)
 {
-	struct stedma40_platform_data *plat_data;
+	struct stedma40_platform_data *plat_data = pdev->dev.platform_data;
 	struct clk *clk = NULL;
 	void __iomem *virtbase = NULL;
 	struct resource *res = NULL;
 	struct d40_base *base = NULL;
 	int num_log_chans = 0;
 	int num_phy_chans;
+	int num_memcpy_chans;
 	int clk_ret = -EINVAL;
 	int i;
 	u32 pid;
@@ -3189,8 +3206,10 @@ static struct d40_base * __init d40_hw_d
 	 * DB8540v1 has revision 4
 	 */
 	rev = AMBA_REV_BITS(pid);
-
-	plat_data = pdev->dev.platform_data;
+	if (rev < 2) {
+		d40_err(&pdev->dev, "hardware revision: %d is not supported", rev);
+		goto failure;
+	}
 
 	/* The number of physical channels on this HW */
 	if (plat_data->num_of_phy_chans)
@@ -3198,26 +3217,20 @@ static struct d40_base * __init d40_hw_d
 	else
 		num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4;
 
-	dev_info(&pdev->dev, "hardware revision: %d @ 0x%x with %d physical channels\n",
-		 rev, res->start, num_phy_chans);
-
-	if (rev < 2) {
-		d40_err(&pdev->dev, "hardware revision: %d is not supported",
-			rev);
-		goto failure;
-	}
+	/* The number of channels used for memcpy */
+	if (plat_data->num_of_memcpy_chans)
+		num_memcpy_chans = plat_data->num_of_memcpy_chans;
+	else
+		num_memcpy_chans = ARRAY_SIZE(dma40_memcpy_channels);
 
-	/* Count the number of logical channels in use */
-	for (i = 0; i < plat_data->dev_len; i++)
-		if (plat_data->dev_rx[i] != 0)
-			num_log_chans++;
+	num_log_chans = num_phy_chans * D40_MAX_LOG_CHAN_PER_PHY;
 
-	for (i = 0; i < plat_data->dev_len; i++)
-		if (plat_data->dev_tx[i] != 0)
-			num_log_chans++;
+	dev_info(&pdev->dev,
+		 "hardware rev: %d @ 0x%x with %d physical and %d logical channels\n",
+		 rev, res->start, num_phy_chans, num_log_chans);
 
 	base = kzalloc(ALIGN(sizeof(struct d40_base), 4) +
-		       (num_phy_chans + num_log_chans + plat_data->memcpy_len) *
+		       (num_phy_chans + num_log_chans + num_memcpy_chans) *
 		       sizeof(struct d40_chan), GFP_KERNEL);
 
 	if (base == NULL) {
@@ -3227,6 +3240,7 @@ static struct d40_base * __init d40_hw_d
 
 	base->rev = rev;
 	base->clk = clk;
+	base->num_memcpy_chans = num_memcpy_chans;
 	base->num_phy_chans = num_phy_chans;
 	base->num_log_chans = num_log_chans;
 	base->phy_start = res->start;
@@ -3278,17 +3292,11 @@ static struct d40_base * __init d40_hw_d
 	if (!base->lookup_phy_chans)
 		goto failure;
 
-	if (num_log_chans + plat_data->memcpy_len) {
-		/*
-		 * The max number of logical channels are event lines for all
-		 * src devices and dst devices
-		 */
-		base->lookup_log_chans = kzalloc(plat_data->dev_len * 2 *
-						 sizeof(struct d40_chan *),
-						 GFP_KERNEL);
-		if (!base->lookup_log_chans)
-			goto failure;
-	}
+	base->lookup_log_chans = kzalloc(num_log_chans *
+					 sizeof(struct d40_chan *),
+					 GFP_KERNEL);
+	if (!base->lookup_log_chans)
+		goto failure;
 
 	base->reg_val_backup_chan = kmalloc(base->num_phy_chans *
 					    sizeof(d40_backup_regs_chan),
@@ -3472,17 +3480,82 @@ failure:
 	return ret;
 }
 
+static int __init d40_of_probe(struct platform_device *pdev,
+			       struct device_node *np)
+{
+	struct stedma40_platform_data *pdata;
+	int num_phy = 0, num_memcpy = 0, num_disabled = 0;
+	const const __be32 *list;
+
+	pdata = devm_kzalloc(&pdev->dev,
+			     sizeof(struct stedma40_platform_data),
+			     GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	/* If absent this value will be obtained from h/w. */
+	of_property_read_u32(np, "dma-channels", &num_phy);
+	if (num_phy > 0)
+		pdata->num_of_phy_chans = num_phy;
+
+	list = of_get_property(np, "memcpy-channels", &num_memcpy);
+	num_memcpy /= sizeof(*list);
+
+	if (num_memcpy > D40_MEMCPY_MAX_CHANS || num_memcpy <= 0) {
+		d40_err(&pdev->dev,
+			"Invalid number of memcpy channels specified (%d)\n",
+			num_memcpy);
+		return -EINVAL;
+	}
+	pdata->num_of_memcpy_chans = num_memcpy;
+
+	of_property_read_u32_array(np, "memcpy-channels",
+				   dma40_memcpy_channels,
+				   num_memcpy);
+
+	list = of_get_property(np, "disabled-channels", &num_disabled);
+	num_disabled /= sizeof(*list);
+
+	if (num_disabled > STEDMA40_MAX_PHYS || num_disabled < 0) {
+		d40_err(&pdev->dev,
+			"Invalid number of disabled channels specified (%d)\n",
+			num_disabled);
+		return -EINVAL;
+	}
+
+	of_property_read_u32_array(np, "disabled-channels",
+				   pdata->disabled_channels,
+				   num_disabled);
+	pdata->disabled_channels[num_disabled] = -1;
+
+	pdev->dev.platform_data = pdata;
+
+	return 0;
+}
+
 static int __init d40_probe(struct platform_device *pdev)
 {
-	int err;
+	struct stedma40_platform_data *plat_data = pdev->dev.platform_data;
+	struct device_node *np = pdev->dev.of_node;
 	int ret = -ENOENT;
-	struct d40_base *base;
+	struct d40_base *base = NULL;
 	struct resource *res = NULL;
 	int num_reserved_chans;
 	u32 val;
 
-	base = d40_hw_detect_init(pdev);
+	if (!plat_data) {
+		if (np) {
+			if(d40_of_probe(pdev, np)) {
+				ret = -ENOMEM;
+				goto failure;
+			}
+		} else {
+			d40_err(&pdev->dev, "No pdata or Device Tree provided\n");
+			goto failure;
+		}
+	}
 
+	base = d40_hw_detect_init(pdev);
 	if (!base)
 		goto failure;
 
@@ -3575,6 +3648,7 @@ static int __init d40_probe(struct platf
 		base->lcpa_regulator = regulator_get(base->dev, "lcla_esram");
 		if (IS_ERR(base->lcpa_regulator)) {
 			d40_err(&pdev->dev, "Failed to get lcpa_regulator\n");
+			ret = PTR_ERR(base->lcpa_regulator);
 			base->lcpa_regulator = NULL;
 			goto failure;
 		}
@@ -3590,19 +3664,26 @@ static int __init d40_probe(struct platf
 	}
 
 	base->initialized = true;
-	err = d40_dmaengine_init(base, num_reserved_chans);
-	if (err)
+	ret = d40_dmaengine_init(base, num_reserved_chans);
+	if (ret)
 		goto failure;
 
 	base->dev->dma_parms = &base->dma_parms;
-	err = dma_set_max_seg_size(base->dev, STEDMA40_MAX_SEG_SIZE);
-	if (err) {
+	ret = dma_set_max_seg_size(base->dev, STEDMA40_MAX_SEG_SIZE);
+	if (ret) {
 		d40_err(&pdev->dev, "Failed to set dma max seg size\n");
 		goto failure;
 	}
 
 	d40_hw_init(base);
 
+	if (np) {
+		ret = of_dma_controller_register(np, d40_xlate, NULL);
+		if (ret)
+			dev_err(&pdev->dev,
+				"could not register of_dma_controller\n");
+	}
+
 	dev_info(base->dev, "initialized\n");
 	return 0;
 
@@ -3656,11 +3737,17 @@ failure:
 	return ret;
 }
 
+static const struct of_device_id d40_match[] = {
+        { .compatible = "stericsson,dma40", },
+        {}
+};
+
 static struct platform_driver d40_driver = {
 	.driver = {
 		.owner = THIS_MODULE,
 		.name  = D40_NAME,
 		.pm = DMA40_PM_OPS,
+		.of_match_table = d40_match,
 	},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/ste_dma40_ll.c linux-libre-3.11-rc7-gnu/drivers/dma/ste_dma40_ll.c
--- linux-libre-3.10-gnu/drivers/dma/ste_dma40_ll.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/ste_dma40_ll.c	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,18 @@
 
 #include "ste_dma40_ll.h"
 
+u8 d40_width_to_bits(enum dma_slave_buswidth width)
+{
+	if (width == DMA_SLAVE_BUSWIDTH_1_BYTE)
+		return STEDMA40_ESIZE_8_BIT;
+	else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
+		return STEDMA40_ESIZE_16_BIT;
+	else if (width == DMA_SLAVE_BUSWIDTH_8_BYTES)
+		return STEDMA40_ESIZE_64_BIT;
+	else
+		return STEDMA40_ESIZE_32_BIT;
+}
+
 /* Sets up proper LCSP1 and LCSP3 register for a logical channel */
 void d40_log_cfg(struct stedma40_chan_cfg *cfg,
 		 u32 *lcsp1, u32 *lcsp3)
@@ -18,106 +30,100 @@ void d40_log_cfg(struct stedma40_chan_cf
 	u32 l1 = 0; /* src */
 
 	/* src is mem? -> increase address pos */
-	if (cfg->dir ==  STEDMA40_MEM_TO_PERIPH ||
-	    cfg->dir ==  STEDMA40_MEM_TO_MEM)
-		l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS;
+	if (cfg->dir ==  DMA_MEM_TO_DEV ||
+	    cfg->dir ==  DMA_MEM_TO_MEM)
+		l1 |= BIT(D40_MEM_LCSP1_SCFG_INCR_POS);
 
 	/* dst is mem? -> increase address pos */
-	if (cfg->dir ==  STEDMA40_PERIPH_TO_MEM ||
-	    cfg->dir ==  STEDMA40_MEM_TO_MEM)
-		l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS;
+	if (cfg->dir ==  DMA_DEV_TO_MEM ||
+	    cfg->dir ==  DMA_MEM_TO_MEM)
+		l3 |= BIT(D40_MEM_LCSP3_DCFG_INCR_POS);
 
 	/* src is hw? -> master port 1 */
-	if (cfg->dir ==  STEDMA40_PERIPH_TO_MEM ||
-	    cfg->dir ==  STEDMA40_PERIPH_TO_PERIPH)
-		l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS;
+	if (cfg->dir ==  DMA_DEV_TO_MEM ||
+	    cfg->dir ==  DMA_DEV_TO_DEV)
+		l1 |= BIT(D40_MEM_LCSP1_SCFG_MST_POS);
 
 	/* dst is hw? -> master port 1 */
-	if (cfg->dir ==  STEDMA40_MEM_TO_PERIPH ||
-	    cfg->dir ==  STEDMA40_PERIPH_TO_PERIPH)
-		l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS;
+	if (cfg->dir ==  DMA_MEM_TO_DEV ||
+	    cfg->dir ==  DMA_DEV_TO_DEV)
+		l3 |= BIT(D40_MEM_LCSP3_DCFG_MST_POS);
 
-	l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS;
+	l3 |= BIT(D40_MEM_LCSP3_DCFG_EIM_POS);
 	l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS;
-	l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS;
+	l3 |= d40_width_to_bits(cfg->dst_info.data_width)
+		<< D40_MEM_LCSP3_DCFG_ESIZE_POS;
 
-	l1 |= 1 << D40_MEM_LCSP1_SCFG_EIM_POS;
+	l1 |= BIT(D40_MEM_LCSP1_SCFG_EIM_POS);
 	l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS;
-	l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS;
+	l1 |= d40_width_to_bits(cfg->src_info.data_width)
+		<< D40_MEM_LCSP1_SCFG_ESIZE_POS;
 
 	*lcsp1 = l1;
 	*lcsp3 = l3;
 
 }
 
-/* Sets up SRC and DST CFG register for both logical and physical channels */
-void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
-		 u32 *src_cfg, u32 *dst_cfg, bool is_log)
+void d40_phy_cfg(struct stedma40_chan_cfg *cfg, u32 *src_cfg, u32 *dst_cfg)
 {
 	u32 src = 0;
 	u32 dst = 0;
 
-	if (!is_log) {
-		/* Physical channel */
-		if ((cfg->dir ==  STEDMA40_PERIPH_TO_MEM) ||
-		    (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) {
-			/* Set master port to 1 */
-			src |= 1 << D40_SREG_CFG_MST_POS;
-			src |= D40_TYPE_TO_EVENT(cfg->src_dev_type);
-
-			if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
-				src |= 1 << D40_SREG_CFG_PHY_TM_POS;
-			else
-				src |= 3 << D40_SREG_CFG_PHY_TM_POS;
-		}
-		if ((cfg->dir ==  STEDMA40_MEM_TO_PERIPH) ||
-		    (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) {
-			/* Set master port to 1 */
-			dst |= 1 << D40_SREG_CFG_MST_POS;
-			dst |= D40_TYPE_TO_EVENT(cfg->dst_dev_type);
+	if ((cfg->dir == DMA_DEV_TO_MEM) ||
+	    (cfg->dir == DMA_DEV_TO_DEV)) {
+		/* Set master port to 1 */
+		src |= BIT(D40_SREG_CFG_MST_POS);
+		src |= D40_TYPE_TO_EVENT(cfg->dev_type);
 
-			if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
-				dst |= 1 << D40_SREG_CFG_PHY_TM_POS;
-			else
-				dst |= 3 << D40_SREG_CFG_PHY_TM_POS;
-		}
-		/* Interrupt on end of transfer for destination */
-		dst |= 1 << D40_SREG_CFG_TIM_POS;
+		if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
+			src |= BIT(D40_SREG_CFG_PHY_TM_POS);
+		else
+			src |= 3 << D40_SREG_CFG_PHY_TM_POS;
+	}
+	if ((cfg->dir == DMA_MEM_TO_DEV) ||
+	    (cfg->dir == DMA_DEV_TO_DEV)) {
+		/* Set master port to 1 */
+		dst |= BIT(D40_SREG_CFG_MST_POS);
+		dst |= D40_TYPE_TO_EVENT(cfg->dev_type);
 
-		/* Generate interrupt on error */
-		src |= 1 << D40_SREG_CFG_EIM_POS;
-		dst |= 1 << D40_SREG_CFG_EIM_POS;
+		if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL)
+			dst |= BIT(D40_SREG_CFG_PHY_TM_POS);
+		else
+			dst |= 3 << D40_SREG_CFG_PHY_TM_POS;
+	}
+	/* Interrupt on end of transfer for destination */
+	dst |= BIT(D40_SREG_CFG_TIM_POS);
 
-		/* PSIZE */
-		if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) {
-			src |= 1 << D40_SREG_CFG_PHY_PEN_POS;
-			src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS;
-		}
-		if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) {
-			dst |= 1 << D40_SREG_CFG_PHY_PEN_POS;
-			dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS;
-		}
+	/* Generate interrupt on error */
+	src |= BIT(D40_SREG_CFG_EIM_POS);
+	dst |= BIT(D40_SREG_CFG_EIM_POS);
 
-		/* Element size */
-		src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS;
-		dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS;
+	/* PSIZE */
+	if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) {
+		src |= BIT(D40_SREG_CFG_PHY_PEN_POS);
+		src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS;
+	}
+	if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) {
+		dst |= BIT(D40_SREG_CFG_PHY_PEN_POS);
+		dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS;
+	}
 
-		/* Set the priority bit to high for the physical channel */
-		if (cfg->high_priority) {
-			src |= 1 << D40_SREG_CFG_PRI_POS;
-			dst |= 1 << D40_SREG_CFG_PRI_POS;
-		}
+	/* Element size */
+	src |= d40_width_to_bits(cfg->src_info.data_width)
+		<< D40_SREG_CFG_ESIZE_POS;
+	dst |= d40_width_to_bits(cfg->dst_info.data_width)
+		<< D40_SREG_CFG_ESIZE_POS;
 
-	} else {
-		/* Logical channel */
-		dst |= 1 << D40_SREG_CFG_LOG_GIM_POS;
-		src |= 1 << D40_SREG_CFG_LOG_GIM_POS;
+	/* Set the priority bit to high for the physical channel */
+	if (cfg->high_priority) {
+		src |= BIT(D40_SREG_CFG_PRI_POS);
+		dst |= BIT(D40_SREG_CFG_PRI_POS);
 	}
 
 	if (cfg->src_info.big_endian)
-		src |= 1 << D40_SREG_CFG_LBE_POS;
+		src |= BIT(D40_SREG_CFG_LBE_POS);
 	if (cfg->dst_info.big_endian)
-		dst |= 1 << D40_SREG_CFG_LBE_POS;
+		dst |= BIT(D40_SREG_CFG_LBE_POS);
 
 	*src_cfg = src;
 	*dst_cfg = dst;
@@ -143,23 +149,22 @@ static int d40_phy_fill_lli(struct d40_p
 		num_elems = 2 << psize;
 
 	/* Must be aligned */
-	if (!IS_ALIGNED(data, 0x1 << data_width))
+	if (!IS_ALIGNED(data, data_width))
 		return -EINVAL;
 
 	/* Transfer size can't be smaller than (num_elms * elem_size) */
-	if (data_size < num_elems * (0x1 << data_width))
+	if (data_size < num_elems * data_width)
 		return -EINVAL;
 
 	/* The number of elements. IE now many chunks */
-	lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS;
+	lli->reg_elt = (data_size / data_width) << D40_SREG_ELEM_PHY_ECNT_POS;
 
 	/*
 	 * Distance to next element sized entry.
 	 * Usually the size of the element unless you want gaps.
 	 */
 	if (addr_inc)
-		lli->reg_elt |= (0x1 << data_width) <<
-			D40_SREG_ELEM_PHY_EIDX_POS;
+		lli->reg_elt |= data_width << D40_SREG_ELEM_PHY_EIDX_POS;
 
 	/* Where the data is */
 	lli->reg_ptr = data;
@@ -167,18 +172,20 @@ static int d40_phy_fill_lli(struct d40_p
 
 	/* If this scatter list entry is the last one, no next link */
 	if (next_lli == 0)
-		lli->reg_lnk = 0x1 << D40_SREG_LNK_PHY_TCP_POS;
+		lli->reg_lnk = BIT(D40_SREG_LNK_PHY_TCP_POS);
 	else
 		lli->reg_lnk = next_lli;
 
 	/* Set/clear interrupt generation on this link item.*/
 	if (term_int)
-		lli->reg_cfg |= 0x1 << D40_SREG_CFG_TIM_POS;
+		lli->reg_cfg |= BIT(D40_SREG_CFG_TIM_POS);
 	else
-		lli->reg_cfg &= ~(0x1 << D40_SREG_CFG_TIM_POS);
+		lli->reg_cfg &= ~BIT(D40_SREG_CFG_TIM_POS);
 
-	/* Post link */
-	lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS;
+	/*
+	 * Post link - D40_SREG_LNK_PHY_PRE_POS = 0
+	 * Relink happens after transfer completion.
+	 */
 
 	return 0;
 }
@@ -187,16 +194,16 @@ static int d40_seg_size(int size, int da
 {
 	u32 max_w = max(data_width1, data_width2);
 	u32 min_w = min(data_width1, data_width2);
-	u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE << min_w, 1 << max_w);
+	u32 seg_max = ALIGN(STEDMA40_MAX_SEG_SIZE * min_w, max_w);
 
 	if (seg_max > STEDMA40_MAX_SEG_SIZE)
-		seg_max -= (1 << max_w);
+		seg_max -= max_w;
 
 	if (size <= seg_max)
 		return size;
 
 	if (size <= 2 * seg_max)
-		return ALIGN(size / 2, 1 << max_w);
+		return ALIGN(size / 2, max_w);
 
 	return seg_max;
 }
@@ -362,10 +369,10 @@ static void d40_log_fill_lli(struct d40_
 	lli->lcsp13 = reg_cfg;
 
 	/* The number of elements to transfer */
-	lli->lcsp02 = ((data_size >> data_width) <<
+	lli->lcsp02 = ((data_size / data_width) <<
 		       D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK;
 
-	BUG_ON((data_size >> data_width) > STEDMA40_MAX_SEG_SIZE);
+	BUG_ON((data_size / data_width) > STEDMA40_MAX_SEG_SIZE);
 
 	/* 16 LSBs address of the current element */
 	lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/ste_dma40_ll.h linux-libre-3.11-rc7-gnu/drivers/dma/ste_dma40_ll.h
--- linux-libre-3.10-gnu/drivers/dma/ste_dma40_ll.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/ste_dma40_ll.h	2013-08-25 20:43:22.000000000 -0400
@@ -432,8 +432,7 @@ enum d40_lli_flags {
 
 void d40_phy_cfg(struct stedma40_chan_cfg *cfg,
 		 u32 *src_cfg,
-		 u32 *dst_cfg,
-		 bool is_log);
+		 u32 *dst_cfg);
 
 void d40_log_cfg(struct stedma40_chan_cfg *cfg,
 		 u32 *lcsp1,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/tegra20-apb-dma.c linux-libre-3.11-rc7-gnu/drivers/dma/tegra20-apb-dma.c
--- linux-libre-3.10-gnu/drivers/dma/tegra20-apb-dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/tegra20-apb-dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -1191,6 +1191,7 @@ static void tegra_dma_free_chan_resource
 	list_splice_init(&tdc->free_dma_desc, &dma_desc_list);
 	INIT_LIST_HEAD(&tdc->cb_desc);
 	tdc->config_init = false;
+	tdc->isr_handler = NULL;
 	spin_unlock_irqrestore(&tdc->lock, flags);
 
 	while (!list_empty(&dma_desc_list)) {
@@ -1334,7 +1335,7 @@ static int tegra_dma_probe(struct platfo
 		if (ret) {
 			dev_err(&pdev->dev,
 				"request_irq failed with err %d channel %d\n",
-				i, ret);
+				ret, i);
 			goto err_irq;
 		}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/dma/timb_dma.c linux-libre-3.11-rc7-gnu/drivers/dma/timb_dma.c
--- linux-libre-3.10-gnu/drivers/dma/timb_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/dma/timb_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -811,8 +811,6 @@ static int td_remove(struct platform_dev
 	kfree(td);
 	release_mem_region(iomem->start, resource_size(iomem));
 
-	platform_set_drvdata(pdev, NULL);
-
 	dev_dbg(&pdev->dev, "Removed...\n");
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/edac/amd64_edac_inj.c linux-libre-3.11-rc7-gnu/drivers/edac/amd64_edac_inj.c
--- linux-libre-3.10-gnu/drivers/edac/amd64_edac_inj.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/edac/amd64_edac_inj.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@ static ssize_t amd64_inject_section_stor
 	unsigned long value;
 	int ret;
 
-	ret = strict_strtoul(data, 10, &value);
+	ret = kstrtoul(data, 10, &value);
 	if (ret < 0)
 		return ret;
 
@@ -61,7 +61,7 @@ static ssize_t amd64_inject_word_store(s
 	unsigned long value;
 	int ret;
 
-	ret = strict_strtoul(data, 10, &value);
+	ret = kstrtoul(data, 10, &value);
 	if (ret < 0)
 		return ret;
 
@@ -97,7 +97,7 @@ static ssize_t amd64_inject_ecc_vector_s
 	unsigned long value;
 	int ret;
 
-	ret = strict_strtoul(data, 16, &value);
+	ret = kstrtoul(data, 16, &value);
 	if (ret < 0)
 		return ret;
 
@@ -124,7 +124,7 @@ static ssize_t amd64_inject_read_store(s
 	u32 section, word_bits;
 	int ret;
 
-	ret = strict_strtoul(data, 10, &value);
+	ret = kstrtoul(data, 10, &value);
 	if (ret < 0)
 		return ret;
 
@@ -157,7 +157,7 @@ static ssize_t amd64_inject_write_store(
 	unsigned long value;
 	int ret;
 
-	ret = strict_strtoul(data, 10, &value);
+	ret = kstrtoul(data, 10, &value);
 	if (ret < 0)
 		return ret;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/edac/edac_mc.c linux-libre-3.11-rc7-gnu/drivers/edac/edac_mc.c
--- linux-libre-3.10-gnu/drivers/edac/edac_mc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/edac/edac_mc.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,6 +48,8 @@ static LIST_HEAD(mc_devices);
  */
 static void const *edac_mc_owner;
 
+static struct bus_type mc_bus[EDAC_MAX_MCS];
+
 unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
 			         unsigned len)
 {
@@ -723,6 +725,11 @@ int edac_mc_add_mc(struct mem_ctl_info *
 	int ret = -EINVAL;
 	edac_dbg(0, "\n");
 
+	if (mci->mc_idx >= EDAC_MAX_MCS) {
+		pr_warn_once("Too many memory controllers: %d\n", mci->mc_idx);
+		return -ENODEV;
+	}
+
 #ifdef CONFIG_EDAC_DEBUG
 	if (edac_debug_level >= 3)
 		edac_mc_dump_mci(mci);
@@ -762,6 +769,8 @@ int edac_mc_add_mc(struct mem_ctl_info *
 	/* set load time so that error rate can be tracked */
 	mci->start_time = jiffies;
 
+	mci->bus = &mc_bus[mci->mc_idx];
+
 	if (edac_create_sysfs_mci_device(mci)) {
 		edac_mc_printk(mci, KERN_WARNING,
 			"failed to create sysfs device\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/edac/edac_mc_sysfs.c linux-libre-3.11-rc7-gnu/drivers/edac/edac_mc_sysfs.c
--- linux-libre-3.10-gnu/drivers/edac/edac_mc_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/edac/edac_mc_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -370,7 +370,7 @@ static int edac_create_csrow_object(stru
 		return -ENODEV;
 
 	csrow->dev.type = &csrow_attr_type;
-	csrow->dev.bus = &mci->bus;
+	csrow->dev.bus = mci->bus;
 	device_initialize(&csrow->dev);
 	csrow->dev.parent = &mci->dev;
 	csrow->mci = mci;
@@ -605,7 +605,7 @@ static int edac_create_dimm_object(struc
 	dimm->mci = mci;
 
 	dimm->dev.type = &dimm_attr_type;
-	dimm->dev.bus = &mci->bus;
+	dimm->dev.bus = mci->bus;
 	device_initialize(&dimm->dev);
 
 	dimm->dev.parent = &mci->dev;
@@ -678,7 +678,7 @@ static ssize_t mci_sdram_scrub_rate_stor
 	unsigned long bandwidth = 0;
 	int new_bw = 0;
 
-	if (strict_strtoul(data, 10, &bandwidth) < 0)
+	if (kstrtoul(data, 10, &bandwidth) < 0)
 		return -EINVAL;
 
 	new_bw = mci->set_sdram_scrub_rate(mci, bandwidth);
@@ -975,11 +975,13 @@ int edac_create_sysfs_mci_device(struct
 	 * The memory controller needs its own bus, in order to avoid
 	 * namespace conflicts at /sys/bus/edac.
 	 */
-	mci->bus.name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
-	if (!mci->bus.name)
+	mci->bus->name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
+	if (!mci->bus->name)
 		return -ENOMEM;
-	edac_dbg(0, "creating bus %s\n", mci->bus.name);
-	err = bus_register(&mci->bus);
+
+	edac_dbg(0, "creating bus %s\n", mci->bus->name);
+
+	err = bus_register(mci->bus);
 	if (err < 0)
 		return err;
 
@@ -988,7 +990,7 @@ int edac_create_sysfs_mci_device(struct
 	device_initialize(&mci->dev);
 
 	mci->dev.parent = mci_pdev;
-	mci->dev.bus = &mci->bus;
+	mci->dev.bus = mci->bus;
 	dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
 	dev_set_drvdata(&mci->dev, mci);
 	pm_runtime_forbid(&mci->dev);
@@ -997,8 +999,8 @@ int edac_create_sysfs_mci_device(struct
 	err = device_add(&mci->dev);
 	if (err < 0) {
 		edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev));
-		bus_unregister(&mci->bus);
-		kfree(mci->bus.name);
+		bus_unregister(mci->bus);
+		kfree(mci->bus->name);
 		return err;
 	}
 
@@ -1064,8 +1066,8 @@ fail:
 	}
 fail2:
 	device_unregister(&mci->dev);
-	bus_unregister(&mci->bus);
-	kfree(mci->bus.name);
+	bus_unregister(mci->bus);
+	kfree(mci->bus->name);
 	return err;
 }
 
@@ -1098,8 +1100,8 @@ void edac_unregister_sysfs(struct mem_ct
 {
 	edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev));
 	device_unregister(&mci->dev);
-	bus_unregister(&mci->bus);
-	kfree(mci->bus.name);
+	bus_unregister(mci->bus);
+	kfree(mci->bus->name);
 }
 
 static void mc_attr_release(struct device *dev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/edac/i5100_edac.c linux-libre-3.11-rc7-gnu/drivers/edac/i5100_edac.c
--- linux-libre-3.10-gnu/drivers/edac/i5100_edac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/edac/i5100_edac.c	2013-08-25 20:43:22.000000000 -0400
@@ -974,7 +974,7 @@ static int i5100_setup_debugfs(struct me
 	if (!i5100_debugfs)
 		return -ENODEV;
 
-	priv->debugfs = debugfs_create_dir(mci->bus.name, i5100_debugfs);
+	priv->debugfs = debugfs_create_dir(mci->bus->name, i5100_debugfs);
 
 	if (!priv->debugfs)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/edac/i7core_edac.c linux-libre-3.11-rc7-gnu/drivers/edac/i7core_edac.c
--- linux-libre-3.10-gnu/drivers/edac/i7core_edac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/edac/i7core_edac.c	2013-08-25 20:43:22.000000000 -0400
@@ -704,7 +704,7 @@ static ssize_t i7core_inject_section_sto
 	if (pvt->inject.enable)
 		disable_inject(mci);
 
-	rc = strict_strtoul(data, 10, &value);
+	rc = kstrtoul(data, 10, &value);
 	if ((rc < 0) || (value > 3))
 		return -EIO;
 
@@ -741,7 +741,7 @@ struct i7core_pvt *pvt = mci->pvt_info;
 	if (pvt->inject.enable)
 		disable_inject(mci);
 
-	rc = strict_strtoul(data, 10, &value);
+	rc = kstrtoul(data, 10, &value);
 	if ((rc < 0) || (value > 7))
 		return -EIO;
 
@@ -781,7 +781,7 @@ static ssize_t i7core_inject_eccmask_sto
 	if (pvt->inject.enable)
 		disable_inject(mci);
 
-	rc = strict_strtoul(data, 10, &value);
+	rc = kstrtoul(data, 10, &value);
 	if (rc < 0)
 		return -EIO;
 
@@ -830,7 +830,7 @@ static ssize_t i7core_inject_store_##par
 	if (!strcasecmp(data, "any") || !strcasecmp(data, "any\n"))\
 		value = -1;					\
 	else {							\
-		rc = strict_strtoul(data, 10, &value);		\
+		rc = kstrtoul(data, 10, &value);		\
 		if ((rc < 0) || (value >= limit))		\
 			return -EIO;				\
 	}							\
@@ -934,7 +934,7 @@ static ssize_t i7core_inject_enable_stor
 	if (!pvt->pci_ch[pvt->inject.channel][0])
 		return 0;
 
-	rc = strict_strtoul(data, 10, &enable);
+	rc = kstrtoul(data, 10, &enable);
 	if ((rc < 0))
 		return 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/edac/Kconfig linux-libre-3.11-rc7-gnu/drivers/edac/Kconfig
--- linux-libre-3.10-gnu/drivers/edac/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/edac/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -145,7 +145,7 @@ config EDAC_E7XXX
 
 config EDAC_E752X
 	tristate "Intel e752x (e7520, e7525, e7320) and 3100"
-	depends on EDAC_MM_EDAC && PCI && X86 && HOTPLUG
+	depends on EDAC_MM_EDAC && PCI && X86
 	help
 	  Support for error detection and correction on the Intel
 	  E7520, E7525, E7320 server chipsets.
@@ -349,21 +349,21 @@ config EDAC_OCTEON_PC
 
 config EDAC_OCTEON_L2C
 	tristate "Cavium Octeon Secondary Caches (L2C)"
-	depends on EDAC_MM_EDAC && CPU_CAVIUM_OCTEON
+	depends on EDAC_MM_EDAC && CAVIUM_OCTEON_SOC
 	help
 	  Support for error detection and correction on the
 	  Cavium Octeon family of SOCs.
 
 config EDAC_OCTEON_LMC
 	tristate "Cavium Octeon DRAM Memory Controller (LMC)"
-	depends on EDAC_MM_EDAC && CPU_CAVIUM_OCTEON
+	depends on EDAC_MM_EDAC && CAVIUM_OCTEON_SOC
 	help
 	  Support for error detection and correction on the
 	  Cavium Octeon family of SOCs.
 
 config EDAC_OCTEON_PCI
 	tristate "Cavium Octeon PCI Controller"
-	depends on EDAC_MM_EDAC && PCI && CPU_CAVIUM_OCTEON
+	depends on EDAC_MM_EDAC && PCI && CAVIUM_OCTEON_SOC
 	help
 	  Support for error detection and correction on the
 	  Cavium Octeon family of SOCs.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/edac/mce_amd.c linux-libre-3.11-rc7-gnu/drivers/edac/mce_amd.c
--- linux-libre-3.10-gnu/drivers/edac/mce_amd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/edac/mce_amd.c	2013-08-25 20:43:22.000000000 -0400
@@ -134,7 +134,8 @@ static const char * const mc5_mce_desc[]
 	"Physical register file AG0 port",
 	"Physical register file AG1 port",
 	"Flag register file",
-	"DE error occurred"
+	"DE error occurred",
+	"Retire status queue"
 };
 
 static bool f12h_mc0_mce(u16 ec, u8 xec)
@@ -624,7 +625,7 @@ static void decode_mc5_mce(struct mce *m
 
 	if (xec == 0x0 || xec == 0xc)
 		pr_cont("%s.\n", mc5_mce_desc[xec]);
-	else if (xec < 0xd)
+	else if (xec <= 0xd)
 		pr_cont("%s parity error.\n", mc5_mce_desc[xec]);
 	else
 		goto wrong_mc5_mce;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/edac/mce_amd_inj.c linux-libre-3.11-rc7-gnu/drivers/edac/mce_amd_inj.c
--- linux-libre-3.10-gnu/drivers/edac/mce_amd_inj.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/edac/mce_amd_inj.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,7 +43,7 @@ static ssize_t edac_inject_##reg##_store
 	int ret = 0;							\
 	unsigned long value;						\
 									\
-	ret = strict_strtoul(data, 16, &value);				\
+	ret = kstrtoul(data, 16, &value);				\
 	if (ret < 0)							\
 		printk(KERN_ERR "Error writing MCE " #reg " field.\n");	\
 									\
@@ -83,7 +83,7 @@ static ssize_t edac_inject_bank_store(st
 	int ret = 0;
 	unsigned long value;
 
-	ret = strict_strtoul(data, 10, &value);
+	ret = kstrtoul(data, 10, &value);
 	if (ret < 0) {
 		printk(KERN_ERR "Invalid bank value!\n");
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/extcon/extcon-class.c linux-libre-3.11-rc7-gnu/drivers/extcon/extcon-class.c
--- linux-libre-3.10-gnu/drivers/extcon/extcon-class.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/extcon/extcon-class.c	2013-08-25 20:43:22.000000000 -0400
@@ -185,26 +185,6 @@ static ssize_t cable_state_show(struct d
 					       cable->cable_index));
 }
 
-static ssize_t cable_state_store(struct device *dev,
-				 struct device_attribute *attr, const char *buf,
-				 size_t count)
-{
-	struct extcon_cable *cable = container_of(attr, struct extcon_cable,
-						  attr_state);
-	int ret, state;
-
-	ret = sscanf(buf, "%d", &state);
-	if (ret == 0)
-		ret = -EINVAL;
-	else
-		ret = extcon_set_cable_state_(cable->edev, cable->cable_index,
-					      state);
-
-	if (ret < 0)
-		return ret;
-	return count;
-}
-
 /**
  * extcon_update_state() - Update the cable attach states of the extcon device
  *			only for the masked bits.
@@ -501,6 +481,7 @@ int extcon_register_interest(struct extc
 		return -ENODEV;
 	}
 }
+EXPORT_SYMBOL_GPL(extcon_register_interest);
 
 /**
  * extcon_unregister_interest() - Unregister the notifier registered by
@@ -515,6 +496,7 @@ int extcon_unregister_interest(struct ex
 
 	return raw_notifier_chain_unregister(&obj->edev->nh, &obj->internal_nb);
 }
+EXPORT_SYMBOL_GPL(extcon_unregister_interest);
 
 /**
  * extcon_register_notifier() - Register a notifiee to get notified by
@@ -620,7 +602,7 @@ int extcon_dev_register(struct extcon_de
 	edev->dev->class = extcon_class;
 	edev->dev->release = extcon_dev_release;
 
-	dev_set_name(edev->dev, edev->name ? edev->name : dev_name(dev));
+	dev_set_name(edev->dev, "%s", edev->name ? edev->name : dev_name(dev));
 
 	if (edev->max_supported) {
 		char buf[10];
@@ -665,9 +647,8 @@ int extcon_dev_register(struct extcon_de
 
 			sysfs_attr_init(&cable->attr_state.attr);
 			cable->attr_state.attr.name = "state";
-			cable->attr_state.attr.mode = 0644;
+			cable->attr_state.attr.mode = 0444;
 			cable->attr_state.show = cable_state_show;
-			cable->attr_state.store = cable_state_store;
 		}
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/extcon/extcon-palmas.c linux-libre-3.11-rc7-gnu/drivers/extcon/extcon-palmas.c
--- linux-libre-3.10-gnu/drivers/extcon/extcon-palmas.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/extcon/extcon-palmas.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,246 @@
+/*
+ * Palmas USB transceiver driver
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Author: Graeme Gregory <gg@slimlogic.co.uk>
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * Based on twl6030_usb.c
+ *
+ * Author: Hema HK <hemahk@ti.com>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/mfd/palmas.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+static const char *palmas_extcon_cable[] = {
+	[0] = "USB",
+	[1] = "USB-HOST",
+	NULL,
+};
+
+static const int mutually_exclusive[] = {0x3, 0x0};
+
+static void palmas_usb_wakeup(struct palmas *palmas, int enable)
+{
+	if (enable)
+		palmas_write(palmas, PALMAS_USB_OTG_BASE, PALMAS_USB_WAKEUP,
+			PALMAS_USB_WAKEUP_ID_WK_UP_COMP);
+	else
+		palmas_write(palmas, PALMAS_USB_OTG_BASE, PALMAS_USB_WAKEUP, 0);
+}
+
+static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb)
+{
+	struct palmas_usb *palmas_usb = _palmas_usb;
+	unsigned int vbus_line_state;
+
+	palmas_read(palmas_usb->palmas, PALMAS_INTERRUPT_BASE,
+		PALMAS_INT3_LINE_STATE, &vbus_line_state);
+
+	if (vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS) {
+		if (palmas_usb->linkstat != PALMAS_USB_STATE_VBUS) {
+			palmas_usb->linkstat = PALMAS_USB_STATE_VBUS;
+			extcon_set_cable_state(&palmas_usb->edev, "USB", true);
+		} else {
+			dev_dbg(palmas_usb->dev,
+				"Spurious connect event detected\n");
+		}
+	} else if (!(vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS)) {
+		if (palmas_usb->linkstat == PALMAS_USB_STATE_VBUS) {
+			palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
+			extcon_set_cable_state(&palmas_usb->edev, "USB", false);
+		} else {
+			dev_dbg(palmas_usb->dev,
+				"Spurious disconnect event detected\n");
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb)
+{
+	unsigned int set;
+	struct palmas_usb *palmas_usb = _palmas_usb;
+
+	palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+		PALMAS_USB_ID_INT_LATCH_SET, &set);
+
+	if (set & PALMAS_USB_ID_INT_SRC_ID_GND) {
+		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+			PALMAS_USB_ID_INT_EN_HI_SET,
+			PALMAS_USB_ID_INT_EN_HI_SET_ID_FLOAT);
+		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+			PALMAS_USB_ID_INT_EN_HI_CLR,
+			PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND);
+		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+			PALMAS_USB_ID_INT_LATCH_CLR,
+			PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND);
+		palmas_usb->linkstat = PALMAS_USB_STATE_ID;
+		extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true);
+	} else if (set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) {
+		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+			PALMAS_USB_ID_INT_EN_HI_SET,
+			PALMAS_USB_ID_INT_EN_HI_SET_ID_GND);
+		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+			PALMAS_USB_ID_INT_EN_HI_CLR,
+			PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT);
+		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+			PALMAS_USB_ID_INT_LATCH_CLR,
+			PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT);
+		palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
+		extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", false);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void palmas_enable_irq(struct palmas_usb *palmas_usb)
+{
+	palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+		PALMAS_USB_VBUS_CTRL_SET,
+		PALMAS_USB_VBUS_CTRL_SET_VBUS_ACT_COMP);
+
+	palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+		PALMAS_USB_ID_CTRL_SET, PALMAS_USB_ID_CTRL_SET_ID_ACT_COMP);
+
+	palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
+		PALMAS_USB_ID_INT_EN_HI_SET,
+		PALMAS_USB_ID_INT_EN_HI_SET_ID_GND);
+
+	palmas_vbus_irq_handler(palmas_usb->vbus_irq, palmas_usb);
+
+	/* cold plug for host mode needs this delay */
+	msleep(30);
+	palmas_id_irq_handler(palmas_usb->id_irq, palmas_usb);
+}
+
+static int palmas_usb_probe(struct platform_device *pdev)
+{
+	struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
+	struct palmas_usb_platform_data	*pdata = pdev->dev.platform_data;
+	struct device_node *node = pdev->dev.of_node;
+	struct palmas_usb *palmas_usb;
+	int status;
+
+	if (node && !pdata) {
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+
+		if (!pdata)
+			return -ENOMEM;
+
+		pdata->wakeup = of_property_read_bool(node, "ti,wakeup");
+	} else if (!pdata) {
+		return -EINVAL;
+	}
+
+	palmas_usb = devm_kzalloc(&pdev->dev, sizeof(*palmas_usb), GFP_KERNEL);
+	if (!palmas_usb)
+		return -ENOMEM;
+
+	palmas->usb = palmas_usb;
+	palmas_usb->palmas = palmas;
+
+	palmas_usb->dev	 = &pdev->dev;
+
+	palmas_usb->id_otg_irq = regmap_irq_get_virq(palmas->irq_data,
+						PALMAS_ID_OTG_IRQ);
+	palmas_usb->id_irq = regmap_irq_get_virq(palmas->irq_data,
+						PALMAS_ID_IRQ);
+	palmas_usb->vbus_otg_irq = regmap_irq_get_virq(palmas->irq_data,
+						PALMAS_VBUS_OTG_IRQ);
+	palmas_usb->vbus_irq = regmap_irq_get_virq(palmas->irq_data,
+						PALMAS_VBUS_IRQ);
+
+	palmas_usb_wakeup(palmas, pdata->wakeup);
+
+	platform_set_drvdata(pdev, palmas_usb);
+
+	palmas_usb->edev.name = "palmas-usb";
+	palmas_usb->edev.supported_cable = palmas_extcon_cable;
+	palmas_usb->edev.mutually_exclusive = mutually_exclusive;
+
+	status = extcon_dev_register(&palmas_usb->edev, palmas_usb->dev);
+	if (status) {
+		dev_err(&pdev->dev, "failed to register extcon device\n");
+		return status;
+	}
+
+	status = devm_request_threaded_irq(palmas_usb->dev, palmas_usb->id_irq,
+			NULL, palmas_id_irq_handler,
+			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			"palmas_usb_id", palmas_usb);
+	if (status < 0) {
+		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
+					palmas_usb->id_irq, status);
+		goto fail_extcon;
+	}
+
+	status = devm_request_threaded_irq(palmas_usb->dev,
+			palmas_usb->vbus_irq, NULL, palmas_vbus_irq_handler,
+			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			"palmas_usb_vbus", palmas_usb);
+	if (status < 0) {
+		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
+					palmas_usb->vbus_irq, status);
+		goto fail_extcon;
+	}
+
+	palmas_enable_irq(palmas_usb);
+
+	return 0;
+
+fail_extcon:
+	extcon_dev_unregister(&palmas_usb->edev);
+
+	return status;
+}
+
+static int palmas_usb_remove(struct platform_device *pdev)
+{
+	struct palmas_usb *palmas_usb = platform_get_drvdata(pdev);
+
+	extcon_dev_unregister(&palmas_usb->edev);
+
+	return 0;
+}
+
+static struct of_device_id of_palmas_match_tbl[] = {
+	{ .compatible = "ti,palmas-usb", },
+	{ .compatible = "ti,twl6035-usb", },
+	{ /* end */ }
+};
+
+static struct platform_driver palmas_usb_driver = {
+	.probe = palmas_usb_probe,
+	.remove = palmas_usb_remove,
+	.driver = {
+		.name = "palmas-usb",
+		.of_match_table = of_palmas_match_tbl,
+		.owner = THIS_MODULE,
+	},
+};
+
+module_platform_driver(palmas_usb_driver);
+
+MODULE_ALIAS("platform:palmas-usb");
+MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
+MODULE_DESCRIPTION("Palmas USB transceiver driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/extcon/Kconfig linux-libre-3.11-rc7-gnu/drivers/extcon/Kconfig
--- linux-libre-3.10-gnu/drivers/extcon/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/extcon/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -53,4 +53,11 @@ config EXTCON_ARIZONA
 	  with Wolfson Arizona devices. These are audio CODECs with
 	  advanced audio accessory detection support.
 
+config EXTCON_PALMAS
+	tristate "Palmas USB EXTCON support"
+	depends on MFD_PALMAS
+	help
+	  Say Y here to enable support for USB peripheral and USB host
+	  detection by palmas usb.
+
 endif # MULTISTATE_SWITCH
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/extcon/Makefile linux-libre-3.11-rc7-gnu/drivers/extcon/Makefile
--- linux-libre-3.10-gnu/drivers/extcon/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/extcon/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -8,3 +8,4 @@ obj-$(CONFIG_EXTCON_ADC_JACK)	+= extcon-
 obj-$(CONFIG_EXTCON_MAX77693)	+= extcon-max77693.o
 obj-$(CONFIG_EXTCON_MAX8997)	+= extcon-max8997.o
 obj-$(CONFIG_EXTCON_ARIZONA)	+= extcon-arizona.o
+obj-$(CONFIG_EXTCON_PALMAS)	+= extcon-palmas.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/firewire/core-cdev.c linux-libre-3.11-rc7-gnu/drivers/firewire/core-cdev.c
--- linux-libre-3.10-gnu/drivers/firewire/core-cdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/firewire/core-cdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,6 +54,7 @@
 #define FW_CDEV_KERNEL_VERSION			5
 #define FW_CDEV_VERSION_EVENT_REQUEST2		4
 #define FW_CDEV_VERSION_ALLOCATE_REGION_END	4
+#define FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW	5
 
 struct client {
 	u32 version;
@@ -1005,6 +1006,8 @@ static int ioctl_create_iso_context(stru
 			a->channel, a->speed, a->header_size, cb, client);
 	if (IS_ERR(context))
 		return PTR_ERR(context);
+	if (client->version < FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW)
+		context->drop_overflow_headers = true;
 
 	/* We only support one context at this time. */
 	spin_lock_irq(&client->lock);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/firewire/core-device.c linux-libre-3.11-rc7-gnu/drivers/firewire/core-device.c
--- linux-libre-3.10-gnu/drivers/firewire/core-device.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/firewire/core-device.c	2013-08-25 20:43:22.000000000 -0400
@@ -165,25 +165,44 @@ static bool match_ids(const struct ieee1
 	return (match & id_table->match_flags) == id_table->match_flags;
 }
 
-static bool is_fw_unit(struct device *dev);
-
-static int fw_unit_match(struct device *dev, struct device_driver *drv)
+static const struct ieee1394_device_id *unit_match(struct device *dev,
+						   struct device_driver *drv)
 {
 	const struct ieee1394_device_id *id_table =
 			container_of(drv, struct fw_driver, driver)->id_table;
 	int id[] = {0, 0, 0, 0};
 
-	/* We only allow binding to fw_units. */
-	if (!is_fw_unit(dev))
-		return 0;
-
 	get_modalias_ids(fw_unit(dev), id);
 
 	for (; id_table->match_flags != 0; id_table++)
 		if (match_ids(id_table, id))
-			return 1;
+			return id_table;
 
-	return 0;
+	return NULL;
+}
+
+static bool is_fw_unit(struct device *dev);
+
+static int fw_unit_match(struct device *dev, struct device_driver *drv)
+{
+	/* We only allow binding to fw_units. */
+	return is_fw_unit(dev) && unit_match(dev, drv) != NULL;
+}
+
+static int fw_unit_probe(struct device *dev)
+{
+	struct fw_driver *driver =
+			container_of(dev->driver, struct fw_driver, driver);
+
+	return driver->probe(fw_unit(dev), unit_match(dev, dev->driver));
+}
+
+static int fw_unit_remove(struct device *dev)
+{
+	struct fw_driver *driver =
+			container_of(dev->driver, struct fw_driver, driver);
+
+	return driver->remove(fw_unit(dev)), 0;
 }
 
 static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
@@ -213,6 +232,8 @@ static int fw_unit_uevent(struct device
 struct bus_type fw_bus_type = {
 	.name = "firewire",
 	.match = fw_unit_match,
+	.probe = fw_unit_probe,
+	.remove = fw_unit_remove,
 };
 EXPORT_SYMBOL(fw_bus_type);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/firewire/net.c linux-libre-3.11-rc7-gnu/drivers/firewire/net.c
--- linux-libre-3.10-gnu/drivers/firewire/net.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/firewire/net.c	2013-08-25 20:43:22.000000000 -0400
@@ -1440,9 +1440,9 @@ static int fwnet_add_peer(struct fwnet_d
 	return 0;
 }
 
-static int fwnet_probe(struct device *_dev)
+static int fwnet_probe(struct fw_unit *unit,
+		       const struct ieee1394_device_id *id)
 {
-	struct fw_unit *unit = fw_unit(_dev);
 	struct fw_device *device = fw_parent_device(unit);
 	struct fw_card *card = device->card;
 	struct net_device *net;
@@ -1526,6 +1526,24 @@ static int fwnet_probe(struct device *_d
 	return ret;
 }
 
+/*
+ * FIXME abort partially sent fragmented datagrams,
+ * discard partially received fragmented datagrams
+ */
+static void fwnet_update(struct fw_unit *unit)
+{
+	struct fw_device *device = fw_parent_device(unit);
+	struct fwnet_peer *peer = dev_get_drvdata(&unit->device);
+	int generation;
+
+	generation = device->generation;
+
+	spin_lock_irq(&peer->dev->lock);
+	peer->node_id    = device->node_id;
+	peer->generation = generation;
+	spin_unlock_irq(&peer->dev->lock);
+}
+
 static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
 {
 	struct fwnet_partial_datagram *pd, *pd_next;
@@ -1542,9 +1560,9 @@ static void fwnet_remove_peer(struct fwn
 	kfree(peer);
 }
 
-static int fwnet_remove(struct device *_dev)
+static void fwnet_remove(struct fw_unit *unit)
 {
-	struct fwnet_peer *peer = dev_get_drvdata(_dev);
+	struct fwnet_peer *peer = dev_get_drvdata(&unit->device);
 	struct fwnet_device *dev = peer->dev;
 	struct net_device *net;
 	int i;
@@ -1569,26 +1587,6 @@ static int fwnet_remove(struct device *_
 	}
 
 	mutex_unlock(&fwnet_device_mutex);
-
-	return 0;
-}
-
-/*
- * FIXME abort partially sent fragmented datagrams,
- * discard partially received fragmented datagrams
- */
-static void fwnet_update(struct fw_unit *unit)
-{
-	struct fw_device *device = fw_parent_device(unit);
-	struct fwnet_peer *peer = dev_get_drvdata(&unit->device);
-	int generation;
-
-	generation = device->generation;
-
-	spin_lock_irq(&peer->dev->lock);
-	peer->node_id    = device->node_id;
-	peer->generation = generation;
-	spin_unlock_irq(&peer->dev->lock);
 }
 
 static const struct ieee1394_device_id fwnet_id_table[] = {
@@ -1614,10 +1612,10 @@ static struct fw_driver fwnet_driver = {
 		.owner  = THIS_MODULE,
 		.name   = KBUILD_MODNAME,
 		.bus    = &fw_bus_type,
-		.probe  = fwnet_probe,
-		.remove = fwnet_remove,
 	},
+	.probe    = fwnet_probe,
 	.update   = fwnet_update,
+	.remove   = fwnet_remove,
 	.id_table = fwnet_id_table,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/firewire/ohci.c linux-libre-3.11-rc7-gnu/drivers/firewire/ohci.c
--- linux-libre-3.10-gnu/drivers/firewire/ohci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/firewire/ohci.c	2013-08-25 20:43:22.000000000 -0400
@@ -2749,8 +2749,11 @@ static void copy_iso_headers(struct iso_
 {
 	u32 *ctx_hdr;
 
-	if (ctx->header_length + ctx->base.header_size > PAGE_SIZE)
+	if (ctx->header_length + ctx->base.header_size > PAGE_SIZE) {
+		if (ctx->base.drop_overflow_headers)
+			return;
 		flush_iso_completions(ctx);
+	}
 
 	ctx_hdr = ctx->header + ctx->header_length;
 	ctx->last_timestamp = (u16)le32_to_cpu((__force __le32)dma_hdr[0]);
@@ -2910,8 +2913,11 @@ static int handle_it_packet(struct conte
 
 	sync_it_packet_for_cpu(context, d);
 
-	if (ctx->header_length + 4 > PAGE_SIZE)
+	if (ctx->header_length + 4 > PAGE_SIZE) {
+		if (ctx->base.drop_overflow_headers)
+			return 1;
 		flush_iso_completions(ctx);
+	}
 
 	ctx_hdr = ctx->header + ctx->header_length;
 	ctx->last_timestamp = le16_to_cpu(last->res_count);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/firewire/sbp2.c linux-libre-3.11-rc7-gnu/drivers/firewire/sbp2.c
--- linux-libre-3.10-gnu/drivers/firewire/sbp2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/firewire/sbp2.c	2013-08-25 20:43:22.000000000 -0400
@@ -1128,11 +1128,10 @@ static void sbp2_init_workarounds(struct
 }
 
 static struct scsi_host_template scsi_driver_template;
-static int sbp2_remove(struct device *dev);
+static void sbp2_remove(struct fw_unit *unit);
 
-static int sbp2_probe(struct device *dev)
+static int sbp2_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
 {
-	struct fw_unit *unit = fw_unit(dev);
 	struct fw_device *device = fw_parent_device(unit);
 	struct sbp2_target *tgt;
 	struct sbp2_logical_unit *lu;
@@ -1196,7 +1195,7 @@ static int sbp2_probe(struct device *dev
 	return 0;
 
  fail_remove:
-	sbp2_remove(dev);
+	sbp2_remove(unit);
 	return -ENOMEM;
 
  fail_shost_put:
@@ -1222,9 +1221,8 @@ static void sbp2_update(struct fw_unit *
 	}
 }
 
-static int sbp2_remove(struct device *dev)
+static void sbp2_remove(struct fw_unit *unit)
 {
-	struct fw_unit *unit = fw_unit(dev);
 	struct fw_device *device = fw_parent_device(unit);
 	struct sbp2_target *tgt = dev_get_drvdata(&unit->device);
 	struct sbp2_logical_unit *lu, *next;
@@ -1261,10 +1259,9 @@ static int sbp2_remove(struct device *de
 		kfree(lu);
 	}
 	scsi_remove_host(shost);
-	dev_notice(dev, "released target %d:0:0\n", shost->host_no);
+	dev_notice(&unit->device, "released target %d:0:0\n", shost->host_no);
 
 	scsi_host_put(shost);
-	return 0;
 }
 
 #define SBP2_UNIT_SPEC_ID_ENTRY	0x0000609e
@@ -1285,10 +1282,10 @@ static struct fw_driver sbp2_driver = {
 		.owner  = THIS_MODULE,
 		.name   = KBUILD_MODNAME,
 		.bus    = &fw_bus_type,
-		.probe  = sbp2_probe,
-		.remove = sbp2_remove,
 	},
+	.probe    = sbp2_probe,
 	.update   = sbp2_update,
+	.remove   = sbp2_remove,
 	.id_table = sbp2_id_table,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/firmware/dmi_scan.c linux-libre-3.11-rc7-gnu/drivers/firmware/dmi_scan.c
--- linux-libre-3.10-gnu/drivers/firmware/dmi_scan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/firmware/dmi_scan.c	2013-08-25 20:43:22.000000000 -0400
@@ -419,6 +419,13 @@ static void __init dmi_format_ids(char *
 			    dmi_get_system_info(DMI_BIOS_DATE));
 }
 
+/*
+ * Check for DMI/SMBIOS headers in the system firmware image.  Any
+ * SMBIOS header must start 16 bytes before the DMI header, so take a
+ * 32 byte buffer and check for DMI at offset 16 and SMBIOS at offset
+ * 0.  If the DMI header is present, set dmi_ver accordingly (SMBIOS
+ * takes precedence) and return 0.  Otherwise return 1.
+ */
 static int __init dmi_present(const u8 *buf)
 {
 	int smbios_ver;
@@ -506,6 +513,13 @@ void __init dmi_scan_machine(void)
 		if (p == NULL)
 			goto error;
 
+		/*
+		 * Iterate over all possible DMI header addresses q.
+		 * Maintain the 32 bytes around q in buf.  On the
+		 * first iteration, substitute zero for the
+		 * out-of-range bytes so there is no chance of falsely
+		 * detecting an SMBIOS header.
+		 */
 		memset(buf, 0, 16);
 		for (q = p; q < p + 0x10000; q += 16) {
 			memcpy_fromio(buf + 16, q, 16);
@@ -551,9 +565,15 @@ static bool dmi_matches(const struct dmi
 		int s = dmi->matches[i].slot;
 		if (s == DMI_NONE)
 			break;
-		if (dmi_ident[s]
-		    && strstr(dmi_ident[s], dmi->matches[i].substr))
-			continue;
+		if (dmi_ident[s]) {
+			if (!dmi->matches[i].exact_match &&
+			    strstr(dmi_ident[s], dmi->matches[i].substr))
+				continue;
+			else if (dmi->matches[i].exact_match &&
+				 !strcmp(dmi_ident[s], dmi->matches[i].substr))
+				continue;
+		}
+
 		/* No match */
 		return false;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/firmware/efi/efi-pstore.c linux-libre-3.11-rc7-gnu/drivers/firmware/efi/efi-pstore.c
--- linux-libre-3.10-gnu/drivers/firmware/efi/efi-pstore.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/firmware/efi/efi-pstore.c	2013-08-25 20:43:22.000000000 -0400
@@ -79,10 +79,9 @@ static int efi_pstore_read_func(struct e
 			   &entry->var.DataSize, entry->var.Data);
 	size = entry->var.DataSize;
 
-	*cb_data->buf = kmalloc(size, GFP_KERNEL);
+	*cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL);
 	if (*cb_data->buf == NULL)
 		return -ENOMEM;
-	memcpy(*cb_data->buf, entry->var.Data, size);
 	return size;
 }
 
@@ -104,7 +103,7 @@ static ssize_t efi_pstore_read(u64 *id,
 
 static int efi_pstore_write(enum pstore_type_id type,
 		enum kmsg_dump_reason reason, u64 *id,
-		unsigned int part, int count, size_t size,
+		unsigned int part, int count, size_t hsize, size_t size,
 		struct pstore_info *psi)
 {
 	char name[DUMP_NAME_LEN];
@@ -236,7 +235,11 @@ static __init int efivars_pstore_init(vo
 	efi_pstore_info.bufsize = 1024;
 	spin_lock_init(&efi_pstore_info.buf_lock);
 
-	pstore_register(&efi_pstore_info);
+	if (pstore_register(&efi_pstore_info)) {
+		kfree(efi_pstore_info.buf);
+		efi_pstore_info.buf = NULL;
+		efi_pstore_info.bufsize = 0;
+	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/firmware/efi/efivars.c linux-libre-3.11-rc7-gnu/drivers/firmware/efi/efivars.c
--- linux-libre-3.10-gnu/drivers/firmware/efi/efivars.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/firmware/efi/efivars.c	2013-08-25 20:43:22.000000000 -0400
@@ -583,6 +583,9 @@ int efivars_sysfs_init(void)
 	struct kobject *parent_kobj = efivars_kobject();
 	int error = 0;
 
+	if (!efi_enabled(EFI_RUNTIME_SERVICES))
+		return -ENODEV;
+
 	/* No efivars has been registered yet */
 	if (!parent_kobj)
 		return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/firmware/Kconfig linux-libre-3.11-rc7-gnu/drivers/firmware/Kconfig
--- linux-libre-3.10-gnu/drivers/firmware/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/firmware/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -64,6 +64,7 @@ config DELL_RBU
 	tristate "BIOS update support for DELL systems via sysfs"
 	depends on X86
 	select FW_LOADER
+	select FW_LOADER_USER_HELPER
 	help
 	 Say m if you want to have the option of updating the BIOS for your
 	 DELL system. Note you need a Dell OpenManage or Dell Update package (DUP)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/fmc-chardev.c linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-chardev.c
--- linux-libre-3.10-gnu/drivers/fmc/fmc-chardev.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-chardev.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Released according to the GNU GPL, version 2 or any later version.
+ *
+ * This work is part of the White Rabbit project, a research effort led
+ * by CERN, the European Institute for Nuclear Research.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+#include <linux/fmc.h>
+#include <linux/uaccess.h>
+
+static LIST_HEAD(fc_devices);
+static DEFINE_SPINLOCK(fc_lock);
+
+struct fc_instance {
+	struct list_head list;
+	struct fmc_device *fmc;
+	struct miscdevice misc;
+};
+
+/* at open time, we must identify our device */
+static int fc_open(struct inode *ino, struct file *f)
+{
+	struct fmc_device *fmc;
+	struct fc_instance *fc;
+	int minor = iminor(ino);
+
+	list_for_each_entry(fc, &fc_devices, list)
+		if (fc->misc.minor == minor)
+			break;
+	if (fc->misc.minor != minor)
+		return -ENODEV;
+	fmc = fc->fmc;
+	if (try_module_get(fmc->owner) == 0)
+		return -ENODEV;
+
+	f->private_data = fmc;
+	return 0;
+}
+
+static int fc_release(struct inode *ino, struct file *f)
+{
+	struct fmc_device *fmc = f->private_data;
+	module_put(fmc->owner);
+	return 0;
+}
+
+/* read and write are simple after the default llseek has been used */
+static ssize_t fc_read(struct file *f, char __user *buf, size_t count,
+		       loff_t *offp)
+{
+	struct fmc_device *fmc = f->private_data;
+	unsigned long addr;
+	uint32_t val;
+
+	if (count < sizeof(val))
+		return -EINVAL;
+	count = sizeof(val);
+
+	addr = *offp;
+	if (addr > fmc->memlen)
+		return -ESPIPE; /* Illegal seek */
+	val = fmc_readl(fmc, addr);
+	if (copy_to_user(buf, &val, count))
+		return -EFAULT;
+	*offp += count;
+	return count;
+}
+
+static ssize_t fc_write(struct file *f, const char __user *buf, size_t count,
+			loff_t *offp)
+{
+	struct fmc_device *fmc = f->private_data;
+	unsigned long addr;
+	uint32_t val;
+
+	if (count < sizeof(val))
+		return -EINVAL;
+	count = sizeof(val);
+
+	addr = *offp;
+	if (addr > fmc->memlen)
+		return -ESPIPE; /* Illegal seek */
+	if (copy_from_user(&val, buf, count))
+		return -EFAULT;
+	fmc_writel(fmc, val, addr);
+	*offp += count;
+	return count;
+}
+
+static const struct file_operations fc_fops = {
+	.owner = THIS_MODULE,
+	.open = fc_open,
+	.release = fc_release,
+	.llseek = generic_file_llseek,
+	.read = fc_read,
+	.write = fc_write,
+};
+
+
+/* Device part .. */
+static int fc_probe(struct fmc_device *fmc);
+static int fc_remove(struct fmc_device *fmc);
+
+static struct fmc_driver fc_drv = {
+	.version = FMC_VERSION,
+	.driver.name = KBUILD_MODNAME,
+	.probe = fc_probe,
+	.remove = fc_remove,
+	/* no table: we want to match everything */
+};
+
+/* We accept the generic busid parameter */
+FMC_PARAM_BUSID(fc_drv);
+
+/* probe and remove must allocate and release a misc device */
+static int fc_probe(struct fmc_device *fmc)
+{
+	int ret;
+	int index = 0;
+
+	struct fc_instance *fc;
+
+	if (fmc->op->validate)
+		index = fmc->op->validate(fmc, &fc_drv);
+	if (index < 0)
+		return -EINVAL; /* not our device: invalid */
+
+	/* Create a char device: we want to create it anew */
+	fc = kzalloc(sizeof(*fc), GFP_KERNEL);
+	if (!fc)
+		return -ENOMEM;
+	fc->fmc = fmc;
+	fc->misc.minor = MISC_DYNAMIC_MINOR;
+	fc->misc.fops = &fc_fops;
+	fc->misc.name = kstrdup(dev_name(&fmc->dev), GFP_KERNEL);
+
+	spin_lock(&fc_lock);
+	ret = misc_register(&fc->misc);
+	if (ret < 0)
+		goto err_unlock;
+	list_add(&fc->list, &fc_devices);
+	spin_unlock(&fc_lock);
+	dev_info(&fc->fmc->dev, "Created misc device \"%s\"\n",
+		 fc->misc.name);
+	return 0;
+
+err_unlock:
+	spin_unlock(&fc_lock);
+	kfree(fc->misc.name);
+	kfree(fc);
+	return ret;
+}
+
+static int fc_remove(struct fmc_device *fmc)
+{
+	struct fc_instance *fc;
+
+	list_for_each_entry(fc, &fc_devices, list)
+		if (fc->fmc == fmc)
+			break;
+	if (fc->fmc != fmc) {
+		dev_err(&fmc->dev, "remove called but not found\n");
+		return -ENODEV;
+	}
+
+	spin_lock(&fc_lock);
+	list_del(&fc->list);
+	misc_deregister(&fc->misc);
+	kfree(fc->misc.name);
+	kfree(fc);
+	spin_unlock(&fc_lock);
+
+	return 0;
+}
+
+
+static int fc_init(void)
+{
+	int ret;
+
+	ret = fmc_driver_register(&fc_drv);
+	return ret;
+}
+
+static void fc_exit(void)
+{
+	fmc_driver_unregister(&fc_drv);
+}
+
+module_init(fc_init);
+module_exit(fc_exit);
+
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/fmc-core.c linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-core.c
--- linux-libre-3.10-gnu/drivers/fmc/fmc-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Released according to the GNU GPL, version 2 or any later version.
+ *
+ * This work is part of the White Rabbit project, a research effort led
+ * by CERN, the European Institute for Nuclear Research.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/fmc.h>
+
+static int fmc_check_version(unsigned long version, const char *name)
+{
+	if (__FMC_MAJOR(version) != FMC_MAJOR) {
+		pr_err("%s: \"%s\" has wrong major (has %li, expected %i)\n",
+		       __func__, name, __FMC_MAJOR(version), FMC_MAJOR);
+		return -EINVAL;
+	}
+
+	if (__FMC_MINOR(version) != FMC_MINOR)
+		pr_info("%s: \"%s\" has wrong minor (has %li, expected %i)\n",
+		       __func__, name, __FMC_MINOR(version), FMC_MINOR);
+	return 0;
+}
+
+static int fmc_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	/* struct fmc_device *fdev = to_fmc_device(dev); */
+
+	/* FIXME: The MODALIAS */
+	add_uevent_var(env, "MODALIAS=%s", "fmc");
+	return 0;
+}
+
+static int fmc_probe(struct device *dev)
+{
+	struct fmc_driver *fdrv = to_fmc_driver(dev->driver);
+	struct fmc_device *fdev = to_fmc_device(dev);
+
+	return fdrv->probe(fdev);
+}
+
+static int fmc_remove(struct device *dev)
+{
+	struct fmc_driver *fdrv = to_fmc_driver(dev->driver);
+	struct fmc_device *fdev = to_fmc_device(dev);
+
+	return fdrv->remove(fdev);
+}
+
+static void fmc_shutdown(struct device *dev)
+{
+	/* not implemented but mandatory */
+}
+
+static struct bus_type fmc_bus_type = {
+	.name = "fmc",
+	.match = fmc_match,
+	.uevent = fmc_uevent,
+	.probe = fmc_probe,
+	.remove = fmc_remove,
+	.shutdown = fmc_shutdown,
+};
+
+static void fmc_release(struct device *dev)
+{
+	struct fmc_device *fmc = container_of(dev, struct fmc_device, dev);
+
+	kfree(fmc);
+}
+
+/*
+ * The eeprom is exported in sysfs, through a binary attribute
+ */
+
+static ssize_t fmc_read_eeprom(struct file *file, struct kobject *kobj,
+			   struct bin_attribute *bin_attr,
+			   char *buf, loff_t off, size_t count)
+{
+	struct device *dev;
+	struct fmc_device *fmc;
+	int eelen;
+
+	dev = container_of(kobj, struct device, kobj);
+	fmc = container_of(dev, struct fmc_device, dev);
+	eelen = fmc->eeprom_len;
+	if (off > eelen)
+		return -ESPIPE;
+	if (off == eelen)
+		return 0; /* EOF */
+	if (off + count > eelen)
+		count = eelen - off;
+	memcpy(buf, fmc->eeprom + off, count);
+	return count;
+}
+
+static struct bin_attribute fmc_eeprom_attr = {
+	.attr = { .name = "eeprom", .mode = S_IRUGO, },
+	.size = 8192, /* more or less standard */
+	.read = fmc_read_eeprom,
+};
+
+/*
+ * Functions for client modules follow
+ */
+
+int fmc_driver_register(struct fmc_driver *drv)
+{
+	if (fmc_check_version(drv->version, drv->driver.name))
+		return -EINVAL;
+	drv->driver.bus = &fmc_bus_type;
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(fmc_driver_register);
+
+void fmc_driver_unregister(struct fmc_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(fmc_driver_unregister);
+
+/*
+ * When a device set is registered, all eeproms must be read
+ * and all FRUs must be parsed
+ */
+int fmc_device_register_n(struct fmc_device **devs, int n)
+{
+	struct fmc_device *fmc, **devarray;
+	uint32_t device_id;
+	int i, ret = 0;
+
+	if (n < 1)
+		return 0;
+
+	/* Check the version of the first data structure (function prints) */
+	if (fmc_check_version(devs[0]->version, devs[0]->carrier_name))
+		return -EINVAL;
+
+	devarray = kmemdup(devs, n * sizeof(*devs), GFP_KERNEL);
+	if (!devarray)
+		return -ENOMEM;
+
+	/* Make all other checks before continuing, for all devices */
+	for (i = 0; i < n; i++) {
+		fmc = devarray[i];
+		if (!fmc->hwdev) {
+			pr_err("%s: device nr. %i has no hwdev pointer\n",
+			       __func__, i);
+			ret = -EINVAL;
+			break;
+		}
+		if (fmc->flags == FMC_DEVICE_NO_MEZZANINE) {
+			dev_info(fmc->hwdev, "absent mezzanine in slot %d\n",
+				 fmc->slot_id);
+			continue;
+		}
+		if (!fmc->eeprom) {
+			dev_err(fmc->hwdev, "no eeprom provided for slot %i\n",
+				fmc->slot_id);
+			ret = -EINVAL;
+		}
+		if (!fmc->eeprom_addr) {
+			dev_err(fmc->hwdev, "no eeprom_addr for slot %i\n",
+				fmc->slot_id);
+			ret = -EINVAL;
+		}
+		if (!fmc->carrier_name || !fmc->carrier_data ||
+		    !fmc->device_id) {
+			dev_err(fmc->hwdev,
+				"deivce nr %i: carrier name, "
+				"data or dev_id not set\n", i);
+			ret = -EINVAL;
+		}
+		if (ret)
+			break;
+
+	}
+	if (ret) {
+		kfree(devarray);
+		return ret;
+	}
+
+	/* Validation is ok. Now init and register the devices */
+	for (i = 0; i < n; i++) {
+		fmc = devarray[i];
+
+		if (fmc->flags == FMC_DEVICE_NO_MEZZANINE)
+			continue; /* dev_info already done above */
+
+		fmc->nr_slots = n; /* each slot must know how many are there */
+		fmc->devarray = devarray;
+
+		device_initialize(&fmc->dev);
+		fmc->dev.release = fmc_release;
+		fmc->dev.parent = fmc->hwdev;
+
+		/* Fill the identification stuff (may fail) */
+		fmc_fill_id_info(fmc);
+
+		fmc->dev.bus = &fmc_bus_type;
+
+		/* Name from mezzanine info or carrier info. Or 0,1,2.. */
+		device_id = fmc->device_id;
+		if (!fmc->mezzanine_name)
+			dev_set_name(&fmc->dev, "fmc-%04x", device_id);
+		else
+			dev_set_name(&fmc->dev, "%s-%04x", fmc->mezzanine_name,
+				     device_id);
+		ret = device_add(&fmc->dev);
+		if (ret < 0) {
+			dev_err(fmc->hwdev, "Slot %i: Failed in registering "
+				"\"%s\"\n", fmc->slot_id, fmc->dev.kobj.name);
+			goto out;
+		}
+		ret = sysfs_create_bin_file(&fmc->dev.kobj, &fmc_eeprom_attr);
+		if (ret < 0) {
+			dev_err(&fmc->dev, "Failed in registering eeprom\n");
+			goto out1;
+		}
+		/* This device went well, give information to the user */
+		fmc_dump_eeprom(fmc);
+		fmc_dump_sdb(fmc);
+	}
+	return 0;
+
+out1:
+	device_del(&fmc->dev);
+out:
+	fmc_free_id_info(fmc);
+	put_device(&fmc->dev);
+
+	kfree(devarray);
+	for (i--; i >= 0; i--) {
+		sysfs_remove_bin_file(&devs[i]->dev.kobj, &fmc_eeprom_attr);
+		device_del(&devs[i]->dev);
+		fmc_free_id_info(devs[i]);
+		put_device(&devs[i]->dev);
+	}
+	return ret;
+
+}
+EXPORT_SYMBOL(fmc_device_register_n);
+
+int fmc_device_register(struct fmc_device *fmc)
+{
+	return fmc_device_register_n(&fmc, 1);
+}
+EXPORT_SYMBOL(fmc_device_register);
+
+void fmc_device_unregister_n(struct fmc_device **devs, int n)
+{
+	int i;
+
+	if (n < 1)
+		return;
+
+	/* Free devarray first, not used by the later loop */
+	kfree(devs[0]->devarray);
+
+	for (i = 0; i < n; i++) {
+		if (devs[i]->flags == FMC_DEVICE_NO_MEZZANINE)
+			continue;
+		sysfs_remove_bin_file(&devs[i]->dev.kobj, &fmc_eeprom_attr);
+		device_del(&devs[i]->dev);
+		fmc_free_id_info(devs[i]);
+		put_device(&devs[i]->dev);
+	}
+}
+EXPORT_SYMBOL(fmc_device_unregister_n);
+
+void fmc_device_unregister(struct fmc_device *fmc)
+{
+	fmc_device_unregister_n(&fmc, 1);
+}
+EXPORT_SYMBOL(fmc_device_unregister);
+
+/* Init and exit are trivial */
+static int fmc_init(void)
+{
+	return bus_register(&fmc_bus_type);
+}
+
+static void fmc_exit(void)
+{
+	bus_unregister(&fmc_bus_type);
+}
+
+module_init(fmc_init);
+module_exit(fmc_exit);
+
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/fmc-dump.c linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-dump.c
--- linux-libre-3.10-gnu/drivers/fmc/fmc-dump.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-dump.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2013 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Released according to the GNU GPL, version 2 or any later version.
+ *
+ * This work is part of the White Rabbit project, a research effort led
+ * by CERN, the European Institute for Nuclear Research.
+ */
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/fmc.h>
+#include <linux/fmc-sdb.h>
+
+static int fmc_must_dump_eeprom;
+module_param_named(dump_eeprom, fmc_must_dump_eeprom, int, 0644);
+static int fmc_must_dump_sdb;
+module_param_named(dump_sdb, fmc_must_dump_sdb, int, 0644);
+
+#define LINELEN 16
+
+/* Dumping 8k takes oh so much: avoid duplicate lines */
+static const uint8_t *dump_line(int addr, const uint8_t *line,
+				const uint8_t *prev)
+{
+	int i;
+
+	if (!prev || memcmp(line, prev, LINELEN)) {
+		pr_info("%04x: ", addr);
+		for (i = 0; i < LINELEN; ) {
+			printk(KERN_CONT "%02x", line[i]);
+			i++;
+			printk(i & 3 ? " " : i & (LINELEN - 1) ? "  " : "\n");
+		}
+		return line;
+	}
+	/* repeated line */
+	if (line == prev + LINELEN)
+		pr_info("[...]\n");
+	return prev;
+}
+
+void fmc_dump_eeprom(const struct fmc_device *fmc)
+{
+	const uint8_t *line, *prev;
+	int i;
+
+	if (!fmc_must_dump_eeprom)
+		return;
+
+	pr_info("FMC: %s (%s), slot %i, device %s\n", dev_name(fmc->hwdev),
+		fmc->carrier_name, fmc->slot_id, dev_name(&fmc->dev));
+	pr_info("FMC: dumping eeprom 0x%x (%i) bytes\n", fmc->eeprom_len,
+	       fmc->eeprom_len);
+
+	line = fmc->eeprom;
+	prev = NULL;
+	for (i = 0; i < fmc->eeprom_len; i += LINELEN, line += LINELEN)
+		prev = dump_line(i, line, prev);
+}
+
+void fmc_dump_sdb(const struct fmc_device *fmc)
+{
+	const uint8_t *line, *prev;
+	int i, len;
+
+	if (!fmc->sdb)
+		return;
+	if (!fmc_must_dump_sdb)
+		return;
+
+	/* If the argument is not-zero, do simple dump (== show) */
+	if (fmc_must_dump_sdb > 0)
+		fmc_show_sdb_tree(fmc);
+
+	if (fmc_must_dump_sdb == 1)
+		return;
+
+	/* If bigger than 1, dump it seriously, to help debugging */
+
+	/*
+	 * Here we should really use libsdbfs (which is designed to
+	 * work in kernel space as well) , but it doesn't support
+	 * directories yet, and it requires better intergration (it
+	 * should be used instead of fmc-specific code).
+	 *
+	 * So, lazily, just dump the top-level array
+	 */
+	pr_info("FMC: %s (%s), slot %i, device %s\n", dev_name(fmc->hwdev),
+		fmc->carrier_name, fmc->slot_id, dev_name(&fmc->dev));
+	pr_info("FMC: poor dump of sdb first level:\n");
+
+	len = fmc->sdb->len * sizeof(union sdb_record);
+	line = (void *)fmc->sdb->record;
+	prev = NULL;
+	for (i = 0; i < len; i += LINELEN, line += LINELEN)
+		prev = dump_line(i, line, prev);
+	return;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/fmc-fakedev.c linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-fakedev.c
--- linux-libre-3.10-gnu/drivers/fmc/fmc-fakedev.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-fakedev.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * The software is provided "as is"; the copyright holders disclaim
+ * all warranties and liabilities, to the extent permitted by
+ * applicable law.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/firmware.h>
+#include <linux/workqueue.h>
+#include <linux/err.h>
+#include <linux/fmc.h>
+
+#define FF_EEPROM_SIZE		8192	/* The standard eeprom size */
+#define FF_MAX_MEZZANINES	4	/* Fakes a multi-mezzanine carrier */
+
+/* The user can pass up to 4 names of eeprom images to load */
+static char *ff_eeprom[FF_MAX_MEZZANINES];
+static int ff_nr_eeprom;
+module_param_array_named(eeprom, ff_eeprom, charp, &ff_nr_eeprom, 0444);
+
+/* The user can ask for a multi-mezzanine carrier, with the default eeprom */
+static int ff_nr_dev = 1;
+module_param_named(ndev, ff_nr_dev, int, 0444);
+
+
+/* Lazily, don't support the "standard" module parameters */
+
+/*
+ * Eeprom built from these commands:
+
+	../fru-generator -v fake-vendor -n fake-design-for-testing \
+		-s 01234 -p none > IPMI-FRU
+
+	gensdbfs . ../fake-eeprom.bin
+*/
+static char ff_eeimg[FF_MAX_MEZZANINES][FF_EEPROM_SIZE] = {
+	{
+	0x01, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 0xf2, 0x01, 0x0b, 0x00, 0xb2,
+	0x86, 0x87, 0xcb, 0x66, 0x61, 0x6b, 0x65, 0x2d, 0x76, 0x65, 0x6e, 0x64,
+	0x6f, 0x72, 0xd7, 0x66, 0x61, 0x6b, 0x65, 0x2d, 0x64, 0x65, 0x73, 0x69,
+	0x67, 0x6e, 0x2d, 0x66, 0x6f, 0x72, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x69,
+	0x6e, 0x67, 0xc5, 0x30, 0x31, 0x32, 0x33, 0x34, 0xc4, 0x6e, 0x6f, 0x6e,
+	0x65, 0xda, 0x32, 0x30, 0x31, 0x32, 0x2d, 0x31, 0x31, 0x2d, 0x31, 0x39,
+	0x20, 0x32, 0x32, 0x3a, 0x34, 0x32, 0x3a, 0x33, 0x30, 0x2e, 0x30, 0x37,
+	0x34, 0x30, 0x35, 0x35, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87,
+	0x02, 0x02, 0x0d, 0xf7, 0xf8, 0x02, 0xb0, 0x04, 0x74, 0x04, 0xec, 0x04,
+	0x00, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x02, 0x02, 0x0d, 0x5c, 0x93, 0x01,
+	0x4a, 0x01, 0x39, 0x01, 0x5a, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0b,
+	0x02, 0x02, 0x0d, 0x63, 0x8c, 0x00, 0xfa, 0x00, 0xed, 0x00, 0x06, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x01, 0x02, 0x0d, 0xfb, 0xf5, 0x05,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x01, 0x02, 0x0d, 0xfc, 0xf4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0d, 0xfd, 0xf3, 0x03,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xfa, 0x82, 0x0b, 0xea, 0x8f, 0xa2, 0x12, 0x00, 0x00, 0x1e, 0x44, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x42, 0x2d, 0x00, 0x03, 0x01, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x01, 0xc4, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61,
+	0x2e, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x46, 0x69, 0x6c, 0x65,
+	0x44, 0x61, 0x74, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x00, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf,
+	0x46, 0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x49, 0x50, 0x4d, 0x49,
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49, 0x50, 0x4d, 0x49,
+	0x2d, 0x46, 0x52, 0x55, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x01, 0x66, 0x61, 0x6b, 0x65, 0x0a,
+	},
+};
+
+struct ff_dev {
+	struct fmc_device *fmc[FF_MAX_MEZZANINES];
+	struct device dev;
+};
+
+static struct ff_dev *ff_current_dev; /* We have 1 carrier, 1 slot */
+
+static int ff_reprogram(struct fmc_device *fmc, struct fmc_driver *drv,
+			  char *gw)
+{
+	const struct firmware *fw;
+	int ret;
+
+	if (!gw) {
+		/* program golden: success */
+		fmc->flags &= ~FMC_DEVICE_HAS_CUSTOM;
+		fmc->flags |= FMC_DEVICE_HAS_GOLDEN;
+		return 0;
+	}
+
+	dev_info(&fmc->dev, "reprogramming with %s\n", gw);
+	ret = request_firmware(&fw, gw, &fmc->dev);
+	if (ret < 0) {
+		dev_warn(&fmc->dev, "request firmware \"%s\": error %i\n",
+			 gw, ret);
+		goto out;
+	}
+	fmc->flags &= ~FMC_DEVICE_HAS_GOLDEN;
+	fmc->flags |= FMC_DEVICE_HAS_CUSTOM;
+
+out:
+	release_firmware(fw);
+	return ret;
+}
+
+static int ff_irq_request(struct fmc_device *fmc, irq_handler_t handler,
+			    char *name, int flags)
+{
+	return -EOPNOTSUPP;
+}
+
+/* FIXME: should also have some fake FMC GPIO mapping */
+
+
+/*
+ * This work function is called when we changed the eeprom. It removes the
+ * current fmc device and registers a new one, with different identifiers.
+ */
+static struct ff_dev *ff_dev_create(void); /* defined later */
+
+static void ff_work_fn(struct work_struct *work)
+{
+	struct ff_dev *ff = ff_current_dev;
+	int ret;
+
+	fmc_device_unregister_n(ff->fmc, ff_nr_dev);
+	device_unregister(&ff->dev);
+	ff_current_dev = NULL;
+
+	ff = ff_dev_create();
+	if (IS_ERR(ff)) {
+		pr_warning("%s: can't re-create FMC devices\n", __func__);
+		return;
+	}
+	ret = fmc_device_register_n(ff->fmc, ff_nr_dev);
+	if (ret < 0) {
+		dev_warn(&ff->dev, "can't re-register FMC devices\n");
+		device_unregister(&ff->dev);
+		return;
+	}
+
+	ff_current_dev = ff;
+}
+
+static DECLARE_DELAYED_WORK(ff_work, ff_work_fn);
+
+
+/* low-level i2c */
+static int ff_eeprom_read(struct fmc_device *fmc, uint32_t offset,
+		void *buf, size_t size)
+{
+	if (offset > FF_EEPROM_SIZE)
+		return -EINVAL;
+	if (offset + size > FF_EEPROM_SIZE)
+		size = FF_EEPROM_SIZE - offset;
+	memcpy(buf, fmc->eeprom + offset, size);
+	return size;
+}
+
+static int ff_eeprom_write(struct fmc_device *fmc, uint32_t offset,
+		    const void *buf, size_t size)
+{
+	if (offset > FF_EEPROM_SIZE)
+		return -EINVAL;
+	if (offset + size > FF_EEPROM_SIZE)
+		size = FF_EEPROM_SIZE - offset;
+	dev_info(&fmc->dev, "write_eeprom: offset %i, size %zi\n",
+		 (int)offset, size);
+	memcpy(fmc->eeprom + offset, buf, size);
+	schedule_delayed_work(&ff_work, HZ * 2); /* remove, replug, in 2s */
+	return size;
+}
+
+/* i2c operations for fmc */
+static int ff_read_ee(struct fmc_device *fmc, int pos, void *data, int len)
+{
+	if (!(fmc->flags & FMC_DEVICE_HAS_GOLDEN))
+		return -EOPNOTSUPP;
+	return ff_eeprom_read(fmc, pos, data, len);
+}
+
+static int ff_write_ee(struct fmc_device *fmc, int pos,
+			 const void *data, int len)
+{
+	if (!(fmc->flags & FMC_DEVICE_HAS_GOLDEN))
+		return -EOPNOTSUPP;
+	return ff_eeprom_write(fmc, pos, data, len);
+}
+
+/* readl and writel do not do anything. Don't waste RAM with "base" */
+static uint32_t ff_readl(struct fmc_device *fmc, int offset)
+{
+	return 0;
+}
+
+static void ff_writel(struct fmc_device *fmc, uint32_t value, int offset)
+{
+	return;
+}
+
+/* validate is useful so fmc-write-eeprom will not reprogram every 2 seconds */
+static int ff_validate(struct fmc_device *fmc, struct fmc_driver *drv)
+{
+	int i;
+
+	if (!drv->busid_n)
+		return 0; /* everyhing is valid */
+	for (i = 0; i < drv->busid_n; i++)
+		if (drv->busid_val[i] == fmc->device_id)
+			return i;
+	return -ENOENT;
+}
+
+
+
+static struct fmc_operations ff_fmc_operations = {
+	.read32 =		ff_readl,
+	.write32 =		ff_writel,
+	.reprogram =		ff_reprogram,
+	.irq_request =		ff_irq_request,
+	.read_ee =		ff_read_ee,
+	.write_ee =		ff_write_ee,
+	.validate =		ff_validate,
+};
+
+/* This device is kmalloced: release it */
+static void ff_dev_release(struct device *dev)
+{
+	struct ff_dev *ff = container_of(dev, struct ff_dev, dev);
+	kfree(ff);
+}
+
+static struct fmc_device ff_template_fmc = {
+	.version = FMC_VERSION,
+	.owner = THIS_MODULE,
+	.carrier_name = "fake-fmc-carrier",
+	.device_id = 0xf001, /* fool */
+	.eeprom_len = sizeof(ff_eeimg[0]),
+	.memlen = 0x1000, /* 4k, to show something */
+	.op = &ff_fmc_operations,
+	.hwdev = NULL, /* filled at creation time */
+	.flags = FMC_DEVICE_HAS_GOLDEN,
+};
+
+static struct ff_dev *ff_dev_create(void)
+{
+	struct ff_dev *ff;
+	struct fmc_device *fmc;
+	int i, ret;
+
+	ff = kzalloc(sizeof(*ff), GFP_KERNEL);
+	if (!ff)
+		return ERR_PTR(-ENOMEM);
+	dev_set_name(&ff->dev, "fake-fmc-carrier");
+	ff->dev.release = ff_dev_release;
+
+	ret = device_register(&ff->dev);
+	if (ret < 0) {
+		put_device(&ff->dev);
+		return ERR_PTR(ret);
+	}
+
+	/* Create fmc structures that refer to this new "hw" device */
+	for (i = 0; i < ff_nr_dev; i++) {
+		fmc = kmemdup(&ff_template_fmc, sizeof(ff_template_fmc),
+			      GFP_KERNEL);
+		fmc->hwdev = &ff->dev;
+		fmc->carrier_data = ff;
+		fmc->nr_slots = ff_nr_dev;
+		/* the following fields are different for each slot */
+		fmc->eeprom = ff_eeimg[i];
+		fmc->eeprom_addr = 0x50 + 2 * i;
+		fmc->slot_id = i;
+		ff->fmc[i] = fmc;
+		/* increment the identifier, each must be different */
+		ff_template_fmc.device_id++;
+	}
+	return ff;
+}
+
+/* init and exit */
+static int ff_init(void)
+{
+	struct ff_dev *ff;
+	const struct firmware *fw;
+	int i, len, ret = 0;
+
+	/* Replicate the default eeprom for the max number of mezzanines */
+	for (i = 1; i < FF_MAX_MEZZANINES; i++)
+		memcpy(ff_eeimg[i], ff_eeimg[0], sizeof(ff_eeimg[0]));
+
+	if (ff_nr_eeprom > ff_nr_dev)
+		ff_nr_dev = ff_nr_eeprom;
+
+	ff = ff_dev_create();
+	if (IS_ERR(ff))
+		return PTR_ERR(ff);
+
+	/* If the user passed "eeprom=" as a parameter, fetch them */
+	for (i = 0; i < ff_nr_eeprom; i++) {
+		if (!strlen(ff_eeprom[i]))
+			continue;
+		ret = request_firmware(&fw, ff_eeprom[i], &ff->dev);
+		if (ret < 0) {
+			dev_err(&ff->dev, "Mezzanine %i: can't load \"%s\" "
+				"(error %i)\n", i, ff_eeprom[i], -ret);
+		} else {
+			len = min_t(size_t, fw->size, (size_t)FF_EEPROM_SIZE);
+			memcpy(ff_eeimg[i], fw->data, len);
+			release_firmware(fw);
+			dev_info(&ff->dev, "Mezzanine %i: eeprom \"%s\"\n", i,
+				ff_eeprom[i]);
+		}
+	}
+
+	ret = fmc_device_register_n(ff->fmc, ff_nr_dev);
+	if (ret) {
+		device_unregister(&ff->dev);
+		return ret;
+	}
+	ff_current_dev = ff;
+	return ret;
+}
+
+static void ff_exit(void)
+{
+	if (ff_current_dev) {
+		fmc_device_unregister_n(ff_current_dev->fmc, ff_nr_dev);
+		device_unregister(&ff_current_dev->dev);
+	}
+	cancel_delayed_work_sync(&ff_work);
+}
+
+module_init(ff_init);
+module_exit(ff_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/fmc-match.c linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-match.c
--- linux-libre-3.10-gnu/drivers/fmc/fmc-match.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-match.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Released according to the GNU GPL, version 2 or any later version.
+ *
+ * This work is part of the White Rabbit project, a research effort led
+ * by CERN, the European Institute for Nuclear Research.
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fmc.h>
+#include <linux/ipmi-fru.h>
+
+/* The fru parser is both user and kernel capable: it needs alloc */
+void *fru_alloc(size_t size)
+{
+	return kzalloc(size, GFP_KERNEL);
+}
+
+/* The actual match function */
+int fmc_match(struct device *dev, struct device_driver *drv)
+{
+	struct fmc_driver *fdrv = to_fmc_driver(drv);
+	struct fmc_device *fdev = to_fmc_device(dev);
+	struct fmc_fru_id *fid;
+	int i, matched = 0;
+
+	/* This currently only matches the EEPROM (FRU id) */
+	fid = fdrv->id_table.fru_id;
+	if (!fid) {
+		dev_warn(&fdev->dev, "Driver has no ID: matches all\n");
+		matched = 1;
+	} else {
+		if (!fdev->id.manufacturer || !fdev->id.product_name)
+			return 0; /* the device has no FRU information */
+		for (i = 0; i < fdrv->id_table.fru_id_nr; i++, fid++) {
+			if (fid->manufacturer &&
+			    strcmp(fid->manufacturer, fdev->id.manufacturer))
+				continue;
+			if (fid->product_name &&
+			    strcmp(fid->product_name, fdev->id.product_name))
+				continue;
+			matched = 1;
+			break;
+		}
+	}
+
+	/* FIXME: match SDB contents */
+	return matched;
+}
+
+/* This function creates ID info for a newly registered device */
+int fmc_fill_id_info(struct fmc_device *fmc)
+{
+	struct fru_common_header *h;
+	struct fru_board_info_area *bia;
+	int ret, allocated = 0;
+
+	/* If we know the eeprom length, try to read it off the device */
+	if (fmc->eeprom_len && !fmc->eeprom) {
+		fmc->eeprom = kzalloc(fmc->eeprom_len, GFP_KERNEL);
+		if (!fmc->eeprom)
+			return -ENOMEM;
+		allocated = 1;
+		ret = fmc->op->read_ee(fmc, 0, fmc->eeprom, fmc->eeprom_len);
+		if (ret < 0)
+			goto out;
+	}
+
+	/* If no eeprom, continue with other matches */
+	if (!fmc->eeprom)
+		return 0;
+
+	dev_info(fmc->hwdev, "mezzanine %i\n", fmc->slot_id); /* header */
+
+	/* So we have the eeprom: parse the FRU part (if any) */
+	h = (void *)fmc->eeprom;
+	if (h->format != 1) {
+		pr_info("      EEPROM has no FRU information\n");
+		goto out;
+	}
+	if (!fru_header_cksum_ok(h)) {
+		pr_info("      FRU: wrong header checksum\n");
+		goto out;
+	}
+	bia = fru_get_board_area(h);
+	if (!fru_bia_cksum_ok(bia)) {
+		pr_info("      FRU: wrong board area checksum\n");
+		goto out;
+	}
+	fmc->id.manufacturer = fru_get_board_manufacturer(h);
+	fmc->id.product_name = fru_get_product_name(h);
+	pr_info("      Manufacturer: %s\n", fmc->id.manufacturer);
+	pr_info("      Product name: %s\n", fmc->id.product_name);
+
+	/* Create the short name (FIXME: look in sdb as well) */
+	fmc->mezzanine_name = kstrdup(fmc->id.product_name, GFP_KERNEL);
+
+out:
+	if (allocated) {
+		kfree(fmc->eeprom);
+		fmc->eeprom = NULL;
+	}
+	return 0; /* no error: let other identification work */
+}
+
+/* Some ID data is allocated using fru_alloc() above, so release it */
+void fmc_free_id_info(struct fmc_device *fmc)
+{
+	kfree(fmc->mezzanine_name);
+	kfree(fmc->id.manufacturer);
+	kfree(fmc->id.product_name);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/fmc-sdb.c linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-sdb.c
--- linux-libre-3.10-gnu/drivers/fmc/fmc-sdb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-sdb.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Released according to the GNU GPL, version 2 or any later version.
+ *
+ * This work is part of the White Rabbit project, a research effort led
+ * by CERN, the European Institute for Nuclear Research.
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fmc.h>
+#include <linux/sdb.h>
+#include <linux/err.h>
+#include <linux/fmc-sdb.h>
+#include <asm/byteorder.h>
+
+static uint32_t __sdb_rd(struct fmc_device *fmc, unsigned long address,
+			int convert)
+{
+	uint32_t res = fmc_readl(fmc, address);
+	if (convert)
+		return __be32_to_cpu(res);
+	return res;
+}
+
+static struct sdb_array *__fmc_scan_sdb_tree(struct fmc_device *fmc,
+					     unsigned long sdb_addr,
+					     unsigned long reg_base, int level)
+{
+	uint32_t onew;
+	int i, j, n, convert = 0;
+	struct sdb_array *arr, *sub;
+
+	onew = fmc_readl(fmc, sdb_addr);
+	if (onew == SDB_MAGIC) {
+		/* Uh! If we are little-endian, we must convert */
+		if (SDB_MAGIC != __be32_to_cpu(SDB_MAGIC))
+			convert = 1;
+	} else if (onew == __be32_to_cpu(SDB_MAGIC)) {
+		/* ok, don't convert */
+	} else {
+		return ERR_PTR(-ENOENT);
+	}
+	/* So, the magic was there: get the count from offset 4*/
+	onew = __sdb_rd(fmc, sdb_addr + 4, convert);
+	n = __be16_to_cpu(*(uint16_t *)&onew);
+	arr = kzalloc(sizeof(*arr), GFP_KERNEL);
+	if (!arr)
+		return ERR_PTR(-ENOMEM);
+	arr->record = kzalloc(sizeof(arr->record[0]) * n, GFP_KERNEL);
+	arr->subtree = kzalloc(sizeof(arr->subtree[0]) * n, GFP_KERNEL);
+	if (!arr->record || !arr->subtree) {
+		kfree(arr->record);
+		kfree(arr->subtree);
+		kfree(arr);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	arr->len = n;
+	arr->level = level;
+	arr->fmc = fmc;
+	for (i = 0; i < n; i++) {
+		union  sdb_record *r;
+
+		for (j = 0; j < sizeof(arr->record[0]); j += 4) {
+			*(uint32_t *)((void *)(arr->record + i) + j) =
+				__sdb_rd(fmc, sdb_addr + (i * 64) + j, convert);
+		}
+		r = &arr->record[i];
+		arr->subtree[i] = ERR_PTR(-ENODEV);
+		if (r->empty.record_type == sdb_type_bridge) {
+			struct sdb_component *c = &r->bridge.sdb_component;
+			uint64_t subaddr = __be64_to_cpu(r->bridge.sdb_child);
+			uint64_t newbase = __be64_to_cpu(c->addr_first);
+
+			subaddr += reg_base;
+			newbase += reg_base;
+			sub = __fmc_scan_sdb_tree(fmc, subaddr, newbase,
+						  level + 1);
+			arr->subtree[i] = sub; /* may be error */
+			if (IS_ERR(sub))
+				continue;
+			sub->parent = arr;
+			sub->baseaddr = newbase;
+		}
+	}
+	return arr;
+}
+
+int fmc_scan_sdb_tree(struct fmc_device *fmc, unsigned long address)
+{
+	struct sdb_array *ret;
+	if (fmc->sdb)
+		return -EBUSY;
+	ret = __fmc_scan_sdb_tree(fmc, address, 0 /* regs */, 0);
+	if (IS_ERR(ret))
+		return PTR_ERR(ret);
+	fmc->sdb = ret;
+	return 0;
+}
+EXPORT_SYMBOL(fmc_scan_sdb_tree);
+
+static void __fmc_sdb_free(struct sdb_array *arr)
+{
+	int i, n;
+
+	if (!arr)
+		return;
+	n = arr->len;
+	for (i = 0; i < n; i++) {
+		if (IS_ERR(arr->subtree[i]))
+			continue;
+		__fmc_sdb_free(arr->subtree[i]);
+	}
+	kfree(arr->record);
+	kfree(arr->subtree);
+	kfree(arr);
+}
+
+int fmc_free_sdb_tree(struct fmc_device *fmc)
+{
+	__fmc_sdb_free(fmc->sdb);
+	fmc->sdb = NULL;
+	return 0;
+}
+EXPORT_SYMBOL(fmc_free_sdb_tree);
+
+/* This helper calls reprogram and inizialized sdb as well */
+int fmc_reprogram(struct fmc_device *fmc, struct fmc_driver *d, char *gw,
+			 int sdb_entry)
+{
+	int ret;
+
+	ret = fmc->op->reprogram(fmc, d, gw);
+	if (ret < 0)
+		return ret;
+	if (sdb_entry < 0)
+		return ret;
+
+	/* We are required to find SDB at a given offset */
+	ret = fmc_scan_sdb_tree(fmc, sdb_entry);
+	if (ret < 0) {
+		dev_err(&fmc->dev, "Can't find SDB at address 0x%x\n",
+			sdb_entry);
+		return -ENODEV;
+	}
+	fmc_dump_sdb(fmc);
+	return 0;
+}
+EXPORT_SYMBOL(fmc_reprogram);
+
+static void __fmc_show_sdb_tree(const struct fmc_device *fmc,
+				const struct sdb_array *arr)
+{
+	int i, j, n = arr->len, level = arr->level;
+	const struct sdb_array *ap;
+
+	for (i = 0; i < n; i++) {
+		unsigned long base;
+		union  sdb_record *r;
+		struct sdb_product *p;
+		struct sdb_component *c;
+		r = &arr->record[i];
+		c = &r->dev.sdb_component;
+		p = &c->product;
+		base = 0;
+		for (ap = arr; ap; ap = ap->parent)
+			base += ap->baseaddr;
+		dev_info(&fmc->dev, "SDB: ");
+
+		for (j = 0; j < level; j++)
+			printk(KERN_CONT "   ");
+		switch (r->empty.record_type) {
+		case sdb_type_interconnect:
+			printk(KERN_CONT "%08llx:%08x %.19s\n",
+			       __be64_to_cpu(p->vendor_id),
+			       __be32_to_cpu(p->device_id),
+			       p->name);
+			break;
+		case sdb_type_device:
+			printk(KERN_CONT "%08llx:%08x %.19s (%08llx-%08llx)\n",
+			       __be64_to_cpu(p->vendor_id),
+			       __be32_to_cpu(p->device_id),
+			       p->name,
+			       __be64_to_cpu(c->addr_first) + base,
+			       __be64_to_cpu(c->addr_last) + base);
+			break;
+		case sdb_type_bridge:
+			printk(KERN_CONT "%08llx:%08x %.19s (bridge: %08llx)\n",
+			       __be64_to_cpu(p->vendor_id),
+			       __be32_to_cpu(p->device_id),
+			       p->name,
+			       __be64_to_cpu(c->addr_first) + base);
+			if (IS_ERR(arr->subtree[i])) {
+				printk(KERN_CONT "(bridge error %li)\n",
+				       PTR_ERR(arr->subtree[i]));
+				break;
+			}
+			__fmc_show_sdb_tree(fmc, arr->subtree[i]);
+			break;
+		case sdb_type_integration:
+			printk(KERN_CONT "integration\n");
+			break;
+		case sdb_type_repo_url:
+			printk(KERN_CONT "repo-url\n");
+			break;
+		case sdb_type_synthesis:
+			printk(KERN_CONT "synthesis-info\n");
+			break;
+		case sdb_type_empty:
+			printk(KERN_CONT "empty\n");
+			break;
+		default:
+			printk(KERN_CONT "UNKNOWN TYPE 0x%02x\n",
+			       r->empty.record_type);
+			break;
+		}
+	}
+}
+
+void fmc_show_sdb_tree(const struct fmc_device *fmc)
+{
+	if (!fmc->sdb)
+		return;
+	__fmc_show_sdb_tree(fmc, fmc->sdb);
+}
+EXPORT_SYMBOL(fmc_show_sdb_tree);
+
+signed long fmc_find_sdb_device(struct sdb_array *tree,
+				uint64_t vid, uint32_t did, unsigned long *sz)
+{
+	signed long res = -ENODEV;
+	union  sdb_record *r;
+	struct sdb_product *p;
+	struct sdb_component *c;
+	int i, n = tree->len;
+	uint64_t last, first;
+
+	/* FIXME: what if the first interconnect is not at zero? */
+	for (i = 0; i < n; i++) {
+		r = &tree->record[i];
+		c = &r->dev.sdb_component;
+		p = &c->product;
+
+		if (!IS_ERR(tree->subtree[i]))
+			res = fmc_find_sdb_device(tree->subtree[i],
+						  vid, did, sz);
+		if (res >= 0)
+			return res + tree->baseaddr;
+		if (r->empty.record_type != sdb_type_device)
+			continue;
+		if (__be64_to_cpu(p->vendor_id) != vid)
+			continue;
+		if (__be32_to_cpu(p->device_id) != did)
+			continue;
+		/* found */
+		last = __be64_to_cpu(c->addr_last);
+		first = __be64_to_cpu(c->addr_first);
+		if (sz)
+			*sz = (typeof(*sz))(last + 1 - first);
+		return first + tree->baseaddr;
+	}
+	return res;
+}
+EXPORT_SYMBOL(fmc_find_sdb_device);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/fmc-trivial.c linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-trivial.c
--- linux-libre-3.10-gnu/drivers/fmc/fmc-trivial.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-trivial.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * The software is provided "as is"; the copyright holders disclaim
+ * all warranties and liabilities, to the extent permitted by
+ * applicable law.
+ */
+
+/* A trivial fmc driver that can load a gateware file and reports interrupts */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/fmc.h>
+
+static struct fmc_driver t_drv; /* initialized later */
+
+static irqreturn_t t_handler(int irq, void *dev_id)
+{
+	struct fmc_device *fmc = dev_id;
+
+	fmc->op->irq_ack(fmc);
+	dev_info(&fmc->dev, "received irq %i\n", irq);
+	return IRQ_HANDLED;
+}
+
+static struct fmc_gpio t_gpio[] = {
+	{
+		.gpio = FMC_GPIO_IRQ(0),
+		.mode = GPIOF_DIR_IN,
+		.irqmode = IRQF_TRIGGER_RISING,
+	}, {
+		.gpio = FMC_GPIO_IRQ(1),
+		.mode = GPIOF_DIR_IN,
+		.irqmode = IRQF_TRIGGER_RISING,
+	}
+};
+
+static int t_probe(struct fmc_device *fmc)
+{
+	int ret;
+	int index = 0;
+
+	if (fmc->op->validate)
+		index = fmc->op->validate(fmc, &t_drv);
+	if (index < 0)
+		return -EINVAL; /* not our device: invalid */
+
+	ret = fmc->op->irq_request(fmc, t_handler, "fmc-trivial", IRQF_SHARED);
+	if (ret < 0)
+		return ret;
+	/* ignore error code of call below, we really don't care */
+	fmc->op->gpio_config(fmc, t_gpio, ARRAY_SIZE(t_gpio));
+
+	/* Reprogram, if asked to. ESRCH == no filename specified */
+	ret = -ESRCH;
+	if (fmc->op->reprogram)
+		ret = fmc->op->reprogram(fmc, &t_drv, "");
+	if (ret == -ESRCH)
+		ret = 0;
+	if (ret < 0)
+		fmc->op->irq_free(fmc);
+
+	/* FIXME: reprogram LM32 too */
+	return ret;
+}
+
+static int t_remove(struct fmc_device *fmc)
+{
+	fmc->op->irq_free(fmc);
+	return 0;
+}
+
+static struct fmc_driver t_drv = {
+	.version = FMC_VERSION,
+	.driver.name = KBUILD_MODNAME,
+	.probe = t_probe,
+	.remove = t_remove,
+	/* no table, as the current match just matches everything */
+};
+
+ /* We accept the generic parameters */
+FMC_PARAM_BUSID(t_drv);
+FMC_PARAM_GATEWARE(t_drv);
+
+static int t_init(void)
+{
+	int ret;
+
+	ret = fmc_driver_register(&t_drv);
+	return ret;
+}
+
+static void t_exit(void)
+{
+	fmc_driver_unregister(&t_drv);
+}
+
+module_init(t_init);
+module_exit(t_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/fmc-write-eeprom.c linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-write-eeprom.c
--- linux-libre-3.10-gnu/drivers/fmc/fmc-write-eeprom.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/fmc-write-eeprom.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Released according to the GNU GPL, version 2 or any later version.
+ *
+ * This work is part of the White Rabbit project, a research effort led
+ * by CERN, the European Institute for Nuclear Research.
+ */
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/firmware.h>
+#include <linux/init.h>
+#include <linux/fmc.h>
+#include <asm/unaligned.h>
+
+/*
+ * This module uses the firmware loader to program the whole or part
+ * of the FMC eeprom. The meat is in the _run functions.  However, no
+ * default file name is provided, to avoid accidental mishaps. Also,
+ * you must pass the busid argument
+ */
+static struct fmc_driver fwe_drv;
+
+FMC_PARAM_BUSID(fwe_drv);
+
+/* The "file=" is like the generic "gateware=" used elsewhere */
+static char *fwe_file[FMC_MAX_CARDS];
+static int fwe_file_n;
+module_param_array_named(file, fwe_file, charp, &fwe_file_n, 444);
+
+static int fwe_run_tlv(struct fmc_device *fmc, const struct firmware *fw,
+	int write)
+{
+	const uint8_t *p = fw->data;
+	int len = fw->size;
+	uint16_t thislen, thisaddr;
+	int err;
+
+	/* format is: 'w' addr16 len16 data... */
+	while (len > 5) {
+		thisaddr = get_unaligned_le16(p+1);
+		thislen = get_unaligned_le16(p+3);
+		if (p[0] != 'w' || thislen + 5 > len) {
+			dev_err(&fmc->dev, "invalid tlv at offset %ti\n",
+				p - fw->data);
+			return -EINVAL;
+		}
+		err = 0;
+		if (write) {
+			dev_info(&fmc->dev, "write %i bytes at 0x%04x\n",
+				 thislen, thisaddr);
+			err = fmc->op->write_ee(fmc, thisaddr, p + 5, thislen);
+		}
+		if (err < 0) {
+			dev_err(&fmc->dev, "write failure @0x%04x\n",
+				thisaddr);
+			return err;
+		}
+		p += 5 + thislen;
+		len -= 5 + thislen;
+	}
+	if (write)
+		dev_info(&fmc->dev, "write_eeprom: success\n");
+	return 0;
+}
+
+static int fwe_run_bin(struct fmc_device *fmc, const struct firmware *fw)
+{
+	int ret;
+
+	dev_info(&fmc->dev, "programming %zi bytes\n", fw->size);
+	ret = fmc->op->write_ee(fmc, 0, (void *)fw->data, fw->size);
+	if (ret < 0) {
+		dev_info(&fmc->dev, "write_eeprom: error %i\n", ret);
+		return ret;
+	}
+	dev_info(&fmc->dev, "write_eeprom: success\n");
+	return 0;
+}
+
+static int fwe_run(struct fmc_device *fmc, const struct firmware *fw, char *s)
+{
+	char *last4 = s + strlen(s) - 4;
+	int err;
+
+	if (!strcmp(last4, ".bin"))
+		return fwe_run_bin(fmc, fw);
+	if (!strcmp(last4, ".tlv")) {
+		err = fwe_run_tlv(fmc, fw, 0);
+		if (!err)
+			err = fwe_run_tlv(fmc, fw, 1);
+		return err;
+	}
+	dev_err(&fmc->dev, "invalid file name \"%s\"\n", s);
+	return -EINVAL;
+}
+
+/*
+ * Programming is done at probe time. Morever, only those listed with
+ * busid= are programmed.
+ * card is probed for, only one is programmed. Unfortunately, it's
+ * difficult to know in advance when probing the first card if others
+ * are there.
+ */
+int fwe_probe(struct fmc_device *fmc)
+{
+	int err, index = 0;
+	const struct firmware *fw;
+	struct device *dev = &fmc->dev;
+	char *s;
+
+	if (!fwe_drv.busid_n) {
+		dev_err(dev, "%s: no busid passed, refusing all cards\n",
+			KBUILD_MODNAME);
+		return -ENODEV;
+	}
+	if (fmc->op->validate)
+		index = fmc->op->validate(fmc, &fwe_drv);
+	if (index < 0) {
+		pr_err("%s: refusing device \"%s\"\n", KBUILD_MODNAME,
+		       dev_name(dev));
+		return -ENODEV;
+	}
+	if (index >= fwe_file_n) {
+		pr_err("%s: no filename for device index %i\n",
+			KBUILD_MODNAME, index);
+		return -ENODEV;
+	}
+	s = fwe_file[index];
+	if (!s) {
+		pr_err("%s: no filename for \"%s\" not programming\n",
+		       KBUILD_MODNAME, dev_name(dev));
+		return -ENOENT;
+	}
+	err = request_firmware(&fw, s, dev);
+	if (err < 0) {
+		dev_err(&fmc->dev, "request firmware \"%s\": error %i\n",
+			s, err);
+		return err;
+	}
+	fwe_run(fmc, fw, s);
+	release_firmware(fw);
+	return 0;
+}
+
+int fwe_remove(struct fmc_device *fmc)
+{
+	return 0;
+}
+
+static struct fmc_driver fwe_drv = {
+	.version = FMC_VERSION,
+	.driver.name = KBUILD_MODNAME,
+	.probe = fwe_probe,
+	.remove = fwe_remove,
+	/* no table, as the current match just matches everything */
+};
+
+static int fwe_init(void)
+{
+	int ret;
+
+	ret = fmc_driver_register(&fwe_drv);
+	return ret;
+}
+
+static void fwe_exit(void)
+{
+	fmc_driver_unregister(&fwe_drv);
+}
+
+module_init(fwe_init);
+module_exit(fwe_exit);
+
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/fru-parse.c linux-libre-3.11-rc7-gnu/drivers/fmc/fru-parse.c
--- linux-libre-3.10-gnu/drivers/fmc/fru-parse.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/fru-parse.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ *
+ * Released according to the GNU GPL, version 2 or any later version.
+ *
+ * This work is part of the White Rabbit project, a research effort led
+ * by CERN, the European Institute for Nuclear Research.
+ */
+#include <linux/ipmi-fru.h>
+
+/* Some internal helpers */
+static struct fru_type_length *
+__fru_get_board_tl(struct fru_common_header *header, int nr)
+{
+	struct fru_board_info_area *bia;
+	struct fru_type_length *tl;
+
+	bia = fru_get_board_area(header);
+	tl = bia->tl;
+	while (nr > 0 && !fru_is_eof(tl)) {
+		tl = fru_next_tl(tl);
+		nr--;
+	}
+	if (fru_is_eof(tl))
+		return NULL;
+	return tl;
+}
+
+static char *__fru_alloc_get_tl(struct fru_common_header *header, int nr)
+{
+	struct fru_type_length *tl;
+	char *res;
+	int len;
+
+	tl = __fru_get_board_tl(header, nr);
+	if (!tl)
+		return NULL;
+	len = fru_strlen(tl);
+	res = fru_alloc(fru_strlen(tl) + 1);
+	if (!res)
+		return NULL;
+	return fru_strcpy(res, tl);
+}
+
+/* Public checksum verifiers */
+int fru_header_cksum_ok(struct fru_common_header *header)
+{
+	uint8_t *ptr = (void *)header;
+	int i, sum;
+
+	for (i = sum = 0; i < sizeof(*header); i++)
+		sum += ptr[i];
+	return (sum & 0xff) == 0;
+}
+int fru_bia_cksum_ok(struct fru_board_info_area *bia)
+{
+	uint8_t *ptr = (void *)bia;
+	int i, sum;
+
+	for (i = sum = 0; i < 8 * bia->area_len; i++)
+		sum += ptr[i];
+	return (sum & 0xff) == 0;
+}
+
+/* Get various stuff, trivial */
+char *fru_get_board_manufacturer(struct fru_common_header *header)
+{
+	return __fru_alloc_get_tl(header, 0);
+}
+char *fru_get_product_name(struct fru_common_header *header)
+{
+	return __fru_alloc_get_tl(header, 1);
+}
+char *fru_get_serial_number(struct fru_common_header *header)
+{
+	return __fru_alloc_get_tl(header, 2);
+}
+char *fru_get_part_number(struct fru_common_header *header)
+{
+	return __fru_alloc_get_tl(header, 3);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/Kconfig linux-libre-3.11-rc7-gnu/drivers/fmc/Kconfig
--- linux-libre-3.10-gnu/drivers/fmc/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,51 @@
+#
+# FMC (ANSI-VITA 57.1) bus support
+#
+
+menuconfig FMC
+	tristate "FMC support"
+	help
+
+	  FMC (FPGA Mezzanine Carrier) is a mechanical and electrical
+	  standard for mezzanine cards that plug into a carrier board.
+	  This kernel subsystem supports the matching between carrier
+	  and mezzanine based on identifiers stored in the internal I2C
+	  EEPROM, as well as having carrier-independent drivers.
+
+	  The framework was born outside of the kernel and at this time
+	  the off-tree code base is more complete.  Code and documentation
+	  is at git://ohwr.org/fmc-projects/fmc-bus.git .
+
+if FMC
+
+config FMC_FAKEDEV
+	tristate "FMC fake device (software testing)"
+	help
+	  This is a fake carrier, bringing a default EEPROM content
+	  that can be rewritten at run time and usef for matching
+	  mezzanines.
+
+config FMC_TRIVIAL
+	tristate "FMC trivial mezzanine driver (software testing)"
+	help
+	  This is a fake mezzanine driver, to show how FMC works and test it.
+	  The driver also handles interrupts (we used it with a real carrier
+	  before the mezzanines were produced)
+
+config FMC_WRITE_EEPROM
+	tristate "FMC mezzanine driver to write I2C EEPROM"
+	help
+	  This driver matches every mezzanine device and can write the
+	  internal EEPROM of the PCB, using the firmware loader to get
+	  its binary and the function carrier->reprogram to actually do it.
+	  It is useful when the mezzanines are produced.
+
+config FMC_CHARDEV
+	tristate "FMC mezzanine driver that registers a char device"
+	help
+	  This driver matches every mezzanine device and allows user
+	  space to read and write registers using a char device. It
+	  can be used to write user-space drivers, or just get
+	  aquainted with a mezzanine before writing its specific driver.
+
+endif # FMC
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/fmc/Makefile linux-libre-3.11-rc7-gnu/drivers/fmc/Makefile
--- linux-libre-3.10-gnu/drivers/fmc/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/fmc/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,13 @@
+
+obj-$(CONFIG_FMC) += fmc.o
+
+fmc-y = fmc-core.o
+fmc-y += fmc-match.o
+fmc-y += fmc-sdb.o
+fmc-y += fru-parse.o
+fmc-y += fmc-dump.o
+
+obj-$(CONFIG_FMC_FAKEDEV) += fmc-fakedev.o
+obj-$(CONFIG_FMC_TRIVIAL) += fmc-trivial.o
+obj-$(CONFIG_FMC_WRITE_EEPROM) += fmc-write-eeprom.o
+obj-$(CONFIG_FMC_CHARDEV) += fmc-chardev.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/devres.c linux-libre-3.11-rc7-gnu/drivers/gpio/devres.c
--- linux-libre-3.10-gnu/drivers/gpio/devres.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/devres.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,10 +34,10 @@ static int devm_gpio_match(struct device
 }
 
 /**
- *      devm_gpio_request - request a gpio for a managed device
- *      @dev: device to request the gpio for
- *      @gpio: gpio to allocate
- *      @label: the name of the requested gpio
+ *      devm_gpio_request - request a GPIO for a managed device
+ *      @dev: device to request the GPIO for
+ *      @gpio: GPIO to allocate
+ *      @label: the name of the requested GPIO
  *
  *      Except for the extra @dev argument, this function takes the
  *      same arguments and performs the same function as
@@ -101,9 +101,9 @@ int devm_gpio_request_one(struct device
 EXPORT_SYMBOL(devm_gpio_request_one);
 
 /**
- *      devm_gpio_free - free an interrupt
- *      @dev: device to free gpio for
- *      @gpio: gpio to free
+ *      devm_gpio_free - free a GPIO
+ *      @dev: device to free GPIO for
+ *      @gpio: GPIO to free
  *
  *      Except for the extra @dev argument, this function takes the
  *      same arguments and performs the same function as gpio_free().
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-bt8xx.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-bt8xx.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-bt8xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-bt8xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -286,7 +286,7 @@ static int bt8xxgpio_resume(struct pci_d
 	unsigned long flags;
 	int err;
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	err = pci_enable_device(pdev);
 	if (err)
 		return err;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-clps711x.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-clps711x.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-clps711x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-clps711x.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  *  CLPS711X GPIO driver
  *
- *  Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru>
+ *  Copyright (C) 2012,2013 Alexander Shiyan <shc_work@mail.ru>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -9,191 +9,91 @@
  * (at your option) any later version.
  */
 
-#include <linux/io.h>
-#include <linux/slab.h>
+#include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/module.h>
-#include <linux/spinlock.h>
+#include <linux/basic_mmio_gpio.h>
 #include <linux/platform_device.h>
 
-#include <mach/hardware.h>
-
-#define CLPS711X_GPIO_PORTS	5
-#define CLPS711X_GPIO_NAME	"gpio-clps711x"
-
-struct clps711x_gpio {
-	struct gpio_chip	chip[CLPS711X_GPIO_PORTS];
-	spinlock_t		lock;
-};
-
-static void __iomem *clps711x_ports[] = {
-	CLPS711X_VIRT_BASE + PADR,
-	CLPS711X_VIRT_BASE + PBDR,
-	CLPS711X_VIRT_BASE + PCDR,
-	CLPS711X_VIRT_BASE + PDDR,
-	CLPS711X_VIRT_BASE + PEDR,
-};
-
-static void __iomem *clps711x_pdirs[] = {
-	CLPS711X_VIRT_BASE + PADDR,
-	CLPS711X_VIRT_BASE + PBDDR,
-	CLPS711X_VIRT_BASE + PCDDR,
-	CLPS711X_VIRT_BASE + PDDDR,
-	CLPS711X_VIRT_BASE + PEDDR,
-};
-
-#define clps711x_port(x)	clps711x_ports[x->base / 8]
-#define clps711x_pdir(x)	clps711x_pdirs[x->base / 8]
-
-static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset)
-{
-	return !!(readb(clps711x_port(chip)) & (1 << offset));
-}
-
-static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset,
-			      int value)
+static int clps711x_gpio_probe(struct platform_device *pdev)
 {
-	int tmp;
-	unsigned long flags;
-	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
-
-	spin_lock_irqsave(&gpio->lock, flags);
-	tmp = readb(clps711x_port(chip)) & ~(1 << offset);
-	if (value)
-		tmp |= 1 << offset;
-	writeb(tmp, clps711x_port(chip));
-	spin_unlock_irqrestore(&gpio->lock, flags);
-}
+	struct device_node *np = pdev->dev.of_node;
+	void __iomem *dat, *dir;
+	struct bgpio_chip *bgc;
+	struct resource *res;
+	int err, id = np ? of_alias_get_id(np, "gpio") : pdev->id;
 
-static int gpio_clps711x_dir_in(struct gpio_chip *chip, unsigned offset)
-{
-	int tmp;
-	unsigned long flags;
-	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+	if ((id < 0) || (id > 4))
+		return -ENODEV;
 
-	spin_lock_irqsave(&gpio->lock, flags);
-	tmp = readb(clps711x_pdir(chip)) & ~(1 << offset);
-	writeb(tmp, clps711x_pdir(chip));
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL);
+	if (!bgc)
+		return -ENOMEM;
 
-	return 0;
-}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dat = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dat))
+		return PTR_ERR(dat);
 
-static int gpio_clps711x_dir_out(struct gpio_chip *chip, unsigned offset,
-				 int value)
-{
-	int tmp;
-	unsigned long flags;
-	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	dir = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dir))
+		return PTR_ERR(dir);
 
-	spin_lock_irqsave(&gpio->lock, flags);
-	tmp = readb(clps711x_pdir(chip)) | (1 << offset);
-	writeb(tmp, clps711x_pdir(chip));
-	tmp = readb(clps711x_port(chip)) & ~(1 << offset);
-	if (value)
-		tmp |= 1 << offset;
-	writeb(tmp, clps711x_port(chip));
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	switch (id) {
+	case 3:
+		/* PORTD is inverted logic for direction register */
+		err = bgpio_init(bgc, &pdev->dev, 1, dat, NULL, NULL,
+				 NULL, dir, 0);
+		break;
+	default:
+		err = bgpio_init(bgc, &pdev->dev, 1, dat, NULL, NULL,
+				 dir, NULL, 0);
+		break;
+	}
 
-	return 0;
-}
+	if (err)
+		return err;
 
-static int gpio_clps711x_dir_in_inv(struct gpio_chip *chip, unsigned offset)
-{
-	int tmp;
-	unsigned long flags;
-	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
+	switch (id) {
+	case 4:
+		/* PORTE is 3 lines only */
+		bgc->gc.ngpio = 3;
+		break;
+	default:
+		break;
+	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
-	tmp = readb(clps711x_pdir(chip)) | (1 << offset);
-	writeb(tmp, clps711x_pdir(chip));
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	bgc->gc.base = id * 8;
+	platform_set_drvdata(pdev, bgc);
 
-	return 0;
+	return gpiochip_add(&bgc->gc);
 }
 
-static int gpio_clps711x_dir_out_inv(struct gpio_chip *chip, unsigned offset,
-				     int value)
+static int clps711x_gpio_remove(struct platform_device *pdev)
 {
-	int tmp;
-	unsigned long flags;
-	struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
-
-	spin_lock_irqsave(&gpio->lock, flags);
-	tmp = readb(clps711x_pdir(chip)) & ~(1 << offset);
-	writeb(tmp, clps711x_pdir(chip));
-	tmp = readb(clps711x_port(chip)) & ~(1 << offset);
-	if (value)
-		tmp |= 1 << offset;
-	writeb(tmp, clps711x_port(chip));
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	struct bgpio_chip *bgc = platform_get_drvdata(pdev);
 
-	return 0;
+	return bgpio_remove(bgc);
 }
 
-static struct {
-	char	*name;
-	int	nr;
-	int	inv_dir;
-} clps711x_gpio_ports[] __initconst = {
-	{ "PORTA", 8, 0, },
-	{ "PORTB", 8, 0, },
-	{ "PORTC", 8, 0, },
-	{ "PORTD", 8, 1, },
-	{ "PORTE", 3, 0, },
+static const struct of_device_id clps711x_gpio_ids[] = {
+	{ .compatible = "cirrus,clps711x-gpio" },
+	{ }
 };
+MODULE_DEVICE_TABLE(of, clps711x_gpio_ids);
 
-static int __init gpio_clps711x_init(void)
-{
-	int i;
-	struct platform_device *pdev;
-	struct clps711x_gpio *gpio;
-
-	pdev = platform_device_alloc(CLPS711X_GPIO_NAME, 0);
-	if (!pdev) {
-		pr_err("Cannot create platform device: %s\n",
-		       CLPS711X_GPIO_NAME);
-		return -ENOMEM;
-	}
-
-	platform_device_add(pdev);
-
-	gpio = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_gpio),
-			    GFP_KERNEL);
-	if (!gpio) {
-		dev_err(&pdev->dev, "GPIO allocating memory error\n");
-		platform_device_unregister(pdev);
-		return -ENOMEM;
-	}
-
-	platform_set_drvdata(pdev, gpio);
-
-	spin_lock_init(&gpio->lock);
-
-	for (i = 0; i < CLPS711X_GPIO_PORTS; i++) {
-		gpio->chip[i].owner		= THIS_MODULE;
-		gpio->chip[i].dev		= &pdev->dev;
-		gpio->chip[i].label		= clps711x_gpio_ports[i].name;
-		gpio->chip[i].base		= i * 8;
-		gpio->chip[i].ngpio		= clps711x_gpio_ports[i].nr;
-		gpio->chip[i].get		= gpio_clps711x_get;
-		gpio->chip[i].set		= gpio_clps711x_set;
-		if (!clps711x_gpio_ports[i].inv_dir) {
-			gpio->chip[i].direction_input = gpio_clps711x_dir_in;
-			gpio->chip[i].direction_output = gpio_clps711x_dir_out;
-		} else {
-			gpio->chip[i].direction_input = gpio_clps711x_dir_in_inv;
-			gpio->chip[i].direction_output = gpio_clps711x_dir_out_inv;
-		}
-		WARN_ON(gpiochip_add(&gpio->chip[i]));
-	}
-
-	dev_info(&pdev->dev, "GPIO driver initialized\n");
-
-	return 0;
-}
-arch_initcall(gpio_clps711x_init);
+static struct platform_driver clps711x_gpio_driver = {
+	.driver	= {
+		.name		= "clps711x-gpio",
+		.owner		= THIS_MODULE,
+		.of_match_table	= of_match_ptr(clps711x_gpio_ids),
+	},
+	.probe	= clps711x_gpio_probe,
+	.remove	= clps711x_gpio_remove,
+};
+module_platform_driver(clps711x_gpio_driver);
 
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
 MODULE_DESCRIPTION("CLPS711X GPIO driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-grgpio.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-grgpio.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-grgpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-grgpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -235,8 +235,8 @@ static irqreturn_t grgpio_irq_handler(in
  * This function will be called as a consequence of the call to
  * irq_create_mapping in grgpio_to_irq
  */
-int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
-		   irq_hw_number_t hwirq)
+static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
+			  irq_hw_number_t hwirq)
 {
 	struct grgpio_priv *priv = d->host_data;
 	struct grgpio_lirq *lirq;
@@ -291,7 +291,7 @@ int grgpio_irq_map(struct irq_domain *d,
 	return ret;
 }
 
-void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
+static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
 {
 	struct grgpio_priv *priv = d->host_data;
 	int index;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-ich.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-ich.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-ich.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-ich.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,12 +41,14 @@ enum GPIO_REG {
 	GPIO_USE_SEL = 0,
 	GPIO_IO_SEL,
 	GPIO_LVL,
+	GPO_BLINK
 };
 
-static const u8 ichx_regs[3][3] = {
+static const u8 ichx_regs[4][3] = {
 	{0x00, 0x30, 0x40},	/* USE_SEL[1-3] offsets */
 	{0x04, 0x34, 0x44},	/* IO_SEL[1-3] offsets */
 	{0x0c, 0x38, 0x48},	/* LVL[1-3] offsets */
+	{0x18, 0x18, 0x18},	/* BLINK offset */
 };
 
 static const u8 ichx_reglen[3] = {
@@ -148,6 +150,10 @@ static int ichx_gpio_direction_input(str
 static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
 					int val)
 {
+	/* Disable blink hardware which is available for GPIOs from 0 to 31. */
+	if (nr < 32)
+		ichx_write_bit(GPO_BLINK, nr, 0, 0);
+
 	/* Set GPIO output value. */
 	ichx_write_bit(GPIO_LVL, nr, val, 0);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-langwell.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-langwell.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-langwell.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-langwell.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Moorestown platform Langwell chip GPIO driver
  *
- * Copyright (c) 2008 - 2009,  Intel Corporation.
+ * Copyright (c) 2008, 2009, 2013, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -20,7 +20,6 @@
 /* Supports:
  * Moorestown platform Langwell chip.
  * Medfield platform Penwell chip.
- * Whitney point.
  */
 
 #include <linux/module.h>
@@ -65,7 +64,7 @@ enum GPIO_REG {
 
 struct lnw_gpio {
 	struct gpio_chip		chip;
-	void				*reg_base;
+	void __iomem			*reg_base;
 	spinlock_t			lock;
 	struct pci_dev			*pdev;
 	struct irq_domain		*domain;
@@ -74,15 +73,13 @@ struct lnw_gpio {
 #define to_lnw_priv(chip)	container_of(chip, struct lnw_gpio, chip)
 
 static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
-			enum GPIO_REG reg_type)
+			      enum GPIO_REG reg_type)
 {
 	struct lnw_gpio *lnw = to_lnw_priv(chip);
 	unsigned nreg = chip->ngpio / 32;
 	u8 reg = offset / 32;
-	void __iomem *ptr;
 
-	ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4);
-	return ptr;
+	return lnw->reg_base + reg_type * nreg * 4 + reg * 4;
 }
 
 static void __iomem *gpio_reg_2bit(struct gpio_chip *chip, unsigned offset,
@@ -91,10 +88,8 @@ static void __iomem *gpio_reg_2bit(struc
 	struct lnw_gpio *lnw = to_lnw_priv(chip);
 	unsigned nreg = chip->ngpio / 32;
 	u8 reg = offset / 16;
-	void __iomem *ptr;
 
-	ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4);
-	return ptr;
+	return lnw->reg_base + reg_type * nreg * 4 + reg * 4;
 }
 
 static int lnw_gpio_request(struct gpio_chip *chip, unsigned offset)
@@ -305,11 +300,7 @@ static const struct irq_domain_ops lnw_g
 
 static int lnw_gpio_runtime_idle(struct device *dev)
 {
-	int err = pm_schedule_suspend(dev, 500);
-
-	if (!err)
-		return 0;
-
+	pm_schedule_suspend(dev, 500);
 	return -EBUSY;
 }
 
@@ -318,56 +309,40 @@ static const struct dev_pm_ops lnw_gpio_
 };
 
 static int lnw_gpio_probe(struct pci_dev *pdev,
-			const struct pci_device_id *id)
+			  const struct pci_device_id *id)
 {
-	void *base;
-	resource_size_t start, len;
+	void __iomem *base;
 	struct lnw_gpio *lnw;
 	u32 gpio_base;
 	u32 irq_base;
 	int retval;
 	int ngpio = id->driver_data;
 
-	retval = pci_enable_device(pdev);
+	retval = pcim_enable_device(pdev);
 	if (retval)
 		return retval;
 
-	retval = pci_request_regions(pdev, "langwell_gpio");
+	retval = pcim_iomap_regions(pdev, 1 << 0 | 1 << 1, pci_name(pdev));
 	if (retval) {
-		dev_err(&pdev->dev, "error requesting resources\n");
-		goto err_pci_req_region;
-	}
-	/* get the gpio_base from bar1 */
-	start = pci_resource_start(pdev, 1);
-	len = pci_resource_len(pdev, 1);
-	base = ioremap_nocache(start, len);
-	if (!base) {
-		dev_err(&pdev->dev, "error mapping bar1\n");
-		retval = -EFAULT;
-		goto err_ioremap;
+		dev_err(&pdev->dev, "I/O memory mapping error\n");
+		return retval;
 	}
-	irq_base = *(u32 *)base;
-	gpio_base = *((u32 *)base + 1);
+
+	base = pcim_iomap_table(pdev)[1];
+
+	irq_base = readl(base);
+	gpio_base = readl(sizeof(u32) + base);
+
 	/* release the IO mapping, since we already get the info from bar1 */
-	iounmap(base);
-	/* get the register base from bar0 */
-	start = pci_resource_start(pdev, 0);
-	len = pci_resource_len(pdev, 0);
-	base = devm_ioremap_nocache(&pdev->dev, start, len);
-	if (!base) {
-		dev_err(&pdev->dev, "error mapping bar0\n");
-		retval = -EFAULT;
-		goto err_ioremap;
-	}
+	pcim_iounmap_regions(pdev, 1 << 1);
 
 	lnw = devm_kzalloc(&pdev->dev, sizeof(*lnw), GFP_KERNEL);
 	if (!lnw) {
-		dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n");
-		retval = -ENOMEM;
-		goto err_ioremap;
+		dev_err(&pdev->dev, "can't allocate chip data\n");
+		return -ENOMEM;
 	}
 
-	lnw->reg_base = base;
+	lnw->reg_base = pcim_iomap_table(pdev)[0];
 	lnw->chip.label = dev_name(&pdev->dev);
 	lnw->chip.request = lnw_gpio_request;
 	lnw->chip.direction_input = lnw_gpio_direction_input;
@@ -380,18 +355,18 @@ static int lnw_gpio_probe(struct pci_dev
 	lnw->chip.can_sleep = 0;
 	lnw->pdev = pdev;
 
+	spin_lock_init(&lnw->lock);
+
 	lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ngpio, irq_base,
 					    &lnw_gpio_irq_ops, lnw);
-	if (!lnw->domain) {
-		retval = -ENOMEM;
-		goto err_ioremap;
-	}
+	if (!lnw->domain)
+		return -ENOMEM;
 
 	pci_set_drvdata(pdev, lnw);
 	retval = gpiochip_add(&lnw->chip);
 	if (retval) {
-		dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval);
-		goto err_ioremap;
+		dev_err(&pdev->dev, "gpiochip_add error %d\n", retval);
+		return retval;
 	}
 
 	lnw_irq_init_hw(lnw);
@@ -399,18 +374,10 @@ static int lnw_gpio_probe(struct pci_dev
 	irq_set_handler_data(pdev->irq, lnw);
 	irq_set_chained_handler(pdev->irq, lnw_irq_handler);
 
-	spin_lock_init(&lnw->lock);
-
 	pm_runtime_put_noidle(&pdev->dev);
 	pm_runtime_allow(&pdev->dev);
 
 	return 0;
-
-err_ioremap:
-	pci_release_regions(pdev);
-err_pci_req_region:
-	pci_disable_device(pdev);
-	return retval;
 }
 
 static struct pci_driver lnw_gpio_driver = {
@@ -422,88 +389,9 @@ static struct pci_driver lnw_gpio_driver
 	},
 };
 
-
-static int wp_gpio_probe(struct platform_device *pdev)
-{
-	struct lnw_gpio *lnw;
-	struct gpio_chip *gc;
-	struct resource *rc;
-	int retval = 0;
-
-	rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!rc)
-		return -EINVAL;
-
-	lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL);
-	if (!lnw) {
-		dev_err(&pdev->dev,
-			"can't allocate whitneypoint_gpio chip data\n");
-		return -ENOMEM;
-	}
-	lnw->reg_base = ioremap_nocache(rc->start, resource_size(rc));
-	if (lnw->reg_base == NULL) {
-		retval = -EINVAL;
-		goto err_kmalloc;
-	}
-	spin_lock_init(&lnw->lock);
-	gc = &lnw->chip;
-	gc->label = dev_name(&pdev->dev);
-	gc->owner = THIS_MODULE;
-	gc->direction_input = lnw_gpio_direction_input;
-	gc->direction_output = lnw_gpio_direction_output;
-	gc->get = lnw_gpio_get;
-	gc->set = lnw_gpio_set;
-	gc->to_irq = NULL;
-	gc->base = 0;
-	gc->ngpio = 64;
-	gc->can_sleep = 0;
-	retval = gpiochip_add(gc);
-	if (retval) {
-		dev_err(&pdev->dev, "whitneypoint gpiochip_add error %d\n",
-								retval);
-		goto err_ioremap;
-	}
-	platform_set_drvdata(pdev, lnw);
-	return 0;
-err_ioremap:
-	iounmap(lnw->reg_base);
-err_kmalloc:
-	kfree(lnw);
-	return retval;
-}
-
-static int wp_gpio_remove(struct platform_device *pdev)
-{
-	struct lnw_gpio *lnw = platform_get_drvdata(pdev);
-	int err;
-	err = gpiochip_remove(&lnw->chip);
-	if (err)
-		dev_err(&pdev->dev, "failed to remove gpio_chip.\n");
-	iounmap(lnw->reg_base);
-	kfree(lnw);
-	platform_set_drvdata(pdev, NULL);
-	return 0;
-}
-
-static struct platform_driver wp_gpio_driver = {
-	.probe		= wp_gpio_probe,
-	.remove		= wp_gpio_remove,
-	.driver		= {
-		.name	= "wp_gpio",
-		.owner	= THIS_MODULE,
-	},
-};
-
 static int __init lnw_gpio_init(void)
 {
-	int ret;
-	ret =  pci_register_driver(&lnw_gpio_driver);
-	if (ret < 0)
-		return ret;
-	ret = platform_driver_register(&wp_gpio_driver);
-	if (ret < 0)
-		pci_unregister_driver(&lnw_gpio_driver);
-	return ret;
+	return pci_register_driver(&lnw_gpio_driver);
 }
 
 device_initcall(lnw_gpio_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpiolib.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpiolib.c
--- linux-libre-3.10-gnu/drivers/gpio/gpiolib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpiolib.c	2013-08-25 20:43:22.000000000 -0400
@@ -1214,15 +1214,14 @@ int gpiochip_add(struct gpio_chip *chip)
 		}
 	}
 
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
 #ifdef CONFIG_PINCTRL
 	INIT_LIST_HEAD(&chip->pin_ranges);
 #endif
 
 	of_gpiochip_add(chip);
 
-unlock:
-	spin_unlock_irqrestore(&gpio_lock, flags);
-
 	if (status)
 		goto fail;
 
@@ -1235,6 +1234,9 @@ unlock:
 		chip->label ? : "generic");
 
 	return 0;
+
+unlock:
+	spin_unlock_irqrestore(&gpio_lock, flags);
 fail:
 	/* failures here can mean systems won't boot... */
 	pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-lynxpoint.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-lynxpoint.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-lynxpoint.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-lynxpoint.c	2013-08-25 20:43:22.000000000 -0400
@@ -447,7 +447,6 @@ static int lp_gpio_remove(struct platfor
 	err = gpiochip_remove(&lg->chip);
 	if (err)
 		dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-ml-ioh.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-ml-ioh.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-ml-ioh.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-ml-ioh.c	2013-08-25 20:43:22.000000000 -0400
@@ -465,6 +465,7 @@ static int ioh_gpio_probe(struct pci_dev
 			dev_warn(&pdev->dev,
 				"ml_ioh_gpio: Failed to get IRQ base num\n");
 			chip->irq_base = -1;
+			ret = irq_base;
 			goto err_irq_alloc_descs;
 		}
 		chip->irq_base = irq_base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-msm-v1.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-msm-v1.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-msm-v1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-msm-v1.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/err.h>
 
 #include <mach/msm_gpiomux.h>
 
@@ -630,7 +631,7 @@ static struct irq_chip msm_gpio_irq_chip
 	.irq_set_type  = msm_gpio_irq_set_type,
 };
 
-static int __devinit gpio_msm_v1_probe(struct platform_device *pdev)
+static int gpio_msm_v1_probe(struct platform_device *pdev)
 {
 	int i, j = 0;
 	const struct platform_device_id *dev_id = platform_get_device_id(pdev);
@@ -652,14 +653,14 @@ static int __devinit gpio_msm_v1_probe(s
 		return irq2;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	base1 = devm_request_and_ioremap(&pdev->dev, res);
-	if (!base1)
-		return -EADDRNOTAVAIL;
+	base1 = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base1))
+		return PTR_ERR(base1);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	base2 = devm_request_and_ioremap(&pdev->dev, res);
-	if (!base2)
-		return -EADDRNOTAVAIL;
+	base2 = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base2))
+		return PTR_ERR(base2);
 
 	for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) {
 		if (i - FIRST_GPIO_IRQ >=
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-msm-v2.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-msm-v2.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-msm-v2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-msm-v2.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,18 +19,21 @@
 
 #include <linux/bitmap.h>
 #include <linux/bitops.h>
+#include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/module.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
-#include <mach/msm_gpiomux.h>
-#include <mach/msm_iomap.h>
+#define MAX_NR_GPIO 300
 
 /* Bits of interest in the GPIO_IN_OUT register.
  */
@@ -77,13 +80,6 @@ enum {
 	TARGET_PROC_NONE     = 7,
 };
 
-
-#define GPIO_INTR_CFG_SU(gpio)    (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio)))
-#define GPIO_CONFIG(gpio)         (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio)))
-#define GPIO_IN_OUT(gpio)         (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio)))
-#define GPIO_INTR_CFG(gpio)       (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio)))
-#define GPIO_INTR_STATUS(gpio)    (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio)))
-
 /**
  * struct msm_gpio_dev: the MSM8660 SoC GPIO device structure
  *
@@ -102,11 +98,27 @@ enum {
  */
 struct msm_gpio_dev {
 	struct gpio_chip gpio_chip;
-	DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS);
-	DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS);
-	DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS);
+	DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
+	DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
+	DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
+	struct irq_domain *domain;
+	unsigned int summary_irq;
+	void __iomem *msm_tlmm_base;
 };
 
+struct msm_gpio_dev msm_gpio;
+
+#define GPIO_INTR_CFG_SU(gpio)    (msm_gpio.msm_tlmm_base + 0x0400 + \
+								(0x04 * (gpio)))
+#define GPIO_CONFIG(gpio)         (msm_gpio.msm_tlmm_base + 0x1000 + \
+								(0x10 * (gpio)))
+#define GPIO_IN_OUT(gpio)         (msm_gpio.msm_tlmm_base + 0x1004 + \
+								(0x10 * (gpio)))
+#define GPIO_INTR_CFG(gpio)       (msm_gpio.msm_tlmm_base + 0x1008 + \
+								(0x10 * (gpio)))
+#define GPIO_INTR_STATUS(gpio)    (msm_gpio.msm_tlmm_base + 0x100c + \
+								(0x10 * (gpio)))
+
 static DEFINE_SPINLOCK(tlmm_lock);
 
 static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
@@ -159,37 +171,29 @@ static int msm_gpio_direction_output(str
 
 static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
 {
-	return msm_gpiomux_get(chip->base + offset);
+	return 0;
 }
 
 static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
-	msm_gpiomux_put(chip->base + offset);
+	return;
 }
 
 static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-	return MSM_GPIO_TO_INT(chip->base + offset);
+	struct msm_gpio_dev *g_dev = to_msm_gpio_dev(chip);
+	struct irq_domain *domain = g_dev->domain;
+
+	return irq_create_mapping(domain, offset);
 }
 
 static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq)
 {
-	return irq - MSM_GPIO_TO_INT(chip->base);
+	struct irq_data *irq_data = irq_get_irq_data(irq);
+
+	return irq_data->hwirq;
 }
 
-static struct msm_gpio_dev msm_gpio = {
-	.gpio_chip = {
-		.base             = 0,
-		.ngpio            = NR_GPIO_IRQS,
-		.direction_input  = msm_gpio_direction_input,
-		.direction_output = msm_gpio_direction_output,
-		.get              = msm_gpio_get,
-		.set              = msm_gpio_set,
-		.to_irq           = msm_gpio_to_irq,
-		.request          = msm_gpio_request,
-		.free             = msm_gpio_free,
-	},
-};
 
 /* For dual-edge interrupts in software, since the hardware has no
  * such support:
@@ -227,9 +231,9 @@ static void msm_gpio_update_dual_edge_po
 		if (intstat || val == val2)
 			return;
 	} while (loop_limit-- > 0);
-	pr_err("dual-edge irq failed to stabilize, "
+	pr_err("%s: dual-edge irq failed to stabilize, "
 	       "interrupts dropped. %#08x != %#08x\n",
-	       val, val2);
+	       __func__, val, val2);
 }
 
 static void msm_gpio_irq_ack(struct irq_data *d)
@@ -316,10 +320,10 @@ static void msm_summary_irq_handler(unsi
 
 	chained_irq_enter(chip, desc);
 
-	for_each_set_bit(i, msm_gpio.enabled_irqs, NR_GPIO_IRQS) {
+	for_each_set_bit(i, msm_gpio.enabled_irqs, MAX_NR_GPIO) {
 		if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS))
-			generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
-							   i));
+			generic_handle_irq(irq_find_mapping(msm_gpio.domain,
+								i));
 	}
 
 	chained_irq_exit(chip, desc);
@@ -330,13 +334,13 @@ static int msm_gpio_irq_set_wake(struct
 	int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
 
 	if (on) {
-		if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
-			irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
+		if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
+			irq_set_irq_wake(msm_gpio.summary_irq, 1);
 		set_bit(gpio, msm_gpio.wake_irqs);
 	} else {
 		clear_bit(gpio, msm_gpio.wake_irqs);
-		if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
-			irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
+		if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
+			irq_set_irq_wake(msm_gpio.summary_irq, 0);
 	}
 
 	return 0;
@@ -351,30 +355,86 @@ static struct irq_chip msm_gpio_irq_chip
 	.irq_set_wake	= msm_gpio_irq_set_wake,
 };
 
-static int msm_gpio_probe(struct platform_device *dev)
+static struct lock_class_key msm_gpio_lock_class;
+
+static int msm_gpio_irq_domain_map(struct irq_domain *d, unsigned int irq,
+				   irq_hw_number_t hwirq)
 {
-	int i, irq, ret;
+	irq_set_lockdep_class(irq, &msm_gpio_lock_class);
+	irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
+			handle_level_irq);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static const struct irq_domain_ops msm_gpio_irq_domain_ops = {
+	.xlate = irq_domain_xlate_twocell,
+	.map = msm_gpio_irq_domain_map,
+};
+
+static int msm_gpio_probe(struct platform_device *pdev)
+{
+	int ret, ngpio;
+	struct resource *res;
+
+	if (of_property_read_u32(pdev->dev.of_node, "ngpio", &ngpio)) {
+		dev_err(&pdev->dev, "%s: ngpio property missing\n", __func__);
+		return -EINVAL;
+	}
+
+	if (ngpio > MAX_NR_GPIO)
+		WARN(1, "ngpio exceeds the MAX_NR_GPIO. Increase MAX_NR_GPIO\n");
+
+	bitmap_zero(msm_gpio.enabled_irqs, MAX_NR_GPIO);
+	bitmap_zero(msm_gpio.wake_irqs, MAX_NR_GPIO);
+	bitmap_zero(msm_gpio.dual_edge_irqs, MAX_NR_GPIO);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	msm_gpio.msm_tlmm_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(msm_gpio.msm_tlmm_base))
+		return PTR_ERR(msm_gpio.msm_tlmm_base);
+
+	msm_gpio.gpio_chip.ngpio = ngpio;
+	msm_gpio.gpio_chip.label = pdev->name;
+	msm_gpio.gpio_chip.dev = &pdev->dev;
+	msm_gpio.gpio_chip.base = 0;
+	msm_gpio.gpio_chip.direction_input = msm_gpio_direction_input;
+	msm_gpio.gpio_chip.direction_output = msm_gpio_direction_output;
+	msm_gpio.gpio_chip.get = msm_gpio_get;
+	msm_gpio.gpio_chip.set = msm_gpio_set;
+	msm_gpio.gpio_chip.to_irq = msm_gpio_to_irq;
+	msm_gpio.gpio_chip.request = msm_gpio_request;
+	msm_gpio.gpio_chip.free = msm_gpio_free;
 
-	bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
-	bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS);
-	bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS);
-	msm_gpio.gpio_chip.label = dev->name;
 	ret = gpiochip_add(&msm_gpio.gpio_chip);
-	if (ret < 0)
+	if (ret < 0) {
+		dev_err(&pdev->dev, "gpiochip_add failed with error %d\n", ret);
 		return ret;
+	}
 
-	for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
-		irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
-		irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
-					 handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
+	msm_gpio.summary_irq = platform_get_irq(pdev, 0);
+	if (msm_gpio.summary_irq < 0) {
+		dev_err(&pdev->dev, "No Summary irq defined for msmgpio\n");
+		return msm_gpio.summary_irq;
 	}
 
-	irq_set_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
-				msm_summary_irq_handler);
+	msm_gpio.domain = irq_domain_add_linear(pdev->dev.of_node, ngpio,
+						&msm_gpio_irq_domain_ops,
+						&msm_gpio);
+	if (!msm_gpio.domain)
+		return -ENODEV;
+
+	irq_set_chained_handler(msm_gpio.summary_irq, msm_summary_irq_handler);
+
 	return 0;
 }
 
+static struct of_device_id msm_gpio_of_match[] = {
+	{ .compatible = "qcom,msm-gpio", },
+	{ },
+};
+
 static int msm_gpio_remove(struct platform_device *dev)
 {
 	int ret = gpiochip_remove(&msm_gpio.gpio_chip);
@@ -382,7 +442,7 @@ static int msm_gpio_remove(struct platfo
 	if (ret < 0)
 		return ret;
 
-	irq_set_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
+	irq_set_handler(msm_gpio.summary_irq, NULL);
 
 	return 0;
 }
@@ -393,36 +453,11 @@ static struct platform_driver msm_gpio_d
 	.driver = {
 		.name = "msmgpio",
 		.owner = THIS_MODULE,
+		.of_match_table = msm_gpio_of_match,
 	},
 };
 
-static struct platform_device msm_device_gpio = {
-	.name = "msmgpio",
-	.id   = -1,
-};
-
-static int __init msm_gpio_init(void)
-{
-	int rc;
-
-	rc = platform_driver_register(&msm_gpio_driver);
-	if (!rc) {
-		rc = platform_device_register(&msm_device_gpio);
-		if (rc)
-			platform_driver_unregister(&msm_gpio_driver);
-	}
-
-	return rc;
-}
-
-static void __exit msm_gpio_exit(void)
-{
-	platform_device_unregister(&msm_device_gpio);
-	platform_driver_unregister(&msm_gpio_driver);
-}
-
-postcore_initcall(msm_gpio_init);
-module_exit(msm_gpio_exit);
+module_platform_driver(msm_gpio_driver)
 
 MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
 MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-mvebu.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-mvebu.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-mvebu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-mvebu.c	2013-08-25 20:43:22.000000000 -0400
@@ -457,7 +457,7 @@ static void mvebu_gpio_irq_handler(unsig
 		if (!(cause & (1 << i)))
 			continue;
 
-		type = irqd_get_trigger_type(irq_get_irq_data(irq));
+		type = irq_get_trigger_type(irq);
 		if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
 			/* Swap polarity (race with GPIO line) */
 			u32 polarity;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-omap.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-omap.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-omap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-omap.c	2013-08-25 20:43:22.000000000 -0400
@@ -1482,7 +1482,7 @@ static void omap_gpio_restore_context(st
 #else
 #define omap_gpio_runtime_suspend NULL
 #define omap_gpio_runtime_resume NULL
-static void omap_gpio_init_context(struct gpio_bank *p) {}
+static inline void omap_gpio_init_context(struct gpio_bank *p) {}
 #endif
 
 static const struct dev_pm_ops gpio_pm_ops = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-rcar.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-rcar.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-rcar.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-rcar.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,6 +49,9 @@ struct gpio_rcar_priv {
 #define POSNEG 0x20
 #define EDGLEVEL 0x24
 #define FILONOFF 0x28
+#define BOTHEDGE 0x4c
+
+#define RCAR_MAX_GPIO_PER_BANK		32
 
 static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs)
 {
@@ -91,7 +94,8 @@ static void gpio_rcar_irq_enable(struct
 static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p,
 						  unsigned int hwirq,
 						  bool active_high_rising_edge,
-						  bool level_trigger)
+						  bool level_trigger,
+						  bool both)
 {
 	unsigned long flags;
 
@@ -108,6 +112,10 @@ static void gpio_rcar_config_interrupt_i
 	/* Configure edge or level trigger in EDGLEVEL */
 	gpio_rcar_modify_bit(p, EDGLEVEL, hwirq, !level_trigger);
 
+	/* Select one edge or both edges in BOTHEDGE */
+	if (p->config.has_both_edge_trigger)
+		gpio_rcar_modify_bit(p, BOTHEDGE, hwirq, both);
+
 	/* Select "Interrupt Input Mode" in IOINTSEL */
 	gpio_rcar_modify_bit(p, IOINTSEL, hwirq, true);
 
@@ -127,16 +135,26 @@ static int gpio_rcar_irq_set_type(struct
 
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_LEVEL_HIGH:
-		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, true);
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, true,
+						      false);
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
-		gpio_rcar_config_interrupt_input_mode(p, hwirq, false, true);
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, false, true,
+						      false);
 		break;
 	case IRQ_TYPE_EDGE_RISING:
-		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, false);
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, false,
+						      false);
 		break;
 	case IRQ_TYPE_EDGE_FALLING:
-		gpio_rcar_config_interrupt_input_mode(p, hwirq, false, false);
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, false, false,
+						      false);
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		if (!p->config.has_both_edge_trigger)
+			return -EINVAL;
+		gpio_rcar_config_interrupt_input_mode(p, hwirq, true, false,
+						      true);
 		break;
 	default:
 		return -EINVAL;
@@ -214,7 +232,14 @@ static int gpio_rcar_direction_input(str
 
 static int gpio_rcar_get(struct gpio_chip *chip, unsigned offset)
 {
-	return (int)(gpio_rcar_read(gpio_to_priv(chip), INDT) & BIT(offset));
+	u32 bit = BIT(offset);
+
+	/* testing on r8a7790 shows that INDT does not show correct pin state
+	 * when configured as output, so use OUTDT in case of output pins */
+	if (gpio_rcar_read(gpio_to_priv(chip), INOUTSEL) & bit)
+		return (int)(gpio_rcar_read(gpio_to_priv(chip), OUTDT) & bit);
+	else
+		return (int)(gpio_rcar_read(gpio_to_priv(chip), INDT) & bit);
 }
 
 static void gpio_rcar_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -258,9 +283,35 @@ static struct irq_domain_ops gpio_rcar_i
 	.map	= gpio_rcar_irq_domain_map,
 };
 
+static void gpio_rcar_parse_pdata(struct gpio_rcar_priv *p)
+{
+	struct gpio_rcar_config *pdata = p->pdev->dev.platform_data;
+	struct device_node *np = p->pdev->dev.of_node;
+	struct of_phandle_args args;
+	int ret;
+
+	if (pdata) {
+		p->config = *pdata;
+	} else if (IS_ENABLED(CONFIG_OF) && np) {
+		ret = of_parse_phandle_with_args(np, "gpio-ranges",
+				"#gpio-range-cells", 0, &args);
+		p->config.number_of_pins = ret == 0 && args.args_count == 3
+					 ? args.args[2]
+					 : RCAR_MAX_GPIO_PER_BANK;
+		p->config.gpio_base = -1;
+	}
+
+	if (p->config.number_of_pins == 0 ||
+	    p->config.number_of_pins > RCAR_MAX_GPIO_PER_BANK) {
+		dev_warn(&p->pdev->dev,
+			 "Invalid number of gpio lines %u, using %u\n",
+			 p->config.number_of_pins, RCAR_MAX_GPIO_PER_BANK);
+		p->config.number_of_pins = RCAR_MAX_GPIO_PER_BANK;
+	}
+}
+
 static int gpio_rcar_probe(struct platform_device *pdev)
 {
-	struct gpio_rcar_config *pdata = pdev->dev.platform_data;
 	struct gpio_rcar_priv *p;
 	struct resource *io, *irq;
 	struct gpio_chip *gpio_chip;
@@ -275,14 +326,14 @@ static int gpio_rcar_probe(struct platfo
 		goto err0;
 	}
 
-	/* deal with driver instance configuration */
-	if (pdata)
-		p->config = *pdata;
-
 	p->pdev = pdev;
-	platform_set_drvdata(pdev, p);
 	spin_lock_init(&p->lock);
 
+	/* Get device configuration from DT node or platform data. */
+	gpio_rcar_parse_pdata(p);
+
+	platform_set_drvdata(pdev, p);
+
 	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
@@ -309,6 +360,7 @@ static int gpio_rcar_probe(struct platfo
 	gpio_chip->set = gpio_rcar_set;
 	gpio_chip->to_irq = gpio_rcar_to_irq;
 	gpio_chip->label = name;
+	gpio_chip->dev = &pdev->dev;
 	gpio_chip->owner = THIS_MODULE;
 	gpio_chip->base = p->config.gpio_base;
 	gpio_chip->ngpio = p->config.number_of_pins;
@@ -333,7 +385,7 @@ static int gpio_rcar_probe(struct platfo
 	}
 
 	if (devm_request_irq(&pdev->dev, irq->start,
-			     gpio_rcar_irq_handler, 0, name, p)) {
+			     gpio_rcar_irq_handler, IRQF_SHARED, name, p)) {
 		dev_err(&pdev->dev, "failed to request IRQ\n");
 		ret = -ENOENT;
 		goto err1;
@@ -355,10 +407,12 @@ static int gpio_rcar_probe(struct platfo
 				 p->config.irq_base, ret);
 	}
 
-	ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0,
-				     gpio_chip->base, gpio_chip->ngpio);
-	if (ret < 0)
-		dev_warn(&pdev->dev, "failed to add pin range\n");
+	if (p->config.pctl_name) {
+		ret = gpiochip_add_pin_range(gpio_chip, p->config.pctl_name, 0,
+					     gpio_chip->base, gpio_chip->ngpio);
+		if (ret < 0)
+			dev_warn(&pdev->dev, "failed to add pin range\n");
+	}
 
 	return 0;
 
@@ -381,11 +435,23 @@ static int gpio_rcar_remove(struct platf
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id gpio_rcar_of_table[] = {
+	{
+		.compatible = "renesas,gpio-rcar",
+	},
+	{ },
+};
+
+MODULE_DEVICE_TABLE(of, gpio_rcar_of_table);
+#endif
+
 static struct platform_driver gpio_rcar_device_driver = {
 	.probe		= gpio_rcar_probe,
 	.remove		= gpio_rcar_remove,
 	.driver		= {
 		.name	= "gpio_rcar",
+		.of_match_table = of_match_ptr(gpio_rcar_of_table),
 	}
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-rdc321x.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-rdc321x.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-rdc321x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-rdc321x.c	2013-08-25 20:43:22.000000000 -0400
@@ -187,20 +187,18 @@ static int rdc321x_gpio_probe(struct pla
 					rdc321x_gpio_dev->reg1_data_base,
 					&rdc321x_gpio_dev->data_reg[0]);
 	if (err)
-		goto out_drvdata;
+		goto out_free;
 
 	err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
 					rdc321x_gpio_dev->reg2_data_base,
 					&rdc321x_gpio_dev->data_reg[1]);
 	if (err)
-		goto out_drvdata;
+		goto out_free;
 
 	dev_info(&pdev->dev, "registering %d GPIOs\n",
 					rdc321x_gpio_dev->chip.ngpio);
 	return gpiochip_add(&rdc321x_gpio_dev->chip);
 
-out_drvdata:
-	platform_set_drvdata(pdev, NULL);
 out_free:
 	kfree(rdc321x_gpio_dev);
 	return err;
@@ -216,7 +214,6 @@ static int rdc321x_gpio_remove(struct pl
 		dev_err(&pdev->dev, "failed to unregister chip\n");
 
 	kfree(rdc321x_gpio_dev);
-	platform_set_drvdata(pdev, NULL);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-samsung.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-samsung.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-samsung.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-samsung.c	2013-08-25 20:43:22.000000000 -0400
@@ -933,67 +933,6 @@ static void __init samsung_gpiolib_add(s
 		s3c_gpiolib_track(chip);
 }
 
-#if defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF)
-static int s3c24xx_gpio_xlate(struct gpio_chip *gc,
-			const struct of_phandle_args *gpiospec, u32 *flags)
-{
-	unsigned int pin;
-
-	if (WARN_ON(gc->of_gpio_n_cells < 3))
-		return -EINVAL;
-
-	if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
-		return -EINVAL;
-
-	if (gpiospec->args[0] > gc->ngpio)
-		return -EINVAL;
-
-	pin = gc->base + gpiospec->args[0];
-
-	if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
-		pr_warn("gpio_xlate: failed to set pin function\n");
-	if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
-		pr_warn("gpio_xlate: failed to set pin pull up/down\n");
-
-	if (flags)
-		*flags = gpiospec->args[2] >> 16;
-
-	return gpiospec->args[0];
-}
-
-static const struct of_device_id s3c24xx_gpio_dt_match[] __initdata = {
-	{ .compatible = "samsung,s3c24xx-gpio", },
-	{}
-};
-
-static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
-						 u64 base, u64 offset)
-{
-	struct gpio_chip *gc =  &chip->chip;
-	u64 address;
-
-	if (!of_have_populated_dt())
-		return;
-
-	address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
-	gc->of_node = of_find_matching_node_by_address(NULL,
-			s3c24xx_gpio_dt_match, address);
-	if (!gc->of_node) {
-		pr_info("gpio: device tree node not found for gpio controller"
-			" with base address %08llx\n", address);
-		return;
-	}
-	gc->of_gpio_n_cells = 3;
-	gc->of_xlate = s3c24xx_gpio_xlate;
-}
-#else
-static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
-						 u64 base, u64 offset)
-{
-	return;
-}
-#endif /* defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) */
-
 static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
 					     int nr_chips, void __iomem *base)
 {
@@ -1018,8 +957,6 @@ static void __init s3c24xx_gpiolib_add_c
 			gc->direction_output = samsung_gpiolib_2bit_output;
 
 		samsung_gpiolib_add(chip);
-
-		s3c24xx_gpiolib_attach_ofnode(chip, S3C24XX_PA_GPIO, i * 0x10);
 	}
 }
 
@@ -3026,6 +2963,10 @@ static __init int samsung_gpiolib_init(v
 	*/
 	struct device_node *pctrl_np;
 	static const struct of_device_id exynos_pinctrl_ids[] = {
+		{ .compatible = "samsung,s3c2412-pinctrl", },
+		{ .compatible = "samsung,s3c2416-pinctrl", },
+		{ .compatible = "samsung,s3c2440-pinctrl", },
+		{ .compatible = "samsung,s3c2450-pinctrl", },
 		{ .compatible = "samsung,exynos4210-pinctrl", },
 		{ .compatible = "samsung,exynos4x12-pinctrl", },
 		{ .compatible = "samsung,exynos5250-pinctrl", },
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-sta2x11.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-sta2x11.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-sta2x11.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-sta2x11.c	2013-08-25 20:43:22.000000000 -0400
@@ -371,8 +371,12 @@ static int gsta_probe(struct platform_de
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 
 	chip = devm_kzalloc(&dev->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
 	chip->dev = &dev->dev;
-	chip->reg_base = devm_request_and_ioremap(&dev->dev, res);
+	chip->reg_base = devm_ioremap_resource(&dev->dev, res);
+	if (IS_ERR(chip->reg_base))
+		return PTR_ERR(chip->reg_base);
 
 	for (i = 0; i < GSTA_NR_BLOCKS; i++) {
 		chip->regs[i] = chip->reg_base + i * 4096;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-stmpe.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-stmpe.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-stmpe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-stmpe.c	2013-08-25 20:43:22.000000000 -0400
@@ -271,8 +271,8 @@ static irqreturn_t stmpe_gpio_irq(int ir
 	return IRQ_HANDLED;
 }
 
-int stmpe_gpio_irq_map(struct irq_domain *d, unsigned int virq,
-		       irq_hw_number_t hwirq)
+static int stmpe_gpio_irq_map(struct irq_domain *d, unsigned int virq,
+			      irq_hw_number_t hwirq)
 {
 	struct stmpe_gpio *stmpe_gpio = d->host_data;
 
@@ -292,7 +292,7 @@ int stmpe_gpio_irq_map(struct irq_domain
 	return 0;
 }
 
-void stmpe_gpio_irq_unmap(struct irq_domain *d, unsigned int virq)
+static void stmpe_gpio_irq_unmap(struct irq_domain *d, unsigned int virq)
 {
 #ifdef CONFIG_ARM
 	set_irq_flags(virq, 0);
@@ -431,7 +431,6 @@ static int stmpe_gpio_remove(struct plat
 	if (irq >= 0)
 		free_irq(irq, stmpe_gpio);
 
-	platform_set_drvdata(pdev, NULL);
 	kfree(stmpe_gpio);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-sx150x.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-sx150x.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-sx150x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-sx150x.c	2013-08-25 20:43:22.000000000 -0400
@@ -548,7 +548,8 @@ static int sx150x_install_irq_chip(struc
 #endif
 	}
 
-	err = request_threaded_irq(irq_summary,
+	err = devm_request_threaded_irq(&chip->client->dev,
+				irq_summary,
 				NULL,
 				sx150x_irq_thread_fn,
 				IRQF_SHARED | IRQF_TRIGGER_FALLING,
@@ -567,8 +568,6 @@ static void sx150x_remove_irq_chip(struc
 	unsigned n;
 	unsigned irq;
 
-	free_irq(chip->irq_summary, chip);
-
 	for (n = 0; n < chip->dev_cfg->ngpios; ++n) {
 		irq = chip->irq_base + n;
 		irq_set_chip_and_handler(irq, NULL, NULL);
@@ -591,18 +590,19 @@ static int sx150x_probe(struct i2c_clien
 	if (!i2c_check_functionality(client->adapter, i2c_funcs))
 		return -ENOSYS;
 
-	chip = kzalloc(sizeof(struct sx150x_chip), GFP_KERNEL);
+	chip = devm_kzalloc(&client->dev,
+		sizeof(struct sx150x_chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
 
 	sx150x_init_chip(chip, client, id->driver_data, pdata);
 	rc = sx150x_init_hw(chip, pdata);
 	if (rc < 0)
-		goto probe_fail_pre_gpiochip_add;
+		return rc;
 
 	rc = gpiochip_add(&chip->gpio_chip);
-	if (rc < 0)
-		goto probe_fail_pre_gpiochip_add;
+	if (rc)
+		return rc;
 
 	if (pdata->irq_summary >= 0) {
 		rc = sx150x_install_irq_chip(chip,
@@ -617,8 +617,6 @@ static int sx150x_probe(struct i2c_clien
 	return 0;
 probe_fail_post_gpiochip_add:
 	WARN_ON(gpiochip_remove(&chip->gpio_chip) < 0);
-probe_fail_pre_gpiochip_add:
-	kfree(chip);
 	return rc;
 }
 
@@ -635,8 +633,6 @@ static int sx150x_remove(struct i2c_clie
 	if (chip->irq_summary >= 0)
 		sx150x_remove_irq_chip(chip);
 
-	kfree(chip);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-tc3589x.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-tc3589x.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-tc3589x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-tc3589x.c	2013-08-25 20:43:22.000000000 -0400
@@ -407,7 +407,6 @@ static int tc3589x_gpio_remove(struct pl
 
 	free_irq(irq, tc3589x_gpio);
 
-	platform_set_drvdata(pdev, NULL);
 	kfree(tc3589x_gpio);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-timberdale.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-timberdale.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-timberdale.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-timberdale.c	2013-08-25 20:43:22.000000000 -0400
@@ -342,8 +342,6 @@ static int timbgpio_remove(struct platfo
 	release_mem_region(iomem->start, resource_size(iomem));
 	kfree(tgpio);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-vx855.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-vx855.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-vx855.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-vx855.c	2013-08-25 20:43:22.000000000 -0400
@@ -279,7 +279,6 @@ out_release:
 		release_region(res_gpi->start, resource_size(res_gpi));
 	if (vg->gpo_reserved)
 		release_region(res_gpi->start, resource_size(res_gpo));
-	platform_set_drvdata(pdev, NULL);
 	kfree(vg);
 	return ret;
 }
@@ -301,7 +300,6 @@ static int vx855gpio_remove(struct platf
 		release_region(res->start, resource_size(res));
 	}
 
-	platform_set_drvdata(pdev, NULL);
 	kfree(vg);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/gpio-xilinx.c linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-xilinx.c
--- linux-libre-3.10-gnu/drivers/gpio/gpio-xilinx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/gpio-xilinx.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- * Xilinx gpio driver
+ * Xilinx gpio driver for xps/axi_gpio IP.
  *
- * Copyright 2008 Xilinx, Inc.
+ * Copyright 2008 - 2013 Xilinx, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2
@@ -12,6 +12,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/bitops.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/module.h>
@@ -26,11 +27,31 @@
 #define XGPIO_DATA_OFFSET   (0x0)	/* Data register  */
 #define XGPIO_TRI_OFFSET    (0x4)	/* I/O direction register  */
 
+#define XGPIO_CHANNEL_OFFSET	0x8
+
+/* Read/Write access to the GPIO registers */
+#ifdef CONFIG_ARCH_ZYNQ
+# define xgpio_readreg(offset)		readl(offset)
+# define xgpio_writereg(offset, val)	writel(val, offset)
+#else
+# define xgpio_readreg(offset)		__raw_readl(offset)
+# define xgpio_writereg(offset, val)	__raw_writel(val, offset)
+#endif
+
+/**
+ * struct xgpio_instance - Stores information about GPIO device
+ * struct of_mm_gpio_chip mmchip: OF GPIO chip for memory mapped banks
+ * gpio_state: GPIO state shadow register
+ * gpio_dir: GPIO direction shadow register
+ * offset: GPIO channel offset
+ * gpio_lock: Lock used for synchronization
+ */
 struct xgpio_instance {
 	struct of_mm_gpio_chip mmchip;
-	u32 gpio_state;		/* GPIO state shadow register */
-	u32 gpio_dir;		/* GPIO direction shadow register */
-	spinlock_t gpio_lock;	/* Lock used for synchronization */
+	u32 gpio_state;
+	u32 gpio_dir;
+	u32 offset;
+	spinlock_t gpio_lock;
 };
 
 /**
@@ -44,8 +65,12 @@ struct xgpio_instance {
 static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct xgpio_instance *chip =
+	    container_of(mm_gc, struct xgpio_instance, mmchip);
 
-	return (in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) >> gpio) & 1;
+	void __iomem *regs = mm_gc->regs + chip->offset;
+
+	return !!(xgpio_readreg(regs + XGPIO_DATA_OFFSET) & BIT(gpio));
 }
 
 /**
@@ -63,15 +88,18 @@ static void xgpio_set(struct gpio_chip *
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 	struct xgpio_instance *chip =
 	    container_of(mm_gc, struct xgpio_instance, mmchip);
+	void __iomem *regs = mm_gc->regs;
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Write to GPIO signal and set its direction to output */
 	if (val)
-		chip->gpio_state |= 1 << gpio;
+		chip->gpio_state |= BIT(gpio);
 	else
-		chip->gpio_state &= ~(1 << gpio);
-	out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
+		chip->gpio_state &= ~BIT(gpio);
+
+	xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET,
+							 chip->gpio_state);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -91,12 +119,13 @@ static int xgpio_dir_in(struct gpio_chip
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 	struct xgpio_instance *chip =
 	    container_of(mm_gc, struct xgpio_instance, mmchip);
+	void __iomem *regs = mm_gc->regs;
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Set the GPIO bit in shadow register and set direction as input */
-	chip->gpio_dir |= (1 << gpio);
-	out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
+	chip->gpio_dir |= BIT(gpio);
+	xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -119,19 +148,21 @@ static int xgpio_dir_out(struct gpio_chi
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
 	struct xgpio_instance *chip =
 	    container_of(mm_gc, struct xgpio_instance, mmchip);
+	void __iomem *regs = mm_gc->regs;
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Write state of GPIO signal */
 	if (val)
-		chip->gpio_state |= 1 << gpio;
+		chip->gpio_state |= BIT(gpio);
 	else
-		chip->gpio_state &= ~(1 << gpio);
-	out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
+		chip->gpio_state &= ~BIT(gpio);
+	xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET,
+		       chip->gpio_state);
 
 	/* Clear the GPIO bit in shadow register and set direction as output */
-	chip->gpio_dir &= (~(1 << gpio));
-	out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
+	chip->gpio_dir &= ~BIT(gpio);
+	xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -147,8 +178,10 @@ static void xgpio_save_regs(struct of_mm
 	struct xgpio_instance *chip =
 	    container_of(mm_gc, struct xgpio_instance, mmchip);
 
-	out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
-	out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
+	xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_DATA_OFFSET,
+							chip->gpio_state);
+	xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_TRI_OFFSET,
+							 chip->gpio_dir);
 }
 
 /**
@@ -170,24 +203,20 @@ static int xgpio_of_probe(struct device_
 		return -ENOMEM;
 
 	/* Update GPIO state shadow register with default value */
-	tree_info = of_get_property(np, "xlnx,dout-default", NULL);
-	if (tree_info)
-		chip->gpio_state = be32_to_cpup(tree_info);
+	of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state);
+
+	/* By default, all pins are inputs */
+	chip->gpio_dir = 0xFFFFFFFF;
 
 	/* Update GPIO direction shadow register with default value */
-	chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */
-	tree_info = of_get_property(np, "xlnx,tri-default", NULL);
-	if (tree_info)
-		chip->gpio_dir = be32_to_cpup(tree_info);
+	of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir);
+
+	/* By default assume full GPIO controller */
+	chip->mmchip.gc.ngpio = 32;
 
 	/* Check device node and parent device node for device width */
-	chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */
-	tree_info = of_get_property(np, "xlnx,gpio-width", NULL);
-	if (!tree_info)
-		tree_info = of_get_property(np->parent,
-					    "xlnx,gpio-width", NULL);
-	if (tree_info)
-		chip->mmchip.gc.ngpio = be32_to_cpup(tree_info);
+	of_property_read_u32(np, "xlnx,gpio-width",
+			      (u32 *)&chip->mmchip.gc.ngpio);
 
 	spin_lock_init(&chip->gpio_lock);
 
@@ -206,6 +235,57 @@ static int xgpio_of_probe(struct device_
 		       np->full_name, status);
 		return status;
 	}
+
+	pr_info("XGpio: %s: registered, base is %d\n", np->full_name,
+							chip->mmchip.gc.base);
+
+	tree_info = of_get_property(np, "xlnx,is-dual", NULL);
+	if (tree_info && be32_to_cpup(tree_info)) {
+		chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+		if (!chip)
+			return -ENOMEM;
+
+		/* Add dual channel offset */
+		chip->offset = XGPIO_CHANNEL_OFFSET;
+
+		/* Update GPIO state shadow register with default value */
+		of_property_read_u32(np, "xlnx,dout-default-2",
+				     &chip->gpio_state);
+
+		/* By default, all pins are inputs */
+		chip->gpio_dir = 0xFFFFFFFF;
+
+		/* Update GPIO direction shadow register with default value */
+		of_property_read_u32(np, "xlnx,tri-default-2", &chip->gpio_dir);
+
+		/* By default assume full GPIO controller */
+		chip->mmchip.gc.ngpio = 32;
+
+		/* Check device node and parent device node for device width */
+		of_property_read_u32(np, "xlnx,gpio2-width",
+				     (u32 *)&chip->mmchip.gc.ngpio);
+
+		spin_lock_init(&chip->gpio_lock);
+
+		chip->mmchip.gc.direction_input = xgpio_dir_in;
+		chip->mmchip.gc.direction_output = xgpio_dir_out;
+		chip->mmchip.gc.get = xgpio_get;
+		chip->mmchip.gc.set = xgpio_set;
+
+		chip->mmchip.save_regs = xgpio_save_regs;
+
+		/* Call the OF gpio helper to setup and register the GPIO dev */
+		status = of_mm_gpiochip_add(np, &chip->mmchip);
+		if (status) {
+			kfree(chip);
+			pr_err("%s: error in probe function with status %d\n",
+			np->full_name, status);
+			return status;
+		}
+		pr_info("XGpio: %s: dual channel registered, base is %d\n",
+					np->full_name, chip->mmchip.gc.base);
+	}
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/Kconfig linux-libre-3.11-rc7-gnu/drivers/gpio/Kconfig
--- linux-libre-3.10-gnu/drivers/gpio/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -109,8 +109,11 @@ config GPIO_MAX730X
 comment "Memory mapped GPIO drivers:"
 
 config GPIO_CLPS711X
-	def_bool y
+	tristate "CLPS711X GPIO support"
 	depends on ARCH_CLPS711X
+	select GPIO_GENERIC
+	help
+	  Say yes here to support GPIO on CLPS711X SoCs.
 
 config GPIO_GENERIC_PLATFORM
 	tristate "Generic memory-mapped GPIO controller support (MMIO platform device)"
@@ -165,7 +168,7 @@ config GPIO_MSM_V1
 
 config GPIO_MSM_V2
 	tristate "Qualcomm MSM GPIO v2"
-	depends on GPIOLIB && ARCH_MSM
+	depends on GPIOLIB && OF && ARCH_MSM
 	help
 	  Say yes here to support the GPIO interface on ARM v7 based
 	  Qualcomm MSM chips.  Most of the pins on the MSM can be
@@ -209,6 +212,13 @@ config GPIO_RCAR
 	help
 	  Say yes here to support GPIO on Renesas R-Car SoCs.
 
+config GPIO_SAMSUNG
+	bool
+	depends on PLAT_SAMSUNG
+	help
+	  Legacy GPIO support. Use only for platforms without support for
+	  pinctrl.
+
 config GPIO_SPEAR_SPICS
 	bool "ST SPEAr13xx SPI Chip Select as GPIO support"
 	depends on PLAT_SPEAR
@@ -234,7 +244,7 @@ config GPIO_TS5500
 
 config GPIO_XILINX
 	bool "Xilinx GPIO support"
-	depends on PPC_OF || MICROBLAZE
+	depends on PPC_OF || MICROBLAZE || ARCH_ZYNQ
 	help
 	  Say yes here to support the Xilinx FPGA GPIO device
 
@@ -330,7 +340,7 @@ config GPIO_MAX7300
 	depends on I2C
 	select GPIO_MAX730X
 	help
-	  GPIO driver for Maxim MAX7301 I2C-based GPIO expander.
+	  GPIO driver for Maxim MAX7300 I2C-based GPIO expander.
 
 config GPIO_MAX732X
 	tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpio/Makefile linux-libre-3.11-rc7-gnu/drivers/gpio/Makefile
--- linux-libre-3.10-gnu/drivers/gpio/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpio/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -59,7 +59,7 @@ obj-$(CONFIG_GPIO_PXA)		+= gpio-pxa.o
 obj-$(CONFIG_GPIO_RC5T583)	+= gpio-rc5t583.o
 obj-$(CONFIG_GPIO_RDC321X)	+= gpio-rdc321x.o
 obj-$(CONFIG_GPIO_RCAR)		+= gpio-rcar.o
-obj-$(CONFIG_PLAT_SAMSUNG)	+= gpio-samsung.o
+obj-$(CONFIG_GPIO_SAMSUNG)	+= gpio-samsung.o
 obj-$(CONFIG_ARCH_SA1100)	+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SCH)		+= gpio-sch.o
 obj-$(CONFIG_GPIO_SODAVILLE)	+= gpio-sodaville.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/ast/ast_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ast/ast_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/ast/ast_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ast/ast_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -348,8 +348,24 @@ int ast_gem_create(struct drm_device *de
 int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr);
 int ast_bo_unpin(struct ast_bo *bo);
 
-int ast_bo_reserve(struct ast_bo *bo, bool no_wait);
-void ast_bo_unreserve(struct ast_bo *bo);
+static inline int ast_bo_reserve(struct ast_bo *bo, bool no_wait)
+{
+	int ret;
+
+	ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
+	if (ret) {
+		if (ret != -ERESTARTSYS && ret != -EBUSY)
+			DRM_ERROR("reserve failed %p\n", bo);
+		return ret;
+	}
+	return 0;
+}
+
+static inline void ast_bo_unreserve(struct ast_bo *bo)
+{
+	ttm_bo_unreserve(&bo->bo);
+}
+
 void ast_ttm_placement(struct ast_bo *bo, int domain);
 int ast_bo_push_sysram(struct ast_bo *bo);
 int ast_mmap(struct file *filp, struct vm_area_struct *vma);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/ast/ast_fb.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ast/ast_fb.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/ast/ast_fb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ast/ast_fb.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,7 +51,7 @@ static void ast_dirty_update(struct ast_
 	struct ast_bo *bo;
 	int src_offset, dst_offset;
 	int bpp = (afbdev->afb.base.bits_per_pixel + 7)/8;
-	int ret;
+	int ret = -EBUSY;
 	bool unmap = false;
 	bool store_for_later = false;
 	int x2, y2;
@@ -65,7 +65,8 @@ static void ast_dirty_update(struct ast_
 	 * then the BO is being moved and we should
 	 * store up the damage until later.
 	 */
-	ret = ast_bo_reserve(bo, true);
+	if (!in_interrupt())
+		ret = ast_bo_reserve(bo, true);
 	if (ret) {
 		if (ret != -EBUSY)
 			return;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/ast/ast_ttm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ast/ast_ttm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/ast/ast_ttm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ast/ast_ttm.c	2013-08-25 20:43:22.000000000 -0400
@@ -271,26 +271,19 @@ int ast_mm_init(struct ast_private *ast)
 		return ret;
 	}
 
-	ast->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
-				    pci_resource_len(dev->pdev, 0),
-				    DRM_MTRR_WC);
+	ast->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0),
+					pci_resource_len(dev->pdev, 0));
 
 	return 0;
 }
 
 void ast_mm_fini(struct ast_private *ast)
 {
-	struct drm_device *dev = ast->dev;
 	ttm_bo_device_release(&ast->ttm.bdev);
 
 	ast_ttm_global_release(ast);
 
-	if (ast->fb_mtrr >= 0) {
-		drm_mtrr_del(ast->fb_mtrr,
-			     pci_resource_start(dev->pdev, 0),
-			     pci_resource_len(dev->pdev, 0), DRM_MTRR_WC);
-		ast->fb_mtrr = -1;
-	}
+	arch_phys_wc_del(ast->fb_mtrr);
 }
 
 void ast_ttm_placement(struct ast_bo *bo, int domain)
@@ -310,24 +303,6 @@ void ast_ttm_placement(struct ast_bo *bo
 	bo->placement.num_busy_placement = c;
 }
 
-int ast_bo_reserve(struct ast_bo *bo, bool no_wait)
-{
-	int ret;
-
-	ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
-	if (ret) {
-		if (ret != -ERESTARTSYS && ret != -EBUSY)
-			DRM_ERROR("reserve failed %p\n", bo);
-		return ret;
-	}
-	return 0;
-}
-
-void ast_bo_unreserve(struct ast_bo *bo)
-{
-	ttm_bo_unreserve(&bo->bo);
-}
-
 int ast_bo_create(struct drm_device *dev, int size, int align,
 		  uint32_t flags, struct ast_bo **pastbo)
 {
@@ -348,6 +323,7 @@ int ast_bo_create(struct drm_device *dev
 
 	astbo->gem.driver_private = NULL;
 	astbo->bo.bdev = &ast->ttm.bdev;
+	astbo->bo.bdev->dev_mapping = dev->dev_mapping;
 
 	ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/cirrus/cirrus_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/cirrus/cirrus_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/cirrus/cirrus_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/cirrus/cirrus_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -240,8 +240,25 @@ void cirrus_ttm_placement(struct cirrus_
 int cirrus_bo_create(struct drm_device *dev, int size, int align,
 		     uint32_t flags, struct cirrus_bo **pcirrusbo);
 int cirrus_mmap(struct file *filp, struct vm_area_struct *vma);
-int cirrus_bo_reserve(struct cirrus_bo *bo, bool no_wait);
-void cirrus_bo_unreserve(struct cirrus_bo *bo);
+
+static inline int cirrus_bo_reserve(struct cirrus_bo *bo, bool no_wait)
+{
+	int ret;
+
+	ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
+	if (ret) {
+		if (ret != -ERESTARTSYS && ret != -EBUSY)
+			DRM_ERROR("reserve failed %p\n", bo);
+		return ret;
+	}
+	return 0;
+}
+
+static inline void cirrus_bo_unreserve(struct cirrus_bo *bo)
+{
+	ttm_bo_unreserve(&bo->bo);
+}
+
 int cirrus_bo_push_sysram(struct cirrus_bo *bo);
 int cirrus_bo_pin(struct cirrus_bo *bo, u32 pl_flag, u64 *gpu_addr);
 #endif				/* __CIRRUS_DRV_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/cirrus/cirrus_fbdev.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/cirrus/cirrus_fbdev.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/cirrus/cirrus_fbdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/cirrus/cirrus_fbdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@ static void cirrus_dirty_update(struct c
 	struct cirrus_bo *bo;
 	int src_offset, dst_offset;
 	int bpp = (afbdev->gfb.base.bits_per_pixel + 7)/8;
-	int ret;
+	int ret = -EBUSY;
 	bool unmap = false;
 	bool store_for_later = false;
 	int x2, y2;
@@ -39,7 +39,8 @@ static void cirrus_dirty_update(struct c
 	 * then the BO is being moved and we should
 	 * store up the damage until later.
 	 */
-	ret = cirrus_bo_reserve(bo, true);
+	if (!in_interrupt())
+		ret = cirrus_bo_reserve(bo, true);
 	if (ret) {
 		if (ret != -EBUSY)
 			return;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/cirrus/cirrus_ttm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/cirrus/cirrus_ttm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/cirrus/cirrus_ttm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/cirrus/cirrus_ttm.c	2013-08-25 20:43:22.000000000 -0400
@@ -271,9 +271,8 @@ int cirrus_mm_init(struct cirrus_device
 		return ret;
 	}
 
-	cirrus->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
-				    pci_resource_len(dev->pdev, 0),
-				    DRM_MTRR_WC);
+	cirrus->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0),
+					   pci_resource_len(dev->pdev, 0));
 
 	cirrus->mm_inited = true;
 	return 0;
@@ -281,8 +280,6 @@ int cirrus_mm_init(struct cirrus_device
 
 void cirrus_mm_fini(struct cirrus_device *cirrus)
 {
-	struct drm_device *dev = cirrus->dev;
-
 	if (!cirrus->mm_inited)
 		return;
 
@@ -290,12 +287,8 @@ void cirrus_mm_fini(struct cirrus_device
 
 	cirrus_ttm_global_release(cirrus);
 
-	if (cirrus->fb_mtrr >= 0) {
-		drm_mtrr_del(cirrus->fb_mtrr,
-			     pci_resource_start(dev->pdev, 0),
-			     pci_resource_len(dev->pdev, 0), DRM_MTRR_WC);
-		cirrus->fb_mtrr = -1;
-	}
+	arch_phys_wc_del(cirrus->fb_mtrr);
+	cirrus->fb_mtrr = 0;
 }
 
 void cirrus_ttm_placement(struct cirrus_bo *bo, int domain)
@@ -315,24 +308,6 @@ void cirrus_ttm_placement(struct cirrus_
 	bo->placement.num_busy_placement = c;
 }
 
-int cirrus_bo_reserve(struct cirrus_bo *bo, bool no_wait)
-{
-	int ret;
-
-	ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
-	if (ret) {
-		if (ret != -ERESTARTSYS && ret != -EBUSY)
-			DRM_ERROR("reserve failed %p\n", bo);
-		return ret;
-	}
-	return 0;
-}
-
-void cirrus_bo_unreserve(struct cirrus_bo *bo)
-{
-	ttm_bo_unreserve(&bo->bo);
-}
-
 int cirrus_bo_create(struct drm_device *dev, int size, int align,
 		  uint32_t flags, struct cirrus_bo **pcirrusbo)
 {
@@ -353,6 +328,7 @@ int cirrus_bo_create(struct drm_device *
 
 	cirrusbo->gem.driver_private = NULL;
 	cirrusbo->bo.bdev = &cirrus->ttm.bdev;
+	cirrusbo->bo.bdev->dev_mapping = dev->dev_mapping;
 
 	cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_bufs.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_bufs.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_bufs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_bufs.c	2013-08-25 20:43:22.000000000 -0400
@@ -210,12 +210,16 @@ static int drm_addmap_core(struct drm_de
 		if (drm_core_has_MTRR(dev)) {
 			if (map->type == _DRM_FRAME_BUFFER ||
 			    (map->flags & _DRM_WRITE_COMBINING)) {
-				map->mtrr = mtrr_add(map->offset, map->size,
-						     MTRR_TYPE_WRCOMB, 1);
+				map->mtrr =
+					arch_phys_wc_add(map->offset, map->size);
 			}
 		}
 		if (map->type == _DRM_REGISTERS) {
-			map->handle = ioremap(map->offset, map->size);
+			if (map->flags & _DRM_WRITE_COMBINING)
+				map->handle = ioremap_wc(map->offset,
+							 map->size);
+			else
+				map->handle = ioremap(map->offset, map->size);
 			if (!map->handle) {
 				kfree(map);
 				return -ENOMEM;
@@ -410,6 +414,15 @@ int drm_addmap_ioctl(struct drm_device *
 
 	/* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */
 	map->handle = (void *)(unsigned long)maplist->user_token;
+
+	/*
+	 * It appears that there are no users of this value whatsoever --
+	 * drmAddMap just discards it.  Let's not encourage its use.
+	 * (Keeping drm_addmap_core's returned mtrr value would be wrong --
+	 *  it's not a real mtrr index anymore.)
+	 */
+	map->mtrr = -1;
+
 	return 0;
 }
 
@@ -451,11 +464,8 @@ int drm_rmmap_locked(struct drm_device *
 		iounmap(map->handle);
 		/* FALLTHROUGH */
 	case _DRM_FRAME_BUFFER:
-		if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
-			int retcode;
-			retcode = mtrr_del(map->mtrr, map->offset, map->size);
-			DRM_DEBUG("mtrr_del=%d\n", retcode);
-		}
+		if (drm_core_has_MTRR(dev))
+			arch_phys_wc_del(map->mtrr);
 		break;
 	case _DRM_SHM:
 		vfree(map->handle);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_crtc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_crtc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_crtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_crtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,7 @@
  *      Dave Airlie <airlied@linux.ie>
  *      Jesse Barnes <jesse.barnes@intel.com>
  */
+#include <linux/ctype.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/export.h>
@@ -91,7 +92,7 @@ EXPORT_SYMBOL(drm_warn_on_modeset_not_al
 
 /* Avoid boilerplate.  I'm tired of typing. */
 #define DRM_ENUM_NAME_FN(fnname, list)				\
-	char *fnname(int val)					\
+	const char *fnname(int val)				\
 	{							\
 		int i;						\
 		for (i = 0; i < ARRAY_SIZE(list); i++) {	\
@@ -104,7 +105,7 @@ EXPORT_SYMBOL(drm_warn_on_modeset_not_al
 /*
  * Global properties
  */
-static struct drm_prop_enum_list drm_dpms_enum_list[] =
+static const struct drm_prop_enum_list drm_dpms_enum_list[] =
 {	{ DRM_MODE_DPMS_ON, "On" },
 	{ DRM_MODE_DPMS_STANDBY, "Standby" },
 	{ DRM_MODE_DPMS_SUSPEND, "Suspend" },
@@ -116,7 +117,7 @@ DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_
 /*
  * Optional properties
  */
-static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
+static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
 {
 	{ DRM_MODE_SCALE_NONE, "None" },
 	{ DRM_MODE_SCALE_FULLSCREEN, "Full" },
@@ -124,7 +125,7 @@ static struct drm_prop_enum_list drm_sca
 	{ DRM_MODE_SCALE_ASPECT, "Full aspect" },
 };
 
-static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
+static const struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
 {
 	{ DRM_MODE_DITHERING_OFF, "Off" },
 	{ DRM_MODE_DITHERING_ON, "On" },
@@ -134,7 +135,7 @@ static struct drm_prop_enum_list drm_dit
 /*
  * Non-global properties, but "required" for certain connectors.
  */
-static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
+static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
 {
 	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
 	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
@@ -143,7 +144,7 @@ static struct drm_prop_enum_list drm_dvi
 
 DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
 
-static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
+static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
 {
 	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
 	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
@@ -153,7 +154,7 @@ static struct drm_prop_enum_list drm_dvi
 DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
 		 drm_dvi_i_subconnector_enum_list)
 
-static struct drm_prop_enum_list drm_tv_select_enum_list[] =
+static const struct drm_prop_enum_list drm_tv_select_enum_list[] =
 {
 	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
 	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
@@ -164,7 +165,7 @@ static struct drm_prop_enum_list drm_tv_
 
 DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
 
-static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
+static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
 {
 	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
 	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
@@ -176,7 +177,7 @@ static struct drm_prop_enum_list drm_tv_
 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
 		 drm_tv_subconnector_enum_list)
 
-static struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
+static const struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
 	{ DRM_MODE_DIRTY_OFF,      "Off"      },
 	{ DRM_MODE_DIRTY_ON,       "On"       },
 	{ DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
@@ -184,7 +185,7 @@ static struct drm_prop_enum_list drm_dir
 
 struct drm_conn_prop_enum_list {
 	int type;
-	char *name;
+	const char *name;
 	int count;
 };
 
@@ -210,7 +211,7 @@ static struct drm_conn_prop_enum_list dr
 	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual", 0},
 };
 
-static struct drm_prop_enum_list drm_encoder_enum_list[] =
+static const struct drm_prop_enum_list drm_encoder_enum_list[] =
 {	{ DRM_MODE_ENCODER_NONE, "None" },
 	{ DRM_MODE_ENCODER_DAC, "DAC" },
 	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
@@ -219,7 +220,7 @@ static struct drm_prop_enum_list drm_enc
 	{ DRM_MODE_ENCODER_VIRTUAL, "Virtual" },
 };
 
-char *drm_get_encoder_name(struct drm_encoder *encoder)
+const char *drm_get_encoder_name(const struct drm_encoder *encoder)
 {
 	static char buf[32];
 
@@ -230,7 +231,7 @@ char *drm_get_encoder_name(struct drm_en
 }
 EXPORT_SYMBOL(drm_get_encoder_name);
 
-char *drm_get_connector_name(struct drm_connector *connector)
+const char *drm_get_connector_name(const struct drm_connector *connector)
 {
 	static char buf[32];
 
@@ -241,7 +242,7 @@ char *drm_get_connector_name(struct drm_
 }
 EXPORT_SYMBOL(drm_get_connector_name);
 
-char *drm_get_connector_status_name(enum drm_connector_status status)
+const char *drm_get_connector_status_name(enum drm_connector_status status)
 {
 	if (status == connector_status_connected)
 		return "connected";
@@ -252,6 +253,28 @@ char *drm_get_connector_status_name(enum
 }
 EXPORT_SYMBOL(drm_get_connector_status_name);
 
+static char printable_char(int c)
+{
+	return isascii(c) && isprint(c) ? c : '?';
+}
+
+const char *drm_get_format_name(uint32_t format)
+{
+	static char buf[32];
+
+	snprintf(buf, sizeof(buf),
+		 "%c%c%c%c %s-endian (0x%08x)",
+		 printable_char(format & 0xff),
+		 printable_char((format >> 8) & 0xff),
+		 printable_char((format >> 16) & 0xff),
+		 printable_char((format >> 24) & 0x7f),
+		 format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
+		 format);
+
+	return buf;
+}
+EXPORT_SYMBOL(drm_get_format_name);
+
 /**
  * drm_mode_object_get - allocate a new modeset identifier
  * @dev: DRM device
@@ -569,16 +592,8 @@ void drm_framebuffer_remove(struct drm_f
 		}
 
 		list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
-			if (plane->fb == fb) {
-				/* should turn off the crtc */
-				ret = plane->funcs->disable_plane(plane);
-				if (ret)
-					DRM_ERROR("failed to disable plane with busy fb\n");
-				/* disconnect the plane from the fb and crtc: */
-				__drm_framebuffer_unreference(plane->fb);
-				plane->fb = NULL;
-				plane->crtc = NULL;
-			}
+			if (plane->fb == fb)
+				drm_plane_force_disable(plane);
 		}
 		drm_modeset_unlock_all(dev);
 	}
@@ -593,7 +608,7 @@ EXPORT_SYMBOL(drm_framebuffer_remove);
  * @crtc: CRTC object to init
  * @funcs: callbacks for the new CRTC
  *
- * Inits a new object created as base part of an driver crtc object.
+ * Inits a new object created as base part of a driver crtc object.
  *
  * RETURNS:
  * Zero on success, error code on failure.
@@ -628,11 +643,12 @@ int drm_crtc_init(struct drm_device *dev
 EXPORT_SYMBOL(drm_crtc_init);
 
 /**
- * drm_crtc_cleanup - Cleans up the core crtc usage.
+ * drm_crtc_cleanup - Clean up the core crtc usage
  * @crtc: CRTC to cleanup
  *
- * Cleanup @crtc. Removes from drm modesetting space
- * does NOT free object, caller does that.
+ * This function cleans up @crtc and removes it from the DRM mode setting
+ * core. Note that the function does *not* free the crtc structure itself,
+ * this is the responsibility of the caller.
  */
 void drm_crtc_cleanup(struct drm_crtc *crtc)
 {
@@ -657,7 +673,7 @@ EXPORT_SYMBOL(drm_crtc_cleanup);
 void drm_mode_probed_add(struct drm_connector *connector,
 			 struct drm_display_mode *mode)
 {
-	list_add(&mode->head, &connector->probed_modes);
+	list_add_tail(&mode->head, &connector->probed_modes);
 }
 EXPORT_SYMBOL(drm_mode_probed_add);
 
@@ -803,6 +819,21 @@ void drm_encoder_cleanup(struct drm_enco
 }
 EXPORT_SYMBOL(drm_encoder_cleanup);
 
+/**
+ * drm_plane_init - Initialise a new plane object
+ * @dev: DRM device
+ * @plane: plane object to init
+ * @possible_crtcs: bitmask of possible CRTCs
+ * @funcs: callbacks for the new plane
+ * @formats: array of supported formats (%DRM_FORMAT_*)
+ * @format_count: number of elements in @formats
+ * @priv: plane is private (hidden from userspace)?
+ *
+ * Inits a new object created as base part of a driver plane object.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure.
+ */
 int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
 		   unsigned long possible_crtcs,
 		   const struct drm_plane_funcs *funcs,
@@ -851,6 +882,14 @@ int drm_plane_init(struct drm_device *de
 }
 EXPORT_SYMBOL(drm_plane_init);
 
+/**
+ * drm_plane_cleanup - Clean up the core plane usage
+ * @plane: plane to cleanup
+ *
+ * This function cleans up @plane and removes it from the DRM mode setting
+ * core. Note that the function does *not* free the plane structure itself,
+ * this is the responsibility of the caller.
+ */
 void drm_plane_cleanup(struct drm_plane *plane)
 {
 	struct drm_device *dev = plane->dev;
@@ -868,6 +907,32 @@ void drm_plane_cleanup(struct drm_plane
 EXPORT_SYMBOL(drm_plane_cleanup);
 
 /**
+ * drm_plane_force_disable - Forcibly disable a plane
+ * @plane: plane to disable
+ *
+ * Forces the plane to be disabled.
+ *
+ * Used when the plane's current framebuffer is destroyed,
+ * and when restoring fbdev mode.
+ */
+void drm_plane_force_disable(struct drm_plane *plane)
+{
+	int ret;
+
+	if (!plane->fb)
+		return;
+
+	ret = plane->funcs->disable_plane(plane);
+	if (ret)
+		DRM_ERROR("failed to disable plane with busy fb\n");
+	/* disconnect the plane from the fb and crtc: */
+	__drm_framebuffer_unreference(plane->fb);
+	plane->fb = NULL;
+	plane->crtc = NULL;
+}
+EXPORT_SYMBOL(drm_plane_force_disable);
+
+/**
  * drm_mode_create - create a new display mode
  * @dev: DRM device
  *
@@ -1740,7 +1805,7 @@ int drm_mode_getplane(struct drm_device
 
 	plane_resp->plane_id = plane->base.id;
 	plane_resp->possible_crtcs = plane->possible_crtcs;
-	plane_resp->gamma_size = plane->gamma_size;
+	plane_resp->gamma_size = 0;
 
 	/*
 	 * This ioctl is called twice, once to determine how much space is
@@ -1834,7 +1899,8 @@ int drm_mode_setplane(struct drm_device
 		if (fb->pixel_format == plane->format_types[i])
 			break;
 	if (i == plane->format_count) {
-		DRM_DEBUG_KMS("Invalid pixel format 0x%08x\n", fb->pixel_format);
+		DRM_DEBUG_KMS("Invalid pixel format %s\n",
+			      drm_get_format_name(fb->pixel_format));
 		ret = -EINVAL;
 		goto out;
 	}
@@ -1906,18 +1972,31 @@ out:
 int drm_mode_set_config_internal(struct drm_mode_set *set)
 {
 	struct drm_crtc *crtc = set->crtc;
-	struct drm_framebuffer *fb, *old_fb;
+	struct drm_framebuffer *fb;
+	struct drm_crtc *tmp;
 	int ret;
 
-	old_fb = crtc->fb;
+	/*
+	 * NOTE: ->set_config can also disable other crtcs (if we steal all
+	 * connectors from it), hence we need to refcount the fbs across all
+	 * crtcs. Atomic modeset will have saner semantics ...
+	 */
+	list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head)
+		tmp->old_fb = tmp->fb;
+
 	fb = set->fb;
 
 	ret = crtc->funcs->set_config(set);
 	if (ret == 0) {
-		if (old_fb)
-			drm_framebuffer_unreference(old_fb);
-		if (fb)
-			drm_framebuffer_reference(fb);
+		/* crtc->fb must be updated by ->set_config, enforces this. */
+		WARN_ON(fb != crtc->fb);
+	}
+
+	list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
+		if (tmp->fb)
+			drm_framebuffer_reference(tmp->fb);
+		if (tmp->old_fb)
+			drm_framebuffer_unreference(tmp->old_fb);
 	}
 
 	return ret;
@@ -2099,10 +2178,10 @@ out:
 	return ret;
 }
 
-int drm_mode_cursor_ioctl(struct drm_device *dev,
-			void *data, struct drm_file *file_priv)
+static int drm_mode_cursor_common(struct drm_device *dev,
+				  struct drm_mode_cursor2 *req,
+				  struct drm_file *file_priv)
 {
-	struct drm_mode_cursor *req = data;
 	struct drm_mode_object *obj;
 	struct drm_crtc *crtc;
 	int ret = 0;
@@ -2122,13 +2201,17 @@ int drm_mode_cursor_ioctl(struct drm_dev
 
 	mutex_lock(&crtc->mutex);
 	if (req->flags & DRM_MODE_CURSOR_BO) {
-		if (!crtc->funcs->cursor_set) {
+		if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) {
 			ret = -ENXIO;
 			goto out;
 		}
 		/* Turns off the cursor if handle is 0 */
-		ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
-					      req->width, req->height);
+		if (crtc->funcs->cursor_set2)
+			ret = crtc->funcs->cursor_set2(crtc, file_priv, req->handle,
+						      req->width, req->height, req->hot_x, req->hot_y);
+		else
+			ret = crtc->funcs->cursor_set(crtc, file_priv, req->handle,
+						      req->width, req->height);
 	}
 
 	if (req->flags & DRM_MODE_CURSOR_MOVE) {
@@ -2143,6 +2226,25 @@ out:
 	mutex_unlock(&crtc->mutex);
 
 	return ret;
+
+}
+int drm_mode_cursor_ioctl(struct drm_device *dev,
+			void *data, struct drm_file *file_priv)
+{
+	struct drm_mode_cursor *req = data;
+	struct drm_mode_cursor2 new_req;
+
+	memcpy(&new_req, req, sizeof(struct drm_mode_cursor));
+	new_req.hot_x = new_req.hot_y = 0;
+
+	return drm_mode_cursor_common(dev, &new_req, file_priv);
+}
+
+int drm_mode_cursor2_ioctl(struct drm_device *dev,
+			   void *data, struct drm_file *file_priv)
+{
+	struct drm_mode_cursor2 *req = data;
+	return drm_mode_cursor_common(dev, req, file_priv);
 }
 
 /* Original addfb only supported RGB formats, so figure out which one */
@@ -2312,7 +2414,8 @@ static int framebuffer_check(const struc
 
 	ret = format_check(r);
 	if (ret) {
-		DRM_DEBUG_KMS("bad framebuffer format 0x%08x\n", r->pixel_format);
+		DRM_DEBUG_KMS("bad framebuffer format %s\n",
+			      drm_get_format_name(r->pixel_format));
 		return ret;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_crtc_helper.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_crtc_helper.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_crtc_helper.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_crtc_helper.c	2013-08-25 20:43:22.000000000 -0400
@@ -189,13 +189,14 @@ prune:
 	if (list_empty(&connector->modes))
 		return 0;
 
+	list_for_each_entry(mode, &connector->modes, head)
+		mode->vrefresh = drm_mode_vrefresh(mode);
+
 	drm_mode_sort(&connector->modes);
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
 			drm_get_connector_name(connector));
 	list_for_each_entry(mode, &connector->modes, head) {
-		mode->vrefresh = drm_mode_vrefresh(mode);
-
 		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
 		drm_mode_debug_printmodeline(mode);
 	}
@@ -564,14 +565,13 @@ int drm_crtc_helper_set_config(struct dr
 
 	DRM_DEBUG_KMS("\n");
 
-	if (!set)
-		return -EINVAL;
-
-	if (!set->crtc)
-		return -EINVAL;
+	BUG_ON(!set);
+	BUG_ON(!set->crtc);
+	BUG_ON(!set->crtc->helper_private);
 
-	if (!set->crtc->helper_private)
-		return -EINVAL;
+	/* Enforce sane interface api - has been abused by the fb helper. */
+	BUG_ON(!set->mode && set->fb);
+	BUG_ON(set->fb && set->num_connectors == 0);
 
 	crtc_funcs = set->crtc->helper_private;
 
@@ -645,11 +645,6 @@ int drm_crtc_helper_set_config(struct dr
 			mode_changed = true;
 		} else if (set->fb == NULL) {
 			mode_changed = true;
-		} else if (set->fb->depth != set->crtc->fb->depth) {
-			mode_changed = true;
-		} else if (set->fb->bits_per_pixel !=
-			   set->crtc->fb->bits_per_pixel) {
-			mode_changed = true;
 		} else if (set->fb->pixel_format !=
 			   set->crtc->fb->pixel_format) {
 			mode_changed = true;
@@ -682,6 +677,11 @@ int drm_crtc_helper_set_config(struct dr
 					/* don't break so fail path works correct */
 					fail = 1;
 				break;
+
+				if (connector->dpms != DRM_MODE_DPMS_ON) {
+					DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
+					mode_changed = true;
+				}
 			}
 		}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -166,6 +166,7 @@ static const struct drm_ioctl_desc drm_i
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 };
 
 #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_edid.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_edid.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_edid.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_edid.c	2013-08-25 20:43:22.000000000 -0400
@@ -968,6 +968,9 @@ bool drm_edid_block_valid(u8 *raw_edid,
 	u8 csum = 0;
 	struct edid *edid = (struct edid *)raw_edid;
 
+	if (WARN_ON(!raw_edid))
+		return false;
+
 	if (edid_fixup > 8 || edid_fixup < 0)
 		edid_fixup = 6;
 
@@ -1010,15 +1013,15 @@ bool drm_edid_block_valid(u8 *raw_edid,
 		break;
 	}
 
-	return 1;
+	return true;
 
 bad:
-	if (raw_edid && print_bad_edid) {
+	if (print_bad_edid) {
 		printk(KERN_ERR "Raw EDID:\n");
 		print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1,
 			       raw_edid, EDID_LENGTH, false);
 	}
-	return 0;
+	return false;
 }
 EXPORT_SYMBOL(drm_edid_block_valid);
 
@@ -1706,11 +1709,11 @@ static struct drm_display_mode *drm_mode
 		return NULL;
 
 	if (pt->misc & DRM_EDID_PT_STEREO) {
-		printk(KERN_WARNING "stereo mode not supported\n");
+		DRM_DEBUG_KMS("stereo mode not supported\n");
 		return NULL;
 	}
 	if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) {
-		printk(KERN_WARNING "composite sync not supported\n");
+		DRM_DEBUG_KMS("composite sync not supported\n");
 	}
 
 	/* it is incorrect if hsync/vsync width is zero */
@@ -2321,6 +2324,31 @@ u8 *drm_find_cea_extension(struct edid *
 }
 EXPORT_SYMBOL(drm_find_cea_extension);
 
+/*
+ * Calculate the alternate clock for the CEA mode
+ * (60Hz vs. 59.94Hz etc.)
+ */
+static unsigned int
+cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
+{
+	unsigned int clock = cea_mode->clock;
+
+	if (cea_mode->vrefresh % 6 != 0)
+		return clock;
+
+	/*
+	 * edid_cea_modes contains the 59.94Hz
+	 * variant for 240 and 480 line modes,
+	 * and the 60Hz variant otherwise.
+	 */
+	if (cea_mode->vdisplay == 240 || cea_mode->vdisplay == 480)
+		clock = clock * 1001 / 1000;
+	else
+		clock = DIV_ROUND_UP(clock * 1000, 1001);
+
+	return clock;
+}
+
 /**
  * drm_match_cea_mode - look for a CEA mode matching given mode
  * @to_match: display mode
@@ -2339,21 +2367,9 @@ u8 drm_match_cea_mode(const struct drm_d
 		const struct drm_display_mode *cea_mode = &edid_cea_modes[mode];
 		unsigned int clock1, clock2;
 
-		clock1 = clock2 = cea_mode->clock;
-
 		/* Check both 60Hz and 59.94Hz */
-		if (cea_mode->vrefresh % 6 == 0) {
-			/*
-			 * edid_cea_modes contains the 59.94Hz
-			 * variant for 240 and 480 line modes,
-			 * and the 60Hz variant otherwise.
-			 */
-			if (cea_mode->vdisplay == 240 ||
-			    cea_mode->vdisplay == 480)
-				clock1 = clock1 * 1001 / 1000;
-			else
-				clock2 = DIV_ROUND_UP(clock2 * 1000, 1001);
-		}
+		clock1 = cea_mode->clock;
+		clock2 = cea_mode_alternate_clock(cea_mode);
 
 		if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
 		     KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
@@ -2364,6 +2380,66 @@ u8 drm_match_cea_mode(const struct drm_d
 }
 EXPORT_SYMBOL(drm_match_cea_mode);
 
+static int
+add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_display_mode *mode, *tmp;
+	LIST_HEAD(list);
+	int modes = 0;
+
+	/* Don't add CEA modes if the CEA extension block is missing */
+	if (!drm_find_cea_extension(edid))
+		return 0;
+
+	/*
+	 * Go through all probed modes and create a new mode
+	 * with the alternate clock for certain CEA modes.
+	 */
+	list_for_each_entry(mode, &connector->probed_modes, head) {
+		const struct drm_display_mode *cea_mode;
+		struct drm_display_mode *newmode;
+		u8 cea_mode_idx = drm_match_cea_mode(mode) - 1;
+		unsigned int clock1, clock2;
+
+		if (cea_mode_idx >= ARRAY_SIZE(edid_cea_modes))
+			continue;
+
+		cea_mode = &edid_cea_modes[cea_mode_idx];
+
+		clock1 = cea_mode->clock;
+		clock2 = cea_mode_alternate_clock(cea_mode);
+
+		if (clock1 == clock2)
+			continue;
+
+		if (mode->clock != clock1 && mode->clock != clock2)
+			continue;
+
+		newmode = drm_mode_duplicate(dev, cea_mode);
+		if (!newmode)
+			continue;
+
+		/*
+		 * The current mode could be either variant. Make
+		 * sure to pick the "other" clock for the new mode.
+		 */
+		if (mode->clock != clock1)
+			newmode->clock = clock1;
+		else
+			newmode->clock = clock2;
+
+		list_add_tail(&newmode->head, &list);
+	}
+
+	list_for_each_entry_safe(mode, tmp, &list, head) {
+		list_del(&mode->head);
+		drm_mode_probed_add(connector, mode);
+		modes++;
+	}
+
+	return modes;
+}
 
 static int
 do_cea_modes (struct drm_connector *connector, u8 *db, u8 len)
@@ -2946,6 +3022,7 @@ int drm_add_edid_modes(struct drm_connec
 	if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
 		num_modes += add_inferred_modes(connector, edid);
 	num_modes += add_cea_modes(connector, edid);
+	num_modes += add_alternate_cea_modes(connector, edid);
 
 	if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
 		edid_fixup_preferred(connector, quirks);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_edid_load.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_edid_load.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_edid_load.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_edid_load.c	2013-08-25 20:43:22.000000000 -0400
@@ -133,8 +133,8 @@ static u8 generic_edid[GENERIC_EDIDS][12
 	},
 };
 
-static u8 *edid_load(struct drm_connector *connector, char *name,
-			char *connector_name)
+static u8 *edid_load(struct drm_connector *connector, const char *name,
+			const char *connector_name)
 {
 	const struct firmware *fw;
 	struct platform_device *pdev;
@@ -186,12 +186,11 @@ static u8 *edid_load(struct drm_connecto
 		goto relfw_out;
 	}
 
-	edid = kmalloc(fwsize, GFP_KERNEL);
+	edid = kmemdup(fwdata, fwsize, GFP_KERNEL);
 	if (edid == NULL) {
 		err = -ENOMEM;
 		goto relfw_out;
 	}
-	memcpy(edid, fwdata, fwsize);
 
 	if (!drm_edid_block_valid(edid, 0, print_bad_edid)) {
 		connector->bad_edid_counter++;
@@ -243,7 +242,7 @@ out:
 
 int drm_load_edid_firmware(struct drm_connector *connector)
 {
-	char *connector_name = drm_get_connector_name(connector);
+	const char *connector_name = drm_get_connector_name(connector);
 	char *edidname = edid_firmware, *last, *colon;
 	int ret;
 	struct edid *edid;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_fb_cma_helper.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_fb_cma_helper.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_fb_cma_helper.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_fb_cma_helper.c	2013-08-25 20:43:22.000000000 -0400
@@ -92,7 +92,7 @@ static struct drm_fb_cma *drm_fb_cma_all
 
 	ret = drm_framebuffer_init(dev, &fb_cma->fb, &drm_fb_cma_funcs);
 	if (ret) {
-		dev_err(dev->dev, "Failed to initalize framebuffer: %d\n", ret);
+		dev_err(dev->dev, "Failed to initialize framebuffer: %d\n", ret);
 		kfree(fb_cma);
 		return ERR_PTR(ret);
 	}
@@ -376,7 +376,7 @@ struct drm_fbdev_cma *drm_fbdev_cma_init
 
 	ret = drm_fb_helper_initial_config(helper, preferred_bpp);
 	if (ret < 0) {
-		dev_err(dev->dev, "Failed to set inital hw configuration.\n");
+		dev_err(dev->dev, "Failed to set initial hw configuration.\n");
 		goto err_drm_fb_helper_fini;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_fb_helper.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_fb_helper.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_fb_helper.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_fb_helper.c	2013-08-25 20:43:22.000000000 -0400
@@ -168,6 +168,9 @@ static void drm_fb_helper_save_lut_atomi
 	uint16_t *r_base, *g_base, *b_base;
 	int i;
 
+	if (helper->funcs->gamma_get == NULL)
+		return;
+
 	r_base = crtc->gamma_store;
 	g_base = r_base + crtc->gamma_size;
 	b_base = g_base + crtc->gamma_size;
@@ -284,13 +287,27 @@ EXPORT_SYMBOL(drm_fb_helper_debug_leave)
  */
 bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper)
 {
+	struct drm_device *dev = fb_helper->dev;
+	struct drm_plane *plane;
 	bool error = false;
-	int i, ret;
+	int i;
 
-	drm_warn_on_modeset_not_all_locked(fb_helper->dev);
+	drm_warn_on_modeset_not_all_locked(dev);
+
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head)
+		drm_plane_force_disable(plane);
 
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
+		struct drm_crtc *crtc = mode_set->crtc;
+		int ret;
+
+		if (crtc->funcs->cursor_set) {
+			ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0);
+			if (ret)
+				error = true;
+		}
+
 		ret = drm_mode_set_config_internal(mode_set);
 		if (ret)
 			error = true;
@@ -583,6 +600,14 @@ static int setcolreg(struct drm_crtc *cr
 		return 0;
 	}
 
+	/*
+	 * The driver really shouldn't advertise pseudo/directcolor
+	 * visuals if it can't deal with the palette.
+	 */
+	if (WARN_ON(!fb_helper->funcs->gamma_set ||
+		    !fb_helper->funcs->gamma_get))
+		return -EINVAL;
+
 	pindex = regno;
 
 	if (fb->bits_per_pixel == 16) {
@@ -626,12 +651,19 @@ static int setcolreg(struct drm_crtc *cr
 int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
 {
 	struct drm_fb_helper *fb_helper = info->par;
+	struct drm_device *dev = fb_helper->dev;
 	struct drm_crtc_helper_funcs *crtc_funcs;
 	u16 *red, *green, *blue, *transp;
 	struct drm_crtc *crtc;
 	int i, j, rc = 0;
 	int start;
 
+	drm_modeset_lock_all(dev);
+	if (!drm_fb_helper_is_bound(fb_helper)) {
+		drm_modeset_unlock_all(dev);
+		return -EBUSY;
+	}
+
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		crtc = fb_helper->crtc_info[i].mode_set.crtc;
 		crtc_funcs = crtc->helper_private;
@@ -654,10 +686,13 @@ int drm_fb_helper_setcmap(struct fb_cmap
 
 			rc = setcolreg(crtc, hred, hgreen, hblue, start++, info);
 			if (rc)
-				return rc;
+				goto out;
 		}
-		crtc_funcs->load_lut(crtc);
+		if (crtc_funcs->load_lut)
+			crtc_funcs->load_lut(crtc);
 	}
+ out:
+	drm_modeset_unlock_all(dev);
 	return rc;
 }
 EXPORT_SYMBOL(drm_fb_helper_setcmap);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_fops.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_fops.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_fops.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_fops.c	2013-08-25 20:43:22.000000000 -0400
@@ -271,6 +271,11 @@ static int drm_open_helper(struct inode
 	priv->uid = current_euid();
 	priv->pid = get_pid(task_pid(current));
 	priv->minor = idr_find(&drm_minors_idr, minor_id);
+	if (!priv->minor) {
+		ret = -ENODEV;
+		goto out_put_pid;
+	}
+
 	priv->ioctl_count = 0;
 	/* for compatibility root is always authenticated */
 	priv->authenticated = capable(CAP_SYS_ADMIN);
@@ -292,7 +297,7 @@ static int drm_open_helper(struct inode
 	if (dev->driver->open) {
 		ret = dev->driver->open(dev, priv);
 		if (ret < 0)
-			goto out_free;
+			goto out_prime_destroy;
 	}
 
 
@@ -304,7 +309,7 @@ static int drm_open_helper(struct inode
 		if (!priv->minor->master) {
 			mutex_unlock(&dev->struct_mutex);
 			ret = -ENOMEM;
-			goto out_free;
+			goto out_close;
 		}
 
 		priv->is_master = 1;
@@ -322,7 +327,7 @@ static int drm_open_helper(struct inode
 				drm_master_put(&priv->minor->master);
 				drm_master_put(&priv->master);
 				mutex_unlock(&dev->struct_mutex);
-				goto out_free;
+				goto out_close;
 			}
 		}
 		mutex_lock(&dev->struct_mutex);
@@ -333,7 +338,7 @@ static int drm_open_helper(struct inode
 				drm_master_put(&priv->minor->master);
 				drm_master_put(&priv->master);
 				mutex_unlock(&dev->struct_mutex);
-				goto out_free;
+				goto out_close;
 			}
 		}
 		mutex_unlock(&dev->struct_mutex);
@@ -367,7 +372,17 @@ static int drm_open_helper(struct inode
 #endif
 
 	return 0;
-      out_free:
+
+out_close:
+	if (dev->driver->postclose)
+		dev->driver->postclose(dev, priv);
+out_prime_destroy:
+	if (drm_core_check_feature(dev, DRIVER_PRIME))
+		drm_prime_destroy_file_private(&priv->prime);
+	if (dev->driver->driver_features & DRIVER_GEM)
+		drm_gem_release(dev, priv);
+out_put_pid:
+	put_pid(priv->pid);
 	kfree(priv);
 	filp->private_data = NULL;
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_gem.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_gem.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_gem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_gem.c	2013-08-25 20:43:22.000000000 -0400
@@ -108,12 +108,8 @@ drm_gem_init(struct drm_device *dev)
 		return -ENOMEM;
 	}
 
-	if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
-			DRM_FILE_PAGE_OFFSET_SIZE)) {
-		drm_ht_remove(&mm->offset_hash);
-		kfree(mm);
-		return -ENOMEM;
-	}
+	drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
+		    DRM_FILE_PAGE_OFFSET_SIZE);
 
 	return 0;
 }
@@ -453,25 +449,21 @@ drm_gem_flink_ioctl(struct drm_device *d
 	spin_lock(&dev->object_name_lock);
 	if (!obj->name) {
 		ret = idr_alloc(&dev->object_name_idr, obj, 1, 0, GFP_NOWAIT);
-		obj->name = ret;
-		args->name = (uint64_t) obj->name;
-		spin_unlock(&dev->object_name_lock);
-		idr_preload_end();
-
 		if (ret < 0)
 			goto err;
-		ret = 0;
+
+		obj->name = ret;
 
 		/* Allocate a reference for the name table.  */
 		drm_gem_object_reference(obj);
-	} else {
-		args->name = (uint64_t) obj->name;
-		spin_unlock(&dev->object_name_lock);
-		idr_preload_end();
-		ret = 0;
 	}
 
+	args->name = (uint64_t) obj->name;
+	ret = 0;
+
 err:
+	spin_unlock(&dev->object_name_lock);
+	idr_preload_end();
 	drm_gem_object_unreference_unlocked(obj);
 	return ret;
 }
@@ -644,6 +636,59 @@ void drm_gem_vm_close(struct vm_area_str
 }
 EXPORT_SYMBOL(drm_gem_vm_close);
 
+/**
+ * drm_gem_mmap_obj - memory map a GEM object
+ * @obj: the GEM object to map
+ * @obj_size: the object size to be mapped, in bytes
+ * @vma: VMA for the area to be mapped
+ *
+ * Set up the VMA to prepare mapping of the GEM object using the gem_vm_ops
+ * provided by the driver. Depending on their requirements, drivers can either
+ * provide a fault handler in their gem_vm_ops (in which case any accesses to
+ * the object will be trapped, to perform migration, GTT binding, surface
+ * register allocation, or performance monitoring), or mmap the buffer memory
+ * synchronously after calling drm_gem_mmap_obj.
+ *
+ * This function is mainly intended to implement the DMABUF mmap operation, when
+ * the GEM object is not looked up based on its fake offset. To implement the
+ * DRM mmap operation, drivers should use the drm_gem_mmap() function.
+ *
+ * NOTE: This function has to be protected with dev->struct_mutex
+ *
+ * Return 0 or success or -EINVAL if the object size is smaller than the VMA
+ * size, or if no gem_vm_ops are provided.
+ */
+int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
+		     struct vm_area_struct *vma)
+{
+	struct drm_device *dev = obj->dev;
+
+	lockdep_assert_held(&dev->struct_mutex);
+
+	/* Check for valid size. */
+	if (obj_size < vma->vm_end - vma->vm_start)
+		return -EINVAL;
+
+	if (!dev->driver->gem_vm_ops)
+		return -EINVAL;
+
+	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
+	vma->vm_ops = dev->driver->gem_vm_ops;
+	vma->vm_private_data = obj;
+	vma->vm_page_prot =  pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+
+	/* Take a ref for this mapping of the object, so that the fault
+	 * handler can dereference the mmap offset's pointer to the object.
+	 * This reference is cleaned up by the corresponding vm_close
+	 * (which should happen whether the vma was created by this call, or
+	 * by a vm_open due to mremap or partial unmap or whatever).
+	 */
+	drm_gem_object_reference(obj);
+
+	drm_vm_open_locked(dev, vma);
+	return 0;
+}
+EXPORT_SYMBOL(drm_gem_mmap_obj);
 
 /**
  * drm_gem_mmap - memory map routine for GEM objects
@@ -653,11 +698,9 @@ EXPORT_SYMBOL(drm_gem_vm_close);
  * If a driver supports GEM object mapping, mmap calls on the DRM file
  * descriptor will end up here.
  *
- * If we find the object based on the offset passed in (vma->vm_pgoff will
+ * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
  * contain the fake offset we created when the GTT map ioctl was called on
- * the object), we set up the driver fault handler so that any accesses
- * to the object can be trapped, to perform migration, GTT binding, surface
- * register allocation, or performance monitoring.
+ * the object) and map it with a call to drm_gem_mmap_obj().
  */
 int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 {
@@ -665,7 +708,6 @@ int drm_gem_mmap(struct file *filp, stru
 	struct drm_device *dev = priv->minor->dev;
 	struct drm_gem_mm *mm = dev->mm_private;
 	struct drm_local_map *map = NULL;
-	struct drm_gem_object *obj;
 	struct drm_hash_item *hash;
 	int ret = 0;
 
@@ -686,32 +728,7 @@ int drm_gem_mmap(struct file *filp, stru
 		goto out_unlock;
 	}
 
-	/* Check for valid size. */
-	if (map->size < vma->vm_end - vma->vm_start) {
-		ret = -EINVAL;
-		goto out_unlock;
-	}
-
-	obj = map->handle;
-	if (!obj->dev->driver->gem_vm_ops) {
-		ret = -EINVAL;
-		goto out_unlock;
-	}
-
-	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
-	vma->vm_ops = obj->dev->driver->gem_vm_ops;
-	vma->vm_private_data = map->handle;
-	vma->vm_page_prot =  pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
-
-	/* Take a ref for this mapping of the object, so that the fault
-	 * handler can dereference the mmap offset's pointer to the object.
-	 * This reference is cleaned up by the corresponding vm_close
-	 * (which should happen whether the vma was created by this call, or
-	 * by a vm_open due to mremap or partial unmap or whatever).
-	 */
-	drm_gem_object_reference(obj);
-
-	drm_vm_open_locked(dev, vma);
+	ret = drm_gem_mmap_obj(map->handle, map->size, vma);
 
 out_unlock:
 	mutex_unlock(&dev->struct_mutex);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_gem_cma_helper.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_gem_cma_helper.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_gem_cma_helper.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_gem_cma_helper.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/export.h>
+#include <linux/dma-buf.h>
 #include <linux/dma-mapping.h>
 
 #include <drm/drmP.h>
@@ -32,11 +33,44 @@ static unsigned int get_gem_mmap_offset(
 	return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT;
 }
 
-static void drm_gem_cma_buf_destroy(struct drm_device *drm,
-		struct drm_gem_cma_object *cma_obj)
+/*
+ * __drm_gem_cma_create - Create a GEM CMA object without allocating memory
+ * @drm: The drm device
+ * @size: The GEM object size
+ *
+ * This function creates and initializes a GEM CMA object of the given size, but
+ * doesn't allocate any memory to back the object.
+ *
+ * Return a struct drm_gem_cma_object* on success or ERR_PTR values on failure.
+ */
+static struct drm_gem_cma_object *
+__drm_gem_cma_create(struct drm_device *drm, unsigned int size)
 {
-	dma_free_writecombine(drm->dev, cma_obj->base.size, cma_obj->vaddr,
-			cma_obj->paddr);
+	struct drm_gem_cma_object *cma_obj;
+	struct drm_gem_object *gem_obj;
+	int ret;
+
+	cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
+	if (!cma_obj)
+		return ERR_PTR(-ENOMEM);
+
+	gem_obj = &cma_obj->base;
+
+	ret = drm_gem_object_init(drm, gem_obj, size);
+	if (ret)
+		goto error;
+
+	ret = drm_gem_create_mmap_offset(gem_obj);
+	if (ret) {
+		drm_gem_object_release(gem_obj);
+		goto error;
+	}
+
+	return cma_obj;
+
+error:
+	kfree(cma_obj);
+	return ERR_PTR(ret);
 }
 
 /*
@@ -49,44 +83,42 @@ struct drm_gem_cma_object *drm_gem_cma_c
 		unsigned int size)
 {
 	struct drm_gem_cma_object *cma_obj;
-	struct drm_gem_object *gem_obj;
+	struct sg_table *sgt = NULL;
 	int ret;
 
 	size = round_up(size, PAGE_SIZE);
 
-	cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
-	if (!cma_obj)
-		return ERR_PTR(-ENOMEM);
+	cma_obj = __drm_gem_cma_create(drm, size);
+	if (IS_ERR(cma_obj))
+		return cma_obj;
 
 	cma_obj->vaddr = dma_alloc_writecombine(drm->dev, size,
 			&cma_obj->paddr, GFP_KERNEL | __GFP_NOWARN);
 	if (!cma_obj->vaddr) {
-		dev_err(drm->dev, "failed to allocate buffer with size %d\n", size);
+		dev_err(drm->dev, "failed to allocate buffer with size %d\n",
+			size);
 		ret = -ENOMEM;
-		goto err_dma_alloc;
+		goto error;
 	}
 
-	gem_obj = &cma_obj->base;
+	sgt = kzalloc(sizeof(*cma_obj->sgt), GFP_KERNEL);
+	if (sgt == NULL) {
+		ret = -ENOMEM;
+		goto error;
+	}
 
-	ret = drm_gem_object_init(drm, gem_obj, size);
-	if (ret)
-		goto err_obj_init;
+	ret = dma_get_sgtable(drm->dev, sgt, cma_obj->vaddr,
+			      cma_obj->paddr, size);
+	if (ret < 0)
+		goto error;
 
-	ret = drm_gem_create_mmap_offset(gem_obj);
-	if (ret)
-		goto err_create_mmap_offset;
+	cma_obj->sgt = sgt;
 
 	return cma_obj;
 
-err_create_mmap_offset:
-	drm_gem_object_release(gem_obj);
-
-err_obj_init:
-	drm_gem_cma_buf_destroy(drm, cma_obj);
-
-err_dma_alloc:
-	kfree(cma_obj);
-
+error:
+	kfree(sgt);
+	drm_gem_cma_free_object(&cma_obj->base);
 	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_create);
@@ -143,11 +175,20 @@ void drm_gem_cma_free_object(struct drm_
 	if (gem_obj->map_list.map)
 		drm_gem_free_mmap_offset(gem_obj);
 
-	drm_gem_object_release(gem_obj);
-
 	cma_obj = to_drm_gem_cma_obj(gem_obj);
 
-	drm_gem_cma_buf_destroy(gem_obj->dev, cma_obj);
+	if (cma_obj->vaddr) {
+		dma_free_writecombine(gem_obj->dev->dev, cma_obj->base.size,
+				      cma_obj->vaddr, cma_obj->paddr);
+		if (cma_obj->sgt) {
+			sg_free_table(cma_obj->sgt);
+			kfree(cma_obj->sgt);
+		}
+	} else if (gem_obj->import_attach) {
+		drm_prime_gem_destroy(gem_obj, cma_obj->sgt);
+	}
+
+	drm_gem_object_release(gem_obj);
 
 	kfree(cma_obj);
 }
@@ -174,10 +215,7 @@ int drm_gem_cma_dumb_create(struct drm_f
 
 	cma_obj = drm_gem_cma_create_with_handle(file_priv, dev,
 			args->size, &args->handle);
-	if (IS_ERR(cma_obj))
-		return PTR_ERR(cma_obj);
-
-	return 0;
+	return PTR_RET(cma_obj);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create);
 
@@ -215,13 +253,26 @@ const struct vm_operations_struct drm_ge
 };
 EXPORT_SYMBOL_GPL(drm_gem_cma_vm_ops);
 
+static int drm_gem_cma_mmap_obj(struct drm_gem_cma_object *cma_obj,
+				struct vm_area_struct *vma)
+{
+	int ret;
+
+	ret = remap_pfn_range(vma, vma->vm_start, cma_obj->paddr >> PAGE_SHIFT,
+			vma->vm_end - vma->vm_start, vma->vm_page_prot);
+	if (ret)
+		drm_gem_vm_close(vma);
+
+	return ret;
+}
+
 /*
  * drm_gem_cma_mmap - (struct file_operation)->mmap callback function
  */
 int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma)
 {
-	struct drm_gem_object *gem_obj;
 	struct drm_gem_cma_object *cma_obj;
+	struct drm_gem_object *gem_obj;
 	int ret;
 
 	ret = drm_gem_mmap(filp, vma);
@@ -231,12 +282,7 @@ int drm_gem_cma_mmap(struct file *filp,
 	gem_obj = vma->vm_private_data;
 	cma_obj = to_drm_gem_cma_obj(gem_obj);
 
-	ret = remap_pfn_range(vma, vma->vm_start, cma_obj->paddr >> PAGE_SHIFT,
-			vma->vm_end - vma->vm_start, vma->vm_page_prot);
-	if (ret)
-		drm_gem_vm_close(vma);
-
-	return ret;
+	return drm_gem_cma_mmap_obj(cma_obj, vma);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_mmap);
 
@@ -270,3 +316,82 @@ void drm_gem_cma_describe(struct drm_gem
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_describe);
 #endif
+
+/* low-level interface prime helpers */
+struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj)
+{
+	struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj);
+	struct sg_table *sgt;
+	int ret;
+
+	sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+	if (!sgt)
+		return NULL;
+
+	ret = dma_get_sgtable(obj->dev->dev, sgt, cma_obj->vaddr,
+			      cma_obj->paddr, obj->size);
+	if (ret < 0)
+		goto out;
+
+	return sgt;
+
+out:
+	kfree(sgt);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_prime_get_sg_table);
+
+struct drm_gem_object *
+drm_gem_cma_prime_import_sg_table(struct drm_device *dev, size_t size,
+				  struct sg_table *sgt)
+{
+	struct drm_gem_cma_object *cma_obj;
+
+	if (sgt->nents != 1)
+		return ERR_PTR(-EINVAL);
+
+	/* Create a CMA GEM buffer. */
+	cma_obj = __drm_gem_cma_create(dev, size);
+	if (IS_ERR(cma_obj))
+		return ERR_PTR(PTR_ERR(cma_obj));
+
+	cma_obj->paddr = sg_dma_address(sgt->sgl);
+	cma_obj->sgt = sgt;
+
+	DRM_DEBUG_PRIME("dma_addr = 0x%x, size = %zu\n", cma_obj->paddr, size);
+
+	return &cma_obj->base;
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table);
+
+int drm_gem_cma_prime_mmap(struct drm_gem_object *obj,
+			   struct vm_area_struct *vma)
+{
+	struct drm_gem_cma_object *cma_obj;
+	struct drm_device *dev = obj->dev;
+	int ret;
+
+	mutex_lock(&dev->struct_mutex);
+	ret = drm_gem_mmap_obj(obj, obj->size, vma);
+	mutex_unlock(&dev->struct_mutex);
+	if (ret < 0)
+		return ret;
+
+	cma_obj = to_drm_gem_cma_obj(obj);
+	return drm_gem_cma_mmap_obj(cma_obj, vma);
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap);
+
+void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj)
+{
+	struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj);
+
+	return cma_obj->vaddr;
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap);
+
+void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+	/* Nothing to do */
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vunmap);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_ioctl.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_ioctl.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,6 +38,9 @@
 
 #include <linux/pci.h>
 #include <linux/export.h>
+#ifdef CONFIG_X86
+#include <asm/mtrr.h>
+#endif
 
 /**
  * Get the bus id.
@@ -181,7 +184,17 @@ int drm_getmap(struct drm_device *dev, v
 	map->type = r_list->map->type;
 	map->flags = r_list->map->flags;
 	map->handle = (void *)(unsigned long) r_list->user_token;
-	map->mtrr = r_list->map->mtrr;
+
+#ifdef CONFIG_X86
+	/*
+	 * There appears to be exactly one user of the mtrr index: dritest.
+	 * It's easy enough to keep it working on non-PAT systems.
+	 */
+	map->mtrr = phys_wc_to_mtrr_index(r_list->map->mtrr);
+#else
+	map->mtrr = -1;
+#endif
+
 	mutex_unlock(&dev->struct_mutex);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_irq.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_irq.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -708,7 +708,10 @@ int drm_calc_vbltimestamp_from_scanoutpo
 	/* Subtract time delta from raw timestamp to get final
 	 * vblank_time timestamp for end of vblank.
 	 */
-	etime = ktime_sub_ns(etime, delta_ns);
+	if (delta_ns < 0)
+		etime = ktime_add_ns(etime, -delta_ns);
+	else
+		etime = ktime_sub_ns(etime, delta_ns);
 	*vblank_time = ktime_to_timeval(etime);
 
 	DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_mm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_mm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_mm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_mm.c	2013-08-25 20:43:22.000000000 -0400
@@ -669,7 +669,7 @@ int drm_mm_clean(struct drm_mm * mm)
 }
 EXPORT_SYMBOL(drm_mm_clean);
 
-int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
+void drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
 {
 	INIT_LIST_HEAD(&mm->hole_stack);
 	INIT_LIST_HEAD(&mm->unused_nodes);
@@ -690,8 +690,6 @@ int drm_mm_init(struct drm_mm * mm, unsi
 	list_add_tail(&mm->head_node.hole_stack, &mm->hole_stack);
 
 	mm->color_adjust = NULL;
-
-	return 0;
 }
 EXPORT_SYMBOL(drm_mm_init);
 
@@ -699,8 +697,8 @@ void drm_mm_takedown(struct drm_mm * mm)
 {
 	struct drm_mm_node *entry, *next;
 
-	if (!list_empty(&mm->head_node.node_list)) {
-		DRM_ERROR("Memory manager not clean. Delaying takedown\n");
+	if (WARN(!list_empty(&mm->head_node.node_list),
+		 "Memory manager not clean. Delaying takedown\n")) {
 		return;
 	}
 
@@ -716,36 +714,37 @@ void drm_mm_takedown(struct drm_mm * mm)
 }
 EXPORT_SYMBOL(drm_mm_takedown);
 
-void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
+static unsigned long drm_mm_debug_hole(struct drm_mm_node *entry,
+				       const char *prefix)
 {
-	struct drm_mm_node *entry;
-	unsigned long total_used = 0, total_free = 0, total = 0;
 	unsigned long hole_start, hole_end, hole_size;
 
-	hole_start = drm_mm_hole_node_start(&mm->head_node);
-	hole_end = drm_mm_hole_node_end(&mm->head_node);
-	hole_size = hole_end - hole_start;
-	if (hole_size)
+	if (entry->hole_follows) {
+		hole_start = drm_mm_hole_node_start(entry);
+		hole_end = drm_mm_hole_node_end(entry);
+		hole_size = hole_end - hole_start;
 		printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n",
 			prefix, hole_start, hole_end,
 			hole_size);
-	total_free += hole_size;
+		return hole_size;
+	}
+
+	return 0;
+}
+
+void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
+{
+	struct drm_mm_node *entry;
+	unsigned long total_used = 0, total_free = 0, total = 0;
+
+	total_free += drm_mm_debug_hole(&mm->head_node, prefix);
 
 	drm_mm_for_each_node(entry, mm) {
 		printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: used\n",
 			prefix, entry->start, entry->start + entry->size,
 			entry->size);
 		total_used += entry->size;
-
-		if (entry->hole_follows) {
-			hole_start = drm_mm_hole_node_start(entry);
-			hole_end = drm_mm_hole_node_end(entry);
-			hole_size = hole_end - hole_start;
-			printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n",
-				prefix, hole_start, hole_end,
-				hole_size);
-			total_free += hole_size;
-		}
+		total_free += drm_mm_debug_hole(entry, prefix);
 	}
 	total = total_free + total_used;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_modes.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_modes.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_modes.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_modes.c	2013-08-25 20:43:22.000000000 -0400
@@ -535,6 +535,8 @@ int drm_display_mode_from_videomode(cons
 		dmode->flags |= DRM_MODE_FLAG_INTERLACE;
 	if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
 		dmode->flags |= DRM_MODE_FLAG_DBLSCAN;
+	if (vm->flags & DISPLAY_FLAGS_DOUBLECLK)
+		dmode->flags |= DRM_MODE_FLAG_DBLCLK;
 	drm_mode_set_name(dmode);
 
 	return 0;
@@ -787,16 +789,17 @@ EXPORT_SYMBOL(drm_mode_set_crtcinfo);
  * LOCKING:
  * None.
  *
- * Copy an existing mode into another mode, preserving the object id
- * of the destination mode.
+ * Copy an existing mode into another mode, preserving the object id and
+ * list head of the destination mode.
  */
 void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src)
 {
 	int id = dst->base.id;
+	struct list_head head = dst->head;
 
 	*dst = *src;
 	dst->base.id = id;
-	INIT_LIST_HEAD(&dst->head);
+	dst->head = head;
 }
 EXPORT_SYMBOL(drm_mode_copy);
 
@@ -1017,6 +1020,11 @@ static int drm_mode_compare(void *priv,
 	diff = b->hdisplay * b->vdisplay - a->hdisplay * a->vdisplay;
 	if (diff)
 		return diff;
+
+	diff = b->vrefresh - a->vrefresh;
+	if (diff)
+		return diff;
+
 	diff = b->clock - a->clock;
 	return diff;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_pci.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_pci.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -278,10 +278,10 @@ static int drm_pci_agp_init(struct drm_d
 		}
 		if (drm_core_has_MTRR(dev)) {
 			if (dev->agp)
-				dev->agp->agp_mtrr =
-					mtrr_add(dev->agp->agp_info.aper_base,
-						 dev->agp->agp_info.aper_size *
-						 1024 * 1024, MTRR_TYPE_WRCOMB, 1);
+				dev->agp->agp_mtrr = arch_phys_wc_add(
+					dev->agp->agp_info.aper_base,
+					dev->agp->agp_info.aper_size *
+					1024 * 1024);
 		}
 	}
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_prime.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_prime.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_prime.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_prime.c	2013-08-25 20:43:22.000000000 -0400
@@ -62,20 +62,125 @@ struct drm_prime_member {
 	struct dma_buf *dma_buf;
 	uint32_t handle;
 };
-static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle);
+
+struct drm_prime_attachment {
+	struct sg_table *sgt;
+	enum dma_data_direction dir;
+};
+
+static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle)
+{
+	struct drm_prime_member *member;
+
+	member = kmalloc(sizeof(*member), GFP_KERNEL);
+	if (!member)
+		return -ENOMEM;
+
+	get_dma_buf(dma_buf);
+	member->dma_buf = dma_buf;
+	member->handle = handle;
+	list_add(&member->entry, &prime_fpriv->head);
+	return 0;
+}
+
+static int drm_gem_map_attach(struct dma_buf *dma_buf,
+			      struct device *target_dev,
+			      struct dma_buf_attachment *attach)
+{
+	struct drm_prime_attachment *prime_attach;
+	struct drm_gem_object *obj = dma_buf->priv;
+	struct drm_device *dev = obj->dev;
+
+	prime_attach = kzalloc(sizeof(*prime_attach), GFP_KERNEL);
+	if (!prime_attach)
+		return -ENOMEM;
+
+	prime_attach->dir = DMA_NONE;
+	attach->priv = prime_attach;
+
+	if (!dev->driver->gem_prime_pin)
+		return 0;
+
+	return dev->driver->gem_prime_pin(obj);
+}
+
+static void drm_gem_map_detach(struct dma_buf *dma_buf,
+			       struct dma_buf_attachment *attach)
+{
+	struct drm_prime_attachment *prime_attach = attach->priv;
+	struct drm_gem_object *obj = dma_buf->priv;
+	struct drm_device *dev = obj->dev;
+	struct sg_table *sgt;
+
+	if (dev->driver->gem_prime_unpin)
+		dev->driver->gem_prime_unpin(obj);
+
+	if (!prime_attach)
+		return;
+
+	sgt = prime_attach->sgt;
+	if (sgt) {
+		if (prime_attach->dir != DMA_NONE)
+			dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents,
+					prime_attach->dir);
+		sg_free_table(sgt);
+	}
+
+	kfree(sgt);
+	kfree(prime_attach);
+	attach->priv = NULL;
+}
+
+static void drm_prime_remove_buf_handle_locked(
+		struct drm_prime_file_private *prime_fpriv,
+		struct dma_buf *dma_buf)
+{
+	struct drm_prime_member *member, *safe;
+
+	list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
+		if (member->dma_buf == dma_buf) {
+			dma_buf_put(dma_buf);
+			list_del(&member->entry);
+			kfree(member);
+		}
+	}
+}
 
 static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
 		enum dma_data_direction dir)
 {
+	struct drm_prime_attachment *prime_attach = attach->priv;
 	struct drm_gem_object *obj = attach->dmabuf->priv;
 	struct sg_table *sgt;
 
+	if (WARN_ON(dir == DMA_NONE || !prime_attach))
+		return ERR_PTR(-EINVAL);
+
+	/* return the cached mapping when possible */
+	if (prime_attach->dir == dir)
+		return prime_attach->sgt;
+
+	/*
+	 * two mappings with different directions for the same attachment are
+	 * not allowed
+	 */
+	if (WARN_ON(prime_attach->dir != DMA_NONE))
+		return ERR_PTR(-EBUSY);
+
 	mutex_lock(&obj->dev->struct_mutex);
 
 	sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
 
-	if (!IS_ERR_OR_NULL(sgt))
-		dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+	if (!IS_ERR(sgt)) {
+		if (!dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir)) {
+			sg_free_table(sgt);
+			kfree(sgt);
+			sgt = ERR_PTR(-ENOMEM);
+		} else {
+			prime_attach->sgt = sgt;
+			prime_attach->dir = dir;
+		}
+	}
 
 	mutex_unlock(&obj->dev->struct_mutex);
 	return sgt;
@@ -84,9 +189,7 @@ static struct sg_table *drm_gem_map_dma_
 static void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
 		struct sg_table *sgt, enum dma_data_direction dir)
 {
-	dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
-	sg_free_table(sgt);
-	kfree(sgt);
+	/* nothing to be done here */
 }
 
 static void drm_gem_dmabuf_release(struct dma_buf *dma_buf)
@@ -142,10 +245,18 @@ static void drm_gem_dmabuf_kunmap(struct
 static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf,
 		struct vm_area_struct *vma)
 {
-	return -EINVAL;
+	struct drm_gem_object *obj = dma_buf->priv;
+	struct drm_device *dev = obj->dev;
+
+	if (!dev->driver->gem_prime_mmap)
+		return -ENOSYS;
+
+	return dev->driver->gem_prime_mmap(obj, vma);
 }
 
 static const struct dma_buf_ops drm_gem_prime_dmabuf_ops =  {
+	.attach = drm_gem_map_attach,
+	.detach = drm_gem_map_detach,
 	.map_dma_buf = drm_gem_map_dma_buf,
 	.unmap_dma_buf = drm_gem_unmap_dma_buf,
 	.release = drm_gem_dmabuf_release,
@@ -185,11 +296,6 @@ static const struct dma_buf_ops drm_gem_
 struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
 				     struct drm_gem_object *obj, int flags)
 {
-	if (dev->driver->gem_prime_pin) {
-		int ret = dev->driver->gem_prime_pin(obj);
-		if (ret)
-			return ERR_PTR(ret);
-	}
 	return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, flags);
 }
 EXPORT_SYMBOL(drm_gem_prime_export);
@@ -235,15 +341,34 @@ int drm_gem_prime_handle_to_fd(struct dr
 	ret = drm_prime_add_buf_handle(&file_priv->prime,
 				       obj->export_dma_buf, handle);
 	if (ret)
-		goto out;
+		goto fail_put_dmabuf;
 
-	*prime_fd = dma_buf_fd(buf, flags);
+	ret = dma_buf_fd(buf, flags);
+	if (ret < 0)
+		goto fail_rm_handle;
+
+	*prime_fd = ret;
 	mutex_unlock(&file_priv->prime.lock);
 	return 0;
 
 out_have_obj:
 	get_dma_buf(dmabuf);
-	*prime_fd = dma_buf_fd(dmabuf, flags);
+	ret = dma_buf_fd(dmabuf, flags);
+	if (ret < 0) {
+		dma_buf_put(dmabuf);
+	} else {
+		*prime_fd = ret;
+		ret = 0;
+	}
+
+	goto out;
+
+fail_rm_handle:
+	drm_prime_remove_buf_handle_locked(&file_priv->prime, buf);
+fail_put_dmabuf:
+	/* clear NOT to be checked when releasing dma_buf */
+	obj->export_dma_buf = NULL;
+	dma_buf_put(buf);
 out:
 	drm_gem_object_unreference_unlocked(obj);
 	mutex_unlock(&file_priv->prime.lock);
@@ -276,7 +401,7 @@ struct drm_gem_object *drm_gem_prime_imp
 
 	attach = dma_buf_attach(dma_buf, dev->dev);
 	if (IS_ERR(attach))
-		return ERR_PTR(PTR_ERR(attach));
+		return ERR_CAST(attach);
 
 	get_dma_buf(dma_buf);
 
@@ -412,8 +537,10 @@ struct sg_table *drm_prime_pages_to_sg(s
 	int ret;
 
 	sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
-	if (!sg)
+	if (!sg) {
+		ret = -ENOMEM;
 		goto out;
+	}
 
 	ret = sg_alloc_table_from_pages(sg, pages, nr_pages, 0,
 				nr_pages << PAGE_SHIFT, GFP_KERNEL);
@@ -423,7 +550,7 @@ struct sg_table *drm_prime_pages_to_sg(s
 	return sg;
 out:
 	kfree(sg);
-	return NULL;
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL(drm_prime_pages_to_sg);
 
@@ -492,21 +619,6 @@ void drm_prime_destroy_file_private(stru
 }
 EXPORT_SYMBOL(drm_prime_destroy_file_private);
 
-static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle)
-{
-	struct drm_prime_member *member;
-
-	member = kmalloc(sizeof(*member), GFP_KERNEL);
-	if (!member)
-		return -ENOMEM;
-
-	get_dma_buf(dma_buf);
-	member->dma_buf = dma_buf;
-	member->handle = handle;
-	list_add(&member->entry, &prime_fpriv->head);
-	return 0;
-}
-
 int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle)
 {
 	struct drm_prime_member *member;
@@ -523,16 +635,8 @@ EXPORT_SYMBOL(drm_prime_lookup_buf_handl
 
 void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf)
 {
-	struct drm_prime_member *member, *safe;
-
 	mutex_lock(&prime_fpriv->lock);
-	list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) {
-		if (member->dma_buf == dma_buf) {
-			dma_buf_put(dma_buf);
-			list_del(&member->entry);
-			kfree(member);
-		}
-	}
+	drm_prime_remove_buf_handle_locked(prime_fpriv, dma_buf);
 	mutex_unlock(&prime_fpriv->lock);
 }
 EXPORT_SYMBOL(drm_prime_remove_buf_handle);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_rect.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_rect.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_rect.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_rect.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2011-2013 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <drm/drmP.h>
+#include <drm/drm_rect.h>
+
+/**
+ * drm_rect_intersect - intersect two rectangles
+ * @r1: first rectangle
+ * @r2: second rectangle
+ *
+ * Calculate the intersection of rectangles @r1 and @r2.
+ * @r1 will be overwritten with the intersection.
+ *
+ * RETURNS:
+ * %true if rectangle @r1 is still visible after the operation,
+ * %false otherwise.
+ */
+bool drm_rect_intersect(struct drm_rect *r1, const struct drm_rect *r2)
+{
+	r1->x1 = max(r1->x1, r2->x1);
+	r1->y1 = max(r1->y1, r2->y1);
+	r1->x2 = min(r1->x2, r2->x2);
+	r1->y2 = min(r1->y2, r2->y2);
+
+	return drm_rect_visible(r1);
+}
+EXPORT_SYMBOL(drm_rect_intersect);
+
+/**
+ * drm_rect_clip_scaled - perform a scaled clip operation
+ * @src: source window rectangle
+ * @dst: destination window rectangle
+ * @clip: clip rectangle
+ * @hscale: horizontal scaling factor
+ * @vscale: vertical scaling factor
+ *
+ * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by the
+ * same amounts multiplied by @hscale and @vscale.
+ *
+ * RETURNS:
+ * %true if rectangle @dst is still visible after being clipped,
+ * %false otherwise
+ */
+bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst,
+			  const struct drm_rect *clip,
+			  int hscale, int vscale)
+{
+	int diff;
+
+	diff = clip->x1 - dst->x1;
+	if (diff > 0) {
+		int64_t tmp = src->x1 + (int64_t) diff * hscale;
+		src->x1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
+	}
+	diff = clip->y1 - dst->y1;
+	if (diff > 0) {
+		int64_t tmp = src->y1 + (int64_t) diff * vscale;
+		src->y1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
+	}
+	diff = dst->x2 - clip->x2;
+	if (diff > 0) {
+		int64_t tmp = src->x2 - (int64_t) diff * hscale;
+		src->x2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
+	}
+	diff = dst->y2 - clip->y2;
+	if (diff > 0) {
+		int64_t tmp = src->y2 - (int64_t) diff * vscale;
+		src->y2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
+	}
+
+	return drm_rect_intersect(dst, clip);
+}
+EXPORT_SYMBOL(drm_rect_clip_scaled);
+
+static int drm_calc_scale(int src, int dst)
+{
+	int scale = 0;
+
+	if (src < 0 || dst < 0)
+		return -EINVAL;
+
+	if (dst == 0)
+		return 0;
+
+	scale = src / dst;
+
+	return scale;
+}
+
+/**
+ * drm_rect_calc_hscale - calculate the horizontal scaling factor
+ * @src: source window rectangle
+ * @dst: destination window rectangle
+ * @min_hscale: minimum allowed horizontal scaling factor
+ * @max_hscale: maximum allowed horizontal scaling factor
+ *
+ * Calculate the horizontal scaling factor as
+ * (@src width) / (@dst width).
+ *
+ * RETURNS:
+ * The horizontal scaling factor, or errno of out of limits.
+ */
+int drm_rect_calc_hscale(const struct drm_rect *src,
+			 const struct drm_rect *dst,
+			 int min_hscale, int max_hscale)
+{
+	int src_w = drm_rect_width(src);
+	int dst_w = drm_rect_width(dst);
+	int hscale = drm_calc_scale(src_w, dst_w);
+
+	if (hscale < 0 || dst_w == 0)
+		return hscale;
+
+	if (hscale < min_hscale || hscale > max_hscale)
+		return -ERANGE;
+
+	return hscale;
+}
+EXPORT_SYMBOL(drm_rect_calc_hscale);
+
+/**
+ * drm_rect_calc_vscale - calculate the vertical scaling factor
+ * @src: source window rectangle
+ * @dst: destination window rectangle
+ * @min_vscale: minimum allowed vertical scaling factor
+ * @max_vscale: maximum allowed vertical scaling factor
+ *
+ * Calculate the vertical scaling factor as
+ * (@src height) / (@dst height).
+ *
+ * RETURNS:
+ * The vertical scaling factor, or errno of out of limits.
+ */
+int drm_rect_calc_vscale(const struct drm_rect *src,
+			 const struct drm_rect *dst,
+			 int min_vscale, int max_vscale)
+{
+	int src_h = drm_rect_height(src);
+	int dst_h = drm_rect_height(dst);
+	int vscale = drm_calc_scale(src_h, dst_h);
+
+	if (vscale < 0 || dst_h == 0)
+		return vscale;
+
+	if (vscale < min_vscale || vscale > max_vscale)
+		return -ERANGE;
+
+	return vscale;
+}
+EXPORT_SYMBOL(drm_rect_calc_vscale);
+
+/**
+ * drm_calc_hscale_relaxed - calculate the horizontal scaling factor
+ * @src: source window rectangle
+ * @dst: destination window rectangle
+ * @min_hscale: minimum allowed horizontal scaling factor
+ * @max_hscale: maximum allowed horizontal scaling factor
+ *
+ * Calculate the horizontal scaling factor as
+ * (@src width) / (@dst width).
+ *
+ * If the calculated scaling factor is below @min_vscale,
+ * decrease the height of rectangle @dst to compensate.
+ *
+ * If the calculated scaling factor is above @max_vscale,
+ * decrease the height of rectangle @src to compensate.
+ *
+ * RETURNS:
+ * The horizontal scaling factor.
+ */
+int drm_rect_calc_hscale_relaxed(struct drm_rect *src,
+				 struct drm_rect *dst,
+				 int min_hscale, int max_hscale)
+{
+	int src_w = drm_rect_width(src);
+	int dst_w = drm_rect_width(dst);
+	int hscale = drm_calc_scale(src_w, dst_w);
+
+	if (hscale < 0 || dst_w == 0)
+		return hscale;
+
+	if (hscale < min_hscale) {
+		int max_dst_w = src_w / min_hscale;
+
+		drm_rect_adjust_size(dst, max_dst_w - dst_w, 0);
+
+		return min_hscale;
+	}
+
+	if (hscale > max_hscale) {
+		int max_src_w = dst_w * max_hscale;
+
+		drm_rect_adjust_size(src, max_src_w - src_w, 0);
+
+		return max_hscale;
+	}
+
+	return hscale;
+}
+EXPORT_SYMBOL(drm_rect_calc_hscale_relaxed);
+
+/**
+ * drm_rect_calc_vscale_relaxed - calculate the vertical scaling factor
+ * @src: source window rectangle
+ * @dst: destination window rectangle
+ * @min_vscale: minimum allowed vertical scaling factor
+ * @max_vscale: maximum allowed vertical scaling factor
+ *
+ * Calculate the vertical scaling factor as
+ * (@src height) / (@dst height).
+ *
+ * If the calculated scaling factor is below @min_vscale,
+ * decrease the height of rectangle @dst to compensate.
+ *
+ * If the calculated scaling factor is above @max_vscale,
+ * decrease the height of rectangle @src to compensate.
+ *
+ * RETURNS:
+ * The vertical scaling factor.
+ */
+int drm_rect_calc_vscale_relaxed(struct drm_rect *src,
+				 struct drm_rect *dst,
+				 int min_vscale, int max_vscale)
+{
+	int src_h = drm_rect_height(src);
+	int dst_h = drm_rect_height(dst);
+	int vscale = drm_calc_scale(src_h, dst_h);
+
+	if (vscale < 0 || dst_h == 0)
+		return vscale;
+
+	if (vscale < min_vscale) {
+		int max_dst_h = src_h / min_vscale;
+
+		drm_rect_adjust_size(dst, 0, max_dst_h - dst_h);
+
+		return min_vscale;
+	}
+
+	if (vscale > max_vscale) {
+		int max_src_h = dst_h * max_vscale;
+
+		drm_rect_adjust_size(src, 0, max_src_h - src_h);
+
+		return max_vscale;
+	}
+
+	return vscale;
+}
+EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed);
+
+/**
+ * drm_rect_debug_print - print the rectangle information
+ * @r: rectangle to print
+ * @fixed_point: rectangle is in 16.16 fixed point format
+ */
+void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point)
+{
+	int w = drm_rect_width(r);
+	int h = drm_rect_height(r);
+
+	if (fixed_point)
+		DRM_DEBUG_KMS("%d.%06ux%d.%06u%+d.%06u%+d.%06u\n",
+			      w >> 16, ((w & 0xffff) * 15625) >> 10,
+			      h >> 16, ((h & 0xffff) * 15625) >> 10,
+			      r->x1 >> 16, ((r->x1 & 0xffff) * 15625) >> 10,
+			      r->y1 >> 16, ((r->y1 & 0xffff) * 15625) >> 10);
+	else
+		DRM_DEBUG_KMS("%dx%d%+d%+d\n", w, h, r->x1, r->y1);
+}
+EXPORT_SYMBOL(drm_rect_debug_print);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_stub.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_stub.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_stub.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_stub.c	2013-08-25 20:43:22.000000000 -0400
@@ -203,7 +203,7 @@ EXPORT_SYMBOL(drm_master_put);
 int drm_setmaster_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv)
 {
-	int ret;
+	int ret = 0;
 
 	if (file_priv->is_master)
 		return 0;
@@ -229,7 +229,7 @@ int drm_setmaster_ioctl(struct drm_devic
 	}
 	mutex_unlock(&dev->struct_mutex);
 
-	return 0;
+	return ret;
 }
 
 int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
@@ -451,14 +451,8 @@ void drm_put_dev(struct drm_device *dev)
 
 	drm_lastclose(dev);
 
-	if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
-	    dev->agp && dev->agp->agp_mtrr >= 0) {
-		int retval;
-		retval = mtrr_del(dev->agp->agp_mtrr,
-				  dev->agp->agp_info.aper_base,
-				  dev->agp->agp_info.aper_size * 1024 * 1024);
-		DRM_DEBUG("mtrr_del=%d\n", retval);
-	}
+	if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp)
+		arch_phys_wc_del(dev->agp->agp_mtrr);
 
 	if (dev->driver->unload)
 		dev->driver->unload(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_sysfs.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_sysfs.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,14 +30,14 @@ static struct device_type drm_sysfs_devi
 };
 
 /**
- * drm_class_suspend - DRM class suspend hook
+ * __drm_class_suspend - internal DRM class suspend routine
  * @dev: Linux device to suspend
  * @state: power state to enter
  *
  * Just figures out what the actual struct drm_device associated with
  * @dev is and calls its suspend hook, if present.
  */
-static int drm_class_suspend(struct device *dev, pm_message_t state)
+static int __drm_class_suspend(struct device *dev, pm_message_t state)
 {
 	if (dev->type == &drm_sysfs_device_minor) {
 		struct drm_minor *drm_minor = to_drm_minor(dev);
@@ -52,6 +52,26 @@ static int drm_class_suspend(struct devi
 }
 
 /**
+ * drm_class_suspend - internal DRM class suspend hook. Simply calls
+ * __drm_class_suspend() with the correct pm state.
+ * @dev: Linux device to suspend
+ */
+static int drm_class_suspend(struct device *dev)
+{
+	return __drm_class_suspend(dev, PMSG_SUSPEND);
+}
+
+/**
+ * drm_class_freeze - internal DRM class freeze hook. Simply calls
+ * __drm_class_suspend() with the correct pm state.
+ * @dev: Linux device to freeze
+ */
+static int drm_class_freeze(struct device *dev)
+{
+	return __drm_class_suspend(dev, PMSG_FREEZE);
+}
+
+/**
  * drm_class_resume - DRM class resume hook
  * @dev: Linux device to resume
  *
@@ -72,6 +92,12 @@ static int drm_class_resume(struct devic
 	return 0;
 }
 
+static const struct dev_pm_ops drm_class_dev_pm_ops = {
+	.suspend	= drm_class_suspend,
+	.resume		= drm_class_resume,
+	.freeze		= drm_class_freeze,
+};
+
 static char *drm_devnode(struct device *dev, umode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
@@ -106,8 +132,7 @@ struct class *drm_sysfs_create(struct mo
 		goto err_out;
 	}
 
-	class->suspend = drm_class_suspend;
-	class->resume = drm_class_resume;
+	class->pm = &drm_class_dev_pm_ops;
 
 	err = class_create_file(class, &class_attr_version.attr);
 	if (err)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_trace.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_trace.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_trace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_trace.h	2013-08-25 20:43:22.000000000 -0400
@@ -21,7 +21,7 @@ TRACE_EVENT(drm_vblank_event,
 		    __entry->crtc = crtc;
 		    __entry->seq = seq;
 		    ),
-	    TP_printk("crtc=%d, seq=%d", __entry->crtc, __entry->seq)
+	    TP_printk("crtc=%d, seq=%u", __entry->crtc, __entry->seq)
 );
 
 TRACE_EVENT(drm_vblank_event_queued,
@@ -37,7 +37,7 @@ TRACE_EVENT(drm_vblank_event_queued,
 		    __entry->crtc = crtc;
 		    __entry->seq = seq;
 		    ),
-	    TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \
+	    TP_printk("pid=%d, crtc=%d, seq=%u", __entry->pid, __entry->crtc, \
 		      __entry->seq)
 );
 
@@ -54,7 +54,7 @@ TRACE_EVENT(drm_vblank_event_delivered,
 		    __entry->crtc = crtc;
 		    __entry->seq = seq;
 		    ),
-	    TP_printk("pid=%d, crtc=%d, seq=%d", __entry->pid, __entry->crtc, \
+	    TP_printk("pid=%d, crtc=%d, seq=%u", __entry->pid, __entry->crtc, \
 		      __entry->seq)
 );
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/drm_vm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_vm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/drm_vm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/drm_vm.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,18 +43,19 @@
 static void drm_vm_open(struct vm_area_struct *vma);
 static void drm_vm_close(struct vm_area_struct *vma);
 
-static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
+static pgprot_t drm_io_prot(struct drm_local_map *map,
+			    struct vm_area_struct *vma)
 {
 	pgprot_t tmp = vm_get_page_prot(vma->vm_flags);
 
 #if defined(__i386__) || defined(__x86_64__)
-	if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) {
-		pgprot_val(tmp) |= _PAGE_PCD;
-		pgprot_val(tmp) &= ~_PAGE_PWT;
-	}
+	if (map->type == _DRM_REGISTERS && !(map->flags & _DRM_WRITE_COMBINING))
+		tmp = pgprot_noncached(tmp);
+	else
+		tmp = pgprot_writecombine(tmp);
 #elif defined(__powerpc__)
 	pgprot_val(tmp) |= _PAGE_NO_CACHE;
-	if (map_type == _DRM_REGISTERS)
+	if (map->type == _DRM_REGISTERS)
 		pgprot_val(tmp) |= _PAGE_GUARDED;
 #elif defined(__ia64__)
 	if (efi_range_is_wc(vma->vm_start, vma->vm_end -
@@ -250,13 +251,8 @@ static void drm_vm_shm_close(struct vm_a
 			switch (map->type) {
 			case _DRM_REGISTERS:
 			case _DRM_FRAME_BUFFER:
-				if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
-					int retcode;
-					retcode = mtrr_del(map->mtrr,
-							   map->offset,
-							   map->size);
-					DRM_DEBUG("mtrr_del = %d\n", retcode);
-				}
+				if (drm_core_has_MTRR(dev))
+					arch_phys_wc_del(map->mtrr);
 				iounmap(map->handle);
 				break;
 			case _DRM_SHM:
@@ -617,8 +613,7 @@ int drm_mmap_locked(struct file *filp, s
 	case _DRM_FRAME_BUFFER:
 	case _DRM_REGISTERS:
 		offset = drm_core_get_reg_ofs(dev);
-		vma->vm_flags |= VM_IO;	/* not in core dump */
-		vma->vm_page_prot = drm_io_prot(map->type, vma);
+		vma->vm_page_prot = drm_io_prot(map, vma);
 		if (io_remap_pfn_range(vma, vma->vm_start,
 				       (map->offset + offset) >> PAGE_SHIFT,
 				       vma->vm_end - vma->vm_start,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_ddc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_ddc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_ddc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_ddc.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,6 @@
 
 #include <linux/kernel.h>
 #include <linux/i2c.h>
-#include <linux/module.h>
 
 
 #include "exynos_drm_drv.h"
@@ -53,6 +52,8 @@ static struct of_device_id hdmiddc_match
 	{
 		.compatible = "samsung,exynos5-hdmiddc",
 	}, {
+		.compatible = "samsung,exynos4210-hdmiddc",
+	}, {
 		/* end node */
 	}
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_buf.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_buf.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_buf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_buf.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,8 +24,6 @@ static int lowlevel_buffer_allocate(stru
 	enum dma_attr attr;
 	unsigned int nr_pages;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (buf->dma_addr) {
 		DRM_DEBUG_KMS("already allocated.\n");
 		return 0;
@@ -59,8 +57,7 @@ static int lowlevel_buffer_allocate(stru
 		dma_addr_t start_addr;
 		unsigned int i = 0;
 
-		buf->pages = kzalloc(sizeof(struct page) * nr_pages,
-					GFP_KERNEL);
+		buf->pages = drm_calloc_large(nr_pages, sizeof(struct page *));
 		if (!buf->pages) {
 			DRM_ERROR("failed to allocate pages.\n");
 			return -ENOMEM;
@@ -71,8 +68,8 @@ static int lowlevel_buffer_allocate(stru
 					&buf->dma_attrs);
 		if (!buf->kvaddr) {
 			DRM_ERROR("failed to allocate buffer.\n");
-			kfree(buf->pages);
-			return -ENOMEM;
+			ret = -ENOMEM;
+			goto err_free;
 		}
 
 		start_addr = buf->dma_addr;
@@ -109,9 +106,9 @@ err_free_attrs:
 	dma_free_attrs(dev->dev, buf->size, buf->pages,
 			(dma_addr_t)buf->dma_addr, &buf->dma_attrs);
 	buf->dma_addr = (dma_addr_t)NULL;
-
+err_free:
 	if (!is_drm_iommu_supported(dev))
-		kfree(buf->pages);
+		drm_free_large(buf->pages);
 
 	return ret;
 }
@@ -119,8 +116,6 @@ err_free_attrs:
 static void lowlevel_buffer_deallocate(struct drm_device *dev,
 		unsigned int flags, struct exynos_drm_gem_buf *buf)
 {
-	DRM_DEBUG_KMS("%s.\n", __FILE__);
-
 	if (!buf->dma_addr) {
 		DRM_DEBUG_KMS("dma_addr is invalid.\n");
 		return;
@@ -138,7 +133,7 @@ static void lowlevel_buffer_deallocate(s
 	if (!is_drm_iommu_supported(dev)) {
 		dma_free_attrs(dev->dev, buf->size, buf->kvaddr,
 				(dma_addr_t)buf->dma_addr, &buf->dma_attrs);
-		kfree(buf->pages);
+		drm_free_large(buf->pages);
 	} else
 		dma_free_attrs(dev->dev, buf->size, buf->pages,
 				(dma_addr_t)buf->dma_addr, &buf->dma_attrs);
@@ -151,7 +146,6 @@ struct exynos_drm_gem_buf *exynos_drm_in
 {
 	struct exynos_drm_gem_buf *buffer;
 
-	DRM_DEBUG_KMS("%s.\n", __FILE__);
 	DRM_DEBUG_KMS("desired size = 0x%x\n", size);
 
 	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
@@ -167,8 +161,6 @@ struct exynos_drm_gem_buf *exynos_drm_in
 void exynos_drm_fini_buf(struct drm_device *dev,
 				struct exynos_drm_gem_buf *buffer)
 {
-	DRM_DEBUG_KMS("%s.\n", __FILE__);
-
 	if (!buffer) {
 		DRM_DEBUG_KMS("buffer is null.\n");
 		return;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_connector.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_connector.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_connector.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_connector.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,7 +34,6 @@ convert_to_display_mode(struct drm_displ
 			struct exynos_drm_panel_info *panel)
 {
 	struct fb_videomode *timing = &panel->timing;
-	DRM_DEBUG_KMS("%s\n", __FILE__);
 
 	mode->clock = timing->pixclock / 1000;
 	mode->vrefresh = timing->refresh;
@@ -58,37 +57,6 @@ convert_to_display_mode(struct drm_displ
 		mode->flags |= DRM_MODE_FLAG_DBLSCAN;
 }
 
-/* convert drm_display_mode to exynos_video_timings */
-static inline void
-convert_to_video_timing(struct fb_videomode *timing,
-			struct drm_display_mode *mode)
-{
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
-	memset(timing, 0, sizeof(*timing));
-
-	timing->pixclock = mode->clock * 1000;
-	timing->refresh = drm_mode_vrefresh(mode);
-
-	timing->xres = mode->hdisplay;
-	timing->right_margin = mode->hsync_start - mode->hdisplay;
-	timing->hsync_len = mode->hsync_end - mode->hsync_start;
-	timing->left_margin = mode->htotal - mode->hsync_end;
-
-	timing->yres = mode->vdisplay;
-	timing->lower_margin = mode->vsync_start - mode->vdisplay;
-	timing->vsync_len = mode->vsync_end - mode->vsync_start;
-	timing->upper_margin = mode->vtotal - mode->vsync_end;
-
-	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-		timing->vmode = FB_VMODE_INTERLACED;
-	else
-		timing->vmode = FB_VMODE_NONINTERLACED;
-
-	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
-		timing->vmode |= FB_VMODE_DOUBLE;
-}
-
 static int exynos_drm_connector_get_modes(struct drm_connector *connector)
 {
 	struct exynos_drm_connector *exynos_connector =
@@ -99,8 +67,6 @@ static int exynos_drm_connector_get_mode
 	unsigned int count = 0;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (!display_ops) {
 		DRM_DEBUG_KMS("display_ops is null.\n");
 		return 0;
@@ -168,15 +134,12 @@ static int exynos_drm_connector_mode_val
 					to_exynos_connector(connector);
 	struct exynos_drm_manager *manager = exynos_connector->manager;
 	struct exynos_drm_display_ops *display_ops = manager->display_ops;
-	struct fb_videomode timing;
 	int ret = MODE_BAD;
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	convert_to_video_timing(&timing, mode);
-
-	if (display_ops && display_ops->check_timing)
-		if (!display_ops->check_timing(manager->dev, (void *)&timing))
+	if (display_ops && display_ops->check_mode)
+		if (!display_ops->check_mode(manager->dev, mode))
 			ret = MODE_OK;
 
 	return ret;
@@ -190,8 +153,6 @@ struct drm_encoder *exynos_drm_best_enco
 	struct drm_mode_object *obj;
 	struct drm_encoder *encoder;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	obj = drm_mode_object_find(dev, exynos_connector->encoder_id,
 				   DRM_MODE_OBJECT_ENCODER);
 	if (!obj) {
@@ -234,8 +195,6 @@ void exynos_drm_display_power(struct drm
 static void exynos_drm_connector_dpms(struct drm_connector *connector,
 					int mode)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	 * in case that drm_crtc_helper_set_mode() is called,
 	 * encoder/crtc->funcs->dpms() will be just returned
@@ -282,8 +241,6 @@ exynos_drm_connector_detect(struct drm_c
 					manager->display_ops;
 	enum drm_connector_status status = connector_status_disconnected;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (display_ops && display_ops->is_connected) {
 		if (display_ops->is_connected(manager->dev))
 			status = connector_status_connected;
@@ -299,8 +256,6 @@ static void exynos_drm_connector_destroy
 	struct exynos_drm_connector *exynos_connector =
 		to_exynos_connector(connector);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
 	kfree(exynos_connector);
@@ -322,8 +277,6 @@ struct drm_connector *exynos_drm_connect
 	int type;
 	int err;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL);
 	if (!exynos_connector) {
 		DRM_ERROR("failed to allocate connector\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_core.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_core.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,8 +27,6 @@ static int exynos_drm_create_enc_conn(st
 	struct drm_connector *connector;
 	int ret;
 
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	subdrv->manager->dev = subdrv->dev;
 
 	/* create and initialize a encoder for this sub driver. */
@@ -102,8 +100,6 @@ static int exynos_drm_subdrv_probe(struc
 static void exynos_drm_subdrv_remove(struct drm_device *dev,
 				      struct exynos_drm_subdrv *subdrv)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	if (subdrv->remove)
 		subdrv->remove(dev, subdrv->dev);
 }
@@ -114,8 +110,6 @@ int exynos_drm_device_register(struct dr
 	unsigned int fine_cnt = 0;
 	int err;
 
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	if (!dev)
 		return -EINVAL;
 
@@ -158,8 +152,6 @@ int exynos_drm_device_unregister(struct
 {
 	struct exynos_drm_subdrv *subdrv;
 
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	if (!dev) {
 		WARN(1, "Unexpected drm device unregister!\n");
 		return -EINVAL;
@@ -176,8 +168,6 @@ EXPORT_SYMBOL_GPL(exynos_drm_device_unre
 
 int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	if (!subdrv)
 		return -EINVAL;
 
@@ -189,8 +179,6 @@ EXPORT_SYMBOL_GPL(exynos_drm_subdrv_regi
 
 int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	if (!subdrv)
 		return -EINVAL;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_crtc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_crtc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_crtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_crtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -76,8 +76,6 @@ static void exynos_drm_crtc_dpms(struct
 
 static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* drm framework doesn't check NULL. */
 }
 
@@ -85,8 +83,6 @@ static void exynos_drm_crtc_commit(struc
 {
 	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
 	exynos_plane_commit(exynos_crtc->plane);
 	exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_ON);
@@ -97,8 +93,6 @@ exynos_drm_crtc_mode_fixup(struct drm_cr
 			    const struct drm_display_mode *mode,
 			    struct drm_display_mode *adjusted_mode)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* drm framework doesn't check NULL */
 	return true;
 }
@@ -115,8 +109,6 @@ exynos_drm_crtc_mode_set(struct drm_crtc
 	int pipe = exynos_crtc->pipe;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	 * copy the mode data adjusted by mode_fixup() into crtc->mode
 	 * so that hardware can be seet to proper mode.
@@ -139,7 +131,7 @@ exynos_drm_crtc_mode_set(struct drm_crtc
 	return 0;
 }
 
-static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y,
 					  struct drm_framebuffer *old_fb)
 {
 	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
@@ -148,8 +140,6 @@ static int exynos_drm_crtc_mode_set_base
 	unsigned int crtc_h;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* when framebuffer changing is requested, crtc's dpms should be on */
 	if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
 		DRM_ERROR("failed framebuffer changing request.\n");
@@ -169,18 +159,16 @@ static int exynos_drm_crtc_mode_set_base
 	return 0;
 }
 
-static void exynos_drm_crtc_load_lut(struct drm_crtc *crtc)
+static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+					  struct drm_framebuffer *old_fb)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-	/* drm framework doesn't check NULL */
+	return exynos_drm_crtc_mode_set_commit(crtc, x, y, old_fb);
 }
 
 static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
 {
 	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_OFF);
 	exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 }
@@ -192,7 +180,6 @@ static struct drm_crtc_helper_funcs exyn
 	.mode_fixup	= exynos_drm_crtc_mode_fixup,
 	.mode_set	= exynos_drm_crtc_mode_set,
 	.mode_set_base	= exynos_drm_crtc_mode_set_base,
-	.load_lut	= exynos_drm_crtc_load_lut,
 	.disable	= exynos_drm_crtc_disable,
 };
 
@@ -206,8 +193,6 @@ static int exynos_drm_crtc_page_flip(str
 	struct drm_framebuffer *old_fb = crtc->fb;
 	int ret = -EINVAL;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* when the page flip is requested, crtc's dpms should be on */
 	if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
 		DRM_ERROR("failed page flip request.\n");
@@ -237,7 +222,7 @@ static int exynos_drm_crtc_page_flip(str
 		spin_unlock_irq(&dev->event_lock);
 
 		crtc->fb = fb;
-		ret = exynos_drm_crtc_mode_set_base(crtc, crtc->x, crtc->y,
+		ret = exynos_drm_crtc_mode_set_commit(crtc, crtc->x, crtc->y,
 						    NULL);
 		if (ret) {
 			crtc->fb = old_fb;
@@ -260,8 +245,6 @@ static void exynos_drm_crtc_destroy(stru
 	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 	struct exynos_drm_private *private = crtc->dev->dev_private;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	private->crtc[exynos_crtc->pipe] = NULL;
 
 	drm_crtc_cleanup(crtc);
@@ -276,8 +259,6 @@ static int exynos_drm_crtc_set_property(
 	struct exynos_drm_private *dev_priv = dev->dev_private;
 	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (property == dev_priv->crtc_mode_property) {
 		enum exynos_crtc_mode mode = val;
 
@@ -322,8 +303,6 @@ static void exynos_drm_crtc_attach_mode_
 	struct exynos_drm_private *dev_priv = dev->dev_private;
 	struct drm_property *prop;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	prop = dev_priv->crtc_mode_property;
 	if (!prop) {
 		prop = drm_property_create_enum(dev, 0, "mode", mode_names,
@@ -343,8 +322,6 @@ int exynos_drm_crtc_create(struct drm_de
 	struct exynos_drm_private *private = dev->dev_private;
 	struct drm_crtc *crtc;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
 	if (!exynos_crtc) {
 		DRM_ERROR("failed to allocate exynos crtc\n");
@@ -379,8 +356,6 @@ int exynos_drm_crtc_enable_vblank(struct
 	struct exynos_drm_crtc *exynos_crtc =
 		to_exynos_crtc(private->crtc[crtc]);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
 		return -EPERM;
 
@@ -396,8 +371,6 @@ void exynos_drm_crtc_disable_vblank(stru
 	struct exynos_drm_crtc *exynos_crtc =
 		to_exynos_crtc(private->crtc[crtc]);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
 		return;
 
@@ -413,8 +386,6 @@ void exynos_drm_crtc_finish_pageflip(str
 	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(drm_crtc);
 	unsigned long flags;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	spin_lock_irqsave(&dev->event_lock, flags);
 
 	list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c	2013-08-25 20:43:22.000000000 -0400
@@ -71,8 +71,6 @@ static struct sg_table *
 	unsigned int i;
 	int nents, ret;
 
-	DRM_DEBUG_PRIME("%s\n", __FILE__);
-
 	/* just return current sgt if already requested. */
 	if (exynos_attach->dir == dir && exynos_attach->is_mapped)
 		return &exynos_attach->sgt;
@@ -133,8 +131,6 @@ static void exynos_dmabuf_release(struct
 {
 	struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv;
 
-	DRM_DEBUG_PRIME("%s\n", __FILE__);
-
 	/*
 	 * exynos_dmabuf_release() call means that file object's
 	 * f_count is 0 and it calls drm_gem_object_handle_unreference()
@@ -219,8 +215,6 @@ struct drm_gem_object *exynos_dmabuf_pri
 	struct exynos_drm_gem_buf *buffer;
 	int ret;
 
-	DRM_DEBUG_PRIME("%s\n", __FILE__);
-
 	/* is this one of own objects? */
 	if (dma_buf->ops == &exynos_dmabuf_ops) {
 		struct drm_gem_object *obj;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,8 +46,6 @@ static int exynos_drm_load(struct drm_de
 	int ret;
 	int nr;
 
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
 	if (!private) {
 		DRM_ERROR("failed to allocate private\n");
@@ -140,8 +138,6 @@ err_crtc:
 
 static int exynos_drm_unload(struct drm_device *dev)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	exynos_drm_fbdev_fini(dev);
 	exynos_drm_device_unregister(dev);
 	drm_vblank_cleanup(dev);
@@ -159,8 +155,7 @@ static int exynos_drm_unload(struct drm_
 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
 {
 	struct drm_exynos_file_private *file_priv;
-
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
+	int ret;
 
 	file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
 	if (!file_priv)
@@ -168,7 +163,13 @@ static int exynos_drm_open(struct drm_de
 
 	file->driver_priv = file_priv;
 
-	return exynos_drm_subdrv_open(dev, file);
+	ret = exynos_drm_subdrv_open(dev, file);
+	if (ret) {
+		kfree(file_priv);
+		file->driver_priv = NULL;
+	}
+
+	return ret;
 }
 
 static void exynos_drm_preclose(struct drm_device *dev,
@@ -178,8 +179,6 @@ static void exynos_drm_preclose(struct d
 	struct drm_pending_vblank_event *e, *t;
 	unsigned long flags;
 
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	/* release events of current file */
 	spin_lock_irqsave(&dev->event_lock, flags);
 	list_for_each_entry_safe(e, t, &private->pageflip_event_list,
@@ -196,8 +195,6 @@ static void exynos_drm_preclose(struct d
 
 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	if (!file->driver_priv)
 		return;
 
@@ -207,8 +204,6 @@ static void exynos_drm_postclose(struct
 
 static void exynos_drm_lastclose(struct drm_device *dev)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	exynos_drm_fbdev_restore_mode(dev);
 }
 
@@ -292,8 +287,6 @@ static struct drm_driver exynos_drm_driv
 
 static int exynos_drm_platform_probe(struct platform_device *pdev)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 	exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls);
 
@@ -302,8 +295,6 @@ static int exynos_drm_platform_probe(str
 
 static int exynos_drm_platform_remove(struct platform_device *pdev)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	drm_platform_exit(&exynos_drm_driver, pdev);
 
 	return 0;
@@ -322,8 +313,6 @@ static int __init exynos_drm_init(void)
 {
 	int ret;
 
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 #ifdef CONFIG_DRM_EXYNOS_FIMD
 	ret = platform_driver_register(&fimd_driver);
 	if (ret < 0)
@@ -455,8 +444,6 @@ out_fimd:
 
 static void __exit exynos_drm_exit(void)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
 	platform_device_unregister(exynos_drm_pdev);
 
 	platform_driver_unregister(&exynos_drm_platform_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -142,7 +142,7 @@ struct exynos_drm_overlay {
  * @is_connected: check for that display is connected or not.
  * @get_edid: get edid modes from display driver.
  * @get_panel: get panel object from display driver.
- * @check_timing: check if timing is valid or not.
+ * @check_mode: check if mode is valid or not.
  * @power_on: display device on or off.
  */
 struct exynos_drm_display_ops {
@@ -151,7 +151,7 @@ struct exynos_drm_display_ops {
 	struct edid *(*get_edid)(struct device *dev,
 			struct drm_connector *connector);
 	void *(*get_panel)(struct device *dev);
-	int (*check_timing)(struct device *dev, void *timing);
+	int (*check_mode)(struct device *dev, struct drm_display_mode *mode);
 	int (*power_on)(struct device *dev, int mode);
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_encoder.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_encoder.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_encoder.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_encoder.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,7 +61,7 @@ static void exynos_drm_encoder_dpms(stru
 	struct exynos_drm_manager_ops *manager_ops = manager->ops;
 	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
 
-	DRM_DEBUG_KMS("%s, encoder dpms: %d\n", __FILE__, mode);
+	DRM_DEBUG_KMS("encoder dpms: %d\n", mode);
 
 	if (exynos_encoder->dpms == mode) {
 		DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
@@ -104,8 +104,6 @@ exynos_drm_encoder_mode_fixup(struct drm
 	struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
 	struct exynos_drm_manager_ops *manager_ops = manager->ops;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		if (connector->encoder == encoder)
 			if (manager_ops && manager_ops->mode_fixup)
@@ -155,8 +153,6 @@ static void exynos_drm_encoder_mode_set(
 	struct exynos_drm_manager *manager;
 	struct exynos_drm_manager_ops *manager_ops;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		if (connector->encoder == encoder) {
 			struct exynos_drm_encoder *exynos_encoder;
@@ -189,8 +185,6 @@ static void exynos_drm_encoder_mode_set(
 
 static void exynos_drm_encoder_prepare(struct drm_encoder *encoder)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* drm framework doesn't check NULL. */
 }
 
@@ -200,8 +194,6 @@ static void exynos_drm_encoder_commit(st
 	struct exynos_drm_manager *manager = exynos_encoder->manager;
 	struct exynos_drm_manager_ops *manager_ops = manager->ops;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (manager_ops && manager_ops->commit)
 		manager_ops->commit(manager->dev);
 
@@ -274,8 +266,6 @@ static void exynos_drm_encoder_destroy(s
 	struct exynos_drm_encoder *exynos_encoder =
 		to_exynos_encoder(encoder);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_encoder->manager->pipe = -1;
 
 	drm_encoder_cleanup(encoder);
@@ -315,8 +305,6 @@ void exynos_drm_encoder_setup(struct drm
 {
 	struct drm_encoder *encoder;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
 		encoder->possible_clones = exynos_drm_encoder_clones(encoder);
 }
@@ -329,8 +317,6 @@ exynos_drm_encoder_create(struct drm_dev
 	struct drm_encoder *encoder;
 	struct exynos_drm_encoder *exynos_encoder;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (!manager || !possible_crtcs)
 		return NULL;
 
@@ -427,8 +413,6 @@ void exynos_drm_encoder_crtc_dpms(struct
 	struct exynos_drm_manager_ops *manager_ops = manager->ops;
 	int mode = *(int *)data;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (manager_ops && manager_ops->dpms)
 		manager_ops->dpms(manager->dev, mode);
 
@@ -449,8 +433,6 @@ void exynos_drm_encoder_crtc_pipe(struct
 		to_exynos_encoder(encoder)->manager;
 	int pipe = *(int *)data;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	 * when crtc is detached from encoder, this pipe is used
 	 * to select manager operation
@@ -465,8 +447,6 @@ void exynos_drm_encoder_plane_mode_set(s
 	struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
 	struct exynos_drm_overlay *overlay = data;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (overlay_ops && overlay_ops->mode_set)
 		overlay_ops->mode_set(manager->dev, overlay);
 }
@@ -478,8 +458,6 @@ void exynos_drm_encoder_plane_commit(str
 	struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
 	int zpos = DEFAULT_ZPOS;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (data)
 		zpos = *(int *)data;
 
@@ -494,8 +472,6 @@ void exynos_drm_encoder_plane_enable(str
 	struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
 	int zpos = DEFAULT_ZPOS;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (data)
 		zpos = *(int *)data;
 
@@ -510,8 +486,6 @@ void exynos_drm_encoder_plane_disable(st
 	struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
 	int zpos = DEFAULT_ZPOS;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (data)
 		zpos = *(int *)data;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_fb.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fb.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_fb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fb.c	2013-08-25 20:43:22.000000000 -0400
@@ -70,8 +70,6 @@ static void exynos_drm_fb_destroy(struct
 	struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
 	unsigned int i;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* make sure that overlay data are updated before relesing fb. */
 	exynos_drm_encoder_complete_scanout(fb);
 
@@ -97,8 +95,6 @@ static int exynos_drm_fb_create_handle(s
 {
 	struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* This fb should have only one gem object. */
 	if (WARN_ON(exynos_fb->buf_cnt != 1))
 		return -EINVAL;
@@ -112,8 +108,6 @@ static int exynos_drm_fb_dirty(struct dr
 				unsigned color, struct drm_clip_rect *clips,
 				unsigned num_clips)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* TODO */
 
 	return 0;
@@ -225,8 +219,6 @@ exynos_user_fb_create(struct drm_device
 	struct exynos_drm_fb *exynos_fb;
 	int i, ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
 	if (!exynos_fb) {
 		DRM_ERROR("failed to allocate exynos drm framebuffer\n");
@@ -293,8 +285,6 @@ struct exynos_drm_gem_buf *exynos_drm_fb
 	struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
 	struct exynos_drm_gem_buf *buffer;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (index >= MAX_FB_BUFFER)
 		return NULL;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_fbdev.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_fbdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fbdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,8 +43,6 @@ static int exynos_drm_fb_mmap(struct fb_
 	unsigned long vm_size;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 
 	vm_size = vma->vm_end - vma->vm_start;
@@ -84,8 +82,6 @@ static int exynos_drm_fbdev_update(struc
 	unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
 	unsigned long offset;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
 	drm_fb_helper_fill_var(fbi, helper, fb->width, fb->height);
 
@@ -148,8 +144,6 @@ static int exynos_drm_fbdev_create(struc
 	unsigned long size;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n",
 			sizes->surface_width, sizes->surface_height,
 			sizes->surface_bpp);
@@ -238,8 +232,6 @@ int exynos_drm_fbdev_init(struct drm_dev
 	unsigned int num_crtc;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
 		return 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fimc.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,6 @@
  *
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
@@ -175,8 +174,6 @@ static void fimc_sw_reset(struct fimc_co
 {
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	/* stop dma operation */
 	cfg = fimc_read(EXYNOS_CISTATUS);
 	if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg)) {
@@ -210,8 +207,6 @@ static void fimc_sw_reset(struct fimc_co
 
 static int fimc_set_camblk_fimd0_wb(struct fimc_context *ctx)
 {
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	return regmap_update_bits(ctx->sysreg, SYSREG_CAMERA_BLK,
 				  SYSREG_FIMD0WB_DEST_MASK,
 				  ctx->id << SYSREG_FIMD0WB_DEST_SHIFT);
@@ -221,7 +216,7 @@ static void fimc_set_type_ctrl(struct fi
 {
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:wb[%d]\n", __func__, wb);
+	DRM_DEBUG_KMS("wb[%d]\n", wb);
 
 	cfg = fimc_read(EXYNOS_CIGCTRL);
 	cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK |
@@ -257,10 +252,10 @@ static void fimc_set_polarity(struct fim
 {
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:inv_pclk[%d]inv_vsync[%d]\n",
-		__func__, pol->inv_pclk, pol->inv_vsync);
-	DRM_DEBUG_KMS("%s:inv_href[%d]inv_hsync[%d]\n",
-		__func__, pol->inv_href, pol->inv_hsync);
+	DRM_DEBUG_KMS("inv_pclk[%d]inv_vsync[%d]\n",
+		pol->inv_pclk, pol->inv_vsync);
+	DRM_DEBUG_KMS("inv_href[%d]inv_hsync[%d]\n",
+		pol->inv_href, pol->inv_hsync);
 
 	cfg = fimc_read(EXYNOS_CIGCTRL);
 	cfg &= ~(EXYNOS_CIGCTRL_INVPOLPCLK | EXYNOS_CIGCTRL_INVPOLVSYNC |
@@ -282,7 +277,7 @@ static void fimc_handle_jpeg(struct fimc
 {
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+	DRM_DEBUG_KMS("enable[%d]\n", enable);
 
 	cfg = fimc_read(EXYNOS_CIGCTRL);
 	if (enable)
@@ -298,7 +293,7 @@ static void fimc_handle_irq(struct fimc_
 {
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:enable[%d]overflow[%d]level[%d]\n", __func__,
+	DRM_DEBUG_KMS("enable[%d]overflow[%d]level[%d]\n",
 			enable, overflow, level);
 
 	cfg = fimc_read(EXYNOS_CIGCTRL);
@@ -319,8 +314,6 @@ static void fimc_clear_irq(struct fimc_c
 {
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	cfg = fimc_read(EXYNOS_CIGCTRL);
 	cfg |= EXYNOS_CIGCTRL_IRQ_CLR;
 	fimc_write(cfg, EXYNOS_CIGCTRL);
@@ -335,7 +328,7 @@ static bool fimc_check_ovf(struct fimc_c
 	flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB |
 		EXYNOS_CISTATUS_OVFICR;
 
-	DRM_DEBUG_KMS("%s:flag[0x%x]\n", __func__, flag);
+	DRM_DEBUG_KMS("flag[0x%x]\n", flag);
 
 	if (status & flag) {
 		cfg = fimc_read(EXYNOS_CIWDOFST);
@@ -364,7 +357,7 @@ static bool fimc_check_frame_end(struct
 
 	cfg = fimc_read(EXYNOS_CISTATUS);
 
-	DRM_DEBUG_KMS("%s:cfg[0x%x]\n", __func__, cfg);
+	DRM_DEBUG_KMS("cfg[0x%x]\n", cfg);
 
 	if (!(cfg & EXYNOS_CISTATUS_FRAMEEND))
 		return false;
@@ -380,15 +373,13 @@ static int fimc_get_buf_id(struct fimc_c
 	u32 cfg;
 	int frame_cnt, buf_id;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	cfg = fimc_read(EXYNOS_CISTATUS2);
 	frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg);
 
 	if (frame_cnt == 0)
 		frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg);
 
-	DRM_DEBUG_KMS("%s:present[%d]before[%d]\n", __func__,
+	DRM_DEBUG_KMS("present[%d]before[%d]\n",
 		EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg),
 		EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg));
 
@@ -398,7 +389,7 @@ static int fimc_get_buf_id(struct fimc_c
 	}
 
 	buf_id = frame_cnt - 1;
-	DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__, buf_id);
+	DRM_DEBUG_KMS("buf_id[%d]\n", buf_id);
 
 	return buf_id;
 }
@@ -407,7 +398,7 @@ static void fimc_handle_lastend(struct f
 {
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+	DRM_DEBUG_KMS("enable[%d]\n", enable);
 
 	cfg = fimc_read(EXYNOS_CIOCTRL);
 	if (enable)
@@ -424,7 +415,7 @@ static int fimc_src_set_fmt_order(struct
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+	DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
 
 	/* RGB */
 	cfg = fimc_read(EXYNOS_CISCCTRL);
@@ -497,7 +488,7 @@ static int fimc_src_set_fmt(struct devic
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+	DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
 
 	cfg = fimc_read(EXYNOS_MSCTRL);
 	cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB;
@@ -557,8 +548,7 @@ static int fimc_src_set_transf(struct de
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg1, cfg2;
 
-	DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
-		degree, flip);
+	DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
 
 	cfg1 = fimc_read(EXYNOS_MSCTRL);
 	cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR |
@@ -621,10 +611,9 @@ static int fimc_set_window(struct fimc_c
 	v1 = pos->y;
 	v2 = sz->vsize - pos->h - pos->y;
 
-	DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n",
-	__func__, pos->x, pos->y, pos->w, pos->h, sz->hsize, sz->vsize);
-	DRM_DEBUG_KMS("%s:h1[%d]h2[%d]v1[%d]v2[%d]\n", __func__,
-		h1, h2, v1, v2);
+	DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n",
+		pos->x, pos->y, pos->w, pos->h, sz->hsize, sz->vsize);
+	DRM_DEBUG_KMS("h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, v2);
 
 	/*
 	 * set window offset 1, 2 size
@@ -653,8 +642,8 @@ static int fimc_src_set_size(struct devi
 	struct drm_exynos_sz img_sz = *sz;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:swap[%d]hsize[%d]vsize[%d]\n",
-		__func__, swap, sz->hsize, sz->vsize);
+	DRM_DEBUG_KMS("swap[%d]hsize[%d]vsize[%d]\n",
+		swap, sz->hsize, sz->vsize);
 
 	/* original size */
 	cfg = (EXYNOS_ORGISIZE_HORIZONTAL(img_sz.hsize) |
@@ -662,8 +651,7 @@ static int fimc_src_set_size(struct devi
 
 	fimc_write(cfg, EXYNOS_ORGISIZE);
 
-	DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]\n", __func__,
-		pos->x, pos->y, pos->w, pos->h);
+	DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h);
 
 	if (swap) {
 		img_pos.w = pos->h;
@@ -720,7 +708,7 @@ static int fimc_src_set_addr(struct devi
 
 	property = &c_node->property;
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
+	DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
 		property->prop_id, buf_id, buf_type);
 
 	if (buf_id > FIMC_MAX_SRC) {
@@ -772,7 +760,7 @@ static int fimc_dst_set_fmt_order(struct
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+	DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
 
 	/* RGB */
 	cfg = fimc_read(EXYNOS_CISCCTRL);
@@ -851,7 +839,7 @@ static int fimc_dst_set_fmt(struct devic
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+	DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
 
 	cfg = fimc_read(EXYNOS_CIEXTEN);
 
@@ -919,8 +907,7 @@ static int fimc_dst_set_transf(struct de
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
-		degree, flip);
+	DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
 
 	cfg = fimc_read(EXYNOS_CITRGFMT);
 	cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK;
@@ -970,7 +957,7 @@ static int fimc_dst_set_transf(struct de
 
 static int fimc_get_ratio_shift(u32 src, u32 dst, u32 *ratio, u32 *shift)
 {
-	DRM_DEBUG_KMS("%s:src[%d]dst[%d]\n", __func__, src, dst);
+	DRM_DEBUG_KMS("src[%d]dst[%d]\n", src, dst);
 
 	if (src >= dst * 64) {
 		DRM_ERROR("failed to make ratio and shift.\n");
@@ -1039,20 +1026,20 @@ static int fimc_set_prescaler(struct fim
 
 	pre_dst_width = src_w / pre_hratio;
 	pre_dst_height = src_h / pre_vratio;
-	DRM_DEBUG_KMS("%s:pre_dst_width[%d]pre_dst_height[%d]\n", __func__,
+	DRM_DEBUG_KMS("pre_dst_width[%d]pre_dst_height[%d]\n",
 		pre_dst_width, pre_dst_height);
-	DRM_DEBUG_KMS("%s:pre_hratio[%d]hfactor[%d]pre_vratio[%d]vfactor[%d]\n",
-		__func__, pre_hratio, hfactor, pre_vratio, vfactor);
+	DRM_DEBUG_KMS("pre_hratio[%d]hfactor[%d]pre_vratio[%d]vfactor[%d]\n",
+		pre_hratio, hfactor, pre_vratio, vfactor);
 
 	sc->hratio = (src_w << 14) / (dst_w << hfactor);
 	sc->vratio = (src_h << 14) / (dst_h << vfactor);
 	sc->up_h = (dst_w >= src_w) ? true : false;
 	sc->up_v = (dst_h >= src_h) ? true : false;
-	DRM_DEBUG_KMS("%s:hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n",
-	__func__, sc->hratio, sc->vratio, sc->up_h, sc->up_v);
+	DRM_DEBUG_KMS("hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n",
+		sc->hratio, sc->vratio, sc->up_h, sc->up_v);
 
 	shfactor = FIMC_SHFACTOR - (hfactor + vfactor);
-	DRM_DEBUG_KMS("%s:shfactor[%d]\n", __func__, shfactor);
+	DRM_DEBUG_KMS("shfactor[%d]\n", shfactor);
 
 	cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) |
 		EXYNOS_CISCPRERATIO_PREHORRATIO(pre_hratio) |
@@ -1070,10 +1057,10 @@ static void fimc_set_scaler(struct fimc_
 {
 	u32 cfg, cfg_ext;
 
-	DRM_DEBUG_KMS("%s:range[%d]bypass[%d]up_h[%d]up_v[%d]\n",
-		__func__, sc->range, sc->bypass, sc->up_h, sc->up_v);
-	DRM_DEBUG_KMS("%s:hratio[%d]vratio[%d]\n",
-		__func__, sc->hratio, sc->vratio);
+	DRM_DEBUG_KMS("range[%d]bypass[%d]up_h[%d]up_v[%d]\n",
+		sc->range, sc->bypass, sc->up_h, sc->up_v);
+	DRM_DEBUG_KMS("hratio[%d]vratio[%d]\n",
+		sc->hratio, sc->vratio);
 
 	cfg = fimc_read(EXYNOS_CISCCTRL);
 	cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS |
@@ -1113,8 +1100,8 @@ static int fimc_dst_set_size(struct devi
 	struct drm_exynos_sz img_sz = *sz;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:swap[%d]hsize[%d]vsize[%d]\n",
-		__func__, swap, sz->hsize, sz->vsize);
+	DRM_DEBUG_KMS("swap[%d]hsize[%d]vsize[%d]\n",
+		swap, sz->hsize, sz->vsize);
 
 	/* original size */
 	cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(img_sz.hsize) |
@@ -1122,8 +1109,7 @@ static int fimc_dst_set_size(struct devi
 
 	fimc_write(cfg, EXYNOS_ORGOSIZE);
 
-	DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]\n",
-		__func__, pos->x, pos->y, pos->w, pos->h);
+	DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h);
 
 	/* CSC ITU */
 	cfg = fimc_read(EXYNOS_CIGCTRL);
@@ -1180,7 +1166,7 @@ static int fimc_dst_get_buf_seq(struct f
 		if (cfg & (mask << i))
 			buf_num++;
 
-	DRM_DEBUG_KMS("%s:buf_num[%d]\n", __func__, buf_num);
+	DRM_DEBUG_KMS("buf_num[%d]\n", buf_num);
 
 	return buf_num;
 }
@@ -1194,8 +1180,7 @@ static int fimc_dst_set_buf_seq(struct f
 	u32 mask = 0x00000001 << buf_id;
 	int ret = 0;
 
-	DRM_DEBUG_KMS("%s:buf_id[%d]buf_type[%d]\n", __func__,
-		buf_id, buf_type);
+	DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
 
 	mutex_lock(&ctx->lock);
 
@@ -1252,7 +1237,7 @@ static int fimc_dst_set_addr(struct devi
 
 	property = &c_node->property;
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
+	DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
 		property->prop_id, buf_id, buf_type);
 
 	if (buf_id > FIMC_MAX_DST) {
@@ -1302,7 +1287,7 @@ static struct exynos_drm_ipp_ops fimc_ds
 
 static int fimc_clk_ctrl(struct fimc_context *ctx, bool enable)
 {
-	DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+	DRM_DEBUG_KMS("enable[%d]\n", enable);
 
 	if (enable) {
 		clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]);
@@ -1326,7 +1311,7 @@ static irqreturn_t fimc_irq_handler(int
 		c_node->event_work;
 	int buf_id;
 
-	DRM_DEBUG_KMS("%s:fimc id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("fimc id[%d]\n", ctx->id);
 
 	fimc_clear_irq(ctx);
 	if (fimc_check_ovf(ctx))
@@ -1339,7 +1324,7 @@ static irqreturn_t fimc_irq_handler(int
 	if (buf_id < 0)
 		return IRQ_HANDLED;
 
-	DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__, buf_id);
+	DRM_DEBUG_KMS("buf_id[%d]\n", buf_id);
 
 	if (fimc_dst_set_buf_seq(ctx, buf_id, IPP_BUF_DEQUEUE) < 0) {
 		DRM_ERROR("failed to dequeue.\n");
@@ -1357,8 +1342,6 @@ static int fimc_init_prop_list(struct ex
 {
 	struct drm_exynos_ipp_prop_list *prop_list;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
 	if (!prop_list) {
 		DRM_ERROR("failed to alloc property list.\n");
@@ -1402,7 +1385,7 @@ static inline bool fimc_check_drm_flip(e
 	case EXYNOS_DRM_FLIP_BOTH:
 		return true;
 	default:
-		DRM_DEBUG_KMS("%s:invalid flip\n", __func__);
+		DRM_DEBUG_KMS("invalid flip\n");
 		return false;
 	}
 }
@@ -1419,8 +1402,6 @@ static int fimc_ippdrv_check_property(st
 	bool swap;
 	int i;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	for_each_ipp_ops(i) {
 		if ((i == EXYNOS_DRM_OPS_SRC) &&
 			(property->cmd == IPP_CMD_WB))
@@ -1526,8 +1507,6 @@ static void fimc_clear_addr(struct fimc_
 {
 	int i;
 
-	DRM_DEBUG_KMS("%s:\n", __func__);
-
 	for (i = 0; i < FIMC_MAX_SRC; i++) {
 		fimc_write(0, EXYNOS_CIIYSA(i));
 		fimc_write(0, EXYNOS_CIICBSA(i));
@@ -1545,8 +1524,6 @@ static int fimc_ippdrv_reset(struct devi
 {
 	struct fimc_context *ctx = get_fimc_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	/* reset h/w block */
 	fimc_sw_reset(ctx);
 
@@ -1570,7 +1547,7 @@ static int fimc_ippdrv_start(struct devi
 	int ret, i;
 	u32 cfg0, cfg1;
 
-	DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
+	DRM_DEBUG_KMS("cmd[%d]\n", cmd);
 
 	if (!c_node) {
 		DRM_ERROR("failed to get c_node.\n");
@@ -1679,7 +1656,7 @@ static void fimc_ippdrv_stop(struct devi
 	struct drm_exynos_ipp_set_wb set_wb = {0, 0};
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
+	DRM_DEBUG_KMS("cmd[%d]\n", cmd);
 
 	switch (cmd) {
 	case IPP_CMD_M2M:
@@ -1869,8 +1846,7 @@ static int fimc_probe(struct platform_de
 		goto err_put_clk;
 	}
 
-	DRM_DEBUG_KMS("%s:id[%d]ippdrv[0x%x]\n", __func__, ctx->id,
-		(int)ippdrv);
+	DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv);
 
 	mutex_init(&ctx->lock);
 	platform_set_drvdata(pdev, ctx);
@@ -1917,7 +1893,7 @@ static int fimc_suspend(struct device *d
 {
 	struct fimc_context *ctx = get_fimc_context(dev);
 
-	DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
 
 	if (pm_runtime_suspended(dev))
 		return 0;
@@ -1929,7 +1905,7 @@ static int fimc_resume(struct device *de
 {
 	struct fimc_context *ctx = get_fimc_context(dev);
 
-	DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
 
 	if (!pm_runtime_suspended(dev))
 		return fimc_clk_ctrl(ctx, true);
@@ -1943,7 +1919,7 @@ static int fimc_runtime_suspend(struct d
 {
 	struct fimc_context *ctx = get_fimc_context(dev);
 
-	DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
 
 	return  fimc_clk_ctrl(ctx, false);
 }
@@ -1952,7 +1928,7 @@ static int fimc_runtime_resume(struct de
 {
 	struct fimc_context *ctx = get_fimc_context(dev);
 
-	DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
 
 	return  fimc_clk_ctrl(ctx, true);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_fimd.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fimd.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_fimd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_fimd.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,7 +14,6 @@
 #include <drm/drmP.h>
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/of_device.h>
@@ -63,14 +62,24 @@
 
 struct fimd_driver_data {
 	unsigned int timing_base;
+
+	unsigned int has_shadowcon:1;
+	unsigned int has_clksel:1;
+};
+
+static struct fimd_driver_data s3c64xx_fimd_driver_data = {
+	.timing_base = 0x0,
+	.has_clksel = 1,
 };
 
 static struct fimd_driver_data exynos4_fimd_driver_data = {
 	.timing_base = 0x0,
+	.has_shadowcon = 1,
 };
 
 static struct fimd_driver_data exynos5_fimd_driver_data = {
 	.timing_base = 0x20000,
+	.has_shadowcon = 1,
 };
 
 struct fimd_win_data {
@@ -107,17 +116,19 @@ struct fimd_context {
 	atomic_t			wait_vsync_event;
 
 	struct exynos_drm_panel_info *panel;
+	struct fimd_driver_data *driver_data;
 };
 
 #ifdef CONFIG_OF
 static const struct of_device_id fimd_driver_dt_match[] = {
+	{ .compatible = "samsung,s3c6400-fimd",
+	  .data = &s3c64xx_fimd_driver_data },
 	{ .compatible = "samsung,exynos4210-fimd",
 	  .data = &exynos4_fimd_driver_data },
 	{ .compatible = "samsung,exynos5250-fimd",
 	  .data = &exynos5_fimd_driver_data },
 	{},
 };
-MODULE_DEVICE_TABLE(of, fimd_driver_dt_match);
 #endif
 
 static inline struct fimd_driver_data *drm_fimd_get_driver_data(
@@ -137,8 +148,6 @@ static inline struct fimd_driver_data *d
 
 static bool fimd_display_is_connected(struct device *dev)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* TODO. */
 
 	return true;
@@ -148,15 +157,11 @@ static void *fimd_get_panel(struct devic
 {
 	struct fimd_context *ctx = get_fimd_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	return ctx->panel;
 }
 
-static int fimd_check_timing(struct device *dev, void *timing)
+static int fimd_check_mode(struct device *dev, struct drm_display_mode *mode)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* TODO. */
 
 	return 0;
@@ -164,8 +169,6 @@ static int fimd_check_timing(struct devi
 
 static int fimd_display_power_on(struct device *dev, int mode)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* TODO */
 
 	return 0;
@@ -175,7 +178,7 @@ static struct exynos_drm_display_ops fim
 	.type = EXYNOS_DISPLAY_TYPE_LCD,
 	.is_connected = fimd_display_is_connected,
 	.get_panel = fimd_get_panel,
-	.check_timing = fimd_check_timing,
+	.check_mode = fimd_check_mode,
 	.power_on = fimd_display_power_on,
 };
 
@@ -183,7 +186,7 @@ static void fimd_dpms(struct device *sub
 {
 	struct fimd_context *ctx = get_fimd_context(subdrv_dev);
 
-	DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
+	DRM_DEBUG_KMS("%d\n", mode);
 
 	mutex_lock(&ctx->lock);
 
@@ -221,8 +224,6 @@ static void fimd_apply(struct device *su
 	struct fimd_win_data *win_data;
 	int i;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	for (i = 0; i < WINDOWS_NR; i++) {
 		win_data = &ctx->win_data[i];
 		if (win_data->enabled && (ovl_ops && ovl_ops->commit))
@@ -239,15 +240,12 @@ static void fimd_commit(struct device *d
 	struct exynos_drm_panel_info *panel = ctx->panel;
 	struct fb_videomode *timing = &panel->timing;
 	struct fimd_driver_data *driver_data;
-	struct platform_device *pdev = to_platform_device(dev);
 	u32 val;
 
-	driver_data = drm_fimd_get_driver_data(pdev);
+	driver_data = ctx->driver_data;
 	if (ctx->suspended)
 		return;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* setup polarity values from machine code. */
 	writel(ctx->vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
 
@@ -274,6 +272,11 @@ static void fimd_commit(struct device *d
 	val = ctx->vidcon0;
 	val &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
 
+	if (ctx->driver_data->has_clksel) {
+		val &= ~VIDCON0_CLKSEL_MASK;
+		val |= VIDCON0_CLKSEL_LCD;
+	}
+
 	if (ctx->clkdiv > 1)
 		val |= VIDCON0_CLKVAL_F(ctx->clkdiv - 1) | VIDCON0_CLKDIR;
 	else
@@ -292,8 +295,6 @@ static int fimd_enable_vblank(struct dev
 	struct fimd_context *ctx = get_fimd_context(dev);
 	u32 val;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (ctx->suspended)
 		return -EPERM;
 
@@ -319,8 +320,6 @@ static void fimd_disable_vblank(struct d
 	struct fimd_context *ctx = get_fimd_context(dev);
 	u32 val;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (ctx->suspended)
 		return;
 
@@ -370,8 +369,6 @@ static void fimd_win_mode_set(struct dev
 	int win;
 	unsigned long offset;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (!overlay) {
 		dev_err(dev, "overlay is NULL\n");
 		return;
@@ -381,7 +378,7 @@ static void fimd_win_mode_set(struct dev
 	if (win == DEFAULT_ZPOS)
 		win = ctx->default_win;
 
-	if (win < 0 || win > WINDOWS_NR)
+	if (win < 0 || win >= WINDOWS_NR)
 		return;
 
 	offset = overlay->fb_x * (overlay->bpp >> 3);
@@ -418,8 +415,6 @@ static void fimd_win_set_pixfmt(struct d
 	struct fimd_win_data *win_data = &ctx->win_data[win];
 	unsigned long val;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	val = WINCONx_ENWIN;
 
 	switch (win_data->bpp) {
@@ -478,8 +473,6 @@ static void fimd_win_set_colkey(struct d
 	struct fimd_context *ctx = get_fimd_context(dev);
 	unsigned int keycon0 = 0, keycon1 = 0;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F |
 			WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0);
 
@@ -489,6 +482,33 @@ static void fimd_win_set_colkey(struct d
 	writel(keycon1, ctx->regs + WKEYCON1_BASE(win));
 }
 
+/**
+ * shadow_protect_win() - disable updating values from shadow registers at vsync
+ *
+ * @win: window to protect registers for
+ * @protect: 1 to protect (disable updates)
+ */
+static void fimd_shadow_protect_win(struct fimd_context *ctx,
+							int win, bool protect)
+{
+	u32 reg, bits, val;
+
+	if (ctx->driver_data->has_shadowcon) {
+		reg = SHADOWCON;
+		bits = SHADOWCON_WINx_PROTECT(win);
+	} else {
+		reg = PRTCON;
+		bits = PRTCON_PROTECT;
+	}
+
+	val = readl(ctx->regs + reg);
+	if (protect)
+		val |= bits;
+	else
+		val &= ~bits;
+	writel(val, ctx->regs + reg);
+}
+
 static void fimd_win_commit(struct device *dev, int zpos)
 {
 	struct fimd_context *ctx = get_fimd_context(dev);
@@ -498,21 +518,19 @@ static void fimd_win_commit(struct devic
 	unsigned int last_x;
 	unsigned int last_y;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (ctx->suspended)
 		return;
 
 	if (win == DEFAULT_ZPOS)
 		win = ctx->default_win;
 
-	if (win < 0 || win > WINDOWS_NR)
+	if (win < 0 || win >= WINDOWS_NR)
 		return;
 
 	win_data = &ctx->win_data[win];
 
 	/*
-	 * SHADOWCON register is used for enabling timing.
+	 * SHADOWCON/PRTCON register is used for enabling timing.
 	 *
 	 * for example, once only width value of a register is set,
 	 * if the dma is started then fimd hardware could malfunction so
@@ -522,9 +540,7 @@ static void fimd_win_commit(struct devic
 	 */
 
 	/* protect windows */
-	val = readl(ctx->regs + SHADOWCON);
-	val |= SHADOWCON_WINx_PROTECT(win);
-	writel(val, ctx->regs + SHADOWCON);
+	fimd_shadow_protect_win(ctx, win, true);
 
 	/* buffer start address */
 	val = (unsigned long)win_data->dma_addr;
@@ -602,10 +618,13 @@ static void fimd_win_commit(struct devic
 	writel(val, ctx->regs + WINCON(win));
 
 	/* Enable DMA channel and unprotect windows */
-	val = readl(ctx->regs + SHADOWCON);
-	val |= SHADOWCON_CHx_ENABLE(win);
-	val &= ~SHADOWCON_WINx_PROTECT(win);
-	writel(val, ctx->regs + SHADOWCON);
+	fimd_shadow_protect_win(ctx, win, false);
+
+	if (ctx->driver_data->has_shadowcon) {
+		val = readl(ctx->regs + SHADOWCON);
+		val |= SHADOWCON_CHx_ENABLE(win);
+		writel(val, ctx->regs + SHADOWCON);
+	}
 
 	win_data->enabled = true;
 }
@@ -617,12 +636,10 @@ static void fimd_win_disable(struct devi
 	int win = zpos;
 	u32 val;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (win == DEFAULT_ZPOS)
 		win = ctx->default_win;
 
-	if (win < 0 || win > WINDOWS_NR)
+	if (win < 0 || win >= WINDOWS_NR)
 		return;
 
 	win_data = &ctx->win_data[win];
@@ -634,9 +651,7 @@ static void fimd_win_disable(struct devi
 	}
 
 	/* protect windows */
-	val = readl(ctx->regs + SHADOWCON);
-	val |= SHADOWCON_WINx_PROTECT(win);
-	writel(val, ctx->regs + SHADOWCON);
+	fimd_shadow_protect_win(ctx, win, true);
 
 	/* wincon */
 	val = readl(ctx->regs + WINCON(win));
@@ -644,10 +659,13 @@ static void fimd_win_disable(struct devi
 	writel(val, ctx->regs + WINCON(win));
 
 	/* unprotect windows */
-	val = readl(ctx->regs + SHADOWCON);
-	val &= ~SHADOWCON_CHx_ENABLE(win);
-	val &= ~SHADOWCON_WINx_PROTECT(win);
-	writel(val, ctx->regs + SHADOWCON);
+	if (ctx->driver_data->has_shadowcon) {
+		val = readl(ctx->regs + SHADOWCON);
+		val &= ~SHADOWCON_CHx_ENABLE(win);
+		writel(val, ctx->regs + SHADOWCON);
+	}
+
+	fimd_shadow_protect_win(ctx, win, false);
 
 	win_data->enabled = false;
 }
@@ -697,8 +715,6 @@ out:
 
 static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	 * enable drm irq mode.
 	 * - with irq_enabled = 1, we can use the vblank feature.
@@ -725,8 +741,6 @@ static int fimd_subdrv_probe(struct drm_
 
 static void fimd_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* detach this sub driver from iommu mapping if supported. */
 	if (is_drm_iommu_supported(drm_dev))
 		drm_iommu_detach_device(drm_dev, dev);
@@ -741,8 +755,6 @@ static int fimd_calc_clkdiv(struct fimd_
 	u32 best_framerate = 0;
 	u32 framerate;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	retrace = timing->left_margin + timing->hsync_len +
 				timing->right_margin + timing->xres;
 	retrace *= timing->upper_margin + timing->vsync_len +
@@ -777,10 +789,6 @@ static int fimd_calc_clkdiv(struct fimd_
 
 static void fimd_clear_win(struct fimd_context *ctx, int win)
 {
-	u32 val;
-
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	writel(0, ctx->regs + WINCON(win));
 	writel(0, ctx->regs + VIDOSD_A(win));
 	writel(0, ctx->regs + VIDOSD_B(win));
@@ -789,15 +797,11 @@ static void fimd_clear_win(struct fimd_c
 	if (win == 1 || win == 2)
 		writel(0, ctx->regs + VIDOSD_D(win));
 
-	val = readl(ctx->regs + SHADOWCON);
-	val &= ~SHADOWCON_WINx_PROTECT(win);
-	writel(val, ctx->regs + SHADOWCON);
+	fimd_shadow_protect_win(ctx, win, false);
 }
 
 static int fimd_clock(struct fimd_context *ctx, bool enable)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (enable) {
 		int ret;
 
@@ -883,8 +887,6 @@ static int fimd_probe(struct platform_de
 	int win;
 	int ret = -EINVAL;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (dev->of_node) {
 		pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 		if (!pdata) {
@@ -949,6 +951,7 @@ static int fimd_probe(struct platform_de
 		return ret;
 	}
 
+	ctx->driver_data = drm_fimd_get_driver_data(pdev);
 	ctx->vidcon0 = pdata->vidcon0;
 	ctx->vidcon1 = pdata->vidcon1;
 	ctx->default_win = pdata->default_win;
@@ -989,8 +992,6 @@ static int fimd_remove(struct platform_d
 	struct device *dev = &pdev->dev;
 	struct fimd_context *ctx = platform_get_drvdata(pdev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_drm_subdrv_unregister(&ctx->subdrv);
 
 	if (ctx->suspended)
@@ -1055,8 +1056,6 @@ static int fimd_runtime_suspend(struct d
 {
 	struct fimd_context *ctx = get_fimd_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	return fimd_activate(ctx, false);
 }
 
@@ -1064,14 +1063,15 @@ static int fimd_runtime_resume(struct de
 {
 	struct fimd_context *ctx = get_fimd_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	return fimd_activate(ctx, true);
 }
 #endif
 
 static struct platform_device_id fimd_driver_ids[] = {
 	{
+		.name		= "s3c64xx-fb",
+		.driver_data	= (unsigned long)&s3c64xx_fimd_driver_data,
+	}, {
 		.name		= "exynos4-fb",
 		.driver_data	= (unsigned long)&exynos4_fimd_driver_data,
 	}, {
@@ -1080,7 +1080,6 @@ static struct platform_device_id fimd_dr
 	},
 	{},
 };
-MODULE_DEVICE_TABLE(platform, fimd_driver_ids);
 
 static const struct dev_pm_ops fimd_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_g2d.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_g2d.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_g2d.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_g2d.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
@@ -388,12 +387,9 @@ out:
 
 	sg_free_table(g2d_userptr->sgt);
 	kfree(g2d_userptr->sgt);
-	g2d_userptr->sgt = NULL;
 
-	kfree(g2d_userptr->pages);
-	g2d_userptr->pages = NULL;
+	drm_free_large(g2d_userptr->pages);
 	kfree(g2d_userptr);
-	g2d_userptr = NULL;
 }
 
 static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
@@ -463,11 +459,11 @@ static dma_addr_t *g2d_userptr_get_dma_a
 	npages = (end - start) >> PAGE_SHIFT;
 	g2d_userptr->npages = npages;
 
-	pages = kzalloc(npages * sizeof(struct page *), GFP_KERNEL);
+	pages = drm_calloc_large(npages, sizeof(struct page *));
 	if (!pages) {
 		DRM_ERROR("failed to allocate pages.\n");
-		kfree(g2d_userptr);
-		return ERR_PTR(-ENOMEM);
+		ret = -ENOMEM;
+		goto err_free;
 	}
 
 	vma = find_vma(current->mm, userptr);
@@ -543,7 +539,6 @@ err_sg_free_table:
 
 err_free_sgt:
 	kfree(sgt);
-	sgt = NULL;
 
 err_free_userptr:
 	exynos_gem_put_pages_to_userptr(g2d_userptr->pages,
@@ -554,10 +549,10 @@ err_put_vma:
 	exynos_gem_put_vma(g2d_userptr->vma);
 
 err_free_pages:
-	kfree(pages);
+	drm_free_large(pages);
+
+err_free:
 	kfree(g2d_userptr);
-	pages = NULL;
-	g2d_userptr = NULL;
 
 	return ERR_PTR(ret);
 }
@@ -810,9 +805,20 @@ static void g2d_dma_start(struct g2d_dat
 	struct g2d_cmdlist_node *node =
 				list_first_entry(&runqueue_node->run_cmdlist,
 						struct g2d_cmdlist_node, list);
+	int ret;
 
-	pm_runtime_get_sync(g2d->dev);
-	clk_enable(g2d->gate_clk);
+	ret = pm_runtime_get_sync(g2d->dev);
+	if (ret < 0) {
+		dev_warn(g2d->dev, "failed pm power on.\n");
+		return;
+	}
+
+	ret = clk_prepare_enable(g2d->gate_clk);
+	if (ret < 0) {
+		dev_warn(g2d->dev, "failed to enable clock.\n");
+		pm_runtime_put_sync(g2d->dev);
+		return;
+	}
 
 	writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR);
 	writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND);
@@ -865,7 +871,7 @@ static void g2d_runqueue_worker(struct w
 					    runqueue_work);
 
 	mutex_lock(&g2d->runqueue_mutex);
-	clk_disable(g2d->gate_clk);
+	clk_disable_unprepare(g2d->gate_clk);
 	pm_runtime_put_sync(g2d->dev);
 
 	complete(&g2d->runqueue_node->complete);
@@ -1525,7 +1531,6 @@ static const struct of_device_id exynos_
 	{ .compatible = "samsung,exynos5250-g2d" },
 	{},
 };
-MODULE_DEVICE_TABLE(of, exynos_g2d_match);
 #endif
 
 struct platform_driver g2d_driver = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_gem.c	2013-08-25 20:43:22.000000000 -0400
@@ -132,8 +132,6 @@ void exynos_drm_gem_destroy(struct exyno
 	struct drm_gem_object *obj;
 	struct exynos_drm_gem_buf *buf;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	obj = &exynos_gem_obj->base;
 	buf = exynos_gem_obj->buffer;
 
@@ -227,7 +225,6 @@ struct exynos_drm_gem_obj *exynos_drm_ge
 	}
 
 	size = roundup_gem_size(size, flags);
-	DRM_DEBUG_KMS("%s\n", __FILE__);
 
 	ret = check_gem_flags(flags);
 	if (ret)
@@ -249,13 +246,14 @@ struct exynos_drm_gem_obj *exynos_drm_ge
 	exynos_gem_obj->flags = flags;
 
 	ret = exynos_drm_alloc_buf(dev, buf, flags);
-	if (ret < 0) {
-		drm_gem_object_release(&exynos_gem_obj->base);
-		goto err_fini_buf;
-	}
+	if (ret < 0)
+		goto err_gem_fini;
 
 	return exynos_gem_obj;
 
+err_gem_fini:
+	drm_gem_object_release(&exynos_gem_obj->base);
+	kfree(exynos_gem_obj);
 err_fini_buf:
 	exynos_drm_fini_buf(dev, buf);
 	return ERR_PTR(ret);
@@ -268,8 +266,6 @@ int exynos_drm_gem_create_ioctl(struct d
 	struct exynos_drm_gem_obj *exynos_gem_obj;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);
 	if (IS_ERR(exynos_gem_obj))
 		return PTR_ERR(exynos_gem_obj);
@@ -331,8 +327,6 @@ int exynos_drm_gem_map_offset_ioctl(stru
 {
 	struct drm_exynos_gem_map_off *args = data;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	DRM_DEBUG_KMS("handle = 0x%x, offset = 0x%lx\n",
 			args->handle, (unsigned long)args->offset);
 
@@ -371,8 +365,6 @@ static int exynos_drm_gem_mmap_buffer(st
 	unsigned long vm_size;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_private_data = obj;
 	vma->vm_ops = drm_dev->driver->gem_vm_ops;
@@ -429,9 +421,7 @@ int exynos_drm_gem_mmap_ioctl(struct drm
 {
 	struct drm_exynos_gem_mmap *args = data;
 	struct drm_gem_object *obj;
-	unsigned int addr;
-
-	DRM_DEBUG_KMS("%s\n", __FILE__);
+	unsigned long addr;
 
 	if (!(dev->driver->driver_features & DRIVER_GEM)) {
 		DRM_ERROR("does not support GEM.\n");
@@ -473,14 +463,14 @@ int exynos_drm_gem_mmap_ioctl(struct drm
 
 	drm_gem_object_unreference(obj);
 
-	if (IS_ERR((void *)addr)) {
+	if (IS_ERR_VALUE(addr)) {
 		/* check filp->f_op, filp->private_data are restored */
 		if (file_priv->filp->f_op == &exynos_drm_gem_fops) {
 			file_priv->filp->f_op = fops_get(dev->driver->fops);
 			file_priv->filp->private_data = file_priv;
 		}
 		mutex_unlock(&dev->struct_mutex);
-		return PTR_ERR((void *)addr);
+		return (int)addr;
 	}
 
 	mutex_unlock(&dev->struct_mutex);
@@ -643,8 +633,6 @@ void exynos_gem_unmap_sgt_from_dma(struc
 
 int exynos_drm_gem_init_object(struct drm_gem_object *obj)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	return 0;
 }
 
@@ -653,8 +641,6 @@ void exynos_drm_gem_free_object(struct d
 	struct exynos_drm_gem_obj *exynos_gem_obj;
 	struct exynos_drm_gem_buf *buf;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_gem_obj = to_exynos_gem_obj(obj);
 	buf = exynos_gem_obj->buffer;
 
@@ -671,8 +657,6 @@ int exynos_drm_gem_dumb_create(struct dr
 	struct exynos_drm_gem_obj *exynos_gem_obj;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	 * alocate memory to be used for framebuffer.
 	 * - this callback would be called by user application
@@ -704,8 +688,6 @@ int exynos_drm_gem_dumb_map_offset(struc
 	struct drm_gem_object *obj;
 	int ret = 0;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	mutex_lock(&dev->struct_mutex);
 
 	/*
@@ -743,8 +725,6 @@ int exynos_drm_gem_dumb_destroy(struct d
 {
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	 * obj->refcount and obj->handle_count are decreased and
 	 * if both them are 0 then exynos_drm_gem_free_object()
@@ -788,8 +768,6 @@ int exynos_drm_gem_mmap(struct file *fil
 	struct drm_gem_object *obj;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* set vm_area_struct. */
 	ret = drm_gem_mmap(filp, vma);
 	if (ret < 0) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_gsc.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,6 @@
  *
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
@@ -400,8 +399,6 @@ static int gsc_sw_reset(struct gsc_conte
 	u32 cfg;
 	int count = GSC_RESET_TIMEOUT;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	/* s/w reset */
 	cfg = (GSC_SW_RESET_SRESET);
 	gsc_write(cfg, GSC_SW_RESET);
@@ -441,8 +438,6 @@ static void gsc_set_gscblk_fimd_wb(struc
 {
 	u32 gscblk_cfg;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	gscblk_cfg = readl(SYSREG_GSCBLK_CFG1);
 
 	if (enable)
@@ -460,7 +455,7 @@ static void gsc_handle_irq(struct gsc_co
 {
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:enable[%d]overflow[%d]level[%d]\n", __func__,
+	DRM_DEBUG_KMS("enable[%d]overflow[%d]level[%d]\n",
 			enable, overflow, done);
 
 	cfg = gsc_read(GSC_IRQ);
@@ -491,7 +486,7 @@ static int gsc_src_set_fmt(struct device
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+	DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
 
 	cfg = gsc_read(GSC_IN_CON);
 	cfg &= ~(GSC_IN_RGB_TYPE_MASK | GSC_IN_YUV422_1P_ORDER_MASK |
@@ -567,8 +562,7 @@ static int gsc_src_set_transf(struct dev
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
-		degree, flip);
+	DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
 
 	cfg = gsc_read(GSC_IN_CON);
 	cfg &= ~GSC_IN_ROT_MASK;
@@ -616,8 +610,8 @@ static int gsc_src_set_size(struct devic
 	struct gsc_scaler *sc = &ctx->sc;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
-		__func__, swap, pos->x, pos->y, pos->w, pos->h);
+	DRM_DEBUG_KMS("swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
+		swap, pos->x, pos->y, pos->w, pos->h);
 
 	if (swap) {
 		img_pos.w = pos->h;
@@ -634,8 +628,7 @@ static int gsc_src_set_size(struct devic
 		GSC_CROPPED_HEIGHT(img_pos.h));
 	gsc_write(cfg, GSC_CROPPED_SIZE);
 
-	DRM_DEBUG_KMS("%s:hsize[%d]vsize[%d]\n",
-		__func__, sz->hsize, sz->vsize);
+	DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", sz->hsize, sz->vsize);
 
 	/* original size */
 	cfg = gsc_read(GSC_SRCIMG_SIZE);
@@ -650,8 +643,7 @@ static int gsc_src_set_size(struct devic
 	cfg = gsc_read(GSC_IN_CON);
 	cfg &= ~GSC_IN_RGB_TYPE_MASK;
 
-	DRM_DEBUG_KMS("%s:width[%d]range[%d]\n",
-		__func__, pos->w, sc->range);
+	DRM_DEBUG_KMS("width[%d]range[%d]\n", pos->w, sc->range);
 
 	if (pos->w >= GSC_WIDTH_ITU_709)
 		if (sc->range)
@@ -677,8 +669,7 @@ static int gsc_src_set_buf_seq(struct gs
 	u32 cfg;
 	u32 mask = 0x00000001 << buf_id;
 
-	DRM_DEBUG_KMS("%s:buf_id[%d]buf_type[%d]\n", __func__,
-		buf_id, buf_type);
+	DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
 
 	/* mask register set */
 	cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK);
@@ -721,7 +712,7 @@ static int gsc_src_set_addr(struct devic
 
 	property = &c_node->property;
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
+	DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
 		property->prop_id, buf_id, buf_type);
 
 	if (buf_id > GSC_MAX_SRC) {
@@ -765,7 +756,7 @@ static int gsc_dst_set_fmt(struct device
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
+	DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
 
 	cfg = gsc_read(GSC_OUT_CON);
 	cfg &= ~(GSC_OUT_RGB_TYPE_MASK | GSC_OUT_YUV422_1P_ORDER_MASK |
@@ -838,8 +829,7 @@ static int gsc_dst_set_transf(struct dev
 	struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
-		degree, flip);
+	DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
 
 	cfg = gsc_read(GSC_IN_CON);
 	cfg &= ~GSC_IN_ROT_MASK;
@@ -881,7 +871,7 @@ static int gsc_dst_set_transf(struct dev
 
 static int gsc_get_ratio_shift(u32 src, u32 dst, u32 *ratio)
 {
-	DRM_DEBUG_KMS("%s:src[%d]dst[%d]\n", __func__, src, dst);
+	DRM_DEBUG_KMS("src[%d]dst[%d]\n", src, dst);
 
 	if (src >= dst * 8) {
 		DRM_ERROR("failed to make ratio and shift.\n");
@@ -944,20 +934,19 @@ static int gsc_set_prescaler(struct gsc_
 		return ret;
 	}
 
-	DRM_DEBUG_KMS("%s:pre_hratio[%d]pre_vratio[%d]\n",
-		__func__, sc->pre_hratio, sc->pre_vratio);
+	DRM_DEBUG_KMS("pre_hratio[%d]pre_vratio[%d]\n",
+		sc->pre_hratio, sc->pre_vratio);
 
 	sc->main_hratio = (src_w << 16) / dst_w;
 	sc->main_vratio = (src_h << 16) / dst_h;
 
-	DRM_DEBUG_KMS("%s:main_hratio[%ld]main_vratio[%ld]\n",
-		__func__, sc->main_hratio, sc->main_vratio);
+	DRM_DEBUG_KMS("main_hratio[%ld]main_vratio[%ld]\n",
+		sc->main_hratio, sc->main_vratio);
 
 	gsc_get_prescaler_shfactor(sc->pre_hratio, sc->pre_vratio,
 		&sc->pre_shfactor);
 
-	DRM_DEBUG_KMS("%s:pre_shfactor[%d]\n", __func__,
-		sc->pre_shfactor);
+	DRM_DEBUG_KMS("pre_shfactor[%d]\n", sc->pre_shfactor);
 
 	cfg = (GSC_PRESC_SHFACTOR(sc->pre_shfactor) |
 		GSC_PRESC_H_RATIO(sc->pre_hratio) |
@@ -1023,8 +1012,8 @@ static void gsc_set_scaler(struct gsc_co
 {
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:main_hratio[%ld]main_vratio[%ld]\n",
-		__func__, sc->main_hratio, sc->main_vratio);
+	DRM_DEBUG_KMS("main_hratio[%ld]main_vratio[%ld]\n",
+		sc->main_hratio, sc->main_vratio);
 
 	gsc_set_h_coef(ctx, sc->main_hratio);
 	cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio);
@@ -1043,8 +1032,8 @@ static int gsc_dst_set_size(struct devic
 	struct gsc_scaler *sc = &ctx->sc;
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
-		__func__, swap, pos->x, pos->y, pos->w, pos->h);
+	DRM_DEBUG_KMS("swap[%d]x[%d]y[%d]w[%d]h[%d]\n",
+		swap, pos->x, pos->y, pos->w, pos->h);
 
 	if (swap) {
 		img_pos.w = pos->h;
@@ -1060,8 +1049,7 @@ static int gsc_dst_set_size(struct devic
 	cfg = (GSC_SCALED_WIDTH(img_pos.w) | GSC_SCALED_HEIGHT(img_pos.h));
 	gsc_write(cfg, GSC_SCALED_SIZE);
 
-	DRM_DEBUG_KMS("%s:hsize[%d]vsize[%d]\n",
-		__func__, sz->hsize, sz->vsize);
+	DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", sz->hsize, sz->vsize);
 
 	/* original size */
 	cfg = gsc_read(GSC_DSTIMG_SIZE);
@@ -1074,8 +1062,7 @@ static int gsc_dst_set_size(struct devic
 	cfg = gsc_read(GSC_OUT_CON);
 	cfg &= ~GSC_OUT_RGB_TYPE_MASK;
 
-	DRM_DEBUG_KMS("%s:width[%d]range[%d]\n",
-		__func__, pos->w, sc->range);
+	DRM_DEBUG_KMS("width[%d]range[%d]\n", pos->w, sc->range);
 
 	if (pos->w >= GSC_WIDTH_ITU_709)
 		if (sc->range)
@@ -1104,7 +1091,7 @@ static int gsc_dst_get_buf_seq(struct gs
 		if (cfg & (mask << i))
 			buf_num--;
 
-	DRM_DEBUG_KMS("%s:buf_num[%d]\n", __func__, buf_num);
+	DRM_DEBUG_KMS("buf_num[%d]\n", buf_num);
 
 	return buf_num;
 }
@@ -1118,8 +1105,7 @@ static int gsc_dst_set_buf_seq(struct gs
 	u32 mask = 0x00000001 << buf_id;
 	int ret = 0;
 
-	DRM_DEBUG_KMS("%s:buf_id[%d]buf_type[%d]\n", __func__,
-		buf_id, buf_type);
+	DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
 
 	mutex_lock(&ctx->lock);
 
@@ -1177,7 +1163,7 @@ static int gsc_dst_set_addr(struct devic
 
 	property = &c_node->property;
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
+	DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n",
 		property->prop_id, buf_id, buf_type);
 
 	if (buf_id > GSC_MAX_DST) {
@@ -1217,7 +1203,7 @@ static struct exynos_drm_ipp_ops gsc_dst
 
 static int gsc_clk_ctrl(struct gsc_context *ctx, bool enable)
 {
-	DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+	DRM_DEBUG_KMS("enable[%d]\n", enable);
 
 	if (enable) {
 		clk_enable(ctx->gsc_clk);
@@ -1236,7 +1222,7 @@ static int gsc_get_src_buf_index(struct
 	u32 buf_id = GSC_MAX_SRC;
 	int ret;
 
-	DRM_DEBUG_KMS("%s:gsc id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id);
 
 	cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK);
 	curr_index = GSC_IN_CURR_GET_INDEX(cfg);
@@ -1259,7 +1245,7 @@ static int gsc_get_src_buf_index(struct
 		return ret;
 	}
 
-	DRM_DEBUG_KMS("%s:cfg[0x%x]curr_index[%d]buf_id[%d]\n", __func__, cfg,
+	DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg,
 		curr_index, buf_id);
 
 	return buf_id;
@@ -1271,7 +1257,7 @@ static int gsc_get_dst_buf_index(struct
 	u32 buf_id = GSC_MAX_DST;
 	int ret;
 
-	DRM_DEBUG_KMS("%s:gsc id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id);
 
 	cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK);
 	curr_index = GSC_OUT_CURR_GET_INDEX(cfg);
@@ -1294,7 +1280,7 @@ static int gsc_get_dst_buf_index(struct
 		return ret;
 	}
 
-	DRM_DEBUG_KMS("%s:cfg[0x%x]curr_index[%d]buf_id[%d]\n", __func__, cfg,
+	DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg,
 		curr_index, buf_id);
 
 	return buf_id;
@@ -1310,7 +1296,7 @@ static irqreturn_t gsc_irq_handler(int i
 	u32 status;
 	int buf_id[EXYNOS_DRM_OPS_MAX];
 
-	DRM_DEBUG_KMS("%s:gsc id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id);
 
 	status = gsc_read(GSC_IRQ);
 	if (status & GSC_IRQ_STATUS_OR_IRQ) {
@@ -1331,7 +1317,7 @@ static irqreturn_t gsc_irq_handler(int i
 		if (buf_id[EXYNOS_DRM_OPS_DST] < 0)
 			return IRQ_HANDLED;
 
-		DRM_DEBUG_KMS("%s:buf_id_src[%d]buf_id_dst[%d]\n", __func__,
+		DRM_DEBUG_KMS("buf_id_src[%d]buf_id_dst[%d]\n",
 			buf_id[EXYNOS_DRM_OPS_SRC], buf_id[EXYNOS_DRM_OPS_DST]);
 
 		event_work->ippdrv = ippdrv;
@@ -1350,8 +1336,6 @@ static int gsc_init_prop_list(struct exy
 {
 	struct drm_exynos_ipp_prop_list *prop_list;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
 	if (!prop_list) {
 		DRM_ERROR("failed to alloc property list.\n");
@@ -1394,7 +1378,7 @@ static inline bool gsc_check_drm_flip(en
 	case EXYNOS_DRM_FLIP_BOTH:
 		return true;
 	default:
-		DRM_DEBUG_KMS("%s:invalid flip\n", __func__);
+		DRM_DEBUG_KMS("invalid flip\n");
 		return false;
 	}
 }
@@ -1411,8 +1395,6 @@ static int gsc_ippdrv_check_property(str
 	bool swap;
 	int i;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	for_each_ipp_ops(i) {
 		if ((i == EXYNOS_DRM_OPS_SRC) &&
 			(property->cmd == IPP_CMD_WB))
@@ -1521,8 +1503,6 @@ static int gsc_ippdrv_reset(struct devic
 	struct gsc_scaler *sc = &ctx->sc;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	/* reset h/w block */
 	ret = gsc_sw_reset(ctx);
 	if (ret < 0) {
@@ -1549,7 +1529,7 @@ static int gsc_ippdrv_start(struct devic
 	u32 cfg;
 	int ret, i;
 
-	DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
+	DRM_DEBUG_KMS("cmd[%d]\n", cmd);
 
 	if (!c_node) {
 		DRM_ERROR("failed to get c_node.\n");
@@ -1643,7 +1623,7 @@ static void gsc_ippdrv_stop(struct devic
 	struct drm_exynos_ipp_set_wb set_wb = {0, 0};
 	u32 cfg;
 
-	DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
+	DRM_DEBUG_KMS("cmd[%d]\n", cmd);
 
 	switch (cmd) {
 	case IPP_CMD_M2M:
@@ -1728,8 +1708,7 @@ static int gsc_probe(struct platform_dev
 		return ret;
 	}
 
-	DRM_DEBUG_KMS("%s:id[%d]ippdrv[0x%x]\n", __func__, ctx->id,
-		(int)ippdrv);
+	DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv);
 
 	mutex_init(&ctx->lock);
 	platform_set_drvdata(pdev, ctx);
@@ -1772,7 +1751,7 @@ static int gsc_suspend(struct device *de
 {
 	struct gsc_context *ctx = get_gsc_context(dev);
 
-	DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
 
 	if (pm_runtime_suspended(dev))
 		return 0;
@@ -1784,7 +1763,7 @@ static int gsc_resume(struct device *dev
 {
 	struct gsc_context *ctx = get_gsc_context(dev);
 
-	DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
 
 	if (!pm_runtime_suspended(dev))
 		return gsc_clk_ctrl(ctx, true);
@@ -1798,7 +1777,7 @@ static int gsc_runtime_suspend(struct de
 {
 	struct gsc_context *ctx = get_gsc_context(dev);
 
-	DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
+	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
 
 	return  gsc_clk_ctrl(ctx, false);
 }
@@ -1807,7 +1786,7 @@ static int gsc_runtime_resume(struct dev
 {
 	struct gsc_context *ctx = get_gsc_context(dev);
 
-	DRM_DEBUG_KMS("%s:id[%d]\n", __FILE__, ctx->id);
+	DRM_DEBUG_KMS("id[%d]\n", ctx->id);
 
 	return  gsc_clk_ctrl(ctx, true);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_hdmi.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_hdmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_hdmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,6 @@
 
 #include <linux/kernel.h>
 #include <linux/wait.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
@@ -88,16 +87,12 @@ void exynos_mixer_drv_attach(struct exyn
 
 void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (ops)
 		hdmi_ops = ops;
 }
 
 void exynos_mixer_ops_register(struct exynos_mixer_ops *ops)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (ops)
 		mixer_ops = ops;
 }
@@ -106,8 +101,6 @@ static bool drm_hdmi_is_connected(struct
 {
 	struct drm_hdmi_context *ctx = to_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (hdmi_ops && hdmi_ops->is_connected)
 		return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx);
 
@@ -119,34 +112,31 @@ static struct edid *drm_hdmi_get_edid(st
 {
 	struct drm_hdmi_context *ctx = to_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (hdmi_ops && hdmi_ops->get_edid)
 		return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector);
 
 	return NULL;
 }
 
-static int drm_hdmi_check_timing(struct device *dev, void *timing)
+static int drm_hdmi_check_mode(struct device *dev,
+		struct drm_display_mode *mode)
 {
 	struct drm_hdmi_context *ctx = to_context(dev);
 	int ret = 0;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	* Both, mixer and hdmi should be able to handle the requested mode.
 	* If any of the two fails, return mode as BAD.
 	*/
 
-	if (mixer_ops && mixer_ops->check_timing)
-		ret = mixer_ops->check_timing(ctx->mixer_ctx->ctx, timing);
+	if (mixer_ops && mixer_ops->check_mode)
+		ret = mixer_ops->check_mode(ctx->mixer_ctx->ctx, mode);
 
 	if (ret)
 		return ret;
 
-	if (hdmi_ops && hdmi_ops->check_timing)
-		return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);
+	if (hdmi_ops && hdmi_ops->check_mode)
+		return hdmi_ops->check_mode(ctx->hdmi_ctx->ctx, mode);
 
 	return 0;
 }
@@ -155,8 +145,6 @@ static int drm_hdmi_power_on(struct devi
 {
 	struct drm_hdmi_context *ctx = to_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (hdmi_ops && hdmi_ops->power_on)
 		return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode);
 
@@ -167,7 +155,7 @@ static struct exynos_drm_display_ops drm
 	.type = EXYNOS_DISPLAY_TYPE_HDMI,
 	.is_connected = drm_hdmi_is_connected,
 	.get_edid = drm_hdmi_get_edid,
-	.check_timing = drm_hdmi_check_timing,
+	.check_mode = drm_hdmi_check_mode,
 	.power_on = drm_hdmi_power_on,
 };
 
@@ -177,8 +165,6 @@ static int drm_hdmi_enable_vblank(struct
 	struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
 	struct exynos_drm_manager *manager = subdrv->manager;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (mixer_ops && mixer_ops->enable_vblank)
 		return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx,
 						manager->pipe);
@@ -190,8 +176,6 @@ static void drm_hdmi_disable_vblank(stru
 {
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (mixer_ops && mixer_ops->disable_vblank)
 		return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
 }
@@ -200,8 +184,6 @@ static void drm_hdmi_wait_for_vblank(str
 {
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (mixer_ops && mixer_ops->wait_for_vblank)
 		mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx);
 }
@@ -214,11 +196,9 @@ static void drm_hdmi_mode_fixup(struct d
 	struct drm_display_mode *m;
 	int mode_ok;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
-	mode_ok = drm_hdmi_check_timing(subdrv_dev, adjusted_mode);
+	mode_ok = drm_hdmi_check_mode(subdrv_dev, adjusted_mode);
 
 	/* just return if user desired mode exists. */
 	if (mode_ok == 0)
@@ -229,7 +209,7 @@ static void drm_hdmi_mode_fixup(struct d
 	 * to adjusted_mode.
 	 */
 	list_for_each_entry(m, &connector->modes, head) {
-		mode_ok = drm_hdmi_check_timing(subdrv_dev, m);
+		mode_ok = drm_hdmi_check_mode(subdrv_dev, m);
 
 		if (mode_ok == 0) {
 			struct drm_mode_object base;
@@ -256,8 +236,6 @@ static void drm_hdmi_mode_set(struct dev
 {
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (hdmi_ops && hdmi_ops->mode_set)
 		hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
 }
@@ -267,8 +245,6 @@ static void drm_hdmi_get_max_resol(struc
 {
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (hdmi_ops && hdmi_ops->get_max_resol)
 		hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height);
 }
@@ -277,8 +253,6 @@ static void drm_hdmi_commit(struct devic
 {
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (hdmi_ops && hdmi_ops->commit)
 		hdmi_ops->commit(ctx->hdmi_ctx->ctx);
 }
@@ -287,8 +261,6 @@ static void drm_hdmi_dpms(struct device
 {
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (mixer_ops && mixer_ops->dpms)
 		mixer_ops->dpms(ctx->mixer_ctx->ctx, mode);
 
@@ -301,8 +273,6 @@ static void drm_hdmi_apply(struct device
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 	int i;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	for (i = 0; i < MIXER_WIN_NR; i++) {
 		if (!ctx->enabled[i])
 			continue;
@@ -331,8 +301,6 @@ static void drm_mixer_mode_set(struct de
 {
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (mixer_ops && mixer_ops->win_mode_set)
 		mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
 }
@@ -342,9 +310,7 @@ static void drm_mixer_commit(struct devi
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 	int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
-	if (win < 0 || win > MIXER_WIN_NR) {
+	if (win < 0 || win >= MIXER_WIN_NR) {
 		DRM_ERROR("mixer window[%d] is wrong\n", win);
 		return;
 	}
@@ -360,9 +326,7 @@ static void drm_mixer_disable(struct dev
 	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
 	int win = (zpos == DEFAULT_ZPOS) ? MIXER_DEFAULT_WIN : zpos;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
-	if (win < 0 || win > MIXER_WIN_NR) {
+	if (win < 0 || win >= MIXER_WIN_NR) {
 		DRM_ERROR("mixer window[%d] is wrong\n", win);
 		return;
 	}
@@ -392,8 +356,6 @@ static int hdmi_subdrv_probe(struct drm_
 	struct exynos_drm_subdrv *subdrv = to_subdrv(dev);
 	struct drm_hdmi_context *ctx;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (!hdmi_ctx) {
 		DRM_ERROR("hdmi context not initialized.\n");
 		return -EFAULT;
@@ -440,8 +402,6 @@ static int exynos_drm_hdmi_probe(struct
 	struct exynos_drm_subdrv *subdrv;
 	struct drm_hdmi_context *ctx;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
 	if (!ctx) {
 		DRM_LOG_KMS("failed to alloc common hdmi context.\n");
@@ -466,8 +426,6 @@ static int exynos_drm_hdmi_remove(struct
 {
 	struct drm_hdmi_context *ctx = platform_get_drvdata(pdev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_drm_subdrv_unregister(&ctx->subdrv);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_hdmi.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_hdmi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_hdmi.h	2013-08-25 20:43:22.000000000 -0400
@@ -32,11 +32,11 @@ struct exynos_hdmi_ops {
 	bool (*is_connected)(void *ctx);
 	struct edid *(*get_edid)(void *ctx,
 			struct drm_connector *connector);
-	int (*check_timing)(void *ctx, struct fb_videomode *timing);
+	int (*check_mode)(void *ctx, struct drm_display_mode *mode);
 	int (*power_on)(void *ctx, int mode);
 
 	/* manager */
-	void (*mode_set)(void *ctx, void *mode);
+	void (*mode_set)(void *ctx, struct drm_display_mode *mode);
 	void (*get_max_resol)(void *ctx, unsigned int *width,
 				unsigned int *height);
 	void (*commit)(void *ctx);
@@ -57,7 +57,7 @@ struct exynos_mixer_ops {
 	void (*win_disable)(void *ctx, int zpos);
 
 	/* display */
-	int (*check_timing)(void *ctx, struct fb_videomode *timing);
+	int (*check_mode)(void *ctx, struct drm_display_mode *mode);
 };
 
 void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_ipp.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_ipp.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_ipp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_ipp.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,6 @@
  *
  */
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/types.h>
 #include <linux/clk.h>
@@ -131,8 +130,6 @@ void exynos_platform_device_ipp_unregist
 
 int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
 {
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (!ippdrv)
 		return -EINVAL;
 
@@ -145,8 +142,6 @@ int exynos_drm_ippdrv_register(struct ex
 
 int exynos_drm_ippdrv_unregister(struct exynos_drm_ippdrv *ippdrv)
 {
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (!ippdrv)
 		return -EINVAL;
 
@@ -162,8 +157,6 @@ static int ipp_create_id(struct idr *id_
 {
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	/* do the allocation under our mutexlock */
 	mutex_lock(lock);
 	ret = idr_alloc(id_idr, obj, 1, 0, GFP_KERNEL);
@@ -179,7 +172,7 @@ static void *ipp_find_obj(struct idr *id
 {
 	void *obj;
 
-	DRM_DEBUG_KMS("%s:id[%d]\n", __func__, id);
+	DRM_DEBUG_KMS("id[%d]\n", id);
 
 	mutex_lock(lock);
 
@@ -216,7 +209,7 @@ static struct exynos_drm_ippdrv *ipp_fin
 	struct exynos_drm_ippdrv *ippdrv;
 	u32 ipp_id = property->ipp_id;
 
-	DRM_DEBUG_KMS("%s:ipp_id[%d]\n", __func__, ipp_id);
+	DRM_DEBUG_KMS("ipp_id[%d]\n", ipp_id);
 
 	if (ipp_id) {
 		/* find ipp driver using idr */
@@ -257,14 +250,13 @@ static struct exynos_drm_ippdrv *ipp_fin
 		 */
 		list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
 			if (ipp_check_dedicated(ippdrv, property->cmd)) {
-				DRM_DEBUG_KMS("%s:used device.\n", __func__);
+				DRM_DEBUG_KMS("used device.\n");
 				continue;
 			}
 
 			if (ippdrv->check_property &&
 			    ippdrv->check_property(ippdrv->dev, property)) {
-				DRM_DEBUG_KMS("%s:not support property.\n",
-					__func__);
+				DRM_DEBUG_KMS("not support property.\n");
 				continue;
 			}
 
@@ -283,10 +275,10 @@ static struct exynos_drm_ippdrv *ipp_fin
 	struct drm_exynos_ipp_cmd_node *c_node;
 	int count = 0;
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, prop_id);
+	DRM_DEBUG_KMS("prop_id[%d]\n", prop_id);
 
 	if (list_empty(&exynos_drm_ippdrv_list)) {
-		DRM_DEBUG_KMS("%s:ippdrv_list is empty.\n", __func__);
+		DRM_DEBUG_KMS("ippdrv_list is empty.\n");
 		return ERR_PTR(-ENODEV);
 	}
 
@@ -296,8 +288,7 @@ static struct exynos_drm_ippdrv *ipp_fin
 	 * e.g PAUSE state, queue buf, command contro.
 	 */
 	list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
-		DRM_DEBUG_KMS("%s:count[%d]ippdrv[0x%x]\n", __func__,
-			count++, (int)ippdrv);
+		DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", count++, (int)ippdrv);
 
 		if (!list_empty(&ippdrv->cmd_list)) {
 			list_for_each_entry(c_node, &ippdrv->cmd_list, list)
@@ -320,8 +311,6 @@ int exynos_drm_ipp_get_property(struct d
 	struct exynos_drm_ippdrv *ippdrv;
 	int count = 0;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (!ctx) {
 		DRM_ERROR("invalid context.\n");
 		return -EINVAL;
@@ -332,7 +321,7 @@ int exynos_drm_ipp_get_property(struct d
 		return -EINVAL;
 	}
 
-	DRM_DEBUG_KMS("%s:ipp_id[%d]\n", __func__, prop_list->ipp_id);
+	DRM_DEBUG_KMS("ipp_id[%d]\n", prop_list->ipp_id);
 
 	if (!prop_list->ipp_id) {
 		list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list)
@@ -352,10 +341,10 @@ int exynos_drm_ipp_get_property(struct d
 		 */
 		ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock,
 						prop_list->ipp_id);
-		if (!ippdrv) {
+		if (IS_ERR(ippdrv)) {
 			DRM_ERROR("not found ipp%d driver.\n",
 					prop_list->ipp_id);
-			return -EINVAL;
+			return PTR_ERR(ippdrv);
 		}
 
 		prop_list = ippdrv->prop_list;
@@ -371,11 +360,11 @@ static void ipp_print_property(struct dr
 	struct drm_exynos_pos *pos = &config->pos;
 	struct drm_exynos_sz *sz = &config->sz;
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]ops[%s]fmt[0x%x]\n",
-		__func__, property->prop_id, idx ? "dst" : "src", config->fmt);
+	DRM_DEBUG_KMS("prop_id[%d]ops[%s]fmt[0x%x]\n",
+		property->prop_id, idx ? "dst" : "src", config->fmt);
 
-	DRM_DEBUG_KMS("%s:pos[%d %d %d %d]sz[%d %d]f[%d]r[%d]\n",
-		__func__, pos->x, pos->y, pos->w, pos->h,
+	DRM_DEBUG_KMS("pos[%d %d %d %d]sz[%d %d]f[%d]r[%d]\n",
+		pos->x, pos->y, pos->w, pos->h,
 		sz->hsize, sz->vsize, config->flip, config->degree);
 }
 
@@ -385,7 +374,7 @@ static int ipp_find_and_set_property(str
 	struct drm_exynos_ipp_cmd_node *c_node;
 	u32 prop_id = property->prop_id;
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, prop_id);
+	DRM_DEBUG_KMS("prop_id[%d]\n", prop_id);
 
 	ippdrv = ipp_find_drv_by_handle(prop_id);
 	if (IS_ERR(ippdrv)) {
@@ -401,8 +390,8 @@ static int ipp_find_and_set_property(str
 	list_for_each_entry(c_node, &ippdrv->cmd_list, list) {
 		if ((c_node->property.prop_id == prop_id) &&
 		    (c_node->state == IPP_STATE_STOP)) {
-			DRM_DEBUG_KMS("%s:found cmd[%d]ippdrv[0x%x]\n",
-				__func__, property->cmd, (int)ippdrv);
+			DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n",
+				property->cmd, (int)ippdrv);
 
 			c_node->property = *property;
 			return 0;
@@ -418,8 +407,6 @@ static struct drm_exynos_ipp_cmd_work *i
 {
 	struct drm_exynos_ipp_cmd_work *cmd_work;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	cmd_work = kzalloc(sizeof(*cmd_work), GFP_KERNEL);
 	if (!cmd_work) {
 		DRM_ERROR("failed to alloc cmd_work.\n");
@@ -435,8 +422,6 @@ static struct drm_exynos_ipp_event_work
 {
 	struct drm_exynos_ipp_event_work *event_work;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	event_work = kzalloc(sizeof(*event_work), GFP_KERNEL);
 	if (!event_work) {
 		DRM_ERROR("failed to alloc event_work.\n");
@@ -460,8 +445,6 @@ int exynos_drm_ipp_set_property(struct d
 	struct drm_exynos_ipp_cmd_node *c_node;
 	int ret, i;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (!ctx) {
 		DRM_ERROR("invalid context.\n");
 		return -EINVAL;
@@ -486,7 +469,7 @@ int exynos_drm_ipp_set_property(struct d
 	 * instead of allocation.
 	 */
 	if (property->prop_id) {
-		DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, property->prop_id);
+		DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
 		return ipp_find_and_set_property(property);
 	}
 
@@ -512,8 +495,8 @@ int exynos_drm_ipp_set_property(struct d
 		goto err_clear;
 	}
 
-	DRM_DEBUG_KMS("%s:created prop_id[%d]cmd[%d]ippdrv[0x%x]\n",
-		__func__, property->prop_id, property->cmd, (int)ippdrv);
+	DRM_DEBUG_KMS("created prop_id[%d]cmd[%d]ippdrv[0x%x]\n",
+		property->prop_id, property->cmd, (int)ippdrv);
 
 	/* stored property information and ippdrv in private data */
 	c_node->priv = priv;
@@ -569,8 +552,6 @@ err_clear:
 
 static void ipp_clean_cmd_node(struct drm_exynos_ipp_cmd_node *c_node)
 {
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	/* delete list */
 	list_del(&c_node->list);
 
@@ -593,8 +574,6 @@ static int ipp_check_mem_list(struct drm
 	struct list_head *head;
 	int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, };
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	mutex_lock(&c_node->mem_lock);
 
 	for_each_ipp_ops(i) {
@@ -602,20 +581,19 @@ static int ipp_check_mem_list(struct drm
 		head = &c_node->mem_list[i];
 
 		if (list_empty(head)) {
-			DRM_DEBUG_KMS("%s:%s memory empty.\n", __func__,
-				i ? "dst" : "src");
+			DRM_DEBUG_KMS("%s memory empty.\n", i ? "dst" : "src");
 			continue;
 		}
 
 		/* find memory node entry */
 		list_for_each_entry(m_node, head, list) {
-			DRM_DEBUG_KMS("%s:%s,count[%d]m_node[0x%x]\n", __func__,
+			DRM_DEBUG_KMS("%s,count[%d]m_node[0x%x]\n",
 				i ? "dst" : "src", count[i], (int)m_node);
 			count[i]++;
 		}
 	}
 
-	DRM_DEBUG_KMS("%s:min[%d]max[%d]\n", __func__,
+	DRM_DEBUG_KMS("min[%d]max[%d]\n",
 		min(count[EXYNOS_DRM_OPS_SRC], count[EXYNOS_DRM_OPS_DST]),
 		max(count[EXYNOS_DRM_OPS_SRC], count[EXYNOS_DRM_OPS_DST]));
 
@@ -644,15 +622,14 @@ static struct drm_exynos_ipp_mem_node
 	struct list_head *head;
 	int count = 0;
 
-	DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__, qbuf->buf_id);
+	DRM_DEBUG_KMS("buf_id[%d]\n", qbuf->buf_id);
 
 	/* source/destination memory list */
 	head = &c_node->mem_list[qbuf->ops_id];
 
 	/* find memory node from memory list */
 	list_for_each_entry(m_node, head, list) {
-		DRM_DEBUG_KMS("%s:count[%d]m_node[0x%x]\n",
-			__func__, count++, (int)m_node);
+		DRM_DEBUG_KMS("count[%d]m_node[0x%x]\n", count++, (int)m_node);
 
 		/* compare buffer id */
 		if (m_node->buf_id == qbuf->buf_id)
@@ -669,7 +646,7 @@ static int ipp_set_mem_node(struct exyno
 	struct exynos_drm_ipp_ops *ops = NULL;
 	int ret = 0;
 
-	DRM_DEBUG_KMS("%s:node[0x%x]\n", __func__, (int)m_node);
+	DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node);
 
 	if (!m_node) {
 		DRM_ERROR("invalid queue node.\n");
@@ -678,7 +655,7 @@ static int ipp_set_mem_node(struct exyno
 
 	mutex_lock(&c_node->mem_lock);
 
-	DRM_DEBUG_KMS("%s:ops_id[%d]\n", __func__, m_node->ops_id);
+	DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
 
 	/* get operations callback */
 	ops = ippdrv->ops[m_node->ops_id];
@@ -714,8 +691,6 @@ static struct drm_exynos_ipp_mem_node
 	void *addr;
 	int i;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	mutex_lock(&c_node->mem_lock);
 
 	m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
@@ -732,14 +707,11 @@ static struct drm_exynos_ipp_mem_node
 	m_node->prop_id = qbuf->prop_id;
 	m_node->buf_id = qbuf->buf_id;
 
-	DRM_DEBUG_KMS("%s:m_node[0x%x]ops_id[%d]\n", __func__,
-		(int)m_node, qbuf->ops_id);
-	DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]\n", __func__,
-		qbuf->prop_id, m_node->buf_id);
+	DRM_DEBUG_KMS("m_node[0x%x]ops_id[%d]\n", (int)m_node, qbuf->ops_id);
+	DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]\n", qbuf->prop_id, m_node->buf_id);
 
 	for_each_ipp_planar(i) {
-		DRM_DEBUG_KMS("%s:i[%d]handle[0x%x]\n", __func__,
-			i, qbuf->handle[i]);
+		DRM_DEBUG_KMS("i[%d]handle[0x%x]\n", i, qbuf->handle[i]);
 
 		/* get dma address by handle */
 		if (qbuf->handle[i]) {
@@ -752,9 +724,8 @@ static struct drm_exynos_ipp_mem_node
 
 			buf_info.handles[i] = qbuf->handle[i];
 			buf_info.base[i] = *(dma_addr_t *) addr;
-			DRM_DEBUG_KMS("%s:i[%d]base[0x%x]hd[0x%x]\n",
-				__func__, i, buf_info.base[i],
-				(int)buf_info.handles[i]);
+			DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%x]\n",
+				i, buf_info.base[i], (int)buf_info.handles[i]);
 		}
 	}
 
@@ -778,7 +749,7 @@ static int ipp_put_mem_node(struct drm_d
 {
 	int i;
 
-	DRM_DEBUG_KMS("%s:node[0x%x]\n", __func__, (int)m_node);
+	DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node);
 
 	if (!m_node) {
 		DRM_ERROR("invalid dequeue node.\n");
@@ -792,7 +763,7 @@ static int ipp_put_mem_node(struct drm_d
 
 	mutex_lock(&c_node->mem_lock);
 
-	DRM_DEBUG_KMS("%s:ops_id[%d]\n", __func__, m_node->ops_id);
+	DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
 
 	/* put gem buffer */
 	for_each_ipp_planar(i) {
@@ -824,8 +795,7 @@ static int ipp_get_event(struct drm_devi
 	struct drm_exynos_ipp_send_event *e;
 	unsigned long flags;
 
-	DRM_DEBUG_KMS("%s:ops_id[%d]buf_id[%d]\n", __func__,
-		qbuf->ops_id, qbuf->buf_id);
+	DRM_DEBUG_KMS("ops_id[%d]buf_id[%d]\n", qbuf->ops_id, qbuf->buf_id);
 
 	e = kzalloc(sizeof(*e), GFP_KERNEL);
 
@@ -857,16 +827,13 @@ static void ipp_put_event(struct drm_exy
 	struct drm_exynos_ipp_send_event *e, *te;
 	int count = 0;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (list_empty(&c_node->event_list)) {
-		DRM_DEBUG_KMS("%s:event_list is empty.\n", __func__);
+		DRM_DEBUG_KMS("event_list is empty.\n");
 		return;
 	}
 
 	list_for_each_entry_safe(e, te, &c_node->event_list, base.link) {
-		DRM_DEBUG_KMS("%s:count[%d]e[0x%x]\n",
-			__func__, count++, (int)e);
+		DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e);
 
 		/*
 		 * quf == NULL condition means all event deletion.
@@ -912,8 +879,6 @@ static int ipp_queue_buf_with_run(struct
 	struct exynos_drm_ipp_ops *ops;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	ippdrv = ipp_find_drv_by_handle(qbuf->prop_id);
 	if (IS_ERR(ippdrv)) {
 		DRM_ERROR("failed to get ipp driver.\n");
@@ -929,12 +894,12 @@ static int ipp_queue_buf_with_run(struct
 	property = &c_node->property;
 
 	if (c_node->state != IPP_STATE_START) {
-		DRM_DEBUG_KMS("%s:bypass for invalid state.\n" , __func__);
+		DRM_DEBUG_KMS("bypass for invalid state.\n");
 		return 0;
 	}
 
 	if (!ipp_check_mem_list(c_node)) {
-		DRM_DEBUG_KMS("%s:empty memory.\n", __func__);
+		DRM_DEBUG_KMS("empty memory.\n");
 		return 0;
 	}
 
@@ -964,8 +929,6 @@ static void ipp_clean_queue_buf(struct d
 {
 	struct drm_exynos_ipp_mem_node *m_node, *tm_node;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (!list_empty(&c_node->mem_list[qbuf->ops_id])) {
 		/* delete list */
 		list_for_each_entry_safe(m_node, tm_node,
@@ -989,8 +952,6 @@ int exynos_drm_ipp_queue_buf(struct drm_
 	struct drm_exynos_ipp_mem_node *m_node;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (!qbuf) {
 		DRM_ERROR("invalid buf parameter.\n");
 		return -EINVAL;
@@ -1001,16 +962,16 @@ int exynos_drm_ipp_queue_buf(struct drm_
 		return -EINVAL;
 	}
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]ops_id[%s]buf_id[%d]buf_type[%d]\n",
-		__func__, qbuf->prop_id, qbuf->ops_id ? "dst" : "src",
+	DRM_DEBUG_KMS("prop_id[%d]ops_id[%s]buf_id[%d]buf_type[%d]\n",
+		qbuf->prop_id, qbuf->ops_id ? "dst" : "src",
 		qbuf->buf_id, qbuf->buf_type);
 
 	/* find command node */
 	c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock,
 		qbuf->prop_id);
-	if (!c_node) {
+	if (IS_ERR(c_node)) {
 		DRM_ERROR("failed to get command node.\n");
-		return -EFAULT;
+		return PTR_ERR(c_node);
 	}
 
 	/* buffer control */
@@ -1075,8 +1036,6 @@ err_clean_node:
 static bool exynos_drm_ipp_check_valid(struct device *dev,
 		enum drm_exynos_ipp_ctrl ctrl, enum drm_exynos_ipp_state state)
 {
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (ctrl != IPP_CTRL_PLAY) {
 		if (pm_runtime_suspended(dev)) {
 			DRM_ERROR("pm:runtime_suspended.\n");
@@ -1104,7 +1063,6 @@ static bool exynos_drm_ipp_check_valid(s
 	default:
 		DRM_ERROR("invalid state.\n");
 		goto err_status;
-		break;
 	}
 
 	return true;
@@ -1126,8 +1084,6 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_d
 	struct drm_exynos_ipp_cmd_work *cmd_work;
 	struct drm_exynos_ipp_cmd_node *c_node;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (!ctx) {
 		DRM_ERROR("invalid context.\n");
 		return -EINVAL;
@@ -1138,7 +1094,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_d
 		return -EINVAL;
 	}
 
-	DRM_DEBUG_KMS("%s:ctrl[%d]prop_id[%d]\n", __func__,
+	DRM_DEBUG_KMS("ctrl[%d]prop_id[%d]\n",
 		cmd_ctrl->ctrl, cmd_ctrl->prop_id);
 
 	ippdrv = ipp_find_drv_by_handle(cmd_ctrl->prop_id);
@@ -1149,9 +1105,9 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_d
 
 	c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock,
 		cmd_ctrl->prop_id);
-	if (!c_node) {
+	if (IS_ERR(c_node)) {
 		DRM_ERROR("invalid command node list.\n");
-		return -EINVAL;
+		return PTR_ERR(c_node);
 	}
 
 	if (!exynos_drm_ipp_check_valid(ippdrv->dev, cmd_ctrl->ctrl,
@@ -1213,7 +1169,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_d
 		return -EINVAL;
 	}
 
-	DRM_DEBUG_KMS("%s:done ctrl[%d]prop_id[%d]\n", __func__,
+	DRM_DEBUG_KMS("done ctrl[%d]prop_id[%d]\n",
 		cmd_ctrl->ctrl, cmd_ctrl->prop_id);
 
 	return 0;
@@ -1249,7 +1205,7 @@ static int ipp_set_property(struct exyno
 		return -EINVAL;
 	}
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, property->prop_id);
+	DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
 
 	/* reset h/w block */
 	if (ippdrv->reset &&
@@ -1310,13 +1266,13 @@ static int ipp_start_property(struct exy
 	struct list_head *head;
 	int ret, i;
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, property->prop_id);
+	DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
 
 	/* store command info in ippdrv */
 	ippdrv->c_node = c_node;
 
 	if (!ipp_check_mem_list(c_node)) {
-		DRM_DEBUG_KMS("%s:empty memory.\n", __func__);
+		DRM_DEBUG_KMS("empty memory.\n");
 		return -ENOMEM;
 	}
 
@@ -1343,8 +1299,7 @@ static int ipp_start_property(struct exy
 				return ret;
 			}
 
-			DRM_DEBUG_KMS("%s:m_node[0x%x]\n",
-				__func__, (int)m_node);
+			DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node);
 
 			ret = ipp_set_mem_node(ippdrv, c_node, m_node);
 			if (ret) {
@@ -1382,7 +1337,7 @@ static int ipp_start_property(struct exy
 		return -EINVAL;
 	}
 
-	DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, property->cmd);
+	DRM_DEBUG_KMS("cmd[%d]\n", property->cmd);
 
 	/* start operations */
 	if (ippdrv->start) {
@@ -1405,7 +1360,7 @@ static int ipp_stop_property(struct drm_
 	struct list_head *head;
 	int ret = 0, i;
 
-	DRM_DEBUG_KMS("%s:prop_id[%d]\n", __func__, property->prop_id);
+	DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
 
 	/* put event */
 	ipp_put_event(c_node, NULL);
@@ -1418,8 +1373,7 @@ static int ipp_stop_property(struct drm_
 			head = &c_node->mem_list[i];
 
 			if (list_empty(head)) {
-				DRM_DEBUG_KMS("%s:mem_list is empty.\n",
-					__func__);
+				DRM_DEBUG_KMS("mem_list is empty.\n");
 				break;
 			}
 
@@ -1439,7 +1393,7 @@ static int ipp_stop_property(struct drm_
 		head = &c_node->mem_list[EXYNOS_DRM_OPS_DST];
 
 		if (list_empty(head)) {
-			DRM_DEBUG_KMS("%s:mem_list is empty.\n", __func__);
+			DRM_DEBUG_KMS("mem_list is empty.\n");
 			break;
 		}
 
@@ -1456,7 +1410,7 @@ static int ipp_stop_property(struct drm_
 		head = &c_node->mem_list[EXYNOS_DRM_OPS_SRC];
 
 		if (list_empty(head)) {
-			DRM_DEBUG_KMS("%s:mem_list is empty.\n", __func__);
+			DRM_DEBUG_KMS("mem_list is empty.\n");
 			break;
 		}
 
@@ -1491,8 +1445,6 @@ void ipp_sched_cmd(struct work_struct *w
 	struct drm_exynos_ipp_property *property;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	ippdrv = cmd_work->ippdrv;
 	if (!ippdrv) {
 		DRM_ERROR("invalid ippdrv list.\n");
@@ -1550,7 +1502,7 @@ void ipp_sched_cmd(struct work_struct *w
 		break;
 	}
 
-	DRM_DEBUG_KMS("%s:ctrl[%d] done.\n", __func__, cmd_work->ctrl);
+	DRM_DEBUG_KMS("ctrl[%d] done.\n", cmd_work->ctrl);
 
 err_unlock:
 	mutex_unlock(&c_node->cmd_lock);
@@ -1571,8 +1523,7 @@ static int ipp_send_event(struct exynos_
 	int ret, i;
 
 	for_each_ipp_ops(i)
-		DRM_DEBUG_KMS("%s:%s buf_id[%d]\n", __func__,
-			i ? "dst" : "src", buf_id[i]);
+		DRM_DEBUG_KMS("%s buf_id[%d]\n", i ? "dst" : "src", buf_id[i]);
 
 	if (!drm_dev) {
 		DRM_ERROR("failed to get drm_dev.\n");
@@ -1585,12 +1536,12 @@ static int ipp_send_event(struct exynos_
 	}
 
 	if (list_empty(&c_node->event_list)) {
-		DRM_DEBUG_KMS("%s:event list is empty.\n", __func__);
+		DRM_DEBUG_KMS("event list is empty.\n");
 		return 0;
 	}
 
 	if (!ipp_check_mem_list(c_node)) {
-		DRM_DEBUG_KMS("%s:empty memory.\n", __func__);
+		DRM_DEBUG_KMS("empty memory.\n");
 		return 0;
 	}
 
@@ -1609,7 +1560,7 @@ static int ipp_send_event(struct exynos_
 			}
 
 			tbuf_id[i] = m_node->buf_id;
-			DRM_DEBUG_KMS("%s:%s buf_id[%d]\n", __func__,
+			DRM_DEBUG_KMS("%s buf_id[%d]\n",
 				i ? "dst" : "src", tbuf_id[i]);
 
 			ret = ipp_put_mem_node(drm_dev, c_node, m_node);
@@ -1677,8 +1628,7 @@ static int ipp_send_event(struct exynos_
 	}
 
 	do_gettimeofday(&now);
-	DRM_DEBUG_KMS("%s:tv_sec[%ld]tv_usec[%ld]\n"
-		, __func__, now.tv_sec, now.tv_usec);
+	DRM_DEBUG_KMS("tv_sec[%ld]tv_usec[%ld]\n", now.tv_sec, now.tv_usec);
 	e->event.tv_sec = now.tv_sec;
 	e->event.tv_usec = now.tv_usec;
 	e->event.prop_id = property->prop_id;
@@ -1692,7 +1642,7 @@ static int ipp_send_event(struct exynos_
 	wake_up_interruptible(&e->base.file_priv->event_wait);
 	spin_unlock_irqrestore(&drm_dev->event_lock, flags);
 
-	DRM_DEBUG_KMS("%s:done cmd[%d]prop_id[%d]buf_id[%d]\n", __func__,
+	DRM_DEBUG_KMS("done cmd[%d]prop_id[%d]buf_id[%d]\n",
 		property->cmd, property->prop_id, tbuf_id[EXYNOS_DRM_OPS_DST]);
 
 	return 0;
@@ -1711,8 +1661,7 @@ void ipp_sched_event(struct work_struct
 		return;
 	}
 
-	DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__,
-		event_work->buf_id[EXYNOS_DRM_OPS_DST]);
+	DRM_DEBUG_KMS("buf_id[%d]\n", event_work->buf_id[EXYNOS_DRM_OPS_DST]);
 
 	ippdrv = event_work->ippdrv;
 	if (!ippdrv) {
@@ -1733,8 +1682,8 @@ void ipp_sched_event(struct work_struct
 	 * or going out operations.
 	 */
 	if (c_node->state != IPP_STATE_START) {
-		DRM_DEBUG_KMS("%s:bypass state[%d]prop_id[%d]\n",
-			__func__, c_node->state, c_node->property.prop_id);
+		DRM_DEBUG_KMS("bypass state[%d]prop_id[%d]\n",
+			c_node->state, c_node->property.prop_id);
 		goto err_completion;
 	}
 
@@ -1759,8 +1708,6 @@ static int ipp_subdrv_probe(struct drm_d
 	struct exynos_drm_ippdrv *ippdrv;
 	int ret, count = 0;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	/* get ipp driver entry */
 	list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
 		ippdrv->drm_dev = drm_dev;
@@ -1772,7 +1719,7 @@ static int ipp_subdrv_probe(struct drm_d
 			goto err_idr;
 		}
 
-		DRM_DEBUG_KMS("%s:count[%d]ippdrv[0x%x]ipp_id[%d]\n", __func__,
+		DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]ipp_id[%d]\n",
 			count++, (int)ippdrv, ippdrv->ipp_id);
 
 		if (ippdrv->ipp_id == 0) {
@@ -1816,8 +1763,6 @@ static void ipp_subdrv_remove(struct drm
 {
 	struct exynos_drm_ippdrv *ippdrv;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	/* get ipp driver entry */
 	list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
 		if (is_drm_iommu_supported(drm_dev))
@@ -1834,8 +1779,6 @@ static int ipp_subdrv_open(struct drm_de
 	struct drm_exynos_file_private *file_priv = file->driver_priv;
 	struct exynos_drm_ipp_private *priv;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv) {
 		DRM_ERROR("failed to allocate priv.\n");
@@ -1846,7 +1789,7 @@ static int ipp_subdrv_open(struct drm_de
 
 	INIT_LIST_HEAD(&priv->event_list);
 
-	DRM_DEBUG_KMS("%s:done priv[0x%x]\n", __func__, (int)priv);
+	DRM_DEBUG_KMS("done priv[0x%x]\n", (int)priv);
 
 	return 0;
 }
@@ -1860,10 +1803,10 @@ static void ipp_subdrv_close(struct drm_
 	struct drm_exynos_ipp_cmd_node *c_node, *tc_node;
 	int count = 0;
 
-	DRM_DEBUG_KMS("%s:for priv[0x%x]\n", __func__, (int)priv);
+	DRM_DEBUG_KMS("for priv[0x%x]\n", (int)priv);
 
 	if (list_empty(&exynos_drm_ippdrv_list)) {
-		DRM_DEBUG_KMS("%s:ippdrv_list is empty.\n", __func__);
+		DRM_DEBUG_KMS("ippdrv_list is empty.\n");
 		goto err_clear;
 	}
 
@@ -1873,8 +1816,8 @@ static void ipp_subdrv_close(struct drm_
 
 		list_for_each_entry_safe(c_node, tc_node,
 			&ippdrv->cmd_list, list) {
-			DRM_DEBUG_KMS("%s:count[%d]ippdrv[0x%x]\n",
-				__func__, count++, (int)ippdrv);
+			DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n",
+				count++, (int)ippdrv);
 
 			if (c_node->priv == priv) {
 				/*
@@ -1913,8 +1856,6 @@ static int ipp_probe(struct platform_dev
 	if (!ctx)
 		return -ENOMEM;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	mutex_init(&ctx->ipp_lock);
 	mutex_init(&ctx->prop_lock);
 
@@ -1978,8 +1919,6 @@ static int ipp_remove(struct platform_de
 {
 	struct ipp_context *ctx = platform_get_drvdata(pdev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	/* unregister sub driver */
 	exynos_drm_subdrv_unregister(&ctx->subdrv);
 
@@ -1999,7 +1938,7 @@ static int ipp_remove(struct platform_de
 
 static int ipp_power_ctrl(struct ipp_context *ctx, bool enable)
 {
-	DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
+	DRM_DEBUG_KMS("enable[%d]\n", enable);
 
 	return 0;
 }
@@ -2009,8 +1948,6 @@ static int ipp_suspend(struct device *de
 {
 	struct ipp_context *ctx = get_ipp_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (pm_runtime_suspended(dev))
 		return 0;
 
@@ -2021,8 +1958,6 @@ static int ipp_resume(struct device *dev
 {
 	struct ipp_context *ctx = get_ipp_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (!pm_runtime_suspended(dev))
 		return ipp_power_ctrl(ctx, true);
 
@@ -2035,8 +1970,6 @@ static int ipp_runtime_suspend(struct de
 {
 	struct ipp_context *ctx = get_ipp_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	return ipp_power_ctrl(ctx, false);
 }
 
@@ -2044,8 +1977,6 @@ static int ipp_runtime_resume(struct dev
 {
 	struct ipp_context *ctx = get_ipp_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	return ipp_power_ctrl(ctx, true);
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_plane.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_plane.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_plane.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_plane.c	2013-08-25 20:43:22.000000000 -0400
@@ -81,8 +81,6 @@ int exynos_plane_mode_set(struct drm_pla
 	int nr;
 	int i;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	nr = exynos_drm_fb_get_buf_cnt(fb);
 	for (i = 0; i < nr; i++) {
 		struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i);
@@ -159,8 +157,6 @@ void exynos_plane_dpms(struct drm_plane
 	struct exynos_plane *exynos_plane = to_exynos_plane(plane);
 	struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	if (mode == DRM_MODE_DPMS_ON) {
 		if (exynos_plane->enabled)
 			return;
@@ -189,8 +185,6 @@ exynos_update_plane(struct drm_plane *pl
 {
 	int ret;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	ret = exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
 			crtc_w, crtc_h, src_x >> 16, src_y >> 16,
 			src_w >> 16, src_h >> 16);
@@ -207,8 +201,6 @@ exynos_update_plane(struct drm_plane *pl
 
 static int exynos_disable_plane(struct drm_plane *plane)
 {
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	exynos_plane_dpms(plane, DRM_MODE_DPMS_OFF);
 
 	return 0;
@@ -218,8 +210,6 @@ static void exynos_plane_destroy(struct
 {
 	struct exynos_plane *exynos_plane = to_exynos_plane(plane);
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	exynos_disable_plane(plane);
 	drm_plane_cleanup(plane);
 	kfree(exynos_plane);
@@ -233,8 +223,6 @@ static int exynos_plane_set_property(str
 	struct exynos_plane *exynos_plane = to_exynos_plane(plane);
 	struct exynos_drm_private *dev_priv = dev->dev_private;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	if (property == dev_priv->plane_zpos_property) {
 		exynos_plane->overlay.zpos = val;
 		return 0;
@@ -256,8 +244,6 @@ static void exynos_plane_attach_zpos_pro
 	struct exynos_drm_private *dev_priv = dev->dev_private;
 	struct drm_property *prop;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	prop = dev_priv->plane_zpos_property;
 	if (!prop) {
 		prop = drm_property_create_range(dev, 0, "zpos", 0,
@@ -277,8 +263,6 @@ struct drm_plane *exynos_plane_init(stru
 	struct exynos_plane *exynos_plane;
 	int err;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
 	if (!exynos_plane) {
 		DRM_ERROR("failed to allocate plane\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_rotator.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_rotator.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_rotator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_rotator.c	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -244,7 +243,7 @@ static int rotator_src_set_size(struct d
 	/* Get format */
 	fmt = rotator_reg_get_fmt(rot);
 	if (!rotator_check_reg_fmt(fmt)) {
-		DRM_ERROR("%s:invalid format.\n", __func__);
+		DRM_ERROR("invalid format.\n");
 		return -EINVAL;
 	}
 
@@ -287,7 +286,7 @@ static int rotator_src_set_addr(struct d
 		/* Get format */
 		fmt = rotator_reg_get_fmt(rot);
 		if (!rotator_check_reg_fmt(fmt)) {
-			DRM_ERROR("%s:invalid format.\n", __func__);
+			DRM_ERROR("invalid format.\n");
 			return -EINVAL;
 		}
 
@@ -381,7 +380,7 @@ static int rotator_dst_set_size(struct d
 	/* Get format */
 	fmt = rotator_reg_get_fmt(rot);
 	if (!rotator_check_reg_fmt(fmt)) {
-		DRM_ERROR("%s:invalid format.\n", __func__);
+		DRM_ERROR("invalid format.\n");
 		return -EINVAL;
 	}
 
@@ -422,7 +421,7 @@ static int rotator_dst_set_addr(struct d
 		/* Get format */
 		fmt = rotator_reg_get_fmt(rot);
 		if (!rotator_check_reg_fmt(fmt)) {
-			DRM_ERROR("%s:invalid format.\n", __func__);
+			DRM_ERROR("invalid format.\n");
 			return -EINVAL;
 		}
 
@@ -471,8 +470,6 @@ static int rotator_init_prop_list(struct
 {
 	struct drm_exynos_ipp_prop_list *prop_list;
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
 	if (!prop_list) {
 		DRM_ERROR("failed to alloc property list.\n");
@@ -502,7 +499,7 @@ static inline bool rotator_check_drm_fmt
 	case DRM_FORMAT_NV12:
 		return true;
 	default:
-		DRM_DEBUG_KMS("%s:not support format\n", __func__);
+		DRM_DEBUG_KMS("not support format\n");
 		return false;
 	}
 }
@@ -516,7 +513,7 @@ static inline bool rotator_check_drm_fli
 	case EXYNOS_DRM_FLIP_BOTH:
 		return true;
 	default:
-		DRM_DEBUG_KMS("%s:invalid flip\n", __func__);
+		DRM_DEBUG_KMS("invalid flip\n");
 		return false;
 	}
 }
@@ -536,19 +533,18 @@ static int rotator_ippdrv_check_property
 
 	/* Check format configuration */
 	if (src_config->fmt != dst_config->fmt) {
-		DRM_DEBUG_KMS("%s:not support csc feature\n", __func__);
+		DRM_DEBUG_KMS("not support csc feature\n");
 		return -EINVAL;
 	}
 
 	if (!rotator_check_drm_fmt(dst_config->fmt)) {
-		DRM_DEBUG_KMS("%s:invalid format\n", __func__);
+		DRM_DEBUG_KMS("invalid format\n");
 		return -EINVAL;
 	}
 
 	/* Check transform configuration */
 	if (src_config->degree != EXYNOS_DRM_DEGREE_0) {
-		DRM_DEBUG_KMS("%s:not support source-side rotation\n",
-			__func__);
+		DRM_DEBUG_KMS("not support source-side rotation\n");
 		return -EINVAL;
 	}
 
@@ -561,51 +557,47 @@ static int rotator_ippdrv_check_property
 		/* No problem */
 		break;
 	default:
-		DRM_DEBUG_KMS("%s:invalid degree\n", __func__);
+		DRM_DEBUG_KMS("invalid degree\n");
 		return -EINVAL;
 	}
 
 	if (src_config->flip != EXYNOS_DRM_FLIP_NONE) {
-		DRM_DEBUG_KMS("%s:not support source-side flip\n", __func__);
+		DRM_DEBUG_KMS("not support source-side flip\n");
 		return -EINVAL;
 	}
 
 	if (!rotator_check_drm_flip(dst_config->flip)) {
-		DRM_DEBUG_KMS("%s:invalid flip\n", __func__);
+		DRM_DEBUG_KMS("invalid flip\n");
 		return -EINVAL;
 	}
 
 	/* Check size configuration */
 	if ((src_pos->x + src_pos->w > src_sz->hsize) ||
 		(src_pos->y + src_pos->h > src_sz->vsize)) {
-		DRM_DEBUG_KMS("%s:out of source buffer bound\n", __func__);
+		DRM_DEBUG_KMS("out of source buffer bound\n");
 		return -EINVAL;
 	}
 
 	if (swap) {
 		if ((dst_pos->x + dst_pos->h > dst_sz->vsize) ||
 			(dst_pos->y + dst_pos->w > dst_sz->hsize)) {
-			DRM_DEBUG_KMS("%s:out of destination buffer bound\n",
-				__func__);
+			DRM_DEBUG_KMS("out of destination buffer bound\n");
 			return -EINVAL;
 		}
 
 		if ((src_pos->w != dst_pos->h) || (src_pos->h != dst_pos->w)) {
-			DRM_DEBUG_KMS("%s:not support scale feature\n",
-				__func__);
+			DRM_DEBUG_KMS("not support scale feature\n");
 			return -EINVAL;
 		}
 	} else {
 		if ((dst_pos->x + dst_pos->w > dst_sz->hsize) ||
 			(dst_pos->y + dst_pos->h > dst_sz->vsize)) {
-			DRM_DEBUG_KMS("%s:out of destination buffer bound\n",
-				__func__);
+			DRM_DEBUG_KMS("out of destination buffer bound\n");
 			return -EINVAL;
 		}
 
 		if ((src_pos->w != dst_pos->w) || (src_pos->h != dst_pos->h)) {
-			DRM_DEBUG_KMS("%s:not support scale feature\n",
-				__func__);
+			DRM_DEBUG_KMS("not support scale feature\n");
 			return -EINVAL;
 		}
 	}
@@ -693,7 +685,7 @@ static int rotator_probe(struct platform
 		goto err_ippdrv_register;
 	}
 
-	DRM_DEBUG_KMS("%s:ippdrv[0x%x]\n", __func__, (int)ippdrv);
+	DRM_DEBUG_KMS("ippdrv[0x%x]\n", (int)ippdrv);
 
 	platform_set_drvdata(pdev, rot);
 
@@ -752,8 +744,6 @@ static struct platform_device_id rotator
 
 static int rotator_clk_crtl(struct rot_context *rot, bool enable)
 {
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (enable) {
 		clk_enable(rot->clock);
 		rot->suspended = false;
@@ -771,8 +761,6 @@ static int rotator_suspend(struct device
 {
 	struct rot_context *rot = dev_get_drvdata(dev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (pm_runtime_suspended(dev))
 		return 0;
 
@@ -783,8 +771,6 @@ static int rotator_resume(struct device
 {
 	struct rot_context *rot = dev_get_drvdata(dev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	if (!pm_runtime_suspended(dev))
 		return rotator_clk_crtl(rot, true);
 
@@ -797,8 +783,6 @@ static int rotator_runtime_suspend(struc
 {
 	struct rot_context *rot = dev_get_drvdata(dev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	return  rotator_clk_crtl(rot, false);
 }
 
@@ -806,8 +790,6 @@ static int rotator_runtime_resume(struct
 {
 	struct rot_context *rot = dev_get_drvdata(dev);
 
-	DRM_DEBUG_KMS("%s\n", __func__);
-
 	return  rotator_clk_crtl(rot, true);
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_vidi.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_vidi.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_drm_vidi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_drm_vidi.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,6 @@
 #include <drm/drmP.h>
 
 #include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include <drm/exynos_drm.h>
@@ -89,8 +88,6 @@ static bool vidi_display_is_connected(st
 {
 	struct vidi_context *ctx = get_vidi_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	 * connection request would come from user side
 	 * to do hotplug through specific ioctl.
@@ -105,8 +102,6 @@ static struct edid *vidi_get_edid(struct
 	struct edid *edid;
 	int edid_len;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	 * the edid data comes from user side and it would be set
 	 * to ctx->raw_edid through specific ioctl.
@@ -128,17 +123,13 @@ static struct edid *vidi_get_edid(struct
 
 static void *vidi_get_panel(struct device *dev)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* TODO. */
 
 	return NULL;
 }
 
-static int vidi_check_timing(struct device *dev, void *timing)
+static int vidi_check_mode(struct device *dev, struct drm_display_mode *mode)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* TODO. */
 
 	return 0;
@@ -146,8 +137,6 @@ static int vidi_check_timing(struct devi
 
 static int vidi_display_power_on(struct device *dev, int mode)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* TODO */
 
 	return 0;
@@ -158,7 +147,7 @@ static struct exynos_drm_display_ops vid
 	.is_connected = vidi_display_is_connected,
 	.get_edid = vidi_get_edid,
 	.get_panel = vidi_get_panel,
-	.check_timing = vidi_check_timing,
+	.check_mode = vidi_check_mode,
 	.power_on = vidi_display_power_on,
 };
 
@@ -166,7 +155,7 @@ static void vidi_dpms(struct device *sub
 {
 	struct vidi_context *ctx = get_vidi_context(subdrv_dev);
 
-	DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
+	DRM_DEBUG_KMS("%d\n", mode);
 
 	mutex_lock(&ctx->lock);
 
@@ -196,8 +185,6 @@ static void vidi_apply(struct device *su
 	struct vidi_win_data *win_data;
 	int i;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	for (i = 0; i < WINDOWS_NR; i++) {
 		win_data = &ctx->win_data[i];
 		if (win_data->enabled && (ovl_ops && ovl_ops->commit))
@@ -212,8 +199,6 @@ static void vidi_commit(struct device *d
 {
 	struct vidi_context *ctx = get_vidi_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (ctx->suspended)
 		return;
 }
@@ -222,8 +207,6 @@ static int vidi_enable_vblank(struct dev
 {
 	struct vidi_context *ctx = get_vidi_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (ctx->suspended)
 		return -EPERM;
 
@@ -246,8 +229,6 @@ static void vidi_disable_vblank(struct d
 {
 	struct vidi_context *ctx = get_vidi_context(dev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (ctx->suspended)
 		return;
 
@@ -271,8 +252,6 @@ static void vidi_win_mode_set(struct dev
 	int win;
 	unsigned long offset;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (!overlay) {
 		dev_err(dev, "overlay is NULL\n");
 		return;
@@ -282,7 +261,7 @@ static void vidi_win_mode_set(struct dev
 	if (win == DEFAULT_ZPOS)
 		win = ctx->default_win;
 
-	if (win < 0 || win > WINDOWS_NR)
+	if (win < 0 || win >= WINDOWS_NR)
 		return;
 
 	offset = overlay->fb_x * (overlay->bpp >> 3);
@@ -324,15 +303,13 @@ static void vidi_win_commit(struct devic
 	struct vidi_win_data *win_data;
 	int win = zpos;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (ctx->suspended)
 		return;
 
 	if (win == DEFAULT_ZPOS)
 		win = ctx->default_win;
 
-	if (win < 0 || win > WINDOWS_NR)
+	if (win < 0 || win >= WINDOWS_NR)
 		return;
 
 	win_data = &ctx->win_data[win];
@@ -351,12 +328,10 @@ static void vidi_win_disable(struct devi
 	struct vidi_win_data *win_data;
 	int win = zpos;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (win == DEFAULT_ZPOS)
 		win = ctx->default_win;
 
-	if (win < 0 || win > WINDOWS_NR)
+	if (win < 0 || win >= WINDOWS_NR)
 		return;
 
 	win_data = &ctx->win_data[win];
@@ -407,8 +382,6 @@ static void vidi_fake_vblank_handler(str
 
 static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/*
 	 * enable drm irq mode.
 	 * - with irq_enabled = 1, we can use the vblank feature.
@@ -431,8 +404,6 @@ static int vidi_subdrv_probe(struct drm_
 
 static void vidi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
 {
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	/* TODO. */
 }
 
@@ -441,11 +412,6 @@ static int vidi_power_on(struct vidi_con
 	struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
 	struct device *dev = subdrv->dev;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
-	if (enable != false && enable != true)
-		return -EINVAL;
-
 	if (enable) {
 		ctx->suspended = false;
 
@@ -483,8 +449,6 @@ static int vidi_store_connection(struct
 	struct vidi_context *ctx = get_vidi_context(dev);
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	ret = kstrtoint(buf, 0, &ctx->connected);
 	if (ret)
 		return ret;
@@ -522,8 +486,6 @@ int vidi_connection_ioctl(struct drm_dev
 	struct drm_exynos_vidi_connection *vidi = data;
 	int edid_len;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	if (!vidi) {
 		DRM_DEBUG_KMS("user data for vidi is null.\n");
 		return -EINVAL;
@@ -592,8 +554,6 @@ static int vidi_probe(struct platform_de
 	struct exynos_drm_subdrv *subdrv;
 	int ret;
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
@@ -625,8 +585,6 @@ static int vidi_remove(struct platform_d
 {
 	struct vidi_context *ctx = platform_get_drvdata(pdev);
 
-	DRM_DEBUG_KMS("%s\n", __FILE__);
-
 	exynos_drm_subdrv_unregister(&ctx->subdrv);
 
 	if (ctx->raw_edid != (struct edid *)fake_edid_info) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_hdmi.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_hdmi.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_hdmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_hdmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/spinlock.h>
 #include <linux/wait.h>
 #include <linux/i2c.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -83,6 +82,7 @@ struct hdmi_resources {
 	struct clk			*sclk_pixel;
 	struct clk			*sclk_hdmiphy;
 	struct clk			*hdmiphy;
+	struct clk			*mout_hdmi;
 	struct regulator_bulk_data	*regul_bulk;
 	int				regul_count;
 };
@@ -689,8 +689,6 @@ static void hdmi_reg_infoframe(struct hd
 	u32 mod;
 	u32 vic;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
 	if (hdata->dvi_mode) {
 		hdmi_reg_writeb(hdata, HDMI_VSI_CON,
@@ -755,8 +753,6 @@ static struct edid *hdmi_get_edid(void *
 	struct edid *raw_edid;
 	struct hdmi_context *hdata = ctx;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	if (!hdata->ddc_port)
 		return ERR_PTR(-ENODEV);
 
@@ -777,8 +773,6 @@ static int hdmi_find_phy_conf(struct hdm
 	const struct hdmiphy_config *confs;
 	int count, i;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	if (hdata->type == HDMI_TYPE13) {
 		confs = hdmiphy_v13_configs;
 		count = ARRAY_SIZE(hdmiphy_v13_configs);
@@ -796,18 +790,17 @@ static int hdmi_find_phy_conf(struct hdm
 	return -EINVAL;
 }
 
-static int hdmi_check_timing(void *ctx, struct fb_videomode *timing)
+static int hdmi_check_mode(void *ctx, struct drm_display_mode *mode)
 {
 	struct hdmi_context *hdata = ctx;
 	int ret;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
-	DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", timing->xres,
-			timing->yres, timing->refresh,
-			timing->vmode);
+	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
+		mode->hdisplay, mode->vdisplay, mode->vrefresh,
+		(mode->flags & DRM_MODE_FLAG_INTERLACE) ? true :
+		false, mode->clock * 1000);
 
-	ret = hdmi_find_phy_conf(hdata, timing->pixclock);
+	ret = hdmi_find_phy_conf(hdata, mode->clock * 1000);
 	if (ret < 0)
 		return ret;
 	return 0;
@@ -1042,7 +1035,7 @@ static void hdmi_conf_init(struct hdmi_c
 	}
 }
 
-static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
+static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
 {
 	const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v13_conf.tg;
 	const struct hdmi_v13_core_regs *core =
@@ -1118,9 +1111,9 @@ static void hdmi_v13_timing_apply(struct
 		hdmi_regs_dump(hdata, "timing apply");
 	}
 
-	clk_disable(hdata->res.sclk_hdmi);
-	clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
-	clk_enable(hdata->res.sclk_hdmi);
+	clk_disable_unprepare(hdata->res.sclk_hdmi);
+	clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
+	clk_prepare_enable(hdata->res.sclk_hdmi);
 
 	/* enable HDMI and timing generator */
 	hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
@@ -1131,7 +1124,7 @@ static void hdmi_v13_timing_apply(struct
 		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
 }
 
-static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
+static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
 {
 	const struct hdmi_tg_regs *tg = &hdata->mode_conf.conf.v14_conf.tg;
 	const struct hdmi_v14_core_regs *core =
@@ -1285,9 +1278,9 @@ static void hdmi_v14_timing_apply(struct
 		hdmi_regs_dump(hdata, "timing apply");
 	}
 
-	clk_disable(hdata->res.sclk_hdmi);
-	clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
-	clk_enable(hdata->res.sclk_hdmi);
+	clk_disable_unprepare(hdata->res.sclk_hdmi);
+	clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_hdmiphy);
+	clk_prepare_enable(hdata->res.sclk_hdmi);
 
 	/* enable HDMI and timing generator */
 	hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
@@ -1298,12 +1291,12 @@ static void hdmi_v14_timing_apply(struct
 		hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
 }
 
-static void hdmi_timing_apply(struct hdmi_context *hdata)
+static void hdmi_mode_apply(struct hdmi_context *hdata)
 {
 	if (hdata->type == HDMI_TYPE13)
-		hdmi_v13_timing_apply(hdata);
+		hdmi_v13_mode_apply(hdata);
 	else
-		hdmi_v14_timing_apply(hdata);
+		hdmi_v14_mode_apply(hdata);
 }
 
 static void hdmiphy_conf_reset(struct hdmi_context *hdata)
@@ -1311,9 +1304,9 @@ static void hdmiphy_conf_reset(struct hd
 	u8 buffer[2];
 	u32 reg;
 
-	clk_disable(hdata->res.sclk_hdmi);
-	clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
-	clk_enable(hdata->res.sclk_hdmi);
+	clk_disable_unprepare(hdata->res.sclk_hdmi);
+	clk_set_parent(hdata->res.mout_hdmi, hdata->res.sclk_pixel);
+	clk_prepare_enable(hdata->res.sclk_hdmi);
 
 	/* operation mode */
 	buffer[0] = 0x1f;
@@ -1336,8 +1329,6 @@ static void hdmiphy_conf_reset(struct hd
 
 static void hdmiphy_poweron(struct hdmi_context *hdata)
 {
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	if (hdata->type == HDMI_TYPE14)
 		hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0,
 			HDMI_PHY_POWER_OFF_EN);
@@ -1345,8 +1336,6 @@ static void hdmiphy_poweron(struct hdmi_
 
 static void hdmiphy_poweroff(struct hdmi_context *hdata)
 {
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	if (hdata->type == HDMI_TYPE14)
 		hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0,
 			HDMI_PHY_POWER_OFF_EN);
@@ -1410,8 +1399,6 @@ static void hdmiphy_conf_apply(struct hd
 
 static void hdmi_conf_apply(struct hdmi_context *hdata)
 {
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	hdmiphy_conf_reset(hdata);
 	hdmiphy_conf_apply(hdata);
 
@@ -1423,7 +1410,7 @@ static void hdmi_conf_apply(struct hdmi_
 	hdmi_audio_init(hdata);
 
 	/* setting core registers */
-	hdmi_timing_apply(hdata);
+	hdmi_mode_apply(hdata);
 	hdmi_audio_control(hdata, true);
 
 	hdmi_regs_dump(hdata, "start");
@@ -1569,8 +1556,7 @@ static void hdmi_v14_mode_set(struct hdm
 			(m->vsync_start - m->vdisplay) / 2);
 		hdmi_set_reg(core->v2_blank, 2, m->vtotal / 2);
 		hdmi_set_reg(core->v1_blank, 2, (m->vtotal - m->vdisplay) / 2);
-		hdmi_set_reg(core->v_blank_f0, 2, (m->vtotal +
-			((m->vsync_end - m->vsync_start) * 4) + 5) / 2);
+		hdmi_set_reg(core->v_blank_f0, 2, m->vtotal - m->vdisplay / 2);
 		hdmi_set_reg(core->v_blank_f1, 2, m->vtotal);
 		hdmi_set_reg(core->v_sync_line_aft_2, 2, (m->vtotal / 2) + 7);
 		hdmi_set_reg(core->v_sync_line_aft_1, 2, (m->vtotal / 2) + 2);
@@ -1580,7 +1566,10 @@ static void hdmi_v14_mode_set(struct hdm
 			(m->htotal / 2) + (m->hsync_start - m->hdisplay));
 		hdmi_set_reg(tg->vact_st, 2, (m->vtotal - m->vdisplay) / 2);
 		hdmi_set_reg(tg->vact_sz, 2, m->vdisplay / 2);
-		hdmi_set_reg(tg->vact_st2, 2, 0x249);/* Reset value + 1*/
+		hdmi_set_reg(tg->vact_st2, 2, m->vtotal - m->vdisplay / 2);
+		hdmi_set_reg(tg->vsync2, 2, (m->vtotal / 2) + 1);
+		hdmi_set_reg(tg->vsync_bot_hdmi, 2, (m->vtotal / 2) + 1);
+		hdmi_set_reg(tg->field_bot_hdmi, 2, (m->vtotal / 2) + 1);
 		hdmi_set_reg(tg->vact_st3, 2, 0x0);
 		hdmi_set_reg(tg->vact_st4, 2, 0x0);
 	} else {
@@ -1602,6 +1591,9 @@ static void hdmi_v14_mode_set(struct hdm
 		hdmi_set_reg(tg->vact_st2, 2, 0x248); /* Reset value */
 		hdmi_set_reg(tg->vact_st3, 2, 0x47b); /* Reset value */
 		hdmi_set_reg(tg->vact_st4, 2, 0x6ae); /* Reset value */
+		hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
+		hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
+		hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
 	}
 
 	/* Following values & calculations are same irrespective of mode type */
@@ -1633,22 +1625,19 @@ static void hdmi_v14_mode_set(struct hdm
 	hdmi_set_reg(tg->hact_sz, 2, m->hdisplay);
 	hdmi_set_reg(tg->v_fsz, 2, m->vtotal);
 	hdmi_set_reg(tg->vsync, 2, 0x1);
-	hdmi_set_reg(tg->vsync2, 2, 0x233); /* Reset value */
 	hdmi_set_reg(tg->field_chg, 2, 0x233); /* Reset value */
 	hdmi_set_reg(tg->vsync_top_hdmi, 2, 0x1); /* Reset value */
-	hdmi_set_reg(tg->vsync_bot_hdmi, 2, 0x233); /* Reset value */
 	hdmi_set_reg(tg->field_top_hdmi, 2, 0x1); /* Reset value */
-	hdmi_set_reg(tg->field_bot_hdmi, 2, 0x233); /* Reset value */
 	hdmi_set_reg(tg->tg_3d, 1, 0x0);
 }
 
-static void hdmi_mode_set(void *ctx, void *mode)
+static void hdmi_mode_set(void *ctx, struct drm_display_mode *mode)
 {
 	struct hdmi_context *hdata = ctx;
 	struct drm_display_mode *m = mode;
 
-	DRM_DEBUG_KMS("[%s]: xres=%d, yres=%d, refresh=%d, intl=%s\n",
-		__func__, m->hdisplay, m->vdisplay,
+	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
+		m->hdisplay, m->vdisplay,
 		m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
 		"INTERLACED" : "PROGERESSIVE");
 
@@ -1661,8 +1650,6 @@ static void hdmi_mode_set(void *ctx, voi
 static void hdmi_get_max_resol(void *ctx, unsigned int *width,
 					unsigned int *height)
 {
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	*width = MAX_WIDTH;
 	*height = MAX_HEIGHT;
 }
@@ -1671,8 +1658,6 @@ static void hdmi_commit(void *ctx)
 {
 	struct hdmi_context *hdata = ctx;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	mutex_lock(&hdata->hdmi_mutex);
 	if (!hdata->powered) {
 		mutex_unlock(&hdata->hdmi_mutex);
@@ -1687,8 +1672,6 @@ static void hdmi_poweron(struct hdmi_con
 {
 	struct hdmi_resources *res = &hdata->res;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	mutex_lock(&hdata->hdmi_mutex);
 	if (hdata->powered) {
 		mutex_unlock(&hdata->hdmi_mutex);
@@ -1699,10 +1682,12 @@ static void hdmi_poweron(struct hdmi_con
 
 	mutex_unlock(&hdata->hdmi_mutex);
 
-	regulator_bulk_enable(res->regul_count, res->regul_bulk);
-	clk_enable(res->hdmiphy);
-	clk_enable(res->hdmi);
-	clk_enable(res->sclk_hdmi);
+	if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
+		DRM_DEBUG_KMS("failed to enable regulator bulk\n");
+
+	clk_prepare_enable(res->hdmiphy);
+	clk_prepare_enable(res->hdmi);
+	clk_prepare_enable(res->sclk_hdmi);
 
 	hdmiphy_poweron(hdata);
 }
@@ -1711,8 +1696,6 @@ static void hdmi_poweroff(struct hdmi_co
 {
 	struct hdmi_resources *res = &hdata->res;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	mutex_lock(&hdata->hdmi_mutex);
 	if (!hdata->powered)
 		goto out;
@@ -1725,9 +1708,9 @@ static void hdmi_poweroff(struct hdmi_co
 	hdmiphy_conf_reset(hdata);
 	hdmiphy_poweroff(hdata);
 
-	clk_disable(res->sclk_hdmi);
-	clk_disable(res->hdmi);
-	clk_disable(res->hdmiphy);
+	clk_disable_unprepare(res->sclk_hdmi);
+	clk_disable_unprepare(res->hdmi);
+	clk_disable_unprepare(res->hdmiphy);
 	regulator_bulk_disable(res->regul_count, res->regul_bulk);
 
 	mutex_lock(&hdata->hdmi_mutex);
@@ -1742,7 +1725,7 @@ static void hdmi_dpms(void *ctx, int mod
 {
 	struct hdmi_context *hdata = ctx;
 
-	DRM_DEBUG_KMS("[%d] %s mode %d\n", __LINE__, __func__, mode);
+	DRM_DEBUG_KMS("mode %d\n", mode);
 
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
@@ -1765,7 +1748,7 @@ static struct exynos_hdmi_ops hdmi_ops =
 	/* display */
 	.is_connected	= hdmi_is_connected,
 	.get_edid	= hdmi_get_edid,
-	.check_timing	= hdmi_check_timing,
+	.check_mode	= hdmi_check_mode,
 
 	/* manager */
 	.mode_set	= hdmi_mode_set,
@@ -1831,8 +1814,13 @@ static int hdmi_resources_init(struct hd
 		DRM_ERROR("failed to get clock 'hdmiphy'\n");
 		goto fail;
 	}
+	res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
+	if (IS_ERR(res->mout_hdmi)) {
+		DRM_ERROR("failed to get clock 'mout_hdmi'\n");
+		goto fail;
+	}
 
-	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
+	clk_set_parent(res->mout_hdmi, res->sclk_pixel);
 
 	res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
 		sizeof(res->regul_bulk[0]), GFP_KERNEL);
@@ -1877,7 +1865,6 @@ static struct s5p_hdmi_platform_data *dr
 {
 	struct device_node *np = dev->of_node;
 	struct s5p_hdmi_platform_data *pd;
-	enum of_gpio_flags flags;
 	u32 value;
 
 	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
@@ -1891,7 +1878,7 @@ static struct s5p_hdmi_platform_data *dr
 		goto err_data;
 	}
 
-	pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
+	pd->hpd_gpio = of_get_named_gpio(np, "hpd-gpio", 0);
 
 	return pd;
 
@@ -1930,6 +1917,9 @@ static struct of_device_id hdmi_match_ty
 		.compatible = "samsung,exynos5-hdmi",
 		.data	= (void	*)HDMI_TYPE14,
 	}, {
+		.compatible = "samsung,exynos4212-hdmi",
+		.data	= (void	*)HDMI_TYPE14,
+	}, {
 		/* end node */
 	}
 };
@@ -1944,8 +1934,6 @@ static int hdmi_probe(struct platform_de
 	struct resource *res;
 	int ret;
 
-	DRM_DEBUG_KMS("[%d]\n", __LINE__);
-
 	if (dev->of_node) {
 		pdata = drm_hdmi_dt_parse_pdata(dev);
 		if (IS_ERR(pdata)) {
@@ -2071,8 +2059,6 @@ static int hdmi_remove(struct platform_d
 {
 	struct device *dev = &pdev->dev;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	pm_runtime_disable(dev);
 
 	/* hdmiphy i2c driver */
@@ -2089,8 +2075,6 @@ static int hdmi_suspend(struct device *d
 	struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
 	struct hdmi_context *hdata = ctx->ctx;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	disable_irq(hdata->irq);
 
 	hdata->hpd = false;
@@ -2098,7 +2082,7 @@ static int hdmi_suspend(struct device *d
 		drm_helper_hpd_irq_event(ctx->drm_dev);
 
 	if (pm_runtime_suspended(dev)) {
-		DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
+		DRM_DEBUG_KMS("Already suspended\n");
 		return 0;
 	}
 
@@ -2112,14 +2096,12 @@ static int hdmi_resume(struct device *de
 	struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
 	struct hdmi_context *hdata = ctx->ctx;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	hdata->hpd = gpio_get_value(hdata->hpd_gpio);
 
 	enable_irq(hdata->irq);
 
 	if (!pm_runtime_suspended(dev)) {
-		DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
+		DRM_DEBUG_KMS("Already resumed\n");
 		return 0;
 	}
 
@@ -2134,7 +2116,6 @@ static int hdmi_runtime_suspend(struct d
 {
 	struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
 	struct hdmi_context *hdata = ctx->ctx;
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
 	hdmi_poweroff(hdata);
 
@@ -2145,7 +2126,6 @@ static int hdmi_runtime_resume(struct de
 {
 	struct exynos_drm_hdmi_context *ctx = get_hdmi_context(dev);
 	struct hdmi_context *hdata = ctx->ctx;
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
 	hdmi_poweron(hdata);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_hdmiphy.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_hdmiphy.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_hdmiphy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_hdmiphy.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,6 @@
 
 #include <linux/kernel.h>
 #include <linux/i2c.h>
-#include <linux/module.h>
 
 #include "exynos_drm_drv.h"
 #include "exynos_hdmi.h"
@@ -51,6 +50,10 @@ static struct of_device_id hdmiphy_match
 	{
 		.compatible = "samsung,exynos5-hdmiphy",
 	}, {
+		.compatible = "samsung,exynos4210-hdmiphy",
+	}, {
+		.compatible = "samsung,exynos4212-hdmiphy",
+	}, {
 		/* end node */
 	}
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_mixer.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_mixer.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/exynos_mixer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/exynos_mixer.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/spinlock.h>
 #include <linux/wait.h>
 #include <linux/i2c.h>
-#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -78,6 +77,7 @@ struct mixer_resources {
 enum mixer_version_id {
 	MXR_VER_0_0_0_16,
 	MXR_VER_16_0_33_0,
+	MXR_VER_128_0_0_184,
 };
 
 struct mixer_context {
@@ -283,17 +283,19 @@ static void mixer_cfg_scan(struct mixer_
 	val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE :
 				MXR_CFG_SCAN_PROGRASSIVE);
 
-	/* choosing between porper HD and SD mode */
-	if (height <= 480)
-		val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
-	else if (height <= 576)
-		val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
-	else if (height <= 720)
-		val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
-	else if (height <= 1080)
-		val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
-	else
-		val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
+	if (ctx->mxr_ver != MXR_VER_128_0_0_184) {
+		/* choosing between proper HD and SD mode */
+		if (height <= 480)
+			val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
+		else if (height <= 576)
+			val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
+		else if (height <= 720)
+			val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
+		else if (height <= 1080)
+			val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
+		else
+			val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
+	}
 
 	mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
 }
@@ -376,7 +378,7 @@ static void vp_video_buffer(struct mixer
 	unsigned long flags;
 	struct hdmi_win_data *win_data;
 	unsigned int x_ratio, y_ratio;
-	unsigned int buf_num;
+	unsigned int buf_num = 1;
 	dma_addr_t luma_addr[2], chroma_addr[2];
 	bool tiled_mode = false;
 	bool crcb_mode = false;
@@ -557,6 +559,14 @@ static void mixer_graph_buffer(struct mi
 	/* setup geometry */
 	mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width);
 
+	/* setup display size */
+	if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
+		win == MIXER_DEFAULT_WIN) {
+		val  = MXR_MXR_RES_HEIGHT(win_data->fb_height);
+		val |= MXR_MXR_RES_WIDTH(win_data->fb_width);
+		mixer_reg_write(res, MXR_RESOLUTION, val);
+	}
+
 	val  = MXR_GRP_WH_WIDTH(win_data->crtc_width);
 	val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height);
 	val |= MXR_GRP_WH_H_SCALE(x_ratio);
@@ -581,7 +591,8 @@ static void mixer_graph_buffer(struct mi
 	mixer_cfg_layer(ctx, win, true);
 
 	/* layer update mandatory for mixer 16.0.33.0 */
-	if (ctx->mxr_ver == MXR_VER_16_0_33_0)
+	if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
+		ctx->mxr_ver == MXR_VER_128_0_0_184)
 		mixer_layer_update(ctx);
 
 	mixer_run(ctx);
@@ -696,8 +707,6 @@ static int mixer_enable_vblank(void *ctx
 	struct mixer_context *mixer_ctx = ctx;
 	struct mixer_resources *res = &mixer_ctx->mixer_res;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	mixer_ctx->pipe = pipe;
 
 	/* enable vsync interrupt */
@@ -712,8 +721,6 @@ static void mixer_disable_vblank(void *c
 	struct mixer_context *mixer_ctx = ctx;
 	struct mixer_resources *res = &mixer_ctx->mixer_res;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	/* disable vsync interrupt */
 	mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
 }
@@ -725,8 +732,6 @@ static void mixer_win_mode_set(void *ctx
 	struct hdmi_win_data *win_data;
 	int win;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	if (!overlay) {
 		DRM_ERROR("overlay is NULL\n");
 		return;
@@ -742,7 +747,7 @@ static void mixer_win_mode_set(void *ctx
 	if (win == DEFAULT_ZPOS)
 		win = MIXER_DEFAULT_WIN;
 
-	if (win < 0 || win > MIXER_WIN_NR) {
+	if (win < 0 || win >= MIXER_WIN_NR) {
 		DRM_ERROR("mixer window[%d] is wrong\n", win);
 		return;
 	}
@@ -776,7 +781,7 @@ static void mixer_win_commit(void *ctx,
 {
 	struct mixer_context *mixer_ctx = ctx;
 
-	DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
+	DRM_DEBUG_KMS("win: %d\n", win);
 
 	mutex_lock(&mixer_ctx->mixer_mutex);
 	if (!mixer_ctx->powered) {
@@ -799,7 +804,7 @@ static void mixer_win_disable(void *ctx,
 	struct mixer_resources *res = &mixer_ctx->mixer_res;
 	unsigned long flags;
 
-	DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
+	DRM_DEBUG_KMS("win: %d\n", win);
 
 	mutex_lock(&mixer_ctx->mixer_mutex);
 	if (!mixer_ctx->powered) {
@@ -820,17 +825,21 @@ static void mixer_win_disable(void *ctx,
 	mixer_ctx->win_data[win].enabled = false;
 }
 
-static int mixer_check_timing(void *ctx, struct fb_videomode *timing)
+static int mixer_check_mode(void *ctx, struct drm_display_mode *mode)
 {
+	struct mixer_context *mixer_ctx = ctx;
 	u32 w, h;
 
-	w = timing->xres;
-	h = timing->yres;
+	w = mode->hdisplay;
+	h = mode->vdisplay;
 
-	DRM_DEBUG_KMS("%s : xres=%d, yres=%d, refresh=%d, intl=%d\n",
-		__func__, timing->xres, timing->yres,
-		timing->refresh, (timing->vmode &
-		FB_VMODE_INTERLACED) ? true : false);
+	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
+		mode->hdisplay, mode->vdisplay, mode->vrefresh,
+		(mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
+
+	if (mixer_ctx->mxr_ver == MXR_VER_0_0_0_16 ||
+		mixer_ctx->mxr_ver == MXR_VER_128_0_0_184)
+		return 0;
 
 	if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
 		(w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
@@ -891,8 +900,6 @@ static void mixer_poweron(struct mixer_c
 {
 	struct mixer_resources *res = &ctx->mixer_res;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	mutex_lock(&ctx->mixer_mutex);
 	if (ctx->powered) {
 		mutex_unlock(&ctx->mixer_mutex);
@@ -901,10 +908,10 @@ static void mixer_poweron(struct mixer_c
 	ctx->powered = true;
 	mutex_unlock(&ctx->mixer_mutex);
 
-	clk_enable(res->mixer);
+	clk_prepare_enable(res->mixer);
 	if (ctx->vp_enabled) {
-		clk_enable(res->vp);
-		clk_enable(res->sclk_mixer);
+		clk_prepare_enable(res->vp);
+		clk_prepare_enable(res->sclk_mixer);
 	}
 
 	mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
@@ -917,8 +924,6 @@ static void mixer_poweroff(struct mixer_
 {
 	struct mixer_resources *res = &ctx->mixer_res;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	mutex_lock(&ctx->mixer_mutex);
 	if (!ctx->powered)
 		goto out;
@@ -928,10 +933,10 @@ static void mixer_poweroff(struct mixer_
 
 	ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
 
-	clk_disable(res->mixer);
+	clk_disable_unprepare(res->mixer);
 	if (ctx->vp_enabled) {
-		clk_disable(res->vp);
-		clk_disable(res->sclk_mixer);
+		clk_disable_unprepare(res->vp);
+		clk_disable_unprepare(res->sclk_mixer);
 	}
 
 	mutex_lock(&ctx->mixer_mutex);
@@ -945,8 +950,6 @@ static void mixer_dpms(void *ctx, int mo
 {
 	struct mixer_context *mixer_ctx = ctx;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	switch (mode) {
 	case DRM_MODE_DPMS_ON:
 		if (pm_runtime_suspended(mixer_ctx->dev))
@@ -978,7 +981,7 @@ static struct exynos_mixer_ops mixer_ops
 	.win_disable		= mixer_win_disable,
 
 	/* display */
-	.check_timing		= mixer_check_timing,
+	.check_mode		= mixer_check_mode,
 };
 
 static irqreturn_t mixer_irq_handler(int irq, void *arg)
@@ -1128,12 +1131,17 @@ static int vp_resources_init(struct exyn
 	return 0;
 }
 
-static struct mixer_drv_data exynos5_mxr_drv_data = {
+static struct mixer_drv_data exynos5420_mxr_drv_data = {
+	.version = MXR_VER_128_0_0_184,
+	.is_vp_enabled = 0,
+};
+
+static struct mixer_drv_data exynos5250_mxr_drv_data = {
 	.version = MXR_VER_16_0_33_0,
 	.is_vp_enabled = 0,
 };
 
-static struct mixer_drv_data exynos4_mxr_drv_data = {
+static struct mixer_drv_data exynos4210_mxr_drv_data = {
 	.version = MXR_VER_0_0_0_16,
 	.is_vp_enabled = 1,
 };
@@ -1141,10 +1149,10 @@ static struct mixer_drv_data exynos4_mxr
 static struct platform_device_id mixer_driver_types[] = {
 	{
 		.name		= "s5p-mixer",
-		.driver_data	= (unsigned long)&exynos4_mxr_drv_data,
+		.driver_data	= (unsigned long)&exynos4210_mxr_drv_data,
 	}, {
 		.name		= "exynos5-mixer",
-		.driver_data	= (unsigned long)&exynos5_mxr_drv_data,
+		.driver_data	= (unsigned long)&exynos5250_mxr_drv_data,
 	}, {
 		/* end node */
 	}
@@ -1153,7 +1161,13 @@ static struct platform_device_id mixer_d
 static struct of_device_id mixer_match_types[] = {
 	{
 		.compatible = "samsung,exynos5-mixer",
-		.data	= &exynos5_mxr_drv_data,
+		.data	= &exynos5250_mxr_drv_data,
+	}, {
+		.compatible = "samsung,exynos5250-mixer",
+		.data	= &exynos5250_mxr_drv_data,
+	}, {
+		.compatible = "samsung,exynos5420-mixer",
+		.data	= &exynos5420_mxr_drv_data,
 	}, {
 		/* end node */
 	}
@@ -1186,8 +1200,7 @@ static int mixer_probe(struct platform_d
 
 	if (dev->of_node) {
 		const struct of_device_id *match;
-		match = of_match_node(of_match_ptr(mixer_match_types),
-							  dev->of_node);
+		match = of_match_node(mixer_match_types, dev->of_node);
 		drv = (struct mixer_drv_data *)match->data;
 	} else {
 		drv = (struct mixer_drv_data *)
@@ -1251,10 +1264,8 @@ static int mixer_suspend(struct device *
 	struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
 	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	if (pm_runtime_suspended(dev)) {
-		DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
+		DRM_DEBUG_KMS("Already suspended\n");
 		return 0;
 	}
 
@@ -1268,10 +1279,8 @@ static int mixer_resume(struct device *d
 	struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
 	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	if (!pm_runtime_suspended(dev)) {
-		DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
+		DRM_DEBUG_KMS("Already resumed\n");
 		return 0;
 	}
 
@@ -1287,8 +1296,6 @@ static int mixer_runtime_suspend(struct
 	struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
 	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	mixer_poweroff(ctx);
 
 	return 0;
@@ -1299,8 +1306,6 @@ static int mixer_runtime_resume(struct d
 	struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
 	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
 
-	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
 	mixer_poweron(ctx);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/exynos/regs-mixer.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/regs-mixer.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/exynos/regs-mixer.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/exynos/regs-mixer.h	2013-08-25 20:43:22.000000000 -0400
@@ -44,6 +44,9 @@
 #define MXR_CM_COEFF_Y			0x0080
 #define MXR_CM_COEFF_CB			0x0084
 #define MXR_CM_COEFF_CR			0x0088
+#define MXR_MO				0x0304
+#define MXR_RESOLUTION			0x0310
+
 #define MXR_GRAPHIC0_BASE_S		0x2024
 #define MXR_GRAPHIC1_BASE_S		0x2044
 
@@ -119,6 +122,10 @@
 #define MXR_GRP_WH_WIDTH(x)		MXR_MASK_VAL(x, 26, 16)
 #define MXR_GRP_WH_HEIGHT(x)		MXR_MASK_VAL(x, 10, 0)
 
+/* bits for MXR_RESOLUTION */
+#define MXR_MXR_RES_HEIGHT(x)		MXR_MASK_VAL(x, 26, 16)
+#define MXR_MXR_RES_WIDTH(x)		MXR_MASK_VAL(x, 10, 0)
+
 /* bits for MXR_GRAPHICn_SXY */
 #define MXR_GRP_SXY_SX(x)		MXR_MASK_VAL(x, 26, 16)
 #define MXR_GRP_SXY_SY(x)		MXR_MASK_VAL(x, 10, 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/gma500/psb_intel_sdvo.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/gma500/psb_intel_sdvo.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/gma500/psb_intel_sdvo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/gma500/psb_intel_sdvo.c	2013-08-25 20:43:22.000000000 -0400
@@ -500,7 +500,8 @@ static bool psb_intel_sdvo_read_response
 				  &status))
 		goto log_fail;
 
-	while (status == SDVO_CMD_STATUS_PENDING && retry--) {
+	while ((status == SDVO_CMD_STATUS_PENDING ||
+		status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && retry--) {
 		udelay(15);
 		if (!psb_intel_sdvo_read_byte(psb_intel_sdvo,
 					  SDVO_I2C_CMD_STATUS,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i810/i810_dma.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i810/i810_dma.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i810/i810_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i810/i810_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -97,7 +97,7 @@ static int i810_mmap_buffers(struct file
 	buf = dev_priv->mmap_buffer;
 	buf_priv = buf->dev_private;
 
-	vma->vm_flags |= (VM_IO | VM_DONTCOPY);
+	vma->vm_flags |= VM_DONTCOPY;
 
 	buf_priv->currently_mapped = I810_BUF_MAPPED;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/dvo_ch7xxx.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/dvo_ch7xxx.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/dvo_ch7xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/dvo_ch7xxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,12 +32,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define CH7xxx_REG_DID		0x4b
 
 #define CH7011_VID		0x83 /* 7010 as well */
+#define CH7010B_VID		0x05
 #define CH7009A_VID		0x84
 #define CH7009B_VID		0x85
 #define CH7301_VID		0x95
 
 #define CH7xxx_VID		0x84
 #define CH7xxx_DID		0x17
+#define CH7010_DID		0x16
 
 #define CH7xxx_NUM_REGS		0x4c
 
@@ -87,11 +89,20 @@ static struct ch7xxx_id_struct {
 	char *name;
 } ch7xxx_ids[] = {
 	{ CH7011_VID, "CH7011" },
+	{ CH7010B_VID, "CH7010B" },
 	{ CH7009A_VID, "CH7009A" },
 	{ CH7009B_VID, "CH7009B" },
 	{ CH7301_VID, "CH7301" },
 };
 
+static struct ch7xxx_did_struct {
+	uint8_t did;
+	char *name;
+} ch7xxx_dids[] = {
+	{ CH7xxx_DID, "CH7XXX" },
+	{ CH7010_DID, "CH7010B" },
+};
+
 struct ch7xxx_priv {
 	bool quiet;
 };
@@ -108,6 +119,18 @@ static char *ch7xxx_get_id(uint8_t vid)
 	return NULL;
 }
 
+static char *ch7xxx_get_did(uint8_t did)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ch7xxx_dids); i++) {
+		if (ch7xxx_dids[i].did == did)
+			return ch7xxx_dids[i].name;
+	}
+
+	return NULL;
+}
+
 /** Reads an 8 bit register */
 static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
 {
@@ -179,7 +202,7 @@ static bool ch7xxx_init(struct intel_dvo
 	/* this will detect the CH7xxx chip on the specified i2c bus */
 	struct ch7xxx_priv *ch7xxx;
 	uint8_t vendor, device;
-	char *name;
+	char *name, *devid;
 
 	ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL);
 	if (ch7xxx == NULL)
@@ -204,7 +227,8 @@ static bool ch7xxx_init(struct intel_dvo
 	if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device))
 		goto out;
 
-	if (device != CH7xxx_DID) {
+	devid = ch7xxx_get_did(device);
+	if (!devid) {
 		DRM_DEBUG_KMS("ch7xxx not detected; got 0x%02x from %s "
 				"slave %d.\n",
 			  vendor, adapter->name, dvo->slave_addr);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_debugfs.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_debugfs.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,11 +61,11 @@ static int i915_capabilities(struct seq_
 
 	seq_printf(m, "gen: %d\n", info->gen);
 	seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev));
-#define DEV_INFO_FLAG(x) seq_printf(m, #x ": %s\n", yesno(info->x))
-#define DEV_INFO_SEP ;
-	DEV_INFO_FLAGS;
-#undef DEV_INFO_FLAG
-#undef DEV_INFO_SEP
+#define PRINT_FLAG(x)  seq_printf(m, #x ": %s\n", yesno(info->x))
+#define SEP_SEMICOLON ;
+	DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_SEMICOLON);
+#undef PRINT_FLAG
+#undef SEP_SEMICOLON
 
 	return 0;
 }
@@ -196,6 +196,32 @@ static int i915_gem_object_list_info(str
 	} \
 } while (0)
 
+struct file_stats {
+	int count;
+	size_t total, active, inactive, unbound;
+};
+
+static int per_file_stats(int id, void *ptr, void *data)
+{
+	struct drm_i915_gem_object *obj = ptr;
+	struct file_stats *stats = data;
+
+	stats->count++;
+	stats->total += obj->base.size;
+
+	if (obj->gtt_space) {
+		if (!list_empty(&obj->ring_list))
+			stats->active += obj->base.size;
+		else
+			stats->inactive += obj->base.size;
+	} else {
+		if (!list_empty(&obj->global_list))
+			stats->unbound += obj->base.size;
+	}
+
+	return 0;
+}
+
 static int i915_gem_object_info(struct seq_file *m, void* data)
 {
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -204,6 +230,7 @@ static int i915_gem_object_info(struct s
 	u32 count, mappable_count, purgeable_count;
 	size_t size, mappable_size, purgeable_size;
 	struct drm_i915_gem_object *obj;
+	struct drm_file *file;
 	int ret;
 
 	ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -215,7 +242,7 @@ static int i915_gem_object_info(struct s
 		   dev_priv->mm.object_memory);
 
 	size = count = mappable_size = mappable_count = 0;
-	count_objects(&dev_priv->mm.bound_list, gtt_list);
+	count_objects(&dev_priv->mm.bound_list, global_list);
 	seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n",
 		   count, mappable_count, size, mappable_size);
 
@@ -230,7 +257,7 @@ static int i915_gem_object_info(struct s
 		   count, mappable_count, size, mappable_size);
 
 	size = count = purgeable_size = purgeable_count = 0;
-	list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list) {
+	list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) {
 		size += obj->base.size, ++count;
 		if (obj->madv == I915_MADV_DONTNEED)
 			purgeable_size += obj->base.size, ++purgeable_count;
@@ -238,7 +265,7 @@ static int i915_gem_object_info(struct s
 	seq_printf(m, "%u unbound objects, %zu bytes\n", count, size);
 
 	size = count = mappable_size = mappable_count = 0;
-	list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
 		if (obj->fault_mappable) {
 			size += obj->gtt_space->size;
 			++count;
@@ -263,6 +290,21 @@ static int i915_gem_object_info(struct s
 		   dev_priv->gtt.total,
 		   dev_priv->gtt.mappable_end - dev_priv->gtt.start);
 
+	seq_printf(m, "\n");
+	list_for_each_entry_reverse(file, &dev->filelist, lhead) {
+		struct file_stats stats;
+
+		memset(&stats, 0, sizeof(stats));
+		idr_for_each(&file->object_idr, per_file_stats, &stats);
+		seq_printf(m, "%s: %u objects, %zu bytes (%zu active, %zu inactive, %zu unbound)\n",
+			   get_pid_task(file->pid, PIDTYPE_PID)->comm,
+			   stats.count,
+			   stats.total,
+			   stats.active,
+			   stats.inactive,
+			   stats.unbound);
+	}
+
 	mutex_unlock(&dev->struct_mutex);
 
 	return 0;
@@ -283,7 +325,7 @@ static int i915_gem_gtt_info(struct seq_
 		return ret;
 
 	total_obj_size = total_gtt_size = count = 0;
-	list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
 		if (list == PINNED_LIST && obj->pin_count == 0)
 			continue;
 
@@ -570,6 +612,7 @@ static const char *ring_str(int ring)
 	case RCS: return "render";
 	case VCS: return "bsd";
 	case BCS: return "blt";
+	case VECS: return "vebox";
 	default: return "";
 	}
 }
@@ -604,73 +647,187 @@ static const char *purgeable_flag(int pu
 	return purgeable ? " purgeable" : "";
 }
 
-static void print_error_buffers(struct seq_file *m,
+static bool __i915_error_ok(struct drm_i915_error_state_buf *e)
+{
+
+	if (!e->err && WARN(e->bytes > (e->size - 1), "overflow")) {
+		e->err = -ENOSPC;
+		return false;
+	}
+
+	if (e->bytes == e->size - 1 || e->err)
+		return false;
+
+	return true;
+}
+
+static bool __i915_error_seek(struct drm_i915_error_state_buf *e,
+			      unsigned len)
+{
+	if (e->pos + len <= e->start) {
+		e->pos += len;
+		return false;
+	}
+
+	/* First vsnprintf needs to fit in its entirety for memmove */
+	if (len >= e->size) {
+		e->err = -EIO;
+		return false;
+	}
+
+	return true;
+}
+
+static void __i915_error_advance(struct drm_i915_error_state_buf *e,
+				 unsigned len)
+{
+	/* If this is first printf in this window, adjust it so that
+	 * start position matches start of the buffer
+	 */
+
+	if (e->pos < e->start) {
+		const size_t off = e->start - e->pos;
+
+		/* Should not happen but be paranoid */
+		if (off > len || e->bytes) {
+			e->err = -EIO;
+			return;
+		}
+
+		memmove(e->buf, e->buf + off, len - off);
+		e->bytes = len - off;
+		e->pos = e->start;
+		return;
+	}
+
+	e->bytes += len;
+	e->pos += len;
+}
+
+static void i915_error_vprintf(struct drm_i915_error_state_buf *e,
+			       const char *f, va_list args)
+{
+	unsigned len;
+
+	if (!__i915_error_ok(e))
+		return;
+
+	/* Seek the first printf which is hits start position */
+	if (e->pos < e->start) {
+		len = vsnprintf(NULL, 0, f, args);
+		if (!__i915_error_seek(e, len))
+			return;
+	}
+
+	len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args);
+	if (len >= e->size - e->bytes)
+		len = e->size - e->bytes - 1;
+
+	__i915_error_advance(e, len);
+}
+
+static void i915_error_puts(struct drm_i915_error_state_buf *e,
+			    const char *str)
+{
+	unsigned len;
+
+	if (!__i915_error_ok(e))
+		return;
+
+	len = strlen(str);
+
+	/* Seek the first printf which is hits start position */
+	if (e->pos < e->start) {
+		if (!__i915_error_seek(e, len))
+			return;
+	}
+
+	if (len >= e->size - e->bytes)
+		len = e->size - e->bytes - 1;
+	memcpy(e->buf + e->bytes, str, len);
+
+	__i915_error_advance(e, len);
+}
+
+void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
+{
+	va_list args;
+
+	va_start(args, f);
+	i915_error_vprintf(e, f, args);
+	va_end(args);
+}
+
+#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
+#define err_puts(e, s) i915_error_puts(e, s)
+
+static void print_error_buffers(struct drm_i915_error_state_buf *m,
 				const char *name,
 				struct drm_i915_error_buffer *err,
 				int count)
 {
-	seq_printf(m, "%s [%d]:\n", name, count);
+	err_printf(m, "%s [%d]:\n", name, count);
 
 	while (count--) {
-		seq_printf(m, "  %08x %8u %02x %02x %x %x%s%s%s%s%s%s%s",
+		err_printf(m, "  %08x %8u %02x %02x %x %x",
 			   err->gtt_offset,
 			   err->size,
 			   err->read_domains,
 			   err->write_domain,
-			   err->rseqno, err->wseqno,
-			   pin_flag(err->pinned),
-			   tiling_flag(err->tiling),
-			   dirty_flag(err->dirty),
-			   purgeable_flag(err->purgeable),
-			   err->ring != -1 ? " " : "",
-			   ring_str(err->ring),
-			   cache_level_str(err->cache_level));
+			   err->rseqno, err->wseqno);
+		err_puts(m, pin_flag(err->pinned));
+		err_puts(m, tiling_flag(err->tiling));
+		err_puts(m, dirty_flag(err->dirty));
+		err_puts(m, purgeable_flag(err->purgeable));
+		err_puts(m, err->ring != -1 ? " " : "");
+		err_puts(m, ring_str(err->ring));
+		err_puts(m, cache_level_str(err->cache_level));
 
 		if (err->name)
-			seq_printf(m, " (name: %d)", err->name);
+			err_printf(m, " (name: %d)", err->name);
 		if (err->fence_reg != I915_FENCE_REG_NONE)
-			seq_printf(m, " (fence: %d)", err->fence_reg);
+			err_printf(m, " (fence: %d)", err->fence_reg);
 
-		seq_printf(m, "\n");
+		err_puts(m, "\n");
 		err++;
 	}
 }
 
-static void i915_ring_error_state(struct seq_file *m,
+static void i915_ring_error_state(struct drm_i915_error_state_buf *m,
 				  struct drm_device *dev,
 				  struct drm_i915_error_state *error,
 				  unsigned ring)
 {
 	BUG_ON(ring >= I915_NUM_RINGS); /* shut up confused gcc */
-	seq_printf(m, "%s command stream:\n", ring_str(ring));
-	seq_printf(m, "  HEAD: 0x%08x\n", error->head[ring]);
-	seq_printf(m, "  TAIL: 0x%08x\n", error->tail[ring]);
-	seq_printf(m, "  CTL: 0x%08x\n", error->ctl[ring]);
-	seq_printf(m, "  ACTHD: 0x%08x\n", error->acthd[ring]);
-	seq_printf(m, "  IPEIR: 0x%08x\n", error->ipeir[ring]);
-	seq_printf(m, "  IPEHR: 0x%08x\n", error->ipehr[ring]);
-	seq_printf(m, "  INSTDONE: 0x%08x\n", error->instdone[ring]);
+	err_printf(m, "%s command stream:\n", ring_str(ring));
+	err_printf(m, "  HEAD: 0x%08x\n", error->head[ring]);
+	err_printf(m, "  TAIL: 0x%08x\n", error->tail[ring]);
+	err_printf(m, "  CTL: 0x%08x\n", error->ctl[ring]);
+	err_printf(m, "  ACTHD: 0x%08x\n", error->acthd[ring]);
+	err_printf(m, "  IPEIR: 0x%08x\n", error->ipeir[ring]);
+	err_printf(m, "  IPEHR: 0x%08x\n", error->ipehr[ring]);
+	err_printf(m, "  INSTDONE: 0x%08x\n", error->instdone[ring]);
 	if (ring == RCS && INTEL_INFO(dev)->gen >= 4)
-		seq_printf(m, "  BBADDR: 0x%08llx\n", error->bbaddr);
+		err_printf(m, "  BBADDR: 0x%08llx\n", error->bbaddr);
 
 	if (INTEL_INFO(dev)->gen >= 4)
-		seq_printf(m, "  INSTPS: 0x%08x\n", error->instps[ring]);
-	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm[ring]);
-	seq_printf(m, "  FADDR: 0x%08x\n", error->faddr[ring]);
+		err_printf(m, "  INSTPS: 0x%08x\n", error->instps[ring]);
+	err_printf(m, "  INSTPM: 0x%08x\n", error->instpm[ring]);
+	err_printf(m, "  FADDR: 0x%08x\n", error->faddr[ring]);
 	if (INTEL_INFO(dev)->gen >= 6) {
-		seq_printf(m, "  RC PSMI: 0x%08x\n", error->rc_psmi[ring]);
-		seq_printf(m, "  FAULT_REG: 0x%08x\n", error->fault_reg[ring]);
-		seq_printf(m, "  SYNC_0: 0x%08x [last synced 0x%08x]\n",
+		err_printf(m, "  RC PSMI: 0x%08x\n", error->rc_psmi[ring]);
+		err_printf(m, "  FAULT_REG: 0x%08x\n", error->fault_reg[ring]);
+		err_printf(m, "  SYNC_0: 0x%08x [last synced 0x%08x]\n",
 			   error->semaphore_mboxes[ring][0],
 			   error->semaphore_seqno[ring][0]);
-		seq_printf(m, "  SYNC_1: 0x%08x [last synced 0x%08x]\n",
+		err_printf(m, "  SYNC_1: 0x%08x [last synced 0x%08x]\n",
 			   error->semaphore_mboxes[ring][1],
 			   error->semaphore_seqno[ring][1]);
 	}
-	seq_printf(m, "  seqno: 0x%08x\n", error->seqno[ring]);
-	seq_printf(m, "  waiting: %s\n", yesno(error->waiting[ring]));
-	seq_printf(m, "  ring->head: 0x%08x\n", error->cpu_ring_head[ring]);
-	seq_printf(m, "  ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]);
+	err_printf(m, "  seqno: 0x%08x\n", error->seqno[ring]);
+	err_printf(m, "  waiting: %s\n", yesno(error->waiting[ring]));
+	err_printf(m, "  ring->head: 0x%08x\n", error->cpu_ring_head[ring]);
+	err_printf(m, "  ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]);
 }
 
 struct i915_error_state_file_priv {
@@ -678,9 +835,11 @@ struct i915_error_state_file_priv {
 	struct drm_i915_error_state *error;
 };
 
-static int i915_error_state(struct seq_file *m, void *unused)
+
+static int i915_error_state(struct i915_error_state_file_priv *error_priv,
+			    struct drm_i915_error_state_buf *m)
+
 {
-	struct i915_error_state_file_priv *error_priv = m->private;
 	struct drm_device *dev = error_priv->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct drm_i915_error_state *error = error_priv->error;
@@ -688,34 +847,35 @@ static int i915_error_state(struct seq_f
 	int i, j, page, offset, elt;
 
 	if (!error) {
-		seq_printf(m, "no error state collected\n");
+		err_printf(m, "no error state collected\n");
 		return 0;
 	}
 
-	seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
+	err_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
 		   error->time.tv_usec);
-	seq_printf(m, "Kernel: " UTS_RELEASE "\n");
-	seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
-	seq_printf(m, "EIR: 0x%08x\n", error->eir);
-	seq_printf(m, "IER: 0x%08x\n", error->ier);
-	seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
-	seq_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake);
-	seq_printf(m, "DERRMR: 0x%08x\n", error->derrmr);
-	seq_printf(m, "CCID: 0x%08x\n", error->ccid);
+	err_printf(m, "Kernel: " UTS_RELEASE "\n");
+	err_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
+	err_printf(m, "EIR: 0x%08x\n", error->eir);
+	err_printf(m, "IER: 0x%08x\n", error->ier);
+	err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
+	err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake);
+	err_printf(m, "DERRMR: 0x%08x\n", error->derrmr);
+	err_printf(m, "CCID: 0x%08x\n", error->ccid);
 
 	for (i = 0; i < dev_priv->num_fence_regs; i++)
-		seq_printf(m, "  fence[%d] = %08llx\n", i, error->fence[i]);
+		err_printf(m, "  fence[%d] = %08llx\n", i, error->fence[i]);
 
 	for (i = 0; i < ARRAY_SIZE(error->extra_instdone); i++)
-		seq_printf(m, "  INSTDONE_%d: 0x%08x\n", i, error->extra_instdone[i]);
+		err_printf(m, "  INSTDONE_%d: 0x%08x\n", i,
+			   error->extra_instdone[i]);
 
 	if (INTEL_INFO(dev)->gen >= 6) {
-		seq_printf(m, "ERROR: 0x%08x\n", error->error);
-		seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg);
+		err_printf(m, "ERROR: 0x%08x\n", error->error);
+		err_printf(m, "DONE_REG: 0x%08x\n", error->done_reg);
 	}
 
 	if (INTEL_INFO(dev)->gen == 7)
-		seq_printf(m, "ERR_INT: 0x%08x\n", error->err_int);
+		err_printf(m, "ERR_INT: 0x%08x\n", error->err_int);
 
 	for_each_ring(ring, dev_priv, i)
 		i915_ring_error_state(m, dev, error, i);
@@ -734,24 +894,25 @@ static int i915_error_state(struct seq_f
 		struct drm_i915_error_object *obj;
 
 		if ((obj = error->ring[i].batchbuffer)) {
-			seq_printf(m, "%s --- gtt_offset = 0x%08x\n",
+			err_printf(m, "%s --- gtt_offset = 0x%08x\n",
 				   dev_priv->ring[i].name,
 				   obj->gtt_offset);
 			offset = 0;
 			for (page = 0; page < obj->page_count; page++) {
 				for (elt = 0; elt < PAGE_SIZE/4; elt++) {
-					seq_printf(m, "%08x :  %08x\n", offset, obj->pages[page][elt]);
+					err_printf(m, "%08x :  %08x\n", offset,
+						   obj->pages[page][elt]);
 					offset += 4;
 				}
 			}
 		}
 
 		if (error->ring[i].num_requests) {
-			seq_printf(m, "%s --- %d requests\n",
+			err_printf(m, "%s --- %d requests\n",
 				   dev_priv->ring[i].name,
 				   error->ring[i].num_requests);
 			for (j = 0; j < error->ring[i].num_requests; j++) {
-				seq_printf(m, "  seqno 0x%08x, emitted %ld, tail 0x%08x\n",
+				err_printf(m, "  seqno 0x%08x, emitted %ld, tail 0x%08x\n",
 					   error->ring[i].requests[j].seqno,
 					   error->ring[i].requests[j].jiffies,
 					   error->ring[i].requests[j].tail);
@@ -759,13 +920,13 @@ static int i915_error_state(struct seq_f
 		}
 
 		if ((obj = error->ring[i].ringbuffer)) {
-			seq_printf(m, "%s --- ringbuffer = 0x%08x\n",
+			err_printf(m, "%s --- ringbuffer = 0x%08x\n",
 				   dev_priv->ring[i].name,
 				   obj->gtt_offset);
 			offset = 0;
 			for (page = 0; page < obj->page_count; page++) {
 				for (elt = 0; elt < PAGE_SIZE/4; elt++) {
-					seq_printf(m, "%08x :  %08x\n",
+					err_printf(m, "%08x :  %08x\n",
 						   offset,
 						   obj->pages[page][elt]);
 					offset += 4;
@@ -775,12 +936,12 @@ static int i915_error_state(struct seq_f
 
 		obj = error->ring[i].ctx;
 		if (obj) {
-			seq_printf(m, "%s --- HW Context = 0x%08x\n",
+			err_printf(m, "%s --- HW Context = 0x%08x\n",
 				   dev_priv->ring[i].name,
 				   obj->gtt_offset);
 			offset = 0;
 			for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
-				seq_printf(m, "[%04x] %08x %08x %08x %08x\n",
+				err_printf(m, "[%04x] %08x %08x %08x %08x\n",
 					   offset,
 					   obj->pages[0][elt],
 					   obj->pages[0][elt+1],
@@ -806,8 +967,7 @@ i915_error_state_write(struct file *filp
 		       size_t cnt,
 		       loff_t *ppos)
 {
-	struct seq_file *m = filp->private_data;
-	struct i915_error_state_file_priv *error_priv = m->private;
+	struct i915_error_state_file_priv *error_priv = filp->private_data;
 	struct drm_device *dev = error_priv->dev;
 	int ret;
 
@@ -842,25 +1002,81 @@ static int i915_error_state_open(struct
 		kref_get(&error_priv->error->ref);
 	spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags);
 
-	return single_open(file, i915_error_state, error_priv);
+	file->private_data = error_priv;
+
+	return 0;
 }
 
 static int i915_error_state_release(struct inode *inode, struct file *file)
 {
-	struct seq_file *m = file->private_data;
-	struct i915_error_state_file_priv *error_priv = m->private;
+	struct i915_error_state_file_priv *error_priv = file->private_data;
 
 	if (error_priv->error)
 		kref_put(&error_priv->error->ref, i915_error_state_free);
 	kfree(error_priv);
 
-	return single_release(inode, file);
+	return 0;
+}
+
+static ssize_t i915_error_state_read(struct file *file, char __user *userbuf,
+				     size_t count, loff_t *pos)
+{
+	struct i915_error_state_file_priv *error_priv = file->private_data;
+	struct drm_i915_error_state_buf error_str;
+	loff_t tmp_pos = 0;
+	ssize_t ret_count = 0;
+	int ret = 0;
+
+	memset(&error_str, 0, sizeof(error_str));
+
+	/* We need to have enough room to store any i915_error_state printf
+	 * so that we can move it to start position.
+	 */
+	error_str.size = count + 1 > PAGE_SIZE ? count + 1 : PAGE_SIZE;
+	error_str.buf = kmalloc(error_str.size,
+				GFP_TEMPORARY | __GFP_NORETRY | __GFP_NOWARN);
+
+	if (error_str.buf == NULL) {
+		error_str.size = PAGE_SIZE;
+		error_str.buf = kmalloc(error_str.size, GFP_TEMPORARY);
+	}
+
+	if (error_str.buf == NULL) {
+		error_str.size = 128;
+		error_str.buf = kmalloc(error_str.size, GFP_TEMPORARY);
+	}
+
+	if (error_str.buf == NULL)
+		return -ENOMEM;
+
+	error_str.start = *pos;
+
+	ret = i915_error_state(error_priv, &error_str);
+	if (ret)
+		goto out;
+
+	if (error_str.bytes == 0 && error_str.err) {
+		ret = error_str.err;
+		goto out;
+	}
+
+	ret_count = simple_read_from_buffer(userbuf, count, &tmp_pos,
+					    error_str.buf,
+					    error_str.bytes);
+
+	if (ret_count < 0)
+		ret = ret_count;
+	else
+		*pos = error_str.start + ret_count;
+out:
+	kfree(error_str.buf);
+	return ret ?: ret_count;
 }
 
 static const struct file_operations i915_error_state_fops = {
 	.owner = THIS_MODULE,
 	.open = i915_error_state_open,
-	.read = seq_read,
+	.read = i915_error_state_read,
 	.write = i915_error_state_write,
 	.llseek = default_llseek,
 	.release = i915_error_state_release,
@@ -941,7 +1157,7 @@ static int i915_cur_delayinfo(struct seq
 			   MEMSTAT_VID_SHIFT);
 		seq_printf(m, "Current P-state: %d\n",
 			   (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT);
-	} else if (IS_GEN6(dev) || IS_GEN7(dev)) {
+	} else if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) {
 		u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
 		u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS);
 		u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
@@ -1009,6 +1225,26 @@ static int i915_cur_delayinfo(struct seq
 
 		seq_printf(m, "Max overclocked frequency: %dMHz\n",
 			   dev_priv->rps.hw_max * GT_FREQUENCY_MULTIPLIER);
+	} else if (IS_VALLEYVIEW(dev)) {
+		u32 freq_sts, val;
+
+		mutex_lock(&dev_priv->rps.hw_lock);
+		freq_sts = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+		seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts);
+		seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq);
+
+		val = vlv_punit_read(dev_priv, PUNIT_FUSE_BUS1);
+		seq_printf(m, "max GPU freq: %d MHz\n",
+			   vlv_gpu_freq(dev_priv->mem_freq, val));
+
+		val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM);
+		seq_printf(m, "min GPU freq: %d MHz\n",
+			   vlv_gpu_freq(dev_priv->mem_freq, val));
+
+		seq_printf(m, "current GPU freq: %d MHz\n",
+			   vlv_gpu_freq(dev_priv->mem_freq,
+					(freq_sts >> 8) & 0xff));
+		mutex_unlock(&dev_priv->rps.hw_lock);
 	} else {
 		seq_printf(m, "no P-state info available\n");
 	}
@@ -1290,6 +1526,25 @@ static int i915_fbc_status(struct seq_fi
 	return 0;
 }
 
+static int i915_ips_status(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!HAS_IPS(dev)) {
+		seq_puts(m, "not supported\n");
+		return 0;
+	}
+
+	if (I915_READ(IPS_CTL) & IPS_ENABLE)
+		seq_puts(m, "enabled\n");
+	else
+		seq_puts(m, "disabled\n");
+
+	return 0;
+}
+
 static int i915_sr_status(struct seq_file *m, void *unused)
 {
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -1642,27 +1897,27 @@ static int i915_dpio_info(struct seq_fil
 	seq_printf(m, "DPIO_CTL: 0x%08x\n", I915_READ(DPIO_CTL));
 
 	seq_printf(m, "DPIO_DIV_A: 0x%08x\n",
-		   intel_dpio_read(dev_priv, _DPIO_DIV_A));
+		   vlv_dpio_read(dev_priv, _DPIO_DIV_A));
 	seq_printf(m, "DPIO_DIV_B: 0x%08x\n",
-		   intel_dpio_read(dev_priv, _DPIO_DIV_B));
+		   vlv_dpio_read(dev_priv, _DPIO_DIV_B));
 
 	seq_printf(m, "DPIO_REFSFR_A: 0x%08x\n",
-		   intel_dpio_read(dev_priv, _DPIO_REFSFR_A));
+		   vlv_dpio_read(dev_priv, _DPIO_REFSFR_A));
 	seq_printf(m, "DPIO_REFSFR_B: 0x%08x\n",
-		   intel_dpio_read(dev_priv, _DPIO_REFSFR_B));
+		   vlv_dpio_read(dev_priv, _DPIO_REFSFR_B));
 
 	seq_printf(m, "DPIO_CORE_CLK_A: 0x%08x\n",
-		   intel_dpio_read(dev_priv, _DPIO_CORE_CLK_A));
+		   vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_A));
 	seq_printf(m, "DPIO_CORE_CLK_B: 0x%08x\n",
-		   intel_dpio_read(dev_priv, _DPIO_CORE_CLK_B));
+		   vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_B));
 
-	seq_printf(m, "DPIO_LFP_COEFF_A: 0x%08x\n",
-		   intel_dpio_read(dev_priv, _DPIO_LFP_COEFF_A));
-	seq_printf(m, "DPIO_LFP_COEFF_B: 0x%08x\n",
-		   intel_dpio_read(dev_priv, _DPIO_LFP_COEFF_B));
+	seq_printf(m, "DPIO_LPF_COEFF_A: 0x%08x\n",
+		   vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_A));
+	seq_printf(m, "DPIO_LPF_COEFF_B: 0x%08x\n",
+		   vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_B));
 
 	seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n",
-		   intel_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE));
+		   vlv_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE));
 
 	mutex_unlock(&dev_priv->dpio_lock);
 
@@ -1780,7 +2035,8 @@ i915_drop_caches_set(void *data, u64 val
 	}
 
 	if (val & DROP_UNBOUND) {
-		list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, gtt_list)
+		list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list,
+					 global_list)
 			if (obj->pages_pin_count == 0) {
 				ret = i915_gem_object_put_pages(obj);
 				if (ret)
@@ -1812,7 +2068,11 @@ i915_max_freq_get(void *data, u64 *val)
 	if (ret)
 		return ret;
 
-	*val = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
+	if (IS_VALLEYVIEW(dev))
+		*val = vlv_gpu_freq(dev_priv->mem_freq,
+				    dev_priv->rps.max_delay);
+	else
+		*val = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
 	return 0;
@@ -1837,9 +2097,16 @@ i915_max_freq_set(void *data, u64 val)
 	/*
 	 * Turbo will still be enabled, but won't go above the set value.
 	 */
-	do_div(val, GT_FREQUENCY_MULTIPLIER);
-	dev_priv->rps.max_delay = val;
-	gen6_set_rps(dev, val);
+	if (IS_VALLEYVIEW(dev)) {
+		val = vlv_freq_opcode(dev_priv->mem_freq, val);
+		dev_priv->rps.max_delay = val;
+		gen6_set_rps(dev, val);
+	} else {
+		do_div(val, GT_FREQUENCY_MULTIPLIER);
+		dev_priv->rps.max_delay = val;
+		gen6_set_rps(dev, val);
+	}
+
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
 	return 0;
@@ -1863,7 +2130,11 @@ i915_min_freq_get(void *data, u64 *val)
 	if (ret)
 		return ret;
 
-	*val = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
+	if (IS_VALLEYVIEW(dev))
+		*val = vlv_gpu_freq(dev_priv->mem_freq,
+				    dev_priv->rps.min_delay);
+	else
+		*val = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
 	return 0;
@@ -1888,9 +2159,15 @@ i915_min_freq_set(void *data, u64 val)
 	/*
 	 * Turbo will still be enabled, but won't go below the set value.
 	 */
-	do_div(val, GT_FREQUENCY_MULTIPLIER);
-	dev_priv->rps.min_delay = val;
-	gen6_set_rps(dev, val);
+	if (IS_VALLEYVIEW(dev)) {
+		val = vlv_freq_opcode(dev_priv->mem_freq, val);
+		dev_priv->rps.min_delay = val;
+		valleyview_set_rps(dev, val);
+	} else {
+		do_div(val, GT_FREQUENCY_MULTIPLIER);
+		dev_priv->rps.min_delay = val;
+		gen6_set_rps(dev, val);
+	}
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
 	return 0;
@@ -2057,6 +2334,7 @@ static struct drm_info_list i915_debugfs
 	{"i915_gem_hws", i915_hws_info, 0, (void *)RCS},
 	{"i915_gem_hws_blt", i915_hws_info, 0, (void *)BCS},
 	{"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS},
+	{"i915_gem_hws_vebox", i915_hws_info, 0, (void *)VECS},
 	{"i915_rstdby_delays", i915_rstdby_delays, 0},
 	{"i915_cur_delayinfo", i915_cur_delayinfo, 0},
 	{"i915_delayfreq_table", i915_delayfreq_table, 0},
@@ -2066,6 +2344,7 @@ static struct drm_info_list i915_debugfs
 	{"i915_ring_freq_table", i915_ring_freq_table, 0},
 	{"i915_gfxec", i915_gfxec, 0},
 	{"i915_fbc_status", i915_fbc_status, 0},
+	{"i915_ips_status", i915_ips_status, 0},
 	{"i915_sr_status", i915_sr_status, 0},
 	{"i915_opregion", i915_opregion, 0},
 	{"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_dma.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_dma.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,7 +42,6 @@
 #include <linux/vga_switcheroo.h>
 #include <linux/slab.h>
 #include <acpi/video.h>
-#include <asm/pat.h>
 
 #define LP_RING(d) (&((struct drm_i915_private *)(d))->ring[RCS])
 
@@ -956,6 +955,9 @@ static int i915_getparam(struct drm_devi
 	case I915_PARAM_HAS_BLT:
 		value = intel_ring_initialized(&dev_priv->ring[BCS]);
 		break;
+	case I915_PARAM_HAS_VEBOX:
+		value = intel_ring_initialized(&dev_priv->ring[VECS]);
+		break;
 	case I915_PARAM_HAS_RELAXED_FENCING:
 		value = 1;
 		break;
@@ -999,8 +1001,7 @@ static int i915_getparam(struct drm_devi
 		value = 1;
 		break;
 	default:
-		DRM_DEBUG_DRIVER("Unknown parameter %d\n",
-				 param->param);
+		DRM_DEBUG("Unknown parameter %d\n", param->param);
 		return -EINVAL;
 	}
 
@@ -1359,8 +1360,10 @@ static int i915_load_modeset_init(struct
 cleanup_gem:
 	mutex_lock(&dev->struct_mutex);
 	i915_gem_cleanup_ringbuffer(dev);
+	i915_gem_context_fini(dev);
 	mutex_unlock(&dev->struct_mutex);
 	i915_gem_cleanup_aliasing_ppgtt(dev);
+	drm_mm_takedown(&dev_priv->mm.gtt_space);
 cleanup_irq:
 	drm_irq_uninstall(dev);
 cleanup_gem_stolen:
@@ -1397,29 +1400,6 @@ void i915_master_destroy(struct drm_devi
 	master->driver_priv = NULL;
 }
 
-static void
-i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base,
-		unsigned long size)
-{
-	dev_priv->mm.gtt_mtrr = -1;
-
-#if defined(CONFIG_X86_PAT)
-	if (cpu_has_pat)
-		return;
-#endif
-
-	/* Set up a WC MTRR for non-PAT systems.  This is more common than
-	 * one would think, because the kernel disables PAT on first
-	 * generation Core chips because WC PAT gets overridden by a UC
-	 * MTRR if present.  Even if a UC MTRR isn't present.
-	 */
-	dev_priv->mm.gtt_mtrr = mtrr_add(base, size, MTRR_TYPE_WRCOMB, 1);
-	if (dev_priv->mm.gtt_mtrr < 0) {
-		DRM_INFO("MTRR allocation failed.  Graphics "
-			 "performance may suffer.\n");
-	}
-}
-
 static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
 {
 	struct apertures_struct *ap;
@@ -1431,7 +1411,7 @@ static void i915_kick_out_firmware_fb(st
 		return;
 
 	ap->ranges[0].base = dev_priv->gtt.mappable_base;
-	ap->ranges[0].size = dev_priv->gtt.mappable_end - dev_priv->gtt.start;
+	ap->ranges[0].size = dev_priv->gtt.mappable_end;
 
 	primary =
 		pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
@@ -1445,15 +1425,19 @@ static void i915_dump_device_info(struct
 {
 	const struct intel_device_info *info = dev_priv->info;
 
-#define DEV_INFO_FLAG(name) info->name ? #name "," : ""
-#define DEV_INFO_SEP ,
+#define PRINT_S(name) "%s"
+#define SEP_EMPTY
+#define PRINT_FLAG(name) info->name ? #name "," : ""
+#define SEP_COMMA ,
 	DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x flags="
-			 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+			 DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY),
 			 info->gen,
 			 dev_priv->dev->pdev->device,
-			 DEV_INFO_FLAGS);
-#undef DEV_INFO_FLAG
-#undef DEV_INFO_SEP
+			 DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA));
+#undef PRINT_S
+#undef SEP_EMPTY
+#undef PRINT_FLAG
+#undef SEP_COMMA
 }
 
 /**
@@ -1468,7 +1452,7 @@ static void intel_early_sanitize_regs(st
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_HASWELL(dev))
+	if (HAS_FPGA_DBG_UNCLAIMED(dev))
 		I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
 }
 
@@ -1511,6 +1495,15 @@ int i915_driver_load(struct drm_device *
 	dev_priv->dev = dev;
 	dev_priv->info = info;
 
+	spin_lock_init(&dev_priv->irq_lock);
+	spin_lock_init(&dev_priv->gpu_error.lock);
+	spin_lock_init(&dev_priv->rps.lock);
+	spin_lock_init(&dev_priv->gt_lock);
+	spin_lock_init(&dev_priv->backlight.lock);
+	mutex_init(&dev_priv->dpio_lock);
+	mutex_init(&dev_priv->rps.hw_lock);
+	mutex_init(&dev_priv->modeset_restore_lock);
+
 	i915_dump_device_info(dev_priv);
 
 	if (i915_get_bridge_dev(dev)) {
@@ -1574,8 +1567,8 @@ int i915_driver_load(struct drm_device *
 		goto out_rmmap;
 	}
 
-	i915_mtrr_setup(dev_priv, dev_priv->gtt.mappable_base,
-			aperture_size);
+	dev_priv->mm.gtt_mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base,
+						 aperture_size);
 
 	/* The i915 workqueue is primarily used for batched retirement of
 	 * requests (and thus managing bo) once the task has been completed
@@ -1601,6 +1594,8 @@ int i915_driver_load(struct drm_device *
 	intel_detect_pch(dev);
 
 	intel_irq_init(dev);
+	intel_pm_init(dev);
+	intel_gt_sanitize(dev);
 	intel_gt_init(dev);
 
 	/* Try to make sure MCHBAR is enabled before poking at it */
@@ -1626,14 +1621,6 @@ int i915_driver_load(struct drm_device *
 	if (!IS_I945G(dev) && !IS_I945GM(dev))
 		pci_enable_msi(dev->pdev);
 
-	spin_lock_init(&dev_priv->irq_lock);
-	spin_lock_init(&dev_priv->gpu_error.lock);
-	spin_lock_init(&dev_priv->rps.lock);
-	mutex_init(&dev_priv->dpio_lock);
-
-	mutex_init(&dev_priv->rps.hw_lock);
-	mutex_init(&dev_priv->modeset_restore_lock);
-
 	dev_priv->num_plane = 1;
 	if (IS_VALLEYVIEW(dev))
 		dev_priv->num_plane = 2;
@@ -1647,6 +1634,9 @@ int i915_driver_load(struct drm_device *
 	/* Start out suspended */
 	dev_priv->mm.suspended = 1;
 
+	if (HAS_POWER_WELL(dev))
+		i915_init_power_well(dev);
+
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		ret = i915_load_modeset_init(dev);
 		if (ret < 0) {
@@ -1679,12 +1669,7 @@ out_gem_unload:
 	intel_teardown_mchbar(dev);
 	destroy_workqueue(dev_priv->wq);
 out_mtrrfree:
-	if (dev_priv->mm.gtt_mtrr >= 0) {
-		mtrr_del(dev_priv->mm.gtt_mtrr,
-			 dev_priv->gtt.mappable_base,
-			 aperture_size);
-		dev_priv->mm.gtt_mtrr = -1;
-	}
+	arch_phys_wc_del(dev_priv->mm.gtt_mtrr);
 	io_mapping_free(dev_priv->gtt.mappable);
 	dev_priv->gtt.gtt_remove(dev);
 out_rmmap:
@@ -1703,6 +1688,9 @@ int i915_driver_unload(struct drm_device
 
 	intel_gpu_ips_teardown();
 
+	if (HAS_POWER_WELL(dev))
+		i915_remove_power_well(dev);
+
 	i915_teardown_sysfs(dev);
 
 	if (dev_priv->mm.inactive_shrinker.shrink)
@@ -1719,12 +1707,7 @@ int i915_driver_unload(struct drm_device
 	cancel_delayed_work_sync(&dev_priv->mm.retire_work);
 
 	io_mapping_free(dev_priv->gtt.mappable);
-	if (dev_priv->mm.gtt_mtrr >= 0) {
-		mtrr_del(dev_priv->mm.gtt_mtrr,
-			 dev_priv->gtt.mappable_base,
-			 dev_priv->gtt.mappable_end);
-		dev_priv->mm.gtt_mtrr = -1;
-	}
+	arch_phys_wc_del(dev_priv->mm.gtt_mtrr);
 
 	acpi_video_unregister();
 
@@ -1737,10 +1720,10 @@ int i915_driver_unload(struct drm_device
 		 * free the memory space allocated for the child device
 		 * config parsed from VBT
 		 */
-		if (dev_priv->child_dev && dev_priv->child_dev_num) {
-			kfree(dev_priv->child_dev);
-			dev_priv->child_dev = NULL;
-			dev_priv->child_dev_num = 0;
+		if (dev_priv->vbt.child_dev && dev_priv->vbt.child_dev_num) {
+			kfree(dev_priv->vbt.child_dev);
+			dev_priv->vbt.child_dev = NULL;
+			dev_priv->vbt.child_dev_num = 0;
 		}
 
 		vga_switcheroo_unregister_client(dev->pdev);
@@ -1773,6 +1756,7 @@ int i915_driver_unload(struct drm_device
 			i915_free_hws(dev);
 	}
 
+	drm_mm_takedown(&dev_priv->mm.gtt_space);
 	if (dev_priv->regs != NULL)
 		pci_iounmap(dev->pdev, dev_priv->regs);
 
@@ -1782,6 +1766,8 @@ int i915_driver_unload(struct drm_device
 	destroy_workqueue(dev_priv->wq);
 	pm_qos_remove_request(&dev_priv->pm_qos);
 
+	dev_priv->gtt.gtt_remove(dev);
+
 	if (dev_priv->slab)
 		kmem_cache_destroy(dev_priv->slab);
 
@@ -1796,7 +1782,7 @@ int i915_driver_open(struct drm_device *
 	struct drm_i915_file_private *file_priv;
 
 	DRM_DEBUG_DRIVER("\n");
-	file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL);
+	file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
 	if (!file_priv)
 		return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -123,10 +123,14 @@ module_param_named(preliminary_hw_suppor
 MODULE_PARM_DESC(preliminary_hw_support,
 		"Enable preliminary hardware support. (default: false)");
 
-int i915_disable_power_well __read_mostly = 0;
+int i915_disable_power_well __read_mostly = 1;
 module_param_named(disable_power_well, i915_disable_power_well, int, 0600);
 MODULE_PARM_DESC(disable_power_well,
-		 "Disable the power well when possible (default: false)");
+		 "Disable the power well when possible (default: true)");
+
+int i915_enable_ips __read_mostly = 1;
+module_param_named(enable_ips, i915_enable_ips, int, 0600);
+MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)");
 
 static struct drm_driver driver;
 extern int intel_agp_enabled;
@@ -280,6 +284,7 @@ static const struct intel_device_info in
 	GEN7_FEATURES,
 	.is_ivybridge = 1,
 	.is_mobile = 1,
+	.has_fbc = 1,
 };
 
 static const struct intel_device_info intel_ivybridge_q_info = {
@@ -308,12 +313,19 @@ static const struct intel_device_info in
 static const struct intel_device_info intel_haswell_d_info = {
 	GEN7_FEATURES,
 	.is_haswell = 1,
+	.has_ddi = 1,
+	.has_fpga_dbg = 1,
+	.has_vebox_ring = 1,
 };
 
 static const struct intel_device_info intel_haswell_m_info = {
 	GEN7_FEATURES,
 	.is_haswell = 1,
 	.is_mobile = 1,
+	.has_ddi = 1,
+	.has_fpga_dbg = 1,
+	.has_fbc = 1,
+	.has_vebox_ring = 1,
 };
 
 static const struct pci_device_id pciidlist[] = {		/* aka */
@@ -445,7 +457,6 @@ void intel_detect_pch(struct drm_device
 	 */
 	if (INTEL_INFO(dev)->num_pipes == 0) {
 		dev_priv->pch_type = PCH_NOP;
-		dev_priv->num_pch_pll = 0;
 		return;
 	}
 
@@ -454,9 +465,15 @@ void intel_detect_pch(struct drm_device
 	 * make graphics device passthrough work easy for VMM, that only
 	 * need to expose ISA bridge to let driver know the real hardware
 	 * underneath. This is a requirement from virtualization team.
+	 *
+	 * In some virtualized environments (e.g. XEN), there is irrelevant
+	 * ISA bridge in the system. To work reliably, we should scan trhough
+	 * all the ISA bridge devices and check for the first match, instead
+	 * of only checking the first one.
 	 */
 	pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
-	if (pch) {
+	while (pch) {
+		struct pci_dev *curr = pch;
 		if (pch->vendor == PCI_VENDOR_ID_INTEL) {
 			unsigned short id;
 			id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
@@ -464,37 +481,39 @@ void intel_detect_pch(struct drm_device
 
 			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_IBX;
-				dev_priv->num_pch_pll = 2;
 				DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
 				WARN_ON(!IS_GEN5(dev));
 			} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_CPT;
-				dev_priv->num_pch_pll = 2;
 				DRM_DEBUG_KMS("Found CougarPoint PCH\n");
 				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
 			} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
 				/* PantherPoint is CPT compatible */
 				dev_priv->pch_type = PCH_CPT;
-				dev_priv->num_pch_pll = 2;
 				DRM_DEBUG_KMS("Found PatherPoint PCH\n");
 				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
 			} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_LPT;
-				dev_priv->num_pch_pll = 0;
 				DRM_DEBUG_KMS("Found LynxPoint PCH\n");
 				WARN_ON(!IS_HASWELL(dev));
 				WARN_ON(IS_ULT(dev));
 			} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_LPT;
-				dev_priv->num_pch_pll = 0;
 				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
 				WARN_ON(!IS_HASWELL(dev));
 				WARN_ON(!IS_ULT(dev));
+			} else {
+				goto check_next;
 			}
-			BUG_ON(dev_priv->num_pch_pll > I915_NUM_PLLS);
+			pci_dev_put(pch);
+			break;
 		}
-		pci_dev_put(pch);
+check_next:
+		pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, curr);
+		pci_dev_put(curr);
 	}
+	if (!pch)
+		DRM_DEBUG_KMS("No PCH found?\n");
 }
 
 bool i915_semaphore_is_enabled(struct drm_device *dev)
@@ -549,6 +568,8 @@ static int i915_drm_freeze(struct drm_de
 		 */
 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
 			dev_priv->display.crtc_disable(crtc);
+
+		intel_modeset_suspend_hw(dev);
 	}
 
 	i915_save_state(dev);
@@ -556,7 +577,7 @@ static int i915_drm_freeze(struct drm_de
 	intel_opregion_fini(dev);
 
 	console_lock();
-	intel_fbdev_set_suspend(dev, 1);
+	intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED);
 	console_unlock();
 
 	return 0;
@@ -600,7 +621,7 @@ void intel_console_resume(struct work_st
 	struct drm_device *dev = dev_priv->dev;
 
 	console_lock();
-	intel_fbdev_set_suspend(dev, 0);
+	intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING);
 	console_unlock();
 }
 
@@ -669,7 +690,7 @@ static int __i915_drm_thaw(struct drm_de
 	 * path of resume if possible.
 	 */
 	if (console_trylock()) {
-		intel_fbdev_set_suspend(dev, 0);
+		intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING);
 		console_unlock();
 	} else {
 		schedule_work(&dev_priv->console_resume_work);
@@ -685,7 +706,7 @@ static int i915_drm_thaw(struct drm_devi
 {
 	int error = 0;
 
-	intel_gt_reset(dev);
+	intel_gt_sanitize(dev);
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		mutex_lock(&dev->struct_mutex);
@@ -711,7 +732,7 @@ int i915_resume(struct drm_device *dev)
 
 	pci_set_master(dev->pdev);
 
-	intel_gt_reset(dev);
+	intel_gt_sanitize(dev);
 
 	/*
 	 * Platforms with opregion should have sane BIOS, older ones (gen3 and
@@ -855,37 +876,14 @@ static int gen6_do_reset(struct drm_devi
 
 int intel_gpu_reset(struct drm_device *dev)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	int ret = -ENODEV;
-
 	switch (INTEL_INFO(dev)->gen) {
 	case 7:
-	case 6:
-		ret = gen6_do_reset(dev);
-		break;
-	case 5:
-		ret = ironlake_do_reset(dev);
-		break;
-	case 4:
-		ret = i965_do_reset(dev);
-		break;
-	case 2:
-		ret = i8xx_do_reset(dev);
-		break;
-	}
-
-	/* Also reset the gpu hangman. */
-	if (dev_priv->gpu_error.stop_rings) {
-		DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
-		dev_priv->gpu_error.stop_rings = 0;
-		if (ret == -ENODEV) {
-			DRM_ERROR("Reset not implemented, but ignoring "
-				  "error for simulated gpu hangs\n");
-			ret = 0;
-		}
+	case 6: return gen6_do_reset(dev);
+	case 5: return ironlake_do_reset(dev);
+	case 4: return i965_do_reset(dev);
+	case 2: return i8xx_do_reset(dev);
+	default: return -ENODEV;
 	}
-
-	return ret;
 }
 
 /**
@@ -906,6 +904,7 @@ int intel_gpu_reset(struct drm_device *d
 int i915_reset(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
+	bool simulated;
 	int ret;
 
 	if (!i915_try_reset)
@@ -915,13 +914,26 @@ int i915_reset(struct drm_device *dev)
 
 	i915_gem_reset(dev);
 
-	ret = -ENODEV;
-	if (get_seconds() - dev_priv->gpu_error.last_reset < 5)
+	simulated = dev_priv->gpu_error.stop_rings != 0;
+
+	if (!simulated && get_seconds() - dev_priv->gpu_error.last_reset < 5) {
 		DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
-	else
+		ret = -ENODEV;
+	} else {
 		ret = intel_gpu_reset(dev);
 
-	dev_priv->gpu_error.last_reset = get_seconds();
+		/* Also reset the gpu hangman. */
+		if (simulated) {
+			DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
+			dev_priv->gpu_error.stop_rings = 0;
+			if (ret == -ENODEV) {
+				DRM_ERROR("Reset not implemented, but ignoring "
+					  "error for simulated gpu hangs\n");
+				ret = 0;
+			}
+		} else
+			dev_priv->gpu_error.last_reset = get_seconds();
+	}
 	if (ret) {
 		DRM_ERROR("Failed to reset chip.\n");
 		mutex_unlock(&dev->struct_mutex);
@@ -984,12 +996,6 @@ static int i915_pci_probe(struct pci_dev
 	struct intel_device_info *intel_info =
 		(struct intel_device_info *) ent->driver_data;
 
-	if (intel_info->is_valleyview)
-		if(!i915_preliminary_hw_support) {
-			DRM_ERROR("Preliminary hardware support disabled\n");
-			return -ENODEV;
-		}
-
 	/* Only bind to function 0 of the device. Early generations
 	 * used function 1 as a placeholder for multi-head. This causes
 	 * us confusion instead, especially on the systems where both
@@ -1218,16 +1224,16 @@ MODULE_LICENSE("GPL and additional right
 static void
 ilk_dummy_write(struct drm_i915_private *dev_priv)
 {
-	/* WaIssueDummyWriteToWakeupFromRC6: Issue a dummy write to wake up the
-	 * chip from rc6 before touching it for real. MI_MODE is masked, hence
-	 * harmless to write 0 into. */
+	/* WaIssueDummyWriteToWakeupFromRC6:ilk Issue a dummy write to wake up
+	 * the chip from rc6 before touching it for real. MI_MODE is masked,
+	 * hence harmless to write 0 into. */
 	I915_WRITE_NOTRACE(MI_MODE, 0);
 }
 
 static void
 hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg)
 {
-	if (IS_HASWELL(dev_priv->dev) &&
+	if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) &&
 	    (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) {
 		DRM_ERROR("Unknown unclaimed register before writing to %x\n",
 			  reg);
@@ -1238,7 +1244,7 @@ hsw_unclaimed_reg_clear(struct drm_i915_
 static void
 hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg)
 {
-	if (IS_HASWELL(dev_priv->dev) &&
+	if (HAS_FPGA_DBG_UNCLAIMED(dev_priv->dev) &&
 	    (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) {
 		DRM_ERROR("Unclaimed write to %x\n", reg);
 		I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
@@ -1247,21 +1253,21 @@ hsw_unclaimed_reg_check(struct drm_i915_
 
 #define __i915_read(x, y) \
 u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
+	unsigned long irqflags; \
 	u##x val = 0; \
+	spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
 	if (IS_GEN5(dev_priv->dev)) \
 		ilk_dummy_write(dev_priv); \
 	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
-		unsigned long irqflags; \
-		spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
 		if (dev_priv->forcewake_count == 0) \
 			dev_priv->gt.force_wake_get(dev_priv); \
 		val = read##y(dev_priv->regs + reg); \
 		if (dev_priv->forcewake_count == 0) \
 			dev_priv->gt.force_wake_put(dev_priv); \
-		spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
 	} else { \
 		val = read##y(dev_priv->regs + reg); \
 	} \
+	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
 	trace_i915_reg_rw(false, reg, val, sizeof(val)); \
 	return val; \
 }
@@ -1274,8 +1280,10 @@ __i915_read(64, q)
 
 #define __i915_write(x, y) \
 void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
+	unsigned long irqflags; \
 	u32 __fifo_ret = 0; \
 	trace_i915_reg_rw(true, reg, val, sizeof(val)); \
+	spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
 	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
 		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
 	} \
@@ -1287,6 +1295,7 @@ void i915_write##x(struct drm_i915_priva
 		gen6_gt_check_fifodbg(dev_priv); \
 	} \
 	hsw_unclaimed_reg_check(dev_priv, reg); \
+	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
 }
 __i915_write(8, b)
 __i915_write(16, w)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -76,6 +76,8 @@ enum plane {
 };
 #define plane_name(p) ((p) + 'A')
 
+#define sprite_name(p, s) ((p) * dev_priv->num_plane + (s) + 'A')
+
 enum port {
 	PORT_A = 0,
 	PORT_B,
@@ -86,6 +88,24 @@ enum port {
 };
 #define port_name(p) ((p) + 'A')
 
+enum intel_display_power_domain {
+	POWER_DOMAIN_PIPE_A,
+	POWER_DOMAIN_PIPE_B,
+	POWER_DOMAIN_PIPE_C,
+	POWER_DOMAIN_PIPE_A_PANEL_FITTER,
+	POWER_DOMAIN_PIPE_B_PANEL_FITTER,
+	POWER_DOMAIN_PIPE_C_PANEL_FITTER,
+	POWER_DOMAIN_TRANSCODER_A,
+	POWER_DOMAIN_TRANSCODER_B,
+	POWER_DOMAIN_TRANSCODER_C,
+	POWER_DOMAIN_TRANSCODER_EDP = POWER_DOMAIN_TRANSCODER_A + 0xF,
+};
+
+#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
+#define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \
+		((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER)
+#define POWER_DOMAIN_TRANSCODER(tran) ((tran) + POWER_DOMAIN_TRANSCODER_A)
+
 enum hpd_pin {
 	HPD_NONE = 0,
 	HPD_PORT_A = HPD_NONE, /* PORT_A is internal */
@@ -112,15 +132,38 @@ enum hpd_pin {
 	list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
 		if ((intel_encoder)->base.crtc == (__crtc))
 
-struct intel_pch_pll {
+struct drm_i915_private;
+
+enum intel_dpll_id {
+	DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
+	/* real shared dpll ids must be >= 0 */
+	DPLL_ID_PCH_PLL_A,
+	DPLL_ID_PCH_PLL_B,
+};
+#define I915_NUM_PLLS 2
+
+struct intel_dpll_hw_state {
+	uint32_t dpll;
+	uint32_t fp0;
+	uint32_t fp1;
+};
+
+struct intel_shared_dpll {
 	int refcount; /* count of number of CRTCs sharing this PLL */
 	int active; /* count of number of active CRTCs (i.e. DPMS on) */
 	bool on; /* is the PLL actually active? Disabled during modeset */
-	int pll_reg;
-	int fp0_reg;
-	int fp1_reg;
+	const char *name;
+	/* should match the index in the dev_priv->shared_dplls array */
+	enum intel_dpll_id id;
+	struct intel_dpll_hw_state hw_state;
+	void (*enable)(struct drm_i915_private *dev_priv,
+		       struct intel_shared_dpll *pll);
+	void (*disable)(struct drm_i915_private *dev_priv,
+			struct intel_shared_dpll *pll);
+	bool (*get_hw_state)(struct drm_i915_private *dev_priv,
+			     struct intel_shared_dpll *pll,
+			     struct intel_dpll_hw_state *hw_state);
 };
-#define I915_NUM_PLLS 2
 
 /* Used by dp and fdi links */
 struct intel_link_m_n {
@@ -175,7 +218,6 @@ struct opregion_header;
 struct opregion_acpi;
 struct opregion_swsci;
 struct opregion_asle;
-struct drm_i915_private;
 
 struct intel_opregion {
 	struct opregion_header __iomem *header;
@@ -286,6 +328,8 @@ struct drm_i915_error_state {
 
 struct intel_crtc_config;
 struct intel_crtc;
+struct intel_limit;
+struct dpll;
 
 struct drm_i915_display_funcs {
 	bool (*fbc_enabled)(struct drm_device *dev);
@@ -293,11 +337,28 @@ struct drm_i915_display_funcs {
 	void (*disable_fbc)(struct drm_device *dev);
 	int (*get_display_clock_speed)(struct drm_device *dev);
 	int (*get_fifo_size)(struct drm_device *dev, int plane);
+	/**
+	 * find_dpll() - Find the best values for the PLL
+	 * @limit: limits for the PLL
+	 * @crtc: current CRTC
+	 * @target: target frequency in kHz
+	 * @refclk: reference clock frequency in kHz
+	 * @match_clock: if provided, @best_clock P divider must
+	 *               match the P divider from @match_clock
+	 *               used for LVDS downclocking
+	 * @best_clock: best PLL values found
+	 *
+	 * Returns true on success, false on failure.
+	 */
+	bool (*find_dpll)(const struct intel_limit *limit,
+			  struct drm_crtc *crtc,
+			  int target, int refclk,
+			  struct dpll *match_clock,
+			  struct dpll *best_clock);
 	void (*update_wm)(struct drm_device *dev);
 	void (*update_sprite_wm)(struct drm_device *dev, int pipe,
-				 uint32_t sprite_width, int pixel_size);
-	void (*update_linetime_wm)(struct drm_device *dev, int pipe,
-				 struct drm_display_mode *mode);
+				 uint32_t sprite_width, int pixel_size,
+				 bool enable);
 	void (*modeset_global_resources)(struct drm_device *dev);
 	/* Returns the active state of the crtc, and if the crtc is active,
 	 * fills out the pipe-config with the hw state. */
@@ -331,68 +392,56 @@ struct drm_i915_gt_funcs {
 	void (*force_wake_put)(struct drm_i915_private *dev_priv);
 };
 
-#define DEV_INFO_FLAGS \
-	DEV_INFO_FLAG(is_mobile) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_i85x) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_i915g) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_i945gm) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_g33) DEV_INFO_SEP \
-	DEV_INFO_FLAG(need_gfx_hws) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_g4x) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_pineview) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_broadwater) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_crestline) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_ivybridge) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_valleyview) DEV_INFO_SEP \
-	DEV_INFO_FLAG(is_haswell) DEV_INFO_SEP \
-	DEV_INFO_FLAG(has_force_wake) DEV_INFO_SEP \
-	DEV_INFO_FLAG(has_fbc) DEV_INFO_SEP \
-	DEV_INFO_FLAG(has_pipe_cxsr) DEV_INFO_SEP \
-	DEV_INFO_FLAG(has_hotplug) DEV_INFO_SEP \
-	DEV_INFO_FLAG(cursor_needs_physical) DEV_INFO_SEP \
-	DEV_INFO_FLAG(has_overlay) DEV_INFO_SEP \
-	DEV_INFO_FLAG(overlay_needs_physical) DEV_INFO_SEP \
-	DEV_INFO_FLAG(supports_tv) DEV_INFO_SEP \
-	DEV_INFO_FLAG(has_bsd_ring) DEV_INFO_SEP \
-	DEV_INFO_FLAG(has_blt_ring) DEV_INFO_SEP \
-	DEV_INFO_FLAG(has_llc)
+#define DEV_INFO_FOR_EACH_FLAG(func, sep) \
+	func(is_mobile) sep \
+	func(is_i85x) sep \
+	func(is_i915g) sep \
+	func(is_i945gm) sep \
+	func(is_g33) sep \
+	func(need_gfx_hws) sep \
+	func(is_g4x) sep \
+	func(is_pineview) sep \
+	func(is_broadwater) sep \
+	func(is_crestline) sep \
+	func(is_ivybridge) sep \
+	func(is_valleyview) sep \
+	func(is_haswell) sep \
+	func(has_force_wake) sep \
+	func(has_fbc) sep \
+	func(has_pipe_cxsr) sep \
+	func(has_hotplug) sep \
+	func(cursor_needs_physical) sep \
+	func(has_overlay) sep \
+	func(overlay_needs_physical) sep \
+	func(supports_tv) sep \
+	func(has_bsd_ring) sep \
+	func(has_blt_ring) sep \
+	func(has_vebox_ring) sep \
+	func(has_llc) sep \
+	func(has_ddi) sep \
+	func(has_fpga_dbg)
+
+#define DEFINE_FLAG(name) u8 name:1
+#define SEP_SEMICOLON ;
 
 struct intel_device_info {
 	u32 display_mmio_offset;
 	u8 num_pipes:3;
 	u8 gen;
-	u8 is_mobile:1;
-	u8 is_i85x:1;
-	u8 is_i915g:1;
-	u8 is_i945gm:1;
-	u8 is_g33:1;
-	u8 need_gfx_hws:1;
-	u8 is_g4x:1;
-	u8 is_pineview:1;
-	u8 is_broadwater:1;
-	u8 is_crestline:1;
-	u8 is_ivybridge:1;
-	u8 is_valleyview:1;
-	u8 has_force_wake:1;
-	u8 is_haswell:1;
-	u8 has_fbc:1;
-	u8 has_pipe_cxsr:1;
-	u8 has_hotplug:1;
-	u8 cursor_needs_physical:1;
-	u8 has_overlay:1;
-	u8 overlay_needs_physical:1;
-	u8 supports_tv:1;
-	u8 has_bsd_ring:1;
-	u8 has_blt_ring:1;
-	u8 has_llc:1;
+	DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
 };
 
+#undef DEFINE_FLAG
+#undef SEP_SEMICOLON
+
 enum i915_cache_level {
 	I915_CACHE_NONE = 0,
 	I915_CACHE_LLC,
 	I915_CACHE_LLC_MLC, /* gen6+, in docs at least! */
 };
 
+typedef uint32_t gen6_gtt_pte_t;
+
 /* The Graphics Translation Table is the way in which GEN hardware translates a
  * Graphics Virtual Address into a Physical Address. In addition to the normal
  * collateral associated with any va->pa translations GEN hardware also has a
@@ -428,6 +477,9 @@ struct i915_gtt {
 				   struct sg_table *st,
 				   unsigned int pg_start,
 				   enum i915_cache_level cache_level);
+	gen6_gtt_pte_t (*pte_encode)(struct drm_device *dev,
+				     dma_addr_t addr,
+				     enum i915_cache_level level);
 };
 #define gtt_total_entries(gtt) ((gtt).total >> PAGE_SHIFT)
 
@@ -449,19 +501,31 @@ struct i915_hw_ppgtt {
 			       struct sg_table *st,
 			       unsigned int pg_start,
 			       enum i915_cache_level cache_level);
+	gen6_gtt_pte_t (*pte_encode)(struct drm_device *dev,
+				     dma_addr_t addr,
+				     enum i915_cache_level level);
 	int (*enable)(struct drm_device *dev);
 	void (*cleanup)(struct i915_hw_ppgtt *ppgtt);
 };
 
+struct i915_ctx_hang_stats {
+	/* This context had batch pending when hang was declared */
+	unsigned batch_pending;
+
+	/* This context had batch active when hang was declared */
+	unsigned batch_active;
+};
 
 /* This must match up with the value previously used for execbuf2.rsvd1. */
 #define DEFAULT_CONTEXT_ID 0
 struct i915_hw_context {
+	struct kref ref;
 	int id;
 	bool is_initialized;
 	struct drm_i915_file_private *file_priv;
 	struct intel_ring_buffer *ring;
 	struct drm_i915_gem_object *obj;
+	struct i915_ctx_hang_stats hang_stats;
 };
 
 enum no_fbc_reason {
@@ -491,6 +555,7 @@ enum intel_sbi_destination {
 #define QUIRK_PIPEA_FORCE (1<<0)
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
+#define QUIRK_NO_PCH_PWM_ENABLE (1<<3)
 
 struct intel_fbdev;
 struct intel_fbc_work;
@@ -658,6 +723,7 @@ struct i915_suspend_saved_registers {
 
 struct intel_gen6_power_mgmt {
 	struct work_struct work;
+	struct delayed_work vlv_work;
 	u32 pm_iir;
 	/* lock - irqsave spinlock that protectects the work_struct and
 	 * pm_iir. */
@@ -668,6 +734,7 @@ struct intel_gen6_power_mgmt {
 	u8 cur_delay;
 	u8 min_delay;
 	u8 max_delay;
+	u8 rpe_delay;
 	u8 hw_max;
 
 	struct delayed_work delayed_resume_work;
@@ -704,6 +771,15 @@ struct intel_ilk_power_mgmt {
 	struct drm_i915_gem_object *renderctx;
 };
 
+/* Power well structure for haswell */
+struct i915_power_well {
+	struct drm_device *device;
+	spinlock_t lock;
+	/* power well enable/disable usage count */
+	int count;
+	int i915_request;
+};
+
 struct i915_dri1_state {
 	unsigned allow_batchbuffer : 1;
 	u32 __iomem *gfx_hws_cpu_addr;
@@ -812,14 +888,20 @@ struct i915_gem_mm {
 	u32 object_count;
 };
 
+struct drm_i915_error_state_buf {
+	unsigned bytes;
+	unsigned size;
+	int err;
+	u8 *buf;
+	loff_t start;
+	loff_t pos;
+};
+
 struct i915_gpu_error {
 	/* For hangcheck timer */
 #define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */
 #define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)
 	struct timer_list hangcheck_timer;
-	int hangcheck_count;
-	uint32_t last_acthd[I915_NUM_RINGS];
-	uint32_t prev_instdone[I915_NUM_INSTDONE_REG];
 
 	/* For reset and error_state handling. */
 	spinlock_t lock;
@@ -875,6 +957,37 @@ enum modeset_restore {
 	MODESET_SUSPENDED,
 };
 
+struct intel_vbt_data {
+	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
+	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
+
+	/* Feature bits */
+	unsigned int int_tv_support:1;
+	unsigned int lvds_dither:1;
+	unsigned int lvds_vbt:1;
+	unsigned int int_crt_support:1;
+	unsigned int lvds_use_ssc:1;
+	unsigned int display_clock_mode:1;
+	unsigned int fdi_rx_polarity_inverted:1;
+	int lvds_ssc_freq;
+	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
+
+	/* eDP */
+	int edp_rate;
+	int edp_lanes;
+	int edp_preemphasis;
+	int edp_vswing;
+	bool edp_initialized;
+	bool edp_support;
+	int edp_bpp;
+	struct edp_power_seq edp_pps;
+
+	int crt_ddc_pin;
+
+	int child_dev_num;
+	struct child_device_config *child_dev;
+};
+
 typedef struct drm_i915_private {
 	struct drm_device *dev;
 	struct kmem_cache *slab;
@@ -941,9 +1054,9 @@ typedef struct drm_i915_private {
 			HPD_MARK_DISABLED = 2
 		} hpd_mark;
 	} hpd_stats[HPD_NUM_PINS];
+	u32 hpd_event_bits;
 	struct timer_list hotplug_reenable_timer;
 
-	int num_pch_pll;
 	int num_plane;
 
 	unsigned long cfb_size;
@@ -953,6 +1066,7 @@ typedef struct drm_i915_private {
 	struct intel_fbc_work *fbc_work;
 
 	struct intel_opregion opregion;
+	struct intel_vbt_data vbt;
 
 	/* overlay */
 	struct intel_overlay *overlay;
@@ -962,37 +1076,15 @@ typedef struct drm_i915_private {
 	struct {
 		int level;
 		bool enabled;
+		spinlock_t lock; /* bl registers and the above bl fields */
 		struct backlight_device *device;
 	} backlight;
 
 	/* LVDS info */
 	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
 	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
-
-	/* Feature bits from the VBIOS */
-	unsigned int int_tv_support:1;
-	unsigned int lvds_dither:1;
-	unsigned int lvds_vbt:1;
-	unsigned int int_crt_support:1;
-	unsigned int lvds_use_ssc:1;
-	unsigned int display_clock_mode:1;
-	unsigned int fdi_rx_polarity_inverted:1;
-	int lvds_ssc_freq;
-	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
-	struct {
-		int rate;
-		int lanes;
-		int preemphasis;
-		int vswing;
-
-		bool initialized;
-		bool support;
-		int bpp;
-		struct edp_power_seq pps;
-	} edp;
 	bool no_aux_handshake;
 
-	int crt_ddc_pin;
 	struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */
 	int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
 	int num_fence_regs; /* 8 on pre-965, 16 otherwise */
@@ -1020,16 +1112,13 @@ typedef struct drm_i915_private {
 	/* Kernel Modesetting */
 
 	struct sdvo_device_mapping sdvo_mappings[2];
-	/* indicate whether the LVDS_BORDER should be enabled or not */
-	unsigned int lvds_border_bits;
-	/* Panel fitter placement and size for Ironlake+ */
-	u32 pch_pf_pos, pch_pf_size;
 
 	struct drm_crtc *plane_to_crtc_mapping[3];
 	struct drm_crtc *pipe_to_crtc_mapping[3];
 	wait_queue_head_t pending_flip_queue;
 
-	struct intel_pch_pll pch_plls[I915_NUM_PLLS];
+	int num_shared_dpll;
+	struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
 	struct intel_ddi_plls ddi_plls;
 
 	/* Reclocking support */
@@ -1038,8 +1127,6 @@ typedef struct drm_i915_private {
 	/* indicates the reduced downclock for LVDS*/
 	int lvds_downclock;
 	u16 orig_clock;
-	int child_dev_num;
-	struct child_device_config *child_dev;
 
 	bool mchbar_need_disable;
 
@@ -1052,6 +1139,9 @@ typedef struct drm_i915_private {
 	 * mchdev_lock in intel_pm.c */
 	struct intel_ilk_power_mgmt ips;
 
+	/* Haswell power well */
+	struct i915_power_well power_well;
+
 	enum no_fbc_reason no_fbc_reason;
 
 	struct drm_mm_node *compressed_fb;
@@ -1059,6 +1149,8 @@ typedef struct drm_i915_private {
 
 	struct i915_gpu_error gpu_error;
 
+	struct drm_i915_gem_object *vlv_pctx;
+
 	/* list of fbdev register on this device */
 	struct intel_fbdev *fbdev;
 
@@ -1124,7 +1216,7 @@ struct drm_i915_gem_object {
 	struct drm_mm_node *gtt_space;
 	/** Stolen memory for this object, instead of being backed by shmem. */
 	struct drm_mm_node *stolen;
-	struct list_head gtt_list;
+	struct list_head global_list;
 
 	/** This object's place on the active/inactive lists */
 	struct list_head ring_list;
@@ -1271,9 +1363,18 @@ struct drm_i915_gem_request {
 	/** GEM sequence number associated with this request. */
 	uint32_t seqno;
 
-	/** Postion in the ringbuffer of the end of the request */
+	/** Position in the ringbuffer of the start of the request */
+	u32 head;
+
+	/** Position in the ringbuffer of the end of the request */
 	u32 tail;
 
+	/** Context related to this request */
+	struct i915_hw_context *ctx;
+
+	/** Batch buffer related to this request if any */
+	struct drm_i915_gem_object *batch_obj;
+
 	/** Time at which this request was emitted, in jiffies. */
 	unsigned long emitted_jiffies;
 
@@ -1291,6 +1392,8 @@ struct drm_i915_file_private {
 		struct list_head request_list;
 	} mm;
 	struct idr context_idr;
+
+	struct i915_ctx_hang_stats hang_stats;
 };
 
 #define INTEL_INFO(dev)	(((struct drm_i915_private *) (dev)->dev_private)->info)
@@ -1341,6 +1444,7 @@ struct drm_i915_file_private {
 
 #define HAS_BSD(dev)            (INTEL_INFO(dev)->has_bsd_ring)
 #define HAS_BLT(dev)            (INTEL_INFO(dev)->has_blt_ring)
+#define HAS_VEBOX(dev)          (INTEL_INFO(dev)->has_vebox_ring)
 #define HAS_LLC(dev)            (INTEL_INFO(dev)->has_llc)
 #define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)
 
@@ -1371,10 +1475,13 @@ struct drm_i915_file_private {
 #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr)
 #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc)
 
+#define HAS_IPS(dev)		(IS_ULT(dev))
+
 #define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5)
 
-#define HAS_DDI(dev)		(IS_HASWELL(dev))
+#define HAS_DDI(dev)		(INTEL_INFO(dev)->has_ddi)
 #define HAS_POWER_WELL(dev)	(IS_HASWELL(dev))
+#define HAS_FPGA_DBG_UNCLAIMED(dev)	(INTEL_INFO(dev)->has_fpga_dbg)
 
 #define INTEL_PCH_DEVICE_ID_MASK		0xff00
 #define INTEL_PCH_IBX_DEVICE_ID_TYPE		0x3b00
@@ -1435,6 +1542,7 @@ extern bool i915_enable_hangcheck __read
 extern int i915_enable_ppgtt __read_mostly;
 extern unsigned int i915_preliminary_hw_support __read_mostly;
 extern int i915_disable_power_well __read_mostly;
+extern int i915_enable_ips __read_mostly;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
@@ -1474,9 +1582,10 @@ void i915_hangcheck_elapsed(unsigned lon
 void i915_handle_error(struct drm_device *dev, bool wedged);
 
 extern void intel_irq_init(struct drm_device *dev);
+extern void intel_pm_init(struct drm_device *dev);
 extern void intel_hpd_init(struct drm_device *dev);
 extern void intel_gt_init(struct drm_device *dev);
-extern void intel_gt_reset(struct drm_device *dev);
+extern void intel_gt_sanitize(struct drm_device *dev);
 
 void i915_error_state_free(struct kref *error_ref);
 
@@ -1486,8 +1595,6 @@ i915_enable_pipestat(drm_i915_private_t
 void
 i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
 
-void intel_enable_asle(struct drm_device *dev);
-
 #ifdef CONFIG_DEBUG_FS
 extern void i915_destroy_error_state(struct drm_device *dev);
 #else
@@ -1626,6 +1733,7 @@ i915_gem_object_unpin_fence(struct drm_i
 {
 	if (obj->fence_reg != I915_FENCE_REG_NONE) {
 		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+		WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count <= 0);
 		dev_priv->fence_regs[obj->fence_reg].pin_count--;
 	}
 }
@@ -1658,9 +1766,12 @@ void i915_gem_init_swizzling(struct drm_
 void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
 int __must_check i915_gpu_idle(struct drm_device *dev);
 int __must_check i915_gem_idle(struct drm_device *dev);
-int i915_add_request(struct intel_ring_buffer *ring,
-		     struct drm_file *file,
-		     u32 *seqno);
+int __i915_add_request(struct intel_ring_buffer *ring,
+		       struct drm_file *file,
+		       struct drm_i915_gem_object *batch_obj,
+		       u32 *seqno);
+#define i915_add_request(ring, seqno) \
+	__i915_add_request(ring, NULL, NULL, seqno)
 int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
 				 uint32_t seqno);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
@@ -1705,6 +1816,21 @@ void i915_gem_context_fini(struct drm_de
 void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
 int i915_switch_context(struct intel_ring_buffer *ring,
 			struct drm_file *file, int to_id);
+void i915_gem_context_free(struct kref *ctx_ref);
+static inline void i915_gem_context_reference(struct i915_hw_context *ctx)
+{
+	kref_get(&ctx->ref);
+}
+
+static inline void i915_gem_context_unreference(struct i915_hw_context *ctx)
+{
+	kref_put(&ctx->ref, i915_gem_context_free);
+}
+
+struct i915_ctx_hang_stats * __must_check
+i915_gem_context_get_hang_stats(struct intel_ring_buffer *ring,
+				struct drm_file *file,
+				u32 id);
 int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
 				  struct drm_file *file);
 int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
@@ -1786,6 +1912,8 @@ void i915_gem_dump_object(struct drm_i91
 /* i915_debugfs.c */
 int i915_debugfs_init(struct drm_minor *minor);
 void i915_debugfs_cleanup(struct drm_minor *minor);
+__printf(2, 3)
+void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...);
 
 /* i915_suspend.c */
 extern int i915_save_state(struct drm_device *dev);
@@ -1802,7 +1930,7 @@ void i915_teardown_sysfs(struct drm_devi
 /* intel_i2c.c */
 extern int intel_setup_gmbus(struct drm_device *dev);
 extern void intel_teardown_gmbus(struct drm_device *dev);
-extern inline bool intel_gmbus_is_port_valid(unsigned port)
+static inline bool intel_gmbus_is_port_valid(unsigned port)
 {
 	return (port >= GMBUS_PORT_SSC && port <= GMBUS_PORT_DPD);
 }
@@ -1811,7 +1939,7 @@ extern struct i2c_adapter *intel_gmbus_g
 		struct drm_i915_private *dev_priv, unsigned port);
 extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
 extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
-extern inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
+static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
 {
 	return container_of(adapter, struct intel_gmbus, adapter)->force_bit;
 }
@@ -1823,14 +1951,10 @@ extern int intel_opregion_setup(struct d
 extern void intel_opregion_init(struct drm_device *dev);
 extern void intel_opregion_fini(struct drm_device *dev);
 extern void intel_opregion_asle_intr(struct drm_device *dev);
-extern void intel_opregion_gse_intr(struct drm_device *dev);
-extern void intel_opregion_enable_asle(struct drm_device *dev);
 #else
 static inline void intel_opregion_init(struct drm_device *dev) { return; }
 static inline void intel_opregion_fini(struct drm_device *dev) { return; }
 static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
-static inline void intel_opregion_gse_intr(struct drm_device *dev) { return; }
-static inline void intel_opregion_enable_asle(struct drm_device *dev) { return; }
 #endif
 
 /* intel_acpi.c */
@@ -1844,6 +1968,7 @@ static inline void intel_unregister_dsm_
 
 /* modesetting */
 extern void intel_modeset_init_hw(struct drm_device *dev);
+extern void intel_modeset_suspend_hw(struct drm_device *dev);
 extern void intel_modeset_init(struct drm_device *dev);
 extern void intel_modeset_gem_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
@@ -1856,6 +1981,9 @@ extern void intel_disable_fbc(struct drm
 extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
 extern void intel_init_pch_refclk(struct drm_device *dev);
 extern void gen6_set_rps(struct drm_device *dev, u8 val);
+extern void valleyview_set_rps(struct drm_device *dev, u8 val);
+extern int valleyview_rps_max_freq(struct drm_i915_private *dev_priv);
+extern int valleyview_rps_min_freq(struct drm_i915_private *dev_priv);
 extern void intel_detect_pch(struct drm_device *dev);
 extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
 extern int intel_enable_rc6(const struct drm_device *dev);
@@ -1867,10 +1995,11 @@ int i915_reg_read_ioctl(struct drm_devic
 /* overlay */
 #ifdef CONFIG_DEBUG_FS
 extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
-extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error);
+extern void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e,
+					    struct intel_overlay_error_state *error);
 
 extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev);
-extern void intel_display_print_error_state(struct seq_file *m,
+extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
 					    struct drm_device *dev,
 					    struct intel_display_error_state *error);
 #endif
@@ -1885,8 +2014,20 @@ int __gen6_gt_wait_for_fifo(struct drm_i
 
 int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val);
 int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val);
-int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val);
-int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val);
+
+/* intel_sideband.c */
+u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr);
+void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val);
+u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
+u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg);
+void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val);
+u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
+		   enum intel_sbi_destination destination);
+void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
+		     enum intel_sbi_destination destination);
+
+int vlv_gpu_freq(int ddr_freq, int val);
+int vlv_freq_opcode(int ddr_freq, int val);
 
 #define __i915_read(x, y) \
 	u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem.c	2013-08-25 20:43:22.000000000 -0400
@@ -176,7 +176,7 @@ i915_gem_get_aperture_ioctl(struct drm_d
 
 	pinned = 0;
 	mutex_lock(&dev->struct_mutex);
-	list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list)
 		if (obj->pin_count)
 			pinned += obj->gtt_space->size;
 	mutex_unlock(&dev->struct_mutex);
@@ -956,7 +956,7 @@ i915_gem_check_olr(struct intel_ring_buf
 
 	ret = 0;
 	if (seqno == ring->outstanding_lazy_request)
-		ret = i915_add_request(ring, NULL, NULL);
+		ret = i915_add_request(ring, NULL);
 
 	return ret;
 }
@@ -1087,6 +1087,25 @@ i915_wait_seqno(struct intel_ring_buffer
 			    interruptible, NULL);
 }
 
+static int
+i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj,
+				     struct intel_ring_buffer *ring)
+{
+	i915_gem_retire_requests_ring(ring);
+
+	/* Manually manage the write flush as we may have not yet
+	 * retired the buffer.
+	 *
+	 * Note that the last_write_seqno is always the earlier of
+	 * the two (read/write) seqno, so if we haved successfully waited,
+	 * we know we have passed the last write.
+	 */
+	obj->last_write_seqno = 0;
+	obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
+
+	return 0;
+}
+
 /**
  * Ensures that all rendering to the object has completed and the object is
  * safe to unbind from the GTT or access from the CPU.
@@ -1107,18 +1126,7 @@ i915_gem_object_wait_rendering(struct dr
 	if (ret)
 		return ret;
 
-	i915_gem_retire_requests_ring(ring);
-
-	/* Manually manage the write flush as we may have not yet
-	 * retired the buffer.
-	 */
-	if (obj->last_write_seqno &&
-	    i915_seqno_passed(seqno, obj->last_write_seqno)) {
-		obj->last_write_seqno = 0;
-		obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
-	}
-
-	return 0;
+	return i915_gem_object_wait_rendering__tail(obj, ring);
 }
 
 /* A nonblocking variant of the above wait. This is a highly dangerous routine
@@ -1154,19 +1162,10 @@ i915_gem_object_wait_rendering__nonblock
 	mutex_unlock(&dev->struct_mutex);
 	ret = __wait_seqno(ring, seqno, reset_counter, true, NULL);
 	mutex_lock(&dev->struct_mutex);
+	if (ret)
+		return ret;
 
-	i915_gem_retire_requests_ring(ring);
-
-	/* Manually manage the write flush as we may have not yet
-	 * retired the buffer.
-	 */
-	if (obj->last_write_seqno &&
-	    i915_seqno_passed(seqno, obj->last_write_seqno)) {
-		obj->last_write_seqno = 0;
-		obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
-	}
-
-	return ret;
+	return i915_gem_object_wait_rendering__tail(obj, ring);
 }
 
 /**
@@ -1676,7 +1675,7 @@ i915_gem_object_put_pages(struct drm_i91
 	/* ->put_pages might need to allocate memory for the bit17 swizzle
 	 * array, hence protect them from being reaped by removing them from gtt
 	 * lists early. */
-	list_del(&obj->gtt_list);
+	list_del(&obj->global_list);
 
 	ops->put_pages(obj);
 	obj->pages = NULL;
@@ -1696,7 +1695,7 @@ __i915_gem_shrink(struct drm_i915_privat
 
 	list_for_each_entry_safe(obj, next,
 				 &dev_priv->mm.unbound_list,
-				 gtt_list) {
+				 global_list) {
 		if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
 		    i915_gem_object_put_pages(obj) == 0) {
 			count += obj->base.size >> PAGE_SHIFT;
@@ -1733,7 +1732,8 @@ i915_gem_shrink_all(struct drm_i915_priv
 
 	i915_gem_evict_everything(dev_priv->dev);
 
-	list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, gtt_list)
+	list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list,
+				 global_list)
 		i915_gem_object_put_pages(obj);
 }
 
@@ -1867,7 +1867,7 @@ i915_gem_object_get_pages(struct drm_i91
 	if (ret)
 		return ret;
 
-	list_add_tail(&obj->gtt_list, &dev_priv->mm.unbound_list);
+	list_add_tail(&obj->global_list, &dev_priv->mm.unbound_list);
 	return 0;
 }
 
@@ -1880,6 +1880,10 @@ i915_gem_object_move_to_active(struct dr
 	u32 seqno = intel_ring_get_seqno(ring);
 
 	BUG_ON(ring == NULL);
+	if (obj->ring != ring && obj->last_write_seqno) {
+		/* Keep the seqno relative to the current ring */
+		obj->last_write_seqno = seqno;
+	}
 	obj->ring = ring;
 
 	/* Add a reference if we're newly entering the active list. */
@@ -2005,17 +2009,18 @@ i915_gem_get_seqno(struct drm_device *de
 	return 0;
 }
 
-int
-i915_add_request(struct intel_ring_buffer *ring,
-		 struct drm_file *file,
-		 u32 *out_seqno)
+int __i915_add_request(struct intel_ring_buffer *ring,
+		       struct drm_file *file,
+		       struct drm_i915_gem_object *obj,
+		       u32 *out_seqno)
 {
 	drm_i915_private_t *dev_priv = ring->dev->dev_private;
 	struct drm_i915_gem_request *request;
-	u32 request_ring_position;
+	u32 request_ring_position, request_start;
 	int was_empty;
 	int ret;
 
+	request_start = intel_ring_get_tail(ring);
 	/*
 	 * Emit any outstanding flushes - execbuf can fail to emit the flush
 	 * after having emitted the batchbuffer command. Hence we need to fix
@@ -2047,7 +2052,21 @@ i915_add_request(struct intel_ring_buffe
 
 	request->seqno = intel_ring_get_seqno(ring);
 	request->ring = ring;
+	request->head = request_start;
 	request->tail = request_ring_position;
+	request->ctx = ring->last_context;
+	request->batch_obj = obj;
+
+	/* Whilst this request exists, batch_obj will be on the
+	 * active_list, and so will hold the active reference. Only when this
+	 * request is retired will the the batch_obj be moved onto the
+	 * inactive_list and lose its active reference. Hence we do not need
+	 * to explicitly hold another reference here.
+	 */
+
+	if (request->ctx)
+		i915_gem_context_reference(request->ctx);
+
 	request->emitted_jiffies = jiffies;
 	was_empty = list_empty(&ring->request_list);
 	list_add_tail(&request->list, &ring->request_list);
@@ -2100,9 +2119,114 @@ i915_gem_request_remove_from_client(stru
 	spin_unlock(&file_priv->mm.lock);
 }
 
+static bool i915_head_inside_object(u32 acthd, struct drm_i915_gem_object *obj)
+{
+	if (acthd >= obj->gtt_offset &&
+	    acthd < obj->gtt_offset + obj->base.size)
+		return true;
+
+	return false;
+}
+
+static bool i915_head_inside_request(const u32 acthd_unmasked,
+				     const u32 request_start,
+				     const u32 request_end)
+{
+	const u32 acthd = acthd_unmasked & HEAD_ADDR;
+
+	if (request_start < request_end) {
+		if (acthd >= request_start && acthd < request_end)
+			return true;
+	} else if (request_start > request_end) {
+		if (acthd >= request_start || acthd < request_end)
+			return true;
+	}
+
+	return false;
+}
+
+static bool i915_request_guilty(struct drm_i915_gem_request *request,
+				const u32 acthd, bool *inside)
+{
+	/* There is a possibility that unmasked head address
+	 * pointing inside the ring, matches the batch_obj address range.
+	 * However this is extremely unlikely.
+	 */
+
+	if (request->batch_obj) {
+		if (i915_head_inside_object(acthd, request->batch_obj)) {
+			*inside = true;
+			return true;
+		}
+	}
+
+	if (i915_head_inside_request(acthd, request->head, request->tail)) {
+		*inside = false;
+		return true;
+	}
+
+	return false;
+}
+
+static void i915_set_reset_status(struct intel_ring_buffer *ring,
+				  struct drm_i915_gem_request *request,
+				  u32 acthd)
+{
+	struct i915_ctx_hang_stats *hs = NULL;
+	bool inside, guilty;
+
+	/* Innocent until proven guilty */
+	guilty = false;
+
+	if (ring->hangcheck.action != wait &&
+	    i915_request_guilty(request, acthd, &inside)) {
+		DRM_ERROR("%s hung %s bo (0x%x ctx %d) at 0x%x\n",
+			  ring->name,
+			  inside ? "inside" : "flushing",
+			  request->batch_obj ?
+			  request->batch_obj->gtt_offset : 0,
+			  request->ctx ? request->ctx->id : 0,
+			  acthd);
+
+		guilty = true;
+	}
+
+	/* If contexts are disabled or this is the default context, use
+	 * file_priv->reset_state
+	 */
+	if (request->ctx && request->ctx->id != DEFAULT_CONTEXT_ID)
+		hs = &request->ctx->hang_stats;
+	else if (request->file_priv)
+		hs = &request->file_priv->hang_stats;
+
+	if (hs) {
+		if (guilty)
+			hs->batch_active++;
+		else
+			hs->batch_pending++;
+	}
+}
+
+static void i915_gem_free_request(struct drm_i915_gem_request *request)
+{
+	list_del(&request->list);
+	i915_gem_request_remove_from_client(request);
+
+	if (request->ctx)
+		i915_gem_context_unreference(request->ctx);
+
+	kfree(request);
+}
+
 static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
 				      struct intel_ring_buffer *ring)
 {
+	u32 completed_seqno;
+	u32 acthd;
+
+	acthd = intel_ring_get_active_head(ring);
+	completed_seqno = ring->get_seqno(ring, false);
+
 	while (!list_empty(&ring->request_list)) {
 		struct drm_i915_gem_request *request;
 
@@ -2110,9 +2234,10 @@ static void i915_gem_reset_ring_lists(st
 					   struct drm_i915_gem_request,
 					   list);
 
-		list_del(&request->list);
-		i915_gem_request_remove_from_client(request);
-		kfree(request);
+		if (request->seqno > completed_seqno)
+			i915_set_reset_status(ring, request, acthd);
+
+		i915_gem_free_request(request);
 	}
 
 	while (!list_empty(&ring->active_list)) {
@@ -2133,7 +2258,17 @@ void i915_gem_restore_fences(struct drm_
 
 	for (i = 0; i < dev_priv->num_fence_regs; i++) {
 		struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
-		i915_gem_write_fence(dev, i, reg->obj);
+
+		/*
+		 * Commit delayed tiling changes if we have an object still
+		 * attached to the fence, otherwise just clear the fence.
+		 */
+		if (reg->obj) {
+			i915_gem_object_update_fence(reg->obj, reg,
+						     reg->obj->tiling_mode);
+		} else {
+			i915_gem_write_fence(dev, i, NULL);
+		}
 	}
 }
 
@@ -2193,9 +2328,7 @@ i915_gem_retire_requests_ring(struct int
 		 */
 		ring->last_retired_head = request->tail;
 
-		list_del(&request->list);
-		i915_gem_request_remove_from_client(request);
-		kfree(request);
+		i915_gem_free_request(request);
 	}
 
 	/* Move any buffers on the active list that are no longer referenced
@@ -2262,7 +2395,7 @@ i915_gem_retire_work_handler(struct work
 	idle = true;
 	for_each_ring(ring, dev_priv, i) {
 		if (ring->gpu_caches_dirty)
-			i915_add_request(ring, NULL, NULL);
+			i915_add_request(ring, NULL);
 
 		idle &= list_empty(&ring->request_list);
 	}
@@ -2494,9 +2627,10 @@ i915_gem_object_unbind(struct drm_i915_g
 		obj->has_aliasing_ppgtt_mapping = 0;
 	}
 	i915_gem_gtt_finish_object(obj);
+	i915_gem_object_unpin_pages(obj);
 
 	list_del(&obj->mm_list);
-	list_move_tail(&obj->gtt_list, &dev_priv->mm.unbound_list);
+	list_move_tail(&obj->global_list, &dev_priv->mm.unbound_list);
 	/* Avoid an unnecessary call to unbind on rebind. */
 	obj->map_and_fenceable = true;
 
@@ -2533,7 +2667,6 @@ static void i965_write_fence_reg(struct
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	int fence_reg;
 	int fence_pitch_shift;
-	uint64_t val;
 
 	if (INTEL_INFO(dev)->gen >= 6) {
 		fence_reg = FENCE_REG_SANDYBRIDGE_0;
@@ -2543,8 +2676,23 @@ static void i965_write_fence_reg(struct
 		fence_pitch_shift = I965_FENCE_PITCH_SHIFT;
 	}
 
+	fence_reg += reg * 8;
+
+	/* To w/a incoherency with non-atomic 64-bit register updates,
+	 * we split the 64-bit update into two 32-bit writes. In order
+	 * for a partial fence not to be evaluated between writes, we
+	 * precede the update with write to turn off the fence register,
+	 * and only enable the fence as the last step.
+	 *
+	 * For extra levels of paranoia, we make sure each step lands
+	 * before applying the next step.
+	 */
+	I915_WRITE(fence_reg, 0);
+	POSTING_READ(fence_reg);
+
 	if (obj) {
 		u32 size = obj->gtt_space->size;
+		uint64_t val;
 
 		val = (uint64_t)((obj->gtt_offset + size - 4096) &
 				 0xfffff000) << 32;
@@ -2553,12 +2701,16 @@ static void i965_write_fence_reg(struct
 		if (obj->tiling_mode == I915_TILING_Y)
 			val |= 1 << I965_FENCE_TILING_Y_SHIFT;
 		val |= I965_FENCE_REG_VALID;
-	} else
-		val = 0;
 
-	fence_reg += reg * 8;
-	I915_WRITE64(fence_reg, val);
-	POSTING_READ(fence_reg);
+		I915_WRITE(fence_reg + 4, val >> 32);
+		POSTING_READ(fence_reg + 4);
+
+		I915_WRITE(fence_reg + 0, val);
+		POSTING_READ(fence_reg);
+	} else {
+		I915_WRITE(fence_reg + 4, 0);
+		POSTING_READ(fence_reg + 4);
+	}
 }
 
 static void i915_write_fence_reg(struct drm_device *dev, int reg,
@@ -2653,6 +2805,10 @@ static void i915_gem_write_fence(struct
 	if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj))
 		mb();
 
+	WARN(obj && (!obj->stride || !obj->tiling_mode),
+	     "bogus fence setup with stride: 0x%x, tiling mode: %i\n",
+	     obj->stride, obj->tiling_mode);
+
 	switch (INTEL_INFO(dev)->gen) {
 	case 7:
 	case 6:
@@ -2676,35 +2832,17 @@ static inline int fence_number(struct dr
 	return fence - dev_priv->fence_regs;
 }
 
-static void i915_gem_write_fence__ipi(void *data)
-{
-	wbinvd();
-}
-
 static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
 					 struct drm_i915_fence_reg *fence,
 					 bool enable)
 {
-	struct drm_device *dev = obj->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	int fence_reg = fence_number(dev_priv, fence);
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	int reg = fence_number(dev_priv, fence);
 
-	/* In order to fully serialize access to the fenced region and
-	 * the update to the fence register we need to take extreme
-	 * measures on SNB+. In theory, the write to the fence register
-	 * flushes all memory transactions before, and coupled with the
-	 * mb() placed around the register write we serialise all memory
-	 * operations with respect to the changes in the tiler. Yet, on
-	 * SNB+ we need to take a step further and emit an explicit wbinvd()
-	 * on each processor in order to manually flush all memory
-	 * transactions before updating the fence register.
-	 */
-	if (HAS_LLC(obj->base.dev))
-		on_each_cpu(i915_gem_write_fence__ipi, NULL, 1);
-	i915_gem_write_fence(dev, fence_reg, enable ? obj : NULL);
+	i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);
 
 	if (enable) {
-		obj->fence_reg = fence_reg;
+		obj->fence_reg = reg;
 		fence->obj = obj;
 		list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
 	} else {
@@ -2712,6 +2850,7 @@ static void i915_gem_object_update_fence
 		fence->obj = NULL;
 		list_del_init(&fence->lru_list);
 	}
+	obj->fence_dirty = false;
 }
 
 static int
@@ -2841,7 +2980,6 @@ i915_gem_object_get_fence(struct drm_i91
 		return 0;
 
 	i915_gem_object_update_fence(obj, reg, enable);
-	obj->fence_dirty = false;
 
 	return 0;
 }
@@ -2883,7 +3021,7 @@ static void i915_gem_verify_gtt(struct d
 	struct drm_i915_gem_object *obj;
 	int err = 0;
 
-	list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
+	list_for_each_entry(obj, &dev_priv->mm.gtt_list, global_list) {
 		if (obj->gtt_space == NULL) {
 			printk(KERN_ERR "object found on GTT list with no space reserved\n");
 			err++;
@@ -2930,6 +3068,8 @@ i915_gem_object_bind_to_gtt(struct drm_i
 	struct drm_mm_node *node;
 	u32 size, fence_size, fence_alignment, unfenced_alignment;
 	bool mappable, fenceable;
+	size_t gtt_max = map_and_fenceable ?
+		dev_priv->gtt.mappable_end : dev_priv->gtt.total;
 	int ret;
 
 	fence_size = i915_gem_get_gtt_size(dev,
@@ -2956,9 +3096,11 @@ i915_gem_object_bind_to_gtt(struct drm_i
 	/* If the object is bigger than the entire aperture, reject it early
 	 * before evicting everything in a vain attempt to find space.
 	 */
-	if (obj->base.size >
-	    (map_and_fenceable ? dev_priv->gtt.mappable_end : dev_priv->gtt.total)) {
-		DRM_ERROR("Attempting to bind an object larger than the aperture\n");
+	if (obj->base.size > gtt_max) {
+		DRM_ERROR("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%zu\n",
+			  obj->base.size,
+			  map_and_fenceable ? "mappable" : "total",
+			  gtt_max);
 		return -E2BIG;
 	}
 
@@ -2974,14 +3116,10 @@ i915_gem_object_bind_to_gtt(struct drm_i
 		return -ENOMEM;
 	}
 
- search_free:
-	if (map_and_fenceable)
-		ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node,
-							  size, alignment, obj->cache_level,
-							  0, dev_priv->gtt.mappable_end);
-	else
-		ret = drm_mm_insert_node_generic(&dev_priv->mm.gtt_space, node,
-						 size, alignment, obj->cache_level);
+search_free:
+	ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node,
+						  size, alignment,
+						  obj->cache_level, 0, gtt_max);
 	if (ret) {
 		ret = i915_gem_evict_something(dev, size, alignment,
 					       obj->cache_level,
@@ -3007,7 +3145,7 @@ i915_gem_object_bind_to_gtt(struct drm_i
 		return ret;
 	}
 
-	list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list);
+	list_move_tail(&obj->global_list, &dev_priv->mm.bound_list);
 	list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
 
 	obj->gtt_space = node;
@@ -3022,7 +3160,6 @@ i915_gem_object_bind_to_gtt(struct drm_i
 
 	obj->map_and_fenceable = mappable && fenceable;
 
-	i915_gem_object_unpin_pages(obj);
 	trace_i915_gem_object_bind(obj, map_and_fenceable);
 	i915_gem_verify_gtt(dev);
 	return 0;
@@ -3722,7 +3859,7 @@ void i915_gem_object_init(struct drm_i91
 			  const struct drm_i915_gem_object_ops *ops)
 {
 	INIT_LIST_HEAD(&obj->mm_list);
-	INIT_LIST_HEAD(&obj->gtt_list);
+	INIT_LIST_HEAD(&obj->global_list);
 	INIT_LIST_HEAD(&obj->ring_list);
 	INIT_LIST_HEAD(&obj->exec_list);
 
@@ -3822,7 +3959,13 @@ void i915_gem_free_object(struct drm_gem
 		dev_priv->mm.interruptible = was_interruptible;
 	}
 
-	obj->pages_pin_count = 0;
+	/* Stolen objects don't hold a ref, but do hold pin count. Fix that up
+	 * before progressing. */
+	if (obj->stolen)
+		i915_gem_object_unpin_pages(obj);
+
+	if (WARN_ON(obj->pages_pin_count))
+		obj->pages_pin_count = 0;
 	i915_gem_object_put_pages(obj);
 	i915_gem_object_free_mmap_offset(obj);
 	i915_gem_object_release_stolen(obj);
@@ -3973,12 +4116,21 @@ static int i915_gem_init_rings(struct dr
 			goto cleanup_bsd_ring;
 	}
 
+	if (HAS_VEBOX(dev)) {
+		ret = intel_init_vebox_ring_buffer(dev);
+		if (ret)
+			goto cleanup_blt_ring;
+	}
+
+
 	ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000));
 	if (ret)
-		goto cleanup_blt_ring;
+		goto cleanup_vebox_ring;
 
 	return 0;
 
+cleanup_vebox_ring:
+	intel_cleanup_ring_buffer(&dev_priv->ring[VECS]);
 cleanup_blt_ring:
 	intel_cleanup_ring_buffer(&dev_priv->ring[BCS]);
 cleanup_bsd_ring:
@@ -4453,10 +4605,10 @@ i915_gem_inactive_shrink(struct shrinker
 	}
 
 	cnt = 0;
-	list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list)
+	list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list)
 		if (obj->pages_pin_count == 0)
 			cnt += obj->base.size >> PAGE_SHIFT;
-	list_for_each_entry(obj, &dev_priv->mm.inactive_list, gtt_list)
+	list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list)
 		if (obj->pin_count == 0 && obj->pages_pin_count == 0)
 			cnt += obj->base.size >> PAGE_SHIFT;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_context.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_context.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_context.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_context.c	2013-08-25 20:43:22.000000000 -0400
@@ -113,7 +113,7 @@ static int get_context_size(struct drm_d
 	case 7:
 		reg = I915_READ(GEN7_CXT_SIZE);
 		if (IS_HASWELL(dev))
-			ret = HSW_CXT_TOTAL_SIZE(reg) * 64;
+			ret = HSW_CXT_TOTAL_SIZE;
 		else
 			ret = GEN7_CXT_TOTAL_SIZE(reg) * 64;
 		break;
@@ -124,10 +124,10 @@ static int get_context_size(struct drm_d
 	return ret;
 }
 
-static void do_destroy(struct i915_hw_context *ctx)
+void i915_gem_context_free(struct kref *ctx_ref)
 {
-	if (ctx->file_priv)
-		idr_remove(&ctx->file_priv->context_idr, ctx->id);
+	struct i915_hw_context *ctx = container_of(ctx_ref,
+						   typeof(*ctx), ref);
 
 	drm_gem_object_unreference(&ctx->obj->base);
 	kfree(ctx);
@@ -145,6 +145,7 @@ create_hw_context(struct drm_device *dev
 	if (ctx == NULL)
 		return ERR_PTR(-ENOMEM);
 
+	kref_init(&ctx->ref);
 	ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
 	if (ctx->obj == NULL) {
 		kfree(ctx);
@@ -155,7 +156,8 @@ create_hw_context(struct drm_device *dev
 	if (INTEL_INFO(dev)->gen >= 7) {
 		ret = i915_gem_object_set_cache_level(ctx->obj,
 						      I915_CACHE_LLC_MLC);
-		if (ret)
+		/* Failure shouldn't ever happen this early */
+		if (WARN_ON(ret))
 			goto err_out;
 	}
 
@@ -169,18 +171,18 @@ create_hw_context(struct drm_device *dev
 	if (file_priv == NULL)
 		return ctx;
 
-	ctx->file_priv = file_priv;
-
 	ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0,
 			GFP_KERNEL);
 	if (ret < 0)
 		goto err_out;
+
+	ctx->file_priv = file_priv;
 	ctx->id = ret;
 
 	return ctx;
 
 err_out:
-	do_destroy(ctx);
+	i915_gem_context_unreference(ctx);
 	return ERR_PTR(ret);
 }
 
@@ -213,12 +215,16 @@ static int create_default_context(struct
 	 */
 	dev_priv->ring[RCS].default_context = ctx;
 	ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false, false);
-	if (ret)
+	if (ret) {
+		DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
 		goto err_destroy;
+	}
 
 	ret = do_switch(ctx);
-	if (ret)
+	if (ret) {
+		DRM_DEBUG_DRIVER("Switch failed %d\n", ret);
 		goto err_unpin;
+	}
 
 	DRM_DEBUG_DRIVER("Default HW context loaded\n");
 	return 0;
@@ -226,7 +232,7 @@ static int create_default_context(struct
 err_unpin:
 	i915_gem_object_unpin(ctx->obj);
 err_destroy:
-	do_destroy(ctx);
+	i915_gem_context_unreference(ctx);
 	return ret;
 }
 
@@ -236,6 +242,7 @@ void i915_gem_context_init(struct drm_de
 
 	if (!HAS_HW_CONTEXTS(dev)) {
 		dev_priv->hw_contexts_disabled = true;
+		DRM_DEBUG_DRIVER("Disabling HW Contexts; old hardware\n");
 		return;
 	}
 
@@ -248,11 +255,13 @@ void i915_gem_context_init(struct drm_de
 
 	if (dev_priv->hw_context_size > (1<<20)) {
 		dev_priv->hw_contexts_disabled = true;
+		DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n");
 		return;
 	}
 
 	if (create_default_context(dev_priv)) {
 		dev_priv->hw_contexts_disabled = true;
+		DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed\n");
 		return;
 	}
 
@@ -262,6 +271,7 @@ void i915_gem_context_init(struct drm_de
 void i915_gem_context_fini(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context;
 
 	if (dev_priv->hw_contexts_disabled)
 		return;
@@ -271,9 +281,16 @@ void i915_gem_context_fini(struct drm_de
 	 * other code, leading to spurious errors. */
 	intel_gpu_reset(dev);
 
-	i915_gem_object_unpin(dev_priv->ring[RCS].default_context->obj);
+	i915_gem_object_unpin(dctx->obj);
 
-	do_destroy(dev_priv->ring[RCS].default_context);
+	/* When default context is created and switched to, base object refcount
+	 * will be 2 (+1 from object creation and +1 from do_switch()).
+	 * i915_gem_context_fini() will be called after gpu_idle() has switched
+	 * to default context. So we need to unreference the base object once
+	 * to offset the do_switch part, so that i915_gem_context_unreference()
+	 * can then free the base object correctly. */
+	drm_gem_object_unreference(&dctx->obj->base);
+	i915_gem_context_unreference(dctx);
 }
 
 static int context_idr_cleanup(int id, void *p, void *data)
@@ -282,11 +299,38 @@ static int context_idr_cleanup(int id, v
 
 	BUG_ON(id == DEFAULT_CONTEXT_ID);
 
-	do_destroy(ctx);
-
+	i915_gem_context_unreference(ctx);
 	return 0;
 }
 
+struct i915_ctx_hang_stats *
+i915_gem_context_get_hang_stats(struct intel_ring_buffer *ring,
+				struct drm_file *file,
+				u32 id)
+{
+	struct drm_i915_private *dev_priv = ring->dev->dev_private;
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+	struct i915_hw_context *to;
+
+	if (dev_priv->hw_contexts_disabled)
+		return ERR_PTR(-ENOENT);
+
+	if (ring->id != RCS)
+		return ERR_PTR(-EINVAL);
+
+	if (file == NULL)
+		return ERR_PTR(-EINVAL);
+
+	if (id == DEFAULT_CONTEXT_ID)
+		return &file_priv->hang_stats;
+
+	to = i915_gem_context_get(file->driver_priv, id);
+	if (to == NULL)
+		return ERR_PTR(-ENOENT);
+
+	return &to->hang_stats;
+}
+
 void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
 {
 	struct drm_i915_file_private *file_priv = file->driver_priv;
@@ -325,6 +369,7 @@ mi_set_context(struct intel_ring_buffer
 	if (ret)
 		return ret;
 
+	/* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw */
 	if (IS_GEN7(ring->dev))
 		intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE);
 	else
@@ -353,13 +398,13 @@ mi_set_context(struct intel_ring_buffer
 static int do_switch(struct i915_hw_context *to)
 {
 	struct intel_ring_buffer *ring = to->ring;
-	struct drm_i915_gem_object *from_obj = ring->last_context_obj;
+	struct i915_hw_context *from = ring->last_context;
 	u32 hw_flags = 0;
 	int ret;
 
-	BUG_ON(from_obj != NULL && from_obj->pin_count == 0);
+	BUG_ON(from != NULL && from->obj != NULL && from->obj->pin_count == 0);
 
-	if (from_obj == to->obj)
+	if (from == to)
 		return 0;
 
 	ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false, false);
@@ -382,7 +427,7 @@ static int do_switch(struct i915_hw_cont
 
 	if (!to->is_initialized || is_default_context(to))
 		hw_flags |= MI_RESTORE_INHIBIT;
-	else if (WARN_ON_ONCE(from_obj == to->obj)) /* not yet expected */
+	else if (WARN_ON_ONCE(from == to)) /* not yet expected */
 		hw_flags |= MI_FORCE_RESTORE;
 
 	ret = mi_set_context(ring, to, hw_flags);
@@ -397,9 +442,9 @@ static int do_switch(struct i915_hw_cont
 	 * is a bit suboptimal because the retiring can occur simply after the
 	 * MI_SET_CONTEXT instead of when the next seqno has completed.
 	 */
-	if (from_obj != NULL) {
-		from_obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
-		i915_gem_object_move_to_active(from_obj, ring);
+	if (from != NULL) {
+		from->obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+		i915_gem_object_move_to_active(from->obj, ring);
 		/* As long as MI_SET_CONTEXT is serializing, ie. it flushes the
 		 * whole damn pipeline, we don't need to explicitly mark the
 		 * object dirty. The only exception is that the context must be
@@ -407,15 +452,26 @@ static int do_switch(struct i915_hw_cont
 		 * able to defer doing this until we know the object would be
 		 * swapped, but there is no way to do that yet.
 		 */
-		from_obj->dirty = 1;
-		BUG_ON(from_obj->ring != ring);
-		i915_gem_object_unpin(from_obj);
+		from->obj->dirty = 1;
+		BUG_ON(from->obj->ring != ring);
 
-		drm_gem_object_unreference(&from_obj->base);
+		ret = i915_add_request(ring, NULL);
+		if (ret) {
+			/* Too late, we've already scheduled a context switch.
+			 * Try to undo the change so that the hw state is
+			 * consistent with out tracking. In case of emergency,
+			 * scream.
+			 */
+			WARN_ON(mi_set_context(ring, from, MI_RESTORE_INHIBIT));
+			return ret;
+		}
+
+		i915_gem_object_unpin(from->obj);
+		i915_gem_context_unreference(from);
 	}
 
-	drm_gem_object_reference(&to->obj->base);
-	ring->last_context_obj = to->obj;
+	i915_gem_context_reference(to);
+	ring->last_context = to;
 	to->is_initialized = true;
 
 	return 0;
@@ -444,6 +500,8 @@ int i915_switch_context(struct intel_rin
 	if (dev_priv->hw_contexts_disabled)
 		return 0;
 
+	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+
 	if (ring != &dev_priv->ring[RCS])
 		return 0;
 
@@ -512,8 +570,8 @@ int i915_gem_context_destroy_ioctl(struc
 		return -ENOENT;
 	}
 
-	do_destroy(ctx);
-
+	idr_remove(&ctx->file_priv->context_idr, ctx->id);
+	i915_gem_context_unreference(ctx);
 	mutex_unlock(&dev->struct_mutex);
 
 	DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_dmabuf.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_dmabuf.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_dmabuf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_dmabuf.c	2013-08-25 20:43:22.000000000 -0400
@@ -85,9 +85,17 @@ static void i915_gem_unmap_dma_buf(struc
 				   struct sg_table *sg,
 				   enum dma_data_direction dir)
 {
+	struct drm_i915_gem_object *obj = attachment->dmabuf->priv;
+
+	mutex_lock(&obj->base.dev->struct_mutex);
+
 	dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir);
 	sg_free_table(sg);
 	kfree(sg);
+
+	i915_gem_object_unpin_pages(obj);
+
+	mutex_unlock(&obj->base.dev->struct_mutex);
 }
 
 static void i915_gem_dmabuf_release(struct dma_buf *dma_buf)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2013-08-25 20:43:22.000000000 -0400
@@ -786,7 +786,7 @@ i915_gem_execbuffer_move_to_active(struc
 			obj->dirty = 1;
 			obj->last_write_seqno = intel_ring_get_seqno(ring);
 			if (obj->pin_count) /* check for potential scanout */
-				intel_mark_fb_busy(obj);
+				intel_mark_fb_busy(obj, ring);
 		}
 
 		trace_i915_gem_object_change_domain(obj, old_read, old_write);
@@ -796,13 +796,14 @@ i915_gem_execbuffer_move_to_active(struc
 static void
 i915_gem_execbuffer_retire_commands(struct drm_device *dev,
 				    struct drm_file *file,
-				    struct intel_ring_buffer *ring)
+				    struct intel_ring_buffer *ring,
+				    struct drm_i915_gem_object *obj)
 {
 	/* Unconditionally force add_request to emit a full flush. */
 	ring->gpu_caches_dirty = true;
 
 	/* Add a breadcrumb for the completion of the batch buffer */
-	(void)i915_add_request(ring, file, NULL);
+	(void)__i915_add_request(ring, file, obj, NULL);
 }
 
 static int
@@ -885,6 +886,15 @@ i915_gem_do_execbuffer(struct drm_device
 			return -EPERM;
 		}
 		break;
+	case I915_EXEC_VEBOX:
+		ring = &dev_priv->ring[VECS];
+		if (ctx_id != 0) {
+			DRM_DEBUG("Ring %s doesn't support contexts\n",
+				  ring->name);
+			return -EPERM;
+		}
+		break;
+
 	default:
 		DRM_DEBUG("execbuf with unknown ring: %d\n",
 			  (int)(args->flags & I915_EXEC_RING_MASK));
@@ -1074,7 +1084,7 @@ i915_gem_do_execbuffer(struct drm_device
 	trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
 
 	i915_gem_execbuffer_move_to_active(&eb->objects, ring);
-	i915_gem_execbuffer_retire_commands(dev, file, ring);
+	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
 
 err:
 	eb_destroy(eb);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_gtt.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_gtt.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_gtt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_gtt.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,8 +28,6 @@
 #include "i915_trace.h"
 #include "intel_drv.h"
 
-typedef uint32_t gen6_gtt_pte_t;
-
 /* PPGTT stuff */
 #define GEN6_GTT_ADDR_ENCODE(addr)	((addr) | (((addr) >> 28) & 0xff0))
 
@@ -44,29 +42,22 @@ typedef uint32_t gen6_gtt_pte_t;
 #define GEN6_PTE_CACHE_LLC_MLC		(3 << 1)
 #define GEN6_PTE_ADDR_ENCODE(addr)	GEN6_GTT_ADDR_ENCODE(addr)
 
-static inline gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev,
-					     dma_addr_t addr,
-					     enum i915_cache_level level)
+static gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev,
+				      dma_addr_t addr,
+				      enum i915_cache_level level)
 {
 	gen6_gtt_pte_t pte = GEN6_PTE_VALID;
 	pte |= GEN6_PTE_ADDR_ENCODE(addr);
 
 	switch (level) {
 	case I915_CACHE_LLC_MLC:
-		/* Haswell doesn't set L3 this way */
-		if (IS_HASWELL(dev))
-			pte |= GEN6_PTE_CACHE_LLC;
-		else
-			pte |= GEN6_PTE_CACHE_LLC_MLC;
+		pte |= GEN6_PTE_CACHE_LLC_MLC;
 		break;
 	case I915_CACHE_LLC:
 		pte |= GEN6_PTE_CACHE_LLC;
 		break;
 	case I915_CACHE_NONE:
-		if (IS_HASWELL(dev))
-			pte |= HSW_PTE_UNCACHED;
-		else
-			pte |= GEN6_PTE_UNCACHED;
+		pte |= GEN6_PTE_UNCACHED;
 		break;
 	default:
 		BUG();
@@ -75,16 +66,48 @@ static inline gen6_gtt_pte_t gen6_pte_en
 	return pte;
 }
 
-static int gen6_ppgtt_enable(struct drm_device *dev)
+#define BYT_PTE_WRITEABLE		(1 << 1)
+#define BYT_PTE_SNOOPED_BY_CPU_CACHES	(1 << 2)
+
+static gen6_gtt_pte_t byt_pte_encode(struct drm_device *dev,
+				     dma_addr_t addr,
+				     enum i915_cache_level level)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	uint32_t pd_offset;
-	struct intel_ring_buffer *ring;
-	struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
+	gen6_gtt_pte_t pte = GEN6_PTE_VALID;
+	pte |= GEN6_PTE_ADDR_ENCODE(addr);
+
+	/* Mark the page as writeable.  Other platforms don't have a
+	 * setting for read-only/writable, so this matches that behavior.
+	 */
+	pte |= BYT_PTE_WRITEABLE;
+
+	if (level != I915_CACHE_NONE)
+		pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES;
+
+	return pte;
+}
+
+static gen6_gtt_pte_t hsw_pte_encode(struct drm_device *dev,
+				     dma_addr_t addr,
+				     enum i915_cache_level level)
+{
+	gen6_gtt_pte_t pte = GEN6_PTE_VALID;
+	pte |= GEN6_PTE_ADDR_ENCODE(addr);
+
+	if (level != I915_CACHE_NONE)
+		pte |= GEN6_PTE_CACHE_LLC;
+
+	return pte;
+}
+
+static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt)
+{
+	struct drm_i915_private *dev_priv = ppgtt->dev->dev_private;
 	gen6_gtt_pte_t __iomem *pd_addr;
 	uint32_t pd_entry;
 	int i;
 
+	WARN_ON(ppgtt->pd_offset & 0x3f);
 	pd_addr = (gen6_gtt_pte_t __iomem*)dev_priv->gtt.gsm +
 		ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
 	for (i = 0; i < ppgtt->num_pd_entries; i++) {
@@ -97,6 +120,19 @@ static int gen6_ppgtt_enable(struct drm_
 		writel(pd_entry, pd_addr + i);
 	}
 	readl(pd_addr);
+}
+
+static int gen6_ppgtt_enable(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	uint32_t pd_offset;
+	struct intel_ring_buffer *ring;
+	struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
+	int i;
+
+	BUG_ON(ppgtt->pd_offset & 0x3f);
+
+	gen6_write_pdes(ppgtt);
 
 	pd_offset = ppgtt->pd_offset;
 	pd_offset /= 64; /* in cachelines, */
@@ -154,9 +190,9 @@ static void gen6_ppgtt_clear_range(struc
 	unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
 	unsigned last_pte, i;
 
-	scratch_pte = gen6_pte_encode(ppgtt->dev,
-				      ppgtt->scratch_page_dma_addr,
-				      I915_CACHE_LLC);
+	scratch_pte = ppgtt->pte_encode(ppgtt->dev,
+					ppgtt->scratch_page_dma_addr,
+					I915_CACHE_LLC);
 
 	while (num_entries) {
 		last_pte = first_pte + num_entries;
@@ -191,8 +227,8 @@ static void gen6_ppgtt_insert_entries(st
 		dma_addr_t page_addr;
 
 		page_addr = sg_page_iter_dma_address(&sg_iter);
-		pt_vaddr[act_pte] = gen6_pte_encode(ppgtt->dev, page_addr,
-						    cache_level);
+		pt_vaddr[act_pte] = ppgtt->pte_encode(ppgtt->dev, page_addr,
+						      cache_level);
 		if (++act_pte == I915_PPGTT_PT_ENTRIES) {
 			kunmap_atomic(pt_vaddr);
 			act_pt++;
@@ -233,8 +269,15 @@ static int gen6_ppgtt_init(struct i915_h
 	/* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024
 	 * entries. For aliasing ppgtt support we just steal them at the end for
 	 * now. */
-       first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt);
+	first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt);
 
+	if (IS_HASWELL(dev)) {
+		ppgtt->pte_encode = hsw_pte_encode;
+	} else if (IS_VALLEYVIEW(dev)) {
+		ppgtt->pte_encode = byt_pte_encode;
+	} else {
+		ppgtt->pte_encode = gen6_pte_encode;
+	}
 	ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES;
 	ppgtt->enable = gen6_ppgtt_enable;
 	ppgtt->clear_range = gen6_ppgtt_clear_range;
@@ -396,7 +439,7 @@ void i915_gem_restore_gtt_mappings(struc
 	dev_priv->gtt.gtt_clear_range(dev, dev_priv->gtt.start / PAGE_SIZE,
 				      dev_priv->gtt.total / PAGE_SIZE);
 
-	list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
 		i915_gem_clflush_object(obj);
 		i915_gem_gtt_bind_object(obj, obj->cache_level);
 	}
@@ -437,7 +480,8 @@ static void gen6_ggtt_insert_entries(str
 
 	for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
 		addr = sg_page_iter_dma_address(&sg_iter);
-		iowrite32(gen6_pte_encode(dev, addr, level), &gtt_entries[i]);
+		iowrite32(dev_priv->gtt.pte_encode(dev, addr, level),
+			  &gtt_entries[i]);
 		i++;
 	}
 
@@ -449,7 +493,7 @@ static void gen6_ggtt_insert_entries(str
 	 */
 	if (i != 0)
 		WARN_ON(readl(&gtt_entries[i-1])
-			!= gen6_pte_encode(dev, addr, level));
+			!= dev_priv->gtt.pte_encode(dev, addr, level));
 
 	/* This next bit makes the above posting read even more important. We
 	 * want to flush the TLBs only after we're certain all the PTE updates
@@ -474,8 +518,9 @@ static void gen6_ggtt_clear_range(struct
 		 first_entry, num_entries, max_entries))
 		num_entries = max_entries;
 
-	scratch_pte = gen6_pte_encode(dev, dev_priv->gtt.scratch_page_dma,
-				      I915_CACHE_LLC);
+	scratch_pte = dev_priv->gtt.pte_encode(dev,
+					       dev_priv->gtt.scratch_page_dma,
+					       I915_CACHE_LLC);
 	for (i = 0; i < num_entries; i++)
 		iowrite32(scratch_pte, &gtt_base[i]);
 	readl(gtt_base);
@@ -586,7 +631,7 @@ void i915_gem_setup_global_gtt(struct dr
 		dev_priv->mm.gtt_space.color_adjust = i915_gtt_color_adjust;
 
 	/* Mark any preallocated objects as occupied */
-	list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
 		DRM_DEBUG_KMS("reserving preallocated space: %x + %zx\n",
 			      obj->gtt_offset, obj->base.size);
 
@@ -809,6 +854,13 @@ int i915_gem_gtt_init(struct drm_device
 	} else {
 		dev_priv->gtt.gtt_probe = gen6_gmch_probe;
 		dev_priv->gtt.gtt_remove = gen6_gmch_remove;
+		if (IS_HASWELL(dev)) {
+			dev_priv->gtt.pte_encode = hsw_pte_encode;
+		} else if (IS_VALLEYVIEW(dev)) {
+			dev_priv->gtt.pte_encode = byt_pte_encode;
+		} else {
+			dev_priv->gtt.pte_encode = gen6_pte_encode;
+		}
 	}
 
 	ret = dev_priv->gtt.gtt_probe(dev, &dev_priv->gtt.total,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_stolen.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_stolen.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_gem_stolen.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_gem_stolen.c	2013-08-25 20:43:22.000000000 -0400
@@ -62,7 +62,10 @@ static unsigned long i915_stolen_to_phys
 	 * its value of TOLUD.
 	 */
 	base = 0;
-	if (INTEL_INFO(dev)->gen >= 6) {
+	if (IS_VALLEYVIEW(dev)) {
+		pci_read_config_dword(dev->pdev, 0x5c, &base);
+		base &= ~((1<<20) - 1);
+	} else if (INTEL_INFO(dev)->gen >= 6) {
 		/* Read Base Data of Stolen Memory Register (BDSM) directly.
 		 * Note that there is also a MCHBAR miror at 0x1080c0 or
 		 * we could use device 2:0x5c instead.
@@ -136,6 +139,7 @@ static int i915_setup_compression(struct
 err_fb:
 	drm_mm_put_block(compressed_fb);
 err:
+	pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
 	return -ENOSPC;
 }
 
@@ -143,7 +147,7 @@ int i915_gem_stolen_setup_compression(st
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (dev_priv->mm.stolen_base == 0)
+	if (!drm_mm_initialized(&dev_priv->mm.stolen))
 		return -ENODEV;
 
 	if (size < dev_priv->cfb_size)
@@ -175,6 +179,9 @@ void i915_gem_cleanup_stolen(struct drm_
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
+	if (!drm_mm_initialized(&dev_priv->mm.stolen))
+		return;
+
 	i915_gem_stolen_cleanup_compression(dev);
 	drm_mm_takedown(&dev_priv->mm.stolen);
 }
@@ -182,6 +189,7 @@ void i915_gem_cleanup_stolen(struct drm_
 int i915_gem_init_stolen(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	int bios_reserved = 0;
 
 	dev_priv->mm.stolen_base = i915_stolen_to_physical(dev);
 	if (dev_priv->mm.stolen_base == 0)
@@ -190,8 +198,12 @@ int i915_gem_init_stolen(struct drm_devi
 	DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08lx\n",
 		      dev_priv->gtt.stolen_size, dev_priv->mm.stolen_base);
 
+	if (IS_VALLEYVIEW(dev))
+		bios_reserved = 1024*1024; /* top 1M on VLV/BYT */
+
 	/* Basic memrange allocator for stolen space */
-	drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size);
+	drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size -
+		    bios_reserved);
 
 	return 0;
 }
@@ -270,7 +282,7 @@ _i915_gem_object_create_stolen(struct dr
 		goto cleanup;
 
 	obj->has_dma_mapping = true;
-	obj->pages_pin_count = 1;
+	i915_gem_object_pin_pages(obj);
 	obj->stolen = stolen;
 
 	obj->base.write_domain = I915_GEM_DOMAIN_GTT;
@@ -291,7 +303,7 @@ i915_gem_object_create_stolen(struct drm
 	struct drm_i915_gem_object *obj;
 	struct drm_mm_node *stolen;
 
-	if (dev_priv->mm.stolen_base == 0)
+	if (!drm_mm_initialized(&dev_priv->mm.stolen))
 		return NULL;
 
 	DRM_DEBUG_KMS("creating stolen object: size=%x\n", size);
@@ -322,7 +334,7 @@ i915_gem_object_create_stolen_for_preall
 	struct drm_i915_gem_object *obj;
 	struct drm_mm_node *stolen;
 
-	if (dev_priv->mm.stolen_base == 0)
+	if (!drm_mm_initialized(&dev_priv->mm.stolen))
 		return NULL;
 
 	DRM_DEBUG_KMS("creating preallocated stolen object: stolen_offset=%x, gtt_offset=%x, size=%x\n",
@@ -330,7 +342,6 @@ i915_gem_object_create_stolen_for_preall
 
 	/* KISS and expect everything to be page-aligned */
 	BUG_ON(stolen_offset & 4095);
-	BUG_ON(gtt_offset & 4095);
 	BUG_ON(size & 4095);
 
 	if (WARN_ON(size == 0))
@@ -351,6 +362,10 @@ i915_gem_object_create_stolen_for_preall
 		return NULL;
 	}
 
+	/* Some objects just need physical mem from stolen space */
+	if (gtt_offset == -1)
+		return obj;
+
 	/* To simplify the initialisation sequence between KMS and GTT,
 	 * we allow construction of the stolen object prior to
 	 * setting up the GTT space. The actual reservation will occur
@@ -371,7 +386,7 @@ i915_gem_object_create_stolen_for_preall
 	obj->gtt_offset = gtt_offset;
 	obj->has_global_gtt_mapping = 1;
 
-	list_add_tail(&obj->gtt_list, &dev_priv->mm.bound_list);
+	list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
 	list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
 
 	return obj;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_irq.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_irq.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -70,15 +70,6 @@ static const u32 hpd_status_gen4[] = {
 	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
 };
 
-static const u32 hpd_status_i965[] = {
-	 [HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
-	 [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I965,
-	 [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I965,
-	 [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
-	 [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
-	 [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
-};
-
 static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */
 	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
 	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I915,
@@ -88,13 +79,12 @@ static const u32 hpd_status_i915[] = { /
 	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
 };
 
-static void ibx_hpd_irq_setup(struct drm_device *dev);
-static void i915_hpd_irq_setup(struct drm_device *dev);
-
 /* For display hotplug interrupt */
 static void
 ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
+	assert_spin_locked(&dev_priv->irq_lock);
+
 	if ((dev_priv->irq_mask & mask) != 0) {
 		dev_priv->irq_mask &= ~mask;
 		I915_WRITE(DEIMR, dev_priv->irq_mask);
@@ -105,6 +95,8 @@ ironlake_enable_display_irq(drm_i915_pri
 static void
 ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
 {
+	assert_spin_locked(&dev_priv->irq_lock);
+
 	if ((dev_priv->irq_mask & mask) != mask) {
 		dev_priv->irq_mask |= mask;
 		I915_WRITE(DEIMR, dev_priv->irq_mask);
@@ -112,6 +104,215 @@ ironlake_disable_display_irq(drm_i915_pr
 	}
 }
 
+static bool ivb_can_enable_err_int(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc;
+	enum pipe pipe;
+
+	assert_spin_locked(&dev_priv->irq_lock);
+
+	for_each_pipe(pipe) {
+		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+
+		if (crtc->cpu_fifo_underrun_disabled)
+			return false;
+	}
+
+	return true;
+}
+
+static bool cpt_can_enable_serr_int(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+	struct intel_crtc *crtc;
+
+	for_each_pipe(pipe) {
+		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+
+		if (crtc->pch_fifo_underrun_disabled)
+			return false;
+	}
+
+	return true;
+}
+
+static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev,
+						 enum pipe pipe, bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN :
+					  DE_PIPEB_FIFO_UNDERRUN;
+
+	if (enable)
+		ironlake_enable_display_irq(dev_priv, bit);
+	else
+		ironlake_disable_display_irq(dev_priv, bit);
+}
+
+static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev,
+						  bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (enable) {
+		if (!ivb_can_enable_err_int(dev))
+			return;
+
+		I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN_A |
+					 ERR_INT_FIFO_UNDERRUN_B |
+					 ERR_INT_FIFO_UNDERRUN_C);
+
+		ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
+	} else {
+		ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
+	}
+}
+
+static void ibx_set_fifo_underrun_reporting(struct intel_crtc *crtc,
+					    bool enable)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t bit = (crtc->pipe == PIPE_A) ? SDE_TRANSA_FIFO_UNDER :
+						SDE_TRANSB_FIFO_UNDER;
+
+	if (enable)
+		I915_WRITE(SDEIMR, I915_READ(SDEIMR) & ~bit);
+	else
+		I915_WRITE(SDEIMR, I915_READ(SDEIMR) | bit);
+
+	POSTING_READ(SDEIMR);
+}
+
+static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
+					    enum transcoder pch_transcoder,
+					    bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (enable) {
+		if (!cpt_can_enable_serr_int(dev))
+			return;
+
+		I915_WRITE(SERR_INT, SERR_INT_TRANS_A_FIFO_UNDERRUN |
+				     SERR_INT_TRANS_B_FIFO_UNDERRUN |
+				     SERR_INT_TRANS_C_FIFO_UNDERRUN);
+
+		I915_WRITE(SDEIMR, I915_READ(SDEIMR) & ~SDE_ERROR_CPT);
+	} else {
+		I915_WRITE(SDEIMR, I915_READ(SDEIMR) | SDE_ERROR_CPT);
+	}
+
+	POSTING_READ(SDEIMR);
+}
+
+/**
+ * intel_set_cpu_fifo_underrun_reporting - enable/disable FIFO underrun messages
+ * @dev: drm device
+ * @pipe: pipe
+ * @enable: true if we want to report FIFO underrun errors, false otherwise
+ *
+ * This function makes us disable or enable CPU fifo underruns for a specific
+ * pipe. Notice that on some Gens (e.g. IVB, HSW), disabling FIFO underrun
+ * reporting for one pipe may also disable all the other CPU error interruts for
+ * the other pipes, due to the fact that there's just one interrupt mask/enable
+ * bit for all the pipes.
+ *
+ * Returns the previous state of underrun reporting.
+ */
+bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
+					   enum pipe pipe, bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	unsigned long flags;
+	bool ret;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+
+	ret = !intel_crtc->cpu_fifo_underrun_disabled;
+
+	if (enable == ret)
+		goto done;
+
+	intel_crtc->cpu_fifo_underrun_disabled = !enable;
+
+	if (IS_GEN5(dev) || IS_GEN6(dev))
+		ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
+	else if (IS_GEN7(dev))
+		ivybridge_set_fifo_underrun_reporting(dev, enable);
+
+done:
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+	return ret;
+}
+
+/**
+ * intel_set_pch_fifo_underrun_reporting - enable/disable FIFO underrun messages
+ * @dev: drm device
+ * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older)
+ * @enable: true if we want to report FIFO underrun errors, false otherwise
+ *
+ * This function makes us disable or enable PCH fifo underruns for a specific
+ * PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO
+ * underrun reporting for one transcoder may also disable all the other PCH
+ * error interruts for the other transcoders, due to the fact that there's just
+ * one interrupt mask/enable bit for all the transcoders.
+ *
+ * Returns the previous state of underrun reporting.
+ */
+bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
+					   enum transcoder pch_transcoder,
+					   bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe p;
+	struct drm_crtc *crtc;
+	struct intel_crtc *intel_crtc;
+	unsigned long flags;
+	bool ret;
+
+	if (HAS_PCH_LPT(dev)) {
+		crtc = NULL;
+		for_each_pipe(p) {
+			struct drm_crtc *c = dev_priv->pipe_to_crtc_mapping[p];
+			if (intel_pipe_has_type(c, INTEL_OUTPUT_ANALOG)) {
+				crtc = c;
+				break;
+			}
+		}
+		if (!crtc) {
+			DRM_ERROR("PCH FIFO underrun, but no CRTC using the PCH found\n");
+			return false;
+		}
+	} else {
+		crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder];
+	}
+	intel_crtc = to_intel_crtc(crtc);
+
+	spin_lock_irqsave(&dev_priv->irq_lock, flags);
+
+	ret = !intel_crtc->pch_fifo_underrun_disabled;
+
+	if (enable == ret)
+		goto done;
+
+	intel_crtc->pch_fifo_underrun_disabled = !enable;
+
+	if (HAS_PCH_IBX(dev))
+		ibx_set_fifo_underrun_reporting(intel_crtc, enable);
+	else
+		cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable);
+
+done:
+	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
+	return ret;
+}
+
+
 void
 i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
 {
@@ -142,28 +343,21 @@ i915_disable_pipestat(drm_i915_private_t
 }
 
 /**
- * intel_enable_asle - enable ASLE interrupt for OpRegion
+ * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion
  */
-void intel_enable_asle(struct drm_device *dev)
+static void i915_enable_asle_pipestat(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	unsigned long irqflags;
 
-	/* FIXME: opregion/asle for VLV */
-	if (IS_VALLEYVIEW(dev))
+	if (!dev_priv->opregion.asle || !IS_MOBILE(dev))
 		return;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 
-	if (HAS_PCH_SPLIT(dev))
-		ironlake_enable_display_irq(dev_priv, DE_GSE);
-	else {
-		i915_enable_pipestat(dev_priv, 1,
-				     PIPE_LEGACY_BLC_EVENT_ENABLE);
-		if (INTEL_INFO(dev)->gen >= 4)
-			i915_enable_pipestat(dev_priv, 0,
-					     PIPE_LEGACY_BLC_EVENT_ENABLE);
-	}
+	i915_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE);
+	if (INTEL_INFO(dev)->gen >= 4)
+		i915_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE);
 
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 }
@@ -181,10 +375,16 @@ static int
 i915_pipe_enabled(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
-								      pipe);
 
-	return I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE;
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		/* Locking is horribly broken here, but whatever. */
+		struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+		return intel_crtc->active;
+	} else {
+		return I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE;
+	}
 }
 
 /* Called from drm generic code, passed a 'crtc', which
@@ -334,6 +534,21 @@ static int i915_get_vblank_timestamp(str
 						     crtc);
 }
 
+static int intel_hpd_irq_event(struct drm_device *dev, struct drm_connector *connector)
+{
+	enum drm_connector_status old_status;
+
+	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
+	old_status = connector->status;
+
+	connector->status = connector->funcs->detect(connector, false);
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
+		      connector->base.id,
+		      drm_get_connector_name(connector),
+		      old_status, connector->status);
+	return (old_status != connector->status);
+}
+
 /*
  * Handle hotplug events outside the interrupt handler proper.
  */
@@ -350,6 +565,8 @@ static void i915_hotplug_work_func(struc
 	struct drm_connector *connector;
 	unsigned long irqflags;
 	bool hpd_disabled = false;
+	bool changed = false;
+	u32 hpd_event_bits;
 
 	/* HPD irq before everything is fully set up. */
 	if (!dev_priv->enable_hotplug_processing)
@@ -359,6 +576,9 @@ static void i915_hotplug_work_func(struc
 	DRM_DEBUG_KMS("running encoder hotplug functions\n");
 
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+
+	hpd_event_bits = dev_priv->hpd_event_bits;
+	dev_priv->hpd_event_bits = 0;
 	list_for_each_entry(connector, &mode_config->connector_list, head) {
 		intel_connector = to_intel_connector(connector);
 		intel_encoder = intel_connector->encoder;
@@ -373,6 +593,10 @@ static void i915_hotplug_work_func(struc
 				| DRM_CONNECTOR_POLL_DISCONNECT;
 			hpd_disabled = true;
 		}
+		if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
+			DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n",
+				      drm_get_connector_name(connector), intel_encoder->hpd_pin);
+		}
 	}
 	 /* if there were no outputs to poll, poll was disabled,
 	  * therefore make sure it's enabled when disabling HPD on
@@ -385,14 +609,20 @@ static void i915_hotplug_work_func(struc
 
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 
-	list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head)
-		if (intel_encoder->hot_plug)
-			intel_encoder->hot_plug(intel_encoder);
-
+	list_for_each_entry(connector, &mode_config->connector_list, head) {
+		intel_connector = to_intel_connector(connector);
+		intel_encoder = intel_connector->encoder;
+		if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) {
+			if (intel_encoder->hot_plug)
+				intel_encoder->hot_plug(intel_encoder);
+			if (intel_hpd_irq_event(dev, connector))
+				changed = true;
+		}
+	}
 	mutex_unlock(&mode_config->mutex);
 
-	/* Just fire off a uevent and let userspace tell us what to do */
-	drm_helper_hpd_irq_event(dev);
+	if (changed)
+		drm_kms_helper_hotplug_event(dev);
 }
 
 static void ironlake_handle_rps_change(struct drm_device *dev)
@@ -447,7 +677,6 @@ static void notify_ring(struct drm_devic
 
 	wake_up_all(&ring->irq_queue);
 	if (i915_enable_hangcheck) {
-		dev_priv->gpu_error.hangcheck_count = 0;
 		mod_timer(&dev_priv->gpu_error.hangcheck_timer,
 			  round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES));
 	}
@@ -464,25 +693,48 @@ static void gen6_pm_rps_work(struct work
 	pm_iir = dev_priv->rps.pm_iir;
 	dev_priv->rps.pm_iir = 0;
 	pm_imr = I915_READ(GEN6_PMIMR);
-	I915_WRITE(GEN6_PMIMR, 0);
+	/* Make sure not to corrupt PMIMR state used by ringbuffer code */
+	I915_WRITE(GEN6_PMIMR, pm_imr & ~GEN6_PM_RPS_EVENTS);
 	spin_unlock_irq(&dev_priv->rps.lock);
 
-	if ((pm_iir & GEN6_PM_DEFERRED_EVENTS) == 0)
+	if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0)
 		return;
 
 	mutex_lock(&dev_priv->rps.hw_lock);
 
-	if (pm_iir & GEN6_PM_RP_UP_THRESHOLD)
+	if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
 		new_delay = dev_priv->rps.cur_delay + 1;
-	else
+
+		/*
+		 * For better performance, jump directly
+		 * to RPe if we're below it.
+		 */
+		if (IS_VALLEYVIEW(dev_priv->dev) &&
+		    dev_priv->rps.cur_delay < dev_priv->rps.rpe_delay)
+			new_delay = dev_priv->rps.rpe_delay;
+	} else
 		new_delay = dev_priv->rps.cur_delay - 1;
 
 	/* sysfs frequency interfaces may have snuck in while servicing the
 	 * interrupt
 	 */
-	if (!(new_delay > dev_priv->rps.max_delay ||
-	      new_delay < dev_priv->rps.min_delay)) {
-		gen6_set_rps(dev_priv->dev, new_delay);
+	if (new_delay >= dev_priv->rps.min_delay &&
+	    new_delay <= dev_priv->rps.max_delay) {
+		if (IS_VALLEYVIEW(dev_priv->dev))
+			valleyview_set_rps(dev_priv->dev, new_delay);
+		else
+			gen6_set_rps(dev_priv->dev, new_delay);
+	}
+
+	if (IS_VALLEYVIEW(dev_priv->dev)) {
+		/*
+		 * On VLV, when we enter RC6 we may not be at the minimum
+		 * voltage level, so arm a timer to check.  It should only
+		 * fire when there's activity or once after we've entered
+		 * RC6, and then won't be re-armed until the next RPS interrupt.
+		 */
+		mod_delayed_work(dev_priv->wq, &dev_priv->rps.vlv_work,
+				 msecs_to_jiffies(100));
 	}
 
 	mutex_unlock(&dev_priv->rps.hw_lock);
@@ -529,7 +781,7 @@ static void ivybridge_parity_work(struct
 	I915_WRITE(GEN7_MISCCPCTL, misccpctl);
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	dev_priv->gt_irq_mask &= ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT;
+	dev_priv->gt_irq_mask &= ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
 	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 
@@ -561,7 +813,7 @@ static void ivybridge_handle_parity_erro
 		return;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	dev_priv->gt_irq_mask |= GT_GEN7_L3_PARITY_ERROR_INTERRUPT;
+	dev_priv->gt_irq_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
 	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 	spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
 
@@ -573,25 +825,26 @@ static void snb_gt_irq_handler(struct dr
 			       u32 gt_iir)
 {
 
-	if (gt_iir & (GEN6_RENDER_USER_INTERRUPT |
-		      GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT))
+	if (gt_iir &
+	    (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT))
 		notify_ring(dev, &dev_priv->ring[RCS]);
-	if (gt_iir & GEN6_BSD_USER_INTERRUPT)
+	if (gt_iir & GT_BSD_USER_INTERRUPT)
 		notify_ring(dev, &dev_priv->ring[VCS]);
-	if (gt_iir & GEN6_BLITTER_USER_INTERRUPT)
+	if (gt_iir & GT_BLT_USER_INTERRUPT)
 		notify_ring(dev, &dev_priv->ring[BCS]);
 
-	if (gt_iir & (GT_GEN6_BLT_CS_ERROR_INTERRUPT |
-		      GT_GEN6_BSD_CS_ERROR_INTERRUPT |
-		      GT_RENDER_CS_ERROR_INTERRUPT)) {
+	if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT |
+		      GT_BSD_CS_ERROR_INTERRUPT |
+		      GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) {
 		DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir);
 		i915_handle_error(dev, false);
 	}
 
-	if (gt_iir & GT_GEN7_L3_PARITY_ERROR_INTERRUPT)
+	if (gt_iir & GT_RENDER_L3_PARITY_ERROR_INTERRUPT)
 		ivybridge_handle_parity_error(dev);
 }
 
+/* Legacy way of handling PM interrupts */
 static void gen6_queue_rps_work(struct drm_i915_private *dev_priv,
 				u32 pm_iir)
 {
@@ -619,23 +872,25 @@ static void gen6_queue_rps_work(struct d
 #define HPD_STORM_DETECT_PERIOD 1000
 #define HPD_STORM_THRESHOLD 5
 
-static inline bool hotplug_irq_storm_detect(struct drm_device *dev,
-					    u32 hotplug_trigger,
-					    const u32 *hpd)
+static inline void intel_hpd_irq_handler(struct drm_device *dev,
+					 u32 hotplug_trigger,
+					 const u32 *hpd)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	unsigned long irqflags;
 	int i;
-	bool ret = false;
+	bool storm_detected = false;
 
-	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	if (!hotplug_trigger)
+		return;
 
+	spin_lock(&dev_priv->irq_lock);
 	for (i = 1; i < HPD_NUM_PINS; i++) {
 
 		if (!(hpd[i] & hotplug_trigger) ||
 		    dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED)
 			continue;
 
+		dev_priv->hpd_event_bits |= (1 << i);
 		if (!time_in_range(jiffies, dev_priv->hpd_stats[i].hpd_last_jiffies,
 				   dev_priv->hpd_stats[i].hpd_last_jiffies
 				   + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD))) {
@@ -643,16 +898,20 @@ static inline bool hotplug_irq_storm_det
 			dev_priv->hpd_stats[i].hpd_cnt = 0;
 		} else if (dev_priv->hpd_stats[i].hpd_cnt > HPD_STORM_THRESHOLD) {
 			dev_priv->hpd_stats[i].hpd_mark = HPD_MARK_DISABLED;
+			dev_priv->hpd_event_bits &= ~(1 << i);
 			DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", i);
-			ret = true;
+			storm_detected = true;
 		} else {
 			dev_priv->hpd_stats[i].hpd_cnt++;
 		}
 	}
 
-	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+	if (storm_detected)
+		dev_priv->display.hpd_irq_setup(dev);
+	spin_unlock(&dev_priv->irq_lock);
 
-	return ret;
+	queue_work(dev_priv->wq,
+		   &dev_priv->hotplug_work);
 }
 
 static void gmbus_irq_handler(struct drm_device *dev)
@@ -669,6 +928,38 @@ static void dp_aux_irq_handler(struct dr
 	wake_up_all(&dev_priv->gmbus_wait_queue);
 }
 
+/* Unlike gen6_queue_rps_work() from which this function is originally derived,
+ * we must be able to deal with other PM interrupts. This is complicated because
+ * of the way in which we use the masks to defer the RPS work (which for
+ * posterity is necessary because of forcewake).
+ */
+static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv,
+			       u32 pm_iir)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->rps.lock, flags);
+	dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS;
+	if (dev_priv->rps.pm_iir) {
+		I915_WRITE(GEN6_PMIMR, dev_priv->rps.pm_iir);
+		/* never want to mask useful interrupts. (also posting read) */
+		WARN_ON(I915_READ_NOTRACE(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS);
+		/* TODO: if queue_work is slow, move it out of the spinlock */
+		queue_work(dev_priv->wq, &dev_priv->rps.work);
+	}
+	spin_unlock_irqrestore(&dev_priv->rps.lock, flags);
+
+	if (pm_iir & ~GEN6_PM_RPS_EVENTS) {
+		if (pm_iir & PM_VEBOX_USER_INTERRUPT)
+			notify_ring(dev_priv->dev, &dev_priv->ring[VECS]);
+
+		if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) {
+			DRM_ERROR("VEBOX CS error interrupt 0x%08x\n", pm_iir);
+			i915_handle_error(dev_priv->dev, false);
+		}
+	}
+}
+
 static irqreturn_t valleyview_irq_handler(int irq, void *arg)
 {
 	struct drm_device *dev = (struct drm_device *) arg;
@@ -727,12 +1018,9 @@ static irqreturn_t valleyview_irq_handle
 
 			DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
 					 hotplug_status);
-			if (hotplug_trigger) {
-				if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_status_i915))
-					i915_hpd_irq_setup(dev);
-				queue_work(dev_priv->wq,
-					   &dev_priv->hotplug_work);
-			}
+
+			intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915);
+
 			I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
 			I915_READ(PORT_HOTPLUG_STAT);
 		}
@@ -740,7 +1028,7 @@ static irqreturn_t valleyview_irq_handle
 		if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS)
 			gmbus_irq_handler(dev);
 
-		if (pm_iir & GEN6_PM_DEFERRED_EVENTS)
+		if (pm_iir & GEN6_PM_RPS_EVENTS)
 			gen6_queue_rps_work(dev_priv, pm_iir);
 
 		I915_WRITE(GTIIR, gt_iir);
@@ -758,15 +1046,14 @@ static void ibx_irq_handler(struct drm_d
 	int pipe;
 	u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK;
 
-	if (hotplug_trigger) {
-		if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_ibx))
-			ibx_hpd_irq_setup(dev);
-		queue_work(dev_priv->wq, &dev_priv->hotplug_work);
-	}
-	if (pch_iir & SDE_AUDIO_POWER_MASK)
+	intel_hpd_irq_handler(dev, hotplug_trigger, hpd_ibx);
+
+	if (pch_iir & SDE_AUDIO_POWER_MASK) {
+		int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >>
+			       SDE_AUDIO_POWER_SHIFT);
 		DRM_DEBUG_DRIVER("PCH audio power change on port %d\n",
-				 (pch_iir & SDE_AUDIO_POWER_MASK) >>
-				 SDE_AUDIO_POWER_SHIFT);
+				 port_name(port));
+	}
 
 	if (pch_iir & SDE_AUX_MASK)
 		dp_aux_irq_handler(dev);
@@ -795,10 +1082,64 @@ static void ibx_irq_handler(struct drm_d
 	if (pch_iir & (SDE_TRANSB_CRC_ERR | SDE_TRANSA_CRC_ERR))
 		DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n");
 
-	if (pch_iir & SDE_TRANSB_FIFO_UNDER)
-		DRM_DEBUG_DRIVER("PCH transcoder B underrun interrupt\n");
 	if (pch_iir & SDE_TRANSA_FIFO_UNDER)
-		DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
+		if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A,
+							  false))
+			DRM_DEBUG_DRIVER("PCH transcoder A FIFO underrun\n");
+
+	if (pch_iir & SDE_TRANSB_FIFO_UNDER)
+		if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B,
+							  false))
+			DRM_DEBUG_DRIVER("PCH transcoder B FIFO underrun\n");
+}
+
+static void ivb_err_int_handler(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 err_int = I915_READ(GEN7_ERR_INT);
+
+	if (err_int & ERR_INT_POISON)
+		DRM_ERROR("Poison interrupt\n");
+
+	if (err_int & ERR_INT_FIFO_UNDERRUN_A)
+		if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false))
+			DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n");
+
+	if (err_int & ERR_INT_FIFO_UNDERRUN_B)
+		if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false))
+			DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n");
+
+	if (err_int & ERR_INT_FIFO_UNDERRUN_C)
+		if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_C, false))
+			DRM_DEBUG_DRIVER("Pipe C FIFO underrun\n");
+
+	I915_WRITE(GEN7_ERR_INT, err_int);
+}
+
+static void cpt_serr_int_handler(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 serr_int = I915_READ(SERR_INT);
+
+	if (serr_int & SERR_INT_POISON)
+		DRM_ERROR("PCH poison interrupt\n");
+
+	if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN)
+		if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A,
+							  false))
+			DRM_DEBUG_DRIVER("PCH transcoder A FIFO underrun\n");
+
+	if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN)
+		if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B,
+							  false))
+			DRM_DEBUG_DRIVER("PCH transcoder B FIFO underrun\n");
+
+	if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN)
+		if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_C,
+							  false))
+			DRM_DEBUG_DRIVER("PCH transcoder C FIFO underrun\n");
+
+	I915_WRITE(SERR_INT, serr_int);
 }
 
 static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
@@ -807,15 +1148,14 @@ static void cpt_irq_handler(struct drm_d
 	int pipe;
 	u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
 
-	if (hotplug_trigger) {
-		if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_cpt))
-			ibx_hpd_irq_setup(dev);
-		queue_work(dev_priv->wq, &dev_priv->hotplug_work);
+	intel_hpd_irq_handler(dev, hotplug_trigger, hpd_cpt);
+
+	if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) {
+		int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >>
+			       SDE_AUDIO_POWER_SHIFT_CPT);
+		DRM_DEBUG_DRIVER("PCH audio power change on port %c\n",
+				 port_name(port));
 	}
-	if (pch_iir & SDE_AUDIO_POWER_MASK_CPT)
-		DRM_DEBUG_DRIVER("PCH audio power change on port %d\n",
-				 (pch_iir & SDE_AUDIO_POWER_MASK_CPT) >>
-				 SDE_AUDIO_POWER_SHIFT_CPT);
 
 	if (pch_iir & SDE_AUX_MASK_CPT)
 		dp_aux_irq_handler(dev);
@@ -834,6 +1174,9 @@ static void cpt_irq_handler(struct drm_d
 			DRM_DEBUG_DRIVER("  pipe %c FDI IIR: 0x%08x\n",
 					 pipe_name(pipe),
 					 I915_READ(FDI_RX_IIR(pipe)));
+
+	if (pch_iir & SDE_ERROR_CPT)
+		cpt_serr_int_handler(dev);
 }
 
 static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
@@ -846,6 +1189,14 @@ static irqreturn_t ivybridge_irq_handler
 
 	atomic_inc(&dev_priv->irq_received);
 
+	/* We get interrupts on unclaimed registers, so check for this before we
+	 * do any I915_{READ,WRITE}. */
+	if (IS_HASWELL(dev) &&
+	    (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) {
+		DRM_ERROR("Unclaimed register before interrupt\n");
+		I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
+	}
+
 	/* disable master interrupt before clearing iir  */
 	de_ier = I915_READ(DEIER);
 	I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
@@ -861,6 +1212,15 @@ static irqreturn_t ivybridge_irq_handler
 		POSTING_READ(SDEIER);
 	}
 
+	/* On Haswell, also mask ERR_INT because we don't want to risk
+	 * generating "unclaimed register" interrupts from inside the interrupt
+	 * handler. */
+	if (IS_HASWELL(dev)) {
+		spin_lock(&dev_priv->irq_lock);
+		ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
+		spin_unlock(&dev_priv->irq_lock);
+	}
+
 	gt_iir = I915_READ(GTIIR);
 	if (gt_iir) {
 		snb_gt_irq_handler(dev, dev_priv, gt_iir);
@@ -870,11 +1230,14 @@ static irqreturn_t ivybridge_irq_handler
 
 	de_iir = I915_READ(DEIIR);
 	if (de_iir) {
+		if (de_iir & DE_ERR_INT_IVB)
+			ivb_err_int_handler(dev);
+
 		if (de_iir & DE_AUX_CHANNEL_A_IVB)
 			dp_aux_irq_handler(dev);
 
 		if (de_iir & DE_GSE_IVB)
-			intel_opregion_gse_intr(dev);
+			intel_opregion_asle_intr(dev);
 
 		for (i = 0; i < 3; i++) {
 			if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i)))
@@ -901,12 +1264,21 @@ static irqreturn_t ivybridge_irq_handler
 
 	pm_iir = I915_READ(GEN6_PMIIR);
 	if (pm_iir) {
-		if (pm_iir & GEN6_PM_DEFERRED_EVENTS)
+		if (IS_HASWELL(dev))
+			hsw_pm_irq_handler(dev_priv, pm_iir);
+		else if (pm_iir & GEN6_PM_RPS_EVENTS)
 			gen6_queue_rps_work(dev_priv, pm_iir);
 		I915_WRITE(GEN6_PMIIR, pm_iir);
 		ret = IRQ_HANDLED;
 	}
 
+	if (IS_HASWELL(dev)) {
+		spin_lock(&dev_priv->irq_lock);
+		if (ivb_can_enable_err_int(dev))
+			ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
+		spin_unlock(&dev_priv->irq_lock);
+	}
+
 	I915_WRITE(DEIER, de_ier);
 	POSTING_READ(DEIER);
 	if (!HAS_PCH_NOP(dev)) {
@@ -921,9 +1293,10 @@ static void ilk_gt_irq_handler(struct dr
 			       struct drm_i915_private *dev_priv,
 			       u32 gt_iir)
 {
-	if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
+	if (gt_iir &
+	    (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT))
 		notify_ring(dev, &dev_priv->ring[RCS]);
-	if (gt_iir & GT_BSD_USER_INTERRUPT)
+	if (gt_iir & ILK_BSD_USER_INTERRUPT)
 		notify_ring(dev, &dev_priv->ring[VCS]);
 }
 
@@ -968,7 +1341,7 @@ static irqreturn_t ironlake_irq_handler(
 		dp_aux_irq_handler(dev);
 
 	if (de_iir & DE_GSE)
-		intel_opregion_gse_intr(dev);
+		intel_opregion_asle_intr(dev);
 
 	if (de_iir & DE_PIPEA_VBLANK)
 		drm_handle_vblank(dev, 0);
@@ -976,6 +1349,17 @@ static irqreturn_t ironlake_irq_handler(
 	if (de_iir & DE_PIPEB_VBLANK)
 		drm_handle_vblank(dev, 1);
 
+	if (de_iir & DE_POISON)
+		DRM_ERROR("Poison interrupt\n");
+
+	if (de_iir & DE_PIPEA_FIFO_UNDERRUN)
+		if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_A, false))
+			DRM_DEBUG_DRIVER("Pipe A FIFO underrun\n");
+
+	if (de_iir & DE_PIPEB_FIFO_UNDERRUN)
+		if (intel_set_cpu_fifo_underrun_reporting(dev, PIPE_B, false))
+			DRM_DEBUG_DRIVER("Pipe B FIFO underrun\n");
+
 	if (de_iir & DE_PLANEA_FLIP_DONE) {
 		intel_prepare_page_flip(dev, 0);
 		intel_finish_page_flip_plane(dev, 0);
@@ -1002,7 +1386,7 @@ static irqreturn_t ironlake_irq_handler(
 	if (IS_GEN5(dev) &&  de_iir & DE_PCU_EVENT)
 		ironlake_handle_rps_change(dev);
 
-	if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS)
+	if (IS_GEN6(dev) && pm_iir & GEN6_PM_RPS_EVENTS)
 		gen6_queue_rps_work(dev_priv, pm_iir);
 
 	I915_WRITE(GTIIR, gt_iir);
@@ -1222,11 +1606,13 @@ i915_error_state_free(struct kref *error
 	for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
 		i915_error_object_free(error->ring[i].batchbuffer);
 		i915_error_object_free(error->ring[i].ringbuffer);
+		i915_error_object_free(error->ring[i].ctx);
 		kfree(error->ring[i].requests);
 	}
 
 	kfree(error->active_bo);
 	kfree(error->overlay);
+	kfree(error->display);
 	kfree(error);
 }
 static void capture_bo(struct drm_i915_error_buffer *err,
@@ -1273,7 +1659,7 @@ static u32 capture_pinned_bo(struct drm_
 	struct drm_i915_gem_object *obj;
 	int i = 0;
 
-	list_for_each_entry(obj, head, gtt_list) {
+	list_for_each_entry(obj, head, global_list) {
 		if (obj->pin_count == 0)
 			continue;
 
@@ -1415,7 +1801,7 @@ static void i915_gem_record_active_conte
 	if (ring->id != RCS || !error->ccid)
 		return;
 
-	list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
 		if ((error->ccid & PAGE_MASK) == obj->gtt_offset) {
 			ering->ctx = i915_error_object_create_sized(dev_priv,
 								    obj, 1);
@@ -1552,7 +1938,7 @@ static void i915_capture_error_state(str
 	list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list)
 		i++;
 	error->active_bo_count = i;
-	list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list)
 		if (obj->pin_count)
 			i++;
 	error->pinned_bo_count = i - error->active_bo_count;
@@ -1932,38 +2318,28 @@ ring_last_seqno(struct intel_ring_buffer
 			  struct drm_i915_gem_request, list)->seqno;
 }
 
-static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err)
+static bool
+ring_idle(struct intel_ring_buffer *ring, u32 seqno)
 {
-	if (list_empty(&ring->request_list) ||
-	    i915_seqno_passed(ring->get_seqno(ring, false),
-			      ring_last_seqno(ring))) {
-		/* Issue a wake-up to catch stuck h/w. */
-		if (waitqueue_active(&ring->irq_queue)) {
-			DRM_ERROR("Hangcheck timer elapsed... %s idle\n",
-				  ring->name);
-			wake_up_all(&ring->irq_queue);
-			*err = true;
-		}
-		return true;
-	}
-	return false;
+	return (list_empty(&ring->request_list) ||
+		i915_seqno_passed(seqno, ring_last_seqno(ring)));
 }
 
-static bool semaphore_passed(struct intel_ring_buffer *ring)
+static struct intel_ring_buffer *
+semaphore_waits_for(struct intel_ring_buffer *ring, u32 *seqno)
 {
 	struct drm_i915_private *dev_priv = ring->dev->dev_private;
-	u32 acthd = intel_ring_get_active_head(ring) & HEAD_ADDR;
-	struct intel_ring_buffer *signaller;
-	u32 cmd, ipehr, acthd_min;
+	u32 cmd, ipehr, acthd, acthd_min;
 
 	ipehr = I915_READ(RING_IPEHR(ring->mmio_base));
 	if ((ipehr & ~(0x3 << 16)) !=
 	    (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | MI_SEMAPHORE_REGISTER))
-		return false;
+		return NULL;
 
 	/* ACTHD is likely pointing to the dword after the actual command,
 	 * so scan backwards until we find the MBOX.
 	 */
+	acthd = intel_ring_get_active_head(ring) & HEAD_ADDR;
 	acthd_min = max((int)acthd - 3 * 4, 0);
 	do {
 		cmd = ioread32(ring->virtual_start + acthd);
@@ -1972,124 +2348,216 @@ static bool semaphore_passed(struct inte
 
 		acthd -= 4;
 		if (acthd < acthd_min)
-			return false;
+			return NULL;
 	} while (1);
 
-	signaller = &dev_priv->ring[(ring->id + (((ipehr >> 17) & 1) + 1)) % 3];
-	return i915_seqno_passed(signaller->get_seqno(signaller, false),
-				 ioread32(ring->virtual_start+acthd+4)+1);
+	*seqno = ioread32(ring->virtual_start+acthd+4)+1;
+	return &dev_priv->ring[(ring->id + (((ipehr >> 17) & 1) + 1)) % 3];
 }
 
-static bool kick_ring(struct intel_ring_buffer *ring)
+static int semaphore_passed(struct intel_ring_buffer *ring)
 {
-	struct drm_device *dev = ring->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 tmp = I915_READ_CTL(ring);
-	if (tmp & RING_WAIT) {
-		DRM_ERROR("Kicking stuck wait on %s\n",
-			  ring->name);
-		I915_WRITE_CTL(ring, tmp);
-		return true;
-	}
+	struct drm_i915_private *dev_priv = ring->dev->dev_private;
+	struct intel_ring_buffer *signaller;
+	u32 seqno, ctl;
 
-	if (INTEL_INFO(dev)->gen >= 6 &&
-	    tmp & RING_WAIT_SEMAPHORE &&
-	    semaphore_passed(ring)) {
-		DRM_ERROR("Kicking stuck semaphore on %s\n",
-			  ring->name);
-		I915_WRITE_CTL(ring, tmp);
-		return true;
-	}
-	return false;
+	ring->hangcheck.deadlock = true;
+
+	signaller = semaphore_waits_for(ring, &seqno);
+	if (signaller == NULL || signaller->hangcheck.deadlock)
+		return -1;
+
+	/* cursory check for an unkickable deadlock */
+	ctl = I915_READ_CTL(signaller);
+	if (ctl & RING_WAIT_SEMAPHORE && semaphore_passed(signaller) < 0)
+		return -1;
+
+	return i915_seqno_passed(signaller->get_seqno(signaller, false), seqno);
 }
 
-static bool i915_hangcheck_hung(struct drm_device *dev)
+static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
-
-	if (dev_priv->gpu_error.hangcheck_count++ > 1) {
-		bool hung = true;
+	struct intel_ring_buffer *ring;
+	int i;
 
-		DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
-		i915_handle_error(dev, true);
+	for_each_ring(ring, dev_priv, i)
+		ring->hangcheck.deadlock = false;
+}
 
-		if (!IS_GEN2(dev)) {
-			struct intel_ring_buffer *ring;
-			int i;
+static enum intel_ring_hangcheck_action
+ring_stuck(struct intel_ring_buffer *ring, u32 acthd)
+{
+	struct drm_device *dev = ring->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
 
-			/* Is the chip hanging on a WAIT_FOR_EVENT?
-			 * If so we can simply poke the RB_WAIT bit
-			 * and break the hang. This should work on
-			 * all but the second generation chipsets.
-			 */
-			for_each_ring(ring, dev_priv, i)
-				hung &= !kick_ring(ring);
-		}
+	if (ring->hangcheck.acthd != acthd)
+		return active;
 
+	if (IS_GEN2(dev))
 		return hung;
+
+	/* Is the chip hanging on a WAIT_FOR_EVENT?
+	 * If so we can simply poke the RB_WAIT bit
+	 * and break the hang. This should work on
+	 * all but the second generation chipsets.
+	 */
+	tmp = I915_READ_CTL(ring);
+	if (tmp & RING_WAIT) {
+		DRM_ERROR("Kicking stuck wait on %s\n",
+			  ring->name);
+		I915_WRITE_CTL(ring, tmp);
+		return kick;
 	}
 
-	return false;
+	if (INTEL_INFO(dev)->gen >= 6 && tmp & RING_WAIT_SEMAPHORE) {
+		switch (semaphore_passed(ring)) {
+		default:
+			return hung;
+		case 1:
+			DRM_ERROR("Kicking stuck semaphore on %s\n",
+				  ring->name);
+			I915_WRITE_CTL(ring, tmp);
+			return kick;
+		case 0:
+			return wait;
+		}
+	}
+
+	return hung;
 }
 
 /**
  * This is called when the chip hasn't reported back with completed
- * batchbuffers in a long time. The first time this is called we simply record
- * ACTHD. If ACTHD hasn't changed by the time the hangcheck timer elapses
- * again, we assume the chip is wedged and try to fix it.
+ * batchbuffers in a long time. We keep track per ring seqno progress and
+ * if there are no progress, hangcheck score for that ring is increased.
+ * Further, acthd is inspected to see if the ring is stuck. On stuck case
+ * we kick the ring. If we see no progress on three subsequent calls
+ * we assume chip is wedged and try to fix it by resetting the chip.
  */
 void i915_hangcheck_elapsed(unsigned long data)
 {
 	struct drm_device *dev = (struct drm_device *)data;
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	uint32_t acthd[I915_NUM_RINGS], instdone[I915_NUM_INSTDONE_REG];
 	struct intel_ring_buffer *ring;
-	bool err = false, idle;
 	int i;
+	int busy_count = 0, rings_hung = 0;
+	bool stuck[I915_NUM_RINGS] = { 0 };
+#define BUSY 1
+#define KICK 5
+#define HUNG 20
+#define FIRE 30
 
 	if (!i915_enable_hangcheck)
 		return;
 
-	memset(acthd, 0, sizeof(acthd));
-	idle = true;
 	for_each_ring(ring, dev_priv, i) {
-	    idle &= i915_hangcheck_ring_idle(ring, &err);
-	    acthd[i] = intel_ring_get_active_head(ring);
-	}
+		u32 seqno, acthd;
+		bool busy = true;
 
-	/* If all work is done then ACTHD clearly hasn't advanced. */
-	if (idle) {
-		if (err) {
-			if (i915_hangcheck_hung(dev))
-				return;
+		semaphore_clear_deadlocks(dev_priv);
 
-			goto repeat;
+		seqno = ring->get_seqno(ring, false);
+		acthd = intel_ring_get_active_head(ring);
+
+		if (ring->hangcheck.seqno == seqno) {
+			if (ring_idle(ring, seqno)) {
+				if (waitqueue_active(&ring->irq_queue)) {
+					/* Issue a wake-up to catch stuck h/w. */
+					DRM_ERROR("Hangcheck timer elapsed... %s idle\n",
+						  ring->name);
+					wake_up_all(&ring->irq_queue);
+					ring->hangcheck.score += HUNG;
+				} else
+					busy = false;
+			} else {
+				int score;
+
+				/* We always increment the hangcheck score
+				 * if the ring is busy and still processing
+				 * the same request, so that no single request
+				 * can run indefinitely (such as a chain of
+				 * batches). The only time we do not increment
+				 * the hangcheck score on this ring, if this
+				 * ring is in a legitimate wait for another
+				 * ring. In that case the waiting ring is a
+				 * victim and we want to be sure we catch the
+				 * right culprit. Then every time we do kick
+				 * the ring, add a small increment to the
+				 * score so that we can catch a batch that is
+				 * being repeatedly kicked and so responsible
+				 * for stalling the machine.
+				 */
+				ring->hangcheck.action = ring_stuck(ring,
+								    acthd);
+
+				switch (ring->hangcheck.action) {
+				case wait:
+					score = 0;
+					break;
+				case active:
+					score = BUSY;
+					break;
+				case kick:
+					score = KICK;
+					break;
+				case hung:
+					score = HUNG;
+					stuck[i] = true;
+					break;
+				}
+				ring->hangcheck.score += score;
+			}
+		} else {
+			/* Gradually reduce the count so that we catch DoS
+			 * attempts across multiple batches.
+			 */
+			if (ring->hangcheck.score > 0)
+				ring->hangcheck.score--;
 		}
 
-		dev_priv->gpu_error.hangcheck_count = 0;
-		return;
+		ring->hangcheck.seqno = seqno;
+		ring->hangcheck.acthd = acthd;
+		busy_count += busy;
 	}
 
-	i915_get_extra_instdone(dev, instdone);
-	if (memcmp(dev_priv->gpu_error.last_acthd, acthd,
-		   sizeof(acthd)) == 0 &&
-	    memcmp(dev_priv->gpu_error.prev_instdone, instdone,
-		   sizeof(instdone)) == 0) {
-		if (i915_hangcheck_hung(dev))
-			return;
-	} else {
-		dev_priv->gpu_error.hangcheck_count = 0;
-
-		memcpy(dev_priv->gpu_error.last_acthd, acthd,
-		       sizeof(acthd));
-		memcpy(dev_priv->gpu_error.prev_instdone, instdone,
-		       sizeof(instdone));
+	for_each_ring(ring, dev_priv, i) {
+		if (ring->hangcheck.score > FIRE) {
+			DRM_ERROR("%s on %s\n",
+				  stuck[i] ? "stuck" : "no progress",
+				  ring->name);
+			rings_hung++;
+		}
 	}
 
-repeat:
-	/* Reset timer case chip hangs without another request being added */
-	mod_timer(&dev_priv->gpu_error.hangcheck_timer,
-		  round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES));
+	if (rings_hung)
+		return i915_handle_error(dev, true);
+
+	if (busy_count)
+		/* Reset timer case chip hangs without another request
+		 * being added */
+		mod_timer(&dev_priv->gpu_error.hangcheck_timer,
+			  round_jiffies_up(jiffies +
+					   DRM_I915_HANGCHECK_JIFFIES));
+}
+
+static void ibx_irq_preinstall(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (HAS_PCH_NOP(dev))
+		return;
+
+	/* south display irq */
+	I915_WRITE(SDEIMR, 0xffffffff);
+	/*
+	 * SDEIER is also touched by the interrupt handler to work around missed
+	 * PCH interrupts. Hence we can't update it after the interrupt handler
+	 * is enabled - instead we unconditionally enable all PCH interrupt
+	 * sources here, but then only unmask them as needed with SDEIMR.
+	 */
+	I915_WRITE(SDEIER, 0xffffffff);
+	POSTING_READ(SDEIER);
 }
 
 /* drm_dma.h hooks
@@ -2113,19 +2581,34 @@ static void ironlake_irq_preinstall(stru
 	I915_WRITE(GTIER, 0x0);
 	POSTING_READ(GTIER);
 
-	if (HAS_PCH_NOP(dev))
-		return;
+	ibx_irq_preinstall(dev);
+}
 
-	/* south display irq */
-	I915_WRITE(SDEIMR, 0xffffffff);
-	/*
-	 * SDEIER is also touched by the interrupt handler to work around missed
-	 * PCH interrupts. Hence we can't update it after the interrupt handler
-	 * is enabled - instead we unconditionally enable all PCH interrupt
-	 * sources here, but then only unmask them as needed with SDEIMR.
-	 */
-	I915_WRITE(SDEIER, 0xffffffff);
-	POSTING_READ(SDEIER);
+static void ivybridge_irq_preinstall(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+	atomic_set(&dev_priv->irq_received, 0);
+
+	I915_WRITE(HWSTAM, 0xeffe);
+
+	/* XXX hotplug from PCH */
+
+	I915_WRITE(DEIMR, 0xffffffff);
+	I915_WRITE(DEIER, 0x0);
+	POSTING_READ(DEIER);
+
+	/* and GT */
+	I915_WRITE(GTIMR, 0xffffffff);
+	I915_WRITE(GTIER, 0x0);
+	POSTING_READ(GTIER);
+
+	/* Power management */
+	I915_WRITE(GEN6_PMIMR, 0xffffffff);
+	I915_WRITE(GEN6_PMIER, 0x0);
+	POSTING_READ(GEN6_PMIER);
+
+	ibx_irq_preinstall(dev);
 }
 
 static void valleyview_irq_preinstall(struct drm_device *dev)
@@ -2201,33 +2684,41 @@ static void ibx_irq_postinstall(struct d
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	u32 mask;
 
-	if (HAS_PCH_IBX(dev))
-		mask = SDE_GMBUS | SDE_AUX_MASK;
-	else
-		mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
-
 	if (HAS_PCH_NOP(dev))
 		return;
 
+	if (HAS_PCH_IBX(dev)) {
+		mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER |
+		       SDE_TRANSA_FIFO_UNDER | SDE_POISON;
+	} else {
+		mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT;
+
+		I915_WRITE(SERR_INT, I915_READ(SERR_INT));
+	}
+
 	I915_WRITE(SDEIIR, I915_READ(SDEIIR));
 	I915_WRITE(SDEIMR, ~mask);
 }
 
 static int ironlake_irq_postinstall(struct drm_device *dev)
 {
+	unsigned long irqflags;
+
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	/* enable kind of interrupts always enabled */
 	u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
 			   DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
-			   DE_AUX_CHANNEL_A;
-	u32 render_irqs;
+			   DE_AUX_CHANNEL_A | DE_PIPEB_FIFO_UNDERRUN |
+			   DE_PIPEA_FIFO_UNDERRUN | DE_POISON;
+	u32 gt_irqs;
 
 	dev_priv->irq_mask = ~display_mask;
 
 	/* should always can generate irq */
 	I915_WRITE(DEIIR, I915_READ(DEIIR));
 	I915_WRITE(DEIMR, dev_priv->irq_mask);
-	I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK);
+	I915_WRITE(DEIER, display_mask |
+			  DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT);
 	POSTING_READ(DEIER);
 
 	dev_priv->gt_irq_mask = ~0;
@@ -2235,26 +2726,28 @@ static int ironlake_irq_postinstall(stru
 	I915_WRITE(GTIIR, I915_READ(GTIIR));
 	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 
+	gt_irqs = GT_RENDER_USER_INTERRUPT;
+
 	if (IS_GEN6(dev))
-		render_irqs =
-			GT_USER_INTERRUPT |
-			GEN6_BSD_USER_INTERRUPT |
-			GEN6_BLITTER_USER_INTERRUPT;
+		gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT;
 	else
-		render_irqs =
-			GT_USER_INTERRUPT |
-			GT_PIPE_NOTIFY |
-			GT_BSD_USER_INTERRUPT;
-	I915_WRITE(GTIER, render_irqs);
+		gt_irqs |= GT_RENDER_PIPECTL_NOTIFY_INTERRUPT |
+			   ILK_BSD_USER_INTERRUPT;
+
+	I915_WRITE(GTIER, gt_irqs);
 	POSTING_READ(GTIER);
 
 	ibx_irq_postinstall(dev);
 
 	if (IS_IRONLAKE_M(dev)) {
-		/* Clear & enable PCU event interrupts */
-		I915_WRITE(DEIIR, DE_PCU_EVENT);
-		I915_WRITE(DEIER, I915_READ(DEIER) | DE_PCU_EVENT);
+		/* Enable PCU event interrupts
+		 *
+		 * spinlocking not required here for correctness since interrupt
+		 * setup is guaranteed to run in single-threaded context. But we
+		 * need it to make the assert_spin_locked happy. */
+		spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 		ironlake_enable_display_irq(dev_priv, DE_PCU_EVENT);
+		spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 	}
 
 	return 0;
@@ -2269,12 +2762,15 @@ static int ivybridge_irq_postinstall(str
 		DE_PLANEC_FLIP_DONE_IVB |
 		DE_PLANEB_FLIP_DONE_IVB |
 		DE_PLANEA_FLIP_DONE_IVB |
-		DE_AUX_CHANNEL_A_IVB;
-	u32 render_irqs;
+		DE_AUX_CHANNEL_A_IVB |
+		DE_ERR_INT_IVB;
+	u32 pm_irqs = GEN6_PM_RPS_EVENTS;
+	u32 gt_irqs;
 
 	dev_priv->irq_mask = ~display_mask;
 
 	/* should always can generate irq */
+	I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
 	I915_WRITE(DEIIR, I915_READ(DEIIR));
 	I915_WRITE(DEIMR, dev_priv->irq_mask);
 	I915_WRITE(DEIER,
@@ -2284,16 +2780,32 @@ static int ivybridge_irq_postinstall(str
 		   DE_PIPEA_VBLANK_IVB);
 	POSTING_READ(DEIER);
 
-	dev_priv->gt_irq_mask = ~GT_GEN7_L3_PARITY_ERROR_INTERRUPT;
+	dev_priv->gt_irq_mask = ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
 
 	I915_WRITE(GTIIR, I915_READ(GTIIR));
 	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 
-	render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT |
-		GEN6_BLITTER_USER_INTERRUPT | GT_GEN7_L3_PARITY_ERROR_INTERRUPT;
-	I915_WRITE(GTIER, render_irqs);
+	gt_irqs = GT_RENDER_USER_INTERRUPT | GT_BSD_USER_INTERRUPT |
+		  GT_BLT_USER_INTERRUPT | GT_RENDER_L3_PARITY_ERROR_INTERRUPT;
+	I915_WRITE(GTIER, gt_irqs);
 	POSTING_READ(GTIER);
 
+	I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR));
+	if (HAS_VEBOX(dev))
+		pm_irqs |= PM_VEBOX_USER_INTERRUPT |
+			PM_VEBOX_CS_ERROR_INTERRUPT;
+
+	/* Our enable/disable rps functions may touch these registers so
+	 * make sure to set a known state for only the non-RPS bits.
+	 * The RMW is extra paranoia since this should be called after being set
+	 * to a known state in preinstall.
+	 * */
+	I915_WRITE(GEN6_PMIMR,
+		   (I915_READ(GEN6_PMIMR) | ~GEN6_PM_RPS_EVENTS) & ~pm_irqs);
+	I915_WRITE(GEN6_PMIER,
+		   (I915_READ(GEN6_PMIER) & GEN6_PM_RPS_EVENTS) | pm_irqs);
+	POSTING_READ(GEN6_PMIER);
+
 	ibx_irq_postinstall(dev);
 
 	return 0;
@@ -2302,10 +2814,9 @@ static int ivybridge_irq_postinstall(str
 static int valleyview_irq_postinstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	u32 gt_irqs;
 	u32 enable_mask;
 	u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV;
-	u32 render_irqs;
-	u16 msid;
 
 	enable_mask = I915_DISPLAY_PORT_INTERRUPT;
 	enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
@@ -2321,13 +2832,6 @@ static int valleyview_irq_postinstall(st
 		I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
 		I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
 
-	/* Hack for broken MSIs on VLV */
-	pci_write_config_dword(dev_priv->dev->pdev, 0x94, 0xfee00000);
-	pci_read_config_word(dev->pdev, 0x98, &msid);
-	msid &= 0xff; /* mask out delivery bits */
-	msid |= (1<<14);
-	pci_write_config_word(dev_priv->dev->pdev, 0x98, msid);
-
 	I915_WRITE(PORT_HOTPLUG_EN, 0);
 	POSTING_READ(PORT_HOTPLUG_EN);
 
@@ -2348,9 +2852,9 @@ static int valleyview_irq_postinstall(st
 	I915_WRITE(GTIIR, I915_READ(GTIIR));
 	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 
-	render_irqs = GT_USER_INTERRUPT | GEN6_BSD_USER_INTERRUPT |
-		GEN6_BLITTER_USER_INTERRUPT;
-	I915_WRITE(GTIER, render_irqs);
+	gt_irqs = GT_RENDER_USER_INTERRUPT | GT_BSD_USER_INTERRUPT |
+		GT_BLT_USER_INTERRUPT;
+	I915_WRITE(GTIER, gt_irqs);
 	POSTING_READ(GTIER);
 
 	/* ack & enable invalid PTE error interrupts */
@@ -2402,6 +2906,8 @@ static void ironlake_irq_uninstall(struc
 	I915_WRITE(DEIMR, 0xffffffff);
 	I915_WRITE(DEIER, 0x0);
 	I915_WRITE(DEIIR, I915_READ(DEIIR));
+	if (IS_GEN7(dev))
+		I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
 
 	I915_WRITE(GTIMR, 0xffffffff);
 	I915_WRITE(GTIER, 0x0);
@@ -2413,6 +2919,8 @@ static void ironlake_irq_uninstall(struc
 	I915_WRITE(SDEIMR, 0xffffffff);
 	I915_WRITE(SDEIER, 0x0);
 	I915_WRITE(SDEIIR, I915_READ(SDEIIR));
+	if (HAS_PCH_CPT(dev) || HAS_PCH_LPT(dev))
+		I915_WRITE(SERR_INT, I915_READ(SERR_INT));
 }
 
 static void i8xx_irq_preinstall(struct drm_device * dev)
@@ -2626,7 +3134,7 @@ static int i915_irq_postinstall(struct d
 	I915_WRITE(IER, enable_mask);
 	POSTING_READ(IER);
 
-	intel_opregion_enable_asle(dev);
+	i915_enable_asle_pipestat(dev);
 
 	return 0;
 }
@@ -2715,12 +3223,9 @@ static irqreturn_t i915_irq_handler(int
 
 			DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
 				  hotplug_status);
-			if (hotplug_trigger) {
-				if (hotplug_irq_storm_detect(dev, hotplug_trigger, hpd_status_i915))
-					i915_hpd_irq_setup(dev);
-				queue_work(dev_priv->wq,
-					   &dev_priv->hotplug_work);
-			}
+
+			intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915);
+
 			I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
 			POSTING_READ(PORT_HOTPLUG_STAT);
 		}
@@ -2860,7 +3365,7 @@ static int i965_irq_postinstall(struct d
 	I915_WRITE(PORT_HOTPLUG_EN, 0);
 	POSTING_READ(PORT_HOTPLUG_EN);
 
-	intel_opregion_enable_asle(dev);
+	i915_enable_asle_pipestat(dev);
 
 	return 0;
 }
@@ -2872,6 +3377,8 @@ static void i915_hpd_irq_setup(struct dr
 	struct intel_encoder *intel_encoder;
 	u32 hotplug_en;
 
+	assert_spin_locked(&dev_priv->irq_lock);
+
 	if (I915_HAS_HOTPLUG(dev)) {
 		hotplug_en = I915_READ(PORT_HOTPLUG_EN);
 		hotplug_en &= ~HOTPLUG_INT_EN_MASK;
@@ -2952,17 +3459,14 @@ static irqreturn_t i965_irq_handler(int
 			u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
 			u32 hotplug_trigger = hotplug_status & (IS_G4X(dev) ?
 								  HOTPLUG_INT_STATUS_G4X :
-								  HOTPLUG_INT_STATUS_I965);
+								  HOTPLUG_INT_STATUS_I915);
 
 			DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
 				  hotplug_status);
-			if (hotplug_trigger) {
-				if (hotplug_irq_storm_detect(dev, hotplug_trigger,
-							    IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i965))
-					i915_hpd_irq_setup(dev);
-				queue_work(dev_priv->wq,
-					   &dev_priv->hotplug_work);
-			}
+
+			intel_hpd_irq_handler(dev, hotplug_trigger,
+					      IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i915);
+
 			I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
 			I915_READ(PORT_HOTPLUG_STAT);
 		}
@@ -3113,9 +3617,9 @@ void intel_irq_init(struct drm_device *d
 		dev->driver->disable_vblank = valleyview_disable_vblank;
 		dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
 	} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
-		/* Share pre & uninstall handlers with ILK/SNB */
+		/* Share uninstall handlers with ILK/SNB */
 		dev->driver->irq_handler = ivybridge_irq_handler;
-		dev->driver->irq_preinstall = ironlake_irq_preinstall;
+		dev->driver->irq_preinstall = ivybridge_irq_preinstall;
 		dev->driver->irq_postinstall = ivybridge_irq_postinstall;
 		dev->driver->irq_uninstall = ironlake_irq_uninstall;
 		dev->driver->enable_vblank = ivybridge_enable_vblank;
@@ -3158,6 +3662,7 @@ void intel_hpd_init(struct drm_device *d
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct drm_connector *connector;
+	unsigned long irqflags;
 	int i;
 
 	for (i = 1; i < HPD_NUM_PINS; i++) {
@@ -3170,6 +3675,11 @@ void intel_hpd_init(struct drm_device *d
 		if (!connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE)
 			connector->polled = DRM_CONNECTOR_POLL_HPD;
 	}
+
+	/* Interrupt setup is already guaranteed to be single-threaded, this is
+	 * just to make the assert_spin_locked checks happy. */
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	if (dev_priv->display.hpd_irq_setup)
 		dev_priv->display.hpd_irq_setup(dev);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_reg.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_reg.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -147,15 +147,9 @@
 #define   VGA_MSR_MEM_EN (1<<1)
 #define   VGA_MSR_CGA_MODE (1<<0)
 
-/*
- * SR01 is the only VGA register touched on non-UMS setups.
- * VLV doesn't do UMS, so the sequencer index/data registers
- * are the only VGA registers which need to include
- * display_mmio_offset.
- */
-#define VGA_SR_INDEX (dev_priv->info->display_mmio_offset + 0x3c4)
+#define VGA_SR_INDEX 0x3c4
 #define SR01			1
-#define VGA_SR_DATA (dev_priv->info->display_mmio_offset + 0x3c5)
+#define VGA_SR_DATA 0x3c5
 
 #define VGA_AR_INDEX 0x3c0
 #define   VGA_AR_VID_EN (1<<5)
@@ -265,13 +259,19 @@
 #define  MI_SEMAPHORE_UPDATE	    (1<<21)
 #define  MI_SEMAPHORE_COMPARE	    (1<<20)
 #define  MI_SEMAPHORE_REGISTER	    (1<<18)
-#define  MI_SEMAPHORE_SYNC_RV	    (2<<16)
-#define  MI_SEMAPHORE_SYNC_RB	    (0<<16)
-#define  MI_SEMAPHORE_SYNC_VR	    (0<<16)
-#define  MI_SEMAPHORE_SYNC_VB	    (2<<16)
-#define  MI_SEMAPHORE_SYNC_BR	    (2<<16)
-#define  MI_SEMAPHORE_SYNC_BV	    (0<<16)
-#define  MI_SEMAPHORE_SYNC_INVALID  (1<<0)
+#define  MI_SEMAPHORE_SYNC_VR	    (0<<16) /* RCS  wait for VCS  (RVSYNC) */
+#define  MI_SEMAPHORE_SYNC_VER	    (1<<16) /* RCS  wait for VECS (RVESYNC) */
+#define  MI_SEMAPHORE_SYNC_BR	    (2<<16) /* RCS  wait for BCS  (RBSYNC) */
+#define  MI_SEMAPHORE_SYNC_BV	    (0<<16) /* VCS  wait for BCS  (VBSYNC) */
+#define  MI_SEMAPHORE_SYNC_VEV	    (1<<16) /* VCS  wait for VECS (VVESYNC) */
+#define  MI_SEMAPHORE_SYNC_RV	    (2<<16) /* VCS  wait for RCS  (VRSYNC) */
+#define  MI_SEMAPHORE_SYNC_RB	    (0<<16) /* BCS  wait for RCS  (BRSYNC) */
+#define  MI_SEMAPHORE_SYNC_VEB	    (1<<16) /* BCS  wait for VECS (BVESYNC) */
+#define  MI_SEMAPHORE_SYNC_VB	    (2<<16) /* BCS  wait for VCS  (BVSYNC) */
+#define  MI_SEMAPHORE_SYNC_BVE	    (0<<16) /* VECS wait for BCS  (VEBSYNC) */
+#define  MI_SEMAPHORE_SYNC_VVE	    (1<<16) /* VECS wait for VCS  (VEVSYNC) */
+#define  MI_SEMAPHORE_SYNC_RVE	    (2<<16) /* VECS wait for RCS  (VERSYNC) */
+#define  MI_SEMAPHORE_SYNC_INVALID  (3<<16)
 /*
  * 3D instructions used by the kernel
  */
@@ -342,33 +342,74 @@
 #define  DEBUG_RESET_DISPLAY		(1<<9)
 
 /*
- * DPIO - a special bus for various display related registers to hide behind:
- *  0x800c: m1, m2, n, p1, p2, k dividers
- *  0x8014: REF and SFR select
- *  0x8014: N divider, VCO select
- *  0x801c/3c: core clock bits
- *  0x8048/68: low pass filter coefficients
- *  0x8100: fast clock controls
+ * IOSF sideband
+ */
+#define VLV_IOSF_DOORBELL_REQ			(VLV_DISPLAY_BASE + 0x2100)
+#define   IOSF_DEVFN_SHIFT			24
+#define   IOSF_OPCODE_SHIFT			16
+#define   IOSF_PORT_SHIFT			8
+#define   IOSF_BYTE_ENABLES_SHIFT		4
+#define   IOSF_BAR_SHIFT			1
+#define   IOSF_SB_BUSY				(1<<0)
+#define   IOSF_PORT_PUNIT			0x4
+#define   IOSF_PORT_NC				0x11
+#define   IOSF_PORT_DPIO			0x12
+#define VLV_IOSF_DATA				(VLV_DISPLAY_BASE + 0x2104)
+#define VLV_IOSF_ADDR				(VLV_DISPLAY_BASE + 0x2108)
+
+#define PUNIT_OPCODE_REG_READ			6
+#define PUNIT_OPCODE_REG_WRITE			7
+
+#define PUNIT_REG_GPU_LFM			0xd3
+#define PUNIT_REG_GPU_FREQ_REQ			0xd4
+#define PUNIT_REG_GPU_FREQ_STS			0xd8
+#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ		0xdc
+
+#define PUNIT_FUSE_BUS2				0xf6 /* bits 47:40 */
+#define PUNIT_FUSE_BUS1				0xf5 /* bits 55:48 */
+
+#define IOSF_NC_FB_GFX_FREQ_FUSE		0x1c
+#define   FB_GFX_MAX_FREQ_FUSE_SHIFT		3
+#define   FB_GFX_MAX_FREQ_FUSE_MASK		0x000007f8
+#define   FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT	11
+#define   FB_GFX_FGUARANTEED_FREQ_FUSE_MASK	0x0007f800
+#define IOSF_NC_FB_GFX_FMAX_FUSE_HI		0x34
+#define   FB_FMAX_VMIN_FREQ_HI_MASK		0x00000007
+#define IOSF_NC_FB_GFX_FMAX_FUSE_LO		0x30
+#define   FB_FMAX_VMIN_FREQ_LO_SHIFT		27
+#define   FB_FMAX_VMIN_FREQ_LO_MASK		0xf8000000
+
+/*
+ * DPIO - a special bus for various display related registers to hide behind
  *
  * DPIO is VLV only.
+ *
+ * Note: digital port B is DDI0, digital pot C is DDI1
  */
-#define DPIO_PKT			(VLV_DISPLAY_BASE + 0x2100)
-#define  DPIO_RID			(0<<24)
-#define  DPIO_OP_WRITE			(1<<16)
-#define  DPIO_OP_READ			(0<<16)
-#define  DPIO_PORTID			(0x12<<8)
-#define  DPIO_BYTE			(0xf<<4)
-#define  DPIO_BUSY			(1<<0) /* status only */
-#define DPIO_DATA			(VLV_DISPLAY_BASE + 0x2104)
-#define DPIO_REG			(VLV_DISPLAY_BASE + 0x2108)
+#define DPIO_DEVFN			0
+#define DPIO_OPCODE_REG_WRITE		1
+#define DPIO_OPCODE_REG_READ		0
+
 #define DPIO_CTL			(VLV_DISPLAY_BASE + 0x2110)
 #define  DPIO_MODSEL1			(1<<3) /* if ref clk b == 27 */
 #define  DPIO_MODSEL0			(1<<2) /* if ref clk a == 27 */
 #define  DPIO_SFR_BYPASS		(1<<1)
 #define  DPIO_RESET			(1<<0)
 
+#define _DPIO_TX3_SWING_CTL4_A		0x690
+#define _DPIO_TX3_SWING_CTL4_B		0x2a90
+#define DPIO_TX3_SWING_CTL4(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL4_A, \
+					_DPIO_TX3_SWING_CTL4_B)
+
+/*
+ * Per pipe/PLL DPIO regs
+ */
 #define _DPIO_DIV_A			0x800c
 #define   DPIO_POST_DIV_SHIFT		(28) /* 3 bits */
+#define   DPIO_POST_DIV_DAC		0
+#define   DPIO_POST_DIV_HDMIDP		1 /* DAC 225-400M rate */
+#define   DPIO_POST_DIV_LVDS1		2
+#define   DPIO_POST_DIV_LVDS2		3
 #define   DPIO_K_SHIFT			(24) /* 4 bits */
 #define   DPIO_P1_SHIFT			(21) /* 3 bits */
 #define   DPIO_P2_SHIFT			(16) /* 5 bits */
@@ -394,14 +435,111 @@
 #define _DPIO_CORE_CLK_B		0x803c
 #define DPIO_CORE_CLK(pipe) _PIPE(pipe, _DPIO_CORE_CLK_A, _DPIO_CORE_CLK_B)
 
-#define _DPIO_LFP_COEFF_A		0x8048
-#define _DPIO_LFP_COEFF_B		0x8068
-#define DPIO_LFP_COEFF(pipe) _PIPE(pipe, _DPIO_LFP_COEFF_A, _DPIO_LFP_COEFF_B)
+#define _DPIO_IREF_CTL_A		0x8040
+#define _DPIO_IREF_CTL_B		0x8060
+#define DPIO_IREF_CTL(pipe) _PIPE(pipe, _DPIO_IREF_CTL_A, _DPIO_IREF_CTL_B)
+
+#define DPIO_IREF_BCAST			0xc044
+#define _DPIO_IREF_A			0x8044
+#define _DPIO_IREF_B			0x8064
+#define DPIO_IREF(pipe) _PIPE(pipe, _DPIO_IREF_A, _DPIO_IREF_B)
+
+#define _DPIO_PLL_CML_A			0x804c
+#define _DPIO_PLL_CML_B			0x806c
+#define DPIO_PLL_CML(pipe) _PIPE(pipe, _DPIO_PLL_CML_A, _DPIO_PLL_CML_B)
+
+#define _DPIO_LPF_COEFF_A		0x8048
+#define _DPIO_LPF_COEFF_B		0x8068
+#define DPIO_LPF_COEFF(pipe) _PIPE(pipe, _DPIO_LPF_COEFF_A, _DPIO_LPF_COEFF_B)
+
+#define DPIO_CALIBRATION		0x80ac
 
 #define DPIO_FASTCLK_DISABLE		0x8100
 
-#define DPIO_DATA_CHANNEL1		0x8220
-#define DPIO_DATA_CHANNEL2		0x8420
+/*
+ * Per DDI channel DPIO regs
+ */
+
+#define _DPIO_PCS_TX_0			0x8200
+#define _DPIO_PCS_TX_1			0x8400
+#define   DPIO_PCS_TX_LANE2_RESET	(1<<16)
+#define   DPIO_PCS_TX_LANE1_RESET	(1<<7)
+#define DPIO_PCS_TX(port) _PORT(port, _DPIO_PCS_TX_0, _DPIO_PCS_TX_1)
+
+#define _DPIO_PCS_CLK_0			0x8204
+#define _DPIO_PCS_CLK_1			0x8404
+#define   DPIO_PCS_CLK_CRI_RXEB_EIOS_EN	(1<<22)
+#define   DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN (1<<21)
+#define   DPIO_PCS_CLK_DATAWIDTH_SHIFT	(6)
+#define   DPIO_PCS_CLK_SOFT_RESET	(1<<5)
+#define DPIO_PCS_CLK(port) _PORT(port, _DPIO_PCS_CLK_0, _DPIO_PCS_CLK_1)
+
+#define _DPIO_PCS_CTL_OVR1_A		0x8224
+#define _DPIO_PCS_CTL_OVR1_B		0x8424
+#define DPIO_PCS_CTL_OVER1(port) _PORT(port, _DPIO_PCS_CTL_OVR1_A, \
+				       _DPIO_PCS_CTL_OVR1_B)
+
+#define _DPIO_PCS_STAGGER0_A		0x822c
+#define _DPIO_PCS_STAGGER0_B		0x842c
+#define DPIO_PCS_STAGGER0(port) _PORT(port, _DPIO_PCS_STAGGER0_A, \
+				      _DPIO_PCS_STAGGER0_B)
+
+#define _DPIO_PCS_STAGGER1_A		0x8230
+#define _DPIO_PCS_STAGGER1_B		0x8430
+#define DPIO_PCS_STAGGER1(port) _PORT(port, _DPIO_PCS_STAGGER1_A, \
+				      _DPIO_PCS_STAGGER1_B)
+
+#define _DPIO_PCS_CLOCKBUF0_A		0x8238
+#define _DPIO_PCS_CLOCKBUF0_B		0x8438
+#define DPIO_PCS_CLOCKBUF0(port) _PORT(port, _DPIO_PCS_CLOCKBUF0_A, \
+				       _DPIO_PCS_CLOCKBUF0_B)
+
+#define _DPIO_PCS_CLOCKBUF8_A		0x825c
+#define _DPIO_PCS_CLOCKBUF8_B		0x845c
+#define DPIO_PCS_CLOCKBUF8(port) _PORT(port, _DPIO_PCS_CLOCKBUF8_A, \
+				       _DPIO_PCS_CLOCKBUF8_B)
+
+#define _DPIO_TX_SWING_CTL2_A		0x8288
+#define _DPIO_TX_SWING_CTL2_B		0x8488
+#define DPIO_TX_SWING_CTL2(port) _PORT(port, _DPIO_TX_SWING_CTL2_A, \
+				       _DPIO_TX_SWING_CTL2_B)
+
+#define _DPIO_TX_SWING_CTL3_A		0x828c
+#define _DPIO_TX_SWING_CTL3_B		0x848c
+#define DPIO_TX_SWING_CTL3(port) _PORT(port, _DPIO_TX_SWING_CTL3_A, \
+				       _DPIO_TX_SWING_CTL3_B)
+
+#define _DPIO_TX_SWING_CTL4_A		0x8290
+#define _DPIO_TX_SWING_CTL4_B		0x8490
+#define DPIO_TX_SWING_CTL4(port) _PORT(port, _DPIO_TX_SWING_CTL4_A, \
+				       _DPIO_TX_SWING_CTL4_B)
+
+#define _DPIO_TX_OCALINIT_0		0x8294
+#define _DPIO_TX_OCALINIT_1		0x8494
+#define   DPIO_TX_OCALINIT_EN		(1<<31)
+#define DPIO_TX_OCALINIT(port) _PORT(port, _DPIO_TX_OCALINIT_0, \
+				     _DPIO_TX_OCALINIT_1)
+
+#define _DPIO_TX_CTL_0			0x82ac
+#define _DPIO_TX_CTL_1			0x84ac
+#define DPIO_TX_CTL(port) _PORT(port, _DPIO_TX_CTL_0, _DPIO_TX_CTL_1)
+
+#define _DPIO_TX_LANE_0			0x82b8
+#define _DPIO_TX_LANE_1			0x84b8
+#define DPIO_TX_LANE(port) _PORT(port, _DPIO_TX_LANE_0, _DPIO_TX_LANE_1)
+
+#define _DPIO_DATA_CHANNEL1		0x8220
+#define _DPIO_DATA_CHANNEL2		0x8420
+#define DPIO_DATA_CHANNEL(port) _PORT(port, _DPIO_DATA_CHANNEL1, _DPIO_DATA_CHANNEL2)
+
+#define _DPIO_PORT0_PCS0		0x0220
+#define _DPIO_PORT0_PCS1		0x0420
+#define _DPIO_PORT1_PCS2		0x2620
+#define _DPIO_PORT1_PCS3		0x2820
+#define DPIO_DATA_LANE_A(port) _PORT(port, _DPIO_PORT0_PCS0, _DPIO_PORT1_PCS2)
+#define DPIO_DATA_LANE_B(port) _PORT(port, _DPIO_PORT0_PCS1, _DPIO_PORT1_PCS3)
+#define DPIO_DATA_CHANNEL1              0x8220
+#define DPIO_DATA_CHANNEL2              0x8420
 
 /*
  * Fence registers
@@ -443,6 +581,7 @@
 #define RENDER_RING_BASE	0x02000
 #define BSD_RING_BASE		0x04000
 #define GEN6_BSD_RING_BASE	0x12000
+#define VEBOX_RING_BASE		0x1a000
 #define BLT_RING_BASE		0x22000
 #define RING_TAIL(base)		((base)+0x30)
 #define RING_HEAD(base)		((base)+0x34)
@@ -450,12 +589,20 @@
 #define RING_CTL(base)		((base)+0x3c)
 #define RING_SYNC_0(base)	((base)+0x40)
 #define RING_SYNC_1(base)	((base)+0x44)
-#define GEN6_RVSYNC (RING_SYNC_0(RENDER_RING_BASE))
-#define GEN6_RBSYNC (RING_SYNC_1(RENDER_RING_BASE))
-#define GEN6_VRSYNC (RING_SYNC_1(GEN6_BSD_RING_BASE))
-#define GEN6_VBSYNC (RING_SYNC_0(GEN6_BSD_RING_BASE))
-#define GEN6_BRSYNC (RING_SYNC_0(BLT_RING_BASE))
-#define GEN6_BVSYNC (RING_SYNC_1(BLT_RING_BASE))
+#define RING_SYNC_2(base)	((base)+0x48)
+#define GEN6_RVSYNC	(RING_SYNC_0(RENDER_RING_BASE))
+#define GEN6_RBSYNC	(RING_SYNC_1(RENDER_RING_BASE))
+#define GEN6_RVESYNC	(RING_SYNC_2(RENDER_RING_BASE))
+#define GEN6_VBSYNC	(RING_SYNC_0(GEN6_BSD_RING_BASE))
+#define GEN6_VRSYNC	(RING_SYNC_1(GEN6_BSD_RING_BASE))
+#define GEN6_VVESYNC	(RING_SYNC_2(GEN6_BSD_RING_BASE))
+#define GEN6_BRSYNC	(RING_SYNC_0(BLT_RING_BASE))
+#define GEN6_BVSYNC	(RING_SYNC_1(BLT_RING_BASE))
+#define GEN6_BVESYNC	(RING_SYNC_2(BLT_RING_BASE))
+#define GEN6_VEBSYNC	(RING_SYNC_0(VEBOX_RING_BASE))
+#define GEN6_VERSYNC	(RING_SYNC_1(VEBOX_RING_BASE))
+#define GEN6_VEVSYNC	(RING_SYNC_2(VEBOX_RING_BASE))
+#define GEN6_NOSYNC 0
 #define RING_MAX_IDLE(base)	((base)+0x54)
 #define RING_HWS_PGA(base)	((base)+0x80)
 #define RING_HWS_PGA_GEN6(base)	((base)+0x2080)
@@ -467,6 +614,7 @@
 #define DONE_REG		0x40b0
 #define BSD_HWS_PGA_GEN7	(0x04180)
 #define BLT_HWS_PGA_GEN7	(0x04280)
+#define VEBOX_HWS_PGA_GEN7	(0x04380)
 #define RING_ACTHD(base)	((base)+0x74)
 #define RING_NOPID(base)	((base)+0x94)
 #define RING_IMR(base)		((base)+0xa8)
@@ -527,7 +675,11 @@
 
 #define ERROR_GEN6	0x040a0
 #define GEN7_ERR_INT	0x44040
-#define   ERR_INT_MMIO_UNCLAIMED (1<<13)
+#define   ERR_INT_POISON		(1<<31)
+#define   ERR_INT_MMIO_UNCLAIMED	(1<<13)
+#define   ERR_INT_FIFO_UNDERRUN_C	(1<<6)
+#define   ERR_INT_FIFO_UNDERRUN_B	(1<<3)
+#define   ERR_INT_FIFO_UNDERRUN_A	(1<<0)
 
 #define FPGA_DBG		0x42300
 #define   FPGA_DBG_RM_NOCLAIM	(1<<31)
@@ -583,24 +735,7 @@
 #define VLV_IIR		(VLV_DISPLAY_BASE + 0x20a4)
 #define VLV_IMR		(VLV_DISPLAY_BASE + 0x20a8)
 #define VLV_ISR		(VLV_DISPLAY_BASE + 0x20ac)
-#define   I915_PIPE_CONTROL_NOTIFY_INTERRUPT		(1<<18)
-#define   I915_DISPLAY_PORT_INTERRUPT			(1<<17)
-#define   I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT	(1<<15)
-#define   I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT	(1<<14) /* p-state */
-#define   I915_HWB_OOM_INTERRUPT			(1<<13)
-#define   I915_SYNC_STATUS_INTERRUPT			(1<<12)
-#define   I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT	(1<<11)
-#define   I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT	(1<<10)
-#define   I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT	(1<<9)
-#define   I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT	(1<<8)
-#define   I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT		(1<<7)
-#define   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT		(1<<6)
-#define   I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT		(1<<5)
-#define   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT		(1<<4)
-#define   I915_DEBUG_INTERRUPT				(1<<2)
-#define   I915_USER_INTERRUPT				(1<<1)
-#define   I915_ASLE_INTERRUPT				(1<<0)
-#define   I915_BSD_USER_INTERRUPT                      (1<<25)
+#define VLV_PCBR	(VLV_DISPLAY_BASE + 0x2120)
 #define   DISPLAY_PLANE_FLIP_PENDING(plane) (1<<(11-(plane))) /* A and B only */
 #define EIR		0x020b0
 #define EMR		0x020b4
@@ -617,6 +752,8 @@
 					will not assert AGPBUSY# and will only
 					be delivered when out of C3. */
 #define   INSTPM_FORCE_ORDERING				(1<<7) /* GEN6+ */
+#define   INSTPM_TLB_INVALIDATE	(1<<9)
+#define   INSTPM_SYNC_FLUSH	(1<<5)
 #define ACTHD	        0x020c8
 #define FW_BLC		0x020d8
 #define FW_BLC2		0x020dc
@@ -712,28 +849,6 @@
 #define CACHE_MODE_1		0x7004 /* IVB+ */
 #define   PIXEL_SUBSPAN_COLLECT_OPT_DISABLE (1<<6)
 
-/* GEN6 interrupt control
- * Note that the per-ring interrupt bits do alias with the global interrupt bits
- * in GTIMR. */
-#define GEN6_RENDER_HWSTAM	0x2098
-#define GEN6_RENDER_IMR		0x20a8
-#define   GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT		(1 << 8)
-#define   GEN6_RENDER_PPGTT_PAGE_FAULT			(1 << 7)
-#define   GEN6_RENDER_TIMEOUT_COUNTER_EXPIRED		(1 << 6)
-#define   GEN6_RENDER_L3_PARITY_ERROR			(1 << 5)
-#define   GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT	(1 << 4)
-#define   GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR	(1 << 3)
-#define   GEN6_RENDER_SYNC_STATUS			(1 << 2)
-#define   GEN6_RENDER_DEBUG_INTERRUPT			(1 << 1)
-#define   GEN6_RENDER_USER_INTERRUPT			(1 << 0)
-
-#define GEN6_BLITTER_HWSTAM	0x22098
-#define GEN6_BLITTER_IMR	0x220a8
-#define   GEN6_BLITTER_MI_FLUSH_DW_NOTIFY_INTERRUPT	(1 << 26)
-#define   GEN6_BLITTER_COMMAND_PARSER_MASTER_ERROR	(1 << 25)
-#define   GEN6_BLITTER_SYNC_STATUS			(1 << 24)
-#define   GEN6_BLITTER_USER_INTERRUPT			(1 << 22)
-
 #define GEN6_BLITTER_ECOSKPD	0x221d0
 #define   GEN6_BLITTER_LOCK_SHIFT			16
 #define   GEN6_BLITTER_FBC_NOTIFY			(1<<3)
@@ -744,9 +859,52 @@
 #define   GEN6_BSD_SLEEP_INDICATOR	(1 << 3)
 #define   GEN6_BSD_GO_INDICATOR		(1 << 4)
 
-#define GEN6_BSD_HWSTAM			0x12098
-#define GEN6_BSD_IMR			0x120a8
-#define   GEN6_BSD_USER_INTERRUPT	(1 << 12)
+/* On modern GEN architectures interrupt control consists of two sets
+ * of registers. The first set pertains to the ring generating the
+ * interrupt. The second control is for the functional block generating the
+ * interrupt. These are PM, GT, DE, etc.
+ *
+ * Luckily *knocks on wood* all the ring interrupt bits match up with the
+ * GT interrupt bits, so we don't need to duplicate the defines.
+ *
+ * These defines should cover us well from SNB->HSW with minor exceptions
+ * it can also work on ILK.
+ */
+#define GT_BLT_FLUSHDW_NOTIFY_INTERRUPT		(1 << 26)
+#define GT_BLT_CS_ERROR_INTERRUPT		(1 << 25)
+#define GT_BLT_USER_INTERRUPT			(1 << 22)
+#define GT_BSD_CS_ERROR_INTERRUPT		(1 << 15)
+#define GT_BSD_USER_INTERRUPT			(1 << 12)
+#define GT_RENDER_L3_PARITY_ERROR_INTERRUPT	(1 <<  5) /* !snb */
+#define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT	(1 <<  4)
+#define GT_RENDER_CS_MASTER_ERROR_INTERRUPT	(1 <<  3)
+#define GT_RENDER_SYNC_STATUS_INTERRUPT		(1 <<  2)
+#define GT_RENDER_DEBUG_INTERRUPT		(1 <<  1)
+#define GT_RENDER_USER_INTERRUPT		(1 <<  0)
+
+#define PM_VEBOX_CS_ERROR_INTERRUPT		(1 << 12) /* hsw+ */
+#define PM_VEBOX_USER_INTERRUPT			(1 << 10) /* hsw+ */
+
+/* These are all the "old" interrupts */
+#define ILK_BSD_USER_INTERRUPT				(1<<5)
+#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT		(1<<18)
+#define I915_DISPLAY_PORT_INTERRUPT			(1<<17)
+#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT	(1<<15)
+#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT	(1<<14) /* p-state */
+#define I915_HWB_OOM_INTERRUPT				(1<<13)
+#define I915_SYNC_STATUS_INTERRUPT			(1<<12)
+#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT	(1<<11)
+#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT	(1<<10)
+#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT	(1<<9)
+#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT	(1<<8)
+#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT		(1<<7)
+#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT		(1<<6)
+#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT		(1<<5)
+#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT		(1<<4)
+#define I915_DEBUG_INTERRUPT				(1<<2)
+#define I915_USER_INTERRUPT				(1<<1)
+#define I915_ASLE_INTERRUPT				(1<<0)
+#define I915_BSD_USER_INTERRUPT				(1 << 25)
 
 #define GEN6_BSD_RNCID			0x12198
 
@@ -807,7 +965,9 @@
 #define   DPFC_CTL_EN		(1<<31)
 #define   DPFC_CTL_PLANEA	(0<<30)
 #define   DPFC_CTL_PLANEB	(1<<30)
+#define   IVB_DPFC_CTL_PLANE_SHIFT	(29)
 #define   DPFC_CTL_FENCE_EN	(1<<29)
+#define   IVB_DPFC_CTL_FENCE_EN	(1<<28)
 #define   DPFC_CTL_PERSISTENT_MODE	(1<<25)
 #define   DPFC_SR_EN		(1<<10)
 #define   DPFC_CTL_LIMIT_1X	(0<<6)
@@ -840,6 +1000,7 @@
 #define ILK_DPFC_CHICKEN	0x43224
 #define ILK_FBC_RT_BASE		0x2128
 #define   ILK_FBC_RT_VALID	(1<<0)
+#define   SNB_FBC_FRONT_BUFFER	(1<<1)
 
 #define ILK_DISPLAY_CHICKEN1	0x42000
 #define   ILK_FBCQ_DIS		(1<<22)
@@ -855,6 +1016,25 @@
 #define   SNB_CPU_FENCE_ENABLE	(1<<29)
 #define DPFC_CPU_FENCE_OFFSET	0x100104
 
+/* Framebuffer compression for Ivybridge */
+#define IVB_FBC_RT_BASE			0x7020
+
+#define IPS_CTL		0x43408
+#define   IPS_ENABLE	(1 << 31)
+
+#define MSG_FBC_REND_STATE	0x50380
+#define   FBC_REND_NUKE		(1<<2)
+#define   FBC_REND_CACHE_CLEAN	(1<<1)
+
+#define _HSW_PIPE_SLICE_CHICKEN_1_A	0x420B0
+#define _HSW_PIPE_SLICE_CHICKEN_1_B	0x420B4
+#define   HSW_BYPASS_FBC_QUEUE		(1<<22)
+#define HSW_PIPE_SLICE_CHICKEN_1(pipe) _PIPE(pipe, + \
+					     _HSW_PIPE_SLICE_CHICKEN_1_A, + \
+					     _HSW_PIPE_SLICE_CHICKEN_1_B)
+
+#define HSW_CLKGATE_DISABLE_PART_1	0x46500
+#define   HSW_DPFC_GATING_DISABLE	(1<<23)
 
 /*
  * GPIO regs
@@ -963,7 +1143,10 @@
 #define   DPLL_FPA01_P1_POST_DIV_MASK	0x00ff0000 /* i915 */
 #define   DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW	0x00ff8000 /* Pineview */
 #define   DPLL_LOCK_VLV			(1<<15)
+#define   DPLL_INTEGRATED_CRI_CLK_VLV	(1<<14)
 #define   DPLL_INTEGRATED_CLOCK_VLV	(1<<13)
+#define   DPLL_PORTC_READY_MASK		(0xf << 4)
+#define   DPLL_PORTB_READY_MASK		(0xf)
 
 #define   DPLL_FPA01_P1_POST_DIV_MASK_I830	0x001f0000
 /*
@@ -1073,7 +1256,7 @@
 #define  DSTATE_PLL_D3_OFF			(1<<3)
 #define  DSTATE_GFX_CLOCK_GATING		(1<<1)
 #define  DSTATE_DOT_CLOCK_GATING		(1<<0)
-#define DSPCLK_GATE_D		0x6200
+#define DSPCLK_GATE_D	(dev_priv->info->display_mmio_offset + 0x6200)
 # define DPUNIT_B_CLOCK_GATE_DISABLE		(1 << 30) /* 965 */
 # define VSUNIT_CLOCK_GATE_DISABLE		(1 << 29) /* 965 */
 # define VRHUNIT_CLOCK_GATE_DISABLE		(1 << 28) /* 965 */
@@ -1186,6 +1369,8 @@
 #define FW_BLC_SELF_VLV		(VLV_DISPLAY_BASE + 0x6500)
 #define  FW_CSPWRDWNEN		(1<<15)
 
+#define MI_ARB_VLV		(VLV_DISPLAY_BASE + 0x6504)
+
 /*
  * Palette regs
  */
@@ -1535,14 +1720,13 @@
 					 GEN7_CXT_EXTENDED_SIZE(ctx_reg) + \
 					 GEN7_CXT_GT1_SIZE(ctx_reg) + \
 					 GEN7_CXT_VFSTATE_SIZE(ctx_reg))
-#define HSW_CXT_POWER_SIZE(ctx_reg)	((ctx_reg >> 26) & 0x3f)
-#define HSW_CXT_RING_SIZE(ctx_reg)	((ctx_reg >> 23) & 0x7)
-#define HSW_CXT_RENDER_SIZE(ctx_reg)	((ctx_reg >> 15) & 0xff)
-#define HSW_CXT_TOTAL_SIZE(ctx_reg)	(HSW_CXT_POWER_SIZE(ctx_reg) + \
-					 HSW_CXT_RING_SIZE(ctx_reg) + \
-					 HSW_CXT_RENDER_SIZE(ctx_reg) + \
-					 GEN7_CXT_VFSTATE_SIZE(ctx_reg))
-
+/* Haswell does have the CXT_SIZE register however it does not appear to be
+ * valid. Now, docs explain in dwords what is in the context object. The full
+ * size is 70720 bytes, however, the power context and execlist context will
+ * never be saved (power context is stored elsewhere, and execlists don't work
+ * on HSW) - so the final size is 66944 bytes, which rounds to 17 pages.
+ */
+#define HSW_CXT_TOTAL_SIZE		(17 * PAGE_SIZE)
 
 /*
  * Overlay regs
@@ -1674,10 +1858,16 @@
 #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV	(1 << 2)
 
 #define PORT_HOTPLUG_STAT	(dev_priv->info->display_mmio_offset + 0x61114)
-/* HDMI/DP bits are gen4+ */
-#define   PORTB_HOTPLUG_LIVE_STATUS               (1 << 29)
+/*
+ * HDMI/DP bits are gen4+
+ *
+ * WARNING: Bspec for hpd status bits on gen4 seems to be completely confused.
+ * Please check the detailed lore in the commit message for for experimental
+ * evidence.
+ */
+#define   PORTD_HOTPLUG_LIVE_STATUS               (1 << 29)
 #define   PORTC_HOTPLUG_LIVE_STATUS               (1 << 28)
-#define   PORTD_HOTPLUG_LIVE_STATUS               (1 << 27)
+#define   PORTB_HOTPLUG_LIVE_STATUS               (1 << 27)
 #define   PORTD_HOTPLUG_INT_STATUS		(3 << 21)
 #define   PORTC_HOTPLUG_INT_STATUS		(3 << 19)
 #define   PORTB_HOTPLUG_INT_STATUS		(3 << 17)
@@ -1691,6 +1881,12 @@
 /* SDVO is different across gen3/4 */
 #define   SDVOC_HOTPLUG_INT_STATUS_G4X		(1 << 3)
 #define   SDVOB_HOTPLUG_INT_STATUS_G4X		(1 << 2)
+/*
+ * Bspec seems to be seriously misleaded about the SDVO hpd bits on i965g/gm,
+ * since reality corrobates that they're the same as on gen3. But keep these
+ * bits here (and the comment!) to help any other lost wanderers back onto the
+ * right tracks.
+ */
 #define   SDVOC_HOTPLUG_INT_STATUS_I965		(3 << 4)
 #define   SDVOB_HOTPLUG_INT_STATUS_I965		(3 << 2)
 #define   SDVOC_HOTPLUG_INT_STATUS_I915		(1 << 7)
@@ -1702,13 +1898,6 @@
 						 PORTC_HOTPLUG_INT_STATUS | \
 						 PORTD_HOTPLUG_INT_STATUS)
 
-#define HOTPLUG_INT_STATUS_I965			(CRT_HOTPLUG_INT_STATUS | \
-						 SDVOB_HOTPLUG_INT_STATUS_I965 | \
-						 SDVOC_HOTPLUG_INT_STATUS_I965 | \
-						 PORTB_HOTPLUG_INT_STATUS | \
-						 PORTC_HOTPLUG_INT_STATUS | \
-						 PORTD_HOTPLUG_INT_STATUS)
-
 #define HOTPLUG_INT_STATUS_I915			(CRT_HOTPLUG_INT_STATUS | \
 						 SDVOB_HOTPLUG_INT_STATUS_I915 | \
 						 SDVOC_HOTPLUG_INT_STATUS_I915 | \
@@ -1967,6 +2156,10 @@
 #define   BLM_PIPE_A			(0 << 29)
 #define   BLM_PIPE_B			(1 << 29)
 #define   BLM_PIPE_C			(2 << 29) /* ivb + */
+#define   BLM_TRANSCODER_A		BLM_PIPE_A /* hsw */
+#define   BLM_TRANSCODER_B		BLM_PIPE_B
+#define   BLM_TRANSCODER_C		BLM_PIPE_C
+#define   BLM_TRANSCODER_EDP		(3 << 29)
 #define   BLM_PIPE(pipe)		((pipe) << 29)
 #define   BLM_POLARITY_I965		(1 << 28) /* gen4 only */
 #define   BLM_PHASE_IN_INTERUPT_STATUS	(1 << 26)
@@ -2540,9 +2733,7 @@
 #define   DP_PRE_EMPHASIS_SHIFT		22
 
 /* How many wires to use. I guess 3 was too hard */
-#define   DP_PORT_WIDTH_1		(0 << 19)
-#define   DP_PORT_WIDTH_2		(1 << 19)
-#define   DP_PORT_WIDTH_4		(3 << 19)
+#define   DP_PORT_WIDTH(width)		(((width) - 1) << 19)
 #define   DP_PORT_WIDTH_MASK		(7 << 19)
 
 /* Mystic DPCD version 1.1 special mode */
@@ -2646,18 +2837,20 @@
  * which is after the LUTs, so we want the bytes for our color format.
  * For our current usage, this is always 3, one byte for R, G and B.
  */
-#define _PIPEA_GMCH_DATA_M			0x70050
-#define _PIPEB_GMCH_DATA_M			0x71050
+#define _PIPEA_DATA_M_G4X	0x70050
+#define _PIPEB_DATA_M_G4X	0x71050
 
 /* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */
 #define  TU_SIZE(x)             (((x)-1) << 25) /* default size 64 */
+#define  TU_SIZE_SHIFT		25
 #define  TU_SIZE_MASK           (0x3f << 25)
 
 #define  DATA_LINK_M_N_MASK	(0xffffff)
 #define  DATA_LINK_N_MAX	(0x800000)
 
-#define _PIPEA_GMCH_DATA_N			0x70054
-#define _PIPEB_GMCH_DATA_N			0x71054
+#define _PIPEA_DATA_N_G4X	0x70054
+#define _PIPEB_DATA_N_G4X	0x71054
+#define   PIPE_GMCH_DATA_N_MASK			(0xffffff)
 
 /*
  * Computing Link M and N values for the Display Port link
@@ -2670,16 +2863,18 @@
  * Attributes and VB-ID.
  */
 
-#define _PIPEA_DP_LINK_M				0x70060
-#define _PIPEB_DP_LINK_M				0x71060
+#define _PIPEA_LINK_M_G4X	0x70060
+#define _PIPEB_LINK_M_G4X	0x71060
+#define   PIPEA_DP_LINK_M_MASK			(0xffffff)
 
-#define _PIPEA_DP_LINK_N				0x70064
-#define _PIPEB_DP_LINK_N				0x71064
+#define _PIPEA_LINK_N_G4X	0x70064
+#define _PIPEB_LINK_N_G4X	0x71064
+#define   PIPEA_DP_LINK_N_MASK			(0xffffff)
 
-#define PIPE_GMCH_DATA_M(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_M, _PIPEB_GMCH_DATA_M)
-#define PIPE_GMCH_DATA_N(pipe) _PIPE(pipe, _PIPEA_GMCH_DATA_N, _PIPEB_GMCH_DATA_N)
-#define PIPE_DP_LINK_M(pipe) _PIPE(pipe, _PIPEA_DP_LINK_M, _PIPEB_DP_LINK_M)
-#define PIPE_DP_LINK_N(pipe) _PIPE(pipe, _PIPEA_DP_LINK_N, _PIPEB_DP_LINK_N)
+#define PIPE_DATA_M_G4X(pipe) _PIPE(pipe, _PIPEA_DATA_M_G4X, _PIPEB_DATA_M_G4X)
+#define PIPE_DATA_N_G4X(pipe) _PIPE(pipe, _PIPEA_DATA_N_G4X, _PIPEB_DATA_N_G4X)
+#define PIPE_LINK_M_G4X(pipe) _PIPE(pipe, _PIPEA_LINK_M_G4X, _PIPEB_LINK_M_G4X)
+#define PIPE_LINK_N_G4X(pipe) _PIPE(pipe, _PIPEA_LINK_N_G4X, _PIPEB_LINK_N_G4X)
 
 /* Display & cursor control */
 
@@ -2715,6 +2910,7 @@
 #define   PIPECONF_INTERLACED_ILK		(3 << 21)
 #define   PIPECONF_INTERLACED_DBL_ILK		(4 << 21) /* ilk/snb only */
 #define   PIPECONF_PFIT_PF_INTERLACED_DBL_ILK	(5 << 21) /* ilk/snb only */
+#define   PIPECONF_INTERLACE_MODE_MASK		(7 << 21)
 #define   PIPECONF_CXSR_DOWNCLOCK	(1<<16)
 #define   PIPECONF_COLOR_RANGE_SELECT	(1 << 13)
 #define   PIPECONF_BPC_MASK	(0x7 << 5)
@@ -2915,6 +3111,10 @@
 #define WM3S_LP_IVB		0x45128
 #define  WM1S_LP_EN		(1<<31)
 
+#define HSW_WM_LP_VAL(lat, fbc, pri, cur) \
+	(WM3_LP_EN | ((lat) << WM1_LP_LATENCY_SHIFT) | \
+	 ((fbc) << WM1_LP_FBC_SHIFT) | ((pri) << WM1_LP_SR_SHIFT) | (cur))
+
 /* Memory latency timer register */
 #define MLTR_ILK		0x11222
 #define  MLTR_WM1_SHIFT		0
@@ -3294,7 +3494,7 @@
 #define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC)
 #define SPRSURFLIVE(pipe) _PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE)
 
-#define _SPACNTR		0x72180
+#define _SPACNTR		(VLV_DISPLAY_BASE + 0x72180)
 #define   SP_ENABLE			(1<<31)
 #define   SP_GEAMMA_ENABLE		(1<<30)
 #define   SP_PIXFORMAT_MASK		(0xf<<26)
@@ -3313,30 +3513,30 @@
 #define   SP_YUV_ORDER_YVYU		(2<<16)
 #define   SP_YUV_ORDER_VYUY		(3<<16)
 #define   SP_TILED			(1<<10)
-#define _SPALINOFF		0x72184
-#define _SPASTRIDE		0x72188
-#define _SPAPOS			0x7218c
-#define _SPASIZE		0x72190
-#define _SPAKEYMINVAL		0x72194
-#define _SPAKEYMSK		0x72198
-#define _SPASURF		0x7219c
-#define _SPAKEYMAXVAL		0x721a0
-#define _SPATILEOFF		0x721a4
-#define _SPACONSTALPHA		0x721a8
-#define _SPAGAMC		0x721f4
+#define _SPALINOFF		(VLV_DISPLAY_BASE + 0x72184)
+#define _SPASTRIDE		(VLV_DISPLAY_BASE + 0x72188)
+#define _SPAPOS			(VLV_DISPLAY_BASE + 0x7218c)
+#define _SPASIZE		(VLV_DISPLAY_BASE + 0x72190)
+#define _SPAKEYMINVAL		(VLV_DISPLAY_BASE + 0x72194)
+#define _SPAKEYMSK		(VLV_DISPLAY_BASE + 0x72198)
+#define _SPASURF		(VLV_DISPLAY_BASE + 0x7219c)
+#define _SPAKEYMAXVAL		(VLV_DISPLAY_BASE + 0x721a0)
+#define _SPATILEOFF		(VLV_DISPLAY_BASE + 0x721a4)
+#define _SPACONSTALPHA		(VLV_DISPLAY_BASE + 0x721a8)
+#define _SPAGAMC		(VLV_DISPLAY_BASE + 0x721f4)
 
-#define _SPBCNTR		0x72280
-#define _SPBLINOFF		0x72284
-#define _SPBSTRIDE		0x72288
-#define _SPBPOS			0x7228c
-#define _SPBSIZE		0x72290
-#define _SPBKEYMINVAL		0x72294
-#define _SPBKEYMSK		0x72298
-#define _SPBSURF		0x7229c
-#define _SPBKEYMAXVAL		0x722a0
-#define _SPBTILEOFF		0x722a4
-#define _SPBCONSTALPHA		0x722a8
-#define _SPBGAMC		0x722f4
+#define _SPBCNTR		(VLV_DISPLAY_BASE + 0x72280)
+#define _SPBLINOFF		(VLV_DISPLAY_BASE + 0x72284)
+#define _SPBSTRIDE		(VLV_DISPLAY_BASE + 0x72288)
+#define _SPBPOS			(VLV_DISPLAY_BASE + 0x7228c)
+#define _SPBSIZE		(VLV_DISPLAY_BASE + 0x72290)
+#define _SPBKEYMINVAL		(VLV_DISPLAY_BASE + 0x72294)
+#define _SPBKEYMSK		(VLV_DISPLAY_BASE + 0x72298)
+#define _SPBSURF		(VLV_DISPLAY_BASE + 0x7229c)
+#define _SPBKEYMAXVAL		(VLV_DISPLAY_BASE + 0x722a0)
+#define _SPBTILEOFF		(VLV_DISPLAY_BASE + 0x722a4)
+#define _SPBCONSTALPHA		(VLV_DISPLAY_BASE + 0x722a8)
+#define _SPBGAMC		(VLV_DISPLAY_BASE + 0x722f4)
 
 #define SPCNTR(pipe, plane) _PIPE(pipe * 2 + plane, _SPACNTR, _SPBCNTR)
 #define SPLINOFF(pipe, plane) _PIPE(pipe * 2 + plane, _SPALINOFF, _SPBLINOFF)
@@ -3474,6 +3674,15 @@
 #define _LGC_PALETTE_B           0x4a800
 #define LGC_PALETTE(pipe) _PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B)
 
+#define _GAMMA_MODE_A		0x4a480
+#define _GAMMA_MODE_B		0x4ac80
+#define GAMMA_MODE(pipe) _PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B)
+#define GAMMA_MODE_MODE_MASK	(3 << 0)
+#define GAMMA_MODE_MODE_8BIT	(0 << 0)
+#define GAMMA_MODE_MODE_10BIT	(1 << 0)
+#define GAMMA_MODE_MODE_12BIT	(2 << 0)
+#define GAMMA_MODE_MODE_SPLIT	(3 << 0)
+
 /* interrupts */
 #define DE_MASTER_IRQ_CONTROL   (1 << 31)
 #define DE_SPRITEB_FLIP_DONE    (1 << 29)
@@ -3502,7 +3711,7 @@
 #define DE_PIPEA_FIFO_UNDERRUN  (1 << 0)
 
 /* More Ivybridge lolz */
-#define DE_ERR_DEBUG_IVB		(1<<30)
+#define DE_ERR_INT_IVB			(1<<30)
 #define DE_GSE_IVB			(1<<29)
 #define DE_PCH_EVENT_IVB		(1<<28)
 #define DE_DP_A_HOTPLUG_IVB		(1<<27)
@@ -3525,21 +3734,6 @@
 #define DEIIR   0x44008
 #define DEIER   0x4400c
 
-/* GT interrupt.
- * Note that for gen6+ the ring-specific interrupt bits do alias with the
- * corresponding bits in the per-ring interrupt control registers. */
-#define GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT	(1 << 26)
-#define GT_GEN6_BLT_CS_ERROR_INTERRUPT		(1 << 25)
-#define GT_GEN6_BLT_USER_INTERRUPT		(1 << 22)
-#define GT_GEN6_BSD_CS_ERROR_INTERRUPT		(1 << 15)
-#define GT_GEN6_BSD_USER_INTERRUPT		(1 << 12)
-#define GT_BSD_USER_INTERRUPT			(1 << 5) /* ilk only */
-#define GT_GEN7_L3_PARITY_ERROR_INTERRUPT	(1 << 5)
-#define GT_PIPE_NOTIFY				(1 << 4)
-#define GT_RENDER_CS_ERROR_INTERRUPT		(1 << 3)
-#define GT_SYNC_STATUS				(1 << 2)
-#define GT_USER_INTERRUPT			(1 << 0)
-
 #define GTISR   0x44010
 #define GTIMR   0x44014
 #define GTIIR   0x44018
@@ -3569,6 +3763,9 @@
 # define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE	(1 << 5)
 # define CHICKEN3_DGMG_DONE_FIX_DISABLE		(1 << 2)
 
+#define CHICKEN_PAR1_1		0x42080
+#define  FORCE_ARB_IDLE_PLANES	(1 << 14)
+
 #define DISP_ARB_CTL	0x45000
 #define  DISP_TILE_SURFACE_SWIZZLING	(1<<13)
 #define  DISP_FBC_WM_DIS		(1<<15)
@@ -3661,6 +3858,7 @@
 				 SDE_PORTC_HOTPLUG_CPT |	\
 				 SDE_PORTB_HOTPLUG_CPT)
 #define SDE_GMBUS_CPT		(1 << 17)
+#define SDE_ERROR_CPT		(1 << 16)
 #define SDE_AUDIO_CP_REQ_C_CPT	(1 << 10)
 #define SDE_AUDIO_CP_CHG_C_CPT	(1 << 9)
 #define SDE_FDI_RXC_CPT		(1 << 8)
@@ -3685,6 +3883,12 @@
 #define SDEIIR  0xc4008
 #define SDEIER  0xc400c
 
+#define SERR_INT			0xc4040
+#define  SERR_INT_POISON		(1<<31)
+#define  SERR_INT_TRANS_C_FIFO_UNDERRUN	(1<<6)
+#define  SERR_INT_TRANS_B_FIFO_UNDERRUN	(1<<3)
+#define  SERR_INT_TRANS_A_FIFO_UNDERRUN	(1<<0)
+
 /* digital port hotplug */
 #define PCH_PORT_HOTPLUG        0xc4030		/* SHOTPLUG_CTL */
 #define PORTD_HOTPLUG_ENABLE            (1 << 20)
@@ -3734,15 +3938,15 @@
 
 #define _PCH_DPLL_A              0xc6014
 #define _PCH_DPLL_B              0xc6018
-#define _PCH_DPLL(pll) (pll == 0 ? _PCH_DPLL_A : _PCH_DPLL_B)
+#define PCH_DPLL(pll) (pll == 0 ? _PCH_DPLL_A : _PCH_DPLL_B)
 
 #define _PCH_FPA0                0xc6040
 #define  FP_CB_TUNE		(0x3<<22)
 #define _PCH_FPA1                0xc6044
 #define _PCH_FPB0                0xc6048
 #define _PCH_FPB1                0xc604c
-#define _PCH_FP0(pll) (pll == 0 ? _PCH_FPA0 : _PCH_FPB0)
-#define _PCH_FP1(pll) (pll == 0 ? _PCH_FPA1 : _PCH_FPB1)
+#define PCH_FP0(pll) (pll == 0 ? _PCH_FPA0 : _PCH_FPB0)
+#define PCH_FP1(pll) (pll == 0 ? _PCH_FPA1 : _PCH_FPB1)
 
 #define PCH_DPLL_TEST           0xc606c
 
@@ -3782,46 +3986,40 @@
 #define PCH_SSC4_AUX_PARMS      0xc6214
 
 #define PCH_DPLL_SEL		0xc7000
-#define  TRANSA_DPLL_ENABLE	(1<<3)
-#define	 TRANSA_DPLLB_SEL	(1<<0)
-#define	 TRANSA_DPLLA_SEL	0
-#define  TRANSB_DPLL_ENABLE	(1<<7)
-#define	 TRANSB_DPLLB_SEL	(1<<4)
-#define	 TRANSB_DPLLA_SEL	(0)
-#define  TRANSC_DPLL_ENABLE	(1<<11)
-#define	 TRANSC_DPLLB_SEL	(1<<8)
-#define	 TRANSC_DPLLA_SEL	(0)
+#define	 TRANS_DPLLB_SEL(pipe)		(1 << (pipe * 4))
+#define	 TRANS_DPLLA_SEL(pipe)		0
+#define  TRANS_DPLL_ENABLE(pipe)	(1 << (pipe * 4 + 3))
 
 /* transcoder */
 
-#define _TRANS_HTOTAL_A          0xe0000
-#define  TRANS_HTOTAL_SHIFT     16
-#define  TRANS_HACTIVE_SHIFT    0
-#define _TRANS_HBLANK_A          0xe0004
-#define  TRANS_HBLANK_END_SHIFT 16
-#define  TRANS_HBLANK_START_SHIFT 0
-#define _TRANS_HSYNC_A           0xe0008
-#define  TRANS_HSYNC_END_SHIFT  16
-#define  TRANS_HSYNC_START_SHIFT 0
-#define _TRANS_VTOTAL_A          0xe000c
-#define  TRANS_VTOTAL_SHIFT     16
-#define  TRANS_VACTIVE_SHIFT    0
-#define _TRANS_VBLANK_A          0xe0010
-#define  TRANS_VBLANK_END_SHIFT 16
-#define  TRANS_VBLANK_START_SHIFT 0
-#define _TRANS_VSYNC_A           0xe0014
-#define  TRANS_VSYNC_END_SHIFT  16
-#define  TRANS_VSYNC_START_SHIFT 0
-#define _TRANS_VSYNCSHIFT_A	0xe0028
+#define _PCH_TRANS_HTOTAL_A		0xe0000
+#define  TRANS_HTOTAL_SHIFT		16
+#define  TRANS_HACTIVE_SHIFT		0
+#define _PCH_TRANS_HBLANK_A		0xe0004
+#define  TRANS_HBLANK_END_SHIFT		16
+#define  TRANS_HBLANK_START_SHIFT	0
+#define _PCH_TRANS_HSYNC_A		0xe0008
+#define  TRANS_HSYNC_END_SHIFT		16
+#define  TRANS_HSYNC_START_SHIFT	0
+#define _PCH_TRANS_VTOTAL_A		0xe000c
+#define  TRANS_VTOTAL_SHIFT		16
+#define  TRANS_VACTIVE_SHIFT		0
+#define _PCH_TRANS_VBLANK_A		0xe0010
+#define  TRANS_VBLANK_END_SHIFT		16
+#define  TRANS_VBLANK_START_SHIFT	0
+#define _PCH_TRANS_VSYNC_A		0xe0014
+#define  TRANS_VSYNC_END_SHIFT	 	16
+#define  TRANS_VSYNC_START_SHIFT	0
+#define _PCH_TRANS_VSYNCSHIFT_A		0xe0028
 
-#define _TRANSA_DATA_M1          0xe0030
-#define _TRANSA_DATA_N1          0xe0034
-#define _TRANSA_DATA_M2          0xe0038
-#define _TRANSA_DATA_N2          0xe003c
-#define _TRANSA_DP_LINK_M1       0xe0040
-#define _TRANSA_DP_LINK_N1       0xe0044
-#define _TRANSA_DP_LINK_M2       0xe0048
-#define _TRANSA_DP_LINK_N2       0xe004c
+#define _PCH_TRANSA_DATA_M1	0xe0030
+#define _PCH_TRANSA_DATA_N1	0xe0034
+#define _PCH_TRANSA_DATA_M2	0xe0038
+#define _PCH_TRANSA_DATA_N2	0xe003c
+#define _PCH_TRANSA_LINK_M1	0xe0040
+#define _PCH_TRANSA_LINK_N1	0xe0044
+#define _PCH_TRANSA_LINK_M2	0xe0048
+#define _PCH_TRANSA_LINK_N2	0xe004c
 
 /* Per-transcoder DIP controls */
 
@@ -3890,44 +4088,45 @@
 #define HSW_TVIDEO_DIP_VSC_DATA(trans) \
 	 _TRANSCODER(trans, HSW_VIDEO_DIP_VSC_DATA_A, HSW_VIDEO_DIP_VSC_DATA_B)
 
-#define _TRANS_HTOTAL_B          0xe1000
-#define _TRANS_HBLANK_B          0xe1004
-#define _TRANS_HSYNC_B           0xe1008
-#define _TRANS_VTOTAL_B          0xe100c
-#define _TRANS_VBLANK_B          0xe1010
-#define _TRANS_VSYNC_B           0xe1014
-#define _TRANS_VSYNCSHIFT_B	 0xe1028
+#define _PCH_TRANS_HTOTAL_B          0xe1000
+#define _PCH_TRANS_HBLANK_B          0xe1004
+#define _PCH_TRANS_HSYNC_B           0xe1008
+#define _PCH_TRANS_VTOTAL_B          0xe100c
+#define _PCH_TRANS_VBLANK_B          0xe1010
+#define _PCH_TRANS_VSYNC_B           0xe1014
+#define _PCH_TRANS_VSYNCSHIFT_B	 0xe1028
 
-#define TRANS_HTOTAL(pipe) _PIPE(pipe, _TRANS_HTOTAL_A, _TRANS_HTOTAL_B)
-#define TRANS_HBLANK(pipe) _PIPE(pipe, _TRANS_HBLANK_A, _TRANS_HBLANK_B)
-#define TRANS_HSYNC(pipe) _PIPE(pipe, _TRANS_HSYNC_A, _TRANS_HSYNC_B)
-#define TRANS_VTOTAL(pipe) _PIPE(pipe, _TRANS_VTOTAL_A, _TRANS_VTOTAL_B)
-#define TRANS_VBLANK(pipe) _PIPE(pipe, _TRANS_VBLANK_A, _TRANS_VBLANK_B)
-#define TRANS_VSYNC(pipe) _PIPE(pipe, _TRANS_VSYNC_A, _TRANS_VSYNC_B)
-#define TRANS_VSYNCSHIFT(pipe) _PIPE(pipe, _TRANS_VSYNCSHIFT_A, \
-				     _TRANS_VSYNCSHIFT_B)
+#define PCH_TRANS_HTOTAL(pipe) _PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B)
+#define PCH_TRANS_HBLANK(pipe) _PIPE(pipe, _PCH_TRANS_HBLANK_A, _PCH_TRANS_HBLANK_B)
+#define PCH_TRANS_HSYNC(pipe) _PIPE(pipe, _PCH_TRANS_HSYNC_A, _PCH_TRANS_HSYNC_B)
+#define PCH_TRANS_VTOTAL(pipe) _PIPE(pipe, _PCH_TRANS_VTOTAL_A, _PCH_TRANS_VTOTAL_B)
+#define PCH_TRANS_VBLANK(pipe) _PIPE(pipe, _PCH_TRANS_VBLANK_A, _PCH_TRANS_VBLANK_B)
+#define PCH_TRANS_VSYNC(pipe) _PIPE(pipe, _PCH_TRANS_VSYNC_A, _PCH_TRANS_VSYNC_B)
+#define PCH_TRANS_VSYNCSHIFT(pipe) _PIPE(pipe, _PCH_TRANS_VSYNCSHIFT_A, \
+					 _PCH_TRANS_VSYNCSHIFT_B)
 
-#define _TRANSB_DATA_M1          0xe1030
-#define _TRANSB_DATA_N1          0xe1034
-#define _TRANSB_DATA_M2          0xe1038
-#define _TRANSB_DATA_N2          0xe103c
-#define _TRANSB_DP_LINK_M1       0xe1040
-#define _TRANSB_DP_LINK_N1       0xe1044
-#define _TRANSB_DP_LINK_M2       0xe1048
-#define _TRANSB_DP_LINK_N2       0xe104c
+#define _PCH_TRANSB_DATA_M1	0xe1030
+#define _PCH_TRANSB_DATA_N1	0xe1034
+#define _PCH_TRANSB_DATA_M2	0xe1038
+#define _PCH_TRANSB_DATA_N2	0xe103c
+#define _PCH_TRANSB_LINK_M1	0xe1040
+#define _PCH_TRANSB_LINK_N1	0xe1044
+#define _PCH_TRANSB_LINK_M2	0xe1048
+#define _PCH_TRANSB_LINK_N2	0xe104c
 
-#define TRANSDATA_M1(pipe) _PIPE(pipe, _TRANSA_DATA_M1, _TRANSB_DATA_M1)
-#define TRANSDATA_N1(pipe) _PIPE(pipe, _TRANSA_DATA_N1, _TRANSB_DATA_N1)
-#define TRANSDATA_M2(pipe) _PIPE(pipe, _TRANSA_DATA_M2, _TRANSB_DATA_M2)
-#define TRANSDATA_N2(pipe) _PIPE(pipe, _TRANSA_DATA_N2, _TRANSB_DATA_N2)
-#define TRANSDPLINK_M1(pipe) _PIPE(pipe, _TRANSA_DP_LINK_M1, _TRANSB_DP_LINK_M1)
-#define TRANSDPLINK_N1(pipe) _PIPE(pipe, _TRANSA_DP_LINK_N1, _TRANSB_DP_LINK_N1)
-#define TRANSDPLINK_M2(pipe) _PIPE(pipe, _TRANSA_DP_LINK_M2, _TRANSB_DP_LINK_M2)
-#define TRANSDPLINK_N2(pipe) _PIPE(pipe, _TRANSA_DP_LINK_N2, _TRANSB_DP_LINK_N2)
+#define PCH_TRANS_DATA_M1(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_M1, _PCH_TRANSB_DATA_M1)
+#define PCH_TRANS_DATA_N1(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_N1, _PCH_TRANSB_DATA_N1)
+#define PCH_TRANS_DATA_M2(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_M2, _PCH_TRANSB_DATA_M2)
+#define PCH_TRANS_DATA_N2(pipe) _PIPE(pipe, _PCH_TRANSA_DATA_N2, _PCH_TRANSB_DATA_N2)
+#define PCH_TRANS_LINK_M1(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_M1, _PCH_TRANSB_LINK_M1)
+#define PCH_TRANS_LINK_N1(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_N1, _PCH_TRANSB_LINK_N1)
+#define PCH_TRANS_LINK_M2(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_M2, _PCH_TRANSB_LINK_M2)
+#define PCH_TRANS_LINK_N2(pipe) _PIPE(pipe, _PCH_TRANSA_LINK_N2, _PCH_TRANSB_LINK_N2)
 
-#define _TRANSACONF              0xf0008
-#define _TRANSBCONF              0xf1008
-#define TRANSCONF(plane) _PIPE(plane, _TRANSACONF, _TRANSBCONF)
+#define _PCH_TRANSACONF              0xf0008
+#define _PCH_TRANSBCONF              0xf1008
+#define PCH_TRANSCONF(pipe) _PIPE(pipe, _PCH_TRANSACONF, _PCH_TRANSBCONF)
+#define LPT_TRANSCONF		_PCH_TRANSACONF /* lpt has only one transcoder */
 #define  TRANS_DISABLE          (0<<31)
 #define  TRANS_ENABLE           (1<<31)
 #define  TRANS_STATE_MASK       (1<<30)
@@ -4011,10 +4210,9 @@
 #define  FDI_LINK_TRAIN_600MV_3_5DB_SNB_B	(0x39<<22)
 #define  FDI_LINK_TRAIN_800MV_0DB_SNB_B		(0x38<<22)
 #define  FDI_LINK_TRAIN_VOL_EMP_MASK		(0x3f<<22)
-#define  FDI_DP_PORT_WIDTH_X1           (0<<19)
-#define  FDI_DP_PORT_WIDTH_X2           (1<<19)
-#define  FDI_DP_PORT_WIDTH_X3           (2<<19)
-#define  FDI_DP_PORT_WIDTH_X4           (3<<19)
+#define  FDI_DP_PORT_WIDTH_SHIFT		19
+#define  FDI_DP_PORT_WIDTH_MASK			(7 << FDI_DP_PORT_WIDTH_SHIFT)
+#define  FDI_DP_PORT_WIDTH(width)           (((width) - 1) << FDI_DP_PORT_WIDTH_SHIFT)
 #define  FDI_TX_ENHANCE_FRAME_ENABLE    (1<<18)
 /* Ironlake: hardwired to 1 */
 #define  FDI_TX_PLL_ENABLE              (1<<14)
@@ -4039,7 +4237,6 @@
 /* train, dp width same as FDI_TX */
 #define  FDI_FS_ERRC_ENABLE		(1<<27)
 #define  FDI_FE_ERRC_ENABLE		(1<<26)
-#define  FDI_DP_PORT_WIDTH_X8           (7<<19)
 #define  FDI_RX_POLARITY_REVERSED_LPT	(1<<16)
 #define  FDI_8BPC                       (0<<16)
 #define  FDI_10BPC                      (1<<16)
@@ -4061,9 +4258,6 @@
 #define  FDI_LINK_TRAIN_PATTERN_IDLE_CPT	(2<<8)
 #define  FDI_LINK_TRAIN_NORMAL_CPT		(3<<8)
 #define  FDI_LINK_TRAIN_PATTERN_MASK_CPT	(3<<8)
-/* LPT */
-#define  FDI_PORT_WIDTH_2X_LPT			(1<<19)
-#define  FDI_PORT_WIDTH_1X_LPT			(0<<19)
 
 #define _FDI_RXA_MISC			0xf0010
 #define _FDI_RXB_MISC			0xf1010
@@ -4309,6 +4503,7 @@
 #define   GEN6_RC_CTL_RC6_ENABLE		(1<<18)
 #define   GEN6_RC_CTL_RC1e_ENABLE		(1<<20)
 #define   GEN6_RC_CTL_RC7_ENABLE		(1<<22)
+#define   GEN7_RC_CTL_TO_MODE			(1<<28)
 #define   GEN6_RC_CTL_EI_MODE(x)		((x)<<27)
 #define   GEN6_RC_CTL_HW_ENABLE			(1<<31)
 #define GEN6_RP_DOWN_TIMEOUT			0xA010
@@ -4370,7 +4565,7 @@
 #define  GEN6_PM_RP_DOWN_THRESHOLD		(1<<4)
 #define  GEN6_PM_RP_UP_EI_EXPIRED		(1<<2)
 #define  GEN6_PM_RP_DOWN_EI_EXPIRED		(1<<1)
-#define  GEN6_PM_DEFERRED_EVENTS		(GEN6_PM_RP_UP_THRESHOLD | \
+#define  GEN6_PM_RPS_EVENTS			(GEN6_PM_RP_UP_THRESHOLD | \
 						 GEN6_PM_RP_DOWN_THRESHOLD | \
 						 GEN6_PM_RP_DOWN_TIMEOUT)
 
@@ -4392,20 +4587,6 @@
 #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT	8
 #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT	16
 
-#define VLV_IOSF_DOORBELL_REQ			0x182100
-#define   IOSF_DEVFN_SHIFT			24
-#define   IOSF_OPCODE_SHIFT			16
-#define   IOSF_PORT_SHIFT			8
-#define   IOSF_BYTE_ENABLES_SHIFT		4
-#define   IOSF_BAR_SHIFT			1
-#define   IOSF_SB_BUSY				(1<<0)
-#define   IOSF_PORT_PUNIT			0x4
-#define VLV_IOSF_DATA				0x182104
-#define VLV_IOSF_ADDR				0x182108
-
-#define PUNIT_OPCODE_REG_READ			6
-#define PUNIT_OPCODE_REG_WRITE			7
-
 #define GEN6_GT_CORE_STATUS		0x138060
 #define   GEN6_CORE_CPD_STATE_MASK	(7<<4)
 #define   GEN6_RCn_MASK			7
@@ -4602,9 +4783,6 @@
 #define  TRANS_DDI_EDP_INPUT_B_ONOFF	(5<<12)
 #define  TRANS_DDI_EDP_INPUT_C_ONOFF	(6<<12)
 #define  TRANS_DDI_BFI_ENABLE		(1<<4)
-#define  TRANS_DDI_PORT_WIDTH_X1	(0<<1)
-#define  TRANS_DDI_PORT_WIDTH_X2	(1<<1)
-#define  TRANS_DDI_PORT_WIDTH_X4	(3<<1)
 
 /* DisplayPort Transport Control */
 #define DP_TP_CTL_A			0x64040
@@ -4648,9 +4826,7 @@
 #define  DDI_BUF_PORT_REVERSAL			(1<<16)
 #define  DDI_BUF_IS_IDLE			(1<<7)
 #define  DDI_A_4_LANES				(1<<4)
-#define  DDI_PORT_WIDTH_X1			(0<<1)
-#define  DDI_PORT_WIDTH_X2			(1<<1)
-#define  DDI_PORT_WIDTH_X4			(3<<1)
+#define  DDI_PORT_WIDTH(width)			(((width) - 1) << 1)
 #define  DDI_INIT_DISPLAY_DETECTED		(1<<0)
 
 /* DDI Buffer Translations */
@@ -4774,6 +4950,9 @@
 #define  SFUSE_STRAP_DDIC_DETECTED	(1<<1)
 #define  SFUSE_STRAP_DDID_DETECTED	(1<<0)
 
+#define WM_MISC				0x45260
+#define  WM_MISC_DATA_PARTITION_5_6	(1 << 0)
+
 #define WM_DBG				0x45280
 #define  WM_DBG_DISALLOW_MULTIPLE_LP	(1<<0)
 #define  WM_DBG_DISALLOW_MAXFIFO	(1<<1)
@@ -4787,6 +4966,9 @@
 #define _PIPE_A_CSC_COEFF_RV_GV	0x49020
 #define _PIPE_A_CSC_COEFF_BV	0x49024
 #define _PIPE_A_CSC_MODE	0x49028
+#define   CSC_BLACK_SCREEN_OFFSET	(1 << 2)
+#define   CSC_POSITION_BEFORE_GAMMA	(1 << 1)
+#define   CSC_MODE_YUV_TO_RGB		(1 << 0)
 #define _PIPE_A_CSC_PREOFF_HI	0x49030
 #define _PIPE_A_CSC_PREOFF_ME	0x49034
 #define _PIPE_A_CSC_PREOFF_LO	0x49038
@@ -4808,10 +4990,6 @@
 #define _PIPE_B_CSC_POSTOFF_ME	0x49144
 #define _PIPE_B_CSC_POSTOFF_LO	0x49148
 
-#define CSC_BLACK_SCREEN_OFFSET (1 << 2)
-#define CSC_POSITION_BEFORE_GAMMA (1 << 1)
-#define CSC_MODE_YUV_TO_RGB (1 << 0)
-
 #define PIPE_CSC_COEFF_RY_GY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RY_GY, _PIPE_B_CSC_COEFF_RY_GY)
 #define PIPE_CSC_COEFF_BY(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_BY, _PIPE_B_CSC_COEFF_BY)
 #define PIPE_CSC_COEFF_RU_GU(pipe) _PIPE(pipe, _PIPE_A_CSC_COEFF_RU_GU, _PIPE_B_CSC_COEFF_RU_GU)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_suspend.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_suspend.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_suspend.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_suspend.c	2013-08-25 20:43:22.000000000 -0400
@@ -192,6 +192,7 @@ static void i915_restore_vga(struct drm_
 static void i915_save_display(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
 
 	/* Display arbitration control */
 	if (INTEL_INFO(dev)->gen <= 4)
@@ -202,6 +203,8 @@ static void i915_save_display(struct drm
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		i915_save_display_reg(dev);
 
+	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+
 	/* LVDS state */
 	if (HAS_PCH_SPLIT(dev)) {
 		dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
@@ -222,6 +225,8 @@ static void i915_save_display(struct drm
 			dev_priv->regfile.saveLVDS = I915_READ(LVDS);
 	}
 
+	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+
 	if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
 		dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
 
@@ -257,6 +262,7 @@ static void i915_restore_display(struct
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 mask = 0xffffffff;
+	unsigned long flags;
 
 	/* Display arbitration */
 	if (INTEL_INFO(dev)->gen <= 4)
@@ -265,6 +271,8 @@ static void i915_restore_display(struct
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		i915_restore_display_reg(dev);
 
+	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+
 	/* LVDS state */
 	if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
 		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
@@ -304,6 +312,8 @@ static void i915_restore_display(struct
 		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
 	}
 
+	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+
 	/* only restore FBC info on the platform that supports FBC*/
 	intel_disable_fbc(dev);
 	if (I915_HAS_FBC(dev)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_sysfs.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_sysfs.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -212,7 +212,13 @@ static ssize_t gt_cur_freq_mhz_show(stru
 	int ret;
 
 	mutex_lock(&dev_priv->rps.hw_lock);
-	ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER;
+	if (IS_VALLEYVIEW(dev_priv->dev)) {
+		u32 freq;
+		freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+		ret = vlv_gpu_freq(dev_priv->mem_freq, (freq >> 8) & 0xff);
+	} else {
+		ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER;
+	}
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
 	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
@@ -226,7 +232,10 @@ static ssize_t gt_max_freq_mhz_show(stru
 	int ret;
 
 	mutex_lock(&dev_priv->rps.hw_lock);
-	ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
+	if (IS_VALLEYVIEW(dev_priv->dev))
+		ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.max_delay);
+	else
+		ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
 	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
@@ -246,16 +255,25 @@ static ssize_t gt_max_freq_mhz_store(str
 	if (ret)
 		return ret;
 
-	val /= GT_FREQUENCY_MULTIPLIER;
-
 	mutex_lock(&dev_priv->rps.hw_lock);
 
-	rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
-	hw_max = dev_priv->rps.hw_max;
-	non_oc_max = (rp_state_cap & 0xff);
-	hw_min = ((rp_state_cap & 0xff0000) >> 16);
+	if (IS_VALLEYVIEW(dev_priv->dev)) {
+		val = vlv_freq_opcode(dev_priv->mem_freq, val);
 
-	if (val < hw_min || val > hw_max || val < dev_priv->rps.min_delay) {
+		hw_max = valleyview_rps_max_freq(dev_priv);
+		hw_min = valleyview_rps_min_freq(dev_priv);
+		non_oc_max = hw_max;
+	} else {
+		val /= GT_FREQUENCY_MULTIPLIER;
+
+		rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
+		hw_max = dev_priv->rps.hw_max;
+		non_oc_max = (rp_state_cap & 0xff);
+		hw_min = ((rp_state_cap & 0xff0000) >> 16);
+	}
+
+	if (val < hw_min || val > hw_max ||
+	    val < dev_priv->rps.min_delay) {
 		mutex_unlock(&dev_priv->rps.hw_lock);
 		return -EINVAL;
 	}
@@ -264,8 +282,12 @@ static ssize_t gt_max_freq_mhz_store(str
 		DRM_DEBUG("User requested overclocking to %d\n",
 			  val * GT_FREQUENCY_MULTIPLIER);
 
-	if (dev_priv->rps.cur_delay > val)
-		gen6_set_rps(dev_priv->dev, val);
+	if (dev_priv->rps.cur_delay > val) {
+		if (IS_VALLEYVIEW(dev_priv->dev))
+			valleyview_set_rps(dev_priv->dev, val);
+		else
+			gen6_set_rps(dev_priv->dev, val);
+	}
 
 	dev_priv->rps.max_delay = val;
 
@@ -282,7 +304,10 @@ static ssize_t gt_min_freq_mhz_show(stru
 	int ret;
 
 	mutex_lock(&dev_priv->rps.hw_lock);
-	ret = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
+	if (IS_VALLEYVIEW(dev_priv->dev))
+		ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.min_delay);
+	else
+		ret = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
 	mutex_unlock(&dev_priv->rps.hw_lock);
 
 	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
@@ -302,21 +327,32 @@ static ssize_t gt_min_freq_mhz_store(str
 	if (ret)
 		return ret;
 
-	val /= GT_FREQUENCY_MULTIPLIER;
-
 	mutex_lock(&dev_priv->rps.hw_lock);
 
-	rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
-	hw_max = dev_priv->rps.hw_max;
-	hw_min = ((rp_state_cap & 0xff0000) >> 16);
+	if (IS_VALLEYVIEW(dev)) {
+		val = vlv_freq_opcode(dev_priv->mem_freq, val);
+
+		hw_max = valleyview_rps_max_freq(dev_priv);
+		hw_min = valleyview_rps_min_freq(dev_priv);
+	} else {
+		val /= GT_FREQUENCY_MULTIPLIER;
+
+		rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
+		hw_max = dev_priv->rps.hw_max;
+		hw_min = ((rp_state_cap & 0xff0000) >> 16);
+	}
 
 	if (val < hw_min || val > hw_max || val > dev_priv->rps.max_delay) {
 		mutex_unlock(&dev_priv->rps.hw_lock);
 		return -EINVAL;
 	}
 
-	if (dev_priv->rps.cur_delay < val)
-		gen6_set_rps(dev_priv->dev, val);
+	if (dev_priv->rps.cur_delay < val) {
+		if (IS_VALLEYVIEW(dev))
+			valleyview_set_rps(dev, val);
+		else
+			gen6_set_rps(dev_priv->dev, val);
+	}
 
 	dev_priv->rps.min_delay = val;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_ums.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_ums.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/i915_ums.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/i915_ums.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,7 +41,7 @@ static bool i915_pipe_enabled(struct drm
 		return false;
 
 	if (HAS_PCH_SPLIT(dev))
-		dpll_reg = _PCH_DPLL(pipe);
+		dpll_reg = PCH_DPLL(pipe);
 	else
 		dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B;
 
@@ -148,13 +148,13 @@ void i915_save_display_reg(struct drm_de
 		dev_priv->regfile.savePFA_WIN_SZ = I915_READ(_PFA_WIN_SZ);
 		dev_priv->regfile.savePFA_WIN_POS = I915_READ(_PFA_WIN_POS);
 
-		dev_priv->regfile.saveTRANSACONF = I915_READ(_TRANSACONF);
-		dev_priv->regfile.saveTRANS_HTOTAL_A = I915_READ(_TRANS_HTOTAL_A);
-		dev_priv->regfile.saveTRANS_HBLANK_A = I915_READ(_TRANS_HBLANK_A);
-		dev_priv->regfile.saveTRANS_HSYNC_A = I915_READ(_TRANS_HSYNC_A);
-		dev_priv->regfile.saveTRANS_VTOTAL_A = I915_READ(_TRANS_VTOTAL_A);
-		dev_priv->regfile.saveTRANS_VBLANK_A = I915_READ(_TRANS_VBLANK_A);
-		dev_priv->regfile.saveTRANS_VSYNC_A = I915_READ(_TRANS_VSYNC_A);
+		dev_priv->regfile.saveTRANSACONF = I915_READ(_PCH_TRANSACONF);
+		dev_priv->regfile.saveTRANS_HTOTAL_A = I915_READ(_PCH_TRANS_HTOTAL_A);
+		dev_priv->regfile.saveTRANS_HBLANK_A = I915_READ(_PCH_TRANS_HBLANK_A);
+		dev_priv->regfile.saveTRANS_HSYNC_A = I915_READ(_PCH_TRANS_HSYNC_A);
+		dev_priv->regfile.saveTRANS_VTOTAL_A = I915_READ(_PCH_TRANS_VTOTAL_A);
+		dev_priv->regfile.saveTRANS_VBLANK_A = I915_READ(_PCH_TRANS_VBLANK_A);
+		dev_priv->regfile.saveTRANS_VSYNC_A = I915_READ(_PCH_TRANS_VSYNC_A);
 	}
 
 	dev_priv->regfile.saveDSPACNTR = I915_READ(_DSPACNTR);
@@ -205,13 +205,13 @@ void i915_save_display_reg(struct drm_de
 		dev_priv->regfile.savePFB_WIN_SZ = I915_READ(_PFB_WIN_SZ);
 		dev_priv->regfile.savePFB_WIN_POS = I915_READ(_PFB_WIN_POS);
 
-		dev_priv->regfile.saveTRANSBCONF = I915_READ(_TRANSBCONF);
-		dev_priv->regfile.saveTRANS_HTOTAL_B = I915_READ(_TRANS_HTOTAL_B);
-		dev_priv->regfile.saveTRANS_HBLANK_B = I915_READ(_TRANS_HBLANK_B);
-		dev_priv->regfile.saveTRANS_HSYNC_B = I915_READ(_TRANS_HSYNC_B);
-		dev_priv->regfile.saveTRANS_VTOTAL_B = I915_READ(_TRANS_VTOTAL_B);
-		dev_priv->regfile.saveTRANS_VBLANK_B = I915_READ(_TRANS_VBLANK_B);
-		dev_priv->regfile.saveTRANS_VSYNC_B = I915_READ(_TRANS_VSYNC_B);
+		dev_priv->regfile.saveTRANSBCONF = I915_READ(_PCH_TRANSBCONF);
+		dev_priv->regfile.saveTRANS_HTOTAL_B = I915_READ(_PCH_TRANS_HTOTAL_B);
+		dev_priv->regfile.saveTRANS_HBLANK_B = I915_READ(_PCH_TRANS_HBLANK_B);
+		dev_priv->regfile.saveTRANS_HSYNC_B = I915_READ(_PCH_TRANS_HSYNC_B);
+		dev_priv->regfile.saveTRANS_VTOTAL_B = I915_READ(_PCH_TRANS_VTOTAL_B);
+		dev_priv->regfile.saveTRANS_VBLANK_B = I915_READ(_PCH_TRANS_VBLANK_B);
+		dev_priv->regfile.saveTRANS_VSYNC_B = I915_READ(_PCH_TRANS_VSYNC_B);
 	}
 
 	dev_priv->regfile.saveDSPBCNTR = I915_READ(_DSPBCNTR);
@@ -259,14 +259,14 @@ void i915_save_display_reg(struct drm_de
 		dev_priv->regfile.saveDP_B = I915_READ(DP_B);
 		dev_priv->regfile.saveDP_C = I915_READ(DP_C);
 		dev_priv->regfile.saveDP_D = I915_READ(DP_D);
-		dev_priv->regfile.savePIPEA_GMCH_DATA_M = I915_READ(_PIPEA_GMCH_DATA_M);
-		dev_priv->regfile.savePIPEB_GMCH_DATA_M = I915_READ(_PIPEB_GMCH_DATA_M);
-		dev_priv->regfile.savePIPEA_GMCH_DATA_N = I915_READ(_PIPEA_GMCH_DATA_N);
-		dev_priv->regfile.savePIPEB_GMCH_DATA_N = I915_READ(_PIPEB_GMCH_DATA_N);
-		dev_priv->regfile.savePIPEA_DP_LINK_M = I915_READ(_PIPEA_DP_LINK_M);
-		dev_priv->regfile.savePIPEB_DP_LINK_M = I915_READ(_PIPEB_DP_LINK_M);
-		dev_priv->regfile.savePIPEA_DP_LINK_N = I915_READ(_PIPEA_DP_LINK_N);
-		dev_priv->regfile.savePIPEB_DP_LINK_N = I915_READ(_PIPEB_DP_LINK_N);
+		dev_priv->regfile.savePIPEA_GMCH_DATA_M = I915_READ(_PIPEA_DATA_M_G4X);
+		dev_priv->regfile.savePIPEB_GMCH_DATA_M = I915_READ(_PIPEB_DATA_M_G4X);
+		dev_priv->regfile.savePIPEA_GMCH_DATA_N = I915_READ(_PIPEA_DATA_N_G4X);
+		dev_priv->regfile.savePIPEB_GMCH_DATA_N = I915_READ(_PIPEB_DATA_N_G4X);
+		dev_priv->regfile.savePIPEA_DP_LINK_M = I915_READ(_PIPEA_LINK_M_G4X);
+		dev_priv->regfile.savePIPEB_DP_LINK_M = I915_READ(_PIPEB_LINK_M_G4X);
+		dev_priv->regfile.savePIPEA_DP_LINK_N = I915_READ(_PIPEA_LINK_N_G4X);
+		dev_priv->regfile.savePIPEB_DP_LINK_N = I915_READ(_PIPEB_LINK_N_G4X);
 	}
 	/* FIXME: regfile.save TV & SDVO state */
 
@@ -282,14 +282,14 @@ void i915_restore_display_reg(struct drm
 
 	/* Display port ratios (must be done before clock is set) */
 	if (SUPPORTS_INTEGRATED_DP(dev)) {
-		I915_WRITE(_PIPEA_GMCH_DATA_M, dev_priv->regfile.savePIPEA_GMCH_DATA_M);
-		I915_WRITE(_PIPEB_GMCH_DATA_M, dev_priv->regfile.savePIPEB_GMCH_DATA_M);
-		I915_WRITE(_PIPEA_GMCH_DATA_N, dev_priv->regfile.savePIPEA_GMCH_DATA_N);
-		I915_WRITE(_PIPEB_GMCH_DATA_N, dev_priv->regfile.savePIPEB_GMCH_DATA_N);
-		I915_WRITE(_PIPEA_DP_LINK_M, dev_priv->regfile.savePIPEA_DP_LINK_M);
-		I915_WRITE(_PIPEB_DP_LINK_M, dev_priv->regfile.savePIPEB_DP_LINK_M);
-		I915_WRITE(_PIPEA_DP_LINK_N, dev_priv->regfile.savePIPEA_DP_LINK_N);
-		I915_WRITE(_PIPEB_DP_LINK_N, dev_priv->regfile.savePIPEB_DP_LINK_N);
+		I915_WRITE(_PIPEA_DATA_M_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_M);
+		I915_WRITE(_PIPEB_DATA_M_G4X, dev_priv->regfile.savePIPEB_GMCH_DATA_M);
+		I915_WRITE(_PIPEA_DATA_N_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_N);
+		I915_WRITE(_PIPEB_DATA_N_G4X, dev_priv->regfile.savePIPEB_GMCH_DATA_N);
+		I915_WRITE(_PIPEA_LINK_M_G4X, dev_priv->regfile.savePIPEA_DP_LINK_M);
+		I915_WRITE(_PIPEB_LINK_M_G4X, dev_priv->regfile.savePIPEB_DP_LINK_M);
+		I915_WRITE(_PIPEA_LINK_N_G4X, dev_priv->regfile.savePIPEA_DP_LINK_N);
+		I915_WRITE(_PIPEB_LINK_N_G4X, dev_priv->regfile.savePIPEB_DP_LINK_N);
 	}
 
 	/* Fences */
@@ -379,13 +379,13 @@ void i915_restore_display_reg(struct drm
 		I915_WRITE(_PFA_WIN_SZ, dev_priv->regfile.savePFA_WIN_SZ);
 		I915_WRITE(_PFA_WIN_POS, dev_priv->regfile.savePFA_WIN_POS);
 
-		I915_WRITE(_TRANSACONF, dev_priv->regfile.saveTRANSACONF);
-		I915_WRITE(_TRANS_HTOTAL_A, dev_priv->regfile.saveTRANS_HTOTAL_A);
-		I915_WRITE(_TRANS_HBLANK_A, dev_priv->regfile.saveTRANS_HBLANK_A);
-		I915_WRITE(_TRANS_HSYNC_A, dev_priv->regfile.saveTRANS_HSYNC_A);
-		I915_WRITE(_TRANS_VTOTAL_A, dev_priv->regfile.saveTRANS_VTOTAL_A);
-		I915_WRITE(_TRANS_VBLANK_A, dev_priv->regfile.saveTRANS_VBLANK_A);
-		I915_WRITE(_TRANS_VSYNC_A, dev_priv->regfile.saveTRANS_VSYNC_A);
+		I915_WRITE(_PCH_TRANSACONF, dev_priv->regfile.saveTRANSACONF);
+		I915_WRITE(_PCH_TRANS_HTOTAL_A, dev_priv->regfile.saveTRANS_HTOTAL_A);
+		I915_WRITE(_PCH_TRANS_HBLANK_A, dev_priv->regfile.saveTRANS_HBLANK_A);
+		I915_WRITE(_PCH_TRANS_HSYNC_A, dev_priv->regfile.saveTRANS_HSYNC_A);
+		I915_WRITE(_PCH_TRANS_VTOTAL_A, dev_priv->regfile.saveTRANS_VTOTAL_A);
+		I915_WRITE(_PCH_TRANS_VBLANK_A, dev_priv->regfile.saveTRANS_VBLANK_A);
+		I915_WRITE(_PCH_TRANS_VSYNC_A, dev_priv->regfile.saveTRANS_VSYNC_A);
 	}
 
 	/* Restore plane info */
@@ -448,13 +448,13 @@ void i915_restore_display_reg(struct drm
 		I915_WRITE(_PFB_WIN_SZ, dev_priv->regfile.savePFB_WIN_SZ);
 		I915_WRITE(_PFB_WIN_POS, dev_priv->regfile.savePFB_WIN_POS);
 
-		I915_WRITE(_TRANSBCONF, dev_priv->regfile.saveTRANSBCONF);
-		I915_WRITE(_TRANS_HTOTAL_B, dev_priv->regfile.saveTRANS_HTOTAL_B);
-		I915_WRITE(_TRANS_HBLANK_B, dev_priv->regfile.saveTRANS_HBLANK_B);
-		I915_WRITE(_TRANS_HSYNC_B, dev_priv->regfile.saveTRANS_HSYNC_B);
-		I915_WRITE(_TRANS_VTOTAL_B, dev_priv->regfile.saveTRANS_VTOTAL_B);
-		I915_WRITE(_TRANS_VBLANK_B, dev_priv->regfile.saveTRANS_VBLANK_B);
-		I915_WRITE(_TRANS_VSYNC_B, dev_priv->regfile.saveTRANS_VSYNC_B);
+		I915_WRITE(_PCH_TRANSBCONF, dev_priv->regfile.saveTRANSBCONF);
+		I915_WRITE(_PCH_TRANS_HTOTAL_B, dev_priv->regfile.saveTRANS_HTOTAL_B);
+		I915_WRITE(_PCH_TRANS_HBLANK_B, dev_priv->regfile.saveTRANS_HBLANK_B);
+		I915_WRITE(_PCH_TRANS_HSYNC_B, dev_priv->regfile.saveTRANS_HSYNC_B);
+		I915_WRITE(_PCH_TRANS_VTOTAL_B, dev_priv->regfile.saveTRANS_VTOTAL_B);
+		I915_WRITE(_PCH_TRANS_VBLANK_B, dev_priv->regfile.saveTRANS_VBLANK_B);
+		I915_WRITE(_PCH_TRANS_VSYNC_B, dev_priv->regfile.saveTRANS_VSYNC_B);
 	}
 
 	/* Restore plane info */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_bios.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_bios.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_bios.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_bios.c	2013-08-25 20:43:22.000000000 -0400
@@ -212,7 +212,7 @@ parse_lfp_panel_data(struct drm_i915_pri
 	if (!lvds_options)
 		return;
 
-	dev_priv->lvds_dither = lvds_options->pixel_dither;
+	dev_priv->vbt.lvds_dither = lvds_options->pixel_dither;
 	if (lvds_options->panel_type == 0xff)
 		return;
 
@@ -226,7 +226,7 @@ parse_lfp_panel_data(struct drm_i915_pri
 	if (!lvds_lfp_data_ptrs)
 		return;
 
-	dev_priv->lvds_vbt = 1;
+	dev_priv->vbt.lvds_vbt = 1;
 
 	panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data,
 					       lvds_lfp_data_ptrs,
@@ -238,7 +238,7 @@ parse_lfp_panel_data(struct drm_i915_pri
 
 	fill_detail_timing_data(panel_fixed_mode, panel_dvo_timing);
 
-	dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
+	dev_priv->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
 
 	DRM_DEBUG_KMS("Found panel mode in BIOS VBT tables:\n");
 	drm_mode_debug_printmodeline(panel_fixed_mode);
@@ -274,9 +274,9 @@ parse_lfp_panel_data(struct drm_i915_pri
 		/* check the resolution, just to be sure */
 		if (fp_timing->x_res == panel_fixed_mode->hdisplay &&
 		    fp_timing->y_res == panel_fixed_mode->vdisplay) {
-			dev_priv->bios_lvds_val = fp_timing->lvds_reg_val;
+			dev_priv->vbt.bios_lvds_val = fp_timing->lvds_reg_val;
 			DRM_DEBUG_KMS("VBT initial LVDS value %x\n",
-				      dev_priv->bios_lvds_val);
+				      dev_priv->vbt.bios_lvds_val);
 		}
 	}
 }
@@ -316,7 +316,7 @@ parse_sdvo_panel_data(struct drm_i915_pr
 
 	fill_detail_timing_data(panel_fixed_mode, dvo_timing + index);
 
-	dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
+	dev_priv->vbt.sdvo_lvds_vbt_mode = panel_fixed_mode;
 
 	DRM_DEBUG_KMS("Found SDVO panel mode in BIOS VBT tables:\n");
 	drm_mode_debug_printmodeline(panel_fixed_mode);
@@ -345,20 +345,20 @@ parse_general_features(struct drm_i915_p
 
 	general = find_section(bdb, BDB_GENERAL_FEATURES);
 	if (general) {
-		dev_priv->int_tv_support = general->int_tv_support;
-		dev_priv->int_crt_support = general->int_crt_support;
-		dev_priv->lvds_use_ssc = general->enable_ssc;
-		dev_priv->lvds_ssc_freq =
+		dev_priv->vbt.int_tv_support = general->int_tv_support;
+		dev_priv->vbt.int_crt_support = general->int_crt_support;
+		dev_priv->vbt.lvds_use_ssc = general->enable_ssc;
+		dev_priv->vbt.lvds_ssc_freq =
 			intel_bios_ssc_frequency(dev, general->ssc_freq);
-		dev_priv->display_clock_mode = general->display_clock_mode;
-		dev_priv->fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted;
+		dev_priv->vbt.display_clock_mode = general->display_clock_mode;
+		dev_priv->vbt.fdi_rx_polarity_inverted = general->fdi_rx_polarity_inverted;
 		DRM_DEBUG_KMS("BDB_GENERAL_FEATURES int_tv_support %d int_crt_support %d lvds_use_ssc %d lvds_ssc_freq %d display_clock_mode %d fdi_rx_polarity_inverted %d\n",
-			      dev_priv->int_tv_support,
-			      dev_priv->int_crt_support,
-			      dev_priv->lvds_use_ssc,
-			      dev_priv->lvds_ssc_freq,
-			      dev_priv->display_clock_mode,
-			      dev_priv->fdi_rx_polarity_inverted);
+			      dev_priv->vbt.int_tv_support,
+			      dev_priv->vbt.int_crt_support,
+			      dev_priv->vbt.lvds_use_ssc,
+			      dev_priv->vbt.lvds_ssc_freq,
+			      dev_priv->vbt.display_clock_mode,
+			      dev_priv->vbt.fdi_rx_polarity_inverted);
 	}
 }
 
@@ -375,7 +375,7 @@ parse_general_definitions(struct drm_i91
 			int bus_pin = general->crt_ddc_gmbus_pin;
 			DRM_DEBUG_KMS("crt_ddc_bus_pin: %d\n", bus_pin);
 			if (intel_gmbus_is_port_valid(bus_pin))
-				dev_priv->crt_ddc_pin = bus_pin;
+				dev_priv->vbt.crt_ddc_pin = bus_pin;
 		} else {
 			DRM_DEBUG_KMS("BDB_GD too small (%d). Invalid.\n",
 				      block_size);
@@ -486,7 +486,7 @@ parse_driver_features(struct drm_i915_pr
 
 	if (SUPPORTS_EDP(dev) &&
 	    driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
-		dev_priv->edp.support = 1;
+		dev_priv->vbt.edp_support = 1;
 
 	if (driver->dual_frequency)
 		dev_priv->render_reclock_avail = true;
@@ -501,20 +501,20 @@ parse_edp(struct drm_i915_private *dev_p
 
 	edp = find_section(bdb, BDB_EDP);
 	if (!edp) {
-		if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support)
+		if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->vbt.edp_support)
 			DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
 		return;
 	}
 
 	switch ((edp->color_depth >> (panel_type * 2)) & 3) {
 	case EDP_18BPP:
-		dev_priv->edp.bpp = 18;
+		dev_priv->vbt.edp_bpp = 18;
 		break;
 	case EDP_24BPP:
-		dev_priv->edp.bpp = 24;
+		dev_priv->vbt.edp_bpp = 24;
 		break;
 	case EDP_30BPP:
-		dev_priv->edp.bpp = 30;
+		dev_priv->vbt.edp_bpp = 30;
 		break;
 	}
 
@@ -522,48 +522,48 @@ parse_edp(struct drm_i915_private *dev_p
 	edp_pps = &edp->power_seqs[panel_type];
 	edp_link_params = &edp->link_params[panel_type];
 
-	dev_priv->edp.pps = *edp_pps;
+	dev_priv->vbt.edp_pps = *edp_pps;
 
-	dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
+	dev_priv->vbt.edp_rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
 		DP_LINK_BW_1_62;
 	switch (edp_link_params->lanes) {
 	case 0:
-		dev_priv->edp.lanes = 1;
+		dev_priv->vbt.edp_lanes = 1;
 		break;
 	case 1:
-		dev_priv->edp.lanes = 2;
+		dev_priv->vbt.edp_lanes = 2;
 		break;
 	case 3:
 	default:
-		dev_priv->edp.lanes = 4;
+		dev_priv->vbt.edp_lanes = 4;
 		break;
 	}
 	switch (edp_link_params->preemphasis) {
 	case 0:
-		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
+		dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
 		break;
 	case 1:
-		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
+		dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
 		break;
 	case 2:
-		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
+		dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
 		break;
 	case 3:
-		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
+		dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
 		break;
 	}
 	switch (edp_link_params->vswing) {
 	case 0:
-		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_400;
+		dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_400;
 		break;
 	case 1:
-		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_600;
+		dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_600;
 		break;
 	case 2:
-		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_800;
+		dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_800;
 		break;
 	case 3:
-		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_1200;
+		dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_1200;
 		break;
 	}
 }
@@ -611,13 +611,13 @@ parse_device_mapping(struct drm_i915_pri
 		DRM_DEBUG_KMS("no child dev is parsed from VBT\n");
 		return;
 	}
-	dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL);
-	if (!dev_priv->child_dev) {
+	dev_priv->vbt.child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL);
+	if (!dev_priv->vbt.child_dev) {
 		DRM_DEBUG_KMS("No memory space for child device\n");
 		return;
 	}
 
-	dev_priv->child_dev_num = count;
+	dev_priv->vbt.child_dev_num = count;
 	count = 0;
 	for (i = 0; i < child_device_num; i++) {
 		p_child = &(p_defs->devices[i]);
@@ -625,7 +625,7 @@ parse_device_mapping(struct drm_i915_pri
 			/* skip the device block if device type is invalid */
 			continue;
 		}
-		child_dev_ptr = dev_priv->child_dev + count;
+		child_dev_ptr = dev_priv->vbt.child_dev + count;
 		count++;
 		memcpy((void *)child_dev_ptr, (void *)p_child,
 					sizeof(*p_child));
@@ -638,23 +638,23 @@ init_vbt_defaults(struct drm_i915_privat
 {
 	struct drm_device *dev = dev_priv->dev;
 
-	dev_priv->crt_ddc_pin = GMBUS_PORT_VGADDC;
+	dev_priv->vbt.crt_ddc_pin = GMBUS_PORT_VGADDC;
 
 	/* LFP panel data */
-	dev_priv->lvds_dither = 1;
-	dev_priv->lvds_vbt = 0;
+	dev_priv->vbt.lvds_dither = 1;
+	dev_priv->vbt.lvds_vbt = 0;
 
 	/* SDVO panel data */
-	dev_priv->sdvo_lvds_vbt_mode = NULL;
+	dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
 
 	/* general features */
-	dev_priv->int_tv_support = 1;
-	dev_priv->int_crt_support = 1;
+	dev_priv->vbt.int_tv_support = 1;
+	dev_priv->vbt.int_crt_support = 1;
 
 	/* Default to using SSC */
-	dev_priv->lvds_use_ssc = 1;
-	dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1);
-	DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
+	dev_priv->vbt.lvds_use_ssc = 1;
+	dev_priv->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1);
+	DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->vbt.lvds_ssc_freq);
 }
 
 static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_crt.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_crt.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_crt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_crt.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,6 +84,28 @@ static bool intel_crt_get_hw_state(struc
 	return true;
 }
 
+static void intel_crt_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_config *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_crt *crt = intel_encoder_to_crt(encoder);
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(crt->adpa_reg);
+
+	if (tmp & ADPA_HSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (tmp & ADPA_VSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 /* Note: The caller is required to filter out dpms modes not supported by the
  * platform. */
 static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
@@ -127,7 +149,7 @@ static void intel_enable_crt(struct inte
 	intel_crt_set_dpms(encoder, crt->connector->base.dpms);
 }
 
-
+/* Special dpms function to support cloning between dvo/sdvo/crt. */
 static void intel_crt_dpms(struct drm_connector *connector, int mode)
 {
 	struct drm_device *dev = connector->dev;
@@ -158,6 +180,8 @@ static void intel_crt_dpms(struct drm_co
 	else
 		encoder->connectors_active = true;
 
+	/* We call connector dpms manually below in case pipe dpms doesn't
+	 * change due to cloning. */
 	if (mode < old_dpms) {
 		/* From off to on, enable the pipe first. */
 		intel_crtc_update_dpms(crtc);
@@ -207,6 +231,10 @@ static bool intel_crt_compute_config(str
 	if (HAS_PCH_SPLIT(dev))
 		pipe_config->has_pch_encoder = true;
 
+	/* LPT FDI RX only supports 8bpc. */
+	if (HAS_PCH_LPT(dev))
+		pipe_config->pipe_bpp = 24;
+
 	return true;
 }
 
@@ -431,7 +459,7 @@ static bool intel_crt_detect_ddc(struct
 
 	BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);
 
-	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin);
+	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
 	edid = intel_crt_get_edid(connector, i2c);
 
 	if (edid) {
@@ -637,7 +665,7 @@ static int intel_crt_get_modes(struct dr
 	int ret;
 	struct i2c_adapter *i2c;
 
-	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin);
+	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin);
 	ret = intel_crt_ddc_get_modes(connector, i2c);
 	if (ret || !IS_G4X(dev))
 		return ret;
@@ -774,6 +802,7 @@ void intel_crt_init(struct drm_device *d
 	crt->base.compute_config = intel_crt_compute_config;
 	crt->base.disable = intel_disable_crt;
 	crt->base.enable = intel_enable_crt;
+	crt->base.get_config = intel_crt_get_config;
 	if (I915_HAS_HOTPLUG(dev))
 		crt->base.hpd_pin = HPD_CRT;
 	if (HAS_DDI(dev))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_ddi.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_ddi.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_ddi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_ddi.c	2013-08-25 20:43:22.000000000 -0400
@@ -174,6 +174,8 @@ void hsw_fdi_link_train(struct drm_crtc
 	 * mode set "sequence for CRT port" document:
 	 * - TP1 to TP2 time with the default value
 	 * - FDI delay to 90h
+	 *
+	 * WaFDIAutoLinkSetTimingOverrride:hsw
 	 */
 	I915_WRITE(_FDI_RXA_MISC, FDI_RX_PWRDN_LANE1_VAL(2) |
 				  FDI_RX_PWRDN_LANE0_VAL(2) |
@@ -181,7 +183,8 @@ void hsw_fdi_link_train(struct drm_crtc
 
 	/* Enable the PCH Receiver FDI PLL */
 	rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
-		     FDI_RX_PLL_ENABLE | ((intel_crtc->fdi_lanes - 1) << 19);
+		     FDI_RX_PLL_ENABLE |
+		     FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
 	I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
 	POSTING_READ(_FDI_RXA_CTL);
 	udelay(220);
@@ -209,7 +212,7 @@ void hsw_fdi_link_train(struct drm_crtc
 		 * port reversal bit */
 		I915_WRITE(DDI_BUF_CTL(PORT_E),
 			   DDI_BUF_CTL_ENABLE |
-			   ((intel_crtc->fdi_lanes - 1) << 1) |
+			   ((intel_crtc->config.fdi_lanes - 1) << 1) |
 			   hsw_ddi_buf_ctl_values[i / 2]);
 		POSTING_READ(DDI_BUF_CTL(PORT_E));
 
@@ -278,392 +281,6 @@ void hsw_fdi_link_train(struct drm_crtc
 	DRM_ERROR("FDI link training failed!\n");
 }
 
-/* WRPLL clock dividers */
-struct wrpll_tmds_clock {
-	u32 clock;
-	u16 p;		/* Post divider */
-	u16 n2;		/* Feedback divider */
-	u16 r2;		/* Reference divider */
-};
-
-/* Table of matching values for WRPLL clocks programming for each frequency.
- * The code assumes this table is sorted. */
-static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
-	{19750,	38,	25,	18},
-	{20000,	48,	32,	18},
-	{21000,	36,	21,	15},
-	{21912,	42,	29,	17},
-	{22000,	36,	22,	15},
-	{23000,	36,	23,	15},
-	{23500,	40,	40,	23},
-	{23750,	26,	16,	14},
-	{24000,	36,	24,	15},
-	{25000,	36,	25,	15},
-	{25175,	26,	40,	33},
-	{25200,	30,	21,	15},
-	{26000,	36,	26,	15},
-	{27000,	30,	21,	14},
-	{27027,	18,	100,	111},
-	{27500,	30,	29,	19},
-	{28000,	34,	30,	17},
-	{28320,	26,	30,	22},
-	{28322,	32,	42,	25},
-	{28750,	24,	23,	18},
-	{29000,	30,	29,	18},
-	{29750,	32,	30,	17},
-	{30000,	30,	25,	15},
-	{30750,	30,	41,	24},
-	{31000,	30,	31,	18},
-	{31500,	30,	28,	16},
-	{32000,	30,	32,	18},
-	{32500,	28,	32,	19},
-	{33000,	24,	22,	15},
-	{34000,	28,	30,	17},
-	{35000,	26,	32,	19},
-	{35500,	24,	30,	19},
-	{36000,	26,	26,	15},
-	{36750,	26,	46,	26},
-	{37000,	24,	23,	14},
-	{37762,	22,	40,	26},
-	{37800,	20,	21,	15},
-	{38000,	24,	27,	16},
-	{38250,	24,	34,	20},
-	{39000,	24,	26,	15},
-	{40000,	24,	32,	18},
-	{40500,	20,	21,	14},
-	{40541,	22,	147,	89},
-	{40750,	18,	19,	14},
-	{41000,	16,	17,	14},
-	{41500,	22,	44,	26},
-	{41540,	22,	44,	26},
-	{42000,	18,	21,	15},
-	{42500,	22,	45,	26},
-	{43000,	20,	43,	27},
-	{43163,	20,	24,	15},
-	{44000,	18,	22,	15},
-	{44900,	20,	108,	65},
-	{45000,	20,	25,	15},
-	{45250,	20,	52,	31},
-	{46000,	18,	23,	15},
-	{46750,	20,	45,	26},
-	{47000,	20,	40,	23},
-	{48000,	18,	24,	15},
-	{49000,	18,	49,	30},
-	{49500,	16,	22,	15},
-	{50000,	18,	25,	15},
-	{50500,	18,	32,	19},
-	{51000,	18,	34,	20},
-	{52000,	18,	26,	15},
-	{52406,	14,	34,	25},
-	{53000,	16,	22,	14},
-	{54000,	16,	24,	15},
-	{54054,	16,	173,	108},
-	{54500,	14,	24,	17},
-	{55000,	12,	22,	18},
-	{56000,	14,	45,	31},
-	{56250,	16,	25,	15},
-	{56750,	14,	25,	17},
-	{57000,	16,	27,	16},
-	{58000,	16,	43,	25},
-	{58250,	16,	38,	22},
-	{58750,	16,	40,	23},
-	{59000,	14,	26,	17},
-	{59341,	14,	40,	26},
-	{59400,	16,	44,	25},
-	{60000,	16,	32,	18},
-	{60500,	12,	39,	29},
-	{61000,	14,	49,	31},
-	{62000,	14,	37,	23},
-	{62250,	14,	42,	26},
-	{63000,	12,	21,	15},
-	{63500,	14,	28,	17},
-	{64000,	12,	27,	19},
-	{65000,	14,	32,	19},
-	{65250,	12,	29,	20},
-	{65500,	12,	32,	22},
-	{66000,	12,	22,	15},
-	{66667,	14,	38,	22},
-	{66750,	10,	21,	17},
-	{67000,	14,	33,	19},
-	{67750,	14,	58,	33},
-	{68000,	14,	30,	17},
-	{68179,	14,	46,	26},
-	{68250,	14,	46,	26},
-	{69000,	12,	23,	15},
-	{70000,	12,	28,	18},
-	{71000,	12,	30,	19},
-	{72000,	12,	24,	15},
-	{73000,	10,	23,	17},
-	{74000,	12,	23,	14},
-	{74176,	8,	100,	91},
-	{74250,	10,	22,	16},
-	{74481,	12,	43,	26},
-	{74500,	10,	29,	21},
-	{75000,	12,	25,	15},
-	{75250,	10,	39,	28},
-	{76000,	12,	27,	16},
-	{77000,	12,	53,	31},
-	{78000,	12,	26,	15},
-	{78750,	12,	28,	16},
-	{79000,	10,	38,	26},
-	{79500,	10,	28,	19},
-	{80000,	12,	32,	18},
-	{81000,	10,	21,	14},
-	{81081,	6,	100,	111},
-	{81624,	8,	29,	24},
-	{82000,	8,	17,	14},
-	{83000,	10,	40,	26},
-	{83950,	10,	28,	18},
-	{84000,	10,	28,	18},
-	{84750,	6,	16,	17},
-	{85000,	6,	17,	18},
-	{85250,	10,	30,	19},
-	{85750,	10,	27,	17},
-	{86000,	10,	43,	27},
-	{87000,	10,	29,	18},
-	{88000,	10,	44,	27},
-	{88500,	10,	41,	25},
-	{89000,	10,	28,	17},
-	{89012,	6,	90,	91},
-	{89100,	10,	33,	20},
-	{90000,	10,	25,	15},
-	{91000,	10,	32,	19},
-	{92000,	10,	46,	27},
-	{93000,	10,	31,	18},
-	{94000,	10,	40,	23},
-	{94500,	10,	28,	16},
-	{95000,	10,	44,	25},
-	{95654,	10,	39,	22},
-	{95750,	10,	39,	22},
-	{96000,	10,	32,	18},
-	{97000,	8,	23,	16},
-	{97750,	8,	42,	29},
-	{98000,	8,	45,	31},
-	{99000,	8,	22,	15},
-	{99750,	8,	34,	23},
-	{100000,	6,	20,	18},
-	{100500,	6,	19,	17},
-	{101000,	6,	37,	33},
-	{101250,	8,	21,	14},
-	{102000,	6,	17,	15},
-	{102250,	6,	25,	22},
-	{103000,	8,	29,	19},
-	{104000,	8,	37,	24},
-	{105000,	8,	28,	18},
-	{106000,	8,	22,	14},
-	{107000,	8,	46,	29},
-	{107214,	8,	27,	17},
-	{108000,	8,	24,	15},
-	{108108,	8,	173,	108},
-	{109000,	6,	23,	19},
-	{110000,	6,	22,	18},
-	{110013,	6,	22,	18},
-	{110250,	8,	49,	30},
-	{110500,	8,	36,	22},
-	{111000,	8,	23,	14},
-	{111264,	8,	150,	91},
-	{111375,	8,	33,	20},
-	{112000,	8,	63,	38},
-	{112500,	8,	25,	15},
-	{113100,	8,	57,	34},
-	{113309,	8,	42,	25},
-	{114000,	8,	27,	16},
-	{115000,	6,	23,	18},
-	{116000,	8,	43,	25},
-	{117000,	8,	26,	15},
-	{117500,	8,	40,	23},
-	{118000,	6,	38,	29},
-	{119000,	8,	30,	17},
-	{119500,	8,	46,	26},
-	{119651,	8,	39,	22},
-	{120000,	8,	32,	18},
-	{121000,	6,	39,	29},
-	{121250,	6,	31,	23},
-	{121750,	6,	23,	17},
-	{122000,	6,	42,	31},
-	{122614,	6,	30,	22},
-	{123000,	6,	41,	30},
-	{123379,	6,	37,	27},
-	{124000,	6,	51,	37},
-	{125000,	6,	25,	18},
-	{125250,	4,	13,	14},
-	{125750,	4,	27,	29},
-	{126000,	6,	21,	15},
-	{127000,	6,	24,	17},
-	{127250,	6,	41,	29},
-	{128000,	6,	27,	19},
-	{129000,	6,	43,	30},
-	{129859,	4,	25,	26},
-	{130000,	6,	26,	18},
-	{130250,	6,	42,	29},
-	{131000,	6,	32,	22},
-	{131500,	6,	38,	26},
-	{131850,	6,	41,	28},
-	{132000,	6,	22,	15},
-	{132750,	6,	28,	19},
-	{133000,	6,	34,	23},
-	{133330,	6,	37,	25},
-	{134000,	6,	61,	41},
-	{135000,	6,	21,	14},
-	{135250,	6,	167,	111},
-	{136000,	6,	62,	41},
-	{137000,	6,	35,	23},
-	{138000,	6,	23,	15},
-	{138500,	6,	40,	26},
-	{138750,	6,	37,	24},
-	{139000,	6,	34,	22},
-	{139050,	6,	34,	22},
-	{139054,	6,	34,	22},
-	{140000,	6,	28,	18},
-	{141000,	6,	36,	23},
-	{141500,	6,	22,	14},
-	{142000,	6,	30,	19},
-	{143000,	6,	27,	17},
-	{143472,	4,	17,	16},
-	{144000,	6,	24,	15},
-	{145000,	6,	29,	18},
-	{146000,	6,	47,	29},
-	{146250,	6,	26,	16},
-	{147000,	6,	49,	30},
-	{147891,	6,	23,	14},
-	{148000,	6,	23,	14},
-	{148250,	6,	28,	17},
-	{148352,	4,	100,	91},
-	{148500,	6,	33,	20},
-	{149000,	6,	48,	29},
-	{150000,	6,	25,	15},
-	{151000,	4,	19,	17},
-	{152000,	6,	27,	16},
-	{152280,	6,	44,	26},
-	{153000,	6,	34,	20},
-	{154000,	6,	53,	31},
-	{155000,	6,	31,	18},
-	{155250,	6,	50,	29},
-	{155750,	6,	45,	26},
-	{156000,	6,	26,	15},
-	{157000,	6,	61,	35},
-	{157500,	6,	28,	16},
-	{158000,	6,	65,	37},
-	{158250,	6,	44,	25},
-	{159000,	6,	53,	30},
-	{159500,	6,	39,	22},
-	{160000,	6,	32,	18},
-	{161000,	4,	31,	26},
-	{162000,	4,	18,	15},
-	{162162,	4,	131,	109},
-	{162500,	4,	53,	44},
-	{163000,	4,	29,	24},
-	{164000,	4,	17,	14},
-	{165000,	4,	22,	18},
-	{166000,	4,	32,	26},
-	{167000,	4,	26,	21},
-	{168000,	4,	46,	37},
-	{169000,	4,	104,	83},
-	{169128,	4,	64,	51},
-	{169500,	4,	39,	31},
-	{170000,	4,	34,	27},
-	{171000,	4,	19,	15},
-	{172000,	4,	51,	40},
-	{172750,	4,	32,	25},
-	{172800,	4,	32,	25},
-	{173000,	4,	41,	32},
-	{174000,	4,	49,	38},
-	{174787,	4,	22,	17},
-	{175000,	4,	35,	27},
-	{176000,	4,	30,	23},
-	{177000,	4,	38,	29},
-	{178000,	4,	29,	22},
-	{178500,	4,	37,	28},
-	{179000,	4,	53,	40},
-	{179500,	4,	73,	55},
-	{180000,	4,	20,	15},
-	{181000,	4,	55,	41},
-	{182000,	4,	31,	23},
-	{183000,	4,	42,	31},
-	{184000,	4,	30,	22},
-	{184750,	4,	26,	19},
-	{185000,	4,	37,	27},
-	{186000,	4,	51,	37},
-	{187000,	4,	36,	26},
-	{188000,	4,	32,	23},
-	{189000,	4,	21,	15},
-	{190000,	4,	38,	27},
-	{190960,	4,	41,	29},
-	{191000,	4,	41,	29},
-	{192000,	4,	27,	19},
-	{192250,	4,	37,	26},
-	{193000,	4,	20,	14},
-	{193250,	4,	53,	37},
-	{194000,	4,	23,	16},
-	{194208,	4,	23,	16},
-	{195000,	4,	26,	18},
-	{196000,	4,	45,	31},
-	{197000,	4,	35,	24},
-	{197750,	4,	41,	28},
-	{198000,	4,	22,	15},
-	{198500,	4,	25,	17},
-	{199000,	4,	28,	19},
-	{200000,	4,	37,	25},
-	{201000,	4,	61,	41},
-	{202000,	4,	112,	75},
-	{202500,	4,	21,	14},
-	{203000,	4,	146,	97},
-	{204000,	4,	62,	41},
-	{204750,	4,	44,	29},
-	{205000,	4,	38,	25},
-	{206000,	4,	29,	19},
-	{207000,	4,	23,	15},
-	{207500,	4,	40,	26},
-	{208000,	4,	37,	24},
-	{208900,	4,	48,	31},
-	{209000,	4,	48,	31},
-	{209250,	4,	31,	20},
-	{210000,	4,	28,	18},
-	{211000,	4,	25,	16},
-	{212000,	4,	22,	14},
-	{213000,	4,	30,	19},
-	{213750,	4,	38,	24},
-	{214000,	4,	46,	29},
-	{214750,	4,	35,	22},
-	{215000,	4,	43,	27},
-	{216000,	4,	24,	15},
-	{217000,	4,	37,	23},
-	{218000,	4,	42,	26},
-	{218250,	4,	42,	26},
-	{218750,	4,	34,	21},
-	{219000,	4,	47,	29},
-	{220000,	4,	44,	27},
-	{220640,	4,	49,	30},
-	{220750,	4,	36,	22},
-	{221000,	4,	36,	22},
-	{222000,	4,	23,	14},
-	{222525,	4,	28,	17},
-	{222750,	4,	33,	20},
-	{227000,	4,	37,	22},
-	{230250,	4,	29,	17},
-	{233500,	4,	38,	22},
-	{235000,	4,	40,	23},
-	{238000,	4,	30,	17},
-	{241500,	2,	17,	19},
-	{245250,	2,	20,	22},
-	{247750,	2,	22,	24},
-	{253250,	2,	15,	16},
-	{256250,	2,	18,	19},
-	{262500,	2,	31,	32},
-	{267250,	2,	66,	67},
-	{268500,	2,	94,	95},
-	{270000,	2,	14,	14},
-	{272500,	2,	77,	76},
-	{273750,	2,	57,	56},
-	{280750,	2,	24,	23},
-	{281250,	2,	23,	22},
-	{286000,	2,	17,	16},
-	{291750,	2,	26,	24},
-	{296703,	2,	56,	51},
-	{297000,	2,	22,	20},
-	{298000,	2,	21,	19},
-};
-
 static void intel_ddi_mode_set(struct drm_encoder *encoder,
 			       struct drm_display_mode *mode,
 			       struct drm_display_mode *adjusted_mode)
@@ -675,7 +292,7 @@ static void intel_ddi_mode_set(struct dr
 	int pipe = intel_crtc->pipe;
 	int type = intel_encoder->type;
 
-	DRM_DEBUG_KMS("Preparing DDI mode for Haswell on port %c, pipe %c\n",
+	DRM_DEBUG_KMS("Preparing DDI mode on port %c, pipe %c\n",
 		      port_name(port), pipe_name(pipe));
 
 	intel_crtc->eld_vld = false;
@@ -684,24 +301,9 @@ static void intel_ddi_mode_set(struct dr
 		struct intel_digital_port *intel_dig_port =
 			enc_to_dig_port(encoder);
 
-		intel_dp->DP = intel_dig_port->port_reversal |
+		intel_dp->DP = intel_dig_port->saved_port_bits |
 			       DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW;
-		switch (intel_dp->lane_count) {
-		case 1:
-			intel_dp->DP |= DDI_PORT_WIDTH_X1;
-			break;
-		case 2:
-			intel_dp->DP |= DDI_PORT_WIDTH_X2;
-			break;
-		case 4:
-			intel_dp->DP |= DDI_PORT_WIDTH_X4;
-			break;
-		default:
-			intel_dp->DP |= DDI_PORT_WIDTH_X4;
-			WARN(1, "Unexpected DP lane count %d\n",
-			     intel_dp->lane_count);
-			break;
-		}
+		intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
 
 		if (intel_dp->has_audio) {
 			DRM_DEBUG_DRIVER("DP audio on pipe %c on DDI\n",
@@ -748,8 +350,8 @@ intel_ddi_get_crtc_encoder(struct drm_cr
 	}
 
 	if (num_encoders != 1)
-		WARN(1, "%d encoders on crtc for pipe %d\n", num_encoders,
-		     intel_crtc->pipe);
+		WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
+		     pipe_name(intel_crtc->pipe));
 
 	BUG_ON(ret == NULL);
 	return ret;
@@ -802,30 +404,227 @@ void intel_ddi_put_crtc_pll(struct drm_c
 	intel_crtc->ddi_pll_sel = PORT_CLK_SEL_NONE;
 }
 
-static void intel_ddi_calculate_wrpll(int clock, int *p, int *n2, int *r2)
+#define LC_FREQ 2700
+#define LC_FREQ_2K (LC_FREQ * 2000)
+
+#define P_MIN 2
+#define P_MAX 64
+#define P_INC 2
+
+/* Constraints for PLL good behavior */
+#define REF_MIN 48
+#define REF_MAX 400
+#define VCO_MIN 2400
+#define VCO_MAX 4800
+
+#define ABS_DIFF(a, b) ((a > b) ? (a - b) : (b - a))
+
+struct wrpll_rnp {
+	unsigned p, n2, r2;
+};
+
+static unsigned wrpll_get_budget_for_freq(int clock)
 {
-	u32 i;
+	unsigned budget;
 
-	for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++)
-		if (clock <= wrpll_tmds_clock_table[i].clock)
-			break;
+	switch (clock) {
+	case 25175000:
+	case 25200000:
+	case 27000000:
+	case 27027000:
+	case 37762500:
+	case 37800000:
+	case 40500000:
+	case 40541000:
+	case 54000000:
+	case 54054000:
+	case 59341000:
+	case 59400000:
+	case 72000000:
+	case 74176000:
+	case 74250000:
+	case 81000000:
+	case 81081000:
+	case 89012000:
+	case 89100000:
+	case 108000000:
+	case 108108000:
+	case 111264000:
+	case 111375000:
+	case 148352000:
+	case 148500000:
+	case 162000000:
+	case 162162000:
+	case 222525000:
+	case 222750000:
+	case 296703000:
+	case 297000000:
+		budget = 0;
+		break;
+	case 233500000:
+	case 245250000:
+	case 247750000:
+	case 253250000:
+	case 298000000:
+		budget = 1500;
+		break;
+	case 169128000:
+	case 169500000:
+	case 179500000:
+	case 202000000:
+		budget = 2000;
+		break;
+	case 256250000:
+	case 262500000:
+	case 270000000:
+	case 272500000:
+	case 273750000:
+	case 280750000:
+	case 281250000:
+	case 286000000:
+	case 291750000:
+		budget = 4000;
+		break;
+	case 267250000:
+	case 268500000:
+		budget = 5000;
+		break;
+	default:
+		budget = 1000;
+		break;
+	}
 
-	if (i == ARRAY_SIZE(wrpll_tmds_clock_table))
-		i--;
+	return budget;
+}
 
-	*p = wrpll_tmds_clock_table[i].p;
-	*n2 = wrpll_tmds_clock_table[i].n2;
-	*r2 = wrpll_tmds_clock_table[i].r2;
+static void wrpll_update_rnp(uint64_t freq2k, unsigned budget,
+			     unsigned r2, unsigned n2, unsigned p,
+			     struct wrpll_rnp *best)
+{
+	uint64_t a, b, c, d, diff, diff_best;
 
-	if (wrpll_tmds_clock_table[i].clock != clock)
-		DRM_INFO("WRPLL: using settings for %dKHz on %dKHz mode\n",
-			 wrpll_tmds_clock_table[i].clock, clock);
+	/* No best (r,n,p) yet */
+	if (best->p == 0) {
+		best->p = p;
+		best->n2 = n2;
+		best->r2 = r2;
+		return;
+	}
 
-	DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
-		      clock, *p, *n2, *r2);
+	/*
+	 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
+	 * freq2k.
+	 *
+	 * delta = 1e6 *
+	 *	   abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
+	 *	   freq2k;
+	 *
+	 * and we would like delta <= budget.
+	 *
+	 * If the discrepancy is above the PPM-based budget, always prefer to
+	 * improve upon the previous solution.  However, if you're within the
+	 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
+	 */
+	a = freq2k * budget * p * r2;
+	b = freq2k * budget * best->p * best->r2;
+	diff = ABS_DIFF((freq2k * p * r2), (LC_FREQ_2K * n2));
+	diff_best = ABS_DIFF((freq2k * best->p * best->r2),
+			     (LC_FREQ_2K * best->n2));
+	c = 1000000 * diff;
+	d = 1000000 * diff_best;
+
+	if (a < c && b < d) {
+		/* If both are above the budget, pick the closer */
+		if (best->p * best->r2 * diff < p * r2 * diff_best) {
+			best->p = p;
+			best->n2 = n2;
+			best->r2 = r2;
+		}
+	} else if (a >= c && b < d) {
+		/* If A is below the threshold but B is above it?  Update. */
+		best->p = p;
+		best->n2 = n2;
+		best->r2 = r2;
+	} else if (a >= c && b >= d) {
+		/* Both are below the limit, so pick the higher n2/(r2*r2) */
+		if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
+			best->p = p;
+			best->n2 = n2;
+			best->r2 = r2;
+		}
+	}
+	/* Otherwise a < c && b >= d, do nothing */
 }
 
-bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock)
+static void
+intel_ddi_calculate_wrpll(int clock /* in Hz */,
+			  unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
+{
+	uint64_t freq2k;
+	unsigned p, n2, r2;
+	struct wrpll_rnp best = { 0, 0, 0 };
+	unsigned budget;
+
+	freq2k = clock / 100;
+
+	budget = wrpll_get_budget_for_freq(clock);
+
+	/* Special case handling for 540 pixel clock: bypass WR PLL entirely
+	 * and directly pass the LC PLL to it. */
+	if (freq2k == 5400000) {
+		*n2_out = 2;
+		*p_out = 1;
+		*r2_out = 2;
+		return;
+	}
+
+	/*
+	 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
+	 * the WR PLL.
+	 *
+	 * We want R so that REF_MIN <= Ref <= REF_MAX.
+	 * Injecting R2 = 2 * R gives:
+	 *   REF_MAX * r2 > LC_FREQ * 2 and
+	 *   REF_MIN * r2 < LC_FREQ * 2
+	 *
+	 * Which means the desired boundaries for r2 are:
+	 *  LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
+	 *
+	 */
+	for (r2 = LC_FREQ * 2 / REF_MAX + 1;
+	     r2 <= LC_FREQ * 2 / REF_MIN;
+	     r2++) {
+
+		/*
+		 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
+		 *
+		 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
+		 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
+		 *   VCO_MAX * r2 > n2 * LC_FREQ and
+		 *   VCO_MIN * r2 < n2 * LC_FREQ)
+		 *
+		 * Which means the desired boundaries for n2 are:
+		 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
+		 */
+		for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
+		     n2 <= VCO_MAX * r2 / LC_FREQ;
+		     n2++) {
+
+			for (p = P_MIN; p <= P_MAX; p += P_INC)
+				wrpll_update_rnp(freq2k, budget,
+						 r2, n2, p, &best);
+		}
+	}
+
+	*n2_out = best.n2;
+	*p_out = best.p;
+	*r2_out = best.r2;
+
+	DRM_DEBUG_KMS("WRPLL: %dHz refresh rate with p=%d, n2=%d r2=%d\n",
+		      clock, *p_out, *n2_out, *r2_out);
+}
+
+bool intel_ddi_pll_mode_set(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
@@ -835,6 +634,7 @@ bool intel_ddi_pll_mode_set(struct drm_c
 	int type = intel_encoder->type;
 	enum pipe pipe = intel_crtc->pipe;
 	uint32_t reg, val;
+	int clock = intel_crtc->config.port_clock;
 
 	/* TODO: reuse PLLs when possible (compare values) */
 
@@ -863,7 +663,7 @@ bool intel_ddi_pll_mode_set(struct drm_c
 		return true;
 
 	} else if (type == INTEL_OUTPUT_HDMI) {
-		int p, n2, r2;
+		unsigned p, n2, r2;
 
 		if (plls->wrpll1_refcount == 0) {
 			DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n",
@@ -885,7 +685,7 @@ bool intel_ddi_pll_mode_set(struct drm_c
 		WARN(I915_READ(reg) & WRPLL_PLL_ENABLE,
 		     "WRPLL already enabled\n");
 
-		intel_ddi_calculate_wrpll(clock, &p, &n2, &r2);
+		intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
 
 		val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 |
 		      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
@@ -995,7 +795,7 @@ void intel_ddi_enable_transcoder_func(st
 			/* Can only use the always-on power well for eDP when
 			 * not using the panel fitter, and when not using motion
 			  * blur mitigation (which we don't support). */
-			if (dev_priv->pch_pf_size)
+			if (intel_crtc->config.pch_pfit.size)
 				temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
 			else
 				temp |= TRANS_DDI_EDP_INPUT_A_ON;
@@ -1022,7 +822,7 @@ void intel_ddi_enable_transcoder_func(st
 
 	} else if (type == INTEL_OUTPUT_ANALOG) {
 		temp |= TRANS_DDI_MODE_SELECT_FDI;
-		temp |= (intel_crtc->fdi_lanes - 1) << 1;
+		temp |= (intel_crtc->config.fdi_lanes - 1) << 1;
 
 	} else if (type == INTEL_OUTPUT_DISPLAYPORT ||
 		   type == INTEL_OUTPUT_EDP) {
@@ -1030,25 +830,10 @@ void intel_ddi_enable_transcoder_func(st
 
 		temp |= TRANS_DDI_MODE_SELECT_DP_SST;
 
-		switch (intel_dp->lane_count) {
-		case 1:
-			temp |= TRANS_DDI_PORT_WIDTH_X1;
-			break;
-		case 2:
-			temp |= TRANS_DDI_PORT_WIDTH_X2;
-			break;
-		case 4:
-			temp |= TRANS_DDI_PORT_WIDTH_X4;
-			break;
-		default:
-			temp |= TRANS_DDI_PORT_WIDTH_X4;
-			WARN(1, "Unsupported lane count %d\n",
-			     intel_dp->lane_count);
-		}
-
+		temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
 	} else {
-		WARN(1, "Invalid encoder type %d for pipe %d\n",
-		     intel_encoder->type, pipe);
+		WARN(1, "Invalid encoder type %d for pipe %c\n",
+		     intel_encoder->type, pipe_name(pipe));
 	}
 
 	I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
@@ -1148,7 +933,7 @@ bool intel_ddi_get_hw_state(struct intel
 		}
 	}
 
-	DRM_DEBUG_KMS("No pipe for ddi port %i found\n", port);
+	DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
 
 	return false;
 }
@@ -1324,7 +1109,8 @@ static void intel_enable_ddi(struct inte
 		 * enabling the port.
 		 */
 		I915_WRITE(DDI_BUF_CTL(port),
-			   intel_dig_port->port_reversal | DDI_BUF_CTL_ENABLE);
+			   intel_dig_port->saved_port_bits |
+			   DDI_BUF_CTL_ENABLE);
 	} else if (type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
@@ -1334,7 +1120,7 @@ static void intel_enable_ddi(struct inte
 		ironlake_edp_backlight_on(intel_dp);
 	}
 
-	if (intel_crtc->eld_vld) {
+	if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) {
 		tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
 		tmp |= ((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4));
 		I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
@@ -1352,9 +1138,12 @@ static void intel_disable_ddi(struct int
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t tmp;
 
-	tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
-	tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) << (pipe * 4));
-	I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
+	if (intel_crtc->eld_vld && type != INTEL_OUTPUT_EDP) {
+		tmp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
+		tmp &= ~((AUDIO_OUTPUT_ENABLE_A | AUDIO_ELD_VALID_A) <<
+			 (pipe * 4));
+		I915_WRITE(HSW_AUD_PIN_ELD_CP_VLD, tmp);
+	}
 
 	if (type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -1366,14 +1155,14 @@ static void intel_disable_ddi(struct int
 int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
 {
 	if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT)
-		return 450;
+		return 450000;
 	else if ((I915_READ(LCPLL_CTL) & LCPLL_CLK_FREQ_MASK) ==
 		 LCPLL_CLK_FREQ_450)
-		return 450;
+		return 450000;
 	else if (IS_ULT(dev_priv->dev))
-		return 338;
+		return 337500;
 	else
-		return 540;
+		return 540000;
 }
 
 void intel_ddi_pll_init(struct drm_device *dev)
@@ -1386,7 +1175,7 @@ void intel_ddi_pll_init(struct drm_devic
 	 * Don't even try to turn it on.
 	 */
 
-	DRM_DEBUG_KMS("CDCLK running at %dMHz\n",
+	DRM_DEBUG_KMS("CDCLK running at %dKHz\n",
 		      intel_ddi_get_cdclk_freq(dev_priv));
 
 	if (val & LCPLL_CD_SOURCE_FCLK)
@@ -1472,6 +1261,27 @@ static void intel_ddi_hot_plug(struct in
 		intel_dp_check_link_status(intel_dp);
 }
 
+static void intel_ddi_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_config *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+	u32 temp, flags = 0;
+
+	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	if (temp & TRANS_DDI_PHSYNC)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	if (temp & TRANS_DDI_PVSYNC)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 static void intel_ddi_destroy(struct drm_encoder *encoder)
 {
 	/* HDMI has nothing special to destroy, so we can go with this. */
@@ -1482,9 +1292,13 @@ static bool intel_ddi_compute_config(str
 				     struct intel_crtc_config *pipe_config)
 {
 	int type = encoder->type;
+	int port = intel_ddi_get_encoder_port(encoder);
 
 	WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
 
+	if (port == PORT_A)
+		pipe_config->cpu_transcoder = TRANSCODER_EDP;
+
 	if (type == INTEL_OUTPUT_HDMI)
 		return intel_hdmi_compute_config(encoder, pipe_config);
 	else
@@ -1518,16 +1332,6 @@ void intel_ddi_init(struct drm_device *d
 		return;
 	}
 
-	if (port != PORT_A) {
-		hdmi_connector = kzalloc(sizeof(struct intel_connector),
-					 GFP_KERNEL);
-		if (!hdmi_connector) {
-			kfree(dp_connector);
-			kfree(intel_dig_port);
-			return;
-		}
-	}
-
 	intel_encoder = &intel_dig_port->base;
 	encoder = &intel_encoder->base;
 
@@ -1541,12 +1345,12 @@ void intel_ddi_init(struct drm_device *d
 	intel_encoder->disable = intel_disable_ddi;
 	intel_encoder->post_disable = intel_ddi_post_disable;
 	intel_encoder->get_hw_state = intel_ddi_get_hw_state;
+	intel_encoder->get_config = intel_ddi_get_config;
 
 	intel_dig_port->port = port;
-	intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) &
-					DDI_BUF_PORT_REVERSAL;
-	if (hdmi_connector)
-		intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
+	intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
+					  (DDI_BUF_PORT_REVERSAL |
+					   DDI_A_4_LANES);
 	intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
 
 	intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
@@ -1554,7 +1358,21 @@ void intel_ddi_init(struct drm_device *d
 	intel_encoder->cloneable = false;
 	intel_encoder->hot_plug = intel_ddi_hot_plug;
 
-	if (hdmi_connector)
+	if (!intel_dp_init_connector(intel_dig_port, dp_connector)) {
+		drm_encoder_cleanup(encoder);
+		kfree(intel_dig_port);
+		kfree(dp_connector);
+		return;
+	}
+
+	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
+		hdmi_connector = kzalloc(sizeof(struct intel_connector),
+					 GFP_KERNEL);
+		if (!hdmi_connector) {
+			return;
+		}
+
+		intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
 		intel_hdmi_init_connector(intel_dig_port, hdmi_connector);
-	intel_dp_init_connector(intel_dig_port, dp_connector);
+	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_display.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_display.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_display.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,18 +46,6 @@ static void intel_increase_pllclock(stru
 static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
 
 typedef struct {
-	/* given values */
-	int n;
-	int m1, m2;
-	int p1, p2;
-	/* derived values */
-	int	dot;
-	int	vco;
-	int	m;
-	int	p;
-} intel_clock_t;
-
-typedef struct {
 	int	min, max;
 } intel_range_t;
 
@@ -71,24 +59,6 @@ typedef struct intel_limit intel_limit_t
 struct intel_limit {
 	intel_range_t   dot, vco, n, m, m1, m2, p, p1;
 	intel_p2_t	    p2;
-	/**
-	 * find_pll() - Find the best values for the PLL
-	 * @limit: limits for the PLL
-	 * @crtc: current CRTC
-	 * @target: target frequency in kHz
-	 * @refclk: reference clock frequency in kHz
-	 * @match_clock: if provided, @best_clock P divider must
-	 *               match the P divider from @match_clock
-	 *               used for LVDS downclocking
-	 * @best_clock: best PLL values found
-	 *
-	 * Returns true on success, false on failure.
-	 */
-	bool (*find_pll)(const intel_limit_t *limit,
-			 struct drm_crtc *crtc,
-			 int target, int refclk,
-			 intel_clock_t *match_clock,
-			 intel_clock_t *best_clock);
 };
 
 /* FDI */
@@ -104,29 +74,6 @@ intel_pch_rawclk(struct drm_device *dev)
 	return I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK;
 }
 
-static bool
-intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-		    int target, int refclk, intel_clock_t *match_clock,
-		    intel_clock_t *best_clock);
-static bool
-intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, intel_clock_t *match_clock,
-			intel_clock_t *best_clock);
-
-static bool
-intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc,
-		      int target, int refclk, intel_clock_t *match_clock,
-		      intel_clock_t *best_clock);
-static bool
-intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc,
-			   int target, int refclk, intel_clock_t *match_clock,
-			   intel_clock_t *best_clock);
-
-static bool
-intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, intel_clock_t *match_clock,
-			intel_clock_t *best_clock);
-
 static inline u32 /* units of 100MHz */
 intel_fdi_link_freq(struct drm_device *dev)
 {
@@ -148,7 +95,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 2, .max = 33 },
 	.p2 = { .dot_limit = 165000,
 		.p2_slow = 4, .p2_fast = 2 },
-	.find_pll = intel_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_i8xx_lvds = {
@@ -162,7 +108,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 1, .max = 6 },
 	.p2 = { .dot_limit = 165000,
 		.p2_slow = 14, .p2_fast = 7 },
-	.find_pll = intel_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_i9xx_sdvo = {
@@ -176,7 +121,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 1, .max = 8 },
 	.p2 = { .dot_limit = 200000,
 		.p2_slow = 10, .p2_fast = 5 },
-	.find_pll = intel_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_i9xx_lvds = {
@@ -190,7 +134,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 1, .max = 8 },
 	.p2 = { .dot_limit = 112000,
 		.p2_slow = 14, .p2_fast = 7 },
-	.find_pll = intel_find_best_PLL,
 };
 
 
@@ -207,7 +150,6 @@ static const intel_limit_t intel_limits_
 		.p2_slow = 10,
 		.p2_fast = 10
 	},
-	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_hdmi = {
@@ -221,7 +163,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 1, .max = 8},
 	.p2 = { .dot_limit = 165000,
 		.p2_slow = 10, .p2_fast = 5 },
-	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
@@ -236,7 +177,6 @@ static const intel_limit_t intel_limits_
 	.p2 = { .dot_limit = 0,
 		.p2_slow = 14, .p2_fast = 14
 	},
-	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
@@ -251,21 +191,6 @@ static const intel_limit_t intel_limits_
 	.p2 = { .dot_limit = 0,
 		.p2_slow = 7, .p2_fast = 7
 	},
-	.find_pll = intel_g4x_find_best_PLL,
-};
-
-static const intel_limit_t intel_limits_g4x_display_port = {
-	.dot = { .min = 161670, .max = 227000 },
-	.vco = { .min = 1750000, .max = 3500000},
-	.n = { .min = 1, .max = 2 },
-	.m = { .min = 97, .max = 108 },
-	.m1 = { .min = 0x10, .max = 0x12 },
-	.m2 = { .min = 0x05, .max = 0x06 },
-	.p = { .min = 10, .max = 20 },
-	.p1 = { .min = 1, .max = 2},
-	.p2 = { .dot_limit = 0,
-		.p2_slow = 10, .p2_fast = 10 },
-	.find_pll = intel_find_pll_g4x_dp,
 };
 
 static const intel_limit_t intel_limits_pineview_sdvo = {
@@ -281,7 +206,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 1, .max = 8 },
 	.p2 = { .dot_limit = 200000,
 		.p2_slow = 10, .p2_fast = 5 },
-	.find_pll = intel_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_pineview_lvds = {
@@ -295,7 +219,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 1, .max = 8 },
 	.p2 = { .dot_limit = 112000,
 		.p2_slow = 14, .p2_fast = 14 },
-	.find_pll = intel_find_best_PLL,
 };
 
 /* Ironlake / Sandybridge
@@ -314,7 +237,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 1, .max = 8 },
 	.p2 = { .dot_limit = 225000,
 		.p2_slow = 10, .p2_fast = 5 },
-	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_ironlake_single_lvds = {
@@ -328,7 +250,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 2, .max = 8 },
 	.p2 = { .dot_limit = 225000,
 		.p2_slow = 14, .p2_fast = 14 },
-	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_ironlake_dual_lvds = {
@@ -342,7 +263,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 2, .max = 8 },
 	.p2 = { .dot_limit = 225000,
 		.p2_slow = 7, .p2_fast = 7 },
-	.find_pll = intel_g4x_find_best_PLL,
 };
 
 /* LVDS 100mhz refclk limits. */
@@ -357,7 +277,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 2, .max = 8 },
 	.p2 = { .dot_limit = 225000,
 		.p2_slow = 14, .p2_fast = 14 },
-	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = {
@@ -371,21 +290,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 2, .max = 6 },
 	.p2 = { .dot_limit = 225000,
 		.p2_slow = 7, .p2_fast = 7 },
-	.find_pll = intel_g4x_find_best_PLL,
-};
-
-static const intel_limit_t intel_limits_ironlake_display_port = {
-	.dot = { .min = 25000, .max = 350000 },
-	.vco = { .min = 1760000, .max = 3510000},
-	.n = { .min = 1, .max = 2 },
-	.m = { .min = 81, .max = 90 },
-	.m1 = { .min = 12, .max = 22 },
-	.m2 = { .min = 5, .max = 9 },
-	.p = { .min = 10, .max = 20 },
-	.p1 = { .min = 1, .max = 2},
-	.p2 = { .dot_limit = 0,
-		.p2_slow = 10, .p2_fast = 10 },
-	.find_pll = intel_find_pll_ironlake_dp,
 };
 
 static const intel_limit_t intel_limits_vlv_dac = {
@@ -396,15 +300,14 @@ static const intel_limit_t intel_limits_
 	.m1 = { .min = 2, .max = 3 },
 	.m2 = { .min = 11, .max = 156 },
 	.p = { .min = 10, .max = 30 },
-	.p1 = { .min = 2, .max = 3 },
+	.p1 = { .min = 1, .max = 3 },
 	.p2 = { .dot_limit = 270000,
 		.p2_slow = 2, .p2_fast = 20 },
-	.find_pll = intel_vlv_find_best_pll,
 };
 
 static const intel_limit_t intel_limits_vlv_hdmi = {
-	.dot = { .min = 20000, .max = 165000 },
-	.vco = { .min = 4000000, .max = 5994000},
+	.dot = { .min = 25000, .max = 270000 },
+	.vco = { .min = 4000000, .max = 6000000 },
 	.n = { .min = 1, .max = 7 },
 	.m = { .min = 60, .max = 300 }, /* guess */
 	.m1 = { .min = 2, .max = 3 },
@@ -413,7 +316,6 @@ static const intel_limit_t intel_limits_
 	.p1 = { .min = 2, .max = 3 },
 	.p2 = { .dot_limit = 270000,
 		.p2_slow = 2, .p2_fast = 20 },
-	.find_pll = intel_vlv_find_best_pll,
 };
 
 static const intel_limit_t intel_limits_vlv_dp = {
@@ -424,61 +326,11 @@ static const intel_limit_t intel_limits_
 	.m1 = { .min = 2, .max = 3 },
 	.m2 = { .min = 11, .max = 156 },
 	.p = { .min = 10, .max = 30 },
-	.p1 = { .min = 2, .max = 3 },
+	.p1 = { .min = 1, .max = 3 },
 	.p2 = { .dot_limit = 270000,
 		.p2_slow = 2, .p2_fast = 20 },
-	.find_pll = intel_vlv_find_best_pll,
 };
 
-u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg)
-{
-	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
-
-	if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) {
-		DRM_ERROR("DPIO idle wait timed out\n");
-		return 0;
-	}
-
-	I915_WRITE(DPIO_REG, reg);
-	I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_READ | DPIO_PORTID |
-		   DPIO_BYTE);
-	if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) {
-		DRM_ERROR("DPIO read wait timed out\n");
-		return 0;
-	}
-
-	return I915_READ(DPIO_DATA);
-}
-
-static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg,
-			     u32 val)
-{
-	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
-
-	if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) {
-		DRM_ERROR("DPIO idle wait timed out\n");
-		return;
-	}
-
-	I915_WRITE(DPIO_DATA, val);
-	I915_WRITE(DPIO_REG, reg);
-	I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID |
-		   DPIO_BYTE);
-	if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100))
-		DRM_ERROR("DPIO write wait timed out\n");
-}
-
-static void vlv_init_dpio(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	/* Reset the DPIO config */
-	I915_WRITE(DPIO_CTL, 0);
-	POSTING_READ(DPIO_CTL);
-	I915_WRITE(DPIO_CTL, 1);
-	POSTING_READ(DPIO_CTL);
-}
-
 static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
 						int refclk)
 {
@@ -497,10 +349,7 @@ static const intel_limit_t *intel_ironla
 			else
 				limit = &intel_limits_ironlake_single_lvds;
 		}
-	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) ||
-		   intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))
-		limit = &intel_limits_ironlake_display_port;
-	else
+	} else
 		limit = &intel_limits_ironlake_dac;
 
 	return limit;
@@ -521,8 +370,6 @@ static const intel_limit_t *intel_g4x_li
 		limit = &intel_limits_g4x_hdmi;
 	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
 		limit = &intel_limits_g4x_sdvo;
-	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
-		limit = &intel_limits_g4x_display_port;
 	} else /* The option is for other outputs */
 		limit = &intel_limits_i9xx_sdvo;
 
@@ -573,13 +420,14 @@ static void pineview_clock(int refclk, i
 	clock->dot = clock->vco / clock->p;
 }
 
-static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock)
+static uint32_t i9xx_dpll_compute_m(struct dpll *dpll)
 {
-	if (IS_PINEVIEW(dev)) {
-		pineview_clock(refclk, clock);
-		return;
-	}
-	clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
+	return 5 * (dpll->m1 + 2) + (dpll->m2 + 2);
+}
+
+static void i9xx_clock(int refclk, intel_clock_t *clock)
+{
+	clock->m = i9xx_dpll_compute_m(clock);
 	clock->p = clock->p1 * clock->p2;
 	clock->vco = refclk * clock->m / (clock->n + 2);
 	clock->dot = clock->vco / clock->p;
@@ -636,10 +484,9 @@ static bool intel_PLL_is_valid(struct dr
 }
 
 static bool
-intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+i9xx_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc,
 		    int target, int refclk, intel_clock_t *match_clock,
 		    intel_clock_t *best_clock)
-
 {
 	struct drm_device *dev = crtc->dev;
 	intel_clock_t clock;
@@ -668,8 +515,7 @@ intel_find_best_PLL(const intel_limit_t
 	     clock.m1++) {
 		for (clock.m2 = limit->m2.min;
 		     clock.m2 <= limit->m2.max; clock.m2++) {
-			/* m1 is always 0 in Pineview */
-			if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
+			if (clock.m2 >= clock.m1)
 				break;
 			for (clock.n = limit->n.min;
 			     clock.n <= limit->n.max; clock.n++) {
@@ -677,7 +523,7 @@ intel_find_best_PLL(const intel_limit_t
 					clock.p1 <= limit->p1.max; clock.p1++) {
 					int this_err;
 
-					intel_clock(dev, refclk, &clock);
+					i9xx_clock(refclk, &clock);
 					if (!intel_PLL_is_valid(dev, limit,
 								&clock))
 						continue;
@@ -699,9 +545,68 @@ intel_find_best_PLL(const intel_limit_t
 }
 
 static bool
-intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, intel_clock_t *match_clock,
-			intel_clock_t *best_clock)
+pnv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc,
+		   int target, int refclk, intel_clock_t *match_clock,
+		   intel_clock_t *best_clock)
+{
+	struct drm_device *dev = crtc->dev;
+	intel_clock_t clock;
+	int err = target;
+
+	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+		/*
+		 * For LVDS just rely on its current settings for dual-channel.
+		 * We haven't figured out how to reliably set up different
+		 * single/dual channel state, if we even can.
+		 */
+		if (intel_is_dual_link_lvds(dev))
+			clock.p2 = limit->p2.p2_fast;
+		else
+			clock.p2 = limit->p2.p2_slow;
+	} else {
+		if (target < limit->p2.dot_limit)
+			clock.p2 = limit->p2.p2_slow;
+		else
+			clock.p2 = limit->p2.p2_fast;
+	}
+
+	memset(best_clock, 0, sizeof(*best_clock));
+
+	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
+	     clock.m1++) {
+		for (clock.m2 = limit->m2.min;
+		     clock.m2 <= limit->m2.max; clock.m2++) {
+			for (clock.n = limit->n.min;
+			     clock.n <= limit->n.max; clock.n++) {
+				for (clock.p1 = limit->p1.min;
+					clock.p1 <= limit->p1.max; clock.p1++) {
+					int this_err;
+
+					pineview_clock(refclk, &clock);
+					if (!intel_PLL_is_valid(dev, limit,
+								&clock))
+						continue;
+					if (match_clock &&
+					    clock.p != match_clock->p)
+						continue;
+
+					this_err = abs(clock.dot - target);
+					if (this_err < err) {
+						*best_clock = clock;
+						err = this_err;
+					}
+				}
+			}
+		}
+	}
+
+	return (err != target);
+}
+
+static bool
+g4x_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc,
+		   int target, int refclk, intel_clock_t *match_clock,
+		   intel_clock_t *best_clock)
 {
 	struct drm_device *dev = crtc->dev;
 	intel_clock_t clock;
@@ -712,12 +617,6 @@ intel_g4x_find_best_PLL(const intel_limi
 	found = false;
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-		int lvds_reg;
-
-		if (HAS_PCH_SPLIT(dev))
-			lvds_reg = PCH_LVDS;
-		else
-			lvds_reg = LVDS;
 		if (intel_is_dual_link_lvds(dev))
 			clock.p2 = limit->p2.p2_fast;
 		else
@@ -742,13 +641,10 @@ intel_g4x_find_best_PLL(const intel_limi
 				     clock.p1 >= limit->p1.min; clock.p1--) {
 					int this_err;
 
-					intel_clock(dev, refclk, &clock);
+					i9xx_clock(refclk, &clock);
 					if (!intel_PLL_is_valid(dev, limit,
 								&clock))
 						continue;
-					if (match_clock &&
-					    clock.p != match_clock->p)
-						continue;
 
 					this_err = abs(clock.dot - target);
 					if (this_err < err_most) {
@@ -765,62 +661,9 @@ intel_g4x_find_best_PLL(const intel_limi
 }
 
 static bool
-intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
-			   int target, int refclk, intel_clock_t *match_clock,
-			   intel_clock_t *best_clock)
-{
-	struct drm_device *dev = crtc->dev;
-	intel_clock_t clock;
-
-	if (target < 200000) {
-		clock.n = 1;
-		clock.p1 = 2;
-		clock.p2 = 10;
-		clock.m1 = 12;
-		clock.m2 = 9;
-	} else {
-		clock.n = 2;
-		clock.p1 = 1;
-		clock.p2 = 10;
-		clock.m1 = 14;
-		clock.m2 = 8;
-	}
-	intel_clock(dev, refclk, &clock);
-	memcpy(best_clock, &clock, sizeof(intel_clock_t));
-	return true;
-}
-
-/* DisplayPort has only two frequencies, 162MHz and 270MHz */
-static bool
-intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
-		      int target, int refclk, intel_clock_t *match_clock,
-		      intel_clock_t *best_clock)
-{
-	intel_clock_t clock;
-	if (target < 200000) {
-		clock.p1 = 2;
-		clock.p2 = 10;
-		clock.n = 2;
-		clock.m1 = 23;
-		clock.m2 = 8;
-	} else {
-		clock.p1 = 1;
-		clock.p2 = 10;
-		clock.n = 1;
-		clock.m1 = 14;
-		clock.m2 = 2;
-	}
-	clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2);
-	clock.p = (clock.p1 * clock.p2);
-	clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p;
-	clock.vco = 0;
-	memcpy(best_clock, &clock, sizeof(intel_clock_t));
-	return true;
-}
-static bool
-intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, intel_clock_t *match_clock,
-			intel_clock_t *best_clock)
+vlv_find_best_dpll(const intel_limit_t *limit, struct drm_crtc *crtc,
+		   int target, int refclk, intel_clock_t *match_clock,
+		   intel_clock_t *best_clock)
 {
 	u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2;
 	u32 m, n, fastclk;
@@ -1066,14 +909,24 @@ static void assert_pll(struct drm_i915_p
 #define assert_pll_enabled(d, p) assert_pll(d, p, true)
 #define assert_pll_disabled(d, p) assert_pll(d, p, false)
 
+static struct intel_shared_dpll *
+intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+
+	if (crtc->config.shared_dpll < 0)
+		return NULL;
+
+	return &dev_priv->shared_dplls[crtc->config.shared_dpll];
+}
+
 /* For ILK+ */
-static void assert_pch_pll(struct drm_i915_private *dev_priv,
-			   struct intel_pch_pll *pll,
-			   struct intel_crtc *crtc,
-			   bool state)
+static void assert_shared_dpll(struct drm_i915_private *dev_priv,
+			       struct intel_shared_dpll *pll,
+			       bool state)
 {
-	u32 val;
 	bool cur_state;
+	struct intel_dpll_hw_state hw_state;
 
 	if (HAS_PCH_LPT(dev_priv->dev)) {
 		DRM_DEBUG_DRIVER("LPT detected: skipping PCH PLL test\n");
@@ -1081,36 +934,16 @@ static void assert_pch_pll(struct drm_i9
 	}
 
 	if (WARN (!pll,
-		  "asserting PCH PLL %s with no PLL\n", state_string(state)))
+		  "asserting DPLL %s with no DPLL\n", state_string(state)))
 		return;
 
-	val = I915_READ(pll->pll_reg);
-	cur_state = !!(val & DPLL_VCO_ENABLE);
+	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
 	WARN(cur_state != state,
-	     "PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n",
-	     pll->pll_reg, state_string(state), state_string(cur_state), val);
-
-	/* Make sure the selected PLL is correctly attached to the transcoder */
-	if (crtc && HAS_PCH_CPT(dev_priv->dev)) {
-		u32 pch_dpll;
-
-		pch_dpll = I915_READ(PCH_DPLL_SEL);
-		cur_state = pll->pll_reg == _PCH_DPLL_B;
-		if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state,
-			  "PLL[%d] not attached to this transcoder %d: %08x\n",
-			  cur_state, crtc->pipe, pch_dpll)) {
-			cur_state = !!(val >> (4*crtc->pipe + 3));
-			WARN(cur_state != state,
-			     "PLL[%d] not %s on this transcoder %d: %08x\n",
-			     pll->pll_reg == _PCH_DPLL_B,
-			     state_string(state),
-			     crtc->pipe,
-			     val);
-		}
-	}
+	     "%s assertion failure (expected %s, current %s)\n",
+	     pll->name, state_string(state), state_string(cur_state));
 }
-#define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true)
-#define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, false)
+#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
+#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
 
 static void assert_fdi_tx(struct drm_i915_private *dev_priv,
 			  enum pipe pipe, bool state)
@@ -1227,8 +1060,8 @@ void assert_pipe(struct drm_i915_private
 	if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
 		state = true;
 
-	if (!intel_using_power_well(dev_priv->dev) &&
-	    cpu_transcoder != TRANSCODER_EDP) {
+	if (!intel_display_power_enabled(dev_priv->dev,
+				POWER_DOMAIN_TRANSCODER(cpu_transcoder))) {
 		cur_state = false;
 	} else {
 		reg = PIPECONF(cpu_transcoder);
@@ -1262,12 +1095,13 @@ static void assert_plane(struct drm_i915
 static void assert_planes_disabled(struct drm_i915_private *dev_priv,
 				   enum pipe pipe)
 {
+	struct drm_device *dev = dev_priv->dev;
 	int reg, i;
 	u32 val;
 	int cur_pipe;
 
-	/* Planes are fixed to pipes on ILK+ */
-	if (HAS_PCH_SPLIT(dev_priv->dev) || IS_VALLEYVIEW(dev_priv->dev)) {
+	/* Primary planes are fixed to pipes on gen4+ */
+	if (INTEL_INFO(dev)->gen >= 4) {
 		reg = DSPCNTR(pipe);
 		val = I915_READ(reg);
 		WARN((val & DISPLAY_PLANE_ENABLE),
@@ -1277,7 +1111,7 @@ static void assert_planes_disabled(struc
 	}
 
 	/* Need to check both planes against the pipe */
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) {
 		reg = DSPCNTR(i);
 		val = I915_READ(reg);
 		cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
@@ -1291,19 +1125,30 @@ static void assert_planes_disabled(struc
 static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
 				    enum pipe pipe)
 {
+	struct drm_device *dev = dev_priv->dev;
 	int reg, i;
 	u32 val;
 
-	if (!IS_VALLEYVIEW(dev_priv->dev))
-		return;
-
-	/* Need to check both planes against the pipe */
-	for (i = 0; i < dev_priv->num_plane; i++) {
-		reg = SPCNTR(pipe, i);
+	if (IS_VALLEYVIEW(dev)) {
+		for (i = 0; i < dev_priv->num_plane; i++) {
+			reg = SPCNTR(pipe, i);
+			val = I915_READ(reg);
+			WARN((val & SP_ENABLE),
+			     "sprite %c assertion failure, should be off on pipe %c but is still active\n",
+			     sprite_name(pipe, i), pipe_name(pipe));
+		}
+	} else if (INTEL_INFO(dev)->gen >= 7) {
+		reg = SPRCTL(pipe);
 		val = I915_READ(reg);
-		WARN((val & SP_ENABLE),
-		     "sprite %d assertion failure, should be off on pipe %c but is still active\n",
-		     pipe * 2 + i, pipe_name(pipe));
+		WARN((val & SPRITE_ENABLE),
+		     "sprite %c assertion failure, should be off on pipe %c but is still active\n",
+		     plane_name(pipe), pipe_name(pipe));
+	} else if (INTEL_INFO(dev)->gen >= 5) {
+		reg = DVSCNTR(pipe);
+		val = I915_READ(reg);
+		WARN((val & DVS_ENABLE),
+		     "sprite %c assertion failure, should be off on pipe %c but is still active\n",
+		     plane_name(pipe), pipe_name(pipe));
 	}
 }
 
@@ -1323,14 +1168,14 @@ static void assert_pch_refclk_enabled(st
 	WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
 }
 
-static void assert_transcoder_disabled(struct drm_i915_private *dev_priv,
-				       enum pipe pipe)
+static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
+					   enum pipe pipe)
 {
 	int reg;
 	u32 val;
 	bool enabled;
 
-	reg = TRANSCONF(pipe);
+	reg = PCH_TRANSCONF(pipe);
 	val = I915_READ(reg);
 	enabled = !!(val & TRANS_ENABLE);
 	WARN(enabled,
@@ -1474,6 +1319,8 @@ static void intel_enable_pll(struct drm_
 	int reg;
 	u32 val;
 
+	assert_pipe_disabled(dev_priv, pipe);
+
 	/* No really, not for ILK+ */
 	BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5);
 
@@ -1525,156 +1372,86 @@ static void intel_disable_pll(struct drm
 	POSTING_READ(reg);
 }
 
-/* SBI access */
-static void
-intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
-		enum intel_sbi_destination destination)
-{
-	u32 tmp;
-
-	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
-
-	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
-				100)) {
-		DRM_ERROR("timeout waiting for SBI to become ready\n");
-		return;
-	}
-
-	I915_WRITE(SBI_ADDR, (reg << 16));
-	I915_WRITE(SBI_DATA, value);
-
-	if (destination == SBI_ICLK)
-		tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
-	else
-		tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
-	I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
-
-	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
-				100)) {
-		DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
-		return;
-	}
-}
-
-static u32
-intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
-	       enum intel_sbi_destination destination)
+void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port)
 {
-	u32 value = 0;
-	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
-
-	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
-				100)) {
-		DRM_ERROR("timeout waiting for SBI to become ready\n");
-		return 0;
-	}
-
-	I915_WRITE(SBI_ADDR, (reg << 16));
+	u32 port_mask;
 
-	if (destination == SBI_ICLK)
-		value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
+	if (!port)
+		port_mask = DPLL_PORTB_READY_MASK;
 	else
-		value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
-	I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
-
-	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
-				100)) {
-		DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
-		return 0;
-	}
+		port_mask = DPLL_PORTC_READY_MASK;
 
-	return I915_READ(SBI_DATA);
+	if (wait_for((I915_READ(DPLL(0)) & port_mask) == 0, 1000))
+		WARN(1, "timed out waiting for port %c ready: 0x%08x\n",
+		     'B' + port, I915_READ(DPLL(0)));
 }
 
 /**
- * ironlake_enable_pch_pll - enable PCH PLL
+ * ironlake_enable_shared_dpll - enable PCH PLL
  * @dev_priv: i915 private structure
  * @pipe: pipe PLL to enable
  *
  * The PCH PLL needs to be enabled before the PCH transcoder, since it
  * drives the transcoder clock.
  */
-static void ironlake_enable_pch_pll(struct intel_crtc *intel_crtc)
+static void ironlake_enable_shared_dpll(struct intel_crtc *crtc)
 {
-	struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
-	struct intel_pch_pll *pll;
-	int reg;
-	u32 val;
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
 
 	/* PCH PLLs only available on ILK, SNB and IVB */
 	BUG_ON(dev_priv->info->gen < 5);
-	pll = intel_crtc->pch_pll;
-	if (pll == NULL)
+	if (WARN_ON(pll == NULL))
 		return;
 
 	if (WARN_ON(pll->refcount == 0))
 		return;
 
-	DRM_DEBUG_KMS("enable PCH PLL %x (active %d, on? %d)for crtc %d\n",
-		      pll->pll_reg, pll->active, pll->on,
-		      intel_crtc->base.base.id);
-
-	/* PCH refclock must be enabled first */
-	assert_pch_refclk_enabled(dev_priv);
+	DRM_DEBUG_KMS("enable %s (active %d, on? %d)for crtc %d\n",
+		      pll->name, pll->active, pll->on,
+		      crtc->base.base.id);
 
-	if (pll->active++ && pll->on) {
-		assert_pch_pll_enabled(dev_priv, pll, NULL);
+	if (pll->active++) {
+		WARN_ON(!pll->on);
+		assert_shared_dpll_enabled(dev_priv, pll);
 		return;
 	}
+	WARN_ON(pll->on);
 
-	DRM_DEBUG_KMS("enabling PCH PLL %x\n", pll->pll_reg);
-
-	reg = pll->pll_reg;
-	val = I915_READ(reg);
-	val |= DPLL_VCO_ENABLE;
-	I915_WRITE(reg, val);
-	POSTING_READ(reg);
-	udelay(200);
-
+	DRM_DEBUG_KMS("enabling %s\n", pll->name);
+	pll->enable(dev_priv, pll);
 	pll->on = true;
 }
 
-static void intel_disable_pch_pll(struct intel_crtc *intel_crtc)
+static void intel_disable_shared_dpll(struct intel_crtc *crtc)
 {
-	struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
-	struct intel_pch_pll *pll = intel_crtc->pch_pll;
-	int reg;
-	u32 val;
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
 
 	/* PCH only available on ILK+ */
 	BUG_ON(dev_priv->info->gen < 5);
-	if (pll == NULL)
+	if (WARN_ON(pll == NULL))
 	       return;
 
 	if (WARN_ON(pll->refcount == 0))
 		return;
 
-	DRM_DEBUG_KMS("disable PCH PLL %x (active %d, on? %d) for crtc %d\n",
-		      pll->pll_reg, pll->active, pll->on,
-		      intel_crtc->base.base.id);
+	DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n",
+		      pll->name, pll->active, pll->on,
+		      crtc->base.base.id);
 
 	if (WARN_ON(pll->active == 0)) {
-		assert_pch_pll_disabled(dev_priv, pll, NULL);
+		assert_shared_dpll_disabled(dev_priv, pll);
 		return;
 	}
 
-	if (--pll->active) {
-		assert_pch_pll_enabled(dev_priv, pll, NULL);
+	assert_shared_dpll_enabled(dev_priv, pll);
+	WARN_ON(!pll->on);
+	if (--pll->active)
 		return;
-	}
-
-	DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg);
-
-	/* Make sure transcoder isn't still depending on us */
-	assert_transcoder_disabled(dev_priv, intel_crtc->pipe);
-
-	reg = pll->pll_reg;
-	val = I915_READ(reg);
-	val &= ~DPLL_VCO_ENABLE;
-	I915_WRITE(reg, val);
-	POSTING_READ(reg);
-	udelay(200);
 
+	DRM_DEBUG_KMS("disabling %s\n", pll->name);
+	pll->disable(dev_priv, pll);
 	pll->on = false;
 }
 
@@ -1683,15 +1460,15 @@ static void ironlake_enable_pch_transcod
 {
 	struct drm_device *dev = dev_priv->dev;
 	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	uint32_t reg, val, pipeconf_val;
 
 	/* PCH only available on ILK+ */
 	BUG_ON(dev_priv->info->gen < 5);
 
 	/* Make sure PCH DPLL is enabled */
-	assert_pch_pll_enabled(dev_priv,
-			       to_intel_crtc(crtc)->pch_pll,
-			       to_intel_crtc(crtc));
+	assert_shared_dpll_enabled(dev_priv,
+				   intel_crtc_to_shared_dpll(intel_crtc));
 
 	/* FDI must be feeding us bits for PCH ports */
 	assert_fdi_tx_enabled(dev_priv, pipe);
@@ -1706,7 +1483,7 @@ static void ironlake_enable_pch_transcod
 		I915_WRITE(reg, val);
 	}
 
-	reg = TRANSCONF(pipe);
+	reg = PCH_TRANSCONF(pipe);
 	val = I915_READ(reg);
 	pipeconf_val = I915_READ(PIPECONF(pipe));
 
@@ -1731,7 +1508,7 @@ static void ironlake_enable_pch_transcod
 
 	I915_WRITE(reg, val | TRANS_ENABLE);
 	if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100))
-		DRM_ERROR("failed to enable transcoder %d\n", pipe);
+		DRM_ERROR("failed to enable transcoder %c\n", pipe_name(pipe));
 }
 
 static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
@@ -1760,8 +1537,8 @@ static void lpt_enable_pch_transcoder(st
 	else
 		val |= TRANS_PROGRESSIVE;
 
-	I915_WRITE(TRANSCONF(TRANSCODER_A), val);
-	if (wait_for(I915_READ(_TRANSACONF) & TRANS_STATE_ENABLE, 100))
+	I915_WRITE(LPT_TRANSCONF, val);
+	if (wait_for(I915_READ(LPT_TRANSCONF) & TRANS_STATE_ENABLE, 100))
 		DRM_ERROR("Failed to enable PCH transcoder\n");
 }
 
@@ -1778,13 +1555,13 @@ static void ironlake_disable_pch_transco
 	/* Ports must be off as well */
 	assert_pch_ports_disabled(dev_priv, pipe);
 
-	reg = TRANSCONF(pipe);
+	reg = PCH_TRANSCONF(pipe);
 	val = I915_READ(reg);
 	val &= ~TRANS_ENABLE;
 	I915_WRITE(reg, val);
 	/* wait for PCH transcoder off, transcoder state */
 	if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50))
-		DRM_ERROR("failed to disable transcoder %d\n", pipe);
+		DRM_ERROR("failed to disable transcoder %c\n", pipe_name(pipe));
 
 	if (!HAS_PCH_IBX(dev)) {
 		/* Workaround: Clear the timing override chicken bit again. */
@@ -1799,11 +1576,11 @@ static void lpt_disable_pch_transcoder(s
 {
 	u32 val;
 
-	val = I915_READ(_TRANSACONF);
+	val = I915_READ(LPT_TRANSCONF);
 	val &= ~TRANS_ENABLE;
-	I915_WRITE(_TRANSACONF, val);
+	I915_WRITE(LPT_TRANSCONF, val);
 	/* wait for PCH transcoder off, transcoder state */
-	if (wait_for((I915_READ(_TRANSACONF) & TRANS_STATE_ENABLE) == 0, 50))
+	if (wait_for((I915_READ(LPT_TRANSCONF) & TRANS_STATE_ENABLE) == 0, 50))
 		DRM_ERROR("Failed to disable PCH transcoder\n");
 
 	/* Workaround: clear timing override bit. */
@@ -1835,6 +1612,9 @@ static void intel_enable_pipe(struct drm
 	int reg;
 	u32 val;
 
+	assert_planes_disabled(dev_priv, pipe);
+	assert_sprites_disabled(dev_priv, pipe);
+
 	if (HAS_PCH_LPT(dev_priv->dev))
 		pch_transcoder = TRANSCODER_A;
 	else
@@ -2096,7 +1876,7 @@ static int i9xx_update_plane(struct drm_
 	case 1:
 		break;
 	default:
-		DRM_ERROR("Can't update plane %d in SAREA\n", plane);
+		DRM_ERROR("Can't update plane %c in SAREA\n", plane_name(plane));
 		return -EINVAL;
 	}
 
@@ -2145,6 +1925,9 @@ static int i9xx_update_plane(struct drm_
 			dspcntr &= ~DISPPLANE_TILED;
 	}
 
+	if (IS_G4X(dev))
+		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
+
 	I915_WRITE(reg, dspcntr);
 
 	linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
@@ -2193,7 +1976,7 @@ static int ironlake_update_plane(struct
 	case 2:
 		break;
 	default:
-		DRM_ERROR("Can't update plane %d in SAREA\n", plane);
+		DRM_ERROR("Can't update plane %c in SAREA\n", plane_name(plane));
 		return -EINVAL;
 	}
 
@@ -2384,9 +2167,9 @@ intel_pipe_set_base(struct drm_crtc *crt
 	}
 
 	if (intel_crtc->plane > INTEL_INFO(dev)->num_pipes) {
-		DRM_ERROR("no plane for crtc: plane %d, num_pipes %d\n",
-				intel_crtc->plane,
-				INTEL_INFO(dev)->num_pipes);
+		DRM_ERROR("no plane for crtc: plane %c, num_pipes %d\n",
+			  plane_name(intel_crtc->plane),
+			  INTEL_INFO(dev)->num_pipes);
 		return -EINVAL;
 	}
 
@@ -2414,7 +2197,8 @@ intel_pipe_set_base(struct drm_crtc *crt
 	crtc->y = y;
 
 	if (old_fb) {
-		intel_wait_for_vblank(dev, intel_crtc->pipe);
+		if (intel_crtc->active && old_fb != fb)
+			intel_wait_for_vblank(dev, intel_crtc->pipe);
 		intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj);
 	}
 
@@ -2467,6 +2251,11 @@ static void intel_fdi_normal_train(struc
 			   FDI_FE_ERRC_ENABLE);
 }
 
+static bool pipe_has_enabled_pch(struct intel_crtc *intel_crtc)
+{
+	return intel_crtc->base.enabled && intel_crtc->config.has_pch_encoder;
+}
+
 static void ivb_modeset_global_resources(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2476,10 +2265,13 @@ static void ivb_modeset_global_resources
 		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_C]);
 	uint32_t temp;
 
-	/* When everything is off disable fdi C so that we could enable fdi B
-	 * with all lanes. XXX: This misses the case where a pipe is not using
-	 * any pch resources and so doesn't need any fdi lanes. */
-	if (!pipe_B_crtc->base.enabled && !pipe_C_crtc->base.enabled) {
+	/*
+	 * When everything is off disable fdi C so that we could enable fdi B
+	 * with all lanes. Note that we don't care about enabled pipes without
+	 * an enabled pch encoder.
+	 */
+	if (!pipe_has_enabled_pch(pipe_B_crtc) &&
+	    !pipe_has_enabled_pch(pipe_C_crtc)) {
 		WARN_ON(I915_READ(FDI_RX_CTL(PIPE_B)) & FDI_RX_ENABLE);
 		WARN_ON(I915_READ(FDI_RX_CTL(PIPE_C)) & FDI_RX_ENABLE);
 
@@ -2517,8 +2309,8 @@ static void ironlake_fdi_link_train(stru
 	/* enable CPU FDI TX and PCH FDI RX */
 	reg = FDI_TX_CTL(pipe);
 	temp = I915_READ(reg);
-	temp &= ~(7 << 19);
-	temp |= (intel_crtc->fdi_lanes - 1) << 19;
+	temp &= ~FDI_DP_PORT_WIDTH_MASK;
+	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
 	temp &= ~FDI_LINK_TRAIN_NONE;
 	temp |= FDI_LINK_TRAIN_PATTERN_1;
 	I915_WRITE(reg, temp | FDI_TX_ENABLE);
@@ -2615,8 +2407,8 @@ static void gen6_fdi_link_train(struct d
 	/* enable CPU FDI TX and PCH FDI RX */
 	reg = FDI_TX_CTL(pipe);
 	temp = I915_READ(reg);
-	temp &= ~(7 << 19);
-	temp |= (intel_crtc->fdi_lanes - 1) << 19;
+	temp &= ~FDI_DP_PORT_WIDTH_MASK;
+	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
 	temp &= ~FDI_LINK_TRAIN_NONE;
 	temp |= FDI_LINK_TRAIN_PATTERN_1;
 	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
@@ -2750,8 +2542,8 @@ static void ivb_manual_fdi_link_train(st
 	/* enable CPU FDI TX and PCH FDI RX */
 	reg = FDI_TX_CTL(pipe);
 	temp = I915_READ(reg);
-	temp &= ~(7 << 19);
-	temp |= (intel_crtc->fdi_lanes - 1) << 19;
+	temp &= ~FDI_DP_PORT_WIDTH_MASK;
+	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
 	temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
 	temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
 	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
@@ -2852,8 +2644,8 @@ static void ironlake_fdi_pll_enable(stru
 	/* enable PCH FDI RX PLL, wait warmup plus DMI latency */
 	reg = FDI_RX_CTL(pipe);
 	temp = I915_READ(reg);
-	temp &= ~((0x7 << 19) | (0x7 << 16));
-	temp |= (intel_crtc->fdi_lanes - 1) << 19;
+	temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
+	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config.fdi_lanes);
 	temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
 	I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE);
 
@@ -3085,6 +2877,30 @@ static void lpt_program_iclkip(struct dr
 	mutex_unlock(&dev_priv->dpio_lock);
 }
 
+static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
+						enum pipe pch_transcoder)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
+
+	I915_WRITE(PCH_TRANS_HTOTAL(pch_transcoder),
+		   I915_READ(HTOTAL(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_HBLANK(pch_transcoder),
+		   I915_READ(HBLANK(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_HSYNC(pch_transcoder),
+		   I915_READ(HSYNC(cpu_transcoder)));
+
+	I915_WRITE(PCH_TRANS_VTOTAL(pch_transcoder),
+		   I915_READ(VTOTAL(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_VBLANK(pch_transcoder),
+		   I915_READ(VBLANK(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_VSYNC(pch_transcoder),
+		   I915_READ(VSYNC(cpu_transcoder)));
+	I915_WRITE(PCH_TRANS_VSYNCSHIFT(pch_transcoder),
+		   I915_READ(VSYNCSHIFT(cpu_transcoder)));
+}
+
 /*
  * Enable PCH resources required for PCH ports:
  *   - PCH PLLs
@@ -3101,7 +2917,7 @@ static void ironlake_pch_enable(struct d
 	int pipe = intel_crtc->pipe;
 	u32 reg, temp;
 
-	assert_transcoder_disabled(dev_priv, pipe);
+	assert_pch_transcoder_disabled(dev_priv, pipe);
 
 	/* Write the TU size bits before fdi link training, so that error
 	 * detection works. */
@@ -3115,31 +2931,18 @@ static void ironlake_pch_enable(struct d
 	 * transcoder, and we actually should do this to not upset any PCH
 	 * transcoder that already use the clock when we share it.
 	 *
-	 * Note that enable_pch_pll tries to do the right thing, but get_pch_pll
-	 * unconditionally resets the pll - we need that to have the right LVDS
-	 * enable sequence. */
-	ironlake_enable_pch_pll(intel_crtc);
+	 * Note that enable_shared_dpll tries to do the right thing, but
+	 * get_shared_dpll unconditionally resets the pll - we need that to have
+	 * the right LVDS enable sequence. */
+	ironlake_enable_shared_dpll(intel_crtc);
 
 	if (HAS_PCH_CPT(dev)) {
 		u32 sel;
 
 		temp = I915_READ(PCH_DPLL_SEL);
-		switch (pipe) {
-		default:
-		case 0:
-			temp |= TRANSA_DPLL_ENABLE;
-			sel = TRANSA_DPLLB_SEL;
-			break;
-		case 1:
-			temp |= TRANSB_DPLL_ENABLE;
-			sel = TRANSB_DPLLB_SEL;
-			break;
-		case 2:
-			temp |= TRANSC_DPLL_ENABLE;
-			sel = TRANSC_DPLLB_SEL;
-			break;
-		}
-		if (intel_crtc->pch_pll->pll_reg == _PCH_DPLL_B)
+		temp |= TRANS_DPLL_ENABLE(pipe);
+		sel = TRANS_DPLLB_SEL(pipe);
+		if (intel_crtc->config.shared_dpll == DPLL_ID_PCH_PLL_B)
 			temp |= sel;
 		else
 			temp &= ~sel;
@@ -3148,14 +2951,7 @@ static void ironlake_pch_enable(struct d
 
 	/* set transcoder timing, panel must allow it */
 	assert_panel_unlocked(dev_priv, pipe);
-	I915_WRITE(TRANS_HTOTAL(pipe), I915_READ(HTOTAL(pipe)));
-	I915_WRITE(TRANS_HBLANK(pipe), I915_READ(HBLANK(pipe)));
-	I915_WRITE(TRANS_HSYNC(pipe),  I915_READ(HSYNC(pipe)));
-
-	I915_WRITE(TRANS_VTOTAL(pipe), I915_READ(VTOTAL(pipe)));
-	I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe)));
-	I915_WRITE(TRANS_VSYNC(pipe),  I915_READ(VSYNC(pipe)));
-	I915_WRITE(TRANS_VSYNCSHIFT(pipe),  I915_READ(VSYNCSHIFT(pipe)));
+	ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
 
 	intel_fdi_normal_train(crtc);
 
@@ -3205,86 +3001,82 @@ static void lpt_pch_enable(struct drm_cr
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
 
-	assert_transcoder_disabled(dev_priv, TRANSCODER_A);
+	assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
 
 	lpt_program_iclkip(crtc);
 
 	/* Set transcoder timing. */
-	I915_WRITE(_TRANS_HTOTAL_A, I915_READ(HTOTAL(cpu_transcoder)));
-	I915_WRITE(_TRANS_HBLANK_A, I915_READ(HBLANK(cpu_transcoder)));
-	I915_WRITE(_TRANS_HSYNC_A,  I915_READ(HSYNC(cpu_transcoder)));
-
-	I915_WRITE(_TRANS_VTOTAL_A, I915_READ(VTOTAL(cpu_transcoder)));
-	I915_WRITE(_TRANS_VBLANK_A, I915_READ(VBLANK(cpu_transcoder)));
-	I915_WRITE(_TRANS_VSYNC_A,  I915_READ(VSYNC(cpu_transcoder)));
-	I915_WRITE(_TRANS_VSYNCSHIFT_A, I915_READ(VSYNCSHIFT(cpu_transcoder)));
+	ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A);
 
 	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
 }
 
-static void intel_put_pch_pll(struct intel_crtc *intel_crtc)
+static void intel_put_shared_dpll(struct intel_crtc *crtc)
 {
-	struct intel_pch_pll *pll = intel_crtc->pch_pll;
+	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
 
 	if (pll == NULL)
 		return;
 
 	if (pll->refcount == 0) {
-		WARN(1, "bad PCH PLL refcount\n");
+		WARN(1, "bad %s refcount\n", pll->name);
 		return;
 	}
 
-	--pll->refcount;
-	intel_crtc->pch_pll = NULL;
+	if (--pll->refcount == 0) {
+		WARN_ON(pll->on);
+		WARN_ON(pll->active);
+	}
+
+	crtc->config.shared_dpll = DPLL_ID_PRIVATE;
 }
 
-static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u32 dpll, u32 fp)
+static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, u32 dpll, u32 fp)
 {
-	struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
-	struct intel_pch_pll *pll;
-	int i;
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+	enum intel_dpll_id i;
 
-	pll = intel_crtc->pch_pll;
 	if (pll) {
-		DRM_DEBUG_KMS("CRTC:%d reusing existing PCH PLL %x\n",
-			      intel_crtc->base.base.id, pll->pll_reg);
-		goto prepare;
+		DRM_DEBUG_KMS("CRTC:%d dropping existing %s\n",
+			      crtc->base.base.id, pll->name);
+		intel_put_shared_dpll(crtc);
 	}
 
 	if (HAS_PCH_IBX(dev_priv->dev)) {
 		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
-		i = intel_crtc->pipe;
-		pll = &dev_priv->pch_plls[i];
+		i = crtc->pipe;
+		pll = &dev_priv->shared_dplls[i];
 
-		DRM_DEBUG_KMS("CRTC:%d using pre-allocated PCH PLL %x\n",
-			      intel_crtc->base.base.id, pll->pll_reg);
+		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
+			      crtc->base.base.id, pll->name);
 
 		goto found;
 	}
 
-	for (i = 0; i < dev_priv->num_pch_pll; i++) {
-		pll = &dev_priv->pch_plls[i];
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		pll = &dev_priv->shared_dplls[i];
 
 		/* Only want to check enabled timings first */
 		if (pll->refcount == 0)
 			continue;
 
-		if (dpll == (I915_READ(pll->pll_reg) & 0x7fffffff) &&
-		    fp == I915_READ(pll->fp0_reg)) {
-			DRM_DEBUG_KMS("CRTC:%d sharing existing PCH PLL %x (refcount %d, ative %d)\n",
-				      intel_crtc->base.base.id,
-				      pll->pll_reg, pll->refcount, pll->active);
+		if (dpll == (I915_READ(PCH_DPLL(pll->id)) & 0x7fffffff) &&
+		    fp == I915_READ(PCH_FP0(pll->id))) {
+			DRM_DEBUG_KMS("CRTC:%d sharing existing %s (refcount %d, ative %d)\n",
+				      crtc->base.base.id,
+				      pll->name, pll->refcount, pll->active);
 
 			goto found;
 		}
 	}
 
 	/* Ok no matching timings, maybe there's a free one? */
-	for (i = 0; i < dev_priv->num_pch_pll; i++) {
-		pll = &dev_priv->pch_plls[i];
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		pll = &dev_priv->shared_dplls[i];
 		if (pll->refcount == 0) {
-			DRM_DEBUG_KMS("CRTC:%d allocated PCH PLL %x\n",
-				      intel_crtc->base.base.id, pll->pll_reg);
+			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
+				      crtc->base.base.id, pll->name);
 			goto found;
 		}
 	}
@@ -3292,24 +3084,32 @@ static struct intel_pch_pll *intel_get_p
 	return NULL;
 
 found:
-	intel_crtc->pch_pll = pll;
-	pll->refcount++;
-	DRM_DEBUG_DRIVER("using pll %d for pipe %d\n", i, intel_crtc->pipe);
-prepare: /* separate function? */
-	DRM_DEBUG_DRIVER("switching PLL %x off\n", pll->pll_reg);
+	crtc->config.shared_dpll = i;
+	DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
+			 pipe_name(crtc->pipe));
 
-	/* Wait for the clocks to stabilize before rewriting the regs */
-	I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE);
-	POSTING_READ(pll->pll_reg);
-	udelay(150);
+	if (pll->active == 0) {
+		memcpy(&pll->hw_state, &crtc->config.dpll_hw_state,
+		       sizeof(pll->hw_state));
+
+		DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
+		WARN_ON(pll->on);
+		assert_shared_dpll_disabled(dev_priv, pll);
+
+		/* Wait for the clocks to stabilize before rewriting the regs */
+		I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE);
+		POSTING_READ(PCH_DPLL(pll->id));
+		udelay(150);
+
+		I915_WRITE(PCH_FP0(pll->id), fp);
+		I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE);
+	}
+	pll->refcount++;
 
-	I915_WRITE(pll->fp0_reg, fp);
-	I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE);
-	pll->on = false;
 	return pll;
 }
 
-void intel_cpt_verify_modeset(struct drm_device *dev, int pipe)
+static void cpt_verify_modeset(struct drm_device *dev, int pipe)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int dslreg = PIPEDSL(pipe);
@@ -3319,10 +3119,53 @@ void intel_cpt_verify_modeset(struct drm
 	udelay(500);
 	if (wait_for(I915_READ(dslreg) != temp, 5)) {
 		if (wait_for(I915_READ(dslreg) != temp, 5))
-			DRM_ERROR("mode set failed: pipe %d stuck\n", pipe);
+			DRM_ERROR("mode set failed: pipe %c stuck\n", pipe_name(pipe));
+	}
+}
+
+static void ironlake_pfit_enable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	if (crtc->config.pch_pfit.size) {
+		/* Force use of hard-coded filter coefficients
+		 * as some pre-programmed values are broken,
+		 * e.g. x201.
+		 */
+		if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
+			I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 |
+						 PF_PIPE_SEL_IVB(pipe));
+		else
+			I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
+		I915_WRITE(PF_WIN_POS(pipe), crtc->config.pch_pfit.pos);
+		I915_WRITE(PF_WIN_SZ(pipe), crtc->config.pch_pfit.size);
 	}
 }
 
+static void intel_enable_planes(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+	struct intel_plane *intel_plane;
+
+	list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head)
+		if (intel_plane->pipe == pipe)
+			intel_plane_restore(&intel_plane->base);
+}
+
+static void intel_disable_planes(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	enum pipe pipe = to_intel_crtc(crtc)->pipe;
+	struct intel_plane *intel_plane;
+
+	list_for_each_entry(intel_plane, &dev->mode_config.plane_list, base.head)
+		if (intel_plane->pipe == pipe)
+			intel_plane_disable(&intel_plane->base);
+}
+
 static void ironlake_crtc_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -3339,6 +3182,10 @@ static void ironlake_crtc_enable(struct
 		return;
 
 	intel_crtc->active = true;
+
+	intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
+	intel_set_pch_fifo_underrun_reporting(dev, pipe, true);
+
 	intel_update_watermarks(dev);
 
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
@@ -3362,22 +3209,7 @@ static void ironlake_crtc_enable(struct
 		if (encoder->pre_enable)
 			encoder->pre_enable(encoder);
 
-	/* Enable panel fitting for LVDS */
-	if (dev_priv->pch_pf_size &&
-	    (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
-	     intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
-		/* Force use of hard-coded filter coefficients
-		 * as some pre-programmed values are broken,
-		 * e.g. x201.
-		 */
-		if (IS_IVYBRIDGE(dev))
-			I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 |
-						 PF_PIPE_SEL_IVB(pipe));
-		else
-			I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
-		I915_WRITE(PF_WIN_POS(pipe), dev_priv->pch_pf_pos);
-		I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size);
-	}
+	ironlake_pfit_enable(intel_crtc);
 
 	/*
 	 * On ILK+ LUT must be loaded before the pipe is running but with
@@ -3388,6 +3220,8 @@ static void ironlake_crtc_enable(struct
 	intel_enable_pipe(dev_priv, pipe,
 			  intel_crtc->config.has_pch_encoder);
 	intel_enable_plane(dev_priv, plane, pipe);
+	intel_enable_planes(crtc);
+	intel_crtc_update_cursor(crtc, true);
 
 	if (intel_crtc->config.has_pch_encoder)
 		ironlake_pch_enable(crtc);
@@ -3396,13 +3230,11 @@ static void ironlake_crtc_enable(struct
 	intel_update_fbc(dev);
 	mutex_unlock(&dev->struct_mutex);
 
-	intel_crtc_update_cursor(crtc, true);
-
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		encoder->enable(encoder);
 
 	if (HAS_PCH_CPT(dev))
-		intel_cpt_verify_modeset(dev, intel_crtc->pipe);
+		cpt_verify_modeset(dev, intel_crtc->pipe);
 
 	/*
 	 * There seems to be a race in PCH platform hw (at least on some
@@ -3415,6 +3247,42 @@ static void ironlake_crtc_enable(struct
 	intel_wait_for_vblank(dev, intel_crtc->pipe);
 }
 
+/* IPS only exists on ULT machines and is tied to pipe A. */
+static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
+{
+	return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
+}
+
+static void hsw_enable_ips(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+
+	if (!crtc->config.ips_enabled)
+		return;
+
+	/* We can only enable IPS after we enable a plane and wait for a vblank.
+	 * We guarantee that the plane is enabled by calling intel_enable_ips
+	 * only after intel_enable_plane. And intel_enable_plane already waits
+	 * for a vblank, so all we need to do here is to enable the IPS bit. */
+	assert_plane_enabled(dev_priv, crtc->plane);
+	I915_WRITE(IPS_CTL, IPS_ENABLE);
+}
+
+static void hsw_disable_ips(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!crtc->config.ips_enabled)
+		return;
+
+	assert_plane_enabled(dev_priv, crtc->plane);
+	I915_WRITE(IPS_CTL, 0);
+
+	/* We need to wait for a vblank before we can disable the plane. */
+	intel_wait_for_vblank(dev, crtc->pipe);
+}
+
 static void haswell_crtc_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -3430,6 +3298,11 @@ static void haswell_crtc_enable(struct d
 		return;
 
 	intel_crtc->active = true;
+
+	intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
+	if (intel_crtc->config.has_pch_encoder)
+		intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true);
+
 	intel_update_watermarks(dev);
 
 	if (intel_crtc->config.has_pch_encoder)
@@ -3441,18 +3314,7 @@ static void haswell_crtc_enable(struct d
 
 	intel_ddi_enable_pipe_clock(intel_crtc);
 
-	/* Enable panel fitting for eDP */
-	if (dev_priv->pch_pf_size &&
-	    intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
-		/* Force use of hard-coded filter coefficients
-		 * as some pre-programmed values are broken,
-		 * e.g. x201.
-		 */
-		I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 |
-					 PF_PIPE_SEL_IVB(pipe));
-		I915_WRITE(PF_WIN_POS(pipe), dev_priv->pch_pf_pos);
-		I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size);
-	}
+	ironlake_pfit_enable(intel_crtc);
 
 	/*
 	 * On ILK+ LUT must be loaded before the pipe is running but with
@@ -3466,6 +3328,10 @@ static void haswell_crtc_enable(struct d
 	intel_enable_pipe(dev_priv, pipe,
 			  intel_crtc->config.has_pch_encoder);
 	intel_enable_plane(dev_priv, plane, pipe);
+	intel_enable_planes(crtc);
+	intel_crtc_update_cursor(crtc, true);
+
+	hsw_enable_ips(intel_crtc);
 
 	if (intel_crtc->config.has_pch_encoder)
 		lpt_pch_enable(crtc);
@@ -3474,8 +3340,6 @@ static void haswell_crtc_enable(struct d
 	intel_update_fbc(dev);
 	mutex_unlock(&dev->struct_mutex);
 
-	intel_crtc_update_cursor(crtc, true);
-
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		encoder->enable(encoder);
 
@@ -3490,6 +3354,21 @@ static void haswell_crtc_enable(struct d
 	intel_wait_for_vblank(dev, intel_crtc->pipe);
 }
 
+static void ironlake_pfit_disable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	/* To avoid upsetting the power well on haswell only disable the pfit if
+	 * it's in use. The hw state code will make sure we get this right. */
+	if (crtc->config.pch_pfit.size) {
+		I915_WRITE(PF_CTL(pipe), 0);
+		I915_WRITE(PF_WIN_POS(pipe), 0);
+		I915_WRITE(PF_WIN_SZ(pipe), 0);
+	}
+}
+
 static void ironlake_crtc_disable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -3509,58 +3388,51 @@ static void ironlake_crtc_disable(struct
 
 	intel_crtc_wait_for_pending_flips(crtc);
 	drm_vblank_off(dev, pipe);
-	intel_crtc_update_cursor(crtc, false);
-
-	intel_disable_plane(dev_priv, plane, pipe);
 
 	if (dev_priv->cfb_plane == plane)
 		intel_disable_fbc(dev);
 
+	intel_crtc_update_cursor(crtc, false);
+	intel_disable_planes(crtc);
+	intel_disable_plane(dev_priv, plane, pipe);
+
+	if (intel_crtc->config.has_pch_encoder)
+		intel_set_pch_fifo_underrun_reporting(dev, pipe, false);
+
 	intel_disable_pipe(dev_priv, pipe);
 
-	/* Disable PF */
-	I915_WRITE(PF_CTL(pipe), 0);
-	I915_WRITE(PF_WIN_SZ(pipe), 0);
+	ironlake_pfit_disable(intel_crtc);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		if (encoder->post_disable)
 			encoder->post_disable(encoder);
 
-	ironlake_fdi_disable(crtc);
+	if (intel_crtc->config.has_pch_encoder) {
+		ironlake_fdi_disable(crtc);
 
-	ironlake_disable_pch_transcoder(dev_priv, pipe);
+		ironlake_disable_pch_transcoder(dev_priv, pipe);
+		intel_set_pch_fifo_underrun_reporting(dev, pipe, true);
 
-	if (HAS_PCH_CPT(dev)) {
-		/* disable TRANS_DP_CTL */
-		reg = TRANS_DP_CTL(pipe);
-		temp = I915_READ(reg);
-		temp &= ~(TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK);
-		temp |= TRANS_DP_PORT_SEL_NONE;
-		I915_WRITE(reg, temp);
+		if (HAS_PCH_CPT(dev)) {
+			/* disable TRANS_DP_CTL */
+			reg = TRANS_DP_CTL(pipe);
+			temp = I915_READ(reg);
+			temp &= ~(TRANS_DP_OUTPUT_ENABLE |
+				  TRANS_DP_PORT_SEL_MASK);
+			temp |= TRANS_DP_PORT_SEL_NONE;
+			I915_WRITE(reg, temp);
 
-		/* disable DPLL_SEL */
-		temp = I915_READ(PCH_DPLL_SEL);
-		switch (pipe) {
-		case 0:
-			temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL);
-			break;
-		case 1:
-			temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL);
-			break;
-		case 2:
-			/* C shares PLL A or B */
-			temp &= ~(TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL);
-			break;
-		default:
-			BUG(); /* wtf */
+			/* disable DPLL_SEL */
+			temp = I915_READ(PCH_DPLL_SEL);
+			temp &= ~(TRANS_DPLL_ENABLE(pipe) | TRANS_DPLLB_SEL(pipe));
+			I915_WRITE(PCH_DPLL_SEL, temp);
 		}
-		I915_WRITE(PCH_DPLL_SEL, temp);
-	}
 
-	/* disable PCH DPLL */
-	intel_disable_pch_pll(intel_crtc);
+		/* disable PCH DPLL */
+		intel_disable_shared_dpll(intel_crtc);
 
-	ironlake_fdi_pll_disable(intel_crtc);
+		ironlake_fdi_pll_disable(intel_crtc);
+	}
 
 	intel_crtc->active = false;
 	intel_update_watermarks(dev);
@@ -3588,24 +3460,24 @@ static void haswell_crtc_disable(struct
 
 	intel_crtc_wait_for_pending_flips(crtc);
 	drm_vblank_off(dev, pipe);
-	intel_crtc_update_cursor(crtc, false);
-
-	intel_disable_plane(dev_priv, plane, pipe);
 
+	/* FBC must be disabled before disabling the plane on HSW. */
 	if (dev_priv->cfb_plane == plane)
 		intel_disable_fbc(dev);
 
+	hsw_disable_ips(intel_crtc);
+
+	intel_crtc_update_cursor(crtc, false);
+	intel_disable_planes(crtc);
+	intel_disable_plane(dev_priv, plane, pipe);
+
+	if (intel_crtc->config.has_pch_encoder)
+		intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false);
 	intel_disable_pipe(dev_priv, pipe);
 
 	intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
 
-	/* XXX: Once we have proper panel fitter state tracking implemented with
-	 * hardware state read/check support we should switch to only disable
-	 * the panel fitter when we know it's used. */
-	if (intel_using_power_well(dev)) {
-		I915_WRITE(PF_CTL(pipe), 0);
-		I915_WRITE(PF_WIN_SZ(pipe), 0);
-	}
+	ironlake_pfit_disable(intel_crtc);
 
 	intel_ddi_disable_pipe_clock(intel_crtc);
 
@@ -3615,6 +3487,7 @@ static void haswell_crtc_disable(struct
 
 	if (intel_crtc->config.has_pch_encoder) {
 		lpt_disable_pch_transcoder(dev_priv);
+		intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true);
 		intel_ddi_fdi_disable(crtc);
 	}
 
@@ -3629,17 +3502,11 @@ static void haswell_crtc_disable(struct
 static void ironlake_crtc_off(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	intel_put_pch_pll(intel_crtc);
+	intel_put_shared_dpll(intel_crtc);
 }
 
 static void haswell_crtc_off(struct drm_crtc *crtc)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-	/* Stop saying we're using TRANSCODER_EDP because some other CRTC might
-	 * start using it. */
-	intel_crtc->config.cpu_transcoder = (enum transcoder) intel_crtc->pipe;
-
 	intel_ddi_put_crtc_pll(crtc);
 }
 
@@ -3685,6 +3552,77 @@ g4x_fixup_plane(struct drm_i915_private
 	}
 }
 
+static void i9xx_pfit_enable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc_config *pipe_config = &crtc->config;
+
+	if (!crtc->config.gmch_pfit.control)
+		return;
+
+	/*
+	 * The panel fitter should only be adjusted whilst the pipe is disabled,
+	 * according to register description and PRM.
+	 */
+	WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE);
+	assert_pipe_disabled(dev_priv, crtc->pipe);
+
+	I915_WRITE(PFIT_PGM_RATIOS, pipe_config->gmch_pfit.pgm_ratios);
+	I915_WRITE(PFIT_CONTROL, pipe_config->gmch_pfit.control);
+
+	/* Border color in case we don't scale up to the full screen. Black by
+	 * default, change to something else for debugging. */
+	I915_WRITE(BCLRPAT(crtc->pipe), 0);
+}
+
+static void valleyview_crtc_enable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_encoder *encoder;
+	int pipe = intel_crtc->pipe;
+	int plane = intel_crtc->plane;
+
+	WARN_ON(!crtc->enabled);
+
+	if (intel_crtc->active)
+		return;
+
+	intel_crtc->active = true;
+	intel_update_watermarks(dev);
+
+	mutex_lock(&dev_priv->dpio_lock);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->pre_pll_enable)
+			encoder->pre_pll_enable(encoder);
+
+	intel_enable_pll(dev_priv, pipe);
+
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->pre_enable)
+			encoder->pre_enable(encoder);
+
+	/* VLV wants encoder enabling _before_ the pipe is up. */
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		encoder->enable(encoder);
+
+	i9xx_pfit_enable(intel_crtc);
+
+	intel_crtc_load_lut(crtc);
+
+	intel_enable_pipe(dev_priv, pipe, false);
+	intel_enable_plane(dev_priv, plane, pipe);
+	intel_enable_planes(crtc);
+	intel_crtc_update_cursor(crtc, true);
+
+	intel_update_fbc(dev);
+
+	mutex_unlock(&dev_priv->dpio_lock);
+}
+
 static void i9xx_crtc_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -3708,17 +3646,22 @@ static void i9xx_crtc_enable(struct drm_
 		if (encoder->pre_enable)
 			encoder->pre_enable(encoder);
 
+	i9xx_pfit_enable(intel_crtc);
+
+	intel_crtc_load_lut(crtc);
+
 	intel_enable_pipe(dev_priv, pipe, false);
 	intel_enable_plane(dev_priv, plane, pipe);
+	intel_enable_planes(crtc);
+	/* The fixup needs to happen before cursor is enabled */
 	if (IS_G4X(dev))
 		g4x_fixup_plane(dev_priv, pipe);
-
-	intel_crtc_load_lut(crtc);
-	intel_update_fbc(dev);
+	intel_crtc_update_cursor(crtc, true);
 
 	/* Give the overlay scaler a chance to enable if it's on this pipe */
 	intel_crtc_dpms_overlay(intel_crtc, true);
-	intel_crtc_update_cursor(crtc, true);
+
+	intel_update_fbc(dev);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		encoder->enable(encoder);
@@ -3728,20 +3671,15 @@ static void i9xx_pfit_disable(struct int
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum pipe pipe;
-	uint32_t pctl = I915_READ(PFIT_CONTROL);
 
-	assert_pipe_disabled(dev_priv, crtc->pipe);
+	if (!crtc->config.gmch_pfit.control)
+		return;
 
-	if (INTEL_INFO(dev)->gen >= 4)
-		pipe = (pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT;
-	else
-		pipe = PIPE_B;
+	assert_pipe_disabled(dev_priv, crtc->pipe);
 
-	if (pipe == crtc->pipe) {
-		DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n", pctl);
-		I915_WRITE(PFIT_CONTROL, 0);
-	}
+	DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n",
+			 I915_READ(PFIT_CONTROL));
+	I915_WRITE(PFIT_CONTROL, 0);
 }
 
 static void i9xx_crtc_disable(struct drm_crtc *crtc)
@@ -3762,17 +3700,23 @@ static void i9xx_crtc_disable(struct drm
 	/* Give the overlay scaler a chance to disable if it's on this pipe */
 	intel_crtc_wait_for_pending_flips(crtc);
 	drm_vblank_off(dev, pipe);
-	intel_crtc_dpms_overlay(intel_crtc, false);
-	intel_crtc_update_cursor(crtc, false);
 
 	if (dev_priv->cfb_plane == plane)
 		intel_disable_fbc(dev);
 
+	intel_crtc_dpms_overlay(intel_crtc, false);
+	intel_crtc_update_cursor(crtc, false);
+	intel_disable_planes(crtc);
 	intel_disable_plane(dev_priv, plane, pipe);
+
 	intel_disable_pipe(dev_priv, pipe);
 
 	i9xx_pfit_disable(intel_crtc);
 
+	for_each_encoder_on_crtc(dev, crtc, encoder)
+		if (encoder->post_disable)
+			encoder->post_disable(encoder);
+
 	intel_disable_pll(dev_priv, pipe);
 
 	intel_crtc->active = false;
@@ -3845,8 +3789,8 @@ static void intel_crtc_disable(struct dr
 	/* crtc should still be enabled when we disable it. */
 	WARN_ON(!crtc->enabled);
 
-	intel_crtc->eld_vld = false;
 	dev_priv->display.crtc_disable(crtc);
+	intel_crtc->eld_vld = false;
 	intel_crtc_update_sarea(crtc, false);
 	dev_priv->display.off(crtc);
 
@@ -3977,17 +3921,131 @@ bool intel_connector_get_hw_state(struct
 	return encoder->get_hw_state(encoder, &pipe);
 }
 
-static bool intel_crtc_compute_config(struct drm_crtc *crtc,
-				      struct intel_crtc_config *pipe_config)
+static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
+				     struct intel_crtc_config *pipe_config)
 {
-	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *pipe_B_crtc =
+		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_B]);
+
+	DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n",
+		      pipe_name(pipe), pipe_config->fdi_lanes);
+	if (pipe_config->fdi_lanes > 4) {
+		DRM_DEBUG_KMS("invalid fdi lane config on pipe %c: %i lanes\n",
+			      pipe_name(pipe), pipe_config->fdi_lanes);
+		return false;
+	}
+
+	if (IS_HASWELL(dev)) {
+		if (pipe_config->fdi_lanes > 2) {
+			DRM_DEBUG_KMS("only 2 lanes on haswell, required: %i lanes\n",
+				      pipe_config->fdi_lanes);
+			return false;
+		} else {
+			return true;
+		}
+	}
+
+	if (INTEL_INFO(dev)->num_pipes == 2)
+		return true;
+
+	/* Ivybridge 3 pipe is really complicated */
+	switch (pipe) {
+	case PIPE_A:
+		return true;
+	case PIPE_B:
+		if (dev_priv->pipe_to_crtc_mapping[PIPE_C]->enabled &&
+		    pipe_config->fdi_lanes > 2) {
+			DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n",
+				      pipe_name(pipe), pipe_config->fdi_lanes);
+			return false;
+		}
+		return true;
+	case PIPE_C:
+		if (!pipe_has_enabled_pch(pipe_B_crtc) ||
+		    pipe_B_crtc->config.fdi_lanes <= 2) {
+			if (pipe_config->fdi_lanes > 2) {
+				DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n",
+					      pipe_name(pipe), pipe_config->fdi_lanes);
+				return false;
+			}
+		} else {
+			DRM_DEBUG_KMS("fdi link B uses too many lanes to enable link C\n");
+			return false;
+		}
+		return true;
+	default:
+		BUG();
+	}
+}
+
+#define RETRY 1
+static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
+				       struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+	int lane, link_bw, fdi_dotclock;
+	bool setup_ok, needs_recompute = false;
+
+retry:
+	/* FDI is a binary signal running at ~2.7GHz, encoding
+	 * each output octet as 10 bits. The actual frequency
+	 * is stored as a divider into a 100MHz clock, and the
+	 * mode pixel clock is stored in units of 1KHz.
+	 * Hence the bw of each lane in terms of the mode signal
+	 * is:
+	 */
+	link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
+
+	fdi_dotclock = adjusted_mode->clock;
+	fdi_dotclock /= pipe_config->pixel_multiplier;
+
+	lane = ironlake_get_lanes_required(fdi_dotclock, link_bw,
+					   pipe_config->pipe_bpp);
+
+	pipe_config->fdi_lanes = lane;
+
+	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
+			       link_bw, &pipe_config->fdi_m_n);
+
+	setup_ok = ironlake_check_fdi_lanes(intel_crtc->base.dev,
+					    intel_crtc->pipe, pipe_config);
+	if (!setup_ok && pipe_config->pipe_bpp > 6*3) {
+		pipe_config->pipe_bpp -= 2*3;
+		DRM_DEBUG_KMS("fdi link bw constraint, reducing pipe bpp to %i\n",
+			      pipe_config->pipe_bpp);
+		needs_recompute = true;
+		pipe_config->bw_constrained = true;
+
+		goto retry;
+	}
+
+	if (needs_recompute)
+		return RETRY;
+
+	return setup_ok ? 0 : -EINVAL;
+}
+
+static void hsw_compute_ips_config(struct intel_crtc *crtc,
+				   struct intel_crtc_config *pipe_config)
+{
+	pipe_config->ips_enabled = i915_enable_ips &&
+				   hsw_crtc_supports_ips(crtc) &&
+				   pipe_config->pipe_bpp == 24;
+}
+
+static int intel_crtc_compute_config(struct intel_crtc *crtc,
+				     struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 
 	if (HAS_PCH_SPLIT(dev)) {
 		/* FDI link clock is fixed at 2.7G */
 		if (pipe_config->requested_mode.clock * 3
 		    > IRONLAKE_FDI_FREQ * 4)
-			return false;
+			return -EINVAL;
 	}
 
 	/* All interlaced capable intel hw wants timings in frames. Note though
@@ -3996,12 +4054,12 @@ static bool intel_crtc_compute_config(st
 	if (!pipe_config->timings_set)
 		drm_mode_set_crtcinfo(adjusted_mode, 0);
 
-	/* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes
-	 * with a hsync front porch of 0.
+	/* Cantiga+ cannot handle modes with a hsync front porch of 0.
+	 * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
 	 */
 	if ((INTEL_INFO(dev)->gen > 4 || IS_G4X(dev)) &&
 		adjusted_mode->hsync_start == adjusted_mode->hdisplay)
-		return false;
+		return -EINVAL;
 
 	if ((IS_G4X(dev) || IS_VALLEYVIEW(dev)) && pipe_config->pipe_bpp > 10*3) {
 		pipe_config->pipe_bpp = 10*3; /* 12bpc is gen5+ */
@@ -4011,7 +4069,18 @@ static bool intel_crtc_compute_config(st
 		pipe_config->pipe_bpp = 8*3;
 	}
 
-	return true;
+	if (HAS_IPS(dev))
+		hsw_compute_ips_config(crtc, pipe_config);
+
+	/* XXX: PCH clock sharing is done in ->mode_set, so make sure the old
+	 * clock survives for now. */
+	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+		pipe_config->shared_dpll = crtc->config.shared_dpll;
+
+	if (pipe_config->has_pch_encoder)
+		return ironlake_fdi_compute_config(crtc, pipe_config);
+
+	return 0;
 }
 
 static int valleyview_get_display_clock_speed(struct drm_device *dev)
@@ -4120,7 +4189,7 @@ static inline bool intel_panel_use_ssc(s
 {
 	if (i915_panel_use_ssc >= 0)
 		return i915_panel_use_ssc != 0;
-	return dev_priv->lvds_use_ssc
+	return dev_priv->vbt.lvds_use_ssc
 		&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
 }
 
@@ -4156,7 +4225,7 @@ static int i9xx_get_refclk(struct drm_cr
 		refclk = vlv_get_refclk(crtc);
 	} else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
 	    intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
-		refclk = dev_priv->lvds_ssc_freq * 1000;
+		refclk = dev_priv->vbt.lvds_ssc_freq * 1000;
 		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
 			      refclk / 1000);
 	} else if (!IS_GEN2(dev)) {
@@ -4168,28 +4237,14 @@ static int i9xx_get_refclk(struct drm_cr
 	return refclk;
 }
 
-static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc *crtc)
+static uint32_t pnv_dpll_compute_fp(struct dpll *dpll)
 {
-	unsigned dotclock = crtc->config.adjusted_mode.clock;
-	struct dpll *clock = &crtc->config.dpll;
-
-	/* SDVO TV has fixed PLL values depend on its clock range,
-	   this mirrors vbios setting. */
-	if (dotclock >= 100000 && dotclock < 140500) {
-		clock->p1 = 2;
-		clock->p2 = 10;
-		clock->n = 3;
-		clock->m1 = 16;
-		clock->m2 = 8;
-	} else if (dotclock >= 140500 && dotclock <= 200000) {
-		clock->p1 = 1;
-		clock->p2 = 10;
-		clock->n = 6;
-		clock->m1 = 12;
-		clock->m2 = 8;
-	}
+	return (1 << dpll->n) << 16 | dpll->m2;
+}
 
-	crtc->config.clock_set = true;
+static uint32_t i9xx_dpll_compute_fp(struct dpll *dpll)
+{
+	return dpll->n << 16 | dpll->m1 << 8 | dpll->m2;
 }
 
 static void i9xx_update_pll_dividers(struct intel_crtc *crtc,
@@ -4199,18 +4254,15 @@ static void i9xx_update_pll_dividers(str
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int pipe = crtc->pipe;
 	u32 fp, fp2 = 0;
-	struct dpll *clock = &crtc->config.dpll;
 
 	if (IS_PINEVIEW(dev)) {
-		fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2;
+		fp = pnv_dpll_compute_fp(&crtc->config.dpll);
 		if (reduced_clock)
-			fp2 = (1 << reduced_clock->n) << 16 |
-				reduced_clock->m1 << 8 | reduced_clock->m2;
+			fp2 = pnv_dpll_compute_fp(reduced_clock);
 	} else {
-		fp = clock->n << 16 | clock->m1 << 8 | clock->m2;
+		fp = i9xx_dpll_compute_fp(&crtc->config.dpll);
 		if (reduced_clock)
-			fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 |
-				reduced_clock->m2;
+			fp2 = i9xx_dpll_compute_fp(reduced_clock);
 	}
 
 	I915_WRITE(FP0(pipe), fp);
@@ -4225,6 +4277,68 @@ static void i9xx_update_pll_dividers(str
 	}
 }
 
+static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv)
+{
+	u32 reg_val;
+
+	/*
+	 * PLLB opamp always calibrates to max value of 0x3f, force enable it
+	 * and set it to a reasonable value instead.
+	 */
+	reg_val = vlv_dpio_read(dev_priv, DPIO_IREF(1));
+	reg_val &= 0xffffff00;
+	reg_val |= 0x00000030;
+	vlv_dpio_write(dev_priv, DPIO_IREF(1), reg_val);
+
+	reg_val = vlv_dpio_read(dev_priv, DPIO_CALIBRATION);
+	reg_val &= 0x8cffffff;
+	reg_val = 0x8c000000;
+	vlv_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val);
+
+	reg_val = vlv_dpio_read(dev_priv, DPIO_IREF(1));
+	reg_val &= 0xffffff00;
+	vlv_dpio_write(dev_priv, DPIO_IREF(1), reg_val);
+
+	reg_val = vlv_dpio_read(dev_priv, DPIO_CALIBRATION);
+	reg_val &= 0x00ffffff;
+	reg_val |= 0xb0000000;
+	vlv_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val);
+}
+
+static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
+					 struct intel_link_m_n *m_n)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+
+	I915_WRITE(PCH_TRANS_DATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m);
+	I915_WRITE(PCH_TRANS_DATA_N1(pipe), m_n->gmch_n);
+	I915_WRITE(PCH_TRANS_LINK_M1(pipe), m_n->link_m);
+	I915_WRITE(PCH_TRANS_LINK_N1(pipe), m_n->link_n);
+}
+
+static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
+					 struct intel_link_m_n *m_n)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe = crtc->pipe;
+	enum transcoder transcoder = crtc->config.cpu_transcoder;
+
+	if (INTEL_INFO(dev)->gen >= 5) {
+		I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m);
+		I915_WRITE(PIPE_DATA_N1(transcoder), m_n->gmch_n);
+		I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m);
+		I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n);
+	} else {
+		I915_WRITE(PIPE_DATA_M_G4X(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m);
+		I915_WRITE(PIPE_DATA_N_G4X(pipe), m_n->gmch_n);
+		I915_WRITE(PIPE_LINK_M_G4X(pipe), m_n->link_m);
+		I915_WRITE(PIPE_LINK_N_G4X(pipe), m_n->link_n);
+	}
+}
+
 static void intel_dp_set_m_n(struct intel_crtc *crtc)
 {
 	if (crtc->config.has_pch_encoder)
@@ -4237,24 +4351,16 @@ static void vlv_update_pll(struct intel_
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *encoder;
 	int pipe = crtc->pipe;
-	u32 dpll, mdiv, pdiv;
+	u32 dpll, mdiv;
 	u32 bestn, bestm1, bestm2, bestp1, bestp2;
-	bool is_sdvo;
-	u32 temp;
+	bool is_hdmi;
+	u32 coreclk, reg_val, dpll_md;
 
 	mutex_lock(&dev_priv->dpio_lock);
 
-	is_sdvo = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_SDVO) ||
-		intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI);
-
-	dpll = DPLL_VGA_MODE_DIS;
-	dpll |= DPLL_EXT_BUFFER_ENABLE_VLV;
-	dpll |= DPLL_REFA_CLK_ENABLE_VLV;
-	dpll |= DPLL_INTEGRATED_CLOCK_VLV;
-
-	I915_WRITE(DPLL(pipe), dpll);
-	POSTING_READ(DPLL(pipe));
+	is_hdmi = intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI);
 
 	bestn = crtc->config.dpll.n;
 	bestm1 = crtc->config.dpll.m1;
@@ -4262,71 +4368,103 @@ static void vlv_update_pll(struct intel_
 	bestp1 = crtc->config.dpll.p1;
 	bestp2 = crtc->config.dpll.p2;
 
-	/*
-	 * In Valleyview PLL and program lane counter registers are exposed
-	 * through DPIO interface
-	 */
+	/* See eDP HDMI DPIO driver vbios notes doc */
+
+	/* PLL B needs special handling */
+	if (pipe)
+		vlv_pllb_recal_opamp(dev_priv);
+
+	/* Set up Tx target for periodic Rcomp update */
+	vlv_dpio_write(dev_priv, DPIO_IREF_BCAST, 0x0100000f);
+
+	/* Disable target IRef on PLL */
+	reg_val = vlv_dpio_read(dev_priv, DPIO_IREF_CTL(pipe));
+	reg_val &= 0x00ffffff;
+	vlv_dpio_write(dev_priv, DPIO_IREF_CTL(pipe), reg_val);
+
+	/* Disable fast lock */
+	vlv_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x610);
+
+	/* Set idtafcrecal before PLL is enabled */
 	mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
 	mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
 	mdiv |= ((bestn << DPIO_N_SHIFT));
-	mdiv |= (1 << DPIO_POST_DIV_SHIFT);
 	mdiv |= (1 << DPIO_K_SHIFT);
+
+	/*
+	 * Post divider depends on pixel clock rate, DAC vs digital (and LVDS,
+	 * but we don't support that).
+	 * Note: don't use the DAC post divider as it seems unstable.
+	 */
+	mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
+	vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
+
 	mdiv |= DPIO_ENABLE_CALIBRATION;
-	intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
+	vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
 
-	intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000);
+	/* Set HBR and RBR LPF coefficients */
+	if (crtc->config.port_clock == 162000 ||
+	    intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) ||
+	    intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
+		vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
+				 0x005f0021);
+	else
+		vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
+				 0x00d0000f);
 
-	pdiv = (1 << DPIO_REFSEL_OVERRIDE) | (5 << DPIO_PLL_MODESEL_SHIFT) |
-		(3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) |
-		(7 << DPIO_PLL_REFCLK_SEL_SHIFT) | (8 << DPIO_DRIVER_CTL_SHIFT) |
-		(5 << DPIO_CLK_BIAS_CTL_SHIFT);
-	intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv);
+	if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) ||
+	    intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) {
+		/* Use SSC source */
+		if (!pipe)
+			vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
+					 0x0df40000);
+		else
+			vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
+					 0x0df70000);
+	} else { /* HDMI or VGA */
+		/* Use bend source */
+		if (!pipe)
+			vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
+					 0x0df70000);
+		else
+			vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
+					 0x0df40000);
+	}
 
-	intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x005f003b);
+	coreclk = vlv_dpio_read(dev_priv, DPIO_CORE_CLK(pipe));
+	coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
+	if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT) ||
+	    intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP))
+		coreclk |= 0x01000000;
+	vlv_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), coreclk);
 
-	dpll |= DPLL_VCO_ENABLE;
-	I915_WRITE(DPLL(pipe), dpll);
-	POSTING_READ(DPLL(pipe));
-	if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
-		DRM_ERROR("DPLL %d failed to lock\n", pipe);
+	vlv_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000);
 
-	intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x620);
+	for_each_encoder_on_crtc(dev, &crtc->base, encoder)
+		if (encoder->pre_pll_enable)
+			encoder->pre_pll_enable(encoder);
 
-	if (crtc->config.has_dp_encoder)
-		intel_dp_set_m_n(crtc);
+	/* Enable DPIO clock input */
+	dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV |
+		DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV;
+	if (pipe)
+		dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
 
+	dpll |= DPLL_VCO_ENABLE;
 	I915_WRITE(DPLL(pipe), dpll);
-
-	/* Wait for the clocks to stabilize. */
 	POSTING_READ(DPLL(pipe));
 	udelay(150);
 
-	temp = 0;
-	if (is_sdvo) {
-		temp = 0;
-		if (crtc->config.pixel_multiplier > 1) {
-			temp = (crtc->config.pixel_multiplier - 1)
-				<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
-		}
-	}
-	I915_WRITE(DPLL_MD(pipe), temp);
-	POSTING_READ(DPLL_MD(pipe));
+	if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
+		DRM_ERROR("DPLL %d failed to lock\n", pipe);
 
-	/* Now program lane control registers */
-	if(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)
-	   || intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI)) {
-		temp = 0x1000C4;
-		if(pipe == 1)
-			temp |= (1 << 21);
-		intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL1, temp);
-	}
+	dpll_md = (crtc->config.pixel_multiplier - 1)
+		<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
+	I915_WRITE(DPLL_MD(pipe), dpll_md);
+	POSTING_READ(DPLL_MD(pipe));
 
-	if(intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP)) {
-		temp = 0x1000C4;
-		if(pipe == 1)
-			temp |= (1 << 21);
-		intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL2, temp);
-	}
+	if (crtc->config.has_dp_encoder)
+		intel_dp_set_m_n(crtc);
 
 	mutex_unlock(&dev_priv->dpio_lock);
 }
@@ -4355,14 +4493,14 @@ static void i9xx_update_pll(struct intel
 	else
 		dpll |= DPLLB_MODE_DAC_SERIAL;
 
-	if (is_sdvo) {
-		if ((crtc->config.pixel_multiplier > 1) &&
-		    (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))) {
-			dpll |= (crtc->config.pixel_multiplier - 1)
-				<< SDVO_MULTIPLIER_SHIFT_HIRES;
-		}
-		dpll |= DPLL_DVO_HIGH_SPEED;
+	if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
+		dpll |= (crtc->config.pixel_multiplier - 1)
+			<< SDVO_MULTIPLIER_SHIFT_HIRES;
 	}
+
+	if (is_sdvo)
+		dpll |= DPLL_DVO_HIGH_SPEED;
+
 	if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT))
 		dpll |= DPLL_DVO_HIGH_SPEED;
 
@@ -4391,12 +4529,8 @@ static void i9xx_update_pll(struct intel
 	if (INTEL_INFO(dev)->gen >= 4)
 		dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
 
-	if (is_sdvo && intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_TVOUT))
+	if (crtc->config.sdvo_tv_clock)
 		dpll |= PLL_REF_INPUT_TVCLKINBC;
-	else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_TVOUT))
-		/* XXX: just matching BIOS for now */
-		/*	dpll |= PLL_REF_INPUT_TVCLKINBC; */
-		dpll |= 3;
 	else if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
 		 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
 		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
@@ -4422,15 +4556,9 @@ static void i9xx_update_pll(struct intel
 	udelay(150);
 
 	if (INTEL_INFO(dev)->gen >= 4) {
-		u32 temp = 0;
-		if (is_sdvo) {
-			temp = 0;
-			if (crtc->config.pixel_multiplier > 1) {
-				temp = (crtc->config.pixel_multiplier - 1)
-					<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
-			}
-		}
-		I915_WRITE(DPLL_MD(pipe), temp);
+		u32 dpll_md = (crtc->config.pixel_multiplier - 1)
+			<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
+		I915_WRITE(DPLL_MD(pipe), dpll_md);
 	} else {
 		/* The pixel multiplier can only be updated once the
 		 * DPLL is enabled and the clocks are stable.
@@ -4442,7 +4570,6 @@ static void i9xx_update_pll(struct intel
 }
 
 static void i8xx_update_pll(struct intel_crtc *crtc,
-			    struct drm_display_mode *adjusted_mode,
 			    intel_clock_t *reduced_clock,
 			    int num_connectors)
 {
@@ -4497,20 +4624,26 @@ static void i8xx_update_pll(struct intel
 	I915_WRITE(DPLL(pipe), dpll);
 }
 
-static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
-				   struct drm_display_mode *mode,
-				   struct drm_display_mode *adjusted_mode)
+static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	enum pipe pipe = intel_crtc->pipe;
 	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
-	uint32_t vsyncshift;
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
+	uint32_t vsyncshift, crtc_vtotal, crtc_vblank_end;
+
+	/* We need to be careful not to changed the adjusted mode, for otherwise
+	 * the hw state checker will get angry at the mismatch. */
+	crtc_vtotal = adjusted_mode->crtc_vtotal;
+	crtc_vblank_end = adjusted_mode->crtc_vblank_end;
 
 	if (!IS_GEN2(dev) && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
 		/* the chip adds 2 halflines automatically */
-		adjusted_mode->crtc_vtotal -= 1;
-		adjusted_mode->crtc_vblank_end -= 1;
+		crtc_vtotal -= 1;
+		crtc_vblank_end -= 1;
 		vsyncshift = adjusted_mode->crtc_hsync_start
 			     - adjusted_mode->crtc_htotal / 2;
 	} else {
@@ -4532,10 +4665,10 @@ static void intel_set_pipe_timings(struc
 
 	I915_WRITE(VTOTAL(cpu_transcoder),
 		   (adjusted_mode->crtc_vdisplay - 1) |
-		   ((adjusted_mode->crtc_vtotal - 1) << 16));
+		   ((crtc_vtotal - 1) << 16));
 	I915_WRITE(VBLANK(cpu_transcoder),
 		   (adjusted_mode->crtc_vblank_start - 1) |
-		   ((adjusted_mode->crtc_vblank_end - 1) << 16));
+		   ((crtc_vblank_end - 1) << 16));
 	I915_WRITE(VSYNC(cpu_transcoder),
 		   (adjusted_mode->crtc_vsync_start - 1) |
 		   ((adjusted_mode->crtc_vsync_end - 1) << 16));
@@ -4555,13 +4688,52 @@ static void intel_set_pipe_timings(struc
 		   ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
 }
 
+static void intel_get_pipe_timings(struct intel_crtc *crtc,
+				   struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+	uint32_t tmp;
+
+	tmp = I915_READ(HTOTAL(cpu_transcoder));
+	pipe_config->adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
+	pipe_config->adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
+	tmp = I915_READ(HBLANK(cpu_transcoder));
+	pipe_config->adjusted_mode.crtc_hblank_start = (tmp & 0xffff) + 1;
+	pipe_config->adjusted_mode.crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1;
+	tmp = I915_READ(HSYNC(cpu_transcoder));
+	pipe_config->adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
+	pipe_config->adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
+
+	tmp = I915_READ(VTOTAL(cpu_transcoder));
+	pipe_config->adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
+	pipe_config->adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
+	tmp = I915_READ(VBLANK(cpu_transcoder));
+	pipe_config->adjusted_mode.crtc_vblank_start = (tmp & 0xffff) + 1;
+	pipe_config->adjusted_mode.crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1;
+	tmp = I915_READ(VSYNC(cpu_transcoder));
+	pipe_config->adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
+	pipe_config->adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
+
+	if (I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK) {
+		pipe_config->adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
+		pipe_config->adjusted_mode.crtc_vtotal += 1;
+		pipe_config->adjusted_mode.crtc_vblank_end += 1;
+	}
+
+	tmp = I915_READ(PIPESRC(crtc->pipe));
+	pipe_config->requested_mode.vdisplay = (tmp & 0xffff) + 1;
+	pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1;
+}
+
 static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t pipeconf;
 
-	pipeconf = I915_READ(PIPECONF(intel_crtc->pipe));
+	pipeconf = 0;
 
 	if (intel_crtc->pipe == 0 && INTEL_INFO(dev)->gen < 4) {
 		/* Enable pixel doubling when the dot clock is > 90% of the (display)
@@ -4573,26 +4745,28 @@ static void i9xx_set_pipeconf(struct int
 		if (intel_crtc->config.requested_mode.clock >
 		    dev_priv->display.get_display_clock_speed(dev) * 9 / 10)
 			pipeconf |= PIPECONF_DOUBLE_WIDE;
-		else
-			pipeconf &= ~PIPECONF_DOUBLE_WIDE;
 	}
 
-	/* default to 8bpc */
-	pipeconf &= ~(PIPECONF_BPC_MASK | PIPECONF_DITHER_EN);
-	if (intel_crtc->config.has_dp_encoder) {
-		if (intel_crtc->config.dither) {
-			pipeconf |= PIPECONF_6BPC |
-				    PIPECONF_DITHER_EN |
+	/* only g4x and later have fancy bpc/dither controls */
+	if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) {
+		/* Bspec claims that we can't use dithering for 30bpp pipes. */
+		if (intel_crtc->config.dither && intel_crtc->config.pipe_bpp != 30)
+			pipeconf |= PIPECONF_DITHER_EN |
 				    PIPECONF_DITHER_TYPE_SP;
-		}
-	}
 
-	if (IS_VALLEYVIEW(dev) && intel_pipe_has_type(&intel_crtc->base,
-						      INTEL_OUTPUT_EDP)) {
-		if (intel_crtc->config.dither) {
-			pipeconf |= PIPECONF_6BPC |
-					PIPECONF_ENABLE |
-					I965_PIPECONF_ACTIVE;
+		switch (intel_crtc->config.pipe_bpp) {
+		case 18:
+			pipeconf |= PIPECONF_6BPC;
+			break;
+		case 24:
+			pipeconf |= PIPECONF_8BPC;
+			break;
+		case 30:
+			pipeconf |= PIPECONF_10BPC;
+			break;
+		default:
+			/* Case prevented by intel_choose_pipe_bpp_dither. */
+			BUG();
 		}
 	}
 
@@ -4602,23 +4776,17 @@ static void i9xx_set_pipeconf(struct int
 			pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
 		} else {
 			DRM_DEBUG_KMS("disabling CxSR downclocking\n");
-			pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
 		}
 	}
 
-	pipeconf &= ~PIPECONF_INTERLACE_MASK;
 	if (!IS_GEN2(dev) &&
 	    intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
 	else
 		pipeconf |= PIPECONF_PROGRESSIVE;
 
-	if (IS_VALLEYVIEW(dev)) {
-		if (intel_crtc->config.limited_color_range)
-			pipeconf |= PIPECONF_COLOR_RANGE_SELECT;
-		else
-			pipeconf &= ~PIPECONF_COLOR_RANGE_SELECT;
-	}
+	if (IS_VALLEYVIEW(dev) && intel_crtc->config.limited_color_range)
+		pipeconf |= PIPECONF_COLOR_RANGE_SELECT;
 
 	I915_WRITE(PIPECONF(intel_crtc->pipe), pipeconf);
 	POSTING_READ(PIPECONF(intel_crtc->pipe));
@@ -4631,16 +4799,14 @@ static int i9xx_crtc_mode_set(struct drm
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct drm_display_mode *adjusted_mode =
-		&intel_crtc->config.adjusted_mode;
 	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	int refclk, num_connectors = 0;
 	intel_clock_t clock, reduced_clock;
 	u32 dspcntr;
-	bool ok, has_reduced_clock = false, is_sdvo = false;
-	bool is_lvds = false, is_tv = false;
+	bool ok, has_reduced_clock = false;
+	bool is_lvds = false;
 	struct intel_encoder *encoder;
 	const intel_limit_t *limit;
 	int ret;
@@ -4650,15 +4816,6 @@ static int i9xx_crtc_mode_set(struct drm
 		case INTEL_OUTPUT_LVDS:
 			is_lvds = true;
 			break;
-		case INTEL_OUTPUT_SDVO:
-		case INTEL_OUTPUT_HDMI:
-			is_sdvo = true;
-			if (encoder->needs_tv_clock)
-				is_tv = true;
-			break;
-		case INTEL_OUTPUT_TVOUT:
-			is_tv = true;
-			break;
 		}
 
 		num_connectors++;
@@ -4672,9 +4829,10 @@ static int i9xx_crtc_mode_set(struct drm
 	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 	 */
 	limit = intel_limit(crtc, refclk);
-	ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
-			     &clock);
-	if (!ok) {
+	ok = dev_priv->display.find_dpll(limit, crtc,
+					 intel_crtc->config.port_clock,
+					 refclk, NULL, &clock);
+	if (!ok && !intel_crtc->config.clock_set) {
 		DRM_ERROR("Couldn't find PLL settings for mode!\n");
 		return -EINVAL;
 	}
@@ -4689,10 +4847,10 @@ static int i9xx_crtc_mode_set(struct drm
 		 * by using the FP0/FP1. In such case we will disable the LVDS
 		 * downclock feature.
 		*/
-		has_reduced_clock = limit->find_pll(limit, crtc,
+		has_reduced_clock =
+			dev_priv->display.find_dpll(limit, crtc,
 						    dev_priv->lvds_downclock,
-						    refclk,
-						    &clock,
+						    refclk, &clock,
 						    &reduced_clock);
 	}
 	/* Compat-code for transition, will disappear. */
@@ -4704,11 +4862,8 @@ static int i9xx_crtc_mode_set(struct drm
 		intel_crtc->config.dpll.p2 = clock.p2;
 	}
 
-	if (is_sdvo && is_tv)
-		i9xx_adjust_sdvo_tv_clock(intel_crtc);
-
 	if (IS_GEN2(dev))
-		i8xx_update_pll(intel_crtc, adjusted_mode,
+		i8xx_update_pll(intel_crtc,
 				has_reduced_clock ? &reduced_clock : NULL,
 				num_connectors);
 	else if (IS_VALLEYVIEW(dev))
@@ -4716,7 +4871,7 @@ static int i9xx_crtc_mode_set(struct drm
 	else
 		i9xx_update_pll(intel_crtc,
 				has_reduced_clock ? &reduced_clock : NULL,
-				num_connectors);
+                                num_connectors);
 
 	/* Set up the display plane register */
 	dspcntr = DISPPLANE_GAMMA_ENABLE;
@@ -4728,10 +4883,7 @@ static int i9xx_crtc_mode_set(struct drm
 			dspcntr |= DISPPLANE_SEL_PIPE_B;
 	}
 
-	DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
-	drm_mode_debug_printmodeline(mode);
-
-	intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
+	intel_set_pipe_timings(intel_crtc);
 
 	/* pipesrc and dspsize control the size that is scaled from,
 	 * which should always be the user's requested size.
@@ -4743,10 +4895,6 @@ static int i9xx_crtc_mode_set(struct drm
 
 	i9xx_set_pipeconf(intel_crtc);
 
-	intel_enable_pipe(dev_priv, pipe, false);
-
-	intel_wait_for_vblank(dev, pipe);
-
 	I915_WRITE(DSPCNTR(plane), dspcntr);
 	POSTING_READ(DSPCNTR(plane));
 
@@ -4757,6 +4905,33 @@ static int i9xx_crtc_mode_set(struct drm
 	return ret;
 }
 
+static void i9xx_get_pfit_config(struct intel_crtc *crtc,
+				 struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	tmp = I915_READ(PFIT_CONTROL);
+	if (!(tmp & PFIT_ENABLE))
+		return;
+
+	/* Check whether the pfit is attached to our pipe. */
+	if (INTEL_INFO(dev)->gen < 4) {
+		if (crtc->pipe != PIPE_B)
+			return;
+	} else {
+		if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT))
+			return;
+	}
+
+	pipe_config->gmch_pfit.control = tmp;
+	pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS);
+	if (INTEL_INFO(dev)->gen < 5)
+		pipe_config->gmch_pfit.lvds_border_bits =
+			I915_READ(LVDS) & LVDS_BORDER_ENABLE;
+}
+
 static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 				 struct intel_crtc_config *pipe_config)
 {
@@ -4764,10 +4939,34 @@ static bool i9xx_get_pipe_config(struct
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t tmp;
 
+	pipe_config->cpu_transcoder = crtc->pipe;
+	pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+
 	tmp = I915_READ(PIPECONF(crtc->pipe));
 	if (!(tmp & PIPECONF_ENABLE))
 		return false;
 
+	intel_get_pipe_timings(crtc, pipe_config);
+
+	i9xx_get_pfit_config(crtc, pipe_config);
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		tmp = I915_READ(DPLL_MD(crtc->pipe));
+		pipe_config->pixel_multiplier =
+			((tmp & DPLL_MD_UDI_MULTIPLIER_MASK)
+			 >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1;
+	} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
+		tmp = I915_READ(DPLL(crtc->pipe));
+		pipe_config->pixel_multiplier =
+			((tmp & SDVO_MULTIPLIER_MASK)
+			 >> SDVO_MULTIPLIER_SHIFT_HIRES) + 1;
+	} else {
+		/* Note that on i915G/GM the pixel multiplier is in the sdvo
+		 * port and will be fixed up in the encoder->get_config
+		 * function. */
+		pipe_config->pixel_multiplier = 1;
+	}
+
 	return true;
 }
 
@@ -4779,7 +4978,6 @@ static void ironlake_init_pch_refclk(str
 	u32 val, final;
 	bool has_lvds = false;
 	bool has_cpu_edp = false;
-	bool has_pch_edp = false;
 	bool has_panel = false;
 	bool has_ck505 = false;
 	bool can_ssc = false;
@@ -4794,25 +4992,22 @@ static void ironlake_init_pch_refclk(str
 			break;
 		case INTEL_OUTPUT_EDP:
 			has_panel = true;
-			if (intel_encoder_is_pch_edp(&encoder->base))
-				has_pch_edp = true;
-			else
+			if (enc_to_dig_port(&encoder->base)->port == PORT_A)
 				has_cpu_edp = true;
 			break;
 		}
 	}
 
 	if (HAS_PCH_IBX(dev)) {
-		has_ck505 = dev_priv->display_clock_mode;
+		has_ck505 = dev_priv->vbt.display_clock_mode;
 		can_ssc = has_ck505;
 	} else {
 		has_ck505 = false;
 		can_ssc = true;
 	}
 
-	DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d\n",
-		      has_panel, has_lvds, has_pch_edp, has_cpu_edp,
-		      has_ck505);
+	DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n",
+		      has_panel, has_lvds, has_ck505);
 
 	/* Ironlake: try to setup display ref clock before DPLL
 	 * enabling. This is only under driver's control after
@@ -5102,7 +5297,6 @@ static int ironlake_get_refclk(struct dr
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_encoder *encoder;
-	struct intel_encoder *edp_encoder = NULL;
 	int num_connectors = 0;
 	bool is_lvds = false;
 
@@ -5111,34 +5305,28 @@ static int ironlake_get_refclk(struct dr
 		case INTEL_OUTPUT_LVDS:
 			is_lvds = true;
 			break;
-		case INTEL_OUTPUT_EDP:
-			edp_encoder = encoder;
-			break;
 		}
 		num_connectors++;
 	}
 
 	if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
 		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
-			      dev_priv->lvds_ssc_freq);
-		return dev_priv->lvds_ssc_freq * 1000;
+			      dev_priv->vbt.lvds_ssc_freq);
+		return dev_priv->vbt.lvds_ssc_freq * 1000;
 	}
 
 	return 120000;
 }
 
-static void ironlake_set_pipeconf(struct drm_crtc *crtc,
-				  struct drm_display_mode *adjusted_mode,
-				  bool dither)
+static void ironlake_set_pipeconf(struct drm_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int pipe = intel_crtc->pipe;
 	uint32_t val;
 
-	val = I915_READ(PIPECONF(pipe));
+	val = 0;
 
-	val &= ~PIPECONF_BPC_MASK;
 	switch (intel_crtc->config.pipe_bpp) {
 	case 18:
 		val |= PIPECONF_6BPC;
@@ -5157,20 +5345,16 @@ static void ironlake_set_pipeconf(struct
 		BUG();
 	}
 
-	val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
-	if (dither)
+	if (intel_crtc->config.dither)
 		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
 
-	val &= ~PIPECONF_INTERLACE_MASK;
-	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+	if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		val |= PIPECONF_INTERLACED_ILK;
 	else
 		val |= PIPECONF_PROGRESSIVE;
 
 	if (intel_crtc->config.limited_color_range)
 		val |= PIPECONF_COLOR_RANGE_SELECT;
-	else
-		val &= ~PIPECONF_COLOR_RANGE_SELECT;
 
 	I915_WRITE(PIPECONF(pipe), val);
 	POSTING_READ(PIPECONF(pipe));
@@ -5240,33 +5424,31 @@ static void intel_set_pipe_csc(struct dr
 	}
 }
 
-static void haswell_set_pipeconf(struct drm_crtc *crtc,
-				 struct drm_display_mode *adjusted_mode,
-				 bool dither)
+static void haswell_set_pipeconf(struct drm_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
 	uint32_t val;
 
-	val = I915_READ(PIPECONF(cpu_transcoder));
+	val = 0;
 
-	val &= ~(PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_MASK);
-	if (dither)
+	if (intel_crtc->config.dither)
 		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
 
-	val &= ~PIPECONF_INTERLACE_MASK_HSW;
-	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+	if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		val |= PIPECONF_INTERLACED_ILK;
 	else
 		val |= PIPECONF_PROGRESSIVE;
 
 	I915_WRITE(PIPECONF(cpu_transcoder), val);
 	POSTING_READ(PIPECONF(cpu_transcoder));
+
+	I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT);
+	POSTING_READ(GAMMA_MODE(intel_crtc->pipe));
 }
 
 static bool ironlake_compute_clocks(struct drm_crtc *crtc,
-				    struct drm_display_mode *adjusted_mode,
 				    intel_clock_t *clock,
 				    bool *has_reduced_clock,
 				    intel_clock_t *reduced_clock)
@@ -5276,22 +5458,13 @@ static bool ironlake_compute_clocks(stru
 	struct intel_encoder *intel_encoder;
 	int refclk;
 	const intel_limit_t *limit;
-	bool ret, is_sdvo = false, is_tv = false, is_lvds = false;
+	bool ret, is_lvds = false;
 
 	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
 		switch (intel_encoder->type) {
 		case INTEL_OUTPUT_LVDS:
 			is_lvds = true;
 			break;
-		case INTEL_OUTPUT_SDVO:
-		case INTEL_OUTPUT_HDMI:
-			is_sdvo = true;
-			if (intel_encoder->needs_tv_clock)
-				is_tv = true;
-			break;
-		case INTEL_OUTPUT_TVOUT:
-			is_tv = true;
-			break;
 		}
 	}
 
@@ -5303,8 +5476,9 @@ static bool ironlake_compute_clocks(stru
 	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 	 */
 	limit = intel_limit(crtc, refclk);
-	ret = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
-			      clock);
+	ret = dev_priv->display.find_dpll(limit, crtc,
+					  to_intel_crtc(crtc)->config.port_clock,
+					  refclk, NULL, clock);
 	if (!ret)
 		return false;
 
@@ -5315,16 +5489,13 @@ static bool ironlake_compute_clocks(stru
 		 * by using the FP0/FP1. In such case we will disable the LVDS
 		 * downclock feature.
 		*/
-		*has_reduced_clock = limit->find_pll(limit, crtc,
-						     dev_priv->lvds_downclock,
-						     refclk,
-						     clock,
-						     reduced_clock);
+		*has_reduced_clock =
+			dev_priv->display.find_dpll(limit, crtc,
+						    dev_priv->lvds_downclock,
+						    refclk, clock,
+						    reduced_clock);
 	}
 
-	if (is_sdvo && is_tv)
-		i9xx_adjust_sdvo_tv_clock(to_intel_crtc(crtc));
-
 	return true;
 }
 
@@ -5346,65 +5517,25 @@ static void cpt_enable_fdi_bc_bifurcatio
 	POSTING_READ(SOUTH_CHICKEN1);
 }
 
-static bool ironlake_check_fdi_lanes(struct intel_crtc *intel_crtc)
+static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *pipe_B_crtc =
-		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_B]);
-
-	DRM_DEBUG_KMS("checking fdi config on pipe %i, lanes %i\n",
-		      intel_crtc->pipe, intel_crtc->fdi_lanes);
-	if (intel_crtc->fdi_lanes > 4) {
-		DRM_DEBUG_KMS("invalid fdi lane config on pipe %i: %i lanes\n",
-			      intel_crtc->pipe, intel_crtc->fdi_lanes);
-		/* Clamp lanes to avoid programming the hw with bogus values. */
-		intel_crtc->fdi_lanes = 4;
-
-		return false;
-	}
-
-	if (INTEL_INFO(dev)->num_pipes == 2)
-		return true;
 
 	switch (intel_crtc->pipe) {
 	case PIPE_A:
-		return true;
+		break;
 	case PIPE_B:
-		if (dev_priv->pipe_to_crtc_mapping[PIPE_C]->enabled &&
-		    intel_crtc->fdi_lanes > 2) {
-			DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %i: %i lanes\n",
-				      intel_crtc->pipe, intel_crtc->fdi_lanes);
-			/* Clamp lanes to avoid programming the hw with bogus values. */
-			intel_crtc->fdi_lanes = 2;
-
-			return false;
-		}
-
-		if (intel_crtc->fdi_lanes > 2)
+		if (intel_crtc->config.fdi_lanes > 2)
 			WARN_ON(I915_READ(SOUTH_CHICKEN1) & FDI_BC_BIFURCATION_SELECT);
 		else
 			cpt_enable_fdi_bc_bifurcation(dev);
 
-		return true;
+		break;
 	case PIPE_C:
-		if (!pipe_B_crtc->base.enabled || pipe_B_crtc->fdi_lanes <= 2) {
-			if (intel_crtc->fdi_lanes > 2) {
-				DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %i: %i lanes\n",
-					      intel_crtc->pipe, intel_crtc->fdi_lanes);
-				/* Clamp lanes to avoid programming the hw with bogus values. */
-				intel_crtc->fdi_lanes = 2;
-
-				return false;
-			}
-		} else {
-			DRM_DEBUG_KMS("fdi link B uses too many lanes to enable link C\n");
-			return false;
-		}
-
 		cpt_enable_fdi_bc_bifurcation(dev);
 
-		return true;
+		break;
 	default:
 		BUG();
 	}
@@ -5421,78 +5552,13 @@ int ironlake_get_lanes_required(int targ
 	return bps / (link_bw * 8) + 1;
 }
 
-void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
-				  struct intel_link_m_n *m_n)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	int pipe = crtc->pipe;
-
-	I915_WRITE(TRANSDATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m);
-	I915_WRITE(TRANSDATA_N1(pipe), m_n->gmch_n);
-	I915_WRITE(TRANSDPLINK_M1(pipe), m_n->link_m);
-	I915_WRITE(TRANSDPLINK_N1(pipe), m_n->link_n);
-}
-
-void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
-				  struct intel_link_m_n *m_n)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	int pipe = crtc->pipe;
-	enum transcoder transcoder = crtc->config.cpu_transcoder;
-
-	if (INTEL_INFO(dev)->gen >= 5) {
-		I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m);
-		I915_WRITE(PIPE_DATA_N1(transcoder), m_n->gmch_n);
-		I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m);
-		I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n);
-	} else {
-		I915_WRITE(PIPE_GMCH_DATA_M(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m);
-		I915_WRITE(PIPE_GMCH_DATA_N(pipe), m_n->gmch_n);
-		I915_WRITE(PIPE_DP_LINK_M(pipe), m_n->link_m);
-		I915_WRITE(PIPE_DP_LINK_N(pipe), m_n->link_n);
-	}
-}
-
-static void ironlake_fdi_set_m_n(struct drm_crtc *crtc)
+static bool ironlake_needs_fb_cb_tune(struct dpll *dpll, int factor)
 {
-	struct drm_device *dev = crtc->dev;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct drm_display_mode *adjusted_mode =
-		&intel_crtc->config.adjusted_mode;
-	struct intel_link_m_n m_n = {0};
-	int target_clock, lane, link_bw;
-
-	/* FDI is a binary signal running at ~2.7GHz, encoding
-	 * each output octet as 10 bits. The actual frequency
-	 * is stored as a divider into a 100MHz clock, and the
-	 * mode pixel clock is stored in units of 1KHz.
-	 * Hence the bw of each lane in terms of the mode signal
-	 * is:
-	 */
-	link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
-
-	if (intel_crtc->config.pixel_target_clock)
-		target_clock = intel_crtc->config.pixel_target_clock;
-	else
-		target_clock = adjusted_mode->clock;
-
-	lane = ironlake_get_lanes_required(target_clock, link_bw,
-					   intel_crtc->config.pipe_bpp);
-
-	intel_crtc->fdi_lanes = lane;
-
-	if (intel_crtc->config.pixel_multiplier > 1)
-		link_bw *= intel_crtc->config.pixel_multiplier;
-	intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane, target_clock,
-			       link_bw, &m_n);
-
-	intel_cpu_transcoder_set_m_n(intel_crtc, &m_n);
+	return i9xx_dpll_compute_m(dpll) < factor * dpll->n;
 }
 
 static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
-				      intel_clock_t *clock, u32 *fp,
+				      u32 *fp,
 				      intel_clock_t *reduced_clock, u32 *fp2)
 {
 	struct drm_crtc *crtc = &intel_crtc->base;
@@ -5501,7 +5567,7 @@ static uint32_t ironlake_compute_dpll(st
 	struct intel_encoder *intel_encoder;
 	uint32_t dpll;
 	int factor, num_connectors = 0;
-	bool is_lvds = false, is_sdvo = false, is_tv = false;
+	bool is_lvds = false, is_sdvo = false;
 
 	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
 		switch (intel_encoder->type) {
@@ -5511,11 +5577,6 @@ static uint32_t ironlake_compute_dpll(st
 		case INTEL_OUTPUT_SDVO:
 		case INTEL_OUTPUT_HDMI:
 			is_sdvo = true;
-			if (intel_encoder->needs_tv_clock)
-				is_tv = true;
-			break;
-		case INTEL_OUTPUT_TVOUT:
-			is_tv = true;
 			break;
 		}
 
@@ -5526,13 +5587,13 @@ static uint32_t ironlake_compute_dpll(st
 	factor = 21;
 	if (is_lvds) {
 		if ((intel_panel_use_ssc(dev_priv) &&
-		     dev_priv->lvds_ssc_freq == 100) ||
+		     dev_priv->vbt.lvds_ssc_freq == 100) ||
 		    (HAS_PCH_IBX(dev) && intel_is_dual_link_lvds(dev)))
 			factor = 25;
-	} else if (is_sdvo && is_tv)
+	} else if (intel_crtc->config.sdvo_tv_clock)
 		factor = 20;
 
-	if (clock->m < factor * clock->n)
+	if (ironlake_needs_fb_cb_tune(&intel_crtc->config.dpll, factor))
 		*fp |= FP_CB_TUNE;
 
 	if (fp2 && (reduced_clock->m < factor * reduced_clock->n))
@@ -5544,23 +5605,21 @@ static uint32_t ironlake_compute_dpll(st
 		dpll |= DPLLB_MODE_LVDS;
 	else
 		dpll |= DPLLB_MODE_DAC_SERIAL;
-	if (is_sdvo) {
-		if (intel_crtc->config.pixel_multiplier > 1) {
-			dpll |= (intel_crtc->config.pixel_multiplier - 1)
-				<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
-		}
+
+	dpll |= (intel_crtc->config.pixel_multiplier - 1)
+		<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
+
+	if (is_sdvo)
 		dpll |= DPLL_DVO_HIGH_SPEED;
-	}
-	if (intel_crtc->config.has_dp_encoder &&
-	    intel_crtc->config.has_pch_encoder)
+	if (intel_crtc->config.has_dp_encoder)
 		dpll |= DPLL_DVO_HIGH_SPEED;
 
 	/* compute bitmask from p1 value */
-	dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+	dpll |= (1 << (intel_crtc->config.dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
 	/* also FPA1 */
-	dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
+	dpll |= (1 << (intel_crtc->config.dpll.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
 
-	switch (clock->p2) {
+	switch (intel_crtc->config.dpll.p2) {
 	case 5:
 		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
 		break;
@@ -5575,18 +5634,12 @@ static uint32_t ironlake_compute_dpll(st
 		break;
 	}
 
-	if (is_sdvo && is_tv)
-		dpll |= PLL_REF_INPUT_TVCLKINBC;
-	else if (is_tv)
-		/* XXX: just matching BIOS for now */
-		/*	dpll |= PLL_REF_INPUT_TVCLKINBC; */
-		dpll |= 3;
-	else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
+	if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
 		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
 	else
 		dpll |= PLL_REF_INPUT_DREFCLK;
 
-	return dpll;
+	return dpll | DPLL_VCO_ENABLE;
 }
 
 static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
@@ -5596,19 +5649,16 @@ static int ironlake_crtc_mode_set(struct
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct drm_display_mode *adjusted_mode =
-		&intel_crtc->config.adjusted_mode;
-	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	int num_connectors = 0;
 	intel_clock_t clock, reduced_clock;
-	u32 dpll, fp = 0, fp2 = 0;
+	u32 dpll = 0, fp = 0, fp2 = 0;
 	bool ok, has_reduced_clock = false;
 	bool is_lvds = false;
 	struct intel_encoder *encoder;
+	struct intel_shared_dpll *pll;
 	int ret;
-	bool dither, fdi_config_ok;
 
 	for_each_encoder_on_crtc(dev, crtc, encoder) {
 		switch (encoder->type) {
@@ -5623,11 +5673,9 @@ static int ironlake_crtc_mode_set(struct
 	WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
 	     "Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
 
-	intel_crtc->config.cpu_transcoder = pipe;
-
-	ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
+	ok = ironlake_compute_clocks(crtc, &clock,
 				     &has_reduced_clock, &reduced_clock);
-	if (!ok) {
+	if (!ok && !intel_crtc->config.clock_set) {
 		DRM_ERROR("Couldn't find PLL settings for mode!\n");
 		return -EINVAL;
 	}
@@ -5643,34 +5691,31 @@ static int ironlake_crtc_mode_set(struct
 	/* Ensure that the cursor is valid for the new mode before changing... */
 	intel_crtc_update_cursor(crtc, true);
 
-	/* determine panel color depth */
-	dither = intel_crtc->config.dither;
-	if (is_lvds && dev_priv->lvds_dither)
-		dither = true;
-
-	fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
-	if (has_reduced_clock)
-		fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
-			reduced_clock.m2;
-
-	dpll = ironlake_compute_dpll(intel_crtc, &clock, &fp, &reduced_clock,
-				     has_reduced_clock ? &fp2 : NULL);
-
-	DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
-	drm_mode_debug_printmodeline(mode);
-
 	/* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
 	if (intel_crtc->config.has_pch_encoder) {
-		struct intel_pch_pll *pll;
+		fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll);
+		if (has_reduced_clock)
+			fp2 = i9xx_dpll_compute_fp(&reduced_clock);
 
-		pll = intel_get_pch_pll(intel_crtc, dpll, fp);
+		dpll = ironlake_compute_dpll(intel_crtc,
+					     &fp, &reduced_clock,
+					     has_reduced_clock ? &fp2 : NULL);
+
+		intel_crtc->config.dpll_hw_state.dpll = dpll;
+		intel_crtc->config.dpll_hw_state.fp0 = fp;
+		if (has_reduced_clock)
+			intel_crtc->config.dpll_hw_state.fp1 = fp2;
+		else
+			intel_crtc->config.dpll_hw_state.fp1 = fp;
+
+		pll = intel_get_shared_dpll(intel_crtc, dpll, fp);
 		if (pll == NULL) {
-			DRM_DEBUG_DRIVER("failed to find PLL for pipe %d\n",
-					 pipe);
+			DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
+					 pipe_name(pipe));
 			return -EINVAL;
 		}
 	} else
-		intel_put_pch_pll(intel_crtc);
+		intel_put_shared_dpll(intel_crtc);
 
 	if (intel_crtc->config.has_dp_encoder)
 		intel_dp_set_m_n(intel_crtc);
@@ -5679,11 +5724,18 @@ static int ironlake_crtc_mode_set(struct
 		if (encoder->pre_pll_enable)
 			encoder->pre_pll_enable(encoder);
 
-	if (intel_crtc->pch_pll) {
-		I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
+	if (is_lvds && has_reduced_clock && i915_powersave)
+		intel_crtc->lowfreq_avail = true;
+	else
+		intel_crtc->lowfreq_avail = false;
+
+	if (intel_crtc->config.has_pch_encoder) {
+		pll = intel_crtc_to_shared_dpll(intel_crtc);
+
+		I915_WRITE(PCH_DPLL(pll->id), dpll);
 
 		/* Wait for the clocks to stabilize. */
-		POSTING_READ(intel_crtc->pch_pll->pll_reg);
+		POSTING_READ(PCH_DPLL(pll->id));
 		udelay(150);
 
 		/* The pixel multiplier can only be updated once the
@@ -5691,32 +5743,25 @@ static int ironlake_crtc_mode_set(struct
 		 *
 		 * So write it again.
 		 */
-		I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
-	}
+		I915_WRITE(PCH_DPLL(pll->id), dpll);
 
-	intel_crtc->lowfreq_avail = false;
-	if (intel_crtc->pch_pll) {
-		if (is_lvds && has_reduced_clock && i915_powersave) {
-			I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
-			intel_crtc->lowfreq_avail = true;
-		} else {
-			I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
-		}
+		if (has_reduced_clock)
+			I915_WRITE(PCH_FP1(pll->id), fp2);
+		else
+			I915_WRITE(PCH_FP1(pll->id), fp);
 	}
 
-	intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
-
-	/* Note, this also computes intel_crtc->fdi_lanes which is used below in
-	 * ironlake_check_fdi_lanes. */
-	intel_crtc->fdi_lanes = 0;
-	if (intel_crtc->config.has_pch_encoder)
-		ironlake_fdi_set_m_n(crtc);
+	intel_set_pipe_timings(intel_crtc);
 
-	fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc);
+	if (intel_crtc->config.has_pch_encoder) {
+		intel_cpu_transcoder_set_m_n(intel_crtc,
+					     &intel_crtc->config.fdi_m_n);
+	}
 
-	ironlake_set_pipeconf(crtc, adjusted_mode, dither);
+	if (IS_IVYBRIDGE(dev))
+		ivybridge_update_fdi_bc_bifurcation(intel_crtc);
 
-	intel_wait_for_vblank(dev, pipe);
+	ironlake_set_pipeconf(crtc);
 
 	/* Set up the display plane register */
 	I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE);
@@ -5726,9 +5771,46 @@ static int ironlake_crtc_mode_set(struct
 
 	intel_update_watermarks(dev);
 
-	intel_update_linetime_watermarks(dev, pipe, adjusted_mode);
+	return ret;
+}
 
-	return fdi_config_ok ? ret : -EINVAL;
+static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
+					struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder transcoder = pipe_config->cpu_transcoder;
+
+	pipe_config->fdi_m_n.link_m = I915_READ(PIPE_LINK_M1(transcoder));
+	pipe_config->fdi_m_n.link_n = I915_READ(PIPE_LINK_N1(transcoder));
+	pipe_config->fdi_m_n.gmch_m = I915_READ(PIPE_DATA_M1(transcoder))
+					& ~TU_SIZE_MASK;
+	pipe_config->fdi_m_n.gmch_n = I915_READ(PIPE_DATA_N1(transcoder));
+	pipe_config->fdi_m_n.tu = ((I915_READ(PIPE_DATA_M1(transcoder))
+				   & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+}
+
+static void ironlake_get_pfit_config(struct intel_crtc *crtc,
+				     struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	tmp = I915_READ(PF_CTL(crtc->pipe));
+
+	if (tmp & PF_ENABLE) {
+		pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe));
+		pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe));
+
+		/* We currently do not free assignements of panel fitters on
+		 * ivb/hsw (since we don't use the higher upscaling modes which
+		 * differentiates them) so just WARN about this case for now. */
+		if (IS_GEN7(dev)) {
+			WARN_ON((tmp & PF_PIPE_SEL_MASK_IVB) !=
+				PF_PIPE_SEL_IVB(crtc->pipe));
+		}
+	}
 }
 
 static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
@@ -5738,42 +5820,67 @@ static bool ironlake_get_pipe_config(str
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t tmp;
 
+	pipe_config->cpu_transcoder = crtc->pipe;
+	pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+
 	tmp = I915_READ(PIPECONF(crtc->pipe));
 	if (!(tmp & PIPECONF_ENABLE))
 		return false;
 
-	if (I915_READ(TRANSCONF(crtc->pipe)) & TRANS_ENABLE)
+	if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) {
+		struct intel_shared_dpll *pll;
+
 		pipe_config->has_pch_encoder = true;
 
+		tmp = I915_READ(FDI_RX_CTL(crtc->pipe));
+		pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
+					  FDI_DP_PORT_WIDTH_SHIFT) + 1;
+
+		ironlake_get_fdi_m_n_config(crtc, pipe_config);
+
+		/* XXX: Can't properly read out the pch dpll pixel multiplier
+		 * since we don't have state tracking for pch clocks yet. */
+		pipe_config->pixel_multiplier = 1;
+
+		if (HAS_PCH_IBX(dev_priv->dev)) {
+			pipe_config->shared_dpll = crtc->pipe;
+		} else {
+			tmp = I915_READ(PCH_DPLL_SEL);
+			if (tmp & TRANS_DPLLB_SEL(crtc->pipe))
+				pipe_config->shared_dpll = DPLL_ID_PCH_PLL_B;
+			else
+				pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A;
+		}
+
+		pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
+
+		WARN_ON(!pll->get_hw_state(dev_priv, pll,
+					   &pipe_config->dpll_hw_state));
+	} else {
+		pipe_config->pixel_multiplier = 1;
+	}
+
+	intel_get_pipe_timings(crtc, pipe_config);
+
+	ironlake_get_pfit_config(crtc, pipe_config);
+
 	return true;
 }
 
 static void haswell_modeset_global_resources(struct drm_device *dev)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	bool enable = false;
 	struct intel_crtc *crtc;
-	struct intel_encoder *encoder;
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
-		if (crtc->pipe != PIPE_A && crtc->base.enabled)
-			enable = true;
-		/* XXX: Should check for edp transcoder here, but thanks to init
-		 * sequence that's not yet available. Just in case desktop eDP
-		 * on PORT D is possible on haswell, too. */
-	}
+		if (!crtc->base.enabled)
+			continue;
 
-	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
-			    base.head) {
-		if (encoder->type != INTEL_OUTPUT_EDP &&
-		    encoder->connectors_active)
+		if (crtc->pipe != PIPE_A || crtc->config.pch_pfit.size ||
+		    crtc->config.cpu_transcoder != TRANSCODER_EDP)
 			enable = true;
 	}
 
-	/* Even the eDP panel fitter is outside the always-on well. */
-	if (dev_priv->pch_pf_size)
-		enable = true;
-
 	intel_set_power_well(dev, enable);
 }
 
@@ -5784,68 +5891,28 @@ static int haswell_crtc_mode_set(struct
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct drm_display_mode *adjusted_mode =
-		&intel_crtc->config.adjusted_mode;
-	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
-	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
-	int num_connectors = 0;
-	bool is_cpu_edp = false;
-	struct intel_encoder *encoder;
 	int ret;
-	bool dither;
 
-	for_each_encoder_on_crtc(dev, crtc, encoder) {
-		switch (encoder->type) {
-		case INTEL_OUTPUT_EDP:
-			if (!intel_encoder_is_pch_edp(&encoder->base))
-				is_cpu_edp = true;
-			break;
-		}
-
-		num_connectors++;
-	}
-
-	if (is_cpu_edp)
-		intel_crtc->config.cpu_transcoder = TRANSCODER_EDP;
-	else
-		intel_crtc->config.cpu_transcoder = pipe;
-
-	/* We are not sure yet this won't happen. */
-	WARN(!HAS_PCH_LPT(dev), "Unexpected PCH type %d\n",
-	     INTEL_PCH_TYPE(dev));
-
-	WARN(num_connectors != 1, "%d connectors attached to pipe %c\n",
-	     num_connectors, pipe_name(pipe));
-
-	WARN_ON(I915_READ(PIPECONF(intel_crtc->config.cpu_transcoder)) &
-		(PIPECONF_ENABLE | I965_PIPECONF_ACTIVE));
-
-	WARN_ON(I915_READ(DSPCNTR(plane)) & DISPLAY_PLANE_ENABLE);
-
-	if (!intel_ddi_pll_mode_set(crtc, adjusted_mode->clock))
+	if (!intel_ddi_pll_mode_set(crtc))
 		return -EINVAL;
 
 	/* Ensure that the cursor is valid for the new mode before changing... */
 	intel_crtc_update_cursor(crtc, true);
 
-	/* determine panel color depth */
-	dither = intel_crtc->config.dither;
-
-	DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
-	drm_mode_debug_printmodeline(mode);
-
 	if (intel_crtc->config.has_dp_encoder)
 		intel_dp_set_m_n(intel_crtc);
 
 	intel_crtc->lowfreq_avail = false;
 
-	intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
+	intel_set_pipe_timings(intel_crtc);
 
-	if (intel_crtc->config.has_pch_encoder)
-		ironlake_fdi_set_m_n(crtc);
+	if (intel_crtc->config.has_pch_encoder) {
+		intel_cpu_transcoder_set_m_n(intel_crtc,
+					     &intel_crtc->config.fdi_m_n);
+	}
 
-	haswell_set_pipeconf(crtc, adjusted_mode, dither);
+	haswell_set_pipeconf(crtc);
 
 	intel_set_pipe_csc(crtc);
 
@@ -5857,8 +5924,6 @@ static int haswell_crtc_mode_set(struct
 
 	intel_update_watermarks(dev);
 
-	intel_update_linetime_watermarks(dev, pipe, adjusted_mode);
-
 	return ret;
 }
 
@@ -5867,22 +5932,69 @@ static bool haswell_get_pipe_config(stru
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum intel_display_power_domain pfit_domain;
 	uint32_t tmp;
 
-	tmp = I915_READ(PIPECONF(crtc->config.cpu_transcoder));
+	pipe_config->cpu_transcoder = crtc->pipe;
+	pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+
+	tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
+	if (tmp & TRANS_DDI_FUNC_ENABLE) {
+		enum pipe trans_edp_pipe;
+		switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
+		default:
+			WARN(1, "unknown pipe linked to edp transcoder\n");
+		case TRANS_DDI_EDP_INPUT_A_ONOFF:
+		case TRANS_DDI_EDP_INPUT_A_ON:
+			trans_edp_pipe = PIPE_A;
+			break;
+		case TRANS_DDI_EDP_INPUT_B_ONOFF:
+			trans_edp_pipe = PIPE_B;
+			break;
+		case TRANS_DDI_EDP_INPUT_C_ONOFF:
+			trans_edp_pipe = PIPE_C;
+			break;
+		}
+
+		if (trans_edp_pipe == crtc->pipe)
+			pipe_config->cpu_transcoder = TRANSCODER_EDP;
+	}
+
+	if (!intel_display_power_enabled(dev,
+			POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder)))
+		return false;
+
+	tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder));
 	if (!(tmp & PIPECONF_ENABLE))
 		return false;
 
 	/*
-	 * aswell has only FDI/PCH transcoder A. It is which is connected to
+	 * Haswell has only FDI/PCH transcoder A. It is which is connected to
 	 * DDI E. So just check whether this pipe is wired to DDI E and whether
 	 * the PCH transcoder is on.
 	 */
-	tmp = I915_READ(TRANS_DDI_FUNC_CTL(crtc->pipe));
+	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
 	if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(PORT_E) &&
-	    I915_READ(TRANSCONF(PIPE_A)) & TRANS_ENABLE)
+	    I915_READ(LPT_TRANSCONF) & TRANS_ENABLE) {
 		pipe_config->has_pch_encoder = true;
 
+		tmp = I915_READ(FDI_RX_CTL(PIPE_A));
+		pipe_config->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >>
+					  FDI_DP_PORT_WIDTH_SHIFT) + 1;
+
+		ironlake_get_fdi_m_n_config(crtc, pipe_config);
+	}
+
+	intel_get_pipe_timings(crtc, pipe_config);
+
+	pfit_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
+	if (intel_display_power_enabled(dev, pfit_domain))
+		ironlake_get_pfit_config(crtc, pipe_config);
+
+	pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) &&
+				   (I915_READ(IPS_CTL) & IPS_ENABLE);
+
+	pipe_config->pixel_multiplier = 1;
 
 	return true;
 }
@@ -6120,7 +6232,7 @@ static void ironlake_write_eld(struct dr
 		eldv |= IBX_ELD_VALIDB << 4;
 		eldv |= IBX_ELD_VALIDB << 8;
 	} else {
-		DRM_DEBUG_DRIVER("ELD on port %c\n", 'A' + i);
+		DRM_DEBUG_DRIVER("ELD on port %c\n", port_name(i));
 		eldv = IBX_ELD_VALIDB << ((i - 1) * 4);
 	}
 
@@ -6188,16 +6300,31 @@ void intel_crtc_load_lut(struct drm_crtc
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	int palreg = PALETTE(intel_crtc->pipe);
+	enum pipe pipe = intel_crtc->pipe;
+	int palreg = PALETTE(pipe);
 	int i;
+	bool reenable_ips = false;
 
 	/* The clocks have to be on to load the palette. */
 	if (!crtc->enabled || !intel_crtc->active)
 		return;
 
+	if (!HAS_PCH_SPLIT(dev_priv->dev))
+		assert_pll_enabled(dev_priv, pipe);
+
 	/* use legacy palette for Ironlake */
 	if (HAS_PCH_SPLIT(dev))
-		palreg = LGC_PALETTE(intel_crtc->pipe);
+		palreg = LGC_PALETTE(pipe);
+
+	/* Workaround : Do not read or write the pipe palette/gamma data while
+	 * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
+	 */
+	if (intel_crtc->config.ips_enabled &&
+	    ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
+	     GAMMA_MODE_MODE_SPLIT)) {
+		hsw_disable_ips(intel_crtc);
+		reenable_ips = true;
+	}
 
 	for (i = 0; i < 256; i++) {
 		I915_WRITE(palreg + 4 * i,
@@ -6205,6 +6332,9 @@ void intel_crtc_load_lut(struct drm_crtc
 			   (intel_crtc->lut_g[i] << 8) |
 			   intel_crtc->lut_b[i]);
 	}
+
+	if (reenable_ips)
+		hsw_enable_ips(intel_crtc);
 }
 
 static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
@@ -6451,7 +6581,7 @@ static int intel_crtc_cursor_set(struct
 	intel_crtc->cursor_width = width;
 	intel_crtc->cursor_height = height;
 
-	intel_crtc_update_cursor(crtc, true);
+	intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
 
 	return 0;
 fail_unpin:
@@ -6470,7 +6600,7 @@ static int intel_crtc_cursor_move(struct
 	intel_crtc->cursor_x = x;
 	intel_crtc->cursor_y = y;
 
-	intel_crtc_update_cursor(crtc, true);
+	intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL);
 
 	return 0;
 }
@@ -6791,8 +6921,10 @@ static int intel_crtc_clock_get(struct d
 			return 0;
 		}
 
-		/* XXX: Handle the 100Mhz refclk */
-		intel_clock(dev, 96000, &clock);
+		if (IS_PINEVIEW(dev))
+			pineview_clock(96000, &clock);
+		else
+			i9xx_clock(96000, &clock);
 	} else {
 		bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
 
@@ -6804,9 +6936,9 @@ static int intel_crtc_clock_get(struct d
 			if ((dpll & PLL_REF_INPUT_MASK) ==
 			    PLLB_REF_INPUT_SPREADSPECTRUMIN) {
 				/* XXX: might not be 66MHz */
-				intel_clock(dev, 66000, &clock);
+				i9xx_clock(66000, &clock);
 			} else
-				intel_clock(dev, 48000, &clock);
+				i9xx_clock(48000, &clock);
 		} else {
 			if (dpll & PLL_P1_DIVIDE_BY_TWO)
 				clock.p1 = 2;
@@ -6819,7 +6951,7 @@ static int intel_crtc_clock_get(struct d
 			else
 				clock.p2 = 2;
 
-			intel_clock(dev, 48000, &clock);
+			i9xx_clock(48000, &clock);
 		}
 	}
 
@@ -6950,7 +7082,8 @@ void intel_mark_idle(struct drm_device *
 	}
 }
 
-void intel_mark_fb_busy(struct drm_i915_gem_object *obj)
+void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
+			struct intel_ring_buffer *ring)
 {
 	struct drm_device *dev = obj->base.dev;
 	struct drm_crtc *crtc;
@@ -6962,8 +7095,12 @@ void intel_mark_fb_busy(struct drm_i915_
 		if (!crtc->fb)
 			continue;
 
-		if (to_intel_framebuffer(crtc->fb)->obj == obj)
-			intel_increase_pllclock(crtc);
+		if (to_intel_framebuffer(crtc->fb)->obj != obj)
+			continue;
+
+		intel_increase_pllclock(crtc);
+		if (ring && intel_fbc_enabled(dev))
+			ring->fbc_dirty = true;
 	}
 }
 
@@ -6984,6 +7121,8 @@ static void intel_crtc_destroy(struct dr
 		kfree(work);
 	}
 
+	intel_crtc_cursor_set(crtc, NULL, 0, 0, 0);
+
 	drm_crtc_cleanup(crtc);
 
 	kfree(intel_crtc);
@@ -7411,7 +7550,7 @@ static int intel_crtc_page_flip(struct d
 		goto cleanup_pending;
 
 	intel_disable_fbc(dev);
-	intel_mark_fb_busy(obj);
+	intel_mark_fb_busy(obj, NULL);
 	mutex_unlock(&dev->struct_mutex);
 
 	trace_i915_flip_request(intel_crtc->plane, obj);
@@ -7442,28 +7581,6 @@ static struct drm_crtc_helper_funcs inte
 	.load_lut = intel_crtc_load_lut,
 };
 
-bool intel_encoder_check_is_cloned(struct intel_encoder *encoder)
-{
-	struct intel_encoder *other_encoder;
-	struct drm_crtc *crtc = &encoder->new_crtc->base;
-
-	if (WARN_ON(!crtc))
-		return false;
-
-	list_for_each_entry(other_encoder,
-			    &crtc->dev->mode_config.encoder_list,
-			    base.head) {
-
-		if (&other_encoder->new_crtc->base != crtc ||
-		    encoder == other_encoder)
-			continue;
-		else
-			return true;
-	}
-
-	return false;
-}
-
 static bool intel_encoder_crtc_ok(struct drm_encoder *encoder,
 				  struct drm_crtc *crtc)
 {
@@ -7531,13 +7648,39 @@ static void intel_modeset_commit_output_
 	}
 }
 
+static void
+connected_sink_compute_bpp(struct intel_connector * connector,
+			   struct intel_crtc_config *pipe_config)
+{
+	int bpp = pipe_config->pipe_bpp;
+
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] checking for sink bpp constrains\n",
+		connector->base.base.id,
+		drm_get_connector_name(&connector->base));
+
+	/* Don't use an invalid EDID bpc value */
+	if (connector->base.display_info.bpc &&
+	    connector->base.display_info.bpc * 3 < bpp) {
+		DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported max of %d\n",
+			      bpp, connector->base.display_info.bpc*3);
+		pipe_config->pipe_bpp = connector->base.display_info.bpc*3;
+	}
+
+	/* Clamp bpp to 8 on screens without EDID 1.4 */
+	if (connector->base.display_info.bpc == 0 && bpp > 24) {
+		DRM_DEBUG_KMS("clamping display bpp (was %d) to default limit of 24\n",
+			      bpp);
+		pipe_config->pipe_bpp = 24;
+	}
+}
+
 static int
-pipe_config_set_bpp(struct drm_crtc *crtc,
-		    struct drm_framebuffer *fb,
-		    struct intel_crtc_config *pipe_config)
+compute_baseline_pipe_bpp(struct intel_crtc *crtc,
+			  struct drm_framebuffer *fb,
+			  struct intel_crtc_config *pipe_config)
 {
-	struct drm_device *dev = crtc->dev;
-	struct drm_connector *connector;
+	struct drm_device *dev = crtc->base.dev;
+	struct intel_connector *connector;
 	int bpp;
 
 	switch (fb->pixel_format) {
@@ -7580,22 +7723,66 @@ pipe_config_set_bpp(struct drm_crtc *crt
 
 	/* Clamp display bpp to EDID value */
 	list_for_each_entry(connector, &dev->mode_config.connector_list,
-			    head) {
-		if (connector->encoder && connector->encoder->crtc != crtc)
+			    base.head) {
+		if (!connector->new_encoder ||
+		    connector->new_encoder->new_crtc != crtc)
 			continue;
 
-		/* Don't use an invalid EDID bpc value */
-		if (connector->display_info.bpc &&
-		    connector->display_info.bpc * 3 < bpp) {
-			DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported max of %d\n",
-				      bpp, connector->display_info.bpc*3);
-			pipe_config->pipe_bpp = connector->display_info.bpc*3;
-		}
+		connected_sink_compute_bpp(connector, pipe_config);
 	}
 
 	return bpp;
 }
 
+static void intel_dump_pipe_config(struct intel_crtc *crtc,
+				   struct intel_crtc_config *pipe_config,
+				   const char *context)
+{
+	DRM_DEBUG_KMS("[CRTC:%d]%s config for pipe %c\n", crtc->base.base.id,
+		      context, pipe_name(crtc->pipe));
+
+	DRM_DEBUG_KMS("cpu_transcoder: %c\n", transcoder_name(pipe_config->cpu_transcoder));
+	DRM_DEBUG_KMS("pipe bpp: %i, dithering: %i\n",
+		      pipe_config->pipe_bpp, pipe_config->dither);
+	DRM_DEBUG_KMS("fdi/pch: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
+		      pipe_config->has_pch_encoder,
+		      pipe_config->fdi_lanes,
+		      pipe_config->fdi_m_n.gmch_m, pipe_config->fdi_m_n.gmch_n,
+		      pipe_config->fdi_m_n.link_m, pipe_config->fdi_m_n.link_n,
+		      pipe_config->fdi_m_n.tu);
+	DRM_DEBUG_KMS("requested mode:\n");
+	drm_mode_debug_printmodeline(&pipe_config->requested_mode);
+	DRM_DEBUG_KMS("adjusted mode:\n");
+	drm_mode_debug_printmodeline(&pipe_config->adjusted_mode);
+	DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n",
+		      pipe_config->gmch_pfit.control,
+		      pipe_config->gmch_pfit.pgm_ratios,
+		      pipe_config->gmch_pfit.lvds_border_bits);
+	DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x\n",
+		      pipe_config->pch_pfit.pos,
+		      pipe_config->pch_pfit.size);
+	DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled);
+}
+
+static bool check_encoder_cloning(struct drm_crtc *crtc)
+{
+	int num_encoders = 0;
+	bool uncloneable_encoders = false;
+	struct intel_encoder *encoder;
+
+	list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list,
+			    base.head) {
+		if (&encoder->new_crtc->base != crtc)
+			continue;
+
+		num_encoders++;
+		if (!encoder->cloneable)
+			uncloneable_encoders = true;
+	}
+
+	return !(num_encoders > 1 && uncloneable_encoders);
+}
+
 static struct intel_crtc_config *
 intel_modeset_pipe_config(struct drm_crtc *crtc,
 			  struct drm_framebuffer *fb,
@@ -7605,7 +7792,13 @@ intel_modeset_pipe_config(struct drm_crt
 	struct drm_encoder_helper_funcs *encoder_funcs;
 	struct intel_encoder *encoder;
 	struct intel_crtc_config *pipe_config;
-	int plane_bpp;
+	int plane_bpp, ret = -EINVAL;
+	bool retry = true;
+
+	if (!check_encoder_cloning(crtc)) {
+		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
+		return ERR_PTR(-EINVAL);
+	}
 
 	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
 	if (!pipe_config)
@@ -7613,11 +7806,23 @@ intel_modeset_pipe_config(struct drm_crt
 
 	drm_mode_copy(&pipe_config->adjusted_mode, mode);
 	drm_mode_copy(&pipe_config->requested_mode, mode);
+	pipe_config->cpu_transcoder = to_intel_crtc(crtc)->pipe;
+	pipe_config->shared_dpll = DPLL_ID_PRIVATE;
 
-	plane_bpp = pipe_config_set_bpp(crtc, fb, pipe_config);
+	/* Compute a starting value for pipe_config->pipe_bpp taking the source
+	 * plane pixel format and any sink constraints into account. Returns the
+	 * source plane bpp so that dithering can be selected on mismatches
+	 * after encoders and crtc also have had their say. */
+	plane_bpp = compute_baseline_pipe_bpp(to_intel_crtc(crtc),
+					      fb, pipe_config);
 	if (plane_bpp < 0)
 		goto fail;
 
+encoder_retry:
+	/* Ensure the port clock defaults are reset when retrying. */
+	pipe_config->port_clock = 0;
+	pipe_config->pixel_multiplier = 1;
+
 	/* Pass our mode to the connectors and the CRTC to give them a chance to
 	 * adjust it according to limitations or connector properties, and also
 	 * a chance to reject the mode entirely.
@@ -7646,11 +7851,27 @@ intel_modeset_pipe_config(struct drm_crt
 		}
 	}
 
-	if (!(intel_crtc_compute_config(crtc, pipe_config))) {
+	/* Set default port clock if not overwritten by the encoder. Needs to be
+	 * done afterwards in case the encoder adjusts the mode. */
+	if (!pipe_config->port_clock)
+		pipe_config->port_clock = pipe_config->adjusted_mode.clock;
+
+	ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config);
+	if (ret < 0) {
 		DRM_DEBUG_KMS("CRTC fixup failed\n");
 		goto fail;
 	}
-	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
+
+	if (ret == RETRY) {
+		if (WARN(!retry, "loop in pipe configuration computation\n")) {
+			ret = -EINVAL;
+			goto fail;
+		}
+
+		DRM_DEBUG_KMS("CRTC bw constrained, retrying\n");
+		retry = false;
+		goto encoder_retry;
+	}
 
 	pipe_config->dither = pipe_config->pipe_bpp != plane_bpp;
 	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
@@ -7659,7 +7880,7 @@ intel_modeset_pipe_config(struct drm_crt
 	return pipe_config;
 fail:
 	kfree(pipe_config);
-	return ERR_PTR(-EINVAL);
+	return ERR_PTR(ret);
 }
 
 /* Computes which crtcs are affected and sets the relevant bits in the mask. For
@@ -7755,6 +7976,9 @@ intel_modeset_affected_pipes(struct drm_
 	 */
 	*modeset_pipes &= 1 << intel_crtc->pipe;
 	*prepare_pipes &= 1 << intel_crtc->pipe;
+
+	DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n",
+		      *modeset_pipes, *prepare_pipes, *disable_pipes);
 }
 
 static bool intel_crtc_in_use(struct drm_crtc *crtc)
@@ -7821,31 +8045,114 @@ intel_modeset_update_state(struct drm_de
 	list_for_each_entry((intel_crtc), \
 			    &(dev)->mode_config.crtc_list, \
 			    base.head) \
-		if (mask & (1 <<(intel_crtc)->pipe)) \
+		if (mask & (1 <<(intel_crtc)->pipe))
 
 static bool
-intel_pipe_config_compare(struct intel_crtc_config *current_config,
+intel_pipe_config_compare(struct drm_device *dev,
+			  struct intel_crtc_config *current_config,
 			  struct intel_crtc_config *pipe_config)
 {
-	if (current_config->has_pch_encoder != pipe_config->has_pch_encoder) {
-		DRM_ERROR("mismatch in has_pch_encoder "
-			  "(expected %i, found %i)\n",
-			  current_config->has_pch_encoder,
-			  pipe_config->has_pch_encoder);
-		return false;
+#define PIPE_CONF_CHECK_X(name)	\
+	if (current_config->name != pipe_config->name) { \
+		DRM_ERROR("mismatch in " #name " " \
+			  "(expected 0x%08x, found 0x%08x)\n", \
+			  current_config->name, \
+			  pipe_config->name); \
+		return false; \
 	}
 
+#define PIPE_CONF_CHECK_I(name)	\
+	if (current_config->name != pipe_config->name) { \
+		DRM_ERROR("mismatch in " #name " " \
+			  "(expected %i, found %i)\n", \
+			  current_config->name, \
+			  pipe_config->name); \
+		return false; \
+	}
+
+#define PIPE_CONF_CHECK_FLAGS(name, mask)	\
+	if ((current_config->name ^ pipe_config->name) & (mask)) { \
+		DRM_ERROR("mismatch in " #name " " \
+			  "(expected %i, found %i)\n", \
+			  current_config->name & (mask), \
+			  pipe_config->name & (mask)); \
+		return false; \
+	}
+
+#define PIPE_CONF_QUIRK(quirk)	\
+	((current_config->quirks | pipe_config->quirks) & (quirk))
+
+	PIPE_CONF_CHECK_I(cpu_transcoder);
+
+	PIPE_CONF_CHECK_I(has_pch_encoder);
+	PIPE_CONF_CHECK_I(fdi_lanes);
+	PIPE_CONF_CHECK_I(fdi_m_n.gmch_m);
+	PIPE_CONF_CHECK_I(fdi_m_n.gmch_n);
+	PIPE_CONF_CHECK_I(fdi_m_n.link_m);
+	PIPE_CONF_CHECK_I(fdi_m_n.link_n);
+	PIPE_CONF_CHECK_I(fdi_m_n.tu);
+
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_hdisplay);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_htotal);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_start);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_end);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_hsync_start);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_hsync_end);
+
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_vdisplay);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_vtotal);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_vblank_start);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_vblank_end);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_start);
+	PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_end);
+
+	if (!HAS_PCH_SPLIT(dev))
+		PIPE_CONF_CHECK_I(pixel_multiplier);
+
+	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+			      DRM_MODE_FLAG_INTERLACE);
+
+	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
+		PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+				      DRM_MODE_FLAG_PHSYNC);
+		PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+				      DRM_MODE_FLAG_NHSYNC);
+		PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+				      DRM_MODE_FLAG_PVSYNC);
+		PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+				      DRM_MODE_FLAG_NVSYNC);
+	}
+
+	PIPE_CONF_CHECK_I(requested_mode.hdisplay);
+	PIPE_CONF_CHECK_I(requested_mode.vdisplay);
+
+	PIPE_CONF_CHECK_I(gmch_pfit.control);
+	/* pfit ratios are autocomputed by the hw on gen4+ */
+	if (INTEL_INFO(dev)->gen < 4)
+		PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
+	PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
+	PIPE_CONF_CHECK_I(pch_pfit.pos);
+	PIPE_CONF_CHECK_I(pch_pfit.size);
+
+	PIPE_CONF_CHECK_I(ips_enabled);
+
+	PIPE_CONF_CHECK_I(shared_dpll);
+	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
+	PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
+	PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
+
+#undef PIPE_CONF_CHECK_X
+#undef PIPE_CONF_CHECK_I
+#undef PIPE_CONF_CHECK_FLAGS
+#undef PIPE_CONF_QUIRK
+
 	return true;
 }
 
-void
-intel_modeset_check_state(struct drm_device *dev)
+static void
+check_connector_state(struct drm_device *dev)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct intel_crtc *crtc;
-	struct intel_encoder *encoder;
 	struct intel_connector *connector;
-	struct intel_crtc_config pipe_config;
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list,
 			    base.head) {
@@ -7856,6 +8163,13 @@ intel_modeset_check_state(struct drm_dev
 		WARN(&connector->new_encoder->base != connector->base.encoder,
 		     "connector's staged encoder doesn't match current encoder\n");
 	}
+}
+
+static void
+check_encoder_state(struct drm_device *dev)
+{
+	struct intel_encoder *encoder;
+	struct intel_connector *connector;
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
 			    base.head) {
@@ -7907,12 +8221,23 @@ intel_modeset_check_state(struct drm_dev
 		     tracked_pipe, pipe);
 
 	}
+}
+
+static void
+check_crtc_state(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc;
+	struct intel_encoder *encoder;
+	struct intel_crtc_config pipe_config;
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list,
 			    base.head) {
 		bool enabled = false;
 		bool active = false;
 
+		memset(&pipe_config, 0, sizeof(pipe_config));
+
 		DRM_DEBUG_KMS("[CRTC:%d]\n",
 			      crtc->base.base.id);
 
@@ -7927,6 +8252,7 @@ intel_modeset_check_state(struct drm_dev
 			if (encoder->connectors_active)
 				active = true;
 		}
+
 		WARN(active != crtc->active,
 		     "crtc's computed active state doesn't match tracked active state "
 		     "(expected %i, found %i)\n", active, crtc->active);
@@ -7934,7 +8260,6 @@ intel_modeset_check_state(struct drm_dev
 		     "crtc's computed enabled state doesn't match tracked enabled state "
 		     "(expected %i, found %i)\n", enabled, crtc->base.enabled);
 
-		memset(&pipe_config, 0, sizeof(pipe_config));
 		active = dev_priv->display.get_pipe_config(crtc,
 							   &pipe_config);
 
@@ -7942,16 +8267,90 @@ intel_modeset_check_state(struct drm_dev
 		if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
 			active = crtc->active;
 
+		list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+				    base.head) {
+			enum pipe pipe;
+			if (encoder->base.crtc != &crtc->base)
+				continue;
+			if (encoder->get_config &&
+			    encoder->get_hw_state(encoder, &pipe))
+				encoder->get_config(encoder, &pipe_config);
+		}
+
 		WARN(crtc->active != active,
 		     "crtc active state doesn't match with hw state "
 		     "(expected %i, found %i)\n", crtc->active, active);
 
-		WARN(active &&
-		     !intel_pipe_config_compare(&crtc->config, &pipe_config),
-		     "pipe state doesn't match!\n");
+		if (active &&
+		    !intel_pipe_config_compare(dev, &crtc->config, &pipe_config)) {
+			WARN(1, "pipe state doesn't match!\n");
+			intel_dump_pipe_config(crtc, &pipe_config,
+					       "[hw state]");
+			intel_dump_pipe_config(crtc, &crtc->config,
+					       "[sw state]");
+		}
+	}
+}
+
+static void
+check_shared_dpll_state(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_crtc *crtc;
+	struct intel_dpll_hw_state dpll_hw_state;
+	int i;
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+		int enabled_crtcs = 0, active_crtcs = 0;
+		bool active;
+
+		memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
+
+		DRM_DEBUG_KMS("%s\n", pll->name);
+
+		active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state);
+
+		WARN(pll->active > pll->refcount,
+		     "more active pll users than references: %i vs %i\n",
+		     pll->active, pll->refcount);
+		WARN(pll->active && !pll->on,
+		     "pll in active use but not on in sw tracking\n");
+		WARN(pll->on && !pll->active,
+		     "pll in on but not on in use in sw tracking\n");
+		WARN(pll->on != active,
+		     "pll on state mismatch (expected %i, found %i)\n",
+		     pll->on, active);
+
+		list_for_each_entry(crtc, &dev->mode_config.crtc_list,
+				    base.head) {
+			if (crtc->base.enabled && intel_crtc_to_shared_dpll(crtc) == pll)
+				enabled_crtcs++;
+			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
+				active_crtcs++;
+		}
+		WARN(pll->active != active_crtcs,
+		     "pll active crtcs mismatch (expected %i, found %i)\n",
+		     pll->active, active_crtcs);
+		WARN(pll->refcount != enabled_crtcs,
+		     "pll enabled crtcs mismatch (expected %i, found %i)\n",
+		     pll->refcount, enabled_crtcs);
+
+		WARN(pll->on && memcmp(&pll->hw_state, &dpll_hw_state,
+				       sizeof(dpll_hw_state)),
+		     "pll hw state mismatch\n");
 	}
 }
 
+void
+intel_modeset_check_state(struct drm_device *dev)
+{
+	check_connector_state(dev);
+	check_encoder_state(dev);
+	check_crtc_state(dev);
+	check_shared_dpll_state(dev);
+}
+
 static int __intel_set_mode(struct drm_crtc *crtc,
 			    struct drm_display_mode *mode,
 			    int x, int y, struct drm_framebuffer *fb)
@@ -7988,11 +8387,10 @@ static int __intel_set_mode(struct drm_c
 
 			goto out;
 		}
+		intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
+				       "[modeset]");
 	}
 
-	DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n",
-		      modeset_pipes, prepare_pipes, disable_pipes);
-
 	for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
 		intel_crtc_disable(&intel_crtc->base);
 
@@ -8005,12 +8403,10 @@ static int __intel_set_mode(struct drm_c
 	 * to set it here already despite that we pass it down the callchain.
 	 */
 	if (modeset_pipes) {
-		enum transcoder tmp = to_intel_crtc(crtc)->config.cpu_transcoder;
 		crtc->mode = *mode;
 		/* mode_set/enable/disable functions rely on a correct pipe
 		 * config. */
 		to_intel_crtc(crtc)->config = *pipe_config;
-		to_intel_crtc(crtc)->config.cpu_transcoder = tmp;
 	}
 
 	/* Only after disabling all output pipelines that will be changed can we
@@ -8146,15 +8542,20 @@ static void intel_set_config_restore_sta
 }
 
 static bool
-is_crtc_connector_off(struct drm_crtc *crtc, struct drm_connector *connectors,
-		      int num_connectors)
+is_crtc_connector_off(struct drm_mode_set *set)
 {
 	int i;
 
-	for (i = 0; i < num_connectors; i++)
-		if (connectors[i].encoder &&
-		    connectors[i].encoder->crtc == crtc &&
-		    connectors[i].dpms != DRM_MODE_DPMS_ON)
+	if (set->num_connectors == 0)
+		return false;
+
+	if (WARN_ON(set->connectors == NULL))
+		return false;
+
+	for (i = 0; i < set->num_connectors; i++)
+		if (set->connectors[i]->encoder &&
+		    set->connectors[i]->encoder->crtc == set->crtc &&
+		    set->connectors[i]->dpms != DRM_MODE_DPMS_ON)
 			return true;
 
 	return false;
@@ -8167,10 +8568,8 @@ intel_set_config_compute_mode_changes(st
 
 	/* We should be able to check here if the fb has the same properties
 	 * and then just flip_or_move it */
-	if (set->connectors != NULL &&
-	    is_crtc_connector_off(set->crtc, *set->connectors,
-				  set->num_connectors)) {
-			config->mode_changed = true;
+	if (is_crtc_connector_off(set)) {
+		config->mode_changed = true;
 	} else if (set->crtc->fb != set->fb) {
 		/* If we have no fb then treat it as a full mode set */
 		if (set->crtc->fb == NULL) {
@@ -8349,12 +8748,6 @@ static int intel_crtc_set_config(struct
 		goto fail;
 
 	if (config->mode_changed) {
-		if (set->mode) {
-			DRM_DEBUG_KMS("attempting to set mode from"
-					" userspace\n");
-			drm_mode_debug_printmodeline(set->mode);
-		}
-
 		ret = intel_set_mode(set->crtc, set->mode,
 				     set->x, set->y, set->fb);
 	} else if (config->fb_changed) {
@@ -8365,8 +8758,8 @@ static int intel_crtc_set_config(struct
 	}
 
 	if (ret) {
-		DRM_ERROR("failed to set mode on [CRTC:%d], err = %d\n",
-			  set->crtc->base.id, ret);
+		DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
+			      set->crtc->base.id, ret);
 fail:
 		intel_set_config_restore_state(dev, config);
 
@@ -8397,23 +8790,93 @@ static void intel_cpu_pll_init(struct dr
 		intel_ddi_pll_init(dev);
 }
 
-static void intel_pch_pll_init(struct drm_device *dev)
+static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
+				      struct intel_shared_dpll *pll,
+				      struct intel_dpll_hw_state *hw_state)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	int i;
+	uint32_t val;
 
-	if (dev_priv->num_pch_pll == 0) {
-		DRM_DEBUG_KMS("No PCH PLLs on this hardware, skipping initialisation\n");
-		return;
+	val = I915_READ(PCH_DPLL(pll->id));
+	hw_state->dpll = val;
+	hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
+	hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
+
+	return val & DPLL_VCO_ENABLE;
+}
+
+static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	uint32_t reg, val;
+
+	/* PCH refclock must be enabled first */
+	assert_pch_refclk_enabled(dev_priv);
+
+	reg = PCH_DPLL(pll->id);
+	val = I915_READ(reg);
+	val |= DPLL_VCO_ENABLE;
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+	udelay(200);
+}
+
+static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_crtc *crtc;
+	uint32_t reg, val;
+
+	/* Make sure no transcoder isn't still depending on us. */
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
+		if (intel_crtc_to_shared_dpll(crtc) == pll)
+			assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
 	}
 
-	for (i = 0; i < dev_priv->num_pch_pll; i++) {
-		dev_priv->pch_plls[i].pll_reg = _PCH_DPLL(i);
-		dev_priv->pch_plls[i].fp0_reg = _PCH_FP0(i);
-		dev_priv->pch_plls[i].fp1_reg = _PCH_FP1(i);
+	reg = PCH_DPLL(pll->id);
+	val = I915_READ(reg);
+	val &= ~DPLL_VCO_ENABLE;
+	I915_WRITE(reg, val);
+	POSTING_READ(reg);
+	udelay(200);
+}
+
+static char *ibx_pch_dpll_names[] = {
+	"PCH DPLL A",
+	"PCH DPLL B",
+};
+
+static void ibx_pch_dpll_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	dev_priv->num_shared_dpll = 2;
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		dev_priv->shared_dplls[i].id = i;
+		dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
+		dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
+		dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
+		dev_priv->shared_dplls[i].get_hw_state =
+			ibx_pch_dpll_get_hw_state;
 	}
 }
 
+static void intel_shared_dpll_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+		ibx_pch_dpll_init(dev);
+	else
+		dev_priv->num_shared_dpll = 0;
+
+	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
+	DRM_DEBUG_KMS("%i shared PLLs initialized\n",
+		      dev_priv->num_shared_dpll);
+}
+
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -8436,7 +8899,6 @@ static void intel_crtc_init(struct drm_d
 	/* Swap pipes & planes for FBC on pre-965 */
 	intel_crtc->pipe = pipe;
 	intel_crtc->plane = pipe;
-	intel_crtc->config.cpu_transcoder = pipe;
 	if (IS_MOBILE(dev) && IS_GEN3(dev)) {
 		DRM_DEBUG_KMS("swapping pipes & planes for FBC\n");
 		intel_crtc->plane = !pipe;
@@ -8519,13 +8981,8 @@ static void intel_setup_outputs(struct d
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_encoder *encoder;
 	bool dpd_is_edp = false;
-	bool has_lvds;
 
-	has_lvds = intel_lvds_init(dev);
-	if (!has_lvds && !HAS_PCH_SPLIT(dev)) {
-		/* disable the panel fitter on everything but LVDS */
-		I915_WRITE(PFIT_CONTROL, 0);
-	}
+	intel_lvds_init(dev);
 
 	if (!IS_ULT(dev))
 		intel_crt_init(dev);
@@ -8598,10 +9055,8 @@ static void intel_setup_outputs(struct d
 				intel_hdmi_init(dev, GEN4_HDMIB, PORT_B);
 			}
 
-			if (!found && SUPPORTS_INTEGRATED_DP(dev)) {
-				DRM_DEBUG_KMS("probing DP_B\n");
+			if (!found && SUPPORTS_INTEGRATED_DP(dev))
 				intel_dp_init(dev, DP_B, PORT_B);
-			}
 		}
 
 		/* Before G4X SDVOC doesn't have its own detect register */
@@ -8617,17 +9072,13 @@ static void intel_setup_outputs(struct d
 				DRM_DEBUG_KMS("probing HDMI on SDVOC\n");
 				intel_hdmi_init(dev, GEN4_HDMIC, PORT_C);
 			}
-			if (SUPPORTS_INTEGRATED_DP(dev)) {
-				DRM_DEBUG_KMS("probing DP_C\n");
+			if (SUPPORTS_INTEGRATED_DP(dev))
 				intel_dp_init(dev, DP_C, PORT_C);
-			}
 		}
 
 		if (SUPPORTS_INTEGRATED_DP(dev) &&
-		    (I915_READ(DP_D) & DP_DETECTED)) {
-			DRM_DEBUG_KMS("probing DP_D\n");
+		    (I915_READ(DP_D) & DP_DETECTED))
 			intel_dp_init(dev, DP_D, PORT_D);
-		}
 	} else if (IS_GEN2(dev))
 		intel_dvo_init(dev);
 
@@ -8675,6 +9126,7 @@ int intel_framebuffer_init(struct drm_de
 			   struct drm_mode_fb_cmd2 *mode_cmd,
 			   struct drm_i915_gem_object *obj)
 {
+	int pitch_limit;
 	int ret;
 
 	if (obj->tiling_mode == I915_TILING_Y) {
@@ -8688,10 +9140,26 @@ int intel_framebuffer_init(struct drm_de
 		return -EINVAL;
 	}
 
-	/* FIXME <= Gen4 stride limits are bit unclear */
-	if (mode_cmd->pitches[0] > 32768) {
-		DRM_DEBUG("pitch (%d) must be at less than 32768\n",
-			  mode_cmd->pitches[0]);
+	if (INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev)) {
+		pitch_limit = 32*1024;
+	} else if (INTEL_INFO(dev)->gen >= 4) {
+		if (obj->tiling_mode)
+			pitch_limit = 16*1024;
+		else
+			pitch_limit = 32*1024;
+	} else if (INTEL_INFO(dev)->gen >= 3) {
+		if (obj->tiling_mode)
+			pitch_limit = 8*1024;
+		else
+			pitch_limit = 16*1024;
+	} else
+		/* XXX DSPC is limited to 4k tiled */
+		pitch_limit = 8*1024;
+
+	if (mode_cmd->pitches[0] > pitch_limit) {
+		DRM_DEBUG("%s pitch (%d) must be at less than %d\n",
+			  obj->tiling_mode ? "tiled" : "linear",
+			  mode_cmd->pitches[0], pitch_limit);
 		return -EINVAL;
 	}
 
@@ -8712,7 +9180,8 @@ int intel_framebuffer_init(struct drm_de
 	case DRM_FORMAT_XRGB1555:
 	case DRM_FORMAT_ARGB1555:
 		if (INTEL_INFO(dev)->gen > 3) {
-			DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+				  drm_get_format_name(mode_cmd->pixel_format));
 			return -EINVAL;
 		}
 		break;
@@ -8723,7 +9192,8 @@ int intel_framebuffer_init(struct drm_de
 	case DRM_FORMAT_XBGR2101010:
 	case DRM_FORMAT_ABGR2101010:
 		if (INTEL_INFO(dev)->gen < 4) {
-			DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+				  drm_get_format_name(mode_cmd->pixel_format));
 			return -EINVAL;
 		}
 		break;
@@ -8732,12 +9202,14 @@ int intel_framebuffer_init(struct drm_de
 	case DRM_FORMAT_YVYU:
 	case DRM_FORMAT_VYUY:
 		if (INTEL_INFO(dev)->gen < 5) {
-			DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
+			DRM_DEBUG("unsupported pixel format: %s\n",
+				  drm_get_format_name(mode_cmd->pixel_format));
 			return -EINVAL;
 		}
 		break;
 	default:
-		DRM_DEBUG("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format);
+		DRM_DEBUG("unsupported pixel format: %s\n",
+			  drm_get_format_name(mode_cmd->pixel_format));
 		return -EINVAL;
 	}
 
@@ -8782,6 +9254,15 @@ static void intel_init_display(struct dr
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
+	if (HAS_PCH_SPLIT(dev) || IS_G4X(dev))
+		dev_priv->display.find_dpll = g4x_find_best_dpll;
+	else if (IS_VALLEYVIEW(dev))
+		dev_priv->display.find_dpll = vlv_find_best_dpll;
+	else if (IS_PINEVIEW(dev))
+		dev_priv->display.find_dpll = pnv_find_best_dpll;
+	else
+		dev_priv->display.find_dpll = i9xx_find_best_dpll;
+
 	if (HAS_DDI(dev)) {
 		dev_priv->display.get_pipe_config = haswell_get_pipe_config;
 		dev_priv->display.crtc_mode_set = haswell_crtc_mode_set;
@@ -8796,6 +9277,13 @@ static void intel_init_display(struct dr
 		dev_priv->display.crtc_disable = ironlake_crtc_disable;
 		dev_priv->display.off = ironlake_crtc_off;
 		dev_priv->display.update_plane = ironlake_update_plane;
+	} else if (IS_VALLEYVIEW(dev)) {
+		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
+		dev_priv->display.crtc_enable = valleyview_crtc_enable;
+		dev_priv->display.crtc_disable = i9xx_crtc_disable;
+		dev_priv->display.off = i9xx_crtc_off;
+		dev_priv->display.update_plane = i9xx_update_plane;
 	} else {
 		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
 		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
@@ -8914,6 +9402,17 @@ static void quirk_invert_brightness(stru
 	DRM_INFO("applying inverted panel brightness quirk\n");
 }
 
+/*
+ * Some machines (Dell XPS13) suffer broken backlight controls if
+ * BLM_PCH_PWM_ENABLE is set.
+ */
+static void quirk_no_pcm_pwm_enable(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	dev_priv->quirks |= QUIRK_NO_PCH_PWM_ENABLE;
+	DRM_INFO("applying no-PCH_PWM_ENABLE quirk\n");
+}
+
 struct intel_quirk {
 	int device;
 	int subsystem_vendor;
@@ -8983,6 +9482,11 @@ static struct intel_quirk intel_quirks[]
 
 	/* Acer Aspire 4736Z */
 	{ 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
+
+	/* Dell XPS13 HD Sandy Bridge */
+	{ 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable },
+	/* Dell XPS13 HD and XPS13 FHD Ivy Bridge */
+	{ 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable },
 };
 
 static void intel_init_quirks(struct drm_device *dev)
@@ -9037,6 +9541,11 @@ void intel_modeset_init_hw(struct drm_de
 	mutex_unlock(&dev->struct_mutex);
 }
 
+void intel_modeset_suspend_hw(struct drm_device *dev)
+{
+	intel_suspend_hw(dev);
+}
+
 void intel_modeset_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -9082,13 +9591,13 @@ void intel_modeset_init(struct drm_devic
 		for (j = 0; j < dev_priv->num_plane; j++) {
 			ret = intel_plane_init(dev, i, j);
 			if (ret)
-				DRM_DEBUG_KMS("pipe %d plane %d init failed: %d\n",
-					      i, j, ret);
+				DRM_DEBUG_KMS("pipe %c sprite %c init failed: %d\n",
+					      pipe_name(i), sprite_name(i, j), ret);
 		}
 	}
 
 	intel_cpu_pll_init(dev);
-	intel_pch_pll_init(dev);
+	intel_shared_dpll_init(dev);
 
 	/* Just disable it once at startup */
 	i915_disable_vga(dev);
@@ -9289,57 +9798,18 @@ void i915_redisable_vga(struct drm_devic
 	}
 }
 
-/* Scan out the current hw modeset state, sanitizes it and maps it into the drm
- * and i915 state tracking structures. */
-void intel_modeset_setup_hw_state(struct drm_device *dev,
-				  bool force_restore)
+static void intel_modeset_readout_hw_state(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	enum pipe pipe;
-	u32 tmp;
-	struct drm_plane *plane;
 	struct intel_crtc *crtc;
 	struct intel_encoder *encoder;
 	struct intel_connector *connector;
+	int i;
 
-	if (HAS_DDI(dev)) {
-		tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
-
-		if (tmp & TRANS_DDI_FUNC_ENABLE) {
-			switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
-			case TRANS_DDI_EDP_INPUT_A_ON:
-			case TRANS_DDI_EDP_INPUT_A_ONOFF:
-				pipe = PIPE_A;
-				break;
-			case TRANS_DDI_EDP_INPUT_B_ONOFF:
-				pipe = PIPE_B;
-				break;
-			case TRANS_DDI_EDP_INPUT_C_ONOFF:
-				pipe = PIPE_C;
-				break;
-			default:
-				/* A bogus value has been programmed, disable
-				 * the transcoder */
-				WARN(1, "Bogus eDP source %08x\n", tmp);
-				intel_ddi_disable_transcoder_func(dev_priv,
-						TRANSCODER_EDP);
-				goto setup_pipes;
-			}
-
-			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
-			crtc->config.cpu_transcoder = TRANSCODER_EDP;
-
-			DRM_DEBUG_KMS("Pipe %c using transcoder EDP\n",
-				      pipe_name(pipe));
-		}
-	}
-
-setup_pipes:
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list,
 			    base.head) {
-		enum transcoder tmp = crtc->config.cpu_transcoder;
 		memset(&crtc->config, 0, sizeof(crtc->config));
-		crtc->config.cpu_transcoder = tmp;
 
 		crtc->active = dev_priv->display.get_pipe_config(crtc,
 								 &crtc->config);
@@ -9351,16 +9821,35 @@ setup_pipes:
 			      crtc->active ? "enabled" : "disabled");
 	}
 
+	/* FIXME: Smash this into the new shared dpll infrastructure. */
 	if (HAS_DDI(dev))
 		intel_ddi_setup_hw_pll_state(dev);
 
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+
+		pll->on = pll->get_hw_state(dev_priv, pll, &pll->hw_state);
+		pll->active = 0;
+		list_for_each_entry(crtc, &dev->mode_config.crtc_list,
+				    base.head) {
+			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
+				pll->active++;
+		}
+		pll->refcount = pll->active;
+
+		DRM_DEBUG_KMS("%s hw state readout: refcount %i, on %i\n",
+			      pll->name, pll->refcount, pll->on);
+	}
+
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
 			    base.head) {
 		pipe = 0;
 
 		if (encoder->get_hw_state(encoder, &pipe)) {
-			encoder->base.crtc =
-				dev_priv->pipe_to_crtc_mapping[pipe];
+			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+			encoder->base.crtc = &crtc->base;
+			if (encoder->get_config)
+				encoder->get_config(encoder, &crtc->config);
 		} else {
 			encoder->base.crtc = NULL;
 		}
@@ -9388,6 +9877,21 @@ setup_pipes:
 			      drm_get_connector_name(&connector->base),
 			      connector->base.encoder ? "enabled" : "disabled");
 	}
+}
+
+/* Scan out the current hw modeset state, sanitizes it and maps it into the drm
+ * and i915 state tracking structures. */
+void intel_modeset_setup_hw_state(struct drm_device *dev,
+				  bool force_restore)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum pipe pipe;
+	struct drm_plane *plane;
+	struct intel_crtc *crtc;
+	struct intel_encoder *encoder;
+	int i;
+
+	intel_modeset_readout_hw_state(dev);
 
 	/* HW state is read out, now we need to sanitize this mess. */
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
@@ -9398,6 +9902,19 @@ setup_pipes:
 	for_each_pipe(pipe) {
 		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
 		intel_sanitize_crtc(crtc);
+		intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]");
+	}
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+
+		if (!pll->on || pll->active)
+			continue;
+
+		DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name);
+
+		pll->disable(dev_priv, pll);
+		pll->on = false;
 	}
 
 	if (force_restore) {
@@ -9440,12 +9957,23 @@ void intel_modeset_cleanup(struct drm_de
 	struct drm_crtc *crtc;
 	struct intel_crtc *intel_crtc;
 
+	/*
+	 * Interrupts and polling as the first thing to avoid creating havoc.
+	 * Too much stuff here (turning of rps, connectors, ...) would
+	 * experience fancy races otherwise.
+	 */
+	drm_irq_uninstall(dev);
+	cancel_work_sync(&dev_priv->hotplug_work);
+	/*
+	 * Due to the hpd irq storm handling the hotplug work can re-arm the
+	 * poll handlers. Hence disable polling after hpd handling is shut down.
+	 */
 	drm_kms_helper_poll_fini(dev);
+
 	mutex_lock(&dev->struct_mutex);
 
 	intel_unregister_dsm_handler();
 
-
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		/* Skip inactive CRTCs */
 		if (!crtc->fb)
@@ -9461,17 +9989,8 @@ void intel_modeset_cleanup(struct drm_de
 
 	ironlake_teardown_rc6(dev);
 
-	if (IS_VALLEYVIEW(dev))
-		vlv_init_dpio(dev);
-
 	mutex_unlock(&dev->struct_mutex);
 
-	/* Disable the irq before mode object teardown, for the irq might
-	 * enqueue unpin/hotplug work. */
-	drm_irq_uninstall(dev);
-	cancel_work_sync(&dev_priv->hotplug_work);
-	cancel_work_sync(&dev_priv->rps.work);
-
 	/* flush any delayed tasks or pending work */
 	flush_scheduled_work();
 
@@ -9520,6 +10039,11 @@ int intel_modeset_vga_set_state(struct d
 #include <linux/seq_file.h>
 
 struct intel_display_error_state {
+
+	u32 power_well_driver;
+
+	int num_transcoders;
+
 	struct intel_cursor_error_state {
 		u32 control;
 		u32 position;
@@ -9528,15 +10052,7 @@ struct intel_display_error_state {
 	} cursor[I915_MAX_PIPES];
 
 	struct intel_pipe_error_state {
-		u32 conf;
 		u32 source;
-
-		u32 htotal;
-		u32 hblank;
-		u32 hsync;
-		u32 vtotal;
-		u32 vblank;
-		u32 vsync;
 	} pipe[I915_MAX_PIPES];
 
 	struct intel_plane_error_state {
@@ -9548,6 +10064,19 @@ struct intel_display_error_state {
 		u32 surface;
 		u32 tile_offset;
 	} plane[I915_MAX_PIPES];
+
+	struct intel_transcoder_error_state {
+		enum transcoder cpu_transcoder;
+
+		u32 conf;
+
+		u32 htotal;
+		u32 hblank;
+		u32 hsync;
+		u32 vtotal;
+		u32 vblank;
+		u32 vsync;
+	} transcoder[4];
 };
 
 struct intel_display_error_state *
@@ -9555,16 +10084,25 @@ intel_display_capture_error_state(struct
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct intel_display_error_state *error;
-	enum transcoder cpu_transcoder;
+	int transcoders[] = {
+		TRANSCODER_A,
+		TRANSCODER_B,
+		TRANSCODER_C,
+		TRANSCODER_EDP,
+	};
 	int i;
 
+	if (INTEL_INFO(dev)->num_pipes == 0)
+		return NULL;
+
 	error = kmalloc(sizeof(*error), GFP_ATOMIC);
 	if (error == NULL)
 		return NULL;
 
-	for_each_pipe(i) {
-		cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i);
+	if (HAS_POWER_WELL(dev))
+		error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER);
 
+	for_each_pipe(i) {
 		if (INTEL_INFO(dev)->gen <= 6 || IS_VALLEYVIEW(dev)) {
 			error->cursor[i].control = I915_READ(CURCNTR(i));
 			error->cursor[i].position = I915_READ(CURPOS(i));
@@ -9588,56 +10126,87 @@ intel_display_capture_error_state(struct
 			error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i));
 		}
 
-		error->pipe[i].conf = I915_READ(PIPECONF(cpu_transcoder));
 		error->pipe[i].source = I915_READ(PIPESRC(i));
-		error->pipe[i].htotal = I915_READ(HTOTAL(cpu_transcoder));
-		error->pipe[i].hblank = I915_READ(HBLANK(cpu_transcoder));
-		error->pipe[i].hsync = I915_READ(HSYNC(cpu_transcoder));
-		error->pipe[i].vtotal = I915_READ(VTOTAL(cpu_transcoder));
-		error->pipe[i].vblank = I915_READ(VBLANK(cpu_transcoder));
-		error->pipe[i].vsync = I915_READ(VSYNC(cpu_transcoder));
 	}
 
+	error->num_transcoders = INTEL_INFO(dev)->num_pipes;
+	if (HAS_DDI(dev_priv->dev))
+		error->num_transcoders++; /* Account for eDP. */
+
+	for (i = 0; i < error->num_transcoders; i++) {
+		enum transcoder cpu_transcoder = transcoders[i];
+
+		error->transcoder[i].cpu_transcoder = cpu_transcoder;
+
+		error->transcoder[i].conf = I915_READ(PIPECONF(cpu_transcoder));
+		error->transcoder[i].htotal = I915_READ(HTOTAL(cpu_transcoder));
+		error->transcoder[i].hblank = I915_READ(HBLANK(cpu_transcoder));
+		error->transcoder[i].hsync = I915_READ(HSYNC(cpu_transcoder));
+		error->transcoder[i].vtotal = I915_READ(VTOTAL(cpu_transcoder));
+		error->transcoder[i].vblank = I915_READ(VBLANK(cpu_transcoder));
+		error->transcoder[i].vsync = I915_READ(VSYNC(cpu_transcoder));
+	}
+
+	/* In the code above we read the registers without checking if the power
+	 * well was on, so here we have to clear the FPGA_DBG_RM_NOCLAIM bit to
+	 * prevent the next I915_WRITE from detecting it and printing an error
+	 * message. */
+	if (HAS_POWER_WELL(dev))
+		I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
+
 	return error;
 }
 
+#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
+
 void
-intel_display_print_error_state(struct seq_file *m,
+intel_display_print_error_state(struct drm_i915_error_state_buf *m,
 				struct drm_device *dev,
 				struct intel_display_error_state *error)
 {
 	int i;
 
-	seq_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes);
+	if (!error)
+		return;
+
+	err_printf(m, "Num Pipes: %d\n", INTEL_INFO(dev)->num_pipes);
+	if (HAS_POWER_WELL(dev))
+		err_printf(m, "PWR_WELL_CTL2: %08x\n",
+			   error->power_well_driver);
 	for_each_pipe(i) {
-		seq_printf(m, "Pipe [%d]:\n", i);
-		seq_printf(m, "  CONF: %08x\n", error->pipe[i].conf);
-		seq_printf(m, "  SRC: %08x\n", error->pipe[i].source);
-		seq_printf(m, "  HTOTAL: %08x\n", error->pipe[i].htotal);
-		seq_printf(m, "  HBLANK: %08x\n", error->pipe[i].hblank);
-		seq_printf(m, "  HSYNC: %08x\n", error->pipe[i].hsync);
-		seq_printf(m, "  VTOTAL: %08x\n", error->pipe[i].vtotal);
-		seq_printf(m, "  VBLANK: %08x\n", error->pipe[i].vblank);
-		seq_printf(m, "  VSYNC: %08x\n", error->pipe[i].vsync);
+		err_printf(m, "Pipe [%d]:\n", i);
+		err_printf(m, "  SRC: %08x\n", error->pipe[i].source);
 
-		seq_printf(m, "Plane [%d]:\n", i);
-		seq_printf(m, "  CNTR: %08x\n", error->plane[i].control);
-		seq_printf(m, "  STRIDE: %08x\n", error->plane[i].stride);
+		err_printf(m, "Plane [%d]:\n", i);
+		err_printf(m, "  CNTR: %08x\n", error->plane[i].control);
+		err_printf(m, "  STRIDE: %08x\n", error->plane[i].stride);
 		if (INTEL_INFO(dev)->gen <= 3) {
-			seq_printf(m, "  SIZE: %08x\n", error->plane[i].size);
-			seq_printf(m, "  POS: %08x\n", error->plane[i].pos);
+			err_printf(m, "  SIZE: %08x\n", error->plane[i].size);
+			err_printf(m, "  POS: %08x\n", error->plane[i].pos);
 		}
 		if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
-			seq_printf(m, "  ADDR: %08x\n", error->plane[i].addr);
+			err_printf(m, "  ADDR: %08x\n", error->plane[i].addr);
 		if (INTEL_INFO(dev)->gen >= 4) {
-			seq_printf(m, "  SURF: %08x\n", error->plane[i].surface);
-			seq_printf(m, "  TILEOFF: %08x\n", error->plane[i].tile_offset);
+			err_printf(m, "  SURF: %08x\n", error->plane[i].surface);
+			err_printf(m, "  TILEOFF: %08x\n", error->plane[i].tile_offset);
 		}
 
-		seq_printf(m, "Cursor [%d]:\n", i);
-		seq_printf(m, "  CNTR: %08x\n", error->cursor[i].control);
-		seq_printf(m, "  POS: %08x\n", error->cursor[i].position);
-		seq_printf(m, "  BASE: %08x\n", error->cursor[i].base);
+		err_printf(m, "Cursor [%d]:\n", i);
+		err_printf(m, "  CNTR: %08x\n", error->cursor[i].control);
+		err_printf(m, "  POS: %08x\n", error->cursor[i].position);
+		err_printf(m, "  BASE: %08x\n", error->cursor[i].base);
+	}
+
+	for (i = 0; i < error->num_transcoders; i++) {
+		err_printf(m, "  CPU transcoder: %c\n",
+			   transcoder_name(error->transcoder[i].cpu_transcoder));
+		err_printf(m, "  CONF: %08x\n", error->transcoder[i].conf);
+		err_printf(m, "  HTOTAL: %08x\n", error->transcoder[i].htotal);
+		err_printf(m, "  HBLANK: %08x\n", error->transcoder[i].hblank);
+		err_printf(m, "  HSYNC: %08x\n", error->transcoder[i].hsync);
+		err_printf(m, "  VTOTAL: %08x\n", error->transcoder[i].vtotal);
+		err_printf(m, "  VBLANK: %08x\n", error->transcoder[i].vblank);
+		err_printf(m, "  VSYNC: %08x\n", error->transcoder[i].vsync);
 	}
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_dp.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_dp.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_dp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_dp.c	2013-08-25 20:43:22.000000000 -0400
@@ -52,30 +52,6 @@ static bool is_edp(struct intel_dp *inte
 	return intel_dig_port->base.type == INTEL_OUTPUT_EDP;
 }
 
-/**
- * is_pch_edp - is the port on the PCH and attached to an eDP panel?
- * @intel_dp: DP struct
- *
- * Returns true if the given DP struct corresponds to a PCH DP port attached
- * to an eDP panel, false otherwise.  Helpful for determining whether we
- * may need FDI resources for a given DP output or not.
- */
-static bool is_pch_edp(struct intel_dp *intel_dp)
-{
-	return intel_dp->is_pch_edp;
-}
-
-/**
- * is_cpu_edp - is the port on the CPU and attached to an eDP panel?
- * @intel_dp: DP struct
- *
- * Returns true if the given DP struct corresponds to a CPU eDP port.
- */
-static bool is_cpu_edp(struct intel_dp *intel_dp)
-{
-	return is_edp(intel_dp) && !is_pch_edp(intel_dp);
-}
-
 static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@ -88,25 +64,6 @@ static struct intel_dp *intel_attached_d
 	return enc_to_intel_dp(&intel_attached_encoder(connector)->base);
 }
 
-/**
- * intel_encoder_is_pch_edp - is the given encoder a PCH attached eDP?
- * @encoder: DRM encoder
- *
- * Return true if @encoder corresponds to a PCH attached eDP panel.  Needed
- * by intel_display.c.
- */
-bool intel_encoder_is_pch_edp(struct drm_encoder *encoder)
-{
-	struct intel_dp *intel_dp;
-
-	if (!encoder)
-		return false;
-
-	intel_dp = enc_to_intel_dp(encoder);
-
-	return is_pch_edp(intel_dp);
-}
-
 static void intel_dp_link_down(struct intel_dp *intel_dp);
 
 static int
@@ -118,7 +75,12 @@ intel_dp_max_link_bw(struct intel_dp *in
 	case DP_LINK_BW_1_62:
 	case DP_LINK_BW_2_7:
 		break;
+	case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */
+		max_link_bw = DP_LINK_BW_2_7;
+		break;
 	default:
+		WARN(1, "invalid max DP link bw val %x, using 1.62Gbps\n",
+		     max_link_bw);
 		max_link_bw = DP_LINK_BW_1_62;
 		break;
 	}
@@ -344,11 +306,12 @@ intel_dp_aux_ch(struct intel_dp *intel_d
 	 * Note that PCH attached eDP panels should use a 125MHz input
 	 * clock divider.
 	 */
-	if (is_cpu_edp(intel_dp)) {
+	if (IS_VALLEYVIEW(dev)) {
+		aux_clock_divider = 100;
+	} else if (intel_dig_port->port == PORT_A) {
 		if (HAS_DDI(dev))
-			aux_clock_divider = intel_ddi_get_cdclk_freq(dev_priv) >> 1;
-		else if (IS_VALLEYVIEW(dev))
-			aux_clock_divider = 100;
+			aux_clock_divider = DIV_ROUND_CLOSEST(
+				intel_ddi_get_cdclk_freq(dev_priv), 2000);
 		else if (IS_GEN6(dev) || IS_GEN7(dev))
 			aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */
 		else
@@ -660,6 +623,49 @@ intel_dp_i2c_init(struct intel_dp *intel
 	return ret;
 }
 
+static void
+intel_dp_set_clock(struct intel_encoder *encoder,
+		   struct intel_crtc_config *pipe_config, int link_bw)
+{
+	struct drm_device *dev = encoder->base.dev;
+
+	if (IS_G4X(dev)) {
+		if (link_bw == DP_LINK_BW_1_62) {
+			pipe_config->dpll.p1 = 2;
+			pipe_config->dpll.p2 = 10;
+			pipe_config->dpll.n = 2;
+			pipe_config->dpll.m1 = 23;
+			pipe_config->dpll.m2 = 8;
+		} else {
+			pipe_config->dpll.p1 = 1;
+			pipe_config->dpll.p2 = 10;
+			pipe_config->dpll.n = 1;
+			pipe_config->dpll.m1 = 14;
+			pipe_config->dpll.m2 = 2;
+		}
+		pipe_config->clock_set = true;
+	} else if (IS_HASWELL(dev)) {
+		/* Haswell has special-purpose DP DDI clocks. */
+	} else if (HAS_PCH_SPLIT(dev)) {
+		if (link_bw == DP_LINK_BW_1_62) {
+			pipe_config->dpll.n = 1;
+			pipe_config->dpll.p1 = 2;
+			pipe_config->dpll.p2 = 10;
+			pipe_config->dpll.m1 = 12;
+			pipe_config->dpll.m2 = 9;
+		} else {
+			pipe_config->dpll.n = 2;
+			pipe_config->dpll.p1 = 1;
+			pipe_config->dpll.p2 = 10;
+			pipe_config->dpll.m1 = 14;
+			pipe_config->dpll.m2 = 8;
+		}
+		pipe_config->clock_set = true;
+	} else if (IS_VALLEYVIEW(dev)) {
+		/* FIXME: Need to figure out optimized DP clocks for vlv. */
+	}
+}
+
 bool
 intel_dp_compute_config(struct intel_encoder *encoder,
 			struct intel_crtc_config *pipe_config)
@@ -667,17 +673,18 @@ intel_dp_compute_config(struct intel_enc
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
-	struct drm_display_mode *mode = &pipe_config->requested_mode;
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	struct intel_crtc *intel_crtc = encoder->new_crtc;
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 	int lane_count, clock;
 	int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
 	int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
 	int bpp, mode_rate;
 	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
-	int target_clock, link_avail, link_clock;
+	int link_avail, link_clock;
 
-	if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && !is_cpu_edp(intel_dp))
+	if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A)
 		pipe_config->has_pch_encoder = true;
 
 	pipe_config->has_dp_encoder = true;
@@ -685,12 +692,13 @@ intel_dp_compute_config(struct intel_enc
 	if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
 		intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
 				       adjusted_mode);
-		intel_pch_panel_fitting(dev,
-					intel_connector->panel.fitting_mode,
-					mode, adjusted_mode);
+		if (!HAS_PCH_SPLIT(dev))
+			intel_gmch_panel_fitting(intel_crtc, pipe_config,
+						 intel_connector->panel.fitting_mode);
+		else
+			intel_pch_panel_fitting(intel_crtc, pipe_config,
+						intel_connector->panel.fitting_mode);
 	}
-	/* We need to take the panel's fixed mode into account. */
-	target_clock = adjusted_mode->clock;
 
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
 		return false;
@@ -701,12 +709,12 @@ intel_dp_compute_config(struct intel_enc
 
 	/* Walk through all bpp values. Luckily they're all nicely spaced with 2
 	 * bpc in between. */
-	bpp = min_t(int, 8*3, pipe_config->pipe_bpp);
-	if (is_edp(intel_dp) && dev_priv->edp.bpp)
-		bpp = min_t(int, bpp, dev_priv->edp.bpp);
+	bpp = pipe_config->pipe_bpp;
+	if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp)
+		bpp = min_t(int, bpp, dev_priv->vbt.edp_bpp);
 
 	for (; bpp >= 6*3; bpp -= 2*3) {
-		mode_rate = intel_dp_link_required(target_clock, bpp);
+		mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
 
 		for (clock = 0; clock <= max_clock; clock++) {
 			for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
@@ -741,20 +749,21 @@ found:
 
 	intel_dp->link_bw = bws[clock];
 	intel_dp->lane_count = lane_count;
-	adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
 	pipe_config->pipe_bpp = bpp;
-	pipe_config->pixel_target_clock = target_clock;
+	pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
 
 	DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
 		      intel_dp->link_bw, intel_dp->lane_count,
-		      adjusted_mode->clock, bpp);
+		      pipe_config->port_clock, bpp);
 	DRM_DEBUG_KMS("DP link bw required %i available %i\n",
 		      mode_rate, link_avail);
 
 	intel_link_compute_m_n(bpp, lane_count,
-			       target_clock, adjusted_mode->clock,
+			       adjusted_mode->clock, pipe_config->port_clock,
 			       &pipe_config->dp_m_n);
 
+	intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
+
 	return true;
 }
 
@@ -773,24 +782,28 @@ void intel_dp_init_link_config(struct in
 	}
 }
 
-static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock)
+static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
 {
-	struct drm_device *dev = crtc->dev;
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
+	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 dpa_ctl;
 
-	DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", clock);
+	DRM_DEBUG_KMS("eDP PLL enable for clock %d\n", crtc->config.port_clock);
 	dpa_ctl = I915_READ(DP_A);
 	dpa_ctl &= ~DP_PLL_FREQ_MASK;
 
-	if (clock < 200000) {
+	if (crtc->config.port_clock == 162000) {
 		/* For a long time we've carried around a ILK-DevA w/a for the
 		 * 160MHz clock. If we're really unlucky, it's still required.
 		 */
 		DRM_DEBUG_KMS("160MHz cpu eDP clock, might need ilk devA w/a\n");
 		dpa_ctl |= DP_PLL_FREQ_160MHZ;
+		intel_dp->DP |= DP_PLL_FREQ_160MHZ;
 	} else {
 		dpa_ctl |= DP_PLL_FREQ_270MHZ;
+		intel_dp->DP |= DP_PLL_FREQ_270MHZ;
 	}
 
 	I915_WRITE(DP_A, dpa_ctl);
@@ -806,8 +819,8 @@ intel_dp_mode_set(struct drm_encoder *en
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-	struct drm_crtc *crtc = encoder->crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
 
 	/*
 	 * There are four kinds of DP registers:
@@ -833,21 +846,11 @@ intel_dp_mode_set(struct drm_encoder *en
 
 	/* Handle DP bits in common between all three register formats */
 	intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
+	intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count);
 
-	switch (intel_dp->lane_count) {
-	case 1:
-		intel_dp->DP |= DP_PORT_WIDTH_1;
-		break;
-	case 2:
-		intel_dp->DP |= DP_PORT_WIDTH_2;
-		break;
-	case 4:
-		intel_dp->DP |= DP_PORT_WIDTH_4;
-		break;
-	}
 	if (intel_dp->has_audio) {
 		DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
-				 pipe_name(intel_crtc->pipe));
+				 pipe_name(crtc->pipe));
 		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
 		intel_write_eld(encoder, adjusted_mode);
 	}
@@ -856,7 +859,7 @@ intel_dp_mode_set(struct drm_encoder *en
 
 	/* Split out the IBX/CPU vs CPT settings */
 
-	if (is_cpu_edp(intel_dp) && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) {
+	if (port == PORT_A && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) {
 		if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
 			intel_dp->DP |= DP_SYNC_HS_HIGH;
 		if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
@@ -866,14 +869,8 @@ intel_dp_mode_set(struct drm_encoder *en
 		if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
 			intel_dp->DP |= DP_ENHANCED_FRAMING;
 
-		intel_dp->DP |= intel_crtc->pipe << 29;
-
-		/* don't miss out required setting for eDP */
-		if (adjusted_mode->clock < 200000)
-			intel_dp->DP |= DP_PLL_FREQ_160MHZ;
-		else
-			intel_dp->DP |= DP_PLL_FREQ_270MHZ;
-	} else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
+		intel_dp->DP |= crtc->pipe << 29;
+	} else if (!HAS_PCH_CPT(dev) || port == PORT_A) {
 		if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev))
 			intel_dp->DP |= intel_dp->color_range;
 
@@ -886,22 +883,14 @@ intel_dp_mode_set(struct drm_encoder *en
 		if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
 			intel_dp->DP |= DP_ENHANCED_FRAMING;
 
-		if (intel_crtc->pipe == 1)
+		if (crtc->pipe == 1)
 			intel_dp->DP |= DP_PIPEB_SELECT;
-
-		if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) {
-			/* don't miss out required setting for eDP */
-			if (adjusted_mode->clock < 200000)
-				intel_dp->DP |= DP_PLL_FREQ_160MHZ;
-			else
-				intel_dp->DP |= DP_PLL_FREQ_270MHZ;
-		}
 	} else {
 		intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
 	}
 
-	if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev))
-		ironlake_set_pll_edp(crtc, adjusted_mode->clock);
+	if (port == PORT_A && !IS_VALLEYVIEW(dev))
+		ironlake_set_pll_cpu_edp(intel_dp);
 }
 
 #define IDLE_ON_MASK		(PP_ON | 0 	  | PP_SEQUENCE_MASK | 0                     | PP_SEQUENCE_STATE_MASK)
@@ -1290,6 +1279,7 @@ static bool intel_dp_get_hw_state(struct
 				  enum pipe *pipe)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	enum port port = dp_to_dig_port(intel_dp)->port;
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 tmp = I915_READ(intel_dp->output_reg);
@@ -1297,9 +1287,9 @@ static bool intel_dp_get_hw_state(struct
 	if (!(tmp & DP_PORT_EN))
 		return false;
 
-	if (is_cpu_edp(intel_dp) && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) {
+	if (port == PORT_A && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) {
 		*pipe = PORT_TO_PIPE_CPT(tmp);
-	} else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) {
+	} else if (!HAS_PCH_CPT(dev) || port == PORT_A) {
 		*pipe = PORT_TO_PIPE(tmp);
 	} else {
 		u32 trans_sel;
@@ -1335,9 +1325,48 @@ static bool intel_dp_get_hw_state(struct
 	return true;
 }
 
+static void intel_dp_get_config(struct intel_encoder *encoder,
+				struct intel_crtc_config *pipe_config)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	u32 tmp, flags = 0;
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+
+	if ((port == PORT_A) || !HAS_PCH_CPT(dev)) {
+		tmp = I915_READ(intel_dp->output_reg);
+		if (tmp & DP_SYNC_HS_HIGH)
+			flags |= DRM_MODE_FLAG_PHSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NHSYNC;
+
+		if (tmp & DP_SYNC_VS_HIGH)
+			flags |= DRM_MODE_FLAG_PVSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NVSYNC;
+	} else {
+		tmp = I915_READ(TRANS_DP_CTL(crtc->pipe));
+		if (tmp & TRANS_DP_HSYNC_ACTIVE_HIGH)
+			flags |= DRM_MODE_FLAG_PHSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NHSYNC;
+
+		if (tmp & TRANS_DP_VSYNC_ACTIVE_HIGH)
+			flags |= DRM_MODE_FLAG_PVSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NVSYNC;
+	}
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 static void intel_disable_dp(struct intel_encoder *encoder)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	enum port port = dp_to_dig_port(intel_dp)->port;
+	struct drm_device *dev = encoder->base.dev;
 
 	/* Make sure the panel is off before trying to change the mode. But also
 	 * ensure that we have vdd while we switch off the panel. */
@@ -1347,16 +1376,17 @@ static void intel_disable_dp(struct inte
 	ironlake_edp_panel_off(intel_dp);
 
 	/* cpu edp my only be disable _after_ the cpu pipe/plane is disabled. */
-	if (!is_cpu_edp(intel_dp))
+	if (!(port == PORT_A || IS_VALLEYVIEW(dev)))
 		intel_dp_link_down(intel_dp);
 }
 
 static void intel_post_disable_dp(struct intel_encoder *encoder)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	enum port port = dp_to_dig_port(intel_dp)->port;
 	struct drm_device *dev = encoder->base.dev;
 
-	if (is_cpu_edp(intel_dp)) {
+	if (port == PORT_A || IS_VALLEYVIEW(dev)) {
 		intel_dp_link_down(intel_dp);
 		if (!IS_VALLEYVIEW(dev))
 			ironlake_edp_pll_off(intel_dp);
@@ -1381,15 +1411,73 @@ static void intel_enable_dp(struct intel
 	intel_dp_complete_link_train(intel_dp);
 	intel_dp_stop_link_train(intel_dp);
 	ironlake_edp_backlight_on(intel_dp);
+
+	if (IS_VALLEYVIEW(dev)) {
+		struct intel_digital_port *dport =
+			enc_to_dig_port(&encoder->base);
+		int channel = vlv_dport_to_channel(dport);
+
+		vlv_wait_port_ready(dev_priv, channel);
+	}
 }
 
 static void intel_pre_enable_dp(struct intel_encoder *encoder)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev))
+	if (dport->port == PORT_A && !IS_VALLEYVIEW(dev))
 		ironlake_edp_pll_on(intel_dp);
+
+	if (IS_VALLEYVIEW(dev)) {
+		struct intel_crtc *intel_crtc =
+			to_intel_crtc(encoder->base.crtc);
+		int port = vlv_dport_to_channel(dport);
+		int pipe = intel_crtc->pipe;
+		u32 val;
+
+		val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port));
+		val = 0;
+		if (pipe)
+			val |= (1<<21);
+		else
+			val &= ~(1<<21);
+		val |= 0x001000c4;
+		vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val);
+
+		vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port),
+				 0x00760018);
+		vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port),
+				 0x00400888);
+	}
+}
+
+static void intel_dp_pre_pll_enable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int port = vlv_dport_to_channel(dport);
+
+	if (!IS_VALLEYVIEW(dev))
+		return;
+
+	/* Program Tx lane resets to default */
+	vlv_dpio_write(dev_priv, DPIO_PCS_TX(port),
+			 DPIO_PCS_TX_LANE2_RESET |
+			 DPIO_PCS_TX_LANE1_RESET);
+	vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port),
+			 DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
+			 DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
+			 (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
+				 DPIO_PCS_CLK_SOFT_RESET);
+
+	/* Fix up inter-pair skew failure */
+	vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER1(port), 0x00750f00);
+	vlv_dpio_write(dev_priv, DPIO_TX_CTL(port), 0x00001500);
+	vlv_dpio_write(dev_priv, DPIO_TX_LANE(port), 0x40400000);
 }
 
 /*
@@ -1451,10 +1539,13 @@ static uint8_t
 intel_dp_voltage_max(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	enum port port = dp_to_dig_port(intel_dp)->port;
 
-	if (IS_GEN7(dev) && is_cpu_edp(intel_dp))
+	if (IS_VALLEYVIEW(dev))
+		return DP_TRAIN_VOLTAGE_SWING_1200;
+	else if (IS_GEN7(dev) && port == PORT_A)
 		return DP_TRAIN_VOLTAGE_SWING_800;
-	else if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp))
+	else if (HAS_PCH_CPT(dev) && port != PORT_A)
 		return DP_TRAIN_VOLTAGE_SWING_1200;
 	else
 		return DP_TRAIN_VOLTAGE_SWING_800;
@@ -1464,6 +1555,7 @@ static uint8_t
 intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	enum port port = dp_to_dig_port(intel_dp)->port;
 
 	if (HAS_DDI(dev)) {
 		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
@@ -1477,7 +1569,19 @@ intel_dp_pre_emphasis_max(struct intel_d
 		default:
 			return DP_TRAIN_PRE_EMPHASIS_0;
 		}
-	} else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) {
+	} else if (IS_VALLEYVIEW(dev)) {
+		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_400:
+			return DP_TRAIN_PRE_EMPHASIS_9_5;
+		case DP_TRAIN_VOLTAGE_SWING_600:
+			return DP_TRAIN_PRE_EMPHASIS_6;
+		case DP_TRAIN_VOLTAGE_SWING_800:
+			return DP_TRAIN_PRE_EMPHASIS_3_5;
+		case DP_TRAIN_VOLTAGE_SWING_1200:
+		default:
+			return DP_TRAIN_PRE_EMPHASIS_0;
+		}
+	} else if (IS_GEN7(dev) && port == PORT_A) {
 		switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
 		case DP_TRAIN_VOLTAGE_SWING_400:
 			return DP_TRAIN_PRE_EMPHASIS_6;
@@ -1502,6 +1606,101 @@ intel_dp_pre_emphasis_max(struct intel_d
 	}
 }
 
+static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp)
+{
+	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+	unsigned long demph_reg_value, preemph_reg_value,
+		uniqtranscale_reg_value;
+	uint8_t train_set = intel_dp->train_set[0];
+	int port = vlv_dport_to_channel(dport);
+
+	switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
+	case DP_TRAIN_PRE_EMPHASIS_0:
+		preemph_reg_value = 0x0004000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_400:
+			demph_reg_value = 0x2B405555;
+			uniqtranscale_reg_value = 0x552AB83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_600:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x5548B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_800:
+			demph_reg_value = 0x2B245555;
+			uniqtranscale_reg_value = 0x5560B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_1200:
+			demph_reg_value = 0x2B405555;
+			uniqtranscale_reg_value = 0x5598DA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPHASIS_3_5:
+		preemph_reg_value = 0x0002000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_400:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x5552B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_600:
+			demph_reg_value = 0x2B404848;
+			uniqtranscale_reg_value = 0x5580B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_800:
+			demph_reg_value = 0x2B404040;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPHASIS_6:
+		preemph_reg_value = 0x0000000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_400:
+			demph_reg_value = 0x2B305555;
+			uniqtranscale_reg_value = 0x5570B83A;
+			break;
+		case DP_TRAIN_VOLTAGE_SWING_600:
+			demph_reg_value = 0x2B2B4040;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	case DP_TRAIN_PRE_EMPHASIS_9_5:
+		preemph_reg_value = 0x0006000;
+		switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) {
+		case DP_TRAIN_VOLTAGE_SWING_400:
+			demph_reg_value = 0x1B405555;
+			uniqtranscale_reg_value = 0x55ADDA3A;
+			break;
+		default:
+			return 0;
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x00000000);
+	vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), demph_reg_value);
+	vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port),
+			 uniqtranscale_reg_value);
+	vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port), 0x0C782040);
+	vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000);
+	vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), preemph_reg_value);
+	vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x80000000);
+
+	return 0;
+}
+
 static void
 intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
@@ -1669,6 +1868,7 @@ static void
 intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	enum port port = intel_dig_port->port;
 	struct drm_device *dev = intel_dig_port->base.base.dev;
 	uint32_t signal_levels, mask;
 	uint8_t train_set = intel_dp->train_set[0];
@@ -1676,10 +1876,13 @@ intel_dp_set_signal_levels(struct intel_
 	if (HAS_DDI(dev)) {
 		signal_levels = intel_hsw_signal_levels(train_set);
 		mask = DDI_BUF_EMP_MASK;
-	} else if (IS_GEN7(dev) && is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) {
+	} else if (IS_VALLEYVIEW(dev)) {
+		signal_levels = intel_vlv_signal_levels(intel_dp);
+		mask = 0;
+	} else if (IS_GEN7(dev) && port == PORT_A) {
 		signal_levels = intel_gen7_edp_signal_levels(train_set);
 		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_IVB;
-	} else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) {
+	} else if (IS_GEN6(dev) && port == PORT_A) {
 		signal_levels = intel_gen6_edp_signal_levels(train_set);
 		mask = EDP_LINK_TRAIN_VOL_EMP_MASK_SNB;
 	} else {
@@ -1729,8 +1932,7 @@ intel_dp_set_link_train(struct intel_dp
 		}
 		I915_WRITE(DP_TP_CTL(port), temp);
 
-	} else if (HAS_PCH_CPT(dev) &&
-		   (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
+	} else if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || port != PORT_A)) {
 		dp_reg_value &= ~DP_LINK_TRAIN_MASK_CPT;
 
 		switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
@@ -1981,6 +2183,7 @@ static void
 intel_dp_link_down(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	enum port port = intel_dig_port->port;
 	struct drm_device *dev = intel_dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc =
@@ -2010,7 +2213,7 @@ intel_dp_link_down(struct intel_dp *inte
 
 	DRM_DEBUG_KMS("\n");
 
-	if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
+	if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || port != PORT_A)) {
 		DP &= ~DP_LINK_TRAIN_MASK_CPT;
 		I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
 	} else {
@@ -2301,11 +2504,10 @@ intel_dp_get_edid(struct drm_connector *
 			return NULL;
 
 		size = (intel_connector->edid->extensions + 1) * EDID_LENGTH;
-		edid = kmalloc(size, GFP_KERNEL);
+		edid = kmemdup(intel_connector->edid, size, GFP_KERNEL);
 		if (!edid)
 			return NULL;
 
-		memcpy(edid, intel_connector->edid, size);
 		return edid;
 	}
 
@@ -2499,15 +2701,16 @@ done:
 }
 
 static void
-intel_dp_destroy(struct drm_connector *connector)
+intel_dp_connector_destroy(struct drm_connector *connector)
 {
-	struct intel_dp *intel_dp = intel_attached_dp(connector);
 	struct intel_connector *intel_connector = to_intel_connector(connector);
 
 	if (!IS_ERR_OR_NULL(intel_connector->edid))
 		kfree(intel_connector->edid);
 
-	if (is_edp(intel_dp))
+	/* Can't call is_edp() since the encoder may have been destroyed
+	 * already. */
+	if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
 		intel_panel_fini(&intel_connector->panel);
 
 	drm_sysfs_connector_remove(connector);
@@ -2541,7 +2744,7 @@ static const struct drm_connector_funcs
 	.detect = intel_dp_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.set_property = intel_dp_set_property,
-	.destroy = intel_dp_destroy,
+	.destroy = intel_dp_connector_destroy,
 };
 
 static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = {
@@ -2588,11 +2791,11 @@ bool intel_dpd_is_edp(struct drm_device
 	struct child_device_config *p_child;
 	int i;
 
-	if (!dev_priv->child_dev_num)
+	if (!dev_priv->vbt.child_dev_num)
 		return false;
 
-	for (i = 0; i < dev_priv->child_dev_num; i++) {
-		p_child = dev_priv->child_dev + i;
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		p_child = dev_priv->vbt.child_dev + i;
 
 		if (p_child->dvo_port == PORT_IDPD &&
 		    p_child->device_type == DEVICE_TYPE_eDP)
@@ -2670,7 +2873,7 @@ intel_dp_init_panel_power_sequencer(stru
 	DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",
 		      cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12);
 
-	vbt = dev_priv->edp.pps;
+	vbt = dev_priv->vbt.edp_pps;
 
 	/* Upper limits from eDP 1.3 spec. Note that we use the clunky units of
 	 * our hw here, which are all in 100usec. */
@@ -2738,9 +2941,6 @@ intel_dp_init_panel_power_sequencer_regi
 		pp_div_reg = PIPEA_PP_DIVISOR;
 	}
 
-	if (IS_VALLEYVIEW(dev))
-		port_sel = I915_READ(pp_on_reg) & 0xc0000000;
-
 	/* And finally store the new values in the power sequencer. */
 	pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) |
 		(seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT);
@@ -2754,8 +2954,10 @@ intel_dp_init_panel_power_sequencer_regi
 
 	/* Haswell doesn't have any port selection bits for the panel
 	 * power sequencer any more. */
-	if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
-		if (is_cpu_edp(intel_dp))
+	if (IS_VALLEYVIEW(dev)) {
+		port_sel = I915_READ(pp_on_reg) & 0xc0000000;
+	} else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
+		if (dp_to_dig_port(intel_dp)->port == PORT_A)
 			port_sel = PANEL_POWER_PORT_DP_A;
 		else
 			port_sel = PANEL_POWER_PORT_DP_D;
@@ -2773,7 +2975,85 @@ intel_dp_init_panel_power_sequencer_regi
 		      I915_READ(pp_div_reg));
 }
 
-void
+static bool intel_edp_init_connector(struct intel_dp *intel_dp,
+				     struct intel_connector *intel_connector)
+{
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *fixed_mode = NULL;
+	struct edp_power_seq power_seq = { 0 };
+	bool has_dpcd;
+	struct drm_display_mode *scan;
+	struct edid *edid;
+
+	if (!is_edp(intel_dp))
+		return true;
+
+	intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);
+
+	/* Cache DPCD and EDID for edp. */
+	ironlake_edp_panel_vdd_on(intel_dp);
+	has_dpcd = intel_dp_get_dpcd(intel_dp);
+	ironlake_edp_panel_vdd_off(intel_dp, false);
+
+	if (has_dpcd) {
+		if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
+			dev_priv->no_aux_handshake =
+				intel_dp->dpcd[DP_MAX_DOWNSPREAD] &
+				DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
+	} else {
+		/* if this fails, presume the device is a ghost */
+		DRM_INFO("failed to retrieve link info, disabling eDP\n");
+		return false;
+	}
+
+	/* We now know it's not a ghost, init power sequence regs. */
+	intel_dp_init_panel_power_sequencer_registers(dev, intel_dp,
+						      &power_seq);
+
+	ironlake_edp_panel_vdd_on(intel_dp);
+	edid = drm_get_edid(connector, &intel_dp->adapter);
+	if (edid) {
+		if (drm_add_edid_modes(connector, edid)) {
+			drm_mode_connector_update_edid_property(connector,
+								edid);
+			drm_edid_to_eld(connector, edid);
+		} else {
+			kfree(edid);
+			edid = ERR_PTR(-EINVAL);
+		}
+	} else {
+		edid = ERR_PTR(-ENOENT);
+	}
+	intel_connector->edid = edid;
+
+	/* prefer fixed mode from EDID if available */
+	list_for_each_entry(scan, &connector->probed_modes, head) {
+		if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
+			fixed_mode = drm_mode_duplicate(dev, scan);
+			break;
+		}
+	}
+
+	/* fallback to VBT if available for eDP */
+	if (!fixed_mode && dev_priv->vbt.lfp_lvds_vbt_mode) {
+		fixed_mode = drm_mode_duplicate(dev,
+					dev_priv->vbt.lfp_lvds_vbt_mode);
+		if (fixed_mode)
+			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
+	}
+
+	ironlake_edp_panel_vdd_off(intel_dp, false);
+
+	intel_panel_init(&intel_connector->panel, fixed_mode);
+	intel_panel_setup_backlight(connector);
+
+	return true;
+}
+
+bool
 intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			struct intel_connector *intel_connector)
 {
@@ -2782,38 +3062,47 @@ intel_dp_init_connector(struct intel_dig
 	struct intel_encoder *intel_encoder = &intel_dig_port->base;
 	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_display_mode *fixed_mode = NULL;
-	struct edp_power_seq power_seq = { 0 };
 	enum port port = intel_dig_port->port;
 	const char *name = NULL;
-	int type;
+	int type, error;
 
 	/* Preserve the current hw state. */
 	intel_dp->DP = I915_READ(intel_dp->output_reg);
 	intel_dp->attached_connector = intel_connector;
 
-	if (HAS_PCH_SPLIT(dev) && port == PORT_D)
-		if (intel_dpd_is_edp(dev))
-			intel_dp->is_pch_edp = true;
-
+	type = DRM_MODE_CONNECTOR_DisplayPort;
 	/*
 	 * FIXME : We need to initialize built-in panels before external panels.
 	 * For X0, DP_C is fixed as eDP. Revisit this as part of VLV eDP cleanup
 	 */
-	if (IS_VALLEYVIEW(dev) && port == PORT_C) {
-		type = DRM_MODE_CONNECTOR_eDP;
-		intel_encoder->type = INTEL_OUTPUT_EDP;
-	} else if (port == PORT_A || is_pch_edp(intel_dp)) {
+	switch (port) {
+	case PORT_A:
 		type = DRM_MODE_CONNECTOR_eDP;
-		intel_encoder->type = INTEL_OUTPUT_EDP;
-	} else {
-		/* The intel_encoder->type value may be INTEL_OUTPUT_UNKNOWN for
-		 * DDI or INTEL_OUTPUT_DISPLAYPORT for the older gens, so don't
-		 * rewrite it.
-		 */
-		type = DRM_MODE_CONNECTOR_DisplayPort;
+		break;
+	case PORT_C:
+		if (IS_VALLEYVIEW(dev))
+			type = DRM_MODE_CONNECTOR_eDP;
+		break;
+	case PORT_D:
+		if (HAS_PCH_SPLIT(dev) && intel_dpd_is_edp(dev))
+			type = DRM_MODE_CONNECTOR_eDP;
+		break;
+	default:	/* silence GCC warning */
+		break;
 	}
 
+	/*
+	 * For eDP we always set the encoder type to INTEL_OUTPUT_EDP, but
+	 * for DP the encoder type can be set by the caller to
+	 * INTEL_OUTPUT_UNKNOWN for DDI, so don't rewrite it.
+	 */
+	if (type == DRM_MODE_CONNECTOR_eDP)
+		intel_encoder->type = INTEL_OUTPUT_EDP;
+
+	DRM_DEBUG_KMS("Adding %s connector on port %c\n",
+			type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP",
+			port_name(port));
+
 	drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
 	drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
 
@@ -2873,74 +3162,21 @@ intel_dp_init_connector(struct intel_dig
 		BUG();
 	}
 
-	if (is_edp(intel_dp))
-		intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);
-
-	intel_dp_i2c_init(intel_dp, intel_connector, name);
-
-	/* Cache DPCD and EDID for edp. */
-	if (is_edp(intel_dp)) {
-		bool ret;
-		struct drm_display_mode *scan;
-		struct edid *edid;
-
-		ironlake_edp_panel_vdd_on(intel_dp);
-		ret = intel_dp_get_dpcd(intel_dp);
-		ironlake_edp_panel_vdd_off(intel_dp, false);
-
-		if (ret) {
-			if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11)
-				dev_priv->no_aux_handshake =
-					intel_dp->dpcd[DP_MAX_DOWNSPREAD] &
-					DP_NO_AUX_HANDSHAKE_LINK_TRAINING;
-		} else {
-			/* if this fails, presume the device is a ghost */
-			DRM_INFO("failed to retrieve link info, disabling eDP\n");
-			intel_dp_encoder_destroy(&intel_encoder->base);
-			intel_dp_destroy(connector);
-			return;
-		}
-
-		/* We now know it's not a ghost, init power sequence regs. */
-		intel_dp_init_panel_power_sequencer_registers(dev, intel_dp,
-							      &power_seq);
-
-		ironlake_edp_panel_vdd_on(intel_dp);
-		edid = drm_get_edid(connector, &intel_dp->adapter);
-		if (edid) {
-			if (drm_add_edid_modes(connector, edid)) {
-				drm_mode_connector_update_edid_property(connector, edid);
-				drm_edid_to_eld(connector, edid);
-			} else {
-				kfree(edid);
-				edid = ERR_PTR(-EINVAL);
-			}
-		} else {
-			edid = ERR_PTR(-ENOENT);
-		}
-		intel_connector->edid = edid;
-
-		/* prefer fixed mode from EDID if available */
-		list_for_each_entry(scan, &connector->probed_modes, head) {
-			if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
-				fixed_mode = drm_mode_duplicate(dev, scan);
-				break;
-			}
-		}
+	error = intel_dp_i2c_init(intel_dp, intel_connector, name);
+	WARN(error, "intel_dp_i2c_init failed with error %d for port %c\n",
+	     error, port_name(port));
 
-		/* fallback to VBT if available for eDP */
-		if (!fixed_mode && dev_priv->lfp_lvds_vbt_mode) {
-			fixed_mode = drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
-			if (fixed_mode)
-				fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
+	if (!intel_edp_init_connector(intel_dp, intel_connector)) {
+		i2c_del_adapter(&intel_dp->adapter);
+		if (is_edp(intel_dp)) {
+			cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
+			mutex_lock(&dev->mode_config.mutex);
+			ironlake_panel_vdd_off_sync(intel_dp);
+			mutex_unlock(&dev->mode_config.mutex);
 		}
-
-		ironlake_edp_panel_vdd_off(intel_dp, false);
-	}
-
-	if (is_edp(intel_dp)) {
-		intel_panel_init(&intel_connector->panel, fixed_mode);
-		intel_panel_setup_backlight(connector);
+		drm_sysfs_connector_remove(connector);
+		drm_connector_cleanup(connector);
+		return false;
 	}
 
 	intel_dp_add_properties(intel_dp, connector);
@@ -2953,6 +3189,8 @@ intel_dp_init_connector(struct intel_dig
 		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
 		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
 	}
+
+	return true;
 }
 
 void
@@ -2986,6 +3224,9 @@ intel_dp_init(struct drm_device *dev, in
 	intel_encoder->disable = intel_disable_dp;
 	intel_encoder->post_disable = intel_post_disable_dp;
 	intel_encoder->get_hw_state = intel_dp_get_hw_state;
+	intel_encoder->get_config = intel_dp_get_config;
+	if (IS_VALLEYVIEW(dev))
+		intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable;
 
 	intel_dig_port->port = port;
 	intel_dig_port->dp.output_reg = output_reg;
@@ -2995,5 +3236,9 @@ intel_dp_init(struct drm_device *dev, in
 	intel_encoder->cloneable = false;
 	intel_encoder->hot_plug = intel_dp_hot_plug;
 
-	intel_dp_init_connector(intel_dig_port, intel_connector);
+	if (!intel_dp_init_connector(intel_dig_port, intel_connector)) {
+		drm_encoder_cleanup(encoder);
+		kfree(intel_dig_port);
+		kfree(intel_connector);
+	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -120,7 +120,6 @@ struct intel_encoder {
 	struct intel_crtc *new_crtc;
 
 	int type;
-	bool needs_tv_clock;
 	/*
 	 * Intel hw has only one MUX where encoders could be clone, hence a
 	 * simple flag is enough to compute the possible_clones mask.
@@ -140,6 +139,12 @@ struct intel_encoder {
 	 * the encoder is active. If the encoder is enabled it also set the pipe
 	 * it is connected to in the pipe parameter. */
 	bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe);
+	/* Reconstructs the equivalent mode flags for the current hardware
+	 * state. This must be called _after_ display->get_pipe_config has
+	 * pre-filled the pipe config. Note that intel_encoder->base.crtc must
+	 * be set correctly before calling this function. */
+	void (*get_config)(struct intel_encoder *,
+			   struct intel_crtc_config *pipe_config);
 	int crtc_mask;
 	enum hpd_pin hpd_pin;
 };
@@ -177,7 +182,30 @@ struct intel_connector {
 	u8 polled;
 };
 
+typedef struct dpll {
+	/* given values */
+	int n;
+	int m1, m2;
+	int p1, p2;
+	/* derived values */
+	int	dot;
+	int	vco;
+	int	m;
+	int	p;
+} intel_clock_t;
+
 struct intel_crtc_config {
+	/**
+	 * quirks - bitfield with hw state readout quirks
+	 *
+	 * For various reasons the hw state readout code might not be able to
+	 * completely faithfully read out the current state. These cases are
+	 * tracked with quirk flags so that fastboot and state checker can act
+	 * accordingly.
+	 */
+#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */
+	unsigned long quirks;
+
 	struct drm_display_mode requested_mode;
 	struct drm_display_mode adjusted_mode;
 	/* This flag must be set by the encoder's compute_config callback if it
@@ -201,29 +229,67 @@ struct intel_crtc_config {
 	/* DP has a bunch of special case unfortunately, so mark the pipe
 	 * accordingly. */
 	bool has_dp_encoder;
+
+	/*
+	 * Enable dithering, used when the selected pipe bpp doesn't match the
+	 * plane bpp.
+	 */
 	bool dither;
 
 	/* Controls for the clock computation, to override various stages. */
 	bool clock_set;
 
+	/* SDVO TV has a bunch of special case. To make multifunction encoders
+	 * work correctly, we need to track this at runtime.*/
+	bool sdvo_tv_clock;
+
+	/*
+	 * crtc bandwidth limit, don't increase pipe bpp or clock if not really
+	 * required. This is set in the 2nd loop of calling encoder's
+	 * ->compute_config if the first pick doesn't work out.
+	 */
+	bool bw_constrained;
+
 	/* Settings for the intel dpll used on pretty much everything but
 	 * haswell. */
-	struct dpll {
-		unsigned n;
-		unsigned m1, m2;
-		unsigned p1, p2;
-	} dpll;
+	struct dpll dpll;
+
+	/* Selected dpll when shared or DPLL_ID_PRIVATE. */
+	enum intel_dpll_id shared_dpll;
+
+	/* Actual register state of the dpll, for shared dpll cross-checking. */
+	struct intel_dpll_hw_state dpll_hw_state;
 
 	int pipe_bpp;
 	struct intel_link_m_n dp_m_n;
-	/**
-	 * This is currently used by DP and HDMI encoders since those can have a
-	 * target pixel clock != the port link clock (which is currently stored
-	 * in adjusted_mode->clock).
+
+	/*
+	 * Frequence the dpll for the port should run at. Differs from the
+	 * adjusted dotclock e.g. for DP or 12bpc hdmi mode.
 	 */
-	int pixel_target_clock;
+	int port_clock;
+
 	/* Used by SDVO (and if we ever fix it, HDMI). */
 	unsigned pixel_multiplier;
+
+	/* Panel fitter controls for gen2-gen4 + VLV */
+	struct {
+		u32 control;
+		u32 pgm_ratios;
+		u32 lvds_border_bits;
+	} gmch_pfit;
+
+	/* Panel fitter placement and size for Ironlake+ */
+	struct {
+		u32 pos;
+		u32 size;
+	} pch_pfit;
+
+	/* FDI configuration, only valid if has_pch_encoder is set. */
+	int fdi_lanes;
+	struct intel_link_m_n fdi_m_n;
+
+	bool ips_enabled;
 };
 
 struct intel_crtc {
@@ -242,7 +308,6 @@ struct intel_crtc {
 	bool lowfreq_avail;
 	struct intel_overlay *overlay;
 	struct intel_unpin_work *unpin_work;
-	int fdi_lanes;
 
 	atomic_t unpin_work_count;
 
@@ -259,12 +324,14 @@ struct intel_crtc {
 
 	struct intel_crtc_config config;
 
-	/* We can share PLLs across outputs if the timings match */
-	struct intel_pch_pll *pch_pll;
 	uint32_t ddi_pll_sel;
 
 	/* reset counter value when the last flip was submitted */
 	unsigned int reset_counter;
+
+	/* Access to these should be protected by dev_priv->irq_lock. */
+	bool cpu_fifo_underrun_disabled;
+	bool pch_fifo_underrun_disabled;
 };
 
 struct intel_plane {
@@ -279,6 +346,18 @@ struct intel_plane {
 	unsigned int crtc_w, crtc_h;
 	uint32_t src_x, src_y;
 	uint32_t src_w, src_h;
+
+	/* Since we need to change the watermarks before/after
+	 * enabling/disabling the planes, we need to store the parameters here
+	 * as the other pieces of the struct may not reflect the values we want
+	 * for the watermark calculations. Currently only Haswell uses this.
+	 */
+	struct {
+		bool enable;
+		uint8_t bytes_per_pixel;
+		uint32_t horiz_pixels;
+	} wm;
+
 	void (*update_plane)(struct drm_plane *plane,
 			     struct drm_framebuffer *fb,
 			     struct drm_i915_gem_object *obj,
@@ -411,7 +490,6 @@ struct intel_dp {
 	uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
 	struct i2c_adapter adapter;
 	struct i2c_algo_dp_aux_data algo;
-	bool is_pch_edp;
 	uint8_t train_set[4];
 	int panel_power_up_delay;
 	int panel_power_down_delay;
@@ -426,11 +504,24 @@ struct intel_dp {
 struct intel_digital_port {
 	struct intel_encoder base;
 	enum port port;
-	u32 port_reversal;
+	u32 saved_port_bits;
 	struct intel_dp dp;
 	struct intel_hdmi hdmi;
 };
 
+static inline int
+vlv_dport_to_channel(struct intel_digital_port *dport)
+{
+	switch (dport->port) {
+	case PORT_B:
+		return 0;
+	case PORT_C:
+		return 1;
+	default:
+		BUG();
+	}
+}
+
 static inline struct drm_crtc *
 intel_get_crtc_for_pipe(struct drm_device *dev, int pipe)
 {
@@ -474,6 +565,7 @@ int intel_ddc_get_modes(struct drm_conne
 extern void intel_attach_force_audio_property(struct drm_connector *connector);
 extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
 
+extern bool intel_pipe_has_type(struct drm_crtc *crtc, int type);
 extern void intel_crt_init(struct drm_device *dev);
 extern void intel_hdmi_init(struct drm_device *dev,
 			    int hdmi_reg, enum port port);
@@ -488,13 +580,14 @@ extern bool intel_sdvo_init(struct drm_d
 extern void intel_dvo_init(struct drm_device *dev);
 extern void intel_tv_init(struct drm_device *dev);
 extern void intel_mark_busy(struct drm_device *dev);
-extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj);
+extern void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
+			       struct intel_ring_buffer *ring);
 extern void intel_mark_idle(struct drm_device *dev);
-extern bool intel_lvds_init(struct drm_device *dev);
+extern void intel_lvds_init(struct drm_device *dev);
 extern bool intel_is_dual_link_lvds(struct drm_device *dev);
 extern void intel_dp_init(struct drm_device *dev, int output_reg,
 			  enum port port);
-extern void intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
+extern bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 				    struct intel_connector *intel_connector);
 extern void intel_dp_init_link_config(struct intel_dp *intel_dp);
 extern void intel_dp_start_link_train(struct intel_dp *intel_dp);
@@ -512,7 +605,6 @@ extern void ironlake_edp_panel_on(struct
 extern void ironlake_edp_panel_off(struct intel_dp *intel_dp);
 extern void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp);
 extern void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
-extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
 extern int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
 extern void intel_flush_display_plane(struct drm_i915_private *dev_priv,
 				      enum plane plane);
@@ -524,12 +616,14 @@ extern void intel_panel_fini(struct inte
 
 extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
 				   struct drm_display_mode *adjusted_mode);
-extern void intel_pch_panel_fitting(struct drm_device *dev,
-				    int fitting_mode,
-				    const struct drm_display_mode *mode,
-				    struct drm_display_mode *adjusted_mode);
-extern u32 intel_panel_get_max_backlight(struct drm_device *dev);
-extern void intel_panel_set_backlight(struct drm_device *dev, u32 level);
+extern void intel_pch_panel_fitting(struct intel_crtc *crtc,
+				    struct intel_crtc_config *pipe_config,
+				    int fitting_mode);
+extern void intel_gmch_panel_fitting(struct intel_crtc *crtc,
+				     struct intel_crtc_config *pipe_config,
+				     int fitting_mode);
+extern void intel_panel_set_backlight(struct drm_device *dev,
+				      u32 level, u32 max);
 extern int intel_panel_setup_backlight(struct drm_connector *connector);
 extern void intel_panel_enable_backlight(struct drm_device *dev,
 					 enum pipe pipe);
@@ -553,11 +647,11 @@ extern void intel_crtc_load_lut(struct d
 extern void intel_crtc_update_dpms(struct drm_crtc *crtc);
 extern void intel_encoder_destroy(struct drm_encoder *encoder);
 extern void intel_encoder_dpms(struct intel_encoder *encoder, int mode);
-extern bool intel_encoder_check_is_cloned(struct intel_encoder *encoder);
 extern void intel_connector_dpms(struct drm_connector *, int mode);
 extern bool intel_connector_get_hw_state(struct intel_connector *connector);
 extern void intel_modeset_check_state(struct drm_device *dev);
 extern void intel_plane_restore(struct drm_plane *plane);
+extern void intel_plane_disable(struct drm_plane *plane);
 
 
 static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector)
@@ -565,19 +659,17 @@ static inline struct intel_encoder *inte
 	return to_intel_connector(connector)->encoder;
 }
 
-static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
-{
-	struct intel_digital_port *intel_dig_port =
-		container_of(encoder, struct intel_digital_port, base.base);
-	return &intel_dig_port->dp;
-}
-
 static inline struct intel_digital_port *
 enc_to_dig_port(struct drm_encoder *encoder)
 {
 	return container_of(encoder, struct intel_digital_port, base.base);
 }
 
+static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
+{
+	return &enc_to_dig_port(encoder)->dp;
+}
+
 static inline struct intel_digital_port *
 dp_to_dig_port(struct intel_dp *intel_dp)
 {
@@ -607,6 +699,7 @@ intel_pipe_to_cpu_transcoder(struct drm_
 extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
 extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe);
 extern int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp);
+extern void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port);
 
 struct intel_load_detect_pipe {
 	struct drm_framebuffer *release_fb;
@@ -660,13 +753,9 @@ extern void assert_pipe(struct drm_i915_
 #define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
 
 extern void intel_init_clock_gating(struct drm_device *dev);
+extern void intel_suspend_hw(struct drm_device *dev);
 extern void intel_write_eld(struct drm_encoder *encoder,
 			    struct drm_display_mode *mode);
-extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe);
-extern void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
-					 struct intel_link_m_n *m_n);
-extern void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
-					 struct intel_link_m_n *m_n);
 extern void intel_prepare_ddi(struct drm_device *dev);
 extern void hsw_fdi_link_train(struct drm_crtc *crtc);
 extern void intel_ddi_init(struct drm_device *dev, enum port port);
@@ -675,9 +764,7 @@ extern void intel_ddi_init(struct drm_de
 extern void intel_update_watermarks(struct drm_device *dev);
 extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
 					   uint32_t sprite_width,
-					   int pixel_size);
-extern void intel_update_linetime_watermarks(struct drm_device *dev, int pipe,
-			 struct drm_display_mode *mode);
+					   int pixel_size, bool enable);
 
 extern unsigned long intel_gen4_compute_page_offset(int *x, int *y,
 						    unsigned int tiling_mode,
@@ -689,8 +776,6 @@ extern int intel_sprite_set_colorkey(str
 extern int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
 				     struct drm_file *file_priv);
 
-extern u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg);
-
 /* Power-related functions, located in intel_pm.c */
 extern void intel_init_pm(struct drm_device *dev);
 /* FBC */
@@ -701,7 +786,12 @@ extern void intel_update_fbc(struct drm_
 extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
 extern void intel_gpu_ips_teardown(void);
 
-extern bool intel_using_power_well(struct drm_device *dev);
+/* Power well */
+extern int i915_init_power_well(struct drm_device *dev);
+extern void i915_remove_power_well(struct drm_device *dev);
+
+extern bool intel_display_power_enabled(struct drm_device *dev,
+					enum intel_display_power_domain domain);
 extern void intel_init_power_well(struct drm_device *dev);
 extern void intel_set_power_well(struct drm_device *dev, bool enable);
 extern void intel_enable_gt_powersave(struct drm_device *dev);
@@ -719,7 +809,7 @@ extern void intel_ddi_disable_transcoder
 extern void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
 extern void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
 extern void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
-extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc, int clock);
+extern bool intel_ddi_pll_mode_set(struct drm_crtc *crtc);
 extern void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
 extern void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
 extern void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
@@ -728,5 +818,11 @@ intel_ddi_connector_get_hw_state(struct
 extern void intel_ddi_fdi_disable(struct drm_crtc *crtc);
 
 extern void intel_display_handle_reset(struct drm_device *dev);
+extern bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
+						  enum pipe pipe,
+						  bool enable);
+extern bool intel_set_pch_fifo_underrun_reporting(struct drm_device *dev,
+						 enum transcoder pch_transcoder,
+						 bool enable);
 
 #endif /* __INTEL_DRV_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_dvo.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_dvo.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_dvo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_dvo.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,6 +54,13 @@ static const struct intel_dvo_device int
 		.dev_ops = &ch7xxx_ops,
 	},
 	{
+		.type = INTEL_DVO_CHIP_TMDS,
+		.name = "ch7xxx",
+		.dvo_reg = DVOC,
+		.slave_addr = 0x75, /* For some ch7010 */
+		.dev_ops = &ch7xxx_ops,
+	},
+	{
 		.type = INTEL_DVO_CHIP_LVDS,
 		.name = "ivch",
 		.dvo_reg = DVOA,
@@ -129,6 +136,26 @@ static bool intel_dvo_get_hw_state(struc
 	return true;
 }
 
+static void intel_dvo_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_config *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(intel_dvo->dev.dvo_reg);
+	if (tmp & DVO_HSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	if (tmp & DVO_VSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 static void intel_disable_dvo(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
@@ -153,6 +180,7 @@ static void intel_enable_dvo(struct inte
 	intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
 }
 
+/* Special dpms function to support cloning between dvo/sdvo/crt. */
 static void intel_dvo_dpms(struct drm_connector *connector, int mode)
 {
 	struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
@@ -174,6 +202,8 @@ static void intel_dvo_dpms(struct drm_co
 		return;
 	}
 
+	/* We call connector dpms manually below in case pipe dpms doesn't
+	 * change due to cloning. */
 	if (mode == DRM_MODE_DPMS_ON) {
 		intel_dvo->base.connectors_active = true;
 
@@ -440,6 +470,7 @@ void intel_dvo_init(struct drm_device *d
 	intel_encoder->disable = intel_disable_dvo;
 	intel_encoder->enable = intel_enable_dvo;
 	intel_encoder->get_hw_state = intel_dvo_get_hw_state;
+	intel_encoder->get_config = intel_dvo_get_config;
 	intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
 
 	/* Now, try to find a controller */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_fb.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_fb.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_fb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_fb.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,8 +60,9 @@ static struct fb_ops intelfb_ops = {
 static int intelfb_create(struct drm_fb_helper *helper,
 			  struct drm_fb_helper_surface_size *sizes)
 {
-	struct intel_fbdev *ifbdev = (struct intel_fbdev *)helper;
-	struct drm_device *dev = ifbdev->helper.dev;
+	struct intel_fbdev *ifbdev =
+		container_of(helper, struct intel_fbdev, helper);
+	struct drm_device *dev = helper->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct fb_info *info;
 	struct drm_framebuffer *fb;
@@ -108,7 +109,7 @@ static int intelfb_create(struct drm_fb_
 		goto out_unpin;
 	}
 
-	info->par = ifbdev;
+	info->par = helper;
 
 	ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
 	if (ret)
@@ -217,7 +218,7 @@ static void intel_fbdev_destroy(struct d
 int intel_fbdev_init(struct drm_device *dev)
 {
 	struct intel_fbdev *ifbdev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret;
 
 	ifbdev = kzalloc(sizeof(struct intel_fbdev), GFP_KERNEL);
@@ -242,7 +243,7 @@ int intel_fbdev_init(struct drm_device *
 
 void intel_fbdev_initial_config(struct drm_device *dev)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	/* Due to peculiar init order wrt to hpd handling this is separate. */
 	drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 32);
@@ -250,7 +251,7 @@ void intel_fbdev_initial_config(struct d
 
 void intel_fbdev_fini(struct drm_device *dev)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	if (!dev_priv->fbdev)
 		return;
 
@@ -261,7 +262,7 @@ void intel_fbdev_fini(struct drm_device
 
 void intel_fbdev_set_suspend(struct drm_device *dev, int state)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_fbdev *ifbdev = dev_priv->fbdev;
 	struct fb_info *info;
 
@@ -274,7 +275,7 @@ void intel_fbdev_set_suspend(struct drm_
 	 * been restored from swap. If the object is stolen however, it will be
 	 * full of whatever garbage was left in there.
 	 */
-	if (!state && ifbdev->ifb.obj->stolen)
+	if (state == FBINFO_STATE_RUNNING && ifbdev->ifb.obj->stolen)
 		memset_io(info->screen_base, 0, info->screen_size);
 
 	fb_set_suspend(info, state);
@@ -284,16 +285,14 @@ MODULE_LICENSE("GPL and additional right
 
 void intel_fb_output_poll_changed(struct drm_device *dev)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);
 }
 
 void intel_fb_restore_mode(struct drm_device *dev)
 {
 	int ret;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_mode_config *config = &dev->mode_config;
-	struct drm_plane *plane;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	if (INTEL_INFO(dev)->num_pipes == 0)
 		return;
@@ -304,10 +303,5 @@ void intel_fb_restore_mode(struct drm_de
 	if (ret)
 		DRM_DEBUG("failed to restore crtc mode\n");
 
-	/* Be sure to shut off any planes that may be active */
-	list_for_each_entry(plane, &config->plane_list, head)
-		if (plane->enabled)
-			plane->funcs->disable_plane(plane);
-
 	drm_modeset_unlock_all(dev);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_hdmi.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_hdmi.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_hdmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_hdmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -602,7 +602,7 @@ static void intel_hdmi_mode_set(struct d
 	u32 hdmi_val;
 
 	hdmi_val = SDVO_ENCODING_HDMI;
-	if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev))
+	if (!HAS_PCH_SPLIT(dev))
 		hdmi_val |= intel_hdmi->color_range;
 	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
 		hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH;
@@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(stru
 	return true;
 }
 
+static void intel_hdmi_get_config(struct intel_encoder *encoder,
+				  struct intel_crtc_config *pipe_config)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(intel_hdmi->hdmi_reg);
+
+	if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 static void intel_enable_hdmi(struct intel_encoder *encoder)
 {
 	struct drm_device *dev = encoder->base.dev;
@@ -697,6 +719,14 @@ static void intel_enable_hdmi(struct int
 		I915_WRITE(intel_hdmi->hdmi_reg, temp);
 		POSTING_READ(intel_hdmi->hdmi_reg);
 	}
+
+	if (IS_VALLEYVIEW(dev)) {
+		struct intel_digital_port *dport =
+			enc_to_dig_port(&encoder->base);
+		int channel = vlv_dport_to_channel(dport);
+
+		vlv_wait_port_ready(dev_priv, channel);
+	}
 }
 
 static void intel_disable_hdmi(struct intel_encoder *encoder)
@@ -755,10 +785,22 @@ static void intel_disable_hdmi(struct in
 	}
 }
 
+static int hdmi_portclock_limit(struct intel_hdmi *hdmi)
+{
+	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
+
+	if (IS_G4X(dev))
+		return 165000;
+	else if (IS_HASWELL(dev))
+		return 300000;
+	else
+		return 225000;
+}
+
 static int intel_hdmi_mode_valid(struct drm_connector *connector,
 				 struct drm_display_mode *mode)
 {
-	if (mode->clock > 165000)
+	if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector)))
 		return MODE_CLOCK_HIGH;
 	if (mode->clock < 20000)
 		return MODE_CLOCK_LOW;
@@ -775,6 +817,9 @@ bool intel_hdmi_compute_config(struct in
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+	int clock_12bpc = pipe_config->requested_mode.clock * 3 / 2;
+	int portclock_limit = hdmi_portclock_limit(intel_hdmi);
+	int desired_bpp;
 
 	if (intel_hdmi->color_range_auto) {
 		/* See CEA-861-E - 5.1 Default Encoding Parameters */
@@ -794,14 +839,29 @@ bool intel_hdmi_compute_config(struct in
 	/*
 	 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
 	 * through, clamp it down. Note that g4x/vlv don't support 12bpc hdmi
-	 * outputs.
+	 * outputs. We also need to check that the higher clock still fits
+	 * within limits.
 	 */
-	if (pipe_config->pipe_bpp > 8*3 && HAS_PCH_SPLIT(dev)) {
-		DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
-		pipe_config->pipe_bpp = 12*3;
+	if (pipe_config->pipe_bpp > 8*3 && clock_12bpc <= portclock_limit
+	    && HAS_PCH_SPLIT(dev)) {
+		DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n");
+		desired_bpp = 12*3;
+
+		/* Need to adjust the port link by 1.5x for 12bpc. */
+		pipe_config->port_clock = clock_12bpc;
 	} else {
-		DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
-		pipe_config->pipe_bpp = 8*3;
+		DRM_DEBUG_KMS("picking bpc to 8 for HDMI output\n");
+		desired_bpp = 8*3;
+	}
+
+	if (!pipe_config->bw_constrained) {
+		DRM_DEBUG_KMS("forcing pipe bpc to %i for HDMI\n", desired_bpp);
+		pipe_config->pipe_bpp = desired_bpp;
+	}
+
+	if (adjusted_mode->clock > portclock_limit) {
+		DRM_DEBUG_KMS("too high HDMI clock, rejecting mode\n");
+		return false;
 	}
 
 	return true;
@@ -955,6 +1015,97 @@ done:
 	return 0;
 }
 
+static void intel_hdmi_pre_enable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc =
+		to_intel_crtc(encoder->base.crtc);
+	int port = vlv_dport_to_channel(dport);
+	int pipe = intel_crtc->pipe;
+	u32 val;
+
+	if (!IS_VALLEYVIEW(dev))
+		return;
+
+	/* Enable clock channels for this port */
+	val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port));
+	val = 0;
+	if (pipe)
+		val |= (1<<21);
+	else
+		val &= ~(1<<21);
+	val |= 0x001000c4;
+	vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val);
+
+	/* HDMI 1.0V-2dB */
+	vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0);
+	vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port),
+			 0x2b245f5f);
+	vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port),
+			 0x5578b83a);
+	vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port),
+			 0x0c782040);
+	vlv_dpio_write(dev_priv, DPIO_TX3_SWING_CTL4(port),
+			 0x2b247878);
+	vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000);
+	vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port),
+			 0x00002000);
+	vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port),
+			 DPIO_TX_OCALINIT_EN);
+
+	/* Program lane clock */
+	vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port),
+			 0x00760018);
+	vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port),
+			 0x00400888);
+}
+
+static void intel_hdmi_pre_pll_enable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int port = vlv_dport_to_channel(dport);
+
+	if (!IS_VALLEYVIEW(dev))
+		return;
+
+	/* Program Tx lane resets to default */
+	vlv_dpio_write(dev_priv, DPIO_PCS_TX(port),
+			 DPIO_PCS_TX_LANE2_RESET |
+			 DPIO_PCS_TX_LANE1_RESET);
+	vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port),
+			 DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
+			 DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
+			 (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
+			 DPIO_PCS_CLK_SOFT_RESET);
+
+	/* Fix up inter-pair skew failure */
+	vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER1(port), 0x00750f00);
+	vlv_dpio_write(dev_priv, DPIO_TX_CTL(port), 0x00001500);
+	vlv_dpio_write(dev_priv, DPIO_TX_LANE(port), 0x40400000);
+
+	vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port),
+			 0x00002000);
+	vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port),
+			 DPIO_TX_OCALINIT_EN);
+}
+
+static void intel_hdmi_post_disable(struct intel_encoder *encoder)
+{
+	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	int port = vlv_dport_to_channel(dport);
+
+	/* Reset lanes to avoid HDMI flicker (VLV w/a) */
+	mutex_lock(&dev_priv->dpio_lock);
+	vlv_dpio_write(dev_priv, DPIO_PCS_TX(port), 0x00000000);
+	vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port), 0x00e00060);
+	mutex_unlock(&dev_priv->dpio_lock);
+}
+
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
 	drm_sysfs_connector_remove(connector);
@@ -1094,6 +1245,12 @@ void intel_hdmi_init(struct drm_device *
 	intel_encoder->enable = intel_enable_hdmi;
 	intel_encoder->disable = intel_disable_hdmi;
 	intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
+	intel_encoder->get_config = intel_hdmi_get_config;
+	if (IS_VALLEYVIEW(dev)) {
+		intel_encoder->pre_enable = intel_hdmi_pre_enable;
+		intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable;
+		intel_encoder->post_disable = intel_hdmi_post_disable;
+	}
 
 	intel_encoder->type = INTEL_OUTPUT_HDMI;
 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_lvds.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_lvds.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_lvds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_lvds.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,8 +49,6 @@ struct intel_lvds_connector {
 struct intel_lvds_encoder {
 	struct intel_encoder base;
 
-	u32 pfit_control;
-	u32 pfit_pgm_ratios;
 	bool is_dual_link;
 	u32 reg;
 
@@ -88,6 +86,38 @@ static bool intel_lvds_get_hw_state(stru
 	return true;
 }
 
+static void intel_lvds_get_config(struct intel_encoder *encoder,
+				  struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 lvds_reg, tmp, flags = 0;
+
+	if (HAS_PCH_SPLIT(dev))
+		lvds_reg = PCH_LVDS;
+	else
+		lvds_reg = LVDS;
+
+	tmp = I915_READ(lvds_reg);
+	if (tmp & LVDS_HSYNC_POLARITY)
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	if (tmp & LVDS_VSYNC_POLARITY)
+		flags |= DRM_MODE_FLAG_NVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_PVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+
+	/* gen2/3 store dither state in pfit control, needs to match */
+	if (INTEL_INFO(dev)->gen < 4) {
+		tmp = I915_READ(PFIT_CONTROL);
+
+		pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
+	}
+}
+
 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
  * This is an exception to the general rule that mode_set doesn't turn
  * things on.
@@ -118,7 +148,8 @@ static void intel_pre_pll_enable_lvds(st
 	}
 
 	/* set the corresponsding LVDS_BORDER bit */
-	temp |= dev_priv->lvds_border_bits;
+	temp &= ~LVDS_BORDER_ENABLE;
+	temp |= intel_crtc->config.gmch_pfit.lvds_border_bits;
 	/* Set the B0-B3 data pairs corresponding to whether we're going to
 	 * set the DPLLs for dual-channel mode or not.
 	 */
@@ -136,7 +167,10 @@ static void intel_pre_pll_enable_lvds(st
 	 * special lvds dither control bit on pch-split platforms, dithering is
 	 * only controlled through the PIPECONF reg. */
 	if (INTEL_INFO(dev)->gen == 4) {
-		if (dev_priv->lvds_dither)
+		/* Bspec wording suggests that LVDS port dithering only exists
+		 * for 18bpp panels. */
+		if (intel_crtc->config.dither &&
+		    intel_crtc->config.pipe_bpp == 18)
 			temp |= LVDS_ENABLE_DITHER;
 		else
 			temp &= ~LVDS_ENABLE_DITHER;
@@ -150,29 +184,6 @@ static void intel_pre_pll_enable_lvds(st
 	I915_WRITE(lvds_encoder->reg, temp);
 }
 
-static void intel_pre_enable_lvds(struct intel_encoder *encoder)
-{
-	struct drm_device *dev = encoder->base.dev;
-	struct intel_lvds_encoder *enc = to_lvds_encoder(&encoder->base);
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (HAS_PCH_SPLIT(dev) || !enc->pfit_control)
-		return;
-
-	/*
-	 * Enable automatic panel scaling so that non-native modes
-	 * fill the screen.  The panel fitter should only be
-	 * adjusted whilst the pipe is disabled, according to
-	 * register description and PRM.
-	 */
-	DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
-		      enc->pfit_control,
-		      enc->pfit_pgm_ratios);
-
-	I915_WRITE(PFIT_PGM_RATIOS, enc->pfit_pgm_ratios);
-	I915_WRITE(PFIT_CONTROL, enc->pfit_control);
-}
-
 /**
  * Sets the power state for the panel.
  */
@@ -241,62 +252,6 @@ static int intel_lvds_mode_valid(struct
 	return MODE_OK;
 }
 
-static void
-centre_horizontally(struct drm_display_mode *mode,
-		    int width)
-{
-	u32 border, sync_pos, blank_width, sync_width;
-
-	/* keep the hsync and hblank widths constant */
-	sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start;
-	blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start;
-	sync_pos = (blank_width - sync_width + 1) / 2;
-
-	border = (mode->hdisplay - width + 1) / 2;
-	border += border & 1; /* make the border even */
-
-	mode->crtc_hdisplay = width;
-	mode->crtc_hblank_start = width + border;
-	mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width;
-
-	mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
-	mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
-}
-
-static void
-centre_vertically(struct drm_display_mode *mode,
-		  int height)
-{
-	u32 border, sync_pos, blank_width, sync_width;
-
-	/* keep the vsync and vblank widths constant */
-	sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start;
-	blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start;
-	sync_pos = (blank_width - sync_width + 1) / 2;
-
-	border = (mode->vdisplay - height + 1) / 2;
-
-	mode->crtc_vdisplay = height;
-	mode->crtc_vblank_start = height + border;
-	mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width;
-
-	mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
-	mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
-}
-
-static inline u32 panel_fitter_scaling(u32 source, u32 target)
-{
-	/*
-	 * Floating point operation is not supported. So the FACTOR
-	 * is defined, which can avoid the floating point computation
-	 * when calculating the panel ratio.
-	 */
-#define ACCURACY 12
-#define FACTOR (1 << ACCURACY)
-	u32 ratio = source * FACTOR / target;
-	return (FACTOR * ratio + FACTOR/2) / FACTOR;
-}
-
 static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 				      struct intel_crtc_config *pipe_config)
 {
@@ -307,11 +262,8 @@ static bool intel_lvds_compute_config(st
 	struct intel_connector *intel_connector =
 		&lvds_encoder->attached_connector->base;
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
-	struct drm_display_mode *mode = &pipe_config->requested_mode;
 	struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
-	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
 	unsigned int lvds_bpp;
-	int pipe;
 
 	/* Should never happen!! */
 	if (INTEL_INFO(dev)->gen < 4 && intel_crtc->pipe == 0) {
@@ -319,20 +271,18 @@ static bool intel_lvds_compute_config(st
 		return false;
 	}
 
-	if (intel_encoder_check_is_cloned(&lvds_encoder->base))
-		return false;
-
 	if ((I915_READ(lvds_encoder->reg) & LVDS_A3_POWER_MASK) ==
 	    LVDS_A3_POWER_UP)
 		lvds_bpp = 8*3;
 	else
 		lvds_bpp = 6*3;
 
-	if (lvds_bpp != pipe_config->pipe_bpp) {
+	if (lvds_bpp != pipe_config->pipe_bpp && !pipe_config->bw_constrained) {
 		DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
 			      pipe_config->pipe_bpp, lvds_bpp);
 		pipe_config->pipe_bpp = lvds_bpp;
 	}
+
 	/*
 	 * We have timings from the BIOS for the panel, put them in
 	 * to the adjusted mode.  The CRTC will be set up for this mode,
@@ -345,138 +295,13 @@ static bool intel_lvds_compute_config(st
 	if (HAS_PCH_SPLIT(dev)) {
 		pipe_config->has_pch_encoder = true;
 
-		intel_pch_panel_fitting(dev,
-					intel_connector->panel.fitting_mode,
-					mode, adjusted_mode);
-		return true;
-	}
-
-	/* Native modes don't need fitting */
-	if (adjusted_mode->hdisplay == mode->hdisplay &&
-	    adjusted_mode->vdisplay == mode->vdisplay)
-		goto out;
-
-	/* 965+ wants fuzzy fitting */
-	if (INTEL_INFO(dev)->gen >= 4)
-		pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
-				 PFIT_FILTER_FUZZY);
-
-	/*
-	 * Enable automatic panel scaling for non-native modes so that they fill
-	 * the screen.  Should be enabled before the pipe is enabled, according
-	 * to register description and PRM.
-	 * Change the value here to see the borders for debugging
-	 */
-	for_each_pipe(pipe)
-		I915_WRITE(BCLRPAT(pipe), 0);
-
-	drm_mode_set_crtcinfo(adjusted_mode, 0);
-	pipe_config->timings_set = true;
-
-	switch (intel_connector->panel.fitting_mode) {
-	case DRM_MODE_SCALE_CENTER:
-		/*
-		 * For centered modes, we have to calculate border widths &
-		 * heights and modify the values programmed into the CRTC.
-		 */
-		centre_horizontally(adjusted_mode, mode->hdisplay);
-		centre_vertically(adjusted_mode, mode->vdisplay);
-		border = LVDS_BORDER_ENABLE;
-		break;
-
-	case DRM_MODE_SCALE_ASPECT:
-		/* Scale but preserve the aspect ratio */
-		if (INTEL_INFO(dev)->gen >= 4) {
-			u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
-			u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
-
-			/* 965+ is easy, it does everything in hw */
-			if (scaled_width > scaled_height)
-				pfit_control |= PFIT_ENABLE | PFIT_SCALING_PILLAR;
-			else if (scaled_width < scaled_height)
-				pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER;
-			else if (adjusted_mode->hdisplay != mode->hdisplay)
-				pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
-		} else {
-			u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay;
-			u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay;
-			/*
-			 * For earlier chips we have to calculate the scaling
-			 * ratio by hand and program it into the
-			 * PFIT_PGM_RATIO register
-			 */
-			if (scaled_width > scaled_height) { /* pillar */
-				centre_horizontally(adjusted_mode, scaled_height / mode->vdisplay);
-
-				border = LVDS_BORDER_ENABLE;
-				if (mode->vdisplay != adjusted_mode->vdisplay) {
-					u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay);
-					pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
-							    bits << PFIT_VERT_SCALE_SHIFT);
-					pfit_control |= (PFIT_ENABLE |
-							 VERT_INTERP_BILINEAR |
-							 HORIZ_INTERP_BILINEAR);
-				}
-			} else if (scaled_width < scaled_height) { /* letter */
-				centre_vertically(adjusted_mode, scaled_width / mode->hdisplay);
-
-				border = LVDS_BORDER_ENABLE;
-				if (mode->hdisplay != adjusted_mode->hdisplay) {
-					u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay);
-					pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
-							    bits << PFIT_VERT_SCALE_SHIFT);
-					pfit_control |= (PFIT_ENABLE |
-							 VERT_INTERP_BILINEAR |
-							 HORIZ_INTERP_BILINEAR);
-				}
-			} else
-				/* Aspects match, Let hw scale both directions */
-				pfit_control |= (PFIT_ENABLE |
-						 VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
-						 VERT_INTERP_BILINEAR |
-						 HORIZ_INTERP_BILINEAR);
-		}
-		break;
-
-	case DRM_MODE_SCALE_FULLSCREEN:
-		/*
-		 * Full scaling, even if it changes the aspect ratio.
-		 * Fortunately this is all done for us in hw.
-		 */
-		if (mode->vdisplay != adjusted_mode->vdisplay ||
-		    mode->hdisplay != adjusted_mode->hdisplay) {
-			pfit_control |= PFIT_ENABLE;
-			if (INTEL_INFO(dev)->gen >= 4)
-				pfit_control |= PFIT_SCALING_AUTO;
-			else
-				pfit_control |= (VERT_AUTO_SCALE |
-						 VERT_INTERP_BILINEAR |
-						 HORIZ_AUTO_SCALE |
-						 HORIZ_INTERP_BILINEAR);
-		}
-		break;
-
-	default:
-		break;
-	}
-
-out:
-	/* If not enabling scaling, be consistent and always use 0. */
-	if ((pfit_control & PFIT_ENABLE) == 0) {
-		pfit_control = 0;
-		pfit_pgm_ratios = 0;
-	}
-
-	/* Make sure pre-965 set dither correctly */
-	if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither)
-		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+		intel_pch_panel_fitting(intel_crtc, pipe_config,
+					intel_connector->panel.fitting_mode);
+	} else {
+		intel_gmch_panel_fitting(intel_crtc, pipe_config,
+					 intel_connector->panel.fitting_mode);
 
-	if (pfit_control != lvds_encoder->pfit_control ||
-	    pfit_pgm_ratios != lvds_encoder->pfit_pgm_ratios) {
-		lvds_encoder->pfit_control = pfit_control;
-		lvds_encoder->pfit_pgm_ratios = pfit_pgm_ratios;
 	}
-	dev_priv->lvds_border_bits = border;
 
 	/*
 	 * XXX: It would be nice to support lower refresh rates on the
@@ -869,6 +694,22 @@ static const struct dmi_system_id intel_
 			DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"),
 		},
 	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Intel D510MO",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D510MO"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Intel D525MW",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
+		},
+	},
 
 	{ }	/* terminating entry */
 };
@@ -937,11 +778,11 @@ static bool lvds_is_present_in_vbt(struc
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int i;
 
-	if (!dev_priv->child_dev_num)
+	if (!dev_priv->vbt.child_dev_num)
 		return true;
 
-	for (i = 0; i < dev_priv->child_dev_num; i++) {
-		struct child_device_config *child = dev_priv->child_dev + i;
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		struct child_device_config *child = dev_priv->vbt.child_dev + i;
 
 		/* If the device type is not LFP, continue.
 		 * We have to check both the new identifiers as well as the
@@ -1029,7 +870,7 @@ static bool compute_is_dual_link_lvds(st
 	 */
 	val = I915_READ(lvds_encoder->reg);
 	if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED)))
-		val = dev_priv->bios_lvds_val;
+		val = dev_priv->vbt.bios_lvds_val;
 
 	return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
 }
@@ -1056,7 +897,7 @@ static bool intel_lvds_supported(struct
  * Create the connector, register the LVDS DDC bus, and try to figure out what
  * modes we can display on the LVDS panel (if present).
  */
-bool intel_lvds_init(struct drm_device *dev)
+void intel_lvds_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_lvds_encoder *lvds_encoder;
@@ -1074,43 +915,39 @@ bool intel_lvds_init(struct drm_device *
 	u8 pin;
 
 	if (!intel_lvds_supported(dev))
-		return false;
+		return;
 
 	/* Skip init on machines we know falsely report LVDS */
 	if (dmi_check_system(intel_no_lvds))
-		return false;
+		return;
 
 	pin = GMBUS_PORT_PANEL;
 	if (!lvds_is_present_in_vbt(dev, &pin)) {
 		DRM_DEBUG_KMS("LVDS is not present in VBT\n");
-		return false;
+		return;
 	}
 
 	if (HAS_PCH_SPLIT(dev)) {
 		if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0)
-			return false;
-		if (dev_priv->edp.support) {
+			return;
+		if (dev_priv->vbt.edp_support) {
 			DRM_DEBUG_KMS("disable LVDS for eDP support\n");
-			return false;
+			return;
 		}
 	}
 
 	lvds_encoder = kzalloc(sizeof(struct intel_lvds_encoder), GFP_KERNEL);
 	if (!lvds_encoder)
-		return false;
+		return;
 
 	lvds_connector = kzalloc(sizeof(struct intel_lvds_connector), GFP_KERNEL);
 	if (!lvds_connector) {
 		kfree(lvds_encoder);
-		return false;
+		return;
 	}
 
 	lvds_encoder->attached_connector = lvds_connector;
 
-	if (!HAS_PCH_SPLIT(dev)) {
-		lvds_encoder->pfit_control = I915_READ(PFIT_CONTROL);
-	}
-
 	intel_encoder = &lvds_encoder->base;
 	encoder = &intel_encoder->base;
 	intel_connector = &lvds_connector->base;
@@ -1122,11 +959,11 @@ bool intel_lvds_init(struct drm_device *
 			 DRM_MODE_ENCODER_LVDS);
 
 	intel_encoder->enable = intel_enable_lvds;
-	intel_encoder->pre_enable = intel_pre_enable_lvds;
 	intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
 	intel_encoder->compute_config = intel_lvds_compute_config;
 	intel_encoder->disable = intel_disable_lvds;
 	intel_encoder->get_hw_state = intel_lvds_get_hw_state;
+	intel_encoder->get_config = intel_lvds_get_config;
 	intel_connector->get_hw_state = intel_connector_get_hw_state;
 
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
@@ -1212,11 +1049,11 @@ bool intel_lvds_init(struct drm_device *
 	}
 
 	/* Failed to get EDID, what about VBT? */
-	if (dev_priv->lfp_lvds_vbt_mode) {
+	if (dev_priv->vbt.lfp_lvds_vbt_mode) {
 		DRM_DEBUG_KMS("using mode from VBT: ");
-		drm_mode_debug_printmodeline(dev_priv->lfp_lvds_vbt_mode);
+		drm_mode_debug_printmodeline(dev_priv->vbt.lfp_lvds_vbt_mode);
 
-		fixed_mode = drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
+		fixed_mode = drm_mode_duplicate(dev, dev_priv->vbt.lfp_lvds_vbt_mode);
 		if (fixed_mode) {
 			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
 			goto out;
@@ -1277,7 +1114,7 @@ out:
 	intel_panel_init(&intel_connector->panel, fixed_mode);
 	intel_panel_setup_backlight(connector);
 
-	return true;
+	return;
 
 failed:
 	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
@@ -1287,5 +1124,5 @@ failed:
 		drm_mode_destroy(dev, fixed_mode);
 	kfree(lvds_encoder);
 	kfree(lvds_connector);
-	return false;
+	return;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_opregion.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_opregion.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_opregion.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_opregion.c	2013-08-25 20:43:22.000000000 -0400
@@ -110,6 +110,10 @@ struct opregion_asle {
 	u8 rsvd[102];
 } __attribute__((packed));
 
+/* Driver readiness indicator */
+#define ASLE_ARDY_READY		(1 << 0)
+#define ASLE_ARDY_NOT_READY	(0 << 0)
+
 /* ASLE irq request bits */
 #define ASLE_SET_ALS_ILLUM     (1 << 0)
 #define ASLE_SET_BACKLIGHT     (1 << 1)
@@ -123,6 +127,12 @@ struct opregion_asle {
 #define ASLE_PFIT_FAILED	(1<<14)
 #define ASLE_PWM_FREQ_FAILED	(1<<16)
 
+/* Technology enabled indicator */
+#define ASLE_TCHE_ALS_EN	(1 << 0)
+#define ASLE_TCHE_BLC_EN	(1 << 1)
+#define ASLE_TCHE_PFIT_EN	(1 << 2)
+#define ASLE_TCHE_PFMB_EN	(1 << 3)
+
 /* ASLE backlight brightness to set */
 #define ASLE_BCLP_VALID                (1<<31)
 #define ASLE_BCLP_MSK          (~(1<<31))
@@ -152,7 +162,6 @@ static u32 asle_set_backlight(struct drm
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
-	u32 max;
 
 	DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
 
@@ -163,8 +172,7 @@ static u32 asle_set_backlight(struct drm
 	if (bclp > 255)
 		return ASLE_BACKLIGHT_FAILED;
 
-	max = intel_panel_get_max_backlight(dev);
-	intel_panel_set_backlight(dev, bclp * max / 255);
+	intel_panel_set_backlight(dev, bclp, 255);
 	iowrite32((bclp*0x64)/0xff | ASLE_CBLV_VALID, &asle->cblv);
 
 	return 0;
@@ -174,29 +182,22 @@ static u32 asle_set_als_illum(struct drm
 {
 	/* alsi is the current ALS reading in lux. 0 indicates below sensor
 	   range, 0xffff indicates above sensor range. 1-0xfffe are valid */
-	return 0;
+	DRM_DEBUG_DRIVER("Illum is not supported\n");
+	return ASLE_ALS_ILLUM_FAILED;
 }
 
 static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	if (pfmb & ASLE_PFMB_PWM_VALID) {
-		u32 blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
-		u32 pwm = pfmb & ASLE_PFMB_PWM_MASK;
-		blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK;
-		pwm = pwm >> 9;
-		/* FIXME - what do we do with the PWM? */
-	}
-	return 0;
+	DRM_DEBUG_DRIVER("PWM freq is not supported\n");
+	return ASLE_PWM_FREQ_FAILED;
 }
 
 static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
 {
 	/* Panel fitting is currently controlled by the X code, so this is a
 	   noop until modesetting support works fully */
-	if (!(pfit & ASLE_PFIT_VALID))
-		return ASLE_PFIT_FAILED;
-	return 0;
+	DRM_DEBUG_DRIVER("Pfit is not supported\n");
+	return ASLE_PFIT_FAILED;
 }
 
 void intel_opregion_asle_intr(struct drm_device *dev)
@@ -231,64 +232,6 @@ void intel_opregion_asle_intr(struct drm
 	iowrite32(asle_stat, &asle->aslc);
 }
 
-void intel_opregion_gse_intr(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
-	u32 asle_stat = 0;
-	u32 asle_req;
-
-	if (!asle)
-		return;
-
-	asle_req = ioread32(&asle->aslc) & ASLE_REQ_MSK;
-
-	if (!asle_req) {
-		DRM_DEBUG_DRIVER("non asle set request??\n");
-		return;
-	}
-
-	if (asle_req & ASLE_SET_ALS_ILLUM) {
-		DRM_DEBUG_DRIVER("Illum is not supported\n");
-		asle_stat |= ASLE_ALS_ILLUM_FAILED;
-	}
-
-	if (asle_req & ASLE_SET_BACKLIGHT)
-		asle_stat |= asle_set_backlight(dev, ioread32(&asle->bclp));
-
-	if (asle_req & ASLE_SET_PFIT) {
-		DRM_DEBUG_DRIVER("Pfit is not supported\n");
-		asle_stat |= ASLE_PFIT_FAILED;
-	}
-
-	if (asle_req & ASLE_SET_PWM_FREQ) {
-		DRM_DEBUG_DRIVER("PWM freq is not supported\n");
-		asle_stat |= ASLE_PWM_FREQ_FAILED;
-	}
-
-	iowrite32(asle_stat, &asle->aslc);
-}
-#define ASLE_ALS_EN    (1<<0)
-#define ASLE_BLC_EN    (1<<1)
-#define ASLE_PFIT_EN   (1<<2)
-#define ASLE_PFMB_EN   (1<<3)
-
-void intel_opregion_enable_asle(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
-
-	if (asle) {
-		if (IS_MOBILE(dev))
-			intel_enable_asle(dev);
-
-		iowrite32(ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
-			  ASLE_PFMB_EN,
-			  &asle->tche);
-		iowrite32(1, &asle->ardy);
-	}
-}
-
 #define ACPI_EV_DISPLAY_SWITCH (1<<0)
 #define ACPI_EV_LID            (1<<1)
 #define ACPI_EV_DOCK           (1<<2)
@@ -368,8 +311,8 @@ static void intel_didl_outputs(struct dr
 
 	list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
 		if (i >= 8) {
-			dev_printk(KERN_ERR, &dev->pdev->dev,
-				    "More than 8 outputs detected\n");
+			dev_dbg(&dev->pdev->dev,
+				"More than 8 outputs detected via ACPI\n");
 			return;
 		}
 		status =
@@ -395,8 +338,8 @@ blind_set:
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		int output_type = ACPI_OTHER_OUTPUT;
 		if (i >= 8) {
-			dev_printk(KERN_ERR, &dev->pdev->dev,
-				    "More than 8 outputs detected\n");
+			dev_dbg(&dev->pdev->dev,
+				"More than 8 outputs in connector list\n");
 			return;
 		}
 		switch (connector->connector_type) {
@@ -472,8 +415,10 @@ void intel_opregion_init(struct drm_devi
 		register_acpi_notifier(&intel_opregion_notifier);
 	}
 
-	if (opregion->asle)
-		intel_opregion_enable_asle(dev);
+	if (opregion->asle) {
+		iowrite32(ASLE_TCHE_BLC_EN, &opregion->asle->tche);
+		iowrite32(ASLE_ARDY_READY, &opregion->asle->ardy);
+	}
 }
 
 void intel_opregion_fini(struct drm_device *dev)
@@ -484,6 +429,9 @@ void intel_opregion_fini(struct drm_devi
 	if (!opregion->header)
 		return;
 
+	if (opregion->asle)
+		iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy);
+
 	if (opregion->acpi) {
 		iowrite32(0, &opregion->acpi->drdy);
 
@@ -546,6 +494,8 @@ int intel_opregion_setup(struct drm_devi
 	if (mboxes & MBOX_ASLE) {
 		DRM_DEBUG_DRIVER("ASLE supported\n");
 		opregion->asle = base + OPREGION_ASLE_OFFSET;
+
+		iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy);
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_overlay.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_overlay.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_overlay.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_overlay.c	2013-08-25 20:43:22.000000000 -0400
@@ -217,7 +217,7 @@ static int intel_overlay_do_wait_request
 	int ret;
 
 	BUG_ON(overlay->last_flip_req);
-	ret = i915_add_request(ring, NULL, &overlay->last_flip_req);
+	ret = i915_add_request(ring, &overlay->last_flip_req);
 	if (ret)
 		return ret;
 
@@ -286,7 +286,7 @@ static int intel_overlay_continue(struct
 	intel_ring_emit(ring, flip_addr);
 	intel_ring_advance(ring);
 
-	return i915_add_request(ring, NULL, &overlay->last_flip_req);
+	return i915_add_request(ring, &overlay->last_flip_req);
 }
 
 static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
@@ -1485,14 +1485,15 @@ err:
 }
 
 void
-intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
+intel_overlay_print_error_state(struct drm_i915_error_state_buf *m,
+				struct intel_overlay_error_state *error)
 {
-	seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
-		   error->dovsta, error->isr);
-	seq_printf(m, "  Register file at 0x%08lx:\n",
-		   error->base);
+	i915_error_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
+			  error->dovsta, error->isr);
+	i915_error_printf(m, "  Register file at 0x%08lx:\n",
+			  error->base);
 
-#define P(x) seq_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
+#define P(x) i915_error_printf(m, "    " #x ":	0x%08x\n", error->regs.x)
 	P(OBUF_0Y);
 	P(OBUF_1Y);
 	P(OBUF_0U);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_panel.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_panel.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_panel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_panel.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,14 +54,16 @@ intel_fixed_panel_mode(struct drm_displa
 
 /* adjusted_mode has been preset to be the panel's fixed mode */
 void
-intel_pch_panel_fitting(struct drm_device *dev,
-			int fitting_mode,
-			const struct drm_display_mode *mode,
-			struct drm_display_mode *adjusted_mode)
+intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
+			struct intel_crtc_config *pipe_config,
+			int fitting_mode)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *mode, *adjusted_mode;
 	int x, y, width, height;
 
+	mode = &pipe_config->requested_mode;
+	adjusted_mode = &pipe_config->adjusted_mode;
+
 	x = y = width = height = 0;
 
 	/* Native modes don't need fitting */
@@ -104,17 +106,212 @@ intel_pch_panel_fitting(struct drm_devic
 		}
 		break;
 
-	default:
 	case DRM_MODE_SCALE_FULLSCREEN:
 		x = y = 0;
 		width = adjusted_mode->hdisplay;
 		height = adjusted_mode->vdisplay;
 		break;
+
+	default:
+		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
+		return;
 	}
 
 done:
-	dev_priv->pch_pf_pos = (x << 16) | y;
-	dev_priv->pch_pf_size = (width << 16) | height;
+	pipe_config->pch_pfit.pos = (x << 16) | y;
+	pipe_config->pch_pfit.size = (width << 16) | height;
+}
+
+static void
+centre_horizontally(struct drm_display_mode *mode,
+		    int width)
+{
+	u32 border, sync_pos, blank_width, sync_width;
+
+	/* keep the hsync and hblank widths constant */
+	sync_width = mode->crtc_hsync_end - mode->crtc_hsync_start;
+	blank_width = mode->crtc_hblank_end - mode->crtc_hblank_start;
+	sync_pos = (blank_width - sync_width + 1) / 2;
+
+	border = (mode->hdisplay - width + 1) / 2;
+	border += border & 1; /* make the border even */
+
+	mode->crtc_hdisplay = width;
+	mode->crtc_hblank_start = width + border;
+	mode->crtc_hblank_end = mode->crtc_hblank_start + blank_width;
+
+	mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
+	mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
+}
+
+static void
+centre_vertically(struct drm_display_mode *mode,
+		  int height)
+{
+	u32 border, sync_pos, blank_width, sync_width;
+
+	/* keep the vsync and vblank widths constant */
+	sync_width = mode->crtc_vsync_end - mode->crtc_vsync_start;
+	blank_width = mode->crtc_vblank_end - mode->crtc_vblank_start;
+	sync_pos = (blank_width - sync_width + 1) / 2;
+
+	border = (mode->vdisplay - height + 1) / 2;
+
+	mode->crtc_vdisplay = height;
+	mode->crtc_vblank_start = height + border;
+	mode->crtc_vblank_end = mode->crtc_vblank_start + blank_width;
+
+	mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
+	mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
+}
+
+static inline u32 panel_fitter_scaling(u32 source, u32 target)
+{
+	/*
+	 * Floating point operation is not supported. So the FACTOR
+	 * is defined, which can avoid the floating point computation
+	 * when calculating the panel ratio.
+	 */
+#define ACCURACY 12
+#define FACTOR (1 << ACCURACY)
+	u32 ratio = source * FACTOR / target;
+	return (FACTOR * ratio + FACTOR/2) / FACTOR;
+}
+
+void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
+			      struct intel_crtc_config *pipe_config,
+			      int fitting_mode)
+{
+	struct drm_device *dev = intel_crtc->base.dev;
+	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
+	struct drm_display_mode *mode, *adjusted_mode;
+
+	mode = &pipe_config->requested_mode;
+	adjusted_mode = &pipe_config->adjusted_mode;
+
+	/* Native modes don't need fitting */
+	if (adjusted_mode->hdisplay == mode->hdisplay &&
+	    adjusted_mode->vdisplay == mode->vdisplay)
+		goto out;
+
+	drm_mode_set_crtcinfo(adjusted_mode, 0);
+	pipe_config->timings_set = true;
+
+	switch (fitting_mode) {
+	case DRM_MODE_SCALE_CENTER:
+		/*
+		 * For centered modes, we have to calculate border widths &
+		 * heights and modify the values programmed into the CRTC.
+		 */
+		centre_horizontally(adjusted_mode, mode->hdisplay);
+		centre_vertically(adjusted_mode, mode->vdisplay);
+		border = LVDS_BORDER_ENABLE;
+		break;
+	case DRM_MODE_SCALE_ASPECT:
+		/* Scale but preserve the aspect ratio */
+		if (INTEL_INFO(dev)->gen >= 4) {
+			u32 scaled_width = adjusted_mode->hdisplay *
+				mode->vdisplay;
+			u32 scaled_height = mode->hdisplay *
+				adjusted_mode->vdisplay;
+
+			/* 965+ is easy, it does everything in hw */
+			if (scaled_width > scaled_height)
+				pfit_control |= PFIT_ENABLE |
+					PFIT_SCALING_PILLAR;
+			else if (scaled_width < scaled_height)
+				pfit_control |= PFIT_ENABLE |
+					PFIT_SCALING_LETTER;
+			else if (adjusted_mode->hdisplay != mode->hdisplay)
+				pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO;
+		} else {
+			u32 scaled_width = adjusted_mode->hdisplay *
+				mode->vdisplay;
+			u32 scaled_height = mode->hdisplay *
+				adjusted_mode->vdisplay;
+			/*
+			 * For earlier chips we have to calculate the scaling
+			 * ratio by hand and program it into the
+			 * PFIT_PGM_RATIO register
+			 */
+			if (scaled_width > scaled_height) { /* pillar */
+				centre_horizontally(adjusted_mode,
+						    scaled_height /
+						    mode->vdisplay);
+
+				border = LVDS_BORDER_ENABLE;
+				if (mode->vdisplay != adjusted_mode->vdisplay) {
+					u32 bits = panel_fitter_scaling(mode->vdisplay, adjusted_mode->vdisplay);
+					pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
+							    bits << PFIT_VERT_SCALE_SHIFT);
+					pfit_control |= (PFIT_ENABLE |
+							 VERT_INTERP_BILINEAR |
+							 HORIZ_INTERP_BILINEAR);
+				}
+			} else if (scaled_width < scaled_height) { /* letter */
+				centre_vertically(adjusted_mode,
+						  scaled_width /
+						  mode->hdisplay);
+
+				border = LVDS_BORDER_ENABLE;
+				if (mode->hdisplay != adjusted_mode->hdisplay) {
+					u32 bits = panel_fitter_scaling(mode->hdisplay, adjusted_mode->hdisplay);
+					pfit_pgm_ratios |= (bits << PFIT_HORIZ_SCALE_SHIFT |
+							    bits << PFIT_VERT_SCALE_SHIFT);
+					pfit_control |= (PFIT_ENABLE |
+							 VERT_INTERP_BILINEAR |
+							 HORIZ_INTERP_BILINEAR);
+				}
+			} else {
+				/* Aspects match, Let hw scale both directions */
+				pfit_control |= (PFIT_ENABLE |
+						 VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
+						 VERT_INTERP_BILINEAR |
+						 HORIZ_INTERP_BILINEAR);
+			}
+		}
+		break;
+	case DRM_MODE_SCALE_FULLSCREEN:
+		/*
+		 * Full scaling, even if it changes the aspect ratio.
+		 * Fortunately this is all done for us in hw.
+		 */
+		if (mode->vdisplay != adjusted_mode->vdisplay ||
+		    mode->hdisplay != adjusted_mode->hdisplay) {
+			pfit_control |= PFIT_ENABLE;
+			if (INTEL_INFO(dev)->gen >= 4)
+				pfit_control |= PFIT_SCALING_AUTO;
+			else
+				pfit_control |= (VERT_AUTO_SCALE |
+						 VERT_INTERP_BILINEAR |
+						 HORIZ_AUTO_SCALE |
+						 HORIZ_INTERP_BILINEAR);
+		}
+		break;
+	default:
+		WARN(1, "bad panel fit mode: %d\n", fitting_mode);
+		return;
+	}
+
+	/* 965+ wants fuzzy fitting */
+	/* FIXME: handle multiple panels by failing gracefully */
+	if (INTEL_INFO(dev)->gen >= 4)
+		pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) |
+				 PFIT_FILTER_FUZZY);
+
+out:
+	if ((pfit_control & PFIT_ENABLE) == 0) {
+		pfit_control = 0;
+		pfit_pgm_ratios = 0;
+	}
+
+	/* Make sure pre-965 set dither correctly for 18bpp panels. */
+	if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18)
+		pfit_control |= PANEL_8TO6_DITHER_ENABLE;
+
+	pipe_config->gmch_pfit.control = pfit_control;
+	pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios;
+	pipe_config->gmch_pfit.lvds_border_bits = border;
 }
 
 static int is_backlight_combination_mode(struct drm_device *dev)
@@ -130,11 +327,16 @@ static int is_backlight_combination_mode
 	return 0;
 }
 
+/* XXX: query mode clock or hardware clock and program max PWM appropriately
+ * when it's 0.
+ */
 static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 val;
 
+	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight.lock));
+
 	/* Restore the CTL value if it lost, e.g. GPU reset */
 
 	if (HAS_PCH_SPLIT(dev_priv->dev)) {
@@ -164,7 +366,7 @@ static u32 i915_read_blc_pwm_ctl(struct
 	return val;
 }
 
-static u32 _intel_panel_get_max_backlight(struct drm_device *dev)
+static u32 intel_panel_get_max_backlight(struct drm_device *dev)
 {
 	u32 max;
 
@@ -182,23 +384,8 @@ static u32 _intel_panel_get_max_backligh
 			max *= 0xff;
 	}
 
-	return max;
-}
-
-u32 intel_panel_get_max_backlight(struct drm_device *dev)
-{
-	u32 max;
-
-	max = _intel_panel_get_max_backlight(dev);
-	if (max == 0) {
-		/* XXX add code here to query mode clock or hardware clock
-		 * and program max PWM appropriately.
-		 */
-		pr_warn_once("fixme: max PWM is zero\n");
-		return 1;
-	}
-
 	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
+
 	return max;
 }
 
@@ -217,8 +404,11 @@ static u32 intel_panel_compute_brightnes
 		return val;
 
 	if (i915_panel_invert_brightness > 0 ||
-	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS)
-		return intel_panel_get_max_backlight(dev) - val;
+	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
+		u32 max = intel_panel_get_max_backlight(dev);
+		if (max)
+			return max - val;
+	}
 
 	return val;
 }
@@ -227,6 +417,9 @@ static u32 intel_panel_get_backlight(str
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
 
 	if (HAS_PCH_SPLIT(dev)) {
 		val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
@@ -244,6 +437,9 @@ static u32 intel_panel_get_backlight(str
 	}
 
 	val = intel_panel_compute_brightness(dev, val);
+
+	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+
 	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
 	return val;
 }
@@ -270,6 +466,10 @@ static void intel_panel_actually_set_bac
 		u32 max = intel_panel_get_max_backlight(dev);
 		u8 lbpc;
 
+		/* we're screwed, but keep behaviour backwards compatible */
+		if (!max)
+			max = 1;
+
 		lbpc = level * 0xfe / max + 1;
 		level /= lbpc;
 		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
@@ -282,9 +482,26 @@ static void intel_panel_actually_set_bac
 	I915_WRITE(BLC_PWM_CTL, tmp | level);
 }
 
-void intel_panel_set_backlight(struct drm_device *dev, u32 level)
+/* set backlight brightness to level in range [0..max] */
+void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 freq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+
+	freq = intel_panel_get_max_backlight(dev);
+	if (!freq) {
+		/* we are screwed, bail out */
+		goto out;
+	}
+
+	/* scale to hardware, but be careful to not overflow */
+	if (freq < max)
+		level = level * freq / max;
+	else
+		level = freq / max * level;
 
 	dev_priv->backlight.level = level;
 	if (dev_priv->backlight.device)
@@ -292,11 +509,27 @@ void intel_panel_set_backlight(struct dr
 
 	if (dev_priv->backlight.enabled)
 		intel_panel_actually_set_backlight(dev, level);
+out:
+	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
 }
 
 void intel_panel_disable_backlight(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	/*
+	 * Do not disable backlight on the vgaswitcheroo path. When switching
+	 * away from i915, the other client may depend on i915 to handle the
+	 * backlight. This will leave the backlight on unnecessarily when
+	 * another client is not activated.
+	 */
+	if (dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) {
+		DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n");
+		return;
+	}
+
+	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
 
 	dev_priv->backlight.enabled = false;
 	intel_panel_actually_set_backlight(dev, 0);
@@ -314,12 +547,19 @@ void intel_panel_disable_backlight(struc
 			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
 		}
 	}
+
+	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
 }
 
 void intel_panel_enable_backlight(struct drm_device *dev,
 				  enum pipe pipe)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder =
+		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
 
 	if (dev_priv->backlight.level == 0) {
 		dev_priv->backlight.level = intel_panel_get_max_backlight(dev);
@@ -347,14 +587,18 @@ void intel_panel_enable_backlight(struct
 		else
 			tmp &= ~BLM_PIPE_SELECT;
 
-		tmp |= BLM_PIPE(pipe);
+		if (cpu_transcoder == TRANSCODER_EDP)
+			tmp |= BLM_TRANSCODER_EDP;
+		else
+			tmp |= BLM_PIPE(cpu_transcoder);
 		tmp &= ~BLM_PWM_ENABLE;
 
 		I915_WRITE(reg, tmp);
 		POSTING_READ(reg);
 		I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
 
-		if (HAS_PCH_SPLIT(dev)) {
+		if (HAS_PCH_SPLIT(dev) &&
+		    !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
 			tmp = I915_READ(BLC_PWM_PCH_CTL1);
 			tmp |= BLM_PCH_PWM_ENABLE;
 			tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
@@ -369,6 +613,8 @@ set_level:
 	 */
 	dev_priv->backlight.enabled = true;
 	intel_panel_actually_set_backlight(dev, dev_priv->backlight.level);
+
+	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
 }
 
 static void intel_panel_init_backlight(struct drm_device *dev)
@@ -405,7 +651,8 @@ intel_panel_detect(struct drm_device *de
 static int intel_panel_update_status(struct backlight_device *bd)
 {
 	struct drm_device *dev = bl_get_data(bd);
-	intel_panel_set_backlight(dev, bd->props.brightness);
+	intel_panel_set_backlight(dev, bd->props.brightness,
+				  bd->props.max_brightness);
 	return 0;
 }
 
@@ -425,6 +672,7 @@ int intel_panel_setup_backlight(struct d
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct backlight_properties props;
+	unsigned long flags;
 
 	intel_panel_init_backlight(dev);
 
@@ -434,7 +682,11 @@ int intel_panel_setup_backlight(struct d
 	memset(&props, 0, sizeof(props));
 	props.type = BACKLIGHT_RAW;
 	props.brightness = dev_priv->backlight.level;
-	props.max_brightness = _intel_panel_get_max_backlight(dev);
+
+	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+	props.max_brightness = intel_panel_get_max_backlight(dev);
+	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+
 	if (props.max_brightness == 0) {
 		DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
 		return -ENODEV;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_pm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_pm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -113,8 +113,8 @@ static void i8xx_enable_fbc(struct drm_c
 	fbc_ctl |= obj->fence_reg;
 	I915_WRITE(FBC_CONTROL, fbc_ctl);
 
-	DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %d, ",
-		      cfb_pitch, crtc->y, intel_crtc->plane);
+	DRM_DEBUG_KMS("enabled FBC, pitch %d, yoff %d, plane %c, ",
+		      cfb_pitch, crtc->y, plane_name(intel_crtc->plane));
 }
 
 static bool i8xx_fbc_enabled(struct drm_device *dev)
@@ -148,7 +148,7 @@ static void g4x_enable_fbc(struct drm_cr
 	/* enable it... */
 	I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN);
 
-	DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
+	DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane));
 }
 
 static void g4x_disable_fbc(struct drm_device *dev)
@@ -228,7 +228,7 @@ static void ironlake_enable_fbc(struct d
 		sandybridge_blit_fbc_update(dev);
 	}
 
-	DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
+	DRM_DEBUG_KMS("enabled fbc on plane %c\n", plane_name(intel_crtc->plane));
 }
 
 static void ironlake_disable_fbc(struct drm_device *dev)
@@ -242,6 +242,18 @@ static void ironlake_disable_fbc(struct
 		dpfc_ctl &= ~DPFC_CTL_EN;
 		I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl);
 
+		if (IS_IVYBRIDGE(dev))
+			/* WaFbcDisableDpfcClockGating:ivb */
+			I915_WRITE(ILK_DSPCLK_GATE_D,
+				   I915_READ(ILK_DSPCLK_GATE_D) &
+				   ~ILK_DPFCUNIT_CLOCK_GATE_DISABLE);
+
+		if (IS_HASWELL(dev))
+			/* WaFbcDisableDpfcClockGating:hsw */
+			I915_WRITE(HSW_CLKGATE_DISABLE_PART_1,
+				   I915_READ(HSW_CLKGATE_DISABLE_PART_1) &
+				   ~HSW_DPFC_GATING_DISABLE);
+
 		DRM_DEBUG_KMS("disabled FBC\n");
 	}
 }
@@ -253,6 +265,47 @@ static bool ironlake_fbc_enabled(struct
 	return I915_READ(ILK_DPFC_CONTROL) & DPFC_CTL_EN;
 }
 
+static void gen7_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_framebuffer *fb = crtc->fb;
+	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+	struct drm_i915_gem_object *obj = intel_fb->obj;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	I915_WRITE(IVB_FBC_RT_BASE, obj->gtt_offset);
+
+	I915_WRITE(ILK_DPFC_CONTROL, DPFC_CTL_EN | DPFC_CTL_LIMIT_1X |
+		   IVB_DPFC_CTL_FENCE_EN |
+		   intel_crtc->plane << IVB_DPFC_CTL_PLANE_SHIFT);
+
+	if (IS_IVYBRIDGE(dev)) {
+		/* WaFbcAsynchFlipDisableFbcQueue:ivb */
+		I915_WRITE(ILK_DISPLAY_CHICKEN1, ILK_FBCQ_DIS);
+		/* WaFbcDisableDpfcClockGating:ivb */
+		I915_WRITE(ILK_DSPCLK_GATE_D,
+			   I915_READ(ILK_DSPCLK_GATE_D) |
+			   ILK_DPFCUNIT_CLOCK_GATE_DISABLE);
+	} else {
+		/* WaFbcAsynchFlipDisableFbcQueue:hsw */
+		I915_WRITE(HSW_PIPE_SLICE_CHICKEN_1(intel_crtc->pipe),
+			   HSW_BYPASS_FBC_QUEUE);
+		/* WaFbcDisableDpfcClockGating:hsw */
+		I915_WRITE(HSW_CLKGATE_DISABLE_PART_1,
+			   I915_READ(HSW_CLKGATE_DISABLE_PART_1) |
+			   HSW_DPFC_GATING_DISABLE);
+	}
+
+	I915_WRITE(SNB_DPFC_CTL_SA,
+		   SNB_CPU_FENCE_ENABLE | obj->fence_reg);
+	I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
+
+	sandybridge_blit_fbc_update(dev);
+
+	DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
+}
+
 bool intel_fbc_enabled(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -378,7 +431,7 @@ void intel_disable_fbc(struct drm_device
  *   - no pixel mulitply/line duplication
  *   - no alpha buffer discard
  *   - no dual wide
- *   - framebuffer <= 2048 in width, 1536 in height
+ *   - framebuffer <= max_hdisplay in width, max_vdisplay in height
  *
  * We can't assume that any compression will take place (worst case),
  * so the compressed buffer has to be the same size as the uncompressed
@@ -396,6 +449,7 @@ void intel_update_fbc(struct drm_device
 	struct intel_framebuffer *intel_fb;
 	struct drm_i915_gem_object *obj;
 	int enable_fbc;
+	unsigned int max_hdisplay, max_vdisplay;
 
 	if (!i915_powersave)
 		return;
@@ -439,7 +493,7 @@ void intel_update_fbc(struct drm_device
 	if (enable_fbc < 0) {
 		DRM_DEBUG_KMS("fbc set to per-chip default\n");
 		enable_fbc = 1;
-		if (INTEL_INFO(dev)->gen <= 6)
+		if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
 			enable_fbc = 0;
 	}
 	if (!enable_fbc) {
@@ -454,13 +508,22 @@ void intel_update_fbc(struct drm_device
 		dev_priv->no_fbc_reason = FBC_UNSUPPORTED_MODE;
 		goto out_disable;
 	}
-	if ((crtc->mode.hdisplay > 2048) ||
-	    (crtc->mode.vdisplay > 1536)) {
+
+	if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
+		max_hdisplay = 4096;
+		max_vdisplay = 2048;
+	} else {
+		max_hdisplay = 2048;
+		max_vdisplay = 1536;
+	}
+	if ((crtc->mode.hdisplay > max_hdisplay) ||
+	    (crtc->mode.vdisplay > max_vdisplay)) {
 		DRM_DEBUG_KMS("mode too large for compression, disabling\n");
 		dev_priv->no_fbc_reason = FBC_MODE_TOO_LARGE;
 		goto out_disable;
 	}
-	if ((IS_I915GM(dev) || IS_I945GM(dev)) && intel_crtc->plane != 0) {
+	if ((IS_I915GM(dev) || IS_I945GM(dev) || IS_HASWELL(dev)) &&
+	    intel_crtc->plane != 0) {
 		DRM_DEBUG_KMS("plane not 0, disabling compression\n");
 		dev_priv->no_fbc_reason = FBC_BAD_PLANE;
 		goto out_disable;
@@ -481,8 +544,6 @@ void intel_update_fbc(struct drm_device
 		goto out_disable;
 
 	if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size)) {
-		DRM_INFO("not enough stolen space for compressed buffer (need %zd bytes), disabling\n", intel_fb->obj->base.size);
-		DRM_INFO("hint: you may be able to increase stolen memory size in the BIOS to avoid this\n");
 		DRM_DEBUG_KMS("framebuffer too large, disabling compression\n");
 		dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL;
 		goto out_disable;
@@ -1633,6 +1694,10 @@ static bool ironlake_check_srwm(struct d
 		I915_WRITE(DISP_ARB_CTL,
 			   I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS);
 		return false;
+	} else if (INTEL_INFO(dev)->gen >= 6) {
+		/* enable FBC WM (except on ILK, where it must remain off) */
+		I915_WRITE(DISP_ARB_CTL,
+			   I915_READ(DISP_ARB_CTL) & ~DISP_FBC_WM_DIS);
 	}
 
 	if (display_wm > display->max_wm) {
@@ -2016,31 +2081,558 @@ static void ivybridge_update_wm(struct d
 		   cursor_wm);
 }
 
-static void
-haswell_update_linetime_wm(struct drm_device *dev, int pipe,
-				 struct drm_display_mode *mode)
+static uint32_t hsw_wm_get_pixel_rate(struct drm_device *dev,
+				      struct drm_crtc *crtc)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t pixel_rate, pfit_size;
+
+	pixel_rate = intel_crtc->config.adjusted_mode.clock;
+
+	/* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
+	 * adjust the pixel_rate here. */
+
+	pfit_size = intel_crtc->config.pch_pfit.size;
+	if (pfit_size) {
+		uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
+
+		pipe_w = intel_crtc->config.requested_mode.hdisplay;
+		pipe_h = intel_crtc->config.requested_mode.vdisplay;
+		pfit_w = (pfit_size >> 16) & 0xFFFF;
+		pfit_h = pfit_size & 0xFFFF;
+		if (pipe_w < pfit_w)
+			pipe_w = pfit_w;
+		if (pipe_h < pfit_h)
+			pipe_h = pfit_h;
+
+		pixel_rate = div_u64((uint64_t) pixel_rate * pipe_w * pipe_h,
+				     pfit_w * pfit_h);
+	}
+
+	return pixel_rate;
+}
+
+static uint32_t hsw_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel,
+			       uint32_t latency)
+{
+	uint64_t ret;
+
+	ret = (uint64_t) pixel_rate * bytes_per_pixel * latency;
+	ret = DIV_ROUND_UP_ULL(ret, 64 * 10000) + 2;
+
+	return ret;
+}
+
+static uint32_t hsw_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+			       uint32_t horiz_pixels, uint8_t bytes_per_pixel,
+			       uint32_t latency)
+{
+	uint32_t ret;
+
+	ret = (latency * pixel_rate) / (pipe_htotal * 10000);
+	ret = (ret + 1) * horiz_pixels * bytes_per_pixel;
+	ret = DIV_ROUND_UP(ret, 64) + 2;
+	return ret;
+}
+
+static uint32_t hsw_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
+			   uint8_t bytes_per_pixel)
+{
+	return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
+}
+
+struct hsw_pipe_wm_parameters {
+	bool active;
+	bool sprite_enabled;
+	uint8_t pri_bytes_per_pixel;
+	uint8_t spr_bytes_per_pixel;
+	uint8_t cur_bytes_per_pixel;
+	uint32_t pri_horiz_pixels;
+	uint32_t spr_horiz_pixels;
+	uint32_t cur_horiz_pixels;
+	uint32_t pipe_htotal;
+	uint32_t pixel_rate;
+};
+
+struct hsw_wm_maximums {
+	uint16_t pri;
+	uint16_t spr;
+	uint16_t cur;
+	uint16_t fbc;
+};
+
+struct hsw_lp_wm_result {
+	bool enable;
+	bool fbc_enable;
+	uint32_t pri_val;
+	uint32_t spr_val;
+	uint32_t cur_val;
+	uint32_t fbc_val;
+};
+
+struct hsw_wm_values {
+	uint32_t wm_pipe[3];
+	uint32_t wm_lp[3];
+	uint32_t wm_lp_spr[3];
+	uint32_t wm_linetime[3];
+	bool enable_fbc_wm;
+};
+
+enum hsw_data_buf_partitioning {
+	HSW_DATA_BUF_PART_1_2,
+	HSW_DATA_BUF_PART_5_6,
+};
+
+/* For both WM_PIPE and WM_LP. */
+static uint32_t hsw_compute_pri_wm(struct hsw_pipe_wm_parameters *params,
+				   uint32_t mem_value,
+				   bool is_lp)
+{
+	uint32_t method1, method2;
+
+	/* TODO: for now, assume the primary plane is always enabled. */
+	if (!params->active)
+		return 0;
+
+	method1 = hsw_wm_method1(params->pixel_rate,
+				 params->pri_bytes_per_pixel,
+				 mem_value);
+
+	if (!is_lp)
+		return method1;
+
+	method2 = hsw_wm_method2(params->pixel_rate,
+				 params->pipe_htotal,
+				 params->pri_horiz_pixels,
+				 params->pri_bytes_per_pixel,
+				 mem_value);
+
+	return min(method1, method2);
+}
+
+/* For both WM_PIPE and WM_LP. */
+static uint32_t hsw_compute_spr_wm(struct hsw_pipe_wm_parameters *params,
+				   uint32_t mem_value)
+{
+	uint32_t method1, method2;
+
+	if (!params->active || !params->sprite_enabled)
+		return 0;
+
+	method1 = hsw_wm_method1(params->pixel_rate,
+				 params->spr_bytes_per_pixel,
+				 mem_value);
+	method2 = hsw_wm_method2(params->pixel_rate,
+				 params->pipe_htotal,
+				 params->spr_horiz_pixels,
+				 params->spr_bytes_per_pixel,
+				 mem_value);
+	return min(method1, method2);
+}
+
+/* For both WM_PIPE and WM_LP. */
+static uint32_t hsw_compute_cur_wm(struct hsw_pipe_wm_parameters *params,
+				   uint32_t mem_value)
+{
+	if (!params->active)
+		return 0;
+
+	return hsw_wm_method2(params->pixel_rate,
+			      params->pipe_htotal,
+			      params->cur_horiz_pixels,
+			      params->cur_bytes_per_pixel,
+			      mem_value);
+}
+
+/* Only for WM_LP. */
+static uint32_t hsw_compute_fbc_wm(struct hsw_pipe_wm_parameters *params,
+				   uint32_t pri_val,
+				   uint32_t mem_value)
+{
+	if (!params->active)
+		return 0;
+
+	return hsw_wm_fbc(pri_val,
+			  params->pri_horiz_pixels,
+			  params->pri_bytes_per_pixel);
+}
+
+static bool hsw_compute_lp_wm(uint32_t mem_value, struct hsw_wm_maximums *max,
+			      struct hsw_pipe_wm_parameters *params,
+			      struct hsw_lp_wm_result *result)
+{
+	enum pipe pipe;
+	uint32_t pri_val[3], spr_val[3], cur_val[3], fbc_val[3];
+
+	for (pipe = PIPE_A; pipe <= PIPE_C; pipe++) {
+		struct hsw_pipe_wm_parameters *p = &params[pipe];
+
+		pri_val[pipe] = hsw_compute_pri_wm(p, mem_value, true);
+		spr_val[pipe] = hsw_compute_spr_wm(p, mem_value);
+		cur_val[pipe] = hsw_compute_cur_wm(p, mem_value);
+		fbc_val[pipe] = hsw_compute_fbc_wm(p, pri_val[pipe], mem_value);
+	}
+
+	result->pri_val = max3(pri_val[0], pri_val[1], pri_val[2]);
+	result->spr_val = max3(spr_val[0], spr_val[1], spr_val[2]);
+	result->cur_val = max3(cur_val[0], cur_val[1], cur_val[2]);
+	result->fbc_val = max3(fbc_val[0], fbc_val[1], fbc_val[2]);
+
+	if (result->fbc_val > max->fbc) {
+		result->fbc_enable = false;
+		result->fbc_val = 0;
+	} else {
+		result->fbc_enable = true;
+	}
+
+	result->enable = result->pri_val <= max->pri &&
+			 result->spr_val <= max->spr &&
+			 result->cur_val <= max->cur;
+	return result->enable;
+}
+
+static uint32_t hsw_compute_wm_pipe(struct drm_i915_private *dev_priv,
+				    uint32_t mem_value, enum pipe pipe,
+				    struct hsw_pipe_wm_parameters *params)
+{
+	uint32_t pri_val, cur_val, spr_val;
+
+	pri_val = hsw_compute_pri_wm(params, mem_value, false);
+	spr_val = hsw_compute_spr_wm(params, mem_value);
+	cur_val = hsw_compute_cur_wm(params, mem_value);
+
+	WARN(pri_val > 127,
+	     "Primary WM error, mode not supported for pipe %c\n",
+	     pipe_name(pipe));
+	WARN(spr_val > 127,
+	     "Sprite WM error, mode not supported for pipe %c\n",
+	     pipe_name(pipe));
+	WARN(cur_val > 63,
+	     "Cursor WM error, mode not supported for pipe %c\n",
+	     pipe_name(pipe));
+
+	return (pri_val << WM0_PIPE_PLANE_SHIFT) |
+	       (spr_val << WM0_PIPE_SPRITE_SHIFT) |
+	       cur_val;
+}
+
+static uint32_t
+hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 temp;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode;
+	u32 linetime, ips_linetime;
 
-	temp = I915_READ(PIPE_WM_LINETIME(pipe));
-	temp &= ~PIPE_WM_LINETIME_MASK;
+	if (!intel_crtc_active(crtc))
+		return 0;
 
 	/* The WM are computed with base on how long it takes to fill a single
 	 * row at the given clock rate, multiplied by 8.
 	 * */
-	temp |= PIPE_WM_LINETIME_TIME(
-		((mode->crtc_hdisplay * 1000) / mode->clock) * 8);
+	linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8, mode->clock);
+	ips_linetime = DIV_ROUND_CLOSEST(mode->htotal * 1000 * 8,
+					 intel_ddi_get_cdclk_freq(dev_priv));
 
-	/* IPS watermarks are only used by pipe A, and are ignored by
-	 * pipes B and C.  They are calculated similarly to the common
-	 * linetime values, except that we are using CD clock frequency
-	 * in MHz instead of pixel rate for the division.
-	 *
-	 * This is a placeholder for the IPS watermark calculation code.
-	 */
+	return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) |
+	       PIPE_WM_LINETIME_TIME(linetime);
+}
 
-	I915_WRITE(PIPE_WM_LINETIME(pipe), temp);
+static void hsw_compute_wm_parameters(struct drm_device *dev,
+				      struct hsw_pipe_wm_parameters *params,
+				      uint32_t *wm,
+				      struct hsw_wm_maximums *lp_max_1_2,
+				      struct hsw_wm_maximums *lp_max_5_6)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	struct drm_plane *plane;
+	uint64_t sskpd = I915_READ64(MCH_SSKPD);
+	enum pipe pipe;
+	int pipes_active = 0, sprites_enabled = 0;
+
+	if ((sskpd >> 56) & 0xFF)
+		wm[0] = (sskpd >> 56) & 0xFF;
+	else
+		wm[0] = sskpd & 0xF;
+	wm[1] = ((sskpd >> 4) & 0xFF) * 5;
+	wm[2] = ((sskpd >> 12) & 0xFF) * 5;
+	wm[3] = ((sskpd >> 20) & 0x1FF) * 5;
+	wm[4] = ((sskpd >> 32) & 0x1FF) * 5;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+		struct hsw_pipe_wm_parameters *p;
+
+		pipe = intel_crtc->pipe;
+		p = &params[pipe];
+
+		p->active = intel_crtc_active(crtc);
+		if (!p->active)
+			continue;
+
+		pipes_active++;
+
+		p->pipe_htotal = intel_crtc->config.adjusted_mode.htotal;
+		p->pixel_rate = hsw_wm_get_pixel_rate(dev, crtc);
+		p->pri_bytes_per_pixel = crtc->fb->bits_per_pixel / 8;
+		p->cur_bytes_per_pixel = 4;
+		p->pri_horiz_pixels =
+			intel_crtc->config.requested_mode.hdisplay;
+		p->cur_horiz_pixels = 64;
+	}
+
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		struct intel_plane *intel_plane = to_intel_plane(plane);
+		struct hsw_pipe_wm_parameters *p;
+
+		pipe = intel_plane->pipe;
+		p = &params[pipe];
+
+		p->sprite_enabled = intel_plane->wm.enable;
+		p->spr_bytes_per_pixel = intel_plane->wm.bytes_per_pixel;
+		p->spr_horiz_pixels = intel_plane->wm.horiz_pixels;
+
+		if (p->sprite_enabled)
+			sprites_enabled++;
+	}
+
+	if (pipes_active > 1) {
+		lp_max_1_2->pri = lp_max_5_6->pri = sprites_enabled ? 128 : 256;
+		lp_max_1_2->spr = lp_max_5_6->spr = 128;
+		lp_max_1_2->cur = lp_max_5_6->cur = 64;
+	} else {
+		lp_max_1_2->pri = sprites_enabled ? 384 : 768;
+		lp_max_5_6->pri = sprites_enabled ? 128 : 768;
+		lp_max_1_2->spr = 384;
+		lp_max_5_6->spr = 640;
+		lp_max_1_2->cur = lp_max_5_6->cur = 255;
+	}
+	lp_max_1_2->fbc = lp_max_5_6->fbc = 15;
+}
+
+static void hsw_compute_wm_results(struct drm_device *dev,
+				   struct hsw_pipe_wm_parameters *params,
+				   uint32_t *wm,
+				   struct hsw_wm_maximums *lp_maximums,
+				   struct hsw_wm_values *results)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	struct hsw_lp_wm_result lp_results[4] = {};
+	enum pipe pipe;
+	int level, max_level, wm_lp;
+
+	for (level = 1; level <= 4; level++)
+		if (!hsw_compute_lp_wm(wm[level], lp_maximums, params,
+				       &lp_results[level - 1]))
+			break;
+	max_level = level - 1;
+
+	/* The spec says it is preferred to disable FBC WMs instead of disabling
+	 * a WM level. */
+	results->enable_fbc_wm = true;
+	for (level = 1; level <= max_level; level++) {
+		if (!lp_results[level - 1].fbc_enable) {
+			results->enable_fbc_wm = false;
+			break;
+		}
+	}
+
+	memset(results, 0, sizeof(*results));
+	for (wm_lp = 1; wm_lp <= 3; wm_lp++) {
+		const struct hsw_lp_wm_result *r;
+
+		level = (max_level == 4 && wm_lp > 1) ? wm_lp + 1 : wm_lp;
+		if (level > max_level)
+			break;
+
+		r = &lp_results[level - 1];
+		results->wm_lp[wm_lp - 1] = HSW_WM_LP_VAL(level * 2,
+							  r->fbc_val,
+							  r->pri_val,
+							  r->cur_val);
+		results->wm_lp_spr[wm_lp - 1] = r->spr_val;
+	}
+
+	for_each_pipe(pipe)
+		results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev_priv, wm[0],
+							     pipe,
+							     &params[pipe]);
+
+	for_each_pipe(pipe) {
+		crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+		results->wm_linetime[pipe] = hsw_compute_linetime_wm(dev, crtc);
+	}
+}
+
+/* Find the result with the highest level enabled. Check for enable_fbc_wm in
+ * case both are at the same level. Prefer r1 in case they're the same. */
+struct hsw_wm_values *hsw_find_best_result(struct hsw_wm_values *r1,
+					   struct hsw_wm_values *r2)
+{
+	int i, val_r1 = 0, val_r2 = 0;
+
+	for (i = 0; i < 3; i++) {
+		if (r1->wm_lp[i] & WM3_LP_EN)
+			val_r1 = r1->wm_lp[i] & WM1_LP_LATENCY_MASK;
+		if (r2->wm_lp[i] & WM3_LP_EN)
+			val_r2 = r2->wm_lp[i] & WM1_LP_LATENCY_MASK;
+	}
+
+	if (val_r1 == val_r2) {
+		if (r2->enable_fbc_wm && !r1->enable_fbc_wm)
+			return r2;
+		else
+			return r1;
+	} else if (val_r1 > val_r2) {
+		return r1;
+	} else {
+		return r2;
+	}
+}
+
+/*
+ * The spec says we shouldn't write when we don't need, because every write
+ * causes WMs to be re-evaluated, expending some power.
+ */
+static void hsw_write_wm_values(struct drm_i915_private *dev_priv,
+				struct hsw_wm_values *results,
+				enum hsw_data_buf_partitioning partitioning)
+{
+	struct hsw_wm_values previous;
+	uint32_t val;
+	enum hsw_data_buf_partitioning prev_partitioning;
+	bool prev_enable_fbc_wm;
+
+	previous.wm_pipe[0] = I915_READ(WM0_PIPEA_ILK);
+	previous.wm_pipe[1] = I915_READ(WM0_PIPEB_ILK);
+	previous.wm_pipe[2] = I915_READ(WM0_PIPEC_IVB);
+	previous.wm_lp[0] = I915_READ(WM1_LP_ILK);
+	previous.wm_lp[1] = I915_READ(WM2_LP_ILK);
+	previous.wm_lp[2] = I915_READ(WM3_LP_ILK);
+	previous.wm_lp_spr[0] = I915_READ(WM1S_LP_ILK);
+	previous.wm_lp_spr[1] = I915_READ(WM2S_LP_IVB);
+	previous.wm_lp_spr[2] = I915_READ(WM3S_LP_IVB);
+	previous.wm_linetime[0] = I915_READ(PIPE_WM_LINETIME(PIPE_A));
+	previous.wm_linetime[1] = I915_READ(PIPE_WM_LINETIME(PIPE_B));
+	previous.wm_linetime[2] = I915_READ(PIPE_WM_LINETIME(PIPE_C));
+
+	prev_partitioning = (I915_READ(WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ?
+			    HSW_DATA_BUF_PART_5_6 : HSW_DATA_BUF_PART_1_2;
+
+	prev_enable_fbc_wm = !(I915_READ(DISP_ARB_CTL) & DISP_FBC_WM_DIS);
+
+	if (memcmp(results->wm_pipe, previous.wm_pipe,
+		   sizeof(results->wm_pipe)) == 0 &&
+	    memcmp(results->wm_lp, previous.wm_lp,
+		   sizeof(results->wm_lp)) == 0 &&
+	    memcmp(results->wm_lp_spr, previous.wm_lp_spr,
+		   sizeof(results->wm_lp_spr)) == 0 &&
+	    memcmp(results->wm_linetime, previous.wm_linetime,
+		   sizeof(results->wm_linetime)) == 0 &&
+	    partitioning == prev_partitioning &&
+	    results->enable_fbc_wm == prev_enable_fbc_wm)
+		return;
+
+	if (previous.wm_lp[2] != 0)
+		I915_WRITE(WM3_LP_ILK, 0);
+	if (previous.wm_lp[1] != 0)
+		I915_WRITE(WM2_LP_ILK, 0);
+	if (previous.wm_lp[0] != 0)
+		I915_WRITE(WM1_LP_ILK, 0);
+
+	if (previous.wm_pipe[0] != results->wm_pipe[0])
+		I915_WRITE(WM0_PIPEA_ILK, results->wm_pipe[0]);
+	if (previous.wm_pipe[1] != results->wm_pipe[1])
+		I915_WRITE(WM0_PIPEB_ILK, results->wm_pipe[1]);
+	if (previous.wm_pipe[2] != results->wm_pipe[2])
+		I915_WRITE(WM0_PIPEC_IVB, results->wm_pipe[2]);
+
+	if (previous.wm_linetime[0] != results->wm_linetime[0])
+		I915_WRITE(PIPE_WM_LINETIME(PIPE_A), results->wm_linetime[0]);
+	if (previous.wm_linetime[1] != results->wm_linetime[1])
+		I915_WRITE(PIPE_WM_LINETIME(PIPE_B), results->wm_linetime[1]);
+	if (previous.wm_linetime[2] != results->wm_linetime[2])
+		I915_WRITE(PIPE_WM_LINETIME(PIPE_C), results->wm_linetime[2]);
+
+	if (prev_partitioning != partitioning) {
+		val = I915_READ(WM_MISC);
+		if (partitioning == HSW_DATA_BUF_PART_1_2)
+			val &= ~WM_MISC_DATA_PARTITION_5_6;
+		else
+			val |= WM_MISC_DATA_PARTITION_5_6;
+		I915_WRITE(WM_MISC, val);
+	}
+
+	if (prev_enable_fbc_wm != results->enable_fbc_wm) {
+		val = I915_READ(DISP_ARB_CTL);
+		if (results->enable_fbc_wm)
+			val &= ~DISP_FBC_WM_DIS;
+		else
+			val |= DISP_FBC_WM_DIS;
+		I915_WRITE(DISP_ARB_CTL, val);
+	}
+
+	if (previous.wm_lp_spr[0] != results->wm_lp_spr[0])
+		I915_WRITE(WM1S_LP_ILK, results->wm_lp_spr[0]);
+	if (previous.wm_lp_spr[1] != results->wm_lp_spr[1])
+		I915_WRITE(WM2S_LP_IVB, results->wm_lp_spr[1]);
+	if (previous.wm_lp_spr[2] != results->wm_lp_spr[2])
+		I915_WRITE(WM3S_LP_IVB, results->wm_lp_spr[2]);
+
+	if (results->wm_lp[0] != 0)
+		I915_WRITE(WM1_LP_ILK, results->wm_lp[0]);
+	if (results->wm_lp[1] != 0)
+		I915_WRITE(WM2_LP_ILK, results->wm_lp[1]);
+	if (results->wm_lp[2] != 0)
+		I915_WRITE(WM3_LP_ILK, results->wm_lp[2]);
+}
+
+static void haswell_update_wm(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct hsw_wm_maximums lp_max_1_2, lp_max_5_6;
+	struct hsw_pipe_wm_parameters params[3];
+	struct hsw_wm_values results_1_2, results_5_6, *best_results;
+	uint32_t wm[5];
+	enum hsw_data_buf_partitioning partitioning;
+
+	hsw_compute_wm_parameters(dev, params, wm, &lp_max_1_2, &lp_max_5_6);
+
+	hsw_compute_wm_results(dev, params, wm, &lp_max_1_2, &results_1_2);
+	if (lp_max_1_2.pri != lp_max_5_6.pri) {
+		hsw_compute_wm_results(dev, params, wm, &lp_max_5_6,
+				       &results_5_6);
+		best_results = hsw_find_best_result(&results_1_2, &results_5_6);
+	} else {
+		best_results = &results_1_2;
+	}
+
+	partitioning = (best_results == &results_1_2) ?
+		       HSW_DATA_BUF_PART_1_2 : HSW_DATA_BUF_PART_5_6;
+
+	hsw_write_wm_values(dev_priv, best_results, partitioning);
+}
+
+static void haswell_update_sprite_wm(struct drm_device *dev, int pipe,
+				     uint32_t sprite_width, int pixel_size,
+				     bool enable)
+{
+	struct drm_plane *plane;
+
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		struct intel_plane *intel_plane = to_intel_plane(plane);
+
+		if (intel_plane->pipe == pipe) {
+			intel_plane->wm.enable = enable;
+			intel_plane->wm.horiz_pixels = sprite_width + 1;
+			intel_plane->wm.bytes_per_pixel = pixel_size;
+			break;
+		}
+	}
+
+	haswell_update_wm(dev);
 }
 
 static bool
@@ -2120,7 +2712,8 @@ sandybridge_compute_sprite_srwm(struct d
 }
 
 static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe,
-					 uint32_t sprite_width, int pixel_size)
+					 uint32_t sprite_width, int pixel_size,
+					 bool enable)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int latency = SNB_READ_WM0_LATENCY() * 100;	/* In unit 0.1us */
@@ -2128,6 +2721,9 @@ static void sandybridge_update_sprite_wm
 	int sprite_wm, reg;
 	int ret;
 
+	if (!enable)
+		return;
+
 	switch (pipe) {
 	case 0:
 		reg = WM0_PIPEA_ILK;
@@ -2146,15 +2742,15 @@ static void sandybridge_update_sprite_wm
 					    &sandybridge_display_wm_info,
 					    latency, &sprite_wm);
 	if (!ret) {
-		DRM_DEBUG_KMS("failed to compute sprite wm for pipe %d\n",
-			      pipe);
+		DRM_DEBUG_KMS("failed to compute sprite wm for pipe %c\n",
+			      pipe_name(pipe));
 		return;
 	}
 
 	val = I915_READ(reg);
 	val &= ~WM0_PIPE_SPRITE_MASK;
 	I915_WRITE(reg, val | (sprite_wm << WM0_PIPE_SPRITE_SHIFT));
-	DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm);
+	DRM_DEBUG_KMS("sprite watermarks For pipe %c - %d\n", pipe_name(pipe), sprite_wm);
 
 
 	ret = sandybridge_compute_sprite_srwm(dev, pipe, sprite_width,
@@ -2163,8 +2759,8 @@ static void sandybridge_update_sprite_wm
 					      SNB_READ_WM1_LATENCY() * 500,
 					      &sprite_wm);
 	if (!ret) {
-		DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %d\n",
-			      pipe);
+		DRM_DEBUG_KMS("failed to compute sprite lp1 wm on pipe %c\n",
+			      pipe_name(pipe));
 		return;
 	}
 	I915_WRITE(WM1S_LP_ILK, sprite_wm);
@@ -2179,8 +2775,8 @@ static void sandybridge_update_sprite_wm
 					      SNB_READ_WM2_LATENCY() * 500,
 					      &sprite_wm);
 	if (!ret) {
-		DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %d\n",
-			      pipe);
+		DRM_DEBUG_KMS("failed to compute sprite lp2 wm on pipe %c\n",
+			      pipe_name(pipe));
 		return;
 	}
 	I915_WRITE(WM2S_LP_IVB, sprite_wm);
@@ -2191,8 +2787,8 @@ static void sandybridge_update_sprite_wm
 					      SNB_READ_WM3_LATENCY() * 500,
 					      &sprite_wm);
 	if (!ret) {
-		DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %d\n",
-			      pipe);
+		DRM_DEBUG_KMS("failed to compute sprite lp3 wm on pipe %c\n",
+			      pipe_name(pipe));
 		return;
 	}
 	I915_WRITE(WM3S_LP_IVB, sprite_wm);
@@ -2238,23 +2834,15 @@ void intel_update_watermarks(struct drm_
 		dev_priv->display.update_wm(dev);
 }
 
-void intel_update_linetime_watermarks(struct drm_device *dev,
-		int pipe, struct drm_display_mode *mode)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (dev_priv->display.update_linetime_wm)
-		dev_priv->display.update_linetime_wm(dev, pipe, mode);
-}
-
 void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
-				    uint32_t sprite_width, int pixel_size)
+				    uint32_t sprite_width, int pixel_size,
+				    bool enable)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	if (dev_priv->display.update_sprite_wm)
 		dev_priv->display.update_sprite_wm(dev, pipe, sprite_width,
-						   pixel_size);
+						   pixel_size, enable);
 }
 
 static struct drm_i915_gem_object *
@@ -2481,6 +3069,67 @@ void gen6_set_rps(struct drm_device *dev
 	trace_intel_gpu_freq_change(val * 50);
 }
 
+/*
+ * Wait until the previous freq change has completed,
+ * or the timeout elapsed, and then update our notion
+ * of the current GPU frequency.
+ */
+static void vlv_update_rps_cur_delay(struct drm_i915_private *dev_priv)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(10);
+	u32 pval;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	do {
+		pval = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+		if (time_after(jiffies, timeout)) {
+			DRM_DEBUG_DRIVER("timed out waiting for Punit\n");
+			break;
+		}
+		udelay(10);
+	} while (pval & 1);
+
+	pval >>= 8;
+
+	if (pval != dev_priv->rps.cur_delay)
+		DRM_DEBUG_DRIVER("Punit overrode GPU freq: %d MHz (%u) requested, but got %d Mhz (%u)\n",
+				 vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.cur_delay),
+				 dev_priv->rps.cur_delay,
+				 vlv_gpu_freq(dev_priv->mem_freq, pval), pval);
+
+	dev_priv->rps.cur_delay = pval;
+}
+
+void valleyview_set_rps(struct drm_device *dev, u8 val)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	gen6_rps_limits(dev_priv, &val);
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	WARN_ON(val > dev_priv->rps.max_delay);
+	WARN_ON(val < dev_priv->rps.min_delay);
+
+	vlv_update_rps_cur_delay(dev_priv);
+
+	DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n",
+			 vlv_gpu_freq(dev_priv->mem_freq,
+				      dev_priv->rps.cur_delay),
+			 dev_priv->rps.cur_delay,
+			 vlv_gpu_freq(dev_priv->mem_freq, val), val);
+
+	if (val == dev_priv->rps.cur_delay)
+		return;
+
+	vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
+
+	dev_priv->rps.cur_delay = val;
+
+	trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv->mem_freq, val));
+}
+
+
 static void gen6_disable_rps(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2488,6 +3137,25 @@ static void gen6_disable_rps(struct drm_
 	I915_WRITE(GEN6_RC_CONTROL, 0);
 	I915_WRITE(GEN6_RPNSWREQ, 1 << 31);
 	I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
+	I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) & ~GEN6_PM_RPS_EVENTS);
+	/* Complete PM interrupt masking here doesn't race with the rps work
+	 * item again unmasking PM interrupts because that is using a different
+	 * register (PMIMR) to mask PM interrupts. The only risk is in leaving
+	 * stale bits in PMIIR and PMIMR which gen6_enable_rps will clean up. */
+
+	spin_lock_irq(&dev_priv->rps.lock);
+	dev_priv->rps.pm_iir = 0;
+	spin_unlock_irq(&dev_priv->rps.lock);
+
+	I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
+}
+
+static void valleyview_disable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(GEN6_RC_CONTROL, 0);
+	I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
 	I915_WRITE(GEN6_PMIER, 0);
 	/* Complete PM interrupt masking here doesn't race with the rps work
 	 * item again unmasking PM interrupts because that is using a different
@@ -2499,6 +3167,11 @@ static void gen6_disable_rps(struct drm_
 	spin_unlock_irq(&dev_priv->rps.lock);
 
 	I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR));
+
+	if (dev_priv->vlv_pctx) {
+		drm_gem_object_unreference(&dev_priv->vlv_pctx->base);
+		dev_priv->vlv_pctx = NULL;
+	}
 }
 
 int intel_enable_rc6(const struct drm_device *dev)
@@ -2655,12 +3328,15 @@ static void gen6_enable_rps(struct drm_d
 	gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8);
 
 	/* requires MSI enabled */
-	I915_WRITE(GEN6_PMIER, GEN6_PM_DEFERRED_EVENTS);
+	I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) | GEN6_PM_RPS_EVENTS);
 	spin_lock_irq(&dev_priv->rps.lock);
-	WARN_ON(dev_priv->rps.pm_iir != 0);
-	I915_WRITE(GEN6_PMIMR, 0);
+	/* FIXME: Our interrupt enabling sequence is bonghits.
+	 * dev_priv->rps.pm_iir really should be 0 here. */
+	dev_priv->rps.pm_iir = 0;
+	I915_WRITE(GEN6_PMIMR, I915_READ(GEN6_PMIMR) & ~GEN6_PM_RPS_EVENTS);
+	I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
 	spin_unlock_irq(&dev_priv->rps.lock);
-	/* enable all PM interrupts */
+	/* unmask all PM interrupts */
 	I915_WRITE(GEN6_PMINTRMSK, 0);
 
 	rc6vids = 0;
@@ -2742,6 +3418,207 @@ static void gen6_update_ring_freq(struct
 	}
 }
 
+int valleyview_rps_max_freq(struct drm_i915_private *dev_priv)
+{
+	u32 val, rp0;
+
+	val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE);
+
+	rp0 = (val & FB_GFX_MAX_FREQ_FUSE_MASK) >> FB_GFX_MAX_FREQ_FUSE_SHIFT;
+	/* Clamp to max */
+	rp0 = min_t(u32, rp0, 0xea);
+
+	return rp0;
+}
+
+static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv)
+{
+	u32 val, rpe;
+
+	val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_LO);
+	rpe = (val & FB_FMAX_VMIN_FREQ_LO_MASK) >> FB_FMAX_VMIN_FREQ_LO_SHIFT;
+	val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FMAX_FUSE_HI);
+	rpe |= (val & FB_FMAX_VMIN_FREQ_HI_MASK) << 5;
+
+	return rpe;
+}
+
+int valleyview_rps_min_freq(struct drm_i915_private *dev_priv)
+{
+	return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff;
+}
+
+static void vlv_rps_timer_work(struct work_struct *work)
+{
+	drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
+						    rps.vlv_work.work);
+
+	/*
+	 * Timer fired, we must be idle.  Drop to min voltage state.
+	 * Note: we use RPe here since it should match the
+	 * Vmin we were shooting for.  That should give us better
+	 * perf when we come back out of RC6 than if we used the
+	 * min freq available.
+	 */
+	mutex_lock(&dev_priv->rps.hw_lock);
+	if (dev_priv->rps.cur_delay > dev_priv->rps.rpe_delay)
+		valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
+	mutex_unlock(&dev_priv->rps.hw_lock);
+}
+
+static void valleyview_setup_pctx(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *pctx;
+	unsigned long pctx_paddr;
+	u32 pcbr;
+	int pctx_size = 24*1024;
+
+	pcbr = I915_READ(VLV_PCBR);
+	if (pcbr) {
+		/* BIOS set it up already, grab the pre-alloc'd space */
+		int pcbr_offset;
+
+		pcbr_offset = (pcbr & (~4095)) - dev_priv->mm.stolen_base;
+		pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv->dev,
+								      pcbr_offset,
+								      -1,
+								      pctx_size);
+		goto out;
+	}
+
+	/*
+	 * From the Gunit register HAS:
+	 * The Gfx driver is expected to program this register and ensure
+	 * proper allocation within Gfx stolen memory.  For example, this
+	 * register should be programmed such than the PCBR range does not
+	 * overlap with other ranges, such as the frame buffer, protected
+	 * memory, or any other relevant ranges.
+	 */
+	pctx = i915_gem_object_create_stolen(dev, pctx_size);
+	if (!pctx) {
+		DRM_DEBUG("not enough stolen space for PCTX, disabling\n");
+		return;
+	}
+
+	pctx_paddr = dev_priv->mm.stolen_base + pctx->stolen->start;
+	I915_WRITE(VLV_PCBR, pctx_paddr);
+
+out:
+	dev_priv->vlv_pctx = pctx;
+}
+
+static void valleyview_enable_rps(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_ring_buffer *ring;
+	u32 gtfifodbg, val;
+	int i;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	if ((gtfifodbg = I915_READ(GTFIFODBG))) {
+		DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg);
+		I915_WRITE(GTFIFODBG, gtfifodbg);
+	}
+
+	valleyview_setup_pctx(dev);
+
+	gen6_gt_force_wake_get(dev_priv);
+
+	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
+	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
+	I915_WRITE(GEN6_RP_UP_EI, 66000);
+	I915_WRITE(GEN6_RP_DOWN_EI, 350000);
+
+	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
+
+	I915_WRITE(GEN6_RP_CONTROL,
+		   GEN6_RP_MEDIA_TURBO |
+		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
+		   GEN6_RP_MEDIA_IS_GFX |
+		   GEN6_RP_ENABLE |
+		   GEN6_RP_UP_BUSY_AVG |
+		   GEN6_RP_DOWN_IDLE_CONT);
+
+	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000);
+	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
+	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25);
+
+	for_each_ring(ring, dev_priv, i)
+		I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
+
+	I915_WRITE(GEN6_RC6_THRESHOLD, 0xc350);
+
+	/* allows RC6 residency counter to work */
+	I915_WRITE(0x138104, _MASKED_BIT_ENABLE(0x3));
+	I915_WRITE(GEN6_RC_CONTROL,
+		   GEN7_RC_CTL_TO_MODE);
+
+	val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+	switch ((val >> 6) & 3) {
+	case 0:
+	case 1:
+		dev_priv->mem_freq = 800;
+		break;
+	case 2:
+		dev_priv->mem_freq = 1066;
+		break;
+	case 3:
+		dev_priv->mem_freq = 1333;
+		break;
+	}
+	DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq);
+
+	DRM_DEBUG_DRIVER("GPLL enabled? %s\n", val & 0x10 ? "yes" : "no");
+	DRM_DEBUG_DRIVER("GPU status: 0x%08x\n", val);
+
+	dev_priv->rps.cur_delay = (val >> 8) & 0xff;
+	DRM_DEBUG_DRIVER("current GPU freq: %d MHz (%u)\n",
+			 vlv_gpu_freq(dev_priv->mem_freq,
+				      dev_priv->rps.cur_delay),
+			 dev_priv->rps.cur_delay);
+
+	dev_priv->rps.max_delay = valleyview_rps_max_freq(dev_priv);
+	dev_priv->rps.hw_max = dev_priv->rps.max_delay;
+	DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
+			 vlv_gpu_freq(dev_priv->mem_freq,
+				      dev_priv->rps.max_delay),
+			 dev_priv->rps.max_delay);
+
+	dev_priv->rps.rpe_delay = valleyview_rps_rpe_freq(dev_priv);
+	DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
+			 vlv_gpu_freq(dev_priv->mem_freq,
+				      dev_priv->rps.rpe_delay),
+			 dev_priv->rps.rpe_delay);
+
+	dev_priv->rps.min_delay = valleyview_rps_min_freq(dev_priv);
+	DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
+			 vlv_gpu_freq(dev_priv->mem_freq,
+				      dev_priv->rps.min_delay),
+			 dev_priv->rps.min_delay);
+
+	DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
+			 vlv_gpu_freq(dev_priv->mem_freq,
+				      dev_priv->rps.rpe_delay),
+			 dev_priv->rps.rpe_delay);
+
+	INIT_DELAYED_WORK(&dev_priv->rps.vlv_work, vlv_rps_timer_work);
+
+	valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
+
+	/* requires MSI enabled */
+	I915_WRITE(GEN6_PMIER, GEN6_PM_RPS_EVENTS);
+	spin_lock_irq(&dev_priv->rps.lock);
+	WARN_ON(dev_priv->rps.pm_iir != 0);
+	I915_WRITE(GEN6_PMIMR, 0);
+	spin_unlock_irq(&dev_priv->rps.lock);
+	/* enable all PM interrupts */
+	I915_WRITE(GEN6_PMINTRMSK, 0);
+
+	gen6_gt_force_wake_put(dev_priv);
+}
+
 void ironlake_teardown_rc6(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3465,13 +4342,22 @@ void intel_disable_gt_powersave(struct d
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
+	/* Interrupts should be disabled already to avoid re-arming. */
+	WARN_ON(dev->irq_enabled);
+
 	if (IS_IRONLAKE_M(dev)) {
 		ironlake_disable_drps(dev);
 		ironlake_disable_rc6(dev);
-	} else if (INTEL_INFO(dev)->gen >= 6 && !IS_VALLEYVIEW(dev)) {
+	} else if (INTEL_INFO(dev)->gen >= 6) {
 		cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work);
+		cancel_work_sync(&dev_priv->rps.work);
+		if (IS_VALLEYVIEW(dev))
+			cancel_delayed_work_sync(&dev_priv->rps.vlv_work);
 		mutex_lock(&dev_priv->rps.hw_lock);
-		gen6_disable_rps(dev);
+		if (IS_VALLEYVIEW(dev))
+			valleyview_disable_rps(dev);
+		else
+			gen6_disable_rps(dev);
 		mutex_unlock(&dev_priv->rps.hw_lock);
 	}
 }
@@ -3484,8 +4370,13 @@ static void intel_gen6_powersave_work(st
 	struct drm_device *dev = dev_priv->dev;
 
 	mutex_lock(&dev_priv->rps.hw_lock);
-	gen6_enable_rps(dev);
-	gen6_update_ring_freq(dev);
+
+	if (IS_VALLEYVIEW(dev)) {
+		valleyview_enable_rps(dev);
+	} else {
+		gen6_enable_rps(dev);
+		gen6_update_ring_freq(dev);
+	}
 	mutex_unlock(&dev_priv->rps.hw_lock);
 }
 
@@ -3497,7 +4388,7 @@ void intel_enable_gt_powersave(struct dr
 		ironlake_enable_drps(dev);
 		ironlake_enable_rc6(dev);
 		intel_init_emon(dev);
-	} else if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) {
+	} else if (IS_GEN6(dev) || IS_GEN7(dev)) {
 		/*
 		 * PCU communication is slow and this doesn't need to be
 		 * done at any specific time, so do this out of our fast path
@@ -3520,6 +4411,19 @@ static void ibx_init_clock_gating(struct
 	I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
 }
 
+static void g4x_disable_trickle_feed(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+
+	for_each_pipe(pipe) {
+		I915_WRITE(DSPCNTR(pipe),
+			   I915_READ(DSPCNTR(pipe)) |
+			   DISPPLANE_TRICKLE_FEED_DISABLE);
+		intel_flush_display_plane(dev_priv, pipe);
+	}
+}
+
 static void ironlake_init_clock_gating(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3579,10 +4483,12 @@ static void ironlake_init_clock_gating(s
 		   _3D_CHICKEN2_WM_READ_PIPELINED << 16 |
 		   _3D_CHICKEN2_WM_READ_PIPELINED);
 
-	/* WaDisableRenderCachePipelinedFlush */
+	/* WaDisableRenderCachePipelinedFlush:ilk */
 	I915_WRITE(CACHE_MODE_0,
 		   _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE));
 
+	g4x_disable_trickle_feed(dev);
+
 	ibx_init_clock_gating(dev);
 }
 
@@ -3607,7 +4513,7 @@ static void cpt_init_clock_gating(struct
 		val = I915_READ(TRANS_CHICKEN2(pipe));
 		val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
 		val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
-		if (dev_priv->fdi_rx_polarity_inverted)
+		if (dev_priv->vbt.fdi_rx_polarity_inverted)
 			val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED;
 		val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK;
 		val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER;
@@ -3637,7 +4543,6 @@ static void gen6_check_mch_setup(struct
 static void gen6_init_clock_gating(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	int pipe;
 	uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE;
 
 	I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate);
@@ -3646,11 +4551,11 @@ static void gen6_init_clock_gating(struc
 		   I915_READ(ILK_DISPLAY_CHICKEN2) |
 		   ILK_ELPIN_409_SELECT);
 
-	/* WaDisableHiZPlanesWhenMSAAEnabled */
+	/* WaDisableHiZPlanesWhenMSAAEnabled:snb */
 	I915_WRITE(_3D_CHICKEN,
 		   _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB));
 
-	/* WaSetupGtModeTdRowDispatch */
+	/* WaSetupGtModeTdRowDispatch:snb */
 	if (IS_SNB_GT1(dev))
 		I915_WRITE(GEN6_GT_MODE,
 			   _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE));
@@ -3677,8 +4582,8 @@ static void gen6_init_clock_gating(struc
 	 * According to the spec, bit 11 (RCCUNIT) must also be set,
 	 * but we didn't debug actual testcases to find it out.
 	 *
-	 * Also apply WaDisableVDSUnitClockGating and
-	 * WaDisableRCPBUnitClockGating.
+	 * Also apply WaDisableVDSUnitClockGating:snb and
+	 * WaDisableRCPBUnitClockGating:snb.
 	 */
 	I915_WRITE(GEN6_UCGCTL2,
 		   GEN7_VDSUNIT_CLOCK_GATE_DISABLE |
@@ -3709,16 +4614,11 @@ static void gen6_init_clock_gating(struc
 		   ILK_DPARBUNIT_CLOCK_GATE_ENABLE  |
 		   ILK_DPFDUNIT_CLOCK_GATE_ENABLE);
 
-	/* WaMbcDriverBootEnable */
+	/* WaMbcDriverBootEnable:snb */
 	I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) |
 		   GEN6_MBCTL_ENABLE_BOOT_FETCH);
 
-	for_each_pipe(pipe) {
-		I915_WRITE(DSPCNTR(pipe),
-			   I915_READ(DSPCNTR(pipe)) |
-			   DISPPLANE_TRICKLE_FEED_DISABLE);
-		intel_flush_display_plane(dev_priv, pipe);
-	}
+	g4x_disable_trickle_feed(dev);
 
 	/* The default value should be 0x200 according to docs, but the two
 	 * platforms I checked have a 0 for this. (Maybe BIOS overrides?) */
@@ -3739,7 +4639,6 @@ static void gen7_setup_fixed_func_schedu
 	reg |= GEN7_FF_VS_SCHED_HW;
 	reg |= GEN7_FF_DS_SCHED_HW;
 
-	/* WaVSRefCountFullforceMissDisable */
 	if (IS_HASWELL(dev_priv->dev))
 		reg &= ~GEN7_FF_VS_REF_CNT_FFME;
 
@@ -3758,65 +4657,72 @@ static void lpt_init_clock_gating(struct
 		I915_WRITE(SOUTH_DSPCLK_GATE_D,
 			   I915_READ(SOUTH_DSPCLK_GATE_D) |
 			   PCH_LP_PARTITION_LEVEL_DISABLE);
+
+	/* WADPOClockGatingDisable:hsw */
+	I915_WRITE(_TRANSA_CHICKEN1,
+		   I915_READ(_TRANSA_CHICKEN1) |
+		   TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
+}
+
+static void lpt_suspend_hw(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
+		uint32_t val = I915_READ(SOUTH_DSPCLK_GATE_D);
+
+		val &= ~PCH_LP_PARTITION_LEVEL_DISABLE;
+		I915_WRITE(SOUTH_DSPCLK_GATE_D, val);
+	}
 }
 
 static void haswell_init_clock_gating(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	int pipe;
 
 	I915_WRITE(WM3_LP_ILK, 0);
 	I915_WRITE(WM2_LP_ILK, 0);
 	I915_WRITE(WM1_LP_ILK, 0);
 
 	/* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
-	 * This implements the WaDisableRCZUnitClockGating workaround.
+	 * This implements the WaDisableRCZUnitClockGating:hsw workaround.
 	 */
 	I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
 
-	/* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
+	/* Apply the WaDisableRHWOOptimizationForRenderHang:hsw workaround. */
 	I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
 		   GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
 
-	/* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
+	/* WaApplyL3ControlAndL3ChickenMode:hsw */
 	I915_WRITE(GEN7_L3CNTLREG1,
 			GEN7_WA_FOR_GEN7_L3_CONTROL);
 	I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
 			GEN7_WA_L3_CHICKEN_MODE);
 
-	/* This is required by WaCatErrorRejectionIssue */
+	/* This is required by WaCatErrorRejectionIssue:hsw */
 	I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
 			I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
 			GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
 
-	for_each_pipe(pipe) {
-		I915_WRITE(DSPCNTR(pipe),
-			   I915_READ(DSPCNTR(pipe)) |
-			   DISPPLANE_TRICKLE_FEED_DISABLE);
-		intel_flush_display_plane(dev_priv, pipe);
-	}
+	g4x_disable_trickle_feed(dev);
 
+	/* WaVSRefCountFullforceMissDisable:hsw */
 	gen7_setup_fixed_func_scheduler(dev_priv);
 
-	/* WaDisable4x2SubspanOptimization */
+	/* WaDisable4x2SubspanOptimization:hsw */
 	I915_WRITE(CACHE_MODE_1,
 		   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
 
-	/* WaMbcDriverBootEnable */
+	/* WaMbcDriverBootEnable:hsw */
 	I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) |
 		   GEN6_MBCTL_ENABLE_BOOT_FETCH);
 
-	/* WaSwitchSolVfFArbitrationPriority */
+	/* WaSwitchSolVfFArbitrationPriority:hsw */
 	I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
 
-	/* XXX: This is a workaround for early silicon revisions and should be
-	 * removed later.
-	 */
-	I915_WRITE(WM_DBG,
-			I915_READ(WM_DBG) |
-			WM_DBG_DISALLOW_MULTIPLE_LP |
-			WM_DBG_DISALLOW_SPRITE |
-			WM_DBG_DISALLOW_MAXFIFO);
+	/* WaRsPkgCStateDisplayPMReq:hsw */
+	I915_WRITE(CHICKEN_PAR1_1,
+		   I915_READ(CHICKEN_PAR1_1) | FORCE_ARB_IDLE_PLANES);
 
 	lpt_init_clock_gating(dev);
 }
@@ -3824,7 +4730,6 @@ static void haswell_init_clock_gating(st
 static void ivybridge_init_clock_gating(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	int pipe;
 	uint32_t snpcr;
 
 	I915_WRITE(WM3_LP_ILK, 0);
@@ -3833,16 +4738,16 @@ static void ivybridge_init_clock_gating(
 
 	I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE);
 
-	/* WaDisableEarlyCull */
+	/* WaDisableEarlyCull:ivb */
 	I915_WRITE(_3D_CHICKEN3,
 		   _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL));
 
-	/* WaDisableBackToBackFlipFix */
+	/* WaDisableBackToBackFlipFix:ivb */
 	I915_WRITE(IVB_CHICKEN3,
 		   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
 		   CHICKEN3_DGMG_DONE_FIX_DISABLE);
 
-	/* WaDisablePSDDualDispatchEnable */
+	/* WaDisablePSDDualDispatchEnable:ivb */
 	if (IS_IVB_GT1(dev))
 		I915_WRITE(GEN7_HALF_SLICE_CHICKEN1,
 			   _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
@@ -3850,11 +4755,11 @@ static void ivybridge_init_clock_gating(
 		I915_WRITE(GEN7_HALF_SLICE_CHICKEN1_GT2,
 			   _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
 
-	/* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
+	/* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */
 	I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
 		   GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
 
-	/* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
+	/* WaApplyL3ControlAndL3ChickenMode:ivb */
 	I915_WRITE(GEN7_L3CNTLREG1,
 			GEN7_WA_FOR_GEN7_L3_CONTROL);
 	I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
@@ -3867,7 +4772,7 @@ static void ivybridge_init_clock_gating(
 			   _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
 
 
-	/* WaForceL3Serialization */
+	/* WaForceL3Serialization:ivb */
 	I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) &
 		   ~L3SQ_URB_READ_CAM_MATCH_DISABLE);
 
@@ -3882,31 +4787,27 @@ static void ivybridge_init_clock_gating(
 	 * but we didn't debug actual testcases to find it out.
 	 *
 	 * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
-	 * This implements the WaDisableRCZUnitClockGating workaround.
+	 * This implements the WaDisableRCZUnitClockGating:ivb workaround.
 	 */
 	I915_WRITE(GEN6_UCGCTL2,
 		   GEN6_RCZUNIT_CLOCK_GATE_DISABLE |
 		   GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
 
-	/* This is required by WaCatErrorRejectionIssue */
+	/* This is required by WaCatErrorRejectionIssue:ivb */
 	I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
 			I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
 			GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
 
-	for_each_pipe(pipe) {
-		I915_WRITE(DSPCNTR(pipe),
-			   I915_READ(DSPCNTR(pipe)) |
-			   DISPPLANE_TRICKLE_FEED_DISABLE);
-		intel_flush_display_plane(dev_priv, pipe);
-	}
+	g4x_disable_trickle_feed(dev);
 
-	/* WaMbcDriverBootEnable */
+	/* WaMbcDriverBootEnable:ivb */
 	I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) |
 		   GEN6_MBCTL_ENABLE_BOOT_FETCH);
 
+	/* WaVSRefCountFullforceMissDisable:ivb */
 	gen7_setup_fixed_func_scheduler(dev_priv);
 
-	/* WaDisable4x2SubspanOptimization */
+	/* WaDisable4x2SubspanOptimization:ivb */
 	I915_WRITE(CACHE_MODE_1,
 		   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
 
@@ -3924,54 +4825,45 @@ static void ivybridge_init_clock_gating(
 static void valleyview_init_clock_gating(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	int pipe;
 
-	I915_WRITE(WM3_LP_ILK, 0);
-	I915_WRITE(WM2_LP_ILK, 0);
-	I915_WRITE(WM1_LP_ILK, 0);
-
-	I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE);
+	I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
 
-	/* WaDisableEarlyCull */
+	/* WaDisableEarlyCull:vlv */
 	I915_WRITE(_3D_CHICKEN3,
 		   _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL));
 
-	/* WaDisableBackToBackFlipFix */
+	/* WaDisableBackToBackFlipFix:vlv */
 	I915_WRITE(IVB_CHICKEN3,
 		   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
 		   CHICKEN3_DGMG_DONE_FIX_DISABLE);
 
-	/* WaDisablePSDDualDispatchEnable */
+	/* WaDisablePSDDualDispatchEnable:vlv */
 	I915_WRITE(GEN7_HALF_SLICE_CHICKEN1,
 		   _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP |
 				      GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
 
-	/* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
+	/* Apply the WaDisableRHWOOptimizationForRenderHang:vlv workaround. */
 	I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
 		   GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
 
-	/* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
+	/* WaApplyL3ControlAndL3ChickenMode:vlv */
 	I915_WRITE(GEN7_L3CNTLREG1, I915_READ(GEN7_L3CNTLREG1) | GEN7_L3AGDIS);
 	I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE);
 
-	/* WaForceL3Serialization */
+	/* WaForceL3Serialization:vlv */
 	I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) &
 		   ~L3SQ_URB_READ_CAM_MATCH_DISABLE);
 
-	/* WaDisableDopClockGating */
+	/* WaDisableDopClockGating:vlv */
 	I915_WRITE(GEN7_ROW_CHICKEN2,
 		   _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
 
-	/* WaForceL3Serialization */
-	I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) &
-		   ~L3SQ_URB_READ_CAM_MATCH_DISABLE);
-
-	/* This is required by WaCatErrorRejectionIssue */
+	/* This is required by WaCatErrorRejectionIssue:vlv */
 	I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
 		   I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
 		   GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
 
-	/* WaMbcDriverBootEnable */
+	/* WaMbcDriverBootEnable:vlv */
 	I915_WRITE(GEN6_MBCTL, I915_READ(GEN6_MBCTL) |
 		   GEN6_MBCTL_ENABLE_BOOT_FETCH);
 
@@ -3987,10 +4879,10 @@ static void valleyview_init_clock_gating
 	 * but we didn't debug actual testcases to find it out.
 	 *
 	 * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
-	 * This implements the WaDisableRCZUnitClockGating workaround.
+	 * This implements the WaDisableRCZUnitClockGating:vlv workaround.
 	 *
-	 * Also apply WaDisableVDSUnitClockGating and
-	 * WaDisableRCPBUnitClockGating.
+	 * Also apply WaDisableVDSUnitClockGating:vlv and
+	 * WaDisableRCPBUnitClockGating:vlv.
 	 */
 	I915_WRITE(GEN6_UCGCTL2,
 		   GEN7_VDSUNIT_CLOCK_GATE_DISABLE |
@@ -4001,18 +4893,13 @@ static void valleyview_init_clock_gating
 
 	I915_WRITE(GEN7_UCGCTL4, GEN7_L3BANK2X_CLOCK_GATE_DISABLE);
 
-	for_each_pipe(pipe) {
-		I915_WRITE(DSPCNTR(pipe),
-			   I915_READ(DSPCNTR(pipe)) |
-			   DISPPLANE_TRICKLE_FEED_DISABLE);
-		intel_flush_display_plane(dev_priv, pipe);
-	}
+	I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE);
 
 	I915_WRITE(CACHE_MODE_1,
 		   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
 
 	/*
-	 * WaDisableVLVClockGating_VBIIssue
+	 * WaDisableVLVClockGating_VBIIssue:vlv
 	 * Disable clock gating on th GCFG unit to prevent a delay
 	 * in the reporting of vblank events.
 	 */
@@ -4048,6 +4935,8 @@ static void g4x_init_clock_gating(struct
 	/* WaDisableRenderCachePipelinedFlush */
 	I915_WRITE(CACHE_MODE_0,
 		   _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE));
+
+	g4x_disable_trickle_feed(dev);
 }
 
 static void crestline_init_clock_gating(struct drm_device *dev)
@@ -4059,6 +4948,8 @@ static void crestline_init_clock_gating(
 	I915_WRITE(DSPCLK_GATE_D, 0);
 	I915_WRITE(RAMCLK_GATE_D, 0);
 	I915_WRITE16(DEUC, 0);
+	I915_WRITE(MI_ARB_STATE,
+		   _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
 }
 
 static void broadwater_init_clock_gating(struct drm_device *dev)
@@ -4071,6 +4962,8 @@ static void broadwater_init_clock_gating
 		   I965_ISC_CLOCK_GATE_DISABLE |
 		   I965_FBC_CLOCK_GATE_DISABLE);
 	I915_WRITE(RENCLK_GATE_D2, 0);
+	I915_WRITE(MI_ARB_STATE,
+		   _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
 }
 
 static void gen3_init_clock_gating(struct drm_device *dev)
@@ -4110,34 +5003,50 @@ void intel_init_clock_gating(struct drm_
 	dev_priv->display.init_clock_gating(dev);
 }
 
+void intel_suspend_hw(struct drm_device *dev)
+{
+	if (HAS_PCH_LPT(dev))
+		lpt_suspend_hw(dev);
+}
+
 /**
  * We should only use the power well if we explicitly asked the hardware to
  * enable it, so check if it's enabled and also check if we've requested it to
  * be enabled.
  */
-bool intel_using_power_well(struct drm_device *dev)
+bool intel_display_power_enabled(struct drm_device *dev,
+				 enum intel_display_power_domain domain)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_HASWELL(dev))
+	if (!HAS_POWER_WELL(dev))
+		return true;
+
+	switch (domain) {
+	case POWER_DOMAIN_PIPE_A:
+	case POWER_DOMAIN_TRANSCODER_EDP:
+		return true;
+	case POWER_DOMAIN_PIPE_B:
+	case POWER_DOMAIN_PIPE_C:
+	case POWER_DOMAIN_PIPE_A_PANEL_FITTER:
+	case POWER_DOMAIN_PIPE_B_PANEL_FITTER:
+	case POWER_DOMAIN_PIPE_C_PANEL_FITTER:
+	case POWER_DOMAIN_TRANSCODER_A:
+	case POWER_DOMAIN_TRANSCODER_B:
+	case POWER_DOMAIN_TRANSCODER_C:
 		return I915_READ(HSW_PWR_WELL_DRIVER) ==
 		       (HSW_PWR_WELL_ENABLE | HSW_PWR_WELL_STATE);
-	else
-		return true;
+	default:
+		BUG();
+	}
 }
 
-void intel_set_power_well(struct drm_device *dev, bool enable)
+static void __intel_set_power_well(struct drm_device *dev, bool enable)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	bool is_enabled, enable_requested;
 	uint32_t tmp;
 
-	if (!HAS_POWER_WELL(dev))
-		return;
-
-	if (!i915_disable_power_well && !enable)
-		return;
-
 	tmp = I915_READ(HSW_PWR_WELL_DRIVER);
 	is_enabled = tmp & HSW_PWR_WELL_STATE;
 	enable_requested = tmp & HSW_PWR_WELL_ENABLE;
@@ -4154,12 +5063,103 @@ void intel_set_power_well(struct drm_dev
 		}
 	} else {
 		if (enable_requested) {
+			unsigned long irqflags;
+			enum pipe p;
+
 			I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
+			POSTING_READ(HSW_PWR_WELL_DRIVER);
 			DRM_DEBUG_KMS("Requesting to disable the power well\n");
+
+			/*
+			 * After this, the registers on the pipes that are part
+			 * of the power well will become zero, so we have to
+			 * adjust our counters according to that.
+			 *
+			 * FIXME: Should we do this in general in
+			 * drm_vblank_post_modeset?
+			 */
+			spin_lock_irqsave(&dev->vbl_lock, irqflags);
+			for_each_pipe(p)
+				if (p != PIPE_A)
+					dev->last_vblank[p] = 0;
+			spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 		}
 	}
 }
 
+static struct i915_power_well *hsw_pwr;
+
+/* Display audio driver power well request */
+void i915_request_power_well(void)
+{
+	if (WARN_ON(!hsw_pwr))
+		return;
+
+	spin_lock_irq(&hsw_pwr->lock);
+	if (!hsw_pwr->count++ &&
+			!hsw_pwr->i915_request)
+		__intel_set_power_well(hsw_pwr->device, true);
+	spin_unlock_irq(&hsw_pwr->lock);
+}
+EXPORT_SYMBOL_GPL(i915_request_power_well);
+
+/* Display audio driver power well release */
+void i915_release_power_well(void)
+{
+	if (WARN_ON(!hsw_pwr))
+		return;
+
+	spin_lock_irq(&hsw_pwr->lock);
+	WARN_ON(!hsw_pwr->count);
+	if (!--hsw_pwr->count &&
+		       !hsw_pwr->i915_request)
+		__intel_set_power_well(hsw_pwr->device, false);
+	spin_unlock_irq(&hsw_pwr->lock);
+}
+EXPORT_SYMBOL_GPL(i915_release_power_well);
+
+int i915_init_power_well(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	hsw_pwr = &dev_priv->power_well;
+
+	hsw_pwr->device = dev;
+	spin_lock_init(&hsw_pwr->lock);
+	hsw_pwr->count = 0;
+
+	return 0;
+}
+
+void i915_remove_power_well(struct drm_device *dev)
+{
+	hsw_pwr = NULL;
+}
+
+void intel_set_power_well(struct drm_device *dev, bool enable)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct i915_power_well *power_well = &dev_priv->power_well;
+
+	if (!HAS_POWER_WELL(dev))
+		return;
+
+	if (!i915_disable_power_well && !enable)
+		return;
+
+	spin_lock_irq(&power_well->lock);
+	power_well->i915_request = enable;
+
+	/* only reject "disable" power well request */
+	if (power_well->count && !enable) {
+		spin_unlock_irq(&power_well->lock);
+		return;
+	}
+
+	__intel_set_power_well(dev, enable);
+	spin_unlock_irq(&power_well->lock);
+}
+
 /*
  * Starting with Haswell, we have a "Power Down Well" that can be turned off
  * when not needed anymore. We have 4 registers that can request the power well
@@ -4190,7 +5190,12 @@ void intel_init_pm(struct drm_device *de
 	if (I915_HAS_FBC(dev)) {
 		if (HAS_PCH_SPLIT(dev)) {
 			dev_priv->display.fbc_enabled = ironlake_fbc_enabled;
-			dev_priv->display.enable_fbc = ironlake_enable_fbc;
+			if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
+				dev_priv->display.enable_fbc =
+					gen7_enable_fbc;
+			else
+				dev_priv->display.enable_fbc =
+					ironlake_enable_fbc;
 			dev_priv->display.disable_fbc = ironlake_disable_fbc;
 		} else if (IS_GM45(dev)) {
 			dev_priv->display.fbc_enabled = g4x_fbc_enabled;
@@ -4242,10 +5247,10 @@ void intel_init_pm(struct drm_device *de
 			}
 			dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
 		} else if (IS_HASWELL(dev)) {
-			if (SNB_READ_WM0_LATENCY()) {
-				dev_priv->display.update_wm = sandybridge_update_wm;
-				dev_priv->display.update_sprite_wm = sandybridge_update_sprite_wm;
-				dev_priv->display.update_linetime_wm = haswell_update_linetime_wm;
+			if (I915_READ64(MCH_SSKPD)) {
+				dev_priv->display.update_wm = haswell_update_wm;
+				dev_priv->display.update_sprite_wm =
+					haswell_update_sprite_wm;
 			} else {
 				DRM_DEBUG_KMS("Failed to read display plane latency. "
 					      "Disable CxSR\n");
@@ -4340,6 +5345,7 @@ static void __gen6_gt_force_wake_get(str
 			    FORCEWAKE_ACK_TIMEOUT_MS))
 		DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
 
+	/* WaRsForcewakeWaitTC0:snb */
 	__gen6_gt_wait_for_thread_c0(dev_priv);
 }
 
@@ -4371,6 +5377,7 @@ static void __gen6_gt_force_wake_mt_get(
 			    FORCEWAKE_ACK_TIMEOUT_MS))
 		DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
 
+	/* WaRsForcewakeWaitTC0:ivb,hsw */
 	__gen6_gt_wait_for_thread_c0(dev_priv);
 }
 
@@ -4474,6 +5481,7 @@ static void vlv_force_wake_get(struct dr
 			    FORCEWAKE_ACK_TIMEOUT_MS))
 		DRM_ERROR("Timed out waiting for media to ack forcewake request.\n");
 
+	/* WaRsForcewakeWaitTC0:vlv */
 	__gen6_gt_wait_for_thread_c0(dev_priv);
 }
 
@@ -4486,7 +5494,7 @@ static void vlv_force_wake_put(struct dr
 	gen6_gt_check_fifodbg(dev_priv);
 }
 
-void intel_gt_reset(struct drm_device *dev)
+void intel_gt_sanitize(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -4497,26 +5505,61 @@ void intel_gt_reset(struct drm_device *d
 		if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
 			__gen6_gt_force_wake_mt_reset(dev_priv);
 	}
+
+	/* BIOS often leaves RC6 enabled, but disable it for hw init */
+	if (INTEL_INFO(dev)->gen >= 6)
+		intel_disable_gt_powersave(dev);
 }
 
 void intel_gt_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	spin_lock_init(&dev_priv->gt_lock);
-
-	intel_gt_reset(dev);
-
 	if (IS_VALLEYVIEW(dev)) {
 		dev_priv->gt.force_wake_get = vlv_force_wake_get;
 		dev_priv->gt.force_wake_put = vlv_force_wake_put;
-	} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
+	} else if (IS_HASWELL(dev)) {
 		dev_priv->gt.force_wake_get = __gen6_gt_force_wake_mt_get;
 		dev_priv->gt.force_wake_put = __gen6_gt_force_wake_mt_put;
+	} else if (IS_IVYBRIDGE(dev)) {
+		u32 ecobus;
+
+		/* IVB configs may use multi-threaded forcewake */
+
+		/* A small trick here - if the bios hasn't configured
+		 * MT forcewake, and if the device is in RC6, then
+		 * force_wake_mt_get will not wake the device and the
+		 * ECOBUS read will return zero. Which will be
+		 * (correctly) interpreted by the test below as MT
+		 * forcewake being disabled.
+		 */
+		mutex_lock(&dev->struct_mutex);
+		__gen6_gt_force_wake_mt_get(dev_priv);
+		ecobus = I915_READ_NOTRACE(ECOBUS);
+		__gen6_gt_force_wake_mt_put(dev_priv);
+		mutex_unlock(&dev->struct_mutex);
+
+		if (ecobus & FORCEWAKE_MT_ENABLE) {
+			dev_priv->gt.force_wake_get =
+						__gen6_gt_force_wake_mt_get;
+			dev_priv->gt.force_wake_put =
+						__gen6_gt_force_wake_mt_put;
+		} else {
+			DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n");
+			DRM_INFO("when using vblank-synced partial screen updates.\n");
+			dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get;
+			dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put;
+		}
 	} else if (IS_GEN6(dev)) {
 		dev_priv->gt.force_wake_get = __gen6_gt_force_wake_get;
 		dev_priv->gt.force_wake_put = __gen6_gt_force_wake_put;
 	}
+}
+
+void intel_pm_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
 	INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work,
 			  intel_gen6_powersave_work);
 }
@@ -4568,55 +5611,58 @@ int sandybridge_pcode_write(struct drm_i
 	return 0;
 }
 
-static int vlv_punit_rw(struct drm_i915_private *dev_priv, u8 opcode,
-			u8 addr, u32 *val)
+int vlv_gpu_freq(int ddr_freq, int val)
 {
-	u32 cmd, devfn, port, be, bar;
-
-	bar = 0;
-	be = 0xf;
-	port = IOSF_PORT_PUNIT;
-	devfn = PCI_DEVFN(2, 0);
-
-	cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
-		(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
-		(bar << IOSF_BAR_SHIFT);
-
-	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+	int mult, base;
 
-	if (I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) {
-		DRM_DEBUG_DRIVER("warning: pcode (%s) mailbox access failed\n",
-				 opcode == PUNIT_OPCODE_REG_READ ?
-				 "read" : "write");
-		return -EAGAIN;
+	switch (ddr_freq) {
+	case 800:
+		mult = 20;
+		base = 120;
+		break;
+	case 1066:
+		mult = 22;
+		base = 133;
+		break;
+	case 1333:
+		mult = 21;
+		base = 125;
+		break;
+	default:
+		return -1;
 	}
 
-	I915_WRITE(VLV_IOSF_ADDR, addr);
-	if (opcode == PUNIT_OPCODE_REG_WRITE)
-		I915_WRITE(VLV_IOSF_DATA, *val);
-	I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
+	return ((val - 0xbd) * mult) + base;
+}
 
-	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0,
-		     500)) {
-		DRM_ERROR("timeout waiting for pcode %s (%d) to finish\n",
-			  opcode == PUNIT_OPCODE_REG_READ ? "read" : "write",
-			  addr);
-		return -ETIMEDOUT;
+int vlv_freq_opcode(int ddr_freq, int val)
+{
+	int mult, base;
+
+	switch (ddr_freq) {
+	case 800:
+		mult = 20;
+		base = 120;
+		break;
+	case 1066:
+		mult = 22;
+		base = 133;
+		break;
+	case 1333:
+		mult = 21;
+		base = 125;
+		break;
+	default:
+		return -1;
 	}
 
-	if (opcode == PUNIT_OPCODE_REG_READ)
-		*val = I915_READ(VLV_IOSF_DATA);
-	I915_WRITE(VLV_IOSF_DATA, 0);
+	val /= mult;
+	val -= base / mult;
+	val += 0xbd;
 
-	return 0;
-}
+	if (val > 0xea)
+		val = 0xea;
 
-int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val)
-{
-	return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_READ, addr, val);
+	return val;
 }
 
-int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
-{
-	return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_WRITE, addr, &val);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_ringbuffer.c	2013-08-25 20:43:22.000000000 -0400
@@ -280,6 +280,27 @@ gen7_render_ring_cs_stall_wa(struct inte
 	return 0;
 }
 
+static int gen7_ring_fbc_flush(struct intel_ring_buffer *ring, u32 value)
+{
+	int ret;
+
+	if (!ring->fbc_dirty)
+		return 0;
+
+	ret = intel_ring_begin(ring, 4);
+	if (ret)
+		return ret;
+	intel_ring_emit(ring, MI_NOOP);
+	/* WaFbcNukeOn3DBlt:ivb/hsw */
+	intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
+	intel_ring_emit(ring, MSG_FBC_REND_STATE);
+	intel_ring_emit(ring, value);
+	intel_ring_advance(ring);
+
+	ring->fbc_dirty = false;
+	return 0;
+}
+
 static int
 gen7_render_ring_flush(struct intel_ring_buffer *ring,
 		       u32 invalidate_domains, u32 flush_domains)
@@ -336,6 +357,9 @@ gen7_render_ring_flush(struct intel_ring
 	intel_ring_emit(ring, 0);
 	intel_ring_advance(ring);
 
+	if (flush_domains)
+		return gen7_ring_fbc_flush(ring, FBC_REND_NUKE);
+
 	return 0;
 }
 
@@ -355,6 +379,17 @@ u32 intel_ring_get_active_head(struct in
 	return I915_READ(acthd_reg);
 }
 
+static void ring_setup_phys_status_page(struct intel_ring_buffer *ring)
+{
+	struct drm_i915_private *dev_priv = ring->dev->dev_private;
+	u32 addr;
+
+	addr = dev_priv->status_page_dmah->busaddr;
+	if (INTEL_INFO(ring->dev)->gen >= 4)
+		addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0;
+	I915_WRITE(HWS_PGA, addr);
+}
+
 static int init_ring_common(struct intel_ring_buffer *ring)
 {
 	struct drm_device *dev = ring->dev;
@@ -366,6 +401,11 @@ static int init_ring_common(struct intel
 	if (HAS_FORCE_WAKE(dev))
 		gen6_gt_force_wake_get(dev_priv);
 
+	if (I915_NEED_GFX_HWS(dev))
+		intel_ring_setup_status_page(ring);
+	else
+		ring_setup_phys_status_page(ring);
+
 	/* Stop the ring if it's running. */
 	I915_WRITE_CTL(ring, 0);
 	I915_WRITE_HEAD(ring, 0);
@@ -429,6 +469,8 @@ static int init_ring_common(struct intel
 		ring->last_retired_head = -1;
 	}
 
+	memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
+
 out:
 	if (HAS_FORCE_WAKE(dev))
 		gen6_gt_force_wake_put(dev_priv);
@@ -464,9 +506,11 @@ init_pipe_control(struct intel_ring_buff
 		goto err_unref;
 
 	pc->gtt_offset = obj->gtt_offset;
-	pc->cpu_page =  kmap(sg_page(obj->pages->sgl));
-	if (pc->cpu_page == NULL)
+	pc->cpu_page = kmap(sg_page(obj->pages->sgl));
+	if (pc->cpu_page == NULL) {
+		ret = -ENOMEM;
 		goto err_unpin;
+	}
 
 	DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n",
 			 ring->name, pc->gtt_offset);
@@ -490,9 +534,6 @@ cleanup_pipe_control(struct intel_ring_b
 	struct pipe_control *pc = ring->private;
 	struct drm_i915_gem_object *obj;
 
-	if (!ring->private)
-		return;
-
 	obj = pc->obj;
 
 	kunmap(sg_page(obj->pages->sgl));
@@ -500,7 +541,6 @@ cleanup_pipe_control(struct intel_ring_b
 	drm_gem_object_unreference(&obj->base);
 
 	kfree(pc);
-	ring->private = NULL;
 }
 
 static int init_render_ring(struct intel_ring_buffer *ring)
@@ -515,6 +555,8 @@ static int init_render_ring(struct intel
 	/* We need to disable the AsyncFlip performance optimisations in order
 	 * to use MI_WAIT_FOR_EVENT within the CS. It should already be
 	 * programmed to '1' on all products.
+	 *
+	 * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv
 	 */
 	if (INTEL_INFO(dev)->gen >= 6)
 		I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE));
@@ -556,7 +598,7 @@ static int init_render_ring(struct intel
 		I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
 
 	if (HAS_L3_GPU_CACHE(dev))
-		I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR);
+		I915_WRITE_IMR(ring, ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
 
 	return ret;
 }
@@ -571,16 +613,26 @@ static void render_ring_cleanup(struct i
 	if (HAS_BROKEN_CS_TLB(dev))
 		drm_gem_object_unreference(to_gem_object(ring->private));
 
-	cleanup_pipe_control(ring);
+	if (INTEL_INFO(dev)->gen >= 5)
+		cleanup_pipe_control(ring);
+
+	ring->private = NULL;
 }
 
 static void
 update_mboxes(struct intel_ring_buffer *ring,
 	      u32 mmio_offset)
 {
+/* NB: In order to be able to do semaphore MBOX updates for varying number
+ * of rings, it's easiest if we round up each individual update to a
+ * multiple of 2 (since ring updates must always be a multiple of 2)
+ * even though the actual update only requires 3 dwords.
+ */
+#define MBOX_UPDATE_DWORDS 4
 	intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
 	intel_ring_emit(ring, mmio_offset);
 	intel_ring_emit(ring, ring->outstanding_lazy_request);
+	intel_ring_emit(ring, MI_NOOP);
 }
 
 /**
@@ -595,19 +647,24 @@ update_mboxes(struct intel_ring_buffer *
 static int
 gen6_add_request(struct intel_ring_buffer *ring)
 {
-	u32 mbox1_reg;
-	u32 mbox2_reg;
-	int ret;
+	struct drm_device *dev = ring->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_ring_buffer *useless;
+	int i, ret;
 
-	ret = intel_ring_begin(ring, 10);
+	ret = intel_ring_begin(ring, ((I915_NUM_RINGS-1) *
+				      MBOX_UPDATE_DWORDS) +
+				      4);
 	if (ret)
 		return ret;
+#undef MBOX_UPDATE_DWORDS
 
-	mbox1_reg = ring->signal_mbox[0];
-	mbox2_reg = ring->signal_mbox[1];
+	for_each_ring(useless, dev_priv, i) {
+		u32 mbox_reg = ring->signal_mbox[i];
+		if (mbox_reg != GEN6_NOSYNC)
+			update_mboxes(ring, mbox_reg);
+	}
 
-	update_mboxes(ring, mbox1_reg);
-	update_mboxes(ring, mbox2_reg);
 	intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
 	intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
 	intel_ring_emit(ring, ring->outstanding_lazy_request);
@@ -779,7 +836,7 @@ gen5_ring_get_irq(struct intel_ring_buff
 		return false;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	if (ring->irq_refcount++ == 0) {
+	if (ring->irq_refcount.gt++ == 0) {
 		dev_priv->gt_irq_mask &= ~ring->irq_enable_mask;
 		I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 		POSTING_READ(GTIMR);
@@ -797,7 +854,7 @@ gen5_ring_put_irq(struct intel_ring_buff
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	if (--ring->irq_refcount == 0) {
+	if (--ring->irq_refcount.gt == 0) {
 		dev_priv->gt_irq_mask |= ring->irq_enable_mask;
 		I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
 		POSTING_READ(GTIMR);
@@ -816,7 +873,7 @@ i9xx_ring_get_irq(struct intel_ring_buff
 		return false;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	if (ring->irq_refcount++ == 0) {
+	if (ring->irq_refcount.gt++ == 0) {
 		dev_priv->irq_mask &= ~ring->irq_enable_mask;
 		I915_WRITE(IMR, dev_priv->irq_mask);
 		POSTING_READ(IMR);
@@ -834,7 +891,7 @@ i9xx_ring_put_irq(struct intel_ring_buff
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	if (--ring->irq_refcount == 0) {
+	if (--ring->irq_refcount.gt == 0) {
 		dev_priv->irq_mask |= ring->irq_enable_mask;
 		I915_WRITE(IMR, dev_priv->irq_mask);
 		POSTING_READ(IMR);
@@ -853,7 +910,7 @@ i8xx_ring_get_irq(struct intel_ring_buff
 		return false;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	if (ring->irq_refcount++ == 0) {
+	if (ring->irq_refcount.gt++ == 0) {
 		dev_priv->irq_mask &= ~ring->irq_enable_mask;
 		I915_WRITE16(IMR, dev_priv->irq_mask);
 		POSTING_READ16(IMR);
@@ -871,7 +928,7 @@ i8xx_ring_put_irq(struct intel_ring_buff
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	if (--ring->irq_refcount == 0) {
+	if (--ring->irq_refcount.gt == 0) {
 		dev_priv->irq_mask |= ring->irq_enable_mask;
 		I915_WRITE16(IMR, dev_priv->irq_mask);
 		POSTING_READ16(IMR);
@@ -899,6 +956,9 @@ void intel_ring_setup_status_page(struct
 		case VCS:
 			mmio = BSD_HWS_PGA_GEN7;
 			break;
+		case VECS:
+			mmio = VEBOX_HWS_PGA_GEN7;
+			break;
 		}
 	} else if (IS_GEN6(ring->dev)) {
 		mmio = RING_HWS_PGA_GEN6(ring->mmio_base);
@@ -908,6 +968,18 @@ void intel_ring_setup_status_page(struct
 
 	I915_WRITE(mmio, (u32)ring->status_page.gfx_addr);
 	POSTING_READ(mmio);
+
+	/* Flush the TLB for this page */
+	if (INTEL_INFO(dev)->gen >= 6) {
+		u32 reg = RING_INSTPM(ring->mmio_base);
+		I915_WRITE(reg,
+			   _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE |
+					      INSTPM_SYNC_FLUSH));
+		if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0,
+			     1000))
+			DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n",
+				  ring->name);
+	}
 }
 
 static int
@@ -961,10 +1033,11 @@ gen6_ring_get_irq(struct intel_ring_buff
 	gen6_gt_force_wake_get(dev_priv);
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	if (ring->irq_refcount++ == 0) {
+	if (ring->irq_refcount.gt++ == 0) {
 		if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS)
-			I915_WRITE_IMR(ring, ~(ring->irq_enable_mask |
-						GEN6_RENDER_L3_PARITY_ERROR));
+			I915_WRITE_IMR(ring,
+				       ~(ring->irq_enable_mask |
+					 GT_RENDER_L3_PARITY_ERROR_INTERRUPT));
 		else
 			I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
 		dev_priv->gt_irq_mask &= ~ring->irq_enable_mask;
@@ -984,9 +1057,10 @@ gen6_ring_put_irq(struct intel_ring_buff
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, flags);
-	if (--ring->irq_refcount == 0) {
+	if (--ring->irq_refcount.gt == 0) {
 		if (HAS_L3_GPU_CACHE(dev) && ring->id == RCS)
-			I915_WRITE_IMR(ring, ~GEN6_RENDER_L3_PARITY_ERROR);
+			I915_WRITE_IMR(ring,
+				       ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT);
 		else
 			I915_WRITE_IMR(ring, ~0);
 		dev_priv->gt_irq_mask |= ring->irq_enable_mask;
@@ -998,6 +1072,48 @@ gen6_ring_put_irq(struct intel_ring_buff
 	gen6_gt_force_wake_put(dev_priv);
 }
 
+static bool
+hsw_vebox_get_irq(struct intel_ring_buffer *ring)
+{
+	struct drm_device *dev = ring->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	if (!dev->irq_enabled)
+		return false;
+
+	spin_lock_irqsave(&dev_priv->rps.lock, flags);
+	if (ring->irq_refcount.pm++ == 0) {
+		u32 pm_imr = I915_READ(GEN6_PMIMR);
+		I915_WRITE_IMR(ring, ~ring->irq_enable_mask);
+		I915_WRITE(GEN6_PMIMR, pm_imr & ~ring->irq_enable_mask);
+		POSTING_READ(GEN6_PMIMR);
+	}
+	spin_unlock_irqrestore(&dev_priv->rps.lock, flags);
+
+	return true;
+}
+
+static void
+hsw_vebox_put_irq(struct intel_ring_buffer *ring)
+{
+	struct drm_device *dev = ring->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	if (!dev->irq_enabled)
+		return;
+
+	spin_lock_irqsave(&dev_priv->rps.lock, flags);
+	if (--ring->irq_refcount.pm == 0) {
+		u32 pm_imr = I915_READ(GEN6_PMIMR);
+		I915_WRITE_IMR(ring, ~0);
+		I915_WRITE(GEN6_PMIMR, pm_imr | ring->irq_enable_mask);
+		POSTING_READ(GEN6_PMIMR);
+	}
+	spin_unlock_irqrestore(&dev_priv->rps.lock, flags);
+}
+
 static int
 i965_dispatch_execbuffer(struct intel_ring_buffer *ring,
 			 u32 offset, u32 length,
@@ -1134,7 +1250,6 @@ static int init_status_page(struct intel
 	ring->status_page.obj = obj;
 	memset(ring->status_page.page_addr, 0, PAGE_SIZE);
 
-	intel_ring_setup_status_page(ring);
 	DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
 			ring->name, ring->status_page.gfx_addr);
 
@@ -1148,10 +1263,9 @@ err:
 	return ret;
 }
 
-static int init_phys_hws_pga(struct intel_ring_buffer *ring)
+static int init_phys_status_page(struct intel_ring_buffer *ring)
 {
 	struct drm_i915_private *dev_priv = ring->dev->dev_private;
-	u32 addr;
 
 	if (!dev_priv->status_page_dmah) {
 		dev_priv->status_page_dmah =
@@ -1160,11 +1274,6 @@ static int init_phys_hws_pga(struct inte
 			return -ENOMEM;
 	}
 
-	addr = dev_priv->status_page_dmah->busaddr;
-	if (INTEL_INFO(ring->dev)->gen >= 4)
-		addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0;
-	I915_WRITE(HWS_PGA, addr);
-
 	ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr;
 	memset(ring->status_page.page_addr, 0, PAGE_SIZE);
 
@@ -1192,7 +1301,7 @@ static int intel_init_ring_buffer(struct
 			return ret;
 	} else {
 		BUG_ON(ring->id != RCS);
-		ret = init_phys_hws_pga(ring);
+		ret = init_phys_status_page(ring);
 		if (ret)
 			return ret;
 	}
@@ -1423,7 +1532,7 @@ int intel_ring_idle(struct intel_ring_bu
 
 	/* We need to add any requests required to flush the objects and ring */
 	if (ring->outstanding_lazy_request) {
-		ret = i915_add_request(ring, NULL, NULL);
+		ret = i915_add_request(ring, NULL);
 		if (ret)
 			return ret;
 	}
@@ -1500,6 +1609,7 @@ void intel_ring_init_seqno(struct intel_
 	}
 
 	ring->set_seqno(ring, seqno);
+	ring->hangcheck.seqno = seqno;
 }
 
 void intel_ring_advance(struct intel_ring_buffer *ring)
@@ -1546,8 +1656,8 @@ static void gen6_bsd_ring_write_tail(str
 		   _MASKED_BIT_DISABLE(GEN6_BSD_SLEEP_MSG_DISABLE));
 }
 
-static int gen6_ring_flush(struct intel_ring_buffer *ring,
-			   u32 invalidate, u32 flush)
+static int gen6_bsd_ring_flush(struct intel_ring_buffer *ring,
+			       u32 invalidate, u32 flush)
 {
 	uint32_t cmd;
 	int ret;
@@ -1618,9 +1728,10 @@ gen6_ring_dispatch_execbuffer(struct int
 
 /* Blitter support (SandyBridge+) */
 
-static int blt_ring_flush(struct intel_ring_buffer *ring,
-			  u32 invalidate, u32 flush)
+static int gen6_ring_flush(struct intel_ring_buffer *ring,
+			   u32 invalidate, u32 flush)
 {
+	struct drm_device *dev = ring->dev;
 	uint32_t cmd;
 	int ret;
 
@@ -1643,6 +1754,10 @@ static int blt_ring_flush(struct intel_r
 	intel_ring_emit(ring, 0);
 	intel_ring_emit(ring, MI_NOOP);
 	intel_ring_advance(ring);
+
+	if (IS_GEN7(dev) && flush)
+		return gen7_ring_fbc_flush(ring, FBC_REND_CACHE_CLEAN);
+
 	return 0;
 }
 
@@ -1662,15 +1777,18 @@ int intel_init_render_ring_buffer(struct
 			ring->flush = gen6_render_ring_flush;
 		ring->irq_get = gen6_ring_get_irq;
 		ring->irq_put = gen6_ring_put_irq;
-		ring->irq_enable_mask = GT_USER_INTERRUPT;
+		ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
 		ring->get_seqno = gen6_ring_get_seqno;
 		ring->set_seqno = ring_set_seqno;
 		ring->sync_to = gen6_ring_sync;
-		ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_INVALID;
-		ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_RV;
-		ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_RB;
-		ring->signal_mbox[0] = GEN6_VRSYNC;
-		ring->signal_mbox[1] = GEN6_BRSYNC;
+		ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_INVALID;
+		ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_RV;
+		ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_RB;
+		ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_RVE;
+		ring->signal_mbox[RCS] = GEN6_NOSYNC;
+		ring->signal_mbox[VCS] = GEN6_VRSYNC;
+		ring->signal_mbox[BCS] = GEN6_BRSYNC;
+		ring->signal_mbox[VECS] = GEN6_VERSYNC;
 	} else if (IS_GEN5(dev)) {
 		ring->add_request = pc_render_add_request;
 		ring->flush = gen4_render_ring_flush;
@@ -1678,7 +1796,8 @@ int intel_init_render_ring_buffer(struct
 		ring->set_seqno = pc_render_set_seqno;
 		ring->irq_get = gen5_ring_get_irq;
 		ring->irq_put = gen5_ring_put_irq;
-		ring->irq_enable_mask = GT_USER_INTERRUPT | GT_PIPE_NOTIFY;
+		ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT |
+					GT_RENDER_PIPECTL_NOTIFY_INTERRUPT;
 	} else {
 		ring->add_request = i9xx_add_request;
 		if (INTEL_INFO(dev)->gen < 4)
@@ -1794,7 +1913,7 @@ int intel_render_ring_init_dri(struct dr
 	}
 
 	if (!I915_NEED_GFX_HWS(dev)) {
-		ret = init_phys_hws_pga(ring);
+		ret = init_phys_status_page(ring);
 		if (ret)
 			return ret;
 	}
@@ -1816,20 +1935,23 @@ int intel_init_bsd_ring_buffer(struct dr
 		/* gen6 bsd needs a special wa for tail updates */
 		if (IS_GEN6(dev))
 			ring->write_tail = gen6_bsd_ring_write_tail;
-		ring->flush = gen6_ring_flush;
+		ring->flush = gen6_bsd_ring_flush;
 		ring->add_request = gen6_add_request;
 		ring->get_seqno = gen6_ring_get_seqno;
 		ring->set_seqno = ring_set_seqno;
-		ring->irq_enable_mask = GEN6_BSD_USER_INTERRUPT;
+		ring->irq_enable_mask = GT_BSD_USER_INTERRUPT;
 		ring->irq_get = gen6_ring_get_irq;
 		ring->irq_put = gen6_ring_put_irq;
 		ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
 		ring->sync_to = gen6_ring_sync;
-		ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_VR;
-		ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_INVALID;
-		ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_VB;
-		ring->signal_mbox[0] = GEN6_RVSYNC;
-		ring->signal_mbox[1] = GEN6_BVSYNC;
+		ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VR;
+		ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_INVALID;
+		ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_VB;
+		ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_VVE;
+		ring->signal_mbox[RCS] = GEN6_RVSYNC;
+		ring->signal_mbox[VCS] = GEN6_NOSYNC;
+		ring->signal_mbox[BCS] = GEN6_BVSYNC;
+		ring->signal_mbox[VECS] = GEN6_VEVSYNC;
 	} else {
 		ring->mmio_base = BSD_RING_BASE;
 		ring->flush = bsd_ring_flush;
@@ -1837,7 +1959,7 @@ int intel_init_bsd_ring_buffer(struct dr
 		ring->get_seqno = ring_get_seqno;
 		ring->set_seqno = ring_set_seqno;
 		if (IS_GEN5(dev)) {
-			ring->irq_enable_mask = GT_BSD_USER_INTERRUPT;
+			ring->irq_enable_mask = ILK_BSD_USER_INTERRUPT;
 			ring->irq_get = gen5_ring_get_irq;
 			ring->irq_put = gen5_ring_put_irq;
 		} else {
@@ -1862,20 +1984,56 @@ int intel_init_blt_ring_buffer(struct dr
 
 	ring->mmio_base = BLT_RING_BASE;
 	ring->write_tail = ring_write_tail;
-	ring->flush = blt_ring_flush;
+	ring->flush = gen6_ring_flush;
 	ring->add_request = gen6_add_request;
 	ring->get_seqno = gen6_ring_get_seqno;
 	ring->set_seqno = ring_set_seqno;
-	ring->irq_enable_mask = GEN6_BLITTER_USER_INTERRUPT;
+	ring->irq_enable_mask = GT_BLT_USER_INTERRUPT;
 	ring->irq_get = gen6_ring_get_irq;
 	ring->irq_put = gen6_ring_put_irq;
 	ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
 	ring->sync_to = gen6_ring_sync;
-	ring->semaphore_register[0] = MI_SEMAPHORE_SYNC_BR;
-	ring->semaphore_register[1] = MI_SEMAPHORE_SYNC_BV;
-	ring->semaphore_register[2] = MI_SEMAPHORE_SYNC_INVALID;
-	ring->signal_mbox[0] = GEN6_RBSYNC;
-	ring->signal_mbox[1] = GEN6_VBSYNC;
+	ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_BR;
+	ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_BV;
+	ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_INVALID;
+	ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_BVE;
+	ring->signal_mbox[RCS] = GEN6_RBSYNC;
+	ring->signal_mbox[VCS] = GEN6_VBSYNC;
+	ring->signal_mbox[BCS] = GEN6_NOSYNC;
+	ring->signal_mbox[VECS] = GEN6_VEBSYNC;
+	ring->init = init_ring_common;
+
+	return intel_init_ring_buffer(dev, ring);
+}
+
+int intel_init_vebox_ring_buffer(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_ring_buffer *ring = &dev_priv->ring[VECS];
+
+	ring->name = "video enhancement ring";
+	ring->id = VECS;
+
+	ring->mmio_base = VEBOX_RING_BASE;
+	ring->write_tail = ring_write_tail;
+	ring->flush = gen6_ring_flush;
+	ring->add_request = gen6_add_request;
+	ring->get_seqno = gen6_ring_get_seqno;
+	ring->set_seqno = ring_set_seqno;
+	ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT |
+		PM_VEBOX_CS_ERROR_INTERRUPT;
+	ring->irq_get = hsw_vebox_get_irq;
+	ring->irq_put = hsw_vebox_put_irq;
+	ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer;
+	ring->sync_to = gen6_ring_sync;
+	ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VER;
+	ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_VEV;
+	ring->semaphore_register[BCS] = MI_SEMAPHORE_SYNC_VEB;
+	ring->semaphore_register[VECS] = MI_SEMAPHORE_SYNC_INVALID;
+	ring->signal_mbox[RCS] = GEN6_RVESYNC;
+	ring->signal_mbox[VCS] = GEN6_VVESYNC;
+	ring->signal_mbox[BCS] = GEN6_BVESYNC;
+	ring->signal_mbox[VECS] = GEN6_NOSYNC;
 	ring->init = init_ring_common;
 
 	return intel_init_ring_buffer(dev, ring);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_ringbuffer.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_ringbuffer.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_ringbuffer.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_ringbuffer.h	2013-08-25 20:43:22.000000000 -0400
@@ -37,14 +37,25 @@ struct  intel_hw_status_page {
 #define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base))
 #define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base))
 
+enum intel_ring_hangcheck_action { wait, active, kick, hung };
+
+struct intel_ring_hangcheck {
+	bool deadlock;
+	u32 seqno;
+	u32 acthd;
+	int score;
+	enum intel_ring_hangcheck_action action;
+};
+
 struct  intel_ring_buffer {
 	const char	*name;
 	enum intel_ring_id {
 		RCS = 0x0,
 		VCS,
 		BCS,
+		VECS,
 	} id;
-#define I915_NUM_RINGS 3
+#define I915_NUM_RINGS 4
 	u32		mmio_base;
 	void		__iomem *virtual_start;
 	struct		drm_device *dev;
@@ -67,7 +78,10 @@ struct  intel_ring_buffer {
 	 */
 	u32		last_retired_head;
 
-	u32		irq_refcount;		/* protected by dev_priv->irq_lock */
+	struct {
+		u32	gt; /*  protected by dev_priv->irq_lock */
+		u32	pm; /*  protected by dev_priv->rps.lock (sucks) */
+	} irq_refcount;
 	u32		irq_enable_mask;	/* bitmask to enable ring interrupt */
 	u32		trace_irq_seqno;
 	u32		sync_seqno[I915_NUM_RINGS-1];
@@ -102,8 +116,11 @@ struct  intel_ring_buffer {
 				   struct intel_ring_buffer *to,
 				   u32 seqno);
 
-	u32		semaphore_register[3]; /*our mbox written by others */
-	u32		signal_mbox[2]; /* mboxes this ring signals to */
+	/* our mbox written by others */
+	u32		semaphore_register[I915_NUM_RINGS];
+	/* mboxes this ring signals to */
+	u32		signal_mbox[I915_NUM_RINGS];
+
 	/**
 	 * List of objects currently involved in rendering from the
 	 * ringbuffer.
@@ -127,6 +144,7 @@ struct  intel_ring_buffer {
 	 */
 	u32 outstanding_lazy_request;
 	bool gpu_caches_dirty;
+	bool fbc_dirty;
 
 	wait_queue_head_t irq_queue;
 
@@ -135,7 +153,9 @@ struct  intel_ring_buffer {
 	 */
 	bool itlb_before_ctx_switch;
 	struct i915_hw_context *default_context;
-	struct drm_i915_gem_object *last_context_obj;
+	struct i915_hw_context *last_context;
+
+	struct intel_ring_hangcheck hangcheck;
 
 	void *private;
 };
@@ -224,6 +244,7 @@ int intel_ring_invalidate_all_caches(str
 int intel_init_render_ring_buffer(struct drm_device *dev);
 int intel_init_bsd_ring_buffer(struct drm_device *dev);
 int intel_init_blt_ring_buffer(struct drm_device *dev);
+int intel_init_vebox_ring_buffer(struct drm_device *dev);
 
 u32 intel_ring_get_active_head(struct intel_ring_buffer *ring);
 void intel_ring_setup_status_page(struct intel_ring_buffer *ring);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_sdvo.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_sdvo.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_sdvo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_sdvo.c	2013-08-25 20:43:22.000000000 -0400
@@ -80,7 +80,7 @@ struct intel_sdvo {
 
 	/*
 	 * Capabilities of the SDVO device returned by
-	 * i830_sdvo_get_capabilities()
+	 * intel_sdvo_get_capabilities()
 	 */
 	struct intel_sdvo_caps caps;
 
@@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct
 		intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
 }
 
+static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
+				  struct intel_sdvo_dtd *dtd)
+{
+	return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
+		intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+}
+
 static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
 					 struct intel_sdvo_dtd *dtd)
 {
@@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing
 				     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
+static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
+					struct intel_sdvo_dtd *dtd)
+{
+	return intel_sdvo_get_timing(intel_sdvo,
+				     SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
+}
+
 static bool
 intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
 					 uint16_t clock,
@@ -1041,6 +1055,32 @@ intel_sdvo_get_preferred_input_mode(stru
 	return true;
 }
 
+static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config)
+{
+	unsigned dotclock = pipe_config->adjusted_mode.clock;
+	struct dpll *clock = &pipe_config->dpll;
+
+	/* SDVO TV has fixed PLL values depend on its clock range,
+	   this mirrors vbios setting. */
+	if (dotclock >= 100000 && dotclock < 140500) {
+		clock->p1 = 2;
+		clock->p2 = 10;
+		clock->n = 3;
+		clock->m1 = 16;
+		clock->m2 = 8;
+	} else if (dotclock >= 140500 && dotclock <= 200000) {
+		clock->p1 = 1;
+		clock->p2 = 10;
+		clock->n = 6;
+		clock->m1 = 12;
+		clock->m2 = 8;
+	} else {
+		WARN(1, "SDVO TV clock out of range: %i\n", dotclock);
+	}
+
+	pipe_config->clock_set = true;
+}
+
 static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
 				      struct intel_crtc_config *pipe_config)
 {
@@ -1066,6 +1106,7 @@ static bool intel_sdvo_compute_config(st
 		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
 							   mode,
 							   adjusted_mode);
+		pipe_config->sdvo_tv_clock = true;
 	} else if (intel_sdvo->is_lvds) {
 		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
 							     intel_sdvo->sdvo_lvds_fixed_mode))
@@ -1097,6 +1138,10 @@ static bool intel_sdvo_compute_config(st
 	if (intel_sdvo->color_range)
 		pipe_config->limited_color_range = true;
 
+	/* Clock computation needs to happen after pixel multiplier. */
+	if (intel_sdvo->is_tv)
+		i9xx_adjust_sdvo_tv_clock(pipe_config);
+
 	return true;
 }
 
@@ -1174,6 +1219,7 @@ static void intel_sdvo_mode_set(struct i
 
 	switch (intel_crtc->config.pixel_multiplier) {
 	default:
+		WARN(1, "unknown pixel mutlipler specified\n");
 	case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
 	case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
 	case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break;
@@ -1231,7 +1277,7 @@ static bool intel_sdvo_connector_get_hw_
 	struct intel_sdvo_connector *intel_sdvo_connector =
 		to_intel_sdvo_connector(&connector->base);
 	struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base);
-	u16 active_outputs;
+	u16 active_outputs = 0;
 
 	intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
 
@@ -1247,7 +1293,7 @@ static bool intel_sdvo_get_hw_state(stru
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
-	u16 active_outputs;
+	u16 active_outputs = 0;
 	u32 tmp;
 
 	tmp = I915_READ(intel_sdvo->sdvo_reg);
@@ -1264,6 +1310,74 @@ static bool intel_sdvo_get_hw_state(stru
 	return true;
 }
 
+static void intel_sdvo_get_config(struct intel_encoder *encoder,
+				  struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
+	struct intel_sdvo_dtd dtd;
+	int encoder_pixel_multiplier = 0;
+	u32 flags = 0, sdvox;
+	u8 val;
+	bool ret;
+
+	ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
+	if (!ret) {
+		/* Some sdvo encoders are not spec compliant and don't
+		 * implement the mandatory get_timings function. */
+		DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n");
+		pipe_config->quirks |= PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS;
+	} else {
+		if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
+			flags |= DRM_MODE_FLAG_PHSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NHSYNC;
+
+		if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
+			flags |= DRM_MODE_FLAG_PVSYNC;
+		else
+			flags |= DRM_MODE_FLAG_NVSYNC;
+	}
+
+	pipe_config->adjusted_mode.flags |= flags;
+
+	/*
+	 * pixel multiplier readout is tricky: Only on i915g/gm it is stored in
+	 * the sdvo port register, on all other platforms it is part of the dpll
+	 * state. Since the general pipe state readout happens before the
+	 * encoder->get_config we so already have a valid pixel multplier on all
+	 * other platfroms.
+	 */
+	if (IS_I915G(dev) || IS_I915GM(dev)) {
+		sdvox = I915_READ(intel_sdvo->sdvo_reg);
+		pipe_config->pixel_multiplier =
+			((sdvox & SDVO_PORT_MULTIPLY_MASK)
+			 >> SDVO_PORT_MULTIPLY_SHIFT) + 1;
+	}
+
+	/* Cross check the port pixel multiplier with the sdvo encoder state. */
+	intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, &val, 1);
+	switch (val) {
+	case SDVO_CLOCK_RATE_MULT_1X:
+		encoder_pixel_multiplier = 1;
+		break;
+	case SDVO_CLOCK_RATE_MULT_2X:
+		encoder_pixel_multiplier = 2;
+		break;
+	case SDVO_CLOCK_RATE_MULT_4X:
+		encoder_pixel_multiplier = 4;
+		break;
+	}
+
+	if(HAS_PCH_SPLIT(dev))
+		return; /* no pixel multiplier readout support yet */
+
+	WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier,
+	     "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n",
+	     pipe_config->pixel_multiplier, encoder_pixel_multiplier);
+}
+
 static void intel_disable_sdvo(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
@@ -1344,6 +1458,7 @@ static void intel_enable_sdvo(struct int
 	intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
 }
 
+/* Special dpms function to support cloning between dvo/sdvo/crt. */
 static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
 {
 	struct drm_crtc *crtc;
@@ -1365,6 +1480,8 @@ static void intel_sdvo_dpms(struct drm_c
 		return;
 	}
 
+	/* We set active outputs manually below in case pipe dpms doesn't change
+	 * due to cloning. */
 	if (mode != DRM_MODE_DPMS_ON) {
 		intel_sdvo_set_active_outputs(intel_sdvo, 0);
 		if (0)
@@ -1495,7 +1612,7 @@ intel_sdvo_get_analog_edid(struct drm_co
 
 	return drm_get_edid(connector,
 			    intel_gmbus_get_adapter(dev_priv,
-						    dev_priv->crt_ddc_pin));
+						    dev_priv->vbt.crt_ddc_pin));
 }
 
 static enum drm_connector_status
@@ -1625,12 +1742,9 @@ intel_sdvo_detect(struct drm_connector *
 	if (ret == connector_status_connected) {
 		intel_sdvo->is_tv = false;
 		intel_sdvo->is_lvds = false;
-		intel_sdvo->base.needs_tv_clock = false;
 
-		if (response & SDVO_TV_MASK) {
+		if (response & SDVO_TV_MASK)
 			intel_sdvo->is_tv = true;
-			intel_sdvo->base.needs_tv_clock = true;
-		}
 		if (response & SDVO_LVDS_MASK)
 			intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL;
 	}
@@ -1772,21 +1886,12 @@ static void intel_sdvo_get_lvds_modes(st
 	struct drm_display_mode *newmode;
 
 	/*
-	 * Attempt to get the mode list from DDC.
-	 * Assume that the preferred modes are
-	 * arranged in priority order.
-	 */
-	intel_ddc_get_modes(connector, &intel_sdvo->ddc);
-
-	/*
 	 * Fetch modes from VBT. For SDVO prefer the VBT mode since some
-	 * SDVO->LVDS transcoders can't cope with the EDID mode. Since
-	 * drm_mode_probed_add adds the mode at the head of the list we add it
-	 * last.
+	 * SDVO->LVDS transcoders can't cope with the EDID mode.
 	 */
-	if (dev_priv->sdvo_lvds_vbt_mode != NULL) {
+	if (dev_priv->vbt.sdvo_lvds_vbt_mode != NULL) {
 		newmode = drm_mode_duplicate(connector->dev,
-					     dev_priv->sdvo_lvds_vbt_mode);
+					     dev_priv->vbt.sdvo_lvds_vbt_mode);
 		if (newmode != NULL) {
 			/* Guarantee the mode is preferred */
 			newmode->type = (DRM_MODE_TYPE_PREFERRED |
@@ -1795,6 +1900,13 @@ static void intel_sdvo_get_lvds_modes(st
 		}
 	}
 
+	/*
+	 * Attempt to get the mode list from DDC.
+	 * Assume that the preferred modes are
+	 * arranged in priority order.
+	 */
+	intel_ddc_get_modes(connector, &intel_sdvo->ddc);
+
 	list_for_each_entry(newmode, &connector->probed_modes, head) {
 		if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
 			intel_sdvo->sdvo_lvds_fixed_mode =
@@ -2329,7 +2441,6 @@ intel_sdvo_tv_init(struct intel_sdvo *in
 	intel_sdvo_connector->output_flag = type;
 
 	intel_sdvo->is_tv = true;
-	intel_sdvo->base.needs_tv_clock = true;
 
 	intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
 
@@ -2417,7 +2528,6 @@ static bool
 intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
 {
 	intel_sdvo->is_tv = false;
-	intel_sdvo->base.needs_tv_clock = false;
 	intel_sdvo->is_lvds = false;
 
 	/* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
@@ -2751,7 +2861,6 @@ bool intel_sdvo_init(struct drm_device *
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_encoder *intel_encoder;
 	struct intel_sdvo *intel_sdvo;
-	u32 hotplug_mask;
 	int i;
 	intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL);
 	if (!intel_sdvo)
@@ -2780,23 +2889,12 @@ bool intel_sdvo_init(struct drm_device *
 		}
 	}
 
-	hotplug_mask = 0;
-	if (IS_G4X(dev)) {
-		hotplug_mask = intel_sdvo->is_sdvob ?
-			SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X;
-	} else if (IS_GEN4(dev)) {
-		hotplug_mask = intel_sdvo->is_sdvob ?
-			SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965;
-	} else {
-		hotplug_mask = intel_sdvo->is_sdvob ?
-			SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;
-	}
-
 	intel_encoder->compute_config = intel_sdvo_compute_config;
 	intel_encoder->disable = intel_disable_sdvo;
 	intel_encoder->mode_set = intel_sdvo_mode_set;
 	intel_encoder->enable = intel_enable_sdvo;
 	intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
+	intel_encoder->get_config = intel_sdvo_get_config;
 
 	/* In default case sdvo lvds is false */
 	if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_sideband.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_sideband.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_sideband.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_sideband.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,177 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ */
+
+#include "i915_drv.h"
+#include "intel_drv.h"
+
+/* IOSF sideband */
+static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
+			   u32 port, u32 opcode, u32 addr, u32 *val)
+{
+	u32 cmd, be = 0xf, bar = 0;
+	bool is_read = (opcode == PUNIT_OPCODE_REG_READ ||
+			opcode == DPIO_OPCODE_REG_READ);
+
+	cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
+		(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
+		(bar << IOSF_BAR_SHIFT);
+
+	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
+
+	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
+		DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n",
+				 is_read ? "read" : "write");
+		return -EAGAIN;
+	}
+
+	I915_WRITE(VLV_IOSF_ADDR, addr);
+	if (!is_read)
+		I915_WRITE(VLV_IOSF_DATA, *val);
+	I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
+
+	if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) {
+		DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
+				 is_read ? "read" : "write");
+		return -ETIMEDOUT;
+	}
+
+	if (is_read)
+		*val = I915_READ(VLV_IOSF_DATA);
+	I915_WRITE(VLV_IOSF_DATA, 0);
+
+	return 0;
+}
+
+u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr)
+{
+	u32 val = 0;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	mutex_lock(&dev_priv->dpio_lock);
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
+			PUNIT_OPCODE_REG_READ, addr, &val);
+	mutex_unlock(&dev_priv->dpio_lock);
+
+	return val;
+}
+
+void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
+{
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	mutex_lock(&dev_priv->dpio_lock);
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_PUNIT,
+			PUNIT_OPCODE_REG_WRITE, addr, &val);
+	mutex_unlock(&dev_priv->dpio_lock);
+}
+
+u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
+{
+	u32 val = 0;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+	mutex_lock(&dev_priv->dpio_lock);
+	vlv_sideband_rw(dev_priv, PCI_DEVFN(2, 0), IOSF_PORT_NC,
+			PUNIT_OPCODE_REG_READ, addr, &val);
+	mutex_unlock(&dev_priv->dpio_lock);
+
+	return val;
+}
+
+u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg)
+{
+	u32 val = 0;
+
+	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
+			DPIO_OPCODE_REG_READ, reg, &val);
+
+	return val;
+}
+
+void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val)
+{
+	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_DPIO,
+			DPIO_OPCODE_REG_WRITE, reg, &val);
+}
+
+/* SBI access */
+u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
+		   enum intel_sbi_destination destination)
+{
+	u32 value = 0;
+	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
+
+	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
+				100)) {
+		DRM_ERROR("timeout waiting for SBI to become ready\n");
+		return 0;
+	}
+
+	I915_WRITE(SBI_ADDR, (reg << 16));
+
+	if (destination == SBI_ICLK)
+		value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
+	else
+		value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
+	I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
+
+	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
+				100)) {
+		DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
+		return 0;
+	}
+
+	return I915_READ(SBI_DATA);
+}
+
+void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
+		     enum intel_sbi_destination destination)
+{
+	u32 tmp;
+
+	WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock));
+
+	if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
+				100)) {
+		DRM_ERROR("timeout waiting for SBI to become ready\n");
+		return;
+	}
+
+	I915_WRITE(SBI_ADDR, (reg << 16));
+	I915_WRITE(SBI_DATA, value);
+
+	if (destination == SBI_ICLK)
+		tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
+	else
+		tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
+	I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
+
+	if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
+				100)) {
+		DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
+		return;
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_sprite.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_sprite.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_sprite.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_sprite.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,7 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_fourcc.h>
+#include <drm/drm_rect.h>
 #include "intel_drv.h"
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
@@ -113,7 +114,7 @@ vlv_update_plane(struct drm_plane *dplan
 	crtc_w--;
 	crtc_h--;
 
-	intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size);
+	intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true);
 
 	I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
 	I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
@@ -267,7 +268,7 @@ ivb_update_plane(struct drm_plane *plane
 	crtc_w--;
 	crtc_h--;
 
-	intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size);
+	intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true);
 
 	/*
 	 * IVB workaround: must disable low power watermarks for at least
@@ -334,6 +335,8 @@ ivb_disable_plane(struct drm_plane *plan
 
 	dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
 
+	intel_update_sprite_watermarks(dev, pipe, 0, 0, false);
+
 	/* potentially re-enable LP watermarks */
 	if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
 		intel_update_watermarks(dev);
@@ -452,7 +455,7 @@ ilk_update_plane(struct drm_plane *plane
 	crtc_w--;
 	crtc_h--;
 
-	intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size);
+	intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size, true);
 
 	dvsscale = 0;
 	if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h)
@@ -583,6 +586,20 @@ ilk_get_colorkey(struct drm_plane *plane
 		key->flags = I915_SET_COLORKEY_NONE;
 }
 
+static bool
+format_is_yuv(uint32_t format)
+{
+	switch (format) {
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_VYUY:
+	case DRM_FORMAT_YVYU:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int
 intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 		   struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -600,9 +617,29 @@ intel_update_plane(struct drm_plane *pla
 	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
 								      pipe);
 	int ret = 0;
-	int x = src_x >> 16, y = src_y >> 16;
-	int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay;
 	bool disable_primary = false;
+	bool visible;
+	int hscale, vscale;
+	int max_scale, min_scale;
+	int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
+	struct drm_rect src = {
+		/* sample coordinates in 16.16 fixed point */
+		.x1 = src_x,
+		.x2 = src_x + src_w,
+		.y1 = src_y,
+		.y2 = src_y + src_h,
+	};
+	struct drm_rect dst = {
+		/* integer pixels */
+		.x1 = crtc_x,
+		.x2 = crtc_x + crtc_w,
+		.y1 = crtc_y,
+		.y2 = crtc_y + crtc_h,
+	};
+	const struct drm_rect clip = {
+		.x2 = crtc->mode.hdisplay,
+		.y2 = crtc->mode.vdisplay,
+	};
 
 	intel_fb = to_intel_framebuffer(fb);
 	obj = intel_fb->obj;
@@ -618,19 +655,23 @@ intel_update_plane(struct drm_plane *pla
 	intel_plane->src_w = src_w;
 	intel_plane->src_h = src_h;
 
-	src_w = src_w >> 16;
-	src_h = src_h >> 16;
-
 	/* Pipe must be running... */
-	if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE))
+	if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) {
+		DRM_DEBUG_KMS("Pipe disabled\n");
 		return -EINVAL;
+	}
 
-	if (crtc_x >= primary_w || crtc_y >= primary_h)
+	/* Don't modify another pipe's plane */
+	if (intel_plane->pipe != intel_crtc->pipe) {
+		DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
 		return -EINVAL;
+	}
 
-	/* Don't modify another pipe's plane */
-	if (intel_plane->pipe != intel_crtc->pipe)
+	/* FIXME check all gen limits */
+	if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
+		DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
 		return -EINVAL;
+	}
 
 	/* Sprite planes can be linear or x-tiled surfaces */
 	switch (obj->tiling_mode) {
@@ -638,55 +679,123 @@ intel_update_plane(struct drm_plane *pla
 		case I915_TILING_X:
 			break;
 		default:
+			DRM_DEBUG_KMS("Unsupported tiling mode\n");
 			return -EINVAL;
 	}
 
 	/*
-	 * Clamp the width & height into the visible area.  Note we don't
-	 * try to scale the source if part of the visible region is offscreen.
-	 * The caller must handle that by adjusting source offset and size.
+	 * FIXME the following code does a bunch of fuzzy adjustments to the
+	 * coordinates and sizes. We probably need some way to decide whether
+	 * more strict checking should be done instead.
 	 */
-	if ((crtc_x < 0) && ((crtc_x + crtc_w) > 0)) {
-		crtc_w += crtc_x;
-		crtc_x = 0;
-	}
-	if ((crtc_x + crtc_w) <= 0) /* Nothing to display */
-		goto out;
-	if ((crtc_x + crtc_w) > primary_w)
-		crtc_w = primary_w - crtc_x;
+	max_scale = intel_plane->max_downscale << 16;
+	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
 
-	if ((crtc_y < 0) && ((crtc_y + crtc_h) > 0)) {
-		crtc_h += crtc_y;
-		crtc_y = 0;
+	hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
+	BUG_ON(hscale < 0);
+
+	vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale);
+	BUG_ON(vscale < 0);
+
+	visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale);
+
+	crtc_x = dst.x1;
+	crtc_y = dst.y1;
+	crtc_w = drm_rect_width(&dst);
+	crtc_h = drm_rect_height(&dst);
+
+	if (visible) {
+		/* check again in case clipping clamped the results */
+		hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale);
+		if (hscale < 0) {
+			DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
+			drm_rect_debug_print(&src, true);
+			drm_rect_debug_print(&dst, false);
+
+			return hscale;
+		}
+
+		vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale);
+		if (vscale < 0) {
+			DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
+			drm_rect_debug_print(&src, true);
+			drm_rect_debug_print(&dst, false);
+
+			return vscale;
+		}
+
+		/* Make the source viewport size an exact multiple of the scaling factors. */
+		drm_rect_adjust_size(&src,
+				     drm_rect_width(&dst) * hscale - drm_rect_width(&src),
+				     drm_rect_height(&dst) * vscale - drm_rect_height(&src));
+
+		/* sanity check to make sure the src viewport wasn't enlarged */
+		WARN_ON(src.x1 < (int) src_x ||
+			src.y1 < (int) src_y ||
+			src.x2 > (int) (src_x + src_w) ||
+			src.y2 > (int) (src_y + src_h));
+
+		/*
+		 * Hardware doesn't handle subpixel coordinates.
+		 * Adjust to (macro)pixel boundary, but be careful not to
+		 * increase the source viewport size, because that could
+		 * push the downscaling factor out of bounds.
+		 */
+		src_x = src.x1 >> 16;
+		src_w = drm_rect_width(&src) >> 16;
+		src_y = src.y1 >> 16;
+		src_h = drm_rect_height(&src) >> 16;
+
+		if (format_is_yuv(fb->pixel_format)) {
+			src_x &= ~1;
+			src_w &= ~1;
+
+			/*
+			 * Must keep src and dst the
+			 * same if we can't scale.
+			 */
+			if (!intel_plane->can_scale)
+				crtc_w &= ~1;
+
+			if (crtc_w == 0)
+				visible = false;
+		}
 	}
-	if ((crtc_y + crtc_h) <= 0) /* Nothing to display */
-		goto out;
-	if (crtc_y + crtc_h > primary_h)
-		crtc_h = primary_h - crtc_y;
 
-	if (!crtc_w || !crtc_h) /* Again, nothing to display */
-		goto out;
+	/* Check size restrictions when scaling */
+	if (visible && (src_w != crtc_w || src_h != crtc_h)) {
+		unsigned int width_bytes;
 
-	/*
-	 * We may not have a scaler, eg. HSW does not have it any more
-	 */
-	if (!intel_plane->can_scale && (crtc_w != src_w || crtc_h != src_h))
-		return -EINVAL;
+		WARN_ON(!intel_plane->can_scale);
 
-	/*
-	 * We can take a larger source and scale it down, but
-	 * only so much...  16x is the max on SNB.
-	 */
-	if (((src_w * src_h) / (crtc_w * crtc_h)) > intel_plane->max_downscale)
-		return -EINVAL;
+		/* FIXME interlacing min height is 6 */
+
+		if (crtc_w < 3 || crtc_h < 3)
+			visible = false;
+
+		if (src_w < 3 || src_h < 3)
+			visible = false;
+
+		width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size;
+
+		if (src_w > 2048 || src_h > 2048 ||
+		    width_bytes > 4096 || fb->pitches[0] > 4096) {
+			DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
+			return -EINVAL;
+		}
+	}
+
+	dst.x1 = crtc_x;
+	dst.x2 = crtc_x + crtc_w;
+	dst.y1 = crtc_y;
+	dst.y2 = crtc_y + crtc_h;
 
 	/*
 	 * If the sprite is completely covering the primary plane,
 	 * we can disable the primary and save power.
 	 */
-	if ((crtc_x == 0) && (crtc_y == 0) &&
-	    (crtc_w == primary_w) && (crtc_h == primary_h))
-		disable_primary = true;
+	disable_primary = drm_rect_equals(&dst, &clip);
+	WARN_ON(disable_primary && !visible);
 
 	mutex_lock(&dev->struct_mutex);
 
@@ -708,8 +817,12 @@ intel_update_plane(struct drm_plane *pla
 	if (!disable_primary)
 		intel_enable_primary(crtc);
 
-	intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y,
-				  crtc_w, crtc_h, x, y, src_w, src_h);
+	if (visible)
+		intel_plane->update_plane(plane, fb, obj,
+					  crtc_x, crtc_y, crtc_w, crtc_h,
+					  src_x, src_y, src_w, src_h);
+	else
+		intel_plane->disable_plane(plane);
 
 	if (disable_primary)
 		intel_disable_primary(crtc);
@@ -732,7 +845,6 @@ intel_update_plane(struct drm_plane *pla
 
 out_unlock:
 	mutex_unlock(&dev->struct_mutex);
-out:
 	return ret;
 }
 
@@ -845,6 +957,14 @@ void intel_plane_restore(struct drm_plan
 			   intel_plane->src_w, intel_plane->src_h);
 }
 
+void intel_plane_disable(struct drm_plane *plane)
+{
+	if (!plane->crtc || !plane->fb)
+		return;
+
+	intel_disable_plane(plane);
+}
+
 static const struct drm_plane_funcs intel_plane_funcs = {
 	.update_plane = intel_update_plane,
 	.disable_plane = intel_disable_plane,
@@ -918,13 +1038,15 @@ intel_plane_init(struct drm_device *dev,
 		break;
 
 	case 7:
-		if (IS_HASWELL(dev) || IS_VALLEYVIEW(dev))
-			intel_plane->can_scale = false;
-		else
+		if (IS_IVYBRIDGE(dev)) {
 			intel_plane->can_scale = true;
+			intel_plane->max_downscale = 2;
+		} else {
+			intel_plane->can_scale = false;
+			intel_plane->max_downscale = 1;
+		}
 
 		if (IS_VALLEYVIEW(dev)) {
-			intel_plane->max_downscale = 1;
 			intel_plane->update_plane = vlv_update_plane;
 			intel_plane->disable_plane = vlv_disable_plane;
 			intel_plane->update_colorkey = vlv_update_colorkey;
@@ -933,7 +1055,6 @@ intel_plane_init(struct drm_device *dev,
 			plane_formats = vlv_plane_formats;
 			num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
 		} else {
-			intel_plane->max_downscale = 2;
 			intel_plane->update_plane = ivb_update_plane;
 			intel_plane->disable_plane = ivb_disable_plane;
 			intel_plane->update_colorkey = ivb_update_colorkey;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_tv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_tv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/intel_tv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/intel_tv.c	2013-08-25 20:43:22.000000000 -0400
@@ -914,9 +914,6 @@ intel_tv_compute_config(struct intel_enc
 	if (!tv_mode)
 		return false;
 
-	if (intel_encoder_check_is_cloned(&intel_tv->base))
-		return false;
-
 	pipe_config->adjusted_mode.clock = tv_mode->clock;
 	DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
 	pipe_config->pipe_bpp = 8*3;
@@ -1521,12 +1518,12 @@ static int tv_is_present_in_vbt(struct d
 	struct child_device_config *p_child;
 	int i, ret;
 
-	if (!dev_priv->child_dev_num)
+	if (!dev_priv->vbt.child_dev_num)
 		return 1;
 
 	ret = 0;
-	for (i = 0; i < dev_priv->child_dev_num; i++) {
-		p_child = dev_priv->child_dev + i;
+	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+		p_child = dev_priv->vbt.child_dev + i;
 		/*
 		 * If the device type is not TV, continue.
 		 */
@@ -1564,7 +1561,7 @@ intel_tv_init(struct drm_device *dev)
 		return;
 	}
 	/* Even if we have an encoder we may not have a connector */
-	if (!dev_priv->int_tv_support)
+	if (!dev_priv->vbt.int_tv_support)
 		return;
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/i915/Makefile linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/Makefile
--- linux-libre-3.10-gnu/drivers/gpu/drm/i915/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/i915/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq
 	  intel_overlay.o \
 	  intel_sprite.o \
 	  intel_opregion.o \
+	  intel_sideband.o \
 	  dvo_ch7xxx.o \
 	  dvo_ch7017.o \
 	  dvo_ivch.o \
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/Kconfig linux-libre-3.11-rc7-gnu/drivers/gpu/drm/Kconfig
--- linux-libre-3.10-gnu/drivers/gpu/drm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -139,6 +139,7 @@ config DRM_I915
 	select BACKLIGHT_CLASS_DEVICE if ACPI
 	select VIDEO_OUTPUT_CONTROL if ACPI
 	select INPUT if ACPI
+	select THERMAL if ACPI
 	select ACPI_VIDEO if ACPI
 	select ACPI_BUTTON if ACPI
 	help
@@ -213,6 +214,8 @@ source "drivers/gpu/drm/mgag200/Kconfig"
 
 source "drivers/gpu/drm/cirrus/Kconfig"
 
+source "drivers/gpu/drm/rcar-du/Kconfig"
+
 source "drivers/gpu/drm/shmobile/Kconfig"
 
 source "drivers/gpu/drm/omapdrm/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/Makefile linux-libre-3.11-rc7-gnu/drivers/gpu/drm/Makefile
--- linux-libre-3.10-gnu/drivers/gpu/drm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,8 @@ drm-y       :=	drm_auth.o drm_buffer.o d
 		drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
 		drm_crtc.o drm_modes.o drm_edid.o \
 		drm_info.o drm_debugfs.o drm_encoder_slave.o \
-		drm_trace_points.o drm_global.o drm_prime.o
+		drm_trace_points.o drm_global.o drm_prime.o \
+		drm_rect.o
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
@@ -48,6 +49,7 @@ obj-$(CONFIG_DRM_EXYNOS) +=exynos/
 obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
+obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
 obj-$(CONFIG_DRM_OMAP)	+= omapdrm/
 obj-$(CONFIG_DRM_TILCDC)	+= tilcdc/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/Makefile linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/Makefile
--- linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 ccflags-y := -Iinclude/drm
-mgag200-y   := mgag200_main.o mgag200_mode.o \
+mgag200-y   := mgag200_main.o mgag200_mode.o mgag200_cursor.o \
 	mgag200_drv.o mgag200_fb.o mgag200_i2c.o mgag200_ttm.o
 
 obj-$(CONFIG_DRM_MGAG200) += mgag200.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_cursor.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_cursor.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_cursor.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_cursor.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2013 Matrox Graphics
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License version 2. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * Author: Christopher Harvey <charvey@matrox.com>
+ */
+
+#include <drm/drmP.h>
+#include "mgag200_drv.h"
+
+static bool warn_transparent = true;
+static bool warn_palette = true;
+
+/*
+  Hide the cursor off screen. We can't disable the cursor hardware because it
+  takes too long to re-activate and causes momentary corruption
+*/
+static void mga_hide_cursor(struct mga_device *mdev)
+{
+	WREG8(MGA_CURPOSXL, 0);
+	WREG8(MGA_CURPOSXH, 0);
+	mgag200_bo_unpin(mdev->cursor.pixels_1);
+	mgag200_bo_unpin(mdev->cursor.pixels_2);
+}
+
+int mga_crtc_cursor_set(struct drm_crtc *crtc,
+			struct drm_file *file_priv,
+			uint32_t handle,
+			uint32_t width,
+			uint32_t height)
+{
+	struct drm_device *dev = (struct drm_device *)file_priv->minor->dev;
+	struct mga_device *mdev = (struct mga_device *)dev->dev_private;
+	struct mgag200_bo *pixels_1 = mdev->cursor.pixels_1;
+	struct mgag200_bo *pixels_2 = mdev->cursor.pixels_2;
+	struct mgag200_bo *pixels_current = mdev->cursor.pixels_current;
+	struct mgag200_bo *pixels_prev = mdev->cursor.pixels_prev;
+	struct drm_gem_object *obj;
+	struct mgag200_bo *bo = NULL;
+	int ret = 0;
+	unsigned int i, row, col;
+	uint32_t colour_set[16];
+	uint32_t *next_space = &colour_set[0];
+	uint32_t *palette_iter;
+	uint32_t this_colour;
+	bool found = false;
+	int colour_count = 0;
+	u64 gpu_addr;
+	u8 reg_index;
+	u8 this_row[48];
+
+	if (!pixels_1 || !pixels_2) {
+		WREG8(MGA_CURPOSXL, 0);
+		WREG8(MGA_CURPOSXH, 0);
+		return -ENOTSUPP; /* Didn't allocate space for cursors */
+	}
+
+	if ((width != 64 || height != 64) && handle) {
+		WREG8(MGA_CURPOSXL, 0);
+		WREG8(MGA_CURPOSXH, 0);
+		return -EINVAL;
+	}
+
+	BUG_ON(pixels_1 != pixels_current && pixels_1 != pixels_prev);
+	BUG_ON(pixels_2 != pixels_current && pixels_2 != pixels_prev);
+	BUG_ON(pixels_current == pixels_prev);
+
+	ret = mgag200_bo_reserve(pixels_1, true);
+	if (ret) {
+		WREG8(MGA_CURPOSXL, 0);
+		WREG8(MGA_CURPOSXH, 0);
+		return ret;
+	}
+	ret = mgag200_bo_reserve(pixels_2, true);
+	if (ret) {
+		WREG8(MGA_CURPOSXL, 0);
+		WREG8(MGA_CURPOSXH, 0);
+		mgag200_bo_unreserve(pixels_1);
+		return ret;
+	}
+
+	if (!handle) {
+		mga_hide_cursor(mdev);
+		ret = 0;
+		goto out1;
+	}
+
+	/* Move cursor buffers into VRAM if they aren't already */
+	if (!pixels_1->pin_count) {
+		ret = mgag200_bo_pin(pixels_1, TTM_PL_FLAG_VRAM,
+				     &mdev->cursor.pixels_1_gpu_addr);
+		if (ret)
+			goto out1;
+	}
+	if (!pixels_2->pin_count) {
+		ret = mgag200_bo_pin(pixels_2, TTM_PL_FLAG_VRAM,
+				     &mdev->cursor.pixels_2_gpu_addr);
+		if (ret) {
+			mgag200_bo_unpin(pixels_1);
+			goto out1;
+		}
+	}
+
+	mutex_lock(&dev->struct_mutex);
+	obj = drm_gem_object_lookup(dev, file_priv, handle);
+	if (!obj) {
+		mutex_unlock(&dev->struct_mutex);
+		ret = -ENOENT;
+		goto out1;
+	}
+	drm_gem_object_unreference(obj);
+	mutex_unlock(&dev->struct_mutex);
+
+	bo = gem_to_mga_bo(obj);
+	ret = mgag200_bo_reserve(bo, true);
+	if (ret) {
+		dev_err(&dev->pdev->dev, "failed to reserve user bo\n");
+		goto out1;
+	}
+	if (!bo->kmap.virtual) {
+		ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+		if (ret) {
+			dev_err(&dev->pdev->dev, "failed to kmap user buffer updates\n");
+			goto out2;
+		}
+	}
+
+	memset(&colour_set[0], 0, sizeof(uint32_t)*16);
+	/* width*height*4 = 16384 */
+	for (i = 0; i < 16384; i += 4) {
+		this_colour = ioread32(bo->kmap.virtual + i);
+		/* No transparency */
+		if (this_colour>>24 != 0xff &&
+			this_colour>>24 != 0x0) {
+			if (warn_transparent) {
+				dev_info(&dev->pdev->dev, "Video card doesn't support cursors with partial transparency.\n");
+				dev_info(&dev->pdev->dev, "Not enabling hardware cursor.\n");
+				warn_transparent = false; /* Only tell the user once. */
+			}
+			ret = -EINVAL;
+			goto out3;
+		}
+		/* Don't need to store transparent pixels as colours */
+		if (this_colour>>24 == 0x0)
+			continue;
+		found = false;
+		for (palette_iter = &colour_set[0]; palette_iter != next_space; palette_iter++) {
+			if (*palette_iter == this_colour) {
+				found = true;
+				break;
+			}
+		}
+		if (found)
+			continue;
+		/* We only support 4bit paletted cursors */
+		if (colour_count >= 16) {
+			if (warn_palette) {
+				dev_info(&dev->pdev->dev, "Video card only supports cursors with up to 16 colours.\n");
+				dev_info(&dev->pdev->dev, "Not enabling hardware cursor.\n");
+				warn_palette = false; /* Only tell the user once. */
+			}
+			ret = -EINVAL;
+			goto out3;
+		}
+		*next_space = this_colour;
+		next_space++;
+		colour_count++;
+	}
+
+	/* Program colours from cursor icon into palette */
+	for (i = 0; i < colour_count; i++) {
+		if (i <= 2)
+			reg_index = 0x8 + i*0x4;
+		else
+			reg_index = 0x60 + i*0x3;
+		WREG_DAC(reg_index, colour_set[i] & 0xff);
+		WREG_DAC(reg_index+1, colour_set[i]>>8 & 0xff);
+		WREG_DAC(reg_index+2, colour_set[i]>>16 & 0xff);
+		BUG_ON((colour_set[i]>>24 & 0xff) != 0xff);
+	}
+
+	/* Map up-coming buffer to write colour indices */
+	if (!pixels_prev->kmap.virtual) {
+		ret = ttm_bo_kmap(&pixels_prev->bo, 0,
+				  pixels_prev->bo.num_pages,
+				  &pixels_prev->kmap);
+		if (ret) {
+			dev_err(&dev->pdev->dev, "failed to kmap cursor updates\n");
+			goto out3;
+		}
+	}
+
+	/* now write colour indices into hardware cursor buffer */
+	for (row = 0; row < 64; row++) {
+		memset(&this_row[0], 0, 48);
+		for (col = 0; col < 64; col++) {
+			this_colour = ioread32(bo->kmap.virtual + 4*(col + 64*row));
+			/* write transparent pixels */
+			if (this_colour>>24 == 0x0) {
+				this_row[47 - col/8] |= 0x80>>(col%8);
+				continue;
+			}
+
+			/* write colour index here */
+			for (i = 0; i < colour_count; i++) {
+				if (colour_set[i] == this_colour) {
+					if (col % 2)
+						this_row[col/2] |= i<<4;
+					else
+						this_row[col/2] |= i;
+					break;
+				}
+			}
+		}
+		memcpy_toio(pixels_prev->kmap.virtual + row*48, &this_row[0], 48);
+	}
+
+	/* Program gpu address of cursor buffer */
+	if (pixels_prev == pixels_1)
+		gpu_addr = mdev->cursor.pixels_1_gpu_addr;
+	else
+		gpu_addr = mdev->cursor.pixels_2_gpu_addr;
+	WREG_DAC(MGA1064_CURSOR_BASE_ADR_LOW, (u8)((gpu_addr>>10) & 0xff));
+	WREG_DAC(MGA1064_CURSOR_BASE_ADR_HI, (u8)((gpu_addr>>18) & 0x3f));
+
+	/* Adjust cursor control register to turn on the cursor */
+	WREG_DAC(MGA1064_CURSOR_CTL, 4); /* 16-colour palletized cursor mode */
+
+	/* Now swap internal buffer pointers */
+	if (mdev->cursor.pixels_1 == mdev->cursor.pixels_prev) {
+		mdev->cursor.pixels_prev = mdev->cursor.pixels_2;
+		mdev->cursor.pixels_current = mdev->cursor.pixels_1;
+	} else if (mdev->cursor.pixels_1 == mdev->cursor.pixels_current) {
+		mdev->cursor.pixels_prev = mdev->cursor.pixels_1;
+		mdev->cursor.pixels_current = mdev->cursor.pixels_2;
+	} else {
+		BUG();
+	}
+	ret = 0;
+
+	ttm_bo_kunmap(&pixels_prev->kmap);
+ out3:
+	ttm_bo_kunmap(&bo->kmap);
+ out2:
+	mgag200_bo_unreserve(bo);
+ out1:
+	if (ret)
+		mga_hide_cursor(mdev);
+	mgag200_bo_unreserve(pixels_1);
+	mgag200_bo_unreserve(pixels_2);
+	return ret;
+}
+
+int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct mga_device *mdev = (struct mga_device *)crtc->dev->dev_private;
+	/* Our origin is at (64,64) */
+	x += 64;
+	y += 64;
+
+	BUG_ON(x <= 0);
+	BUG_ON(y <= 0);
+	BUG_ON(x & ~0xffff);
+	BUG_ON(y & ~0xffff);
+
+	WREG8(MGA_CURPOSXL, x & 0xff);
+	WREG8(MGA_CURPOSXH, (x>>8) & 0xff);
+
+	WREG8(MGA_CURPOSYL, y & 0xff);
+	WREG8(MGA_CURPOSYH, (y>>8) & 0xff);
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -149,6 +149,21 @@ struct mga_connector {
 	struct mga_i2c_chan *i2c;
 };
 
+struct mga_cursor {
+	/*
+	   We have to have 2 buffers for the cursor to avoid occasional
+	   corruption while switching cursor icons.
+	   If either of these is NULL, then don't do hardware cursors, and
+	   fall back to software.
+	*/
+	struct mgag200_bo *pixels_1;
+	struct mgag200_bo *pixels_2;
+	u64 pixels_1_gpu_addr, pixels_2_gpu_addr;
+	/* The currently displayed icon, this points to one of pixels_1, or pixels_2 */
+	struct mgag200_bo *pixels_current;
+	/* The previously displayed icon */
+	struct mgag200_bo *pixels_prev;
+};
 
 struct mga_mc {
 	resource_size_t			vram_size;
@@ -181,6 +196,7 @@ struct mga_device {
 	struct mga_mode_info		mode_info;
 
 	struct mga_fbdev *mfbdev;
+	struct mga_cursor cursor;
 
 	bool				suspended;
 	int				num_crtc;
@@ -198,7 +214,8 @@ struct mga_device {
 		struct ttm_bo_device bdev;
 	} ttm;
 
-	u32 reg_1e24; /* SE model number */
+	/* SE model number stored in reg 0x1e24 */
+	u32 unique_rev_id;
 };
 
 
@@ -263,8 +280,24 @@ void mgag200_i2c_destroy(struct mga_i2c_
 #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
 void mgag200_ttm_placement(struct mgag200_bo *bo, int domain);
 
-int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait);
-void mgag200_bo_unreserve(struct mgag200_bo *bo);
+static inline int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait)
+{
+	int ret;
+
+	ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
+	if (ret) {
+		if (ret != -ERESTARTSYS && ret != -EBUSY)
+			DRM_ERROR("reserve failed %p\n", bo);
+		return ret;
+	}
+	return 0;
+}
+
+static inline void mgag200_bo_unreserve(struct mgag200_bo *bo)
+{
+	ttm_bo_unreserve(&bo->bo);
+}
+
 int mgag200_bo_create(struct drm_device *dev, int size, int align,
 		      uint32_t flags, struct mgag200_bo **pastbo);
 int mgag200_mm_init(struct mga_device *mdev);
@@ -273,4 +306,9 @@ int mgag200_mmap(struct file *filp, stru
 int mgag200_bo_pin(struct mgag200_bo *bo, u32 pl_flag, u64 *gpu_addr);
 int mgag200_bo_unpin(struct mgag200_bo *bo);
 int mgag200_bo_push_sysram(struct mgag200_bo *bo);
+			   /* mgag200_cursor.c */
+int mga_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
+						uint32_t handle, uint32_t width, uint32_t height);
+int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
+
 #endif				/* __MGAG200_DRV_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_fb.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_fb.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_fb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_fb.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@ static void mga_dirty_update(struct mga_
 	struct mgag200_bo *bo;
 	int src_offset, dst_offset;
 	int bpp = (mfbdev->mfb.base.bits_per_pixel + 7)/8;
-	int ret;
+	int ret = -EBUSY;
 	bool unmap = false;
 	bool store_for_later = false;
 	int x2, y2;
@@ -41,7 +41,8 @@ static void mga_dirty_update(struct mga_
 	 * then the BO is being moved and we should
 	 * store up the damage until later.
 	 */
-	ret = mgag200_bo_reserve(bo, true);
+	if (!in_interrupt())
+		ret = mgag200_bo_reserve(bo, true);
 	if (ret) {
 		if (ret != -EBUSY)
 			return;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_main.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_main.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -176,7 +176,7 @@ static int mgag200_device_init(struct dr
 
 	/* stash G200 SE model number for later use */
 	if (IS_G200_SE(mdev))
-		mdev->reg_1e24 = RREG32(0x1e24);
+		mdev->unique_rev_id = RREG32(0x1e24);
 
 	ret = mga_vram_init(mdev);
 	if (ret)
@@ -209,7 +209,7 @@ int mgag200_driver_load(struct drm_devic
 	r = mgag200_device_init(dev, flags);
 	if (r) {
 		dev_err(&dev->pdev->dev, "Fatal error during GPU init: %d\n", r);
-		goto out;
+		return r;
 	}
 	r = mgag200_mm_init(mdev);
 	if (r)
@@ -221,8 +221,27 @@ int mgag200_driver_load(struct drm_devic
 	dev->mode_config.prefer_shadow = 1;
 
 	r = mgag200_modeset_init(mdev);
-	if (r)
+	if (r) {
 		dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r);
+		goto out;
+	}
+
+	/* Make small buffers to store a hardware cursor (double buffered icon updates) */
+	mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0,
+					  &mdev->cursor.pixels_1);
+	mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0,
+					  &mdev->cursor.pixels_2);
+	if (!mdev->cursor.pixels_2 || !mdev->cursor.pixels_1)
+		goto cursor_nospace;
+	mdev->cursor.pixels_current = mdev->cursor.pixels_1;
+	mdev->cursor.pixels_prev = mdev->cursor.pixels_2;
+	goto cursor_done;
+ cursor_nospace:
+	mdev->cursor.pixels_1 = NULL;
+	mdev->cursor.pixels_2 = NULL;
+	dev_warn(&dev->pdev->dev, "Could not allocate space for cursors. Not doing hardware cursors.\n");
+ cursor_done:
+
 out:
 	if (r)
 		mgag200_driver_unload(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_mode.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_mode.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_mode.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_mode.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,7 @@ static void mga_crtc_load_lut(struct drm
 	struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct mga_device *mdev = dev->dev_private;
+	struct drm_framebuffer *fb = crtc->fb;
 	int i;
 
 	if (!crtc->enabled)
@@ -36,6 +37,28 @@ static void mga_crtc_load_lut(struct drm
 
 	WREG8(DAC_INDEX + MGA1064_INDEX, 0);
 
+	if (fb && fb->bits_per_pixel == 16) {
+		int inc = (fb->depth == 15) ? 8 : 4;
+		u8 r, b;
+		for (i = 0; i < MGAG200_LUT_SIZE; i += inc) {
+			if (fb->depth == 16) {
+				if (i > (MGAG200_LUT_SIZE >> 1)) {
+					r = b = 0;
+				} else {
+					r = mga_crtc->lut_r[i << 1];
+					b = mga_crtc->lut_b[i << 1];
+				}
+			} else {
+				r = mga_crtc->lut_r[i];
+				b = mga_crtc->lut_b[i];
+			}
+			/* VGA registers */
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, r);
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]);
+			WREG8(DAC_INDEX + MGA1064_COL_PAL, b);
+		}
+		return;
+	}
 	for (i = 0; i < MGAG200_LUT_SIZE; i++) {
 		/* VGA registers */
 		WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_r[i]);
@@ -877,7 +900,7 @@ static int mga_crtc_mode_set(struct drm_
 
 	pitch = crtc->fb->pitches[0] / (crtc->fb->bits_per_pixel / 8);
 	if (crtc->fb->bits_per_pixel == 24)
-		pitch = pitch >> (4 - bppshift);
+		pitch = (pitch * 3) >> (4 - bppshift);
 	else
 		pitch = pitch >> (4 - bppshift);
 
@@ -1008,7 +1031,7 @@ static int mga_crtc_mode_set(struct drm_
 
 
 	if (IS_G200_SE(mdev)) {
-		if (mdev->reg_1e24 >= 0x02) {
+		if (mdev->unique_rev_id >= 0x02) {
 			u8 hi_pri_lvl;
 			u32 bpp;
 			u32 mb;
@@ -1038,7 +1061,7 @@ static int mga_crtc_mode_set(struct drm_
 			WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl);
 		} else {
 			WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
-			if (mdev->reg_1e24 >= 0x01)
+			if (mdev->unique_rev_id >= 0x01)
 				WREG8(MGAREG_CRTCEXT_DATA, 0x03);
 			else
 				WREG8(MGAREG_CRTCEXT_DATA, 0x04);
@@ -1251,14 +1274,35 @@ static void mga_crtc_destroy(struct drm_
 	kfree(mga_crtc);
 }
 
+static void mga_crtc_disable(struct drm_crtc *crtc)
+{
+	int ret;
+	DRM_DEBUG_KMS("\n");
+	mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+	if (crtc->fb) {
+		struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->fb);
+		struct drm_gem_object *obj = mga_fb->obj;
+		struct mgag200_bo *bo = gem_to_mga_bo(obj);
+		ret = mgag200_bo_reserve(bo, false);
+		if (ret)
+			return;
+		mgag200_bo_push_sysram(bo);
+		mgag200_bo_unreserve(bo);
+	}
+	crtc->fb = NULL;
+}
+
 /* These provide the minimum set of functions required to handle a CRTC */
 static const struct drm_crtc_funcs mga_crtc_funcs = {
+	.cursor_set = mga_crtc_cursor_set,
+	.cursor_move = mga_crtc_cursor_move,
 	.gamma_set = mga_crtc_gamma_set,
 	.set_config = drm_crtc_helper_set_config,
 	.destroy = mga_crtc_destroy,
 };
 
 static const struct drm_crtc_helper_funcs mga_helper_funcs = {
+	.disable = mga_crtc_disable,
 	.dpms = mga_crtc_dpms,
 	.mode_fixup = mga_crtc_mode_fixup,
 	.mode_set = mga_crtc_mode_set,
@@ -1410,6 +1454,32 @@ static int mga_vga_get_modes(struct drm_
 	return ret;
 }
 
+static uint32_t mga_vga_calculate_mode_bandwidth(struct drm_display_mode *mode,
+							int bits_per_pixel)
+{
+	uint32_t total_area, divisor;
+	int64_t active_area, pixels_per_second, bandwidth;
+	uint64_t bytes_per_pixel = (bits_per_pixel + 7) / 8;
+
+	divisor = 1024;
+
+	if (!mode->htotal || !mode->vtotal || !mode->clock)
+		return 0;
+
+	active_area = mode->hdisplay * mode->vdisplay;
+	total_area = mode->htotal * mode->vtotal;
+
+	pixels_per_second = active_area * mode->clock * 1000;
+	do_div(pixels_per_second, total_area);
+
+	bandwidth = pixels_per_second * bytes_per_pixel * 100;
+	do_div(bandwidth, divisor);
+
+	return (uint32_t)(bandwidth);
+}
+
+#define MODE_BANDWIDTH	MODE_BAD
+
 static int mga_vga_mode_valid(struct drm_connector *connector,
 				 struct drm_display_mode *mode)
 {
@@ -1421,7 +1491,45 @@ static int mga_vga_mode_valid(struct drm
 	int bpp = 32;
 	int i = 0;
 
-	/* FIXME: Add bandwidth and g200se limitations */
+	if (IS_G200_SE(mdev)) {
+		if (mdev->unique_rev_id == 0x01) {
+			if (mode->hdisplay > 1600)
+				return MODE_VIRTUAL_X;
+			if (mode->vdisplay > 1200)
+				return MODE_VIRTUAL_Y;
+			if (mga_vga_calculate_mode_bandwidth(mode, bpp)
+				> (24400 * 1024))
+				return MODE_BANDWIDTH;
+		} else if (mdev->unique_rev_id >= 0x02) {
+			if (mode->hdisplay > 1920)
+				return MODE_VIRTUAL_X;
+			if (mode->vdisplay > 1200)
+				return MODE_VIRTUAL_Y;
+			if (mga_vga_calculate_mode_bandwidth(mode, bpp)
+				> (30100 * 1024))
+				return MODE_BANDWIDTH;
+		}
+	} else if (mdev->type == G200_WB) {
+		if (mode->hdisplay > 1280)
+			return MODE_VIRTUAL_X;
+		if (mode->vdisplay > 1024)
+			return MODE_VIRTUAL_Y;
+		if (mga_vga_calculate_mode_bandwidth(mode,
+			bpp > (31877 * 1024)))
+			return MODE_BANDWIDTH;
+	} else if (mdev->type == G200_EV &&
+		(mga_vga_calculate_mode_bandwidth(mode, bpp)
+			> (32700 * 1024))) {
+		return MODE_BANDWIDTH;
+	} else if (mode->type == G200_EH &&
+		(mga_vga_calculate_mode_bandwidth(mode, bpp)
+			> (37500 * 1024))) {
+		return MODE_BANDWIDTH;
+	} else if (mode->type == G200_ER &&
+		(mga_vga_calculate_mode_bandwidth(mode,
+			bpp) > (55000 * 1024))) {
+		return MODE_BANDWIDTH;
+	}
 
 	if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
 	    mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||
@@ -1515,6 +1623,8 @@ static struct drm_connector *mga_vga_ini
 
 	drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
 
+	drm_sysfs_connector_add(connector);
+
 	mga_connector->i2c = mgag200_i2c_create(dev);
 	if (!mga_connector->i2c)
 		DRM_ERROR("failed to add ddc bus\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_reg.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_reg.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -235,7 +235,11 @@
 #define MGAREG_CRTCEXT_INDEX	0x1fde
 #define MGAREG_CRTCEXT_DATA	0x1fdf
 
-
+/* Cursor X and Y position */
+#define MGA_CURPOSXL 0x3c0c
+#define MGA_CURPOSXH 0x3c0d
+#define MGA_CURPOSYL 0x3c0e
+#define MGA_CURPOSYH 0x3c0f
 
 /* MGA bits for registers PCI_OPTION_REG */
 #define MGA1064_OPT_SYS_CLK_PCI   		( 0x00 << 0 )
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_ttm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_ttm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/mgag200/mgag200_ttm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/mgag200/mgag200_ttm.c	2013-08-25 20:43:22.000000000 -0400
@@ -270,26 +270,20 @@ int mgag200_mm_init(struct mga_device *m
 		return ret;
 	}
 
-	mdev->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
-				    pci_resource_len(dev->pdev, 0),
-				    DRM_MTRR_WC);
+	mdev->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0),
+					 pci_resource_len(dev->pdev, 0));
 
 	return 0;
 }
 
 void mgag200_mm_fini(struct mga_device *mdev)
 {
-	struct drm_device *dev = mdev->dev;
 	ttm_bo_device_release(&mdev->ttm.bdev);
 
 	mgag200_ttm_global_release(mdev);
 
-	if (mdev->fb_mtrr >= 0) {
-		drm_mtrr_del(mdev->fb_mtrr,
-			     pci_resource_start(dev->pdev, 0),
-			     pci_resource_len(dev->pdev, 0), DRM_MTRR_WC);
-		mdev->fb_mtrr = -1;
-	}
+	arch_phys_wc_del(mdev->fb_mtrr);
+	mdev->fb_mtrr = 0;
 }
 
 void mgag200_ttm_placement(struct mgag200_bo *bo, int domain)
@@ -309,24 +303,6 @@ void mgag200_ttm_placement(struct mgag20
 	bo->placement.num_busy_placement = c;
 }
 
-int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait)
-{
-	int ret;
-
-	ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, 0);
-	if (ret) {
-		if (ret != -ERESTARTSYS && ret != -EBUSY)
-			DRM_ERROR("reserve failed %p %d\n", bo, ret);
-		return ret;
-	}
-	return 0;
-}
-
-void mgag200_bo_unreserve(struct mgag200_bo *bo)
-{
-	ttm_bo_unreserve(&bo->bo);
-}
-
 int mgag200_bo_create(struct drm_device *dev, int size, int align,
 		  uint32_t flags, struct mgag200_bo **pmgabo)
 {
@@ -347,6 +323,7 @@ int mgag200_bo_create(struct drm_device
 
 	mgabo->gem.driver_private = NULL;
 	mgabo->bo.bdev = &mdev->ttm.bdev;
+	mgabo->bo.bdev->dev_mapping = dev->dev_mapping;
 
 	mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
 
@@ -377,6 +354,7 @@ int mgag200_bo_pin(struct mgag200_bo *bo
 		bo->pin_count++;
 		if (gpu_addr)
 			*gpu_addr = mgag200_bo_gpu_offset(bo);
+		return 0;
 	}
 
 	mgag200_ttm_placement(bo, pl_flag);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/core/falcon.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/core/falcon.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/core/falcon.c	2013-07-01 10:31:59.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/core/falcon.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,250 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 <core/falcon.h>
-
-#include <subdev/timer.h>
-
-u32
-_nouveau_falcon_rd32(struct nouveau_object *object, u64 addr)
-{
-	struct nouveau_falcon *falcon = (void *)object;
-	return nv_rd32(falcon, falcon->addr + addr);
-}
-
-void
-_nouveau_falcon_wr32(struct nouveau_object *object, u64 addr, u32 data)
-{
-	struct nouveau_falcon *falcon = (void *)object;
-	nv_wr32(falcon, falcon->addr + addr, data);
-}
-
-int
-_nouveau_falcon_init(struct nouveau_object *object)
-{
-	struct nouveau_device *device = nv_device(object);
-	struct nouveau_falcon *falcon = (void *)object;
-	const struct firmware *fw;
-	char name[32] = "internal";
-	int ret, i;
-	u32 caps;
-
-	/* enable engine, and determine its capabilities */
-	ret = nouveau_engine_init(&falcon->base);
-	if (ret)
-		return ret;
-
-	if (device->chipset <  0xa3 ||
-	    device->chipset == 0xaa || device->chipset == 0xac) {
-		falcon->version = 0;
-		falcon->secret  = (falcon->addr == 0x087000) ? 1 : 0;
-	} else {
-		caps = nv_ro32(falcon, 0x12c);
-		falcon->version = (caps & 0x0000000f);
-		falcon->secret  = (caps & 0x00000030) >> 4;
-	}
-
-	caps = nv_ro32(falcon, 0x108);
-	falcon->code.limit = (caps & 0x000001ff) << 8;
-	falcon->data.limit = (caps & 0x0003fe00) >> 1;
-
-	nv_debug(falcon, "falcon version: %d\n", falcon->version);
-	nv_debug(falcon, "secret level: %d\n", falcon->secret);
-	nv_debug(falcon, "code limit: %d\n", falcon->code.limit);
-	nv_debug(falcon, "data limit: %d\n", falcon->data.limit);
-
-	/* wait for 'uc halted' to be signalled before continuing */
-	if (falcon->secret && falcon->version < 4) {
-		if (!falcon->version)
-			nv_wait(falcon, 0x008, 0x00000010, 0x00000010);
-		else
-			nv_wait(falcon, 0x180, 0x80000000, 0);
-		nv_wo32(falcon, 0x004, 0x00000010);
-	}
-
-	/* disable all interrupts */
-	nv_wo32(falcon, 0x014, 0xffffffff);
-
-	/* no default ucode provided by the engine implementation, try and
-	 * locate a "self-bootstrapping" firmware image for the engine
-	 */
-	if (!falcon->code.data) {
-		snprintf(name, sizeof(name), "/*(DEBLOBBED)*/",
-			 device->chipset, falcon->addr >> 12);
-
-		ret = reject_firmware(&fw, name, &device->pdev->dev);
-		if (ret == 0) {
-			falcon->code.data = kmemdup(fw->data, fw->size, GFP_KERNEL);
-			falcon->code.size = fw->size;
-			falcon->data.data = NULL;
-			falcon->data.size = 0;
-			release_firmware(fw);
-		}
-
-		falcon->external = true;
-	}
-
-	/* next step is to try and load "static code/data segment" firmware
-	 * images for the engine
-	 */
-	if (!falcon->code.data) {
-		snprintf(name, sizeof(name), "/*(DEBLOBBED)*/",
-			 device->chipset, falcon->addr >> 12);
-
-		ret = reject_firmware(&fw, name, &device->pdev->dev);
-		if (ret) {
-			nv_error(falcon, "unable to load firmware data\n");
-			return ret;
-		}
-
-		falcon->data.data = kmemdup(fw->data, fw->size, GFP_KERNEL);
-		falcon->data.size = fw->size;
-		release_firmware(fw);
-		if (!falcon->data.data)
-			return -ENOMEM;
-
-		snprintf(name, sizeof(name), "/*(DEBLOBBED)*/",
-			 device->chipset, falcon->addr >> 12);
-
-		ret = reject_firmware(&fw, name, &device->pdev->dev);
-		if (ret) {
-			nv_error(falcon, "unable to load firmware code\n");
-			return ret;
-		}
-
-		falcon->code.data = kmemdup(fw->data, fw->size, GFP_KERNEL);
-		falcon->code.size = fw->size;
-		release_firmware(fw);
-		if (!falcon->code.data)
-			return -ENOMEM;
-	}
-
-	nv_debug(falcon, "firmware: %s (%s)\n", name, falcon->data.data ?
-		 "static code/data segments" : "self-bootstrapping");
-
-	/* ensure any "self-bootstrapping" firmware image is in vram */
-	if (!falcon->data.data && !falcon->core) {
-		ret = nouveau_gpuobj_new(object->parent, NULL,
-					 falcon->code.size, 256, 0,
-					&falcon->core);
-		if (ret) {
-			nv_error(falcon, "core allocation failed, %d\n", ret);
-			return ret;
-		}
-
-		for (i = 0; i < falcon->code.size; i += 4)
-			nv_wo32(falcon->core, i, falcon->code.data[i / 4]);
-	}
-
-	/* upload firmware bootloader (or the full code segments) */
-	if (falcon->core) {
-		if (device->card_type < NV_C0)
-			nv_wo32(falcon, 0x618, 0x04000000);
-		else
-			nv_wo32(falcon, 0x618, 0x00000114);
-		nv_wo32(falcon, 0x11c, 0);
-		nv_wo32(falcon, 0x110, falcon->core->addr >> 8);
-		nv_wo32(falcon, 0x114, 0);
-		nv_wo32(falcon, 0x118, 0x00006610);
-	} else {
-		if (falcon->code.size > falcon->code.limit ||
-		    falcon->data.size > falcon->data.limit) {
-			nv_error(falcon, "ucode exceeds falcon limit(s)\n");
-			return -EINVAL;
-		}
-
-		if (falcon->version < 3) {
-			nv_wo32(falcon, 0xff8, 0x00100000);
-			for (i = 0; i < falcon->code.size / 4; i++)
-				nv_wo32(falcon, 0xff4, falcon->code.data[i]);
-		} else {
-			nv_wo32(falcon, 0x180, 0x01000000);
-			for (i = 0; i < falcon->code.size / 4; i++) {
-				if ((i & 0x3f) == 0)
-					nv_wo32(falcon, 0x188, i >> 6);
-				nv_wo32(falcon, 0x184, falcon->code.data[i]);
-			}
-		}
-	}
-
-	/* upload data segment (if necessary), zeroing the remainder */
-	if (falcon->version < 3) {
-		nv_wo32(falcon, 0xff8, 0x00000000);
-		for (i = 0; !falcon->core && i < falcon->data.size / 4; i++)
-			nv_wo32(falcon, 0xff4, falcon->data.data[i]);
-		for (; i < falcon->data.limit; i += 4)
-			nv_wo32(falcon, 0xff4, 0x00000000);
-	} else {
-		nv_wo32(falcon, 0x1c0, 0x01000000);
-		for (i = 0; !falcon->core && i < falcon->data.size / 4; i++)
-			nv_wo32(falcon, 0x1c4, falcon->data.data[i]);
-		for (; i < falcon->data.limit / 4; i++)
-			nv_wo32(falcon, 0x1c4, 0x00000000);
-	}
-
-	/* start it running */
-	nv_wo32(falcon, 0x10c, 0x00000001); /* BLOCK_ON_FIFO */
-	nv_wo32(falcon, 0x104, 0x00000000); /* ENTRY */
-	nv_wo32(falcon, 0x100, 0x00000002); /* TRIGGER */
-	nv_wo32(falcon, 0x048, 0x00000003); /* FIFO | CHSW */
-	return 0;
-}
-
-int
-_nouveau_falcon_fini(struct nouveau_object *object, bool suspend)
-{
-	struct nouveau_falcon *falcon = (void *)object;
-
-	if (!suspend) {
-		nouveau_gpuobj_ref(NULL, &falcon->core);
-		if (falcon->external) {
-			kfree(falcon->data.data);
-			kfree(falcon->code.data);
-			falcon->code.data = NULL;
-		}
-	}
-
-	nv_mo32(falcon, 0x048, 0x00000003, 0x00000000);
-	nv_wo32(falcon, 0x014, 0xffffffff);
-
-	return nouveau_engine_fini(&falcon->base, suspend);
-}
-
-int
-nouveau_falcon_create_(struct nouveau_object *parent,
-		       struct nouveau_object *engine,
-		       struct nouveau_oclass *oclass, u32 addr, bool enable,
-		       const char *iname, const char *fname,
-		       int length, void **pobject)
-{
-	struct nouveau_falcon *falcon;
-	int ret;
-
-	ret = nouveau_engine_create_(parent, engine, oclass, enable, iname,
-				     fname, length, pobject);
-	falcon = *pobject;
-	if (ret)
-		return ret;
-
-	falcon->addr = addr;
-	return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/core/mm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/core/mm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/core/mm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/core/mm.c	2013-08-25 20:43:22.000000000 -0400
@@ -98,6 +98,8 @@ nouveau_mm_head(struct nouveau_mm *mm, u
 	u32 splitoff;
 	u32 s, e;
 
+	BUG_ON(!type);
+
 	list_for_each_entry(this, &mm->free, fl_entry) {
 		e = this->offset + this->length;
 		s = this->offset;
@@ -162,6 +164,8 @@ nouveau_mm_tail(struct nouveau_mm *mm, u
 	struct nouveau_mm_node *prev, *this, *next;
 	u32 mask = align - 1;
 
+	BUG_ON(!type);
+
 	list_for_each_entry_reverse(this, &mm->free, fl_entry) {
 		u32 e = this->offset + this->length;
 		u32 s = this->offset;
@@ -208,7 +212,6 @@ nouveau_mm_init(struct nouveau_mm *mm, u
 	struct nouveau_mm_node *node;
 
 	if (block) {
-		mutex_init(&mm->mutex);
 		INIT_LIST_HEAD(&mm->nodes);
 		INIT_LIST_HEAD(&mm->free);
 		mm->block_size = block;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nv84.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,24 +19,19 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs, Ilia Mirkin
  */
 
-#include <core/engctx.h>
-#include <core/class.h>
-
+#include <engine/xtensa.h>
 #include <engine/bsp.h>
 
-struct nv84_bsp_priv {
-	struct nouveau_engine base;
-};
-
 /*******************************************************************************
  * BSP object classes
  ******************************************************************************/
 
 static struct nouveau_oclass
 nv84_bsp_sclass[] = {
+	{ 0x74b0, &nouveau_object_ofuncs },
 	{},
 };
 
@@ -48,7 +43,7 @@ static struct nouveau_oclass
 nv84_bsp_cclass = {
 	.handle = NV_ENGCTX(BSP, 0x84),
 	.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = _nouveau_engctx_ctor,
+		.ctor = _nouveau_xtensa_engctx_ctor,
 		.dtor = _nouveau_engctx_dtor,
 		.init = _nouveau_engctx_init,
 		.fini = _nouveau_engctx_fini,
@@ -66,10 +61,10 @@ nv84_bsp_ctor(struct nouveau_object *par
 	      struct nouveau_oclass *oclass, void *data, u32 size,
 	      struct nouveau_object **pobject)
 {
-	struct nv84_bsp_priv *priv;
+	struct nouveau_xtensa *priv;
 	int ret;
 
-	ret = nouveau_engine_create(parent, engine, oclass, true,
+	ret = nouveau_xtensa_create(parent, engine, oclass, 0x103000, true,
 				    "PBSP", "bsp", &priv);
 	*pobject = nv_object(priv);
 	if (ret)
@@ -78,6 +73,8 @@ nv84_bsp_ctor(struct nouveau_object *par
 	nv_subdev(priv)->unit = 0x04008000;
 	nv_engine(priv)->cclass = &nv84_bsp_cclass;
 	nv_engine(priv)->sclass = nv84_bsp_sclass;
+	priv->fifo_val = 0x1111;
+	priv->unkd28 = 0x90044;
 	return 0;
 }
 
@@ -86,8 +83,10 @@ nv84_bsp_oclass = {
 	.handle = NV_ENGINE(BSP, 0x84),
 	.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nv84_bsp_ctor,
-		.dtor = _nouveau_engine_dtor,
-		.init = _nouveau_engine_init,
-		.fini = _nouveau_engine_fini,
+		.dtor = _nouveau_xtensa_dtor,
+		.init = _nouveau_xtensa_init,
+		.fini = _nouveau_xtensa_fini,
+		.rd32 = _nouveau_xtensa_rd32,
+		.wr32 = _nouveau_xtensa_wr32,
 	},
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/engctx.h>
+#include <core/class.h>
+
+#include <engine/bsp.h>
+
+struct nv98_bsp_priv {
+	struct nouveau_engine base;
+};
+
+/*******************************************************************************
+ * BSP object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_bsp_sclass[] = {
+	{},
+};
+
+/*******************************************************************************
+ * BSP context
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_bsp_cclass = {
+	.handle = NV_ENGCTX(BSP, 0x98),
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = _nouveau_engctx_ctor,
+		.dtor = _nouveau_engctx_dtor,
+		.init = _nouveau_engctx_init,
+		.fini = _nouveau_engctx_fini,
+		.rd32 = _nouveau_engctx_rd32,
+		.wr32 = _nouveau_engctx_wr32,
+	},
+};
+
+/*******************************************************************************
+ * BSP engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv98_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+	      struct nouveau_oclass *oclass, void *data, u32 size,
+	      struct nouveau_object **pobject)
+{
+	struct nv98_bsp_priv *priv;
+	int ret;
+
+	ret = nouveau_engine_create(parent, engine, oclass, true,
+				    "PBSP", "bsp", &priv);
+	*pobject = nv_object(priv);
+	if (ret)
+		return ret;
+
+	nv_subdev(priv)->unit = 0x04008000;
+	nv_engine(priv)->cclass = &nv98_bsp_cclass;
+	nv_engine(priv)->sclass = nv98_bsp_sclass;
+	return 0;
+}
+
+struct nouveau_oclass
+nv98_bsp_oclass = {
+	.handle = NV_ENGINE(BSP, 0x98),
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv98_bsp_ctor,
+		.dtor = _nouveau_engine_dtor,
+		.init = _nouveau_engine_init,
+		.fini = _nouveau_engine_fini,
+	},
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,8 +22,7 @@
  * Authors: Maarten Lankhorst
  */
 
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
 #include <engine/bsp.h>
 
 struct nvc0_bsp_priv {
@@ -91,6 +90,7 @@ nvc0_bsp_ctor(struct nouveau_object *par
 		return ret;
 
 	nv_subdev(priv)->unit = 0x00008000;
+	nv_subdev(priv)->intr = nouveau_falcon_intr;
 	nv_engine(priv)->cclass = &nvc0_bsp_cclass;
 	nv_engine(priv)->sclass = nvc0_bsp_sclass;
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,8 +22,7 @@
  * Authors: Ben Skeggs
  */
 
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
 #include <engine/bsp.h>
 
 struct nve0_bsp_priv {
@@ -91,6 +90,7 @@ nve0_bsp_ctor(struct nouveau_object *par
 		return ret;
 
 	nv_subdev(priv)->unit = 0x00008000;
+	nv_subdev(priv)->intr = nouveau_falcon_intr;
 	nv_engine(priv)->cclass = &nve0_bsp_cclass;
 	nv_engine(priv)->sclass = nve0_bsp_sclass;
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nva3.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-static u32 nva3_pcopy_data[] = {
+uint32_t nva3_pcopy_data[] = {
 /* 0x0000: ctx_object */
 	0x00000000,
 /* 0x0004: ctx_dma */
@@ -183,7 +183,7 @@ static u32 nva3_pcopy_data[] = {
 	0x00000800,
 };
 
-static u32 nva3_pcopy_code[] = {
+uint32_t nva3_pcopy_code[] = {
 /* 0x0000: main */
 	0x04fe04bd,
 	0x3517f000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/fuc/nvc0.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-static u32 nvc0_pcopy_data[] = {
+uint32_t nvc0_pcopy_data[] = {
 /* 0x0000: ctx_object */
 	0x00000000,
 /* 0x0004: ctx_query_address_high */
@@ -171,7 +171,7 @@ static u32 nvc0_pcopy_data[] = {
 	0x00000800,
 };
 
-static u32 nvc0_pcopy_code[] = {
+uint32_t nvc0_pcopy_code[] = {
 /* 0x0000: main */
 	0x04fe04bd,
 	0x3517f000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,16 +22,17 @@
  * Authors: Ben Skeggs
  */
 
-#include <core/client.h>
-#include <core/falcon.h>
-#include <core/class.h>
-#include <core/enum.h>
+#include <engine/falcon.h>
+#include <engine/fifo.h>
+#include <engine/copy.h>
 
 #include <subdev/fb.h>
 #include <subdev/vm.h>
 
-#include <engine/fifo.h>
-#include <engine/copy.h>
+#include <core/client.h>
+#include <core/class.h>
+#include <core/enum.h>
+
 
 #include "fuc/nva3.fuc.h"
 
@@ -117,13 +118,6 @@ nva3_copy_intr(struct nouveau_subdev *su
 }
 
 static int
-nva3_copy_tlb_flush(struct nouveau_engine *engine)
-{
-	nv50_vm_flush_engine(&engine->base, 0x0d);
-	return 0;
-}
-
-static int
 nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	       struct nouveau_oclass *oclass, void *data, u32 size,
 	       struct nouveau_object **pobject)
@@ -142,7 +136,6 @@ nva3_copy_ctor(struct nouveau_object *pa
 	nv_subdev(priv)->intr = nva3_copy_intr;
 	nv_engine(priv)->cclass = &nva3_copy_cclass;
 	nv_engine(priv)->sclass = nva3_copy_sclass;
-	nv_engine(priv)->tlb_flush = nva3_copy_tlb_flush;
 	nv_falcon(priv)->code.data = nva3_pcopy_code;
 	nv_falcon(priv)->code.size = sizeof(nva3_pcopy_code);
 	nv_falcon(priv)->data.data = nva3_pcopy_data;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,13 +22,15 @@
  * Authors: Ben Skeggs
  */
 
-#include <core/falcon.h>
-#include <core/class.h>
-#include <core/enum.h>
-
+#include <engine/falcon.h>
 #include <engine/fifo.h>
 #include <engine/copy.h>
 
+#include <core/class.h>
+#include <core/enum.h>
+#include <core/class.h>
+#include <core/enum.h>
+
 #include "fuc/nvc0.fuc.h"
 
 struct nvc0_copy_priv {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c	2013-08-25 20:43:22.000000000 -0400
@@ -67,6 +67,19 @@ nve0_copy_cclass = {
  * PCOPY engine/subdev functions
  ******************************************************************************/
 
+static void
+nve0_copy_intr(struct nouveau_subdev *subdev)
+{
+	const int ce = nv_subidx(nv_object(subdev)) - NVDEV_ENGINE_COPY0;
+	struct nve0_copy_priv *priv = (void *)subdev;
+	u32 stat = nv_rd32(priv, 0x104908 + (ce * 0x1000));
+
+	if (stat) {
+		nv_warn(priv, "unhandled intr 0x%08x\n", stat);
+		nv_wr32(priv, 0x104908 + (ce * 0x1000), stat);
+	}
+}
+
 static int
 nve0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 		struct nouveau_oclass *oclass, void *data, u32 size,
@@ -85,6 +98,7 @@ nve0_copy0_ctor(struct nouveau_object *p
 		return ret;
 
 	nv_subdev(priv)->unit = 0x00000040;
+	nv_subdev(priv)->intr = nve0_copy_intr;
 	nv_engine(priv)->cclass = &nve0_copy_cclass;
 	nv_engine(priv)->sclass = nve0_copy_sclass;
 	return 0;
@@ -108,6 +122,28 @@ nve0_copy1_ctor(struct nouveau_object *p
 		return ret;
 
 	nv_subdev(priv)->unit = 0x00000080;
+	nv_subdev(priv)->intr = nve0_copy_intr;
+	nv_engine(priv)->cclass = &nve0_copy_cclass;
+	nv_engine(priv)->sclass = nve0_copy_sclass;
+	return 0;
+}
+
+static int
+nve0_copy2_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nve0_copy_priv *priv;
+	int ret;
+
+	ret = nouveau_engine_create(parent, engine, oclass, true,
+				    "PCE2", "copy2", &priv);
+	*pobject = nv_object(priv);
+	if (ret)
+		return ret;
+
+	nv_subdev(priv)->unit = 0x00200000;
+	nv_subdev(priv)->intr = nve0_copy_intr;
 	nv_engine(priv)->cclass = &nve0_copy_cclass;
 	nv_engine(priv)->sclass = nve0_copy_sclass;
 	return 0;
@@ -132,5 +168,16 @@ nve0_copy1_oclass = {
 		.dtor = _nouveau_engine_dtor,
 		.init = _nouveau_engine_init,
 		.fini = _nouveau_engine_fini,
+	},
+};
+
+struct nouveau_oclass
+nve0_copy2_oclass = {
+	.handle = NV_ENGINE(COPY2, 0xe0),
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nve0_copy2_ctor,
+		.dtor = _nouveau_engine_dtor,
+		.init = _nouveau_engine_init,
+		.fini = _nouveau_engine_fini,
 	},
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/fuc/nv98.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-static uint32_t nv98_pcrypt_data[] = {
+uint32_t nv98_pcrypt_data[] = {
 /* 0x0000: ctx_dma */
 /* 0x0000: ctx_dma_query */
 	0x00000000,
@@ -150,7 +150,7 @@ static uint32_t nv98_pcrypt_data[] = {
 	0x00000000,
 };
 
-static uint32_t nv98_pcrypt_code[] = {
+uint32_t nv98_pcrypt_code[] = {
 	0x17f004bd,
 	0x0010fe35,
 	0xf10004fe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c	2013-08-25 20:43:22.000000000 -0400
@@ -141,13 +141,6 @@ nv84_crypt_intr(struct nouveau_subdev *s
 }
 
 static int
-nv84_crypt_tlb_flush(struct nouveau_engine *engine)
-{
-	nv50_vm_flush_engine(&engine->base, 0x0a);
-	return 0;
-}
-
-static int
 nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	       struct nouveau_oclass *oclass, void *data, u32 size,
 	       struct nouveau_object **pobject)
@@ -165,7 +158,6 @@ nv84_crypt_ctor(struct nouveau_object *p
 	nv_subdev(priv)->intr = nv84_crypt_intr;
 	nv_engine(priv)->cclass = &nv84_crypt_cclass;
 	nv_engine(priv)->sclass = nv84_crypt_sclass;
-	nv_engine(priv)->tlb_flush = nv84_crypt_tlb_flush;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,11 +27,11 @@
 #include <core/enum.h>
 #include <core/class.h>
 #include <core/engctx.h>
-#include <core/falcon.h>
 
 #include <subdev/timer.h>
 #include <subdev/fb.h>
 
+#include <engine/falcon.h>
 #include <engine/fifo.h>
 #include <engine/crypt.h>
 
@@ -119,13 +119,6 @@ nv98_crypt_intr(struct nouveau_subdev *s
 }
 
 static int
-nv98_crypt_tlb_flush(struct nouveau_engine *engine)
-{
-	nv50_vm_flush_engine(&engine->base, 0x0a);
-	return 0;
-}
-
-static int
 nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	       struct nouveau_oclass *oclass, void *data, u32 size,
 	       struct nouveau_object **pobject)
@@ -143,7 +136,6 @@ nv98_crypt_ctor(struct nouveau_object *p
 	nv_subdev(priv)->intr = nv98_crypt_intr;
 	nv_engine(priv)->cclass = &nv98_crypt_cclass;
 	nv_engine(priv)->sclass = nv98_crypt_sclass;
-	nv_engine(priv)->tlb_flush = nv98_crypt_tlb_flush;
 	nv_falcon(priv)->code.data = nv98_pcrypt_code;
 	nv_falcon(priv)->code.size = sizeof(nv98_pcrypt_code);
 	nv_falcon(priv)->data.data = nv98_pcrypt_data;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/device/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/device/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/device/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -227,9 +227,9 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nv84_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nv50_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv50_graph_oclass;
-		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
+		device->oclass[NVDEV_ENGINE_VP     ] = &nv98_vp_oclass;
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv98_crypt_oclass;
-		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
+		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nv94_disp_oclass;
 		break;
@@ -279,9 +279,9 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nv84_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nv50_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv50_graph_oclass;
-		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
+		device->oclass[NVDEV_ENGINE_VP     ] = &nv98_vp_oclass;
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv98_crypt_oclass;
-		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
+		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nv94_disp_oclass;
 		break;
@@ -305,9 +305,9 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nv84_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nv50_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv50_graph_oclass;
-		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
+		device->oclass[NVDEV_ENGINE_VP     ] = &nv98_vp_oclass;
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv98_crypt_oclass;
-		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
+		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nv94_disp_oclass;
 		break;
@@ -319,7 +319,7 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nva3_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nv50_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -332,8 +332,8 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_SW     ] = &nv50_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv50_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv84_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
-		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
+		device->oclass[NVDEV_ENGINE_VP     ] = &nv98_vp_oclass;
+		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nva3_copy_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
@@ -346,7 +346,7 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nva3_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nv50_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -358,8 +358,8 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nv84_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nv50_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv50_graph_oclass;
-		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
-		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
+		device->oclass[NVDEV_ENGINE_VP     ] = &nv98_vp_oclass;
+		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nva3_copy_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
@@ -372,7 +372,7 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nva3_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nv50_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -384,8 +384,8 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nv84_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nv50_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv50_graph_oclass;
-		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
-		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
+		device->oclass[NVDEV_ENGINE_VP     ] = &nv98_vp_oclass;
+		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nva3_copy_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
@@ -398,7 +398,7 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nva3_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nv50_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -410,8 +410,8 @@ nv50_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nv84_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nv50_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv50_graph_oclass;
-		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
-		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
+		device->oclass[NVDEV_ENGINE_VP     ] = &nv98_vp_oclass;
+		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nva3_copy_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -62,7 +62,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -75,7 +75,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nvc0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc0_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -91,7 +91,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -104,7 +104,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nvc0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc3_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -120,7 +120,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -133,7 +133,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nvc0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc3_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -148,7 +148,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -161,7 +161,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nvc0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc3_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -177,7 +177,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -190,7 +190,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nvc0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc3_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -206,7 +206,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -219,7 +219,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nvc0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc1_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -234,7 +234,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nva3_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -247,7 +247,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nvc0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc8_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -263,7 +263,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -276,7 +276,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nvc0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvd9_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -291,7 +291,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -304,7 +304,7 @@ nvc0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nvc0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvd7_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/device/nve0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/device/nve0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/device/nve0.c	2013-08-25 20:43:22.000000000 -0400
@@ -62,7 +62,7 @@ nve0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -75,10 +75,11 @@ nve0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nve0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nve0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nve4_graph_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nve0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
+		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nve0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nve0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -91,7 +92,7 @@ nve0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -104,10 +105,11 @@ nve0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nve0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nve0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nve4_graph_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nve0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
+		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nve0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nve0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -120,7 +122,7 @@ nve0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -133,10 +135,11 @@ nve0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nve0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nve0_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nve4_graph_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nve0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
+		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nve0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nve0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
@@ -149,7 +152,7 @@ nve0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nvc0_clock_oclass;
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
-		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_BUS    ] = &nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
@@ -160,16 +163,14 @@ nve0_identify(struct nouveau_device *dev
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
-#if 0
 		device->oclass[NVDEV_ENGINE_FIFO   ] = &nve0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] = &nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] = &nve0_graph_oclass;
-#endif
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvf0_graph_oclass;
 		device->oclass[NVDEV_ENGINE_DISP   ] = &nvf0_disp_oclass;
-#if 0
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
 		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
+#if 0
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nve0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nve0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,8 @@ nva3_hda_eld(struct nv50_disp_priv *priv
 	if (data && data[0]) {
 		for (i = 0; i < size; i++)
 			nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]);
+		for (; i < 0x60; i++)
+			nv_wr32(priv, 0x61c440 + soff, (i << 8));
 		nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003);
 	} else
 	if (data) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,6 +41,8 @@ nvd0_hda_eld(struct nv50_disp_priv *priv
 	if (data && data[0]) {
 		for (i = 0; i < size; i++)
 			nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]);
+		for (; i < 0x60; i++)
+			nv_wr32(priv, 0x10ec00 + soff, (i << 8));
 		nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003);
 	} else
 	if (data) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,6 +55,10 @@ nva3_hdmi_ctrl(struct nv50_disp_priv *pr
 	nv_wr32(priv, 0x61c510 + soff, 0x00000000);
 	nv_mask(priv, 0x61c500 + soff, 0x00000001, 0x00000001);
 
+	nv_mask(priv, 0x61c5d0 + soff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
+	nv_mask(priv, 0x61c568 + soff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
+	nv_mask(priv, 0x61c578 + soff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
+
 	/* ??? */
 	nv_mask(priv, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
 	nv_mask(priv, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,9 +34,9 @@
 #include <subdev/bios/disp.h>
 #include <subdev/bios/init.h>
 #include <subdev/bios/pll.h>
+#include <subdev/devinit.h>
 #include <subdev/timer.h>
 #include <subdev/fb.h>
-#include <subdev/clock.h>
 
 #include "nv50.h"
 
@@ -987,10 +987,10 @@ nv50_disp_intr_unk20_0(struct nv50_disp_
 static void
 nv50_disp_intr_unk20_1(struct nv50_disp_priv *priv, int head)
 {
-	struct nouveau_clock *clk = nouveau_clock(priv);
+	struct nouveau_devinit *devinit = nouveau_devinit(priv);
 	u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
 	if (pclk)
-		clk->pll_set(clk, PLL_VPLL0 + head, pclk);
+		devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
 }
 
 static void
@@ -1107,6 +1107,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp_
 	u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff;
 	u32 hval, hreg = 0x614200 + (head * 0x800);
 	u32 oval, oreg;
+	u32 mask;
 	u32 conf = exec_clkcmp(priv, head, 0xff, pclk, &outp);
 	if (conf != ~0) {
 		if (outp.location == 0 && outp.type == DCB_OUTPUT_DP) {
@@ -1133,6 +1134,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp_
 			oreg = 0x614280 + (ffs(outp.or) - 1) * 0x800;
 			oval = 0x00000000;
 			hval = 0x00000000;
+			mask = 0xffffffff;
 		} else
 		if (!outp.location) {
 			if (outp.type == DCB_OUTPUT_DP)
@@ -1140,14 +1142,16 @@ nv50_disp_intr_unk20_2(struct nv50_disp_
 			oreg = 0x614300 + (ffs(outp.or) - 1) * 0x800;
 			oval = (conf & 0x0100) ? 0x00000101 : 0x00000000;
 			hval = 0x00000000;
+			mask = 0x00000707;
 		} else {
 			oreg = 0x614380 + (ffs(outp.or) - 1) * 0x800;
 			oval = 0x00000001;
 			hval = 0x00000001;
+			mask = 0x00000707;
 		}
 
 		nv_mask(priv, hreg, 0x0000000f, hval);
-		nv_mask(priv, oreg, 0x00000707, oval);
+		nv_mask(priv, oreg, mask, oval);
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,15 +29,14 @@
 
 #include <engine/disp.h>
 
-#include <subdev/timer.h>
-#include <subdev/fb.h>
-#include <subdev/clock.h>
-
 #include <subdev/bios.h>
 #include <subdev/bios/dcb.h>
 #include <subdev/bios/disp.h>
 #include <subdev/bios/init.h>
 #include <subdev/bios/pll.h>
+#include <subdev/devinit.h>
+#include <subdev/fb.h>
+#include <subdev/timer.h>
 
 #include "nv50.h"
 
@@ -738,10 +737,10 @@ nvd0_disp_intr_unk2_0(struct nv50_disp_p
 static void
 nvd0_disp_intr_unk2_1(struct nv50_disp_priv *priv, int head)
 {
-	struct nouveau_clock *clk = nouveau_clock(priv);
+	struct nouveau_devinit *devinit = nouveau_devinit(priv);
 	u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000;
 	if (pclk)
-		clk->pll_set(clk, PLL_VPLL0 + head, pclk);
+		devinit->pll_set(devinit, PLL_VPLL0 + head, pclk);
 	nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000);
 }
 
@@ -959,6 +958,9 @@ nvd0_disp_ctor(struct nouveau_object *pa
 	int heads = nv_rd32(parent, 0x022448);
 	int ret;
 
+	if (nv_rd32(parent, 0x022500) & 0x00000001)
+		return -ENODEV;
+
 	ret = nouveau_disp_create(parent, engine, oclass, heads,
 				  "PDISP", "display", &priv);
 	*pobject = nv_object(priv);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,6 +54,9 @@ nve0_disp_ctor(struct nouveau_object *pa
 	int heads = nv_rd32(parent, 0x022448);
 	int ret;
 
+	if (nv_rd32(parent, 0x022500) & 0x00000001)
+		return -ENODEV;
+
 	ret = nouveau_disp_create(parent, engine, oclass, heads,
 				  "PDISP", "display", &priv);
 	*pobject = nv_object(priv);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,6 +54,9 @@ nvf0_disp_ctor(struct nouveau_object *pa
 	int heads = nv_rd32(parent, 0x022448);
 	int ret;
 
+	if (nv_rd32(parent, 0x022500) & 0x00000001)
+		return -ENODEV;
+
 	ret = nouveau_disp_create(parent, engine, oclass, heads,
 				  "PDISP", "display", &priv);
 	*pobject = nv_object(priv);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,14 +47,8 @@ int
 nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
 {
 	struct nv50_disp_priv *priv = (void *)object->engine;
-	struct nouveau_bios *bios = nouveau_bios(priv);
-	const u16 type = (mthd & NV50_DISP_SOR_MTHD_TYPE) >> 12;
 	const u8  head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3;
-	const u8  link = (mthd & NV50_DISP_SOR_MTHD_LINK) >> 2;
 	const u8    or = (mthd & NV50_DISP_SOR_MTHD_OR);
-	const u16 mask = (0x0100 << head) | (0x0040 << link) | (0x0001 << or);
-	struct dcb_output outp;
-	u8  ver, hdr;
 	u32 data;
 	int ret = -EINVAL;
 
@@ -62,8 +56,6 @@ nv50_sor_mthd(struct nouveau_object *obj
 		return -EINVAL;
 	data = *(u32 *)args;
 
-	if (type && !dcb_outp_match(bios, type, mask, &ver, &hdr, &outp))
-		return -ENODEV;
 
 	switch (mthd & ~0x3f) {
 	case NV50_DISP_SOR_PWR:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/falcon.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/falcon.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/falcon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/falcon.c	2013-08-31 17:51:21.000000000 -0400
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 <engine/falcon.h>
+#include <subdev/timer.h>
+
+void
+nouveau_falcon_intr(struct nouveau_subdev *subdev)
+{
+	struct nouveau_falcon *falcon = (void *)subdev;
+	u32 dispatch = nv_ro32(falcon, 0x01c);
+	u32 intr = nv_ro32(falcon, 0x008) & dispatch & ~(dispatch >> 16);
+
+	if (intr & 0x00000010) {
+		nv_debug(falcon, "ucode halted\n");
+		nv_wo32(falcon, 0x004, 0x00000010);
+		intr &= ~0x00000010;
+	}
+
+	if (intr)  {
+		nv_error(falcon, "unhandled intr 0x%08x\n", intr);
+		nv_wo32(falcon, 0x004, intr);
+	}
+}
+
+u32
+_nouveau_falcon_rd32(struct nouveau_object *object, u64 addr)
+{
+	struct nouveau_falcon *falcon = (void *)object;
+	return nv_rd32(falcon, falcon->addr + addr);
+}
+
+void
+_nouveau_falcon_wr32(struct nouveau_object *object, u64 addr, u32 data)
+{
+	struct nouveau_falcon *falcon = (void *)object;
+	nv_wr32(falcon, falcon->addr + addr, data);
+}
+
+int
+_nouveau_falcon_init(struct nouveau_object *object)
+{
+	struct nouveau_device *device = nv_device(object);
+	struct nouveau_falcon *falcon = (void *)object;
+	const struct firmware *fw;
+	char name[32] = "internal";
+	int ret, i;
+	u32 caps;
+
+	/* enable engine, and determine its capabilities */
+	ret = nouveau_engine_init(&falcon->base);
+	if (ret)
+		return ret;
+
+	if (device->chipset <  0xa3 ||
+	    device->chipset == 0xaa || device->chipset == 0xac) {
+		falcon->version = 0;
+		falcon->secret  = (falcon->addr == 0x087000) ? 1 : 0;
+	} else {
+		caps = nv_ro32(falcon, 0x12c);
+		falcon->version = (caps & 0x0000000f);
+		falcon->secret  = (caps & 0x00000030) >> 4;
+	}
+
+	caps = nv_ro32(falcon, 0x108);
+	falcon->code.limit = (caps & 0x000001ff) << 8;
+	falcon->data.limit = (caps & 0x0003fe00) >> 1;
+
+	nv_debug(falcon, "falcon version: %d\n", falcon->version);
+	nv_debug(falcon, "secret level: %d\n", falcon->secret);
+	nv_debug(falcon, "code limit: %d\n", falcon->code.limit);
+	nv_debug(falcon, "data limit: %d\n", falcon->data.limit);
+
+	/* wait for 'uc halted' to be signalled before continuing */
+	if (falcon->secret && falcon->version < 4) {
+		if (!falcon->version)
+			nv_wait(falcon, 0x008, 0x00000010, 0x00000010);
+		else
+			nv_wait(falcon, 0x180, 0x80000000, 0);
+		nv_wo32(falcon, 0x004, 0x00000010);
+	}
+
+	/* disable all interrupts */
+	nv_wo32(falcon, 0x014, 0xffffffff);
+
+	/* no default ucode provided by the engine implementation, try and
+	 * locate a "self-bootstrapping" firmware image for the engine
+	 */
+	if (!falcon->code.data) {
+		snprintf(name, sizeof(name), "/*(DEBLOBBED)*/",
+			 device->chipset, falcon->addr >> 12);
+
+		ret = reject_firmware(&fw, name, &device->pdev->dev);
+		if (ret == 0) {
+			falcon->code.data = kmemdup(fw->data, fw->size, GFP_KERNEL);
+			falcon->code.size = fw->size;
+			falcon->data.data = NULL;
+			falcon->data.size = 0;
+			release_firmware(fw);
+		}
+
+		falcon->external = true;
+	}
+
+	/* next step is to try and load "static code/data segment" firmware
+	 * images for the engine
+	 */
+	if (!falcon->code.data) {
+		snprintf(name, sizeof(name), "/*(DEBLOBBED)*/",
+			 device->chipset, falcon->addr >> 12);
+
+		ret = reject_firmware(&fw, name, &device->pdev->dev);
+		if (ret) {
+			nv_error(falcon, "unable to load firmware data\n");
+			return ret;
+		}
+
+		falcon->data.data = kmemdup(fw->data, fw->size, GFP_KERNEL);
+		falcon->data.size = fw->size;
+		release_firmware(fw);
+		if (!falcon->data.data)
+			return -ENOMEM;
+
+		snprintf(name, sizeof(name), "/*(DEBLOBBED)*/",
+			 device->chipset, falcon->addr >> 12);
+
+		ret = reject_firmware(&fw, name, &device->pdev->dev);
+		if (ret) {
+			nv_error(falcon, "unable to load firmware code\n");
+			return ret;
+		}
+
+		falcon->code.data = kmemdup(fw->data, fw->size, GFP_KERNEL);
+		falcon->code.size = fw->size;
+		release_firmware(fw);
+		if (!falcon->code.data)
+			return -ENOMEM;
+	}
+
+	nv_debug(falcon, "firmware: %s (%s)\n", name, falcon->data.data ?
+		 "static code/data segments" : "self-bootstrapping");
+
+	/* ensure any "self-bootstrapping" firmware image is in vram */
+	if (!falcon->data.data && !falcon->core) {
+		ret = nouveau_gpuobj_new(object->parent, NULL,
+					 falcon->code.size, 256, 0,
+					&falcon->core);
+		if (ret) {
+			nv_error(falcon, "core allocation failed, %d\n", ret);
+			return ret;
+		}
+
+		for (i = 0; i < falcon->code.size; i += 4)
+			nv_wo32(falcon->core, i, falcon->code.data[i / 4]);
+	}
+
+	/* upload firmware bootloader (or the full code segments) */
+	if (falcon->core) {
+		if (device->card_type < NV_C0)
+			nv_wo32(falcon, 0x618, 0x04000000);
+		else
+			nv_wo32(falcon, 0x618, 0x00000114);
+		nv_wo32(falcon, 0x11c, 0);
+		nv_wo32(falcon, 0x110, falcon->core->addr >> 8);
+		nv_wo32(falcon, 0x114, 0);
+		nv_wo32(falcon, 0x118, 0x00006610);
+	} else {
+		if (falcon->code.size > falcon->code.limit ||
+		    falcon->data.size > falcon->data.limit) {
+			nv_error(falcon, "ucode exceeds falcon limit(s)\n");
+			return -EINVAL;
+		}
+
+		if (falcon->version < 3) {
+			nv_wo32(falcon, 0xff8, 0x00100000);
+			for (i = 0; i < falcon->code.size / 4; i++)
+				nv_wo32(falcon, 0xff4, falcon->code.data[i]);
+		} else {
+			nv_wo32(falcon, 0x180, 0x01000000);
+			for (i = 0; i < falcon->code.size / 4; i++) {
+				if ((i & 0x3f) == 0)
+					nv_wo32(falcon, 0x188, i >> 6);
+				nv_wo32(falcon, 0x184, falcon->code.data[i]);
+			}
+		}
+	}
+
+	/* upload data segment (if necessary), zeroing the remainder */
+	if (falcon->version < 3) {
+		nv_wo32(falcon, 0xff8, 0x00000000);
+		for (i = 0; !falcon->core && i < falcon->data.size / 4; i++)
+			nv_wo32(falcon, 0xff4, falcon->data.data[i]);
+		for (; i < falcon->data.limit; i += 4)
+			nv_wo32(falcon, 0xff4, 0x00000000);
+	} else {
+		nv_wo32(falcon, 0x1c0, 0x01000000);
+		for (i = 0; !falcon->core && i < falcon->data.size / 4; i++)
+			nv_wo32(falcon, 0x1c4, falcon->data.data[i]);
+		for (; i < falcon->data.limit / 4; i++)
+			nv_wo32(falcon, 0x1c4, 0x00000000);
+	}
+
+	/* start it running */
+	nv_wo32(falcon, 0x10c, 0x00000001); /* BLOCK_ON_FIFO */
+	nv_wo32(falcon, 0x104, 0x00000000); /* ENTRY */
+	nv_wo32(falcon, 0x100, 0x00000002); /* TRIGGER */
+	nv_wo32(falcon, 0x048, 0x00000003); /* FIFO | CHSW */
+	return 0;
+}
+
+int
+_nouveau_falcon_fini(struct nouveau_object *object, bool suspend)
+{
+	struct nouveau_falcon *falcon = (void *)object;
+
+	if (!suspend) {
+		nouveau_gpuobj_ref(NULL, &falcon->core);
+		if (falcon->external) {
+			kfree(falcon->data.data);
+			kfree(falcon->code.data);
+			falcon->code.data = NULL;
+		}
+	}
+
+	nv_mo32(falcon, 0x048, 0x00000003, 0x00000000);
+	nv_wo32(falcon, 0x014, 0xffffffff);
+
+	return nouveau_engine_fini(&falcon->base, suspend);
+}
+
+int
+nouveau_falcon_create_(struct nouveau_object *parent,
+		       struct nouveau_object *engine,
+		       struct nouveau_oclass *oclass, u32 addr, bool enable,
+		       const char *iname, const char *fname,
+		       int length, void **pobject)
+{
+	struct nouveau_falcon *falcon;
+	int ret;
+
+	ret = nouveau_engine_create_(parent, engine, oclass, enable, iname,
+				     fname, length, pobject);
+	falcon = *pobject;
+	if (ret)
+		return ret;
+
+	falcon->addr = addr;
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c	2013-08-25 20:43:22.000000000 -0400
@@ -320,7 +320,7 @@ nv40_fifo_init(struct nouveau_object *ob
 		break;
 	default:
 		nv_wr32(priv, 0x002230, 0x00000000);
-		nv_wr32(priv, 0x002220, ((pfb->ram.size - 512 * 1024 +
+		nv_wr32(priv, 0x002220, ((pfb->ram->size - 512 * 1024 +
 					 priv->ramfc->addr) >> 16) |
 					0x00030000);
 		break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,7 +56,9 @@ nv84_fifo_context_attach(struct nouveau_
 	switch (nv_engidx(object->engine)) {
 	case NVDEV_ENGINE_SW   : return 0;
 	case NVDEV_ENGINE_GR   : addr = 0x0020; break;
+	case NVDEV_ENGINE_VP   : addr = 0x0040; break;
 	case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
+	case NVDEV_ENGINE_BSP  : addr = 0x0080; break;
 	case NVDEV_ENGINE_CRYPT: addr = 0x00a0; break;
 	case NVDEV_ENGINE_COPY0: addr = 0x00c0; break;
 	default:
@@ -89,7 +91,9 @@ nv84_fifo_context_detach(struct nouveau_
 	switch (nv_engidx(object->engine)) {
 	case NVDEV_ENGINE_SW   : return 0;
 	case NVDEV_ENGINE_GR   : engn = 0; addr = 0x0020; break;
+	case NVDEV_ENGINE_VP   : engn = 3; addr = 0x0040; break;
 	case NVDEV_ENGINE_MPEG : engn = 1; addr = 0x0060; break;
+	case NVDEV_ENGINE_BSP  : engn = 5; addr = 0x0080; break;
 	case NVDEV_ENGINE_CRYPT: engn = 4; addr = 0x00a0; break;
 	case NVDEV_ENGINE_COPY0: engn = 2; addr = 0x00c0; break;
 	default:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,7 +44,8 @@ static const struct {
 	u64 subdev;
 	u64 mask;
 } fifo_engine[] = {
-	_(NVDEV_ENGINE_GR      , (1ULL << NVDEV_ENGINE_SW)),
+	_(NVDEV_ENGINE_GR      , (1ULL << NVDEV_ENGINE_SW) |
+				 (1ULL << NVDEV_ENGINE_COPY2)),
 	_(NVDEV_ENGINE_VP      , 0),
 	_(NVDEV_ENGINE_PPP     , 0),
 	_(NVDEV_ENGINE_BSP     , 0),
@@ -96,18 +97,6 @@ nve0_fifo_playlist_update(struct nve0_fi
 
 	mutex_lock(&nv_subdev(priv)->mutex);
 	cur = engn->playlist[engn->cur_playlist];
-	if (unlikely(cur == NULL)) {
-		int ret = nouveau_gpuobj_new(nv_object(priv), NULL,
-					     0x8000, 0x1000, 0, &cur);
-		if (ret) {
-			mutex_unlock(&nv_subdev(priv)->mutex);
-			nv_error(priv, "playlist alloc failed\n");
-			return;
-		}
-
-		engn->playlist[engn->cur_playlist] = cur;
-	}
-
 	engn->cur_playlist = !engn->cur_playlist;
 
 	for (i = 0, p = 0; i < priv->base.max; i++) {
@@ -138,10 +127,12 @@ nve0_fifo_context_attach(struct nouveau_
 	int ret;
 
 	switch (nv_engidx(object->engine)) {
-	case NVDEV_ENGINE_SW   : return 0;
-	case NVDEV_ENGINE_GR   :
+	case NVDEV_ENGINE_SW   :
 	case NVDEV_ENGINE_COPY0:
-	case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
+	case NVDEV_ENGINE_COPY1:
+	case NVDEV_ENGINE_COPY2:
+		return 0;
+	case NVDEV_ENGINE_GR   : addr = 0x0210; break;
 	case NVDEV_ENGINE_BSP  : addr = 0x0270; break;
 	case NVDEV_ENGINE_VP   : addr = 0x0250; break;
 	case NVDEV_ENGINE_PPP  : addr = 0x0260; break;
@@ -176,9 +167,10 @@ nve0_fifo_context_detach(struct nouveau_
 
 	switch (nv_engidx(object->engine)) {
 	case NVDEV_ENGINE_SW   : return 0;
-	case NVDEV_ENGINE_GR   :
 	case NVDEV_ENGINE_COPY0:
-	case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
+	case NVDEV_ENGINE_COPY1:
+	case NVDEV_ENGINE_COPY2: addr = 0x0000; break;
+	case NVDEV_ENGINE_GR   : addr = 0x0210; break;
 	case NVDEV_ENGINE_BSP  : addr = 0x0270; break;
 	case NVDEV_ENGINE_VP   : addr = 0x0250; break;
 	case NVDEV_ENGINE_PPP  : addr = 0x0260; break;
@@ -194,9 +186,12 @@ nve0_fifo_context_detach(struct nouveau_
 			return -EBUSY;
 	}
 
-	nv_wo32(base, addr + 0x00, 0x00000000);
-	nv_wo32(base, addr + 0x04, 0x00000000);
-	bar->flush(bar);
+	if (addr) {
+		nv_wo32(base, addr + 0x00, 0x00000000);
+		nv_wo32(base, addr + 0x04, 0x00000000);
+		bar->flush(bar);
+	}
+
 	return 0;
 }
 
@@ -226,8 +221,10 @@ nve0_fifo_chan_ctor(struct nouveau_objec
 		}
 	}
 
-	if (i == FIFO_ENGINE_NR)
+	if (i == FIFO_ENGINE_NR) {
+		nv_error(priv, "unsupported engines 0x%08x\n", args->engine);
 		return -ENODEV;
+	}
 
 	ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
 					  priv->user.bar.offset, 0x200,
@@ -592,13 +589,25 @@ nve0_fifo_ctor(struct nouveau_object *pa
 	       struct nouveau_object **pobject)
 {
 	struct nve0_fifo_priv *priv;
-	int ret;
+	int ret, i;
 
 	ret = nouveau_fifo_create(parent, engine, oclass, 0, 4095, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
+	for (i = 0; i < FIFO_ENGINE_NR; i++) {
+		ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
+					 0, &priv->engine[i].playlist[0]);
+		if (ret)
+			return ret;
+
+		ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
+					 0, &priv->engine[i].playlist[1]);
+		if (ret)
+			return ret;
+	}
+
 	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 4096 * 0x200, 0x1000,
 				 NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
 	if (ret)
@@ -629,7 +638,7 @@ nve0_fifo_dtor(struct nouveau_object *ob
 	nouveau_gpuobj_unmap(&priv->user.bar);
 	nouveau_gpuobj_ref(NULL, &priv->user.mem);
 
-	for (i = 0; i < ARRAY_SIZE(priv->engine); i++) {
+	for (i = 0; i < FIFO_ENGINE_NR; i++) {
 		nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[1]);
 		nouveau_gpuobj_ref(NULL, &priv->engine[i].playlist[0]);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,3015 +24,1220 @@
 
 #include "nvc0.h"
 
-void
-nv_icmd(struct nvc0_graph_priv *priv, u32 icmd, u32 data)
-{
-	nv_wr32(priv, 0x400204, data);
-	nv_wr32(priv, 0x400200, icmd);
-	while (nv_rd32(priv, 0x400700) & 2) {}
-}
+struct nvc0_graph_init
+nvc0_grctx_init_icmd[] = {
+	{ 0x001000,   1, 0x01, 0x00000004 },
+	{ 0x0000a9,   1, 0x01, 0x0000ffff },
+	{ 0x000038,   1, 0x01, 0x0fac6881 },
+	{ 0x00003d,   1, 0x01, 0x00000001 },
+	{ 0x0000e8,   8, 0x01, 0x00000400 },
+	{ 0x000078,   8, 0x01, 0x00000300 },
+	{ 0x000050,   1, 0x01, 0x00000011 },
+	{ 0x000058,   8, 0x01, 0x00000008 },
+	{ 0x000208,   8, 0x01, 0x00000001 },
+	{ 0x000081,   1, 0x01, 0x00000001 },
+	{ 0x000085,   1, 0x01, 0x00000004 },
+	{ 0x000088,   1, 0x01, 0x00000400 },
+	{ 0x000090,   1, 0x01, 0x00000300 },
+	{ 0x000098,   1, 0x01, 0x00001001 },
+	{ 0x0000e3,   1, 0x01, 0x00000001 },
+	{ 0x0000da,   1, 0x01, 0x00000001 },
+	{ 0x0000f8,   1, 0x01, 0x00000003 },
+	{ 0x0000fa,   1, 0x01, 0x00000001 },
+	{ 0x00009f,   4, 0x01, 0x0000ffff },
+	{ 0x0000b1,   1, 0x01, 0x00000001 },
+	{ 0x0000b2,  40, 0x01, 0x00000000 },
+	{ 0x000210,   8, 0x01, 0x00000040 },
+	{ 0x000218,   8, 0x01, 0x0000c080 },
+	{ 0x0000ad,   1, 0x01, 0x0000013e },
+	{ 0x0000e1,   1, 0x01, 0x00000010 },
+	{ 0x000290,  16, 0x01, 0x00000000 },
+	{ 0x0003b0,  16, 0x01, 0x00000000 },
+	{ 0x0002a0,  16, 0x01, 0x00000000 },
+	{ 0x000420,  16, 0x01, 0x00000000 },
+	{ 0x0002b0,  16, 0x01, 0x00000000 },
+	{ 0x000430,  16, 0x01, 0x00000000 },
+	{ 0x0002c0,  16, 0x01, 0x00000000 },
+	{ 0x0004d0,  16, 0x01, 0x00000000 },
+	{ 0x000720,  16, 0x01, 0x00000000 },
+	{ 0x0008c0,  16, 0x01, 0x00000000 },
+	{ 0x000890,  16, 0x01, 0x00000000 },
+	{ 0x0008e0,  16, 0x01, 0x00000000 },
+	{ 0x0008a0,  16, 0x01, 0x00000000 },
+	{ 0x0008f0,  16, 0x01, 0x00000000 },
+	{ 0x00094c,   1, 0x01, 0x000000ff },
+	{ 0x00094d,   1, 0x01, 0xffffffff },
+	{ 0x00094e,   1, 0x01, 0x00000002 },
+	{ 0x0002ec,   1, 0x01, 0x00000001 },
+	{ 0x000303,   1, 0x01, 0x00000001 },
+	{ 0x0002e6,   1, 0x01, 0x00000001 },
+	{ 0x000466,   1, 0x01, 0x00000052 },
+	{ 0x000301,   1, 0x01, 0x3f800000 },
+	{ 0x000304,   1, 0x01, 0x30201000 },
+	{ 0x000305,   1, 0x01, 0x70605040 },
+	{ 0x000306,   1, 0x01, 0xb8a89888 },
+	{ 0x000307,   1, 0x01, 0xf8e8d8c8 },
+	{ 0x00030a,   1, 0x01, 0x00ffff00 },
+	{ 0x00030b,   1, 0x01, 0x0000001a },
+	{ 0x00030c,   1, 0x01, 0x00000001 },
+	{ 0x000318,   1, 0x01, 0x00000001 },
+	{ 0x000340,   1, 0x01, 0x00000000 },
+	{ 0x000375,   1, 0x01, 0x00000001 },
+	{ 0x000351,   1, 0x01, 0x00000100 },
+	{ 0x00037d,   1, 0x01, 0x00000006 },
+	{ 0x0003a0,   1, 0x01, 0x00000002 },
+	{ 0x0003aa,   1, 0x01, 0x00000001 },
+	{ 0x0003a9,   1, 0x01, 0x00000001 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000360,   1, 0x01, 0x00000040 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00001fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x003fffff },
+	{ 0x00037a,   1, 0x01, 0x00000012 },
+	{ 0x0005e0,   5, 0x01, 0x00000022 },
+	{ 0x000619,   1, 0x01, 0x00000003 },
+	{ 0x000811,   1, 0x01, 0x00000003 },
+	{ 0x000812,   1, 0x01, 0x00000004 },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000815,   1, 0x01, 0x0000000b },
+	{ 0x000800,   6, 0x01, 0x00000001 },
+	{ 0x000632,   1, 0x01, 0x00000001 },
+	{ 0x000633,   1, 0x01, 0x00000002 },
+	{ 0x000634,   1, 0x01, 0x00000003 },
+	{ 0x000635,   1, 0x01, 0x00000004 },
+	{ 0x000654,   1, 0x01, 0x3f800000 },
+	{ 0x000657,   1, 0x01, 0x3f800000 },
+	{ 0x000655,   2, 0x01, 0x3f800000 },
+	{ 0x0006cd,   1, 0x01, 0x3f800000 },
+	{ 0x0007f5,   1, 0x01, 0x3f800000 },
+	{ 0x0007dc,   1, 0x01, 0x39291909 },
+	{ 0x0007dd,   1, 0x01, 0x79695949 },
+	{ 0x0007de,   1, 0x01, 0xb9a99989 },
+	{ 0x0007df,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007e8,   1, 0x01, 0x00003210 },
+	{ 0x0007e9,   1, 0x01, 0x00007654 },
+	{ 0x0007ea,   1, 0x01, 0x00000098 },
+	{ 0x0007ec,   1, 0x01, 0x39291909 },
+	{ 0x0007ed,   1, 0x01, 0x79695949 },
+	{ 0x0007ee,   1, 0x01, 0xb9a99989 },
+	{ 0x0007ef,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007f0,   1, 0x01, 0x00003210 },
+	{ 0x0007f1,   1, 0x01, 0x00007654 },
+	{ 0x0007f2,   1, 0x01, 0x00000098 },
+	{ 0x0005a5,   1, 0x01, 0x00000001 },
+	{ 0x000980, 128, 0x01, 0x00000000 },
+	{ 0x000468,   1, 0x01, 0x00000004 },
+	{ 0x00046c,   1, 0x01, 0x00000001 },
+	{ 0x000470,  96, 0x01, 0x00000000 },
+	{ 0x000510,  16, 0x01, 0x3f800000 },
+	{ 0x000520,   1, 0x01, 0x000002b6 },
+	{ 0x000529,   1, 0x01, 0x00000001 },
+	{ 0x000530,  16, 0x01, 0xffff0000 },
+	{ 0x000585,   1, 0x01, 0x0000003f },
+	{ 0x000576,   1, 0x01, 0x00000003 },
+	{ 0x000586,   1, 0x01, 0x00000040 },
+	{ 0x000582,   2, 0x01, 0x00000080 },
+	{ 0x0005c2,   1, 0x01, 0x00000001 },
+	{ 0x000638,   1, 0x01, 0x00000001 },
+	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x00063a,   1, 0x01, 0x00000002 },
+	{ 0x00063b,   2, 0x01, 0x00000001 },
+	{ 0x00063d,   1, 0x01, 0x00000002 },
+	{ 0x00063e,   1, 0x01, 0x00000001 },
+	{ 0x0008b8,   8, 0x01, 0x00000001 },
+	{ 0x000900,   8, 0x01, 0x00000001 },
+	{ 0x000908,   8, 0x01, 0x00000002 },
+	{ 0x000910,  16, 0x01, 0x00000001 },
+	{ 0x000920,   8, 0x01, 0x00000002 },
+	{ 0x000928,   8, 0x01, 0x00000001 },
+	{ 0x000648,   9, 0x01, 0x00000001 },
+	{ 0x000658,   1, 0x01, 0x0000000f },
+	{ 0x0007ff,   1, 0x01, 0x0000000a },
+	{ 0x00066a,   1, 0x01, 0x40000000 },
+	{ 0x00066b,   1, 0x01, 0x10000000 },
+	{ 0x00066c,   2, 0x01, 0xffff0000 },
+	{ 0x0007af,   2, 0x01, 0x00000008 },
+	{ 0x0007f6,   1, 0x01, 0x00000001 },
+	{ 0x0006b2,   1, 0x01, 0x00000055 },
+	{ 0x0007ad,   1, 0x01, 0x00000003 },
+	{ 0x000937,   1, 0x01, 0x00000001 },
+	{ 0x000971,   1, 0x01, 0x00000008 },
+	{ 0x000972,   1, 0x01, 0x00000040 },
+	{ 0x000973,   1, 0x01, 0x0000012c },
+	{ 0x00097c,   1, 0x01, 0x00000040 },
+	{ 0x000979,   1, 0x01, 0x00000003 },
+	{ 0x000975,   1, 0x01, 0x00000020 },
+	{ 0x000976,   1, 0x01, 0x00000001 },
+	{ 0x000977,   1, 0x01, 0x00000020 },
+	{ 0x000978,   1, 0x01, 0x00000001 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095e,   1, 0x01, 0x20164010 },
+	{ 0x00095f,   1, 0x01, 0x00000020 },
+	{ 0x000683,   1, 0x01, 0x00000006 },
+	{ 0x000685,   1, 0x01, 0x003fffff },
+	{ 0x000687,   1, 0x01, 0x00000c48 },
+	{ 0x0006a0,   1, 0x01, 0x00000005 },
+	{ 0x000840,   1, 0x01, 0x00300008 },
+	{ 0x000841,   1, 0x01, 0x04000080 },
+	{ 0x000842,   1, 0x01, 0x00300008 },
+	{ 0x000843,   1, 0x01, 0x04000080 },
+	{ 0x000818,   8, 0x01, 0x00000000 },
+	{ 0x000848,  16, 0x01, 0x00000000 },
+	{ 0x000738,   1, 0x01, 0x00000000 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ab,   1, 0x01, 0x00000002 },
+	{ 0x0006ac,   1, 0x01, 0x00000080 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x0006bb,   1, 0x01, 0x000000cf },
+	{ 0x0006ce,   1, 0x01, 0x2a712488 },
+	{ 0x000739,   1, 0x01, 0x4085c000 },
+	{ 0x00073a,   1, 0x01, 0x00000080 },
+	{ 0x000786,   1, 0x01, 0x80000100 },
+	{ 0x00073c,   1, 0x01, 0x00010100 },
+	{ 0x00073d,   1, 0x01, 0x02800000 },
+	{ 0x000787,   1, 0x01, 0x000000cf },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x000836,   1, 0x01, 0x00000001 },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x00080c,   1, 0x01, 0x00000002 },
+	{ 0x00080d,   2, 0x01, 0x00000100 },
+	{ 0x00080f,   1, 0x01, 0x00000001 },
+	{ 0x000823,   1, 0x01, 0x00000002 },
+	{ 0x000824,   2, 0x01, 0x00000100 },
+	{ 0x000826,   1, 0x01, 0x00000001 },
+	{ 0x00095d,   1, 0x01, 0x00000001 },
+	{ 0x00082b,   1, 0x01, 0x00000004 },
+	{ 0x000942,   1, 0x01, 0x00010001 },
+	{ 0x000943,   1, 0x01, 0x00000001 },
+	{ 0x000944,   1, 0x01, 0x00000022 },
+	{ 0x0007c5,   1, 0x01, 0x00010001 },
+	{ 0x000834,   1, 0x01, 0x00000001 },
+	{ 0x0007c7,   1, 0x01, 0x00000001 },
+	{ 0x00c1b0,   8, 0x01, 0x0000000f },
+	{ 0x00c1b8,   1, 0x01, 0x0fac6881 },
+	{ 0x00c1b9,   1, 0x01, 0x00fac688 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000002 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000014 },
+	{ 0x000351,   1, 0x01, 0x00000100 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095d,   1, 0x01, 0x00000001 },
+	{ 0x00082b,   1, 0x01, 0x00000004 },
+	{ 0x000942,   1, 0x01, 0x00010001 },
+	{ 0x000943,   1, 0x01, 0x00000001 },
+	{ 0x0007c5,   1, 0x01, 0x00010001 },
+	{ 0x000834,   1, 0x01, 0x00000001 },
+	{ 0x0007c7,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000001 },
+	{ 0x00080c,   1, 0x01, 0x00000002 },
+	{ 0x00080d,   2, 0x01, 0x00000100 },
+	{ 0x00080f,   1, 0x01, 0x00000001 },
+	{ 0x000823,   1, 0x01, 0x00000002 },
+	{ 0x000824,   2, 0x01, 0x00000100 },
+	{ 0x000826,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{}
+};
 
-int
-nvc0_grctx_init(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
-{
-	struct nouveau_bar *bar = nouveau_bar(priv);
-	struct nouveau_gpuobj *chan;
-	u32 size = (0x80000 + priv->size + 4095) & ~4095;
-	int ret, i;
+struct nvc0_graph_init
+nvc0_grctx_init_9097[] = {
+	{ 0x000800,   8, 0x40, 0x00000000 },
+	{ 0x000804,   8, 0x40, 0x00000000 },
+	{ 0x000808,   8, 0x40, 0x00000400 },
+	{ 0x00080c,   8, 0x40, 0x00000300 },
+	{ 0x000810,   1, 0x04, 0x000000cf },
+	{ 0x000850,   7, 0x40, 0x00000000 },
+	{ 0x000814,   8, 0x40, 0x00000040 },
+	{ 0x000818,   8, 0x40, 0x00000001 },
+	{ 0x00081c,   8, 0x40, 0x00000000 },
+	{ 0x000820,   8, 0x40, 0x00000000 },
+	{ 0x002700,   8, 0x20, 0x00000000 },
+	{ 0x002704,   8, 0x20, 0x00000000 },
+	{ 0x002708,   8, 0x20, 0x00000000 },
+	{ 0x00270c,   8, 0x20, 0x00000000 },
+	{ 0x002710,   8, 0x20, 0x00014000 },
+	{ 0x002714,   8, 0x20, 0x00000040 },
+	{ 0x001c00,  16, 0x10, 0x00000000 },
+	{ 0x001c04,  16, 0x10, 0x00000000 },
+	{ 0x001c08,  16, 0x10, 0x00000000 },
+	{ 0x001c0c,  16, 0x10, 0x00000000 },
+	{ 0x001d00,  16, 0x10, 0x00000000 },
+	{ 0x001d04,  16, 0x10, 0x00000000 },
+	{ 0x001d08,  16, 0x10, 0x00000000 },
+	{ 0x001d0c,  16, 0x10, 0x00000000 },
+	{ 0x001f00,  16, 0x08, 0x00000000 },
+	{ 0x001f04,  16, 0x08, 0x00000000 },
+	{ 0x001f80,  16, 0x08, 0x00000000 },
+	{ 0x001f84,  16, 0x08, 0x00000000 },
+	{ 0x002200,   5, 0x10, 0x00000022 },
+	{ 0x002000,   1, 0x04, 0x00000000 },
+	{ 0x002040,   1, 0x04, 0x00000011 },
+	{ 0x002080,   1, 0x04, 0x00000020 },
+	{ 0x0020c0,   1, 0x04, 0x00000030 },
+	{ 0x002100,   1, 0x04, 0x00000040 },
+	{ 0x002140,   1, 0x04, 0x00000051 },
+	{ 0x00200c,   6, 0x40, 0x00000001 },
+	{ 0x002010,   1, 0x04, 0x00000000 },
+	{ 0x002050,   1, 0x04, 0x00000000 },
+	{ 0x002090,   1, 0x04, 0x00000001 },
+	{ 0x0020d0,   1, 0x04, 0x00000002 },
+	{ 0x002110,   1, 0x04, 0x00000003 },
+	{ 0x002150,   1, 0x04, 0x00000004 },
+	{ 0x000380,   4, 0x20, 0x00000000 },
+	{ 0x000384,   4, 0x20, 0x00000000 },
+	{ 0x000388,   4, 0x20, 0x00000000 },
+	{ 0x00038c,   4, 0x20, 0x00000000 },
+	{ 0x000700,   4, 0x10, 0x00000000 },
+	{ 0x000704,   4, 0x10, 0x00000000 },
+	{ 0x000708,   4, 0x10, 0x00000000 },
+	{ 0x002800, 128, 0x04, 0x00000000 },
+	{ 0x000a00,  16, 0x20, 0x00000000 },
+	{ 0x000a04,  16, 0x20, 0x00000000 },
+	{ 0x000a08,  16, 0x20, 0x00000000 },
+	{ 0x000a0c,  16, 0x20, 0x00000000 },
+	{ 0x000a10,  16, 0x20, 0x00000000 },
+	{ 0x000a14,  16, 0x20, 0x00000000 },
+	{ 0x000c00,  16, 0x10, 0x00000000 },
+	{ 0x000c04,  16, 0x10, 0x00000000 },
+	{ 0x000c08,  16, 0x10, 0x00000000 },
+	{ 0x000c0c,  16, 0x10, 0x3f800000 },
+	{ 0x000d00,   8, 0x08, 0xffff0000 },
+	{ 0x000d04,   8, 0x08, 0xffff0000 },
+	{ 0x000e00,  16, 0x10, 0x00000000 },
+	{ 0x000e04,  16, 0x10, 0xffff0000 },
+	{ 0x000e08,  16, 0x10, 0xffff0000 },
+	{ 0x000d40,   4, 0x08, 0x00000000 },
+	{ 0x000d44,   4, 0x08, 0x00000000 },
+	{ 0x001e00,   8, 0x20, 0x00000001 },
+	{ 0x001e04,   8, 0x20, 0x00000001 },
+	{ 0x001e08,   8, 0x20, 0x00000002 },
+	{ 0x001e0c,   8, 0x20, 0x00000001 },
+	{ 0x001e10,   8, 0x20, 0x00000001 },
+	{ 0x001e14,   8, 0x20, 0x00000002 },
+	{ 0x001e18,   8, 0x20, 0x00000001 },
+	{ 0x003400, 128, 0x04, 0x00000000 },
+	{ 0x00030c,   1, 0x04, 0x00000001 },
+	{ 0x001944,   1, 0x04, 0x00000000 },
+	{ 0x001514,   1, 0x04, 0x00000000 },
+	{ 0x000d68,   1, 0x04, 0x0000ffff },
+	{ 0x00121c,   1, 0x04, 0x0fac6881 },
+	{ 0x000fac,   1, 0x04, 0x00000001 },
+	{ 0x001538,   1, 0x04, 0x00000001 },
+	{ 0x000fe0,   2, 0x04, 0x00000000 },
+	{ 0x000fe8,   1, 0x04, 0x00000014 },
+	{ 0x000fec,   1, 0x04, 0x00000040 },
+	{ 0x000ff0,   1, 0x04, 0x00000000 },
+	{ 0x00179c,   1, 0x04, 0x00000000 },
+	{ 0x001228,   1, 0x04, 0x00000400 },
+	{ 0x00122c,   1, 0x04, 0x00000300 },
+	{ 0x001230,   1, 0x04, 0x00010001 },
+	{ 0x0007f8,   1, 0x04, 0x00000000 },
+	{ 0x0015b4,   1, 0x04, 0x00000001 },
+	{ 0x0015cc,   1, 0x04, 0x00000000 },
+	{ 0x001534,   1, 0x04, 0x00000000 },
+	{ 0x000fb0,   1, 0x04, 0x00000000 },
+	{ 0x0015d0,   1, 0x04, 0x00000000 },
+	{ 0x00153c,   1, 0x04, 0x00000000 },
+	{ 0x0016b4,   1, 0x04, 0x00000003 },
+	{ 0x000fbc,   4, 0x04, 0x0000ffff },
+	{ 0x000df8,   2, 0x04, 0x00000000 },
+	{ 0x001948,   1, 0x04, 0x00000000 },
+	{ 0x001970,   1, 0x04, 0x00000001 },
+	{ 0x00161c,   1, 0x04, 0x000009f0 },
+	{ 0x000dcc,   1, 0x04, 0x00000010 },
+	{ 0x00163c,   1, 0x04, 0x00000000 },
+	{ 0x0015e4,   1, 0x04, 0x00000000 },
+	{ 0x001160,  32, 0x04, 0x25e00040 },
+	{ 0x001880,  32, 0x04, 0x00000000 },
+	{ 0x000f84,   2, 0x04, 0x00000000 },
+	{ 0x0017c8,   2, 0x04, 0x00000000 },
+	{ 0x0017d0,   1, 0x04, 0x000000ff },
+	{ 0x0017d4,   1, 0x04, 0xffffffff },
+	{ 0x0017d8,   1, 0x04, 0x00000002 },
+	{ 0x0017dc,   1, 0x04, 0x00000000 },
+	{ 0x0015f4,   2, 0x04, 0x00000000 },
+	{ 0x001434,   2, 0x04, 0x00000000 },
+	{ 0x000d74,   1, 0x04, 0x00000000 },
+	{ 0x000dec,   1, 0x04, 0x00000001 },
+	{ 0x0013a4,   1, 0x04, 0x00000000 },
+	{ 0x001318,   1, 0x04, 0x00000001 },
+	{ 0x001644,   1, 0x04, 0x00000000 },
+	{ 0x000748,   1, 0x04, 0x00000000 },
+	{ 0x000de8,   1, 0x04, 0x00000000 },
+	{ 0x001648,   1, 0x04, 0x00000000 },
+	{ 0x0012a4,   1, 0x04, 0x00000000 },
+	{ 0x001120,   4, 0x04, 0x00000000 },
+	{ 0x001118,   1, 0x04, 0x00000000 },
+	{ 0x00164c,   1, 0x04, 0x00000000 },
+	{ 0x001658,   1, 0x04, 0x00000000 },
+	{ 0x001910,   1, 0x04, 0x00000290 },
+	{ 0x001518,   1, 0x04, 0x00000000 },
+	{ 0x00165c,   1, 0x04, 0x00000001 },
+	{ 0x001520,   1, 0x04, 0x00000000 },
+	{ 0x001604,   1, 0x04, 0x00000000 },
+	{ 0x001570,   1, 0x04, 0x00000000 },
+	{ 0x0013b0,   2, 0x04, 0x3f800000 },
+	{ 0x00020c,   1, 0x04, 0x00000000 },
+	{ 0x001670,   1, 0x04, 0x30201000 },
+	{ 0x001674,   1, 0x04, 0x70605040 },
+	{ 0x001678,   1, 0x04, 0xb8a89888 },
+	{ 0x00167c,   1, 0x04, 0xf8e8d8c8 },
+	{ 0x00166c,   1, 0x04, 0x00000000 },
+	{ 0x001680,   1, 0x04, 0x00ffff00 },
+	{ 0x0012d0,   1, 0x04, 0x00000003 },
+	{ 0x0012d4,   1, 0x04, 0x00000002 },
+	{ 0x001684,   2, 0x04, 0x00000000 },
+	{ 0x000dac,   2, 0x04, 0x00001b02 },
+	{ 0x000db4,   1, 0x04, 0x00000000 },
+	{ 0x00168c,   1, 0x04, 0x00000000 },
+	{ 0x0015bc,   1, 0x04, 0x00000000 },
+	{ 0x00156c,   1, 0x04, 0x00000000 },
+	{ 0x00187c,   1, 0x04, 0x00000000 },
+	{ 0x001110,   1, 0x04, 0x00000001 },
+	{ 0x000dc0,   3, 0x04, 0x00000000 },
+	{ 0x001234,   1, 0x04, 0x00000000 },
+	{ 0x001690,   1, 0x04, 0x00000000 },
+	{ 0x0012ac,   1, 0x04, 0x00000001 },
+	{ 0x0002c4,   1, 0x04, 0x00000000 },
+	{ 0x000790,   5, 0x04, 0x00000000 },
+	{ 0x00077c,   1, 0x04, 0x00000000 },
+	{ 0x001000,   1, 0x04, 0x00000010 },
+	{ 0x0010fc,   1, 0x04, 0x00000000 },
+	{ 0x001290,   1, 0x04, 0x00000000 },
+	{ 0x000218,   1, 0x04, 0x00000010 },
+	{ 0x0012d8,   1, 0x04, 0x00000000 },
+	{ 0x0012dc,   1, 0x04, 0x00000010 },
+	{ 0x000d94,   1, 0x04, 0x00000001 },
+	{ 0x00155c,   2, 0x04, 0x00000000 },
+	{ 0x001564,   1, 0x04, 0x00001fff },
+	{ 0x001574,   2, 0x04, 0x00000000 },
+	{ 0x00157c,   1, 0x04, 0x003fffff },
+	{ 0x001354,   1, 0x04, 0x00000000 },
+	{ 0x001664,   1, 0x04, 0x00000000 },
+	{ 0x001610,   1, 0x04, 0x00000012 },
+	{ 0x001608,   2, 0x04, 0x00000000 },
+	{ 0x00162c,   1, 0x04, 0x00000003 },
+	{ 0x000210,   1, 0x04, 0x00000000 },
+	{ 0x000320,   1, 0x04, 0x00000000 },
+	{ 0x000324,   6, 0x04, 0x3f800000 },
+	{ 0x000750,   1, 0x04, 0x00000000 },
+	{ 0x000760,   1, 0x04, 0x39291909 },
+	{ 0x000764,   1, 0x04, 0x79695949 },
+	{ 0x000768,   1, 0x04, 0xb9a99989 },
+	{ 0x00076c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x000770,   1, 0x04, 0x30201000 },
+	{ 0x000774,   1, 0x04, 0x70605040 },
+	{ 0x000778,   1, 0x04, 0x00009080 },
+	{ 0x000780,   1, 0x04, 0x39291909 },
+	{ 0x000784,   1, 0x04, 0x79695949 },
+	{ 0x000788,   1, 0x04, 0xb9a99989 },
+	{ 0x00078c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x0007d0,   1, 0x04, 0x30201000 },
+	{ 0x0007d4,   1, 0x04, 0x70605040 },
+	{ 0x0007d8,   1, 0x04, 0x00009080 },
+	{ 0x00037c,   1, 0x04, 0x00000001 },
+	{ 0x000740,   2, 0x04, 0x00000000 },
+	{ 0x002600,   1, 0x04, 0x00000000 },
+	{ 0x001918,   1, 0x04, 0x00000000 },
+	{ 0x00191c,   1, 0x04, 0x00000900 },
+	{ 0x001920,   1, 0x04, 0x00000405 },
+	{ 0x001308,   1, 0x04, 0x00000001 },
+	{ 0x001924,   1, 0x04, 0x00000000 },
+	{ 0x0013ac,   1, 0x04, 0x00000000 },
+	{ 0x00192c,   1, 0x04, 0x00000001 },
+	{ 0x00193c,   1, 0x04, 0x00002c1c },
+	{ 0x000d7c,   1, 0x04, 0x00000000 },
+	{ 0x000f8c,   1, 0x04, 0x00000000 },
+	{ 0x0002c0,   1, 0x04, 0x00000001 },
+	{ 0x001510,   1, 0x04, 0x00000000 },
+	{ 0x001940,   1, 0x04, 0x00000000 },
+	{ 0x000ff4,   2, 0x04, 0x00000000 },
+	{ 0x00194c,   2, 0x04, 0x00000000 },
+	{ 0x001968,   1, 0x04, 0x00000000 },
+	{ 0x001590,   1, 0x04, 0x0000003f },
+	{ 0x0007e8,   4, 0x04, 0x00000000 },
+	{ 0x00196c,   1, 0x04, 0x00000011 },
+	{ 0x00197c,   1, 0x04, 0x00000000 },
+	{ 0x000fcc,   2, 0x04, 0x00000000 },
+	{ 0x0002d8,   1, 0x04, 0x00000040 },
+	{ 0x001980,   1, 0x04, 0x00000080 },
+	{ 0x001504,   1, 0x04, 0x00000080 },
+	{ 0x001984,   1, 0x04, 0x00000000 },
+	{ 0x000300,   1, 0x04, 0x00000001 },
+	{ 0x0013a8,   1, 0x04, 0x00000000 },
+	{ 0x0012ec,   1, 0x04, 0x00000000 },
+	{ 0x001310,   1, 0x04, 0x00000000 },
+	{ 0x001314,   1, 0x04, 0x00000001 },
+	{ 0x001380,   1, 0x04, 0x00000000 },
+	{ 0x001384,   4, 0x04, 0x00000001 },
+	{ 0x001394,   1, 0x04, 0x00000000 },
+	{ 0x00139c,   1, 0x04, 0x00000000 },
+	{ 0x001398,   1, 0x04, 0x00000000 },
+	{ 0x001594,   1, 0x04, 0x00000000 },
+	{ 0x001598,   4, 0x04, 0x00000001 },
+	{ 0x000f54,   3, 0x04, 0x00000000 },
+	{ 0x0019bc,   1, 0x04, 0x00000000 },
+	{ 0x000f9c,   2, 0x04, 0x00000000 },
+	{ 0x0012cc,   1, 0x04, 0x00000000 },
+	{ 0x0012e8,   1, 0x04, 0x00000000 },
+	{ 0x00130c,   1, 0x04, 0x00000001 },
+	{ 0x001360,   8, 0x04, 0x00000000 },
+	{ 0x00133c,   2, 0x04, 0x00000001 },
+	{ 0x001344,   1, 0x04, 0x00000002 },
+	{ 0x001348,   2, 0x04, 0x00000001 },
+	{ 0x001350,   1, 0x04, 0x00000002 },
+	{ 0x001358,   1, 0x04, 0x00000001 },
+	{ 0x0012e4,   1, 0x04, 0x00000000 },
+	{ 0x00131c,   1, 0x04, 0x00000000 },
+	{ 0x001320,   3, 0x04, 0x00000000 },
+	{ 0x0019c0,   1, 0x04, 0x00000000 },
+	{ 0x001140,   1, 0x04, 0x00000000 },
+	{ 0x0019c4,   1, 0x04, 0x00000000 },
+	{ 0x0019c8,   1, 0x04, 0x00001500 },
+	{ 0x00135c,   1, 0x04, 0x00000000 },
+	{ 0x000f90,   1, 0x04, 0x00000000 },
+	{ 0x0019e0,   8, 0x04, 0x00000001 },
+	{ 0x0019cc,   1, 0x04, 0x00000001 },
+	{ 0x0015b8,   1, 0x04, 0x00000000 },
+	{ 0x001a00,   1, 0x04, 0x00001111 },
+	{ 0x001a04,   7, 0x04, 0x00000000 },
+	{ 0x000d6c,   2, 0x04, 0xffff0000 },
+	{ 0x0010f8,   1, 0x04, 0x00001010 },
+	{ 0x000d80,   5, 0x04, 0x00000000 },
+	{ 0x000da0,   1, 0x04, 0x00000000 },
+	{ 0x001508,   1, 0x04, 0x80000000 },
+	{ 0x00150c,   1, 0x04, 0x40000000 },
+	{ 0x001668,   1, 0x04, 0x00000000 },
+	{ 0x000318,   2, 0x04, 0x00000008 },
+	{ 0x000d9c,   1, 0x04, 0x00000001 },
+	{ 0x0007dc,   1, 0x04, 0x00000000 },
+	{ 0x00074c,   1, 0x04, 0x00000055 },
+	{ 0x001420,   1, 0x04, 0x00000003 },
+	{ 0x0017bc,   2, 0x04, 0x00000000 },
+	{ 0x0017c4,   1, 0x04, 0x00000001 },
+	{ 0x001008,   1, 0x04, 0x00000008 },
+	{ 0x00100c,   1, 0x04, 0x00000040 },
+	{ 0x001010,   1, 0x04, 0x0000012c },
+	{ 0x000d60,   1, 0x04, 0x00000040 },
+	{ 0x00075c,   1, 0x04, 0x00000003 },
+	{ 0x001018,   1, 0x04, 0x00000020 },
+	{ 0x00101c,   1, 0x04, 0x00000001 },
+	{ 0x001020,   1, 0x04, 0x00000020 },
+	{ 0x001024,   1, 0x04, 0x00000001 },
+	{ 0x001444,   3, 0x04, 0x00000000 },
+	{ 0x000360,   1, 0x04, 0x20164010 },
+	{ 0x000364,   1, 0x04, 0x00000020 },
+	{ 0x000368,   1, 0x04, 0x00000000 },
+	{ 0x000de4,   1, 0x04, 0x00000000 },
+	{ 0x000204,   1, 0x04, 0x00000006 },
+	{ 0x000208,   1, 0x04, 0x00000000 },
+	{ 0x0002cc,   1, 0x04, 0x003fffff },
+	{ 0x0002d0,   1, 0x04, 0x00000c48 },
+	{ 0x001220,   1, 0x04, 0x00000005 },
+	{ 0x000fdc,   1, 0x04, 0x00000000 },
+	{ 0x000f98,   1, 0x04, 0x00300008 },
+	{ 0x001284,   1, 0x04, 0x04000080 },
+	{ 0x001450,   1, 0x04, 0x00300008 },
+	{ 0x001454,   1, 0x04, 0x04000080 },
+	{ 0x000214,   1, 0x04, 0x00000000 },
+	{}
+};
 
-	/* allocate memory to for a "channel", which we'll use to generate
-	 * the default context values
-	 */
-	ret = nouveau_gpuobj_new(nv_object(priv), NULL, size, 0x1000,
-				 NVOBJ_FLAG_ZERO_ALLOC, &info->chan);
-	chan = info->chan;
-	if (ret) {
-		nv_error(priv, "failed to allocate channel memory, %d\n", ret);
-		return ret;
-	}
+struct nvc0_graph_init
+nvc0_grctx_init_902d[] = {
+	{ 0x000200,   1, 0x04, 0x000000cf },
+	{ 0x000204,   1, 0x04, 0x00000001 },
+	{ 0x000208,   1, 0x04, 0x00000020 },
+	{ 0x00020c,   1, 0x04, 0x00000001 },
+	{ 0x000210,   1, 0x04, 0x00000000 },
+	{ 0x000214,   1, 0x04, 0x00000080 },
+	{ 0x000218,   2, 0x04, 0x00000100 },
+	{ 0x000220,   2, 0x04, 0x00000000 },
+	{ 0x000230,   1, 0x04, 0x000000cf },
+	{ 0x000234,   1, 0x04, 0x00000001 },
+	{ 0x000238,   1, 0x04, 0x00000020 },
+	{ 0x00023c,   1, 0x04, 0x00000001 },
+	{ 0x000244,   1, 0x04, 0x00000080 },
+	{ 0x000248,   2, 0x04, 0x00000100 },
+	{}
+};
 
-	/* PGD pointer */
-	nv_wo32(chan, 0x0200, lower_32_bits(chan->addr + 0x1000));
-	nv_wo32(chan, 0x0204, upper_32_bits(chan->addr + 0x1000));
-	nv_wo32(chan, 0x0208, 0xffffffff);
-	nv_wo32(chan, 0x020c, 0x000000ff);
+struct nvc0_graph_init
+nvc0_grctx_init_9039[] = {
+	{ 0x00030c,   3, 0x04, 0x00000000 },
+	{ 0x000320,   1, 0x04, 0x00000000 },
+	{ 0x000238,   2, 0x04, 0x00000000 },
+	{ 0x000318,   2, 0x04, 0x00000000 },
+	{}
+};
 
-	/* PGT[0] pointer */
-	nv_wo32(chan, 0x1000, 0x00000000);
-	nv_wo32(chan, 0x1004, 0x00000001 | (chan->addr + 0x2000) >> 8);
+struct nvc0_graph_init
+nvc0_grctx_init_90c0[] = {
+	{ 0x00270c,   8, 0x20, 0x00000000 },
+	{ 0x00030c,   1, 0x04, 0x00000001 },
+	{ 0x001944,   1, 0x04, 0x00000000 },
+	{ 0x000758,   1, 0x04, 0x00000100 },
+	{ 0x0002c4,   1, 0x04, 0x00000000 },
+	{ 0x000790,   5, 0x04, 0x00000000 },
+	{ 0x00077c,   1, 0x04, 0x00000000 },
+	{ 0x000204,   3, 0x04, 0x00000000 },
+	{ 0x000214,   1, 0x04, 0x00000000 },
+	{ 0x00024c,   1, 0x04, 0x00000000 },
+	{ 0x000d94,   1, 0x04, 0x00000001 },
+	{ 0x001608,   2, 0x04, 0x00000000 },
+	{ 0x001664,   1, 0x04, 0x00000000 },
+	{}
+};
 
-	/* identity-map the whole "channel" into its own vm */
-	for (i = 0; i < size / 4096; i++) {
-		u64 addr = ((chan->addr + (i * 4096)) >> 8) | 1;
-		nv_wo32(chan, 0x2000 + (i * 8), lower_32_bits(addr));
-		nv_wo32(chan, 0x2004 + (i * 8), upper_32_bits(addr));
-	}
+struct nvc0_graph_init
+nvc0_grctx_init_base[] = {
+	{ 0x400204,   2, 0x04, 0x00000000 },
+	{}
+};
 
-	/* context pointer (virt) */
-	nv_wo32(chan, 0x0210, 0x00080004);
-	nv_wo32(chan, 0x0214, 0x00000000);
+struct nvc0_graph_init
+nvc0_grctx_init_unk40xx[] = {
+	{ 0x404004,  10, 0x04, 0x00000000 },
+	{ 0x404044,   1, 0x04, 0x00000000 },
+	{ 0x404094,   1, 0x04, 0x00000000 },
+	{ 0x404098,  12, 0x04, 0x00000000 },
+	{ 0x4040c8,   1, 0x04, 0xf0000087 },
+	{ 0x4040d0,   6, 0x04, 0x00000000 },
+	{ 0x4040e8,   1, 0x04, 0x00001000 },
+	{ 0x4040f8,   1, 0x04, 0x00000000 },
+	{ 0x404130,   1, 0x04, 0x00000000 },
+	{ 0x404134,   1, 0x04, 0x00000000 },
+	{ 0x404138,   1, 0x04, 0x20000040 },
+	{ 0x404150,   1, 0x04, 0x0000002e },
+	{ 0x404154,   1, 0x04, 0x00000400 },
+	{ 0x404158,   1, 0x04, 0x00000200 },
+	{ 0x404164,   1, 0x04, 0x00000055 },
+	{ 0x404168,   1, 0x04, 0x00000000 },
+	{ 0x404174,   1, 0x04, 0x00000000 },
+	{ 0x404178,   2, 0x04, 0x00000000 },
+	{ 0x404200,   8, 0x04, 0x00000000 },
+	{}
+};
 
-	bar->flush(bar);
+struct nvc0_graph_init
+nvc0_grctx_init_unk44xx[] = {
+	{ 0x404404,  14, 0x04, 0x00000000 },
+	{ 0x404460,   2, 0x04, 0x00000000 },
+	{ 0x404468,   1, 0x04, 0x00ffffff },
+	{ 0x40446c,   1, 0x04, 0x00000000 },
+	{ 0x404480,   1, 0x04, 0x00000001 },
+	{ 0x404498,   1, 0x04, 0x00000001 },
+	{}
+};
 
-	nv_wr32(priv, 0x100cb8, (chan->addr + 0x1000) >> 8);
-	nv_wr32(priv, 0x100cbc, 0x80000001);
-	nv_wait(priv, 0x100c80, 0x00008000, 0x00008000);
+struct nvc0_graph_init
+nvc0_grctx_init_unk46xx[] = {
+	{ 0x404604,   1, 0x04, 0x00000015 },
+	{ 0x404608,   1, 0x04, 0x00000000 },
+	{ 0x40460c,   1, 0x04, 0x00002e00 },
+	{ 0x404610,   1, 0x04, 0x00000100 },
+	{ 0x404618,   8, 0x04, 0x00000000 },
+	{ 0x404638,   1, 0x04, 0x00000004 },
+	{ 0x40463c,   8, 0x04, 0x00000000 },
+	{ 0x40465c,   1, 0x04, 0x007f0100 },
+	{ 0x404660,   7, 0x04, 0x00000000 },
+	{ 0x40467c,   1, 0x04, 0x00000002 },
+	{ 0x404680,   8, 0x04, 0x00000000 },
+	{ 0x4046a0,   1, 0x04, 0x007f0080 },
+	{ 0x4046a4,  18, 0x04, 0x00000000 },
+	{ 0x4046f0,   2, 0x04, 0x00000000 },
+	{}
+};
 
-	/* setup default state for mmio list construction */
-	info->data = priv->mmio_data;
-	info->mmio = priv->mmio_list;
-	info->addr = 0x2000 + (i * 8);
-	info->priv = priv;
-	info->buffer_nr = 0;
+struct nvc0_graph_init
+nvc0_grctx_init_unk47xx[] = {
+	{ 0x404700,  13, 0x04, 0x00000000 },
+	{ 0x404734,   1, 0x04, 0x00000100 },
+	{ 0x404738,   8, 0x04, 0x00000000 },
+	{}
+};
 
-	if (priv->firmware) {
-		nv_wr32(priv, 0x409840, 0x00000030);
-		nv_wr32(priv, 0x409500, 0x80000000 | chan->addr >> 12);
-		nv_wr32(priv, 0x409504, 0x00000003);
-		if (!nv_wait(priv, 0x409800, 0x00000010, 0x00000010))
-			nv_error(priv, "load_ctx timeout\n");
+struct nvc0_graph_init
+nvc0_grctx_init_unk58xx[] = {
+	{ 0x405800,   1, 0x04, 0x078000bf },
+	{ 0x405830,   1, 0x04, 0x02180000 },
+	{ 0x405834,   2, 0x04, 0x00000000 },
+	{ 0x405854,   1, 0x04, 0x00000000 },
+	{ 0x405870,   4, 0x04, 0x00000001 },
+	{ 0x405a00,   2, 0x04, 0x00000000 },
+	{ 0x405a18,   1, 0x04, 0x00000000 },
+	{}
+};
 
-		nv_wo32(chan, 0x8001c, 1);
-		nv_wo32(chan, 0x80020, 0);
-		nv_wo32(chan, 0x80028, 0);
-		nv_wo32(chan, 0x8002c, 0);
-		bar->flush(bar);
-		return 0;
-	}
+struct nvc0_graph_init
+nvc0_grctx_init_unk60xx[] = {
+	{ 0x406020,   1, 0x04, 0x000103c1 },
+	{ 0x406028,   4, 0x04, 0x00000001 },
+	{}
+};
 
-	/* HUB_FUC(SET_CHAN) */
-	nv_wr32(priv, 0x409840, 0x80000000);
-	nv_wr32(priv, 0x409500, 0x80000000 | chan->addr >> 12);
-	nv_wr32(priv, 0x409504, 0x00000001);
-	if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) {
-		nv_error(priv, "HUB_SET_CHAN timeout\n");
-		nvc0_graph_ctxctl_debug(priv);
-		nouveau_gpuobj_ref(NULL, &info->chan);
-		return -EBUSY;
-	}
+struct nvc0_graph_init
+nvc0_grctx_init_unk64xx[] = {
+	{ 0x4064a8,   1, 0x04, 0x00000000 },
+	{ 0x4064ac,   1, 0x04, 0x00003fff },
+	{ 0x4064b4,   2, 0x04, 0x00000000 },
+	{}
+};
 
-	return 0;
-}
+struct nvc0_graph_init
+nvc0_grctx_init_unk78xx[] = {
+	{ 0x407804,   1, 0x04, 0x00000023 },
+	{ 0x40780c,   1, 0x04, 0x0a418820 },
+	{ 0x407810,   1, 0x04, 0x062080e6 },
+	{ 0x407814,   1, 0x04, 0x020398a4 },
+	{ 0x407818,   1, 0x04, 0x0e629062 },
+	{ 0x40781c,   1, 0x04, 0x0a418820 },
+	{ 0x407820,   1, 0x04, 0x000000e6 },
+	{ 0x4078bc,   1, 0x04, 0x00000103 },
+	{}
+};
 
-void
-nvc0_grctx_data(struct nvc0_grctx *info, u32 size, u32 align, u32 access)
-{
-	info->buffer[info->buffer_nr]  = info->addr;
-	info->buffer[info->buffer_nr] +=  (align - 1);
-	info->buffer[info->buffer_nr] &= ~(align - 1);
-	info->addr = info->buffer[info->buffer_nr++] + size;
+struct nvc0_graph_init
+nvc0_grctx_init_unk80xx[] = {
+	{ 0x408000,   2, 0x04, 0x00000000 },
+	{ 0x408008,   1, 0x04, 0x00000018 },
+	{ 0x40800c,   2, 0x04, 0x00000000 },
+	{ 0x408014,   1, 0x04, 0x00000069 },
+	{ 0x408018,   1, 0x04, 0xe100e100 },
+	{ 0x408064,   1, 0x04, 0x00000000 },
+	{}
+};
 
-	info->data->size = size;
-	info->data->align = align;
-	info->data->access = access;
-	info->data++;
-}
+struct nvc0_graph_init
+nvc0_grctx_init_rop[] = {
+	{ 0x408800,   1, 0x04, 0x02802a3c },
+	{ 0x408804,   1, 0x04, 0x00000040 },
+	{ 0x408808,   1, 0x04, 0x0003e00d },
+	{ 0x408900,   1, 0x04, 0x3080b801 },
+	{ 0x408904,   1, 0x04, 0x02000001 },
+	{ 0x408908,   1, 0x04, 0x00c80929 },
+	{ 0x408980,   1, 0x04, 0x0000011d },
+	{}
+};
 
-void
-nvc0_grctx_mmio(struct nvc0_grctx *info, u32 addr, u32 data, u32 shift, u32 buf)
-{
-	struct nvc0_graph_priv *priv = info->priv;
+struct nvc0_graph_init
+nvc0_grctx_init_gpc_0[] = {
+	{ 0x418380,   1, 0x04, 0x00000016 },
+	{ 0x418400,   1, 0x04, 0x38004e00 },
+	{ 0x418404,   1, 0x04, 0x71e0ffff },
+	{ 0x418408,   1, 0x04, 0x00000000 },
+	{ 0x41840c,   1, 0x04, 0x00001008 },
+	{ 0x418410,   1, 0x04, 0x0fff0fff },
+	{ 0x418414,   1, 0x04, 0x00200fff },
+	{ 0x418450,   6, 0x04, 0x00000000 },
+	{ 0x418468,   1, 0x04, 0x00000001 },
+	{ 0x41846c,   2, 0x04, 0x00000000 },
+	{ 0x418600,   1, 0x04, 0x0000001f },
+	{ 0x418684,   1, 0x04, 0x0000000f },
+	{ 0x418700,   1, 0x04, 0x00000002 },
+	{ 0x418704,   1, 0x04, 0x00000080 },
+	{ 0x418708,   1, 0x04, 0x00000000 },
+	{ 0x41870c,   1, 0x04, 0x07c80000 },
+	{ 0x418710,   1, 0x04, 0x00000000 },
+	{ 0x418800,   1, 0x04, 0x0006860a },
+	{ 0x418808,   3, 0x04, 0x00000000 },
+	{ 0x418828,   1, 0x04, 0x00008442 },
+	{ 0x418830,   1, 0x04, 0x00000001 },
+	{ 0x4188d8,   1, 0x04, 0x00000008 },
+	{ 0x4188e0,   1, 0x04, 0x01000000 },
+	{ 0x4188e8,   5, 0x04, 0x00000000 },
+	{ 0x4188fc,   1, 0x04, 0x00100000 },
+	{ 0x41891c,   1, 0x04, 0x00ff00ff },
+	{ 0x418924,   1, 0x04, 0x00000000 },
+	{ 0x418928,   1, 0x04, 0x00ffff00 },
+	{ 0x41892c,   1, 0x04, 0x0000ff00 },
+	{ 0x418b00,   1, 0x04, 0x00000000 },
+	{ 0x418b08,   1, 0x04, 0x0a418820 },
+	{ 0x418b0c,   1, 0x04, 0x062080e6 },
+	{ 0x418b10,   1, 0x04, 0x020398a4 },
+	{ 0x418b14,   1, 0x04, 0x0e629062 },
+	{ 0x418b18,   1, 0x04, 0x0a418820 },
+	{ 0x418b1c,   1, 0x04, 0x000000e6 },
+	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{ 0x418c08,   1, 0x04, 0x00000001 },
+	{ 0x418c10,   8, 0x04, 0x00000000 },
+	{ 0x418c80,   1, 0x04, 0x20200004 },
+	{ 0x418c8c,   1, 0x04, 0x00000001 },
+	{ 0x419000,   1, 0x04, 0x00000780 },
+	{ 0x419004,   2, 0x04, 0x00000000 },
+	{ 0x419014,   1, 0x04, 0x00000004 },
+	{}
+};
 
-	info->mmio->addr = addr;
-	info->mmio->data = data;
-	info->mmio->shift = shift;
-	info->mmio->buffer = buf;
-	info->mmio++;
+struct nvc0_graph_init
+nvc0_grctx_init_gpc_1[] = {
+	{ 0x418a00,   3, 0x04, 0x00000000 },
+	{ 0x418a0c,   1, 0x04, 0x00010000 },
+	{ 0x418a10,   3, 0x04, 0x00000000 },
+	{ 0x418a20,   3, 0x04, 0x00000000 },
+	{ 0x418a2c,   1, 0x04, 0x00010000 },
+	{ 0x418a30,   3, 0x04, 0x00000000 },
+	{ 0x418a40,   3, 0x04, 0x00000000 },
+	{ 0x418a4c,   1, 0x04, 0x00010000 },
+	{ 0x418a50,   3, 0x04, 0x00000000 },
+	{ 0x418a60,   3, 0x04, 0x00000000 },
+	{ 0x418a6c,   1, 0x04, 0x00010000 },
+	{ 0x418a70,   3, 0x04, 0x00000000 },
+	{ 0x418a80,   3, 0x04, 0x00000000 },
+	{ 0x418a8c,   1, 0x04, 0x00010000 },
+	{ 0x418a90,   3, 0x04, 0x00000000 },
+	{ 0x418aa0,   3, 0x04, 0x00000000 },
+	{ 0x418aac,   1, 0x04, 0x00010000 },
+	{ 0x418ab0,   3, 0x04, 0x00000000 },
+	{ 0x418ac0,   3, 0x04, 0x00000000 },
+	{ 0x418acc,   1, 0x04, 0x00010000 },
+	{ 0x418ad0,   3, 0x04, 0x00000000 },
+	{ 0x418ae0,   3, 0x04, 0x00000000 },
+	{ 0x418aec,   1, 0x04, 0x00010000 },
+	{ 0x418af0,   3, 0x04, 0x00000000 },
+	{}
+};
 
-	if (shift)
-		data |= info->buffer[buf] >> shift;
-	nv_wr32(priv, addr, data);
-}
+struct nvc0_graph_init
+nvc0_grctx_init_tpc[] = {
+	{ 0x419818,   1, 0x04, 0x00000000 },
+	{ 0x41983c,   1, 0x04, 0x00038bc7 },
+	{ 0x419848,   1, 0x04, 0x00000000 },
+	{ 0x419864,   1, 0x04, 0x0000012a },
+	{ 0x419888,   1, 0x04, 0x00000000 },
+	{ 0x419a00,   1, 0x04, 0x000001f0 },
+	{ 0x419a04,   1, 0x04, 0x00000001 },
+	{ 0x419a08,   1, 0x04, 0x00000023 },
+	{ 0x419a0c,   1, 0x04, 0x00020000 },
+	{ 0x419a10,   1, 0x04, 0x00000000 },
+	{ 0x419a14,   1, 0x04, 0x00000200 },
+	{ 0x419b00,   1, 0x04, 0x0a418820 },
+	{ 0x419b04,   1, 0x04, 0x062080e6 },
+	{ 0x419b08,   1, 0x04, 0x020398a4 },
+	{ 0x419b0c,   1, 0x04, 0x0e629062 },
+	{ 0x419b10,   1, 0x04, 0x0a418820 },
+	{ 0x419b14,   1, 0x04, 0x000000e6 },
+	{ 0x419bd0,   1, 0x04, 0x00900103 },
+	{ 0x419be0,   1, 0x04, 0x00000001 },
+	{ 0x419be4,   1, 0x04, 0x00000000 },
+	{ 0x419c00,   1, 0x04, 0x00000002 },
+	{ 0x419c04,   1, 0x04, 0x00000006 },
+	{ 0x419c08,   1, 0x04, 0x00000002 },
+	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{ 0x419cb0,   1, 0x04, 0x00060048 },
+	{ 0x419ce8,   1, 0x04, 0x00000000 },
+	{ 0x419cf4,   1, 0x04, 0x00000183 },
+	{ 0x419d20,   1, 0x04, 0x02180000 },
+	{ 0x419d24,   1, 0x04, 0x00001fff },
+	{ 0x419e04,   3, 0x04, 0x00000000 },
+	{ 0x419e10,   1, 0x04, 0x00000002 },
+	{ 0x419e44,   1, 0x04, 0x001beff2 },
+	{ 0x419e48,   1, 0x04, 0x00000000 },
+	{ 0x419e4c,   1, 0x04, 0x0000000f },
+	{ 0x419e50,  17, 0x04, 0x00000000 },
+	{ 0x419e98,   1, 0x04, 0x00000000 },
+	{ 0x419f50,   2, 0x04, 0x00000000 },
+	{}
+};
 
-int
-nvc0_grctx_fini(struct nvc0_grctx *info)
+void
+nvc0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 {
-	struct nvc0_graph_priv *priv = info->priv;
-	int i;
-
-	/* trigger a context unload by unsetting the "next channel valid" bit
-	 * and faking a context switch interrupt
-	 */
-	nv_mask(priv, 0x409b04, 0x80000000, 0x00000000);
-	nv_wr32(priv, 0x409000, 0x00000100);
-	if (!nv_wait(priv, 0x409b00, 0x80000000, 0x00000000)) {
-		nv_error(priv, "grctx template channel unload timeout\n");
-		return -EBUSY;
-	}
+	int gpc, tpc;
+	u32 offset;
 
-	priv->data = kmalloc(priv->size, GFP_KERNEL);
-	if (priv->data) {
-		for (i = 0; i < priv->size; i += 4)
-			priv->data[i / 4] = nv_ro32(info->chan, 0x80000 + i);
-	}
+	mmio_data(0x002000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
 
-	nouveau_gpuobj_ref(NULL, &info->chan);
-	return priv->data ? 0 : -ENOMEM;
-}
+	mmio_list(0x408004, 0x00000000,  8, 0);
+	mmio_list(0x408008, 0x80000018,  0, 0);
+	mmio_list(0x40800c, 0x00000000,  8, 1);
+	mmio_list(0x408010, 0x80000000,  0, 0);
+	mmio_list(0x418810, 0x80000000, 12, 2);
+	mmio_list(0x419848, 0x10000000, 12, 2);
+	mmio_list(0x419004, 0x00000000,  8, 1);
+	mmio_list(0x419008, 0x00000000,  0, 0);
+	mmio_list(0x418808, 0x00000000,  8, 0);
+	mmio_list(0x41880c, 0x80000018,  0, 0);
 
-static void
-nvc0_grctx_generate_9097(struct nvc0_graph_priv *priv)
-{
-	u32 fermi = nvc0_graph_class(priv);
-	u32 mthd;
+	mmio_list(0x405830, 0x02180000, 0, 0);
 
-	nv_mthd(priv, 0x9097, 0x0800, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0840, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0880, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x08c0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0900, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0940, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0980, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x09c0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0804, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0844, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0884, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x08c4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0904, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0944, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0984, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x09c4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0808, 0x00000400);
-	nv_mthd(priv, 0x9097, 0x0848, 0x00000400);
-	nv_mthd(priv, 0x9097, 0x0888, 0x00000400);
-	nv_mthd(priv, 0x9097, 0x08c8, 0x00000400);
-	nv_mthd(priv, 0x9097, 0x0908, 0x00000400);
-	nv_mthd(priv, 0x9097, 0x0948, 0x00000400);
-	nv_mthd(priv, 0x9097, 0x0988, 0x00000400);
-	nv_mthd(priv, 0x9097, 0x09c8, 0x00000400);
-	nv_mthd(priv, 0x9097, 0x080c, 0x00000300);
-	nv_mthd(priv, 0x9097, 0x084c, 0x00000300);
-	nv_mthd(priv, 0x9097, 0x088c, 0x00000300);
-	nv_mthd(priv, 0x9097, 0x08cc, 0x00000300);
-	nv_mthd(priv, 0x9097, 0x090c, 0x00000300);
-	nv_mthd(priv, 0x9097, 0x094c, 0x00000300);
-	nv_mthd(priv, 0x9097, 0x098c, 0x00000300);
-	nv_mthd(priv, 0x9097, 0x09cc, 0x00000300);
-	nv_mthd(priv, 0x9097, 0x0810, 0x000000cf);
-	nv_mthd(priv, 0x9097, 0x0850, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0890, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x08d0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0910, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0950, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0990, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x09d0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0814, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x0854, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x0894, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x08d4, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x0914, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x0954, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x0994, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x09d4, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x0818, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x0858, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x0898, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x08d8, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x0918, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x0958, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x0998, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x09d8, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x081c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x085c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x089c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x08dc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x091c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x095c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x099c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x09dc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0820, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0860, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x08a0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x08e0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0920, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0960, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x09a0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x09e0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2700, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2720, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2740, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2760, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2780, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27a0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27c0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27e0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2704, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2724, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2744, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2764, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2784, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27a4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27c4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27e4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2708, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2728, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2748, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2768, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2788, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27a8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27c8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27e8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x270c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x272c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x274c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x276c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x278c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27ac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27cc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x27ec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2710, 0x00014000);
-	nv_mthd(priv, 0x9097, 0x2730, 0x00014000);
-	nv_mthd(priv, 0x9097, 0x2750, 0x00014000);
-	nv_mthd(priv, 0x9097, 0x2770, 0x00014000);
-	nv_mthd(priv, 0x9097, 0x2790, 0x00014000);
-	nv_mthd(priv, 0x9097, 0x27b0, 0x00014000);
-	nv_mthd(priv, 0x9097, 0x27d0, 0x00014000);
-	nv_mthd(priv, 0x9097, 0x27f0, 0x00014000);
-	nv_mthd(priv, 0x9097, 0x2714, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x2734, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x2754, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x2774, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x2794, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x27b4, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x27d4, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x27f4, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x1c00, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c10, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c20, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c30, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c40, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c50, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c60, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c70, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c80, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c90, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ca0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cb0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cc0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cd0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ce0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cf0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c04, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c14, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c24, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c34, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c44, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c54, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c64, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c74, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c84, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c94, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ca4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cb4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cc4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cd4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ce4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cf4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c08, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c18, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c28, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c38, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c48, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c58, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c68, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c78, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c88, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c98, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ca8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cb8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cc8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cd8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ce8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cf8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c0c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c1c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c2c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c3c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c4c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c5c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c6c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c7c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c8c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1c9c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cbc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ccc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cdc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1cfc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d00, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d10, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d20, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d30, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d40, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d50, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d60, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d70, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d80, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d90, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1da0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1db0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dc0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dd0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1de0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1df0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d04, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d14, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d24, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d34, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d44, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d54, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d64, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d74, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d84, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d94, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1da4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1db4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dc4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dd4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1de4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1df4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d08, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d18, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d28, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d38, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d48, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d58, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d68, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d78, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d88, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d98, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1da8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1db8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dc8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dd8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1de8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1df8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d0c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d1c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d2c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d3c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d4c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d5c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d6c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d7c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d8c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1d9c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dbc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dcc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ddc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1dfc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f00, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f08, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f10, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f18, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f20, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f28, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f30, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f38, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f40, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f48, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f50, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f58, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f60, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f68, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f70, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f78, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f04, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f0c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f14, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f1c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f24, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f2c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f34, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f3c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f44, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f4c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f54, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f5c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f64, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f6c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f74, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f7c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f80, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f88, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f90, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f98, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fa0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fa8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fb0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fb8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fc0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fc8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fd0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fd8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fe0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fe8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ff0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ff8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f84, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f8c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f94, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1f9c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fa4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fb4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fbc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fc4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fcc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fd4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fdc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fe4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1fec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ff4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1ffc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2200, 0x00000022);
-	nv_mthd(priv, 0x9097, 0x2210, 0x00000022);
-	nv_mthd(priv, 0x9097, 0x2220, 0x00000022);
-	nv_mthd(priv, 0x9097, 0x2230, 0x00000022);
-	nv_mthd(priv, 0x9097, 0x2240, 0x00000022);
-	nv_mthd(priv, 0x9097, 0x2000, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2040, 0x00000011);
-	nv_mthd(priv, 0x9097, 0x2080, 0x00000020);
-	nv_mthd(priv, 0x9097, 0x20c0, 0x00000030);
-	nv_mthd(priv, 0x9097, 0x2100, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x2140, 0x00000051);
-	nv_mthd(priv, 0x9097, 0x200c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x204c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x208c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x20cc, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x210c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x214c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x2010, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2050, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2090, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x20d0, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x2110, 0x00000003);
-	nv_mthd(priv, 0x9097, 0x2150, 0x00000004);
-	nv_mthd(priv, 0x9097, 0x0380, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03a0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03c0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03e0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0384, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03a4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03c4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03e4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0388, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03a8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03c8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03e8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x038c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03ac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03cc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x03ec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0700, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0710, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0720, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0730, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0704, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0714, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0724, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0734, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0708, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0718, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0728, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0738, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2800, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2804, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2808, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x280c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2810, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2814, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2818, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x281c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2820, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2824, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2828, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x282c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2830, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2834, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2838, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x283c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2840, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2844, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2848, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x284c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2850, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2854, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2858, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x285c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2860, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2864, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2868, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x286c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2870, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2874, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2878, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x287c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2880, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2884, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2888, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x288c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2890, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2894, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2898, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x289c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28a0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28a4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28a8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28ac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28b0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28b4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28b8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28bc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28c0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28c4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28c8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28cc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28d0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28d4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28d8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28dc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28e0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28e4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28e8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28ec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28f0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28f4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28f8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x28fc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2900, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2904, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2908, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x290c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2910, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2914, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2918, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x291c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2920, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2924, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2928, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x292c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2930, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2934, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2938, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x293c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2940, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2944, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2948, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x294c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2950, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2954, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2958, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x295c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2960, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2964, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2968, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x296c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2970, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2974, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2978, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x297c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2980, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2984, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2988, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x298c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2990, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2994, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2998, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x299c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29a0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29a4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29a8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29ac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29b0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29b4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29b8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29bc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29c0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29c4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29c8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29cc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29d0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29d4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29d8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29dc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29e0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29e4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29e8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29ec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29f0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29f4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29f8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x29fc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a00, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a20, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a40, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a60, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a80, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0aa0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ac0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ae0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b00, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b20, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b40, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b60, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b80, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ba0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bc0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0be0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a04, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a24, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a44, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a64, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a84, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0aa4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ac4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ae4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b04, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b24, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b44, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b64, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b84, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ba4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bc4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0be4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a08, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a28, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a48, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a68, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a88, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0aa8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ac8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ae8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b08, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b28, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b48, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b68, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b88, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ba8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bc8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0be8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a0c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a2c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a4c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a6c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a8c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0aac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0acc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0aec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b0c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b2c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b4c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b6c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b8c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bcc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a10, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a30, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a50, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a70, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a90, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ab0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ad0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0af0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b10, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b30, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b50, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b70, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b90, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bb0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bd0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bf0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a14, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a34, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a54, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a74, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0a94, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ab4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ad4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0af4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b14, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b34, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b54, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b74, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0b94, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bb4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bd4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0bf4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c00, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c10, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c20, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c30, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c40, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c50, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c60, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c70, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c80, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c90, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ca0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cb0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cc0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cd0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ce0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cf0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c04, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c14, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c24, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c34, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c44, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c54, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c64, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c74, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c84, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c94, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ca4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cb4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cc4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cd4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ce4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cf4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c08, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c18, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c28, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c38, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c48, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c58, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c68, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c78, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c88, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c98, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ca8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cb8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cc8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cd8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ce8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0cf8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0c0c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0c1c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0c2c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0c3c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0c4c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0c5c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0c6c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0c7c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0c8c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0c9c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0cac, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0cbc, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0ccc, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0cdc, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0cec, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0cfc, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0d00, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d08, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d10, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d18, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d20, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d28, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d30, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d38, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d04, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d0c, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d14, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d1c, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d24, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d2c, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d34, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d3c, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e00, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e10, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e20, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e30, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e40, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e50, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e60, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e70, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e80, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e90, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ea0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0eb0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ec0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ed0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ee0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ef0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0e04, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e14, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e24, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e34, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e44, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e54, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e64, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e74, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e84, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e94, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ea4, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0eb4, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ec4, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ed4, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ee4, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ef4, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e08, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e18, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e28, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e38, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e48, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e58, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e68, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e78, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e88, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0e98, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ea8, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0eb8, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ec8, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ed8, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ee8, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0ef8, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d40, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d48, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d50, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d58, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d44, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d4c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d54, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d5c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1e00, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e20, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e40, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e60, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e80, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ea0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ec0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ee0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e04, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e24, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e44, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e64, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e84, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ea4, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ec4, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ee4, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e08, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e28, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e48, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e68, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e88, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1ea8, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1ec8, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1ee8, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e0c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e2c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e4c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e6c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e8c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1eac, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ecc, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1eec, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e10, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e30, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e50, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e70, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e90, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1eb0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ed0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ef0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e14, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e34, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e54, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e74, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e94, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1eb4, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1ed4, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1ef4, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1e18, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e38, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e58, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e78, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1e98, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1eb8, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ed8, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1ef8, 0x00000001);
-	if (fermi == 0x9097) {
-		for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4)
-			nv_mthd(priv, 0x9097, mthd, 0x00000000);
+	for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
+		for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+			u32 addr = TPC_UNIT(gpc, tpc, 0x0520);
+			mmio_list(addr, 0x02180000 | offset, 0, 0);
+			offset += 0x0324;
+		}
 	}
-	nv_mthd(priv, 0x9097, 0x030c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1944, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1514, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d68, 0x0000ffff);
-	nv_mthd(priv, 0x9097, 0x121c, 0x0fac6881);
-	nv_mthd(priv, 0x9097, 0x0fac, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1538, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x0fe0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0fe4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0fe8, 0x00000014);
-	nv_mthd(priv, 0x9097, 0x0fec, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x0ff0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x179c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1228, 0x00000400);
-	nv_mthd(priv, 0x9097, 0x122c, 0x00000300);
-	nv_mthd(priv, 0x9097, 0x1230, 0x00010001);
-	nv_mthd(priv, 0x9097, 0x07f8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x15b4, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x15cc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1534, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0fb0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x15d0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x153c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x16b4, 0x00000003);
-	nv_mthd(priv, 0x9097, 0x0fbc, 0x0000ffff);
-	nv_mthd(priv, 0x9097, 0x0fc0, 0x0000ffff);
-	nv_mthd(priv, 0x9097, 0x0fc4, 0x0000ffff);
-	nv_mthd(priv, 0x9097, 0x0fc8, 0x0000ffff);
-	nv_mthd(priv, 0x9097, 0x0df8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0dfc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1948, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1970, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x161c, 0x000009f0);
-	nv_mthd(priv, 0x9097, 0x0dcc, 0x00000010);
-	nv_mthd(priv, 0x9097, 0x163c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x15e4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1160, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1164, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1168, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x116c, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1170, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1174, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1178, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x117c, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1180, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1184, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1188, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x118c, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1190, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1194, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1198, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x119c, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11a0, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11a4, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11a8, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11ac, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11b0, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11b4, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11b8, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11bc, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11c0, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11c4, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11c8, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11cc, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11d0, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11d4, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11d8, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x11dc, 0x25e00040);
-	nv_mthd(priv, 0x9097, 0x1880, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1884, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1888, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x188c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1890, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1894, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1898, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x189c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18a0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18a4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18a8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18ac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18b0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18b4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18b8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18bc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18c0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18c4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18c8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18cc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18d0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18d4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18d8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18dc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18e0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18e4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18e8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18ec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18f0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18f4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18f8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x18fc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0f84, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0f88, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x17c8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x17cc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x17d0, 0x000000ff);
-	nv_mthd(priv, 0x9097, 0x17d4, 0xffffffff);
-	nv_mthd(priv, 0x9097, 0x17d8, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x17dc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x15f4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x15f8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1434, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1438, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d74, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0dec, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x13a4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1318, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1644, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0748, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0de8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1648, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x12a4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1120, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1124, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1128, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x112c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1118, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x164c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1658, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1910, 0x00000290);
-	nv_mthd(priv, 0x9097, 0x1518, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x165c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1520, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1604, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1570, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x13b0, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x13b4, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x020c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1670, 0x30201000);
-	nv_mthd(priv, 0x9097, 0x1674, 0x70605040);
-	nv_mthd(priv, 0x9097, 0x1678, 0xb8a89888);
-	nv_mthd(priv, 0x9097, 0x167c, 0xf8e8d8c8);
-	nv_mthd(priv, 0x9097, 0x166c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1680, 0x00ffff00);
-	nv_mthd(priv, 0x9097, 0x12d0, 0x00000003);
-	nv_mthd(priv, 0x9097, 0x12d4, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1684, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1688, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0dac, 0x00001b02);
-	nv_mthd(priv, 0x9097, 0x0db0, 0x00001b02);
-	nv_mthd(priv, 0x9097, 0x0db4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x168c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x15bc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x156c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x187c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1110, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x0dc0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0dc4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0dc8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1234, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1690, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x12ac, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x02c4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0790, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0794, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0798, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x079c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x07a0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x077c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1000, 0x00000010);
-	nv_mthd(priv, 0x9097, 0x10fc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1290, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0218, 0x00000010);
-	nv_mthd(priv, 0x9097, 0x12d8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x12dc, 0x00000010);
-	nv_mthd(priv, 0x9097, 0x0d94, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x155c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1560, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1564, 0x00001fff);
-	nv_mthd(priv, 0x9097, 0x1574, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1578, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x157c, 0x003fffff);
-	nv_mthd(priv, 0x9097, 0x1354, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1664, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1610, 0x00000012);
-	nv_mthd(priv, 0x9097, 0x1608, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x160c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x162c, 0x00000003);
-	nv_mthd(priv, 0x9097, 0x0210, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0320, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0324, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0328, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x032c, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0330, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0334, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0338, 0x3f800000);
-	nv_mthd(priv, 0x9097, 0x0750, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0760, 0x39291909);
-	nv_mthd(priv, 0x9097, 0x0764, 0x79695949);
-	nv_mthd(priv, 0x9097, 0x0768, 0xb9a99989);
-	nv_mthd(priv, 0x9097, 0x076c, 0xf9e9d9c9);
-	nv_mthd(priv, 0x9097, 0x0770, 0x30201000);
-	nv_mthd(priv, 0x9097, 0x0774, 0x70605040);
-	nv_mthd(priv, 0x9097, 0x0778, 0x00009080);
-	nv_mthd(priv, 0x9097, 0x0780, 0x39291909);
-	nv_mthd(priv, 0x9097, 0x0784, 0x79695949);
-	nv_mthd(priv, 0x9097, 0x0788, 0xb9a99989);
-	nv_mthd(priv, 0x9097, 0x078c, 0xf9e9d9c9);
-	nv_mthd(priv, 0x9097, 0x07d0, 0x30201000);
-	nv_mthd(priv, 0x9097, 0x07d4, 0x70605040);
-	nv_mthd(priv, 0x9097, 0x07d8, 0x00009080);
-	nv_mthd(priv, 0x9097, 0x037c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x0740, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0744, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x2600, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1918, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x191c, 0x00000900);
-	nv_mthd(priv, 0x9097, 0x1920, 0x00000405);
-	nv_mthd(priv, 0x9097, 0x1308, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1924, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x13ac, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x192c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x193c, 0x00002c1c);
-	nv_mthd(priv, 0x9097, 0x0d7c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0f8c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x02c0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1510, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1940, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ff4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0ff8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x194c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1950, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1968, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1590, 0x0000003f);
-	nv_mthd(priv, 0x9097, 0x07e8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x07ec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x07f0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x07f4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x196c, 0x00000011);
-	nv_mthd(priv, 0x9097, 0x197c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0fcc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0fd0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x02d8, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x1980, 0x00000080);
-	nv_mthd(priv, 0x9097, 0x1504, 0x00000080);
-	nv_mthd(priv, 0x9097, 0x1984, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0300, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x13a8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x12ec, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1310, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1314, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1380, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1384, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1388, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x138c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1390, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1394, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x139c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1398, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1594, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1598, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x159c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x15a0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x15a4, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x0f54, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0f58, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0f5c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x19bc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0f9c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0fa0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x12cc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x12e8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x130c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1360, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1364, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1368, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x136c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1370, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1374, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1378, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x137c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x133c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1340, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1344, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1348, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x134c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1350, 0x00000002);
-	nv_mthd(priv, 0x9097, 0x1358, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x12e4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x131c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1320, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1324, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1328, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x19c0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1140, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x19c4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x19c8, 0x00001500);
-	nv_mthd(priv, 0x9097, 0x135c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0f90, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x19e0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x19e4, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x19e8, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x19ec, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x19f0, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x19f4, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x19f8, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x19fc, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x19cc, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x15b8, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1a00, 0x00001111);
-	nv_mthd(priv, 0x9097, 0x1a04, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1a08, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1a0c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1a10, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1a14, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1a18, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1a1c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d6c, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x0d70, 0xffff0000);
-	nv_mthd(priv, 0x9097, 0x10f8, 0x00001010);
-	nv_mthd(priv, 0x9097, 0x0d80, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d84, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d88, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d8c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0d90, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0da0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1508, 0x80000000);
-	nv_mthd(priv, 0x9097, 0x150c, 0x40000000);
-	nv_mthd(priv, 0x9097, 0x1668, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0318, 0x00000008);
-	nv_mthd(priv, 0x9097, 0x031c, 0x00000008);
-	nv_mthd(priv, 0x9097, 0x0d9c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x07dc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x074c, 0x00000055);
-	nv_mthd(priv, 0x9097, 0x1420, 0x00000003);
-	nv_mthd(priv, 0x9097, 0x17bc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x17c0, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x17c4, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1008, 0x00000008);
-	nv_mthd(priv, 0x9097, 0x100c, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x1010, 0x0000012c);
-	nv_mthd(priv, 0x9097, 0x0d60, 0x00000040);
-	nv_mthd(priv, 0x9097, 0x075c, 0x00000003);
-	nv_mthd(priv, 0x9097, 0x1018, 0x00000020);
-	nv_mthd(priv, 0x9097, 0x101c, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1020, 0x00000020);
-	nv_mthd(priv, 0x9097, 0x1024, 0x00000001);
-	nv_mthd(priv, 0x9097, 0x1444, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x1448, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x144c, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0360, 0x20164010);
-	nv_mthd(priv, 0x9097, 0x0364, 0x00000020);
-	nv_mthd(priv, 0x9097, 0x0368, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0de4, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0204, 0x00000006);
-	nv_mthd(priv, 0x9097, 0x0208, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x02cc, 0x003fffff);
-	nv_mthd(priv, 0x9097, 0x02d0, 0x00000c48);
-	nv_mthd(priv, 0x9097, 0x1220, 0x00000005);
-	nv_mthd(priv, 0x9097, 0x0fdc, 0x00000000);
-	nv_mthd(priv, 0x9097, 0x0f98, 0x00300008);
-	nv_mthd(priv, 0x9097, 0x1284, 0x04000080);
-	nv_mthd(priv, 0x9097, 0x1450, 0x00300008);
-	nv_mthd(priv, 0x9097, 0x1454, 0x04000080);
-	nv_mthd(priv, 0x9097, 0x0214, 0x00000000);
-	/* in trace, right after 0x90c0, not here */
-	nv_mthd(priv, 0x9097, 0x3410, 0x80002006);
 }
 
-static void
-nvc0_grctx_generate_9197(struct nvc0_graph_priv *priv)
+void
+nvc0_grctx_generate_unkn(struct nvc0_graph_priv *priv)
 {
-	u32 fermi = nvc0_graph_class(priv);
-	u32 mthd;
-
-	if (fermi == 0x9197) {
-		for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4)
-			nv_mthd(priv, 0x9197, mthd, 0x00000000);
-	}
-	nv_mthd(priv, 0x9197, 0x02e4, 0x0000b001);
 }
 
-static void
-nvc0_grctx_generate_9297(struct nvc0_graph_priv *priv)
+void
+nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *priv)
 {
-	u32 fermi = nvc0_graph_class(priv);
-	u32 mthd;
+	int gpc, tpc, id;
 
-	if (fermi == 0x9297) {
-		for (mthd = 0x3400; mthd <= 0x35fc; mthd += 4)
-			nv_mthd(priv, 0x9297, mthd, 0x00000000);
+	for (tpc = 0, id = 0; tpc < 4; tpc++) {
+		for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+			if (tpc < priv->tpc_nr[gpc]) {
+				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x698), id);
+				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x4e8), id);
+				nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id);
+				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x088), id);
+				id++;
+			}
+
+			nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]);
+			nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]);
+		}
 	}
-	nv_mthd(priv, 0x9297, 0x036c, 0x00000000);
-	nv_mthd(priv, 0x9297, 0x0370, 0x00000000);
-	nv_mthd(priv, 0x9297, 0x07a4, 0x00000000);
-	nv_mthd(priv, 0x9297, 0x07a8, 0x00000000);
-	nv_mthd(priv, 0x9297, 0x0374, 0x00000000);
-	nv_mthd(priv, 0x9297, 0x0378, 0x00000020);
 }
 
-static void
-nvc0_grctx_generate_902d(struct nvc0_graph_priv *priv)
+void
+nvc0_grctx_generate_r406028(struct nvc0_graph_priv *priv)
 {
-	nv_mthd(priv, 0x902d, 0x0200, 0x000000cf);
-	nv_mthd(priv, 0x902d, 0x0204, 0x00000001);
-	nv_mthd(priv, 0x902d, 0x0208, 0x00000020);
-	nv_mthd(priv, 0x902d, 0x020c, 0x00000001);
-	nv_mthd(priv, 0x902d, 0x0210, 0x00000000);
-	nv_mthd(priv, 0x902d, 0x0214, 0x00000080);
-	nv_mthd(priv, 0x902d, 0x0218, 0x00000100);
-	nv_mthd(priv, 0x902d, 0x021c, 0x00000100);
-	nv_mthd(priv, 0x902d, 0x0220, 0x00000000);
-	nv_mthd(priv, 0x902d, 0x0224, 0x00000000);
-	nv_mthd(priv, 0x902d, 0x0230, 0x000000cf);
-	nv_mthd(priv, 0x902d, 0x0234, 0x00000001);
-	nv_mthd(priv, 0x902d, 0x0238, 0x00000020);
-	nv_mthd(priv, 0x902d, 0x023c, 0x00000001);
-	nv_mthd(priv, 0x902d, 0x0244, 0x00000080);
-	nv_mthd(priv, 0x902d, 0x0248, 0x00000100);
-	nv_mthd(priv, 0x902d, 0x024c, 0x00000100);
+	u32 tmp[GPC_MAX / 8] = {}, i = 0;
+	for (i = 0; i < priv->gpc_nr; i++)
+		tmp[i / 8] |= priv->tpc_nr[i] << ((i % 8) * 4);
+	for (i = 0; i < 4; i++) {
+		nv_wr32(priv, 0x406028 + (i * 4), tmp[i]);
+		nv_wr32(priv, 0x405870 + (i * 4), tmp[i]);
+	}
 }
 
-static void
-nvc0_grctx_generate_9039(struct nvc0_graph_priv *priv)
+void
+nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *priv)
 {
-	nv_mthd(priv, 0x9039, 0x030c, 0x00000000);
-	nv_mthd(priv, 0x9039, 0x0310, 0x00000000);
-	nv_mthd(priv, 0x9039, 0x0314, 0x00000000);
-	nv_mthd(priv, 0x9039, 0x0320, 0x00000000);
-	nv_mthd(priv, 0x9039, 0x0238, 0x00000000);
-	nv_mthd(priv, 0x9039, 0x023c, 0x00000000);
-	nv_mthd(priv, 0x9039, 0x0318, 0x00000000);
-	nv_mthd(priv, 0x9039, 0x031c, 0x00000000);
-}
+	u8  tpcnr[GPC_MAX], data[TPC_MAX];
+	int gpc, tpc, i;
 
-static void
-nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv)
-{
-	int i;
+	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+	memset(data, 0x1f, sizeof(data));
 
-	for (i = 0; nv_device(priv)->chipset >= 0xd0 && i < 4; i++) {
-		nv_mthd(priv, 0x90c0, 0x2700 + (i * 0x40), 0x00000000);
-		nv_mthd(priv, 0x90c0, 0x2720 + (i * 0x40), 0x00000000);
-		nv_mthd(priv, 0x90c0, 0x2704 + (i * 0x40), 0x00000000);
-		nv_mthd(priv, 0x90c0, 0x2724 + (i * 0x40), 0x00000000);
-		nv_mthd(priv, 0x90c0, 0x2708 + (i * 0x40), 0x00000000);
-		nv_mthd(priv, 0x90c0, 0x2728 + (i * 0x40), 0x00000000);
-	}
-	nv_mthd(priv, 0x90c0, 0x270c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x272c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x274c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x276c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x278c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x27ac, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x27cc, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x27ec, 0x00000000);
-	for (i = 0; nv_device(priv)->chipset >= 0xd0 && i < 4; i++) {
-		nv_mthd(priv, 0x90c0, 0x2710 + (i * 0x40), 0x00014000);
-		nv_mthd(priv, 0x90c0, 0x2730 + (i * 0x40), 0x00014000);
-		nv_mthd(priv, 0x90c0, 0x2714 + (i * 0x40), 0x00000040);
-		nv_mthd(priv, 0x90c0, 0x2734 + (i * 0x40), 0x00000040);
+	gpc = -1;
+	for (tpc = 0; tpc < priv->tpc_total; tpc++) {
+		do {
+			gpc = (gpc + 1) % priv->gpc_nr;
+		} while (!tpcnr[gpc]);
+		tpcnr[gpc]--;
+		data[tpc] = gpc;
 	}
-	nv_mthd(priv, 0x90c0, 0x030c, 0x00000001);
-	nv_mthd(priv, 0x90c0, 0x1944, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x0758, 0x00000100);
-	nv_mthd(priv, 0x90c0, 0x02c4, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x0790, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x0794, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x0798, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x079c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x07a0, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x077c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x0204, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x0208, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x020c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x0214, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x024c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x0d94, 0x00000001);
-	nv_mthd(priv, 0x90c0, 0x1608, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x160c, 0x00000000);
-	nv_mthd(priv, 0x90c0, 0x1664, 0x00000000);
-}
 
-static void
-nvc0_grctx_generate_dispatch(struct nvc0_graph_priv *priv)
-{
-	int i;
-
-	nv_wr32(priv, 0x404004, 0x00000000);
-	nv_wr32(priv, 0x404008, 0x00000000);
-	nv_wr32(priv, 0x40400c, 0x00000000);
-	nv_wr32(priv, 0x404010, 0x00000000);
-	nv_wr32(priv, 0x404014, 0x00000000);
-	nv_wr32(priv, 0x404018, 0x00000000);
-	nv_wr32(priv, 0x40401c, 0x00000000);
-	nv_wr32(priv, 0x404020, 0x00000000);
-	nv_wr32(priv, 0x404024, 0x00000000);
-	nv_wr32(priv, 0x404028, 0x00000000);
-	nv_wr32(priv, 0x40402c, 0x00000000);
-	nv_wr32(priv, 0x404044, 0x00000000);
-	nv_wr32(priv, 0x404094, 0x00000000);
-	nv_wr32(priv, 0x404098, 0x00000000);
-	nv_wr32(priv, 0x40409c, 0x00000000);
-	nv_wr32(priv, 0x4040a0, 0x00000000);
-	nv_wr32(priv, 0x4040a4, 0x00000000);
-	nv_wr32(priv, 0x4040a8, 0x00000000);
-	nv_wr32(priv, 0x4040ac, 0x00000000);
-	nv_wr32(priv, 0x4040b0, 0x00000000);
-	nv_wr32(priv, 0x4040b4, 0x00000000);
-	nv_wr32(priv, 0x4040b8, 0x00000000);
-	nv_wr32(priv, 0x4040bc, 0x00000000);
-	nv_wr32(priv, 0x4040c0, 0x00000000);
-	nv_wr32(priv, 0x4040c4, 0x00000000);
-	nv_wr32(priv, 0x4040c8, 0xf0000087);
-	nv_wr32(priv, 0x4040d4, 0x00000000);
-	nv_wr32(priv, 0x4040d8, 0x00000000);
-	nv_wr32(priv, 0x4040dc, 0x00000000);
-	nv_wr32(priv, 0x4040e0, 0x00000000);
-	nv_wr32(priv, 0x4040e4, 0x00000000);
-	nv_wr32(priv, 0x4040e8, 0x00001000);
-	nv_wr32(priv, 0x4040f8, 0x00000000);
-	nv_wr32(priv, 0x404130, 0x00000000);
-	nv_wr32(priv, 0x404134, 0x00000000);
-	nv_wr32(priv, 0x404138, 0x20000040);
-	nv_wr32(priv, 0x404150, 0x0000002e);
-	nv_wr32(priv, 0x404154, 0x00000400);
-	nv_wr32(priv, 0x404158, 0x00000200);
-	nv_wr32(priv, 0x404164, 0x00000055);
-	nv_wr32(priv, 0x404168, 0x00000000);
-	nv_wr32(priv, 0x404174, 0x00000000);
-	nv_wr32(priv, 0x404178, 0x00000000);
-	nv_wr32(priv, 0x40417c, 0x00000000);
-	for (i = 0; i < 8; i++)
-		nv_wr32(priv, 0x404200 + (i * 4), 0x00000000); /* subc */
+	for (i = 0; i < 4; i++)
+		nv_wr32(priv, 0x4060a8 + (i * 4), ((u32 *)data)[i]);
 }
 
-static void
-nvc0_grctx_generate_macro(struct nvc0_graph_priv *priv)
+void
+nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *priv)
 {
-	nv_wr32(priv, 0x404404, 0x00000000);
-	nv_wr32(priv, 0x404408, 0x00000000);
-	nv_wr32(priv, 0x40440c, 0x00000000);
-	nv_wr32(priv, 0x404410, 0x00000000);
-	nv_wr32(priv, 0x404414, 0x00000000);
-	nv_wr32(priv, 0x404418, 0x00000000);
-	nv_wr32(priv, 0x40441c, 0x00000000);
-	nv_wr32(priv, 0x404420, 0x00000000);
-	nv_wr32(priv, 0x404424, 0x00000000);
-	nv_wr32(priv, 0x404428, 0x00000000);
-	nv_wr32(priv, 0x40442c, 0x00000000);
-	nv_wr32(priv, 0x404430, 0x00000000);
-	nv_wr32(priv, 0x404434, 0x00000000);
-	nv_wr32(priv, 0x404438, 0x00000000);
-	nv_wr32(priv, 0x404460, 0x00000000);
-	nv_wr32(priv, 0x404464, 0x00000000);
-	nv_wr32(priv, 0x404468, 0x00ffffff);
-	nv_wr32(priv, 0x40446c, 0x00000000);
-	nv_wr32(priv, 0x404480, 0x00000001);
-	nv_wr32(priv, 0x404498, 0x00000001);
-}
+	u32 data[6] = {}, data2[2] = {};
+	u8  tpcnr[GPC_MAX];
+	u8  shift, ntpcv;
+	int gpc, tpc, i;
 
-static void
-nvc0_grctx_generate_m2mf(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x404604, 0x00000015);
-	nv_wr32(priv, 0x404608, 0x00000000);
-	nv_wr32(priv, 0x40460c, 0x00002e00);
-	nv_wr32(priv, 0x404610, 0x00000100);
-	nv_wr32(priv, 0x404618, 0x00000000);
-	nv_wr32(priv, 0x40461c, 0x00000000);
-	nv_wr32(priv, 0x404620, 0x00000000);
-	nv_wr32(priv, 0x404624, 0x00000000);
-	nv_wr32(priv, 0x404628, 0x00000000);
-	nv_wr32(priv, 0x40462c, 0x00000000);
-	nv_wr32(priv, 0x404630, 0x00000000);
-	nv_wr32(priv, 0x404634, 0x00000000);
-	nv_wr32(priv, 0x404638, 0x00000004);
-	nv_wr32(priv, 0x40463c, 0x00000000);
-	nv_wr32(priv, 0x404640, 0x00000000);
-	nv_wr32(priv, 0x404644, 0x00000000);
-	nv_wr32(priv, 0x404648, 0x00000000);
-	nv_wr32(priv, 0x40464c, 0x00000000);
-	nv_wr32(priv, 0x404650, 0x00000000);
-	nv_wr32(priv, 0x404654, 0x00000000);
-	nv_wr32(priv, 0x404658, 0x00000000);
-	nv_wr32(priv, 0x40465c, 0x007f0100);
-	nv_wr32(priv, 0x404660, 0x00000000);
-	nv_wr32(priv, 0x404664, 0x00000000);
-	nv_wr32(priv, 0x404668, 0x00000000);
-	nv_wr32(priv, 0x40466c, 0x00000000);
-	nv_wr32(priv, 0x404670, 0x00000000);
-	nv_wr32(priv, 0x404674, 0x00000000);
-	nv_wr32(priv, 0x404678, 0x00000000);
-	nv_wr32(priv, 0x40467c, 0x00000002);
-	nv_wr32(priv, 0x404680, 0x00000000);
-	nv_wr32(priv, 0x404684, 0x00000000);
-	nv_wr32(priv, 0x404688, 0x00000000);
-	nv_wr32(priv, 0x40468c, 0x00000000);
-	nv_wr32(priv, 0x404690, 0x00000000);
-	nv_wr32(priv, 0x404694, 0x00000000);
-	nv_wr32(priv, 0x404698, 0x00000000);
-	nv_wr32(priv, 0x40469c, 0x00000000);
-	nv_wr32(priv, 0x4046a0, 0x007f0080);
-	nv_wr32(priv, 0x4046a4, 0x00000000);
-	nv_wr32(priv, 0x4046a8, 0x00000000);
-	nv_wr32(priv, 0x4046ac, 0x00000000);
-	nv_wr32(priv, 0x4046b0, 0x00000000);
-	nv_wr32(priv, 0x4046b4, 0x00000000);
-	nv_wr32(priv, 0x4046b8, 0x00000000);
-	nv_wr32(priv, 0x4046bc, 0x00000000);
-	nv_wr32(priv, 0x4046c0, 0x00000000);
-	nv_wr32(priv, 0x4046c4, 0x00000000);
-	nv_wr32(priv, 0x4046c8, 0x00000000);
-	nv_wr32(priv, 0x4046cc, 0x00000000);
-	nv_wr32(priv, 0x4046d0, 0x00000000);
-	nv_wr32(priv, 0x4046d4, 0x00000000);
-	nv_wr32(priv, 0x4046d8, 0x00000000);
-	nv_wr32(priv, 0x4046dc, 0x00000000);
-	nv_wr32(priv, 0x4046e0, 0x00000000);
-	nv_wr32(priv, 0x4046e4, 0x00000000);
-	nv_wr32(priv, 0x4046e8, 0x00000000);
-	nv_wr32(priv, 0x4046f0, 0x00000000);
-	nv_wr32(priv, 0x4046f4, 0x00000000);
-}
+	/* calculate first set of magics */
+	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
 
-static void
-nvc0_grctx_generate_unk47xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x404700, 0x00000000);
-	nv_wr32(priv, 0x404704, 0x00000000);
-	nv_wr32(priv, 0x404708, 0x00000000);
-	nv_wr32(priv, 0x40470c, 0x00000000);
-	nv_wr32(priv, 0x404710, 0x00000000);
-	nv_wr32(priv, 0x404714, 0x00000000);
-	nv_wr32(priv, 0x404718, 0x00000000);
-	nv_wr32(priv, 0x40471c, 0x00000000);
-	nv_wr32(priv, 0x404720, 0x00000000);
-	nv_wr32(priv, 0x404724, 0x00000000);
-	nv_wr32(priv, 0x404728, 0x00000000);
-	nv_wr32(priv, 0x40472c, 0x00000000);
-	nv_wr32(priv, 0x404730, 0x00000000);
-	nv_wr32(priv, 0x404734, 0x00000100);
-	nv_wr32(priv, 0x404738, 0x00000000);
-	nv_wr32(priv, 0x40473c, 0x00000000);
-	nv_wr32(priv, 0x404740, 0x00000000);
-	nv_wr32(priv, 0x404744, 0x00000000);
-	nv_wr32(priv, 0x404748, 0x00000000);
-	nv_wr32(priv, 0x40474c, 0x00000000);
-	nv_wr32(priv, 0x404750, 0x00000000);
-	nv_wr32(priv, 0x404754, 0x00000000);
-}
+	gpc = -1;
+	for (tpc = 0; tpc < priv->tpc_total; tpc++) {
+		do {
+			gpc = (gpc + 1) % priv->gpc_nr;
+		} while (!tpcnr[gpc]);
+		tpcnr[gpc]--;
 
-static void
-nvc0_grctx_generate_shaders(struct nvc0_graph_priv *priv)
-{
+		data[tpc / 6] |= gpc << ((tpc % 6) * 5);
+	}
 
-	if (nv_device(priv)->chipset >= 0xd0) {
-		nv_wr32(priv, 0x405800, 0x0f8000bf);
-		nv_wr32(priv, 0x405830, 0x02180218);
-		nv_wr32(priv, 0x405834, 0x08000000);
-	} else
-	if (nv_device(priv)->chipset == 0xc1) {
-		nv_wr32(priv, 0x405800, 0x0f8000bf);
-		nv_wr32(priv, 0x405830, 0x02180218);
-		nv_wr32(priv, 0x405834, 0x00000000);
-	} else {
-		nv_wr32(priv, 0x405800, 0x078000bf);
-		nv_wr32(priv, 0x405830, 0x02180000);
-		nv_wr32(priv, 0x405834, 0x00000000);
+	for (; tpc < 32; tpc++)
+		data[tpc / 6] |= 7 << ((tpc % 6) * 5);
+
+	/* and the second... */
+	shift = 0;
+	ntpcv = priv->tpc_total;
+	while (!(ntpcv & (1 << 4))) {
+		ntpcv <<= 1;
+		shift++;
 	}
-	nv_wr32(priv, 0x405838, 0x00000000);
-	nv_wr32(priv, 0x405854, 0x00000000);
-	nv_wr32(priv, 0x405870, 0x00000001);
-	nv_wr32(priv, 0x405874, 0x00000001);
-	nv_wr32(priv, 0x405878, 0x00000001);
-	nv_wr32(priv, 0x40587c, 0x00000001);
-	nv_wr32(priv, 0x405a00, 0x00000000);
-	nv_wr32(priv, 0x405a04, 0x00000000);
-	nv_wr32(priv, 0x405a18, 0x00000000);
-}
 
-static void
-nvc0_grctx_generate_unk60xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x406020, 0x000103c1);
-	nv_wr32(priv, 0x406028, 0x00000001);
-	nv_wr32(priv, 0x40602c, 0x00000001);
-	nv_wr32(priv, 0x406030, 0x00000001);
-	nv_wr32(priv, 0x406034, 0x00000001);
-}
+	data2[0]  = (ntpcv << 16);
+	data2[0] |= (shift << 21);
+	data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
+	for (i = 1; i < 7; i++)
+		data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
 
-static void
-nvc0_grctx_generate_unk64xx(struct nvc0_graph_priv *priv)
-{
+	/* GPC_BROADCAST */
+	nv_wr32(priv, 0x418bb8, (priv->tpc_total << 8) |
+				 priv->magic_not_rop_nr);
+	for (i = 0; i < 6; i++)
+		nv_wr32(priv, 0x418b08 + (i * 4), data[i]);
 
-	nv_wr32(priv, 0x4064a8, 0x00000000);
-	nv_wr32(priv, 0x4064ac, 0x00003fff);
-	nv_wr32(priv, 0x4064b4, 0x00000000);
-	nv_wr32(priv, 0x4064b8, 0x00000000);
-	if (nv_device(priv)->chipset >= 0xd0)
-		nv_wr32(priv, 0x4064bc, 0x00000000);
-	if (nv_device(priv)->chipset == 0xc1 ||
-	    nv_device(priv)->chipset >= 0xd0) {
-		nv_wr32(priv, 0x4064c0, 0x80140078);
-		nv_wr32(priv, 0x4064c4, 0x0086ffff);
-	}
-}
+	/* GPC_BROADCAST.TP_BROADCAST */
+	nv_wr32(priv, 0x419bd0, (priv->tpc_total << 8) |
+				 priv->magic_not_rop_nr | data2[0]);
+	nv_wr32(priv, 0x419be4, data2[1]);
+	for (i = 0; i < 6; i++)
+		nv_wr32(priv, 0x419b00 + (i * 4), data[i]);
 
-static void
-nvc0_grctx_generate_tpbus(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x407804, 0x00000023);
-	nv_wr32(priv, 0x40780c, 0x0a418820);
-	nv_wr32(priv, 0x407810, 0x062080e6);
-	nv_wr32(priv, 0x407814, 0x020398a4);
-	nv_wr32(priv, 0x407818, 0x0e629062);
-	nv_wr32(priv, 0x40781c, 0x0a418820);
-	nv_wr32(priv, 0x407820, 0x000000e6);
-	nv_wr32(priv, 0x4078bc, 0x00000103);
+	/* UNK78xx */
+	nv_wr32(priv, 0x4078bc, (priv->tpc_total << 8) |
+				 priv->magic_not_rop_nr);
+	for (i = 0; i < 6; i++)
+		nv_wr32(priv, 0x40780c + (i * 4), data[i]);
 }
 
-static void
-nvc0_grctx_generate_ccache(struct nvc0_graph_priv *priv)
+void
+nvc0_grctx_generate_r406800(struct nvc0_graph_priv *priv)
 {
-	nv_wr32(priv, 0x408000, 0x00000000);
-	nv_wr32(priv, 0x408004, 0x00000000);
-	nv_wr32(priv, 0x408008, 0x00000018);
-	nv_wr32(priv, 0x40800c, 0x00000000);
-	nv_wr32(priv, 0x408010, 0x00000000);
-	nv_wr32(priv, 0x408014, 0x00000069);
-	nv_wr32(priv, 0x408018, 0xe100e100);
-	nv_wr32(priv, 0x408064, 0x00000000);
-}
+	u64 tpc_mask = 0, tpc_set = 0;
+	u8  tpcnr[GPC_MAX];
+	int gpc, tpc;
+	int i, a, b;
 
-static void
-nvc0_grctx_generate_rop(struct nvc0_graph_priv *priv)
-{
-	int chipset = nv_device(priv)->chipset;
+	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++)
+		tpc_mask |= ((1ULL << priv->tpc_nr[gpc]) - 1) << (gpc * 8);
 
-	/* ROPC_BROADCAST */
-	nv_wr32(priv, 0x408800, 0x02802a3c);
-	nv_wr32(priv, 0x408804, 0x00000040);
-	if (chipset >= 0xd0) {
-		nv_wr32(priv, 0x408808, 0x1043e005);
-		nv_wr32(priv, 0x408900, 0x3080b801);
-		nv_wr32(priv, 0x408904, 0x1043e005);
-		nv_wr32(priv, 0x408908, 0x00c8102f);
-	} else
-	if (chipset == 0xc1) {
-		nv_wr32(priv, 0x408808, 0x1003e005);
-		nv_wr32(priv, 0x408900, 0x3080b801);
-		nv_wr32(priv, 0x408904, 0x62000001);
-		nv_wr32(priv, 0x408908, 0x00c80929);
-	} else {
-		nv_wr32(priv, 0x408808, 0x0003e00d);
-		nv_wr32(priv, 0x408900, 0x3080b801);
-		nv_wr32(priv, 0x408904, 0x02000001);
-		nv_wr32(priv, 0x408908, 0x00c80929);
+	for (i = 0, gpc = -1, b = -1; i < 32; i++) {
+		a = (i * (priv->tpc_total - 1)) / 32;
+		if (a != b) {
+			b = a;
+			do {
+				gpc = (gpc + 1) % priv->gpc_nr;
+			} while (!tpcnr[gpc]);
+			tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
+
+			tpc_set |= 1 << ((gpc * 8) + tpc);
+		}
+
+		nv_wr32(priv, 0x406800 + (i * 0x20), lower_32_bits(tpc_set));
+		nv_wr32(priv, 0x406c00 + (i * 0x20), lower_32_bits(tpc_set ^ tpc_mask));
+		if (priv->gpc_nr > 4) {
+			nv_wr32(priv, 0x406804 + (i * 0x20), upper_32_bits(tpc_set));
+			nv_wr32(priv, 0x406c04 + (i * 0x20), upper_32_bits(tpc_set ^ tpc_mask));
+		}
 	}
-	nv_wr32(priv, 0x40890c, 0x00000000);
-	nv_wr32(priv, 0x408980, 0x0000011d);
 }
 
-static void
-nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
+void
+nvc0_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 {
-	int chipset = nv_device(priv)->chipset;
+	struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
 	int i;
 
-	/* GPC_BROADCAST */
-	nv_wr32(priv, 0x418380, 0x00000016);
-	nv_wr32(priv, 0x418400, 0x38004e00);
-	nv_wr32(priv, 0x418404, 0x71e0ffff);
-	nv_wr32(priv, 0x418408, 0x00000000);
-	nv_wr32(priv, 0x41840c, 0x00001008);
-	nv_wr32(priv, 0x418410, 0x0fff0fff);
-	nv_wr32(priv, 0x418414, chipset < 0xd0 ? 0x00200fff : 0x02200fff);
-	nv_wr32(priv, 0x418450, 0x00000000);
-	nv_wr32(priv, 0x418454, 0x00000000);
-	nv_wr32(priv, 0x418458, 0x00000000);
-	nv_wr32(priv, 0x41845c, 0x00000000);
-	nv_wr32(priv, 0x418460, 0x00000000);
-	nv_wr32(priv, 0x418464, 0x00000000);
-	nv_wr32(priv, 0x418468, 0x00000001);
-	nv_wr32(priv, 0x41846c, 0x00000000);
-	nv_wr32(priv, 0x418470, 0x00000000);
-	nv_wr32(priv, 0x418600, 0x0000001f);
-	nv_wr32(priv, 0x418684, 0x0000000f);
-	nv_wr32(priv, 0x418700, 0x00000002);
-	nv_wr32(priv, 0x418704, 0x00000080);
-	nv_wr32(priv, 0x418708, 0x00000000);
-	nv_wr32(priv, 0x41870c, chipset < 0xd0 ? 0x07c80000 : 0x00000000);
-	nv_wr32(priv, 0x418710, 0x00000000);
-	nv_wr32(priv, 0x418800, chipset < 0xd0 ? 0x0006860a : 0x7006860a);
-	nv_wr32(priv, 0x418808, 0x00000000);
-	nv_wr32(priv, 0x41880c, 0x00000000);
-	nv_wr32(priv, 0x418810, 0x00000000);
-	nv_wr32(priv, 0x418828, 0x00008442);
-	if (chipset == 0xc1 || chipset >= 0xd0)
-		nv_wr32(priv, 0x418830, 0x10000001);
-	else
-		nv_wr32(priv, 0x418830, 0x00000001);
-	nv_wr32(priv, 0x4188d8, 0x00000008);
-	nv_wr32(priv, 0x4188e0, 0x01000000);
-	nv_wr32(priv, 0x4188e8, 0x00000000);
-	nv_wr32(priv, 0x4188ec, 0x00000000);
-	nv_wr32(priv, 0x4188f0, 0x00000000);
-	nv_wr32(priv, 0x4188f4, 0x00000000);
-	nv_wr32(priv, 0x4188f8, 0x00000000);
-	if (chipset >= 0xd0)
-		nv_wr32(priv, 0x4188fc, 0x20100008);
-	else if (chipset == 0xc1)
-		nv_wr32(priv, 0x4188fc, 0x00100018);
-	else
-		nv_wr32(priv, 0x4188fc, 0x00100000);
-	nv_wr32(priv, 0x41891c, 0x00ff00ff);
-	nv_wr32(priv, 0x418924, 0x00000000);
-	nv_wr32(priv, 0x418928, 0x00ffff00);
-	nv_wr32(priv, 0x41892c, 0x0000ff00);
-	for (i = 0; i < 8; i++) {
-		nv_wr32(priv, 0x418a00 + (i * 0x20), 0x00000000);
-		nv_wr32(priv, 0x418a04 + (i * 0x20), 0x00000000);
-		nv_wr32(priv, 0x418a08 + (i * 0x20), 0x00000000);
-		nv_wr32(priv, 0x418a0c + (i * 0x20), 0x00010000);
-		nv_wr32(priv, 0x418a10 + (i * 0x20), 0x00000000);
-		nv_wr32(priv, 0x418a14 + (i * 0x20), 0x00000000);
-		nv_wr32(priv, 0x418a18 + (i * 0x20), 0x00000000);
-	}
-	nv_wr32(priv, 0x418b00, chipset < 0xd0 ? 0x00000000 : 0x00000006);
-	nv_wr32(priv, 0x418b08, 0x0a418820);
-	nv_wr32(priv, 0x418b0c, 0x062080e6);
-	nv_wr32(priv, 0x418b10, 0x020398a4);
-	nv_wr32(priv, 0x418b14, 0x0e629062);
-	nv_wr32(priv, 0x418b18, 0x0a418820);
-	nv_wr32(priv, 0x418b1c, 0x000000e6);
-	nv_wr32(priv, 0x418bb8, 0x00000103);
-	nv_wr32(priv, 0x418c08, 0x00000001);
-	nv_wr32(priv, 0x418c10, 0x00000000);
-	nv_wr32(priv, 0x418c14, 0x00000000);
-	nv_wr32(priv, 0x418c18, 0x00000000);
-	nv_wr32(priv, 0x418c1c, 0x00000000);
-	nv_wr32(priv, 0x418c20, 0x00000000);
-	nv_wr32(priv, 0x418c24, 0x00000000);
-	nv_wr32(priv, 0x418c28, 0x00000000);
-	nv_wr32(priv, 0x418c2c, 0x00000000);
-	if (chipset == 0xc1 || chipset >= 0xd0)
-		nv_wr32(priv, 0x418c6c, 0x00000001);
-	nv_wr32(priv, 0x418c80, 0x20200004);
-	nv_wr32(priv, 0x418c8c, 0x00000001);
-	nv_wr32(priv, 0x419000, 0x00000780);
-	nv_wr32(priv, 0x419004, 0x00000000);
-	nv_wr32(priv, 0x419008, 0x00000000);
-	nv_wr32(priv, 0x419014, 0x00000004);
-}
+	nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
 
-static void
-nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
-{
-	int chipset = nv_device(priv)->chipset;
+	for (i = 0; oclass->hub[i]; i++)
+		nvc0_graph_mmio(priv, oclass->hub[i]);
+	for (i = 0; oclass->gpc[i]; i++)
+		nvc0_graph_mmio(priv, oclass->gpc[i]);
 
-	/* GPC_BROADCAST.TP_BROADCAST */
-	nv_wr32(priv, 0x419818, 0x00000000);
-	nv_wr32(priv, 0x41983c, 0x00038bc7);
-	nv_wr32(priv, 0x419848, 0x00000000);
-	if (chipset == 0xc1 || chipset >= 0xd0)
-		nv_wr32(priv, 0x419864, 0x00000129);
-	else
-		nv_wr32(priv, 0x419864, 0x0000012a);
-	nv_wr32(priv, 0x419888, 0x00000000);
-	nv_wr32(priv, 0x419a00, 0x000001f0);
-	nv_wr32(priv, 0x419a04, 0x00000001);
-	nv_wr32(priv, 0x419a08, 0x00000023);
-	nv_wr32(priv, 0x419a0c, 0x00020000);
-	nv_wr32(priv, 0x419a10, 0x00000000);
-	nv_wr32(priv, 0x419a14, 0x00000200);
-	nv_wr32(priv, 0x419a1c, 0x00000000);
-	nv_wr32(priv, 0x419a20, 0x00000800);
-	if (chipset >= 0xd0)
-		nv_wr32(priv, 0x00419ac4, 0x0017f440);
-	else if (chipset != 0xc0 && chipset != 0xc8)
-		nv_wr32(priv, 0x00419ac4, 0x0007f440);
-	nv_wr32(priv, 0x419b00, 0x0a418820);
-	nv_wr32(priv, 0x419b04, 0x062080e6);
-	nv_wr32(priv, 0x419b08, 0x020398a4);
-	nv_wr32(priv, 0x419b0c, 0x0e629062);
-	nv_wr32(priv, 0x419b10, 0x0a418820);
-	nv_wr32(priv, 0x419b14, 0x000000e6);
-	nv_wr32(priv, 0x419bd0, 0x00900103);
-	if (chipset == 0xc1 || chipset >= 0xd0)
-		nv_wr32(priv, 0x419be0, 0x00400001);
-	else
-		nv_wr32(priv, 0x419be0, 0x00000001);
-	nv_wr32(priv, 0x419be4, 0x00000000);
-	nv_wr32(priv, 0x419c00, chipset < 0xd0 ? 0x00000002 : 0x0000000a);
-	nv_wr32(priv, 0x419c04, 0x00000006);
-	nv_wr32(priv, 0x419c08, 0x00000002);
-	nv_wr32(priv, 0x419c20, 0x00000000);
-	if (nv_device(priv)->chipset >= 0xd0) {
-		nv_wr32(priv, 0x419c24, 0x00084210);
-		nv_wr32(priv, 0x419c28, 0x3cf3cf3c);
-		nv_wr32(priv, 0x419cb0, 0x00020048);
-	} else
-	if (chipset == 0xce || chipset == 0xcf) {
-		nv_wr32(priv, 0x419cb0, 0x00020048);
-	} else {
-		nv_wr32(priv, 0x419cb0, 0x00060048);
-	}
-	nv_wr32(priv, 0x419ce8, 0x00000000);
-	nv_wr32(priv, 0x419cf4, 0x00000183);
-	if (chipset == 0xc1 || chipset >= 0xd0)
-		nv_wr32(priv, 0x419d20, 0x12180000);
-	else
-		nv_wr32(priv, 0x419d20, 0x02180000);
-	nv_wr32(priv, 0x419d24, 0x00001fff);
-	if (chipset == 0xc1 || chipset >= 0xd0)
-		nv_wr32(priv, 0x419d44, 0x02180218);
-	nv_wr32(priv, 0x419e04, 0x00000000);
-	nv_wr32(priv, 0x419e08, 0x00000000);
-	nv_wr32(priv, 0x419e0c, 0x00000000);
-	nv_wr32(priv, 0x419e10, 0x00000002);
-	nv_wr32(priv, 0x419e44, 0x001beff2);
-	nv_wr32(priv, 0x419e48, 0x00000000);
-	nv_wr32(priv, 0x419e4c, 0x0000000f);
-	nv_wr32(priv, 0x419e50, 0x00000000);
-	nv_wr32(priv, 0x419e54, 0x00000000);
-	nv_wr32(priv, 0x419e58, 0x00000000);
-	nv_wr32(priv, 0x419e5c, 0x00000000);
-	nv_wr32(priv, 0x419e60, 0x00000000);
-	nv_wr32(priv, 0x419e64, 0x00000000);
-	nv_wr32(priv, 0x419e68, 0x00000000);
-	nv_wr32(priv, 0x419e6c, 0x00000000);
-	nv_wr32(priv, 0x419e70, 0x00000000);
-	nv_wr32(priv, 0x419e74, 0x00000000);
-	nv_wr32(priv, 0x419e78, 0x00000000);
-	nv_wr32(priv, 0x419e7c, 0x00000000);
-	nv_wr32(priv, 0x419e80, 0x00000000);
-	nv_wr32(priv, 0x419e84, 0x00000000);
-	nv_wr32(priv, 0x419e88, 0x00000000);
-	nv_wr32(priv, 0x419e8c, 0x00000000);
-	nv_wr32(priv, 0x419e90, 0x00000000);
-	nv_wr32(priv, 0x419e98, 0x00000000);
-	if (chipset != 0xc0 && chipset != 0xc8)
-		nv_wr32(priv, 0x419ee0, 0x00011110);
-	nv_wr32(priv, 0x419f50, 0x00000000);
-	nv_wr32(priv, 0x419f54, 0x00000000);
-	if (chipset != 0xc0 && chipset != 0xc8)
-		nv_wr32(priv, 0x419f58, 0x00000000);
+	nv_wr32(priv, 0x404154, 0x00000000);
+
+	oclass->mods(priv, info);
+	oclass->unkn(priv);
+
+	nvc0_grctx_generate_tpcid(priv);
+	nvc0_grctx_generate_r406028(priv);
+	nvc0_grctx_generate_r4060a8(priv);
+	nvc0_grctx_generate_r418bb8(priv);
+	nvc0_grctx_generate_r406800(priv);
+
+	nvc0_graph_icmd(priv, oclass->icmd);
+	nv_wr32(priv, 0x404154, 0x00000400);
+	nvc0_graph_mthd(priv, oclass->mthd);
+	nv_mask(priv, 0x000260, 0x00000001, 0x00000001);
 }
 
 int
 nvc0_grctx_generate(struct nvc0_graph_priv *priv)
 {
+	struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
+	struct nouveau_bar *bar = nouveau_bar(priv);
+	struct nouveau_gpuobj *chan;
 	struct nvc0_grctx info;
-	int ret, i, gpc, tpc, id;
-	u32 fermi = nvc0_graph_class(priv);
-	u32 r000260, tmp;
+	int ret, i;
 
-	ret = nvc0_grctx_init(priv, &info);
-	if (ret)
+	/* allocate memory to for a "channel", which we'll use to generate
+	 * the default context values
+	 */
+	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x80000 + priv->size,
+				 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &chan);
+	if (ret) {
+		nv_error(priv, "failed to allocate channel memory, %d\n", ret);
 		return ret;
-
-	r000260 = nv_rd32(priv, 0x000260);
-	nv_wr32(priv, 0x000260, r000260 & ~1);
-	nv_wr32(priv, 0x400208, 0x00000000);
-
-	nvc0_grctx_generate_dispatch(priv);
-	nvc0_grctx_generate_macro(priv);
-	nvc0_grctx_generate_m2mf(priv);
-	nvc0_grctx_generate_unk47xx(priv);
-	nvc0_grctx_generate_shaders(priv);
-	nvc0_grctx_generate_unk60xx(priv);
-	nvc0_grctx_generate_unk64xx(priv);
-	nvc0_grctx_generate_tpbus(priv);
-	nvc0_grctx_generate_ccache(priv);
-	nvc0_grctx_generate_rop(priv);
-	nvc0_grctx_generate_gpc(priv);
-	nvc0_grctx_generate_tp(priv);
-
-	nv_wr32(priv, 0x404154, 0x00000000);
-
-	/* generate per-context mmio list data */
-	mmio_data(0x002000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
-	mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
-	mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
-	mmio_list(0x408004, 0x00000000,  8, 0);
-	mmio_list(0x408008, 0x80000018,  0, 0);
-	mmio_list(0x40800c, 0x00000000,  8, 1);
-	mmio_list(0x408010, 0x80000000,  0, 0);
-	mmio_list(0x418810, 0x80000000, 12, 2);
-	mmio_list(0x419848, 0x10000000, 12, 2);
-	mmio_list(0x419004, 0x00000000,  8, 1);
-	mmio_list(0x419008, 0x00000000,  0, 0);
-	mmio_list(0x418808, 0x00000000,  8, 0);
-	mmio_list(0x41880c, 0x80000018,  0, 0);
-	if (nv_device(priv)->chipset != 0xc1) {
-		tmp = 0x02180000;
-		mmio_list(0x405830, tmp, 0, 0);
-		for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-			for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
-				u32 reg = TPC_UNIT(gpc, tpc, 0x0520);
-				mmio_list(reg, tmp, 0, 0);
-				tmp += 0x0324;
-			}
-		}
-	} else {
-		tmp = 0x02180000;
-		mmio_list(0x405830, 0x00000218 | tmp, 0, 0);
-		mmio_list(0x4064c4, 0x0086ffff, 0, 0);
-		for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-			for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
-				u32 reg = TPC_UNIT(gpc, tpc, 0x0520);
-				mmio_list(reg, 0x10000000 | tmp, 0, 0);
-				tmp += 0x0324;
-			}
-			for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
-				u32 reg = TPC_UNIT(gpc, tpc, 0x0544);
-				mmio_list(reg, tmp, 0, 0);
-				tmp += 0x0324;
-			}
-		}
 	}
 
-	for (tpc = 0, id = 0; tpc < 4; tpc++) {
-		for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-			if (tpc < priv->tpc_nr[gpc]) {
-				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x698), id);
-				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x4e8), id);
-				nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id);
-				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x088), id);
-				id++;
-			}
-
-			nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]);
-			nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]);
-		}
-	}
-
-	tmp = 0;
-	for (i = 0; i < priv->gpc_nr; i++)
-		tmp |= priv->tpc_nr[i] << (i * 4);
-	nv_wr32(priv, 0x406028, tmp);
-	nv_wr32(priv, 0x405870, tmp);
-
-	nv_wr32(priv, 0x40602c, 0x00000000);
-	nv_wr32(priv, 0x405874, 0x00000000);
-	nv_wr32(priv, 0x406030, 0x00000000);
-	nv_wr32(priv, 0x405878, 0x00000000);
-	nv_wr32(priv, 0x406034, 0x00000000);
-	nv_wr32(priv, 0x40587c, 0x00000000);
-
-	if (1) {
-		u8 tpcnr[GPC_MAX], data[TPC_MAX];
-
-		memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
-		memset(data, 0x1f, sizeof(data));
+	/* PGD pointer */
+	nv_wo32(chan, 0x0200, lower_32_bits(chan->addr + 0x1000));
+	nv_wo32(chan, 0x0204, upper_32_bits(chan->addr + 0x1000));
+	nv_wo32(chan, 0x0208, 0xffffffff);
+	nv_wo32(chan, 0x020c, 0x000000ff);
 
-		gpc = -1;
-		for (tpc = 0; tpc < priv->tpc_total; tpc++) {
-			do {
-				gpc = (gpc + 1) % priv->gpc_nr;
-			} while (!tpcnr[gpc]);
-			tpcnr[gpc]--;
-			data[tpc] = gpc;
-		}
+	/* PGT[0] pointer */
+	nv_wo32(chan, 0x1000, 0x00000000);
+	nv_wo32(chan, 0x1004, 0x00000001 | (chan->addr + 0x2000) >> 8);
 
-		for (i = 0; i < 4; i++)
-			nv_wr32(priv, 0x4060a8 + (i * 4), ((u32 *)data)[i]);
+	/* identity-map the whole "channel" into its own vm */
+	for (i = 0; i < chan->size / 4096; i++) {
+		u64 addr = ((chan->addr + (i * 4096)) >> 8) | 1;
+		nv_wo32(chan, 0x2000 + (i * 8), lower_32_bits(addr));
+		nv_wo32(chan, 0x2004 + (i * 8), upper_32_bits(addr));
 	}
 
-	if (1) {
-		u32 data[6] = {}, data2[2] = {};
-		u8 tpcnr[GPC_MAX];
-		u8 shift, ntpcv;
-
-		/* calculate first set of magics */
-		memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
-
-		gpc = -1;
-		for (tpc = 0; tpc < priv->tpc_total; tpc++) {
-			do {
-				gpc = (gpc + 1) % priv->gpc_nr;
-			} while (!tpcnr[gpc]);
-			tpcnr[gpc]--;
-
-			data[tpc / 6] |= gpc << ((tpc % 6) * 5);
-		}
-
-		for (; tpc < 32; tpc++)
-			data[tpc / 6] |= 7 << ((tpc % 6) * 5);
+	/* context pointer (virt) */
+	nv_wo32(chan, 0x0210, 0x00080004);
+	nv_wo32(chan, 0x0214, 0x00000000);
 
-		/* and the second... */
-		shift = 0;
-		ntpcv = priv->tpc_total;
-		while (!(ntpcv & (1 << 4))) {
-			ntpcv <<= 1;
-			shift++;
-		}
+	bar->flush(bar);
 
-		data2[0]  = (ntpcv << 16);
-		data2[0] |= (shift << 21);
-		data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
-		for (i = 1; i < 7; i++)
-			data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
+	nv_wr32(priv, 0x100cb8, (chan->addr + 0x1000) >> 8);
+	nv_wr32(priv, 0x100cbc, 0x80000001);
+	nv_wait(priv, 0x100c80, 0x00008000, 0x00008000);
 
-		/* GPC_BROADCAST */
-		nv_wr32(priv, 0x418bb8, (priv->tpc_total << 8) |
-					priv->magic_not_rop_nr);
-		for (i = 0; i < 6; i++)
-			nv_wr32(priv, 0x418b08 + (i * 4), data[i]);
+	/* setup default state for mmio list construction */
+	info.priv = priv;
+	info.data = priv->mmio_data;
+	info.mmio = priv->mmio_list;
+	info.addr = 0x2000 + (i * 8);
+	info.buffer_nr = 0;
 
-		/* GPC_BROADCAST.TP_BROADCAST */
-		nv_wr32(priv, 0x419bd0, (priv->tpc_total << 8) |
-				       priv->magic_not_rop_nr |
-				       data2[0]);
-		nv_wr32(priv, 0x419be4, data2[1]);
-		for (i = 0; i < 6; i++)
-			nv_wr32(priv, 0x419b00 + (i * 4), data[i]);
+	/* make channel current */
+	if (priv->firmware) {
+		nv_wr32(priv, 0x409840, 0x00000030);
+		nv_wr32(priv, 0x409500, 0x80000000 | chan->addr >> 12);
+		nv_wr32(priv, 0x409504, 0x00000003);
+		if (!nv_wait(priv, 0x409800, 0x00000010, 0x00000010))
+			nv_error(priv, "load_ctx timeout\n");
 
-		/* UNK78xx */
-		nv_wr32(priv, 0x4078bc, (priv->tpc_total << 8) |
-					priv->magic_not_rop_nr);
-		for (i = 0; i < 6; i++)
-			nv_wr32(priv, 0x40780c + (i * 4), data[i]);
+		nv_wo32(chan, 0x8001c, 1);
+		nv_wo32(chan, 0x80020, 0);
+		nv_wo32(chan, 0x80028, 0);
+		nv_wo32(chan, 0x8002c, 0);
+		bar->flush(bar);
+	} else {
+		nv_wr32(priv, 0x409840, 0x80000000);
+		nv_wr32(priv, 0x409500, 0x80000000 | chan->addr >> 12);
+		nv_wr32(priv, 0x409504, 0x00000001);
+		if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000))
+			nv_error(priv, "HUB_SET_CHAN timeout\n");
 	}
 
-	if (1) {
-		u32 tpc_mask = 0, tpc_set = 0;
-		u8  tpcnr[GPC_MAX], a, b;
-
-		memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
-		for (gpc = 0; gpc < priv->gpc_nr; gpc++)
-			tpc_mask |= ((1 << priv->tpc_nr[gpc]) - 1) << (gpc * 8);
-
-		for (i = 0, gpc = -1, b = -1; i < 32; i++) {
-			a = (i * (priv->tpc_total - 1)) / 32;
-			if (a != b) {
-				b = a;
-				do {
-					gpc = (gpc + 1) % priv->gpc_nr;
-				} while (!tpcnr[gpc]);
-				tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
+	oclass->main(priv, &info);
 
-				tpc_set |= 1 << ((gpc * 8) + tpc);
-			}
+	/* trigger a context unload by unsetting the "next channel valid" bit
+	 * and faking a context switch interrupt
+	 */
+	nv_mask(priv, 0x409b04, 0x80000000, 0x00000000);
+	nv_wr32(priv, 0x409000, 0x00000100);
+	if (!nv_wait(priv, 0x409b00, 0x80000000, 0x00000000)) {
+		nv_error(priv, "grctx template channel unload timeout\n");
+		ret = -EBUSY;
+		goto done;
+	}
 
-			nv_wr32(priv, 0x406800 + (i * 0x20), tpc_set);
-			nv_wr32(priv, 0x406c00 + (i * 0x20), tpc_set ^ tpc_mask);
-		}
+	priv->data = kmalloc(priv->size, GFP_KERNEL);
+	if (priv->data) {
+		for (i = 0; i < priv->size; i += 4)
+			priv->data[i / 4] = nv_ro32(chan, 0x80000 + i);
+		ret = 0;
+	} else {
+		ret = -ENOMEM;
 	}
 
-	nv_wr32(priv, 0x400208, 0x80000000);
+done:
+	nouveau_gpuobj_ref(NULL, &chan);
+	return ret;
+}
 
-	nv_icmd(priv, 0x00001000, 0x00000004);
-	nv_icmd(priv, 0x000000a9, 0x0000ffff);
-	nv_icmd(priv, 0x00000038, 0x0fac6881);
-	nv_icmd(priv, 0x0000003d, 0x00000001);
-	nv_icmd(priv, 0x000000e8, 0x00000400);
-	nv_icmd(priv, 0x000000e9, 0x00000400);
-	nv_icmd(priv, 0x000000ea, 0x00000400);
-	nv_icmd(priv, 0x000000eb, 0x00000400);
-	nv_icmd(priv, 0x000000ec, 0x00000400);
-	nv_icmd(priv, 0x000000ed, 0x00000400);
-	nv_icmd(priv, 0x000000ee, 0x00000400);
-	nv_icmd(priv, 0x000000ef, 0x00000400);
-	nv_icmd(priv, 0x00000078, 0x00000300);
-	nv_icmd(priv, 0x00000079, 0x00000300);
-	nv_icmd(priv, 0x0000007a, 0x00000300);
-	nv_icmd(priv, 0x0000007b, 0x00000300);
-	nv_icmd(priv, 0x0000007c, 0x00000300);
-	nv_icmd(priv, 0x0000007d, 0x00000300);
-	nv_icmd(priv, 0x0000007e, 0x00000300);
-	nv_icmd(priv, 0x0000007f, 0x00000300);
-	nv_icmd(priv, 0x00000050, 0x00000011);
-	nv_icmd(priv, 0x00000058, 0x00000008);
-	nv_icmd(priv, 0x00000059, 0x00000008);
-	nv_icmd(priv, 0x0000005a, 0x00000008);
-	nv_icmd(priv, 0x0000005b, 0x00000008);
-	nv_icmd(priv, 0x0000005c, 0x00000008);
-	nv_icmd(priv, 0x0000005d, 0x00000008);
-	nv_icmd(priv, 0x0000005e, 0x00000008);
-	nv_icmd(priv, 0x0000005f, 0x00000008);
-	nv_icmd(priv, 0x00000208, 0x00000001);
-	nv_icmd(priv, 0x00000209, 0x00000001);
-	nv_icmd(priv, 0x0000020a, 0x00000001);
-	nv_icmd(priv, 0x0000020b, 0x00000001);
-	nv_icmd(priv, 0x0000020c, 0x00000001);
-	nv_icmd(priv, 0x0000020d, 0x00000001);
-	nv_icmd(priv, 0x0000020e, 0x00000001);
-	nv_icmd(priv, 0x0000020f, 0x00000001);
-	nv_icmd(priv, 0x00000081, 0x00000001);
-	nv_icmd(priv, 0x00000085, 0x00000004);
-	nv_icmd(priv, 0x00000088, 0x00000400);
-	nv_icmd(priv, 0x00000090, 0x00000300);
-	nv_icmd(priv, 0x00000098, 0x00001001);
-	nv_icmd(priv, 0x000000e3, 0x00000001);
-	nv_icmd(priv, 0x000000da, 0x00000001);
-	nv_icmd(priv, 0x000000f8, 0x00000003);
-	nv_icmd(priv, 0x000000fa, 0x00000001);
-	nv_icmd(priv, 0x0000009f, 0x0000ffff);
-	nv_icmd(priv, 0x000000a0, 0x0000ffff);
-	nv_icmd(priv, 0x000000a1, 0x0000ffff);
-	nv_icmd(priv, 0x000000a2, 0x0000ffff);
-	nv_icmd(priv, 0x000000b1, 0x00000001);
-	nv_icmd(priv, 0x000000b2, 0x00000000);
-	nv_icmd(priv, 0x000000b3, 0x00000000);
-	nv_icmd(priv, 0x000000b4, 0x00000000);
-	nv_icmd(priv, 0x000000b5, 0x00000000);
-	nv_icmd(priv, 0x000000b6, 0x00000000);
-	nv_icmd(priv, 0x000000b7, 0x00000000);
-	nv_icmd(priv, 0x000000b8, 0x00000000);
-	nv_icmd(priv, 0x000000b9, 0x00000000);
-	nv_icmd(priv, 0x000000ba, 0x00000000);
-	nv_icmd(priv, 0x000000bb, 0x00000000);
-	nv_icmd(priv, 0x000000bc, 0x00000000);
-	nv_icmd(priv, 0x000000bd, 0x00000000);
-	nv_icmd(priv, 0x000000be, 0x00000000);
-	nv_icmd(priv, 0x000000bf, 0x00000000);
-	nv_icmd(priv, 0x000000c0, 0x00000000);
-	nv_icmd(priv, 0x000000c1, 0x00000000);
-	nv_icmd(priv, 0x000000c2, 0x00000000);
-	nv_icmd(priv, 0x000000c3, 0x00000000);
-	nv_icmd(priv, 0x000000c4, 0x00000000);
-	nv_icmd(priv, 0x000000c5, 0x00000000);
-	nv_icmd(priv, 0x000000c6, 0x00000000);
-	nv_icmd(priv, 0x000000c7, 0x00000000);
-	nv_icmd(priv, 0x000000c8, 0x00000000);
-	nv_icmd(priv, 0x000000c9, 0x00000000);
-	nv_icmd(priv, 0x000000ca, 0x00000000);
-	nv_icmd(priv, 0x000000cb, 0x00000000);
-	nv_icmd(priv, 0x000000cc, 0x00000000);
-	nv_icmd(priv, 0x000000cd, 0x00000000);
-	nv_icmd(priv, 0x000000ce, 0x00000000);
-	nv_icmd(priv, 0x000000cf, 0x00000000);
-	nv_icmd(priv, 0x000000d0, 0x00000000);
-	nv_icmd(priv, 0x000000d1, 0x00000000);
-	nv_icmd(priv, 0x000000d2, 0x00000000);
-	nv_icmd(priv, 0x000000d3, 0x00000000);
-	nv_icmd(priv, 0x000000d4, 0x00000000);
-	nv_icmd(priv, 0x000000d5, 0x00000000);
-	nv_icmd(priv, 0x000000d6, 0x00000000);
-	nv_icmd(priv, 0x000000d7, 0x00000000);
-	nv_icmd(priv, 0x000000d8, 0x00000000);
-	nv_icmd(priv, 0x000000d9, 0x00000000);
-	nv_icmd(priv, 0x00000210, 0x00000040);
-	nv_icmd(priv, 0x00000211, 0x00000040);
-	nv_icmd(priv, 0x00000212, 0x00000040);
-	nv_icmd(priv, 0x00000213, 0x00000040);
-	nv_icmd(priv, 0x00000214, 0x00000040);
-	nv_icmd(priv, 0x00000215, 0x00000040);
-	nv_icmd(priv, 0x00000216, 0x00000040);
-	nv_icmd(priv, 0x00000217, 0x00000040);
-	if (nv_device(priv)->chipset >= 0xd0) {
-		for (i = 0x0400; i <= 0x0417; i++)
-			nv_icmd(priv, i, 0x00000040);
-	}
-	nv_icmd(priv, 0x00000218, 0x0000c080);
-	nv_icmd(priv, 0x00000219, 0x0000c080);
-	nv_icmd(priv, 0x0000021a, 0x0000c080);
-	nv_icmd(priv, 0x0000021b, 0x0000c080);
-	nv_icmd(priv, 0x0000021c, 0x0000c080);
-	nv_icmd(priv, 0x0000021d, 0x0000c080);
-	nv_icmd(priv, 0x0000021e, 0x0000c080);
-	nv_icmd(priv, 0x0000021f, 0x0000c080);
-	if (nv_device(priv)->chipset >= 0xd0) {
-		for (i = 0x0440; i <= 0x0457; i++)
-			nv_icmd(priv, i, 0x0000c080);
-	}
-	nv_icmd(priv, 0x000000ad, 0x0000013e);
-	nv_icmd(priv, 0x000000e1, 0x00000010);
-	nv_icmd(priv, 0x00000290, 0x00000000);
-	nv_icmd(priv, 0x00000291, 0x00000000);
-	nv_icmd(priv, 0x00000292, 0x00000000);
-	nv_icmd(priv, 0x00000293, 0x00000000);
-	nv_icmd(priv, 0x00000294, 0x00000000);
-	nv_icmd(priv, 0x00000295, 0x00000000);
-	nv_icmd(priv, 0x00000296, 0x00000000);
-	nv_icmd(priv, 0x00000297, 0x00000000);
-	nv_icmd(priv, 0x00000298, 0x00000000);
-	nv_icmd(priv, 0x00000299, 0x00000000);
-	nv_icmd(priv, 0x0000029a, 0x00000000);
-	nv_icmd(priv, 0x0000029b, 0x00000000);
-	nv_icmd(priv, 0x0000029c, 0x00000000);
-	nv_icmd(priv, 0x0000029d, 0x00000000);
-	nv_icmd(priv, 0x0000029e, 0x00000000);
-	nv_icmd(priv, 0x0000029f, 0x00000000);
-	nv_icmd(priv, 0x000003b0, 0x00000000);
-	nv_icmd(priv, 0x000003b1, 0x00000000);
-	nv_icmd(priv, 0x000003b2, 0x00000000);
-	nv_icmd(priv, 0x000003b3, 0x00000000);
-	nv_icmd(priv, 0x000003b4, 0x00000000);
-	nv_icmd(priv, 0x000003b5, 0x00000000);
-	nv_icmd(priv, 0x000003b6, 0x00000000);
-	nv_icmd(priv, 0x000003b7, 0x00000000);
-	nv_icmd(priv, 0x000003b8, 0x00000000);
-	nv_icmd(priv, 0x000003b9, 0x00000000);
-	nv_icmd(priv, 0x000003ba, 0x00000000);
-	nv_icmd(priv, 0x000003bb, 0x00000000);
-	nv_icmd(priv, 0x000003bc, 0x00000000);
-	nv_icmd(priv, 0x000003bd, 0x00000000);
-	nv_icmd(priv, 0x000003be, 0x00000000);
-	nv_icmd(priv, 0x000003bf, 0x00000000);
-	nv_icmd(priv, 0x000002a0, 0x00000000);
-	nv_icmd(priv, 0x000002a1, 0x00000000);
-	nv_icmd(priv, 0x000002a2, 0x00000000);
-	nv_icmd(priv, 0x000002a3, 0x00000000);
-	nv_icmd(priv, 0x000002a4, 0x00000000);
-	nv_icmd(priv, 0x000002a5, 0x00000000);
-	nv_icmd(priv, 0x000002a6, 0x00000000);
-	nv_icmd(priv, 0x000002a7, 0x00000000);
-	nv_icmd(priv, 0x000002a8, 0x00000000);
-	nv_icmd(priv, 0x000002a9, 0x00000000);
-	nv_icmd(priv, 0x000002aa, 0x00000000);
-	nv_icmd(priv, 0x000002ab, 0x00000000);
-	nv_icmd(priv, 0x000002ac, 0x00000000);
-	nv_icmd(priv, 0x000002ad, 0x00000000);
-	nv_icmd(priv, 0x000002ae, 0x00000000);
-	nv_icmd(priv, 0x000002af, 0x00000000);
-	nv_icmd(priv, 0x00000420, 0x00000000);
-	nv_icmd(priv, 0x00000421, 0x00000000);
-	nv_icmd(priv, 0x00000422, 0x00000000);
-	nv_icmd(priv, 0x00000423, 0x00000000);
-	nv_icmd(priv, 0x00000424, 0x00000000);
-	nv_icmd(priv, 0x00000425, 0x00000000);
-	nv_icmd(priv, 0x00000426, 0x00000000);
-	nv_icmd(priv, 0x00000427, 0x00000000);
-	nv_icmd(priv, 0x00000428, 0x00000000);
-	nv_icmd(priv, 0x00000429, 0x00000000);
-	nv_icmd(priv, 0x0000042a, 0x00000000);
-	nv_icmd(priv, 0x0000042b, 0x00000000);
-	nv_icmd(priv, 0x0000042c, 0x00000000);
-	nv_icmd(priv, 0x0000042d, 0x00000000);
-	nv_icmd(priv, 0x0000042e, 0x00000000);
-	nv_icmd(priv, 0x0000042f, 0x00000000);
-	nv_icmd(priv, 0x000002b0, 0x00000000);
-	nv_icmd(priv, 0x000002b1, 0x00000000);
-	nv_icmd(priv, 0x000002b2, 0x00000000);
-	nv_icmd(priv, 0x000002b3, 0x00000000);
-	nv_icmd(priv, 0x000002b4, 0x00000000);
-	nv_icmd(priv, 0x000002b5, 0x00000000);
-	nv_icmd(priv, 0x000002b6, 0x00000000);
-	nv_icmd(priv, 0x000002b7, 0x00000000);
-	nv_icmd(priv, 0x000002b8, 0x00000000);
-	nv_icmd(priv, 0x000002b9, 0x00000000);
-	nv_icmd(priv, 0x000002ba, 0x00000000);
-	nv_icmd(priv, 0x000002bb, 0x00000000);
-	nv_icmd(priv, 0x000002bc, 0x00000000);
-	nv_icmd(priv, 0x000002bd, 0x00000000);
-	nv_icmd(priv, 0x000002be, 0x00000000);
-	nv_icmd(priv, 0x000002bf, 0x00000000);
-	nv_icmd(priv, 0x00000430, 0x00000000);
-	nv_icmd(priv, 0x00000431, 0x00000000);
-	nv_icmd(priv, 0x00000432, 0x00000000);
-	nv_icmd(priv, 0x00000433, 0x00000000);
-	nv_icmd(priv, 0x00000434, 0x00000000);
-	nv_icmd(priv, 0x00000435, 0x00000000);
-	nv_icmd(priv, 0x00000436, 0x00000000);
-	nv_icmd(priv, 0x00000437, 0x00000000);
-	nv_icmd(priv, 0x00000438, 0x00000000);
-	nv_icmd(priv, 0x00000439, 0x00000000);
-	nv_icmd(priv, 0x0000043a, 0x00000000);
-	nv_icmd(priv, 0x0000043b, 0x00000000);
-	nv_icmd(priv, 0x0000043c, 0x00000000);
-	nv_icmd(priv, 0x0000043d, 0x00000000);
-	nv_icmd(priv, 0x0000043e, 0x00000000);
-	nv_icmd(priv, 0x0000043f, 0x00000000);
-	nv_icmd(priv, 0x000002c0, 0x00000000);
-	nv_icmd(priv, 0x000002c1, 0x00000000);
-	nv_icmd(priv, 0x000002c2, 0x00000000);
-	nv_icmd(priv, 0x000002c3, 0x00000000);
-	nv_icmd(priv, 0x000002c4, 0x00000000);
-	nv_icmd(priv, 0x000002c5, 0x00000000);
-	nv_icmd(priv, 0x000002c6, 0x00000000);
-	nv_icmd(priv, 0x000002c7, 0x00000000);
-	nv_icmd(priv, 0x000002c8, 0x00000000);
-	nv_icmd(priv, 0x000002c9, 0x00000000);
-	nv_icmd(priv, 0x000002ca, 0x00000000);
-	nv_icmd(priv, 0x000002cb, 0x00000000);
-	nv_icmd(priv, 0x000002cc, 0x00000000);
-	nv_icmd(priv, 0x000002cd, 0x00000000);
-	nv_icmd(priv, 0x000002ce, 0x00000000);
-	nv_icmd(priv, 0x000002cf, 0x00000000);
-	nv_icmd(priv, 0x000004d0, 0x00000000);
-	nv_icmd(priv, 0x000004d1, 0x00000000);
-	nv_icmd(priv, 0x000004d2, 0x00000000);
-	nv_icmd(priv, 0x000004d3, 0x00000000);
-	nv_icmd(priv, 0x000004d4, 0x00000000);
-	nv_icmd(priv, 0x000004d5, 0x00000000);
-	nv_icmd(priv, 0x000004d6, 0x00000000);
-	nv_icmd(priv, 0x000004d7, 0x00000000);
-	nv_icmd(priv, 0x000004d8, 0x00000000);
-	nv_icmd(priv, 0x000004d9, 0x00000000);
-	nv_icmd(priv, 0x000004da, 0x00000000);
-	nv_icmd(priv, 0x000004db, 0x00000000);
-	nv_icmd(priv, 0x000004dc, 0x00000000);
-	nv_icmd(priv, 0x000004dd, 0x00000000);
-	nv_icmd(priv, 0x000004de, 0x00000000);
-	nv_icmd(priv, 0x000004df, 0x00000000);
-	nv_icmd(priv, 0x00000720, 0x00000000);
-	nv_icmd(priv, 0x00000721, 0x00000000);
-	nv_icmd(priv, 0x00000722, 0x00000000);
-	nv_icmd(priv, 0x00000723, 0x00000000);
-	nv_icmd(priv, 0x00000724, 0x00000000);
-	nv_icmd(priv, 0x00000725, 0x00000000);
-	nv_icmd(priv, 0x00000726, 0x00000000);
-	nv_icmd(priv, 0x00000727, 0x00000000);
-	nv_icmd(priv, 0x00000728, 0x00000000);
-	nv_icmd(priv, 0x00000729, 0x00000000);
-	nv_icmd(priv, 0x0000072a, 0x00000000);
-	nv_icmd(priv, 0x0000072b, 0x00000000);
-	nv_icmd(priv, 0x0000072c, 0x00000000);
-	nv_icmd(priv, 0x0000072d, 0x00000000);
-	nv_icmd(priv, 0x0000072e, 0x00000000);
-	nv_icmd(priv, 0x0000072f, 0x00000000);
-	nv_icmd(priv, 0x000008c0, 0x00000000);
-	nv_icmd(priv, 0x000008c1, 0x00000000);
-	nv_icmd(priv, 0x000008c2, 0x00000000);
-	nv_icmd(priv, 0x000008c3, 0x00000000);
-	nv_icmd(priv, 0x000008c4, 0x00000000);
-	nv_icmd(priv, 0x000008c5, 0x00000000);
-	nv_icmd(priv, 0x000008c6, 0x00000000);
-	nv_icmd(priv, 0x000008c7, 0x00000000);
-	nv_icmd(priv, 0x000008c8, 0x00000000);
-	nv_icmd(priv, 0x000008c9, 0x00000000);
-	nv_icmd(priv, 0x000008ca, 0x00000000);
-	nv_icmd(priv, 0x000008cb, 0x00000000);
-	nv_icmd(priv, 0x000008cc, 0x00000000);
-	nv_icmd(priv, 0x000008cd, 0x00000000);
-	nv_icmd(priv, 0x000008ce, 0x00000000);
-	nv_icmd(priv, 0x000008cf, 0x00000000);
-	nv_icmd(priv, 0x00000890, 0x00000000);
-	nv_icmd(priv, 0x00000891, 0x00000000);
-	nv_icmd(priv, 0x00000892, 0x00000000);
-	nv_icmd(priv, 0x00000893, 0x00000000);
-	nv_icmd(priv, 0x00000894, 0x00000000);
-	nv_icmd(priv, 0x00000895, 0x00000000);
-	nv_icmd(priv, 0x00000896, 0x00000000);
-	nv_icmd(priv, 0x00000897, 0x00000000);
-	nv_icmd(priv, 0x00000898, 0x00000000);
-	nv_icmd(priv, 0x00000899, 0x00000000);
-	nv_icmd(priv, 0x0000089a, 0x00000000);
-	nv_icmd(priv, 0x0000089b, 0x00000000);
-	nv_icmd(priv, 0x0000089c, 0x00000000);
-	nv_icmd(priv, 0x0000089d, 0x00000000);
-	nv_icmd(priv, 0x0000089e, 0x00000000);
-	nv_icmd(priv, 0x0000089f, 0x00000000);
-	nv_icmd(priv, 0x000008e0, 0x00000000);
-	nv_icmd(priv, 0x000008e1, 0x00000000);
-	nv_icmd(priv, 0x000008e2, 0x00000000);
-	nv_icmd(priv, 0x000008e3, 0x00000000);
-	nv_icmd(priv, 0x000008e4, 0x00000000);
-	nv_icmd(priv, 0x000008e5, 0x00000000);
-	nv_icmd(priv, 0x000008e6, 0x00000000);
-	nv_icmd(priv, 0x000008e7, 0x00000000);
-	nv_icmd(priv, 0x000008e8, 0x00000000);
-	nv_icmd(priv, 0x000008e9, 0x00000000);
-	nv_icmd(priv, 0x000008ea, 0x00000000);
-	nv_icmd(priv, 0x000008eb, 0x00000000);
-	nv_icmd(priv, 0x000008ec, 0x00000000);
-	nv_icmd(priv, 0x000008ed, 0x00000000);
-	nv_icmd(priv, 0x000008ee, 0x00000000);
-	nv_icmd(priv, 0x000008ef, 0x00000000);
-	nv_icmd(priv, 0x000008a0, 0x00000000);
-	nv_icmd(priv, 0x000008a1, 0x00000000);
-	nv_icmd(priv, 0x000008a2, 0x00000000);
-	nv_icmd(priv, 0x000008a3, 0x00000000);
-	nv_icmd(priv, 0x000008a4, 0x00000000);
-	nv_icmd(priv, 0x000008a5, 0x00000000);
-	nv_icmd(priv, 0x000008a6, 0x00000000);
-	nv_icmd(priv, 0x000008a7, 0x00000000);
-	nv_icmd(priv, 0x000008a8, 0x00000000);
-	nv_icmd(priv, 0x000008a9, 0x00000000);
-	nv_icmd(priv, 0x000008aa, 0x00000000);
-	nv_icmd(priv, 0x000008ab, 0x00000000);
-	nv_icmd(priv, 0x000008ac, 0x00000000);
-	nv_icmd(priv, 0x000008ad, 0x00000000);
-	nv_icmd(priv, 0x000008ae, 0x00000000);
-	nv_icmd(priv, 0x000008af, 0x00000000);
-	nv_icmd(priv, 0x000008f0, 0x00000000);
-	nv_icmd(priv, 0x000008f1, 0x00000000);
-	nv_icmd(priv, 0x000008f2, 0x00000000);
-	nv_icmd(priv, 0x000008f3, 0x00000000);
-	nv_icmd(priv, 0x000008f4, 0x00000000);
-	nv_icmd(priv, 0x000008f5, 0x00000000);
-	nv_icmd(priv, 0x000008f6, 0x00000000);
-	nv_icmd(priv, 0x000008f7, 0x00000000);
-	nv_icmd(priv, 0x000008f8, 0x00000000);
-	nv_icmd(priv, 0x000008f9, 0x00000000);
-	nv_icmd(priv, 0x000008fa, 0x00000000);
-	nv_icmd(priv, 0x000008fb, 0x00000000);
-	nv_icmd(priv, 0x000008fc, 0x00000000);
-	nv_icmd(priv, 0x000008fd, 0x00000000);
-	nv_icmd(priv, 0x000008fe, 0x00000000);
-	nv_icmd(priv, 0x000008ff, 0x00000000);
-	nv_icmd(priv, 0x0000094c, 0x000000ff);
-	nv_icmd(priv, 0x0000094d, 0xffffffff);
-	nv_icmd(priv, 0x0000094e, 0x00000002);
-	nv_icmd(priv, 0x000002ec, 0x00000001);
-	nv_icmd(priv, 0x00000303, 0x00000001);
-	nv_icmd(priv, 0x000002e6, 0x00000001);
-	nv_icmd(priv, 0x00000466, 0x00000052);
-	nv_icmd(priv, 0x00000301, 0x3f800000);
-	nv_icmd(priv, 0x00000304, 0x30201000);
-	nv_icmd(priv, 0x00000305, 0x70605040);
-	nv_icmd(priv, 0x00000306, 0xb8a89888);
-	nv_icmd(priv, 0x00000307, 0xf8e8d8c8);
-	nv_icmd(priv, 0x0000030a, 0x00ffff00);
-	nv_icmd(priv, 0x0000030b, 0x0000001a);
-	nv_icmd(priv, 0x0000030c, 0x00000001);
-	nv_icmd(priv, 0x00000318, 0x00000001);
-	nv_icmd(priv, 0x00000340, 0x00000000);
-	nv_icmd(priv, 0x00000375, 0x00000001);
-	nv_icmd(priv, 0x00000351, 0x00000100);
-	nv_icmd(priv, 0x0000037d, 0x00000006);
-	nv_icmd(priv, 0x000003a0, 0x00000002);
-	nv_icmd(priv, 0x000003aa, 0x00000001);
-	nv_icmd(priv, 0x000003a9, 0x00000001);
-	nv_icmd(priv, 0x00000380, 0x00000001);
-	nv_icmd(priv, 0x00000360, 0x00000040);
-	nv_icmd(priv, 0x00000366, 0x00000000);
-	nv_icmd(priv, 0x00000367, 0x00000000);
-	nv_icmd(priv, 0x00000368, 0x00001fff);
-	nv_icmd(priv, 0x00000370, 0x00000000);
-	nv_icmd(priv, 0x00000371, 0x00000000);
-	nv_icmd(priv, 0x00000372, 0x003fffff);
-	nv_icmd(priv, 0x0000037a, 0x00000012);
-	nv_icmd(priv, 0x000005e0, 0x00000022);
-	nv_icmd(priv, 0x000005e1, 0x00000022);
-	nv_icmd(priv, 0x000005e2, 0x00000022);
-	nv_icmd(priv, 0x000005e3, 0x00000022);
-	nv_icmd(priv, 0x000005e4, 0x00000022);
-	nv_icmd(priv, 0x00000619, 0x00000003);
-	nv_icmd(priv, 0x00000811, 0x00000003);
-	nv_icmd(priv, 0x00000812, 0x00000004);
-	nv_icmd(priv, 0x00000813, 0x00000006);
-	nv_icmd(priv, 0x00000814, 0x00000008);
-	nv_icmd(priv, 0x00000815, 0x0000000b);
-	nv_icmd(priv, 0x00000800, 0x00000001);
-	nv_icmd(priv, 0x00000801, 0x00000001);
-	nv_icmd(priv, 0x00000802, 0x00000001);
-	nv_icmd(priv, 0x00000803, 0x00000001);
-	nv_icmd(priv, 0x00000804, 0x00000001);
-	nv_icmd(priv, 0x00000805, 0x00000001);
-	nv_icmd(priv, 0x00000632, 0x00000001);
-	nv_icmd(priv, 0x00000633, 0x00000002);
-	nv_icmd(priv, 0x00000634, 0x00000003);
-	nv_icmd(priv, 0x00000635, 0x00000004);
-	nv_icmd(priv, 0x00000654, 0x3f800000);
-	nv_icmd(priv, 0x00000657, 0x3f800000);
-	nv_icmd(priv, 0x00000655, 0x3f800000);
-	nv_icmd(priv, 0x00000656, 0x3f800000);
-	nv_icmd(priv, 0x000006cd, 0x3f800000);
-	nv_icmd(priv, 0x000007f5, 0x3f800000);
-	nv_icmd(priv, 0x000007dc, 0x39291909);
-	nv_icmd(priv, 0x000007dd, 0x79695949);
-	nv_icmd(priv, 0x000007de, 0xb9a99989);
-	nv_icmd(priv, 0x000007df, 0xf9e9d9c9);
-	nv_icmd(priv, 0x000007e8, 0x00003210);
-	nv_icmd(priv, 0x000007e9, 0x00007654);
-	nv_icmd(priv, 0x000007ea, 0x00000098);
-	nv_icmd(priv, 0x000007ec, 0x39291909);
-	nv_icmd(priv, 0x000007ed, 0x79695949);
-	nv_icmd(priv, 0x000007ee, 0xb9a99989);
-	nv_icmd(priv, 0x000007ef, 0xf9e9d9c9);
-	nv_icmd(priv, 0x000007f0, 0x00003210);
-	nv_icmd(priv, 0x000007f1, 0x00007654);
-	nv_icmd(priv, 0x000007f2, 0x00000098);
-	nv_icmd(priv, 0x000005a5, 0x00000001);
-	nv_icmd(priv, 0x00000980, 0x00000000);
-	nv_icmd(priv, 0x00000981, 0x00000000);
-	nv_icmd(priv, 0x00000982, 0x00000000);
-	nv_icmd(priv, 0x00000983, 0x00000000);
-	nv_icmd(priv, 0x00000984, 0x00000000);
-	nv_icmd(priv, 0x00000985, 0x00000000);
-	nv_icmd(priv, 0x00000986, 0x00000000);
-	nv_icmd(priv, 0x00000987, 0x00000000);
-	nv_icmd(priv, 0x00000988, 0x00000000);
-	nv_icmd(priv, 0x00000989, 0x00000000);
-	nv_icmd(priv, 0x0000098a, 0x00000000);
-	nv_icmd(priv, 0x0000098b, 0x00000000);
-	nv_icmd(priv, 0x0000098c, 0x00000000);
-	nv_icmd(priv, 0x0000098d, 0x00000000);
-	nv_icmd(priv, 0x0000098e, 0x00000000);
-	nv_icmd(priv, 0x0000098f, 0x00000000);
-	nv_icmd(priv, 0x00000990, 0x00000000);
-	nv_icmd(priv, 0x00000991, 0x00000000);
-	nv_icmd(priv, 0x00000992, 0x00000000);
-	nv_icmd(priv, 0x00000993, 0x00000000);
-	nv_icmd(priv, 0x00000994, 0x00000000);
-	nv_icmd(priv, 0x00000995, 0x00000000);
-	nv_icmd(priv, 0x00000996, 0x00000000);
-	nv_icmd(priv, 0x00000997, 0x00000000);
-	nv_icmd(priv, 0x00000998, 0x00000000);
-	nv_icmd(priv, 0x00000999, 0x00000000);
-	nv_icmd(priv, 0x0000099a, 0x00000000);
-	nv_icmd(priv, 0x0000099b, 0x00000000);
-	nv_icmd(priv, 0x0000099c, 0x00000000);
-	nv_icmd(priv, 0x0000099d, 0x00000000);
-	nv_icmd(priv, 0x0000099e, 0x00000000);
-	nv_icmd(priv, 0x0000099f, 0x00000000);
-	nv_icmd(priv, 0x000009a0, 0x00000000);
-	nv_icmd(priv, 0x000009a1, 0x00000000);
-	nv_icmd(priv, 0x000009a2, 0x00000000);
-	nv_icmd(priv, 0x000009a3, 0x00000000);
-	nv_icmd(priv, 0x000009a4, 0x00000000);
-	nv_icmd(priv, 0x000009a5, 0x00000000);
-	nv_icmd(priv, 0x000009a6, 0x00000000);
-	nv_icmd(priv, 0x000009a7, 0x00000000);
-	nv_icmd(priv, 0x000009a8, 0x00000000);
-	nv_icmd(priv, 0x000009a9, 0x00000000);
-	nv_icmd(priv, 0x000009aa, 0x00000000);
-	nv_icmd(priv, 0x000009ab, 0x00000000);
-	nv_icmd(priv, 0x000009ac, 0x00000000);
-	nv_icmd(priv, 0x000009ad, 0x00000000);
-	nv_icmd(priv, 0x000009ae, 0x00000000);
-	nv_icmd(priv, 0x000009af, 0x00000000);
-	nv_icmd(priv, 0x000009b0, 0x00000000);
-	nv_icmd(priv, 0x000009b1, 0x00000000);
-	nv_icmd(priv, 0x000009b2, 0x00000000);
-	nv_icmd(priv, 0x000009b3, 0x00000000);
-	nv_icmd(priv, 0x000009b4, 0x00000000);
-	nv_icmd(priv, 0x000009b5, 0x00000000);
-	nv_icmd(priv, 0x000009b6, 0x00000000);
-	nv_icmd(priv, 0x000009b7, 0x00000000);
-	nv_icmd(priv, 0x000009b8, 0x00000000);
-	nv_icmd(priv, 0x000009b9, 0x00000000);
-	nv_icmd(priv, 0x000009ba, 0x00000000);
-	nv_icmd(priv, 0x000009bb, 0x00000000);
-	nv_icmd(priv, 0x000009bc, 0x00000000);
-	nv_icmd(priv, 0x000009bd, 0x00000000);
-	nv_icmd(priv, 0x000009be, 0x00000000);
-	nv_icmd(priv, 0x000009bf, 0x00000000);
-	nv_icmd(priv, 0x000009c0, 0x00000000);
-	nv_icmd(priv, 0x000009c1, 0x00000000);
-	nv_icmd(priv, 0x000009c2, 0x00000000);
-	nv_icmd(priv, 0x000009c3, 0x00000000);
-	nv_icmd(priv, 0x000009c4, 0x00000000);
-	nv_icmd(priv, 0x000009c5, 0x00000000);
-	nv_icmd(priv, 0x000009c6, 0x00000000);
-	nv_icmd(priv, 0x000009c7, 0x00000000);
-	nv_icmd(priv, 0x000009c8, 0x00000000);
-	nv_icmd(priv, 0x000009c9, 0x00000000);
-	nv_icmd(priv, 0x000009ca, 0x00000000);
-	nv_icmd(priv, 0x000009cb, 0x00000000);
-	nv_icmd(priv, 0x000009cc, 0x00000000);
-	nv_icmd(priv, 0x000009cd, 0x00000000);
-	nv_icmd(priv, 0x000009ce, 0x00000000);
-	nv_icmd(priv, 0x000009cf, 0x00000000);
-	nv_icmd(priv, 0x000009d0, 0x00000000);
-	nv_icmd(priv, 0x000009d1, 0x00000000);
-	nv_icmd(priv, 0x000009d2, 0x00000000);
-	nv_icmd(priv, 0x000009d3, 0x00000000);
-	nv_icmd(priv, 0x000009d4, 0x00000000);
-	nv_icmd(priv, 0x000009d5, 0x00000000);
-	nv_icmd(priv, 0x000009d6, 0x00000000);
-	nv_icmd(priv, 0x000009d7, 0x00000000);
-	nv_icmd(priv, 0x000009d8, 0x00000000);
-	nv_icmd(priv, 0x000009d9, 0x00000000);
-	nv_icmd(priv, 0x000009da, 0x00000000);
-	nv_icmd(priv, 0x000009db, 0x00000000);
-	nv_icmd(priv, 0x000009dc, 0x00000000);
-	nv_icmd(priv, 0x000009dd, 0x00000000);
-	nv_icmd(priv, 0x000009de, 0x00000000);
-	nv_icmd(priv, 0x000009df, 0x00000000);
-	nv_icmd(priv, 0x000009e0, 0x00000000);
-	nv_icmd(priv, 0x000009e1, 0x00000000);
-	nv_icmd(priv, 0x000009e2, 0x00000000);
-	nv_icmd(priv, 0x000009e3, 0x00000000);
-	nv_icmd(priv, 0x000009e4, 0x00000000);
-	nv_icmd(priv, 0x000009e5, 0x00000000);
-	nv_icmd(priv, 0x000009e6, 0x00000000);
-	nv_icmd(priv, 0x000009e7, 0x00000000);
-	nv_icmd(priv, 0x000009e8, 0x00000000);
-	nv_icmd(priv, 0x000009e9, 0x00000000);
-	nv_icmd(priv, 0x000009ea, 0x00000000);
-	nv_icmd(priv, 0x000009eb, 0x00000000);
-	nv_icmd(priv, 0x000009ec, 0x00000000);
-	nv_icmd(priv, 0x000009ed, 0x00000000);
-	nv_icmd(priv, 0x000009ee, 0x00000000);
-	nv_icmd(priv, 0x000009ef, 0x00000000);
-	nv_icmd(priv, 0x000009f0, 0x00000000);
-	nv_icmd(priv, 0x000009f1, 0x00000000);
-	nv_icmd(priv, 0x000009f2, 0x00000000);
-	nv_icmd(priv, 0x000009f3, 0x00000000);
-	nv_icmd(priv, 0x000009f4, 0x00000000);
-	nv_icmd(priv, 0x000009f5, 0x00000000);
-	nv_icmd(priv, 0x000009f6, 0x00000000);
-	nv_icmd(priv, 0x000009f7, 0x00000000);
-	nv_icmd(priv, 0x000009f8, 0x00000000);
-	nv_icmd(priv, 0x000009f9, 0x00000000);
-	nv_icmd(priv, 0x000009fa, 0x00000000);
-	nv_icmd(priv, 0x000009fb, 0x00000000);
-	nv_icmd(priv, 0x000009fc, 0x00000000);
-	nv_icmd(priv, 0x000009fd, 0x00000000);
-	nv_icmd(priv, 0x000009fe, 0x00000000);
-	nv_icmd(priv, 0x000009ff, 0x00000000);
-	nv_icmd(priv, 0x00000468, 0x00000004);
-	nv_icmd(priv, 0x0000046c, 0x00000001);
-	nv_icmd(priv, 0x00000470, 0x00000000);
-	nv_icmd(priv, 0x00000471, 0x00000000);
-	nv_icmd(priv, 0x00000472, 0x00000000);
-	nv_icmd(priv, 0x00000473, 0x00000000);
-	nv_icmd(priv, 0x00000474, 0x00000000);
-	nv_icmd(priv, 0x00000475, 0x00000000);
-	nv_icmd(priv, 0x00000476, 0x00000000);
-	nv_icmd(priv, 0x00000477, 0x00000000);
-	nv_icmd(priv, 0x00000478, 0x00000000);
-	nv_icmd(priv, 0x00000479, 0x00000000);
-	nv_icmd(priv, 0x0000047a, 0x00000000);
-	nv_icmd(priv, 0x0000047b, 0x00000000);
-	nv_icmd(priv, 0x0000047c, 0x00000000);
-	nv_icmd(priv, 0x0000047d, 0x00000000);
-	nv_icmd(priv, 0x0000047e, 0x00000000);
-	nv_icmd(priv, 0x0000047f, 0x00000000);
-	nv_icmd(priv, 0x00000480, 0x00000000);
-	nv_icmd(priv, 0x00000481, 0x00000000);
-	nv_icmd(priv, 0x00000482, 0x00000000);
-	nv_icmd(priv, 0x00000483, 0x00000000);
-	nv_icmd(priv, 0x00000484, 0x00000000);
-	nv_icmd(priv, 0x00000485, 0x00000000);
-	nv_icmd(priv, 0x00000486, 0x00000000);
-	nv_icmd(priv, 0x00000487, 0x00000000);
-	nv_icmd(priv, 0x00000488, 0x00000000);
-	nv_icmd(priv, 0x00000489, 0x00000000);
-	nv_icmd(priv, 0x0000048a, 0x00000000);
-	nv_icmd(priv, 0x0000048b, 0x00000000);
-	nv_icmd(priv, 0x0000048c, 0x00000000);
-	nv_icmd(priv, 0x0000048d, 0x00000000);
-	nv_icmd(priv, 0x0000048e, 0x00000000);
-	nv_icmd(priv, 0x0000048f, 0x00000000);
-	nv_icmd(priv, 0x00000490, 0x00000000);
-	nv_icmd(priv, 0x00000491, 0x00000000);
-	nv_icmd(priv, 0x00000492, 0x00000000);
-	nv_icmd(priv, 0x00000493, 0x00000000);
-	nv_icmd(priv, 0x00000494, 0x00000000);
-	nv_icmd(priv, 0x00000495, 0x00000000);
-	nv_icmd(priv, 0x00000496, 0x00000000);
-	nv_icmd(priv, 0x00000497, 0x00000000);
-	nv_icmd(priv, 0x00000498, 0x00000000);
-	nv_icmd(priv, 0x00000499, 0x00000000);
-	nv_icmd(priv, 0x0000049a, 0x00000000);
-	nv_icmd(priv, 0x0000049b, 0x00000000);
-	nv_icmd(priv, 0x0000049c, 0x00000000);
-	nv_icmd(priv, 0x0000049d, 0x00000000);
-	nv_icmd(priv, 0x0000049e, 0x00000000);
-	nv_icmd(priv, 0x0000049f, 0x00000000);
-	nv_icmd(priv, 0x000004a0, 0x00000000);
-	nv_icmd(priv, 0x000004a1, 0x00000000);
-	nv_icmd(priv, 0x000004a2, 0x00000000);
-	nv_icmd(priv, 0x000004a3, 0x00000000);
-	nv_icmd(priv, 0x000004a4, 0x00000000);
-	nv_icmd(priv, 0x000004a5, 0x00000000);
-	nv_icmd(priv, 0x000004a6, 0x00000000);
-	nv_icmd(priv, 0x000004a7, 0x00000000);
-	nv_icmd(priv, 0x000004a8, 0x00000000);
-	nv_icmd(priv, 0x000004a9, 0x00000000);
-	nv_icmd(priv, 0x000004aa, 0x00000000);
-	nv_icmd(priv, 0x000004ab, 0x00000000);
-	nv_icmd(priv, 0x000004ac, 0x00000000);
-	nv_icmd(priv, 0x000004ad, 0x00000000);
-	nv_icmd(priv, 0x000004ae, 0x00000000);
-	nv_icmd(priv, 0x000004af, 0x00000000);
-	nv_icmd(priv, 0x000004b0, 0x00000000);
-	nv_icmd(priv, 0x000004b1, 0x00000000);
-	nv_icmd(priv, 0x000004b2, 0x00000000);
-	nv_icmd(priv, 0x000004b3, 0x00000000);
-	nv_icmd(priv, 0x000004b4, 0x00000000);
-	nv_icmd(priv, 0x000004b5, 0x00000000);
-	nv_icmd(priv, 0x000004b6, 0x00000000);
-	nv_icmd(priv, 0x000004b7, 0x00000000);
-	nv_icmd(priv, 0x000004b8, 0x00000000);
-	nv_icmd(priv, 0x000004b9, 0x00000000);
-	nv_icmd(priv, 0x000004ba, 0x00000000);
-	nv_icmd(priv, 0x000004bb, 0x00000000);
-	nv_icmd(priv, 0x000004bc, 0x00000000);
-	nv_icmd(priv, 0x000004bd, 0x00000000);
-	nv_icmd(priv, 0x000004be, 0x00000000);
-	nv_icmd(priv, 0x000004bf, 0x00000000);
-	nv_icmd(priv, 0x000004c0, 0x00000000);
-	nv_icmd(priv, 0x000004c1, 0x00000000);
-	nv_icmd(priv, 0x000004c2, 0x00000000);
-	nv_icmd(priv, 0x000004c3, 0x00000000);
-	nv_icmd(priv, 0x000004c4, 0x00000000);
-	nv_icmd(priv, 0x000004c5, 0x00000000);
-	nv_icmd(priv, 0x000004c6, 0x00000000);
-	nv_icmd(priv, 0x000004c7, 0x00000000);
-	nv_icmd(priv, 0x000004c8, 0x00000000);
-	nv_icmd(priv, 0x000004c9, 0x00000000);
-	nv_icmd(priv, 0x000004ca, 0x00000000);
-	nv_icmd(priv, 0x000004cb, 0x00000000);
-	nv_icmd(priv, 0x000004cc, 0x00000000);
-	nv_icmd(priv, 0x000004cd, 0x00000000);
-	nv_icmd(priv, 0x000004ce, 0x00000000);
-	nv_icmd(priv, 0x000004cf, 0x00000000);
-	nv_icmd(priv, 0x00000510, 0x3f800000);
-	nv_icmd(priv, 0x00000511, 0x3f800000);
-	nv_icmd(priv, 0x00000512, 0x3f800000);
-	nv_icmd(priv, 0x00000513, 0x3f800000);
-	nv_icmd(priv, 0x00000514, 0x3f800000);
-	nv_icmd(priv, 0x00000515, 0x3f800000);
-	nv_icmd(priv, 0x00000516, 0x3f800000);
-	nv_icmd(priv, 0x00000517, 0x3f800000);
-	nv_icmd(priv, 0x00000518, 0x3f800000);
-	nv_icmd(priv, 0x00000519, 0x3f800000);
-	nv_icmd(priv, 0x0000051a, 0x3f800000);
-	nv_icmd(priv, 0x0000051b, 0x3f800000);
-	nv_icmd(priv, 0x0000051c, 0x3f800000);
-	nv_icmd(priv, 0x0000051d, 0x3f800000);
-	nv_icmd(priv, 0x0000051e, 0x3f800000);
-	nv_icmd(priv, 0x0000051f, 0x3f800000);
-	nv_icmd(priv, 0x00000520, 0x000002b6);
-	nv_icmd(priv, 0x00000529, 0x00000001);
-	nv_icmd(priv, 0x00000530, 0xffff0000);
-	nv_icmd(priv, 0x00000531, 0xffff0000);
-	nv_icmd(priv, 0x00000532, 0xffff0000);
-	nv_icmd(priv, 0x00000533, 0xffff0000);
-	nv_icmd(priv, 0x00000534, 0xffff0000);
-	nv_icmd(priv, 0x00000535, 0xffff0000);
-	nv_icmd(priv, 0x00000536, 0xffff0000);
-	nv_icmd(priv, 0x00000537, 0xffff0000);
-	nv_icmd(priv, 0x00000538, 0xffff0000);
-	nv_icmd(priv, 0x00000539, 0xffff0000);
-	nv_icmd(priv, 0x0000053a, 0xffff0000);
-	nv_icmd(priv, 0x0000053b, 0xffff0000);
-	nv_icmd(priv, 0x0000053c, 0xffff0000);
-	nv_icmd(priv, 0x0000053d, 0xffff0000);
-	nv_icmd(priv, 0x0000053e, 0xffff0000);
-	nv_icmd(priv, 0x0000053f, 0xffff0000);
-	nv_icmd(priv, 0x00000585, 0x0000003f);
-	nv_icmd(priv, 0x00000576, 0x00000003);
-	if (nv_device(priv)->chipset == 0xc1 ||
-	    nv_device(priv)->chipset >= 0xd0)
-		nv_icmd(priv, 0x0000057b, 0x00000059);
-	nv_icmd(priv, 0x00000586, 0x00000040);
-	nv_icmd(priv, 0x00000582, 0x00000080);
-	nv_icmd(priv, 0x00000583, 0x00000080);
-	nv_icmd(priv, 0x000005c2, 0x00000001);
-	nv_icmd(priv, 0x00000638, 0x00000001);
-	nv_icmd(priv, 0x00000639, 0x00000001);
-	nv_icmd(priv, 0x0000063a, 0x00000002);
-	nv_icmd(priv, 0x0000063b, 0x00000001);
-	nv_icmd(priv, 0x0000063c, 0x00000001);
-	nv_icmd(priv, 0x0000063d, 0x00000002);
-	nv_icmd(priv, 0x0000063e, 0x00000001);
-	nv_icmd(priv, 0x000008b8, 0x00000001);
-	nv_icmd(priv, 0x000008b9, 0x00000001);
-	nv_icmd(priv, 0x000008ba, 0x00000001);
-	nv_icmd(priv, 0x000008bb, 0x00000001);
-	nv_icmd(priv, 0x000008bc, 0x00000001);
-	nv_icmd(priv, 0x000008bd, 0x00000001);
-	nv_icmd(priv, 0x000008be, 0x00000001);
-	nv_icmd(priv, 0x000008bf, 0x00000001);
-	nv_icmd(priv, 0x00000900, 0x00000001);
-	nv_icmd(priv, 0x00000901, 0x00000001);
-	nv_icmd(priv, 0x00000902, 0x00000001);
-	nv_icmd(priv, 0x00000903, 0x00000001);
-	nv_icmd(priv, 0x00000904, 0x00000001);
-	nv_icmd(priv, 0x00000905, 0x00000001);
-	nv_icmd(priv, 0x00000906, 0x00000001);
-	nv_icmd(priv, 0x00000907, 0x00000001);
-	nv_icmd(priv, 0x00000908, 0x00000002);
-	nv_icmd(priv, 0x00000909, 0x00000002);
-	nv_icmd(priv, 0x0000090a, 0x00000002);
-	nv_icmd(priv, 0x0000090b, 0x00000002);
-	nv_icmd(priv, 0x0000090c, 0x00000002);
-	nv_icmd(priv, 0x0000090d, 0x00000002);
-	nv_icmd(priv, 0x0000090e, 0x00000002);
-	nv_icmd(priv, 0x0000090f, 0x00000002);
-	nv_icmd(priv, 0x00000910, 0x00000001);
-	nv_icmd(priv, 0x00000911, 0x00000001);
-	nv_icmd(priv, 0x00000912, 0x00000001);
-	nv_icmd(priv, 0x00000913, 0x00000001);
-	nv_icmd(priv, 0x00000914, 0x00000001);
-	nv_icmd(priv, 0x00000915, 0x00000001);
-	nv_icmd(priv, 0x00000916, 0x00000001);
-	nv_icmd(priv, 0x00000917, 0x00000001);
-	nv_icmd(priv, 0x00000918, 0x00000001);
-	nv_icmd(priv, 0x00000919, 0x00000001);
-	nv_icmd(priv, 0x0000091a, 0x00000001);
-	nv_icmd(priv, 0x0000091b, 0x00000001);
-	nv_icmd(priv, 0x0000091c, 0x00000001);
-	nv_icmd(priv, 0x0000091d, 0x00000001);
-	nv_icmd(priv, 0x0000091e, 0x00000001);
-	nv_icmd(priv, 0x0000091f, 0x00000001);
-	nv_icmd(priv, 0x00000920, 0x00000002);
-	nv_icmd(priv, 0x00000921, 0x00000002);
-	nv_icmd(priv, 0x00000922, 0x00000002);
-	nv_icmd(priv, 0x00000923, 0x00000002);
-	nv_icmd(priv, 0x00000924, 0x00000002);
-	nv_icmd(priv, 0x00000925, 0x00000002);
-	nv_icmd(priv, 0x00000926, 0x00000002);
-	nv_icmd(priv, 0x00000927, 0x00000002);
-	nv_icmd(priv, 0x00000928, 0x00000001);
-	nv_icmd(priv, 0x00000929, 0x00000001);
-	nv_icmd(priv, 0x0000092a, 0x00000001);
-	nv_icmd(priv, 0x0000092b, 0x00000001);
-	nv_icmd(priv, 0x0000092c, 0x00000001);
-	nv_icmd(priv, 0x0000092d, 0x00000001);
-	nv_icmd(priv, 0x0000092e, 0x00000001);
-	nv_icmd(priv, 0x0000092f, 0x00000001);
-	nv_icmd(priv, 0x00000648, 0x00000001);
-	nv_icmd(priv, 0x00000649, 0x00000001);
-	nv_icmd(priv, 0x0000064a, 0x00000001);
-	nv_icmd(priv, 0x0000064b, 0x00000001);
-	nv_icmd(priv, 0x0000064c, 0x00000001);
-	nv_icmd(priv, 0x0000064d, 0x00000001);
-	nv_icmd(priv, 0x0000064e, 0x00000001);
-	nv_icmd(priv, 0x0000064f, 0x00000001);
-	nv_icmd(priv, 0x00000650, 0x00000001);
-	nv_icmd(priv, 0x00000658, 0x0000000f);
-	nv_icmd(priv, 0x000007ff, 0x0000000a);
-	nv_icmd(priv, 0x0000066a, 0x40000000);
-	nv_icmd(priv, 0x0000066b, 0x10000000);
-	nv_icmd(priv, 0x0000066c, 0xffff0000);
-	nv_icmd(priv, 0x0000066d, 0xffff0000);
-	nv_icmd(priv, 0x000007af, 0x00000008);
-	nv_icmd(priv, 0x000007b0, 0x00000008);
-	nv_icmd(priv, 0x000007f6, 0x00000001);
-	nv_icmd(priv, 0x000006b2, 0x00000055);
-	nv_icmd(priv, 0x000007ad, 0x00000003);
-	nv_icmd(priv, 0x00000937, 0x00000001);
-	nv_icmd(priv, 0x00000971, 0x00000008);
-	nv_icmd(priv, 0x00000972, 0x00000040);
-	nv_icmd(priv, 0x00000973, 0x0000012c);
-	nv_icmd(priv, 0x0000097c, 0x00000040);
-	nv_icmd(priv, 0x00000979, 0x00000003);
-	nv_icmd(priv, 0x00000975, 0x00000020);
-	nv_icmd(priv, 0x00000976, 0x00000001);
-	nv_icmd(priv, 0x00000977, 0x00000020);
-	nv_icmd(priv, 0x00000978, 0x00000001);
-	nv_icmd(priv, 0x00000957, 0x00000003);
-	nv_icmd(priv, 0x0000095e, 0x20164010);
-	nv_icmd(priv, 0x0000095f, 0x00000020);
-	if (nv_device(priv)->chipset >= 0xd0)
-		nv_icmd(priv, 0x0000097d, 0x00000020);
-	nv_icmd(priv, 0x00000683, 0x00000006);
-	nv_icmd(priv, 0x00000685, 0x003fffff);
-	nv_icmd(priv, 0x00000687, 0x00000c48);
-	nv_icmd(priv, 0x000006a0, 0x00000005);
-	nv_icmd(priv, 0x00000840, 0x00300008);
-	nv_icmd(priv, 0x00000841, 0x04000080);
-	nv_icmd(priv, 0x00000842, 0x00300008);
-	nv_icmd(priv, 0x00000843, 0x04000080);
-	nv_icmd(priv, 0x00000818, 0x00000000);
-	nv_icmd(priv, 0x00000819, 0x00000000);
-	nv_icmd(priv, 0x0000081a, 0x00000000);
-	nv_icmd(priv, 0x0000081b, 0x00000000);
-	nv_icmd(priv, 0x0000081c, 0x00000000);
-	nv_icmd(priv, 0x0000081d, 0x00000000);
-	nv_icmd(priv, 0x0000081e, 0x00000000);
-	nv_icmd(priv, 0x0000081f, 0x00000000);
-	nv_icmd(priv, 0x00000848, 0x00000000);
-	nv_icmd(priv, 0x00000849, 0x00000000);
-	nv_icmd(priv, 0x0000084a, 0x00000000);
-	nv_icmd(priv, 0x0000084b, 0x00000000);
-	nv_icmd(priv, 0x0000084c, 0x00000000);
-	nv_icmd(priv, 0x0000084d, 0x00000000);
-	nv_icmd(priv, 0x0000084e, 0x00000000);
-	nv_icmd(priv, 0x0000084f, 0x00000000);
-	nv_icmd(priv, 0x00000850, 0x00000000);
-	nv_icmd(priv, 0x00000851, 0x00000000);
-	nv_icmd(priv, 0x00000852, 0x00000000);
-	nv_icmd(priv, 0x00000853, 0x00000000);
-	nv_icmd(priv, 0x00000854, 0x00000000);
-	nv_icmd(priv, 0x00000855, 0x00000000);
-	nv_icmd(priv, 0x00000856, 0x00000000);
-	nv_icmd(priv, 0x00000857, 0x00000000);
-	nv_icmd(priv, 0x00000738, 0x00000000);
-	nv_icmd(priv, 0x000006aa, 0x00000001);
-	nv_icmd(priv, 0x000006ab, 0x00000002);
-	nv_icmd(priv, 0x000006ac, 0x00000080);
-	nv_icmd(priv, 0x000006ad, 0x00000100);
-	nv_icmd(priv, 0x000006ae, 0x00000100);
-	nv_icmd(priv, 0x000006b1, 0x00000011);
-	nv_icmd(priv, 0x000006bb, 0x000000cf);
-	nv_icmd(priv, 0x000006ce, 0x2a712488);
-	nv_icmd(priv, 0x00000739, 0x4085c000);
-	nv_icmd(priv, 0x0000073a, 0x00000080);
-	nv_icmd(priv, 0x00000786, 0x80000100);
-	nv_icmd(priv, 0x0000073c, 0x00010100);
-	nv_icmd(priv, 0x0000073d, 0x02800000);
-	nv_icmd(priv, 0x00000787, 0x000000cf);
-	nv_icmd(priv, 0x0000078c, 0x00000008);
-	nv_icmd(priv, 0x00000792, 0x00000001);
-	nv_icmd(priv, 0x00000794, 0x00000001);
-	nv_icmd(priv, 0x00000795, 0x00000001);
-	nv_icmd(priv, 0x00000796, 0x00000001);
-	nv_icmd(priv, 0x00000797, 0x000000cf);
-	nv_icmd(priv, 0x00000836, 0x00000001);
-	nv_icmd(priv, 0x0000079a, 0x00000002);
-	nv_icmd(priv, 0x00000833, 0x04444480);
-	nv_icmd(priv, 0x000007a1, 0x00000001);
-	nv_icmd(priv, 0x000007a3, 0x00000001);
-	nv_icmd(priv, 0x000007a4, 0x00000001);
-	nv_icmd(priv, 0x000007a5, 0x00000001);
-	nv_icmd(priv, 0x00000831, 0x00000004);
-	nv_icmd(priv, 0x0000080c, 0x00000002);
-	nv_icmd(priv, 0x0000080d, 0x00000100);
-	nv_icmd(priv, 0x0000080e, 0x00000100);
-	nv_icmd(priv, 0x0000080f, 0x00000001);
-	nv_icmd(priv, 0x00000823, 0x00000002);
-	nv_icmd(priv, 0x00000824, 0x00000100);
-	nv_icmd(priv, 0x00000825, 0x00000100);
-	nv_icmd(priv, 0x00000826, 0x00000001);
-	nv_icmd(priv, 0x0000095d, 0x00000001);
-	nv_icmd(priv, 0x0000082b, 0x00000004);
-	nv_icmd(priv, 0x00000942, 0x00010001);
-	nv_icmd(priv, 0x00000943, 0x00000001);
-	nv_icmd(priv, 0x00000944, 0x00000022);
-	nv_icmd(priv, 0x000007c5, 0x00010001);
-	nv_icmd(priv, 0x00000834, 0x00000001);
-	nv_icmd(priv, 0x000007c7, 0x00000001);
-	nv_icmd(priv, 0x0000c1b0, 0x0000000f);
-	nv_icmd(priv, 0x0000c1b1, 0x0000000f);
-	nv_icmd(priv, 0x0000c1b2, 0x0000000f);
-	nv_icmd(priv, 0x0000c1b3, 0x0000000f);
-	nv_icmd(priv, 0x0000c1b4, 0x0000000f);
-	nv_icmd(priv, 0x0000c1b5, 0x0000000f);
-	nv_icmd(priv, 0x0000c1b6, 0x0000000f);
-	nv_icmd(priv, 0x0000c1b7, 0x0000000f);
-	nv_icmd(priv, 0x0000c1b8, 0x0fac6881);
-	nv_icmd(priv, 0x0000c1b9, 0x00fac688);
-	nv_icmd(priv, 0x0001e100, 0x00000001);
-	nv_icmd(priv, 0x00001000, 0x00000002);
-	nv_icmd(priv, 0x000006aa, 0x00000001);
-	nv_icmd(priv, 0x000006ad, 0x00000100);
-	nv_icmd(priv, 0x000006ae, 0x00000100);
-	nv_icmd(priv, 0x000006b1, 0x00000011);
-	nv_icmd(priv, 0x0000078c, 0x00000008);
-	nv_icmd(priv, 0x00000792, 0x00000001);
-	nv_icmd(priv, 0x00000794, 0x00000001);
-	nv_icmd(priv, 0x00000795, 0x00000001);
-	nv_icmd(priv, 0x00000796, 0x00000001);
-	nv_icmd(priv, 0x00000797, 0x000000cf);
-	nv_icmd(priv, 0x0000079a, 0x00000002);
-	nv_icmd(priv, 0x00000833, 0x04444480);
-	nv_icmd(priv, 0x000007a1, 0x00000001);
-	nv_icmd(priv, 0x000007a3, 0x00000001);
-	nv_icmd(priv, 0x000007a4, 0x00000001);
-	nv_icmd(priv, 0x000007a5, 0x00000001);
-	nv_icmd(priv, 0x00000831, 0x00000004);
-	nv_icmd(priv, 0x0001e100, 0x00000001);
-	nv_icmd(priv, 0x00001000, 0x00000014);
-	nv_icmd(priv, 0x00000351, 0x00000100);
-	nv_icmd(priv, 0x00000957, 0x00000003);
-	nv_icmd(priv, 0x0000095d, 0x00000001);
-	nv_icmd(priv, 0x0000082b, 0x00000004);
-	nv_icmd(priv, 0x00000942, 0x00010001);
-	nv_icmd(priv, 0x00000943, 0x00000001);
-	nv_icmd(priv, 0x000007c5, 0x00010001);
-	nv_icmd(priv, 0x00000834, 0x00000001);
-	nv_icmd(priv, 0x000007c7, 0x00000001);
-	nv_icmd(priv, 0x0001e100, 0x00000001);
-	nv_icmd(priv, 0x00001000, 0x00000001);
-	nv_icmd(priv, 0x0000080c, 0x00000002);
-	nv_icmd(priv, 0x0000080d, 0x00000100);
-	nv_icmd(priv, 0x0000080e, 0x00000100);
-	nv_icmd(priv, 0x0000080f, 0x00000001);
-	nv_icmd(priv, 0x00000823, 0x00000002);
-	nv_icmd(priv, 0x00000824, 0x00000100);
-	nv_icmd(priv, 0x00000825, 0x00000100);
-	nv_icmd(priv, 0x00000826, 0x00000001);
-	nv_icmd(priv, 0x0001e100, 0x00000001);
-	nv_wr32(priv, 0x400208, 0x00000000);
-	nv_wr32(priv, 0x404154, 0x00000400);
+struct nvc0_graph_init *
+nvc0_grctx_init_hub[] = {
+	nvc0_grctx_init_base,
+	nvc0_grctx_init_unk40xx,
+	nvc0_grctx_init_unk44xx,
+	nvc0_grctx_init_unk46xx,
+	nvc0_grctx_init_unk47xx,
+	nvc0_grctx_init_unk58xx,
+	nvc0_grctx_init_unk60xx,
+	nvc0_grctx_init_unk64xx,
+	nvc0_grctx_init_unk78xx,
+	nvc0_grctx_init_unk80xx,
+	nvc0_grctx_init_rop,
+	NULL
+};
 
-	nvc0_grctx_generate_9097(priv);
-	if (fermi >= 0x9197)
-		nvc0_grctx_generate_9197(priv);
-	if (fermi >= 0x9297)
-		nvc0_grctx_generate_9297(priv);
-	nvc0_grctx_generate_902d(priv);
-	nvc0_grctx_generate_9039(priv);
-	nvc0_grctx_generate_90c0(priv);
+static struct nvc0_graph_init *
+nvc0_grctx_init_gpc[] = {
+	nvc0_grctx_init_gpc_0,
+	nvc0_grctx_init_gpc_1,
+	nvc0_grctx_init_tpc,
+	NULL
+};
 
-	nv_wr32(priv, 0x000260, r000260);
+struct nvc0_graph_init
+nvc0_grctx_init_mthd_magic[] = {
+	{ 0x3410, 1, 0x04, 0x00000000 },
+	{}
+};
 
-	return nvc0_grctx_fini(&info);
-}
+struct nvc0_graph_mthd
+nvc0_grctx_init_mthd[] = {
+	{ 0x9097, nvc0_grctx_init_9097, },
+	{ 0x902d, nvc0_grctx_init_902d, },
+	{ 0x9039, nvc0_grctx_init_9039, },
+	{ 0x90c0, nvc0_grctx_init_90c0, },
+	{ 0x902d, nvc0_grctx_init_mthd_magic, },
+	{}
+};
+
+struct nouveau_oclass *
+nvc0_grctx_oclass = &(struct nvc0_grctx_oclass) {
+	.base.handle = NV_ENGCTX(GR, 0xc0),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_context_ctor,
+		.dtor = nvc0_graph_context_dtor,
+		.init = _nouveau_graph_context_init,
+		.fini = _nouveau_graph_context_fini,
+		.rd32 = _nouveau_graph_context_rd32,
+		.wr32 = _nouveau_graph_context_wr32,
+	},
+	.main = nvc0_grctx_generate_main,
+	.mods = nvc0_grctx_generate_mods,
+	.unkn = nvc0_grctx_generate_unkn,
+	.hub  = nvc0_grctx_init_hub,
+	.gpc  = nvc0_grctx_init_gpc,
+	.icmd = nvc0_grctx_init_icmd,
+	.mthd = nvc0_grctx_init_mthd,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,823 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+static struct nvc0_graph_init
+nvc1_grctx_init_icmd[] = {
+	{ 0x001000,   1, 0x01, 0x00000004 },
+	{ 0x0000a9,   1, 0x01, 0x0000ffff },
+	{ 0x000038,   1, 0x01, 0x0fac6881 },
+	{ 0x00003d,   1, 0x01, 0x00000001 },
+	{ 0x0000e8,   8, 0x01, 0x00000400 },
+	{ 0x000078,   8, 0x01, 0x00000300 },
+	{ 0x000050,   1, 0x01, 0x00000011 },
+	{ 0x000058,   8, 0x01, 0x00000008 },
+	{ 0x000208,   8, 0x01, 0x00000001 },
+	{ 0x000081,   1, 0x01, 0x00000001 },
+	{ 0x000085,   1, 0x01, 0x00000004 },
+	{ 0x000088,   1, 0x01, 0x00000400 },
+	{ 0x000090,   1, 0x01, 0x00000300 },
+	{ 0x000098,   1, 0x01, 0x00001001 },
+	{ 0x0000e3,   1, 0x01, 0x00000001 },
+	{ 0x0000da,   1, 0x01, 0x00000001 },
+	{ 0x0000f8,   1, 0x01, 0x00000003 },
+	{ 0x0000fa,   1, 0x01, 0x00000001 },
+	{ 0x00009f,   4, 0x01, 0x0000ffff },
+	{ 0x0000b1,   1, 0x01, 0x00000001 },
+	{ 0x0000b2,  40, 0x01, 0x00000000 },
+	{ 0x000210,   8, 0x01, 0x00000040 },
+	{ 0x000218,   8, 0x01, 0x0000c080 },
+	{ 0x0000ad,   1, 0x01, 0x0000013e },
+	{ 0x0000e1,   1, 0x01, 0x00000010 },
+	{ 0x000290,  16, 0x01, 0x00000000 },
+	{ 0x0003b0,  16, 0x01, 0x00000000 },
+	{ 0x0002a0,  16, 0x01, 0x00000000 },
+	{ 0x000420,  16, 0x01, 0x00000000 },
+	{ 0x0002b0,  16, 0x01, 0x00000000 },
+	{ 0x000430,  16, 0x01, 0x00000000 },
+	{ 0x0002c0,  16, 0x01, 0x00000000 },
+	{ 0x0004d0,  16, 0x01, 0x00000000 },
+	{ 0x000720,  16, 0x01, 0x00000000 },
+	{ 0x0008c0,  16, 0x01, 0x00000000 },
+	{ 0x000890,  16, 0x01, 0x00000000 },
+	{ 0x0008e0,  16, 0x01, 0x00000000 },
+	{ 0x0008a0,  16, 0x01, 0x00000000 },
+	{ 0x0008f0,  16, 0x01, 0x00000000 },
+	{ 0x00094c,   1, 0x01, 0x000000ff },
+	{ 0x00094d,   1, 0x01, 0xffffffff },
+	{ 0x00094e,   1, 0x01, 0x00000002 },
+	{ 0x0002ec,   1, 0x01, 0x00000001 },
+	{ 0x000303,   1, 0x01, 0x00000001 },
+	{ 0x0002e6,   1, 0x01, 0x00000001 },
+	{ 0x000466,   1, 0x01, 0x00000052 },
+	{ 0x000301,   1, 0x01, 0x3f800000 },
+	{ 0x000304,   1, 0x01, 0x30201000 },
+	{ 0x000305,   1, 0x01, 0x70605040 },
+	{ 0x000306,   1, 0x01, 0xb8a89888 },
+	{ 0x000307,   1, 0x01, 0xf8e8d8c8 },
+	{ 0x00030a,   1, 0x01, 0x00ffff00 },
+	{ 0x00030b,   1, 0x01, 0x0000001a },
+	{ 0x00030c,   1, 0x01, 0x00000001 },
+	{ 0x000318,   1, 0x01, 0x00000001 },
+	{ 0x000340,   1, 0x01, 0x00000000 },
+	{ 0x000375,   1, 0x01, 0x00000001 },
+	{ 0x000351,   1, 0x01, 0x00000100 },
+	{ 0x00037d,   1, 0x01, 0x00000006 },
+	{ 0x0003a0,   1, 0x01, 0x00000002 },
+	{ 0x0003aa,   1, 0x01, 0x00000001 },
+	{ 0x0003a9,   1, 0x01, 0x00000001 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000360,   1, 0x01, 0x00000040 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00001fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x003fffff },
+	{ 0x00037a,   1, 0x01, 0x00000012 },
+	{ 0x0005e0,   5, 0x01, 0x00000022 },
+	{ 0x000619,   1, 0x01, 0x00000003 },
+	{ 0x000811,   1, 0x01, 0x00000003 },
+	{ 0x000812,   1, 0x01, 0x00000004 },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000815,   1, 0x01, 0x0000000b },
+	{ 0x000800,   6, 0x01, 0x00000001 },
+	{ 0x000632,   1, 0x01, 0x00000001 },
+	{ 0x000633,   1, 0x01, 0x00000002 },
+	{ 0x000634,   1, 0x01, 0x00000003 },
+	{ 0x000635,   1, 0x01, 0x00000004 },
+	{ 0x000654,   1, 0x01, 0x3f800000 },
+	{ 0x000657,   1, 0x01, 0x3f800000 },
+	{ 0x000655,   2, 0x01, 0x3f800000 },
+	{ 0x0006cd,   1, 0x01, 0x3f800000 },
+	{ 0x0007f5,   1, 0x01, 0x3f800000 },
+	{ 0x0007dc,   1, 0x01, 0x39291909 },
+	{ 0x0007dd,   1, 0x01, 0x79695949 },
+	{ 0x0007de,   1, 0x01, 0xb9a99989 },
+	{ 0x0007df,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007e8,   1, 0x01, 0x00003210 },
+	{ 0x0007e9,   1, 0x01, 0x00007654 },
+	{ 0x0007ea,   1, 0x01, 0x00000098 },
+	{ 0x0007ec,   1, 0x01, 0x39291909 },
+	{ 0x0007ed,   1, 0x01, 0x79695949 },
+	{ 0x0007ee,   1, 0x01, 0xb9a99989 },
+	{ 0x0007ef,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007f0,   1, 0x01, 0x00003210 },
+	{ 0x0007f1,   1, 0x01, 0x00007654 },
+	{ 0x0007f2,   1, 0x01, 0x00000098 },
+	{ 0x0005a5,   1, 0x01, 0x00000001 },
+	{ 0x000980, 128, 0x01, 0x00000000 },
+	{ 0x000468,   1, 0x01, 0x00000004 },
+	{ 0x00046c,   1, 0x01, 0x00000001 },
+	{ 0x000470,  96, 0x01, 0x00000000 },
+	{ 0x000510,  16, 0x01, 0x3f800000 },
+	{ 0x000520,   1, 0x01, 0x000002b6 },
+	{ 0x000529,   1, 0x01, 0x00000001 },
+	{ 0x000530,  16, 0x01, 0xffff0000 },
+	{ 0x000585,   1, 0x01, 0x0000003f },
+	{ 0x000576,   1, 0x01, 0x00000003 },
+	{ 0x00057b,   1, 0x01, 0x00000059 },
+	{ 0x000586,   1, 0x01, 0x00000040 },
+	{ 0x000582,   2, 0x01, 0x00000080 },
+	{ 0x0005c2,   1, 0x01, 0x00000001 },
+	{ 0x000638,   1, 0x01, 0x00000001 },
+	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x00063a,   1, 0x01, 0x00000002 },
+	{ 0x00063b,   2, 0x01, 0x00000001 },
+	{ 0x00063d,   1, 0x01, 0x00000002 },
+	{ 0x00063e,   1, 0x01, 0x00000001 },
+	{ 0x0008b8,   8, 0x01, 0x00000001 },
+	{ 0x000900,   8, 0x01, 0x00000001 },
+	{ 0x000908,   8, 0x01, 0x00000002 },
+	{ 0x000910,  16, 0x01, 0x00000001 },
+	{ 0x000920,   8, 0x01, 0x00000002 },
+	{ 0x000928,   8, 0x01, 0x00000001 },
+	{ 0x000648,   9, 0x01, 0x00000001 },
+	{ 0x000658,   1, 0x01, 0x0000000f },
+	{ 0x0007ff,   1, 0x01, 0x0000000a },
+	{ 0x00066a,   1, 0x01, 0x40000000 },
+	{ 0x00066b,   1, 0x01, 0x10000000 },
+	{ 0x00066c,   2, 0x01, 0xffff0000 },
+	{ 0x0007af,   2, 0x01, 0x00000008 },
+	{ 0x0007f6,   1, 0x01, 0x00000001 },
+	{ 0x0006b2,   1, 0x01, 0x00000055 },
+	{ 0x0007ad,   1, 0x01, 0x00000003 },
+	{ 0x000937,   1, 0x01, 0x00000001 },
+	{ 0x000971,   1, 0x01, 0x00000008 },
+	{ 0x000972,   1, 0x01, 0x00000040 },
+	{ 0x000973,   1, 0x01, 0x0000012c },
+	{ 0x00097c,   1, 0x01, 0x00000040 },
+	{ 0x000979,   1, 0x01, 0x00000003 },
+	{ 0x000975,   1, 0x01, 0x00000020 },
+	{ 0x000976,   1, 0x01, 0x00000001 },
+	{ 0x000977,   1, 0x01, 0x00000020 },
+	{ 0x000978,   1, 0x01, 0x00000001 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095e,   1, 0x01, 0x20164010 },
+	{ 0x00095f,   1, 0x01, 0x00000020 },
+	{ 0x000683,   1, 0x01, 0x00000006 },
+	{ 0x000685,   1, 0x01, 0x003fffff },
+	{ 0x000687,   1, 0x01, 0x00000c48 },
+	{ 0x0006a0,   1, 0x01, 0x00000005 },
+	{ 0x000840,   1, 0x01, 0x00300008 },
+	{ 0x000841,   1, 0x01, 0x04000080 },
+	{ 0x000842,   1, 0x01, 0x00300008 },
+	{ 0x000843,   1, 0x01, 0x04000080 },
+	{ 0x000818,   8, 0x01, 0x00000000 },
+	{ 0x000848,  16, 0x01, 0x00000000 },
+	{ 0x000738,   1, 0x01, 0x00000000 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ab,   1, 0x01, 0x00000002 },
+	{ 0x0006ac,   1, 0x01, 0x00000080 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x0006bb,   1, 0x01, 0x000000cf },
+	{ 0x0006ce,   1, 0x01, 0x2a712488 },
+	{ 0x000739,   1, 0x01, 0x4085c000 },
+	{ 0x00073a,   1, 0x01, 0x00000080 },
+	{ 0x000786,   1, 0x01, 0x80000100 },
+	{ 0x00073c,   1, 0x01, 0x00010100 },
+	{ 0x00073d,   1, 0x01, 0x02800000 },
+	{ 0x000787,   1, 0x01, 0x000000cf },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x000836,   1, 0x01, 0x00000001 },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x00080c,   1, 0x01, 0x00000002 },
+	{ 0x00080d,   2, 0x01, 0x00000100 },
+	{ 0x00080f,   1, 0x01, 0x00000001 },
+	{ 0x000823,   1, 0x01, 0x00000002 },
+	{ 0x000824,   2, 0x01, 0x00000100 },
+	{ 0x000826,   1, 0x01, 0x00000001 },
+	{ 0x00095d,   1, 0x01, 0x00000001 },
+	{ 0x00082b,   1, 0x01, 0x00000004 },
+	{ 0x000942,   1, 0x01, 0x00010001 },
+	{ 0x000943,   1, 0x01, 0x00000001 },
+	{ 0x000944,   1, 0x01, 0x00000022 },
+	{ 0x0007c5,   1, 0x01, 0x00010001 },
+	{ 0x000834,   1, 0x01, 0x00000001 },
+	{ 0x0007c7,   1, 0x01, 0x00000001 },
+	{ 0x00c1b0,   8, 0x01, 0x0000000f },
+	{ 0x00c1b8,   1, 0x01, 0x0fac6881 },
+	{ 0x00c1b9,   1, 0x01, 0x00fac688 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000002 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000014 },
+	{ 0x000351,   1, 0x01, 0x00000100 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095d,   1, 0x01, 0x00000001 },
+	{ 0x00082b,   1, 0x01, 0x00000004 },
+	{ 0x000942,   1, 0x01, 0x00010001 },
+	{ 0x000943,   1, 0x01, 0x00000001 },
+	{ 0x0007c5,   1, 0x01, 0x00010001 },
+	{ 0x000834,   1, 0x01, 0x00000001 },
+	{ 0x0007c7,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000001 },
+	{ 0x00080c,   1, 0x01, 0x00000002 },
+	{ 0x00080d,   2, 0x01, 0x00000100 },
+	{ 0x00080f,   1, 0x01, 0x00000001 },
+	{ 0x000823,   1, 0x01, 0x00000002 },
+	{ 0x000824,   2, 0x01, 0x00000100 },
+	{ 0x000826,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc1_grctx_init_9097[] = {
+	{ 0x000800,   8, 0x40, 0x00000000 },
+	{ 0x000804,   8, 0x40, 0x00000000 },
+	{ 0x000808,   8, 0x40, 0x00000400 },
+	{ 0x00080c,   8, 0x40, 0x00000300 },
+	{ 0x000810,   1, 0x04, 0x000000cf },
+	{ 0x000850,   7, 0x40, 0x00000000 },
+	{ 0x000814,   8, 0x40, 0x00000040 },
+	{ 0x000818,   8, 0x40, 0x00000001 },
+	{ 0x00081c,   8, 0x40, 0x00000000 },
+	{ 0x000820,   8, 0x40, 0x00000000 },
+	{ 0x002700,   8, 0x20, 0x00000000 },
+	{ 0x002704,   8, 0x20, 0x00000000 },
+	{ 0x002708,   8, 0x20, 0x00000000 },
+	{ 0x00270c,   8, 0x20, 0x00000000 },
+	{ 0x002710,   8, 0x20, 0x00014000 },
+	{ 0x002714,   8, 0x20, 0x00000040 },
+	{ 0x001c00,  16, 0x10, 0x00000000 },
+	{ 0x001c04,  16, 0x10, 0x00000000 },
+	{ 0x001c08,  16, 0x10, 0x00000000 },
+	{ 0x001c0c,  16, 0x10, 0x00000000 },
+	{ 0x001d00,  16, 0x10, 0x00000000 },
+	{ 0x001d04,  16, 0x10, 0x00000000 },
+	{ 0x001d08,  16, 0x10, 0x00000000 },
+	{ 0x001d0c,  16, 0x10, 0x00000000 },
+	{ 0x001f00,  16, 0x08, 0x00000000 },
+	{ 0x001f04,  16, 0x08, 0x00000000 },
+	{ 0x001f80,  16, 0x08, 0x00000000 },
+	{ 0x001f84,  16, 0x08, 0x00000000 },
+	{ 0x002200,   5, 0x10, 0x00000022 },
+	{ 0x002000,   1, 0x04, 0x00000000 },
+	{ 0x002040,   1, 0x04, 0x00000011 },
+	{ 0x002080,   1, 0x04, 0x00000020 },
+	{ 0x0020c0,   1, 0x04, 0x00000030 },
+	{ 0x002100,   1, 0x04, 0x00000040 },
+	{ 0x002140,   1, 0x04, 0x00000051 },
+	{ 0x00200c,   6, 0x40, 0x00000001 },
+	{ 0x002010,   1, 0x04, 0x00000000 },
+	{ 0x002050,   1, 0x04, 0x00000000 },
+	{ 0x002090,   1, 0x04, 0x00000001 },
+	{ 0x0020d0,   1, 0x04, 0x00000002 },
+	{ 0x002110,   1, 0x04, 0x00000003 },
+	{ 0x002150,   1, 0x04, 0x00000004 },
+	{ 0x000380,   4, 0x20, 0x00000000 },
+	{ 0x000384,   4, 0x20, 0x00000000 },
+	{ 0x000388,   4, 0x20, 0x00000000 },
+	{ 0x00038c,   4, 0x20, 0x00000000 },
+	{ 0x000700,   4, 0x10, 0x00000000 },
+	{ 0x000704,   4, 0x10, 0x00000000 },
+	{ 0x000708,   4, 0x10, 0x00000000 },
+	{ 0x002800, 128, 0x04, 0x00000000 },
+	{ 0x000a00,  16, 0x20, 0x00000000 },
+	{ 0x000a04,  16, 0x20, 0x00000000 },
+	{ 0x000a08,  16, 0x20, 0x00000000 },
+	{ 0x000a0c,  16, 0x20, 0x00000000 },
+	{ 0x000a10,  16, 0x20, 0x00000000 },
+	{ 0x000a14,  16, 0x20, 0x00000000 },
+	{ 0x000c00,  16, 0x10, 0x00000000 },
+	{ 0x000c04,  16, 0x10, 0x00000000 },
+	{ 0x000c08,  16, 0x10, 0x00000000 },
+	{ 0x000c0c,  16, 0x10, 0x3f800000 },
+	{ 0x000d00,   8, 0x08, 0xffff0000 },
+	{ 0x000d04,   8, 0x08, 0xffff0000 },
+	{ 0x000e00,  16, 0x10, 0x00000000 },
+	{ 0x000e04,  16, 0x10, 0xffff0000 },
+	{ 0x000e08,  16, 0x10, 0xffff0000 },
+	{ 0x000d40,   4, 0x08, 0x00000000 },
+	{ 0x000d44,   4, 0x08, 0x00000000 },
+	{ 0x001e00,   8, 0x20, 0x00000001 },
+	{ 0x001e04,   8, 0x20, 0x00000001 },
+	{ 0x001e08,   8, 0x20, 0x00000002 },
+	{ 0x001e0c,   8, 0x20, 0x00000001 },
+	{ 0x001e10,   8, 0x20, 0x00000001 },
+	{ 0x001e14,   8, 0x20, 0x00000002 },
+	{ 0x001e18,   8, 0x20, 0x00000001 },
+	{ 0x00030c,   1, 0x04, 0x00000001 },
+	{ 0x001944,   1, 0x04, 0x00000000 },
+	{ 0x001514,   1, 0x04, 0x00000000 },
+	{ 0x000d68,   1, 0x04, 0x0000ffff },
+	{ 0x00121c,   1, 0x04, 0x0fac6881 },
+	{ 0x000fac,   1, 0x04, 0x00000001 },
+	{ 0x001538,   1, 0x04, 0x00000001 },
+	{ 0x000fe0,   2, 0x04, 0x00000000 },
+	{ 0x000fe8,   1, 0x04, 0x00000014 },
+	{ 0x000fec,   1, 0x04, 0x00000040 },
+	{ 0x000ff0,   1, 0x04, 0x00000000 },
+	{ 0x00179c,   1, 0x04, 0x00000000 },
+	{ 0x001228,   1, 0x04, 0x00000400 },
+	{ 0x00122c,   1, 0x04, 0x00000300 },
+	{ 0x001230,   1, 0x04, 0x00010001 },
+	{ 0x0007f8,   1, 0x04, 0x00000000 },
+	{ 0x0015b4,   1, 0x04, 0x00000001 },
+	{ 0x0015cc,   1, 0x04, 0x00000000 },
+	{ 0x001534,   1, 0x04, 0x00000000 },
+	{ 0x000fb0,   1, 0x04, 0x00000000 },
+	{ 0x0015d0,   1, 0x04, 0x00000000 },
+	{ 0x00153c,   1, 0x04, 0x00000000 },
+	{ 0x0016b4,   1, 0x04, 0x00000003 },
+	{ 0x000fbc,   4, 0x04, 0x0000ffff },
+	{ 0x000df8,   2, 0x04, 0x00000000 },
+	{ 0x001948,   1, 0x04, 0x00000000 },
+	{ 0x001970,   1, 0x04, 0x00000001 },
+	{ 0x00161c,   1, 0x04, 0x000009f0 },
+	{ 0x000dcc,   1, 0x04, 0x00000010 },
+	{ 0x00163c,   1, 0x04, 0x00000000 },
+	{ 0x0015e4,   1, 0x04, 0x00000000 },
+	{ 0x001160,  32, 0x04, 0x25e00040 },
+	{ 0x001880,  32, 0x04, 0x00000000 },
+	{ 0x000f84,   2, 0x04, 0x00000000 },
+	{ 0x0017c8,   2, 0x04, 0x00000000 },
+	{ 0x0017d0,   1, 0x04, 0x000000ff },
+	{ 0x0017d4,   1, 0x04, 0xffffffff },
+	{ 0x0017d8,   1, 0x04, 0x00000002 },
+	{ 0x0017dc,   1, 0x04, 0x00000000 },
+	{ 0x0015f4,   2, 0x04, 0x00000000 },
+	{ 0x001434,   2, 0x04, 0x00000000 },
+	{ 0x000d74,   1, 0x04, 0x00000000 },
+	{ 0x000dec,   1, 0x04, 0x00000001 },
+	{ 0x0013a4,   1, 0x04, 0x00000000 },
+	{ 0x001318,   1, 0x04, 0x00000001 },
+	{ 0x001644,   1, 0x04, 0x00000000 },
+	{ 0x000748,   1, 0x04, 0x00000000 },
+	{ 0x000de8,   1, 0x04, 0x00000000 },
+	{ 0x001648,   1, 0x04, 0x00000000 },
+	{ 0x0012a4,   1, 0x04, 0x00000000 },
+	{ 0x001120,   4, 0x04, 0x00000000 },
+	{ 0x001118,   1, 0x04, 0x00000000 },
+	{ 0x00164c,   1, 0x04, 0x00000000 },
+	{ 0x001658,   1, 0x04, 0x00000000 },
+	{ 0x001910,   1, 0x04, 0x00000290 },
+	{ 0x001518,   1, 0x04, 0x00000000 },
+	{ 0x00165c,   1, 0x04, 0x00000001 },
+	{ 0x001520,   1, 0x04, 0x00000000 },
+	{ 0x001604,   1, 0x04, 0x00000000 },
+	{ 0x001570,   1, 0x04, 0x00000000 },
+	{ 0x0013b0,   2, 0x04, 0x3f800000 },
+	{ 0x00020c,   1, 0x04, 0x00000000 },
+	{ 0x001670,   1, 0x04, 0x30201000 },
+	{ 0x001674,   1, 0x04, 0x70605040 },
+	{ 0x001678,   1, 0x04, 0xb8a89888 },
+	{ 0x00167c,   1, 0x04, 0xf8e8d8c8 },
+	{ 0x00166c,   1, 0x04, 0x00000000 },
+	{ 0x001680,   1, 0x04, 0x00ffff00 },
+	{ 0x0012d0,   1, 0x04, 0x00000003 },
+	{ 0x0012d4,   1, 0x04, 0x00000002 },
+	{ 0x001684,   2, 0x04, 0x00000000 },
+	{ 0x000dac,   2, 0x04, 0x00001b02 },
+	{ 0x000db4,   1, 0x04, 0x00000000 },
+	{ 0x00168c,   1, 0x04, 0x00000000 },
+	{ 0x0015bc,   1, 0x04, 0x00000000 },
+	{ 0x00156c,   1, 0x04, 0x00000000 },
+	{ 0x00187c,   1, 0x04, 0x00000000 },
+	{ 0x001110,   1, 0x04, 0x00000001 },
+	{ 0x000dc0,   3, 0x04, 0x00000000 },
+	{ 0x001234,   1, 0x04, 0x00000000 },
+	{ 0x001690,   1, 0x04, 0x00000000 },
+	{ 0x0012ac,   1, 0x04, 0x00000001 },
+	{ 0x0002c4,   1, 0x04, 0x00000000 },
+	{ 0x000790,   5, 0x04, 0x00000000 },
+	{ 0x00077c,   1, 0x04, 0x00000000 },
+	{ 0x001000,   1, 0x04, 0x00000010 },
+	{ 0x0010fc,   1, 0x04, 0x00000000 },
+	{ 0x001290,   1, 0x04, 0x00000000 },
+	{ 0x000218,   1, 0x04, 0x00000010 },
+	{ 0x0012d8,   1, 0x04, 0x00000000 },
+	{ 0x0012dc,   1, 0x04, 0x00000010 },
+	{ 0x000d94,   1, 0x04, 0x00000001 },
+	{ 0x00155c,   2, 0x04, 0x00000000 },
+	{ 0x001564,   1, 0x04, 0x00001fff },
+	{ 0x001574,   2, 0x04, 0x00000000 },
+	{ 0x00157c,   1, 0x04, 0x003fffff },
+	{ 0x001354,   1, 0x04, 0x00000000 },
+	{ 0x001664,   1, 0x04, 0x00000000 },
+	{ 0x001610,   1, 0x04, 0x00000012 },
+	{ 0x001608,   2, 0x04, 0x00000000 },
+	{ 0x00162c,   1, 0x04, 0x00000003 },
+	{ 0x000210,   1, 0x04, 0x00000000 },
+	{ 0x000320,   1, 0x04, 0x00000000 },
+	{ 0x000324,   6, 0x04, 0x3f800000 },
+	{ 0x000750,   1, 0x04, 0x00000000 },
+	{ 0x000760,   1, 0x04, 0x39291909 },
+	{ 0x000764,   1, 0x04, 0x79695949 },
+	{ 0x000768,   1, 0x04, 0xb9a99989 },
+	{ 0x00076c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x000770,   1, 0x04, 0x30201000 },
+	{ 0x000774,   1, 0x04, 0x70605040 },
+	{ 0x000778,   1, 0x04, 0x00009080 },
+	{ 0x000780,   1, 0x04, 0x39291909 },
+	{ 0x000784,   1, 0x04, 0x79695949 },
+	{ 0x000788,   1, 0x04, 0xb9a99989 },
+	{ 0x00078c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x0007d0,   1, 0x04, 0x30201000 },
+	{ 0x0007d4,   1, 0x04, 0x70605040 },
+	{ 0x0007d8,   1, 0x04, 0x00009080 },
+	{ 0x00037c,   1, 0x04, 0x00000001 },
+	{ 0x000740,   2, 0x04, 0x00000000 },
+	{ 0x002600,   1, 0x04, 0x00000000 },
+	{ 0x001918,   1, 0x04, 0x00000000 },
+	{ 0x00191c,   1, 0x04, 0x00000900 },
+	{ 0x001920,   1, 0x04, 0x00000405 },
+	{ 0x001308,   1, 0x04, 0x00000001 },
+	{ 0x001924,   1, 0x04, 0x00000000 },
+	{ 0x0013ac,   1, 0x04, 0x00000000 },
+	{ 0x00192c,   1, 0x04, 0x00000001 },
+	{ 0x00193c,   1, 0x04, 0x00002c1c },
+	{ 0x000d7c,   1, 0x04, 0x00000000 },
+	{ 0x000f8c,   1, 0x04, 0x00000000 },
+	{ 0x0002c0,   1, 0x04, 0x00000001 },
+	{ 0x001510,   1, 0x04, 0x00000000 },
+	{ 0x001940,   1, 0x04, 0x00000000 },
+	{ 0x000ff4,   2, 0x04, 0x00000000 },
+	{ 0x00194c,   2, 0x04, 0x00000000 },
+	{ 0x001968,   1, 0x04, 0x00000000 },
+	{ 0x001590,   1, 0x04, 0x0000003f },
+	{ 0x0007e8,   4, 0x04, 0x00000000 },
+	{ 0x00196c,   1, 0x04, 0x00000011 },
+	{ 0x00197c,   1, 0x04, 0x00000000 },
+	{ 0x000fcc,   2, 0x04, 0x00000000 },
+	{ 0x0002d8,   1, 0x04, 0x00000040 },
+	{ 0x001980,   1, 0x04, 0x00000080 },
+	{ 0x001504,   1, 0x04, 0x00000080 },
+	{ 0x001984,   1, 0x04, 0x00000000 },
+	{ 0x000300,   1, 0x04, 0x00000001 },
+	{ 0x0013a8,   1, 0x04, 0x00000000 },
+	{ 0x0012ec,   1, 0x04, 0x00000000 },
+	{ 0x001310,   1, 0x04, 0x00000000 },
+	{ 0x001314,   1, 0x04, 0x00000001 },
+	{ 0x001380,   1, 0x04, 0x00000000 },
+	{ 0x001384,   4, 0x04, 0x00000001 },
+	{ 0x001394,   1, 0x04, 0x00000000 },
+	{ 0x00139c,   1, 0x04, 0x00000000 },
+	{ 0x001398,   1, 0x04, 0x00000000 },
+	{ 0x001594,   1, 0x04, 0x00000000 },
+	{ 0x001598,   4, 0x04, 0x00000001 },
+	{ 0x000f54,   3, 0x04, 0x00000000 },
+	{ 0x0019bc,   1, 0x04, 0x00000000 },
+	{ 0x000f9c,   2, 0x04, 0x00000000 },
+	{ 0x0012cc,   1, 0x04, 0x00000000 },
+	{ 0x0012e8,   1, 0x04, 0x00000000 },
+	{ 0x00130c,   1, 0x04, 0x00000001 },
+	{ 0x001360,   8, 0x04, 0x00000000 },
+	{ 0x00133c,   2, 0x04, 0x00000001 },
+	{ 0x001344,   1, 0x04, 0x00000002 },
+	{ 0x001348,   2, 0x04, 0x00000001 },
+	{ 0x001350,   1, 0x04, 0x00000002 },
+	{ 0x001358,   1, 0x04, 0x00000001 },
+	{ 0x0012e4,   1, 0x04, 0x00000000 },
+	{ 0x00131c,   1, 0x04, 0x00000000 },
+	{ 0x001320,   3, 0x04, 0x00000000 },
+	{ 0x0019c0,   1, 0x04, 0x00000000 },
+	{ 0x001140,   1, 0x04, 0x00000000 },
+	{ 0x0019c4,   1, 0x04, 0x00000000 },
+	{ 0x0019c8,   1, 0x04, 0x00001500 },
+	{ 0x00135c,   1, 0x04, 0x00000000 },
+	{ 0x000f90,   1, 0x04, 0x00000000 },
+	{ 0x0019e0,   8, 0x04, 0x00000001 },
+	{ 0x0019cc,   1, 0x04, 0x00000001 },
+	{ 0x0015b8,   1, 0x04, 0x00000000 },
+	{ 0x001a00,   1, 0x04, 0x00001111 },
+	{ 0x001a04,   7, 0x04, 0x00000000 },
+	{ 0x000d6c,   2, 0x04, 0xffff0000 },
+	{ 0x0010f8,   1, 0x04, 0x00001010 },
+	{ 0x000d80,   5, 0x04, 0x00000000 },
+	{ 0x000da0,   1, 0x04, 0x00000000 },
+	{ 0x001508,   1, 0x04, 0x80000000 },
+	{ 0x00150c,   1, 0x04, 0x40000000 },
+	{ 0x001668,   1, 0x04, 0x00000000 },
+	{ 0x000318,   2, 0x04, 0x00000008 },
+	{ 0x000d9c,   1, 0x04, 0x00000001 },
+	{ 0x0007dc,   1, 0x04, 0x00000000 },
+	{ 0x00074c,   1, 0x04, 0x00000055 },
+	{ 0x001420,   1, 0x04, 0x00000003 },
+	{ 0x0017bc,   2, 0x04, 0x00000000 },
+	{ 0x0017c4,   1, 0x04, 0x00000001 },
+	{ 0x001008,   1, 0x04, 0x00000008 },
+	{ 0x00100c,   1, 0x04, 0x00000040 },
+	{ 0x001010,   1, 0x04, 0x0000012c },
+	{ 0x000d60,   1, 0x04, 0x00000040 },
+	{ 0x00075c,   1, 0x04, 0x00000003 },
+	{ 0x001018,   1, 0x04, 0x00000020 },
+	{ 0x00101c,   1, 0x04, 0x00000001 },
+	{ 0x001020,   1, 0x04, 0x00000020 },
+	{ 0x001024,   1, 0x04, 0x00000001 },
+	{ 0x001444,   3, 0x04, 0x00000000 },
+	{ 0x000360,   1, 0x04, 0x20164010 },
+	{ 0x000364,   1, 0x04, 0x00000020 },
+	{ 0x000368,   1, 0x04, 0x00000000 },
+	{ 0x000de4,   1, 0x04, 0x00000000 },
+	{ 0x000204,   1, 0x04, 0x00000006 },
+	{ 0x000208,   1, 0x04, 0x00000000 },
+	{ 0x0002cc,   1, 0x04, 0x003fffff },
+	{ 0x0002d0,   1, 0x04, 0x00000c48 },
+	{ 0x001220,   1, 0x04, 0x00000005 },
+	{ 0x000fdc,   1, 0x04, 0x00000000 },
+	{ 0x000f98,   1, 0x04, 0x00300008 },
+	{ 0x001284,   1, 0x04, 0x04000080 },
+	{ 0x001450,   1, 0x04, 0x00300008 },
+	{ 0x001454,   1, 0x04, 0x04000080 },
+	{ 0x000214,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvc1_grctx_init_9197[] = {
+	{ 0x003400, 128, 0x04, 0x00000000 },
+	{ 0x0002e4,   1, 0x04, 0x0000b001 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvc1_grctx_init_unk58xx[] = {
+	{ 0x405800,   1, 0x04, 0x0f8000bf },
+	{ 0x405830,   1, 0x04, 0x02180218 },
+	{ 0x405834,   2, 0x04, 0x00000000 },
+	{ 0x405854,   1, 0x04, 0x00000000 },
+	{ 0x405870,   4, 0x04, 0x00000001 },
+	{ 0x405a00,   2, 0x04, 0x00000000 },
+	{ 0x405a18,   1, 0x04, 0x00000000 },
+};
+
+static struct nvc0_graph_init
+nvc1_grctx_init_rop[] = {
+	{ 0x408800,   1, 0x04, 0x02802a3c },
+	{ 0x408804,   1, 0x04, 0x00000040 },
+	{ 0x408808,   1, 0x04, 0x1003e005 },
+	{ 0x408900,   1, 0x04, 0x3080b801 },
+	{ 0x408904,   1, 0x04, 0x62000001 },
+	{ 0x408908,   1, 0x04, 0x00c80929 },
+	{ 0x408980,   1, 0x04, 0x0000011d },
+};
+
+static struct nvc0_graph_init
+nvc1_grctx_init_gpc_0[] = {
+	{ 0x418380,   1, 0x04, 0x00000016 },
+	{ 0x418400,   1, 0x04, 0x38004e00 },
+	{ 0x418404,   1, 0x04, 0x71e0ffff },
+	{ 0x418408,   1, 0x04, 0x00000000 },
+	{ 0x41840c,   1, 0x04, 0x00001008 },
+	{ 0x418410,   1, 0x04, 0x0fff0fff },
+	{ 0x418414,   1, 0x04, 0x00200fff },
+	{ 0x418450,   6, 0x04, 0x00000000 },
+	{ 0x418468,   1, 0x04, 0x00000001 },
+	{ 0x41846c,   2, 0x04, 0x00000000 },
+	{ 0x418600,   1, 0x04, 0x0000001f },
+	{ 0x418684,   1, 0x04, 0x0000000f },
+	{ 0x418700,   1, 0x04, 0x00000002 },
+	{ 0x418704,   1, 0x04, 0x00000080 },
+	{ 0x418708,   1, 0x04, 0x00000000 },
+	{ 0x41870c,   1, 0x04, 0x07c80000 },
+	{ 0x418710,   1, 0x04, 0x00000000 },
+	{ 0x418800,   1, 0x04, 0x0006860a },
+	{ 0x418808,   3, 0x04, 0x00000000 },
+	{ 0x418828,   1, 0x04, 0x00008442 },
+	{ 0x418830,   1, 0x04, 0x10000001 },
+	{ 0x4188d8,   1, 0x04, 0x00000008 },
+	{ 0x4188e0,   1, 0x04, 0x01000000 },
+	{ 0x4188e8,   5, 0x04, 0x00000000 },
+	{ 0x4188fc,   1, 0x04, 0x00100018 },
+	{ 0x41891c,   1, 0x04, 0x00ff00ff },
+	{ 0x418924,   1, 0x04, 0x00000000 },
+	{ 0x418928,   1, 0x04, 0x00ffff00 },
+	{ 0x41892c,   1, 0x04, 0x0000ff00 },
+	{ 0x418a00,   3, 0x04, 0x00000000 },
+	{ 0x418a0c,   1, 0x04, 0x00010000 },
+	{ 0x418a10,   3, 0x04, 0x00000000 },
+	{ 0x418a20,   3, 0x04, 0x00000000 },
+	{ 0x418a2c,   1, 0x04, 0x00010000 },
+	{ 0x418a30,   3, 0x04, 0x00000000 },
+	{ 0x418a40,   3, 0x04, 0x00000000 },
+	{ 0x418a4c,   1, 0x04, 0x00010000 },
+	{ 0x418a50,   3, 0x04, 0x00000000 },
+	{ 0x418a60,   3, 0x04, 0x00000000 },
+	{ 0x418a6c,   1, 0x04, 0x00010000 },
+	{ 0x418a70,   3, 0x04, 0x00000000 },
+	{ 0x418a80,   3, 0x04, 0x00000000 },
+	{ 0x418a8c,   1, 0x04, 0x00010000 },
+	{ 0x418a90,   3, 0x04, 0x00000000 },
+	{ 0x418aa0,   3, 0x04, 0x00000000 },
+	{ 0x418aac,   1, 0x04, 0x00010000 },
+	{ 0x418ab0,   3, 0x04, 0x00000000 },
+	{ 0x418ac0,   3, 0x04, 0x00000000 },
+	{ 0x418acc,   1, 0x04, 0x00010000 },
+	{ 0x418ad0,   3, 0x04, 0x00000000 },
+	{ 0x418ae0,   3, 0x04, 0x00000000 },
+	{ 0x418aec,   1, 0x04, 0x00010000 },
+	{ 0x418af0,   3, 0x04, 0x00000000 },
+	{ 0x418b00,   1, 0x04, 0x00000000 },
+	{ 0x418b08,   1, 0x04, 0x0a418820 },
+	{ 0x418b0c,   1, 0x04, 0x062080e6 },
+	{ 0x418b10,   1, 0x04, 0x020398a4 },
+	{ 0x418b14,   1, 0x04, 0x0e629062 },
+	{ 0x418b18,   1, 0x04, 0x0a418820 },
+	{ 0x418b1c,   1, 0x04, 0x000000e6 },
+	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{ 0x418c08,   1, 0x04, 0x00000001 },
+	{ 0x418c10,   8, 0x04, 0x00000000 },
+	{ 0x418c6c,   1, 0x04, 0x00000001 },
+	{ 0x418c80,   1, 0x04, 0x20200004 },
+	{ 0x418c8c,   1, 0x04, 0x00000001 },
+	{ 0x419000,   1, 0x04, 0x00000780 },
+	{ 0x419004,   2, 0x04, 0x00000000 },
+	{ 0x419014,   1, 0x04, 0x00000004 },
+};
+
+static struct nvc0_graph_init
+nvc1_grctx_init_tpc[] = {
+	{ 0x419818,   1, 0x04, 0x00000000 },
+	{ 0x41983c,   1, 0x04, 0x00038bc7 },
+	{ 0x419848,   1, 0x04, 0x00000000 },
+	{ 0x419864,   1, 0x04, 0x00000129 },
+	{ 0x419888,   1, 0x04, 0x00000000 },
+	{ 0x419a00,   1, 0x04, 0x000001f0 },
+	{ 0x419a04,   1, 0x04, 0x00000001 },
+	{ 0x419a08,   1, 0x04, 0x00000023 },
+	{ 0x419a0c,   1, 0x04, 0x00020000 },
+	{ 0x419a10,   1, 0x04, 0x00000000 },
+	{ 0x419a14,   1, 0x04, 0x00000200 },
+	{ 0x419a1c,   1, 0x04, 0x00000000 },
+	{ 0x419a20,   1, 0x04, 0x00000800 },
+	{ 0x419ac4,   1, 0x04, 0x0007f440 },
+	{ 0x419b00,   1, 0x04, 0x0a418820 },
+	{ 0x419b04,   1, 0x04, 0x062080e6 },
+	{ 0x419b08,   1, 0x04, 0x020398a4 },
+	{ 0x419b0c,   1, 0x04, 0x0e629062 },
+	{ 0x419b10,   1, 0x04, 0x0a418820 },
+	{ 0x419b14,   1, 0x04, 0x000000e6 },
+	{ 0x419bd0,   1, 0x04, 0x00900103 },
+	{ 0x419be0,   1, 0x04, 0x00400001 },
+	{ 0x419be4,   1, 0x04, 0x00000000 },
+	{ 0x419c00,   1, 0x04, 0x00000002 },
+	{ 0x419c04,   1, 0x04, 0x00000006 },
+	{ 0x419c08,   1, 0x04, 0x00000002 },
+	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{ 0x419cb0,   1, 0x04, 0x00020048 },
+	{ 0x419ce8,   1, 0x04, 0x00000000 },
+	{ 0x419cf4,   1, 0x04, 0x00000183 },
+	{ 0x419d20,   1, 0x04, 0x12180000 },
+	{ 0x419d24,   1, 0x04, 0x00001fff },
+	{ 0x419d44,   1, 0x04, 0x02180218 },
+	{ 0x419e04,   3, 0x04, 0x00000000 },
+	{ 0x419e10,   1, 0x04, 0x00000002 },
+	{ 0x419e44,   1, 0x04, 0x001beff2 },
+	{ 0x419e48,   1, 0x04, 0x00000000 },
+	{ 0x419e4c,   1, 0x04, 0x0000000f },
+	{ 0x419e50,  17, 0x04, 0x00000000 },
+	{ 0x419e98,   1, 0x04, 0x00000000 },
+	{ 0x419ee0,   1, 0x04, 0x00011110 },
+	{ 0x419f30,  11, 0x04, 0x00000000 },
+};
+
+void
+nvc1_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+{
+	int gpc, tpc;
+	u32 offset;
+
+	mmio_data(0x002000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
+	mmio_list(0x408004, 0x00000000,  8, 0);
+	mmio_list(0x408008, 0x80000018,  0, 0);
+	mmio_list(0x40800c, 0x00000000,  8, 1);
+	mmio_list(0x408010, 0x80000000,  0, 0);
+	mmio_list(0x418810, 0x80000000, 12, 2);
+	mmio_list(0x419848, 0x10000000, 12, 2);
+	mmio_list(0x419004, 0x00000000,  8, 1);
+	mmio_list(0x419008, 0x00000000,  0, 0);
+	mmio_list(0x418808, 0x00000000,  8, 0);
+	mmio_list(0x41880c, 0x80000018,  0, 0);
+
+	mmio_list(0x405830, 0x02180218, 0, 0);
+	mmio_list(0x4064c4, 0x0086ffff, 0, 0);
+
+	for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
+		for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+			u32 addr = TPC_UNIT(gpc, tpc, 0x0520);
+			mmio_list(addr, 0x12180000 | offset, 0, 0);
+			offset += 0x0324;
+		}
+		for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+			u32 addr = TPC_UNIT(gpc, tpc, 0x0544);
+			mmio_list(addr, 0x02180000 | offset, 0, 0);
+			offset += 0x0324;
+		}
+	}
+}
+
+void
+nvc1_grctx_generate_unkn(struct nvc0_graph_priv *priv)
+{
+	nv_mask(priv, 0x418c6c, 0x00000001, 0x00000001);
+	nv_mask(priv, 0x41980c, 0x00000010, 0x00000010);
+	nv_mask(priv, 0x419814, 0x00000004, 0x00000004);
+	nv_mask(priv, 0x4064c0, 0x80000000, 0x80000000);
+	nv_mask(priv, 0x405800, 0x08000000, 0x08000000);
+	nv_mask(priv, 0x419c00, 0x00000008, 0x00000008);
+}
+
+static struct nvc0_graph_init *
+nvc1_grctx_init_hub[] = {
+	nvc0_grctx_init_base,
+	nvc0_grctx_init_unk40xx,
+	nvc0_grctx_init_unk44xx,
+	nvc0_grctx_init_unk46xx,
+	nvc0_grctx_init_unk47xx,
+	nvc1_grctx_init_unk58xx,
+	nvc0_grctx_init_unk60xx,
+	nvc0_grctx_init_unk64xx,
+	nvc0_grctx_init_unk78xx,
+	nvc0_grctx_init_unk80xx,
+	nvc1_grctx_init_rop,
+	NULL
+};
+
+struct nvc0_graph_init *
+nvc1_grctx_init_gpc[] = {
+	nvc1_grctx_init_gpc_0,
+	nvc0_grctx_init_gpc_1,
+	nvc1_grctx_init_tpc,
+	NULL
+};
+
+static struct nvc0_graph_mthd
+nvc1_grctx_init_mthd[] = {
+	{ 0x9097, nvc1_grctx_init_9097, },
+	{ 0x9197, nvc1_grctx_init_9197, },
+	{ 0x902d, nvc0_grctx_init_902d, },
+	{ 0x9039, nvc0_grctx_init_9039, },
+	{ 0x90c0, nvc0_grctx_init_90c0, },
+	{ 0x902d, nvc0_grctx_init_mthd_magic, },
+	{}
+};
+
+struct nouveau_oclass *
+nvc1_grctx_oclass = &(struct nvc0_grctx_oclass) {
+	.base.handle = NV_ENGCTX(GR, 0xc1),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_context_ctor,
+		.dtor = nvc0_graph_context_dtor,
+		.init = _nouveau_graph_context_init,
+		.fini = _nouveau_graph_context_fini,
+		.rd32 = _nouveau_graph_context_rd32,
+		.wr32 = _nouveau_graph_context_wr32,
+	},
+	.main = nvc0_grctx_generate_main,
+	.mods = nvc1_grctx_generate_mods,
+	.unkn = nvc1_grctx_generate_unkn,
+	.hub  = nvc1_grctx_init_hub,
+	.gpc  = nvc1_grctx_init_gpc,
+	.icmd = nvc1_grctx_init_icmd,
+	.mthd = nvc1_grctx_init_mthd,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc3.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc3.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc3.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+static struct nvc0_graph_init
+nvc3_grctx_init_tpc[] = {
+	{ 0x419818,   1, 0x04, 0x00000000 },
+	{ 0x41983c,   1, 0x04, 0x00038bc7 },
+	{ 0x419848,   1, 0x04, 0x00000000 },
+	{ 0x419864,   1, 0x04, 0x0000012a },
+	{ 0x419888,   1, 0x04, 0x00000000 },
+	{ 0x419a00,   1, 0x04, 0x000001f0 },
+	{ 0x419a04,   1, 0x04, 0x00000001 },
+	{ 0x419a08,   1, 0x04, 0x00000023 },
+	{ 0x419a0c,   1, 0x04, 0x00020000 },
+	{ 0x419a10,   1, 0x04, 0x00000000 },
+	{ 0x419a14,   1, 0x04, 0x00000200 },
+	{ 0x419a1c,   1, 0x04, 0x00000000 },
+	{ 0x419a20,   1, 0x04, 0x00000800 },
+	{ 0x419ac4,   1, 0x04, 0x0007f440 },
+	{ 0x419b00,   1, 0x04, 0x0a418820 },
+	{ 0x419b04,   1, 0x04, 0x062080e6 },
+	{ 0x419b08,   1, 0x04, 0x020398a4 },
+	{ 0x419b0c,   1, 0x04, 0x0e629062 },
+	{ 0x419b10,   1, 0x04, 0x0a418820 },
+	{ 0x419b14,   1, 0x04, 0x000000e6 },
+	{ 0x419bd0,   1, 0x04, 0x00900103 },
+	{ 0x419be0,   1, 0x04, 0x00000001 },
+	{ 0x419be4,   1, 0x04, 0x00000000 },
+	{ 0x419c00,   1, 0x04, 0x00000002 },
+	{ 0x419c04,   1, 0x04, 0x00000006 },
+	{ 0x419c08,   1, 0x04, 0x00000002 },
+	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{ 0x419cb0,   1, 0x04, 0x00020048 },
+	{ 0x419ce8,   1, 0x04, 0x00000000 },
+	{ 0x419cf4,   1, 0x04, 0x00000183 },
+	{ 0x419d20,   1, 0x04, 0x02180000 },
+	{ 0x419d24,   1, 0x04, 0x00001fff },
+	{ 0x419e04,   3, 0x04, 0x00000000 },
+	{ 0x419e10,   1, 0x04, 0x00000002 },
+	{ 0x419e44,   1, 0x04, 0x001beff2 },
+	{ 0x419e48,   1, 0x04, 0x00000000 },
+	{ 0x419e4c,   1, 0x04, 0x0000000f },
+	{ 0x419e50,  17, 0x04, 0x00000000 },
+	{ 0x419e98,   1, 0x04, 0x00000000 },
+	{ 0x419ee0,   1, 0x04, 0x00011110 },
+	{ 0x419f30,  11, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init *
+nvc3_grctx_init_gpc[] = {
+	nvc0_grctx_init_gpc_0,
+	nvc0_grctx_init_gpc_1,
+	nvc3_grctx_init_tpc,
+	NULL
+};
+
+struct nouveau_oclass *
+nvc3_grctx_oclass = &(struct nvc0_grctx_oclass) {
+	.base.handle = NV_ENGCTX(GR, 0xc3),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_context_ctor,
+		.dtor = nvc0_graph_context_dtor,
+		.init = _nouveau_graph_context_init,
+		.fini = _nouveau_graph_context_fini,
+		.rd32 = _nouveau_graph_context_rd32,
+		.wr32 = _nouveau_graph_context_wr32,
+	},
+	.main = nvc0_grctx_generate_main,
+	.mods = nvc0_grctx_generate_mods,
+	.unkn = nvc0_grctx_generate_unkn,
+	.hub  = nvc0_grctx_init_hub,
+	.gpc  = nvc3_grctx_init_gpc,
+	.icmd = nvc0_grctx_init_icmd,
+	.mthd = nvc0_grctx_init_mthd,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+static struct nvc0_graph_init
+nvc8_grctx_init_icmd[] = {
+	{ 0x001000,   1, 0x01, 0x00000004 },
+	{ 0x0000a9,   1, 0x01, 0x0000ffff },
+	{ 0x000038,   1, 0x01, 0x0fac6881 },
+	{ 0x00003d,   1, 0x01, 0x00000001 },
+	{ 0x0000e8,   8, 0x01, 0x00000400 },
+	{ 0x000078,   8, 0x01, 0x00000300 },
+	{ 0x000050,   1, 0x01, 0x00000011 },
+	{ 0x000058,   8, 0x01, 0x00000008 },
+	{ 0x000208,   8, 0x01, 0x00000001 },
+	{ 0x000081,   1, 0x01, 0x00000001 },
+	{ 0x000085,   1, 0x01, 0x00000004 },
+	{ 0x000088,   1, 0x01, 0x00000400 },
+	{ 0x000090,   1, 0x01, 0x00000300 },
+	{ 0x000098,   1, 0x01, 0x00001001 },
+	{ 0x0000e3,   1, 0x01, 0x00000001 },
+	{ 0x0000da,   1, 0x01, 0x00000001 },
+	{ 0x0000f8,   1, 0x01, 0x00000003 },
+	{ 0x0000fa,   1, 0x01, 0x00000001 },
+	{ 0x00009f,   4, 0x01, 0x0000ffff },
+	{ 0x0000b1,   1, 0x01, 0x00000001 },
+	{ 0x0000b2,  40, 0x01, 0x00000000 },
+	{ 0x000210,   8, 0x01, 0x00000040 },
+	{ 0x000218,   8, 0x01, 0x0000c080 },
+	{ 0x0000ad,   1, 0x01, 0x0000013e },
+	{ 0x0000e1,   1, 0x01, 0x00000010 },
+	{ 0x000290,  16, 0x01, 0x00000000 },
+	{ 0x0003b0,  16, 0x01, 0x00000000 },
+	{ 0x0002a0,  16, 0x01, 0x00000000 },
+	{ 0x000420,  16, 0x01, 0x00000000 },
+	{ 0x0002b0,  16, 0x01, 0x00000000 },
+	{ 0x000430,  16, 0x01, 0x00000000 },
+	{ 0x0002c0,  16, 0x01, 0x00000000 },
+	{ 0x0004d0,  16, 0x01, 0x00000000 },
+	{ 0x000720,  16, 0x01, 0x00000000 },
+	{ 0x0008c0,  16, 0x01, 0x00000000 },
+	{ 0x000890,  16, 0x01, 0x00000000 },
+	{ 0x0008e0,  16, 0x01, 0x00000000 },
+	{ 0x0008a0,  16, 0x01, 0x00000000 },
+	{ 0x0008f0,  16, 0x01, 0x00000000 },
+	{ 0x00094c,   1, 0x01, 0x000000ff },
+	{ 0x00094d,   1, 0x01, 0xffffffff },
+	{ 0x00094e,   1, 0x01, 0x00000002 },
+	{ 0x0002ec,   1, 0x01, 0x00000001 },
+	{ 0x000303,   1, 0x01, 0x00000001 },
+	{ 0x0002e6,   1, 0x01, 0x00000001 },
+	{ 0x000466,   1, 0x01, 0x00000052 },
+	{ 0x000301,   1, 0x01, 0x3f800000 },
+	{ 0x000304,   1, 0x01, 0x30201000 },
+	{ 0x000305,   1, 0x01, 0x70605040 },
+	{ 0x000306,   1, 0x01, 0xb8a89888 },
+	{ 0x000307,   1, 0x01, 0xf8e8d8c8 },
+	{ 0x00030a,   1, 0x01, 0x00ffff00 },
+	{ 0x00030b,   1, 0x01, 0x0000001a },
+	{ 0x00030c,   1, 0x01, 0x00000001 },
+	{ 0x000318,   1, 0x01, 0x00000001 },
+	{ 0x000340,   1, 0x01, 0x00000000 },
+	{ 0x000375,   1, 0x01, 0x00000001 },
+	{ 0x000351,   1, 0x01, 0x00000100 },
+	{ 0x00037d,   1, 0x01, 0x00000006 },
+	{ 0x0003a0,   1, 0x01, 0x00000002 },
+	{ 0x0003aa,   1, 0x01, 0x00000001 },
+	{ 0x0003a9,   1, 0x01, 0x00000001 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000360,   1, 0x01, 0x00000040 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00001fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x003fffff },
+	{ 0x00037a,   1, 0x01, 0x00000012 },
+	{ 0x0005e0,   5, 0x01, 0x00000022 },
+	{ 0x000619,   1, 0x01, 0x00000003 },
+	{ 0x000811,   1, 0x01, 0x00000003 },
+	{ 0x000812,   1, 0x01, 0x00000004 },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000815,   1, 0x01, 0x0000000b },
+	{ 0x000800,   6, 0x01, 0x00000001 },
+	{ 0x000632,   1, 0x01, 0x00000001 },
+	{ 0x000633,   1, 0x01, 0x00000002 },
+	{ 0x000634,   1, 0x01, 0x00000003 },
+	{ 0x000635,   1, 0x01, 0x00000004 },
+	{ 0x000654,   1, 0x01, 0x3f800000 },
+	{ 0x000657,   1, 0x01, 0x3f800000 },
+	{ 0x000655,   2, 0x01, 0x3f800000 },
+	{ 0x0006cd,   1, 0x01, 0x3f800000 },
+	{ 0x0007f5,   1, 0x01, 0x3f800000 },
+	{ 0x0007dc,   1, 0x01, 0x39291909 },
+	{ 0x0007dd,   1, 0x01, 0x79695949 },
+	{ 0x0007de,   1, 0x01, 0xb9a99989 },
+	{ 0x0007df,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007e8,   1, 0x01, 0x00003210 },
+	{ 0x0007e9,   1, 0x01, 0x00007654 },
+	{ 0x0007ea,   1, 0x01, 0x00000098 },
+	{ 0x0007ec,   1, 0x01, 0x39291909 },
+	{ 0x0007ed,   1, 0x01, 0x79695949 },
+	{ 0x0007ee,   1, 0x01, 0xb9a99989 },
+	{ 0x0007ef,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007f0,   1, 0x01, 0x00003210 },
+	{ 0x0007f1,   1, 0x01, 0x00007654 },
+	{ 0x0007f2,   1, 0x01, 0x00000098 },
+	{ 0x0005a5,   1, 0x01, 0x00000001 },
+	{ 0x000980, 128, 0x01, 0x00000000 },
+	{ 0x000468,   1, 0x01, 0x00000004 },
+	{ 0x00046c,   1, 0x01, 0x00000001 },
+	{ 0x000470,  96, 0x01, 0x00000000 },
+	{ 0x000510,  16, 0x01, 0x3f800000 },
+	{ 0x000520,   1, 0x01, 0x000002b6 },
+	{ 0x000529,   1, 0x01, 0x00000001 },
+	{ 0x000530,  16, 0x01, 0xffff0000 },
+	{ 0x000585,   1, 0x01, 0x0000003f },
+	{ 0x000576,   1, 0x01, 0x00000003 },
+	{ 0x00057b,   1, 0x01, 0x00000059 },
+	{ 0x000586,   1, 0x01, 0x00000040 },
+	{ 0x000582,   2, 0x01, 0x00000080 },
+	{ 0x0005c2,   1, 0x01, 0x00000001 },
+	{ 0x000638,   1, 0x01, 0x00000001 },
+	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x00063a,   1, 0x01, 0x00000002 },
+	{ 0x00063b,   2, 0x01, 0x00000001 },
+	{ 0x00063d,   1, 0x01, 0x00000002 },
+	{ 0x00063e,   1, 0x01, 0x00000001 },
+	{ 0x0008b8,   8, 0x01, 0x00000001 },
+	{ 0x000900,   8, 0x01, 0x00000001 },
+	{ 0x000908,   8, 0x01, 0x00000002 },
+	{ 0x000910,  16, 0x01, 0x00000001 },
+	{ 0x000920,   8, 0x01, 0x00000002 },
+	{ 0x000928,   8, 0x01, 0x00000001 },
+	{ 0x000648,   9, 0x01, 0x00000001 },
+	{ 0x000658,   1, 0x01, 0x0000000f },
+	{ 0x0007ff,   1, 0x01, 0x0000000a },
+	{ 0x00066a,   1, 0x01, 0x40000000 },
+	{ 0x00066b,   1, 0x01, 0x10000000 },
+	{ 0x00066c,   2, 0x01, 0xffff0000 },
+	{ 0x0007af,   2, 0x01, 0x00000008 },
+	{ 0x0007f6,   1, 0x01, 0x00000001 },
+	{ 0x0006b2,   1, 0x01, 0x00000055 },
+	{ 0x0007ad,   1, 0x01, 0x00000003 },
+	{ 0x000937,   1, 0x01, 0x00000001 },
+	{ 0x000971,   1, 0x01, 0x00000008 },
+	{ 0x000972,   1, 0x01, 0x00000040 },
+	{ 0x000973,   1, 0x01, 0x0000012c },
+	{ 0x00097c,   1, 0x01, 0x00000040 },
+	{ 0x000979,   1, 0x01, 0x00000003 },
+	{ 0x000975,   1, 0x01, 0x00000020 },
+	{ 0x000976,   1, 0x01, 0x00000001 },
+	{ 0x000977,   1, 0x01, 0x00000020 },
+	{ 0x000978,   1, 0x01, 0x00000001 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095e,   1, 0x01, 0x20164010 },
+	{ 0x00095f,   1, 0x01, 0x00000020 },
+	{ 0x00097d,   1, 0x01, 0x00000020 },
+	{ 0x000683,   1, 0x01, 0x00000006 },
+	{ 0x000685,   1, 0x01, 0x003fffff },
+	{ 0x000687,   1, 0x01, 0x00000c48 },
+	{ 0x0006a0,   1, 0x01, 0x00000005 },
+	{ 0x000840,   1, 0x01, 0x00300008 },
+	{ 0x000841,   1, 0x01, 0x04000080 },
+	{ 0x000842,   1, 0x01, 0x00300008 },
+	{ 0x000843,   1, 0x01, 0x04000080 },
+	{ 0x000818,   8, 0x01, 0x00000000 },
+	{ 0x000848,  16, 0x01, 0x00000000 },
+	{ 0x000738,   1, 0x01, 0x00000000 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ab,   1, 0x01, 0x00000002 },
+	{ 0x0006ac,   1, 0x01, 0x00000080 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x0006bb,   1, 0x01, 0x000000cf },
+	{ 0x0006ce,   1, 0x01, 0x2a712488 },
+	{ 0x000739,   1, 0x01, 0x4085c000 },
+	{ 0x00073a,   1, 0x01, 0x00000080 },
+	{ 0x000786,   1, 0x01, 0x80000100 },
+	{ 0x00073c,   1, 0x01, 0x00010100 },
+	{ 0x00073d,   1, 0x01, 0x02800000 },
+	{ 0x000787,   1, 0x01, 0x000000cf },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x000836,   1, 0x01, 0x00000001 },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x00080c,   1, 0x01, 0x00000002 },
+	{ 0x00080d,   2, 0x01, 0x00000100 },
+	{ 0x00080f,   1, 0x01, 0x00000001 },
+	{ 0x000823,   1, 0x01, 0x00000002 },
+	{ 0x000824,   2, 0x01, 0x00000100 },
+	{ 0x000826,   1, 0x01, 0x00000001 },
+	{ 0x00095d,   1, 0x01, 0x00000001 },
+	{ 0x00082b,   1, 0x01, 0x00000004 },
+	{ 0x000942,   1, 0x01, 0x00010001 },
+	{ 0x000943,   1, 0x01, 0x00000001 },
+	{ 0x000944,   1, 0x01, 0x00000022 },
+	{ 0x0007c5,   1, 0x01, 0x00010001 },
+	{ 0x000834,   1, 0x01, 0x00000001 },
+	{ 0x0007c7,   1, 0x01, 0x00000001 },
+	{ 0x00c1b0,   8, 0x01, 0x0000000f },
+	{ 0x00c1b8,   1, 0x01, 0x0fac6881 },
+	{ 0x00c1b9,   1, 0x01, 0x00fac688 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000002 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000014 },
+	{ 0x000351,   1, 0x01, 0x00000100 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095d,   1, 0x01, 0x00000001 },
+	{ 0x00082b,   1, 0x01, 0x00000004 },
+	{ 0x000942,   1, 0x01, 0x00010001 },
+	{ 0x000943,   1, 0x01, 0x00000001 },
+	{ 0x0007c5,   1, 0x01, 0x00010001 },
+	{ 0x000834,   1, 0x01, 0x00000001 },
+	{ 0x0007c7,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000001 },
+	{ 0x00080c,   1, 0x01, 0x00000002 },
+	{ 0x00080d,   2, 0x01, 0x00000100 },
+	{ 0x00080f,   1, 0x01, 0x00000001 },
+	{ 0x000823,   1, 0x01, 0x00000002 },
+	{ 0x000824,   2, 0x01, 0x00000100 },
+	{ 0x000826,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvc8_grctx_init_tpc[] = {
+	{ 0x419818,   1, 0x04, 0x00000000 },
+	{ 0x41983c,   1, 0x04, 0x00038bc7 },
+	{ 0x419848,   1, 0x04, 0x00000000 },
+	{ 0x419864,   1, 0x04, 0x0000012a },
+	{ 0x419888,   1, 0x04, 0x00000000 },
+	{ 0x419a00,   1, 0x04, 0x000001f0 },
+	{ 0x419a04,   1, 0x04, 0x00000001 },
+	{ 0x419a08,   1, 0x04, 0x00000023 },
+	{ 0x419a0c,   1, 0x04, 0x00020000 },
+	{ 0x419a10,   1, 0x04, 0x00000000 },
+	{ 0x419a14,   1, 0x04, 0x00000200 },
+	{ 0x419a1c,   1, 0x04, 0x00000000 },
+	{ 0x419a20,   1, 0x04, 0x00000800 },
+	{ 0x419b00,   1, 0x04, 0x0a418820 },
+	{ 0x419b04,   1, 0x04, 0x062080e6 },
+	{ 0x419b08,   1, 0x04, 0x020398a4 },
+	{ 0x419b0c,   1, 0x04, 0x0e629062 },
+	{ 0x419b10,   1, 0x04, 0x0a418820 },
+	{ 0x419b14,   1, 0x04, 0x000000e6 },
+	{ 0x419bd0,   1, 0x04, 0x00900103 },
+	{ 0x419be0,   1, 0x04, 0x00000001 },
+	{ 0x419be4,   1, 0x04, 0x00000000 },
+	{ 0x419c00,   1, 0x04, 0x00000002 },
+	{ 0x419c04,   1, 0x04, 0x00000006 },
+	{ 0x419c08,   1, 0x04, 0x00000002 },
+	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{ 0x419cb0,   1, 0x04, 0x00060048 },
+	{ 0x419ce8,   1, 0x04, 0x00000000 },
+	{ 0x419cf4,   1, 0x04, 0x00000183 },
+	{ 0x419d20,   1, 0x04, 0x02180000 },
+	{ 0x419d24,   1, 0x04, 0x00001fff },
+	{ 0x419e04,   3, 0x04, 0x00000000 },
+	{ 0x419e10,   1, 0x04, 0x00000002 },
+	{ 0x419e44,   1, 0x04, 0x001beff2 },
+	{ 0x419e48,   1, 0x04, 0x00000000 },
+	{ 0x419e4c,   1, 0x04, 0x0000000f },
+	{ 0x419e50,  17, 0x04, 0x00000000 },
+	{ 0x419e98,   1, 0x04, 0x00000000 },
+	{ 0x419f50,   2, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc8_grctx_init_9197[] = {
+	{ 0x0002e4,   1, 0x04, 0x0000b001 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc8_grctx_init_9297[] = {
+	{ 0x003400, 128, 0x04, 0x00000000 },
+	{ 0x00036c,   2, 0x04, 0x00000000 },
+	{ 0x0007a4,   2, 0x04, 0x00000000 },
+	{ 0x000374,   1, 0x04, 0x00000000 },
+	{ 0x000378,   1, 0x04, 0x00000020 },
+	{}
+};
+
+static struct nvc0_graph_mthd
+nvc8_grctx_init_mthd[] = {
+	{ 0x9097, nvc1_grctx_init_9097, },
+	{ 0x9197, nvc8_grctx_init_9197, },
+	{ 0x9297, nvc8_grctx_init_9297, },
+	{ 0x902d, nvc0_grctx_init_902d, },
+	{ 0x9039, nvc0_grctx_init_9039, },
+	{ 0x90c0, nvc0_grctx_init_90c0, },
+	{ 0x902d, nvc0_grctx_init_mthd_magic, },
+	{}
+};
+
+static struct nvc0_graph_init *
+nvc8_grctx_init_gpc[] = {
+	nvc0_grctx_init_gpc_0,
+	nvc0_grctx_init_gpc_1,
+	nvc8_grctx_init_tpc,
+	NULL
+};
+
+struct nouveau_oclass *
+nvc8_grctx_oclass = &(struct nvc0_grctx_oclass) {
+	.base.handle = NV_ENGCTX(GR, 0xc8),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_context_ctor,
+		.dtor = nvc0_graph_context_dtor,
+		.init = _nouveau_graph_context_init,
+		.fini = _nouveau_graph_context_fini,
+		.rd32 = _nouveau_graph_context_rd32,
+		.wr32 = _nouveau_graph_context_wr32,
+	},
+	.main = nvc0_grctx_generate_main,
+	.mods = nvc0_grctx_generate_mods,
+	.unkn = nvc0_grctx_generate_unkn,
+	.hub  = nvc0_grctx_init_hub,
+	.gpc  = nvc8_grctx_init_gpc,
+	.icmd = nvc8_grctx_init_icmd,
+	.mthd = nvc8_grctx_init_mthd,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+struct nvc0_graph_init
+nvd7_grctx_init_unk40xx[] = {
+	{ 0x404004,  10, 0x04, 0x00000000 },
+	{ 0x404044,   1, 0x04, 0x00000000 },
+	{ 0x404094,   1, 0x04, 0x00000000 },
+	{ 0x404098,  12, 0x04, 0x00000000 },
+	{ 0x4040c8,   1, 0x04, 0xf0000087 },
+	{ 0x4040d0,   6, 0x04, 0x00000000 },
+	{ 0x4040e8,   1, 0x04, 0x00001000 },
+	{ 0x4040f8,   1, 0x04, 0x00000000 },
+	{ 0x404130,   1, 0x04, 0x00000000 },
+	{ 0x404134,   1, 0x04, 0x00000000 },
+	{ 0x404138,   1, 0x04, 0x20000040 },
+	{ 0x404150,   1, 0x04, 0x0000002e },
+	{ 0x404154,   1, 0x04, 0x00000400 },
+	{ 0x404158,   1, 0x04, 0x00000200 },
+	{ 0x404164,   1, 0x04, 0x00000055 },
+	{ 0x404168,   1, 0x04, 0x00000000 },
+	{ 0x404178,   2, 0x04, 0x00000000 },
+	{ 0x404200,   8, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd7_grctx_init_unk58xx[] = {
+	{ 0x405800,   1, 0x04, 0x0f8000bf },
+	{ 0x405830,   1, 0x04, 0x02180324 },
+	{ 0x405834,   1, 0x04, 0x08000000 },
+	{ 0x405838,   1, 0x04, 0x00000000 },
+	{ 0x405854,   1, 0x04, 0x00000000 },
+	{ 0x405870,   4, 0x04, 0x00000001 },
+	{ 0x405a00,   2, 0x04, 0x00000000 },
+	{ 0x405a18,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd7_grctx_init_unk64xx[] = {
+	{ 0x4064a8,   1, 0x04, 0x00000000 },
+	{ 0x4064ac,   1, 0x04, 0x00003fff },
+	{ 0x4064b4,   3, 0x04, 0x00000000 },
+	{ 0x4064c0,   1, 0x04, 0x801a0078 },
+	{ 0x4064c4,   1, 0x04, 0x00c9ffff },
+	{ 0x4064d0,   8, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd7_grctx_init_gpc_0[] = {
+	{ 0x418380,   1, 0x04, 0x00000016 },
+	{ 0x418400,   1, 0x04, 0x38004e00 },
+	{ 0x418404,   1, 0x04, 0x71e0ffff },
+	{ 0x41840c,   1, 0x04, 0x00001008 },
+	{ 0x418410,   1, 0x04, 0x0fff0fff },
+	{ 0x418414,   1, 0x04, 0x02200fff },
+	{ 0x418450,   6, 0x04, 0x00000000 },
+	{ 0x418468,   1, 0x04, 0x00000001 },
+	{ 0x41846c,   2, 0x04, 0x00000000 },
+	{ 0x418600,   1, 0x04, 0x0000001f },
+	{ 0x418684,   1, 0x04, 0x0000000f },
+	{ 0x418700,   1, 0x04, 0x00000002 },
+	{ 0x418704,   1, 0x04, 0x00000080 },
+	{ 0x418708,   3, 0x04, 0x00000000 },
+	{ 0x418800,   1, 0x04, 0x7006860a },
+	{ 0x418808,   3, 0x04, 0x00000000 },
+	{ 0x418828,   1, 0x04, 0x00008442 },
+	{ 0x418830,   1, 0x04, 0x10000001 },
+	{ 0x4188d8,   1, 0x04, 0x00000008 },
+	{ 0x4188e0,   1, 0x04, 0x01000000 },
+	{ 0x4188e8,   5, 0x04, 0x00000000 },
+	{ 0x4188fc,   1, 0x04, 0x20100018 },
+	{ 0x41891c,   1, 0x04, 0x00ff00ff },
+	{ 0x418924,   1, 0x04, 0x00000000 },
+	{ 0x418928,   1, 0x04, 0x00ffff00 },
+	{ 0x41892c,   1, 0x04, 0x0000ff00 },
+	{ 0x418b00,   1, 0x04, 0x00000006 },
+	{ 0x418b08,   1, 0x04, 0x0a418820 },
+	{ 0x418b0c,   1, 0x04, 0x062080e6 },
+	{ 0x418b10,   1, 0x04, 0x020398a4 },
+	{ 0x418b14,   1, 0x04, 0x0e629062 },
+	{ 0x418b18,   1, 0x04, 0x0a418820 },
+	{ 0x418b1c,   1, 0x04, 0x000000e6 },
+	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{ 0x418c08,   1, 0x04, 0x00000001 },
+	{ 0x418c10,   8, 0x04, 0x00000000 },
+	{ 0x418c6c,   1, 0x04, 0x00000001 },
+	{ 0x418c80,   1, 0x04, 0x20200004 },
+	{ 0x418c8c,   1, 0x04, 0x00000001 },
+	{ 0x419000,   1, 0x04, 0x00000780 },
+	{ 0x419004,   2, 0x04, 0x00000000 },
+	{ 0x419014,   1, 0x04, 0x00000004 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd7_grctx_init_tpc[] = {
+	{ 0x419848,   1, 0x04, 0x00000000 },
+	{ 0x419864,   1, 0x04, 0x00000129 },
+	{ 0x419888,   1, 0x04, 0x00000000 },
+	{ 0x419a00,   1, 0x04, 0x000001f0 },
+	{ 0x419a04,   1, 0x04, 0x00000001 },
+	{ 0x419a08,   1, 0x04, 0x00000023 },
+	{ 0x419a0c,   1, 0x04, 0x00020000 },
+	{ 0x419a10,   1, 0x04, 0x00000000 },
+	{ 0x419a14,   1, 0x04, 0x00000200 },
+	{ 0x419a1c,   1, 0x04, 0x00008000 },
+	{ 0x419a20,   1, 0x04, 0x00000800 },
+	{ 0x419ac4,   1, 0x04, 0x0017f440 },
+	{ 0x419c00,   1, 0x04, 0x0000000a },
+	{ 0x419c04,   1, 0x04, 0x00000006 },
+	{ 0x419c08,   1, 0x04, 0x00000002 },
+	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{ 0x419c24,   1, 0x04, 0x00084210 },
+	{ 0x419c28,   1, 0x04, 0x3efbefbe },
+	{ 0x419cb0,   1, 0x04, 0x00020048 },
+	{ 0x419ce8,   1, 0x04, 0x00000000 },
+	{ 0x419cf4,   1, 0x04, 0x00000183 },
+	{ 0x419e04,   3, 0x04, 0x00000000 },
+	{ 0x419e10,   1, 0x04, 0x00000002 },
+	{ 0x419e44,   1, 0x04, 0x001beff2 },
+	{ 0x419e48,   1, 0x04, 0x00000000 },
+	{ 0x419e4c,   1, 0x04, 0x0000000f },
+	{ 0x419e50,  17, 0x04, 0x00000000 },
+	{ 0x419e98,   1, 0x04, 0x00000000 },
+	{ 0x419ee0,   1, 0x04, 0x00010110 },
+	{ 0x419f30,  11, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd7_grctx_init_unk[] = {
+	{ 0x41be24,   1, 0x04, 0x00000002 },
+	{ 0x41bec0,   1, 0x04, 0x12180000 },
+	{ 0x41bec4,   1, 0x04, 0x00003fff },
+	{ 0x41bee4,   1, 0x04, 0x03240218 },
+	{ 0x41bf00,   1, 0x04, 0x0a418820 },
+	{ 0x41bf04,   1, 0x04, 0x062080e6 },
+	{ 0x41bf08,   1, 0x04, 0x020398a4 },
+	{ 0x41bf0c,   1, 0x04, 0x0e629062 },
+	{ 0x41bf10,   1, 0x04, 0x0a418820 },
+	{ 0x41bf14,   1, 0x04, 0x000000e6 },
+	{ 0x41bfd0,   1, 0x04, 0x00900103 },
+	{ 0x41bfe0,   1, 0x04, 0x00400001 },
+	{ 0x41bfe4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static void
+nvd7_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+{
+	u32 magic[GPC_MAX][2];
+	u32 offset;
+	int gpc;
+
+	mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
+	mmio_list(0x40800c, 0x00000000,  8, 1);
+	mmio_list(0x408010, 0x80000000,  0, 0);
+	mmio_list(0x419004, 0x00000000,  8, 1);
+	mmio_list(0x419008, 0x00000000,  0, 0);
+	mmio_list(0x408004, 0x00000000,  8, 0);
+	mmio_list(0x408008, 0x80000018,  0, 0);
+	mmio_list(0x418808, 0x00000000,  8, 0);
+	mmio_list(0x41880c, 0x80000018,  0, 0);
+	mmio_list(0x418810, 0x80000000, 12, 2);
+	mmio_list(0x419848, 0x10000000, 12, 2);
+
+	mmio_list(0x405830, 0x02180324,  0, 0);
+	mmio_list(0x4064c4, 0x00c9ffff,  0, 0);
+
+	for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
+		u16 magic0 = 0x0218 * priv->tpc_nr[gpc];
+		u16 magic1 = 0x0324 * priv->tpc_nr[gpc];
+		magic[gpc][0]  = 0x10000000 | (magic0 << 16) | offset;
+		magic[gpc][1]  = 0x00000000 | (magic1 << 16);
+		offset += 0x0324 * priv->tpc_nr[gpc];
+	}
+
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0);
+		mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0);
+		offset += 0x07ff * priv->tpc_nr[gpc];
+	}
+	mmio_list(0x17e91c, 0x03060609, 0, 0); /* different from kepler */
+}
+
+void
+nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+{
+	struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
+	int i;
+
+	nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
+
+	for (i = 0; oclass->hub[i]; i++)
+		nvc0_graph_mmio(priv, oclass->hub[i]);
+	for (i = 0; oclass->gpc[i]; i++)
+		nvc0_graph_mmio(priv, oclass->gpc[i]);
+
+	nv_wr32(priv, 0x404154, 0x00000000);
+
+	oclass->mods(priv, info);
+	oclass->unkn(priv);
+
+	nvc0_grctx_generate_tpcid(priv);
+	nvc0_grctx_generate_r406028(priv);
+	nvc0_grctx_generate_r4060a8(priv);
+	nve4_grctx_generate_r418bb8(priv);
+	nvc0_grctx_generate_r406800(priv);
+
+	for (i = 0; i < 8; i++)
+		nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
+
+	nvc0_graph_icmd(priv, oclass->icmd);
+	nv_wr32(priv, 0x404154, 0x00000400);
+	nvc0_graph_mthd(priv, oclass->mthd);
+	nv_mask(priv, 0x000260, 0x00000001, 0x00000001);
+}
+
+
+static struct nvc0_graph_init *
+nvd7_grctx_init_hub[] = {
+	nvc0_grctx_init_base,
+	nvd7_grctx_init_unk40xx,
+	nvc0_grctx_init_unk44xx,
+	nvc0_grctx_init_unk46xx,
+	nvc0_grctx_init_unk47xx,
+	nvd7_grctx_init_unk58xx,
+	nvc0_grctx_init_unk60xx,
+	nvd7_grctx_init_unk64xx,
+	nvc0_grctx_init_unk78xx,
+	nvc0_grctx_init_unk80xx,
+	nvd9_grctx_init_rop,
+};
+
+struct nvc0_graph_init *
+nvd7_grctx_init_gpc[] = {
+	nvd7_grctx_init_gpc_0,
+	nvc0_grctx_init_gpc_1,
+	nvd7_grctx_init_tpc,
+	nvd7_grctx_init_unk,
+	NULL
+};
+
+struct nouveau_oclass *
+nvd7_grctx_oclass = &(struct nvc0_grctx_oclass) {
+	.base.handle = NV_ENGCTX(GR, 0xd7),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_context_ctor,
+		.dtor = nvc0_graph_context_dtor,
+		.init = _nouveau_graph_context_init,
+		.fini = _nouveau_graph_context_fini,
+		.rd32 = _nouveau_graph_context_rd32,
+		.wr32 = _nouveau_graph_context_wr32,
+	},
+	.main = nvd7_grctx_generate_main,
+	.mods = nvd7_grctx_generate_mods,
+	.unkn = nve4_grctx_generate_unkn,
+	.hub  = nvd7_grctx_init_hub,
+	.gpc  = nvd7_grctx_init_gpc,
+	.icmd = nvd9_grctx_init_icmd,
+	.mthd = nvd9_grctx_init_mthd,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,515 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+struct nvc0_graph_init
+nvd9_grctx_init_90c0[] = {
+	{ 0x002700,   4, 0x40, 0x00000000 },
+	{ 0x002720,   4, 0x40, 0x00000000 },
+	{ 0x002704,   4, 0x40, 0x00000000 },
+	{ 0x002724,   4, 0x40, 0x00000000 },
+	{ 0x002708,   4, 0x40, 0x00000000 },
+	{ 0x002728,   4, 0x40, 0x00000000 },
+	{ 0x00270c,   8, 0x20, 0x00000000 },
+	{ 0x002710,   4, 0x40, 0x00014000 },
+	{ 0x002730,   4, 0x40, 0x00014000 },
+	{ 0x002714,   4, 0x40, 0x00000040 },
+	{ 0x002734,   4, 0x40, 0x00000040 },
+	{ 0x00030c,   1, 0x04, 0x00000001 },
+	{ 0x001944,   1, 0x04, 0x00000000 },
+	{ 0x000758,   1, 0x04, 0x00000100 },
+	{ 0x0002c4,   1, 0x04, 0x00000000 },
+	{ 0x000790,   5, 0x04, 0x00000000 },
+	{ 0x00077c,   1, 0x04, 0x00000000 },
+	{ 0x000204,   3, 0x04, 0x00000000 },
+	{ 0x000214,   1, 0x04, 0x00000000 },
+	{ 0x00024c,   1, 0x04, 0x00000000 },
+	{ 0x000d94,   1, 0x04, 0x00000001 },
+	{ 0x001608,   2, 0x04, 0x00000000 },
+	{ 0x001664,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvd9_grctx_init_icmd[] = {
+	{ 0x001000,   1, 0x01, 0x00000004 },
+	{ 0x0000a9,   1, 0x01, 0x0000ffff },
+	{ 0x000038,   1, 0x01, 0x0fac6881 },
+	{ 0x00003d,   1, 0x01, 0x00000001 },
+	{ 0x0000e8,   8, 0x01, 0x00000400 },
+	{ 0x000078,   8, 0x01, 0x00000300 },
+	{ 0x000050,   1, 0x01, 0x00000011 },
+	{ 0x000058,   8, 0x01, 0x00000008 },
+	{ 0x000208,   8, 0x01, 0x00000001 },
+	{ 0x000081,   1, 0x01, 0x00000001 },
+	{ 0x000085,   1, 0x01, 0x00000004 },
+	{ 0x000088,   1, 0x01, 0x00000400 },
+	{ 0x000090,   1, 0x01, 0x00000300 },
+	{ 0x000098,   1, 0x01, 0x00001001 },
+	{ 0x0000e3,   1, 0x01, 0x00000001 },
+	{ 0x0000da,   1, 0x01, 0x00000001 },
+	{ 0x0000f8,   1, 0x01, 0x00000003 },
+	{ 0x0000fa,   1, 0x01, 0x00000001 },
+	{ 0x00009f,   4, 0x01, 0x0000ffff },
+	{ 0x0000b1,   1, 0x01, 0x00000001 },
+	{ 0x0000b2,  40, 0x01, 0x00000000 },
+	{ 0x000210,   8, 0x01, 0x00000040 },
+	{ 0x000400,  24, 0x01, 0x00000040 },
+	{ 0x000218,   8, 0x01, 0x0000c080 },
+	{ 0x000440,  24, 0x01, 0x0000c080 },
+	{ 0x0000ad,   1, 0x01, 0x0000013e },
+	{ 0x0000e1,   1, 0x01, 0x00000010 },
+	{ 0x000290,  16, 0x01, 0x00000000 },
+	{ 0x0003b0,  16, 0x01, 0x00000000 },
+	{ 0x0002a0,  16, 0x01, 0x00000000 },
+	{ 0x000420,  16, 0x01, 0x00000000 },
+	{ 0x0002b0,  16, 0x01, 0x00000000 },
+	{ 0x000430,  16, 0x01, 0x00000000 },
+	{ 0x0002c0,  16, 0x01, 0x00000000 },
+	{ 0x0004d0,  16, 0x01, 0x00000000 },
+	{ 0x000720,  16, 0x01, 0x00000000 },
+	{ 0x0008c0,  16, 0x01, 0x00000000 },
+	{ 0x000890,  16, 0x01, 0x00000000 },
+	{ 0x0008e0,  16, 0x01, 0x00000000 },
+	{ 0x0008a0,  16, 0x01, 0x00000000 },
+	{ 0x0008f0,  16, 0x01, 0x00000000 },
+	{ 0x00094c,   1, 0x01, 0x000000ff },
+	{ 0x00094d,   1, 0x01, 0xffffffff },
+	{ 0x00094e,   1, 0x01, 0x00000002 },
+	{ 0x0002ec,   1, 0x01, 0x00000001 },
+	{ 0x000303,   1, 0x01, 0x00000001 },
+	{ 0x0002e6,   1, 0x01, 0x00000001 },
+	{ 0x000466,   1, 0x01, 0x00000052 },
+	{ 0x000301,   1, 0x01, 0x3f800000 },
+	{ 0x000304,   1, 0x01, 0x30201000 },
+	{ 0x000305,   1, 0x01, 0x70605040 },
+	{ 0x000306,   1, 0x01, 0xb8a89888 },
+	{ 0x000307,   1, 0x01, 0xf8e8d8c8 },
+	{ 0x00030a,   1, 0x01, 0x00ffff00 },
+	{ 0x00030b,   1, 0x01, 0x0000001a },
+	{ 0x00030c,   1, 0x01, 0x00000001 },
+	{ 0x000318,   1, 0x01, 0x00000001 },
+	{ 0x000340,   1, 0x01, 0x00000000 },
+	{ 0x000375,   1, 0x01, 0x00000001 },
+	{ 0x000351,   1, 0x01, 0x00000100 },
+	{ 0x00037d,   1, 0x01, 0x00000006 },
+	{ 0x0003a0,   1, 0x01, 0x00000002 },
+	{ 0x0003aa,   1, 0x01, 0x00000001 },
+	{ 0x0003a9,   1, 0x01, 0x00000001 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000360,   1, 0x01, 0x00000040 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00001fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x003fffff },
+	{ 0x00037a,   1, 0x01, 0x00000012 },
+	{ 0x0005e0,   5, 0x01, 0x00000022 },
+	{ 0x000619,   1, 0x01, 0x00000003 },
+	{ 0x000811,   1, 0x01, 0x00000003 },
+	{ 0x000812,   1, 0x01, 0x00000004 },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000815,   1, 0x01, 0x0000000b },
+	{ 0x000800,   6, 0x01, 0x00000001 },
+	{ 0x000632,   1, 0x01, 0x00000001 },
+	{ 0x000633,   1, 0x01, 0x00000002 },
+	{ 0x000634,   1, 0x01, 0x00000003 },
+	{ 0x000635,   1, 0x01, 0x00000004 },
+	{ 0x000654,   1, 0x01, 0x3f800000 },
+	{ 0x000657,   1, 0x01, 0x3f800000 },
+	{ 0x000655,   2, 0x01, 0x3f800000 },
+	{ 0x0006cd,   1, 0x01, 0x3f800000 },
+	{ 0x0007f5,   1, 0x01, 0x3f800000 },
+	{ 0x0007dc,   1, 0x01, 0x39291909 },
+	{ 0x0007dd,   1, 0x01, 0x79695949 },
+	{ 0x0007de,   1, 0x01, 0xb9a99989 },
+	{ 0x0007df,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007e8,   1, 0x01, 0x00003210 },
+	{ 0x0007e9,   1, 0x01, 0x00007654 },
+	{ 0x0007ea,   1, 0x01, 0x00000098 },
+	{ 0x0007ec,   1, 0x01, 0x39291909 },
+	{ 0x0007ed,   1, 0x01, 0x79695949 },
+	{ 0x0007ee,   1, 0x01, 0xb9a99989 },
+	{ 0x0007ef,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007f0,   1, 0x01, 0x00003210 },
+	{ 0x0007f1,   1, 0x01, 0x00007654 },
+	{ 0x0007f2,   1, 0x01, 0x00000098 },
+	{ 0x0005a5,   1, 0x01, 0x00000001 },
+	{ 0x000980, 128, 0x01, 0x00000000 },
+	{ 0x000468,   1, 0x01, 0x00000004 },
+	{ 0x00046c,   1, 0x01, 0x00000001 },
+	{ 0x000470,  96, 0x01, 0x00000000 },
+	{ 0x000510,  16, 0x01, 0x3f800000 },
+	{ 0x000520,   1, 0x01, 0x000002b6 },
+	{ 0x000529,   1, 0x01, 0x00000001 },
+	{ 0x000530,  16, 0x01, 0xffff0000 },
+	{ 0x000585,   1, 0x01, 0x0000003f },
+	{ 0x000576,   1, 0x01, 0x00000003 },
+	{ 0x00057b,   1, 0x01, 0x00000059 },
+	{ 0x000586,   1, 0x01, 0x00000040 },
+	{ 0x000582,   2, 0x01, 0x00000080 },
+	{ 0x0005c2,   1, 0x01, 0x00000001 },
+	{ 0x000638,   1, 0x01, 0x00000001 },
+	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x00063a,   1, 0x01, 0x00000002 },
+	{ 0x00063b,   2, 0x01, 0x00000001 },
+	{ 0x00063d,   1, 0x01, 0x00000002 },
+	{ 0x00063e,   1, 0x01, 0x00000001 },
+	{ 0x0008b8,   8, 0x01, 0x00000001 },
+	{ 0x000900,   8, 0x01, 0x00000001 },
+	{ 0x000908,   8, 0x01, 0x00000002 },
+	{ 0x000910,  16, 0x01, 0x00000001 },
+	{ 0x000920,   8, 0x01, 0x00000002 },
+	{ 0x000928,   8, 0x01, 0x00000001 },
+	{ 0x000648,   9, 0x01, 0x00000001 },
+	{ 0x000658,   1, 0x01, 0x0000000f },
+	{ 0x0007ff,   1, 0x01, 0x0000000a },
+	{ 0x00066a,   1, 0x01, 0x40000000 },
+	{ 0x00066b,   1, 0x01, 0x10000000 },
+	{ 0x00066c,   2, 0x01, 0xffff0000 },
+	{ 0x0007af,   2, 0x01, 0x00000008 },
+	{ 0x0007f6,   1, 0x01, 0x00000001 },
+	{ 0x0006b2,   1, 0x01, 0x00000055 },
+	{ 0x0007ad,   1, 0x01, 0x00000003 },
+	{ 0x000937,   1, 0x01, 0x00000001 },
+	{ 0x000971,   1, 0x01, 0x00000008 },
+	{ 0x000972,   1, 0x01, 0x00000040 },
+	{ 0x000973,   1, 0x01, 0x0000012c },
+	{ 0x00097c,   1, 0x01, 0x00000040 },
+	{ 0x000979,   1, 0x01, 0x00000003 },
+	{ 0x000975,   1, 0x01, 0x00000020 },
+	{ 0x000976,   1, 0x01, 0x00000001 },
+	{ 0x000977,   1, 0x01, 0x00000020 },
+	{ 0x000978,   1, 0x01, 0x00000001 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095e,   1, 0x01, 0x20164010 },
+	{ 0x00095f,   1, 0x01, 0x00000020 },
+	{ 0x00097d,   1, 0x01, 0x00000020 },
+	{ 0x000683,   1, 0x01, 0x00000006 },
+	{ 0x000685,   1, 0x01, 0x003fffff },
+	{ 0x000687,   1, 0x01, 0x00000c48 },
+	{ 0x0006a0,   1, 0x01, 0x00000005 },
+	{ 0x000840,   1, 0x01, 0x00300008 },
+	{ 0x000841,   1, 0x01, 0x04000080 },
+	{ 0x000842,   1, 0x01, 0x00300008 },
+	{ 0x000843,   1, 0x01, 0x04000080 },
+	{ 0x000818,   8, 0x01, 0x00000000 },
+	{ 0x000848,  16, 0x01, 0x00000000 },
+	{ 0x000738,   1, 0x01, 0x00000000 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ab,   1, 0x01, 0x00000002 },
+	{ 0x0006ac,   1, 0x01, 0x00000080 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x0006bb,   1, 0x01, 0x000000cf },
+	{ 0x0006ce,   1, 0x01, 0x2a712488 },
+	{ 0x000739,   1, 0x01, 0x4085c000 },
+	{ 0x00073a,   1, 0x01, 0x00000080 },
+	{ 0x000786,   1, 0x01, 0x80000100 },
+	{ 0x00073c,   1, 0x01, 0x00010100 },
+	{ 0x00073d,   1, 0x01, 0x02800000 },
+	{ 0x000787,   1, 0x01, 0x000000cf },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x000836,   1, 0x01, 0x00000001 },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x00080c,   1, 0x01, 0x00000002 },
+	{ 0x00080d,   2, 0x01, 0x00000100 },
+	{ 0x00080f,   1, 0x01, 0x00000001 },
+	{ 0x000823,   1, 0x01, 0x00000002 },
+	{ 0x000824,   2, 0x01, 0x00000100 },
+	{ 0x000826,   1, 0x01, 0x00000001 },
+	{ 0x00095d,   1, 0x01, 0x00000001 },
+	{ 0x00082b,   1, 0x01, 0x00000004 },
+	{ 0x000942,   1, 0x01, 0x00010001 },
+	{ 0x000943,   1, 0x01, 0x00000001 },
+	{ 0x000944,   1, 0x01, 0x00000022 },
+	{ 0x0007c5,   1, 0x01, 0x00010001 },
+	{ 0x000834,   1, 0x01, 0x00000001 },
+	{ 0x0007c7,   1, 0x01, 0x00000001 },
+	{ 0x00c1b0,   8, 0x01, 0x0000000f },
+	{ 0x00c1b8,   1, 0x01, 0x0fac6881 },
+	{ 0x00c1b9,   1, 0x01, 0x00fac688 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000002 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000014 },
+	{ 0x000351,   1, 0x01, 0x00000100 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095d,   1, 0x01, 0x00000001 },
+	{ 0x00082b,   1, 0x01, 0x00000004 },
+	{ 0x000942,   1, 0x01, 0x00010001 },
+	{ 0x000943,   1, 0x01, 0x00000001 },
+	{ 0x0007c5,   1, 0x01, 0x00010001 },
+	{ 0x000834,   1, 0x01, 0x00000001 },
+	{ 0x0007c7,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000001 },
+	{ 0x00080c,   1, 0x01, 0x00000002 },
+	{ 0x00080d,   2, 0x01, 0x00000100 },
+	{ 0x00080f,   1, 0x01, 0x00000001 },
+	{ 0x000823,   1, 0x01, 0x00000002 },
+	{ 0x000824,   2, 0x01, 0x00000100 },
+	{ 0x000826,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{}
+};
+
+struct nvc0_graph_init
+nvd9_grctx_init_unk40xx[] = {
+	{ 0x404004,  11, 0x04, 0x00000000 },
+	{ 0x404044,   1, 0x04, 0x00000000 },
+	{ 0x404094,   1, 0x04, 0x00000000 },
+	{ 0x404098,  12, 0x04, 0x00000000 },
+	{ 0x4040c8,   1, 0x04, 0xf0000087 },
+	{ 0x4040d0,   6, 0x04, 0x00000000 },
+	{ 0x4040e8,   1, 0x04, 0x00001000 },
+	{ 0x4040f8,   1, 0x04, 0x00000000 },
+	{ 0x404130,   1, 0x04, 0x00000000 },
+	{ 0x404134,   1, 0x04, 0x00000000 },
+	{ 0x404138,   1, 0x04, 0x20000040 },
+	{ 0x404150,   1, 0x04, 0x0000002e },
+	{ 0x404154,   1, 0x04, 0x00000400 },
+	{ 0x404158,   1, 0x04, 0x00000200 },
+	{ 0x404164,   1, 0x04, 0x00000055 },
+	{ 0x404168,   1, 0x04, 0x00000000 },
+	{ 0x404178,   2, 0x04, 0x00000000 },
+	{ 0x404200,   8, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd9_grctx_init_unk58xx[] = {
+	{ 0x405800,   1, 0x04, 0x0f8000bf },
+	{ 0x405830,   1, 0x04, 0x02180218 },
+	{ 0x405834,   1, 0x04, 0x08000000 },
+	{ 0x405838,   1, 0x04, 0x00000000 },
+	{ 0x405854,   1, 0x04, 0x00000000 },
+	{ 0x405870,   4, 0x04, 0x00000001 },
+	{ 0x405a00,   2, 0x04, 0x00000000 },
+	{ 0x405a18,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd9_grctx_init_unk64xx[] = {
+	{ 0x4064a8,   1, 0x04, 0x00000000 },
+	{ 0x4064ac,   1, 0x04, 0x00003fff },
+	{ 0x4064b4,   3, 0x04, 0x00000000 },
+	{ 0x4064c0,   1, 0x04, 0x80140078 },
+	{ 0x4064c4,   1, 0x04, 0x0086ffff },
+	{}
+};
+
+struct nvc0_graph_init
+nvd9_grctx_init_rop[] = {
+	{ 0x408800,   1, 0x04, 0x02802a3c },
+	{ 0x408804,   1, 0x04, 0x00000040 },
+	{ 0x408808,   1, 0x04, 0x1043e005 },
+	{ 0x408900,   1, 0x04, 0x3080b801 },
+	{ 0x408904,   1, 0x04, 0x1043e005 },
+	{ 0x408908,   1, 0x04, 0x00c8102f },
+	{ 0x408980,   1, 0x04, 0x0000011d },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd9_grctx_init_gpc_0[] = {
+	{ 0x418380,   1, 0x04, 0x00000016 },
+	{ 0x418400,   1, 0x04, 0x38004e00 },
+	{ 0x418404,   1, 0x04, 0x71e0ffff },
+	{ 0x41840c,   1, 0x04, 0x00001008 },
+	{ 0x418410,   1, 0x04, 0x0fff0fff },
+	{ 0x418414,   1, 0x04, 0x02200fff },
+	{ 0x418450,   6, 0x04, 0x00000000 },
+	{ 0x418468,   1, 0x04, 0x00000001 },
+	{ 0x41846c,   2, 0x04, 0x00000000 },
+	{ 0x418600,   1, 0x04, 0x0000001f },
+	{ 0x418684,   1, 0x04, 0x0000000f },
+	{ 0x418700,   1, 0x04, 0x00000002 },
+	{ 0x418704,   1, 0x04, 0x00000080 },
+	{ 0x418708,   3, 0x04, 0x00000000 },
+	{ 0x418800,   1, 0x04, 0x7006860a },
+	{ 0x418808,   3, 0x04, 0x00000000 },
+	{ 0x418828,   1, 0x04, 0x00008442 },
+	{ 0x418830,   1, 0x04, 0x10000001 },
+	{ 0x4188d8,   1, 0x04, 0x00000008 },
+	{ 0x4188e0,   1, 0x04, 0x01000000 },
+	{ 0x4188e8,   5, 0x04, 0x00000000 },
+	{ 0x4188fc,   1, 0x04, 0x20100008 },
+	{ 0x41891c,   1, 0x04, 0x00ff00ff },
+	{ 0x418924,   1, 0x04, 0x00000000 },
+	{ 0x418928,   1, 0x04, 0x00ffff00 },
+	{ 0x41892c,   1, 0x04, 0x0000ff00 },
+	{ 0x418b00,   1, 0x04, 0x00000006 },
+	{ 0x418b08,   1, 0x04, 0x0a418820 },
+	{ 0x418b0c,   1, 0x04, 0x062080e6 },
+	{ 0x418b10,   1, 0x04, 0x020398a4 },
+	{ 0x418b14,   1, 0x04, 0x0e629062 },
+	{ 0x418b18,   1, 0x04, 0x0a418820 },
+	{ 0x418b1c,   1, 0x04, 0x000000e6 },
+	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{ 0x418c08,   1, 0x04, 0x00000001 },
+	{ 0x418c10,   8, 0x04, 0x00000000 },
+	{ 0x418c6c,   1, 0x04, 0x00000001 },
+	{ 0x418c80,   1, 0x04, 0x20200004 },
+	{ 0x418c8c,   1, 0x04, 0x00000001 },
+	{ 0x419000,   1, 0x04, 0x00000780 },
+	{ 0x419004,   2, 0x04, 0x00000000 },
+	{ 0x419014,   1, 0x04, 0x00000004 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd9_grctx_init_tpc[] = {
+	{ 0x419818,   1, 0x04, 0x00000000 },
+	{ 0x41983c,   1, 0x04, 0x00038bc7 },
+	{ 0x419848,   1, 0x04, 0x00000000 },
+	{ 0x419864,   1, 0x04, 0x00000129 },
+	{ 0x419888,   1, 0x04, 0x00000000 },
+	{ 0x419a00,   1, 0x04, 0x000001f0 },
+	{ 0x419a04,   1, 0x04, 0x00000001 },
+	{ 0x419a08,   1, 0x04, 0x00000023 },
+	{ 0x419a0c,   1, 0x04, 0x00020000 },
+	{ 0x419a10,   1, 0x04, 0x00000000 },
+	{ 0x419a14,   1, 0x04, 0x00000200 },
+	{ 0x419a1c,   1, 0x04, 0x00000000 },
+	{ 0x419a20,   1, 0x04, 0x00000800 },
+	{ 0x419ac4,   1, 0x04, 0x0017f440 },
+	{ 0x419b00,   1, 0x04, 0x0a418820 },
+	{ 0x419b04,   1, 0x04, 0x062080e6 },
+	{ 0x419b08,   1, 0x04, 0x020398a4 },
+	{ 0x419b0c,   1, 0x04, 0x0e629062 },
+	{ 0x419b10,   1, 0x04, 0x0a418820 },
+	{ 0x419b14,   1, 0x04, 0x000000e6 },
+	{ 0x419bd0,   1, 0x04, 0x00900103 },
+	{ 0x419be0,   1, 0x04, 0x00400001 },
+	{ 0x419be4,   1, 0x04, 0x00000000 },
+	{ 0x419c00,   1, 0x04, 0x0000000a },
+	{ 0x419c04,   1, 0x04, 0x00000006 },
+	{ 0x419c08,   1, 0x04, 0x00000002 },
+	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{ 0x419c24,   1, 0x04, 0x00084210 },
+	{ 0x419c28,   1, 0x04, 0x3cf3cf3c },
+	{ 0x419cb0,   1, 0x04, 0x00020048 },
+	{ 0x419ce8,   1, 0x04, 0x00000000 },
+	{ 0x419cf4,   1, 0x04, 0x00000183 },
+	{ 0x419d20,   1, 0x04, 0x12180000 },
+	{ 0x419d24,   1, 0x04, 0x00001fff },
+	{ 0x419d44,   1, 0x04, 0x02180218 },
+	{ 0x419e04,   3, 0x04, 0x00000000 },
+	{ 0x419e10,   1, 0x04, 0x00000002 },
+	{ 0x419e44,   1, 0x04, 0x001beff2 },
+	{ 0x419e48,   1, 0x04, 0x00000000 },
+	{ 0x419e4c,   1, 0x04, 0x0000000f },
+	{ 0x419e50,  17, 0x04, 0x00000000 },
+	{ 0x419e98,   1, 0x04, 0x00000000 },
+	{ 0x419ee0,   1, 0x04, 0x00010110 },
+	{ 0x419f30,  11, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init *
+nvd9_grctx_init_hub[] = {
+	nvc0_grctx_init_base,
+	nvd9_grctx_init_unk40xx,
+	nvc0_grctx_init_unk44xx,
+	nvc0_grctx_init_unk46xx,
+	nvc0_grctx_init_unk47xx,
+	nvd9_grctx_init_unk58xx,
+	nvc0_grctx_init_unk60xx,
+	nvd9_grctx_init_unk64xx,
+	nvc0_grctx_init_unk78xx,
+	nvc0_grctx_init_unk80xx,
+	nvd9_grctx_init_rop,
+};
+
+struct nvc0_graph_init *
+nvd9_grctx_init_gpc[] = {
+	nvd9_grctx_init_gpc_0,
+	nvc0_grctx_init_gpc_1,
+	nvd9_grctx_init_tpc,
+	NULL
+};
+
+struct nvc0_graph_init
+nvd9_grctx_init_mthd_magic[] = {
+	{ 0x3410, 1, 0x04, 0x80002006 },
+	{}
+};
+
+struct nvc0_graph_mthd
+nvd9_grctx_init_mthd[] = {
+	{ 0x9097, nvc1_grctx_init_9097, },
+	{ 0x9197, nvc8_grctx_init_9197, },
+	{ 0x9297, nvc8_grctx_init_9297, },
+	{ 0x902d, nvc0_grctx_init_902d, },
+	{ 0x9039, nvc0_grctx_init_9039, },
+	{ 0x90c0, nvd9_grctx_init_90c0, },
+	{ 0x902d, nvd9_grctx_init_mthd_magic, },
+	{}
+};
+
+struct nouveau_oclass *
+nvd9_grctx_oclass = &(struct nvc0_grctx_oclass) {
+	.base.handle = NV_ENGCTX(GR, 0xd9),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_context_ctor,
+		.dtor = nvc0_graph_context_dtor,
+		.init = _nouveau_graph_context_init,
+		.fini = _nouveau_graph_context_fini,
+		.rd32 = _nouveau_graph_context_rd32,
+		.wr32 = _nouveau_graph_context_wr32,
+	},
+	.main = nvc0_grctx_generate_main,
+	.mods = nvc1_grctx_generate_mods,
+	.unkn = nvc1_grctx_generate_unkn,
+	.hub  = nvd9_grctx_init_hub,
+	.gpc  = nvd9_grctx_init_gpc,
+	.icmd = nvd9_grctx_init_icmd,
+	.mthd = nvd9_grctx_init_mthd,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2793 +0,0 @@
-/*
- * Copyright 2010 Red Hat Inc.
- *
- * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "nvc0.h"
-
-static void
-nve0_grctx_generate_icmd(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x400208, 0x80000000);
-	nv_icmd(priv, 0x001000, 0x00000004);
-	nv_icmd(priv, 0x000039, 0x00000000);
-	nv_icmd(priv, 0x00003a, 0x00000000);
-	nv_icmd(priv, 0x00003b, 0x00000000);
-	nv_icmd(priv, 0x0000a9, 0x0000ffff);
-	nv_icmd(priv, 0x000038, 0x0fac6881);
-	nv_icmd(priv, 0x00003d, 0x00000001);
-	nv_icmd(priv, 0x0000e8, 0x00000400);
-	nv_icmd(priv, 0x0000e9, 0x00000400);
-	nv_icmd(priv, 0x0000ea, 0x00000400);
-	nv_icmd(priv, 0x0000eb, 0x00000400);
-	nv_icmd(priv, 0x0000ec, 0x00000400);
-	nv_icmd(priv, 0x0000ed, 0x00000400);
-	nv_icmd(priv, 0x0000ee, 0x00000400);
-	nv_icmd(priv, 0x0000ef, 0x00000400);
-	nv_icmd(priv, 0x000078, 0x00000300);
-	nv_icmd(priv, 0x000079, 0x00000300);
-	nv_icmd(priv, 0x00007a, 0x00000300);
-	nv_icmd(priv, 0x00007b, 0x00000300);
-	nv_icmd(priv, 0x00007c, 0x00000300);
-	nv_icmd(priv, 0x00007d, 0x00000300);
-	nv_icmd(priv, 0x00007e, 0x00000300);
-	nv_icmd(priv, 0x00007f, 0x00000300);
-	nv_icmd(priv, 0x000050, 0x00000011);
-	nv_icmd(priv, 0x000058, 0x00000008);
-	nv_icmd(priv, 0x000059, 0x00000008);
-	nv_icmd(priv, 0x00005a, 0x00000008);
-	nv_icmd(priv, 0x00005b, 0x00000008);
-	nv_icmd(priv, 0x00005c, 0x00000008);
-	nv_icmd(priv, 0x00005d, 0x00000008);
-	nv_icmd(priv, 0x00005e, 0x00000008);
-	nv_icmd(priv, 0x00005f, 0x00000008);
-	nv_icmd(priv, 0x000208, 0x00000001);
-	nv_icmd(priv, 0x000209, 0x00000001);
-	nv_icmd(priv, 0x00020a, 0x00000001);
-	nv_icmd(priv, 0x00020b, 0x00000001);
-	nv_icmd(priv, 0x00020c, 0x00000001);
-	nv_icmd(priv, 0x00020d, 0x00000001);
-	nv_icmd(priv, 0x00020e, 0x00000001);
-	nv_icmd(priv, 0x00020f, 0x00000001);
-	nv_icmd(priv, 0x000081, 0x00000001);
-	nv_icmd(priv, 0x000085, 0x00000004);
-	nv_icmd(priv, 0x000088, 0x00000400);
-	nv_icmd(priv, 0x000090, 0x00000300);
-	nv_icmd(priv, 0x000098, 0x00001001);
-	nv_icmd(priv, 0x0000e3, 0x00000001);
-	nv_icmd(priv, 0x0000da, 0x00000001);
-	nv_icmd(priv, 0x0000f8, 0x00000003);
-	nv_icmd(priv, 0x0000fa, 0x00000001);
-	nv_icmd(priv, 0x00009f, 0x0000ffff);
-	nv_icmd(priv, 0x0000a0, 0x0000ffff);
-	nv_icmd(priv, 0x0000a1, 0x0000ffff);
-	nv_icmd(priv, 0x0000a2, 0x0000ffff);
-	nv_icmd(priv, 0x0000b1, 0x00000001);
-	nv_icmd(priv, 0x0000ad, 0x0000013e);
-	nv_icmd(priv, 0x0000e1, 0x00000010);
-	nv_icmd(priv, 0x000290, 0x00000000);
-	nv_icmd(priv, 0x000291, 0x00000000);
-	nv_icmd(priv, 0x000292, 0x00000000);
-	nv_icmd(priv, 0x000293, 0x00000000);
-	nv_icmd(priv, 0x000294, 0x00000000);
-	nv_icmd(priv, 0x000295, 0x00000000);
-	nv_icmd(priv, 0x000296, 0x00000000);
-	nv_icmd(priv, 0x000297, 0x00000000);
-	nv_icmd(priv, 0x000298, 0x00000000);
-	nv_icmd(priv, 0x000299, 0x00000000);
-	nv_icmd(priv, 0x00029a, 0x00000000);
-	nv_icmd(priv, 0x00029b, 0x00000000);
-	nv_icmd(priv, 0x00029c, 0x00000000);
-	nv_icmd(priv, 0x00029d, 0x00000000);
-	nv_icmd(priv, 0x00029e, 0x00000000);
-	nv_icmd(priv, 0x00029f, 0x00000000);
-	nv_icmd(priv, 0x0003b0, 0x00000000);
-	nv_icmd(priv, 0x0003b1, 0x00000000);
-	nv_icmd(priv, 0x0003b2, 0x00000000);
-	nv_icmd(priv, 0x0003b3, 0x00000000);
-	nv_icmd(priv, 0x0003b4, 0x00000000);
-	nv_icmd(priv, 0x0003b5, 0x00000000);
-	nv_icmd(priv, 0x0003b6, 0x00000000);
-	nv_icmd(priv, 0x0003b7, 0x00000000);
-	nv_icmd(priv, 0x0003b8, 0x00000000);
-	nv_icmd(priv, 0x0003b9, 0x00000000);
-	nv_icmd(priv, 0x0003ba, 0x00000000);
-	nv_icmd(priv, 0x0003bb, 0x00000000);
-	nv_icmd(priv, 0x0003bc, 0x00000000);
-	nv_icmd(priv, 0x0003bd, 0x00000000);
-	nv_icmd(priv, 0x0003be, 0x00000000);
-	nv_icmd(priv, 0x0003bf, 0x00000000);
-	nv_icmd(priv, 0x0002a0, 0x00000000);
-	nv_icmd(priv, 0x0002a1, 0x00000000);
-	nv_icmd(priv, 0x0002a2, 0x00000000);
-	nv_icmd(priv, 0x0002a3, 0x00000000);
-	nv_icmd(priv, 0x0002a4, 0x00000000);
-	nv_icmd(priv, 0x0002a5, 0x00000000);
-	nv_icmd(priv, 0x0002a6, 0x00000000);
-	nv_icmd(priv, 0x0002a7, 0x00000000);
-	nv_icmd(priv, 0x0002a8, 0x00000000);
-	nv_icmd(priv, 0x0002a9, 0x00000000);
-	nv_icmd(priv, 0x0002aa, 0x00000000);
-	nv_icmd(priv, 0x0002ab, 0x00000000);
-	nv_icmd(priv, 0x0002ac, 0x00000000);
-	nv_icmd(priv, 0x0002ad, 0x00000000);
-	nv_icmd(priv, 0x0002ae, 0x00000000);
-	nv_icmd(priv, 0x0002af, 0x00000000);
-	nv_icmd(priv, 0x000420, 0x00000000);
-	nv_icmd(priv, 0x000421, 0x00000000);
-	nv_icmd(priv, 0x000422, 0x00000000);
-	nv_icmd(priv, 0x000423, 0x00000000);
-	nv_icmd(priv, 0x000424, 0x00000000);
-	nv_icmd(priv, 0x000425, 0x00000000);
-	nv_icmd(priv, 0x000426, 0x00000000);
-	nv_icmd(priv, 0x000427, 0x00000000);
-	nv_icmd(priv, 0x000428, 0x00000000);
-	nv_icmd(priv, 0x000429, 0x00000000);
-	nv_icmd(priv, 0x00042a, 0x00000000);
-	nv_icmd(priv, 0x00042b, 0x00000000);
-	nv_icmd(priv, 0x00042c, 0x00000000);
-	nv_icmd(priv, 0x00042d, 0x00000000);
-	nv_icmd(priv, 0x00042e, 0x00000000);
-	nv_icmd(priv, 0x00042f, 0x00000000);
-	nv_icmd(priv, 0x0002b0, 0x00000000);
-	nv_icmd(priv, 0x0002b1, 0x00000000);
-	nv_icmd(priv, 0x0002b2, 0x00000000);
-	nv_icmd(priv, 0x0002b3, 0x00000000);
-	nv_icmd(priv, 0x0002b4, 0x00000000);
-	nv_icmd(priv, 0x0002b5, 0x00000000);
-	nv_icmd(priv, 0x0002b6, 0x00000000);
-	nv_icmd(priv, 0x0002b7, 0x00000000);
-	nv_icmd(priv, 0x0002b8, 0x00000000);
-	nv_icmd(priv, 0x0002b9, 0x00000000);
-	nv_icmd(priv, 0x0002ba, 0x00000000);
-	nv_icmd(priv, 0x0002bb, 0x00000000);
-	nv_icmd(priv, 0x0002bc, 0x00000000);
-	nv_icmd(priv, 0x0002bd, 0x00000000);
-	nv_icmd(priv, 0x0002be, 0x00000000);
-	nv_icmd(priv, 0x0002bf, 0x00000000);
-	nv_icmd(priv, 0x000430, 0x00000000);
-	nv_icmd(priv, 0x000431, 0x00000000);
-	nv_icmd(priv, 0x000432, 0x00000000);
-	nv_icmd(priv, 0x000433, 0x00000000);
-	nv_icmd(priv, 0x000434, 0x00000000);
-	nv_icmd(priv, 0x000435, 0x00000000);
-	nv_icmd(priv, 0x000436, 0x00000000);
-	nv_icmd(priv, 0x000437, 0x00000000);
-	nv_icmd(priv, 0x000438, 0x00000000);
-	nv_icmd(priv, 0x000439, 0x00000000);
-	nv_icmd(priv, 0x00043a, 0x00000000);
-	nv_icmd(priv, 0x00043b, 0x00000000);
-	nv_icmd(priv, 0x00043c, 0x00000000);
-	nv_icmd(priv, 0x00043d, 0x00000000);
-	nv_icmd(priv, 0x00043e, 0x00000000);
-	nv_icmd(priv, 0x00043f, 0x00000000);
-	nv_icmd(priv, 0x0002c0, 0x00000000);
-	nv_icmd(priv, 0x0002c1, 0x00000000);
-	nv_icmd(priv, 0x0002c2, 0x00000000);
-	nv_icmd(priv, 0x0002c3, 0x00000000);
-	nv_icmd(priv, 0x0002c4, 0x00000000);
-	nv_icmd(priv, 0x0002c5, 0x00000000);
-	nv_icmd(priv, 0x0002c6, 0x00000000);
-	nv_icmd(priv, 0x0002c7, 0x00000000);
-	nv_icmd(priv, 0x0002c8, 0x00000000);
-	nv_icmd(priv, 0x0002c9, 0x00000000);
-	nv_icmd(priv, 0x0002ca, 0x00000000);
-	nv_icmd(priv, 0x0002cb, 0x00000000);
-	nv_icmd(priv, 0x0002cc, 0x00000000);
-	nv_icmd(priv, 0x0002cd, 0x00000000);
-	nv_icmd(priv, 0x0002ce, 0x00000000);
-	nv_icmd(priv, 0x0002cf, 0x00000000);
-	nv_icmd(priv, 0x0004d0, 0x00000000);
-	nv_icmd(priv, 0x0004d1, 0x00000000);
-	nv_icmd(priv, 0x0004d2, 0x00000000);
-	nv_icmd(priv, 0x0004d3, 0x00000000);
-	nv_icmd(priv, 0x0004d4, 0x00000000);
-	nv_icmd(priv, 0x0004d5, 0x00000000);
-	nv_icmd(priv, 0x0004d6, 0x00000000);
-	nv_icmd(priv, 0x0004d7, 0x00000000);
-	nv_icmd(priv, 0x0004d8, 0x00000000);
-	nv_icmd(priv, 0x0004d9, 0x00000000);
-	nv_icmd(priv, 0x0004da, 0x00000000);
-	nv_icmd(priv, 0x0004db, 0x00000000);
-	nv_icmd(priv, 0x0004dc, 0x00000000);
-	nv_icmd(priv, 0x0004dd, 0x00000000);
-	nv_icmd(priv, 0x0004de, 0x00000000);
-	nv_icmd(priv, 0x0004df, 0x00000000);
-	nv_icmd(priv, 0x000720, 0x00000000);
-	nv_icmd(priv, 0x000721, 0x00000000);
-	nv_icmd(priv, 0x000722, 0x00000000);
-	nv_icmd(priv, 0x000723, 0x00000000);
-	nv_icmd(priv, 0x000724, 0x00000000);
-	nv_icmd(priv, 0x000725, 0x00000000);
-	nv_icmd(priv, 0x000726, 0x00000000);
-	nv_icmd(priv, 0x000727, 0x00000000);
-	nv_icmd(priv, 0x000728, 0x00000000);
-	nv_icmd(priv, 0x000729, 0x00000000);
-	nv_icmd(priv, 0x00072a, 0x00000000);
-	nv_icmd(priv, 0x00072b, 0x00000000);
-	nv_icmd(priv, 0x00072c, 0x00000000);
-	nv_icmd(priv, 0x00072d, 0x00000000);
-	nv_icmd(priv, 0x00072e, 0x00000000);
-	nv_icmd(priv, 0x00072f, 0x00000000);
-	nv_icmd(priv, 0x0008c0, 0x00000000);
-	nv_icmd(priv, 0x0008c1, 0x00000000);
-	nv_icmd(priv, 0x0008c2, 0x00000000);
-	nv_icmd(priv, 0x0008c3, 0x00000000);
-	nv_icmd(priv, 0x0008c4, 0x00000000);
-	nv_icmd(priv, 0x0008c5, 0x00000000);
-	nv_icmd(priv, 0x0008c6, 0x00000000);
-	nv_icmd(priv, 0x0008c7, 0x00000000);
-	nv_icmd(priv, 0x0008c8, 0x00000000);
-	nv_icmd(priv, 0x0008c9, 0x00000000);
-	nv_icmd(priv, 0x0008ca, 0x00000000);
-	nv_icmd(priv, 0x0008cb, 0x00000000);
-	nv_icmd(priv, 0x0008cc, 0x00000000);
-	nv_icmd(priv, 0x0008cd, 0x00000000);
-	nv_icmd(priv, 0x0008ce, 0x00000000);
-	nv_icmd(priv, 0x0008cf, 0x00000000);
-	nv_icmd(priv, 0x000890, 0x00000000);
-	nv_icmd(priv, 0x000891, 0x00000000);
-	nv_icmd(priv, 0x000892, 0x00000000);
-	nv_icmd(priv, 0x000893, 0x00000000);
-	nv_icmd(priv, 0x000894, 0x00000000);
-	nv_icmd(priv, 0x000895, 0x00000000);
-	nv_icmd(priv, 0x000896, 0x00000000);
-	nv_icmd(priv, 0x000897, 0x00000000);
-	nv_icmd(priv, 0x000898, 0x00000000);
-	nv_icmd(priv, 0x000899, 0x00000000);
-	nv_icmd(priv, 0x00089a, 0x00000000);
-	nv_icmd(priv, 0x00089b, 0x00000000);
-	nv_icmd(priv, 0x00089c, 0x00000000);
-	nv_icmd(priv, 0x00089d, 0x00000000);
-	nv_icmd(priv, 0x00089e, 0x00000000);
-	nv_icmd(priv, 0x00089f, 0x00000000);
-	nv_icmd(priv, 0x0008e0, 0x00000000);
-	nv_icmd(priv, 0x0008e1, 0x00000000);
-	nv_icmd(priv, 0x0008e2, 0x00000000);
-	nv_icmd(priv, 0x0008e3, 0x00000000);
-	nv_icmd(priv, 0x0008e4, 0x00000000);
-	nv_icmd(priv, 0x0008e5, 0x00000000);
-	nv_icmd(priv, 0x0008e6, 0x00000000);
-	nv_icmd(priv, 0x0008e7, 0x00000000);
-	nv_icmd(priv, 0x0008e8, 0x00000000);
-	nv_icmd(priv, 0x0008e9, 0x00000000);
-	nv_icmd(priv, 0x0008ea, 0x00000000);
-	nv_icmd(priv, 0x0008eb, 0x00000000);
-	nv_icmd(priv, 0x0008ec, 0x00000000);
-	nv_icmd(priv, 0x0008ed, 0x00000000);
-	nv_icmd(priv, 0x0008ee, 0x00000000);
-	nv_icmd(priv, 0x0008ef, 0x00000000);
-	nv_icmd(priv, 0x0008a0, 0x00000000);
-	nv_icmd(priv, 0x0008a1, 0x00000000);
-	nv_icmd(priv, 0x0008a2, 0x00000000);
-	nv_icmd(priv, 0x0008a3, 0x00000000);
-	nv_icmd(priv, 0x0008a4, 0x00000000);
-	nv_icmd(priv, 0x0008a5, 0x00000000);
-	nv_icmd(priv, 0x0008a6, 0x00000000);
-	nv_icmd(priv, 0x0008a7, 0x00000000);
-	nv_icmd(priv, 0x0008a8, 0x00000000);
-	nv_icmd(priv, 0x0008a9, 0x00000000);
-	nv_icmd(priv, 0x0008aa, 0x00000000);
-	nv_icmd(priv, 0x0008ab, 0x00000000);
-	nv_icmd(priv, 0x0008ac, 0x00000000);
-	nv_icmd(priv, 0x0008ad, 0x00000000);
-	nv_icmd(priv, 0x0008ae, 0x00000000);
-	nv_icmd(priv, 0x0008af, 0x00000000);
-	nv_icmd(priv, 0x0008f0, 0x00000000);
-	nv_icmd(priv, 0x0008f1, 0x00000000);
-	nv_icmd(priv, 0x0008f2, 0x00000000);
-	nv_icmd(priv, 0x0008f3, 0x00000000);
-	nv_icmd(priv, 0x0008f4, 0x00000000);
-	nv_icmd(priv, 0x0008f5, 0x00000000);
-	nv_icmd(priv, 0x0008f6, 0x00000000);
-	nv_icmd(priv, 0x0008f7, 0x00000000);
-	nv_icmd(priv, 0x0008f8, 0x00000000);
-	nv_icmd(priv, 0x0008f9, 0x00000000);
-	nv_icmd(priv, 0x0008fa, 0x00000000);
-	nv_icmd(priv, 0x0008fb, 0x00000000);
-	nv_icmd(priv, 0x0008fc, 0x00000000);
-	nv_icmd(priv, 0x0008fd, 0x00000000);
-	nv_icmd(priv, 0x0008fe, 0x00000000);
-	nv_icmd(priv, 0x0008ff, 0x00000000);
-	nv_icmd(priv, 0x00094c, 0x000000ff);
-	nv_icmd(priv, 0x00094d, 0xffffffff);
-	nv_icmd(priv, 0x00094e, 0x00000002);
-	nv_icmd(priv, 0x0002ec, 0x00000001);
-	nv_icmd(priv, 0x000303, 0x00000001);
-	nv_icmd(priv, 0x0002e6, 0x00000001);
-	nv_icmd(priv, 0x000466, 0x00000052);
-	nv_icmd(priv, 0x000301, 0x3f800000);
-	nv_icmd(priv, 0x000304, 0x30201000);
-	nv_icmd(priv, 0x000305, 0x70605040);
-	nv_icmd(priv, 0x000306, 0xb8a89888);
-	nv_icmd(priv, 0x000307, 0xf8e8d8c8);
-	nv_icmd(priv, 0x00030a, 0x00ffff00);
-	nv_icmd(priv, 0x00030b, 0x0000001a);
-	nv_icmd(priv, 0x00030c, 0x00000001);
-	nv_icmd(priv, 0x000318, 0x00000001);
-	nv_icmd(priv, 0x000340, 0x00000000);
-	nv_icmd(priv, 0x000375, 0x00000001);
-	nv_icmd(priv, 0x00037d, 0x00000006);
-	nv_icmd(priv, 0x0003a0, 0x00000002);
-	nv_icmd(priv, 0x0003aa, 0x00000001);
-	nv_icmd(priv, 0x0003a9, 0x00000001);
-	nv_icmd(priv, 0x000380, 0x00000001);
-	nv_icmd(priv, 0x000383, 0x00000011);
-	nv_icmd(priv, 0x000360, 0x00000040);
-	nv_icmd(priv, 0x000366, 0x00000000);
-	nv_icmd(priv, 0x000367, 0x00000000);
-	nv_icmd(priv, 0x000368, 0x00000fff);
-	nv_icmd(priv, 0x000370, 0x00000000);
-	nv_icmd(priv, 0x000371, 0x00000000);
-	nv_icmd(priv, 0x000372, 0x000fffff);
-	nv_icmd(priv, 0x00037a, 0x00000012);
-	nv_icmd(priv, 0x000619, 0x00000003);
-	nv_icmd(priv, 0x000811, 0x00000003);
-	nv_icmd(priv, 0x000812, 0x00000004);
-	nv_icmd(priv, 0x000813, 0x00000006);
-	nv_icmd(priv, 0x000814, 0x00000008);
-	nv_icmd(priv, 0x000815, 0x0000000b);
-	nv_icmd(priv, 0x000800, 0x00000001);
-	nv_icmd(priv, 0x000801, 0x00000001);
-	nv_icmd(priv, 0x000802, 0x00000001);
-	nv_icmd(priv, 0x000803, 0x00000001);
-	nv_icmd(priv, 0x000804, 0x00000001);
-	nv_icmd(priv, 0x000805, 0x00000001);
-	nv_icmd(priv, 0x000632, 0x00000001);
-	nv_icmd(priv, 0x000633, 0x00000002);
-	nv_icmd(priv, 0x000634, 0x00000003);
-	nv_icmd(priv, 0x000635, 0x00000004);
-	nv_icmd(priv, 0x000654, 0x3f800000);
-	nv_icmd(priv, 0x000657, 0x3f800000);
-	nv_icmd(priv, 0x000655, 0x3f800000);
-	nv_icmd(priv, 0x000656, 0x3f800000);
-	nv_icmd(priv, 0x0006cd, 0x3f800000);
-	nv_icmd(priv, 0x0007f5, 0x3f800000);
-	nv_icmd(priv, 0x0007dc, 0x39291909);
-	nv_icmd(priv, 0x0007dd, 0x79695949);
-	nv_icmd(priv, 0x0007de, 0xb9a99989);
-	nv_icmd(priv, 0x0007df, 0xf9e9d9c9);
-	nv_icmd(priv, 0x0007e8, 0x00003210);
-	nv_icmd(priv, 0x0007e9, 0x00007654);
-	nv_icmd(priv, 0x0007ea, 0x00000098);
-	nv_icmd(priv, 0x0007ec, 0x39291909);
-	nv_icmd(priv, 0x0007ed, 0x79695949);
-	nv_icmd(priv, 0x0007ee, 0xb9a99989);
-	nv_icmd(priv, 0x0007ef, 0xf9e9d9c9);
-	nv_icmd(priv, 0x0007f0, 0x00003210);
-	nv_icmd(priv, 0x0007f1, 0x00007654);
-	nv_icmd(priv, 0x0007f2, 0x00000098);
-	nv_icmd(priv, 0x0005a5, 0x00000001);
-	nv_icmd(priv, 0x000980, 0x00000000);
-	nv_icmd(priv, 0x000981, 0x00000000);
-	nv_icmd(priv, 0x000982, 0x00000000);
-	nv_icmd(priv, 0x000983, 0x00000000);
-	nv_icmd(priv, 0x000984, 0x00000000);
-	nv_icmd(priv, 0x000985, 0x00000000);
-	nv_icmd(priv, 0x000986, 0x00000000);
-	nv_icmd(priv, 0x000987, 0x00000000);
-	nv_icmd(priv, 0x000988, 0x00000000);
-	nv_icmd(priv, 0x000989, 0x00000000);
-	nv_icmd(priv, 0x00098a, 0x00000000);
-	nv_icmd(priv, 0x00098b, 0x00000000);
-	nv_icmd(priv, 0x00098c, 0x00000000);
-	nv_icmd(priv, 0x00098d, 0x00000000);
-	nv_icmd(priv, 0x00098e, 0x00000000);
-	nv_icmd(priv, 0x00098f, 0x00000000);
-	nv_icmd(priv, 0x000990, 0x00000000);
-	nv_icmd(priv, 0x000991, 0x00000000);
-	nv_icmd(priv, 0x000992, 0x00000000);
-	nv_icmd(priv, 0x000993, 0x00000000);
-	nv_icmd(priv, 0x000994, 0x00000000);
-	nv_icmd(priv, 0x000995, 0x00000000);
-	nv_icmd(priv, 0x000996, 0x00000000);
-	nv_icmd(priv, 0x000997, 0x00000000);
-	nv_icmd(priv, 0x000998, 0x00000000);
-	nv_icmd(priv, 0x000999, 0x00000000);
-	nv_icmd(priv, 0x00099a, 0x00000000);
-	nv_icmd(priv, 0x00099b, 0x00000000);
-	nv_icmd(priv, 0x00099c, 0x00000000);
-	nv_icmd(priv, 0x00099d, 0x00000000);
-	nv_icmd(priv, 0x00099e, 0x00000000);
-	nv_icmd(priv, 0x00099f, 0x00000000);
-	nv_icmd(priv, 0x0009a0, 0x00000000);
-	nv_icmd(priv, 0x0009a1, 0x00000000);
-	nv_icmd(priv, 0x0009a2, 0x00000000);
-	nv_icmd(priv, 0x0009a3, 0x00000000);
-	nv_icmd(priv, 0x0009a4, 0x00000000);
-	nv_icmd(priv, 0x0009a5, 0x00000000);
-	nv_icmd(priv, 0x0009a6, 0x00000000);
-	nv_icmd(priv, 0x0009a7, 0x00000000);
-	nv_icmd(priv, 0x0009a8, 0x00000000);
-	nv_icmd(priv, 0x0009a9, 0x00000000);
-	nv_icmd(priv, 0x0009aa, 0x00000000);
-	nv_icmd(priv, 0x0009ab, 0x00000000);
-	nv_icmd(priv, 0x0009ac, 0x00000000);
-	nv_icmd(priv, 0x0009ad, 0x00000000);
-	nv_icmd(priv, 0x0009ae, 0x00000000);
-	nv_icmd(priv, 0x0009af, 0x00000000);
-	nv_icmd(priv, 0x0009b0, 0x00000000);
-	nv_icmd(priv, 0x0009b1, 0x00000000);
-	nv_icmd(priv, 0x0009b2, 0x00000000);
-	nv_icmd(priv, 0x0009b3, 0x00000000);
-	nv_icmd(priv, 0x0009b4, 0x00000000);
-	nv_icmd(priv, 0x0009b5, 0x00000000);
-	nv_icmd(priv, 0x0009b6, 0x00000000);
-	nv_icmd(priv, 0x0009b7, 0x00000000);
-	nv_icmd(priv, 0x0009b8, 0x00000000);
-	nv_icmd(priv, 0x0009b9, 0x00000000);
-	nv_icmd(priv, 0x0009ba, 0x00000000);
-	nv_icmd(priv, 0x0009bb, 0x00000000);
-	nv_icmd(priv, 0x0009bc, 0x00000000);
-	nv_icmd(priv, 0x0009bd, 0x00000000);
-	nv_icmd(priv, 0x0009be, 0x00000000);
-	nv_icmd(priv, 0x0009bf, 0x00000000);
-	nv_icmd(priv, 0x0009c0, 0x00000000);
-	nv_icmd(priv, 0x0009c1, 0x00000000);
-	nv_icmd(priv, 0x0009c2, 0x00000000);
-	nv_icmd(priv, 0x0009c3, 0x00000000);
-	nv_icmd(priv, 0x0009c4, 0x00000000);
-	nv_icmd(priv, 0x0009c5, 0x00000000);
-	nv_icmd(priv, 0x0009c6, 0x00000000);
-	nv_icmd(priv, 0x0009c7, 0x00000000);
-	nv_icmd(priv, 0x0009c8, 0x00000000);
-	nv_icmd(priv, 0x0009c9, 0x00000000);
-	nv_icmd(priv, 0x0009ca, 0x00000000);
-	nv_icmd(priv, 0x0009cb, 0x00000000);
-	nv_icmd(priv, 0x0009cc, 0x00000000);
-	nv_icmd(priv, 0x0009cd, 0x00000000);
-	nv_icmd(priv, 0x0009ce, 0x00000000);
-	nv_icmd(priv, 0x0009cf, 0x00000000);
-	nv_icmd(priv, 0x0009d0, 0x00000000);
-	nv_icmd(priv, 0x0009d1, 0x00000000);
-	nv_icmd(priv, 0x0009d2, 0x00000000);
-	nv_icmd(priv, 0x0009d3, 0x00000000);
-	nv_icmd(priv, 0x0009d4, 0x00000000);
-	nv_icmd(priv, 0x0009d5, 0x00000000);
-	nv_icmd(priv, 0x0009d6, 0x00000000);
-	nv_icmd(priv, 0x0009d7, 0x00000000);
-	nv_icmd(priv, 0x0009d8, 0x00000000);
-	nv_icmd(priv, 0x0009d9, 0x00000000);
-	nv_icmd(priv, 0x0009da, 0x00000000);
-	nv_icmd(priv, 0x0009db, 0x00000000);
-	nv_icmd(priv, 0x0009dc, 0x00000000);
-	nv_icmd(priv, 0x0009dd, 0x00000000);
-	nv_icmd(priv, 0x0009de, 0x00000000);
-	nv_icmd(priv, 0x0009df, 0x00000000);
-	nv_icmd(priv, 0x0009e0, 0x00000000);
-	nv_icmd(priv, 0x0009e1, 0x00000000);
-	nv_icmd(priv, 0x0009e2, 0x00000000);
-	nv_icmd(priv, 0x0009e3, 0x00000000);
-	nv_icmd(priv, 0x0009e4, 0x00000000);
-	nv_icmd(priv, 0x0009e5, 0x00000000);
-	nv_icmd(priv, 0x0009e6, 0x00000000);
-	nv_icmd(priv, 0x0009e7, 0x00000000);
-	nv_icmd(priv, 0x0009e8, 0x00000000);
-	nv_icmd(priv, 0x0009e9, 0x00000000);
-	nv_icmd(priv, 0x0009ea, 0x00000000);
-	nv_icmd(priv, 0x0009eb, 0x00000000);
-	nv_icmd(priv, 0x0009ec, 0x00000000);
-	nv_icmd(priv, 0x0009ed, 0x00000000);
-	nv_icmd(priv, 0x0009ee, 0x00000000);
-	nv_icmd(priv, 0x0009ef, 0x00000000);
-	nv_icmd(priv, 0x0009f0, 0x00000000);
-	nv_icmd(priv, 0x0009f1, 0x00000000);
-	nv_icmd(priv, 0x0009f2, 0x00000000);
-	nv_icmd(priv, 0x0009f3, 0x00000000);
-	nv_icmd(priv, 0x0009f4, 0x00000000);
-	nv_icmd(priv, 0x0009f5, 0x00000000);
-	nv_icmd(priv, 0x0009f6, 0x00000000);
-	nv_icmd(priv, 0x0009f7, 0x00000000);
-	nv_icmd(priv, 0x0009f8, 0x00000000);
-	nv_icmd(priv, 0x0009f9, 0x00000000);
-	nv_icmd(priv, 0x0009fa, 0x00000000);
-	nv_icmd(priv, 0x0009fb, 0x00000000);
-	nv_icmd(priv, 0x0009fc, 0x00000000);
-	nv_icmd(priv, 0x0009fd, 0x00000000);
-	nv_icmd(priv, 0x0009fe, 0x00000000);
-	nv_icmd(priv, 0x0009ff, 0x00000000);
-	nv_icmd(priv, 0x000468, 0x00000004);
-	nv_icmd(priv, 0x00046c, 0x00000001);
-	nv_icmd(priv, 0x000470, 0x00000000);
-	nv_icmd(priv, 0x000471, 0x00000000);
-	nv_icmd(priv, 0x000472, 0x00000000);
-	nv_icmd(priv, 0x000473, 0x00000000);
-	nv_icmd(priv, 0x000474, 0x00000000);
-	nv_icmd(priv, 0x000475, 0x00000000);
-	nv_icmd(priv, 0x000476, 0x00000000);
-	nv_icmd(priv, 0x000477, 0x00000000);
-	nv_icmd(priv, 0x000478, 0x00000000);
-	nv_icmd(priv, 0x000479, 0x00000000);
-	nv_icmd(priv, 0x00047a, 0x00000000);
-	nv_icmd(priv, 0x00047b, 0x00000000);
-	nv_icmd(priv, 0x00047c, 0x00000000);
-	nv_icmd(priv, 0x00047d, 0x00000000);
-	nv_icmd(priv, 0x00047e, 0x00000000);
-	nv_icmd(priv, 0x00047f, 0x00000000);
-	nv_icmd(priv, 0x000480, 0x00000000);
-	nv_icmd(priv, 0x000481, 0x00000000);
-	nv_icmd(priv, 0x000482, 0x00000000);
-	nv_icmd(priv, 0x000483, 0x00000000);
-	nv_icmd(priv, 0x000484, 0x00000000);
-	nv_icmd(priv, 0x000485, 0x00000000);
-	nv_icmd(priv, 0x000486, 0x00000000);
-	nv_icmd(priv, 0x000487, 0x00000000);
-	nv_icmd(priv, 0x000488, 0x00000000);
-	nv_icmd(priv, 0x000489, 0x00000000);
-	nv_icmd(priv, 0x00048a, 0x00000000);
-	nv_icmd(priv, 0x00048b, 0x00000000);
-	nv_icmd(priv, 0x00048c, 0x00000000);
-	nv_icmd(priv, 0x00048d, 0x00000000);
-	nv_icmd(priv, 0x00048e, 0x00000000);
-	nv_icmd(priv, 0x00048f, 0x00000000);
-	nv_icmd(priv, 0x000490, 0x00000000);
-	nv_icmd(priv, 0x000491, 0x00000000);
-	nv_icmd(priv, 0x000492, 0x00000000);
-	nv_icmd(priv, 0x000493, 0x00000000);
-	nv_icmd(priv, 0x000494, 0x00000000);
-	nv_icmd(priv, 0x000495, 0x00000000);
-	nv_icmd(priv, 0x000496, 0x00000000);
-	nv_icmd(priv, 0x000497, 0x00000000);
-	nv_icmd(priv, 0x000498, 0x00000000);
-	nv_icmd(priv, 0x000499, 0x00000000);
-	nv_icmd(priv, 0x00049a, 0x00000000);
-	nv_icmd(priv, 0x00049b, 0x00000000);
-	nv_icmd(priv, 0x00049c, 0x00000000);
-	nv_icmd(priv, 0x00049d, 0x00000000);
-	nv_icmd(priv, 0x00049e, 0x00000000);
-	nv_icmd(priv, 0x00049f, 0x00000000);
-	nv_icmd(priv, 0x0004a0, 0x00000000);
-	nv_icmd(priv, 0x0004a1, 0x00000000);
-	nv_icmd(priv, 0x0004a2, 0x00000000);
-	nv_icmd(priv, 0x0004a3, 0x00000000);
-	nv_icmd(priv, 0x0004a4, 0x00000000);
-	nv_icmd(priv, 0x0004a5, 0x00000000);
-	nv_icmd(priv, 0x0004a6, 0x00000000);
-	nv_icmd(priv, 0x0004a7, 0x00000000);
-	nv_icmd(priv, 0x0004a8, 0x00000000);
-	nv_icmd(priv, 0x0004a9, 0x00000000);
-	nv_icmd(priv, 0x0004aa, 0x00000000);
-	nv_icmd(priv, 0x0004ab, 0x00000000);
-	nv_icmd(priv, 0x0004ac, 0x00000000);
-	nv_icmd(priv, 0x0004ad, 0x00000000);
-	nv_icmd(priv, 0x0004ae, 0x00000000);
-	nv_icmd(priv, 0x0004af, 0x00000000);
-	nv_icmd(priv, 0x0004b0, 0x00000000);
-	nv_icmd(priv, 0x0004b1, 0x00000000);
-	nv_icmd(priv, 0x0004b2, 0x00000000);
-	nv_icmd(priv, 0x0004b3, 0x00000000);
-	nv_icmd(priv, 0x0004b4, 0x00000000);
-	nv_icmd(priv, 0x0004b5, 0x00000000);
-	nv_icmd(priv, 0x0004b6, 0x00000000);
-	nv_icmd(priv, 0x0004b7, 0x00000000);
-	nv_icmd(priv, 0x0004b8, 0x00000000);
-	nv_icmd(priv, 0x0004b9, 0x00000000);
-	nv_icmd(priv, 0x0004ba, 0x00000000);
-	nv_icmd(priv, 0x0004bb, 0x00000000);
-	nv_icmd(priv, 0x0004bc, 0x00000000);
-	nv_icmd(priv, 0x0004bd, 0x00000000);
-	nv_icmd(priv, 0x0004be, 0x00000000);
-	nv_icmd(priv, 0x0004bf, 0x00000000);
-	nv_icmd(priv, 0x0004c0, 0x00000000);
-	nv_icmd(priv, 0x0004c1, 0x00000000);
-	nv_icmd(priv, 0x0004c2, 0x00000000);
-	nv_icmd(priv, 0x0004c3, 0x00000000);
-	nv_icmd(priv, 0x0004c4, 0x00000000);
-	nv_icmd(priv, 0x0004c5, 0x00000000);
-	nv_icmd(priv, 0x0004c6, 0x00000000);
-	nv_icmd(priv, 0x0004c7, 0x00000000);
-	nv_icmd(priv, 0x0004c8, 0x00000000);
-	nv_icmd(priv, 0x0004c9, 0x00000000);
-	nv_icmd(priv, 0x0004ca, 0x00000000);
-	nv_icmd(priv, 0x0004cb, 0x00000000);
-	nv_icmd(priv, 0x0004cc, 0x00000000);
-	nv_icmd(priv, 0x0004cd, 0x00000000);
-	nv_icmd(priv, 0x0004ce, 0x00000000);
-	nv_icmd(priv, 0x0004cf, 0x00000000);
-	nv_icmd(priv, 0x000510, 0x3f800000);
-	nv_icmd(priv, 0x000511, 0x3f800000);
-	nv_icmd(priv, 0x000512, 0x3f800000);
-	nv_icmd(priv, 0x000513, 0x3f800000);
-	nv_icmd(priv, 0x000514, 0x3f800000);
-	nv_icmd(priv, 0x000515, 0x3f800000);
-	nv_icmd(priv, 0x000516, 0x3f800000);
-	nv_icmd(priv, 0x000517, 0x3f800000);
-	nv_icmd(priv, 0x000518, 0x3f800000);
-	nv_icmd(priv, 0x000519, 0x3f800000);
-	nv_icmd(priv, 0x00051a, 0x3f800000);
-	nv_icmd(priv, 0x00051b, 0x3f800000);
-	nv_icmd(priv, 0x00051c, 0x3f800000);
-	nv_icmd(priv, 0x00051d, 0x3f800000);
-	nv_icmd(priv, 0x00051e, 0x3f800000);
-	nv_icmd(priv, 0x00051f, 0x3f800000);
-	nv_icmd(priv, 0x000520, 0x000002b6);
-	nv_icmd(priv, 0x000529, 0x00000001);
-	nv_icmd(priv, 0x000530, 0xffff0000);
-	nv_icmd(priv, 0x000531, 0xffff0000);
-	nv_icmd(priv, 0x000532, 0xffff0000);
-	nv_icmd(priv, 0x000533, 0xffff0000);
-	nv_icmd(priv, 0x000534, 0xffff0000);
-	nv_icmd(priv, 0x000535, 0xffff0000);
-	nv_icmd(priv, 0x000536, 0xffff0000);
-	nv_icmd(priv, 0x000537, 0xffff0000);
-	nv_icmd(priv, 0x000538, 0xffff0000);
-	nv_icmd(priv, 0x000539, 0xffff0000);
-	nv_icmd(priv, 0x00053a, 0xffff0000);
-	nv_icmd(priv, 0x00053b, 0xffff0000);
-	nv_icmd(priv, 0x00053c, 0xffff0000);
-	nv_icmd(priv, 0x00053d, 0xffff0000);
-	nv_icmd(priv, 0x00053e, 0xffff0000);
-	nv_icmd(priv, 0x00053f, 0xffff0000);
-	nv_icmd(priv, 0x000585, 0x0000003f);
-	nv_icmd(priv, 0x000576, 0x00000003);
-	nv_icmd(priv, 0x00057b, 0x00000059);
-	nv_icmd(priv, 0x000586, 0x00000040);
-	nv_icmd(priv, 0x000582, 0x00000080);
-	nv_icmd(priv, 0x000583, 0x00000080);
-	nv_icmd(priv, 0x0005c2, 0x00000001);
-	nv_icmd(priv, 0x000638, 0x00000001);
-	nv_icmd(priv, 0x000639, 0x00000001);
-	nv_icmd(priv, 0x00063a, 0x00000002);
-	nv_icmd(priv, 0x00063b, 0x00000001);
-	nv_icmd(priv, 0x00063c, 0x00000001);
-	nv_icmd(priv, 0x00063d, 0x00000002);
-	nv_icmd(priv, 0x00063e, 0x00000001);
-	nv_icmd(priv, 0x0008b8, 0x00000001);
-	nv_icmd(priv, 0x0008b9, 0x00000001);
-	nv_icmd(priv, 0x0008ba, 0x00000001);
-	nv_icmd(priv, 0x0008bb, 0x00000001);
-	nv_icmd(priv, 0x0008bc, 0x00000001);
-	nv_icmd(priv, 0x0008bd, 0x00000001);
-	nv_icmd(priv, 0x0008be, 0x00000001);
-	nv_icmd(priv, 0x0008bf, 0x00000001);
-	nv_icmd(priv, 0x000900, 0x00000001);
-	nv_icmd(priv, 0x000901, 0x00000001);
-	nv_icmd(priv, 0x000902, 0x00000001);
-	nv_icmd(priv, 0x000903, 0x00000001);
-	nv_icmd(priv, 0x000904, 0x00000001);
-	nv_icmd(priv, 0x000905, 0x00000001);
-	nv_icmd(priv, 0x000906, 0x00000001);
-	nv_icmd(priv, 0x000907, 0x00000001);
-	nv_icmd(priv, 0x000908, 0x00000002);
-	nv_icmd(priv, 0x000909, 0x00000002);
-	nv_icmd(priv, 0x00090a, 0x00000002);
-	nv_icmd(priv, 0x00090b, 0x00000002);
-	nv_icmd(priv, 0x00090c, 0x00000002);
-	nv_icmd(priv, 0x00090d, 0x00000002);
-	nv_icmd(priv, 0x00090e, 0x00000002);
-	nv_icmd(priv, 0x00090f, 0x00000002);
-	nv_icmd(priv, 0x000910, 0x00000001);
-	nv_icmd(priv, 0x000911, 0x00000001);
-	nv_icmd(priv, 0x000912, 0x00000001);
-	nv_icmd(priv, 0x000913, 0x00000001);
-	nv_icmd(priv, 0x000914, 0x00000001);
-	nv_icmd(priv, 0x000915, 0x00000001);
-	nv_icmd(priv, 0x000916, 0x00000001);
-	nv_icmd(priv, 0x000917, 0x00000001);
-	nv_icmd(priv, 0x000918, 0x00000001);
-	nv_icmd(priv, 0x000919, 0x00000001);
-	nv_icmd(priv, 0x00091a, 0x00000001);
-	nv_icmd(priv, 0x00091b, 0x00000001);
-	nv_icmd(priv, 0x00091c, 0x00000001);
-	nv_icmd(priv, 0x00091d, 0x00000001);
-	nv_icmd(priv, 0x00091e, 0x00000001);
-	nv_icmd(priv, 0x00091f, 0x00000001);
-	nv_icmd(priv, 0x000920, 0x00000002);
-	nv_icmd(priv, 0x000921, 0x00000002);
-	nv_icmd(priv, 0x000922, 0x00000002);
-	nv_icmd(priv, 0x000923, 0x00000002);
-	nv_icmd(priv, 0x000924, 0x00000002);
-	nv_icmd(priv, 0x000925, 0x00000002);
-	nv_icmd(priv, 0x000926, 0x00000002);
-	nv_icmd(priv, 0x000927, 0x00000002);
-	nv_icmd(priv, 0x000928, 0x00000001);
-	nv_icmd(priv, 0x000929, 0x00000001);
-	nv_icmd(priv, 0x00092a, 0x00000001);
-	nv_icmd(priv, 0x00092b, 0x00000001);
-	nv_icmd(priv, 0x00092c, 0x00000001);
-	nv_icmd(priv, 0x00092d, 0x00000001);
-	nv_icmd(priv, 0x00092e, 0x00000001);
-	nv_icmd(priv, 0x00092f, 0x00000001);
-	nv_icmd(priv, 0x000648, 0x00000001);
-	nv_icmd(priv, 0x000649, 0x00000001);
-	nv_icmd(priv, 0x00064a, 0x00000001);
-	nv_icmd(priv, 0x00064b, 0x00000001);
-	nv_icmd(priv, 0x00064c, 0x00000001);
-	nv_icmd(priv, 0x00064d, 0x00000001);
-	nv_icmd(priv, 0x00064e, 0x00000001);
-	nv_icmd(priv, 0x00064f, 0x00000001);
-	nv_icmd(priv, 0x000650, 0x00000001);
-	nv_icmd(priv, 0x000658, 0x0000000f);
-	nv_icmd(priv, 0x0007ff, 0x0000000a);
-	nv_icmd(priv, 0x00066a, 0x40000000);
-	nv_icmd(priv, 0x00066b, 0x10000000);
-	nv_icmd(priv, 0x00066c, 0xffff0000);
-	nv_icmd(priv, 0x00066d, 0xffff0000);
-	nv_icmd(priv, 0x0007af, 0x00000008);
-	nv_icmd(priv, 0x0007b0, 0x00000008);
-	nv_icmd(priv, 0x0007f6, 0x00000001);
-	nv_icmd(priv, 0x0006b2, 0x00000055);
-	nv_icmd(priv, 0x0007ad, 0x00000003);
-	nv_icmd(priv, 0x000937, 0x00000001);
-	nv_icmd(priv, 0x000971, 0x00000008);
-	nv_icmd(priv, 0x000972, 0x00000040);
-	nv_icmd(priv, 0x000973, 0x0000012c);
-	nv_icmd(priv, 0x00097c, 0x00000040);
-	nv_icmd(priv, 0x000979, 0x00000003);
-	nv_icmd(priv, 0x000975, 0x00000020);
-	nv_icmd(priv, 0x000976, 0x00000001);
-	nv_icmd(priv, 0x000977, 0x00000020);
-	nv_icmd(priv, 0x000978, 0x00000001);
-	nv_icmd(priv, 0x000957, 0x00000003);
-	nv_icmd(priv, 0x00095e, 0x20164010);
-	nv_icmd(priv, 0x00095f, 0x00000020);
-	nv_icmd(priv, 0x00097d, 0x00000020);
-	nv_icmd(priv, 0x000683, 0x00000006);
-	nv_icmd(priv, 0x000685, 0x003fffff);
-	nv_icmd(priv, 0x000687, 0x003fffff);
-	nv_icmd(priv, 0x0006a0, 0x00000005);
-	nv_icmd(priv, 0x000840, 0x00400008);
-	nv_icmd(priv, 0x000841, 0x08000080);
-	nv_icmd(priv, 0x000842, 0x00400008);
-	nv_icmd(priv, 0x000843, 0x08000080);
-	nv_icmd(priv, 0x000818, 0x00000000);
-	nv_icmd(priv, 0x000819, 0x00000000);
-	nv_icmd(priv, 0x00081a, 0x00000000);
-	nv_icmd(priv, 0x00081b, 0x00000000);
-	nv_icmd(priv, 0x00081c, 0x00000000);
-	nv_icmd(priv, 0x00081d, 0x00000000);
-	nv_icmd(priv, 0x00081e, 0x00000000);
-	nv_icmd(priv, 0x00081f, 0x00000000);
-	nv_icmd(priv, 0x000848, 0x00000000);
-	nv_icmd(priv, 0x000849, 0x00000000);
-	nv_icmd(priv, 0x00084a, 0x00000000);
-	nv_icmd(priv, 0x00084b, 0x00000000);
-	nv_icmd(priv, 0x00084c, 0x00000000);
-	nv_icmd(priv, 0x00084d, 0x00000000);
-	nv_icmd(priv, 0x00084e, 0x00000000);
-	nv_icmd(priv, 0x00084f, 0x00000000);
-	nv_icmd(priv, 0x000850, 0x00000000);
-	nv_icmd(priv, 0x000851, 0x00000000);
-	nv_icmd(priv, 0x000852, 0x00000000);
-	nv_icmd(priv, 0x000853, 0x00000000);
-	nv_icmd(priv, 0x000854, 0x00000000);
-	nv_icmd(priv, 0x000855, 0x00000000);
-	nv_icmd(priv, 0x000856, 0x00000000);
-	nv_icmd(priv, 0x000857, 0x00000000);
-	nv_icmd(priv, 0x000738, 0x00000000);
-	nv_icmd(priv, 0x0006aa, 0x00000001);
-	nv_icmd(priv, 0x0006ab, 0x00000002);
-	nv_icmd(priv, 0x0006ac, 0x00000080);
-	nv_icmd(priv, 0x0006ad, 0x00000100);
-	nv_icmd(priv, 0x0006ae, 0x00000100);
-	nv_icmd(priv, 0x0006b1, 0x00000011);
-	nv_icmd(priv, 0x0006bb, 0x000000cf);
-	nv_icmd(priv, 0x0006ce, 0x2a712488);
-	nv_icmd(priv, 0x000739, 0x4085c000);
-	nv_icmd(priv, 0x00073a, 0x00000080);
-	nv_icmd(priv, 0x000786, 0x80000100);
-	nv_icmd(priv, 0x00073c, 0x00010100);
-	nv_icmd(priv, 0x00073d, 0x02800000);
-	nv_icmd(priv, 0x000787, 0x000000cf);
-	nv_icmd(priv, 0x00078c, 0x00000008);
-	nv_icmd(priv, 0x000792, 0x00000001);
-	nv_icmd(priv, 0x000794, 0x00000001);
-	nv_icmd(priv, 0x000795, 0x00000001);
-	nv_icmd(priv, 0x000796, 0x00000001);
-	nv_icmd(priv, 0x000797, 0x000000cf);
-	nv_icmd(priv, 0x000836, 0x00000001);
-	nv_icmd(priv, 0x00079a, 0x00000002);
-	nv_icmd(priv, 0x000833, 0x04444480);
-	nv_icmd(priv, 0x0007a1, 0x00000001);
-	nv_icmd(priv, 0x0007a3, 0x00000001);
-	nv_icmd(priv, 0x0007a4, 0x00000001);
-	nv_icmd(priv, 0x0007a5, 0x00000001);
-	nv_icmd(priv, 0x000831, 0x00000004);
-	nv_icmd(priv, 0x000b07, 0x00000002);
-	nv_icmd(priv, 0x000b08, 0x00000100);
-	nv_icmd(priv, 0x000b09, 0x00000100);
-	nv_icmd(priv, 0x000b0a, 0x00000001);
-	nv_icmd(priv, 0x000a04, 0x000000ff);
-	nv_icmd(priv, 0x000a0b, 0x00000040);
-	nv_icmd(priv, 0x00097f, 0x00000100);
-	nv_icmd(priv, 0x000a02, 0x00000001);
-	nv_icmd(priv, 0x000809, 0x00000007);
-	nv_icmd(priv, 0x00c221, 0x00000040);
-	nv_icmd(priv, 0x00c1b0, 0x0000000f);
-	nv_icmd(priv, 0x00c1b1, 0x0000000f);
-	nv_icmd(priv, 0x00c1b2, 0x0000000f);
-	nv_icmd(priv, 0x00c1b3, 0x0000000f);
-	nv_icmd(priv, 0x00c1b4, 0x0000000f);
-	nv_icmd(priv, 0x00c1b5, 0x0000000f);
-	nv_icmd(priv, 0x00c1b6, 0x0000000f);
-	nv_icmd(priv, 0x00c1b7, 0x0000000f);
-	nv_icmd(priv, 0x00c1b8, 0x0fac6881);
-	nv_icmd(priv, 0x00c1b9, 0x00fac688);
-	nv_icmd(priv, 0x00c401, 0x00000001);
-	nv_icmd(priv, 0x00c402, 0x00010001);
-	nv_icmd(priv, 0x00c403, 0x00000001);
-	nv_icmd(priv, 0x00c404, 0x00000001);
-	nv_icmd(priv, 0x00c40e, 0x00000020);
-	nv_icmd(priv, 0x00c500, 0x00000003);
-	nv_icmd(priv, 0x01e100, 0x00000001);
-	nv_icmd(priv, 0x001000, 0x00000002);
-	nv_icmd(priv, 0x0006aa, 0x00000001);
-	nv_icmd(priv, 0x0006ad, 0x00000100);
-	nv_icmd(priv, 0x0006ae, 0x00000100);
-	nv_icmd(priv, 0x0006b1, 0x00000011);
-	nv_icmd(priv, 0x00078c, 0x00000008);
-	nv_icmd(priv, 0x000792, 0x00000001);
-	nv_icmd(priv, 0x000794, 0x00000001);
-	nv_icmd(priv, 0x000795, 0x00000001);
-	nv_icmd(priv, 0x000796, 0x00000001);
-	nv_icmd(priv, 0x000797, 0x000000cf);
-	nv_icmd(priv, 0x00079a, 0x00000002);
-	nv_icmd(priv, 0x000833, 0x04444480);
-	nv_icmd(priv, 0x0007a1, 0x00000001);
-	nv_icmd(priv, 0x0007a3, 0x00000001);
-	nv_icmd(priv, 0x0007a4, 0x00000001);
-	nv_icmd(priv, 0x0007a5, 0x00000001);
-	nv_icmd(priv, 0x000831, 0x00000004);
-	nv_icmd(priv, 0x01e100, 0x00000001);
-	nv_icmd(priv, 0x001000, 0x00000008);
-	nv_icmd(priv, 0x000039, 0x00000000);
-	nv_icmd(priv, 0x00003a, 0x00000000);
-	nv_icmd(priv, 0x00003b, 0x00000000);
-	nv_icmd(priv, 0x000380, 0x00000001);
-	nv_icmd(priv, 0x000366, 0x00000000);
-	nv_icmd(priv, 0x000367, 0x00000000);
-	nv_icmd(priv, 0x000368, 0x00000fff);
-	nv_icmd(priv, 0x000370, 0x00000000);
-	nv_icmd(priv, 0x000371, 0x00000000);
-	nv_icmd(priv, 0x000372, 0x000fffff);
-	nv_icmd(priv, 0x000813, 0x00000006);
-	nv_icmd(priv, 0x000814, 0x00000008);
-	nv_icmd(priv, 0x000957, 0x00000003);
-	nv_icmd(priv, 0x000818, 0x00000000);
-	nv_icmd(priv, 0x000819, 0x00000000);
-	nv_icmd(priv, 0x00081a, 0x00000000);
-	nv_icmd(priv, 0x00081b, 0x00000000);
-	nv_icmd(priv, 0x00081c, 0x00000000);
-	nv_icmd(priv, 0x00081d, 0x00000000);
-	nv_icmd(priv, 0x00081e, 0x00000000);
-	nv_icmd(priv, 0x00081f, 0x00000000);
-	nv_icmd(priv, 0x000848, 0x00000000);
-	nv_icmd(priv, 0x000849, 0x00000000);
-	nv_icmd(priv, 0x00084a, 0x00000000);
-	nv_icmd(priv, 0x00084b, 0x00000000);
-	nv_icmd(priv, 0x00084c, 0x00000000);
-	nv_icmd(priv, 0x00084d, 0x00000000);
-	nv_icmd(priv, 0x00084e, 0x00000000);
-	nv_icmd(priv, 0x00084f, 0x00000000);
-	nv_icmd(priv, 0x000850, 0x00000000);
-	nv_icmd(priv, 0x000851, 0x00000000);
-	nv_icmd(priv, 0x000852, 0x00000000);
-	nv_icmd(priv, 0x000853, 0x00000000);
-	nv_icmd(priv, 0x000854, 0x00000000);
-	nv_icmd(priv, 0x000855, 0x00000000);
-	nv_icmd(priv, 0x000856, 0x00000000);
-	nv_icmd(priv, 0x000857, 0x00000000);
-	nv_icmd(priv, 0x000738, 0x00000000);
-	nv_icmd(priv, 0x000b07, 0x00000002);
-	nv_icmd(priv, 0x000b08, 0x00000100);
-	nv_icmd(priv, 0x000b09, 0x00000100);
-	nv_icmd(priv, 0x000b0a, 0x00000001);
-	nv_icmd(priv, 0x000a04, 0x000000ff);
-	nv_icmd(priv, 0x00097f, 0x00000100);
-	nv_icmd(priv, 0x000a02, 0x00000001);
-	nv_icmd(priv, 0x000809, 0x00000007);
-	nv_icmd(priv, 0x00c221, 0x00000040);
-	nv_icmd(priv, 0x00c401, 0x00000001);
-	nv_icmd(priv, 0x00c402, 0x00010001);
-	nv_icmd(priv, 0x00c403, 0x00000001);
-	nv_icmd(priv, 0x00c404, 0x00000001);
-	nv_icmd(priv, 0x00c40e, 0x00000020);
-	nv_icmd(priv, 0x00c500, 0x00000003);
-	nv_icmd(priv, 0x01e100, 0x00000001);
-	nv_icmd(priv, 0x001000, 0x00000001);
-	nv_icmd(priv, 0x000b07, 0x00000002);
-	nv_icmd(priv, 0x000b08, 0x00000100);
-	nv_icmd(priv, 0x000b09, 0x00000100);
-	nv_icmd(priv, 0x000b0a, 0x00000001);
-	nv_icmd(priv, 0x01e100, 0x00000001);
-	nv_wr32(priv, 0x400208, 0x00000000);
-}
-
-static void
-nve0_grctx_generate_a097(struct nvc0_graph_priv *priv)
-{
-	nv_mthd(priv, 0xa097, 0x0800, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0840, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0880, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x08c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0900, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0940, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0980, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x09c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0804, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0844, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0884, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x08c4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0904, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0944, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0984, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x09c4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0808, 0x00000400);
-	nv_mthd(priv, 0xa097, 0x0848, 0x00000400);
-	nv_mthd(priv, 0xa097, 0x0888, 0x00000400);
-	nv_mthd(priv, 0xa097, 0x08c8, 0x00000400);
-	nv_mthd(priv, 0xa097, 0x0908, 0x00000400);
-	nv_mthd(priv, 0xa097, 0x0948, 0x00000400);
-	nv_mthd(priv, 0xa097, 0x0988, 0x00000400);
-	nv_mthd(priv, 0xa097, 0x09c8, 0x00000400);
-	nv_mthd(priv, 0xa097, 0x080c, 0x00000300);
-	nv_mthd(priv, 0xa097, 0x084c, 0x00000300);
-	nv_mthd(priv, 0xa097, 0x088c, 0x00000300);
-	nv_mthd(priv, 0xa097, 0x08cc, 0x00000300);
-	nv_mthd(priv, 0xa097, 0x090c, 0x00000300);
-	nv_mthd(priv, 0xa097, 0x094c, 0x00000300);
-	nv_mthd(priv, 0xa097, 0x098c, 0x00000300);
-	nv_mthd(priv, 0xa097, 0x09cc, 0x00000300);
-	nv_mthd(priv, 0xa097, 0x0810, 0x000000cf);
-	nv_mthd(priv, 0xa097, 0x0850, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0890, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x08d0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0910, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0950, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0990, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x09d0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0814, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x0854, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x0894, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x08d4, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x0914, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x0954, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x0994, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x09d4, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x0818, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0858, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0898, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x08d8, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0918, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0958, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0998, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x09d8, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x081c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x085c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x089c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x08dc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x091c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x095c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x099c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x09dc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0820, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0860, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x08a0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x08e0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0920, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0960, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x09a0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x09e0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c00, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c10, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c20, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c30, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c40, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c50, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c60, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c70, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c80, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c90, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ca0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cb0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cc0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cd0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ce0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cf0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c04, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c14, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c24, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c34, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c44, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c54, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c64, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c74, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c84, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c94, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ca4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cb4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cc4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cd4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ce4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cf4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c08, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c18, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c28, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c38, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c48, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c58, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c68, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c78, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c88, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c98, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ca8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cb8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cc8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cd8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ce8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cf8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c0c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c1c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c2c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c3c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c4c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c5c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c6c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c7c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c8c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1c9c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cbc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ccc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cdc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1cfc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d00, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d10, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d20, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d30, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d40, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d50, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d60, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d70, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d80, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d90, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1da0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1db0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dc0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dd0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1de0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1df0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d04, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d14, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d24, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d34, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d44, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d54, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d64, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d74, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d84, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d94, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1da4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1db4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dc4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dd4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1de4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1df4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d08, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d18, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d28, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d38, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d48, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d58, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d68, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d78, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d88, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d98, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1da8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1db8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dc8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dd8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1de8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1df8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d0c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d1c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d2c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d3c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d4c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d5c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d6c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d7c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d8c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1d9c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dbc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dcc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ddc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1dfc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f00, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f08, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f10, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f18, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f20, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f28, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f30, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f38, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f40, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f48, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f50, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f58, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f60, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f68, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f70, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f78, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f04, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f0c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f14, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f1c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f24, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f2c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f34, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f3c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f44, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f4c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f54, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f5c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f64, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f6c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f74, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f7c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f80, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f88, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f90, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f98, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fa0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fa8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fb0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fb8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fc0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fc8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fd0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fd8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fe0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fe8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ff0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ff8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f84, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f8c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f94, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1f9c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fa4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fb4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fbc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fc4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fcc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fd4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fdc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fe4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1fec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ff4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1ffc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2000, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2040, 0x00000011);
-	nv_mthd(priv, 0xa097, 0x2080, 0x00000020);
-	nv_mthd(priv, 0xa097, 0x20c0, 0x00000030);
-	nv_mthd(priv, 0xa097, 0x2100, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x2140, 0x00000051);
-	nv_mthd(priv, 0xa097, 0x200c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x204c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x208c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x20cc, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x210c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x214c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x2010, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2050, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2090, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x20d0, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x2110, 0x00000003);
-	nv_mthd(priv, 0xa097, 0x2150, 0x00000004);
-	nv_mthd(priv, 0xa097, 0x0380, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03a0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03e0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0384, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03a4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03c4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03e4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0388, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03a8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03c8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03e8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x038c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03ac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03cc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x03ec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0700, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0710, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0720, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0730, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0704, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0714, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0724, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0734, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0708, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0718, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0728, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0738, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2800, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2804, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2808, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x280c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2810, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2814, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2818, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x281c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2820, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2824, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2828, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x282c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2830, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2834, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2838, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x283c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2840, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2844, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2848, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x284c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2850, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2854, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2858, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x285c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2860, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2864, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2868, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x286c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2870, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2874, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2878, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x287c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2880, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2884, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2888, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x288c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2890, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2894, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2898, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x289c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28a0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28a4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28a8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28ac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28b0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28b4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28b8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28bc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28c4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28c8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28cc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28d0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28d4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28d8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28dc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28e0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28e4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28e8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28ec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28f0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28f4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28f8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x28fc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2900, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2904, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2908, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x290c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2910, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2914, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2918, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x291c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2920, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2924, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2928, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x292c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2930, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2934, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2938, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x293c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2940, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2944, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2948, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x294c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2950, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2954, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2958, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x295c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2960, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2964, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2968, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x296c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2970, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2974, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2978, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x297c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2980, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2984, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2988, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x298c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2990, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2994, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2998, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x299c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29a0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29a4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29a8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29ac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29b0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29b4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29b8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29bc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29c4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29c8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29cc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29d0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29d4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29d8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29dc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29e0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29e4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29e8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29ec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29f0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29f4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29f8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x29fc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a00, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a20, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a40, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a60, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a80, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0aa0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ac0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ae0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b00, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b20, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b40, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b60, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b80, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ba0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bc0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0be0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a04, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a24, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a44, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a64, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a84, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0aa4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ac4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ae4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b04, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b24, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b44, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b64, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b84, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ba4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bc4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0be4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a08, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a28, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a48, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a68, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a88, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0aa8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ac8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ae8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b08, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b28, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b48, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b68, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b88, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ba8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bc8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0be8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a0c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a2c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a4c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a6c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a8c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0aac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0acc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0aec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b0c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b2c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b4c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b6c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b8c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bcc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a10, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a30, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a50, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a70, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a90, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ab0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ad0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0af0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b10, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b30, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b50, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b70, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b90, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bb0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bd0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bf0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a14, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a34, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a54, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a74, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0a94, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ab4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ad4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0af4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b14, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b34, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b54, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b74, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0b94, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bb4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bd4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0bf4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c00, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c10, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c20, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c30, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c40, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c50, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c60, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c70, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c80, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c90, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ca0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cb0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cc0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cd0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ce0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cf0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c04, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c14, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c24, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c34, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c44, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c54, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c64, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c74, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c84, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c94, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ca4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cb4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cc4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cd4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ce4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cf4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c08, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c18, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c28, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c38, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c48, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c58, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c68, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c78, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c88, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c98, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ca8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cb8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cc8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cd8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ce8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0cf8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0c0c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0c1c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0c2c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0c3c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0c4c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0c5c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0c6c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0c7c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0c8c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0c9c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0cac, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0cbc, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0ccc, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0cdc, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0cec, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0cfc, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0d00, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d08, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d10, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d18, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d20, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d28, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d30, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d38, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d04, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d0c, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d14, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d1c, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d24, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d2c, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d34, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d3c, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e00, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e10, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e20, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e30, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e40, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e50, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e60, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e70, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e80, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e90, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ea0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0eb0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ec0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ed0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ee0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ef0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0e04, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e14, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e24, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e34, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e44, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e54, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e64, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e74, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e84, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e94, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ea4, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0eb4, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ec4, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ed4, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ee4, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ef4, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e08, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e18, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e28, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e38, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e48, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e58, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e68, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e78, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e88, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0e98, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ea8, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0eb8, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ec8, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ed8, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ee8, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0ef8, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d40, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d48, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d50, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d58, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d44, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d4c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d54, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d5c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1e00, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e20, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e40, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e60, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e80, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ea0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ec0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ee0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e04, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e24, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e44, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e64, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e84, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ea4, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ec4, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ee4, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e08, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e28, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e48, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e68, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e88, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1ea8, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1ec8, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1ee8, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e0c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e2c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e4c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e6c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e8c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1eac, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ecc, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1eec, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e10, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e30, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e50, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e70, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e90, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1eb0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ed0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ef0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e14, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e34, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e54, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e74, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e94, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1eb4, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1ed4, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1ef4, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1e18, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e38, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e58, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e78, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1e98, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1eb8, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ed8, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1ef8, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x3400, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3404, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3408, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x340c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3410, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3414, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3418, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x341c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3420, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3424, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3428, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x342c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3430, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3434, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3438, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x343c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3440, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3444, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3448, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x344c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3450, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3454, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3458, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x345c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3460, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3464, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3468, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x346c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3470, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3474, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3478, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x347c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3480, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3484, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3488, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x348c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3490, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3494, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3498, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x349c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34a0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34a4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34a8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34ac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34b0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34b4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34b8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34bc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34c4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34c8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34cc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34d0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34d4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34d8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34dc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34e0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34e4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34e8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34ec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34f0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34f4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34f8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x34fc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3500, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3504, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3508, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x350c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3510, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3514, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3518, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x351c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3520, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3524, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3528, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x352c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3530, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3534, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3538, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x353c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3540, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3544, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3548, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x354c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3550, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3554, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3558, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x355c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3560, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3564, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3568, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x356c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3570, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3574, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3578, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x357c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3580, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3584, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3588, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x358c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3590, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3594, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x3598, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x359c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35a0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35a4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35a8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35ac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35b0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35b4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35b8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35bc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35c4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35c8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35cc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35d0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35d4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35d8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35dc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35e0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35e4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35e8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35ec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35f0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35f4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35f8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x35fc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x030c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1944, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1514, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d68, 0x0000ffff);
-	nv_mthd(priv, 0xa097, 0x121c, 0x0fac6881);
-	nv_mthd(priv, 0xa097, 0x0fac, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1538, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0fe0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0fe4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0fe8, 0x00000014);
-	nv_mthd(priv, 0xa097, 0x0fec, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x0ff0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x179c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1228, 0x00000400);
-	nv_mthd(priv, 0xa097, 0x122c, 0x00000300);
-	nv_mthd(priv, 0xa097, 0x1230, 0x00010001);
-	nv_mthd(priv, 0xa097, 0x07f8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x15b4, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x15cc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1534, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0fb0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x15d0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x153c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x16b4, 0x00000003);
-	nv_mthd(priv, 0xa097, 0x0fbc, 0x0000ffff);
-	nv_mthd(priv, 0xa097, 0x0fc0, 0x0000ffff);
-	nv_mthd(priv, 0xa097, 0x0fc4, 0x0000ffff);
-	nv_mthd(priv, 0xa097, 0x0fc8, 0x0000ffff);
-	nv_mthd(priv, 0xa097, 0x0df8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0dfc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1948, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1970, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x161c, 0x000009f0);
-	nv_mthd(priv, 0xa097, 0x0dcc, 0x00000010);
-	nv_mthd(priv, 0xa097, 0x163c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x15e4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1160, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1164, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1168, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x116c, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1170, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1174, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1178, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x117c, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1180, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1184, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1188, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x118c, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1190, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1194, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1198, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x119c, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11a0, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11a4, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11a8, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11ac, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11b0, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11b4, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11b8, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11bc, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11c0, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11c4, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11c8, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11cc, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11d0, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11d4, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11d8, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x11dc, 0x25e00040);
-	nv_mthd(priv, 0xa097, 0x1880, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1884, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1888, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x188c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1890, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1894, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1898, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x189c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18a0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18a4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18a8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18ac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18b0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18b4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18b8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18bc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18c4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18c8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18cc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18d0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18d4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18d8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18dc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18e0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18e4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18e8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18ec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18f0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18f4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18f8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x18fc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0f84, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0f88, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x17c8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x17cc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x17d0, 0x000000ff);
-	nv_mthd(priv, 0xa097, 0x17d4, 0xffffffff);
-	nv_mthd(priv, 0xa097, 0x17d8, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x17dc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x15f4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x15f8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1434, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1438, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d74, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0dec, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x13a4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1318, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1644, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0748, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0de8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1648, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x12a4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1120, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1124, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1128, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x112c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1118, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x164c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1658, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1910, 0x00000290);
-	nv_mthd(priv, 0xa097, 0x1518, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x165c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1520, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1604, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1570, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x13b0, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x13b4, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x020c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1670, 0x30201000);
-	nv_mthd(priv, 0xa097, 0x1674, 0x70605040);
-	nv_mthd(priv, 0xa097, 0x1678, 0xb8a89888);
-	nv_mthd(priv, 0xa097, 0x167c, 0xf8e8d8c8);
-	nv_mthd(priv, 0xa097, 0x166c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1680, 0x00ffff00);
-	nv_mthd(priv, 0xa097, 0x12d0, 0x00000003);
-	nv_mthd(priv, 0xa097, 0x12d4, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1684, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1688, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0dac, 0x00001b02);
-	nv_mthd(priv, 0xa097, 0x0db0, 0x00001b02);
-	nv_mthd(priv, 0xa097, 0x0db4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x168c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x15bc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x156c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x187c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1110, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0dc0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0dc4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0dc8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1234, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1690, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x12ac, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0790, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0794, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0798, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x079c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x07a0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x077c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1000, 0x00000010);
-	nv_mthd(priv, 0xa097, 0x10fc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1290, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0218, 0x00000010);
-	nv_mthd(priv, 0xa097, 0x12d8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x12dc, 0x00000010);
-	nv_mthd(priv, 0xa097, 0x0d94, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x155c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1560, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1564, 0x00000fff);
-	nv_mthd(priv, 0xa097, 0x1574, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1578, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x157c, 0x000fffff);
-	nv_mthd(priv, 0xa097, 0x1354, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1610, 0x00000012);
-	nv_mthd(priv, 0xa097, 0x1608, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x160c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x260c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x07ac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x162c, 0x00000003);
-	nv_mthd(priv, 0xa097, 0x0210, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0320, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0324, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0328, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x032c, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0330, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0334, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0338, 0x3f800000);
-	nv_mthd(priv, 0xa097, 0x0750, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0760, 0x39291909);
-	nv_mthd(priv, 0xa097, 0x0764, 0x79695949);
-	nv_mthd(priv, 0xa097, 0x0768, 0xb9a99989);
-	nv_mthd(priv, 0xa097, 0x076c, 0xf9e9d9c9);
-	nv_mthd(priv, 0xa097, 0x0770, 0x30201000);
-	nv_mthd(priv, 0xa097, 0x0774, 0x70605040);
-	nv_mthd(priv, 0xa097, 0x0778, 0x00009080);
-	nv_mthd(priv, 0xa097, 0x0780, 0x39291909);
-	nv_mthd(priv, 0xa097, 0x0784, 0x79695949);
-	nv_mthd(priv, 0xa097, 0x0788, 0xb9a99989);
-	nv_mthd(priv, 0xa097, 0x078c, 0xf9e9d9c9);
-	nv_mthd(priv, 0xa097, 0x07d0, 0x30201000);
-	nv_mthd(priv, 0xa097, 0x07d4, 0x70605040);
-	nv_mthd(priv, 0xa097, 0x07d8, 0x00009080);
-	nv_mthd(priv, 0xa097, 0x037c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0740, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0744, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x2600, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1918, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x191c, 0x00000900);
-	nv_mthd(priv, 0xa097, 0x1920, 0x00000405);
-	nv_mthd(priv, 0xa097, 0x1308, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1924, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x13ac, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x192c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x193c, 0x00002c1c);
-	nv_mthd(priv, 0xa097, 0x0d7c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0f8c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x02c0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1510, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1940, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ff4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0ff8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x194c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1950, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1968, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1590, 0x0000003f);
-	nv_mthd(priv, 0xa097, 0x07e8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x07ec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x07f0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x07f4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x196c, 0x00000011);
-	nv_mthd(priv, 0xa097, 0x02e4, 0x0000b001);
-	nv_mthd(priv, 0xa097, 0x036c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0370, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x197c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0fcc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0fd0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x02d8, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x1980, 0x00000080);
-	nv_mthd(priv, 0xa097, 0x1504, 0x00000080);
-	nv_mthd(priv, 0xa097, 0x1984, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0300, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x13a8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x12ec, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1310, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1314, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1380, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1384, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1388, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x138c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1390, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1394, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x139c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1398, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1594, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1598, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x159c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x15a0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x15a4, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0f54, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0f58, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0f5c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x19bc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0f9c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0fa0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x12cc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x12e8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x130c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1360, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1364, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1368, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x136c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1370, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1374, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1378, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x137c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x133c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1340, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1344, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1348, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x134c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1350, 0x00000002);
-	nv_mthd(priv, 0xa097, 0x1358, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x12e4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x131c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1320, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1324, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1328, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x19c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1140, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x19c4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x19c8, 0x00001500);
-	nv_mthd(priv, 0xa097, 0x135c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0f90, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x19e0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x19e4, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x19e8, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x19ec, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x19f0, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x19f4, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x19f8, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x19fc, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x19cc, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x15b8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1a00, 0x00001111);
-	nv_mthd(priv, 0xa097, 0x1a04, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1a08, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1a0c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1a10, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1a14, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1a18, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1a1c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d6c, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x0d70, 0xffff0000);
-	nv_mthd(priv, 0xa097, 0x10f8, 0x00001010);
-	nv_mthd(priv, 0xa097, 0x0d80, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d84, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d88, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d8c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0d90, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0da0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x07a4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x07a8, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1508, 0x80000000);
-	nv_mthd(priv, 0xa097, 0x150c, 0x40000000);
-	nv_mthd(priv, 0xa097, 0x1668, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0318, 0x00000008);
-	nv_mthd(priv, 0xa097, 0x031c, 0x00000008);
-	nv_mthd(priv, 0xa097, 0x0d9c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x0374, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0378, 0x00000020);
-	nv_mthd(priv, 0xa097, 0x07dc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x074c, 0x00000055);
-	nv_mthd(priv, 0xa097, 0x1420, 0x00000003);
-	nv_mthd(priv, 0xa097, 0x17bc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x17c0, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x17c4, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1008, 0x00000008);
-	nv_mthd(priv, 0xa097, 0x100c, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x1010, 0x0000012c);
-	nv_mthd(priv, 0xa097, 0x0d60, 0x00000040);
-	nv_mthd(priv, 0xa097, 0x075c, 0x00000003);
-	nv_mthd(priv, 0xa097, 0x1018, 0x00000020);
-	nv_mthd(priv, 0xa097, 0x101c, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1020, 0x00000020);
-	nv_mthd(priv, 0xa097, 0x1024, 0x00000001);
-	nv_mthd(priv, 0xa097, 0x1444, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x1448, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x144c, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0360, 0x20164010);
-	nv_mthd(priv, 0xa097, 0x0364, 0x00000020);
-	nv_mthd(priv, 0xa097, 0x0368, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0de4, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0204, 0x00000006);
-	nv_mthd(priv, 0xa097, 0x0208, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x02cc, 0x003fffff);
-	nv_mthd(priv, 0xa097, 0x02d0, 0x003fffff);
-	nv_mthd(priv, 0xa097, 0x1220, 0x00000005);
-	nv_mthd(priv, 0xa097, 0x0fdc, 0x00000000);
-	nv_mthd(priv, 0xa097, 0x0f98, 0x00400008);
-	nv_mthd(priv, 0xa097, 0x1284, 0x08000080);
-	nv_mthd(priv, 0xa097, 0x1450, 0x00400008);
-	nv_mthd(priv, 0xa097, 0x1454, 0x08000080);
-	nv_mthd(priv, 0xa097, 0x0214, 0x00000000);
-}
-
-static void
-nve0_grctx_generate_902d(struct nvc0_graph_priv *priv)
-{
-	nv_mthd(priv, 0x902d, 0x0200, 0x000000cf);
-	nv_mthd(priv, 0x902d, 0x0204, 0x00000001);
-	nv_mthd(priv, 0x902d, 0x0208, 0x00000020);
-	nv_mthd(priv, 0x902d, 0x020c, 0x00000001);
-	nv_mthd(priv, 0x902d, 0x0210, 0x00000000);
-	nv_mthd(priv, 0x902d, 0x0214, 0x00000080);
-	nv_mthd(priv, 0x902d, 0x0218, 0x00000100);
-	nv_mthd(priv, 0x902d, 0x021c, 0x00000100);
-	nv_mthd(priv, 0x902d, 0x0220, 0x00000000);
-	nv_mthd(priv, 0x902d, 0x0224, 0x00000000);
-	nv_mthd(priv, 0x902d, 0x0230, 0x000000cf);
-	nv_mthd(priv, 0x902d, 0x0234, 0x00000001);
-	nv_mthd(priv, 0x902d, 0x0238, 0x00000020);
-	nv_mthd(priv, 0x902d, 0x023c, 0x00000001);
-	nv_mthd(priv, 0x902d, 0x0244, 0x00000080);
-	nv_mthd(priv, 0x902d, 0x0248, 0x00000100);
-	nv_mthd(priv, 0x902d, 0x024c, 0x00000100);
-	nv_mthd(priv, 0x902d, 0x3410, 0x00000000);
-}
-
-static void
-nve0_graph_generate_unk40xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x404010, 0x0);
-	nv_wr32(priv, 0x404014, 0x0);
-	nv_wr32(priv, 0x404018, 0x0);
-	nv_wr32(priv, 0x40401c, 0x0);
-	nv_wr32(priv, 0x404020, 0x0);
-	nv_wr32(priv, 0x404024, 0xe000);
-	nv_wr32(priv, 0x404028, 0x0);
-	nv_wr32(priv, 0x4040a8, 0x0);
-	nv_wr32(priv, 0x4040ac, 0x0);
-	nv_wr32(priv, 0x4040b0, 0x0);
-	nv_wr32(priv, 0x4040b4, 0x0);
-	nv_wr32(priv, 0x4040b8, 0x0);
-	nv_wr32(priv, 0x4040bc, 0x0);
-	nv_wr32(priv, 0x4040c0, 0x0);
-	nv_wr32(priv, 0x4040c4, 0x0);
-	nv_wr32(priv, 0x4040c8, 0xf800008f);
-	nv_wr32(priv, 0x4040d0, 0x0);
-	nv_wr32(priv, 0x4040d4, 0x0);
-	nv_wr32(priv, 0x4040d8, 0x0);
-	nv_wr32(priv, 0x4040dc, 0x0);
-	nv_wr32(priv, 0x4040e0, 0x0);
-	nv_wr32(priv, 0x4040e4, 0x0);
-	nv_wr32(priv, 0x4040e8, 0x1000);
-	nv_wr32(priv, 0x4040f8, 0x0);
-	nv_wr32(priv, 0x404130, 0x0);
-	nv_wr32(priv, 0x404134, 0x0);
-	nv_wr32(priv, 0x404138, 0x20000040);
-	nv_wr32(priv, 0x404150, 0x2e);
-	nv_wr32(priv, 0x404154, 0x400);
-	nv_wr32(priv, 0x404158, 0x200);
-	nv_wr32(priv, 0x404164, 0x55);
-	nv_wr32(priv, 0x4041a0, 0x0);
-	nv_wr32(priv, 0x4041a4, 0x0);
-	nv_wr32(priv, 0x4041a8, 0x0);
-	nv_wr32(priv, 0x4041ac, 0x0);
-	nv_wr32(priv, 0x404200, 0x0);
-	nv_wr32(priv, 0x404204, 0x0);
-	nv_wr32(priv, 0x404208, 0x0);
-	nv_wr32(priv, 0x40420c, 0x0);
-}
-
-static void
-nve0_graph_generate_unk44xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x404404, 0x0);
-	nv_wr32(priv, 0x404408, 0x0);
-	nv_wr32(priv, 0x40440c, 0x0);
-	nv_wr32(priv, 0x404410, 0x0);
-	nv_wr32(priv, 0x404414, 0x0);
-	nv_wr32(priv, 0x404418, 0x0);
-	nv_wr32(priv, 0x40441c, 0x0);
-	nv_wr32(priv, 0x404420, 0x0);
-	nv_wr32(priv, 0x404424, 0x0);
-	nv_wr32(priv, 0x404428, 0x0);
-	nv_wr32(priv, 0x40442c, 0x0);
-	nv_wr32(priv, 0x404430, 0x0);
-	nv_wr32(priv, 0x404434, 0x0);
-	nv_wr32(priv, 0x404438, 0x0);
-	nv_wr32(priv, 0x404460, 0x0);
-	nv_wr32(priv, 0x404464, 0x0);
-	nv_wr32(priv, 0x404468, 0xffffff);
-	nv_wr32(priv, 0x40446c, 0x0);
-	nv_wr32(priv, 0x404480, 0x1);
-	nv_wr32(priv, 0x404498, 0x1);
-}
-
-static void
-nve0_graph_generate_unk46xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x404604, 0x14);
-	nv_wr32(priv, 0x404608, 0x0);
-	nv_wr32(priv, 0x40460c, 0x3fff);
-	nv_wr32(priv, 0x404610, 0x100);
-	nv_wr32(priv, 0x404618, 0x0);
-	nv_wr32(priv, 0x40461c, 0x0);
-	nv_wr32(priv, 0x404620, 0x0);
-	nv_wr32(priv, 0x404624, 0x0);
-	nv_wr32(priv, 0x40462c, 0x0);
-	nv_wr32(priv, 0x404630, 0x0);
-	nv_wr32(priv, 0x404640, 0x0);
-	nv_wr32(priv, 0x404654, 0x0);
-	nv_wr32(priv, 0x404660, 0x0);
-	nv_wr32(priv, 0x404678, 0x0);
-	nv_wr32(priv, 0x40467c, 0x2);
-	nv_wr32(priv, 0x404680, 0x0);
-	nv_wr32(priv, 0x404684, 0x0);
-	nv_wr32(priv, 0x404688, 0x0);
-	nv_wr32(priv, 0x40468c, 0x0);
-	nv_wr32(priv, 0x404690, 0x0);
-	nv_wr32(priv, 0x404694, 0x0);
-	nv_wr32(priv, 0x404698, 0x0);
-	nv_wr32(priv, 0x40469c, 0x0);
-	nv_wr32(priv, 0x4046a0, 0x7f0080);
-	nv_wr32(priv, 0x4046a4, 0x0);
-	nv_wr32(priv, 0x4046a8, 0x0);
-	nv_wr32(priv, 0x4046ac, 0x0);
-	nv_wr32(priv, 0x4046b0, 0x0);
-	nv_wr32(priv, 0x4046b4, 0x0);
-	nv_wr32(priv, 0x4046b8, 0x0);
-	nv_wr32(priv, 0x4046bc, 0x0);
-	nv_wr32(priv, 0x4046c0, 0x0);
-	nv_wr32(priv, 0x4046c8, 0x0);
-	nv_wr32(priv, 0x4046cc, 0x0);
-	nv_wr32(priv, 0x4046d0, 0x0);
-}
-
-static void
-nve0_graph_generate_unk47xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x404700, 0x0);
-	nv_wr32(priv, 0x404704, 0x0);
-	nv_wr32(priv, 0x404708, 0x0);
-	nv_wr32(priv, 0x404718, 0x0);
-	nv_wr32(priv, 0x40471c, 0x0);
-	nv_wr32(priv, 0x404720, 0x0);
-	nv_wr32(priv, 0x404724, 0x0);
-	nv_wr32(priv, 0x404728, 0x0);
-	nv_wr32(priv, 0x40472c, 0x0);
-	nv_wr32(priv, 0x404730, 0x0);
-	nv_wr32(priv, 0x404734, 0x100);
-	nv_wr32(priv, 0x404738, 0x0);
-	nv_wr32(priv, 0x40473c, 0x0);
-	nv_wr32(priv, 0x404744, 0x0);
-	nv_wr32(priv, 0x404748, 0x0);
-	nv_wr32(priv, 0x404754, 0x0);
-}
-
-static void
-nve0_graph_generate_unk58xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x405800, 0xf8000bf);
-	nv_wr32(priv, 0x405830, 0x2180648);
-	nv_wr32(priv, 0x405834, 0x8000000);
-	nv_wr32(priv, 0x405838, 0x0);
-	nv_wr32(priv, 0x405854, 0x0);
-	nv_wr32(priv, 0x405870, 0x1);
-	nv_wr32(priv, 0x405874, 0x1);
-	nv_wr32(priv, 0x405878, 0x1);
-	nv_wr32(priv, 0x40587c, 0x1);
-	nv_wr32(priv, 0x405a00, 0x0);
-	nv_wr32(priv, 0x405a04, 0x0);
-	nv_wr32(priv, 0x405a18, 0x0);
-	nv_wr32(priv, 0x405b00, 0x0);
-	nv_wr32(priv, 0x405b10, 0x1000);
-}
-
-static void
-nve0_graph_generate_unk60xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x406020, 0x4103c1);
-	nv_wr32(priv, 0x406028, 0x1);
-	nv_wr32(priv, 0x40602c, 0x1);
-	nv_wr32(priv, 0x406030, 0x1);
-	nv_wr32(priv, 0x406034, 0x1);
-}
-
-static void
-nve0_graph_generate_unk64xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x4064a8, 0x0);
-	nv_wr32(priv, 0x4064ac, 0x3fff);
-	nv_wr32(priv, 0x4064b4, 0x0);
-	nv_wr32(priv, 0x4064b8, 0x0);
-	nv_wr32(priv, 0x4064c0, 0x801a00f0);
-	nv_wr32(priv, 0x4064c4, 0x192ffff);
-	nv_wr32(priv, 0x4064c8, 0x1800600);
-	nv_wr32(priv, 0x4064cc, 0x0);
-	nv_wr32(priv, 0x4064d0, 0x0);
-	nv_wr32(priv, 0x4064d4, 0x0);
-	nv_wr32(priv, 0x4064d8, 0x0);
-	nv_wr32(priv, 0x4064dc, 0x0);
-	nv_wr32(priv, 0x4064e0, 0x0);
-	nv_wr32(priv, 0x4064e4, 0x0);
-	nv_wr32(priv, 0x4064e8, 0x0);
-	nv_wr32(priv, 0x4064ec, 0x0);
-	nv_wr32(priv, 0x4064fc, 0x22a);
-}
-
-static void
-nve0_graph_generate_unk70xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x407040, 0x0);
-}
-
-static void
-nve0_graph_generate_unk78xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x407804, 0x23);
-	nv_wr32(priv, 0x40780c, 0xa418820);
-	nv_wr32(priv, 0x407810, 0x62080e6);
-	nv_wr32(priv, 0x407814, 0x20398a4);
-	nv_wr32(priv, 0x407818, 0xe629062);
-	nv_wr32(priv, 0x40781c, 0xa418820);
-	nv_wr32(priv, 0x407820, 0xe6);
-	nv_wr32(priv, 0x4078bc, 0x103);
-}
-
-static void
-nve0_graph_generate_unk80xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x408000, 0x0);
-	nv_wr32(priv, 0x408004, 0x0);
-	nv_wr32(priv, 0x408008, 0x30);
-	nv_wr32(priv, 0x40800c, 0x0);
-	nv_wr32(priv, 0x408010, 0x0);
-	nv_wr32(priv, 0x408014, 0x69);
-	nv_wr32(priv, 0x408018, 0xe100e100);
-	nv_wr32(priv, 0x408064, 0x0);
-}
-
-static void
-nve0_graph_generate_unk88xx(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x408800, 0x2802a3c);
-	nv_wr32(priv, 0x408804, 0x40);
-	nv_wr32(priv, 0x408808, 0x1043e005);
-	nv_wr32(priv, 0x408840, 0xb);
-	nv_wr32(priv, 0x408900, 0x3080b801);
-	nv_wr32(priv, 0x408904, 0x62000001);
-	nv_wr32(priv, 0x408908, 0xc8102f);
-	nv_wr32(priv, 0x408980, 0x11d);
-}
-
-static void
-nve0_graph_generate_gpc(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x418380, 0x16);
-	nv_wr32(priv, 0x418400, 0x38004e00);
-	nv_wr32(priv, 0x418404, 0x71e0ffff);
-	nv_wr32(priv, 0x41840c, 0x1008);
-	nv_wr32(priv, 0x418410, 0xfff0fff);
-	nv_wr32(priv, 0x418414, 0x2200fff);
-	nv_wr32(priv, 0x418450, 0x0);
-	nv_wr32(priv, 0x418454, 0x0);
-	nv_wr32(priv, 0x418458, 0x0);
-	nv_wr32(priv, 0x41845c, 0x0);
-	nv_wr32(priv, 0x418460, 0x0);
-	nv_wr32(priv, 0x418464, 0x0);
-	nv_wr32(priv, 0x418468, 0x1);
-	nv_wr32(priv, 0x41846c, 0x0);
-	nv_wr32(priv, 0x418470, 0x0);
-	nv_wr32(priv, 0x418600, 0x1f);
-	nv_wr32(priv, 0x418684, 0xf);
-	nv_wr32(priv, 0x418700, 0x2);
-	nv_wr32(priv, 0x418704, 0x80);
-	nv_wr32(priv, 0x418708, 0x0);
-	nv_wr32(priv, 0x41870c, 0x0);
-	nv_wr32(priv, 0x418710, 0x0);
-	nv_wr32(priv, 0x418800, 0x7006860a);
-	nv_wr32(priv, 0x418808, 0x0);
-	nv_wr32(priv, 0x41880c, 0x0);
-	nv_wr32(priv, 0x418810, 0x0);
-	nv_wr32(priv, 0x418828, 0x44);
-	nv_wr32(priv, 0x418830, 0x10000001);
-	nv_wr32(priv, 0x4188d8, 0x8);
-	nv_wr32(priv, 0x4188e0, 0x1000000);
-	nv_wr32(priv, 0x4188e8, 0x0);
-	nv_wr32(priv, 0x4188ec, 0x0);
-	nv_wr32(priv, 0x4188f0, 0x0);
-	nv_wr32(priv, 0x4188f4, 0x0);
-	nv_wr32(priv, 0x4188f8, 0x0);
-	nv_wr32(priv, 0x4188fc, 0x20100018);
-	nv_wr32(priv, 0x41891c, 0xff00ff);
-	nv_wr32(priv, 0x418924, 0x0);
-	nv_wr32(priv, 0x418928, 0xffff00);
-	nv_wr32(priv, 0x41892c, 0xff00);
-	nv_wr32(priv, 0x418a00, 0x0);
-	nv_wr32(priv, 0x418a04, 0x0);
-	nv_wr32(priv, 0x418a08, 0x0);
-	nv_wr32(priv, 0x418a0c, 0x10000);
-	nv_wr32(priv, 0x418a10, 0x0);
-	nv_wr32(priv, 0x418a14, 0x0);
-	nv_wr32(priv, 0x418a18, 0x0);
-	nv_wr32(priv, 0x418a20, 0x0);
-	nv_wr32(priv, 0x418a24, 0x0);
-	nv_wr32(priv, 0x418a28, 0x0);
-	nv_wr32(priv, 0x418a2c, 0x10000);
-	nv_wr32(priv, 0x418a30, 0x0);
-	nv_wr32(priv, 0x418a34, 0x0);
-	nv_wr32(priv, 0x418a38, 0x0);
-	nv_wr32(priv, 0x418a40, 0x0);
-	nv_wr32(priv, 0x418a44, 0x0);
-	nv_wr32(priv, 0x418a48, 0x0);
-	nv_wr32(priv, 0x418a4c, 0x10000);
-	nv_wr32(priv, 0x418a50, 0x0);
-	nv_wr32(priv, 0x418a54, 0x0);
-	nv_wr32(priv, 0x418a58, 0x0);
-	nv_wr32(priv, 0x418a60, 0x0);
-	nv_wr32(priv, 0x418a64, 0x0);
-	nv_wr32(priv, 0x418a68, 0x0);
-	nv_wr32(priv, 0x418a6c, 0x10000);
-	nv_wr32(priv, 0x418a70, 0x0);
-	nv_wr32(priv, 0x418a74, 0x0);
-	nv_wr32(priv, 0x418a78, 0x0);
-	nv_wr32(priv, 0x418a80, 0x0);
-	nv_wr32(priv, 0x418a84, 0x0);
-	nv_wr32(priv, 0x418a88, 0x0);
-	nv_wr32(priv, 0x418a8c, 0x10000);
-	nv_wr32(priv, 0x418a90, 0x0);
-	nv_wr32(priv, 0x418a94, 0x0);
-	nv_wr32(priv, 0x418a98, 0x0);
-	nv_wr32(priv, 0x418aa0, 0x0);
-	nv_wr32(priv, 0x418aa4, 0x0);
-	nv_wr32(priv, 0x418aa8, 0x0);
-	nv_wr32(priv, 0x418aac, 0x10000);
-	nv_wr32(priv, 0x418ab0, 0x0);
-	nv_wr32(priv, 0x418ab4, 0x0);
-	nv_wr32(priv, 0x418ab8, 0x0);
-	nv_wr32(priv, 0x418ac0, 0x0);
-	nv_wr32(priv, 0x418ac4, 0x0);
-	nv_wr32(priv, 0x418ac8, 0x0);
-	nv_wr32(priv, 0x418acc, 0x10000);
-	nv_wr32(priv, 0x418ad0, 0x0);
-	nv_wr32(priv, 0x418ad4, 0x0);
-	nv_wr32(priv, 0x418ad8, 0x0);
-	nv_wr32(priv, 0x418ae0, 0x0);
-	nv_wr32(priv, 0x418ae4, 0x0);
-	nv_wr32(priv, 0x418ae8, 0x0);
-	nv_wr32(priv, 0x418aec, 0x10000);
-	nv_wr32(priv, 0x418af0, 0x0);
-	nv_wr32(priv, 0x418af4, 0x0);
-	nv_wr32(priv, 0x418af8, 0x0);
-	nv_wr32(priv, 0x418b00, 0x6);
-	nv_wr32(priv, 0x418b08, 0xa418820);
-	nv_wr32(priv, 0x418b0c, 0x62080e6);
-	nv_wr32(priv, 0x418b10, 0x20398a4);
-	nv_wr32(priv, 0x418b14, 0xe629062);
-	nv_wr32(priv, 0x418b18, 0xa418820);
-	nv_wr32(priv, 0x418b1c, 0xe6);
-	nv_wr32(priv, 0x418bb8, 0x103);
-	nv_wr32(priv, 0x418c08, 0x1);
-	nv_wr32(priv, 0x418c10, 0x0);
-	nv_wr32(priv, 0x418c14, 0x0);
-	nv_wr32(priv, 0x418c18, 0x0);
-	nv_wr32(priv, 0x418c1c, 0x0);
-	nv_wr32(priv, 0x418c20, 0x0);
-	nv_wr32(priv, 0x418c24, 0x0);
-	nv_wr32(priv, 0x418c28, 0x0);
-	nv_wr32(priv, 0x418c2c, 0x0);
-	nv_wr32(priv, 0x418c40, 0xffffffff);
-	nv_wr32(priv, 0x418c6c, 0x1);
-	nv_wr32(priv, 0x418c80, 0x20200004);
-	nv_wr32(priv, 0x418c8c, 0x1);
-	nv_wr32(priv, 0x419000, 0x780);
-	nv_wr32(priv, 0x419004, 0x0);
-	nv_wr32(priv, 0x419008, 0x0);
-	nv_wr32(priv, 0x419014, 0x4);
-}
-
-static void
-nve0_graph_generate_tpc(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x419848, 0x0);
-	nv_wr32(priv, 0x419864, 0x129);
-	nv_wr32(priv, 0x419888, 0x0);
-	nv_wr32(priv, 0x419a00, 0xf0);
-	nv_wr32(priv, 0x419a04, 0x1);
-	nv_wr32(priv, 0x419a08, 0x21);
-	nv_wr32(priv, 0x419a0c, 0x20000);
-	nv_wr32(priv, 0x419a10, 0x0);
-	nv_wr32(priv, 0x419a14, 0x200);
-	nv_wr32(priv, 0x419a1c, 0xc000);
-	nv_wr32(priv, 0x419a20, 0x800);
-	nv_wr32(priv, 0x419a30, 0x1);
-	nv_wr32(priv, 0x419ac4, 0x37f440);
-	nv_wr32(priv, 0x419c00, 0xa);
-	nv_wr32(priv, 0x419c04, 0x80000006);
-	nv_wr32(priv, 0x419c08, 0x2);
-	nv_wr32(priv, 0x419c20, 0x0);
-	nv_wr32(priv, 0x419c24, 0x84210);
-	nv_wr32(priv, 0x419c28, 0x3efbefbe);
-	nv_wr32(priv, 0x419ce8, 0x0);
-	nv_wr32(priv, 0x419cf4, 0x3203);
-	nv_wr32(priv, 0x419e04, 0x0);
-	nv_wr32(priv, 0x419e08, 0x0);
-	nv_wr32(priv, 0x419e0c, 0x0);
-	nv_wr32(priv, 0x419e10, 0x402);
-	nv_wr32(priv, 0x419e44, 0x13eff2);
-	nv_wr32(priv, 0x419e48, 0x0);
-	nv_wr32(priv, 0x419e4c, 0x7f);
-	nv_wr32(priv, 0x419e50, 0x0);
-	nv_wr32(priv, 0x419e54, 0x0);
-	nv_wr32(priv, 0x419e58, 0x0);
-	nv_wr32(priv, 0x419e5c, 0x0);
-	nv_wr32(priv, 0x419e60, 0x0);
-	nv_wr32(priv, 0x419e64, 0x0);
-	nv_wr32(priv, 0x419e68, 0x0);
-	nv_wr32(priv, 0x419e6c, 0x0);
-	nv_wr32(priv, 0x419e70, 0x0);
-	nv_wr32(priv, 0x419e74, 0x0);
-	nv_wr32(priv, 0x419e78, 0x0);
-	nv_wr32(priv, 0x419e7c, 0x0);
-	nv_wr32(priv, 0x419e80, 0x0);
-	nv_wr32(priv, 0x419e84, 0x0);
-	nv_wr32(priv, 0x419e88, 0x0);
-	nv_wr32(priv, 0x419e8c, 0x0);
-	nv_wr32(priv, 0x419e90, 0x0);
-	nv_wr32(priv, 0x419e94, 0x0);
-	nv_wr32(priv, 0x419e98, 0x0);
-	nv_wr32(priv, 0x419eac, 0x1fcf);
-	nv_wr32(priv, 0x419eb0, 0xd3f);
-	nv_wr32(priv, 0x419ec8, 0x1304f);
-	nv_wr32(priv, 0x419f30, 0x0);
-	nv_wr32(priv, 0x419f34, 0x0);
-	nv_wr32(priv, 0x419f38, 0x0);
-	nv_wr32(priv, 0x419f3c, 0x0);
-	nv_wr32(priv, 0x419f40, 0x0);
-	nv_wr32(priv, 0x419f44, 0x0);
-	nv_wr32(priv, 0x419f48, 0x0);
-	nv_wr32(priv, 0x419f4c, 0x0);
-	nv_wr32(priv, 0x419f58, 0x0);
-	nv_wr32(priv, 0x419f78, 0xb);
-}
-
-static void
-nve0_graph_generate_tpcunk(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x41be24, 0x6);
-	nv_wr32(priv, 0x41bec0, 0x12180000);
-	nv_wr32(priv, 0x41bec4, 0x37f7f);
-	nv_wr32(priv, 0x41bee4, 0x6480430);
-	nv_wr32(priv, 0x41bf00, 0xa418820);
-	nv_wr32(priv, 0x41bf04, 0x62080e6);
-	nv_wr32(priv, 0x41bf08, 0x20398a4);
-	nv_wr32(priv, 0x41bf0c, 0xe629062);
-	nv_wr32(priv, 0x41bf10, 0xa418820);
-	nv_wr32(priv, 0x41bf14, 0xe6);
-	nv_wr32(priv, 0x41bfd0, 0x900103);
-	nv_wr32(priv, 0x41bfe0, 0x400001);
-	nv_wr32(priv, 0x41bfe4, 0x0);
-}
-
-int
-nve0_grctx_generate(struct nvc0_graph_priv *priv)
-{
-	struct nvc0_grctx info;
-	int ret, i, gpc, tpc, id;
-	u32 data[6] = {}, data2[2] = {}, tmp;
-	u32 tpc_set = 0, tpc_mask = 0;
-	u32 magic[GPC_MAX][2], offset;
-	u8 tpcnr[GPC_MAX], a, b;
-	u8 shift, ntpcv;
-
-	ret = nvc0_grctx_init(priv, &info);
-	if (ret)
-		return ret;
-
-	nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
-	nv_wr32(priv, 0x400204, 0x00000000);
-	nv_wr32(priv, 0x400208, 0x00000000);
-
-	nve0_graph_generate_unk40xx(priv);
-	nve0_graph_generate_unk44xx(priv);
-	nve0_graph_generate_unk46xx(priv);
-	nve0_graph_generate_unk47xx(priv);
-	nve0_graph_generate_unk58xx(priv);
-	nve0_graph_generate_unk60xx(priv);
-	nve0_graph_generate_unk64xx(priv);
-	nve0_graph_generate_unk70xx(priv);
-	nve0_graph_generate_unk78xx(priv);
-	nve0_graph_generate_unk80xx(priv);
-	nve0_graph_generate_unk88xx(priv);
-	nve0_graph_generate_gpc(priv);
-	nve0_graph_generate_tpc(priv);
-	nve0_graph_generate_tpcunk(priv);
-
-	nv_wr32(priv, 0x404154, 0x0);
-
-	mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
-	mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
-	mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
-	mmio_list(0x40800c, 0x00000000,  8, 1);
-	mmio_list(0x408010, 0x80000000,  0, 0);
-	mmio_list(0x419004, 0x00000000,  8, 1);
-	mmio_list(0x419008, 0x00000000,  0, 0);
-	mmio_list(0x4064cc, 0x80000000,  0, 0);
-	mmio_list(0x408004, 0x00000000,  8, 0);
-	mmio_list(0x408008, 0x80000030,  0, 0);
-	mmio_list(0x418808, 0x00000000,  8, 0);
-	mmio_list(0x41880c, 0x80000030,  0, 0);
-	mmio_list(0x4064c8, 0x01800600,  0, 0);
-	mmio_list(0x418810, 0x80000000, 12, 2);
-	mmio_list(0x419848, 0x10000000, 12, 2);
-	mmio_list(0x405830, 0x02180648,  0, 0);
-	mmio_list(0x4064c4, 0x0192ffff,  0, 0);
-	for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
-		u16 magic0 = 0x0218 * priv->tpc_nr[gpc];
-		u16 magic1 = 0x0648 * priv->tpc_nr[gpc];
-		magic[gpc][0]  = 0x10000000 | (magic0 << 16) | offset;
-		magic[gpc][1]  = 0x00000000 | (magic1 << 16);
-		offset += 0x0324 * priv->tpc_nr[gpc];
-	}
-	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-		mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0);
-		mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0);
-		offset += 0x07ff * priv->tpc_nr[gpc];
-	}
-	mmio_list(0x17e91c, 0x06060609, 0, 0);
-	mmio_list(0x17e920, 0x00090a05, 0, 0);
-
-	nv_wr32(priv, 0x418c6c, 0x1);
-	nv_wr32(priv, 0x41980c, 0x10);
-	nv_wr32(priv, 0x41be08, 0x4);
-	nv_wr32(priv, 0x4064c0, 0x801a00f0);
-	nv_wr32(priv, 0x405800, 0xf8000bf);
-	nv_wr32(priv, 0x419c00, 0xa);
-
-	for (tpc = 0, id = 0; tpc < 4; tpc++) {
-		for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-			if (tpc < priv->tpc_nr[gpc]) {
-				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0698), id);
-				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x04e8), id);
-				nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id);
-				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0088), id++);
-			}
-
-			nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]);
-			nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]);
-		}
-	}
-
-	tmp = 0;
-	for (i = 0; i < priv->gpc_nr; i++)
-		tmp |= priv->tpc_nr[i] << (i * 4);
-	nv_wr32(priv, 0x406028, tmp);
-	nv_wr32(priv, 0x405870, tmp);
-
-	nv_wr32(priv, 0x40602c, 0x0);
-	nv_wr32(priv, 0x405874, 0x0);
-	nv_wr32(priv, 0x406030, 0x0);
-	nv_wr32(priv, 0x405878, 0x0);
-	nv_wr32(priv, 0x406034, 0x0);
-	nv_wr32(priv, 0x40587c, 0x0);
-
-	/* calculate first set of magics */
-	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
-
-	gpc = -1;
-	for (tpc = 0; tpc < priv->tpc_total; tpc++) {
-		do {
-			gpc = (gpc + 1) % priv->gpc_nr;
-		} while (!tpcnr[gpc]);
-		tpcnr[gpc]--;
-
-		data[tpc / 6] |= gpc << ((tpc % 6) * 5);
-	}
-
-	for (; tpc < 32; tpc++)
-		data[tpc / 6] |= 7 << ((tpc % 6) * 5);
-
-	/* and the second... */
-	shift = 0;
-	ntpcv = priv->tpc_total;
-	while (!(ntpcv & (1 << 4))) {
-		ntpcv <<= 1;
-		shift++;
-	}
-
-	data2[0]  = ntpcv << 16;
-	data2[0] |= shift << 21;
-	data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
-	data2[0] |= priv->tpc_total << 8;
-	data2[0] |= priv->magic_not_rop_nr;
-	for (i = 1; i < 7; i++)
-		data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
-
-	/* and write it all the various parts of PGRAPH */
-	nv_wr32(priv, 0x418bb8, (priv->tpc_total << 8) | priv->magic_not_rop_nr);
-	for (i = 0; i < 6; i++)
-		nv_wr32(priv, 0x418b08 + (i * 4), data[i]);
-
-	nv_wr32(priv, 0x41bfd0, data2[0]);
-	nv_wr32(priv, 0x41bfe4, data2[1]);
-	for (i = 0; i < 6; i++)
-		nv_wr32(priv, 0x41bf00 + (i * 4), data[i]);
-
-	nv_wr32(priv, 0x4078bc, (priv->tpc_total << 8) | priv->magic_not_rop_nr);
-	for (i = 0; i < 6; i++)
-		nv_wr32(priv, 0x40780c + (i * 4), data[i]);
-
-
-	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
-	for (gpc = 0; gpc < priv->gpc_nr; gpc++)
-		tpc_mask |= ((1 << priv->tpc_nr[gpc]) - 1) << (gpc * 8);
-
-	for (i = 0, gpc = -1, b = -1; i < 32; i++) {
-		a = (i * (priv->tpc_total - 1)) / 32;
-		if (a != b) {
-			b = a;
-			do {
-				gpc = (gpc + 1) % priv->gpc_nr;
-			} while (!tpcnr[gpc]);
-			tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
-
-			tpc_set |= 1 << ((gpc * 8) + tpc);
-		}
-
-		nv_wr32(priv, 0x406800 + (i * 0x20), tpc_set);
-		nv_wr32(priv, 0x406c00 + (i * 0x20), tpc_set ^ tpc_mask);
-	}
-
-	for (i = 0; i < 8; i++)
-		nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
-
-	nv_wr32(priv, 0x405b00, (priv->tpc_total << 8) | priv->gpc_nr);
-	if (priv->gpc_nr == 1) {
-		nv_mask(priv, 0x408850, 0x0000000f, priv->tpc_nr[0]);
-		nv_mask(priv, 0x408958, 0x0000000f, priv->tpc_nr[0]);
-	} else {
-		nv_mask(priv, 0x408850, 0x0000000f, priv->gpc_nr);
-		nv_mask(priv, 0x408958, 0x0000000f, priv->gpc_nr);
-	}
-	nv_mask(priv, 0x419f78, 0x00000001, 0x00000000);
-
-	nve0_grctx_generate_icmd(priv);
-	nve0_grctx_generate_a097(priv);
-	nve0_grctx_generate_902d(priv);
-
-	nv_mask(priv, 0x000260, 0x00000001, 0x00000001);
-	nv_wr32(priv, 0x418800, 0x7026860a); //XXX
-	nv_wr32(priv, 0x41be10, 0x00bb8bc7); //XXX
-	return nvc0_grctx_fini(&info);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1018 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+struct nvc0_graph_init
+nve4_grctx_init_icmd[] = {
+	{ 0x001000,   1, 0x01, 0x00000004 },
+	{ 0x000039,   3, 0x01, 0x00000000 },
+	{ 0x0000a9,   1, 0x01, 0x0000ffff },
+	{ 0x000038,   1, 0x01, 0x0fac6881 },
+	{ 0x00003d,   1, 0x01, 0x00000001 },
+	{ 0x0000e8,   8, 0x01, 0x00000400 },
+	{ 0x000078,   8, 0x01, 0x00000300 },
+	{ 0x000050,   1, 0x01, 0x00000011 },
+	{ 0x000058,   8, 0x01, 0x00000008 },
+	{ 0x000208,   8, 0x01, 0x00000001 },
+	{ 0x000081,   1, 0x01, 0x00000001 },
+	{ 0x000085,   1, 0x01, 0x00000004 },
+	{ 0x000088,   1, 0x01, 0x00000400 },
+	{ 0x000090,   1, 0x01, 0x00000300 },
+	{ 0x000098,   1, 0x01, 0x00001001 },
+	{ 0x0000e3,   1, 0x01, 0x00000001 },
+	{ 0x0000da,   1, 0x01, 0x00000001 },
+	{ 0x0000f8,   1, 0x01, 0x00000003 },
+	{ 0x0000fa,   1, 0x01, 0x00000001 },
+	{ 0x00009f,   4, 0x01, 0x0000ffff },
+	{ 0x0000b1,   1, 0x01, 0x00000001 },
+	{ 0x0000ad,   1, 0x01, 0x0000013e },
+	{ 0x0000e1,   1, 0x01, 0x00000010 },
+	{ 0x000290,  16, 0x01, 0x00000000 },
+	{ 0x0003b0,  16, 0x01, 0x00000000 },
+	{ 0x0002a0,  16, 0x01, 0x00000000 },
+	{ 0x000420,  16, 0x01, 0x00000000 },
+	{ 0x0002b0,  16, 0x01, 0x00000000 },
+	{ 0x000430,  16, 0x01, 0x00000000 },
+	{ 0x0002c0,  16, 0x01, 0x00000000 },
+	{ 0x0004d0,  16, 0x01, 0x00000000 },
+	{ 0x000720,  16, 0x01, 0x00000000 },
+	{ 0x0008c0,  16, 0x01, 0x00000000 },
+	{ 0x000890,  16, 0x01, 0x00000000 },
+	{ 0x0008e0,  16, 0x01, 0x00000000 },
+	{ 0x0008a0,  16, 0x01, 0x00000000 },
+	{ 0x0008f0,  16, 0x01, 0x00000000 },
+	{ 0x00094c,   1, 0x01, 0x000000ff },
+	{ 0x00094d,   1, 0x01, 0xffffffff },
+	{ 0x00094e,   1, 0x01, 0x00000002 },
+	{ 0x0002ec,   1, 0x01, 0x00000001 },
+	{ 0x000303,   1, 0x01, 0x00000001 },
+	{ 0x0002e6,   1, 0x01, 0x00000001 },
+	{ 0x000466,   1, 0x01, 0x00000052 },
+	{ 0x000301,   1, 0x01, 0x3f800000 },
+	{ 0x000304,   1, 0x01, 0x30201000 },
+	{ 0x000305,   1, 0x01, 0x70605040 },
+	{ 0x000306,   1, 0x01, 0xb8a89888 },
+	{ 0x000307,   1, 0x01, 0xf8e8d8c8 },
+	{ 0x00030a,   1, 0x01, 0x00ffff00 },
+	{ 0x00030b,   1, 0x01, 0x0000001a },
+	{ 0x00030c,   1, 0x01, 0x00000001 },
+	{ 0x000318,   1, 0x01, 0x00000001 },
+	{ 0x000340,   1, 0x01, 0x00000000 },
+	{ 0x000375,   1, 0x01, 0x00000001 },
+	{ 0x00037d,   1, 0x01, 0x00000006 },
+	{ 0x0003a0,   1, 0x01, 0x00000002 },
+	{ 0x0003aa,   1, 0x01, 0x00000001 },
+	{ 0x0003a9,   1, 0x01, 0x00000001 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000383,   1, 0x01, 0x00000011 },
+	{ 0x000360,   1, 0x01, 0x00000040 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00000fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x000fffff },
+	{ 0x00037a,   1, 0x01, 0x00000012 },
+	{ 0x000619,   1, 0x01, 0x00000003 },
+	{ 0x000811,   1, 0x01, 0x00000003 },
+	{ 0x000812,   1, 0x01, 0x00000004 },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000815,   1, 0x01, 0x0000000b },
+	{ 0x000800,   6, 0x01, 0x00000001 },
+	{ 0x000632,   1, 0x01, 0x00000001 },
+	{ 0x000633,   1, 0x01, 0x00000002 },
+	{ 0x000634,   1, 0x01, 0x00000003 },
+	{ 0x000635,   1, 0x01, 0x00000004 },
+	{ 0x000654,   1, 0x01, 0x3f800000 },
+	{ 0x000657,   1, 0x01, 0x3f800000 },
+	{ 0x000655,   2, 0x01, 0x3f800000 },
+	{ 0x0006cd,   1, 0x01, 0x3f800000 },
+	{ 0x0007f5,   1, 0x01, 0x3f800000 },
+	{ 0x0007dc,   1, 0x01, 0x39291909 },
+	{ 0x0007dd,   1, 0x01, 0x79695949 },
+	{ 0x0007de,   1, 0x01, 0xb9a99989 },
+	{ 0x0007df,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007e8,   1, 0x01, 0x00003210 },
+	{ 0x0007e9,   1, 0x01, 0x00007654 },
+	{ 0x0007ea,   1, 0x01, 0x00000098 },
+	{ 0x0007ec,   1, 0x01, 0x39291909 },
+	{ 0x0007ed,   1, 0x01, 0x79695949 },
+	{ 0x0007ee,   1, 0x01, 0xb9a99989 },
+	{ 0x0007ef,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007f0,   1, 0x01, 0x00003210 },
+	{ 0x0007f1,   1, 0x01, 0x00007654 },
+	{ 0x0007f2,   1, 0x01, 0x00000098 },
+	{ 0x0005a5,   1, 0x01, 0x00000001 },
+	{ 0x000980, 128, 0x01, 0x00000000 },
+	{ 0x000468,   1, 0x01, 0x00000004 },
+	{ 0x00046c,   1, 0x01, 0x00000001 },
+	{ 0x000470,  96, 0x01, 0x00000000 },
+	{ 0x000510,  16, 0x01, 0x3f800000 },
+	{ 0x000520,   1, 0x01, 0x000002b6 },
+	{ 0x000529,   1, 0x01, 0x00000001 },
+	{ 0x000530,  16, 0x01, 0xffff0000 },
+	{ 0x000585,   1, 0x01, 0x0000003f },
+	{ 0x000576,   1, 0x01, 0x00000003 },
+	{ 0x00057b,   1, 0x01, 0x00000059 },
+	{ 0x000586,   1, 0x01, 0x00000040 },
+	{ 0x000582,   2, 0x01, 0x00000080 },
+	{ 0x0005c2,   1, 0x01, 0x00000001 },
+	{ 0x000638,   1, 0x01, 0x00000001 },
+	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x00063a,   1, 0x01, 0x00000002 },
+	{ 0x00063b,   2, 0x01, 0x00000001 },
+	{ 0x00063d,   1, 0x01, 0x00000002 },
+	{ 0x00063e,   1, 0x01, 0x00000001 },
+	{ 0x0008b8,   8, 0x01, 0x00000001 },
+	{ 0x000900,   8, 0x01, 0x00000001 },
+	{ 0x000908,   8, 0x01, 0x00000002 },
+	{ 0x000910,  16, 0x01, 0x00000001 },
+	{ 0x000920,   8, 0x01, 0x00000002 },
+	{ 0x000928,   8, 0x01, 0x00000001 },
+	{ 0x000648,   9, 0x01, 0x00000001 },
+	{ 0x000658,   1, 0x01, 0x0000000f },
+	{ 0x0007ff,   1, 0x01, 0x0000000a },
+	{ 0x00066a,   1, 0x01, 0x40000000 },
+	{ 0x00066b,   1, 0x01, 0x10000000 },
+	{ 0x00066c,   2, 0x01, 0xffff0000 },
+	{ 0x0007af,   2, 0x01, 0x00000008 },
+	{ 0x0007f6,   1, 0x01, 0x00000001 },
+	{ 0x0006b2,   1, 0x01, 0x00000055 },
+	{ 0x0007ad,   1, 0x01, 0x00000003 },
+	{ 0x000937,   1, 0x01, 0x00000001 },
+	{ 0x000971,   1, 0x01, 0x00000008 },
+	{ 0x000972,   1, 0x01, 0x00000040 },
+	{ 0x000973,   1, 0x01, 0x0000012c },
+	{ 0x00097c,   1, 0x01, 0x00000040 },
+	{ 0x000979,   1, 0x01, 0x00000003 },
+	{ 0x000975,   1, 0x01, 0x00000020 },
+	{ 0x000976,   1, 0x01, 0x00000001 },
+	{ 0x000977,   1, 0x01, 0x00000020 },
+	{ 0x000978,   1, 0x01, 0x00000001 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095e,   1, 0x01, 0x20164010 },
+	{ 0x00095f,   1, 0x01, 0x00000020 },
+	{ 0x00097d,   1, 0x01, 0x00000020 },
+	{ 0x000683,   1, 0x01, 0x00000006 },
+	{ 0x000685,   1, 0x01, 0x003fffff },
+	{ 0x000687,   1, 0x01, 0x003fffff },
+	{ 0x0006a0,   1, 0x01, 0x00000005 },
+	{ 0x000840,   1, 0x01, 0x00400008 },
+	{ 0x000841,   1, 0x01, 0x08000080 },
+	{ 0x000842,   1, 0x01, 0x00400008 },
+	{ 0x000843,   1, 0x01, 0x08000080 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ab,   1, 0x01, 0x00000002 },
+	{ 0x0006ac,   1, 0x01, 0x00000080 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x0006bb,   1, 0x01, 0x000000cf },
+	{ 0x0006ce,   1, 0x01, 0x2a712488 },
+	{ 0x000739,   1, 0x01, 0x4085c000 },
+	{ 0x00073a,   1, 0x01, 0x00000080 },
+	{ 0x000786,   1, 0x01, 0x80000100 },
+	{ 0x00073c,   1, 0x01, 0x00010100 },
+	{ 0x00073d,   1, 0x01, 0x02800000 },
+	{ 0x000787,   1, 0x01, 0x000000cf },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x000836,   1, 0x01, 0x00000001 },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x000b07,   1, 0x01, 0x00000002 },
+	{ 0x000b08,   2, 0x01, 0x00000100 },
+	{ 0x000b0a,   1, 0x01, 0x00000001 },
+	{ 0x000a04,   1, 0x01, 0x000000ff },
+	{ 0x000a0b,   1, 0x01, 0x00000040 },
+	{ 0x00097f,   1, 0x01, 0x00000100 },
+	{ 0x000a02,   1, 0x01, 0x00000001 },
+	{ 0x000809,   1, 0x01, 0x00000007 },
+	{ 0x00c221,   1, 0x01, 0x00000040 },
+	{ 0x00c1b0,   8, 0x01, 0x0000000f },
+	{ 0x00c1b8,   1, 0x01, 0x0fac6881 },
+	{ 0x00c1b9,   1, 0x01, 0x00fac688 },
+	{ 0x00c401,   1, 0x01, 0x00000001 },
+	{ 0x00c402,   1, 0x01, 0x00010001 },
+	{ 0x00c403,   2, 0x01, 0x00000001 },
+	{ 0x00c40e,   1, 0x01, 0x00000020 },
+	{ 0x00c500,   1, 0x01, 0x00000003 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000002 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   1, 0x01, 0x00000001 },
+	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   1, 0x01, 0x00000001 },
+	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000008 },
+	{ 0x000039,   3, 0x01, 0x00000000 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00000fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x000fffff },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x000b07,   1, 0x01, 0x00000002 },
+	{ 0x000b08,   2, 0x01, 0x00000100 },
+	{ 0x000b0a,   1, 0x01, 0x00000001 },
+	{ 0x000a04,   1, 0x01, 0x000000ff },
+	{ 0x00097f,   1, 0x01, 0x00000100 },
+	{ 0x000a02,   1, 0x01, 0x00000001 },
+	{ 0x000809,   1, 0x01, 0x00000007 },
+	{ 0x00c221,   1, 0x01, 0x00000040 },
+	{ 0x00c401,   1, 0x01, 0x00000001 },
+	{ 0x00c402,   1, 0x01, 0x00010001 },
+	{ 0x00c403,   2, 0x01, 0x00000001 },
+	{ 0x00c40e,   1, 0x01, 0x00000020 },
+	{ 0x00c500,   1, 0x01, 0x00000003 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000001 },
+	{ 0x000b07,   1, 0x01, 0x00000002 },
+	{ 0x000b08,   2, 0x01, 0x00000100 },
+	{ 0x000b0a,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{}
+};
+
+struct nvc0_graph_init
+nve4_grctx_init_a097[] = {
+	{ 0x000800,   8, 0x40, 0x00000000 },
+	{ 0x000804,   8, 0x40, 0x00000000 },
+	{ 0x000808,   8, 0x40, 0x00000400 },
+	{ 0x00080c,   8, 0x40, 0x00000300 },
+	{ 0x000810,   1, 0x04, 0x000000cf },
+	{ 0x000850,   7, 0x40, 0x00000000 },
+	{ 0x000814,   8, 0x40, 0x00000040 },
+	{ 0x000818,   8, 0x40, 0x00000001 },
+	{ 0x00081c,   8, 0x40, 0x00000000 },
+	{ 0x000820,   8, 0x40, 0x00000000 },
+	{ 0x001c00,  16, 0x10, 0x00000000 },
+	{ 0x001c04,  16, 0x10, 0x00000000 },
+	{ 0x001c08,  16, 0x10, 0x00000000 },
+	{ 0x001c0c,  16, 0x10, 0x00000000 },
+	{ 0x001d00,  16, 0x10, 0x00000000 },
+	{ 0x001d04,  16, 0x10, 0x00000000 },
+	{ 0x001d08,  16, 0x10, 0x00000000 },
+	{ 0x001d0c,  16, 0x10, 0x00000000 },
+	{ 0x001f00,  16, 0x08, 0x00000000 },
+	{ 0x001f04,  16, 0x08, 0x00000000 },
+	{ 0x001f80,  16, 0x08, 0x00000000 },
+	{ 0x001f84,  16, 0x08, 0x00000000 },
+	{ 0x002000,   1, 0x04, 0x00000000 },
+	{ 0x002040,   1, 0x04, 0x00000011 },
+	{ 0x002080,   1, 0x04, 0x00000020 },
+	{ 0x0020c0,   1, 0x04, 0x00000030 },
+	{ 0x002100,   1, 0x04, 0x00000040 },
+	{ 0x002140,   1, 0x04, 0x00000051 },
+	{ 0x00200c,   6, 0x40, 0x00000001 },
+	{ 0x002010,   1, 0x04, 0x00000000 },
+	{ 0x002050,   1, 0x04, 0x00000000 },
+	{ 0x002090,   1, 0x04, 0x00000001 },
+	{ 0x0020d0,   1, 0x04, 0x00000002 },
+	{ 0x002110,   1, 0x04, 0x00000003 },
+	{ 0x002150,   1, 0x04, 0x00000004 },
+	{ 0x000380,   4, 0x20, 0x00000000 },
+	{ 0x000384,   4, 0x20, 0x00000000 },
+	{ 0x000388,   4, 0x20, 0x00000000 },
+	{ 0x00038c,   4, 0x20, 0x00000000 },
+	{ 0x000700,   4, 0x10, 0x00000000 },
+	{ 0x000704,   4, 0x10, 0x00000000 },
+	{ 0x000708,   4, 0x10, 0x00000000 },
+	{ 0x002800, 128, 0x04, 0x00000000 },
+	{ 0x000a00,  16, 0x20, 0x00000000 },
+	{ 0x000a04,  16, 0x20, 0x00000000 },
+	{ 0x000a08,  16, 0x20, 0x00000000 },
+	{ 0x000a0c,  16, 0x20, 0x00000000 },
+	{ 0x000a10,  16, 0x20, 0x00000000 },
+	{ 0x000a14,  16, 0x20, 0x00000000 },
+	{ 0x000c00,  16, 0x10, 0x00000000 },
+	{ 0x000c04,  16, 0x10, 0x00000000 },
+	{ 0x000c08,  16, 0x10, 0x00000000 },
+	{ 0x000c0c,  16, 0x10, 0x3f800000 },
+	{ 0x000d00,   8, 0x08, 0xffff0000 },
+	{ 0x000d04,   8, 0x08, 0xffff0000 },
+	{ 0x000e00,  16, 0x10, 0x00000000 },
+	{ 0x000e04,  16, 0x10, 0xffff0000 },
+	{ 0x000e08,  16, 0x10, 0xffff0000 },
+	{ 0x000d40,   4, 0x08, 0x00000000 },
+	{ 0x000d44,   4, 0x08, 0x00000000 },
+	{ 0x001e00,   8, 0x20, 0x00000001 },
+	{ 0x001e04,   8, 0x20, 0x00000001 },
+	{ 0x001e08,   8, 0x20, 0x00000002 },
+	{ 0x001e0c,   8, 0x20, 0x00000001 },
+	{ 0x001e10,   8, 0x20, 0x00000001 },
+	{ 0x001e14,   8, 0x20, 0x00000002 },
+	{ 0x001e18,   8, 0x20, 0x00000001 },
+	{ 0x003400, 128, 0x04, 0x00000000 },
+	{ 0x00030c,   1, 0x04, 0x00000001 },
+	{ 0x001944,   1, 0x04, 0x00000000 },
+	{ 0x001514,   1, 0x04, 0x00000000 },
+	{ 0x000d68,   1, 0x04, 0x0000ffff },
+	{ 0x00121c,   1, 0x04, 0x0fac6881 },
+	{ 0x000fac,   1, 0x04, 0x00000001 },
+	{ 0x001538,   1, 0x04, 0x00000001 },
+	{ 0x000fe0,   2, 0x04, 0x00000000 },
+	{ 0x000fe8,   1, 0x04, 0x00000014 },
+	{ 0x000fec,   1, 0x04, 0x00000040 },
+	{ 0x000ff0,   1, 0x04, 0x00000000 },
+	{ 0x00179c,   1, 0x04, 0x00000000 },
+	{ 0x001228,   1, 0x04, 0x00000400 },
+	{ 0x00122c,   1, 0x04, 0x00000300 },
+	{ 0x001230,   1, 0x04, 0x00010001 },
+	{ 0x0007f8,   1, 0x04, 0x00000000 },
+	{ 0x0015b4,   1, 0x04, 0x00000001 },
+	{ 0x0015cc,   1, 0x04, 0x00000000 },
+	{ 0x001534,   1, 0x04, 0x00000000 },
+	{ 0x000fb0,   1, 0x04, 0x00000000 },
+	{ 0x0015d0,   1, 0x04, 0x00000000 },
+	{ 0x00153c,   1, 0x04, 0x00000000 },
+	{ 0x0016b4,   1, 0x04, 0x00000003 },
+	{ 0x000fbc,   4, 0x04, 0x0000ffff },
+	{ 0x000df8,   2, 0x04, 0x00000000 },
+	{ 0x001948,   1, 0x04, 0x00000000 },
+	{ 0x001970,   1, 0x04, 0x00000001 },
+	{ 0x00161c,   1, 0x04, 0x000009f0 },
+	{ 0x000dcc,   1, 0x04, 0x00000010 },
+	{ 0x00163c,   1, 0x04, 0x00000000 },
+	{ 0x0015e4,   1, 0x04, 0x00000000 },
+	{ 0x001160,  32, 0x04, 0x25e00040 },
+	{ 0x001880,  32, 0x04, 0x00000000 },
+	{ 0x000f84,   2, 0x04, 0x00000000 },
+	{ 0x0017c8,   2, 0x04, 0x00000000 },
+	{ 0x0017d0,   1, 0x04, 0x000000ff },
+	{ 0x0017d4,   1, 0x04, 0xffffffff },
+	{ 0x0017d8,   1, 0x04, 0x00000002 },
+	{ 0x0017dc,   1, 0x04, 0x00000000 },
+	{ 0x0015f4,   2, 0x04, 0x00000000 },
+	{ 0x001434,   2, 0x04, 0x00000000 },
+	{ 0x000d74,   1, 0x04, 0x00000000 },
+	{ 0x000dec,   1, 0x04, 0x00000001 },
+	{ 0x0013a4,   1, 0x04, 0x00000000 },
+	{ 0x001318,   1, 0x04, 0x00000001 },
+	{ 0x001644,   1, 0x04, 0x00000000 },
+	{ 0x000748,   1, 0x04, 0x00000000 },
+	{ 0x000de8,   1, 0x04, 0x00000000 },
+	{ 0x001648,   1, 0x04, 0x00000000 },
+	{ 0x0012a4,   1, 0x04, 0x00000000 },
+	{ 0x001120,   4, 0x04, 0x00000000 },
+	{ 0x001118,   1, 0x04, 0x00000000 },
+	{ 0x00164c,   1, 0x04, 0x00000000 },
+	{ 0x001658,   1, 0x04, 0x00000000 },
+	{ 0x001910,   1, 0x04, 0x00000290 },
+	{ 0x001518,   1, 0x04, 0x00000000 },
+	{ 0x00165c,   1, 0x04, 0x00000001 },
+	{ 0x001520,   1, 0x04, 0x00000000 },
+	{ 0x001604,   1, 0x04, 0x00000000 },
+	{ 0x001570,   1, 0x04, 0x00000000 },
+	{ 0x0013b0,   2, 0x04, 0x3f800000 },
+	{ 0x00020c,   1, 0x04, 0x00000000 },
+	{ 0x001670,   1, 0x04, 0x30201000 },
+	{ 0x001674,   1, 0x04, 0x70605040 },
+	{ 0x001678,   1, 0x04, 0xb8a89888 },
+	{ 0x00167c,   1, 0x04, 0xf8e8d8c8 },
+	{ 0x00166c,   1, 0x04, 0x00000000 },
+	{ 0x001680,   1, 0x04, 0x00ffff00 },
+	{ 0x0012d0,   1, 0x04, 0x00000003 },
+	{ 0x0012d4,   1, 0x04, 0x00000002 },
+	{ 0x001684,   2, 0x04, 0x00000000 },
+	{ 0x000dac,   2, 0x04, 0x00001b02 },
+	{ 0x000db4,   1, 0x04, 0x00000000 },
+	{ 0x00168c,   1, 0x04, 0x00000000 },
+	{ 0x0015bc,   1, 0x04, 0x00000000 },
+	{ 0x00156c,   1, 0x04, 0x00000000 },
+	{ 0x00187c,   1, 0x04, 0x00000000 },
+	{ 0x001110,   1, 0x04, 0x00000001 },
+	{ 0x000dc0,   3, 0x04, 0x00000000 },
+	{ 0x001234,   1, 0x04, 0x00000000 },
+	{ 0x001690,   1, 0x04, 0x00000000 },
+	{ 0x0012ac,   1, 0x04, 0x00000001 },
+	{ 0x000790,   5, 0x04, 0x00000000 },
+	{ 0x00077c,   1, 0x04, 0x00000000 },
+	{ 0x001000,   1, 0x04, 0x00000010 },
+	{ 0x0010fc,   1, 0x04, 0x00000000 },
+	{ 0x001290,   1, 0x04, 0x00000000 },
+	{ 0x000218,   1, 0x04, 0x00000010 },
+	{ 0x0012d8,   1, 0x04, 0x00000000 },
+	{ 0x0012dc,   1, 0x04, 0x00000010 },
+	{ 0x000d94,   1, 0x04, 0x00000001 },
+	{ 0x00155c,   2, 0x04, 0x00000000 },
+	{ 0x001564,   1, 0x04, 0x00000fff },
+	{ 0x001574,   2, 0x04, 0x00000000 },
+	{ 0x00157c,   1, 0x04, 0x000fffff },
+	{ 0x001354,   1, 0x04, 0x00000000 },
+	{ 0x001610,   1, 0x04, 0x00000012 },
+	{ 0x001608,   2, 0x04, 0x00000000 },
+	{ 0x00260c,   1, 0x04, 0x00000000 },
+	{ 0x0007ac,   1, 0x04, 0x00000000 },
+	{ 0x00162c,   1, 0x04, 0x00000003 },
+	{ 0x000210,   1, 0x04, 0x00000000 },
+	{ 0x000320,   1, 0x04, 0x00000000 },
+	{ 0x000324,   6, 0x04, 0x3f800000 },
+	{ 0x000750,   1, 0x04, 0x00000000 },
+	{ 0x000760,   1, 0x04, 0x39291909 },
+	{ 0x000764,   1, 0x04, 0x79695949 },
+	{ 0x000768,   1, 0x04, 0xb9a99989 },
+	{ 0x00076c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x000770,   1, 0x04, 0x30201000 },
+	{ 0x000774,   1, 0x04, 0x70605040 },
+	{ 0x000778,   1, 0x04, 0x00009080 },
+	{ 0x000780,   1, 0x04, 0x39291909 },
+	{ 0x000784,   1, 0x04, 0x79695949 },
+	{ 0x000788,   1, 0x04, 0xb9a99989 },
+	{ 0x00078c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x0007d0,   1, 0x04, 0x30201000 },
+	{ 0x0007d4,   1, 0x04, 0x70605040 },
+	{ 0x0007d8,   1, 0x04, 0x00009080 },
+	{ 0x00037c,   1, 0x04, 0x00000001 },
+	{ 0x000740,   2, 0x04, 0x00000000 },
+	{ 0x002600,   1, 0x04, 0x00000000 },
+	{ 0x001918,   1, 0x04, 0x00000000 },
+	{ 0x00191c,   1, 0x04, 0x00000900 },
+	{ 0x001920,   1, 0x04, 0x00000405 },
+	{ 0x001308,   1, 0x04, 0x00000001 },
+	{ 0x001924,   1, 0x04, 0x00000000 },
+	{ 0x0013ac,   1, 0x04, 0x00000000 },
+	{ 0x00192c,   1, 0x04, 0x00000001 },
+	{ 0x00193c,   1, 0x04, 0x00002c1c },
+	{ 0x000d7c,   1, 0x04, 0x00000000 },
+	{ 0x000f8c,   1, 0x04, 0x00000000 },
+	{ 0x0002c0,   1, 0x04, 0x00000001 },
+	{ 0x001510,   1, 0x04, 0x00000000 },
+	{ 0x001940,   1, 0x04, 0x00000000 },
+	{ 0x000ff4,   2, 0x04, 0x00000000 },
+	{ 0x00194c,   2, 0x04, 0x00000000 },
+	{ 0x001968,   1, 0x04, 0x00000000 },
+	{ 0x001590,   1, 0x04, 0x0000003f },
+	{ 0x0007e8,   4, 0x04, 0x00000000 },
+	{ 0x00196c,   1, 0x04, 0x00000011 },
+	{ 0x0002e4,   1, 0x04, 0x0000b001 },
+	{ 0x00036c,   2, 0x04, 0x00000000 },
+	{ 0x00197c,   1, 0x04, 0x00000000 },
+	{ 0x000fcc,   2, 0x04, 0x00000000 },
+	{ 0x0002d8,   1, 0x04, 0x00000040 },
+	{ 0x001980,   1, 0x04, 0x00000080 },
+	{ 0x001504,   1, 0x04, 0x00000080 },
+	{ 0x001984,   1, 0x04, 0x00000000 },
+	{ 0x000300,   1, 0x04, 0x00000001 },
+	{ 0x0013a8,   1, 0x04, 0x00000000 },
+	{ 0x0012ec,   1, 0x04, 0x00000000 },
+	{ 0x001310,   1, 0x04, 0x00000000 },
+	{ 0x001314,   1, 0x04, 0x00000001 },
+	{ 0x001380,   1, 0x04, 0x00000000 },
+	{ 0x001384,   4, 0x04, 0x00000001 },
+	{ 0x001394,   1, 0x04, 0x00000000 },
+	{ 0x00139c,   1, 0x04, 0x00000000 },
+	{ 0x001398,   1, 0x04, 0x00000000 },
+	{ 0x001594,   1, 0x04, 0x00000000 },
+	{ 0x001598,   4, 0x04, 0x00000001 },
+	{ 0x000f54,   3, 0x04, 0x00000000 },
+	{ 0x0019bc,   1, 0x04, 0x00000000 },
+	{ 0x000f9c,   2, 0x04, 0x00000000 },
+	{ 0x0012cc,   1, 0x04, 0x00000000 },
+	{ 0x0012e8,   1, 0x04, 0x00000000 },
+	{ 0x00130c,   1, 0x04, 0x00000001 },
+	{ 0x001360,   8, 0x04, 0x00000000 },
+	{ 0x00133c,   2, 0x04, 0x00000001 },
+	{ 0x001344,   1, 0x04, 0x00000002 },
+	{ 0x001348,   2, 0x04, 0x00000001 },
+	{ 0x001350,   1, 0x04, 0x00000002 },
+	{ 0x001358,   1, 0x04, 0x00000001 },
+	{ 0x0012e4,   1, 0x04, 0x00000000 },
+	{ 0x00131c,   1, 0x04, 0x00000000 },
+	{ 0x001320,   3, 0x04, 0x00000000 },
+	{ 0x0019c0,   1, 0x04, 0x00000000 },
+	{ 0x001140,   1, 0x04, 0x00000000 },
+	{ 0x0019c4,   1, 0x04, 0x00000000 },
+	{ 0x0019c8,   1, 0x04, 0x00001500 },
+	{ 0x00135c,   1, 0x04, 0x00000000 },
+	{ 0x000f90,   1, 0x04, 0x00000000 },
+	{ 0x0019e0,   8, 0x04, 0x00000001 },
+	{ 0x0019cc,   1, 0x04, 0x00000001 },
+	{ 0x0015b8,   1, 0x04, 0x00000000 },
+	{ 0x001a00,   1, 0x04, 0x00001111 },
+	{ 0x001a04,   7, 0x04, 0x00000000 },
+	{ 0x000d6c,   2, 0x04, 0xffff0000 },
+	{ 0x0010f8,   1, 0x04, 0x00001010 },
+	{ 0x000d80,   5, 0x04, 0x00000000 },
+	{ 0x000da0,   1, 0x04, 0x00000000 },
+	{ 0x0007a4,   2, 0x04, 0x00000000 },
+	{ 0x001508,   1, 0x04, 0x80000000 },
+	{ 0x00150c,   1, 0x04, 0x40000000 },
+	{ 0x001668,   1, 0x04, 0x00000000 },
+	{ 0x000318,   2, 0x04, 0x00000008 },
+	{ 0x000d9c,   1, 0x04, 0x00000001 },
+	{ 0x000374,   1, 0x04, 0x00000000 },
+	{ 0x000378,   1, 0x04, 0x00000020 },
+	{ 0x0007dc,   1, 0x04, 0x00000000 },
+	{ 0x00074c,   1, 0x04, 0x00000055 },
+	{ 0x001420,   1, 0x04, 0x00000003 },
+	{ 0x0017bc,   2, 0x04, 0x00000000 },
+	{ 0x0017c4,   1, 0x04, 0x00000001 },
+	{ 0x001008,   1, 0x04, 0x00000008 },
+	{ 0x00100c,   1, 0x04, 0x00000040 },
+	{ 0x001010,   1, 0x04, 0x0000012c },
+	{ 0x000d60,   1, 0x04, 0x00000040 },
+	{ 0x00075c,   1, 0x04, 0x00000003 },
+	{ 0x001018,   1, 0x04, 0x00000020 },
+	{ 0x00101c,   1, 0x04, 0x00000001 },
+	{ 0x001020,   1, 0x04, 0x00000020 },
+	{ 0x001024,   1, 0x04, 0x00000001 },
+	{ 0x001444,   3, 0x04, 0x00000000 },
+	{ 0x000360,   1, 0x04, 0x20164010 },
+	{ 0x000364,   1, 0x04, 0x00000020 },
+	{ 0x000368,   1, 0x04, 0x00000000 },
+	{ 0x000de4,   1, 0x04, 0x00000000 },
+	{ 0x000204,   1, 0x04, 0x00000006 },
+	{ 0x000208,   1, 0x04, 0x00000000 },
+	{ 0x0002cc,   2, 0x04, 0x003fffff },
+	{ 0x001220,   1, 0x04, 0x00000005 },
+	{ 0x000fdc,   1, 0x04, 0x00000000 },
+	{ 0x000f98,   1, 0x04, 0x00400008 },
+	{ 0x001284,   1, 0x04, 0x08000080 },
+	{ 0x001450,   1, 0x04, 0x00400008 },
+	{ 0x001454,   1, 0x04, 0x08000080 },
+	{ 0x000214,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_grctx_init_unk40xx[] = {
+	{ 0x404010,   5, 0x04, 0x00000000 },
+	{ 0x404024,   1, 0x04, 0x0000e000 },
+	{ 0x404028,   1, 0x04, 0x00000000 },
+	{ 0x4040a8,   1, 0x04, 0x00000000 },
+	{ 0x4040ac,   7, 0x04, 0x00000000 },
+	{ 0x4040c8,   1, 0x04, 0xf800008f },
+	{ 0x4040d0,   6, 0x04, 0x00000000 },
+	{ 0x4040e8,   1, 0x04, 0x00001000 },
+	{ 0x4040f8,   1, 0x04, 0x00000000 },
+	{ 0x404130,   1, 0x04, 0x00000000 },
+	{ 0x404134,   1, 0x04, 0x00000000 },
+	{ 0x404138,   1, 0x04, 0x20000040 },
+	{ 0x404150,   1, 0x04, 0x0000002e },
+	{ 0x404154,   1, 0x04, 0x00000400 },
+	{ 0x404158,   1, 0x04, 0x00000200 },
+	{ 0x404164,   1, 0x04, 0x00000055 },
+	{ 0x4041a0,   4, 0x04, 0x00000000 },
+	{ 0x404200,   4, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nve4_grctx_init_unk46xx[] = {
+	{ 0x404604,   1, 0x04, 0x00000014 },
+	{ 0x404608,   1, 0x04, 0x00000000 },
+	{ 0x40460c,   1, 0x04, 0x00003fff },
+	{ 0x404610,   1, 0x04, 0x00000100 },
+	{ 0x404618,   4, 0x04, 0x00000000 },
+	{ 0x40462c,   2, 0x04, 0x00000000 },
+	{ 0x404640,   1, 0x04, 0x00000000 },
+	{ 0x404654,   1, 0x04, 0x00000000 },
+	{ 0x404660,   1, 0x04, 0x00000000 },
+	{ 0x404678,   1, 0x04, 0x00000000 },
+	{ 0x40467c,   1, 0x04, 0x00000002 },
+	{ 0x404680,   8, 0x04, 0x00000000 },
+	{ 0x4046a0,   1, 0x04, 0x007f0080 },
+	{ 0x4046a4,   8, 0x04, 0x00000000 },
+	{ 0x4046c8,   3, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nve4_grctx_init_unk47xx[] = {
+	{ 0x404700,   3, 0x04, 0x00000000 },
+	{ 0x404718,   7, 0x04, 0x00000000 },
+	{ 0x404734,   1, 0x04, 0x00000100 },
+	{ 0x404738,   2, 0x04, 0x00000000 },
+	{ 0x404744,   2, 0x04, 0x00000000 },
+	{ 0x404754,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nve4_grctx_init_unk58xx[] = {
+	{ 0x405800,   1, 0x04, 0x0f8000bf },
+	{ 0x405830,   1, 0x04, 0x02180648 },
+	{ 0x405834,   1, 0x04, 0x08000000 },
+	{ 0x405838,   1, 0x04, 0x00000000 },
+	{ 0x405854,   1, 0x04, 0x00000000 },
+	{ 0x405870,   4, 0x04, 0x00000001 },
+	{ 0x405a00,   2, 0x04, 0x00000000 },
+	{ 0x405a18,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_grctx_init_unk5bxx[] = {
+	{ 0x405b00,   1, 0x04, 0x00000000 },
+	{ 0x405b10,   1, 0x04, 0x00001000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_grctx_init_unk60xx[] = {
+	{ 0x406020,   1, 0x04, 0x004103c1 },
+	{ 0x406028,   4, 0x04, 0x00000001 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_grctx_init_unk64xx[] = {
+	{ 0x4064a8,   1, 0x04, 0x00000000 },
+	{ 0x4064ac,   1, 0x04, 0x00003fff },
+	{ 0x4064b4,   2, 0x04, 0x00000000 },
+	{ 0x4064c0,   1, 0x04, 0x801a00f0 },
+	{ 0x4064c4,   1, 0x04, 0x0192ffff },
+	{ 0x4064c8,   1, 0x04, 0x01800600 },
+	{ 0x4064cc,   9, 0x04, 0x00000000 },
+	{ 0x4064fc,   1, 0x04, 0x0000022a },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_grctx_init_unk70xx[] = {
+	{ 0x407040,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nve4_grctx_init_unk80xx[] = {
+	{ 0x408000,   2, 0x04, 0x00000000 },
+	{ 0x408008,   1, 0x04, 0x00000030 },
+	{ 0x40800c,   2, 0x04, 0x00000000 },
+	{ 0x408014,   1, 0x04, 0x00000069 },
+	{ 0x408018,   1, 0x04, 0xe100e100 },
+	{ 0x408064,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_grctx_init_rop[] = {
+	{ 0x408800,   1, 0x04, 0x02802a3c },
+	{ 0x408804,   1, 0x04, 0x00000040 },
+	{ 0x408808,   1, 0x04, 0x1043e005 },
+	{ 0x408840,   1, 0x04, 0x0000000b },
+	{ 0x408900,   1, 0x04, 0x3080b801 },
+	{ 0x408904,   1, 0x04, 0x62000001 },
+	{ 0x408908,   1, 0x04, 0x00c8102f },
+	{ 0x408980,   1, 0x04, 0x0000011d },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_grctx_init_gpc_0[] = {
+	{ 0x418380,   1, 0x04, 0x00000016 },
+	{ 0x418400,   1, 0x04, 0x38004e00 },
+	{ 0x418404,   1, 0x04, 0x71e0ffff },
+	{ 0x41840c,   1, 0x04, 0x00001008 },
+	{ 0x418410,   1, 0x04, 0x0fff0fff },
+	{ 0x418414,   1, 0x04, 0x02200fff },
+	{ 0x418450,   6, 0x04, 0x00000000 },
+	{ 0x418468,   1, 0x04, 0x00000001 },
+	{ 0x41846c,   2, 0x04, 0x00000000 },
+	{ 0x418600,   1, 0x04, 0x0000001f },
+	{ 0x418684,   1, 0x04, 0x0000000f },
+	{ 0x418700,   1, 0x04, 0x00000002 },
+	{ 0x418704,   1, 0x04, 0x00000080 },
+	{ 0x418708,   3, 0x04, 0x00000000 },
+	{ 0x418800,   1, 0x04, 0x7006860a },
+	{ 0x418808,   3, 0x04, 0x00000000 },
+	{ 0x418828,   1, 0x04, 0x00000044 },
+	{ 0x418830,   1, 0x04, 0x10000001 },
+	{ 0x4188d8,   1, 0x04, 0x00000008 },
+	{ 0x4188e0,   1, 0x04, 0x01000000 },
+	{ 0x4188e8,   5, 0x04, 0x00000000 },
+	{ 0x4188fc,   1, 0x04, 0x20100018 },
+	{ 0x41891c,   1, 0x04, 0x00ff00ff },
+	{ 0x418924,   1, 0x04, 0x00000000 },
+	{ 0x418928,   1, 0x04, 0x00ffff00 },
+	{ 0x41892c,   1, 0x04, 0x0000ff00 },
+	{ 0x418b00,   1, 0x04, 0x00000006 },
+	{ 0x418b08,   1, 0x04, 0x0a418820 },
+	{ 0x418b0c,   1, 0x04, 0x062080e6 },
+	{ 0x418b10,   1, 0x04, 0x020398a4 },
+	{ 0x418b14,   1, 0x04, 0x0e629062 },
+	{ 0x418b18,   1, 0x04, 0x0a418820 },
+	{ 0x418b1c,   1, 0x04, 0x000000e6 },
+	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{ 0x418c08,   1, 0x04, 0x00000001 },
+	{ 0x418c10,   8, 0x04, 0x00000000 },
+	{ 0x418c40,   1, 0x04, 0xffffffff },
+	{ 0x418c6c,   1, 0x04, 0x00000001 },
+	{ 0x418c80,   1, 0x04, 0x20200004 },
+	{ 0x418c8c,   1, 0x04, 0x00000001 },
+	{ 0x419000,   1, 0x04, 0x00000780 },
+	{ 0x419004,   2, 0x04, 0x00000000 },
+	{ 0x419014,   1, 0x04, 0x00000004 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_grctx_init_tpc[] = {
+	{ 0x419848,   1, 0x04, 0x00000000 },
+	{ 0x419864,   1, 0x04, 0x00000129 },
+	{ 0x419888,   1, 0x04, 0x00000000 },
+	{ 0x419a00,   1, 0x04, 0x000000f0 },
+	{ 0x419a04,   1, 0x04, 0x00000001 },
+	{ 0x419a08,   1, 0x04, 0x00000021 },
+	{ 0x419a0c,   1, 0x04, 0x00020000 },
+	{ 0x419a10,   1, 0x04, 0x00000000 },
+	{ 0x419a14,   1, 0x04, 0x00000200 },
+	{ 0x419a1c,   1, 0x04, 0x0000c000 },
+	{ 0x419a20,   1, 0x04, 0x00000800 },
+	{ 0x419a30,   1, 0x04, 0x00000001 },
+	{ 0x419ac4,   1, 0x04, 0x0037f440 },
+	{ 0x419c00,   1, 0x04, 0x0000000a },
+	{ 0x419c04,   1, 0x04, 0x80000006 },
+	{ 0x419c08,   1, 0x04, 0x00000002 },
+	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{ 0x419c24,   1, 0x04, 0x00084210 },
+	{ 0x419c28,   1, 0x04, 0x3efbefbe },
+	{ 0x419ce8,   1, 0x04, 0x00000000 },
+	{ 0x419cf4,   1, 0x04, 0x00003203 },
+	{ 0x419e04,   3, 0x04, 0x00000000 },
+	{ 0x419e10,   1, 0x04, 0x00000402 },
+	{ 0x419e44,   1, 0x04, 0x0013eff2 },
+	{ 0x419e48,   1, 0x04, 0x00000000 },
+	{ 0x419e4c,   1, 0x04, 0x0000007f },
+	{ 0x419e50,  19, 0x04, 0x00000000 },
+	{ 0x419eac,   1, 0x04, 0x00001f8f },
+	{ 0x419eb0,   1, 0x04, 0x00000d3f },
+	{ 0x419ec8,   1, 0x04, 0x0001304f },
+	{ 0x419f30,   8, 0x04, 0x00000000 },
+	{ 0x419f58,   1, 0x04, 0x00000000 },
+	{ 0x419f70,   1, 0x04, 0x00000000 },
+	{ 0x419f78,   1, 0x04, 0x0000000b },
+	{ 0x419f7c,   1, 0x04, 0x0000027a },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_grctx_init_unk[] = {
+	{ 0x41be24,   1, 0x04, 0x00000006 },
+	{ 0x41bec0,   1, 0x04, 0x12180000 },
+	{ 0x41bec4,   1, 0x04, 0x00037f7f },
+	{ 0x41bee4,   1, 0x04, 0x06480430 },
+	{ 0x41bf00,   1, 0x04, 0x0a418820 },
+	{ 0x41bf04,   1, 0x04, 0x062080e6 },
+	{ 0x41bf08,   1, 0x04, 0x020398a4 },
+	{ 0x41bf0c,   1, 0x04, 0x0e629062 },
+	{ 0x41bf10,   1, 0x04, 0x0a418820 },
+	{ 0x41bf14,   1, 0x04, 0x000000e6 },
+	{ 0x41bfd0,   1, 0x04, 0x00900103 },
+	{ 0x41bfe0,   1, 0x04, 0x00400001 },
+	{ 0x41bfe4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static void
+nve4_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+{
+	u32 magic[GPC_MAX][2];
+	u32 offset;
+	int gpc;
+
+	mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
+	mmio_list(0x40800c, 0x00000000,  8, 1);
+	mmio_list(0x408010, 0x80000000,  0, 0);
+	mmio_list(0x419004, 0x00000000,  8, 1);
+	mmio_list(0x419008, 0x00000000,  0, 0);
+	mmio_list(0x4064cc, 0x80000000,  0, 0);
+	mmio_list(0x408004, 0x00000000,  8, 0);
+	mmio_list(0x408008, 0x80000030,  0, 0);
+	mmio_list(0x418808, 0x00000000,  8, 0);
+	mmio_list(0x41880c, 0x80000030,  0, 0);
+	mmio_list(0x4064c8, 0x01800600,  0, 0);
+	mmio_list(0x418810, 0x80000000, 12, 2);
+	mmio_list(0x419848, 0x10000000, 12, 2);
+
+	mmio_list(0x405830, 0x02180648,  0, 0);
+	mmio_list(0x4064c4, 0x0192ffff,  0, 0);
+
+	for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
+		u16 magic0 = 0x0218 * priv->tpc_nr[gpc];
+		u16 magic1 = 0x0648 * priv->tpc_nr[gpc];
+		magic[gpc][0]  = 0x10000000 | (magic0 << 16) | offset;
+		magic[gpc][1]  = 0x00000000 | (magic1 << 16);
+		offset += 0x0324 * priv->tpc_nr[gpc];
+	}
+
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0);
+		mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0);
+		offset += 0x07ff * priv->tpc_nr[gpc];
+	}
+
+	mmio_list(0x17e91c, 0x06060609, 0, 0);
+	mmio_list(0x17e920, 0x00090a05, 0, 0);
+}
+
+void
+nve4_grctx_generate_unkn(struct nvc0_graph_priv *priv)
+{
+	nv_mask(priv, 0x418c6c, 0x00000001, 0x00000001);
+	nv_mask(priv, 0x41980c, 0x00000010, 0x00000010);
+	nv_mask(priv, 0x41be08, 0x00000004, 0x00000004);
+	nv_mask(priv, 0x4064c0, 0x80000000, 0x80000000);
+	nv_mask(priv, 0x405800, 0x08000000, 0x08000000);
+	nv_mask(priv, 0x419c00, 0x00000008, 0x00000008);
+}
+
+void
+nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *priv)
+{
+	u32 data[6] = {}, data2[2] = {};
+	u8  tpcnr[GPC_MAX];
+	u8  shift, ntpcv;
+	int gpc, tpc, i;
+
+	/* calculate first set of magics */
+	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+
+	gpc = -1;
+	for (tpc = 0; tpc < priv->tpc_total; tpc++) {
+		do {
+			gpc = (gpc + 1) % priv->gpc_nr;
+		} while (!tpcnr[gpc]);
+		tpcnr[gpc]--;
+
+		data[tpc / 6] |= gpc << ((tpc % 6) * 5);
+	}
+
+	for (; tpc < 32; tpc++)
+		data[tpc / 6] |= 7 << ((tpc % 6) * 5);
+
+	/* and the second... */
+	shift = 0;
+	ntpcv = priv->tpc_total;
+	while (!(ntpcv & (1 << 4))) {
+		ntpcv <<= 1;
+		shift++;
+	}
+
+	data2[0]  = (ntpcv << 16);
+	data2[0] |= (shift << 21);
+	data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24);
+	for (i = 1; i < 7; i++)
+		data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
+
+	/* GPC_BROADCAST */
+	nv_wr32(priv, 0x418bb8, (priv->tpc_total << 8) |
+				 priv->magic_not_rop_nr);
+	for (i = 0; i < 6; i++)
+		nv_wr32(priv, 0x418b08 + (i * 4), data[i]);
+
+	/* GPC_BROADCAST.TP_BROADCAST */
+	nv_wr32(priv, 0x41bfd0, (priv->tpc_total << 8) |
+				 priv->magic_not_rop_nr | data2[0]);
+	nv_wr32(priv, 0x41bfe4, data2[1]);
+	for (i = 0; i < 6; i++)
+		nv_wr32(priv, 0x41bf00 + (i * 4), data[i]);
+
+	/* UNK78xx */
+	nv_wr32(priv, 0x4078bc, (priv->tpc_total << 8) |
+				 priv->magic_not_rop_nr);
+	for (i = 0; i < 6; i++)
+		nv_wr32(priv, 0x40780c + (i * 4), data[i]);
+}
+
+void
+nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+{
+	struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
+	int i;
+
+	nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
+
+	for (i = 0; oclass->hub[i]; i++)
+		nvc0_graph_mmio(priv, oclass->hub[i]);
+	for (i = 0; oclass->gpc[i]; i++)
+		nvc0_graph_mmio(priv, oclass->gpc[i]);
+
+	nv_wr32(priv, 0x404154, 0x00000000);
+
+	oclass->mods(priv, info);
+	oclass->unkn(priv);
+
+	nvc0_grctx_generate_tpcid(priv);
+	nvc0_grctx_generate_r406028(priv);
+	nve4_grctx_generate_r418bb8(priv);
+	nvc0_grctx_generate_r406800(priv);
+
+	for (i = 0; i < 8; i++)
+		nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
+
+	nv_wr32(priv, 0x405b00, (priv->tpc_total << 8) | priv->gpc_nr);
+	if (priv->gpc_nr == 1) {
+		nv_mask(priv, 0x408850, 0x0000000f, priv->tpc_nr[0]);
+		nv_mask(priv, 0x408958, 0x0000000f, priv->tpc_nr[0]);
+	} else {
+		nv_mask(priv, 0x408850, 0x0000000f, priv->gpc_nr);
+		nv_mask(priv, 0x408958, 0x0000000f, priv->gpc_nr);
+	}
+	nv_mask(priv, 0x419f78, 0x00000001, 0x00000000);
+
+	nvc0_graph_icmd(priv, oclass->icmd);
+	nv_wr32(priv, 0x404154, 0x00000400);
+	nvc0_graph_mthd(priv, oclass->mthd);
+	nv_mask(priv, 0x000260, 0x00000001, 0x00000001);
+
+	nv_mask(priv, 0x418800, 0x00200000, 0x00200000);
+	nv_mask(priv, 0x41be10, 0x00800000, 0x00800000);
+}
+
+static struct nvc0_graph_init *
+nve4_grctx_init_hub[] = {
+	nvc0_grctx_init_base,
+	nve4_grctx_init_unk40xx,
+	nvc0_grctx_init_unk44xx,
+	nve4_grctx_init_unk46xx,
+	nve4_grctx_init_unk47xx,
+	nve4_grctx_init_unk58xx,
+	nve4_grctx_init_unk5bxx,
+	nve4_grctx_init_unk60xx,
+	nve4_grctx_init_unk64xx,
+	nve4_grctx_init_unk70xx,
+	nvc0_grctx_init_unk78xx,
+	nve4_grctx_init_unk80xx,
+	nve4_grctx_init_rop,
+	NULL
+};
+
+struct nvc0_graph_init *
+nve4_grctx_init_gpc[] = {
+	nve4_grctx_init_gpc_0,
+	nvc0_grctx_init_gpc_1,
+	nve4_grctx_init_tpc,
+	nve4_grctx_init_unk,
+	NULL
+};
+
+static struct nvc0_graph_mthd
+nve4_grctx_init_mthd[] = {
+	{ 0xa097, nve4_grctx_init_a097, },
+	{ 0x902d, nvc0_grctx_init_902d, },
+	{ 0x902d, nvc0_grctx_init_mthd_magic, },
+	{}
+};
+
+struct nouveau_oclass *
+nve4_grctx_oclass = &(struct nvc0_grctx_oclass) {
+	.base.handle = NV_ENGCTX(GR, 0xe4),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_context_ctor,
+		.dtor = nvc0_graph_context_dtor,
+		.init = _nouveau_graph_context_init,
+		.fini = _nouveau_graph_context_fini,
+		.rd32 = _nouveau_graph_context_rd32,
+		.wr32 = _nouveau_graph_context_wr32,
+	},
+	.main = nve4_grctx_generate_main,
+	.mods = nve4_grctx_generate_mods,
+	.unkn = nve4_grctx_generate_unkn,
+	.hub  = nve4_grctx_init_hub,
+	.gpc  = nve4_grctx_init_gpc,
+	.icmd = nve4_grctx_init_icmd,
+	.mthd = nve4_grctx_init_mthd,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+static struct nvc0_graph_init
+nvf0_grctx_init_unk40xx[] = {
+	{ 0x404004,   8, 0x04, 0x00000000 },
+	{ 0x404024,   1, 0x04, 0x0000e000 },
+	{ 0x404028,   8, 0x04, 0x00000000 },
+	{ 0x4040a8,   8, 0x04, 0x00000000 },
+	{ 0x4040c8,   1, 0x04, 0xf800008f },
+	{ 0x4040d0,   6, 0x04, 0x00000000 },
+	{ 0x4040e8,   1, 0x04, 0x00001000 },
+	{ 0x4040f8,   1, 0x04, 0x00000000 },
+	{ 0x404100,  10, 0x04, 0x00000000 },
+	{ 0x404130,   2, 0x04, 0x00000000 },
+	{ 0x404138,   1, 0x04, 0x20000040 },
+	{ 0x404150,   1, 0x04, 0x0000002e },
+	{ 0x404154,   1, 0x04, 0x00000400 },
+	{ 0x404158,   1, 0x04, 0x00000200 },
+	{ 0x404164,   1, 0x04, 0x00000055 },
+	{ 0x40417c,   2, 0x04, 0x00000000 },
+	{ 0x4041a0,   4, 0x04, 0x00000000 },
+	{ 0x404200,   1, 0x04, 0x0000a197 },
+	{ 0x404204,   1, 0x04, 0x0000a1c0 },
+	{ 0x404208,   1, 0x04, 0x0000a140 },
+	{ 0x40420c,   1, 0x04, 0x0000902d },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_grctx_init_unk44xx[] = {
+	{ 0x404404,  12, 0x04, 0x00000000 },
+	{ 0x404438,   1, 0x04, 0x00000000 },
+	{ 0x404460,   2, 0x04, 0x00000000 },
+	{ 0x404468,   1, 0x04, 0x00ffffff },
+	{ 0x40446c,   1, 0x04, 0x00000000 },
+	{ 0x404480,   1, 0x04, 0x00000001 },
+	{ 0x404498,   1, 0x04, 0x00000001 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_grctx_init_unk5bxx[] = {
+	{ 0x405b00,   1, 0x04, 0x00000000 },
+	{ 0x405b10,   1, 0x04, 0x00001000 },
+	{ 0x405b20,   1, 0x04, 0x04000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_grctx_init_unk60xx[] = {
+	{ 0x406020,   1, 0x04, 0x034103c1 },
+	{ 0x406028,   4, 0x04, 0x00000001 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_grctx_init_unk64xx[] = {
+	{ 0x4064a8,   1, 0x04, 0x00000000 },
+	{ 0x4064ac,   1, 0x04, 0x00003fff },
+	{ 0x4064b0,   3, 0x04, 0x00000000 },
+	{ 0x4064c0,   1, 0x04, 0x802000f0 },
+	{ 0x4064c4,   1, 0x04, 0x0192ffff },
+	{ 0x4064c8,   1, 0x04, 0x018007c0 },
+	{ 0x4064cc,   9, 0x04, 0x00000000 },
+	{ 0x4064fc,   1, 0x04, 0x0000022a },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_grctx_init_unk88xx[] = {
+	{ 0x408800,   1, 0x04, 0x12802a3c },
+	{ 0x408804,   1, 0x04, 0x00000040 },
+	{ 0x408808,   1, 0x04, 0x1003e005 },
+	{ 0x408840,   1, 0x04, 0x0000000b },
+	{ 0x408900,   1, 0x04, 0x3080b801 },
+	{ 0x408904,   1, 0x04, 0x62000001 },
+	{ 0x408908,   1, 0x04, 0x00c8102f },
+	{ 0x408980,   1, 0x04, 0x0000011d },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_grctx_init_gpc_0[] = {
+	{ 0x418380,   1, 0x04, 0x00000016 },
+	{ 0x418400,   1, 0x04, 0x38004e00 },
+	{ 0x418404,   1, 0x04, 0x71e0ffff },
+	{ 0x41840c,   1, 0x04, 0x00001008 },
+	{ 0x418410,   1, 0x04, 0x0fff0fff },
+	{ 0x418414,   1, 0x04, 0x02200fff },
+	{ 0x418450,   6, 0x04, 0x00000000 },
+	{ 0x418468,   1, 0x04, 0x00000001 },
+	{ 0x41846c,   2, 0x04, 0x00000000 },
+	{ 0x418600,   1, 0x04, 0x0000001f },
+	{ 0x418684,   1, 0x04, 0x0000000f },
+	{ 0x418700,   1, 0x04, 0x00000002 },
+	{ 0x418704,   1, 0x04, 0x00000080 },
+	{ 0x418708,   3, 0x04, 0x00000000 },
+	{ 0x418800,   1, 0x04, 0x7006860a },
+	{ 0x418808,   1, 0x04, 0x00000000 },
+	{ 0x41880c,   1, 0x04, 0x00000030 },
+	{ 0x418810,   1, 0x04, 0x00000000 },
+	{ 0x418828,   1, 0x04, 0x00000044 },
+	{ 0x418830,   1, 0x04, 0x10000001 },
+	{ 0x4188d8,   1, 0x04, 0x00000008 },
+	{ 0x4188e0,   1, 0x04, 0x01000000 },
+	{ 0x4188e8,   5, 0x04, 0x00000000 },
+	{ 0x4188fc,   1, 0x04, 0x20100018 },
+	{ 0x41891c,   1, 0x04, 0x00ff00ff },
+	{ 0x418924,   1, 0x04, 0x00000000 },
+	{ 0x418928,   1, 0x04, 0x00ffff00 },
+	{ 0x41892c,   1, 0x04, 0x0000ff00 },
+	{ 0x418b00,   1, 0x04, 0x00000006 },
+	{ 0x418b08,   1, 0x04, 0x0a418820 },
+	{ 0x418b0c,   1, 0x04, 0x062080e6 },
+	{ 0x418b10,   1, 0x04, 0x020398a4 },
+	{ 0x418b14,   1, 0x04, 0x0e629062 },
+	{ 0x418b18,   1, 0x04, 0x0a418820 },
+	{ 0x418b1c,   1, 0x04, 0x000000e6 },
+	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{ 0x418c08,   1, 0x04, 0x00000001 },
+	{ 0x418c10,   8, 0x04, 0x00000000 },
+	{ 0x418c40,   1, 0x04, 0xffffffff },
+	{ 0x418c6c,   1, 0x04, 0x00000001 },
+	{ 0x418c80,   1, 0x04, 0x20200004 },
+	{ 0x418c8c,   1, 0x04, 0x00000001 },
+	{ 0x418d24,   1, 0x04, 0x00000000 },
+	{ 0x419000,   1, 0x04, 0x00000780 },
+	{ 0x419004,   2, 0x04, 0x00000000 },
+	{ 0x419014,   1, 0x04, 0x00000004 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_grctx_init_tpc[] = {
+	{ 0x419848,   1, 0x04, 0x00000000 },
+	{ 0x419864,   1, 0x04, 0x00000129 },
+	{ 0x419888,   1, 0x04, 0x00000000 },
+	{ 0x419a00,   1, 0x04, 0x000000f0 },
+	{ 0x419a04,   1, 0x04, 0x00000001 },
+	{ 0x419a08,   1, 0x04, 0x00000021 },
+	{ 0x419a0c,   1, 0x04, 0x00020000 },
+	{ 0x419a10,   1, 0x04, 0x00000000 },
+	{ 0x419a14,   1, 0x04, 0x00000200 },
+	{ 0x419a1c,   1, 0x04, 0x0000c000 },
+	{ 0x419a20,   1, 0x04, 0x00020800 },
+	{ 0x419a30,   1, 0x04, 0x00000001 },
+	{ 0x419ac4,   1, 0x04, 0x0037f440 },
+	{ 0x419c00,   1, 0x04, 0x0000001a },
+	{ 0x419c04,   1, 0x04, 0x80000006 },
+	{ 0x419c08,   1, 0x04, 0x00000002 },
+	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{ 0x419c24,   1, 0x04, 0x00084210 },
+	{ 0x419c28,   1, 0x04, 0x3efbefbe },
+	{ 0x419ce8,   1, 0x04, 0x00000000 },
+	{ 0x419cf4,   1, 0x04, 0x00000203 },
+	{ 0x419e04,   1, 0x04, 0x00000000 },
+	{ 0x419e08,   1, 0x04, 0x0000001d },
+	{ 0x419e0c,   1, 0x04, 0x00000000 },
+	{ 0x419e10,   1, 0x04, 0x00001c02 },
+	{ 0x419e44,   1, 0x04, 0x0013eff2 },
+	{ 0x419e48,   1, 0x04, 0x00000000 },
+	{ 0x419e4c,   1, 0x04, 0x0000007f },
+	{ 0x419e50,   2, 0x04, 0x00000000 },
+	{ 0x419e58,   1, 0x04, 0x00000001 },
+	{ 0x419e5c,   3, 0x04, 0x00000000 },
+	{ 0x419e68,   1, 0x04, 0x00000002 },
+	{ 0x419e6c,  12, 0x04, 0x00000000 },
+	{ 0x419eac,   1, 0x04, 0x00001fcf },
+	{ 0x419eb0,   1, 0x04, 0x0db00da0 },
+	{ 0x419eb8,   1, 0x04, 0x00000000 },
+	{ 0x419ec8,   1, 0x04, 0x0001304f },
+	{ 0x419f30,   4, 0x04, 0x00000000 },
+	{ 0x419f40,   1, 0x04, 0x00000018 },
+	{ 0x419f44,   3, 0x04, 0x00000000 },
+	{ 0x419f58,   1, 0x04, 0x00000000 },
+	{ 0x419f70,   1, 0x04, 0x00007300 },
+	{ 0x419f78,   1, 0x04, 0x000000eb },
+	{ 0x419f7c,   1, 0x04, 0x00000404 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_grctx_init_unk[] = {
+	{ 0x41be24,   1, 0x04, 0x00000006 },
+	{ 0x41bec0,   1, 0x04, 0x10000000 },
+	{ 0x41bec4,   1, 0x04, 0x00037f7f },
+	{ 0x41bee4,   1, 0x04, 0x00000000 },
+	{ 0x41bf00,   1, 0x04, 0x0a418820 },
+	{ 0x41bf04,   1, 0x04, 0x062080e6 },
+	{ 0x41bf08,   1, 0x04, 0x020398a4 },
+	{ 0x41bf0c,   1, 0x04, 0x0e629062 },
+	{ 0x41bf10,   1, 0x04, 0x0a418820 },
+	{ 0x41bf14,   1, 0x04, 0x000000e6 },
+	{ 0x41bfd0,   1, 0x04, 0x00900103 },
+	{ 0x41bfe0,   1, 0x04, 0x00400001 },
+	{ 0x41bfe4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static void
+nvf0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+{
+	u32 magic[GPC_MAX][4];
+	u32 offset;
+	int gpc;
+
+	mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
+	mmio_list(0x40800c, 0x00000000,  8, 1);
+	mmio_list(0x408010, 0x80000000,  0, 0);
+	mmio_list(0x419004, 0x00000000,  8, 1);
+	mmio_list(0x419008, 0x00000000,  0, 0);
+	mmio_list(0x4064cc, 0x80000000,  0, 0);
+	mmio_list(0x408004, 0x00000000,  8, 0);
+	mmio_list(0x408008, 0x80000030,  0, 0);
+	mmio_list(0x418808, 0x00000000,  8, 0);
+	mmio_list(0x41880c, 0x80000030,  0, 0);
+	mmio_list(0x4064c8, 0x01800600,  0, 0);
+	mmio_list(0x418810, 0x80000000, 12, 2);
+	mmio_list(0x419848, 0x10000000, 12, 2);
+
+	mmio_list(0x405830, 0x02180648,  0, 0);
+	mmio_list(0x4064c4, 0x0192ffff,  0, 0);
+
+	for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
+		u16 magic0 = 0x0218 * (priv->tpc_nr[gpc] - 1);
+		u16 magic1 = 0x0648 * (priv->tpc_nr[gpc] - 1);
+		u16 magic2 = 0x0218;
+		u16 magic3 = 0x0648;
+		magic[gpc][0]  = 0x10000000 | (magic0 << 16) | offset;
+		magic[gpc][1]  = 0x00000000 | (magic1 << 16);
+		offset += 0x0324 * (priv->tpc_nr[gpc] - 1);;
+		magic[gpc][2]  = 0x10000000 | (magic2 << 16) | offset;
+		magic[gpc][3]  = 0x00000000 | (magic3 << 16);
+		offset += 0x0324;
+	}
+
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0);
+		mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0);
+		offset += 0x07ff * (priv->tpc_nr[gpc] - 1);
+		mmio_list(GPC_UNIT(gpc, 0x32c0), magic[gpc][2], 0, 0);
+		mmio_list(GPC_UNIT(gpc, 0x32e4), magic[gpc][3] | offset, 0, 0);
+		offset += 0x07ff;
+	}
+
+	mmio_list(0x17e91c, 0x06060609, 0, 0);
+	mmio_list(0x17e920, 0x00090a05, 0, 0);
+}
+
+static struct nvc0_graph_init *
+nvf0_grctx_init_hub[] = {
+	nvc0_grctx_init_base,
+	nvf0_grctx_init_unk40xx,
+	nvf0_grctx_init_unk44xx,
+	nve4_grctx_init_unk46xx,
+	nve4_grctx_init_unk47xx,
+	nve4_grctx_init_unk58xx,
+	nvf0_grctx_init_unk5bxx,
+	nvf0_grctx_init_unk60xx,
+	nvf0_grctx_init_unk64xx,
+	nve4_grctx_init_unk80xx,
+	nvf0_grctx_init_unk88xx,
+	nvd9_grctx_init_rop,
+	NULL
+};
+
+struct nvc0_graph_init *
+nvf0_grctx_init_gpc[] = {
+	nvf0_grctx_init_gpc_0,
+	nvc0_grctx_init_gpc_1,
+	nvf0_grctx_init_tpc,
+	nvf0_grctx_init_unk,
+	NULL
+};
+
+static struct nvc0_graph_mthd
+nvf0_grctx_init_mthd[] = {
+	{ 0xa197, nvc1_grctx_init_9097, },
+	{ 0x902d, nvc0_grctx_init_902d, },
+	{ 0x902d, nvc0_grctx_init_mthd_magic, },
+	{}
+};
+
+struct nouveau_oclass *
+nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) {
+	.base.handle = NV_ENGCTX(GR, 0xf0),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_context_ctor,
+		.dtor = nvc0_graph_context_dtor,
+		.init = _nouveau_graph_context_init,
+		.fini = _nouveau_graph_context_fini,
+		.rd32 = _nouveau_graph_context_rd32,
+		.wr32 = _nouveau_graph_context_wr32,
+	},
+	.main = nve4_grctx_generate_main,
+	.mods = nvf0_grctx_generate_mods,
+	.unkn = nve4_grctx_generate_unkn,
+	.hub  = nvf0_grctx_init_hub,
+	.gpc  = nvf0_grctx_init_gpc,
+	.icmd = nvc0_grctx_init_icmd,
+	.mthd = nvf0_grctx_init_mthd,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,375 @@
+/* fuc microcode util functions for nvc0 PGRAPH
+ *
+ * Copyright 2011 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#ifdef INCLUDE_CODE
+// queue_put - add request to queue
+//
+// In : $r13 queue pointer
+//	$r14 command
+//	$r15 data
+//
+queue_put:
+	// make sure we have space..
+	ld b32 $r8 D[$r13 + 0x0]	// GET
+	ld b32 $r9 D[$r13 + 0x4]	// PUT
+	xor $r8 8
+	cmpu b32 $r8 $r9
+	bra ne #queue_put_next
+		mov $r15 E_CMD_OVERFLOW
+		call #error
+		ret
+
+	// store cmd/data on queue
+	queue_put_next:
+	and $r8 $r9 7
+	shl b32 $r8 3
+	add b32 $r8 $r13
+	add b32 $r8 8
+	st b32 D[$r8 + 0x0] $r14
+	st b32 D[$r8 + 0x4] $r15
+
+	// update PUT
+	add b32 $r9 1
+	and $r9 0xf
+	st b32 D[$r13 + 0x4] $r9
+	ret
+
+// queue_get - fetch request from queue
+//
+// In : $r13 queue pointer
+//
+// Out:	$p1  clear on success (data available)
+//	$r14 command
+// 	$r15 data
+//
+queue_get:
+	bset $flags $p1
+	ld b32 $r8 D[$r13 + 0x0]	// GET
+	ld b32 $r9 D[$r13 + 0x4]	// PUT
+	cmpu b32 $r8 $r9
+	bra e #queue_get_done
+		// fetch first cmd/data pair
+		and $r9 $r8 7
+		shl b32 $r9 3
+		add b32 $r9 $r13
+		add b32 $r9 8
+		ld b32 $r14 D[$r9 + 0x0]
+		ld b32 $r15 D[$r9 + 0x4]
+
+		// update GET
+		add b32 $r8 1
+		and $r8 0xf
+		st b32 D[$r13 + 0x0] $r8
+		bclr $flags $p1
+queue_get_done:
+	ret
+
+// nv_rd32 - read 32-bit value from nv register
+//
+// In : $r14 register
+// Out: $r15 value
+//
+nv_rd32:
+	mov $r11 0x728
+	shl b32 $r11 6
+	mov b32 $r12 $r14
+	bset $r12 31			// MMIO_CTRL_PENDING
+	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
+	nv_rd32_wait:
+		iord $r12 I[$r11 + 0x000]
+		xbit $r12 $r12 31
+		bra ne #nv_rd32_wait
+	mov $r10 6			// DONE_MMIO_RD
+	call #wait_doneo
+	iord $r15 I[$r11 + 0x100]	// MMIO_RDVAL
+	ret
+
+// nv_wr32 - write 32-bit value to nv register
+//
+// In : $r14 register
+//      $r15 value
+//
+nv_wr32:
+	mov $r11 0x728
+	shl b32 $r11 6
+	iowr I[$r11 + 0x200] $r15	// MMIO_WRVAL
+	mov b32 $r12 $r14
+	bset $r12 31			// MMIO_CTRL_PENDING
+	bset $r12 30			// MMIO_CTRL_WRITE
+	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
+	nv_wr32_wait:
+		iord $r12 I[$r11 + 0x000]
+		xbit $r12 $r12 31
+		bra ne #nv_wr32_wait
+	ret
+
+// (re)set watchdog timer
+//
+// In : $r15 timeout
+//
+watchdog_reset:
+	mov $r8 0x430
+	shl b32 $r8 6
+	bset $r15 31
+	iowr I[$r8 + 0x000] $r15
+	ret
+
+// clear watchdog timer
+watchdog_clear:
+	mov $r8 0x430
+	shl b32 $r8 6
+	iowr I[$r8 + 0x000] $r0
+	ret
+
+// wait_donez - wait on FUC_DONE bit to become clear
+//
+// In : $r10 bit to wait on
+//
+wait_donez:
+	trace_set(T_WAIT);
+	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)
+	wait_donez_ne:
+		nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)
+		xbit $r8 $r8 $r10
+		bra ne #wait_donez_ne
+	trace_clr(T_WAIT)
+	ret
+
+// wait_doneo - wait on FUC_DONE bit to become set
+//
+// In : $r10 bit to wait on
+//
+wait_doneo:
+	trace_set(T_WAIT);
+	mov $r8 0x818
+	shl b32 $r8 6
+	iowr I[$r8 + 0x000] $r10
+	wait_doneo_e:
+		mov $r8 0x400
+		shl b32 $r8 6
+		iord $r8 I[$r8 + 0x000]
+		xbit $r8 $r8 $r10
+		bra e #wait_doneo_e
+	trace_clr(T_WAIT)
+	ret
+
+// mmctx_size - determine size of a mmio list transfer
+//
+// In : $r14 mmio list head
+//      $r15 mmio list tail
+// Out: $r15 transfer size (in bytes)
+//
+mmctx_size:
+	clear b32 $r9
+	nv_mmctx_size_loop:
+		ld b32 $r8 D[$r14]
+		shr b32 $r8 26
+		add b32 $r8 1
+		shl b32 $r8 2
+		add b32 $r9 $r8
+		add b32 $r14 4
+		cmpu b32 $r14 $r15
+		bra ne #nv_mmctx_size_loop
+	mov b32 $r15 $r9
+	ret
+
+// mmctx_xfer - execute a list of mmio transfers
+//
+// In : $r10 flags
+//		bit 0: direction (0 = save, 1 = load)
+//		bit 1: set if first transfer
+//		bit 2: set if last transfer
+//	$r11 base
+//	$r12 mmio list head
+//	$r13 mmio list tail
+//	$r14 multi_stride
+//	$r15 multi_mask
+//
+mmctx_xfer:
+	trace_set(T_MMCTX)
+	mov $r8 0x710
+	shl b32 $r8 6
+	clear b32 $r9
+	or $r11 $r11
+	bra e #mmctx_base_disabled
+		iowr I[$r8 + 0x000] $r11	// MMCTX_BASE
+		bset $r9 0			// BASE_EN
+	mmctx_base_disabled:
+	or $r14 $r14
+	bra e #mmctx_multi_disabled
+		iowr I[$r8 + 0x200] $r14 	// MMCTX_MULTI_STRIDE
+		iowr I[$r8 + 0x300] $r15 	// MMCTX_MULTI_MASK
+		bset $r9 1			// MULTI_EN
+	mmctx_multi_disabled:
+	add b32 $r8 0x100
+
+	xbit $r11 $r10 0
+	shl b32 $r11 16			// DIR
+	bset $r11 12			// QLIMIT = 0x10
+	xbit $r14 $r10 1
+	shl b32 $r14 17
+	or $r11 $r14			// START_TRIGGER
+	iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
+
+	// loop over the mmio list, and send requests to the hw
+	mmctx_exec_loop:
+		// wait for space in mmctx queue
+		mmctx_wait_free:
+			iord $r14 I[$r8 + 0x000] // MMCTX_CTRL
+			and $r14 0x1f
+			bra e #mmctx_wait_free
+
+		// queue up an entry
+		ld b32 $r14 D[$r12]
+		or $r14 $r9
+		iowr I[$r8 + 0x300] $r14
+		add b32 $r12 4
+		cmpu b32 $r12 $r13
+		bra ne #mmctx_exec_loop
+
+	xbit $r11 $r10 2
+	bra ne #mmctx_stop
+		// wait for queue to empty
+		mmctx_fini_wait:
+			iord $r11 I[$r8 + 0x000]	// MMCTX_CTRL
+			and $r11 0x1f
+			cmpu b32 $r11 0x10
+			bra ne #mmctx_fini_wait
+		mov $r10 2				// DONE_MMCTX
+		call #wait_donez
+		bra #mmctx_done
+	mmctx_stop:
+		xbit $r11 $r10 0
+		shl b32 $r11 16			// DIR
+		bset $r11 12			// QLIMIT = 0x10
+		bset $r11 18			// STOP_TRIGGER
+		iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
+		mmctx_stop_wait:
+			// wait for STOP_TRIGGER to clear
+			iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
+			xbit $r11 $r11 18
+			bra ne #mmctx_stop_wait
+	mmctx_done:
+	trace_clr(T_MMCTX)
+	ret
+
+// Wait for DONE_STRAND
+//
+strand_wait:
+	push $r10
+	mov $r10 2
+	call #wait_donez
+	pop $r10
+	ret
+
+// unknown - call before issuing strand commands
+//
+strand_pre:
+	mov $r8 0x4afc
+	sethi $r8 0x20000
+	mov $r9 0xc
+	iowr I[$r8] $r9
+	call #strand_wait
+	ret
+
+// unknown - call after issuing strand commands
+//
+strand_post:
+	mov $r8 0x4afc
+	sethi $r8 0x20000
+	mov $r9 0xd
+	iowr I[$r8] $r9
+	call #strand_wait
+	ret
+
+// Selects strand set?!
+//
+// In: $r14 id
+//
+strand_set:
+	mov $r10 0x4ffc
+	sethi $r10 0x20000
+	sub b32 $r11 $r10 0x500
+	mov $r12 0xf
+	iowr I[$r10 + 0x000] $r12		// 0x93c = 0xf
+	mov $r12 0xb
+	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xb
+	call #strand_wait
+	iowr I[$r10 + 0x000] $r14		// 0x93c = <id>
+	mov $r12 0xa
+	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xa
+	call #strand_wait
+	ret
+
+// Initialise strand context data
+//
+// In : $r15 context base
+// Out: $r15 context size (in bytes)
+//
+// Strandset(?) 3 hardcoded currently
+//
+strand_ctx_init:
+	trace_set(T_STRINIT)
+	call #strand_pre
+	mov $r14 3
+	call #strand_set
+	mov $r10 0x46fc
+	sethi $r10 0x20000
+	add b32 $r11 $r10 0x400
+	iowr I[$r10 + 0x100] $r0	// STRAND_FIRST_GENE = 0
+	mov $r12 1
+	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_FIRST_GENE
+	call #strand_wait
+	sub b32 $r12 $r0 1
+	iowr I[$r10 + 0x000] $r12	// STRAND_GENE_CNT = 0xffffffff
+	mov $r12 2
+	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_GENE_CNT
+	call #strand_wait
+	call #strand_post
+
+	// read the size of each strand, poke the context offset of
+	// each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
+	// about it later then.
+	mov $r8 0x880
+	shl b32 $r8 6
+	iord $r9 I[$r8 + 0x000]		// STRANDS
+	add b32 $r8 0x2200
+	shr b32 $r14 $r15 8
+	ctx_init_strand_loop:
+		iowr I[$r8 + 0x000] $r14	// STRAND_SAVE_SWBASE
+		iowr I[$r8 + 0x100] $r14	// STRAND_LOAD_SWBASE
+		iord $r10 I[$r8 + 0x200]	// STRAND_SIZE
+		shr b32 $r10 6
+		add b32 $r10 1
+		add b32 $r14 $r10
+		add b32 $r8 4
+		sub b32 $r9 1
+		bra ne #ctx_init_strand_loop
+
+	shl b32 $r14 8
+	sub b32 $r15 $r14 $r15
+	trace_clr(T_STRINIT)
+	ret
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,404 @@
+/* fuc microcode for nvc0 PGRAPH/GPC
+ *
+ * Copyright 2011 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+/* TODO
+ * - bracket certain functions with scratch writes, useful for debugging
+ * - watchdog timer around ctx operations
+ */
+
+#ifdef INCLUDE_DATA
+gpc_mmio_list_head:	.b32 #mmio_list_base
+gpc_mmio_list_tail:
+tpc_mmio_list_head:	.b32 #mmio_list_base
+tpc_mmio_list_tail:
+unk_mmio_list_head:	.b32 #mmio_list_base
+unk_mmio_list_tail:	.b32 #mmio_list_base
+
+gpc_id:			.b32 0
+
+tpc_count:		.b32 0
+tpc_mask:		.b32 0
+
+#if NV_PGRAPH_GPCX_UNK__SIZE > 0
+unk_count:		.b32 0
+unk_mask:		.b32 0
+#endif
+
+cmd_queue:		queue_init
+
+mmio_list_base:
+#endif
+
+#ifdef INCLUDE_CODE
+// reports an exception to the host
+//
+// In: $r15 error code (see nvc0.fuc)
+//
+error:
+	push $r14
+	mov $r14 -0x67ec 	// 0x9814
+	sethi $r14 0x400000
+	call #nv_wr32		// HUB_CTXCTL_CC_SCRATCH[5] = error code
+	add b32 $r14 0x41c
+	mov $r15 1
+	call #nv_wr32		// HUB_CTXCTL_INTR_UP_SET
+	pop $r14
+	ret
+
+// GPC fuc initialisation, executed by triggering ucode start, will
+// fall through to main loop after completion.
+//
+// Input:
+//   CC_SCRATCH[1]: context base
+//
+// Output:
+//   CC_SCRATCH[0]:
+//	     31:31: set to signal completion
+//   CC_SCRATCH[1]:
+//	      31:0: GPC context size
+//
+init:
+	clear b32 $r0
+	mov $sp $r0
+
+	// enable fifo access
+	mov $r1 0x1200
+	mov $r2 2
+	iowr I[$r1 + 0x000] $r2		// FIFO_ENABLE
+
+	// setup i0 handler, and route all interrupts to it
+	mov $r1 #ih
+	mov $iv0 $r1
+	mov $r1 0x400
+	iowr I[$r1 + 0x300] $r0		// INTR_DISPATCH
+
+	// enable fifo interrupt
+	mov $r2 4
+	iowr I[$r1 + 0x000] $r2		// INTR_EN_SET
+
+	// enable interrupts
+	bset $flags ie0
+
+	// figure out which GPC we are, and how many TPCs we have
+	mov $r1 0x608
+	shl b32 $r1 6
+	iord $r2 I[$r1 + 0x000]		// UNITS
+	mov $r3 1
+	and $r2 0x1f
+	shl b32 $r3 $r2
+	sub b32 $r3 1
+	st b32 D[$r0 + #tpc_count] $r2
+	st b32 D[$r0 + #tpc_mask] $r3
+	add b32 $r1 0x400
+	iord $r2 I[$r1 + 0x000]		// MYINDEX
+	st b32 D[$r0 + #gpc_id] $r2
+
+#if NV_PGRAPH_GPCX_UNK__SIZE > 0
+	// figure out which, and how many, UNKs are actually present
+	mov $r14 0x0c30
+	sethi $r14 0x500000
+	clear b32 $r2
+	clear b32 $r3
+	clear b32 $r4
+	init_unk_loop:
+		call #nv_rd32
+		cmp b32 $r15 0
+		bra z #init_unk_next
+			mov $r15 1
+			shl b32 $r15 $r2
+			or $r4 $r15
+			add b32 $r3 1
+		init_unk_next:
+		add b32 $r2 1
+		add b32 $r14 4
+		cmp b32 $r2 NV_PGRAPH_GPCX_UNK__SIZE
+		bra ne #init_unk_loop
+	init_unk_done:
+	st b32 D[$r0 + #unk_count] $r3
+	st b32 D[$r0 + #unk_mask] $r4
+#endif
+
+	// initialise context base, and size tracking
+	nv_iord($r2, NV_PGRAPH_GPCX_GPCCS_CC_SCRATCH_VAL(1), 0)
+	clear b32 $r3		// track GPC context size here
+
+	// set mmctx base addresses now so we don't have to do it later,
+	// they don't currently ever change
+	mov $r4 0x700
+	shl b32 $r4 6
+	shr b32 $r5 $r2 8
+	iowr I[$r4 + 0x000] $r5		// MMCTX_SAVE_SWBASE
+	iowr I[$r4 + 0x100] $r5		// MMCTX_LOAD_SWBASE
+
+	// calculate GPC mmio context size
+	ld b32 $r14 D[$r0 + #gpc_mmio_list_head]
+	ld b32 $r15 D[$r0 + #gpc_mmio_list_tail]
+	call #mmctx_size
+	add b32 $r2 $r15
+	add b32 $r3 $r15
+
+	// calculate per-TPC mmio context size
+	ld b32 $r14 D[$r0 + #tpc_mmio_list_head]
+	ld b32 $r15 D[$r0 + #tpc_mmio_list_tail]
+	call #mmctx_size
+	ld b32 $r14 D[$r0 + #tpc_count]
+	mulu $r14 $r15
+	add b32 $r2 $r14
+	add b32 $r3 $r14
+
+#if NV_PGRAPH_GPCX_UNK__SIZE > 0
+	// calculate per-UNK mmio context size
+	ld b32 $r14 D[$r0 + #unk_mmio_list_head]
+	ld b32 $r15 D[$r0 + #unk_mmio_list_tail]
+	call #mmctx_size
+	ld b32 $r14 D[$r0 + #unk_count]
+	mulu $r14 $r15
+	add b32 $r2 $r14
+	add b32 $r3 $r14
+#endif
+
+	// round up base/size to 256 byte boundary (for strand SWBASE)
+	add b32 $r4 0x1300
+	shr b32 $r3 2
+	iowr I[$r4 + 0x000] $r3		// MMCTX_LOAD_COUNT, wtf for?!?
+	shr b32 $r2 8
+	shr b32 $r3 6
+	add b32 $r2 1
+	add b32 $r3 1
+	shl b32 $r2 8
+	shl b32 $r3 8
+
+	// calculate size of strand context data
+	mov b32 $r15 $r2
+	call #strand_ctx_init
+	add b32 $r3 $r15
+
+	// save context size, and tell HUB we're done
+	nv_iowr(NV_PGRAPH_GPCX_GPCCS_CC_SCRATCH_VAL(1), 0, $r3)
+	clear b32 $r2
+	bset $r2 31
+	nv_iowr(NV_PGRAPH_GPCX_GPCCS_CC_SCRATCH_SET(0), 0, $r2)
+
+// Main program loop, very simple, sleeps until woken up by the interrupt
+// handler, pulls a command from the queue and executes its handler
+//
+main:
+	bset $flags $p0
+	sleep $p0
+	mov $r13 #cmd_queue
+	call #queue_get
+	bra $p1 #main
+
+	// 0x0000-0x0003 are all context transfers
+	cmpu b32 $r14 0x04
+	bra nc #main_not_ctx_xfer
+		// fetch $flags and mask off $p1/$p2
+		mov $r1 $flags
+		mov $r2 0x0006
+		not b32 $r2
+		and $r1 $r2
+		// set $p1/$p2 according to transfer type
+		shl b32 $r14 1
+		or $r1 $r14
+		mov $flags $r1
+		// transfer context data
+		call #ctx_xfer
+		bra #main
+
+	main_not_ctx_xfer:
+	shl b32 $r15 $r14 16
+	or $r15 E_BAD_COMMAND
+	call #error
+	bra #main
+
+// interrupt handler
+ih:
+	push $r8
+	mov $r8 $flags
+	push $r8
+	push $r9
+	push $r10
+	push $r11
+	push $r13
+	push $r14
+	push $r15
+	clear b32 $r0
+
+	// incoming fifo command?
+	iord $r10 I[$r0 + 0x200]	// INTR
+	and $r11 $r10 0x00000004
+	bra e #ih_no_fifo
+		// queue incoming fifo command for later processing
+		mov $r11 0x1900
+		mov $r13 #cmd_queue
+		iord $r14 I[$r11 + 0x100]	// FIFO_CMD
+		iord $r15 I[$r11 + 0x000]	// FIFO_DATA
+		call #queue_put
+		add b32 $r11 0x400
+		mov $r14 1
+		iowr I[$r11 + 0x000] $r14	// FIFO_ACK
+
+	// ack, and wake up main()
+	ih_no_fifo:
+	iowr I[$r0 + 0x100] $r10	// INTR_ACK
+
+	pop $r15
+	pop $r14
+	pop $r13
+	pop $r11
+	pop $r10
+	pop $r9
+	pop $r8
+	mov $flags $r8
+	pop $r8
+	bclr $flags $p0
+	iret
+
+// Set this GPC's bit in HUB_BAR, used to signal completion of various
+// activities to the HUB fuc
+//
+hub_barrier_done:
+	mov $r15 1
+	ld b32 $r14 D[$r0 + #gpc_id]
+	shl b32 $r15 $r14
+	mov $r14 -0x6be8 	// 0x409418 - HUB_BAR_SET
+	sethi $r14 0x400000
+	call #nv_wr32
+	ret
+
+// Disables various things, waits a bit, and re-enables them..
+//
+// Not sure how exactly this helps, perhaps "ENABLE" is not such a
+// good description for the bits we turn off?  Anyways, without this,
+// funny things happen.
+//
+ctx_redswitch:
+	mov $r14 0x614
+	shl b32 $r14 6
+	mov $r15 0x020
+	iowr I[$r14] $r15	// GPC_RED_SWITCH = POWER
+	mov $r15 8
+	ctx_redswitch_delay:
+		sub b32 $r15 1
+		bra ne #ctx_redswitch_delay
+	mov $r15 0xa20
+	iowr I[$r14] $r15	// GPC_RED_SWITCH = UNK11, ENABLE, POWER
+	ret
+
+// Transfer GPC context data between GPU and storage area
+//
+// In: $r15 context base address
+//     $p1 clear on save, set on load
+//     $p2 set if opposite direction done/will be done, so:
+//		on save it means: "a load will follow this save"
+//		on load it means: "a save preceeded this load"
+//
+ctx_xfer:
+	// set context base address
+	mov $r1 0xa04
+	shl b32 $r1 6
+	iowr I[$r1 + 0x000] $r15// MEM_BASE
+	bra not $p1 #ctx_xfer_not_load
+		call #ctx_redswitch
+	ctx_xfer_not_load:
+
+	// strands
+	mov $r1 0x4afc
+	sethi $r1 0x20000
+	mov $r2 0xc
+	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x0c
+	call #strand_wait
+	mov $r2 0x47fc
+	sethi $r2 0x20000
+	iowr I[$r2] $r0		// STRAND_FIRST_GENE(0x3f) = 0x00
+	xbit $r2 $flags $p1
+	add b32 $r2 3
+	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
+
+	// mmio context
+	xbit $r10 $flags $p1	// direction
+	or $r10 2		// first
+	mov $r11 0x0000
+	sethi $r11 0x500000
+	ld b32 $r12 D[$r0 + #gpc_id]
+	shl b32 $r12 15
+	add b32 $r11 $r12	// base = NV_PGRAPH_GPCn
+	ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
+	ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
+	mov $r14 0		// not multi
+	call #mmctx_xfer
+
+	// per-TPC mmio context
+	xbit $r10 $flags $p1	// direction
+#if !NV_PGRAPH_GPCX_UNK__SIZE
+	or $r10 4		// last
+#endif
+	mov $r11 0x4000
+	sethi $r11 0x500000	// base = NV_PGRAPH_GPC0_TPC0
+	ld b32 $r12 D[$r0 + #gpc_id]
+	shl b32 $r12 15
+	add b32 $r11 $r12	// base = NV_PGRAPH_GPCn_TPC0
+	ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
+	ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
+	ld b32 $r15 D[$r0 + #tpc_mask]
+	mov $r14 0x800		// stride = 0x800
+	call #mmctx_xfer
+
+#if NV_PGRAPH_GPCX_UNK__SIZE > 0
+	// per-UNK mmio context
+	xbit $r10 $flags $p1	// direction
+	or $r10 4		// last
+	mov $r11 0x3000
+	sethi $r11 0x500000	// base = NV_PGRAPH_GPC0_UNK0
+	ld b32 $r12 D[$r0 + #gpc_id]
+	shl b32 $r12 15
+	add b32 $r11 $r12	// base = NV_PGRAPH_GPCn_UNK0
+	ld b32 $r12 D[$r0 + #unk_mmio_list_head]
+	ld b32 $r13 D[$r0 + #unk_mmio_list_tail]
+	ld b32 $r15 D[$r0 + #unk_mask]
+	mov $r14 0x200		// stride = 0x200
+	call #mmctx_xfer
+#endif
+
+	// wait for strands to finish
+	call #strand_wait
+
+	// if load, or a save without a load following, do some
+	// unknown stuff that's done after finishing a block of
+	// strand commands
+	bra $p1 #ctx_xfer_post
+	bra not $p2 #ctx_xfer_done
+	ctx_xfer_post:
+		mov $r1 0x4afc
+		sethi $r1 0x20000
+		mov $r2 0xd
+		iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x0d
+		call #strand_wait
+
+	// mark completion in HUB's barrier
+	ctx_xfer_done:
+	call #hub_barrier_done
+	ret
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,5 @@
-/* fuc microcode for nvc0 PGRAPH/GPC
- *
- * Copyright 2011 Red Hat Inc.
+/*
+ * Copyright 2013 Red Hat Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -20,525 +19,24 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-/* To build:
- *    m4 gpcnvc0.fuc | envyas -a -w -m fuc -V fuc3 -o gpcnvc0.fuc.h
- */
+#define NV_PGRAPH_GPCX_UNK__SIZE                                     0x00000000
 
-/* TODO
- * - bracket certain functions with scratch writes, useful for debugging
- * - watchdog timer around ctx operations
- */
+#define CHIPSET GF100
+#include "macros.fuc"
 
 .section #nvc0_grgpc_data
-include(`nvc0.fuc')
-gpc_id:			.b32 0
-gpc_mmio_list_head:	.b32 0
-gpc_mmio_list_tail:	.b32 0
-
-tpc_count:		.b32 0
-tpc_mask:		.b32 0
-tpc_mmio_list_head:	.b32 0
-tpc_mmio_list_tail:	.b32 0
-
-cmd_queue:		queue_init
-
-// chipset descriptions
-chipsets:
-.b8  0xc0 0 0 0
-.b16 #nvc0_gpc_mmio_head
-.b16 #nvc0_gpc_mmio_tail
-.b16 #nvc0_tpc_mmio_head
-.b16 #nvc0_tpc_mmio_tail
-.b8  0xc1 0 0 0
-.b16 #nvc0_gpc_mmio_head
-.b16 #nvc1_gpc_mmio_tail
-.b16 #nvc0_tpc_mmio_head
-.b16 #nvc1_tpc_mmio_tail
-.b8  0xc3 0 0 0
-.b16 #nvc0_gpc_mmio_head
-.b16 #nvc0_gpc_mmio_tail
-.b16 #nvc0_tpc_mmio_head
-.b16 #nvc3_tpc_mmio_tail
-.b8  0xc4 0 0 0
-.b16 #nvc0_gpc_mmio_head
-.b16 #nvc0_gpc_mmio_tail
-.b16 #nvc0_tpc_mmio_head
-.b16 #nvc3_tpc_mmio_tail
-.b8  0xc8 0 0 0
-.b16 #nvc0_gpc_mmio_head
-.b16 #nvc0_gpc_mmio_tail
-.b16 #nvc0_tpc_mmio_head
-.b16 #nvc0_tpc_mmio_tail
-.b8  0xce 0 0 0
-.b16 #nvc0_gpc_mmio_head
-.b16 #nvc0_gpc_mmio_tail
-.b16 #nvc0_tpc_mmio_head
-.b16 #nvc3_tpc_mmio_tail
-.b8  0xcf 0 0 0
-.b16 #nvc0_gpc_mmio_head
-.b16 #nvc0_gpc_mmio_tail
-.b16 #nvc0_tpc_mmio_head
-.b16 #nvcf_tpc_mmio_tail
-.b8  0xd9 0 0 0
-.b16 #nvd9_gpc_mmio_head
-.b16 #nvd9_gpc_mmio_tail
-.b16 #nvd9_tpc_mmio_head
-.b16 #nvd9_tpc_mmio_tail
-.b8  0xd7 0 0 0
-.b16 #nvd9_gpc_mmio_head
-.b16 #nvd9_gpc_mmio_tail
-.b16 #nvd9_tpc_mmio_head
-.b16 #nvd9_tpc_mmio_tail
-.b8  0 0 0 0
-
-// GPC mmio lists
-nvc0_gpc_mmio_head:
-mmctx_data(0x000380, 1)
-mmctx_data(0x000400, 6)
-mmctx_data(0x000450, 9)
-mmctx_data(0x000600, 1)
-mmctx_data(0x000684, 1)
-mmctx_data(0x000700, 5)
-mmctx_data(0x000800, 1)
-mmctx_data(0x000808, 3)
-mmctx_data(0x000828, 1)
-mmctx_data(0x000830, 1)
-mmctx_data(0x0008d8, 1)
-mmctx_data(0x0008e0, 1)
-mmctx_data(0x0008e8, 6)
-mmctx_data(0x00091c, 1)
-mmctx_data(0x000924, 3)
-mmctx_data(0x000b00, 1)
-mmctx_data(0x000b08, 6)
-mmctx_data(0x000bb8, 1)
-mmctx_data(0x000c08, 1)
-mmctx_data(0x000c10, 8)
-mmctx_data(0x000c80, 1)
-mmctx_data(0x000c8c, 1)
-mmctx_data(0x001000, 3)
-mmctx_data(0x001014, 1)
-nvc0_gpc_mmio_tail:
-mmctx_data(0x000c6c, 1);
-nvc1_gpc_mmio_tail:
-
-nvd9_gpc_mmio_head:
-mmctx_data(0x000380, 1)
-mmctx_data(0x000400, 2)
-mmctx_data(0x00040c, 3)
-mmctx_data(0x000450, 9)
-mmctx_data(0x000600, 1)
-mmctx_data(0x000684, 1)
-mmctx_data(0x000700, 5)
-mmctx_data(0x000800, 1)
-mmctx_data(0x000808, 3)
-mmctx_data(0x000828, 1)
-mmctx_data(0x000830, 1)
-mmctx_data(0x0008d8, 1)
-mmctx_data(0x0008e0, 1)
-mmctx_data(0x0008e8, 6)
-mmctx_data(0x00091c, 1)
-mmctx_data(0x000924, 3)
-mmctx_data(0x000b00, 1)
-mmctx_data(0x000b08, 6)
-mmctx_data(0x000bb8, 1)
-mmctx_data(0x000c08, 1)
-mmctx_data(0x000c10, 8)
-mmctx_data(0x000c6c, 1)
-mmctx_data(0x000c80, 1)
-mmctx_data(0x000c8c, 1)
-mmctx_data(0x001000, 3)
-mmctx_data(0x001014, 1)
-nvd9_gpc_mmio_tail:
-
-// TPC mmio lists
-nvc0_tpc_mmio_head:
-mmctx_data(0x000018, 1)
-mmctx_data(0x00003c, 1)
-mmctx_data(0x000048, 1)
-mmctx_data(0x000064, 1)
-mmctx_data(0x000088, 1)
-mmctx_data(0x000200, 6)
-mmctx_data(0x00021c, 2)
-mmctx_data(0x000300, 6)
-mmctx_data(0x0003d0, 1)
-mmctx_data(0x0003e0, 2)
-mmctx_data(0x000400, 3)
-mmctx_data(0x000420, 1)
-mmctx_data(0x0004b0, 1)
-mmctx_data(0x0004e8, 1)
-mmctx_data(0x0004f4, 1)
-mmctx_data(0x000520, 2)
-mmctx_data(0x000604, 4)
-mmctx_data(0x000644, 20)
-mmctx_data(0x000698, 1)
-mmctx_data(0x000750, 2)
-nvc0_tpc_mmio_tail:
-mmctx_data(0x000758, 1)
-mmctx_data(0x0002c4, 1)
-mmctx_data(0x0006e0, 1)
-nvcf_tpc_mmio_tail:
-mmctx_data(0x0004bc, 1)
-nvc3_tpc_mmio_tail:
-mmctx_data(0x000544, 1)
-nvc1_tpc_mmio_tail:
-
-nvd9_tpc_mmio_head:
-mmctx_data(0x000018, 1)
-mmctx_data(0x00003c, 1)
-mmctx_data(0x000048, 1)
-mmctx_data(0x000064, 1)
-mmctx_data(0x000088, 1)
-mmctx_data(0x000200, 6)
-mmctx_data(0x00021c, 2)
-mmctx_data(0x0002c4, 1)
-mmctx_data(0x000300, 6)
-mmctx_data(0x0003d0, 1)
-mmctx_data(0x0003e0, 2)
-mmctx_data(0x000400, 3)
-mmctx_data(0x000420, 3)
-mmctx_data(0x0004b0, 1)
-mmctx_data(0x0004e8, 1)
-mmctx_data(0x0004f4, 1)
-mmctx_data(0x000520, 2)
-mmctx_data(0x000544, 1)
-mmctx_data(0x000604, 4)
-mmctx_data(0x000644, 20)
-mmctx_data(0x000698, 1)
-mmctx_data(0x0006e0, 1)
-mmctx_data(0x000750, 3)
-nvd9_tpc_mmio_tail:
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "gpc.fuc"
+#undef INCLUDE_DATA
 
 .section #nvc0_grgpc_code
+#define INCLUDE_CODE
 bra #init
-define(`include_code')
-include(`nvc0.fuc')
-
-// reports an exception to the host
-//
-// In: $r15 error code (see nvc0.fuc)
-//
-error:
-	push $r14
-	mov $r14 -0x67ec 	// 0x9814
-	sethi $r14 0x400000
-	call #nv_wr32		// HUB_CTXCTL_CC_SCRATCH[5] = error code
-	add b32 $r14 0x41c
-	mov $r15 1
-	call #nv_wr32		// HUB_CTXCTL_INTR_UP_SET
-	pop $r14
-	ret
-
-// GPC fuc initialisation, executed by triggering ucode start, will
-// fall through to main loop after completion.
-//
-// Input:
-//   CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
-//   CC_SCRATCH[1]: context base
-//
-// Output:
-//   CC_SCRATCH[0]:
-//	     31:31: set to signal completion
-//   CC_SCRATCH[1]:
-//	      31:0: GPC context size
-//
-init:
-	clear b32 $r0
-	mov $sp $r0
-
-	// enable fifo access
-	mov $r1 0x1200
-	mov $r2 2
-	iowr I[$r1 + 0x000] $r2		// FIFO_ENABLE
-
-	// setup i0 handler, and route all interrupts to it
-	mov $r1 #ih
-	mov $iv0 $r1
-	mov $r1 0x400
-	iowr I[$r1 + 0x300] $r0		// INTR_DISPATCH
-
-	// enable fifo interrupt
-	mov $r2 4
-	iowr I[$r1 + 0x000] $r2		// INTR_EN_SET
-
-	// enable interrupts
-	bset $flags ie0
-
-	// figure out which GPC we are, and how many TPCs we have
-	mov $r1 0x608
-	shl b32 $r1 6
-	iord $r2 I[$r1 + 0x000]		// UNITS
-	mov $r3 1
-	and $r2 0x1f
-	shl b32 $r3 $r2
-	sub b32 $r3 1
-	st b32 D[$r0 + #tpc_count] $r2
-	st b32 D[$r0 + #tpc_mask] $r3
-	add b32 $r1 0x400
-	iord $r2 I[$r1 + 0x000]		// MYINDEX
-	st b32 D[$r0 + #gpc_id] $r2
-
-	// find context data for this chipset
-	mov $r2 0x800
-	shl b32 $r2 6
-	iord $r2 I[$r2 + 0x000]		// CC_SCRATCH[0]
-	mov $r1 #chipsets - 12
-	init_find_chipset:
-		add b32 $r1 12
-		ld b32 $r3 D[$r1 + 0x00]
-		cmpu b32 $r3 $r2
-		bra e #init_context
-		cmpu b32 $r3 0
-		bra ne #init_find_chipset
-		// unknown chipset
-		ret
-
-	// initialise context base, and size tracking
-	init_context:
-	mov $r2 0x800
-	shl b32 $r2 6
-	iord $r2 I[$r2 + 0x100]	// CC_SCRATCH[1], initial base
-	clear b32 $r3		// track GPC context size here
-
-	// set mmctx base addresses now so we don't have to do it later,
-	// they don't currently ever change
-	mov $r4 0x700
-	shl b32 $r4 6
-	shr b32 $r5 $r2 8
-	iowr I[$r4 + 0x000] $r5		// MMCTX_SAVE_SWBASE
-	iowr I[$r4 + 0x100] $r5		// MMCTX_LOAD_SWBASE
-
-	// calculate GPC mmio context size, store the chipset-specific
-	// mmio list pointers somewhere we can get at them later without
-	// re-parsing the chipset list
-	clear b32 $r14
-	clear b32 $r15
-	ld b16 $r14 D[$r1 + 4]
-	ld b16 $r15 D[$r1 + 6]
-	st b16 D[$r0 + #gpc_mmio_list_head] $r14
-	st b16 D[$r0 + #gpc_mmio_list_tail] $r15
-	call #mmctx_size
-	add b32 $r2 $r15
-	add b32 $r3 $r15
-
-	// calculate per-TPC mmio context size, store the list pointers
-	ld b16 $r14 D[$r1 + 8]
-	ld b16 $r15 D[$r1 + 10]
-	st b16 D[$r0 + #tpc_mmio_list_head] $r14
-	st b16 D[$r0 + #tpc_mmio_list_tail] $r15
-	call #mmctx_size
-	ld b32 $r14 D[$r0 + #tpc_count]
-	mulu $r14 $r15
-	add b32 $r2 $r14
-	add b32 $r3 $r14
-
-	// round up base/size to 256 byte boundary (for strand SWBASE)
-	add b32 $r4 0x1300
-	shr b32 $r3 2
-	iowr I[$r4 + 0x000] $r3		// MMCTX_LOAD_COUNT, wtf for?!?
-	shr b32 $r2 8
-	shr b32 $r3 6
-	add b32 $r2 1
-	add b32 $r3 1
-	shl b32 $r2 8
-	shl b32 $r3 8
-
-	// calculate size of strand context data
-	mov b32 $r15 $r2
-	call #strand_ctx_init
-	add b32 $r3 $r15
-
-	// save context size, and tell HUB we're done
-	mov $r1 0x800
-	shl b32 $r1 6
-	iowr I[$r1 + 0x100] $r3		// CC_SCRATCH[1]  = context size
-	add b32 $r1 0x800
-	clear b32 $r2
-	bset $r2 31
-	iowr I[$r1 + 0x000] $r2		// CC_SCRATCH[0] |= 0x80000000
-
-// Main program loop, very simple, sleeps until woken up by the interrupt
-// handler, pulls a command from the queue and executes its handler
-//
-main:
-	bset $flags $p0
-	sleep $p0
-	mov $r13 #cmd_queue
-	call #queue_get
-	bra $p1 #main
-
-	// 0x0000-0x0003 are all context transfers
-	cmpu b32 $r14 0x04
-	bra nc #main_not_ctx_xfer
-		// fetch $flags and mask off $p1/$p2
-		mov $r1 $flags
-		mov $r2 0x0006
-		not b32 $r2
-		and $r1 $r2
-		// set $p1/$p2 according to transfer type
-		shl b32 $r14 1
-		or $r1 $r14
-		mov $flags $r1
-		// transfer context data
-		call #ctx_xfer
-		bra #main
-
-	main_not_ctx_xfer:
-	shl b32 $r15 $r14 16
-	or $r15 E_BAD_COMMAND
-	call #error
-	bra #main
-
-// interrupt handler
-ih:
-	push $r8
-	mov $r8 $flags
-	push $r8
-	push $r9
-	push $r10
-	push $r11
-	push $r13
-	push $r14
-	push $r15
-
-	// incoming fifo command?
-	iord $r10 I[$r0 + 0x200]	// INTR
-	and $r11 $r10 0x00000004
-	bra e #ih_no_fifo
-		// queue incoming fifo command for later processing
-		mov $r11 0x1900
-		mov $r13 #cmd_queue
-		iord $r14 I[$r11 + 0x100]	// FIFO_CMD
-		iord $r15 I[$r11 + 0x000]	// FIFO_DATA
-		call #queue_put
-		add b32 $r11 0x400
-		mov $r14 1
-		iowr I[$r11 + 0x000] $r14	// FIFO_ACK
-
-	// ack, and wake up main()
-	ih_no_fifo:
-	iowr I[$r0 + 0x100] $r10	// INTR_ACK
-
-	pop $r15
-	pop $r14
-	pop $r13
-	pop $r11
-	pop $r10
-	pop $r9
-	pop $r8
-	mov $flags $r8
-	pop $r8
-	bclr $flags $p0
-	iret
-
-// Set this GPC's bit in HUB_BAR, used to signal completion of various
-// activities to the HUB fuc
-//
-hub_barrier_done:
-	mov $r15 1
-	ld b32 $r14 D[$r0 + #gpc_id]
-	shl b32 $r15 $r14
-	mov $r14 -0x6be8 	// 0x409418 - HUB_BAR_SET
-	sethi $r14 0x400000
-	call #nv_wr32
-	ret
-
-// Disables various things, waits a bit, and re-enables them..
-//
-// Not sure how exactly this helps, perhaps "ENABLE" is not such a
-// good description for the bits we turn off?  Anyways, without this,
-// funny things happen.
-//
-ctx_redswitch:
-	mov $r14 0x614
-	shl b32 $r14 6
-	mov $r15 0x020
-	iowr I[$r14] $r15	// GPC_RED_SWITCH = POWER
-	mov $r15 8
-	ctx_redswitch_delay:
-		sub b32 $r15 1
-		bra ne #ctx_redswitch_delay
-	mov $r15 0xa20
-	iowr I[$r14] $r15	// GPC_RED_SWITCH = UNK11, ENABLE, POWER
-	ret
-
-// Transfer GPC context data between GPU and storage area
-//
-// In: $r15 context base address
-//     $p1 clear on save, set on load
-//     $p2 set if opposite direction done/will be done, so:
-//		on save it means: "a load will follow this save"
-//		on load it means: "a save preceeded this load"
-//
-ctx_xfer:
-	// set context base address
-	mov $r1 0xa04
-	shl b32 $r1 6
-	iowr I[$r1 + 0x000] $r15// MEM_BASE
-	bra not $p1 #ctx_xfer_not_load
-		call #ctx_redswitch
-	ctx_xfer_not_load:
-
-	// strands
-	mov $r1 0x4afc
-	sethi $r1 0x20000
-	mov $r2 0xc
-	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x0c
-	call #strand_wait
-	mov $r2 0x47fc
-	sethi $r2 0x20000
-	iowr I[$r2] $r0		// STRAND_FIRST_GENE(0x3f) = 0x00
-	xbit $r2 $flags $p1
-	add b32 $r2 3
-	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
-
-	// mmio context
-	xbit $r10 $flags $p1	// direction
-	or $r10 2		// first
-	mov $r11 0x0000
-	sethi $r11 0x500000
-	ld b32 $r12 D[$r0 + #gpc_id]
-	shl b32 $r12 15
-	add b32 $r11 $r12	// base = NV_PGRAPH_GPCn
-	ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
-	ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
-	mov $r14 0		// not multi
-	call #mmctx_xfer
-
-	// per-TPC mmio context
-	xbit $r10 $flags $p1	// direction
-	or $r10 4		// last
-	mov $r11 0x4000
-	sethi $r11 0x500000	// base = NV_PGRAPH_GPC0_TPC0
-	ld b32 $r12 D[$r0 + #gpc_id]
-	shl b32 $r12 15
-	add b32 $r11 $r12	// base = NV_PGRAPH_GPCn_TPC0
-	ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
-	ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
-	ld b32 $r15 D[$r0 + #tpc_mask]
-	mov $r14 0x800		// stride = 0x800
-	call #mmctx_xfer
-
-	// wait for strands to finish
-	call #strand_wait
-
-	// if load, or a save without a load following, do some
-	// unknown stuff that's done after finishing a block of
-	// strand commands
-	bra $p1 #ctx_xfer_post
-	bra not $p2 #ctx_xfer_done
-	ctx_xfer_post:
-		mov $r1 0x4afc
-		sethi $r1 0x20000
-		mov $r2 0xd
-		iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x0d
-		call #strand_wait
-
-	// mark completion in HUB's barrier
-	ctx_xfer_done:
-	call #hub_barrier_done
-	ret
-
+#include "com.fuc"
+#include "gpc.fuc"
 .align 256
+#undef INCLUDE_CODE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,17 +1,19 @@
 uint32_t nvc0_grgpc_data[] = {
-/* 0x0000: gpc_id */
-	0x00000000,
-/* 0x0004: gpc_mmio_list_head */
-	0x00000000,
-/* 0x0008: gpc_mmio_list_tail */
-	0x00000000,
-/* 0x000c: tpc_count */
-	0x00000000,
-/* 0x0010: tpc_mask */
+/* 0x0000: gpc_mmio_list_head */
+	0x00000064,
+/* 0x0004: gpc_mmio_list_tail */
+/* 0x0004: tpc_mmio_list_head */
+	0x00000064,
+/* 0x0008: tpc_mmio_list_tail */
+/* 0x0008: unk_mmio_list_head */
+	0x00000064,
+/* 0x000c: unk_mmio_list_tail */
+	0x00000064,
+/* 0x0010: gpc_id */
 	0x00000000,
-/* 0x0014: tpc_mmio_list_head */
+/* 0x0014: tpc_count */
 	0x00000000,
-/* 0x0018: tpc_mmio_list_tail */
+/* 0x0018: tpc_mask */
 	0x00000000,
 /* 0x001c: cmd_queue */
 	0x00000000,
@@ -32,153 +34,17 @@ uint32_t nvc0_grgpc_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
-/* 0x0064: chipsets */
-	0x000000c0,
-	0x012800c8,
-	0x01e40194,
-	0x000000c1,
-	0x012c00c8,
-	0x01f80194,
-	0x000000c3,
-	0x012800c8,
-	0x01f40194,
-	0x000000c4,
-	0x012800c8,
-	0x01f40194,
-	0x000000c8,
-	0x012800c8,
-	0x01e40194,
-	0x000000ce,
-	0x012800c8,
-	0x01f40194,
-	0x000000cf,
-	0x012800c8,
-	0x01f00194,
-	0x000000d9,
-	0x0194012c,
-	0x025401f8,
-	0x00000000,
-/* 0x00c8: nvc0_gpc_mmio_head */
-	0x00000380,
-	0x14000400,
-	0x20000450,
-	0x00000600,
-	0x00000684,
-	0x10000700,
-	0x00000800,
-	0x08000808,
-	0x00000828,
-	0x00000830,
-	0x000008d8,
-	0x000008e0,
-	0x140008e8,
-	0x0000091c,
-	0x08000924,
-	0x00000b00,
-	0x14000b08,
-	0x00000bb8,
-	0x00000c08,
-	0x1c000c10,
-	0x00000c80,
-	0x00000c8c,
-	0x08001000,
-	0x00001014,
-/* 0x0128: nvc0_gpc_mmio_tail */
-	0x00000c6c,
-/* 0x012c: nvc1_gpc_mmio_tail */
-/* 0x012c: nvd9_gpc_mmio_head */
-	0x00000380,
-	0x04000400,
-	0x0800040c,
-	0x20000450,
-	0x00000600,
-	0x00000684,
-	0x10000700,
-	0x00000800,
-	0x08000808,
-	0x00000828,
-	0x00000830,
-	0x000008d8,
-	0x000008e0,
-	0x140008e8,
-	0x0000091c,
-	0x08000924,
-	0x00000b00,
-	0x14000b08,
-	0x00000bb8,
-	0x00000c08,
-	0x1c000c10,
-	0x00000c6c,
-	0x00000c80,
-	0x00000c8c,
-	0x08001000,
-	0x00001014,
-/* 0x0194: nvd9_gpc_mmio_tail */
-/* 0x0194: nvc0_tpc_mmio_head */
-	0x00000018,
-	0x0000003c,
-	0x00000048,
-	0x00000064,
-	0x00000088,
-	0x14000200,
-	0x0400021c,
-	0x14000300,
-	0x000003d0,
-	0x040003e0,
-	0x08000400,
-	0x00000420,
-	0x000004b0,
-	0x000004e8,
-	0x000004f4,
-	0x04000520,
-	0x0c000604,
-	0x4c000644,
-	0x00000698,
-	0x04000750,
-/* 0x01e4: nvc0_tpc_mmio_tail */
-	0x00000758,
-	0x000002c4,
-	0x000006e0,
-/* 0x01f0: nvcf_tpc_mmio_tail */
-	0x000004bc,
-/* 0x01f4: nvc3_tpc_mmio_tail */
-	0x00000544,
-/* 0x01f8: nvc1_tpc_mmio_tail */
-/* 0x01f8: nvd9_tpc_mmio_head */
-	0x00000018,
-	0x0000003c,
-	0x00000048,
-	0x00000064,
-	0x00000088,
-	0x14000200,
-	0x0400021c,
-	0x000002c4,
-	0x14000300,
-	0x000003d0,
-	0x040003e0,
-	0x08000400,
-	0x08000420,
-	0x000004b0,
-	0x000004e8,
-	0x000004f4,
-	0x04000520,
-	0x00000544,
-	0x0c000604,
-	0x4c000644,
-	0x00000698,
-	0x000006e0,
-	0x08000750,
 };
 
 uint32_t nvc0_grgpc_code[] = {
-	0x03060ef5,
+	0x03180ef5,
 /* 0x0004: queue_put */
 	0x9800d898,
 	0x86f001d9,
 	0x0489b808,
 	0xf00c1bf4,
 	0x21f502f7,
-	0x00f802ec,
+	0x00f802fe,
 /* 0x001c: queue_put_next */
 	0xb60798c4,
 	0x8dbb0384,
@@ -210,7 +76,7 @@ uint32_t nvc0_grgpc_code[] = {
 	0xc800bccf,
 	0x1bf41fcc,
 	0x06a7f0fa,
-	0x010321f5,
+	0x010921f5,
 	0xf840bfcf,
 /* 0x008d: nv_wr32 */
 	0x28b7f100,
@@ -232,63 +98,66 @@ uint32_t nvc0_grgpc_code[] = {
 	0x0684b604,
 	0xf80080d0,
 /* 0x00c9: wait_donez */
-	0x3c87f100,
-	0x0684b608,
-	0x99f094bd,
-	0x0089d000,
-	0x081887f1,
-	0xd00684b6,
-/* 0x00e2: wait_done_wait_donez */
-	0x87f1008a,
-	0x84b60400,
-	0x0088cf06,
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x07f104bd,
+	0x03f00600,
+	0x000ad002,
+/* 0x00e6: wait_donez_ne */
+	0x87f104bd,
+	0x83f00000,
+	0x0088cf01,
 	0xf4888aff,
-	0x87f1f31b,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00099,
-/* 0x0103: wait_doneo */
-	0xf100f800,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00099f0,
-	0x87f10089,
+	0x94bdf31b,
+	0xf10099f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0109: wait_doneo */
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x87f104bd,
 	0x84b60818,
 	0x008ad006,
-/* 0x011c: wait_done_wait_doneo */
+/* 0x0124: wait_doneo_e */
 	0x040087f1,
 	0xcf0684b6,
 	0x8aff0088,
 	0xf30bf488,
-	0x085c87f1,
-	0xbd0684b6,
-	0x0099f094,
-	0xf80089d0,
-/* 0x013d: mmctx_size */
-/* 0x013f: nv_mmctx_size_loop */
-	0x9894bd00,
-	0x85b600e8,
-	0x0180b61a,
-	0xbb0284b6,
-	0xe0b60098,
-	0x04efb804,
-	0xb9eb1bf4,
-	0x00f8029f,
-/* 0x015c: mmctx_xfer */
-	0x083c87f1,
-	0xbd0684b6,
-	0x0199f094,
-	0xf10089d0,
+	0x99f094bd,
+	0x0007f100,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x0147: mmctx_size */
+	0xbd00f804,
+/* 0x0149: nv_mmctx_size_loop */
+	0x00e89894,
+	0xb61a85b6,
+	0x84b60180,
+	0x0098bb02,
+	0xb804e0b6,
+	0x1bf404ef,
+	0x029fb9eb,
+/* 0x0166: mmctx_xfer */
+	0x94bd00f8,
+	0xf10199f0,
+	0xf00f0007,
+	0x09d00203,
+	0xf104bd00,
 	0xb6071087,
 	0x94bd0684,
 	0xf405bbfd,
 	0x8bd0090b,
 	0x0099f000,
-/* 0x0180: mmctx_base_disabled */
+/* 0x018c: mmctx_base_disabled */
 	0xf405eefd,
 	0x8ed00c0b,
 	0xc08fd080,
-/* 0x018f: mmctx_multi_disabled */
+/* 0x019b: mmctx_multi_disabled */
 	0xb70199f0,
 	0xc8010080,
 	0xb4b600ab,
@@ -296,8 +165,8 @@ uint32_t nvc0_grgpc_code[] = {
 	0xb601aec8,
 	0xbefd11e4,
 	0x008bd005,
-/* 0x01a8: mmctx_exec_loop */
-/* 0x01a8: mmctx_wait_free */
+/* 0x01b4: mmctx_exec_loop */
+/* 0x01b4: mmctx_wait_free */
 	0xf0008ecf,
 	0x0bf41fe4,
 	0x00ce98fa,
@@ -306,76 +175,77 @@ uint32_t nvc0_grgpc_code[] = {
 	0x04cdb804,
 	0xc8e81bf4,
 	0x1bf402ab,
-/* 0x01c9: mmctx_fini_wait */
+/* 0x01d5: mmctx_fini_wait */
 	0x008bcf18,
 	0xb01fb4f0,
 	0x1bf410b4,
 	0x02a7f0f7,
 	0xf4c921f4,
-/* 0x01de: mmctx_stop */
+/* 0x01ea: mmctx_stop */
 	0xabc81b0e,
 	0x10b4b600,
 	0xf00cb9f0,
 	0x8bd012b9,
-/* 0x01ed: mmctx_stop_wait */
+/* 0x01f9: mmctx_stop_wait */
 	0x008bcf00,
 	0xf412bbc8,
-/* 0x01f6: mmctx_done */
-	0x87f1fa1b,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00199,
-/* 0x0207: strand_wait */
-	0xf900f800,
-	0x02a7f0a0,
-	0xfcc921f4,
-/* 0x0213: strand_pre */
-	0xf100f8a0,
-	0xf04afc87,
-	0x97f00283,
-	0x0089d00c,
-	0x020721f5,
-/* 0x0226: strand_post */
-	0x87f100f8,
-	0x83f04afc,
-	0x0d97f002,
-	0xf50089d0,
-	0xf8020721,
-/* 0x0239: strand_set */
-	0xfca7f100,
-	0x02a3f04f,
-	0x0500aba2,
-	0xd00fc7f0,
-	0xc7f000ac,
-	0x00bcd00b,
-	0x020721f5,
-	0xf000aed0,
-	0xbcd00ac7,
-	0x0721f500,
-/* 0x0263: strand_ctx_init */
-	0xf100f802,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00399f0,
+/* 0x0202: mmctx_done */
+	0x94bdfa1b,
+	0xf10199f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0215: strand_wait */
+	0xf0a0f900,
+	0x21f402a7,
+	0xf8a0fcc9,
+/* 0x0221: strand_pre */
+	0xfc87f100,
+	0x0283f04a,
+	0xd00c97f0,
 	0x21f50089,
-	0xe7f00213,
-	0x3921f503,
+	0x00f80215,
+/* 0x0234: strand_post */
+	0x4afc87f1,
+	0xf00283f0,
+	0x89d00d97,
+	0x1521f500,
+/* 0x0247: strand_set */
+	0xf100f802,
+	0xf04ffca7,
+	0xaba202a3,
+	0xc7f00500,
+	0x00acd00f,
+	0xd00bc7f0,
+	0x21f500bc,
+	0xaed00215,
+	0x0ac7f000,
+	0xf500bcd0,
+	0xf8021521,
+/* 0x0271: strand_ctx_init */
+	0xf094bd00,
+	0x07f10399,
+	0x03f00f00,
+	0x0009d002,
+	0x21f504bd,
+	0xe7f00221,
+	0x4721f503,
 	0xfca7f102,
 	0x02a3f046,
 	0x0400aba0,
 	0xf040a0d0,
 	0xbcd001c7,
-	0x0721f500,
+	0x1521f500,
 	0x010c9202,
 	0xf000acd0,
 	0xbcd002c7,
-	0x0721f500,
-	0x2621f502,
+	0x1521f500,
+	0x3421f502,
 	0x8087f102,
 	0x0684b608,
 	0xb70089cf,
 	0x95220080,
-/* 0x02ba: ctx_init_strand_loop */
+/* 0x02ca: ctx_init_strand_loop */
 	0x8ed008fe,
 	0x408ed000,
 	0xb6808acf,
@@ -384,86 +254,74 @@ uint32_t nvc0_grgpc_code[] = {
 	0xb60480b6,
 	0x1bf40192,
 	0x08e4b6e8,
-	0xf1f2efbc,
-	0xb6085c87,
-	0x94bd0684,
-	0xd00399f0,
-	0x00f80089,
-/* 0x02ec: error */
-	0xe7f1e0f9,
-	0xe3f09814,
-	0x8d21f440,
-	0x041ce0b7,
-	0xf401f7f0,
-	0xe0fc8d21,
-/* 0x0306: init */
-	0x04bd00f8,
-	0xf10004fe,
-	0xf0120017,
-	0x12d00227,
-	0x3e17f100,
-	0x0010fe04,
-	0x040017f1,
-	0xf0c010d0,
-	0x12d00427,
-	0x1031f400,
-	0x060817f1,
-	0xcf0614b6,
-	0x37f00012,
-	0x1f24f001,
-	0xb60432bb,
-	0x02800132,
-	0x04038003,
-	0x040010b7,
-	0x800012cf,
-	0x27f10002,
-	0x24b60800,
-	0x0022cf06,
-/* 0x035f: init_find_chipset */
-	0xb65817f0,
-	0x13980c10,
-	0x0432b800,
-	0xb00b0bf4,
-	0x1bf40034,
-/* 0x0373: init_context */
-	0xf100f8f1,
-	0xb6080027,
-	0x22cf0624,
-	0xf134bd40,
-	0xb6070047,
-	0x25950644,
-	0x0045d008,
-	0xbd4045d0,
-	0x58f4bde4,
-	0x1f58021e,
-	0x020e4003,
-	0xf5040f40,
-	0xbb013d21,
-	0x3fbb002f,
-	0x041e5800,
-	0x40051f58,
-	0x0f400a0e,
-	0x3d21f50c,
-	0x030e9801,
-	0xbb00effd,
-	0x3ebb002e,
-	0x0040b700,
-	0x0235b613,
-	0xb60043d0,
-	0x35b60825,
-	0x0120b606,
-	0xb60130b6,
-	0x34b60824,
-	0x022fb908,
-	0x026321f5,
-	0xf1003fbb,
-	0xb6080017,
-	0x13d00614,
-	0x0010b740,
-	0xf024bd08,
-	0x12d01f29,
-/* 0x0401: main */
-	0x0031f400,
+	0xbdf2efbc,
+	0x0399f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+/* 0x02fe: error */
+	0xe0f900f8,
+	0x9814e7f1,
+	0xf440e3f0,
+	0xe0b78d21,
+	0xf7f0041c,
+	0x8d21f401,
+	0x00f8e0fc,
+/* 0x0318: init */
+	0x04fe04bd,
+	0x0017f100,
+	0x0227f012,
+	0xf10012d0,
+	0xfe042617,
+	0x17f10010,
+	0x10d00400,
+	0x0427f0c0,
+	0xf40012d0,
+	0x17f11031,
+	0x14b60608,
+	0x0012cf06,
+	0xf00137f0,
+	0x32bb1f24,
+	0x0132b604,
+	0x80050280,
+	0x10b70603,
+	0x12cf0400,
+	0x04028000,
+	0x010027f1,
+	0xcf0223f0,
+	0x34bd0022,
+	0x070047f1,
+	0x950644b6,
+	0x45d00825,
+	0x4045d000,
+	0x98000e98,
+	0x21f5010f,
+	0x2fbb0147,
+	0x003fbb00,
+	0x98010e98,
+	0x21f5020f,
+	0x0e980147,
+	0x00effd05,
+	0xbb002ebb,
+	0x40b7003e,
+	0x35b61300,
+	0x0043d002,
+	0xb60825b6,
+	0x20b60635,
+	0x0130b601,
+	0xb60824b6,
+	0x2fb90834,
+	0x7121f502,
+	0x003fbb02,
+	0x010007f1,
+	0xd00203f0,
+	0x04bd0003,
+	0x29f024bd,
+	0x0007f11f,
+	0x0203f008,
+	0xbd0002d0,
+/* 0x03e9: main */
+	0x0031f404,
 	0xf00028f4,
 	0x21f41cd7,
 	0xf401f439,
@@ -474,94 +332,100 @@ uint32_t nvc0_grgpc_code[] = {
 	0x01e4b604,
 	0xfe051efd,
 	0x21f50018,
-	0x0ef404c3,
-/* 0x0431: main_not_ctx_xfer */
+	0x0ef404ad,
+/* 0x0419: main_not_ctx_xfer */
 	0x10ef94d3,
 	0xf501f5f0,
-	0xf402ec21,
-/* 0x043e: ih */
+	0xf402fe21,
+/* 0x0426: ih */
 	0x80f9c60e,
 	0xf90188fe,
 	0xf990f980,
 	0xf9b0f9a0,
 	0xf9e0f9d0,
-	0x800acff0,
-	0xf404abc4,
-	0xb7f11d0b,
-	0xd7f01900,
-	0x40becf1c,
-	0xf400bfcf,
-	0xb0b70421,
-	0xe7f00400,
-	0x00bed001,
-/* 0x0474: ih_no_fifo */
-	0xfc400ad0,
-	0xfce0fcf0,
-	0xfcb0fcd0,
-	0xfc90fca0,
-	0x0088fe80,
-	0x32f480fc,
-/* 0x048f: hub_barrier_done */
-	0xf001f800,
-	0x0e9801f7,
-	0x04febb00,
-	0x9418e7f1,
-	0xf440e3f0,
-	0x00f88d21,
-/* 0x04a4: ctx_redswitch */
-	0x0614e7f1,
-	0xf006e4b6,
-	0xefd020f7,
-	0x08f7f000,
-/* 0x04b4: ctx_redswitch_delay */
-	0xf401f2b6,
-	0xf7f1fd1b,
-	0xefd00a20,
-/* 0x04c3: ctx_xfer */
-	0xf100f800,
-	0xb60a0417,
-	0x1fd00614,
-	0x0711f400,
-	0x04a421f5,
-/* 0x04d4: ctx_xfer_not_load */
-	0x4afc17f1,
-	0xf00213f0,
-	0x12d00c27,
-	0x0721f500,
-	0xfc27f102,
-	0x0223f047,
-	0xf00020d0,
-	0x20b6012c,
-	0x0012d003,
+	0xcf04bdf0,
+	0xabc4800a,
+	0x1d0bf404,
+	0x1900b7f1,
+	0xcf1cd7f0,
+	0xbfcf40be,
+	0x0421f400,
+	0x0400b0b7,
+	0xd001e7f0,
+/* 0x045e: ih_no_fifo */
+	0x0ad000be,
+	0xfcf0fc40,
+	0xfcd0fce0,
+	0xfca0fcb0,
+	0xfe80fc90,
+	0x80fc0088,
+	0xf80032f4,
+/* 0x0479: hub_barrier_done */
+	0x01f7f001,
+	0xbb040e98,
+	0xe7f104fe,
+	0xe3f09418,
+	0x8d21f440,
+/* 0x048e: ctx_redswitch */
+	0xe7f100f8,
+	0xe4b60614,
+	0x20f7f006,
+	0xf000efd0,
+/* 0x049e: ctx_redswitch_delay */
+	0xf2b608f7,
+	0xfd1bf401,
+	0x0a20f7f1,
+	0xf800efd0,
+/* 0x04ad: ctx_xfer */
+	0x0417f100,
+	0x0614b60a,
+	0xf4001fd0,
+	0x21f50711,
+/* 0x04be: ctx_xfer_not_load */
+	0x17f1048e,
+	0x13f04afc,
+	0x0c27f002,
+	0xf50012d0,
+	0xf1021521,
+	0xf047fc27,
+	0x20d00223,
+	0x012cf000,
+	0xd00320b6,
+	0xacf00012,
+	0x02a5f001,
+	0xf000b7f0,
+	0x0c9850b3,
+	0x0fc4b604,
+	0x9800bcbb,
+	0x0d98000c,
+	0x00e7f001,
+	0x016621f5,
 	0xf001acf0,
-	0xb7f002a5,
-	0x50b3f000,
-	0xb6000c98,
-	0xbcbb0fc4,
-	0x010c9800,
-	0xf0020d98,
-	0x21f500e7,
-	0xacf0015c,
-	0x04a5f001,
-	0x4000b7f1,
-	0x9850b3f0,
-	0xc4b6000c,
-	0x00bcbb0f,
-	0x98050c98,
-	0x0f98060d,
-	0x00e7f104,
-	0x5c21f508,
-	0x0721f501,
-	0x0601f402,
-/* 0x054b: ctx_xfer_post */
-	0xf11412f4,
-	0xf04afc17,
-	0x27f00213,
-	0x0012d00d,
-	0x020721f5,
-/* 0x055c: ctx_xfer_done */
-	0x048f21f5,
-	0x000000f8,
+	0xb7f104a5,
+	0xb3f04000,
+	0x040c9850,
+	0xbb0fc4b6,
+	0x0c9800bc,
+	0x020d9801,
+	0xf1060f98,
+	0xf50800e7,
+	0xf5016621,
+	0xf4021521,
+	0x12f40601,
+/* 0x0535: ctx_xfer_post */
+	0xfc17f114,
+	0x0213f04a,
+	0xd00d27f0,
+	0x21f50012,
+/* 0x0546: ctx_xfer_done */
+	0x21f50215,
+	0x00f80479,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
 	0x00000000,
 	0x00000000,
 	0x00000000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#define NV_PGRAPH_GPCX_UNK__SIZE                                     0x00000001
+
+#define CHIPSET GF117
+#include "macros.fuc"
+
+.section #nvd7_grgpc_data
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "gpc.fuc"
+#undef INCLUDE_DATA
+
+.section #nvd7_grgpc_code
+#define INCLUDE_CODE
+bra #init
+#include "com.fuc"
+#include "gpc.fuc"
+.align 256
+#undef INCLUDE_CODE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,475 @@
+uint32_t nvd7_grgpc_data[] = {
+/* 0x0000: gpc_mmio_list_head */
+	0x0000006c,
+/* 0x0004: gpc_mmio_list_tail */
+/* 0x0004: tpc_mmio_list_head */
+	0x0000006c,
+/* 0x0008: tpc_mmio_list_tail */
+/* 0x0008: unk_mmio_list_head */
+	0x0000006c,
+/* 0x000c: unk_mmio_list_tail */
+	0x0000006c,
+/* 0x0010: gpc_id */
+	0x00000000,
+/* 0x0014: tpc_count */
+	0x00000000,
+/* 0x0018: tpc_mask */
+	0x00000000,
+/* 0x001c: unk_count */
+	0x00000000,
+/* 0x0020: unk_mask */
+	0x00000000,
+/* 0x0024: cmd_queue */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
+
+uint32_t nvd7_grgpc_code[] = {
+	0x03180ef5,
+/* 0x0004: queue_put */
+	0x9800d898,
+	0x86f001d9,
+	0x0489b808,
+	0xf00c1bf4,
+	0x21f502f7,
+	0x00f802fe,
+/* 0x001c: queue_put_next */
+	0xb60798c4,
+	0x8dbb0384,
+	0x0880b600,
+	0x80008e80,
+	0x90b6018f,
+	0x0f94f001,
+	0xf801d980,
+/* 0x0039: queue_get */
+	0x0131f400,
+	0x9800d898,
+	0x89b801d9,
+	0x210bf404,
+	0xb60789c4,
+	0x9dbb0394,
+	0x0890b600,
+	0x98009e98,
+	0x80b6019f,
+	0x0f84f001,
+	0xf400d880,
+/* 0x0066: queue_get_done */
+	0x00f80132,
+/* 0x0068: nv_rd32 */
+	0x0728b7f1,
+	0xb906b4b6,
+	0xc9f002ec,
+	0x00bcd01f,
+/* 0x0078: nv_rd32_wait */
+	0xc800bccf,
+	0x1bf41fcc,
+	0x06a7f0fa,
+	0x010921f5,
+	0xf840bfcf,
+/* 0x008d: nv_wr32 */
+	0x28b7f100,
+	0x06b4b607,
+	0xb980bfd0,
+	0xc9f002ec,
+	0x1ec9f01f,
+/* 0x00a3: nv_wr32_wait */
+	0xcf00bcd0,
+	0xccc800bc,
+	0xfa1bf41f,
+/* 0x00ae: watchdog_reset */
+	0x87f100f8,
+	0x84b60430,
+	0x1ff9f006,
+	0xf8008fd0,
+/* 0x00bd: watchdog_clear */
+	0x3087f100,
+	0x0684b604,
+	0xf80080d0,
+/* 0x00c9: wait_donez */
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x07f104bd,
+	0x03f00600,
+	0x000ad002,
+/* 0x00e6: wait_donez_ne */
+	0x87f104bd,
+	0x83f00000,
+	0x0088cf01,
+	0xf4888aff,
+	0x94bdf31b,
+	0xf10099f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0109: wait_doneo */
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x87f104bd,
+	0x84b60818,
+	0x008ad006,
+/* 0x0124: wait_doneo_e */
+	0x040087f1,
+	0xcf0684b6,
+	0x8aff0088,
+	0xf30bf488,
+	0x99f094bd,
+	0x0007f100,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x0147: mmctx_size */
+	0xbd00f804,
+/* 0x0149: nv_mmctx_size_loop */
+	0x00e89894,
+	0xb61a85b6,
+	0x84b60180,
+	0x0098bb02,
+	0xb804e0b6,
+	0x1bf404ef,
+	0x029fb9eb,
+/* 0x0166: mmctx_xfer */
+	0x94bd00f8,
+	0xf10199f0,
+	0xf00f0007,
+	0x09d00203,
+	0xf104bd00,
+	0xb6071087,
+	0x94bd0684,
+	0xf405bbfd,
+	0x8bd0090b,
+	0x0099f000,
+/* 0x018c: mmctx_base_disabled */
+	0xf405eefd,
+	0x8ed00c0b,
+	0xc08fd080,
+/* 0x019b: mmctx_multi_disabled */
+	0xb70199f0,
+	0xc8010080,
+	0xb4b600ab,
+	0x0cb9f010,
+	0xb601aec8,
+	0xbefd11e4,
+	0x008bd005,
+/* 0x01b4: mmctx_exec_loop */
+/* 0x01b4: mmctx_wait_free */
+	0xf0008ecf,
+	0x0bf41fe4,
+	0x00ce98fa,
+	0xd005e9fd,
+	0xc0b6c08e,
+	0x04cdb804,
+	0xc8e81bf4,
+	0x1bf402ab,
+/* 0x01d5: mmctx_fini_wait */
+	0x008bcf18,
+	0xb01fb4f0,
+	0x1bf410b4,
+	0x02a7f0f7,
+	0xf4c921f4,
+/* 0x01ea: mmctx_stop */
+	0xabc81b0e,
+	0x10b4b600,
+	0xf00cb9f0,
+	0x8bd012b9,
+/* 0x01f9: mmctx_stop_wait */
+	0x008bcf00,
+	0xf412bbc8,
+/* 0x0202: mmctx_done */
+	0x94bdfa1b,
+	0xf10199f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0215: strand_wait */
+	0xf0a0f900,
+	0x21f402a7,
+	0xf8a0fcc9,
+/* 0x0221: strand_pre */
+	0xfc87f100,
+	0x0283f04a,
+	0xd00c97f0,
+	0x21f50089,
+	0x00f80215,
+/* 0x0234: strand_post */
+	0x4afc87f1,
+	0xf00283f0,
+	0x89d00d97,
+	0x1521f500,
+/* 0x0247: strand_set */
+	0xf100f802,
+	0xf04ffca7,
+	0xaba202a3,
+	0xc7f00500,
+	0x00acd00f,
+	0xd00bc7f0,
+	0x21f500bc,
+	0xaed00215,
+	0x0ac7f000,
+	0xf500bcd0,
+	0xf8021521,
+/* 0x0271: strand_ctx_init */
+	0xf094bd00,
+	0x07f10399,
+	0x03f00f00,
+	0x0009d002,
+	0x21f504bd,
+	0xe7f00221,
+	0x4721f503,
+	0xfca7f102,
+	0x02a3f046,
+	0x0400aba0,
+	0xf040a0d0,
+	0xbcd001c7,
+	0x1521f500,
+	0x010c9202,
+	0xf000acd0,
+	0xbcd002c7,
+	0x1521f500,
+	0x3421f502,
+	0x8087f102,
+	0x0684b608,
+	0xb70089cf,
+	0x95220080,
+/* 0x02ca: ctx_init_strand_loop */
+	0x8ed008fe,
+	0x408ed000,
+	0xb6808acf,
+	0xa0b606a5,
+	0x00eabb01,
+	0xb60480b6,
+	0x1bf40192,
+	0x08e4b6e8,
+	0xbdf2efbc,
+	0x0399f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+/* 0x02fe: error */
+	0xe0f900f8,
+	0x9814e7f1,
+	0xf440e3f0,
+	0xe0b78d21,
+	0xf7f0041c,
+	0x8d21f401,
+	0x00f8e0fc,
+/* 0x0318: init */
+	0x04fe04bd,
+	0x0017f100,
+	0x0227f012,
+	0xf10012d0,
+	0xfe047017,
+	0x17f10010,
+	0x10d00400,
+	0x0427f0c0,
+	0xf40012d0,
+	0x17f11031,
+	0x14b60608,
+	0x0012cf06,
+	0xf00137f0,
+	0x32bb1f24,
+	0x0132b604,
+	0x80050280,
+	0x10b70603,
+	0x12cf0400,
+	0x04028000,
+	0x0c30e7f1,
+	0xbd50e3f0,
+	0xbd34bd24,
+/* 0x0371: init_unk_loop */
+	0x6821f444,
+	0xf400f6b0,
+	0xf7f00f0b,
+	0x04f2bb01,
+	0xb6054ffd,
+/* 0x0386: init_unk_next */
+	0x20b60130,
+	0x04e0b601,
+	0xf40126b0,
+/* 0x0392: init_unk_done */
+	0x0380e21b,
+	0x08048007,
+	0x010027f1,
+	0xcf0223f0,
+	0x34bd0022,
+	0x070047f1,
+	0x950644b6,
+	0x45d00825,
+	0x4045d000,
+	0x98000e98,
+	0x21f5010f,
+	0x2fbb0147,
+	0x003fbb00,
+	0x98010e98,
+	0x21f5020f,
+	0x0e980147,
+	0x00effd05,
+	0xbb002ebb,
+	0x0e98003e,
+	0x030f9802,
+	0x014721f5,
+	0xfd070e98,
+	0x2ebb00ef,
+	0x003ebb00,
+	0x130040b7,
+	0xd00235b6,
+	0x25b60043,
+	0x0635b608,
+	0xb60120b6,
+	0x24b60130,
+	0x0834b608,
+	0xf5022fb9,
+	0xbb027121,
+	0x07f1003f,
+	0x03f00100,
+	0x0003d002,
+	0x24bd04bd,
+	0xf11f29f0,
+	0xf0080007,
+	0x02d00203,
+/* 0x0433: main */
+	0xf404bd00,
+	0x28f40031,
+	0x24d7f000,
+	0xf43921f4,
+	0xe4b0f401,
+	0x1e18f404,
+	0xf00181fe,
+	0x20bd0627,
+	0xb60412fd,
+	0x1efd01e4,
+	0x0018fe05,
+	0x04f721f5,
+/* 0x0463: main_not_ctx_xfer */
+	0x94d30ef4,
+	0xf5f010ef,
+	0xfe21f501,
+	0xc60ef402,
+/* 0x0470: ih */
+	0x88fe80f9,
+	0xf980f901,
+	0xf9a0f990,
+	0xf9d0f9b0,
+	0xbdf0f9e0,
+	0x800acf04,
+	0xf404abc4,
+	0xb7f11d0b,
+	0xd7f01900,
+	0x40becf24,
+	0xf400bfcf,
+	0xb0b70421,
+	0xe7f00400,
+	0x00bed001,
+/* 0x04a8: ih_no_fifo */
+	0xfc400ad0,
+	0xfce0fcf0,
+	0xfcb0fcd0,
+	0xfc90fca0,
+	0x0088fe80,
+	0x32f480fc,
+/* 0x04c3: hub_barrier_done */
+	0xf001f800,
+	0x0e9801f7,
+	0x04febb04,
+	0x9418e7f1,
+	0xf440e3f0,
+	0x00f88d21,
+/* 0x04d8: ctx_redswitch */
+	0x0614e7f1,
+	0xf006e4b6,
+	0xefd020f7,
+	0x08f7f000,
+/* 0x04e8: ctx_redswitch_delay */
+	0xf401f2b6,
+	0xf7f1fd1b,
+	0xefd00a20,
+/* 0x04f7: ctx_xfer */
+	0xf100f800,
+	0xb60a0417,
+	0x1fd00614,
+	0x0711f400,
+	0x04d821f5,
+/* 0x0508: ctx_xfer_not_load */
+	0x4afc17f1,
+	0xf00213f0,
+	0x12d00c27,
+	0x1521f500,
+	0xfc27f102,
+	0x0223f047,
+	0xf00020d0,
+	0x20b6012c,
+	0x0012d003,
+	0xf001acf0,
+	0xb7f002a5,
+	0x50b3f000,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x000c9800,
+	0xf0010d98,
+	0x21f500e7,
+	0xacf00166,
+	0x00b7f101,
+	0x50b3f040,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x010c9800,
+	0x98020d98,
+	0xe7f1060f,
+	0x21f50800,
+	0xacf00166,
+	0x04a5f001,
+	0x3000b7f1,
+	0x9850b3f0,
+	0xc4b6040c,
+	0x00bcbb0f,
+	0x98020c98,
+	0x0f98030d,
+	0x00e7f108,
+	0x6621f502,
+	0x1521f501,
+	0x0601f402,
+/* 0x05a3: ctx_xfer_post */
+	0xf11412f4,
+	0xf04afc17,
+	0x27f00213,
+	0x0012d00d,
+	0x021521f5,
+/* 0x05b4: ctx_xfer_done */
+	0x04c321f5,
+	0x000000f8,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,5 @@
-/* fuc microcode for nve0 PGRAPH/GPC
- *
- * Copyright 2011 Red Hat Inc.
+/*
+ * Copyright 2013 Red Hat Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -20,437 +19,24 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-/* To build:
- *    m4 nve0_grgpc.fuc | envyas -a -w -m fuc -V nva3 -o nve0_grgpc.fuc.h
- */
+#define NV_PGRAPH_GPCX_UNK__SIZE                                     0x00000001
 
-/* TODO
- * - bracket certain functions with scratch writes, useful for debugging
- * - watchdog timer around ctx operations
- */
+#define CHIPSET GK100
+#include "macros.fuc"
 
 .section #nve0_grgpc_data
-include(`nve0.fuc')
-gpc_id:			.b32 0
-gpc_mmio_list_head:	.b32 0
-gpc_mmio_list_tail:	.b32 0
-
-tpc_count:		.b32 0
-tpc_mask:		.b32 0
-tpc_mmio_list_head:	.b32 0
-tpc_mmio_list_tail:	.b32 0
-
-cmd_queue:		queue_init
-
-// chipset descriptions
-chipsets:
-.b8  0xe4 0 0 0
-.b16 #nve4_gpc_mmio_head
-.b16 #nve4_gpc_mmio_tail
-.b16 #nve4_tpc_mmio_head
-.b16 #nve4_tpc_mmio_tail
-.b8  0xe7 0 0 0
-.b16 #nve4_gpc_mmio_head
-.b16 #nve4_gpc_mmio_tail
-.b16 #nve4_tpc_mmio_head
-.b16 #nve4_tpc_mmio_tail
-.b8  0xe6 0 0 0
-.b16 #nve4_gpc_mmio_head
-.b16 #nve4_gpc_mmio_tail
-.b16 #nve4_tpc_mmio_head
-.b16 #nve4_tpc_mmio_tail
-.b8  0 0 0 0
-
-// GPC mmio lists
-nve4_gpc_mmio_head:
-mmctx_data(0x000380, 1)
-mmctx_data(0x000400, 2)
-mmctx_data(0x00040c, 3)
-mmctx_data(0x000450, 9)
-mmctx_data(0x000600, 1)
-mmctx_data(0x000684, 1)
-mmctx_data(0x000700, 5)
-mmctx_data(0x000800, 1)
-mmctx_data(0x000808, 3)
-mmctx_data(0x000828, 1)
-mmctx_data(0x000830, 1)
-mmctx_data(0x0008d8, 1)
-mmctx_data(0x0008e0, 1)
-mmctx_data(0x0008e8, 6)
-mmctx_data(0x00091c, 1)
-mmctx_data(0x000924, 3)
-mmctx_data(0x000b00, 1)
-mmctx_data(0x000b08, 6)
-mmctx_data(0x000bb8, 1)
-mmctx_data(0x000c08, 1)
-mmctx_data(0x000c10, 8)
-mmctx_data(0x000c40, 1)
-mmctx_data(0x000c6c, 1)
-mmctx_data(0x000c80, 1)
-mmctx_data(0x000c8c, 1)
-mmctx_data(0x001000, 3)
-mmctx_data(0x001014, 1)
-mmctx_data(0x003024, 1)
-mmctx_data(0x0030c0, 2)
-mmctx_data(0x0030e4, 1)
-mmctx_data(0x003100, 6)
-mmctx_data(0x0031d0, 1)
-mmctx_data(0x0031e0, 2)
-nve4_gpc_mmio_tail:
-
-// TPC mmio lists
-nve4_tpc_mmio_head:
-mmctx_data(0x000048, 1)
-mmctx_data(0x000064, 1)
-mmctx_data(0x000088, 1)
-mmctx_data(0x000200, 6)
-mmctx_data(0x00021c, 2)
-mmctx_data(0x000230, 1)
-mmctx_data(0x0002c4, 1)
-mmctx_data(0x000400, 3)
-mmctx_data(0x000420, 3)
-mmctx_data(0x0004e8, 1)
-mmctx_data(0x0004f4, 1)
-mmctx_data(0x000604, 4)
-mmctx_data(0x000644, 22)
-mmctx_data(0x0006ac, 2)
-mmctx_data(0x0006c8, 1)
-mmctx_data(0x000730, 8)
-mmctx_data(0x000758, 1)
-mmctx_data(0x000778, 1)
-nve4_tpc_mmio_tail:
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "gpc.fuc"
+#undef INCLUDE_DATA
 
 .section #nve0_grgpc_code
+#define INCLUDE_CODE
 bra #init
-define(`include_code')
-include(`nve0.fuc')
-
-// reports an exception to the host
-//
-// In: $r15 error code (see nve0.fuc)
-//
-error:
-	push $r14
-	mov $r14 -0x67ec 	// 0x9814
-	sethi $r14 0x400000
-	call #nv_wr32		// HUB_CTXCTL_CC_SCRATCH[5] = error code
-	add b32 $r14 0x41c
-	mov $r15 1
-	call #nv_wr32		// HUB_CTXCTL_INTR_UP_SET
-	pop $r14
-	ret
-
-// GPC fuc initialisation, executed by triggering ucode start, will
-// fall through to main loop after completion.
-//
-// Input:
-//   CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
-//   CC_SCRATCH[1]: context base
-//
-// Output:
-//   CC_SCRATCH[0]:
-//	     31:31: set to signal completion
-//   CC_SCRATCH[1]:
-//	      31:0: GPC context size
-//
-init:
-	clear b32 $r0
-	mov $sp $r0
-
-	// enable fifo access
-	mov $r1 0x1200
-	mov $r2 2
-	iowr I[$r1 + 0x000] $r2		// FIFO_ENABLE
-
-	// setup i0 handler, and route all interrupts to it
-	mov $r1 #ih
-	mov $iv0 $r1
-	mov $r1 0x400
-	iowr I[$r1 + 0x300] $r0		// INTR_DISPATCH
-
-	// enable fifo interrupt
-	mov $r2 4
-	iowr I[$r1 + 0x000] $r2		// INTR_EN_SET
-
-	// enable interrupts
-	bset $flags ie0
-
-	// figure out which GPC we are, and how many TPCs we have
-	mov $r1 0x608
-	shl b32 $r1 6
-	iord $r2 I[$r1 + 0x000]		// UNITS
-	mov $r3 1
-	and $r2 0x1f
-	shl b32 $r3 $r2
-	sub b32 $r3 1
-	st b32 D[$r0 + #tpc_count] $r2
-	st b32 D[$r0 + #tpc_mask] $r3
-	add b32 $r1 0x400
-	iord $r2 I[$r1 + 0x000]		// MYINDEX
-	st b32 D[$r0 + #gpc_id] $r2
-
-	// find context data for this chipset
-	mov $r2 0x800
-	shl b32 $r2 6
-	iord $r2 I[$r2 + 0x000]		// CC_SCRATCH[0]
-	mov $r1 #chipsets - 12
-	init_find_chipset:
-		add b32 $r1 12
-		ld b32 $r3 D[$r1 + 0x00]
-		cmpu b32 $r3 $r2
-		bra e #init_context
-		cmpu b32 $r3 0
-		bra ne #init_find_chipset
-		// unknown chipset
-		ret
-
-	// initialise context base, and size tracking
-	init_context:
-	mov $r2 0x800
-	shl b32 $r2 6
-	iord $r2 I[$r2 + 0x100]	// CC_SCRATCH[1], initial base
-	clear b32 $r3		// track GPC context size here
-
-	// set mmctx base addresses now so we don't have to do it later,
-	// they don't currently ever change
-	mov $r4 0x700
-	shl b32 $r4 6
-	shr b32 $r5 $r2 8
-	iowr I[$r4 + 0x000] $r5		// MMCTX_SAVE_SWBASE
-	iowr I[$r4 + 0x100] $r5		// MMCTX_LOAD_SWBASE
-
-	// calculate GPC mmio context size, store the chipset-specific
-	// mmio list pointers somewhere we can get at them later without
-	// re-parsing the chipset list
-	clear b32 $r14
-	clear b32 $r15
-	ld b16 $r14 D[$r1 + 4]
-	ld b16 $r15 D[$r1 + 6]
-	st b16 D[$r0 + #gpc_mmio_list_head] $r14
-	st b16 D[$r0 + #gpc_mmio_list_tail] $r15
-	call #mmctx_size
-	add b32 $r2 $r15
-	add b32 $r3 $r15
-
-	// calculate per-TPC mmio context size, store the list pointers
-	ld b16 $r14 D[$r1 + 8]
-	ld b16 $r15 D[$r1 + 10]
-	st b16 D[$r0 + #tpc_mmio_list_head] $r14
-	st b16 D[$r0 + #tpc_mmio_list_tail] $r15
-	call #mmctx_size
-	ld b32 $r14 D[$r0 + #tpc_count]
-	mulu $r14 $r15
-	add b32 $r2 $r14
-	add b32 $r3 $r14
-
-	// round up base/size to 256 byte boundary (for strand SWBASE)
-	add b32 $r4 0x1300
-	shr b32 $r3 2
-	iowr I[$r4 + 0x000] $r3		// MMCTX_LOAD_COUNT, wtf for?!?
-	shr b32 $r2 8
-	shr b32 $r3 6
-	add b32 $r2 1
-	add b32 $r3 1
-	shl b32 $r2 8
-	shl b32 $r3 8
-
-	// calculate size of strand context data
-	mov b32 $r15 $r2
-	call #strand_ctx_init
-	add b32 $r3 $r15
-
-	// save context size, and tell HUB we're done
-	mov $r1 0x800
-	shl b32 $r1 6
-	iowr I[$r1 + 0x100] $r3		// CC_SCRATCH[1]  = context size
-	add b32 $r1 0x800
-	clear b32 $r2
-	bset $r2 31
-	iowr I[$r1 + 0x000] $r2		// CC_SCRATCH[0] |= 0x80000000
-
-// Main program loop, very simple, sleeps until woken up by the interrupt
-// handler, pulls a command from the queue and executes its handler
-//
-main:
-	bset $flags $p0
-	sleep $p0
-	mov $r13 #cmd_queue
-	call #queue_get
-	bra $p1 #main
-
-	// 0x0000-0x0003 are all context transfers
-	cmpu b32 $r14 0x04
-	bra nc #main_not_ctx_xfer
-		// fetch $flags and mask off $p1/$p2
-		mov $r1 $flags
-		mov $r2 0x0006
-		not b32 $r2
-		and $r1 $r2
-		// set $p1/$p2 according to transfer type
-		shl b32 $r14 1
-		or $r1 $r14
-		mov $flags $r1
-		// transfer context data
-		call #ctx_xfer
-		bra #main
-
-	main_not_ctx_xfer:
-	shl b32 $r15 $r14 16
-	or $r15 E_BAD_COMMAND
-	call #error
-	bra #main
-
-// interrupt handler
-ih:
-	push $r8
-	mov $r8 $flags
-	push $r8
-	push $r9
-	push $r10
-	push $r11
-	push $r13
-	push $r14
-	push $r15
-
-	// incoming fifo command?
-	iord $r10 I[$r0 + 0x200]	// INTR
-	and $r11 $r10 0x00000004
-	bra e #ih_no_fifo
-		// queue incoming fifo command for later processing
-		mov $r11 0x1900
-		mov $r13 #cmd_queue
-		iord $r14 I[$r11 + 0x100]	// FIFO_CMD
-		iord $r15 I[$r11 + 0x000]	// FIFO_DATA
-		call #queue_put
-		add b32 $r11 0x400
-		mov $r14 1
-		iowr I[$r11 + 0x000] $r14	// FIFO_ACK
-
-	// ack, and wake up main()
-	ih_no_fifo:
-	iowr I[$r0 + 0x100] $r10	// INTR_ACK
-
-	pop $r15
-	pop $r14
-	pop $r13
-	pop $r11
-	pop $r10
-	pop $r9
-	pop $r8
-	mov $flags $r8
-	pop $r8
-	bclr $flags $p0
-	iret
-
-// Set this GPC's bit in HUB_BAR, used to signal completion of various
-// activities to the HUB fuc
-//
-hub_barrier_done:
-	mov $r15 1
-	ld b32 $r14 D[$r0 + #gpc_id]
-	shl b32 $r15 $r14
-	mov $r14 -0x6be8 	// 0x409418 - HUB_BAR_SET
-	sethi $r14 0x400000
-	call #nv_wr32
-	ret
-
-// Disables various things, waits a bit, and re-enables them..
-//
-// Not sure how exactly this helps, perhaps "ENABLE" is not such a
-// good description for the bits we turn off?  Anyways, without this,
-// funny things happen.
-//
-ctx_redswitch:
-	mov $r14 0x614
-	shl b32 $r14 6
-	mov $r15 0x020
-	iowr I[$r14] $r15	// GPC_RED_SWITCH = POWER
-	mov $r15 8
-	ctx_redswitch_delay:
-		sub b32 $r15 1
-		bra ne #ctx_redswitch_delay
-	mov $r15 0xa20
-	iowr I[$r14] $r15	// GPC_RED_SWITCH = UNK11, ENABLE, POWER
-	ret
-
-// Transfer GPC context data between GPU and storage area
-//
-// In: $r15 context base address
-//     $p1 clear on save, set on load
-//     $p2 set if opposite direction done/will be done, so:
-//		on save it means: "a load will follow this save"
-//		on load it means: "a save preceeded this load"
-//
-ctx_xfer:
-	// set context base address
-	mov $r1 0xa04
-	shl b32 $r1 6
-	iowr I[$r1 + 0x000] $r15// MEM_BASE
-	bra not $p1 #ctx_xfer_not_load
-		call #ctx_redswitch
-	ctx_xfer_not_load:
-
-	// strands
-	mov $r1 0x4afc
-	sethi $r1 0x20000
-	mov $r2 0xc
-	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x0c
-	call #strand_wait
-	mov $r2 0x47fc
-	sethi $r2 0x20000
-	iowr I[$r2] $r0		// STRAND_FIRST_GENE(0x3f) = 0x00
-	xbit $r2 $flags $p1
-	add b32 $r2 3
-	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
-
-	// mmio context
-	xbit $r10 $flags $p1	// direction
-	or $r10 2		// first
-	mov $r11 0x0000
-	sethi $r11 0x500000
-	ld b32 $r12 D[$r0 + #gpc_id]
-	shl b32 $r12 15
-	add b32 $r11 $r12	// base = NV_PGRAPH_GPCn
-	ld b32 $r12 D[$r0 + #gpc_mmio_list_head]
-	ld b32 $r13 D[$r0 + #gpc_mmio_list_tail]
-	mov $r14 0		// not multi
-	call #mmctx_xfer
-
-	// per-TPC mmio context
-	xbit $r10 $flags $p1	// direction
-	or $r10 4		// last
-	mov $r11 0x4000
-	sethi $r11 0x500000	// base = NV_PGRAPH_GPC0_TPC0
-	ld b32 $r12 D[$r0 + #gpc_id]
-	shl b32 $r12 15
-	add b32 $r11 $r12	// base = NV_PGRAPH_GPCn_TPC0
-	ld b32 $r12 D[$r0 + #tpc_mmio_list_head]
-	ld b32 $r13 D[$r0 + #tpc_mmio_list_tail]
-	ld b32 $r15 D[$r0 + #tpc_mask]
-	mov $r14 0x800		// stride = 0x800
-	call #mmctx_xfer
-
-	// wait for strands to finish
-	call #strand_wait
-
-	// if load, or a save without a load following, do some
-	// unknown stuff that's done after finishing a block of
-	// strand commands
-	bra $p1 #ctx_xfer_post
-	bra not $p2 #ctx_xfer_done
-	ctx_xfer_post:
-		mov $r1 0x4afc
-		sethi $r1 0x20000
-		mov $r2 0xd
-		iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x0d
-		call #strand_wait
-
-	// mark completion in HUB's barrier
-	ctx_xfer_done:
-	call #hub_barrier_done
-	ret
-
+#include "com.fuc"
+#include "gpc.fuc"
 .align 256
+#undef INCLUDE_CODE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,20 +1,25 @@
 uint32_t nve0_grgpc_data[] = {
-/* 0x0000: gpc_id */
-	0x00000000,
-/* 0x0004: gpc_mmio_list_head */
-	0x00000000,
-/* 0x0008: gpc_mmio_list_tail */
-	0x00000000,
-/* 0x000c: tpc_count */
+/* 0x0000: gpc_mmio_list_head */
+	0x0000006c,
+/* 0x0004: gpc_mmio_list_tail */
+/* 0x0004: tpc_mmio_list_head */
+	0x0000006c,
+/* 0x0008: tpc_mmio_list_tail */
+/* 0x0008: unk_mmio_list_head */
+	0x0000006c,
+/* 0x000c: unk_mmio_list_tail */
+	0x0000006c,
+/* 0x0010: gpc_id */
 	0x00000000,
-/* 0x0010: tpc_mask */
+/* 0x0014: tpc_count */
 	0x00000000,
-/* 0x0014: tpc_mmio_list_head */
+/* 0x0018: tpc_mask */
 	0x00000000,
-/* 0x0018: tpc_mmio_list_tail */
+/* 0x001c: unk_count */
 	0x00000000,
-/* 0x001c: cmd_queue */
+/* 0x0020: unk_mask */
 	0x00000000,
+/* 0x0024: cmd_queue */
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -32,82 +37,18 @@ uint32_t nve0_grgpc_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
-/* 0x0064: chipsets */
-	0x000000e4,
-	0x0110008c,
-	0x01580110,
-	0x000000e7,
-	0x0110008c,
-	0x01580110,
-	0x000000e6,
-	0x0110008c,
-	0x01580110,
 	0x00000000,
-/* 0x008c: nve4_gpc_mmio_head */
-	0x00000380,
-	0x04000400,
-	0x0800040c,
-	0x20000450,
-	0x00000600,
-	0x00000684,
-	0x10000700,
-	0x00000800,
-	0x08000808,
-	0x00000828,
-	0x00000830,
-	0x000008d8,
-	0x000008e0,
-	0x140008e8,
-	0x0000091c,
-	0x08000924,
-	0x00000b00,
-	0x14000b08,
-	0x00000bb8,
-	0x00000c08,
-	0x1c000c10,
-	0x00000c40,
-	0x00000c6c,
-	0x00000c80,
-	0x00000c8c,
-	0x08001000,
-	0x00001014,
-	0x00003024,
-	0x040030c0,
-	0x000030e4,
-	0x14003100,
-	0x000031d0,
-	0x040031e0,
-/* 0x0110: nve4_gpc_mmio_tail */
-/* 0x0110: nve4_tpc_mmio_head */
-	0x00000048,
-	0x00000064,
-	0x00000088,
-	0x14000200,
-	0x0400021c,
-	0x00000230,
-	0x000002c4,
-	0x08000400,
-	0x08000420,
-	0x000004e8,
-	0x000004f4,
-	0x0c000604,
-	0x54000644,
-	0x040006ac,
-	0x000006c8,
-	0x1c000730,
-	0x00000758,
-	0x00000778,
 };
 
 uint32_t nve0_grgpc_code[] = {
-	0x03060ef5,
+	0x03180ef5,
 /* 0x0004: queue_put */
 	0x9800d898,
 	0x86f001d9,
 	0x0489b808,
 	0xf00c1bf4,
 	0x21f502f7,
-	0x00f802ec,
+	0x00f802fe,
 /* 0x001c: queue_put_next */
 	0xb60798c4,
 	0x8dbb0384,
@@ -139,7 +80,7 @@ uint32_t nve0_grgpc_code[] = {
 	0xc800bccf,
 	0x1bf41fcc,
 	0x06a7f0fa,
-	0x010321f5,
+	0x010921f5,
 	0xf840bfcf,
 /* 0x008d: nv_wr32 */
 	0x28b7f100,
@@ -161,63 +102,66 @@ uint32_t nve0_grgpc_code[] = {
 	0x0684b604,
 	0xf80080d0,
 /* 0x00c9: wait_donez */
-	0x3c87f100,
-	0x0684b608,
-	0x99f094bd,
-	0x0089d000,
-	0x081887f1,
-	0xd00684b6,
-/* 0x00e2: wait_done_wait_donez */
-	0x87f1008a,
-	0x84b60400,
-	0x0088cf06,
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x07f104bd,
+	0x03f00600,
+	0x000ad002,
+/* 0x00e6: wait_donez_ne */
+	0x87f104bd,
+	0x83f00000,
+	0x0088cf01,
 	0xf4888aff,
-	0x87f1f31b,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00099,
-/* 0x0103: wait_doneo */
-	0xf100f800,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00099f0,
-	0x87f10089,
+	0x94bdf31b,
+	0xf10099f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0109: wait_doneo */
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x87f104bd,
 	0x84b60818,
 	0x008ad006,
-/* 0x011c: wait_done_wait_doneo */
+/* 0x0124: wait_doneo_e */
 	0x040087f1,
 	0xcf0684b6,
 	0x8aff0088,
 	0xf30bf488,
-	0x085c87f1,
-	0xbd0684b6,
-	0x0099f094,
-	0xf80089d0,
-/* 0x013d: mmctx_size */
-/* 0x013f: nv_mmctx_size_loop */
-	0x9894bd00,
-	0x85b600e8,
-	0x0180b61a,
-	0xbb0284b6,
-	0xe0b60098,
-	0x04efb804,
-	0xb9eb1bf4,
-	0x00f8029f,
-/* 0x015c: mmctx_xfer */
-	0x083c87f1,
-	0xbd0684b6,
-	0x0199f094,
-	0xf10089d0,
+	0x99f094bd,
+	0x0007f100,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x0147: mmctx_size */
+	0xbd00f804,
+/* 0x0149: nv_mmctx_size_loop */
+	0x00e89894,
+	0xb61a85b6,
+	0x84b60180,
+	0x0098bb02,
+	0xb804e0b6,
+	0x1bf404ef,
+	0x029fb9eb,
+/* 0x0166: mmctx_xfer */
+	0x94bd00f8,
+	0xf10199f0,
+	0xf00f0007,
+	0x09d00203,
+	0xf104bd00,
 	0xb6071087,
 	0x94bd0684,
 	0xf405bbfd,
 	0x8bd0090b,
 	0x0099f000,
-/* 0x0180: mmctx_base_disabled */
+/* 0x018c: mmctx_base_disabled */
 	0xf405eefd,
 	0x8ed00c0b,
 	0xc08fd080,
-/* 0x018f: mmctx_multi_disabled */
+/* 0x019b: mmctx_multi_disabled */
 	0xb70199f0,
 	0xc8010080,
 	0xb4b600ab,
@@ -225,8 +169,8 @@ uint32_t nve0_grgpc_code[] = {
 	0xb601aec8,
 	0xbefd11e4,
 	0x008bd005,
-/* 0x01a8: mmctx_exec_loop */
-/* 0x01a8: mmctx_wait_free */
+/* 0x01b4: mmctx_exec_loop */
+/* 0x01b4: mmctx_wait_free */
 	0xf0008ecf,
 	0x0bf41fe4,
 	0x00ce98fa,
@@ -235,76 +179,77 @@ uint32_t nve0_grgpc_code[] = {
 	0x04cdb804,
 	0xc8e81bf4,
 	0x1bf402ab,
-/* 0x01c9: mmctx_fini_wait */
+/* 0x01d5: mmctx_fini_wait */
 	0x008bcf18,
 	0xb01fb4f0,
 	0x1bf410b4,
 	0x02a7f0f7,
 	0xf4c921f4,
-/* 0x01de: mmctx_stop */
+/* 0x01ea: mmctx_stop */
 	0xabc81b0e,
 	0x10b4b600,
 	0xf00cb9f0,
 	0x8bd012b9,
-/* 0x01ed: mmctx_stop_wait */
+/* 0x01f9: mmctx_stop_wait */
 	0x008bcf00,
 	0xf412bbc8,
-/* 0x01f6: mmctx_done */
-	0x87f1fa1b,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00199,
-/* 0x0207: strand_wait */
-	0xf900f800,
-	0x02a7f0a0,
-	0xfcc921f4,
-/* 0x0213: strand_pre */
-	0xf100f8a0,
-	0xf04afc87,
-	0x97f00283,
-	0x0089d00c,
-	0x020721f5,
-/* 0x0226: strand_post */
-	0x87f100f8,
-	0x83f04afc,
-	0x0d97f002,
-	0xf50089d0,
-	0xf8020721,
-/* 0x0239: strand_set */
-	0xfca7f100,
-	0x02a3f04f,
-	0x0500aba2,
-	0xd00fc7f0,
-	0xc7f000ac,
-	0x00bcd00b,
-	0x020721f5,
-	0xf000aed0,
-	0xbcd00ac7,
-	0x0721f500,
-/* 0x0263: strand_ctx_init */
-	0xf100f802,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00399f0,
+/* 0x0202: mmctx_done */
+	0x94bdfa1b,
+	0xf10199f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0215: strand_wait */
+	0xf0a0f900,
+	0x21f402a7,
+	0xf8a0fcc9,
+/* 0x0221: strand_pre */
+	0xfc87f100,
+	0x0283f04a,
+	0xd00c97f0,
 	0x21f50089,
-	0xe7f00213,
-	0x3921f503,
+	0x00f80215,
+/* 0x0234: strand_post */
+	0x4afc87f1,
+	0xf00283f0,
+	0x89d00d97,
+	0x1521f500,
+/* 0x0247: strand_set */
+	0xf100f802,
+	0xf04ffca7,
+	0xaba202a3,
+	0xc7f00500,
+	0x00acd00f,
+	0xd00bc7f0,
+	0x21f500bc,
+	0xaed00215,
+	0x0ac7f000,
+	0xf500bcd0,
+	0xf8021521,
+/* 0x0271: strand_ctx_init */
+	0xf094bd00,
+	0x07f10399,
+	0x03f00f00,
+	0x0009d002,
+	0x21f504bd,
+	0xe7f00221,
+	0x4721f503,
 	0xfca7f102,
 	0x02a3f046,
 	0x0400aba0,
 	0xf040a0d0,
 	0xbcd001c7,
-	0x0721f500,
+	0x1521f500,
 	0x010c9202,
 	0xf000acd0,
 	0xbcd002c7,
-	0x0721f500,
-	0x2621f502,
+	0x1521f500,
+	0x3421f502,
 	0x8087f102,
 	0x0684b608,
 	0xb70089cf,
 	0x95220080,
-/* 0x02ba: ctx_init_strand_loop */
+/* 0x02ca: ctx_init_strand_loop */
 	0x8ed008fe,
 	0x408ed000,
 	0xb6808acf,
@@ -313,150 +258,160 @@ uint32_t nve0_grgpc_code[] = {
 	0xb60480b6,
 	0x1bf40192,
 	0x08e4b6e8,
-	0xf1f2efbc,
-	0xb6085c87,
-	0x94bd0684,
-	0xd00399f0,
-	0x00f80089,
-/* 0x02ec: error */
-	0xe7f1e0f9,
-	0xe3f09814,
-	0x8d21f440,
-	0x041ce0b7,
-	0xf401f7f0,
-	0xe0fc8d21,
-/* 0x0306: init */
-	0x04bd00f8,
-	0xf10004fe,
-	0xf0120017,
-	0x12d00227,
-	0x3e17f100,
-	0x0010fe04,
-	0x040017f1,
-	0xf0c010d0,
-	0x12d00427,
-	0x1031f400,
-	0x060817f1,
-	0xcf0614b6,
-	0x37f00012,
-	0x1f24f001,
-	0xb60432bb,
-	0x02800132,
-	0x04038003,
-	0x040010b7,
-	0x800012cf,
-	0x27f10002,
-	0x24b60800,
-	0x0022cf06,
-/* 0x035f: init_find_chipset */
-	0xb65817f0,
-	0x13980c10,
-	0x0432b800,
-	0xb00b0bf4,
-	0x1bf40034,
-/* 0x0373: init_context */
-	0xf100f8f1,
-	0xb6080027,
-	0x22cf0624,
-	0xf134bd40,
-	0xb6070047,
-	0x25950644,
-	0x0045d008,
-	0xbd4045d0,
-	0x58f4bde4,
-	0x1f58021e,
-	0x020e4003,
-	0xf5040f40,
-	0xbb013d21,
-	0x3fbb002f,
-	0x041e5800,
-	0x40051f58,
-	0x0f400a0e,
-	0x3d21f50c,
-	0x030e9801,
-	0xbb00effd,
-	0x3ebb002e,
-	0x0040b700,
-	0x0235b613,
-	0xb60043d0,
-	0x35b60825,
-	0x0120b606,
-	0xb60130b6,
-	0x34b60824,
-	0x022fb908,
-	0x026321f5,
-	0xf1003fbb,
-	0xb6080017,
-	0x13d00614,
-	0x0010b740,
-	0xf024bd08,
-	0x12d01f29,
-/* 0x0401: main */
-	0x0031f400,
-	0xf00028f4,
-	0x21f41cd7,
-	0xf401f439,
-	0xf404e4b0,
-	0x81fe1e18,
-	0x0627f001,
-	0x12fd20bd,
-	0x01e4b604,
-	0xfe051efd,
-	0x21f50018,
-	0x0ef404c3,
-/* 0x0431: main_not_ctx_xfer */
-	0x10ef94d3,
-	0xf501f5f0,
-	0xf402ec21,
-/* 0x043e: ih */
-	0x80f9c60e,
-	0xf90188fe,
-	0xf990f980,
-	0xf9b0f9a0,
-	0xf9e0f9d0,
-	0x800acff0,
+	0xbdf2efbc,
+	0x0399f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+/* 0x02fe: error */
+	0xe0f900f8,
+	0x9814e7f1,
+	0xf440e3f0,
+	0xe0b78d21,
+	0xf7f0041c,
+	0x8d21f401,
+	0x00f8e0fc,
+/* 0x0318: init */
+	0x04fe04bd,
+	0x0017f100,
+	0x0227f012,
+	0xf10012d0,
+	0xfe047017,
+	0x17f10010,
+	0x10d00400,
+	0x0427f0c0,
+	0xf40012d0,
+	0x17f11031,
+	0x14b60608,
+	0x0012cf06,
+	0xf00137f0,
+	0x32bb1f24,
+	0x0132b604,
+	0x80050280,
+	0x10b70603,
+	0x12cf0400,
+	0x04028000,
+	0x0c30e7f1,
+	0xbd50e3f0,
+	0xbd34bd24,
+/* 0x0371: init_unk_loop */
+	0x6821f444,
+	0xf400f6b0,
+	0xf7f00f0b,
+	0x04f2bb01,
+	0xb6054ffd,
+/* 0x0386: init_unk_next */
+	0x20b60130,
+	0x04e0b601,
+	0xf40126b0,
+/* 0x0392: init_unk_done */
+	0x0380e21b,
+	0x08048007,
+	0x010027f1,
+	0xcf0223f0,
+	0x34bd0022,
+	0x070047f1,
+	0x950644b6,
+	0x45d00825,
+	0x4045d000,
+	0x98000e98,
+	0x21f5010f,
+	0x2fbb0147,
+	0x003fbb00,
+	0x98010e98,
+	0x21f5020f,
+	0x0e980147,
+	0x00effd05,
+	0xbb002ebb,
+	0x0e98003e,
+	0x030f9802,
+	0x014721f5,
+	0xfd070e98,
+	0x2ebb00ef,
+	0x003ebb00,
+	0x130040b7,
+	0xd00235b6,
+	0x25b60043,
+	0x0635b608,
+	0xb60120b6,
+	0x24b60130,
+	0x0834b608,
+	0xf5022fb9,
+	0xbb027121,
+	0x07f1003f,
+	0x03f00100,
+	0x0003d002,
+	0x24bd04bd,
+	0xf11f29f0,
+	0xf0080007,
+	0x02d00203,
+/* 0x0433: main */
+	0xf404bd00,
+	0x28f40031,
+	0x24d7f000,
+	0xf43921f4,
+	0xe4b0f401,
+	0x1e18f404,
+	0xf00181fe,
+	0x20bd0627,
+	0xb60412fd,
+	0x1efd01e4,
+	0x0018fe05,
+	0x04f721f5,
+/* 0x0463: main_not_ctx_xfer */
+	0x94d30ef4,
+	0xf5f010ef,
+	0xfe21f501,
+	0xc60ef402,
+/* 0x0470: ih */
+	0x88fe80f9,
+	0xf980f901,
+	0xf9a0f990,
+	0xf9d0f9b0,
+	0xbdf0f9e0,
+	0x800acf04,
 	0xf404abc4,
 	0xb7f11d0b,
 	0xd7f01900,
-	0x40becf1c,
+	0x40becf24,
 	0xf400bfcf,
 	0xb0b70421,
 	0xe7f00400,
 	0x00bed001,
-/* 0x0474: ih_no_fifo */
+/* 0x04a8: ih_no_fifo */
 	0xfc400ad0,
 	0xfce0fcf0,
 	0xfcb0fcd0,
 	0xfc90fca0,
 	0x0088fe80,
 	0x32f480fc,
-/* 0x048f: hub_barrier_done */
+/* 0x04c3: hub_barrier_done */
 	0xf001f800,
 	0x0e9801f7,
-	0x04febb00,
+	0x04febb04,
 	0x9418e7f1,
 	0xf440e3f0,
 	0x00f88d21,
-/* 0x04a4: ctx_redswitch */
+/* 0x04d8: ctx_redswitch */
 	0x0614e7f1,
 	0xf006e4b6,
 	0xefd020f7,
 	0x08f7f000,
-/* 0x04b4: ctx_redswitch_delay */
+/* 0x04e8: ctx_redswitch_delay */
 	0xf401f2b6,
 	0xf7f1fd1b,
 	0xefd00a20,
-/* 0x04c3: ctx_xfer */
+/* 0x04f7: ctx_xfer */
 	0xf100f800,
 	0xb60a0417,
 	0x1fd00614,
 	0x0711f400,
-	0x04a421f5,
-/* 0x04d4: ctx_xfer_not_load */
+	0x04d821f5,
+/* 0x0508: ctx_xfer_not_load */
 	0x4afc17f1,
 	0xf00213f0,
 	0x12d00c27,
-	0x0721f500,
+	0x1521f500,
 	0xfc27f102,
 	0x0223f047,
 	0xf00020d0,
@@ -465,57 +420,44 @@ uint32_t nve0_grgpc_code[] = {
 	0xf001acf0,
 	0xb7f002a5,
 	0x50b3f000,
-	0xb6000c98,
+	0xb6040c98,
 	0xbcbb0fc4,
-	0x010c9800,
-	0xf0020d98,
+	0x000c9800,
+	0xf0010d98,
 	0x21f500e7,
-	0xacf0015c,
+	0xacf00166,
+	0x00b7f101,
+	0x50b3f040,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x010c9800,
+	0x98020d98,
+	0xe7f1060f,
+	0x21f50800,
+	0xacf00166,
 	0x04a5f001,
-	0x4000b7f1,
+	0x3000b7f1,
 	0x9850b3f0,
-	0xc4b6000c,
+	0xc4b6040c,
 	0x00bcbb0f,
-	0x98050c98,
-	0x0f98060d,
-	0x00e7f104,
-	0x5c21f508,
-	0x0721f501,
+	0x98020c98,
+	0x0f98030d,
+	0x00e7f108,
+	0x6621f502,
+	0x1521f501,
 	0x0601f402,
-/* 0x054b: ctx_xfer_post */
+/* 0x05a3: ctx_xfer_post */
 	0xf11412f4,
 	0xf04afc17,
 	0x27f00213,
 	0x0012d00d,
-	0x020721f5,
-/* 0x055c: ctx_xfer_done */
-	0x048f21f5,
+	0x021521f5,
+/* 0x05b4: ctx_xfer_done */
+	0x04c321f5,
 	0x000000f8,
 	0x00000000,
 	0x00000000,
 	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
 	0x00000000,
 	0x00000000,
 	0x00000000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#define NV_PGRAPH_GPCX_UNK__SIZE                                     0x00000002
+
+#define CHIPSET GK110
+#include "macros.fuc"
+
+.section #nvf0_grgpc_data
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "gpc.fuc"
+#undef INCLUDE_DATA
+
+.section #nvf0_grgpc_code
+#define INCLUDE_CODE
+bra #init
+#include "com.fuc"
+#include "gpc.fuc"
+.align 256
+#undef INCLUDE_CODE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,475 @@
+uint32_t nvf0_grgpc_data[] = {
+/* 0x0000: gpc_mmio_list_head */
+	0x0000006c,
+/* 0x0004: gpc_mmio_list_tail */
+/* 0x0004: tpc_mmio_list_head */
+	0x0000006c,
+/* 0x0008: tpc_mmio_list_tail */
+/* 0x0008: unk_mmio_list_head */
+	0x0000006c,
+/* 0x000c: unk_mmio_list_tail */
+	0x0000006c,
+/* 0x0010: gpc_id */
+	0x00000000,
+/* 0x0014: tpc_count */
+	0x00000000,
+/* 0x0018: tpc_mask */
+	0x00000000,
+/* 0x001c: unk_count */
+	0x00000000,
+/* 0x0020: unk_mask */
+	0x00000000,
+/* 0x0024: cmd_queue */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
+
+uint32_t nvf0_grgpc_code[] = {
+	0x03180ef5,
+/* 0x0004: queue_put */
+	0x9800d898,
+	0x86f001d9,
+	0x0489b808,
+	0xf00c1bf4,
+	0x21f502f7,
+	0x00f802fe,
+/* 0x001c: queue_put_next */
+	0xb60798c4,
+	0x8dbb0384,
+	0x0880b600,
+	0x80008e80,
+	0x90b6018f,
+	0x0f94f001,
+	0xf801d980,
+/* 0x0039: queue_get */
+	0x0131f400,
+	0x9800d898,
+	0x89b801d9,
+	0x210bf404,
+	0xb60789c4,
+	0x9dbb0394,
+	0x0890b600,
+	0x98009e98,
+	0x80b6019f,
+	0x0f84f001,
+	0xf400d880,
+/* 0x0066: queue_get_done */
+	0x00f80132,
+/* 0x0068: nv_rd32 */
+	0x0728b7f1,
+	0xb906b4b6,
+	0xc9f002ec,
+	0x00bcd01f,
+/* 0x0078: nv_rd32_wait */
+	0xc800bccf,
+	0x1bf41fcc,
+	0x06a7f0fa,
+	0x010921f5,
+	0xf840bfcf,
+/* 0x008d: nv_wr32 */
+	0x28b7f100,
+	0x06b4b607,
+	0xb980bfd0,
+	0xc9f002ec,
+	0x1ec9f01f,
+/* 0x00a3: nv_wr32_wait */
+	0xcf00bcd0,
+	0xccc800bc,
+	0xfa1bf41f,
+/* 0x00ae: watchdog_reset */
+	0x87f100f8,
+	0x84b60430,
+	0x1ff9f006,
+	0xf8008fd0,
+/* 0x00bd: watchdog_clear */
+	0x3087f100,
+	0x0684b604,
+	0xf80080d0,
+/* 0x00c9: wait_donez */
+	0xf094bd00,
+	0x07f10099,
+	0x03f03700,
+	0x0009d002,
+	0x07f104bd,
+	0x03f00600,
+	0x000ad002,
+/* 0x00e6: wait_donez_ne */
+	0x87f104bd,
+	0x83f00000,
+	0x0088cf01,
+	0xf4888aff,
+	0x94bdf31b,
+	0xf10099f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0109: wait_doneo */
+	0xf094bd00,
+	0x07f10099,
+	0x03f03700,
+	0x0009d002,
+	0x87f104bd,
+	0x84b60818,
+	0x008ad006,
+/* 0x0124: wait_doneo_e */
+	0x040087f1,
+	0xcf0684b6,
+	0x8aff0088,
+	0xf30bf488,
+	0x99f094bd,
+	0x0007f100,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x0147: mmctx_size */
+	0xbd00f804,
+/* 0x0149: nv_mmctx_size_loop */
+	0x00e89894,
+	0xb61a85b6,
+	0x84b60180,
+	0x0098bb02,
+	0xb804e0b6,
+	0x1bf404ef,
+	0x029fb9eb,
+/* 0x0166: mmctx_xfer */
+	0x94bd00f8,
+	0xf10199f0,
+	0xf0370007,
+	0x09d00203,
+	0xf104bd00,
+	0xb6071087,
+	0x94bd0684,
+	0xf405bbfd,
+	0x8bd0090b,
+	0x0099f000,
+/* 0x018c: mmctx_base_disabled */
+	0xf405eefd,
+	0x8ed00c0b,
+	0xc08fd080,
+/* 0x019b: mmctx_multi_disabled */
+	0xb70199f0,
+	0xc8010080,
+	0xb4b600ab,
+	0x0cb9f010,
+	0xb601aec8,
+	0xbefd11e4,
+	0x008bd005,
+/* 0x01b4: mmctx_exec_loop */
+/* 0x01b4: mmctx_wait_free */
+	0xf0008ecf,
+	0x0bf41fe4,
+	0x00ce98fa,
+	0xd005e9fd,
+	0xc0b6c08e,
+	0x04cdb804,
+	0xc8e81bf4,
+	0x1bf402ab,
+/* 0x01d5: mmctx_fini_wait */
+	0x008bcf18,
+	0xb01fb4f0,
+	0x1bf410b4,
+	0x02a7f0f7,
+	0xf4c921f4,
+/* 0x01ea: mmctx_stop */
+	0xabc81b0e,
+	0x10b4b600,
+	0xf00cb9f0,
+	0x8bd012b9,
+/* 0x01f9: mmctx_stop_wait */
+	0x008bcf00,
+	0xf412bbc8,
+/* 0x0202: mmctx_done */
+	0x94bdfa1b,
+	0xf10199f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0215: strand_wait */
+	0xf0a0f900,
+	0x21f402a7,
+	0xf8a0fcc9,
+/* 0x0221: strand_pre */
+	0xfc87f100,
+	0x0283f04a,
+	0xd00c97f0,
+	0x21f50089,
+	0x00f80215,
+/* 0x0234: strand_post */
+	0x4afc87f1,
+	0xf00283f0,
+	0x89d00d97,
+	0x1521f500,
+/* 0x0247: strand_set */
+	0xf100f802,
+	0xf04ffca7,
+	0xaba202a3,
+	0xc7f00500,
+	0x00acd00f,
+	0xd00bc7f0,
+	0x21f500bc,
+	0xaed00215,
+	0x0ac7f000,
+	0xf500bcd0,
+	0xf8021521,
+/* 0x0271: strand_ctx_init */
+	0xf094bd00,
+	0x07f10399,
+	0x03f03700,
+	0x0009d002,
+	0x21f504bd,
+	0xe7f00221,
+	0x4721f503,
+	0xfca7f102,
+	0x02a3f046,
+	0x0400aba0,
+	0xf040a0d0,
+	0xbcd001c7,
+	0x1521f500,
+	0x010c9202,
+	0xf000acd0,
+	0xbcd002c7,
+	0x1521f500,
+	0x3421f502,
+	0x8087f102,
+	0x0684b608,
+	0xb70089cf,
+	0x95220080,
+/* 0x02ca: ctx_init_strand_loop */
+	0x8ed008fe,
+	0x408ed000,
+	0xb6808acf,
+	0xa0b606a5,
+	0x00eabb01,
+	0xb60480b6,
+	0x1bf40192,
+	0x08e4b6e8,
+	0xbdf2efbc,
+	0x0399f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+/* 0x02fe: error */
+	0xe0f900f8,
+	0x9814e7f1,
+	0xf440e3f0,
+	0xe0b78d21,
+	0xf7f0041c,
+	0x8d21f401,
+	0x00f8e0fc,
+/* 0x0318: init */
+	0x04fe04bd,
+	0x0017f100,
+	0x0227f012,
+	0xf10012d0,
+	0xfe047017,
+	0x17f10010,
+	0x10d00400,
+	0x0427f0c0,
+	0xf40012d0,
+	0x17f11031,
+	0x14b60608,
+	0x0012cf06,
+	0xf00137f0,
+	0x32bb1f24,
+	0x0132b604,
+	0x80050280,
+	0x10b70603,
+	0x12cf0400,
+	0x04028000,
+	0x0c30e7f1,
+	0xbd50e3f0,
+	0xbd34bd24,
+/* 0x0371: init_unk_loop */
+	0x6821f444,
+	0xf400f6b0,
+	0xf7f00f0b,
+	0x04f2bb01,
+	0xb6054ffd,
+/* 0x0386: init_unk_next */
+	0x20b60130,
+	0x04e0b601,
+	0xf40226b0,
+/* 0x0392: init_unk_done */
+	0x0380e21b,
+	0x08048007,
+	0x010027f1,
+	0xcf0223f0,
+	0x34bd0022,
+	0x070047f1,
+	0x950644b6,
+	0x45d00825,
+	0x4045d000,
+	0x98000e98,
+	0x21f5010f,
+	0x2fbb0147,
+	0x003fbb00,
+	0x98010e98,
+	0x21f5020f,
+	0x0e980147,
+	0x00effd05,
+	0xbb002ebb,
+	0x0e98003e,
+	0x030f9802,
+	0x014721f5,
+	0xfd070e98,
+	0x2ebb00ef,
+	0x003ebb00,
+	0x130040b7,
+	0xd00235b6,
+	0x25b60043,
+	0x0635b608,
+	0xb60120b6,
+	0x24b60130,
+	0x0834b608,
+	0xf5022fb9,
+	0xbb027121,
+	0x07f1003f,
+	0x03f00100,
+	0x0003d002,
+	0x24bd04bd,
+	0xf11f29f0,
+	0xf0300007,
+	0x02d00203,
+/* 0x0433: main */
+	0xf404bd00,
+	0x28f40031,
+	0x24d7f000,
+	0xf43921f4,
+	0xe4b0f401,
+	0x1e18f404,
+	0xf00181fe,
+	0x20bd0627,
+	0xb60412fd,
+	0x1efd01e4,
+	0x0018fe05,
+	0x04f721f5,
+/* 0x0463: main_not_ctx_xfer */
+	0x94d30ef4,
+	0xf5f010ef,
+	0xfe21f501,
+	0xc60ef402,
+/* 0x0470: ih */
+	0x88fe80f9,
+	0xf980f901,
+	0xf9a0f990,
+	0xf9d0f9b0,
+	0xbdf0f9e0,
+	0x800acf04,
+	0xf404abc4,
+	0xb7f11d0b,
+	0xd7f01900,
+	0x40becf24,
+	0xf400bfcf,
+	0xb0b70421,
+	0xe7f00400,
+	0x00bed001,
+/* 0x04a8: ih_no_fifo */
+	0xfc400ad0,
+	0xfce0fcf0,
+	0xfcb0fcd0,
+	0xfc90fca0,
+	0x0088fe80,
+	0x32f480fc,
+/* 0x04c3: hub_barrier_done */
+	0xf001f800,
+	0x0e9801f7,
+	0x04febb04,
+	0x9418e7f1,
+	0xf440e3f0,
+	0x00f88d21,
+/* 0x04d8: ctx_redswitch */
+	0x0614e7f1,
+	0xf006e4b6,
+	0xefd020f7,
+	0x08f7f000,
+/* 0x04e8: ctx_redswitch_delay */
+	0xf401f2b6,
+	0xf7f1fd1b,
+	0xefd00a20,
+/* 0x04f7: ctx_xfer */
+	0xf100f800,
+	0xb60a0417,
+	0x1fd00614,
+	0x0711f400,
+	0x04d821f5,
+/* 0x0508: ctx_xfer_not_load */
+	0x4afc17f1,
+	0xf00213f0,
+	0x12d00c27,
+	0x1521f500,
+	0xfc27f102,
+	0x0223f047,
+	0xf00020d0,
+	0x20b6012c,
+	0x0012d003,
+	0xf001acf0,
+	0xb7f002a5,
+	0x50b3f000,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x000c9800,
+	0xf0010d98,
+	0x21f500e7,
+	0xacf00166,
+	0x00b7f101,
+	0x50b3f040,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x010c9800,
+	0x98020d98,
+	0xe7f1060f,
+	0x21f50800,
+	0xacf00166,
+	0x04a5f001,
+	0x3000b7f1,
+	0x9850b3f0,
+	0xc4b6040c,
+	0x00bcbb0f,
+	0x98020c98,
+	0x0f98030d,
+	0x00e7f108,
+	0x6621f502,
+	0x1521f501,
+	0x0601f402,
+/* 0x05a3: ctx_xfer_post */
+	0xf11412f4,
+	0xf04afc17,
+	0x27f00213,
+	0x0012d00d,
+	0x021521f5,
+/* 0x05b4: ctx_xfer_done */
+	0x04c321f5,
+	0x000000f8,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,724 @@
+/* fuc microcode for nvc0 PGRAPH/HUB
+ *
+ * Copyright 2011 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#ifdef INCLUDE_DATA
+hub_mmio_list_head:	.b32 #hub_mmio_list_base
+hub_mmio_list_tail:	.b32 #hub_mmio_list_next
+
+gpc_count:		.b32 0
+rop_count:		.b32 0
+cmd_queue:		queue_init
+
+ctx_current:		.b32 0
+
+.align 256
+chan_data:
+chan_mmio_count:	.b32 0
+chan_mmio_address:	.b32 0
+
+.align 256
+xfer_data: 		.skip 256
+
+hub_mmio_list_base:
+.b32 0x0417e91c // 0x17e91c, 2
+hub_mmio_list_next:
+#endif
+
+#ifdef INCLUDE_CODE
+// reports an exception to the host
+//
+// In: $r15 error code (see nvc0.fuc)
+//
+error:
+	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(5), 0, $r15)
+	mov $r15 1
+	nv_iowr(NV_PGRAPH_FECS_INTR_UP_SET, 0, $r15)
+	ret
+
+// HUB fuc initialisation, executed by triggering ucode start, will
+// fall through to main loop after completion.
+//
+// Output:
+//   CC_SCRATCH[0]:
+//	     31:31: set to signal completion
+//   CC_SCRATCH[1]:
+//	      31:0: total PGRAPH context size
+//
+init:
+	clear b32 $r0
+	mov $sp $r0
+	mov $xdbase $r0
+
+	// enable fifo access
+	mov $r1 0x1200
+	mov $r2 2
+	iowr I[$r1 + 0x000] $r2	// FIFO_ENABLE
+
+	// setup i0 handler, and route all interrupts to it
+	mov $r1 #ih
+	mov $iv0 $r1
+	mov $r1 0x400
+	iowr I[$r1 + 0x300] $r0	// INTR_DISPATCH
+
+	// route HUB_CHANNEL_SWITCH to fuc interrupt 8
+	mov $r3 0x404
+	shl b32 $r3 6
+	mov $r2 0x2003		// { HUB_CHANNEL_SWITCH, ZERO } -> intr 8
+	iowr I[$r3 + 0x000] $r2
+
+	// not sure what these are, route them because NVIDIA does, and
+	// the IRQ handler will signal the host if we ever get one.. we
+	// may find out if/why we need to handle these if so..
+	//
+	mov $r2 0x2004
+	iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9
+	mov $r2 0x200b
+	iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10
+	mov $r2 0x200c
+	iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15
+
+	// enable all INTR_UP interrupts
+	mov $r2 0xc24
+	shl b32 $r2 6
+	not b32 $r3 $r0
+	iowr I[$r2] $r3
+
+	// enable fifo, ctxsw, 9, 10, 15 interrupts
+	mov $r2 -0x78fc		// 0x8704
+	sethi $r2 0
+	iowr I[$r1 + 0x000] $r2	// INTR_EN_SET
+
+	// fifo level triggered, rest edge
+	sub b32 $r1 0x100
+	mov $r2 4
+	iowr I[$r1] $r2
+
+	// enable interrupts
+	bset $flags ie0
+
+	// fetch enabled GPC/ROP counts
+	mov $r14 -0x69fc	// 0x409604
+	sethi $r14 0x400000
+	call #nv_rd32
+	extr $r1 $r15 16:20
+	st b32 D[$r0 + #rop_count] $r1
+	and $r15 0x1f
+	st b32 D[$r0 + #gpc_count] $r15
+
+	// set BAR_REQMASK to GPC mask
+	mov $r1 1
+	shl b32 $r1 $r15
+	sub b32 $r1 1
+	mov $r2 0x40c
+	shl b32 $r2 6
+	iowr I[$r2 + 0x000] $r1
+	iowr I[$r2 + 0x100] $r1
+
+	// context size calculation, reserve first 256 bytes for use by fuc
+	mov $r1 256
+
+	// calculate size of mmio context data
+	ld b32 $r14 D[$r0 + #hub_mmio_list_head]
+	ld b32 $r15 D[$r0 + #hub_mmio_list_tail]
+	call #mmctx_size
+
+	// set mmctx base addresses now so we don't have to do it later,
+	// they don't (currently) ever change
+	mov $r3 0x700
+	shl b32 $r3 6
+	shr b32 $r4 $r1 8
+	iowr I[$r3 + 0x000] $r4		// MMCTX_SAVE_SWBASE
+	iowr I[$r3 + 0x100] $r4		// MMCTX_LOAD_SWBASE
+	add b32 $r3 0x1300
+	add b32 $r1 $r15
+	shr b32 $r15 2
+	iowr I[$r3 + 0x000] $r15	// MMCTX_LOAD_COUNT, wtf for?!?
+
+	// strands, base offset needs to be aligned to 256 bytes
+	shr b32 $r1 8
+	add b32 $r1 1
+	shl b32 $r1 8
+	mov b32 $r15 $r1
+	call #strand_ctx_init
+	add b32 $r1 $r15
+
+	// initialise each GPC in sequence by passing in the offset of its
+	// context data in GPCn_CC_SCRATCH[1], and starting its FUC (which
+	// has previously been uploaded by the host) running.
+	//
+	// the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31
+	// when it has completed, and return the size of its context data
+	// in GPCn_CC_SCRATCH[1]
+	//
+	ld b32 $r3 D[$r0 + #gpc_count]
+	mov $r4 0x2000
+	sethi $r4 0x500000
+	init_gpc:
+		// setup, and start GPC ucode running
+		add b32 $r14 $r4 0x804
+		mov b32 $r15 $r1
+		call #nv_wr32			// CC_SCRATCH[1] = ctx offset
+		add b32 $r14 $r4 0x10c
+		clear b32 $r15
+		call #nv_wr32
+		add b32 $r14 $r4 0x104
+		call #nv_wr32			// ENTRY
+		add b32 $r14 $r4 0x100
+		mov $r15 2			// CTRL_START_TRIGGER
+		call #nv_wr32			// CTRL
+
+		// wait for it to complete, and adjust context size
+		add b32 $r14 $r4 0x800
+		init_gpc_wait:
+			call #nv_rd32
+			xbit $r15 $r15 31
+			bra e #init_gpc_wait
+		add b32 $r14 $r4 0x804
+		call #nv_rd32
+		add b32 $r1 $r15
+
+		// next!
+		add b32 $r4 0x8000
+		sub b32 $r3 1
+		bra ne #init_gpc
+
+	// save context size, and tell host we're ready
+	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(1), 0, $r1)
+	clear b32 $r1
+	bset $r1 31
+	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_SET(0), 0, $r1)
+
+// Main program loop, very simple, sleeps until woken up by the interrupt
+// handler, pulls a command from the queue and executes its handler
+//
+main:
+	// sleep until we have something to do
+	bset $flags $p0
+	sleep $p0
+	mov $r13 #cmd_queue
+	call #queue_get
+	bra $p1 #main
+
+	// context switch, requested by GPU?
+	cmpu b32 $r14 0x4001
+	bra ne #main_not_ctx_switch
+		trace_set(T_AUTO)
+		mov $r1 0xb00
+		shl b32 $r1 6
+		iord $r2 I[$r1 + 0x100]		// CHAN_NEXT
+		iord $r1 I[$r1 + 0x000]		// CHAN_CUR
+
+		xbit $r3 $r1 31
+		bra e #chsw_no_prev
+			xbit $r3 $r2 31
+			bra e #chsw_prev_no_next
+				push $r2
+				mov b32 $r2 $r1
+				trace_set(T_SAVE)
+				bclr $flags $p1
+				bset $flags $p2
+				call #ctx_xfer
+				trace_clr(T_SAVE);
+				pop $r2
+				trace_set(T_LOAD);
+				bset $flags $p1
+				call #ctx_xfer
+				trace_clr(T_LOAD);
+				bra #chsw_done
+			chsw_prev_no_next:
+				push $r2
+				mov b32 $r2 $r1
+				bclr $flags $p1
+				bclr $flags $p2
+				call #ctx_xfer
+				pop $r2
+				mov $r1 0xb00
+				shl b32 $r1 6
+				iowr I[$r1] $r2
+				bra #chsw_done
+		chsw_no_prev:
+			xbit $r3 $r2 31
+			bra e #chsw_done
+				bset $flags $p1
+				bclr $flags $p2
+				call #ctx_xfer
+
+		// ack the context switch request
+		chsw_done:
+		mov $r1 0xb0c
+		shl b32 $r1 6
+		mov $r2 1
+		iowr I[$r1 + 0x000] $r2		// 0x409b0c
+		trace_clr(T_AUTO)
+		bra #main
+
+	// request to set current channel? (*not* a context switch)
+	main_not_ctx_switch:
+	cmpu b32 $r14 0x0001
+	bra ne #main_not_ctx_chan
+		mov b32 $r2 $r15
+		call #ctx_chan
+		bra #main_done
+
+	// request to store current channel context?
+	main_not_ctx_chan:
+	cmpu b32 $r14 0x0002
+	bra ne #main_not_ctx_save
+		trace_set(T_SAVE)
+		bclr $flags $p1
+		bclr $flags $p2
+		call #ctx_xfer
+		trace_clr(T_SAVE)
+		bra #main_done
+
+	main_not_ctx_save:
+		shl b32 $r15 $r14 16
+		or $r15 E_BAD_COMMAND
+		call #error
+		bra #main
+
+	main_done:
+	clear b32 $r2
+	bset $r2 31
+	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_SET(0), 0, $r2)
+	bra #main
+
+// interrupt handler
+ih:
+	push $r8
+	mov $r8 $flags
+	push $r8
+	push $r9
+	push $r10
+	push $r11
+	push $r13
+	push $r14
+	push $r15
+	clear b32 $r0
+
+	// incoming fifo command?
+	iord $r10 I[$r0 + 0x200]	// INTR
+	and $r11 $r10 0x00000004
+	bra e #ih_no_fifo
+		// queue incoming fifo command for later processing
+		mov $r11 0x1900
+		mov $r13 #cmd_queue
+		iord $r14 I[$r11 + 0x100]	// FIFO_CMD
+		iord $r15 I[$r11 + 0x000]	// FIFO_DATA
+		call #queue_put
+		add b32 $r11 0x400
+		mov $r14 1
+		iowr I[$r11 + 0x000] $r14	// FIFO_ACK
+
+	// context switch request?
+	ih_no_fifo:
+	and $r11 $r10 0x00000100
+	bra e #ih_no_ctxsw
+		// enqueue a context switch for later processing
+		mov $r13 #cmd_queue
+		mov $r14 0x4001
+		call #queue_put
+
+	// anything we didn't handle, bring it to the host's attention
+	ih_no_ctxsw:
+	mov $r11 0x104
+	not b32 $r11
+	and $r11 $r10 $r11
+	bra e #ih_no_other
+		mov $r10 0xc1c
+		shl b32 $r10 6
+		iowr I[$r10] $r11	// INTR_UP_SET
+
+	// ack, and wake up main()
+	ih_no_other:
+	iowr I[$r0 + 0x100] $r10	// INTR_ACK
+
+	pop $r15
+	pop $r14
+	pop $r13
+	pop $r11
+	pop $r10
+	pop $r9
+	pop $r8
+	mov $flags $r8
+	pop $r8
+	bclr $flags $p0
+	iret
+
+#if CHIPSET < GK100
+// Not real sure, but, MEM_CMD 7 will hang forever if this isn't done
+ctx_4160s:
+	mov $r14 0x4160
+	sethi $r14 0x400000
+	mov $r15 1
+	call #nv_wr32
+	ctx_4160s_wait:
+		call #nv_rd32
+		xbit $r15 $r15 4
+		bra e #ctx_4160s_wait
+	ret
+
+// Without clearing again at end of xfer, some things cause PGRAPH
+// to hang with STATUS=0x00000007 until it's cleared.. fbcon can
+// still function with it set however...
+ctx_4160c:
+	mov $r14 0x4160
+	sethi $r14 0x400000
+	clear b32 $r15
+	call #nv_wr32
+	ret
+#endif
+
+// Again, not real sure
+//
+// In: $r15 value to set 0x404170 to
+//
+ctx_4170s:
+	mov $r14 0x4170
+	sethi $r14 0x400000
+	or $r15 0x10
+	call #nv_wr32
+	ret
+
+// Waits for a ctx_4170s() call to complete
+//
+ctx_4170w:
+	mov $r14 0x4170
+	sethi $r14 0x400000
+	call #nv_rd32
+	and $r15 0x10
+	bra ne #ctx_4170w
+	ret
+
+// Disables various things, waits a bit, and re-enables them..
+//
+// Not sure how exactly this helps, perhaps "ENABLE" is not such a
+// good description for the bits we turn off?  Anyways, without this,
+// funny things happen.
+//
+ctx_redswitch:
+	mov $r14 0x614
+	shl b32 $r14 6
+	mov $r15 0x270
+	iowr I[$r14] $r15	// HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL
+	mov $r15 8
+	ctx_redswitch_delay:
+		sub b32 $r15 1
+		bra ne #ctx_redswitch_delay
+	mov $r15 0x770
+	iowr I[$r14] $r15	// HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL
+	ret
+
+// Not a clue what this is for, except that unless the value is 0x10, the
+// strand context is saved (and presumably restored) incorrectly..
+//
+// In: $r15 value to set to (0x00/0x10 are used)
+//
+ctx_86c:
+	mov $r14 0x86c
+	shl b32 $r14 6
+	iowr I[$r14] $r15	// HUB(0x86c) = val
+	mov $r14 -0x75ec
+	sethi $r14 0x400000
+	call #nv_wr32		// ROP(0xa14) = val
+	mov $r14 -0x5794
+	sethi $r14 0x410000
+	call #nv_wr32		// GPC(0x86c) = val
+	ret
+
+// ctx_load - load's a channel's ctxctl data, and selects its vm
+//
+// In: $r2 channel address
+//
+ctx_load:
+	trace_set(T_CHAN)
+
+	// switch to channel, somewhat magic in parts..
+	mov $r10 12		// DONE_UNK12
+	call #wait_donez
+	mov $r1 0xa24
+	shl b32 $r1 6
+	iowr I[$r1 + 0x000] $r0	// 0x409a24
+	mov $r3 0xb00
+	shl b32 $r3 6
+	iowr I[$r3 + 0x100] $r2	// CHAN_NEXT
+	mov $r1 0xa0c
+	shl b32 $r1 6
+	mov $r4 7
+	iowr I[$r1 + 0x000] $r2 // MEM_CHAN
+	iowr I[$r1 + 0x100] $r4	// MEM_CMD
+	ctx_chan_wait_0:
+		iord $r4 I[$r1 + 0x100]
+		and $r4 0x1f
+		bra ne #ctx_chan_wait_0
+	iowr I[$r3 + 0x000] $r2	// CHAN_CUR
+
+	// load channel header, fetch PGRAPH context pointer
+	mov $xtargets $r0
+	bclr $r2 31
+	shl b32 $r2 4
+	add b32 $r2 2
+
+	trace_set(T_LCHAN)
+	mov $r1 0xa04
+	shl b32 $r1 6
+	iowr I[$r1 + 0x000] $r2		// MEM_BASE
+	mov $r1 0xa20
+	shl b32 $r1 6
+	mov $r2 0x0002
+	sethi $r2 0x80000000
+	iowr I[$r1 + 0x000] $r2		// MEM_TARGET = vram
+	mov $r1 0x10			// chan + 0x0210
+	mov $r2 #xfer_data
+	sethi $r2 0x00020000		// 16 bytes
+	xdld $r1 $r2
+	xdwait
+	trace_clr(T_LCHAN)
+
+	// update current context
+	ld b32 $r1 D[$r0 + #xfer_data + 4]
+	shl b32 $r1 24
+	ld b32 $r2 D[$r0 + #xfer_data + 0]
+	shr b32 $r2 8
+	or $r1 $r2
+	st b32 D[$r0 + #ctx_current] $r1
+
+	// set transfer base to start of context, and fetch context header
+	trace_set(T_LCTXH)
+	mov $r2 0xa04
+	shl b32 $r2 6
+	iowr I[$r2 + 0x000] $r1		// MEM_BASE
+	mov $r2 1
+	mov $r1 0xa20
+	shl b32 $r1 6
+	iowr I[$r1 + 0x000] $r2		// MEM_TARGET = vm
+	mov $r1 #chan_data
+	sethi $r1 0x00060000		// 256 bytes
+	xdld $r0 $r1
+	xdwait
+	trace_clr(T_LCTXH)
+
+	trace_clr(T_CHAN)
+	ret
+
+// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as
+//            the active channel for ctxctl, but not actually transfer
+//            any context data.  intended for use only during initial
+//            context construction.
+//
+// In: $r2 channel address
+//
+ctx_chan:
+#if CHIPSET < GK100
+	call #ctx_4160s
+#endif
+	call #ctx_load
+	mov $r10 12			// DONE_UNK12
+	call #wait_donez
+	mov $r1 0xa10
+	shl b32 $r1 6
+	mov $r2 5
+	iowr I[$r1 + 0x000] $r2		// MEM_CMD = 5 (???)
+	ctx_chan_wait:
+		iord $r2 I[$r1 + 0x000]
+		or $r2 $r2
+		bra ne #ctx_chan_wait
+#if CHIPSET < GK100
+	call #ctx_4160c
+#endif
+	ret
+
+// Execute per-context state overrides list
+//
+// Only executed on the first load of a channel.  Might want to look into
+// removing this and having the host directly modify the channel's context
+// to change this state...  The nouveau DRM already builds this list as
+// it's definitely needed for NVIDIA's, so we may as well use it for now
+//
+// Input: $r1 mmio list length
+//
+ctx_mmio_exec:
+	// set transfer base to be the mmio list
+	ld b32 $r3 D[$r0 + #chan_mmio_address]
+	mov $r2 0xa04
+	shl b32 $r2 6
+	iowr I[$r2 + 0x000] $r3		// MEM_BASE
+
+	clear b32 $r3
+	ctx_mmio_loop:
+		// fetch next 256 bytes of mmio list if necessary
+		and $r4 $r3 0xff
+		bra ne #ctx_mmio_pull
+			mov $r5 #xfer_data
+			sethi $r5 0x00060000	// 256 bytes
+			xdld $r3 $r5
+			xdwait
+
+		// execute a single list entry
+		ctx_mmio_pull:
+		ld b32 $r14 D[$r4 + #xfer_data + 0x00]
+		ld b32 $r15 D[$r4 + #xfer_data + 0x04]
+		call #nv_wr32
+
+		// next!
+		add b32 $r3 8
+		sub b32 $r1 1
+		bra ne #ctx_mmio_loop
+
+	// set transfer base back to the current context
+	ctx_mmio_done:
+	ld b32 $r3 D[$r0 + #ctx_current]
+	iowr I[$r2 + 0x000] $r3		// MEM_BASE
+
+	// disable the mmio list now, we don't need/want to execute it again
+	st b32 D[$r0 + #chan_mmio_count] $r0
+	mov $r1 #chan_data
+	sethi $r1 0x00060000		// 256 bytes
+	xdst $r0 $r1
+	xdwait
+	ret
+
+// Transfer HUB context data between GPU and storage area
+//
+// In: $r2 channel address
+//     $p1 clear on save, set on load
+//     $p2 set if opposite direction done/will be done, so:
+//		on save it means: "a load will follow this save"
+//		on load it means: "a save preceeded this load"
+//
+ctx_xfer:
+	// according to mwk, some kind of wait for idle
+	mov $r15 0xc00
+	shl b32 $r15 6
+	mov $r14 4
+	iowr I[$r15 + 0x200] $r14
+	ctx_xfer_idle:
+		iord $r14 I[$r15 + 0x000]
+		and $r14 0x2000
+		bra ne #ctx_xfer_idle
+
+	bra not $p1 #ctx_xfer_pre
+	bra $p2 #ctx_xfer_pre_load
+	ctx_xfer_pre:
+		mov $r15 0x10
+		call #ctx_86c
+#if CHIPSET < GK100
+		call #ctx_4160s
+#endif
+		bra not $p1 #ctx_xfer_exec
+
+	ctx_xfer_pre_load:
+		mov $r15 2
+		call #ctx_4170s
+		call #ctx_4170w
+		call #ctx_redswitch
+		clear b32 $r15
+		call #ctx_4170s
+		call #ctx_load
+
+	// fetch context pointer, and initiate xfer on all GPCs
+	ctx_xfer_exec:
+	ld b32 $r1 D[$r0 + #ctx_current]
+	mov $r2 0x414
+	shl b32 $r2 6
+	iowr I[$r2 + 0x000] $r0	// BAR_STATUS = reset
+	mov $r14 -0x5b00
+	sethi $r14 0x410000
+	mov b32 $r15 $r1
+	call #nv_wr32		// GPC_BCAST_WRCMD_DATA = ctx pointer
+	add b32 $r14 4
+	xbit $r15 $flags $p1
+	xbit $r2 $flags $p2
+	shl b32 $r2 1
+	or $r15 $r2
+	call #nv_wr32		// GPC_BCAST_WRCMD_CMD = GPC_XFER(type)
+
+	// strands
+	mov $r1 0x4afc
+	sethi $r1 0x20000
+	mov $r2 0xc
+	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x0c
+	call #strand_wait
+	mov $r2 0x47fc
+	sethi $r2 0x20000
+	iowr I[$r2] $r0		// STRAND_FIRST_GENE(0x3f) = 0x00
+	xbit $r2 $flags $p1
+	add b32 $r2 3
+	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
+
+	// mmio context
+	xbit $r10 $flags $p1	// direction
+	or $r10 6		// first, last
+	mov $r11 0		// base = 0
+	ld b32 $r12 D[$r0 + #hub_mmio_list_head]
+	ld b32 $r13 D[$r0 + #hub_mmio_list_tail]
+	mov $r14 0		// not multi
+	call #mmctx_xfer
+
+	// wait for GPCs to all complete
+	mov $r10 8		// DONE_BAR
+	call #wait_doneo
+
+	// wait for strand xfer to complete
+	call #strand_wait
+
+	// post-op
+	bra $p1 #ctx_xfer_post
+		mov $r10 12		// DONE_UNK12
+		call #wait_donez
+		mov $r1 0xa10
+		shl b32 $r1 6
+		mov $r2 5
+		iowr I[$r1] $r2		// MEM_CMD
+		ctx_xfer_post_save_wait:
+			iord $r2 I[$r1]
+			or $r2 $r2
+			bra ne #ctx_xfer_post_save_wait
+
+	bra $p2 #ctx_xfer_done
+	ctx_xfer_post:
+		mov $r15 2
+		call #ctx_4170s
+		clear b32 $r15
+		call #ctx_86c
+		call #strand_post
+		call #ctx_4170w
+		clear b32 $r15
+		call #ctx_4170s
+
+		bra not $p1 #ctx_xfer_no_post_mmio
+		ld b32 $r1 D[$r0 + #chan_mmio_count]
+		or $r1 $r1
+		bra e #ctx_xfer_no_post_mmio
+			call #ctx_mmio_exec
+
+		ctx_xfer_no_post_mmio:
+#if CHIPSET < GK100
+		call #ctx_4160c
+#endif
+
+	ctx_xfer_done:
+	ret
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,5 @@
-/* fuc microcode for nvc0 PGRAPH/HUB
- *
- * Copyright 2011 Red Hat Inc.
+/*
+ * Copyright 2013 Red Hat Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -20,850 +19,22 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-/* To build:
- *    m4 hubnvc0.fuc | envyas -a -w -m fuc -V fuc3 -o hubnvc0.fuc.h
- */
+#define CHIPSET GF100
+#include "macros.fuc"
 
 .section #nvc0_grhub_data
-include(`nvc0.fuc')
-gpc_count:		.b32 0
-rop_count:		.b32 0
-cmd_queue:		queue_init
-hub_mmio_list_head:	.b32 0
-hub_mmio_list_tail:	.b32 0
-
-ctx_current:		.b32 0
-
-chipsets:
-.b8  0xc0 0 0 0
-.b16 #nvc0_hub_mmio_head
-.b16 #nvc0_hub_mmio_tail
-.b8  0xc1 0 0 0
-.b16 #nvc0_hub_mmio_head
-.b16 #nvc1_hub_mmio_tail
-.b8  0xc3 0 0 0
-.b16 #nvc0_hub_mmio_head
-.b16 #nvc0_hub_mmio_tail
-.b8  0xc4 0 0 0
-.b16 #nvc0_hub_mmio_head
-.b16 #nvc0_hub_mmio_tail
-.b8  0xc8 0 0 0
-.b16 #nvc0_hub_mmio_head
-.b16 #nvc0_hub_mmio_tail
-.b8  0xce 0 0 0
-.b16 #nvc0_hub_mmio_head
-.b16 #nvc0_hub_mmio_tail
-.b8  0xcf 0 0 0
-.b16 #nvc0_hub_mmio_head
-.b16 #nvc0_hub_mmio_tail
-.b8  0xd9 0 0 0
-.b16 #nvd9_hub_mmio_head
-.b16 #nvd9_hub_mmio_tail
-.b8  0xd7 0 0 0
-.b16 #nvd9_hub_mmio_head
-.b16 #nvd9_hub_mmio_tail
-.b8  0 0 0 0
-
-nvc0_hub_mmio_head:
-mmctx_data(0x17e91c, 2)
-mmctx_data(0x400204, 2)
-mmctx_data(0x404004, 11)
-mmctx_data(0x404044, 1)
-mmctx_data(0x404094, 14)
-mmctx_data(0x4040d0, 7)
-mmctx_data(0x4040f8, 1)
-mmctx_data(0x404130, 3)
-mmctx_data(0x404150, 3)
-mmctx_data(0x404164, 2)
-mmctx_data(0x404174, 3)
-mmctx_data(0x404200, 8)
-mmctx_data(0x404404, 14)
-mmctx_data(0x404460, 4)
-mmctx_data(0x404480, 1)
-mmctx_data(0x404498, 1)
-mmctx_data(0x404604, 4)
-mmctx_data(0x404618, 32)
-mmctx_data(0x404698, 21)
-mmctx_data(0x4046f0, 2)
-mmctx_data(0x404700, 22)
-mmctx_data(0x405800, 1)
-mmctx_data(0x405830, 3)
-mmctx_data(0x405854, 1)
-mmctx_data(0x405870, 4)
-mmctx_data(0x405a00, 2)
-mmctx_data(0x405a18, 1)
-mmctx_data(0x406020, 1)
-mmctx_data(0x406028, 4)
-mmctx_data(0x4064a8, 2)
-mmctx_data(0x4064b4, 2)
-mmctx_data(0x407804, 1)
-mmctx_data(0x40780c, 6)
-mmctx_data(0x4078bc, 1)
-mmctx_data(0x408000, 7)
-mmctx_data(0x408064, 1)
-mmctx_data(0x408800, 3)
-mmctx_data(0x408900, 4)
-mmctx_data(0x408980, 1)
-nvc0_hub_mmio_tail:
-mmctx_data(0x4064c0, 2)
-nvc1_hub_mmio_tail:
-
-nvd9_hub_mmio_head:
-mmctx_data(0x17e91c, 2)
-mmctx_data(0x400204, 2)
-mmctx_data(0x404004, 10)
-mmctx_data(0x404044, 1)
-mmctx_data(0x404094, 14)
-mmctx_data(0x4040d0, 7)
-mmctx_data(0x4040f8, 1)
-mmctx_data(0x404130, 3)
-mmctx_data(0x404150, 3)
-mmctx_data(0x404164, 2)
-mmctx_data(0x404178, 2)
-mmctx_data(0x404200, 8)
-mmctx_data(0x404404, 14)
-mmctx_data(0x404460, 4)
-mmctx_data(0x404480, 1)
-mmctx_data(0x404498, 1)
-mmctx_data(0x404604, 4)
-mmctx_data(0x404618, 32)
-mmctx_data(0x404698, 21)
-mmctx_data(0x4046f0, 2)
-mmctx_data(0x404700, 22)
-mmctx_data(0x405800, 1)
-mmctx_data(0x405830, 3)
-mmctx_data(0x405854, 1)
-mmctx_data(0x405870, 4)
-mmctx_data(0x405a00, 2)
-mmctx_data(0x405a18, 1)
-mmctx_data(0x406020, 1)
-mmctx_data(0x406028, 4)
-mmctx_data(0x4064a8, 2)
-mmctx_data(0x4064b4, 5)
-mmctx_data(0x407804, 1)
-mmctx_data(0x40780c, 6)
-mmctx_data(0x4078bc, 1)
-mmctx_data(0x408000, 7)
-mmctx_data(0x408064, 1)
-mmctx_data(0x408800, 3)
-mmctx_data(0x408900, 4)
-mmctx_data(0x408980, 1)
-nvd9_hub_mmio_tail:
-
-.align 256
-chan_data:
-chan_mmio_count:	.b32 0
-chan_mmio_address:	.b32 0
-
-.align 256
-xfer_data: 		.b32 0
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "hub.fuc"
+#undef INCLUDE_DATA
 
 .section #nvc0_grhub_code
+#define INCLUDE_CODE
 bra #init
-define(`include_code')
-include(`nvc0.fuc')
-
-// reports an exception to the host
-//
-// In: $r15 error code (see nvc0.fuc)
-//
-error:
-	push $r14
-	mov $r14 0x814
-	shl b32 $r14 6
-	iowr I[$r14 + 0x000] $r15	// CC_SCRATCH[5] = error code
-	mov $r14 0xc1c
-	shl b32 $r14 6
-	mov $r15 1
-	iowr I[$r14 + 0x000] $r15	// INTR_UP_SET
-	pop $r14
-	ret
-
-// HUB fuc initialisation, executed by triggering ucode start, will
-// fall through to main loop after completion.
-//
-// Input:
-//   CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
-//
-// Output:
-//   CC_SCRATCH[0]:
-//	     31:31: set to signal completion
-//   CC_SCRATCH[1]:
-//	      31:0: total PGRAPH context size
-//
-init:
-	clear b32 $r0
-	mov $sp $r0
-	mov $xdbase $r0
-
-	// enable fifo access
-	mov $r1 0x1200
-	mov $r2 2
-	iowr I[$r1 + 0x000] $r2	// FIFO_ENABLE
-
-	// setup i0 handler, and route all interrupts to it
-	mov $r1 #ih
-	mov $iv0 $r1
-	mov $r1 0x400
-	iowr I[$r1 + 0x300] $r0	// INTR_DISPATCH
-
-	// route HUB_CHANNEL_SWITCH to fuc interrupt 8
-	mov $r3 0x404
-	shl b32 $r3 6
-	mov $r2 0x2003		// { HUB_CHANNEL_SWITCH, ZERO } -> intr 8
-	iowr I[$r3 + 0x000] $r2
-
-	// not sure what these are, route them because NVIDIA does, and
-	// the IRQ handler will signal the host if we ever get one.. we
-	// may find out if/why we need to handle these if so..
-	//
-	mov $r2 0x2004
-	iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9
-	mov $r2 0x200b
-	iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10
-	mov $r2 0x200c
-	iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15
-
-	// enable all INTR_UP interrupts
-	mov $r2 0xc24
-	shl b32 $r2 6
-	not b32 $r3 $r0
-	iowr I[$r2] $r3
-
-	// enable fifo, ctxsw, 9, 10, 15 interrupts
-	mov $r2 -0x78fc		// 0x8704
-	sethi $r2 0
-	iowr I[$r1 + 0x000] $r2	// INTR_EN_SET
-
-	// fifo level triggered, rest edge
-	sub b32 $r1 0x100
-	mov $r2 4
-	iowr I[$r1] $r2
-
-	// enable interrupts
-	bset $flags ie0
-
-	// fetch enabled GPC/ROP counts
-	mov $r14 -0x69fc	// 0x409604
-	sethi $r14 0x400000
-	call #nv_rd32
-	extr $r1 $r15 16:20
-	st b32 D[$r0 + #rop_count] $r1
-	and $r15 0x1f
-	st b32 D[$r0 + #gpc_count] $r15
-
-	// set BAR_REQMASK to GPC mask
-	mov $r1 1
-	shl b32 $r1 $r15
-	sub b32 $r1 1
-	mov $r2 0x40c
-	shl b32 $r2 6
-	iowr I[$r2 + 0x000] $r1
-	iowr I[$r2 + 0x100] $r1
-
-	// find context data for this chipset
-	mov $r2 0x800
-	shl b32 $r2 6
-	iord $r2 I[$r2 + 0x000]		// CC_SCRATCH[0]
-	mov $r15 #chipsets - 8
-	init_find_chipset:
-		add b32 $r15 8
-		ld b32 $r3 D[$r15 + 0x00]
-		cmpu b32 $r3 $r2
-		bra e #init_context
-		cmpu b32 $r3 0
-		bra ne #init_find_chipset
-		// unknown chipset
-		ret
-
-	// context size calculation, reserve first 256 bytes for use by fuc
-	init_context:
-	mov $r1 256
-
-	// calculate size of mmio context data
-	ld b16 $r14 D[$r15 + 4]
-	ld b16 $r15 D[$r15 + 6]
-	sethi $r14 0
-	st b32 D[$r0 + #hub_mmio_list_head] $r14
-	st b32 D[$r0 + #hub_mmio_list_tail] $r15
-	call #mmctx_size
-
-	// set mmctx base addresses now so we don't have to do it later,
-	// they don't (currently) ever change
-	mov $r3 0x700
-	shl b32 $r3 6
-	shr b32 $r4 $r1 8
-	iowr I[$r3 + 0x000] $r4		// MMCTX_SAVE_SWBASE
-	iowr I[$r3 + 0x100] $r4		// MMCTX_LOAD_SWBASE
-	add b32 $r3 0x1300
-	add b32 $r1 $r15
-	shr b32 $r15 2
-	iowr I[$r3 + 0x000] $r15	// MMCTX_LOAD_COUNT, wtf for?!?
-
-	// strands, base offset needs to be aligned to 256 bytes
-	shr b32 $r1 8
-	add b32 $r1 1
-	shl b32 $r1 8
-	mov b32 $r15 $r1
-	call #strand_ctx_init
-	add b32 $r1 $r15
-
-	// initialise each GPC in sequence by passing in the offset of its
-	// context data in GPCn_CC_SCRATCH[1], and starting its FUC (which
-	// has previously been uploaded by the host) running.
-	//
-	// the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31
-	// when it has completed, and return the size of its context data
-	// in GPCn_CC_SCRATCH[1]
-	//
-	ld b32 $r3 D[$r0 + #gpc_count]
-	mov $r4 0x2000
-	sethi $r4 0x500000
-	init_gpc:
-		// setup, and start GPC ucode running
-		add b32 $r14 $r4 0x804
-		mov b32 $r15 $r1
-		call #nv_wr32			// CC_SCRATCH[1] = ctx offset
-		add b32 $r14 $r4 0x800
-		mov b32 $r15 $r2
-		call #nv_wr32			// CC_SCRATCH[0] = chipset
-		add b32 $r14 $r4 0x10c
-		clear b32 $r15
-		call #nv_wr32
-		add b32 $r14 $r4 0x104
-		call #nv_wr32			// ENTRY
-		add b32 $r14 $r4 0x100
-		mov $r15 2			// CTRL_START_TRIGGER
-		call #nv_wr32			// CTRL
-
-		// wait for it to complete, and adjust context size
-		add b32 $r14 $r4 0x800
-		init_gpc_wait:
-			call #nv_rd32
-			xbit $r15 $r15 31
-			bra e #init_gpc_wait
-		add b32 $r14 $r4 0x804
-		call #nv_rd32
-		add b32 $r1 $r15
-
-		// next!
-		add b32 $r4 0x8000
-		sub b32 $r3 1
-		bra ne #init_gpc
-
-	// save context size, and tell host we're ready
-	mov $r2 0x800
-	shl b32 $r2 6
-	iowr I[$r2 + 0x100] $r1		// CC_SCRATCH[1]  = context size
-	add b32 $r2 0x800
-	clear b32 $r1
-	bset $r1 31
-	iowr I[$r2 + 0x000] $r1		// CC_SCRATCH[0] |= 0x80000000
-
-// Main program loop, very simple, sleeps until woken up by the interrupt
-// handler, pulls a command from the queue and executes its handler
-//
-main:
-	// sleep until we have something to do
-	bset $flags $p0
-	sleep $p0
-	mov $r13 #cmd_queue
-	call #queue_get
-	bra $p1 #main
-
-	// context switch, requested by GPU?
-	cmpu b32 $r14 0x4001
-	bra ne #main_not_ctx_switch
-		trace_set(T_AUTO)
-		mov $r1 0xb00
-		shl b32 $r1 6
-		iord $r2 I[$r1 + 0x100]		// CHAN_NEXT
-		iord $r1 I[$r1 + 0x000]		// CHAN_CUR
-
-		xbit $r3 $r1 31
-		bra e #chsw_no_prev
-			xbit $r3 $r2 31
-			bra e #chsw_prev_no_next
-				push $r2
-				mov b32 $r2 $r1
-				trace_set(T_SAVE)
-				bclr $flags $p1
-				bset $flags $p2
-				call #ctx_xfer
-				trace_clr(T_SAVE);
-				pop $r2
-				trace_set(T_LOAD);
-				bset $flags $p1
-				call #ctx_xfer
-				trace_clr(T_LOAD);
-				bra #chsw_done
-			chsw_prev_no_next:
-				push $r2
-				mov b32 $r2 $r1
-				bclr $flags $p1
-				bclr $flags $p2
-				call #ctx_xfer
-				pop $r2
-				mov $r1 0xb00
-				shl b32 $r1 6
-				iowr I[$r1] $r2
-				bra #chsw_done
-		chsw_no_prev:
-			xbit $r3 $r2 31
-			bra e #chsw_done
-				bset $flags $p1
-				bclr $flags $p2
-				call #ctx_xfer
-
-		// ack the context switch request
-		chsw_done:
-		mov $r1 0xb0c
-		shl b32 $r1 6
-		mov $r2 1
-		iowr I[$r1 + 0x000] $r2		// 0x409b0c
-		trace_clr(T_AUTO)
-		bra #main
-
-	// request to set current channel? (*not* a context switch)
-	main_not_ctx_switch:
-	cmpu b32 $r14 0x0001
-	bra ne #main_not_ctx_chan
-		mov b32 $r2 $r15
-		call #ctx_chan
-		bra #main_done
-
-	// request to store current channel context?
-	main_not_ctx_chan:
-	cmpu b32 $r14 0x0002
-	bra ne #main_not_ctx_save
-		trace_set(T_SAVE)
-		bclr $flags $p1
-		bclr $flags $p2
-		call #ctx_xfer
-		trace_clr(T_SAVE)
-		bra #main_done
-
-	main_not_ctx_save:
-		shl b32 $r15 $r14 16
-		or $r15 E_BAD_COMMAND
-		call #error
-		bra #main
-
-	main_done:
-	mov $r1 0x820
-	shl b32 $r1 6
-	clear b32 $r2
-	bset $r2 31
-	iowr I[$r1 + 0x000] $r2		// CC_SCRATCH[0] |= 0x80000000
-	bra #main
-
-// interrupt handler
-ih:
-	push $r8
-	mov $r8 $flags
-	push $r8
-	push $r9
-	push $r10
-	push $r11
-	push $r13
-	push $r14
-	push $r15
-
-	// incoming fifo command?
-	iord $r10 I[$r0 + 0x200]	// INTR
-	and $r11 $r10 0x00000004
-	bra e #ih_no_fifo
-		// queue incoming fifo command for later processing
-		mov $r11 0x1900
-		mov $r13 #cmd_queue
-		iord $r14 I[$r11 + 0x100]	// FIFO_CMD
-		iord $r15 I[$r11 + 0x000]	// FIFO_DATA
-		call #queue_put
-		add b32 $r11 0x400
-		mov $r14 1
-		iowr I[$r11 + 0x000] $r14	// FIFO_ACK
-
-	// context switch request?
-	ih_no_fifo:
-	and $r11 $r10 0x00000100
-	bra e #ih_no_ctxsw
-		// enqueue a context switch for later processing
-		mov $r13 #cmd_queue
-		mov $r14 0x4001
-		call #queue_put
-
-	// anything we didn't handle, bring it to the host's attention
-	ih_no_ctxsw:
-	mov $r11 0x104
-	not b32 $r11
-	and $r11 $r10 $r11
-	bra e #ih_no_other
-		mov $r10 0xc1c
-		shl b32 $r10 6
-		iowr I[$r10] $r11	// INTR_UP_SET
-
-	// ack, and wake up main()
-	ih_no_other:
-	iowr I[$r0 + 0x100] $r10	// INTR_ACK
-
-	pop $r15
-	pop $r14
-	pop $r13
-	pop $r11
-	pop $r10
-	pop $r9
-	pop $r8
-	mov $flags $r8
-	pop $r8
-	bclr $flags $p0
-	iret
-
-// Not real sure, but, MEM_CMD 7 will hang forever if this isn't done
-ctx_4160s:
-	mov $r14 0x4160
-	sethi $r14 0x400000
-	mov $r15 1
-	call #nv_wr32
-	ctx_4160s_wait:
-		call #nv_rd32
-		xbit $r15 $r15 4
-		bra e #ctx_4160s_wait
-	ret
-
-// Without clearing again at end of xfer, some things cause PGRAPH
-// to hang with STATUS=0x00000007 until it's cleared.. fbcon can
-// still function with it set however...
-ctx_4160c:
-	mov $r14 0x4160
-	sethi $r14 0x400000
-	clear b32 $r15
-	call #nv_wr32
-	ret
-
-// Again, not real sure
-//
-// In: $r15 value to set 0x404170 to
-//
-ctx_4170s:
-	mov $r14 0x4170
-	sethi $r14 0x400000
-	or $r15 0x10
-	call #nv_wr32
-	ret
-
-// Waits for a ctx_4170s() call to complete
-//
-ctx_4170w:
-	mov $r14 0x4170
-	sethi $r14 0x400000
-	call #nv_rd32
-	and $r15 0x10
-	bra ne #ctx_4170w
-	ret
-
-// Disables various things, waits a bit, and re-enables them..
-//
-// Not sure how exactly this helps, perhaps "ENABLE" is not such a
-// good description for the bits we turn off?  Anyways, without this,
-// funny things happen.
-//
-ctx_redswitch:
-	mov $r14 0x614
-	shl b32 $r14 6
-	mov $r15 0x270
-	iowr I[$r14] $r15	// HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL
-	mov $r15 8
-	ctx_redswitch_delay:
-		sub b32 $r15 1
-		bra ne #ctx_redswitch_delay
-	mov $r15 0x770
-	iowr I[$r14] $r15	// HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL
-	ret
-
-// Not a clue what this is for, except that unless the value is 0x10, the
-// strand context is saved (and presumably restored) incorrectly..
-//
-// In: $r15 value to set to (0x00/0x10 are used)
-//
-ctx_86c:
-	mov $r14 0x86c
-	shl b32 $r14 6
-	iowr I[$r14] $r15	// HUB(0x86c) = val
-	mov $r14 -0x75ec
-	sethi $r14 0x400000
-	call #nv_wr32		// ROP(0xa14) = val
-	mov $r14 -0x5794
-	sethi $r14 0x410000
-	call #nv_wr32		// GPC(0x86c) = val
-	ret
-
-// ctx_load - load's a channel's ctxctl data, and selects its vm
-//
-// In: $r2 channel address
-//
-ctx_load:
-	trace_set(T_CHAN)
-
-	// switch to channel, somewhat magic in parts..
-	mov $r10 12		// DONE_UNK12
-	call #wait_donez
-	mov $r1 0xa24
-	shl b32 $r1 6
-	iowr I[$r1 + 0x000] $r0	// 0x409a24
-	mov $r3 0xb00
-	shl b32 $r3 6
-	iowr I[$r3 + 0x100] $r2	// CHAN_NEXT
-	mov $r1 0xa0c
-	shl b32 $r1 6
-	mov $r4 7
-	iowr I[$r1 + 0x000] $r2 // MEM_CHAN
-	iowr I[$r1 + 0x100] $r4	// MEM_CMD
-	ctx_chan_wait_0:
-		iord $r4 I[$r1 + 0x100]
-		and $r4 0x1f
-		bra ne #ctx_chan_wait_0
-	iowr I[$r3 + 0x000] $r2	// CHAN_CUR
-
-	// load channel header, fetch PGRAPH context pointer
-	mov $xtargets $r0
-	bclr $r2 31
-	shl b32 $r2 4
-	add b32 $r2 2
-
-	trace_set(T_LCHAN)
-	mov $r1 0xa04
-	shl b32 $r1 6
-	iowr I[$r1 + 0x000] $r2		// MEM_BASE
-	mov $r1 0xa20
-	shl b32 $r1 6
-	mov $r2 0x0002
-	sethi $r2 0x80000000
-	iowr I[$r1 + 0x000] $r2		// MEM_TARGET = vram
-	mov $r1 0x10			// chan + 0x0210
-	mov $r2 #xfer_data
-	sethi $r2 0x00020000		// 16 bytes
-	xdld $r1 $r2
-	xdwait
-	trace_clr(T_LCHAN)
-
-	// update current context
-	ld b32 $r1 D[$r0 + #xfer_data + 4]
-	shl b32 $r1 24
-	ld b32 $r2 D[$r0 + #xfer_data + 0]
-	shr b32 $r2 8
-	or $r1 $r2
-	st b32 D[$r0 + #ctx_current] $r1
-
-	// set transfer base to start of context, and fetch context header
-	trace_set(T_LCTXH)
-	mov $r2 0xa04
-	shl b32 $r2 6
-	iowr I[$r2 + 0x000] $r1		// MEM_BASE
-	mov $r2 1
-	mov $r1 0xa20
-	shl b32 $r1 6
-	iowr I[$r1 + 0x000] $r2		// MEM_TARGET = vm
-	mov $r1 #chan_data
-	sethi $r1 0x00060000		// 256 bytes
-	xdld $r0 $r1
-	xdwait
-	trace_clr(T_LCTXH)
-
-	trace_clr(T_CHAN)
-	ret
-
-// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as
-//            the active channel for ctxctl, but not actually transfer
-//            any context data.  intended for use only during initial
-//            context construction.
-//
-// In: $r2 channel address
-//
-ctx_chan:
-	call #ctx_4160s
-	call #ctx_load
-	mov $r10 12			// DONE_UNK12
-	call #wait_donez
-	mov $r1 0xa10
-	shl b32 $r1 6
-	mov $r2 5
-	iowr I[$r1 + 0x000] $r2		// MEM_CMD = 5 (???)
-	ctx_chan_wait:
-		iord $r2 I[$r1 + 0x000]
-		or $r2 $r2
-		bra ne #ctx_chan_wait
-	call #ctx_4160c
-	ret
-
-// Execute per-context state overrides list
-//
-// Only executed on the first load of a channel.  Might want to look into
-// removing this and having the host directly modify the channel's context
-// to change this state...  The nouveau DRM already builds this list as
-// it's definitely needed for NVIDIA's, so we may as well use it for now
-//
-// Input: $r1 mmio list length
-//
-ctx_mmio_exec:
-	// set transfer base to be the mmio list
-	ld b32 $r3 D[$r0 + #chan_mmio_address]
-	mov $r2 0xa04
-	shl b32 $r2 6
-	iowr I[$r2 + 0x000] $r3		// MEM_BASE
-
-	clear b32 $r3
-	ctx_mmio_loop:
-		// fetch next 256 bytes of mmio list if necessary
-		and $r4 $r3 0xff
-		bra ne #ctx_mmio_pull
-			mov $r5 #xfer_data
-			sethi $r5 0x00060000	// 256 bytes
-			xdld $r3 $r5
-			xdwait
-
-		// execute a single list entry
-		ctx_mmio_pull:
-		ld b32 $r14 D[$r4 + #xfer_data + 0x00]
-		ld b32 $r15 D[$r4 + #xfer_data + 0x04]
-		call #nv_wr32
-
-		// next!
-		add b32 $r3 8
-		sub b32 $r1 1
-		bra ne #ctx_mmio_loop
-
-	// set transfer base back to the current context
-	ctx_mmio_done:
-	ld b32 $r3 D[$r0 + #ctx_current]
-	iowr I[$r2 + 0x000] $r3		// MEM_BASE
-
-	// disable the mmio list now, we don't need/want to execute it again
-	st b32 D[$r0 + #chan_mmio_count] $r0
-	mov $r1 #chan_data
-	sethi $r1 0x00060000		// 256 bytes
-	xdst $r0 $r1
-	xdwait
-	ret
-
-// Transfer HUB context data between GPU and storage area
-//
-// In: $r2 channel address
-//     $p1 clear on save, set on load
-//     $p2 set if opposite direction done/will be done, so:
-//		on save it means: "a load will follow this save"
-//		on load it means: "a save preceeded this load"
-//
-ctx_xfer:
-	// according to mwk, some kind of wait for idle
-	mov $r15 0xc00
-	shl b32 $r15 6
-	mov $r14 4
-	iowr I[$r15 + 0x200] $r14
-	ctx_xfer_idle:
-		iord $r14 I[$r15 + 0x000]
-		and $r14 0x2000
-		bra ne #ctx_xfer_idle
-
-	bra not $p1 #ctx_xfer_pre
-	bra $p2 #ctx_xfer_pre_load
-	ctx_xfer_pre:
-		mov $r15 0x10
-		call #ctx_86c
-		call #ctx_4160s
-		bra not $p1 #ctx_xfer_exec
-
-	ctx_xfer_pre_load:
-		mov $r15 2
-		call #ctx_4170s
-		call #ctx_4170w
-		call #ctx_redswitch
-		clear b32 $r15
-		call #ctx_4170s
-		call #ctx_load
-
-	// fetch context pointer, and initiate xfer on all GPCs
-	ctx_xfer_exec:
-	ld b32 $r1 D[$r0 + #ctx_current]
-	mov $r2 0x414
-	shl b32 $r2 6
-	iowr I[$r2 + 0x000] $r0	// BAR_STATUS = reset
-	mov $r14 -0x5b00
-	sethi $r14 0x410000
-	mov b32 $r15 $r1
-	call #nv_wr32		// GPC_BCAST_WRCMD_DATA = ctx pointer
-	add b32 $r14 4
-	xbit $r15 $flags $p1
-	xbit $r2 $flags $p2
-	shl b32 $r2 1
-	or $r15 $r2
-	call #nv_wr32		// GPC_BCAST_WRCMD_CMD = GPC_XFER(type)
-
-	// strands
-	mov $r1 0x4afc
-	sethi $r1 0x20000
-	mov $r2 0xc
-	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x0c
-	call #strand_wait
-	mov $r2 0x47fc
-	sethi $r2 0x20000
-	iowr I[$r2] $r0		// STRAND_FIRST_GENE(0x3f) = 0x00
-	xbit $r2 $flags $p1
-	add b32 $r2 3
-	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
-
-	// mmio context
-	xbit $r10 $flags $p1	// direction
-	or $r10 6		// first, last
-	mov $r11 0		// base = 0
-	ld b32 $r12 D[$r0 + #hub_mmio_list_head]
-	ld b32 $r13 D[$r0 + #hub_mmio_list_tail]
-	mov $r14 0		// not multi
-	call #mmctx_xfer
-
-	// wait for GPCs to all complete
-	mov $r10 8		// DONE_BAR
-	call #wait_doneo
-
-	// wait for strand xfer to complete
-	call #strand_wait
-
-	// post-op
-	bra $p1 #ctx_xfer_post
-		mov $r10 12		// DONE_UNK12
-		call #wait_donez
-		mov $r1 0xa10
-		shl b32 $r1 6
-		mov $r2 5
-		iowr I[$r1] $r2		// MEM_CMD
-		ctx_xfer_post_save_wait:
-			iord $r2 I[$r1]
-			or $r2 $r2
-			bra ne #ctx_xfer_post_save_wait
-
-	bra $p2 #ctx_xfer_done
-	ctx_xfer_post:
-		mov $r15 2
-		call #ctx_4170s
-		clear b32 $r15
-		call #ctx_86c
-		call #strand_post
-		call #ctx_4170w
-		clear b32 $r15
-		call #ctx_4170s
-
-		bra not $p1 #ctx_xfer_no_post_mmio
-		ld b32 $r1 D[$r0 + #chan_mmio_count]
-		or $r1 $r1
-		bra e #ctx_xfer_no_post_mmio
-			call #ctx_mmio_exec
-
-		ctx_xfer_no_post_mmio:
-		call #ctx_4160c
-
-	ctx_xfer_done:
-	ret
-
+#include "com.fuc"
+#include "hub.fuc"
 .align 256
+#undef INCLUDE_CODE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,9 +1,13 @@
 uint32_t nvc0_grhub_data[] = {
-/* 0x0000: gpc_count */
+/* 0x0000: hub_mmio_list_head */
+	0x00000300,
+/* 0x0004: hub_mmio_list_tail */
+	0x00000304,
+/* 0x0008: gpc_count */
 	0x00000000,
-/* 0x0004: rop_count */
+/* 0x000c: rop_count */
 	0x00000000,
-/* 0x0008: cmd_queue */
+/* 0x0010: cmd_queue */
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -22,114 +26,13 @@ uint32_t nvc0_grhub_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
-/* 0x0050: hub_mmio_list_head */
+/* 0x0058: ctx_current */
+	0x00000000,
+	0x00000000,
 	0x00000000,
-/* 0x0054: hub_mmio_list_tail */
 	0x00000000,
-/* 0x0058: ctx_current */
 	0x00000000,
-/* 0x005c: chipsets */
-	0x000000c0,
-	0x013c00a0,
-	0x000000c1,
-	0x014000a0,
-	0x000000c3,
-	0x013c00a0,
-	0x000000c4,
-	0x013c00a0,
-	0x000000c8,
-	0x013c00a0,
-	0x000000ce,
-	0x013c00a0,
-	0x000000cf,
-	0x013c00a0,
-	0x000000d9,
-	0x01dc0140,
 	0x00000000,
-/* 0x00a0: nvc0_hub_mmio_head */
-	0x0417e91c,
-	0x04400204,
-	0x28404004,
-	0x00404044,
-	0x34404094,
-	0x184040d0,
-	0x004040f8,
-	0x08404130,
-	0x08404150,
-	0x04404164,
-	0x08404174,
-	0x1c404200,
-	0x34404404,
-	0x0c404460,
-	0x00404480,
-	0x00404498,
-	0x0c404604,
-	0x7c404618,
-	0x50404698,
-	0x044046f0,
-	0x54404700,
-	0x00405800,
-	0x08405830,
-	0x00405854,
-	0x0c405870,
-	0x04405a00,
-	0x00405a18,
-	0x00406020,
-	0x0c406028,
-	0x044064a8,
-	0x044064b4,
-	0x00407804,
-	0x1440780c,
-	0x004078bc,
-	0x18408000,
-	0x00408064,
-	0x08408800,
-	0x0c408900,
-	0x00408980,
-/* 0x013c: nvc0_hub_mmio_tail */
-	0x044064c0,
-/* 0x0140: nvc1_hub_mmio_tail */
-/* 0x0140: nvd9_hub_mmio_head */
-	0x0417e91c,
-	0x04400204,
-	0x24404004,
-	0x00404044,
-	0x34404094,
-	0x184040d0,
-	0x004040f8,
-	0x08404130,
-	0x08404150,
-	0x04404164,
-	0x04404178,
-	0x1c404200,
-	0x34404404,
-	0x0c404460,
-	0x00404480,
-	0x00404498,
-	0x0c404604,
-	0x7c404618,
-	0x50404698,
-	0x044046f0,
-	0x54404700,
-	0x00405800,
-	0x08405830,
-	0x00405854,
-	0x0c405870,
-	0x04405a00,
-	0x00405a18,
-	0x00406020,
-	0x0c406028,
-	0x044064a8,
-	0x104064b4,
-	0x00407804,
-	0x1440780c,
-	0x004078bc,
-	0x18408000,
-	0x00408064,
-	0x08408800,
-	0x0c408900,
-	0x00408980,
-/* 0x01dc: nvd9_hub_mmio_tail */
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -139,10 +42,7 @@ uint32_t nvc0_grhub_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
-/* 0x0200: chan_data */
-/* 0x0200: chan_mmio_count */
 	0x00000000,
-/* 0x0204: chan_mmio_address */
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -169,6 +69,32 @@ uint32_t nvc0_grhub_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
+/* 0x0100: chan_data */
+/* 0x0100: chan_mmio_count */
+	0x00000000,
+/* 0x0104: chan_mmio_address */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -206,19 +132,88 @@ uint32_t nvc0_grhub_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
-/* 0x0300: xfer_data */
 	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0200: xfer_data */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0300: hub_mmio_list_base */
+	0x0417e91c,
 };
 
 uint32_t nvc0_grhub_code[] = {
-	0x03090ef5,
+	0x031b0ef5,
 /* 0x0004: queue_put */
 	0x9800d898,
 	0x86f001d9,
 	0x0489b808,
 	0xf00c1bf4,
 	0x21f502f7,
-	0x00f802ec,
+	0x00f802fe,
 /* 0x001c: queue_put_next */
 	0xb60798c4,
 	0x8dbb0384,
@@ -250,7 +245,7 @@ uint32_t nvc0_grhub_code[] = {
 	0xc800bccf,
 	0x1bf41fcc,
 	0x06a7f0fa,
-	0x010321f5,
+	0x010921f5,
 	0xf840bfcf,
 /* 0x008d: nv_wr32 */
 	0x28b7f100,
@@ -272,63 +267,66 @@ uint32_t nvc0_grhub_code[] = {
 	0x0684b604,
 	0xf80080d0,
 /* 0x00c9: wait_donez */
-	0x3c87f100,
-	0x0684b608,
-	0x99f094bd,
-	0x0089d000,
-	0x081887f1,
-	0xd00684b6,
-/* 0x00e2: wait_done_wait_donez */
-	0x87f1008a,
-	0x84b60400,
-	0x0088cf06,
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x07f104bd,
+	0x03f00600,
+	0x000ad002,
+/* 0x00e6: wait_donez_ne */
+	0x87f104bd,
+	0x83f00000,
+	0x0088cf01,
 	0xf4888aff,
-	0x87f1f31b,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00099,
-/* 0x0103: wait_doneo */
-	0xf100f800,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00099f0,
-	0x87f10089,
+	0x94bdf31b,
+	0xf10099f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0109: wait_doneo */
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x87f104bd,
 	0x84b60818,
 	0x008ad006,
-/* 0x011c: wait_done_wait_doneo */
+/* 0x0124: wait_doneo_e */
 	0x040087f1,
 	0xcf0684b6,
 	0x8aff0088,
 	0xf30bf488,
-	0x085c87f1,
-	0xbd0684b6,
-	0x0099f094,
-	0xf80089d0,
-/* 0x013d: mmctx_size */
-/* 0x013f: nv_mmctx_size_loop */
-	0x9894bd00,
-	0x85b600e8,
-	0x0180b61a,
-	0xbb0284b6,
-	0xe0b60098,
-	0x04efb804,
-	0xb9eb1bf4,
-	0x00f8029f,
-/* 0x015c: mmctx_xfer */
-	0x083c87f1,
-	0xbd0684b6,
-	0x0199f094,
-	0xf10089d0,
+	0x99f094bd,
+	0x0007f100,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x0147: mmctx_size */
+	0xbd00f804,
+/* 0x0149: nv_mmctx_size_loop */
+	0x00e89894,
+	0xb61a85b6,
+	0x84b60180,
+	0x0098bb02,
+	0xb804e0b6,
+	0x1bf404ef,
+	0x029fb9eb,
+/* 0x0166: mmctx_xfer */
+	0x94bd00f8,
+	0xf10199f0,
+	0xf00f0007,
+	0x09d00203,
+	0xf104bd00,
 	0xb6071087,
 	0x94bd0684,
 	0xf405bbfd,
 	0x8bd0090b,
 	0x0099f000,
-/* 0x0180: mmctx_base_disabled */
+/* 0x018c: mmctx_base_disabled */
 	0xf405eefd,
 	0x8ed00c0b,
 	0xc08fd080,
-/* 0x018f: mmctx_multi_disabled */
+/* 0x019b: mmctx_multi_disabled */
 	0xb70199f0,
 	0xc8010080,
 	0xb4b600ab,
@@ -336,8 +334,8 @@ uint32_t nvc0_grhub_code[] = {
 	0xb601aec8,
 	0xbefd11e4,
 	0x008bd005,
-/* 0x01a8: mmctx_exec_loop */
-/* 0x01a8: mmctx_wait_free */
+/* 0x01b4: mmctx_exec_loop */
+/* 0x01b4: mmctx_wait_free */
 	0xf0008ecf,
 	0x0bf41fe4,
 	0x00ce98fa,
@@ -346,76 +344,77 @@ uint32_t nvc0_grhub_code[] = {
 	0x04cdb804,
 	0xc8e81bf4,
 	0x1bf402ab,
-/* 0x01c9: mmctx_fini_wait */
+/* 0x01d5: mmctx_fini_wait */
 	0x008bcf18,
 	0xb01fb4f0,
 	0x1bf410b4,
 	0x02a7f0f7,
 	0xf4c921f4,
-/* 0x01de: mmctx_stop */
+/* 0x01ea: mmctx_stop */
 	0xabc81b0e,
 	0x10b4b600,
 	0xf00cb9f0,
 	0x8bd012b9,
-/* 0x01ed: mmctx_stop_wait */
+/* 0x01f9: mmctx_stop_wait */
 	0x008bcf00,
 	0xf412bbc8,
-/* 0x01f6: mmctx_done */
-	0x87f1fa1b,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00199,
-/* 0x0207: strand_wait */
-	0xf900f800,
-	0x02a7f0a0,
-	0xfcc921f4,
-/* 0x0213: strand_pre */
-	0xf100f8a0,
-	0xf04afc87,
-	0x97f00283,
-	0x0089d00c,
-	0x020721f5,
-/* 0x0226: strand_post */
-	0x87f100f8,
-	0x83f04afc,
-	0x0d97f002,
-	0xf50089d0,
-	0xf8020721,
-/* 0x0239: strand_set */
-	0xfca7f100,
-	0x02a3f04f,
-	0x0500aba2,
-	0xd00fc7f0,
-	0xc7f000ac,
-	0x00bcd00b,
-	0x020721f5,
-	0xf000aed0,
-	0xbcd00ac7,
-	0x0721f500,
-/* 0x0263: strand_ctx_init */
-	0xf100f802,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00399f0,
+/* 0x0202: mmctx_done */
+	0x94bdfa1b,
+	0xf10199f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0215: strand_wait */
+	0xf0a0f900,
+	0x21f402a7,
+	0xf8a0fcc9,
+/* 0x0221: strand_pre */
+	0xfc87f100,
+	0x0283f04a,
+	0xd00c97f0,
 	0x21f50089,
-	0xe7f00213,
-	0x3921f503,
+	0x00f80215,
+/* 0x0234: strand_post */
+	0x4afc87f1,
+	0xf00283f0,
+	0x89d00d97,
+	0x1521f500,
+/* 0x0247: strand_set */
+	0xf100f802,
+	0xf04ffca7,
+	0xaba202a3,
+	0xc7f00500,
+	0x00acd00f,
+	0xd00bc7f0,
+	0x21f500bc,
+	0xaed00215,
+	0x0ac7f000,
+	0xf500bcd0,
+	0xf8021521,
+/* 0x0271: strand_ctx_init */
+	0xf094bd00,
+	0x07f10399,
+	0x03f00f00,
+	0x0009d002,
+	0x21f504bd,
+	0xe7f00221,
+	0x4721f503,
 	0xfca7f102,
 	0x02a3f046,
 	0x0400aba0,
 	0xf040a0d0,
 	0xbcd001c7,
-	0x0721f500,
+	0x1521f500,
 	0x010c9202,
 	0xf000acd0,
 	0xbcd002c7,
-	0x0721f500,
-	0x2621f502,
+	0x1521f500,
+	0x3421f502,
 	0x8087f102,
 	0x0684b608,
 	0xb70089cf,
 	0x95220080,
-/* 0x02ba: ctx_init_strand_loop */
+/* 0x02ca: ctx_init_strand_loop */
 	0x8ed008fe,
 	0x408ed000,
 	0xb6808acf,
@@ -424,73 +423,61 @@ uint32_t nvc0_grhub_code[] = {
 	0xb60480b6,
 	0x1bf40192,
 	0x08e4b6e8,
-	0xf1f2efbc,
-	0xb6085c87,
-	0x94bd0684,
-	0xd00399f0,
-	0x00f80089,
-/* 0x02ec: error */
-	0xe7f1e0f9,
-	0xe4b60814,
-	0x00efd006,
-	0x0c1ce7f1,
-	0xf006e4b6,
-	0xefd001f7,
-	0xf8e0fc00,
-/* 0x0309: init */
-	0xfe04bd00,
-	0x07fe0004,
-	0x0017f100,
-	0x0227f012,
-	0xf10012d0,
-	0xfe05b917,
-	0x17f10010,
-	0x10d00400,
-	0x0437f1c0,
-	0x0634b604,
-	0x200327f1,
-	0xf10032d0,
-	0xd0200427,
-	0x27f10132,
-	0x32d0200b,
-	0x0c27f102,
-	0x0732d020,
-	0x0c2427f1,
-	0xb90624b6,
-	0x23d00003,
+	0xbdf2efbc,
+	0x0399f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+/* 0x02fe: error */
+	0x07f100f8,
+	0x03f00500,
+	0x000fd002,
+	0xf7f004bd,
+	0x0007f101,
+	0x0303f007,
+	0xbd000fd0,
+/* 0x031b: init */
+	0xbd00f804,
+	0x0004fe04,
+	0xf10007fe,
+	0xf0120017,
+	0x12d00227,
+	0xb117f100,
+	0x0010fe05,
+	0x040017f1,
+	0xf1c010d0,
+	0xb6040437,
+	0x27f10634,
+	0x32d02003,
 	0x0427f100,
-	0x0023f087,
-	0xb70012d0,
-	0xf0010012,
-	0x12d00427,
-	0x1031f400,
-	0x9604e7f1,
-	0xf440e3f0,
-	0xf1c76821,
-	0x01018090,
-	0x801ff4f0,
-	0x17f0000f,
-	0x041fbb01,
-	0xf10112b6,
-	0xb6040c27,
-	0x21d00624,
-	0x4021d000,
-	0x080027f1,
-	0xcf0624b6,
-	0xf7f00022,
-/* 0x03a9: init_find_chipset */
-	0x08f0b654,
-	0xb800f398,
-	0x0bf40432,
-	0x0034b00b,
-	0xf8f11bf4,
-/* 0x03bd: init_context */
-	0x0017f100,
-	0x02fe5801,
-	0xf003ff58,
-	0x0e8000e3,
-	0x150f8014,
-	0x013d21f5,
+	0x0132d020,
+	0x200b27f1,
+	0xf10232d0,
+	0xd0200c27,
+	0x27f10732,
+	0x24b60c24,
+	0x0003b906,
+	0xf10023d0,
+	0xf0870427,
+	0x12d00023,
+	0x0012b700,
+	0x0427f001,
+	0xf40012d0,
+	0xe7f11031,
+	0xe3f09604,
+	0x6821f440,
+	0x8090f1c7,
+	0xf4f00301,
+	0x020f801f,
+	0xbb0117f0,
+	0x12b6041f,
+	0x0c27f101,
+	0x0624b604,
+	0xd00021d0,
+	0x17f14021,
+	0x0e980100,
+	0x010f9800,
+	0x014721f5,
 	0x070037f1,
 	0x950634b6,
 	0x34d00814,
@@ -501,208 +488,213 @@ uint32_t nvc0_grhub_code[] = {
 	0x0815b600,
 	0xb60110b6,
 	0x1fb90814,
-	0x6321f502,
+	0x7121f502,
 	0x001fbb02,
-	0xf1000398,
+	0xf1020398,
 	0xf0200047,
-/* 0x040e: init_gpc */
+/* 0x03f6: init_gpc */
 	0x4ea05043,
 	0x1fb90804,
 	0x8d21f402,
-	0x08004ea0,
-	0xf4022fb9,
-	0x4ea08d21,
-	0xf4bd010c,
-	0xa08d21f4,
-	0xf401044e,
+	0x010c4ea0,
+	0x21f4f4bd,
+	0x044ea08d,
+	0x8d21f401,
+	0x01004ea0,
+	0xf402f7f0,
 	0x4ea08d21,
-	0xf7f00100,
-	0x8d21f402,
-	0x08004ea0,
-/* 0x0440: init_gpc_wait */
-	0xc86821f4,
-	0x0bf41fff,
-	0x044ea0fa,
-	0x6821f408,
-	0xb7001fbb,
-	0xb6800040,
-	0x1bf40132,
-	0x0027f1b4,
-	0x0624b608,
-	0xb74021d0,
-	0xbd080020,
+/* 0x041e: init_gpc_wait */
+	0x21f40800,
+	0x1fffc868,
+	0xa0fa0bf4,
+	0xf408044e,
+	0x1fbb6821,
+	0x0040b700,
+	0x0132b680,
+	0xf1be1bf4,
+	0xf0010007,
+	0x01d00203,
+	0xbd04bd00,
 	0x1f19f014,
-/* 0x0473: main */
-	0xf40021d0,
-	0x28f40031,
-	0x08d7f000,
-	0xf43921f4,
-	0xe4b1f401,
-	0x1bf54001,
-	0x87f100d1,
-	0x84b6083c,
-	0xf094bd06,
-	0x89d00499,
-	0x0017f100,
-	0x0614b60b,
-	0xcf4012cf,
-	0x13c80011,
-	0x7e0bf41f,
+	0x080007f1,
+	0xd00203f0,
+	0x04bd0001,
+/* 0x0458: main */
+	0xf40031f4,
+	0xd7f00028,
+	0x3921f410,
+	0xb1f401f4,
+	0xf54001e4,
+	0xbd00de1b,
+	0x0499f094,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x0b0017f1,
+	0xcf0614b6,
+	0x11cf4012,
+	0x1f13c800,
+	0x00870bf5,
 	0xf41f23c8,
-	0x20f95a0b,
-	0xf10212b9,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00799f0,
-	0x32f40089,
-	0x0231f401,
-	0x082921f5,
-	0x085c87f1,
-	0xbd0684b6,
+	0x20f9620b,
+	0xbd0212b9,
 	0x0799f094,
-	0xfc0089d0,
-	0x3c87f120,
-	0x0684b608,
-	0x99f094bd,
-	0x0089d006,
-	0xf50131f4,
-	0xf1082921,
-	0xb6085c87,
-	0x94bd0684,
-	0xd00699f0,
-	0x0ef40089,
-/* 0x0509: chsw_prev_no_next */
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0xf40132f4,
+	0x21f50231,
+	0x94bd082f,
+	0xf10799f0,
+	0xf0170007,
+	0x09d00203,
+	0xfc04bd00,
+	0xf094bd20,
+	0x07f10699,
+	0x03f00f00,
+	0x0009d002,
+	0x31f404bd,
+	0x2f21f501,
+	0xf094bd08,
+	0x07f10699,
+	0x03f01700,
+	0x0009d002,
+	0x0ef404bd,
+/* 0x04f9: chsw_prev_no_next */
 	0xb920f931,
 	0x32f40212,
 	0x0232f401,
-	0x082921f5,
+	0x082f21f5,
 	0x17f120fc,
 	0x14b60b00,
 	0x0012d006,
-/* 0x0527: chsw_no_prev */
+/* 0x0517: chsw_no_prev */
 	0xc8130ef4,
 	0x0bf41f23,
 	0x0131f40d,
 	0xf50232f4,
-/* 0x0537: chsw_done */
-	0xf1082921,
+/* 0x0527: chsw_done */
+	0xf1082f21,
 	0xb60b0c17,
 	0x27f00614,
 	0x0012d001,
-	0x085c87f1,
-	0xbd0684b6,
-	0x0499f094,
-	0xf50089d0,
-/* 0x0557: main_not_ctx_switch */
-	0xb0ff200e,
-	0x1bf401e4,
-	0x02f2b90d,
-	0x07b521f5,
-/* 0x0567: main_not_ctx_chan */
-	0xb0420ef4,
-	0x1bf402e4,
-	0x3c87f12e,
-	0x0684b608,
 	0x99f094bd,
-	0x0089d007,
+	0x0007f104,
+	0x0203f017,
+	0xbd0009d0,
+	0x130ef504,
+/* 0x0549: main_not_ctx_switch */
+	0x01e4b0ff,
+	0xb90d1bf4,
+	0x21f502f2,
+	0x0ef407bb,
+/* 0x0559: main_not_ctx_chan */
+	0x02e4b046,
+	0xbd321bf4,
+	0x0799f094,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
 	0xf40132f4,
 	0x21f50232,
-	0x87f10829,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00799,
-	0x110ef400,
-/* 0x0598: main_not_ctx_save */
-	0xf010ef94,
-	0x21f501f5,
-	0x0ef502ec,
-/* 0x05a6: main_done */
-	0x17f1fed1,
-	0x14b60820,
-	0xf024bd06,
-	0x12d01f29,
-	0xbe0ef500,
-/* 0x05b9: ih */
+	0x94bd082f,
+	0xf10799f0,
+	0xf0170007,
+	0x09d00203,
+	0xf404bd00,
+/* 0x058e: main_not_ctx_save */
+	0xef94110e,
+	0x01f5f010,
+	0x02fe21f5,
+	0xfec00ef5,
+/* 0x059c: main_done */
+	0x29f024bd,
+	0x0007f11f,
+	0x0203f008,
+	0xbd0002d0,
+	0xab0ef504,
+/* 0x05b1: ih */
 	0xfe80f9fe,
 	0x80f90188,
 	0xa0f990f9,
 	0xd0f9b0f9,
 	0xf0f9e0f9,
-	0xc4800acf,
-	0x0bf404ab,
-	0x00b7f11d,
-	0x08d7f019,
-	0xcf40becf,
-	0x21f400bf,
-	0x00b0b704,
-	0x01e7f004,
-/* 0x05ef: ih_no_fifo */
-	0xe400bed0,
-	0xf40100ab,
-	0xd7f00d0b,
-	0x01e7f108,
-	0x0421f440,
-/* 0x0600: ih_no_ctxsw */
-	0x0104b7f1,
-	0xabffb0bd,
-	0x0d0bf4b4,
-	0x0c1ca7f1,
-	0xd006a4b6,
-/* 0x0616: ih_no_other */
-	0x0ad000ab,
-	0xfcf0fc40,
-	0xfcd0fce0,
-	0xfca0fcb0,
-	0xfe80fc90,
-	0x80fc0088,
-	0xf80032f4,
-/* 0x0631: ctx_4160s */
-	0x60e7f101,
-	0x40e3f041,
-	0xf401f7f0,
-/* 0x063e: ctx_4160s_wait */
-	0x21f48d21,
-	0x04ffc868,
-	0xf8fa0bf4,
-/* 0x0649: ctx_4160c */
-	0x60e7f100,
+	0x0acf04bd,
+	0x04abc480,
+	0xf11d0bf4,
+	0xf01900b7,
+	0xbecf10d7,
+	0x00bfcf40,
+	0xb70421f4,
+	0xf00400b0,
+	0xbed001e7,
+/* 0x05e9: ih_no_fifo */
+	0x00abe400,
+	0x0d0bf401,
+	0xf110d7f0,
+	0xf44001e7,
+/* 0x05fa: ih_no_ctxsw */
+	0xb7f10421,
+	0xb0bd0104,
+	0xf4b4abff,
+	0xa7f10d0b,
+	0xa4b60c1c,
+	0x00abd006,
+/* 0x0610: ih_no_other */
+	0xfc400ad0,
+	0xfce0fcf0,
+	0xfcb0fcd0,
+	0xfc90fca0,
+	0x0088fe80,
+	0x32f480fc,
+/* 0x062b: ctx_4160s */
+	0xf101f800,
+	0xf04160e7,
+	0xf7f040e3,
+	0x8d21f401,
+/* 0x0638: ctx_4160s_wait */
+	0xc86821f4,
+	0x0bf404ff,
+/* 0x0643: ctx_4160c */
+	0xf100f8fa,
+	0xf04160e7,
+	0xf4bd40e3,
+	0xf88d21f4,
+/* 0x0651: ctx_4170s */
+	0x70e7f100,
 	0x40e3f041,
-	0x21f4f4bd,
-/* 0x0657: ctx_4170s */
-	0xf100f88d,
-	0xf04170e7,
-	0xf5f040e3,
-	0x8d21f410,
-/* 0x0666: ctx_4170w */
-	0xe7f100f8,
-	0xe3f04170,
-	0x6821f440,
-	0xf410f4f0,
-	0x00f8f31b,
-/* 0x0678: ctx_redswitch */
-	0x0614e7f1,
-	0xf106e4b6,
-	0xd00270f7,
-	0xf7f000ef,
-/* 0x0689: ctx_redswitch_delay */
-	0x01f2b608,
-	0xf1fd1bf4,
-	0xd00770f7,
-	0x00f800ef,
-/* 0x0698: ctx_86c */
-	0x086ce7f1,
-	0xd006e4b6,
-	0xe7f100ef,
-	0xe3f08a14,
-	0x8d21f440,
-	0xa86ce7f1,
-	0xf441e3f0,
+	0xf410f5f0,
 	0x00f88d21,
-/* 0x06b8: ctx_load */
-	0x083c87f1,
-	0xbd0684b6,
-	0x0599f094,
-	0xf00089d0,
+/* 0x0660: ctx_4170w */
+	0x4170e7f1,
+	0xf440e3f0,
+	0xf4f06821,
+	0xf31bf410,
+/* 0x0672: ctx_redswitch */
+	0xe7f100f8,
+	0xe4b60614,
+	0x70f7f106,
+	0x00efd002,
+/* 0x0683: ctx_redswitch_delay */
+	0xb608f7f0,
+	0x1bf401f2,
+	0x70f7f1fd,
+	0x00efd007,
+/* 0x0692: ctx_86c */
+	0xe7f100f8,
+	0xe4b6086c,
+	0x00efd006,
+	0x8a14e7f1,
+	0xf440e3f0,
+	0xe7f18d21,
+	0xe3f0a86c,
+	0x8d21f441,
+/* 0x06b2: ctx_load */
+	0x94bd00f8,
+	0xf10599f0,
+	0xf00f0007,
+	0x09d00203,
+	0xf004bd00,
 	0x21f40ca7,
 	0x2417f1c9,
 	0x0614b60a,
@@ -713,168 +705,169 @@ uint32_t nvc0_grhub_code[] = {
 	0x0614b60a,
 	0xd00747f0,
 	0x14d00012,
-/* 0x06f1: ctx_chan_wait_0 */
+/* 0x06ed: ctx_chan_wait_0 */
 	0x4014cf40,
 	0xf41f44f0,
 	0x32d0fa1b,
 	0x000bfe00,
 	0xb61f2af0,
 	0x20b60424,
-	0x3c87f102,
-	0x0684b608,
+	0xf094bd02,
+	0x07f10899,
+	0x03f00f00,
+	0x0009d002,
+	0x17f104bd,
+	0x14b60a04,
+	0x0012d006,
+	0x0a2017f1,
+	0xf00614b6,
+	0x23f10227,
+	0x12d08000,
+	0x1017f000,
+	0x020027f1,
+	0xfa0223f0,
+	0x03f80512,
 	0x99f094bd,
-	0x0089d008,
-	0x0a0417f1,
-	0xd00614b6,
-	0x17f10012,
-	0x14b60a20,
-	0x0227f006,
-	0x800023f1,
-	0xf00012d0,
-	0x27f11017,
-	0x23f00300,
-	0x0512fa02,
-	0x87f103f8,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00899,
-	0xc1019800,
+	0x0007f108,
+	0x0203f017,
+	0xbd0009d0,
+	0x81019804,
 	0x981814b6,
-	0x25b6c002,
+	0x25b68002,
 	0x0512fd08,
-	0xf1160180,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00999f0,
-	0x27f10089,
-	0x24b60a04,
-	0x0021d006,
-	0xf10127f0,
-	0xb60a2017,
-	0x12d00614,
-	0x0017f100,
-	0x0613f002,
-	0xf80501fa,
-	0x5c87f103,
-	0x0684b608,
-	0x99f094bd,
-	0x0089d009,
-	0x085c87f1,
-	0xbd0684b6,
-	0x0599f094,
-	0xf80089d0,
-/* 0x07b5: ctx_chan */
-	0x3121f500,
-	0xb821f506,
-	0x0ca7f006,
-	0xf1c921f4,
-	0xb60a1017,
-	0x27f00614,
-	0x0012d005,
-/* 0x07d0: ctx_chan_wait */
-	0xfd0012cf,
-	0x1bf40522,
-	0x4921f5fa,
-/* 0x07df: ctx_mmio_exec */
-	0x9800f806,
-	0x27f18103,
-	0x24b60a04,
-	0x0023d006,
-/* 0x07ee: ctx_mmio_loop */
-	0x34c434bd,
-	0x0f1bf4ff,
-	0x030057f1,
-	0xfa0653f0,
-	0x03f80535,
-/* 0x0800: ctx_mmio_pull */
-	0x98c04e98,
-	0x21f4c14f,
-	0x0830b68d,
-	0xf40112b6,
-/* 0x0812: ctx_mmio_done */
-	0x0398df1b,
-	0x0023d016,
-	0xf1800080,
-	0xf0020017,
+	0xbd160180,
+	0x0999f094,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x0a0427f1,
+	0xd00624b6,
+	0x27f00021,
+	0x2017f101,
+	0x0614b60a,
+	0xf10012d0,
+	0xf0010017,
 	0x01fa0613,
-	0xf803f806,
-/* 0x0829: ctx_xfer */
-	0x00f7f100,
-	0x06f4b60c,
-	0xd004e7f0,
-/* 0x0836: ctx_xfer_idle */
-	0xfecf80fe,
-	0x00e4f100,
-	0xf91bf420,
-	0xf40611f4,
-/* 0x0846: ctx_xfer_pre */
-	0xf7f01102,
-	0x9821f510,
-	0x3121f506,
-	0x1c11f406,
-/* 0x0854: ctx_xfer_pre_load */
-	0xf502f7f0,
-	0xf5065721,
-	0xf5066621,
-	0xbd067821,
-	0x5721f5f4,
-	0xb821f506,
-/* 0x086d: ctx_xfer_exec */
-	0x16019806,
-	0x041427f1,
+	0xbd03f805,
+	0x0999f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x99f094bd,
+	0x0007f105,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x07bb: ctx_chan */
+	0xf500f804,
+	0xf5062b21,
+	0xf006b221,
+	0x21f40ca7,
+	0x1017f1c9,
+	0x0614b60a,
+	0xd00527f0,
+/* 0x07d6: ctx_chan_wait */
+	0x12cf0012,
+	0x0522fd00,
+	0xf5fa1bf4,
+	0xf8064321,
+/* 0x07e5: ctx_mmio_exec */
+	0x41039800,
+	0x0a0427f1,
 	0xd00624b6,
-	0xe7f10020,
-	0xe3f0a500,
-	0x021fb941,
+	0x34bd0023,
+/* 0x07f4: ctx_mmio_loop */
+	0xf4ff34c4,
+	0x57f10f1b,
+	0x53f00200,
+	0x0535fa06,
+/* 0x0806: ctx_mmio_pull */
+	0x4e9803f8,
+	0x814f9880,
 	0xb68d21f4,
-	0xfcf004e0,
-	0x022cf001,
-	0xfd0124b6,
-	0x21f405f2,
-	0xfc17f18d,
-	0x0213f04a,
-	0xd00c27f0,
-	0x21f50012,
-	0x27f10207,
-	0x23f047fc,
-	0x0020d002,
-	0xb6012cf0,
-	0x12d00320,
-	0x01acf000,
-	0xf006a5f0,
-	0x0c9800b7,
-	0x150d9814,
-	0xf500e7f0,
-	0xf0015c21,
-	0x21f508a7,
-	0x21f50103,
-	0x01f40207,
-	0x0ca7f022,
-	0xf1c921f4,
-	0xb60a1017,
-	0x27f00614,
-	0x0012d005,
-/* 0x08f4: ctx_xfer_post_save_wait */
-	0xfd0012cf,
-	0x1bf40522,
-	0x3202f4fa,
-/* 0x0900: ctx_xfer_post */
-	0xf502f7f0,
-	0xbd065721,
-	0x9821f5f4,
-	0x2621f506,
-	0x6621f502,
+	0x12b60830,
+	0xdf1bf401,
+/* 0x0818: ctx_mmio_done */
+	0xd0160398,
+	0x00800023,
+	0x0017f140,
+	0x0613f001,
+	0xf80601fa,
+/* 0x082f: ctx_xfer */
+	0xf100f803,
+	0xb60c00f7,
+	0xe7f006f4,
+	0x80fed004,
+/* 0x083c: ctx_xfer_idle */
+	0xf100fecf,
+	0xf42000e4,
+	0x11f4f91b,
+	0x1102f406,
+/* 0x084c: ctx_xfer_pre */
+	0xf510f7f0,
+	0xf5069221,
+	0xf4062b21,
+/* 0x085a: ctx_xfer_pre_load */
+	0xf7f01c11,
+	0x5121f502,
+	0x6021f506,
+	0x7221f506,
 	0xf5f4bd06,
-	0xf4065721,
-	0x01981011,
-	0x0511fd80,
-	0xf5070bf4,
-/* 0x092b: ctx_xfer_no_post_mmio */
-	0xf507df21,
-/* 0x092f: ctx_xfer_done */
-	0xf8064921,
-	0x00000000,
-	0x00000000,
+	0xf5065121,
+/* 0x0873: ctx_xfer_exec */
+	0x9806b221,
+	0x27f11601,
+	0x24b60414,
+	0x0020d006,
+	0xa500e7f1,
+	0xb941e3f0,
+	0x21f4021f,
+	0x04e0b68d,
+	0xf001fcf0,
+	0x24b6022c,
+	0x05f2fd01,
+	0xf18d21f4,
+	0xf04afc17,
+	0x27f00213,
+	0x0012d00c,
+	0x021521f5,
+	0x47fc27f1,
+	0xd00223f0,
+	0x2cf00020,
+	0x0320b601,
+	0xf00012d0,
+	0xa5f001ac,
+	0x00b7f006,
+	0x98000c98,
+	0xe7f0010d,
+	0x6621f500,
+	0x08a7f001,
+	0x010921f5,
+	0x021521f5,
+	0xf02201f4,
+	0x21f40ca7,
+	0x1017f1c9,
+	0x0614b60a,
+	0xd00527f0,
+/* 0x08fa: ctx_xfer_post_save_wait */
+	0x12cf0012,
+	0x0522fd00,
+	0xf4fa1bf4,
+/* 0x0906: ctx_xfer_post */
+	0xf7f03202,
+	0x5121f502,
+	0xf5f4bd06,
+	0xf5069221,
+	0xf5023421,
+	0xbd066021,
+	0x5121f5f4,
+	0x1011f406,
+	0xfd400198,
+	0x0bf40511,
+	0xe521f507,
+/* 0x0931: ctx_xfer_no_post_mmio */
+	0x4321f507,
+/* 0x0935: ctx_xfer_done */
+	0x0000f806,
 	0x00000000,
 	0x00000000,
 	0x00000000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#define CHIPSET GF117
+#include "macros.fuc"
+
+.section #nvd7_grhub_data
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "hub.fuc"
+#undef INCLUDE_DATA
+
+.section #nvd7_grhub_code
+#define INCLUDE_CODE
+bra #init
+#include "com.fuc"
+#include "hub.fuc"
+.align 256
+#undef INCLUDE_CODE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,921 @@
+uint32_t nvd7_grhub_data[] = {
+/* 0x0000: hub_mmio_list_head */
+	0x00000300,
+/* 0x0004: hub_mmio_list_tail */
+	0x00000304,
+/* 0x0008: gpc_count */
+	0x00000000,
+/* 0x000c: rop_count */
+	0x00000000,
+/* 0x0010: cmd_queue */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0058: ctx_current */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0100: chan_data */
+/* 0x0100: chan_mmio_count */
+	0x00000000,
+/* 0x0104: chan_mmio_address */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0200: xfer_data */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0300: hub_mmio_list_base */
+	0x0417e91c,
+};
+
+uint32_t nvd7_grhub_code[] = {
+	0x031b0ef5,
+/* 0x0004: queue_put */
+	0x9800d898,
+	0x86f001d9,
+	0x0489b808,
+	0xf00c1bf4,
+	0x21f502f7,
+	0x00f802fe,
+/* 0x001c: queue_put_next */
+	0xb60798c4,
+	0x8dbb0384,
+	0x0880b600,
+	0x80008e80,
+	0x90b6018f,
+	0x0f94f001,
+	0xf801d980,
+/* 0x0039: queue_get */
+	0x0131f400,
+	0x9800d898,
+	0x89b801d9,
+	0x210bf404,
+	0xb60789c4,
+	0x9dbb0394,
+	0x0890b600,
+	0x98009e98,
+	0x80b6019f,
+	0x0f84f001,
+	0xf400d880,
+/* 0x0066: queue_get_done */
+	0x00f80132,
+/* 0x0068: nv_rd32 */
+	0x0728b7f1,
+	0xb906b4b6,
+	0xc9f002ec,
+	0x00bcd01f,
+/* 0x0078: nv_rd32_wait */
+	0xc800bccf,
+	0x1bf41fcc,
+	0x06a7f0fa,
+	0x010921f5,
+	0xf840bfcf,
+/* 0x008d: nv_wr32 */
+	0x28b7f100,
+	0x06b4b607,
+	0xb980bfd0,
+	0xc9f002ec,
+	0x1ec9f01f,
+/* 0x00a3: nv_wr32_wait */
+	0xcf00bcd0,
+	0xccc800bc,
+	0xfa1bf41f,
+/* 0x00ae: watchdog_reset */
+	0x87f100f8,
+	0x84b60430,
+	0x1ff9f006,
+	0xf8008fd0,
+/* 0x00bd: watchdog_clear */
+	0x3087f100,
+	0x0684b604,
+	0xf80080d0,
+/* 0x00c9: wait_donez */
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x07f104bd,
+	0x03f00600,
+	0x000ad002,
+/* 0x00e6: wait_donez_ne */
+	0x87f104bd,
+	0x83f00000,
+	0x0088cf01,
+	0xf4888aff,
+	0x94bdf31b,
+	0xf10099f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0109: wait_doneo */
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x87f104bd,
+	0x84b60818,
+	0x008ad006,
+/* 0x0124: wait_doneo_e */
+	0x040087f1,
+	0xcf0684b6,
+	0x8aff0088,
+	0xf30bf488,
+	0x99f094bd,
+	0x0007f100,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x0147: mmctx_size */
+	0xbd00f804,
+/* 0x0149: nv_mmctx_size_loop */
+	0x00e89894,
+	0xb61a85b6,
+	0x84b60180,
+	0x0098bb02,
+	0xb804e0b6,
+	0x1bf404ef,
+	0x029fb9eb,
+/* 0x0166: mmctx_xfer */
+	0x94bd00f8,
+	0xf10199f0,
+	0xf00f0007,
+	0x09d00203,
+	0xf104bd00,
+	0xb6071087,
+	0x94bd0684,
+	0xf405bbfd,
+	0x8bd0090b,
+	0x0099f000,
+/* 0x018c: mmctx_base_disabled */
+	0xf405eefd,
+	0x8ed00c0b,
+	0xc08fd080,
+/* 0x019b: mmctx_multi_disabled */
+	0xb70199f0,
+	0xc8010080,
+	0xb4b600ab,
+	0x0cb9f010,
+	0xb601aec8,
+	0xbefd11e4,
+	0x008bd005,
+/* 0x01b4: mmctx_exec_loop */
+/* 0x01b4: mmctx_wait_free */
+	0xf0008ecf,
+	0x0bf41fe4,
+	0x00ce98fa,
+	0xd005e9fd,
+	0xc0b6c08e,
+	0x04cdb804,
+	0xc8e81bf4,
+	0x1bf402ab,
+/* 0x01d5: mmctx_fini_wait */
+	0x008bcf18,
+	0xb01fb4f0,
+	0x1bf410b4,
+	0x02a7f0f7,
+	0xf4c921f4,
+/* 0x01ea: mmctx_stop */
+	0xabc81b0e,
+	0x10b4b600,
+	0xf00cb9f0,
+	0x8bd012b9,
+/* 0x01f9: mmctx_stop_wait */
+	0x008bcf00,
+	0xf412bbc8,
+/* 0x0202: mmctx_done */
+	0x94bdfa1b,
+	0xf10199f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0215: strand_wait */
+	0xf0a0f900,
+	0x21f402a7,
+	0xf8a0fcc9,
+/* 0x0221: strand_pre */
+	0xfc87f100,
+	0x0283f04a,
+	0xd00c97f0,
+	0x21f50089,
+	0x00f80215,
+/* 0x0234: strand_post */
+	0x4afc87f1,
+	0xf00283f0,
+	0x89d00d97,
+	0x1521f500,
+/* 0x0247: strand_set */
+	0xf100f802,
+	0xf04ffca7,
+	0xaba202a3,
+	0xc7f00500,
+	0x00acd00f,
+	0xd00bc7f0,
+	0x21f500bc,
+	0xaed00215,
+	0x0ac7f000,
+	0xf500bcd0,
+	0xf8021521,
+/* 0x0271: strand_ctx_init */
+	0xf094bd00,
+	0x07f10399,
+	0x03f00f00,
+	0x0009d002,
+	0x21f504bd,
+	0xe7f00221,
+	0x4721f503,
+	0xfca7f102,
+	0x02a3f046,
+	0x0400aba0,
+	0xf040a0d0,
+	0xbcd001c7,
+	0x1521f500,
+	0x010c9202,
+	0xf000acd0,
+	0xbcd002c7,
+	0x1521f500,
+	0x3421f502,
+	0x8087f102,
+	0x0684b608,
+	0xb70089cf,
+	0x95220080,
+/* 0x02ca: ctx_init_strand_loop */
+	0x8ed008fe,
+	0x408ed000,
+	0xb6808acf,
+	0xa0b606a5,
+	0x00eabb01,
+	0xb60480b6,
+	0x1bf40192,
+	0x08e4b6e8,
+	0xbdf2efbc,
+	0x0399f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+/* 0x02fe: error */
+	0x07f100f8,
+	0x03f00500,
+	0x000fd002,
+	0xf7f004bd,
+	0x0007f101,
+	0x0303f007,
+	0xbd000fd0,
+/* 0x031b: init */
+	0xbd00f804,
+	0x0004fe04,
+	0xf10007fe,
+	0xf0120017,
+	0x12d00227,
+	0xb117f100,
+	0x0010fe05,
+	0x040017f1,
+	0xf1c010d0,
+	0xb6040437,
+	0x27f10634,
+	0x32d02003,
+	0x0427f100,
+	0x0132d020,
+	0x200b27f1,
+	0xf10232d0,
+	0xd0200c27,
+	0x27f10732,
+	0x24b60c24,
+	0x0003b906,
+	0xf10023d0,
+	0xf0870427,
+	0x12d00023,
+	0x0012b700,
+	0x0427f001,
+	0xf40012d0,
+	0xe7f11031,
+	0xe3f09604,
+	0x6821f440,
+	0x8090f1c7,
+	0xf4f00301,
+	0x020f801f,
+	0xbb0117f0,
+	0x12b6041f,
+	0x0c27f101,
+	0x0624b604,
+	0xd00021d0,
+	0x17f14021,
+	0x0e980100,
+	0x010f9800,
+	0x014721f5,
+	0x070037f1,
+	0x950634b6,
+	0x34d00814,
+	0x4034d000,
+	0x130030b7,
+	0xb6001fbb,
+	0x3fd002f5,
+	0x0815b600,
+	0xb60110b6,
+	0x1fb90814,
+	0x7121f502,
+	0x001fbb02,
+	0xf1020398,
+	0xf0200047,
+/* 0x03f6: init_gpc */
+	0x4ea05043,
+	0x1fb90804,
+	0x8d21f402,
+	0x010c4ea0,
+	0x21f4f4bd,
+	0x044ea08d,
+	0x8d21f401,
+	0x01004ea0,
+	0xf402f7f0,
+	0x4ea08d21,
+/* 0x041e: init_gpc_wait */
+	0x21f40800,
+	0x1fffc868,
+	0xa0fa0bf4,
+	0xf408044e,
+	0x1fbb6821,
+	0x0040b700,
+	0x0132b680,
+	0xf1be1bf4,
+	0xf0010007,
+	0x01d00203,
+	0xbd04bd00,
+	0x1f19f014,
+	0x080007f1,
+	0xd00203f0,
+	0x04bd0001,
+/* 0x0458: main */
+	0xf40031f4,
+	0xd7f00028,
+	0x3921f410,
+	0xb1f401f4,
+	0xf54001e4,
+	0xbd00de1b,
+	0x0499f094,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x0b0017f1,
+	0xcf0614b6,
+	0x11cf4012,
+	0x1f13c800,
+	0x00870bf5,
+	0xf41f23c8,
+	0x20f9620b,
+	0xbd0212b9,
+	0x0799f094,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0xf40132f4,
+	0x21f50231,
+	0x94bd082f,
+	0xf10799f0,
+	0xf0170007,
+	0x09d00203,
+	0xfc04bd00,
+	0xf094bd20,
+	0x07f10699,
+	0x03f00f00,
+	0x0009d002,
+	0x31f404bd,
+	0x2f21f501,
+	0xf094bd08,
+	0x07f10699,
+	0x03f01700,
+	0x0009d002,
+	0x0ef404bd,
+/* 0x04f9: chsw_prev_no_next */
+	0xb920f931,
+	0x32f40212,
+	0x0232f401,
+	0x082f21f5,
+	0x17f120fc,
+	0x14b60b00,
+	0x0012d006,
+/* 0x0517: chsw_no_prev */
+	0xc8130ef4,
+	0x0bf41f23,
+	0x0131f40d,
+	0xf50232f4,
+/* 0x0527: chsw_done */
+	0xf1082f21,
+	0xb60b0c17,
+	0x27f00614,
+	0x0012d001,
+	0x99f094bd,
+	0x0007f104,
+	0x0203f017,
+	0xbd0009d0,
+	0x130ef504,
+/* 0x0549: main_not_ctx_switch */
+	0x01e4b0ff,
+	0xb90d1bf4,
+	0x21f502f2,
+	0x0ef407bb,
+/* 0x0559: main_not_ctx_chan */
+	0x02e4b046,
+	0xbd321bf4,
+	0x0799f094,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0xf40132f4,
+	0x21f50232,
+	0x94bd082f,
+	0xf10799f0,
+	0xf0170007,
+	0x09d00203,
+	0xf404bd00,
+/* 0x058e: main_not_ctx_save */
+	0xef94110e,
+	0x01f5f010,
+	0x02fe21f5,
+	0xfec00ef5,
+/* 0x059c: main_done */
+	0x29f024bd,
+	0x0007f11f,
+	0x0203f008,
+	0xbd0002d0,
+	0xab0ef504,
+/* 0x05b1: ih */
+	0xfe80f9fe,
+	0x80f90188,
+	0xa0f990f9,
+	0xd0f9b0f9,
+	0xf0f9e0f9,
+	0x0acf04bd,
+	0x04abc480,
+	0xf11d0bf4,
+	0xf01900b7,
+	0xbecf10d7,
+	0x00bfcf40,
+	0xb70421f4,
+	0xf00400b0,
+	0xbed001e7,
+/* 0x05e9: ih_no_fifo */
+	0x00abe400,
+	0x0d0bf401,
+	0xf110d7f0,
+	0xf44001e7,
+/* 0x05fa: ih_no_ctxsw */
+	0xb7f10421,
+	0xb0bd0104,
+	0xf4b4abff,
+	0xa7f10d0b,
+	0xa4b60c1c,
+	0x00abd006,
+/* 0x0610: ih_no_other */
+	0xfc400ad0,
+	0xfce0fcf0,
+	0xfcb0fcd0,
+	0xfc90fca0,
+	0x0088fe80,
+	0x32f480fc,
+/* 0x062b: ctx_4160s */
+	0xf101f800,
+	0xf04160e7,
+	0xf7f040e3,
+	0x8d21f401,
+/* 0x0638: ctx_4160s_wait */
+	0xc86821f4,
+	0x0bf404ff,
+/* 0x0643: ctx_4160c */
+	0xf100f8fa,
+	0xf04160e7,
+	0xf4bd40e3,
+	0xf88d21f4,
+/* 0x0651: ctx_4170s */
+	0x70e7f100,
+	0x40e3f041,
+	0xf410f5f0,
+	0x00f88d21,
+/* 0x0660: ctx_4170w */
+	0x4170e7f1,
+	0xf440e3f0,
+	0xf4f06821,
+	0xf31bf410,
+/* 0x0672: ctx_redswitch */
+	0xe7f100f8,
+	0xe4b60614,
+	0x70f7f106,
+	0x00efd002,
+/* 0x0683: ctx_redswitch_delay */
+	0xb608f7f0,
+	0x1bf401f2,
+	0x70f7f1fd,
+	0x00efd007,
+/* 0x0692: ctx_86c */
+	0xe7f100f8,
+	0xe4b6086c,
+	0x00efd006,
+	0x8a14e7f1,
+	0xf440e3f0,
+	0xe7f18d21,
+	0xe3f0a86c,
+	0x8d21f441,
+/* 0x06b2: ctx_load */
+	0x94bd00f8,
+	0xf10599f0,
+	0xf00f0007,
+	0x09d00203,
+	0xf004bd00,
+	0x21f40ca7,
+	0x2417f1c9,
+	0x0614b60a,
+	0xf10010d0,
+	0xb60b0037,
+	0x32d00634,
+	0x0c17f140,
+	0x0614b60a,
+	0xd00747f0,
+	0x14d00012,
+/* 0x06ed: ctx_chan_wait_0 */
+	0x4014cf40,
+	0xf41f44f0,
+	0x32d0fa1b,
+	0x000bfe00,
+	0xb61f2af0,
+	0x20b60424,
+	0xf094bd02,
+	0x07f10899,
+	0x03f00f00,
+	0x0009d002,
+	0x17f104bd,
+	0x14b60a04,
+	0x0012d006,
+	0x0a2017f1,
+	0xf00614b6,
+	0x23f10227,
+	0x12d08000,
+	0x1017f000,
+	0x020027f1,
+	0xfa0223f0,
+	0x03f80512,
+	0x99f094bd,
+	0x0007f108,
+	0x0203f017,
+	0xbd0009d0,
+	0x81019804,
+	0x981814b6,
+	0x25b68002,
+	0x0512fd08,
+	0xbd160180,
+	0x0999f094,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x0a0427f1,
+	0xd00624b6,
+	0x27f00021,
+	0x2017f101,
+	0x0614b60a,
+	0xf10012d0,
+	0xf0010017,
+	0x01fa0613,
+	0xbd03f805,
+	0x0999f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x99f094bd,
+	0x0007f105,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x07bb: ctx_chan */
+	0xf500f804,
+	0xf5062b21,
+	0xf006b221,
+	0x21f40ca7,
+	0x1017f1c9,
+	0x0614b60a,
+	0xd00527f0,
+/* 0x07d6: ctx_chan_wait */
+	0x12cf0012,
+	0x0522fd00,
+	0xf5fa1bf4,
+	0xf8064321,
+/* 0x07e5: ctx_mmio_exec */
+	0x41039800,
+	0x0a0427f1,
+	0xd00624b6,
+	0x34bd0023,
+/* 0x07f4: ctx_mmio_loop */
+	0xf4ff34c4,
+	0x57f10f1b,
+	0x53f00200,
+	0x0535fa06,
+/* 0x0806: ctx_mmio_pull */
+	0x4e9803f8,
+	0x814f9880,
+	0xb68d21f4,
+	0x12b60830,
+	0xdf1bf401,
+/* 0x0818: ctx_mmio_done */
+	0xd0160398,
+	0x00800023,
+	0x0017f140,
+	0x0613f001,
+	0xf80601fa,
+/* 0x082f: ctx_xfer */
+	0xf100f803,
+	0xb60c00f7,
+	0xe7f006f4,
+	0x80fed004,
+/* 0x083c: ctx_xfer_idle */
+	0xf100fecf,
+	0xf42000e4,
+	0x11f4f91b,
+	0x1102f406,
+/* 0x084c: ctx_xfer_pre */
+	0xf510f7f0,
+	0xf5069221,
+	0xf4062b21,
+/* 0x085a: ctx_xfer_pre_load */
+	0xf7f01c11,
+	0x5121f502,
+	0x6021f506,
+	0x7221f506,
+	0xf5f4bd06,
+	0xf5065121,
+/* 0x0873: ctx_xfer_exec */
+	0x9806b221,
+	0x27f11601,
+	0x24b60414,
+	0x0020d006,
+	0xa500e7f1,
+	0xb941e3f0,
+	0x21f4021f,
+	0x04e0b68d,
+	0xf001fcf0,
+	0x24b6022c,
+	0x05f2fd01,
+	0xf18d21f4,
+	0xf04afc17,
+	0x27f00213,
+	0x0012d00c,
+	0x021521f5,
+	0x47fc27f1,
+	0xd00223f0,
+	0x2cf00020,
+	0x0320b601,
+	0xf00012d0,
+	0xa5f001ac,
+	0x00b7f006,
+	0x98000c98,
+	0xe7f0010d,
+	0x6621f500,
+	0x08a7f001,
+	0x010921f5,
+	0x021521f5,
+	0xf02201f4,
+	0x21f40ca7,
+	0x1017f1c9,
+	0x0614b60a,
+	0xd00527f0,
+/* 0x08fa: ctx_xfer_post_save_wait */
+	0x12cf0012,
+	0x0522fd00,
+	0xf4fa1bf4,
+/* 0x0906: ctx_xfer_post */
+	0xf7f03202,
+	0x5121f502,
+	0xf5f4bd06,
+	0xf5069221,
+	0xf5023421,
+	0xbd066021,
+	0x5121f5f4,
+	0x1011f406,
+	0xfd400198,
+	0x0bf40511,
+	0xe521f507,
+/* 0x0931: ctx_xfer_no_post_mmio */
+	0x4321f507,
+/* 0x0935: ctx_xfer_done */
+	0x0000f806,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,5 @@
-/* fuc microcode for nve0 PGRAPH/HUB
- *
- * Copyright 2011 Red Hat Inc.
+/*
+ * Copyright 2013 Red Hat Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -20,774 +19,22 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-/* To build:
- *    m4 nve0_grhub.fuc | envyas -a -w -m fuc -V nva3 -o nve0_grhub.fuc.h
- */
+#define CHIPSET GK100
+#include "macros.fuc"
 
 .section #nve0_grhub_data
-include(`nve0.fuc')
-gpc_count:		.b32 0
-rop_count:		.b32 0
-cmd_queue:		queue_init
-hub_mmio_list_head:	.b32 0
-hub_mmio_list_tail:	.b32 0
-
-ctx_current:		.b32 0
-
-chipsets:
-.b8  0xe4 0 0 0
-.b16 #nve4_hub_mmio_head
-.b16 #nve4_hub_mmio_tail
-.b8  0xe7 0 0 0
-.b16 #nve4_hub_mmio_head
-.b16 #nve4_hub_mmio_tail
-.b8  0xe6 0 0 0
-.b16 #nve4_hub_mmio_head
-.b16 #nve4_hub_mmio_tail
-.b8  0 0 0 0
-
-nve4_hub_mmio_head:
-mmctx_data(0x17e91c, 2)
-mmctx_data(0x400204, 2)
-mmctx_data(0x404010, 7)
-mmctx_data(0x4040a8, 9)
-mmctx_data(0x4040d0, 7)
-mmctx_data(0x4040f8, 1)
-mmctx_data(0x404130, 3)
-mmctx_data(0x404150, 3)
-mmctx_data(0x404164, 1)
-mmctx_data(0x4041a0, 4)
-mmctx_data(0x404200, 4)
-mmctx_data(0x404404, 14)
-mmctx_data(0x404460, 4)
-mmctx_data(0x404480, 1)
-mmctx_data(0x404498, 1)
-mmctx_data(0x404604, 4)
-mmctx_data(0x404618, 4)
-mmctx_data(0x40462c, 2)
-mmctx_data(0x404640, 1)
-mmctx_data(0x404654, 1)
-mmctx_data(0x404660, 1)
-mmctx_data(0x404678, 19)
-mmctx_data(0x4046c8, 3)
-mmctx_data(0x404700, 3)
-mmctx_data(0x404718, 10)
-mmctx_data(0x404744, 2)
-mmctx_data(0x404754, 1)
-mmctx_data(0x405800, 1)
-mmctx_data(0x405830, 3)
-mmctx_data(0x405854, 1)
-mmctx_data(0x405870, 4)
-mmctx_data(0x405a00, 2)
-mmctx_data(0x405a18, 1)
-mmctx_data(0x405b00, 1)
-mmctx_data(0x405b10, 1)
-mmctx_data(0x406020, 1)
-mmctx_data(0x406028, 4)
-mmctx_data(0x4064a8, 2)
-mmctx_data(0x4064b4, 2)
-mmctx_data(0x4064c0, 12)
-mmctx_data(0x4064fc, 1)
-mmctx_data(0x407040, 1)
-mmctx_data(0x407804, 1)
-mmctx_data(0x40780c, 6)
-mmctx_data(0x4078bc, 1)
-mmctx_data(0x408000, 7)
-mmctx_data(0x408064, 1)
-mmctx_data(0x408800, 3)
-mmctx_data(0x408840, 1)
-mmctx_data(0x408900, 3)
-mmctx_data(0x408980, 1)
-nve4_hub_mmio_tail:
-
-.align 256
-chan_data:
-chan_mmio_count:	.b32 0
-chan_mmio_address:	.b32 0
-
-.align 256
-xfer_data: 		.b32 0
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "hub.fuc"
+#undef INCLUDE_DATA
 
 .section #nve0_grhub_code
+#define INCLUDE_CODE
 bra #init
-define(`include_code')
-include(`nve0.fuc')
-
-// reports an exception to the host
-//
-// In: $r15 error code (see nve0.fuc)
-//
-error:
-	push $r14
-	mov $r14 0x814
-	shl b32 $r14 6
-	iowr I[$r14 + 0x000] $r15	// CC_SCRATCH[5] = error code
-	mov $r14 0xc1c
-	shl b32 $r14 6
-	mov $r15 1
-	iowr I[$r14 + 0x000] $r15	// INTR_UP_SET
-	pop $r14
-	ret
-
-// HUB fuc initialisation, executed by triggering ucode start, will
-// fall through to main loop after completion.
-//
-// Input:
-//   CC_SCRATCH[0]: chipset (PMC_BOOT_0 read returns 0x0bad0bad... sigh)
-//
-// Output:
-//   CC_SCRATCH[0]:
-//	     31:31: set to signal completion
-//   CC_SCRATCH[1]:
-//	      31:0: total PGRAPH context size
-//
-init:
-	clear b32 $r0
-	mov $sp $r0
-	mov $xdbase $r0
-
-	// enable fifo access
-	mov $r1 0x1200
-	mov $r2 2
-	iowr I[$r1 + 0x000] $r2	// FIFO_ENABLE
-
-	// setup i0 handler, and route all interrupts to it
-	mov $r1 #ih
-	mov $iv0 $r1
-	mov $r1 0x400
-	iowr I[$r1 + 0x300] $r0	// INTR_DISPATCH
-
-	// route HUB_CHANNEL_SWITCH to fuc interrupt 8
-	mov $r3 0x404
-	shl b32 $r3 6
-	mov $r2 0x2003		// { HUB_CHANNEL_SWITCH, ZERO } -> intr 8
-	iowr I[$r3 + 0x000] $r2
-
-	// not sure what these are, route them because NVIDIA does, and
-	// the IRQ handler will signal the host if we ever get one.. we
-	// may find out if/why we need to handle these if so..
-	//
-	mov $r2 0x2004
-	iowr I[$r3 + 0x004] $r2 // { 0x04, ZERO } -> intr 9
-	mov $r2 0x200b
-	iowr I[$r3 + 0x008] $r2 // { 0x0b, ZERO } -> intr 10
-	mov $r2 0x200c
-	iowr I[$r3 + 0x01c] $r2 // { 0x0c, ZERO } -> intr 15
-
-	// enable all INTR_UP interrupts
-	mov $r2 0xc24
-	shl b32 $r2 6
-	not b32 $r3 $r0
-	iowr I[$r2] $r3
-
-	// enable fifo, ctxsw, 9, 10, 15 interrupts
-	mov $r2 -0x78fc		// 0x8704
-	sethi $r2 0
-	iowr I[$r1 + 0x000] $r2	// INTR_EN_SET
-
-	// fifo level triggered, rest edge
-	sub b32 $r1 0x100
-	mov $r2 4
-	iowr I[$r1] $r2
-
-	// enable interrupts
-	bset $flags ie0
-
-	// fetch enabled GPC/ROP counts
-	mov $r14 -0x69fc	// 0x409604
-	sethi $r14 0x400000
-	call #nv_rd32
-	extr $r1 $r15 16:20
-	st b32 D[$r0 + #rop_count] $r1
-	and $r15 0x1f
-	st b32 D[$r0 + #gpc_count] $r15
-
-	// set BAR_REQMASK to GPC mask
-	mov $r1 1
-	shl b32 $r1 $r15
-	sub b32 $r1 1
-	mov $r2 0x40c
-	shl b32 $r2 6
-	iowr I[$r2 + 0x000] $r1
-	iowr I[$r2 + 0x100] $r1
-
-	// find context data for this chipset
-	mov $r2 0x800
-	shl b32 $r2 6
-	iord $r2 I[$r2 + 0x000]		// CC_SCRATCH[0]
-	mov $r15 #chipsets - 8
-	init_find_chipset:
-		add b32 $r15 8
-		ld b32 $r3 D[$r15 + 0x00]
-		cmpu b32 $r3 $r2
-		bra e #init_context
-		cmpu b32 $r3 0
-		bra ne #init_find_chipset
-		// unknown chipset
-		ret
-
-	// context size calculation, reserve first 256 bytes for use by fuc
-	init_context:
-	mov $r1 256
-
-	// calculate size of mmio context data
-	ld b16 $r14 D[$r15 + 4]
-	ld b16 $r15 D[$r15 + 6]
-	sethi $r14 0
-	st b32 D[$r0 + #hub_mmio_list_head] $r14
-	st b32 D[$r0 + #hub_mmio_list_tail] $r15
-	call #mmctx_size
-
-	// set mmctx base addresses now so we don't have to do it later,
-	// they don't (currently) ever change
-	mov $r3 0x700
-	shl b32 $r3 6
-	shr b32 $r4 $r1 8
-	iowr I[$r3 + 0x000] $r4		// MMCTX_SAVE_SWBASE
-	iowr I[$r3 + 0x100] $r4		// MMCTX_LOAD_SWBASE
-	add b32 $r3 0x1300
-	add b32 $r1 $r15
-	shr b32 $r15 2
-	iowr I[$r3 + 0x000] $r15	// MMCTX_LOAD_COUNT, wtf for?!?
-
-	// strands, base offset needs to be aligned to 256 bytes
-	shr b32 $r1 8
-	add b32 $r1 1
-	shl b32 $r1 8
-	mov b32 $r15 $r1
-	call #strand_ctx_init
-	add b32 $r1 $r15
-
-	// initialise each GPC in sequence by passing in the offset of its
-	// context data in GPCn_CC_SCRATCH[1], and starting its FUC (which
-	// has previously been uploaded by the host) running.
-	//
-	// the GPC fuc init sequence will set GPCn_CC_SCRATCH[0] bit 31
-	// when it has completed, and return the size of its context data
-	// in GPCn_CC_SCRATCH[1]
-	//
-	ld b32 $r3 D[$r0 + #gpc_count]
-	mov $r4 0x2000
-	sethi $r4 0x500000
-	init_gpc:
-		// setup, and start GPC ucode running
-		add b32 $r14 $r4 0x804
-		mov b32 $r15 $r1
-		call #nv_wr32			// CC_SCRATCH[1] = ctx offset
-		add b32 $r14 $r4 0x800
-		mov b32 $r15 $r2
-		call #nv_wr32			// CC_SCRATCH[0] = chipset
-		add b32 $r14 $r4 0x10c
-		clear b32 $r15
-		call #nv_wr32
-		add b32 $r14 $r4 0x104
-		call #nv_wr32			// ENTRY
-		add b32 $r14 $r4 0x100
-		mov $r15 2			// CTRL_START_TRIGGER
-		call #nv_wr32			// CTRL
-
-		// wait for it to complete, and adjust context size
-		add b32 $r14 $r4 0x800
-		init_gpc_wait:
-			call #nv_rd32
-			xbit $r15 $r15 31
-			bra e #init_gpc_wait
-		add b32 $r14 $r4 0x804
-		call #nv_rd32
-		add b32 $r1 $r15
-
-		// next!
-		add b32 $r4 0x8000
-		sub b32 $r3 1
-		bra ne #init_gpc
-
-	// save context size, and tell host we're ready
-	mov $r2 0x800
-	shl b32 $r2 6
-	iowr I[$r2 + 0x100] $r1		// CC_SCRATCH[1]  = context size
-	add b32 $r2 0x800
-	clear b32 $r1
-	bset $r1 31
-	iowr I[$r2 + 0x000] $r1		// CC_SCRATCH[0] |= 0x80000000
-
-// Main program loop, very simple, sleeps until woken up by the interrupt
-// handler, pulls a command from the queue and executes its handler
-//
-main:
-	// sleep until we have something to do
-	bset $flags $p0
-	sleep $p0
-	mov $r13 #cmd_queue
-	call #queue_get
-	bra $p1 #main
-
-	// context switch, requested by GPU?
-	cmpu b32 $r14 0x4001
-	bra ne #main_not_ctx_switch
-		trace_set(T_AUTO)
-		mov $r1 0xb00
-		shl b32 $r1 6
-		iord $r2 I[$r1 + 0x100]		// CHAN_NEXT
-		iord $r1 I[$r1 + 0x000]		// CHAN_CUR
-
-		xbit $r3 $r1 31
-		bra e #chsw_no_prev
-			xbit $r3 $r2 31
-			bra e #chsw_prev_no_next
-				push $r2
-				mov b32 $r2 $r1
-				trace_set(T_SAVE)
-				bclr $flags $p1
-				bset $flags $p2
-				call #ctx_xfer
-				trace_clr(T_SAVE);
-				pop $r2
-				trace_set(T_LOAD);
-				bset $flags $p1
-				call #ctx_xfer
-				trace_clr(T_LOAD);
-				bra #chsw_done
-			chsw_prev_no_next:
-				push $r2
-				mov b32 $r2 $r1
-				bclr $flags $p1
-				bclr $flags $p2
-				call #ctx_xfer
-				pop $r2
-				mov $r1 0xb00
-				shl b32 $r1 6
-				iowr I[$r1] $r2
-				bra #chsw_done
-		chsw_no_prev:
-			xbit $r3 $r2 31
-			bra e #chsw_done
-				bset $flags $p1
-				bclr $flags $p2
-				call #ctx_xfer
-
-		// ack the context switch request
-		chsw_done:
-		mov $r1 0xb0c
-		shl b32 $r1 6
-		mov $r2 1
-		iowr I[$r1 + 0x000] $r2		// 0x409b0c
-		trace_clr(T_AUTO)
-		bra #main
-
-	// request to set current channel? (*not* a context switch)
-	main_not_ctx_switch:
-	cmpu b32 $r14 0x0001
-	bra ne #main_not_ctx_chan
-		mov b32 $r2 $r15
-		call #ctx_chan
-		bra #main_done
-
-	// request to store current channel context?
-	main_not_ctx_chan:
-	cmpu b32 $r14 0x0002
-	bra ne #main_not_ctx_save
-		trace_set(T_SAVE)
-		bclr $flags $p1
-		bclr $flags $p2
-		call #ctx_xfer
-		trace_clr(T_SAVE)
-		bra #main_done
-
-	main_not_ctx_save:
-		shl b32 $r15 $r14 16
-		or $r15 E_BAD_COMMAND
-		call #error
-		bra #main
-
-	main_done:
-	mov $r1 0x820
-	shl b32 $r1 6
-	clear b32 $r2
-	bset $r2 31
-	iowr I[$r1 + 0x000] $r2		// CC_SCRATCH[0] |= 0x80000000
-	bra #main
-
-// interrupt handler
-ih:
-	push $r8
-	mov $r8 $flags
-	push $r8
-	push $r9
-	push $r10
-	push $r11
-	push $r13
-	push $r14
-	push $r15
-
-	// incoming fifo command?
-	iord $r10 I[$r0 + 0x200]	// INTR
-	and $r11 $r10 0x00000004
-	bra e #ih_no_fifo
-		// queue incoming fifo command for later processing
-		mov $r11 0x1900
-		mov $r13 #cmd_queue
-		iord $r14 I[$r11 + 0x100]	// FIFO_CMD
-		iord $r15 I[$r11 + 0x000]	// FIFO_DATA
-		call #queue_put
-		add b32 $r11 0x400
-		mov $r14 1
-		iowr I[$r11 + 0x000] $r14	// FIFO_ACK
-
-	// context switch request?
-	ih_no_fifo:
-	and $r11 $r10 0x00000100
-	bra e #ih_no_ctxsw
-		// enqueue a context switch for later processing
-		mov $r13 #cmd_queue
-		mov $r14 0x4001
-		call #queue_put
-
-	// anything we didn't handle, bring it to the host's attention
-	ih_no_ctxsw:
-	mov $r11 0x104
-	not b32 $r11
-	and $r11 $r10 $r11
-	bra e #ih_no_other
-		mov $r10 0xc1c
-		shl b32 $r10 6
-		iowr I[$r10] $r11	// INTR_UP_SET
-
-	// ack, and wake up main()
-	ih_no_other:
-	iowr I[$r0 + 0x100] $r10	// INTR_ACK
-
-	pop $r15
-	pop $r14
-	pop $r13
-	pop $r11
-	pop $r10
-	pop $r9
-	pop $r8
-	mov $flags $r8
-	pop $r8
-	bclr $flags $p0
-	iret
-
-// Again, not real sure
-//
-// In: $r15 value to set 0x404170 to
-//
-ctx_4170s:
-	mov $r14 0x4170
-	sethi $r14 0x400000
-	or $r15 0x10
-	call #nv_wr32
-	ret
-
-// Waits for a ctx_4170s() call to complete
-//
-ctx_4170w:
-	mov $r14 0x4170
-	sethi $r14 0x400000
-	call #nv_rd32
-	and $r15 0x10
-	bra ne #ctx_4170w
-	ret
-
-// Disables various things, waits a bit, and re-enables them..
-//
-// Not sure how exactly this helps, perhaps "ENABLE" is not such a
-// good description for the bits we turn off?  Anyways, without this,
-// funny things happen.
-//
-ctx_redswitch:
-	mov $r14 0x614
-	shl b32 $r14 6
-	mov $r15 0x270
-	iowr I[$r14] $r15	// HUB_RED_SWITCH = ENABLE_GPC, POWER_ALL
-	mov $r15 8
-	ctx_redswitch_delay:
-		sub b32 $r15 1
-		bra ne #ctx_redswitch_delay
-	mov $r15 0x770
-	iowr I[$r14] $r15	// HUB_RED_SWITCH = ENABLE_ALL, POWER_ALL
-	ret
-
-// Not a clue what this is for, except that unless the value is 0x10, the
-// strand context is saved (and presumably restored) incorrectly..
-//
-// In: $r15 value to set to (0x00/0x10 are used)
-//
-ctx_86c:
-	mov $r14 0x86c
-	shl b32 $r14 6
-	iowr I[$r14] $r15	// HUB(0x86c) = val
-	mov $r14 -0x75ec
-	sethi $r14 0x400000
-	call #nv_wr32		// ROP(0xa14) = val
-	mov $r14 -0x5794
-	sethi $r14 0x410000
-	call #nv_wr32		// GPC(0x86c) = val
-	ret
-
-// ctx_load - load's a channel's ctxctl data, and selects its vm
-//
-// In: $r2 channel address
-//
-ctx_load:
-	trace_set(T_CHAN)
-
-	// switch to channel, somewhat magic in parts..
-	mov $r10 12		// DONE_UNK12
-	call #wait_donez
-	mov $r1 0xa24
-	shl b32 $r1 6
-	iowr I[$r1 + 0x000] $r0	// 0x409a24
-	mov $r3 0xb00
-	shl b32 $r3 6
-	iowr I[$r3 + 0x100] $r2	// CHAN_NEXT
-	mov $r1 0xa0c
-	shl b32 $r1 6
-	mov $r4 7
-	iowr I[$r1 + 0x000] $r2 // MEM_CHAN
-	iowr I[$r1 + 0x100] $r4	// MEM_CMD
-	ctx_chan_wait_0:
-		iord $r4 I[$r1 + 0x100]
-		and $r4 0x1f
-		bra ne #ctx_chan_wait_0
-	iowr I[$r3 + 0x000] $r2	// CHAN_CUR
-
-	// load channel header, fetch PGRAPH context pointer
-	mov $xtargets $r0
-	bclr $r2 31
-	shl b32 $r2 4
-	add b32 $r2 2
-
-	trace_set(T_LCHAN)
-	mov $r1 0xa04
-	shl b32 $r1 6
-	iowr I[$r1 + 0x000] $r2		// MEM_BASE
-	mov $r1 0xa20
-	shl b32 $r1 6
-	mov $r2 0x0002
-	sethi $r2 0x80000000
-	iowr I[$r1 + 0x000] $r2		// MEM_TARGET = vram
-	mov $r1 0x10			// chan + 0x0210
-	mov $r2 #xfer_data
-	sethi $r2 0x00020000		// 16 bytes
-	xdld $r1 $r2
-	xdwait
-	trace_clr(T_LCHAN)
-
-	// update current context
-	ld b32 $r1 D[$r0 + #xfer_data + 4]
-	shl b32 $r1 24
-	ld b32 $r2 D[$r0 + #xfer_data + 0]
-	shr b32 $r2 8
-	or $r1 $r2
-	st b32 D[$r0 + #ctx_current] $r1
-
-	// set transfer base to start of context, and fetch context header
-	trace_set(T_LCTXH)
-	mov $r2 0xa04
-	shl b32 $r2 6
-	iowr I[$r2 + 0x000] $r1		// MEM_BASE
-	mov $r2 1
-	mov $r1 0xa20
-	shl b32 $r1 6
-	iowr I[$r1 + 0x000] $r2		// MEM_TARGET = vm
-	mov $r1 #chan_data
-	sethi $r1 0x00060000		// 256 bytes
-	xdld $r0 $r1
-	xdwait
-	trace_clr(T_LCTXH)
-
-	trace_clr(T_CHAN)
-	ret
-
-// ctx_chan - handler for HUB_SET_CHAN command, will set a channel as
-//            the active channel for ctxctl, but not actually transfer
-//            any context data.  intended for use only during initial
-//            context construction.
-//
-// In: $r2 channel address
-//
-ctx_chan:
-	call #ctx_load
-	mov $r10 12			// DONE_UNK12
-	call #wait_donez
-	mov $r1 0xa10
-	shl b32 $r1 6
-	mov $r2 5
-	iowr I[$r1 + 0x000] $r2		// MEM_CMD = 5 (???)
-	ctx_chan_wait:
-		iord $r2 I[$r1 + 0x000]
-		or $r2 $r2
-		bra ne #ctx_chan_wait
-	ret
-
-// Execute per-context state overrides list
-//
-// Only executed on the first load of a channel.  Might want to look into
-// removing this and having the host directly modify the channel's context
-// to change this state...  The nouveau DRM already builds this list as
-// it's definitely needed for NVIDIA's, so we may as well use it for now
-//
-// Input: $r1 mmio list length
-//
-ctx_mmio_exec:
-	// set transfer base to be the mmio list
-	ld b32 $r3 D[$r0 + #chan_mmio_address]
-	mov $r2 0xa04
-	shl b32 $r2 6
-	iowr I[$r2 + 0x000] $r3		// MEM_BASE
-
-	clear b32 $r3
-	ctx_mmio_loop:
-		// fetch next 256 bytes of mmio list if necessary
-		and $r4 $r3 0xff
-		bra ne #ctx_mmio_pull
-			mov $r5 #xfer_data
-			sethi $r5 0x00060000	// 256 bytes
-			xdld $r3 $r5
-			xdwait
-
-		// execute a single list entry
-		ctx_mmio_pull:
-		ld b32 $r14 D[$r4 + #xfer_data + 0x00]
-		ld b32 $r15 D[$r4 + #xfer_data + 0x04]
-		call #nv_wr32
-
-		// next!
-		add b32 $r3 8
-		sub b32 $r1 1
-		bra ne #ctx_mmio_loop
-
-	// set transfer base back to the current context
-	ctx_mmio_done:
-	ld b32 $r3 D[$r0 + #ctx_current]
-	iowr I[$r2 + 0x000] $r3		// MEM_BASE
-
-	// disable the mmio list now, we don't need/want to execute it again
-	st b32 D[$r0 + #chan_mmio_count] $r0
-	mov $r1 #chan_data
-	sethi $r1 0x00060000		// 256 bytes
-	xdst $r0 $r1
-	xdwait
-	ret
-
-// Transfer HUB context data between GPU and storage area
-//
-// In: $r2 channel address
-//     $p1 clear on save, set on load
-//     $p2 set if opposite direction done/will be done, so:
-//		on save it means: "a load will follow this save"
-//		on load it means: "a save preceeded this load"
-//
-ctx_xfer:
-	// according to mwk, some kind of wait for idle
-	mov $r15 0xc00
-	shl b32 $r15 6
-	mov $r14 4
-	iowr I[$r15 + 0x200] $r14
-	ctx_xfer_idle:
-		iord $r14 I[$r15 + 0x000]
-		and $r14 0x2000
-		bra ne #ctx_xfer_idle
-
-	bra not $p1 #ctx_xfer_pre
-	bra $p2 #ctx_xfer_pre_load
-	ctx_xfer_pre:
-		mov $r15 0x10
-		call #ctx_86c
-		bra not $p1 #ctx_xfer_exec
-
-	ctx_xfer_pre_load:
-		mov $r15 2
-		call #ctx_4170s
-		call #ctx_4170w
-		call #ctx_redswitch
-		clear b32 $r15
-		call #ctx_4170s
-		call #ctx_load
-
-	// fetch context pointer, and initiate xfer on all GPCs
-	ctx_xfer_exec:
-	ld b32 $r1 D[$r0 + #ctx_current]
-	mov $r2 0x414
-	shl b32 $r2 6
-	iowr I[$r2 + 0x000] $r0	// BAR_STATUS = reset
-	mov $r14 -0x5b00
-	sethi $r14 0x410000
-	mov b32 $r15 $r1
-	call #nv_wr32		// GPC_BCAST_WRCMD_DATA = ctx pointer
-	add b32 $r14 4
-	xbit $r15 $flags $p1
-	xbit $r2 $flags $p2
-	shl b32 $r2 1
-	or $r15 $r2
-	call #nv_wr32		// GPC_BCAST_WRCMD_CMD = GPC_XFER(type)
-
-	// strands
-	mov $r1 0x4afc
-	sethi $r1 0x20000
-	mov $r2 0xc
-	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x0c
-	call #strand_wait
-	mov $r2 0x47fc
-	sethi $r2 0x20000
-	iowr I[$r2] $r0		// STRAND_FIRST_GENE(0x3f) = 0x00
-	xbit $r2 $flags $p1
-	add b32 $r2 3
-	iowr I[$r1] $r2		// STRAND_CMD(0x3f) = 0x03/0x04 (SAVE/LOAD)
-
-	// mmio context
-	xbit $r10 $flags $p1	// direction
-	or $r10 6		// first, last
-	mov $r11 0		// base = 0
-	ld b32 $r12 D[$r0 + #hub_mmio_list_head]
-	ld b32 $r13 D[$r0 + #hub_mmio_list_tail]
-	mov $r14 0		// not multi
-	call #mmctx_xfer
-
-	// wait for GPCs to all complete
-	mov $r10 8		// DONE_BAR
-	call #wait_doneo
-
-	// wait for strand xfer to complete
-	call #strand_wait
-
-	// post-op
-	bra $p1 #ctx_xfer_post
-		mov $r10 12		// DONE_UNK12
-		call #wait_donez
-		mov $r1 0xa10
-		shl b32 $r1 6
-		mov $r2 5
-		iowr I[$r1] $r2		// MEM_CMD
-		ctx_xfer_post_save_wait:
-			iord $r2 I[$r1]
-			or $r2 $r2
-			bra ne #ctx_xfer_post_save_wait
-
-	bra $p2 #ctx_xfer_done
-	ctx_xfer_post:
-		mov $r15 2
-		call #ctx_4170s
-		clear b32 $r15
-		call #ctx_86c
-		call #strand_post
-		call #ctx_4170w
-		clear b32 $r15
-		call #ctx_4170s
-
-		bra not $p1 #ctx_xfer_no_post_mmio
-		ld b32 $r1 D[$r0 + #chan_mmio_count]
-		or $r1 $r1
-		bra e #ctx_xfer_no_post_mmio
-			call #ctx_mmio_exec
-
-		ctx_xfer_no_post_mmio:
-
-	ctx_xfer_done:
-	ret
-
+#include "com.fuc"
+#include "hub.fuc"
 .align 256
+#undef INCLUDE_CODE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,9 +1,13 @@
 uint32_t nve0_grhub_data[] = {
-/* 0x0000: gpc_count */
+/* 0x0000: hub_mmio_list_head */
+	0x00000300,
+/* 0x0004: hub_mmio_list_tail */
+	0x00000304,
+/* 0x0008: gpc_count */
 	0x00000000,
-/* 0x0004: rop_count */
+/* 0x000c: rop_count */
 	0x00000000,
-/* 0x0008: cmd_queue */
+/* 0x0010: cmd_queue */
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -22,73 +26,11 @@ uint32_t nve0_grhub_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
-/* 0x0050: hub_mmio_list_head */
+/* 0x0058: ctx_current */
 	0x00000000,
-/* 0x0054: hub_mmio_list_tail */
 	0x00000000,
-/* 0x0058: ctx_current */
 	0x00000000,
-/* 0x005c: chipsets */
-	0x000000e4,
-	0x01440078,
-	0x000000e7,
-	0x01440078,
-	0x000000e6,
-	0x01440078,
 	0x00000000,
-/* 0x0078: nve4_hub_mmio_head */
-	0x0417e91c,
-	0x04400204,
-	0x18404010,
-	0x204040a8,
-	0x184040d0,
-	0x004040f8,
-	0x08404130,
-	0x08404150,
-	0x00404164,
-	0x0c4041a0,
-	0x0c404200,
-	0x34404404,
-	0x0c404460,
-	0x00404480,
-	0x00404498,
-	0x0c404604,
-	0x0c404618,
-	0x0440462c,
-	0x00404640,
-	0x00404654,
-	0x00404660,
-	0x48404678,
-	0x084046c8,
-	0x08404700,
-	0x24404718,
-	0x04404744,
-	0x00404754,
-	0x00405800,
-	0x08405830,
-	0x00405854,
-	0x0c405870,
-	0x04405a00,
-	0x00405a18,
-	0x00405b00,
-	0x00405b10,
-	0x00406020,
-	0x0c406028,
-	0x044064a8,
-	0x044064b4,
-	0x2c4064c0,
-	0x004064fc,
-	0x00407040,
-	0x00407804,
-	0x1440780c,
-	0x004078bc,
-	0x18408000,
-	0x00408064,
-	0x08408800,
-	0x00408840,
-	0x08408900,
-	0x00408980,
-/* 0x0144: nve4_hub_mmio_tail */
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -127,7 +69,10 @@ uint32_t nve0_grhub_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
+/* 0x0100: chan_data */
+/* 0x0100: chan_mmio_count */
 	0x00000000,
+/* 0x0104: chan_mmio_address */
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -136,10 +81,7 @@ uint32_t nve0_grhub_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
-/* 0x0200: chan_data */
-/* 0x0200: chan_mmio_count */
 	0x00000000,
-/* 0x0204: chan_mmio_address */
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -194,6 +136,31 @@ uint32_t nve0_grhub_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
+/* 0x0200: xfer_data */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -203,19 +170,50 @@ uint32_t nve0_grhub_data[] = {
 	0x00000000,
 	0x00000000,
 	0x00000000,
-/* 0x0300: xfer_data */
 	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0300: hub_mmio_list_base */
+	0x0417e91c,
 };
 
 uint32_t nve0_grhub_code[] = {
-	0x03090ef5,
+	0x031b0ef5,
 /* 0x0004: queue_put */
 	0x9800d898,
 	0x86f001d9,
 	0x0489b808,
 	0xf00c1bf4,
 	0x21f502f7,
-	0x00f802ec,
+	0x00f802fe,
 /* 0x001c: queue_put_next */
 	0xb60798c4,
 	0x8dbb0384,
@@ -247,7 +245,7 @@ uint32_t nve0_grhub_code[] = {
 	0xc800bccf,
 	0x1bf41fcc,
 	0x06a7f0fa,
-	0x010321f5,
+	0x010921f5,
 	0xf840bfcf,
 /* 0x008d: nv_wr32 */
 	0x28b7f100,
@@ -269,63 +267,66 @@ uint32_t nve0_grhub_code[] = {
 	0x0684b604,
 	0xf80080d0,
 /* 0x00c9: wait_donez */
-	0x3c87f100,
-	0x0684b608,
-	0x99f094bd,
-	0x0089d000,
-	0x081887f1,
-	0xd00684b6,
-/* 0x00e2: wait_done_wait_donez */
-	0x87f1008a,
-	0x84b60400,
-	0x0088cf06,
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x07f104bd,
+	0x03f00600,
+	0x000ad002,
+/* 0x00e6: wait_donez_ne */
+	0x87f104bd,
+	0x83f00000,
+	0x0088cf01,
 	0xf4888aff,
-	0x87f1f31b,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00099,
-/* 0x0103: wait_doneo */
-	0xf100f800,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00099f0,
-	0x87f10089,
+	0x94bdf31b,
+	0xf10099f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0109: wait_doneo */
+	0xf094bd00,
+	0x07f10099,
+	0x03f00f00,
+	0x0009d002,
+	0x87f104bd,
 	0x84b60818,
 	0x008ad006,
-/* 0x011c: wait_done_wait_doneo */
+/* 0x0124: wait_doneo_e */
 	0x040087f1,
 	0xcf0684b6,
 	0x8aff0088,
 	0xf30bf488,
-	0x085c87f1,
-	0xbd0684b6,
-	0x0099f094,
-	0xf80089d0,
-/* 0x013d: mmctx_size */
-/* 0x013f: nv_mmctx_size_loop */
-	0x9894bd00,
-	0x85b600e8,
-	0x0180b61a,
-	0xbb0284b6,
-	0xe0b60098,
-	0x04efb804,
-	0xb9eb1bf4,
-	0x00f8029f,
-/* 0x015c: mmctx_xfer */
-	0x083c87f1,
-	0xbd0684b6,
-	0x0199f094,
-	0xf10089d0,
+	0x99f094bd,
+	0x0007f100,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x0147: mmctx_size */
+	0xbd00f804,
+/* 0x0149: nv_mmctx_size_loop */
+	0x00e89894,
+	0xb61a85b6,
+	0x84b60180,
+	0x0098bb02,
+	0xb804e0b6,
+	0x1bf404ef,
+	0x029fb9eb,
+/* 0x0166: mmctx_xfer */
+	0x94bd00f8,
+	0xf10199f0,
+	0xf00f0007,
+	0x09d00203,
+	0xf104bd00,
 	0xb6071087,
 	0x94bd0684,
 	0xf405bbfd,
 	0x8bd0090b,
 	0x0099f000,
-/* 0x0180: mmctx_base_disabled */
+/* 0x018c: mmctx_base_disabled */
 	0xf405eefd,
 	0x8ed00c0b,
 	0xc08fd080,
-/* 0x018f: mmctx_multi_disabled */
+/* 0x019b: mmctx_multi_disabled */
 	0xb70199f0,
 	0xc8010080,
 	0xb4b600ab,
@@ -333,8 +334,8 @@ uint32_t nve0_grhub_code[] = {
 	0xb601aec8,
 	0xbefd11e4,
 	0x008bd005,
-/* 0x01a8: mmctx_exec_loop */
-/* 0x01a8: mmctx_wait_free */
+/* 0x01b4: mmctx_exec_loop */
+/* 0x01b4: mmctx_wait_free */
 	0xf0008ecf,
 	0x0bf41fe4,
 	0x00ce98fa,
@@ -343,76 +344,77 @@ uint32_t nve0_grhub_code[] = {
 	0x04cdb804,
 	0xc8e81bf4,
 	0x1bf402ab,
-/* 0x01c9: mmctx_fini_wait */
+/* 0x01d5: mmctx_fini_wait */
 	0x008bcf18,
 	0xb01fb4f0,
 	0x1bf410b4,
 	0x02a7f0f7,
 	0xf4c921f4,
-/* 0x01de: mmctx_stop */
+/* 0x01ea: mmctx_stop */
 	0xabc81b0e,
 	0x10b4b600,
 	0xf00cb9f0,
 	0x8bd012b9,
-/* 0x01ed: mmctx_stop_wait */
+/* 0x01f9: mmctx_stop_wait */
 	0x008bcf00,
 	0xf412bbc8,
-/* 0x01f6: mmctx_done */
-	0x87f1fa1b,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00199,
-/* 0x0207: strand_wait */
-	0xf900f800,
-	0x02a7f0a0,
-	0xfcc921f4,
-/* 0x0213: strand_pre */
-	0xf100f8a0,
-	0xf04afc87,
-	0x97f00283,
-	0x0089d00c,
-	0x020721f5,
-/* 0x0226: strand_post */
-	0x87f100f8,
-	0x83f04afc,
-	0x0d97f002,
-	0xf50089d0,
-	0xf8020721,
-/* 0x0239: strand_set */
-	0xfca7f100,
-	0x02a3f04f,
-	0x0500aba2,
-	0xd00fc7f0,
-	0xc7f000ac,
-	0x00bcd00b,
-	0x020721f5,
-	0xf000aed0,
-	0xbcd00ac7,
-	0x0721f500,
-/* 0x0263: strand_ctx_init */
-	0xf100f802,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00399f0,
+/* 0x0202: mmctx_done */
+	0x94bdfa1b,
+	0xf10199f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0215: strand_wait */
+	0xf0a0f900,
+	0x21f402a7,
+	0xf8a0fcc9,
+/* 0x0221: strand_pre */
+	0xfc87f100,
+	0x0283f04a,
+	0xd00c97f0,
 	0x21f50089,
-	0xe7f00213,
-	0x3921f503,
+	0x00f80215,
+/* 0x0234: strand_post */
+	0x4afc87f1,
+	0xf00283f0,
+	0x89d00d97,
+	0x1521f500,
+/* 0x0247: strand_set */
+	0xf100f802,
+	0xf04ffca7,
+	0xaba202a3,
+	0xc7f00500,
+	0x00acd00f,
+	0xd00bc7f0,
+	0x21f500bc,
+	0xaed00215,
+	0x0ac7f000,
+	0xf500bcd0,
+	0xf8021521,
+/* 0x0271: strand_ctx_init */
+	0xf094bd00,
+	0x07f10399,
+	0x03f00f00,
+	0x0009d002,
+	0x21f504bd,
+	0xe7f00221,
+	0x4721f503,
 	0xfca7f102,
 	0x02a3f046,
 	0x0400aba0,
 	0xf040a0d0,
 	0xbcd001c7,
-	0x0721f500,
+	0x1521f500,
 	0x010c9202,
 	0xf000acd0,
 	0xbcd002c7,
-	0x0721f500,
-	0x2621f502,
+	0x1521f500,
+	0x3421f502,
 	0x8087f102,
 	0x0684b608,
 	0xb70089cf,
 	0x95220080,
-/* 0x02ba: ctx_init_strand_loop */
+/* 0x02ca: ctx_init_strand_loop */
 	0x8ed008fe,
 	0x408ed000,
 	0xb6808acf,
@@ -421,73 +423,61 @@ uint32_t nve0_grhub_code[] = {
 	0xb60480b6,
 	0x1bf40192,
 	0x08e4b6e8,
-	0xf1f2efbc,
-	0xb6085c87,
-	0x94bd0684,
-	0xd00399f0,
-	0x00f80089,
-/* 0x02ec: error */
-	0xe7f1e0f9,
-	0xe4b60814,
-	0x00efd006,
-	0x0c1ce7f1,
-	0xf006e4b6,
-	0xefd001f7,
-	0xf8e0fc00,
-/* 0x0309: init */
-	0xfe04bd00,
-	0x07fe0004,
-	0x0017f100,
-	0x0227f012,
-	0xf10012d0,
-	0xfe05b917,
-	0x17f10010,
-	0x10d00400,
-	0x0437f1c0,
-	0x0634b604,
-	0x200327f1,
-	0xf10032d0,
-	0xd0200427,
-	0x27f10132,
-	0x32d0200b,
-	0x0c27f102,
-	0x0732d020,
-	0x0c2427f1,
-	0xb90624b6,
-	0x23d00003,
+	0xbdf2efbc,
+	0x0399f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+/* 0x02fe: error */
+	0x07f100f8,
+	0x03f00500,
+	0x000fd002,
+	0xf7f004bd,
+	0x0007f101,
+	0x0303f007,
+	0xbd000fd0,
+/* 0x031b: init */
+	0xbd00f804,
+	0x0004fe04,
+	0xf10007fe,
+	0xf0120017,
+	0x12d00227,
+	0xb117f100,
+	0x0010fe05,
+	0x040017f1,
+	0xf1c010d0,
+	0xb6040437,
+	0x27f10634,
+	0x32d02003,
 	0x0427f100,
-	0x0023f087,
-	0xb70012d0,
-	0xf0010012,
-	0x12d00427,
-	0x1031f400,
-	0x9604e7f1,
-	0xf440e3f0,
-	0xf1c76821,
-	0x01018090,
-	0x801ff4f0,
-	0x17f0000f,
-	0x041fbb01,
-	0xf10112b6,
-	0xb6040c27,
-	0x21d00624,
-	0x4021d000,
-	0x080027f1,
-	0xcf0624b6,
-	0xf7f00022,
-/* 0x03a9: init_find_chipset */
-	0x08f0b654,
-	0xb800f398,
-	0x0bf40432,
-	0x0034b00b,
-	0xf8f11bf4,
-/* 0x03bd: init_context */
-	0x0017f100,
-	0x02fe5801,
-	0xf003ff58,
-	0x0e8000e3,
-	0x150f8014,
-	0x013d21f5,
+	0x0132d020,
+	0x200b27f1,
+	0xf10232d0,
+	0xd0200c27,
+	0x27f10732,
+	0x24b60c24,
+	0x0003b906,
+	0xf10023d0,
+	0xf0870427,
+	0x12d00023,
+	0x0012b700,
+	0x0427f001,
+	0xf40012d0,
+	0xe7f11031,
+	0xe3f09604,
+	0x6821f440,
+	0x8090f1c7,
+	0xf4f00301,
+	0x020f801f,
+	0xbb0117f0,
+	0x12b6041f,
+	0x0c27f101,
+	0x0624b604,
+	0xd00021d0,
+	0x17f14021,
+	0x0e980100,
+	0x010f9800,
+	0x014721f5,
 	0x070037f1,
 	0x950634b6,
 	0x34d00814,
@@ -498,196 +488,201 @@ uint32_t nve0_grhub_code[] = {
 	0x0815b600,
 	0xb60110b6,
 	0x1fb90814,
-	0x6321f502,
+	0x7121f502,
 	0x001fbb02,
-	0xf1000398,
+	0xf1020398,
 	0xf0200047,
-/* 0x040e: init_gpc */
+/* 0x03f6: init_gpc */
 	0x4ea05043,
 	0x1fb90804,
 	0x8d21f402,
-	0x08004ea0,
-	0xf4022fb9,
-	0x4ea08d21,
-	0xf4bd010c,
-	0xa08d21f4,
-	0xf401044e,
+	0x010c4ea0,
+	0x21f4f4bd,
+	0x044ea08d,
+	0x8d21f401,
+	0x01004ea0,
+	0xf402f7f0,
 	0x4ea08d21,
-	0xf7f00100,
-	0x8d21f402,
-	0x08004ea0,
-/* 0x0440: init_gpc_wait */
-	0xc86821f4,
-	0x0bf41fff,
-	0x044ea0fa,
-	0x6821f408,
-	0xb7001fbb,
-	0xb6800040,
-	0x1bf40132,
-	0x0027f1b4,
-	0x0624b608,
-	0xb74021d0,
-	0xbd080020,
+/* 0x041e: init_gpc_wait */
+	0x21f40800,
+	0x1fffc868,
+	0xa0fa0bf4,
+	0xf408044e,
+	0x1fbb6821,
+	0x0040b700,
+	0x0132b680,
+	0xf1be1bf4,
+	0xf0010007,
+	0x01d00203,
+	0xbd04bd00,
 	0x1f19f014,
-/* 0x0473: main */
-	0xf40021d0,
-	0x28f40031,
-	0x08d7f000,
-	0xf43921f4,
-	0xe4b1f401,
-	0x1bf54001,
-	0x87f100d1,
-	0x84b6083c,
-	0xf094bd06,
-	0x89d00499,
-	0x0017f100,
-	0x0614b60b,
-	0xcf4012cf,
-	0x13c80011,
-	0x7e0bf41f,
+	0x080007f1,
+	0xd00203f0,
+	0x04bd0001,
+/* 0x0458: main */
+	0xf40031f4,
+	0xd7f00028,
+	0x3921f410,
+	0xb1f401f4,
+	0xf54001e4,
+	0xbd00de1b,
+	0x0499f094,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x0b0017f1,
+	0xcf0614b6,
+	0x11cf4012,
+	0x1f13c800,
+	0x00870bf5,
 	0xf41f23c8,
-	0x20f95a0b,
-	0xf10212b9,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00799f0,
-	0x32f40089,
-	0x0231f401,
-	0x07fb21f5,
-	0x085c87f1,
-	0xbd0684b6,
+	0x20f9620b,
+	0xbd0212b9,
 	0x0799f094,
-	0xfc0089d0,
-	0x3c87f120,
-	0x0684b608,
-	0x99f094bd,
-	0x0089d006,
-	0xf50131f4,
-	0xf107fb21,
-	0xb6085c87,
-	0x94bd0684,
-	0xd00699f0,
-	0x0ef40089,
-/* 0x0509: chsw_prev_no_next */
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0xf40132f4,
+	0x21f50231,
+	0x94bd0801,
+	0xf10799f0,
+	0xf0170007,
+	0x09d00203,
+	0xfc04bd00,
+	0xf094bd20,
+	0x07f10699,
+	0x03f00f00,
+	0x0009d002,
+	0x31f404bd,
+	0x0121f501,
+	0xf094bd08,
+	0x07f10699,
+	0x03f01700,
+	0x0009d002,
+	0x0ef404bd,
+/* 0x04f9: chsw_prev_no_next */
 	0xb920f931,
 	0x32f40212,
 	0x0232f401,
-	0x07fb21f5,
+	0x080121f5,
 	0x17f120fc,
 	0x14b60b00,
 	0x0012d006,
-/* 0x0527: chsw_no_prev */
+/* 0x0517: chsw_no_prev */
 	0xc8130ef4,
 	0x0bf41f23,
 	0x0131f40d,
 	0xf50232f4,
-/* 0x0537: chsw_done */
-	0xf107fb21,
+/* 0x0527: chsw_done */
+	0xf1080121,
 	0xb60b0c17,
 	0x27f00614,
 	0x0012d001,
-	0x085c87f1,
-	0xbd0684b6,
-	0x0499f094,
-	0xf50089d0,
-/* 0x0557: main_not_ctx_switch */
-	0xb0ff200e,
-	0x1bf401e4,
-	0x02f2b90d,
-	0x078f21f5,
-/* 0x0567: main_not_ctx_chan */
-	0xb0420ef4,
-	0x1bf402e4,
-	0x3c87f12e,
-	0x0684b608,
 	0x99f094bd,
-	0x0089d007,
+	0x0007f104,
+	0x0203f017,
+	0xbd0009d0,
+	0x130ef504,
+/* 0x0549: main_not_ctx_switch */
+	0x01e4b0ff,
+	0xb90d1bf4,
+	0x21f502f2,
+	0x0ef40795,
+/* 0x0559: main_not_ctx_chan */
+	0x02e4b046,
+	0xbd321bf4,
+	0x0799f094,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
 	0xf40132f4,
 	0x21f50232,
-	0x87f107fb,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00799,
-	0x110ef400,
-/* 0x0598: main_not_ctx_save */
-	0xf010ef94,
-	0x21f501f5,
-	0x0ef502ec,
-/* 0x05a6: main_done */
-	0x17f1fed1,
-	0x14b60820,
-	0xf024bd06,
-	0x12d01f29,
-	0xbe0ef500,
-/* 0x05b9: ih */
+	0x94bd0801,
+	0xf10799f0,
+	0xf0170007,
+	0x09d00203,
+	0xf404bd00,
+/* 0x058e: main_not_ctx_save */
+	0xef94110e,
+	0x01f5f010,
+	0x02fe21f5,
+	0xfec00ef5,
+/* 0x059c: main_done */
+	0x29f024bd,
+	0x0007f11f,
+	0x0203f008,
+	0xbd0002d0,
+	0xab0ef504,
+/* 0x05b1: ih */
 	0xfe80f9fe,
 	0x80f90188,
 	0xa0f990f9,
 	0xd0f9b0f9,
 	0xf0f9e0f9,
-	0xc4800acf,
-	0x0bf404ab,
-	0x00b7f11d,
-	0x08d7f019,
-	0xcf40becf,
-	0x21f400bf,
-	0x00b0b704,
-	0x01e7f004,
-/* 0x05ef: ih_no_fifo */
-	0xe400bed0,
-	0xf40100ab,
-	0xd7f00d0b,
-	0x01e7f108,
-	0x0421f440,
-/* 0x0600: ih_no_ctxsw */
-	0x0104b7f1,
-	0xabffb0bd,
-	0x0d0bf4b4,
-	0x0c1ca7f1,
-	0xd006a4b6,
-/* 0x0616: ih_no_other */
-	0x0ad000ab,
-	0xfcf0fc40,
-	0xfcd0fce0,
-	0xfca0fcb0,
-	0xfe80fc90,
-	0x80fc0088,
-	0xf80032f4,
-/* 0x0631: ctx_4170s */
-	0x70e7f101,
-	0x40e3f041,
-	0xf410f5f0,
-	0x00f88d21,
-/* 0x0640: ctx_4170w */
-	0x4170e7f1,
-	0xf440e3f0,
-	0xf4f06821,
-	0xf31bf410,
-/* 0x0652: ctx_redswitch */
-	0xe7f100f8,
-	0xe4b60614,
-	0x70f7f106,
-	0x00efd002,
-/* 0x0663: ctx_redswitch_delay */
-	0xb608f7f0,
-	0x1bf401f2,
-	0x70f7f1fd,
-	0x00efd007,
-/* 0x0672: ctx_86c */
+	0x0acf04bd,
+	0x04abc480,
+	0xf11d0bf4,
+	0xf01900b7,
+	0xbecf10d7,
+	0x00bfcf40,
+	0xb70421f4,
+	0xf00400b0,
+	0xbed001e7,
+/* 0x05e9: ih_no_fifo */
+	0x00abe400,
+	0x0d0bf401,
+	0xf110d7f0,
+	0xf44001e7,
+/* 0x05fa: ih_no_ctxsw */
+	0xb7f10421,
+	0xb0bd0104,
+	0xf4b4abff,
+	0xa7f10d0b,
+	0xa4b60c1c,
+	0x00abd006,
+/* 0x0610: ih_no_other */
+	0xfc400ad0,
+	0xfce0fcf0,
+	0xfcb0fcd0,
+	0xfc90fca0,
+	0x0088fe80,
+	0x32f480fc,
+/* 0x062b: ctx_4170s */
+	0xf101f800,
+	0xf04170e7,
+	0xf5f040e3,
+	0x8d21f410,
+/* 0x063a: ctx_4170w */
 	0xe7f100f8,
-	0xe4b6086c,
-	0x00efd006,
-	0x8a14e7f1,
-	0xf440e3f0,
-	0xe7f18d21,
-	0xe3f0a86c,
-	0x8d21f441,
-/* 0x0692: ctx_load */
-	0x87f100f8,
-	0x84b6083c,
-	0xf094bd06,
-	0x89d00599,
-	0x0ca7f000,
+	0xe3f04170,
+	0x6821f440,
+	0xf410f4f0,
+	0x00f8f31b,
+/* 0x064c: ctx_redswitch */
+	0x0614e7f1,
+	0xf106e4b6,
+	0xd00270f7,
+	0xf7f000ef,
+/* 0x065d: ctx_redswitch_delay */
+	0x01f2b608,
+	0xf1fd1bf4,
+	0xd00770f7,
+	0x00f800ef,
+/* 0x066c: ctx_86c */
+	0x086ce7f1,
+	0xd006e4b6,
+	0xe7f100ef,
+	0xe3f08a14,
+	0x8d21f440,
+	0xa86ce7f1,
+	0xf441e3f0,
+	0x00f88d21,
+/* 0x068c: ctx_load */
+	0x99f094bd,
+	0x0007f105,
+	0x0203f00f,
+	0xbd0009d0,
+	0x0ca7f004,
 	0xf1c921f4,
 	0xb60a2417,
 	0x10d00614,
@@ -697,162 +692,227 @@ uint32_t nve0_grhub_code[] = {
 	0xb60a0c17,
 	0x47f00614,
 	0x0012d007,
-/* 0x06cb: ctx_chan_wait_0 */
+/* 0x06c7: ctx_chan_wait_0 */
 	0xcf4014d0,
 	0x44f04014,
 	0xfa1bf41f,
 	0xfe0032d0,
 	0x2af0000b,
 	0x0424b61f,
-	0xf10220b6,
-	0xb6083c87,
-	0x94bd0684,
-	0xd00899f0,
-	0x17f10089,
-	0x14b60a04,
-	0x0012d006,
-	0x0a2017f1,
-	0xf00614b6,
-	0x23f10227,
-	0x12d08000,
-	0x1017f000,
-	0x030027f1,
-	0xfa0223f0,
-	0x03f80512,
-	0x085c87f1,
-	0xbd0684b6,
+	0xbd0220b6,
 	0x0899f094,
-	0x980089d0,
-	0x14b6c101,
-	0xc0029818,
+	0x0f0007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x0a0417f1,
+	0xd00614b6,
+	0x17f10012,
+	0x14b60a20,
+	0x0227f006,
+	0x800023f1,
+	0xf00012d0,
+	0x27f11017,
+	0x23f00200,
+	0x0512fa02,
+	0x94bd03f8,
+	0xf10899f0,
+	0xf0170007,
+	0x09d00203,
+	0x9804bd00,
+	0x14b68101,
+	0x80029818,
 	0xfd0825b6,
 	0x01800512,
-	0x3c87f116,
-	0x0684b608,
-	0x99f094bd,
-	0x0089d009,
-	0x0a0427f1,
-	0xd00624b6,
-	0x27f00021,
-	0x2017f101,
-	0x0614b60a,
-	0xf10012d0,
-	0xf0020017,
+	0xf094bd16,
+	0x07f10999,
+	0x03f00f00,
+	0x0009d002,
+	0x27f104bd,
+	0x24b60a04,
+	0x0021d006,
+	0xf10127f0,
+	0xb60a2017,
+	0x12d00614,
+	0x0017f100,
+	0x0613f001,
+	0xf80501fa,
+	0xf094bd03,
+	0x07f10999,
+	0x03f01700,
+	0x0009d002,
+	0x94bd04bd,
+	0xf10599f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0795: ctx_chan */
+	0x8c21f500,
+	0x0ca7f006,
+	0xf1c921f4,
+	0xb60a1017,
+	0x27f00614,
+	0x0012d005,
+/* 0x07ac: ctx_chan_wait */
+	0xfd0012cf,
+	0x1bf40522,
+/* 0x07b7: ctx_mmio_exec */
+	0x9800f8fa,
+	0x27f14103,
+	0x24b60a04,
+	0x0023d006,
+/* 0x07c6: ctx_mmio_loop */
+	0x34c434bd,
+	0x0f1bf4ff,
+	0x020057f1,
+	0xfa0653f0,
+	0x03f80535,
+/* 0x07d8: ctx_mmio_pull */
+	0x98804e98,
+	0x21f4814f,
+	0x0830b68d,
+	0xf40112b6,
+/* 0x07ea: ctx_mmio_done */
+	0x0398df1b,
+	0x0023d016,
+	0xf1400080,
+	0xf0010017,
 	0x01fa0613,
-	0xf103f805,
-	0xb6085c87,
-	0x94bd0684,
-	0xd00999f0,
-	0x87f10089,
-	0x84b6085c,
-	0xf094bd06,
-	0x89d00599,
-/* 0x078f: ctx_chan */
-	0xf500f800,
-	0xf0069221,
-	0x21f40ca7,
-	0x1017f1c9,
-	0x0614b60a,
-	0xd00527f0,
-/* 0x07a6: ctx_chan_wait */
-	0x12cf0012,
-	0x0522fd00,
-	0xf8fa1bf4,
-/* 0x07b1: ctx_mmio_exec */
-	0x81039800,
-	0x0a0427f1,
+	0xf803f806,
+/* 0x0801: ctx_xfer */
+	0x00f7f100,
+	0x06f4b60c,
+	0xd004e7f0,
+/* 0x080e: ctx_xfer_idle */
+	0xfecf80fe,
+	0x00e4f100,
+	0xf91bf420,
+	0xf40611f4,
+/* 0x081e: ctx_xfer_pre */
+	0xf7f00d02,
+	0x6c21f510,
+	0x1c11f406,
+/* 0x0828: ctx_xfer_pre_load */
+	0xf502f7f0,
+	0xf5062b21,
+	0xf5063a21,
+	0xbd064c21,
+	0x2b21f5f4,
+	0x8c21f506,
+/* 0x0841: ctx_xfer_exec */
+	0x16019806,
+	0x041427f1,
 	0xd00624b6,
-	0x34bd0023,
-/* 0x07c0: ctx_mmio_loop */
-	0xf4ff34c4,
-	0x57f10f1b,
-	0x53f00300,
-	0x0535fa06,
-/* 0x07d2: ctx_mmio_pull */
-	0x4e9803f8,
-	0xc14f98c0,
+	0xe7f10020,
+	0xe3f0a500,
+	0x021fb941,
 	0xb68d21f4,
-	0x12b60830,
-	0xdf1bf401,
-/* 0x07e4: ctx_mmio_done */
-	0xd0160398,
-	0x00800023,
-	0x0017f180,
-	0x0613f002,
-	0xf80601fa,
-/* 0x07fb: ctx_xfer */
-	0xf100f803,
-	0xb60c00f7,
-	0xe7f006f4,
-	0x80fed004,
-/* 0x0808: ctx_xfer_idle */
-	0xf100fecf,
-	0xf42000e4,
-	0x11f4f91b,
-	0x0d02f406,
-/* 0x0818: ctx_xfer_pre */
-	0xf510f7f0,
-	0xf4067221,
-/* 0x0822: ctx_xfer_pre_load */
-	0xf7f01c11,
-	0x3121f502,
-	0x4021f506,
-	0x5221f506,
-	0xf5f4bd06,
-	0xf5063121,
-/* 0x083b: ctx_xfer_exec */
-	0x98069221,
-	0x27f11601,
-	0x24b60414,
-	0x0020d006,
-	0xa500e7f1,
-	0xb941e3f0,
-	0x21f4021f,
-	0x04e0b68d,
-	0xf001fcf0,
-	0x24b6022c,
-	0x05f2fd01,
-	0xf18d21f4,
-	0xf04afc17,
-	0x27f00213,
-	0x0012d00c,
-	0x020721f5,
-	0x47fc27f1,
-	0xd00223f0,
-	0x2cf00020,
-	0x0320b601,
-	0xf00012d0,
-	0xa5f001ac,
-	0x00b7f006,
-	0x98140c98,
-	0xe7f0150d,
-	0x5c21f500,
-	0x08a7f001,
-	0x010321f5,
-	0x020721f5,
-	0xf02201f4,
-	0x21f40ca7,
-	0x1017f1c9,
-	0x0614b60a,
-	0xd00527f0,
-/* 0x08c2: ctx_xfer_post_save_wait */
-	0x12cf0012,
-	0x0522fd00,
-	0xf4fa1bf4,
-/* 0x08ce: ctx_xfer_post */
-	0xf7f02e02,
-	0x3121f502,
+	0xfcf004e0,
+	0x022cf001,
+	0xfd0124b6,
+	0x21f405f2,
+	0xfc17f18d,
+	0x0213f04a,
+	0xd00c27f0,
+	0x21f50012,
+	0x27f10215,
+	0x23f047fc,
+	0x0020d002,
+	0xb6012cf0,
+	0x12d00320,
+	0x01acf000,
+	0xf006a5f0,
+	0x0c9800b7,
+	0x010d9800,
+	0xf500e7f0,
+	0xf0016621,
+	0x21f508a7,
+	0x21f50109,
+	0x01f40215,
+	0x0ca7f022,
+	0xf1c921f4,
+	0xb60a1017,
+	0x27f00614,
+	0x0012d005,
+/* 0x08c8: ctx_xfer_post_save_wait */
+	0xfd0012cf,
+	0x1bf40522,
+	0x2e02f4fa,
+/* 0x08d4: ctx_xfer_post */
+	0xf502f7f0,
+	0xbd062b21,
+	0x6c21f5f4,
+	0x3421f506,
+	0x3a21f502,
 	0xf5f4bd06,
-	0xf5067221,
-	0xf5022621,
-	0xbd064021,
-	0x3121f5f4,
-	0x1011f406,
-	0xfd800198,
-	0x0bf40511,
-	0xb121f507,
-/* 0x08f9: ctx_xfer_no_post_mmio */
-/* 0x08f9: ctx_xfer_done */
-	0x0000f807,
+	0xf4062b21,
+	0x01981011,
+	0x0511fd40,
+	0xf5070bf4,
+/* 0x08ff: ctx_xfer_no_post_mmio */
+/* 0x08ff: ctx_xfer_done */
+	0xf807b721,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
 	0x00000000,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#define CHIPSET GK110
+#include "macros.fuc"
+
+.section #nvf0_grhub_data
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "hub.fuc"
+#undef INCLUDE_DATA
+
+.section #nvf0_grhub_code
+#define INCLUDE_CODE
+bra #init
+#include "com.fuc"
+#include "hub.fuc"
+.align 256
+#undef INCLUDE_CODE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,918 @@
+uint32_t nvf0_grhub_data[] = {
+/* 0x0000: hub_mmio_list_head */
+	0x00000300,
+/* 0x0004: hub_mmio_list_tail */
+	0x00000304,
+/* 0x0008: gpc_count */
+	0x00000000,
+/* 0x000c: rop_count */
+	0x00000000,
+/* 0x0010: cmd_queue */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0058: ctx_current */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0100: chan_data */
+/* 0x0100: chan_mmio_count */
+	0x00000000,
+/* 0x0104: chan_mmio_address */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0200: xfer_data */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0300: hub_mmio_list_base */
+	0x0417e91c,
+};
+
+uint32_t nvf0_grhub_code[] = {
+	0x031b0ef5,
+/* 0x0004: queue_put */
+	0x9800d898,
+	0x86f001d9,
+	0x0489b808,
+	0xf00c1bf4,
+	0x21f502f7,
+	0x00f802fe,
+/* 0x001c: queue_put_next */
+	0xb60798c4,
+	0x8dbb0384,
+	0x0880b600,
+	0x80008e80,
+	0x90b6018f,
+	0x0f94f001,
+	0xf801d980,
+/* 0x0039: queue_get */
+	0x0131f400,
+	0x9800d898,
+	0x89b801d9,
+	0x210bf404,
+	0xb60789c4,
+	0x9dbb0394,
+	0x0890b600,
+	0x98009e98,
+	0x80b6019f,
+	0x0f84f001,
+	0xf400d880,
+/* 0x0066: queue_get_done */
+	0x00f80132,
+/* 0x0068: nv_rd32 */
+	0x0728b7f1,
+	0xb906b4b6,
+	0xc9f002ec,
+	0x00bcd01f,
+/* 0x0078: nv_rd32_wait */
+	0xc800bccf,
+	0x1bf41fcc,
+	0x06a7f0fa,
+	0x010921f5,
+	0xf840bfcf,
+/* 0x008d: nv_wr32 */
+	0x28b7f100,
+	0x06b4b607,
+	0xb980bfd0,
+	0xc9f002ec,
+	0x1ec9f01f,
+/* 0x00a3: nv_wr32_wait */
+	0xcf00bcd0,
+	0xccc800bc,
+	0xfa1bf41f,
+/* 0x00ae: watchdog_reset */
+	0x87f100f8,
+	0x84b60430,
+	0x1ff9f006,
+	0xf8008fd0,
+/* 0x00bd: watchdog_clear */
+	0x3087f100,
+	0x0684b604,
+	0xf80080d0,
+/* 0x00c9: wait_donez */
+	0xf094bd00,
+	0x07f10099,
+	0x03f03700,
+	0x0009d002,
+	0x07f104bd,
+	0x03f00600,
+	0x000ad002,
+/* 0x00e6: wait_donez_ne */
+	0x87f104bd,
+	0x83f00000,
+	0x0088cf01,
+	0xf4888aff,
+	0x94bdf31b,
+	0xf10099f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0109: wait_doneo */
+	0xf094bd00,
+	0x07f10099,
+	0x03f03700,
+	0x0009d002,
+	0x87f104bd,
+	0x84b60818,
+	0x008ad006,
+/* 0x0124: wait_doneo_e */
+	0x040087f1,
+	0xcf0684b6,
+	0x8aff0088,
+	0xf30bf488,
+	0x99f094bd,
+	0x0007f100,
+	0x0203f017,
+	0xbd0009d0,
+/* 0x0147: mmctx_size */
+	0xbd00f804,
+/* 0x0149: nv_mmctx_size_loop */
+	0x00e89894,
+	0xb61a85b6,
+	0x84b60180,
+	0x0098bb02,
+	0xb804e0b6,
+	0x1bf404ef,
+	0x029fb9eb,
+/* 0x0166: mmctx_xfer */
+	0x94bd00f8,
+	0xf10199f0,
+	0xf0370007,
+	0x09d00203,
+	0xf104bd00,
+	0xb6071087,
+	0x94bd0684,
+	0xf405bbfd,
+	0x8bd0090b,
+	0x0099f000,
+/* 0x018c: mmctx_base_disabled */
+	0xf405eefd,
+	0x8ed00c0b,
+	0xc08fd080,
+/* 0x019b: mmctx_multi_disabled */
+	0xb70199f0,
+	0xc8010080,
+	0xb4b600ab,
+	0x0cb9f010,
+	0xb601aec8,
+	0xbefd11e4,
+	0x008bd005,
+/* 0x01b4: mmctx_exec_loop */
+/* 0x01b4: mmctx_wait_free */
+	0xf0008ecf,
+	0x0bf41fe4,
+	0x00ce98fa,
+	0xd005e9fd,
+	0xc0b6c08e,
+	0x04cdb804,
+	0xc8e81bf4,
+	0x1bf402ab,
+/* 0x01d5: mmctx_fini_wait */
+	0x008bcf18,
+	0xb01fb4f0,
+	0x1bf410b4,
+	0x02a7f0f7,
+	0xf4c921f4,
+/* 0x01ea: mmctx_stop */
+	0xabc81b0e,
+	0x10b4b600,
+	0xf00cb9f0,
+	0x8bd012b9,
+/* 0x01f9: mmctx_stop_wait */
+	0x008bcf00,
+	0xf412bbc8,
+/* 0x0202: mmctx_done */
+	0x94bdfa1b,
+	0xf10199f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0215: strand_wait */
+	0xf0a0f900,
+	0x21f402a7,
+	0xf8a0fcc9,
+/* 0x0221: strand_pre */
+	0xfc87f100,
+	0x0283f04a,
+	0xd00c97f0,
+	0x21f50089,
+	0x00f80215,
+/* 0x0234: strand_post */
+	0x4afc87f1,
+	0xf00283f0,
+	0x89d00d97,
+	0x1521f500,
+/* 0x0247: strand_set */
+	0xf100f802,
+	0xf04ffca7,
+	0xaba202a3,
+	0xc7f00500,
+	0x00acd00f,
+	0xd00bc7f0,
+	0x21f500bc,
+	0xaed00215,
+	0x0ac7f000,
+	0xf500bcd0,
+	0xf8021521,
+/* 0x0271: strand_ctx_init */
+	0xf094bd00,
+	0x07f10399,
+	0x03f03700,
+	0x0009d002,
+	0x21f504bd,
+	0xe7f00221,
+	0x4721f503,
+	0xfca7f102,
+	0x02a3f046,
+	0x0400aba0,
+	0xf040a0d0,
+	0xbcd001c7,
+	0x1521f500,
+	0x010c9202,
+	0xf000acd0,
+	0xbcd002c7,
+	0x1521f500,
+	0x3421f502,
+	0x8087f102,
+	0x0684b608,
+	0xb70089cf,
+	0x95220080,
+/* 0x02ca: ctx_init_strand_loop */
+	0x8ed008fe,
+	0x408ed000,
+	0xb6808acf,
+	0xa0b606a5,
+	0x00eabb01,
+	0xb60480b6,
+	0x1bf40192,
+	0x08e4b6e8,
+	0xbdf2efbc,
+	0x0399f094,
+	0x170007f1,
+	0xd00203f0,
+	0x04bd0009,
+/* 0x02fe: error */
+	0x07f100f8,
+	0x03f00500,
+	0x000fd002,
+	0xf7f004bd,
+	0x0007f101,
+	0x0303f007,
+	0xbd000fd0,
+/* 0x031b: init */
+	0xbd00f804,
+	0x0004fe04,
+	0xf10007fe,
+	0xf0120017,
+	0x12d00227,
+	0xb117f100,
+	0x0010fe05,
+	0x040017f1,
+	0xf1c010d0,
+	0xb6040437,
+	0x27f10634,
+	0x32d02003,
+	0x0427f100,
+	0x0132d020,
+	0x200b27f1,
+	0xf10232d0,
+	0xd0200c27,
+	0x27f10732,
+	0x24b60c24,
+	0x0003b906,
+	0xf10023d0,
+	0xf0870427,
+	0x12d00023,
+	0x0012b700,
+	0x0427f001,
+	0xf40012d0,
+	0xe7f11031,
+	0xe3f09604,
+	0x6821f440,
+	0x8090f1c7,
+	0xf4f00301,
+	0x020f801f,
+	0xbb0117f0,
+	0x12b6041f,
+	0x0c27f101,
+	0x0624b604,
+	0xd00021d0,
+	0x17f14021,
+	0x0e980100,
+	0x010f9800,
+	0x014721f5,
+	0x070037f1,
+	0x950634b6,
+	0x34d00814,
+	0x4034d000,
+	0x130030b7,
+	0xb6001fbb,
+	0x3fd002f5,
+	0x0815b600,
+	0xb60110b6,
+	0x1fb90814,
+	0x7121f502,
+	0x001fbb02,
+	0xf1020398,
+	0xf0200047,
+/* 0x03f6: init_gpc */
+	0x4ea05043,
+	0x1fb90804,
+	0x8d21f402,
+	0x010c4ea0,
+	0x21f4f4bd,
+	0x044ea08d,
+	0x8d21f401,
+	0x01004ea0,
+	0xf402f7f0,
+	0x4ea08d21,
+/* 0x041e: init_gpc_wait */
+	0x21f40800,
+	0x1fffc868,
+	0xa0fa0bf4,
+	0xf408044e,
+	0x1fbb6821,
+	0x0040b700,
+	0x0132b680,
+	0xf1be1bf4,
+	0xf0010007,
+	0x01d00203,
+	0xbd04bd00,
+	0x1f19f014,
+	0x300007f1,
+	0xd00203f0,
+	0x04bd0001,
+/* 0x0458: main */
+	0xf40031f4,
+	0xd7f00028,
+	0x3921f410,
+	0xb1f401f4,
+	0xf54001e4,
+	0xbd00de1b,
+	0x0499f094,
+	0x370007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x0b0017f1,
+	0xcf0614b6,
+	0x11cf4012,
+	0x1f13c800,
+	0x00870bf5,
+	0xf41f23c8,
+	0x20f9620b,
+	0xbd0212b9,
+	0x0799f094,
+	0x370007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0xf40132f4,
+	0x21f50231,
+	0x94bd0801,
+	0xf10799f0,
+	0xf0170007,
+	0x09d00203,
+	0xfc04bd00,
+	0xf094bd20,
+	0x07f10699,
+	0x03f03700,
+	0x0009d002,
+	0x31f404bd,
+	0x0121f501,
+	0xf094bd08,
+	0x07f10699,
+	0x03f01700,
+	0x0009d002,
+	0x0ef404bd,
+/* 0x04f9: chsw_prev_no_next */
+	0xb920f931,
+	0x32f40212,
+	0x0232f401,
+	0x080121f5,
+	0x17f120fc,
+	0x14b60b00,
+	0x0012d006,
+/* 0x0517: chsw_no_prev */
+	0xc8130ef4,
+	0x0bf41f23,
+	0x0131f40d,
+	0xf50232f4,
+/* 0x0527: chsw_done */
+	0xf1080121,
+	0xb60b0c17,
+	0x27f00614,
+	0x0012d001,
+	0x99f094bd,
+	0x0007f104,
+	0x0203f017,
+	0xbd0009d0,
+	0x130ef504,
+/* 0x0549: main_not_ctx_switch */
+	0x01e4b0ff,
+	0xb90d1bf4,
+	0x21f502f2,
+	0x0ef40795,
+/* 0x0559: main_not_ctx_chan */
+	0x02e4b046,
+	0xbd321bf4,
+	0x0799f094,
+	0x370007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0xf40132f4,
+	0x21f50232,
+	0x94bd0801,
+	0xf10799f0,
+	0xf0170007,
+	0x09d00203,
+	0xf404bd00,
+/* 0x058e: main_not_ctx_save */
+	0xef94110e,
+	0x01f5f010,
+	0x02fe21f5,
+	0xfec00ef5,
+/* 0x059c: main_done */
+	0x29f024bd,
+	0x0007f11f,
+	0x0203f030,
+	0xbd0002d0,
+	0xab0ef504,
+/* 0x05b1: ih */
+	0xfe80f9fe,
+	0x80f90188,
+	0xa0f990f9,
+	0xd0f9b0f9,
+	0xf0f9e0f9,
+	0x0acf04bd,
+	0x04abc480,
+	0xf11d0bf4,
+	0xf01900b7,
+	0xbecf10d7,
+	0x00bfcf40,
+	0xb70421f4,
+	0xf00400b0,
+	0xbed001e7,
+/* 0x05e9: ih_no_fifo */
+	0x00abe400,
+	0x0d0bf401,
+	0xf110d7f0,
+	0xf44001e7,
+/* 0x05fa: ih_no_ctxsw */
+	0xb7f10421,
+	0xb0bd0104,
+	0xf4b4abff,
+	0xa7f10d0b,
+	0xa4b60c1c,
+	0x00abd006,
+/* 0x0610: ih_no_other */
+	0xfc400ad0,
+	0xfce0fcf0,
+	0xfcb0fcd0,
+	0xfc90fca0,
+	0x0088fe80,
+	0x32f480fc,
+/* 0x062b: ctx_4170s */
+	0xf101f800,
+	0xf04170e7,
+	0xf5f040e3,
+	0x8d21f410,
+/* 0x063a: ctx_4170w */
+	0xe7f100f8,
+	0xe3f04170,
+	0x6821f440,
+	0xf410f4f0,
+	0x00f8f31b,
+/* 0x064c: ctx_redswitch */
+	0x0614e7f1,
+	0xf106e4b6,
+	0xd00270f7,
+	0xf7f000ef,
+/* 0x065d: ctx_redswitch_delay */
+	0x01f2b608,
+	0xf1fd1bf4,
+	0xd00770f7,
+	0x00f800ef,
+/* 0x066c: ctx_86c */
+	0x086ce7f1,
+	0xd006e4b6,
+	0xe7f100ef,
+	0xe3f08a14,
+	0x8d21f440,
+	0xa86ce7f1,
+	0xf441e3f0,
+	0x00f88d21,
+/* 0x068c: ctx_load */
+	0x99f094bd,
+	0x0007f105,
+	0x0203f037,
+	0xbd0009d0,
+	0x0ca7f004,
+	0xf1c921f4,
+	0xb60a2417,
+	0x10d00614,
+	0x0037f100,
+	0x0634b60b,
+	0xf14032d0,
+	0xb60a0c17,
+	0x47f00614,
+	0x0012d007,
+/* 0x06c7: ctx_chan_wait_0 */
+	0xcf4014d0,
+	0x44f04014,
+	0xfa1bf41f,
+	0xfe0032d0,
+	0x2af0000b,
+	0x0424b61f,
+	0xbd0220b6,
+	0x0899f094,
+	0x370007f1,
+	0xd00203f0,
+	0x04bd0009,
+	0x0a0417f1,
+	0xd00614b6,
+	0x17f10012,
+	0x14b60a20,
+	0x0227f006,
+	0x800023f1,
+	0xf00012d0,
+	0x27f11017,
+	0x23f00200,
+	0x0512fa02,
+	0x94bd03f8,
+	0xf10899f0,
+	0xf0170007,
+	0x09d00203,
+	0x9804bd00,
+	0x14b68101,
+	0x80029818,
+	0xfd0825b6,
+	0x01800512,
+	0xf094bd16,
+	0x07f10999,
+	0x03f03700,
+	0x0009d002,
+	0x27f104bd,
+	0x24b60a04,
+	0x0021d006,
+	0xf10127f0,
+	0xb60a2017,
+	0x12d00614,
+	0x0017f100,
+	0x0613f001,
+	0xf80501fa,
+	0xf094bd03,
+	0x07f10999,
+	0x03f01700,
+	0x0009d002,
+	0x94bd04bd,
+	0xf10599f0,
+	0xf0170007,
+	0x09d00203,
+	0xf804bd00,
+/* 0x0795: ctx_chan */
+	0x8c21f500,
+	0x0ca7f006,
+	0xf1c921f4,
+	0xb60a1017,
+	0x27f00614,
+	0x0012d005,
+/* 0x07ac: ctx_chan_wait */
+	0xfd0012cf,
+	0x1bf40522,
+/* 0x07b7: ctx_mmio_exec */
+	0x9800f8fa,
+	0x27f14103,
+	0x24b60a04,
+	0x0023d006,
+/* 0x07c6: ctx_mmio_loop */
+	0x34c434bd,
+	0x0f1bf4ff,
+	0x020057f1,
+	0xfa0653f0,
+	0x03f80535,
+/* 0x07d8: ctx_mmio_pull */
+	0x98804e98,
+	0x21f4814f,
+	0x0830b68d,
+	0xf40112b6,
+/* 0x07ea: ctx_mmio_done */
+	0x0398df1b,
+	0x0023d016,
+	0xf1400080,
+	0xf0010017,
+	0x01fa0613,
+	0xf803f806,
+/* 0x0801: ctx_xfer */
+	0x00f7f100,
+	0x06f4b60c,
+	0xd004e7f0,
+/* 0x080e: ctx_xfer_idle */
+	0xfecf80fe,
+	0x00e4f100,
+	0xf91bf420,
+	0xf40611f4,
+/* 0x081e: ctx_xfer_pre */
+	0xf7f00d02,
+	0x6c21f510,
+	0x1c11f406,
+/* 0x0828: ctx_xfer_pre_load */
+	0xf502f7f0,
+	0xf5062b21,
+	0xf5063a21,
+	0xbd064c21,
+	0x2b21f5f4,
+	0x8c21f506,
+/* 0x0841: ctx_xfer_exec */
+	0x16019806,
+	0x041427f1,
+	0xd00624b6,
+	0xe7f10020,
+	0xe3f0a500,
+	0x021fb941,
+	0xb68d21f4,
+	0xfcf004e0,
+	0x022cf001,
+	0xfd0124b6,
+	0x21f405f2,
+	0xfc17f18d,
+	0x0213f04a,
+	0xd00c27f0,
+	0x21f50012,
+	0x27f10215,
+	0x23f047fc,
+	0x0020d002,
+	0xb6012cf0,
+	0x12d00320,
+	0x01acf000,
+	0xf006a5f0,
+	0x0c9800b7,
+	0x010d9800,
+	0xf500e7f0,
+	0xf0016621,
+	0x21f508a7,
+	0x21f50109,
+	0x01f40215,
+	0x0ca7f022,
+	0xf1c921f4,
+	0xb60a1017,
+	0x27f00614,
+	0x0012d005,
+/* 0x08c8: ctx_xfer_post_save_wait */
+	0xfd0012cf,
+	0x1bf40522,
+	0x2e02f4fa,
+/* 0x08d4: ctx_xfer_post */
+	0xf502f7f0,
+	0xbd062b21,
+	0x6c21f5f4,
+	0x3421f506,
+	0x3a21f502,
+	0xf5f4bd06,
+	0xf4062b21,
+	0x01981011,
+	0x0511fd40,
+	0xf5070bf4,
+/* 0x08ff: ctx_xfer_no_post_mmio */
+/* 0x08ff: ctx_xfer_done */
+	0xf807b721,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "os.h"
+
+#define GF100 0xc0
+#define GF117 0xd7
+#define GK100 0xe0
+#define GK110 0xf0
+
+#define NV_PGRAPH_FECS_SIGNAL                                          0x409400
+#if CHIPSET < GK110
+#define NV_PGRAPH_FECS_CC_SCRATCH_VAL(n)                    ((n) * 4 + 0x409800)
+#define NV_PGRAPH_FECS_CC_SCRATCH_SET(n)                    ((n) * 4 + 0x409820)
+#define NV_PGRAPH_FECS_CC_SCRATCH_CLR(n)                    ((n) * 4 + 0x409840)
+#else
+#define NV_PGRAPH_FECS_CC_SCRATCH_VAL(n)                    ((n) * 4 + 0x409800)
+#define NV_PGRAPH_FECS_CC_SCRATCH_CLR(n)                    ((n) * 4 + 0x409840)
+#define NV_PGRAPH_FECS_CC_SCRATCH_SET(n)                    ((n) * 4 + 0x4098c0)
+#endif
+#define NV_PGRAPH_FECS_INTR_UP_SET                                     0x409c1c
+
+#if CHIPSET < GK110
+#define NV_PGRAPH_GPCX_GPCCS_CC_SCRATCH_VAL(n)              ((n) * 4 + 0x41a800)
+#define NV_PGRAPH_GPCX_GPCCS_CC_SCRATCH_SET(n)              ((n) * 4 + 0x41a820)
+#define NV_PGRAPH_GPCX_GPCCS_CC_SCRATCH_CLR(n)              ((n) * 4 + 0x41a840)
+#else
+#define NV_PGRAPH_GPCX_GPCCS_CC_SCRATCH_VAL(n)              ((n) * 4 + 0x41a800)
+#define NV_PGRAPH_GPCX_GPCCS_CC_SCRATCH_CLR(n)              ((n) * 4 + 0x41a840)
+#define NV_PGRAPH_GPCX_GPCCS_CC_SCRATCH_SET(n)              ((n) * 4 + 0x41a8c0)
+#endif
+
+#define mmctx_data(r,c) .b32 (((c - 1) << 26) | r)
+#define queue_init      .skip 72 // (2 * 4) + ((8 * 4) * 2)
+
+#define T_WAIT    0
+#define T_MMCTX   1
+#define T_STRWAIT 2
+#define T_STRINIT 3
+#define T_AUTO    4
+#define T_CHAN    5
+#define T_LOAD    6
+#define T_SAVE    7
+#define T_LCHAN   8
+#define T_LCTXH   9
+
+#define nv_mkmm(rv,r) /*
+*/	movw rv  ((r) & 0x0000fffc) /*
+*/	sethi rv ((r) & 0x00ff0000)
+#define nv_mkio(rv,r,i) /*
+*/	nv_mkmm(rv, (((r) & 0xffc) << 6) | ((i) << 2))
+
+#define nv_iord(rv,r,i) /*
+*/	nv_mkio(rv,r,i) /*
+*/	iord rv I[rv]
+#define nv_iowr(r,i,rv) /*
+*/	nv_mkio($r0,r,i) /*
+*/	iowr I[$r0] rv /*
+*/	clear b32 $r0
+
+#define trace_set(bit) /*
+*/	clear b32 $r9 /*
+*/	bset $r9 bit /*
+*/	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_SET(7), 0, $r9)
+#define trace_clr(bit) /*
+*/	clear b32 $r9 /*
+*/	bset $r9 bit /*
+*/	nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_CLR(7), 0, $r9)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nvc0.fuc	1969-12-31 19:00:00.000000000 -0500
@@ -1,400 +0,0 @@
-/* fuc microcode util functions for nvc0 PGRAPH
- *
- * Copyright 2011 Red Hat Inc.
- *
- * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)')
-define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))')
-
-ifdef(`include_code', `
-// Error codes
-define(`E_BAD_COMMAND', 0x01)
-define(`E_CMD_OVERFLOW', 0x02)
-
-// Util macros to help with debugging ucode hangs etc
-define(`T_WAIT', 0)
-define(`T_MMCTX', 1)
-define(`T_STRWAIT', 2)
-define(`T_STRINIT', 3)
-define(`T_AUTO', 4)
-define(`T_CHAN', 5)
-define(`T_LOAD', 6)
-define(`T_SAVE', 7)
-define(`T_LCHAN', 8)
-define(`T_LCTXH', 9)
-
-define(`trace_set', `
-	mov $r8 0x83c
-	shl b32 $r8 6
-	clear b32 $r9
-	bset $r9 $1
-	iowr I[$r8 + 0x000] $r9		// CC_SCRATCH[7]
-')
-
-define(`trace_clr', `
-	mov $r8 0x85c
-	shl b32 $r8 6
-	clear b32 $r9
-	bset $r9 $1
-	iowr I[$r8 + 0x000] $r9		// CC_SCRATCH[7]
-')
-
-// queue_put - add request to queue
-//
-// In : $r13 queue pointer
-//	$r14 command
-//	$r15 data
-//
-queue_put:
-	// make sure we have space..
-	ld b32 $r8 D[$r13 + 0x0]	// GET
-	ld b32 $r9 D[$r13 + 0x4]	// PUT
-	xor $r8 8
-	cmpu b32 $r8 $r9
-	bra ne #queue_put_next
-		mov $r15 E_CMD_OVERFLOW
-		call #error
-		ret
-
-	// store cmd/data on queue
-	queue_put_next:
-	and $r8 $r9 7
-	shl b32 $r8 3
-	add b32 $r8 $r13
-	add b32 $r8 8
-	st b32 D[$r8 + 0x0] $r14
-	st b32 D[$r8 + 0x4] $r15
-
-	// update PUT
-	add b32 $r9 1
-	and $r9 0xf
-	st b32 D[$r13 + 0x4] $r9
-	ret
-
-// queue_get - fetch request from queue
-//
-// In : $r13 queue pointer
-//
-// Out:	$p1  clear on success (data available)
-//	$r14 command
-// 	$r15 data
-//
-queue_get:
-	bset $flags $p1
-	ld b32 $r8 D[$r13 + 0x0]	// GET
-	ld b32 $r9 D[$r13 + 0x4]	// PUT
-	cmpu b32 $r8 $r9
-	bra e #queue_get_done
-		// fetch first cmd/data pair
-		and $r9 $r8 7
-		shl b32 $r9 3
-		add b32 $r9 $r13
-		add b32 $r9 8
-		ld b32 $r14 D[$r9 + 0x0]
-		ld b32 $r15 D[$r9 + 0x4]
-
-		// update GET
-		add b32 $r8 1
-		and $r8 0xf
-		st b32 D[$r13 + 0x0] $r8
-		bclr $flags $p1
-queue_get_done:
-	ret
-
-// nv_rd32 - read 32-bit value from nv register
-//
-// In : $r14 register
-// Out: $r15 value
-//
-nv_rd32:
-	mov $r11 0x728
-	shl b32 $r11 6
-	mov b32 $r12 $r14
-	bset $r12 31			// MMIO_CTRL_PENDING
-	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
-	nv_rd32_wait:
-		iord $r12 I[$r11 + 0x000]
-		xbit $r12 $r12 31
-		bra ne #nv_rd32_wait
-	mov $r10 6			// DONE_MMIO_RD
-	call #wait_doneo
-	iord $r15 I[$r11 + 0x100]	// MMIO_RDVAL
-	ret
-
-// nv_wr32 - write 32-bit value to nv register
-//
-// In : $r14 register
-//      $r15 value
-//
-nv_wr32:
-	mov $r11 0x728
-	shl b32 $r11 6
-	iowr I[$r11 + 0x200] $r15	// MMIO_WRVAL
-	mov b32 $r12 $r14
-	bset $r12 31			// MMIO_CTRL_PENDING
-	bset $r12 30			// MMIO_CTRL_WRITE
-	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
-	nv_wr32_wait:
-		iord $r12 I[$r11 + 0x000]
-		xbit $r12 $r12 31
-		bra ne #nv_wr32_wait
-	ret
-
-// (re)set watchdog timer
-//
-// In : $r15 timeout
-//
-watchdog_reset:
-	mov $r8 0x430
-	shl b32 $r8 6
-	bset $r15 31
-	iowr I[$r8 + 0x000] $r15
-	ret
-
-// clear watchdog timer
-watchdog_clear:
-	mov $r8 0x430
-	shl b32 $r8 6
-	iowr I[$r8 + 0x000] $r0
-	ret
-
-// wait_done{z,o} - wait on FUC_DONE bit to become clear/set
-//
-// In : $r10 bit to wait on
-//
-define(`wait_done', `
-$1:
-	trace_set(T_WAIT);
-	mov $r8 0x818
-	shl b32 $r8 6
-	iowr I[$r8 + 0x000] $r10	// CC_SCRATCH[6] = wait bit
-	wait_done_$1:
-		mov $r8 0x400
-		shl b32 $r8 6
-		iord $r8 I[$r8 + 0x000]	// DONE
-		xbit $r8 $r8 $r10
-		bra $2 #wait_done_$1
-	trace_clr(T_WAIT)
-	ret
-')
-wait_done(wait_donez, ne)
-wait_done(wait_doneo, e)
-
-// mmctx_size - determine size of a mmio list transfer
-//
-// In : $r14 mmio list head
-//      $r15 mmio list tail
-// Out: $r15 transfer size (in bytes)
-//
-mmctx_size:
-	clear b32 $r9
-	nv_mmctx_size_loop:
-		ld b32 $r8 D[$r14]
-		shr b32 $r8 26
-		add b32 $r8 1
-		shl b32 $r8 2
-		add b32 $r9 $r8
-		add b32 $r14 4
-		cmpu b32 $r14 $r15
-		bra ne #nv_mmctx_size_loop
-	mov b32 $r15 $r9
-	ret
-
-// mmctx_xfer - execute a list of mmio transfers
-//
-// In : $r10 flags
-//		bit 0: direction (0 = save, 1 = load)
-//		bit 1: set if first transfer
-//		bit 2: set if last transfer
-//	$r11 base
-//	$r12 mmio list head
-//	$r13 mmio list tail
-//	$r14 multi_stride
-//	$r15 multi_mask
-//
-mmctx_xfer:
-	trace_set(T_MMCTX)
-	mov $r8 0x710
-	shl b32 $r8 6
-	clear b32 $r9
-	or $r11 $r11
-	bra e #mmctx_base_disabled
-		iowr I[$r8 + 0x000] $r11	// MMCTX_BASE
-		bset $r9 0			// BASE_EN
-	mmctx_base_disabled:
-	or $r14 $r14
-	bra e #mmctx_multi_disabled
-		iowr I[$r8 + 0x200] $r14 	// MMCTX_MULTI_STRIDE
-		iowr I[$r8 + 0x300] $r15 	// MMCTX_MULTI_MASK
-		bset $r9 1			// MULTI_EN
-	mmctx_multi_disabled:
-	add b32 $r8 0x100
-
-	xbit $r11 $r10 0
-	shl b32 $r11 16			// DIR
-	bset $r11 12			// QLIMIT = 0x10
-	xbit $r14 $r10 1
-	shl b32 $r14 17
-	or $r11 $r14			// START_TRIGGER
-	iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
-
-	// loop over the mmio list, and send requests to the hw
-	mmctx_exec_loop:
-		// wait for space in mmctx queue
-		mmctx_wait_free:
-			iord $r14 I[$r8 + 0x000] // MMCTX_CTRL
-			and $r14 0x1f
-			bra e #mmctx_wait_free
-
-		// queue up an entry
-		ld b32 $r14 D[$r12]
-		or $r14 $r9
-		iowr I[$r8 + 0x300] $r14
-		add b32 $r12 4
-		cmpu b32 $r12 $r13
-		bra ne #mmctx_exec_loop
-
-	xbit $r11 $r10 2
-	bra ne #mmctx_stop
-		// wait for queue to empty
-		mmctx_fini_wait:
-			iord $r11 I[$r8 + 0x000]	// MMCTX_CTRL
-			and $r11 0x1f
-			cmpu b32 $r11 0x10
-			bra ne #mmctx_fini_wait
-		mov $r10 2				// DONE_MMCTX
-		call #wait_donez
-		bra #mmctx_done
-	mmctx_stop:
-		xbit $r11 $r10 0
-		shl b32 $r11 16			// DIR
-		bset $r11 12			// QLIMIT = 0x10
-		bset $r11 18			// STOP_TRIGGER
-		iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
-		mmctx_stop_wait:
-			// wait for STOP_TRIGGER to clear
-			iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
-			xbit $r11 $r11 18
-			bra ne #mmctx_stop_wait
-	mmctx_done:
-	trace_clr(T_MMCTX)
-	ret
-
-// Wait for DONE_STRAND
-//
-strand_wait:
-	push $r10
-	mov $r10 2
-	call #wait_donez
-	pop $r10
-	ret
-
-// unknown - call before issuing strand commands
-//
-strand_pre:
-	mov $r8 0x4afc
-	sethi $r8 0x20000
-	mov $r9 0xc
-	iowr I[$r8] $r9
-	call #strand_wait
-	ret
-
-// unknown - call after issuing strand commands
-//
-strand_post:
-	mov $r8 0x4afc
-	sethi $r8 0x20000
-	mov $r9 0xd
-	iowr I[$r8] $r9
-	call #strand_wait
-	ret
-
-// Selects strand set?!
-//
-// In: $r14 id
-//
-strand_set:
-	mov $r10 0x4ffc
-	sethi $r10 0x20000
-	sub b32 $r11 $r10 0x500
-	mov $r12 0xf
-	iowr I[$r10 + 0x000] $r12		// 0x93c = 0xf
-	mov $r12 0xb
-	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xb
-	call #strand_wait
-	iowr I[$r10 + 0x000] $r14		// 0x93c = <id>
-	mov $r12 0xa
-	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xa
-	call #strand_wait
-	ret
-
-// Initialise strand context data
-//
-// In : $r15 context base
-// Out: $r15 context size (in bytes)
-//
-// Strandset(?) 3 hardcoded currently
-//
-strand_ctx_init:
-	trace_set(T_STRINIT)
-	call #strand_pre
-	mov $r14 3
-	call #strand_set
-	mov $r10 0x46fc
-	sethi $r10 0x20000
-	add b32 $r11 $r10 0x400
-	iowr I[$r10 + 0x100] $r0	// STRAND_FIRST_GENE = 0
-	mov $r12 1
-	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_FIRST_GENE
-	call #strand_wait
-	sub b32 $r12 $r0 1
-	iowr I[$r10 + 0x000] $r12	// STRAND_GENE_CNT = 0xffffffff
-	mov $r12 2
-	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_GENE_CNT
-	call #strand_wait
-	call #strand_post
-
-	// read the size of each strand, poke the context offset of
-	// each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
-	// about it later then.
-	mov $r8 0x880
-	shl b32 $r8 6
-	iord $r9 I[$r8 + 0x000]		// STRANDS
-	add b32 $r8 0x2200
-	shr b32 $r14 $r15 8
-	ctx_init_strand_loop:
-		iowr I[$r8 + 0x000] $r14	// STRAND_SAVE_SWBASE
-		iowr I[$r8 + 0x100] $r14	// STRAND_LOAD_SWBASE
-		iord $r10 I[$r8 + 0x200]	// STRAND_SIZE
-		shr b32 $r10 6
-		add b32 $r10 1
-		add b32 $r14 $r10
-		add b32 $r8 4
-		sub b32 $r9 1
-		bra ne #ctx_init_strand_loop
-
-	shl b32 $r14 8
-	sub b32 $r15 $r14 $r15
-	trace_clr(T_STRINIT)
-	ret
-')
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/nve0.fuc	1969-12-31 19:00:00.000000000 -0500
@@ -1,400 +0,0 @@
-/* fuc microcode util functions for nve0 PGRAPH
- *
- * Copyright 2011 Red Hat Inc.
- *
- * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-define(`mmctx_data', `.b32 eval((($2 - 1) << 26) | $1)')
-define(`queue_init', `.skip eval((2 * 4) + ((8 * 4) * 2))')
-
-ifdef(`include_code', `
-// Error codes
-define(`E_BAD_COMMAND', 0x01)
-define(`E_CMD_OVERFLOW', 0x02)
-
-// Util macros to help with debugging ucode hangs etc
-define(`T_WAIT', 0)
-define(`T_MMCTX', 1)
-define(`T_STRWAIT', 2)
-define(`T_STRINIT', 3)
-define(`T_AUTO', 4)
-define(`T_CHAN', 5)
-define(`T_LOAD', 6)
-define(`T_SAVE', 7)
-define(`T_LCHAN', 8)
-define(`T_LCTXH', 9)
-
-define(`trace_set', `
-	mov $r8 0x83c
-	shl b32 $r8 6
-	clear b32 $r9
-	bset $r9 $1
-	iowr I[$r8 + 0x000] $r9		// CC_SCRATCH[7]
-')
-
-define(`trace_clr', `
-	mov $r8 0x85c
-	shl b32 $r8 6
-	clear b32 $r9
-	bset $r9 $1
-	iowr I[$r8 + 0x000] $r9		// CC_SCRATCH[7]
-')
-
-// queue_put - add request to queue
-//
-// In : $r13 queue pointer
-//	$r14 command
-//	$r15 data
-//
-queue_put:
-	// make sure we have space..
-	ld b32 $r8 D[$r13 + 0x0]	// GET
-	ld b32 $r9 D[$r13 + 0x4]	// PUT
-	xor $r8 8
-	cmpu b32 $r8 $r9
-	bra ne #queue_put_next
-		mov $r15 E_CMD_OVERFLOW
-		call #error
-		ret
-
-	// store cmd/data on queue
-	queue_put_next:
-	and $r8 $r9 7
-	shl b32 $r8 3
-	add b32 $r8 $r13
-	add b32 $r8 8
-	st b32 D[$r8 + 0x0] $r14
-	st b32 D[$r8 + 0x4] $r15
-
-	// update PUT
-	add b32 $r9 1
-	and $r9 0xf
-	st b32 D[$r13 + 0x4] $r9
-	ret
-
-// queue_get - fetch request from queue
-//
-// In : $r13 queue pointer
-//
-// Out:	$p1  clear on success (data available)
-//	$r14 command
-// 	$r15 data
-//
-queue_get:
-	bset $flags $p1
-	ld b32 $r8 D[$r13 + 0x0]	// GET
-	ld b32 $r9 D[$r13 + 0x4]	// PUT
-	cmpu b32 $r8 $r9
-	bra e #queue_get_done
-		// fetch first cmd/data pair
-		and $r9 $r8 7
-		shl b32 $r9 3
-		add b32 $r9 $r13
-		add b32 $r9 8
-		ld b32 $r14 D[$r9 + 0x0]
-		ld b32 $r15 D[$r9 + 0x4]
-
-		// update GET
-		add b32 $r8 1
-		and $r8 0xf
-		st b32 D[$r13 + 0x0] $r8
-		bclr $flags $p1
-queue_get_done:
-	ret
-
-// nv_rd32 - read 32-bit value from nv register
-//
-// In : $r14 register
-// Out: $r15 value
-//
-nv_rd32:
-	mov $r11 0x728
-	shl b32 $r11 6
-	mov b32 $r12 $r14
-	bset $r12 31			// MMIO_CTRL_PENDING
-	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
-	nv_rd32_wait:
-		iord $r12 I[$r11 + 0x000]
-		xbit $r12 $r12 31
-		bra ne #nv_rd32_wait
-	mov $r10 6			// DONE_MMIO_RD
-	call #wait_doneo
-	iord $r15 I[$r11 + 0x100]	// MMIO_RDVAL
-	ret
-
-// nv_wr32 - write 32-bit value to nv register
-//
-// In : $r14 register
-//      $r15 value
-//
-nv_wr32:
-	mov $r11 0x728
-	shl b32 $r11 6
-	iowr I[$r11 + 0x200] $r15	// MMIO_WRVAL
-	mov b32 $r12 $r14
-	bset $r12 31			// MMIO_CTRL_PENDING
-	bset $r12 30			// MMIO_CTRL_WRITE
-	iowr I[$r11 + 0x000] $r12	// MMIO_CTRL
-	nv_wr32_wait:
-		iord $r12 I[$r11 + 0x000]
-		xbit $r12 $r12 31
-		bra ne #nv_wr32_wait
-	ret
-
-// (re)set watchdog timer
-//
-// In : $r15 timeout
-//
-watchdog_reset:
-	mov $r8 0x430
-	shl b32 $r8 6
-	bset $r15 31
-	iowr I[$r8 + 0x000] $r15
-	ret
-
-// clear watchdog timer
-watchdog_clear:
-	mov $r8 0x430
-	shl b32 $r8 6
-	iowr I[$r8 + 0x000] $r0
-	ret
-
-// wait_done{z,o} - wait on FUC_DONE bit to become clear/set
-//
-// In : $r10 bit to wait on
-//
-define(`wait_done', `
-$1:
-	trace_set(T_WAIT);
-	mov $r8 0x818
-	shl b32 $r8 6
-	iowr I[$r8 + 0x000] $r10	// CC_SCRATCH[6] = wait bit
-	wait_done_$1:
-		mov $r8 0x400
-		shl b32 $r8 6
-		iord $r8 I[$r8 + 0x000]	// DONE
-		xbit $r8 $r8 $r10
-		bra $2 #wait_done_$1
-	trace_clr(T_WAIT)
-	ret
-')
-wait_done(wait_donez, ne)
-wait_done(wait_doneo, e)
-
-// mmctx_size - determine size of a mmio list transfer
-//
-// In : $r14 mmio list head
-//      $r15 mmio list tail
-// Out: $r15 transfer size (in bytes)
-//
-mmctx_size:
-	clear b32 $r9
-	nv_mmctx_size_loop:
-		ld b32 $r8 D[$r14]
-		shr b32 $r8 26
-		add b32 $r8 1
-		shl b32 $r8 2
-		add b32 $r9 $r8
-		add b32 $r14 4
-		cmpu b32 $r14 $r15
-		bra ne #nv_mmctx_size_loop
-	mov b32 $r15 $r9
-	ret
-
-// mmctx_xfer - execute a list of mmio transfers
-//
-// In : $r10 flags
-//		bit 0: direction (0 = save, 1 = load)
-//		bit 1: set if first transfer
-//		bit 2: set if last transfer
-//	$r11 base
-//	$r12 mmio list head
-//	$r13 mmio list tail
-//	$r14 multi_stride
-//	$r15 multi_mask
-//
-mmctx_xfer:
-	trace_set(T_MMCTX)
-	mov $r8 0x710
-	shl b32 $r8 6
-	clear b32 $r9
-	or $r11 $r11
-	bra e #mmctx_base_disabled
-		iowr I[$r8 + 0x000] $r11	// MMCTX_BASE
-		bset $r9 0			// BASE_EN
-	mmctx_base_disabled:
-	or $r14 $r14
-	bra e #mmctx_multi_disabled
-		iowr I[$r8 + 0x200] $r14 	// MMCTX_MULTI_STRIDE
-		iowr I[$r8 + 0x300] $r15 	// MMCTX_MULTI_MASK
-		bset $r9 1			// MULTI_EN
-	mmctx_multi_disabled:
-	add b32 $r8 0x100
-
-	xbit $r11 $r10 0
-	shl b32 $r11 16			// DIR
-	bset $r11 12			// QLIMIT = 0x10
-	xbit $r14 $r10 1
-	shl b32 $r14 17
-	or $r11 $r14			// START_TRIGGER
-	iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
-
-	// loop over the mmio list, and send requests to the hw
-	mmctx_exec_loop:
-		// wait for space in mmctx queue
-		mmctx_wait_free:
-			iord $r14 I[$r8 + 0x000] // MMCTX_CTRL
-			and $r14 0x1f
-			bra e #mmctx_wait_free
-
-		// queue up an entry
-		ld b32 $r14 D[$r12]
-		or $r14 $r9
-		iowr I[$r8 + 0x300] $r14
-		add b32 $r12 4
-		cmpu b32 $r12 $r13
-		bra ne #mmctx_exec_loop
-
-	xbit $r11 $r10 2
-	bra ne #mmctx_stop
-		// wait for queue to empty
-		mmctx_fini_wait:
-			iord $r11 I[$r8 + 0x000]	// MMCTX_CTRL
-			and $r11 0x1f
-			cmpu b32 $r11 0x10
-			bra ne #mmctx_fini_wait
-		mov $r10 2				// DONE_MMCTX
-		call #wait_donez
-		bra #mmctx_done
-	mmctx_stop:
-		xbit $r11 $r10 0
-		shl b32 $r11 16			// DIR
-		bset $r11 12			// QLIMIT = 0x10
-		bset $r11 18			// STOP_TRIGGER
-		iowr I[$r8 + 0x000] $r11	// MMCTX_CTRL
-		mmctx_stop_wait:
-			// wait for STOP_TRIGGER to clear
-			iord $r11 I[$r8 + 0x000] // MMCTX_CTRL
-			xbit $r11 $r11 18
-			bra ne #mmctx_stop_wait
-	mmctx_done:
-	trace_clr(T_MMCTX)
-	ret
-
-// Wait for DONE_STRAND
-//
-strand_wait:
-	push $r10
-	mov $r10 2
-	call #wait_donez
-	pop $r10
-	ret
-
-// unknown - call before issuing strand commands
-//
-strand_pre:
-	mov $r8 0x4afc
-	sethi $r8 0x20000
-	mov $r9 0xc
-	iowr I[$r8] $r9
-	call #strand_wait
-	ret
-
-// unknown - call after issuing strand commands
-//
-strand_post:
-	mov $r8 0x4afc
-	sethi $r8 0x20000
-	mov $r9 0xd
-	iowr I[$r8] $r9
-	call #strand_wait
-	ret
-
-// Selects strand set?!
-//
-// In: $r14 id
-//
-strand_set:
-	mov $r10 0x4ffc
-	sethi $r10 0x20000
-	sub b32 $r11 $r10 0x500
-	mov $r12 0xf
-	iowr I[$r10 + 0x000] $r12		// 0x93c = 0xf
-	mov $r12 0xb
-	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xb
-	call #strand_wait
-	iowr I[$r10 + 0x000] $r14		// 0x93c = <id>
-	mov $r12 0xa
-	iowr I[$r11 + 0x000] $r12		// 0x928 = 0xa
-	call #strand_wait
-	ret
-
-// Initialise strand context data
-//
-// In : $r15 context base
-// Out: $r15 context size (in bytes)
-//
-// Strandset(?) 3 hardcoded currently
-//
-strand_ctx_init:
-	trace_set(T_STRINIT)
-	call #strand_pre
-	mov $r14 3
-	call #strand_set
-	mov $r10 0x46fc
-	sethi $r10 0x20000
-	add b32 $r11 $r10 0x400
-	iowr I[$r10 + 0x100] $r0	// STRAND_FIRST_GENE = 0
-	mov $r12 1
-	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_FIRST_GENE
-	call #strand_wait
-	sub b32 $r12 $r0 1
-	iowr I[$r10 + 0x000] $r12	// STRAND_GENE_CNT = 0xffffffff
-	mov $r12 2
-	iowr I[$r11 + 0x000] $r12	// STRAND_CMD = LATCH_GENE_CNT
-	call #strand_wait
-	call #strand_post
-
-	// read the size of each strand, poke the context offset of
-	// each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
-	// about it later then.
-	mov $r8 0x880
-	shl b32 $r8 6
-	iord $r9 I[$r8 + 0x000]		// STRANDS
-	add b32 $r8 0x2200
-	shr b32 $r14 $r15 8
-	ctx_init_strand_loop:
-		iowr I[$r8 + 0x000] $r14	// STRAND_SAVE_SWBASE
-		iowr I[$r8 + 0x100] $r14	// STRAND_LOAD_SWBASE
-		iord $r10 I[$r8 + 0x200]	// STRAND_SIZE
-		shr b32 $r10 6
-		add b32 $r10 1
-		add b32 $r14 $r10
-		add b32 $r8 4
-		sub b32 $r9 1
-		bra ne #ctx_init_strand_loop
-
-	shl b32 $r14 8
-	sub b32 $r15 $r14 $r15
-	trace_clr(T_STRINIT)
-	ret
-')
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,7 @@
+#ifndef __NVKM_GRAPH_OS_H__
+#define __NVKM_GRAPH_OS_H__
+
+#define E_BAD_COMMAND  0x00000001
+#define E_CMD_OVERFLOW 0x00000002
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -186,13 +186,6 @@ nv50_graph_cclass = {
  * PGRAPH engine/subdev functions
  ******************************************************************************/
 
-static int
-nv50_graph_tlb_flush(struct nouveau_engine *engine)
-{
-	nv50_vm_flush_engine(&engine->base, 0x00);
-	return 0;
-}
-
 static const struct nouveau_bitfield nv50_pgraph_status[] = {
 	{ 0x00000001, "BUSY" }, /* set when any bit is set */
 	{ 0x00000002, "DISPATCH" },
@@ -302,8 +295,10 @@ nv84_graph_tlb_flush(struct nouveau_engi
 				nv_rd32(priv, 0x400388));
 	}
 
-	nv50_vm_flush_engine(&engine->base, 0x00);
 
+	nv_wr32(priv, 0x100c80, 0x00000001);
+	if (!nv_wait(priv, 0x100c80, 0x00000001, 0x00000000))
+		nv_error(priv, "vm flush timeout\n");
 	nv_mask(priv, 0x400500, 0x00000001, 0x00000001);
 	spin_unlock_irqrestore(&priv->lock, flags);
 	return timeout ? -EBUSY : 0;
@@ -857,10 +852,9 @@ nv50_graph_ctor(struct nouveau_object *p
 
 	};
 
-	if (nv_device(priv)->chipset == 0x50 ||
-	    nv_device(priv)->chipset == 0xac)
-		nv_engine(priv)->tlb_flush = nv50_graph_tlb_flush;
-	else
+	/* unfortunate hw bug workaround... */
+	if (nv_device(priv)->chipset != 0x50 &&
+	    nv_device(priv)->chipset != 0xac)
 		nv_engine(priv)->tlb_flush = nv84_graph_tlb_flush;
 
 	spin_lock_init(&priv->lock);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c	2013-07-01 10:31:58.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c	2013-08-31 17:51:19.000000000 -0400
@@ -23,14 +23,12 @@
  */
 
 #include "nvc0.h"
-#include "fuc/hubnvc0.fuc.h"
-#include "fuc/gpcnvc0.fuc.h"
 
 /*******************************************************************************
  * Graphics object classes
  ******************************************************************************/
 
-static struct nouveau_oclass
+struct nouveau_oclass
 nvc0_graph_sclass[] = {
 	{ 0x902d, &nouveau_object_ofuncs },
 	{ 0x9039, &nouveau_object_ofuncs },
@@ -39,40 +37,6 @@ nvc0_graph_sclass[] = {
 	{}
 };
 
-static struct nouveau_oclass
-nvc1_graph_sclass[] = {
-	{ 0x902d, &nouveau_object_ofuncs },
-	{ 0x9039, &nouveau_object_ofuncs },
-	{ 0x9097, &nouveau_object_ofuncs },
-	{ 0x90c0, &nouveau_object_ofuncs },
-	{ 0x9197, &nouveau_object_ofuncs },
-	{}
-};
-
-static struct nouveau_oclass
-nvc8_graph_sclass[] = {
-	{ 0x902d, &nouveau_object_ofuncs },
-	{ 0x9039, &nouveau_object_ofuncs },
-	{ 0x9097, &nouveau_object_ofuncs },
-	{ 0x90c0, &nouveau_object_ofuncs },
-	{ 0x9197, &nouveau_object_ofuncs },
-	{ 0x9297, &nouveau_object_ofuncs },
-	{}
-};
-
-u64
-nvc0_graph_units(struct nouveau_graph *graph)
-{
-	struct nvc0_graph_priv *priv = (void *)graph;
-	u64 cfg;
-
-	cfg  = (u32)priv->gpc_nr;
-	cfg |= (u32)priv->tpc_total << 8;
-	cfg |= (u64)priv->rop_nr << 32;
-
-	return cfg;
-}
-
 /*******************************************************************************
  * PGRAPH context
  ******************************************************************************/
@@ -181,60 +145,308 @@ nvc0_graph_context_dtor(struct nouveau_o
 	nouveau_graph_context_destroy(&chan->base);
 }
 
-static struct nouveau_oclass
-nvc0_graph_cclass = {
-	.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = nvc0_graph_context_ctor,
-		.dtor = nvc0_graph_context_dtor,
-		.init = _nouveau_graph_context_init,
-		.fini = _nouveau_graph_context_fini,
-		.rd32 = _nouveau_graph_context_rd32,
-		.wr32 = _nouveau_graph_context_wr32,
-	},
-};
-
 /*******************************************************************************
  * PGRAPH engine/subdev functions
  ******************************************************************************/
 
-static void
-nvc0_graph_ctxctl_debug_unit(struct nvc0_graph_priv *priv, u32 base)
+struct nvc0_graph_init
+nvc0_graph_init_regs[] = {
+	{ 0x400080,   1, 0x04, 0x003083c2 },
+	{ 0x400088,   1, 0x04, 0x00006fe7 },
+	{ 0x40008c,   1, 0x04, 0x00000000 },
+	{ 0x400090,   1, 0x04, 0x00000030 },
+	{ 0x40013c,   1, 0x04, 0x013901f7 },
+	{ 0x400140,   1, 0x04, 0x00000100 },
+	{ 0x400144,   1, 0x04, 0x00000000 },
+	{ 0x400148,   1, 0x04, 0x00000110 },
+	{ 0x400138,   1, 0x04, 0x00000000 },
+	{ 0x400130,   2, 0x04, 0x00000000 },
+	{ 0x400124,   1, 0x04, 0x00000002 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc0_graph_init_unk40xx[] = {
+	{ 0x40415c,   1, 0x04, 0x00000000 },
+	{ 0x404170,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc0_graph_init_unk44xx[] = {
+	{ 0x404488,   2, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc0_graph_init_unk78xx[] = {
+	{ 0x407808,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc0_graph_init_unk60xx[] = {
+	{ 0x406024,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc0_graph_init_unk58xx[] = {
+	{ 0x405844,   1, 0x04, 0x00ffffff },
+	{ 0x405850,   1, 0x04, 0x00000000 },
+	{ 0x405908,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc0_graph_init_unk80xx[] = {
+	{ 0x40803c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc0_graph_init_gpc[] = {
+	{ 0x4184a0,   1, 0x04, 0x00000000 },
+	{ 0x418604,   1, 0x04, 0x00000000 },
+	{ 0x418680,   1, 0x04, 0x00000000 },
+	{ 0x418714,   1, 0x04, 0x80000000 },
+	{ 0x418384,   1, 0x04, 0x00000000 },
+	{ 0x418814,   3, 0x04, 0x00000000 },
+	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{ 0x4188c8,   1, 0x04, 0x80000000 },
+	{ 0x4188cc,   1, 0x04, 0x00000000 },
+	{ 0x4188d0,   1, 0x04, 0x00010000 },
+	{ 0x4188d4,   1, 0x04, 0x00000001 },
+	{ 0x418910,   1, 0x04, 0x00010001 },
+	{ 0x418914,   1, 0x04, 0x00000301 },
+	{ 0x418918,   1, 0x04, 0x00800000 },
+	{ 0x418980,   1, 0x04, 0x77777770 },
+	{ 0x418984,   3, 0x04, 0x77777777 },
+	{ 0x418c04,   1, 0x04, 0x00000000 },
+	{ 0x418c88,   1, 0x04, 0x00000000 },
+	{ 0x418d00,   1, 0x04, 0x00000000 },
+	{ 0x418f08,   1, 0x04, 0x00000000 },
+	{ 0x418e00,   1, 0x04, 0x00000050 },
+	{ 0x418e08,   1, 0x04, 0x00000000 },
+	{ 0x41900c,   1, 0x04, 0x00000000 },
+	{ 0x419018,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvc0_graph_init_tpc[] = {
+	{ 0x419d08,   2, 0x04, 0x00000000 },
+	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{ 0x419ab0,   1, 0x04, 0x00000000 },
+	{ 0x419ab8,   1, 0x04, 0x000000e7 },
+	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{ 0x41980c,   3, 0x04, 0x00000000 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x41984c,   1, 0x04, 0x00005bc5 },
+	{ 0x419850,   4, 0x04, 0x00000000 },
+	{ 0x419c98,   1, 0x04, 0x00000000 },
+	{ 0x419ca8,   1, 0x04, 0x80000000 },
+	{ 0x419cb4,   1, 0x04, 0x00000000 },
+	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
+	{ 0x419cbc,   1, 0x04, 0x28137606 },
+	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{ 0x419bd4,   1, 0x04, 0x00800000 },
+	{ 0x419bdc,   1, 0x04, 0x00000000 },
+	{ 0x419d2c,   1, 0x04, 0x00000000 },
+	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{ 0x419e00,   1, 0x04, 0x00000000 },
+	{ 0x419ea0,   1, 0x04, 0x00000000 },
+	{ 0x419ea4,   1, 0x04, 0x00000100 },
+	{ 0x419ea8,   1, 0x04, 0x00001100 },
+	{ 0x419eac,   1, 0x04, 0x11100702 },
+	{ 0x419eb0,   1, 0x04, 0x00000003 },
+	{ 0x419eb4,   4, 0x04, 0x00000000 },
+	{ 0x419ec8,   1, 0x04, 0x06060618 },
+	{ 0x419ed0,   1, 0x04, 0x0eff0e38 },
+	{ 0x419ed4,   1, 0x04, 0x011104f1 },
+	{ 0x419edc,   1, 0x04, 0x00000000 },
+	{ 0x419f00,   1, 0x04, 0x00000000 },
+	{ 0x419f2c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc0_graph_init_unk88xx[] = {
+	{ 0x40880c,   1, 0x04, 0x00000000 },
+	{ 0x408910,   9, 0x04, 0x00000000 },
+	{ 0x408950,   1, 0x04, 0x00000000 },
+	{ 0x408954,   1, 0x04, 0x0000ffff },
+	{ 0x408984,   1, 0x04, 0x00000000 },
+	{ 0x408988,   1, 0x04, 0x08040201 },
+	{ 0x40898c,   1, 0x04, 0x80402010 },
+	{}
+};
+
+struct nvc0_graph_init
+nvc0_graph_tpc_0[] = {
+	{ 0x50405c,   1, 0x04, 0x00000001 },
+	{}
+};
+
+void
+nvc0_graph_mmio(struct nvc0_graph_priv *priv, struct nvc0_graph_init *init)
 {
-	nv_error(priv, "%06x - done 0x%08x\n", base,
-		 nv_rd32(priv, base + 0x400));
-	nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
-		 nv_rd32(priv, base + 0x800), nv_rd32(priv, base + 0x804),
-		 nv_rd32(priv, base + 0x808), nv_rd32(priv, base + 0x80c));
-	nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
-		 nv_rd32(priv, base + 0x810), nv_rd32(priv, base + 0x814),
-		 nv_rd32(priv, base + 0x818), nv_rd32(priv, base + 0x81c));
+	for (; init && init->count; init++) {
+		u32 addr = init->addr, i;
+		for (i = 0; i < init->count; i++) {
+			nv_wr32(priv, addr, init->data);
+			addr += init->pitch;
+		}
+	}
 }
 
 void
-nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *priv)
+nvc0_graph_icmd(struct nvc0_graph_priv *priv, struct nvc0_graph_init *init)
 {
-	u32 gpcnr = nv_rd32(priv, 0x409604) & 0xffff;
-	u32 gpc;
+	u32 addr, data;
+	int i, j;
 
-	nvc0_graph_ctxctl_debug_unit(priv, 0x409000);
-	for (gpc = 0; gpc < gpcnr; gpc++)
-		nvc0_graph_ctxctl_debug_unit(priv, 0x502000 + (gpc * 0x8000));
+	nv_wr32(priv, 0x400208, 0x80000000);
+	for (i = 0; init->count; init++, i++) {
+		if (!i || data != init->data) {
+			nv_wr32(priv, 0x400204, init->data);
+			data = init->data;
+		}
+
+		addr = init->addr;
+		for (j = 0; j < init->count; j++) {
+			nv_wr32(priv, 0x400200, addr);
+			addr += init->pitch;
+			while (nv_rd32(priv, 0x400700) & 0x00000002) {}
+		}
+	}
+	nv_wr32(priv, 0x400208, 0x00000000);
+}
+
+void
+nvc0_graph_mthd(struct nvc0_graph_priv *priv, struct nvc0_graph_mthd *mthds)
+{
+	struct nvc0_graph_mthd *mthd;
+	struct nvc0_graph_init *init;
+	int i = 0, j;
+	u32 data;
+
+	while ((mthd = &mthds[i++]) && (init = mthd->init)) {
+		u32  addr = 0x80000000 | mthd->oclass;
+		for (data = 0; init->count; init++) {
+			if (data != init->data) {
+				nv_wr32(priv, 0x40448c, init->data);
+				data = init->data;
+			}
+
+			addr = (addr & 0x8000ffff) | (init->addr << 14);
+			for (j = 0; j < init->count; j++) {
+				nv_wr32(priv, 0x404488, addr);
+				addr += init->pitch << 14;
+			}
+		}
+	}
+}
+
+u64
+nvc0_graph_units(struct nouveau_graph *graph)
+{
+	struct nvc0_graph_priv *priv = (void *)graph;
+	u64 cfg;
+
+	cfg  = (u32)priv->gpc_nr;
+	cfg |= (u32)priv->tpc_total << 8;
+	cfg |= (u64)priv->rop_nr << 32;
+
+	return cfg;
+}
+
+static const struct nouveau_enum nve0_sked_error[] = {
+	{ 7, "CONSTANT_BUFFER_SIZE" },
+	{ 9, "LOCAL_MEMORY_SIZE_POS" },
+	{ 10, "LOCAL_MEMORY_SIZE_NEG" },
+	{ 11, "WARP_CSTACK_SIZE" },
+	{ 12, "TOTAL_TEMP_SIZE" },
+	{ 13, "REGISTER_COUNT" },
+	{ 18, "TOTAL_THREADS" },
+	{ 20, "PROGRAM_OFFSET" },
+	{ 21, "SHARED_MEMORY_SIZE" },
+	{ 25, "SHARED_CONFIG_TOO_SMALL" },
+	{ 26, "TOTAL_REGISTER_COUNT" },
+	{}
+};
+
+static const struct nouveau_enum nvc0_gpc_rop_error[] = {
+	{ 1, "RT_PITCH_OVERRUN" },
+	{ 4, "RT_WIDTH_OVERRUN" },
+	{ 5, "RT_HEIGHT_OVERRUN" },
+	{ 7, "ZETA_STORAGE_TYPE_MISMATCH" },
+	{ 8, "RT_STORAGE_TYPE_MISMATCH" },
+	{ 10, "RT_LINEAR_MISMATCH" },
+	{}
+};
+
+static void
+nvc0_graph_trap_gpc_rop(struct nvc0_graph_priv *priv, int gpc)
+{
+	u32 trap[4];
+	int i;
+
+	trap[0] = nv_rd32(priv, GPC_UNIT(gpc, 0x0420));
+	trap[1] = nv_rd32(priv, GPC_UNIT(gpc, 0x0434));
+	trap[2] = nv_rd32(priv, GPC_UNIT(gpc, 0x0438));
+	trap[3] = nv_rd32(priv, GPC_UNIT(gpc, 0x043c));
+
+	nv_error(priv, "GPC%d/PROP trap:", gpc);
+	for (i = 0; i <= 29; ++i) {
+		if (!(trap[0] & (1 << i)))
+			continue;
+		pr_cont(" ");
+		nouveau_enum_print(nvc0_gpc_rop_error, i);
+	}
+	pr_cont("\n");
+
+	nv_error(priv, "x = %u, y = %u, format = %x, storage type = %x\n",
+		 trap[1] & 0xffff, trap[1] >> 16, (trap[2] >> 8) & 0x3f,
+		 trap[3] & 0xff);
+	nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
 }
 
+static const struct nouveau_enum nvc0_mp_warp_error[] = {
+	{ 0x00, "NO_ERROR" },
+	{ 0x01, "STACK_MISMATCH" },
+	{ 0x05, "MISALIGNED_PC" },
+	{ 0x08, "MISALIGNED_GPR" },
+	{ 0x09, "INVALID_OPCODE" },
+	{ 0x0d, "GPR_OUT_OF_BOUNDS" },
+	{ 0x0e, "MEM_OUT_OF_BOUNDS" },
+	{ 0x0f, "UNALIGNED_MEM_ACCESS" },
+	{ 0x11, "INVALID_PARAM" },
+	{}
+};
+
+static const struct nouveau_bitfield nvc0_mp_global_error[] = {
+	{ 0x00000004, "MULTIPLE_WARP_ERRORS" },
+	{ 0x00000008, "OUT_OF_STACK_SPACE" },
+	{}
+};
+
 static void
-nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
+nvc0_graph_trap_mp(struct nvc0_graph_priv *priv, int gpc, int tpc)
 {
-	u32 ustat = nv_rd32(priv, 0x409c18);
+	u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x648));
+	u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x650));
 
-	if (ustat & 0x00000001)
-		nv_error(priv, "CTXCTRL ucode error\n");
-	if (ustat & 0x00080000)
-		nv_error(priv, "CTXCTRL watchdog timeout\n");
-	if (ustat & ~0x00080001)
-		nv_error(priv, "CTXCTRL 0x%08x\n", ustat);
+	nv_error(priv, "GPC%i/TPC%i/MP trap:", gpc, tpc);
+	nouveau_bitfield_print(nvc0_mp_global_error, gerr);
+	if (werr) {
+		pr_cont(" ");
+		nouveau_enum_print(nvc0_mp_warp_error, werr & 0xffff);
+	}
+	pr_cont("\n");
 
-	nvc0_graph_ctxctl_debug(priv);
-	nv_wr32(priv, 0x409c20, ustat);
+	nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x648), 0x00000000);
+	nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x650), gerr);
 }
 
 static void
@@ -246,18 +458,11 @@ nvc0_graph_trap_tpc(struct nvc0_graph_pr
 		u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0224));
 		nv_error(priv, "GPC%d/TPC%d/TEX: 0x%08x\n", gpc, tpc, trap);
 		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0224), 0xc0000000);
-		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000001);
 		stat &= ~0x00000001;
 	}
 
 	if (stat & 0x00000002) {
-		u32 trap0 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0644));
-		u32 trap1 = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x064c));
-		nv_error(priv, "GPC%d/TPC%d/MP: 0x%08x 0x%08x\n",
-			       gpc, tpc, trap0, trap1);
-		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0644), 0x001ffffe);
-		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x064c), 0x0000000f);
-		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000002);
+		nvc0_graph_trap_mp(priv, gpc, tpc);
 		stat &= ~0x00000002;
 	}
 
@@ -265,7 +470,6 @@ nvc0_graph_trap_tpc(struct nvc0_graph_pr
 		u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x0084));
 		nv_error(priv, "GPC%d/TPC%d/POLY: 0x%08x\n", gpc, tpc, trap);
 		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0084), 0xc0000000);
-		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000004);
 		stat &= ~0x00000004;
 	}
 
@@ -273,13 +477,11 @@ nvc0_graph_trap_tpc(struct nvc0_graph_pr
 		u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tpc, 0x048c));
 		nv_error(priv, "GPC%d/TPC%d/L1C: 0x%08x\n", gpc, tpc, trap);
 		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x048c), 0xc0000000);
-		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), 0x00000008);
 		stat &= ~0x00000008;
 	}
 
 	if (stat) {
 		nv_error(priv, "GPC%d/TPC%d/0x%08x: unknown\n", gpc, tpc, stat);
-		nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x0508), stat);
 	}
 }
 
@@ -290,10 +492,7 @@ nvc0_graph_trap_gpc(struct nvc0_graph_pr
 	int tpc;
 
 	if (stat & 0x00000001) {
-		u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0420));
-		nv_error(priv, "GPC%d/PROP: 0x%08x\n", gpc, trap);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000001);
+		nvc0_graph_trap_gpc_rop(priv, gpc);
 		stat &= ~0x00000001;
 	}
 
@@ -301,7 +500,6 @@ nvc0_graph_trap_gpc(struct nvc0_graph_pr
 		u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0900));
 		nv_error(priv, "GPC%d/ZCULL: 0x%08x\n", gpc, trap);
 		nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000002);
 		stat &= ~0x00000002;
 	}
 
@@ -309,7 +507,6 @@ nvc0_graph_trap_gpc(struct nvc0_graph_pr
 		u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x1028));
 		nv_error(priv, "GPC%d/CCACHE: 0x%08x\n", gpc, trap);
 		nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000004);
 		stat &= ~0x00000004;
 	}
 
@@ -317,7 +514,6 @@ nvc0_graph_trap_gpc(struct nvc0_graph_pr
 		u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0824));
 		nv_error(priv, "GPC%d/ESETUP: 0x%08x\n", gpc, trap);
 		nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0x00000008);
 		stat &= ~0x00000009;
 	}
 
@@ -332,7 +528,6 @@ nvc0_graph_trap_gpc(struct nvc0_graph_pr
 
 	if (stat) {
 		nv_error(priv, "GPC%d/0x%08x: unknown\n", gpc, stat);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), stat);
 	}
 }
 
@@ -340,7 +535,7 @@ static void
 nvc0_graph_trap_intr(struct nvc0_graph_priv *priv)
 {
 	u32 trap = nv_rd32(priv, 0x400108);
-	int rop, gpc;
+	int rop, gpc, i;
 
 	if (trap & 0x00000001) {
 		u32 stat = nv_rd32(priv, 0x404000);
@@ -390,6 +585,24 @@ nvc0_graph_trap_intr(struct nvc0_graph_p
 		trap &= ~0x00000080;
 	}
 
+	if (trap & 0x00000100) {
+		u32 stat = nv_rd32(priv, 0x407020);
+
+		nv_error(priv, "SKED:");
+		for (i = 0; i <= 29; ++i) {
+			if (!(stat & (1 << i)))
+				continue;
+			pr_cont(" ");
+			nouveau_enum_print(nve0_sked_error, i);
+		}
+		pr_cont("\n");
+
+		if (stat & 0x3fffffff)
+			nv_wr32(priv, 0x407020, 0x40000000);
+		nv_wr32(priv, 0x400108, 0x00000100);
+		trap &= ~0x00000100;
+	}
+
 	if (trap & 0x01000000) {
 		u32 stat = nv_rd32(priv, 0x400118);
 		for (gpc = 0; stat && gpc < priv->gpc_nr; gpc++) {
@@ -424,6 +637,46 @@ nvc0_graph_trap_intr(struct nvc0_graph_p
 }
 
 static void
+nvc0_graph_ctxctl_debug_unit(struct nvc0_graph_priv *priv, u32 base)
+{
+	nv_error(priv, "%06x - done 0x%08x\n", base,
+		 nv_rd32(priv, base + 0x400));
+	nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
+		 nv_rd32(priv, base + 0x800), nv_rd32(priv, base + 0x804),
+		 nv_rd32(priv, base + 0x808), nv_rd32(priv, base + 0x80c));
+	nv_error(priv, "%06x - stat 0x%08x 0x%08x 0x%08x 0x%08x\n", base,
+		 nv_rd32(priv, base + 0x810), nv_rd32(priv, base + 0x814),
+		 nv_rd32(priv, base + 0x818), nv_rd32(priv, base + 0x81c));
+}
+
+void
+nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *priv)
+{
+	u32 gpcnr = nv_rd32(priv, 0x409604) & 0xffff;
+	u32 gpc;
+
+	nvc0_graph_ctxctl_debug_unit(priv, 0x409000);
+	for (gpc = 0; gpc < gpcnr; gpc++)
+		nvc0_graph_ctxctl_debug_unit(priv, 0x502000 + (gpc * 0x8000));
+}
+
+static void
+nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
+{
+	u32 ustat = nv_rd32(priv, 0x409c18);
+
+	if (ustat & 0x00000001)
+		nv_error(priv, "CTXCTL ucode error\n");
+	if (ustat & 0x00080000)
+		nv_error(priv, "CTXCTL watchdog timeout\n");
+	if (ustat & ~0x00080001)
+		nv_error(priv, "CTXCTL 0x%08x\n", ustat);
+
+	nvc0_graph_ctxctl_debug(priv);
+	nv_wr32(priv, 0x409c20, ustat);
+}
+
+static void
 nvc0_graph_intr(struct nouveau_subdev *subdev)
 {
 	struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
@@ -499,290 +752,6 @@ nvc0_graph_intr(struct nouveau_subdev *s
 	nouveau_engctx_put(engctx);
 }
 
-int
-nvc0_graph_ctor_fw(struct nvc0_graph_priv *priv, const char *fwname,
-		   struct nvc0_graph_fuc *fuc)
-{
-	struct nouveau_device *device = nv_device(priv);
-	const struct firmware *fw;
-	char f[32];
-	int ret;
-
-	snprintf(f, sizeof(f), "/*(DEBLOBBED)*/", device->chipset, fwname);
-	ret = reject_firmware(&fw, f, &device->pdev->dev);
-	if (ret) {
-		snprintf(f, sizeof(f), "/*(DEBLOBBED)*/", fwname);
-		ret = reject_firmware(&fw, f, &device->pdev->dev);
-		if (ret) {
-			nv_error(priv, "failed to load %s\n", fwname);
-			return ret;
-		}
-	}
-
-	fuc->size = fw->size;
-	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
-	release_firmware(fw);
-	return (fuc->data != NULL) ? 0 : -ENOMEM;
-}
-
-static int
-nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
-		struct nouveau_oclass *oclass, void *data, u32 size,
-		struct nouveau_object **pobject)
-{
-	struct nouveau_device *device = nv_device(parent);
-	struct nvc0_graph_priv *priv;
-	bool enable = device->chipset != 0xd7;
-	int ret, i;
-
-	ret = nouveau_graph_create(parent, engine, oclass, enable, &priv);
-	*pobject = nv_object(priv);
-	if (ret)
-		return ret;
-
-	nv_subdev(priv)->unit = 0x18001000;
-	nv_subdev(priv)->intr = nvc0_graph_intr;
-	nv_engine(priv)->cclass = &nvc0_graph_cclass;
-
-	priv->base.units = nvc0_graph_units;
-
-	if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
-		nv_info(priv, "using external firmware\n");
-		if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
-		    nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
-		    nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
-		    nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
-			return -EINVAL;
-		priv->firmware = true;
-	}
-
-	switch (nvc0_graph_class(priv)) {
-	case 0x9097:
-		nv_engine(priv)->sclass = nvc0_graph_sclass;
-		break;
-	case 0x9197:
-		nv_engine(priv)->sclass = nvc1_graph_sclass;
-		break;
-	case 0x9297:
-		nv_engine(priv)->sclass = nvc8_graph_sclass;
-		break;
-	}
-
-	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
-				&priv->unk4188b4);
-	if (ret)
-		return ret;
-
-	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
-				&priv->unk4188b8);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < 0x1000; i += 4) {
-		nv_wo32(priv->unk4188b4, i, 0x00000010);
-		nv_wo32(priv->unk4188b8, i, 0x00000010);
-	}
-
-	priv->rop_nr = (nv_rd32(priv, 0x409604) & 0x001f0000) >> 16;
-	priv->gpc_nr =  nv_rd32(priv, 0x409604) & 0x0000001f;
-	for (i = 0; i < priv->gpc_nr; i++) {
-		priv->tpc_nr[i]  = nv_rd32(priv, GPC_UNIT(i, 0x2608));
-		priv->tpc_total += priv->tpc_nr[i];
-	}
-
-	/*XXX: these need figuring out... though it might not even matter */
-	switch (nv_device(priv)->chipset) {
-	case 0xc0:
-		if (priv->tpc_total == 11) { /* 465, 3/4/4/0, 4 */
-			priv->magic_not_rop_nr = 0x07;
-		} else
-		if (priv->tpc_total == 14) { /* 470, 3/3/4/4, 5 */
-			priv->magic_not_rop_nr = 0x05;
-		} else
-		if (priv->tpc_total == 15) { /* 480, 3/4/4/4, 6 */
-			priv->magic_not_rop_nr = 0x06;
-		}
-		break;
-	case 0xc3: /* 450, 4/0/0/0, 2 */
-		priv->magic_not_rop_nr = 0x03;
-		break;
-	case 0xc4: /* 460, 3/4/0/0, 4 */
-		priv->magic_not_rop_nr = 0x01;
-		break;
-	case 0xc1: /* 2/0/0/0, 1 */
-		priv->magic_not_rop_nr = 0x01;
-		break;
-	case 0xc8: /* 4/4/3/4, 5 */
-		priv->magic_not_rop_nr = 0x06;
-		break;
-	case 0xce: /* 4/4/0/0, 4 */
-		priv->magic_not_rop_nr = 0x03;
-		break;
-	case 0xcf: /* 4/0/0/0, 3 */
-		priv->magic_not_rop_nr = 0x03;
-		break;
-	case 0xd9: /* 1/0/0/0, 1 */
-		priv->magic_not_rop_nr = 0x01;
-		break;
-	}
-
-	return 0;
-}
-
-static void
-nvc0_graph_dtor_fw(struct nvc0_graph_fuc *fuc)
-{
-	kfree(fuc->data);
-	fuc->data = NULL;
-}
-
-void
-nvc0_graph_dtor(struct nouveau_object *object)
-{
-	struct nvc0_graph_priv *priv = (void *)object;
-
-	kfree(priv->data);
-
-	nvc0_graph_dtor_fw(&priv->fuc409c);
-	nvc0_graph_dtor_fw(&priv->fuc409d);
-	nvc0_graph_dtor_fw(&priv->fuc41ac);
-	nvc0_graph_dtor_fw(&priv->fuc41ad);
-
-	nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
-	nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
-
-	nouveau_graph_destroy(&priv->base);
-}
-
-static void
-nvc0_graph_init_obj418880(struct nvc0_graph_priv *priv)
-{
-	int i;
-
-	nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000);
-	nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000);
-	for (i = 0; i < 4; i++)
-		nv_wr32(priv, GPC_BCAST(0x0888) + (i * 4), 0x00000000);
-	nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
-	nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
-}
-
-static void
-nvc0_graph_init_regs(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x400080, 0x003083c2);
-	nv_wr32(priv, 0x400088, 0x00006fe7);
-	nv_wr32(priv, 0x40008c, 0x00000000);
-	nv_wr32(priv, 0x400090, 0x00000030);
-	nv_wr32(priv, 0x40013c, 0x013901f7);
-	nv_wr32(priv, 0x400140, 0x00000100);
-	nv_wr32(priv, 0x400144, 0x00000000);
-	nv_wr32(priv, 0x400148, 0x00000110);
-	nv_wr32(priv, 0x400138, 0x00000000);
-	nv_wr32(priv, 0x400130, 0x00000000);
-	nv_wr32(priv, 0x400134, 0x00000000);
-	nv_wr32(priv, 0x400124, 0x00000002);
-}
-
-static void
-nvc0_graph_init_gpc_0(struct nvc0_graph_priv *priv)
-{
-	const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
-	u32 data[TPC_MAX / 8];
-	u8  tpcnr[GPC_MAX];
-	int i, gpc, tpc;
-
-	nv_wr32(priv, TPC_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */
-
-	/*
-	 *      TP      ROP UNKVAL(magic_not_rop_nr)
-	 * 450: 4/0/0/0 2        3
-	 * 460: 3/4/0/0 4        1
-	 * 465: 3/4/4/0 4        7
-	 * 470: 3/3/4/4 5        5
-	 * 480: 3/4/4/4 6        6
-	 */
-
-	memset(data, 0x00, sizeof(data));
-	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
-	for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
-		do {
-			gpc = (gpc + 1) % priv->gpc_nr;
-		} while (!tpcnr[gpc]);
-		tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
-
-		data[i / 8] |= tpc << ((i % 8) * 4);
-	}
-
-	nv_wr32(priv, GPC_BCAST(0x0980), data[0]);
-	nv_wr32(priv, GPC_BCAST(0x0984), data[1]);
-	nv_wr32(priv, GPC_BCAST(0x0988), data[2]);
-	nv_wr32(priv, GPC_BCAST(0x098c), data[3]);
-
-	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
-						  priv->tpc_nr[gpc]);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
-	}
-
-	nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918);
-	nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
-}
-
-static void
-nvc0_graph_init_units(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x409c24, 0x000f0000);
-	nv_wr32(priv, 0x404000, 0xc0000000); /* DISPATCH */
-	nv_wr32(priv, 0x404600, 0xc0000000); /* M2MF */
-	nv_wr32(priv, 0x408030, 0xc0000000);
-	nv_wr32(priv, 0x40601c, 0xc0000000);
-	nv_wr32(priv, 0x404490, 0xc0000000); /* MACRO */
-	nv_wr32(priv, 0x406018, 0xc0000000);
-	nv_wr32(priv, 0x405840, 0xc0000000);
-	nv_wr32(priv, 0x405844, 0x00ffffff);
-	nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008);
-	nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000);
-}
-
-static void
-nvc0_graph_init_gpc_1(struct nvc0_graph_priv *priv)
-{
-	int gpc, tpc;
-
-	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
-		for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f);
-		}
-		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
-	}
-}
-
-static void
-nvc0_graph_init_rop(struct nvc0_graph_priv *priv)
-{
-	int rop;
-
-	for (rop = 0; rop < priv->rop_nr; rop++) {
-		nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
-		nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
-		nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff);
-		nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff);
-	}
-}
-
 void
 nvc0_graph_init_fw(struct nvc0_graph_priv *priv, u32 fuc_base,
 		   struct nvc0_graph_fuc *code, struct nvc0_graph_fuc *data)
@@ -801,9 +770,46 @@ nvc0_graph_init_fw(struct nvc0_graph_pri
 	}
 }
 
-static int
+static void
+nvc0_graph_init_csdata(struct nvc0_graph_priv *priv,
+		       struct nvc0_graph_init *init,
+		       u32 falcon, u32 starstar, u32 base)
+{
+	u32 addr = init->addr;
+	u32 next = addr;
+	u32 star, temp;
+
+	nv_wr32(priv, falcon + 0x01c0, 0x02000000 + starstar);
+	star = nv_rd32(priv, falcon + 0x01c4);
+	temp = nv_rd32(priv, falcon + 0x01c4);
+	if (temp > star)
+		star = temp;
+	nv_wr32(priv, falcon + 0x01c0, 0x01000000 + star);
+
+	do {
+		if (init->addr != next) {
+			while (addr < next) {
+				u32 nr = min((int)(next - addr) / 4, 32);
+				nv_wr32(priv, falcon + 0x01c4,
+					((nr - 1) << 26) | (addr - base));
+				addr += nr * 4;
+				star += 4;
+			}
+			addr = next = init->addr;
+		}
+		next += init->count * 4;
+	} while ((init++)->count);
+
+	nv_wr32(priv, falcon + 0x01c0, 0x01000004 + starstar);
+	nv_wr32(priv, falcon + 0x01c4, star);
+}
+
+int
 nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
 {
+	struct nvc0_graph_oclass *oclass = (void *)nv_object(priv)->oclass;
+	struct nvc0_grctx_oclass *cclass = (void *)nv_engine(priv)->cclass;
+	struct nvc0_graph_init *init;
 	u32 r000260;
 	int i;
 
@@ -854,6 +860,38 @@ nvc0_graph_init_ctxctl(struct nvc0_graph
 			return -EBUSY;
 		}
 
+		if (nv_device(priv)->chipset >= 0xe0) {
+			nv_wr32(priv, 0x409800, 0x00000000);
+			nv_wr32(priv, 0x409500, 0x00000001);
+			nv_wr32(priv, 0x409504, 0x00000030);
+			if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+				nv_error(priv, "fuc09 req 0x30 timeout\n");
+				return -EBUSY;
+			}
+
+			nv_wr32(priv, 0x409810, 0xb00095c8);
+			nv_wr32(priv, 0x409800, 0x00000000);
+			nv_wr32(priv, 0x409500, 0x00000001);
+			nv_wr32(priv, 0x409504, 0x00000031);
+			if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+				nv_error(priv, "fuc09 req 0x31 timeout\n");
+				return -EBUSY;
+			}
+
+			nv_wr32(priv, 0x409810, 0x00080420);
+			nv_wr32(priv, 0x409800, 0x00000000);
+			nv_wr32(priv, 0x409500, 0x00000001);
+			nv_wr32(priv, 0x409504, 0x00000032);
+			if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
+				nv_error(priv, "fuc09 req 0x32 timeout\n");
+				return -EBUSY;
+			}
+
+			nv_wr32(priv, 0x409614, 0x00000070);
+			nv_wr32(priv, 0x409614, 0x00000770);
+			nv_wr32(priv, 0x40802c, 0x00000001);
+		}
+
 		if (priv->data == NULL) {
 			int ret = nvc0_grctx_generate(priv);
 			if (ret) {
@@ -868,31 +906,41 @@ nvc0_graph_init_ctxctl(struct nvc0_graph
 	/* load HUB microcode */
 	r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
 	nv_wr32(priv, 0x4091c0, 0x01000000);
-	for (i = 0; i < sizeof(nvc0_grhub_data) / 4; i++)
-		nv_wr32(priv, 0x4091c4, nvc0_grhub_data[i]);
+	for (i = 0; i < oclass->fecs.ucode->data.size / 4; i++)
+		nv_wr32(priv, 0x4091c4, oclass->fecs.ucode->data.data[i]);
 
 	nv_wr32(priv, 0x409180, 0x01000000);
-	for (i = 0; i < sizeof(nvc0_grhub_code) / 4; i++) {
+	for (i = 0; i < oclass->fecs.ucode->code.size / 4; i++) {
 		if ((i & 0x3f) == 0)
 			nv_wr32(priv, 0x409188, i >> 6);
-		nv_wr32(priv, 0x409184, nvc0_grhub_code[i]);
+		nv_wr32(priv, 0x409184, oclass->fecs.ucode->code.data[i]);
+	}
+
+	for (i = 0; (init = cclass->hub[i]); i++) {
+		nvc0_graph_init_csdata(priv, init, 0x409000, 0x000, 0x000000);
 	}
 
 	/* load GPC microcode */
 	nv_wr32(priv, 0x41a1c0, 0x01000000);
-	for (i = 0; i < sizeof(nvc0_grgpc_data) / 4; i++)
-		nv_wr32(priv, 0x41a1c4, nvc0_grgpc_data[i]);
+	for (i = 0; i < oclass->gpccs.ucode->data.size / 4; i++)
+		nv_wr32(priv, 0x41a1c4, oclass->gpccs.ucode->data.data[i]);
 
 	nv_wr32(priv, 0x41a180, 0x01000000);
-	for (i = 0; i < sizeof(nvc0_grgpc_code) / 4; i++) {
+	for (i = 0; i < oclass->gpccs.ucode->code.size / 4; i++) {
 		if ((i & 0x3f) == 0)
 			nv_wr32(priv, 0x41a188, i >> 6);
-		nv_wr32(priv, 0x41a184, nvc0_grgpc_code[i]);
+		nv_wr32(priv, 0x41a184, oclass->gpccs.ucode->code.data[i]);
 	}
 	nv_wr32(priv, 0x000260, r000260);
 
+	if ((init = cclass->gpc[0]))
+		nvc0_graph_init_csdata(priv, init, 0x41a000, 0x000, 0x418000);
+	if ((init = cclass->gpc[2]))
+		nvc0_graph_init_csdata(priv, init, 0x41a000, 0x004, 0x419800);
+	if ((init = cclass->gpc[3]))
+		nvc0_graph_init_csdata(priv, init, 0x41a000, 0x008, 0x41be00);
+
 	/* start HUB ucode running, it'll init the GPCs */
-	nv_wr32(priv, 0x409800, nv_device(priv)->chipset);
 	nv_wr32(priv, 0x40910c, 0x00000000);
 	nv_wr32(priv, 0x409100, 0x00000002);
 	if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) {
@@ -913,29 +961,104 @@ nvc0_graph_init_ctxctl(struct nvc0_graph
 	return 0;
 }
 
-static int
+int
 nvc0_graph_init(struct nouveau_object *object)
 {
+	struct nvc0_graph_oclass *oclass = (void *)object->oclass;
 	struct nvc0_graph_priv *priv = (void *)object;
-	int ret;
+	const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
+	u32 data[TPC_MAX / 8] = {};
+	u8  tpcnr[GPC_MAX];
+	int gpc, tpc, rop;
+	int ret, i;
 
 	ret = nouveau_graph_init(&priv->base);
 	if (ret)
 		return ret;
 
-	nvc0_graph_init_obj418880(priv);
-	nvc0_graph_init_regs(priv);
-	/*nvc0_graph_init_unitplemented_magics(priv);*/
-	nvc0_graph_init_gpc_0(priv);
-	/*nvc0_graph_init_unitplemented_c242(priv);*/
+	nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x0888), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x088c), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x0890), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x0894), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
+	nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
+
+	for (i = 0; oclass->mmio[i]; i++)
+		nvc0_graph_mmio(priv, oclass->mmio[i]);
+
+	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+	for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
+		do {
+			gpc = (gpc + 1) % priv->gpc_nr;
+		} while (!tpcnr[gpc]);
+		tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
+
+		data[i / 8] |= tpc << ((i % 8) * 4);
+	}
+
+	nv_wr32(priv, GPC_BCAST(0x0980), data[0]);
+	nv_wr32(priv, GPC_BCAST(0x0984), data[1]);
+	nv_wr32(priv, GPC_BCAST(0x0988), data[2]);
+	nv_wr32(priv, GPC_BCAST(0x098c), data[3]);
+
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0914),
+			priv->magic_not_rop_nr << 8 | priv->tpc_nr[gpc]);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 |
+			priv->tpc_total);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
+	}
+
+	if (nv_device(priv)->chipset != 0xd7)
+		nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918);
+	else
+		nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918);
+
+	nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
 
 	nv_wr32(priv, 0x400500, 0x00010001);
+
 	nv_wr32(priv, 0x400100, 0xffffffff);
 	nv_wr32(priv, 0x40013c, 0xffffffff);
 
-	nvc0_graph_init_units(priv);
-	nvc0_graph_init_gpc_1(priv);
-	nvc0_graph_init_rop(priv);
+	nv_wr32(priv, 0x409c24, 0x000f0000);
+	nv_wr32(priv, 0x404000, 0xc0000000);
+	nv_wr32(priv, 0x404600, 0xc0000000);
+	nv_wr32(priv, 0x408030, 0xc0000000);
+	nv_wr32(priv, 0x40601c, 0xc0000000);
+	nv_wr32(priv, 0x404490, 0xc0000000);
+	nv_wr32(priv, 0x406018, 0xc0000000);
+	nv_wr32(priv, 0x405840, 0xc0000000);
+	nv_wr32(priv, 0x405844, 0x00ffffff);
+	nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008);
+	nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000);
+
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
+		for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f);
+		}
+		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
+	}
+
+	for (rop = 0; rop < priv->rop_nr; rop++) {
+		nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
+		nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
+		nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff);
+		nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff);
+	}
 
 	nv_wr32(priv, 0x400108, 0xffffffff);
 	nv_wr32(priv, 0x400138, 0xffffffff);
@@ -943,22 +1066,205 @@ nvc0_graph_init(struct nouveau_object *o
 	nv_wr32(priv, 0x400130, 0xffffffff);
 	nv_wr32(priv, 0x40011c, 0xffffffff);
 	nv_wr32(priv, 0x400134, 0xffffffff);
+
 	nv_wr32(priv, 0x400054, 0x34ce3464);
+	return nvc0_graph_init_ctxctl(priv);
+}
 
-	ret = nvc0_graph_init_ctxctl(priv);
+static void
+nvc0_graph_dtor_fw(struct nvc0_graph_fuc *fuc)
+{
+	kfree(fuc->data);
+	fuc->data = NULL;
+}
+
+int
+nvc0_graph_ctor_fw(struct nvc0_graph_priv *priv, const char *fwname,
+		   struct nvc0_graph_fuc *fuc)
+{
+	struct nouveau_device *device = nv_device(priv);
+	const struct firmware *fw;
+	char f[32];
+	int ret;
+
+	snprintf(f, sizeof(f), "/*(DEBLOBBED)*/", device->chipset, fwname);
+	ret = reject_firmware(&fw, f, &device->pdev->dev);
+	if (ret) {
+		snprintf(f, sizeof(f), "/*(DEBLOBBED)*/", fwname);
+		ret = reject_firmware(&fw, f, &device->pdev->dev);
+		if (ret) {
+			nv_error(priv, "failed to load %s\n", fwname);
+			return ret;
+		}
+	}
+
+	fuc->size = fw->size;
+	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
+	release_firmware(fw);
+	return (fuc->data != NULL) ? 0 : -ENOMEM;
+}
+
+void
+nvc0_graph_dtor(struct nouveau_object *object)
+{
+	struct nvc0_graph_priv *priv = (void *)object;
+
+	kfree(priv->data);
+
+	nvc0_graph_dtor_fw(&priv->fuc409c);
+	nvc0_graph_dtor_fw(&priv->fuc409d);
+	nvc0_graph_dtor_fw(&priv->fuc41ac);
+	nvc0_graph_dtor_fw(&priv->fuc41ad);
+
+	nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
+	nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
+
+	nouveau_graph_destroy(&priv->base);
+}
+
+int
+nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *bclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nvc0_graph_oclass *oclass = (void *)bclass;
+	struct nouveau_device *device = nv_device(parent);
+	struct nvc0_graph_priv *priv;
+	int ret, i;
+
+	ret = nouveau_graph_create(parent, engine, bclass,
+				   (oclass->fecs.ucode != NULL), &priv);
+	*pobject = nv_object(priv);
+	if (ret)
+		return ret;
+
+	nv_subdev(priv)->unit = 0x18001000;
+	nv_subdev(priv)->intr = nvc0_graph_intr;
+
+	priv->base.units = nvc0_graph_units;
+
+	if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
+		nv_info(priv, "using external firmware\n");
+		if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
+		    nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
+		    nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
+		    nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
+			return -EINVAL;
+		priv->firmware = true;
+	}
+
+	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
+				&priv->unk4188b4);
+	if (ret)
+		return ret;
+
+	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
+				&priv->unk4188b8);
 	if (ret)
 		return ret;
 
+	for (i = 0; i < 0x1000; i += 4) {
+		nv_wo32(priv->unk4188b4, i, 0x00000010);
+		nv_wo32(priv->unk4188b8, i, 0x00000010);
+	}
+
+	priv->rop_nr = (nv_rd32(priv, 0x409604) & 0x001f0000) >> 16;
+	priv->gpc_nr =  nv_rd32(priv, 0x409604) & 0x0000001f;
+	for (i = 0; i < priv->gpc_nr; i++) {
+		priv->tpc_nr[i]  = nv_rd32(priv, GPC_UNIT(i, 0x2608));
+		priv->tpc_total += priv->tpc_nr[i];
+	}
+
+	/*XXX: these need figuring out... though it might not even matter */
+	switch (nv_device(priv)->chipset) {
+	case 0xc0:
+		if (priv->tpc_total == 11) { /* 465, 3/4/4/0, 4 */
+			priv->magic_not_rop_nr = 0x07;
+		} else
+		if (priv->tpc_total == 14) { /* 470, 3/3/4/4, 5 */
+			priv->magic_not_rop_nr = 0x05;
+		} else
+		if (priv->tpc_total == 15) { /* 480, 3/4/4/4, 6 */
+			priv->magic_not_rop_nr = 0x06;
+		}
+		break;
+	case 0xc3: /* 450, 4/0/0/0, 2 */
+		priv->magic_not_rop_nr = 0x03;
+		break;
+	case 0xc4: /* 460, 3/4/0/0, 4 */
+		priv->magic_not_rop_nr = 0x01;
+		break;
+	case 0xc1: /* 2/0/0/0, 1 */
+		priv->magic_not_rop_nr = 0x01;
+		break;
+	case 0xc8: /* 4/4/3/4, 5 */
+		priv->magic_not_rop_nr = 0x06;
+		break;
+	case 0xce: /* 4/4/0/0, 4 */
+		priv->magic_not_rop_nr = 0x03;
+		break;
+	case 0xcf: /* 4/0/0/0, 3 */
+		priv->magic_not_rop_nr = 0x03;
+		break;
+	case 0xd7:
+	case 0xd9: /* 1/0/0/0, 1 */
+		priv->magic_not_rop_nr = 0x01;
+		break;
+	}
+
+	nv_engine(priv)->cclass = *oclass->cclass;
+	nv_engine(priv)->sclass =  oclass->sclass;
 	return 0;
 }
 
-struct nouveau_oclass
-nvc0_graph_oclass = {
-	.handle = NV_ENGINE(GR, 0xc0),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nvc0_graph_init *
+nvc0_graph_init_mmio[] = {
+	nvc0_graph_init_regs,
+	nvc0_graph_init_unk40xx,
+	nvc0_graph_init_unk44xx,
+	nvc0_graph_init_unk78xx,
+	nvc0_graph_init_unk60xx,
+	nvc0_graph_init_unk58xx,
+	nvc0_graph_init_unk80xx,
+	nvc0_graph_init_gpc,
+	nvc0_graph_init_tpc,
+	nvc0_graph_init_unk88xx,
+	nvc0_graph_tpc_0,
+	NULL
+};
+
+#include "fuc/hubnvc0.fuc.h"
+
+struct nvc0_graph_ucode
+nvc0_graph_fecs_ucode = {
+	.code.data = nvc0_grhub_code,
+	.code.size = sizeof(nvc0_grhub_code),
+	.data.data = nvc0_grhub_data,
+	.data.size = sizeof(nvc0_grhub_data),
+};
+
+#include "fuc/gpcnvc0.fuc.h"
+
+struct nvc0_graph_ucode
+nvc0_graph_gpccs_ucode = {
+	.code.data = nvc0_grgpc_code,
+	.code.size = sizeof(nvc0_grgpc_code),
+	.data.data = nvc0_grgpc_data,
+	.data.size = sizeof(nvc0_grgpc_data),
+};
+
+struct nouveau_oclass *
+nvc0_graph_oclass = &(struct nvc0_graph_oclass) {
+	.base.handle = NV_ENGINE(GR, 0xc0),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nvc0_graph_ctor,
 		.dtor = nvc0_graph_dtor,
 		.init = nvc0_graph_init,
 		.fini = _nouveau_graph_fini,
 	},
-};
+	.cclass = &nvc0_grctx_oclass,
+	.sclass =  nvc0_graph_sclass,
+	.mmio = nvc0_graph_init_mmio,
+	.fecs.ucode = &nvc0_graph_fecs_ucode,
+	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,8 +38,8 @@
 #include <engine/fifo.h>
 #include <engine/graph.h>
 
-#define GPC_MAX 4
-#define TPC_MAX 32
+#define GPC_MAX 32
+#define TPC_MAX (GPC_MAX * 8)
 
 #define ROP_BCAST(r)      (0x408800 + (r))
 #define ROP_UNIT(u, r)    (0x410000 + (u) * 0x400 + (r))
@@ -102,74 +102,187 @@ struct nvc0_graph_chan {
 	} data[4];
 };
 
-static inline u32
-nvc0_graph_class(void *obj)
-{
-	struct nouveau_device *device = nv_device(obj);
+int  nvc0_grctx_generate(struct nvc0_graph_priv *);
 
-	switch (device->chipset) {
-	case 0xc0:
-	case 0xc3:
-	case 0xc4:
-	case 0xce: /* guess, mmio trace shows only 0x9097 state */
-	case 0xcf: /* guess, mmio trace shows only 0x9097 state */
-		return 0x9097;
-	case 0xc1:
-		return 0x9197;
-	case 0xc8:
-	case 0xd9:
-	case 0xd7:
-		return 0x9297;
-	case 0xe4:
-	case 0xe7:
-	case 0xe6:
-		return 0xa097;
-	default:
-		return 0;
-	}
-}
+int  nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *,
+			     struct nouveau_oclass *, void *, u32,
+			     struct nouveau_object **);
+void nvc0_graph_context_dtor(struct nouveau_object *);
 
-void nv_icmd(struct nvc0_graph_priv *priv, u32 icmd, u32 data);
+void nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *);
 
-static inline void
-nv_mthd(struct nvc0_graph_priv *priv, u32 class, u32 mthd, u32 data)
-{
-	nv_wr32(priv, 0x40448c, data);
-	nv_wr32(priv, 0x404488, 0x80000000 | (mthd << 14) | class);
-}
+u64  nvc0_graph_units(struct nouveau_graph *);
+int  nvc0_graph_ctor(struct nouveau_object *, struct nouveau_object *,
+		     struct nouveau_oclass *, void *data, u32 size,
+		     struct nouveau_object **);
+void nvc0_graph_dtor(struct nouveau_object *);
+int  nvc0_graph_init(struct nouveau_object *);
+int  nve4_graph_init(struct nouveau_object *);
+
+extern struct nouveau_oclass nvc0_graph_sclass[];
+
+extern struct nouveau_oclass nvc8_graph_sclass[];
+
+struct nvc0_graph_init {
+	u32 addr;
+	u8  count;
+	u8  pitch;
+	u32 data;
+};
+
+struct nvc0_graph_mthd {
+	u16 oclass;
+	struct nvc0_graph_init *init;
+};
 
 struct nvc0_grctx {
 	struct nvc0_graph_priv *priv;
 	struct nvc0_graph_data *data;
 	struct nvc0_graph_mmio *mmio;
-	struct nouveau_gpuobj *chan;
 	int buffer_nr;
 	u64 buffer[4];
 	u64 addr;
 };
 
+struct nvc0_grctx_oclass {
+	struct nouveau_oclass base;
+	/* main context generation function */
+	void  (*main)(struct nvc0_graph_priv *, struct nvc0_grctx *);
+	/* context-specific modify-on-first-load list generation function */
+	void  (*mods)(struct nvc0_graph_priv *, struct nvc0_grctx *);
+	void  (*unkn)(struct nvc0_graph_priv *);
+	/* mmio context data */
+	struct nvc0_graph_init **hub;
+	struct nvc0_graph_init **gpc;
+	/* indirect context data, generated with icmds/mthds */
+	struct nvc0_graph_init *icmd;
+	struct nvc0_graph_mthd *mthd;
+};
+
+struct nvc0_graph_ucode {
+	struct nvc0_graph_fuc code;
+	struct nvc0_graph_fuc data;
+};
+
+extern struct nvc0_graph_ucode nvc0_graph_fecs_ucode;
+extern struct nvc0_graph_ucode nvc0_graph_gpccs_ucode;
+
+struct nvc0_graph_oclass {
+	struct nouveau_oclass base;
+	struct nouveau_oclass **cclass;
+	struct nouveau_oclass *sclass;
+	struct nvc0_graph_init **mmio;
+	struct {
+		struct nvc0_graph_ucode *ucode;
+	} fecs;
+	struct {
+		struct nvc0_graph_ucode *ucode;
+	} gpccs;
+};
+
+void nvc0_graph_mmio(struct nvc0_graph_priv *, struct nvc0_graph_init *);
+void nvc0_graph_icmd(struct nvc0_graph_priv *, struct nvc0_graph_init *);
+void nvc0_graph_mthd(struct nvc0_graph_priv *, struct nvc0_graph_mthd *);
+int  nvc0_graph_init_ctxctl(struct nvc0_graph_priv *);
+
+extern struct nvc0_graph_init nvc0_graph_init_regs[];
+extern struct nvc0_graph_init nvc0_graph_init_unk40xx[];
+extern struct nvc0_graph_init nvc0_graph_init_unk44xx[];
+extern struct nvc0_graph_init nvc0_graph_init_unk78xx[];
+extern struct nvc0_graph_init nvc0_graph_init_unk60xx[];
+extern struct nvc0_graph_init nvc0_graph_init_unk58xx[];
+extern struct nvc0_graph_init nvc0_graph_init_unk80xx[];
+extern struct nvc0_graph_init nvc0_graph_init_gpc[];
+extern struct nvc0_graph_init nvc0_graph_init_unk88xx[];
+extern struct nvc0_graph_init nvc0_graph_tpc_0[];
+
+extern struct nvc0_graph_init nvc3_graph_init_unk58xx[];
+
+extern struct nvc0_graph_init nvd9_graph_init_unk58xx[];
+extern struct nvc0_graph_init nvd9_graph_init_unk64xx[];
+
+extern struct nvc0_graph_init nve4_graph_init_regs[];
+extern struct nvc0_graph_init nve4_graph_init_unk[];
+extern struct nvc0_graph_init nve4_graph_init_unk88xx[];
+
 int  nvc0_grctx_generate(struct nvc0_graph_priv *);
-int  nvc0_grctx_init(struct nvc0_graph_priv *, struct nvc0_grctx *);
-void nvc0_grctx_data(struct nvc0_grctx *, u32, u32, u32);
-void nvc0_grctx_mmio(struct nvc0_grctx *, u32, u32, u32, u32);
-int  nvc0_grctx_fini(struct nvc0_grctx *);
+void nvc0_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
+void nvc0_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
+void nvc0_grctx_generate_unkn(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_r406028(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *);
+void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_r406800(struct nvc0_graph_priv *);
 
-int  nve0_grctx_generate(struct nvc0_graph_priv *);
+extern struct nouveau_oclass *nvc0_grctx_oclass;
+extern struct nvc0_graph_init *nvc0_grctx_init_hub[];
+extern struct nvc0_graph_init nvc0_grctx_init_base[];
+extern struct nvc0_graph_init nvc0_grctx_init_unk40xx[];
+extern struct nvc0_graph_init nvc0_grctx_init_unk44xx[];
+extern struct nvc0_graph_init nvc0_grctx_init_unk46xx[];
+extern struct nvc0_graph_init nvc0_grctx_init_unk47xx[];
+extern struct nvc0_graph_init nvc0_grctx_init_unk60xx[];
+extern struct nvc0_graph_init nvc0_grctx_init_unk64xx[];
+extern struct nvc0_graph_init nvc0_grctx_init_unk78xx[];
+extern struct nvc0_graph_init nvc0_grctx_init_unk80xx[];
+extern struct nvc0_graph_init nvc0_grctx_init_gpc_0[];
+extern struct nvc0_graph_init nvc0_grctx_init_gpc_1[];
+extern struct nvc0_graph_init nvc0_grctx_init_tpc[];
+extern struct nvc0_graph_init nvc0_grctx_init_icmd[];
+extern struct nvc0_graph_init nvd9_grctx_init_icmd[]; //
 
-#define mmio_data(s,a,p) nvc0_grctx_data(&info, (s), (a), (p))
-#define mmio_list(r,d,s,b) nvc0_grctx_mmio(&info, (r), (d), (s), (b))
+extern struct nvc0_graph_mthd nvc0_grctx_init_mthd[];
+extern struct nvc0_graph_init nvc0_grctx_init_902d[];
+extern struct nvc0_graph_init nvc0_grctx_init_9039[];
+extern struct nvc0_graph_init nvc0_grctx_init_90c0[];
+extern struct nvc0_graph_init nvc0_grctx_init_mthd_magic[];
 
-void nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *);
-int  nvc0_graph_ctor_fw(struct nvc0_graph_priv *, const char *,
-			struct nvc0_graph_fuc *);
-void nvc0_graph_dtor(struct nouveau_object *);
-void nvc0_graph_init_fw(struct nvc0_graph_priv *, u32 base,
-			struct nvc0_graph_fuc *, struct nvc0_graph_fuc *);
-int  nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *,
-			     struct nouveau_oclass *, void *, u32,
-			     struct nouveau_object **);
-void nvc0_graph_context_dtor(struct nouveau_object *);
+void nvc1_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
+void nvc1_grctx_generate_unkn(struct nvc0_graph_priv *);
+extern struct nouveau_oclass *nvc1_grctx_oclass;
+extern struct nvc0_graph_init nvc1_grctx_init_9097[];
 
-u64 nvc0_graph_units(struct nouveau_graph *);
+extern struct nouveau_oclass *nvc3_grctx_oclass;
+
+extern struct nouveau_oclass *nvc8_grctx_oclass;
+extern struct nvc0_graph_init nvc8_grctx_init_9197[];
+extern struct nvc0_graph_init nvc8_grctx_init_9297[];
+
+extern struct nouveau_oclass *nvd7_grctx_oclass;
+
+extern struct nouveau_oclass *nvd9_grctx_oclass;
+extern struct nvc0_graph_init nvd9_grctx_init_rop[];
+extern struct nvc0_graph_mthd nvd9_grctx_init_mthd[];
+
+void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
+void nve4_grctx_generate_unkn(struct nvc0_graph_priv *);
+extern struct nouveau_oclass *nve4_grctx_oclass;
+extern struct nvc0_graph_init nve4_grctx_init_unk46xx[];
+extern struct nvc0_graph_init nve4_grctx_init_unk47xx[];
+extern struct nvc0_graph_init nve4_grctx_init_unk58xx[];
+extern struct nvc0_graph_init nve4_grctx_init_unk80xx[];
+extern struct nvc0_graph_init nve4_grctx_init_unk90xx[];
+
+extern struct nouveau_oclass *nvf0_grctx_oclass;
+
+#define mmio_data(s,a,p) do {                                                  \
+	info->buffer[info->buffer_nr] = round_up(info->addr, (a));             \
+	info->addr = info->buffer[info->buffer_nr++] + (s);                    \
+	info->data->size = (s);                                                \
+	info->data->align = (a);                                               \
+	info->data->access = (p);                                              \
+	info->data++;                                                          \
+} while(0)
+
+#define mmio_list(r,d,s,b) do {                                                \
+	info->mmio->addr = (r);                                                \
+	info->mmio->data = (d);                                                \
+	info->mmio->shift = (s);                                               \
+	info->mmio->buffer = (b);                                              \
+	info->mmio++;                                                          \
+	nv_wr32(priv, (r), (d) | ((s) ? (info->buffer[(b)] >> (s)) : 0));      \
+} while(0)
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nvc1_graph_sclass[] = {
+	{ 0x902d, &nouveau_object_ofuncs },
+	{ 0x9039, &nouveau_object_ofuncs },
+	{ 0x9097, &nouveau_object_ofuncs },
+	{ 0x90c0, &nouveau_object_ofuncs },
+	{ 0x9197, &nouveau_object_ofuncs },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static struct nvc0_graph_init
+nvc1_graph_init_gpc[] = {
+	{ 0x4184a0,   1, 0x04, 0x00000000 },
+	{ 0x418604,   1, 0x04, 0x00000000 },
+	{ 0x418680,   1, 0x04, 0x00000000 },
+	{ 0x418714,   1, 0x04, 0x00000000 },
+	{ 0x418384,   1, 0x04, 0x00000000 },
+	{ 0x418814,   3, 0x04, 0x00000000 },
+	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{ 0x4188c8,   2, 0x04, 0x00000000 },
+	{ 0x4188d0,   1, 0x04, 0x00010000 },
+	{ 0x4188d4,   1, 0x04, 0x00000001 },
+	{ 0x418910,   1, 0x04, 0x00010001 },
+	{ 0x418914,   1, 0x04, 0x00000301 },
+	{ 0x418918,   1, 0x04, 0x00800000 },
+	{ 0x418980,   1, 0x04, 0x77777770 },
+	{ 0x418984,   3, 0x04, 0x77777777 },
+	{ 0x418c04,   1, 0x04, 0x00000000 },
+	{ 0x418c88,   1, 0x04, 0x00000000 },
+	{ 0x418d00,   1, 0x04, 0x00000000 },
+	{ 0x418f08,   1, 0x04, 0x00000000 },
+	{ 0x418e00,   1, 0x04, 0x00000003 },
+	{ 0x418e08,   1, 0x04, 0x00000000 },
+	{ 0x41900c,   1, 0x04, 0x00000000 },
+	{ 0x419018,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvc1_graph_init_tpc[] = {
+	{ 0x419d08,   2, 0x04, 0x00000000 },
+	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{ 0x419ab0,   1, 0x04, 0x00000000 },
+	{ 0x419ac8,   1, 0x04, 0x00000000 },
+	{ 0x419ab8,   1, 0x04, 0x000000e7 },
+	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{ 0x41980c,   2, 0x04, 0x00000000 },
+	{ 0x419814,   1, 0x04, 0x00000004 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x41984c,   1, 0x04, 0x00005bc5 },
+	{ 0x419850,   4, 0x04, 0x00000000 },
+	{ 0x419880,   1, 0x04, 0x00000002 },
+	{ 0x419c98,   1, 0x04, 0x00000000 },
+	{ 0x419ca8,   1, 0x04, 0x80000000 },
+	{ 0x419cb4,   1, 0x04, 0x00000000 },
+	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
+	{ 0x419cbc,   1, 0x04, 0x28137606 },
+	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{ 0x419bd4,   1, 0x04, 0x00800000 },
+	{ 0x419bdc,   1, 0x04, 0x00000000 },
+	{ 0x419d2c,   1, 0x04, 0x00000000 },
+	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{ 0x419e00,   1, 0x04, 0x00000000 },
+	{ 0x419ea0,   1, 0x04, 0x00000000 },
+	{ 0x419ea4,   1, 0x04, 0x00000100 },
+	{ 0x419ea8,   1, 0x04, 0x00001100 },
+	{ 0x419eac,   1, 0x04, 0x11100702 },
+	{ 0x419eb0,   1, 0x04, 0x00000003 },
+	{ 0x419eb4,   4, 0x04, 0x00000000 },
+	{ 0x419ec8,   1, 0x04, 0x0e063818 },
+	{ 0x419ecc,   1, 0x04, 0x0e060e06 },
+	{ 0x419ed0,   1, 0x04, 0x00003818 },
+	{ 0x419ed4,   1, 0x04, 0x011104f1 },
+	{ 0x419edc,   1, 0x04, 0x00000000 },
+	{ 0x419f00,   1, 0x04, 0x00000000 },
+	{ 0x419f2c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init *
+nvc1_graph_init_mmio[] = {
+	nvc0_graph_init_regs,
+	nvc0_graph_init_unk40xx,
+	nvc0_graph_init_unk44xx,
+	nvc0_graph_init_unk78xx,
+	nvc0_graph_init_unk60xx,
+	nvc3_graph_init_unk58xx,
+	nvc0_graph_init_unk80xx,
+	nvc1_graph_init_gpc,
+	nvc1_graph_init_tpc,
+	nvc0_graph_init_unk88xx,
+	nvc0_graph_tpc_0,
+	NULL
+};
+
+struct nouveau_oclass *
+nvc1_graph_oclass = &(struct nvc0_graph_oclass) {
+	.base.handle = NV_ENGINE(GR, 0xc1),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_ctor,
+		.dtor = nvc0_graph_dtor,
+		.init = nvc0_graph_init,
+		.fini = _nouveau_graph_fini,
+	},
+	.cclass = &nvc1_grctx_oclass,
+	.sclass = nvc1_graph_sclass,
+	.mmio = nvc1_graph_init_mmio,
+	.fecs.ucode = &nvc0_graph_fecs_ucode,
+	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc3.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc3.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc3.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+struct nvc0_graph_init
+nvc3_graph_init_unk58xx[] = {
+	{ 0x405844,   1, 0x04, 0x00ffffff },
+	{ 0x405850,   1, 0x04, 0x00000000 },
+	{ 0x405900,   1, 0x04, 0x00002834 },
+	{ 0x405908,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvc3_graph_init_tpc[] = {
+	{ 0x419d08,   2, 0x04, 0x00000000 },
+	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{ 0x419ab0,   1, 0x04, 0x00000000 },
+	{ 0x419ac8,   1, 0x04, 0x00000000 },
+	{ 0x419ab8,   1, 0x04, 0x000000e7 },
+	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{ 0x41980c,   3, 0x04, 0x00000000 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x41984c,   1, 0x04, 0x00005bc5 },
+	{ 0x419850,   4, 0x04, 0x00000000 },
+	{ 0x419880,   1, 0x04, 0x00000002 },
+	{ 0x419c98,   1, 0x04, 0x00000000 },
+	{ 0x419ca8,   1, 0x04, 0x80000000 },
+	{ 0x419cb4,   1, 0x04, 0x00000000 },
+	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
+	{ 0x419cbc,   1, 0x04, 0x28137606 },
+	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{ 0x419bd4,   1, 0x04, 0x00800000 },
+	{ 0x419bdc,   1, 0x04, 0x00000000 },
+	{ 0x419d2c,   1, 0x04, 0x00000000 },
+	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{ 0x419e00,   1, 0x04, 0x00000000 },
+	{ 0x419ea0,   1, 0x04, 0x00000000 },
+	{ 0x419ea4,   1, 0x04, 0x00000100 },
+	{ 0x419ea8,   1, 0x04, 0x00001100 },
+	{ 0x419eac,   1, 0x04, 0x11100702 },
+	{ 0x419eb0,   1, 0x04, 0x00000003 },
+	{ 0x419eb4,   4, 0x04, 0x00000000 },
+	{ 0x419ec8,   1, 0x04, 0x0e063818 },
+	{ 0x419ecc,   1, 0x04, 0x0e060e06 },
+	{ 0x419ed0,   1, 0x04, 0x00003818 },
+	{ 0x419ed4,   1, 0x04, 0x011104f1 },
+	{ 0x419edc,   1, 0x04, 0x00000000 },
+	{ 0x419f00,   1, 0x04, 0x00000000 },
+	{ 0x419f2c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init *
+nvc3_graph_init_mmio[] = {
+	nvc0_graph_init_regs,
+	nvc0_graph_init_unk40xx,
+	nvc0_graph_init_unk44xx,
+	nvc0_graph_init_unk78xx,
+	nvc0_graph_init_unk60xx,
+	nvc3_graph_init_unk58xx,
+	nvc0_graph_init_unk80xx,
+	nvc0_graph_init_gpc,
+	nvc3_graph_init_tpc,
+	nvc0_graph_init_unk88xx,
+	nvc0_graph_tpc_0,
+	NULL
+};
+
+struct nouveau_oclass *
+nvc3_graph_oclass = &(struct nvc0_graph_oclass) {
+	.base.handle = NV_ENGINE(GR, 0xc3),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_ctor,
+		.dtor = nvc0_graph_dtor,
+		.init = nvc0_graph_init,
+		.fini = _nouveau_graph_fini,
+	},
+	.cclass = &nvc3_grctx_oclass,
+	.sclass = nvc0_graph_sclass,
+	.mmio = nvc3_graph_init_mmio,
+	.fecs.ucode = &nvc0_graph_fecs_ucode,
+	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+struct nouveau_oclass
+nvc8_graph_sclass[] = {
+	{ 0x902d, &nouveau_object_ofuncs },
+	{ 0x9039, &nouveau_object_ofuncs },
+	{ 0x9097, &nouveau_object_ofuncs },
+	{ 0x90c0, &nouveau_object_ofuncs },
+	{ 0x9197, &nouveau_object_ofuncs },
+	{ 0x9297, &nouveau_object_ofuncs },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static struct nvc0_graph_init
+nvc8_graph_init_gpc[] = {
+	{ 0x4184a0,   1, 0x04, 0x00000000 },
+	{ 0x418604,   1, 0x04, 0x00000000 },
+	{ 0x418680,   1, 0x04, 0x00000000 },
+	{ 0x418714,   1, 0x04, 0x80000000 },
+	{ 0x418384,   1, 0x04, 0x00000000 },
+	{ 0x418814,   3, 0x04, 0x00000000 },
+	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{ 0x4188c8,   2, 0x04, 0x00000000 },
+	{ 0x4188d0,   1, 0x04, 0x00010000 },
+	{ 0x4188d4,   1, 0x04, 0x00000001 },
+	{ 0x418910,   1, 0x04, 0x00010001 },
+	{ 0x418914,   1, 0x04, 0x00000301 },
+	{ 0x418918,   1, 0x04, 0x00800000 },
+	{ 0x418980,   1, 0x04, 0x77777770 },
+	{ 0x418984,   3, 0x04, 0x77777777 },
+	{ 0x418c04,   1, 0x04, 0x00000000 },
+	{ 0x418c88,   1, 0x04, 0x00000000 },
+	{ 0x418d00,   1, 0x04, 0x00000000 },
+	{ 0x418f08,   1, 0x04, 0x00000000 },
+	{ 0x418e00,   1, 0x04, 0x00000050 },
+	{ 0x418e08,   1, 0x04, 0x00000000 },
+	{ 0x41900c,   1, 0x04, 0x00000000 },
+	{ 0x419018,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvc8_graph_init_tpc[] = {
+	{ 0x419d08,   2, 0x04, 0x00000000 },
+	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{ 0x419ab0,   1, 0x04, 0x00000000 },
+	{ 0x419ab8,   1, 0x04, 0x000000e7 },
+	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{ 0x41980c,   3, 0x04, 0x00000000 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x41984c,   1, 0x04, 0x00005bc5 },
+	{ 0x419850,   4, 0x04, 0x00000000 },
+	{ 0x419c98,   1, 0x04, 0x00000000 },
+	{ 0x419ca8,   1, 0x04, 0x80000000 },
+	{ 0x419cb4,   1, 0x04, 0x00000000 },
+	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
+	{ 0x419cbc,   1, 0x04, 0x28137606 },
+	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{ 0x419bd4,   1, 0x04, 0x00800000 },
+	{ 0x419bdc,   1, 0x04, 0x00000000 },
+	{ 0x419d2c,   1, 0x04, 0x00000000 },
+	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{ 0x419e00,   1, 0x04, 0x00000000 },
+	{ 0x419ea0,   1, 0x04, 0x00000000 },
+	{ 0x419ea4,   1, 0x04, 0x00000100 },
+	{ 0x419ea8,   1, 0x04, 0x00001100 },
+	{ 0x419eac,   1, 0x04, 0x11100f02 },
+	{ 0x419eb0,   1, 0x04, 0x00000003 },
+	{ 0x419eb4,   4, 0x04, 0x00000000 },
+	{ 0x419ec8,   1, 0x04, 0x06060618 },
+	{ 0x419ed0,   1, 0x04, 0x0eff0e38 },
+	{ 0x419ed4,   1, 0x04, 0x011104f1 },
+	{ 0x419edc,   1, 0x04, 0x00000000 },
+	{ 0x419f00,   1, 0x04, 0x00000000 },
+	{ 0x419f2c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init *
+nvc8_graph_init_mmio[] = {
+	nvc0_graph_init_regs,
+	nvc0_graph_init_unk40xx,
+	nvc0_graph_init_unk44xx,
+	nvc0_graph_init_unk78xx,
+	nvc0_graph_init_unk60xx,
+	nvc0_graph_init_unk58xx,
+	nvc0_graph_init_unk80xx,
+	nvc8_graph_init_gpc,
+	nvc8_graph_init_tpc,
+	nvc0_graph_init_unk88xx,
+	nvc0_graph_tpc_0,
+	NULL
+};
+
+struct nouveau_oclass *
+nvc8_graph_oclass = &(struct nvc0_graph_oclass) {
+	.base.handle = NV_ENGINE(GR, 0xc8),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_ctor,
+		.dtor = nvc0_graph_dtor,
+		.init = nvc0_graph_init,
+		.fini = _nouveau_graph_fini,
+	},
+	.cclass = &nvc8_grctx_oclass,
+	.sclass = nvc8_graph_sclass,
+	.mmio = nvc8_graph_init_mmio,
+	.fecs.ucode = &nvc0_graph_fecs_ucode,
+	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+#include "fuc/hubnvd7.fuc.h"
+
+struct nvc0_graph_ucode
+nvd7_graph_fecs_ucode = {
+	.code.data = nvd7_grhub_code,
+	.code.size = sizeof(nvd7_grhub_code),
+	.data.data = nvd7_grhub_data,
+	.data.size = sizeof(nvd7_grhub_data),
+};
+
+#include "fuc/gpcnvd7.fuc.h"
+
+struct nvc0_graph_ucode
+nvd7_graph_gpccs_ucode = {
+	.code.data = nvd7_grgpc_code,
+	.code.size = sizeof(nvd7_grgpc_code),
+	.data.data = nvd7_grgpc_data,
+	.data.size = sizeof(nvd7_grgpc_data),
+};
+
+static struct nvc0_graph_init
+nvd7_graph_init_gpc[] = {
+	{ 0x418408,   1, 0x04, 0x00000000 },
+	{ 0x4184a0,   1, 0x04, 0x00000000 },
+	{ 0x4184a4,   2, 0x04, 0x00000000 },
+	{ 0x418604,   1, 0x04, 0x00000000 },
+	{ 0x418680,   1, 0x04, 0x00000000 },
+	{ 0x418714,   1, 0x04, 0x00000000 },
+	{ 0x418384,   1, 0x04, 0x00000000 },
+	{ 0x418814,   3, 0x04, 0x00000000 },
+	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{ 0x4188c8,   2, 0x04, 0x00000000 },
+	{ 0x4188d0,   1, 0x04, 0x00010000 },
+	{ 0x4188d4,   1, 0x04, 0x00000001 },
+	{ 0x418910,   1, 0x04, 0x00010001 },
+	{ 0x418914,   1, 0x04, 0x00000301 },
+	{ 0x418918,   1, 0x04, 0x00800000 },
+	{ 0x418980,   1, 0x04, 0x77777770 },
+	{ 0x418984,   3, 0x04, 0x77777777 },
+	{ 0x418c04,   1, 0x04, 0x00000000 },
+	{ 0x418c64,   1, 0x04, 0x00000000 },
+	{ 0x418c68,   1, 0x04, 0x00000000 },
+	{ 0x418c88,   1, 0x04, 0x00000000 },
+	{ 0x418cb4,   2, 0x04, 0x00000000 },
+	{ 0x418d00,   1, 0x04, 0x00000000 },
+	{ 0x418d28,   1, 0x04, 0x00000000 },
+	{ 0x418f00,   1, 0x04, 0x00000000 },
+	{ 0x418f08,   1, 0x04, 0x00000000 },
+	{ 0x418f20,   2, 0x04, 0x00000000 },
+	{ 0x418e00,   1, 0x04, 0x00000003 },
+	{ 0x418e08,   1, 0x04, 0x00000000 },
+	{ 0x418e1c,   1, 0x04, 0x00000000 },
+	{ 0x418e20,   1, 0x04, 0x00000000 },
+	{ 0x41900c,   1, 0x04, 0x00000000 },
+	{ 0x419018,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd7_graph_init_tpc[] = {
+	{ 0x419d08,   2, 0x04, 0x00000000 },
+	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{ 0x419ab0,   1, 0x04, 0x00000000 },
+	{ 0x419ac8,   1, 0x04, 0x00000000 },
+	{ 0x419ab8,   1, 0x04, 0x000000e7 },
+	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{ 0x419ab4,   1, 0x04, 0x00000000 },
+	{ 0x41980c,   1, 0x04, 0x00000010 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x41984c,   1, 0x04, 0x00005bc8 },
+	{ 0x419850,   2, 0x04, 0x00000000 },
+	{ 0x419c98,   1, 0x04, 0x00000000 },
+	{ 0x419ca8,   1, 0x04, 0x80000000 },
+	{ 0x419cb4,   1, 0x04, 0x00000000 },
+	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
+	{ 0x419cbc,   1, 0x04, 0x28137606 },
+	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{ 0x419e00,   1, 0x04, 0x00000000 },
+	{ 0x419ea0,   1, 0x04, 0x00000000 },
+	{ 0x419ea4,   1, 0x04, 0x00000100 },
+	{ 0x419ea8,   1, 0x04, 0x02001100 },
+	{ 0x419eac,   1, 0x04, 0x11100702 },
+	{ 0x419eb0,   1, 0x04, 0x00000003 },
+	{ 0x419eb4,   4, 0x04, 0x00000000 },
+	{ 0x419ec8,   1, 0x04, 0x0e063818 },
+	{ 0x419ecc,   1, 0x04, 0x0e060e06 },
+	{ 0x419ed0,   1, 0x04, 0x00003818 },
+	{ 0x419ed4,   1, 0x04, 0x011104f1 },
+	{ 0x419edc,   1, 0x04, 0x00000000 },
+	{ 0x419f00,   1, 0x04, 0x00000000 },
+	{ 0x419f2c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd7_graph_init_tpc_0[] = {
+	{ 0x40402c,   1, 0x04, 0x00000000 },
+	{ 0x4040f0,   1, 0x04, 0x00000000 },
+	{ 0x404174,   1, 0x04, 0x00000000 },
+	{ 0x503018,   1, 0x04, 0x00000001 },
+	{}
+};
+
+static struct nvc0_graph_init *
+nvd7_graph_init_mmio[] = {
+	nvc0_graph_init_regs,
+	nvc0_graph_init_unk40xx,
+	nvc0_graph_init_unk44xx,
+	nvc0_graph_init_unk78xx,
+	nvc0_graph_init_unk60xx,
+	nvd9_graph_init_unk64xx,
+	nvd9_graph_init_unk58xx,
+	nvc0_graph_init_unk80xx,
+	nvd7_graph_init_gpc,
+	nvd7_graph_init_tpc,
+	nve4_graph_init_unk,
+	nvc0_graph_init_unk88xx,
+	nvd7_graph_init_tpc_0,
+	NULL
+};
+
+struct nouveau_oclass *
+nvd7_graph_oclass = &(struct nvc0_graph_oclass) {
+	.base.handle = NV_ENGINE(GR, 0xd7),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_ctor,
+		.dtor = nvc0_graph_dtor,
+		.init = nvc0_graph_init,
+		.fini = _nouveau_graph_fini,
+	},
+	.cclass = &nvd7_grctx_oclass,
+	.sclass = nvc8_graph_sclass,
+	.mmio = nvd7_graph_init_mmio,
+	.fecs.ucode = &nvd7_graph_fecs_ucode,
+	.gpccs.ucode = &nvd7_graph_gpccs_ucode,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+struct nvc0_graph_init
+nvd9_graph_init_unk64xx[] = {
+	{ 0x4064f0,   3, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nvd9_graph_init_unk58xx[] = {
+	{ 0x405844,   1, 0x04, 0x00ffffff },
+	{ 0x405850,   1, 0x04, 0x00000000 },
+	{ 0x405900,   1, 0x04, 0x00002834 },
+	{ 0x405908,   1, 0x04, 0x00000000 },
+	{ 0x405928,   1, 0x04, 0x00000000 },
+	{ 0x40592c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd9_graph_init_gpc[] = {
+	{ 0x418408,   1, 0x04, 0x00000000 },
+	{ 0x4184a0,   1, 0x04, 0x00000000 },
+	{ 0x4184a4,   2, 0x04, 0x00000000 },
+	{ 0x418604,   1, 0x04, 0x00000000 },
+	{ 0x418680,   1, 0x04, 0x00000000 },
+	{ 0x418714,   1, 0x04, 0x00000000 },
+	{ 0x418384,   1, 0x04, 0x00000000 },
+	{ 0x418814,   3, 0x04, 0x00000000 },
+	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{ 0x4188c8,   2, 0x04, 0x00000000 },
+	{ 0x4188d0,   1, 0x04, 0x00010000 },
+	{ 0x4188d4,   1, 0x04, 0x00000001 },
+	{ 0x418910,   1, 0x04, 0x00010001 },
+	{ 0x418914,   1, 0x04, 0x00000301 },
+	{ 0x418918,   1, 0x04, 0x00800000 },
+	{ 0x418980,   1, 0x04, 0x77777770 },
+	{ 0x418984,   3, 0x04, 0x77777777 },
+	{ 0x418c04,   1, 0x04, 0x00000000 },
+	{ 0x418c64,   1, 0x04, 0x00000000 },
+	{ 0x418c68,   1, 0x04, 0x00000000 },
+	{ 0x418c88,   1, 0x04, 0x00000000 },
+	{ 0x418cb4,   2, 0x04, 0x00000000 },
+	{ 0x418d00,   1, 0x04, 0x00000000 },
+	{ 0x418d28,   1, 0x04, 0x00000000 },
+	{ 0x418d2c,   1, 0x04, 0x00000000 },
+	{ 0x418f00,   1, 0x04, 0x00000000 },
+	{ 0x418f08,   1, 0x04, 0x00000000 },
+	{ 0x418f20,   2, 0x04, 0x00000000 },
+	{ 0x418e00,   1, 0x04, 0x00000003 },
+	{ 0x418e08,   1, 0x04, 0x00000000 },
+	{ 0x418e1c,   1, 0x04, 0x00000000 },
+	{ 0x418e20,   1, 0x04, 0x00000000 },
+	{ 0x41900c,   1, 0x04, 0x00000000 },
+	{ 0x419018,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvd9_graph_init_tpc[] = {
+	{ 0x419d08,   2, 0x04, 0x00000000 },
+	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{ 0x419ab0,   1, 0x04, 0x00000000 },
+	{ 0x419ac8,   1, 0x04, 0x00000000 },
+	{ 0x419ab8,   1, 0x04, 0x000000e7 },
+	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{ 0x419ab4,   1, 0x04, 0x00000000 },
+	{ 0x41980c,   1, 0x04, 0x00000010 },
+	{ 0x419810,   1, 0x04, 0x00000000 },
+	{ 0x419814,   1, 0x04, 0x00000004 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x41984c,   1, 0x04, 0x0000a918 },
+	{ 0x419850,   4, 0x04, 0x00000000 },
+	{ 0x419880,   1, 0x04, 0x00000002 },
+	{ 0x419c98,   1, 0x04, 0x00000000 },
+	{ 0x419ca8,   1, 0x04, 0x80000000 },
+	{ 0x419cb4,   1, 0x04, 0x00000000 },
+	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
+	{ 0x419cbc,   1, 0x04, 0x28137606 },
+	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{ 0x419bd4,   1, 0x04, 0x00800000 },
+	{ 0x419bdc,   1, 0x04, 0x00000000 },
+	{ 0x419bf8,   1, 0x04, 0x00000000 },
+	{ 0x419bfc,   1, 0x04, 0x00000000 },
+	{ 0x419d2c,   1, 0x04, 0x00000000 },
+	{ 0x419d48,   1, 0x04, 0x00000000 },
+	{ 0x419d4c,   1, 0x04, 0x00000000 },
+	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{ 0x419e00,   1, 0x04, 0x00000000 },
+	{ 0x419ea0,   1, 0x04, 0x00000000 },
+	{ 0x419ea4,   1, 0x04, 0x00000100 },
+	{ 0x419ea8,   1, 0x04, 0x02001100 },
+	{ 0x419eac,   1, 0x04, 0x11100702 },
+	{ 0x419eb0,   1, 0x04, 0x00000003 },
+	{ 0x419eb4,   4, 0x04, 0x00000000 },
+	{ 0x419ec8,   1, 0x04, 0x0e063818 },
+	{ 0x419ecc,   1, 0x04, 0x0e060e06 },
+	{ 0x419ed0,   1, 0x04, 0x00003818 },
+	{ 0x419ed4,   1, 0x04, 0x011104f1 },
+	{ 0x419edc,   1, 0x04, 0x00000000 },
+	{ 0x419f00,   1, 0x04, 0x00000000 },
+	{ 0x419f2c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init *
+nvd9_graph_init_mmio[] = {
+	nvc0_graph_init_regs,
+	nvc0_graph_init_unk40xx,
+	nvc0_graph_init_unk44xx,
+	nvc0_graph_init_unk78xx,
+	nvc0_graph_init_unk60xx,
+	nvd9_graph_init_unk64xx,
+	nvd9_graph_init_unk58xx,
+	nvc0_graph_init_unk80xx,
+	nvd9_graph_init_gpc,
+	nvd9_graph_init_tpc,
+	nvc0_graph_init_unk88xx,
+	nvc0_graph_tpc_0,
+	NULL
+};
+
+struct nouveau_oclass *
+nvd9_graph_oclass = &(struct nvc0_graph_oclass) {
+	.base.handle = NV_ENGINE(GR, 0xd9),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_ctor,
+		.dtor = nvc0_graph_dtor,
+		.init = nvc0_graph_init,
+		.fini = _nouveau_graph_fini,
+	},
+	.cclass = &nvd9_grctx_oclass,
+	.sclass = nvc8_graph_sclass,
+	.mmio = nvd9_graph_init_mmio,
+	.fecs.ucode = &nvc0_graph_fecs_ucode,
+	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,807 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
- *
- * Authors: Ben Skeggs
- */
-
-#include "nvc0.h"
-#include "fuc/hubnve0.fuc.h"
-#include "fuc/gpcnve0.fuc.h"
-
-/*******************************************************************************
- * Graphics object classes
- ******************************************************************************/
-
-static struct nouveau_oclass
-nve0_graph_sclass[] = {
-	{ 0x902d, &nouveau_object_ofuncs },
-	{ 0xa040, &nouveau_object_ofuncs },
-	{ 0xa097, &nouveau_object_ofuncs },
-	{ 0xa0c0, &nouveau_object_ofuncs },
-	{ 0xa0b5, &nouveau_object_ofuncs },
-	{}
-};
-
-/*******************************************************************************
- * PGRAPH context
- ******************************************************************************/
-
-static struct nouveau_oclass
-nve0_graph_cclass = {
-	.handle = NV_ENGCTX(GR, 0xe0),
-	.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = nvc0_graph_context_ctor,
-		.dtor = nvc0_graph_context_dtor,
-		.init = _nouveau_graph_context_init,
-		.fini = _nouveau_graph_context_fini,
-		.rd32 = _nouveau_graph_context_rd32,
-		.wr32 = _nouveau_graph_context_wr32,
-	},
-};
-
-/*******************************************************************************
- * PGRAPH engine/subdev functions
- ******************************************************************************/
-
-static void
-nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
-{
-	u32 ustat = nv_rd32(priv, 0x409c18);
-
-	if (ustat & 0x00000001)
-		nv_error(priv, "CTXCTRL ucode error\n");
-	if (ustat & 0x00080000)
-		nv_error(priv, "CTXCTRL watchdog timeout\n");
-	if (ustat & ~0x00080001)
-		nv_error(priv, "CTXCTRL 0x%08x\n", ustat);
-
-	nvc0_graph_ctxctl_debug(priv);
-	nv_wr32(priv, 0x409c20, ustat);
-}
-
-static const struct nouveau_enum nve0_mp_warp_error[] = {
-	{ 0x00, "NO_ERROR" },
-	{ 0x01, "STACK_MISMATCH" },
-	{ 0x05, "MISALIGNED_PC" },
-	{ 0x08, "MISALIGNED_GPR" },
-	{ 0x09, "INVALID_OPCODE" },
-	{ 0x0d, "GPR_OUT_OF_BOUNDS" },
-	{ 0x0e, "MEM_OUT_OF_BOUNDS" },
-	{ 0x0f, "UNALIGNED_MEM_ACCESS" },
-	{ 0x11, "INVALID_PARAM" },
-	{}
-};
-
-static const struct nouveau_enum nve0_mp_global_error[] = {
-	{ 2, "MULTIPLE_WARP_ERRORS" },
-	{ 3, "OUT_OF_STACK_SPACE" },
-	{}
-};
-
-static const struct nouveau_enum nve0_gpc_rop_error[] = {
-	{ 1, "RT_PITCH_OVERRUN" },
-	{ 4, "RT_WIDTH_OVERRUN" },
-	{ 5, "RT_HEIGHT_OVERRUN" },
-	{ 7, "ZETA_STORAGE_TYPE_MISMATCH" },
-	{ 8, "RT_STORAGE_TYPE_MISMATCH" },
-	{ 10, "RT_LINEAR_MISMATCH" },
-	{}
-};
-
-static const struct nouveau_enum nve0_sked_error[] = {
-	{ 7, "CONSTANT_BUFFER_SIZE" },
-	{ 9, "LOCAL_MEMORY_SIZE_POS" },
-	{ 10, "LOCAL_MEMORY_SIZE_NEG" },
-	{ 11, "WARP_CSTACK_SIZE" },
-	{ 12, "TOTAL_TEMP_SIZE" },
-	{ 13, "REGISTER_COUNT" },
-	{ 18, "TOTAL_THREADS" },
-	{ 20, "PROGRAM_OFFSET" },
-	{ 21, "SHARED_MEMORY_SIZE" },
-	{ 25, "SHARED_CONFIG_TOO_SMALL" },
-	{ 26, "TOTAL_REGISTER_COUNT" },
-	{}
-};
-
-static void
-nve0_graph_mp_trap(struct nvc0_graph_priv *priv, int gpc, int tp)
-{
-	int i;
-	u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x648));
-	u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x650));
-
-	nv_error(priv, "GPC%i/TP%i/MP trap:", gpc, tp);
-
-	for (i = 0; i <= 31; ++i) {
-		if (!(gerr & (1 << i)))
-			continue;
-		pr_cont(" ");
-		nouveau_enum_print(nve0_mp_global_error, i);
-	}
-	if (werr) {
-		pr_cont(" ");
-		nouveau_enum_print(nve0_mp_warp_error, werr & 0xffff);
-	}
-	pr_cont("\n");
-
-	/* disable MP trap to avoid spam */
-	nv_mask(priv, TPC_UNIT(gpc, tp, 0x50c), 0x2, 0x0);
-
-	/* TODO: figure out how to resume after an MP trap */
-}
-
-static void
-nve0_graph_tp_trap(struct nvc0_graph_priv *priv, int gpc, int tp)
-{
-	u32 stat = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x508));
-
-	if (stat & 0x1) {
-		u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x224));
-		nv_error(priv, "GPC%i/TP%i/TEX trap: %08x\n",
-			 gpc, tp, trap);
-
-		nv_wr32(priv, TPC_UNIT(gpc, tp, 0x224), 0xc0000000);
-		stat &= ~0x1;
-	}
-
-	if (stat & 0x2) {
-		nve0_graph_mp_trap(priv, gpc, tp);
-		stat &= ~0x2;
-	}
-
-	if (stat & 0x4) {
-		u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x084));
-		nv_error(priv, "GPC%i/TP%i/POLY trap: %08x\n",
-			 gpc, tp, trap);
-
-		nv_wr32(priv, TPC_UNIT(gpc, tp, 0x084), 0xc0000000);
-		stat &= ~0x4;
-	}
-
-	if (stat & 0x8) {
-		u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x48c));
-		nv_error(priv, "GPC%i/TP%i/L1C trap: %08x\n",
-			 gpc, tp, trap);
-
-		nv_wr32(priv, TPC_UNIT(gpc, tp, 0x48c), 0xc0000000);
-		stat &= ~0x8;
-	}
-
-	if (stat) {
-		nv_error(priv, "GPC%i/TP%i: unknown stat %08x\n",
-			 gpc, tp, stat);
-	}
-}
-
-static void
-nve0_graph_gpc_trap(struct nvc0_graph_priv *priv)
-{
-	const u32 mask = nv_rd32(priv, 0x400118);
-	int gpc;
-
-	for (gpc = 0; gpc < 4; ++gpc) {
-		u32 stat;
-		int tp;
-
-		if (!(mask & (1 << gpc)))
-			continue;
-		stat = nv_rd32(priv, GPC_UNIT(gpc, 0x2c90));
-
-		if (stat & 0x0001) {
-			u32 trap[4];
-			int i;
-
-			trap[0] = nv_rd32(priv, GPC_UNIT(gpc, 0x0420));
-			trap[1] = nv_rd32(priv, GPC_UNIT(gpc, 0x0434));
-			trap[2] = nv_rd32(priv, GPC_UNIT(gpc, 0x0438));
-			trap[3] = nv_rd32(priv, GPC_UNIT(gpc, 0x043c));
-
-			nv_error(priv, "GPC%i/PROP trap:", gpc);
-			for (i = 0; i <= 29; ++i) {
-				if (!(trap[0] & (1 << i)))
-					continue;
-				pr_cont(" ");
-				nouveau_enum_print(nve0_gpc_rop_error, i);
-			}
-			pr_cont("\n");
-
-			nv_error(priv, "x = %u, y = %u, "
-				 "format = %x, storage type = %x\n",
-				 trap[1] & 0xffff,
-				 trap[1] >> 16,
-				 (trap[2] >> 8) & 0x3f,
-				 trap[3] & 0xff);
-
-			nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
-			stat &= ~0x0001;
-		}
-
-		if (stat & 0x0002) {
-			u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0900));
-			nv_error(priv, "GPC%i/ZCULL trap: %08x\n", gpc,
-				 trap);
-			nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
-			stat &= ~0x0002;
-		}
-
-		if (stat & 0x0004) {
-			u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x1028));
-			nv_error(priv, "GPC%i/CCACHE trap: %08x\n", gpc,
-				 trap);
-			nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
-			stat &= ~0x0004;
-		}
-
-		if (stat & 0x0008) {
-			u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0824));
-			nv_error(priv, "GPC%i/ESETUP trap %08x\n", gpc,
-				 trap);
-			nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
-			stat &= ~0x0008;
-		}
-
-		for (tp = 0; tp < 8; ++tp) {
-			if (stat & (1 << (16 + tp)))
-				nve0_graph_tp_trap(priv, gpc, tp);
-		}
-		stat &= ~0xff0000;
-
-		if (stat) {
-			nv_error(priv, "GPC%i: unknown stat %08x\n",
-				 gpc, stat);
-		}
-	}
-}
-
-
-static void
-nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst,
-		struct nouveau_object *engctx)
-{
-	u32 trap = nv_rd32(priv, 0x400108);
-	int i;
-	int rop;
-
-	if (trap & 0x00000001) {
-		u32 stat = nv_rd32(priv, 0x404000);
-		nv_error(priv, "DISPATCH ch %d [0x%010llx %s] 0x%08x\n",
-			 chid, inst, nouveau_client_name(engctx), stat);
-		nv_wr32(priv, 0x404000, 0xc0000000);
-		nv_wr32(priv, 0x400108, 0x00000001);
-		trap &= ~0x00000001;
-	}
-
-	if (trap & 0x00000010) {
-		u32 stat = nv_rd32(priv, 0x405840);
-		nv_error(priv, "SHADER ch %d [0x%010llx %s] 0x%08x\n",
-			 chid, inst, nouveau_client_name(engctx), stat);
-		nv_wr32(priv, 0x405840, 0xc0000000);
-		nv_wr32(priv, 0x400108, 0x00000010);
-		trap &= ~0x00000010;
-	}
-
-	if (trap & 0x00000100) {
-		u32 stat = nv_rd32(priv, 0x407020);
-		nv_error(priv, "SKED ch %d [0x%010llx %s]:",
-			 chid, inst, nouveau_client_name(engctx));
-
-		for (i = 0; i <= 29; ++i) {
-			if (!(stat & (1 << i)))
-				continue;
-			pr_cont(" ");
-			nouveau_enum_print(nve0_sked_error, i);
-		}
-		pr_cont("\n");
-
-		if (stat & 0x3fffffff)
-			nv_wr32(priv, 0x407020, 0x40000000);
-		nv_wr32(priv, 0x400108, 0x00000100);
-		trap &= ~0x00000100;
-	}
-
-	if (trap & 0x01000000) {
-		nv_error(priv, "GPC ch %d [0x%010llx %s]:\n",
-			 chid, inst, nouveau_client_name(engctx));
-		nve0_graph_gpc_trap(priv);
-		trap &= ~0x01000000;
-	}
-
-	if (trap & 0x02000000) {
-		for (rop = 0; rop < priv->rop_nr; rop++) {
-			u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070));
-			u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144));
-			nv_error(priv,
-				 "ROP%d ch %d [0x%010llx %s] 0x%08x 0x%08x\n",
-				 rop, chid, inst, nouveau_client_name(engctx),
-				 statz, statc);
-			nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
-			nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
-		}
-		nv_wr32(priv, 0x400108, 0x02000000);
-		trap &= ~0x02000000;
-	}
-
-	if (trap) {
-		nv_error(priv, "TRAP ch %d [0x%010llx %s] 0x%08x\n",
-			 chid, inst, nouveau_client_name(engctx), trap);
-		nv_wr32(priv, 0x400108, trap);
-	}
-}
-
-static void
-nve0_graph_intr(struct nouveau_subdev *subdev)
-{
-	struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
-	struct nouveau_engine *engine = nv_engine(subdev);
-	struct nouveau_object *engctx;
-	struct nouveau_handle *handle;
-	struct nvc0_graph_priv *priv = (void *)subdev;
-	u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff;
-	u32 stat = nv_rd32(priv, 0x400100);
-	u32 addr = nv_rd32(priv, 0x400704);
-	u32 mthd = (addr & 0x00003ffc);
-	u32 subc = (addr & 0x00070000) >> 16;
-	u32 data = nv_rd32(priv, 0x400708);
-	u32 code = nv_rd32(priv, 0x400110);
-	u32 class = nv_rd32(priv, 0x404200 + (subc * 4));
-	int chid;
-
-	engctx = nouveau_engctx_get(engine, inst);
-	chid   = pfifo->chid(pfifo, engctx);
-
-	if (stat & 0x00000010) {
-		handle = nouveau_handle_get_class(engctx, class);
-		if (!handle || nv_call(handle->object, mthd, data)) {
-			nv_error(priv,
-				 "ILLEGAL_MTHD ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
-				 chid, inst, nouveau_client_name(engctx), subc,
-				 class, mthd, data);
-		}
-		nouveau_handle_put(handle);
-		nv_wr32(priv, 0x400100, 0x00000010);
-		stat &= ~0x00000010;
-	}
-
-	if (stat & 0x00000020) {
-		nv_error(priv,
-			 "ILLEGAL_CLASS ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
-			 chid, inst, nouveau_client_name(engctx), subc, class,
-			 mthd, data);
-		nv_wr32(priv, 0x400100, 0x00000020);
-		stat &= ~0x00000020;
-	}
-
-	if (stat & 0x00100000) {
-		nv_error(priv, "DATA_ERROR [");
-		nouveau_enum_print(nv50_data_error_names, code);
-		pr_cont("] ch %d [0x%010llx %s] subc %d class 0x%04x mthd 0x%04x data 0x%08x\n",
-			chid, inst, nouveau_client_name(engctx), subc, class,
-			mthd, data);
-		nv_wr32(priv, 0x400100, 0x00100000);
-		stat &= ~0x00100000;
-	}
-
-	if (stat & 0x00200000) {
-		nve0_graph_trap_isr(priv, chid, inst, engctx);
-		nv_wr32(priv, 0x400100, 0x00200000);
-		stat &= ~0x00200000;
-	}
-
-	if (stat & 0x00080000) {
-		nve0_graph_ctxctl_isr(priv);
-		nv_wr32(priv, 0x400100, 0x00080000);
-		stat &= ~0x00080000;
-	}
-
-	if (stat) {
-		nv_error(priv, "unknown stat 0x%08x\n", stat);
-		nv_wr32(priv, 0x400100, stat);
-	}
-
-	nv_wr32(priv, 0x400500, 0x00010001);
-	nouveau_engctx_put(engctx);
-}
-
-static int
-nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
-	       struct nouveau_oclass *oclass, void *data, u32 size,
-	       struct nouveau_object **pobject)
-{
-	struct nouveau_device *device = nv_device(parent);
-	struct nvc0_graph_priv *priv;
-	int ret, i;
-
-	ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
-	*pobject = nv_object(priv);
-	if (ret)
-		return ret;
-
-	nv_subdev(priv)->unit = 0x18001000;
-	nv_subdev(priv)->intr = nve0_graph_intr;
-	nv_engine(priv)->cclass = &nve0_graph_cclass;
-	nv_engine(priv)->sclass = nve0_graph_sclass;
-
-	priv->base.units = nvc0_graph_units;
-
-	if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
-		nv_info(priv, "using external firmware\n");
-		if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
-		    nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
-		    nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
-		    nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
-			return -EINVAL;
-		priv->firmware = true;
-	}
-
-	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
-				&priv->unk4188b4);
-	if (ret)
-		return ret;
-
-	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
-				&priv->unk4188b8);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < 0x1000; i += 4) {
-		nv_wo32(priv->unk4188b4, i, 0x00000010);
-		nv_wo32(priv->unk4188b8, i, 0x00000010);
-	}
-
-	priv->gpc_nr =  nv_rd32(priv, 0x409604) & 0x0000001f;
-	priv->rop_nr = (nv_rd32(priv, 0x409604) & 0x001f0000) >> 16;
-	for (i = 0; i < priv->gpc_nr; i++) {
-		priv->tpc_nr[i] = nv_rd32(priv, GPC_UNIT(i, 0x2608));
-		priv->tpc_total += priv->tpc_nr[i];
-	}
-
-	switch (nv_device(priv)->chipset) {
-	case 0xe4:
-		if (priv->tpc_total == 8)
-			priv->magic_not_rop_nr = 3;
-		else
-		if (priv->tpc_total == 7)
-			priv->magic_not_rop_nr = 1;
-		break;
-	case 0xe7:
-	case 0xe6:
-		priv->magic_not_rop_nr = 1;
-		break;
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-static void
-nve0_graph_init_obj418880(struct nvc0_graph_priv *priv)
-{
-	int i;
-
-	nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000);
-	nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000);
-	for (i = 0; i < 4; i++)
-		nv_wr32(priv, GPC_BCAST(0x0888) + (i * 4), 0x00000000);
-	nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
-	nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
-}
-
-static void
-nve0_graph_init_regs(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x400080, 0x003083c2);
-	nv_wr32(priv, 0x400088, 0x0001ffe7);
-	nv_wr32(priv, 0x40008c, 0x00000000);
-	nv_wr32(priv, 0x400090, 0x00000030);
-	nv_wr32(priv, 0x40013c, 0x003901f7);
-	nv_wr32(priv, 0x400140, 0x00000100);
-	nv_wr32(priv, 0x400144, 0x00000000);
-	nv_wr32(priv, 0x400148, 0x00000110);
-	nv_wr32(priv, 0x400138, 0x00000000);
-	nv_wr32(priv, 0x400130, 0x00000000);
-	nv_wr32(priv, 0x400134, 0x00000000);
-	nv_wr32(priv, 0x400124, 0x00000002);
-}
-
-static void
-nve0_graph_init_units(struct nvc0_graph_priv *priv)
-{
-	nv_wr32(priv, 0x409ffc, 0x00000000);
-	nv_wr32(priv, 0x409c14, 0x00003e3e);
-	nv_wr32(priv, 0x409c24, 0x000f0000);
-
-	nv_wr32(priv, 0x404000, 0xc0000000);
-	nv_wr32(priv, 0x404600, 0xc0000000);
-	nv_wr32(priv, 0x408030, 0xc0000000);
-	nv_wr32(priv, 0x404490, 0xc0000000);
-	nv_wr32(priv, 0x406018, 0xc0000000);
-	nv_wr32(priv, 0x407020, 0xc0000000);
-	nv_wr32(priv, 0x405840, 0xc0000000);
-	nv_wr32(priv, 0x405844, 0x00ffffff);
-
-	nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008);
-	nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000);
-
-}
-
-static void
-nve0_graph_init_gpc_0(struct nvc0_graph_priv *priv)
-{
-	const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
-	u32 data[TPC_MAX / 8];
-	u8  tpcnr[GPC_MAX];
-	int i, gpc, tpc;
-
-	nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001);
-
-	memset(data, 0x00, sizeof(data));
-	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
-	for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
-		do {
-			gpc = (gpc + 1) % priv->gpc_nr;
-		} while (!tpcnr[gpc]);
-		tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
-
-		data[i / 8] |= tpc << ((i % 8) * 4);
-	}
-
-	nv_wr32(priv, GPC_BCAST(0x0980), data[0]);
-	nv_wr32(priv, GPC_BCAST(0x0984), data[1]);
-	nv_wr32(priv, GPC_BCAST(0x0988), data[2]);
-	nv_wr32(priv, GPC_BCAST(0x098c), data[3]);
-
-	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
-						  priv->tpc_nr[gpc]);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
-	}
-
-	nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918);
-	nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
-}
-
-static void
-nve0_graph_init_gpc_1(struct nvc0_graph_priv *priv)
-{
-	int gpc, tpc;
-
-	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-		nv_wr32(priv, GPC_UNIT(gpc, 0x3038), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
-		for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe);
-			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f);
-		}
-		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
-		nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
-	}
-}
-
-static void
-nve0_graph_init_rop(struct nvc0_graph_priv *priv)
-{
-	int rop;
-
-	for (rop = 0; rop < priv->rop_nr; rop++) {
-		nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
-		nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
-		nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff);
-		nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff);
-	}
-}
-
-static int
-nve0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
-{
-	u32 r000260;
-	int i;
-
-	if (priv->firmware) {
-		/* load fuc microcode */
-		r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
-		nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c, &priv->fuc409d);
-		nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac, &priv->fuc41ad);
-		nv_wr32(priv, 0x000260, r000260);
-
-		/* start both of them running */
-		nv_wr32(priv, 0x409840, 0xffffffff);
-		nv_wr32(priv, 0x41a10c, 0x00000000);
-		nv_wr32(priv, 0x40910c, 0x00000000);
-		nv_wr32(priv, 0x41a100, 0x00000002);
-		nv_wr32(priv, 0x409100, 0x00000002);
-		if (!nv_wait(priv, 0x409800, 0x00000001, 0x00000001))
-			nv_error(priv, "0x409800 wait failed\n");
-
-		nv_wr32(priv, 0x409840, 0xffffffff);
-		nv_wr32(priv, 0x409500, 0x7fffffff);
-		nv_wr32(priv, 0x409504, 0x00000021);
-
-		nv_wr32(priv, 0x409840, 0xffffffff);
-		nv_wr32(priv, 0x409500, 0x00000000);
-		nv_wr32(priv, 0x409504, 0x00000010);
-		if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
-			nv_error(priv, "fuc09 req 0x10 timeout\n");
-			return -EBUSY;
-		}
-		priv->size = nv_rd32(priv, 0x409800);
-
-		nv_wr32(priv, 0x409840, 0xffffffff);
-		nv_wr32(priv, 0x409500, 0x00000000);
-		nv_wr32(priv, 0x409504, 0x00000016);
-		if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
-			nv_error(priv, "fuc09 req 0x16 timeout\n");
-			return -EBUSY;
-		}
-
-		nv_wr32(priv, 0x409840, 0xffffffff);
-		nv_wr32(priv, 0x409500, 0x00000000);
-		nv_wr32(priv, 0x409504, 0x00000025);
-		if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
-			nv_error(priv, "fuc09 req 0x25 timeout\n");
-			return -EBUSY;
-		}
-
-		nv_wr32(priv, 0x409800, 0x00000000);
-		nv_wr32(priv, 0x409500, 0x00000001);
-		nv_wr32(priv, 0x409504, 0x00000030);
-		if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
-			nv_error(priv, "fuc09 req 0x30 timeout\n");
-			return -EBUSY;
-		}
-
-		nv_wr32(priv, 0x409810, 0xb00095c8);
-		nv_wr32(priv, 0x409800, 0x00000000);
-		nv_wr32(priv, 0x409500, 0x00000001);
-		nv_wr32(priv, 0x409504, 0x00000031);
-		if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
-			nv_error(priv, "fuc09 req 0x31 timeout\n");
-			return -EBUSY;
-		}
-
-		nv_wr32(priv, 0x409810, 0x00080420);
-		nv_wr32(priv, 0x409800, 0x00000000);
-		nv_wr32(priv, 0x409500, 0x00000001);
-		nv_wr32(priv, 0x409504, 0x00000032);
-		if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
-			nv_error(priv, "fuc09 req 0x32 timeout\n");
-			return -EBUSY;
-		}
-
-		nv_wr32(priv, 0x409614, 0x00000070);
-		nv_wr32(priv, 0x409614, 0x00000770);
-		nv_wr32(priv, 0x40802c, 0x00000001);
-
-		if (priv->data == NULL) {
-			int ret = nve0_grctx_generate(priv);
-			if (ret) {
-				nv_error(priv, "failed to construct context\n");
-				return ret;
-			}
-		}
-
-		return 0;
-	}
-
-	/* load HUB microcode */
-	r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
-	nv_wr32(priv, 0x4091c0, 0x01000000);
-	for (i = 0; i < sizeof(nve0_grhub_data) / 4; i++)
-		nv_wr32(priv, 0x4091c4, nve0_grhub_data[i]);
-
-	nv_wr32(priv, 0x409180, 0x01000000);
-	for (i = 0; i < sizeof(nve0_grhub_code) / 4; i++) {
-		if ((i & 0x3f) == 0)
-			nv_wr32(priv, 0x409188, i >> 6);
-		nv_wr32(priv, 0x409184, nve0_grhub_code[i]);
-	}
-
-	/* load GPC microcode */
-	nv_wr32(priv, 0x41a1c0, 0x01000000);
-	for (i = 0; i < sizeof(nve0_grgpc_data) / 4; i++)
-		nv_wr32(priv, 0x41a1c4, nve0_grgpc_data[i]);
-
-	nv_wr32(priv, 0x41a180, 0x01000000);
-	for (i = 0; i < sizeof(nve0_grgpc_code) / 4; i++) {
-		if ((i & 0x3f) == 0)
-			nv_wr32(priv, 0x41a188, i >> 6);
-		nv_wr32(priv, 0x41a184, nve0_grgpc_code[i]);
-	}
-	nv_wr32(priv, 0x000260, r000260);
-
-	/* start HUB ucode running, it'll init the GPCs */
-	nv_wr32(priv, 0x409800, nv_device(priv)->chipset);
-	nv_wr32(priv, 0x40910c, 0x00000000);
-	nv_wr32(priv, 0x409100, 0x00000002);
-	if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) {
-		nv_error(priv, "HUB_INIT timed out\n");
-		nvc0_graph_ctxctl_debug(priv);
-		return -EBUSY;
-	}
-
-	priv->size = nv_rd32(priv, 0x409804);
-	if (priv->data == NULL) {
-		int ret = nve0_grctx_generate(priv);
-		if (ret) {
-			nv_error(priv, "failed to construct context\n");
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-static int
-nve0_graph_init(struct nouveau_object *object)
-{
-	struct nvc0_graph_priv *priv = (void *)object;
-	int ret;
-
-	ret = nouveau_graph_init(&priv->base);
-	if (ret)
-		return ret;
-
-	nve0_graph_init_obj418880(priv);
-	nve0_graph_init_regs(priv);
-	nve0_graph_init_gpc_0(priv);
-
-	nv_wr32(priv, 0x400500, 0x00010001);
-	nv_wr32(priv, 0x400100, 0xffffffff);
-	nv_wr32(priv, 0x40013c, 0xffffffff);
-
-	nve0_graph_init_units(priv);
-	nve0_graph_init_gpc_1(priv);
-	nve0_graph_init_rop(priv);
-
-	nv_wr32(priv, 0x400108, 0xffffffff);
-	nv_wr32(priv, 0x400138, 0xffffffff);
-	nv_wr32(priv, 0x400118, 0xffffffff);
-	nv_wr32(priv, 0x400130, 0xffffffff);
-	nv_wr32(priv, 0x40011c, 0xffffffff);
-	nv_wr32(priv, 0x400134, 0xffffffff);
-	nv_wr32(priv, 0x400054, 0x34ce3464);
-
-	ret = nve0_graph_init_ctxctl(priv);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-struct nouveau_oclass
-nve0_graph_oclass = {
-	.handle = NV_ENGINE(GR, 0xe0),
-	.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = nve0_graph_ctor,
-		.dtor = nvc0_graph_dtor,
-		.init = nve0_graph_init,
-		.fini = _nouveau_graph_fini,
-	},
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nve4_graph_sclass[] = {
+	{ 0x902d, &nouveau_object_ofuncs },
+	{ 0xa040, &nouveau_object_ofuncs },
+	{ 0xa097, &nouveau_object_ofuncs },
+	{ 0xa0c0, &nouveau_object_ofuncs },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+struct nvc0_graph_init
+nve4_graph_init_regs[] = {
+	{ 0x400080,   1, 0x04, 0x003083c2 },
+	{ 0x400088,   1, 0x04, 0x0001ffe7 },
+	{ 0x40008c,   1, 0x04, 0x00000000 },
+	{ 0x400090,   1, 0x04, 0x00000030 },
+	{ 0x40013c,   1, 0x04, 0x003901f7 },
+	{ 0x400140,   1, 0x04, 0x00000100 },
+	{ 0x400144,   1, 0x04, 0x00000000 },
+	{ 0x400148,   1, 0x04, 0x00000110 },
+	{ 0x400138,   1, 0x04, 0x00000000 },
+	{ 0x400130,   2, 0x04, 0x00000000 },
+	{ 0x400124,   1, 0x04, 0x00000002 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_graph_init_unk58xx[] = {
+	{ 0x405844,   1, 0x04, 0x00ffffff },
+	{ 0x405850,   1, 0x04, 0x00000000 },
+	{ 0x405900,   1, 0x04, 0x0000ff34 },
+	{ 0x405908,   1, 0x04, 0x00000000 },
+	{ 0x405928,   1, 0x04, 0x00000000 },
+	{ 0x40592c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_graph_init_unk70xx[] = {
+	{ 0x407010,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nve4_graph_init_unk5bxx[] = {
+	{ 0x405b50,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_graph_init_gpc[] = {
+	{ 0x418408,   1, 0x04, 0x00000000 },
+	{ 0x4184a0,   1, 0x04, 0x00000000 },
+	{ 0x4184a4,   2, 0x04, 0x00000000 },
+	{ 0x418604,   1, 0x04, 0x00000000 },
+	{ 0x418680,   1, 0x04, 0x00000000 },
+	{ 0x418714,   1, 0x04, 0x00000000 },
+	{ 0x418384,   1, 0x04, 0x00000000 },
+	{ 0x418814,   3, 0x04, 0x00000000 },
+	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{ 0x4188c8,   2, 0x04, 0x00000000 },
+	{ 0x4188d0,   1, 0x04, 0x00010000 },
+	{ 0x4188d4,   1, 0x04, 0x00000001 },
+	{ 0x418910,   1, 0x04, 0x00010001 },
+	{ 0x418914,   1, 0x04, 0x00000301 },
+	{ 0x418918,   1, 0x04, 0x00800000 },
+	{ 0x418980,   1, 0x04, 0x77777770 },
+	{ 0x418984,   3, 0x04, 0x77777777 },
+	{ 0x418c04,   1, 0x04, 0x00000000 },
+	{ 0x418c64,   1, 0x04, 0x00000000 },
+	{ 0x418c68,   1, 0x04, 0x00000000 },
+	{ 0x418c88,   1, 0x04, 0x00000000 },
+	{ 0x418cb4,   2, 0x04, 0x00000000 },
+	{ 0x418d00,   1, 0x04, 0x00000000 },
+	{ 0x418d28,   1, 0x04, 0x00000000 },
+	{ 0x418d2c,   1, 0x04, 0x00000000 },
+	{ 0x418f00,   1, 0x04, 0x00000000 },
+	{ 0x418f08,   1, 0x04, 0x00000000 },
+	{ 0x418f20,   2, 0x04, 0x00000000 },
+	{ 0x418e00,   1, 0x04, 0x00000060 },
+	{ 0x418e08,   1, 0x04, 0x00000000 },
+	{ 0x418e1c,   1, 0x04, 0x00000000 },
+	{ 0x418e20,   1, 0x04, 0x00000000 },
+	{ 0x41900c,   1, 0x04, 0x00000000 },
+	{ 0x419018,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nve4_graph_init_tpc[] = {
+	{ 0x419d0c,   1, 0x04, 0x00000000 },
+	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{ 0x419ab0,   1, 0x04, 0x00000000 },
+	{ 0x419ac8,   1, 0x04, 0x00000000 },
+	{ 0x419ab8,   1, 0x04, 0x000000e7 },
+	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{ 0x419ab4,   1, 0x04, 0x00000000 },
+	{ 0x41980c,   1, 0x04, 0x00000010 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x419850,   1, 0x04, 0x00000004 },
+	{ 0x419854,   2, 0x04, 0x00000000 },
+	{ 0x419c98,   1, 0x04, 0x00000000 },
+	{ 0x419ca8,   1, 0x04, 0x00000000 },
+	{ 0x419cb0,   1, 0x04, 0x01000000 },
+	{ 0x419cb4,   1, 0x04, 0x00000000 },
+	{ 0x419cb8,   1, 0x04, 0x00b08bea },
+	{ 0x419c84,   1, 0x04, 0x00010384 },
+	{ 0x419cbc,   1, 0x04, 0x28137646 },
+	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{ 0x419c80,   1, 0x04, 0x00020232 },
+	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{ 0x419e00,   1, 0x04, 0x00000000 },
+	{ 0x419ea0,   1, 0x04, 0x00000000 },
+	{ 0x419ee4,   1, 0x04, 0x00000000 },
+	{ 0x419ea4,   1, 0x04, 0x00000100 },
+	{ 0x419ea8,   1, 0x04, 0x00000000 },
+	{ 0x419eb4,   1, 0x04, 0x00000000 },
+	{ 0x419eb8,   3, 0x04, 0x00000000 },
+	{ 0x419edc,   1, 0x04, 0x00000000 },
+	{ 0x419f00,   1, 0x04, 0x00000000 },
+	{ 0x419f74,   1, 0x04, 0x00000555 },
+	{}
+};
+
+struct nvc0_graph_init
+nve4_graph_init_unk[] = {
+	{ 0x41be04,   1, 0x04, 0x00000000 },
+	{ 0x41be08,   1, 0x04, 0x00000004 },
+	{ 0x41be0c,   1, 0x04, 0x00000000 },
+	{ 0x41be10,   1, 0x04, 0x003b8bc7 },
+	{ 0x41be14,   2, 0x04, 0x00000000 },
+	{ 0x41bfd4,   1, 0x04, 0x00800000 },
+	{ 0x41bfdc,   1, 0x04, 0x00000000 },
+	{ 0x41bff8,   1, 0x04, 0x00000000 },
+	{ 0x41bffc,   1, 0x04, 0x00000000 },
+	{ 0x41becc,   1, 0x04, 0x00000000 },
+	{ 0x41bee8,   1, 0x04, 0x00000000 },
+	{ 0x41beec,   1, 0x04, 0x00000000 },
+	{}
+};
+
+struct nvc0_graph_init
+nve4_graph_init_unk88xx[] = {
+	{ 0x40880c,   1, 0x04, 0x00000000 },
+	{ 0x408850,   1, 0x04, 0x00000004 },
+	{ 0x408910,   9, 0x04, 0x00000000 },
+	{ 0x408950,   1, 0x04, 0x00000000 },
+	{ 0x408954,   1, 0x04, 0x0000ffff },
+	{ 0x408958,   1, 0x04, 0x00000034 },
+	{ 0x408984,   1, 0x04, 0x00000000 },
+	{ 0x408988,   1, 0x04, 0x08040201 },
+	{ 0x40898c,   1, 0x04, 0x80402010 },
+	{}
+};
+
+int
+nve4_graph_init(struct nouveau_object *object)
+{
+	struct nvc0_graph_oclass *oclass = (void *)object->oclass;
+	struct nvc0_graph_priv *priv = (void *)object;
+	const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
+	u32 data[TPC_MAX / 8] = {};
+	u8  tpcnr[GPC_MAX];
+	int gpc, tpc, rop;
+	int ret, i;
+
+	ret = nouveau_graph_init(&priv->base);
+	if (ret)
+		return ret;
+
+	nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x0888), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x088c), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x0890), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x0894), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
+	nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
+
+	for (i = 0; oclass->mmio[i]; i++)
+		nvc0_graph_mmio(priv, oclass->mmio[i]);
+
+	nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001);
+
+	memset(data, 0x00, sizeof(data));
+	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+	for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
+		do {
+			gpc = (gpc + 1) % priv->gpc_nr;
+		} while (!tpcnr[gpc]);
+		tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
+
+		data[i / 8] |= tpc << ((i % 8) * 4);
+	}
+
+	nv_wr32(priv, GPC_BCAST(0x0980), data[0]);
+	nv_wr32(priv, GPC_BCAST(0x0984), data[1]);
+	nv_wr32(priv, GPC_BCAST(0x0988), data[2]);
+	nv_wr32(priv, GPC_BCAST(0x098c), data[3]);
+
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0914),
+			priv->magic_not_rop_nr << 8 | priv->tpc_nr[gpc]);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 |
+			priv->tpc_total);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
+	}
+
+	nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918);
+	nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
+
+	nv_wr32(priv, 0x400500, 0x00010001);
+
+	nv_wr32(priv, 0x400100, 0xffffffff);
+	nv_wr32(priv, 0x40013c, 0xffffffff);
+
+	nv_wr32(priv, 0x409ffc, 0x00000000);
+	nv_wr32(priv, 0x409c14, 0x00003e3e);
+	nv_wr32(priv, 0x409c24, 0x000f0001);
+	nv_wr32(priv, 0x404000, 0xc0000000);
+	nv_wr32(priv, 0x404600, 0xc0000000);
+	nv_wr32(priv, 0x408030, 0xc0000000);
+	nv_wr32(priv, 0x404490, 0xc0000000);
+	nv_wr32(priv, 0x406018, 0xc0000000);
+	nv_wr32(priv, 0x407020, 0x40000000);
+	nv_wr32(priv, 0x405840, 0xc0000000);
+	nv_wr32(priv, 0x405844, 0x00ffffff);
+	nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008);
+	nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000);
+
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		nv_wr32(priv, GPC_UNIT(gpc, 0x3038), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
+		for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f);
+		}
+		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
+	}
+
+	for (rop = 0; rop < priv->rop_nr; rop++) {
+		nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
+		nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
+		nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff);
+		nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff);
+	}
+
+	nv_wr32(priv, 0x400108, 0xffffffff);
+	nv_wr32(priv, 0x400138, 0xffffffff);
+	nv_wr32(priv, 0x400118, 0xffffffff);
+	nv_wr32(priv, 0x400130, 0xffffffff);
+	nv_wr32(priv, 0x40011c, 0xffffffff);
+	nv_wr32(priv, 0x400134, 0xffffffff);
+
+	nv_wr32(priv, 0x400054, 0x34ce3464);
+	return nvc0_graph_init_ctxctl(priv);
+}
+
+static struct nvc0_graph_init *
+nve4_graph_init_mmio[] = {
+	nve4_graph_init_regs,
+	nvc0_graph_init_unk40xx,
+	nvc0_graph_init_unk44xx,
+	nvc0_graph_init_unk78xx,
+	nvc0_graph_init_unk60xx,
+	nvd9_graph_init_unk64xx,
+	nve4_graph_init_unk58xx,
+	nvc0_graph_init_unk80xx,
+	nve4_graph_init_unk70xx,
+	nve4_graph_init_unk5bxx,
+	nve4_graph_init_gpc,
+	nve4_graph_init_tpc,
+	nve4_graph_init_unk,
+	nve4_graph_init_unk88xx,
+	NULL
+};
+
+#include "fuc/hubnve0.fuc.h"
+
+static struct nvc0_graph_ucode
+nve4_graph_fecs_ucode = {
+	.code.data = nve0_grhub_code,
+	.code.size = sizeof(nve0_grhub_code),
+	.data.data = nve0_grhub_data,
+	.data.size = sizeof(nve0_grhub_data),
+};
+
+#include "fuc/gpcnve0.fuc.h"
+
+static struct nvc0_graph_ucode
+nve4_graph_gpccs_ucode = {
+	.code.data = nve0_grgpc_code,
+	.code.size = sizeof(nve0_grgpc_code),
+	.data.data = nve0_grgpc_data,
+	.data.size = sizeof(nve0_grgpc_data),
+};
+
+struct nouveau_oclass *
+nve4_graph_oclass = &(struct nvc0_graph_oclass) {
+	.base.handle = NV_ENGINE(GR, 0xe4),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_ctor,
+		.dtor = nvc0_graph_dtor,
+		.init = nve4_graph_init,
+		.fini = _nouveau_graph_fini,
+	},
+	.cclass = &nve4_grctx_oclass,
+	.sclass = nve4_graph_sclass,
+	.mmio = nve4_graph_init_mmio,
+	.fecs.ucode = &nve4_graph_fecs_ucode,
+	.gpccs.ucode = &nve4_graph_gpccs_ucode,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "nvc0.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nvf0_graph_sclass[] = {
+	{ 0x902d, &nouveau_object_ofuncs },
+	{ 0xa140, &nouveau_object_ofuncs },
+	{ 0xa197, &nouveau_object_ofuncs },
+	{ 0xa1c0, &nouveau_object_ofuncs },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static struct nvc0_graph_init
+nvf0_graph_init_unk40xx[] = {
+	{ 0x40415c,   1, 0x04, 0x00000000 },
+	{ 0x404170,   1, 0x04, 0x00000000 },
+	{ 0x4041b4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_graph_init_unk58xx[] = {
+	{ 0x405844,   1, 0x04, 0x00ffffff },
+	{ 0x405850,   1, 0x04, 0x00000000 },
+	{ 0x405900,   1, 0x04, 0x0000ff00 },
+	{ 0x405908,   1, 0x04, 0x00000000 },
+	{ 0x405928,   1, 0x04, 0x00000000 },
+	{ 0x40592c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_graph_init_unk70xx[] = {
+	{ 0x407010,   1, 0x04, 0x00000000 },
+	{ 0x407040,   1, 0x04, 0x80440424 },
+	{ 0x407048,   1, 0x04, 0x0000000a },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_graph_init_unk5bxx[] = {
+	{ 0x405b44,   1, 0x04, 0x00000000 },
+	{ 0x405b50,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_graph_init_gpc[] = {
+	{ 0x418408,   1, 0x04, 0x00000000 },
+	{ 0x4184a0,   1, 0x04, 0x00000000 },
+	{ 0x4184a4,   2, 0x04, 0x00000000 },
+	{ 0x418604,   1, 0x04, 0x00000000 },
+	{ 0x418680,   1, 0x04, 0x00000000 },
+	{ 0x418714,   1, 0x04, 0x00000000 },
+	{ 0x418384,   1, 0x04, 0x00000000 },
+	{ 0x418814,   3, 0x04, 0x00000000 },
+	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{ 0x4188c8,   2, 0x04, 0x00000000 },
+	{ 0x4188d0,   1, 0x04, 0x00010000 },
+	{ 0x4188d4,   1, 0x04, 0x00000001 },
+	{ 0x418910,   1, 0x04, 0x00010001 },
+	{ 0x418914,   1, 0x04, 0x00000301 },
+	{ 0x418918,   1, 0x04, 0x00800000 },
+	{ 0x418980,   1, 0x04, 0x77777770 },
+	{ 0x418984,   3, 0x04, 0x77777777 },
+	{ 0x418c04,   1, 0x04, 0x00000000 },
+	{ 0x418c64,   1, 0x04, 0x00000000 },
+	{ 0x418c68,   1, 0x04, 0x00000000 },
+	{ 0x418c88,   1, 0x04, 0x00000000 },
+	{ 0x418cb4,   2, 0x04, 0x00000000 },
+	{ 0x418d00,   1, 0x04, 0x00000000 },
+	{ 0x418d28,   1, 0x04, 0x00000000 },
+	{ 0x418d2c,   1, 0x04, 0x00000000 },
+	{ 0x418f00,   1, 0x04, 0x00000400 },
+	{ 0x418f08,   1, 0x04, 0x00000000 },
+	{ 0x418f20,   1, 0x04, 0x00000000 },
+	{ 0x418f24,   1, 0x04, 0x00000000 },
+	{ 0x418e00,   1, 0x04, 0x00000000 },
+	{ 0x418e08,   1, 0x04, 0x00000000 },
+	{ 0x418e1c,   2, 0x04, 0x00000000 },
+	{ 0x41900c,   1, 0x04, 0x00000000 },
+	{ 0x419018,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static struct nvc0_graph_init
+nvf0_graph_init_tpc[] = {
+	{ 0x419d0c,   1, 0x04, 0x00000000 },
+	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{ 0x419ab0,   1, 0x04, 0x00000000 },
+	{ 0x419ac8,   1, 0x04, 0x00000000 },
+	{ 0x419ab8,   1, 0x04, 0x000000e7 },
+	{ 0x419aec,   1, 0x04, 0x00000000 },
+	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{ 0x419ab4,   1, 0x04, 0x00000000 },
+	{ 0x419aa8,   2, 0x04, 0x00000000 },
+	{ 0x41980c,   1, 0x04, 0x00000010 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x419850,   1, 0x04, 0x00000004 },
+	{ 0x419854,   2, 0x04, 0x00000000 },
+	{ 0x419c98,   1, 0x04, 0x00000000 },
+	{ 0x419ca8,   1, 0x04, 0x00000000 },
+	{ 0x419cb0,   1, 0x04, 0x01000000 },
+	{ 0x419cb4,   1, 0x04, 0x00000000 },
+	{ 0x419cb8,   1, 0x04, 0x00b08bea },
+	{ 0x419c84,   1, 0x04, 0x00010384 },
+	{ 0x419cbc,   1, 0x04, 0x281b3646 },
+	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{ 0x419c80,   1, 0x04, 0x00020230 },
+	{ 0x419ccc,   2, 0x04, 0x00000000 },
+	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{ 0x419e00,   1, 0x04, 0x00000080 },
+	{ 0x419ea0,   1, 0x04, 0x00000000 },
+	{ 0x419ee4,   1, 0x04, 0x00000000 },
+	{ 0x419ea4,   1, 0x04, 0x00000100 },
+	{ 0x419ea8,   1, 0x04, 0x00000000 },
+	{ 0x419eb4,   1, 0x04, 0x00000000 },
+	{ 0x419ebc,   2, 0x04, 0x00000000 },
+	{ 0x419edc,   1, 0x04, 0x00000000 },
+	{ 0x419f00,   1, 0x04, 0x00000000 },
+	{ 0x419ed0,   1, 0x04, 0x00003234 },
+	{ 0x419f74,   1, 0x04, 0x00015555 },
+	{ 0x419f80,   4, 0x04, 0x00000000 },
+	{}
+};
+
+static int
+nvf0_graph_fini(struct nouveau_object *object, bool suspend)
+{
+	struct nvc0_graph_priv *priv = (void *)object;
+	static const struct {
+		u32 addr;
+		u32 data;
+	} magic[] = {
+		{ 0x020520, 0xfffffffc },
+		{ 0x020524, 0xfffffffe },
+		{ 0x020524, 0xfffffffc },
+		{ 0x020524, 0xfffffff8 },
+		{ 0x020524, 0xffffffe0 },
+		{ 0x020530, 0xfffffffe },
+		{ 0x02052c, 0xfffffffa },
+		{ 0x02052c, 0xfffffff0 },
+		{ 0x02052c, 0xffffffc0 },
+		{ 0x02052c, 0xffffff00 },
+		{ 0x02052c, 0xfffffc00 },
+		{ 0x02052c, 0xfffcfc00 },
+		{ 0x02052c, 0xfff0fc00 },
+		{ 0x02052c, 0xff80fc00 },
+		{ 0x020528, 0xfffffffe },
+		{ 0x020528, 0xfffffffc },
+	};
+	int i;
+
+	nv_mask(priv, 0x000200, 0x08001000, 0x00000000);
+	nv_mask(priv, 0x0206b4, 0x00000000, 0x00000000);
+	for (i = 0; i < ARRAY_SIZE(magic); i++) {
+		nv_wr32(priv, magic[i].addr, magic[i].data);
+		nv_wait(priv, magic[i].addr, 0x80000000, 0x00000000);
+	}
+
+	return nouveau_graph_fini(&priv->base, suspend);
+}
+
+static struct nvc0_graph_init *
+nvf0_graph_init_mmio[] = {
+	nve4_graph_init_regs,
+	nvf0_graph_init_unk40xx,
+	nvc0_graph_init_unk44xx,
+	nvc0_graph_init_unk78xx,
+	nvc0_graph_init_unk60xx,
+	nvd9_graph_init_unk64xx,
+	nvf0_graph_init_unk58xx,
+	nvc0_graph_init_unk80xx,
+	nvf0_graph_init_unk70xx,
+	nvf0_graph_init_unk5bxx,
+	nvf0_graph_init_gpc,
+	nvf0_graph_init_tpc,
+	nve4_graph_init_unk,
+	nve4_graph_init_unk88xx,
+	NULL
+};
+
+#include "fuc/hubnvf0.fuc.h"
+
+static struct nvc0_graph_ucode
+nvf0_graph_fecs_ucode = {
+	.code.data = nvf0_grhub_code,
+	.code.size = sizeof(nvf0_grhub_code),
+	.data.data = nvf0_grhub_data,
+	.data.size = sizeof(nvf0_grhub_data),
+};
+
+#include "fuc/gpcnvf0.fuc.h"
+
+static struct nvc0_graph_ucode
+nvf0_graph_gpccs_ucode = {
+	.code.data = nvf0_grgpc_code,
+	.code.size = sizeof(nvf0_grgpc_code),
+	.data.data = nvf0_grgpc_data,
+	.data.size = sizeof(nvf0_grgpc_data),
+};
+
+struct nouveau_oclass *
+nvf0_graph_oclass = &(struct nvc0_graph_oclass) {
+	.base.handle = NV_ENGINE(GR, 0xf0),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_ctor,
+		.dtor = nvc0_graph_dtor,
+		.init = nve4_graph_init,
+		.fini = nvf0_graph_fini,
+	},
+	.cclass = &nvf0_grctx_oclass,
+	.sclass =  nvf0_graph_sclass,
+	.mmio = nvf0_graph_init_mmio,
+	.fecs.ucode = 0 ? &nvf0_graph_fecs_ucode : NULL,
+	.gpccs.ucode = &nvf0_graph_gpccs_ucode,
+}.base;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c	2013-08-25 20:43:22.000000000 -0400
@@ -265,8 +265,8 @@ nv31_mpeg_ctor(struct nouveau_object *pa
 int
 nv31_mpeg_init(struct nouveau_object *object)
 {
-	struct nouveau_engine *engine = nv_engine(object->engine);
-	struct nv31_mpeg_priv *priv = (void *)engine;
+	struct nouveau_engine *engine = nv_engine(object);
+	struct nv31_mpeg_priv *priv = (void *)object;
 	struct nouveau_fb *pfb = nouveau_fb(object);
 	int ret, i;
 
@@ -284,7 +284,10 @@ nv31_mpeg_init(struct nouveau_object *ob
 	/* PMPEG init */
 	nv_wr32(priv, 0x00b32c, 0x00000000);
 	nv_wr32(priv, 0x00b314, 0x00000100);
-	nv_wr32(priv, 0x00b220, nv44_graph_class(priv) ? 0x00000044 : 0x00000031);
+	if (nv_device(priv)->chipset >= 0x40 && nv44_graph_class(priv))
+		nv_wr32(priv, 0x00b220, 0x00000044);
+	else
+		nv_wr32(priv, 0x00b220, 0x00000031);
 	nv_wr32(priv, 0x00b300, 0x02001ec1);
 	nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,6 +61,7 @@ nv40_mpeg_context_ctor(struct nouveau_ob
 	if (ret)
 		return ret;
 
+	nv_wo32(&chan->base.base, 0x78, 0x02001ec1);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -125,13 +125,6 @@ nv50_mpeg_cclass = {
  * PMPEG engine/subdev functions
  ******************************************************************************/
 
-int
-nv50_mpeg_tlb_flush(struct nouveau_engine *engine)
-{
-	nv50_vm_flush_engine(&engine->base, 0x08);
-	return 0;
-}
-
 void
 nv50_mpeg_intr(struct nouveau_subdev *subdev)
 {
@@ -191,7 +184,6 @@ nv50_mpeg_ctor(struct nouveau_object *pa
 	nv_subdev(priv)->intr = nv50_vpe_intr;
 	nv_engine(priv)->cclass = &nv50_mpeg_cclass;
 	nv_engine(priv)->sclass = nv50_mpeg_sclass;
-	nv_engine(priv)->tlb_flush = nv50_mpeg_tlb_flush;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,7 +88,6 @@ nv84_mpeg_ctor(struct nouveau_object *pa
 	nv_subdev(priv)->intr = nv50_mpeg_intr;
 	nv_engine(priv)->cclass = &nv84_mpeg_cclass;
 	nv_engine(priv)->sclass = nv84_mpeg_sclass;
-	nv_engine(priv)->tlb_flush = nv50_mpeg_tlb_flush;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,8 +22,7 @@
  * Authors: Maarten Lankhorst
  */
 
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
 #include <engine/ppp.h>
 
 struct nvc0_ppp_priv {
@@ -91,6 +90,7 @@ nvc0_ppp_ctor(struct nouveau_object *par
 		return ret;
 
 	nv_subdev(priv)->unit = 0x00000002;
+	nv_subdev(priv)->intr = nouveau_falcon_intr;
 	nv_engine(priv)->cclass = &nvc0_ppp_cclass;
 	nv_engine(priv)->sclass = nvc0_ppp_sclass;
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nv84.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,24 +19,19 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
+ * Authors: Ben Skeggs, Ilia Mirkin
  */
 
-#include <core/engctx.h>
-#include <core/class.h>
-
+#include <engine/xtensa.h>
 #include <engine/vp.h>
 
-struct nv84_vp_priv {
-	struct nouveau_engine base;
-};
-
 /*******************************************************************************
  * VP object classes
  ******************************************************************************/
 
 static struct nouveau_oclass
 nv84_vp_sclass[] = {
+	{ 0x7476, &nouveau_object_ofuncs },
 	{},
 };
 
@@ -48,7 +43,7 @@ static struct nouveau_oclass
 nv84_vp_cclass = {
 	.handle = NV_ENGCTX(VP, 0x84),
 	.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = _nouveau_engctx_ctor,
+		.ctor = _nouveau_xtensa_engctx_ctor,
 		.dtor = _nouveau_engctx_dtor,
 		.init = _nouveau_engctx_init,
 		.fini = _nouveau_engctx_fini,
@@ -66,10 +61,10 @@ nv84_vp_ctor(struct nouveau_object *pare
 	     struct nouveau_oclass *oclass, void *data, u32 size,
 	     struct nouveau_object **pobject)
 {
-	struct nv84_vp_priv *priv;
+	struct nouveau_xtensa *priv;
 	int ret;
 
-	ret = nouveau_engine_create(parent, engine, oclass, true,
+	ret = nouveau_xtensa_create(parent, engine, oclass, 0xf000, true,
 				    "PVP", "vp", &priv);
 	*pobject = nv_object(priv);
 	if (ret)
@@ -78,6 +73,8 @@ nv84_vp_ctor(struct nouveau_object *pare
 	nv_subdev(priv)->unit = 0x01020000;
 	nv_engine(priv)->cclass = &nv84_vp_cclass;
 	nv_engine(priv)->sclass = nv84_vp_sclass;
+	priv->fifo_val = 0x111;
+	priv->unkd28 = 0x9c544;
 	return 0;
 }
 
@@ -86,8 +83,10 @@ nv84_vp_oclass = {
 	.handle = NV_ENGINE(VP, 0x84),
 	.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nv84_vp_ctor,
-		.dtor = _nouveau_engine_dtor,
-		.init = _nouveau_engine_init,
-		.fini = _nouveau_engine_fini,
+		.dtor = _nouveau_xtensa_dtor,
+		.init = _nouveau_xtensa_init,
+		.fini = _nouveau_xtensa_fini,
+		.rd32 = _nouveau_xtensa_rd32,
+		.wr32 = _nouveau_xtensa_wr32,
 	},
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/engctx.h>
+#include <core/class.h>
+
+#include <engine/vp.h>
+
+struct nv98_vp_priv {
+	struct nouveau_engine base;
+};
+
+/*******************************************************************************
+ * VP object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_vp_sclass[] = {
+	{},
+};
+
+/*******************************************************************************
+ * PVP context
+ ******************************************************************************/
+
+static struct nouveau_oclass
+nv98_vp_cclass = {
+	.handle = NV_ENGCTX(VP, 0x98),
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = _nouveau_engctx_ctor,
+		.dtor = _nouveau_engctx_dtor,
+		.init = _nouveau_engctx_init,
+		.fini = _nouveau_engctx_fini,
+		.rd32 = _nouveau_engctx_rd32,
+		.wr32 = _nouveau_engctx_wr32,
+	},
+};
+
+/*******************************************************************************
+ * PVP engine/subdev functions
+ ******************************************************************************/
+
+static int
+nv98_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+	     struct nouveau_oclass *oclass, void *data, u32 size,
+	     struct nouveau_object **pobject)
+{
+	struct nv98_vp_priv *priv;
+	int ret;
+
+	ret = nouveau_engine_create(parent, engine, oclass, true,
+				    "PVP", "vp", &priv);
+	*pobject = nv_object(priv);
+	if (ret)
+		return ret;
+
+	nv_subdev(priv)->unit = 0x01020000;
+	nv_engine(priv)->cclass = &nv98_vp_cclass;
+	nv_engine(priv)->sclass = nv98_vp_sclass;
+	return 0;
+}
+
+struct nouveau_oclass
+nv98_vp_oclass = {
+	.handle = NV_ENGINE(VP, 0x98),
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv98_vp_ctor,
+		.dtor = _nouveau_engine_dtor,
+		.init = _nouveau_engine_init,
+		.fini = _nouveau_engine_fini,
+	},
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,8 +22,7 @@
  * Authors: Maarten Lankhorst
  */
 
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
 #include <engine/vp.h>
 
 struct nvc0_vp_priv {
@@ -91,6 +90,7 @@ nvc0_vp_ctor(struct nouveau_object *pare
 		return ret;
 
 	nv_subdev(priv)->unit = 0x00020000;
+	nv_subdev(priv)->intr = nouveau_falcon_intr;
 	nv_engine(priv)->cclass = &nvc0_vp_cclass;
 	nv_engine(priv)->sclass = nvc0_vp_sclass;
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,8 +22,7 @@
  * Authors: Ben Skeggs
  */
 
-#include <core/falcon.h>
-
+#include <engine/falcon.h>
 #include <engine/vp.h>
 
 struct nve0_vp_priv {
@@ -91,6 +90,7 @@ nve0_vp_ctor(struct nouveau_object *pare
 		return ret;
 
 	nv_subdev(priv)->unit = 0x00020000;
+	nv_subdev(priv)->intr = nouveau_falcon_intr;
 	nv_engine(priv)->cclass = &nve0_vp_cclass;
 	nv_engine(priv)->sclass = nve0_vp_sclass;
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/xtensa.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/xtensa.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/engine/xtensa.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/engine/xtensa.c	2013-08-31 17:51:23.000000000 -0400
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2013 Ilia Mirkin
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 <engine/xtensa.h>
+
+u32
+_nouveau_xtensa_rd32(struct nouveau_object *object, u64 addr)
+{
+	struct nouveau_xtensa *xtensa = (void *)object;
+	return nv_rd32(xtensa, xtensa->addr + addr);
+}
+
+void
+_nouveau_xtensa_wr32(struct nouveau_object *object, u64 addr, u32 data)
+{
+	struct nouveau_xtensa *xtensa = (void *)object;
+	nv_wr32(xtensa, xtensa->addr + addr, data);
+}
+
+int
+_nouveau_xtensa_engctx_ctor(struct nouveau_object *parent,
+			    struct nouveau_object *engine,
+			    struct nouveau_oclass *oclass, void *data, u32 size,
+			    struct nouveau_object **pobject)
+{
+	struct nouveau_engctx *engctx;
+	int ret;
+
+	ret = nouveau_engctx_create(parent, engine, oclass, NULL,
+				    0x10000, 0x1000,
+				    NVOBJ_FLAG_ZERO_ALLOC, &engctx);
+	*pobject = nv_object(engctx);
+	return ret;
+}
+
+void
+_nouveau_xtensa_intr(struct nouveau_subdev *subdev)
+{
+	struct nouveau_xtensa *xtensa = (void *)subdev;
+	u32 unk104 = nv_ro32(xtensa, 0xd04);
+	u32 intr = nv_ro32(xtensa, 0xc20);
+	u32 chan = nv_ro32(xtensa, 0xc28);
+	u32 unk10c = nv_ro32(xtensa, 0xd0c);
+
+	if (intr & 0x10)
+		nv_warn(xtensa, "Watchdog interrupt, engine hung.\n");
+	nv_wo32(xtensa, 0xc20, intr);
+	intr = nv_ro32(xtensa, 0xc20);
+	if (unk104 == 0x10001 && unk10c == 0x200 && chan && !intr) {
+		nv_debug(xtensa, "Enabling FIFO_CTRL\n");
+		nv_mask(xtensa, xtensa->addr + 0xd94, 0, xtensa->fifo_val);
+	}
+}
+
+int
+nouveau_xtensa_create_(struct nouveau_object *parent,
+		       struct nouveau_object *engine,
+		       struct nouveau_oclass *oclass, u32 addr, bool enable,
+		       const char *iname, const char *fname,
+		       int length, void **pobject)
+{
+	struct nouveau_xtensa *xtensa;
+	int ret;
+
+	ret = nouveau_engine_create_(parent, engine, oclass, enable, iname,
+				     fname, length, pobject);
+	xtensa = *pobject;
+	if (ret)
+		return ret;
+
+	nv_subdev(xtensa)->intr = _nouveau_xtensa_intr;
+
+	xtensa->addr = addr;
+
+	return 0;
+}
+
+int
+_nouveau_xtensa_init(struct nouveau_object *object)
+{
+	struct nouveau_device *device = nv_device(object);
+	struct nouveau_xtensa *xtensa = (void *)object;
+	const struct firmware *fw;
+	char name[32];
+	int i, ret;
+	u32 tmp;
+
+	ret = nouveau_engine_init(&xtensa->base);
+	if (ret)
+		return ret;
+
+	if (!xtensa->gpu_fw) {
+		snprintf(name, sizeof(name), "/*(DEBLOBBED)*/",
+			 xtensa->addr >> 12);
+
+		ret = reject_firmware(&fw, name, &device->pdev->dev);
+		if (ret) {
+			nv_warn(xtensa, "unable to load firmware %s\n", name);
+			return ret;
+		}
+
+		if (fw->size > 0x40000) {
+			nv_warn(xtensa, "firmware %s too large\n", name);
+			release_firmware(fw);
+			return -EINVAL;
+		}
+
+		ret = nouveau_gpuobj_new(object, NULL, 0x40000, 0x1000, 0,
+					 &xtensa->gpu_fw);
+		if (ret) {
+			release_firmware(fw);
+			return ret;
+		}
+
+		nv_debug(xtensa, "Loading firmware to address: 0x%llx\n",
+			 xtensa->gpu_fw->addr);
+
+		for (i = 0; i < fw->size / 4; i++)
+			nv_wo32(xtensa->gpu_fw, i * 4, *((u32 *)fw->data + i));
+		release_firmware(fw);
+	}
+
+	nv_wo32(xtensa, 0xd10, 0x1fffffff); /* ?? */
+	nv_wo32(xtensa, 0xd08, 0x0fffffff); /* ?? */
+
+	nv_wo32(xtensa, 0xd28, xtensa->unkd28); /* ?? */
+	nv_wo32(xtensa, 0xc20, 0x3f); /* INTR */
+	nv_wo32(xtensa, 0xd84, 0x3f); /* INTR_EN */
+
+	nv_wo32(xtensa, 0xcc0, xtensa->gpu_fw->addr >> 8); /* XT_REGION_BASE */
+	nv_wo32(xtensa, 0xcc4, 0x1c); /* XT_REGION_SETUP */
+	nv_wo32(xtensa, 0xcc8, xtensa->gpu_fw->size >> 8); /* XT_REGION_LIMIT */
+
+	tmp = nv_rd32(xtensa, 0x0);
+	nv_wo32(xtensa, 0xde0, tmp); /* SCRATCH_H2X */
+
+	nv_wo32(xtensa, 0xce8, 0xf); /* XT_REGION_SETUP */
+
+	nv_wo32(xtensa, 0xc20, 0x3f); /* INTR */
+	nv_wo32(xtensa, 0xd84, 0x3f); /* INTR_EN */
+
+	return 0;
+}
+
+int
+_nouveau_xtensa_fini(struct nouveau_object *object, bool suspend)
+{
+	struct nouveau_xtensa *xtensa = (void *)object;
+
+	nv_wo32(xtensa, 0xd84, 0); /* INTR_EN */
+	nv_wo32(xtensa, 0xd94, 0); /* FIFO_CTRL */
+
+	if (!suspend)
+		nouveau_gpuobj_ref(NULL, &xtensa->gpu_fw);
+
+	return nouveau_engine_fini(&xtensa->base, suspend);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/core/device.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/core/device.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/core/device.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/core/device.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,8 +17,7 @@ enum nv_subdev_type {
 	NVDEV_SUBDEV_DEVINIT,
 	NVDEV_SUBDEV_GPIO,
 	NVDEV_SUBDEV_I2C,
-	NVDEV_SUBDEV_CLOCK,
-	NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_CLOCK,
+	NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_I2C,
 
 	/* This grouping of subdevs are initialised right after they've
 	 * been created, and are allowed to assume any subdevs in the
@@ -35,6 +34,7 @@ enum nv_subdev_type {
 	NVDEV_SUBDEV_VM,
 	NVDEV_SUBDEV_BAR,
 	NVDEV_SUBDEV_VOLT,
+	NVDEV_SUBDEV_CLOCK,
 	NVDEV_SUBDEV_THERM,
 
 	NVDEV_ENGINE_DMAOBJ,
@@ -49,6 +49,7 @@ enum nv_subdev_type {
 	NVDEV_ENGINE_PPP,
 	NVDEV_ENGINE_COPY0,
 	NVDEV_ENGINE_COPY1,
+	NVDEV_ENGINE_COPY2,
 	NVDEV_ENGINE_UNK1C1,
 	NVDEV_ENGINE_VENC,
 	NVDEV_ENGINE_DISP,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/core/falcon.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/core/falcon.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/core/falcon.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/core/falcon.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,81 +0,0 @@
-#ifndef __NOUVEAU_FALCON_H__
-#define __NOUVEAU_FALCON_H__
-
-#include <core/engine.h>
-#include <core/engctx.h>
-#include <core/gpuobj.h>
-
-struct nouveau_falcon_chan {
-	struct nouveau_engctx base;
-};
-
-#define nouveau_falcon_context_create(p,e,c,g,s,a,f,d)                         \
-	nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
-#define nouveau_falcon_context_destroy(d)                                      \
-	nouveau_engctx_destroy(&(d)->base)
-#define nouveau_falcon_context_init(d)                                         \
-	nouveau_engctx_init(&(d)->base)
-#define nouveau_falcon_context_fini(d,s)                                       \
-	nouveau_engctx_fini(&(d)->base, (s))
-
-#define _nouveau_falcon_context_ctor _nouveau_engctx_ctor
-#define _nouveau_falcon_context_dtor _nouveau_engctx_dtor
-#define _nouveau_falcon_context_init _nouveau_engctx_init
-#define _nouveau_falcon_context_fini _nouveau_engctx_fini
-#define _nouveau_falcon_context_rd32 _nouveau_engctx_rd32
-#define _nouveau_falcon_context_wr32 _nouveau_engctx_wr32
-
-struct nouveau_falcon_data {
-	bool external;
-};
-
-struct nouveau_falcon {
-	struct nouveau_engine base;
-
-	u32 addr;
-	u8  version;
-	u8  secret;
-
-	struct nouveau_gpuobj *core;
-	bool external;
-
-	struct {
-		u32 limit;
-		u32 *data;
-		u32  size;
-	} code;
-
-	struct {
-		u32 limit;
-		u32 *data;
-		u32  size;
-	} data;
-};
-
-#define nv_falcon(priv) (&(priv)->base)
-
-#define nouveau_falcon_create(p,e,c,b,d,i,f,r)                                 \
-	nouveau_falcon_create_((p), (e), (c), (b), (d), (i), (f),              \
-			       sizeof(**r),(void **)r)
-#define nouveau_falcon_destroy(p)                                              \
-	nouveau_engine_destroy(&(p)->base)
-#define nouveau_falcon_init(p) ({                                              \
-	struct nouveau_falcon *falcon = (p);                                   \
-	_nouveau_falcon_init(nv_object(falcon));                               \
-})
-#define nouveau_falcon_fini(p,s) ({                                            \
-	struct nouveau_falcon *falcon = (p);                                   \
-	_nouveau_falcon_fini(nv_object(falcon), (s));                          \
-})
-
-int nouveau_falcon_create_(struct nouveau_object *, struct nouveau_object *,
-			   struct nouveau_oclass *, u32, bool, const char *,
-			   const char *, int, void **);
-
-#define _nouveau_falcon_dtor _nouveau_engine_dtor
-int  _nouveau_falcon_init(struct nouveau_object *);
-int  _nouveau_falcon_fini(struct nouveau_object *, bool);
-u32  _nouveau_falcon_rd32(struct nouveau_object *, u64);
-void _nouveau_falcon_wr32(struct nouveau_object *, u64, u32);
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/core/mm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/core/mm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/core/mm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/core/mm.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,8 +15,6 @@ struct nouveau_mm {
 	struct list_head nodes;
 	struct list_head free;
 
-	struct mutex mutex;
-
 	u32 block_size;
 	int heap_nodes;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/bsp.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/bsp.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/bsp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/bsp.h	2013-08-25 20:43:22.000000000 -0400
@@ -2,6 +2,7 @@
 #define __NOUVEAU_BSP_H__
 
 extern struct nouveau_oclass nv84_bsp_oclass;
+extern struct nouveau_oclass nv98_bsp_oclass;
 extern struct nouveau_oclass nvc0_bsp_oclass;
 extern struct nouveau_oclass nve0_bsp_oclass;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/copy.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/copy.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/copy.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/copy.h	2013-08-25 20:43:22.000000000 -0400
@@ -8,5 +8,6 @@ extern struct nouveau_oclass nvc0_copy0_
 extern struct nouveau_oclass nvc0_copy1_oclass;
 extern struct nouveau_oclass nve0_copy0_oclass;
 extern struct nouveau_oclass nve0_copy1_oclass;
+extern struct nouveau_oclass nve0_copy2_oclass;
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/falcon.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/falcon.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/falcon.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/falcon.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,83 @@
+#ifndef __NOUVEAU_FALCON_H__
+#define __NOUVEAU_FALCON_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+#include <core/gpuobj.h>
+
+struct nouveau_falcon_chan {
+	struct nouveau_engctx base;
+};
+
+#define nouveau_falcon_context_create(p,e,c,g,s,a,f,d)                         \
+	nouveau_engctx_create((p), (e), (c), (g), (s), (a), (f), (d))
+#define nouveau_falcon_context_destroy(d)                                      \
+	nouveau_engctx_destroy(&(d)->base)
+#define nouveau_falcon_context_init(d)                                         \
+	nouveau_engctx_init(&(d)->base)
+#define nouveau_falcon_context_fini(d,s)                                       \
+	nouveau_engctx_fini(&(d)->base, (s))
+
+#define _nouveau_falcon_context_ctor _nouveau_engctx_ctor
+#define _nouveau_falcon_context_dtor _nouveau_engctx_dtor
+#define _nouveau_falcon_context_init _nouveau_engctx_init
+#define _nouveau_falcon_context_fini _nouveau_engctx_fini
+#define _nouveau_falcon_context_rd32 _nouveau_engctx_rd32
+#define _nouveau_falcon_context_wr32 _nouveau_engctx_wr32
+
+struct nouveau_falcon_data {
+	bool external;
+};
+
+struct nouveau_falcon {
+	struct nouveau_engine base;
+
+	u32 addr;
+	u8  version;
+	u8  secret;
+
+	struct nouveau_gpuobj *core;
+	bool external;
+
+	struct {
+		u32 limit;
+		u32 *data;
+		u32  size;
+	} code;
+
+	struct {
+		u32 limit;
+		u32 *data;
+		u32  size;
+	} data;
+};
+
+#define nv_falcon(priv) (&(priv)->base)
+
+#define nouveau_falcon_create(p,e,c,b,d,i,f,r)                                 \
+	nouveau_falcon_create_((p), (e), (c), (b), (d), (i), (f),              \
+			       sizeof(**r),(void **)r)
+#define nouveau_falcon_destroy(p)                                              \
+	nouveau_engine_destroy(&(p)->base)
+#define nouveau_falcon_init(p) ({                                              \
+	struct nouveau_falcon *falcon = (p);                                   \
+	_nouveau_falcon_init(nv_object(falcon));                               \
+})
+#define nouveau_falcon_fini(p,s) ({                                            \
+	struct nouveau_falcon *falcon = (p);                                   \
+	_nouveau_falcon_fini(nv_object(falcon), (s));                          \
+})
+
+int nouveau_falcon_create_(struct nouveau_object *, struct nouveau_object *,
+			   struct nouveau_oclass *, u32, bool, const char *,
+			   const char *, int, void **);
+
+void nouveau_falcon_intr(struct nouveau_subdev *subdev);
+
+#define _nouveau_falcon_dtor _nouveau_engine_dtor
+int  _nouveau_falcon_init(struct nouveau_object *);
+int  _nouveau_falcon_fini(struct nouveau_object *, bool);
+u32  _nouveau_falcon_rd32(struct nouveau_object *, u64);
+void _nouveau_falcon_wr32(struct nouveau_object *, u64, u32);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/graph.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/graph.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/graph.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/graph.h	2013-08-25 20:43:22.000000000 -0400
@@ -61,8 +61,14 @@ extern struct nouveau_oclass nv34_graph_
 extern struct nouveau_oclass nv35_graph_oclass;
 extern struct nouveau_oclass nv40_graph_oclass;
 extern struct nouveau_oclass nv50_graph_oclass;
-extern struct nouveau_oclass nvc0_graph_oclass;
-extern struct nouveau_oclass nve0_graph_oclass;
+extern struct nouveau_oclass *nvc0_graph_oclass;
+extern struct nouveau_oclass *nvc1_graph_oclass;
+extern struct nouveau_oclass *nvc3_graph_oclass;
+extern struct nouveau_oclass *nvc8_graph_oclass;
+extern struct nouveau_oclass *nvd7_graph_oclass;
+extern struct nouveau_oclass *nvd9_graph_oclass;
+extern struct nouveau_oclass *nve4_graph_oclass;
+extern struct nouveau_oclass *nvf0_graph_oclass;
 
 extern const struct nouveau_bitfield nv04_graph_nsource[];
 extern struct nouveau_ofuncs nv04_graph_ofuncs;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,6 @@ extern struct nouveau_ofuncs nv50_mpeg_o
 int  nv50_mpeg_context_ctor(struct nouveau_object *, struct nouveau_object *,
 			    struct nouveau_oclass *, void *, u32,
 			    struct nouveau_object **);
-int  nv50_mpeg_tlb_flush(struct nouveau_engine *);
 void nv50_mpeg_intr(struct nouveau_subdev *);
 int  nv50_mpeg_init(struct nouveau_object *);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/vp.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/vp.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/vp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/vp.h	2013-08-25 20:43:22.000000000 -0400
@@ -2,6 +2,7 @@
 #define __NOUVEAU_VP_H__
 
 extern struct nouveau_oclass nv84_vp_oclass;
+extern struct nouveau_oclass nv98_vp_oclass;
 extern struct nouveau_oclass nvc0_vp_oclass;
 extern struct nouveau_oclass nve0_vp_oclass;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/engine/xtensa.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,38 @@
+#ifndef __NOUVEAU_XTENSA_H__
+#define __NOUVEAU_XTENSA_H__
+
+#include <core/engine.h>
+#include <core/engctx.h>
+#include <core/gpuobj.h>
+
+struct nouveau_xtensa {
+	struct nouveau_engine base;
+
+	u32 addr;
+	struct nouveau_gpuobj *gpu_fw;
+	u32 fifo_val;
+	u32 unkd28;
+};
+
+#define nouveau_xtensa_create(p,e,c,b,d,i,f,r)				\
+	nouveau_xtensa_create_((p), (e), (c), (b), (d), (i), (f),	\
+			       sizeof(**r),(void **)r)
+
+int _nouveau_xtensa_engctx_ctor(struct nouveau_object *,
+				struct nouveau_object *,
+				struct nouveau_oclass *, void *, u32,
+				struct nouveau_object **);
+
+void _nouveau_xtensa_intr(struct nouveau_subdev *);
+int nouveau_xtensa_create_(struct nouveau_object *,
+			   struct nouveau_object *,
+			   struct nouveau_oclass *, u32, bool,
+			   const char *, const char *,
+			   int, void **);
+#define _nouveau_xtensa_dtor _nouveau_engine_dtor
+int _nouveau_xtensa_init(struct nouveau_object *);
+int _nouveau_xtensa_fini(struct nouveau_object *, bool);
+u32  _nouveau_xtensa_rd32(struct nouveau_object *, u64);
+void _nouveau_xtensa_wr32(struct nouveau_object *, u64, u32);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/clock.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/clock.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/clock.h	2013-08-25 20:43:22.000000000 -0400
@@ -10,8 +10,6 @@ struct nvbios_pll;
 struct nouveau_clock {
 	struct nouveau_subdev base;
 
-	int (*pll_set)(struct nouveau_clock *, u32 type, u32 freq);
-
 	/*XXX: die, these are here *only* to support the completely
 	 *     bat-shit insane what-was-nouveau_hw.c code
 	 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,8 @@ struct nouveau_devinit {
 	struct nouveau_subdev base;
 	bool post;
 	void (*meminit)(struct nouveau_devinit *);
+	int  (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq);
+
 };
 
 static inline struct nouveau_devinit *
@@ -20,11 +22,20 @@ nouveau_devinit(void *obj)
 	nouveau_devinit_create_((p), (e), (o), sizeof(**d), (void **)d)
 #define nouveau_devinit_destroy(p)                                             \
 	nouveau_subdev_destroy(&(p)->base)
+#define nouveau_devinit_init(p) ({                                             \
+	struct nouveau_devinit *d = (p);                                       \
+	_nouveau_devinit_init(nv_object(d));                                   \
+})
+#define nouveau_devinit_fini(p,s) ({                                           \
+	struct nouveau_devinit *d = (p);                                       \
+	_nouveau_devinit_fini(nv_object(d), (s));                              \
+})
 
 int nouveau_devinit_create_(struct nouveau_object *, struct nouveau_object *,
 			    struct nouveau_oclass *, int, void **);
-int nouveau_devinit_init(struct nouveau_devinit *);
-int nouveau_devinit_fini(struct nouveau_devinit *, bool suspend);
+#define _nouveau_devinit_dtor _nouveau_subdev_dtor
+int _nouveau_devinit_init(struct nouveau_object *);
+int _nouveau_devinit_fini(struct nouveau_object *, bool suspend);
 
 extern struct nouveau_oclass nv04_devinit_oclass;
 extern struct nouveau_oclass nv05_devinit_oclass;
@@ -32,9 +43,7 @@ extern struct nouveau_oclass nv10_devini
 extern struct nouveau_oclass nv1a_devinit_oclass;
 extern struct nouveau_oclass nv20_devinit_oclass;
 extern struct nouveau_oclass nv50_devinit_oclass;
-
-void nv04_devinit_dtor(struct nouveau_object *);
-int  nv04_devinit_init(struct nouveau_object *);
-int  nv04_devinit_fini(struct nouveau_object *, bool);
+extern struct nouveau_oclass nva3_devinit_oclass;
+extern struct nouveau_oclass nvc0_devinit_oclass;
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/fb.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/fb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/fb.h	2013-08-25 20:43:22.000000000 -0400
@@ -53,31 +53,7 @@ struct nouveau_fb {
 
 	bool (*memtype_valid)(struct nouveau_fb *, u32 memtype);
 
-	struct {
-		enum {
-			NV_MEM_TYPE_UNKNOWN = 0,
-			NV_MEM_TYPE_STOLEN,
-			NV_MEM_TYPE_SGRAM,
-			NV_MEM_TYPE_SDRAM,
-			NV_MEM_TYPE_DDR1,
-			NV_MEM_TYPE_DDR2,
-			NV_MEM_TYPE_DDR3,
-			NV_MEM_TYPE_GDDR2,
-			NV_MEM_TYPE_GDDR3,
-			NV_MEM_TYPE_GDDR4,
-			NV_MEM_TYPE_GDDR5
-		} type;
-		u64 stolen;
-		u64 size;
-
-		int ranks;
-		int parts;
-
-		int  (*init)(struct nouveau_fb *);
-		int  (*get)(struct nouveau_fb *, u64 size, u32 align,
-			    u32 size_nc, u32 type, struct nouveau_mem **);
-		void (*put)(struct nouveau_fb *, struct nouveau_mem **);
-	} ram;
+	struct nouveau_ram *ram;
 
 	struct nouveau_mm vram;
 	struct nouveau_mm tags;
@@ -102,18 +78,6 @@ nouveau_fb(void *obj)
 	return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
 }
 
-#define nouveau_fb_create(p,e,c,d)                                             \
-	nouveau_subdev_create((p), (e), (c), 0, "PFB", "fb", (d))
-int  nouveau_fb_preinit(struct nouveau_fb *);
-void nouveau_fb_destroy(struct nouveau_fb *);
-int  nouveau_fb_init(struct nouveau_fb *);
-#define nouveau_fb_fini(p,s)                                                   \
-	nouveau_subdev_fini(&(p)->base, (s))
-
-void _nouveau_fb_dtor(struct nouveau_object *);
-int  _nouveau_fb_init(struct nouveau_object *);
-#define _nouveau_fb_fini _nouveau_subdev_fini
-
 extern struct nouveau_oclass nv04_fb_oclass;
 extern struct nouveau_oclass nv10_fb_oclass;
 extern struct nouveau_oclass nv1a_fb_oclass;
@@ -132,40 +96,31 @@ extern struct nouveau_oclass nv4e_fb_ocl
 extern struct nouveau_oclass nv50_fb_oclass;
 extern struct nouveau_oclass nvc0_fb_oclass;
 
-struct nouveau_bios;
-int  nouveau_fb_bios_memtype(struct nouveau_bios *);
-
-bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
-
-void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
-		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
-void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
-void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-int  nv20_fb_vram_init(struct nouveau_fb *);
-void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
-		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
-void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
-void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-int  nv30_fb_init(struct nouveau_object *);
-void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
-		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
-
-void nv40_fb_tile_comp(struct nouveau_fb *, int i, u32 size, u32 flags,
-		       struct nouveau_fb_tile *);
-
-int  nv41_fb_vram_init(struct nouveau_fb *);
-int  nv41_fb_init(struct nouveau_object *);
-void nv41_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
-
-int  nv44_fb_vram_init(struct nouveau_fb *);
-int  nv44_fb_init(struct nouveau_object *);
-void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+struct nouveau_ram {
+	struct nouveau_object base;
+	enum {
+		NV_MEM_TYPE_UNKNOWN = 0,
+		NV_MEM_TYPE_STOLEN,
+		NV_MEM_TYPE_SGRAM,
+		NV_MEM_TYPE_SDRAM,
+		NV_MEM_TYPE_DDR1,
+		NV_MEM_TYPE_DDR2,
+		NV_MEM_TYPE_DDR3,
+		NV_MEM_TYPE_GDDR2,
+		NV_MEM_TYPE_GDDR3,
+		NV_MEM_TYPE_GDDR4,
+		NV_MEM_TYPE_GDDR5
+	} type;
+	u64 stolen;
+	u64 size;
+	u32 tags;
 
-void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
-		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
+	int ranks;
+	int parts;
 
-void nv50_fb_vram_del(struct nouveau_fb *, struct nouveau_mem **);
+	int  (*get)(struct nouveau_fb *, u64 size, u32 align,
+		    u32 size_nc, u32 type, struct nouveau_mem **);
+	void (*put)(struct nouveau_fb *, struct nouveau_mem **);
+};
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/mc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/mc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/mc.h	2013-08-25 20:43:22.000000000 -0400
@@ -20,8 +20,8 @@ nouveau_mc(void *obj)
 	return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC];
 }
 
-#define nouveau_mc_create(p,e,o,d)                                             \
-	nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nouveau_mc_create(p,e,o,m,d)                                           \
+	nouveau_mc_create_((p), (e), (o), (m), sizeof(**d), (void **)d)
 #define nouveau_mc_destroy(p) ({                                               \
 	struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc));        \
 })
@@ -33,7 +33,8 @@ nouveau_mc(void *obj)
 })
 
 int  nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
-			struct nouveau_oclass *, int, void **);
+			struct nouveau_oclass *, const struct nouveau_mc_intr *,
+			int, void **);
 void _nouveau_mc_dtor(struct nouveau_object *);
 int  _nouveau_mc_init(struct nouveau_object *);
 int  _nouveau_mc_fini(struct nouveau_object *, bool);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/vm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/vm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/include/subdev/vm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/include/subdev/vm.h	2013-08-25 20:43:22.000000000 -0400
@@ -55,10 +55,10 @@ struct nouveau_vma {
 struct nouveau_vm {
 	struct nouveau_vmmgr *vmm;
 	struct nouveau_mm mm;
-	int refcount;
+	struct kref refcount;
 
 	struct list_head pgd_list;
-	atomic_t engref[64]; //NVDEV_SUBDEV_NR];
+	atomic_t engref[NVDEV_SUBDEV_NR];
 
 	struct nouveau_vm_pgt *pgt;
 	u32 fpde;
@@ -117,9 +117,6 @@ int  nv04_vm_create(struct nouveau_vmmgr
 		    struct nouveau_vm **);
 void nv04_vmmgr_dtor(struct nouveau_object *);
 
-void nv50_vm_flush_engine(struct nouveau_subdev *, int engine);
-void nvc0_vm_flush_engine(struct nouveau_subdev *, u64 addr, int type);
-
 /* nouveau_vm.c */
 int  nouveau_vm_create(struct nouveau_vmmgr *, u64 offset, u64 length,
 		       u64 mm_offset, u32 block, struct nouveau_vm **);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,7 +53,6 @@ nv50_bar_kmap(struct nouveau_bar *bar, s
 		return ret;
 
 	nouveau_vm_map(vma, mem);
-	nv50_vm_flush_engine(nv_subdev(bar), 6);
 	return 0;
 }
 
@@ -69,7 +68,6 @@ nv50_bar_umap(struct nouveau_bar *bar, s
 		return ret;
 
 	nouveau_vm_map(vma, mem);
-	nv50_vm_flush_engine(nv_subdev(bar), 6);
 	return 0;
 }
 
@@ -77,7 +75,6 @@ static void
 nv50_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
 {
 	nouveau_vm_unmap(vma);
-	nv50_vm_flush_engine(nv_subdev(bar), 6);
 	nouveau_vm_put(vma);
 }
 
@@ -147,6 +144,8 @@ nv50_bar_ctor(struct nouveau_object *par
 	if (ret)
 		return ret;
 
+	atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
 	ret = nouveau_gpuobj_new(nv_object(priv), heap,
 				 ((limit-- - start) >> 12) * 8, 0x1000,
 				 NVOBJ_FLAG_ZERO_ALLOC, &vm->pgt[0].obj[0]);
@@ -179,6 +178,8 @@ nv50_bar_ctor(struct nouveau_object *par
 	if (ret)
 		return ret;
 
+	atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
 	ret = nouveau_vm_ref(vm, &priv->bar1_vm, priv->pgd);
 	nouveau_vm_ref(NULL, &vm, NULL);
 	if (ret)
@@ -237,7 +238,11 @@ nv50_bar_init(struct nouveau_object *obj
 
 	nv_mask(priv, 0x000200, 0x00000100, 0x00000000);
 	nv_mask(priv, 0x000200, 0x00000100, 0x00000100);
-	nv50_vm_flush_engine(nv_subdev(priv), 6);
+	nv_wr32(priv, 0x100c80, 0x00060001);
+	if (!nv_wait(priv, 0x100c80, 0x00000001, 0x00000000)) {
+		nv_error(priv, "vm flush timeout\n");
+		return -EBUSY;
+	}
 
 	nv_wr32(priv, 0x001704, 0x00000000 | priv->mem->addr >> 12);
 	nv_wr32(priv, 0x001704, 0x40000000 | priv->mem->addr >> 12);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,7 +51,6 @@ nvc0_bar_kmap(struct nouveau_bar *bar, s
 		return ret;
 
 	nouveau_vm_map(vma, mem);
-	nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[0].pgd->addr, 5);
 	return 0;
 }
 
@@ -68,18 +67,13 @@ nvc0_bar_umap(struct nouveau_bar *bar, s
 		return ret;
 
 	nouveau_vm_map(vma, mem);
-	nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[1].pgd->addr, 5);
 	return 0;
 }
 
 static void
 nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
 {
-	struct nvc0_bar_priv *priv = (void *)bar;
-	int i = !(vma->vm == priv->bar[0].vm);
-
 	nouveau_vm_unmap(vma);
-	nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[i].pgd->addr, 5);
 	nouveau_vm_put(vma);
 }
 
@@ -116,6 +110,8 @@ nvc0_bar_ctor(struct nouveau_object *par
 	if (ret)
 		return ret;
 
+	atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
 	ret = nouveau_gpuobj_new(nv_object(priv), NULL,
 				 (pci_resource_len(pdev, 3) >> 12) * 8,
 				 0x1000, NVOBJ_FLAG_ZERO_ALLOC,
@@ -150,6 +146,8 @@ nvc0_bar_ctor(struct nouveau_object *par
 	if (ret)
 		return ret;
 
+	atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
 	ret = nouveau_vm_ref(vm, &priv->bar[1].vm, priv->bar[1].pgd);
 	nouveau_vm_ref(NULL, &vm, NULL);
 	if (ret)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/bios/base.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/bios/base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/bios/base.c	2013-08-25 20:43:22.000000000 -0400
@@ -85,11 +85,15 @@ static void
 nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
 {
 	struct nouveau_device *device = nv_device(bios);
+	u64 addr = 0;
 	u32 bar0 = 0;
 	int i;
 
 	if (device->card_type >= NV_50) {
-		u64 addr = (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8;
+		if (  device->card_type < NV_C0 ||
+		    !(nv_rd32(bios, 0x022500) & 0x00000001))
+			addr = (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8;
+
 		if (!addr) {
 			addr  = (u64)nv_rd32(bios, 0x001700) << 16;
 			addr += 0xf0000;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/bios/init.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/bios/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/bios/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -10,7 +10,6 @@
 #include <subdev/bios/gpio.h>
 #include <subdev/bios/init.h>
 #include <subdev/devinit.h>
-#include <subdev/clock.h>
 #include <subdev/i2c.h>
 #include <subdev/vga.h>
 #include <subdev/gpio.h>
@@ -300,9 +299,9 @@ init_wrauxr(struct nvbios_init *init, u3
 static void
 init_prog_pll(struct nvbios_init *init, u32 id, u32 freq)
 {
-	struct nouveau_clock *clk = nouveau_clock(init->bios);
-	if (clk && clk->pll_set && init_exec(init)) {
-		int ret = clk->pll_set(clk, id, freq);
+	struct nouveau_devinit *devinit = nouveau_devinit(init->bios);
+	if (devinit->pll_set && init_exec(init)) {
+		int ret = devinit->pll_set(devinit, id, freq);
 		if (ret)
 			warn("failed to prog pll 0x%08x to %dkHz\n", id, freq);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,9 +22,10 @@
  * Authors: Ben Skeggs
  */
 
-#include <subdev/clock.h>
 #include <subdev/bios.h>
 #include <subdev/bios/pll.h>
+#include <subdev/clock.h>
+#include <subdev/devinit/priv.h>
 
 #include "pll.h"
 
@@ -32,272 +33,12 @@ struct nv04_clock_priv {
 	struct nouveau_clock base;
 };
 
-static int
-powerctrl_1_shift(int chip_version, int reg)
-{
-	int shift = -4;
-
-	if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
-		return shift;
-
-	switch (reg) {
-	case 0x680520:
-		shift += 4;
-	case 0x680508:
-		shift += 4;
-	case 0x680504:
-		shift += 4;
-	case 0x680500:
-		shift += 4;
-	}
-
-	/*
-	 * the shift for vpll regs is only used for nv3x chips with a single
-	 * stage pll
-	 */
-	if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
-			  chip_version == 0x36 || chip_version >= 0x40))
-		shift = -4;
-
-	return shift;
-}
-
-static void
-setPLL_single(struct nv04_clock_priv *priv, u32 reg,
-	      struct nouveau_pll_vals *pv)
-{
-	int chip_version = nouveau_bios(priv)->version.chip;
-	uint32_t oldpll = nv_rd32(priv, reg);
-	int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
-	uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
-	uint32_t saved_powerctrl_1 = 0;
-	int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
-
-	if (oldpll == pll)
-		return;	/* already set */
-
-	if (shift_powerctrl_1 >= 0) {
-		saved_powerctrl_1 = nv_rd32(priv, 0x001584);
-		nv_wr32(priv, 0x001584,
-			(saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
-			1 << shift_powerctrl_1);
-	}
-
-	if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
-		/* upclock -- write new post divider first */
-		nv_wr32(priv, reg, pv->log2P << 16 | (oldpll & 0xffff));
-	else
-		/* downclock -- write new NM first */
-		nv_wr32(priv, reg, (oldpll & 0xffff0000) | pv->NM1);
-
-	if (chip_version < 0x17 && chip_version != 0x11)
-		/* wait a bit on older chips */
-		msleep(64);
-	nv_rd32(priv, reg);
-
-	/* then write the other half as well */
-	nv_wr32(priv, reg, pll);
-
-	if (shift_powerctrl_1 >= 0)
-		nv_wr32(priv, 0x001584, saved_powerctrl_1);
-}
-
-static uint32_t
-new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
-{
-	bool head_a = (reg1 == 0x680508);
-
-	if (ss)	/* single stage pll mode */
-		ramdac580 |= head_a ? 0x00000100 : 0x10000000;
-	else
-		ramdac580 &= head_a ? 0xfffffeff : 0xefffffff;
-
-	return ramdac580;
-}
-
-static void
-setPLL_double_highregs(struct nv04_clock_priv *priv, u32 reg1,
-		       struct nouveau_pll_vals *pv)
-{
-	int chip_version = nouveau_bios(priv)->version.chip;
-	bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
-	uint32_t reg2 = reg1 + ((reg1 == 0x680520) ? 0x5c : 0x70);
-	uint32_t oldpll1 = nv_rd32(priv, reg1);
-	uint32_t oldpll2 = !nv3035 ? nv_rd32(priv, reg2) : 0;
-	uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
-	uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
-	uint32_t oldramdac580 = 0, ramdac580 = 0;
-	bool single_stage = !pv->NM2 || pv->N2 == pv->M2;	/* nv41+ only */
-	uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
-	int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
-
-	/* model specific additions to generic pll1 and pll2 set up above */
-	if (nv3035) {
-		pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
-		       (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
-		pll2 = 0;
-	}
-	if (chip_version > 0x40 && reg1 >= 0x680508) { /* !nv40 */
-		oldramdac580 = nv_rd32(priv, 0x680580);
-		ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
-		if (oldramdac580 != ramdac580)
-			oldpll1 = ~0;	/* force mismatch */
-		if (single_stage)
-			/* magic value used by nvidia in single stage mode */
-			pll2 |= 0x011f;
-	}
-	if (chip_version > 0x70)
-		/* magic bits set by the blob (but not the bios) on g71-73 */
-		pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
-
-	if (oldpll1 == pll1 && oldpll2 == pll2)
-		return;	/* already set */
-
-	if (shift_powerctrl_1 >= 0) {
-		saved_powerctrl_1 = nv_rd32(priv, 0x001584);
-		nv_wr32(priv, 0x001584,
-			(saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
-			1 << shift_powerctrl_1);
-	}
-
-	if (chip_version >= 0x40) {
-		int shift_c040 = 14;
-
-		switch (reg1) {
-		case 0x680504:
-			shift_c040 += 2;
-		case 0x680500:
-			shift_c040 += 2;
-		case 0x680520:
-			shift_c040 += 2;
-		case 0x680508:
-			shift_c040 += 2;
-		}
-
-		savedc040 = nv_rd32(priv, 0xc040);
-		if (shift_c040 != 14)
-			nv_wr32(priv, 0xc040, savedc040 & ~(3 << shift_c040));
-	}
-
-	if (oldramdac580 != ramdac580)
-		nv_wr32(priv, 0x680580, ramdac580);
-
-	if (!nv3035)
-		nv_wr32(priv, reg2, pll2);
-	nv_wr32(priv, reg1, pll1);
-
-	if (shift_powerctrl_1 >= 0)
-		nv_wr32(priv, 0x001584, saved_powerctrl_1);
-	if (chip_version >= 0x40)
-		nv_wr32(priv, 0xc040, savedc040);
-}
-
-static void
-setPLL_double_lowregs(struct nv04_clock_priv *priv, u32 NMNMreg,
-		      struct nouveau_pll_vals *pv)
-{
-	/* When setting PLLs, there is a merry game of disabling and enabling
-	 * various bits of hardware during the process. This function is a
-	 * synthesis of six nv4x traces, nearly each card doing a subtly
-	 * different thing. With luck all the necessary bits for each card are
-	 * combined herein. Without luck it deviates from each card's formula
-	 * so as to not work on any :)
-	 */
-
-	uint32_t Preg = NMNMreg - 4;
-	bool mpll = Preg == 0x4020;
-	uint32_t oldPval = nv_rd32(priv, Preg);
-	uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
-	uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) |
-			0xc << 28 | pv->log2P << 16;
-	uint32_t saved4600 = 0;
-	/* some cards have different maskc040s */
-	uint32_t maskc040 = ~(3 << 14), savedc040;
-	bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
-
-	if (nv_rd32(priv, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
-		return;
-
-	if (Preg == 0x4000)
-		maskc040 = ~0x333;
-	if (Preg == 0x4058)
-		maskc040 = ~(0xc << 24);
-
-	if (mpll) {
-		struct nvbios_pll info;
-		uint8_t Pval2;
-
-		if (nvbios_pll_parse(nouveau_bios(priv), Preg, &info))
-			return;
-
-		Pval2 = pv->log2P + info.bias_p;
-		if (Pval2 > info.max_p)
-			Pval2 = info.max_p;
-		Pval |= 1 << 28 | Pval2 << 20;
-
-		saved4600 = nv_rd32(priv, 0x4600);
-		nv_wr32(priv, 0x4600, saved4600 | 8 << 28);
-	}
-	if (single_stage)
-		Pval |= mpll ? 1 << 12 : 1 << 8;
-
-	nv_wr32(priv, Preg, oldPval | 1 << 28);
-	nv_wr32(priv, Preg, Pval & ~(4 << 28));
-	if (mpll) {
-		Pval |= 8 << 20;
-		nv_wr32(priv, 0x4020, Pval & ~(0xc << 28));
-		nv_wr32(priv, 0x4038, Pval & ~(0xc << 28));
-	}
-
-	savedc040 = nv_rd32(priv, 0xc040);
-	nv_wr32(priv, 0xc040, savedc040 & maskc040);
-
-	nv_wr32(priv, NMNMreg, NMNM);
-	if (NMNMreg == 0x4024)
-		nv_wr32(priv, 0x403c, NMNM);
-
-	nv_wr32(priv, Preg, Pval);
-	if (mpll) {
-		Pval &= ~(8 << 20);
-		nv_wr32(priv, 0x4020, Pval);
-		nv_wr32(priv, 0x4038, Pval);
-		nv_wr32(priv, 0x4600, saved4600);
-	}
-
-	nv_wr32(priv, 0xc040, savedc040);
-
-	if (mpll) {
-		nv_wr32(priv, 0x4020, Pval & ~(1 << 28));
-		nv_wr32(priv, 0x4038, Pval & ~(1 << 28));
-	}
-}
-
-int
-nv04_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
-{
-	struct nv04_clock_priv *priv = (void *)clk;
-	struct nouveau_pll_vals pv;
-	struct nvbios_pll info;
-	int ret;
-
-	ret = nvbios_pll_parse(nouveau_bios(priv), type > 0x405c ?
-			       type : type - 4, &info);
-	if (ret)
-		return ret;
-
-	ret = clk->pll_calc(clk, &info, freq, &pv);
-	if (!ret)
-		return ret;
-
-	return clk->pll_prog(clk, type, &pv);
-}
-
 int
 nv04_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
 		    int clk, struct nouveau_pll_vals *pv)
 {
 	int N1, M1, N2, M2, P;
-	int ret = nv04_pll_calc(clock, info, clk, &N1, &M1, &N2, &M2, &P);
+	int ret = nv04_pll_calc(nv_subdev(clock), info, clk, &N1, &M1, &N2, &M2, &P);
 	if (ret) {
 		pv->refclk = info->refclk;
 		pv->N1 = N1;
@@ -313,17 +54,17 @@ int
 nv04_clock_pll_prog(struct nouveau_clock *clk, u32 reg1,
 		    struct nouveau_pll_vals *pv)
 {
-	struct nv04_clock_priv *priv = (void *)clk;
+	struct nouveau_devinit *devinit = nouveau_devinit(clk);
 	int cv = nouveau_bios(clk)->version.chip;
 
 	if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
 	    cv >= 0x40) {
 		if (reg1 > 0x405c)
-			setPLL_double_highregs(priv, reg1, pv);
+			setPLL_double_highregs(devinit, reg1, pv);
 		else
-			setPLL_double_lowregs(priv, reg1, pv);
+			setPLL_double_lowregs(devinit, reg1, pv);
 	} else
-		setPLL_single(priv, reg1, pv);
+		setPLL_single(devinit, reg1, pv);
 
 	return 0;
 }
@@ -341,7 +82,6 @@ nv04_clock_ctor(struct nouveau_object *p
 	if (ret)
 		return ret;
 
-	priv->base.pll_set = nv04_clock_pll_set;
 	priv->base.pll_calc = nv04_clock_pll_calc;
 	priv->base.pll_prog = nv04_clock_pll_prog;
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,7 +41,6 @@ nv40_clock_ctor(struct nouveau_object *p
 	if (ret)
 		return ret;
 
-	priv->base.pll_set = nv04_clock_pll_set;
 	priv->base.pll_calc = nv04_clock_pll_calc;
 	priv->base.pll_prog = nv04_clock_pll_prog;
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,50 +33,6 @@ struct nv50_clock_priv {
 };
 
 static int
-nv50_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
-{
-	struct nv50_clock_priv *priv = (void *)clk;
-	struct nouveau_bios *bios = nouveau_bios(priv);
-	struct nvbios_pll info;
-	int N1, M1, N2, M2, P;
-	int ret;
-
-	ret = nvbios_pll_parse(bios, type, &info);
-	if (ret) {
-		nv_error(clk, "failed to retrieve pll data, %d\n", ret);
-		return ret;
-	}
-
-	ret = nv04_pll_calc(clk, &info, freq, &N1, &M1, &N2, &M2, &P);
-	if (!ret) {
-		nv_error(clk, "failed pll calculation\n");
-		return ret;
-	}
-
-	switch (info.type) {
-	case PLL_VPLL0:
-	case PLL_VPLL1:
-		nv_wr32(priv, info.reg + 0, 0x10000611);
-		nv_mask(priv, info.reg + 4, 0x00ff00ff, (M1 << 16) | N1);
-		nv_mask(priv, info.reg + 8, 0x7fff00ff, (P  << 28) |
-							(M2 << 16) | N2);
-		break;
-	case PLL_MEMORY:
-		nv_mask(priv, info.reg + 0, 0x01ff0000, (P << 22) |
-						        (info.bias_p << 19) |
-							(P << 16));
-		nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
-		break;
-	default:
-		nv_mask(priv, info.reg + 0, 0x00070000, (P << 16));
-		nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
-		break;
-	}
-
-	return 0;
-}
-
-static int
 nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 		struct nouveau_oclass *oclass, void *data, u32 size,
 		struct nouveau_object **pobject)
@@ -89,7 +45,6 @@ nv50_clock_ctor(struct nouveau_object *p
 	if (ret)
 		return ret;
 
-	priv->base.pll_set = nv50_clock_pll_set;
 	priv->base.pll_calc = nv04_clock_pll_calc;
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,47 +32,13 @@ struct nva3_clock_priv {
 	struct nouveau_clock base;
 };
 
-static int
-nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
-{
-	struct nva3_clock_priv *priv = (void *)clk;
-	struct nouveau_bios *bios = nouveau_bios(priv);
-	struct nvbios_pll info;
-	int N, fN, M, P;
-	int ret;
-
-	ret = nvbios_pll_parse(bios, type, &info);
-	if (ret)
-		return ret;
-
-	ret = nva3_pll_calc(clk, &info, freq, &N, &fN, &M, &P);
-	if (ret < 0)
-		return ret;
-
-	switch (info.type) {
-	case PLL_VPLL0:
-	case PLL_VPLL1:
-		nv_wr32(priv, info.reg + 0, 0x50000610);
-		nv_mask(priv, info.reg + 4, 0x003fffff,
-					    (P << 16) | (M << 8) | N);
-		nv_wr32(priv, info.reg + 8, fN);
-		break;
-	default:
-		nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
 int
 nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
 		    int clk, struct nouveau_pll_vals *pv)
 {
 	int ret, N, M, P;
 
-	ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P);
+	ret = nva3_pll_calc(nv_subdev(clock), info, clk, &N, NULL, &M, &P);
 
 	if (ret > 0) {
 		pv->refclk = info->refclk;
@@ -97,7 +63,6 @@ nva3_clock_ctor(struct nouveau_object *p
 	if (ret)
 		return ret;
 
-	priv->base.pll_set = nva3_clock_pll_set;
 	priv->base.pll_calc = nva3_clock_pll_calc;
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,41 +33,6 @@ struct nvc0_clock_priv {
 };
 
 static int
-nvc0_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
-{
-	struct nvc0_clock_priv *priv = (void *)clk;
-	struct nouveau_bios *bios = nouveau_bios(priv);
-	struct nvbios_pll info;
-	int N, fN, M, P;
-	int ret;
-
-	ret = nvbios_pll_parse(bios, type, &info);
-	if (ret)
-		return ret;
-
-	ret = nva3_pll_calc(clk, &info, freq, &N, &fN, &M, &P);
-	if (ret < 0)
-		return ret;
-
-	switch (info.type) {
-	case PLL_VPLL0:
-	case PLL_VPLL1:
-	case PLL_VPLL2:
-	case PLL_VPLL3:
-		nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
-		nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
-		nv_wr32(priv, info.reg + 0x10, fN << 16);
-		break;
-	default:
-		nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static int
 nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 		struct nouveau_oclass *oclass, void *data, u32 size,
 		struct nouveau_object **pobject)
@@ -80,7 +45,6 @@ nvc0_clock_ctor(struct nouveau_object *p
 	if (ret)
 		return ret;
 
-	priv->base.pll_set = nvc0_clock_pll_set;
 	priv->base.pll_calc = nva3_clock_pll_calc;
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,9 +1,9 @@
 #ifndef __NOUVEAU_PLL_H__
 #define __NOUVEAU_PLL_H__
 
-int nv04_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
+int nv04_pll_calc(struct nouveau_subdev *, struct nvbios_pll *, u32 freq,
 		  int *N1, int *M1, int *N2, int *M2, int *P);
-int nva3_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
+int nva3_pll_calc(struct nouveau_subdev *, struct nvbios_pll *, u32 freq,
 		  int *N, int *fN, int *M, int *P);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,14 +21,13 @@
  * SOFTWARE.
  */
 
-#include <subdev/clock.h>
 #include <subdev/bios.h>
 #include <subdev/bios/pll.h>
 
 #include "pll.h"
 
 static int
-getMNP_single(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
+getMNP_single(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
 	      int *pN, int *pM, int *pP)
 {
 	/* Find M, N and P for a single stage PLL
@@ -39,7 +38,7 @@ getMNP_single(struct nouveau_clock *cloc
 	 * "clk" parameter in kHz
 	 * returns calculated clock
 	 */
-	int cv = nouveau_bios(clock)->version.chip;
+	int cv = nouveau_bios(subdev)->version.chip;
 	int minvco = info->vco1.min_freq, maxvco = info->vco1.max_freq;
 	int minM = info->vco1.min_m, maxM = info->vco1.max_m;
 	int minN = info->vco1.min_n, maxN = info->vco1.max_n;
@@ -124,7 +123,7 @@ getMNP_single(struct nouveau_clock *cloc
 }
 
 static int
-getMNP_double(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
+getMNP_double(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk,
 	      int *pN1, int *pM1, int *pN2, int *pM2, int *pP)
 {
 	/* Find M, N and P for a two stage PLL
@@ -135,7 +134,7 @@ getMNP_double(struct nouveau_clock *cloc
 	 * "clk" parameter in kHz
 	 * returns calculated clock
 	 */
-	int chip_version = nouveau_bios(clock)->version.chip;
+	int chip_version = nouveau_bios(subdev)->version.chip;
 	int minvco1 = info->vco1.min_freq, maxvco1 = info->vco1.max_freq;
 	int minvco2 = info->vco2.min_freq, maxvco2 = info->vco2.max_freq;
 	int minU1 = info->vco1.min_inputfreq, minU2 = info->vco2.min_inputfreq;
@@ -223,20 +222,20 @@ getMNP_double(struct nouveau_clock *cloc
 }
 
 int
-nv04_pll_calc(struct nouveau_clock *clk, struct nvbios_pll *info, u32 freq,
+nv04_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info, u32 freq,
 	      int *N1, int *M1, int *N2, int *M2, int *P)
 {
 	int ret;
 
 	if (!info->vco2.max_freq) {
-		ret = getMNP_single(clk, info, freq, N1, M1, P);
+		ret = getMNP_single(subdev, info, freq, N1, M1, P);
 		*N2 = 1;
 		*M2 = 1;
 	} else {
-		ret = getMNP_double(clk, info, freq, N1, M1, N2, M2, P);
+		ret = getMNP_double(subdev, info, freq, N1, M1, N2, M2, P);
 	}
 
 	if (!ret)
-		nv_error(clk, "unable to compute acceptable pll values\n");
+		nv_error(subdev, "unable to compute acceptable pll values\n");
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,7 @@
 #include "pll.h"
 
 int
-nva3_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
+nva3_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info,
 	      u32 freq, int *pN, int *pfN, int *pM, int *P)
 {
 	u32 best_err = ~0, err;
@@ -50,8 +50,15 @@ nva3_pll_calc(struct nouveau_clock *cloc
 		u32 tmp = freq * *P * M;
 		N  = tmp / info->refclk;
 		fN = tmp % info->refclk;
-		if (!pfN && fN >= info->refclk / 2)
-			N++;
+
+		if (!pfN) {
+			if (fN >= info->refclk / 2)
+				N++;
+		} else {
+			if (fN <  info->refclk / 2)
+				N--;
+			fN = tmp - (N * info->refclk);
+		}
 
 		if (N < info->vco1.min_n)
 			continue;
@@ -66,13 +73,14 @@ nva3_pll_calc(struct nouveau_clock *cloc
 		}
 
 		if (pfN) {
-			*pfN = (((fN << 13) / info->refclk) - 4096) & 0xffff;
+			*pfN = ((fN << 13) + info->refclk / 2) / info->refclk;
+			*pfN = (*pfN - 4096) & 0xffff;
 			return freq;
 		}
 	}
 
 	if (unlikely(best_err == ~0)) {
-		nv_error(clock, "unable to find matching pll values\n");
+		nv_error(subdev, "unable to find matching pll values\n");
 		return -EINVAL;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,18 +29,10 @@
 #include <subdev/bios/init.h>
 
 int
-nouveau_devinit_init(struct nouveau_devinit *devinit)
+_nouveau_devinit_fini(struct nouveau_object *object, bool suspend)
 {
-	int ret = nouveau_subdev_init(&devinit->base);
-	if (ret)
-		return ret;
-
-	return nvbios_init(&devinit->base, devinit->post);
-}
+	struct nouveau_devinit *devinit = (void *)object;
 
-int
-nouveau_devinit_fini(struct nouveau_devinit *devinit, bool suspend)
-{
 	/* force full reinit on resume */
 	if (suspend)
 		devinit->post = true;
@@ -49,6 +41,17 @@ nouveau_devinit_fini(struct nouveau_devi
 }
 
 int
+_nouveau_devinit_init(struct nouveau_object *object)
+{
+	struct nouveau_devinit *devinit = (void *)object;
+	int ret = nouveau_subdev_init(&devinit->base);
+	if (ret)
+		return ret;
+
+	return nvbios_init(&devinit->base, devinit->post);
+}
+
+int
 nouveau_devinit_create_(struct nouveau_object *parent,
 			struct nouveau_object *engine,
 			struct nouveau_oclass *oclass,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,10 +24,10 @@
  *
  */
 
-#include <subdev/devinit.h>
 #include <subdev/vga.h>
 
 #include "fbmem.h"
+#include "priv.h"
 
 struct nv04_devinit_priv {
 	struct nouveau_devinit base;
@@ -111,33 +111,298 @@ nv04_devinit_meminit(struct nouveau_devi
 }
 
 static int
-nv04_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
-		  struct nouveau_oclass *oclass, void *data, u32 size,
-		  struct nouveau_object **pobject)
+powerctrl_1_shift(int chip_version, int reg)
 {
-	struct nv04_devinit_priv *priv;
+	int shift = -4;
+
+	if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
+		return shift;
+
+	switch (reg) {
+	case 0x680520:
+		shift += 4;
+	case 0x680508:
+		shift += 4;
+	case 0x680504:
+		shift += 4;
+	case 0x680500:
+		shift += 4;
+	}
+
+	/*
+	 * the shift for vpll regs is only used for nv3x chips with a single
+	 * stage pll
+	 */
+	if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
+			  chip_version == 0x36 || chip_version >= 0x40))
+		shift = -4;
+
+	return shift;
+}
+
+void
+setPLL_single(struct nouveau_devinit *devinit, u32 reg,
+	      struct nouveau_pll_vals *pv)
+{
+	int chip_version = nouveau_bios(devinit)->version.chip;
+	uint32_t oldpll = nv_rd32(devinit, reg);
+	int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
+	uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
+	uint32_t saved_powerctrl_1 = 0;
+	int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
+
+	if (oldpll == pll)
+		return;	/* already set */
+
+	if (shift_powerctrl_1 >= 0) {
+		saved_powerctrl_1 = nv_rd32(devinit, 0x001584);
+		nv_wr32(devinit, 0x001584,
+			(saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
+			1 << shift_powerctrl_1);
+	}
+
+	if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
+		/* upclock -- write new post divider first */
+		nv_wr32(devinit, reg, pv->log2P << 16 | (oldpll & 0xffff));
+	else
+		/* downclock -- write new NM first */
+		nv_wr32(devinit, reg, (oldpll & 0xffff0000) | pv->NM1);
+
+	if (chip_version < 0x17 && chip_version != 0x11)
+		/* wait a bit on older chips */
+		msleep(64);
+	nv_rd32(devinit, reg);
+
+	/* then write the other half as well */
+	nv_wr32(devinit, reg, pll);
+
+	if (shift_powerctrl_1 >= 0)
+		nv_wr32(devinit, 0x001584, saved_powerctrl_1);
+}
+
+static uint32_t
+new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
+{
+	bool head_a = (reg1 == 0x680508);
+
+	if (ss)	/* single stage pll mode */
+		ramdac580 |= head_a ? 0x00000100 : 0x10000000;
+	else
+		ramdac580 &= head_a ? 0xfffffeff : 0xefffffff;
+
+	return ramdac580;
+}
+
+void
+setPLL_double_highregs(struct nouveau_devinit *devinit, u32 reg1,
+		       struct nouveau_pll_vals *pv)
+{
+	int chip_version = nouveau_bios(devinit)->version.chip;
+	bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
+	uint32_t reg2 = reg1 + ((reg1 == 0x680520) ? 0x5c : 0x70);
+	uint32_t oldpll1 = nv_rd32(devinit, reg1);
+	uint32_t oldpll2 = !nv3035 ? nv_rd32(devinit, reg2) : 0;
+	uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
+	uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
+	uint32_t oldramdac580 = 0, ramdac580 = 0;
+	bool single_stage = !pv->NM2 || pv->N2 == pv->M2;	/* nv41+ only */
+	uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
+	int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
+
+	/* model specific additions to generic pll1 and pll2 set up above */
+	if (nv3035) {
+		pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
+		       (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
+		pll2 = 0;
+	}
+	if (chip_version > 0x40 && reg1 >= 0x680508) { /* !nv40 */
+		oldramdac580 = nv_rd32(devinit, 0x680580);
+		ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
+		if (oldramdac580 != ramdac580)
+			oldpll1 = ~0;	/* force mismatch */
+		if (single_stage)
+			/* magic value used by nvidia in single stage mode */
+			pll2 |= 0x011f;
+	}
+	if (chip_version > 0x70)
+		/* magic bits set by the blob (but not the bios) on g71-73 */
+		pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
+
+	if (oldpll1 == pll1 && oldpll2 == pll2)
+		return;	/* already set */
+
+	if (shift_powerctrl_1 >= 0) {
+		saved_powerctrl_1 = nv_rd32(devinit, 0x001584);
+		nv_wr32(devinit, 0x001584,
+			(saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
+			1 << shift_powerctrl_1);
+	}
+
+	if (chip_version >= 0x40) {
+		int shift_c040 = 14;
+
+		switch (reg1) {
+		case 0x680504:
+			shift_c040 += 2;
+		case 0x680500:
+			shift_c040 += 2;
+		case 0x680520:
+			shift_c040 += 2;
+		case 0x680508:
+			shift_c040 += 2;
+		}
+
+		savedc040 = nv_rd32(devinit, 0xc040);
+		if (shift_c040 != 14)
+			nv_wr32(devinit, 0xc040, savedc040 & ~(3 << shift_c040));
+	}
+
+	if (oldramdac580 != ramdac580)
+		nv_wr32(devinit, 0x680580, ramdac580);
+
+	if (!nv3035)
+		nv_wr32(devinit, reg2, pll2);
+	nv_wr32(devinit, reg1, pll1);
+
+	if (shift_powerctrl_1 >= 0)
+		nv_wr32(devinit, 0x001584, saved_powerctrl_1);
+	if (chip_version >= 0x40)
+		nv_wr32(devinit, 0xc040, savedc040);
+}
+
+void
+setPLL_double_lowregs(struct nouveau_devinit *devinit, u32 NMNMreg,
+		      struct nouveau_pll_vals *pv)
+{
+	/* When setting PLLs, there is a merry game of disabling and enabling
+	 * various bits of hardware during the process. This function is a
+	 * synthesis of six nv4x traces, nearly each card doing a subtly
+	 * different thing. With luck all the necessary bits for each card are
+	 * combined herein. Without luck it deviates from each card's formula
+	 * so as to not work on any :)
+	 */
+
+	uint32_t Preg = NMNMreg - 4;
+	bool mpll = Preg == 0x4020;
+	uint32_t oldPval = nv_rd32(devinit, Preg);
+	uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
+	uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) |
+			0xc << 28 | pv->log2P << 16;
+	uint32_t saved4600 = 0;
+	/* some cards have different maskc040s */
+	uint32_t maskc040 = ~(3 << 14), savedc040;
+	bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
+
+	if (nv_rd32(devinit, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
+		return;
+
+	if (Preg == 0x4000)
+		maskc040 = ~0x333;
+	if (Preg == 0x4058)
+		maskc040 = ~(0xc << 24);
+
+	if (mpll) {
+		struct nvbios_pll info;
+		uint8_t Pval2;
+
+		if (nvbios_pll_parse(nouveau_bios(devinit), Preg, &info))
+			return;
+
+		Pval2 = pv->log2P + info.bias_p;
+		if (Pval2 > info.max_p)
+			Pval2 = info.max_p;
+		Pval |= 1 << 28 | Pval2 << 20;
+
+		saved4600 = nv_rd32(devinit, 0x4600);
+		nv_wr32(devinit, 0x4600, saved4600 | 8 << 28);
+	}
+	if (single_stage)
+		Pval |= mpll ? 1 << 12 : 1 << 8;
+
+	nv_wr32(devinit, Preg, oldPval | 1 << 28);
+	nv_wr32(devinit, Preg, Pval & ~(4 << 28));
+	if (mpll) {
+		Pval |= 8 << 20;
+		nv_wr32(devinit, 0x4020, Pval & ~(0xc << 28));
+		nv_wr32(devinit, 0x4038, Pval & ~(0xc << 28));
+	}
+
+	savedc040 = nv_rd32(devinit, 0xc040);
+	nv_wr32(devinit, 0xc040, savedc040 & maskc040);
+
+	nv_wr32(devinit, NMNMreg, NMNM);
+	if (NMNMreg == 0x4024)
+		nv_wr32(devinit, 0x403c, NMNM);
+
+	nv_wr32(devinit, Preg, Pval);
+	if (mpll) {
+		Pval &= ~(8 << 20);
+		nv_wr32(devinit, 0x4020, Pval);
+		nv_wr32(devinit, 0x4038, Pval);
+		nv_wr32(devinit, 0x4600, saved4600);
+	}
+
+	nv_wr32(devinit, 0xc040, savedc040);
+
+	if (mpll) {
+		nv_wr32(devinit, 0x4020, Pval & ~(1 << 28));
+		nv_wr32(devinit, 0x4038, Pval & ~(1 << 28));
+	}
+}
+
+int
+nv04_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+{
+	struct nouveau_bios *bios = nouveau_bios(devinit);
+	struct nouveau_pll_vals pv;
+	struct nvbios_pll info;
+	int cv = bios->version.chip;
+	int N1, M1, N2, M2, P;
 	int ret;
 
-	ret = nouveau_devinit_create(parent, engine, oclass, &priv);
-	*pobject = nv_object(priv);
+	ret = nvbios_pll_parse(bios, type > 0x405c ? type : type - 4, &info);
 	if (ret)
 		return ret;
 
-	priv->base.meminit = nv04_devinit_meminit;
-	priv->owner = -1;
+	ret = nv04_pll_calc(nv_subdev(devinit), &info, freq,
+			   &N1, &M1, &N2, &M2, &P);
+	if (!ret)
+		return -EINVAL;
+
+	pv.refclk = info.refclk;
+	pv.N1 = N1;
+	pv.M1 = M1;
+	pv.N2 = N2;
+	pv.M2 = M2;
+	pv.log2P = P;
+
+	if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
+	    cv >= 0x40) {
+		if (type > 0x405c)
+			setPLL_double_highregs(devinit, type, &pv);
+		else
+			setPLL_double_lowregs(devinit, type, &pv);
+	} else
+		setPLL_single(devinit, type, &pv);
+
 	return 0;
 }
 
-void
-nv04_devinit_dtor(struct nouveau_object *object)
+int
+nv04_devinit_fini(struct nouveau_object *object, bool suspend)
 {
 	struct nv04_devinit_priv *priv = (void *)object;
 
-	/* restore vga owner saved at first init, and lock crtc regs  */
-	nv_wrvgaowner(priv, priv->owner);
-	nv_lockvgac(priv, true);
+	/* make i2c busses accessible */
+	nv_mask(priv, 0x000200, 0x00000001, 0x00000001);
 
-	nouveau_devinit_destroy(&priv->base);
+	/* unlock extended vga crtc regs, and unslave crtcs */
+	nv_lockvgac(priv, false);
+	if (priv->owner < 0)
+		priv->owner = nv_rdvgaowner(priv);
+	nv_wrvgaowner(priv, 0);
+
+	return nouveau_devinit_fini(&priv->base, suspend);
 }
 
 int
@@ -160,21 +425,35 @@ nv04_devinit_init(struct nouveau_object
 	return nouveau_devinit_init(&priv->base);
 }
 
-int
-nv04_devinit_fini(struct nouveau_object *object, bool suspend)
+void
+nv04_devinit_dtor(struct nouveau_object *object)
 {
 	struct nv04_devinit_priv *priv = (void *)object;
 
-	/* make i2c busses accessible */
-	nv_mask(priv, 0x000200, 0x00000001, 0x00000001);
+	/* restore vga owner saved at first init, and lock crtc regs  */
+	nv_wrvgaowner(priv, priv->owner);
+	nv_lockvgac(priv, true);
 
-	/* unlock extended vga crtc regs, and unslave crtcs */
-	nv_lockvgac(priv, false);
-	if (priv->owner < 0)
-		priv->owner = nv_rdvgaowner(priv);
-	nv_wrvgaowner(priv, 0);
+	nouveau_devinit_destroy(&priv->base);
+}
 
-	return nouveau_devinit_fini(&priv->base, suspend);
+static int
+nv04_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+		  struct nouveau_oclass *oclass, void *data, u32 size,
+		  struct nouveau_object **pobject)
+{
+	struct nv04_devinit_priv *priv;
+	int ret;
+
+	ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+	*pobject = nv_object(priv);
+	if (ret)
+		return ret;
+
+	priv->base.meminit = nv04_devinit_meminit;
+	priv->base.pll_set = nv04_devinit_pll_set;
+	priv->owner = -1;
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,12 +24,12 @@
  *
  */
 
-#include <subdev/devinit.h>
 #include <subdev/bios.h>
 #include <subdev/bios/bmp.h>
 #include <subdev/vga.h>
 
 #include "fbmem.h"
+#include "priv.h"
 
 struct nv05_devinit_priv {
 	struct nouveau_devinit base;
@@ -144,6 +144,7 @@ nv05_devinit_ctor(struct nouveau_object
 		return ret;
 
 	priv->base.meminit = nv05_devinit_meminit;
+	priv->base.pll_set = nv04_devinit_pll_set;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,10 +24,10 @@
  *
  */
 
-#include <subdev/devinit.h>
 #include <subdev/vga.h>
 
 #include "fbmem.h"
+#include "priv.h"
 
 struct nv10_devinit_priv {
 	struct nouveau_devinit base;
@@ -109,6 +109,7 @@ nv10_devinit_ctor(struct nouveau_object
 		return ret;
 
 	priv->base.meminit = nv10_devinit_meminit;
+	priv->base.pll_set = nv04_devinit_pll_set;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,8 +22,7 @@
  * Authors: Ben Skeggs
  */
 
-#include <subdev/devinit.h>
-#include <subdev/vga.h>
+#include "priv.h"
 
 struct nv1a_devinit_priv {
 	struct nouveau_devinit base;
@@ -43,6 +42,7 @@ nv1a_devinit_ctor(struct nouveau_object
 	if (ret)
 		return ret;
 
+	priv->base.pll_set = nv04_devinit_pll_set;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,9 +24,7 @@
  *
  */
 
-#include <subdev/devinit.h>
-#include <subdev/vga.h>
-
+#include "priv.h"
 #include "fbmem.h"
 
 struct nv20_devinit_priv {
@@ -81,6 +79,7 @@ nv20_devinit_ctor(struct nouveau_object
 		return ret;
 
 	priv->base.meminit = nv20_devinit_meminit;
+	priv->base.pll_set = nv04_devinit_pll_set;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Red Hat Inc.
+ * Copyright 2013 Red Hat Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -26,37 +26,55 @@
 #include <subdev/bios/dcb.h>
 #include <subdev/bios/disp.h>
 #include <subdev/bios/init.h>
-#include <subdev/devinit.h>
 #include <subdev/vga.h>
 
-struct nv50_devinit_priv {
-	struct nouveau_devinit base;
-};
+#include "priv.h"
 
 static int
-nv50_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
-		  struct nouveau_oclass *oclass, void *data, u32 size,
-		  struct nouveau_object **pobject)
+nv50_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
 {
-	struct nv50_devinit_priv *priv;
+	struct nv50_devinit_priv *priv = (void *)devinit;
+	struct nouveau_bios *bios = nouveau_bios(priv);
+	struct nvbios_pll info;
+	int N1, M1, N2, M2, P;
 	int ret;
 
-	ret = nouveau_devinit_create(parent, engine, oclass, &priv);
-	*pobject = nv_object(priv);
-	if (ret)
+	ret = nvbios_pll_parse(bios, type, &info);
+	if (ret) {
+		nv_error(devinit, "failed to retrieve pll data, %d\n", ret);
 		return ret;
+	}
 
-	return 0;
-}
+	ret = nv04_pll_calc(nv_subdev(devinit), &info, freq, &N1, &M1, &N2, &M2, &P);
+	if (!ret) {
+		nv_error(devinit, "failed pll calculation\n");
+		return ret;
+	}
 
-static void
-nv50_devinit_dtor(struct nouveau_object *object)
-{
-	struct nv50_devinit_priv *priv = (void *)object;
-	nouveau_devinit_destroy(&priv->base);
+	switch (info.type) {
+	case PLL_VPLL0:
+	case PLL_VPLL1:
+		nv_wr32(priv, info.reg + 0, 0x10000611);
+		nv_mask(priv, info.reg + 4, 0x00ff00ff, (M1 << 16) | N1);
+		nv_mask(priv, info.reg + 8, 0x7fff00ff, (P  << 28) |
+							(M2 << 16) | N2);
+		break;
+	case PLL_MEMORY:
+		nv_mask(priv, info.reg + 0, 0x01ff0000, (P << 22) |
+						        (info.bias_p << 19) |
+							(P << 16));
+		nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
+		break;
+	default:
+		nv_mask(priv, info.reg + 0, 0x00070000, (P << 16));
+		nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
+		break;
+	}
+
+	return 0;
 }
 
-static int
+int
 nv50_devinit_init(struct nouveau_object *object)
 {
 	struct nouveau_bios *bios = nouveau_bios(object);
@@ -103,10 +121,20 @@ nv50_devinit_init(struct nouveau_object
 }
 
 static int
-nv50_devinit_fini(struct nouveau_object *object, bool suspend)
+nv50_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+		  struct nouveau_oclass *oclass, void *data, u32 size,
+		  struct nouveau_object **pobject)
 {
-	struct nv50_devinit_priv *priv = (void *)object;
-	return nouveau_devinit_fini(&priv->base, suspend);
+	struct nv50_devinit_priv *priv;
+	int ret;
+
+	ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+	*pobject = nv_object(priv);
+	if (ret)
+		return ret;
+
+	priv->base.pll_set = nv50_devinit_pll_set;
+	return 0;
 }
 
 struct nouveau_oclass
@@ -114,8 +142,8 @@ nv50_devinit_oclass = {
 	.handle = NV_SUBDEV(DEVINIT, 0x50),
 	.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nv50_devinit_ctor,
-		.dtor = nv50_devinit_dtor,
+		.dtor = _nouveau_devinit_dtor,
 		.init = nv50_devinit_init,
-		.fini = nv50_devinit_fini,
+		.fini = _nouveau_devinit_fini,
 	},
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nva3_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+{
+	struct nva3_devinit_priv *priv = (void *)devinit;
+	struct nouveau_bios *bios = nouveau_bios(priv);
+	struct nvbios_pll info;
+	int N, fN, M, P;
+	int ret;
+
+	ret = nvbios_pll_parse(bios, type, &info);
+	if (ret)
+		return ret;
+
+	ret = nva3_pll_calc(nv_subdev(devinit), &info, freq, &N, &fN, &M, &P);
+	if (ret < 0)
+		return ret;
+
+	switch (info.type) {
+	case PLL_VPLL0:
+	case PLL_VPLL1:
+		nv_wr32(priv, info.reg + 0, 0x50000610);
+		nv_mask(priv, info.reg + 4, 0x003fffff,
+					    (P << 16) | (M << 8) | N);
+		nv_wr32(priv, info.reg + 8, fN);
+		break;
+	default:
+		nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int
+nva3_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+		  struct nouveau_oclass *oclass, void *data, u32 size,
+		  struct nouveau_object **pobject)
+{
+	struct nv50_devinit_priv *priv;
+	int ret;
+
+	ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+	*pobject = nv_object(priv);
+	if (ret)
+		return ret;
+
+	priv->base.pll_set = nva3_devinit_pll_set;
+	return 0;
+}
+
+struct nouveau_oclass
+nva3_devinit_oclass = {
+	.handle = NV_SUBDEV(DEVINIT, 0xa3),
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nva3_devinit_ctor,
+		.dtor = _nouveau_devinit_dtor,
+		.init = nv50_devinit_init,
+		.fini = _nouveau_devinit_fini,
+	},
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nvc0_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq)
+{
+	struct nvc0_devinit_priv *priv = (void *)devinit;
+	struct nouveau_bios *bios = nouveau_bios(priv);
+	struct nvbios_pll info;
+	int N, fN, M, P;
+	int ret;
+
+	ret = nvbios_pll_parse(bios, type, &info);
+	if (ret)
+		return ret;
+
+	ret = nva3_pll_calc(nv_subdev(devinit), &info, freq, &N, &fN, &M, &P);
+	if (ret < 0)
+		return ret;
+
+	switch (info.type) {
+	case PLL_VPLL0:
+	case PLL_VPLL1:
+	case PLL_VPLL2:
+	case PLL_VPLL3:
+		nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
+		nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
+		nv_wr32(priv, info.reg + 0x10, fN << 16);
+		break;
+	default:
+		nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int
+nvc0_devinit_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+		  struct nouveau_oclass *oclass, void *data, u32 size,
+		  struct nouveau_object **pobject)
+{
+	struct nv50_devinit_priv *priv;
+	int ret;
+
+	ret = nouveau_devinit_create(parent, engine, oclass, &priv);
+	*pobject = nv_object(priv);
+	if (ret)
+		return ret;
+
+	priv->base.pll_set = nvc0_devinit_pll_set;
+	if (nv_rd32(priv, 0x022500) & 0x00000001)
+		priv->base.post = true;
+	return 0;
+}
+
+struct nouveau_oclass
+nvc0_devinit_oclass = {
+	.handle = NV_SUBDEV(DEVINIT, 0xc0),
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_devinit_ctor,
+		.dtor = _nouveau_devinit_dtor,
+		.init = nv50_devinit_init,
+		.fini = _nouveau_devinit_fini,
+	},
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,25 @@
+#ifndef __NVKM_DEVINIT_PRIV_H__
+#define __NVKM_DEVINIT_PRIV_H__
+
+#include <subdev/bios.h>
+#include <subdev/bios/pll.h>
+#include <subdev/clock/pll.h>
+#include <subdev/devinit.h>
+
+void nv04_devinit_dtor(struct nouveau_object *);
+int  nv04_devinit_init(struct nouveau_object *);
+int  nv04_devinit_fini(struct nouveau_object *, bool);
+int  nv04_devinit_pll_set(struct nouveau_devinit *, u32, u32);
+
+void setPLL_single(struct nouveau_devinit *, u32, struct nouveau_pll_vals *);
+void setPLL_double_highregs(struct nouveau_devinit *, u32, struct nouveau_pll_vals *);
+void setPLL_double_lowregs(struct nouveau_devinit *, u32, struct nouveau_pll_vals *);
+
+
+struct nv50_devinit_priv {
+	struct nouveau_devinit base;
+};
+
+int  nv50_devinit_init(struct nouveau_object *);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/base.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/base.c	2013-08-25 20:43:22.000000000 -0400
@@ -57,7 +57,57 @@ nouveau_fb_bios_memtype(struct nouveau_b
 }
 
 int
-nouveau_fb_preinit(struct nouveau_fb *pfb)
+_nouveau_fb_fini(struct nouveau_object *object, bool suspend)
+{
+	struct nouveau_fb *pfb = (void *)object;
+	int ret;
+
+	ret = nv_ofuncs(pfb->ram)->fini(nv_object(pfb->ram), suspend);
+	if (ret && suspend)
+		return ret;
+
+	return nouveau_subdev_fini(&pfb->base, suspend);
+}
+
+int
+_nouveau_fb_init(struct nouveau_object *object)
+{
+	struct nouveau_fb *pfb = (void *)object;
+	int ret, i;
+
+	ret = nouveau_subdev_init(&pfb->base);
+	if (ret)
+		return ret;
+
+	ret = nv_ofuncs(pfb->ram)->init(nv_object(pfb->ram));
+	if (ret)
+		return ret;
+
+	for (i = 0; i < pfb->tile.regions; i++)
+		pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
+
+	return 0;
+}
+
+void
+_nouveau_fb_dtor(struct nouveau_object *object)
+{
+	struct nouveau_fb *pfb = (void *)object;
+	int i;
+
+	for (i = 0; i < pfb->tile.regions; i++)
+		pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
+	nouveau_mm_fini(&pfb->tags);
+	nouveau_mm_fini(&pfb->vram);
+
+	nouveau_object_ref(NULL, (struct nouveau_object **)&pfb->ram);
+	nouveau_subdev_destroy(&pfb->base);
+}
+
+int
+nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine,
+		   struct nouveau_oclass *oclass, struct nouveau_oclass *ramcls,
+		   int length, void **pobject)
 {
 	static const char *name[] = {
 		[NV_MEM_TYPE_UNKNOWN] = "unknown",
@@ -72,69 +122,42 @@ nouveau_fb_preinit(struct nouveau_fb *pf
 		[NV_MEM_TYPE_GDDR4  ] = "GDDR4",
 		[NV_MEM_TYPE_GDDR5  ] = "GDDR5",
 	};
-	int ret, tags;
+	struct nouveau_object *ram;
+	struct nouveau_fb *pfb;
+	int ret;
 
-	tags = pfb->ram.init(pfb);
-	if (tags < 0 || !pfb->ram.size) {
+	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PFB", "fb",
+				     length, pobject);
+	pfb = *pobject;
+	if (ret)
+		return ret;
+
+	ret = nouveau_object_ctor(nv_object(pfb), nv_object(pfb),
+				  ramcls, NULL, 0, &ram);
+	if (ret) {
 		nv_fatal(pfb, "error detecting memory configuration!!\n");
-		return (tags < 0) ? tags : -ERANGE;
+		return ret;
 	}
 
+	atomic_dec(&ram->parent->refcount);
+	atomic_dec(&ram->engine->refcount);
+	pfb->ram = (void *)ram;
+
 	if (!nouveau_mm_initialised(&pfb->vram)) {
-		ret = nouveau_mm_init(&pfb->vram, 0, pfb->ram.size >> 12, 1);
+		ret = nouveau_mm_init(&pfb->vram, 0, pfb->ram->size >> 12, 1);
 		if (ret)
 			return ret;
 	}
 
 	if (!nouveau_mm_initialised(&pfb->tags)) {
-		ret = nouveau_mm_init(&pfb->tags, 0, tags ? ++tags : 0, 1);
+		ret = nouveau_mm_init(&pfb->tags, 0, pfb->ram->tags ?
+				     ++pfb->ram->tags : 0, 1);
 		if (ret)
 			return ret;
 	}
 
-	nv_info(pfb, "RAM type: %s\n", name[pfb->ram.type]);
-	nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram.size >> 20));
-	nv_info(pfb, "   ZCOMP: %d tags\n", tags);
-	return 0;
-}
-
-void
-nouveau_fb_destroy(struct nouveau_fb *pfb)
-{
-	int i;
-
-	for (i = 0; i < pfb->tile.regions; i++)
-		pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
-	nouveau_mm_fini(&pfb->tags);
-	nouveau_mm_fini(&pfb->vram);
-
-	nouveau_subdev_destroy(&pfb->base);
-}
-
-void
-_nouveau_fb_dtor(struct nouveau_object *object)
-{
-	struct nouveau_fb *pfb = (void *)object;
-	nouveau_fb_destroy(pfb);
-}
-int
-nouveau_fb_init(struct nouveau_fb *pfb)
-{
-	int ret, i;
-
-	ret = nouveau_subdev_init(&pfb->base);
-	if (ret)
-		return ret;
-
-	for (i = 0; i < pfb->tile.regions; i++)
-		pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
-
+	nv_info(pfb, "RAM type: %s\n", name[pfb->ram->type]);
+	nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram->size >> 20));
+	nv_info(pfb, "   ZCOMP: %d tags\n", pfb->ram->tags);
 	return 0;
 }
-
-int
-_nouveau_fb_init(struct nouveau_object *object)
-{
-	struct nouveau_fb *pfb = (void *)object;
-	return nouveau_fb_init(pfb);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,24 +22,8 @@
  * Authors: Ben Skeggs
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
-#define NV04_PFB_BOOT_0						0x00100000
-#	define NV04_PFB_BOOT_0_RAM_AMOUNT			0x00000003
-#	define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB			0x00000000
-#	define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB			0x00000001
-#	define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB			0x00000002
-#	define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB			0x00000003
-#	define NV04_PFB_BOOT_0_RAM_WIDTH_128			0x00000004
-#	define NV04_PFB_BOOT_0_RAM_TYPE				0x00000028
-#	define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT		0x00000000
-#	define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT		0x00000008
-#	define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK	0x00000010
-#	define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT		0x00000018
-#	define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT		0x00000020
-#	define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16		0x00000028
-#	define NV04_PFB_BOOT_0_UMA_ENABLE			0x00000100
-#	define NV04_PFB_BOOT_0_UMA_SIZE				0x0000f000
 #define NV04_PFB_CFG0						0x00100200
 
 struct nv04_fb_priv {
@@ -56,37 +40,6 @@ nv04_fb_memtype_valid(struct nouveau_fb
 }
 
 static int
-nv04_fb_vram_init(struct nouveau_fb *pfb)
-{
-	u32 boot0 = nv_rd32(pfb, NV04_PFB_BOOT_0);
-	if (boot0 & 0x00000100) {
-		pfb->ram.size  = ((boot0 >> 12) & 0xf) * 2 + 2;
-		pfb->ram.size *= 1024 * 1024;
-	} else {
-		switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
-		case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
-			pfb->ram.size = 32 * 1024 * 1024;
-			break;
-		case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
-			pfb->ram.size = 16 * 1024 * 1024;
-			break;
-		case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
-			pfb->ram.size = 8 * 1024 * 1024;
-			break;
-		case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
-			pfb->ram.size = 4 * 1024 * 1024;
-			break;
-		}
-	}
-
-	if ((boot0 & 0x00000038) <= 0x10)
-		pfb->ram.type = NV_MEM_TYPE_SGRAM;
-	else
-		pfb->ram.type = NV_MEM_TYPE_SDRAM;
-	return 0;
-}
-
-static int
 nv04_fb_init(struct nouveau_object *object)
 {
 	struct nv04_fb_priv *priv = (void *)object;
@@ -112,14 +65,13 @@ nv04_fb_ctor(struct nouveau_object *pare
 	struct nv04_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv04_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv04_fb_vram_init;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,25 +24,12 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv10_fb_priv {
 	struct nouveau_fb base;
 };
 
-static int
-nv10_fb_vram_init(struct nouveau_fb *pfb)
-{
-	u32 cfg0 = nv_rd32(pfb, 0x100200);
-	if (cfg0 & 0x00000001)
-		pfb->ram.type = NV_MEM_TYPE_DDR1;
-	else
-		pfb->ram.type = NV_MEM_TYPE_SDRAM;
-
-	pfb->ram.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
-	return 0;
-}
-
 void
 nv10_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
 		  u32 flags, struct nouveau_fb_tile *tile)
@@ -78,18 +65,17 @@ nv10_fb_ctor(struct nouveau_object *pare
 	struct nv10_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv10_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv10_fb_vram_init;
 	priv->base.tile.regions = 8;
 	priv->base.tile.init = nv10_fb_tile_init;
 	priv->base.tile.fini = nv10_fb_tile_fini;
 	priv->base.tile.prog = nv10_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,38 +24,13 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv1a_fb_priv {
 	struct nouveau_fb base;
 };
 
 static int
-nv1a_fb_vram_init(struct nouveau_fb *pfb)
-{
-	struct pci_dev *bridge;
-	u32 mem, mib;
-
-	bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
-	if (!bridge) {
-		nv_fatal(pfb, "no bridge device\n");
-		return -ENODEV;
-	}
-
-	if (nv_device(pfb)->chipset == 0x1a) {
-		pci_read_config_dword(bridge, 0x7c, &mem);
-		mib = ((mem >> 6) & 31) + 1;
-	} else {
-		pci_read_config_dword(bridge, 0x84, &mem);
-		mib = ((mem >> 4) & 127) + 1;
-	}
-
-	pfb->ram.type = NV_MEM_TYPE_STOLEN;
-	pfb->ram.size = mib * 1024 * 1024;
-	return 0;
-}
-
-static int
 nv1a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	     struct nouveau_oclass *oclass, void *data, u32 size,
 	     struct nouveau_object **pobject)
@@ -63,18 +38,17 @@ nv1a_fb_ctor(struct nouveau_object *pare
 	struct nv1a_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv1a_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv1a_fb_vram_init;
 	priv->base.tile.regions = 8;
 	priv->base.tile.init = nv10_fb_tile_init;
 	priv->base.tile.fini = nv10_fb_tile_fini;
 	priv->base.tile.prog = nv10_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,29 +24,12 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv20_fb_priv {
 	struct nouveau_fb base;
 };
 
-int
-nv20_fb_vram_init(struct nouveau_fb *pfb)
-{
-	u32 pbus1218 = nv_rd32(pfb, 0x001218);
-
-	switch (pbus1218 & 0x00000300) {
-	case 0x00000000: pfb->ram.type = NV_MEM_TYPE_SDRAM; break;
-	case 0x00000100: pfb->ram.type = NV_MEM_TYPE_DDR1; break;
-	case 0x00000200: pfb->ram.type = NV_MEM_TYPE_GDDR3; break;
-	case 0x00000300: pfb->ram.type = NV_MEM_TYPE_GDDR2; break;
-	}
-	pfb->ram.size  = (nv_rd32(pfb, 0x10020c) & 0xff000000);
-	pfb->ram.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
-
-	return nv_rd32(pfb, 0x100320);
-}
-
 void
 nv20_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
 		  u32 flags, struct nouveau_fb_tile *tile)
@@ -65,7 +48,7 @@ nv20_fb_tile_comp(struct nouveau_fb *pfb
 		  struct nouveau_fb_tile *tile)
 {
 	u32 tiles = DIV_ROUND_UP(size, 0x40);
-	u32 tags  = round_up(tiles / pfb->ram.parts, 0x40);
+	u32 tags  = round_up(tiles / pfb->ram->parts, 0x40);
 	if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
 		if (!(flags & 2)) tile->zcomp = 0x00000000; /* Z16 */
 		else              tile->zcomp = 0x04000000; /* Z24S8 */
@@ -105,19 +88,18 @@ nv20_fb_ctor(struct nouveau_object *pare
 	struct nv20_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv20_fb_vram_init;
 	priv->base.tile.regions = 8;
 	priv->base.tile.init = nv20_fb_tile_init;
 	priv->base.tile.comp = nv20_fb_tile_comp;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv20_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv25_fb_priv {
 	struct nouveau_fb base;
@@ -35,7 +35,7 @@ nv25_fb_tile_comp(struct nouveau_fb *pfb
 		  struct nouveau_fb_tile *tile)
 {
 	u32 tiles = DIV_ROUND_UP(size, 0x40);
-	u32 tags  = round_up(tiles / pfb->ram.parts, 0x40);
+	u32 tags  = round_up(tiles / pfb->ram->parts, 0x40);
 	if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
 		if (!(flags & 2)) tile->zcomp = 0x00100000; /* Z16 */
 		else              tile->zcomp = 0x00200000; /* Z24S8 */
@@ -54,19 +54,18 @@ nv25_fb_ctor(struct nouveau_object *pare
 	struct nv25_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv20_fb_vram_init;
 	priv->base.tile.regions = 8;
 	priv->base.tile.init = nv20_fb_tile_init;
 	priv->base.tile.comp = nv25_fb_tile_comp;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv20_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv30_fb_priv {
 	struct nouveau_fb base;
@@ -54,7 +54,7 @@ nv30_fb_tile_comp(struct nouveau_fb *pfb
 		  struct nouveau_fb_tile *tile)
 {
 	u32 tiles = DIV_ROUND_UP(size, 0x40);
-	u32 tags  = round_up(tiles / pfb->ram.parts, 0x40);
+	u32 tags  = round_up(tiles / pfb->ram->parts, 0x40);
 	if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
 		if (flags & 2) tile->zcomp |= 0x01000000; /* Z16 */
 		else           tile->zcomp |= 0x02000000; /* Z24S8 */
@@ -132,19 +132,18 @@ nv30_fb_ctor(struct nouveau_object *pare
 	struct nv30_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv20_fb_vram_init;
 	priv->base.tile.regions = 8;
 	priv->base.tile.init = nv30_fb_tile_init;
 	priv->base.tile.comp = nv30_fb_tile_comp;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv20_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv35_fb_priv {
 	struct nouveau_fb base;
@@ -35,7 +35,7 @@ nv35_fb_tile_comp(struct nouveau_fb *pfb
 		  struct nouveau_fb_tile *tile)
 {
 	u32 tiles = DIV_ROUND_UP(size, 0x40);
-	u32 tags  = round_up(tiles / pfb->ram.parts, 0x40);
+	u32 tags  = round_up(tiles / pfb->ram->parts, 0x40);
 	if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
 		if (flags & 2) tile->zcomp |= 0x04000000; /* Z16 */
 		else           tile->zcomp |= 0x08000000; /* Z24S8 */
@@ -55,19 +55,18 @@ nv35_fb_ctor(struct nouveau_object *pare
 	struct nv35_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv20_fb_vram_init;
 	priv->base.tile.regions = 8;
 	priv->base.tile.init = nv30_fb_tile_init;
 	priv->base.tile.comp = nv35_fb_tile_comp;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv20_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv36_fb_priv {
 	struct nouveau_fb base;
@@ -35,7 +35,7 @@ nv36_fb_tile_comp(struct nouveau_fb *pfb
 		  struct nouveau_fb_tile *tile)
 {
 	u32 tiles = DIV_ROUND_UP(size, 0x40);
-	u32 tags  = round_up(tiles / pfb->ram.parts, 0x40);
+	u32 tags  = round_up(tiles / pfb->ram->parts, 0x40);
 	if (!nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
 		if (flags & 2) tile->zcomp |= 0x10000000; /* Z16 */
 		else           tile->zcomp |= 0x20000000; /* Z24S8 */
@@ -55,19 +55,18 @@ nv36_fb_ctor(struct nouveau_object *pare
 	struct nv36_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv20_fb_vram_init;
 	priv->base.tile.regions = 8;
 	priv->base.tile.init = nv30_fb_tile_init;
 	priv->base.tile.comp = nv36_fb_tile_comp;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv20_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,34 +24,18 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv40_fb_priv {
 	struct nouveau_fb base;
 };
 
-static int
-nv40_fb_vram_init(struct nouveau_fb *pfb)
-{
-	u32 pbus1218 = nv_rd32(pfb, 0x001218);
-	switch (pbus1218 & 0x00000300) {
-	case 0x00000000: pfb->ram.type = NV_MEM_TYPE_SDRAM; break;
-	case 0x00000100: pfb->ram.type = NV_MEM_TYPE_DDR1; break;
-	case 0x00000200: pfb->ram.type = NV_MEM_TYPE_GDDR3; break;
-	case 0x00000300: pfb->ram.type = NV_MEM_TYPE_DDR2; break;
-	}
-
-	pfb->ram.size  =  nv_rd32(pfb, 0x10020c) & 0xff000000;
-	pfb->ram.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
-	return nv_rd32(pfb, 0x100320);
-}
-
 void
 nv40_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags,
 		  struct nouveau_fb_tile *tile)
 {
 	u32 tiles = DIV_ROUND_UP(size, 0x80);
-	u32 tags  = round_up(tiles / pfb->ram.parts, 0x100);
+	u32 tags  = round_up(tiles / pfb->ram->parts, 0x100);
 	if ( (flags & 2) &&
 	    !nouveau_mm_head(&pfb->tags, 1, tags, tags, 1, &tile->tag)) {
 		tile->zcomp  = 0x28000000; /* Z24S8_SPLIT_GRAD */
@@ -85,19 +69,18 @@ nv40_fb_ctor(struct nouveau_object *pare
 	struct nv40_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv40_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv40_fb_vram_init;
 	priv->base.tile.regions = 8;
 	priv->base.tile.init = nv30_fb_tile_init;
 	priv->base.tile.comp = nv40_fb_tile_comp;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv20_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,28 +24,12 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv41_fb_priv {
 	struct nouveau_fb base;
 };
 
-int
-nv41_fb_vram_init(struct nouveau_fb *pfb)
-{
-	u32 pfb474 = nv_rd32(pfb, 0x100474);
-	if (pfb474 & 0x00000004)
-		pfb->ram.type = NV_MEM_TYPE_GDDR3;
-	if (pfb474 & 0x00000002)
-		pfb->ram.type = NV_MEM_TYPE_DDR2;
-	if (pfb474 & 0x00000001)
-		pfb->ram.type = NV_MEM_TYPE_DDR1;
-
-	pfb->ram.size =   nv_rd32(pfb, 0x10020c) & 0xff000000;
-	pfb->ram.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
-	return nv_rd32(pfb, 0x100320);
-}
-
 void
 nv41_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
 {
@@ -78,19 +62,18 @@ nv41_fb_ctor(struct nouveau_object *pare
 	struct nv41_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv41_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv41_fb_vram_init;
 	priv->base.tile.regions = 12;
 	priv->base.tile.init = nv30_fb_tile_init;
 	priv->base.tile.comp = nv40_fb_tile_comp;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv41_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,27 +24,12 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv44_fb_priv {
 	struct nouveau_fb base;
 };
 
-int
-nv44_fb_vram_init(struct nouveau_fb *pfb)
-{
-	u32 pfb474 = nv_rd32(pfb, 0x100474);
-	if (pfb474 & 0x00000004)
-		pfb->ram.type = NV_MEM_TYPE_GDDR3;
-	if (pfb474 & 0x00000002)
-		pfb->ram.type = NV_MEM_TYPE_DDR2;
-	if (pfb474 & 0x00000001)
-		pfb->ram.type = NV_MEM_TYPE_DDR1;
-
-	pfb->ram.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
-	return 0;
-}
-
 static void
 nv44_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
 		  u32 flags, struct nouveau_fb_tile *tile)
@@ -87,18 +72,17 @@ nv44_fb_ctor(struct nouveau_object *pare
 	struct nv44_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv44_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv44_fb_vram_init;
 	priv->base.tile.regions = 12;
 	priv->base.tile.init = nv44_fb_tile_init;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv44_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv46_fb_priv {
 	struct nouveau_fb base;
@@ -52,18 +52,17 @@ nv46_fb_ctor(struct nouveau_object *pare
 	struct nv46_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv44_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv44_fb_vram_init;
 	priv->base.tile.regions = 15;
 	priv->base.tile.init = nv46_fb_tile_init;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv44_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv47_fb_priv {
 	struct nouveau_fb base;
@@ -38,19 +38,18 @@ nv47_fb_ctor(struct nouveau_object *pare
 	struct nv47_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv41_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv41_fb_vram_init;
 	priv->base.tile.regions = 15;
 	priv->base.tile.init = nv30_fb_tile_init;
 	priv->base.tile.comp = nv40_fb_tile_comp;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv41_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,30 +24,13 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv49_fb_priv {
 	struct nouveau_fb base;
 };
 
 static int
-nv49_fb_vram_init(struct nouveau_fb *pfb)
-{
-	u32 pfb914 = nv_rd32(pfb, 0x100914);
-
-	switch (pfb914 & 0x00000003) {
-	case 0x00000000: pfb->ram.type = NV_MEM_TYPE_DDR1; break;
-	case 0x00000001: pfb->ram.type = NV_MEM_TYPE_DDR2; break;
-	case 0x00000002: pfb->ram.type = NV_MEM_TYPE_GDDR3; break;
-	case 0x00000003: break;
-	}
-
-	pfb->ram.size =   nv_rd32(pfb, 0x10020c) & 0xff000000;
-	pfb->ram.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
-	return nv_rd32(pfb, 0x100320);
-}
-
-static int
 nv49_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	     struct nouveau_oclass *oclass, void *data, u32 size,
 	     struct nouveau_object **pobject)
@@ -55,20 +38,18 @@ nv49_fb_ctor(struct nouveau_object *pare
 	struct nv49_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv49_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv49_fb_vram_init;
 	priv->base.tile.regions = 15;
 	priv->base.tile.init = nv30_fb_tile_init;
 	priv->base.tile.comp = nv40_fb_tile_comp;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv41_fb_tile_prog;
-
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,21 +24,13 @@
  *
  */
 
-#include <subdev/fb.h>
+#include "priv.h"
 
 struct nv4e_fb_priv {
 	struct nouveau_fb base;
 };
 
 static int
-nv4e_fb_vram_init(struct nouveau_fb *pfb)
-{
-	pfb->ram.size = nv_rd32(pfb, 0x10020c) & 0xff000000;
-	pfb->ram.type = NV_MEM_TYPE_STOLEN;
-	return 0;
-}
-
-static int
 nv4e_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	     struct nouveau_oclass *oclass, void *data, u32 size,
 	     struct nouveau_object **pobject)
@@ -46,18 +38,17 @@ nv4e_fb_ctor(struct nouveau_object *pare
 	struct nv4e_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv4e_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nv04_fb_memtype_valid;
-	priv->base.ram.init = nv4e_fb_vram_init;
 	priv->base.tile.regions = 12;
 	priv->base.tile.init = nv46_fb_tile_init;
 	priv->base.tile.fini = nv20_fb_tile_fini;
 	priv->base.tile.prog = nv44_fb_tile_prog;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 struct nouveau_oclass
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@
 #include <core/engctx.h>
 #include <core/object.h>
 
-#include <subdev/fb.h>
+#include "priv.h"
 #include <subdev/bios.h>
 
 struct nv50_fb_priv {
@@ -36,7 +36,8 @@ struct nv50_fb_priv {
 	dma_addr_t r100c08;
 };
 
-static int types[0x80] = {
+int
+nv50_fb_memtype[0x80] = {
 	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
 	1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
@@ -50,192 +51,7 @@ static int types[0x80] = {
 static bool
 nv50_fb_memtype_valid(struct nouveau_fb *pfb, u32 memtype)
 {
-	return types[(memtype & 0xff00) >> 8] != 0;
-}
-
-static u32
-nv50_fb_vram_rblock(struct nouveau_fb *pfb)
-{
-	int i, parts, colbits, rowbitsa, rowbitsb, banks;
-	u64 rowsize, predicted;
-	u32 r0, r4, rt, ru, rblock_size;
-
-	r0 = nv_rd32(pfb, 0x100200);
-	r4 = nv_rd32(pfb, 0x100204);
-	rt = nv_rd32(pfb, 0x100250);
-	ru = nv_rd32(pfb, 0x001540);
-	nv_debug(pfb, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
-
-	for (i = 0, parts = 0; i < 8; i++) {
-		if (ru & (0x00010000 << i))
-			parts++;
-	}
-
-	colbits  =  (r4 & 0x0000f000) >> 12;
-	rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
-	rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
-	banks    = 1 << (((r4 & 0x03000000) >> 24) + 2);
-
-	rowsize = parts * banks * (1 << colbits) * 8;
-	predicted = rowsize << rowbitsa;
-	if (r0 & 0x00000004)
-		predicted += rowsize << rowbitsb;
-
-	if (predicted != pfb->ram.size) {
-		nv_warn(pfb, "memory controller reports %d MiB VRAM\n",
-			(u32)(pfb->ram.size >> 20));
-	}
-
-	rblock_size = rowsize;
-	if (rt & 1)
-		rblock_size *= 3;
-
-	nv_debug(pfb, "rblock %d bytes\n", rblock_size);
-	return rblock_size;
-}
-
-static int
-nv50_fb_vram_init(struct nouveau_fb *pfb)
-{
-	struct nouveau_device *device = nv_device(pfb);
-	struct nouveau_bios *bios = nouveau_bios(device);
-	const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
-	const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
-	u32 size, tags = 0;
-	int ret;
-
-	pfb->ram.size = nv_rd32(pfb, 0x10020c);
-	pfb->ram.size = (pfb->ram.size & 0xffffff00) |
-		       ((pfb->ram.size & 0x000000ff) << 32);
-
-	size = (pfb->ram.size >> 12) - rsvd_head - rsvd_tail;
-	switch (device->chipset) {
-	case 0xaa:
-	case 0xac:
-	case 0xaf: /* IGPs, no reordering, no real VRAM */
-		ret = nouveau_mm_init(&pfb->vram, rsvd_head, size, 1);
-		if (ret)
-			return ret;
-
-		pfb->ram.type   = NV_MEM_TYPE_STOLEN;
-		pfb->ram.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
-		break;
-	default:
-		switch (nv_rd32(pfb, 0x100714) & 0x00000007) {
-		case 0: pfb->ram.type = NV_MEM_TYPE_DDR1; break;
-		case 1:
-			if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3)
-				pfb->ram.type = NV_MEM_TYPE_DDR3;
-			else
-				pfb->ram.type = NV_MEM_TYPE_DDR2;
-			break;
-		case 2: pfb->ram.type = NV_MEM_TYPE_GDDR3; break;
-		case 3: pfb->ram.type = NV_MEM_TYPE_GDDR4; break;
-		case 4: pfb->ram.type = NV_MEM_TYPE_GDDR5; break;
-		default:
-			break;
-		}
-
-		ret = nouveau_mm_init(&pfb->vram, rsvd_head, size,
-				      nv50_fb_vram_rblock(pfb) >> 12);
-		if (ret)
-			return ret;
-
-		pfb->ram.ranks = (nv_rd32(pfb, 0x100200) & 0x4) ? 2 : 1;
-		tags = nv_rd32(pfb, 0x100320);
-		break;
-	}
-
-	return tags;
-}
-
-static int
-nv50_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
-		 u32 memtype, struct nouveau_mem **pmem)
-{
-	struct nv50_fb_priv *priv = (void *)pfb;
-	struct nouveau_mm *heap = &priv->base.vram;
-	struct nouveau_mm *tags = &priv->base.tags;
-	struct nouveau_mm_node *r;
-	struct nouveau_mem *mem;
-	int comp = (memtype & 0x300) >> 8;
-	int type = (memtype & 0x07f);
-	int back = (memtype & 0x800);
-	int min, max, ret;
-
-	max = (size >> 12);
-	min = ncmin ? (ncmin >> 12) : max;
-	align >>= 12;
-
-	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-	if (!mem)
-		return -ENOMEM;
-
-	mutex_lock(&pfb->base.mutex);
-	if (comp) {
-		if (align == 16) {
-			int n = (max >> 4) * comp;
-
-			ret = nouveau_mm_head(tags, 1, n, n, 1, &mem->tag);
-			if (ret)
-				mem->tag = NULL;
-		}
-
-		if (unlikely(!mem->tag))
-			comp = 0;
-	}
-
-	INIT_LIST_HEAD(&mem->regions);
-	mem->memtype = (comp << 7) | type;
-	mem->size = max;
-
-	type = types[type];
-	do {
-		if (back)
-			ret = nouveau_mm_tail(heap, type, max, min, align, &r);
-		else
-			ret = nouveau_mm_head(heap, type, max, min, align, &r);
-		if (ret) {
-			mutex_unlock(&pfb->base.mutex);
-			pfb->ram.put(pfb, &mem);
-			return ret;
-		}
-
-		list_add_tail(&r->rl_entry, &mem->regions);
-		max -= r->length;
-	} while (max);
-	mutex_unlock(&pfb->base.mutex);
-
-	r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
-	mem->offset = (u64)r->offset << 12;
-	*pmem = mem;
-	return 0;
-}
-
-void
-nv50_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
-{
-	struct nv50_fb_priv *priv = (void *)pfb;
-	struct nouveau_mm_node *this;
-	struct nouveau_mem *mem;
-
-	mem = *pmem;
-	*pmem = NULL;
-	if (unlikely(mem == NULL))
-		return;
-
-	mutex_lock(&pfb->base.mutex);
-	while (!list_empty(&mem->regions)) {
-		this = list_first_entry(&mem->regions, typeof(*this), rl_entry);
-
-		list_del(&this->rl_entry);
-		nouveau_mm_free(&priv->base.vram, &this);
-	}
-
-	nouveau_mm_free(&priv->base.tags, &mem->tag);
-	mutex_unlock(&pfb->base.mutex);
-
-	kfree(mem);
+	return nv50_fb_memtype[(memtype & 0xff00) >> 8] != 0;
 }
 
 static const struct nouveau_enum vm_dispatch_subclients[] = {
@@ -432,7 +248,7 @@ nv50_fb_ctor(struct nouveau_object *pare
 	struct nv50_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nv50_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
@@ -449,11 +265,8 @@ nv50_fb_ctor(struct nouveau_object *pare
 	}
 
 	priv->base.memtype_valid = nv50_fb_memtype_valid;
-	priv->base.ram.init = nv50_fb_vram_init;
-	priv->base.ram.get = nv50_fb_vram_new;
-	priv->base.ram.put = nv50_fb_vram_del;
 	nv_subdev(priv)->intr = nv50_fb_intr;
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 static void
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,9 +22,7 @@
  * Authors: Ben Skeggs
  */
 
-#include <subdev/fb.h>
-#include <subdev/ltcg.h>
-#include <subdev/bios.h>
+#include "priv.h"
 
 struct nvc0_fb_priv {
 	struct nouveau_fb base;
@@ -34,7 +32,6 @@ struct nvc0_fb_priv {
 
 extern const u8 nvc0_pte_storage_type_map[256];
 
-
 static bool
 nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
 {
@@ -43,137 +40,6 @@ nvc0_fb_memtype_valid(struct nouveau_fb
 }
 
 static int
-nvc0_fb_vram_init(struct nouveau_fb *pfb)
-{
-	struct nouveau_bios *bios = nouveau_bios(pfb);
-	const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
-	const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
-	u32 parts = nv_rd32(pfb, 0x022438);
-	u32 pmask = nv_rd32(pfb, 0x022554);
-	u32 bsize = nv_rd32(pfb, 0x10f20c);
-	u32 offset, length;
-	bool uniform = true;
-	int ret, part;
-
-	nv_debug(pfb, "0x100800: 0x%08x\n", nv_rd32(pfb, 0x100800));
-	nv_debug(pfb, "parts 0x%08x mask 0x%08x\n", parts, pmask);
-
-	pfb->ram.type = nouveau_fb_bios_memtype(bios);
-	pfb->ram.ranks = (nv_rd32(pfb, 0x10f200) & 0x00000004) ? 2 : 1;
-
-	/* read amount of vram attached to each memory controller */
-	for (part = 0; part < parts; part++) {
-		if (!(pmask & (1 << part))) {
-			u32 psize = nv_rd32(pfb, 0x11020c + (part * 0x1000));
-			if (psize != bsize) {
-				if (psize < bsize)
-					bsize = psize;
-				uniform = false;
-			}
-
-			nv_debug(pfb, "%d: mem_amount 0x%08x\n", part, psize);
-			pfb->ram.size += (u64)psize << 20;
-		}
-	}
-
-	/* if all controllers have the same amount attached, there's no holes */
-	if (uniform) {
-		offset = rsvd_head;
-		length = (pfb->ram.size >> 12) - rsvd_head - rsvd_tail;
-		return nouveau_mm_init(&pfb->vram, offset, length, 1);
-	}
-
-	/* otherwise, address lowest common amount from 0GiB */
-	ret = nouveau_mm_init(&pfb->vram, rsvd_head, (bsize << 8) * parts, 1);
-	if (ret)
-		return ret;
-
-	/* and the rest starting from (8GiB + common_size) */
-	offset = (0x0200000000ULL >> 12) + (bsize << 8);
-	length = (pfb->ram.size >> 12) - (bsize << 8) - rsvd_tail;
-
-	ret = nouveau_mm_init(&pfb->vram, offset, length, 0);
-	if (ret) {
-		nouveau_mm_fini(&pfb->vram);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int
-nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
-		 u32 memtype, struct nouveau_mem **pmem)
-{
-	struct nouveau_mm *mm = &pfb->vram;
-	struct nouveau_mm_node *r;
-	struct nouveau_mem *mem;
-	int type = (memtype & 0x0ff);
-	int back = (memtype & 0x800);
-	int ret;
-	const bool comp = nvc0_pte_storage_type_map[type] != type;
-
-	size  >>= 12;
-	align >>= 12;
-	ncmin >>= 12;
-	if (!ncmin)
-		ncmin = size;
-
-	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-	if (!mem)
-		return -ENOMEM;
-
-	INIT_LIST_HEAD(&mem->regions);
-	mem->size = size;
-
-	mutex_lock(&pfb->base.mutex);
-	if (comp) {
-		struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
-
-		/* compression only works with lpages */
-		if (align == (1 << (17 - 12))) {
-			int n = size >> 5;
-			ltcg->tags_alloc(ltcg, n, &mem->tag);
-		}
-		if (unlikely(!mem->tag))
-			type = nvc0_pte_storage_type_map[type];
-	}
-	mem->memtype = type;
-
-	do {
-		if (back)
-			ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
-		else
-			ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
-		if (ret) {
-			mutex_unlock(&pfb->base.mutex);
-			pfb->ram.put(pfb, &mem);
-			return ret;
-		}
-
-		list_add_tail(&r->rl_entry, &mem->regions);
-		size -= r->length;
-	} while (size);
-	mutex_unlock(&pfb->base.mutex);
-
-	r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
-	mem->offset = (u64)r->offset << 12;
-	*pmem = mem;
-	return 0;
-}
-
-static void
-nvc0_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
-{
-	struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
-
-	if ((*pmem)->tag)
-		ltcg->tags_free(ltcg, &(*pmem)->tag);
-
-	nv50_fb_vram_del(pfb, pmem);
-}
-
-static int
 nvc0_fb_init(struct nouveau_object *object)
 {
 	struct nvc0_fb_priv *priv = (void *)object;
@@ -212,15 +78,12 @@ nvc0_fb_ctor(struct nouveau_object *pare
 	struct nvc0_fb_priv *priv;
 	int ret;
 
-	ret = nouveau_fb_create(parent, engine, oclass, &priv);
+	ret = nouveau_fb_create(parent, engine, oclass, &nvc0_ram_oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->base.memtype_valid = nvc0_fb_memtype_valid;
-	priv->base.ram.init = nvc0_fb_vram_init;
-	priv->base.ram.get = nvc0_fb_vram_new;
-	priv->base.ram.put = nvc0_fb_vram_del;
 
 	priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
 	if (priv->r100c10_page) {
@@ -231,7 +94,7 @@ nvc0_fb_ctor(struct nouveau_object *pare
 			return -EFAULT;
 	}
 
-	return nouveau_fb_preinit(&priv->base);
+	return 0;
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,87 @@
+#ifndef __NVKM_FB_PRIV_H__
+#define __NVKM_FB_PRIV_H__
+
+#include <subdev/fb.h>
+
+#define nouveau_ram_create(p,e,o,d)                                            \
+	nouveau_object_create_((p), (e), (o), 0, sizeof(**d), (void **)d)
+#define nouveau_ram_destroy(p)                                                 \
+	nouveau_object_destroy(&(p)->base)
+#define nouveau_ram_init(p)                                                    \
+	nouveau_object_init(&(p)->base)
+#define nouveau_ram_fini(p,s)                                                  \
+	nouveau_object_fini(&(p)->base, (s))
+
+#define _nouveau_ram_dtor nouveau_object_destroy
+#define _nouveau_ram_init nouveau_object_init
+#define _nouveau_ram_fini nouveau_object_fini
+
+extern struct nouveau_oclass nv04_ram_oclass;
+extern struct nouveau_oclass nv10_ram_oclass;
+extern struct nouveau_oclass nv1a_ram_oclass;
+extern struct nouveau_oclass nv20_ram_oclass;
+extern struct nouveau_oclass nv40_ram_oclass;
+extern struct nouveau_oclass nv41_ram_oclass;
+extern struct nouveau_oclass nv44_ram_oclass;
+extern struct nouveau_oclass nv49_ram_oclass;
+extern struct nouveau_oclass nv4e_ram_oclass;
+extern struct nouveau_oclass nv50_ram_oclass;
+extern struct nouveau_oclass nvc0_ram_oclass;
+
+#define nouveau_fb_create(p,e,c,r,d)                                           \
+	nouveau_fb_create_((p), (e), (c), (r), sizeof(**d), (void **)d)
+#define nouveau_fb_destroy(p) ({                                               \
+	struct nouveau_fb *pfb = (p);                                          \
+	_nouveau_fb_dtor(nv_object(pfb));                                      \
+})
+#define nouveau_fb_init(p) ({                                                  \
+	struct nouveau_fb *pfb = (p);                                          \
+	_nouveau_fb_init(nv_object(pfb));                                      \
+})
+#define nouveau_fb_fini(p,s) ({                                                \
+	struct nouveau_fb *pfb = (p);                                          \
+	_nouveau_fb_fini(nv_object(pfb), (s));                                 \
+})
+
+int nouveau_fb_create_(struct nouveau_object *, struct nouveau_object *,
+		       struct nouveau_oclass *, struct nouveau_oclass *,
+		       int length, void **pobject);
+void _nouveau_fb_dtor(struct nouveau_object *);
+int  _nouveau_fb_init(struct nouveau_object *);
+int  _nouveau_fb_fini(struct nouveau_object *, bool);
+
+struct nouveau_bios;
+int  nouveau_fb_bios_memtype(struct nouveau_bios *);
+
+bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
+
+void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
+void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
+void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
+void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
+void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+int  nv30_fb_init(struct nouveau_object *);
+void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
+
+void nv40_fb_tile_comp(struct nouveau_fb *, int i, u32 size, u32 flags,
+		       struct nouveau_fb_tile *);
+
+int  nv41_fb_init(struct nouveau_object *);
+void nv41_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+int  nv44_fb_init(struct nouveau_object *);
+void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+		       u32 pitch, u32 flags, struct nouveau_fb_tile *);
+
+void __nv50_ram_put(struct nouveau_fb *, struct nouveau_mem *);
+extern int nv50_fb_memtype[0x80];
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv04.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#define NV04_PFB_BOOT_0						0x00100000
+#	define NV04_PFB_BOOT_0_RAM_AMOUNT			0x00000003
+#	define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB			0x00000000
+#	define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB			0x00000001
+#	define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB			0x00000002
+#	define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB			0x00000003
+#	define NV04_PFB_BOOT_0_RAM_WIDTH_128			0x00000004
+#	define NV04_PFB_BOOT_0_RAM_TYPE				0x00000028
+#	define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT		0x00000000
+#	define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT		0x00000008
+#	define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK	0x00000010
+#	define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT		0x00000018
+#	define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT		0x00000020
+#	define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16		0x00000028
+#	define NV04_PFB_BOOT_0_UMA_ENABLE			0x00000100
+#	define NV04_PFB_BOOT_0_UMA_SIZE				0x0000f000
+
+#include "priv.h"
+
+static int
+nv04_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_ram *ram;
+	u32 boot0 = nv_rd32(pfb, NV04_PFB_BOOT_0);
+	int ret;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	if (boot0 & 0x00000100) {
+		ram->size  = ((boot0 >> 12) & 0xf) * 2 + 2;
+		ram->size *= 1024 * 1024;
+	} else {
+		switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
+		case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
+			ram->size = 32 * 1024 * 1024;
+			break;
+		case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
+			ram->size = 16 * 1024 * 1024;
+			break;
+		case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
+			ram->size = 8 * 1024 * 1024;
+			break;
+		case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
+			ram->size = 4 * 1024 * 1024;
+			break;
+		}
+	}
+
+	if ((boot0 & 0x00000038) <= 0x10)
+		ram->type = NV_MEM_TYPE_SGRAM;
+	else
+		ram->type = NV_MEM_TYPE_SDRAM;
+	return 0;
+}
+
+struct nouveau_oclass
+nv04_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv04_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv10.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv10_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_ram *ram;
+	u32 cfg0 = nv_rd32(pfb, 0x100200);
+	int ret;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	if (cfg0 & 0x00000001)
+		ram->type = NV_MEM_TYPE_DDR1;
+	else
+		ram->type = NV_MEM_TYPE_SDRAM;
+
+	ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+	return 0;
+}
+
+
+struct nouveau_oclass
+nv10_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv10_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv1a.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv1a_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_ram *ram;
+	struct pci_dev *bridge;
+	u32 mem, mib;
+	int ret;
+
+	bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
+	if (!bridge) {
+		nv_fatal(pfb, "no bridge device\n");
+		return -ENODEV;
+	}
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	if (nv_device(pfb)->chipset == 0x1a) {
+		pci_read_config_dword(bridge, 0x7c, &mem);
+		mib = ((mem >> 6) & 31) + 1;
+	} else {
+		pci_read_config_dword(bridge, 0x84, &mem);
+		mib = ((mem >> 4) & 127) + 1;
+	}
+
+	ram->type = NV_MEM_TYPE_STOLEN;
+	ram->size = mib * 1024 * 1024;
+	return 0;
+}
+
+struct nouveau_oclass
+nv1a_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv1a_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv20.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv20_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_ram *ram;
+	u32 pbus1218 = nv_rd32(pfb, 0x001218);
+	int ret;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	switch (pbus1218 & 0x00000300) {
+	case 0x00000000: ram->type = NV_MEM_TYPE_SDRAM; break;
+	case 0x00000100: ram->type = NV_MEM_TYPE_DDR1; break;
+	case 0x00000200: ram->type = NV_MEM_TYPE_GDDR3; break;
+	case 0x00000300: ram->type = NV_MEM_TYPE_GDDR2; break;
+	}
+	ram->size  = (nv_rd32(pfb, 0x10020c) & 0xff000000);
+	ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+	ram->tags  = nv_rd32(pfb, 0x100320);
+	return 0;
+}
+
+struct nouveau_oclass
+nv20_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv20_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_ram *ram;
+	u32 pbus1218 = nv_rd32(pfb, 0x001218);
+	int ret;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	switch (pbus1218 & 0x00000300) {
+	case 0x00000000: ram->type = NV_MEM_TYPE_SDRAM; break;
+	case 0x00000100: ram->type = NV_MEM_TYPE_DDR1; break;
+	case 0x00000200: ram->type = NV_MEM_TYPE_GDDR3; break;
+	case 0x00000300: ram->type = NV_MEM_TYPE_DDR2; break;
+	}
+
+	ram->size  =  nv_rd32(pfb, 0x10020c) & 0xff000000;
+	ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+	ram->tags  =  nv_rd32(pfb, 0x100320);
+	return 0;
+}
+
+
+struct nouveau_oclass
+nv40_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv40_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_ram *ram;
+	u32 pfb474 = nv_rd32(pfb, 0x100474);
+	int ret;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	if (pfb474 & 0x00000004)
+		ram->type = NV_MEM_TYPE_GDDR3;
+	if (pfb474 & 0x00000002)
+		ram->type = NV_MEM_TYPE_DDR2;
+	if (pfb474 & 0x00000001)
+		ram->type = NV_MEM_TYPE_DDR1;
+
+	ram->size  =  nv_rd32(pfb, 0x10020c) & 0xff000000;
+	ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+	ram->tags  =  nv_rd32(pfb, 0x100320);
+	return 0;
+}
+
+struct nouveau_oclass
+nv41_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv41_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_ram *ram;
+	u32 pfb474 = nv_rd32(pfb, 0x100474);
+	int ret;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	if (pfb474 & 0x00000004)
+		ram->type = NV_MEM_TYPE_GDDR3;
+	if (pfb474 & 0x00000002)
+		ram->type = NV_MEM_TYPE_DDR2;
+	if (pfb474 & 0x00000001)
+		ram->type = NV_MEM_TYPE_DDR1;
+
+	ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+	return 0;
+}
+
+struct nouveau_oclass
+nv44_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv44_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_ram *ram;
+	u32 pfb914 = nv_rd32(pfb, 0x100914);
+	int ret;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	switch (pfb914 & 0x00000003) {
+	case 0x00000000: ram->type = NV_MEM_TYPE_DDR1; break;
+	case 0x00000001: ram->type = NV_MEM_TYPE_DDR2; break;
+	case 0x00000002: ram->type = NV_MEM_TYPE_GDDR3; break;
+	case 0x00000003: break;
+	}
+
+	ram->size  =  nv_rd32(pfb, 0x10020c) & 0xff000000;
+	ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
+	ram->tags  =  nv_rd32(pfb, 0x100320);
+	return 0;
+}
+
+struct nouveau_oclass
+nv49_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv49_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv4e.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+static int
+nv4e_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_ram *ram;
+	int ret;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000;
+	ram->type = NV_MEM_TYPE_STOLEN;
+	return 0;
+}
+
+struct nouveau_oclass
+nv4e_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv4e_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/bios.h>
+#include <core/mm.h>
+#include "priv.h"
+
+void
+__nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem *mem)
+{
+	struct nouveau_mm_node *this;
+
+	while (!list_empty(&mem->regions)) {
+		this = list_first_entry(&mem->regions, typeof(*this), rl_entry);
+
+		list_del(&this->rl_entry);
+		nouveau_mm_free(&pfb->vram, &this);
+	}
+
+	nouveau_mm_free(&pfb->tags, &mem->tag);
+}
+
+void
+nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
+{
+	struct nouveau_mem *mem = *pmem;
+
+	*pmem = NULL;
+	if (unlikely(mem == NULL))
+		return;
+
+	mutex_lock(&pfb->base.mutex);
+	__nv50_ram_put(pfb, mem);
+	mutex_unlock(&pfb->base.mutex);
+
+	kfree(mem);
+}
+
+static int
+nv50_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
+	     u32 memtype, struct nouveau_mem **pmem)
+{
+	struct nouveau_mm *heap = &pfb->vram;
+	struct nouveau_mm *tags = &pfb->tags;
+	struct nouveau_mm_node *r;
+	struct nouveau_mem *mem;
+	int comp = (memtype & 0x300) >> 8;
+	int type = (memtype & 0x07f);
+	int back = (memtype & 0x800);
+	int min, max, ret;
+
+	max = (size >> 12);
+	min = ncmin ? (ncmin >> 12) : max;
+	align >>= 12;
+
+	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	if (!mem)
+		return -ENOMEM;
+
+	mutex_lock(&pfb->base.mutex);
+	if (comp) {
+		if (align == 16) {
+			int n = (max >> 4) * comp;
+
+			ret = nouveau_mm_head(tags, 1, n, n, 1, &mem->tag);
+			if (ret)
+				mem->tag = NULL;
+		}
+
+		if (unlikely(!mem->tag))
+			comp = 0;
+	}
+
+	INIT_LIST_HEAD(&mem->regions);
+	mem->memtype = (comp << 7) | type;
+	mem->size = max;
+
+	type = nv50_fb_memtype[type];
+	do {
+		if (back)
+			ret = nouveau_mm_tail(heap, type, max, min, align, &r);
+		else
+			ret = nouveau_mm_head(heap, type, max, min, align, &r);
+		if (ret) {
+			mutex_unlock(&pfb->base.mutex);
+			pfb->ram->put(pfb, &mem);
+			return ret;
+		}
+
+		list_add_tail(&r->rl_entry, &mem->regions);
+		max -= r->length;
+	} while (max);
+	mutex_unlock(&pfb->base.mutex);
+
+	r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+	mem->offset = (u64)r->offset << 12;
+	*pmem = mem;
+	return 0;
+}
+
+static u32
+nv50_fb_vram_rblock(struct nouveau_fb *pfb, struct nouveau_ram *ram)
+{
+	int i, parts, colbits, rowbitsa, rowbitsb, banks;
+	u64 rowsize, predicted;
+	u32 r0, r4, rt, ru, rblock_size;
+
+	r0 = nv_rd32(pfb, 0x100200);
+	r4 = nv_rd32(pfb, 0x100204);
+	rt = nv_rd32(pfb, 0x100250);
+	ru = nv_rd32(pfb, 0x001540);
+	nv_debug(pfb, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
+
+	for (i = 0, parts = 0; i < 8; i++) {
+		if (ru & (0x00010000 << i))
+			parts++;
+	}
+
+	colbits  =  (r4 & 0x0000f000) >> 12;
+	rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
+	rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
+	banks    = 1 << (((r4 & 0x03000000) >> 24) + 2);
+
+	rowsize = parts * banks * (1 << colbits) * 8;
+	predicted = rowsize << rowbitsa;
+	if (r0 & 0x00000004)
+		predicted += rowsize << rowbitsb;
+
+	if (predicted != ram->size) {
+		nv_warn(pfb, "memory controller reports %d MiB VRAM\n",
+			(u32)(ram->size >> 20));
+	}
+
+	rblock_size = rowsize;
+	if (rt & 1)
+		rblock_size *= 3;
+
+	nv_debug(pfb, "rblock %d bytes\n", rblock_size);
+	return rblock_size;
+}
+
+static int
+nv50_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 datasize,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_device *device = nv_device(pfb);
+	struct nouveau_bios *bios = nouveau_bios(device);
+	struct nouveau_ram *ram;
+	const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
+	const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
+	u32 size;
+	int ret;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	ram->size = nv_rd32(pfb, 0x10020c);
+	ram->size = (ram->size & 0xffffff00) |
+		       ((ram->size & 0x000000ff) << 32);
+
+	size = (ram->size >> 12) - rsvd_head - rsvd_tail;
+	switch (device->chipset) {
+	case 0xaa:
+	case 0xac:
+	case 0xaf: /* IGPs, no reordering, no real VRAM */
+		ret = nouveau_mm_init(&pfb->vram, rsvd_head, size, 1);
+		if (ret)
+			return ret;
+
+		ram->type   = NV_MEM_TYPE_STOLEN;
+		ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
+		break;
+	default:
+		switch (nv_rd32(pfb, 0x100714) & 0x00000007) {
+		case 0: ram->type = NV_MEM_TYPE_DDR1; break;
+		case 1:
+			if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3)
+				ram->type = NV_MEM_TYPE_DDR3;
+			else
+				ram->type = NV_MEM_TYPE_DDR2;
+			break;
+		case 2: ram->type = NV_MEM_TYPE_GDDR3; break;
+		case 3: ram->type = NV_MEM_TYPE_GDDR4; break;
+		case 4: ram->type = NV_MEM_TYPE_GDDR5; break;
+		default:
+			break;
+		}
+
+		ret = nouveau_mm_init(&pfb->vram, rsvd_head, size,
+				      nv50_fb_vram_rblock(pfb, ram) >> 12);
+		if (ret)
+			return ret;
+
+		ram->ranks = (nv_rd32(pfb, 0x100200) & 0x4) ? 2 : 1;
+		ram->tags  =  nv_rd32(pfb, 0x100320);
+		break;
+	}
+
+	ram->get = nv50_ram_get;
+	ram->put = nv50_ram_put;
+	return 0;
+}
+
+struct nouveau_oclass
+nv50_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nv50_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/bios.h>
+#include <subdev/ltcg.h>
+
+#include "priv.h"
+
+extern const u8 nvc0_pte_storage_type_map[256];
+
+void
+nvc0_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
+{
+	struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb);
+	struct nouveau_mem *mem = *pmem;
+
+	*pmem = NULL;
+	if (unlikely(mem == NULL))
+		return;
+
+	mutex_lock(&pfb->base.mutex);
+	if (mem->tag)
+		ltcg->tags_free(ltcg, &mem->tag);
+	__nv50_ram_put(pfb, mem);
+	mutex_unlock(&pfb->base.mutex);
+
+	kfree(mem);
+}
+
+int
+nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
+	     u32 memtype, struct nouveau_mem **pmem)
+{
+	struct nouveau_mm *mm = &pfb->vram;
+	struct nouveau_mm_node *r;
+	struct nouveau_mem *mem;
+	int type = (memtype & 0x0ff);
+	int back = (memtype & 0x800);
+	const bool comp = nvc0_pte_storage_type_map[type] != type;
+	int ret;
+
+	size  >>= 12;
+	align >>= 12;
+	ncmin >>= 12;
+	if (!ncmin)
+		ncmin = size;
+
+	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+	if (!mem)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&mem->regions);
+	mem->size = size;
+
+	mutex_lock(&pfb->base.mutex);
+	if (comp) {
+		struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb);
+
+		/* compression only works with lpages */
+		if (align == (1 << (17 - 12))) {
+			int n = size >> 5;
+			ltcg->tags_alloc(ltcg, n, &mem->tag);
+		}
+
+		if (unlikely(!mem->tag))
+			type = nvc0_pte_storage_type_map[type];
+	}
+	mem->memtype = type;
+
+	do {
+		if (back)
+			ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
+		else
+			ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
+		if (ret) {
+			mutex_unlock(&pfb->base.mutex);
+			pfb->ram->put(pfb, &mem);
+			return ret;
+		}
+
+		list_add_tail(&r->rl_entry, &mem->regions);
+		size -= r->length;
+	} while (size);
+	mutex_unlock(&pfb->base.mutex);
+
+	r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+	mem->offset = (u64)r->offset << 12;
+	*pmem = mem;
+	return 0;
+}
+
+static int
+nvc0_ram_create(struct nouveau_object *parent, struct nouveau_object *engine,
+		struct nouveau_oclass *oclass, void *data, u32 size,
+		struct nouveau_object **pobject)
+{
+	struct nouveau_fb *pfb = nouveau_fb(parent);
+	struct nouveau_bios *bios = nouveau_bios(pfb);
+	struct nouveau_ram *ram;
+	const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
+	const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
+	u32 parts = nv_rd32(pfb, 0x022438);
+	u32 pmask = nv_rd32(pfb, 0x022554);
+	u32 bsize = nv_rd32(pfb, 0x10f20c);
+	u32 offset, length;
+	bool uniform = true;
+	int ret, part;
+
+	ret = nouveau_ram_create(parent, engine, oclass, &ram);
+	*pobject = nv_object(ram);
+	if (ret)
+		return ret;
+
+	nv_debug(pfb, "0x100800: 0x%08x\n", nv_rd32(pfb, 0x100800));
+	nv_debug(pfb, "parts 0x%08x mask 0x%08x\n", parts, pmask);
+
+	ram->type = nouveau_fb_bios_memtype(bios);
+	ram->ranks = (nv_rd32(pfb, 0x10f200) & 0x00000004) ? 2 : 1;
+
+	/* read amount of vram attached to each memory controller */
+	for (part = 0; part < parts; part++) {
+		if (!(pmask & (1 << part))) {
+			u32 psize = nv_rd32(pfb, 0x11020c + (part * 0x1000));
+			if (psize != bsize) {
+				if (psize < bsize)
+					bsize = psize;
+				uniform = false;
+			}
+
+			nv_debug(pfb, "%d: mem_amount 0x%08x\n", part, psize);
+			ram->size += (u64)psize << 20;
+		}
+	}
+
+	/* if all controllers have the same amount attached, there's no holes */
+	if (uniform) {
+		offset = rsvd_head;
+		length = (ram->size >> 12) - rsvd_head - rsvd_tail;
+		ret = nouveau_mm_init(&pfb->vram, offset, length, 1);
+	} else {
+		/* otherwise, address lowest common amount from 0GiB */
+		ret = nouveau_mm_init(&pfb->vram, rsvd_head,
+				      (bsize << 8) * parts, 1);
+		if (ret)
+			return ret;
+
+		/* and the rest starting from (8GiB + common_size) */
+		offset = (0x0200000000ULL >> 12) + (bsize << 8);
+		length = (ram->size >> 12) - (bsize << 8) - rsvd_tail;
+
+		ret = nouveau_mm_init(&pfb->vram, offset, length, 0);
+		if (ret)
+			nouveau_mm_fini(&pfb->vram);
+	}
+
+	if (ret)
+		return ret;
+
+	ram->get = nvc0_ram_get;
+	ram->put = nvc0_ram_put;
+	return 0;
+}
+
+struct nouveau_oclass
+nvc0_ram_oclass = {
+	.handle = 0,
+	.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_ram_create,
+		.dtor = _nouveau_ram_dtor,
+		.init = _nouveau_ram_init,
+		.fini = _nouveau_ram_fini,
+	}
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -103,7 +103,7 @@ nv50_gpio_intr(struct nouveau_subdev *su
 	int i;
 
 	intr0 = nv_rd32(priv, 0xe054) & nv_rd32(priv, 0xe050);
-	if (nv_device(priv)->chipset >= 0x90)
+	if (nv_device(priv)->chipset > 0x92)
 		intr1 = nv_rd32(priv, 0xe074) & nv_rd32(priv, 0xe070);
 
 	hi = (intr0 & 0x0000ffff) | (intr1 << 16);
@@ -115,7 +115,7 @@ nv50_gpio_intr(struct nouveau_subdev *su
 	}
 
 	nv_wr32(priv, 0xe054, intr0);
-	if (nv_device(priv)->chipset >= 0x90)
+	if (nv_device(priv)->chipset > 0x92)
 		nv_wr32(priv, 0xe074, intr1);
 }
 
@@ -146,7 +146,7 @@ nv50_gpio_ctor(struct nouveau_object *pa
 	int ret;
 
 	ret = nouveau_gpio_create(parent, engine, oclass,
-				  nv_device(parent)->chipset >= 0x90 ? 32 : 16,
+				  nv_device(parent)->chipset > 0x92 ? 32 : 16,
 				  &priv);
 	*pobject = nv_object(priv);
 	if (ret)
@@ -182,7 +182,7 @@ nv50_gpio_init(struct nouveau_object *ob
 	/* disable, and ack any pending gpio interrupts */
 	nv_wr32(priv, 0xe050, 0x00000000);
 	nv_wr32(priv, 0xe054, 0xffffffff);
-	if (nv_device(priv)->chipset >= 0x90) {
+	if (nv_device(priv)->chipset > 0x92) {
 		nv_wr32(priv, 0xe070, 0x00000000);
 		nv_wr32(priv, 0xe074, 0xffffffff);
 	}
@@ -195,7 +195,7 @@ nv50_gpio_fini(struct nouveau_object *ob
 {
 	struct nv50_gpio_priv *priv = (void *)object;
 	nv_wr32(priv, 0xe050, 0x00000000);
-	if (nv_device(priv)->chipset >= 0x90)
+	if (nv_device(priv)->chipset > 0x92)
 		nv_wr32(priv, 0xe070, 0x00000000);
 	return nouveau_gpio_fini(&priv->base, suspend);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,7 +56,7 @@ nv50_instobj_ctor(struct nouveau_object
 	if (ret)
 		return ret;
 
-	ret = pfb->ram.get(pfb, size, align, 0, 0x800, &node->mem);
+	ret = pfb->ram->get(pfb, size, align, 0, 0x800, &node->mem);
 	if (ret)
 		return ret;
 
@@ -71,7 +71,7 @@ nv50_instobj_dtor(struct nouveau_object
 {
 	struct nv50_instobj_priv *node = (void *)object;
 	struct nouveau_fb *pfb = nouveau_fb(object);
-	pfb->ram.put(pfb, &node->mem);
+	pfb->ram->put(pfb, &node->mem);
 	nouveau_instobj_destroy(&node->base);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,8 +30,9 @@ struct nvc0_ltcg_priv {
 	struct nouveau_ltcg base;
 	u32 part_nr;
 	u32 subp_nr;
-	struct nouveau_mm tags;
 	u32 num_tags;
+	u32 tag_base;
+	struct nouveau_mm tags;
 	struct nouveau_mm_node *tag_ram;
 };
 
@@ -117,12 +118,8 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb
 	u32 tag_size, tag_margin, tag_align;
 	int ret;
 
-	nv_wr32(priv, 0x17e8d8, priv->part_nr);
-	if (nv_device(pfb)->card_type >= NV_E0)
-		nv_wr32(priv, 0x17e000, priv->part_nr);
-
 	/* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
-	priv->num_tags = (pfb->ram.size >> 17) / 4;
+	priv->num_tags = (pfb->ram->size >> 17) / 4;
 	if (priv->num_tags > (1 << 17))
 		priv->num_tags = 1 << 17; /* we have 17 bits in PTE */
 	priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */
@@ -142,7 +139,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb
 	tag_size += tag_align;
 	tag_size  = (tag_size + 0xfff) >> 12; /* round up */
 
-	ret = nouveau_mm_tail(&pfb->vram, 0, tag_size, tag_size, 1,
+	ret = nouveau_mm_tail(&pfb->vram, 1, tag_size, tag_size, 1,
 	                      &priv->tag_ram);
 	if (ret) {
 		priv->num_tags = 0;
@@ -152,7 +149,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb
 		tag_base += tag_align - 1;
 		ret = do_div(tag_base, tag_align);
 
-		nv_wr32(priv, 0x17e8d4, tag_base);
+		priv->tag_base = tag_base;
 	}
 	ret = nouveau_mm_init(&priv->tags, 0, priv->num_tags, 1);
 
@@ -182,8 +179,6 @@ nvc0_ltcg_ctor(struct nouveau_object *pa
 	}
 	priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28;
 
-	nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
-
 	ret = nvc0_ltcg_init_tag_ram(pfb, priv);
 	if (ret)
 		return ret;
@@ -209,13 +204,32 @@ nvc0_ltcg_dtor(struct nouveau_object *ob
 	nouveau_ltcg_destroy(ltcg);
 }
 
+static int
+nvc0_ltcg_init(struct nouveau_object *object)
+{
+	struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object;
+	struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
+	int ret;
+
+	ret = nouveau_ltcg_init(ltcg);
+	if (ret)
+		return ret;
+
+	nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
+	nv_wr32(priv, 0x17e8d8, priv->part_nr);
+	if (nv_device(ltcg)->card_type >= NV_E0)
+		nv_wr32(priv, 0x17e000, priv->part_nr);
+	nv_wr32(priv, 0x17e8d4, priv->tag_base);
+	return 0;
+}
+
 struct nouveau_oclass
 nvc0_ltcg_oclass = {
 	.handle = NV_SUBDEV(LTCG, 0xc0),
 	.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nvc0_ltcg_ctor,
 		.dtor = nvc0_ltcg_dtor,
-		.init = _nouveau_ltcg_init,
+		.init = nvc0_ltcg_init,
 		.fini = _nouveau_ltcg_fini,
 	},
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/base.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/base.c	2013-08-25 20:43:22.000000000 -0400
@@ -80,7 +80,9 @@ _nouveau_mc_dtor(struct nouveau_object *
 
 int
 nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
-		   struct nouveau_oclass *oclass, int length, void **pobject)
+		   struct nouveau_oclass *oclass,
+		   const struct nouveau_mc_intr *intr_map,
+		   int length, void **pobject)
 {
 	struct nouveau_device *device = nv_device(parent);
 	struct nouveau_mc *pmc;
@@ -92,6 +94,8 @@ nouveau_mc_create_(struct nouveau_object
 	if (ret)
 		return ret;
 
+	pmc->intr_map = intr_map;
+
 	ret = request_irq(device->pdev->irq, nouveau_mc_intr,
 			  IRQF_SHARED, "nouveau", pmc);
 	if (ret < 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,12 +50,11 @@ nv04_mc_ctor(struct nouveau_object *pare
 	struct nv04_mc_priv *priv;
 	int ret;
 
-	ret = nouveau_mc_create(parent, engine, oclass, &priv);
+	ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
-	priv->base.intr_map = nv04_mc_intr;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,12 +36,11 @@ nv44_mc_ctor(struct nouveau_object *pare
 	struct nv44_mc_priv *priv;
 	int ret;
 
-	ret = nouveau_mc_create(parent, engine, oclass, &priv);
+	ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
-	priv->base.intr_map = nv04_mc_intr;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,12 +35,13 @@ nv50_mc_intr[] = {
 	{ 0x00001000, NVDEV_ENGINE_GR },
 	{ 0x00004000, NVDEV_ENGINE_CRYPT },	/* NV84- */
 	{ 0x00008000, NVDEV_ENGINE_BSP },	/* NV84- */
+	{ 0x00020000, NVDEV_ENGINE_VP },	/* NV84- */
 	{ 0x00100000, NVDEV_SUBDEV_TIMER },
 	{ 0x00200000, NVDEV_SUBDEV_GPIO },
 	{ 0x04000000, NVDEV_ENGINE_DISP },
 	{ 0x10000000, NVDEV_SUBDEV_BUS },
 	{ 0x80000000, NVDEV_ENGINE_SW },
-	{ 0x0000d101, NVDEV_SUBDEV_FB },
+	{ 0x0002d101, NVDEV_SUBDEV_FB },
 	{},
 };
 
@@ -52,12 +53,11 @@ nv50_mc_ctor(struct nouveau_object *pare
 	struct nv50_mc_priv *priv;
 	int ret;
 
-	ret = nouveau_mc_create(parent, engine, oclass, &priv);
+	ret = nouveau_mc_create(parent, engine, oclass, nv50_mc_intr, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
-	priv->base.intr_map = nv50_mc_intr;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,12 +54,11 @@ nv98_mc_ctor(struct nouveau_object *pare
 	struct nv98_mc_priv *priv;
 	int ret;
 
-	ret = nouveau_mc_create(parent, engine, oclass, &priv);
+	ret = nouveau_mc_create(parent, engine, oclass, nv98_mc_intr, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
-	priv->base.intr_map = nv98_mc_intr;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,6 +33,7 @@ nvc0_mc_intr[] = {
 	{ 0x00000001, NVDEV_ENGINE_PPP },
 	{ 0x00000020, NVDEV_ENGINE_COPY0 },
 	{ 0x00000040, NVDEV_ENGINE_COPY1 },
+	{ 0x00000080, NVDEV_ENGINE_COPY2 },
 	{ 0x00000100, NVDEV_ENGINE_FIFO },
 	{ 0x00001000, NVDEV_ENGINE_GR },
 	{ 0x00008000, NVDEV_ENGINE_BSP },
@@ -56,12 +57,11 @@ nvc0_mc_ctor(struct nouveau_object *pare
 	struct nvc0_mc_priv *priv;
 	int ret;
 
-	ret = nouveau_mc_create(parent, engine, oclass, &priv);
+	ret = nouveau_mc_create(parent, engine, oclass, nvc0_mc_intr, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
-	priv->base.intr_map = nvc0_mc_intr;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/base.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/base.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/base.c	2013-08-25 20:43:22.000000000 -0400
@@ -236,9 +236,9 @@ nouveau_vm_unmap_pgt(struct nouveau_vm *
 			vmm->map_pgt(vpgd->obj, pde, vpgt->obj);
 		}
 
-		mutex_unlock(&vm->mm.mutex);
+		mutex_unlock(&nv_subdev(vmm)->mutex);
 		nouveau_gpuobj_ref(NULL, &pgt);
-		mutex_lock(&vm->mm.mutex);
+		mutex_lock(&nv_subdev(vmm)->mutex);
 	}
 }
 
@@ -256,18 +256,18 @@ nouveau_vm_map_pgt(struct nouveau_vm *vm
 	pgt_size  = (1 << (vmm->pgt_bits + 12)) >> type;
 	pgt_size *= 8;
 
-	mutex_unlock(&vm->mm.mutex);
+	mutex_unlock(&nv_subdev(vmm)->mutex);
 	ret = nouveau_gpuobj_new(nv_object(vm->vmm), NULL, pgt_size, 0x1000,
 				 NVOBJ_FLAG_ZERO_ALLOC, &pgt);
-	mutex_lock(&vm->mm.mutex);
+	mutex_lock(&nv_subdev(vmm)->mutex);
 	if (unlikely(ret))
 		return ret;
 
 	/* someone beat us to filling the PDE while we didn't have the lock */
 	if (unlikely(vpgt->refcount[big]++)) {
-		mutex_unlock(&vm->mm.mutex);
+		mutex_unlock(&nv_subdev(vmm)->mutex);
 		nouveau_gpuobj_ref(NULL, &pgt);
-		mutex_lock(&vm->mm.mutex);
+		mutex_lock(&nv_subdev(vmm)->mutex);
 		return 0;
 	}
 
@@ -289,11 +289,11 @@ nouveau_vm_get(struct nouveau_vm *vm, u6
 	u32 fpde, lpde, pde;
 	int ret;
 
-	mutex_lock(&vm->mm.mutex);
+	mutex_lock(&nv_subdev(vmm)->mutex);
 	ret = nouveau_mm_head(&vm->mm, page_shift, msize, msize, align,
 			     &vma->node);
 	if (unlikely(ret != 0)) {
-		mutex_unlock(&vm->mm.mutex);
+		mutex_unlock(&nv_subdev(vmm)->mutex);
 		return ret;
 	}
 
@@ -314,13 +314,14 @@ nouveau_vm_get(struct nouveau_vm *vm, u6
 			if (pde != fpde)
 				nouveau_vm_unmap_pgt(vm, big, fpde, pde - 1);
 			nouveau_mm_free(&vm->mm, &vma->node);
-			mutex_unlock(&vm->mm.mutex);
+			mutex_unlock(&nv_subdev(vmm)->mutex);
 			return ret;
 		}
 	}
-	mutex_unlock(&vm->mm.mutex);
+	mutex_unlock(&nv_subdev(vmm)->mutex);
 
-	vma->vm     = vm;
+	vma->vm = NULL;
+	nouveau_vm_ref(vm, &vma->vm, NULL);
 	vma->offset = (u64)vma->node->offset << 12;
 	vma->access = access;
 	return 0;
@@ -338,10 +339,12 @@ nouveau_vm_put(struct nouveau_vma *vma)
 	fpde = (vma->node->offset >> vmm->pgt_bits);
 	lpde = (vma->node->offset + vma->node->length - 1) >> vmm->pgt_bits;
 
-	mutex_lock(&vm->mm.mutex);
+	mutex_lock(&nv_subdev(vmm)->mutex);
 	nouveau_vm_unmap_pgt(vm, vma->node->type != vmm->spg_shift, fpde, lpde);
 	nouveau_mm_free(&vm->mm, &vma->node);
-	mutex_unlock(&vm->mm.mutex);
+	mutex_unlock(&nv_subdev(vmm)->mutex);
+
+	nouveau_vm_ref(NULL, &vma->vm, NULL);
 }
 
 int
@@ -358,11 +361,11 @@ nouveau_vm_create(struct nouveau_vmmgr *
 
 	INIT_LIST_HEAD(&vm->pgd_list);
 	vm->vmm = vmm;
-	vm->refcount = 1;
+	kref_init(&vm->refcount);
 	vm->fpde = offset >> (vmm->pgt_bits + 12);
 	vm->lpde = (offset + length - 1) >> (vmm->pgt_bits + 12);
 
-	vm->pgt  = kcalloc(vm->lpde - vm->fpde + 1, sizeof(*vm->pgt), GFP_KERNEL);
+	vm->pgt  = vzalloc((vm->lpde - vm->fpde + 1) * sizeof(*vm->pgt));
 	if (!vm->pgt) {
 		kfree(vm);
 		return -ENOMEM;
@@ -371,7 +374,7 @@ nouveau_vm_create(struct nouveau_vmmgr *
 	ret = nouveau_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12,
 			      block >> 12);
 	if (ret) {
-		kfree(vm->pgt);
+		vfree(vm->pgt);
 		kfree(vm);
 		return ret;
 	}
@@ -405,24 +408,25 @@ nouveau_vm_link(struct nouveau_vm *vm, s
 
 	nouveau_gpuobj_ref(pgd, &vpgd->obj);
 
-	mutex_lock(&vm->mm.mutex);
+	mutex_lock(&nv_subdev(vmm)->mutex);
 	for (i = vm->fpde; i <= vm->lpde; i++)
 		vmm->map_pgt(pgd, i, vm->pgt[i - vm->fpde].obj);
 	list_add(&vpgd->head, &vm->pgd_list);
-	mutex_unlock(&vm->mm.mutex);
+	mutex_unlock(&nv_subdev(vmm)->mutex);
 	return 0;
 }
 
 static void
 nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *mpgd)
 {
+	struct nouveau_vmmgr *vmm = vm->vmm;
 	struct nouveau_vm_pgd *vpgd, *tmp;
 	struct nouveau_gpuobj *pgd = NULL;
 
 	if (!mpgd)
 		return;
 
-	mutex_lock(&vm->mm.mutex);
+	mutex_lock(&nv_subdev(vmm)->mutex);
 	list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
 		if (vpgd->obj == mpgd) {
 			pgd = vpgd->obj;
@@ -431,14 +435,15 @@ nouveau_vm_unlink(struct nouveau_vm *vm,
 			break;
 		}
 	}
-	mutex_unlock(&vm->mm.mutex);
+	mutex_unlock(&nv_subdev(vmm)->mutex);
 
 	nouveau_gpuobj_ref(NULL, &pgd);
 }
 
 static void
-nouveau_vm_del(struct nouveau_vm *vm)
+nouveau_vm_del(struct kref *kref)
 {
+	struct nouveau_vm *vm = container_of(kref, typeof(*vm), refcount);
 	struct nouveau_vm_pgd *vpgd, *tmp;
 
 	list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) {
@@ -446,7 +451,7 @@ nouveau_vm_del(struct nouveau_vm *vm)
 	}
 
 	nouveau_mm_fini(&vm->mm);
-	kfree(vm->pgt);
+	vfree(vm->pgt);
 	kfree(vm);
 }
 
@@ -454,27 +459,19 @@ int
 nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr,
 	       struct nouveau_gpuobj *pgd)
 {
-	struct nouveau_vm *vm;
-	int ret;
-
-	vm = ref;
-	if (vm) {
-		ret = nouveau_vm_link(vm, pgd);
+	if (ref) {
+		int ret = nouveau_vm_link(ref, pgd);
 		if (ret)
 			return ret;
 
-		vm->refcount++;
+		kref_get(&ref->refcount);
 	}
 
-	vm = *ptr;
-	*ptr = ref;
-
-	if (vm) {
-		nouveau_vm_unlink(vm, pgd);
-
-		if (--vm->refcount == 0)
-			nouveau_vm_del(vm);
+	if (*ptr) {
+		nouveau_vm_unlink(*ptr, pgd);
+		kref_put(&(*ptr)->refcount, nouveau_vm_del);
 	}
 
+	*ptr = ref;
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,11 +27,11 @@
 
 #include <subdev/timer.h>
 #include <subdev/fb.h>
+#include <subdev/bar.h>
 #include <subdev/vm.h>
 
 struct nv50_vmmgr_priv {
 	struct nouveau_vmmgr base;
-	spinlock_t lock;
 };
 
 static void
@@ -86,8 +86,8 @@ nv50_vm_map(struct nouveau_vma *vma, str
 
 	/* IGPs don't have real VRAM, re-target to stolen system memory */
 	target = 0;
-	if (nouveau_fb(vma->vm->vmm)->ram.stolen) {
-		phys += nouveau_fb(vma->vm->vmm)->ram.stolen;
+	if (nouveau_fb(vma->vm->vmm)->ram->stolen) {
+		phys += nouveau_fb(vma->vm->vmm)->ram->stolen;
 		target = 3;
 	}
 
@@ -151,29 +151,42 @@ nv50_vm_unmap(struct nouveau_gpuobj *pgt
 static void
 nv50_vm_flush(struct nouveau_vm *vm)
 {
+	struct nv50_vmmgr_priv *priv = (void *)vm->vmm;
+	struct nouveau_bar *bar = nouveau_bar(priv);
 	struct nouveau_engine *engine;
-	int i;
+	int i, vme;
 
+	bar->flush(bar);
+
+	mutex_lock(&nv_subdev(priv)->mutex);
 	for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
-		if (atomic_read(&vm->engref[i])) {
-			engine = nouveau_engine(vm->vmm, i);
-			if (engine && engine->tlb_flush)
-				engine->tlb_flush(engine);
+		if (!atomic_read(&vm->engref[i]))
+			continue;
+
+		/* unfortunate hw bug workaround... */
+		engine = nouveau_engine(priv, i);
+		if (engine && engine->tlb_flush) {
+			engine->tlb_flush(engine);
+			continue;
 		}
-	}
-}
 
-void
-nv50_vm_flush_engine(struct nouveau_subdev *subdev, int engine)
-{
-	struct nv50_vmmgr_priv *priv = (void *)nouveau_vmmgr(subdev);
-	unsigned long flags;
+		switch (i) {
+		case NVDEV_ENGINE_GR   : vme = 0x00; break;
+		case NVDEV_ENGINE_VP   : vme = 0x01; break;
+		case NVDEV_SUBDEV_BAR  : vme = 0x06; break;
+		case NVDEV_ENGINE_MPEG : vme = 0x08; break;
+		case NVDEV_ENGINE_BSP  : vme = 0x09; break;
+		case NVDEV_ENGINE_CRYPT: vme = 0x0a; break;
+		case NVDEV_ENGINE_COPY0: vme = 0x0d; break;
+		default:
+			continue;
+		}
 
-	spin_lock_irqsave(&priv->lock, flags);
-	nv_wr32(subdev, 0x100c80, (engine << 16) | 1);
-	if (!nv_wait(subdev, 0x100c80, 0x00000001, 0x00000000))
-		nv_error(subdev, "vm flush timeout: engine %d\n", engine);
-	spin_unlock_irqrestore(&priv->lock, flags);
+		nv_wr32(priv, 0x100c80, (vme << 16) | 1);
+		if (!nv_wait(priv, 0x100c80, 0x00000001, 0x00000000))
+			nv_error(priv, "vm flush timeout: engine %d\n", vme);
+	}
+	mutex_unlock(&nv_subdev(priv)->mutex);
 }
 
 static int
@@ -211,7 +224,6 @@ nv50_vmmgr_ctor(struct nouveau_object *p
 	priv->base.map_sg = nv50_vm_map_sg;
 	priv->base.unmap = nv50_vm_unmap;
 	priv->base.flush = nv50_vm_flush;
-	spin_lock_init(&priv->lock);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,10 +29,10 @@
 #include <subdev/fb.h>
 #include <subdev/vm.h>
 #include <subdev/ltcg.h>
+#include <subdev/bar.h>
 
 struct nvc0_vmmgr_priv {
 	struct nouveau_vmmgr base;
-	spinlock_t lock;
 };
 
 
@@ -160,40 +160,40 @@ nvc0_vm_unmap(struct nouveau_gpuobj *pgt
 	}
 }
 
-void
-nvc0_vm_flush_engine(struct nouveau_subdev *subdev, u64 addr, int type)
-{
-	struct nvc0_vmmgr_priv *priv = (void *)nouveau_vmmgr(subdev);
-	unsigned long flags;
-
-	/* looks like maybe a "free flush slots" counter, the
-	 * faster you write to 0x100cbc to more it decreases
-	 */
-	spin_lock_irqsave(&priv->lock, flags);
-	if (!nv_wait_ne(subdev, 0x100c80, 0x00ff0000, 0x00000000)) {
-		nv_error(subdev, "vm timeout 0: 0x%08x %d\n",
-			 nv_rd32(subdev, 0x100c80), type);
-	}
-
-	nv_wr32(subdev, 0x100cb8, addr >> 8);
-	nv_wr32(subdev, 0x100cbc, 0x80000000 | type);
-
-	/* wait for flush to be queued? */
-	if (!nv_wait(subdev, 0x100c80, 0x00008000, 0x00008000)) {
-		nv_error(subdev, "vm timeout 1: 0x%08x %d\n",
-			 nv_rd32(subdev, 0x100c80), type);
-	}
-	spin_unlock_irqrestore(&priv->lock, flags);
-}
-
 static void
 nvc0_vm_flush(struct nouveau_vm *vm)
 {
+	struct nvc0_vmmgr_priv *priv = (void *)vm->vmm;
+	struct nouveau_bar *bar = nouveau_bar(priv);
 	struct nouveau_vm_pgd *vpgd;
+	u32 type;
+
+	bar->flush(bar);
+
+	type = 0x00000001; /* PAGE_ALL */
+	if (atomic_read(&vm->engref[NVDEV_SUBDEV_BAR]))
+		type |= 0x00000004; /* HUB_ONLY */
 
+	mutex_lock(&nv_subdev(priv)->mutex);
 	list_for_each_entry(vpgd, &vm->pgd_list, head) {
-		nvc0_vm_flush_engine(nv_subdev(vm->vmm), vpgd->obj->addr, 1);
+		/* looks like maybe a "free flush slots" counter, the
+		 * faster you write to 0x100cbc to more it decreases
+		 */
+		if (!nv_wait_ne(priv, 0x100c80, 0x00ff0000, 0x00000000)) {
+			nv_error(priv, "vm timeout 0: 0x%08x %d\n",
+				 nv_rd32(priv, 0x100c80), type);
+		}
+
+		nv_wr32(priv, 0x100cb8, vpgd->obj->addr >> 8);
+		nv_wr32(priv, 0x100cbc, 0x80000000 | type);
+
+		/* wait for flush to be queued? */
+		if (!nv_wait(priv, 0x100c80, 0x00008000, 0x00008000)) {
+			nv_error(priv, "vm timeout 1: 0x%08x %d\n",
+				 nv_rd32(priv, 0x100c80), type);
+		}
 	}
+	mutex_unlock(&nv_subdev(priv)->mutex);
 }
 
 static int
@@ -227,7 +227,6 @@ nvc0_vmmgr_ctor(struct nouveau_object *p
 	priv->base.map_sg = nvc0_vm_map_sg;
 	priv->base.unmap = nvc0_vm_unmap;
 	priv->base.flush = nvc0_vm_flush;
-	spin_lock_init(&priv->lock);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/dispnv04/crtc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/dispnv04/crtc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/dispnv04/crtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/dispnv04/crtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -606,6 +606,24 @@ nv_crtc_mode_set_regs(struct drm_crtc *c
 	regp->ramdac_a34 = 0x1;
 }
 
+static int
+nv_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb)
+{
+	struct nv04_display *disp = nv04_display(crtc->dev);
+	struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb);
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	int ret;
+
+	ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM);
+	if (ret == 0) {
+		if (disp->image[nv_crtc->index])
+			nouveau_bo_unpin(disp->image[nv_crtc->index]);
+		nouveau_bo_ref(nvfb->nvbo, &disp->image[nv_crtc->index]);
+	}
+
+	return ret;
+}
+
 /**
  * Sets up registers for the given mode/adjusted_mode pair.
  *
@@ -622,10 +640,15 @@ nv_crtc_mode_set(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 	struct nouveau_drm *drm = nouveau_drm(dev);
+	int ret;
 
 	NV_DEBUG(drm, "CTRC mode on CRTC %d:\n", nv_crtc->index);
 	drm_mode_debug_printmodeline(adjusted_mode);
 
+	ret = nv_crtc_swap_fbs(crtc, old_fb);
+	if (ret)
+		return ret;
+
 	/* unlock must come after turning off FP_TG_CONTROL in output_prepare */
 	nv_lock_vga_crtc_shadow(dev, nv_crtc->index, -1);
 
@@ -722,6 +745,7 @@ static void nv_crtc_commit(struct drm_cr
 
 static void nv_crtc_destroy(struct drm_crtc *crtc)
 {
+	struct nv04_display *disp = nv04_display(crtc->dev);
 	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 
 	if (!nv_crtc)
@@ -729,6 +753,10 @@ static void nv_crtc_destroy(struct drm_c
 
 	drm_crtc_cleanup(crtc);
 
+	if (disp->image[nv_crtc->index])
+		nouveau_bo_unpin(disp->image[nv_crtc->index]);
+	nouveau_bo_ref(NULL, &disp->image[nv_crtc->index]);
+
 	nouveau_bo_unmap(nv_crtc->cursor.nvbo);
 	nouveau_bo_unpin(nv_crtc->cursor.nvbo);
 	nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
@@ -754,6 +782,16 @@ nv_crtc_gamma_load(struct drm_crtc *crtc
 }
 
 static void
+nv_crtc_disable(struct drm_crtc *crtc)
+{
+	struct nv04_display *disp = nv04_display(crtc->dev);
+	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	if (disp->image[nv_crtc->index])
+		nouveau_bo_unpin(disp->image[nv_crtc->index]);
+	nouveau_bo_ref(NULL, &disp->image[nv_crtc->index]);
+}
+
+static void
 nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start,
 		  uint32_t size)
 {
@@ -791,7 +829,6 @@ nv04_crtc_do_mode_set_base(struct drm_cr
 	struct drm_framebuffer *drm_fb;
 	struct nouveau_framebuffer *fb;
 	int arb_burst, arb_lwm;
-	int ret;
 
 	NV_DEBUG(drm, "index %d\n", nv_crtc->index);
 
@@ -801,10 +838,8 @@ nv04_crtc_do_mode_set_base(struct drm_cr
 		return 0;
 	}
 
-
 	/* If atomic, we want to switch to the fb we were passed, so
-	 * now we update pointers to do that.  (We don't pin; just
-	 * assume we're already pinned and update the base address.)
+	 * now we update pointers to do that.
 	 */
 	if (atomic) {
 		drm_fb = passed_fb;
@@ -812,17 +847,6 @@ nv04_crtc_do_mode_set_base(struct drm_cr
 	} else {
 		drm_fb = crtc->fb;
 		fb = nouveau_framebuffer(crtc->fb);
-		/* If not atomic, we can go ahead and pin, and unpin the
-		 * old fb we were passed.
-		 */
-		ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
-		if (ret)
-			return ret;
-
-		if (passed_fb) {
-			struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
-			nouveau_bo_unpin(ofb->nvbo);
-		}
 	}
 
 	nv_crtc->fb.offset = fb->nvbo->bo.offset;
@@ -877,6 +901,9 @@ static int
 nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 			struct drm_framebuffer *old_fb)
 {
+	int ret = nv_crtc_swap_fbs(crtc, old_fb);
+	if (ret)
+		return ret;
 	return nv04_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
 }
 
@@ -1027,6 +1054,7 @@ static const struct drm_crtc_helper_func
 	.mode_set_base = nv04_crtc_mode_set_base,
 	.mode_set_base_atomic = nv04_crtc_mode_set_base_atomic,
 	.load_lut = nv_crtc_gamma_load,
+	.disable = nv_crtc_disable,
 };
 
 int
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/dispnv04/disp.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/dispnv04/disp.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/dispnv04/disp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/dispnv04/disp.h	2013-08-25 20:43:22.000000000 -0400
@@ -81,6 +81,7 @@ struct nv04_display {
 	uint32_t saved_vga_font[4][16384];
 	uint32_t dac_users[4];
 	struct nouveau_object *core;
+	struct nouveau_bo *image[2];
 };
 
 static inline struct nv04_display *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/Kconfig linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/Kconfig
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,13 @@ config DRM_NOUVEAU
 	select ACPI_WMI if ACPI && X86
 	select MXM_WMI if ACPI && X86
 	select POWER_SUPPLY
+	# Similar to i915, we need to select ACPI_VIDEO and it's dependencies
+	select BACKLIGHT_LCD_SUPPORT if ACPI && X86
+	select BACKLIGHT_CLASS_DEVICE if ACPI && X86
+	select VIDEO_OUTPUT_CONTROL if ACPI && X86
+	select INPUT if ACPI && X86
+	select THERMAL if ACPI && X86
+	select ACPI_VIDEO if ACPI && X86
 	help
 	  Choose this option for open-source nVidia support.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/Makefile linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/Makefile
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,6 @@ nouveau-y += core/core/engctx.o
 nouveau-y += core/core/engine.o
 nouveau-y += core/core/enum.o
 nouveau-y += core/core/event.o
-nouveau-y += core/core/falcon.o
 nouveau-y += core/core/gpuobj.o
 nouveau-y += core/core/handle.o
 nouveau-y += core/core/mm.o
@@ -60,6 +59,8 @@ nouveau-y += core/subdev/devinit/nv10.o
 nouveau-y += core/subdev/devinit/nv1a.o
 nouveau-y += core/subdev/devinit/nv20.o
 nouveau-y += core/subdev/devinit/nv50.o
+nouveau-y += core/subdev/devinit/nva3.o
+nouveau-y += core/subdev/devinit/nvc0.o
 nouveau-y += core/subdev/fb/base.o
 nouveau-y += core/subdev/fb/nv04.o
 nouveau-y += core/subdev/fb/nv10.o
@@ -78,6 +79,17 @@ nouveau-y += core/subdev/fb/nv49.o
 nouveau-y += core/subdev/fb/nv4e.o
 nouveau-y += core/subdev/fb/nv50.o
 nouveau-y += core/subdev/fb/nvc0.o
+nouveau-y += core/subdev/fb/ramnv04.o
+nouveau-y += core/subdev/fb/ramnv10.o
+nouveau-y += core/subdev/fb/ramnv1a.o
+nouveau-y += core/subdev/fb/ramnv20.o
+nouveau-y += core/subdev/fb/ramnv40.o
+nouveau-y += core/subdev/fb/ramnv41.o
+nouveau-y += core/subdev/fb/ramnv44.o
+nouveau-y += core/subdev/fb/ramnv49.o
+nouveau-y += core/subdev/fb/ramnv4e.o
+nouveau-y += core/subdev/fb/ramnv50.o
+nouveau-y += core/subdev/fb/ramnvc0.o
 nouveau-y += core/subdev/gpio/base.o
 nouveau-y += core/subdev/gpio/nv10.o
 nouveau-y += core/subdev/gpio/nv50.o
@@ -129,12 +141,15 @@ nouveau-y += core/subdev/vm/nv44.o
 nouveau-y += core/subdev/vm/nv50.o
 nouveau-y += core/subdev/vm/nvc0.o
 
+nouveau-y += core/engine/falcon.o
+nouveau-y += core/engine/xtensa.o
 nouveau-y += core/engine/dmaobj/base.o
 nouveau-y += core/engine/dmaobj/nv04.o
 nouveau-y += core/engine/dmaobj/nv50.o
 nouveau-y += core/engine/dmaobj/nvc0.o
 nouveau-y += core/engine/dmaobj/nvd0.o
 nouveau-y += core/engine/bsp/nv84.o
+nouveau-y += core/engine/bsp/nv98.o
 nouveau-y += core/engine/bsp/nvc0.o
 nouveau-y += core/engine/bsp/nve0.o
 nouveau-y += core/engine/copy/nva3.o
@@ -185,7 +200,13 @@ nouveau-y += core/engine/fifo/nve0.o
 nouveau-y += core/engine/graph/ctxnv40.o
 nouveau-y += core/engine/graph/ctxnv50.o
 nouveau-y += core/engine/graph/ctxnvc0.o
-nouveau-y += core/engine/graph/ctxnve0.o
+nouveau-y += core/engine/graph/ctxnvc1.o
+nouveau-y += core/engine/graph/ctxnvc3.o
+nouveau-y += core/engine/graph/ctxnvc8.o
+nouveau-y += core/engine/graph/ctxnvd7.o
+nouveau-y += core/engine/graph/ctxnvd9.o
+nouveau-y += core/engine/graph/ctxnve4.o
+nouveau-y += core/engine/graph/ctxnvf0.o
 nouveau-y += core/engine/graph/nv04.o
 nouveau-y += core/engine/graph/nv10.o
 nouveau-y += core/engine/graph/nv20.o
@@ -197,7 +218,13 @@ nouveau-y += core/engine/graph/nv35.o
 nouveau-y += core/engine/graph/nv40.o
 nouveau-y += core/engine/graph/nv50.o
 nouveau-y += core/engine/graph/nvc0.o
-nouveau-y += core/engine/graph/nve0.o
+nouveau-y += core/engine/graph/nvc1.o
+nouveau-y += core/engine/graph/nvc3.o
+nouveau-y += core/engine/graph/nvc8.o
+nouveau-y += core/engine/graph/nvd7.o
+nouveau-y += core/engine/graph/nvd9.o
+nouveau-y += core/engine/graph/nve4.o
+nouveau-y += core/engine/graph/nvf0.o
 nouveau-y += core/engine/mpeg/nv31.o
 nouveau-y += core/engine/mpeg/nv40.o
 nouveau-y += core/engine/mpeg/nv50.o
@@ -209,6 +236,7 @@ nouveau-y += core/engine/software/nv10.o
 nouveau-y += core/engine/software/nv50.o
 nouveau-y += core/engine/software/nvc0.o
 nouveau-y += core/engine/vp/nv84.o
+nouveau-y += core/engine/vp/nv98.o
 nouveau-y += core/engine/vp/nvc0.o
 nouveau-y += core/engine/vp/nve0.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_abi16.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_abi16.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_abi16.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_abi16.c	2013-08-25 20:43:22.000000000 -0400
@@ -129,6 +129,7 @@ nouveau_abi16_chan_fini(struct nouveau_a
 
 	if (chan->ntfy) {
 		nouveau_bo_vma_del(chan->ntfy, &chan->ntfy_vma);
+		nouveau_bo_unpin(chan->ntfy);
 		drm_gem_object_unreference_unlocked(chan->ntfy->gem);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_bios.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_bios.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_bios.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_bios.c	2013-08-25 20:43:22.000000000 -0400
@@ -1878,9 +1878,6 @@ parse_dcb_table(struct drm_device *dev,
 	if (dcb->version < 0x21)
 		merge_like_dcb_entries(dev, dcb);
 
-	if (!dcb->entries)
-		return -ENXIO;
-
 	/* dump connector table entries to log, if any exist */
 	idx = -1;
 	while ((conn = olddcb_conn(dev, ++idx))) {
@@ -2054,19 +2051,14 @@ nouveau_bios_posted(struct drm_device *d
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	unsigned htotal;
 
-	if (nv_device(drm->device)->card_type >= NV_50) {
-		if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
-		    NVReadVgaCrtc(dev, 0, 0x1a) == 0)
-			return false;
+	if (nv_device(drm->device)->card_type >= NV_50)
 		return true;
-	}
 
 	htotal  = NVReadVgaCrtc(dev, 0, 0x06);
 	htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
 	htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
 	htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
 	htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
-
 	return (htotal != 0);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_bo.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_bo.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_bo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_bo.c	2013-08-25 20:43:22.000000000 -0400
@@ -148,6 +148,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_obj
 
 	if (unlikely(nvbo->gem))
 		DRM_ERROR("bo %p still attached to GEM object\n", bo);
+	WARN_ON(nvbo->pin_refcnt > 0);
 	nv10_bo_put_tile_region(dev, nvbo->tile, NULL);
 	kfree(nvbo);
 }
@@ -197,6 +198,17 @@ nouveau_bo_new(struct drm_device *dev, i
 	size_t acc_size;
 	int ret;
 	int type = ttm_bo_type_device;
+	int lpg_shift = 12;
+	int max_size;
+
+	if (drm->client.base.vm)
+		lpg_shift = drm->client.base.vm->vmm->lpg_shift;
+	max_size = INT_MAX & ~((1 << lpg_shift) - 1);
+
+	if (size <= 0 || size > max_size) {
+		nv_warn(drm, "skipped size %x\n", (u32)size);
+		return -EINVAL;
+	}
 
 	if (sg)
 		type = ttm_bo_type_sg;
@@ -255,7 +267,7 @@ set_placement_range(struct nouveau_bo *n
 {
 	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
 	struct nouveau_fb *pfb = nouveau_fb(drm->device);
-	u32 vram_pages = pfb->ram.size >> PAGE_SHIFT;
+	u32 vram_pages = pfb->ram->size >> PAGE_SHIFT;
 
 	if (nv_device(drm->device)->card_type == NV_10 &&
 	    nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
@@ -340,13 +352,15 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo
 {
 	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
 	struct ttm_buffer_object *bo = &nvbo->bo;
-	int ret;
+	int ret, ref;
 
 	ret = ttm_bo_reserve(bo, false, false, false, 0);
 	if (ret)
 		return ret;
 
-	if (--nvbo->pin_refcnt)
+	ref = --nvbo->pin_refcnt;
+	WARN_ON_ONCE(ref < 0);
+	if (ref)
 		goto out;
 
 	nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);
@@ -578,7 +592,7 @@ nve0_bo_move_init(struct nouveau_channel
 	int ret = RING_SPACE(chan, 2);
 	if (ret == 0) {
 		BEGIN_NVC0(chan, NvSubCopy, 0x0000, 1);
-		OUT_RING  (chan, handle);
+		OUT_RING  (chan, handle & 0x0000ffff);
 		FIRE_RING (chan);
 	}
 	return ret;
@@ -968,12 +982,12 @@ nouveau_bo_move_m2mf(struct ttm_buffer_o
 		     bool no_wait_gpu, struct ttm_mem_reg *new_mem)
 {
 	struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
-	struct nouveau_channel *chan = chan = drm->channel;
+	struct nouveau_channel *chan = chan = drm->ttm.chan;
 	struct nouveau_bo *nvbo = nouveau_bo(bo);
 	struct ttm_mem_reg *old_mem = &bo->mem;
 	int ret;
 
-	mutex_lock(&chan->cli->mutex);
+	mutex_lock_nested(&chan->cli->mutex, SINGLE_DEPTH_NESTING);
 
 	/* create temporary vmas for the transfer and attach them to the
 	 * old nouveau_mem node, these will get cleaned up after ttm has
@@ -1014,7 +1028,7 @@ nouveau_bo_move_init(struct nouveau_drm
 			    struct ttm_mem_reg *, struct ttm_mem_reg *);
 		int (*init)(struct nouveau_channel *, u32 handle);
 	} _methods[] = {
-		{  "COPY", 0, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
+		{  "COPY", 4, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
 		{  "GRCE", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init },
 		{ "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_move_init },
 		{ "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_move_init },
@@ -1034,7 +1048,7 @@ nouveau_bo_move_init(struct nouveau_drm
 		struct nouveau_channel *chan;
 		u32 handle = (mthd->engine << 16) | mthd->oclass;
 
-		if (mthd->init == nve0_bo_move_init)
+		if (mthd->engine)
 			chan = drm->cechan;
 		else
 			chan = drm->channel;
@@ -1052,6 +1066,7 @@ nouveau_bo_move_init(struct nouveau_drm
 			}
 
 			drm->ttm.move = mthd->exec;
+			drm->ttm.chan = chan;
 			name = mthd->name;
 			break;
 		}
@@ -1550,13 +1565,8 @@ void
 nouveau_bo_vma_del(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
 {
 	if (vma->node) {
-		if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM) {
-			spin_lock(&nvbo->bo.bdev->fence_lock);
-			ttm_bo_wait(&nvbo->bo, false, false, false);
-			spin_unlock(&nvbo->bo.bdev->fence_lock);
+		if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM)
 			nouveau_vm_unmap(vma);
-		}
-
 		nouveau_vm_put(vma);
 		list_del(&vma->head);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_chan.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_chan.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_chan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_chan.c	2013-08-25 20:43:22.000000000 -0400
@@ -147,7 +147,7 @@ nouveau_channel_prep(struct nouveau_drm
 		args.limit = client->vm->vmm->limit - 1;
 	} else
 	if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) {
-		u64 limit = pfb->ram.size - imem->reserved - 1;
+		u64 limit = pfb->ram->size - imem->reserved - 1;
 		if (device->card_type == NV_04) {
 			/* nv04 vram pushbuf hack, retarget to its location in
 			 * the framebuffer bar rather than direct vram access..
@@ -282,7 +282,7 @@ nouveau_channel_init(struct nouveau_chan
 		} else {
 			args.flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR;
 			args.start = 0;
-			args.limit = pfb->ram.size - imem->reserved - 1;
+			args.limit = pfb->ram->size - imem->reserved - 1;
 		}
 
 		ret = nouveau_object_new(nv_object(client), chan->handle, vram,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_display.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_display.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_display.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_display.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,7 @@
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
+#include <drm/ttm/ttm_execbuf_util.h>
 
 #include "nouveau_fbcon.h"
 #include "dispnv04/hw.h"
@@ -137,7 +138,7 @@ nouveau_user_framebuffer_create(struct d
 {
 	struct nouveau_framebuffer *nouveau_fb;
 	struct drm_gem_object *gem;
-	int ret;
+	int ret = -ENOMEM;
 
 	gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
 	if (!gem)
@@ -145,15 +146,19 @@ nouveau_user_framebuffer_create(struct d
 
 	nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL);
 	if (!nouveau_fb)
-		return ERR_PTR(-ENOMEM);
+		goto err_unref;
 
 	ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem));
-	if (ret) {
-		drm_gem_object_unreference(gem);
-		return ERR_PTR(ret);
-	}
+	if (ret)
+		goto err;
 
 	return &nouveau_fb->base;
+
+err:
+	kfree(nouveau_fb);
+err_unref:
+	drm_gem_object_unreference(gem);
+	return ERR_PTR(ret);
 }
 
 static const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
@@ -332,10 +337,15 @@ nouveau_display_create(struct drm_device
 
 	if (nouveau_modeset == 1 ||
 	    (nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) {
-		if (nv_device(drm->device)->card_type < NV_50)
-			ret = nv04_display_create(dev);
-		else
-			ret = nv50_display_create(dev);
+		if (drm->vbios.dcb.entries) {
+			if (nv_device(drm->device)->card_type < NV_50)
+				ret = nv04_display_create(dev);
+			else
+				ret = nv50_display_create(dev);
+		} else {
+			ret = 0;
+		}
+
 		if (ret)
 			goto disp_create_err;
 
@@ -457,51 +467,6 @@ nouveau_display_resume(struct drm_device
 }
 
 static int
-nouveau_page_flip_reserve(struct nouveau_bo *old_bo,
-			  struct nouveau_bo *new_bo)
-{
-	int ret;
-
-	ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM);
-	if (ret)
-		return ret;
-
-	ret = ttm_bo_reserve(&new_bo->bo, false, false, false, 0);
-	if (ret)
-		goto fail;
-
-	if (likely(old_bo != new_bo)) {
-		ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0);
-		if (ret)
-			goto fail_unreserve;
-	}
-
-	return 0;
-
-fail_unreserve:
-	ttm_bo_unreserve(&new_bo->bo);
-fail:
-	nouveau_bo_unpin(new_bo);
-	return ret;
-}
-
-static void
-nouveau_page_flip_unreserve(struct nouveau_bo *old_bo,
-			    struct nouveau_bo *new_bo,
-			    struct nouveau_fence *fence)
-{
-	nouveau_bo_fence(new_bo, fence);
-	ttm_bo_unreserve(&new_bo->bo);
-
-	if (likely(old_bo != new_bo)) {
-		nouveau_bo_fence(old_bo, fence);
-		ttm_bo_unreserve(&old_bo->bo);
-	}
-
-	nouveau_bo_unpin(old_bo);
-}
-
-static int
 nouveau_page_flip_emit(struct nouveau_channel *chan,
 		       struct nouveau_bo *old_bo,
 		       struct nouveau_bo *new_bo,
@@ -563,6 +528,12 @@ nouveau_crtc_page_flip(struct drm_crtc *
 	struct nouveau_page_flip_state *s;
 	struct nouveau_channel *chan = NULL;
 	struct nouveau_fence *fence;
+	struct ttm_validate_buffer resv[2] = {
+		{ .bo = &old_bo->bo },
+		{ .bo = &new_bo->bo },
+	};
+	struct ww_acquire_ctx ticket;
+	LIST_HEAD(res);
 	int ret;
 
 	if (!drm->channel)
@@ -572,32 +543,43 @@ nouveau_crtc_page_flip(struct drm_crtc *
 	if (!s)
 		return -ENOMEM;
 
-	/* Don't let the buffers go away while we flip */
-	ret = nouveau_page_flip_reserve(old_bo, new_bo);
-	if (ret)
-		goto fail_free;
-
-	/* Initialize a page flip struct */
-	*s = (struct nouveau_page_flip_state)
-		{ { }, event, nouveau_crtc(crtc)->index,
-		  fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y,
-		  new_bo->bo.offset };
-
 	/* Choose the channel the flip will be handled in */
+	spin_lock(&old_bo->bo.bdev->fence_lock);
 	fence = new_bo->bo.sync_obj;
 	if (fence)
 		chan = fence->channel;
 	if (!chan)
 		chan = drm->channel;
+	spin_unlock(&old_bo->bo.bdev->fence_lock);
+
+	if (new_bo != old_bo) {
+		ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM);
+		if (ret)
+			goto fail_free;
+
+		list_add(&resv[1].head, &res);
+	}
+	list_add(&resv[0].head, &res);
+
 	mutex_lock(&chan->cli->mutex);
+	ret = ttm_eu_reserve_buffers(&ticket, &res);
+	if (ret)
+		goto fail_unpin;
+
+	/* Initialize a page flip struct */
+	*s = (struct nouveau_page_flip_state)
+		{ { }, event, nouveau_crtc(crtc)->index,
+		  fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y,
+		  new_bo->bo.offset };
 
 	/* Emit a page flip */
 	if (nv_device(drm->device)->card_type >= NV_50) {
 		ret = nv50_display_flip_next(crtc, fb, chan, 0);
-		if (ret) {
-			mutex_unlock(&chan->cli->mutex);
+		if (ret)
 			goto fail_unreserve;
-		}
+	} else {
+		struct nv04_display *dispnv04 = nv04_display(dev);
+		nouveau_bo_ref(new_bo, &dispnv04->image[nouveau_crtc(crtc)->index]);
 	}
 
 	ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
@@ -608,12 +590,18 @@ nouveau_crtc_page_flip(struct drm_crtc *
 	/* Update the crtc struct and cleanup */
 	crtc->fb = fb;
 
-	nouveau_page_flip_unreserve(old_bo, new_bo, fence);
+	ttm_eu_fence_buffer_objects(&ticket, &res, fence);
+	if (old_bo != new_bo)
+		nouveau_bo_unpin(old_bo);
 	nouveau_fence_unref(&fence);
 	return 0;
 
 fail_unreserve:
-	nouveau_page_flip_unreserve(old_bo, new_bo, NULL);
+	ttm_eu_backoff_reservation(&ticket, &res);
+fail_unpin:
+	mutex_unlock(&chan->cli->mutex);
+	if (old_bo != new_bo)
+		nouveau_bo_unpin(new_bo);
 fail_free:
 	kfree(s);
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_drm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_drm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_drm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_drm.c	2013-08-25 20:43:22.000000000 -0400
@@ -192,6 +192,18 @@ nouveau_accel_init(struct nouveau_drm *d
 
 		arg0 = NVE0_CHANNEL_IND_ENGINE_GR;
 		arg1 = 1;
+	} else
+	if (device->chipset >= 0xa3 &&
+	    device->chipset != 0xaa &&
+	    device->chipset != 0xac) {
+		ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE,
+					  NVDRM_CHAN + 1, NvDmaFB, NvDmaTT,
+					  &drm->cechan);
+		if (ret)
+			NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
+
+		arg0 = NvDmaFB;
+		arg1 = NvDmaTT;
 	} else {
 		arg0 = NvDmaFB;
 		arg1 = NvDmaTT;
@@ -284,8 +296,6 @@ static int nouveau_drm_probe(struct pci_
 	return 0;
 }
 
-static struct lock_class_key drm_client_lock_class_key;
-
 static int
 nouveau_drm_load(struct drm_device *dev, unsigned long flags)
 {
@@ -297,7 +307,6 @@ nouveau_drm_load(struct drm_device *dev,
 	ret = nouveau_cli_create(pdev, "DRM", sizeof(*drm), (void**)&drm);
 	if (ret)
 		return ret;
-	lockdep_set_class(&drm->client.mutex, &drm_client_lock_class_key);
 
 	dev->dev_private = drm;
 	drm->dev = dev;
@@ -702,6 +711,7 @@ driver = {
 	.gem_prime_export = drm_gem_prime_export,
 	.gem_prime_import = drm_gem_prime_import,
 	.gem_prime_pin = nouveau_gem_prime_pin,
+	.gem_prime_unpin = nouveau_gem_prime_unpin,
 	.gem_prime_get_sg_table = nouveau_gem_prime_get_sg_table,
 	.gem_prime_import_sg_table = nouveau_gem_prime_import_sg_table,
 	.gem_prime_vmap = nouveau_gem_prime_vmap,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_drm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_drm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_drm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_drm.h	2013-08-25 20:43:22.000000000 -0400
@@ -96,6 +96,7 @@ struct nouveau_drm {
 		int (*move)(struct nouveau_channel *,
 			    struct ttm_buffer_object *,
 			    struct ttm_mem_reg *, struct ttm_mem_reg *);
+		struct nouveau_channel *chan;
 		int mtrr;
 	} ttm;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_fbcon.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_fbcon.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_fbcon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_fbcon.c	2013-08-25 20:43:22.000000000 -0400
@@ -289,16 +289,13 @@ nouveau_fbcon_create(struct drm_fb_helpe
 	ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM);
 	if (ret) {
 		NV_ERROR(drm, "failed to pin fb: %d\n", ret);
-		nouveau_bo_ref(NULL, &nvbo);
-		goto out;
+		goto out_unref;
 	}
 
 	ret = nouveau_bo_map(nvbo);
 	if (ret) {
 		NV_ERROR(drm, "failed to map fb: %d\n", ret);
-		nouveau_bo_unpin(nvbo);
-		nouveau_bo_ref(NULL, &nvbo);
-		goto out;
+		goto out_unpin;
 	}
 
 	chan = nouveau_nofbaccel ? NULL : drm->channel;
@@ -316,13 +313,14 @@ nouveau_fbcon_create(struct drm_fb_helpe
 	info = framebuffer_alloc(0, &pdev->dev);
 	if (!info) {
 		ret = -ENOMEM;
-		goto out_unref;
+		goto out_unlock;
 	}
 
 	ret = fb_alloc_cmap(&info->cmap, 256, 0);
 	if (ret) {
 		ret = -ENOMEM;
-		goto out_unref;
+		framebuffer_release(info);
+		goto out_unlock;
 	}
 
 	info->par = fbcon;
@@ -337,7 +335,7 @@ nouveau_fbcon_create(struct drm_fb_helpe
 	fbcon->helper.fbdev = info;
 
 	strcpy(info->fix.id, "nouveaufb");
-	if (nouveau_nofbaccel)
+	if (!chan)
 		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_DISABLED;
 	else
 		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
@@ -383,8 +381,15 @@ nouveau_fbcon_create(struct drm_fb_helpe
 	vga_switcheroo_client_fb_set(dev->pdev, info);
 	return 0;
 
-out_unref:
+out_unlock:
 	mutex_unlock(&dev->struct_mutex);
+	if (chan)
+		nouveau_bo_vma_del(nvbo, &fbcon->nouveau_fb.vma);
+	nouveau_bo_unmap(nvbo);
+out_unpin:
+	nouveau_bo_unpin(nvbo);
+out_unref:
+	nouveau_bo_ref(NULL, &nvbo);
 out:
 	return ret;
 }
@@ -393,7 +398,8 @@ void
 nouveau_fbcon_output_poll_changed(struct drm_device *dev)
 {
 	struct nouveau_drm *drm = nouveau_drm(dev);
-	drm_fb_helper_hotplug_event(&drm->fbcon->helper);
+	if (drm->fbcon)
+		drm_fb_helper_hotplug_event(&drm->fbcon->helper);
 }
 
 static int
@@ -413,6 +419,7 @@ nouveau_fbcon_destroy(struct drm_device
 	if (nouveau_fb->nvbo) {
 		nouveau_bo_unmap(nouveau_fb->nvbo);
 		nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma);
+		nouveau_bo_unpin(nouveau_fb->nvbo);
 		drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem);
 		nouveau_fb->nvbo = NULL;
 	}
@@ -467,10 +474,10 @@ nouveau_fbcon_init(struct drm_device *de
 
 	drm_fb_helper_single_add_all_connectors(&fbcon->helper);
 
-	if (pfb->ram.size <= 32 * 1024 * 1024)
+	if (pfb->ram->size <= 32 * 1024 * 1024)
 		preferred_bpp = 8;
 	else
-	if (pfb->ram.size <= 64 * 1024 * 1024)
+	if (pfb->ram->size <= 64 * 1024 * 1024)
 		preferred_bpp = 16;
 	else
 		preferred_bpp = 32;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_fence.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_fence.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_fence.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_fence.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,15 +35,34 @@
 
 #include <engine/fifo.h>
 
+struct fence_work {
+	struct work_struct base;
+	struct list_head head;
+	void (*func)(void *);
+	void *data;
+};
+
+static void
+nouveau_fence_signal(struct nouveau_fence *fence)
+{
+	struct fence_work *work, *temp;
+
+	list_for_each_entry_safe(work, temp, &fence->work, head) {
+		schedule_work(&work->base);
+		list_del(&work->head);
+	}
+
+	fence->channel = NULL;
+	list_del(&fence->head);
+}
+
 void
 nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
 {
 	struct nouveau_fence *fence, *fnext;
 	spin_lock(&fctx->lock);
 	list_for_each_entry_safe(fence, fnext, &fctx->pending, head) {
-		fence->channel = NULL;
-		list_del(&fence->head);
-		nouveau_fence_unref(&fence);
+		nouveau_fence_signal(fence);
 	}
 	spin_unlock(&fctx->lock);
 }
@@ -57,6 +76,50 @@ nouveau_fence_context_new(struct nouveau
 }
 
 static void
+nouveau_fence_work_handler(struct work_struct *kwork)
+{
+	struct fence_work *work = container_of(kwork, typeof(*work), base);
+	work->func(work->data);
+	kfree(work);
+}
+
+void
+nouveau_fence_work(struct nouveau_fence *fence,
+		   void (*func)(void *), void *data)
+{
+	struct nouveau_channel *chan = fence->channel;
+	struct nouveau_fence_chan *fctx;
+	struct fence_work *work = NULL;
+
+	if (nouveau_fence_done(fence)) {
+		func(data);
+		return;
+	}
+
+	fctx = chan->fence;
+	work = kmalloc(sizeof(*work), GFP_KERNEL);
+	if (!work) {
+		WARN_ON(nouveau_fence_wait(fence, false, false));
+		func(data);
+		return;
+	}
+
+	spin_lock(&fctx->lock);
+	if (!fence->channel) {
+		spin_unlock(&fctx->lock);
+		kfree(work);
+		func(data);
+		return;
+	}
+
+	INIT_WORK(&work->base, nouveau_fence_work_handler);
+	work->func = func;
+	work->data = data;
+	list_add(&work->head, &fence->work);
+	spin_unlock(&fctx->lock);
+}
+
+static void
 nouveau_fence_update(struct nouveau_channel *chan)
 {
 	struct nouveau_fence_chan *fctx = chan->fence;
@@ -67,8 +130,7 @@ nouveau_fence_update(struct nouveau_chan
 		if (fctx->read(chan) < fence->sequence)
 			break;
 
-		fence->channel = NULL;
-		list_del(&fence->head);
+		nouveau_fence_signal(fence);
 		nouveau_fence_unref(&fence);
 	}
 	spin_unlock(&fctx->lock);
@@ -81,7 +143,7 @@ nouveau_fence_emit(struct nouveau_fence
 	int ret;
 
 	fence->channel  = chan;
-	fence->timeout  = jiffies + (3 * DRM_HZ);
+	fence->timeout  = jiffies + (15 * DRM_HZ);
 	fence->sequence = ++fctx->sequence;
 
 	ret = fctx->emit(fence);
@@ -265,6 +327,7 @@ nouveau_fence_new(struct nouveau_channel
 	if (!fence)
 		return -ENOMEM;
 
+	INIT_LIST_HEAD(&fence->work);
 	fence->sysmem = sysmem;
 	kref_init(&fence->kref);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_fence.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_fence.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_fence.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_fence.h	2013-08-25 20:43:22.000000000 -0400
@@ -5,6 +5,7 @@ struct nouveau_drm;
 
 struct nouveau_fence {
 	struct list_head head;
+	struct list_head work;
 	struct kref kref;
 
 	bool sysmem;
@@ -22,6 +23,7 @@ void nouveau_fence_unref(struct nouveau_
 
 int  nouveau_fence_emit(struct nouveau_fence *, struct nouveau_channel *);
 bool nouveau_fence_done(struct nouveau_fence *);
+void nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *);
 int  nouveau_fence_wait(struct nouveau_fence *, bool lazy, bool intr);
 int  nouveau_fence_sync(struct nouveau_fence *, struct nouveau_channel *);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_gem.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_gem.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_gem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_gem.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,11 +50,6 @@ nouveau_gem_object_del(struct drm_gem_ob
 		return;
 	nvbo->gem = NULL;
 
-	if (unlikely(nvbo->pin_refcnt)) {
-		nvbo->pin_refcnt = 1;
-		nouveau_bo_unpin(nvbo);
-	}
-
 	if (gem->import_attach)
 		drm_prime_gem_destroy(gem, nvbo->bo.sg);
 
@@ -101,6 +96,41 @@ out:
 	return ret;
 }
 
+static void
+nouveau_gem_object_delete(void *data)
+{
+	struct nouveau_vma *vma = data;
+	nouveau_vm_unmap(vma);
+	nouveau_vm_put(vma);
+	kfree(vma);
+}
+
+static void
+nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
+{
+	const bool mapped = nvbo->bo.mem.mem_type != TTM_PL_SYSTEM;
+	struct nouveau_fence *fence = NULL;
+
+	list_del(&vma->head);
+
+	if (mapped) {
+		spin_lock(&nvbo->bo.bdev->fence_lock);
+		if (nvbo->bo.sync_obj)
+			fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+		spin_unlock(&nvbo->bo.bdev->fence_lock);
+	}
+
+	if (fence) {
+		nouveau_fence_work(fence, nouveau_gem_object_delete, vma);
+	} else {
+		if (mapped)
+			nouveau_vm_unmap(vma);
+		nouveau_vm_put(vma);
+		kfree(vma);
+	}
+	nouveau_fence_unref(&fence);
+}
+
 void
 nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
 {
@@ -118,10 +148,8 @@ nouveau_gem_object_close(struct drm_gem_
 
 	vma = nouveau_bo_vma_find(nvbo, cli->base.vm);
 	if (vma) {
-		if (--vma->refcount == 0) {
-			nouveau_bo_vma_del(nvbo, vma);
-			kfree(vma);
-		}
+		if (--vma->refcount == 0)
+			nouveau_gem_object_unmap(nvbo, vma);
 	}
 	ttm_bo_unreserve(&nvbo->bo);
 }
@@ -276,10 +304,12 @@ struct validate_op {
 	struct list_head vram_list;
 	struct list_head gart_list;
 	struct list_head both_list;
+	struct ww_acquire_ctx ticket;
 };
 
 static void
-validate_fini_list(struct list_head *list, struct nouveau_fence *fence)
+validate_fini_list(struct list_head *list, struct nouveau_fence *fence,
+		   struct ww_acquire_ctx *ticket)
 {
 	struct list_head *entry, *tmp;
 	struct nouveau_bo *nvbo;
@@ -296,17 +326,24 @@ validate_fini_list(struct list_head *lis
 
 		list_del(&nvbo->entry);
 		nvbo->reserved_by = NULL;
-		ttm_bo_unreserve(&nvbo->bo);
+		ttm_bo_unreserve_ticket(&nvbo->bo, ticket);
 		drm_gem_object_unreference_unlocked(nvbo->gem);
 	}
 }
 
 static void
-validate_fini(struct validate_op *op, struct nouveau_fence* fence)
+validate_fini_no_ticket(struct validate_op *op, struct nouveau_fence *fence)
 {
-	validate_fini_list(&op->vram_list, fence);
-	validate_fini_list(&op->gart_list, fence);
-	validate_fini_list(&op->both_list, fence);
+	validate_fini_list(&op->vram_list, fence, &op->ticket);
+	validate_fini_list(&op->gart_list, fence, &op->ticket);
+	validate_fini_list(&op->both_list, fence, &op->ticket);
+}
+
+static void
+validate_fini(struct validate_op *op, struct nouveau_fence *fence)
+{
+	validate_fini_no_ticket(op, fence);
+	ww_acquire_fini(&op->ticket);
 }
 
 static int
@@ -316,13 +353,11 @@ validate_init(struct nouveau_channel *ch
 {
 	struct nouveau_cli *cli = nouveau_cli(file_priv);
 	struct drm_device *dev = chan->drm->dev;
-	struct nouveau_drm *drm = nouveau_drm(dev);
-	uint32_t sequence;
 	int trycnt = 0;
 	int ret, i;
 	struct nouveau_bo *res_bo = NULL;
 
-	sequence = atomic_add_return(1, &drm->ttm.validate_sequence);
+	ww_acquire_init(&op->ticket, &reservation_ww_class);
 retry:
 	if (++trycnt > 100000) {
 		NV_ERROR(cli, "%s failed and gave up.\n", __func__);
@@ -337,6 +372,7 @@ retry:
 		gem = drm_gem_object_lookup(dev, file_priv, b->handle);
 		if (!gem) {
 			NV_ERROR(cli, "Unknown handle 0x%08x\n", b->handle);
+			ww_acquire_done(&op->ticket);
 			validate_fini(op, NULL);
 			return -ENOENT;
 		}
@@ -351,21 +387,23 @@ retry:
 			NV_ERROR(cli, "multiple instances of buffer %d on "
 				      "validation list\n", b->handle);
 			drm_gem_object_unreference_unlocked(gem);
+			ww_acquire_done(&op->ticket);
 			validate_fini(op, NULL);
 			return -EINVAL;
 		}
 
-		ret = ttm_bo_reserve(&nvbo->bo, true, false, true, sequence);
+		ret = ttm_bo_reserve(&nvbo->bo, true, false, true, &op->ticket);
 		if (ret) {
-			validate_fini(op, NULL);
-			if (unlikely(ret == -EAGAIN)) {
-				sequence = atomic_add_return(1, &drm->ttm.validate_sequence);
+			validate_fini_no_ticket(op, NULL);
+			if (unlikely(ret == -EDEADLK)) {
 				ret = ttm_bo_reserve_slowpath(&nvbo->bo, true,
-							      sequence);
+							      &op->ticket);
 				if (!ret)
 					res_bo = nvbo;
 			}
 			if (unlikely(ret)) {
+				ww_acquire_done(&op->ticket);
+				ww_acquire_fini(&op->ticket);
 				drm_gem_object_unreference_unlocked(gem);
 				if (ret != -ERESTARTSYS)
 					NV_ERROR(cli, "fail reserve\n");
@@ -389,6 +427,7 @@ retry:
 			NV_ERROR(cli, "invalid valid domains: 0x%08x\n",
 				 b->valid_domains);
 			list_add_tail(&nvbo->entry, &op->both_list);
+			ww_acquire_done(&op->ticket);
 			validate_fini(op, NULL);
 			return -EINVAL;
 		}
@@ -396,6 +435,7 @@ retry:
 			goto retry;
 	}
 
+	ww_acquire_done(&op->ticket);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_gem.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_gem.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_gem.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_gem.h	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,7 @@ extern int nouveau_gem_ioctl_info(struct
 				  struct drm_file *);
 
 extern int nouveau_gem_prime_pin(struct drm_gem_object *);
+extern void nouveau_gem_prime_unpin(struct drm_gem_object *);
 extern struct sg_table *nouveau_gem_prime_get_sg_table(struct drm_gem_object *);
 extern struct drm_gem_object *nouveau_gem_prime_import_sg_table(
 	struct drm_device *, size_t size, struct sg_table *);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_mem.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_mem.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_mem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_mem.c	2013-08-25 20:43:22.000000000 -0400
@@ -125,7 +125,7 @@ nv50_mem_timing_calc(struct drm_device *
 		t->reg[7] = 0x4000202 | (e->tCL - 1) << 16;
 
 		/* XXX: P.version == 1 only has DDR2 and GDDR3? */
-		if (pfb->ram.type == NV_MEM_TYPE_DDR2) {
+		if (pfb->ram->type == NV_MEM_TYPE_DDR2) {
 			t->reg[5] |= (e->tCL + 3) << 8;
 			t->reg[6] |= (t->tCWL - 2) << 8;
 			t->reg[8] |= (e->tCL - 4);
@@ -428,7 +428,7 @@ nouveau_mem_timing_calc(struct drm_devic
 		break;
 	}
 
-	switch (pfb->ram.type * !ret) {
+	switch (pfb->ram->type * !ret) {
 	case NV_MEM_TYPE_GDDR3:
 		ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
 		break;
@@ -455,7 +455,7 @@ nouveau_mem_timing_calc(struct drm_devic
 		else
 			dll_off = !!(ramcfg[2] & 0x40);
 
-		switch (pfb->ram.type) {
+		switch (pfb->ram->type) {
 		case NV_MEM_TYPE_GDDR3:
 			t->mr[1] &= ~0x00000040;
 			t->mr[1] |=  0x00000040 * dll_off;
@@ -522,7 +522,7 @@ nouveau_mem_timing_read(struct drm_devic
 	t->odt = 0;
 	t->drive_strength = 0;
 
-	switch (pfb->ram.type) {
+	switch (pfb->ram->type) {
 	case NV_MEM_TYPE_DDR3:
 		t->odt |= (t->mr[1] & 0x200) >> 7;
 	case NV_MEM_TYPE_DDR2:
@@ -551,7 +551,7 @@ nouveau_mem_exec(struct nouveau_mem_exec
 	u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] };
 	u32 mr1_dlloff;
 
-	switch (pfb->ram.type) {
+	switch (pfb->ram->type) {
 	case NV_MEM_TYPE_DDR2:
 		tDLLK = 2000;
 		mr1_dlloff = 0x00000001;
@@ -572,7 +572,7 @@ nouveau_mem_exec(struct nouveau_mem_exec
 	}
 
 	/* fetch current MRs */
-	switch (pfb->ram.type) {
+	switch (pfb->ram->type) {
 	case NV_MEM_TYPE_GDDR3:
 	case NV_MEM_TYPE_DDR3:
 		mr[2] = exec->mrg(exec, 2);
@@ -639,7 +639,7 @@ nouveau_mem_exec(struct nouveau_mem_exec
 		exec->mrs (exec, 0, info->mr[0] | 0x00000000);
 		exec->wait(exec, tMRD);
 		exec->wait(exec, tDLLK);
-		if (pfb->ram.type == NV_MEM_TYPE_GDDR3)
+		if (pfb->ram->type == NV_MEM_TYPE_GDDR3)
 			exec->precharge(exec);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_prime.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_prime.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_prime.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_prime.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,7 +84,7 @@ struct drm_gem_object *nouveau_gem_prime
 int nouveau_gem_prime_pin(struct drm_gem_object *obj)
 {
 	struct nouveau_bo *nvbo = nouveau_gem_object(obj);
-	int ret = 0;
+	int ret;
 
 	/* pin buffer into GTT */
 	ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_TT);
@@ -93,3 +93,10 @@ int nouveau_gem_prime_pin(struct drm_gem
 
 	return 0;
 }
+
+void nouveau_gem_prime_unpin(struct drm_gem_object *obj)
+{
+	struct nouveau_bo *nvbo = nouveau_gem_object(obj);
+
+	nouveau_bo_unpin(nvbo);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_ttm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_ttm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nouveau_ttm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nouveau_ttm.c	2013-08-25 20:43:22.000000000 -0400
@@ -69,7 +69,7 @@ nouveau_vram_manager_del(struct ttm_mem_
 	struct nouveau_drm *drm = nouveau_bdev(man->bdev);
 	struct nouveau_fb *pfb = nouveau_fb(drm->device);
 	nouveau_mem_node_cleanup(mem->mm_node);
-	pfb->ram.put(pfb, (struct nouveau_mem **)&mem->mm_node);
+	pfb->ram->put(pfb, (struct nouveau_mem **)&mem->mm_node);
 }
 
 static int
@@ -88,7 +88,7 @@ nouveau_vram_manager_new(struct ttm_mem_
 	if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG)
 		size_nc = 1 << nvbo->page_shift;
 
-	ret = pfb->ram.get(pfb, mem->num_pages << PAGE_SHIFT,
+	ret = pfb->ram->get(pfb, mem->num_pages << PAGE_SHIFT,
 			   mem->page_alignment << PAGE_SHIFT, size_nc,
 			   (nvbo->tile_flags >> 8) & 0x3ff, &node);
 	if (ret) {
@@ -111,7 +111,7 @@ nouveau_vram_manager_debug(struct ttm_me
 	struct nouveau_mm_node *r;
 	u32 total = 0, free = 0;
 
-	mutex_lock(&mm->mutex);
+	mutex_lock(&nv_subdev(pfb)->mutex);
 	list_for_each_entry(r, &mm->nodes, nl_entry) {
 		printk(KERN_DEBUG "%s %d: 0x%010llx 0x%010llx\n",
 		       prefix, r->type, ((u64)r->offset << 12),
@@ -121,7 +121,7 @@ nouveau_vram_manager_debug(struct ttm_me
 		if (!r->type)
 			free += r->length;
 	}
-	mutex_unlock(&mm->mutex);
+	mutex_unlock(&nv_subdev(pfb)->mutex);
 
 	printk(KERN_DEBUG "%s  total: 0x%010llx free: 0x%010llx\n",
 	       prefix, (u64)total << 12, (u64)free << 12);
@@ -168,9 +168,6 @@ nouveau_gart_manager_new(struct ttm_mem_
 	struct nouveau_bo *nvbo = nouveau_bo(bo);
 	struct nouveau_mem *node;
 
-	if (unlikely((mem->num_pages << PAGE_SHIFT) >= 512 * 1024 * 1024))
-		return -ENOMEM;
-
 	node = kzalloc(sizeof(*node), GFP_KERNEL);
 	if (!node)
 		return -ENOMEM;
@@ -386,7 +383,7 @@ nouveau_ttm_init(struct nouveau_drm *drm
 	}
 
 	/* VRAM init */
-	drm->gem.vram_available  = nouveau_fb(drm->device)->ram.size;
+	drm->gem.vram_available  = nouveau_fb(drm->device)->ram->size;
 	drm->gem.vram_available -= nouveau_instmem(drm->device)->reserved;
 
 	ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_VRAM,
@@ -396,15 +393,12 @@ nouveau_ttm_init(struct nouveau_drm *drm
 		return ret;
 	}
 
-	drm->ttm.mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 1),
-				     pci_resource_len(dev->pdev, 1),
-				     DRM_MTRR_WC);
+	drm->ttm.mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 1),
+					 pci_resource_len(dev->pdev, 1));
 
 	/* GART init */
 	if (drm->agp.stat != ENABLED) {
 		drm->gem.gart_available = nouveau_vmmgr(drm->device)->limit;
-		if (drm->gem.gart_available > 512 * 1024 * 1024)
-			drm->gem.gart_available = 512 * 1024 * 1024;
 	} else {
 		drm->gem.gart_available = drm->agp.size;
 	}
@@ -433,10 +427,6 @@ nouveau_ttm_fini(struct nouveau_drm *drm
 
 	nouveau_ttm_global_release(drm);
 
-	if (drm->ttm.mtrr >= 0) {
-		drm_mtrr_del(drm->ttm.mtrr,
-			     pci_resource_start(drm->dev->pdev, 1),
-			     pci_resource_len(drm->dev->pdev, 1), DRM_MTRR_WC);
-		drm->ttm.mtrr = -1;
-	}
+	arch_phys_wc_del(drm->ttm.mtrr);
+	drm->ttm.mtrr = 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv17_fence.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv17_fence.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv17_fence.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv17_fence.c	2013-08-25 20:43:22.000000000 -0400
@@ -76,7 +76,7 @@ nv17_fence_context_new(struct nouveau_ch
 	struct ttm_mem_reg *mem = &priv->bo->bo.mem;
 	struct nouveau_object *object;
 	u32 start = mem->start * PAGE_SIZE;
-	u32 limit = mem->start + mem->size - 1;
+	u32 limit = start + mem->size - 1;
 	int ret = 0;
 
 	fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv40_pm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv40_pm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv40_pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv40_pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -131,7 +131,7 @@ nv40_calc_pll(struct drm_device *dev, u3
 	if (clk < pll->vco1.max_freq)
 		pll->vco2.max_freq = 0;
 
-	pclk->pll_calc(pclk, pll, clk, &coef);
+	ret = pclk->pll_calc(pclk, pll, clk, &coef);
 	if (ret == 0)
 		return -ERANGE;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv50_display.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv50_display.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv50_display.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv50_display.c	2013-08-25 20:43:22.000000000 -0400
@@ -159,7 +159,7 @@ nv50_dmac_create_fbdma(struct nouveau_ob
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
 					.start = 0,
-					.limit = pfb->ram.size - 1,
+					.limit = pfb->ram->size - 1,
 					.conf0 = NV50_DMA_CONF0_ENABLE |
 					         NV50_DMA_CONF0_PART_256,
 				     }, sizeof(struct nv_dma_class), &object);
@@ -172,7 +172,7 @@ nv50_dmac_create_fbdma(struct nouveau_ob
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
 					.start = 0,
-					.limit = pfb->ram.size - 1,
+					.limit = pfb->ram->size - 1,
 					.conf0 = NV50_DMA_CONF0_ENABLE | 0x70 |
 					         NV50_DMA_CONF0_PART_256,
 				 }, sizeof(struct nv_dma_class), &object);
@@ -185,7 +185,7 @@ nv50_dmac_create_fbdma(struct nouveau_ob
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
 					.start = 0,
-					.limit = pfb->ram.size - 1,
+					.limit = pfb->ram->size - 1,
 					.conf0 = NV50_DMA_CONF0_ENABLE | 0x7a |
 					         NV50_DMA_CONF0_PART_256,
 				 }, sizeof(struct nv_dma_class), &object);
@@ -204,7 +204,7 @@ nvc0_dmac_create_fbdma(struct nouveau_ob
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
 					.start = 0,
-					.limit = pfb->ram.size - 1,
+					.limit = pfb->ram->size - 1,
 					.conf0 = NVC0_DMA_CONF0_ENABLE,
 				     }, sizeof(struct nv_dma_class), &object);
 	if (ret)
@@ -216,7 +216,7 @@ nvc0_dmac_create_fbdma(struct nouveau_ob
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
 					.start = 0,
-					.limit = pfb->ram.size - 1,
+					.limit = pfb->ram->size - 1,
 					.conf0 = NVC0_DMA_CONF0_ENABLE | 0xfe,
 				 }, sizeof(struct nv_dma_class), &object);
 	if (ret)
@@ -228,7 +228,7 @@ nvc0_dmac_create_fbdma(struct nouveau_ob
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
 					.start = 0,
-					.limit = pfb->ram.size - 1,
+					.limit = pfb->ram->size - 1,
 					.conf0 = NVC0_DMA_CONF0_ENABLE | 0xfe,
 				 }, sizeof(struct nv_dma_class), &object);
 	return ret;
@@ -246,7 +246,7 @@ nvd0_dmac_create_fbdma(struct nouveau_ob
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
 					.start = 0,
-					.limit = pfb->ram.size - 1,
+					.limit = pfb->ram->size - 1,
 					.conf0 = NVD0_DMA_CONF0_ENABLE |
 						 NVD0_DMA_CONF0_PAGE_LP,
 				     }, sizeof(struct nv_dma_class), &object);
@@ -259,7 +259,7 @@ nvd0_dmac_create_fbdma(struct nouveau_ob
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
 					.start = 0,
-					.limit = pfb->ram.size - 1,
+					.limit = pfb->ram->size - 1,
 					.conf0 = NVD0_DMA_CONF0_ENABLE | 0xfe |
 						 NVD0_DMA_CONF0_PAGE_LP,
 				 }, sizeof(struct nv_dma_class), &object);
@@ -316,7 +316,7 @@ nv50_dmac_create(struct nouveau_object *
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
 					.start = 0,
-					.limit = pfb->ram.size - 1,
+					.limit = pfb->ram->size - 1,
 				 }, sizeof(struct nv_dma_class), &object);
 	if (ret)
 		return ret;
@@ -355,6 +355,7 @@ struct nv50_oimm {
 
 struct nv50_head {
 	struct nouveau_crtc base;
+	struct nouveau_bo *image;
 	struct nv50_curs curs;
 	struct nv50_sync sync;
 	struct nv50_ovly ovly;
@@ -517,9 +518,10 @@ nv50_display_flip_next(struct drm_crtc *
 {
 	struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
 	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+	struct nv50_head *head = nv50_head(crtc);
 	struct nv50_sync *sync = nv50_sync(crtc);
-	int head = nv_crtc->index, ret;
 	u32 *push;
+	int ret;
 
 	swap_interval <<= 4;
 	if (swap_interval == 0)
@@ -537,7 +539,7 @@ nv50_display_flip_next(struct drm_crtc *
 			return ret;
 
 		BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2);
-		OUT_RING  (chan, NvEvoSema0 + head);
+		OUT_RING  (chan, NvEvoSema0 + nv_crtc->index);
 		OUT_RING  (chan, sync->addr ^ 0x10);
 		BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1);
 		OUT_RING  (chan, sync->data + 1);
@@ -546,7 +548,7 @@ nv50_display_flip_next(struct drm_crtc *
 		OUT_RING  (chan, sync->data);
 	} else
 	if (chan && nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) {
-		u64 addr = nv84_fence_crtc(chan, head) + sync->addr;
+		u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr;
 		ret = RING_SPACE(chan, 12);
 		if (ret)
 			return ret;
@@ -565,7 +567,7 @@ nv50_display_flip_next(struct drm_crtc *
 		OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
 	} else
 	if (chan) {
-		u64 addr = nv84_fence_crtc(chan, head) + sync->addr;
+		u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr;
 		ret = RING_SPACE(chan, 10);
 		if (ret)
 			return ret;
@@ -630,6 +632,8 @@ nv50_display_flip_next(struct drm_crtc *
 	evo_mthd(push, 0x0080, 1);
 	evo_data(push, 0x00000000);
 	evo_kick(push, sync);
+
+	nouveau_bo_ref(nv_fb->nvbo, &head->image);
 	return 0;
 }
 
@@ -1038,18 +1042,17 @@ static int
 nv50_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb)
 {
 	struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb);
+	struct nv50_head *head = nv50_head(crtc);
 	int ret;
 
 	ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM);
-	if (ret)
-		return ret;
-
-	if (old_fb) {
-		nvfb = nouveau_framebuffer(old_fb);
-		nouveau_bo_unpin(nvfb->nvbo);
+	if (ret == 0) {
+		if (head->image)
+			nouveau_bo_unpin(head->image);
+		nouveau_bo_ref(nvfb->nvbo, &head->image);
 	}
 
-	return 0;
+	return ret;
 }
 
 static int
@@ -1198,6 +1201,15 @@ nv50_crtc_lut_load(struct drm_crtc *crtc
 	}
 }
 
+static void
+nv50_crtc_disable(struct drm_crtc *crtc)
+{
+	struct nv50_head *head = nv50_head(crtc);
+	if (head->image)
+		nouveau_bo_unpin(head->image);
+	nouveau_bo_ref(NULL, &head->image);
+}
+
 static int
 nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
 		     uint32_t handle, uint32_t width, uint32_t height)
@@ -1271,18 +1283,29 @@ nv50_crtc_destroy(struct drm_crtc *crtc)
 	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 	struct nv50_disp *disp = nv50_disp(crtc->dev);
 	struct nv50_head *head = nv50_head(crtc);
+
 	nv50_dmac_destroy(disp->core, &head->ovly.base);
 	nv50_pioc_destroy(disp->core, &head->oimm.base);
 	nv50_dmac_destroy(disp->core, &head->sync.base);
 	nv50_pioc_destroy(disp->core, &head->curs.base);
+
+	/*XXX: this shouldn't be necessary, but the core doesn't call
+	 *     disconnect() during the cleanup paths
+	 */
+	if (head->image)
+		nouveau_bo_unpin(head->image);
+	nouveau_bo_ref(NULL, &head->image);
+
 	nouveau_bo_unmap(nv_crtc->cursor.nvbo);
 	if (nv_crtc->cursor.nvbo)
 		nouveau_bo_unpin(nv_crtc->cursor.nvbo);
 	nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+
 	nouveau_bo_unmap(nv_crtc->lut.nvbo);
 	if (nv_crtc->lut.nvbo)
 		nouveau_bo_unpin(nv_crtc->lut.nvbo);
 	nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
+
 	drm_crtc_cleanup(crtc);
 	kfree(crtc);
 }
@@ -1296,6 +1319,7 @@ static const struct drm_crtc_helper_func
 	.mode_set_base = nv50_crtc_mode_set_base,
 	.mode_set_base_atomic = nv50_crtc_mode_set_base_atomic,
 	.load_lut = nv50_crtc_lut_load,
+	.disable = nv50_crtc_disable,
 };
 
 static const struct drm_crtc_funcs nv50_crtc_func = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv50_fence.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv50_fence.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv50_fence.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv50_fence.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,8 @@ nv50_fence_context_new(struct nouveau_ch
 	struct nv10_fence_chan *fctx;
 	struct ttm_mem_reg *mem = &priv->bo->bo.mem;
 	struct nouveau_object *object;
+	u32 start = mem->start * PAGE_SIZE;
+	u32 limit = start + mem->size - 1;
 	int ret, i;
 
 	fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
@@ -51,26 +53,28 @@ nv50_fence_context_new(struct nouveau_ch
 	fctx->base.sync = nv17_fence_sync;
 
 	ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
-				 NvSema, 0x0002,
+				 NvSema, 0x003d,
 				 &(struct nv_dma_class) {
 					.flags = NV_DMA_TARGET_VRAM |
 						 NV_DMA_ACCESS_RDWR,
-					.start = mem->start * PAGE_SIZE,
-					.limit = mem->size - 1,
+					.start = start,
+					.limit = limit,
 				 }, sizeof(struct nv_dma_class),
 				 &object);
 
 	/* dma objects for display sync channel semaphore blocks */
 	for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) {
 		struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i);
+		u32 start = bo->bo.mem.start * PAGE_SIZE;
+		u32 limit = start + bo->bo.mem.size - 1;
 
 		ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
 					 NvEvoSema0 + i, 0x003d,
 					 &(struct nv_dma_class) {
 						.flags = NV_DMA_TARGET_VRAM |
 							 NV_DMA_ACCESS_RDWR,
-						.start = bo->bo.offset,
-						.limit = bo->bo.offset + 0xfff,
+						.start = start,
+						.limit = limit,
 					 }, sizeof(struct nv_dma_class),
 					 &object);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv50_pm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv50_pm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nv50_pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nv50_pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -493,12 +493,12 @@ mclk_mrs(struct nouveau_mem_exec_func *e
 	struct hwsq_ucode *hwsq = &info->mclk_hwsq;
 
 	if (mr <= 1) {
-		if (pfb->ram.ranks > 1)
+		if (pfb->ram->ranks > 1)
 			hwsq_wr32(hwsq, 0x1002c8 + ((mr - 0) * 4), data);
 		hwsq_wr32(hwsq, 0x1002c0 + ((mr - 0) * 4), data);
 	} else
 	if (mr <= 3) {
-		if (pfb->ram.ranks > 1)
+		if (pfb->ram->ranks > 1)
 			hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data);
 		hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nva3_pm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nva3_pm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nva3_pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nva3_pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -389,12 +389,12 @@ mclk_mrs(struct nouveau_mem_exec_func *e
 	struct nouveau_device *device = nouveau_dev(exec->dev);
 	struct nouveau_fb *pfb = nouveau_fb(device);
 	if (mr <= 1) {
-		if (pfb->ram.ranks > 1)
+		if (pfb->ram->ranks > 1)
 			nv_wr32(device, 0x1002c8 + ((mr - 0) * 4), data);
 		nv_wr32(device, 0x1002c0 + ((mr - 0) * 4), data);
 	} else
 	if (mr <= 3) {
-		if (pfb->ram.ranks > 1)
+		if (pfb->ram->ranks > 1)
 			nv_wr32(device, 0x1002e8 + ((mr - 2) * 4), data);
 		nv_wr32(device, 0x1002e0 + ((mr - 2) * 4), data);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nvc0_pm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nvc0_pm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/nouveau/nvc0_pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/nouveau/nvc0_pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -477,7 +477,7 @@ mclk_mrg(struct nouveau_mem_exec_func *e
 {
 	struct nouveau_device *device = nouveau_dev(exec->dev);
 	struct nouveau_fb *pfb = nouveau_fb(device);
-	if (pfb->ram.type != NV_MEM_TYPE_GDDR5) {
+	if (pfb->ram->type != NV_MEM_TYPE_GDDR5) {
 		if (mr <= 1)
 			return nv_rd32(device, 0x10f300 + ((mr - 0) * 4));
 		return nv_rd32(device, 0x10f320 + ((mr - 2) * 4));
@@ -496,15 +496,15 @@ mclk_mrs(struct nouveau_mem_exec_func *e
 {
 	struct nouveau_device *device = nouveau_dev(exec->dev);
 	struct nouveau_fb *pfb = nouveau_fb(device);
-	if (pfb->ram.type != NV_MEM_TYPE_GDDR5) {
+	if (pfb->ram->type != NV_MEM_TYPE_GDDR5) {
 		if (mr <= 1) {
 			nv_wr32(device, 0x10f300 + ((mr - 0) * 4), data);
-			if (pfb->ram.ranks > 1)
+			if (pfb->ram->ranks > 1)
 				nv_wr32(device, 0x10f308 + ((mr - 0) * 4), data);
 		} else
 		if (mr <= 3) {
 			nv_wr32(device, 0x10f320 + ((mr - 2) * 4), data);
-			if (pfb->ram.ranks > 1)
+			if (pfb->ram->ranks > 1)
 				nv_wr32(device, 0x10f328 + ((mr - 2) * 4), data);
 		}
 	} else {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/Kconfig linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/Kconfig
--- linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 
 config DRM_OMAP
 	tristate "OMAP DRM"
-	depends on DRM && !CONFIG_FB_OMAP2
+	depends on DRM
 	depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
 	depends on OMAP2_DSS
 	select DRM_KMS_HELPER
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_crtc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_crtc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_crtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_crtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,7 +40,7 @@ struct omap_crtc {
 	 * mgr->id.)  Eventually this will be replaced w/ something
 	 * more common-panel-framework-y
 	 */
-	struct omap_overlay_manager mgr;
+	struct omap_overlay_manager *mgr;
 
 	struct omap_video_timings timings;
 	bool enabled;
@@ -90,7 +90,32 @@ uint32_t pipe2vbl(struct drm_crtc *crtc)
  * job of sequencing the setup of the video pipe in the proper order
  */
 
+/* ovl-mgr-id -> crtc */
+static struct omap_crtc *omap_crtcs[8];
+
 /* we can probably ignore these until we support command-mode panels: */
+static int omap_crtc_connect(struct omap_overlay_manager *mgr,
+		struct omap_dss_device *dst)
+{
+	if (mgr->output)
+		return -EINVAL;
+
+	if ((mgr->supported_outputs & dst->id) == 0)
+		return -EINVAL;
+
+	dst->manager = mgr;
+	mgr->output = dst;
+
+	return 0;
+}
+
+static void omap_crtc_disconnect(struct omap_overlay_manager *mgr,
+		struct omap_dss_device *dst)
+{
+	mgr->output->manager = NULL;
+	mgr->output = NULL;
+}
+
 static void omap_crtc_start_update(struct omap_overlay_manager *mgr)
 {
 }
@@ -107,7 +132,7 @@ static void omap_crtc_disable(struct oma
 static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
 		const struct omap_video_timings *timings)
 {
-	struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr);
+	struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
 	DBG("%s", omap_crtc->name);
 	omap_crtc->timings = *timings;
 	omap_crtc->full_update = true;
@@ -116,7 +141,7 @@ static void omap_crtc_set_timings(struct
 static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr,
 		const struct dss_lcd_mgr_config *config)
 {
-	struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr);
+	struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
 	DBG("%s", omap_crtc->name);
 	dispc_mgr_set_lcd_config(omap_crtc->channel, config);
 }
@@ -135,6 +160,8 @@ static void omap_crtc_unregister_framedo
 }
 
 static const struct dss_mgr_ops mgr_ops = {
+		.connect = omap_crtc_connect,
+		.disconnect = omap_crtc_disconnect,
 		.start_update = omap_crtc_start_update,
 		.enable = omap_crtc_enable,
 		.disable = omap_crtc_disable,
@@ -253,10 +280,6 @@ static int omap_crtc_mode_set_base(struc
 			NULL, NULL);
 }
 
-static void omap_crtc_load_lut(struct drm_crtc *crtc)
-{
-}
-
 static void vblank_cb(void *arg)
 {
 	struct drm_crtc *crtc = arg;
@@ -366,7 +389,6 @@ static const struct drm_crtc_helper_func
 	.prepare = omap_crtc_prepare,
 	.commit = omap_crtc_commit,
 	.mode_set_base = omap_crtc_mode_set_base,
-	.load_lut = omap_crtc_load_lut,
 };
 
 const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc)
@@ -569,7 +591,7 @@ static void omap_crtc_pre_apply(struct o
 	} else {
 		if (encoder) {
 			omap_encoder_set_enabled(encoder, false);
-			omap_encoder_update(encoder, &omap_crtc->mgr,
+			omap_encoder_update(encoder, omap_crtc->mgr,
 					&omap_crtc->timings);
 			omap_encoder_set_enabled(encoder, true);
 			omap_crtc->full_update = false;
@@ -595,6 +617,11 @@ static const char *channel_names[] = {
 		[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
 };
 
+void omap_crtc_pre_init(void)
+{
+	dss_install_mgr_ops(&mgr_ops);
+}
+
 /* initialize crtc */
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 		struct drm_plane *plane, enum omap_channel channel, int id)
@@ -635,9 +662,7 @@ struct drm_crtc *omap_crtc_init(struct d
 	omap_irq_register(dev, &omap_crtc->error_irq);
 
 	/* temporary: */
-	omap_crtc->mgr.id = channel;
-
-	dss_install_mgr_ops(&mgr_ops);
+	omap_crtc->mgr = omap_dss_get_overlay_manager(channel);
 
 	/* TODO: fix hard-coded setup.. add properties! */
 	info = &omap_crtc->info;
@@ -651,6 +676,8 @@ struct drm_crtc *omap_crtc_init(struct d
 
 	omap_plane_install_properties(omap_crtc->plane, &crtc->base);
 
+	omap_crtcs[channel] = omap_crtc;
+
 	return crtc;
 
 fail:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -65,10 +65,8 @@ static int get_connector_type(struct oma
 	switch (dssdev->type) {
 	case OMAP_DISPLAY_TYPE_HDMI:
 		return DRM_MODE_CONNECTOR_HDMIA;
-	case OMAP_DISPLAY_TYPE_DPI:
-		if (!strcmp(dssdev->name, "dvi"))
-			return DRM_MODE_CONNECTOR_DVID;
-		/* fallthrough */
+	case OMAP_DISPLAY_TYPE_DVI:
+		return DRM_MODE_CONNECTOR_DVID;
 	default:
 		return DRM_MODE_CONNECTOR_Unknown;
 	}
@@ -97,6 +95,9 @@ static int omap_modeset_init(struct drm_
 	int num_mgrs = dss_feat_get_num_mgrs();
 	int num_crtcs;
 	int i, id = 0;
+	int r;
+
+	omap_crtc_pre_init();
 
 	drm_mode_config_init(dev);
 
@@ -116,6 +117,7 @@ static int omap_modeset_init(struct drm_
 		struct drm_connector *connector;
 		struct drm_encoder *encoder;
 		enum omap_channel channel;
+		struct omap_overlay_manager *mgr;
 
 		if (!dssdev->driver) {
 			dev_warn(dev->dev, "%s has no driver.. skipping it\n",
@@ -131,6 +133,13 @@ static int omap_modeset_init(struct drm_
 			continue;
 		}
 
+		r = dssdev->driver->connect(dssdev);
+		if (r) {
+			dev_err(dev->dev, "could not connect display: %s\n",
+					dssdev->name);
+			continue;
+		}
+
 		encoder = omap_encoder_init(dev, dssdev);
 
 		if (!encoder) {
@@ -172,8 +181,9 @@ static int omap_modeset_init(struct drm_
 		 * other possible channels to which the encoder can connect are
 		 * not considered.
 		 */
-		channel = dssdev->output->dispc_channel;
 
+		mgr = omapdss_find_mgr_from_display(dssdev);
+		channel = mgr->id;
 		/*
 		 * if this channel hasn't already been taken by a previously
 		 * allocated crtc, we create a new crtc for it
@@ -247,6 +257,9 @@ static int omap_modeset_init(struct drm_
 		struct drm_encoder *encoder = priv->encoders[i];
 		struct omap_dss_device *dssdev =
 					omap_encoder_get_dssdev(encoder);
+		struct omap_dss_device *output;
+
+		output = omapdss_find_output_from_display(dssdev);
 
 		/* figure out which crtc's we can connect the encoder to: */
 		encoder->possible_crtcs = 0;
@@ -259,9 +272,11 @@ static int omap_modeset_init(struct drm_
 			supported_outputs =
 				dss_feat_get_supported_outputs(crtc_channel);
 
-			if (supported_outputs & dssdev->output->id)
+			if (supported_outputs & output->id)
 				encoder->possible_crtcs |= (1 << id);
 		}
+
+		omap_dss_put_device(output);
 	}
 
 	DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -157,6 +157,7 @@ const struct omap_video_timings *omap_cr
 enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
 int omap_crtc_apply(struct drm_crtc *crtc,
 		struct omap_drm_apply *apply);
+void omap_crtc_pre_init(void);
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 		struct drm_plane *plane, enum omap_channel channel, int id);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_fbdev.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_fbdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_fbdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -281,21 +281,7 @@ fail:
 	return ret;
 }
 
-static void omap_crtc_fb_gamma_set(struct drm_crtc *crtc,
-		u16 red, u16 green, u16 blue, int regno)
-{
-	DBG("fbdev: set gamma");
-}
-
-static void omap_crtc_fb_gamma_get(struct drm_crtc *crtc,
-		u16 *red, u16 *green, u16 *blue, int regno)
-{
-	DBG("fbdev: get gamma");
-}
-
 static struct drm_fb_helper_funcs omap_fb_helper_funcs = {
-	.gamma_set = omap_crtc_fb_gamma_set,
-	.gamma_get = omap_crtc_fb_gamma_get,
 	.fb_probe = omap_fbdev_create,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c	2013-08-25 20:43:22.000000000 -0400
@@ -136,44 +136,21 @@ static void omap_gem_dmabuf_kunmap(struc
 	kunmap(pages[page_num]);
 }
 
-/*
- * TODO maybe we can split up drm_gem_mmap to avoid duplicating
- * some here.. or at least have a drm_dmabuf_mmap helper.
- */
 static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
 		struct vm_area_struct *vma)
 {
 	struct drm_gem_object *obj = buffer->priv;
+	struct drm_device *dev = obj->dev;
 	int ret = 0;
 
 	if (WARN_ON(!obj->filp))
 		return -EINVAL;
 
-	/* Check for valid size. */
-	if (omap_gem_mmap_size(obj) < vma->vm_end - vma->vm_start) {
-		ret = -EINVAL;
-		goto out_unlock;
-	}
-
-	if (!obj->dev->driver->gem_vm_ops) {
-		ret = -EINVAL;
-		goto out_unlock;
-	}
-
-	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
-	vma->vm_ops = obj->dev->driver->gem_vm_ops;
-	vma->vm_private_data = obj;
-	vma->vm_page_prot =  pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
-
-	/* Take a ref for this mapping of the object, so that the fault
-	 * handler can dereference the mmap offset's pointer to the object.
-	 * This reference is cleaned up by the corresponding vm_close
-	 * (which should happen whether the vma was created by this call, or
-	 * by a vm_open due to mremap or partial unmap or whatever).
-	 */
-	vma->vm_ops->open(vma);
-
-out_unlock:
+	mutex_lock(&dev->struct_mutex);
+	ret = drm_gem_mmap_obj(obj, omap_gem_mmap_size(obj), vma);
+	mutex_unlock(&dev->struct_mutex);
+	if (ret < 0)
+		return ret;
 
 	return omap_gem_mmap_obj(obj, vma);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_cmd.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_cmd.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_cmd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_cmd.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,6 +49,11 @@ void qxl_ring_free(struct qxl_ring *ring
 	kfree(ring);
 }
 
+void qxl_ring_init_hdr(struct qxl_ring *ring)
+{
+	ring->ring->header.notify_on_prod = ring->n_elements;
+}
+
 struct qxl_ring *
 qxl_ring_create(struct qxl_ring_header *header,
 		int element_size,
@@ -69,7 +74,7 @@ qxl_ring_create(struct qxl_ring_header *
 	ring->prod_notify = prod_notify;
 	ring->push_event = push_event;
 	if (set_prod_notify)
-		header->notify_on_prod = ring->n_elements;
+		qxl_ring_init_hdr(ring);
 	spin_lock_init(&ring->lock);
 	return ring;
 }
@@ -87,7 +92,7 @@ static int qxl_check_header(struct qxl_r
 	return ret;
 }
 
-static int qxl_check_idle(struct qxl_ring *ring)
+int qxl_check_idle(struct qxl_ring *ring)
 {
 	int ret;
 	struct qxl_ring_header *header = &(ring->ring->header);
@@ -174,9 +179,10 @@ qxl_push_command_ring_release(struct qxl
 			      uint32_t type, bool interruptible)
 {
 	struct qxl_command cmd;
+	struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
 
 	cmd.type = type;
-	cmd.data = qxl_bo_physical_address(qdev, release->bos[0], release->release_offset);
+	cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset);
 
 	return qxl_ring_push(qdev->command_ring, &cmd, interruptible);
 }
@@ -186,9 +192,10 @@ qxl_push_cursor_ring_release(struct qxl_
 			     uint32_t type, bool interruptible)
 {
 	struct qxl_command cmd;
+	struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
 
 	cmd.type = type;
-	cmd.data = qxl_bo_physical_address(qdev, release->bos[0], release->release_offset);
+	cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset);
 
 	return qxl_ring_push(qdev->cursor_ring, &cmd, interruptible);
 }
@@ -209,7 +216,6 @@ int qxl_garbage_collect(struct qxl_devic
 	struct qxl_release *release;
 	uint64_t id, next_id;
 	int i = 0;
-	int ret;
 	union qxl_release_info *info;
 
 	while (qxl_ring_pop(qdev->release_ring, &id)) {
@@ -219,17 +225,10 @@ int qxl_garbage_collect(struct qxl_devic
 			if (release == NULL)
 				break;
 
-			ret = qxl_release_reserve(qdev, release, false);
-			if (ret) {
-				qxl_io_log(qdev, "failed to reserve release on garbage collect %lld\n", id);
-				DRM_ERROR("failed to reserve release %lld\n", id);
-			}
-
 			info = qxl_release_map(qdev, release);
 			next_id = info->next;
 			qxl_release_unmap(qdev, release, info);
 
-			qxl_release_unreserve(qdev, release);
 			QXL_INFO(qdev, "popped %lld, next %lld\n", id,
 				next_id);
 
@@ -254,27 +253,29 @@ int qxl_garbage_collect(struct qxl_devic
 	return i;
 }
 
-int qxl_alloc_bo_reserved(struct qxl_device *qdev, unsigned long size,
+int qxl_alloc_bo_reserved(struct qxl_device *qdev,
+			  struct qxl_release *release,
+			  unsigned long size,
 			  struct qxl_bo **_bo)
 {
 	struct qxl_bo *bo;
 	int ret;
 
 	ret = qxl_bo_create(qdev, size, false /* not kernel - device */,
-			    QXL_GEM_DOMAIN_VRAM, NULL, &bo);
+			    false, QXL_GEM_DOMAIN_VRAM, NULL, &bo);
 	if (ret) {
 		DRM_ERROR("failed to allocate VRAM BO\n");
 		return ret;
 	}
-	ret = qxl_bo_reserve(bo, false);
-	if (unlikely(ret != 0))
+	ret = qxl_release_list_add(release, bo);
+	if (ret)
 		goto out_unref;
 
 	*_bo = bo;
 	return 0;
 out_unref:
 	qxl_bo_unref(&bo);
-	return 0;
+	return ret;
 }
 
 static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port, bool intr)
@@ -375,8 +376,8 @@ void qxl_io_destroy_primary(struct qxl_d
 	wait_for_io_cmd(qdev, 0, QXL_IO_DESTROY_PRIMARY_ASYNC);
 }
 
-void qxl_io_create_primary(struct qxl_device *qdev, unsigned width,
-			   unsigned height, unsigned offset, struct qxl_bo *bo)
+void qxl_io_create_primary(struct qxl_device *qdev,
+			   unsigned offset, struct qxl_bo *bo)
 {
 	struct qxl_surface_create *create;
 
@@ -384,8 +385,8 @@ void qxl_io_create_primary(struct qxl_de
 		 qdev->ram_header);
 	create = &qdev->ram_header->create_surface;
 	create->format = bo->surf.format;
-	create->width = width;
-	create->height = height;
+	create->width = bo->surf.width;
+	create->height = bo->surf.height;
 	create->stride = bo->surf.stride;
 	create->mem = qxl_bo_physical_address(qdev, bo, offset);
 
@@ -498,6 +499,10 @@ int qxl_hw_surface_alloc(struct qxl_devi
 	if (ret)
 		return ret;
 
+	ret = qxl_release_reserve_list(release, true);
+	if (ret)
+		return ret;
+
 	cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release);
 	cmd->type = QXL_SURFACE_CMD_CREATE;
 	cmd->u.surface_create.format = surf->surf.format;
@@ -519,14 +524,11 @@ int qxl_hw_surface_alloc(struct qxl_devi
 
 	surf->surf_create = release;
 
-	/* no need to add a release to the fence for this bo,
+	/* no need to add a release to the fence for this surface bo,
 	   since it is only released when we ask to destroy the surface
 	   and it would never signal otherwise */
-	qxl_fence_releaseable(qdev, release);
-
 	qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
-
-	qxl_release_unreserve(qdev, release);
+	qxl_release_fence_buffer_objects(release);
 
 	surf->hw_surf_alloc = true;
 	spin_lock(&qdev->surf_id_idr_lock);
@@ -568,12 +570,9 @@ int qxl_hw_surface_dealloc(struct qxl_de
 	cmd->surface_id = id;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
-	qxl_fence_releaseable(qdev, release);
-
 	qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
 
-	qxl_release_unreserve(qdev, release);
-
+	qxl_release_fence_buffer_objects(release);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_display.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_display.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_display.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_display.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,53 +30,9 @@
 #include "qxl_object.h"
 #include "drm_crtc_helper.h"
 
-static void qxl_crtc_set_to_mode(struct qxl_device *qdev,
-				 struct drm_connector *connector,
-				 struct qxl_head *head)
-{
-	struct drm_device *dev = connector->dev;
-	struct drm_display_mode *mode, *t;
-	int width = head->width;
-	int height = head->height;
-
-	if (width < 320 || height < 240) {
-		qxl_io_log(qdev, "%s: bad head: %dx%d", width, height);
-		width = 1024;
-		height = 768;
-	}
-	if (width * height * 4 > 16*1024*1024) {
-		width = 1024;
-		height = 768;
-	}
-	/* TODO: go over regular modes and removed preferred? */
-	list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
-		drm_mode_remove(connector, mode);
-	mode = drm_cvt_mode(dev, width, height, 60, false, false, false);
-	mode->type |= DRM_MODE_TYPE_PREFERRED;
-	mode->status = MODE_OK;
-	drm_mode_probed_add(connector, mode);
-	qxl_io_log(qdev, "%s: %d x %d\n", __func__, width, height);
-}
-
-void qxl_crtc_set_from_monitors_config(struct qxl_device *qdev)
+static bool qxl_head_enabled(struct qxl_head *head)
 {
-	struct drm_connector *connector;
-	int i;
-	struct drm_device *dev = qdev->ddev;
-
-	i = 0;
-	qxl_io_log(qdev, "%s: %d, %d\n", __func__,
-		   dev->mode_config.num_connector,
-		   qdev->monitors_config->count);
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (i > qdev->monitors_config->count) {
-			/* crtc will be reported as disabled */
-			continue;
-		}
-		qxl_crtc_set_to_mode(qdev, connector,
-				     &qdev->monitors_config->heads[i]);
-		++i;
-	}
+	return head->width && head->height;
 }
 
 void qxl_alloc_client_monitors_config(struct qxl_device *qdev, unsigned count)
@@ -106,7 +62,6 @@ static int qxl_display_copy_rom_client_m
 	int num_monitors;
 	uint32_t crc;
 
-	BUG_ON(!qdev->monitors_config);
 	num_monitors = qdev->rom->client_monitors_config.count;
 	crc = crc32(0, (const uint8_t *)&qdev->rom->client_monitors_config,
 		  sizeof(qdev->rom->client_monitors_config));
@@ -117,8 +72,8 @@ static int qxl_display_copy_rom_client_m
 		return 1;
 	}
 	if (num_monitors > qdev->monitors_config->max_allowed) {
-		DRM_INFO("client monitors list will be truncated: %d < %d\n",
-			 qdev->monitors_config->max_allowed, num_monitors);
+		DRM_DEBUG_KMS("client monitors list will be truncated: %d < %d\n",
+			      qdev->monitors_config->max_allowed, num_monitors);
 		num_monitors = qdev->monitors_config->max_allowed;
 	} else {
 		num_monitors = qdev->rom->client_monitors_config.count;
@@ -132,18 +87,15 @@ static int qxl_display_copy_rom_client_m
 			&qdev->rom->client_monitors_config.heads[i];
 		struct qxl_head *client_head =
 			&qdev->client_monitors_config->heads[i];
-		struct qxl_head *head = &qdev->monitors_config->heads[i];
-		client_head->x = head->x = c_rect->left;
-		client_head->y = head->y = c_rect->top;
-		client_head->width = head->width =
-						c_rect->right - c_rect->left;
-		client_head->height = head->height =
-						c_rect->bottom - c_rect->top;
-		client_head->surface_id = head->surface_id = 0;
-		client_head->id = head->id = i;
-		client_head->flags = head->flags = 0;
-		QXL_DEBUG(qdev, "read %dx%d+%d+%d\n", head->width, head->height,
-			  head->x, head->y);
+		client_head->x = c_rect->left;
+		client_head->y = c_rect->top;
+		client_head->width = c_rect->right - c_rect->left;
+		client_head->height = c_rect->bottom - c_rect->top;
+		client_head->surface_id = 0;
+		client_head->id = i;
+		client_head->flags = 0;
+		DRM_DEBUG_KMS("read %dx%d+%d+%d\n", client_head->width, client_head->height,
+			  client_head->x, client_head->y);
 	}
 	return 0;
 }
@@ -155,10 +107,7 @@ void qxl_display_read_client_monitors_co
 		qxl_io_log(qdev, "failed crc check for client_monitors_config,"
 				 " retrying\n");
 	}
-	qxl_crtc_set_from_monitors_config(qdev);
-	/* fire off a uevent and let userspace tell us what to do */
-	qxl_io_log(qdev, "calling drm_sysfs_hotplug_event\n");
-	drm_sysfs_hotplug_event(qdev->ddev);
+	drm_helper_hpd_irq_event(qdev->ddev);
 }
 
 static int qxl_add_monitors_config_modes(struct drm_connector *connector)
@@ -170,9 +119,9 @@ static int qxl_add_monitors_config_modes
 	struct drm_display_mode *mode = NULL;
 	struct qxl_head *head;
 
-	if (!qdev->monitors_config)
+	if (!qdev->client_monitors_config)
 		return 0;
-	head = &qdev->monitors_config->heads[h];
+	head = &qdev->client_monitors_config->heads[h];
 
 	mode = drm_cvt_mode(dev, head->width, head->height, 60, false, false,
 			    false);
@@ -222,12 +171,6 @@ static int qxl_add_common_modes(struct d
 	return i - 1;
 }
 
-static void qxl_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
-			       u16 *blue, uint32_t start, uint32_t size)
-{
-	/* TODO */
-}
-
 static void qxl_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct qxl_crtc *qxl_crtc = to_qxl_crtc(crtc);
@@ -236,7 +179,7 @@ static void qxl_crtc_destroy(struct drm_
 	kfree(qxl_crtc);
 }
 
-static void
+static int
 qxl_hide_cursor(struct qxl_device *qdev)
 {
 	struct qxl_release *release;
@@ -245,21 +188,29 @@ qxl_hide_cursor(struct qxl_device *qdev)
 
 	ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), QXL_RELEASE_CURSOR_CMD,
 					 &release, NULL);
+	if (ret)
+		return ret;
+
+	ret = qxl_release_reserve_list(release, true);
+	if (ret) {
+		qxl_release_free(qdev, release);
+		return ret;
+	}
 
 	cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
 	cmd->type = QXL_CURSOR_HIDE;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
-	qxl_fence_releaseable(qdev, release);
 	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
-	qxl_release_unreserve(qdev, release);
+	qxl_release_fence_buffer_objects(release);
+	return 0;
 }
 
-static int qxl_crtc_cursor_set(struct drm_crtc *crtc,
-			       struct drm_file *file_priv,
-			       uint32_t handle,
-			       uint32_t width,
-			       uint32_t height)
+static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
+				struct drm_file *file_priv,
+				uint32_t handle,
+				uint32_t width,
+				uint32_t height, int32_t hot_x, int32_t hot_y)
 {
 	struct drm_device *dev = crtc->dev;
 	struct qxl_device *qdev = dev->dev_private;
@@ -273,10 +224,8 @@ static int qxl_crtc_cursor_set(struct dr
 
 	int size = 64*64*4;
 	int ret = 0;
-	if (!handle) {
-		qxl_hide_cursor(qdev);
-		return 0;
-	}
+	if (!handle)
+		return qxl_hide_cursor(qdev);
 
 	obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
 	if (!obj) {
@@ -291,8 +240,9 @@ static int qxl_crtc_cursor_set(struct dr
 		goto out_unref;
 
 	ret = qxl_bo_pin(user_bo, QXL_GEM_DOMAIN_CPU, NULL);
+	qxl_bo_unreserve(user_bo);
 	if (ret)
-		goto out_unreserve;
+		goto out_unref;
 
 	ret = qxl_bo_kmap(user_bo, &user_ptr);
 	if (ret)
@@ -303,20 +253,26 @@ static int qxl_crtc_cursor_set(struct dr
 					 &release, NULL);
 	if (ret)
 		goto out_kunmap;
-	ret = qxl_alloc_bo_reserved(qdev, sizeof(struct qxl_cursor) + size,
-				    &cursor_bo);
+
+	ret = qxl_alloc_bo_reserved(qdev, release, sizeof(struct qxl_cursor) + size,
+			   &cursor_bo);
 	if (ret)
 		goto out_free_release;
-	ret = qxl_bo_kmap(cursor_bo, (void **)&cursor);
+
+	ret = qxl_release_reserve_list(release, false);
 	if (ret)
 		goto out_free_bo;
 
+	ret = qxl_bo_kmap(cursor_bo, (void **)&cursor);
+	if (ret)
+		goto out_backoff;
+
 	cursor->header.unique = 0;
 	cursor->header.type = SPICE_CURSOR_TYPE_ALPHA;
 	cursor->header.width = 64;
 	cursor->header.height = 64;
-	cursor->header.hot_spot_x = 0;
-	cursor->header.hot_spot_y = 0;
+	cursor->header.hot_spot_x = hot_x;
+	cursor->header.hot_spot_y = hot_y;
 	cursor->data_size = size;
 	cursor->chunk.next_chunk = 0;
 	cursor->chunk.prev_chunk = 0;
@@ -326,11 +282,7 @@ static int qxl_crtc_cursor_set(struct dr
 
 	qxl_bo_kunmap(cursor_bo);
 
-	/* finish with the userspace bo */
 	qxl_bo_kunmap(user_bo);
-	qxl_bo_unpin(user_bo);
-	qxl_bo_unreserve(user_bo);
-	drm_gem_object_unreference_unlocked(obj);
 
 	cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
 	cmd->type = QXL_CURSOR_SET;
@@ -338,30 +290,35 @@ static int qxl_crtc_cursor_set(struct dr
 	cmd->u.set.position.y = qcrtc->cur_y;
 
 	cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0);
-	qxl_release_add_res(qdev, release, cursor_bo);
 
 	cmd->u.set.visible = 1;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
-	qxl_fence_releaseable(qdev, release);
 	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
-	qxl_release_unreserve(qdev, release);
+	qxl_release_fence_buffer_objects(release);
+
+	/* finish with the userspace bo */
+	ret = qxl_bo_reserve(user_bo, false);
+	if (!ret) {
+		qxl_bo_unpin(user_bo);
+		qxl_bo_unreserve(user_bo);
+	}
+	drm_gem_object_unreference_unlocked(obj);
 
-	qxl_bo_unreserve(cursor_bo);
 	qxl_bo_unref(&cursor_bo);
 
 	return ret;
+
+out_backoff:
+	qxl_release_backoff_reserve_list(release);
 out_free_bo:
 	qxl_bo_unref(&cursor_bo);
 out_free_release:
-	qxl_release_unreserve(qdev, release);
 	qxl_release_free(qdev, release);
 out_kunmap:
 	qxl_bo_kunmap(user_bo);
 out_unpin:
 	qxl_bo_unpin(user_bo);
-out_unreserve:
-	qxl_bo_unreserve(user_bo);
 out_unref:
 	drm_gem_object_unreference_unlocked(obj);
 	return ret;
@@ -379,6 +336,14 @@ static int qxl_crtc_cursor_move(struct d
 
 	ret = qxl_alloc_release_reserved(qdev, sizeof(*cmd), QXL_RELEASE_CURSOR_CMD,
 				   &release, NULL);
+	if (ret)
+		return ret;
+
+	ret = qxl_release_reserve_list(release, true);
+	if (ret) {
+		qxl_release_free(qdev, release);
+		return ret;
+	}
 
 	qcrtc->cur_x = x;
 	qcrtc->cur_y = y;
@@ -389,17 +354,16 @@ static int qxl_crtc_cursor_move(struct d
 	cmd->u.position.y = qcrtc->cur_y;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
-	qxl_fence_releaseable(qdev, release);
 	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
-	qxl_release_unreserve(qdev, release);
+	qxl_release_fence_buffer_objects(release);
+
 	return 0;
 }
 
 
 static const struct drm_crtc_funcs qxl_crtc_funcs = {
-	.cursor_set = qxl_crtc_cursor_set,
+	.cursor_set2 = qxl_crtc_cursor_set2,
 	.cursor_move = qxl_crtc_cursor_move,
-	.gamma_set = qxl_crtc_gamma_set,
 	.set_config = drm_crtc_helper_set_config,
 	.destroy = qxl_crtc_destroy,
 };
@@ -506,7 +470,7 @@ qxl_send_monitors_config(struct qxl_devi
 	for (i = 0 ; i < qdev->monitors_config->count ; ++i) {
 		struct qxl_head *head = &qdev->monitors_config->heads[i];
 
-		if (head->y > 8192 || head->y < head->x ||
+		if (head->y > 8192 || head->x > 8192 ||
 		    head->width > 8192 || head->height > 8192) {
 			DRM_ERROR("head %d wrong: %dx%d+%d+%d\n",
 				  i, head->width, head->height,
@@ -517,16 +481,19 @@ qxl_send_monitors_config(struct qxl_devi
 	qxl_io_monitors_config(qdev);
 }
 
-static void qxl_monitors_config_set_single(struct qxl_device *qdev,
-					   unsigned x, unsigned y,
-					   unsigned width, unsigned height)
+static void qxl_monitors_config_set(struct qxl_device *qdev,
+				    int index,
+				    unsigned x, unsigned y,
+				    unsigned width, unsigned height,
+				    unsigned surf_id)
 {
-	DRM_DEBUG("%dx%d+%d+%d\n", width, height, x, y);
-	qdev->monitors_config->count = 1;
-	qdev->monitors_config->heads[0].x = x;
-	qdev->monitors_config->heads[0].y = y;
-	qdev->monitors_config->heads[0].width = width;
-	qdev->monitors_config->heads[0].height = height;
+	DRM_DEBUG_KMS("%d:%dx%d+%d+%d\n", index, width, height, x, y);
+	qdev->monitors_config->heads[index].x = x;
+	qdev->monitors_config->heads[index].y = y;
+	qdev->monitors_config->heads[index].width = width;
+	qdev->monitors_config->heads[index].height = height;
+	qdev->monitors_config->heads[index].surface_id = surf_id;
+
 }
 
 static int qxl_crtc_mode_set(struct drm_crtc *crtc,
@@ -540,10 +507,11 @@ static int qxl_crtc_mode_set(struct drm_
 	struct qxl_mode *m = (void *)mode->private;
 	struct qxl_framebuffer *qfb;
 	struct qxl_bo *bo, *old_bo = NULL;
+	struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
 	uint32_t width, height, base_offset;
 	bool recreate_primary = false;
 	int ret;
-
+	int surf_id;
 	if (!crtc->fb) {
 		DRM_DEBUG_KMS("No FB bound\n");
 		return 0;
@@ -567,7 +535,8 @@ static int qxl_crtc_mode_set(struct drm_
 		  adjusted_mode->hdisplay,
 		  adjusted_mode->vdisplay);
 
-	recreate_primary = true;
+	if (qcrtc->index == 0)
+		recreate_primary = true;
 
 	width = mode->hdisplay;
 	height = mode->vdisplay;
@@ -588,8 +557,11 @@ static int qxl_crtc_mode_set(struct drm_
 			   "recreate primary: %dx%d (was %dx%d,%d,%d)\n",
 			   width, height, bo->surf.width,
 			   bo->surf.height, bo->surf.stride, bo->surf.format);
-		qxl_io_create_primary(qdev, width, height, base_offset, bo);
+		qxl_io_create_primary(qdev, base_offset, bo);
 		bo->is_primary = true;
+		surf_id = 0;
+	} else {
+		surf_id = bo->surface_id;
 	}
 
 	if (old_bo && old_bo != bo) {
@@ -599,11 +571,9 @@ static int qxl_crtc_mode_set(struct drm_
 		qxl_bo_unreserve(old_bo);
 	}
 
-	if (qdev->monitors_config->count == 0) {
-		qxl_monitors_config_set_single(qdev, x, y,
-					       mode->hdisplay,
-					       mode->vdisplay);
-	}
+	qxl_monitors_config_set(qdev, qcrtc->index, x, y,
+				mode->hdisplay,
+				mode->vdisplay, surf_id);
 	return 0;
 }
 
@@ -619,21 +589,36 @@ static void qxl_crtc_commit(struct drm_c
 	DRM_DEBUG("\n");
 }
 
-static void qxl_crtc_load_lut(struct drm_crtc *crtc)
+static void qxl_crtc_disable(struct drm_crtc *crtc)
 {
-	DRM_DEBUG("\n");
+	struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct qxl_device *qdev = dev->dev_private;
+	if (crtc->fb) {
+		struct qxl_framebuffer *qfb = to_qxl_framebuffer(crtc->fb);
+		struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj);
+		int ret;
+		ret = qxl_bo_reserve(bo, false);
+		qxl_bo_unpin(bo);
+		qxl_bo_unreserve(bo);
+		crtc->fb = NULL;
+	}
+
+	qxl_monitors_config_set(qdev, qcrtc->index, 0, 0, 0, 0, 0);
+
+	qxl_send_monitors_config(qdev);
 }
 
 static const struct drm_crtc_helper_funcs qxl_crtc_helper_funcs = {
 	.dpms = qxl_crtc_dpms,
+	.disable = qxl_crtc_disable,
 	.mode_fixup = qxl_crtc_mode_fixup,
 	.mode_set = qxl_crtc_mode_set,
 	.prepare = qxl_crtc_prepare,
 	.commit = qxl_crtc_commit,
-	.load_lut = qxl_crtc_load_lut,
 };
 
-static int qdev_crtc_init(struct drm_device *dev, int num_crtc)
+static int qdev_crtc_init(struct drm_device *dev, int crtc_id)
 {
 	struct qxl_crtc *qxl_crtc;
 
@@ -642,7 +627,7 @@ static int qdev_crtc_init(struct drm_dev
 		return -ENOMEM;
 
 	drm_crtc_init(dev, &qxl_crtc->base, &qxl_crtc_funcs);
-
+	qxl_crtc->index = crtc_id;
 	drm_mode_crtc_set_gamma_size(&qxl_crtc->base, 256);
 	drm_crtc_helper_add(&qxl_crtc->base, &qxl_crtc_helper_funcs);
 	return 0;
@@ -670,18 +655,13 @@ static void qxl_write_monitors_config_fo
 		struct drm_encoder *encoder)
 {
 	int i;
+	struct qxl_output *output = drm_encoder_to_qxl_output(encoder);
 	struct qxl_head *head;
 	struct drm_display_mode *mode;
 
 	BUG_ON(!encoder);
 	/* TODO: ugly, do better */
-	for (i = 0 ; (encoder->possible_crtcs != (1 << i)) && i < 32; ++i)
-		;
-	if (encoder->possible_crtcs != (1 << i)) {
-		DRM_ERROR("encoder has wrong possible_crtcs: %x\n",
-			  encoder->possible_crtcs);
-		return;
-	}
+	i = output->index;
 	if (!qdev->monitors_config ||
 	    qdev->monitors_config->max_allowed <= i) {
 		DRM_ERROR(
@@ -699,7 +679,6 @@ static void qxl_write_monitors_config_fo
 		DRM_DEBUG("missing for multiple monitors: no head holes\n");
 	head = &qdev->monitors_config->heads[i];
 	head->id = i;
-	head->surface_id = 0;
 	if (encoder->crtc->enabled) {
 		mode = &encoder->crtc->mode;
 		head->width = mode->hdisplay;
@@ -714,8 +693,8 @@ static void qxl_write_monitors_config_fo
 		head->x = 0;
 		head->y = 0;
 	}
-	DRM_DEBUG("setting head %d to +%d+%d %dx%d\n",
-		  i, head->x, head->y, head->width, head->height);
+	DRM_DEBUG_KMS("setting head %d to +%d+%d %dx%d out of %d\n",
+		      i, head->x, head->y, head->width, head->height, qdev->monitors_config->count);
 	head->flags = 0;
 	/* TODO - somewhere else to call this for multiple monitors
 	 * (config_commit?) */
@@ -810,8 +789,9 @@ static enum drm_connector_status qxl_con
 
 	/* The first monitor is always connected */
 	connected = (output->index == 0) ||
-		    (qdev->monitors_config &&
-		     qdev->monitors_config->count > output->index);
+		    (qdev->client_monitors_config &&
+		     qdev->client_monitors_config->count > output->index &&
+		     qxl_head_enabled(&qdev->client_monitors_config->heads[output->index]));
 
 	DRM_DEBUG("\n");
 	return connected ? connector_status_connected
@@ -875,6 +855,8 @@ static int qdev_output_init(struct drm_d
 	drm_encoder_init(dev, &qxl_output->enc, &qxl_enc_funcs,
 			 DRM_MODE_ENCODER_VIRTUAL);
 
+	/* we get HPD via client monitors config */
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
 	encoder->possible_crtcs = 1 << num_output;
 	drm_mode_connector_attach_encoder(&qxl_output->base,
 					  &qxl_output->enc);
@@ -914,16 +896,14 @@ static const struct drm_mode_config_func
 	.fb_create = qxl_user_framebuffer_create,
 };
 
-int qxl_modeset_init(struct qxl_device *qdev)
+int qxl_create_monitors_object(struct qxl_device *qdev)
 {
-	int i;
 	int ret;
 	struct drm_gem_object *gobj;
-	int max_allowed = QXL_NUM_OUTPUTS;
+	int max_allowed = qxl_num_crtc;
 	int monitors_config_size = sizeof(struct qxl_monitors_config) +
-				   max_allowed * sizeof(struct qxl_head);
+		max_allowed * sizeof(struct qxl_head);
 
-	drm_mode_config_init(qdev->ddev);
 	ret = qxl_gem_object_create(qdev, monitors_config_size, 0,
 				    QXL_GEM_DOMAIN_VRAM,
 				    false, false, NULL, &gobj);
@@ -932,13 +912,59 @@ int qxl_modeset_init(struct qxl_device *
 		return -ENOMEM;
 	}
 	qdev->monitors_config_bo = gem_to_qxl_bo(gobj);
+
+	ret = qxl_bo_reserve(qdev->monitors_config_bo, false);
+	if (ret)
+		return ret;
+
+	ret = qxl_bo_pin(qdev->monitors_config_bo, QXL_GEM_DOMAIN_VRAM, NULL);
+	if (ret) {
+		qxl_bo_unreserve(qdev->monitors_config_bo);
+		return ret;
+	}
+
+	qxl_bo_unreserve(qdev->monitors_config_bo);
+
 	qxl_bo_kmap(qdev->monitors_config_bo, NULL);
+
 	qdev->monitors_config = qdev->monitors_config_bo->kptr;
 	qdev->ram_header->monitors_config =
 		qxl_bo_physical_address(qdev, qdev->monitors_config_bo, 0);
 
 	memset(qdev->monitors_config, 0, monitors_config_size);
 	qdev->monitors_config->max_allowed = max_allowed;
+	return 0;
+}
+
+int qxl_destroy_monitors_object(struct qxl_device *qdev)
+{
+	int ret;
+
+	qdev->monitors_config = NULL;
+	qdev->ram_header->monitors_config = 0;
+
+	qxl_bo_kunmap(qdev->monitors_config_bo);
+	ret = qxl_bo_reserve(qdev->monitors_config_bo, false);
+	if (ret)
+		return ret;
+
+	qxl_bo_unpin(qdev->monitors_config_bo);
+	qxl_bo_unreserve(qdev->monitors_config_bo);
+
+	qxl_bo_unref(&qdev->monitors_config_bo);
+	return 0;
+}
+
+int qxl_modeset_init(struct qxl_device *qdev)
+{
+	int i;
+	int ret;
+
+	drm_mode_config_init(qdev->ddev);
+
+	ret = qxl_create_monitors_object(qdev);
+	if (ret)
+		return ret;
 
 	qdev->ddev->mode_config.funcs = (void *)&qxl_mode_funcs;
 
@@ -949,7 +975,7 @@ int qxl_modeset_init(struct qxl_device *
 	qdev->ddev->mode_config.max_height = 8192;
 
 	qdev->ddev->mode_config.fb_base = qdev->vram_base;
-	for (i = 0 ; i < QXL_NUM_OUTPUTS; ++i) {
+	for (i = 0 ; i < qxl_num_crtc; ++i) {
 		qdev_crtc_init(qdev->ddev, i);
 		qdev_output_init(qdev->ddev, i);
 	}
@@ -966,6 +992,8 @@ int qxl_modeset_init(struct qxl_device *
 void qxl_modeset_fini(struct qxl_device *qdev)
 {
 	qxl_fbdev_fini(qdev);
+
+	qxl_destroy_monitors_object(qdev);
 	if (qdev->mode_info.mode_config_initialized) {
 		drm_mode_config_cleanup(qdev->ddev);
 		qdev->mode_info.mode_config_initialized = false;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_draw.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_draw.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_draw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_draw.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,25 +23,29 @@
 #include "qxl_drv.h"
 #include "qxl_object.h"
 
+static int alloc_clips(struct qxl_device *qdev,
+		       struct qxl_release *release,
+		       unsigned num_clips,
+		       struct qxl_bo **clips_bo)
+{
+	int size = sizeof(struct qxl_clip_rects) + sizeof(struct qxl_rect) * num_clips;
+
+	return qxl_alloc_bo_reserved(qdev, release, size, clips_bo);
+}
+
 /* returns a pointer to the already allocated qxl_rect array inside
  * the qxl_clip_rects. This is *not* the same as the memory allocated
  * on the device, it is offset to qxl_clip_rects.chunk.data */
 static struct qxl_rect *drawable_set_clipping(struct qxl_device *qdev,
 					      struct qxl_drawable *drawable,
 					      unsigned num_clips,
-					      struct qxl_bo **clips_bo,
-					      struct qxl_release *release)
+					      struct qxl_bo *clips_bo)
 {
 	struct qxl_clip_rects *dev_clips;
 	int ret;
-	int size = sizeof(*dev_clips) + sizeof(struct qxl_rect) * num_clips;
-	ret = qxl_alloc_bo_reserved(qdev, size, clips_bo);
-	if (ret)
-		return NULL;
 
-	ret = qxl_bo_kmap(*clips_bo, (void **)&dev_clips);
+	ret = qxl_bo_kmap(clips_bo, (void **)&dev_clips);
 	if (ret) {
-		qxl_bo_unref(clips_bo);
 		return NULL;
 	}
 	dev_clips->num_rects = num_clips;
@@ -52,20 +56,34 @@ static struct qxl_rect *drawable_set_cli
 }
 
 static int
+alloc_drawable(struct qxl_device *qdev, struct qxl_release **release)
+{
+	int ret;
+	ret = qxl_alloc_release_reserved(qdev, sizeof(struct qxl_drawable),
+					 QXL_RELEASE_DRAWABLE, release,
+					 NULL);
+	return ret;
+}
+
+static void
+free_drawable(struct qxl_device *qdev, struct qxl_release *release)
+{
+	qxl_release_free(qdev, release);
+}
+
+/* release needs to be reserved at this point */
+static int
 make_drawable(struct qxl_device *qdev, int surface, uint8_t type,
 	      const struct qxl_rect *rect,
-	      struct qxl_release **release)
+	      struct qxl_release *release)
 {
 	struct qxl_drawable *drawable;
-	int i, ret;
+	int i;
 
-	ret = qxl_alloc_release_reserved(qdev, sizeof(*drawable),
-					 QXL_RELEASE_DRAWABLE, release,
-					 NULL);
-	if (ret)
-		return ret;
+	drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
+	if (!drawable)
+		return -ENOMEM;
 
-	drawable = (struct qxl_drawable *)qxl_release_map(qdev, *release);
 	drawable->type = type;
 
 	drawable->surface_id = surface;		/* Only primary for now */
@@ -91,14 +109,23 @@ make_drawable(struct qxl_device *qdev, i
 		drawable->bbox = *rect;
 
 	drawable->mm_time = qdev->rom->mm_clock;
-	qxl_release_unmap(qdev, *release, &drawable->release_info);
+	qxl_release_unmap(qdev, release, &drawable->release_info);
 	return 0;
 }
 
-static int qxl_palette_create_1bit(struct qxl_bo **palette_bo,
+static int alloc_palette_object(struct qxl_device *qdev,
+				struct qxl_release *release,
+				struct qxl_bo **palette_bo)
+{
+	return qxl_alloc_bo_reserved(qdev, release,
+				     sizeof(struct qxl_palette) + sizeof(uint32_t) * 2,
+				     palette_bo);
+}
+
+static int qxl_palette_create_1bit(struct qxl_bo *palette_bo,
+				   struct qxl_release *release,
 				   const struct qxl_fb_image *qxl_fb_image)
 {
-	struct qxl_device *qdev = qxl_fb_image->qdev;
 	const struct fb_image *fb_image = &qxl_fb_image->fb_image;
 	uint32_t visual = qxl_fb_image->visual;
 	const uint32_t *pseudo_palette = qxl_fb_image->pseudo_palette;
@@ -108,12 +135,7 @@ static int qxl_palette_create_1bit(struc
 	static uint64_t unique; /* we make no attempt to actually set this
 				 * correctly globaly, since that would require
 				 * tracking all of our palettes. */
-
-	ret = qxl_alloc_bo_reserved(qdev,
-				    sizeof(struct qxl_palette) + sizeof(uint32_t) * 2,
-				    palette_bo);
-
-	ret = qxl_bo_kmap(*palette_bo, (void **)&pal);
+	ret = qxl_bo_kmap(palette_bo, (void **)&pal);
 	pal->num_ents = 2;
 	pal->unique = unique++;
 	if (visual == FB_VISUAL_TRUECOLOR || visual == FB_VISUAL_DIRECTCOLOR) {
@@ -126,7 +148,7 @@ static int qxl_palette_create_1bit(struc
 	}
 	pal->ents[0] = bgcolor;
 	pal->ents[1] = fgcolor;
-	qxl_bo_kunmap(*palette_bo);
+	qxl_bo_kunmap(palette_bo);
 	return 0;
 }
 
@@ -144,44 +166,63 @@ void qxl_draw_opaque_fb(const struct qxl
 	const char *src = fb_image->data;
 	int depth = fb_image->depth;
 	struct qxl_release *release;
-	struct qxl_bo *image_bo;
 	struct qxl_image *image;
 	int ret;
-
+	struct qxl_drm_image *dimage;
+	struct qxl_bo *palette_bo = NULL;
 	if (stride == 0)
 		stride = depth * width / 8;
 
+	ret = alloc_drawable(qdev, &release);
+	if (ret)
+		return;
+
+	ret = qxl_image_alloc_objects(qdev, release,
+				      &dimage,
+				      height, stride);
+	if (ret)
+		goto out_free_drawable;
+
+	if (depth == 1) {
+		ret = alloc_palette_object(qdev, release, &palette_bo);
+		if (ret)
+			goto out_free_image;
+	}
+
+	/* do a reservation run over all the objects we just allocated */
+	ret = qxl_release_reserve_list(release, true);
+	if (ret)
+		goto out_free_palette;
+
 	rect.left = x;
 	rect.right = x + width;
 	rect.top = y;
 	rect.bottom = y + height;
 
-	ret = make_drawable(qdev, 0, QXL_DRAW_COPY, &rect, &release);
-	if (ret)
-		return;
+	ret = make_drawable(qdev, 0, QXL_DRAW_COPY, &rect, release);
+	if (ret) {
+		qxl_release_backoff_reserve_list(release);
+		goto out_free_palette;
+	}
 
-	ret = qxl_image_create(qdev, release, &image_bo,
-			       (const uint8_t *)src, 0, 0,
-			       width, height, depth, stride);
+	ret = qxl_image_init(qdev, release, dimage,
+			     (const uint8_t *)src, 0, 0,
+			     width, height, depth, stride);
 	if (ret) {
-		qxl_release_unreserve(qdev, release);
+		qxl_release_backoff_reserve_list(release);
 		qxl_release_free(qdev, release);
 		return;
 	}
 
 	if (depth == 1) {
-		struct qxl_bo *palette_bo;
 		void *ptr;
-		ret = qxl_palette_create_1bit(&palette_bo, qxl_fb_image);
-		qxl_release_add_res(qdev, release, palette_bo);
+		ret = qxl_palette_create_1bit(palette_bo, release, qxl_fb_image);
 
-		ptr = qxl_bo_kmap_atomic_page(qdev, image_bo, 0);
+		ptr = qxl_bo_kmap_atomic_page(qdev, dimage->bo, 0);
 		image = ptr;
 		image->u.bitmap.palette =
 			qxl_bo_physical_address(qdev, palette_bo, 0);
-		qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr);
-		qxl_bo_unreserve(palette_bo);
-		qxl_bo_unref(&palette_bo);
+		qxl_bo_kunmap_atomic_page(qdev, dimage->bo, ptr);
 	}
 
 	drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
@@ -199,16 +240,20 @@ void qxl_draw_opaque_fb(const struct qxl
 	drawable->u.copy.mask.bitmap = 0;
 
 	drawable->u.copy.src_bitmap =
-		qxl_bo_physical_address(qdev, image_bo, 0);
+		qxl_bo_physical_address(qdev, dimage->bo, 0);
 	qxl_release_unmap(qdev, release, &drawable->release_info);
 
-	qxl_release_add_res(qdev, release, image_bo);
-	qxl_bo_unreserve(image_bo);
-	qxl_bo_unref(&image_bo);
-
-	qxl_fence_releaseable(qdev, release);
 	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
-	qxl_release_unreserve(qdev, release);
+	qxl_release_fence_buffer_objects(release);
+
+out_free_palette:
+	if (palette_bo)
+		qxl_bo_unref(&palette_bo);
+out_free_image:
+	qxl_image_free_objects(qdev, dimage);
+out_free_drawable:
+	if (ret)
+		free_drawable(qdev, release);
 }
 
 /* push a draw command using the given clipping rectangles as
@@ -243,10 +288,14 @@ void qxl_draw_dirty_fb(struct qxl_device
 	int depth = qxl_fb->base.bits_per_pixel;
 	uint8_t *surface_base;
 	struct qxl_release *release;
-	struct qxl_bo *image_bo;
 	struct qxl_bo *clips_bo;
+	struct qxl_drm_image *dimage;
 	int ret;
 
+	ret = alloc_drawable(qdev, &release);
+	if (ret)
+		return;
+
 	left = clips->x1;
 	right = clips->x2;
 	top = clips->y1;
@@ -263,36 +312,52 @@ void qxl_draw_dirty_fb(struct qxl_device
 
 	width = right - left;
 	height = bottom - top;
+
+	ret = alloc_clips(qdev, release, num_clips, &clips_bo);
+	if (ret)
+		goto out_free_drawable;
+
+	ret = qxl_image_alloc_objects(qdev, release,
+				      &dimage,
+				      height, stride);
+	if (ret)
+		goto out_free_clips;
+
+	/* do a reservation run over all the objects we just allocated */
+	ret = qxl_release_reserve_list(release, true);
+	if (ret)
+		goto out_free_image;
+
 	drawable_rect.left = left;
 	drawable_rect.right = right;
 	drawable_rect.top = top;
 	drawable_rect.bottom = bottom;
+
 	ret = make_drawable(qdev, 0, QXL_DRAW_COPY, &drawable_rect,
-			    &release);
+			    release);
 	if (ret)
-		return;
+		goto out_release_backoff;
 
 	ret = qxl_bo_kmap(bo, (void **)&surface_base);
 	if (ret)
-		goto out_unref;
+		goto out_release_backoff;
 
-	ret = qxl_image_create(qdev, release, &image_bo, surface_base,
-			       left, top, width, height, depth, stride);
+
+	ret = qxl_image_init(qdev, release, dimage, surface_base,
+			     left, top, width, height, depth, stride);
 	qxl_bo_kunmap(bo);
 	if (ret)
-		goto out_unref;
+		goto out_release_backoff;
+
+	rects = drawable_set_clipping(qdev, drawable, num_clips, clips_bo);
+	if (!rects)
+		goto out_release_backoff;
 
-	rects = drawable_set_clipping(qdev, drawable, num_clips, &clips_bo, release);
-	if (!rects) {
-		qxl_bo_unref(&image_bo);
-		goto out_unref;
-	}
 	drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
 
 	drawable->clip.type = SPICE_CLIP_TYPE_RECTS;
 	drawable->clip.data = qxl_bo_physical_address(qdev,
 						      clips_bo, 0);
-	qxl_release_add_res(qdev, release, clips_bo);
 
 	drawable->u.copy.src_area.top = 0;
 	drawable->u.copy.src_area.bottom = height;
@@ -306,11 +371,9 @@ void qxl_draw_dirty_fb(struct qxl_device
 	drawable->u.copy.mask.pos.y = 0;
 	drawable->u.copy.mask.bitmap = 0;
 
-	drawable->u.copy.src_bitmap = qxl_bo_physical_address(qdev, image_bo, 0);
+	drawable->u.copy.src_bitmap = qxl_bo_physical_address(qdev, dimage->bo, 0);
 	qxl_release_unmap(qdev, release, &drawable->release_info);
-	qxl_release_add_res(qdev, release, image_bo);
-	qxl_bo_unreserve(image_bo);
-	qxl_bo_unref(&image_bo);
+
 	clips_ptr = clips;
 	for (i = 0; i < num_clips; i++, clips_ptr += inc) {
 		rects[i].left   = clips_ptr->x1;
@@ -319,17 +382,22 @@ void qxl_draw_dirty_fb(struct qxl_device
 		rects[i].bottom = clips_ptr->y2;
 	}
 	qxl_bo_kunmap(clips_bo);
-	qxl_bo_unreserve(clips_bo);
-	qxl_bo_unref(&clips_bo);
 
-	qxl_fence_releaseable(qdev, release);
 	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
-	qxl_release_unreserve(qdev, release);
-	return;
+	qxl_release_fence_buffer_objects(release);
+
+out_release_backoff:
+	if (ret)
+		qxl_release_backoff_reserve_list(release);
+out_free_image:
+	qxl_image_free_objects(qdev, dimage);
+out_free_clips:
+	qxl_bo_unref(&clips_bo);
+out_free_drawable:
+	/* only free drawable on error */
+	if (ret)
+		free_drawable(qdev, release);
 
-out_unref:
-	qxl_release_unreserve(qdev, release);
-	qxl_release_free(qdev, release);
 }
 
 void qxl_draw_copyarea(struct qxl_device *qdev,
@@ -342,22 +410,36 @@ void qxl_draw_copyarea(struct qxl_device
 	struct qxl_release *release;
 	int ret;
 
+	ret = alloc_drawable(qdev, &release);
+	if (ret)
+		return;
+
+	/* do a reservation run over all the objects we just allocated */
+	ret = qxl_release_reserve_list(release, true);
+	if (ret)
+		goto out_free_release;
+
 	rect.left = dx;
 	rect.top = dy;
 	rect.right = dx + width;
 	rect.bottom = dy + height;
-	ret = make_drawable(qdev, 0, QXL_COPY_BITS, &rect, &release);
-	if (ret)
-		return;
+	ret = make_drawable(qdev, 0, QXL_COPY_BITS, &rect, release);
+	if (ret) {
+		qxl_release_backoff_reserve_list(release);
+		goto out_free_release;
+	}
 
 	drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
 	drawable->u.copy_bits.src_pos.x = sx;
 	drawable->u.copy_bits.src_pos.y = sy;
-
 	qxl_release_unmap(qdev, release, &drawable->release_info);
-	qxl_fence_releaseable(qdev, release);
+
 	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
-	qxl_release_unreserve(qdev, release);
+	qxl_release_fence_buffer_objects(release);
+
+out_free_release:
+	if (ret)
+		free_drawable(qdev, release);
 }
 
 void qxl_draw_fill(struct qxl_draw_fill *qxl_draw_fill_rec)
@@ -370,10 +452,21 @@ void qxl_draw_fill(struct qxl_draw_fill
 	struct qxl_release *release;
 	int ret;
 
-	ret = make_drawable(qdev, 0, QXL_DRAW_FILL, &rect, &release);
+	ret = alloc_drawable(qdev, &release);
 	if (ret)
 		return;
 
+	/* do a reservation run over all the objects we just allocated */
+	ret = qxl_release_reserve_list(release, true);
+	if (ret)
+		goto out_free_release;
+
+	ret = make_drawable(qdev, 0, QXL_DRAW_FILL, &rect, release);
+	if (ret) {
+		qxl_release_backoff_reserve_list(release);
+		goto out_free_release;
+	}
+
 	drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
 	drawable->u.fill.brush.type = SPICE_BRUSH_TYPE_SOLID;
 	drawable->u.fill.brush.u.color = color;
@@ -384,7 +477,11 @@ void qxl_draw_fill(struct qxl_draw_fill
 	drawable->u.fill.mask.bitmap = 0;
 
 	qxl_release_unmap(qdev, release, &drawable->release_info);
-	qxl_fence_releaseable(qdev, release);
+
 	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
-	qxl_release_unreserve(qdev, release);
+	qxl_release_fence_buffer_objects(release);
+
+out_free_release:
+	if (ret)
+		free_drawable(qdev, release);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,8 +33,9 @@
 
 #include "drmP.h"
 #include "drm/drm.h"
-
+#include "drm_crtc_helper.h"
 #include "qxl_drv.h"
+#include "qxl_object.h"
 
 extern int qxl_max_ioctls;
 static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
@@ -47,10 +48,14 @@ static DEFINE_PCI_DEVICE_TABLE(pciidlist
 MODULE_DEVICE_TABLE(pci, pciidlist);
 
 static int qxl_modeset = -1;
+int qxl_num_crtc = 4;
 
 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
 module_param_named(modeset, qxl_modeset, int, 0400);
 
+MODULE_PARM_DESC(num_heads, "Number of virtual crtcs to expose (default 4)");
+module_param_named(num_heads, qxl_num_crtc, int, 0400);
+
 static struct drm_driver qxl_driver;
 static struct pci_driver qxl_pci_driver;
 
@@ -73,13 +78,6 @@ qxl_pci_remove(struct pci_dev *pdev)
 	drm_put_dev(dev);
 }
 
-static struct pci_driver qxl_pci_driver = {
-	 .name = DRIVER_NAME,
-	 .id_table = pciidlist,
-	 .probe = qxl_pci_probe,
-	 .remove = qxl_pci_remove,
-};
-
 static const struct file_operations qxl_fops = {
 	.owner = THIS_MODULE,
 	.open = drm_open,
@@ -90,6 +88,130 @@ static const struct file_operations qxl_
 	.mmap = qxl_mmap,
 };
 
+static int qxl_drm_freeze(struct drm_device *dev)
+{
+	struct pci_dev *pdev = dev->pdev;
+	struct qxl_device *qdev = dev->dev_private;
+	struct drm_crtc *crtc;
+
+	drm_kms_helper_poll_disable(dev);
+
+	console_lock();
+	qxl_fbdev_set_suspend(qdev, 1);
+	console_unlock();
+
+	/* unpin the front buffers */
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+		if (crtc->enabled)
+			(*crtc_funcs->disable)(crtc);
+	}
+
+	qxl_destroy_monitors_object(qdev);
+	qxl_surf_evict(qdev);
+	qxl_vram_evict(qdev);
+
+	while (!qxl_check_idle(qdev->command_ring));
+	while (!qxl_check_idle(qdev->release_ring))
+		qxl_queue_garbage_collect(qdev, 1);
+
+	pci_save_state(pdev);
+
+	return 0;
+}
+
+static int qxl_drm_resume(struct drm_device *dev, bool thaw)
+{
+	struct qxl_device *qdev = dev->dev_private;
+
+	qdev->ram_header->int_mask = QXL_INTERRUPT_MASK;
+	if (!thaw) {
+		qxl_reinit_memslots(qdev);
+		qxl_ring_init_hdr(qdev->release_ring);
+	}
+
+	qxl_create_monitors_object(qdev);
+	drm_helper_resume_force_mode(dev);
+
+	console_lock();
+	qxl_fbdev_set_suspend(qdev, 0);
+	console_unlock();
+
+	drm_kms_helper_poll_enable(dev);
+	return 0;
+}
+
+static int qxl_pm_suspend(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+	int error;
+
+	error = qxl_drm_freeze(drm_dev);
+	if (error)
+		return error;
+
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
+	return 0;
+}
+
+static int qxl_pm_resume(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	if (pci_enable_device(pdev)) {
+		return -EIO;
+	}
+
+	return qxl_drm_resume(drm_dev, false);
+}
+
+static int qxl_pm_thaw(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+	return qxl_drm_resume(drm_dev, true);
+}
+
+static int qxl_pm_freeze(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+	return qxl_drm_freeze(drm_dev);
+}
+
+static int qxl_pm_restore(struct device *dev)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct drm_device *drm_dev = pci_get_drvdata(pdev);
+	struct qxl_device *qdev = drm_dev->dev_private;
+
+	qxl_io_reset(qdev);
+	return qxl_drm_resume(drm_dev, false);
+}
+
+static const struct dev_pm_ops qxl_pm_ops = {
+	.suspend = qxl_pm_suspend,
+	.resume = qxl_pm_resume,
+	.freeze = qxl_pm_freeze,
+	.thaw = qxl_pm_thaw,
+	.poweroff = qxl_pm_freeze,
+	.restore = qxl_pm_restore,
+};
+static struct pci_driver qxl_pci_driver = {
+	 .name = DRIVER_NAME,
+	 .id_table = pciidlist,
+	 .probe = qxl_pci_probe,
+	 .remove = qxl_pci_remove,
+	 .driver.pm = &qxl_pm_ops,
+};
+
 static struct drm_driver qxl_driver = {
 	.driver_features = DRIVER_GEM | DRIVER_MODESET |
 			   DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -42,6 +42,9 @@
 #include <ttm/ttm_placement.h>
 #include <ttm/ttm_module.h>
 
+/* just for ttm_validate_buffer */
+#include <ttm/ttm_execbuf_util.h>
+
 #include <drm/qxl_drm.h>
 #include "qxl_dev.h"
 
@@ -55,11 +58,10 @@
 #define DRIVER_MINOR 1
 #define DRIVER_PATCHLEVEL 0
 
-#define QXL_NUM_OUTPUTS 1
-
 #define QXL_DEBUGFS_MAX_COMPONENTS		32
 
 extern int qxl_log_level;
+extern int qxl_num_crtc;
 
 enum {
 	QXL_INFO_LEVEL = 1,
@@ -119,9 +121,9 @@ struct qxl_bo {
 	uint32_t surface_id;
 	struct qxl_fence fence; /* per bo fence  - list of releases */
 	struct qxl_release *surf_create;
-	atomic_t reserve_count;
 };
 #define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, gem_base)
+#define to_qxl_bo(tobj) container_of((tobj), struct qxl_bo, tbo)
 
 struct qxl_gem {
 	struct mutex		mutex;
@@ -129,16 +131,12 @@ struct qxl_gem {
 };
 
 struct qxl_bo_list {
-	struct list_head lhead;
-	struct qxl_bo *bo;
-};
-
-struct qxl_reloc_list {
-	struct list_head bos;
+	struct ttm_validate_buffer tv;
 };
 
 struct qxl_crtc {
 	struct drm_crtc base;
+	int index;
 	int cur_x;
 	int cur_y;
 };
@@ -156,7 +154,7 @@ struct qxl_framebuffer {
 
 #define to_qxl_crtc(x) container_of(x, struct qxl_crtc, base)
 #define drm_connector_to_qxl_output(x) container_of(x, struct qxl_output, base)
-#define drm_encoder_to_qxl_output(x) container_of(x, struct qxl_output, base)
+#define drm_encoder_to_qxl_output(x) container_of(x, struct qxl_output, enc)
 #define to_qxl_framebuffer(x) container_of(x, struct qxl_framebuffer, base)
 
 struct qxl_mman {
@@ -195,10 +193,20 @@ enum {
 struct qxl_release {
 	int id;
 	int type;
-	int bo_count;
 	uint32_t release_offset;
 	uint32_t surface_release_id;
-	struct qxl_bo *bos[QXL_MAX_RES];
+	struct ww_acquire_ctx ticket;
+	struct list_head bos;
+};
+
+struct qxl_drm_chunk {
+	struct list_head head;
+	struct qxl_bo *bo;
+};
+
+struct qxl_drm_image {
+	struct qxl_bo *bo;
+	struct list_head chunk_list;
 };
 
 struct qxl_fb_image {
@@ -314,6 +322,7 @@ struct qxl_device {
 	struct workqueue_struct *gc_queue;
 	struct work_struct gc_work;
 
+	struct work_struct fb_work;
 };
 
 /* forward declaration for QXL_INFO_IO */
@@ -331,6 +340,10 @@ void qxl_modeset_fini(struct qxl_device
 int qxl_bo_init(struct qxl_device *qdev);
 void qxl_bo_fini(struct qxl_device *qdev);
 
+void qxl_reinit_memslots(struct qxl_device *qdev);
+int qxl_surf_evict(struct qxl_device *qdev);
+int qxl_vram_evict(struct qxl_device *qdev);
+
 struct qxl_ring *qxl_ring_create(struct qxl_ring_header *header,
 				 int element_size,
 				 int n_elements,
@@ -338,6 +351,8 @@ struct qxl_ring *qxl_ring_create(struct
 				 bool set_prod_notify,
 				 wait_queue_head_t *push_event);
 void qxl_ring_free(struct qxl_ring *ring);
+void qxl_ring_init_hdr(struct qxl_ring *ring);
+int qxl_check_idle(struct qxl_ring *ring);
 
 static inline void *
 qxl_fb_virtual_address(struct qxl_device *qdev, unsigned long physical)
@@ -365,6 +380,7 @@ void qxl_fbdev_fini(struct qxl_device *q
 int qxl_get_handle_for_primary_fb(struct qxl_device *qdev,
 				  struct drm_file *file_priv,
 				  uint32_t *handle);
+void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state);
 
 /* qxl_display.c */
 int
@@ -374,6 +390,8 @@ qxl_framebuffer_init(struct drm_device *
 		     struct drm_gem_object *obj);
 void qxl_display_read_client_monitors_config(struct qxl_device *qdev);
 void qxl_send_monitors_config(struct qxl_device *qdev);
+int qxl_create_monitors_object(struct qxl_device *qdev);
+int qxl_destroy_monitors_object(struct qxl_device *qdev);
 
 /* used by qxl_debugfs only */
 void qxl_crtc_set_from_monitors_config(struct qxl_device *qdev);
@@ -424,18 +442,25 @@ int qxl_mmap(struct file *filp, struct v
 
 /* qxl image */
 
-int qxl_image_create(struct qxl_device *qdev,
-		     struct qxl_release *release,
-		     struct qxl_bo **image_bo,
-		     const uint8_t *data,
-		     int x, int y, int width, int height,
-		     int depth, int stride);
+int qxl_image_init(struct qxl_device *qdev,
+		   struct qxl_release *release,
+		   struct qxl_drm_image *dimage,
+		   const uint8_t *data,
+		   int x, int y, int width, int height,
+		   int depth, int stride);
+int
+qxl_image_alloc_objects(struct qxl_device *qdev,
+			struct qxl_release *release,
+			struct qxl_drm_image **image_ptr,
+			int height, int stride);
+void qxl_image_free_objects(struct qxl_device *qdev, struct qxl_drm_image *dimage);
+
 void qxl_update_screen(struct qxl_device *qxl);
 
 /* qxl io operations (qxl_cmd.c) */
 
 void qxl_io_create_primary(struct qxl_device *qdev,
-			   unsigned width, unsigned height, unsigned offset,
+			   unsigned offset,
 			   struct qxl_bo *bo);
 void qxl_io_destroy_primary(struct qxl_device *qdev);
 void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id);
@@ -450,20 +475,15 @@ int qxl_ring_push(struct qxl_ring *ring,
 void qxl_io_flush_release(struct qxl_device *qdev);
 void qxl_io_flush_surfaces(struct qxl_device *qdev);
 
-int qxl_release_reserve(struct qxl_device *qdev,
-			struct qxl_release *release, bool no_wait);
-void qxl_release_unreserve(struct qxl_device *qdev,
-			   struct qxl_release *release);
 union qxl_release_info *qxl_release_map(struct qxl_device *qdev,
 					struct qxl_release *release);
 void qxl_release_unmap(struct qxl_device *qdev,
 		       struct qxl_release *release,
 		       union qxl_release_info *info);
-/*
- * qxl_bo_add_resource.
- *
- */
-void qxl_bo_add_resource(struct qxl_bo *main_bo, struct qxl_bo *resource);
+int qxl_release_list_add(struct qxl_release *release, struct qxl_bo *bo);
+int qxl_release_reserve_list(struct qxl_release *release, bool no_intr);
+void qxl_release_backoff_reserve_list(struct qxl_release *release);
+void qxl_release_fence_buffer_objects(struct qxl_release *release);
 
 int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
 				       enum qxl_surface_cmd_type surface_cmd_type,
@@ -472,15 +492,16 @@ int qxl_alloc_surface_release_reserved(s
 int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
 			       int type, struct qxl_release **release,
 			       struct qxl_bo **rbo);
-int qxl_fence_releaseable(struct qxl_device *qdev,
-			  struct qxl_release *release);
+
 int
 qxl_push_command_ring_release(struct qxl_device *qdev, struct qxl_release *release,
 			      uint32_t type, bool interruptible);
 int
 qxl_push_cursor_ring_release(struct qxl_device *qdev, struct qxl_release *release,
 			     uint32_t type, bool interruptible);
-int qxl_alloc_bo_reserved(struct qxl_device *qdev, unsigned long size,
+int qxl_alloc_bo_reserved(struct qxl_device *qdev,
+			  struct qxl_release *release,
+			  unsigned long size,
 			  struct qxl_bo **_bo);
 /* qxl drawing commands */
 
@@ -501,15 +522,9 @@ void qxl_draw_copyarea(struct qxl_device
 		       u32 sx, u32 sy,
 		       u32 dx, u32 dy);
 
-uint64_t
-qxl_release_alloc(struct qxl_device *qdev, int type,
-		  struct qxl_release **ret);
-
 void qxl_release_free(struct qxl_device *qdev,
 		      struct qxl_release *release);
-void qxl_release_add_res(struct qxl_device *qdev,
-			 struct qxl_release *release,
-			 struct qxl_bo *bo);
+
 /* used by qxl_debugfs_release */
 struct qxl_release *qxl_release_from_id_locked(struct qxl_device *qdev,
 						   uint64_t id);
@@ -528,6 +543,7 @@ irqreturn_t qxl_irq_handler(DRM_IRQ_ARGS
 
 /* qxl_fb.c */
 int qxl_fb_init(struct qxl_device *qdev);
+bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj);
 
 int qxl_debugfs_add_files(struct qxl_device *qdev,
 			  struct drm_info_list *files,
@@ -551,7 +567,7 @@ void qxl_surface_evict(struct qxl_device
 int qxl_update_surface(struct qxl_device *qdev, struct qxl_bo *surf);
 
 /* qxl_fence.c */
-int qxl_fence_add_release(struct qxl_fence *qfence, uint32_t rel_id);
+void qxl_fence_add_release_locked(struct qxl_fence *qfence, uint32_t rel_id);
 int qxl_fence_remove_release(struct qxl_fence *qfence, uint32_t rel_id);
 int qxl_fence_init(struct qxl_device *qdev, struct qxl_fence *qfence);
 void qxl_fence_fini(struct qxl_fence *qfence);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_fb.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_fb.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_fb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_fb.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,12 +37,29 @@
 
 #define QXL_DIRTY_DELAY (HZ / 30)
 
+#define QXL_FB_OP_FILLRECT 1
+#define QXL_FB_OP_COPYAREA 2
+#define QXL_FB_OP_IMAGEBLIT 3
+
+struct qxl_fb_op {
+	struct list_head head;
+	int op_type;
+	union {
+		struct fb_fillrect fr;
+		struct fb_copyarea ca;
+		struct fb_image ib;
+	} op;
+	void *img_data;
+};
+
 struct qxl_fbdev {
 	struct drm_fb_helper helper;
 	struct qxl_framebuffer	qfb;
 	struct list_head	fbdev_list;
 	struct qxl_device	*qdev;
 
+	spinlock_t delayed_ops_lock;
+	struct list_head delayed_ops;
 	void *shadow;
 	int size;
 
@@ -164,8 +181,69 @@ static struct fb_deferred_io qxl_defio =
 	.deferred_io	= qxl_deferred_io,
 };
 
-static void qxl_fb_fillrect(struct fb_info *info,
-			    const struct fb_fillrect *fb_rect)
+static void qxl_fb_delayed_fillrect(struct qxl_fbdev *qfbdev,
+				    const struct fb_fillrect *fb_rect)
+{
+	struct qxl_fb_op *op;
+	unsigned long flags;
+
+	op = kmalloc(sizeof(struct qxl_fb_op), GFP_ATOMIC | __GFP_NOWARN);
+	if (!op)
+		return;
+
+	op->op.fr = *fb_rect;
+	op->img_data = NULL;
+	op->op_type = QXL_FB_OP_FILLRECT;
+
+	spin_lock_irqsave(&qfbdev->delayed_ops_lock, flags);
+	list_add_tail(&op->head, &qfbdev->delayed_ops);
+	spin_unlock_irqrestore(&qfbdev->delayed_ops_lock, flags);
+}
+
+static void qxl_fb_delayed_copyarea(struct qxl_fbdev *qfbdev,
+				    const struct fb_copyarea *fb_copy)
+{
+	struct qxl_fb_op *op;
+	unsigned long flags;
+
+	op = kmalloc(sizeof(struct qxl_fb_op), GFP_ATOMIC | __GFP_NOWARN);
+	if (!op)
+		return;
+
+	op->op.ca = *fb_copy;
+	op->img_data = NULL;
+	op->op_type = QXL_FB_OP_COPYAREA;
+
+	spin_lock_irqsave(&qfbdev->delayed_ops_lock, flags);
+	list_add_tail(&op->head, &qfbdev->delayed_ops);
+	spin_unlock_irqrestore(&qfbdev->delayed_ops_lock, flags);
+}
+
+static void qxl_fb_delayed_imageblit(struct qxl_fbdev *qfbdev,
+				     const struct fb_image *fb_image)
+{
+	struct qxl_fb_op *op;
+	unsigned long flags;
+	uint32_t size = fb_image->width * fb_image->height * (fb_image->depth >= 8 ? fb_image->depth / 8 : 1);
+
+	op = kmalloc(sizeof(struct qxl_fb_op) + size, GFP_ATOMIC | __GFP_NOWARN);
+	if (!op)
+		return;
+
+	op->op.ib = *fb_image;
+	op->img_data = (void *)(op + 1);
+	op->op_type = QXL_FB_OP_IMAGEBLIT;
+
+	memcpy(op->img_data, fb_image->data, size);
+
+	op->op.ib.data = op->img_data;
+	spin_lock_irqsave(&qfbdev->delayed_ops_lock, flags);
+	list_add_tail(&op->head, &qfbdev->delayed_ops);
+	spin_unlock_irqrestore(&qfbdev->delayed_ops_lock, flags);
+}
+
+static void qxl_fb_fillrect_internal(struct fb_info *info,
+				     const struct fb_fillrect *fb_rect)
 {
 	struct qxl_fbdev *qfbdev = info->par;
 	struct qxl_device *qdev = qfbdev->qdev;
@@ -203,17 +281,28 @@ static void qxl_fb_fillrect(struct fb_in
 	qxl_draw_fill_rec.rect = rect;
 	qxl_draw_fill_rec.color = color;
 	qxl_draw_fill_rec.rop = rop;
+
+	qxl_draw_fill(&qxl_draw_fill_rec);
+}
+
+static void qxl_fb_fillrect(struct fb_info *info,
+			    const struct fb_fillrect *fb_rect)
+{
+	struct qxl_fbdev *qfbdev = info->par;
+	struct qxl_device *qdev = qfbdev->qdev;
+
 	if (!drm_can_sleep()) {
-		qxl_io_log(qdev,
-			"%s: TODO use RCU, mysterious locks with spin_lock\n",
-			__func__);
+		qxl_fb_delayed_fillrect(qfbdev, fb_rect);
+		schedule_work(&qdev->fb_work);
 		return;
 	}
-	qxl_draw_fill(&qxl_draw_fill_rec);
+	/* make sure any previous work is done */
+	flush_work(&qdev->fb_work);
+	qxl_fb_fillrect_internal(info, fb_rect);
 }
 
-static void qxl_fb_copyarea(struct fb_info *info,
-			    const struct fb_copyarea *region)
+static void qxl_fb_copyarea_internal(struct fb_info *info,
+				     const struct fb_copyarea *region)
 {
 	struct qxl_fbdev *qfbdev = info->par;
 
@@ -223,37 +312,89 @@ static void qxl_fb_copyarea(struct fb_in
 			  region->dx, region->dy);
 }
 
+static void qxl_fb_copyarea(struct fb_info *info,
+			    const struct fb_copyarea *region)
+{
+	struct qxl_fbdev *qfbdev = info->par;
+	struct qxl_device *qdev = qfbdev->qdev;
+
+	if (!drm_can_sleep()) {
+		qxl_fb_delayed_copyarea(qfbdev, region);
+		schedule_work(&qdev->fb_work);
+		return;
+	}
+	/* make sure any previous work is done */
+	flush_work(&qdev->fb_work);
+	qxl_fb_copyarea_internal(info, region);
+}
+
 static void qxl_fb_imageblit_safe(struct qxl_fb_image *qxl_fb_image)
 {
 	qxl_draw_opaque_fb(qxl_fb_image, 0);
 }
 
+static void qxl_fb_imageblit_internal(struct fb_info *info,
+				      const struct fb_image *image)
+{
+	struct qxl_fbdev *qfbdev = info->par;
+	struct qxl_fb_image qxl_fb_image;
+
+	/* ensure proper order  rendering operations - TODO: must do this
+	 * for everything. */
+	qxl_fb_image_init(&qxl_fb_image, qfbdev->qdev, info, image);
+	qxl_fb_imageblit_safe(&qxl_fb_image);
+}
+
 static void qxl_fb_imageblit(struct fb_info *info,
 			     const struct fb_image *image)
 {
 	struct qxl_fbdev *qfbdev = info->par;
 	struct qxl_device *qdev = qfbdev->qdev;
-	struct qxl_fb_image qxl_fb_image;
 
 	if (!drm_can_sleep()) {
-		/* we cannot do any ttm_bo allocation since that will fail on
-		 * ioremap_wc..__get_vm_area_node, so queue the work item
-		 * instead This can happen from printk inside an interrupt
-		 * context, i.e.: smp_apic_timer_interrupt..check_cpu_stall */
-		qxl_io_log(qdev,
-			"%s: TODO use RCU, mysterious locks with spin_lock\n",
-			   __func__);
+		qxl_fb_delayed_imageblit(qfbdev, image);
+		schedule_work(&qdev->fb_work);
 		return;
 	}
+	/* make sure any previous work is done */
+	flush_work(&qdev->fb_work);
+	qxl_fb_imageblit_internal(info, image);
+}
 
-	/* ensure proper order of rendering operations - TODO: must do this
-	 * for everything. */
-	qxl_fb_image_init(&qxl_fb_image, qfbdev->qdev, info, image);
-	qxl_fb_imageblit_safe(&qxl_fb_image);
+static void qxl_fb_work(struct work_struct *work)
+{
+	struct qxl_device *qdev = container_of(work, struct qxl_device, fb_work);
+	unsigned long flags;
+	struct qxl_fb_op *entry, *tmp;
+	struct qxl_fbdev *qfbdev = qdev->mode_info.qfbdev;
+
+	/* since the irq context just adds entries to the end of the
+	   list dropping the lock should be fine, as entry isn't modified
+	   in the operation code */
+	spin_lock_irqsave(&qfbdev->delayed_ops_lock, flags);
+	list_for_each_entry_safe(entry, tmp, &qfbdev->delayed_ops, head) {
+		spin_unlock_irqrestore(&qfbdev->delayed_ops_lock, flags);
+		switch (entry->op_type) {
+		case QXL_FB_OP_FILLRECT:
+			qxl_fb_fillrect_internal(qfbdev->helper.fbdev, &entry->op.fr);
+			break;
+		case QXL_FB_OP_COPYAREA:
+			qxl_fb_copyarea_internal(qfbdev->helper.fbdev, &entry->op.ca);
+			break;
+		case QXL_FB_OP_IMAGEBLIT:
+			qxl_fb_imageblit_internal(qfbdev->helper.fbdev, &entry->op.ib);
+			break;
+		}
+		spin_lock_irqsave(&qfbdev->delayed_ops_lock, flags);
+		list_del(&entry->head);
+		kfree(entry);
+	}
+	spin_unlock_irqrestore(&qfbdev->delayed_ops_lock, flags);
 }
 
 int qxl_fb_init(struct qxl_device *qdev)
 {
+	INIT_WORK(&qdev->fb_work, qxl_fb_work);
 	return 0;
 }
 
@@ -520,10 +661,6 @@ static int qxl_fbdev_destroy(struct drm_
 }
 
 static struct drm_fb_helper_funcs qxl_fb_helper_funcs = {
-	/* TODO
-	.gamma_set = qxl_crtc_fb_gamma_set,
-	.gamma_get = qxl_crtc_fb_gamma_get,
-	*/
 	.fb_probe = qxl_fb_find_or_create_single,
 };
 
@@ -540,9 +677,10 @@ int qxl_fbdev_init(struct qxl_device *qd
 	qfbdev->qdev = qdev;
 	qdev->mode_info.qfbdev = qfbdev;
 	qfbdev->helper.funcs = &qxl_fb_helper_funcs;
-
+	spin_lock_init(&qfbdev->delayed_ops_lock);
+	INIT_LIST_HEAD(&qfbdev->delayed_ops);
 	ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper,
-				 1 /* num_crtc - QXL supports just 1 */,
+				 qxl_num_crtc /* num_crtc - QXL supports just 1 */,
 				 QXLFB_CONN_LIMIT);
 	if (ret) {
 		kfree(qfbdev);
@@ -564,4 +702,14 @@ void qxl_fbdev_fini(struct qxl_device *q
 	qdev->mode_info.qfbdev = NULL;
 }
 
+void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state)
+{
+	fb_set_suspend(qdev->mode_info.qfbdev->helper.fbdev, state);
+}
 
+bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj)
+{
+	if (qobj == gem_to_qxl_bo(qdev->mode_info.qfbdev->qfb.obj))
+		return true;
+	return false;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_fence.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_fence.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_fence.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_fence.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,17 +49,11 @@
 
    For some reason every so often qxl hw fails to release, things go wrong.
 */
-
-
-int qxl_fence_add_release(struct qxl_fence *qfence, uint32_t rel_id)
+/* must be called with the fence lock held */
+void qxl_fence_add_release_locked(struct qxl_fence *qfence, uint32_t rel_id)
 {
-	struct qxl_bo *bo = container_of(qfence, struct qxl_bo, fence);
-
-	spin_lock(&bo->tbo.bdev->fence_lock);
 	radix_tree_insert(&qfence->tree, rel_id, qfence);
 	qfence->num_active_releases++;
-	spin_unlock(&bo->tbo.bdev->fence_lock);
-	return 0;
 }
 
 int qxl_fence_remove_release(struct qxl_fence *qfence, uint32_t rel_id)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_gem.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_gem.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_gem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_gem.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,7 +55,7 @@ int qxl_gem_object_create(struct qxl_dev
 	/* At least align on page size */
 	if (alignment < PAGE_SIZE)
 		alignment = PAGE_SIZE;
-	r = qxl_bo_create(qdev, size, kernel, initial_domain, surf, &qbo);
+	r = qxl_bo_create(qdev, size, kernel, false, initial_domain, surf, &qbo);
 	if (r) {
 		if (r != -ERESTARTSYS)
 			DRM_ERROR(
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_image.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_image.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_image.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_image.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,31 +30,100 @@
 #include "qxl_object.h"
 
 static int
-qxl_image_create_helper(struct qxl_device *qdev,
+qxl_allocate_chunk(struct qxl_device *qdev,
+		   struct qxl_release *release,
+		   struct qxl_drm_image *image,
+		   unsigned int chunk_size)
+{
+	struct qxl_drm_chunk *chunk;
+	int ret;
+
+	chunk = kmalloc(sizeof(struct qxl_drm_chunk), GFP_KERNEL);
+	if (!chunk)
+		return -ENOMEM;
+
+	ret = qxl_alloc_bo_reserved(qdev, release, chunk_size, &chunk->bo);
+	if (ret) {
+		kfree(chunk);
+		return ret;
+	}
+
+	list_add_tail(&chunk->head, &image->chunk_list);
+	return 0;
+}
+
+int
+qxl_image_alloc_objects(struct qxl_device *qdev,
 			struct qxl_release *release,
-			struct qxl_bo **image_bo,
-			const uint8_t *data,
-			int width, int height,
-			int depth, unsigned int hash,
-			int stride)
+			struct qxl_drm_image **image_ptr,
+			int height, int stride)
 {
+	struct qxl_drm_image *image;
+	int ret;
+
+	image = kmalloc(sizeof(struct qxl_drm_image), GFP_KERNEL);
+	if (!image)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&image->chunk_list);
+
+	ret = qxl_alloc_bo_reserved(qdev, release, sizeof(struct qxl_image), &image->bo);
+	if (ret) {
+		kfree(image);
+		return ret;
+	}
+
+	ret = qxl_allocate_chunk(qdev, release, image, sizeof(struct qxl_data_chunk) + stride * height);
+	if (ret) {
+		qxl_bo_unref(&image->bo);
+		kfree(image);
+		return ret;
+	}
+	*image_ptr = image;
+	return 0;
+}
+
+void qxl_image_free_objects(struct qxl_device *qdev, struct qxl_drm_image *dimage)
+{
+	struct qxl_drm_chunk *chunk, *tmp;
+
+	list_for_each_entry_safe(chunk, tmp, &dimage->chunk_list, head) {
+		qxl_bo_unref(&chunk->bo);
+		kfree(chunk);
+	}
+
+	qxl_bo_unref(&dimage->bo);
+	kfree(dimage);
+}
+
+static int
+qxl_image_init_helper(struct qxl_device *qdev,
+		      struct qxl_release *release,
+		      struct qxl_drm_image *dimage,
+		      const uint8_t *data,
+		      int width, int height,
+		      int depth, unsigned int hash,
+		      int stride)
+{
+	struct qxl_drm_chunk *drv_chunk;
 	struct qxl_image *image;
 	struct qxl_data_chunk *chunk;
 	int i;
 	int chunk_stride;
 	int linesize = width * depth / 8;
-	struct qxl_bo *chunk_bo;
-	int ret;
+	struct qxl_bo *chunk_bo, *image_bo;
 	void *ptr;
 	/* Chunk */
 	/* FIXME: Check integer overflow */
 	/* TODO: variable number of chunks */
+
+	drv_chunk = list_first_entry(&dimage->chunk_list, struct qxl_drm_chunk, head);
+
+	chunk_bo = drv_chunk->bo;
 	chunk_stride = stride; /* TODO: should use linesize, but it renders
 				  wrong (check the bitmaps are sent correctly
 				  first) */
-	ret = qxl_alloc_bo_reserved(qdev, sizeof(*chunk) + height * chunk_stride,
-				    &chunk_bo);
-	
+
 	ptr = qxl_bo_kmap_atomic_page(qdev, chunk_bo, 0);
 	chunk = ptr;
 	chunk->data_size = height * chunk_stride;
@@ -102,7 +171,6 @@ qxl_image_create_helper(struct qxl_devic
 				while (remain > 0) {
 					page_base = out_offset & PAGE_MASK;
 					page_offset = offset_in_page(out_offset);
-					
 					size = min((int)(PAGE_SIZE - page_offset), remain);
 
 					ptr = qxl_bo_kmap_atomic_page(qdev, chunk_bo, page_base);
@@ -116,14 +184,10 @@ qxl_image_create_helper(struct qxl_devic
 			}
 		}
 	}
-
-
 	qxl_bo_kunmap(chunk_bo);
 
-	/* Image */
-	ret = qxl_alloc_bo_reserved(qdev, sizeof(*image), image_bo);
-
-	ptr = qxl_bo_kmap_atomic_page(qdev, *image_bo, 0);
+	image_bo = dimage->bo;
+	ptr = qxl_bo_kmap_atomic_page(qdev, image_bo, 0);
 	image = ptr;
 
 	image->descriptor.id = 0;
@@ -154,23 +218,20 @@ qxl_image_create_helper(struct qxl_devic
 	image->u.bitmap.stride = chunk_stride;
 	image->u.bitmap.palette = 0;
 	image->u.bitmap.data = qxl_bo_physical_address(qdev, chunk_bo, 0);
-	qxl_release_add_res(qdev, release, chunk_bo);
-	qxl_bo_unreserve(chunk_bo);
-	qxl_bo_unref(&chunk_bo);
 
-	qxl_bo_kunmap_atomic_page(qdev, *image_bo, ptr);
+	qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr);
 
 	return 0;
 }
 
-int qxl_image_create(struct qxl_device *qdev,
+int qxl_image_init(struct qxl_device *qdev,
 		     struct qxl_release *release,
-		     struct qxl_bo **image_bo,
+		     struct qxl_drm_image *dimage,
 		     const uint8_t *data,
 		     int x, int y, int width, int height,
 		     int depth, int stride)
 {
 	data += y * stride + x * (depth / 8);
-	return qxl_image_create_helper(qdev, release, image_bo, data,
+	return qxl_image_init_helper(qdev, release, dimage, data,
 				       width, height, depth, 0, stride);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_ioctl.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_ioctl.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -68,55 +68,60 @@ static int qxl_map_ioctl(struct drm_devi
 				  &qxl_map->offset);
 }
 
+struct qxl_reloc_info {
+	int type;
+	struct qxl_bo *dst_bo;
+	uint32_t dst_offset;
+	struct qxl_bo *src_bo;
+	int src_offset;
+};
+
 /*
  * dst must be validated, i.e. whole bo on vram/surfacesram (right now all bo's
  * are on vram).
  * *(dst + dst_off) = qxl_bo_physical_address(src, src_off)
  */
 static void
-apply_reloc(struct qxl_device *qdev, struct qxl_bo *dst, uint64_t dst_off,
-	    struct qxl_bo *src, uint64_t src_off)
+apply_reloc(struct qxl_device *qdev, struct qxl_reloc_info *info)
 {
 	void *reloc_page;
-
-	reloc_page = qxl_bo_kmap_atomic_page(qdev, dst, dst_off & PAGE_MASK);
-	*(uint64_t *)(reloc_page + (dst_off & ~PAGE_MASK)) = qxl_bo_physical_address(qdev,
-								     src, src_off);
-	qxl_bo_kunmap_atomic_page(qdev, dst, reloc_page);
+	reloc_page = qxl_bo_kmap_atomic_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK);
+	*(uint64_t *)(reloc_page + (info->dst_offset & ~PAGE_MASK)) = qxl_bo_physical_address(qdev,
+											      info->src_bo,
+											      info->src_offset);
+	qxl_bo_kunmap_atomic_page(qdev, info->dst_bo, reloc_page);
 }
 
 static void
-apply_surf_reloc(struct qxl_device *qdev, struct qxl_bo *dst, uint64_t dst_off,
-		 struct qxl_bo *src)
+apply_surf_reloc(struct qxl_device *qdev, struct qxl_reloc_info *info)
 {
 	uint32_t id = 0;
 	void *reloc_page;
 
-	if (src && !src->is_primary)
-		id = src->surface_id;
+	if (info->src_bo && !info->src_bo->is_primary)
+		id = info->src_bo->surface_id;
 
-	reloc_page = qxl_bo_kmap_atomic_page(qdev, dst, dst_off & PAGE_MASK);
-	*(uint32_t *)(reloc_page + (dst_off & ~PAGE_MASK)) = id;
-	qxl_bo_kunmap_atomic_page(qdev, dst, reloc_page);
+	reloc_page = qxl_bo_kmap_atomic_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK);
+	*(uint32_t *)(reloc_page + (info->dst_offset & ~PAGE_MASK)) = id;
+	qxl_bo_kunmap_atomic_page(qdev, info->dst_bo, reloc_page);
 }
 
 /* return holding the reference to this object */
 static struct qxl_bo *qxlhw_handle_to_bo(struct qxl_device *qdev,
 					 struct drm_file *file_priv, uint64_t handle,
-					 struct qxl_reloc_list *reloc_list)
+					 struct qxl_release *release)
 {
 	struct drm_gem_object *gobj;
 	struct qxl_bo *qobj;
 	int ret;
 
 	gobj = drm_gem_object_lookup(qdev->ddev, file_priv, handle);
-	if (!gobj) {
-		DRM_ERROR("bad bo handle %lld\n", handle);
+	if (!gobj)
 		return NULL;
-	}
+
 	qobj = gem_to_qxl_bo(gobj);
 
-	ret = qxl_bo_list_add(reloc_list, qobj);
+	ret = qxl_release_list_add(release, qobj);
 	if (ret)
 		return NULL;
 
@@ -129,145 +134,177 @@ static struct qxl_bo *qxlhw_handle_to_bo
  * However, the command as passed from user space must *not* contain the initial
  * QXLReleaseInfo struct (first XXX bytes)
  */
-static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data,
-				struct drm_file *file_priv)
+static int qxl_process_single_command(struct qxl_device *qdev,
+				      struct drm_qxl_command *cmd,
+				      struct drm_file *file_priv)
 {
-	struct qxl_device *qdev = dev->dev_private;
-	struct drm_qxl_execbuffer *execbuffer = data;
-	struct drm_qxl_command user_cmd;
-	int cmd_num;
-	struct qxl_bo *reloc_src_bo;
-	struct qxl_bo *reloc_dst_bo;
-	struct drm_qxl_reloc reloc;
+	struct qxl_reloc_info *reloc_info;
+	int release_type;
+	struct qxl_release *release;
+	struct qxl_bo *cmd_bo;
 	void *fb_cmd;
-	int i, ret;
-	struct qxl_reloc_list reloc_list;
+	int i, j, ret, num_relocs;
 	int unwritten;
-	uint32_t reloc_dst_offset;
-	INIT_LIST_HEAD(&reloc_list.bos);
 
-	for (cmd_num = 0; cmd_num < execbuffer->commands_num; ++cmd_num) {
-		struct qxl_release *release;
-		struct qxl_bo *cmd_bo;
-		int release_type;
-		struct drm_qxl_command *commands =
-			(struct drm_qxl_command *)(uintptr_t)execbuffer->commands;
+	switch (cmd->type) {
+	case QXL_CMD_DRAW:
+		release_type = QXL_RELEASE_DRAWABLE;
+		break;
+	case QXL_CMD_SURFACE:
+	case QXL_CMD_CURSOR:
+	default:
+		DRM_DEBUG("Only draw commands in execbuffers\n");
+		return -EINVAL;
+		break;
+	}
 
-		if (DRM_COPY_FROM_USER(&user_cmd, &commands[cmd_num],
-				       sizeof(user_cmd)))
-			return -EFAULT;
-		switch (user_cmd.type) {
-		case QXL_CMD_DRAW:
-			release_type = QXL_RELEASE_DRAWABLE;
-			break;
-		case QXL_CMD_SURFACE:
-		case QXL_CMD_CURSOR:
-		default:
-			DRM_DEBUG("Only draw commands in execbuffers\n");
-			return -EINVAL;
-			break;
-		}
+	if (cmd->command_size > PAGE_SIZE - sizeof(union qxl_release_info))
+		return -EINVAL;
 
-		if (user_cmd.command_size > PAGE_SIZE - sizeof(union qxl_release_info))
-			return -EINVAL;
+	if (!access_ok(VERIFY_READ,
+		       (void *)(unsigned long)cmd->command,
+		       cmd->command_size))
+		return -EFAULT;
 
-		if (!access_ok(VERIFY_READ,
-			       (void *)(unsigned long)user_cmd.command,
-			       user_cmd.command_size))
-			return -EFAULT;
+	reloc_info = kmalloc(sizeof(struct qxl_reloc_info) * cmd->relocs_num, GFP_KERNEL);
+	if (!reloc_info)
+		return -ENOMEM;
 
-		ret = qxl_alloc_release_reserved(qdev,
-						 sizeof(union qxl_release_info) +
-						 user_cmd.command_size,
-						 release_type,
-						 &release,
-						 &cmd_bo);
-		if (ret)
-			return ret;
+	ret = qxl_alloc_release_reserved(qdev,
+					 sizeof(union qxl_release_info) +
+					 cmd->command_size,
+					 release_type,
+					 &release,
+					 &cmd_bo);
+	if (ret)
+		goto out_free_reloc;
 
-		/* TODO copy slow path code from i915 */
-		fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_SIZE));
-		unwritten = __copy_from_user_inatomic_nocache(fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE), (void *)(unsigned long)user_cmd.command, user_cmd.command_size);
-		qxl_bo_kunmap_atomic_page(qdev, cmd_bo, fb_cmd);
-		if (unwritten) {
-			DRM_ERROR("got unwritten %d\n", unwritten);
-			qxl_release_unreserve(qdev, release);
-			qxl_release_free(qdev, release);
-			return -EFAULT;
+	/* TODO copy slow path code from i915 */
+	fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_SIZE));
+	unwritten = __copy_from_user_inatomic_nocache(fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE), (void *)(unsigned long)cmd->command, cmd->command_size);
+
+	{
+		struct qxl_drawable *draw = fb_cmd;
+		draw->mm_time = qdev->rom->mm_clock;
+	}
+
+	qxl_bo_kunmap_atomic_page(qdev, cmd_bo, fb_cmd);
+	if (unwritten) {
+		DRM_ERROR("got unwritten %d\n", unwritten);
+		ret = -EFAULT;
+		goto out_free_release;
+	}
+
+	/* fill out reloc info structs */
+	num_relocs = 0;
+	for (i = 0; i < cmd->relocs_num; ++i) {
+		struct drm_qxl_reloc reloc;
+
+		if (DRM_COPY_FROM_USER(&reloc,
+				       &((struct drm_qxl_reloc *)(uintptr_t)cmd->relocs)[i],
+				       sizeof(reloc))) {
+			ret = -EFAULT;
+			goto out_free_bos;
 		}
 
-		for (i = 0 ; i < user_cmd.relocs_num; ++i) {
-			if (DRM_COPY_FROM_USER(&reloc,
-					       &((struct drm_qxl_reloc *)(uintptr_t)user_cmd.relocs)[i],
-					       sizeof(reloc))) {
-				qxl_bo_list_unreserve(&reloc_list, true);
-				qxl_release_unreserve(qdev, release);
-				qxl_release_free(qdev, release);
-				return -EFAULT;
-			}
+		/* add the bos to the list of bos to validate -
+		   need to validate first then process relocs? */
+		if (reloc.reloc_type != QXL_RELOC_TYPE_BO && reloc.reloc_type != QXL_RELOC_TYPE_SURF) {
+			DRM_DEBUG("unknown reloc type %d\n", reloc_info[i].type);
 
-			/* add the bos to the list of bos to validate -
-			   need to validate first then process relocs? */
-			if (reloc.dst_handle) {
-				reloc_dst_bo = qxlhw_handle_to_bo(qdev, file_priv,
-								  reloc.dst_handle, &reloc_list);
-				if (!reloc_dst_bo) {
-					qxl_bo_list_unreserve(&reloc_list, true);
-					qxl_release_unreserve(qdev, release);
-					qxl_release_free(qdev, release);
-					return -EINVAL;
-				}
-				reloc_dst_offset = 0;
-			} else {
-				reloc_dst_bo = cmd_bo;
-				reloc_dst_offset = release->release_offset;
-			}
+			ret = -EINVAL;
+			goto out_free_bos;
+		}
+		reloc_info[i].type = reloc.reloc_type;
 
-			/* reserve and validate the reloc dst bo */
-			if (reloc.reloc_type == QXL_RELOC_TYPE_BO || reloc.src_handle > 0) {
-				reloc_src_bo =
-					qxlhw_handle_to_bo(qdev, file_priv,
-							   reloc.src_handle, &reloc_list);
-				if (!reloc_src_bo) {
-					if (reloc_dst_bo != cmd_bo)
-						drm_gem_object_unreference_unlocked(&reloc_dst_bo->gem_base);
-					qxl_bo_list_unreserve(&reloc_list, true);
-					qxl_release_unreserve(qdev, release);
-					qxl_release_free(qdev, release);
-					return -EINVAL;
-				}
-			} else
-				reloc_src_bo = NULL;
-			if (reloc.reloc_type == QXL_RELOC_TYPE_BO) {
-				apply_reloc(qdev, reloc_dst_bo, reloc_dst_offset + reloc.dst_offset,
-					    reloc_src_bo, reloc.src_offset);
-			} else if (reloc.reloc_type == QXL_RELOC_TYPE_SURF) {
-				apply_surf_reloc(qdev, reloc_dst_bo, reloc_dst_offset + reloc.dst_offset, reloc_src_bo);
-			} else {
-				DRM_ERROR("unknown reloc type %d\n", reloc.reloc_type);
-				return -EINVAL;
+		if (reloc.dst_handle) {
+			reloc_info[i].dst_bo = qxlhw_handle_to_bo(qdev, file_priv,
+								  reloc.dst_handle, release);
+			if (!reloc_info[i].dst_bo) {
+				ret = -EINVAL;
+				reloc_info[i].src_bo = NULL;
+				goto out_free_bos;
 			}
+			reloc_info[i].dst_offset = reloc.dst_offset;
+		} else {
+			reloc_info[i].dst_bo = cmd_bo;
+			reloc_info[i].dst_offset = reloc.dst_offset + release->release_offset;
+		}
+		num_relocs++;
 
-			if (reloc_src_bo && reloc_src_bo != cmd_bo) {
-				qxl_release_add_res(qdev, release, reloc_src_bo);
-				drm_gem_object_unreference_unlocked(&reloc_src_bo->gem_base);
+		/* reserve and validate the reloc dst bo */
+		if (reloc.reloc_type == QXL_RELOC_TYPE_BO || reloc.src_handle > 0) {
+			reloc_info[i].src_bo =
+				qxlhw_handle_to_bo(qdev, file_priv,
+						   reloc.src_handle, release);
+			if (!reloc_info[i].src_bo) {
+				if (reloc_info[i].dst_bo != cmd_bo)
+					drm_gem_object_unreference_unlocked(&reloc_info[i].dst_bo->gem_base);
+				ret = -EINVAL;
+				goto out_free_bos;
 			}
-
-			if (reloc_dst_bo != cmd_bo)
-				drm_gem_object_unreference_unlocked(&reloc_dst_bo->gem_base);
+			reloc_info[i].src_offset = reloc.src_offset;
+		} else {
+			reloc_info[i].src_bo = NULL;
+			reloc_info[i].src_offset = 0;
 		}
-		qxl_fence_releaseable(qdev, release);
+	}
 
-		ret = qxl_push_command_ring_release(qdev, release, user_cmd.type, true);
-		if (ret == -ERESTARTSYS) {
-			qxl_release_unreserve(qdev, release);
-			qxl_release_free(qdev, release);
-			qxl_bo_list_unreserve(&reloc_list, true);
+	/* validate all buffers */
+	ret = qxl_release_reserve_list(release, false);
+	if (ret)
+		goto out_free_bos;
+
+	for (i = 0; i < cmd->relocs_num; ++i) {
+		if (reloc_info[i].type == QXL_RELOC_TYPE_BO)
+			apply_reloc(qdev, &reloc_info[i]);
+		else if (reloc_info[i].type == QXL_RELOC_TYPE_SURF)
+			apply_surf_reloc(qdev, &reloc_info[i]);
+	}
+
+	ret = qxl_push_command_ring_release(qdev, release, cmd->type, true);
+	if (ret)
+		qxl_release_backoff_reserve_list(release);
+	else
+		qxl_release_fence_buffer_objects(release);
+
+out_free_bos:
+	for (j = 0; j < num_relocs; j++) {
+		if (reloc_info[j].dst_bo != cmd_bo)
+			drm_gem_object_unreference_unlocked(&reloc_info[j].dst_bo->gem_base);
+		if (reloc_info[j].src_bo && reloc_info[j].src_bo != cmd_bo)
+			drm_gem_object_unreference_unlocked(&reloc_info[j].src_bo->gem_base);
+	}
+out_free_release:
+	if (ret)
+		qxl_release_free(qdev, release);
+out_free_reloc:
+	kfree(reloc_info);
+	return ret;
+}
+
+static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_priv)
+{
+	struct qxl_device *qdev = dev->dev_private;
+	struct drm_qxl_execbuffer *execbuffer = data;
+	struct drm_qxl_command user_cmd;
+	int cmd_num;
+	int ret;
+
+	for (cmd_num = 0; cmd_num < execbuffer->commands_num; ++cmd_num) {
+
+		struct drm_qxl_command *commands =
+			(struct drm_qxl_command *)(uintptr_t)execbuffer->commands;
+
+		if (DRM_COPY_FROM_USER(&user_cmd, &commands[cmd_num],
+				       sizeof(user_cmd)))
+			return -EFAULT;
+
+		ret = qxl_process_single_command(qdev, &user_cmd, file_priv);
+		if (ret)
 			return ret;
-		}
-		qxl_release_unreserve(qdev, release);
 	}
-	qxl_bo_list_unreserve(&reloc_list, 0);
 	return 0;
 }
 
@@ -299,7 +336,7 @@ static int qxl_update_area_ioctl(struct
 		goto out;
 
 	if (!qobj->pin_count) {
-		qxl_ttm_placement_from_domain(qobj, qobj->type);
+		qxl_ttm_placement_from_domain(qobj, qobj->type, false);
 		ret = ttm_bo_validate(&qobj->tbo, &qobj->placement,
 				      true, false);
 		if (unlikely(ret))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_kms.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_kms.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_kms.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_kms.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,7 @@
 #include "qxl_drv.h"
 #include "qxl_object.h"
 
+#include <drm/drm_crtc_helper.h>
 #include <linux/io-mapping.h>
 
 int qxl_log_level;
@@ -72,21 +73,28 @@ static bool qxl_check_device(struct qxl_
 	return true;
 }
 
+static void setup_hw_slot(struct qxl_device *qdev, int slot_index,
+			  struct qxl_memslot *slot)
+{
+	qdev->ram_header->mem_slot.mem_start = slot->start_phys_addr;
+	qdev->ram_header->mem_slot.mem_end = slot->end_phys_addr;
+	qxl_io_memslot_add(qdev, slot_index);
+}
+
 static uint8_t setup_slot(struct qxl_device *qdev, uint8_t slot_index_offset,
 	unsigned long start_phys_addr, unsigned long end_phys_addr)
 {
 	uint64_t high_bits;
 	struct qxl_memslot *slot;
 	uint8_t slot_index;
-	struct qxl_ram_header *ram_header = qdev->ram_header;
 
 	slot_index = qdev->rom->slots_start + slot_index_offset;
 	slot = &qdev->mem_slots[slot_index];
 	slot->start_phys_addr = start_phys_addr;
 	slot->end_phys_addr = end_phys_addr;
-	ram_header->mem_slot.mem_start = slot->start_phys_addr;
-	ram_header->mem_slot.mem_end = slot->end_phys_addr;
-	qxl_io_memslot_add(qdev, slot_index);
+
+	setup_hw_slot(qdev, slot_index, slot);
+
 	slot->generation = qdev->rom->slot_generation;
 	high_bits = slot_index << qdev->slot_gen_bits;
 	high_bits |= slot->generation;
@@ -95,6 +103,12 @@ static uint8_t setup_slot(struct qxl_dev
 	return slot_index;
 }
 
+void qxl_reinit_memslots(struct qxl_device *qdev)
+{
+	setup_hw_slot(qdev, qdev->main_mem_slot, &qdev->mem_slots[qdev->main_mem_slot]);
+	setup_hw_slot(qdev, qdev->surfaces_mem_slot, &qdev->mem_slots[qdev->surfaces_mem_slot]);
+}
+
 static void qxl_gc_work(struct work_struct *work)
 {
 	struct qxl_device *qdev = container_of(work, struct qxl_device, gc_work);
@@ -294,6 +308,8 @@ int qxl_driver_load(struct drm_device *d
 		goto out;
 	}
 
+	drm_kms_helper_poll_init(qdev->ddev);
+
 	return 0;
 out:
 	kfree(qdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_object.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_object.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_object.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_object.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,20 +51,21 @@ bool qxl_ttm_bo_is_qxl_bo(struct ttm_buf
 	return false;
 }
 
-void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain)
+void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain, bool pinned)
 {
 	u32 c = 0;
+	u32 pflag = pinned ? TTM_PL_FLAG_NO_EVICT : 0;
 
 	qbo->placement.fpfn = 0;
 	qbo->placement.lpfn = 0;
 	qbo->placement.placement = qbo->placements;
 	qbo->placement.busy_placement = qbo->placements;
 	if (domain == QXL_GEM_DOMAIN_VRAM)
-		qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_VRAM;
+		qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_VRAM | pflag;
 	if (domain == QXL_GEM_DOMAIN_SURFACE)
-		qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_PRIV0;
+		qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_PRIV0 | pflag;
 	if (domain == QXL_GEM_DOMAIN_CPU)
-		qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+		qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM | pflag;
 	if (!c)
 		qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
 	qbo->placement.num_placement = c;
@@ -73,7 +74,7 @@ void qxl_ttm_placement_from_domain(struc
 
 
 int qxl_bo_create(struct qxl_device *qdev,
-		  unsigned long size, bool kernel, u32 domain,
+		  unsigned long size, bool kernel, bool pinned, u32 domain,
 		  struct qxl_surface *surf,
 		  struct qxl_bo **bo_ptr)
 {
@@ -99,15 +100,15 @@ int qxl_bo_create(struct qxl_device *qde
 	}
 	bo->gem_base.driver_private = NULL;
 	bo->type = domain;
-	bo->pin_count = 0;
+	bo->pin_count = pinned ? 1 : 0;
 	bo->surface_id = 0;
 	qxl_fence_init(qdev, &bo->fence);
 	INIT_LIST_HEAD(&bo->list);
-	atomic_set(&bo->reserve_count, 0);
+
 	if (surf)
 		bo->surf = *surf;
 
-	qxl_ttm_placement_from_domain(bo, domain);
+	qxl_ttm_placement_from_domain(bo, domain, pinned);
 
 	r = ttm_bo_init(&qdev->mman.bdev, &bo->tbo, size, type,
 			&bo->placement, 0, !kernel, NULL, size,
@@ -228,7 +229,7 @@ struct qxl_bo *qxl_bo_ref(struct qxl_bo
 int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
 {
 	struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
-	int r, i;
+	int r;
 
 	if (bo->pin_count) {
 		bo->pin_count++;
@@ -236,9 +237,7 @@ int qxl_bo_pin(struct qxl_bo *bo, u32 do
 			*gpu_addr = qxl_bo_gpu_offset(bo);
 		return 0;
 	}
-	qxl_ttm_placement_from_domain(bo, domain);
-	for (i = 0; i < bo->placement.num_placement; i++)
-		bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+	qxl_ttm_placement_from_domain(bo, domain, true);
 	r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
 	if (likely(r == 0)) {
 		bo->pin_count = 1;
@@ -317,49 +316,12 @@ int qxl_bo_check_id(struct qxl_device *q
 	return 0;
 }
 
-void qxl_bo_list_unreserve(struct qxl_reloc_list *reloc_list, bool failed)
+int qxl_surf_evict(struct qxl_device *qdev)
 {
-	struct qxl_bo_list *entry, *sf;
-
-	list_for_each_entry_safe(entry, sf, &reloc_list->bos, lhead) {
-		qxl_bo_unreserve(entry->bo);
-		list_del(&entry->lhead);
-		kfree(entry);
-	}
+	return ttm_bo_evict_mm(&qdev->mman.bdev, TTM_PL_PRIV0);
 }
 
-int qxl_bo_list_add(struct qxl_reloc_list *reloc_list, struct qxl_bo *bo)
+int qxl_vram_evict(struct qxl_device *qdev)
 {
-	struct qxl_bo_list *entry;
-	int ret;
-
-	list_for_each_entry(entry, &reloc_list->bos, lhead) {
-		if (entry->bo == bo)
-			return 0;
-	}
-
-	entry = kmalloc(sizeof(struct qxl_bo_list), GFP_KERNEL);
-	if (!entry)
-		return -ENOMEM;
-
-	entry->bo = bo;
-	list_add(&entry->lhead, &reloc_list->bos);
-
-	ret = qxl_bo_reserve(bo, false);
-	if (ret)
-		return ret;
-
-	if (!bo->pin_count) {
-		qxl_ttm_placement_from_domain(bo, bo->type);
-		ret = ttm_bo_validate(&bo->tbo, &bo->placement,
-				      true, false);
-		if (ret)
-			return ret;
-	}
-
-	/* allocate a surface for reserved + validated buffers */
-	ret = qxl_bo_check_id(bo->gem_base.dev->dev_private, bo);
-	if (ret)
-		return ret;
-	return 0;
+	return ttm_bo_evict_mm(&qdev->mman.bdev, TTM_PL_VRAM);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_object.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_object.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_object.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_object.h	2013-08-25 20:43:22.000000000 -0400
@@ -57,11 +57,6 @@ static inline unsigned long qxl_bo_size(
 	return bo->tbo.num_pages << PAGE_SHIFT;
 }
 
-static inline bool qxl_bo_is_reserved(struct qxl_bo *bo)
-{
-	return !!atomic_read(&bo->tbo.reserved);
-}
-
 static inline u64 qxl_bo_mmap_offset(struct qxl_bo *bo)
 {
 	return bo->tbo.addr_space_offset;
@@ -93,7 +88,7 @@ static inline int qxl_bo_wait(struct qxl
 
 extern int qxl_bo_create(struct qxl_device *qdev,
 			 unsigned long size,
-			 bool kernel, u32 domain,
+			 bool kernel, bool pinned, u32 domain,
 			 struct qxl_surface *surf,
 			 struct qxl_bo **bo_ptr);
 extern int qxl_bo_kmap(struct qxl_bo *bo, void **ptr);
@@ -104,9 +99,7 @@ extern struct qxl_bo *qxl_bo_ref(struct
 extern void qxl_bo_unref(struct qxl_bo **bo);
 extern int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr);
 extern int qxl_bo_unpin(struct qxl_bo *bo);
-extern void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain);
+extern void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain, bool pinned);
 extern bool qxl_ttm_bo_is_qxl_bo(struct ttm_buffer_object *bo);
 
-extern int qxl_bo_list_add(struct qxl_reloc_list *reloc_list, struct qxl_bo *bo);
-extern void qxl_bo_list_unreserve(struct qxl_reloc_list *reloc_list, bool failed);
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_release.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_release.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_release.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_release.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,8 @@
 
 static const int release_size_per_bo[] = { RELEASE_SIZE, SURFACE_RELEASE_SIZE, RELEASE_SIZE };
 static const int releases_per_bo[] = { RELEASES_PER_BO, SURFACE_RELEASES_PER_BO, RELEASES_PER_BO };
-uint64_t
+
+static uint64_t
 qxl_release_alloc(struct qxl_device *qdev, int type,
 		  struct qxl_release **ret)
 {
@@ -53,9 +54,9 @@ qxl_release_alloc(struct qxl_device *qde
 		return 0;
 	}
 	release->type = type;
-	release->bo_count = 0;
 	release->release_offset = 0;
 	release->surface_release_id = 0;
+	INIT_LIST_HEAD(&release->bos);
 
 	idr_preload(GFP_KERNEL);
 	spin_lock(&qdev->release_idr_lock);
@@ -77,20 +78,20 @@ void
 qxl_release_free(struct qxl_device *qdev,
 		 struct qxl_release *release)
 {
-	int i;
-
-	QXL_INFO(qdev, "release %d, type %d, %d bos\n", release->id,
-		 release->type, release->bo_count);
+	struct qxl_bo_list *entry, *tmp;
+	QXL_INFO(qdev, "release %d, type %d\n", release->id,
+		 release->type);
 
 	if (release->surface_release_id)
 		qxl_surface_id_dealloc(qdev, release->surface_release_id);
 
-	for (i = 0 ; i < release->bo_count; ++i) {
+	list_for_each_entry_safe(entry, tmp, &release->bos, tv.head) {
+		struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
 		QXL_INFO(qdev, "release %llx\n",
-			release->bos[i]->tbo.addr_space_offset
+			entry->tv.bo->addr_space_offset
 						- DRM_FILE_OFFSET);
-		qxl_fence_remove_release(&release->bos[i]->fence, release->id);
-		qxl_bo_unref(&release->bos[i]);
+		qxl_fence_remove_release(&bo->fence, release->id);
+		qxl_bo_unref(&bo);
 	}
 	spin_lock(&qdev->release_idr_lock);
 	idr_remove(&qdev->release_idr, release->id);
@@ -98,83 +99,117 @@ qxl_release_free(struct qxl_device *qdev
 	kfree(release);
 }
 
-void
-qxl_release_add_res(struct qxl_device *qdev, struct qxl_release *release,
-		    struct qxl_bo *bo)
-{
-	int i;
-	for (i = 0; i < release->bo_count; i++)
-		if (release->bos[i] == bo)
-			return;
-
-	if (release->bo_count >= QXL_MAX_RES) {
-		DRM_ERROR("exceeded max resource on a qxl_release item\n");
-		return;
-	}
-	release->bos[release->bo_count++] = qxl_bo_ref(bo);
-}
-
 static int qxl_release_bo_alloc(struct qxl_device *qdev,
 				struct qxl_bo **bo)
 {
 	int ret;
-	ret = qxl_bo_create(qdev, PAGE_SIZE, false, QXL_GEM_DOMAIN_VRAM, NULL,
+	/* pin releases bo's they are too messy to evict */
+	ret = qxl_bo_create(qdev, PAGE_SIZE, false, true,
+			    QXL_GEM_DOMAIN_VRAM, NULL,
 			    bo);
 	return ret;
 }
 
-int qxl_release_reserve(struct qxl_device *qdev,
-			struct qxl_release *release, bool no_wait)
+int qxl_release_list_add(struct qxl_release *release, struct qxl_bo *bo)
+{
+	struct qxl_bo_list *entry;
+
+	list_for_each_entry(entry, &release->bos, tv.head) {
+		if (entry->tv.bo == &bo->tbo)
+			return 0;
+	}
+
+	entry = kmalloc(sizeof(struct qxl_bo_list), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	qxl_bo_ref(bo);
+	entry->tv.bo = &bo->tbo;
+	list_add_tail(&entry->tv.head, &release->bos);
+	return 0;
+}
+
+static int qxl_release_validate_bo(struct qxl_bo *bo)
 {
 	int ret;
-	if (atomic_inc_return(&release->bos[0]->reserve_count) == 1) {
-		ret = qxl_bo_reserve(release->bos[0], no_wait);
+
+	if (!bo->pin_count) {
+		qxl_ttm_placement_from_domain(bo, bo->type, false);
+		ret = ttm_bo_validate(&bo->tbo, &bo->placement,
+				      true, false);
 		if (ret)
 			return ret;
 	}
+
+	/* allocate a surface for reserved + validated buffers */
+	ret = qxl_bo_check_id(bo->gem_base.dev->dev_private, bo);
+	if (ret)
+		return ret;
 	return 0;
 }
 
-void qxl_release_unreserve(struct qxl_device *qdev,
-			  struct qxl_release *release)
+int qxl_release_reserve_list(struct qxl_release *release, bool no_intr)
 {
-	if (atomic_dec_and_test(&release->bos[0]->reserve_count))
-		qxl_bo_unreserve(release->bos[0]);
+	int ret;
+	struct qxl_bo_list *entry;
+
+	/* if only one object on the release its the release itself
+	   since these objects are pinned no need to reserve */
+	if (list_is_singular(&release->bos))
+		return 0;
+
+	ret = ttm_eu_reserve_buffers(&release->ticket, &release->bos);
+	if (ret)
+		return ret;
+
+	list_for_each_entry(entry, &release->bos, tv.head) {
+		struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
+
+		ret = qxl_release_validate_bo(bo);
+		if (ret) {
+			ttm_eu_backoff_reservation(&release->ticket, &release->bos);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+void qxl_release_backoff_reserve_list(struct qxl_release *release)
+{
+	/* if only one object on the release its the release itself
+	   since these objects are pinned no need to reserve */
+	if (list_is_singular(&release->bos))
+		return;
+
+	ttm_eu_backoff_reservation(&release->ticket, &release->bos);
 }
 
+
 int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
 				       enum qxl_surface_cmd_type surface_cmd_type,
 				       struct qxl_release *create_rel,
 				       struct qxl_release **release)
 {
-	int ret;
-
 	if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) {
 		int idr_ret;
+		struct qxl_bo_list *entry = list_first_entry(&create_rel->bos, struct qxl_bo_list, tv.head);
 		struct qxl_bo *bo;
 		union qxl_release_info *info;
 
 		/* stash the release after the create command */
 		idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
-		bo = qxl_bo_ref(create_rel->bos[0]);
+		bo = qxl_bo_ref(to_qxl_bo(entry->tv.bo));
 
 		(*release)->release_offset = create_rel->release_offset + 64;
 
-		qxl_release_add_res(qdev, *release, bo);
+		qxl_release_list_add(*release, bo);
 
-		ret = qxl_release_reserve(qdev, *release, false);
-		if (ret) {
-			DRM_ERROR("release reserve failed\n");
-			goto out_unref;
-		}
 		info = qxl_release_map(qdev, *release);
 		info->id = idr_ret;
 		qxl_release_unmap(qdev, *release, info);
 
-
-out_unref:
 		qxl_bo_unref(&bo);
-		return ret;
+		return 0;
 	}
 
 	return qxl_alloc_release_reserved(qdev, sizeof(struct qxl_surface_cmd),
@@ -187,7 +222,7 @@ int qxl_alloc_release_reserved(struct qx
 {
 	struct qxl_bo *bo;
 	int idr_ret;
-	int ret;
+	int ret = 0;
 	union qxl_release_info *info;
 	int cur_idx;
 
@@ -216,11 +251,6 @@ int qxl_alloc_release_reserved(struct qx
 			mutex_unlock(&qdev->release_mutex);
 			return ret;
 		}
-
-		/* pin releases bo's they are too messy to evict */
-		ret = qxl_bo_reserve(qdev->current_release_bo[cur_idx], false);
-		qxl_bo_pin(qdev->current_release_bo[cur_idx], QXL_GEM_DOMAIN_VRAM, NULL);
-		qxl_bo_unreserve(qdev->current_release_bo[cur_idx]);
 	}
 
 	bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]);
@@ -231,36 +261,18 @@ int qxl_alloc_release_reserved(struct qx
 	if (rbo)
 		*rbo = bo;
 
-	qxl_release_add_res(qdev, *release, bo);
-
-	ret = qxl_release_reserve(qdev, *release, false);
 	mutex_unlock(&qdev->release_mutex);
-	if (ret)
-		goto out_unref;
+
+	qxl_release_list_add(*release, bo);
 
 	info = qxl_release_map(qdev, *release);
 	info->id = idr_ret;
 	qxl_release_unmap(qdev, *release, info);
 
-out_unref:
 	qxl_bo_unref(&bo);
 	return ret;
 }
 
-int qxl_fence_releaseable(struct qxl_device *qdev,
-			  struct qxl_release *release)
-{
-	int i, ret;
-	for (i = 0; i < release->bo_count; i++) {
-		if (!release->bos[i]->tbo.sync_obj)
-			release->bos[i]->tbo.sync_obj = &release->bos[i]->fence;
-		ret = qxl_fence_add_release(&release->bos[i]->fence, release->id);
-		if (ret)
-			return ret;
-	}
-	return 0;
-}
-
 struct qxl_release *qxl_release_from_id_locked(struct qxl_device *qdev,
 						   uint64_t id)
 {
@@ -273,10 +285,7 @@ struct qxl_release *qxl_release_from_id_
 		DRM_ERROR("failed to find id in release_idr\n");
 		return NULL;
 	}
-	if (release->bo_count < 1) {
-		DRM_ERROR("read a released resource with 0 bos\n");
-		return NULL;
-	}
+
 	return release;
 }
 
@@ -285,9 +294,12 @@ union qxl_release_info *qxl_release_map(
 {
 	void *ptr;
 	union qxl_release_info *info;
-	struct qxl_bo *bo = release->bos[0];
+	struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
+	struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
 
 	ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_SIZE);
+	if (!ptr)
+		return NULL;
 	info = ptr + (release->release_offset & ~PAGE_SIZE);
 	return info;
 }
@@ -296,9 +308,51 @@ void qxl_release_unmap(struct qxl_device
 		       struct qxl_release *release,
 		       union qxl_release_info *info)
 {
-	struct qxl_bo *bo = release->bos[0];
+	struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
+	struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
 	void *ptr;
 
 	ptr = ((void *)info) - (release->release_offset & ~PAGE_SIZE);
 	qxl_bo_kunmap_atomic_page(qdev, bo, ptr);
 }
+
+void qxl_release_fence_buffer_objects(struct qxl_release *release)
+{
+	struct ttm_validate_buffer *entry;
+	struct ttm_buffer_object *bo;
+	struct ttm_bo_global *glob;
+	struct ttm_bo_device *bdev;
+	struct ttm_bo_driver *driver;
+	struct qxl_bo *qbo;
+
+	/* if only one object on the release its the release itself
+	   since these objects are pinned no need to reserve */
+	if (list_is_singular(&release->bos))
+		return;
+
+	bo = list_first_entry(&release->bos, struct ttm_validate_buffer, head)->bo;
+	bdev = bo->bdev;
+	driver = bdev->driver;
+	glob = bo->glob;
+
+	spin_lock(&glob->lru_lock);
+	spin_lock(&bdev->fence_lock);
+
+	list_for_each_entry(entry, &release->bos, head) {
+		bo = entry->bo;
+		qbo = to_qxl_bo(bo);
+
+		if (!entry->bo->sync_obj)
+			entry->bo->sync_obj = &qbo->fence;
+
+		qxl_fence_add_release_locked(&qbo->fence, release->id);
+
+		ttm_bo_add_to_lru(bo);
+		ww_mutex_unlock(&bo->resv->lock);
+		entry->reserved = false;
+	}
+	spin_unlock(&bdev->fence_lock);
+	spin_unlock(&glob->lru_lock);
+	ww_acquire_fini(&release->ticket);
+}
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_ttm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_ttm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/qxl/qxl_ttm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/qxl/qxl_ttm.c	2013-08-25 20:43:22.000000000 -0400
@@ -206,7 +206,7 @@ static void qxl_evict_flags(struct ttm_b
 		return;
 	}
 	qbo = container_of(bo, struct qxl_bo, tbo);
-	qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU);
+	qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU, false);
 	*placement = qbo->placement;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atombios_crtc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atombios_crtc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atombios_crtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atombios_crtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -555,7 +555,7 @@ static u32 atombios_adjust_pll(struct dr
 		if (rdev->family < CHIP_RV770)
 			radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
 		/* use frac fb div on APUs */
-		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
+		if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
 			radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
 		/* use frac fb div on RS780/RS880 */
 		if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
@@ -743,7 +743,7 @@ static void atombios_crtc_set_disp_eng_p
 			 * SetPixelClock provides the dividers
 			 */
 			args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
-			if (ASIC_IS_DCE61(rdev))
+			if (ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
 				args.v6.ucPpll = ATOM_EXT_PLL1;
 			else if (ASIC_IS_DCE6(rdev))
 				args.v6.ucPpll = ATOM_PPLL0;
@@ -1143,7 +1143,9 @@ static int dce4_crtc_do_set_base(struct
 	}
 
 	if (tiling_flags & RADEON_TILING_MACRO) {
-		if (rdev->family >= CHIP_TAHITI)
+		if (rdev->family >= CHIP_BONAIRE)
+			tmp = rdev->config.cik.tile_config;
+		else if (rdev->family >= CHIP_TAHITI)
 			tmp = rdev->config.si.tile_config;
 		else if (rdev->family >= CHIP_CAYMAN)
 			tmp = rdev->config.cayman.tile_config;
@@ -1170,11 +1172,29 @@ static int dce4_crtc_do_set_base(struct
 		fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
 		fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
 		fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
+		if (rdev->family >= CHIP_BONAIRE) {
+			/* XXX need to know more about the surface tiling mode */
+			fb_format |= CIK_GRPH_MICRO_TILE_MODE(CIK_DISPLAY_MICRO_TILING);
+		}
 	} else if (tiling_flags & RADEON_TILING_MICRO)
 		fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
 
-	if ((rdev->family == CHIP_TAHITI) ||
-	    (rdev->family == CHIP_PITCAIRN))
+	if (rdev->family >= CHIP_BONAIRE) {
+		u32 num_pipe_configs = rdev->config.cik.max_tile_pipes;
+		u32 num_rb = rdev->config.cik.max_backends_per_se;
+		if (num_pipe_configs > 8)
+			num_pipe_configs = 8;
+		if (num_pipe_configs == 8)
+			fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P8_32x32_16x16);
+		else if (num_pipe_configs == 4) {
+			if (num_rb == 4)
+				fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_16x16);
+			else if (num_rb < 4)
+				fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_8x16);
+		} else if (num_pipe_configs == 2)
+			fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P2);
+	} else if ((rdev->family == CHIP_TAHITI) ||
+		   (rdev->family == CHIP_PITCAIRN))
 		fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16);
 	else if (rdev->family == CHIP_VERDE)
 		fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16);
@@ -1224,8 +1244,12 @@ static int dce4_crtc_do_set_base(struct
 	WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
 	WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
 
-	WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
-	       target_fb->height);
+	if (rdev->family >= CHIP_BONAIRE)
+		WREG32(CIK_LB_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
+		       target_fb->height);
+	else
+		WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
+		       target_fb->height);
 	x &= ~3;
 	y &= ~1;
 	WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
@@ -1597,6 +1621,12 @@ static int radeon_get_shared_nondp_ppll(
  *
  * Asic specific PLL information
  *
+ * DCE 8.x
+ * KB/KV
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP)
+ * CI
+ * - PPLL0, PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
  * DCE 6.1
  * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
  * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
@@ -1623,7 +1653,47 @@ static int radeon_atom_pick_pll(struct d
 	u32 pll_in_use;
 	int pll;
 
-	if (ASIC_IS_DCE61(rdev)) {
+	if (ASIC_IS_DCE8(rdev)) {
+		if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+			if (rdev->clock.dp_extclk)
+				/* skip PPLL programming if using ext clock */
+				return ATOM_PPLL_INVALID;
+			else {
+				/* use the same PPLL for all DP monitors */
+				pll = radeon_get_shared_dp_ppll(crtc);
+				if (pll != ATOM_PPLL_INVALID)
+					return pll;
+			}
+		} else {
+			/* use the same PPLL for all monitors with the same clock */
+			pll = radeon_get_shared_nondp_ppll(crtc);
+			if (pll != ATOM_PPLL_INVALID)
+				return pll;
+		}
+		/* otherwise, pick one of the plls */
+		if ((rdev->family == CHIP_KAVERI) ||
+		    (rdev->family == CHIP_KABINI)) {
+			/* KB/KV has PPLL1 and PPLL2 */
+			pll_in_use = radeon_get_pll_use_mask(crtc);
+			if (!(pll_in_use & (1 << ATOM_PPLL2)))
+				return ATOM_PPLL2;
+			if (!(pll_in_use & (1 << ATOM_PPLL1)))
+				return ATOM_PPLL1;
+			DRM_ERROR("unable to allocate a PPLL\n");
+			return ATOM_PPLL_INVALID;
+		} else {
+			/* CI has PPLL0, PPLL1, and PPLL2 */
+			pll_in_use = radeon_get_pll_use_mask(crtc);
+			if (!(pll_in_use & (1 << ATOM_PPLL2)))
+				return ATOM_PPLL2;
+			if (!(pll_in_use & (1 << ATOM_PPLL1)))
+				return ATOM_PPLL1;
+			if (!(pll_in_use & (1 << ATOM_PPLL0)))
+				return ATOM_PPLL0;
+			DRM_ERROR("unable to allocate a PPLL\n");
+			return ATOM_PPLL_INVALID;
+		}
+	} else if (ASIC_IS_DCE61(rdev)) {
 		struct radeon_encoder_atom_dig *dig =
 			radeon_encoder->enc_priv;
 
@@ -1771,6 +1841,9 @@ int atombios_crtc_mode_set(struct drm_cr
 	atombios_crtc_set_base(crtc, x, y, old_fb);
 	atombios_overscan_setup(crtc, mode, adjusted_mode);
 	atombios_scaler_setup(crtc);
+	/* update the hw version fpr dpm */
+	radeon_crtc->hw_mode = *adjusted_mode;
+
 	return 0;
 }
 
@@ -1861,7 +1934,7 @@ static void atombios_crtc_disable(struct
 		break;
 	case ATOM_PPLL0:
 		/* disable the ppll */
-		if (ASIC_IS_DCE61(rdev))
+		if ((rdev->family == CHIP_ARUBA) || (rdev->family == CHIP_BONAIRE))
 			atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
 						  0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
 		break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atombios_dp.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atombios_dp.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atombios_dp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atombios_dp.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,6 +44,41 @@ static char *pre_emph_names[] = {
 };
 
 /***** radeon AUX functions *****/
+
+/* Atom needs data in little endian format
+ * so swap as appropriate when copying data to
+ * or from atom. Note that atom operates on
+ * dw units.
+ */
+static void radeon_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
+{
+#ifdef __BIG_ENDIAN
+	u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */
+	u32 *dst32, *src32;
+	int i;
+
+	memcpy(src_tmp, src, num_bytes);
+	src32 = (u32 *)src_tmp;
+	dst32 = (u32 *)dst_tmp;
+	if (to_le) {
+		for (i = 0; i < ((num_bytes + 3) / 4); i++)
+			dst32[i] = cpu_to_le32(src32[i]);
+		memcpy(dst, dst_tmp, num_bytes);
+	} else {
+		u8 dws = num_bytes & ~3;
+		for (i = 0; i < ((num_bytes + 3) / 4); i++)
+			dst32[i] = le32_to_cpu(src32[i]);
+		memcpy(dst, dst_tmp, dws);
+		if (num_bytes % 4) {
+			for (i = 0; i < (num_bytes % 4); i++)
+				dst[dws+i] = dst_tmp[dws+i];
+		}
+	}
+#else
+	memcpy(dst, src, num_bytes);
+#endif
+}
+
 union aux_channel_transaction {
 	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
 	PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
@@ -65,10 +100,10 @@ static int radeon_process_aux_ch(struct
 
 	base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
 
-	memcpy(base, send, send_bytes);
+	radeon_copy_swap(base, send, send_bytes, true);
 
-	args.v1.lpAuxRequest = 0 + 4;
-	args.v1.lpDataOut = 16 + 4;
+	args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4));
+	args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4));
 	args.v1.ucDataOutLen = 0;
 	args.v1.ucChannelID = chan->rec.i2c_id;
 	args.v1.ucDelay = delay / 10;
@@ -102,7 +137,7 @@ static int radeon_process_aux_ch(struct
 		recv_bytes = recv_size;
 
 	if (recv && recv_size)
-		memcpy(recv, base + 16, recv_bytes);
+		radeon_copy_swap(recv, base + 16, recv_bytes, false);
 
 	return recv_bytes;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atombios_encoders.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atombios_encoders.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atombios_encoders.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atombios_encoders.c	2013-08-25 20:43:22.000000000 -0400
@@ -186,6 +186,13 @@ void radeon_atom_backlight_init(struct r
 	u8 backlight_level;
 	char bl_name[16];
 
+	/* Mac laptops with multiple GPUs use the gmux driver for backlight
+	 * so don't register a backlight device
+	 */
+	if ((rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
+	    (rdev->pdev->device == 0x6741))
+		return;
+
 	if (!radeon_encoder->enc_priv)
 		return;
 
@@ -296,6 +303,7 @@ static inline bool radeon_encoder_is_dig
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 		return true;
 	default:
 		return false;
@@ -479,11 +487,11 @@ static u8 radeon_atom_get_bpc(struct drm
 	}
 }
 
-
 union dvo_encoder_control {
 	ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
 	DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
 	DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;
+	DVO_ENCODER_CONTROL_PS_ALLOCATION_V1_4 dvo_v4;
 };
 
 void
@@ -533,6 +541,13 @@ atombios_dvo_setup(struct drm_encoder *e
 			args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
 			args.dvo_v3.ucDVOConfig = 0; /* XXX */
 			break;
+		case 4:
+			/* DCE8 */
+			args.dvo_v4.ucAction = action;
+			args.dvo_v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+			args.dvo_v4.ucDVOConfig = 0; /* XXX */
+			args.dvo_v4.ucBitPerColor = radeon_atom_get_bpc(encoder);
+			break;
 		default:
 			DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
 			break;
@@ -915,10 +930,14 @@ atombios_dig_encoder_setup(struct drm_en
 				args.v4.ucLaneNum = 4;
 
 			if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode)) {
-				if (dp_clock == 270000)
-					args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
-				else if (dp_clock == 540000)
+				if (dp_clock == 540000)
 					args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
+				else if (dp_clock == 324000)
+					args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_3_24GHZ;
+				else if (dp_clock == 270000)
+					args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
+				else
+					args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ;
 			}
 			args.v4.acConfig.ucDigSel = dig->dig_encoder;
 			args.v4.ucBitPerColor = radeon_atom_get_bpc(encoder);
@@ -1012,6 +1031,7 @@ atombios_dig_transmitter_setup(struct dr
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 		index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
@@ -1271,6 +1291,9 @@ atombios_dig_transmitter_setup(struct dr
 				else
 					args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYE;
 				break;
+			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
+				args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYG;
+				break;
 			}
 			if (is_dp)
 				args.v5.ucLaneNum = dp_lane_count;
@@ -1735,6 +1758,7 @@ radeon_atom_encoder_dpms(struct drm_enco
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 		radeon_atom_encoder_dpms_dig(encoder, mode);
 		break;
@@ -1872,6 +1896,7 @@ atombios_set_encoder_crtc_source(struct
 			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 				dig = radeon_encoder->enc_priv;
 				switch (dig->dig_encoder) {
@@ -1893,6 +1918,9 @@ atombios_set_encoder_crtc_source(struct
 				case 5:
 					args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
 					break;
+				case 6:
+					args.v2.ucEncoderID = ASIC_INT_DIG7_ENCODER_ID;
+					break;
 				}
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
@@ -1955,7 +1983,13 @@ atombios_apply_encoder_quirks(struct drm
 	/* set scaler clears this on some chips */
 	if (ASIC_IS_AVIVO(rdev) &&
 	    (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) {
-		if (ASIC_IS_DCE4(rdev)) {
+		if (ASIC_IS_DCE8(rdev)) {
+			if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+				WREG32(CIK_LB_DATA_FORMAT + radeon_crtc->crtc_offset,
+				       CIK_INTERLEAVE_EN);
+			else
+				WREG32(CIK_LB_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
+		} else if (ASIC_IS_DCE4(rdev)) {
 			if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 				WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
 				       EVERGREEN_INTERLEAVE_EN);
@@ -2002,6 +2036,9 @@ static int radeon_atom_pick_dig_encoder(
 			else
 				return 4;
 			break;
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
+			return 6;
+			break;
 		}
 	} else if (ASIC_IS_DCE4(rdev)) {
 		/* DCE4/5 */
@@ -2086,6 +2123,7 @@ radeon_atom_encoder_init(struct radeon_d
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
 			break;
@@ -2130,6 +2168,7 @@ radeon_atom_encoder_mode_set(struct drm_
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 		/* handled in dpms */
 		break;
@@ -2395,6 +2434,7 @@ static void radeon_atom_encoder_disable(
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 		/* handled in dpms */
 		break;
@@ -2626,6 +2666,7 @@ radeon_add_atom_encoder(struct drm_devic
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
 		if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
 			radeon_encoder->rmx_type = RMX_FULL;
 			drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atombios.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atombios.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atombios.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atombios.h	2013-08-25 20:43:22.000000000 -0400
@@ -74,6 +74,8 @@
 #define ATOM_PPLL2            1
 #define ATOM_DCPLL            2
 #define ATOM_PPLL0            2
+#define ATOM_PPLL3            3
+
 #define ATOM_EXT_PLL1         8
 #define ATOM_EXT_PLL2         9
 #define ATOM_EXT_CLOCK        10
@@ -259,7 +261,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMM
   USHORT AdjustDisplayPll;											 //Atomic Table,  used by various SW componentes. 
   USHORT AdjustMemoryController;                 //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock                
   USHORT EnableASIC_StaticPwrMgt;                //Atomic Table,  only used by Bios
-  USHORT ASIC_StaticPwrMgtStatusChange;          //Obsolete ,     only used by Bios   
+  USHORT SetUniphyInstance;                      //Atomic Table,  only used by Bios   
   USHORT DAC_LoadDetection;                      //Atomic Table,  directly used by various SW components,latest version 1.2  
   USHORT LVTMAEncoderControl;                    //Atomic Table,directly used by various SW components,latest version 1.3
   USHORT HW_Misc_Operation;                      //Atomic Table,  directly used by various SW components,latest version 1.1 
@@ -271,7 +273,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMM
   USHORT TVEncoderControl;                       //Function Table,directly used by various SW components,latest version 1.1
   USHORT PatchMCSetting;                         //only used by BIOS
   USHORT MC_SEQ_Control;                         //only used by BIOS
-  USHORT TV1OutputControl;                       //Atomic Table,  Obsolete from Ry6xx, use DAC2 Output instead
+  USHORT Gfx_Harvesting;                         //Atomic Table,  Obsolete from Ry6xx, Now only used by BIOS for GFX harvesting
   USHORT EnableScaler;                           //Atomic Table,  used only by Bios
   USHORT BlankCRTC;                              //Atomic Table,  directly used by various SW components,latest version 1.1 
   USHORT EnableCRTC;                             //Atomic Table,  directly used by various SW components,latest version 1.1 
@@ -328,7 +330,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMM
 #define UNIPHYTransmitterControl			     DIG1TransmitterControl
 #define LVTMATransmitterControl				     DIG2TransmitterControl
 #define SetCRTC_DPM_State                        GetConditionalGoldenSetting
-#define SetUniphyInstance                        ASIC_StaticPwrMgtStatusChange
+#define ASIC_StaticPwrMgtStatusChange            SetUniphyInstance 
 #define HPDInterruptService                      ReadHWAssistedI2CStatus
 #define EnableVGA_Access                         GetSCLKOverMCLKRatio
 #define EnableYUV                                GetDispObjectInfo                         
@@ -338,7 +340,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMM
 #define TMDSAEncoderControl                      PatchMCSetting
 #define LVDSEncoderControl                       MC_SEQ_Control
 #define LCD1OutputControl                        HW_Misc_Operation
-
+#define TV1OutputControl                         Gfx_Harvesting
 
 typedef struct _ATOM_MASTER_COMMAND_TABLE
 {
@@ -478,11 +480,11 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PL
 typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4
 {
 #if ATOM_BIG_ENDIAN
-  ULONG  ucPostDiv;          //return parameter: post divider which is used to program to register directly
+  ULONG  ucPostDiv:8;        //return parameter: post divider which is used to program to register directly
   ULONG  ulClock:24;         //Input= target clock, output = actual clock 
 #else
   ULONG  ulClock:24;         //Input= target clock, output = actual clock 
-  ULONG  ucPostDiv;          //return parameter: post divider which is used to program to register directly
+  ULONG  ucPostDiv:8;        //return parameter: post divider which is used to program to register directly
 #endif
 }COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4;
 
@@ -504,6 +506,32 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PL
   UCHAR   ucReserved;                       
 }COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5;
 
+
+typedef struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6
+{
+  ATOM_COMPUTE_CLOCK_FREQ  ulClock;         //Input Parameter
+  ULONG   ulReserved[2];
+}COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6;
+
+//ATOM_COMPUTE_CLOCK_FREQ.ulComputeClockFlag
+#define COMPUTE_GPUCLK_INPUT_FLAG_CLK_TYPE_MASK            0x0f
+#define COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK           0x00
+#define COMPUTE_GPUCLK_INPUT_FLAG_SCLK                     0x01
+
+typedef struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6
+{
+  COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4  ulClock;         //Output Parameter: ucPostDiv=DFS divider
+  ATOM_S_MPLL_FB_DIVIDER   ulFbDiv;         //Output Parameter: PLL FB divider
+  UCHAR   ucPllRefDiv;                      //Output Parameter: PLL ref divider      
+  UCHAR   ucPllPostDiv;                     //Output Parameter: PLL post divider      
+  UCHAR   ucPllCntlFlag;                    //Output Flags: control flag
+  UCHAR   ucReserved;                       
+}COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6;
+
+//ucPllCntlFlag
+#define SPLL_CNTL_FLAG_VCO_MODE_MASK            0x03 
+
+
 // ucInputFlag
 #define ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN  1   // 1-StrobeMode, 0-PerformanceMode
 
@@ -1686,6 +1714,7 @@ typedef struct _PIXEL_CLOCK_PARAMETERS_V
 #define PIXEL_CLOCK_V6_MISC_HDMI_30BPP              0x08
 #define PIXEL_CLOCK_V6_MISC_HDMI_48BPP              0x0c
 #define PIXEL_CLOCK_V6_MISC_REF_DIV_SRC             0x10
+#define PIXEL_CLOCK_V6_MISC_GEN_DPREFCLK            0x40
 
 typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2
 {
@@ -2102,6 +2131,17 @@ typedef struct _DVO_ENCODER_CONTROL_PARA
 }DVO_ENCODER_CONTROL_PARAMETERS_V3;
 #define DVO_ENCODER_CONTROL_PS_ALLOCATION_V3	DVO_ENCODER_CONTROL_PARAMETERS_V3
 
+typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V1_4
+{
+  USHORT usPixelClock; 
+  UCHAR  ucDVOConfig;
+  UCHAR  ucAction;														//ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT
+  UCHAR  ucBitPerColor;                       //please refer to definition of PANEL_xBIT_PER_COLOR
+  UCHAR  ucReseved[3];
+}DVO_ENCODER_CONTROL_PARAMETERS_V1_4;
+#define DVO_ENCODER_CONTROL_PS_ALLOCATION_V1_4	DVO_ENCODER_CONTROL_PARAMETERS_V1_4
+
+
 //ucTableFormatRevision=1
 //ucTableContentRevision=3 structure is not changed but usMisc add bit 1 as another input for 
 // bit1=0: non-coherent mode
@@ -2165,7 +2205,7 @@ typedef struct _DVO_ENCODER_CONTROL_PARA
 #define SET_ASIC_VOLTAGE_MODE_SOURCE_B         0x4
 
 #define	SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE      0x0
-#define	SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL      0x1	
+#define	SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL      0x1
 #define	SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK     0x2
 
 typedef struct	_SET_VOLTAGE_PARAMETERS
@@ -2200,15 +2240,20 @@ typedef struct	_SET_VOLTAGE_PARAMETERS_V
 //SET_VOLTAGE_PARAMETERS_V3.ucVoltageMode
 #define ATOM_SET_VOLTAGE                     0        //Set voltage Level
 #define ATOM_INIT_VOLTAGE_REGULATOR          3        //Init Regulator
-#define ATOM_SET_VOLTAGE_PHASE               4        //Set Vregulator Phase
-#define ATOM_GET_MAX_VOLTAGE                 6        //Get Max Voltage, not used in SetVoltageTable v1.3
-#define ATOM_GET_VOLTAGE_LEVEL               6        //Get Voltage level from vitual voltage ID
+#define ATOM_SET_VOLTAGE_PHASE               4        //Set Vregulator Phase, only for SVID/PVID regulator
+#define ATOM_GET_MAX_VOLTAGE                 6        //Get Max Voltage, not used from SetVoltageTable v1.3
+#define ATOM_GET_VOLTAGE_LEVEL               6        //Get Voltage level from vitual voltage ID, not used for SetVoltage v1.4
+#define ATOM_GET_LEAKAGE_ID                  8        //Get Leakage Voltage Id ( starting from SMU7x IP ), SetVoltage v1.4 
 
 // define vitual voltage id in usVoltageLevel
 #define ATOM_VIRTUAL_VOLTAGE_ID0             0xff01
 #define ATOM_VIRTUAL_VOLTAGE_ID1             0xff02
 #define ATOM_VIRTUAL_VOLTAGE_ID2             0xff03
 #define ATOM_VIRTUAL_VOLTAGE_ID3             0xff04
+#define ATOM_VIRTUAL_VOLTAGE_ID4             0xff05
+#define ATOM_VIRTUAL_VOLTAGE_ID5             0xff06
+#define ATOM_VIRTUAL_VOLTAGE_ID6             0xff07
+#define ATOM_VIRTUAL_VOLTAGE_ID7             0xff08
 
 typedef struct _SET_VOLTAGE_PS_ALLOCATION
 {
@@ -2628,7 +2673,8 @@ typedef struct _ATOM_FIRMWARE_INFO_V2_2
   ULONG                           ulFirmwareRevision;
   ULONG                           ulDefaultEngineClock;       //In 10Khz unit
   ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
-  ULONG                           ulReserved[2];
+  ULONG                           ulSPLL_OutputFreq;          //In 10Khz unit  
+  ULONG                           ulGPUPLL_OutputFreq;        //In 10Khz unit
   ULONG                           ulReserved1;                //Was ulMaxEngineClockPLL_Output; //In 10Khz unit*
   ULONG                           ulReserved2;                //Was ulMaxMemoryClockPLL_Output; //In 10Khz unit*
   ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
@@ -3813,6 +3859,12 @@ typedef struct _ATOM_GPIO_PIN_ASSIGNMENT
   UCHAR                    ucGPIO_ID;
 }ATOM_GPIO_PIN_ASSIGNMENT;
 
+//ucGPIO_ID pre-define id for multiple usage
+//from SMU7.x, if ucGPIO_ID=PP_AC_DC_SWITCH_GPIO_PINID in GPIO_LUTTable, AC/DC swithing feature is enable
+#define PP_AC_DC_SWITCH_GPIO_PINID          60
+//from SMU7.x, if ucGPIO_ID=VDDC_REGULATOR_VRHOT_GPIO_PINID in GPIO_LUTable, VRHot feature is enable
+#define VDDC_VRHOT_GPIO_PINID               61
+
 typedef struct _ATOM_GPIO_PIN_LUT
 {
   ATOM_COMMON_TABLE_HEADER  sHeader;
@@ -4074,17 +4126,19 @@ typedef struct _EXT_DISPLAY_PATH
 
 //usCaps
 #define  EXT_DISPLAY_PATH_CAPS__HBR2_DISABLE          0x01
+#define  EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN        0x02
 
 typedef  struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO
 {
   ATOM_COMMON_TABLE_HEADER sHeader;
   UCHAR                    ucGuid [NUMBER_OF_UCHAR_FOR_GUID];     // a GUID is a 16 byte long string
   EXT_DISPLAY_PATH         sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries.
-  UCHAR                    ucChecksum;                            // a  simple Checksum of the sum of whole structure equal to 0x0. 
+  UCHAR                    ucChecksum;                            // a simple Checksum of the sum of whole structure equal to 0x0. 
   UCHAR                    uc3DStereoPinId;                       // use for eDP panel
   UCHAR                    ucRemoteDisplayConfig;
   UCHAR                    uceDPToLVDSRxId;
-  UCHAR                    Reserved[4];                           // for potential expansion
+  UCHAR                    ucFixDPVoltageSwing;                   // usCaps[1]=1, this indicate DP_LANE_SET value
+  UCHAR                    Reserved[3];                           // for potential expansion
 }ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO;
 
 //Related definitions, all records are different but they have a commond header
@@ -4416,6 +4470,13 @@ typedef struct _ATOM_VOLTAGE_CONTROL
 #define	VOLTAGE_CONTROL_ID_CHL822x						0x08									
 #define	VOLTAGE_CONTROL_ID_VT1586M						0x09
 #define VOLTAGE_CONTROL_ID_UP1637 						0x0A
+#define	VOLTAGE_CONTROL_ID_CHL8214            0x0B
+#define	VOLTAGE_CONTROL_ID_UP1801             0x0C
+#define	VOLTAGE_CONTROL_ID_ST6788A            0x0D
+#define VOLTAGE_CONTROL_ID_CHLIR3564SVI2      0x0E
+#define VOLTAGE_CONTROL_ID_AD527x      	      0x0F
+#define VOLTAGE_CONTROL_ID_NCP81022    	      0x10
+#define VOLTAGE_CONTROL_ID_LTC2635			  0x11
 
 typedef struct  _ATOM_VOLTAGE_OBJECT
 {
@@ -4458,6 +4519,15 @@ typedef struct _ATOM_VOLTAGE_OBJECT_HEAD
 	 USHORT		usSize;													//Size of Object	
 }ATOM_VOLTAGE_OBJECT_HEADER_V3;
 
+// ATOM_VOLTAGE_OBJECT_HEADER_V3.ucVoltageMode
+#define VOLTAGE_OBJ_GPIO_LUT                 0        //VOLTAGE and GPIO Lookup table ->ATOM_GPIO_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_VR_I2C_INIT_SEQ          3        //VOLTAGE REGULATOR INIT sequece through I2C -> ATOM_I2C_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_PHASE_LUT                4        //Set Vregulator Phase lookup table ->ATOM_GPIO_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_SVID2                    7        //Indicate voltage control by SVID2 ->ATOM_SVID2_VOLTAGE_OBJECT_V3
+#define	VOLTAGE_OBJ_PWRBOOST_LEAKAGE_LUT     0x10     //Powerboost Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
+#define	VOLTAGE_OBJ_HIGH_STATE_LEAKAGE_LUT   0x11     //High voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_HIGH1_STATE_LEAKAGE_LUT  0x12     //High1 voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
+
 typedef struct  _VOLTAGE_LUT_ENTRY_V2
 {
 	 ULONG		ulVoltageId;									  // The Voltage ID which is used to program GPIO register
@@ -4473,7 +4543,7 @@ typedef struct  _LEAKAGE_VOLTAGE_LUT_ENT
 
 typedef struct  _ATOM_I2C_VOLTAGE_OBJECT_V3
 {
-   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;
+   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;    // voltage mode = VOLTAGE_OBJ_VR_I2C_INIT_SEQ
    UCHAR	ucVoltageRegulatorId;					  //Indicate Voltage Regulator Id
    UCHAR    ucVoltageControlI2cLine;
    UCHAR    ucVoltageControlAddress;
@@ -4484,7 +4554,7 @@ typedef struct  _ATOM_I2C_VOLTAGE_OBJECT
 
 typedef struct  _ATOM_GPIO_VOLTAGE_OBJECT_V3
 {
-   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;   
+   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;   // voltage mode = VOLTAGE_OBJ_GPIO_LUT or VOLTAGE_OBJ_PHASE_LUT
    UCHAR    ucVoltageGpioCntlId;         // default is 0 which indicate control through CG VID mode 
    UCHAR    ucGpioEntryNum;              // indiate the entry numbers of Votlage/Gpio value Look up table
    UCHAR    ucPhaseDelay;                // phase delay in unit of micro second
@@ -4495,7 +4565,7 @@ typedef struct  _ATOM_GPIO_VOLTAGE_OBJEC
 
 typedef struct  _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
 {
-   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;
+   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;    // voltage mode = 0x10/0x11/0x12
    UCHAR    ucLeakageCntlId;             // default is 0
    UCHAR    ucLeakageEntryNum;           // indicate the entry number of LeakageId/Voltage Lut table
    UCHAR    ucReserved[2];               
@@ -4503,10 +4573,26 @@ typedef struct  _ATOM_LEAKAGE_VOLTAGE_OB
    LEAKAGE_VOLTAGE_LUT_ENTRY_V2 asLeakageIdLut[1];   
 }ATOM_LEAKAGE_VOLTAGE_OBJECT_V3;
 
+
+typedef struct  _ATOM_SVID2_VOLTAGE_OBJECT_V3
+{
+   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;    // voltage mode = VOLTAGE_OBJ_SVID2
+// 14:7  PSI0_VID
+// 6  PSI0_EN
+// 5  PSI1
+// 4:2  load line slope trim. 
+// 1:0  offset trim, 
+   USHORT   usLoadLine_PSI;    
+// GPU GPIO pin Id to SVID2 regulator VRHot pin. possible value 0~31. 0 means GPIO0, 31 means GPIO31
+   UCHAR    ucReserved[2];
+   ULONG    ulReserved;
+}ATOM_SVID2_VOLTAGE_OBJECT_V3;
+
 typedef union _ATOM_VOLTAGE_OBJECT_V3{
   ATOM_GPIO_VOLTAGE_OBJECT_V3 asGpioVoltageObj;
   ATOM_I2C_VOLTAGE_OBJECT_V3 asI2cVoltageObj;
   ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 asLeakageObj;
+  ATOM_SVID2_VOLTAGE_OBJECT_V3 asSVID2Obj;
 }ATOM_VOLTAGE_OBJECT_V3;
 
 typedef struct  _ATOM_VOLTAGE_OBJECT_INFO_V3_1
@@ -4536,6 +4622,21 @@ typedef struct  _ATOM_ASIC_PROFILING_INF
 	ATOM_ASIC_PROFILE_VOLTAGE			asVoltage;
 }ATOM_ASIC_PROFILING_INFO;
 
+typedef struct  _ATOM_ASIC_PROFILING_INFO_V2_1
+{
+  ATOM_COMMON_TABLE_HEADER			asHeader; 
+  UCHAR  ucLeakageBinNum;                // indicate the entry number of LeakageId/Voltage Lut table
+  USHORT usLeakageBinArrayOffset;        // offset of USHORT Leakage Bin list array ( from lower LeakageId to higher) 
+
+  UCHAR  ucElbVDDC_Num;               
+  USHORT usElbVDDC_IdArrayOffset;        // offset of USHORT virtual VDDC voltage id ( 0xff01~0xff08 )
+  USHORT usElbVDDC_LevelArrayOffset;     // offset of 2 dimension voltage level USHORT array
+
+  UCHAR  ucElbVDDCI_Num;
+  USHORT usElbVDDCI_IdArrayOffset;       // offset of USHORT virtual VDDCI voltage id ( 0xff01~0xff08 )
+  USHORT usElbVDDCI_LevelArrayOffset;    // offset of 2 dimension voltage level USHORT array
+}ATOM_ASIC_PROFILING_INFO_V2_1;
+
 typedef struct _ATOM_POWER_SOURCE_OBJECT
 {
 	UCHAR	ucPwrSrcId;													// Power source
@@ -4652,6 +4753,8 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_I
 #define SYS_INFO_LVDSMISC__888_BPC                                                   0x04
 #define SYS_INFO_LVDSMISC__OVERRIDE_EN                                               0x08
 #define SYS_INFO_LVDSMISC__BLON_ACTIVE_LOW                                           0x10
+// new since Trinity
+#define SYS_INFO_LVDSMISC__TRAVIS_LVDS_VOL_OVERRIDE_EN                               0x20
 
 // not used any more
 #define SYS_INFO_LVDSMISC__VSYNC_ACTIVE_LOW                                          0x04
@@ -4752,6 +4855,29 @@ typedef struct _ATOM_FUSION_SYSTEM_INFO_
   ATOM_INTEGRATED_SYSTEM_INFO_V6    sIntegratedSysInfo;   
   ULONG  ulPowerplayTable[128];  
 }ATOM_FUSION_SYSTEM_INFO_V1; 
+
+
+typedef struct _ATOM_TDP_CONFIG_BITS
+{
+#if ATOM_BIG_ENDIAN
+  ULONG   uReserved:2;
+  ULONG   uTDP_Value:14;  // Original TDP value in tens of milli watts
+  ULONG   uCTDP_Value:14; // Override value in tens of milli watts
+  ULONG   uCTDP_Enable:2; // = (uCTDP_Value > uTDP_Value? 2: (uCTDP_Value < uTDP_Value))
+#else
+  ULONG   uCTDP_Enable:2; // = (uCTDP_Value > uTDP_Value? 2: (uCTDP_Value < uTDP_Value))
+  ULONG   uCTDP_Value:14; // Override value in tens of milli watts
+  ULONG   uTDP_Value:14;  // Original TDP value in tens of milli watts
+  ULONG   uReserved:2;
+#endif
+}ATOM_TDP_CONFIG_BITS;
+
+typedef union _ATOM_TDP_CONFIG
+{
+  ATOM_TDP_CONFIG_BITS TDP_config;
+  ULONG            TDP_config_all;
+}ATOM_TDP_CONFIG;
+
 /**********************************************************************************************************************
   ATOM_FUSION_SYSTEM_INFO_V1 Description
 sIntegratedSysInfo:               refer to ATOM_INTEGRATED_SYSTEM_INFO_V6 definition.
@@ -4784,7 +4910,8 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_I
   UCHAR  ucMemoryType;  
   UCHAR  ucUMAChannelNumber;
   UCHAR  strVBIOSMsg[40];
-  ULONG  ulReserved[20];
+  ATOM_TDP_CONFIG  asTdpConfig;
+  ULONG  ulReserved[19];
   ATOM_AVAILABLE_SCLK_LIST   sAvail_SCLK[5];
   ULONG  ulGMCRestoreResetTime;
   ULONG  ulMinimumNClk;
@@ -4809,7 +4936,7 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_I
   USHORT GnbTdpLimit;
   USHORT usMaxLVDSPclkFreqInSingleLink;
   UCHAR  ucLvdsMisc;
-  UCHAR  ucLVDSReserved;
+  UCHAR  ucTravisLVDSVolAdjust;
   UCHAR  ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
   UCHAR  ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
   UCHAR  ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
@@ -4817,7 +4944,7 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_I
   UCHAR  ucLVDSOffToOnDelay_in4Ms;
   UCHAR  ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
   UCHAR  ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
-  UCHAR  ucLVDSReserved1;
+  UCHAR  ucMinAllowedBL_Level;
   ULONG  ulLCDBitDepthControlVal;
   ULONG  ulNbpStateMemclkFreq[4];
   USHORT usNBP2Voltage;               
@@ -4846,6 +4973,7 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_I
 #define SYS_INFO_GPUCAPS__TMDSHDMI_COHERENT_SINGLEPLL_MODE                0x01
 #define SYS_INFO_GPUCAPS__DP_SINGLEPLL_MODE                               0x02
 #define SYS_INFO_GPUCAPS__DISABLE_AUX_MODE_DETECT                         0x08
+#define SYS_INFO_GPUCAPS__ENABEL_DFS_BYPASS                               0x10
 
 /**********************************************************************************************************************
   ATOM_INTEGRATED_SYSTEM_INFO_V1_7 Description
@@ -4945,6 +5073,9 @@ ucLVDSMisc:                       [bit0]
                                   [bit2] LVDS 888bit per color mode  =0: 666 bit per color =1:888 bit per color
                                   [bit3] LVDS parameter override enable  =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used
                                   [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low )
+                                  [bit5] Travid LVDS output voltage override enable, when =1, use ucTravisLVDSVolAdjust value to overwrite Traivs register LVDS_CTRL_4
+ucTravisLVDSVolAdjust             When ucLVDSMisc[5]=1,it means platform SBIOS want to overwrite TravisLVDSVoltage. Then VBIOS will use ucTravisLVDSVolAdjust 
+                                  value to program Travis register LVDS_CTRL_4
 ucLVDSPwrOnSeqDIGONtoDE_in4Ms:    LVDS power up sequence time in unit of 4ms, time delay from DIGON signal active to data enable signal active( DE ).
                                   =0 mean use VBIOS default which is 8 ( 32ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON. 
                                   This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
@@ -4964,18 +5095,241 @@ ucLVDSOffToOnDelay_in4Ms:         LVDS p
                                   =0 means to use VBIOS default delay which is 125 ( 500ms ).
                                   This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
 
-ucLVDSPwrOnVARY_BLtoBLON_in4Ms:   LVDS power up sequence time in unit of 4ms. Time delay from VARY_BL signal on to DLON signal active. 
+ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms:
+                                  LVDS power up sequence time in unit of 4ms. Time delay from VARY_BL signal on to DLON signal active. 
                                   =0 means to use VBIOS default delay which is 0 ( 0ms ).
                                   This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
 
-ucLVDSPwrOffBLONtoVARY_BL_in4Ms:  LVDS power down sequence time in unit of 4ms. Time delay from BLON signal off to VARY_BL signal off. 
+ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms:  
+                                  LVDS power down sequence time in unit of 4ms. Time delay from BLON signal off to VARY_BL signal off. 
                                   =0 means to use VBIOS default delay which is 0 ( 0ms ).
                                   This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
 
+ucMinAllowedBL_Level:             Lowest LCD backlight PWM level. This is customer platform specific parameters. By default it is 0. 
+
 ulNbpStateMemclkFreq[4]:          system memory clock frequncey in unit of 10Khz in different NB pstate. 
 
 **********************************************************************************************************************/
 
+// this IntegrateSystemInfoTable is used for Kaveri & Kabini APU
+typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  ULONG  ulBootUpEngineClock;
+  ULONG  ulDentistVCOFreq;
+  ULONG  ulBootUpUMAClock;
+  ATOM_CLK_VOLT_CAPABILITY   sDISPCLK_Voltage[4];
+  ULONG  ulBootUpReqDisplayVector;
+  ULONG  ulVBIOSMisc;
+  ULONG  ulGPUCapInfo;
+  ULONG  ulDISP_CLK2Freq;
+  USHORT usRequestedPWMFreqInHz;
+  UCHAR  ucHtcTmpLmt;
+  UCHAR  ucHtcHystLmt;
+  ULONG  ulReserved2;
+  ULONG  ulSystemConfig;            
+  ULONG  ulCPUCapInfo;
+  ULONG  ulReserved3;
+  USHORT usGPUReservedSysMemSize;
+  USHORT usExtDispConnInfoOffset;
+  USHORT usPanelRefreshRateRange;     
+  UCHAR  ucMemoryType;  
+  UCHAR  ucUMAChannelNumber;
+  UCHAR  strVBIOSMsg[40];
+  ATOM_TDP_CONFIG  asTdpConfig;
+  ULONG  ulReserved[19];
+  ATOM_AVAILABLE_SCLK_LIST   sAvail_SCLK[5];
+  ULONG  ulGMCRestoreResetTime;
+  ULONG  ulReserved4;
+  ULONG  ulIdleNClk;
+  ULONG  ulDDR_DLL_PowerUpTime;
+  ULONG  ulDDR_PLL_PowerUpTime;
+  USHORT usPCIEClkSSPercentage;
+  USHORT usPCIEClkSSType;
+  USHORT usLvdsSSPercentage;
+  USHORT usLvdsSSpreadRateIn10Hz;
+  USHORT usHDMISSPercentage;
+  USHORT usHDMISSpreadRateIn10Hz;
+  USHORT usDVISSPercentage;
+  USHORT usDVISSpreadRateIn10Hz;
+  ULONG  ulGPUReservedSysMemBaseAddrLo;
+  ULONG  ulGPUReservedSysMemBaseAddrHi;
+  ULONG  ulReserved5[3];
+  USHORT usMaxLVDSPclkFreqInSingleLink;
+  UCHAR  ucLvdsMisc;
+  UCHAR  ucTravisLVDSVolAdjust;
+  UCHAR  ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
+  UCHAR  ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
+  UCHAR  ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
+  UCHAR  ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
+  UCHAR  ucLVDSOffToOnDelay_in4Ms;
+  UCHAR  ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
+  UCHAR  ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
+  UCHAR  ucMinAllowedBL_Level;
+  ULONG  ulLCDBitDepthControlVal;
+  ULONG  ulNbpStateMemclkFreq[4];
+  ULONG  ulReserved6;               
+  ULONG  ulNbpStateNClkFreq[4];
+  USHORT usNBPStateVoltage[4];            
+  USHORT usBootUpNBVoltage;   
+  USHORT usReserved2; 
+  ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo;
+}ATOM_INTEGRATED_SYSTEM_INFO_V1_8;
+
+/**********************************************************************************************************************
+  ATOM_INTEGRATED_SYSTEM_INFO_V1_8 Description
+ulBootUpEngineClock:              VBIOS bootup Engine clock frequency, in 10kHz unit. if it is equal 0, then VBIOS use pre-defined bootup engine clock
+ulDentistVCOFreq:                 Dentist VCO clock in 10kHz unit. 
+ulBootUpUMAClock:                 System memory boot up clock frequency in 10Khz unit. 
+sDISPCLK_Voltage:                 Report Display clock frequency requirement on GNB voltage(up to 4 voltage levels).
+ 
+ulBootUpReqDisplayVector:         VBIOS boot up display IDs, following are supported devices in Trinity projects:
+                                  ATOM_DEVICE_CRT1_SUPPORT                  0x0001
+                                  ATOM_DEVICE_DFP1_SUPPORT                  0x0008
+                                  ATOM_DEVICE_DFP6_SUPPORT                  0x0040
+                                  ATOM_DEVICE_DFP2_SUPPORT                  0x0080
+                                  ATOM_DEVICE_DFP3_SUPPORT                  0x0200
+                                  ATOM_DEVICE_DFP4_SUPPORT                  0x0400
+                                  ATOM_DEVICE_DFP5_SUPPORT                  0x0800
+                                  ATOM_DEVICE_LCD1_SUPPORT                  0x0002
+
+ulVBIOSMisc:      	              Miscellenous flags for VBIOS requirement and interface 
+                                  bit[0]=0: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is not supported by SBIOS. 
+                                        =1: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is supported by SBIOS.
+                                  bit[1]=0: INT15 callback function Get boot display( ax=4e08, bl=01h) is not supported by SBIOS
+                                        =1: INT15 callback function Get boot display( ax=4e08, bl=01h) is supported by SBIOS
+                                  bit[2]=0: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is not supported by SBIOS
+                                        =1: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is supported by SBIOS
+                                  bit[3]=0: VBIOS fast boot is disable
+                                        =1: VBIOS fast boot is enable. ( VBIOS skip display device detection in every set mode if LCD panel is connect and LID is open)
+
+ulGPUCapInfo:                     bit[0~2]= Reserved
+                                  bit[3]=0: Enable AUX HW mode detection logic
+                                        =1: Disable AUX HW mode detection logic
+                                  bit[4]=0: Disable DFS bypass feature
+                                        =1: Enable DFS bypass feature
+
+usRequestedPWMFreqInHz:           When it's set to 0x0 by SBIOS: the LCD BackLight is not controlled by GPU(SW). 
+                                  Any attempt to change BL using VBIOS function or enable VariBri from PP table is not effective since ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==0;
+                                  
+                                  When it's set to a non-zero frequency, the BackLight is controlled by GPU (SW) in one of two ways below:
+                                  1. SW uses the GPU BL PWM output to control the BL, in chis case, this non-zero frequency determines what freq GPU should use;
+                                  VBIOS will set up proper PWM frequency and ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1,as the result,
+                                  Changing BL using VBIOS function is functional in both driver and non-driver present environment; 
+                                  and enabling VariBri under the driver environment from PP table is optional.
+
+                                  2. SW uses other means to control BL (like DPCD),this non-zero frequency serves as a flag only indicating
+                                  that BL control from GPU is expected.
+                                  VBIOS will NOT set up PWM frequency but make ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1
+                                  Changing BL using VBIOS function could be functional in both driver and non-driver present environment,but
+                                  it's per platform 
+                                  and enabling VariBri under the driver environment from PP table is optional.
+
+ucHtcTmpLmt:                      Refer to D18F3x64 bit[22:16], HtcTmpLmt. Threshold on value to enter HTC_active state.
+ucHtcHystLmt:                     Refer to D18F3x64 bit[27:24], HtcHystLmt. 
+                                  To calculate threshold off value to exit HTC_active state, which is Threshold on vlaue minus ucHtcHystLmt.
+
+ulSystemConfig:                   Bit[0]=0: PCIE Power Gating Disabled 
+                                        =1: PCIE Power Gating Enabled
+                                  Bit[1]=0: DDR-DLL shut-down feature disabled.
+                                         1: DDR-DLL shut-down feature enabled.
+                                  Bit[2]=0: DDR-PLL Power down feature disabled.
+                                         1: DDR-PLL Power down feature enabled. 
+                                  Bit[3]=0: GNB DPM is disabled
+                                        =1: GNB DPM is enabled                                
+ulCPUCapInfo:                     TBD
+
+usExtDispConnInfoOffset:          Offset to sExtDispConnInfo inside the structure
+usPanelRefreshRateRange:          Bit vector for LCD supported refresh rate range. If DRR is requestd by the platform, at least two bits need to be set
+                                  to indicate a range.
+                                  SUPPORTED_LCD_REFRESHRATE_30Hz          0x0004
+                                  SUPPORTED_LCD_REFRESHRATE_40Hz          0x0008
+                                  SUPPORTED_LCD_REFRESHRATE_50Hz          0x0010
+                                  SUPPORTED_LCD_REFRESHRATE_60Hz          0x0020
+
+ucMemoryType:                     [3:0]=1:DDR1;=2:DDR2;=3:DDR3;=5:GDDR5; [7:4] is reserved.
+ucUMAChannelNumber:      	        System memory channel numbers. 
+
+strVBIOSMsg[40]:                  VBIOS boot up customized message string 
+
+sAvail_SCLK[5]:                   Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high  
+
+ulGMCRestoreResetTime:            GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns. 
+ulIdleNClk:                       NCLK speed while memory runs in self-refresh state, used to calculate self-refresh latency. Unit in 10kHz.
+ulDDR_DLL_PowerUpTime:            DDR PHY DLL power up time. Unit in ns.
+ulDDR_PLL_PowerUpTime:            DDR PHY PLL power up time. Unit in ns.
+
+usPCIEClkSSPercentage:            PCIE Clock Spread Spectrum Percentage in unit 0.01%; 100 mean 1%.
+usPCIEClkSSType:                  PCIE Clock Spread Spectrum Type. 0 for Down spread(default); 1 for Center spread.
+usLvdsSSPercentage:               LVDS panel ( not include eDP ) Spread Spectrum Percentage in unit of 0.01%, =0, use VBIOS default setting. 
+usLvdsSSpreadRateIn10Hz:          LVDS panel ( not include eDP ) Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. 
+usHDMISSPercentage:               HDMI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%,  =0, use VBIOS default setting. 
+usHDMISSpreadRateIn10Hz:          HDMI Spread Spectrum frequency in unit of 10Hz,  =0, use VBIOS default setting. 
+usDVISSPercentage:                DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%,  =0, use VBIOS default setting. 
+usDVISSpreadRateIn10Hz:           DVI Spread Spectrum frequency in unit of 10Hz,  =0, use VBIOS default setting. 
+
+usGPUReservedSysMemSize:          Reserved system memory size for ACP engine in APU GNB, units in MB. 0/2/4MB based on CMOS options, current default could be 0MB. KV only, not on KB.
+ulGPUReservedSysMemBaseAddrLo:    Low 32 bits base address to the reserved system memory. 
+ulGPUReservedSysMemBaseAddrHi:    High 32 bits base address to the reserved system memory. 
+
+usMaxLVDSPclkFreqInSingleLink:    Max pixel clock LVDS panel single link, if=0 means VBIOS use default threhold, right now it is 85Mhz
+ucLVDSMisc:                       [bit0] LVDS 888bit panel mode =0: LVDS 888 panel in LDI mode, =1: LVDS 888 panel in FPDI mode
+                                  [bit1] LVDS panel lower and upper link mapping =0: lower link and upper link not swap, =1: lower link and upper link are swapped
+                                  [bit2] LVDS 888bit per color mode  =0: 666 bit per color =1:888 bit per color
+                                  [bit3] LVDS parameter override enable  =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used
+                                  [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low )
+                                  [bit5] Travid LVDS output voltage override enable, when =1, use ucTravisLVDSVolAdjust value to overwrite Traivs register LVDS_CTRL_4
+ucTravisLVDSVolAdjust             When ucLVDSMisc[5]=1,it means platform SBIOS want to overwrite TravisLVDSVoltage. Then VBIOS will use ucTravisLVDSVolAdjust 
+                                  value to program Travis register LVDS_CTRL_4
+ucLVDSPwrOnSeqDIGONtoDE_in4Ms:    
+                                  LVDS power up sequence time in unit of 4ms, time delay from DIGON signal active to data enable signal active( DE ).
+                                  =0 mean use VBIOS default which is 8 ( 32ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON. 
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSPwrOnDEtoVARY_BL_in4Ms:     
+                                  LVDS power up sequence time in unit of 4ms., time delay from DE( data enable ) active to Vary Brightness enable signal active( VARY_BL ).  
+                                  =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON. 
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSPwrOffVARY_BLtoDE_in4Ms:    
+                                  LVDS power down sequence time in unit of 4ms, time delay from data enable ( DE ) signal off to LCDVCC (DIGON) off. 
+                                  =0 mean use VBIOS default delay which is 8 ( 32ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSPwrOffDEtoDIGON_in4Ms:      
+                                   LVDS power down sequence time in unit of 4ms, time delay from vary brightness enable signal( VARY_BL) off to data enable ( DE ) signal off. 
+                                  =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSOffToOnDelay_in4Ms:         
+                                  LVDS power down sequence time in unit of 4ms. Time delay from DIGON signal off to DIGON signal active. 
+                                  =0 means to use VBIOS default delay which is 125 ( 500ms ).
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms:
+                                  LVDS power up sequence time in unit of 4ms. Time delay from VARY_BL signal on to DLON signal active. 
+                                  =0 means to use VBIOS default delay which is 0 ( 0ms ).
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+
+ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms:  
+                                  LVDS power down sequence time in unit of 4ms. Time delay from BLON signal off to VARY_BL signal off. 
+                                  =0 means to use VBIOS default delay which is 0 ( 0ms ).
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucMinAllowedBL_Level:             Lowest LCD backlight PWM level. This is customer platform specific parameters. By default it is 0. 
+
+ulLCDBitDepthControlVal:          GPU display control encoder bit dither control setting, used to program register mmFMT_BIT_DEPTH_CONTROL
+
+ulNbpStateMemclkFreq[4]:          system memory clock frequncey in unit of 10Khz in different NB P-State(P0, P1, P2 & P3).
+ulNbpStateNClkFreq[4]:            NB P-State NClk frequency in different NB P-State
+usNBPStateVoltage[4]:             NB P-State (P0/P1 & P2/P3) voltage; NBP3 refers to lowes voltage
+usBootUpNBVoltage:                NB P-State voltage during boot up before driver loaded 
+sExtDispConnInfo:                 Display connector information table provided to VBIOS
+
+**********************************************************************************************************************/
+
+// this Table is used for Kaveri/Kabini APU
+typedef struct _ATOM_FUSION_SYSTEM_INFO_V2
+{
+  ATOM_INTEGRATED_SYSTEM_INFO_V1_8    sIntegratedSysInfo;       // refer to ATOM_INTEGRATED_SYSTEM_INFO_V1_8 definition
+  ULONG                               ulPowerplayTable[128];    // Update comments here to link new powerplay table definition structure
+}ATOM_FUSION_SYSTEM_INFO_V2; 
+
+
 /**************************************************************************/
 // This portion is only used when ext thermal chip or engine/memory clock SS chip is populated on a design
 //Memory SS Info Table
@@ -5026,22 +5380,24 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT
 
 //Define ucClockIndication, SW uses the IDs below to search if the SS is required/enabled on a clock branch/signal type.
 //SS is not required or enabled if a match is not found.
-#define ASIC_INTERNAL_MEMORY_SS			1
-#define ASIC_INTERNAL_ENGINE_SS			2
-#define ASIC_INTERNAL_UVD_SS        3
-#define ASIC_INTERNAL_SS_ON_TMDS    4
-#define ASIC_INTERNAL_SS_ON_HDMI    5
-#define ASIC_INTERNAL_SS_ON_LVDS    6
-#define ASIC_INTERNAL_SS_ON_DP      7
-#define ASIC_INTERNAL_SS_ON_DCPLL   8
-#define ASIC_EXTERNAL_SS_ON_DP_CLOCK 9
-#define ASIC_INTERNAL_VCE_SS        10
+#define ASIC_INTERNAL_MEMORY_SS	         1
+#define ASIC_INTERNAL_ENGINE_SS	         2
+#define ASIC_INTERNAL_UVD_SS             3
+#define ASIC_INTERNAL_SS_ON_TMDS         4
+#define ASIC_INTERNAL_SS_ON_HDMI         5
+#define ASIC_INTERNAL_SS_ON_LVDS         6
+#define ASIC_INTERNAL_SS_ON_DP           7
+#define ASIC_INTERNAL_SS_ON_DCPLL        8
+#define ASIC_EXTERNAL_SS_ON_DP_CLOCK     9
+#define ASIC_INTERNAL_VCE_SS             10
+#define ASIC_INTERNAL_GPUPLL_SS          11
+
 
 typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2
 {
 	ULONG								ulTargetClockRange;						//For mem/engine/uvd, Clock Out frequence (VCO ), in unit of 10Khz
                                                     //For TMDS/HDMI/LVDS, it is pixel clock , for DP, it is link clock ( 27000 or 16200 )
-  USHORT              usSpreadSpectrumPercentage;		//in unit of 0.01%
+  USHORT              usSpreadSpectrumPercentage;		//in unit of 0.01% or 0.001%, decided by ucSpreadSpectrumMode bit4
 	USHORT							usSpreadRateIn10Hz;						//in unit of 10Hz, modulation freq
   UCHAR               ucClockIndication;					  //Indicate which clock source needs SS
 	UCHAR								ucSpreadSpectrumMode;					//Bit0=0 Down Spread,=1 Center Spread, bit1=0: internal SS bit1=1: external SS
@@ -5079,6 +5435,11 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT_
 	UCHAR								ucReserved[2];
 }ATOM_ASIC_SS_ASSIGNMENT_V3;
 
+//ATOM_ASIC_SS_ASSIGNMENT_V3.ucSpreadSpectrumMode
+#define SS_MODE_V3_CENTRE_SPREAD_MASK             0x01
+#define SS_MODE_V3_EXTERNAL_SS_MASK               0x02
+#define SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK    0x10
+
 typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3
 {
   ATOM_COMMON_TABLE_HEADER	      sHeader; 
@@ -5719,6 +6080,7 @@ typedef struct _INDIRECT_IO_ACCESS
 #define INDIRECT_IO_PCIE           3
 #define INDIRECT_IO_PCIEP          4
 #define INDIRECT_IO_NBMISC         5
+#define INDIRECT_IO_SMU            5
 
 #define INDIRECT_IO_PLL_READ       INDIRECT_IO_PLL   | INDIRECT_READ
 #define INDIRECT_IO_PLL_WRITE      INDIRECT_IO_PLL   | INDIRECT_WRITE
@@ -5730,6 +6092,8 @@ typedef struct _INDIRECT_IO_ACCESS
 #define INDIRECT_IO_PCIEP_WRITE    INDIRECT_IO_PCIEP | INDIRECT_WRITE
 #define INDIRECT_IO_NBMISC_READ    INDIRECT_IO_NBMISC | INDIRECT_READ
 #define INDIRECT_IO_NBMISC_WRITE   INDIRECT_IO_NBMISC | INDIRECT_WRITE
+#define INDIRECT_IO_SMU_READ       INDIRECT_IO_SMU | INDIRECT_READ
+#define INDIRECT_IO_SMU_WRITE      INDIRECT_IO_SMU | INDIRECT_WRITE
 
 typedef struct _ATOM_OEM_INFO
 { 
@@ -5875,6 +6239,7 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE
 #define _64Mx32             0x43
 #define _128Mx8             0x51
 #define _128Mx16            0x52
+#define _128Mx32            0x53
 #define _256Mx8             0x61
 #define _256Mx16            0x62
 
@@ -5893,6 +6258,8 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE
 #define PROMOS              MOSEL
 #define KRETON              INFINEON
 #define ELIXIR              NANYA
+#define MEZZA               ELPIDA
+
 
 /////////////Support for GDDR5 MC uCode to reside in upper 64K of ROM/////////////
 
@@ -6625,6 +6992,10 @@ typedef struct _ATOM_DISP_OUT_INFO_V3
 	ASIC_TRANSMITTER_INFO_V2  asTransmitterInfo[1];     // for alligment only
 }ATOM_DISP_OUT_INFO_V3;
 
+//ucDispCaps
+#define DISPLAY_CAPS__DP_PCLK_FROM_PPLL        0x01
+#define DISPLAY_CAPS__FORCE_DISPDEV_CONNECTED  0x02
+
 typedef enum CORE_REF_CLK_SOURCE{
   CLOCK_SRC_XTALIN=0,
   CLOCK_SRC_XO_IN=1,
@@ -6829,6 +7200,17 @@ typedef struct _DIG_TRANSMITTER_INFO_HEA
   USHORT usPhyPllSettingOffset;          // offset of CLOCK_CONDITION_SETTING_ENTRY* with Phy Pll Settings
 }DIG_TRANSMITTER_INFO_HEADER_V3_1;
 
+typedef struct _DIG_TRANSMITTER_INFO_HEADER_V3_2{  
+  ATOM_COMMON_TABLE_HEADER sHeader;  
+  USHORT usDPVsPreEmphSettingOffset;     // offset of PHY_ANALOG_SETTING_INFO * with DP Voltage Swing and Pre-Emphasis for each Link clock 
+  USHORT usPhyAnalogRegListOffset;       // offset of CLOCK_CONDITION_REGESTER_INFO* with None-DP mode Analog Setting's register Info 
+  USHORT usPhyAnalogSettingOffset;       // offset of CLOCK_CONDITION_SETTING_ENTRY* with None-DP mode Analog Setting for each link clock range
+  USHORT usPhyPllRegListOffset;          // offset of CLOCK_CONDITION_REGESTER_INFO* with Phy Pll register Info 
+  USHORT usPhyPllSettingOffset;          // offset of CLOCK_CONDITION_SETTING_ENTRY* with Phy Pll Settings
+  USHORT usDPSSRegListOffset;            // offset of CLOCK_CONDITION_REGESTER_INFO* with Phy SS Pll register Info 
+  USHORT usDPSSSettingOffset;            // offset of CLOCK_CONDITION_SETTING_ENTRY* with Phy SS Pll Settings
+}DIG_TRANSMITTER_INFO_HEADER_V3_2;
+
 typedef struct _CLOCK_CONDITION_REGESTER_INFO{
   USHORT usRegisterIndex;
   UCHAR  ucStartBit;
@@ -6852,12 +7234,24 @@ typedef struct _PHY_CONDITION_REG_VAL{
   ULONG  ulRegVal;
 }PHY_CONDITION_REG_VAL;
 
+typedef struct _PHY_CONDITION_REG_VAL_V2{
+  ULONG  ulCondition;
+  UCHAR  ucCondition2;
+  ULONG  ulRegVal;
+}PHY_CONDITION_REG_VAL_V2;
+
 typedef struct _PHY_CONDITION_REG_INFO{
   USHORT usRegIndex;
   USHORT usSize;
   PHY_CONDITION_REG_VAL asRegVal[1];
 }PHY_CONDITION_REG_INFO;
 
+typedef struct _PHY_CONDITION_REG_INFO_V2{
+  USHORT usRegIndex;
+  USHORT usSize;
+  PHY_CONDITION_REG_VAL_V2 asRegVal[1];
+}PHY_CONDITION_REG_INFO_V2;
+
 typedef struct _PHY_ANALOG_SETTING_INFO{
   UCHAR  ucEncodeMode;
   UCHAR  ucPhySel;
@@ -6865,6 +7259,25 @@ typedef struct _PHY_ANALOG_SETTING_INFO{
   PHY_CONDITION_REG_INFO  asAnalogSetting[1];
 }PHY_ANALOG_SETTING_INFO;
 
+typedef struct _PHY_ANALOG_SETTING_INFO_V2{
+  UCHAR  ucEncodeMode;
+  UCHAR  ucPhySel;
+  USHORT usSize;
+  PHY_CONDITION_REG_INFO_V2  asAnalogSetting[1];
+}PHY_ANALOG_SETTING_INFO_V2;
+
+typedef struct _GFX_HAVESTING_PARAMETERS {
+  UCHAR ucGfxBlkId;                        //GFX blk id to be harvested, like CU, RB or PRIM
+  UCHAR ucReserved;                        //reserved 
+  UCHAR ucActiveUnitNumPerSH;              //requested active CU/RB/PRIM number per shader array
+  UCHAR ucMaxUnitNumPerSH;                 //max CU/RB/PRIM number per shader array   
+} GFX_HAVESTING_PARAMETERS;
+
+//ucGfxBlkId
+#define GFX_HARVESTING_CU_ID               0
+#define GFX_HARVESTING_RB_ID               1
+#define GFX_HARVESTING_PRIM_ID             2
+
 /****************************************************************************/	
 //Portion VI: Definitinos for vbios MC scratch registers that driver used
 /****************************************************************************/
@@ -6875,8 +7288,17 @@ typedef struct _PHY_ANALOG_SETTING_INFO{
 #define MC_MISC0__MEMORY_TYPE__GDDR3  0x30000000
 #define MC_MISC0__MEMORY_TYPE__GDDR4  0x40000000
 #define MC_MISC0__MEMORY_TYPE__GDDR5  0x50000000
+#define MC_MISC0__MEMORY_TYPE__HBM    0x60000000
 #define MC_MISC0__MEMORY_TYPE__DDR3   0xB0000000
 
+#define ATOM_MEM_TYPE_DDR_STRING      "DDR"
+#define ATOM_MEM_TYPE_DDR2_STRING     "DDR2"
+#define ATOM_MEM_TYPE_GDDR3_STRING    "GDDR3"
+#define ATOM_MEM_TYPE_GDDR4_STRING    "GDDR4"
+#define ATOM_MEM_TYPE_GDDR5_STRING    "GDDR5"
+#define ATOM_MEM_TYPE_HBM_STRING      "HBM"
+#define ATOM_MEM_TYPE_DDR3_STRING     "DDR3"
+
 /****************************************************************************/	
 //Portion VI: Definitinos being oboselete
 /****************************************************************************/
@@ -7274,6 +7696,7 @@ typedef struct _ATOM_PPLIB_THERMALCONTRO
 #define ATOM_PP_THERMALCONTROLLER_NISLANDS  15
 #define ATOM_PP_THERMALCONTROLLER_SISLANDS  16
 #define ATOM_PP_THERMALCONTROLLER_LM96163   17
+#define ATOM_PP_THERMALCONTROLLER_CISLANDS  18
 
 // Thermal controller 'combo type' to use an external controller for Fan control and an internal controller for thermal.
 // We probably should reserve the bit 0x80 for this use.
@@ -7316,6 +7739,8 @@ typedef struct _ATOM_PPLIB_EXTENDEDHEADE
     // Add extra system parameters here, always adjust size to include all fields.
     USHORT  usVCETableOffset; //points to ATOM_PPLIB_VCE_Table
     USHORT  usUVDTableOffset;   //points to ATOM_PPLIB_UVD_Table
+    USHORT  usSAMUTableOffset;  //points to ATOM_PPLIB_SAMU_Table
+    USHORT  usPPMTableOffset;   //points to ATOM_PPLIB_PPM_Table
 } ATOM_PPLIB_EXTENDEDHEADER;
 
 //// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps
@@ -7337,7 +7762,10 @@ typedef struct _ATOM_PPLIB_EXTENDEDHEADE
 #define ATOM_PP_PLATFORM_CAP_VDDCI_CONTROL 0x8000                   // Does the driver control VDDCI independently from VDDC.
 #define ATOM_PP_PLATFORM_CAP_REGULATOR_HOT 0x00010000               // Enable the 'regulator hot' feature.
 #define ATOM_PP_PLATFORM_CAP_BACO          0x00020000               // Does the driver supports BACO state.
-
+#define ATOM_PP_PLATFORM_CAP_NEW_CAC_VOLTAGE   0x00040000           // Does the driver supports new CAC voltage table.
+#define ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY   0x00080000     // Does the driver supports revert GPIO5 polarity.
+#define ATOM_PP_PLATFORM_CAP_OUTPUT_THERMAL2GPIO17   0x00100000     // Does the driver supports thermal2GPIO17.
+#define ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE   0x00200000   // Does the driver supports VR HOT GPIO Configurable.
 
 typedef struct _ATOM_PPLIB_POWERPLAYTABLE
 {
@@ -7398,7 +7826,7 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABL
     USHORT                     usVddcDependencyOnMCLKOffset;
     USHORT                     usMaxClockVoltageOnDCOffset;
     USHORT                     usVddcPhaseShedLimitsTableOffset;    // Points to ATOM_PPLIB_PhaseSheddingLimits_Table
-    USHORT                     usReserved;  
+    USHORT                     usMvddDependencyOnMCLKOffset;  
 } ATOM_PPLIB_POWERPLAYTABLE4, *LPATOM_PPLIB_POWERPLAYTABLE4;
 
 typedef struct _ATOM_PPLIB_POWERPLAYTABLE5
@@ -7563,6 +7991,17 @@ typedef struct _ATOM_PPLIB_SI_CLOCK_INFO
 
 } ATOM_PPLIB_SI_CLOCK_INFO;
 
+typedef struct _ATOM_PPLIB_CI_CLOCK_INFO
+{
+      USHORT usEngineClockLow;
+      UCHAR  ucEngineClockHigh;
+
+      USHORT usMemoryClockLow;
+      UCHAR  ucMemoryClockHigh;
+      
+      UCHAR  ucPCIEGen;
+      USHORT usPCIELane;
+} ATOM_PPLIB_CI_CLOCK_INFO;
 
 typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO
 
@@ -7680,8 +8119,8 @@ typedef struct _ATOM_PPLIB_Clock_Voltage
 
 typedef struct _ATOM_PPLIB_CAC_Leakage_Record
 {
-    USHORT usVddc;  // We use this field for the "fake" standardized VDDC for power calculations                                                  
-    ULONG  ulLeakageValue;
+    USHORT usVddc;  // We use this field for the "fake" standardized VDDC for power calculations; For CI and newer, we use this as the real VDDC value.
+    ULONG  ulLeakageValue;  // For CI and newer we use this as the "fake" standar VDDC value.
 }ATOM_PPLIB_CAC_Leakage_Record;
 
 typedef struct _ATOM_PPLIB_CAC_Leakage_Table
@@ -7796,6 +8235,42 @@ typedef struct _ATOM_PPLIB_UVD_Table
 //    ATOM_PPLIB_UVD_State_Table states;
 }ATOM_PPLIB_UVD_Table;
 
+
+typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Record
+{
+      USHORT usVoltage;
+      USHORT usSAMClockLow;
+      UCHAR  ucSAMClockHigh;
+}ATOM_PPLIB_SAMClk_Voltage_Limit_Record;
+
+typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Table{
+    UCHAR numEntries;
+    ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[1];
+}ATOM_PPLIB_SAMClk_Voltage_Limit_Table;
+
+typedef struct _ATOM_PPLIB_SAMU_Table
+{
+      UCHAR revid;
+      ATOM_PPLIB_SAMClk_Voltage_Limit_Table limits;
+}ATOM_PPLIB_SAMU_Table;
+
+#define ATOM_PPM_A_A    1
+#define ATOM_PPM_A_I    2
+typedef struct _ATOM_PPLIB_PPM_Table
+{
+      UCHAR  ucRevId;
+      UCHAR  ucPpmDesign;          //A+I or A+A
+      USHORT usCpuCoreNumber;
+      ULONG  ulPlatformTDP;
+      ULONG  ulSmallACPlatformTDP;
+      ULONG  ulPlatformTDC;
+      ULONG  ulSmallACPlatformTDC;
+      ULONG  ulApuTDP;
+      ULONG  ulDGpuTDP;  
+      ULONG  ulDGpuUlvPower;
+      ULONG  ulTjmax;
+} ATOM_PPLIB_PPM_Table;
+
 /**************************************************************************/
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atom.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atom.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/atom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/atom.c	2013-08-25 20:43:22.000000000 -0400
@@ -1222,12 +1222,17 @@ int atom_execute_table(struct atom_conte
 	int r;
 
 	mutex_lock(&ctx->mutex);
+	/* reset data block */
+	ctx->data_block = 0;
 	/* reset reg block */
 	ctx->reg_block = 0;
 	/* reset fb window */
 	ctx->fb_base = 0;
 	/* reset io mode */
 	ctx->io_mode = ATOM_IO_MM;
+	/* reset divmul */
+	ctx->divmul[0] = 0;
+	ctx->divmul[1] = 0;
 	r = atom_execute_table_locked(ctx, index, params);
 	mutex_unlock(&ctx->mutex);
 	return r;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/btcd.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/btcd.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/btcd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/btcd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2010 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+#ifndef _BTCD_H_
+#define _BTCD_H_
+
+/* pm registers */
+
+#define GENERAL_PWRMGT                                  0x63c
+#       define GLOBAL_PWRMGT_EN                         (1 << 0)
+#       define STATIC_PM_EN                             (1 << 1)
+#       define THERMAL_PROTECTION_DIS                   (1 << 2)
+#       define THERMAL_PROTECTION_TYPE                  (1 << 3)
+#       define ENABLE_GEN2PCIE                          (1 << 4)
+#       define ENABLE_GEN2XSP                           (1 << 5)
+#       define SW_SMIO_INDEX(x)                         ((x) << 6)
+#       define SW_SMIO_INDEX_MASK                       (3 << 6)
+#       define SW_SMIO_INDEX_SHIFT                      6
+#       define LOW_VOLT_D2_ACPI                         (1 << 8)
+#       define LOW_VOLT_D3_ACPI                         (1 << 9)
+#       define VOLT_PWRMGT_EN                           (1 << 10)
+#       define BACKBIAS_PAD_EN                          (1 << 18)
+#       define BACKBIAS_VALUE                           (1 << 19)
+#       define DYN_SPREAD_SPECTRUM_EN                   (1 << 23)
+#       define AC_DC_SW                                 (1 << 24)
+
+#define	CG_BIF_REQ_AND_RSP				0x7f4
+#define		CG_CLIENT_REQ(x)			((x) << 0)
+#define		CG_CLIENT_REQ_MASK			(0xff << 0)
+#define		CG_CLIENT_REQ_SHIFT			0
+#define		CG_CLIENT_RESP(x)			((x) << 8)
+#define		CG_CLIENT_RESP_MASK			(0xff << 8)
+#define		CG_CLIENT_RESP_SHIFT			8
+#define		CLIENT_CG_REQ(x)			((x) << 16)
+#define		CLIENT_CG_REQ_MASK			(0xff << 16)
+#define		CLIENT_CG_REQ_SHIFT			16
+#define		CLIENT_CG_RESP(x)			((x) << 24)
+#define		CLIENT_CG_RESP_MASK			(0xff << 24)
+#define		CLIENT_CG_RESP_SHIFT			24
+
+#define	SCLK_PSKIP_CNTL					0x8c0
+#define		PSKIP_ON_ALLOW_STOP_HI(x)		((x) << 16)
+#define		PSKIP_ON_ALLOW_STOP_HI_MASK		(0xff << 16)
+#define		PSKIP_ON_ALLOW_STOP_HI_SHIFT		16
+
+#define	CG_ULV_CONTROL					0x8c8
+#define	CG_ULV_PARAMETER				0x8cc
+
+#define	MC_ARB_DRAM_TIMING				0x2774
+#define	MC_ARB_DRAM_TIMING2				0x2778
+
+#define	MC_ARB_RFSH_RATE				0x27b0
+#define		POWERMODE0(x)				((x) << 0)
+#define		POWERMODE0_MASK				(0xff << 0)
+#define		POWERMODE0_SHIFT			0
+#define		POWERMODE1(x)				((x) << 8)
+#define		POWERMODE1_MASK				(0xff << 8)
+#define		POWERMODE1_SHIFT			8
+#define		POWERMODE2(x)				((x) << 16)
+#define		POWERMODE2_MASK				(0xff << 16)
+#define		POWERMODE2_SHIFT			16
+#define		POWERMODE3(x)				((x) << 24)
+#define		POWERMODE3_MASK				(0xff << 24)
+#define		POWERMODE3_SHIFT			24
+
+#define MC_ARB_BURST_TIME                               0x2808
+#define		STATE0(x)				((x) << 0)
+#define		STATE0_MASK				(0x1f << 0)
+#define		STATE0_SHIFT				0
+#define		STATE1(x)				((x) << 5)
+#define		STATE1_MASK				(0x1f << 5)
+#define		STATE1_SHIFT				5
+#define		STATE2(x)				((x) << 10)
+#define		STATE2_MASK				(0x1f << 10)
+#define		STATE2_SHIFT				10
+#define		STATE3(x)				((x) << 15)
+#define		STATE3_MASK				(0x1f << 15)
+#define		STATE3_SHIFT				15
+
+#define MC_SEQ_RAS_TIMING                               0x28a0
+#define MC_SEQ_CAS_TIMING                               0x28a4
+#define MC_SEQ_MISC_TIMING                              0x28a8
+#define MC_SEQ_MISC_TIMING2                             0x28ac
+
+#define MC_SEQ_RD_CTL_D0                                0x28b4
+#define MC_SEQ_RD_CTL_D1                                0x28b8
+#define MC_SEQ_WR_CTL_D0                                0x28bc
+#define MC_SEQ_WR_CTL_D1                                0x28c0
+
+#define MC_PMG_AUTO_CFG                                 0x28d4
+
+#define MC_SEQ_STATUS_M                                 0x29f4
+#       define PMG_PWRSTATE                             (1 << 16)
+
+#define MC_SEQ_MISC0                                    0x2a00
+#define         MC_SEQ_MISC0_GDDR5_SHIFT                28
+#define         MC_SEQ_MISC0_GDDR5_MASK                 0xf0000000
+#define         MC_SEQ_MISC0_GDDR5_VALUE                5
+#define MC_SEQ_MISC1                                    0x2a04
+#define MC_SEQ_RESERVE_M                                0x2a08
+#define MC_PMG_CMD_EMRS                                 0x2a0c
+
+#define MC_SEQ_MISC3                                    0x2a2c
+
+#define MC_SEQ_MISC5                                    0x2a54
+#define MC_SEQ_MISC6                                    0x2a58
+
+#define MC_SEQ_MISC7                                    0x2a64
+
+#define MC_SEQ_CG                                       0x2a68
+#define		CG_SEQ_REQ(x)				((x) << 0)
+#define		CG_SEQ_REQ_MASK				(0xff << 0)
+#define		CG_SEQ_REQ_SHIFT			0
+#define		CG_SEQ_RESP(x)				((x) << 8)
+#define		CG_SEQ_RESP_MASK			(0xff << 8)
+#define		CG_SEQ_RESP_SHIFT			8
+#define		SEQ_CG_REQ(x)				((x) << 16)
+#define		SEQ_CG_REQ_MASK				(0xff << 16)
+#define		SEQ_CG_REQ_SHIFT			16
+#define		SEQ_CG_RESP(x)				((x) << 24)
+#define		SEQ_CG_RESP_MASK			(0xff << 24)
+#define		SEQ_CG_RESP_SHIFT			24
+#define MC_SEQ_RAS_TIMING_LP                            0x2a6c
+#define MC_SEQ_CAS_TIMING_LP                            0x2a70
+#define MC_SEQ_MISC_TIMING_LP                           0x2a74
+#define MC_SEQ_MISC_TIMING2_LP                          0x2a78
+#define MC_SEQ_WR_CTL_D0_LP                             0x2a7c
+#define MC_SEQ_WR_CTL_D1_LP                             0x2a80
+#define MC_SEQ_PMG_CMD_EMRS_LP                          0x2a84
+#define MC_SEQ_PMG_CMD_MRS_LP                           0x2a88
+
+#define MC_PMG_CMD_MRS                                  0x2aac
+
+#define MC_SEQ_RD_CTL_D0_LP                             0x2b1c
+#define MC_SEQ_RD_CTL_D1_LP                             0x2b20
+
+#define MC_PMG_CMD_MRS1                                 0x2b44
+#define MC_SEQ_PMG_CMD_MRS1_LP                          0x2b48
+
+#define	LB_SYNC_RESET_SEL				0x6b28
+#define		LB_SYNC_RESET_SEL_MASK			(3 << 0)
+#define		LB_SYNC_RESET_SEL_SHIFT			0
+
+/* PCIE link stuff */
+#define PCIE_LC_SPEED_CNTL                                0xa4 /* PCIE_P */
+#       define LC_GEN2_EN_STRAP                           (1 << 0)
+#       define LC_TARGET_LINK_SPEED_OVERRIDE_EN           (1 << 1)
+#       define LC_FORCE_EN_HW_SPEED_CHANGE                (1 << 5)
+#       define LC_FORCE_DIS_HW_SPEED_CHANGE               (1 << 6)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK      (0x3 << 8)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT     3
+#       define LC_CURRENT_DATA_RATE                       (1 << 11)
+#       define LC_HW_VOLTAGE_IF_CONTROL(x)                ((x) << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_MASK              (3 << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_SHIFT             12
+#       define LC_VOLTAGE_TIMER_SEL_MASK                  (0xf << 14)
+#       define LC_CLR_FAILED_SPD_CHANGE_CNT               (1 << 21)
+#       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 23)
+#       define LC_OTHER_SIDE_SUPPORTS_GEN2                (1 << 24)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/btc_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/btc_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/btc_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/btc_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2738 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "btcd.h"
+#include "r600_dpm.h"
+#include "cypress_dpm.h"
+#include "btc_dpm.h"
+#include "atom.h"
+
+#define MC_CG_ARB_FREQ_F0           0x0a
+#define MC_CG_ARB_FREQ_F1           0x0b
+#define MC_CG_ARB_FREQ_F2           0x0c
+#define MC_CG_ARB_FREQ_F3           0x0d
+
+#define MC_CG_SEQ_DRAMCONF_S0       0x05
+#define MC_CG_SEQ_DRAMCONF_S1       0x06
+#define MC_CG_SEQ_YCLK_SUSPEND      0x04
+#define MC_CG_SEQ_YCLK_RESUME       0x0a
+
+#define SMC_RAM_END 0x8000
+
+#ifndef BTC_MGCG_SEQUENCE
+#define BTC_MGCG_SEQUENCE  300
+
+struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
+struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
+
+
+//********* BARTS **************//
+static const u32 barts_cgcg_cgls_default[] =
+{
+	/* Register,   Value,     Mask bits */
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff
+};
+#define BARTS_CGCG_CGLS_DEFAULT_LENGTH sizeof(barts_cgcg_cgls_default) / (3 * sizeof(u32))
+
+static const u32 barts_cgcg_cgls_disable[] =
+{
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x00000644, 0x000f7912, 0x001f4180,
+	0x00000644, 0x000f3812, 0x001f4180
+};
+#define BARTS_CGCG_CGLS_DISABLE_LENGTH sizeof(barts_cgcg_cgls_disable) / (3 * sizeof(u32))
+
+static const u32 barts_cgcg_cgls_enable[] =
+{
+	/* 0x0000c124, 0x84180000, 0x00180000, */
+	0x00000644, 0x000f7892, 0x001f4080,
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff
+};
+#define BARTS_CGCG_CGLS_ENABLE_LENGTH sizeof(barts_cgcg_cgls_enable) / (3 * sizeof(u32))
+
+static const u32 barts_mgcg_default[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x00005448, 0x00000100, 0xffffffff,
+	0x000055e4, 0x00600100, 0xffffffff,
+	0x0000160c, 0x00000100, 0xffffffff,
+	0x0000c164, 0x00000100, 0xffffffff,
+	0x00008a18, 0x00000100, 0xffffffff,
+	0x0000897c, 0x06000100, 0xffffffff,
+	0x00008b28, 0x00000100, 0xffffffff,
+	0x00009144, 0x00000100, 0xffffffff,
+	0x00009a60, 0x00000100, 0xffffffff,
+	0x00009868, 0x00000100, 0xffffffff,
+	0x00008d58, 0x00000100, 0xffffffff,
+	0x00009510, 0x00000100, 0xffffffff,
+	0x0000949c, 0x00000100, 0xffffffff,
+	0x00009654, 0x00000100, 0xffffffff,
+	0x00009030, 0x00000100, 0xffffffff,
+	0x00009034, 0x00000100, 0xffffffff,
+	0x00009038, 0x00000100, 0xffffffff,
+	0x0000903c, 0x00000100, 0xffffffff,
+	0x00009040, 0x00000100, 0xffffffff,
+	0x0000a200, 0x00000100, 0xffffffff,
+	0x0000a204, 0x00000100, 0xffffffff,
+	0x0000a208, 0x00000100, 0xffffffff,
+	0x0000a20c, 0x00000100, 0xffffffff,
+	0x0000977c, 0x00000100, 0xffffffff,
+	0x00003f80, 0x00000100, 0xffffffff,
+	0x0000a210, 0x00000100, 0xffffffff,
+	0x0000a214, 0x00000100, 0xffffffff,
+	0x000004d8, 0x00000100, 0xffffffff,
+	0x00009784, 0x00000100, 0xffffffff,
+	0x00009698, 0x00000100, 0xffffffff,
+	0x000004d4, 0x00000200, 0xffffffff,
+	0x000004d0, 0x00000000, 0xffffffff,
+	0x000030cc, 0x00000100, 0xffffffff,
+	0x0000d0c0, 0xff000100, 0xffffffff,
+	0x0000802c, 0x40000000, 0xffffffff,
+	0x0000915c, 0x00010000, 0xffffffff,
+	0x00009160, 0x00030002, 0xffffffff,
+	0x00009164, 0x00050004, 0xffffffff,
+	0x00009168, 0x00070006, 0xffffffff,
+	0x00009178, 0x00070000, 0xffffffff,
+	0x0000917c, 0x00030002, 0xffffffff,
+	0x00009180, 0x00050004, 0xffffffff,
+	0x0000918c, 0x00010006, 0xffffffff,
+	0x00009190, 0x00090008, 0xffffffff,
+	0x00009194, 0x00070000, 0xffffffff,
+	0x00009198, 0x00030002, 0xffffffff,
+	0x0000919c, 0x00050004, 0xffffffff,
+	0x000091a8, 0x00010006, 0xffffffff,
+	0x000091ac, 0x00090008, 0xffffffff,
+	0x000091b0, 0x00070000, 0xffffffff,
+	0x000091b4, 0x00030002, 0xffffffff,
+	0x000091b8, 0x00050004, 0xffffffff,
+	0x000091c4, 0x00010006, 0xffffffff,
+	0x000091c8, 0x00090008, 0xffffffff,
+	0x000091cc, 0x00070000, 0xffffffff,
+	0x000091d0, 0x00030002, 0xffffffff,
+	0x000091d4, 0x00050004, 0xffffffff,
+	0x000091e0, 0x00010006, 0xffffffff,
+	0x000091e4, 0x00090008, 0xffffffff,
+	0x000091e8, 0x00000000, 0xffffffff,
+	0x000091ec, 0x00070000, 0xffffffff,
+	0x000091f0, 0x00030002, 0xffffffff,
+	0x000091f4, 0x00050004, 0xffffffff,
+	0x00009200, 0x00010006, 0xffffffff,
+	0x00009204, 0x00090008, 0xffffffff,
+	0x00009208, 0x00070000, 0xffffffff,
+	0x0000920c, 0x00030002, 0xffffffff,
+	0x00009210, 0x00050004, 0xffffffff,
+	0x0000921c, 0x00010006, 0xffffffff,
+	0x00009220, 0x00090008, 0xffffffff,
+	0x00009224, 0x00070000, 0xffffffff,
+	0x00009228, 0x00030002, 0xffffffff,
+	0x0000922c, 0x00050004, 0xffffffff,
+	0x00009238, 0x00010006, 0xffffffff,
+	0x0000923c, 0x00090008, 0xffffffff,
+	0x00009294, 0x00000000, 0xffffffff,
+	0x0000802c, 0x40010000, 0xffffffff,
+	0x0000915c, 0x00010000, 0xffffffff,
+	0x00009160, 0x00030002, 0xffffffff,
+	0x00009164, 0x00050004, 0xffffffff,
+	0x00009168, 0x00070006, 0xffffffff,
+	0x00009178, 0x00070000, 0xffffffff,
+	0x0000917c, 0x00030002, 0xffffffff,
+	0x00009180, 0x00050004, 0xffffffff,
+	0x0000918c, 0x00010006, 0xffffffff,
+	0x00009190, 0x00090008, 0xffffffff,
+	0x00009194, 0x00070000, 0xffffffff,
+	0x00009198, 0x00030002, 0xffffffff,
+	0x0000919c, 0x00050004, 0xffffffff,
+	0x000091a8, 0x00010006, 0xffffffff,
+	0x000091ac, 0x00090008, 0xffffffff,
+	0x000091b0, 0x00070000, 0xffffffff,
+	0x000091b4, 0x00030002, 0xffffffff,
+	0x000091b8, 0x00050004, 0xffffffff,
+	0x000091c4, 0x00010006, 0xffffffff,
+	0x000091c8, 0x00090008, 0xffffffff,
+	0x000091cc, 0x00070000, 0xffffffff,
+	0x000091d0, 0x00030002, 0xffffffff,
+	0x000091d4, 0x00050004, 0xffffffff,
+	0x000091e0, 0x00010006, 0xffffffff,
+	0x000091e4, 0x00090008, 0xffffffff,
+	0x000091e8, 0x00000000, 0xffffffff,
+	0x000091ec, 0x00070000, 0xffffffff,
+	0x000091f0, 0x00030002, 0xffffffff,
+	0x000091f4, 0x00050004, 0xffffffff,
+	0x00009200, 0x00010006, 0xffffffff,
+	0x00009204, 0x00090008, 0xffffffff,
+	0x00009208, 0x00070000, 0xffffffff,
+	0x0000920c, 0x00030002, 0xffffffff,
+	0x00009210, 0x00050004, 0xffffffff,
+	0x0000921c, 0x00010006, 0xffffffff,
+	0x00009220, 0x00090008, 0xffffffff,
+	0x00009224, 0x00070000, 0xffffffff,
+	0x00009228, 0x00030002, 0xffffffff,
+	0x0000922c, 0x00050004, 0xffffffff,
+	0x00009238, 0x00010006, 0xffffffff,
+	0x0000923c, 0x00090008, 0xffffffff,
+	0x00009294, 0x00000000, 0xffffffff,
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff
+};
+#define BARTS_MGCG_DEFAULT_LENGTH sizeof(barts_mgcg_default) / (3 * sizeof(u32))
+
+static const u32 barts_mgcg_disable[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000002, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000003, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x00009150, 0x00600000, 0xffffffff
+};
+#define BARTS_MGCG_DISABLE_LENGTH sizeof(barts_mgcg_disable) / (3 * sizeof(u32))
+
+static const u32 barts_mgcg_enable[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000002, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000003, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x00009150, 0x81944000, 0xffffffff
+};
+#define BARTS_MGCG_ENABLE_LENGTH sizeof(barts_mgcg_enable) / (3 * sizeof(u32))
+
+//********* CAICOS **************//
+static const u32 caicos_cgcg_cgls_default[] =
+{
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff
+};
+#define CAICOS_CGCG_CGLS_DEFAULT_LENGTH sizeof(caicos_cgcg_cgls_default) / (3 * sizeof(u32))
+
+static const u32 caicos_cgcg_cgls_disable[] =
+{
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x00000644, 0x000f7912, 0x001f4180,
+	0x00000644, 0x000f3812, 0x001f4180
+};
+#define CAICOS_CGCG_CGLS_DISABLE_LENGTH sizeof(caicos_cgcg_cgls_disable) / (3 * sizeof(u32))
+
+static const u32 caicos_cgcg_cgls_enable[] =
+{
+	/* 0x0000c124, 0x84180000, 0x00180000, */
+	0x00000644, 0x000f7892, 0x001f4080,
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff
+};
+#define CAICOS_CGCG_CGLS_ENABLE_LENGTH sizeof(caicos_cgcg_cgls_enable) / (3 * sizeof(u32))
+
+static const u32 caicos_mgcg_default[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x00005448, 0x00000100, 0xffffffff,
+	0x000055e4, 0x00600100, 0xffffffff,
+	0x0000160c, 0x00000100, 0xffffffff,
+	0x0000c164, 0x00000100, 0xffffffff,
+	0x00008a18, 0x00000100, 0xffffffff,
+	0x0000897c, 0x06000100, 0xffffffff,
+	0x00008b28, 0x00000100, 0xffffffff,
+	0x00009144, 0x00000100, 0xffffffff,
+	0x00009a60, 0x00000100, 0xffffffff,
+	0x00009868, 0x00000100, 0xffffffff,
+	0x00008d58, 0x00000100, 0xffffffff,
+	0x00009510, 0x00000100, 0xffffffff,
+	0x0000949c, 0x00000100, 0xffffffff,
+	0x00009654, 0x00000100, 0xffffffff,
+	0x00009030, 0x00000100, 0xffffffff,
+	0x00009034, 0x00000100, 0xffffffff,
+	0x00009038, 0x00000100, 0xffffffff,
+	0x0000903c, 0x00000100, 0xffffffff,
+	0x00009040, 0x00000100, 0xffffffff,
+	0x0000a200, 0x00000100, 0xffffffff,
+	0x0000a204, 0x00000100, 0xffffffff,
+	0x0000a208, 0x00000100, 0xffffffff,
+	0x0000a20c, 0x00000100, 0xffffffff,
+	0x0000977c, 0x00000100, 0xffffffff,
+	0x00003f80, 0x00000100, 0xffffffff,
+	0x0000a210, 0x00000100, 0xffffffff,
+	0x0000a214, 0x00000100, 0xffffffff,
+	0x000004d8, 0x00000100, 0xffffffff,
+	0x00009784, 0x00000100, 0xffffffff,
+	0x00009698, 0x00000100, 0xffffffff,
+	0x000004d4, 0x00000200, 0xffffffff,
+	0x000004d0, 0x00000000, 0xffffffff,
+	0x000030cc, 0x00000100, 0xffffffff,
+	0x0000d0c0, 0xff000100, 0xffffffff,
+	0x0000915c, 0x00010000, 0xffffffff,
+	0x00009160, 0x00030002, 0xffffffff,
+	0x00009164, 0x00050004, 0xffffffff,
+	0x00009168, 0x00070006, 0xffffffff,
+	0x00009178, 0x00070000, 0xffffffff,
+	0x0000917c, 0x00030002, 0xffffffff,
+	0x00009180, 0x00050004, 0xffffffff,
+	0x0000918c, 0x00010006, 0xffffffff,
+	0x00009190, 0x00090008, 0xffffffff,
+	0x00009194, 0x00070000, 0xffffffff,
+	0x00009198, 0x00030002, 0xffffffff,
+	0x0000919c, 0x00050004, 0xffffffff,
+	0x000091a8, 0x00010006, 0xffffffff,
+	0x000091ac, 0x00090008, 0xffffffff,
+	0x000091e8, 0x00000000, 0xffffffff,
+	0x00009294, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff
+};
+#define CAICOS_MGCG_DEFAULT_LENGTH sizeof(caicos_mgcg_default) / (3 * sizeof(u32))
+
+static const u32 caicos_mgcg_disable[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000002, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000003, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x00009150, 0x00600000, 0xffffffff
+};
+#define CAICOS_MGCG_DISABLE_LENGTH sizeof(caicos_mgcg_disable) / (3 * sizeof(u32))
+
+static const u32 caicos_mgcg_enable[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000002, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000003, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x00009150, 0x46944040, 0xffffffff
+};
+#define CAICOS_MGCG_ENABLE_LENGTH sizeof(caicos_mgcg_enable) / (3 * sizeof(u32))
+
+//********* TURKS **************//
+static const u32 turks_cgcg_cgls_default[] =
+{
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff
+};
+#define TURKS_CGCG_CGLS_DEFAULT_LENGTH  sizeof(turks_cgcg_cgls_default) / (3 * sizeof(u32))
+
+static const u32 turks_cgcg_cgls_disable[] =
+{
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x00000644, 0x000f7912, 0x001f4180,
+	0x00000644, 0x000f3812, 0x001f4180
+};
+#define TURKS_CGCG_CGLS_DISABLE_LENGTH sizeof(turks_cgcg_cgls_disable) / (3 * sizeof(u32))
+
+static const u32 turks_cgcg_cgls_enable[] =
+{
+	/* 0x0000c124, 0x84180000, 0x00180000, */
+	0x00000644, 0x000f7892, 0x001f4080,
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff
+};
+#define TURKS_CGCG_CGLS_ENABLE_LENGTH sizeof(turks_cgcg_cgls_enable) / (3 * sizeof(u32))
+
+// These are the sequences for turks_mgcg_shls
+static const u32 turks_mgcg_default[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x00005448, 0x00000100, 0xffffffff,
+	0x000055e4, 0x00600100, 0xffffffff,
+	0x0000160c, 0x00000100, 0xffffffff,
+	0x0000c164, 0x00000100, 0xffffffff,
+	0x00008a18, 0x00000100, 0xffffffff,
+	0x0000897c, 0x06000100, 0xffffffff,
+	0x00008b28, 0x00000100, 0xffffffff,
+	0x00009144, 0x00000100, 0xffffffff,
+	0x00009a60, 0x00000100, 0xffffffff,
+	0x00009868, 0x00000100, 0xffffffff,
+	0x00008d58, 0x00000100, 0xffffffff,
+	0x00009510, 0x00000100, 0xffffffff,
+	0x0000949c, 0x00000100, 0xffffffff,
+	0x00009654, 0x00000100, 0xffffffff,
+	0x00009030, 0x00000100, 0xffffffff,
+	0x00009034, 0x00000100, 0xffffffff,
+	0x00009038, 0x00000100, 0xffffffff,
+	0x0000903c, 0x00000100, 0xffffffff,
+	0x00009040, 0x00000100, 0xffffffff,
+	0x0000a200, 0x00000100, 0xffffffff,
+	0x0000a204, 0x00000100, 0xffffffff,
+	0x0000a208, 0x00000100, 0xffffffff,
+	0x0000a20c, 0x00000100, 0xffffffff,
+	0x0000977c, 0x00000100, 0xffffffff,
+	0x00003f80, 0x00000100, 0xffffffff,
+	0x0000a210, 0x00000100, 0xffffffff,
+	0x0000a214, 0x00000100, 0xffffffff,
+	0x000004d8, 0x00000100, 0xffffffff,
+	0x00009784, 0x00000100, 0xffffffff,
+	0x00009698, 0x00000100, 0xffffffff,
+	0x000004d4, 0x00000200, 0xffffffff,
+	0x000004d0, 0x00000000, 0xffffffff,
+	0x000030cc, 0x00000100, 0xffffffff,
+	0x0000d0c0, 0x00000100, 0xffffffff,
+	0x0000915c, 0x00010000, 0xffffffff,
+	0x00009160, 0x00030002, 0xffffffff,
+	0x00009164, 0x00050004, 0xffffffff,
+	0x00009168, 0x00070006, 0xffffffff,
+	0x00009178, 0x00070000, 0xffffffff,
+	0x0000917c, 0x00030002, 0xffffffff,
+	0x00009180, 0x00050004, 0xffffffff,
+	0x0000918c, 0x00010006, 0xffffffff,
+	0x00009190, 0x00090008, 0xffffffff,
+	0x00009194, 0x00070000, 0xffffffff,
+	0x00009198, 0x00030002, 0xffffffff,
+	0x0000919c, 0x00050004, 0xffffffff,
+	0x000091a8, 0x00010006, 0xffffffff,
+	0x000091ac, 0x00090008, 0xffffffff,
+	0x000091b0, 0x00070000, 0xffffffff,
+	0x000091b4, 0x00030002, 0xffffffff,
+	0x000091b8, 0x00050004, 0xffffffff,
+	0x000091c4, 0x00010006, 0xffffffff,
+	0x000091c8, 0x00090008, 0xffffffff,
+	0x000091cc, 0x00070000, 0xffffffff,
+	0x000091d0, 0x00030002, 0xffffffff,
+	0x000091d4, 0x00050004, 0xffffffff,
+	0x000091e0, 0x00010006, 0xffffffff,
+	0x000091e4, 0x00090008, 0xffffffff,
+	0x000091e8, 0x00000000, 0xffffffff,
+	0x000091ec, 0x00070000, 0xffffffff,
+	0x000091f0, 0x00030002, 0xffffffff,
+	0x000091f4, 0x00050004, 0xffffffff,
+	0x00009200, 0x00010006, 0xffffffff,
+	0x00009204, 0x00090008, 0xffffffff,
+	0x00009208, 0x00070000, 0xffffffff,
+	0x0000920c, 0x00030002, 0xffffffff,
+	0x00009210, 0x00050004, 0xffffffff,
+	0x0000921c, 0x00010006, 0xffffffff,
+	0x00009220, 0x00090008, 0xffffffff,
+	0x00009294, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff
+};
+#define TURKS_MGCG_DEFAULT_LENGTH sizeof(turks_mgcg_default) / (3 * sizeof(u32))
+
+static const u32 turks_mgcg_disable[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000002, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000003, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x00009150, 0x00600000, 0xffffffff
+};
+#define TURKS_MGCG_DISABLE_LENGTH sizeof(turks_mgcg_disable) / (3 * sizeof(u32))
+
+static const u32 turks_mgcg_enable[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000002, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000003, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x00009150, 0x6e944000, 0xffffffff
+};
+#define TURKS_MGCG_ENABLE_LENGTH sizeof(turks_mgcg_enable) / (3 * sizeof(u32))
+
+#endif
+
+#ifndef BTC_SYSLS_SEQUENCE
+#define BTC_SYSLS_SEQUENCE  100
+
+
+//********* BARTS **************//
+static const u32 barts_sysls_default[] =
+{
+	/* Register,   Value,     Mask bits */
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x000020c0, 0x000c0c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x000064ec, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00006dfc, 0x00000000, 0xffffffff
+};
+#define BARTS_SYSLS_DEFAULT_LENGTH sizeof(barts_sysls_default) / (3 * sizeof(u32))
+
+static const u32 barts_sysls_disable[] =
+{
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x00041401, 0xffffffff,
+	0x0000264c, 0x00040400, 0xffffffff,
+	0x00002648, 0x00040400, 0xffffffff,
+	0x00002650, 0x00040400, 0xffffffff,
+	0x000020b8, 0x00040400, 0xffffffff,
+	0x000020bc, 0x00040400, 0xffffffff,
+	0x000020c0, 0x00040c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680000, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x000064ec, 0x00007ffd, 0xffffffff,
+	0x00000c7c, 0x0000ff00, 0xffffffff,
+	0x00006dfc, 0x0000007f, 0xffffffff
+};
+#define BARTS_SYSLS_DISABLE_LENGTH sizeof(barts_sysls_disable) / (3 * sizeof(u32))
+
+static const u32 barts_sysls_enable[] =
+{
+	0x000055e8, 0x00000001, 0xffffffff,
+	0x0000d0bc, 0x00000100, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x000020c0, 0x000c0c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x000004c8, 0x00000000, 0xffffffff,
+	0x000064ec, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00006dfc, 0x00000000, 0xffffffff
+};
+#define BARTS_SYSLS_ENABLE_LENGTH sizeof(barts_sysls_enable) / (3 * sizeof(u32))
+
+//********* CAICOS **************//
+static const u32 caicos_sysls_default[] =
+{
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x000064ec, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00006dfc, 0x00000000, 0xffffffff
+};
+#define CAICOS_SYSLS_DEFAULT_LENGTH sizeof(caicos_sysls_default) / (3 * sizeof(u32))
+
+static const u32 caicos_sysls_disable[] =
+{
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x00041401, 0xffffffff,
+	0x0000264c, 0x00040400, 0xffffffff,
+	0x00002648, 0x00040400, 0xffffffff,
+	0x00002650, 0x00040400, 0xffffffff,
+	0x000020b8, 0x00040400, 0xffffffff,
+	0x000020bc, 0x00040400, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680000, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x000064ec, 0x00007ffd, 0xffffffff,
+	0x00000c7c, 0x0000ff00, 0xffffffff,
+	0x00006dfc, 0x0000007f, 0xffffffff
+};
+#define CAICOS_SYSLS_DISABLE_LENGTH sizeof(caicos_sysls_disable) / (3 * sizeof(u32))
+
+static const u32 caicos_sysls_enable[] =
+{
+	0x000055e8, 0x00000001, 0xffffffff,
+	0x0000d0bc, 0x00000100, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x000064ec, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00006dfc, 0x00000000, 0xffffffff,
+	0x000004c8, 0x00000000, 0xffffffff
+};
+#define CAICOS_SYSLS_ENABLE_LENGTH sizeof(caicos_sysls_enable) / (3 * sizeof(u32))
+
+//********* TURKS **************//
+static const u32 turks_sysls_default[] =
+{
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x000020c0, 0x000c0c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x000064ec, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00006dfc, 0x00000000, 0xffffffff
+};
+#define TURKS_SYSLS_DEFAULT_LENGTH sizeof(turks_sysls_default) / (3 * sizeof(u32))
+
+static const u32 turks_sysls_disable[] =
+{
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x00041401, 0xffffffff,
+	0x0000264c, 0x00040400, 0xffffffff,
+	0x00002648, 0x00040400, 0xffffffff,
+	0x00002650, 0x00040400, 0xffffffff,
+	0x000020b8, 0x00040400, 0xffffffff,
+	0x000020bc, 0x00040400, 0xffffffff,
+	0x000020c0, 0x00040c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680000, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x000064ec, 0x00007ffd, 0xffffffff,
+	0x00000c7c, 0x0000ff00, 0xffffffff,
+	0x00006dfc, 0x0000007f, 0xffffffff
+};
+#define TURKS_SYSLS_DISABLE_LENGTH sizeof(turks_sysls_disable) / (3 * sizeof(u32))
+
+static const u32 turks_sysls_enable[] =
+{
+	0x000055e8, 0x00000001, 0xffffffff,
+	0x0000d0bc, 0x00000100, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x000020c0, 0x000c0c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x000004c8, 0x00000000, 0xffffffff,
+	0x000064ec, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00006dfc, 0x00000000, 0xffffffff
+};
+#define TURKS_SYSLS_ENABLE_LENGTH sizeof(turks_sysls_enable) / (3 * sizeof(u32))
+
+#endif
+
+u32 btc_valid_sclk[40] =
+{
+	5000,   10000,  15000,  20000,  25000,  30000,  35000,  40000,  45000,  50000,
+	55000,  60000,  65000,  70000,  75000,  80000,  85000,  90000,  95000,  100000,
+	105000, 110000, 11500,  120000, 125000, 130000, 135000, 140000, 145000, 150000,
+	155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000
+};
+
+static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
+{
+        { 10000, 30000, RADEON_SCLK_UP },
+        { 15000, 30000, RADEON_SCLK_UP },
+        { 20000, 30000, RADEON_SCLK_UP },
+        { 25000, 30000, RADEON_SCLK_UP }
+};
+
+void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
+					u32 clock, u16 max_voltage, u16 *voltage)
+{
+	u32 i;
+
+	if ((table == NULL) || (table->count == 0))
+		return;
+
+	for (i= 0; i < table->count; i++) {
+		if (clock <= table->entries[i].clk) {
+			if (*voltage < table->entries[i].v)
+				*voltage = (u16)((table->entries[i].v < max_voltage) ?
+						  table->entries[i].v : max_voltage);
+			return;
+		}
+	}
+
+	*voltage = (*voltage > max_voltage) ? *voltage : max_voltage;
+}
+
+static u32 btc_find_valid_clock(struct radeon_clock_array *clocks,
+				u32 max_clock, u32 requested_clock)
+{
+	unsigned int i;
+
+	if ((clocks == NULL) || (clocks->count == 0))
+		return (requested_clock < max_clock) ? requested_clock : max_clock;
+
+	for (i = 0; i < clocks->count; i++) {
+		if (clocks->values[i] >= requested_clock)
+			return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;
+	}
+
+	return (clocks->values[clocks->count - 1] < max_clock) ?
+		clocks->values[clocks->count - 1] : max_clock;
+}
+
+static u32 btc_get_valid_mclk(struct radeon_device *rdev,
+			      u32 max_mclk, u32 requested_mclk)
+{
+	return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_mclk_values,
+				    max_mclk, requested_mclk);
+}
+
+static u32 btc_get_valid_sclk(struct radeon_device *rdev,
+			      u32 max_sclk, u32 requested_sclk)
+{
+	return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_sclk_values,
+				    max_sclk, requested_sclk);
+}
+
+void btc_skip_blacklist_clocks(struct radeon_device *rdev,
+			       const u32 max_sclk, const u32 max_mclk,
+			       u32 *sclk, u32 *mclk)
+{
+	int i, num_blacklist_clocks;
+
+	if ((sclk == NULL) || (mclk == NULL))
+		return;
+
+	num_blacklist_clocks = ARRAY_SIZE(btc_blacklist_clocks);
+
+	for (i = 0; i < num_blacklist_clocks; i++) {
+		if ((btc_blacklist_clocks[i].sclk == *sclk) &&
+		    (btc_blacklist_clocks[i].mclk == *mclk))
+			break;
+	}
+
+	if (i < num_blacklist_clocks) {
+		if (btc_blacklist_clocks[i].action == RADEON_SCLK_UP) {
+			*sclk = btc_get_valid_sclk(rdev, max_sclk, *sclk + 1);
+
+			if (*sclk < max_sclk)
+				btc_skip_blacklist_clocks(rdev, max_sclk, max_mclk, sclk, mclk);
+		}
+	}
+}
+
+void btc_adjust_clock_combinations(struct radeon_device *rdev,
+				   const struct radeon_clock_and_voltage_limits *max_limits,
+				   struct rv7xx_pl *pl)
+{
+
+	if ((pl->mclk == 0) || (pl->sclk == 0))
+		return;
+
+	if (pl->mclk == pl->sclk)
+		return;
+
+	if (pl->mclk > pl->sclk) {
+		if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > rdev->pm.dpm.dyn_state.mclk_sclk_ratio)
+			pl->sclk = btc_get_valid_sclk(rdev,
+						      max_limits->sclk,
+						      (pl->mclk +
+						       (rdev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /
+						      rdev->pm.dpm.dyn_state.mclk_sclk_ratio);
+	} else {
+		if ((pl->sclk - pl->mclk) > rdev->pm.dpm.dyn_state.sclk_mclk_delta)
+			pl->mclk = btc_get_valid_mclk(rdev,
+						      max_limits->mclk,
+						      pl->sclk -
+						      rdev->pm.dpm.dyn_state.sclk_mclk_delta);
+	}
+}
+
+static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
+{
+	unsigned int i;
+
+	for (i = 0; i < table->count; i++) {
+		if (voltage <= table->entries[i].value)
+			return table->entries[i].value;
+	}
+
+	return table->entries[table->count - 1].value;
+}
+
+void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
+				   u16 max_vddc, u16 max_vddci,
+				   u16 *vddc, u16 *vddci)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u16 new_voltage;
+
+	if ((0 == *vddc) || (0 == *vddci))
+		return;
+
+	if (*vddc > *vddci) {
+		if ((*vddc - *vddci) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
+			new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table,
+						       (*vddc - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
+			*vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci;
+		}
+	} else {
+		if ((*vddci - *vddc) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
+			new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table,
+						       (*vddci - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
+			*vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc;
+		}
+	}
+}
+
+static void btc_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
+					     bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 tmp, bif;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+	if (enable) {
+		if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+		    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+			if (!pi->boot_in_gen2) {
+				bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
+				bif |= CG_CLIENT_REQ(0xd);
+				WREG32(CG_BIF_REQ_AND_RSP, bif);
+
+				tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+				tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
+				tmp |= LC_GEN2_EN_STRAP;
+
+				tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT;
+				WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+				udelay(10);
+				tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
+				WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+			}
+		}
+	} else {
+		if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
+		    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+			if (!pi->boot_in_gen2) {
+				bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
+				bif |= CG_CLIENT_REQ(0xd);
+				WREG32(CG_BIF_REQ_AND_RSP, bif);
+
+				tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+				tmp &= ~LC_GEN2_EN_STRAP;
+			}
+			WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+		}
+	}
+}
+
+static void btc_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
+					 bool enable)
+{
+	btc_enable_bif_dynamic_pcie_gen2(rdev, enable);
+
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
+}
+
+static int btc_disable_ulv(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (eg_pi->ulv.supported) {
+		if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableULV) != PPSMC_Result_OK)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static int btc_populate_ulv_state(struct radeon_device *rdev,
+				  RV770_SMC_STATETABLE *table)
+{
+	int ret = -EINVAL;
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
+
+	if (ulv_pl->vddc) {
+		ret = cypress_convert_power_level_to_smc(rdev,
+							 ulv_pl,
+							 &table->ULVState.levels[0],
+							 PPSMC_DISPLAY_WATERMARK_LOW);
+		if (ret == 0) {
+			table->ULVState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
+			table->ULVState.levels[0].ACIndex = 1;
+
+			table->ULVState.levels[1] = table->ULVState.levels[0];
+			table->ULVState.levels[2] = table->ULVState.levels[0];
+
+			table->ULVState.flags |= PPSMC_SWSTATE_FLAG_DC;
+
+			WREG32(CG_ULV_CONTROL, BTC_CGULVCONTROL_DFLT);
+			WREG32(CG_ULV_PARAMETER, BTC_CGULVPARAMETER_DFLT);
+		}
+	}
+
+	return ret;
+}
+
+static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
+				       RV770_SMC_STATETABLE *table)
+{
+	int ret = cypress_populate_smc_acpi_state(rdev, table);
+
+	if (ret == 0) {
+		table->ACPIState.levels[0].ACIndex = 0;
+		table->ACPIState.levels[1].ACIndex = 0;
+		table->ACPIState.levels[2].ACIndex = 0;
+	}
+
+	return ret;
+}
+
+void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
+				  const u32 *sequence, u32 count)
+{
+	u32 i, length = count * 3;
+	u32 tmp;
+
+	for (i = 0; i < length; i+=3) {
+		tmp = RREG32(sequence[i]);
+		tmp &= ~sequence[i+2];
+		tmp |= sequence[i+1] & sequence[i+2];
+		WREG32(sequence[i], tmp);
+	}
+}
+
+static void btc_cg_clock_gating_default(struct radeon_device *rdev)
+{
+	u32 count;
+	const u32 *p = NULL;
+
+	if (rdev->family == CHIP_BARTS) {
+		p = (const u32 *)&barts_cgcg_cgls_default;
+		count = BARTS_CGCG_CGLS_DEFAULT_LENGTH;
+	} else if (rdev->family == CHIP_TURKS) {
+		p = (const u32 *)&turks_cgcg_cgls_default;
+		count = TURKS_CGCG_CGLS_DEFAULT_LENGTH;
+	} else if (rdev->family == CHIP_CAICOS) {
+		p = (const u32 *)&caicos_cgcg_cgls_default;
+		count = CAICOS_CGCG_CGLS_DEFAULT_LENGTH;
+	} else
+		return;
+
+	btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_cg_clock_gating_enable(struct radeon_device *rdev,
+				       bool enable)
+{
+	u32 count;
+	const u32 *p = NULL;
+
+	if (enable) {
+		if (rdev->family == CHIP_BARTS) {
+			p = (const u32 *)&barts_cgcg_cgls_enable;
+			count = BARTS_CGCG_CGLS_ENABLE_LENGTH;
+		} else if (rdev->family == CHIP_TURKS) {
+			p = (const u32 *)&turks_cgcg_cgls_enable;
+			count = TURKS_CGCG_CGLS_ENABLE_LENGTH;
+		} else if (rdev->family == CHIP_CAICOS) {
+			p = (const u32 *)&caicos_cgcg_cgls_enable;
+			count = CAICOS_CGCG_CGLS_ENABLE_LENGTH;
+		} else
+			return;
+	} else {
+		if (rdev->family == CHIP_BARTS) {
+			p = (const u32 *)&barts_cgcg_cgls_disable;
+			count = BARTS_CGCG_CGLS_DISABLE_LENGTH;
+		} else if (rdev->family == CHIP_TURKS) {
+			p = (const u32 *)&turks_cgcg_cgls_disable;
+			count = TURKS_CGCG_CGLS_DISABLE_LENGTH;
+		} else if (rdev->family == CHIP_CAICOS) {
+			p = (const u32 *)&caicos_cgcg_cgls_disable;
+			count = CAICOS_CGCG_CGLS_DISABLE_LENGTH;
+		} else
+			return;
+	}
+
+	btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_mg_clock_gating_default(struct radeon_device *rdev)
+{
+	u32 count;
+	const u32 *p = NULL;
+
+	if (rdev->family == CHIP_BARTS) {
+		p = (const u32 *)&barts_mgcg_default;
+		count = BARTS_MGCG_DEFAULT_LENGTH;
+	} else if (rdev->family == CHIP_TURKS) {
+		p = (const u32 *)&turks_mgcg_default;
+		count = TURKS_MGCG_DEFAULT_LENGTH;
+	} else if (rdev->family == CHIP_CAICOS) {
+		p = (const u32 *)&caicos_mgcg_default;
+		count = CAICOS_MGCG_DEFAULT_LENGTH;
+	} else
+		return;
+
+	btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_mg_clock_gating_enable(struct radeon_device *rdev,
+				       bool enable)
+{
+	u32 count;
+	const u32 *p = NULL;
+
+	if (enable) {
+		if (rdev->family == CHIP_BARTS) {
+			p = (const u32 *)&barts_mgcg_enable;
+			count = BARTS_MGCG_ENABLE_LENGTH;
+		} else if (rdev->family == CHIP_TURKS) {
+			p = (const u32 *)&turks_mgcg_enable;
+			count = TURKS_MGCG_ENABLE_LENGTH;
+		} else if (rdev->family == CHIP_CAICOS) {
+			p = (const u32 *)&caicos_mgcg_enable;
+			count = CAICOS_MGCG_ENABLE_LENGTH;
+		} else
+			return;
+	} else {
+		if (rdev->family == CHIP_BARTS) {
+			p = (const u32 *)&barts_mgcg_disable[0];
+			count = BARTS_MGCG_DISABLE_LENGTH;
+		} else if (rdev->family == CHIP_TURKS) {
+			p = (const u32 *)&turks_mgcg_disable[0];
+			count = TURKS_MGCG_DISABLE_LENGTH;
+		} else if (rdev->family == CHIP_CAICOS) {
+			p = (const u32 *)&caicos_mgcg_disable[0];
+			count = CAICOS_MGCG_DISABLE_LENGTH;
+		} else
+			return;
+	}
+
+	btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_ls_clock_gating_default(struct radeon_device *rdev)
+{
+	u32 count;
+	const u32 *p = NULL;
+
+	if (rdev->family == CHIP_BARTS) {
+		p = (const u32 *)&barts_sysls_default;
+		count = BARTS_SYSLS_DEFAULT_LENGTH;
+	} else if (rdev->family == CHIP_TURKS) {
+		p = (const u32 *)&turks_sysls_default;
+		count = TURKS_SYSLS_DEFAULT_LENGTH;
+	} else if (rdev->family == CHIP_CAICOS) {
+		p = (const u32 *)&caicos_sysls_default;
+		count = CAICOS_SYSLS_DEFAULT_LENGTH;
+	} else
+		return;
+
+	btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_ls_clock_gating_enable(struct radeon_device *rdev,
+				       bool enable)
+{
+	u32 count;
+	const u32 *p = NULL;
+
+	if (enable) {
+		if (rdev->family == CHIP_BARTS) {
+			p = (const u32 *)&barts_sysls_enable;
+			count = BARTS_SYSLS_ENABLE_LENGTH;
+		} else if (rdev->family == CHIP_TURKS) {
+			p = (const u32 *)&turks_sysls_enable;
+			count = TURKS_SYSLS_ENABLE_LENGTH;
+		} else if (rdev->family == CHIP_CAICOS) {
+			p = (const u32 *)&caicos_sysls_enable;
+			count = CAICOS_SYSLS_ENABLE_LENGTH;
+		} else
+			return;
+	} else {
+		if (rdev->family == CHIP_BARTS) {
+			p = (const u32 *)&barts_sysls_disable;
+			count = BARTS_SYSLS_DISABLE_LENGTH;
+		} else if (rdev->family == CHIP_TURKS) {
+			p = (const u32 *)&turks_sysls_disable;
+			count = TURKS_SYSLS_DISABLE_LENGTH;
+		} else if (rdev->family == CHIP_CAICOS) {
+			p = (const u32 *)&caicos_sysls_disable;
+			count = CAICOS_SYSLS_DISABLE_LENGTH;
+		} else
+			return;
+	}
+
+	btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+bool btc_dpm_enabled(struct radeon_device *rdev)
+{
+	if (rv770_is_smc_running(rdev))
+		return true;
+	else
+		return false;
+}
+
+static int btc_init_smc_table(struct radeon_device *rdev,
+			      struct radeon_ps *radeon_boot_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	RV770_SMC_STATETABLE *table = &pi->smc_statetable;
+	int ret;
+
+	memset(table, 0, sizeof(RV770_SMC_STATETABLE));
+
+	cypress_populate_smc_voltage_tables(rdev, table);
+
+	switch (rdev->pm.int_thermal_type) {
+        case THERMAL_TYPE_EVERGREEN:
+        case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
+		break;
+        case THERMAL_TYPE_NONE:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
+		break;
+        default:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
+		break;
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
+
+	if (pi->mem_gddr5)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
+
+	ret = cypress_populate_smc_initial_state(rdev, radeon_boot_state, table);
+	if (ret)
+		return ret;
+
+	if (eg_pi->sclk_deep_sleep)
+		WREG32_P(SCLK_PSKIP_CNTL, PSKIP_ON_ALLOW_STOP_HI(32),
+			 ~PSKIP_ON_ALLOW_STOP_HI_MASK);
+
+	ret = btc_populate_smc_acpi_state(rdev, table);
+	if (ret)
+		return ret;
+
+	if (eg_pi->ulv.supported) {
+		ret = btc_populate_ulv_state(rdev, table);
+		if (ret)
+			eg_pi->ulv.supported = false;
+	}
+
+	table->driverState = table->initialState;
+
+	return rv770_copy_bytes_to_smc(rdev,
+				       pi->state_table_start,
+				       (u8 *)table,
+				       sizeof(RV770_SMC_STATETABLE),
+				       pi->sram_end);
+}
+
+static void btc_set_at_for_uvd(struct radeon_device *rdev,
+			       struct radeon_ps *radeon_new_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	int idx = 0;
+
+	if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2))
+		idx = 1;
+
+	if ((idx == 1) && !eg_pi->smu_uvd_hs) {
+		pi->rlp = 10;
+		pi->rmp = 100;
+		pi->lhp = 100;
+		pi->lmp = 10;
+	} else {
+		pi->rlp = eg_pi->ats[idx].rlp;
+		pi->rmp = eg_pi->ats[idx].rmp;
+		pi->lhp = eg_pi->ats[idx].lhp;
+		pi->lmp = eg_pi->ats[idx].lmp;
+	}
+
+}
+
+void btc_notify_uvd_to_smc(struct radeon_device *rdev,
+			   struct radeon_ps *radeon_new_state)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
+		rv770_write_smc_soft_register(rdev,
+					      RV770_SMC_SOFT_REGISTER_uvd_enabled, 1);
+		eg_pi->uvd_enabled = true;
+	} else {
+		rv770_write_smc_soft_register(rdev,
+					      RV770_SMC_SOFT_REGISTER_uvd_enabled, 0);
+		eg_pi->uvd_enabled = false;
+	}
+}
+
+int btc_reset_to_default(struct radeon_device *rdev)
+{
+	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void btc_stop_smc(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (((RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK) >> LB_SYNC_RESET_SEL_SHIFT) != 1)
+			break;
+		udelay(1);
+	}
+	udelay(100);
+
+	r7xx_stop_smc(rdev);
+}
+
+void btc_read_arb_registers(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct evergreen_arb_registers *arb_registers =
+		&eg_pi->bootup_arb_registers;
+
+	arb_registers->mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING);
+	arb_registers->mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
+	arb_registers->mc_arb_rfsh_rate = RREG32(MC_ARB_RFSH_RATE);
+	arb_registers->mc_arb_burst_time = RREG32(MC_ARB_BURST_TIME);
+}
+
+
+static void btc_set_arb0_registers(struct radeon_device *rdev,
+				   struct evergreen_arb_registers *arb_registers)
+{
+	u32 val;
+
+	WREG32(MC_ARB_DRAM_TIMING,  arb_registers->mc_arb_dram_timing);
+	WREG32(MC_ARB_DRAM_TIMING2, arb_registers->mc_arb_dram_timing2);
+
+	val = (arb_registers->mc_arb_rfsh_rate & POWERMODE0_MASK) >>
+		POWERMODE0_SHIFT;
+	WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
+
+	val = (arb_registers->mc_arb_burst_time & STATE0_MASK) >>
+		STATE0_SHIFT;
+	WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
+}
+
+static void btc_set_boot_state_timing(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (eg_pi->ulv.supported)
+		btc_set_arb0_registers(rdev, &eg_pi->bootup_arb_registers);
+}
+
+static bool btc_is_state_ulv_compatible(struct radeon_device *rdev,
+					struct radeon_ps *radeon_state)
+{
+	struct rv7xx_ps *state = rv770_get_ps(radeon_state);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
+
+	if (state->low.mclk != ulv_pl->mclk)
+		return false;
+
+	if (state->low.vddci != ulv_pl->vddci)
+		return false;
+
+	/* XXX check minclocks, etc. */
+
+	return true;
+}
+
+
+static int btc_set_ulv_dram_timing(struct radeon_device *rdev)
+{
+	u32 val;
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
+
+	radeon_atom_set_engine_dram_timings(rdev,
+					    ulv_pl->sclk,
+					    ulv_pl->mclk);
+
+	val = rv770_calculate_memory_refresh_rate(rdev, ulv_pl->sclk);
+	WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
+
+	val = cypress_calculate_burst_time(rdev, ulv_pl->sclk, ulv_pl->mclk);
+	WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
+
+	return 0;
+}
+
+static int btc_enable_ulv(struct radeon_device *rdev)
+{
+	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableULV) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int btc_set_power_state_conditionally_enable_ulv(struct radeon_device *rdev,
+							struct radeon_ps *radeon_new_state)
+{
+	int ret = 0;
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (eg_pi->ulv.supported) {
+		if (btc_is_state_ulv_compatible(rdev, radeon_new_state)) {
+			// Set ARB[0] to reflect the DRAM timing needed for ULV.
+			ret = btc_set_ulv_dram_timing(rdev);
+			if (ret == 0)
+				ret = btc_enable_ulv(rdev);
+		}
+	}
+
+	return ret;
+}
+
+static bool btc_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
+{
+	bool result = true;
+
+	switch (in_reg) {
+	case MC_SEQ_RAS_TIMING >> 2:
+		*out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
+		break;
+        case MC_SEQ_CAS_TIMING >> 2:
+		*out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
+		break;
+        case MC_SEQ_MISC_TIMING >> 2:
+		*out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
+		break;
+        case MC_SEQ_MISC_TIMING2 >> 2:
+		*out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
+		break;
+        case MC_SEQ_RD_CTL_D0 >> 2:
+		*out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
+		break;
+        case MC_SEQ_RD_CTL_D1 >> 2:
+		*out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
+		break;
+        case MC_SEQ_WR_CTL_D0 >> 2:
+		*out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
+		break;
+        case MC_SEQ_WR_CTL_D1 >> 2:
+		*out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
+		break;
+        case MC_PMG_CMD_EMRS >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
+		break;
+        case MC_PMG_CMD_MRS >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
+		break;
+        case MC_PMG_CMD_MRS1 >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+		break;
+        default:
+		result = false;
+		break;
+	}
+
+	return result;
+}
+
+static void btc_set_valid_flag(struct evergreen_mc_reg_table *table)
+{
+	u8 i, j;
+
+	for (i = 0; i < table->last; i++) {
+		for (j = 1; j < table->num_entries; j++) {
+			if (table->mc_reg_table_entry[j-1].mc_data[i] !=
+			    table->mc_reg_table_entry[j].mc_data[i]) {
+				table->valid_flag |= (1 << i);
+				break;
+			}
+		}
+	}
+}
+
+static int btc_set_mc_special_registers(struct radeon_device *rdev,
+					struct evergreen_mc_reg_table *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u8 i, j, k;
+	u32 tmp;
+
+	for (i = 0, j = table->last; i < table->last; i++) {
+		switch (table->mc_reg_address[i].s1) {
+		case MC_SEQ_MISC1 >> 2:
+			tmp = RREG32(MC_PMG_CMD_EMRS);
+			table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
+			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
+			for (k = 0; k < table->num_entries; k++) {
+				table->mc_reg_table_entry[k].mc_data[j] =
+					((tmp & 0xffff0000)) |
+					((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
+			}
+			j++;
+
+			if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+
+			tmp = RREG32(MC_PMG_CMD_MRS);
+			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
+			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
+			for (k = 0; k < table->num_entries; k++) {
+				table->mc_reg_table_entry[k].mc_data[j] =
+					(tmp & 0xffff0000) |
+					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+				if (!pi->mem_gddr5)
+					table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
+			}
+			j++;
+
+			if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+			break;
+		case MC_SEQ_RESERVE_M >> 2:
+			tmp = RREG32(MC_PMG_CMD_MRS1);
+			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
+			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+			for (k = 0; k < table->num_entries; k++) {
+				table->mc_reg_table_entry[k].mc_data[j] =
+					(tmp & 0xffff0000) |
+					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+			}
+			j++;
+
+			if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+			break;
+		default:
+			break;
+		}
+	}
+
+	table->last = j;
+
+	return 0;
+}
+
+static void btc_set_s0_mc_reg_index(struct evergreen_mc_reg_table *table)
+{
+	u32 i;
+	u16 address;
+
+	for (i = 0; i < table->last; i++) {
+		table->mc_reg_address[i].s0 =
+			btc_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
+			address : table->mc_reg_address[i].s1;
+	}
+}
+
+static int btc_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
+				       struct evergreen_mc_reg_table *eg_table)
+{
+	u8 i, j;
+
+	if (table->last > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
+		return -EINVAL;
+
+	if (table->num_entries > MAX_AC_TIMING_ENTRIES)
+		return -EINVAL;
+
+	for (i = 0; i < table->last; i++)
+		eg_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
+	eg_table->last = table->last;
+
+	for (i = 0; i < table->num_entries; i++) {
+		eg_table->mc_reg_table_entry[i].mclk_max =
+			table->mc_reg_table_entry[i].mclk_max;
+		for(j = 0; j < table->last; j++)
+			eg_table->mc_reg_table_entry[i].mc_data[j] =
+				table->mc_reg_table_entry[i].mc_data[j];
+	}
+	eg_table->num_entries = table->num_entries;
+
+	return 0;
+}
+
+static int btc_initialize_mc_reg_table(struct radeon_device *rdev)
+{
+	int ret;
+	struct atom_mc_reg_table *table;
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct evergreen_mc_reg_table *eg_table = &eg_pi->mc_reg_table;
+	u8 module_index = rv770_get_memory_module_index(rdev);
+
+	table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
+	if (!table)
+		return -ENOMEM;
+
+	/* Program additional LP registers that are no longer programmed by VBIOS */
+	WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
+	WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
+	WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
+	WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
+	WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
+	WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
+	WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
+	WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
+	WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
+	WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
+	WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
+
+	ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
+
+	if (ret)
+		goto init_mc_done;
+
+	ret = btc_copy_vbios_mc_reg_table(table, eg_table);
+
+	if (ret)
+		goto init_mc_done;
+
+	btc_set_s0_mc_reg_index(eg_table);
+	ret = btc_set_mc_special_registers(rdev, eg_table);
+
+	if (ret)
+		goto init_mc_done;
+
+	btc_set_valid_flag(eg_table);
+
+init_mc_done:
+	kfree(table);
+
+	return ret;
+}
+
+static void btc_init_stutter_mode(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 tmp;
+
+	if (pi->mclk_stutter_mode_threshold) {
+		if (pi->mem_gddr5) {
+			tmp = RREG32(MC_PMG_AUTO_CFG);
+			if ((0x200 & tmp) == 0) {
+				tmp = (tmp & 0xfffffc0b) | 0x204;
+				WREG32(MC_PMG_AUTO_CFG, tmp);
+			}
+		}
+	}
+}
+
+bool btc_dpm_vblank_too_short(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 vblank_time = r600_dpm_get_vblank_time(rdev);
+	u32 switch_limit = pi->mem_gddr5 ? 450 : 100;
+
+	if (vblank_time < switch_limit)
+		return true;
+	else
+		return false;
+
+}
+
+static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
+					 struct radeon_ps *rps)
+{
+	struct rv7xx_ps *ps = rv770_get_ps(rps);
+	struct radeon_clock_and_voltage_limits *max_limits;
+	bool disable_mclk_switching;
+	u32 mclk, sclk;
+	u16 vddc, vddci;
+
+	if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
+	    btc_dpm_vblank_too_short(rdev))
+		disable_mclk_switching = true;
+	else
+		disable_mclk_switching = false;
+
+	if (rdev->pm.dpm.ac_power)
+		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
+	else
+		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
+
+	if (rdev->pm.dpm.ac_power == false) {
+		if (ps->high.mclk > max_limits->mclk)
+			ps->high.mclk = max_limits->mclk;
+		if (ps->high.sclk > max_limits->sclk)
+			ps->high.sclk = max_limits->sclk;
+		if (ps->high.vddc > max_limits->vddc)
+			ps->high.vddc = max_limits->vddc;
+		if (ps->high.vddci > max_limits->vddci)
+			ps->high.vddci = max_limits->vddci;
+
+		if (ps->medium.mclk > max_limits->mclk)
+			ps->medium.mclk = max_limits->mclk;
+		if (ps->medium.sclk > max_limits->sclk)
+			ps->medium.sclk = max_limits->sclk;
+		if (ps->medium.vddc > max_limits->vddc)
+			ps->medium.vddc = max_limits->vddc;
+		if (ps->medium.vddci > max_limits->vddci)
+			ps->medium.vddci = max_limits->vddci;
+
+		if (ps->low.mclk > max_limits->mclk)
+			ps->low.mclk = max_limits->mclk;
+		if (ps->low.sclk > max_limits->sclk)
+			ps->low.sclk = max_limits->sclk;
+		if (ps->low.vddc > max_limits->vddc)
+			ps->low.vddc = max_limits->vddc;
+		if (ps->low.vddci > max_limits->vddci)
+			ps->low.vddci = max_limits->vddci;
+	}
+
+	/* XXX validate the min clocks required for display */
+
+	if (disable_mclk_switching) {
+		sclk = ps->low.sclk;
+		mclk = ps->high.mclk;
+		vddc = ps->low.vddc;
+		vddci = ps->high.vddci;
+	} else {
+		sclk = ps->low.sclk;
+		mclk = ps->low.mclk;
+		vddc = ps->low.vddc;
+		vddci = ps->low.vddci;
+	}
+
+	/* adjusted low state */
+	ps->low.sclk = sclk;
+	ps->low.mclk = mclk;
+	ps->low.vddc = vddc;
+	ps->low.vddci = vddci;
+
+	btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
+				  &ps->low.sclk, &ps->low.mclk);
+
+	/* adjusted medium, high states */
+	if (ps->medium.sclk < ps->low.sclk)
+		ps->medium.sclk = ps->low.sclk;
+	if (ps->medium.vddc < ps->low.vddc)
+		ps->medium.vddc = ps->low.vddc;
+	if (ps->high.sclk < ps->medium.sclk)
+		ps->high.sclk = ps->medium.sclk;
+	if (ps->high.vddc < ps->medium.vddc)
+		ps->high.vddc = ps->medium.vddc;
+
+	if (disable_mclk_switching) {
+		mclk = ps->low.mclk;
+		if (mclk < ps->medium.mclk)
+			mclk = ps->medium.mclk;
+		if (mclk < ps->high.mclk)
+			mclk = ps->high.mclk;
+		ps->low.mclk = mclk;
+		ps->low.vddci = vddci;
+		ps->medium.mclk = mclk;
+		ps->medium.vddci = vddci;
+		ps->high.mclk = mclk;
+		ps->high.vddci = vddci;
+	} else {
+		if (ps->medium.mclk < ps->low.mclk)
+			ps->medium.mclk = ps->low.mclk;
+		if (ps->medium.vddci < ps->low.vddci)
+			ps->medium.vddci = ps->low.vddci;
+		if (ps->high.mclk < ps->medium.mclk)
+			ps->high.mclk = ps->medium.mclk;
+		if (ps->high.vddci < ps->medium.vddci)
+			ps->high.vddci = ps->medium.vddci;
+	}
+
+	btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
+				  &ps->medium.sclk, &ps->medium.mclk);
+	btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
+				  &ps->high.sclk, &ps->high.mclk);
+
+	btc_adjust_clock_combinations(rdev, max_limits, &ps->low);
+	btc_adjust_clock_combinations(rdev, max_limits, &ps->medium);
+	btc_adjust_clock_combinations(rdev, max_limits, &ps->high);
+
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
+					   ps->low.sclk, max_limits->vddc, &ps->low.vddc);
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+					   ps->low.mclk, max_limits->vddci, &ps->low.vddci);
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+					   ps->low.mclk, max_limits->vddc, &ps->low.vddc);
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+					   rdev->clock.current_dispclk, max_limits->vddc, &ps->low.vddc);
+
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
+					   ps->medium.sclk, max_limits->vddc, &ps->medium.vddc);
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+					   ps->medium.mclk, max_limits->vddci, &ps->medium.vddci);
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+					   ps->medium.mclk, max_limits->vddc, &ps->medium.vddc);
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+					   rdev->clock.current_dispclk, max_limits->vddc, &ps->medium.vddc);
+
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
+					   ps->high.sclk, max_limits->vddc, &ps->high.vddc);
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+					   ps->high.mclk, max_limits->vddci, &ps->high.vddci);
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+					   ps->high.mclk, max_limits->vddc, &ps->high.vddc);
+	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+					   rdev->clock.current_dispclk, max_limits->vddc, &ps->high.vddc);
+
+	btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
+				      &ps->low.vddc, &ps->low.vddci);
+	btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
+				      &ps->medium.vddc, &ps->medium.vddci);
+	btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
+				      &ps->high.vddc, &ps->high.vddci);
+
+	if ((ps->high.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
+	    (ps->medium.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
+	    (ps->low.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc))
+		ps->dc_compatible = true;
+	else
+		ps->dc_compatible = false;
+
+	if (ps->low.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
+		ps->low.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
+	if (ps->medium.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
+		ps->medium.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
+	if (ps->high.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
+		ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
+}
+
+static void btc_update_current_ps(struct radeon_device *rdev,
+				  struct radeon_ps *rps)
+{
+	struct rv7xx_ps *new_ps = rv770_get_ps(rps);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	eg_pi->current_rps = *rps;
+	eg_pi->current_ps = *new_ps;
+	eg_pi->current_rps.ps_priv = &eg_pi->current_ps;
+}
+
+static void btc_update_requested_ps(struct radeon_device *rdev,
+				    struct radeon_ps *rps)
+{
+	struct rv7xx_ps *new_ps = rv770_get_ps(rps);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	eg_pi->requested_rps = *rps;
+	eg_pi->requested_ps = *new_ps;
+	eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps;
+}
+
+void btc_dpm_reset_asic(struct radeon_device *rdev)
+{
+	rv770_restrict_performance_levels_before_switch(rdev);
+	btc_disable_ulv(rdev);
+	btc_set_boot_state_timing(rdev);
+	rv770_set_boot_state(rdev);
+}
+
+int btc_dpm_pre_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
+	struct radeon_ps *new_ps = &requested_ps;
+
+	btc_update_requested_ps(rdev, new_ps);
+
+	btc_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
+
+	return 0;
+}
+
+int btc_dpm_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *new_ps = &eg_pi->requested_rps;
+	struct radeon_ps *old_ps = &eg_pi->current_rps;
+	int ret;
+
+	ret = btc_disable_ulv(rdev);
+	btc_set_boot_state_timing(rdev);
+	ret = rv770_restrict_performance_levels_before_switch(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_restrict_performance_levels_before_switch failed\n");
+		return ret;
+	}
+	if (eg_pi->pcie_performance_request)
+		cypress_notify_link_speed_change_before_state_change(rdev, new_ps, old_ps);
+
+	rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+	ret = rv770_halt_smc(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_halt_smc failed\n");
+		return ret;
+	}
+	btc_set_at_for_uvd(rdev, new_ps);
+	if (eg_pi->smu_uvd_hs)
+		btc_notify_uvd_to_smc(rdev, new_ps);
+	ret = cypress_upload_sw_state(rdev, new_ps);
+	if (ret) {
+		DRM_ERROR("cypress_upload_sw_state failed\n");
+		return ret;
+	}
+	if (eg_pi->dynamic_ac_timing) {
+		ret = cypress_upload_mc_reg_table(rdev, new_ps);
+		if (ret) {
+			DRM_ERROR("cypress_upload_mc_reg_table failed\n");
+			return ret;
+		}
+	}
+
+	cypress_program_memory_timing_parameters(rdev, new_ps);
+
+	ret = rv770_resume_smc(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_resume_smc failed\n");
+		return ret;
+	}
+	ret = rv770_set_sw_state(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_set_sw_state failed\n");
+		return ret;
+	}
+	rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+
+	if (eg_pi->pcie_performance_request)
+		cypress_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
+
+	ret = btc_set_power_state_conditionally_enable_ulv(rdev, new_ps);
+	if (ret) {
+		DRM_ERROR("btc_set_power_state_conditionally_enable_ulv failed\n");
+		return ret;
+	}
+
+	ret = rv770_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO);
+	if (ret) {
+		DRM_ERROR("rv770_dpm_force_performance_level failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+void btc_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *new_ps = &eg_pi->requested_rps;
+
+	btc_update_current_ps(rdev, new_ps);
+}
+
+int btc_dpm_enable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+	int ret;
+
+	if (pi->gfx_clock_gating)
+		btc_cg_clock_gating_default(rdev);
+
+	if (btc_dpm_enabled(rdev))
+		return -EINVAL;
+
+	if (pi->mg_clock_gating)
+		btc_mg_clock_gating_default(rdev);
+
+	if (eg_pi->ls_clock_gating)
+		btc_ls_clock_gating_default(rdev);
+
+	if (pi->voltage_control) {
+		rv770_enable_voltage_control(rdev, true);
+		ret = cypress_construct_voltage_tables(rdev);
+		if (ret) {
+			DRM_ERROR("cypress_construct_voltage_tables failed\n");
+			return ret;
+		}
+	}
+
+	if (pi->mvdd_control) {
+		ret = cypress_get_mvdd_configuration(rdev);
+		if (ret) {
+			DRM_ERROR("cypress_get_mvdd_configuration failed\n");
+			return ret;
+		}
+	}
+
+	if (eg_pi->dynamic_ac_timing) {
+		ret = btc_initialize_mc_reg_table(rdev);
+		if (ret)
+			eg_pi->dynamic_ac_timing = false;
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
+		rv770_enable_backbias(rdev, true);
+
+	if (pi->dynamic_ss)
+		cypress_enable_spread_spectrum(rdev, true);
+
+	if (pi->thermal_protection)
+		rv770_enable_thermal_protection(rdev, true);
+
+	rv770_setup_bsp(rdev);
+	rv770_program_git(rdev);
+	rv770_program_tp(rdev);
+	rv770_program_tpp(rdev);
+	rv770_program_sstp(rdev);
+	rv770_program_engine_speed_parameters(rdev);
+	cypress_enable_display_gap(rdev);
+	rv770_program_vc(rdev);
+
+	if (pi->dynamic_pcie_gen2)
+		btc_enable_dynamic_pcie_gen2(rdev, true);
+
+	ret = rv770_upload_firmware(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_upload_firmware failed\n");
+		return ret;
+	}
+	ret = cypress_get_table_locations(rdev);
+	if (ret) {
+		DRM_ERROR("cypress_get_table_locations failed\n");
+		return ret;
+	}
+	ret = btc_init_smc_table(rdev, boot_ps);
+	if (ret)
+		return ret;
+
+	if (eg_pi->dynamic_ac_timing) {
+		ret = cypress_populate_mc_reg_table(rdev, boot_ps);
+		if (ret) {
+			DRM_ERROR("cypress_populate_mc_reg_table failed\n");
+			return ret;
+		}
+	}
+
+	cypress_program_response_times(rdev);
+	r7xx_start_smc(rdev);
+	ret = cypress_notify_smc_display_change(rdev, false);
+	if (ret) {
+		DRM_ERROR("cypress_notify_smc_display_change failed\n");
+		return ret;
+	}
+	cypress_enable_sclk_control(rdev, true);
+
+	if (eg_pi->memory_transition)
+		cypress_enable_mclk_control(rdev, true);
+
+	cypress_start_dpm(rdev);
+
+	if (pi->gfx_clock_gating)
+		btc_cg_clock_gating_enable(rdev, true);
+
+	if (pi->mg_clock_gating)
+		btc_mg_clock_gating_enable(rdev, true);
+
+	if (eg_pi->ls_clock_gating)
+		btc_ls_clock_gating_enable(rdev, true);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		PPSMC_Result result;
+
+		ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+		if (ret)
+			return ret;
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+		result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
+
+		if (result != PPSMC_Result_OK)
+			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
+	}
+
+	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+	btc_init_stutter_mode(rdev);
+
+	btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
+	return 0;
+};
+
+void btc_dpm_disable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (!btc_dpm_enabled(rdev))
+		return;
+
+	rv770_clear_vc(rdev);
+
+	if (pi->thermal_protection)
+		rv770_enable_thermal_protection(rdev, false);
+
+	if (pi->dynamic_pcie_gen2)
+		btc_enable_dynamic_pcie_gen2(rdev, false);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		rdev->irq.dpm_thermal = false;
+		radeon_irq_set(rdev);
+	}
+
+	if (pi->gfx_clock_gating)
+		btc_cg_clock_gating_enable(rdev, false);
+
+	if (pi->mg_clock_gating)
+		btc_mg_clock_gating_enable(rdev, false);
+
+	if (eg_pi->ls_clock_gating)
+		btc_ls_clock_gating_enable(rdev, false);
+
+	rv770_stop_dpm(rdev);
+	btc_reset_to_default(rdev);
+	btc_stop_smc(rdev);
+	cypress_enable_spread_spectrum(rdev, false);
+
+	btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+}
+
+void btc_dpm_setup_asic(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	rv770_get_memory_type(rdev);
+	rv740_read_clock_registers(rdev);
+	btc_read_arb_registers(rdev);
+	rv770_read_voltage_smio_registers(rdev);
+
+	if (eg_pi->pcie_performance_request)
+		cypress_advertise_gen2_capability(rdev);
+
+	rv770_get_pcie_gen2_status(rdev);
+	rv770_enable_acpi_pm(rdev);
+}
+
+int btc_dpm_init(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi;
+	struct evergreen_power_info *eg_pi;
+	struct atom_clock_dividers dividers;
+	int ret;
+
+	eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL);
+	if (eg_pi == NULL)
+		return -ENOMEM;
+	rdev->pm.dpm.priv = eg_pi;
+	pi = &eg_pi->rv7xx;
+
+	rv770_get_max_vddc(rdev);
+
+	eg_pi->ulv.supported = false;
+	pi->acpi_vddc = 0;
+	eg_pi->acpi_vddci = 0;
+	pi->min_vddc_in_table = 0;
+	pi->max_vddc_in_table = 0;
+
+	ret = rv7xx_parse_power_table(rdev);
+	if (ret)
+		return ret;
+	ret = r600_parse_extended_power_table(rdev);
+	if (ret)
+		return ret;
+
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
+		kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL);
+	if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
+		r600_free_extended_power_table(rdev);
+		return -ENOMEM;
+	}
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 800;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 800;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 800;
+
+	if (rdev->pm.dpm.voltage_response_time == 0)
+		rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
+	if (rdev->pm.dpm.backbias_response_time == 0)
+		rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     0, false, &dividers);
+	if (ret)
+		pi->ref_div = dividers.ref_div + 1;
+	else
+		pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
+
+	pi->mclk_strobe_mode_threshold = 40000;
+	pi->mclk_edc_enable_threshold = 40000;
+	eg_pi->mclk_edc_wr_enable_threshold = 40000;
+
+	pi->rlp = RV770_RLP_DFLT;
+	pi->rmp = RV770_RMP_DFLT;
+	pi->lhp = RV770_LHP_DFLT;
+	pi->lmp = RV770_LMP_DFLT;
+
+	eg_pi->ats[0].rlp = RV770_RLP_DFLT;
+	eg_pi->ats[0].rmp = RV770_RMP_DFLT;
+	eg_pi->ats[0].lhp = RV770_LHP_DFLT;
+	eg_pi->ats[0].lmp = RV770_LMP_DFLT;
+
+	eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
+	eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
+	eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
+	eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
+
+	eg_pi->smu_uvd_hs = true;
+
+	pi->voltage_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
+
+	pi->mvdd_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
+
+	eg_pi->vddci_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
+
+	rv770_get_engine_memory_ss(rdev);
+
+	pi->asi = RV770_ASI_DFLT;
+	pi->pasi = CYPRESS_HASI_DFLT;
+	pi->vrc = CYPRESS_VRC_DFLT;
+
+	pi->power_gating = false;
+
+	pi->gfx_clock_gating = true;
+
+	pi->mg_clock_gating = true;
+	pi->mgcgtssm = true;
+	eg_pi->ls_clock_gating = false;
+	eg_pi->sclk_deep_sleep = false;
+
+	pi->dynamic_pcie_gen2 = true;
+
+	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
+		pi->thermal_protection = true;
+	else
+		pi->thermal_protection = false;
+
+	pi->display_gap = true;
+
+	if (rdev->flags & RADEON_IS_MOBILITY)
+		pi->dcodt = true;
+	else
+		pi->dcodt = false;
+
+	pi->ulps = true;
+
+	eg_pi->dynamic_ac_timing = true;
+	eg_pi->abm = true;
+	eg_pi->mcls = true;
+	eg_pi->light_sleep = true;
+	eg_pi->memory_transition = true;
+#if defined(CONFIG_ACPI)
+	eg_pi->pcie_performance_request =
+		radeon_acpi_is_pcie_performance_request_supported(rdev);
+#else
+	eg_pi->pcie_performance_request = false;
+#endif
+
+	if (rdev->family == CHIP_BARTS)
+		eg_pi->dll_default_on = true;
+	else
+		eg_pi->dll_default_on = false;
+
+	eg_pi->sclk_deep_sleep = false;
+	if (ASIC_IS_LOMBOK(rdev))
+		pi->mclk_stutter_mode_threshold = 30000;
+	else
+		pi->mclk_stutter_mode_threshold = 0;
+
+	pi->sram_end = SMC_RAM_END;
+
+	rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
+	rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
+	rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900;
+	rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk);
+	rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk;
+	rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
+	rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
+
+	if (rdev->family == CHIP_TURKS)
+		rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
+	else
+		rdev->pm.dpm.dyn_state.sclk_mclk_delta = 10000;
+
+	return 0;
+}
+
+void btc_dpm_fini(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	}
+	kfree(rdev->pm.dpm.ps);
+	kfree(rdev->pm.dpm.priv);
+	kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
+	r600_free_extended_power_table(rdev);
+}
+
+u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
+
+	if (low)
+		return requested_state->low.sclk;
+	else
+		return requested_state->high.sclk;
+}
+
+u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
+
+	if (low)
+		return requested_state->low.mclk;
+	else
+		return requested_state->high.mclk;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/btc_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/btc_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/btc_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/btc_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __BTC_DPM_H__
+#define __BTC_DPM_H__
+
+#define BTC_RLP_UVD_DFLT                              20
+#define BTC_RMP_UVD_DFLT                              50
+#define BTC_LHP_UVD_DFLT                              50
+#define BTC_LMP_UVD_DFLT                              20
+#define BARTS_MGCGCGTSSMCTRL_DFLT                     0x81944000
+#define TURKS_MGCGCGTSSMCTRL_DFLT                     0x6e944000
+#define CAICOS_MGCGCGTSSMCTRL_DFLT                    0x46944040
+#define BTC_CGULVPARAMETER_DFLT                       0x00040035
+#define BTC_CGULVCONTROL_DFLT                         0x00001450
+
+extern u32 btc_valid_sclk[40];
+
+void btc_read_arb_registers(struct radeon_device *rdev);
+void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
+				  const u32 *sequence, u32 count);
+void btc_skip_blacklist_clocks(struct radeon_device *rdev,
+			       const u32 max_sclk, const u32 max_mclk,
+			       u32 *sclk, u32 *mclk);
+void btc_adjust_clock_combinations(struct radeon_device *rdev,
+				   const struct radeon_clock_and_voltage_limits *max_limits,
+				   struct rv7xx_pl *pl);
+void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
+					u32 clock, u16 max_voltage, u16 *voltage);
+void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
+				   u16 max_vddc, u16 max_vddci,
+				   u16 *vddc, u16 *vddci);
+bool btc_dpm_enabled(struct radeon_device *rdev);
+int btc_reset_to_default(struct radeon_device *rdev);
+void btc_notify_uvd_to_smc(struct radeon_device *rdev,
+			   struct radeon_ps *radeon_new_state);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cik_blit_shaders.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cik_blit_shaders.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cik_blit_shaders.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cik_blit_shaders.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 (including the next
+ * paragraph) 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 COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS 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.
+ *
+ * Authors:
+ *     Alex Deucher <alexander.deucher@amd.com>
+ */
+
+#include <linux/types.h>
+#include <linux/bug.h>
+#include <linux/kernel.h>
+
+const u32 cik_default_state[] =
+{
+	0xc0066900,
+	0x00000000,
+	0x00000060, /* DB_RENDER_CONTROL */
+	0x00000000, /* DB_COUNT_CONTROL */
+	0x00000000, /* DB_DEPTH_VIEW */
+	0x0000002a, /* DB_RENDER_OVERRIDE */
+	0x00000000, /* DB_RENDER_OVERRIDE2 */
+	0x00000000, /* DB_HTILE_DATA_BASE */
+
+	0xc0046900,
+	0x00000008,
+	0x00000000, /* DB_DEPTH_BOUNDS_MIN */
+	0x00000000, /* DB_DEPTH_BOUNDS_MAX */
+	0x00000000, /* DB_STENCIL_CLEAR */
+	0x00000000, /* DB_DEPTH_CLEAR */
+
+	0xc0036900,
+	0x0000000f,
+	0x00000000, /* DB_DEPTH_INFO */
+	0x00000000, /* DB_Z_INFO */
+	0x00000000, /* DB_STENCIL_INFO */
+
+	0xc0016900,
+	0x00000080,
+	0x00000000, /* PA_SC_WINDOW_OFFSET */
+
+	0xc00d6900,
+	0x00000083,
+	0x0000ffff, /* PA_SC_CLIPRECT_RULE */
+	0x00000000, /* PA_SC_CLIPRECT_0_TL */
+	0x20002000, /* PA_SC_CLIPRECT_0_BR */
+	0x00000000,
+	0x20002000,
+	0x00000000,
+	0x20002000,
+	0x00000000,
+	0x20002000,
+	0xaaaaaaaa, /* PA_SC_EDGERULE */
+	0x00000000, /* PA_SU_HARDWARE_SCREEN_OFFSET */
+	0x0000000f, /* CB_TARGET_MASK */
+	0x0000000f, /* CB_SHADER_MASK */
+
+	0xc0226900,
+	0x00000094,
+	0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */
+	0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x00000000, /* PA_SC_VPORT_ZMIN_0 */
+	0x3f800000, /* PA_SC_VPORT_ZMAX_0 */
+
+	0xc0046900,
+	0x00000100,
+	0xffffffff, /* VGT_MAX_VTX_INDX */
+	0x00000000, /* VGT_MIN_VTX_INDX */
+	0x00000000, /* VGT_INDX_OFFSET */
+	0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */
+
+	0xc0046900,
+	0x00000105,
+	0x00000000, /* CB_BLEND_RED */
+	0x00000000, /* CB_BLEND_GREEN */
+	0x00000000, /* CB_BLEND_BLUE */
+	0x00000000, /* CB_BLEND_ALPHA */
+
+	0xc0016900,
+	0x000001e0,
+	0x00000000, /* CB_BLEND0_CONTROL */
+
+	0xc00c6900,
+	0x00000200,
+	0x00000000, /* DB_DEPTH_CONTROL */
+	0x00000000, /* DB_EQAA */
+	0x00cc0010, /* CB_COLOR_CONTROL */
+	0x00000210, /* DB_SHADER_CONTROL */
+	0x00010000, /* PA_CL_CLIP_CNTL */
+	0x00000004, /* PA_SU_SC_MODE_CNTL */
+	0x00000100, /* PA_CL_VTE_CNTL */
+	0x00000000, /* PA_CL_VS_OUT_CNTL */
+	0x00000000, /* PA_CL_NANINF_CNTL */
+	0x00000000, /* PA_SU_LINE_STIPPLE_CNTL */
+	0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */
+	0x00000000, /* PA_SU_PRIM_FILTER_CNTL */
+
+	0xc0116900,
+	0x00000280,
+	0x00000000, /* PA_SU_POINT_SIZE */
+	0x00000000, /* PA_SU_POINT_MINMAX */
+	0x00000008, /* PA_SU_LINE_CNTL */
+	0x00000000, /* PA_SC_LINE_STIPPLE */
+	0x00000000, /* VGT_OUTPUT_PATH_CNTL */
+	0x00000000, /* VGT_HOS_CNTL */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000, /* VGT_GS_MODE */
+
+	0xc0026900,
+	0x00000292,
+	0x00000000, /* PA_SC_MODE_CNTL_0 */
+	0x00000000, /* PA_SC_MODE_CNTL_1 */
+
+	0xc0016900,
+	0x000002a1,
+	0x00000000, /* VGT_PRIMITIVEID_EN */
+
+	0xc0016900,
+	0x000002a5,
+	0x00000000, /* VGT_MULTI_PRIM_IB_RESET_EN */
+
+	0xc0026900,
+	0x000002a8,
+	0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */
+	0x00000000,
+
+	0xc0026900,
+	0x000002ad,
+	0x00000000, /* VGT_REUSE_OFF */
+	0x00000000,
+
+	0xc0016900,
+	0x000002d5,
+	0x00000000, /* VGT_SHADER_STAGES_EN */
+
+	0xc0016900,
+	0x000002dc,
+	0x0000aa00, /* DB_ALPHA_TO_MASK */
+
+	0xc0066900,
+	0x000002de,
+	0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+
+	0xc0026900,
+	0x000002e5,
+	0x00000000, /* VGT_STRMOUT_CONFIG */
+	0x00000000,
+
+	0xc01b6900,
+	0x000002f5,
+	0x76543210, /* PA_SC_CENTROID_PRIORITY_0 */
+	0xfedcba98, /* PA_SC_CENTROID_PRIORITY_1 */
+	0x00000000, /* PA_SC_LINE_CNTL */
+	0x00000000, /* PA_SC_AA_CONFIG */
+	0x00000005, /* PA_SU_VTX_CNTL */
+	0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */
+	0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */
+	0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */
+	0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */
+	0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xffffffff, /* PA_SC_AA_MASK_X0Y0_X1Y0 */
+	0xffffffff,
+
+	0xc0026900,
+	0x00000316,
+	0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */
+	0x00000010, /*  */
+};
+
+const u32 cik_default_size = ARRAY_SIZE(cik_default_state);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cik_blit_shaders.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cik_blit_shaders.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cik_blit_shaders.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cik_blit_shaders.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 (including the next
+ * paragraph) 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 COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS 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 CIK_BLIT_SHADERS_H
+#define CIK_BLIT_SHADERS_H
+
+extern const u32 cik_default_state[];
+
+extern const u32 cik_default_size;
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cik.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cik.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cik.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cik.c	2013-08-31 17:51:52.000000000 -0400
@@ -0,0 +1,6998 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include "drmP.h"
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "cikd.h"
+#include "atom.h"
+#include "cik_blit_shaders.h"
+
+/* GFX */
+#define CIK_PFP_UCODE_SIZE 2144
+#define CIK_ME_UCODE_SIZE 2144
+#define CIK_CE_UCODE_SIZE 2144
+/* compute */
+#define CIK_MEC_UCODE_SIZE 4192
+/* interrupts */
+#define BONAIRE_RLC_UCODE_SIZE 2048
+#define KB_RLC_UCODE_SIZE 2560
+#define KV_RLC_UCODE_SIZE 2560
+/* gddr controller */
+#define CIK_MC_UCODE_SIZE 7866
+/* sdma */
+#define CIK_SDMA_UCODE_SIZE 1050
+#define CIK_SDMA_UCODE_VERSION 64
+
+/*(DEBLOBBED)*/
+
+extern int r600_ih_ring_alloc(struct radeon_device *rdev);
+extern void r600_ih_ring_fini(struct radeon_device *rdev);
+extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
+extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
+extern bool evergreen_is_display_hung(struct radeon_device *rdev);
+extern void si_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
+extern void si_rlc_fini(struct radeon_device *rdev);
+extern int si_rlc_init(struct radeon_device *rdev);
+static void cik_rlc_stop(struct radeon_device *rdev);
+
+/*
+ * Indirect registers accessor
+ */
+u32 cik_pciep_rreg(struct radeon_device *rdev, u32 reg)
+{
+	u32 r;
+
+	WREG32(PCIE_INDEX, reg);
+	(void)RREG32(PCIE_INDEX);
+	r = RREG32(PCIE_DATA);
+	return r;
+}
+
+void cik_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+	WREG32(PCIE_INDEX, reg);
+	(void)RREG32(PCIE_INDEX);
+	WREG32(PCIE_DATA, v);
+	(void)RREG32(PCIE_DATA);
+}
+
+static const u32 bonaire_golden_spm_registers[] =
+{
+	0x30800, 0xe0ffffff, 0xe0000000
+};
+
+static const u32 bonaire_golden_common_registers[] =
+{
+	0xc770, 0xffffffff, 0x00000800,
+	0xc774, 0xffffffff, 0x00000800,
+	0xc798, 0xffffffff, 0x00007fbf,
+	0xc79c, 0xffffffff, 0x00007faf
+};
+
+static const u32 bonaire_golden_registers[] =
+{
+	0x3354, 0x00000333, 0x00000333,
+	0x3350, 0x000c0fc0, 0x00040200,
+	0x9a10, 0x00010000, 0x00058208,
+	0x3c000, 0xffff1fff, 0x00140000,
+	0x3c200, 0xfdfc0fff, 0x00000100,
+	0x3c234, 0x40000000, 0x40000200,
+	0x9830, 0xffffffff, 0x00000000,
+	0x9834, 0xf00fffff, 0x00000400,
+	0x9838, 0x0002021c, 0x00020200,
+	0xc78, 0x00000080, 0x00000000,
+	0x5bb0, 0x000000f0, 0x00000070,
+	0x5bc0, 0xf0311fff, 0x80300000,
+	0x98f8, 0x73773777, 0x12010001,
+	0x350c, 0x00810000, 0x408af000,
+	0x7030, 0x31000111, 0x00000011,
+	0x2f48, 0x73773777, 0x12010001,
+	0x220c, 0x00007fb6, 0x0021a1b1,
+	0x2210, 0x00007fb6, 0x002021b1,
+	0x2180, 0x00007fb6, 0x00002191,
+	0x2218, 0x00007fb6, 0x002121b1,
+	0x221c, 0x00007fb6, 0x002021b1,
+	0x21dc, 0x00007fb6, 0x00002191,
+	0x21e0, 0x00007fb6, 0x00002191,
+	0x3628, 0x0000003f, 0x0000000a,
+	0x362c, 0x0000003f, 0x0000000a,
+	0x2ae4, 0x00073ffe, 0x000022a2,
+	0x240c, 0x000007ff, 0x00000000,
+	0x8a14, 0xf000003f, 0x00000007,
+	0x8bf0, 0x00002001, 0x00000001,
+	0x8b24, 0xffffffff, 0x00ffffff,
+	0x30a04, 0x0000ff0f, 0x00000000,
+	0x28a4c, 0x07ffffff, 0x06000000,
+	0x4d8, 0x00000fff, 0x00000100,
+	0x3e78, 0x00000001, 0x00000002,
+	0x9100, 0x03000000, 0x0362c688,
+	0x8c00, 0x000000ff, 0x00000001,
+	0xe40, 0x00001fff, 0x00001fff,
+	0x9060, 0x0000007f, 0x00000020,
+	0x9508, 0x00010000, 0x00010000,
+	0xac14, 0x000003ff, 0x000000f3,
+	0xac0c, 0xffffffff, 0x00001032
+};
+
+static const u32 bonaire_mgcg_cgcg_init[] =
+{
+	0xc420, 0xffffffff, 0xfffffffc,
+	0x30800, 0xffffffff, 0xe0000000,
+	0x3c2a0, 0xffffffff, 0x00000100,
+	0x3c208, 0xffffffff, 0x00000100,
+	0x3c2c0, 0xffffffff, 0xc0000100,
+	0x3c2c8, 0xffffffff, 0xc0000100,
+	0x3c2c4, 0xffffffff, 0xc0000100,
+	0x55e4, 0xffffffff, 0x00600100,
+	0x3c280, 0xffffffff, 0x00000100,
+	0x3c214, 0xffffffff, 0x06000100,
+	0x3c220, 0xffffffff, 0x00000100,
+	0x3c218, 0xffffffff, 0x06000100,
+	0x3c204, 0xffffffff, 0x00000100,
+	0x3c2e0, 0xffffffff, 0x00000100,
+	0x3c224, 0xffffffff, 0x00000100,
+	0x3c200, 0xffffffff, 0x00000100,
+	0x3c230, 0xffffffff, 0x00000100,
+	0x3c234, 0xffffffff, 0x00000100,
+	0x3c250, 0xffffffff, 0x00000100,
+	0x3c254, 0xffffffff, 0x00000100,
+	0x3c258, 0xffffffff, 0x00000100,
+	0x3c25c, 0xffffffff, 0x00000100,
+	0x3c260, 0xffffffff, 0x00000100,
+	0x3c27c, 0xffffffff, 0x00000100,
+	0x3c278, 0xffffffff, 0x00000100,
+	0x3c210, 0xffffffff, 0x06000100,
+	0x3c290, 0xffffffff, 0x00000100,
+	0x3c274, 0xffffffff, 0x00000100,
+	0x3c2b4, 0xffffffff, 0x00000100,
+	0x3c2b0, 0xffffffff, 0x00000100,
+	0x3c270, 0xffffffff, 0x00000100,
+	0x30800, 0xffffffff, 0xe0000000,
+	0x3c020, 0xffffffff, 0x00010000,
+	0x3c024, 0xffffffff, 0x00030002,
+	0x3c028, 0xffffffff, 0x00040007,
+	0x3c02c, 0xffffffff, 0x00060005,
+	0x3c030, 0xffffffff, 0x00090008,
+	0x3c034, 0xffffffff, 0x00010000,
+	0x3c038, 0xffffffff, 0x00030002,
+	0x3c03c, 0xffffffff, 0x00040007,
+	0x3c040, 0xffffffff, 0x00060005,
+	0x3c044, 0xffffffff, 0x00090008,
+	0x3c048, 0xffffffff, 0x00010000,
+	0x3c04c, 0xffffffff, 0x00030002,
+	0x3c050, 0xffffffff, 0x00040007,
+	0x3c054, 0xffffffff, 0x00060005,
+	0x3c058, 0xffffffff, 0x00090008,
+	0x3c05c, 0xffffffff, 0x00010000,
+	0x3c060, 0xffffffff, 0x00030002,
+	0x3c064, 0xffffffff, 0x00040007,
+	0x3c068, 0xffffffff, 0x00060005,
+	0x3c06c, 0xffffffff, 0x00090008,
+	0x3c070, 0xffffffff, 0x00010000,
+	0x3c074, 0xffffffff, 0x00030002,
+	0x3c078, 0xffffffff, 0x00040007,
+	0x3c07c, 0xffffffff, 0x00060005,
+	0x3c080, 0xffffffff, 0x00090008,
+	0x3c084, 0xffffffff, 0x00010000,
+	0x3c088, 0xffffffff, 0x00030002,
+	0x3c08c, 0xffffffff, 0x00040007,
+	0x3c090, 0xffffffff, 0x00060005,
+	0x3c094, 0xffffffff, 0x00090008,
+	0x3c098, 0xffffffff, 0x00010000,
+	0x3c09c, 0xffffffff, 0x00030002,
+	0x3c0a0, 0xffffffff, 0x00040007,
+	0x3c0a4, 0xffffffff, 0x00060005,
+	0x3c0a8, 0xffffffff, 0x00090008,
+	0x3c000, 0xffffffff, 0x96e00200,
+	0x8708, 0xffffffff, 0x00900100,
+	0xc424, 0xffffffff, 0x0020003f,
+	0x38, 0xffffffff, 0x0140001c,
+	0x3c, 0x000f0000, 0x000f0000,
+	0x220, 0xffffffff, 0xC060000C,
+	0x224, 0xc0000fff, 0x00000100,
+	0xf90, 0xffffffff, 0x00000100,
+	0xf98, 0x00000101, 0x00000000,
+	0x20a8, 0xffffffff, 0x00000104,
+	0x55e4, 0xff000fff, 0x00000100,
+	0x30cc, 0xc0000fff, 0x00000104,
+	0xc1e4, 0x00000001, 0x00000001,
+	0xd00c, 0xff000ff0, 0x00000100,
+	0xd80c, 0xff000ff0, 0x00000100
+};
+
+static const u32 spectre_golden_spm_registers[] =
+{
+	0x30800, 0xe0ffffff, 0xe0000000
+};
+
+static const u32 spectre_golden_common_registers[] =
+{
+	0xc770, 0xffffffff, 0x00000800,
+	0xc774, 0xffffffff, 0x00000800,
+	0xc798, 0xffffffff, 0x00007fbf,
+	0xc79c, 0xffffffff, 0x00007faf
+};
+
+static const u32 spectre_golden_registers[] =
+{
+	0x3c000, 0xffff1fff, 0x96940200,
+	0x3c00c, 0xffff0001, 0xff000000,
+	0x3c200, 0xfffc0fff, 0x00000100,
+	0x6ed8, 0x00010101, 0x00010000,
+	0x9834, 0xf00fffff, 0x00000400,
+	0x9838, 0xfffffffc, 0x00020200,
+	0x5bb0, 0x000000f0, 0x00000070,
+	0x5bc0, 0xf0311fff, 0x80300000,
+	0x98f8, 0x73773777, 0x12010001,
+	0x9b7c, 0x00ff0000, 0x00fc0000,
+	0x2f48, 0x73773777, 0x12010001,
+	0x8a14, 0xf000003f, 0x00000007,
+	0x8b24, 0xffffffff, 0x00ffffff,
+	0x28350, 0x3f3f3fff, 0x00000082,
+	0x28355, 0x0000003f, 0x00000000,
+	0x3e78, 0x00000001, 0x00000002,
+	0x913c, 0xffff03df, 0x00000004,
+	0xc768, 0x00000008, 0x00000008,
+	0x8c00, 0x000008ff, 0x00000800,
+	0x9508, 0x00010000, 0x00010000,
+	0xac0c, 0xffffffff, 0x54763210,
+	0x214f8, 0x01ff01ff, 0x00000002,
+	0x21498, 0x007ff800, 0x00200000,
+	0x2015c, 0xffffffff, 0x00000f40,
+	0x30934, 0xffffffff, 0x00000001
+};
+
+static const u32 spectre_mgcg_cgcg_init[] =
+{
+	0xc420, 0xffffffff, 0xfffffffc,
+	0x30800, 0xffffffff, 0xe0000000,
+	0x3c2a0, 0xffffffff, 0x00000100,
+	0x3c208, 0xffffffff, 0x00000100,
+	0x3c2c0, 0xffffffff, 0x00000100,
+	0x3c2c8, 0xffffffff, 0x00000100,
+	0x3c2c4, 0xffffffff, 0x00000100,
+	0x55e4, 0xffffffff, 0x00600100,
+	0x3c280, 0xffffffff, 0x00000100,
+	0x3c214, 0xffffffff, 0x06000100,
+	0x3c220, 0xffffffff, 0x00000100,
+	0x3c218, 0xffffffff, 0x06000100,
+	0x3c204, 0xffffffff, 0x00000100,
+	0x3c2e0, 0xffffffff, 0x00000100,
+	0x3c224, 0xffffffff, 0x00000100,
+	0x3c200, 0xffffffff, 0x00000100,
+	0x3c230, 0xffffffff, 0x00000100,
+	0x3c234, 0xffffffff, 0x00000100,
+	0x3c250, 0xffffffff, 0x00000100,
+	0x3c254, 0xffffffff, 0x00000100,
+	0x3c258, 0xffffffff, 0x00000100,
+	0x3c25c, 0xffffffff, 0x00000100,
+	0x3c260, 0xffffffff, 0x00000100,
+	0x3c27c, 0xffffffff, 0x00000100,
+	0x3c278, 0xffffffff, 0x00000100,
+	0x3c210, 0xffffffff, 0x06000100,
+	0x3c290, 0xffffffff, 0x00000100,
+	0x3c274, 0xffffffff, 0x00000100,
+	0x3c2b4, 0xffffffff, 0x00000100,
+	0x3c2b0, 0xffffffff, 0x00000100,
+	0x3c270, 0xffffffff, 0x00000100,
+	0x30800, 0xffffffff, 0xe0000000,
+	0x3c020, 0xffffffff, 0x00010000,
+	0x3c024, 0xffffffff, 0x00030002,
+	0x3c028, 0xffffffff, 0x00040007,
+	0x3c02c, 0xffffffff, 0x00060005,
+	0x3c030, 0xffffffff, 0x00090008,
+	0x3c034, 0xffffffff, 0x00010000,
+	0x3c038, 0xffffffff, 0x00030002,
+	0x3c03c, 0xffffffff, 0x00040007,
+	0x3c040, 0xffffffff, 0x00060005,
+	0x3c044, 0xffffffff, 0x00090008,
+	0x3c048, 0xffffffff, 0x00010000,
+	0x3c04c, 0xffffffff, 0x00030002,
+	0x3c050, 0xffffffff, 0x00040007,
+	0x3c054, 0xffffffff, 0x00060005,
+	0x3c058, 0xffffffff, 0x00090008,
+	0x3c05c, 0xffffffff, 0x00010000,
+	0x3c060, 0xffffffff, 0x00030002,
+	0x3c064, 0xffffffff, 0x00040007,
+	0x3c068, 0xffffffff, 0x00060005,
+	0x3c06c, 0xffffffff, 0x00090008,
+	0x3c070, 0xffffffff, 0x00010000,
+	0x3c074, 0xffffffff, 0x00030002,
+	0x3c078, 0xffffffff, 0x00040007,
+	0x3c07c, 0xffffffff, 0x00060005,
+	0x3c080, 0xffffffff, 0x00090008,
+	0x3c084, 0xffffffff, 0x00010000,
+	0x3c088, 0xffffffff, 0x00030002,
+	0x3c08c, 0xffffffff, 0x00040007,
+	0x3c090, 0xffffffff, 0x00060005,
+	0x3c094, 0xffffffff, 0x00090008,
+	0x3c098, 0xffffffff, 0x00010000,
+	0x3c09c, 0xffffffff, 0x00030002,
+	0x3c0a0, 0xffffffff, 0x00040007,
+	0x3c0a4, 0xffffffff, 0x00060005,
+	0x3c0a8, 0xffffffff, 0x00090008,
+	0x3c0ac, 0xffffffff, 0x00010000,
+	0x3c0b0, 0xffffffff, 0x00030002,
+	0x3c0b4, 0xffffffff, 0x00040007,
+	0x3c0b8, 0xffffffff, 0x00060005,
+	0x3c0bc, 0xffffffff, 0x00090008,
+	0x3c000, 0xffffffff, 0x96e00200,
+	0x8708, 0xffffffff, 0x00900100,
+	0xc424, 0xffffffff, 0x0020003f,
+	0x38, 0xffffffff, 0x0140001c,
+	0x3c, 0x000f0000, 0x000f0000,
+	0x220, 0xffffffff, 0xC060000C,
+	0x224, 0xc0000fff, 0x00000100,
+	0xf90, 0xffffffff, 0x00000100,
+	0xf98, 0x00000101, 0x00000000,
+	0x20a8, 0xffffffff, 0x00000104,
+	0x55e4, 0xff000fff, 0x00000100,
+	0x30cc, 0xc0000fff, 0x00000104,
+	0xc1e4, 0x00000001, 0x00000001,
+	0xd00c, 0xff000ff0, 0x00000100,
+	0xd80c, 0xff000ff0, 0x00000100
+};
+
+static const u32 kalindi_golden_spm_registers[] =
+{
+	0x30800, 0xe0ffffff, 0xe0000000
+};
+
+static const u32 kalindi_golden_common_registers[] =
+{
+	0xc770, 0xffffffff, 0x00000800,
+	0xc774, 0xffffffff, 0x00000800,
+	0xc798, 0xffffffff, 0x00007fbf,
+	0xc79c, 0xffffffff, 0x00007faf
+};
+
+static const u32 kalindi_golden_registers[] =
+{
+	0x3c000, 0xffffdfff, 0x6e944040,
+	0x55e4, 0xff607fff, 0xfc000100,
+	0x3c220, 0xff000fff, 0x00000100,
+	0x3c224, 0xff000fff, 0x00000100,
+	0x3c200, 0xfffc0fff, 0x00000100,
+	0x6ed8, 0x00010101, 0x00010000,
+	0x9830, 0xffffffff, 0x00000000,
+	0x9834, 0xf00fffff, 0x00000400,
+	0x5bb0, 0x000000f0, 0x00000070,
+	0x5bc0, 0xf0311fff, 0x80300000,
+	0x98f8, 0x73773777, 0x12010001,
+	0x98fc, 0xffffffff, 0x00000010,
+	0x9b7c, 0x00ff0000, 0x00fc0000,
+	0x8030, 0x00001f0f, 0x0000100a,
+	0x2f48, 0x73773777, 0x12010001,
+	0x2408, 0x000fffff, 0x000c007f,
+	0x8a14, 0xf000003f, 0x00000007,
+	0x8b24, 0x3fff3fff, 0x00ffcfff,
+	0x30a04, 0x0000ff0f, 0x00000000,
+	0x28a4c, 0x07ffffff, 0x06000000,
+	0x4d8, 0x00000fff, 0x00000100,
+	0x3e78, 0x00000001, 0x00000002,
+	0xc768, 0x00000008, 0x00000008,
+	0x8c00, 0x000000ff, 0x00000003,
+	0x214f8, 0x01ff01ff, 0x00000002,
+	0x21498, 0x007ff800, 0x00200000,
+	0x2015c, 0xffffffff, 0x00000f40,
+	0x88c4, 0x001f3ae3, 0x00000082,
+	0x88d4, 0x0000001f, 0x00000010,
+	0x30934, 0xffffffff, 0x00000000
+};
+
+static const u32 kalindi_mgcg_cgcg_init[] =
+{
+	0xc420, 0xffffffff, 0xfffffffc,
+	0x30800, 0xffffffff, 0xe0000000,
+	0x3c2a0, 0xffffffff, 0x00000100,
+	0x3c208, 0xffffffff, 0x00000100,
+	0x3c2c0, 0xffffffff, 0x00000100,
+	0x3c2c8, 0xffffffff, 0x00000100,
+	0x3c2c4, 0xffffffff, 0x00000100,
+	0x55e4, 0xffffffff, 0x00600100,
+	0x3c280, 0xffffffff, 0x00000100,
+	0x3c214, 0xffffffff, 0x06000100,
+	0x3c220, 0xffffffff, 0x00000100,
+	0x3c218, 0xffffffff, 0x06000100,
+	0x3c204, 0xffffffff, 0x00000100,
+	0x3c2e0, 0xffffffff, 0x00000100,
+	0x3c224, 0xffffffff, 0x00000100,
+	0x3c200, 0xffffffff, 0x00000100,
+	0x3c230, 0xffffffff, 0x00000100,
+	0x3c234, 0xffffffff, 0x00000100,
+	0x3c250, 0xffffffff, 0x00000100,
+	0x3c254, 0xffffffff, 0x00000100,
+	0x3c258, 0xffffffff, 0x00000100,
+	0x3c25c, 0xffffffff, 0x00000100,
+	0x3c260, 0xffffffff, 0x00000100,
+	0x3c27c, 0xffffffff, 0x00000100,
+	0x3c278, 0xffffffff, 0x00000100,
+	0x3c210, 0xffffffff, 0x06000100,
+	0x3c290, 0xffffffff, 0x00000100,
+	0x3c274, 0xffffffff, 0x00000100,
+	0x3c2b4, 0xffffffff, 0x00000100,
+	0x3c2b0, 0xffffffff, 0x00000100,
+	0x3c270, 0xffffffff, 0x00000100,
+	0x30800, 0xffffffff, 0xe0000000,
+	0x3c020, 0xffffffff, 0x00010000,
+	0x3c024, 0xffffffff, 0x00030002,
+	0x3c028, 0xffffffff, 0x00040007,
+	0x3c02c, 0xffffffff, 0x00060005,
+	0x3c030, 0xffffffff, 0x00090008,
+	0x3c034, 0xffffffff, 0x00010000,
+	0x3c038, 0xffffffff, 0x00030002,
+	0x3c03c, 0xffffffff, 0x00040007,
+	0x3c040, 0xffffffff, 0x00060005,
+	0x3c044, 0xffffffff, 0x00090008,
+	0x3c000, 0xffffffff, 0x96e00200,
+	0x8708, 0xffffffff, 0x00900100,
+	0xc424, 0xffffffff, 0x0020003f,
+	0x38, 0xffffffff, 0x0140001c,
+	0x3c, 0x000f0000, 0x000f0000,
+	0x220, 0xffffffff, 0xC060000C,
+	0x224, 0xc0000fff, 0x00000100,
+	0x20a8, 0xffffffff, 0x00000104,
+	0x55e4, 0xff000fff, 0x00000100,
+	0x30cc, 0xc0000fff, 0x00000104,
+	0xc1e4, 0x00000001, 0x00000001,
+	0xd00c, 0xff000ff0, 0x00000100,
+	0xd80c, 0xff000ff0, 0x00000100
+};
+
+static void cik_init_golden_registers(struct radeon_device *rdev)
+{
+	switch (rdev->family) {
+	case CHIP_BONAIRE:
+		radeon_program_register_sequence(rdev,
+						 bonaire_mgcg_cgcg_init,
+						 (const u32)ARRAY_SIZE(bonaire_mgcg_cgcg_init));
+		radeon_program_register_sequence(rdev,
+						 bonaire_golden_registers,
+						 (const u32)ARRAY_SIZE(bonaire_golden_registers));
+		radeon_program_register_sequence(rdev,
+						 bonaire_golden_common_registers,
+						 (const u32)ARRAY_SIZE(bonaire_golden_common_registers));
+		radeon_program_register_sequence(rdev,
+						 bonaire_golden_spm_registers,
+						 (const u32)ARRAY_SIZE(bonaire_golden_spm_registers));
+		break;
+	case CHIP_KABINI:
+		radeon_program_register_sequence(rdev,
+						 kalindi_mgcg_cgcg_init,
+						 (const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init));
+		radeon_program_register_sequence(rdev,
+						 kalindi_golden_registers,
+						 (const u32)ARRAY_SIZE(kalindi_golden_registers));
+		radeon_program_register_sequence(rdev,
+						 kalindi_golden_common_registers,
+						 (const u32)ARRAY_SIZE(kalindi_golden_common_registers));
+		radeon_program_register_sequence(rdev,
+						 kalindi_golden_spm_registers,
+						 (const u32)ARRAY_SIZE(kalindi_golden_spm_registers));
+		break;
+	case CHIP_KAVERI:
+		radeon_program_register_sequence(rdev,
+						 spectre_mgcg_cgcg_init,
+						 (const u32)ARRAY_SIZE(spectre_mgcg_cgcg_init));
+		radeon_program_register_sequence(rdev,
+						 spectre_golden_registers,
+						 (const u32)ARRAY_SIZE(spectre_golden_registers));
+		radeon_program_register_sequence(rdev,
+						 spectre_golden_common_registers,
+						 (const u32)ARRAY_SIZE(spectre_golden_common_registers));
+		radeon_program_register_sequence(rdev,
+						 spectre_golden_spm_registers,
+						 (const u32)ARRAY_SIZE(spectre_golden_spm_registers));
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ * cik_get_xclk - get the xclk
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Returns the reference clock used by the gfx engine
+ * (CIK).
+ */
+u32 cik_get_xclk(struct radeon_device *rdev)
+{
+        u32 reference_clock = rdev->clock.spll.reference_freq;
+
+	if (rdev->flags & RADEON_IS_IGP) {
+		if (RREG32_SMC(GENERAL_PWRMGT) & GPU_COUNTER_CLK)
+			return reference_clock / 2;
+	} else {
+		if (RREG32_SMC(CG_CLKPIN_CNTL) & XTALIN_DIVIDE)
+			return reference_clock / 4;
+	}
+	return reference_clock;
+}
+
+/**
+ * cik_mm_rdoorbell - read a doorbell dword
+ *
+ * @rdev: radeon_device pointer
+ * @offset: byte offset into the aperture
+ *
+ * Returns the value in the doorbell aperture at the
+ * requested offset (CIK).
+ */
+u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 offset)
+{
+	if (offset < rdev->doorbell.size) {
+		return readl(((void __iomem *)rdev->doorbell.ptr) + offset);
+	} else {
+		DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", offset);
+		return 0;
+	}
+}
+
+/**
+ * cik_mm_wdoorbell - write a doorbell dword
+ *
+ * @rdev: radeon_device pointer
+ * @offset: byte offset into the aperture
+ * @v: value to write
+ *
+ * Writes @v to the doorbell aperture at the
+ * requested offset (CIK).
+ */
+void cik_mm_wdoorbell(struct radeon_device *rdev, u32 offset, u32 v)
+{
+	if (offset < rdev->doorbell.size) {
+		writel(v, ((void __iomem *)rdev->doorbell.ptr) + offset);
+	} else {
+		DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", offset);
+	}
+}
+
+#define BONAIRE_IO_MC_REGS_SIZE 36
+
+static const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] =
+{
+	{0x00000070, 0x04400000},
+	{0x00000071, 0x80c01803},
+	{0x00000072, 0x00004004},
+	{0x00000073, 0x00000100},
+	{0x00000074, 0x00ff0000},
+	{0x00000075, 0x34000000},
+	{0x00000076, 0x08000014},
+	{0x00000077, 0x00cc08ec},
+	{0x00000078, 0x00000400},
+	{0x00000079, 0x00000000},
+	{0x0000007a, 0x04090000},
+	{0x0000007c, 0x00000000},
+	{0x0000007e, 0x4408a8e8},
+	{0x0000007f, 0x00000304},
+	{0x00000080, 0x00000000},
+	{0x00000082, 0x00000001},
+	{0x00000083, 0x00000002},
+	{0x00000084, 0xf3e4f400},
+	{0x00000085, 0x052024e3},
+	{0x00000087, 0x00000000},
+	{0x00000088, 0x01000000},
+	{0x0000008a, 0x1c0a0000},
+	{0x0000008b, 0xff010000},
+	{0x0000008d, 0xffffefff},
+	{0x0000008e, 0xfff3efff},
+	{0x0000008f, 0xfff3efbf},
+	{0x00000092, 0xf7ffffff},
+	{0x00000093, 0xffffff7f},
+	{0x00000095, 0x00101101},
+	{0x00000096, 0x00000fff},
+	{0x00000097, 0x00116fff},
+	{0x00000098, 0x60010000},
+	{0x00000099, 0x10010000},
+	{0x0000009a, 0x00006000},
+	{0x0000009b, 0x00001000},
+	{0x0000009f, 0x00b48000}
+};
+
+/**
+ * cik_srbm_select - select specific register instances
+ *
+ * @rdev: radeon_device pointer
+ * @me: selected ME (micro engine)
+ * @pipe: pipe
+ * @queue: queue
+ * @vmid: VMID
+ *
+ * Switches the currently active registers instances.  Some
+ * registers are instanced per VMID, others are instanced per
+ * me/pipe/queue combination.
+ */
+static void cik_srbm_select(struct radeon_device *rdev,
+			    u32 me, u32 pipe, u32 queue, u32 vmid)
+{
+	u32 srbm_gfx_cntl = (PIPEID(pipe & 0x3) |
+			     MEID(me & 0x3) |
+			     VMID(vmid & 0xf) |
+			     QUEUEID(queue & 0x7));
+	WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl);
+}
+
+/* ucode loading */
+/**
+ * ci_mc_load_microcode - load MC ucode into the hw
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Load the GDDR MC ucode into the hw (CIK).
+ * Returns 0 on success, error on failure.
+ */
+static int ci_mc_load_microcode(struct radeon_device *rdev)
+{
+	const __be32 *fw_data;
+	u32 running, blackout = 0;
+	u32 *io_mc_regs;
+	int i, ucode_size, regs_size;
+
+	if (!rdev->mc_fw)
+		return -EINVAL;
+
+	switch (rdev->family) {
+	case CHIP_BONAIRE:
+	default:
+		io_mc_regs = (u32 *)&bonaire_io_mc_regs;
+		ucode_size = CIK_MC_UCODE_SIZE;
+		regs_size = BONAIRE_IO_MC_REGS_SIZE;
+		break;
+	}
+
+	running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
+
+	if (running == 0) {
+		if (running) {
+			blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
+			WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
+		}
+
+		/* reset the engine and set to writable */
+		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
+		WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
+
+		/* load mc io regs */
+		for (i = 0; i < regs_size; i++) {
+			WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
+			WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
+		}
+		/* load the MC ucode */
+		fw_data = (const __be32 *)rdev->mc_fw->data;
+		for (i = 0; i < ucode_size; i++)
+			WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+
+		/* put the engine back into the active state */
+		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
+		WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
+		WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
+
+		/* wait for training to complete */
+		for (i = 0; i < rdev->usec_timeout; i++) {
+			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0)
+				break;
+			udelay(1);
+		}
+		for (i = 0; i < rdev->usec_timeout; i++) {
+			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
+				break;
+			udelay(1);
+		}
+
+		if (running)
+			WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
+	}
+
+	return 0;
+}
+
+/**
+ * cik_init_microcode - load ucode images from disk
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Use the firmware interface to load the ucode images into
+ * the driver (not loaded into hw).
+ * Returns 0 on success, error on failure.
+ */
+static int cik_init_microcode(struct radeon_device *rdev)
+{
+	const char *chip_name;
+	size_t pfp_req_size, me_req_size, ce_req_size,
+		mec_req_size, rlc_req_size, mc_req_size,
+		sdma_req_size;
+	char fw_name[30];
+	int err;
+
+	DRM_DEBUG("\n");
+
+	switch (rdev->family) {
+	case CHIP_BONAIRE:
+		chip_name = "BONAIRE";
+		pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
+		me_req_size = CIK_ME_UCODE_SIZE * 4;
+		ce_req_size = CIK_CE_UCODE_SIZE * 4;
+		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
+		rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
+		mc_req_size = CIK_MC_UCODE_SIZE * 4;
+		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
+		break;
+	case CHIP_KAVERI:
+		chip_name = "KAVERI";
+		pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
+		me_req_size = CIK_ME_UCODE_SIZE * 4;
+		ce_req_size = CIK_CE_UCODE_SIZE * 4;
+		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
+		rlc_req_size = KV_RLC_UCODE_SIZE * 4;
+		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
+		break;
+	case CHIP_KABINI:
+		chip_name = "KABINI";
+		pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
+		me_req_size = CIK_ME_UCODE_SIZE * 4;
+		ce_req_size = CIK_CE_UCODE_SIZE * 4;
+		mec_req_size = CIK_MEC_UCODE_SIZE * 4;
+		rlc_req_size = KB_RLC_UCODE_SIZE * 4;
+		sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
+		break;
+	default: BUG();
+	}
+
+	DRM_INFO("Loading %s Microcode\n", chip_name);
+
+	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
+	err = reject_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
+	if (err)
+		goto out;
+	if (rdev->pfp_fw->size != pfp_req_size) {
+		printk(KERN_ERR
+		       "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->pfp_fw->size, fw_name);
+		err = -EINVAL;
+		goto out;
+	}
+
+	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
+	err = reject_firmware(&rdev->me_fw, fw_name, rdev->dev);
+	if (err)
+		goto out;
+	if (rdev->me_fw->size != me_req_size) {
+		printk(KERN_ERR
+		       "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->me_fw->size, fw_name);
+		err = -EINVAL;
+	}
+
+	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
+	err = reject_firmware(&rdev->ce_fw, fw_name, rdev->dev);
+	if (err)
+		goto out;
+	if (rdev->ce_fw->size != ce_req_size) {
+		printk(KERN_ERR
+		       "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->ce_fw->size, fw_name);
+		err = -EINVAL;
+	}
+
+	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
+	err = reject_firmware(&rdev->mec_fw, fw_name, rdev->dev);
+	if (err)
+		goto out;
+	if (rdev->mec_fw->size != mec_req_size) {
+		printk(KERN_ERR
+		       "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->mec_fw->size, fw_name);
+		err = -EINVAL;
+	}
+
+	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
+	err = reject_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
+	if (err)
+		goto out;
+	if (rdev->rlc_fw->size != rlc_req_size) {
+		printk(KERN_ERR
+		       "cik_rlc: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->rlc_fw->size, fw_name);
+		err = -EINVAL;
+	}
+
+	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
+	err = reject_firmware(&rdev->sdma_fw, fw_name, rdev->dev);
+	if (err)
+		goto out;
+	if (rdev->sdma_fw->size != sdma_req_size) {
+		printk(KERN_ERR
+		       "cik_sdma: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->sdma_fw->size, fw_name);
+		err = -EINVAL;
+	}
+
+	/* No MC ucode on APUs */
+	if (!(rdev->flags & RADEON_IS_IGP)) {
+		snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
+		err = reject_firmware(&rdev->mc_fw, fw_name, rdev->dev);
+		if (err)
+			goto out;
+		if (rdev->mc_fw->size != mc_req_size) {
+			printk(KERN_ERR
+			       "cik_mc: Bogus length %zu in firmware \"%s\"\n",
+			       rdev->mc_fw->size, fw_name);
+			err = -EINVAL;
+		}
+	}
+
+out:
+	if (err) {
+		if (err != -EINVAL)
+			printk(KERN_ERR
+			       "cik_cp: Failed to load firmware \"%s\"\n",
+			       fw_name);
+		release_firmware(rdev->pfp_fw);
+		rdev->pfp_fw = NULL;
+		release_firmware(rdev->me_fw);
+		rdev->me_fw = NULL;
+		release_firmware(rdev->ce_fw);
+		rdev->ce_fw = NULL;
+		release_firmware(rdev->rlc_fw);
+		rdev->rlc_fw = NULL;
+		release_firmware(rdev->mc_fw);
+		rdev->mc_fw = NULL;
+	}
+	return err;
+}
+
+/*
+ * Core functions
+ */
+/**
+ * cik_tiling_mode_table_init - init the hw tiling table
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Starting with SI, the tiling setup is done globally in a
+ * set of 32 tiling modes.  Rather than selecting each set of
+ * parameters per surface as on older asics, we just select
+ * which index in the tiling table we want to use, and the
+ * surface uses those parameters (CIK).
+ */
+static void cik_tiling_mode_table_init(struct radeon_device *rdev)
+{
+	const u32 num_tile_mode_states = 32;
+	const u32 num_secondary_tile_mode_states = 16;
+	u32 reg_offset, gb_tile_moden, split_equal_to_row_size;
+	u32 num_pipe_configs;
+	u32 num_rbs = rdev->config.cik.max_backends_per_se *
+		rdev->config.cik.max_shader_engines;
+
+	switch (rdev->config.cik.mem_row_size_in_kb) {
+	case 1:
+		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB;
+		break;
+	case 2:
+	default:
+		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB;
+		break;
+	case 4:
+		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB;
+		break;
+	}
+
+	num_pipe_configs = rdev->config.cik.max_tile_pipes;
+	if (num_pipe_configs > 8)
+		num_pipe_configs = 8; /* ??? */
+
+	if (num_pipe_configs == 8) {
+		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
+			switch (reg_offset) {
+			case 0:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+				break;
+			case 1:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+				break;
+			case 2:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+				break;
+			case 3:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+				break;
+			case 4:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 5:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+				break;
+			case 6:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+				break;
+			case 7:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 8:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16));
+				break;
+			case 9:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+				break;
+			case 10:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 11:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 12:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 13:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+				break;
+			case 14:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 16:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 17:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 27:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+				break;
+			case 28:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 29:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 30:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			default:
+				gb_tile_moden = 0;
+				break;
+			}
+			rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
+			WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+		}
+		for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) {
+			switch (reg_offset) {
+			case 0:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 1:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 2:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 3:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 4:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			case 5:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 6:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			case 8:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 9:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 10:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 11:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 12:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			case 13:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 14:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_2_BANK));
+				break;
+			default:
+				gb_tile_moden = 0;
+				break;
+			}
+			WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+		}
+	} else if (num_pipe_configs == 4) {
+		if (num_rbs == 4) {
+			for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
+				switch (reg_offset) {
+				case 0:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+					break;
+				case 1:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+					break;
+				case 2:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+					break;
+				case 3:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+					break;
+				case 4:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 TILE_SPLIT(split_equal_to_row_size));
+					break;
+				case 5:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+					break;
+				case 6:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+					break;
+				case 7:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 TILE_SPLIT(split_equal_to_row_size));
+					break;
+				case 8:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16));
+					break;
+				case 9:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+					break;
+				case 10:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 11:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 12:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 13:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+					break;
+				case 14:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 16:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 17:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 27:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+					break;
+				case 28:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 29:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 30:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				default:
+					gb_tile_moden = 0;
+					break;
+				}
+				rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
+				WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+			}
+		} else if (num_rbs < 4) {
+			for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
+				switch (reg_offset) {
+				case 0:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+					break;
+				case 1:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+					break;
+				case 2:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+					break;
+				case 3:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+					break;
+				case 4:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 TILE_SPLIT(split_equal_to_row_size));
+					break;
+				case 5:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+					break;
+				case 6:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+					break;
+				case 7:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 TILE_SPLIT(split_equal_to_row_size));
+					break;
+				case 8:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+						 PIPE_CONFIG(ADDR_SURF_P4_8x16));
+					break;
+				case 9:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+					break;
+				case 10:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 11:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 12:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 13:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+					break;
+				case 14:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 16:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 17:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 27:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+					break;
+				case 28:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 29:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				case 30:
+					gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+							 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+							 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+							 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+					break;
+				default:
+					gb_tile_moden = 0;
+					break;
+				}
+				rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
+				WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+			}
+		}
+		for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) {
+			switch (reg_offset) {
+			case 0:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 1:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 2:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 3:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 4:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 5:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			case 6:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			case 8:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 9:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 10:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 11:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 12:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 13:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			case 14:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+						 NUM_BANKS(ADDR_SURF_4_BANK));
+				break;
+			default:
+				gb_tile_moden = 0;
+				break;
+			}
+			WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+		}
+	} else if (num_pipe_configs == 2) {
+		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
+			switch (reg_offset) {
+			case 0:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+				break;
+			case 1:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+				break;
+			case 2:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+				break;
+			case 3:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+				break;
+			case 4:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 5:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+				break;
+			case 6:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+				break;
+			case 7:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 TILE_SPLIT(split_equal_to_row_size));
+				break;
+			case 8:
+				gb_tile_moden = ARRAY_MODE(ARRAY_LINEAR_ALIGNED);
+				break;
+			case 9:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+				break;
+			case 10:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 11:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 12:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 13:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+				break;
+			case 14:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 16:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 17:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 27:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+				break;
+			case 28:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 29:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			case 30:
+				gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+						 MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+						 PIPE_CONFIG(ADDR_SURF_P2) |
+						 SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+				break;
+			default:
+				gb_tile_moden = 0;
+				break;
+			}
+			rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
+			WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+		}
+		for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) {
+			switch (reg_offset) {
+			case 0:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 1:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 2:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 3:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 4:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 5:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 6:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			case 8:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 9:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 10:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 11:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 12:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 13:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+						 NUM_BANKS(ADDR_SURF_16_BANK));
+				break;
+			case 14:
+				gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+						 NUM_BANKS(ADDR_SURF_8_BANK));
+				break;
+			default:
+				gb_tile_moden = 0;
+				break;
+			}
+			WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+		}
+	} else
+		DRM_ERROR("unknown num pipe config: 0x%x\n", num_pipe_configs);
+}
+
+/**
+ * cik_select_se_sh - select which SE, SH to address
+ *
+ * @rdev: radeon_device pointer
+ * @se_num: shader engine to address
+ * @sh_num: sh block to address
+ *
+ * Select which SE, SH combinations to address. Certain
+ * registers are instanced per SE or SH.  0xffffffff means
+ * broadcast to all SEs or SHs (CIK).
+ */
+static void cik_select_se_sh(struct radeon_device *rdev,
+			     u32 se_num, u32 sh_num)
+{
+	u32 data = INSTANCE_BROADCAST_WRITES;
+
+	if ((se_num == 0xffffffff) && (sh_num == 0xffffffff))
+		data |= SH_BROADCAST_WRITES | SE_BROADCAST_WRITES;
+	else if (se_num == 0xffffffff)
+		data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num);
+	else if (sh_num == 0xffffffff)
+		data |= SH_BROADCAST_WRITES | SE_INDEX(se_num);
+	else
+		data |= SH_INDEX(sh_num) | SE_INDEX(se_num);
+	WREG32(GRBM_GFX_INDEX, data);
+}
+
+/**
+ * cik_create_bitmask - create a bitmask
+ *
+ * @bit_width: length of the mask
+ *
+ * create a variable length bit mask (CIK).
+ * Returns the bitmask.
+ */
+static u32 cik_create_bitmask(u32 bit_width)
+{
+	u32 i, mask = 0;
+
+	for (i = 0; i < bit_width; i++) {
+		mask <<= 1;
+		mask |= 1;
+	}
+	return mask;
+}
+
+/**
+ * cik_select_se_sh - select which SE, SH to address
+ *
+ * @rdev: radeon_device pointer
+ * @max_rb_num: max RBs (render backends) for the asic
+ * @se_num: number of SEs (shader engines) for the asic
+ * @sh_per_se: number of SH blocks per SE for the asic
+ *
+ * Calculates the bitmask of disabled RBs (CIK).
+ * Returns the disabled RB bitmask.
+ */
+static u32 cik_get_rb_disabled(struct radeon_device *rdev,
+			      u32 max_rb_num, u32 se_num,
+			      u32 sh_per_se)
+{
+	u32 data, mask;
+
+	data = RREG32(CC_RB_BACKEND_DISABLE);
+	if (data & 1)
+		data &= BACKEND_DISABLE_MASK;
+	else
+		data = 0;
+	data |= RREG32(GC_USER_RB_BACKEND_DISABLE);
+
+	data >>= BACKEND_DISABLE_SHIFT;
+
+	mask = cik_create_bitmask(max_rb_num / se_num / sh_per_se);
+
+	return data & mask;
+}
+
+/**
+ * cik_setup_rb - setup the RBs on the asic
+ *
+ * @rdev: radeon_device pointer
+ * @se_num: number of SEs (shader engines) for the asic
+ * @sh_per_se: number of SH blocks per SE for the asic
+ * @max_rb_num: max RBs (render backends) for the asic
+ *
+ * Configures per-SE/SH RB registers (CIK).
+ */
+static void cik_setup_rb(struct radeon_device *rdev,
+			 u32 se_num, u32 sh_per_se,
+			 u32 max_rb_num)
+{
+	int i, j;
+	u32 data, mask;
+	u32 disabled_rbs = 0;
+	u32 enabled_rbs = 0;
+
+	for (i = 0; i < se_num; i++) {
+		for (j = 0; j < sh_per_se; j++) {
+			cik_select_se_sh(rdev, i, j);
+			data = cik_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se);
+			disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH);
+		}
+	}
+	cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
+
+	mask = 1;
+	for (i = 0; i < max_rb_num; i++) {
+		if (!(disabled_rbs & mask))
+			enabled_rbs |= mask;
+		mask <<= 1;
+	}
+
+	for (i = 0; i < se_num; i++) {
+		cik_select_se_sh(rdev, i, 0xffffffff);
+		data = 0;
+		for (j = 0; j < sh_per_se; j++) {
+			switch (enabled_rbs & 3) {
+			case 1:
+				data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2);
+				break;
+			case 2:
+				data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2);
+				break;
+			case 3:
+			default:
+				data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2);
+				break;
+			}
+			enabled_rbs >>= 2;
+		}
+		WREG32(PA_SC_RASTER_CONFIG, data);
+	}
+	cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
+}
+
+/**
+ * cik_gpu_init - setup the 3D engine
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Configures the 3D engine and tiling configuration
+ * registers so that the 3D engine is usable.
+ */
+static void cik_gpu_init(struct radeon_device *rdev)
+{
+	u32 gb_addr_config = RREG32(GB_ADDR_CONFIG);
+	u32 mc_shared_chmap, mc_arb_ramcfg;
+	u32 hdp_host_path_cntl;
+	u32 tmp;
+	int i, j;
+
+	switch (rdev->family) {
+	case CHIP_BONAIRE:
+		rdev->config.cik.max_shader_engines = 2;
+		rdev->config.cik.max_tile_pipes = 4;
+		rdev->config.cik.max_cu_per_sh = 7;
+		rdev->config.cik.max_sh_per_se = 1;
+		rdev->config.cik.max_backends_per_se = 2;
+		rdev->config.cik.max_texture_channel_caches = 4;
+		rdev->config.cik.max_gprs = 256;
+		rdev->config.cik.max_gs_threads = 32;
+		rdev->config.cik.max_hw_contexts = 8;
+
+		rdev->config.cik.sc_prim_fifo_size_frontend = 0x20;
+		rdev->config.cik.sc_prim_fifo_size_backend = 0x100;
+		rdev->config.cik.sc_hiz_tile_fifo_size = 0x30;
+		rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130;
+		gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN;
+		break;
+	case CHIP_KAVERI:
+		/* TODO */
+		break;
+	case CHIP_KABINI:
+	default:
+		rdev->config.cik.max_shader_engines = 1;
+		rdev->config.cik.max_tile_pipes = 2;
+		rdev->config.cik.max_cu_per_sh = 2;
+		rdev->config.cik.max_sh_per_se = 1;
+		rdev->config.cik.max_backends_per_se = 1;
+		rdev->config.cik.max_texture_channel_caches = 2;
+		rdev->config.cik.max_gprs = 256;
+		rdev->config.cik.max_gs_threads = 16;
+		rdev->config.cik.max_hw_contexts = 8;
+
+		rdev->config.cik.sc_prim_fifo_size_frontend = 0x20;
+		rdev->config.cik.sc_prim_fifo_size_backend = 0x100;
+		rdev->config.cik.sc_hiz_tile_fifo_size = 0x30;
+		rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130;
+		gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN;
+		break;
+	}
+
+	/* Initialize HDP */
+	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
+		WREG32((0x2c14 + j), 0x00000000);
+		WREG32((0x2c18 + j), 0x00000000);
+		WREG32((0x2c1c + j), 0x00000000);
+		WREG32((0x2c20 + j), 0x00000000);
+		WREG32((0x2c24 + j), 0x00000000);
+	}
+
+	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
+
+	WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
+
+	mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
+	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
+
+	rdev->config.cik.num_tile_pipes = rdev->config.cik.max_tile_pipes;
+	rdev->config.cik.mem_max_burst_length_bytes = 256;
+	tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
+	rdev->config.cik.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
+	if (rdev->config.cik.mem_row_size_in_kb > 4)
+		rdev->config.cik.mem_row_size_in_kb = 4;
+	/* XXX use MC settings? */
+	rdev->config.cik.shader_engine_tile_size = 32;
+	rdev->config.cik.num_gpus = 1;
+	rdev->config.cik.multi_gpu_tile_size = 64;
+
+	/* fix up row size */
+	gb_addr_config &= ~ROW_SIZE_MASK;
+	switch (rdev->config.cik.mem_row_size_in_kb) {
+	case 1:
+	default:
+		gb_addr_config |= ROW_SIZE(0);
+		break;
+	case 2:
+		gb_addr_config |= ROW_SIZE(1);
+		break;
+	case 4:
+		gb_addr_config |= ROW_SIZE(2);
+		break;
+	}
+
+	/* setup tiling info dword.  gb_addr_config is not adequate since it does
+	 * not have bank info, so create a custom tiling dword.
+	 * bits 3:0   num_pipes
+	 * bits 7:4   num_banks
+	 * bits 11:8  group_size
+	 * bits 15:12 row_size
+	 */
+	rdev->config.cik.tile_config = 0;
+	switch (rdev->config.cik.num_tile_pipes) {
+	case 1:
+		rdev->config.cik.tile_config |= (0 << 0);
+		break;
+	case 2:
+		rdev->config.cik.tile_config |= (1 << 0);
+		break;
+	case 4:
+		rdev->config.cik.tile_config |= (2 << 0);
+		break;
+	case 8:
+	default:
+		/* XXX what about 12? */
+		rdev->config.cik.tile_config |= (3 << 0);
+		break;
+	}
+	if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT)
+		rdev->config.cik.tile_config |= 1 << 4;
+	else
+		rdev->config.cik.tile_config |= 0 << 4;
+	rdev->config.cik.tile_config |=
+		((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
+	rdev->config.cik.tile_config |=
+		((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
+
+	WREG32(GB_ADDR_CONFIG, gb_addr_config);
+	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
+	WREG32(DMIF_ADDR_CALC, gb_addr_config);
+	WREG32(SDMA0_TILING_CONFIG + SDMA0_REGISTER_OFFSET, gb_addr_config & 0x70);
+	WREG32(SDMA0_TILING_CONFIG + SDMA1_REGISTER_OFFSET, gb_addr_config & 0x70);
+	WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
+	WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
+	WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
+
+	cik_tiling_mode_table_init(rdev);
+
+	cik_setup_rb(rdev, rdev->config.cik.max_shader_engines,
+		     rdev->config.cik.max_sh_per_se,
+		     rdev->config.cik.max_backends_per_se);
+
+	/* set HW defaults for 3D engine */
+	WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
+
+	WREG32(SX_DEBUG_1, 0x20);
+
+	WREG32(TA_CNTL_AUX, 0x00010000);
+
+	tmp = RREG32(SPI_CONFIG_CNTL);
+	tmp |= 0x03000000;
+	WREG32(SPI_CONFIG_CNTL, tmp);
+
+	WREG32(SQ_CONFIG, 1);
+
+	WREG32(DB_DEBUG, 0);
+
+	tmp = RREG32(DB_DEBUG2) & ~0xf00fffff;
+	tmp |= 0x00000400;
+	WREG32(DB_DEBUG2, tmp);
+
+	tmp = RREG32(DB_DEBUG3) & ~0x0002021c;
+	tmp |= 0x00020200;
+	WREG32(DB_DEBUG3, tmp);
+
+	tmp = RREG32(CB_HW_CONTROL) & ~0x00010000;
+	tmp |= 0x00018208;
+	WREG32(CB_HW_CONTROL, tmp);
+
+	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
+
+	WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.cik.sc_prim_fifo_size_frontend) |
+				 SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.cik.sc_prim_fifo_size_backend) |
+				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.cik.sc_hiz_tile_fifo_size) |
+				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cik.sc_earlyz_tile_fifo_size)));
+
+	WREG32(VGT_NUM_INSTANCES, 1);
+
+	WREG32(CP_PERFMON_CNTL, 0);
+
+	WREG32(SQ_CONFIG, 0);
+
+	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
+					  FORCE_EOV_MAX_REZ_CNT(255)));
+
+	WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
+	       AUTO_INVLD_EN(ES_AND_GS_AUTO));
+
+	WREG32(VGT_GS_VERTEX_REUSE, 16);
+	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
+
+	tmp = RREG32(HDP_MISC_CNTL);
+	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
+	WREG32(HDP_MISC_CNTL, tmp);
+
+	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
+	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
+
+	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
+	WREG32(PA_SC_ENHANCE, ENABLE_PA_SC_OUT_OF_ORDER);
+
+	udelay(50);
+}
+
+/*
+ * GPU scratch registers helpers function.
+ */
+/**
+ * cik_scratch_init - setup driver info for CP scratch regs
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Set up the number and offset of the CP scratch registers.
+ * NOTE: use of CP scratch registers is a legacy inferface and
+ * is not used by default on newer asics (r6xx+).  On newer asics,
+ * memory buffers are used for fences rather than scratch regs.
+ */
+static void cik_scratch_init(struct radeon_device *rdev)
+{
+	int i;
+
+	rdev->scratch.num_reg = 7;
+	rdev->scratch.reg_base = SCRATCH_REG0;
+	for (i = 0; i < rdev->scratch.num_reg; i++) {
+		rdev->scratch.free[i] = true;
+		rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4);
+	}
+}
+
+/**
+ * cik_ring_test - basic gfx ring test
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Allocate a scratch register and write to it using the gfx ring (CIK).
+ * Provides a basic gfx ring test to verify that the ring is working.
+ * Used by cik_cp_gfx_resume();
+ * Returns 0 on success, error on failure.
+ */
+int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+	uint32_t scratch;
+	uint32_t tmp = 0;
+	unsigned i;
+	int r;
+
+	r = radeon_scratch_get(rdev, &scratch);
+	if (r) {
+		DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
+		return r;
+	}
+	WREG32(scratch, 0xCAFEDEAD);
+	r = radeon_ring_lock(rdev, ring, 3);
+	if (r) {
+		DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ring->idx, r);
+		radeon_scratch_free(rdev, scratch);
+		return r;
+	}
+	radeon_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1));
+	radeon_ring_write(ring, ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2));
+	radeon_ring_write(ring, 0xDEADBEEF);
+	radeon_ring_unlock_commit(rdev, ring);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(scratch);
+		if (tmp == 0xDEADBEEF)
+			break;
+		DRM_UDELAY(1);
+	}
+	if (i < rdev->usec_timeout) {
+		DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
+	} else {
+		DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)\n",
+			  ring->idx, scratch, tmp);
+		r = -EINVAL;
+	}
+	radeon_scratch_free(rdev, scratch);
+	return r;
+}
+
+/**
+ * cik_fence_gfx_ring_emit - emit a fence on the gfx ring
+ *
+ * @rdev: radeon_device pointer
+ * @fence: radeon fence object
+ *
+ * Emits a fence sequnce number on the gfx ring and flushes
+ * GPU caches.
+ */
+void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
+			     struct radeon_fence *fence)
+{
+	struct radeon_ring *ring = &rdev->ring[fence->ring];
+	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
+
+	/* EVENT_WRITE_EOP - flush caches, send int */
+	radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
+	radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
+				 EOP_TC_ACTION_EN |
+				 EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
+				 EVENT_INDEX(5)));
+	radeon_ring_write(ring, addr & 0xfffffffc);
+	radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | DATA_SEL(1) | INT_SEL(2));
+	radeon_ring_write(ring, fence->seq);
+	radeon_ring_write(ring, 0);
+	/* HDP flush */
+	/* We should be using the new WAIT_REG_MEM special op packet here
+	 * but it causes the CP to hang
+	 */
+	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+				 WRITE_DATA_DST_SEL(0)));
+	radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
+	radeon_ring_write(ring, 0);
+	radeon_ring_write(ring, 0);
+}
+
+/**
+ * cik_fence_compute_ring_emit - emit a fence on the compute ring
+ *
+ * @rdev: radeon_device pointer
+ * @fence: radeon fence object
+ *
+ * Emits a fence sequnce number on the compute ring and flushes
+ * GPU caches.
+ */
+void cik_fence_compute_ring_emit(struct radeon_device *rdev,
+				 struct radeon_fence *fence)
+{
+	struct radeon_ring *ring = &rdev->ring[fence->ring];
+	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
+
+	/* RELEASE_MEM - flush caches, send int */
+	radeon_ring_write(ring, PACKET3(PACKET3_RELEASE_MEM, 5));
+	radeon_ring_write(ring, (EOP_TCL1_ACTION_EN |
+				 EOP_TC_ACTION_EN |
+				 EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) |
+				 EVENT_INDEX(5)));
+	radeon_ring_write(ring, DATA_SEL(1) | INT_SEL(2));
+	radeon_ring_write(ring, addr & 0xfffffffc);
+	radeon_ring_write(ring, upper_32_bits(addr));
+	radeon_ring_write(ring, fence->seq);
+	radeon_ring_write(ring, 0);
+	/* HDP flush */
+	/* We should be using the new WAIT_REG_MEM special op packet here
+	 * but it causes the CP to hang
+	 */
+	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+				 WRITE_DATA_DST_SEL(0)));
+	radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
+	radeon_ring_write(ring, 0);
+	radeon_ring_write(ring, 0);
+}
+
+void cik_semaphore_ring_emit(struct radeon_device *rdev,
+			     struct radeon_ring *ring,
+			     struct radeon_semaphore *semaphore,
+			     bool emit_wait)
+{
+	uint64_t addr = semaphore->gpu_addr;
+	unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL;
+
+	radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1));
+	radeon_ring_write(ring, addr & 0xffffffff);
+	radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel);
+}
+
+/*
+ * IB stuff
+ */
+/**
+ * cik_ring_ib_execute - emit an IB (Indirect Buffer) on the gfx ring
+ *
+ * @rdev: radeon_device pointer
+ * @ib: radeon indirect buffer object
+ *
+ * Emits an DE (drawing engine) or CE (constant engine) IB
+ * on the gfx ring.  IBs are usually generated by userspace
+ * acceleration drivers and submitted to the kernel for
+ * sheduling on the ring.  This function schedules the IB
+ * on the gfx ring for execution by the GPU.
+ */
+void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+	struct radeon_ring *ring = &rdev->ring[ib->ring];
+	u32 header, control = INDIRECT_BUFFER_VALID;
+
+	if (ib->is_const_ib) {
+		/* set switch buffer packet before const IB */
+		radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
+		radeon_ring_write(ring, 0);
+
+		header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
+	} else {
+		u32 next_rptr;
+		if (ring->rptr_save_reg) {
+			next_rptr = ring->wptr + 3 + 4;
+			radeon_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1));
+			radeon_ring_write(ring, ((ring->rptr_save_reg -
+						  PACKET3_SET_UCONFIG_REG_START) >> 2));
+			radeon_ring_write(ring, next_rptr);
+		} else if (rdev->wb.enabled) {
+			next_rptr = ring->wptr + 5 + 4;
+			radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+			radeon_ring_write(ring, WRITE_DATA_DST_SEL(1));
+			radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
+			radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff);
+			radeon_ring_write(ring, next_rptr);
+		}
+
+		header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
+	}
+
+	control |= ib->length_dw |
+		(ib->vm ? (ib->vm->id << 24) : 0);
+
+	radeon_ring_write(ring, header);
+	radeon_ring_write(ring,
+#ifdef __BIG_ENDIAN
+			  (2 << 0) |
+#endif
+			  (ib->gpu_addr & 0xFFFFFFFC));
+	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
+	radeon_ring_write(ring, control);
+}
+
+/**
+ * cik_ib_test - basic gfx ring IB test
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Allocate an IB and execute it on the gfx ring (CIK).
+ * Provides a basic gfx ring test to verify that IBs are working.
+ * Returns 0 on success, error on failure.
+ */
+int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+	struct radeon_ib ib;
+	uint32_t scratch;
+	uint32_t tmp = 0;
+	unsigned i;
+	int r;
+
+	r = radeon_scratch_get(rdev, &scratch);
+	if (r) {
+		DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
+		return r;
+	}
+	WREG32(scratch, 0xCAFEDEAD);
+	r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256);
+	if (r) {
+		DRM_ERROR("radeon: failed to get ib (%d).\n", r);
+		return r;
+	}
+	ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1);
+	ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2);
+	ib.ptr[2] = 0xDEADBEEF;
+	ib.length_dw = 3;
+	r = radeon_ib_schedule(rdev, &ib, NULL);
+	if (r) {
+		radeon_scratch_free(rdev, scratch);
+		radeon_ib_free(rdev, &ib);
+		DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
+		return r;
+	}
+	r = radeon_fence_wait(ib.fence, false);
+	if (r) {
+		DRM_ERROR("radeon: fence wait failed (%d).\n", r);
+		return r;
+	}
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(scratch);
+		if (tmp == 0xDEADBEEF)
+			break;
+		DRM_UDELAY(1);
+	}
+	if (i < rdev->usec_timeout) {
+		DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib.fence->ring, i);
+	} else {
+		DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n",
+			  scratch, tmp);
+		r = -EINVAL;
+	}
+	radeon_scratch_free(rdev, scratch);
+	radeon_ib_free(rdev, &ib);
+	return r;
+}
+
+/*
+ * CP.
+ * On CIK, gfx and compute now have independant command processors.
+ *
+ * GFX
+ * Gfx consists of a single ring and can process both gfx jobs and
+ * compute jobs.  The gfx CP consists of three microengines (ME):
+ * PFP - Pre-Fetch Parser
+ * ME - Micro Engine
+ * CE - Constant Engine
+ * The PFP and ME make up what is considered the Drawing Engine (DE).
+ * The CE is an asynchronous engine used for updating buffer desciptors
+ * used by the DE so that they can be loaded into cache in parallel
+ * while the DE is processing state update packets.
+ *
+ * Compute
+ * The compute CP consists of two microengines (ME):
+ * MEC1 - Compute MicroEngine 1
+ * MEC2 - Compute MicroEngine 2
+ * Each MEC supports 4 compute pipes and each pipe supports 8 queues.
+ * The queues are exposed to userspace and are programmed directly
+ * by the compute runtime.
+ */
+/**
+ * cik_cp_gfx_enable - enable/disable the gfx CP MEs
+ *
+ * @rdev: radeon_device pointer
+ * @enable: enable or disable the MEs
+ *
+ * Halts or unhalts the gfx MEs.
+ */
+static void cik_cp_gfx_enable(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32(CP_ME_CNTL, 0);
+	else {
+		WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT));
+		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
+	}
+	udelay(50);
+}
+
+/**
+ * cik_cp_gfx_load_microcode - load the gfx CP ME ucode
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Loads the gfx PFP, ME, and CE ucode.
+ * Returns 0 for success, -EINVAL if the ucode is not available.
+ */
+static int cik_cp_gfx_load_microcode(struct radeon_device *rdev)
+{
+	const __be32 *fw_data;
+	int i;
+
+	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw)
+		return -EINVAL;
+
+	cik_cp_gfx_enable(rdev, false);
+
+	/* PFP */
+	fw_data = (const __be32 *)rdev->pfp_fw->data;
+	WREG32(CP_PFP_UCODE_ADDR, 0);
+	for (i = 0; i < CIK_PFP_UCODE_SIZE; i++)
+		WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
+	WREG32(CP_PFP_UCODE_ADDR, 0);
+
+	/* CE */
+	fw_data = (const __be32 *)rdev->ce_fw->data;
+	WREG32(CP_CE_UCODE_ADDR, 0);
+	for (i = 0; i < CIK_CE_UCODE_SIZE; i++)
+		WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
+	WREG32(CP_CE_UCODE_ADDR, 0);
+
+	/* ME */
+	fw_data = (const __be32 *)rdev->me_fw->data;
+	WREG32(CP_ME_RAM_WADDR, 0);
+	for (i = 0; i < CIK_ME_UCODE_SIZE; i++)
+		WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
+	WREG32(CP_ME_RAM_WADDR, 0);
+
+	WREG32(CP_PFP_UCODE_ADDR, 0);
+	WREG32(CP_CE_UCODE_ADDR, 0);
+	WREG32(CP_ME_RAM_WADDR, 0);
+	WREG32(CP_ME_RAM_RADDR, 0);
+	return 0;
+}
+
+/**
+ * cik_cp_gfx_start - start the gfx ring
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Enables the ring and loads the clear state context and other
+ * packets required to init the ring.
+ * Returns 0 for success, error for failure.
+ */
+static int cik_cp_gfx_start(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+	int r, i;
+
+	/* init the CP */
+	WREG32(CP_MAX_CONTEXT, rdev->config.cik.max_hw_contexts - 1);
+	WREG32(CP_ENDIAN_SWAP, 0);
+	WREG32(CP_DEVICE_ID, 1);
+
+	cik_cp_gfx_enable(rdev, true);
+
+	r = radeon_ring_lock(rdev, ring, cik_default_size + 17);
+	if (r) {
+		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
+		return r;
+	}
+
+	/* init the CE partitions.  CE only used for gfx on CIK */
+	radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2));
+	radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
+	radeon_ring_write(ring, 0xc000);
+	radeon_ring_write(ring, 0xc000);
+
+	/* setup clear context state */
+	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
+	radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
+
+	radeon_ring_write(ring, PACKET3(PACKET3_CONTEXT_CONTROL, 1));
+	radeon_ring_write(ring, 0x80000000);
+	radeon_ring_write(ring, 0x80000000);
+
+	for (i = 0; i < cik_default_size; i++)
+		radeon_ring_write(ring, cik_default_state[i]);
+
+	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
+	radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
+
+	/* set clear context state */
+	radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
+	radeon_ring_write(ring, 0);
+
+	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
+	radeon_ring_write(ring, 0x00000316);
+	radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
+	radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */
+
+	radeon_ring_unlock_commit(rdev, ring);
+
+	return 0;
+}
+
+/**
+ * cik_cp_gfx_fini - stop the gfx ring
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Stop the gfx ring and tear down the driver ring
+ * info.
+ */
+static void cik_cp_gfx_fini(struct radeon_device *rdev)
+{
+	cik_cp_gfx_enable(rdev, false);
+	radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
+}
+
+/**
+ * cik_cp_gfx_resume - setup the gfx ring buffer registers
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Program the location and size of the gfx ring buffer
+ * and test it to make sure it's working.
+ * Returns 0 for success, error for failure.
+ */
+static int cik_cp_gfx_resume(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	u32 tmp;
+	u32 rb_bufsz;
+	u64 rb_addr;
+	int r;
+
+	WREG32(CP_SEM_WAIT_TIMER, 0x0);
+	WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
+
+	/* Set the write pointer delay */
+	WREG32(CP_RB_WPTR_DELAY, 0);
+
+	/* set the RB to use vmid 0 */
+	WREG32(CP_RB_VMID, 0);
+
+	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
+
+	/* ring 0 - compute and gfx */
+	/* Set ring buffer size */
+	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+	rb_bufsz = drm_order(ring->ring_size / 8);
+	tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
+#ifdef __BIG_ENDIAN
+	tmp |= BUF_SWAP_32BIT;
+#endif
+	WREG32(CP_RB0_CNTL, tmp);
+
+	/* Initialize the ring buffer's read and write pointers */
+	WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
+	ring->wptr = 0;
+	WREG32(CP_RB0_WPTR, ring->wptr);
+
+	/* set the wb address wether it's enabled or not */
+	WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
+	WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
+
+	/* scratch register shadowing is no longer supported */
+	WREG32(SCRATCH_UMSK, 0);
+
+	if (!rdev->wb.enabled)
+		tmp |= RB_NO_UPDATE;
+
+	mdelay(1);
+	WREG32(CP_RB0_CNTL, tmp);
+
+	rb_addr = ring->gpu_addr >> 8;
+	WREG32(CP_RB0_BASE, rb_addr);
+	WREG32(CP_RB0_BASE_HI, upper_32_bits(rb_addr));
+
+	ring->rptr = RREG32(CP_RB0_RPTR);
+
+	/* start the ring */
+	cik_cp_gfx_start(rdev);
+	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
+	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
+	if (r) {
+		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
+		return r;
+	}
+	return 0;
+}
+
+u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
+			      struct radeon_ring *ring)
+{
+	u32 rptr;
+
+
+
+	if (rdev->wb.enabled) {
+		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+	} else {
+		mutex_lock(&rdev->srbm_mutex);
+		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
+		rptr = RREG32(CP_HQD_PQ_RPTR);
+		cik_srbm_select(rdev, 0, 0, 0, 0);
+		mutex_unlock(&rdev->srbm_mutex);
+	}
+	rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+	return rptr;
+}
+
+u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
+			      struct radeon_ring *ring)
+{
+	u32 wptr;
+
+	if (rdev->wb.enabled) {
+		wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
+	} else {
+		mutex_lock(&rdev->srbm_mutex);
+		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
+		wptr = RREG32(CP_HQD_PQ_WPTR);
+		cik_srbm_select(rdev, 0, 0, 0, 0);
+		mutex_unlock(&rdev->srbm_mutex);
+	}
+	wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+	return wptr;
+}
+
+void cik_compute_ring_set_wptr(struct radeon_device *rdev,
+			       struct radeon_ring *ring)
+{
+	u32 wptr = (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask;
+
+	rdev->wb.wb[ring->wptr_offs/4] = cpu_to_le32(wptr);
+	WDOORBELL32(ring->doorbell_offset, wptr);
+}
+
+/**
+ * cik_cp_compute_enable - enable/disable the compute CP MEs
+ *
+ * @rdev: radeon_device pointer
+ * @enable: enable or disable the MEs
+ *
+ * Halts or unhalts the compute MEs.
+ */
+static void cik_cp_compute_enable(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32(CP_MEC_CNTL, 0);
+	else
+		WREG32(CP_MEC_CNTL, (MEC_ME1_HALT | MEC_ME2_HALT));
+	udelay(50);
+}
+
+/**
+ * cik_cp_compute_load_microcode - load the compute CP ME ucode
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Loads the compute MEC1&2 ucode.
+ * Returns 0 for success, -EINVAL if the ucode is not available.
+ */
+static int cik_cp_compute_load_microcode(struct radeon_device *rdev)
+{
+	const __be32 *fw_data;
+	int i;
+
+	if (!rdev->mec_fw)
+		return -EINVAL;
+
+	cik_cp_compute_enable(rdev, false);
+
+	/* MEC1 */
+	fw_data = (const __be32 *)rdev->mec_fw->data;
+	WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
+	for (i = 0; i < CIK_MEC_UCODE_SIZE; i++)
+		WREG32(CP_MEC_ME1_UCODE_DATA, be32_to_cpup(fw_data++));
+	WREG32(CP_MEC_ME1_UCODE_ADDR, 0);
+
+	if (rdev->family == CHIP_KAVERI) {
+		/* MEC2 */
+		fw_data = (const __be32 *)rdev->mec_fw->data;
+		WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
+		for (i = 0; i < CIK_MEC_UCODE_SIZE; i++)
+			WREG32(CP_MEC_ME2_UCODE_DATA, be32_to_cpup(fw_data++));
+		WREG32(CP_MEC_ME2_UCODE_ADDR, 0);
+	}
+
+	return 0;
+}
+
+/**
+ * cik_cp_compute_start - start the compute queues
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Enable the compute queues.
+ * Returns 0 for success, error for failure.
+ */
+static int cik_cp_compute_start(struct radeon_device *rdev)
+{
+	cik_cp_compute_enable(rdev, true);
+
+	return 0;
+}
+
+/**
+ * cik_cp_compute_fini - stop the compute queues
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Stop the compute queues and tear down the driver queue
+ * info.
+ */
+static void cik_cp_compute_fini(struct radeon_device *rdev)
+{
+	int i, idx, r;
+
+	cik_cp_compute_enable(rdev, false);
+
+	for (i = 0; i < 2; i++) {
+		if (i == 0)
+			idx = CAYMAN_RING_TYPE_CP1_INDEX;
+		else
+			idx = CAYMAN_RING_TYPE_CP2_INDEX;
+
+		if (rdev->ring[idx].mqd_obj) {
+			r = radeon_bo_reserve(rdev->ring[idx].mqd_obj, false);
+			if (unlikely(r != 0))
+				dev_warn(rdev->dev, "(%d) reserve MQD bo failed\n", r);
+
+			radeon_bo_unpin(rdev->ring[idx].mqd_obj);
+			radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
+
+			radeon_bo_unref(&rdev->ring[idx].mqd_obj);
+			rdev->ring[idx].mqd_obj = NULL;
+		}
+	}
+}
+
+static void cik_mec_fini(struct radeon_device *rdev)
+{
+	int r;
+
+	if (rdev->mec.hpd_eop_obj) {
+		r = radeon_bo_reserve(rdev->mec.hpd_eop_obj, false);
+		if (unlikely(r != 0))
+			dev_warn(rdev->dev, "(%d) reserve HPD EOP bo failed\n", r);
+		radeon_bo_unpin(rdev->mec.hpd_eop_obj);
+		radeon_bo_unreserve(rdev->mec.hpd_eop_obj);
+
+		radeon_bo_unref(&rdev->mec.hpd_eop_obj);
+		rdev->mec.hpd_eop_obj = NULL;
+	}
+}
+
+#define MEC_HPD_SIZE 2048
+
+static int cik_mec_init(struct radeon_device *rdev)
+{
+	int r;
+	u32 *hpd;
+
+	/*
+	 * KV:    2 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 64 Queues total
+	 * CI/KB: 1 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 32 Queues total
+	 */
+	if (rdev->family == CHIP_KAVERI)
+		rdev->mec.num_mec = 2;
+	else
+		rdev->mec.num_mec = 1;
+	rdev->mec.num_pipe = 4;
+	rdev->mec.num_queue = rdev->mec.num_mec * rdev->mec.num_pipe * 8;
+
+	if (rdev->mec.hpd_eop_obj == NULL) {
+		r = radeon_bo_create(rdev,
+				     rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2,
+				     PAGE_SIZE, true,
+				     RADEON_GEM_DOMAIN_GTT, NULL,
+				     &rdev->mec.hpd_eop_obj);
+		if (r) {
+			dev_warn(rdev->dev, "(%d) create HDP EOP bo failed\n", r);
+			return r;
+		}
+	}
+
+	r = radeon_bo_reserve(rdev->mec.hpd_eop_obj, false);
+	if (unlikely(r != 0)) {
+		cik_mec_fini(rdev);
+		return r;
+	}
+	r = radeon_bo_pin(rdev->mec.hpd_eop_obj, RADEON_GEM_DOMAIN_GTT,
+			  &rdev->mec.hpd_eop_gpu_addr);
+	if (r) {
+		dev_warn(rdev->dev, "(%d) pin HDP EOP bo failed\n", r);
+		cik_mec_fini(rdev);
+		return r;
+	}
+	r = radeon_bo_kmap(rdev->mec.hpd_eop_obj, (void **)&hpd);
+	if (r) {
+		dev_warn(rdev->dev, "(%d) map HDP EOP bo failed\n", r);
+		cik_mec_fini(rdev);
+		return r;
+	}
+
+	/* clear memory.  Not sure if this is required or not */
+	memset(hpd, 0, rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2);
+
+	radeon_bo_kunmap(rdev->mec.hpd_eop_obj);
+	radeon_bo_unreserve(rdev->mec.hpd_eop_obj);
+
+	return 0;
+}
+
+struct hqd_registers
+{
+	u32 cp_mqd_base_addr;
+	u32 cp_mqd_base_addr_hi;
+	u32 cp_hqd_active;
+	u32 cp_hqd_vmid;
+	u32 cp_hqd_persistent_state;
+	u32 cp_hqd_pipe_priority;
+	u32 cp_hqd_queue_priority;
+	u32 cp_hqd_quantum;
+	u32 cp_hqd_pq_base;
+	u32 cp_hqd_pq_base_hi;
+	u32 cp_hqd_pq_rptr;
+	u32 cp_hqd_pq_rptr_report_addr;
+	u32 cp_hqd_pq_rptr_report_addr_hi;
+	u32 cp_hqd_pq_wptr_poll_addr;
+	u32 cp_hqd_pq_wptr_poll_addr_hi;
+	u32 cp_hqd_pq_doorbell_control;
+	u32 cp_hqd_pq_wptr;
+	u32 cp_hqd_pq_control;
+	u32 cp_hqd_ib_base_addr;
+	u32 cp_hqd_ib_base_addr_hi;
+	u32 cp_hqd_ib_rptr;
+	u32 cp_hqd_ib_control;
+	u32 cp_hqd_iq_timer;
+	u32 cp_hqd_iq_rptr;
+	u32 cp_hqd_dequeue_request;
+	u32 cp_hqd_dma_offload;
+	u32 cp_hqd_sema_cmd;
+	u32 cp_hqd_msg_type;
+	u32 cp_hqd_atomic0_preop_lo;
+	u32 cp_hqd_atomic0_preop_hi;
+	u32 cp_hqd_atomic1_preop_lo;
+	u32 cp_hqd_atomic1_preop_hi;
+	u32 cp_hqd_hq_scheduler0;
+	u32 cp_hqd_hq_scheduler1;
+	u32 cp_mqd_control;
+};
+
+struct bonaire_mqd
+{
+	u32 header;
+	u32 dispatch_initiator;
+	u32 dimensions[3];
+	u32 start_idx[3];
+	u32 num_threads[3];
+	u32 pipeline_stat_enable;
+	u32 perf_counter_enable;
+	u32 pgm[2];
+	u32 tba[2];
+	u32 tma[2];
+	u32 pgm_rsrc[2];
+	u32 vmid;
+	u32 resource_limits;
+	u32 static_thread_mgmt01[2];
+	u32 tmp_ring_size;
+	u32 static_thread_mgmt23[2];
+	u32 restart[3];
+	u32 thread_trace_enable;
+	u32 reserved1;
+	u32 user_data[16];
+	u32 vgtcs_invoke_count[2];
+	struct hqd_registers queue_state;
+	u32 dequeue_cntr;
+	u32 interrupt_queue[64];
+};
+
+/**
+ * cik_cp_compute_resume - setup the compute queue registers
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Program the compute queues and test them to make sure they
+ * are working.
+ * Returns 0 for success, error for failure.
+ */
+static int cik_cp_compute_resume(struct radeon_device *rdev)
+{
+	int r, i, idx;
+	u32 tmp;
+	bool use_doorbell = true;
+	u64 hqd_gpu_addr;
+	u64 mqd_gpu_addr;
+	u64 eop_gpu_addr;
+	u64 wb_gpu_addr;
+	u32 *buf;
+	struct bonaire_mqd *mqd;
+
+	r = cik_cp_compute_start(rdev);
+	if (r)
+		return r;
+
+	/* fix up chicken bits */
+	tmp = RREG32(CP_CPF_DEBUG);
+	tmp |= (1 << 23);
+	WREG32(CP_CPF_DEBUG, tmp);
+
+	/* init the pipes */
+	mutex_lock(&rdev->srbm_mutex);
+	for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) {
+		int me = (i < 4) ? 1 : 2;
+		int pipe = (i < 4) ? i : (i - 4);
+
+		eop_gpu_addr = rdev->mec.hpd_eop_gpu_addr + (i * MEC_HPD_SIZE * 2);
+
+		cik_srbm_select(rdev, me, pipe, 0, 0);
+
+		/* write the EOP addr */
+		WREG32(CP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8);
+		WREG32(CP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(eop_gpu_addr) >> 8);
+
+		/* set the VMID assigned */
+		WREG32(CP_HPD_EOP_VMID, 0);
+
+		/* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */
+		tmp = RREG32(CP_HPD_EOP_CONTROL);
+		tmp &= ~EOP_SIZE_MASK;
+		tmp |= drm_order(MEC_HPD_SIZE / 8);
+		WREG32(CP_HPD_EOP_CONTROL, tmp);
+	}
+	cik_srbm_select(rdev, 0, 0, 0, 0);
+	mutex_unlock(&rdev->srbm_mutex);
+
+	/* init the queues.  Just two for now. */
+	for (i = 0; i < 2; i++) {
+		if (i == 0)
+			idx = CAYMAN_RING_TYPE_CP1_INDEX;
+		else
+			idx = CAYMAN_RING_TYPE_CP2_INDEX;
+
+		if (rdev->ring[idx].mqd_obj == NULL) {
+			r = radeon_bo_create(rdev,
+					     sizeof(struct bonaire_mqd),
+					     PAGE_SIZE, true,
+					     RADEON_GEM_DOMAIN_GTT, NULL,
+					     &rdev->ring[idx].mqd_obj);
+			if (r) {
+				dev_warn(rdev->dev, "(%d) create MQD bo failed\n", r);
+				return r;
+			}
+		}
+
+		r = radeon_bo_reserve(rdev->ring[idx].mqd_obj, false);
+		if (unlikely(r != 0)) {
+			cik_cp_compute_fini(rdev);
+			return r;
+		}
+		r = radeon_bo_pin(rdev->ring[idx].mqd_obj, RADEON_GEM_DOMAIN_GTT,
+				  &mqd_gpu_addr);
+		if (r) {
+			dev_warn(rdev->dev, "(%d) pin MQD bo failed\n", r);
+			cik_cp_compute_fini(rdev);
+			return r;
+		}
+		r = radeon_bo_kmap(rdev->ring[idx].mqd_obj, (void **)&buf);
+		if (r) {
+			dev_warn(rdev->dev, "(%d) map MQD bo failed\n", r);
+			cik_cp_compute_fini(rdev);
+			return r;
+		}
+
+		/* doorbell offset */
+		rdev->ring[idx].doorbell_offset =
+			(rdev->ring[idx].doorbell_page_num * PAGE_SIZE) + 0;
+
+		/* init the mqd struct */
+		memset(buf, 0, sizeof(struct bonaire_mqd));
+
+		mqd = (struct bonaire_mqd *)buf;
+		mqd->header = 0xC0310800;
+		mqd->static_thread_mgmt01[0] = 0xffffffff;
+		mqd->static_thread_mgmt01[1] = 0xffffffff;
+		mqd->static_thread_mgmt23[0] = 0xffffffff;
+		mqd->static_thread_mgmt23[1] = 0xffffffff;
+
+		mutex_lock(&rdev->srbm_mutex);
+		cik_srbm_select(rdev, rdev->ring[idx].me,
+				rdev->ring[idx].pipe,
+				rdev->ring[idx].queue, 0);
+
+		/* disable wptr polling */
+		tmp = RREG32(CP_PQ_WPTR_POLL_CNTL);
+		tmp &= ~WPTR_POLL_EN;
+		WREG32(CP_PQ_WPTR_POLL_CNTL, tmp);
+
+		/* enable doorbell? */
+		mqd->queue_state.cp_hqd_pq_doorbell_control =
+			RREG32(CP_HQD_PQ_DOORBELL_CONTROL);
+		if (use_doorbell)
+			mqd->queue_state.cp_hqd_pq_doorbell_control |= DOORBELL_EN;
+		else
+			mqd->queue_state.cp_hqd_pq_doorbell_control &= ~DOORBELL_EN;
+		WREG32(CP_HQD_PQ_DOORBELL_CONTROL,
+		       mqd->queue_state.cp_hqd_pq_doorbell_control);
+
+		/* disable the queue if it's active */
+		mqd->queue_state.cp_hqd_dequeue_request = 0;
+		mqd->queue_state.cp_hqd_pq_rptr = 0;
+		mqd->queue_state.cp_hqd_pq_wptr= 0;
+		if (RREG32(CP_HQD_ACTIVE) & 1) {
+			WREG32(CP_HQD_DEQUEUE_REQUEST, 1);
+			for (i = 0; i < rdev->usec_timeout; i++) {
+				if (!(RREG32(CP_HQD_ACTIVE) & 1))
+					break;
+				udelay(1);
+			}
+			WREG32(CP_HQD_DEQUEUE_REQUEST, mqd->queue_state.cp_hqd_dequeue_request);
+			WREG32(CP_HQD_PQ_RPTR, mqd->queue_state.cp_hqd_pq_rptr);
+			WREG32(CP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr);
+		}
+
+		/* set the pointer to the MQD */
+		mqd->queue_state.cp_mqd_base_addr = mqd_gpu_addr & 0xfffffffc;
+		mqd->queue_state.cp_mqd_base_addr_hi = upper_32_bits(mqd_gpu_addr);
+		WREG32(CP_MQD_BASE_ADDR, mqd->queue_state.cp_mqd_base_addr);
+		WREG32(CP_MQD_BASE_ADDR_HI, mqd->queue_state.cp_mqd_base_addr_hi);
+		/* set MQD vmid to 0 */
+		mqd->queue_state.cp_mqd_control = RREG32(CP_MQD_CONTROL);
+		mqd->queue_state.cp_mqd_control &= ~MQD_VMID_MASK;
+		WREG32(CP_MQD_CONTROL, mqd->queue_state.cp_mqd_control);
+
+		/* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */
+		hqd_gpu_addr = rdev->ring[idx].gpu_addr >> 8;
+		mqd->queue_state.cp_hqd_pq_base = hqd_gpu_addr;
+		mqd->queue_state.cp_hqd_pq_base_hi = upper_32_bits(hqd_gpu_addr);
+		WREG32(CP_HQD_PQ_BASE, mqd->queue_state.cp_hqd_pq_base);
+		WREG32(CP_HQD_PQ_BASE_HI, mqd->queue_state.cp_hqd_pq_base_hi);
+
+		/* set up the HQD, this is similar to CP_RB0_CNTL */
+		mqd->queue_state.cp_hqd_pq_control = RREG32(CP_HQD_PQ_CONTROL);
+		mqd->queue_state.cp_hqd_pq_control &=
+			~(QUEUE_SIZE_MASK | RPTR_BLOCK_SIZE_MASK);
+
+		mqd->queue_state.cp_hqd_pq_control |=
+			drm_order(rdev->ring[idx].ring_size / 8);
+		mqd->queue_state.cp_hqd_pq_control |=
+			(drm_order(RADEON_GPU_PAGE_SIZE/8) << 8);
+#ifdef __BIG_ENDIAN
+		mqd->queue_state.cp_hqd_pq_control |= BUF_SWAP_32BIT;
+#endif
+		mqd->queue_state.cp_hqd_pq_control &=
+			~(UNORD_DISPATCH | ROQ_PQ_IB_FLIP | PQ_VOLATILE);
+		mqd->queue_state.cp_hqd_pq_control |=
+			PRIV_STATE | KMD_QUEUE; /* assuming kernel queue control */
+		WREG32(CP_HQD_PQ_CONTROL, mqd->queue_state.cp_hqd_pq_control);
+
+		/* only used if CP_PQ_WPTR_POLL_CNTL.WPTR_POLL_EN=1 */
+		if (i == 0)
+			wb_gpu_addr = rdev->wb.gpu_addr + CIK_WB_CP1_WPTR_OFFSET;
+		else
+			wb_gpu_addr = rdev->wb.gpu_addr + CIK_WB_CP2_WPTR_OFFSET;
+		mqd->queue_state.cp_hqd_pq_wptr_poll_addr = wb_gpu_addr & 0xfffffffc;
+		mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0xffff;
+		WREG32(CP_HQD_PQ_WPTR_POLL_ADDR, mqd->queue_state.cp_hqd_pq_wptr_poll_addr);
+		WREG32(CP_HQD_PQ_WPTR_POLL_ADDR_HI,
+		       mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi);
+
+		/* set the wb address wether it's enabled or not */
+		if (i == 0)
+			wb_gpu_addr = rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET;
+		else
+			wb_gpu_addr = rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET;
+		mqd->queue_state.cp_hqd_pq_rptr_report_addr = wb_gpu_addr & 0xfffffffc;
+		mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi =
+			upper_32_bits(wb_gpu_addr) & 0xffff;
+		WREG32(CP_HQD_PQ_RPTR_REPORT_ADDR,
+		       mqd->queue_state.cp_hqd_pq_rptr_report_addr);
+		WREG32(CP_HQD_PQ_RPTR_REPORT_ADDR_HI,
+		       mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi);
+
+		/* enable the doorbell if requested */
+		if (use_doorbell) {
+			mqd->queue_state.cp_hqd_pq_doorbell_control =
+				RREG32(CP_HQD_PQ_DOORBELL_CONTROL);
+			mqd->queue_state.cp_hqd_pq_doorbell_control &= ~DOORBELL_OFFSET_MASK;
+			mqd->queue_state.cp_hqd_pq_doorbell_control |=
+				DOORBELL_OFFSET(rdev->ring[idx].doorbell_offset / 4);
+			mqd->queue_state.cp_hqd_pq_doorbell_control |= DOORBELL_EN;
+			mqd->queue_state.cp_hqd_pq_doorbell_control &=
+				~(DOORBELL_SOURCE | DOORBELL_HIT);
+
+		} else {
+			mqd->queue_state.cp_hqd_pq_doorbell_control = 0;
+		}
+		WREG32(CP_HQD_PQ_DOORBELL_CONTROL,
+		       mqd->queue_state.cp_hqd_pq_doorbell_control);
+
+		/* read and write pointers, similar to CP_RB0_WPTR/_RPTR */
+		rdev->ring[idx].wptr = 0;
+		mqd->queue_state.cp_hqd_pq_wptr = rdev->ring[idx].wptr;
+		WREG32(CP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr);
+		rdev->ring[idx].rptr = RREG32(CP_HQD_PQ_RPTR);
+		mqd->queue_state.cp_hqd_pq_rptr = rdev->ring[idx].rptr;
+
+		/* set the vmid for the queue */
+		mqd->queue_state.cp_hqd_vmid = 0;
+		WREG32(CP_HQD_VMID, mqd->queue_state.cp_hqd_vmid);
+
+		/* activate the queue */
+		mqd->queue_state.cp_hqd_active = 1;
+		WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active);
+
+		cik_srbm_select(rdev, 0, 0, 0, 0);
+		mutex_unlock(&rdev->srbm_mutex);
+
+		radeon_bo_kunmap(rdev->ring[idx].mqd_obj);
+		radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
+
+		rdev->ring[idx].ready = true;
+		r = radeon_ring_test(rdev, idx, &rdev->ring[idx]);
+		if (r)
+			rdev->ring[idx].ready = false;
+	}
+
+	return 0;
+}
+
+static void cik_cp_enable(struct radeon_device *rdev, bool enable)
+{
+	cik_cp_gfx_enable(rdev, enable);
+	cik_cp_compute_enable(rdev, enable);
+}
+
+static int cik_cp_load_microcode(struct radeon_device *rdev)
+{
+	int r;
+
+	r = cik_cp_gfx_load_microcode(rdev);
+	if (r)
+		return r;
+	r = cik_cp_compute_load_microcode(rdev);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+static void cik_cp_fini(struct radeon_device *rdev)
+{
+	cik_cp_gfx_fini(rdev);
+	cik_cp_compute_fini(rdev);
+}
+
+static int cik_cp_resume(struct radeon_device *rdev)
+{
+	int r;
+
+	/* Reset all cp blocks */
+	WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
+	RREG32(GRBM_SOFT_RESET);
+	mdelay(15);
+	WREG32(GRBM_SOFT_RESET, 0);
+	RREG32(GRBM_SOFT_RESET);
+
+	r = cik_cp_load_microcode(rdev);
+	if (r)
+		return r;
+
+	r = cik_cp_gfx_resume(rdev);
+	if (r)
+		return r;
+	r = cik_cp_compute_resume(rdev);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+/*
+ * sDMA - System DMA
+ * Starting with CIK, the GPU has new asynchronous
+ * DMA engines.  These engines are used for compute
+ * and gfx.  There are two DMA engines (SDMA0, SDMA1)
+ * and each one supports 1 ring buffer used for gfx
+ * and 2 queues used for compute.
+ *
+ * The programming model is very similar to the CP
+ * (ring buffer, IBs, etc.), but sDMA has it's own
+ * packet format that is different from the PM4 format
+ * used by the CP. sDMA supports copying data, writing
+ * embedded data, solid fills, and a number of other
+ * things.  It also has support for tiling/detiling of
+ * buffers.
+ */
+/**
+ * cik_sdma_ring_ib_execute - Schedule an IB on the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @ib: IB object to schedule
+ *
+ * Schedule an IB in the DMA ring (CIK).
+ */
+void cik_sdma_ring_ib_execute(struct radeon_device *rdev,
+			      struct radeon_ib *ib)
+{
+	struct radeon_ring *ring = &rdev->ring[ib->ring];
+	u32 extra_bits = (ib->vm ? ib->vm->id : 0) & 0xf;
+
+	if (rdev->wb.enabled) {
+		u32 next_rptr = ring->wptr + 5;
+		while ((next_rptr & 7) != 4)
+			next_rptr++;
+		next_rptr += 4;
+		radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0));
+		radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
+		radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff);
+		radeon_ring_write(ring, 1); /* number of DWs to follow */
+		radeon_ring_write(ring, next_rptr);
+	}
+
+	/* IB packet must end on a 8 DW boundary */
+	while ((ring->wptr & 7) != 4)
+		radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_INDIRECT_BUFFER, 0, extra_bits));
+	radeon_ring_write(ring, ib->gpu_addr & 0xffffffe0); /* base must be 32 byte aligned */
+	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xffffffff);
+	radeon_ring_write(ring, ib->length_dw);
+
+}
+
+/**
+ * cik_sdma_fence_ring_emit - emit a fence on the DMA ring
+ *
+ * @rdev: radeon_device pointer
+ * @fence: radeon fence object
+ *
+ * Add a DMA fence packet to the ring to write
+ * the fence seq number and DMA trap packet to generate
+ * an interrupt if needed (CIK).
+ */
+void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
+			      struct radeon_fence *fence)
+{
+	struct radeon_ring *ring = &rdev->ring[fence->ring];
+	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
+	u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) |
+			  SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */
+	u32 ref_and_mask;
+
+	if (fence->ring == R600_RING_TYPE_DMA_INDEX)
+		ref_and_mask = SDMA0;
+	else
+		ref_and_mask = SDMA1;
+
+	/* write the fence */
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_FENCE, 0, 0));
+	radeon_ring_write(ring, addr & 0xffffffff);
+	radeon_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
+	radeon_ring_write(ring, fence->seq);
+	/* generate an interrupt */
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_TRAP, 0, 0));
+	/* flush HDP */
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits));
+	radeon_ring_write(ring, GPU_HDP_FLUSH_DONE);
+	radeon_ring_write(ring, GPU_HDP_FLUSH_REQ);
+	radeon_ring_write(ring, ref_and_mask); /* REFERENCE */
+	radeon_ring_write(ring, ref_and_mask); /* MASK */
+	radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */
+}
+
+/**
+ * cik_sdma_semaphore_ring_emit - emit a semaphore on the dma ring
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ * @semaphore: radeon semaphore object
+ * @emit_wait: wait or signal semaphore
+ *
+ * Add a DMA semaphore packet to the ring wait on or signal
+ * other rings (CIK).
+ */
+void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
+				  struct radeon_ring *ring,
+				  struct radeon_semaphore *semaphore,
+				  bool emit_wait)
+{
+	u64 addr = semaphore->gpu_addr;
+	u32 extra_bits = emit_wait ? 0 : SDMA_SEMAPHORE_EXTRA_S;
+
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SEMAPHORE, 0, extra_bits));
+	radeon_ring_write(ring, addr & 0xfffffff8);
+	radeon_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
+}
+
+/**
+ * cik_sdma_gfx_stop - stop the gfx async dma engines
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Stop the gfx async dma ring buffers (CIK).
+ */
+static void cik_sdma_gfx_stop(struct radeon_device *rdev)
+{
+	u32 rb_cntl, reg_offset;
+	int i;
+
+	radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
+
+	for (i = 0; i < 2; i++) {
+		if (i == 0)
+			reg_offset = SDMA0_REGISTER_OFFSET;
+		else
+			reg_offset = SDMA1_REGISTER_OFFSET;
+		rb_cntl = RREG32(SDMA0_GFX_RB_CNTL + reg_offset);
+		rb_cntl &= ~SDMA_RB_ENABLE;
+		WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl);
+		WREG32(SDMA0_GFX_IB_CNTL + reg_offset, 0);
+	}
+}
+
+/**
+ * cik_sdma_rlc_stop - stop the compute async dma engines
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Stop the compute async dma queues (CIK).
+ */
+static void cik_sdma_rlc_stop(struct radeon_device *rdev)
+{
+	/* XXX todo */
+}
+
+/**
+ * cik_sdma_enable - stop the async dma engines
+ *
+ * @rdev: radeon_device pointer
+ * @enable: enable/disable the DMA MEs.
+ *
+ * Halt or unhalt the async dma engines (CIK).
+ */
+static void cik_sdma_enable(struct radeon_device *rdev, bool enable)
+{
+	u32 me_cntl, reg_offset;
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (i == 0)
+			reg_offset = SDMA0_REGISTER_OFFSET;
+		else
+			reg_offset = SDMA1_REGISTER_OFFSET;
+		me_cntl = RREG32(SDMA0_ME_CNTL + reg_offset);
+		if (enable)
+			me_cntl &= ~SDMA_HALT;
+		else
+			me_cntl |= SDMA_HALT;
+		WREG32(SDMA0_ME_CNTL + reg_offset, me_cntl);
+	}
+}
+
+/**
+ * cik_sdma_gfx_resume - setup and start the async dma engines
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Set up the gfx DMA ring buffers and enable them (CIK).
+ * Returns 0 for success, error for failure.
+ */
+static int cik_sdma_gfx_resume(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	u32 rb_cntl, ib_cntl;
+	u32 rb_bufsz;
+	u32 reg_offset, wb_offset;
+	int i, r;
+
+	for (i = 0; i < 2; i++) {
+		if (i == 0) {
+			ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+			reg_offset = SDMA0_REGISTER_OFFSET;
+			wb_offset = R600_WB_DMA_RPTR_OFFSET;
+		} else {
+			ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
+			reg_offset = SDMA1_REGISTER_OFFSET;
+			wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET;
+		}
+
+		WREG32(SDMA0_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0);
+		WREG32(SDMA0_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0);
+
+		/* Set ring buffer size in dwords */
+		rb_bufsz = drm_order(ring->ring_size / 4);
+		rb_cntl = rb_bufsz << 1;
+#ifdef __BIG_ENDIAN
+		rb_cntl |= SDMA_RB_SWAP_ENABLE | SDMA_RPTR_WRITEBACK_SWAP_ENABLE;
+#endif
+		WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl);
+
+		/* Initialize the ring buffer's read and write pointers */
+		WREG32(SDMA0_GFX_RB_RPTR + reg_offset, 0);
+		WREG32(SDMA0_GFX_RB_WPTR + reg_offset, 0);
+
+		/* set the wb address whether it's enabled or not */
+		WREG32(SDMA0_GFX_RB_RPTR_ADDR_HI + reg_offset,
+		       upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFF);
+		WREG32(SDMA0_GFX_RB_RPTR_ADDR_LO + reg_offset,
+		       ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC));
+
+		if (rdev->wb.enabled)
+			rb_cntl |= SDMA_RPTR_WRITEBACK_ENABLE;
+
+		WREG32(SDMA0_GFX_RB_BASE + reg_offset, ring->gpu_addr >> 8);
+		WREG32(SDMA0_GFX_RB_BASE_HI + reg_offset, ring->gpu_addr >> 40);
+
+		ring->wptr = 0;
+		WREG32(SDMA0_GFX_RB_WPTR + reg_offset, ring->wptr << 2);
+
+		ring->rptr = RREG32(SDMA0_GFX_RB_RPTR + reg_offset) >> 2;
+
+		/* enable DMA RB */
+		WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl | SDMA_RB_ENABLE);
+
+		ib_cntl = SDMA_IB_ENABLE;
+#ifdef __BIG_ENDIAN
+		ib_cntl |= SDMA_IB_SWAP_ENABLE;
+#endif
+		/* enable DMA IBs */
+		WREG32(SDMA0_GFX_IB_CNTL + reg_offset, ib_cntl);
+
+		ring->ready = true;
+
+		r = radeon_ring_test(rdev, ring->idx, ring);
+		if (r) {
+			ring->ready = false;
+			return r;
+		}
+	}
+
+	radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
+
+	return 0;
+}
+
+/**
+ * cik_sdma_rlc_resume - setup and start the async dma engines
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Set up the compute DMA queues and enable them (CIK).
+ * Returns 0 for success, error for failure.
+ */
+static int cik_sdma_rlc_resume(struct radeon_device *rdev)
+{
+	/* XXX todo */
+	return 0;
+}
+
+/**
+ * cik_sdma_load_microcode - load the sDMA ME ucode
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Loads the sDMA0/1 ucode.
+ * Returns 0 for success, -EINVAL if the ucode is not available.
+ */
+static int cik_sdma_load_microcode(struct radeon_device *rdev)
+{
+	const __be32 *fw_data;
+	int i;
+
+	if (!rdev->sdma_fw)
+		return -EINVAL;
+
+	/* stop the gfx rings and rlc compute queues */
+	cik_sdma_gfx_stop(rdev);
+	cik_sdma_rlc_stop(rdev);
+
+	/* halt the MEs */
+	cik_sdma_enable(rdev, false);
+
+	/* sdma0 */
+	fw_data = (const __be32 *)rdev->sdma_fw->data;
+	WREG32(SDMA0_UCODE_ADDR + SDMA0_REGISTER_OFFSET, 0);
+	for (i = 0; i < CIK_SDMA_UCODE_SIZE; i++)
+		WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, be32_to_cpup(fw_data++));
+	WREG32(SDMA0_UCODE_DATA + SDMA0_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
+
+	/* sdma1 */
+	fw_data = (const __be32 *)rdev->sdma_fw->data;
+	WREG32(SDMA0_UCODE_ADDR + SDMA1_REGISTER_OFFSET, 0);
+	for (i = 0; i < CIK_SDMA_UCODE_SIZE; i++)
+		WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, be32_to_cpup(fw_data++));
+	WREG32(SDMA0_UCODE_DATA + SDMA1_REGISTER_OFFSET, CIK_SDMA_UCODE_VERSION);
+
+	WREG32(SDMA0_UCODE_ADDR + SDMA0_REGISTER_OFFSET, 0);
+	WREG32(SDMA0_UCODE_ADDR + SDMA1_REGISTER_OFFSET, 0);
+	return 0;
+}
+
+/**
+ * cik_sdma_resume - setup and start the async dma engines
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Set up the DMA engines and enable them (CIK).
+ * Returns 0 for success, error for failure.
+ */
+static int cik_sdma_resume(struct radeon_device *rdev)
+{
+	int r;
+
+	/* Reset dma */
+	WREG32(SRBM_SOFT_RESET, SOFT_RESET_SDMA | SOFT_RESET_SDMA1);
+	RREG32(SRBM_SOFT_RESET);
+	udelay(50);
+	WREG32(SRBM_SOFT_RESET, 0);
+	RREG32(SRBM_SOFT_RESET);
+
+	r = cik_sdma_load_microcode(rdev);
+	if (r)
+		return r;
+
+	/* unhalt the MEs */
+	cik_sdma_enable(rdev, true);
+
+	/* start the gfx rings and rlc compute queues */
+	r = cik_sdma_gfx_resume(rdev);
+	if (r)
+		return r;
+	r = cik_sdma_rlc_resume(rdev);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+/**
+ * cik_sdma_fini - tear down the async dma engines
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Stop the async dma engines and free the rings (CIK).
+ */
+static void cik_sdma_fini(struct radeon_device *rdev)
+{
+	/* stop the gfx rings and rlc compute queues */
+	cik_sdma_gfx_stop(rdev);
+	cik_sdma_rlc_stop(rdev);
+	/* halt the MEs */
+	cik_sdma_enable(rdev, false);
+	radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]);
+	radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]);
+	/* XXX - compute dma queue tear down */
+}
+
+/**
+ * cik_copy_dma - copy pages using the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @src_offset: src GPU address
+ * @dst_offset: dst GPU address
+ * @num_gpu_pages: number of GPU pages to xfer
+ * @fence: radeon fence object
+ *
+ * Copy GPU paging using the DMA engine (CIK).
+ * Used by the radeon ttm implementation to move pages if
+ * registered as the asic copy callback.
+ */
+int cik_copy_dma(struct radeon_device *rdev,
+		 uint64_t src_offset, uint64_t dst_offset,
+		 unsigned num_gpu_pages,
+		 struct radeon_fence **fence)
+{
+	struct radeon_semaphore *sem = NULL;
+	int ring_index = rdev->asic->copy.dma_ring_index;
+	struct radeon_ring *ring = &rdev->ring[ring_index];
+	u32 size_in_bytes, cur_size_in_bytes;
+	int i, num_loops;
+	int r = 0;
+
+	r = radeon_semaphore_create(rdev, &sem);
+	if (r) {
+		DRM_ERROR("radeon: moving bo (%d).\n", r);
+		return r;
+	}
+
+	size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
+	num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff);
+	r = radeon_ring_lock(rdev, ring, num_loops * 7 + 14);
+	if (r) {
+		DRM_ERROR("radeon: moving bo (%d).\n", r);
+		radeon_semaphore_free(rdev, &sem, NULL);
+		return r;
+	}
+
+	if (radeon_fence_need_sync(*fence, ring->idx)) {
+		radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+					    ring->idx);
+		radeon_fence_note_sync(*fence, ring->idx);
+	} else {
+		radeon_semaphore_free(rdev, &sem, NULL);
+	}
+
+	for (i = 0; i < num_loops; i++) {
+		cur_size_in_bytes = size_in_bytes;
+		if (cur_size_in_bytes > 0x1fffff)
+			cur_size_in_bytes = 0x1fffff;
+		size_in_bytes -= cur_size_in_bytes;
+		radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_LINEAR, 0));
+		radeon_ring_write(ring, cur_size_in_bytes);
+		radeon_ring_write(ring, 0); /* src/dst endian swap */
+		radeon_ring_write(ring, src_offset & 0xffffffff);
+		radeon_ring_write(ring, upper_32_bits(src_offset) & 0xffffffff);
+		radeon_ring_write(ring, dst_offset & 0xfffffffc);
+		radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xffffffff);
+		src_offset += cur_size_in_bytes;
+		dst_offset += cur_size_in_bytes;
+	}
+
+	r = radeon_fence_emit(rdev, fence, ring->idx);
+	if (r) {
+		radeon_ring_unlock_undo(rdev, ring);
+		return r;
+	}
+
+	radeon_ring_unlock_commit(rdev, ring);
+	radeon_semaphore_free(rdev, &sem, *fence);
+
+	return r;
+}
+
+/**
+ * cik_sdma_ring_test - simple async dma engine test
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Test the DMA engine by writing using it to write an
+ * value to memory. (CIK).
+ * Returns 0 for success, error for failure.
+ */
+int cik_sdma_ring_test(struct radeon_device *rdev,
+		       struct radeon_ring *ring)
+{
+	unsigned i;
+	int r;
+	void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
+	u32 tmp;
+
+	if (!ptr) {
+		DRM_ERROR("invalid vram scratch pointer\n");
+		return -EINVAL;
+	}
+
+	tmp = 0xCAFEDEAD;
+	writel(tmp, ptr);
+
+	r = radeon_ring_lock(rdev, ring, 4);
+	if (r) {
+		DRM_ERROR("radeon: dma failed to lock ring %d (%d).\n", ring->idx, r);
+		return r;
+	}
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0));
+	radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc);
+	radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xffffffff);
+	radeon_ring_write(ring, 1); /* number of DWs to follow */
+	radeon_ring_write(ring, 0xDEADBEEF);
+	radeon_ring_unlock_commit(rdev, ring);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = readl(ptr);
+		if (tmp == 0xDEADBEEF)
+			break;
+		DRM_UDELAY(1);
+	}
+
+	if (i < rdev->usec_timeout) {
+		DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
+	} else {
+		DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
+			  ring->idx, tmp);
+		r = -EINVAL;
+	}
+	return r;
+}
+
+/**
+ * cik_sdma_ib_test - test an IB on the DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Test a simple IB in the DMA ring (CIK).
+ * Returns 0 on success, error on failure.
+ */
+int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+	struct radeon_ib ib;
+	unsigned i;
+	int r;
+	void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
+	u32 tmp = 0;
+
+	if (!ptr) {
+		DRM_ERROR("invalid vram scratch pointer\n");
+		return -EINVAL;
+	}
+
+	tmp = 0xCAFEDEAD;
+	writel(tmp, ptr);
+
+	r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256);
+	if (r) {
+		DRM_ERROR("radeon: failed to get ib (%d).\n", r);
+		return r;
+	}
+
+	ib.ptr[0] = SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
+	ib.ptr[1] = rdev->vram_scratch.gpu_addr & 0xfffffffc;
+	ib.ptr[2] = upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xffffffff;
+	ib.ptr[3] = 1;
+	ib.ptr[4] = 0xDEADBEEF;
+	ib.length_dw = 5;
+
+	r = radeon_ib_schedule(rdev, &ib, NULL);
+	if (r) {
+		radeon_ib_free(rdev, &ib);
+		DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
+		return r;
+	}
+	r = radeon_fence_wait(ib.fence, false);
+	if (r) {
+		DRM_ERROR("radeon: fence wait failed (%d).\n", r);
+		return r;
+	}
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = readl(ptr);
+		if (tmp == 0xDEADBEEF)
+			break;
+		DRM_UDELAY(1);
+	}
+	if (i < rdev->usec_timeout) {
+		DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib.fence->ring, i);
+	} else {
+		DRM_ERROR("radeon: ib test failed (0x%08X)\n", tmp);
+		r = -EINVAL;
+	}
+	radeon_ib_free(rdev, &ib);
+	return r;
+}
+
+
+static void cik_print_gpu_status_regs(struct radeon_device *rdev)
+{
+	dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
+		RREG32(GRBM_STATUS));
+	dev_info(rdev->dev, "  GRBM_STATUS2=0x%08X\n",
+		RREG32(GRBM_STATUS2));
+	dev_info(rdev->dev, "  GRBM_STATUS_SE0=0x%08X\n",
+		RREG32(GRBM_STATUS_SE0));
+	dev_info(rdev->dev, "  GRBM_STATUS_SE1=0x%08X\n",
+		RREG32(GRBM_STATUS_SE1));
+	dev_info(rdev->dev, "  GRBM_STATUS_SE2=0x%08X\n",
+		RREG32(GRBM_STATUS_SE2));
+	dev_info(rdev->dev, "  GRBM_STATUS_SE3=0x%08X\n",
+		RREG32(GRBM_STATUS_SE3));
+	dev_info(rdev->dev, "  SRBM_STATUS=0x%08X\n",
+		RREG32(SRBM_STATUS));
+	dev_info(rdev->dev, "  SRBM_STATUS2=0x%08X\n",
+		RREG32(SRBM_STATUS2));
+	dev_info(rdev->dev, "  SDMA0_STATUS_REG   = 0x%08X\n",
+		RREG32(SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET));
+	dev_info(rdev->dev, "  SDMA1_STATUS_REG   = 0x%08X\n",
+		 RREG32(SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET));
+	dev_info(rdev->dev, "  CP_STAT = 0x%08x\n", RREG32(CP_STAT));
+	dev_info(rdev->dev, "  CP_STALLED_STAT1 = 0x%08x\n",
+		 RREG32(CP_STALLED_STAT1));
+	dev_info(rdev->dev, "  CP_STALLED_STAT2 = 0x%08x\n",
+		 RREG32(CP_STALLED_STAT2));
+	dev_info(rdev->dev, "  CP_STALLED_STAT3 = 0x%08x\n",
+		 RREG32(CP_STALLED_STAT3));
+	dev_info(rdev->dev, "  CP_CPF_BUSY_STAT = 0x%08x\n",
+		 RREG32(CP_CPF_BUSY_STAT));
+	dev_info(rdev->dev, "  CP_CPF_STALLED_STAT1 = 0x%08x\n",
+		 RREG32(CP_CPF_STALLED_STAT1));
+	dev_info(rdev->dev, "  CP_CPF_STATUS = 0x%08x\n", RREG32(CP_CPF_STATUS));
+	dev_info(rdev->dev, "  CP_CPC_BUSY_STAT = 0x%08x\n", RREG32(CP_CPC_BUSY_STAT));
+	dev_info(rdev->dev, "  CP_CPC_STALLED_STAT1 = 0x%08x\n",
+		 RREG32(CP_CPC_STALLED_STAT1));
+	dev_info(rdev->dev, "  CP_CPC_STATUS = 0x%08x\n", RREG32(CP_CPC_STATUS));
+}
+
+/**
+ * cik_gpu_check_soft_reset - check which blocks are busy
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Check which blocks are busy and return the relevant reset
+ * mask to be used by cik_gpu_soft_reset().
+ * Returns a mask of the blocks to be reset.
+ */
+static u32 cik_gpu_check_soft_reset(struct radeon_device *rdev)
+{
+	u32 reset_mask = 0;
+	u32 tmp;
+
+	/* GRBM_STATUS */
+	tmp = RREG32(GRBM_STATUS);
+	if (tmp & (PA_BUSY | SC_BUSY |
+		   BCI_BUSY | SX_BUSY |
+		   TA_BUSY | VGT_BUSY |
+		   DB_BUSY | CB_BUSY |
+		   GDS_BUSY | SPI_BUSY |
+		   IA_BUSY | IA_BUSY_NO_DMA))
+		reset_mask |= RADEON_RESET_GFX;
+
+	if (tmp & (CP_BUSY | CP_COHERENCY_BUSY))
+		reset_mask |= RADEON_RESET_CP;
+
+	/* GRBM_STATUS2 */
+	tmp = RREG32(GRBM_STATUS2);
+	if (tmp & RLC_BUSY)
+		reset_mask |= RADEON_RESET_RLC;
+
+	/* SDMA0_STATUS_REG */
+	tmp = RREG32(SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET);
+	if (!(tmp & SDMA_IDLE))
+		reset_mask |= RADEON_RESET_DMA;
+
+	/* SDMA1_STATUS_REG */
+	tmp = RREG32(SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET);
+	if (!(tmp & SDMA_IDLE))
+		reset_mask |= RADEON_RESET_DMA1;
+
+	/* SRBM_STATUS2 */
+	tmp = RREG32(SRBM_STATUS2);
+	if (tmp & SDMA_BUSY)
+		reset_mask |= RADEON_RESET_DMA;
+
+	if (tmp & SDMA1_BUSY)
+		reset_mask |= RADEON_RESET_DMA1;
+
+	/* SRBM_STATUS */
+	tmp = RREG32(SRBM_STATUS);
+
+	if (tmp & IH_BUSY)
+		reset_mask |= RADEON_RESET_IH;
+
+	if (tmp & SEM_BUSY)
+		reset_mask |= RADEON_RESET_SEM;
+
+	if (tmp & GRBM_RQ_PENDING)
+		reset_mask |= RADEON_RESET_GRBM;
+
+	if (tmp & VMC_BUSY)
+		reset_mask |= RADEON_RESET_VMC;
+
+	if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
+		   MCC_BUSY | MCD_BUSY))
+		reset_mask |= RADEON_RESET_MC;
+
+	if (evergreen_is_display_hung(rdev))
+		reset_mask |= RADEON_RESET_DISPLAY;
+
+	/* Skip MC reset as it's mostly likely not hung, just busy */
+	if (reset_mask & RADEON_RESET_MC) {
+		DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
+		reset_mask &= ~RADEON_RESET_MC;
+	}
+
+	return reset_mask;
+}
+
+/**
+ * cik_gpu_soft_reset - soft reset GPU
+ *
+ * @rdev: radeon_device pointer
+ * @reset_mask: mask of which blocks to reset
+ *
+ * Soft reset the blocks specified in @reset_mask.
+ */
+static void cik_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
+{
+	struct evergreen_mc_save save;
+	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
+	u32 tmp;
+
+	if (reset_mask == 0)
+		return;
+
+	dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
+
+	cik_print_gpu_status_regs(rdev);
+	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
+		 RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
+	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
+		 RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+
+	/* stop the rlc */
+	cik_rlc_stop(rdev);
+
+	/* Disable GFX parsing/prefetching */
+	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
+
+	/* Disable MEC parsing/prefetching */
+	WREG32(CP_MEC_CNTL, MEC_ME1_HALT | MEC_ME2_HALT);
+
+	if (reset_mask & RADEON_RESET_DMA) {
+		/* sdma0 */
+		tmp = RREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET);
+		tmp |= SDMA_HALT;
+		WREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET, tmp);
+	}
+	if (reset_mask & RADEON_RESET_DMA1) {
+		/* sdma1 */
+		tmp = RREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET);
+		tmp |= SDMA_HALT;
+		WREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET, tmp);
+	}
+
+	evergreen_mc_stop(rdev, &save);
+	if (evergreen_mc_wait_for_idle(rdev)) {
+		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+	}
+
+	if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP))
+		grbm_soft_reset = SOFT_RESET_CP | SOFT_RESET_GFX;
+
+	if (reset_mask & RADEON_RESET_CP) {
+		grbm_soft_reset |= SOFT_RESET_CP;
+
+		srbm_soft_reset |= SOFT_RESET_GRBM;
+	}
+
+	if (reset_mask & RADEON_RESET_DMA)
+		srbm_soft_reset |= SOFT_RESET_SDMA;
+
+	if (reset_mask & RADEON_RESET_DMA1)
+		srbm_soft_reset |= SOFT_RESET_SDMA1;
+
+	if (reset_mask & RADEON_RESET_DISPLAY)
+		srbm_soft_reset |= SOFT_RESET_DC;
+
+	if (reset_mask & RADEON_RESET_RLC)
+		grbm_soft_reset |= SOFT_RESET_RLC;
+
+	if (reset_mask & RADEON_RESET_SEM)
+		srbm_soft_reset |= SOFT_RESET_SEM;
+
+	if (reset_mask & RADEON_RESET_IH)
+		srbm_soft_reset |= SOFT_RESET_IH;
+
+	if (reset_mask & RADEON_RESET_GRBM)
+		srbm_soft_reset |= SOFT_RESET_GRBM;
+
+	if (reset_mask & RADEON_RESET_VMC)
+		srbm_soft_reset |= SOFT_RESET_VMC;
+
+	if (!(rdev->flags & RADEON_IS_IGP)) {
+		if (reset_mask & RADEON_RESET_MC)
+			srbm_soft_reset |= SOFT_RESET_MC;
+	}
+
+	if (grbm_soft_reset) {
+		tmp = RREG32(GRBM_SOFT_RESET);
+		tmp |= grbm_soft_reset;
+		dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
+		WREG32(GRBM_SOFT_RESET, tmp);
+		tmp = RREG32(GRBM_SOFT_RESET);
+
+		udelay(50);
+
+		tmp &= ~grbm_soft_reset;
+		WREG32(GRBM_SOFT_RESET, tmp);
+		tmp = RREG32(GRBM_SOFT_RESET);
+	}
+
+	if (srbm_soft_reset) {
+		tmp = RREG32(SRBM_SOFT_RESET);
+		tmp |= srbm_soft_reset;
+		dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
+		WREG32(SRBM_SOFT_RESET, tmp);
+		tmp = RREG32(SRBM_SOFT_RESET);
+
+		udelay(50);
+
+		tmp &= ~srbm_soft_reset;
+		WREG32(SRBM_SOFT_RESET, tmp);
+		tmp = RREG32(SRBM_SOFT_RESET);
+	}
+
+	/* Wait a little for things to settle down */
+	udelay(50);
+
+	evergreen_mc_resume(rdev, &save);
+	udelay(50);
+
+	cik_print_gpu_status_regs(rdev);
+}
+
+/**
+ * cik_asic_reset - soft reset GPU
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Look up which blocks are hung and attempt
+ * to reset them.
+ * Returns 0 for success.
+ */
+int cik_asic_reset(struct radeon_device *rdev)
+{
+	u32 reset_mask;
+
+	reset_mask = cik_gpu_check_soft_reset(rdev);
+
+	if (reset_mask)
+		r600_set_bios_scratch_engine_hung(rdev, true);
+
+	cik_gpu_soft_reset(rdev, reset_mask);
+
+	reset_mask = cik_gpu_check_soft_reset(rdev);
+
+	if (!reset_mask)
+		r600_set_bios_scratch_engine_hung(rdev, false);
+
+	return 0;
+}
+
+/**
+ * cik_gfx_is_lockup - check if the 3D engine is locked up
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Check if the 3D engine is locked up (CIK).
+ * Returns true if the engine is locked, false if not.
+ */
+bool cik_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+	u32 reset_mask = cik_gpu_check_soft_reset(rdev);
+
+	if (!(reset_mask & (RADEON_RESET_GFX |
+			    RADEON_RESET_COMPUTE |
+			    RADEON_RESET_CP))) {
+		radeon_ring_lockup_update(ring);
+		return false;
+	}
+	/* force CP activities */
+	radeon_ring_force_activity(rdev, ring);
+	return radeon_ring_test_lockup(rdev, ring);
+}
+
+/**
+ * cik_sdma_is_lockup - Check if the DMA engine is locked up
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon_ring structure holding ring information
+ *
+ * Check if the async DMA engine is locked up (CIK).
+ * Returns true if the engine appears to be locked up, false if not.
+ */
+bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
+{
+	u32 reset_mask = cik_gpu_check_soft_reset(rdev);
+	u32 mask;
+
+	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+		mask = RADEON_RESET_DMA;
+	else
+		mask = RADEON_RESET_DMA1;
+
+	if (!(reset_mask & mask)) {
+		radeon_ring_lockup_update(ring);
+		return false;
+	}
+	/* force ring activities */
+	radeon_ring_force_activity(rdev, ring);
+	return radeon_ring_test_lockup(rdev, ring);
+}
+
+/* MC */
+/**
+ * cik_mc_program - program the GPU memory controller
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Set the location of vram, gart, and AGP in the GPU's
+ * physical address space (CIK).
+ */
+static void cik_mc_program(struct radeon_device *rdev)
+{
+	struct evergreen_mc_save save;
+	u32 tmp;
+	int i, j;
+
+	/* Initialize HDP */
+	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
+		WREG32((0x2c14 + j), 0x00000000);
+		WREG32((0x2c18 + j), 0x00000000);
+		WREG32((0x2c1c + j), 0x00000000);
+		WREG32((0x2c20 + j), 0x00000000);
+		WREG32((0x2c24 + j), 0x00000000);
+	}
+	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
+
+	evergreen_mc_stop(rdev, &save);
+	if (radeon_mc_wait_for_idle(rdev)) {
+		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+	}
+	/* Lockout access through VGA aperture*/
+	WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
+	/* Update configuration */
+	WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+	       rdev->mc.vram_start >> 12);
+	WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+	       rdev->mc.vram_end >> 12);
+	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
+	       rdev->vram_scratch.gpu_addr >> 12);
+	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
+	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
+	WREG32(MC_VM_FB_LOCATION, tmp);
+	/* XXX double check these! */
+	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
+	WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
+	WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
+	WREG32(MC_VM_AGP_BASE, 0);
+	WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
+	WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
+	if (radeon_mc_wait_for_idle(rdev)) {
+		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+	}
+	evergreen_mc_resume(rdev, &save);
+	/* we need to own VRAM, so turn off the VGA renderer here
+	 * to stop it overwriting our objects */
+	rv515_vga_render_disable(rdev);
+}
+
+/**
+ * cik_mc_init - initialize the memory controller driver params
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Look up the amount of vram, vram width, and decide how to place
+ * vram and gart within the GPU's physical address space (CIK).
+ * Returns 0 for success.
+ */
+static int cik_mc_init(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int chansize, numchan;
+
+	/* Get VRAM informations */
+	rdev->mc.vram_is_ddr = true;
+	tmp = RREG32(MC_ARB_RAMCFG);
+	if (tmp & CHANSIZE_MASK) {
+		chansize = 64;
+	} else {
+		chansize = 32;
+	}
+	tmp = RREG32(MC_SHARED_CHMAP);
+	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
+	case 0:
+	default:
+		numchan = 1;
+		break;
+	case 1:
+		numchan = 2;
+		break;
+	case 2:
+		numchan = 4;
+		break;
+	case 3:
+		numchan = 8;
+		break;
+	case 4:
+		numchan = 3;
+		break;
+	case 5:
+		numchan = 6;
+		break;
+	case 6:
+		numchan = 10;
+		break;
+	case 7:
+		numchan = 12;
+		break;
+	case 8:
+		numchan = 16;
+		break;
+	}
+	rdev->mc.vram_width = numchan * chansize;
+	/* Could aper size report 0 ? */
+	rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
+	rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
+	/* size in MB on si */
+	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
+	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
+	rdev->mc.visible_vram_size = rdev->mc.aper_size;
+	si_vram_gtt_location(rdev, &rdev->mc);
+	radeon_update_bandwidth_info(rdev);
+
+	return 0;
+}
+
+/*
+ * GART
+ * VMID 0 is the physical GPU addresses as used by the kernel.
+ * VMIDs 1-15 are used for userspace clients and are handled
+ * by the radeon vm/hsa code.
+ */
+/**
+ * cik_pcie_gart_tlb_flush - gart tlb flush callback
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Flush the TLB for the VMID 0 page table (CIK).
+ */
+void cik_pcie_gart_tlb_flush(struct radeon_device *rdev)
+{
+	/* flush hdp cache */
+	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0);
+
+	/* bits 0-15 are the VM contexts0-15 */
+	WREG32(VM_INVALIDATE_REQUEST, 0x1);
+}
+
+/**
+ * cik_pcie_gart_enable - gart enable
+ *
+ * @rdev: radeon_device pointer
+ *
+ * This sets up the TLBs, programs the page tables for VMID0,
+ * sets up the hw for VMIDs 1-15 which are allocated on
+ * demand, and sets up the global locations for the LDS, GDS,
+ * and GPUVM for FSA64 clients (CIK).
+ * Returns 0 for success, errors for failure.
+ */
+static int cik_pcie_gart_enable(struct radeon_device *rdev)
+{
+	int r, i;
+
+	if (rdev->gart.robj == NULL) {
+		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
+		return -EINVAL;
+	}
+	r = radeon_gart_table_vram_pin(rdev);
+	if (r)
+		return r;
+	radeon_gart_restore(rdev);
+	/* Setup TLB control */
+	WREG32(MC_VM_MX_L1_TLB_CNTL,
+	       (0xA << 7) |
+	       ENABLE_L1_TLB |
+	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+	       ENABLE_ADVANCED_DRIVER_MODEL |
+	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
+	/* Setup L2 cache */
+	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
+	       ENABLE_L2_FRAGMENT_PROCESSING |
+	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
+	       EFFECTIVE_L2_QUEUE_SIZE(7) |
+	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
+	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
+	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
+	       L2_CACHE_BIGK_FRAGMENT_SIZE(6));
+	/* setup context0 */
+	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
+	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
+			(u32)(rdev->dummy_page.addr >> 12));
+	WREG32(VM_CONTEXT0_CNTL2, 0);
+	WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
+				  RANGE_PROTECTION_FAULT_ENABLE_DEFAULT));
+
+	WREG32(0x15D4, 0);
+	WREG32(0x15D8, 0);
+	WREG32(0x15DC, 0);
+
+	/* empty context1-15 */
+	/* FIXME start with 4G, once using 2 level pt switch to full
+	 * vm size space
+	 */
+	/* set vm size, must be a multiple of 4 */
+	WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
+	WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
+	for (i = 1; i < 16; i++) {
+		if (i < 8)
+			WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
+			       rdev->gart.table_addr >> 12);
+		else
+			WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
+			       rdev->gart.table_addr >> 12);
+	}
+
+	/* enable context1-15 */
+	WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
+	       (u32)(rdev->dummy_page.addr >> 12));
+	WREG32(VM_CONTEXT1_CNTL2, 4);
+	WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
+				RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
+				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
+				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
+				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
+				PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
+				PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
+				VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
+				VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
+				READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
+				READ_PROTECTION_FAULT_ENABLE_DEFAULT |
+				WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
+				WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
+
+	/* TC cache setup ??? */
+	WREG32(TC_CFG_L1_LOAD_POLICY0, 0);
+	WREG32(TC_CFG_L1_LOAD_POLICY1, 0);
+	WREG32(TC_CFG_L1_STORE_POLICY, 0);
+
+	WREG32(TC_CFG_L2_LOAD_POLICY0, 0);
+	WREG32(TC_CFG_L2_LOAD_POLICY1, 0);
+	WREG32(TC_CFG_L2_STORE_POLICY0, 0);
+	WREG32(TC_CFG_L2_STORE_POLICY1, 0);
+	WREG32(TC_CFG_L2_ATOMIC_POLICY, 0);
+
+	WREG32(TC_CFG_L1_VOLATILE, 0);
+	WREG32(TC_CFG_L2_VOLATILE, 0);
+
+	if (rdev->family == CHIP_KAVERI) {
+		u32 tmp = RREG32(CHUB_CONTROL);
+		tmp &= ~BYPASS_VM;
+		WREG32(CHUB_CONTROL, tmp);
+	}
+
+	/* XXX SH_MEM regs */
+	/* where to put LDS, scratch, GPUVM in FSA64 space */
+	mutex_lock(&rdev->srbm_mutex);
+	for (i = 0; i < 16; i++) {
+		cik_srbm_select(rdev, 0, 0, 0, i);
+		/* CP and shaders */
+		WREG32(SH_MEM_CONFIG, 0);
+		WREG32(SH_MEM_APE1_BASE, 1);
+		WREG32(SH_MEM_APE1_LIMIT, 0);
+		WREG32(SH_MEM_BASES, 0);
+		/* SDMA GFX */
+		WREG32(SDMA0_GFX_VIRTUAL_ADDR + SDMA0_REGISTER_OFFSET, 0);
+		WREG32(SDMA0_GFX_APE1_CNTL + SDMA0_REGISTER_OFFSET, 0);
+		WREG32(SDMA0_GFX_VIRTUAL_ADDR + SDMA1_REGISTER_OFFSET, 0);
+		WREG32(SDMA0_GFX_APE1_CNTL + SDMA1_REGISTER_OFFSET, 0);
+		/* XXX SDMA RLC - todo */
+	}
+	cik_srbm_select(rdev, 0, 0, 0, 0);
+	mutex_unlock(&rdev->srbm_mutex);
+
+	cik_pcie_gart_tlb_flush(rdev);
+	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
+		 (unsigned)(rdev->mc.gtt_size >> 20),
+		 (unsigned long long)rdev->gart.table_addr);
+	rdev->gart.ready = true;
+	return 0;
+}
+
+/**
+ * cik_pcie_gart_disable - gart disable
+ *
+ * @rdev: radeon_device pointer
+ *
+ * This disables all VM page table (CIK).
+ */
+static void cik_pcie_gart_disable(struct radeon_device *rdev)
+{
+	/* Disable all tables */
+	WREG32(VM_CONTEXT0_CNTL, 0);
+	WREG32(VM_CONTEXT1_CNTL, 0);
+	/* Setup TLB control */
+	WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
+	/* Setup L2 cache */
+	WREG32(VM_L2_CNTL,
+	       ENABLE_L2_FRAGMENT_PROCESSING |
+	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
+	       EFFECTIVE_L2_QUEUE_SIZE(7) |
+	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
+	WREG32(VM_L2_CNTL2, 0);
+	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
+	       L2_CACHE_BIGK_FRAGMENT_SIZE(6));
+	radeon_gart_table_vram_unpin(rdev);
+}
+
+/**
+ * cik_pcie_gart_fini - vm fini callback
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tears down the driver GART/VM setup (CIK).
+ */
+static void cik_pcie_gart_fini(struct radeon_device *rdev)
+{
+	cik_pcie_gart_disable(rdev);
+	radeon_gart_table_vram_free(rdev);
+	radeon_gart_fini(rdev);
+}
+
+/* vm parser */
+/**
+ * cik_ib_parse - vm ib_parse callback
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer pointer
+ *
+ * CIK uses hw IB checking so this is a nop (CIK).
+ */
+int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+	return 0;
+}
+
+/*
+ * vm
+ * VMID 0 is the physical GPU addresses as used by the kernel.
+ * VMIDs 1-15 are used for userspace clients and are handled
+ * by the radeon vm/hsa code.
+ */
+/**
+ * cik_vm_init - cik vm init callback
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Inits cik specific vm parameters (number of VMs, base of vram for
+ * VMIDs 1-15) (CIK).
+ * Returns 0 for success.
+ */
+int cik_vm_init(struct radeon_device *rdev)
+{
+	/* number of VMs */
+	rdev->vm_manager.nvm = 16;
+	/* base offset of vram pages */
+	if (rdev->flags & RADEON_IS_IGP) {
+		u64 tmp = RREG32(MC_VM_FB_OFFSET);
+		tmp <<= 22;
+		rdev->vm_manager.vram_base_offset = tmp;
+	} else
+		rdev->vm_manager.vram_base_offset = 0;
+
+	return 0;
+}
+
+/**
+ * cik_vm_fini - cik vm fini callback
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down any asic specific VM setup (CIK).
+ */
+void cik_vm_fini(struct radeon_device *rdev)
+{
+}
+
+/**
+ * cik_vm_decode_fault - print human readable fault info
+ *
+ * @rdev: radeon_device pointer
+ * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
+ * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
+ *
+ * Print human readable fault information (CIK).
+ */
+static void cik_vm_decode_fault(struct radeon_device *rdev,
+				u32 status, u32 addr, u32 mc_client)
+{
+	u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
+	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
+	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
+	char *block = (char *)&mc_client;
+
+	printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
+	       protections, vmid, addr,
+	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
+	       block, mc_id);
+}
+
+/**
+ * cik_vm_flush - cik vm flush using the CP
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Update the page table base and flush the VM TLB
+ * using the CP (CIK).
+ */
+void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
+{
+	struct radeon_ring *ring = &rdev->ring[ridx];
+
+	if (vm == NULL)
+		return;
+
+	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+				 WRITE_DATA_DST_SEL(0)));
+	if (vm->id < 8) {
+		radeon_ring_write(ring,
+				  (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2);
+	} else {
+		radeon_ring_write(ring,
+				  (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2);
+	}
+	radeon_ring_write(ring, 0);
+	radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+
+	/* update SH_MEM_* regs */
+	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+				 WRITE_DATA_DST_SEL(0)));
+	radeon_ring_write(ring, SRBM_GFX_CNTL >> 2);
+	radeon_ring_write(ring, 0);
+	radeon_ring_write(ring, VMID(vm->id));
+
+	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 6));
+	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+				 WRITE_DATA_DST_SEL(0)));
+	radeon_ring_write(ring, SH_MEM_BASES >> 2);
+	radeon_ring_write(ring, 0);
+
+	radeon_ring_write(ring, 0); /* SH_MEM_BASES */
+	radeon_ring_write(ring, 0); /* SH_MEM_CONFIG */
+	radeon_ring_write(ring, 1); /* SH_MEM_APE1_BASE */
+	radeon_ring_write(ring, 0); /* SH_MEM_APE1_LIMIT */
+
+	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+				 WRITE_DATA_DST_SEL(0)));
+	radeon_ring_write(ring, SRBM_GFX_CNTL >> 2);
+	radeon_ring_write(ring, 0);
+	radeon_ring_write(ring, VMID(0));
+
+	/* HDP flush */
+	/* We should be using the WAIT_REG_MEM packet here like in
+	 * cik_fence_ring_emit(), but it causes the CP to hang in this
+	 * context...
+	 */
+	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+				 WRITE_DATA_DST_SEL(0)));
+	radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
+	radeon_ring_write(ring, 0);
+	radeon_ring_write(ring, 0);
+
+	/* bits 0-15 are the VM contexts0-15 */
+	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
+	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
+				 WRITE_DATA_DST_SEL(0)));
+	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
+	radeon_ring_write(ring, 0);
+	radeon_ring_write(ring, 1 << vm->id);
+
+	/* compute doesn't have PFP */
+	if (ridx == RADEON_RING_TYPE_GFX_INDEX) {
+		/* sync PFP to ME, otherwise we might get invalid PFP reads */
+		radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
+		radeon_ring_write(ring, 0x0);
+	}
+}
+
+/**
+ * cik_vm_set_page - update the page tables using sDMA
+ *
+ * @rdev: radeon_device pointer
+ * @ib: indirect buffer to fill with commands
+ * @pe: addr of the page entry
+ * @addr: dst addr to write into pe
+ * @count: number of page entries to update
+ * @incr: increase next addr by incr bytes
+ * @flags: access flags
+ *
+ * Update the page tables using CP or sDMA (CIK).
+ */
+void cik_vm_set_page(struct radeon_device *rdev,
+		     struct radeon_ib *ib,
+		     uint64_t pe,
+		     uint64_t addr, unsigned count,
+		     uint32_t incr, uint32_t flags)
+{
+	uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
+	uint64_t value;
+	unsigned ndw;
+
+	if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
+		/* CP */
+		while (count) {
+			ndw = 2 + count * 2;
+			if (ndw > 0x3FFE)
+				ndw = 0x3FFE;
+
+			ib->ptr[ib->length_dw++] = PACKET3(PACKET3_WRITE_DATA, ndw);
+			ib->ptr[ib->length_dw++] = (WRITE_DATA_ENGINE_SEL(0) |
+						    WRITE_DATA_DST_SEL(1));
+			ib->ptr[ib->length_dw++] = pe;
+			ib->ptr[ib->length_dw++] = upper_32_bits(pe);
+			for (; ndw > 2; ndw -= 2, --count, pe += 8) {
+				if (flags & RADEON_VM_PAGE_SYSTEM) {
+					value = radeon_vm_map_gart(rdev, addr);
+					value &= 0xFFFFFFFFFFFFF000ULL;
+				} else if (flags & RADEON_VM_PAGE_VALID) {
+					value = addr;
+				} else {
+					value = 0;
+				}
+				addr += incr;
+				value |= r600_flags;
+				ib->ptr[ib->length_dw++] = value;
+				ib->ptr[ib->length_dw++] = upper_32_bits(value);
+			}
+		}
+	} else {
+		/* DMA */
+		if (flags & RADEON_VM_PAGE_SYSTEM) {
+			while (count) {
+				ndw = count * 2;
+				if (ndw > 0xFFFFE)
+					ndw = 0xFFFFE;
+
+				/* for non-physically contiguous pages (system) */
+				ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0);
+				ib->ptr[ib->length_dw++] = pe;
+				ib->ptr[ib->length_dw++] = upper_32_bits(pe);
+				ib->ptr[ib->length_dw++] = ndw;
+				for (; ndw > 0; ndw -= 2, --count, pe += 8) {
+					if (flags & RADEON_VM_PAGE_SYSTEM) {
+						value = radeon_vm_map_gart(rdev, addr);
+						value &= 0xFFFFFFFFFFFFF000ULL;
+					} else if (flags & RADEON_VM_PAGE_VALID) {
+						value = addr;
+					} else {
+						value = 0;
+					}
+					addr += incr;
+					value |= r600_flags;
+					ib->ptr[ib->length_dw++] = value;
+					ib->ptr[ib->length_dw++] = upper_32_bits(value);
+				}
+			}
+		} else {
+			while (count) {
+				ndw = count;
+				if (ndw > 0x7FFFF)
+					ndw = 0x7FFFF;
+
+				if (flags & RADEON_VM_PAGE_VALID)
+					value = addr;
+				else
+					value = 0;
+				/* for physically contiguous pages (vram) */
+				ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_GENERATE_PTE_PDE, 0, 0);
+				ib->ptr[ib->length_dw++] = pe; /* dst addr */
+				ib->ptr[ib->length_dw++] = upper_32_bits(pe);
+				ib->ptr[ib->length_dw++] = r600_flags; /* mask */
+				ib->ptr[ib->length_dw++] = 0;
+				ib->ptr[ib->length_dw++] = value; /* value */
+				ib->ptr[ib->length_dw++] = upper_32_bits(value);
+				ib->ptr[ib->length_dw++] = incr; /* increment size */
+				ib->ptr[ib->length_dw++] = 0;
+				ib->ptr[ib->length_dw++] = ndw; /* number of entries */
+				pe += ndw * 8;
+				addr += ndw * incr;
+				count -= ndw;
+			}
+		}
+		while (ib->length_dw & 0x7)
+			ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0);
+	}
+}
+
+/**
+ * cik_dma_vm_flush - cik vm flush using sDMA
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Update the page table base and flush the VM TLB
+ * using sDMA (CIK).
+ */
+void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
+{
+	struct radeon_ring *ring = &rdev->ring[ridx];
+	u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) |
+			  SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */
+	u32 ref_and_mask;
+
+	if (vm == NULL)
+		return;
+
+	if (ridx == R600_RING_TYPE_DMA_INDEX)
+		ref_and_mask = SDMA0;
+	else
+		ref_and_mask = SDMA1;
+
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
+	if (vm->id < 8) {
+		radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2);
+	} else {
+		radeon_ring_write(ring, (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2);
+	}
+	radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
+
+	/* update SH_MEM_* regs */
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
+	radeon_ring_write(ring, SRBM_GFX_CNTL >> 2);
+	radeon_ring_write(ring, VMID(vm->id));
+
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
+	radeon_ring_write(ring, SH_MEM_BASES >> 2);
+	radeon_ring_write(ring, 0);
+
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
+	radeon_ring_write(ring, SH_MEM_CONFIG >> 2);
+	radeon_ring_write(ring, 0);
+
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
+	radeon_ring_write(ring, SH_MEM_APE1_BASE >> 2);
+	radeon_ring_write(ring, 1);
+
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
+	radeon_ring_write(ring, SH_MEM_APE1_LIMIT >> 2);
+	radeon_ring_write(ring, 0);
+
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
+	radeon_ring_write(ring, SRBM_GFX_CNTL >> 2);
+	radeon_ring_write(ring, VMID(0));
+
+	/* flush HDP */
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits));
+	radeon_ring_write(ring, GPU_HDP_FLUSH_DONE);
+	radeon_ring_write(ring, GPU_HDP_FLUSH_REQ);
+	radeon_ring_write(ring, ref_and_mask); /* REFERENCE */
+	radeon_ring_write(ring, ref_and_mask); /* MASK */
+	radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */
+
+	/* flush TLB */
+	radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
+	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
+	radeon_ring_write(ring, 1 << vm->id);
+}
+
+/*
+ * RLC
+ * The RLC is a multi-purpose microengine that handles a
+ * variety of functions, the most important of which is
+ * the interrupt controller.
+ */
+/**
+ * cik_rlc_stop - stop the RLC ME
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Halt the RLC ME (MicroEngine) (CIK).
+ */
+static void cik_rlc_stop(struct radeon_device *rdev)
+{
+	int i, j, k;
+	u32 mask, tmp;
+
+	tmp = RREG32(CP_INT_CNTL_RING0);
+	tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
+	WREG32(CP_INT_CNTL_RING0, tmp);
+
+	RREG32(CB_CGTT_SCLK_CTRL);
+	RREG32(CB_CGTT_SCLK_CTRL);
+	RREG32(CB_CGTT_SCLK_CTRL);
+	RREG32(CB_CGTT_SCLK_CTRL);
+
+	tmp = RREG32(RLC_CGCG_CGLS_CTRL) & 0xfffffffc;
+	WREG32(RLC_CGCG_CGLS_CTRL, tmp);
+
+	WREG32(RLC_CNTL, 0);
+
+	for (i = 0; i < rdev->config.cik.max_shader_engines; i++) {
+		for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) {
+			cik_select_se_sh(rdev, i, j);
+			for (k = 0; k < rdev->usec_timeout; k++) {
+				if (RREG32(RLC_SERDES_CU_MASTER_BUSY) == 0)
+					break;
+				udelay(1);
+			}
+		}
+	}
+	cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
+
+	mask = SE_MASTER_BUSY_MASK | GC_MASTER_BUSY | TC0_MASTER_BUSY | TC1_MASTER_BUSY;
+	for (k = 0; k < rdev->usec_timeout; k++) {
+		if ((RREG32(RLC_SERDES_NONCU_MASTER_BUSY) & mask) == 0)
+			break;
+		udelay(1);
+	}
+}
+
+/**
+ * cik_rlc_start - start the RLC ME
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Unhalt the RLC ME (MicroEngine) (CIK).
+ */
+static void cik_rlc_start(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	WREG32(RLC_CNTL, RLC_ENABLE);
+
+	tmp = RREG32(CP_INT_CNTL_RING0);
+	tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
+	WREG32(CP_INT_CNTL_RING0, tmp);
+
+	udelay(50);
+}
+
+/**
+ * cik_rlc_resume - setup the RLC hw
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Initialize the RLC registers, load the ucode,
+ * and start the RLC (CIK).
+ * Returns 0 for success, -EINVAL if the ucode is not available.
+ */
+static int cik_rlc_resume(struct radeon_device *rdev)
+{
+	u32 i, size;
+	u32 clear_state_info[3];
+	const __be32 *fw_data;
+
+	if (!rdev->rlc_fw)
+		return -EINVAL;
+
+	switch (rdev->family) {
+	case CHIP_BONAIRE:
+	default:
+		size = BONAIRE_RLC_UCODE_SIZE;
+		break;
+	case CHIP_KAVERI:
+		size = KV_RLC_UCODE_SIZE;
+		break;
+	case CHIP_KABINI:
+		size = KB_RLC_UCODE_SIZE;
+		break;
+	}
+
+	cik_rlc_stop(rdev);
+
+	WREG32(GRBM_SOFT_RESET, SOFT_RESET_RLC);
+	RREG32(GRBM_SOFT_RESET);
+	udelay(50);
+	WREG32(GRBM_SOFT_RESET, 0);
+	RREG32(GRBM_SOFT_RESET);
+	udelay(50);
+
+	WREG32(RLC_LB_CNTR_INIT, 0);
+	WREG32(RLC_LB_CNTR_MAX, 0x00008000);
+
+	cik_select_se_sh(rdev, 0xffffffff, 0xffffffff);
+	WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff);
+	WREG32(RLC_LB_PARAMS, 0x00600408);
+	WREG32(RLC_LB_CNTL, 0x80000004);
+
+	WREG32(RLC_MC_CNTL, 0);
+	WREG32(RLC_UCODE_CNTL, 0);
+
+	fw_data = (const __be32 *)rdev->rlc_fw->data;
+		WREG32(RLC_GPM_UCODE_ADDR, 0);
+	for (i = 0; i < size; i++)
+		WREG32(RLC_GPM_UCODE_DATA, be32_to_cpup(fw_data++));
+	WREG32(RLC_GPM_UCODE_ADDR, 0);
+
+	/* XXX */
+	clear_state_info[0] = 0;//upper_32_bits(rdev->rlc.save_restore_gpu_addr);
+	clear_state_info[1] = 0;//rdev->rlc.save_restore_gpu_addr;
+	clear_state_info[2] = 0;//cik_default_size;
+	WREG32(RLC_GPM_SCRATCH_ADDR, 0x3d);
+	for (i = 0; i < 3; i++)
+		WREG32(RLC_GPM_SCRATCH_DATA, clear_state_info[i]);
+	WREG32(RLC_DRIVER_DMA_STATUS, 0);
+
+	cik_rlc_start(rdev);
+
+	return 0;
+}
+
+/*
+ * Interrupts
+ * Starting with r6xx, interrupts are handled via a ring buffer.
+ * Ring buffers are areas of GPU accessible memory that the GPU
+ * writes interrupt vectors into and the host reads vectors out of.
+ * There is a rptr (read pointer) that determines where the
+ * host is currently reading, and a wptr (write pointer)
+ * which determines where the GPU has written.  When the
+ * pointers are equal, the ring is idle.  When the GPU
+ * writes vectors to the ring buffer, it increments the
+ * wptr.  When there is an interrupt, the host then starts
+ * fetching commands and processing them until the pointers are
+ * equal again at which point it updates the rptr.
+ */
+
+/**
+ * cik_enable_interrupts - Enable the interrupt ring buffer
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Enable the interrupt ring buffer (CIK).
+ */
+static void cik_enable_interrupts(struct radeon_device *rdev)
+{
+	u32 ih_cntl = RREG32(IH_CNTL);
+	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
+
+	ih_cntl |= ENABLE_INTR;
+	ih_rb_cntl |= IH_RB_ENABLE;
+	WREG32(IH_CNTL, ih_cntl);
+	WREG32(IH_RB_CNTL, ih_rb_cntl);
+	rdev->ih.enabled = true;
+}
+
+/**
+ * cik_disable_interrupts - Disable the interrupt ring buffer
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Disable the interrupt ring buffer (CIK).
+ */
+static void cik_disable_interrupts(struct radeon_device *rdev)
+{
+	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
+	u32 ih_cntl = RREG32(IH_CNTL);
+
+	ih_rb_cntl &= ~IH_RB_ENABLE;
+	ih_cntl &= ~ENABLE_INTR;
+	WREG32(IH_RB_CNTL, ih_rb_cntl);
+	WREG32(IH_CNTL, ih_cntl);
+	/* set rptr, wptr to 0 */
+	WREG32(IH_RB_RPTR, 0);
+	WREG32(IH_RB_WPTR, 0);
+	rdev->ih.enabled = false;
+	rdev->ih.rptr = 0;
+}
+
+/**
+ * cik_disable_interrupt_state - Disable all interrupt sources
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Clear all interrupt enable bits used by the driver (CIK).
+ */
+static void cik_disable_interrupt_state(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	/* gfx ring */
+	WREG32(CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
+	/* sdma */
+	tmp = RREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
+	WREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET, tmp);
+	tmp = RREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
+	WREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET, tmp);
+	/* compute queues */
+	WREG32(CP_ME1_PIPE0_INT_CNTL, 0);
+	WREG32(CP_ME1_PIPE1_INT_CNTL, 0);
+	WREG32(CP_ME1_PIPE2_INT_CNTL, 0);
+	WREG32(CP_ME1_PIPE3_INT_CNTL, 0);
+	WREG32(CP_ME2_PIPE0_INT_CNTL, 0);
+	WREG32(CP_ME2_PIPE1_INT_CNTL, 0);
+	WREG32(CP_ME2_PIPE2_INT_CNTL, 0);
+	WREG32(CP_ME2_PIPE3_INT_CNTL, 0);
+	/* grbm */
+	WREG32(GRBM_INT_CNTL, 0);
+	/* vline/vblank, etc. */
+	WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
+	WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+	if (rdev->num_crtc >= 4) {
+		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
+		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
+		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
+		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
+	}
+
+	/* dac hotplug */
+	WREG32(DAC_AUTODETECT_INT_CONTROL, 0);
+
+	/* digital hotplug */
+	tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+	WREG32(DC_HPD1_INT_CONTROL, tmp);
+	tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+	WREG32(DC_HPD2_INT_CONTROL, tmp);
+	tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+	WREG32(DC_HPD3_INT_CONTROL, tmp);
+	tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+	WREG32(DC_HPD4_INT_CONTROL, tmp);
+	tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+	WREG32(DC_HPD5_INT_CONTROL, tmp);
+	tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
+	WREG32(DC_HPD6_INT_CONTROL, tmp);
+
+}
+
+/**
+ * cik_irq_init - init and enable the interrupt ring
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Allocate a ring buffer for the interrupt controller,
+ * enable the RLC, disable interrupts, enable the IH
+ * ring buffer and enable it (CIK).
+ * Called at device load and reume.
+ * Returns 0 for success, errors for failure.
+ */
+static int cik_irq_init(struct radeon_device *rdev)
+{
+	int ret = 0;
+	int rb_bufsz;
+	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
+
+	/* allocate ring */
+	ret = r600_ih_ring_alloc(rdev);
+	if (ret)
+		return ret;
+
+	/* disable irqs */
+	cik_disable_interrupts(rdev);
+
+	/* init rlc */
+	ret = cik_rlc_resume(rdev);
+	if (ret) {
+		r600_ih_ring_fini(rdev);
+		return ret;
+	}
+
+	/* setup interrupt control */
+	/* XXX this should actually be a bus address, not an MC address. same on older asics */
+	WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8);
+	interrupt_cntl = RREG32(INTERRUPT_CNTL);
+	/* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
+	 * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
+	 */
+	interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
+	/* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
+	interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
+	WREG32(INTERRUPT_CNTL, interrupt_cntl);
+
+	WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
+	rb_bufsz = drm_order(rdev->ih.ring_size / 4);
+
+	ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
+		      IH_WPTR_OVERFLOW_CLEAR |
+		      (rb_bufsz << 1));
+
+	if (rdev->wb.enabled)
+		ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;
+
+	/* set the writeback address whether it's enabled or not */
+	WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC);
+	WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF);
+
+	WREG32(IH_RB_CNTL, ih_rb_cntl);
+
+	/* set rptr, wptr to 0 */
+	WREG32(IH_RB_RPTR, 0);
+	WREG32(IH_RB_WPTR, 0);
+
+	/* Default settings for IH_CNTL (disabled at first) */
+	ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0);
+	/* RPTR_REARM only works if msi's are enabled */
+	if (rdev->msi_enabled)
+		ih_cntl |= RPTR_REARM;
+	WREG32(IH_CNTL, ih_cntl);
+
+	/* force the active interrupt state to all disabled */
+	cik_disable_interrupt_state(rdev);
+
+	pci_set_master(rdev->pdev);
+
+	/* enable irqs */
+	cik_enable_interrupts(rdev);
+
+	return ret;
+}
+
+/**
+ * cik_irq_set - enable/disable interrupt sources
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Enable interrupt sources on the GPU (vblanks, hpd,
+ * etc.) (CIK).
+ * Returns 0 for success, errors for failure.
+ */
+int cik_irq_set(struct radeon_device *rdev)
+{
+	u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE |
+		PRIV_INSTR_INT_ENABLE | PRIV_REG_INT_ENABLE;
+	u32 cp_m1p0, cp_m1p1, cp_m1p2, cp_m1p3;
+	u32 cp_m2p0, cp_m2p1, cp_m2p2, cp_m2p3;
+	u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
+	u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
+	u32 grbm_int_cntl = 0;
+	u32 dma_cntl, dma_cntl1;
+
+	if (!rdev->irq.installed) {
+		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
+		return -EINVAL;
+	}
+	/* don't enable anything if the ih is disabled */
+	if (!rdev->ih.enabled) {
+		cik_disable_interrupts(rdev);
+		/* force the active interrupt state to all disabled */
+		cik_disable_interrupt_state(rdev);
+		return 0;
+	}
+
+	hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN;
+	hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN;
+	hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN;
+	hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
+	hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
+	hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
+
+	dma_cntl = RREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
+	dma_cntl1 = RREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
+
+	cp_m1p0 = RREG32(CP_ME1_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+	cp_m1p1 = RREG32(CP_ME1_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+	cp_m1p2 = RREG32(CP_ME1_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+	cp_m1p3 = RREG32(CP_ME1_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+	cp_m2p0 = RREG32(CP_ME2_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+	cp_m2p1 = RREG32(CP_ME2_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+	cp_m2p2 = RREG32(CP_ME2_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+	cp_m2p3 = RREG32(CP_ME2_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE;
+
+	/* enable CP interrupts on all rings */
+	if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
+		DRM_DEBUG("cik_irq_set: sw int gfx\n");
+		cp_int_cntl |= TIME_STAMP_INT_ENABLE;
+	}
+	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
+		struct radeon_ring *ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
+		DRM_DEBUG("si_irq_set: sw int cp1\n");
+		if (ring->me == 1) {
+			switch (ring->pipe) {
+			case 0:
+				cp_m1p0 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 1:
+				cp_m1p1 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 2:
+				cp_m1p2 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 3:
+				cp_m1p2 |= TIME_STAMP_INT_ENABLE;
+				break;
+			default:
+				DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe %d\n", ring->pipe);
+				break;
+			}
+		} else if (ring->me == 2) {
+			switch (ring->pipe) {
+			case 0:
+				cp_m2p0 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 1:
+				cp_m2p1 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 2:
+				cp_m2p2 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 3:
+				cp_m2p2 |= TIME_STAMP_INT_ENABLE;
+				break;
+			default:
+				DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe %d\n", ring->pipe);
+				break;
+			}
+		} else {
+			DRM_DEBUG("si_irq_set: sw int cp1 invalid me %d\n", ring->me);
+		}
+	}
+	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
+		struct radeon_ring *ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
+		DRM_DEBUG("si_irq_set: sw int cp2\n");
+		if (ring->me == 1) {
+			switch (ring->pipe) {
+			case 0:
+				cp_m1p0 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 1:
+				cp_m1p1 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 2:
+				cp_m1p2 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 3:
+				cp_m1p2 |= TIME_STAMP_INT_ENABLE;
+				break;
+			default:
+				DRM_DEBUG("si_irq_set: sw int cp2 invalid pipe %d\n", ring->pipe);
+				break;
+			}
+		} else if (ring->me == 2) {
+			switch (ring->pipe) {
+			case 0:
+				cp_m2p0 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 1:
+				cp_m2p1 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 2:
+				cp_m2p2 |= TIME_STAMP_INT_ENABLE;
+				break;
+			case 3:
+				cp_m2p2 |= TIME_STAMP_INT_ENABLE;
+				break;
+			default:
+				DRM_DEBUG("si_irq_set: sw int cp2 invalid pipe %d\n", ring->pipe);
+				break;
+			}
+		} else {
+			DRM_DEBUG("si_irq_set: sw int cp2 invalid me %d\n", ring->me);
+		}
+	}
+
+	if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
+		DRM_DEBUG("cik_irq_set: sw int dma\n");
+		dma_cntl |= TRAP_ENABLE;
+	}
+
+	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
+		DRM_DEBUG("cik_irq_set: sw int dma1\n");
+		dma_cntl1 |= TRAP_ENABLE;
+	}
+
+	if (rdev->irq.crtc_vblank_int[0] ||
+	    atomic_read(&rdev->irq.pflip[0])) {
+		DRM_DEBUG("cik_irq_set: vblank 0\n");
+		crtc1 |= VBLANK_INTERRUPT_MASK;
+	}
+	if (rdev->irq.crtc_vblank_int[1] ||
+	    atomic_read(&rdev->irq.pflip[1])) {
+		DRM_DEBUG("cik_irq_set: vblank 1\n");
+		crtc2 |= VBLANK_INTERRUPT_MASK;
+	}
+	if (rdev->irq.crtc_vblank_int[2] ||
+	    atomic_read(&rdev->irq.pflip[2])) {
+		DRM_DEBUG("cik_irq_set: vblank 2\n");
+		crtc3 |= VBLANK_INTERRUPT_MASK;
+	}
+	if (rdev->irq.crtc_vblank_int[3] ||
+	    atomic_read(&rdev->irq.pflip[3])) {
+		DRM_DEBUG("cik_irq_set: vblank 3\n");
+		crtc4 |= VBLANK_INTERRUPT_MASK;
+	}
+	if (rdev->irq.crtc_vblank_int[4] ||
+	    atomic_read(&rdev->irq.pflip[4])) {
+		DRM_DEBUG("cik_irq_set: vblank 4\n");
+		crtc5 |= VBLANK_INTERRUPT_MASK;
+	}
+	if (rdev->irq.crtc_vblank_int[5] ||
+	    atomic_read(&rdev->irq.pflip[5])) {
+		DRM_DEBUG("cik_irq_set: vblank 5\n");
+		crtc6 |= VBLANK_INTERRUPT_MASK;
+	}
+	if (rdev->irq.hpd[0]) {
+		DRM_DEBUG("cik_irq_set: hpd 1\n");
+		hpd1 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[1]) {
+		DRM_DEBUG("cik_irq_set: hpd 2\n");
+		hpd2 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[2]) {
+		DRM_DEBUG("cik_irq_set: hpd 3\n");
+		hpd3 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[3]) {
+		DRM_DEBUG("cik_irq_set: hpd 4\n");
+		hpd4 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[4]) {
+		DRM_DEBUG("cik_irq_set: hpd 5\n");
+		hpd5 |= DC_HPDx_INT_EN;
+	}
+	if (rdev->irq.hpd[5]) {
+		DRM_DEBUG("cik_irq_set: hpd 6\n");
+		hpd6 |= DC_HPDx_INT_EN;
+	}
+
+	WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
+
+	WREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET, dma_cntl);
+	WREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET, dma_cntl1);
+
+	WREG32(CP_ME1_PIPE0_INT_CNTL, cp_m1p0);
+	WREG32(CP_ME1_PIPE1_INT_CNTL, cp_m1p1);
+	WREG32(CP_ME1_PIPE2_INT_CNTL, cp_m1p2);
+	WREG32(CP_ME1_PIPE3_INT_CNTL, cp_m1p3);
+	WREG32(CP_ME2_PIPE0_INT_CNTL, cp_m2p0);
+	WREG32(CP_ME2_PIPE1_INT_CNTL, cp_m2p1);
+	WREG32(CP_ME2_PIPE2_INT_CNTL, cp_m2p2);
+	WREG32(CP_ME2_PIPE3_INT_CNTL, cp_m2p3);
+
+	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
+
+	WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
+	WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
+	if (rdev->num_crtc >= 4) {
+		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3);
+		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4);
+	}
+	if (rdev->num_crtc >= 6) {
+		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5);
+		WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
+	}
+
+	WREG32(DC_HPD1_INT_CONTROL, hpd1);
+	WREG32(DC_HPD2_INT_CONTROL, hpd2);
+	WREG32(DC_HPD3_INT_CONTROL, hpd3);
+	WREG32(DC_HPD4_INT_CONTROL, hpd4);
+	WREG32(DC_HPD5_INT_CONTROL, hpd5);
+	WREG32(DC_HPD6_INT_CONTROL, hpd6);
+
+	return 0;
+}
+
+/**
+ * cik_irq_ack - ack interrupt sources
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Ack interrupt sources on the GPU (vblanks, hpd,
+ * etc.) (CIK).  Certain interrupts sources are sw
+ * generated and do not require an explicit ack.
+ */
+static inline void cik_irq_ack(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	rdev->irq.stat_regs.cik.disp_int = RREG32(DISP_INTERRUPT_STATUS);
+	rdev->irq.stat_regs.cik.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
+	rdev->irq.stat_regs.cik.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2);
+	rdev->irq.stat_regs.cik.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3);
+	rdev->irq.stat_regs.cik.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4);
+	rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
+	rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6);
+
+	if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT)
+		WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
+	if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT)
+		WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK);
+	if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT)
+		WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK);
+	if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT)
+		WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
+
+	if (rdev->num_crtc >= 4) {
+		if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
+			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
+			WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
+		if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
+			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
+			WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
+	}
+
+	if (rdev->num_crtc >= 6) {
+		if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
+			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
+			WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
+		if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
+			WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
+			WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
+	}
+
+	if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) {
+		tmp = RREG32(DC_HPD1_INT_CONTROL);
+		tmp |= DC_HPDx_INT_ACK;
+		WREG32(DC_HPD1_INT_CONTROL, tmp);
+	}
+	if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) {
+		tmp = RREG32(DC_HPD2_INT_CONTROL);
+		tmp |= DC_HPDx_INT_ACK;
+		WREG32(DC_HPD2_INT_CONTROL, tmp);
+	}
+	if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) {
+		tmp = RREG32(DC_HPD3_INT_CONTROL);
+		tmp |= DC_HPDx_INT_ACK;
+		WREG32(DC_HPD3_INT_CONTROL, tmp);
+	}
+	if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) {
+		tmp = RREG32(DC_HPD4_INT_CONTROL);
+		tmp |= DC_HPDx_INT_ACK;
+		WREG32(DC_HPD4_INT_CONTROL, tmp);
+	}
+	if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) {
+		tmp = RREG32(DC_HPD5_INT_CONTROL);
+		tmp |= DC_HPDx_INT_ACK;
+		WREG32(DC_HPD5_INT_CONTROL, tmp);
+	}
+	if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) {
+		tmp = RREG32(DC_HPD5_INT_CONTROL);
+		tmp |= DC_HPDx_INT_ACK;
+		WREG32(DC_HPD6_INT_CONTROL, tmp);
+	}
+}
+
+/**
+ * cik_irq_disable - disable interrupts
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Disable interrupts on the hw (CIK).
+ */
+static void cik_irq_disable(struct radeon_device *rdev)
+{
+	cik_disable_interrupts(rdev);
+	/* Wait and acknowledge irq */
+	mdelay(1);
+	cik_irq_ack(rdev);
+	cik_disable_interrupt_state(rdev);
+}
+
+/**
+ * cik_irq_disable - disable interrupts for suspend
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Disable interrupts and stop the RLC (CIK).
+ * Used for suspend.
+ */
+static void cik_irq_suspend(struct radeon_device *rdev)
+{
+	cik_irq_disable(rdev);
+	cik_rlc_stop(rdev);
+}
+
+/**
+ * cik_irq_fini - tear down interrupt support
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Disable interrupts on the hw and free the IH ring
+ * buffer (CIK).
+ * Used for driver unload.
+ */
+static void cik_irq_fini(struct radeon_device *rdev)
+{
+	cik_irq_suspend(rdev);
+	r600_ih_ring_fini(rdev);
+}
+
+/**
+ * cik_get_ih_wptr - get the IH ring buffer wptr
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Get the IH ring buffer wptr from either the register
+ * or the writeback memory buffer (CIK).  Also check for
+ * ring buffer overflow and deal with it.
+ * Used by cik_irq_process().
+ * Returns the value of the wptr.
+ */
+static inline u32 cik_get_ih_wptr(struct radeon_device *rdev)
+{
+	u32 wptr, tmp;
+
+	if (rdev->wb.enabled)
+		wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
+	else
+		wptr = RREG32(IH_RB_WPTR);
+
+	if (wptr & RB_OVERFLOW) {
+		/* When a ring buffer overflow happen start parsing interrupt
+		 * from the last not overwritten vector (wptr + 16). Hopefully
+		 * this should allow us to catchup.
+		 */
+		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n",
+			wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask);
+		rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
+		tmp = RREG32(IH_RB_CNTL);
+		tmp |= IH_WPTR_OVERFLOW_CLEAR;
+		WREG32(IH_RB_CNTL, tmp);
+	}
+	return (wptr & rdev->ih.ptr_mask);
+}
+
+/*        CIK IV Ring
+ * Each IV ring entry is 128 bits:
+ * [7:0]    - interrupt source id
+ * [31:8]   - reserved
+ * [59:32]  - interrupt source data
+ * [63:60]  - reserved
+ * [71:64]  - RINGID
+ *            CP:
+ *            ME_ID [1:0], PIPE_ID[1:0], QUEUE_ID[2:0]
+ *            QUEUE_ID - for compute, which of the 8 queues owned by the dispatcher
+ *                     - for gfx, hw shader state (0=PS...5=LS, 6=CS)
+ *            ME_ID - 0 = gfx, 1 = first 4 CS pipes, 2 = second 4 CS pipes
+ *            PIPE_ID - ME0 0=3D
+ *                    - ME1&2 compute dispatcher (4 pipes each)
+ *            SDMA:
+ *            INSTANCE_ID [1:0], QUEUE_ID[1:0]
+ *            INSTANCE_ID - 0 = sdma0, 1 = sdma1
+ *            QUEUE_ID - 0 = gfx, 1 = rlc0, 2 = rlc1
+ * [79:72]  - VMID
+ * [95:80]  - PASID
+ * [127:96] - reserved
+ */
+/**
+ * cik_irq_process - interrupt handler
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Interrupt hander (CIK).  Walk the IH ring,
+ * ack interrupts and schedule work to handle
+ * interrupt events.
+ * Returns irq process return code.
+ */
+int cik_irq_process(struct radeon_device *rdev)
+{
+	struct radeon_ring *cp1_ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
+	struct radeon_ring *cp2_ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
+	u32 wptr;
+	u32 rptr;
+	u32 src_id, src_data, ring_id;
+	u8 me_id, pipe_id, queue_id;
+	u32 ring_index;
+	bool queue_hotplug = false;
+	bool queue_reset = false;
+	u32 addr, status, mc_client;
+
+	if (!rdev->ih.enabled || rdev->shutdown)
+		return IRQ_NONE;
+
+	wptr = cik_get_ih_wptr(rdev);
+
+restart_ih:
+	/* is somebody else already processing irqs? */
+	if (atomic_xchg(&rdev->ih.lock, 1))
+		return IRQ_NONE;
+
+	rptr = rdev->ih.rptr;
+	DRM_DEBUG("cik_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
+
+	/* Order reading of wptr vs. reading of IH ring data */
+	rmb();
+
+	/* display interrupts */
+	cik_irq_ack(rdev);
+
+	while (rptr != wptr) {
+		/* wptr/rptr are in bytes! */
+		ring_index = rptr / 4;
+		src_id =  le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
+		src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
+		ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff;
+
+		switch (src_id) {
+		case 1: /* D1 vblank/vline */
+			switch (src_data) {
+			case 0: /* D1 vblank */
+				if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) {
+					if (rdev->irq.crtc_vblank_int[0]) {
+						drm_handle_vblank(rdev->ddev, 0);
+						rdev->pm.vblank_sync = true;
+						wake_up(&rdev->irq.vblank_queue);
+					}
+					if (atomic_read(&rdev->irq.pflip[0]))
+						radeon_crtc_handle_flip(rdev, 0);
+					rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D1 vblank\n");
+				}
+				break;
+			case 1: /* D1 vline */
+				if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT;
+					DRM_DEBUG("IH: D1 vline\n");
+				}
+				break;
+			default:
+				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 2: /* D2 vblank/vline */
+			switch (src_data) {
+			case 0: /* D2 vblank */
+				if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
+					if (rdev->irq.crtc_vblank_int[1]) {
+						drm_handle_vblank(rdev->ddev, 1);
+						rdev->pm.vblank_sync = true;
+						wake_up(&rdev->irq.vblank_queue);
+					}
+					if (atomic_read(&rdev->irq.pflip[1]))
+						radeon_crtc_handle_flip(rdev, 1);
+					rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D2 vblank\n");
+				}
+				break;
+			case 1: /* D2 vline */
+				if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
+					DRM_DEBUG("IH: D2 vline\n");
+				}
+				break;
+			default:
+				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 3: /* D3 vblank/vline */
+			switch (src_data) {
+			case 0: /* D3 vblank */
+				if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
+					if (rdev->irq.crtc_vblank_int[2]) {
+						drm_handle_vblank(rdev->ddev, 2);
+						rdev->pm.vblank_sync = true;
+						wake_up(&rdev->irq.vblank_queue);
+					}
+					if (atomic_read(&rdev->irq.pflip[2]))
+						radeon_crtc_handle_flip(rdev, 2);
+					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D3 vblank\n");
+				}
+				break;
+			case 1: /* D3 vline */
+				if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
+					DRM_DEBUG("IH: D3 vline\n");
+				}
+				break;
+			default:
+				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 4: /* D4 vblank/vline */
+			switch (src_data) {
+			case 0: /* D4 vblank */
+				if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
+					if (rdev->irq.crtc_vblank_int[3]) {
+						drm_handle_vblank(rdev->ddev, 3);
+						rdev->pm.vblank_sync = true;
+						wake_up(&rdev->irq.vblank_queue);
+					}
+					if (atomic_read(&rdev->irq.pflip[3]))
+						radeon_crtc_handle_flip(rdev, 3);
+					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D4 vblank\n");
+				}
+				break;
+			case 1: /* D4 vline */
+				if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
+					DRM_DEBUG("IH: D4 vline\n");
+				}
+				break;
+			default:
+				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 5: /* D5 vblank/vline */
+			switch (src_data) {
+			case 0: /* D5 vblank */
+				if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
+					if (rdev->irq.crtc_vblank_int[4]) {
+						drm_handle_vblank(rdev->ddev, 4);
+						rdev->pm.vblank_sync = true;
+						wake_up(&rdev->irq.vblank_queue);
+					}
+					if (atomic_read(&rdev->irq.pflip[4]))
+						radeon_crtc_handle_flip(rdev, 4);
+					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D5 vblank\n");
+				}
+				break;
+			case 1: /* D5 vline */
+				if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
+					DRM_DEBUG("IH: D5 vline\n");
+				}
+				break;
+			default:
+				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 6: /* D6 vblank/vline */
+			switch (src_data) {
+			case 0: /* D6 vblank */
+				if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
+					if (rdev->irq.crtc_vblank_int[5]) {
+						drm_handle_vblank(rdev->ddev, 5);
+						rdev->pm.vblank_sync = true;
+						wake_up(&rdev->irq.vblank_queue);
+					}
+					if (atomic_read(&rdev->irq.pflip[5]))
+						radeon_crtc_handle_flip(rdev, 5);
+					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
+					DRM_DEBUG("IH: D6 vblank\n");
+				}
+				break;
+			case 1: /* D6 vline */
+				if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
+					DRM_DEBUG("IH: D6 vline\n");
+				}
+				break;
+			default:
+				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 42: /* HPD hotplug */
+			switch (src_data) {
+			case 0:
+				if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD1\n");
+				}
+				break;
+			case 1:
+				if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD2\n");
+				}
+				break;
+			case 2:
+				if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD3\n");
+				}
+				break;
+			case 3:
+				if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD4\n");
+				}
+				break;
+			case 4:
+				if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD5\n");
+				}
+				break;
+			case 5:
+				if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) {
+					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
+					queue_hotplug = true;
+					DRM_DEBUG("IH: HPD6\n");
+				}
+				break;
+			default:
+				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
+				break;
+			}
+			break;
+		case 146:
+		case 147:
+			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
+			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
+			mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT);
+			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
+			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
+				addr);
+			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
+				status);
+			cik_vm_decode_fault(rdev, status, addr, mc_client);
+			/* reset addr and status */
+			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
+			break;
+		case 176: /* GFX RB CP_INT */
+		case 177: /* GFX IB CP_INT */
+			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
+			break;
+		case 181: /* CP EOP event */
+			DRM_DEBUG("IH: CP EOP\n");
+			/* XXX check the bitfield order! */
+			me_id = (ring_id & 0x60) >> 5;
+			pipe_id = (ring_id & 0x18) >> 3;
+			queue_id = (ring_id & 0x7) >> 0;
+			switch (me_id) {
+			case 0:
+				radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
+				break;
+			case 1:
+			case 2:
+				if ((cp1_ring->me == me_id) & (cp1_ring->pipe == pipe_id))
+					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
+				if ((cp2_ring->me == me_id) & (cp2_ring->pipe == pipe_id))
+					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
+				break;
+			}
+			break;
+		case 184: /* CP Privileged reg access */
+			DRM_ERROR("Illegal register access in command stream\n");
+			/* XXX check the bitfield order! */
+			me_id = (ring_id & 0x60) >> 5;
+			pipe_id = (ring_id & 0x18) >> 3;
+			queue_id = (ring_id & 0x7) >> 0;
+			switch (me_id) {
+			case 0:
+				/* This results in a full GPU reset, but all we need to do is soft
+				 * reset the CP for gfx
+				 */
+				queue_reset = true;
+				break;
+			case 1:
+				/* XXX compute */
+				queue_reset = true;
+				break;
+			case 2:
+				/* XXX compute */
+				queue_reset = true;
+				break;
+			}
+			break;
+		case 185: /* CP Privileged inst */
+			DRM_ERROR("Illegal instruction in command stream\n");
+			/* XXX check the bitfield order! */
+			me_id = (ring_id & 0x60) >> 5;
+			pipe_id = (ring_id & 0x18) >> 3;
+			queue_id = (ring_id & 0x7) >> 0;
+			switch (me_id) {
+			case 0:
+				/* This results in a full GPU reset, but all we need to do is soft
+				 * reset the CP for gfx
+				 */
+				queue_reset = true;
+				break;
+			case 1:
+				/* XXX compute */
+				queue_reset = true;
+				break;
+			case 2:
+				/* XXX compute */
+				queue_reset = true;
+				break;
+			}
+			break;
+		case 224: /* SDMA trap event */
+			/* XXX check the bitfield order! */
+			me_id = (ring_id & 0x3) >> 0;
+			queue_id = (ring_id & 0xc) >> 2;
+			DRM_DEBUG("IH: SDMA trap\n");
+			switch (me_id) {
+			case 0:
+				switch (queue_id) {
+				case 0:
+					radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
+					break;
+				case 1:
+					/* XXX compute */
+					break;
+				case 2:
+					/* XXX compute */
+					break;
+				}
+				break;
+			case 1:
+				switch (queue_id) {
+				case 0:
+					radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
+					break;
+				case 1:
+					/* XXX compute */
+					break;
+				case 2:
+					/* XXX compute */
+					break;
+				}
+				break;
+			}
+			break;
+		case 241: /* SDMA Privileged inst */
+		case 247: /* SDMA Privileged inst */
+			DRM_ERROR("Illegal instruction in SDMA command stream\n");
+			/* XXX check the bitfield order! */
+			me_id = (ring_id & 0x3) >> 0;
+			queue_id = (ring_id & 0xc) >> 2;
+			switch (me_id) {
+			case 0:
+				switch (queue_id) {
+				case 0:
+					queue_reset = true;
+					break;
+				case 1:
+					/* XXX compute */
+					queue_reset = true;
+					break;
+				case 2:
+					/* XXX compute */
+					queue_reset = true;
+					break;
+				}
+				break;
+			case 1:
+				switch (queue_id) {
+				case 0:
+					queue_reset = true;
+					break;
+				case 1:
+					/* XXX compute */
+					queue_reset = true;
+					break;
+				case 2:
+					/* XXX compute */
+					queue_reset = true;
+					break;
+				}
+				break;
+			}
+			break;
+		case 233: /* GUI IDLE */
+			DRM_DEBUG("IH: GUI idle\n");
+			break;
+		default:
+			DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
+			break;
+		}
+
+		/* wptr/rptr are in bytes! */
+		rptr += 16;
+		rptr &= rdev->ih.ptr_mask;
+	}
+	if (queue_hotplug)
+		schedule_work(&rdev->hotplug_work);
+	if (queue_reset)
+		schedule_work(&rdev->reset_work);
+	rdev->ih.rptr = rptr;
+	WREG32(IH_RB_RPTR, rdev->ih.rptr);
+	atomic_set(&rdev->ih.lock, 0);
+
+	/* make sure wptr hasn't changed while processing */
+	wptr = cik_get_ih_wptr(rdev);
+	if (wptr != rptr)
+		goto restart_ih;
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * startup/shutdown callbacks
+ */
+/**
+ * cik_startup - program the asic to a functional state
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Programs the asic to a functional state (CIK).
+ * Called by cik_init() and cik_resume().
+ * Returns 0 for success, error for failure.
+ */
+static int cik_startup(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	cik_mc_program(rdev);
+
+	if (rdev->flags & RADEON_IS_IGP) {
+		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
+		    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
+			r = cik_init_microcode(rdev);
+			if (r) {
+				DRM_ERROR("Failed to load firmware!\n");
+				return r;
+			}
+		}
+	} else {
+		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
+		    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw ||
+		    !rdev->mc_fw) {
+			r = cik_init_microcode(rdev);
+			if (r) {
+				DRM_ERROR("Failed to load firmware!\n");
+				return r;
+			}
+		}
+
+		r = ci_mc_load_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load MC firmware!\n");
+			return r;
+		}
+	}
+
+	r = r600_vram_scratch_init(rdev);
+	if (r)
+		return r;
+
+	r = cik_pcie_gart_enable(rdev);
+	if (r)
+		return r;
+	cik_gpu_init(rdev);
+
+	/* allocate rlc buffers */
+	r = si_rlc_init(rdev);
+	if (r) {
+		DRM_ERROR("Failed to init rlc BOs!\n");
+		return r;
+	}
+
+	/* allocate wb buffer */
+	r = radeon_wb_init(rdev);
+	if (r)
+		return r;
+
+	/* allocate mec buffers */
+	r = cik_mec_init(rdev);
+	if (r) {
+		DRM_ERROR("Failed to init MEC BOs!\n");
+		return r;
+	}
+
+	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
+	if (r) {
+		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
+		return r;
+	}
+
+	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
+	if (r) {
+		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
+		return r;
+	}
+
+	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
+	if (r) {
+		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
+		return r;
+	}
+
+	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
+	if (r) {
+		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
+		return r;
+	}
+
+	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
+	if (r) {
+		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
+		return r;
+	}
+
+	r = cik_uvd_resume(rdev);
+	if (!r) {
+		r = radeon_fence_driver_start_ring(rdev,
+						   R600_RING_TYPE_UVD_INDEX);
+		if (r)
+			dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
+	}
+	if (r)
+		rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
+
+	/* Enable IRQ */
+	if (!rdev->irq.installed) {
+		r = radeon_irq_kms_init(rdev);
+		if (r)
+			return r;
+	}
+
+	r = cik_irq_init(rdev);
+	if (r) {
+		DRM_ERROR("radeon: IH init failed (%d).\n", r);
+		radeon_irq_kms_fini(rdev);
+		return r;
+	}
+	cik_irq_set(rdev);
+
+	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
+			     CP_RB0_RPTR, CP_RB0_WPTR,
+			     0, 0xfffff, RADEON_CP_PACKET2);
+	if (r)
+		return r;
+
+	/* set up the compute queues */
+	/* type-2 packets are deprecated on MEC, use type-3 instead */
+	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
+			     CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
+			     0, 0xfffff, PACKET3(PACKET3_NOP, 0x3FFF));
+	if (r)
+		return r;
+	ring->me = 1; /* first MEC */
+	ring->pipe = 0; /* first pipe */
+	ring->queue = 0; /* first queue */
+	ring->wptr_offs = CIK_WB_CP1_WPTR_OFFSET;
+
+	/* type-2 packets are deprecated on MEC, use type-3 instead */
+	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
+			     CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
+			     0, 0xffffffff, PACKET3(PACKET3_NOP, 0x3FFF));
+	if (r)
+		return r;
+	/* dGPU only have 1 MEC */
+	ring->me = 1; /* first MEC */
+	ring->pipe = 0; /* first pipe */
+	ring->queue = 1; /* second queue */
+	ring->wptr_offs = CIK_WB_CP2_WPTR_OFFSET;
+
+	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
+			     SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET,
+			     SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET,
+			     2, 0xfffffffc, SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
+	if (r)
+		return r;
+
+	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
+	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
+			     SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET,
+			     SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET,
+			     2, 0xfffffffc, SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
+	if (r)
+		return r;
+
+	r = cik_cp_resume(rdev);
+	if (r)
+		return r;
+
+	r = cik_sdma_resume(rdev);
+	if (r)
+		return r;
+
+	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+	if (ring->ring_size) {
+		r = radeon_ring_init(rdev, ring, ring->ring_size,
+				     R600_WB_UVD_RPTR_OFFSET,
+				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
+				     0, 0xfffff, RADEON_CP_PACKET2);
+		if (!r)
+			r = r600_uvd_init(rdev);
+		if (r)
+			DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
+	}
+
+	r = radeon_ib_pool_init(rdev);
+	if (r) {
+		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
+		return r;
+	}
+
+	r = radeon_vm_manager_init(rdev);
+	if (r) {
+		dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
+		return r;
+	}
+
+	return 0;
+}
+
+/**
+ * cik_resume - resume the asic to a functional state
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Programs the asic to a functional state (CIK).
+ * Called at resume.
+ * Returns 0 for success, error for failure.
+ */
+int cik_resume(struct radeon_device *rdev)
+{
+	int r;
+
+	/* post card */
+	atom_asic_init(rdev->mode_info.atom_context);
+
+	/* init golden registers */
+	cik_init_golden_registers(rdev);
+
+	rdev->accel_working = true;
+	r = cik_startup(rdev);
+	if (r) {
+		DRM_ERROR("cik startup failed on resume\n");
+		rdev->accel_working = false;
+		return r;
+	}
+
+	return r;
+
+}
+
+/**
+ * cik_suspend - suspend the asic
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Bring the chip into a state suitable for suspend (CIK).
+ * Called at suspend.
+ * Returns 0 for success.
+ */
+int cik_suspend(struct radeon_device *rdev)
+{
+	radeon_vm_manager_fini(rdev);
+	cik_cp_enable(rdev, false);
+	cik_sdma_enable(rdev, false);
+	r600_uvd_stop(rdev);
+	radeon_uvd_suspend(rdev);
+	cik_irq_suspend(rdev);
+	radeon_wb_disable(rdev);
+	cik_pcie_gart_disable(rdev);
+	return 0;
+}
+
+/* Plan is to move initialization in that function and use
+ * helper function so that radeon_device_init pretty much
+ * do nothing more than calling asic specific function. This
+ * should also allow to remove a bunch of callback function
+ * like vram_info.
+ */
+/**
+ * cik_init - asic specific driver and hw init
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Setup asic specific driver variables and program the hw
+ * to a functional state (CIK).
+ * Called at driver startup.
+ * Returns 0 for success, errors for failure.
+ */
+int cik_init(struct radeon_device *rdev)
+{
+	struct radeon_ring *ring;
+	int r;
+
+	/* Read BIOS */
+	if (!radeon_get_bios(rdev)) {
+		if (ASIC_IS_AVIVO(rdev))
+			return -EINVAL;
+	}
+	/* Must be an ATOMBIOS */
+	if (!rdev->is_atom_bios) {
+		dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
+		return -EINVAL;
+	}
+	r = radeon_atombios_init(rdev);
+	if (r)
+		return r;
+
+	/* Post card if necessary */
+	if (!radeon_card_posted(rdev)) {
+		if (!rdev->bios) {
+			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
+			return -EINVAL;
+		}
+		DRM_INFO("GPU not posted. posting now...\n");
+		atom_asic_init(rdev->mode_info.atom_context);
+	}
+	/* init golden registers */
+	cik_init_golden_registers(rdev);
+	/* Initialize scratch registers */
+	cik_scratch_init(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
+	/* Initialize clocks */
+	radeon_get_clock_info(rdev->ddev);
+
+	/* Fence driver */
+	r = radeon_fence_driver_init(rdev);
+	if (r)
+		return r;
+
+	/* initialize memory controller */
+	r = cik_mc_init(rdev);
+	if (r)
+		return r;
+	/* Memory manager */
+	r = radeon_bo_init(rdev);
+	if (r)
+		return r;
+
+	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 1024 * 1024);
+
+	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 1024 * 1024);
+	r = radeon_doorbell_get(rdev, &ring->doorbell_page_num);
+	if (r)
+		return r;
+
+	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 1024 * 1024);
+	r = radeon_doorbell_get(rdev, &ring->doorbell_page_num);
+	if (r)
+		return r;
+
+	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 256 * 1024);
+
+	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
+	ring->ring_obj = NULL;
+	r600_ring_init(rdev, ring, 256 * 1024);
+
+	r = radeon_uvd_init(rdev);
+	if (!r) {
+		ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
+		ring->ring_obj = NULL;
+		r600_ring_init(rdev, ring, 4096);
+	}
+
+	rdev->ih.ring_obj = NULL;
+	r600_ih_ring_init(rdev, 64 * 1024);
+
+	r = r600_pcie_gart_init(rdev);
+	if (r)
+		return r;
+
+	rdev->accel_working = true;
+	r = cik_startup(rdev);
+	if (r) {
+		dev_err(rdev->dev, "disabling GPU acceleration\n");
+		cik_cp_fini(rdev);
+		cik_sdma_fini(rdev);
+		cik_irq_fini(rdev);
+		si_rlc_fini(rdev);
+		cik_mec_fini(rdev);
+		radeon_wb_fini(rdev);
+		radeon_ib_pool_fini(rdev);
+		radeon_vm_manager_fini(rdev);
+		radeon_irq_kms_fini(rdev);
+		cik_pcie_gart_fini(rdev);
+		rdev->accel_working = false;
+	}
+
+	/* Don't start up if the MC ucode is missing.
+	 * The default clocks and voltages before the MC ucode
+	 * is loaded are not suffient for advanced operations.
+	 */
+	if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
+		DRM_ERROR("radeon: MC ucode required for NI+.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * cik_fini - asic specific driver and hw fini
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down the asic specific driver variables and program the hw
+ * to an idle state (CIK).
+ * Called at driver unload.
+ */
+void cik_fini(struct radeon_device *rdev)
+{
+	cik_cp_fini(rdev);
+	cik_sdma_fini(rdev);
+	cik_irq_fini(rdev);
+	si_rlc_fini(rdev);
+	cik_mec_fini(rdev);
+	radeon_wb_fini(rdev);
+	radeon_vm_manager_fini(rdev);
+	radeon_ib_pool_fini(rdev);
+	radeon_irq_kms_fini(rdev);
+	r600_uvd_stop(rdev);
+	radeon_uvd_fini(rdev);
+	cik_pcie_gart_fini(rdev);
+	r600_vram_scratch_fini(rdev);
+	radeon_gem_fini(rdev);
+	radeon_fence_driver_fini(rdev);
+	radeon_bo_fini(rdev);
+	radeon_atombios_fini(rdev);
+	kfree(rdev->bios);
+	rdev->bios = NULL;
+}
+
+/* display watermark setup */
+/**
+ * dce8_line_buffer_adjust - Set up the line buffer
+ *
+ * @rdev: radeon_device pointer
+ * @radeon_crtc: the selected display controller
+ * @mode: the current display mode on the selected display
+ * controller
+ *
+ * Setup up the line buffer allocation for
+ * the selected display controller (CIK).
+ * Returns the line buffer size in pixels.
+ */
+static u32 dce8_line_buffer_adjust(struct radeon_device *rdev,
+				   struct radeon_crtc *radeon_crtc,
+				   struct drm_display_mode *mode)
+{
+	u32 tmp;
+
+	/*
+	 * Line Buffer Setup
+	 * There are 6 line buffers, one for each display controllers.
+	 * There are 3 partitions per LB. Select the number of partitions
+	 * to enable based on the display width.  For display widths larger
+	 * than 4096, you need use to use 2 display controllers and combine
+	 * them using the stereo blender.
+	 */
+	if (radeon_crtc->base.enabled && mode) {
+		if (mode->crtc_hdisplay < 1920)
+			tmp = 1;
+		else if (mode->crtc_hdisplay < 2560)
+			tmp = 2;
+		else if (mode->crtc_hdisplay < 4096)
+			tmp = 0;
+		else {
+			DRM_DEBUG_KMS("Mode too big for LB!\n");
+			tmp = 0;
+		}
+	} else
+		tmp = 1;
+
+	WREG32(LB_MEMORY_CTRL + radeon_crtc->crtc_offset,
+	       LB_MEMORY_CONFIG(tmp) | LB_MEMORY_SIZE(0x6B0));
+
+	if (radeon_crtc->base.enabled && mode) {
+		switch (tmp) {
+		case 0:
+		default:
+			return 4096 * 2;
+		case 1:
+			return 1920 * 2;
+		case 2:
+			return 2560 * 2;
+		}
+	}
+
+	/* controller not enabled, so no lb used */
+	return 0;
+}
+
+/**
+ * cik_get_number_of_dram_channels - get the number of dram channels
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Look up the number of video ram channels (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns the number of dram channels
+ */
+static u32 cik_get_number_of_dram_channels(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32(MC_SHARED_CHMAP);
+
+	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
+	case 0:
+	default:
+		return 1;
+	case 1:
+		return 2;
+	case 2:
+		return 4;
+	case 3:
+		return 8;
+	case 4:
+		return 3;
+	case 5:
+		return 6;
+	case 6:
+		return 10;
+	case 7:
+		return 12;
+	case 8:
+		return 16;
+	}
+}
+
+struct dce8_wm_params {
+	u32 dram_channels; /* number of dram channels */
+	u32 yclk;          /* bandwidth per dram data pin in kHz */
+	u32 sclk;          /* engine clock in kHz */
+	u32 disp_clk;      /* display clock in kHz */
+	u32 src_width;     /* viewport width */
+	u32 active_time;   /* active display time in ns */
+	u32 blank_time;    /* blank time in ns */
+	bool interlaced;    /* mode is interlaced */
+	fixed20_12 vsc;    /* vertical scale ratio */
+	u32 num_heads;     /* number of active crtcs */
+	u32 bytes_per_pixel; /* bytes per pixel display + overlay */
+	u32 lb_size;       /* line buffer allocated to pipe */
+	u32 vtaps;         /* vertical scaler taps */
+};
+
+/**
+ * dce8_dram_bandwidth - get the dram bandwidth
+ *
+ * @wm: watermark calculation data
+ *
+ * Calculate the raw dram bandwidth (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns the dram bandwidth in MBytes/s
+ */
+static u32 dce8_dram_bandwidth(struct dce8_wm_params *wm)
+{
+	/* Calculate raw DRAM Bandwidth */
+	fixed20_12 dram_efficiency; /* 0.7 */
+	fixed20_12 yclk, dram_channels, bandwidth;
+	fixed20_12 a;
+
+	a.full = dfixed_const(1000);
+	yclk.full = dfixed_const(wm->yclk);
+	yclk.full = dfixed_div(yclk, a);
+	dram_channels.full = dfixed_const(wm->dram_channels * 4);
+	a.full = dfixed_const(10);
+	dram_efficiency.full = dfixed_const(7);
+	dram_efficiency.full = dfixed_div(dram_efficiency, a);
+	bandwidth.full = dfixed_mul(dram_channels, yclk);
+	bandwidth.full = dfixed_mul(bandwidth, dram_efficiency);
+
+	return dfixed_trunc(bandwidth);
+}
+
+/**
+ * dce8_dram_bandwidth_for_display - get the dram bandwidth for display
+ *
+ * @wm: watermark calculation data
+ *
+ * Calculate the dram bandwidth used for display (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns the dram bandwidth for display in MBytes/s
+ */
+static u32 dce8_dram_bandwidth_for_display(struct dce8_wm_params *wm)
+{
+	/* Calculate DRAM Bandwidth and the part allocated to display. */
+	fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */
+	fixed20_12 yclk, dram_channels, bandwidth;
+	fixed20_12 a;
+
+	a.full = dfixed_const(1000);
+	yclk.full = dfixed_const(wm->yclk);
+	yclk.full = dfixed_div(yclk, a);
+	dram_channels.full = dfixed_const(wm->dram_channels * 4);
+	a.full = dfixed_const(10);
+	disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */
+	disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a);
+	bandwidth.full = dfixed_mul(dram_channels, yclk);
+	bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation);
+
+	return dfixed_trunc(bandwidth);
+}
+
+/**
+ * dce8_data_return_bandwidth - get the data return bandwidth
+ *
+ * @wm: watermark calculation data
+ *
+ * Calculate the data return bandwidth used for display (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns the data return bandwidth in MBytes/s
+ */
+static u32 dce8_data_return_bandwidth(struct dce8_wm_params *wm)
+{
+	/* Calculate the display Data return Bandwidth */
+	fixed20_12 return_efficiency; /* 0.8 */
+	fixed20_12 sclk, bandwidth;
+	fixed20_12 a;
+
+	a.full = dfixed_const(1000);
+	sclk.full = dfixed_const(wm->sclk);
+	sclk.full = dfixed_div(sclk, a);
+	a.full = dfixed_const(10);
+	return_efficiency.full = dfixed_const(8);
+	return_efficiency.full = dfixed_div(return_efficiency, a);
+	a.full = dfixed_const(32);
+	bandwidth.full = dfixed_mul(a, sclk);
+	bandwidth.full = dfixed_mul(bandwidth, return_efficiency);
+
+	return dfixed_trunc(bandwidth);
+}
+
+/**
+ * dce8_dmif_request_bandwidth - get the dmif bandwidth
+ *
+ * @wm: watermark calculation data
+ *
+ * Calculate the dmif bandwidth used for display (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns the dmif bandwidth in MBytes/s
+ */
+static u32 dce8_dmif_request_bandwidth(struct dce8_wm_params *wm)
+{
+	/* Calculate the DMIF Request Bandwidth */
+	fixed20_12 disp_clk_request_efficiency; /* 0.8 */
+	fixed20_12 disp_clk, bandwidth;
+	fixed20_12 a, b;
+
+	a.full = dfixed_const(1000);
+	disp_clk.full = dfixed_const(wm->disp_clk);
+	disp_clk.full = dfixed_div(disp_clk, a);
+	a.full = dfixed_const(32);
+	b.full = dfixed_mul(a, disp_clk);
+
+	a.full = dfixed_const(10);
+	disp_clk_request_efficiency.full = dfixed_const(8);
+	disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a);
+
+	bandwidth.full = dfixed_mul(b, disp_clk_request_efficiency);
+
+	return dfixed_trunc(bandwidth);
+}
+
+/**
+ * dce8_available_bandwidth - get the min available bandwidth
+ *
+ * @wm: watermark calculation data
+ *
+ * Calculate the min available bandwidth used for display (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns the min available bandwidth in MBytes/s
+ */
+static u32 dce8_available_bandwidth(struct dce8_wm_params *wm)
+{
+	/* Calculate the Available bandwidth. Display can use this temporarily but not in average. */
+	u32 dram_bandwidth = dce8_dram_bandwidth(wm);
+	u32 data_return_bandwidth = dce8_data_return_bandwidth(wm);
+	u32 dmif_req_bandwidth = dce8_dmif_request_bandwidth(wm);
+
+	return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth));
+}
+
+/**
+ * dce8_average_bandwidth - get the average available bandwidth
+ *
+ * @wm: watermark calculation data
+ *
+ * Calculate the average available bandwidth used for display (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns the average available bandwidth in MBytes/s
+ */
+static u32 dce8_average_bandwidth(struct dce8_wm_params *wm)
+{
+	/* Calculate the display mode Average Bandwidth
+	 * DisplayMode should contain the source and destination dimensions,
+	 * timing, etc.
+	 */
+	fixed20_12 bpp;
+	fixed20_12 line_time;
+	fixed20_12 src_width;
+	fixed20_12 bandwidth;
+	fixed20_12 a;
+
+	a.full = dfixed_const(1000);
+	line_time.full = dfixed_const(wm->active_time + wm->blank_time);
+	line_time.full = dfixed_div(line_time, a);
+	bpp.full = dfixed_const(wm->bytes_per_pixel);
+	src_width.full = dfixed_const(wm->src_width);
+	bandwidth.full = dfixed_mul(src_width, bpp);
+	bandwidth.full = dfixed_mul(bandwidth, wm->vsc);
+	bandwidth.full = dfixed_div(bandwidth, line_time);
+
+	return dfixed_trunc(bandwidth);
+}
+
+/**
+ * dce8_latency_watermark - get the latency watermark
+ *
+ * @wm: watermark calculation data
+ *
+ * Calculate the latency watermark (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns the latency watermark in ns
+ */
+static u32 dce8_latency_watermark(struct dce8_wm_params *wm)
+{
+	/* First calculate the latency in ns */
+	u32 mc_latency = 2000; /* 2000 ns. */
+	u32 available_bandwidth = dce8_available_bandwidth(wm);
+	u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth;
+	u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth;
+	u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */
+	u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) +
+		(wm->num_heads * cursor_line_pair_return_time);
+	u32 latency = mc_latency + other_heads_data_return_time + dc_latency;
+	u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time;
+	u32 tmp, dmif_size = 12288;
+	fixed20_12 a, b, c;
+
+	if (wm->num_heads == 0)
+		return 0;
+
+	a.full = dfixed_const(2);
+	b.full = dfixed_const(1);
+	if ((wm->vsc.full > a.full) ||
+	    ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) ||
+	    (wm->vtaps >= 5) ||
+	    ((wm->vsc.full >= a.full) && wm->interlaced))
+		max_src_lines_per_dst_line = 4;
+	else
+		max_src_lines_per_dst_line = 2;
+
+	a.full = dfixed_const(available_bandwidth);
+	b.full = dfixed_const(wm->num_heads);
+	a.full = dfixed_div(a, b);
+
+	b.full = dfixed_const(mc_latency + 512);
+	c.full = dfixed_const(wm->disp_clk);
+	b.full = dfixed_div(b, c);
+
+	c.full = dfixed_const(dmif_size);
+	b.full = dfixed_div(c, b);
+
+	tmp = min(dfixed_trunc(a), dfixed_trunc(b));
+
+	b.full = dfixed_const(1000);
+	c.full = dfixed_const(wm->disp_clk);
+	b.full = dfixed_div(c, b);
+	c.full = dfixed_const(wm->bytes_per_pixel);
+	b.full = dfixed_mul(b, c);
+
+	lb_fill_bw = min(tmp, dfixed_trunc(b));
+
+	a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
+	b.full = dfixed_const(1000);
+	c.full = dfixed_const(lb_fill_bw);
+	b.full = dfixed_div(c, b);
+	a.full = dfixed_div(a, b);
+	line_fill_time = dfixed_trunc(a);
+
+	if (line_fill_time < wm->active_time)
+		return latency;
+	else
+		return latency + (line_fill_time - wm->active_time);
+
+}
+
+/**
+ * dce8_average_bandwidth_vs_dram_bandwidth_for_display - check
+ * average and available dram bandwidth
+ *
+ * @wm: watermark calculation data
+ *
+ * Check if the display average bandwidth fits in the display
+ * dram bandwidth (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns true if the display fits, false if not.
+ */
+static bool dce8_average_bandwidth_vs_dram_bandwidth_for_display(struct dce8_wm_params *wm)
+{
+	if (dce8_average_bandwidth(wm) <=
+	    (dce8_dram_bandwidth_for_display(wm) / wm->num_heads))
+		return true;
+	else
+		return false;
+}
+
+/**
+ * dce8_average_bandwidth_vs_available_bandwidth - check
+ * average and available bandwidth
+ *
+ * @wm: watermark calculation data
+ *
+ * Check if the display average bandwidth fits in the display
+ * available bandwidth (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns true if the display fits, false if not.
+ */
+static bool dce8_average_bandwidth_vs_available_bandwidth(struct dce8_wm_params *wm)
+{
+	if (dce8_average_bandwidth(wm) <=
+	    (dce8_available_bandwidth(wm) / wm->num_heads))
+		return true;
+	else
+		return false;
+}
+
+/**
+ * dce8_check_latency_hiding - check latency hiding
+ *
+ * @wm: watermark calculation data
+ *
+ * Check latency hiding (CIK).
+ * Used for display watermark bandwidth calculations
+ * Returns true if the display fits, false if not.
+ */
+static bool dce8_check_latency_hiding(struct dce8_wm_params *wm)
+{
+	u32 lb_partitions = wm->lb_size / wm->src_width;
+	u32 line_time = wm->active_time + wm->blank_time;
+	u32 latency_tolerant_lines;
+	u32 latency_hiding;
+	fixed20_12 a;
+
+	a.full = dfixed_const(1);
+	if (wm->vsc.full > a.full)
+		latency_tolerant_lines = 1;
+	else {
+		if (lb_partitions <= (wm->vtaps + 1))
+			latency_tolerant_lines = 1;
+		else
+			latency_tolerant_lines = 2;
+	}
+
+	latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time);
+
+	if (dce8_latency_watermark(wm) <= latency_hiding)
+		return true;
+	else
+		return false;
+}
+
+/**
+ * dce8_program_watermarks - program display watermarks
+ *
+ * @rdev: radeon_device pointer
+ * @radeon_crtc: the selected display controller
+ * @lb_size: line buffer size
+ * @num_heads: number of display controllers in use
+ *
+ * Calculate and program the display watermarks for the
+ * selected display controller (CIK).
+ */
+static void dce8_program_watermarks(struct radeon_device *rdev,
+				    struct radeon_crtc *radeon_crtc,
+				    u32 lb_size, u32 num_heads)
+{
+	struct drm_display_mode *mode = &radeon_crtc->base.mode;
+	struct dce8_wm_params wm;
+	u32 pixel_period;
+	u32 line_time = 0;
+	u32 latency_watermark_a = 0, latency_watermark_b = 0;
+	u32 tmp, wm_mask;
+
+	if (radeon_crtc->base.enabled && num_heads && mode) {
+		pixel_period = 1000000 / (u32)mode->clock;
+		line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
+
+		wm.yclk = rdev->pm.current_mclk * 10;
+		wm.sclk = rdev->pm.current_sclk * 10;
+		wm.disp_clk = mode->clock;
+		wm.src_width = mode->crtc_hdisplay;
+		wm.active_time = mode->crtc_hdisplay * pixel_period;
+		wm.blank_time = line_time - wm.active_time;
+		wm.interlaced = false;
+		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+			wm.interlaced = true;
+		wm.vsc = radeon_crtc->vsc;
+		wm.vtaps = 1;
+		if (radeon_crtc->rmx_type != RMX_OFF)
+			wm.vtaps = 2;
+		wm.bytes_per_pixel = 4; /* XXX: get this from fb config */
+		wm.lb_size = lb_size;
+		wm.dram_channels = cik_get_number_of_dram_channels(rdev);
+		wm.num_heads = num_heads;
+
+		/* set for high clocks */
+		latency_watermark_a = min(dce8_latency_watermark(&wm), (u32)65535);
+		/* set for low clocks */
+		/* wm.yclk = low clk; wm.sclk = low clk */
+		latency_watermark_b = min(dce8_latency_watermark(&wm), (u32)65535);
+
+		/* possibly force display priority to high */
+		/* should really do this at mode validation time... */
+		if (!dce8_average_bandwidth_vs_dram_bandwidth_for_display(&wm) ||
+		    !dce8_average_bandwidth_vs_available_bandwidth(&wm) ||
+		    !dce8_check_latency_hiding(&wm) ||
+		    (rdev->disp_priority == 2)) {
+			DRM_DEBUG_KMS("force priority to high\n");
+		}
+	}
+
+	/* select wm A */
+	wm_mask = RREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset);
+	tmp = wm_mask;
+	tmp &= ~LATENCY_WATERMARK_MASK(3);
+	tmp |= LATENCY_WATERMARK_MASK(1);
+	WREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset, tmp);
+	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
+	       (LATENCY_LOW_WATERMARK(latency_watermark_a) |
+		LATENCY_HIGH_WATERMARK(line_time)));
+	/* select wm B */
+	tmp = RREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset);
+	tmp &= ~LATENCY_WATERMARK_MASK(3);
+	tmp |= LATENCY_WATERMARK_MASK(2);
+	WREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset, tmp);
+	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
+	       (LATENCY_LOW_WATERMARK(latency_watermark_b) |
+		LATENCY_HIGH_WATERMARK(line_time)));
+	/* restore original selection */
+	WREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset, wm_mask);
+}
+
+/**
+ * dce8_bandwidth_update - program display watermarks
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Calculate and program the display watermarks and line
+ * buffer allocation (CIK).
+ */
+void dce8_bandwidth_update(struct radeon_device *rdev)
+{
+	struct drm_display_mode *mode = NULL;
+	u32 num_heads = 0, lb_size;
+	int i;
+
+	radeon_update_display_priority(rdev);
+
+	for (i = 0; i < rdev->num_crtc; i++) {
+		if (rdev->mode_info.crtcs[i]->base.enabled)
+			num_heads++;
+	}
+	for (i = 0; i < rdev->num_crtc; i++) {
+		mode = &rdev->mode_info.crtcs[i]->base.mode;
+		lb_size = dce8_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode);
+		dce8_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads);
+	}
+}
+
+/**
+ * cik_get_gpu_clock_counter - return GPU clock counter snapshot
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Fetches a GPU clock counter snapshot (SI).
+ * Returns the 64 bit clock counter snapshot.
+ */
+uint64_t cik_get_gpu_clock_counter(struct radeon_device *rdev)
+{
+	uint64_t clock;
+
+	mutex_lock(&rdev->gpu_clock_mutex);
+	WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
+	clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
+	        ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
+	mutex_unlock(&rdev->gpu_clock_mutex);
+	return clock;
+}
+
+static int cik_set_uvd_clock(struct radeon_device *rdev, u32 clock,
+                              u32 cntl_reg, u32 status_reg)
+{
+	int r, i;
+	struct atom_clock_dividers dividers;
+	uint32_t tmp;
+
+	r = radeon_atom_get_clock_dividers(rdev, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
+					   clock, false, &dividers);
+	if (r)
+		return r;
+
+	tmp = RREG32_SMC(cntl_reg);
+	tmp &= ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK);
+	tmp |= dividers.post_divider;
+	WREG32_SMC(cntl_reg, tmp);
+
+	for (i = 0; i < 100; i++) {
+		if (RREG32_SMC(status_reg) & DCLK_STATUS)
+			break;
+		mdelay(10);
+	}
+	if (i == 100)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
+{
+	int r = 0;
+
+	r = cik_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS);
+	if (r)
+		return r;
+
+	r = cik_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS);
+	return r;
+}
+
+int cik_uvd_resume(struct radeon_device *rdev)
+{
+	uint64_t addr;
+	uint32_t size;
+	int r;
+
+	r = radeon_uvd_resume(rdev);
+	if (r)
+		return r;
+
+	/* programm the VCPU memory controller bits 0-27 */
+	addr = rdev->uvd.gpu_addr >> 3;
+	size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
+	WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
+	WREG32(UVD_VCPU_CACHE_SIZE0, size);
+
+	addr += size;
+	size = RADEON_UVD_STACK_SIZE >> 3;
+	WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
+	WREG32(UVD_VCPU_CACHE_SIZE1, size);
+
+	addr += size;
+	size = RADEON_UVD_HEAP_SIZE >> 3;
+	WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
+	WREG32(UVD_VCPU_CACHE_SIZE2, size);
+
+	/* bits 28-31 */
+	addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
+	WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
+
+	/* bits 32-39 */
+	addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
+	WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cikd.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cikd.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cikd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cikd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1313 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+#ifndef CIK_H
+#define CIK_H
+
+#define BONAIRE_GB_ADDR_CONFIG_GOLDEN        0x12010001
+
+#define CIK_RB_BITMAP_WIDTH_PER_SH  2
+
+/* SMC IND registers */
+#define GENERAL_PWRMGT                                    0xC0200000
+#       define GPU_COUNTER_CLK                            (1 << 15)
+
+#define CG_CLKPIN_CNTL                                    0xC05001A0
+#       define XTALIN_DIVIDE                              (1 << 1)
+
+#define PCIE_INDEX  					0x38
+#define PCIE_DATA  					0x3C
+
+#define VGA_HDP_CONTROL  				0x328
+#define		VGA_MEMORY_DISABLE				(1 << 4)
+
+#define DMIF_ADDR_CALC  				0xC00
+
+#define	SRBM_GFX_CNTL				        0xE44
+#define		PIPEID(x)					((x) << 0)
+#define		MEID(x)						((x) << 2)
+#define		VMID(x)						((x) << 4)
+#define		QUEUEID(x)					((x) << 8)
+
+#define	SRBM_STATUS2				        0xE4C
+#define		SDMA_BUSY 				(1 << 5)
+#define		SDMA1_BUSY 				(1 << 6)
+#define	SRBM_STATUS				        0xE50
+#define		UVD_RQ_PENDING 				(1 << 1)
+#define		GRBM_RQ_PENDING 			(1 << 5)
+#define		VMC_BUSY 				(1 << 8)
+#define		MCB_BUSY 				(1 << 9)
+#define		MCB_NON_DISPLAY_BUSY 			(1 << 10)
+#define		MCC_BUSY 				(1 << 11)
+#define		MCD_BUSY 				(1 << 12)
+#define		SEM_BUSY 				(1 << 14)
+#define		IH_BUSY 				(1 << 17)
+#define		UVD_BUSY 				(1 << 19)
+
+#define	SRBM_SOFT_RESET				        0xE60
+#define		SOFT_RESET_BIF				(1 << 1)
+#define		SOFT_RESET_R0PLL			(1 << 4)
+#define		SOFT_RESET_DC				(1 << 5)
+#define		SOFT_RESET_SDMA1			(1 << 6)
+#define		SOFT_RESET_GRBM				(1 << 8)
+#define		SOFT_RESET_HDP				(1 << 9)
+#define		SOFT_RESET_IH				(1 << 10)
+#define		SOFT_RESET_MC				(1 << 11)
+#define		SOFT_RESET_ROM				(1 << 14)
+#define		SOFT_RESET_SEM				(1 << 15)
+#define		SOFT_RESET_VMC				(1 << 17)
+#define		SOFT_RESET_SDMA				(1 << 20)
+#define		SOFT_RESET_TST				(1 << 21)
+#define		SOFT_RESET_REGBB		       	(1 << 22)
+#define		SOFT_RESET_ORB				(1 << 23)
+#define		SOFT_RESET_VCE				(1 << 24)
+
+#define VM_L2_CNTL					0x1400
+#define		ENABLE_L2_CACHE					(1 << 0)
+#define		ENABLE_L2_FRAGMENT_PROCESSING			(1 << 1)
+#define		L2_CACHE_PTE_ENDIAN_SWAP_MODE(x)		((x) << 2)
+#define		L2_CACHE_PDE_ENDIAN_SWAP_MODE(x)		((x) << 4)
+#define		ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE		(1 << 9)
+#define		ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE	(1 << 10)
+#define		EFFECTIVE_L2_QUEUE_SIZE(x)			(((x) & 7) << 15)
+#define		CONTEXT1_IDENTITY_ACCESS_MODE(x)		(((x) & 3) << 19)
+#define VM_L2_CNTL2					0x1404
+#define		INVALIDATE_ALL_L1_TLBS				(1 << 0)
+#define		INVALIDATE_L2_CACHE				(1 << 1)
+#define		INVALIDATE_CACHE_MODE(x)			((x) << 26)
+#define			INVALIDATE_PTE_AND_PDE_CACHES		0
+#define			INVALIDATE_ONLY_PTE_CACHES		1
+#define			INVALIDATE_ONLY_PDE_CACHES		2
+#define VM_L2_CNTL3					0x1408
+#define		BANK_SELECT(x)					((x) << 0)
+#define		L2_CACHE_UPDATE_MODE(x)				((x) << 6)
+#define		L2_CACHE_BIGK_FRAGMENT_SIZE(x)			((x) << 15)
+#define		L2_CACHE_BIGK_ASSOCIATIVITY			(1 << 20)
+#define	VM_L2_STATUS					0x140C
+#define		L2_BUSY						(1 << 0)
+#define VM_CONTEXT0_CNTL				0x1410
+#define		ENABLE_CONTEXT					(1 << 0)
+#define		PAGE_TABLE_DEPTH(x)				(((x) & 3) << 1)
+#define		RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT		(1 << 3)
+#define		RANGE_PROTECTION_FAULT_ENABLE_DEFAULT		(1 << 4)
+#define		DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT	(1 << 6)
+#define		DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT	(1 << 7)
+#define		PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT		(1 << 9)
+#define		PDE0_PROTECTION_FAULT_ENABLE_DEFAULT		(1 << 10)
+#define		VALID_PROTECTION_FAULT_ENABLE_INTERRUPT		(1 << 12)
+#define		VALID_PROTECTION_FAULT_ENABLE_DEFAULT		(1 << 13)
+#define		READ_PROTECTION_FAULT_ENABLE_INTERRUPT		(1 << 15)
+#define		READ_PROTECTION_FAULT_ENABLE_DEFAULT		(1 << 16)
+#define		WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT		(1 << 18)
+#define		WRITE_PROTECTION_FAULT_ENABLE_DEFAULT		(1 << 19)
+#define VM_CONTEXT1_CNTL				0x1414
+#define VM_CONTEXT0_CNTL2				0x1430
+#define VM_CONTEXT1_CNTL2				0x1434
+#define	VM_CONTEXT8_PAGE_TABLE_BASE_ADDR		0x1438
+#define	VM_CONTEXT9_PAGE_TABLE_BASE_ADDR		0x143c
+#define	VM_CONTEXT10_PAGE_TABLE_BASE_ADDR		0x1440
+#define	VM_CONTEXT11_PAGE_TABLE_BASE_ADDR		0x1444
+#define	VM_CONTEXT12_PAGE_TABLE_BASE_ADDR		0x1448
+#define	VM_CONTEXT13_PAGE_TABLE_BASE_ADDR		0x144c
+#define	VM_CONTEXT14_PAGE_TABLE_BASE_ADDR		0x1450
+#define	VM_CONTEXT15_PAGE_TABLE_BASE_ADDR		0x1454
+
+#define VM_INVALIDATE_REQUEST				0x1478
+#define VM_INVALIDATE_RESPONSE				0x147c
+
+#define	VM_CONTEXT1_PROTECTION_FAULT_STATUS		0x14DC
+#define		PROTECTIONS_MASK			(0xf << 0)
+#define		PROTECTIONS_SHIFT			0
+		/* bit 0: range
+		 * bit 1: pde0
+		 * bit 2: valid
+		 * bit 3: read
+		 * bit 4: write
+		 */
+#define		MEMORY_CLIENT_ID_MASK			(0xff << 12)
+#define		MEMORY_CLIENT_ID_SHIFT			12
+#define		MEMORY_CLIENT_RW_MASK			(1 << 24)
+#define		MEMORY_CLIENT_RW_SHIFT			24
+#define		FAULT_VMID_MASK				(0xf << 25)
+#define		FAULT_VMID_SHIFT			25
+
+#define	VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT		0x14E4
+
+#define	VM_CONTEXT1_PROTECTION_FAULT_ADDR		0x14FC
+
+#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR	0x1518
+#define VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR	0x151c
+
+#define	VM_CONTEXT0_PAGE_TABLE_BASE_ADDR		0x153c
+#define	VM_CONTEXT1_PAGE_TABLE_BASE_ADDR		0x1540
+#define	VM_CONTEXT2_PAGE_TABLE_BASE_ADDR		0x1544
+#define	VM_CONTEXT3_PAGE_TABLE_BASE_ADDR		0x1548
+#define	VM_CONTEXT4_PAGE_TABLE_BASE_ADDR		0x154c
+#define	VM_CONTEXT5_PAGE_TABLE_BASE_ADDR		0x1550
+#define	VM_CONTEXT6_PAGE_TABLE_BASE_ADDR		0x1554
+#define	VM_CONTEXT7_PAGE_TABLE_BASE_ADDR		0x1558
+#define	VM_CONTEXT0_PAGE_TABLE_START_ADDR		0x155c
+#define	VM_CONTEXT1_PAGE_TABLE_START_ADDR		0x1560
+
+#define	VM_CONTEXT0_PAGE_TABLE_END_ADDR			0x157C
+#define	VM_CONTEXT1_PAGE_TABLE_END_ADDR			0x1580
+
+#define MC_SHARED_CHMAP						0x2004
+#define		NOOFCHAN_SHIFT					12
+#define		NOOFCHAN_MASK					0x0000f000
+#define MC_SHARED_CHREMAP					0x2008
+
+#define CHUB_CONTROL					0x1864
+#define		BYPASS_VM					(1 << 0)
+
+#define	MC_VM_FB_LOCATION				0x2024
+#define	MC_VM_AGP_TOP					0x2028
+#define	MC_VM_AGP_BOT					0x202C
+#define	MC_VM_AGP_BASE					0x2030
+#define	MC_VM_SYSTEM_APERTURE_LOW_ADDR			0x2034
+#define	MC_VM_SYSTEM_APERTURE_HIGH_ADDR			0x2038
+#define	MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR		0x203C
+
+#define	MC_VM_MX_L1_TLB_CNTL				0x2064
+#define		ENABLE_L1_TLB					(1 << 0)
+#define		ENABLE_L1_FRAGMENT_PROCESSING			(1 << 1)
+#define		SYSTEM_ACCESS_MODE_PA_ONLY			(0 << 3)
+#define		SYSTEM_ACCESS_MODE_USE_SYS_MAP			(1 << 3)
+#define		SYSTEM_ACCESS_MODE_IN_SYS			(2 << 3)
+#define		SYSTEM_ACCESS_MODE_NOT_IN_SYS			(3 << 3)
+#define		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU	(0 << 5)
+#define		ENABLE_ADVANCED_DRIVER_MODEL			(1 << 6)
+#define	MC_VM_FB_OFFSET					0x2068
+
+#define MC_SHARED_BLACKOUT_CNTL           		0x20ac
+
+#define	MC_ARB_RAMCFG					0x2760
+#define		NOOFBANK_SHIFT					0
+#define		NOOFBANK_MASK					0x00000003
+#define		NOOFRANK_SHIFT					2
+#define		NOOFRANK_MASK					0x00000004
+#define		NOOFROWS_SHIFT					3
+#define		NOOFROWS_MASK					0x00000038
+#define		NOOFCOLS_SHIFT					6
+#define		NOOFCOLS_MASK					0x000000C0
+#define		CHANSIZE_SHIFT					8
+#define		CHANSIZE_MASK					0x00000100
+#define		NOOFGROUPS_SHIFT				12
+#define		NOOFGROUPS_MASK					0x00001000
+
+#define MC_SEQ_SUP_CNTL           			0x28c8
+#define		RUN_MASK      				(1 << 0)
+#define MC_SEQ_SUP_PGM           			0x28cc
+
+#define	MC_SEQ_TRAIN_WAKEUP_CNTL			0x28e8
+#define		TRAIN_DONE_D0      			(1 << 30)
+#define		TRAIN_DONE_D1      			(1 << 31)
+
+#define MC_IO_PAD_CNTL_D0           			0x29d0
+#define		MEM_FALL_OUT_CMD      			(1 << 8)
+
+#define MC_SEQ_IO_DEBUG_INDEX           		0x2a44
+#define MC_SEQ_IO_DEBUG_DATA           			0x2a48
+
+#define	HDP_HOST_PATH_CNTL				0x2C00
+#define	HDP_NONSURFACE_BASE				0x2C04
+#define	HDP_NONSURFACE_INFO				0x2C08
+#define	HDP_NONSURFACE_SIZE				0x2C0C
+
+#define HDP_ADDR_CONFIG  				0x2F48
+#define HDP_MISC_CNTL					0x2F4C
+#define 	HDP_FLUSH_INVALIDATE_CACHE			(1 << 0)
+
+#define IH_RB_CNTL                                        0x3e00
+#       define IH_RB_ENABLE                               (1 << 0)
+#       define IH_RB_SIZE(x)                              ((x) << 1) /* log2 */
+#       define IH_RB_FULL_DRAIN_ENABLE                    (1 << 6)
+#       define IH_WPTR_WRITEBACK_ENABLE                   (1 << 8)
+#       define IH_WPTR_WRITEBACK_TIMER(x)                 ((x) << 9) /* log2 */
+#       define IH_WPTR_OVERFLOW_ENABLE                    (1 << 16)
+#       define IH_WPTR_OVERFLOW_CLEAR                     (1 << 31)
+#define IH_RB_BASE                                        0x3e04
+#define IH_RB_RPTR                                        0x3e08
+#define IH_RB_WPTR                                        0x3e0c
+#       define RB_OVERFLOW                                (1 << 0)
+#       define WPTR_OFFSET_MASK                           0x3fffc
+#define IH_RB_WPTR_ADDR_HI                                0x3e10
+#define IH_RB_WPTR_ADDR_LO                                0x3e14
+#define IH_CNTL                                           0x3e18
+#       define ENABLE_INTR                                (1 << 0)
+#       define IH_MC_SWAP(x)                              ((x) << 1)
+#       define IH_MC_SWAP_NONE                            0
+#       define IH_MC_SWAP_16BIT                           1
+#       define IH_MC_SWAP_32BIT                           2
+#       define IH_MC_SWAP_64BIT                           3
+#       define RPTR_REARM                                 (1 << 4)
+#       define MC_WRREQ_CREDIT(x)                         ((x) << 15)
+#       define MC_WR_CLEAN_CNT(x)                         ((x) << 20)
+#       define MC_VMID(x)                                 ((x) << 25)
+
+#define	CONFIG_MEMSIZE					0x5428
+
+#define INTERRUPT_CNTL                                    0x5468
+#       define IH_DUMMY_RD_OVERRIDE                       (1 << 0)
+#       define IH_DUMMY_RD_EN                             (1 << 1)
+#       define IH_REQ_NONSNOOP_EN                         (1 << 3)
+#       define GEN_IH_INT_EN                              (1 << 8)
+#define INTERRUPT_CNTL2                                   0x546c
+
+#define HDP_MEM_COHERENCY_FLUSH_CNTL			0x5480
+
+#define	BIF_FB_EN						0x5490
+#define		FB_READ_EN					(1 << 0)
+#define		FB_WRITE_EN					(1 << 1)
+
+#define HDP_REG_COHERENCY_FLUSH_CNTL			0x54A0
+
+#define GPU_HDP_FLUSH_REQ				0x54DC
+#define GPU_HDP_FLUSH_DONE				0x54E0
+#define		CP0					(1 << 0)
+#define		CP1					(1 << 1)
+#define		CP2					(1 << 2)
+#define		CP3					(1 << 3)
+#define		CP4					(1 << 4)
+#define		CP5					(1 << 5)
+#define		CP6					(1 << 6)
+#define		CP7					(1 << 7)
+#define		CP8					(1 << 8)
+#define		CP9					(1 << 9)
+#define		SDMA0					(1 << 10)
+#define		SDMA1					(1 << 11)
+
+/* 0x6b04, 0x7704, 0x10304, 0x10f04, 0x11b04, 0x12704 */
+#define	LB_MEMORY_CTRL					0x6b04
+#define		LB_MEMORY_SIZE(x)			((x) << 0)
+#define		LB_MEMORY_CONFIG(x)			((x) << 20)
+
+#define	DPG_WATERMARK_MASK_CONTROL			0x6cc8
+#       define LATENCY_WATERMARK_MASK(x)		((x) << 8)
+#define	DPG_PIPE_LATENCY_CONTROL			0x6ccc
+#       define LATENCY_LOW_WATERMARK(x)			((x) << 0)
+#       define LATENCY_HIGH_WATERMARK(x)		((x) << 16)
+
+/* 0x6b24, 0x7724, 0x10324, 0x10f24, 0x11b24, 0x12724 */
+#define LB_VLINE_STATUS                                 0x6b24
+#       define VLINE_OCCURRED                           (1 << 0)
+#       define VLINE_ACK                                (1 << 4)
+#       define VLINE_STAT                               (1 << 12)
+#       define VLINE_INTERRUPT                          (1 << 16)
+#       define VLINE_INTERRUPT_TYPE                     (1 << 17)
+/* 0x6b2c, 0x772c, 0x1032c, 0x10f2c, 0x11b2c, 0x1272c */
+#define LB_VBLANK_STATUS                                0x6b2c
+#       define VBLANK_OCCURRED                          (1 << 0)
+#       define VBLANK_ACK                               (1 << 4)
+#       define VBLANK_STAT                              (1 << 12)
+#       define VBLANK_INTERRUPT                         (1 << 16)
+#       define VBLANK_INTERRUPT_TYPE                    (1 << 17)
+
+/* 0x6b20, 0x7720, 0x10320, 0x10f20, 0x11b20, 0x12720 */
+#define LB_INTERRUPT_MASK                               0x6b20
+#       define VBLANK_INTERRUPT_MASK                    (1 << 0)
+#       define VLINE_INTERRUPT_MASK                     (1 << 4)
+#       define VLINE2_INTERRUPT_MASK                    (1 << 8)
+
+#define DISP_INTERRUPT_STATUS                           0x60f4
+#       define LB_D1_VLINE_INTERRUPT                    (1 << 2)
+#       define LB_D1_VBLANK_INTERRUPT                   (1 << 3)
+#       define DC_HPD1_INTERRUPT                        (1 << 17)
+#       define DC_HPD1_RX_INTERRUPT                     (1 << 18)
+#       define DACA_AUTODETECT_INTERRUPT                (1 << 22)
+#       define DACB_AUTODETECT_INTERRUPT                (1 << 23)
+#       define DC_I2C_SW_DONE_INTERRUPT                 (1 << 24)
+#       define DC_I2C_HW_DONE_INTERRUPT                 (1 << 25)
+#define DISP_INTERRUPT_STATUS_CONTINUE                  0x60f8
+#       define LB_D2_VLINE_INTERRUPT                    (1 << 2)
+#       define LB_D2_VBLANK_INTERRUPT                   (1 << 3)
+#       define DC_HPD2_INTERRUPT                        (1 << 17)
+#       define DC_HPD2_RX_INTERRUPT                     (1 << 18)
+#       define DISP_TIMER_INTERRUPT                     (1 << 24)
+#define DISP_INTERRUPT_STATUS_CONTINUE2                 0x60fc
+#       define LB_D3_VLINE_INTERRUPT                    (1 << 2)
+#       define LB_D3_VBLANK_INTERRUPT                   (1 << 3)
+#       define DC_HPD3_INTERRUPT                        (1 << 17)
+#       define DC_HPD3_RX_INTERRUPT                     (1 << 18)
+#define DISP_INTERRUPT_STATUS_CONTINUE3                 0x6100
+#       define LB_D4_VLINE_INTERRUPT                    (1 << 2)
+#       define LB_D4_VBLANK_INTERRUPT                   (1 << 3)
+#       define DC_HPD4_INTERRUPT                        (1 << 17)
+#       define DC_HPD4_RX_INTERRUPT                     (1 << 18)
+#define DISP_INTERRUPT_STATUS_CONTINUE4                 0x614c
+#       define LB_D5_VLINE_INTERRUPT                    (1 << 2)
+#       define LB_D5_VBLANK_INTERRUPT                   (1 << 3)
+#       define DC_HPD5_INTERRUPT                        (1 << 17)
+#       define DC_HPD5_RX_INTERRUPT                     (1 << 18)
+#define DISP_INTERRUPT_STATUS_CONTINUE5                 0x6150
+#       define LB_D6_VLINE_INTERRUPT                    (1 << 2)
+#       define LB_D6_VBLANK_INTERRUPT                   (1 << 3)
+#       define DC_HPD6_INTERRUPT                        (1 << 17)
+#       define DC_HPD6_RX_INTERRUPT                     (1 << 18)
+#define DISP_INTERRUPT_STATUS_CONTINUE6                 0x6780
+
+#define	DAC_AUTODETECT_INT_CONTROL			0x67c8
+
+#define DC_HPD1_INT_STATUS                              0x601c
+#define DC_HPD2_INT_STATUS                              0x6028
+#define DC_HPD3_INT_STATUS                              0x6034
+#define DC_HPD4_INT_STATUS                              0x6040
+#define DC_HPD5_INT_STATUS                              0x604c
+#define DC_HPD6_INT_STATUS                              0x6058
+#       define DC_HPDx_INT_STATUS                       (1 << 0)
+#       define DC_HPDx_SENSE                            (1 << 1)
+#       define DC_HPDx_SENSE_DELAYED                    (1 << 4)
+#       define DC_HPDx_RX_INT_STATUS                    (1 << 8)
+
+#define DC_HPD1_INT_CONTROL                             0x6020
+#define DC_HPD2_INT_CONTROL                             0x602c
+#define DC_HPD3_INT_CONTROL                             0x6038
+#define DC_HPD4_INT_CONTROL                             0x6044
+#define DC_HPD5_INT_CONTROL                             0x6050
+#define DC_HPD6_INT_CONTROL                             0x605c
+#       define DC_HPDx_INT_ACK                          (1 << 0)
+#       define DC_HPDx_INT_POLARITY                     (1 << 8)
+#       define DC_HPDx_INT_EN                           (1 << 16)
+#       define DC_HPDx_RX_INT_ACK                       (1 << 20)
+#       define DC_HPDx_RX_INT_EN                        (1 << 24)
+
+#define DC_HPD1_CONTROL                                   0x6024
+#define DC_HPD2_CONTROL                                   0x6030
+#define DC_HPD3_CONTROL                                   0x603c
+#define DC_HPD4_CONTROL                                   0x6048
+#define DC_HPD5_CONTROL                                   0x6054
+#define DC_HPD6_CONTROL                                   0x6060
+#       define DC_HPDx_CONNECTION_TIMER(x)                ((x) << 0)
+#       define DC_HPDx_RX_INT_TIMER(x)                    ((x) << 16)
+#       define DC_HPDx_EN                                 (1 << 28)
+
+#define	GRBM_CNTL					0x8000
+#define		GRBM_READ_TIMEOUT(x)				((x) << 0)
+
+#define	GRBM_STATUS2					0x8008
+#define		ME0PIPE1_CMDFIFO_AVAIL_MASK			0x0000000F
+#define		ME0PIPE1_CF_RQ_PENDING				(1 << 4)
+#define		ME0PIPE1_PF_RQ_PENDING				(1 << 5)
+#define		ME1PIPE0_RQ_PENDING				(1 << 6)
+#define		ME1PIPE1_RQ_PENDING				(1 << 7)
+#define		ME1PIPE2_RQ_PENDING				(1 << 8)
+#define		ME1PIPE3_RQ_PENDING				(1 << 9)
+#define		ME2PIPE0_RQ_PENDING				(1 << 10)
+#define		ME2PIPE1_RQ_PENDING				(1 << 11)
+#define		ME2PIPE2_RQ_PENDING				(1 << 12)
+#define		ME2PIPE3_RQ_PENDING				(1 << 13)
+#define		RLC_RQ_PENDING 					(1 << 14)
+#define		RLC_BUSY 					(1 << 24)
+#define		TC_BUSY 					(1 << 25)
+#define		CPF_BUSY 					(1 << 28)
+#define		CPC_BUSY 					(1 << 29)
+#define		CPG_BUSY 					(1 << 30)
+
+#define	GRBM_STATUS					0x8010
+#define		ME0PIPE0_CMDFIFO_AVAIL_MASK			0x0000000F
+#define		SRBM_RQ_PENDING					(1 << 5)
+#define		ME0PIPE0_CF_RQ_PENDING				(1 << 7)
+#define		ME0PIPE0_PF_RQ_PENDING				(1 << 8)
+#define		GDS_DMA_RQ_PENDING				(1 << 9)
+#define		DB_CLEAN					(1 << 12)
+#define		CB_CLEAN					(1 << 13)
+#define		TA_BUSY 					(1 << 14)
+#define		GDS_BUSY 					(1 << 15)
+#define		WD_BUSY_NO_DMA 					(1 << 16)
+#define		VGT_BUSY					(1 << 17)
+#define		IA_BUSY_NO_DMA					(1 << 18)
+#define		IA_BUSY						(1 << 19)
+#define		SX_BUSY 					(1 << 20)
+#define		WD_BUSY 					(1 << 21)
+#define		SPI_BUSY					(1 << 22)
+#define		BCI_BUSY					(1 << 23)
+#define		SC_BUSY 					(1 << 24)
+#define		PA_BUSY 					(1 << 25)
+#define		DB_BUSY 					(1 << 26)
+#define		CP_COHERENCY_BUSY      				(1 << 28)
+#define		CP_BUSY 					(1 << 29)
+#define		CB_BUSY 					(1 << 30)
+#define		GUI_ACTIVE					(1 << 31)
+#define	GRBM_STATUS_SE0					0x8014
+#define	GRBM_STATUS_SE1					0x8018
+#define	GRBM_STATUS_SE2					0x8038
+#define	GRBM_STATUS_SE3					0x803C
+#define		SE_DB_CLEAN					(1 << 1)
+#define		SE_CB_CLEAN					(1 << 2)
+#define		SE_BCI_BUSY					(1 << 22)
+#define		SE_VGT_BUSY					(1 << 23)
+#define		SE_PA_BUSY					(1 << 24)
+#define		SE_TA_BUSY					(1 << 25)
+#define		SE_SX_BUSY					(1 << 26)
+#define		SE_SPI_BUSY					(1 << 27)
+#define		SE_SC_BUSY					(1 << 29)
+#define		SE_DB_BUSY					(1 << 30)
+#define		SE_CB_BUSY					(1 << 31)
+
+#define	GRBM_SOFT_RESET					0x8020
+#define		SOFT_RESET_CP					(1 << 0)  /* All CP blocks */
+#define		SOFT_RESET_RLC					(1 << 2)  /* RLC */
+#define		SOFT_RESET_GFX					(1 << 16) /* GFX */
+#define		SOFT_RESET_CPF					(1 << 17) /* CP fetcher shared by gfx and compute */
+#define		SOFT_RESET_CPC					(1 << 18) /* CP Compute (MEC1/2) */
+#define		SOFT_RESET_CPG					(1 << 19) /* CP GFX (PFP, ME, CE) */
+
+#define GRBM_INT_CNTL                                   0x8060
+#       define RDERR_INT_ENABLE                         (1 << 0)
+#       define GUI_IDLE_INT_ENABLE                      (1 << 19)
+
+#define CP_CPC_STATUS					0x8210
+#define CP_CPC_BUSY_STAT				0x8214
+#define CP_CPC_STALLED_STAT1				0x8218
+#define CP_CPF_STATUS					0x821c
+#define CP_CPF_BUSY_STAT				0x8220
+#define CP_CPF_STALLED_STAT1				0x8224
+
+#define CP_MEC_CNTL					0x8234
+#define		MEC_ME2_HALT					(1 << 28)
+#define		MEC_ME1_HALT					(1 << 30)
+
+#define CP_MEC_CNTL					0x8234
+#define		MEC_ME2_HALT					(1 << 28)
+#define		MEC_ME1_HALT					(1 << 30)
+
+#define CP_STALLED_STAT3				0x8670
+#define CP_STALLED_STAT1				0x8674
+#define CP_STALLED_STAT2				0x8678
+
+#define CP_STAT						0x8680
+
+#define CP_ME_CNTL					0x86D8
+#define		CP_CE_HALT					(1 << 24)
+#define		CP_PFP_HALT					(1 << 26)
+#define		CP_ME_HALT					(1 << 28)
+
+#define	CP_RB0_RPTR					0x8700
+#define	CP_RB_WPTR_DELAY				0x8704
+
+#define CP_MEQ_THRESHOLDS				0x8764
+#define		MEQ1_START(x)				((x) << 0)
+#define		MEQ2_START(x)				((x) << 8)
+
+#define	VGT_VTX_VECT_EJECT_REG				0x88B0
+
+#define	VGT_CACHE_INVALIDATION				0x88C4
+#define		CACHE_INVALIDATION(x)				((x) << 0)
+#define			VC_ONLY						0
+#define			TC_ONLY						1
+#define			VC_AND_TC					2
+#define		AUTO_INVLD_EN(x)				((x) << 6)
+#define			NO_AUTO						0
+#define			ES_AUTO						1
+#define			GS_AUTO						2
+#define			ES_AND_GS_AUTO					3
+
+#define	VGT_GS_VERTEX_REUSE				0x88D4
+
+#define CC_GC_SHADER_ARRAY_CONFIG			0x89bc
+#define		INACTIVE_CUS_MASK			0xFFFF0000
+#define		INACTIVE_CUS_SHIFT			16
+#define GC_USER_SHADER_ARRAY_CONFIG			0x89c0
+
+#define	PA_CL_ENHANCE					0x8A14
+#define		CLIP_VTX_REORDER_ENA				(1 << 0)
+#define		NUM_CLIP_SEQ(x)					((x) << 1)
+
+#define	PA_SC_FORCE_EOV_MAX_CNTS			0x8B24
+#define		FORCE_EOV_MAX_CLK_CNT(x)			((x) << 0)
+#define		FORCE_EOV_MAX_REZ_CNT(x)			((x) << 16)
+
+#define	PA_SC_FIFO_SIZE					0x8BCC
+#define		SC_FRONTEND_PRIM_FIFO_SIZE(x)			((x) << 0)
+#define		SC_BACKEND_PRIM_FIFO_SIZE(x)			((x) << 6)
+#define		SC_HIZ_TILE_FIFO_SIZE(x)			((x) << 15)
+#define		SC_EARLYZ_TILE_FIFO_SIZE(x)			((x) << 23)
+
+#define	PA_SC_ENHANCE					0x8BF0
+#define		ENABLE_PA_SC_OUT_OF_ORDER			(1 << 0)
+#define		DISABLE_PA_SC_GUIDANCE				(1 << 13)
+
+#define	SQ_CONFIG					0x8C00
+
+#define	SH_MEM_BASES					0x8C28
+/* if PTR32, these are the bases for scratch and lds */
+#define		PRIVATE_BASE(x)					((x) << 0) /* scratch */
+#define		SHARED_BASE(x)					((x) << 16) /* LDS */
+#define	SH_MEM_APE1_BASE				0x8C2C
+/* if PTR32, this is the base location of GPUVM */
+#define	SH_MEM_APE1_LIMIT				0x8C30
+/* if PTR32, this is the upper limit of GPUVM */
+#define	SH_MEM_CONFIG					0x8C34
+#define		PTR32						(1 << 0)
+#define		ALIGNMENT_MODE(x)				((x) << 2)
+#define			SH_MEM_ALIGNMENT_MODE_DWORD			0
+#define			SH_MEM_ALIGNMENT_MODE_DWORD_STRICT		1
+#define			SH_MEM_ALIGNMENT_MODE_STRICT			2
+#define			SH_MEM_ALIGNMENT_MODE_UNALIGNED			3
+#define		DEFAULT_MTYPE(x)				((x) << 4)
+#define		APE1_MTYPE(x)					((x) << 7)
+
+#define	SX_DEBUG_1					0x9060
+
+#define	SPI_CONFIG_CNTL					0x9100
+
+#define	SPI_CONFIG_CNTL_1				0x913C
+#define		VTX_DONE_DELAY(x)				((x) << 0)
+#define		INTERP_ONE_PRIM_PER_ROW				(1 << 4)
+
+#define	TA_CNTL_AUX					0x9508
+
+#define DB_DEBUG					0x9830
+#define DB_DEBUG2					0x9834
+#define DB_DEBUG3					0x9838
+
+#define CC_RB_BACKEND_DISABLE				0x98F4
+#define		BACKEND_DISABLE(x)     			((x) << 16)
+#define GB_ADDR_CONFIG  				0x98F8
+#define		NUM_PIPES(x)				((x) << 0)
+#define		NUM_PIPES_MASK				0x00000007
+#define		NUM_PIPES_SHIFT				0
+#define		PIPE_INTERLEAVE_SIZE(x)			((x) << 4)
+#define		PIPE_INTERLEAVE_SIZE_MASK		0x00000070
+#define		PIPE_INTERLEAVE_SIZE_SHIFT		4
+#define		NUM_SHADER_ENGINES(x)			((x) << 12)
+#define		NUM_SHADER_ENGINES_MASK			0x00003000
+#define		NUM_SHADER_ENGINES_SHIFT		12
+#define		SHADER_ENGINE_TILE_SIZE(x)     		((x) << 16)
+#define		SHADER_ENGINE_TILE_SIZE_MASK		0x00070000
+#define		SHADER_ENGINE_TILE_SIZE_SHIFT		16
+#define		ROW_SIZE(x)             		((x) << 28)
+#define		ROW_SIZE_MASK				0x30000000
+#define		ROW_SIZE_SHIFT				28
+
+#define	GB_TILE_MODE0					0x9910
+#       define ARRAY_MODE(x)					((x) << 2)
+#              define	ARRAY_LINEAR_GENERAL			0
+#              define	ARRAY_LINEAR_ALIGNED			1
+#              define	ARRAY_1D_TILED_THIN1			2
+#              define	ARRAY_2D_TILED_THIN1			4
+#              define	ARRAY_PRT_TILED_THIN1			5
+#              define	ARRAY_PRT_2D_TILED_THIN1		6
+#       define PIPE_CONFIG(x)					((x) << 6)
+#              define	ADDR_SURF_P2				0
+#              define	ADDR_SURF_P4_8x16			4
+#              define	ADDR_SURF_P4_16x16			5
+#              define	ADDR_SURF_P4_16x32			6
+#              define	ADDR_SURF_P4_32x32			7
+#              define	ADDR_SURF_P8_16x16_8x16			8
+#              define	ADDR_SURF_P8_16x32_8x16			9
+#              define	ADDR_SURF_P8_32x32_8x16			10
+#              define	ADDR_SURF_P8_16x32_16x16		11
+#              define	ADDR_SURF_P8_32x32_16x16		12
+#              define	ADDR_SURF_P8_32x32_16x32		13
+#              define	ADDR_SURF_P8_32x64_32x32		14
+#       define TILE_SPLIT(x)					((x) << 11)
+#              define	ADDR_SURF_TILE_SPLIT_64B		0
+#              define	ADDR_SURF_TILE_SPLIT_128B		1
+#              define	ADDR_SURF_TILE_SPLIT_256B		2
+#              define	ADDR_SURF_TILE_SPLIT_512B		3
+#              define	ADDR_SURF_TILE_SPLIT_1KB		4
+#              define	ADDR_SURF_TILE_SPLIT_2KB		5
+#              define	ADDR_SURF_TILE_SPLIT_4KB		6
+#       define MICRO_TILE_MODE_NEW(x)				((x) << 22)
+#              define	ADDR_SURF_DISPLAY_MICRO_TILING		0
+#              define	ADDR_SURF_THIN_MICRO_TILING		1
+#              define	ADDR_SURF_DEPTH_MICRO_TILING		2
+#              define	ADDR_SURF_ROTATED_MICRO_TILING		3
+#       define SAMPLE_SPLIT(x)					((x) << 25)
+#              define	ADDR_SURF_SAMPLE_SPLIT_1		0
+#              define	ADDR_SURF_SAMPLE_SPLIT_2		1
+#              define	ADDR_SURF_SAMPLE_SPLIT_4		2
+#              define	ADDR_SURF_SAMPLE_SPLIT_8		3
+
+#define	GB_MACROTILE_MODE0					0x9990
+#       define BANK_WIDTH(x)					((x) << 0)
+#              define	ADDR_SURF_BANK_WIDTH_1			0
+#              define	ADDR_SURF_BANK_WIDTH_2			1
+#              define	ADDR_SURF_BANK_WIDTH_4			2
+#              define	ADDR_SURF_BANK_WIDTH_8			3
+#       define BANK_HEIGHT(x)					((x) << 2)
+#              define	ADDR_SURF_BANK_HEIGHT_1			0
+#              define	ADDR_SURF_BANK_HEIGHT_2			1
+#              define	ADDR_SURF_BANK_HEIGHT_4			2
+#              define	ADDR_SURF_BANK_HEIGHT_8			3
+#       define MACRO_TILE_ASPECT(x)				((x) << 4)
+#              define	ADDR_SURF_MACRO_ASPECT_1		0
+#              define	ADDR_SURF_MACRO_ASPECT_2		1
+#              define	ADDR_SURF_MACRO_ASPECT_4		2
+#              define	ADDR_SURF_MACRO_ASPECT_8		3
+#       define NUM_BANKS(x)					((x) << 6)
+#              define	ADDR_SURF_2_BANK			0
+#              define	ADDR_SURF_4_BANK			1
+#              define	ADDR_SURF_8_BANK			2
+#              define	ADDR_SURF_16_BANK			3
+
+#define	CB_HW_CONTROL					0x9A10
+
+#define	GC_USER_RB_BACKEND_DISABLE			0x9B7C
+#define		BACKEND_DISABLE_MASK			0x00FF0000
+#define		BACKEND_DISABLE_SHIFT			16
+
+#define	TCP_CHAN_STEER_LO				0xac0c
+#define	TCP_CHAN_STEER_HI				0xac10
+
+#define	TC_CFG_L1_LOAD_POLICY0				0xAC68
+#define	TC_CFG_L1_LOAD_POLICY1				0xAC6C
+#define	TC_CFG_L1_STORE_POLICY				0xAC70
+#define	TC_CFG_L2_LOAD_POLICY0				0xAC74
+#define	TC_CFG_L2_LOAD_POLICY1				0xAC78
+#define	TC_CFG_L2_STORE_POLICY0				0xAC7C
+#define	TC_CFG_L2_STORE_POLICY1				0xAC80
+#define	TC_CFG_L2_ATOMIC_POLICY				0xAC84
+#define	TC_CFG_L1_VOLATILE				0xAC88
+#define	TC_CFG_L2_VOLATILE				0xAC8C
+
+#define	CP_RB0_BASE					0xC100
+#define	CP_RB0_CNTL					0xC104
+#define		RB_BUFSZ(x)					((x) << 0)
+#define		RB_BLKSZ(x)					((x) << 8)
+#define		BUF_SWAP_32BIT					(2 << 16)
+#define		RB_NO_UPDATE					(1 << 27)
+#define		RB_RPTR_WR_ENA					(1 << 31)
+
+#define	CP_RB0_RPTR_ADDR				0xC10C
+#define		RB_RPTR_SWAP_32BIT				(2 << 0)
+#define	CP_RB0_RPTR_ADDR_HI				0xC110
+#define	CP_RB0_WPTR					0xC114
+
+#define	CP_DEVICE_ID					0xC12C
+#define	CP_ENDIAN_SWAP					0xC140
+#define	CP_RB_VMID					0xC144
+
+#define	CP_PFP_UCODE_ADDR				0xC150
+#define	CP_PFP_UCODE_DATA				0xC154
+#define	CP_ME_RAM_RADDR					0xC158
+#define	CP_ME_RAM_WADDR					0xC15C
+#define	CP_ME_RAM_DATA					0xC160
+
+#define	CP_CE_UCODE_ADDR				0xC168
+#define	CP_CE_UCODE_DATA				0xC16C
+#define	CP_MEC_ME1_UCODE_ADDR				0xC170
+#define	CP_MEC_ME1_UCODE_DATA				0xC174
+#define	CP_MEC_ME2_UCODE_ADDR				0xC178
+#define	CP_MEC_ME2_UCODE_DATA				0xC17C
+
+#define CP_INT_CNTL_RING0                               0xC1A8
+#       define CNTX_BUSY_INT_ENABLE                     (1 << 19)
+#       define CNTX_EMPTY_INT_ENABLE                    (1 << 20)
+#       define PRIV_INSTR_INT_ENABLE                    (1 << 22)
+#       define PRIV_REG_INT_ENABLE                      (1 << 23)
+#       define TIME_STAMP_INT_ENABLE                    (1 << 26)
+#       define CP_RINGID2_INT_ENABLE                    (1 << 29)
+#       define CP_RINGID1_INT_ENABLE                    (1 << 30)
+#       define CP_RINGID0_INT_ENABLE                    (1 << 31)
+
+#define CP_INT_STATUS_RING0                             0xC1B4
+#       define PRIV_INSTR_INT_STAT                      (1 << 22)
+#       define PRIV_REG_INT_STAT                        (1 << 23)
+#       define TIME_STAMP_INT_STAT                      (1 << 26)
+#       define CP_RINGID2_INT_STAT                      (1 << 29)
+#       define CP_RINGID1_INT_STAT                      (1 << 30)
+#       define CP_RINGID0_INT_STAT                      (1 << 31)
+
+#define CP_CPF_DEBUG                                    0xC200
+
+#define CP_PQ_WPTR_POLL_CNTL                            0xC20C
+#define		WPTR_POLL_EN      			(1 << 31)
+
+#define CP_ME1_PIPE0_INT_CNTL                           0xC214
+#define CP_ME1_PIPE1_INT_CNTL                           0xC218
+#define CP_ME1_PIPE2_INT_CNTL                           0xC21C
+#define CP_ME1_PIPE3_INT_CNTL                           0xC220
+#define CP_ME2_PIPE0_INT_CNTL                           0xC224
+#define CP_ME2_PIPE1_INT_CNTL                           0xC228
+#define CP_ME2_PIPE2_INT_CNTL                           0xC22C
+#define CP_ME2_PIPE3_INT_CNTL                           0xC230
+#       define DEQUEUE_REQUEST_INT_ENABLE               (1 << 13)
+#       define WRM_POLL_TIMEOUT_INT_ENABLE              (1 << 17)
+#       define PRIV_REG_INT_ENABLE                      (1 << 23)
+#       define TIME_STAMP_INT_ENABLE                    (1 << 26)
+#       define GENERIC2_INT_ENABLE                      (1 << 29)
+#       define GENERIC1_INT_ENABLE                      (1 << 30)
+#       define GENERIC0_INT_ENABLE                      (1 << 31)
+#define CP_ME1_PIPE0_INT_STATUS                         0xC214
+#define CP_ME1_PIPE1_INT_STATUS                         0xC218
+#define CP_ME1_PIPE2_INT_STATUS                         0xC21C
+#define CP_ME1_PIPE3_INT_STATUS                         0xC220
+#define CP_ME2_PIPE0_INT_STATUS                         0xC224
+#define CP_ME2_PIPE1_INT_STATUS                         0xC228
+#define CP_ME2_PIPE2_INT_STATUS                         0xC22C
+#define CP_ME2_PIPE3_INT_STATUS                         0xC230
+#       define DEQUEUE_REQUEST_INT_STATUS               (1 << 13)
+#       define WRM_POLL_TIMEOUT_INT_STATUS              (1 << 17)
+#       define PRIV_REG_INT_STATUS                      (1 << 23)
+#       define TIME_STAMP_INT_STATUS                    (1 << 26)
+#       define GENERIC2_INT_STATUS                      (1 << 29)
+#       define GENERIC1_INT_STATUS                      (1 << 30)
+#       define GENERIC0_INT_STATUS                      (1 << 31)
+
+#define	CP_MAX_CONTEXT					0xC2B8
+
+#define	CP_RB0_BASE_HI					0xC2C4
+
+#define RLC_CNTL                                          0xC300
+#       define RLC_ENABLE                                 (1 << 0)
+
+#define RLC_MC_CNTL                                       0xC30C
+
+#define RLC_LB_CNTR_MAX                                   0xC348
+
+#define RLC_LB_CNTL                                       0xC364
+
+#define RLC_LB_CNTR_INIT                                  0xC36C
+
+#define RLC_SAVE_AND_RESTORE_BASE                         0xC374
+#define RLC_DRIVER_DMA_STATUS                             0xC378
+
+#define RLC_GPM_UCODE_ADDR                                0xC388
+#define RLC_GPM_UCODE_DATA                                0xC38C
+#define RLC_GPU_CLOCK_COUNT_LSB                           0xC390
+#define RLC_GPU_CLOCK_COUNT_MSB                           0xC394
+#define RLC_CAPTURE_GPU_CLOCK_COUNT                       0xC398
+#define RLC_UCODE_CNTL                                    0xC39C
+
+#define RLC_CGCG_CGLS_CTRL                                0xC424
+
+#define RLC_LB_INIT_CU_MASK                               0xC43C
+
+#define RLC_LB_PARAMS                                     0xC444
+
+#define RLC_SERDES_CU_MASTER_BUSY                         0xC484
+#define RLC_SERDES_NONCU_MASTER_BUSY                      0xC488
+#       define SE_MASTER_BUSY_MASK                        0x0000ffff
+#       define GC_MASTER_BUSY                             (1 << 16)
+#       define TC0_MASTER_BUSY                            (1 << 17)
+#       define TC1_MASTER_BUSY                            (1 << 18)
+
+#define RLC_GPM_SCRATCH_ADDR                              0xC4B0
+#define RLC_GPM_SCRATCH_DATA                              0xC4B4
+
+#define CP_HPD_EOP_BASE_ADDR                              0xC904
+#define CP_HPD_EOP_BASE_ADDR_HI                           0xC908
+#define CP_HPD_EOP_VMID                                   0xC90C
+#define CP_HPD_EOP_CONTROL                                0xC910
+#define		EOP_SIZE(x)				((x) << 0)
+#define		EOP_SIZE_MASK      			(0x3f << 0)
+#define CP_MQD_BASE_ADDR                                  0xC914
+#define CP_MQD_BASE_ADDR_HI                               0xC918
+#define CP_HQD_ACTIVE                                     0xC91C
+#define CP_HQD_VMID                                       0xC920
+
+#define CP_HQD_PQ_BASE                                    0xC934
+#define CP_HQD_PQ_BASE_HI                                 0xC938
+#define CP_HQD_PQ_RPTR                                    0xC93C
+#define CP_HQD_PQ_RPTR_REPORT_ADDR                        0xC940
+#define CP_HQD_PQ_RPTR_REPORT_ADDR_HI                     0xC944
+#define CP_HQD_PQ_WPTR_POLL_ADDR                          0xC948
+#define CP_HQD_PQ_WPTR_POLL_ADDR_HI                       0xC94C
+#define CP_HQD_PQ_DOORBELL_CONTROL                        0xC950
+#define		DOORBELL_OFFSET(x)			((x) << 2)
+#define		DOORBELL_OFFSET_MASK			(0x1fffff << 2)
+#define		DOORBELL_SOURCE      			(1 << 28)
+#define		DOORBELL_SCHD_HIT      			(1 << 29)
+#define		DOORBELL_EN      			(1 << 30)
+#define		DOORBELL_HIT      			(1 << 31)
+#define CP_HQD_PQ_WPTR                                    0xC954
+#define CP_HQD_PQ_CONTROL                                 0xC958
+#define		QUEUE_SIZE(x)				((x) << 0)
+#define		QUEUE_SIZE_MASK      			(0x3f << 0)
+#define		RPTR_BLOCK_SIZE(x)			((x) << 8)
+#define		RPTR_BLOCK_SIZE_MASK			(0x3f << 8)
+#define		PQ_VOLATILE      			(1 << 26)
+#define		NO_UPDATE_RPTR      			(1 << 27)
+#define		UNORD_DISPATCH      			(1 << 28)
+#define		ROQ_PQ_IB_FLIP      			(1 << 29)
+#define		PRIV_STATE      			(1 << 30)
+#define		KMD_QUEUE      				(1 << 31)
+
+#define CP_HQD_DEQUEUE_REQUEST                          0xC974
+
+#define CP_MQD_CONTROL                                  0xC99C
+#define		MQD_VMID(x)				((x) << 0)
+#define		MQD_VMID_MASK      			(0xf << 0)
+
+#define PA_SC_RASTER_CONFIG                             0x28350
+#       define RASTER_CONFIG_RB_MAP_0                   0
+#       define RASTER_CONFIG_RB_MAP_1                   1
+#       define RASTER_CONFIG_RB_MAP_2                   2
+#       define RASTER_CONFIG_RB_MAP_3                   3
+
+#define VGT_EVENT_INITIATOR                             0x28a90
+#       define SAMPLE_STREAMOUTSTATS1                   (1 << 0)
+#       define SAMPLE_STREAMOUTSTATS2                   (2 << 0)
+#       define SAMPLE_STREAMOUTSTATS3                   (3 << 0)
+#       define CACHE_FLUSH_TS                           (4 << 0)
+#       define CACHE_FLUSH                              (6 << 0)
+#       define CS_PARTIAL_FLUSH                         (7 << 0)
+#       define VGT_STREAMOUT_RESET                      (10 << 0)
+#       define END_OF_PIPE_INCR_DE                      (11 << 0)
+#       define END_OF_PIPE_IB_END                       (12 << 0)
+#       define RST_PIX_CNT                              (13 << 0)
+#       define VS_PARTIAL_FLUSH                         (15 << 0)
+#       define PS_PARTIAL_FLUSH                         (16 << 0)
+#       define CACHE_FLUSH_AND_INV_TS_EVENT             (20 << 0)
+#       define ZPASS_DONE                               (21 << 0)
+#       define CACHE_FLUSH_AND_INV_EVENT                (22 << 0)
+#       define PERFCOUNTER_START                        (23 << 0)
+#       define PERFCOUNTER_STOP                         (24 << 0)
+#       define PIPELINESTAT_START                       (25 << 0)
+#       define PIPELINESTAT_STOP                        (26 << 0)
+#       define PERFCOUNTER_SAMPLE                       (27 << 0)
+#       define SAMPLE_PIPELINESTAT                      (30 << 0)
+#       define SO_VGT_STREAMOUT_FLUSH                   (31 << 0)
+#       define SAMPLE_STREAMOUTSTATS                    (32 << 0)
+#       define RESET_VTX_CNT                            (33 << 0)
+#       define VGT_FLUSH                                (36 << 0)
+#       define BOTTOM_OF_PIPE_TS                        (40 << 0)
+#       define DB_CACHE_FLUSH_AND_INV                   (42 << 0)
+#       define FLUSH_AND_INV_DB_DATA_TS                 (43 << 0)
+#       define FLUSH_AND_INV_DB_META                    (44 << 0)
+#       define FLUSH_AND_INV_CB_DATA_TS                 (45 << 0)
+#       define FLUSH_AND_INV_CB_META                    (46 << 0)
+#       define CS_DONE                                  (47 << 0)
+#       define PS_DONE                                  (48 << 0)
+#       define FLUSH_AND_INV_CB_PIXEL_DATA              (49 << 0)
+#       define THREAD_TRACE_START                       (51 << 0)
+#       define THREAD_TRACE_STOP                        (52 << 0)
+#       define THREAD_TRACE_FLUSH                       (54 << 0)
+#       define THREAD_TRACE_FINISH                      (55 << 0)
+#       define PIXEL_PIPE_STAT_CONTROL                  (56 << 0)
+#       define PIXEL_PIPE_STAT_DUMP                     (57 << 0)
+#       define PIXEL_PIPE_STAT_RESET                    (58 << 0)
+
+#define	SCRATCH_REG0					0x30100
+#define	SCRATCH_REG1					0x30104
+#define	SCRATCH_REG2					0x30108
+#define	SCRATCH_REG3					0x3010C
+#define	SCRATCH_REG4					0x30110
+#define	SCRATCH_REG5					0x30114
+#define	SCRATCH_REG6					0x30118
+#define	SCRATCH_REG7					0x3011C
+
+#define	SCRATCH_UMSK					0x30140
+#define	SCRATCH_ADDR					0x30144
+
+#define	CP_SEM_WAIT_TIMER				0x301BC
+
+#define	CP_SEM_INCOMPLETE_TIMER_CNTL			0x301C8
+
+#define	CP_WAIT_REG_MEM_TIMEOUT				0x301D0
+
+#define GRBM_GFX_INDEX          			0x30800
+#define		INSTANCE_INDEX(x)			((x) << 0)
+#define		SH_INDEX(x)     			((x) << 8)
+#define		SE_INDEX(x)     			((x) << 16)
+#define		SH_BROADCAST_WRITES      		(1 << 29)
+#define		INSTANCE_BROADCAST_WRITES      		(1 << 30)
+#define		SE_BROADCAST_WRITES      		(1 << 31)
+
+#define	VGT_ESGS_RING_SIZE				0x30900
+#define	VGT_GSVS_RING_SIZE				0x30904
+#define	VGT_PRIMITIVE_TYPE				0x30908
+#define	VGT_INDEX_TYPE					0x3090C
+
+#define	VGT_NUM_INDICES					0x30930
+#define	VGT_NUM_INSTANCES				0x30934
+#define	VGT_TF_RING_SIZE				0x30938
+#define	VGT_HS_OFFCHIP_PARAM				0x3093C
+#define	VGT_TF_MEMORY_BASE				0x30940
+
+#define	PA_SU_LINE_STIPPLE_VALUE			0x30a00
+#define	PA_SC_LINE_STIPPLE_STATE			0x30a04
+
+#define	SQC_CACHES					0x30d20
+
+#define	CP_PERFMON_CNTL					0x36020
+
+#define	CGTS_TCC_DISABLE				0x3c00c
+#define	CGTS_USER_TCC_DISABLE				0x3c010
+#define		TCC_DISABLE_MASK				0xFFFF0000
+#define		TCC_DISABLE_SHIFT				16
+
+#define	CB_CGTT_SCLK_CTRL				0x3c2a0
+
+/*
+ * PM4
+ */
+#define	PACKET_TYPE0	0
+#define	PACKET_TYPE1	1
+#define	PACKET_TYPE2	2
+#define	PACKET_TYPE3	3
+
+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
+#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2)
+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
+#define PACKET0(reg, n)	((PACKET_TYPE0 << 30) |				\
+			 (((reg) >> 2) & 0xFFFF) |			\
+			 ((n) & 0x3FFF) << 16)
+#define CP_PACKET2			0x80000000
+#define		PACKET2_PAD_SHIFT		0
+#define		PACKET2_PAD_MASK		(0x3fffffff << 0)
+
+#define PACKET2(v)	(CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
+
+#define PACKET3(op, n)	((PACKET_TYPE3 << 30) |				\
+			 (((op) & 0xFF) << 8) |				\
+			 ((n) & 0x3FFF) << 16)
+
+#define PACKET3_COMPUTE(op, n) (PACKET3(op, n) | 1 << 1)
+
+/* Packet 3 types */
+#define	PACKET3_NOP					0x10
+#define	PACKET3_SET_BASE				0x11
+#define		PACKET3_BASE_INDEX(x)                  ((x) << 0)
+#define			CE_PARTITION_BASE		3
+#define	PACKET3_CLEAR_STATE				0x12
+#define	PACKET3_INDEX_BUFFER_SIZE			0x13
+#define	PACKET3_DISPATCH_DIRECT				0x15
+#define	PACKET3_DISPATCH_INDIRECT			0x16
+#define	PACKET3_ATOMIC_GDS				0x1D
+#define	PACKET3_ATOMIC_MEM				0x1E
+#define	PACKET3_OCCLUSION_QUERY				0x1F
+#define	PACKET3_SET_PREDICATION				0x20
+#define	PACKET3_REG_RMW					0x21
+#define	PACKET3_COND_EXEC				0x22
+#define	PACKET3_PRED_EXEC				0x23
+#define	PACKET3_DRAW_INDIRECT				0x24
+#define	PACKET3_DRAW_INDEX_INDIRECT			0x25
+#define	PACKET3_INDEX_BASE				0x26
+#define	PACKET3_DRAW_INDEX_2				0x27
+#define	PACKET3_CONTEXT_CONTROL				0x28
+#define	PACKET3_INDEX_TYPE				0x2A
+#define	PACKET3_DRAW_INDIRECT_MULTI			0x2C
+#define	PACKET3_DRAW_INDEX_AUTO				0x2D
+#define	PACKET3_NUM_INSTANCES				0x2F
+#define	PACKET3_DRAW_INDEX_MULTI_AUTO			0x30
+#define	PACKET3_INDIRECT_BUFFER_CONST			0x33
+#define	PACKET3_STRMOUT_BUFFER_UPDATE			0x34
+#define	PACKET3_DRAW_INDEX_OFFSET_2			0x35
+#define	PACKET3_DRAW_PREAMBLE				0x36
+#define	PACKET3_WRITE_DATA				0x37
+#define		WRITE_DATA_DST_SEL(x)                   ((x) << 8)
+                /* 0 - register
+		 * 1 - memory (sync - via GRBM)
+		 * 2 - gl2
+		 * 3 - gds
+		 * 4 - reserved
+		 * 5 - memory (async - direct)
+		 */
+#define		WR_ONE_ADDR                             (1 << 16)
+#define		WR_CONFIRM                              (1 << 20)
+#define		WRITE_DATA_CACHE_POLICY(x)              ((x) << 25)
+                /* 0 - LRU
+		 * 1 - Stream
+		 */
+#define		WRITE_DATA_ENGINE_SEL(x)                ((x) << 30)
+                /* 0 - me
+		 * 1 - pfp
+		 * 2 - ce
+		 */
+#define	PACKET3_DRAW_INDEX_INDIRECT_MULTI		0x38
+#define	PACKET3_MEM_SEMAPHORE				0x39
+#              define PACKET3_SEM_USE_MAILBOX       (0x1 << 16)
+#              define PACKET3_SEM_SEL_SIGNAL_TYPE   (0x1 << 20) /* 0 = increment, 1 = write 1 */
+#              define PACKET3_SEM_CLIENT_CODE	    ((x) << 24) /* 0 = CP, 1 = CB, 2 = DB */
+#              define PACKET3_SEM_SEL_SIGNAL	    (0x6 << 29)
+#              define PACKET3_SEM_SEL_WAIT	    (0x7 << 29)
+#define	PACKET3_COPY_DW					0x3B
+#define	PACKET3_WAIT_REG_MEM				0x3C
+#define		WAIT_REG_MEM_FUNCTION(x)                ((x) << 0)
+                /* 0 - always
+		 * 1 - <
+		 * 2 - <=
+		 * 3 - ==
+		 * 4 - !=
+		 * 5 - >=
+		 * 6 - >
+		 */
+#define		WAIT_REG_MEM_MEM_SPACE(x)               ((x) << 4)
+                /* 0 - reg
+		 * 1 - mem
+		 */
+#define		WAIT_REG_MEM_OPERATION(x)               ((x) << 6)
+                /* 0 - wait_reg_mem
+		 * 1 - wr_wait_wr_reg
+		 */
+#define		WAIT_REG_MEM_ENGINE(x)                  ((x) << 8)
+                /* 0 - me
+		 * 1 - pfp
+		 */
+#define	PACKET3_INDIRECT_BUFFER				0x3F
+#define		INDIRECT_BUFFER_TCL2_VOLATILE           (1 << 22)
+#define		INDIRECT_BUFFER_VALID                   (1 << 23)
+#define		INDIRECT_BUFFER_CACHE_POLICY(x)         ((x) << 28)
+                /* 0 - LRU
+		 * 1 - Stream
+		 * 2 - Bypass
+		 */
+#define	PACKET3_COPY_DATA				0x40
+#define	PACKET3_PFP_SYNC_ME				0x42
+#define	PACKET3_SURFACE_SYNC				0x43
+#              define PACKET3_DEST_BASE_0_ENA      (1 << 0)
+#              define PACKET3_DEST_BASE_1_ENA      (1 << 1)
+#              define PACKET3_CB0_DEST_BASE_ENA    (1 << 6)
+#              define PACKET3_CB1_DEST_BASE_ENA    (1 << 7)
+#              define PACKET3_CB2_DEST_BASE_ENA    (1 << 8)
+#              define PACKET3_CB3_DEST_BASE_ENA    (1 << 9)
+#              define PACKET3_CB4_DEST_BASE_ENA    (1 << 10)
+#              define PACKET3_CB5_DEST_BASE_ENA    (1 << 11)
+#              define PACKET3_CB6_DEST_BASE_ENA    (1 << 12)
+#              define PACKET3_CB7_DEST_BASE_ENA    (1 << 13)
+#              define PACKET3_DB_DEST_BASE_ENA     (1 << 14)
+#              define PACKET3_TCL1_VOL_ACTION_ENA  (1 << 15)
+#              define PACKET3_TC_VOL_ACTION_ENA    (1 << 16) /* L2 */
+#              define PACKET3_TC_WB_ACTION_ENA     (1 << 18) /* L2 */
+#              define PACKET3_DEST_BASE_2_ENA      (1 << 19)
+#              define PACKET3_DEST_BASE_3_ENA      (1 << 21)
+#              define PACKET3_TCL1_ACTION_ENA      (1 << 22)
+#              define PACKET3_TC_ACTION_ENA        (1 << 23) /* L2 */
+#              define PACKET3_CB_ACTION_ENA        (1 << 25)
+#              define PACKET3_DB_ACTION_ENA        (1 << 26)
+#              define PACKET3_SH_KCACHE_ACTION_ENA (1 << 27)
+#              define PACKET3_SH_KCACHE_VOL_ACTION_ENA (1 << 28)
+#              define PACKET3_SH_ICACHE_ACTION_ENA (1 << 29)
+#define	PACKET3_COND_WRITE				0x45
+#define	PACKET3_EVENT_WRITE				0x46
+#define		EVENT_TYPE(x)                           ((x) << 0)
+#define		EVENT_INDEX(x)                          ((x) << 8)
+                /* 0 - any non-TS event
+		 * 1 - ZPASS_DONE, PIXEL_PIPE_STAT_*
+		 * 2 - SAMPLE_PIPELINESTAT
+		 * 3 - SAMPLE_STREAMOUTSTAT*
+		 * 4 - *S_PARTIAL_FLUSH
+		 * 5 - EOP events
+		 * 6 - EOS events
+		 */
+#define	PACKET3_EVENT_WRITE_EOP				0x47
+#define		EOP_TCL1_VOL_ACTION_EN                  (1 << 12)
+#define		EOP_TC_VOL_ACTION_EN                    (1 << 13) /* L2 */
+#define		EOP_TC_WB_ACTION_EN                     (1 << 15) /* L2 */
+#define		EOP_TCL1_ACTION_EN                      (1 << 16)
+#define		EOP_TC_ACTION_EN                        (1 << 17) /* L2 */
+#define		EOP_CACHE_POLICY(x)                     ((x) << 25)
+                /* 0 - LRU
+		 * 1 - Stream
+		 * 2 - Bypass
+		 */
+#define		EOP_TCL2_VOLATILE                       (1 << 27)
+#define		DATA_SEL(x)                             ((x) << 29)
+                /* 0 - discard
+		 * 1 - send low 32bit data
+		 * 2 - send 64bit data
+		 * 3 - send 64bit GPU counter value
+		 * 4 - send 64bit sys counter value
+		 */
+#define		INT_SEL(x)                              ((x) << 24)
+                /* 0 - none
+		 * 1 - interrupt only (DATA_SEL = 0)
+		 * 2 - interrupt when data write is confirmed
+		 */
+#define		DST_SEL(x)                              ((x) << 16)
+                /* 0 - MC
+		 * 1 - TC/L2
+		 */
+#define	PACKET3_EVENT_WRITE_EOS				0x48
+#define	PACKET3_RELEASE_MEM				0x49
+#define	PACKET3_PREAMBLE_CNTL				0x4A
+#              define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE     (2 << 28)
+#              define PACKET3_PREAMBLE_END_CLEAR_STATE       (3 << 28)
+#define	PACKET3_DMA_DATA				0x50
+#define	PACKET3_AQUIRE_MEM				0x58
+#define	PACKET3_REWIND					0x59
+#define	PACKET3_LOAD_UCONFIG_REG			0x5E
+#define	PACKET3_LOAD_SH_REG				0x5F
+#define	PACKET3_LOAD_CONFIG_REG				0x60
+#define	PACKET3_LOAD_CONTEXT_REG			0x61
+#define	PACKET3_SET_CONFIG_REG				0x68
+#define		PACKET3_SET_CONFIG_REG_START			0x00008000
+#define		PACKET3_SET_CONFIG_REG_END			0x0000b000
+#define	PACKET3_SET_CONTEXT_REG				0x69
+#define		PACKET3_SET_CONTEXT_REG_START			0x00028000
+#define		PACKET3_SET_CONTEXT_REG_END			0x00029000
+#define	PACKET3_SET_CONTEXT_REG_INDIRECT		0x73
+#define	PACKET3_SET_SH_REG				0x76
+#define		PACKET3_SET_SH_REG_START			0x0000b000
+#define		PACKET3_SET_SH_REG_END				0x0000c000
+#define	PACKET3_SET_SH_REG_OFFSET			0x77
+#define	PACKET3_SET_QUEUE_REG				0x78
+#define	PACKET3_SET_UCONFIG_REG				0x79
+#define		PACKET3_SET_UCONFIG_REG_START			0x00030000
+#define		PACKET3_SET_UCONFIG_REG_END			0x00031000
+#define	PACKET3_SCRATCH_RAM_WRITE			0x7D
+#define	PACKET3_SCRATCH_RAM_READ			0x7E
+#define	PACKET3_LOAD_CONST_RAM				0x80
+#define	PACKET3_WRITE_CONST_RAM				0x81
+#define	PACKET3_DUMP_CONST_RAM				0x83
+#define	PACKET3_INCREMENT_CE_COUNTER			0x84
+#define	PACKET3_INCREMENT_DE_COUNTER			0x85
+#define	PACKET3_WAIT_ON_CE_COUNTER			0x86
+#define	PACKET3_WAIT_ON_DE_COUNTER_DIFF			0x88
+#define	PACKET3_SWITCH_BUFFER				0x8B
+
+/* SDMA - first instance at 0xd000, second at 0xd800 */
+#define SDMA0_REGISTER_OFFSET                             0x0 /* not a register */
+#define SDMA1_REGISTER_OFFSET                             0x800 /* not a register */
+
+#define	SDMA0_UCODE_ADDR                                  0xD000
+#define	SDMA0_UCODE_DATA                                  0xD004
+
+#define SDMA0_CNTL                                        0xD010
+#       define TRAP_ENABLE                                (1 << 0)
+#       define SEM_INCOMPLETE_INT_ENABLE                  (1 << 1)
+#       define SEM_WAIT_INT_ENABLE                        (1 << 2)
+#       define DATA_SWAP_ENABLE                           (1 << 3)
+#       define FENCE_SWAP_ENABLE                          (1 << 4)
+#       define AUTO_CTXSW_ENABLE                          (1 << 18)
+#       define CTXEMPTY_INT_ENABLE                        (1 << 28)
+
+#define SDMA0_TILING_CONFIG  				  0xD018
+
+#define SDMA0_SEM_INCOMPLETE_TIMER_CNTL                   0xD020
+#define SDMA0_SEM_WAIT_FAIL_TIMER_CNTL                    0xD024
+
+#define SDMA0_STATUS_REG                                  0xd034
+#       define SDMA_IDLE                                  (1 << 0)
+
+#define SDMA0_ME_CNTL                                     0xD048
+#       define SDMA_HALT                                  (1 << 0)
+
+#define SDMA0_GFX_RB_CNTL                                 0xD200
+#       define SDMA_RB_ENABLE                             (1 << 0)
+#       define SDMA_RB_SIZE(x)                            ((x) << 1) /* log2 */
+#       define SDMA_RB_SWAP_ENABLE                        (1 << 9) /* 8IN32 */
+#       define SDMA_RPTR_WRITEBACK_ENABLE                 (1 << 12)
+#       define SDMA_RPTR_WRITEBACK_SWAP_ENABLE            (1 << 13)  /* 8IN32 */
+#       define SDMA_RPTR_WRITEBACK_TIMER(x)               ((x) << 16) /* log2 */
+#define SDMA0_GFX_RB_BASE                                 0xD204
+#define SDMA0_GFX_RB_BASE_HI                              0xD208
+#define SDMA0_GFX_RB_RPTR                                 0xD20C
+#define SDMA0_GFX_RB_WPTR                                 0xD210
+
+#define SDMA0_GFX_RB_RPTR_ADDR_HI                         0xD220
+#define SDMA0_GFX_RB_RPTR_ADDR_LO                         0xD224
+#define SDMA0_GFX_IB_CNTL                                 0xD228
+#       define SDMA_IB_ENABLE                             (1 << 0)
+#       define SDMA_IB_SWAP_ENABLE                        (1 << 4)
+#       define SDMA_SWITCH_INSIDE_IB                      (1 << 8)
+#       define SDMA_CMD_VMID(x)                           ((x) << 16)
+
+#define SDMA0_GFX_VIRTUAL_ADDR                            0xD29C
+#define SDMA0_GFX_APE1_CNTL                               0xD2A0
+
+#define SDMA_PACKET(op, sub_op, e)	((((e) & 0xFFFF) << 16) |	\
+					 (((sub_op) & 0xFF) << 8) |	\
+					 (((op) & 0xFF) << 0))
+/* sDMA opcodes */
+#define	SDMA_OPCODE_NOP					  0
+#define	SDMA_OPCODE_COPY				  1
+#       define SDMA_COPY_SUB_OPCODE_LINEAR                0
+#       define SDMA_COPY_SUB_OPCODE_TILED                 1
+#       define SDMA_COPY_SUB_OPCODE_SOA                   3
+#       define SDMA_COPY_SUB_OPCODE_LINEAR_SUB_WINDOW     4
+#       define SDMA_COPY_SUB_OPCODE_TILED_SUB_WINDOW      5
+#       define SDMA_COPY_SUB_OPCODE_T2T_SUB_WINDOW        6
+#define	SDMA_OPCODE_WRITE				  2
+#       define SDMA_WRITE_SUB_OPCODE_LINEAR               0
+#       define SDMA_WRTIE_SUB_OPCODE_TILED                1
+#define	SDMA_OPCODE_INDIRECT_BUFFER			  4
+#define	SDMA_OPCODE_FENCE				  5
+#define	SDMA_OPCODE_TRAP				  6
+#define	SDMA_OPCODE_SEMAPHORE				  7
+#       define SDMA_SEMAPHORE_EXTRA_O                     (1 << 13)
+                /* 0 - increment
+		 * 1 - write 1
+		 */
+#       define SDMA_SEMAPHORE_EXTRA_S                     (1 << 14)
+                /* 0 - wait
+		 * 1 - signal
+		 */
+#       define SDMA_SEMAPHORE_EXTRA_M                     (1 << 15)
+                /* mailbox */
+#define	SDMA_OPCODE_POLL_REG_MEM			  8
+#       define SDMA_POLL_REG_MEM_EXTRA_OP(x)              ((x) << 10)
+                /* 0 - wait_reg_mem
+		 * 1 - wr_wait_wr_reg
+		 */
+#       define SDMA_POLL_REG_MEM_EXTRA_FUNC(x)            ((x) << 12)
+                /* 0 - always
+		 * 1 - <
+		 * 2 - <=
+		 * 3 - ==
+		 * 4 - !=
+		 * 5 - >=
+		 * 6 - >
+		 */
+#       define SDMA_POLL_REG_MEM_EXTRA_M                  (1 << 15)
+                /* 0 = register
+		 * 1 = memory
+		 */
+#define	SDMA_OPCODE_COND_EXEC				  9
+#define	SDMA_OPCODE_CONSTANT_FILL			  11
+#       define SDMA_CONSTANT_FILL_EXTRA_SIZE(x)           ((x) << 14)
+                /* 0 = byte fill
+		 * 2 = DW fill
+		 */
+#define	SDMA_OPCODE_GENERATE_PTE_PDE			  12
+#define	SDMA_OPCODE_TIMESTAMP				  13
+#       define SDMA_TIMESTAMP_SUB_OPCODE_SET_LOCAL        0
+#       define SDMA_TIMESTAMP_SUB_OPCODE_GET_LOCAL        1
+#       define SDMA_TIMESTAMP_SUB_OPCODE_GET_GLOBAL       2
+#define	SDMA_OPCODE_SRBM_WRITE				  14
+#       define SDMA_SRBM_WRITE_EXTRA_BYTE_ENABLE(x)       ((x) << 12)
+                /* byte mask */
+
+/* UVD */
+
+#define UVD_UDEC_ADDR_CONFIG		0xef4c
+#define UVD_UDEC_DB_ADDR_CONFIG		0xef50
+#define UVD_UDEC_DBW_ADDR_CONFIG	0xef54
+
+#define UVD_LMI_EXT40_ADDR		0xf498
+#define UVD_LMI_ADDR_EXT		0xf594
+#define UVD_VCPU_CACHE_OFFSET0		0xf608
+#define UVD_VCPU_CACHE_SIZE0		0xf60c
+#define UVD_VCPU_CACHE_OFFSET1		0xf610
+#define UVD_VCPU_CACHE_SIZE1		0xf614
+#define UVD_VCPU_CACHE_OFFSET2		0xf618
+#define UVD_VCPU_CACHE_SIZE2		0xf61c
+
+#define UVD_RBC_RB_RPTR			0xf690
+#define UVD_RBC_RB_WPTR			0xf694
+
+/* UVD clocks */
+
+#define CG_DCLK_CNTL			0xC050009C
+#	define DCLK_DIVIDER_MASK	0x7f
+#	define DCLK_DIR_CNTL_EN		(1 << 8)
+#define CG_DCLK_STATUS			0xC05000A0
+#	define DCLK_STATUS		(1 << 0)
+#define CG_VCLK_CNTL			0xC05000A4
+#define CG_VCLK_STATUS			0xC05000A8
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cik_reg.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cik_reg.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cik_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cik_reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+#ifndef __CIK_REG_H__
+#define __CIK_REG_H__
+
+#define CIK_DC_GPIO_HPD_MASK                      0x65b0
+#define CIK_DC_GPIO_HPD_A                         0x65b4
+#define CIK_DC_GPIO_HPD_EN                        0x65b8
+#define CIK_DC_GPIO_HPD_Y                         0x65bc
+
+#define CIK_GRPH_CONTROL                          0x6804
+#       define CIK_GRPH_DEPTH(x)                  (((x) & 0x3) << 0)
+#       define CIK_GRPH_DEPTH_8BPP                0
+#       define CIK_GRPH_DEPTH_16BPP               1
+#       define CIK_GRPH_DEPTH_32BPP               2
+#       define CIK_GRPH_NUM_BANKS(x)              (((x) & 0x3) << 2)
+#       define CIK_ADDR_SURF_2_BANK               0
+#       define CIK_ADDR_SURF_4_BANK               1
+#       define CIK_ADDR_SURF_8_BANK               2
+#       define CIK_ADDR_SURF_16_BANK              3
+#       define CIK_GRPH_Z(x)                      (((x) & 0x3) << 4)
+#       define CIK_GRPH_BANK_WIDTH(x)             (((x) & 0x3) << 6)
+#       define CIK_ADDR_SURF_BANK_WIDTH_1         0
+#       define CIK_ADDR_SURF_BANK_WIDTH_2         1
+#       define CIK_ADDR_SURF_BANK_WIDTH_4         2
+#       define CIK_ADDR_SURF_BANK_WIDTH_8         3
+#       define CIK_GRPH_FORMAT(x)                 (((x) & 0x7) << 8)
+/* 8 BPP */
+#       define CIK_GRPH_FORMAT_INDEXED            0
+/* 16 BPP */
+#       define CIK_GRPH_FORMAT_ARGB1555           0
+#       define CIK_GRPH_FORMAT_ARGB565            1
+#       define CIK_GRPH_FORMAT_ARGB4444           2
+#       define CIK_GRPH_FORMAT_AI88               3
+#       define CIK_GRPH_FORMAT_MONO16             4
+#       define CIK_GRPH_FORMAT_BGRA5551           5
+/* 32 BPP */
+#       define CIK_GRPH_FORMAT_ARGB8888           0
+#       define CIK_GRPH_FORMAT_ARGB2101010        1
+#       define CIK_GRPH_FORMAT_32BPP_DIG          2
+#       define CIK_GRPH_FORMAT_8B_ARGB2101010     3
+#       define CIK_GRPH_FORMAT_BGRA1010102        4
+#       define CIK_GRPH_FORMAT_8B_BGRA1010102     5
+#       define CIK_GRPH_FORMAT_RGB111110          6
+#       define CIK_GRPH_FORMAT_BGR101111          7
+#       define CIK_GRPH_BANK_HEIGHT(x)            (((x) & 0x3) << 11)
+#       define CIK_ADDR_SURF_BANK_HEIGHT_1        0
+#       define CIK_ADDR_SURF_BANK_HEIGHT_2        1
+#       define CIK_ADDR_SURF_BANK_HEIGHT_4        2
+#       define CIK_ADDR_SURF_BANK_HEIGHT_8        3
+#       define CIK_GRPH_TILE_SPLIT(x)             (((x) & 0x7) << 13)
+#       define CIK_ADDR_SURF_TILE_SPLIT_64B       0
+#       define CIK_ADDR_SURF_TILE_SPLIT_128B      1
+#       define CIK_ADDR_SURF_TILE_SPLIT_256B      2
+#       define CIK_ADDR_SURF_TILE_SPLIT_512B      3
+#       define CIK_ADDR_SURF_TILE_SPLIT_1KB       4
+#       define CIK_ADDR_SURF_TILE_SPLIT_2KB       5
+#       define CIK_ADDR_SURF_TILE_SPLIT_4KB       6
+#       define CIK_GRPH_MACRO_TILE_ASPECT(x)      (((x) & 0x3) << 18)
+#       define CIK_ADDR_SURF_MACRO_TILE_ASPECT_1  0
+#       define CIK_ADDR_SURF_MACRO_TILE_ASPECT_2  1
+#       define CIK_ADDR_SURF_MACRO_TILE_ASPECT_4  2
+#       define CIK_ADDR_SURF_MACRO_TILE_ASPECT_8  3
+#       define CIK_GRPH_ARRAY_MODE(x)             (((x) & 0x7) << 20)
+#       define CIK_GRPH_ARRAY_LINEAR_GENERAL      0
+#       define CIK_GRPH_ARRAY_LINEAR_ALIGNED      1
+#       define CIK_GRPH_ARRAY_1D_TILED_THIN1      2
+#       define CIK_GRPH_ARRAY_2D_TILED_THIN1      4
+#       define CIK_GRPH_PIPE_CONFIG(x)		 (((x) & 0x1f) << 24)
+#       define CIK_ADDR_SURF_P2			 0
+#       define CIK_ADDR_SURF_P4_8x16		 4
+#       define CIK_ADDR_SURF_P4_16x16		 5
+#       define CIK_ADDR_SURF_P4_16x32		 6
+#       define CIK_ADDR_SURF_P4_32x32		 7
+#       define CIK_ADDR_SURF_P8_16x16_8x16	 8
+#       define CIK_ADDR_SURF_P8_16x32_8x16	 9
+#       define CIK_ADDR_SURF_P8_32x32_8x16	 10
+#       define CIK_ADDR_SURF_P8_16x32_16x16	 11
+#       define CIK_ADDR_SURF_P8_32x32_16x16	 12
+#       define CIK_ADDR_SURF_P8_32x32_16x32	 13
+#       define CIK_ADDR_SURF_P8_32x64_32x32	 14
+#       define CIK_GRPH_MICRO_TILE_MODE(x)       (((x) & 0x7) << 29)
+#       define CIK_DISPLAY_MICRO_TILING          0
+#       define CIK_THIN_MICRO_TILING             1
+#       define CIK_DEPTH_MICRO_TILING            2
+#       define CIK_ROTATED_MICRO_TILING          4
+
+/* CUR blocks at 0x6998, 0x7598, 0x10198, 0x10d98, 0x11998, 0x12598 */
+#define CIK_CUR_CONTROL                           0x6998
+#       define CIK_CURSOR_EN                      (1 << 0)
+#       define CIK_CURSOR_MODE(x)                 (((x) & 0x3) << 8)
+#       define CIK_CURSOR_MONO                    0
+#       define CIK_CURSOR_24_1                    1
+#       define CIK_CURSOR_24_8_PRE_MULT           2
+#       define CIK_CURSOR_24_8_UNPRE_MULT         3
+#       define CIK_CURSOR_2X_MAGNIFY              (1 << 16)
+#       define CIK_CURSOR_FORCE_MC_ON             (1 << 20)
+#       define CIK_CURSOR_URGENT_CONTROL(x)       (((x) & 0x7) << 24)
+#       define CIK_CURSOR_URGENT_ALWAYS           0
+#       define CIK_CURSOR_URGENT_1_8              1
+#       define CIK_CURSOR_URGENT_1_4              2
+#       define CIK_CURSOR_URGENT_3_8              3
+#       define CIK_CURSOR_URGENT_1_2              4
+#define CIK_CUR_SURFACE_ADDRESS                   0x699c
+#       define CIK_CUR_SURFACE_ADDRESS_MASK       0xfffff000
+#define CIK_CUR_SIZE                              0x69a0
+#define CIK_CUR_SURFACE_ADDRESS_HIGH              0x69a4
+#define CIK_CUR_POSITION                          0x69a8
+#define CIK_CUR_HOT_SPOT                          0x69ac
+#define CIK_CUR_COLOR1                            0x69b0
+#define CIK_CUR_COLOR2                            0x69b4
+#define CIK_CUR_UPDATE                            0x69b8
+#       define CIK_CURSOR_UPDATE_PENDING          (1 << 0)
+#       define CIK_CURSOR_UPDATE_TAKEN            (1 << 1)
+#       define CIK_CURSOR_UPDATE_LOCK             (1 << 16)
+#       define CIK_CURSOR_DISABLE_MULTIPLE_UPDATE (1 << 24)
+
+#define CIK_ALPHA_CONTROL                         0x6af0
+#       define CIK_CURSOR_ALPHA_BLND_ENA          (1 << 1)
+
+#define CIK_LB_DATA_FORMAT                        0x6b00
+#       define CIK_INTERLEAVE_EN                  (1 << 3)
+
+#define CIK_LB_DESKTOP_HEIGHT                     0x6b0c
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/clearstate_cayman.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/clearstate_cayman.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/clearstate_cayman.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/clearstate_cayman.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1081 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ */
+
+static const u32 SECT_CONTEXT_def_1[] =
+{
+    0x00000000, // DB_RENDER_CONTROL
+    0x00000000, // DB_COUNT_CONTROL
+    0x00000000, // DB_DEPTH_VIEW
+    0x00000000, // DB_RENDER_OVERRIDE
+    0x00000000, // DB_RENDER_OVERRIDE2
+    0x00000000, // DB_HTILE_DATA_BASE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // DB_STENCIL_CLEAR
+    0x00000000, // DB_DEPTH_CLEAR
+    0x00000000, // PA_SC_SCREEN_SCISSOR_TL
+    0x40004000, // PA_SC_SCREEN_SCISSOR_BR
+    0, // HOLE
+    0x00000000, // DB_DEPTH_INFO
+    0x00000000, // DB_Z_INFO
+    0x00000000, // DB_STENCIL_INFO
+    0x00000000, // DB_Z_READ_BASE
+    0x00000000, // DB_STENCIL_READ_BASE
+    0x00000000, // DB_Z_WRITE_BASE
+    0x00000000, // DB_STENCIL_WRITE_BASE
+    0x00000000, // DB_DEPTH_SIZE
+    0x00000000, // DB_DEPTH_SLICE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_15
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_15
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_15
+    0x00000000, // PA_SC_WINDOW_OFFSET
+    0x80000000, // PA_SC_WINDOW_SCISSOR_TL
+    0x40004000, // PA_SC_WINDOW_SCISSOR_BR
+    0x0000ffff, // PA_SC_CLIPRECT_RULE
+    0x00000000, // PA_SC_CLIPRECT_0_TL
+    0x40004000, // PA_SC_CLIPRECT_0_BR
+    0x00000000, // PA_SC_CLIPRECT_1_TL
+    0x40004000, // PA_SC_CLIPRECT_1_BR
+    0x00000000, // PA_SC_CLIPRECT_2_TL
+    0x40004000, // PA_SC_CLIPRECT_2_BR
+    0x00000000, // PA_SC_CLIPRECT_3_TL
+    0x40004000, // PA_SC_CLIPRECT_3_BR
+    0xaa99aaaa, // PA_SC_EDGERULE
+    0x00000000, // PA_SU_HARDWARE_SCREEN_OFFSET
+    0xffffffff, // CB_TARGET_MASK
+    0xffffffff, // CB_SHADER_MASK
+    0x80000000, // PA_SC_GENERIC_SCISSOR_TL
+    0x40004000, // PA_SC_GENERIC_SCISSOR_BR
+    0x00000000, // COHER_DEST_BASE_0
+    0x00000000, // COHER_DEST_BASE_1
+    0x80000000, // PA_SC_VPORT_SCISSOR_0_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_0_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_1_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_1_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_2_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_2_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_3_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_3_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_4_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_4_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_5_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_5_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_6_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_6_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_7_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_7_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_8_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_8_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_9_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_9_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_10_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_10_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_11_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_11_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_12_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_12_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_13_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_13_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_14_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_14_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_15_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_15_BR
+    0x00000000, // PA_SC_VPORT_ZMIN_0
+    0x3f800000, // PA_SC_VPORT_ZMAX_0
+    0x00000000, // PA_SC_VPORT_ZMIN_1
+    0x3f800000, // PA_SC_VPORT_ZMAX_1
+    0x00000000, // PA_SC_VPORT_ZMIN_2
+    0x3f800000, // PA_SC_VPORT_ZMAX_2
+    0x00000000, // PA_SC_VPORT_ZMIN_3
+    0x3f800000, // PA_SC_VPORT_ZMAX_3
+    0x00000000, // PA_SC_VPORT_ZMIN_4
+    0x3f800000, // PA_SC_VPORT_ZMAX_4
+    0x00000000, // PA_SC_VPORT_ZMIN_5
+    0x3f800000, // PA_SC_VPORT_ZMAX_5
+    0x00000000, // PA_SC_VPORT_ZMIN_6
+    0x3f800000, // PA_SC_VPORT_ZMAX_6
+    0x00000000, // PA_SC_VPORT_ZMIN_7
+    0x3f800000, // PA_SC_VPORT_ZMAX_7
+    0x00000000, // PA_SC_VPORT_ZMIN_8
+    0x3f800000, // PA_SC_VPORT_ZMAX_8
+    0x00000000, // PA_SC_VPORT_ZMIN_9
+    0x3f800000, // PA_SC_VPORT_ZMAX_9
+    0x00000000, // PA_SC_VPORT_ZMIN_10
+    0x3f800000, // PA_SC_VPORT_ZMAX_10
+    0x00000000, // PA_SC_VPORT_ZMIN_11
+    0x3f800000, // PA_SC_VPORT_ZMAX_11
+    0x00000000, // PA_SC_VPORT_ZMIN_12
+    0x3f800000, // PA_SC_VPORT_ZMAX_12
+    0x00000000, // PA_SC_VPORT_ZMIN_13
+    0x3f800000, // PA_SC_VPORT_ZMAX_13
+    0x00000000, // PA_SC_VPORT_ZMIN_14
+    0x3f800000, // PA_SC_VPORT_ZMAX_14
+    0x00000000, // PA_SC_VPORT_ZMIN_15
+    0x3f800000, // PA_SC_VPORT_ZMAX_15
+    0x00000000, // SX_MISC
+    0x00000000, // SX_SURFACE_SYNC
+    0x00000000, // SX_SCATTER_EXPORT_BASE
+    0x00000000, // SX_SCATTER_EXPORT_SIZE
+    0x00000000, // CP_PERFMON_CNTX_CNTL
+    0x00000000, // CP_RINGID
+    0x00000000, // CP_VMID
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_VTX_SEMANTIC_0
+    0x00000000, // SQ_VTX_SEMANTIC_1
+    0x00000000, // SQ_VTX_SEMANTIC_2
+    0x00000000, // SQ_VTX_SEMANTIC_3
+    0x00000000, // SQ_VTX_SEMANTIC_4
+    0x00000000, // SQ_VTX_SEMANTIC_5
+    0x00000000, // SQ_VTX_SEMANTIC_6
+    0x00000000, // SQ_VTX_SEMANTIC_7
+    0x00000000, // SQ_VTX_SEMANTIC_8
+    0x00000000, // SQ_VTX_SEMANTIC_9
+    0x00000000, // SQ_VTX_SEMANTIC_10
+    0x00000000, // SQ_VTX_SEMANTIC_11
+    0x00000000, // SQ_VTX_SEMANTIC_12
+    0x00000000, // SQ_VTX_SEMANTIC_13
+    0x00000000, // SQ_VTX_SEMANTIC_14
+    0x00000000, // SQ_VTX_SEMANTIC_15
+    0x00000000, // SQ_VTX_SEMANTIC_16
+    0x00000000, // SQ_VTX_SEMANTIC_17
+    0x00000000, // SQ_VTX_SEMANTIC_18
+    0x00000000, // SQ_VTX_SEMANTIC_19
+    0x00000000, // SQ_VTX_SEMANTIC_20
+    0x00000000, // SQ_VTX_SEMANTIC_21
+    0x00000000, // SQ_VTX_SEMANTIC_22
+    0x00000000, // SQ_VTX_SEMANTIC_23
+    0x00000000, // SQ_VTX_SEMANTIC_24
+    0x00000000, // SQ_VTX_SEMANTIC_25
+    0x00000000, // SQ_VTX_SEMANTIC_26
+    0x00000000, // SQ_VTX_SEMANTIC_27
+    0x00000000, // SQ_VTX_SEMANTIC_28
+    0x00000000, // SQ_VTX_SEMANTIC_29
+    0x00000000, // SQ_VTX_SEMANTIC_30
+    0x00000000, // SQ_VTX_SEMANTIC_31
+    0xffffffff, // VGT_MAX_VTX_INDX
+    0x00000000, // VGT_MIN_VTX_INDX
+    0x00000000, // VGT_INDX_OFFSET
+    0x00000000, // VGT_MULTI_PRIM_IB_RESET_INDX
+    0x00000000, // SX_ALPHA_TEST_CONTROL
+    0x00000000, // CB_BLEND_RED
+    0x00000000, // CB_BLEND_GREEN
+    0x00000000, // CB_BLEND_BLUE
+    0x00000000, // CB_BLEND_ALPHA
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // DB_STENCILREFMASK
+    0x00000000, // DB_STENCILREFMASK_BF
+    0x00000000, // SX_ALPHA_REF
+    0x00000000, // PA_CL_VPORT_XSCALE
+    0x00000000, // PA_CL_VPORT_XOFFSET
+    0x00000000, // PA_CL_VPORT_YSCALE
+    0x00000000, // PA_CL_VPORT_YOFFSET
+    0x00000000, // PA_CL_VPORT_ZSCALE
+    0x00000000, // PA_CL_VPORT_ZOFFSET
+    0x00000000, // PA_CL_VPORT_XSCALE_1
+    0x00000000, // PA_CL_VPORT_XOFFSET_1
+    0x00000000, // PA_CL_VPORT_YSCALE_1
+    0x00000000, // PA_CL_VPORT_YOFFSET_1
+    0x00000000, // PA_CL_VPORT_ZSCALE_1
+    0x00000000, // PA_CL_VPORT_ZOFFSET_1
+    0x00000000, // PA_CL_VPORT_XSCALE_2
+    0x00000000, // PA_CL_VPORT_XOFFSET_2
+    0x00000000, // PA_CL_VPORT_YSCALE_2
+    0x00000000, // PA_CL_VPORT_YOFFSET_2
+    0x00000000, // PA_CL_VPORT_ZSCALE_2
+    0x00000000, // PA_CL_VPORT_ZOFFSET_2
+    0x00000000, // PA_CL_VPORT_XSCALE_3
+    0x00000000, // PA_CL_VPORT_XOFFSET_3
+    0x00000000, // PA_CL_VPORT_YSCALE_3
+    0x00000000, // PA_CL_VPORT_YOFFSET_3
+    0x00000000, // PA_CL_VPORT_ZSCALE_3
+    0x00000000, // PA_CL_VPORT_ZOFFSET_3
+    0x00000000, // PA_CL_VPORT_XSCALE_4
+    0x00000000, // PA_CL_VPORT_XOFFSET_4
+    0x00000000, // PA_CL_VPORT_YSCALE_4
+    0x00000000, // PA_CL_VPORT_YOFFSET_4
+    0x00000000, // PA_CL_VPORT_ZSCALE_4
+    0x00000000, // PA_CL_VPORT_ZOFFSET_4
+    0x00000000, // PA_CL_VPORT_XSCALE_5
+    0x00000000, // PA_CL_VPORT_XOFFSET_5
+    0x00000000, // PA_CL_VPORT_YSCALE_5
+    0x00000000, // PA_CL_VPORT_YOFFSET_5
+    0x00000000, // PA_CL_VPORT_ZSCALE_5
+    0x00000000, // PA_CL_VPORT_ZOFFSET_5
+    0x00000000, // PA_CL_VPORT_XSCALE_6
+    0x00000000, // PA_CL_VPORT_XOFFSET_6
+    0x00000000, // PA_CL_VPORT_YSCALE_6
+    0x00000000, // PA_CL_VPORT_YOFFSET_6
+    0x00000000, // PA_CL_VPORT_ZSCALE_6
+    0x00000000, // PA_CL_VPORT_ZOFFSET_6
+    0x00000000, // PA_CL_VPORT_XSCALE_7
+    0x00000000, // PA_CL_VPORT_XOFFSET_7
+    0x00000000, // PA_CL_VPORT_YSCALE_7
+    0x00000000, // PA_CL_VPORT_YOFFSET_7
+    0x00000000, // PA_CL_VPORT_ZSCALE_7
+    0x00000000, // PA_CL_VPORT_ZOFFSET_7
+    0x00000000, // PA_CL_VPORT_XSCALE_8
+    0x00000000, // PA_CL_VPORT_XOFFSET_8
+    0x00000000, // PA_CL_VPORT_YSCALE_8
+    0x00000000, // PA_CL_VPORT_YOFFSET_8
+    0x00000000, // PA_CL_VPORT_ZSCALE_8
+    0x00000000, // PA_CL_VPORT_ZOFFSET_8
+    0x00000000, // PA_CL_VPORT_XSCALE_9
+    0x00000000, // PA_CL_VPORT_XOFFSET_9
+    0x00000000, // PA_CL_VPORT_YSCALE_9
+    0x00000000, // PA_CL_VPORT_YOFFSET_9
+    0x00000000, // PA_CL_VPORT_ZSCALE_9
+    0x00000000, // PA_CL_VPORT_ZOFFSET_9
+    0x00000000, // PA_CL_VPORT_XSCALE_10
+    0x00000000, // PA_CL_VPORT_XOFFSET_10
+    0x00000000, // PA_CL_VPORT_YSCALE_10
+    0x00000000, // PA_CL_VPORT_YOFFSET_10
+    0x00000000, // PA_CL_VPORT_ZSCALE_10
+    0x00000000, // PA_CL_VPORT_ZOFFSET_10
+    0x00000000, // PA_CL_VPORT_XSCALE_11
+    0x00000000, // PA_CL_VPORT_XOFFSET_11
+    0x00000000, // PA_CL_VPORT_YSCALE_11
+    0x00000000, // PA_CL_VPORT_YOFFSET_11
+    0x00000000, // PA_CL_VPORT_ZSCALE_11
+    0x00000000, // PA_CL_VPORT_ZOFFSET_11
+    0x00000000, // PA_CL_VPORT_XSCALE_12
+    0x00000000, // PA_CL_VPORT_XOFFSET_12
+    0x00000000, // PA_CL_VPORT_YSCALE_12
+    0x00000000, // PA_CL_VPORT_YOFFSET_12
+    0x00000000, // PA_CL_VPORT_ZSCALE_12
+    0x00000000, // PA_CL_VPORT_ZOFFSET_12
+    0x00000000, // PA_CL_VPORT_XSCALE_13
+    0x00000000, // PA_CL_VPORT_XOFFSET_13
+    0x00000000, // PA_CL_VPORT_YSCALE_13
+    0x00000000, // PA_CL_VPORT_YOFFSET_13
+    0x00000000, // PA_CL_VPORT_ZSCALE_13
+    0x00000000, // PA_CL_VPORT_ZOFFSET_13
+    0x00000000, // PA_CL_VPORT_XSCALE_14
+    0x00000000, // PA_CL_VPORT_XOFFSET_14
+    0x00000000, // PA_CL_VPORT_YSCALE_14
+    0x00000000, // PA_CL_VPORT_YOFFSET_14
+    0x00000000, // PA_CL_VPORT_ZSCALE_14
+    0x00000000, // PA_CL_VPORT_ZOFFSET_14
+    0x00000000, // PA_CL_VPORT_XSCALE_15
+    0x00000000, // PA_CL_VPORT_XOFFSET_15
+    0x00000000, // PA_CL_VPORT_YSCALE_15
+    0x00000000, // PA_CL_VPORT_YOFFSET_15
+    0x00000000, // PA_CL_VPORT_ZSCALE_15
+    0x00000000, // PA_CL_VPORT_ZOFFSET_15
+    0x00000000, // PA_CL_UCP_0_X
+    0x00000000, // PA_CL_UCP_0_Y
+    0x00000000, // PA_CL_UCP_0_Z
+    0x00000000, // PA_CL_UCP_0_W
+    0x00000000, // PA_CL_UCP_1_X
+    0x00000000, // PA_CL_UCP_1_Y
+    0x00000000, // PA_CL_UCP_1_Z
+    0x00000000, // PA_CL_UCP_1_W
+    0x00000000, // PA_CL_UCP_2_X
+    0x00000000, // PA_CL_UCP_2_Y
+    0x00000000, // PA_CL_UCP_2_Z
+    0x00000000, // PA_CL_UCP_2_W
+    0x00000000, // PA_CL_UCP_3_X
+    0x00000000, // PA_CL_UCP_3_Y
+    0x00000000, // PA_CL_UCP_3_Z
+    0x00000000, // PA_CL_UCP_3_W
+    0x00000000, // PA_CL_UCP_4_X
+    0x00000000, // PA_CL_UCP_4_Y
+    0x00000000, // PA_CL_UCP_4_Z
+    0x00000000, // PA_CL_UCP_4_W
+    0x00000000, // PA_CL_UCP_5_X
+    0x00000000, // PA_CL_UCP_5_Y
+    0x00000000, // PA_CL_UCP_5_Z
+    0x00000000, // PA_CL_UCP_5_W
+    0x00000000, // SPI_VS_OUT_ID_0
+    0x00000000, // SPI_VS_OUT_ID_1
+    0x00000000, // SPI_VS_OUT_ID_2
+    0x00000000, // SPI_VS_OUT_ID_3
+    0x00000000, // SPI_VS_OUT_ID_4
+    0x00000000, // SPI_VS_OUT_ID_5
+    0x00000000, // SPI_VS_OUT_ID_6
+    0x00000000, // SPI_VS_OUT_ID_7
+    0x00000000, // SPI_VS_OUT_ID_8
+    0x00000000, // SPI_VS_OUT_ID_9
+    0x00000000, // SPI_PS_INPUT_CNTL_0
+    0x00000000, // SPI_PS_INPUT_CNTL_1
+    0x00000000, // SPI_PS_INPUT_CNTL_2
+    0x00000000, // SPI_PS_INPUT_CNTL_3
+    0x00000000, // SPI_PS_INPUT_CNTL_4
+    0x00000000, // SPI_PS_INPUT_CNTL_5
+    0x00000000, // SPI_PS_INPUT_CNTL_6
+    0x00000000, // SPI_PS_INPUT_CNTL_7
+    0x00000000, // SPI_PS_INPUT_CNTL_8
+    0x00000000, // SPI_PS_INPUT_CNTL_9
+    0x00000000, // SPI_PS_INPUT_CNTL_10
+    0x00000000, // SPI_PS_INPUT_CNTL_11
+    0x00000000, // SPI_PS_INPUT_CNTL_12
+    0x00000000, // SPI_PS_INPUT_CNTL_13
+    0x00000000, // SPI_PS_INPUT_CNTL_14
+    0x00000000, // SPI_PS_INPUT_CNTL_15
+    0x00000000, // SPI_PS_INPUT_CNTL_16
+    0x00000000, // SPI_PS_INPUT_CNTL_17
+    0x00000000, // SPI_PS_INPUT_CNTL_18
+    0x00000000, // SPI_PS_INPUT_CNTL_19
+    0x00000000, // SPI_PS_INPUT_CNTL_20
+    0x00000000, // SPI_PS_INPUT_CNTL_21
+    0x00000000, // SPI_PS_INPUT_CNTL_22
+    0x00000000, // SPI_PS_INPUT_CNTL_23
+    0x00000000, // SPI_PS_INPUT_CNTL_24
+    0x00000000, // SPI_PS_INPUT_CNTL_25
+    0x00000000, // SPI_PS_INPUT_CNTL_26
+    0x00000000, // SPI_PS_INPUT_CNTL_27
+    0x00000000, // SPI_PS_INPUT_CNTL_28
+    0x00000000, // SPI_PS_INPUT_CNTL_29
+    0x00000000, // SPI_PS_INPUT_CNTL_30
+    0x00000000, // SPI_PS_INPUT_CNTL_31
+    0x00000000, // SPI_VS_OUT_CONFIG
+    0x00000001, // SPI_THREAD_GROUPING
+    0x00000002, // SPI_PS_IN_CONTROL_0
+    0x00000000, // SPI_PS_IN_CONTROL_1
+    0x00000000, // SPI_INTERP_CONTROL_0
+    0x00000000, // SPI_INPUT_Z
+    0x00000000, // SPI_FOG_CNTL
+    0x00000000, // SPI_BARYC_CNTL
+    0x00000000, // SPI_PS_IN_CONTROL_2
+    0x00000000, // SPI_COMPUTE_INPUT_CNTL
+    0x00000000, // SPI_COMPUTE_NUM_THREAD_X
+    0x00000000, // SPI_COMPUTE_NUM_THREAD_Y
+    0x00000000, // SPI_COMPUTE_NUM_THREAD_Z
+    0x00000000, // SPI_GPR_MGMT
+    0x00000000, // SPI_LDS_MGMT
+    0x00000000, // SPI_STACK_MGMT
+    0x00000000, // SPI_WAVE_MGMT_1
+    0x00000000, // SPI_WAVE_MGMT_2
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // GDS_ADDR_BASE
+    0x00003fff, // GDS_ADDR_SIZE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // GDS_ORDERED_COUNT
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // GDS_APPEND_CONSUME_UAV0
+    0x00000000, // GDS_APPEND_CONSUME_UAV1
+    0x00000000, // GDS_APPEND_CONSUME_UAV2
+    0x00000000, // GDS_APPEND_CONSUME_UAV3
+    0x00000000, // GDS_APPEND_CONSUME_UAV4
+    0x00000000, // GDS_APPEND_CONSUME_UAV5
+    0x00000000, // GDS_APPEND_CONSUME_UAV6
+    0x00000000, // GDS_APPEND_CONSUME_UAV7
+    0x00000000, // GDS_APPEND_CONSUME_UAV8
+    0x00000000, // GDS_APPEND_CONSUME_UAV9
+    0x00000000, // GDS_APPEND_CONSUME_UAV10
+    0x00000000, // GDS_APPEND_CONSUME_UAV11
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_BLEND0_CONTROL
+    0x00000000, // CB_BLEND1_CONTROL
+    0x00000000, // CB_BLEND2_CONTROL
+    0x00000000, // CB_BLEND3_CONTROL
+    0x00000000, // CB_BLEND4_CONTROL
+    0x00000000, // CB_BLEND5_CONTROL
+    0x00000000, // CB_BLEND6_CONTROL
+    0x00000000, // CB_BLEND7_CONTROL
+};
+static const u32 SECT_CONTEXT_def_2[] =
+{
+    0x00000000, // PA_CL_POINT_X_RAD
+    0x00000000, // PA_CL_POINT_Y_RAD
+    0x00000000, // PA_CL_POINT_SIZE
+    0x00000000, // PA_CL_POINT_CULL_RAD
+    0x00000000, // VGT_DMA_BASE_HI
+    0x00000000, // VGT_DMA_BASE
+};
+static const u32 SECT_CONTEXT_def_3[] =
+{
+    0x00000000, // DB_DEPTH_CONTROL
+    0x00000000, // DB_EQAA
+    0x00000000, // CB_COLOR_CONTROL
+    0x00000200, // DB_SHADER_CONTROL
+    0x00000000, // PA_CL_CLIP_CNTL
+    0x00000000, // PA_SU_SC_MODE_CNTL
+    0x00000000, // PA_CL_VTE_CNTL
+    0x00000000, // PA_CL_VS_OUT_CNTL
+    0x00000000, // PA_CL_NANINF_CNTL
+    0x00000000, // PA_SU_LINE_STIPPLE_CNTL
+    0x00000000, // PA_SU_LINE_STIPPLE_SCALE
+    0x00000000, // PA_SU_PRIM_FILTER_CNTL
+    0x00000000, // SQ_LSTMP_RING_ITEMSIZE
+    0x00000000, // SQ_HSTMP_RING_ITEMSIZE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_PS
+    0x00000000, // SQ_PGM_RESOURCES_PS
+    0x00000000, // SQ_PGM_RESOURCES_2_PS
+    0x00000000, // SQ_PGM_EXPORTS_PS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_VS
+    0x00000000, // SQ_PGM_RESOURCES_VS
+    0x00000000, // SQ_PGM_RESOURCES_2_VS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_GS
+    0x00000000, // SQ_PGM_RESOURCES_GS
+    0x00000000, // SQ_PGM_RESOURCES_2_GS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_ES
+    0x00000000, // SQ_PGM_RESOURCES_ES
+    0x00000000, // SQ_PGM_RESOURCES_2_ES
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_FS
+    0x00000000, // SQ_PGM_RESOURCES_FS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_HS
+    0x00000000, // SQ_PGM_RESOURCES_HS
+    0x00000000, // SQ_PGM_RESOURCES_2_HS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_LS
+    0x00000000, // SQ_PGM_RESOURCES_LS
+    0x00000000, // SQ_PGM_RESOURCES_2_LS
+};
+static const u32 SECT_CONTEXT_def_4[] =
+{
+    0x00000000, // SQ_LDS_ALLOC
+    0x00000000, // SQ_LDS_ALLOC_PS
+    0x00000000, // SQ_VTX_SEMANTIC_CLEAR
+    0, // HOLE
+    0x00000000, // SQ_THREAD_TRACE_CTRL
+    0, // HOLE
+    0x00000000, // SQ_ESGS_RING_ITEMSIZE
+    0x00000000, // SQ_GSVS_RING_ITEMSIZE
+    0x00000000, // SQ_ESTMP_RING_ITEMSIZE
+    0x00000000, // SQ_GSTMP_RING_ITEMSIZE
+    0x00000000, // SQ_VSTMP_RING_ITEMSIZE
+    0x00000000, // SQ_PSTMP_RING_ITEMSIZE
+    0, // HOLE
+    0x00000000, // SQ_GS_VERT_ITEMSIZE
+    0x00000000, // SQ_GS_VERT_ITEMSIZE_1
+    0x00000000, // SQ_GS_VERT_ITEMSIZE_2
+    0x00000000, // SQ_GS_VERT_ITEMSIZE_3
+    0x00000000, // SQ_GSVS_RING_OFFSET_1
+    0x00000000, // SQ_GSVS_RING_OFFSET_2
+    0x00000000, // SQ_GSVS_RING_OFFSET_3
+    0x00000000, // SQ_GWS_RING_OFFSET
+    0, // HOLE
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_15
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_15
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_15
+    0x00000000, // PA_SU_POINT_SIZE
+    0x00000000, // PA_SU_POINT_MINMAX
+    0x00000000, // PA_SU_LINE_CNTL
+    0x00000000, // PA_SC_LINE_STIPPLE
+    0x00000000, // VGT_OUTPUT_PATH_CNTL
+    0x00000000, // VGT_HOS_CNTL
+    0x00000000, // VGT_HOS_MAX_TESS_LEVEL
+    0x00000000, // VGT_HOS_MIN_TESS_LEVEL
+    0x00000000, // VGT_HOS_REUSE_DEPTH
+    0x00000000, // VGT_GROUP_PRIM_TYPE
+    0x00000000, // VGT_GROUP_FIRST_DECR
+    0x00000000, // VGT_GROUP_DECR
+    0x00000000, // VGT_GROUP_VECT_0_CNTL
+    0x00000000, // VGT_GROUP_VECT_1_CNTL
+    0x00000000, // VGT_GROUP_VECT_0_FMT_CNTL
+    0x00000000, // VGT_GROUP_VECT_1_FMT_CNTL
+    0x00000000, // VGT_GS_MODE
+    0, // HOLE
+    0x00000000, // PA_SC_MODE_CNTL_0
+    0x00000000, // PA_SC_MODE_CNTL_1
+    0x00000000, // VGT_ENHANCE
+    0x00000100, // VGT_GS_PER_ES
+    0x00000080, // VGT_ES_PER_GS
+    0x00000002, // VGT_GS_PER_VS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_GS_OUT_PRIM_TYPE
+    0x00000000, // IA_ENHANCE
+};
+static const u32 SECT_CONTEXT_def_5[] =
+{
+    0x00000000, // VGT_DMA_MAX_SIZE
+    0x00000000, // VGT_DMA_INDEX_TYPE
+    0, // HOLE
+    0x00000000, // VGT_PRIMITIVEID_EN
+    0x00000000, // VGT_DMA_NUM_INSTANCES
+};
+static const u32 SECT_CONTEXT_def_6[] =
+{
+    0x00000000, // VGT_MULTI_PRIM_IB_RESET_EN
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_INSTANCE_STEP_RATE_0
+    0x00000000, // VGT_INSTANCE_STEP_RATE_1
+    0x000000ff, // IA_MULTI_VGT_PARAM
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_REUSE_OFF
+    0x00000000, // VGT_VTX_CNT_EN
+    0x00000000, // DB_HTILE_SURFACE
+    0x00000000, // DB_SRESULTS_COMPARE_STATE0
+    0x00000000, // DB_SRESULTS_COMPARE_STATE1
+    0x00000000, // DB_PRELOAD_CONTROL
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_0
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_0
+    0x00000000, // VGT_STRMOUT_BUFFER_BASE_0
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_0
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_1
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_1
+    0x00000000, // VGT_STRMOUT_BUFFER_BASE_1
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_1
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_2
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_2
+    0x00000000, // VGT_STRMOUT_BUFFER_BASE_2
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_2
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_3
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_3
+    0x00000000, // VGT_STRMOUT_BUFFER_BASE_3
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_3
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_0
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_1
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_2
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_3
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_OFFSET
+    0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
+    0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
+    0, // HOLE
+    0x00000000, // VGT_GS_MAX_VERT_OUT
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_HI_0
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_HI_1
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_HI_2
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_HI_3
+    0x00000000, // VGT_SHADER_STAGES_EN
+    0x00000000, // VGT_LS_HS_CONFIG
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_TF_PARAM
+    0x00000000, // DB_ALPHA_TO_MASK
+};
+static const u32 SECT_CONTEXT_def_7[] =
+{
+    0x00000000, // PA_SU_POLY_OFFSET_DB_FMT_CNTL
+    0x00000000, // PA_SU_POLY_OFFSET_CLAMP
+    0x00000000, // PA_SU_POLY_OFFSET_FRONT_SCALE
+    0x00000000, // PA_SU_POLY_OFFSET_FRONT_OFFSET
+    0x00000000, // PA_SU_POLY_OFFSET_BACK_SCALE
+    0x00000000, // PA_SU_POLY_OFFSET_BACK_OFFSET
+    0x00000000, // VGT_GS_INSTANCE_CNT
+    0x00000000, // VGT_STRMOUT_CONFIG
+    0x00000000, // VGT_STRMOUT_BUFFER_CONFIG
+    0x00000000, // CB_IMMED0_BASE
+    0x00000000, // CB_IMMED1_BASE
+    0x00000000, // CB_IMMED2_BASE
+    0x00000000, // CB_IMMED3_BASE
+    0x00000000, // CB_IMMED4_BASE
+    0x00000000, // CB_IMMED5_BASE
+    0x00000000, // CB_IMMED6_BASE
+    0x00000000, // CB_IMMED7_BASE
+    0x00000000, // CB_IMMED8_BASE
+    0x00000000, // CB_IMMED9_BASE
+    0x00000000, // CB_IMMED10_BASE
+    0x00000000, // CB_IMMED11_BASE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // PA_SC_CENTROID_PRIORITY_0
+    0x00000000, // PA_SC_CENTROID_PRIORITY_1
+    0x00001000, // PA_SC_LINE_CNTL
+    0x00000000, // PA_SC_AA_CONFIG
+    0x00000005, // PA_SU_VTX_CNTL
+    0x3f800000, // PA_CL_GB_VERT_CLIP_ADJ
+    0x3f800000, // PA_CL_GB_VERT_DISC_ADJ
+    0x3f800000, // PA_CL_GB_HORZ_CLIP_ADJ
+    0x3f800000, // PA_CL_GB_HORZ_DISC_ADJ
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3
+    0xffffffff, // PA_SC_AA_MASK_X0Y0_X1Y0
+    0xffffffff, // PA_SC_AA_MASK_X0Y1_X1Y1
+    0x00000000, // CB_CLRCMP_CONTROL
+    0x00000000, // CB_CLRCMP_SRC
+    0x00000000, // CB_CLRCMP_DST
+    0x00000000, // CB_CLRCMP_MSK
+    0, // HOLE
+    0, // HOLE
+    0x0000000e, // VGT_VERTEX_REUSE_BLOCK_CNTL
+    0x00000010, // VGT_OUT_DEALLOC_CNTL
+    0x00000000, // CB_COLOR0_BASE
+    0x00000000, // CB_COLOR0_PITCH
+    0x00000000, // CB_COLOR0_SLICE
+    0x00000000, // CB_COLOR0_VIEW
+    0x00000000, // CB_COLOR0_INFO
+    0x00000000, // CB_COLOR0_ATTRIB
+    0x00000000, // CB_COLOR0_DIM
+    0x00000000, // CB_COLOR0_CMASK
+    0x00000000, // CB_COLOR0_CMASK_SLICE
+    0x00000000, // CB_COLOR0_FMASK
+    0x00000000, // CB_COLOR0_FMASK_SLICE
+    0x00000000, // CB_COLOR0_CLEAR_WORD0
+    0x00000000, // CB_COLOR0_CLEAR_WORD1
+    0x00000000, // CB_COLOR0_CLEAR_WORD2
+    0x00000000, // CB_COLOR0_CLEAR_WORD3
+    0x00000000, // CB_COLOR1_BASE
+    0x00000000, // CB_COLOR1_PITCH
+    0x00000000, // CB_COLOR1_SLICE
+    0x00000000, // CB_COLOR1_VIEW
+    0x00000000, // CB_COLOR1_INFO
+    0x00000000, // CB_COLOR1_ATTRIB
+    0x00000000, // CB_COLOR1_DIM
+    0x00000000, // CB_COLOR1_CMASK
+    0x00000000, // CB_COLOR1_CMASK_SLICE
+    0x00000000, // CB_COLOR1_FMASK
+    0x00000000, // CB_COLOR1_FMASK_SLICE
+    0x00000000, // CB_COLOR1_CLEAR_WORD0
+    0x00000000, // CB_COLOR1_CLEAR_WORD1
+    0x00000000, // CB_COLOR1_CLEAR_WORD2
+    0x00000000, // CB_COLOR1_CLEAR_WORD3
+    0x00000000, // CB_COLOR2_BASE
+    0x00000000, // CB_COLOR2_PITCH
+    0x00000000, // CB_COLOR2_SLICE
+    0x00000000, // CB_COLOR2_VIEW
+    0x00000000, // CB_COLOR2_INFO
+    0x00000000, // CB_COLOR2_ATTRIB
+    0x00000000, // CB_COLOR2_DIM
+    0x00000000, // CB_COLOR2_CMASK
+    0x00000000, // CB_COLOR2_CMASK_SLICE
+    0x00000000, // CB_COLOR2_FMASK
+    0x00000000, // CB_COLOR2_FMASK_SLICE
+    0x00000000, // CB_COLOR2_CLEAR_WORD0
+    0x00000000, // CB_COLOR2_CLEAR_WORD1
+    0x00000000, // CB_COLOR2_CLEAR_WORD2
+    0x00000000, // CB_COLOR2_CLEAR_WORD3
+    0x00000000, // CB_COLOR3_BASE
+    0x00000000, // CB_COLOR3_PITCH
+    0x00000000, // CB_COLOR3_SLICE
+    0x00000000, // CB_COLOR3_VIEW
+    0x00000000, // CB_COLOR3_INFO
+    0x00000000, // CB_COLOR3_ATTRIB
+    0x00000000, // CB_COLOR3_DIM
+    0x00000000, // CB_COLOR3_CMASK
+    0x00000000, // CB_COLOR3_CMASK_SLICE
+    0x00000000, // CB_COLOR3_FMASK
+    0x00000000, // CB_COLOR3_FMASK_SLICE
+    0x00000000, // CB_COLOR3_CLEAR_WORD0
+    0x00000000, // CB_COLOR3_CLEAR_WORD1
+    0x00000000, // CB_COLOR3_CLEAR_WORD2
+    0x00000000, // CB_COLOR3_CLEAR_WORD3
+    0x00000000, // CB_COLOR4_BASE
+    0x00000000, // CB_COLOR4_PITCH
+    0x00000000, // CB_COLOR4_SLICE
+    0x00000000, // CB_COLOR4_VIEW
+    0x00000000, // CB_COLOR4_INFO
+    0x00000000, // CB_COLOR4_ATTRIB
+    0x00000000, // CB_COLOR4_DIM
+    0x00000000, // CB_COLOR4_CMASK
+    0x00000000, // CB_COLOR4_CMASK_SLICE
+    0x00000000, // CB_COLOR4_FMASK
+    0x00000000, // CB_COLOR4_FMASK_SLICE
+    0x00000000, // CB_COLOR4_CLEAR_WORD0
+    0x00000000, // CB_COLOR4_CLEAR_WORD1
+    0x00000000, // CB_COLOR4_CLEAR_WORD2
+    0x00000000, // CB_COLOR4_CLEAR_WORD3
+    0x00000000, // CB_COLOR5_BASE
+    0x00000000, // CB_COLOR5_PITCH
+    0x00000000, // CB_COLOR5_SLICE
+    0x00000000, // CB_COLOR5_VIEW
+    0x00000000, // CB_COLOR5_INFO
+    0x00000000, // CB_COLOR5_ATTRIB
+    0x00000000, // CB_COLOR5_DIM
+    0x00000000, // CB_COLOR5_CMASK
+    0x00000000, // CB_COLOR5_CMASK_SLICE
+    0x00000000, // CB_COLOR5_FMASK
+    0x00000000, // CB_COLOR5_FMASK_SLICE
+    0x00000000, // CB_COLOR5_CLEAR_WORD0
+    0x00000000, // CB_COLOR5_CLEAR_WORD1
+    0x00000000, // CB_COLOR5_CLEAR_WORD2
+    0x00000000, // CB_COLOR5_CLEAR_WORD3
+    0x00000000, // CB_COLOR6_BASE
+    0x00000000, // CB_COLOR6_PITCH
+    0x00000000, // CB_COLOR6_SLICE
+    0x00000000, // CB_COLOR6_VIEW
+    0x00000000, // CB_COLOR6_INFO
+    0x00000000, // CB_COLOR6_ATTRIB
+    0x00000000, // CB_COLOR6_DIM
+    0x00000000, // CB_COLOR6_CMASK
+    0x00000000, // CB_COLOR6_CMASK_SLICE
+    0x00000000, // CB_COLOR6_FMASK
+    0x00000000, // CB_COLOR6_FMASK_SLICE
+    0x00000000, // CB_COLOR6_CLEAR_WORD0
+    0x00000000, // CB_COLOR6_CLEAR_WORD1
+    0x00000000, // CB_COLOR6_CLEAR_WORD2
+    0x00000000, // CB_COLOR6_CLEAR_WORD3
+    0x00000000, // CB_COLOR7_BASE
+    0x00000000, // CB_COLOR7_PITCH
+    0x00000000, // CB_COLOR7_SLICE
+    0x00000000, // CB_COLOR7_VIEW
+    0x00000000, // CB_COLOR7_INFO
+    0x00000000, // CB_COLOR7_ATTRIB
+    0x00000000, // CB_COLOR7_DIM
+    0x00000000, // CB_COLOR7_CMASK
+    0x00000000, // CB_COLOR7_CMASK_SLICE
+    0x00000000, // CB_COLOR7_FMASK
+    0x00000000, // CB_COLOR7_FMASK_SLICE
+    0x00000000, // CB_COLOR7_CLEAR_WORD0
+    0x00000000, // CB_COLOR7_CLEAR_WORD1
+    0x00000000, // CB_COLOR7_CLEAR_WORD2
+    0x00000000, // CB_COLOR7_CLEAR_WORD3
+    0x00000000, // CB_COLOR8_BASE
+    0x00000000, // CB_COLOR8_PITCH
+    0x00000000, // CB_COLOR8_SLICE
+    0x00000000, // CB_COLOR8_VIEW
+    0x00000000, // CB_COLOR8_INFO
+    0x00000000, // CB_COLOR8_ATTRIB
+    0x00000000, // CB_COLOR8_DIM
+    0x00000000, // CB_COLOR9_BASE
+    0x00000000, // CB_COLOR9_PITCH
+    0x00000000, // CB_COLOR9_SLICE
+    0x00000000, // CB_COLOR9_VIEW
+    0x00000000, // CB_COLOR9_INFO
+    0x00000000, // CB_COLOR9_ATTRIB
+    0x00000000, // CB_COLOR9_DIM
+    0x00000000, // CB_COLOR10_BASE
+    0x00000000, // CB_COLOR10_PITCH
+    0x00000000, // CB_COLOR10_SLICE
+    0x00000000, // CB_COLOR10_VIEW
+    0x00000000, // CB_COLOR10_INFO
+    0x00000000, // CB_COLOR10_ATTRIB
+    0x00000000, // CB_COLOR10_DIM
+    0x00000000, // CB_COLOR11_BASE
+    0x00000000, // CB_COLOR11_PITCH
+    0x00000000, // CB_COLOR11_SLICE
+    0x00000000, // CB_COLOR11_VIEW
+    0x00000000, // CB_COLOR11_INFO
+    0x00000000, // CB_COLOR11_ATTRIB
+    0x00000000, // CB_COLOR11_DIM
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_15
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_15
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_15
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_15
+};
+static const struct cs_extent_def SECT_CONTEXT_defs[] =
+{
+    {SECT_CONTEXT_def_1, 0x0000a000, 488 },
+    {SECT_CONTEXT_def_2, 0x0000a1f5, 6 },
+    {SECT_CONTEXT_def_3, 0x0000a200, 55 },
+    {SECT_CONTEXT_def_4, 0x0000a23a, 99 },
+    {SECT_CONTEXT_def_5, 0x0000a29e, 5 },
+    {SECT_CONTEXT_def_6, 0x0000a2a5, 56 },
+    {SECT_CONTEXT_def_7, 0x0000a2de, 290 },
+    { 0, 0, 0 }
+};
+static const u32 SECT_CLEAR_def_1[] =
+{
+    0xffffffff, // SQ_TEX_SAMPLER_CLEAR
+    0xffffffff, // SQ_TEX_RESOURCE_CLEAR
+    0xffffffff, // SQ_LOOP_BOOL_CLEAR
+};
+static const struct cs_extent_def SECT_CLEAR_defs[] =
+{
+    {SECT_CLEAR_def_1, 0x0000ffc0, 3 },
+    { 0, 0, 0 }
+};
+static const u32 SECT_CTRLCONST_def_1[] =
+{
+    0x00000000, // SQ_VTX_BASE_VTX_LOC
+    0x00000000, // SQ_VTX_START_INST_LOC
+};
+static const struct cs_extent_def SECT_CTRLCONST_defs[] =
+{
+    {SECT_CTRLCONST_def_1, 0x0000f3fc, 2 },
+    { 0, 0, 0 }
+};
+struct cs_section_def cayman_cs_data[] = {
+    { SECT_CONTEXT_defs, SECT_CONTEXT },
+    { SECT_CLEAR_defs, SECT_CLEAR },
+    { SECT_CTRLCONST_defs, SECT_CTRLCONST },
+    { 0, SECT_NONE }
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/clearstate_defs.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/clearstate_defs.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/clearstate_defs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/clearstate_defs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 CLEARSTATE_DEFS_H
+#define CLEARSTATE_DEFS_H
+
+enum section_id {
+    SECT_NONE,
+    SECT_CONTEXT,
+    SECT_CLEAR,
+    SECT_CTRLCONST
+};
+
+struct cs_extent_def {
+    const unsigned int *extent;
+    const unsigned int reg_index;
+    const unsigned int reg_count;
+};
+
+struct cs_section_def {
+    const struct cs_extent_def *section;
+    const enum section_id id;
+};
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/clearstate_evergreen.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/clearstate_evergreen.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/clearstate_evergreen.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/clearstate_evergreen.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1080 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ */
+
+static const u32 SECT_CONTEXT_def_1[] =
+{
+    0x00000000, // DB_RENDER_CONTROL
+    0x00000000, // DB_COUNT_CONTROL
+    0x00000000, // DB_DEPTH_VIEW
+    0x00000000, // DB_RENDER_OVERRIDE
+    0x00000000, // DB_RENDER_OVERRIDE2
+    0x00000000, // DB_HTILE_DATA_BASE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // DB_STENCIL_CLEAR
+    0x00000000, // DB_DEPTH_CLEAR
+    0x00000000, // PA_SC_SCREEN_SCISSOR_TL
+    0x40004000, // PA_SC_SCREEN_SCISSOR_BR
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // DB_Z_INFO
+    0x00000000, // DB_STENCIL_INFO
+    0x00000000, // DB_Z_READ_BASE
+    0x00000000, // DB_STENCIL_READ_BASE
+    0x00000000, // DB_Z_WRITE_BASE
+    0x00000000, // DB_STENCIL_WRITE_BASE
+    0x00000000, // DB_DEPTH_SIZE
+    0x00000000, // DB_DEPTH_SLICE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_PS_15
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_VS_15
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_GS_15
+    0x00000000, // PA_SC_WINDOW_OFFSET
+    0x80000000, // PA_SC_WINDOW_SCISSOR_TL
+    0x40004000, // PA_SC_WINDOW_SCISSOR_BR
+    0x0000ffff, // PA_SC_CLIPRECT_RULE
+    0x00000000, // PA_SC_CLIPRECT_0_TL
+    0x40004000, // PA_SC_CLIPRECT_0_BR
+    0x00000000, // PA_SC_CLIPRECT_1_TL
+    0x40004000, // PA_SC_CLIPRECT_1_BR
+    0x00000000, // PA_SC_CLIPRECT_2_TL
+    0x40004000, // PA_SC_CLIPRECT_2_BR
+    0x00000000, // PA_SC_CLIPRECT_3_TL
+    0x40004000, // PA_SC_CLIPRECT_3_BR
+    0xaa99aaaa, // PA_SC_EDGERULE
+    0x00000000, // PA_SU_HARDWARE_SCREEN_OFFSET
+    0xffffffff, // CB_TARGET_MASK
+    0xffffffff, // CB_SHADER_MASK
+    0x80000000, // PA_SC_GENERIC_SCISSOR_TL
+    0x40004000, // PA_SC_GENERIC_SCISSOR_BR
+    0x00000000, // COHER_DEST_BASE_0
+    0x00000000, // COHER_DEST_BASE_1
+    0x80000000, // PA_SC_VPORT_SCISSOR_0_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_0_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_1_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_1_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_2_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_2_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_3_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_3_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_4_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_4_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_5_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_5_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_6_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_6_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_7_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_7_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_8_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_8_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_9_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_9_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_10_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_10_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_11_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_11_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_12_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_12_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_13_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_13_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_14_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_14_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_15_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_15_BR
+    0x00000000, // PA_SC_VPORT_ZMIN_0
+    0x3f800000, // PA_SC_VPORT_ZMAX_0
+    0x00000000, // PA_SC_VPORT_ZMIN_1
+    0x3f800000, // PA_SC_VPORT_ZMAX_1
+    0x00000000, // PA_SC_VPORT_ZMIN_2
+    0x3f800000, // PA_SC_VPORT_ZMAX_2
+    0x00000000, // PA_SC_VPORT_ZMIN_3
+    0x3f800000, // PA_SC_VPORT_ZMAX_3
+    0x00000000, // PA_SC_VPORT_ZMIN_4
+    0x3f800000, // PA_SC_VPORT_ZMAX_4
+    0x00000000, // PA_SC_VPORT_ZMIN_5
+    0x3f800000, // PA_SC_VPORT_ZMAX_5
+    0x00000000, // PA_SC_VPORT_ZMIN_6
+    0x3f800000, // PA_SC_VPORT_ZMAX_6
+    0x00000000, // PA_SC_VPORT_ZMIN_7
+    0x3f800000, // PA_SC_VPORT_ZMAX_7
+    0x00000000, // PA_SC_VPORT_ZMIN_8
+    0x3f800000, // PA_SC_VPORT_ZMAX_8
+    0x00000000, // PA_SC_VPORT_ZMIN_9
+    0x3f800000, // PA_SC_VPORT_ZMAX_9
+    0x00000000, // PA_SC_VPORT_ZMIN_10
+    0x3f800000, // PA_SC_VPORT_ZMAX_10
+    0x00000000, // PA_SC_VPORT_ZMIN_11
+    0x3f800000, // PA_SC_VPORT_ZMAX_11
+    0x00000000, // PA_SC_VPORT_ZMIN_12
+    0x3f800000, // PA_SC_VPORT_ZMAX_12
+    0x00000000, // PA_SC_VPORT_ZMIN_13
+    0x3f800000, // PA_SC_VPORT_ZMAX_13
+    0x00000000, // PA_SC_VPORT_ZMIN_14
+    0x3f800000, // PA_SC_VPORT_ZMAX_14
+    0x00000000, // PA_SC_VPORT_ZMIN_15
+    0x3f800000, // PA_SC_VPORT_ZMAX_15
+    0x00000000, // SX_MISC
+    0x00000000, // SX_SURFACE_SYNC
+    0x00000000, // CP_PERFMON_CNTX_CNTL
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_VTX_SEMANTIC_0
+    0x00000000, // SQ_VTX_SEMANTIC_1
+    0x00000000, // SQ_VTX_SEMANTIC_2
+    0x00000000, // SQ_VTX_SEMANTIC_3
+    0x00000000, // SQ_VTX_SEMANTIC_4
+    0x00000000, // SQ_VTX_SEMANTIC_5
+    0x00000000, // SQ_VTX_SEMANTIC_6
+    0x00000000, // SQ_VTX_SEMANTIC_7
+    0x00000000, // SQ_VTX_SEMANTIC_8
+    0x00000000, // SQ_VTX_SEMANTIC_9
+    0x00000000, // SQ_VTX_SEMANTIC_10
+    0x00000000, // SQ_VTX_SEMANTIC_11
+    0x00000000, // SQ_VTX_SEMANTIC_12
+    0x00000000, // SQ_VTX_SEMANTIC_13
+    0x00000000, // SQ_VTX_SEMANTIC_14
+    0x00000000, // SQ_VTX_SEMANTIC_15
+    0x00000000, // SQ_VTX_SEMANTIC_16
+    0x00000000, // SQ_VTX_SEMANTIC_17
+    0x00000000, // SQ_VTX_SEMANTIC_18
+    0x00000000, // SQ_VTX_SEMANTIC_19
+    0x00000000, // SQ_VTX_SEMANTIC_20
+    0x00000000, // SQ_VTX_SEMANTIC_21
+    0x00000000, // SQ_VTX_SEMANTIC_22
+    0x00000000, // SQ_VTX_SEMANTIC_23
+    0x00000000, // SQ_VTX_SEMANTIC_24
+    0x00000000, // SQ_VTX_SEMANTIC_25
+    0x00000000, // SQ_VTX_SEMANTIC_26
+    0x00000000, // SQ_VTX_SEMANTIC_27
+    0x00000000, // SQ_VTX_SEMANTIC_28
+    0x00000000, // SQ_VTX_SEMANTIC_29
+    0x00000000, // SQ_VTX_SEMANTIC_30
+    0x00000000, // SQ_VTX_SEMANTIC_31
+    0xffffffff, // VGT_MAX_VTX_INDX
+    0x00000000, // VGT_MIN_VTX_INDX
+    0x00000000, // VGT_INDX_OFFSET
+    0x00000000, // VGT_MULTI_PRIM_IB_RESET_INDX
+    0x00000000, // SX_ALPHA_TEST_CONTROL
+    0x00000000, // CB_BLEND_RED
+    0x00000000, // CB_BLEND_GREEN
+    0x00000000, // CB_BLEND_BLUE
+    0x00000000, // CB_BLEND_ALPHA
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // DB_STENCILREFMASK
+    0x00000000, // DB_STENCILREFMASK_BF
+    0x00000000, // SX_ALPHA_REF
+    0x00000000, // PA_CL_VPORT_XSCALE
+    0x00000000, // PA_CL_VPORT_XOFFSET
+    0x00000000, // PA_CL_VPORT_YSCALE
+    0x00000000, // PA_CL_VPORT_YOFFSET
+    0x00000000, // PA_CL_VPORT_ZSCALE
+    0x00000000, // PA_CL_VPORT_ZOFFSET
+    0x00000000, // PA_CL_VPORT_XSCALE_1
+    0x00000000, // PA_CL_VPORT_XOFFSET_1
+    0x00000000, // PA_CL_VPORT_YSCALE_1
+    0x00000000, // PA_CL_VPORT_YOFFSET_1
+    0x00000000, // PA_CL_VPORT_ZSCALE_1
+    0x00000000, // PA_CL_VPORT_ZOFFSET_1
+    0x00000000, // PA_CL_VPORT_XSCALE_2
+    0x00000000, // PA_CL_VPORT_XOFFSET_2
+    0x00000000, // PA_CL_VPORT_YSCALE_2
+    0x00000000, // PA_CL_VPORT_YOFFSET_2
+    0x00000000, // PA_CL_VPORT_ZSCALE_2
+    0x00000000, // PA_CL_VPORT_ZOFFSET_2
+    0x00000000, // PA_CL_VPORT_XSCALE_3
+    0x00000000, // PA_CL_VPORT_XOFFSET_3
+    0x00000000, // PA_CL_VPORT_YSCALE_3
+    0x00000000, // PA_CL_VPORT_YOFFSET_3
+    0x00000000, // PA_CL_VPORT_ZSCALE_3
+    0x00000000, // PA_CL_VPORT_ZOFFSET_3
+    0x00000000, // PA_CL_VPORT_XSCALE_4
+    0x00000000, // PA_CL_VPORT_XOFFSET_4
+    0x00000000, // PA_CL_VPORT_YSCALE_4
+    0x00000000, // PA_CL_VPORT_YOFFSET_4
+    0x00000000, // PA_CL_VPORT_ZSCALE_4
+    0x00000000, // PA_CL_VPORT_ZOFFSET_4
+    0x00000000, // PA_CL_VPORT_XSCALE_5
+    0x00000000, // PA_CL_VPORT_XOFFSET_5
+    0x00000000, // PA_CL_VPORT_YSCALE_5
+    0x00000000, // PA_CL_VPORT_YOFFSET_5
+    0x00000000, // PA_CL_VPORT_ZSCALE_5
+    0x00000000, // PA_CL_VPORT_ZOFFSET_5
+    0x00000000, // PA_CL_VPORT_XSCALE_6
+    0x00000000, // PA_CL_VPORT_XOFFSET_6
+    0x00000000, // PA_CL_VPORT_YSCALE_6
+    0x00000000, // PA_CL_VPORT_YOFFSET_6
+    0x00000000, // PA_CL_VPORT_ZSCALE_6
+    0x00000000, // PA_CL_VPORT_ZOFFSET_6
+    0x00000000, // PA_CL_VPORT_XSCALE_7
+    0x00000000, // PA_CL_VPORT_XOFFSET_7
+    0x00000000, // PA_CL_VPORT_YSCALE_7
+    0x00000000, // PA_CL_VPORT_YOFFSET_7
+    0x00000000, // PA_CL_VPORT_ZSCALE_7
+    0x00000000, // PA_CL_VPORT_ZOFFSET_7
+    0x00000000, // PA_CL_VPORT_XSCALE_8
+    0x00000000, // PA_CL_VPORT_XOFFSET_8
+    0x00000000, // PA_CL_VPORT_YSCALE_8
+    0x00000000, // PA_CL_VPORT_YOFFSET_8
+    0x00000000, // PA_CL_VPORT_ZSCALE_8
+    0x00000000, // PA_CL_VPORT_ZOFFSET_8
+    0x00000000, // PA_CL_VPORT_XSCALE_9
+    0x00000000, // PA_CL_VPORT_XOFFSET_9
+    0x00000000, // PA_CL_VPORT_YSCALE_9
+    0x00000000, // PA_CL_VPORT_YOFFSET_9
+    0x00000000, // PA_CL_VPORT_ZSCALE_9
+    0x00000000, // PA_CL_VPORT_ZOFFSET_9
+    0x00000000, // PA_CL_VPORT_XSCALE_10
+    0x00000000, // PA_CL_VPORT_XOFFSET_10
+    0x00000000, // PA_CL_VPORT_YSCALE_10
+    0x00000000, // PA_CL_VPORT_YOFFSET_10
+    0x00000000, // PA_CL_VPORT_ZSCALE_10
+    0x00000000, // PA_CL_VPORT_ZOFFSET_10
+    0x00000000, // PA_CL_VPORT_XSCALE_11
+    0x00000000, // PA_CL_VPORT_XOFFSET_11
+    0x00000000, // PA_CL_VPORT_YSCALE_11
+    0x00000000, // PA_CL_VPORT_YOFFSET_11
+    0x00000000, // PA_CL_VPORT_ZSCALE_11
+    0x00000000, // PA_CL_VPORT_ZOFFSET_11
+    0x00000000, // PA_CL_VPORT_XSCALE_12
+    0x00000000, // PA_CL_VPORT_XOFFSET_12
+    0x00000000, // PA_CL_VPORT_YSCALE_12
+    0x00000000, // PA_CL_VPORT_YOFFSET_12
+    0x00000000, // PA_CL_VPORT_ZSCALE_12
+    0x00000000, // PA_CL_VPORT_ZOFFSET_12
+    0x00000000, // PA_CL_VPORT_XSCALE_13
+    0x00000000, // PA_CL_VPORT_XOFFSET_13
+    0x00000000, // PA_CL_VPORT_YSCALE_13
+    0x00000000, // PA_CL_VPORT_YOFFSET_13
+    0x00000000, // PA_CL_VPORT_ZSCALE_13
+    0x00000000, // PA_CL_VPORT_ZOFFSET_13
+    0x00000000, // PA_CL_VPORT_XSCALE_14
+    0x00000000, // PA_CL_VPORT_XOFFSET_14
+    0x00000000, // PA_CL_VPORT_YSCALE_14
+    0x00000000, // PA_CL_VPORT_YOFFSET_14
+    0x00000000, // PA_CL_VPORT_ZSCALE_14
+    0x00000000, // PA_CL_VPORT_ZOFFSET_14
+    0x00000000, // PA_CL_VPORT_XSCALE_15
+    0x00000000, // PA_CL_VPORT_XOFFSET_15
+    0x00000000, // PA_CL_VPORT_YSCALE_15
+    0x00000000, // PA_CL_VPORT_YOFFSET_15
+    0x00000000, // PA_CL_VPORT_ZSCALE_15
+    0x00000000, // PA_CL_VPORT_ZOFFSET_15
+    0x00000000, // PA_CL_UCP_0_X
+    0x00000000, // PA_CL_UCP_0_Y
+    0x00000000, // PA_CL_UCP_0_Z
+    0x00000000, // PA_CL_UCP_0_W
+    0x00000000, // PA_CL_UCP_1_X
+    0x00000000, // PA_CL_UCP_1_Y
+    0x00000000, // PA_CL_UCP_1_Z
+    0x00000000, // PA_CL_UCP_1_W
+    0x00000000, // PA_CL_UCP_2_X
+    0x00000000, // PA_CL_UCP_2_Y
+    0x00000000, // PA_CL_UCP_2_Z
+    0x00000000, // PA_CL_UCP_2_W
+    0x00000000, // PA_CL_UCP_3_X
+    0x00000000, // PA_CL_UCP_3_Y
+    0x00000000, // PA_CL_UCP_3_Z
+    0x00000000, // PA_CL_UCP_3_W
+    0x00000000, // PA_CL_UCP_4_X
+    0x00000000, // PA_CL_UCP_4_Y
+    0x00000000, // PA_CL_UCP_4_Z
+    0x00000000, // PA_CL_UCP_4_W
+    0x00000000, // PA_CL_UCP_5_X
+    0x00000000, // PA_CL_UCP_5_Y
+    0x00000000, // PA_CL_UCP_5_Z
+    0x00000000, // PA_CL_UCP_5_W
+    0x00000000, // SPI_VS_OUT_ID_0
+    0x00000000, // SPI_VS_OUT_ID_1
+    0x00000000, // SPI_VS_OUT_ID_2
+    0x00000000, // SPI_VS_OUT_ID_3
+    0x00000000, // SPI_VS_OUT_ID_4
+    0x00000000, // SPI_VS_OUT_ID_5
+    0x00000000, // SPI_VS_OUT_ID_6
+    0x00000000, // SPI_VS_OUT_ID_7
+    0x00000000, // SPI_VS_OUT_ID_8
+    0x00000000, // SPI_VS_OUT_ID_9
+    0x00000000, // SPI_PS_INPUT_CNTL_0
+    0x00000000, // SPI_PS_INPUT_CNTL_1
+    0x00000000, // SPI_PS_INPUT_CNTL_2
+    0x00000000, // SPI_PS_INPUT_CNTL_3
+    0x00000000, // SPI_PS_INPUT_CNTL_4
+    0x00000000, // SPI_PS_INPUT_CNTL_5
+    0x00000000, // SPI_PS_INPUT_CNTL_6
+    0x00000000, // SPI_PS_INPUT_CNTL_7
+    0x00000000, // SPI_PS_INPUT_CNTL_8
+    0x00000000, // SPI_PS_INPUT_CNTL_9
+    0x00000000, // SPI_PS_INPUT_CNTL_10
+    0x00000000, // SPI_PS_INPUT_CNTL_11
+    0x00000000, // SPI_PS_INPUT_CNTL_12
+    0x00000000, // SPI_PS_INPUT_CNTL_13
+    0x00000000, // SPI_PS_INPUT_CNTL_14
+    0x00000000, // SPI_PS_INPUT_CNTL_15
+    0x00000000, // SPI_PS_INPUT_CNTL_16
+    0x00000000, // SPI_PS_INPUT_CNTL_17
+    0x00000000, // SPI_PS_INPUT_CNTL_18
+    0x00000000, // SPI_PS_INPUT_CNTL_19
+    0x00000000, // SPI_PS_INPUT_CNTL_20
+    0x00000000, // SPI_PS_INPUT_CNTL_21
+    0x00000000, // SPI_PS_INPUT_CNTL_22
+    0x00000000, // SPI_PS_INPUT_CNTL_23
+    0x00000000, // SPI_PS_INPUT_CNTL_24
+    0x00000000, // SPI_PS_INPUT_CNTL_25
+    0x00000000, // SPI_PS_INPUT_CNTL_26
+    0x00000000, // SPI_PS_INPUT_CNTL_27
+    0x00000000, // SPI_PS_INPUT_CNTL_28
+    0x00000000, // SPI_PS_INPUT_CNTL_29
+    0x00000000, // SPI_PS_INPUT_CNTL_30
+    0x00000000, // SPI_PS_INPUT_CNTL_31
+    0x00000000, // SPI_VS_OUT_CONFIG
+    0x00000001, // SPI_THREAD_GROUPING
+    0x00000000, // SPI_PS_IN_CONTROL_0
+    0x00000000, // SPI_PS_IN_CONTROL_1
+    0x00000000, // SPI_INTERP_CONTROL_0
+    0x00000000, // SPI_INPUT_Z
+    0x00000000, // SPI_FOG_CNTL
+    0x00000000, // SPI_BARYC_CNTL
+    0x00000000, // SPI_PS_IN_CONTROL_2
+    0x00000000, // SPI_COMPUTE_INPUT_CNTL
+    0x00000000, // SPI_COMPUTE_NUM_THREAD_X
+    0x00000000, // SPI_COMPUTE_NUM_THREAD_Y
+    0x00000000, // SPI_COMPUTE_NUM_THREAD_Z
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // GDS_ADDR_BASE
+    0x00003fff, // GDS_ADDR_SIZE
+    0x00000001, // GDS_ORDERED_WAVE_PER_SE
+    0x00000000, // GDS_APPEND_CONSUME_UAV0
+    0x00000000, // GDS_APPEND_CONSUME_UAV1
+    0x00000000, // GDS_APPEND_CONSUME_UAV2
+    0x00000000, // GDS_APPEND_CONSUME_UAV3
+    0x00000000, // GDS_APPEND_CONSUME_UAV4
+    0x00000000, // GDS_APPEND_CONSUME_UAV5
+    0x00000000, // GDS_APPEND_CONSUME_UAV6
+    0x00000000, // GDS_APPEND_CONSUME_UAV7
+    0x00000000, // GDS_APPEND_CONSUME_UAV8
+    0x00000000, // GDS_APPEND_CONSUME_UAV9
+    0x00000000, // GDS_APPEND_CONSUME_UAV10
+    0x00000000, // GDS_APPEND_CONSUME_UAV11
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_BLEND0_CONTROL
+    0x00000000, // CB_BLEND1_CONTROL
+    0x00000000, // CB_BLEND2_CONTROL
+    0x00000000, // CB_BLEND3_CONTROL
+    0x00000000, // CB_BLEND4_CONTROL
+    0x00000000, // CB_BLEND5_CONTROL
+    0x00000000, // CB_BLEND6_CONTROL
+    0x00000000, // CB_BLEND7_CONTROL
+};
+static const u32 SECT_CONTEXT_def_2[] =
+{
+    0x00000000, // PA_CL_POINT_X_RAD
+    0x00000000, // PA_CL_POINT_Y_RAD
+    0x00000000, // PA_CL_POINT_SIZE
+    0x00000000, // PA_CL_POINT_CULL_RAD
+    0x00000000, // VGT_DMA_BASE_HI
+    0x00000000, // VGT_DMA_BASE
+};
+static const u32 SECT_CONTEXT_def_3[] =
+{
+    0x00000000, // DB_DEPTH_CONTROL
+    0, // HOLE
+    0x00000000, // CB_COLOR_CONTROL
+    0x00000200, // DB_SHADER_CONTROL
+    0x00000000, // PA_CL_CLIP_CNTL
+    0x00000000, // PA_SU_SC_MODE_CNTL
+    0x00000000, // PA_CL_VTE_CNTL
+    0x00000000, // PA_CL_VS_OUT_CNTL
+    0x00000000, // PA_CL_NANINF_CNTL
+    0x00000000, // PA_SU_LINE_STIPPLE_CNTL
+    0x00000000, // PA_SU_LINE_STIPPLE_SCALE
+    0x00000000, // PA_SU_PRIM_FILTER_CNTL
+    0x00000000, // SQ_LSTMP_RING_ITEMSIZE
+    0x00000000, // SQ_HSTMP_RING_ITEMSIZE
+    0x00000000, // SQ_DYN_GPR_RESOURCE_LIMIT_1
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_PS
+    0x00000000, // SQ_PGM_RESOURCES_PS
+    0x00000000, // SQ_PGM_RESOURCES_2_PS
+    0x00000000, // SQ_PGM_EXPORTS_PS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_VS
+    0x00000000, // SQ_PGM_RESOURCES_VS
+    0x00000000, // SQ_PGM_RESOURCES_2_VS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_GS
+    0x00000000, // SQ_PGM_RESOURCES_GS
+    0x00000000, // SQ_PGM_RESOURCES_2_GS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_ES
+    0x00000000, // SQ_PGM_RESOURCES_ES
+    0x00000000, // SQ_PGM_RESOURCES_2_ES
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_FS
+    0x00000000, // SQ_PGM_RESOURCES_FS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_HS
+    0x00000000, // SQ_PGM_RESOURCES_HS
+    0x00000000, // SQ_PGM_RESOURCES_2_HS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_PGM_START_LS
+    0x00000000, // SQ_PGM_RESOURCES_LS
+    0x00000000, // SQ_PGM_RESOURCES_2_LS
+};
+static const u32 SECT_CONTEXT_def_4[] =
+{
+    0x00000000, // SQ_LDS_ALLOC
+    0x00000000, // SQ_LDS_ALLOC_PS
+    0x00000000, // SQ_VTX_SEMANTIC_CLEAR
+    0, // HOLE
+    0x00000000, // SQ_THREAD_TRACE_CTRL
+    0, // HOLE
+    0x00000000, // SQ_ESGS_RING_ITEMSIZE
+    0x00000000, // SQ_GSVS_RING_ITEMSIZE
+    0x00000000, // SQ_ESTMP_RING_ITEMSIZE
+    0x00000000, // SQ_GSTMP_RING_ITEMSIZE
+    0x00000000, // SQ_VSTMP_RING_ITEMSIZE
+    0x00000000, // SQ_PSTMP_RING_ITEMSIZE
+    0, // HOLE
+    0x00000000, // SQ_GS_VERT_ITEMSIZE
+    0x00000000, // SQ_GS_VERT_ITEMSIZE_1
+    0x00000000, // SQ_GS_VERT_ITEMSIZE_2
+    0x00000000, // SQ_GS_VERT_ITEMSIZE_3
+    0x00000000, // SQ_GSVS_RING_OFFSET_1
+    0x00000000, // SQ_GSVS_RING_OFFSET_2
+    0x00000000, // SQ_GSVS_RING_OFFSET_3
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_PS_15
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_VS_15
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_GS_15
+    0x00000000, // PA_SU_POINT_SIZE
+    0x00000000, // PA_SU_POINT_MINMAX
+    0x00000000, // PA_SU_LINE_CNTL
+    0x00000000, // PA_SC_LINE_STIPPLE
+    0x00000000, // VGT_OUTPUT_PATH_CNTL
+    0x00000000, // VGT_HOS_CNTL
+    0x00000000, // VGT_HOS_MAX_TESS_LEVEL
+    0x00000000, // VGT_HOS_MIN_TESS_LEVEL
+    0x00000000, // VGT_HOS_REUSE_DEPTH
+    0x00000000, // VGT_GROUP_PRIM_TYPE
+    0x00000000, // VGT_GROUP_FIRST_DECR
+    0x00000000, // VGT_GROUP_DECR
+    0x00000000, // VGT_GROUP_VECT_0_CNTL
+    0x00000000, // VGT_GROUP_VECT_1_CNTL
+    0x00000000, // VGT_GROUP_VECT_0_FMT_CNTL
+    0x00000000, // VGT_GROUP_VECT_1_FMT_CNTL
+    0x00000000, // VGT_GS_MODE
+    0, // HOLE
+    0x00000000, // PA_SC_MODE_CNTL_0
+    0x00000000, // PA_SC_MODE_CNTL_1
+    0x00000000, // VGT_ENHANCE
+    0x00000000, // VGT_GS_PER_ES
+    0x00000000, // VGT_ES_PER_GS
+    0x00000000, // VGT_GS_PER_VS
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_GS_OUT_PRIM_TYPE
+};
+static const u32 SECT_CONTEXT_def_5[] =
+{
+    0x00000000, // VGT_DMA_MAX_SIZE
+    0x00000000, // VGT_DMA_INDEX_TYPE
+    0, // HOLE
+    0x00000000, // VGT_PRIMITIVEID_EN
+    0x00000000, // VGT_DMA_NUM_INSTANCES
+};
+static const u32 SECT_CONTEXT_def_6[] =
+{
+    0x00000000, // VGT_MULTI_PRIM_IB_RESET_EN
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_INSTANCE_STEP_RATE_0
+    0x00000000, // VGT_INSTANCE_STEP_RATE_1
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_REUSE_OFF
+    0x00000000, // VGT_VTX_CNT_EN
+    0x00000000, // DB_HTILE_SURFACE
+    0x00000000, // DB_SRESULTS_COMPARE_STATE0
+    0x00000000, // DB_SRESULTS_COMPARE_STATE1
+    0x00000000, // DB_PRELOAD_CONTROL
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_0
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_0
+    0x00000000, // VGT_STRMOUT_BUFFER_BASE_0
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_0
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_1
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_1
+    0x00000000, // VGT_STRMOUT_BUFFER_BASE_1
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_1
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_2
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_2
+    0x00000000, // VGT_STRMOUT_BUFFER_BASE_2
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_2
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_3
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_3
+    0x00000000, // VGT_STRMOUT_BUFFER_BASE_3
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_3
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_0
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_1
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_2
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_3
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_OFFSET
+    0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
+    0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
+    0, // HOLE
+    0x00000000, // VGT_GS_MAX_VERT_OUT
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_HI_0
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_HI_1
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_HI_2
+    0x00000000, // VGT_STRMOUT_BASE_OFFSET_HI_3
+    0x00000000, // VGT_SHADER_STAGES_EN
+    0x00000000, // VGT_LS_HS_CONFIG
+    0x00000000, // VGT_LS_SIZE
+    0x00000000, // VGT_HS_SIZE
+    0x00000000, // VGT_LS_HS_ALLOC
+    0x00000000, // VGT_HS_PATCH_CONST
+    0x00000000, // VGT_TF_PARAM
+    0x00000000, // DB_ALPHA_TO_MASK
+};
+static const u32 SECT_CONTEXT_def_7[] =
+{
+    0x00000000, // PA_SU_POLY_OFFSET_DB_FMT_CNTL
+    0x00000000, // PA_SU_POLY_OFFSET_CLAMP
+    0x00000000, // PA_SU_POLY_OFFSET_FRONT_SCALE
+    0x00000000, // PA_SU_POLY_OFFSET_FRONT_OFFSET
+    0x00000000, // PA_SU_POLY_OFFSET_BACK_SCALE
+    0x00000000, // PA_SU_POLY_OFFSET_BACK_OFFSET
+    0x00000000, // VGT_GS_INSTANCE_CNT
+    0x00000000, // VGT_STRMOUT_CONFIG
+    0x00000000, // VGT_STRMOUT_BUFFER_CONFIG
+    0x00000000, // CB_IMMED0_BASE
+    0x00000000, // CB_IMMED1_BASE
+    0x00000000, // CB_IMMED2_BASE
+    0x00000000, // CB_IMMED3_BASE
+    0x00000000, // CB_IMMED4_BASE
+    0x00000000, // CB_IMMED5_BASE
+    0x00000000, // CB_IMMED6_BASE
+    0x00000000, // CB_IMMED7_BASE
+    0x00000000, // CB_IMMED8_BASE
+    0x00000000, // CB_IMMED9_BASE
+    0x00000000, // CB_IMMED10_BASE
+    0x00000000, // CB_IMMED11_BASE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00001000, // PA_SC_LINE_CNTL
+    0x00000000, // PA_SC_AA_CONFIG
+    0x00000005, // PA_SU_VTX_CNTL
+    0x3f800000, // PA_CL_GB_VERT_CLIP_ADJ
+    0x3f800000, // PA_CL_GB_VERT_DISC_ADJ
+    0x3f800000, // PA_CL_GB_HORZ_CLIP_ADJ
+    0x3f800000, // PA_CL_GB_HORZ_DISC_ADJ
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_0
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_1
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_2
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_3
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_4
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_5
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_6
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_7
+    0xffffffff, // PA_SC_AA_MASK
+    0x00000000, // CB_CLRCMP_CONTROL
+    0x00000000, // CB_CLRCMP_SRC
+    0x00000000, // CB_CLRCMP_DST
+    0x00000000, // CB_CLRCMP_MSK
+    0, // HOLE
+    0, // HOLE
+    0x0000000e, // VGT_VERTEX_REUSE_BLOCK_CNTL
+    0x00000010, // VGT_OUT_DEALLOC_CNTL
+    0x00000000, // CB_COLOR0_BASE
+    0x00000000, // CB_COLOR0_PITCH
+    0x00000000, // CB_COLOR0_SLICE
+    0x00000000, // CB_COLOR0_VIEW
+    0x00000000, // CB_COLOR0_INFO
+    0x00000000, // CB_COLOR0_ATTRIB
+    0x00000000, // CB_COLOR0_DIM
+    0x00000000, // CB_COLOR0_CMASK
+    0x00000000, // CB_COLOR0_CMASK_SLICE
+    0x00000000, // CB_COLOR0_FMASK
+    0x00000000, // CB_COLOR0_FMASK_SLICE
+    0x00000000, // CB_COLOR0_CLEAR_WORD0
+    0x00000000, // CB_COLOR0_CLEAR_WORD1
+    0x00000000, // CB_COLOR0_CLEAR_WORD2
+    0x00000000, // CB_COLOR0_CLEAR_WORD3
+    0x00000000, // CB_COLOR1_BASE
+    0x00000000, // CB_COLOR1_PITCH
+    0x00000000, // CB_COLOR1_SLICE
+    0x00000000, // CB_COLOR1_VIEW
+    0x00000000, // CB_COLOR1_INFO
+    0x00000000, // CB_COLOR1_ATTRIB
+    0x00000000, // CB_COLOR1_DIM
+    0x00000000, // CB_COLOR1_CMASK
+    0x00000000, // CB_COLOR1_CMASK_SLICE
+    0x00000000, // CB_COLOR1_FMASK
+    0x00000000, // CB_COLOR1_FMASK_SLICE
+    0x00000000, // CB_COLOR1_CLEAR_WORD0
+    0x00000000, // CB_COLOR1_CLEAR_WORD1
+    0x00000000, // CB_COLOR1_CLEAR_WORD2
+    0x00000000, // CB_COLOR1_CLEAR_WORD3
+    0x00000000, // CB_COLOR2_BASE
+    0x00000000, // CB_COLOR2_PITCH
+    0x00000000, // CB_COLOR2_SLICE
+    0x00000000, // CB_COLOR2_VIEW
+    0x00000000, // CB_COLOR2_INFO
+    0x00000000, // CB_COLOR2_ATTRIB
+    0x00000000, // CB_COLOR2_DIM
+    0x00000000, // CB_COLOR2_CMASK
+    0x00000000, // CB_COLOR2_CMASK_SLICE
+    0x00000000, // CB_COLOR2_FMASK
+    0x00000000, // CB_COLOR2_FMASK_SLICE
+    0x00000000, // CB_COLOR2_CLEAR_WORD0
+    0x00000000, // CB_COLOR2_CLEAR_WORD1
+    0x00000000, // CB_COLOR2_CLEAR_WORD2
+    0x00000000, // CB_COLOR2_CLEAR_WORD3
+    0x00000000, // CB_COLOR3_BASE
+    0x00000000, // CB_COLOR3_PITCH
+    0x00000000, // CB_COLOR3_SLICE
+    0x00000000, // CB_COLOR3_VIEW
+    0x00000000, // CB_COLOR3_INFO
+    0x00000000, // CB_COLOR3_ATTRIB
+    0x00000000, // CB_COLOR3_DIM
+    0x00000000, // CB_COLOR3_CMASK
+    0x00000000, // CB_COLOR3_CMASK_SLICE
+    0x00000000, // CB_COLOR3_FMASK
+    0x00000000, // CB_COLOR3_FMASK_SLICE
+    0x00000000, // CB_COLOR3_CLEAR_WORD0
+    0x00000000, // CB_COLOR3_CLEAR_WORD1
+    0x00000000, // CB_COLOR3_CLEAR_WORD2
+    0x00000000, // CB_COLOR3_CLEAR_WORD3
+    0x00000000, // CB_COLOR4_BASE
+    0x00000000, // CB_COLOR4_PITCH
+    0x00000000, // CB_COLOR4_SLICE
+    0x00000000, // CB_COLOR4_VIEW
+    0x00000000, // CB_COLOR4_INFO
+    0x00000000, // CB_COLOR4_ATTRIB
+    0x00000000, // CB_COLOR4_DIM
+    0x00000000, // CB_COLOR4_CMASK
+    0x00000000, // CB_COLOR4_CMASK_SLICE
+    0x00000000, // CB_COLOR4_FMASK
+    0x00000000, // CB_COLOR4_FMASK_SLICE
+    0x00000000, // CB_COLOR4_CLEAR_WORD0
+    0x00000000, // CB_COLOR4_CLEAR_WORD1
+    0x00000000, // CB_COLOR4_CLEAR_WORD2
+    0x00000000, // CB_COLOR4_CLEAR_WORD3
+    0x00000000, // CB_COLOR5_BASE
+    0x00000000, // CB_COLOR5_PITCH
+    0x00000000, // CB_COLOR5_SLICE
+    0x00000000, // CB_COLOR5_VIEW
+    0x00000000, // CB_COLOR5_INFO
+    0x00000000, // CB_COLOR5_ATTRIB
+    0x00000000, // CB_COLOR5_DIM
+    0x00000000, // CB_COLOR5_CMASK
+    0x00000000, // CB_COLOR5_CMASK_SLICE
+    0x00000000, // CB_COLOR5_FMASK
+    0x00000000, // CB_COLOR5_FMASK_SLICE
+    0x00000000, // CB_COLOR5_CLEAR_WORD0
+    0x00000000, // CB_COLOR5_CLEAR_WORD1
+    0x00000000, // CB_COLOR5_CLEAR_WORD2
+    0x00000000, // CB_COLOR5_CLEAR_WORD3
+    0x00000000, // CB_COLOR6_BASE
+    0x00000000, // CB_COLOR6_PITCH
+    0x00000000, // CB_COLOR6_SLICE
+    0x00000000, // CB_COLOR6_VIEW
+    0x00000000, // CB_COLOR6_INFO
+    0x00000000, // CB_COLOR6_ATTRIB
+    0x00000000, // CB_COLOR6_DIM
+    0x00000000, // CB_COLOR6_CMASK
+    0x00000000, // CB_COLOR6_CMASK_SLICE
+    0x00000000, // CB_COLOR6_FMASK
+    0x00000000, // CB_COLOR6_FMASK_SLICE
+    0x00000000, // CB_COLOR6_CLEAR_WORD0
+    0x00000000, // CB_COLOR6_CLEAR_WORD1
+    0x00000000, // CB_COLOR6_CLEAR_WORD2
+    0x00000000, // CB_COLOR6_CLEAR_WORD3
+    0x00000000, // CB_COLOR7_BASE
+    0x00000000, // CB_COLOR7_PITCH
+    0x00000000, // CB_COLOR7_SLICE
+    0x00000000, // CB_COLOR7_VIEW
+    0x00000000, // CB_COLOR7_INFO
+    0x00000000, // CB_COLOR7_ATTRIB
+    0x00000000, // CB_COLOR7_DIM
+    0x00000000, // CB_COLOR7_CMASK
+    0x00000000, // CB_COLOR7_CMASK_SLICE
+    0x00000000, // CB_COLOR7_FMASK
+    0x00000000, // CB_COLOR7_FMASK_SLICE
+    0x00000000, // CB_COLOR7_CLEAR_WORD0
+    0x00000000, // CB_COLOR7_CLEAR_WORD1
+    0x00000000, // CB_COLOR7_CLEAR_WORD2
+    0x00000000, // CB_COLOR7_CLEAR_WORD3
+    0x00000000, // CB_COLOR8_BASE
+    0x00000000, // CB_COLOR8_PITCH
+    0x00000000, // CB_COLOR8_SLICE
+    0x00000000, // CB_COLOR8_VIEW
+    0x00000000, // CB_COLOR8_INFO
+    0x00000000, // CB_COLOR8_ATTRIB
+    0x00000000, // CB_COLOR8_DIM
+    0x00000000, // CB_COLOR9_BASE
+    0x00000000, // CB_COLOR9_PITCH
+    0x00000000, // CB_COLOR9_SLICE
+    0x00000000, // CB_COLOR9_VIEW
+    0x00000000, // CB_COLOR9_INFO
+    0x00000000, // CB_COLOR9_ATTRIB
+    0x00000000, // CB_COLOR9_DIM
+    0x00000000, // CB_COLOR10_BASE
+    0x00000000, // CB_COLOR10_PITCH
+    0x00000000, // CB_COLOR10_SLICE
+    0x00000000, // CB_COLOR10_VIEW
+    0x00000000, // CB_COLOR10_INFO
+    0x00000000, // CB_COLOR10_ATTRIB
+    0x00000000, // CB_COLOR10_DIM
+    0x00000000, // CB_COLOR11_BASE
+    0x00000000, // CB_COLOR11_PITCH
+    0x00000000, // CB_COLOR11_SLICE
+    0x00000000, // CB_COLOR11_VIEW
+    0x00000000, // CB_COLOR11_INFO
+    0x00000000, // CB_COLOR11_ATTRIB
+    0x00000000, // CB_COLOR11_DIM
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_HS_15
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_0
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_1
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_2
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_3
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_4
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_5
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_6
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_7
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_8
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_9
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_10
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_11
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_12
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_13
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_14
+    0x00000000, // SQ_ALU_CONST_CACHE_LS_15
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_HS_15
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_0
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_1
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_2
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_3
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_4
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_5
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_6
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_7
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_8
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_9
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_10
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_11
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_12
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_13
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_14
+    0x00000000, // SQ_ALU_CONST_BUFFER_SIZE_LS_15
+};
+static const struct cs_extent_def SECT_CONTEXT_defs[] =
+{
+    {SECT_CONTEXT_def_1, 0x0000a000, 488 },
+    {SECT_CONTEXT_def_2, 0x0000a1f5, 6 },
+    {SECT_CONTEXT_def_3, 0x0000a200, 55 },
+    {SECT_CONTEXT_def_4, 0x0000a23a, 98 },
+    {SECT_CONTEXT_def_5, 0x0000a29e, 5 },
+    {SECT_CONTEXT_def_6, 0x0000a2a5, 56 },
+    {SECT_CONTEXT_def_7, 0x0000a2de, 290 },
+    { 0, 0, 0 }
+};
+static const u32 SECT_CLEAR_def_1[] =
+{
+    0xffffffff, // SQ_TEX_SAMPLER_CLEAR
+    0xffffffff, // SQ_TEX_RESOURCE_CLEAR
+    0xffffffff, // SQ_LOOP_BOOL_CLEAR
+};
+static const struct cs_extent_def SECT_CLEAR_defs[] =
+{
+    {SECT_CLEAR_def_1, 0x0000ffc0, 3 },
+    { 0, 0, 0 }
+};
+static const u32 SECT_CTRLCONST_def_1[] =
+{
+    0x00000000, // SQ_VTX_BASE_VTX_LOC
+    0x00000000, // SQ_VTX_START_INST_LOC
+};
+static const struct cs_extent_def SECT_CTRLCONST_defs[] =
+{
+    {SECT_CTRLCONST_def_1, 0x0000f3fc, 2 },
+    { 0, 0, 0 }
+};
+struct cs_section_def evergreen_cs_data[] = {
+    { SECT_CONTEXT_defs, SECT_CONTEXT },
+    { SECT_CLEAR_defs, SECT_CLEAR },
+    { SECT_CTRLCONST_defs, SECT_CTRLCONST },
+    { 0, SECT_NONE }
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/clearstate_si.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/clearstate_si.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/clearstate_si.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/clearstate_si.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,941 @@
+/*
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ */
+
+static const u32 si_SECT_CONTEXT_def_1[] =
+{
+    0x00000000, // DB_RENDER_CONTROL
+    0x00000000, // DB_COUNT_CONTROL
+    0x00000000, // DB_DEPTH_VIEW
+    0x00000000, // DB_RENDER_OVERRIDE
+    0x00000000, // DB_RENDER_OVERRIDE2
+    0x00000000, // DB_HTILE_DATA_BASE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // DB_DEPTH_BOUNDS_MIN
+    0x00000000, // DB_DEPTH_BOUNDS_MAX
+    0x00000000, // DB_STENCIL_CLEAR
+    0x00000000, // DB_DEPTH_CLEAR
+    0x00000000, // PA_SC_SCREEN_SCISSOR_TL
+    0x40004000, // PA_SC_SCREEN_SCISSOR_BR
+    0, // HOLE
+    0x00000000, // DB_DEPTH_INFO
+    0x00000000, // DB_Z_INFO
+    0x00000000, // DB_STENCIL_INFO
+    0x00000000, // DB_Z_READ_BASE
+    0x00000000, // DB_STENCIL_READ_BASE
+    0x00000000, // DB_Z_WRITE_BASE
+    0x00000000, // DB_STENCIL_WRITE_BASE
+    0x00000000, // DB_DEPTH_SIZE
+    0x00000000, // DB_DEPTH_SLICE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // TA_BC_BASE_ADDR
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // COHER_DEST_BASE_2
+    0x00000000, // COHER_DEST_BASE_3
+    0x00000000, // PA_SC_WINDOW_OFFSET
+    0x80000000, // PA_SC_WINDOW_SCISSOR_TL
+    0x40004000, // PA_SC_WINDOW_SCISSOR_BR
+    0x0000ffff, // PA_SC_CLIPRECT_RULE
+    0x00000000, // PA_SC_CLIPRECT_0_TL
+    0x40004000, // PA_SC_CLIPRECT_0_BR
+    0x00000000, // PA_SC_CLIPRECT_1_TL
+    0x40004000, // PA_SC_CLIPRECT_1_BR
+    0x00000000, // PA_SC_CLIPRECT_2_TL
+    0x40004000, // PA_SC_CLIPRECT_2_BR
+    0x00000000, // PA_SC_CLIPRECT_3_TL
+    0x40004000, // PA_SC_CLIPRECT_3_BR
+    0xaa99aaaa, // PA_SC_EDGERULE
+    0x00000000, // PA_SU_HARDWARE_SCREEN_OFFSET
+    0xffffffff, // CB_TARGET_MASK
+    0xffffffff, // CB_SHADER_MASK
+    0x80000000, // PA_SC_GENERIC_SCISSOR_TL
+    0x40004000, // PA_SC_GENERIC_SCISSOR_BR
+    0x00000000, // COHER_DEST_BASE_0
+    0x00000000, // COHER_DEST_BASE_1
+    0x80000000, // PA_SC_VPORT_SCISSOR_0_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_0_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_1_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_1_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_2_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_2_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_3_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_3_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_4_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_4_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_5_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_5_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_6_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_6_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_7_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_7_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_8_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_8_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_9_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_9_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_10_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_10_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_11_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_11_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_12_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_12_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_13_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_13_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_14_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_14_BR
+    0x80000000, // PA_SC_VPORT_SCISSOR_15_TL
+    0x40004000, // PA_SC_VPORT_SCISSOR_15_BR
+    0x00000000, // PA_SC_VPORT_ZMIN_0
+    0x3f800000, // PA_SC_VPORT_ZMAX_0
+    0x00000000, // PA_SC_VPORT_ZMIN_1
+    0x3f800000, // PA_SC_VPORT_ZMAX_1
+    0x00000000, // PA_SC_VPORT_ZMIN_2
+    0x3f800000, // PA_SC_VPORT_ZMAX_2
+    0x00000000, // PA_SC_VPORT_ZMIN_3
+    0x3f800000, // PA_SC_VPORT_ZMAX_3
+    0x00000000, // PA_SC_VPORT_ZMIN_4
+    0x3f800000, // PA_SC_VPORT_ZMAX_4
+    0x00000000, // PA_SC_VPORT_ZMIN_5
+    0x3f800000, // PA_SC_VPORT_ZMAX_5
+    0x00000000, // PA_SC_VPORT_ZMIN_6
+    0x3f800000, // PA_SC_VPORT_ZMAX_6
+    0x00000000, // PA_SC_VPORT_ZMIN_7
+    0x3f800000, // PA_SC_VPORT_ZMAX_7
+    0x00000000, // PA_SC_VPORT_ZMIN_8
+    0x3f800000, // PA_SC_VPORT_ZMAX_8
+    0x00000000, // PA_SC_VPORT_ZMIN_9
+    0x3f800000, // PA_SC_VPORT_ZMAX_9
+    0x00000000, // PA_SC_VPORT_ZMIN_10
+    0x3f800000, // PA_SC_VPORT_ZMAX_10
+    0x00000000, // PA_SC_VPORT_ZMIN_11
+    0x3f800000, // PA_SC_VPORT_ZMAX_11
+    0x00000000, // PA_SC_VPORT_ZMIN_12
+    0x3f800000, // PA_SC_VPORT_ZMAX_12
+    0x00000000, // PA_SC_VPORT_ZMIN_13
+    0x3f800000, // PA_SC_VPORT_ZMAX_13
+    0x00000000, // PA_SC_VPORT_ZMIN_14
+    0x3f800000, // PA_SC_VPORT_ZMAX_14
+    0x00000000, // PA_SC_VPORT_ZMIN_15
+    0x3f800000, // PA_SC_VPORT_ZMAX_15
+};
+static const u32 si_SECT_CONTEXT_def_2[] =
+{
+    0x00000000, // CP_PERFMON_CNTX_CNTL
+    0x00000000, // CP_RINGID
+    0x00000000, // CP_VMID
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0xffffffff, // VGT_MAX_VTX_INDX
+    0x00000000, // VGT_MIN_VTX_INDX
+    0x00000000, // VGT_INDX_OFFSET
+    0x00000000, // VGT_MULTI_PRIM_IB_RESET_INDX
+    0, // HOLE
+    0x00000000, // CB_BLEND_RED
+    0x00000000, // CB_BLEND_GREEN
+    0x00000000, // CB_BLEND_BLUE
+    0x00000000, // CB_BLEND_ALPHA
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // DB_STENCIL_CONTROL
+    0x00000000, // DB_STENCILREFMASK
+    0x00000000, // DB_STENCILREFMASK_BF
+    0, // HOLE
+    0x00000000, // PA_CL_VPORT_XSCALE
+    0x00000000, // PA_CL_VPORT_XOFFSET
+    0x00000000, // PA_CL_VPORT_YSCALE
+    0x00000000, // PA_CL_VPORT_YOFFSET
+    0x00000000, // PA_CL_VPORT_ZSCALE
+    0x00000000, // PA_CL_VPORT_ZOFFSET
+    0x00000000, // PA_CL_VPORT_XSCALE_1
+    0x00000000, // PA_CL_VPORT_XOFFSET_1
+    0x00000000, // PA_CL_VPORT_YSCALE_1
+    0x00000000, // PA_CL_VPORT_YOFFSET_1
+    0x00000000, // PA_CL_VPORT_ZSCALE_1
+    0x00000000, // PA_CL_VPORT_ZOFFSET_1
+    0x00000000, // PA_CL_VPORT_XSCALE_2
+    0x00000000, // PA_CL_VPORT_XOFFSET_2
+    0x00000000, // PA_CL_VPORT_YSCALE_2
+    0x00000000, // PA_CL_VPORT_YOFFSET_2
+    0x00000000, // PA_CL_VPORT_ZSCALE_2
+    0x00000000, // PA_CL_VPORT_ZOFFSET_2
+    0x00000000, // PA_CL_VPORT_XSCALE_3
+    0x00000000, // PA_CL_VPORT_XOFFSET_3
+    0x00000000, // PA_CL_VPORT_YSCALE_3
+    0x00000000, // PA_CL_VPORT_YOFFSET_3
+    0x00000000, // PA_CL_VPORT_ZSCALE_3
+    0x00000000, // PA_CL_VPORT_ZOFFSET_3
+    0x00000000, // PA_CL_VPORT_XSCALE_4
+    0x00000000, // PA_CL_VPORT_XOFFSET_4
+    0x00000000, // PA_CL_VPORT_YSCALE_4
+    0x00000000, // PA_CL_VPORT_YOFFSET_4
+    0x00000000, // PA_CL_VPORT_ZSCALE_4
+    0x00000000, // PA_CL_VPORT_ZOFFSET_4
+    0x00000000, // PA_CL_VPORT_XSCALE_5
+    0x00000000, // PA_CL_VPORT_XOFFSET_5
+    0x00000000, // PA_CL_VPORT_YSCALE_5
+    0x00000000, // PA_CL_VPORT_YOFFSET_5
+    0x00000000, // PA_CL_VPORT_ZSCALE_5
+    0x00000000, // PA_CL_VPORT_ZOFFSET_5
+    0x00000000, // PA_CL_VPORT_XSCALE_6
+    0x00000000, // PA_CL_VPORT_XOFFSET_6
+    0x00000000, // PA_CL_VPORT_YSCALE_6
+    0x00000000, // PA_CL_VPORT_YOFFSET_6
+    0x00000000, // PA_CL_VPORT_ZSCALE_6
+    0x00000000, // PA_CL_VPORT_ZOFFSET_6
+    0x00000000, // PA_CL_VPORT_XSCALE_7
+    0x00000000, // PA_CL_VPORT_XOFFSET_7
+    0x00000000, // PA_CL_VPORT_YSCALE_7
+    0x00000000, // PA_CL_VPORT_YOFFSET_7
+    0x00000000, // PA_CL_VPORT_ZSCALE_7
+    0x00000000, // PA_CL_VPORT_ZOFFSET_7
+    0x00000000, // PA_CL_VPORT_XSCALE_8
+    0x00000000, // PA_CL_VPORT_XOFFSET_8
+    0x00000000, // PA_CL_VPORT_YSCALE_8
+    0x00000000, // PA_CL_VPORT_YOFFSET_8
+    0x00000000, // PA_CL_VPORT_ZSCALE_8
+    0x00000000, // PA_CL_VPORT_ZOFFSET_8
+    0x00000000, // PA_CL_VPORT_XSCALE_9
+    0x00000000, // PA_CL_VPORT_XOFFSET_9
+    0x00000000, // PA_CL_VPORT_YSCALE_9
+    0x00000000, // PA_CL_VPORT_YOFFSET_9
+    0x00000000, // PA_CL_VPORT_ZSCALE_9
+    0x00000000, // PA_CL_VPORT_ZOFFSET_9
+    0x00000000, // PA_CL_VPORT_XSCALE_10
+    0x00000000, // PA_CL_VPORT_XOFFSET_10
+    0x00000000, // PA_CL_VPORT_YSCALE_10
+    0x00000000, // PA_CL_VPORT_YOFFSET_10
+    0x00000000, // PA_CL_VPORT_ZSCALE_10
+    0x00000000, // PA_CL_VPORT_ZOFFSET_10
+    0x00000000, // PA_CL_VPORT_XSCALE_11
+    0x00000000, // PA_CL_VPORT_XOFFSET_11
+    0x00000000, // PA_CL_VPORT_YSCALE_11
+    0x00000000, // PA_CL_VPORT_YOFFSET_11
+    0x00000000, // PA_CL_VPORT_ZSCALE_11
+    0x00000000, // PA_CL_VPORT_ZOFFSET_11
+    0x00000000, // PA_CL_VPORT_XSCALE_12
+    0x00000000, // PA_CL_VPORT_XOFFSET_12
+    0x00000000, // PA_CL_VPORT_YSCALE_12
+    0x00000000, // PA_CL_VPORT_YOFFSET_12
+    0x00000000, // PA_CL_VPORT_ZSCALE_12
+    0x00000000, // PA_CL_VPORT_ZOFFSET_12
+    0x00000000, // PA_CL_VPORT_XSCALE_13
+    0x00000000, // PA_CL_VPORT_XOFFSET_13
+    0x00000000, // PA_CL_VPORT_YSCALE_13
+    0x00000000, // PA_CL_VPORT_YOFFSET_13
+    0x00000000, // PA_CL_VPORT_ZSCALE_13
+    0x00000000, // PA_CL_VPORT_ZOFFSET_13
+    0x00000000, // PA_CL_VPORT_XSCALE_14
+    0x00000000, // PA_CL_VPORT_XOFFSET_14
+    0x00000000, // PA_CL_VPORT_YSCALE_14
+    0x00000000, // PA_CL_VPORT_YOFFSET_14
+    0x00000000, // PA_CL_VPORT_ZSCALE_14
+    0x00000000, // PA_CL_VPORT_ZOFFSET_14
+    0x00000000, // PA_CL_VPORT_XSCALE_15
+    0x00000000, // PA_CL_VPORT_XOFFSET_15
+    0x00000000, // PA_CL_VPORT_YSCALE_15
+    0x00000000, // PA_CL_VPORT_YOFFSET_15
+    0x00000000, // PA_CL_VPORT_ZSCALE_15
+    0x00000000, // PA_CL_VPORT_ZOFFSET_15
+    0x00000000, // PA_CL_UCP_0_X
+    0x00000000, // PA_CL_UCP_0_Y
+    0x00000000, // PA_CL_UCP_0_Z
+    0x00000000, // PA_CL_UCP_0_W
+    0x00000000, // PA_CL_UCP_1_X
+    0x00000000, // PA_CL_UCP_1_Y
+    0x00000000, // PA_CL_UCP_1_Z
+    0x00000000, // PA_CL_UCP_1_W
+    0x00000000, // PA_CL_UCP_2_X
+    0x00000000, // PA_CL_UCP_2_Y
+    0x00000000, // PA_CL_UCP_2_Z
+    0x00000000, // PA_CL_UCP_2_W
+    0x00000000, // PA_CL_UCP_3_X
+    0x00000000, // PA_CL_UCP_3_Y
+    0x00000000, // PA_CL_UCP_3_Z
+    0x00000000, // PA_CL_UCP_3_W
+    0x00000000, // PA_CL_UCP_4_X
+    0x00000000, // PA_CL_UCP_4_Y
+    0x00000000, // PA_CL_UCP_4_Z
+    0x00000000, // PA_CL_UCP_4_W
+    0x00000000, // PA_CL_UCP_5_X
+    0x00000000, // PA_CL_UCP_5_Y
+    0x00000000, // PA_CL_UCP_5_Z
+    0x00000000, // PA_CL_UCP_5_W
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SPI_PS_INPUT_CNTL_0
+    0x00000000, // SPI_PS_INPUT_CNTL_1
+    0x00000000, // SPI_PS_INPUT_CNTL_2
+    0x00000000, // SPI_PS_INPUT_CNTL_3
+    0x00000000, // SPI_PS_INPUT_CNTL_4
+    0x00000000, // SPI_PS_INPUT_CNTL_5
+    0x00000000, // SPI_PS_INPUT_CNTL_6
+    0x00000000, // SPI_PS_INPUT_CNTL_7
+    0x00000000, // SPI_PS_INPUT_CNTL_8
+    0x00000000, // SPI_PS_INPUT_CNTL_9
+    0x00000000, // SPI_PS_INPUT_CNTL_10
+    0x00000000, // SPI_PS_INPUT_CNTL_11
+    0x00000000, // SPI_PS_INPUT_CNTL_12
+    0x00000000, // SPI_PS_INPUT_CNTL_13
+    0x00000000, // SPI_PS_INPUT_CNTL_14
+    0x00000000, // SPI_PS_INPUT_CNTL_15
+    0x00000000, // SPI_PS_INPUT_CNTL_16
+    0x00000000, // SPI_PS_INPUT_CNTL_17
+    0x00000000, // SPI_PS_INPUT_CNTL_18
+    0x00000000, // SPI_PS_INPUT_CNTL_19
+    0x00000000, // SPI_PS_INPUT_CNTL_20
+    0x00000000, // SPI_PS_INPUT_CNTL_21
+    0x00000000, // SPI_PS_INPUT_CNTL_22
+    0x00000000, // SPI_PS_INPUT_CNTL_23
+    0x00000000, // SPI_PS_INPUT_CNTL_24
+    0x00000000, // SPI_PS_INPUT_CNTL_25
+    0x00000000, // SPI_PS_INPUT_CNTL_26
+    0x00000000, // SPI_PS_INPUT_CNTL_27
+    0x00000000, // SPI_PS_INPUT_CNTL_28
+    0x00000000, // SPI_PS_INPUT_CNTL_29
+    0x00000000, // SPI_PS_INPUT_CNTL_30
+    0x00000000, // SPI_PS_INPUT_CNTL_31
+    0x00000000, // SPI_VS_OUT_CONFIG
+    0, // HOLE
+    0x00000000, // SPI_PS_INPUT_ENA
+    0x00000000, // SPI_PS_INPUT_ADDR
+    0x00000000, // SPI_INTERP_CONTROL_0
+    0x00000002, // SPI_PS_IN_CONTROL
+    0, // HOLE
+    0x00000000, // SPI_BARYC_CNTL
+    0, // HOLE
+    0x00000000, // SPI_TMPRING_SIZE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // SPI_WAVE_MGMT_1
+    0x00000000, // SPI_WAVE_MGMT_2
+    0x00000000, // SPI_SHADER_POS_FORMAT
+    0x00000000, // SPI_SHADER_Z_FORMAT
+    0x00000000, // SPI_SHADER_COL_FORMAT
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_BLEND0_CONTROL
+    0x00000000, // CB_BLEND1_CONTROL
+    0x00000000, // CB_BLEND2_CONTROL
+    0x00000000, // CB_BLEND3_CONTROL
+    0x00000000, // CB_BLEND4_CONTROL
+    0x00000000, // CB_BLEND5_CONTROL
+    0x00000000, // CB_BLEND6_CONTROL
+    0x00000000, // CB_BLEND7_CONTROL
+};
+static const u32 si_SECT_CONTEXT_def_3[] =
+{
+    0x00000000, // PA_CL_POINT_X_RAD
+    0x00000000, // PA_CL_POINT_Y_RAD
+    0x00000000, // PA_CL_POINT_SIZE
+    0x00000000, // PA_CL_POINT_CULL_RAD
+    0x00000000, // VGT_DMA_BASE_HI
+    0x00000000, // VGT_DMA_BASE
+};
+static const u32 si_SECT_CONTEXT_def_4[] =
+{
+    0x00000000, // DB_DEPTH_CONTROL
+    0x00000000, // DB_EQAA
+    0x00000000, // CB_COLOR_CONTROL
+    0x00000000, // DB_SHADER_CONTROL
+    0x00090000, // PA_CL_CLIP_CNTL
+    0x00000004, // PA_SU_SC_MODE_CNTL
+    0x00000000, // PA_CL_VTE_CNTL
+    0x00000000, // PA_CL_VS_OUT_CNTL
+    0x00000000, // PA_CL_NANINF_CNTL
+    0x00000000, // PA_SU_LINE_STIPPLE_CNTL
+    0x00000000, // PA_SU_LINE_STIPPLE_SCALE
+    0x00000000, // PA_SU_PRIM_FILTER_CNTL
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // PA_SU_POINT_SIZE
+    0x00000000, // PA_SU_POINT_MINMAX
+    0x00000000, // PA_SU_LINE_CNTL
+    0x00000000, // PA_SC_LINE_STIPPLE
+    0x00000000, // VGT_OUTPUT_PATH_CNTL
+    0x00000000, // VGT_HOS_CNTL
+    0x00000000, // VGT_HOS_MAX_TESS_LEVEL
+    0x00000000, // VGT_HOS_MIN_TESS_LEVEL
+    0x00000000, // VGT_HOS_REUSE_DEPTH
+    0x00000000, // VGT_GROUP_PRIM_TYPE
+    0x00000000, // VGT_GROUP_FIRST_DECR
+    0x00000000, // VGT_GROUP_DECR
+    0x00000000, // VGT_GROUP_VECT_0_CNTL
+    0x00000000, // VGT_GROUP_VECT_1_CNTL
+    0x00000000, // VGT_GROUP_VECT_0_FMT_CNTL
+    0x00000000, // VGT_GROUP_VECT_1_FMT_CNTL
+    0x00000000, // VGT_GS_MODE
+    0, // HOLE
+    0x00000000, // PA_SC_MODE_CNTL_0
+    0x00000000, // PA_SC_MODE_CNTL_1
+    0x00000000, // VGT_ENHANCE
+    0x00000100, // VGT_GS_PER_ES
+    0x00000080, // VGT_ES_PER_GS
+    0x00000002, // VGT_GS_PER_VS
+    0x00000000, // VGT_GSVS_RING_OFFSET_1
+    0x00000000, // VGT_GSVS_RING_OFFSET_2
+    0x00000000, // VGT_GSVS_RING_OFFSET_3
+    0x00000000, // VGT_GS_OUT_PRIM_TYPE
+    0x00000000, // IA_ENHANCE
+};
+static const u32 si_SECT_CONTEXT_def_5[] =
+{
+    0x00000000, // VGT_PRIMITIVEID_EN
+};
+static const u32 si_SECT_CONTEXT_def_6[] =
+{
+    0x00000000, // VGT_PRIMITIVEID_RESET
+};
+static const u32 si_SECT_CONTEXT_def_7[] =
+{
+    0x00000000, // VGT_MULTI_PRIM_IB_RESET_EN
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_INSTANCE_STEP_RATE_0
+    0x00000000, // VGT_INSTANCE_STEP_RATE_1
+    0x000000ff, // IA_MULTI_VGT_PARAM
+    0x00000000, // VGT_ESGS_RING_ITEMSIZE
+    0x00000000, // VGT_GSVS_RING_ITEMSIZE
+    0x00000000, // VGT_REUSE_OFF
+    0x00000000, // VGT_VTX_CNT_EN
+    0x00000000, // DB_HTILE_SURFACE
+    0x00000000, // DB_SRESULTS_COMPARE_STATE0
+    0x00000000, // DB_SRESULTS_COMPARE_STATE1
+    0x00000000, // DB_PRELOAD_CONTROL
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_0
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_0
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_0
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_1
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_1
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_1
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_2
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_2
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_2
+    0x00000000, // VGT_STRMOUT_BUFFER_SIZE_3
+    0x00000000, // VGT_STRMOUT_VTX_STRIDE_3
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_BUFFER_OFFSET_3
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_OFFSET
+    0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
+    0x00000000, // VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
+    0, // HOLE
+    0x00000000, // VGT_GS_MAX_VERT_OUT
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // VGT_SHADER_STAGES_EN
+    0x00000000, // VGT_LS_HS_CONFIG
+    0x00000000, // VGT_GS_VERT_ITEMSIZE
+    0x00000000, // VGT_GS_VERT_ITEMSIZE_1
+    0x00000000, // VGT_GS_VERT_ITEMSIZE_2
+    0x00000000, // VGT_GS_VERT_ITEMSIZE_3
+    0x00000000, // VGT_TF_PARAM
+    0x00000000, // DB_ALPHA_TO_MASK
+    0, // HOLE
+    0x00000000, // PA_SU_POLY_OFFSET_DB_FMT_CNTL
+    0x00000000, // PA_SU_POLY_OFFSET_CLAMP
+    0x00000000, // PA_SU_POLY_OFFSET_FRONT_SCALE
+    0x00000000, // PA_SU_POLY_OFFSET_FRONT_OFFSET
+    0x00000000, // PA_SU_POLY_OFFSET_BACK_SCALE
+    0x00000000, // PA_SU_POLY_OFFSET_BACK_OFFSET
+    0x00000000, // VGT_GS_INSTANCE_CNT
+    0x00000000, // VGT_STRMOUT_CONFIG
+    0x00000000, // VGT_STRMOUT_BUFFER_CONFIG
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // PA_SC_CENTROID_PRIORITY_0
+    0x00000000, // PA_SC_CENTROID_PRIORITY_1
+    0x00001000, // PA_SC_LINE_CNTL
+    0x00000000, // PA_SC_AA_CONFIG
+    0x00000005, // PA_SU_VTX_CNTL
+    0x3f800000, // PA_CL_GB_VERT_CLIP_ADJ
+    0x3f800000, // PA_CL_GB_VERT_DISC_ADJ
+    0x3f800000, // PA_CL_GB_HORZ_CLIP_ADJ
+    0x3f800000, // PA_CL_GB_HORZ_DISC_ADJ
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_1
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_2
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_3
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_1
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_2
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_3
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_1
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_2
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_3
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_1
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_2
+    0x00000000, // PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_3
+    0xffffffff, // PA_SC_AA_MASK_X0Y0_X1Y0
+    0xffffffff, // PA_SC_AA_MASK_X0Y1_X1Y1
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0, // HOLE
+    0x0000000e, // VGT_VERTEX_REUSE_BLOCK_CNTL
+    0x00000010, // VGT_OUT_DEALLOC_CNTL
+    0x00000000, // CB_COLOR0_BASE
+    0x00000000, // CB_COLOR0_PITCH
+    0x00000000, // CB_COLOR0_SLICE
+    0x00000000, // CB_COLOR0_VIEW
+    0x00000000, // CB_COLOR0_INFO
+    0x00000000, // CB_COLOR0_ATTRIB
+    0, // HOLE
+    0x00000000, // CB_COLOR0_CMASK
+    0x00000000, // CB_COLOR0_CMASK_SLICE
+    0x00000000, // CB_COLOR0_FMASK
+    0x00000000, // CB_COLOR0_FMASK_SLICE
+    0x00000000, // CB_COLOR0_CLEAR_WORD0
+    0x00000000, // CB_COLOR0_CLEAR_WORD1
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_COLOR1_BASE
+    0x00000000, // CB_COLOR1_PITCH
+    0x00000000, // CB_COLOR1_SLICE
+    0x00000000, // CB_COLOR1_VIEW
+    0x00000000, // CB_COLOR1_INFO
+    0x00000000, // CB_COLOR1_ATTRIB
+    0, // HOLE
+    0x00000000, // CB_COLOR1_CMASK
+    0x00000000, // CB_COLOR1_CMASK_SLICE
+    0x00000000, // CB_COLOR1_FMASK
+    0x00000000, // CB_COLOR1_FMASK_SLICE
+    0x00000000, // CB_COLOR1_CLEAR_WORD0
+    0x00000000, // CB_COLOR1_CLEAR_WORD1
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_COLOR2_BASE
+    0x00000000, // CB_COLOR2_PITCH
+    0x00000000, // CB_COLOR2_SLICE
+    0x00000000, // CB_COLOR2_VIEW
+    0x00000000, // CB_COLOR2_INFO
+    0x00000000, // CB_COLOR2_ATTRIB
+    0, // HOLE
+    0x00000000, // CB_COLOR2_CMASK
+    0x00000000, // CB_COLOR2_CMASK_SLICE
+    0x00000000, // CB_COLOR2_FMASK
+    0x00000000, // CB_COLOR2_FMASK_SLICE
+    0x00000000, // CB_COLOR2_CLEAR_WORD0
+    0x00000000, // CB_COLOR2_CLEAR_WORD1
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_COLOR3_BASE
+    0x00000000, // CB_COLOR3_PITCH
+    0x00000000, // CB_COLOR3_SLICE
+    0x00000000, // CB_COLOR3_VIEW
+    0x00000000, // CB_COLOR3_INFO
+    0x00000000, // CB_COLOR3_ATTRIB
+    0, // HOLE
+    0x00000000, // CB_COLOR3_CMASK
+    0x00000000, // CB_COLOR3_CMASK_SLICE
+    0x00000000, // CB_COLOR3_FMASK
+    0x00000000, // CB_COLOR3_FMASK_SLICE
+    0x00000000, // CB_COLOR3_CLEAR_WORD0
+    0x00000000, // CB_COLOR3_CLEAR_WORD1
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_COLOR4_BASE
+    0x00000000, // CB_COLOR4_PITCH
+    0x00000000, // CB_COLOR4_SLICE
+    0x00000000, // CB_COLOR4_VIEW
+    0x00000000, // CB_COLOR4_INFO
+    0x00000000, // CB_COLOR4_ATTRIB
+    0, // HOLE
+    0x00000000, // CB_COLOR4_CMASK
+    0x00000000, // CB_COLOR4_CMASK_SLICE
+    0x00000000, // CB_COLOR4_FMASK
+    0x00000000, // CB_COLOR4_FMASK_SLICE
+    0x00000000, // CB_COLOR4_CLEAR_WORD0
+    0x00000000, // CB_COLOR4_CLEAR_WORD1
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_COLOR5_BASE
+    0x00000000, // CB_COLOR5_PITCH
+    0x00000000, // CB_COLOR5_SLICE
+    0x00000000, // CB_COLOR5_VIEW
+    0x00000000, // CB_COLOR5_INFO
+    0x00000000, // CB_COLOR5_ATTRIB
+    0, // HOLE
+    0x00000000, // CB_COLOR5_CMASK
+    0x00000000, // CB_COLOR5_CMASK_SLICE
+    0x00000000, // CB_COLOR5_FMASK
+    0x00000000, // CB_COLOR5_FMASK_SLICE
+    0x00000000, // CB_COLOR5_CLEAR_WORD0
+    0x00000000, // CB_COLOR5_CLEAR_WORD1
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_COLOR6_BASE
+    0x00000000, // CB_COLOR6_PITCH
+    0x00000000, // CB_COLOR6_SLICE
+    0x00000000, // CB_COLOR6_VIEW
+    0x00000000, // CB_COLOR6_INFO
+    0x00000000, // CB_COLOR6_ATTRIB
+    0, // HOLE
+    0x00000000, // CB_COLOR6_CMASK
+    0x00000000, // CB_COLOR6_CMASK_SLICE
+    0x00000000, // CB_COLOR6_FMASK
+    0x00000000, // CB_COLOR6_FMASK_SLICE
+    0x00000000, // CB_COLOR6_CLEAR_WORD0
+    0x00000000, // CB_COLOR6_CLEAR_WORD1
+    0, // HOLE
+    0, // HOLE
+    0x00000000, // CB_COLOR7_BASE
+    0x00000000, // CB_COLOR7_PITCH
+    0x00000000, // CB_COLOR7_SLICE
+    0x00000000, // CB_COLOR7_VIEW
+    0x00000000, // CB_COLOR7_INFO
+    0x00000000, // CB_COLOR7_ATTRIB
+    0, // HOLE
+    0x00000000, // CB_COLOR7_CMASK
+    0x00000000, // CB_COLOR7_CMASK_SLICE
+    0x00000000, // CB_COLOR7_FMASK
+    0x00000000, // CB_COLOR7_FMASK_SLICE
+    0x00000000, // CB_COLOR7_CLEAR_WORD0
+    0x00000000, // CB_COLOR7_CLEAR_WORD1
+};
+static const struct cs_extent_def si_SECT_CONTEXT_defs[] =
+{
+    {si_SECT_CONTEXT_def_1, 0x0000a000, 212 },
+    {si_SECT_CONTEXT_def_2, 0x0000a0d8, 272 },
+    {si_SECT_CONTEXT_def_3, 0x0000a1f5, 6 },
+    {si_SECT_CONTEXT_def_4, 0x0000a200, 157 },
+    {si_SECT_CONTEXT_def_5, 0x0000a2a1, 1 },
+    {si_SECT_CONTEXT_def_6, 0x0000a2a3, 1 },
+    {si_SECT_CONTEXT_def_7, 0x0000a2a5, 233 },
+    { 0, 0, 0 }
+};
+static const struct cs_section_def si_cs_data[] = {
+    { si_SECT_CONTEXT_defs, SECT_CONTEXT },
+    { 0, SECT_NONE }
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cypress_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cypress_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cypress_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cypress_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2176 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "evergreend.h"
+#include "r600_dpm.h"
+#include "cypress_dpm.h"
+#include "atom.h"
+
+#define SMC_RAM_END 0x8000
+
+#define MC_CG_ARB_FREQ_F0           0x0a
+#define MC_CG_ARB_FREQ_F1           0x0b
+#define MC_CG_ARB_FREQ_F2           0x0c
+#define MC_CG_ARB_FREQ_F3           0x0d
+
+#define MC_CG_SEQ_DRAMCONF_S0       0x05
+#define MC_CG_SEQ_DRAMCONF_S1       0x06
+#define MC_CG_SEQ_YCLK_SUSPEND      0x04
+#define MC_CG_SEQ_YCLK_RESUME       0x0a
+
+struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
+struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
+
+static void cypress_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
+						 bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 tmp, bif;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+	if (enable) {
+		if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+		    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+			if (!pi->boot_in_gen2) {
+				bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
+				bif |= CG_CLIENT_REQ(0xd);
+				WREG32(CG_BIF_REQ_AND_RSP, bif);
+
+				tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+				tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
+				tmp |= LC_GEN2_EN_STRAP;
+
+				tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT;
+				WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+				udelay(10);
+				tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
+				WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+			}
+		}
+	} else {
+		if (!pi->boot_in_gen2) {
+			tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+			tmp &= ~LC_GEN2_EN_STRAP;
+		}
+		if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
+		    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
+			WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+	}
+}
+
+static void cypress_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
+					     bool enable)
+{
+	cypress_enable_bif_dynamic_pcie_gen2(rdev, enable);
+
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
+}
+
+#if 0
+static int cypress_enter_ulp_state(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (pi->gfx_clock_gating) {
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
+		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
+
+		RREG32(GB_ADDR_CONFIG);
+	}
+
+	WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_SwitchToMinimumPower),
+		 ~HOST_SMC_MSG_MASK);
+
+	udelay(7000);
+
+	return 0;
+}
+#endif
+
+static void cypress_gfx_clock_gating_enable(struct radeon_device *rdev,
+					    bool enable)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (enable) {
+		if (eg_pi->light_sleep) {
+			WREG32(GRBM_GFX_INDEX, 0xC0000000);
+
+			WREG32_CG(CG_CGLS_TILE_0, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_1, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_2, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_3, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_4, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_5, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_6, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_7, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_8, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_9, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_10, 0xFFFFFFFF);
+			WREG32_CG(CG_CGLS_TILE_11, 0xFFFFFFFF);
+
+			WREG32_P(SCLK_PWRMGT_CNTL, DYN_LIGHT_SLEEP_EN, ~DYN_LIGHT_SLEEP_EN);
+		}
+		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
+	} else {
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
+		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
+		RREG32(GB_ADDR_CONFIG);
+
+		if (eg_pi->light_sleep) {
+			WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_LIGHT_SLEEP_EN);
+
+			WREG32(GRBM_GFX_INDEX, 0xC0000000);
+
+			WREG32_CG(CG_CGLS_TILE_0, 0);
+			WREG32_CG(CG_CGLS_TILE_1, 0);
+			WREG32_CG(CG_CGLS_TILE_2, 0);
+			WREG32_CG(CG_CGLS_TILE_3, 0);
+			WREG32_CG(CG_CGLS_TILE_4, 0);
+			WREG32_CG(CG_CGLS_TILE_5, 0);
+			WREG32_CG(CG_CGLS_TILE_6, 0);
+			WREG32_CG(CG_CGLS_TILE_7, 0);
+			WREG32_CG(CG_CGLS_TILE_8, 0);
+			WREG32_CG(CG_CGLS_TILE_9, 0);
+			WREG32_CG(CG_CGLS_TILE_10, 0);
+			WREG32_CG(CG_CGLS_TILE_11, 0);
+		}
+	}
+}
+
+static void cypress_mg_clock_gating_enable(struct radeon_device *rdev,
+					   bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (enable) {
+		u32 cgts_sm_ctrl_reg;
+
+		if (rdev->family == CHIP_CEDAR)
+			cgts_sm_ctrl_reg = CEDAR_MGCGCGTSSMCTRL_DFLT;
+		else if (rdev->family == CHIP_REDWOOD)
+			cgts_sm_ctrl_reg = REDWOOD_MGCGCGTSSMCTRL_DFLT;
+		else
+			cgts_sm_ctrl_reg = CYPRESS_MGCGCGTSSMCTRL_DFLT;
+
+		WREG32(GRBM_GFX_INDEX, 0xC0000000);
+
+		WREG32_CG(CG_CGTT_LOCAL_0, CYPRESS_MGCGTTLOCAL0_DFLT);
+		WREG32_CG(CG_CGTT_LOCAL_1, CYPRESS_MGCGTTLOCAL1_DFLT & 0xFFFFCFFF);
+		WREG32_CG(CG_CGTT_LOCAL_2, CYPRESS_MGCGTTLOCAL2_DFLT);
+		WREG32_CG(CG_CGTT_LOCAL_3, CYPRESS_MGCGTTLOCAL3_DFLT);
+
+		if (pi->mgcgtssm)
+			WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg);
+
+		if (eg_pi->mcls) {
+			WREG32_P(MC_CITF_MISC_RD_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE);
+			WREG32_P(MC_CITF_MISC_WR_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE);
+			WREG32_P(MC_CITF_MISC_VM_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE);
+			WREG32_P(MC_HUB_MISC_HUB_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE);
+			WREG32_P(MC_HUB_MISC_VM_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE);
+			WREG32_P(MC_HUB_MISC_SIP_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE);
+			WREG32_P(MC_XPB_CLK_GAT, MEM_LS_ENABLE, ~MEM_LS_ENABLE);
+			WREG32_P(VM_L2_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE);
+		}
+	} else {
+		WREG32(GRBM_GFX_INDEX, 0xC0000000);
+
+		WREG32_CG(CG_CGTT_LOCAL_0, 0xFFFFFFFF);
+		WREG32_CG(CG_CGTT_LOCAL_1, 0xFFFFFFFF);
+		WREG32_CG(CG_CGTT_LOCAL_2, 0xFFFFFFFF);
+		WREG32_CG(CG_CGTT_LOCAL_3, 0xFFFFFFFF);
+
+		if (pi->mgcgtssm)
+			WREG32(CGTS_SM_CTRL_REG, 0x81f44bc0);
+	}
+}
+
+void cypress_enable_spread_spectrum(struct radeon_device *rdev,
+				    bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (enable) {
+		if (pi->sclk_ss)
+			WREG32_P(GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, ~DYN_SPREAD_SPECTRUM_EN);
+
+		if (pi->mclk_ss)
+			WREG32_P(MPLL_CNTL_MODE, SS_SSEN, ~SS_SSEN);
+	} else {
+		WREG32_P(CG_SPLL_SPREAD_SPECTRUM, 0, ~SSEN);
+		WREG32_P(GENERAL_PWRMGT, 0, ~DYN_SPREAD_SPECTRUM_EN);
+		WREG32_P(MPLL_CNTL_MODE, 0, ~SS_SSEN);
+		WREG32_P(MPLL_CNTL_MODE, 0, ~SS_DSMODE_EN);
+	}
+}
+
+void cypress_start_dpm(struct radeon_device *rdev)
+{
+	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
+}
+
+void cypress_enable_sclk_control(struct radeon_device *rdev,
+				 bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
+	else
+		WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
+}
+
+void cypress_enable_mclk_control(struct radeon_device *rdev,
+				 bool enable)
+{
+	if (enable)
+		WREG32_P(MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF);
+	else
+		WREG32_P(MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF);
+}
+
+int cypress_notify_smc_display_change(struct radeon_device *rdev,
+				      bool has_display)
+{
+	PPSMC_Msg msg = has_display ?
+		(PPSMC_Msg)PPSMC_MSG_HasDisplay : (PPSMC_Msg)PPSMC_MSG_NoDisplay;
+
+	if (rv770_send_msg_to_smc(rdev, msg) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+void cypress_program_response_times(struct radeon_device *rdev)
+{
+	u32 reference_clock;
+	u32 mclk_switch_limit;
+
+	reference_clock = radeon_get_xclk(rdev);
+	mclk_switch_limit = (460 * reference_clock) / 100;
+
+	rv770_write_smc_soft_register(rdev,
+				      RV770_SMC_SOFT_REGISTER_mclk_switch_lim,
+				      mclk_switch_limit);
+
+	rv770_write_smc_soft_register(rdev,
+				      RV770_SMC_SOFT_REGISTER_mvdd_chg_time, 1);
+
+	rv770_write_smc_soft_register(rdev,
+				      RV770_SMC_SOFT_REGISTER_mc_block_delay, 0xAA);
+
+	rv770_program_response_times(rdev);
+
+	if (ASIC_IS_LOMBOK(rdev))
+		rv770_write_smc_soft_register(rdev,
+					      RV770_SMC_SOFT_REGISTER_is_asic_lombok, 1);
+
+}
+
+static int cypress_pcie_performance_request(struct radeon_device *rdev,
+					    u8 perf_req, bool advertise)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 tmp;
+
+	udelay(10);
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+	if ((perf_req == PCIE_PERF_REQ_PECI_GEN1) && (tmp & LC_CURRENT_DATA_RATE))
+		return 0;
+
+#if defined(CONFIG_ACPI)
+	if ((perf_req == PCIE_PERF_REQ_PECI_GEN1) ||
+	    (perf_req == PCIE_PERF_REQ_PECI_GEN2)) {
+		eg_pi->pcie_performance_request_registered = true;
+		return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise);
+	} else if ((perf_req == PCIE_PERF_REQ_REMOVE_REGISTRY) &&
+		   eg_pi->pcie_performance_request_registered) {
+		eg_pi->pcie_performance_request_registered = false;
+		return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise);
+	}
+#endif
+
+	return 0;
+}
+
+void cypress_advertise_gen2_capability(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 tmp;
+
+#if defined(CONFIG_ACPI)
+	radeon_acpi_pcie_notify_device_ready(rdev);
+#endif
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+
+	if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+	    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
+		pi->pcie_gen2 = true;
+	else
+		pi->pcie_gen2 = false;
+
+	if (!pi->pcie_gen2)
+		cypress_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, true);
+
+}
+
+static enum radeon_pcie_gen cypress_get_maximum_link_speed(struct radeon_ps *radeon_state)
+{
+	struct rv7xx_ps *state = rv770_get_ps(radeon_state);
+
+	if (state->high.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
+		return 1;
+	return 0;
+}
+
+void cypress_notify_link_speed_change_after_state_change(struct radeon_device *rdev,
+							 struct radeon_ps *radeon_new_state,
+							 struct radeon_ps *radeon_current_state)
+{
+	enum radeon_pcie_gen pcie_link_speed_target =
+		cypress_get_maximum_link_speed(radeon_new_state);
+	enum radeon_pcie_gen pcie_link_speed_current =
+		cypress_get_maximum_link_speed(radeon_current_state);
+	u8 request;
+
+	if (pcie_link_speed_target < pcie_link_speed_current) {
+		if (pcie_link_speed_target == RADEON_PCIE_GEN1)
+			request = PCIE_PERF_REQ_PECI_GEN1;
+		else if (pcie_link_speed_target == RADEON_PCIE_GEN2)
+			request = PCIE_PERF_REQ_PECI_GEN2;
+		else
+			request = PCIE_PERF_REQ_PECI_GEN3;
+
+		cypress_pcie_performance_request(rdev, request, false);
+	}
+}
+
+void cypress_notify_link_speed_change_before_state_change(struct radeon_device *rdev,
+							  struct radeon_ps *radeon_new_state,
+							  struct radeon_ps *radeon_current_state)
+{
+	enum radeon_pcie_gen pcie_link_speed_target =
+		cypress_get_maximum_link_speed(radeon_new_state);
+	enum radeon_pcie_gen pcie_link_speed_current =
+		cypress_get_maximum_link_speed(radeon_current_state);
+	u8 request;
+
+	if (pcie_link_speed_target > pcie_link_speed_current) {
+		if (pcie_link_speed_target == RADEON_PCIE_GEN1)
+			request = PCIE_PERF_REQ_PECI_GEN1;
+		else if (pcie_link_speed_target == RADEON_PCIE_GEN2)
+			request = PCIE_PERF_REQ_PECI_GEN2;
+		else
+			request = PCIE_PERF_REQ_PECI_GEN3;
+
+		cypress_pcie_performance_request(rdev, request, false);
+	}
+}
+
+static int cypress_populate_voltage_value(struct radeon_device *rdev,
+					  struct atom_voltage_table *table,
+					  u16 value, RV770_SMC_VOLTAGE_VALUE *voltage)
+{
+	unsigned int i;
+
+	for (i = 0; i < table->count; i++) {
+		if (value <= table->entries[i].value) {
+			voltage->index = (u8)i;
+			voltage->value = cpu_to_be16(table->entries[i].value);
+			break;
+		}
+	}
+
+	if (i == table->count)
+		return -EINVAL;
+
+	return 0;
+}
+
+u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u8 result = 0;
+	bool strobe_mode = false;
+
+	if (pi->mem_gddr5) {
+		if (mclk <= pi->mclk_strobe_mode_threshold)
+			strobe_mode = true;
+		result = cypress_get_mclk_frequency_ratio(rdev, mclk, strobe_mode);
+
+		if (strobe_mode)
+			result |= SMC_STROBE_ENABLE;
+	}
+
+	return result;
+}
+
+u32 cypress_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf)
+{
+	u32 ref_clk = rdev->clock.mpll.reference_freq;
+	u32 vco = clkf * ref_clk;
+
+	/* 100 Mhz ref clk */
+	if (ref_clk == 10000) {
+		if (vco > 500000)
+			return 0xC6;
+		if (vco > 400000)
+			return 0x9D;
+		if (vco > 330000)
+			return 0x6C;
+		if (vco > 250000)
+			return 0x2B;
+		if (vco >  160000)
+			return 0x5B;
+		if (vco > 120000)
+			return 0x0A;
+		return 0x4B;
+	}
+
+	/* 27 Mhz ref clk */
+	if (vco > 250000)
+		return 0x8B;
+	if (vco > 200000)
+		return 0xCC;
+	if (vco > 150000)
+		return 0x9B;
+	return 0x6B;
+}
+
+static int cypress_populate_mclk_value(struct radeon_device *rdev,
+				       u32 engine_clock, u32 memory_clock,
+				       RV7XX_SMC_MCLK_VALUE *mclk,
+				       bool strobe_mode, bool dll_state_on)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	u32 mpll_ad_func_cntl =
+		pi->clk_regs.rv770.mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2 =
+		pi->clk_regs.rv770.mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl =
+		pi->clk_regs.rv770.mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2 =
+		pi->clk_regs.rv770.mpll_dq_func_cntl_2;
+	u32 mclk_pwrmgt_cntl =
+		pi->clk_regs.rv770.mclk_pwrmgt_cntl;
+	u32 dll_cntl =
+		pi->clk_regs.rv770.dll_cntl;
+	u32 mpll_ss1 = pi->clk_regs.rv770.mpll_ss1;
+	u32 mpll_ss2 = pi->clk_regs.rv770.mpll_ss2;
+	struct atom_clock_dividers dividers;
+	u32 ibias;
+	u32 dll_speed;
+	int ret;
+	u32 mc_seq_misc7;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
+					     memory_clock, strobe_mode, &dividers);
+	if (ret)
+		return ret;
+
+	if (!strobe_mode) {
+		mc_seq_misc7 = RREG32(MC_SEQ_MISC7);
+
+		if(mc_seq_misc7 & 0x8000000)
+			dividers.post_div = 1;
+	}
+
+	ibias = cypress_map_clkf_to_ibias(rdev, dividers.whole_fb_div);
+
+	mpll_ad_func_cntl &= ~(CLKR_MASK |
+			       YCLK_POST_DIV_MASK |
+			       CLKF_MASK |
+			       CLKFRAC_MASK |
+			       IBIAS_MASK);
+	mpll_ad_func_cntl |= CLKR(dividers.ref_div);
+	mpll_ad_func_cntl |= YCLK_POST_DIV(dividers.post_div);
+	mpll_ad_func_cntl |= CLKF(dividers.whole_fb_div);
+	mpll_ad_func_cntl |= CLKFRAC(dividers.frac_fb_div);
+	mpll_ad_func_cntl |= IBIAS(ibias);
+
+	if (dividers.vco_mode)
+		mpll_ad_func_cntl_2 |= VCO_MODE;
+	else
+		mpll_ad_func_cntl_2 &= ~VCO_MODE;
+
+	if (pi->mem_gddr5) {
+		mpll_dq_func_cntl &= ~(CLKR_MASK |
+				       YCLK_POST_DIV_MASK |
+				       CLKF_MASK |
+				       CLKFRAC_MASK |
+				       IBIAS_MASK);
+		mpll_dq_func_cntl |= CLKR(dividers.ref_div);
+		mpll_dq_func_cntl |= YCLK_POST_DIV(dividers.post_div);
+		mpll_dq_func_cntl |= CLKF(dividers.whole_fb_div);
+		mpll_dq_func_cntl |= CLKFRAC(dividers.frac_fb_div);
+		mpll_dq_func_cntl |= IBIAS(ibias);
+
+		if (strobe_mode)
+			mpll_dq_func_cntl &= ~PDNB;
+		else
+			mpll_dq_func_cntl |= PDNB;
+
+		if (dividers.vco_mode)
+			mpll_dq_func_cntl_2 |= VCO_MODE;
+		else
+			mpll_dq_func_cntl_2 &= ~VCO_MODE;
+	}
+
+	if (pi->mclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 vco_freq = memory_clock * dividers.post_div;
+
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+						     ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
+			u32 reference_clock = rdev->clock.mpll.reference_freq;
+			u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
+			u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
+			u32 clk_v = ss.percentage *
+				(0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
+
+			mpll_ss1 &= ~CLKV_MASK;
+			mpll_ss1 |= CLKV(clk_v);
+
+			mpll_ss2 &= ~CLKS_MASK;
+			mpll_ss2 |= CLKS(clk_s);
+		}
+	}
+
+	dll_speed = rv740_get_dll_speed(pi->mem_gddr5,
+					memory_clock);
+
+	mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;
+	mclk_pwrmgt_cntl |= DLL_SPEED(dll_speed);
+	if (dll_state_on)
+		mclk_pwrmgt_cntl |= (MRDCKA0_PDNB |
+				     MRDCKA1_PDNB |
+				     MRDCKB0_PDNB |
+				     MRDCKB1_PDNB |
+				     MRDCKC0_PDNB |
+				     MRDCKC1_PDNB |
+				     MRDCKD0_PDNB |
+				     MRDCKD1_PDNB);
+	else
+		mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB |
+				      MRDCKA1_PDNB |
+				      MRDCKB0_PDNB |
+				      MRDCKB1_PDNB |
+				      MRDCKC0_PDNB |
+				      MRDCKC1_PDNB |
+				      MRDCKD0_PDNB |
+				      MRDCKD1_PDNB);
+
+	mclk->mclk770.mclk_value = cpu_to_be32(memory_clock);
+	mclk->mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
+	mclk->mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
+	mclk->mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
+	mclk->mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
+	mclk->mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	mclk->mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
+	mclk->mclk770.vMPLL_SS = cpu_to_be32(mpll_ss1);
+	mclk->mclk770.vMPLL_SS2 = cpu_to_be32(mpll_ss2);
+
+	return 0;
+}
+
+u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
+				    u32 memory_clock, bool strobe_mode)
+{
+	u8 mc_para_index;
+
+	if (rdev->family >= CHIP_BARTS) {
+		if (strobe_mode) {
+			if (memory_clock < 10000)
+				mc_para_index = 0x00;
+			else if (memory_clock > 47500)
+				mc_para_index = 0x0f;
+			else
+				mc_para_index = (u8)((memory_clock - 10000) / 2500);
+		} else {
+			if (memory_clock < 65000)
+				mc_para_index = 0x00;
+			else if (memory_clock > 135000)
+				mc_para_index = 0x0f;
+			else
+				mc_para_index = (u8)((memory_clock - 60000) / 5000);
+		}
+	} else {
+		if (strobe_mode) {
+			if (memory_clock < 10000)
+				mc_para_index = 0x00;
+			else if (memory_clock > 47500)
+				mc_para_index = 0x0f;
+			else
+				mc_para_index = (u8)((memory_clock - 10000) / 2500);
+		} else {
+			if (memory_clock < 40000)
+				mc_para_index = 0x00;
+			else if (memory_clock > 115000)
+				mc_para_index = 0x0f;
+			else
+				mc_para_index = (u8)((memory_clock - 40000) / 5000);
+		}
+	}
+	return mc_para_index;
+}
+
+static int cypress_populate_mvdd_value(struct radeon_device *rdev,
+				       u32 mclk,
+				       RV770_SMC_VOLTAGE_VALUE *voltage)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (!pi->mvdd_control) {
+		voltage->index = eg_pi->mvdd_high_index;
+		voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
+		return 0;
+	}
+
+	if (mclk <= pi->mvdd_split_frequency) {
+		voltage->index = eg_pi->mvdd_low_index;
+		voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
+	} else {
+		voltage->index = eg_pi->mvdd_high_index;
+		voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
+	}
+
+	return 0;
+}
+
+int cypress_convert_power_level_to_smc(struct radeon_device *rdev,
+				       struct rv7xx_pl *pl,
+				       RV770_SMC_HW_PERFORMANCE_LEVEL *level,
+				       u8 watermark_level)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	int ret;
+	bool dll_state_on;
+
+	level->gen2PCIE = pi->pcie_gen2 ?
+		((pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0) : 0;
+	level->gen2XSP  = (pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0;
+	level->backbias = (pl->flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ? 1 : 0;
+	level->displayWatermark = watermark_level;
+
+	ret = rv740_populate_sclk_value(rdev, pl->sclk, &level->sclk);
+	if (ret)
+		return ret;
+
+	level->mcFlags =  0;
+	if (pi->mclk_stutter_mode_threshold &&
+	    (pl->mclk <= pi->mclk_stutter_mode_threshold) &&
+	    !eg_pi->uvd_enabled) {
+		level->mcFlags |= SMC_MC_STUTTER_EN;
+		if (eg_pi->sclk_deep_sleep)
+			level->stateFlags |= PPSMC_STATEFLAG_AUTO_PULSE_SKIP;
+		else
+			level->stateFlags &= ~PPSMC_STATEFLAG_AUTO_PULSE_SKIP;
+	}
+
+	if (pi->mem_gddr5) {
+		if (pl->mclk > pi->mclk_edc_enable_threshold)
+			level->mcFlags |= SMC_MC_EDC_RD_FLAG;
+
+		if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold)
+			level->mcFlags |= SMC_MC_EDC_WR_FLAG;
+
+		level->strobeMode = cypress_get_strobe_mode_settings(rdev, pl->mclk);
+
+		if (level->strobeMode & SMC_STROBE_ENABLE) {
+			if (cypress_get_mclk_frequency_ratio(rdev, pl->mclk, true) >=
+			    ((RREG32(MC_SEQ_MISC7) >> 16) & 0xf))
+				dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
+			else
+				dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false;
+		} else
+			dll_state_on = eg_pi->dll_default_on;
+
+		ret = cypress_populate_mclk_value(rdev,
+						  pl->sclk,
+						  pl->mclk,
+						  &level->mclk,
+						  (level->strobeMode & SMC_STROBE_ENABLE) != 0,
+						  dll_state_on);
+	} else {
+		ret = cypress_populate_mclk_value(rdev,
+						  pl->sclk,
+						  pl->mclk,
+						  &level->mclk,
+						  true,
+						  true);
+	}
+	if (ret)
+		return ret;
+
+	ret = cypress_populate_voltage_value(rdev,
+					     &eg_pi->vddc_voltage_table,
+					     pl->vddc,
+					     &level->vddc);
+	if (ret)
+		return ret;
+
+	if (eg_pi->vddci_control) {
+		ret = cypress_populate_voltage_value(rdev,
+						     &eg_pi->vddci_voltage_table,
+						     pl->vddci,
+						     &level->vddci);
+		if (ret)
+			return ret;
+	}
+
+	ret = cypress_populate_mvdd_value(rdev, pl->mclk, &level->mvdd);
+
+	return ret;
+}
+
+static int cypress_convert_power_state_to_smc(struct radeon_device *rdev,
+					      struct radeon_ps *radeon_state,
+					      RV770_SMC_SWSTATE *smc_state)
+{
+	struct rv7xx_ps *state = rv770_get_ps(radeon_state);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	int ret;
+
+	if (!(radeon_state->caps & ATOM_PPLIB_DISALLOW_ON_DC))
+		smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
+
+	ret = cypress_convert_power_level_to_smc(rdev,
+						 &state->low,
+						 &smc_state->levels[0],
+						 PPSMC_DISPLAY_WATERMARK_LOW);
+	if (ret)
+		return ret;
+
+	ret = cypress_convert_power_level_to_smc(rdev,
+						 &state->medium,
+						 &smc_state->levels[1],
+						 PPSMC_DISPLAY_WATERMARK_LOW);
+	if (ret)
+		return ret;
+
+	ret = cypress_convert_power_level_to_smc(rdev,
+						 &state->high,
+						 &smc_state->levels[2],
+						 PPSMC_DISPLAY_WATERMARK_HIGH);
+	if (ret)
+		return ret;
+
+	smc_state->levels[0].arbValue = MC_CG_ARB_FREQ_F1;
+	smc_state->levels[1].arbValue = MC_CG_ARB_FREQ_F2;
+	smc_state->levels[2].arbValue = MC_CG_ARB_FREQ_F3;
+
+	if (eg_pi->dynamic_ac_timing) {
+		smc_state->levels[0].ACIndex = 2;
+		smc_state->levels[1].ACIndex = 3;
+		smc_state->levels[2].ACIndex = 4;
+	} else {
+		smc_state->levels[0].ACIndex = 0;
+		smc_state->levels[1].ACIndex = 0;
+		smc_state->levels[2].ACIndex = 0;
+	}
+
+	rv770_populate_smc_sp(rdev, radeon_state, smc_state);
+
+	return rv770_populate_smc_t(rdev, radeon_state, smc_state);
+}
+
+static void cypress_convert_mc_registers(struct evergreen_mc_reg_entry *entry,
+					 SMC_Evergreen_MCRegisterSet *data,
+					 u32 num_entries, u32 valid_flag)
+{
+	u32 i, j;
+
+	for (i = 0, j = 0; j < num_entries; j++) {
+		if (valid_flag & (1 << j)) {
+			data->value[i] = cpu_to_be32(entry->mc_data[j]);
+			i++;
+		}
+	}
+}
+
+static void cypress_convert_mc_reg_table_entry_to_smc(struct radeon_device *rdev,
+						      struct rv7xx_pl *pl,
+						      SMC_Evergreen_MCRegisterSet *mc_reg_table_data)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 i = 0;
+
+	for (i = 0; i < eg_pi->mc_reg_table.num_entries; i++) {
+		if (pl->mclk <=
+		    eg_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max)
+			break;
+	}
+
+	if ((i == eg_pi->mc_reg_table.num_entries) && (i > 0))
+		--i;
+
+	cypress_convert_mc_registers(&eg_pi->mc_reg_table.mc_reg_table_entry[i],
+				     mc_reg_table_data,
+				     eg_pi->mc_reg_table.last,
+				     eg_pi->mc_reg_table.valid_flag);
+}
+
+static void cypress_convert_mc_reg_table_to_smc(struct radeon_device *rdev,
+						struct radeon_ps *radeon_state,
+						SMC_Evergreen_MCRegisters *mc_reg_table)
+{
+	struct rv7xx_ps *state = rv770_get_ps(radeon_state);
+
+	cypress_convert_mc_reg_table_entry_to_smc(rdev,
+						  &state->low,
+						  &mc_reg_table->data[2]);
+	cypress_convert_mc_reg_table_entry_to_smc(rdev,
+						  &state->medium,
+						  &mc_reg_table->data[3]);
+	cypress_convert_mc_reg_table_entry_to_smc(rdev,
+						  &state->high,
+						  &mc_reg_table->data[4]);
+}
+
+int cypress_upload_sw_state(struct radeon_device *rdev,
+			    struct radeon_ps *radeon_new_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u16 address = pi->state_table_start +
+		offsetof(RV770_SMC_STATETABLE, driverState);
+	RV770_SMC_SWSTATE state = { 0 };
+	int ret;
+
+	ret = cypress_convert_power_state_to_smc(rdev, radeon_new_state, &state);
+	if (ret)
+		return ret;
+
+	return rv770_copy_bytes_to_smc(rdev, address, (u8 *)&state,
+				    sizeof(RV770_SMC_SWSTATE),
+				    pi->sram_end);
+}
+
+int cypress_upload_mc_reg_table(struct radeon_device *rdev,
+				struct radeon_ps *radeon_new_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	SMC_Evergreen_MCRegisters mc_reg_table = { 0 };
+	u16 address;
+
+	cypress_convert_mc_reg_table_to_smc(rdev, radeon_new_state, &mc_reg_table);
+
+	address = eg_pi->mc_reg_table_start +
+		(u16)offsetof(SMC_Evergreen_MCRegisters, data[2]);
+
+	return rv770_copy_bytes_to_smc(rdev, address,
+				       (u8 *)&mc_reg_table.data[2],
+				       sizeof(SMC_Evergreen_MCRegisterSet) * 3,
+				       pi->sram_end);
+}
+
+u32 cypress_calculate_burst_time(struct radeon_device *rdev,
+				 u32 engine_clock, u32 memory_clock)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 multiplier = pi->mem_gddr5 ? 1 : 2;
+	u32 result = (4 * multiplier * engine_clock) / (memory_clock / 2);
+	u32 burst_time;
+
+	if (result <= 4)
+		burst_time = 0;
+	else if (result < 8)
+		burst_time = result - 4;
+	else {
+		burst_time = result / 2 ;
+		if (burst_time > 18)
+			burst_time = 18;
+	}
+
+	return burst_time;
+}
+
+void cypress_program_memory_timing_parameters(struct radeon_device *rdev,
+					      struct radeon_ps *radeon_new_state)
+{
+	struct rv7xx_ps *new_state = rv770_get_ps(radeon_new_state);
+	u32 mc_arb_burst_time = RREG32(MC_ARB_BURST_TIME);
+
+	mc_arb_burst_time &= ~(STATE1_MASK | STATE2_MASK | STATE3_MASK);
+
+	mc_arb_burst_time |= STATE1(cypress_calculate_burst_time(rdev,
+								 new_state->low.sclk,
+								 new_state->low.mclk));
+	mc_arb_burst_time |= STATE2(cypress_calculate_burst_time(rdev,
+								 new_state->medium.sclk,
+								 new_state->medium.mclk));
+	mc_arb_burst_time |= STATE3(cypress_calculate_burst_time(rdev,
+								 new_state->high.sclk,
+								 new_state->high.mclk));
+
+	rv730_program_memory_timing_parameters(rdev, radeon_new_state);
+
+	WREG32(MC_ARB_BURST_TIME, mc_arb_burst_time);
+}
+
+static void cypress_populate_mc_reg_addresses(struct radeon_device *rdev,
+					      SMC_Evergreen_MCRegisters *mc_reg_table)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 i, j;
+
+	for (i = 0, j = 0; j < eg_pi->mc_reg_table.last; j++) {
+		if (eg_pi->mc_reg_table.valid_flag & (1 << j)) {
+			mc_reg_table->address[i].s0 =
+				cpu_to_be16(eg_pi->mc_reg_table.mc_reg_address[j].s0);
+			mc_reg_table->address[i].s1 =
+				cpu_to_be16(eg_pi->mc_reg_table.mc_reg_address[j].s1);
+			i++;
+		}
+	}
+
+	mc_reg_table->last = (u8)i;
+}
+
+static void cypress_set_mc_reg_address_table(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 i = 0;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_RAS_TIMING_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_RAS_TIMING >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_CAS_TIMING_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_CAS_TIMING >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_MISC_TIMING_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_MISC_TIMING >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_MISC_TIMING2_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_MISC_TIMING2 >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_RD_CTL_D0_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_RD_CTL_D0 >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_RD_CTL_D1_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_RD_CTL_D1 >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_WR_CTL_D0_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_WR_CTL_D0 >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_WR_CTL_D1_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_WR_CTL_D1 >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_PMG_CMD_EMRS >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_PMG_CMD_MRS >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_PMG_CMD_MRS1 >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_MISC1 >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_MISC1 >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_RESERVE_M >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_RESERVE_M >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_MISC3 >> 2;
+	eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_MISC3 >> 2;
+	i++;
+
+	eg_pi->mc_reg_table.last = (u8)i;
+}
+
+static void cypress_retrieve_ac_timing_for_one_entry(struct radeon_device *rdev,
+						     struct evergreen_mc_reg_entry *entry)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 i;
+
+	for (i = 0; i < eg_pi->mc_reg_table.last; i++)
+		entry->mc_data[i] =
+			RREG32(eg_pi->mc_reg_table.mc_reg_address[i].s1 << 2);
+
+}
+
+static void cypress_retrieve_ac_timing_for_all_ranges(struct radeon_device *rdev,
+						      struct atom_memory_clock_range_table *range_table)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 i, j;
+
+	for (i = 0; i < range_table->num_entries; i++) {
+		eg_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max =
+			range_table->mclk[i];
+		radeon_atom_set_ac_timing(rdev, range_table->mclk[i]);
+		cypress_retrieve_ac_timing_for_one_entry(rdev,
+							 &eg_pi->mc_reg_table.mc_reg_table_entry[i]);
+	}
+
+	eg_pi->mc_reg_table.num_entries = range_table->num_entries;
+	eg_pi->mc_reg_table.valid_flag = 0;
+
+	for (i = 0; i < eg_pi->mc_reg_table.last; i++) {
+		for (j = 1; j < range_table->num_entries; j++) {
+			if (eg_pi->mc_reg_table.mc_reg_table_entry[j-1].mc_data[i] !=
+			    eg_pi->mc_reg_table.mc_reg_table_entry[j].mc_data[i]) {
+				eg_pi->mc_reg_table.valid_flag |= (1 << i);
+				break;
+			}
+		}
+	}
+}
+
+static int cypress_initialize_mc_reg_table(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u8 module_index = rv770_get_memory_module_index(rdev);
+	struct atom_memory_clock_range_table range_table = { 0 };
+	int ret;
+
+	ret = radeon_atom_get_mclk_range_table(rdev,
+					       pi->mem_gddr5,
+					       module_index, &range_table);
+	if (ret)
+		return ret;
+
+	cypress_retrieve_ac_timing_for_all_ranges(rdev, &range_table);
+
+	return 0;
+}
+
+static void cypress_wait_for_mc_sequencer(struct radeon_device *rdev, u8 value)
+{
+	u32 i, j;
+	u32 channels = 2;
+
+	if ((rdev->family == CHIP_CYPRESS) ||
+	    (rdev->family == CHIP_HEMLOCK))
+		channels = 4;
+	else if (rdev->family == CHIP_CEDAR)
+		channels = 1;
+
+	for (i = 0; i < channels; i++) {
+		if ((rdev->family == CHIP_CYPRESS) ||
+		    (rdev->family == CHIP_HEMLOCK)) {
+			WREG32_P(MC_CONFIG_MCD, MC_RD_ENABLE_MCD(i), ~MC_RD_ENABLE_MCD_MASK);
+			WREG32_P(MC_CG_CONFIG_MCD, MC_RD_ENABLE_MCD(i), ~MC_RD_ENABLE_MCD_MASK);
+		} else {
+			WREG32_P(MC_CONFIG, MC_RD_ENABLE(i), ~MC_RD_ENABLE_MASK);
+			WREG32_P(MC_CG_CONFIG, MC_RD_ENABLE(i), ~MC_RD_ENABLE_MASK);
+		}
+		for (j = 0; j < rdev->usec_timeout; j++) {
+			if (((RREG32(MC_SEQ_CG) & CG_SEQ_RESP_MASK) >> CG_SEQ_RESP_SHIFT) == value)
+				break;
+			udelay(1);
+		}
+	}
+}
+
+static void cypress_force_mc_use_s1(struct radeon_device *rdev,
+				    struct radeon_ps *radeon_boot_state)
+{
+	struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state);
+	u32 strobe_mode;
+	u32 mc_seq_cg;
+	int i;
+
+	if (RREG32(MC_SEQ_STATUS_M) & PMG_PWRSTATE)
+		return;
+
+	radeon_atom_set_ac_timing(rdev, boot_state->low.mclk);
+	radeon_mc_wait_for_idle(rdev);
+
+	if ((rdev->family == CHIP_CYPRESS) ||
+	    (rdev->family == CHIP_HEMLOCK)) {
+		WREG32(MC_CONFIG_MCD, 0xf);
+		WREG32(MC_CG_CONFIG_MCD, 0xf);
+	} else {
+		WREG32(MC_CONFIG, 0xf);
+		WREG32(MC_CG_CONFIG, 0xf);
+	}
+
+	for (i = 0; i < rdev->num_crtc; i++)
+		radeon_wait_for_vblank(rdev, i);
+
+	WREG32(MC_SEQ_CG, MC_CG_SEQ_YCLK_SUSPEND);
+	cypress_wait_for_mc_sequencer(rdev, MC_CG_SEQ_YCLK_SUSPEND);
+
+	strobe_mode = cypress_get_strobe_mode_settings(rdev,
+						       boot_state->low.mclk);
+
+	mc_seq_cg = CG_SEQ_REQ(MC_CG_SEQ_DRAMCONF_S1);
+	mc_seq_cg |= SEQ_CG_RESP(strobe_mode);
+	WREG32(MC_SEQ_CG, mc_seq_cg);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(MC_SEQ_STATUS_M) & PMG_PWRSTATE)
+			break;
+		udelay(1);
+	}
+
+	mc_seq_cg &= ~CG_SEQ_REQ_MASK;
+	mc_seq_cg |= CG_SEQ_REQ(MC_CG_SEQ_YCLK_RESUME);
+	WREG32(MC_SEQ_CG, mc_seq_cg);
+
+	cypress_wait_for_mc_sequencer(rdev, MC_CG_SEQ_YCLK_RESUME);
+}
+
+static void cypress_copy_ac_timing_from_s1_to_s0(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 value;
+	u32 i;
+
+	for (i = 0; i < eg_pi->mc_reg_table.last; i++) {
+		value = RREG32(eg_pi->mc_reg_table.mc_reg_address[i].s1 << 2);
+		WREG32(eg_pi->mc_reg_table.mc_reg_address[i].s0 << 2, value);
+	}
+}
+
+static void cypress_force_mc_use_s0(struct radeon_device *rdev,
+				    struct radeon_ps *radeon_boot_state)
+{
+	struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state);
+	u32 strobe_mode;
+	u32 mc_seq_cg;
+	int i;
+
+	cypress_copy_ac_timing_from_s1_to_s0(rdev);
+	radeon_mc_wait_for_idle(rdev);
+
+	if ((rdev->family == CHIP_CYPRESS) ||
+	    (rdev->family == CHIP_HEMLOCK)) {
+		WREG32(MC_CONFIG_MCD, 0xf);
+		WREG32(MC_CG_CONFIG_MCD, 0xf);
+	} else {
+		WREG32(MC_CONFIG, 0xf);
+		WREG32(MC_CG_CONFIG, 0xf);
+	}
+
+	for (i = 0; i < rdev->num_crtc; i++)
+		radeon_wait_for_vblank(rdev, i);
+
+	WREG32(MC_SEQ_CG, MC_CG_SEQ_YCLK_SUSPEND);
+	cypress_wait_for_mc_sequencer(rdev, MC_CG_SEQ_YCLK_SUSPEND);
+
+	strobe_mode = cypress_get_strobe_mode_settings(rdev,
+						       boot_state->low.mclk);
+
+	mc_seq_cg = CG_SEQ_REQ(MC_CG_SEQ_DRAMCONF_S0);
+	mc_seq_cg |= SEQ_CG_RESP(strobe_mode);
+	WREG32(MC_SEQ_CG, mc_seq_cg);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (!(RREG32(MC_SEQ_STATUS_M) & PMG_PWRSTATE))
+			break;
+		udelay(1);
+	}
+
+	mc_seq_cg &= ~CG_SEQ_REQ_MASK;
+	mc_seq_cg |= CG_SEQ_REQ(MC_CG_SEQ_YCLK_RESUME);
+	WREG32(MC_SEQ_CG, mc_seq_cg);
+
+	cypress_wait_for_mc_sequencer(rdev, MC_CG_SEQ_YCLK_RESUME);
+}
+
+static int cypress_populate_initial_mvdd_value(struct radeon_device *rdev,
+					       RV770_SMC_VOLTAGE_VALUE *voltage)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	voltage->index = eg_pi->mvdd_high_index;
+	voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
+
+	return 0;
+}
+
+int cypress_populate_smc_initial_state(struct radeon_device *rdev,
+				       struct radeon_ps *radeon_initial_state,
+				       RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_ps *initial_state = rv770_get_ps(radeon_initial_state);
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 a_t;
+
+	table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl);
+	table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl_2);
+	table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl);
+	table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl_2);
+	table->initialState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.mclk_pwrmgt_cntl);
+	table->initialState.levels[0].mclk.mclk770.vDLL_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.dll_cntl);
+
+	table->initialState.levels[0].mclk.mclk770.vMPLL_SS =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_ss1);
+	table->initialState.levels[0].mclk.mclk770.vMPLL_SS2 =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_ss2);
+
+	table->initialState.levels[0].mclk.mclk770.mclk_value =
+		cpu_to_be32(initial_state->low.mclk);
+
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_2);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_3);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum_2);
+
+	table->initialState.levels[0].sclk.sclk_value =
+		cpu_to_be32(initial_state->low.sclk);
+
+	table->initialState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
+
+	table->initialState.levels[0].ACIndex = 0;
+
+	cypress_populate_voltage_value(rdev,
+				       &eg_pi->vddc_voltage_table,
+				       initial_state->low.vddc,
+				       &table->initialState.levels[0].vddc);
+
+	if (eg_pi->vddci_control)
+		cypress_populate_voltage_value(rdev,
+					       &eg_pi->vddci_voltage_table,
+					       initial_state->low.vddci,
+					       &table->initialState.levels[0].vddci);
+
+	cypress_populate_initial_mvdd_value(rdev,
+					    &table->initialState.levels[0].mvdd);
+
+	a_t = CG_R(0xffff) | CG_L(0);
+	table->initialState.levels[0].aT = cpu_to_be32(a_t);
+
+	table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
+
+
+	if (pi->boot_in_gen2)
+		table->initialState.levels[0].gen2PCIE = 1;
+	else
+		table->initialState.levels[0].gen2PCIE = 0;
+	if (initial_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
+		table->initialState.levels[0].gen2XSP = 1;
+	else
+		table->initialState.levels[0].gen2XSP = 0;
+
+	if (pi->mem_gddr5) {
+		table->initialState.levels[0].strobeMode =
+			cypress_get_strobe_mode_settings(rdev,
+							 initial_state->low.mclk);
+
+		if (initial_state->low.mclk > pi->mclk_edc_enable_threshold)
+			table->initialState.levels[0].mcFlags = SMC_MC_EDC_RD_FLAG | SMC_MC_EDC_WR_FLAG;
+		else
+			table->initialState.levels[0].mcFlags =  0;
+	}
+
+	table->initialState.levels[1] = table->initialState.levels[0];
+	table->initialState.levels[2] = table->initialState.levels[0];
+
+	table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
+
+	return 0;
+}
+
+int cypress_populate_smc_acpi_state(struct radeon_device *rdev,
+				    RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 mpll_ad_func_cntl =
+		pi->clk_regs.rv770.mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2 =
+		pi->clk_regs.rv770.mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl =
+		pi->clk_regs.rv770.mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2 =
+		pi->clk_regs.rv770.mpll_dq_func_cntl_2;
+	u32 spll_func_cntl =
+		pi->clk_regs.rv770.cg_spll_func_cntl;
+	u32 spll_func_cntl_2 =
+		pi->clk_regs.rv770.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3 =
+		pi->clk_regs.rv770.cg_spll_func_cntl_3;
+	u32 mclk_pwrmgt_cntl =
+		pi->clk_regs.rv770.mclk_pwrmgt_cntl;
+	u32 dll_cntl =
+		pi->clk_regs.rv770.dll_cntl;
+
+	table->ACPIState = table->initialState;
+
+	table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
+
+	if (pi->acpi_vddc) {
+		cypress_populate_voltage_value(rdev,
+					       &eg_pi->vddc_voltage_table,
+					       pi->acpi_vddc,
+					       &table->ACPIState.levels[0].vddc);
+		if (pi->pcie_gen2) {
+			if (pi->acpi_pcie_gen2)
+				table->ACPIState.levels[0].gen2PCIE = 1;
+			else
+				table->ACPIState.levels[0].gen2PCIE = 0;
+		} else
+			table->ACPIState.levels[0].gen2PCIE = 0;
+		if (pi->acpi_pcie_gen2)
+			table->ACPIState.levels[0].gen2XSP = 1;
+		else
+			table->ACPIState.levels[0].gen2XSP = 0;
+	} else {
+		cypress_populate_voltage_value(rdev,
+					       &eg_pi->vddc_voltage_table,
+					       pi->min_vddc_in_table,
+					       &table->ACPIState.levels[0].vddc);
+		table->ACPIState.levels[0].gen2PCIE = 0;
+	}
+
+	if (eg_pi->acpi_vddci) {
+		if (eg_pi->vddci_control) {
+			cypress_populate_voltage_value(rdev,
+						       &eg_pi->vddci_voltage_table,
+						       eg_pi->acpi_vddci,
+						       &table->ACPIState.levels[0].vddci);
+		}
+	}
+
+	mpll_ad_func_cntl &= ~PDNB;
+
+	mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
+
+	if (pi->mem_gddr5)
+		mpll_dq_func_cntl &= ~PDNB;
+	mpll_dq_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN | BYPASS;
+
+	mclk_pwrmgt_cntl |= (MRDCKA0_RESET |
+			     MRDCKA1_RESET |
+			     MRDCKB0_RESET |
+			     MRDCKB1_RESET |
+			     MRDCKC0_RESET |
+			     MRDCKC1_RESET |
+			     MRDCKD0_RESET |
+			     MRDCKD1_RESET);
+
+	mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB |
+			      MRDCKA1_PDNB |
+			      MRDCKB0_PDNB |
+			      MRDCKB1_PDNB |
+			      MRDCKC0_PDNB |
+			      MRDCKC1_PDNB |
+			      MRDCKD0_PDNB |
+			      MRDCKD1_PDNB);
+
+	dll_cntl |= (MRDCKA0_BYPASS |
+		     MRDCKA1_BYPASS |
+		     MRDCKB0_BYPASS |
+		     MRDCKB1_BYPASS |
+		     MRDCKC0_BYPASS |
+		     MRDCKC1_BYPASS |
+		     MRDCKD0_BYPASS |
+		     MRDCKD1_BYPASS);
+
+	/* evergreen only */
+	if (rdev->family <= CHIP_HEMLOCK)
+		spll_func_cntl |= SPLL_RESET | SPLL_SLEEP | SPLL_BYPASS_EN;
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(4);
+
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL =
+		cpu_to_be32(mpll_ad_func_cntl);
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 =
+		cpu_to_be32(mpll_ad_func_cntl_2);
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL =
+		cpu_to_be32(mpll_dq_func_cntl);
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 =
+		cpu_to_be32(mpll_dq_func_cntl_2);
+	table->ACPIState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL =
+		cpu_to_be32(mclk_pwrmgt_cntl);
+	table->ACPIState.levels[0].mclk.mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
+
+	table->ACPIState.levels[0].mclk.mclk770.mclk_value = 0;
+
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
+		cpu_to_be32(spll_func_cntl);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
+		cpu_to_be32(spll_func_cntl_2);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
+		cpu_to_be32(spll_func_cntl_3);
+
+	table->ACPIState.levels[0].sclk.sclk_value = 0;
+
+	cypress_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
+
+	if (eg_pi->dynamic_ac_timing)
+		table->ACPIState.levels[0].ACIndex = 1;
+
+	table->ACPIState.levels[1] = table->ACPIState.levels[0];
+	table->ACPIState.levels[2] = table->ACPIState.levels[0];
+
+	return 0;
+}
+
+static void cypress_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev,
+							  struct atom_voltage_table *voltage_table)
+{
+	unsigned int i, diff;
+
+	if (voltage_table->count <= MAX_NO_VREG_STEPS)
+		return;
+
+	diff = voltage_table->count - MAX_NO_VREG_STEPS;
+
+	for (i= 0; i < MAX_NO_VREG_STEPS; i++)
+		voltage_table->entries[i] = voltage_table->entries[i + diff];
+
+	voltage_table->count = MAX_NO_VREG_STEPS;
+}
+
+int cypress_construct_voltage_tables(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	int ret;
+
+	ret = radeon_atom_get_voltage_table(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0,
+					    &eg_pi->vddc_voltage_table);
+	if (ret)
+		return ret;
+
+	if (eg_pi->vddc_voltage_table.count > MAX_NO_VREG_STEPS)
+		cypress_trim_voltage_table_to_fit_state_table(rdev,
+							      &eg_pi->vddc_voltage_table);
+
+	if (eg_pi->vddci_control) {
+		ret = radeon_atom_get_voltage_table(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0,
+						    &eg_pi->vddci_voltage_table);
+		if (ret)
+			return ret;
+
+		if (eg_pi->vddci_voltage_table.count > MAX_NO_VREG_STEPS)
+			cypress_trim_voltage_table_to_fit_state_table(rdev,
+								      &eg_pi->vddci_voltage_table);
+	}
+
+	return 0;
+}
+
+static void cypress_populate_smc_voltage_table(struct radeon_device *rdev,
+					       struct atom_voltage_table *voltage_table,
+					       RV770_SMC_STATETABLE *table)
+{
+	unsigned int i;
+
+	for (i = 0; i < voltage_table->count; i++) {
+		table->highSMIO[i] = 0;
+		table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low);
+	}
+}
+
+int cypress_populate_smc_voltage_tables(struct radeon_device *rdev,
+					RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	unsigned char i;
+
+	if (eg_pi->vddc_voltage_table.count) {
+		cypress_populate_smc_voltage_table(rdev,
+						   &eg_pi->vddc_voltage_table,
+						   table);
+
+		table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_VDDC] = 0;
+		table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_VDDC] =
+			cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
+
+		for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {
+			if (pi->max_vddc_in_table <=
+			    eg_pi->vddc_voltage_table.entries[i].value) {
+				table->maxVDDCIndexInPPTable = i;
+				break;
+			}
+		}
+	}
+
+	if (eg_pi->vddci_voltage_table.count) {
+		cypress_populate_smc_voltage_table(rdev,
+						   &eg_pi->vddci_voltage_table,
+						   table);
+
+		table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_VDDCI] = 0;
+		table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_VDDCI] =
+			cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
+	}
+
+	return 0;
+}
+
+static u32 cypress_get_mclk_split_point(struct atom_memory_info *memory_info)
+{
+	if ((memory_info->mem_type == MEM_TYPE_GDDR3) ||
+	    (memory_info->mem_type == MEM_TYPE_DDR3))
+		return 30000;
+
+	return 0;
+}
+
+int cypress_get_mvdd_configuration(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u8 module_index;
+	struct atom_memory_info memory_info;
+	u32 tmp = RREG32(GENERAL_PWRMGT);
+
+	if (!(tmp & BACKBIAS_PAD_EN)) {
+		eg_pi->mvdd_high_index = 0;
+		eg_pi->mvdd_low_index = 1;
+		pi->mvdd_control = false;
+		return 0;
+	}
+
+	if (tmp & BACKBIAS_VALUE)
+		eg_pi->mvdd_high_index = 1;
+	else
+		eg_pi->mvdd_high_index = 0;
+
+	eg_pi->mvdd_low_index =
+		(eg_pi->mvdd_high_index == 0) ? 1 : 0;
+
+	module_index = rv770_get_memory_module_index(rdev);
+
+	if (radeon_atom_get_memory_info(rdev, module_index, &memory_info)) {
+		pi->mvdd_control = false;
+		return 0;
+	}
+
+	pi->mvdd_split_frequency =
+		cypress_get_mclk_split_point(&memory_info);
+
+	if (pi->mvdd_split_frequency == 0) {
+		pi->mvdd_control = false;
+		return 0;
+	}
+
+	return 0;
+}
+
+static int cypress_init_smc_table(struct radeon_device *rdev,
+				  struct radeon_ps *radeon_boot_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	RV770_SMC_STATETABLE *table = &pi->smc_statetable;
+	int ret;
+
+	memset(table, 0, sizeof(RV770_SMC_STATETABLE));
+
+	cypress_populate_smc_voltage_tables(rdev, table);
+
+	switch (rdev->pm.int_thermal_type) {
+        case THERMAL_TYPE_EVERGREEN:
+        case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
+		break;
+        case THERMAL_TYPE_NONE:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
+		break;
+        default:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
+		break;
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
+
+	if (pi->mem_gddr5)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
+
+	ret = cypress_populate_smc_initial_state(rdev, radeon_boot_state, table);
+	if (ret)
+		return ret;
+
+	ret = cypress_populate_smc_acpi_state(rdev, table);
+	if (ret)
+		return ret;
+
+	table->driverState = table->initialState;
+
+	return rv770_copy_bytes_to_smc(rdev,
+				       pi->state_table_start,
+				       (u8 *)table, sizeof(RV770_SMC_STATETABLE),
+				       pi->sram_end);
+}
+
+int cypress_populate_mc_reg_table(struct radeon_device *rdev,
+				  struct radeon_ps *radeon_boot_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state);
+	SMC_Evergreen_MCRegisters mc_reg_table = { 0 };
+
+	rv770_write_smc_soft_register(rdev,
+				      RV770_SMC_SOFT_REGISTER_seq_index, 1);
+
+	cypress_populate_mc_reg_addresses(rdev, &mc_reg_table);
+
+	cypress_convert_mc_reg_table_entry_to_smc(rdev,
+						  &boot_state->low,
+						  &mc_reg_table.data[0]);
+
+	cypress_convert_mc_registers(&eg_pi->mc_reg_table.mc_reg_table_entry[0],
+				     &mc_reg_table.data[1], eg_pi->mc_reg_table.last,
+				     eg_pi->mc_reg_table.valid_flag);
+
+	cypress_convert_mc_reg_table_to_smc(rdev, radeon_boot_state, &mc_reg_table);
+
+	return rv770_copy_bytes_to_smc(rdev, eg_pi->mc_reg_table_start,
+				       (u8 *)&mc_reg_table, sizeof(SMC_Evergreen_MCRegisters),
+				       pi->sram_end);
+}
+
+int cypress_get_table_locations(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 tmp;
+	int ret;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION +
+					EVERGREEN_SMC_FIRMWARE_HEADER_stateTable,
+					&tmp, pi->sram_end);
+	if (ret)
+		return ret;
+
+	pi->state_table_start = (u16)tmp;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION +
+					EVERGREEN_SMC_FIRMWARE_HEADER_softRegisters,
+					&tmp, pi->sram_end);
+	if (ret)
+		return ret;
+
+	pi->soft_regs_start = (u16)tmp;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION +
+					EVERGREEN_SMC_FIRMWARE_HEADER_mcRegisterTable,
+					&tmp, pi->sram_end);
+	if (ret)
+		return ret;
+
+	eg_pi->mc_reg_table_start = (u16)tmp;
+
+	return 0;
+}
+
+void cypress_enable_display_gap(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
+
+	tmp &= ~(DISP1_GAP_MASK | DISP2_GAP_MASK);
+	tmp |= (DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE) |
+		DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE));
+
+	tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
+	tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK) |
+		DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE));
+	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
+}
+
+static void cypress_program_display_gap(struct radeon_device *rdev)
+{
+	u32 tmp, pipe;
+	int i;
+
+	tmp = RREG32(CG_DISPLAY_GAP_CNTL) & ~(DISP1_GAP_MASK | DISP2_GAP_MASK);
+	if (rdev->pm.dpm.new_active_crtc_count > 0)
+		tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM);
+	else
+		tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE);
+
+	if (rdev->pm.dpm.new_active_crtc_count > 1)
+		tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM);
+	else
+		tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE);
+
+	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
+
+	tmp = RREG32(DCCG_DISP_SLOW_SELECT_REG);
+	pipe = (tmp & DCCG_DISP1_SLOW_SELECT_MASK) >> DCCG_DISP1_SLOW_SELECT_SHIFT;
+
+	if ((rdev->pm.dpm.new_active_crtc_count > 0) &&
+	    (!(rdev->pm.dpm.new_active_crtcs & (1 << pipe)))) {
+		/* find the first active crtc */
+		for (i = 0; i < rdev->num_crtc; i++) {
+			if (rdev->pm.dpm.new_active_crtcs & (1 << i))
+				break;
+		}
+		if (i == rdev->num_crtc)
+			pipe = 0;
+		else
+			pipe = i;
+
+		tmp &= ~DCCG_DISP1_SLOW_SELECT_MASK;
+		tmp |= DCCG_DISP1_SLOW_SELECT(pipe);
+		WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp);
+	}
+
+	cypress_notify_smc_display_change(rdev, rdev->pm.dpm.new_active_crtc_count > 0);
+}
+
+void cypress_dpm_setup_asic(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	rv740_read_clock_registers(rdev);
+	rv770_read_voltage_smio_registers(rdev);
+	rv770_get_max_vddc(rdev);
+	rv770_get_memory_type(rdev);
+
+	if (eg_pi->pcie_performance_request)
+		eg_pi->pcie_performance_request_registered = false;
+
+	if (eg_pi->pcie_performance_request)
+		cypress_advertise_gen2_capability(rdev);
+
+	rv770_get_pcie_gen2_status(rdev);
+
+	rv770_enable_acpi_pm(rdev);
+}
+
+int cypress_dpm_enable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+	int ret;
+
+	if (pi->gfx_clock_gating)
+		rv770_restore_cgcg(rdev);
+
+	if (rv770_dpm_enabled(rdev))
+		return -EINVAL;
+
+	if (pi->voltage_control) {
+		rv770_enable_voltage_control(rdev, true);
+		ret = cypress_construct_voltage_tables(rdev);
+		if (ret) {
+			DRM_ERROR("cypress_construct_voltage_tables failed\n");
+			return ret;
+		}
+	}
+
+	if (pi->mvdd_control) {
+		ret = cypress_get_mvdd_configuration(rdev);
+		if (ret) {
+			DRM_ERROR("cypress_get_mvdd_configuration failed\n");
+			return ret;
+		}
+	}
+
+	if (eg_pi->dynamic_ac_timing) {
+		cypress_set_mc_reg_address_table(rdev);
+		cypress_force_mc_use_s0(rdev, boot_ps);
+		ret = cypress_initialize_mc_reg_table(rdev);
+		if (ret)
+			eg_pi->dynamic_ac_timing = false;
+		cypress_force_mc_use_s1(rdev, boot_ps);
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
+		rv770_enable_backbias(rdev, true);
+
+	if (pi->dynamic_ss)
+		cypress_enable_spread_spectrum(rdev, true);
+
+	if (pi->thermal_protection)
+		rv770_enable_thermal_protection(rdev, true);
+
+	rv770_setup_bsp(rdev);
+	rv770_program_git(rdev);
+	rv770_program_tp(rdev);
+	rv770_program_tpp(rdev);
+	rv770_program_sstp(rdev);
+	rv770_program_engine_speed_parameters(rdev);
+	cypress_enable_display_gap(rdev);
+	rv770_program_vc(rdev);
+
+	if (pi->dynamic_pcie_gen2)
+		cypress_enable_dynamic_pcie_gen2(rdev, true);
+
+	ret = rv770_upload_firmware(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_upload_firmware failed\n");
+		return ret;
+	}
+
+	ret = cypress_get_table_locations(rdev);
+	if (ret) {
+		DRM_ERROR("cypress_get_table_locations failed\n");
+		return ret;
+	}
+	ret = cypress_init_smc_table(rdev, boot_ps);
+	if (ret) {
+		DRM_ERROR("cypress_init_smc_table failed\n");
+		return ret;
+	}
+	if (eg_pi->dynamic_ac_timing) {
+		ret = cypress_populate_mc_reg_table(rdev, boot_ps);
+		if (ret) {
+			DRM_ERROR("cypress_populate_mc_reg_table failed\n");
+			return ret;
+		}
+	}
+
+	cypress_program_response_times(rdev);
+
+	r7xx_start_smc(rdev);
+
+	ret = cypress_notify_smc_display_change(rdev, false);
+	if (ret) {
+		DRM_ERROR("cypress_notify_smc_display_change failed\n");
+		return ret;
+	}
+	cypress_enable_sclk_control(rdev, true);
+
+	if (eg_pi->memory_transition)
+		cypress_enable_mclk_control(rdev, true);
+
+	cypress_start_dpm(rdev);
+
+	if (pi->gfx_clock_gating)
+		cypress_gfx_clock_gating_enable(rdev, true);
+
+	if (pi->mg_clock_gating)
+		cypress_mg_clock_gating_enable(rdev, true);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		PPSMC_Result result;
+
+		ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+		if (ret)
+			return ret;
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+		result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
+
+		if (result != PPSMC_Result_OK)
+			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
+	}
+
+	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+	return 0;
+}
+
+void cypress_dpm_disable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+
+	if (!rv770_dpm_enabled(rdev))
+		return;
+
+	rv770_clear_vc(rdev);
+
+	if (pi->thermal_protection)
+		rv770_enable_thermal_protection(rdev, false);
+
+	if (pi->dynamic_pcie_gen2)
+		cypress_enable_dynamic_pcie_gen2(rdev, false);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		rdev->irq.dpm_thermal = false;
+		radeon_irq_set(rdev);
+	}
+
+	if (pi->gfx_clock_gating)
+		cypress_gfx_clock_gating_enable(rdev, false);
+
+	if (pi->mg_clock_gating)
+		cypress_mg_clock_gating_enable(rdev, false);
+
+	rv770_stop_dpm(rdev);
+	r7xx_stop_smc(rdev);
+
+	cypress_enable_spread_spectrum(rdev, false);
+
+	if (eg_pi->dynamic_ac_timing)
+		cypress_force_mc_use_s1(rdev, boot_ps);
+
+	rv770_reset_smio_status(rdev);
+}
+
+int cypress_dpm_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
+	struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;
+	int ret;
+
+	ret = rv770_restrict_performance_levels_before_switch(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_restrict_performance_levels_before_switch failed\n");
+		return ret;
+	}
+	if (eg_pi->pcie_performance_request)
+		cypress_notify_link_speed_change_before_state_change(rdev, new_ps, old_ps);
+
+	rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+	ret = rv770_halt_smc(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_halt_smc failed\n");
+		return ret;
+	}
+	ret = cypress_upload_sw_state(rdev, new_ps);
+	if (ret) {
+		DRM_ERROR("cypress_upload_sw_state failed\n");
+		return ret;
+	}
+	if (eg_pi->dynamic_ac_timing) {
+		ret = cypress_upload_mc_reg_table(rdev, new_ps);
+		if (ret) {
+			DRM_ERROR("cypress_upload_mc_reg_table failed\n");
+			return ret;
+		}
+	}
+
+	cypress_program_memory_timing_parameters(rdev, new_ps);
+
+	ret = rv770_resume_smc(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_resume_smc failed\n");
+		return ret;
+	}
+	ret = rv770_set_sw_state(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_set_sw_state failed\n");
+		return ret;
+	}
+	rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+
+	if (eg_pi->pcie_performance_request)
+		cypress_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
+
+	ret = rv770_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO);
+	if (ret) {
+		DRM_ERROR("rv770_dpm_force_performance_level failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+void cypress_dpm_reset_asic(struct radeon_device *rdev)
+{
+	rv770_restrict_performance_levels_before_switch(rdev);
+	rv770_set_boot_state(rdev);
+}
+
+void cypress_dpm_display_configuration_changed(struct radeon_device *rdev)
+{
+	cypress_program_display_gap(rdev);
+}
+
+int cypress_dpm_init(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi;
+	struct evergreen_power_info *eg_pi;
+	struct atom_clock_dividers dividers;
+	int ret;
+
+	eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL);
+	if (eg_pi == NULL)
+		return -ENOMEM;
+	rdev->pm.dpm.priv = eg_pi;
+	pi = &eg_pi->rv7xx;
+
+	rv770_get_max_vddc(rdev);
+
+	eg_pi->ulv.supported = false;
+	pi->acpi_vddc = 0;
+	eg_pi->acpi_vddci = 0;
+	pi->min_vddc_in_table = 0;
+	pi->max_vddc_in_table = 0;
+
+	ret = rv7xx_parse_power_table(rdev);
+	if (ret)
+		return ret;
+
+	if (rdev->pm.dpm.voltage_response_time == 0)
+		rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
+	if (rdev->pm.dpm.backbias_response_time == 0)
+		rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     0, false, &dividers);
+	if (ret)
+		pi->ref_div = dividers.ref_div + 1;
+	else
+		pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
+
+	pi->mclk_strobe_mode_threshold = 40000;
+	pi->mclk_edc_enable_threshold = 40000;
+	eg_pi->mclk_edc_wr_enable_threshold = 40000;
+
+	pi->rlp = RV770_RLP_DFLT;
+	pi->rmp = RV770_RMP_DFLT;
+	pi->lhp = RV770_LHP_DFLT;
+	pi->lmp = RV770_LMP_DFLT;
+
+	pi->voltage_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
+
+	pi->mvdd_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
+
+	eg_pi->vddci_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
+
+	rv770_get_engine_memory_ss(rdev);
+
+	pi->asi = RV770_ASI_DFLT;
+	pi->pasi = CYPRESS_HASI_DFLT;
+	pi->vrc = CYPRESS_VRC_DFLT;
+
+	pi->power_gating = false;
+
+	if ((rdev->family == CHIP_CYPRESS) ||
+	    (rdev->family == CHIP_HEMLOCK))
+		pi->gfx_clock_gating = false;
+	else
+		pi->gfx_clock_gating = true;
+
+	pi->mg_clock_gating = true;
+	pi->mgcgtssm = true;
+	eg_pi->ls_clock_gating = false;
+	eg_pi->sclk_deep_sleep = false;
+
+	pi->dynamic_pcie_gen2 = true;
+
+	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
+		pi->thermal_protection = true;
+	else
+		pi->thermal_protection = false;
+
+	pi->display_gap = true;
+
+	if (rdev->flags & RADEON_IS_MOBILITY)
+		pi->dcodt = true;
+	else
+		pi->dcodt = false;
+
+	pi->ulps = true;
+
+	eg_pi->dynamic_ac_timing = true;
+	eg_pi->abm = true;
+	eg_pi->mcls = true;
+	eg_pi->light_sleep = true;
+	eg_pi->memory_transition = true;
+#if defined(CONFIG_ACPI)
+	eg_pi->pcie_performance_request =
+		radeon_acpi_is_pcie_performance_request_supported(rdev);
+#else
+	eg_pi->pcie_performance_request = false;
+#endif
+
+	if ((rdev->family == CHIP_CYPRESS) ||
+	    (rdev->family == CHIP_HEMLOCK) ||
+	    (rdev->family == CHIP_JUNIPER))
+		eg_pi->dll_default_on = true;
+	else
+		eg_pi->dll_default_on = false;
+
+	eg_pi->sclk_deep_sleep = false;
+	pi->mclk_stutter_mode_threshold = 0;
+
+	pi->sram_end = SMC_RAM_END;
+
+	return 0;
+}
+
+void cypress_dpm_fini(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	}
+	kfree(rdev->pm.dpm.ps);
+	kfree(rdev->pm.dpm.priv);
+}
+
+bool cypress_dpm_vblank_too_short(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 vblank_time = r600_dpm_get_vblank_time(rdev);
+	u32 switch_limit = pi->mem_gddr5 ? 450 : 300;
+
+	if (vblank_time < switch_limit)
+		return true;
+	else
+		return false;
+
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cypress_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cypress_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/cypress_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/cypress_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __CYPRESS_DPM_H__
+#define __CYPRESS_DPM_H__
+
+#include "rv770_dpm.h"
+#include "evergreen_smc.h"
+
+struct evergreen_mc_reg_entry {
+	u32 mclk_max;
+	u32 mc_data[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE];
+};
+
+struct evergreen_mc_reg_table {
+	u8 last;
+	u8 num_entries;
+	u16 valid_flag;
+	struct evergreen_mc_reg_entry mc_reg_table_entry[MAX_AC_TIMING_ENTRIES];
+	SMC_Evergreen_MCRegisterAddress mc_reg_address[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE];
+};
+
+struct evergreen_ulv_param {
+	bool supported;
+	struct rv7xx_pl *pl;
+};
+
+struct evergreen_arb_registers {
+	u32 mc_arb_dram_timing;
+	u32 mc_arb_dram_timing2;
+	u32 mc_arb_rfsh_rate;
+	u32 mc_arb_burst_time;
+};
+
+struct at {
+	u32 rlp;
+	u32 rmp;
+	u32 lhp;
+	u32 lmp;
+};
+
+struct evergreen_power_info {
+	/* must be first! */
+	struct rv7xx_power_info rv7xx;
+	/* flags */
+	bool vddci_control;
+	bool dynamic_ac_timing;
+	bool abm;
+	bool mcls;
+	bool light_sleep;
+	bool memory_transition;
+	bool pcie_performance_request;
+	bool pcie_performance_request_registered;
+	bool sclk_deep_sleep;
+	bool dll_default_on;
+	bool ls_clock_gating;
+	bool smu_uvd_hs;
+	bool uvd_enabled;
+	/* stored values */
+	u16 acpi_vddci;
+	u8 mvdd_high_index;
+	u8 mvdd_low_index;
+	u32 mclk_edc_wr_enable_threshold;
+	struct evergreen_mc_reg_table mc_reg_table;
+	struct atom_voltage_table vddc_voltage_table;
+	struct atom_voltage_table vddci_voltage_table;
+	struct evergreen_arb_registers bootup_arb_registers;
+	struct evergreen_ulv_param ulv;
+	struct at ats[2];
+	/* smc offsets */
+	u16 mc_reg_table_start;
+	struct radeon_ps current_rps;
+	struct rv7xx_ps current_ps;
+	struct radeon_ps requested_rps;
+	struct rv7xx_ps requested_ps;
+};
+
+#define CYPRESS_HASI_DFLT                               400000
+#define CYPRESS_MGCGTTLOCAL0_DFLT                       0x00000000
+#define CYPRESS_MGCGTTLOCAL1_DFLT                       0x00000000
+#define CYPRESS_MGCGTTLOCAL2_DFLT                       0x00000000
+#define CYPRESS_MGCGTTLOCAL3_DFLT                       0x00000000
+#define CYPRESS_MGCGCGTSSMCTRL_DFLT                     0x81944bc0
+#define REDWOOD_MGCGCGTSSMCTRL_DFLT                     0x6e944040
+#define CEDAR_MGCGCGTSSMCTRL_DFLT                       0x46944040
+#define CYPRESS_VRC_DFLT                                0xC00033
+
+#define PCIE_PERF_REQ_REMOVE_REGISTRY   0
+#define PCIE_PERF_REQ_FORCE_LOWPOWER    1
+#define PCIE_PERF_REQ_PECI_GEN1         2
+#define PCIE_PERF_REQ_PECI_GEN2         3
+#define PCIE_PERF_REQ_PECI_GEN3         4
+
+int cypress_convert_power_level_to_smc(struct radeon_device *rdev,
+				       struct rv7xx_pl *pl,
+				       RV770_SMC_HW_PERFORMANCE_LEVEL *level,
+				       u8 watermark_level);
+int cypress_populate_smc_acpi_state(struct radeon_device *rdev,
+				    RV770_SMC_STATETABLE *table);
+int cypress_populate_smc_voltage_tables(struct radeon_device *rdev,
+					RV770_SMC_STATETABLE *table);
+int cypress_populate_smc_initial_state(struct radeon_device *rdev,
+				       struct radeon_ps *radeon_initial_state,
+				       RV770_SMC_STATETABLE *table);
+u32 cypress_calculate_burst_time(struct radeon_device *rdev,
+				 u32 engine_clock, u32 memory_clock);
+void cypress_notify_link_speed_change_before_state_change(struct radeon_device *rdev,
+							  struct radeon_ps *radeon_new_state,
+							  struct radeon_ps *radeon_current_state);
+int cypress_upload_sw_state(struct radeon_device *rdev,
+			    struct radeon_ps *radeon_new_state);
+int cypress_upload_mc_reg_table(struct radeon_device *rdev,
+				struct radeon_ps *radeon_new_state);
+void cypress_program_memory_timing_parameters(struct radeon_device *rdev,
+					      struct radeon_ps *radeon_new_state);
+void cypress_notify_link_speed_change_after_state_change(struct radeon_device *rdev,
+							 struct radeon_ps *radeon_new_state,
+							 struct radeon_ps *radeon_current_state);
+int cypress_construct_voltage_tables(struct radeon_device *rdev);
+int cypress_get_mvdd_configuration(struct radeon_device *rdev);
+void cypress_enable_spread_spectrum(struct radeon_device *rdev,
+				    bool enable);
+void cypress_enable_display_gap(struct radeon_device *rdev);
+int cypress_get_table_locations(struct radeon_device *rdev);
+int cypress_populate_mc_reg_table(struct radeon_device *rdev,
+				  struct radeon_ps *radeon_boot_state);
+void cypress_program_response_times(struct radeon_device *rdev);
+int cypress_notify_smc_display_change(struct radeon_device *rdev,
+				      bool has_display);
+void cypress_enable_sclk_control(struct radeon_device *rdev,
+				 bool enable);
+void cypress_enable_mclk_control(struct radeon_device *rdev,
+				 bool enable);
+void cypress_start_dpm(struct radeon_device *rdev);
+void cypress_advertise_gen2_capability(struct radeon_device *rdev);
+u32 cypress_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf);
+u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
+				    u32 memory_clock, bool strobe_mode);
+u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreen.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreen.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreen.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreen.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,9 +33,7 @@
 #include "avivod.h"
 #include "evergreen_reg.h"
 #include "evergreen_blit_shaders.h"
-
-#define EVERGREEN_PFP_UCODE_SIZE 1120
-#define EVERGREEN_PM4_UCODE_SIZE 1376
+#include "radeon_ucode.h"
 
 static const u32 crtc_offsets[6] =
 {
@@ -47,11 +45,102 @@ static const u32 crtc_offsets[6] =
 	EVERGREEN_CRTC5_REGISTER_OFFSET
 };
 
+#include "clearstate_evergreen.h"
+
+static u32 sumo_rlc_save_restore_register_list[] =
+{
+	0x98fc,
+	0x9830,
+	0x9834,
+	0x9838,
+	0x9870,
+	0x9874,
+	0x8a14,
+	0x8b24,
+	0x8bcc,
+	0x8b10,
+	0x8d00,
+	0x8d04,
+	0x8c00,
+	0x8c04,
+	0x8c08,
+	0x8c0c,
+	0x8d8c,
+	0x8c20,
+	0x8c24,
+	0x8c28,
+	0x8c18,
+	0x8c1c,
+	0x8cf0,
+	0x8e2c,
+	0x8e38,
+	0x8c30,
+	0x9508,
+	0x9688,
+	0x9608,
+	0x960c,
+	0x9610,
+	0x9614,
+	0x88c4,
+	0x88d4,
+	0xa008,
+	0x900c,
+	0x9100,
+	0x913c,
+	0x98f8,
+	0x98f4,
+	0x9b7c,
+	0x3f8c,
+	0x8950,
+	0x8954,
+	0x8a18,
+	0x8b28,
+	0x9144,
+	0x9148,
+	0x914c,
+	0x3f90,
+	0x3f94,
+	0x915c,
+	0x9160,
+	0x9178,
+	0x917c,
+	0x9180,
+	0x918c,
+	0x9190,
+	0x9194,
+	0x9198,
+	0x919c,
+	0x91a8,
+	0x91ac,
+	0x91b0,
+	0x91b4,
+	0x91b8,
+	0x91c4,
+	0x91c8,
+	0x91cc,
+	0x91d0,
+	0x91d4,
+	0x91e0,
+	0x91e4,
+	0x91ec,
+	0x91f0,
+	0x91f4,
+	0x9200,
+	0x9204,
+	0x929c,
+	0x9150,
+	0x802c,
+};
+static u32 sumo_rlc_save_restore_register_list_size = ARRAY_SIZE(sumo_rlc_save_restore_register_list);
+
 static void evergreen_gpu_init(struct radeon_device *rdev);
 void evergreen_fini(struct radeon_device *rdev);
 void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
+void evergreen_program_aspm(struct radeon_device *rdev);
 extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
 				     int ring, u32 cp_int_cntl);
+extern void cayman_vm_decode_fault(struct radeon_device *rdev,
+				   u32 status, u32 addr);
 
 static const u32 evergreen_golden_registers[] =
 {
@@ -1417,8 +1506,8 @@ void evergreen_pm_misc(struct radeon_dev
 	struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
 
 	if (voltage->type == VOLTAGE_SW) {
-		/* 0xff01 is a flag rather then an actual voltage */
-		if (voltage->voltage == 0xff01)
+		/* 0xff0x are flags rather then an actual voltage */
+		if ((voltage->voltage & 0xff00) == 0xff00)
 			return;
 		if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) {
 			radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
@@ -1438,8 +1527,8 @@ void evergreen_pm_misc(struct radeon_dev
 			voltage = &rdev->pm.power_state[req_ps_idx].
 				clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage;
 
-		/* 0xff01 is a flag rather then an actual voltage */
-		if (voltage->vddci == 0xff01)
+		/* 0xff0x are flags rather then an actual voltage */
+		if ((voltage->vddci & 0xff00) == 0xff00)
 			return;
 		if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) {
 			radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI);
@@ -2036,7 +2125,8 @@ static void evergreen_program_watermarks
 					 u32 lb_size, u32 num_heads)
 {
 	struct drm_display_mode *mode = &radeon_crtc->base.mode;
-	struct evergreen_wm_params wm;
+	struct evergreen_wm_params wm_low, wm_high;
+	u32 dram_channels;
 	u32 pixel_period;
 	u32 line_time = 0;
 	u32 latency_watermark_a = 0, latency_watermark_b = 0;
@@ -2052,39 +2142,81 @@ static void evergreen_program_watermarks
 		line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
 		priority_a_cnt = 0;
 		priority_b_cnt = 0;
+		dram_channels = evergreen_get_number_of_dram_channels(rdev);
 
-		wm.yclk = rdev->pm.current_mclk * 10;
-		wm.sclk = rdev->pm.current_sclk * 10;
-		wm.disp_clk = mode->clock;
-		wm.src_width = mode->crtc_hdisplay;
-		wm.active_time = mode->crtc_hdisplay * pixel_period;
-		wm.blank_time = line_time - wm.active_time;
-		wm.interlaced = false;
+		/* watermark for high clocks */
+		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
+			wm_high.yclk =
+				radeon_dpm_get_mclk(rdev, false) * 10;
+			wm_high.sclk =
+				radeon_dpm_get_sclk(rdev, false) * 10;
+		} else {
+			wm_high.yclk = rdev->pm.current_mclk * 10;
+			wm_high.sclk = rdev->pm.current_sclk * 10;
+		}
+
+		wm_high.disp_clk = mode->clock;
+		wm_high.src_width = mode->crtc_hdisplay;
+		wm_high.active_time = mode->crtc_hdisplay * pixel_period;
+		wm_high.blank_time = line_time - wm_high.active_time;
+		wm_high.interlaced = false;
 		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-			wm.interlaced = true;
-		wm.vsc = radeon_crtc->vsc;
-		wm.vtaps = 1;
+			wm_high.interlaced = true;
+		wm_high.vsc = radeon_crtc->vsc;
+		wm_high.vtaps = 1;
 		if (radeon_crtc->rmx_type != RMX_OFF)
-			wm.vtaps = 2;
-		wm.bytes_per_pixel = 4; /* XXX: get this from fb config */
-		wm.lb_size = lb_size;
-		wm.dram_channels = evergreen_get_number_of_dram_channels(rdev);
-		wm.num_heads = num_heads;
+			wm_high.vtaps = 2;
+		wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
+		wm_high.lb_size = lb_size;
+		wm_high.dram_channels = dram_channels;
+		wm_high.num_heads = num_heads;
+
+		/* watermark for low clocks */
+		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
+			wm_low.yclk =
+				radeon_dpm_get_mclk(rdev, true) * 10;
+			wm_low.sclk =
+				radeon_dpm_get_sclk(rdev, true) * 10;
+		} else {
+			wm_low.yclk = rdev->pm.current_mclk * 10;
+			wm_low.sclk = rdev->pm.current_sclk * 10;
+		}
+
+		wm_low.disp_clk = mode->clock;
+		wm_low.src_width = mode->crtc_hdisplay;
+		wm_low.active_time = mode->crtc_hdisplay * pixel_period;
+		wm_low.blank_time = line_time - wm_low.active_time;
+		wm_low.interlaced = false;
+		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+			wm_low.interlaced = true;
+		wm_low.vsc = radeon_crtc->vsc;
+		wm_low.vtaps = 1;
+		if (radeon_crtc->rmx_type != RMX_OFF)
+			wm_low.vtaps = 2;
+		wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
+		wm_low.lb_size = lb_size;
+		wm_low.dram_channels = dram_channels;
+		wm_low.num_heads = num_heads;
 
 		/* set for high clocks */
-		latency_watermark_a = min(evergreen_latency_watermark(&wm), (u32)65535);
+		latency_watermark_a = min(evergreen_latency_watermark(&wm_high), (u32)65535);
 		/* set for low clocks */
-		/* wm.yclk = low clk; wm.sclk = low clk */
-		latency_watermark_b = min(evergreen_latency_watermark(&wm), (u32)65535);
+		latency_watermark_b = min(evergreen_latency_watermark(&wm_low), (u32)65535);
 
 		/* possibly force display priority to high */
 		/* should really do this at mode validation time... */
-		if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm) ||
-		    !evergreen_average_bandwidth_vs_available_bandwidth(&wm) ||
-		    !evergreen_check_latency_hiding(&wm) ||
+		if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) ||
+		    !evergreen_average_bandwidth_vs_available_bandwidth(&wm_high) ||
+		    !evergreen_check_latency_hiding(&wm_high) ||
 		    (rdev->disp_priority == 2)) {
-			DRM_DEBUG_KMS("force priority to high\n");
+			DRM_DEBUG_KMS("force priority a to high\n");
 			priority_a_cnt |= PRIORITY_ALWAYS_ON;
+		}
+		if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) ||
+		    !evergreen_average_bandwidth_vs_available_bandwidth(&wm_low) ||
+		    !evergreen_check_latency_hiding(&wm_low) ||
+		    (rdev->disp_priority == 2)) {
+			DRM_DEBUG_KMS("force priority b to high\n");
 			priority_b_cnt |= PRIORITY_ALWAYS_ON;
 		}
 
@@ -2137,6 +2269,10 @@ static void evergreen_program_watermarks
 	WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt);
 	WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt);
 
+	/* save values for DPM */
+	radeon_crtc->line_time = line_time;
+	radeon_crtc->wm_high = latency_watermark_a;
+	radeon_crtc->wm_low = latency_watermark_b;
 }
 
 /**
@@ -3120,10 +3256,8 @@ static void evergreen_gpu_init(struct ra
 		u32 efuse_straps_4;
 		u32 efuse_straps_3;
 
-		WREG32(RCU_IND_INDEX, 0x204);
-		efuse_straps_4 = RREG32(RCU_IND_DATA);
-		WREG32(RCU_IND_INDEX, 0x203);
-		efuse_straps_3 = RREG32(RCU_IND_DATA);
+		efuse_straps_4 = RREG32_RCU(0x204);
+		efuse_straps_3 = RREG32_RCU(0x203);
 		tmp = (((efuse_straps_4 & 0xf) << 4) |
 		      ((efuse_straps_3 & 0xf0000000) >> 28));
 	} else {
@@ -3727,6 +3861,262 @@ bool evergreen_dma_is_lockup(struct rade
 	return radeon_ring_test_lockup(rdev, ring);
 }
 
+/*
+ * RLC
+ */
+#define RLC_SAVE_RESTORE_LIST_END_MARKER    0x00000000
+#define RLC_CLEAR_STATE_END_MARKER          0x00000001
+
+void sumo_rlc_fini(struct radeon_device *rdev)
+{
+	int r;
+
+	/* save restore block */
+	if (rdev->rlc.save_restore_obj) {
+		r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
+		if (unlikely(r != 0))
+			dev_warn(rdev->dev, "(%d) reserve RLC sr bo failed\n", r);
+		radeon_bo_unpin(rdev->rlc.save_restore_obj);
+		radeon_bo_unreserve(rdev->rlc.save_restore_obj);
+
+		radeon_bo_unref(&rdev->rlc.save_restore_obj);
+		rdev->rlc.save_restore_obj = NULL;
+	}
+
+	/* clear state block */
+	if (rdev->rlc.clear_state_obj) {
+		r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
+		if (unlikely(r != 0))
+			dev_warn(rdev->dev, "(%d) reserve RLC c bo failed\n", r);
+		radeon_bo_unpin(rdev->rlc.clear_state_obj);
+		radeon_bo_unreserve(rdev->rlc.clear_state_obj);
+
+		radeon_bo_unref(&rdev->rlc.clear_state_obj);
+		rdev->rlc.clear_state_obj = NULL;
+	}
+}
+
+int sumo_rlc_init(struct radeon_device *rdev)
+{
+	u32 *src_ptr;
+	volatile u32 *dst_ptr;
+	u32 dws, data, i, j, k, reg_num;
+	u32 reg_list_num, reg_list_hdr_blk_index, reg_list_blk_index;
+	u64 reg_list_mc_addr;
+	struct cs_section_def *cs_data;
+	int r;
+
+	src_ptr = rdev->rlc.reg_list;
+	dws = rdev->rlc.reg_list_size;
+	cs_data = rdev->rlc.cs_data;
+
+	/* save restore block */
+	if (rdev->rlc.save_restore_obj == NULL) {
+		r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
+				     RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.save_restore_obj);
+		if (r) {
+			dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
+			return r;
+		}
+	}
+
+	r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
+	if (unlikely(r != 0)) {
+		sumo_rlc_fini(rdev);
+		return r;
+	}
+	r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
+			  &rdev->rlc.save_restore_gpu_addr);
+	if (r) {
+		radeon_bo_unreserve(rdev->rlc.save_restore_obj);
+		dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
+		sumo_rlc_fini(rdev);
+		return r;
+	}
+	r = radeon_bo_kmap(rdev->rlc.save_restore_obj, (void **)&rdev->rlc.sr_ptr);
+	if (r) {
+		dev_warn(rdev->dev, "(%d) map RLC sr bo failed\n", r);
+		sumo_rlc_fini(rdev);
+		return r;
+	}
+	/* write the sr buffer */
+	dst_ptr = rdev->rlc.sr_ptr;
+	/* format:
+	 * dw0: (reg2 << 16) | reg1
+	 * dw1: reg1 save space
+	 * dw2: reg2 save space
+	 */
+	for (i = 0; i < dws; i++) {
+		data = src_ptr[i] >> 2;
+		i++;
+		if (i < dws)
+			data |= (src_ptr[i] >> 2) << 16;
+		j = (((i - 1) * 3) / 2);
+		dst_ptr[j] = data;
+	}
+	j = ((i * 3) / 2);
+	dst_ptr[j] = RLC_SAVE_RESTORE_LIST_END_MARKER;
+
+	radeon_bo_kunmap(rdev->rlc.save_restore_obj);
+	radeon_bo_unreserve(rdev->rlc.save_restore_obj);
+
+	/* clear state block */
+	reg_list_num = 0;
+	dws = 0;
+	for (i = 0; cs_data[i].section != NULL; i++) {
+		for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
+			reg_list_num++;
+			dws += cs_data[i].section[j].reg_count;
+		}
+	}
+	reg_list_blk_index = (3 * reg_list_num + 2);
+	dws += reg_list_blk_index;
+
+	if (rdev->rlc.clear_state_obj == NULL) {
+		r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
+				     RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.clear_state_obj);
+		if (r) {
+			dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
+			sumo_rlc_fini(rdev);
+			return r;
+		}
+	}
+	r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
+	if (unlikely(r != 0)) {
+		sumo_rlc_fini(rdev);
+		return r;
+	}
+	r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
+			  &rdev->rlc.clear_state_gpu_addr);
+	if (r) {
+
+		radeon_bo_unreserve(rdev->rlc.clear_state_obj);
+		dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
+		sumo_rlc_fini(rdev);
+		return r;
+	}
+	r = radeon_bo_kmap(rdev->rlc.clear_state_obj, (void **)&rdev->rlc.cs_ptr);
+	if (r) {
+		dev_warn(rdev->dev, "(%d) map RLC c bo failed\n", r);
+		sumo_rlc_fini(rdev);
+		return r;
+	}
+	/* set up the cs buffer */
+	dst_ptr = rdev->rlc.cs_ptr;
+	reg_list_hdr_blk_index = 0;
+	reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4);
+	data = upper_32_bits(reg_list_mc_addr);
+	dst_ptr[reg_list_hdr_blk_index] = data;
+	reg_list_hdr_blk_index++;
+	for (i = 0; cs_data[i].section != NULL; i++) {
+		for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
+			reg_num = cs_data[i].section[j].reg_count;
+			data = reg_list_mc_addr & 0xffffffff;
+			dst_ptr[reg_list_hdr_blk_index] = data;
+			reg_list_hdr_blk_index++;
+
+			data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff;
+			dst_ptr[reg_list_hdr_blk_index] = data;
+			reg_list_hdr_blk_index++;
+
+			data = 0x08000000 | (reg_num * 4);
+			dst_ptr[reg_list_hdr_blk_index] = data;
+			reg_list_hdr_blk_index++;
+
+			for (k = 0; k < reg_num; k++) {
+				data = cs_data[i].section[j].extent[k];
+				dst_ptr[reg_list_blk_index + k] = data;
+			}
+			reg_list_mc_addr += reg_num * 4;
+			reg_list_blk_index += reg_num;
+		}
+	}
+	dst_ptr[reg_list_hdr_blk_index] = RLC_CLEAR_STATE_END_MARKER;
+
+	radeon_bo_kunmap(rdev->rlc.clear_state_obj);
+	radeon_bo_unreserve(rdev->rlc.clear_state_obj);
+
+	return 0;
+}
+
+static void evergreen_rlc_start(struct radeon_device *rdev)
+{
+	u32 mask = RLC_ENABLE;
+
+	if (rdev->flags & RADEON_IS_IGP) {
+		mask |= GFX_POWER_GATING_ENABLE | GFX_POWER_GATING_SRC;
+	}
+
+	WREG32(RLC_CNTL, mask);
+}
+
+int evergreen_rlc_resume(struct radeon_device *rdev)
+{
+	u32 i;
+	const __be32 *fw_data;
+
+	if (!rdev->rlc_fw)
+		return -EINVAL;
+
+	r600_rlc_stop(rdev);
+
+	WREG32(RLC_HB_CNTL, 0);
+
+	if (rdev->flags & RADEON_IS_IGP) {
+		if (rdev->family == CHIP_ARUBA) {
+			u32 always_on_bitmap =
+				3 | (3 << (16 * rdev->config.cayman.max_shader_engines));
+			/* find out the number of active simds */
+			u32 tmp = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16;
+			tmp |= 0xffffffff << rdev->config.cayman.max_simds_per_se;
+			tmp = hweight32(~tmp);
+			if (tmp == rdev->config.cayman.max_simds_per_se) {
+				WREG32(TN_RLC_LB_ALWAYS_ACTIVE_SIMD_MASK, always_on_bitmap);
+				WREG32(TN_RLC_LB_PARAMS, 0x00601004);
+				WREG32(TN_RLC_LB_INIT_SIMD_MASK, 0xffffffff);
+				WREG32(TN_RLC_LB_CNTR_INIT, 0x00000000);
+				WREG32(TN_RLC_LB_CNTR_MAX, 0x00002000);
+			}
+		} else {
+			WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
+			WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
+		}
+		WREG32(TN_RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
+		WREG32(TN_RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
+	} else {
+		WREG32(RLC_HB_BASE, 0);
+		WREG32(RLC_HB_RPTR, 0);
+		WREG32(RLC_HB_WPTR, 0);
+		WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
+		WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
+	}
+	WREG32(RLC_MC_CNTL, 0);
+	WREG32(RLC_UCODE_CNTL, 0);
+
+	fw_data = (const __be32 *)rdev->rlc_fw->data;
+	if (rdev->family >= CHIP_ARUBA) {
+		for (i = 0; i < ARUBA_RLC_UCODE_SIZE; i++) {
+			WREG32(RLC_UCODE_ADDR, i);
+			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+		}
+	} else if (rdev->family >= CHIP_CAYMAN) {
+		for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) {
+			WREG32(RLC_UCODE_ADDR, i);
+			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+		}
+	} else {
+		for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) {
+			WREG32(RLC_UCODE_ADDR, i);
+			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
+		}
+	}
+	WREG32(RLC_UCODE_ADDR, 0);
+
+	evergreen_rlc_start(rdev);
+
+	return 0;
+}
+
 /* Interrupts */
 
 u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc)
@@ -3805,6 +4195,7 @@ int evergreen_irq_set(struct radeon_devi
 	u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
 	u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0;
 	u32 dma_cntl, dma_cntl1 = 0;
+	u32 thermal_int = 0;
 
 	if (!rdev->irq.installed) {
 		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
@@ -3824,6 +4215,12 @@ int evergreen_irq_set(struct radeon_devi
 	hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
 	hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
 	hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
+	if (rdev->family == CHIP_ARUBA)
+		thermal_int = RREG32(TN_CG_THERMAL_INT_CTRL) &
+			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
+	else
+		thermal_int = RREG32(CG_THERMAL_INT) &
+			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
 
 	afmt1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
 	afmt2 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
@@ -3869,6 +4266,11 @@ int evergreen_irq_set(struct radeon_devi
 		}
 	}
 
+	if (rdev->irq.dpm_thermal) {
+		DRM_DEBUG("dpm thermal\n");
+		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
+	}
+
 	if (rdev->irq.crtc_vblank_int[0] ||
 	    atomic_read(&rdev->irq.pflip[0])) {
 		DRM_DEBUG("evergreen_irq_set: vblank 0\n");
@@ -3990,6 +4392,10 @@ int evergreen_irq_set(struct radeon_devi
 	WREG32(DC_HPD4_INT_CONTROL, hpd4);
 	WREG32(DC_HPD5_INT_CONTROL, hpd5);
 	WREG32(DC_HPD6_INT_CONTROL, hpd6);
+	if (rdev->family == CHIP_ARUBA)
+		WREG32(TN_CG_THERMAL_INT_CTRL, thermal_int);
+	else
+		WREG32(CG_THERMAL_INT, thermal_int);
 
 	WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, afmt1);
 	WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, afmt2);
@@ -4181,6 +4587,8 @@ int evergreen_irq_process(struct radeon_
 	u32 ring_index;
 	bool queue_hotplug = false;
 	bool queue_hdmi = false;
+	bool queue_thermal = false;
+	u32 status, addr;
 
 	if (!rdev->ih.enabled || rdev->shutdown)
 		return IRQ_NONE;
@@ -4467,11 +4875,14 @@ restart_ih:
 			break;
 		case 146:
 		case 147:
+			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
+			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
 			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
-				RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
+				addr);
 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
-				RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+				status);
+			cayman_vm_decode_fault(rdev, status, addr);
 			/* reset addr and status */
 			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
 			break;
@@ -4502,6 +4913,16 @@ restart_ih:
 			DRM_DEBUG("IH: DMA trap\n");
 			radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
 			break;
+		case 230: /* thermal low to high */
+			DRM_DEBUG("IH: thermal low to high\n");
+			rdev->pm.dpm.thermal.high_to_low = false;
+			queue_thermal = true;
+			break;
+		case 231: /* thermal high to low */
+			DRM_DEBUG("IH: thermal high to low\n");
+			rdev->pm.dpm.thermal.high_to_low = true;
+			queue_thermal = true;
+			break;
 		case 233: /* GUI IDLE */
 			DRM_DEBUG("IH: GUI idle\n");
 			break;
@@ -4524,6 +4945,8 @@ restart_ih:
 		schedule_work(&rdev->hotplug_work);
 	if (queue_hdmi)
 		schedule_work(&rdev->audio_work);
+	if (queue_thermal && rdev->pm.dpm_enabled)
+		schedule_work(&rdev->pm.dpm.thermal.work);
 	rdev->ih.rptr = rptr;
 	WREG32(IH_RB_RPTR, rdev->ih.rptr);
 	atomic_set(&rdev->ih.lock, 0);
@@ -4680,6 +5103,10 @@ static int evergreen_startup(struct rade
 
 	/* enable pcie gen2 link */
 	evergreen_pcie_gen2_enable(rdev);
+	/* enable aspm */
+	evergreen_program_aspm(rdev);
+
+	evergreen_mc_program(rdev);
 
 	if (ASIC_IS_DCE5(rdev)) {
 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
@@ -4708,7 +5135,6 @@ static int evergreen_startup(struct rade
 	if (r)
 		return r;
 
-	evergreen_mc_program(rdev);
 	if (rdev->flags & RADEON_IS_AGP) {
 		evergreen_agp_enable(rdev);
 	} else {
@@ -4725,6 +5151,18 @@ static int evergreen_startup(struct rade
 		dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
 	}
 
+	/* allocate rlc buffers */
+	if (rdev->flags & RADEON_IS_IGP) {
+		rdev->rlc.reg_list = sumo_rlc_save_restore_register_list;
+		rdev->rlc.reg_list_size = sumo_rlc_save_restore_register_list_size;
+		rdev->rlc.cs_data = evergreen_cs_data;
+		r = sumo_rlc_init(rdev);
+		if (r) {
+			DRM_ERROR("Failed to init rlc BOs!\n");
+			return r;
+		}
+	}
+
 	/* allocate wb buffer */
 	r = radeon_wb_init(rdev);
 	if (r)
@@ -4854,10 +5292,10 @@ int evergreen_resume(struct radeon_devic
 int evergreen_suspend(struct radeon_device *rdev)
 {
 	r600_audio_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_suspend(rdev);
 	r700_cp_stop(rdev);
 	r600_dma_stop(rdev);
-	r600_uvd_rbc_stop(rdev);
 	evergreen_irq_suspend(rdev);
 	radeon_wb_disable(rdev);
 	evergreen_pcie_gart_disable(rdev);
@@ -4956,6 +5394,8 @@ int evergreen_init(struct radeon_device
 		r700_cp_fini(rdev);
 		r600_dma_fini(rdev);
 		r600_irq_fini(rdev);
+		if (rdev->flags & RADEON_IS_IGP)
+			sumo_rlc_fini(rdev);
 		radeon_wb_fini(rdev);
 		radeon_ib_pool_fini(rdev);
 		radeon_irq_kms_fini(rdev);
@@ -4984,10 +5424,13 @@ void evergreen_fini(struct radeon_device
 	r700_cp_fini(rdev);
 	r600_dma_fini(rdev);
 	r600_irq_fini(rdev);
+	if (rdev->flags & RADEON_IS_IGP)
+		sumo_rlc_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	evergreen_pcie_gart_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
@@ -5061,3 +5504,153 @@ void evergreen_pcie_gen2_enable(struct r
 		WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
 	}
 }
+
+void evergreen_program_aspm(struct radeon_device *rdev)
+{
+	u32 data, orig;
+	u32 pcie_lc_cntl, pcie_lc_cntl_old;
+	bool disable_l0s, disable_l1 = false, disable_plloff_in_l1 = false;
+	/* fusion_platform = true
+	 * if the system is a fusion system
+	 * (APU or DGPU in a fusion system).
+	 * todo: check if the system is a fusion platform.
+	 */
+	bool fusion_platform = false;
+
+	if (radeon_aspm == 0)
+		return;
+
+	if (!(rdev->flags & RADEON_IS_PCIE))
+		return;
+
+	switch (rdev->family) {
+	case CHIP_CYPRESS:
+	case CHIP_HEMLOCK:
+	case CHIP_JUNIPER:
+	case CHIP_REDWOOD:
+	case CHIP_CEDAR:
+	case CHIP_SUMO:
+	case CHIP_SUMO2:
+	case CHIP_PALM:
+	case CHIP_ARUBA:
+		disable_l0s = true;
+		break;
+	default:
+		disable_l0s = false;
+		break;
+	}
+
+	if (rdev->flags & RADEON_IS_IGP)
+		fusion_platform = true; /* XXX also dGPUs in a fusion system */
+
+	data = orig = RREG32_PIF_PHY0(PB0_PIF_PAIRING);
+	if (fusion_platform)
+		data &= ~MULTI_PIF;
+	else
+		data |= MULTI_PIF;
+	if (data != orig)
+		WREG32_PIF_PHY0(PB0_PIF_PAIRING, data);
+
+	data = orig = RREG32_PIF_PHY1(PB1_PIF_PAIRING);
+	if (fusion_platform)
+		data &= ~MULTI_PIF;
+	else
+		data |= MULTI_PIF;
+	if (data != orig)
+		WREG32_PIF_PHY1(PB1_PIF_PAIRING, data);
+
+	pcie_lc_cntl = pcie_lc_cntl_old = RREG32_PCIE_PORT(PCIE_LC_CNTL);
+	pcie_lc_cntl &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
+	if (!disable_l0s) {
+		if (rdev->family >= CHIP_BARTS)
+			pcie_lc_cntl |= LC_L0S_INACTIVITY(7);
+		else
+			pcie_lc_cntl |= LC_L0S_INACTIVITY(3);
+	}
+
+	if (!disable_l1) {
+		if (rdev->family >= CHIP_BARTS)
+			pcie_lc_cntl |= LC_L1_INACTIVITY(7);
+		else
+			pcie_lc_cntl |= LC_L1_INACTIVITY(8);
+
+		if (!disable_plloff_in_l1) {
+			data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
+			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
+			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
+			if (data != orig)
+				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
+
+			data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
+			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
+			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
+			if (data != orig)
+				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
+
+			data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
+			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
+			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
+			if (data != orig)
+				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
+
+			data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
+			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
+			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
+			if (data != orig)
+				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
+
+			if (rdev->family >= CHIP_BARTS) {
+				data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
+				data &= ~PLL_RAMP_UP_TIME_0_MASK;
+				data |= PLL_RAMP_UP_TIME_0(4);
+				if (data != orig)
+					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
+
+				data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
+				data &= ~PLL_RAMP_UP_TIME_1_MASK;
+				data |= PLL_RAMP_UP_TIME_1(4);
+				if (data != orig)
+					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
+
+				data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
+				data &= ~PLL_RAMP_UP_TIME_0_MASK;
+				data |= PLL_RAMP_UP_TIME_0(4);
+				if (data != orig)
+					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
+
+				data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
+				data &= ~PLL_RAMP_UP_TIME_1_MASK;
+				data |= PLL_RAMP_UP_TIME_1(4);
+				if (data != orig)
+					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
+			}
+
+			data = orig = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
+			data &= ~LC_DYN_LANES_PWR_STATE_MASK;
+			data |= LC_DYN_LANES_PWR_STATE(3);
+			if (data != orig)
+				WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
+
+			if (rdev->family >= CHIP_BARTS) {
+				data = orig = RREG32_PIF_PHY0(PB0_PIF_CNTL);
+				data &= ~LS2_EXIT_TIME_MASK;
+				data |= LS2_EXIT_TIME(1);
+				if (data != orig)
+					WREG32_PIF_PHY0(PB0_PIF_CNTL, data);
+
+				data = orig = RREG32_PIF_PHY1(PB1_PIF_CNTL);
+				data &= ~LS2_EXIT_TIME_MASK;
+				data |= LS2_EXIT_TIME(1);
+				if (data != orig)
+					WREG32_PIF_PHY1(PB1_PIF_CNTL, data);
+			}
+		}
+	}
+
+	/* evergreen parts only */
+	if (rdev->family < CHIP_BARTS)
+		pcie_lc_cntl |= LC_PMI_TO_L1_DIS;
+
+	if (pcie_lc_cntl != pcie_lc_cntl_old)
+		WREG32_PCIE_PORT(PCIE_LC_CNTL, pcie_lc_cntl);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreend.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreend.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreend.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreend.h	2013-08-25 20:43:22.000000000 -0400
@@ -48,6 +48,293 @@
 #define SUMO_GB_ADDR_CONFIG_GOLDEN           0x02010002
 #define SUMO2_GB_ADDR_CONFIG_GOLDEN          0x02010002
 
+/* pm registers */
+#define	SMC_MSG						0x20c
+#define		HOST_SMC_MSG(x)				((x) << 0)
+#define		HOST_SMC_MSG_MASK			(0xff << 0)
+#define		HOST_SMC_MSG_SHIFT			0
+#define		HOST_SMC_RESP(x)			((x) << 8)
+#define		HOST_SMC_RESP_MASK			(0xff << 8)
+#define		HOST_SMC_RESP_SHIFT			8
+#define		SMC_HOST_MSG(x)				((x) << 16)
+#define		SMC_HOST_MSG_MASK			(0xff << 16)
+#define		SMC_HOST_MSG_SHIFT			16
+#define		SMC_HOST_RESP(x)			((x) << 24)
+#define		SMC_HOST_RESP_MASK			(0xff << 24)
+#define		SMC_HOST_RESP_SHIFT			24
+
+#define DCCG_DISP_SLOW_SELECT_REG                       0x4fc
+#define		DCCG_DISP1_SLOW_SELECT(x)		((x) << 0)
+#define		DCCG_DISP1_SLOW_SELECT_MASK		(7 << 0)
+#define		DCCG_DISP1_SLOW_SELECT_SHIFT		0
+#define		DCCG_DISP2_SLOW_SELECT(x)		((x) << 4)
+#define		DCCG_DISP2_SLOW_SELECT_MASK		(7 << 4)
+#define		DCCG_DISP2_SLOW_SELECT_SHIFT		4
+
+#define	CG_SPLL_FUNC_CNTL				0x600
+#define		SPLL_RESET				(1 << 0)
+#define		SPLL_SLEEP				(1 << 1)
+#define		SPLL_BYPASS_EN				(1 << 3)
+#define		SPLL_REF_DIV(x)				((x) << 4)
+#define		SPLL_REF_DIV_MASK			(0x3f << 4)
+#define		SPLL_PDIV_A(x)				((x) << 20)
+#define		SPLL_PDIV_A_MASK			(0x7f << 20)
+#define	CG_SPLL_FUNC_CNTL_2				0x604
+#define		SCLK_MUX_SEL(x)				((x) << 0)
+#define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define	CG_SPLL_FUNC_CNTL_3				0x608
+#define		SPLL_FB_DIV(x)				((x) << 0)
+#define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
+#define		SPLL_DITHEN				(1 << 28)
+
+#define MPLL_CNTL_MODE                                  0x61c
+#       define SS_SSEN                                  (1 << 24)
+#       define SS_DSMODE_EN                             (1 << 25)
+
+#define	MPLL_AD_FUNC_CNTL				0x624
+#define		CLKF(x)					((x) << 0)
+#define		CLKF_MASK				(0x7f << 0)
+#define		CLKR(x)					((x) << 7)
+#define		CLKR_MASK				(0x1f << 7)
+#define		CLKFRAC(x)				((x) << 12)
+#define		CLKFRAC_MASK				(0x1f << 12)
+#define		YCLK_POST_DIV(x)			((x) << 17)
+#define		YCLK_POST_DIV_MASK			(3 << 17)
+#define		IBIAS(x)				((x) << 20)
+#define		IBIAS_MASK				(0x3ff << 20)
+#define		RESET					(1 << 30)
+#define		PDNB					(1 << 31)
+#define	MPLL_AD_FUNC_CNTL_2				0x628
+#define		BYPASS					(1 << 19)
+#define		BIAS_GEN_PDNB				(1 << 24)
+#define		RESET_EN				(1 << 25)
+#define		VCO_MODE				(1 << 29)
+#define	MPLL_DQ_FUNC_CNTL				0x62c
+#define	MPLL_DQ_FUNC_CNTL_2				0x630
+
+#define GENERAL_PWRMGT                                  0x63c
+#       define GLOBAL_PWRMGT_EN                         (1 << 0)
+#       define STATIC_PM_EN                             (1 << 1)
+#       define THERMAL_PROTECTION_DIS                   (1 << 2)
+#       define THERMAL_PROTECTION_TYPE                  (1 << 3)
+#       define ENABLE_GEN2PCIE                          (1 << 4)
+#       define ENABLE_GEN2XSP                           (1 << 5)
+#       define SW_SMIO_INDEX(x)                         ((x) << 6)
+#       define SW_SMIO_INDEX_MASK                       (3 << 6)
+#       define SW_SMIO_INDEX_SHIFT                      6
+#       define LOW_VOLT_D2_ACPI                         (1 << 8)
+#       define LOW_VOLT_D3_ACPI                         (1 << 9)
+#       define VOLT_PWRMGT_EN                           (1 << 10)
+#       define BACKBIAS_PAD_EN                          (1 << 18)
+#       define BACKBIAS_VALUE                           (1 << 19)
+#       define DYN_SPREAD_SPECTRUM_EN                   (1 << 23)
+#       define AC_DC_SW                                 (1 << 24)
+
+#define SCLK_PWRMGT_CNTL                                  0x644
+#       define SCLK_PWRMGT_OFF                            (1 << 0)
+#       define SCLK_LOW_D1                                (1 << 1)
+#       define FIR_RESET                                  (1 << 4)
+#       define FIR_FORCE_TREND_SEL                        (1 << 5)
+#       define FIR_TREND_MODE                             (1 << 6)
+#       define DYN_GFX_CLK_OFF_EN                         (1 << 7)
+#       define GFX_CLK_FORCE_ON                           (1 << 8)
+#       define GFX_CLK_REQUEST_OFF                        (1 << 9)
+#       define GFX_CLK_FORCE_OFF                          (1 << 10)
+#       define GFX_CLK_OFF_ACPI_D1                        (1 << 11)
+#       define GFX_CLK_OFF_ACPI_D2                        (1 << 12)
+#       define GFX_CLK_OFF_ACPI_D3                        (1 << 13)
+#       define DYN_LIGHT_SLEEP_EN                         (1 << 14)
+#define	MCLK_PWRMGT_CNTL				0x648
+#       define DLL_SPEED(x)				((x) << 0)
+#       define DLL_SPEED_MASK				(0x1f << 0)
+#       define MPLL_PWRMGT_OFF                          (1 << 5)
+#       define DLL_READY                                (1 << 6)
+#       define MC_INT_CNTL                              (1 << 7)
+#       define MRDCKA0_PDNB                             (1 << 8)
+#       define MRDCKA1_PDNB                             (1 << 9)
+#       define MRDCKB0_PDNB                             (1 << 10)
+#       define MRDCKB1_PDNB                             (1 << 11)
+#       define MRDCKC0_PDNB                             (1 << 12)
+#       define MRDCKC1_PDNB                             (1 << 13)
+#       define MRDCKD0_PDNB                             (1 << 14)
+#       define MRDCKD1_PDNB                             (1 << 15)
+#       define MRDCKA0_RESET                            (1 << 16)
+#       define MRDCKA1_RESET                            (1 << 17)
+#       define MRDCKB0_RESET                            (1 << 18)
+#       define MRDCKB1_RESET                            (1 << 19)
+#       define MRDCKC0_RESET                            (1 << 20)
+#       define MRDCKC1_RESET                            (1 << 21)
+#       define MRDCKD0_RESET                            (1 << 22)
+#       define MRDCKD1_RESET                            (1 << 23)
+#       define DLL_READY_READ                           (1 << 24)
+#       define USE_DISPLAY_GAP                          (1 << 25)
+#       define USE_DISPLAY_URGENT_NORMAL                (1 << 26)
+#       define MPLL_TURNOFF_D2                          (1 << 28)
+#define	DLL_CNTL					0x64c
+#       define MRDCKA0_BYPASS                           (1 << 24)
+#       define MRDCKA1_BYPASS                           (1 << 25)
+#       define MRDCKB0_BYPASS                           (1 << 26)
+#       define MRDCKB1_BYPASS                           (1 << 27)
+#       define MRDCKC0_BYPASS                           (1 << 28)
+#       define MRDCKC1_BYPASS                           (1 << 29)
+#       define MRDCKD0_BYPASS                           (1 << 30)
+#       define MRDCKD1_BYPASS                           (1 << 31)
+
+#define CG_AT                                           0x6d4
+#       define CG_R(x)					((x) << 0)
+#       define CG_R_MASK				(0xffff << 0)
+#       define CG_L(x)					((x) << 16)
+#       define CG_L_MASK				(0xffff << 16)
+
+#define CG_DISPLAY_GAP_CNTL                               0x714
+#       define DISP1_GAP(x)                               ((x) << 0)
+#       define DISP1_GAP_MASK                             (3 << 0)
+#       define DISP2_GAP(x)                               ((x) << 2)
+#       define DISP2_GAP_MASK                             (3 << 2)
+#       define VBI_TIMER_COUNT(x)                         ((x) << 4)
+#       define VBI_TIMER_COUNT_MASK                       (0x3fff << 4)
+#       define VBI_TIMER_UNIT(x)                          ((x) << 20)
+#       define VBI_TIMER_UNIT_MASK                        (7 << 20)
+#       define DISP1_GAP_MCHG(x)                          ((x) << 24)
+#       define DISP1_GAP_MCHG_MASK                        (3 << 24)
+#       define DISP2_GAP_MCHG(x)                          ((x) << 26)
+#       define DISP2_GAP_MCHG_MASK                        (3 << 26)
+
+#define	CG_BIF_REQ_AND_RSP				0x7f4
+#define		CG_CLIENT_REQ(x)			((x) << 0)
+#define		CG_CLIENT_REQ_MASK			(0xff << 0)
+#define		CG_CLIENT_REQ_SHIFT			0
+#define		CG_CLIENT_RESP(x)			((x) << 8)
+#define		CG_CLIENT_RESP_MASK			(0xff << 8)
+#define		CG_CLIENT_RESP_SHIFT			8
+#define		CLIENT_CG_REQ(x)			((x) << 16)
+#define		CLIENT_CG_REQ_MASK			(0xff << 16)
+#define		CLIENT_CG_REQ_SHIFT			16
+#define		CLIENT_CG_RESP(x)			((x) << 24)
+#define		CLIENT_CG_RESP_MASK			(0xff << 24)
+#define		CLIENT_CG_RESP_SHIFT			24
+
+#define	CG_SPLL_SPREAD_SPECTRUM				0x790
+#define		SSEN					(1 << 0)
+#define	CG_SPLL_SPREAD_SPECTRUM_2			0x794
+
+#define	MPLL_SS1					0x85c
+#define		CLKV(x)					((x) << 0)
+#define		CLKV_MASK				(0x3ffffff << 0)
+#define	MPLL_SS2					0x860
+#define		CLKS(x)					((x) << 0)
+#define		CLKS_MASK				(0xfff << 0)
+
+#define	CG_IND_ADDR					0x8f8
+#define	CG_IND_DATA					0x8fc
+/* CGIND regs */
+#define	CG_CGTT_LOCAL_0					0x00
+#define	CG_CGTT_LOCAL_1					0x01
+#define	CG_CGTT_LOCAL_2					0x02
+#define	CG_CGTT_LOCAL_3					0x03
+#define	CG_CGLS_TILE_0					0x20
+#define	CG_CGLS_TILE_1					0x21
+#define	CG_CGLS_TILE_2					0x22
+#define	CG_CGLS_TILE_3					0x23
+#define	CG_CGLS_TILE_4					0x24
+#define	CG_CGLS_TILE_5					0x25
+#define	CG_CGLS_TILE_6					0x26
+#define	CG_CGLS_TILE_7					0x27
+#define	CG_CGLS_TILE_8					0x28
+#define	CG_CGLS_TILE_9					0x29
+#define	CG_CGLS_TILE_10					0x2a
+#define	CG_CGLS_TILE_11					0x2b
+
+#define VM_L2_CG                                        0x15c0
+
+#define MC_CONFIG                                       0x2000
+
+#define MC_CONFIG_MCD                                   0x20a0
+#define MC_CG_CONFIG_MCD                                0x20a4
+#define		MC_RD_ENABLE_MCD(x)			((x) << 8)
+#define		MC_RD_ENABLE_MCD_MASK			(7 << 8)
+
+#define MC_HUB_MISC_HUB_CG                              0x20b8
+#define MC_HUB_MISC_VM_CG                               0x20bc
+#define MC_HUB_MISC_SIP_CG                              0x20c0
+
+#define MC_XPB_CLK_GAT                                  0x2478
+
+#define MC_CG_CONFIG                                    0x25bc
+#define		MC_RD_ENABLE(x)				((x) << 4)
+#define		MC_RD_ENABLE_MASK			(3 << 4)
+
+#define MC_CITF_MISC_RD_CG                              0x2648
+#define MC_CITF_MISC_WR_CG                              0x264c
+#define MC_CITF_MISC_VM_CG                              0x2650
+#       define MEM_LS_ENABLE                            (1 << 19)
+
+#define MC_ARB_BURST_TIME                               0x2808
+#define		STATE0(x)				((x) << 0)
+#define		STATE0_MASK				(0x1f << 0)
+#define		STATE1(x)				((x) << 5)
+#define		STATE1_MASK				(0x1f << 5)
+#define		STATE2(x)				((x) << 10)
+#define		STATE2_MASK				(0x1f << 10)
+#define		STATE3(x)				((x) << 15)
+#define		STATE3_MASK				(0x1f << 15)
+
+#define MC_SEQ_RAS_TIMING                               0x28a0
+#define MC_SEQ_CAS_TIMING                               0x28a4
+#define MC_SEQ_MISC_TIMING                              0x28a8
+#define MC_SEQ_MISC_TIMING2                             0x28ac
+
+#define MC_SEQ_RD_CTL_D0                                0x28b4
+#define MC_SEQ_RD_CTL_D1                                0x28b8
+#define MC_SEQ_WR_CTL_D0                                0x28bc
+#define MC_SEQ_WR_CTL_D1                                0x28c0
+
+#define MC_SEQ_STATUS_M                                 0x29f4
+#       define PMG_PWRSTATE                             (1 << 16)
+
+#define MC_SEQ_MISC1                                    0x2a04
+#define MC_SEQ_RESERVE_M                                0x2a08
+#define MC_PMG_CMD_EMRS                                 0x2a0c
+
+#define MC_SEQ_MISC3                                    0x2a2c
+
+#define MC_SEQ_MISC5                                    0x2a54
+#define MC_SEQ_MISC6                                    0x2a58
+
+#define MC_SEQ_MISC7                                    0x2a64
+
+#define MC_SEQ_CG                                       0x2a68
+#define		CG_SEQ_REQ(x)				((x) << 0)
+#define		CG_SEQ_REQ_MASK				(0xff << 0)
+#define		CG_SEQ_REQ_SHIFT			0
+#define		CG_SEQ_RESP(x)				((x) << 8)
+#define		CG_SEQ_RESP_MASK			(0xff << 8)
+#define		CG_SEQ_RESP_SHIFT			8
+#define		SEQ_CG_REQ(x)				((x) << 16)
+#define		SEQ_CG_REQ_MASK				(0xff << 16)
+#define		SEQ_CG_REQ_SHIFT			16
+#define		SEQ_CG_RESP(x)				((x) << 24)
+#define		SEQ_CG_RESP_MASK			(0xff << 24)
+#define		SEQ_CG_RESP_SHIFT			24
+#define MC_SEQ_RAS_TIMING_LP                            0x2a6c
+#define MC_SEQ_CAS_TIMING_LP                            0x2a70
+#define MC_SEQ_MISC_TIMING_LP                           0x2a74
+#define MC_SEQ_MISC_TIMING2_LP                          0x2a78
+#define MC_SEQ_WR_CTL_D0_LP                             0x2a7c
+#define MC_SEQ_WR_CTL_D1_LP                             0x2a80
+#define MC_SEQ_PMG_CMD_EMRS_LP                          0x2a84
+#define MC_SEQ_PMG_CMD_MRS_LP                           0x2a88
+
+#define MC_PMG_CMD_MRS                                  0x2aac
+
+#define MC_SEQ_RD_CTL_D0_LP                             0x2b1c
+#define MC_SEQ_RD_CTL_D1_LP                             0x2b20
+
+#define MC_PMG_CMD_MRS1                                 0x2b44
+#define MC_SEQ_PMG_CMD_MRS1_LP                          0x2b48
+
+#define CGTS_SM_CTRL_REG                                0x9150
+
 /* Registers */
 
 #define RCU_IND_INDEX           			0x100
@@ -90,6 +377,34 @@
 #define CG_VCLK_STATUS                                  0x61c
 #define	CG_SCRATCH1					0x820
 
+#define RLC_CNTL                                        0x3f00
+#       define RLC_ENABLE                               (1 << 0)
+#       define GFX_POWER_GATING_ENABLE                  (1 << 7)
+#       define GFX_POWER_GATING_SRC                     (1 << 8)
+#       define DYN_PER_SIMD_PG_ENABLE                   (1 << 27)
+#       define LB_CNT_SPIM_ACTIVE                       (1 << 30)
+#       define LOAD_BALANCE_ENABLE                      (1 << 31)
+
+#define RLC_HB_BASE                                       0x3f10
+#define RLC_HB_CNTL                                       0x3f0c
+#define RLC_HB_RPTR                                       0x3f20
+#define RLC_HB_WPTR                                       0x3f1c
+#define RLC_HB_WPTR_LSB_ADDR                              0x3f14
+#define RLC_HB_WPTR_MSB_ADDR                              0x3f18
+#define RLC_MC_CNTL                                       0x3f44
+#define RLC_UCODE_CNTL                                    0x3f48
+#define RLC_UCODE_ADDR                                    0x3f2c
+#define RLC_UCODE_DATA                                    0x3f30
+
+/* new for TN */
+#define TN_RLC_SAVE_AND_RESTORE_BASE                      0x3f10
+#define TN_RLC_LB_CNTR_MAX                                0x3f14
+#define TN_RLC_LB_CNTR_INIT                               0x3f18
+#define TN_RLC_CLEAR_STATE_RESTORE_BASE                   0x3f20
+#define TN_RLC_LB_INIT_SIMD_MASK                          0x3fe4
+#define TN_RLC_LB_ALWAYS_ACTIVE_SIMD_MASK                 0x3fe8
+#define TN_RLC_LB_PARAMS                                  0x3fec
+
 #define GRBM_GFX_INDEX          			0x802C
 #define		INSTANCE_INDEX(x)			((x) << 0)
 #define		SE_INDEX(x)     			((x) << 16)
@@ -182,6 +497,9 @@
 #define DCCG_AUDIO_DTO0_MODULE            0x05b4
 #define DCCG_AUDIO_DTO0_LOAD              0x05b8
 #define DCCG_AUDIO_DTO0_CNTL              0x05bc
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0)
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0
 
 #define DCCG_AUDIO_DTO1_PHASE             0x05c0
 #define DCCG_AUDIO_DTO1_MODULE            0x05c4
@@ -503,6 +821,30 @@
 #define	CG_THERMAL_CTRL					0x72c
 #define		TOFFSET_MASK			        0x00003FE0
 #define		TOFFSET_SHIFT			        5
+#define		DIG_THERM_DPM(x)			((x) << 14)
+#define		DIG_THERM_DPM_MASK			0x003FC000
+#define		DIG_THERM_DPM_SHIFT			14
+
+#define	CG_THERMAL_INT					0x734
+#define		DIG_THERM_INTH(x)			((x) << 8)
+#define		DIG_THERM_INTH_MASK			0x0000FF00
+#define		DIG_THERM_INTH_SHIFT			8
+#define		DIG_THERM_INTL(x)			((x) << 16)
+#define		DIG_THERM_INTL_MASK			0x00FF0000
+#define		DIG_THERM_INTL_SHIFT			16
+#define 	THERM_INT_MASK_HIGH			(1 << 24)
+#define 	THERM_INT_MASK_LOW			(1 << 25)
+
+#define	TN_CG_THERMAL_INT_CTRL				0x738
+#define		TN_DIG_THERM_INTH(x)			((x) << 0)
+#define		TN_DIG_THERM_INTH_MASK			0x000000FF
+#define		TN_DIG_THERM_INTH_SHIFT			0
+#define		TN_DIG_THERM_INTL(x)			((x) << 8)
+#define		TN_DIG_THERM_INTL_MASK			0x0000FF00
+#define		TN_DIG_THERM_INTL_SHIFT			8
+#define 	TN_THERM_INT_MASK_HIGH			(1 << 24)
+#define 	TN_THERM_INT_MASK_LOW			(1 << 25)
+
 #define	CG_MULT_THERMAL_STATUS				0x740
 #define		ASIC_T(x)			        ((x) << 16)
 #define		ASIC_T_MASK			        0x07FF0000
@@ -510,6 +852,7 @@
 #define	CG_TS0_STATUS					0x760
 #define		TS0_ADC_DOUT_MASK			0x000003FF
 #define		TS0_ADC_DOUT_SHIFT			0
+
 /* APU */
 #define	CG_THERMAL_STATUS			        0x678
 
@@ -992,7 +1335,48 @@
 #define	DMA_PACKET_CONSTANT_FILL                0xd
 #define	DMA_PACKET_NOP                          0xf
 
-/* PCIE link stuff */
+/* PIF PHY0 indirect regs */
+#define PB0_PIF_CNTL                                      0x10
+#       define LS2_EXIT_TIME(x)                           ((x) << 17)
+#       define LS2_EXIT_TIME_MASK                         (0x7 << 17)
+#       define LS2_EXIT_TIME_SHIFT                        17
+#define PB0_PIF_PAIRING                                   0x11
+#       define MULTI_PIF                                  (1 << 25)
+#define PB0_PIF_PWRDOWN_0                                 0x12
+#       define PLL_POWER_STATE_IN_TXS2_0(x)               ((x) << 7)
+#       define PLL_POWER_STATE_IN_TXS2_0_MASK             (0x7 << 7)
+#       define PLL_POWER_STATE_IN_TXS2_0_SHIFT            7
+#       define PLL_POWER_STATE_IN_OFF_0(x)                ((x) << 10)
+#       define PLL_POWER_STATE_IN_OFF_0_MASK              (0x7 << 10)
+#       define PLL_POWER_STATE_IN_OFF_0_SHIFT             10
+#       define PLL_RAMP_UP_TIME_0(x)                      ((x) << 24)
+#       define PLL_RAMP_UP_TIME_0_MASK                    (0x7 << 24)
+#       define PLL_RAMP_UP_TIME_0_SHIFT                   24
+#define PB0_PIF_PWRDOWN_1                                 0x13
+#       define PLL_POWER_STATE_IN_TXS2_1(x)               ((x) << 7)
+#       define PLL_POWER_STATE_IN_TXS2_1_MASK             (0x7 << 7)
+#       define PLL_POWER_STATE_IN_TXS2_1_SHIFT            7
+#       define PLL_POWER_STATE_IN_OFF_1(x)                ((x) << 10)
+#       define PLL_POWER_STATE_IN_OFF_1_MASK              (0x7 << 10)
+#       define PLL_POWER_STATE_IN_OFF_1_SHIFT             10
+#       define PLL_RAMP_UP_TIME_1(x)                      ((x) << 24)
+#       define PLL_RAMP_UP_TIME_1_MASK                    (0x7 << 24)
+#       define PLL_RAMP_UP_TIME_1_SHIFT                   24
+/* PIF PHY1 indirect regs */
+#define PB1_PIF_CNTL                                      0x10
+#define PB1_PIF_PAIRING                                   0x11
+#define PB1_PIF_PWRDOWN_0                                 0x12
+#define PB1_PIF_PWRDOWN_1                                 0x13
+/* PCIE PORT indirect regs */
+#define PCIE_LC_CNTL                                      0xa0
+#       define LC_L0S_INACTIVITY(x)                       ((x) << 8)
+#       define LC_L0S_INACTIVITY_MASK                     (0xf << 8)
+#       define LC_L0S_INACTIVITY_SHIFT                    8
+#       define LC_L1_INACTIVITY(x)                        ((x) << 12)
+#       define LC_L1_INACTIVITY_MASK                      (0xf << 12)
+#       define LC_L1_INACTIVITY_SHIFT                     12
+#       define LC_PMI_TO_L1_DIS                           (1 << 16)
+#       define LC_ASPM_TO_L1_DIS                          (1 << 24)
 #define PCIE_LC_TRAINING_CNTL                             0xa1 /* PCIE_P */
 #define PCIE_LC_LINK_WIDTH_CNTL                           0xa2 /* PCIE_P */
 #       define LC_LINK_WIDTH_SHIFT                        0
@@ -1012,6 +1396,9 @@
 #       define LC_SHORT_RECONFIG_EN                       (1 << 11)
 #       define LC_UPCONFIGURE_SUPPORT                     (1 << 12)
 #       define LC_UPCONFIGURE_DIS                         (1 << 13)
+#       define LC_DYN_LANES_PWR_STATE(x)                  ((x) << 21)
+#       define LC_DYN_LANES_PWR_STATE_MASK                (0x3 << 21)
+#       define LC_DYN_LANES_PWR_STATE_SHIFT               21
 #define PCIE_LC_SPEED_CNTL                                0xa4 /* PCIE_P */
 #       define LC_GEN2_EN_STRAP                           (1 << 0)
 #       define LC_TARGET_LINK_SPEED_OVERRIDE_EN           (1 << 1)
@@ -1020,6 +1407,9 @@
 #       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK      (0x3 << 8)
 #       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT     3
 #       define LC_CURRENT_DATA_RATE                       (1 << 11)
+#       define LC_HW_VOLTAGE_IF_CONTROL(x)                ((x) << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_MASK              (3 << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_SHIFT             12
 #       define LC_VOLTAGE_TIMER_SEL_MASK                  (0xf << 14)
 #       define LC_CLR_FAILED_SPD_CHANGE_CNT               (1 << 21)
 #       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 23)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreen_hdmi.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreen_hdmi.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreen_hdmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreen_hdmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,14 +128,7 @@ static void evergreen_hdmi_update_avi_in
 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 	uint32_t offset = dig->afmt->offset;
 	uint8_t *frame = buffer + 3;
-
-	/* Our header values (type, version, length) should be alright, Intel
-	 * is using the same. Checksum function also seems to be OK, it works
-	 * fine for audio infoframe. However calculated value is always lower
-	 * by 2 in comparison to fglrx. It breaks displaying anything in case
-	 * of TVs that strictly check the checksum. Hack it manually here to
-	 * workaround this issue. */
-	frame[0x0] += 2;
+	uint8_t *header = buffer;
 
 	WREG32(AFMT_AVI_INFO0 + offset,
 		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
@@ -144,7 +137,7 @@ static void evergreen_hdmi_update_avi_in
 	WREG32(AFMT_AVI_INFO2 + offset,
 		frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
 	WREG32(AFMT_AVI_INFO3 + offset,
-		frame[0xC] | (frame[0xD] << 8));
+		frame[0xC] | (frame[0xD] << 8) | (header[1] << 24));
 }
 
 static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
@@ -155,18 +148,40 @@ static void evergreen_audio_set_dto(stru
 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
 	u32 base_rate = 24000;
+	u32 max_ratio = clock / base_rate;
+	u32 dto_phase;
+	u32 dto_modulo = clock;
+	u32 wallclock_ratio;
+	u32 dto_cntl;
 
 	if (!dig || !dig->afmt)
 		return;
 
+	if (max_ratio >= 8) {
+		dto_phase = 192 * 1000;
+		wallclock_ratio = 3;
+	} else if (max_ratio >= 4) {
+		dto_phase = 96 * 1000;
+		wallclock_ratio = 2;
+	} else if (max_ratio >= 2) {
+		dto_phase = 48 * 1000;
+		wallclock_ratio = 1;
+	} else {
+		dto_phase = 24 * 1000;
+		wallclock_ratio = 0;
+	}
+	dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+	dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
+	WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
+
 	/* XXX two dtos; generally use dto0 for hdmi */
 	/* Express [24MHz / target pixel clock] as an exact rational
 	 * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
 	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
 	 */
-	WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
-	WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
 	WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id));
+	WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
+	WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
 }
 
 
@@ -184,6 +199,9 @@ void evergreen_hdmi_setmode(struct drm_e
 	uint32_t offset;
 	ssize_t err;
 
+	if (!dig || !dig->afmt)
+		return;
+
 	/* Silent, r600_hdmi_enable will raise WARN for us */
 	if (!dig->afmt->enabled)
 		return;
@@ -287,6 +305,9 @@ void evergreen_hdmi_enable(struct drm_en
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 
+	if (!dig || !dig->afmt)
+		return;
+
 	/* Silent, r600_hdmi_enable will raise WARN for us */
 	if (enable && dig->afmt->enabled)
 		return;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreen_reg.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreen_reg.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreen_reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreen_reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,16 @@
 #ifndef __EVERGREEN_REG_H__
 #define __EVERGREEN_REG_H__
 
+/* trinity */
+#define TN_SMC_IND_INDEX_0                              0x200
+#define TN_SMC_IND_DATA_0                               0x204
+
 /* evergreen */
+#define EVERGREEN_PIF_PHY0_INDEX                        0x8
+#define EVERGREEN_PIF_PHY0_DATA                         0xc
+#define EVERGREEN_PIF_PHY1_INDEX                        0x10
+#define EVERGREEN_PIF_PHY1_DATA                         0x14
+
 #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS               0x310
 #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH          0x324
 #define EVERGREEN_D3VGA_CONTROL                         0x3e0
@@ -40,6 +49,9 @@
 #define EVERGREEN_AUDIO_PLL1_DIV			0x5b4
 #define EVERGREEN_AUDIO_PLL1_UNK			0x5bc
 
+#define EVERGREEN_CG_IND_ADDR                           0x8f8
+#define EVERGREEN_CG_IND_DATA                           0x8fc
+
 #define EVERGREEN_AUDIO_ENABLE				0x5e78
 #define EVERGREEN_AUDIO_VENDOR_ID			0x5ec0
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreen_smc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreen_smc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/evergreen_smc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/evergreen_smc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __EVERGREEN_SMC_H__
+#define __EVERGREEN_SMC_H__
+
+#include "rv770_smc.h"
+
+#pragma pack(push, 1)
+
+#define SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE 16
+
+struct SMC_Evergreen_MCRegisterAddress
+{
+    uint16_t s0;
+    uint16_t s1;
+};
+
+typedef struct SMC_Evergreen_MCRegisterAddress SMC_Evergreen_MCRegisterAddress;
+
+
+struct SMC_Evergreen_MCRegisterSet
+{
+    uint32_t value[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE];
+};
+
+typedef struct SMC_Evergreen_MCRegisterSet SMC_Evergreen_MCRegisterSet;
+
+struct SMC_Evergreen_MCRegisters
+{
+    uint8_t                             last;
+    uint8_t                             reserved[3];
+    SMC_Evergreen_MCRegisterAddress     address[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE];
+    SMC_Evergreen_MCRegisterSet         data[5];
+};
+
+typedef struct SMC_Evergreen_MCRegisters SMC_Evergreen_MCRegisters;
+
+#define EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION 0x100
+
+#define EVERGREEN_SMC_FIRMWARE_HEADER_softRegisters   0x0
+#define EVERGREEN_SMC_FIRMWARE_HEADER_stateTable      0xC
+#define EVERGREEN_SMC_FIRMWARE_HEADER_mcRegisterTable 0x20
+
+
+#pragma pack(pop)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/Makefile linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/Makefile
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -76,7 +76,10 @@ radeon-y += radeon_device.o radeon_asic.
 	evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
 	evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
 	atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
-	si_blit_shaders.o radeon_prime.o radeon_uvd.o
+	si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
+	r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
+	rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \
+	trinity_smc.o ni_dpm.o si_smc.o si_dpm.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/mkregtable.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/mkregtable.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/mkregtable.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/mkregtable.c	2013-08-25 20:43:22.000000000 -0400
@@ -373,19 +373,6 @@ static inline void list_splice_tail_init
 		pos = pos->next)
 
 /**
- * __list_for_each	-	iterate over a list
- * @pos:	the &struct list_head to use as a loop cursor.
- * @head:	the head for your list.
- *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no prefetching is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __list_for_each(pos, head) \
-	for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
  * list_for_each_prev	-	iterate over a list backwards
  * @pos:	the &struct list_head to use as a loop cursor.
  * @head:	the head for your list.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ni.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ni.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ni.c	2013-07-01 10:32:21.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ni.c	2013-08-31 17:51:43.000000000 -0400
@@ -22,7 +22,6 @@
  * Authors: Alex Deucher
  */
 #include <linux/firmware.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <drm/drmP.h>
@@ -33,6 +32,135 @@
 #include "atom.h"
 #include "ni_reg.h"
 #include "cayman_blit_shaders.h"
+#include "radeon_ucode.h"
+#include "clearstate_cayman.h"
+
+static u32 tn_rlc_save_restore_register_list[] =
+{
+	0x98fc,
+	0x98f0,
+	0x9834,
+	0x9838,
+	0x9870,
+	0x9874,
+	0x8a14,
+	0x8b24,
+	0x8bcc,
+	0x8b10,
+	0x8c30,
+	0x8d00,
+	0x8d04,
+	0x8c00,
+	0x8c04,
+	0x8c10,
+	0x8c14,
+	0x8d8c,
+	0x8cf0,
+	0x8e38,
+	0x9508,
+	0x9688,
+	0x9608,
+	0x960c,
+	0x9610,
+	0x9614,
+	0x88c4,
+	0x8978,
+	0x88d4,
+	0x900c,
+	0x9100,
+	0x913c,
+	0x90e8,
+	0x9354,
+	0xa008,
+	0x98f8,
+	0x9148,
+	0x914c,
+	0x3f94,
+	0x98f4,
+	0x9b7c,
+	0x3f8c,
+	0x8950,
+	0x8954,
+	0x8a18,
+	0x8b28,
+	0x9144,
+	0x3f90,
+	0x915c,
+	0x9160,
+	0x9178,
+	0x917c,
+	0x9180,
+	0x918c,
+	0x9190,
+	0x9194,
+	0x9198,
+	0x919c,
+	0x91a8,
+	0x91ac,
+	0x91b0,
+	0x91b4,
+	0x91b8,
+	0x91c4,
+	0x91c8,
+	0x91cc,
+	0x91d0,
+	0x91d4,
+	0x91e0,
+	0x91e4,
+	0x91ec,
+	0x91f0,
+	0x91f4,
+	0x9200,
+	0x9204,
+	0x929c,
+	0x8030,
+	0x9150,
+	0x9a60,
+	0x920c,
+	0x9210,
+	0x9228,
+	0x922c,
+	0x9244,
+	0x9248,
+	0x91e8,
+	0x9294,
+	0x9208,
+	0x9224,
+	0x9240,
+	0x9220,
+	0x923c,
+	0x9258,
+	0x9744,
+	0xa200,
+	0xa204,
+	0xa208,
+	0xa20c,
+	0x8d58,
+	0x9030,
+	0x9034,
+	0x9038,
+	0x903c,
+	0x9040,
+	0x9654,
+	0x897c,
+	0xa210,
+	0xa214,
+	0x9868,
+	0xa02c,
+	0x9664,
+	0x9698,
+	0x949c,
+	0x8e10,
+	0x8e18,
+	0x8c50,
+	0x8c58,
+	0x8c60,
+	0x8c68,
+	0x89b4,
+	0x9830,
+	0x802c,
+};
+static u32 tn_rlc_save_restore_register_list_size = ARRAY_SIZE(tn_rlc_save_restore_register_list);
 
 extern bool evergreen_is_display_hung(struct radeon_device *rdev);
 extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
@@ -44,20 +172,9 @@ extern void evergreen_irq_suspend(struct
 extern int evergreen_mc_init(struct radeon_device *rdev);
 extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
 extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
-extern void si_rlc_fini(struct radeon_device *rdev);
-extern int si_rlc_init(struct radeon_device *rdev);
-
-#define EVERGREEN_PFP_UCODE_SIZE 1120
-#define EVERGREEN_PM4_UCODE_SIZE 1376
-#define EVERGREEN_RLC_UCODE_SIZE 768
-#define BTC_MC_UCODE_SIZE 6024
-
-#define CAYMAN_PFP_UCODE_SIZE 2176
-#define CAYMAN_PM4_UCODE_SIZE 2176
-#define CAYMAN_RLC_UCODE_SIZE 1024
-#define CAYMAN_MC_UCODE_SIZE 6037
-
-#define ARUBA_RLC_UCODE_SIZE 1536
+extern void evergreen_program_aspm(struct radeon_device *rdev);
+extern void sumo_rlc_fini(struct radeon_device *rdev);
+extern int sumo_rlc_init(struct radeon_device *rdev);
 
 /* Firmware Names */
 /*(DEBLOBBED)*/
@@ -546,22 +663,15 @@ int ni_mc_load_microcode(struct radeon_d
 
 int ni_init_microcode(struct radeon_device *rdev)
 {
-	struct platform_device *pdev;
 	const char *chip_name;
 	const char *rlc_chip_name;
 	size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
+	size_t smc_req_size = 0;
 	char fw_name[30];
 	int err;
 
 	DRM_DEBUG("\n");
 
-	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
-	err = IS_ERR(pdev);
-	if (err) {
-		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
-		return -EINVAL;
-	}
-
 	switch (rdev->family) {
 	case CHIP_BARTS:
 		chip_name = "BARTS";
@@ -570,6 +680,7 @@ int ni_init_microcode(struct radeon_devi
 		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
 		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
 		mc_req_size = BTC_MC_UCODE_SIZE * 4;
+		smc_req_size = ALIGN(BARTS_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_TURKS:
 		chip_name = "TURKS";
@@ -578,6 +689,7 @@ int ni_init_microcode(struct radeon_devi
 		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
 		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
 		mc_req_size = BTC_MC_UCODE_SIZE * 4;
+		smc_req_size = ALIGN(TURKS_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_CAICOS:
 		chip_name = "CAICOS";
@@ -586,6 +698,7 @@ int ni_init_microcode(struct radeon_devi
 		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
 		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
 		mc_req_size = BTC_MC_UCODE_SIZE * 4;
+		smc_req_size = ALIGN(CAICOS_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_CAYMAN:
 		chip_name = "CAYMAN";
@@ -594,6 +707,7 @@ int ni_init_microcode(struct radeon_devi
 		me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
 		rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
 		mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
+		smc_req_size = ALIGN(CAYMAN_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_ARUBA:
 		chip_name = "ARUBA";
@@ -610,7 +724,7 @@ int ni_init_microcode(struct radeon_devi
 	DRM_INFO("Loading %s Microcode\n", chip_name);
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
-	err = reject_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->pfp_fw->size != pfp_req_size) {
@@ -622,7 +736,7 @@ int ni_init_microcode(struct radeon_devi
 	}
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
-	err = reject_firmware(&rdev->me_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->me_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->me_fw->size != me_req_size) {
@@ -633,7 +747,7 @@ int ni_init_microcode(struct radeon_devi
 	}
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", rlc_chip_name);
-	err = reject_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->rlc_fw->size != rlc_req_size) {
@@ -646,7 +760,7 @@ int ni_init_microcode(struct radeon_devi
 	/* no MC ucode on TN */
 	if (!(rdev->flags & RADEON_IS_IGP)) {
 		snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
-		err = reject_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
+		err = reject_firmware(&rdev->mc_fw, fw_name, rdev->dev);
 		if (err)
 			goto out;
 		if (rdev->mc_fw->size != mc_req_size) {
@@ -656,9 +770,25 @@ int ni_init_microcode(struct radeon_devi
 			err = -EINVAL;
 		}
 	}
-out:
-	platform_device_unregister(pdev);
 
+	if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
+		snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
+		err = reject_firmware(&rdev->smc_fw, fw_name, rdev->dev);
+		if (err) {
+			printk(KERN_ERR
+			       "smc: error loading firmware \"%s\"\n",
+			       fw_name);
+			release_firmware(rdev->smc_fw);
+			rdev->smc_fw = NULL;
+		} else if (rdev->smc_fw->size != smc_req_size) {
+			printk(KERN_ERR
+			       "ni_mc: Bogus length %zu in firmware \"%s\"\n",
+			       rdev->mc_fw->size, fw_name);
+			err = -EINVAL;
+		}
+	}
+
+out:
 	if (err) {
 		if (err != -EINVAL)
 			printk(KERN_ERR
@@ -676,6 +806,14 @@ out:
 	return err;
 }
 
+int tn_get_temp(struct radeon_device *rdev)
+{
+	u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
+	int actual_temp = (temp / 8) - 49;
+
+	return actual_temp * 1000;
+}
+
 /*
  * Core functions
  */
@@ -1011,6 +1149,16 @@ static void cayman_gpu_init(struct radeo
 	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
 
 	udelay(50);
+
+	/* set clockgating golden values on TN */
+	if (rdev->family == CHIP_ARUBA) {
+		tmp = RREG32_CG(CG_CGTT_LOCAL_0);
+		tmp &= ~0x00380000;
+		WREG32_CG(CG_CGTT_LOCAL_0, tmp);
+                tmp = RREG32_CG(CG_CGTT_LOCAL_1);
+		tmp &= ~0x0e000000;
+		WREG32_CG(CG_CGTT_LOCAL_1, tmp);
+	}
 }
 
 /*
@@ -1912,6 +2060,10 @@ static int cayman_startup(struct radeon_
 
 	/* enable pcie gen2 link */
 	evergreen_pcie_gen2_enable(rdev);
+	/* enable aspm */
+	evergreen_program_aspm(rdev);
+
+	evergreen_mc_program(rdev);
 
 	if (rdev->flags & RADEON_IS_IGP) {
 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
@@ -1941,7 +2093,6 @@ static int cayman_startup(struct radeon_
 	if (r)
 		return r;
 
-	evergreen_mc_program(rdev);
 	r = cayman_pcie_gart_enable(rdev);
 	if (r)
 		return r;
@@ -1956,7 +2107,10 @@ static int cayman_startup(struct radeon_
 
 	/* allocate rlc buffers */
 	if (rdev->flags & RADEON_IS_IGP) {
-		r = si_rlc_init(rdev);
+		rdev->rlc.reg_list = tn_rlc_save_restore_register_list;
+		rdev->rlc.reg_list_size = tn_rlc_save_restore_register_list_size;
+		rdev->rlc.cs_data = cayman_cs_data;
+		r = sumo_rlc_init(rdev);
 		if (r) {
 			DRM_ERROR("Failed to init rlc BOs!\n");
 			return r;
@@ -2117,7 +2271,7 @@ int cayman_suspend(struct radeon_device
 	radeon_vm_manager_fini(rdev);
 	cayman_cp_enable(rdev, false);
 	cayman_dma_stop(rdev);
-	r600_uvd_rbc_stop(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_suspend(rdev);
 	evergreen_irq_suspend(rdev);
 	radeon_wb_disable(rdev);
@@ -2213,7 +2367,7 @@ int cayman_init(struct radeon_device *rd
 		cayman_dma_fini(rdev);
 		r600_irq_fini(rdev);
 		if (rdev->flags & RADEON_IS_IGP)
-			si_rlc_fini(rdev);
+			sumo_rlc_fini(rdev);
 		radeon_wb_fini(rdev);
 		radeon_ib_pool_fini(rdev);
 		radeon_vm_manager_fini(rdev);
@@ -2244,11 +2398,12 @@ void cayman_fini(struct radeon_device *r
 	cayman_dma_fini(rdev);
 	r600_irq_fini(rdev);
 	if (rdev->flags & RADEON_IS_IGP)
-		si_rlc_fini(rdev);
+		sumo_rlc_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_vm_manager_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_fini(rdev);
 	cayman_pcie_gart_fini(rdev);
 	r600_vram_scratch_fini(rdev);
@@ -2281,6 +2436,167 @@ void cayman_vm_fini(struct radeon_device
 {
 }
 
+/**
+ * cayman_vm_decode_fault - print human readable fault info
+ *
+ * @rdev: radeon_device pointer
+ * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
+ * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
+ *
+ * Print human readable fault information (cayman/TN).
+ */
+void cayman_vm_decode_fault(struct radeon_device *rdev,
+			    u32 status, u32 addr)
+{
+	u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
+	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
+	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
+	char *block;
+
+	switch (mc_id) {
+	case 32:
+	case 16:
+	case 96:
+	case 80:
+	case 160:
+	case 144:
+	case 224:
+	case 208:
+		block = "CB";
+		break;
+	case 33:
+	case 17:
+	case 97:
+	case 81:
+	case 161:
+	case 145:
+	case 225:
+	case 209:
+		block = "CB_FMASK";
+		break;
+	case 34:
+	case 18:
+	case 98:
+	case 82:
+	case 162:
+	case 146:
+	case 226:
+	case 210:
+		block = "CB_CMASK";
+		break;
+	case 35:
+	case 19:
+	case 99:
+	case 83:
+	case 163:
+	case 147:
+	case 227:
+	case 211:
+		block = "CB_IMMED";
+		break;
+	case 36:
+	case 20:
+	case 100:
+	case 84:
+	case 164:
+	case 148:
+	case 228:
+	case 212:
+		block = "DB";
+		break;
+	case 37:
+	case 21:
+	case 101:
+	case 85:
+	case 165:
+	case 149:
+	case 229:
+	case 213:
+		block = "DB_HTILE";
+		break;
+	case 38:
+	case 22:
+	case 102:
+	case 86:
+	case 166:
+	case 150:
+	case 230:
+	case 214:
+		block = "SX";
+		break;
+	case 39:
+	case 23:
+	case 103:
+	case 87:
+	case 167:
+	case 151:
+	case 231:
+	case 215:
+		block = "DB_STEN";
+		break;
+	case 40:
+	case 24:
+	case 104:
+	case 88:
+	case 232:
+	case 216:
+	case 168:
+	case 152:
+		block = "TC_TFETCH";
+		break;
+	case 41:
+	case 25:
+	case 105:
+	case 89:
+	case 233:
+	case 217:
+	case 169:
+	case 153:
+		block = "TC_VFETCH";
+		break;
+	case 42:
+	case 26:
+	case 106:
+	case 90:
+	case 234:
+	case 218:
+	case 170:
+	case 154:
+		block = "VC";
+		break;
+	case 112:
+		block = "CP";
+		break;
+	case 113:
+	case 114:
+		block = "SH";
+		break;
+	case 115:
+		block = "VGT";
+		break;
+	case 178:
+		block = "IH";
+		break;
+	case 51:
+		block = "RLC";
+		break;
+	case 55:
+		block = "DMA";
+		break;
+	case 56:
+		block = "HDP";
+		break;
+	default:
+		block = "unknown";
+		break;
+	}
+
+	printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
+	       protections, vmid, addr,
+	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
+	       block, mc_id);
+}
+
 #define R600_ENTRY_VALID   (1 << 0)
 #define R600_PTE_SYSTEM    (1 << 1)
 #define R600_PTE_SNOOPED   (1 << 2)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/nid.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/nid.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/nid.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/nid.h	2013-08-25 20:43:22.000000000 -0400
@@ -133,6 +133,22 @@
 #define VM_CONTEXT1_CNTL2				0x1434
 #define VM_INVALIDATE_REQUEST				0x1478
 #define VM_INVALIDATE_RESPONSE				0x147c
+#define	VM_CONTEXT1_PROTECTION_FAULT_ADDR		0x14FC
+#define	VM_CONTEXT1_PROTECTION_FAULT_STATUS		0x14DC
+#define		PROTECTIONS_MASK			(0xf << 0)
+#define		PROTECTIONS_SHIFT			0
+		/* bit 0: range
+		 * bit 2: pde0
+		 * bit 3: valid
+		 * bit 4: read
+		 * bit 5: write
+		 */
+#define		MEMORY_CLIENT_ID_MASK			(0xff << 12)
+#define		MEMORY_CLIENT_ID_SHIFT			12
+#define		MEMORY_CLIENT_RW_MASK			(1 << 24)
+#define		MEMORY_CLIENT_RW_SHIFT			24
+#define		FAULT_VMID_MASK				(0x7 << 25)
+#define		FAULT_VMID_SHIFT			25
 #define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR	0x1518
 #define VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR	0x151c
 #define	VM_CONTEXT0_PAGE_TABLE_BASE_ADDR		0x153C
@@ -489,6 +505,571 @@
 #       define CACHE_FLUSH_AND_INV_EVENT_TS                     (0x14 << 0)
 #       define CACHE_FLUSH_AND_INV_EVENT                        (0x16 << 0)
 
+/* TN SMU registers */
+#define	TN_CURRENT_GNB_TEMP				0x1F390
+
+/* pm registers */
+#define	SMC_MSG						0x20c
+#define		HOST_SMC_MSG(x)				((x) << 0)
+#define		HOST_SMC_MSG_MASK			(0xff << 0)
+#define		HOST_SMC_MSG_SHIFT			0
+#define		HOST_SMC_RESP(x)			((x) << 8)
+#define		HOST_SMC_RESP_MASK			(0xff << 8)
+#define		HOST_SMC_RESP_SHIFT			8
+#define		SMC_HOST_MSG(x)				((x) << 16)
+#define		SMC_HOST_MSG_MASK			(0xff << 16)
+#define		SMC_HOST_MSG_SHIFT			16
+#define		SMC_HOST_RESP(x)			((x) << 24)
+#define		SMC_HOST_RESP_MASK			(0xff << 24)
+#define		SMC_HOST_RESP_SHIFT			24
+
+#define	CG_SPLL_FUNC_CNTL				0x600
+#define		SPLL_RESET				(1 << 0)
+#define		SPLL_SLEEP				(1 << 1)
+#define		SPLL_BYPASS_EN				(1 << 3)
+#define		SPLL_REF_DIV(x)				((x) << 4)
+#define		SPLL_REF_DIV_MASK			(0x3f << 4)
+#define		SPLL_PDIV_A(x)				((x) << 20)
+#define		SPLL_PDIV_A_MASK			(0x7f << 20)
+#define		SPLL_PDIV_A_SHIFT			20
+#define	CG_SPLL_FUNC_CNTL_2				0x604
+#define		SCLK_MUX_SEL(x)				((x) << 0)
+#define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define	CG_SPLL_FUNC_CNTL_3				0x608
+#define		SPLL_FB_DIV(x)				((x) << 0)
+#define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
+#define		SPLL_FB_DIV_SHIFT			0
+#define		SPLL_DITHEN				(1 << 28)
+
+#define MPLL_CNTL_MODE                                  0x61c
+#       define SS_SSEN                                  (1 << 24)
+#       define SS_DSMODE_EN                             (1 << 25)
+
+#define	MPLL_AD_FUNC_CNTL				0x624
+#define		CLKF(x)					((x) << 0)
+#define		CLKF_MASK				(0x7f << 0)
+#define		CLKR(x)					((x) << 7)
+#define		CLKR_MASK				(0x1f << 7)
+#define		CLKFRAC(x)				((x) << 12)
+#define		CLKFRAC_MASK				(0x1f << 12)
+#define		YCLK_POST_DIV(x)			((x) << 17)
+#define		YCLK_POST_DIV_MASK			(3 << 17)
+#define		IBIAS(x)				((x) << 20)
+#define		IBIAS_MASK				(0x3ff << 20)
+#define		RESET					(1 << 30)
+#define		PDNB					(1 << 31)
+#define	MPLL_AD_FUNC_CNTL_2				0x628
+#define		BYPASS					(1 << 19)
+#define		BIAS_GEN_PDNB				(1 << 24)
+#define		RESET_EN				(1 << 25)
+#define		VCO_MODE				(1 << 29)
+#define	MPLL_DQ_FUNC_CNTL				0x62c
+#define	MPLL_DQ_FUNC_CNTL_2				0x630
+
+#define GENERAL_PWRMGT                                  0x63c
+#       define GLOBAL_PWRMGT_EN                         (1 << 0)
+#       define STATIC_PM_EN                             (1 << 1)
+#       define THERMAL_PROTECTION_DIS                   (1 << 2)
+#       define THERMAL_PROTECTION_TYPE                  (1 << 3)
+#       define ENABLE_GEN2PCIE                          (1 << 4)
+#       define ENABLE_GEN2XSP                           (1 << 5)
+#       define SW_SMIO_INDEX(x)                         ((x) << 6)
+#       define SW_SMIO_INDEX_MASK                       (3 << 6)
+#       define SW_SMIO_INDEX_SHIFT                      6
+#       define LOW_VOLT_D2_ACPI                         (1 << 8)
+#       define LOW_VOLT_D3_ACPI                         (1 << 9)
+#       define VOLT_PWRMGT_EN                           (1 << 10)
+#       define BACKBIAS_PAD_EN                          (1 << 18)
+#       define BACKBIAS_VALUE                           (1 << 19)
+#       define DYN_SPREAD_SPECTRUM_EN                   (1 << 23)
+#       define AC_DC_SW                                 (1 << 24)
+
+#define SCLK_PWRMGT_CNTL                                  0x644
+#       define SCLK_PWRMGT_OFF                            (1 << 0)
+#       define SCLK_LOW_D1                                (1 << 1)
+#       define FIR_RESET                                  (1 << 4)
+#       define FIR_FORCE_TREND_SEL                        (1 << 5)
+#       define FIR_TREND_MODE                             (1 << 6)
+#       define DYN_GFX_CLK_OFF_EN                         (1 << 7)
+#       define GFX_CLK_FORCE_ON                           (1 << 8)
+#       define GFX_CLK_REQUEST_OFF                        (1 << 9)
+#       define GFX_CLK_FORCE_OFF                          (1 << 10)
+#       define GFX_CLK_OFF_ACPI_D1                        (1 << 11)
+#       define GFX_CLK_OFF_ACPI_D2                        (1 << 12)
+#       define GFX_CLK_OFF_ACPI_D3                        (1 << 13)
+#       define DYN_LIGHT_SLEEP_EN                         (1 << 14)
+#define	MCLK_PWRMGT_CNTL				0x648
+#       define DLL_SPEED(x)				((x) << 0)
+#       define DLL_SPEED_MASK				(0x1f << 0)
+#       define MPLL_PWRMGT_OFF                          (1 << 5)
+#       define DLL_READY                                (1 << 6)
+#       define MC_INT_CNTL                              (1 << 7)
+#       define MRDCKA0_PDNB                             (1 << 8)
+#       define MRDCKA1_PDNB                             (1 << 9)
+#       define MRDCKB0_PDNB                             (1 << 10)
+#       define MRDCKB1_PDNB                             (1 << 11)
+#       define MRDCKC0_PDNB                             (1 << 12)
+#       define MRDCKC1_PDNB                             (1 << 13)
+#       define MRDCKD0_PDNB                             (1 << 14)
+#       define MRDCKD1_PDNB                             (1 << 15)
+#       define MRDCKA0_RESET                            (1 << 16)
+#       define MRDCKA1_RESET                            (1 << 17)
+#       define MRDCKB0_RESET                            (1 << 18)
+#       define MRDCKB1_RESET                            (1 << 19)
+#       define MRDCKC0_RESET                            (1 << 20)
+#       define MRDCKC1_RESET                            (1 << 21)
+#       define MRDCKD0_RESET                            (1 << 22)
+#       define MRDCKD1_RESET                            (1 << 23)
+#       define DLL_READY_READ                           (1 << 24)
+#       define USE_DISPLAY_GAP                          (1 << 25)
+#       define USE_DISPLAY_URGENT_NORMAL                (1 << 26)
+#       define MPLL_TURNOFF_D2                          (1 << 28)
+#define	DLL_CNTL					0x64c
+#       define MRDCKA0_BYPASS                           (1 << 24)
+#       define MRDCKA1_BYPASS                           (1 << 25)
+#       define MRDCKB0_BYPASS                           (1 << 26)
+#       define MRDCKB1_BYPASS                           (1 << 27)
+#       define MRDCKC0_BYPASS                           (1 << 28)
+#       define MRDCKC1_BYPASS                           (1 << 29)
+#       define MRDCKD0_BYPASS                           (1 << 30)
+#       define MRDCKD1_BYPASS                           (1 << 31)
+
+#define TARGET_AND_CURRENT_PROFILE_INDEX                  0x66c
+#       define CURRENT_STATE_INDEX_MASK                   (0xf << 4)
+#       define CURRENT_STATE_INDEX_SHIFT                  4
+
+#define CG_AT                                           0x6d4
+#       define CG_R(x)					((x) << 0)
+#       define CG_R_MASK				(0xffff << 0)
+#       define CG_L(x)					((x) << 16)
+#       define CG_L_MASK				(0xffff << 16)
+
+#define	CG_BIF_REQ_AND_RSP				0x7f4
+#define		CG_CLIENT_REQ(x)			((x) << 0)
+#define		CG_CLIENT_REQ_MASK			(0xff << 0)
+#define		CG_CLIENT_REQ_SHIFT			0
+#define		CG_CLIENT_RESP(x)			((x) << 8)
+#define		CG_CLIENT_RESP_MASK			(0xff << 8)
+#define		CG_CLIENT_RESP_SHIFT			8
+#define		CLIENT_CG_REQ(x)			((x) << 16)
+#define		CLIENT_CG_REQ_MASK			(0xff << 16)
+#define		CLIENT_CG_REQ_SHIFT			16
+#define		CLIENT_CG_RESP(x)			((x) << 24)
+#define		CLIENT_CG_RESP_MASK			(0xff << 24)
+#define		CLIENT_CG_RESP_SHIFT			24
+
+#define	CG_SPLL_SPREAD_SPECTRUM				0x790
+#define		SSEN					(1 << 0)
+#define		CLK_S(x)				((x) << 4)
+#define		CLK_S_MASK				(0xfff << 4)
+#define		CLK_S_SHIFT				4
+#define	CG_SPLL_SPREAD_SPECTRUM_2			0x794
+#define		CLK_V(x)				((x) << 0)
+#define		CLK_V_MASK				(0x3ffffff << 0)
+#define		CLK_V_SHIFT				0
+
+#define SMC_SCRATCH0                                    0x81c
+
+#define	CG_SPLL_FUNC_CNTL_4				0x850
+
+#define	MPLL_SS1					0x85c
+#define		CLKV(x)					((x) << 0)
+#define		CLKV_MASK				(0x3ffffff << 0)
+#define	MPLL_SS2					0x860
+#define		CLKS(x)					((x) << 0)
+#define		CLKS_MASK				(0xfff << 0)
+
+#define	CG_CAC_CTRL					0x88c
+#define		TID_CNT(x)				((x) << 0)
+#define		TID_CNT_MASK				(0x3fff << 0)
+#define		TID_UNIT(x)				((x) << 14)
+#define		TID_UNIT_MASK				(0xf << 14)
+
+#define	CG_IND_ADDR					0x8f8
+#define	CG_IND_DATA					0x8fc
+/* CGIND regs */
+#define	CG_CGTT_LOCAL_0					0x00
+#define	CG_CGTT_LOCAL_1					0x01
+
+#define MC_CG_CONFIG                                    0x25bc
+#define         MCDW_WR_ENABLE                          (1 << 0)
+#define         MCDX_WR_ENABLE                          (1 << 1)
+#define         MCDY_WR_ENABLE                          (1 << 2)
+#define         MCDZ_WR_ENABLE                          (1 << 3)
+#define		MC_RD_ENABLE(x)				((x) << 4)
+#define		MC_RD_ENABLE_MASK			(3 << 4)
+#define		INDEX(x)				((x) << 6)
+#define		INDEX_MASK				(0xfff << 6)
+#define		INDEX_SHIFT				6
+
+#define	MC_ARB_CAC_CNTL					0x2750
+#define         ENABLE                                  (1 << 0)
+#define		READ_WEIGHT(x)				((x) << 1)
+#define		READ_WEIGHT_MASK			(0x3f << 1)
+#define		READ_WEIGHT_SHIFT			1
+#define		WRITE_WEIGHT(x)				((x) << 7)
+#define		WRITE_WEIGHT_MASK			(0x3f << 7)
+#define		WRITE_WEIGHT_SHIFT			7
+#define         ALLOW_OVERFLOW                          (1 << 13)
+
+#define	MC_ARB_DRAM_TIMING				0x2774
+#define	MC_ARB_DRAM_TIMING2				0x2778
+
+#define	MC_ARB_RFSH_RATE				0x27b0
+#define		POWERMODE0(x)				((x) << 0)
+#define		POWERMODE0_MASK				(0xff << 0)
+#define		POWERMODE0_SHIFT			0
+#define		POWERMODE1(x)				((x) << 8)
+#define		POWERMODE1_MASK				(0xff << 8)
+#define		POWERMODE1_SHIFT			8
+#define		POWERMODE2(x)				((x) << 16)
+#define		POWERMODE2_MASK				(0xff << 16)
+#define		POWERMODE2_SHIFT			16
+#define		POWERMODE3(x)				((x) << 24)
+#define		POWERMODE3_MASK				(0xff << 24)
+#define		POWERMODE3_SHIFT			24
+
+#define MC_ARB_CG                                       0x27e8
+#define		CG_ARB_REQ(x)				((x) << 0)
+#define		CG_ARB_REQ_MASK				(0xff << 0)
+#define		CG_ARB_REQ_SHIFT			0
+#define		CG_ARB_RESP(x)				((x) << 8)
+#define		CG_ARB_RESP_MASK			(0xff << 8)
+#define		CG_ARB_RESP_SHIFT			8
+#define		ARB_CG_REQ(x)				((x) << 16)
+#define		ARB_CG_REQ_MASK				(0xff << 16)
+#define		ARB_CG_REQ_SHIFT			16
+#define		ARB_CG_RESP(x)				((x) << 24)
+#define		ARB_CG_RESP_MASK			(0xff << 24)
+#define		ARB_CG_RESP_SHIFT			24
+
+#define	MC_ARB_DRAM_TIMING_1				0x27f0
+#define	MC_ARB_DRAM_TIMING_2				0x27f4
+#define	MC_ARB_DRAM_TIMING_3				0x27f8
+#define	MC_ARB_DRAM_TIMING2_1				0x27fc
+#define	MC_ARB_DRAM_TIMING2_2				0x2800
+#define	MC_ARB_DRAM_TIMING2_3				0x2804
+#define MC_ARB_BURST_TIME                               0x2808
+#define		STATE0(x)				((x) << 0)
+#define		STATE0_MASK				(0x1f << 0)
+#define		STATE0_SHIFT				0
+#define		STATE1(x)				((x) << 5)
+#define		STATE1_MASK				(0x1f << 5)
+#define		STATE1_SHIFT				5
+#define		STATE2(x)				((x) << 10)
+#define		STATE2_MASK				(0x1f << 10)
+#define		STATE2_SHIFT				10
+#define		STATE3(x)				((x) << 15)
+#define		STATE3_MASK				(0x1f << 15)
+#define		STATE3_SHIFT				15
+
+#define MC_CG_DATAPORT                                  0x2884
+
+#define MC_SEQ_RAS_TIMING                               0x28a0
+#define MC_SEQ_CAS_TIMING                               0x28a4
+#define MC_SEQ_MISC_TIMING                              0x28a8
+#define MC_SEQ_MISC_TIMING2                             0x28ac
+#define MC_SEQ_PMG_TIMING                               0x28b0
+#define MC_SEQ_RD_CTL_D0                                0x28b4
+#define MC_SEQ_RD_CTL_D1                                0x28b8
+#define MC_SEQ_WR_CTL_D0                                0x28bc
+#define MC_SEQ_WR_CTL_D1                                0x28c0
+
+#define MC_SEQ_MISC0                                    0x2a00
+#define         MC_SEQ_MISC0_GDDR5_SHIFT                28
+#define         MC_SEQ_MISC0_GDDR5_MASK                 0xf0000000
+#define         MC_SEQ_MISC0_GDDR5_VALUE                5
+#define MC_SEQ_MISC1                                    0x2a04
+#define MC_SEQ_RESERVE_M                                0x2a08
+#define MC_PMG_CMD_EMRS                                 0x2a0c
+
+#define MC_SEQ_MISC3                                    0x2a2c
+
+#define MC_SEQ_MISC5                                    0x2a54
+#define MC_SEQ_MISC6                                    0x2a58
+
+#define MC_SEQ_MISC7                                    0x2a64
+
+#define MC_SEQ_RAS_TIMING_LP                            0x2a6c
+#define MC_SEQ_CAS_TIMING_LP                            0x2a70
+#define MC_SEQ_MISC_TIMING_LP                           0x2a74
+#define MC_SEQ_MISC_TIMING2_LP                          0x2a78
+#define MC_SEQ_WR_CTL_D0_LP                             0x2a7c
+#define MC_SEQ_WR_CTL_D1_LP                             0x2a80
+#define MC_SEQ_PMG_CMD_EMRS_LP                          0x2a84
+#define MC_SEQ_PMG_CMD_MRS_LP                           0x2a88
+
+#define MC_PMG_CMD_MRS                                  0x2aac
+
+#define MC_SEQ_RD_CTL_D0_LP                             0x2b1c
+#define MC_SEQ_RD_CTL_D1_LP                             0x2b20
+
+#define MC_PMG_CMD_MRS1                                 0x2b44
+#define MC_SEQ_PMG_CMD_MRS1_LP                          0x2b48
+#define MC_SEQ_PMG_TIMING_LP                            0x2b4c
+
+#define MC_PMG_CMD_MRS2                                 0x2b5c
+#define MC_SEQ_PMG_CMD_MRS2_LP                          0x2b60
+
+#define	LB_SYNC_RESET_SEL				0x6b28
+#define		LB_SYNC_RESET_SEL_MASK			(3 << 0)
+#define		LB_SYNC_RESET_SEL_SHIFT			0
+
+#define	DC_STUTTER_CNTL					0x6b30
+#define		DC_STUTTER_ENABLE_A			(1 << 0)
+#define		DC_STUTTER_ENABLE_B			(1 << 1)
+
+#define SQ_CAC_THRESHOLD                                0x8e4c
+#define		VSP(x)					((x) << 0)
+#define		VSP_MASK				(0xff << 0)
+#define		VSP_SHIFT				0
+#define		VSP0(x)					((x) << 8)
+#define		VSP0_MASK				(0xff << 8)
+#define		VSP0_SHIFT				8
+#define		GPR(x)					((x) << 16)
+#define		GPR_MASK				(0xff << 16)
+#define		GPR_SHIFT				16
+
+#define SQ_POWER_THROTTLE                               0x8e58
+#define		MIN_POWER(x)				((x) << 0)
+#define		MIN_POWER_MASK				(0x3fff << 0)
+#define		MIN_POWER_SHIFT				0
+#define		MAX_POWER(x)				((x) << 16)
+#define		MAX_POWER_MASK				(0x3fff << 16)
+#define		MAX_POWER_SHIFT				0
+#define SQ_POWER_THROTTLE2                              0x8e5c
+#define		MAX_POWER_DELTA(x)			((x) << 0)
+#define		MAX_POWER_DELTA_MASK			(0x3fff << 0)
+#define		MAX_POWER_DELTA_SHIFT			0
+#define		STI_SIZE(x)				((x) << 16)
+#define		STI_SIZE_MASK				(0x3ff << 16)
+#define		STI_SIZE_SHIFT				16
+#define		LTI_RATIO(x)				((x) << 27)
+#define		LTI_RATIO_MASK				(0xf << 27)
+#define		LTI_RATIO_SHIFT				27
+
+/* CG indirect registers */
+#define CG_CAC_REGION_1_WEIGHT_0                        0x83
+#define		WEIGHT_TCP_SIG0(x)			((x) << 0)
+#define		WEIGHT_TCP_SIG0_MASK			(0x3f << 0)
+#define		WEIGHT_TCP_SIG0_SHIFT			0
+#define		WEIGHT_TCP_SIG1(x)			((x) << 6)
+#define		WEIGHT_TCP_SIG1_MASK			(0x3f << 6)
+#define		WEIGHT_TCP_SIG1_SHIFT			6
+#define		WEIGHT_TA_SIG(x)			((x) << 12)
+#define		WEIGHT_TA_SIG_MASK			(0x3f << 12)
+#define		WEIGHT_TA_SIG_SHIFT			12
+#define CG_CAC_REGION_1_WEIGHT_1                        0x84
+#define		WEIGHT_TCC_EN0(x)			((x) << 0)
+#define		WEIGHT_TCC_EN0_MASK			(0x3f << 0)
+#define		WEIGHT_TCC_EN0_SHIFT			0
+#define		WEIGHT_TCC_EN1(x)			((x) << 6)
+#define		WEIGHT_TCC_EN1_MASK			(0x3f << 6)
+#define		WEIGHT_TCC_EN1_SHIFT			6
+#define		WEIGHT_TCC_EN2(x)			((x) << 12)
+#define		WEIGHT_TCC_EN2_MASK			(0x3f << 12)
+#define		WEIGHT_TCC_EN2_SHIFT			12
+#define		WEIGHT_TCC_EN3(x)			((x) << 18)
+#define		WEIGHT_TCC_EN3_MASK			(0x3f << 18)
+#define		WEIGHT_TCC_EN3_SHIFT			18
+#define CG_CAC_REGION_2_WEIGHT_0                        0x85
+#define		WEIGHT_CB_EN0(x)			((x) << 0)
+#define		WEIGHT_CB_EN0_MASK			(0x3f << 0)
+#define		WEIGHT_CB_EN0_SHIFT			0
+#define		WEIGHT_CB_EN1(x)			((x) << 6)
+#define		WEIGHT_CB_EN1_MASK			(0x3f << 6)
+#define		WEIGHT_CB_EN1_SHIFT			6
+#define		WEIGHT_CB_EN2(x)			((x) << 12)
+#define		WEIGHT_CB_EN2_MASK			(0x3f << 12)
+#define		WEIGHT_CB_EN2_SHIFT			12
+#define		WEIGHT_CB_EN3(x)			((x) << 18)
+#define		WEIGHT_CB_EN3_MASK			(0x3f << 18)
+#define		WEIGHT_CB_EN3_SHIFT			18
+#define CG_CAC_REGION_2_WEIGHT_1                        0x86
+#define		WEIGHT_DB_SIG0(x)			((x) << 0)
+#define		WEIGHT_DB_SIG0_MASK			(0x3f << 0)
+#define		WEIGHT_DB_SIG0_SHIFT			0
+#define		WEIGHT_DB_SIG1(x)			((x) << 6)
+#define		WEIGHT_DB_SIG1_MASK			(0x3f << 6)
+#define		WEIGHT_DB_SIG1_SHIFT			6
+#define		WEIGHT_DB_SIG2(x)			((x) << 12)
+#define		WEIGHT_DB_SIG2_MASK			(0x3f << 12)
+#define		WEIGHT_DB_SIG2_SHIFT			12
+#define		WEIGHT_DB_SIG3(x)			((x) << 18)
+#define		WEIGHT_DB_SIG3_MASK			(0x3f << 18)
+#define		WEIGHT_DB_SIG3_SHIFT			18
+#define CG_CAC_REGION_2_WEIGHT_2                        0x87
+#define		WEIGHT_SXM_SIG0(x)			((x) << 0)
+#define		WEIGHT_SXM_SIG0_MASK			(0x3f << 0)
+#define		WEIGHT_SXM_SIG0_SHIFT			0
+#define		WEIGHT_SXM_SIG1(x)			((x) << 6)
+#define		WEIGHT_SXM_SIG1_MASK			(0x3f << 6)
+#define		WEIGHT_SXM_SIG1_SHIFT			6
+#define		WEIGHT_SXM_SIG2(x)			((x) << 12)
+#define		WEIGHT_SXM_SIG2_MASK			(0x3f << 12)
+#define		WEIGHT_SXM_SIG2_SHIFT			12
+#define		WEIGHT_SXS_SIG0(x)			((x) << 18)
+#define		WEIGHT_SXS_SIG0_MASK			(0x3f << 18)
+#define		WEIGHT_SXS_SIG0_SHIFT			18
+#define		WEIGHT_SXS_SIG1(x)			((x) << 24)
+#define		WEIGHT_SXS_SIG1_MASK			(0x3f << 24)
+#define		WEIGHT_SXS_SIG1_SHIFT			24
+#define CG_CAC_REGION_3_WEIGHT_0                        0x88
+#define		WEIGHT_XBR_0(x)				((x) << 0)
+#define		WEIGHT_XBR_0_MASK			(0x3f << 0)
+#define		WEIGHT_XBR_0_SHIFT			0
+#define		WEIGHT_XBR_1(x)				((x) << 6)
+#define		WEIGHT_XBR_1_MASK			(0x3f << 6)
+#define		WEIGHT_XBR_1_SHIFT			6
+#define		WEIGHT_XBR_2(x)				((x) << 12)
+#define		WEIGHT_XBR_2_MASK			(0x3f << 12)
+#define		WEIGHT_XBR_2_SHIFT			12
+#define		WEIGHT_SPI_SIG0(x)			((x) << 18)
+#define		WEIGHT_SPI_SIG0_MASK			(0x3f << 18)
+#define		WEIGHT_SPI_SIG0_SHIFT			18
+#define CG_CAC_REGION_3_WEIGHT_1                        0x89
+#define		WEIGHT_SPI_SIG1(x)			((x) << 0)
+#define		WEIGHT_SPI_SIG1_MASK			(0x3f << 0)
+#define		WEIGHT_SPI_SIG1_SHIFT			0
+#define		WEIGHT_SPI_SIG2(x)			((x) << 6)
+#define		WEIGHT_SPI_SIG2_MASK			(0x3f << 6)
+#define		WEIGHT_SPI_SIG2_SHIFT			6
+#define		WEIGHT_SPI_SIG3(x)			((x) << 12)
+#define		WEIGHT_SPI_SIG3_MASK			(0x3f << 12)
+#define		WEIGHT_SPI_SIG3_SHIFT			12
+#define		WEIGHT_SPI_SIG4(x)			((x) << 18)
+#define		WEIGHT_SPI_SIG4_MASK			(0x3f << 18)
+#define		WEIGHT_SPI_SIG4_SHIFT			18
+#define		WEIGHT_SPI_SIG5(x)			((x) << 24)
+#define		WEIGHT_SPI_SIG5_MASK			(0x3f << 24)
+#define		WEIGHT_SPI_SIG5_SHIFT			24
+#define CG_CAC_REGION_4_WEIGHT_0                        0x8a
+#define		WEIGHT_LDS_SIG0(x)			((x) << 0)
+#define		WEIGHT_LDS_SIG0_MASK			(0x3f << 0)
+#define		WEIGHT_LDS_SIG0_SHIFT			0
+#define		WEIGHT_LDS_SIG1(x)			((x) << 6)
+#define		WEIGHT_LDS_SIG1_MASK			(0x3f << 6)
+#define		WEIGHT_LDS_SIG1_SHIFT			6
+#define		WEIGHT_SC(x)				((x) << 24)
+#define		WEIGHT_SC_MASK				(0x3f << 24)
+#define		WEIGHT_SC_SHIFT				24
+#define CG_CAC_REGION_4_WEIGHT_1                        0x8b
+#define		WEIGHT_BIF(x)				((x) << 0)
+#define		WEIGHT_BIF_MASK				(0x3f << 0)
+#define		WEIGHT_BIF_SHIFT			0
+#define		WEIGHT_CP(x)				((x) << 6)
+#define		WEIGHT_CP_MASK				(0x3f << 6)
+#define		WEIGHT_CP_SHIFT				6
+#define		WEIGHT_PA_SIG0(x)			((x) << 12)
+#define		WEIGHT_PA_SIG0_MASK			(0x3f << 12)
+#define		WEIGHT_PA_SIG0_SHIFT			12
+#define		WEIGHT_PA_SIG1(x)			((x) << 18)
+#define		WEIGHT_PA_SIG1_MASK			(0x3f << 18)
+#define		WEIGHT_PA_SIG1_SHIFT			18
+#define		WEIGHT_VGT_SIG0(x)			((x) << 24)
+#define		WEIGHT_VGT_SIG0_MASK			(0x3f << 24)
+#define		WEIGHT_VGT_SIG0_SHIFT			24
+#define CG_CAC_REGION_4_WEIGHT_2                        0x8c
+#define		WEIGHT_VGT_SIG1(x)			((x) << 0)
+#define		WEIGHT_VGT_SIG1_MASK			(0x3f << 0)
+#define		WEIGHT_VGT_SIG1_SHIFT			0
+#define		WEIGHT_VGT_SIG2(x)			((x) << 6)
+#define		WEIGHT_VGT_SIG2_MASK			(0x3f << 6)
+#define		WEIGHT_VGT_SIG2_SHIFT			6
+#define		WEIGHT_DC_SIG0(x)			((x) << 12)
+#define		WEIGHT_DC_SIG0_MASK			(0x3f << 12)
+#define		WEIGHT_DC_SIG0_SHIFT			12
+#define		WEIGHT_DC_SIG1(x)			((x) << 18)
+#define		WEIGHT_DC_SIG1_MASK			(0x3f << 18)
+#define		WEIGHT_DC_SIG1_SHIFT			18
+#define		WEIGHT_DC_SIG2(x)			((x) << 24)
+#define		WEIGHT_DC_SIG2_MASK			(0x3f << 24)
+#define		WEIGHT_DC_SIG2_SHIFT			24
+#define CG_CAC_REGION_4_WEIGHT_3                        0x8d
+#define		WEIGHT_DC_SIG3(x)			((x) << 0)
+#define		WEIGHT_DC_SIG3_MASK			(0x3f << 0)
+#define		WEIGHT_DC_SIG3_SHIFT			0
+#define		WEIGHT_UVD_SIG0(x)			((x) << 6)
+#define		WEIGHT_UVD_SIG0_MASK			(0x3f << 6)
+#define		WEIGHT_UVD_SIG0_SHIFT			6
+#define		WEIGHT_UVD_SIG1(x)			((x) << 12)
+#define		WEIGHT_UVD_SIG1_MASK			(0x3f << 12)
+#define		WEIGHT_UVD_SIG1_SHIFT			12
+#define		WEIGHT_SPARE0(x)			((x) << 18)
+#define		WEIGHT_SPARE0_MASK			(0x3f << 18)
+#define		WEIGHT_SPARE0_SHIFT			18
+#define		WEIGHT_SPARE1(x)			((x) << 24)
+#define		WEIGHT_SPARE1_MASK			(0x3f << 24)
+#define		WEIGHT_SPARE1_SHIFT			24
+#define CG_CAC_REGION_5_WEIGHT_0                        0x8e
+#define		WEIGHT_SQ_VSP(x)			((x) << 0)
+#define		WEIGHT_SQ_VSP_MASK			(0x3fff << 0)
+#define		WEIGHT_SQ_VSP_SHIFT			0
+#define		WEIGHT_SQ_VSP0(x)			((x) << 14)
+#define		WEIGHT_SQ_VSP0_MASK			(0x3fff << 14)
+#define		WEIGHT_SQ_VSP0_SHIFT			14
+#define CG_CAC_REGION_4_OVERRIDE_4                      0xab
+#define		OVR_MODE_SPARE_0(x)			((x) << 16)
+#define		OVR_MODE_SPARE_0_MASK			(0x1 << 16)
+#define		OVR_MODE_SPARE_0_SHIFT			16
+#define		OVR_VAL_SPARE_0(x)			((x) << 17)
+#define		OVR_VAL_SPARE_0_MASK			(0x1 << 17)
+#define		OVR_VAL_SPARE_0_SHIFT			17
+#define		OVR_MODE_SPARE_1(x)			((x) << 18)
+#define		OVR_MODE_SPARE_1_MASK			(0x3f << 18)
+#define		OVR_MODE_SPARE_1_SHIFT			18
+#define		OVR_VAL_SPARE_1(x)			((x) << 19)
+#define		OVR_VAL_SPARE_1_MASK			(0x3f << 19)
+#define		OVR_VAL_SPARE_1_SHIFT			19
+#define CG_CAC_REGION_5_WEIGHT_1                        0xb7
+#define		WEIGHT_SQ_GPR(x)			((x) << 0)
+#define		WEIGHT_SQ_GPR_MASK			(0x3fff << 0)
+#define		WEIGHT_SQ_GPR_SHIFT			0
+#define		WEIGHT_SQ_LDS(x)			((x) << 14)
+#define		WEIGHT_SQ_LDS_MASK			(0x3fff << 14)
+#define		WEIGHT_SQ_LDS_SHIFT			14
+
+/* PCIE link stuff */
+#define PCIE_LC_TRAINING_CNTL                             0xa1 /* PCIE_P */
+#define PCIE_LC_LINK_WIDTH_CNTL                           0xa2 /* PCIE_P */
+#       define LC_LINK_WIDTH_SHIFT                        0
+#       define LC_LINK_WIDTH_MASK                         0x7
+#       define LC_LINK_WIDTH_X0                           0
+#       define LC_LINK_WIDTH_X1                           1
+#       define LC_LINK_WIDTH_X2                           2
+#       define LC_LINK_WIDTH_X4                           3
+#       define LC_LINK_WIDTH_X8                           4
+#       define LC_LINK_WIDTH_X16                          6
+#       define LC_LINK_WIDTH_RD_SHIFT                     4
+#       define LC_LINK_WIDTH_RD_MASK                      0x70
+#       define LC_RECONFIG_ARC_MISSING_ESCAPE             (1 << 7)
+#       define LC_RECONFIG_NOW                            (1 << 8)
+#       define LC_RENEGOTIATION_SUPPORT                   (1 << 9)
+#       define LC_RENEGOTIATE_EN                          (1 << 10)
+#       define LC_SHORT_RECONFIG_EN                       (1 << 11)
+#       define LC_UPCONFIGURE_SUPPORT                     (1 << 12)
+#       define LC_UPCONFIGURE_DIS                         (1 << 13)
+#define PCIE_LC_SPEED_CNTL                                0xa4 /* PCIE_P */
+#       define LC_GEN2_EN_STRAP                           (1 << 0)
+#       define LC_TARGET_LINK_SPEED_OVERRIDE_EN           (1 << 1)
+#       define LC_FORCE_EN_HW_SPEED_CHANGE                (1 << 5)
+#       define LC_FORCE_DIS_HW_SPEED_CHANGE               (1 << 6)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK      (0x3 << 8)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT     3
+#       define LC_CURRENT_DATA_RATE                       (1 << 11)
+#       define LC_HW_VOLTAGE_IF_CONTROL(x)                ((x) << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_MASK              (3 << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_SHIFT             12
+#       define LC_VOLTAGE_TIMER_SEL_MASK                  (0xf << 14)
+#       define LC_CLR_FAILED_SPD_CHANGE_CNT               (1 << 21)
+#       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 23)
+#       define LC_OTHER_SIDE_SUPPORTS_GEN2                (1 << 24)
+#define MM_CFGREGS_CNTL                                   0x544c
+#       define MM_WR_TO_CFG_EN                            (1 << 3)
+#define LINK_CNTL2                                        0x88 /* F0 */
+#       define TARGET_LINK_SPEED_MASK                     (0xf << 0)
+#       define SELECTABLE_DEEMPHASIS                      (1 << 6)
+
 /*
  * UVD
  */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ni_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ni_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ni_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ni_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,4352 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "drmP.h"
+#include "radeon.h"
+#include "nid.h"
+#include "r600_dpm.h"
+#include "ni_dpm.h"
+#include "atom.h"
+#include <linux/math64.h>
+#include <linux/seq_file.h>
+
+#define MC_CG_ARB_FREQ_F0           0x0a
+#define MC_CG_ARB_FREQ_F1           0x0b
+#define MC_CG_ARB_FREQ_F2           0x0c
+#define MC_CG_ARB_FREQ_F3           0x0d
+
+#define SMC_RAM_END 0xC000
+
+static const struct ni_cac_weights cac_weights_cayman_xt =
+{
+	0x15,
+	0x2,
+	0x19,
+	0x2,
+	0x8,
+	0x14,
+	0x2,
+	0x16,
+	0xE,
+	0x17,
+	0x13,
+	0x2B,
+	0x10,
+	0x7,
+	0x5,
+	0x5,
+	0x5,
+	0x2,
+	0x3,
+	0x9,
+	0x10,
+	0x10,
+	0x2B,
+	0xA,
+	0x9,
+	0x4,
+	0xD,
+	0xD,
+	0x3E,
+	0x18,
+	0x14,
+	0,
+	0x3,
+	0x3,
+	0x5,
+	0,
+	0x2,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0x1CC,
+	0,
+	0x164,
+	1,
+	1,
+	1,
+	1,
+	12,
+	12,
+	12,
+	0x12,
+	0x1F,
+	132,
+	5,
+	7,
+	0,
+	{ 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0 },
+	true
+};
+
+static const struct ni_cac_weights cac_weights_cayman_pro =
+{
+	0x16,
+	0x4,
+	0x10,
+	0x2,
+	0xA,
+	0x16,
+	0x2,
+	0x18,
+	0x10,
+	0x1A,
+	0x16,
+	0x2D,
+	0x12,
+	0xA,
+	0x6,
+	0x6,
+	0x6,
+	0x2,
+	0x4,
+	0xB,
+	0x11,
+	0x11,
+	0x2D,
+	0xC,
+	0xC,
+	0x7,
+	0x10,
+	0x10,
+	0x3F,
+	0x1A,
+	0x16,
+	0,
+	0x7,
+	0x4,
+	0x6,
+	1,
+	0x2,
+	0x1,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0x30,
+	0,
+	0x1CF,
+	0,
+	0x166,
+	1,
+	1,
+	1,
+	1,
+	12,
+	12,
+	12,
+	0x15,
+	0x1F,
+	132,
+	6,
+	6,
+	0,
+	{ 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0 },
+	true
+};
+
+static const struct ni_cac_weights cac_weights_cayman_le =
+{
+	0x7,
+	0xE,
+	0x1,
+	0xA,
+	0x1,
+	0x3F,
+	0x2,
+	0x18,
+	0x10,
+	0x1A,
+	0x1,
+	0x3F,
+	0x1,
+	0xE,
+	0x6,
+	0x6,
+	0x6,
+	0x2,
+	0x4,
+	0x9,
+	0x1A,
+	0x1A,
+	0x2C,
+	0xA,
+	0x11,
+	0x8,
+	0x19,
+	0x19,
+	0x1,
+	0x1,
+	0x1A,
+	0,
+	0x8,
+	0x5,
+	0x8,
+	0x1,
+	0x3,
+	0x1,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0x38,
+	0x38,
+	0x239,
+	0x3,
+	0x18A,
+	1,
+	1,
+	1,
+	1,
+	12,
+	12,
+	12,
+	0x15,
+	0x22,
+	132,
+	6,
+	6,
+	0,
+	{ 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0 },
+	true
+};
+
+#define NISLANDS_MGCG_SEQUENCE  300
+
+static const u32 cayman_cgcg_cgls_default[] =
+{
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff
+};
+#define CAYMAN_CGCG_CGLS_DEFAULT_LENGTH sizeof(cayman_cgcg_cgls_default) / (3 * sizeof(u32))
+
+static const u32 cayman_cgcg_cgls_disable[] =
+{
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x00000644, 0x000f7902, 0x001f4180,
+	0x00000644, 0x000f3802, 0x001f4180
+};
+#define CAYMAN_CGCG_CGLS_DISABLE_LENGTH sizeof(cayman_cgcg_cgls_disable) / (3 * sizeof(u32))
+
+static const u32 cayman_cgcg_cgls_enable[] =
+{
+	0x00000644, 0x000f7882, 0x001f4080,
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000020, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000021, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000022, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000023, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000024, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000025, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000026, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000027, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000028, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000029, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000002a, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x0000002b, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff
+};
+#define CAYMAN_CGCG_CGLS_ENABLE_LENGTH  sizeof(cayman_cgcg_cgls_enable) / (3 * sizeof(u32))
+
+static const u32 cayman_mgcg_default[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x00003fc4, 0xc0000000, 0xffffffff,
+	0x00005448, 0x00000100, 0xffffffff,
+	0x000055e4, 0x00000100, 0xffffffff,
+	0x0000160c, 0x00000100, 0xffffffff,
+	0x00008984, 0x06000100, 0xffffffff,
+	0x0000c164, 0x00000100, 0xffffffff,
+	0x00008a18, 0x00000100, 0xffffffff,
+	0x0000897c, 0x06000100, 0xffffffff,
+	0x00008b28, 0x00000100, 0xffffffff,
+	0x00009144, 0x00800200, 0xffffffff,
+	0x00009a60, 0x00000100, 0xffffffff,
+	0x00009868, 0x00000100, 0xffffffff,
+	0x00008d58, 0x00000100, 0xffffffff,
+	0x00009510, 0x00000100, 0xffffffff,
+	0x0000949c, 0x00000100, 0xffffffff,
+	0x00009654, 0x00000100, 0xffffffff,
+	0x00009030, 0x00000100, 0xffffffff,
+	0x00009034, 0x00000100, 0xffffffff,
+	0x00009038, 0x00000100, 0xffffffff,
+	0x0000903c, 0x00000100, 0xffffffff,
+	0x00009040, 0x00000100, 0xffffffff,
+	0x0000a200, 0x00000100, 0xffffffff,
+	0x0000a204, 0x00000100, 0xffffffff,
+	0x0000a208, 0x00000100, 0xffffffff,
+	0x0000a20c, 0x00000100, 0xffffffff,
+	0x00009744, 0x00000100, 0xffffffff,
+	0x00003f80, 0x00000100, 0xffffffff,
+	0x0000a210, 0x00000100, 0xffffffff,
+	0x0000a214, 0x00000100, 0xffffffff,
+	0x000004d8, 0x00000100, 0xffffffff,
+	0x00009664, 0x00000100, 0xffffffff,
+	0x00009698, 0x00000100, 0xffffffff,
+	0x000004d4, 0x00000200, 0xffffffff,
+	0x000004d0, 0x00000000, 0xffffffff,
+	0x000030cc, 0x00000104, 0xffffffff,
+	0x0000d0c0, 0x00000100, 0xffffffff,
+	0x0000d8c0, 0x00000100, 0xffffffff,
+	0x0000802c, 0x40000000, 0xffffffff,
+	0x00003fc4, 0x40000000, 0xffffffff,
+	0x0000915c, 0x00010000, 0xffffffff,
+	0x00009160, 0x00030002, 0xffffffff,
+	0x00009164, 0x00050004, 0xffffffff,
+	0x00009168, 0x00070006, 0xffffffff,
+	0x00009178, 0x00070000, 0xffffffff,
+	0x0000917c, 0x00030002, 0xffffffff,
+	0x00009180, 0x00050004, 0xffffffff,
+	0x0000918c, 0x00010006, 0xffffffff,
+	0x00009190, 0x00090008, 0xffffffff,
+	0x00009194, 0x00070000, 0xffffffff,
+	0x00009198, 0x00030002, 0xffffffff,
+	0x0000919c, 0x00050004, 0xffffffff,
+	0x000091a8, 0x00010006, 0xffffffff,
+	0x000091ac, 0x00090008, 0xffffffff,
+	0x000091b0, 0x00070000, 0xffffffff,
+	0x000091b4, 0x00030002, 0xffffffff,
+	0x000091b8, 0x00050004, 0xffffffff,
+	0x000091c4, 0x00010006, 0xffffffff,
+	0x000091c8, 0x00090008, 0xffffffff,
+	0x000091cc, 0x00070000, 0xffffffff,
+	0x000091d0, 0x00030002, 0xffffffff,
+	0x000091d4, 0x00050004, 0xffffffff,
+	0x000091e0, 0x00010006, 0xffffffff,
+	0x000091e4, 0x00090008, 0xffffffff,
+	0x000091e8, 0x00000000, 0xffffffff,
+	0x000091ec, 0x00070000, 0xffffffff,
+	0x000091f0, 0x00030002, 0xffffffff,
+	0x000091f4, 0x00050004, 0xffffffff,
+	0x00009200, 0x00010006, 0xffffffff,
+	0x00009204, 0x00090008, 0xffffffff,
+	0x00009208, 0x00070000, 0xffffffff,
+	0x0000920c, 0x00030002, 0xffffffff,
+	0x00009210, 0x00050004, 0xffffffff,
+	0x0000921c, 0x00010006, 0xffffffff,
+	0x00009220, 0x00090008, 0xffffffff,
+	0x00009224, 0x00070000, 0xffffffff,
+	0x00009228, 0x00030002, 0xffffffff,
+	0x0000922c, 0x00050004, 0xffffffff,
+	0x00009238, 0x00010006, 0xffffffff,
+	0x0000923c, 0x00090008, 0xffffffff,
+	0x00009240, 0x00070000, 0xffffffff,
+	0x00009244, 0x00030002, 0xffffffff,
+	0x00009248, 0x00050004, 0xffffffff,
+	0x00009254, 0x00010006, 0xffffffff,
+	0x00009258, 0x00090008, 0xffffffff,
+	0x0000925c, 0x00070000, 0xffffffff,
+	0x00009260, 0x00030002, 0xffffffff,
+	0x00009264, 0x00050004, 0xffffffff,
+	0x00009270, 0x00010006, 0xffffffff,
+	0x00009274, 0x00090008, 0xffffffff,
+	0x00009278, 0x00070000, 0xffffffff,
+	0x0000927c, 0x00030002, 0xffffffff,
+	0x00009280, 0x00050004, 0xffffffff,
+	0x0000928c, 0x00010006, 0xffffffff,
+	0x00009290, 0x00090008, 0xffffffff,
+	0x000092a8, 0x00070000, 0xffffffff,
+	0x000092ac, 0x00030002, 0xffffffff,
+	0x000092b0, 0x00050004, 0xffffffff,
+	0x000092bc, 0x00010006, 0xffffffff,
+	0x000092c0, 0x00090008, 0xffffffff,
+	0x000092c4, 0x00070000, 0xffffffff,
+	0x000092c8, 0x00030002, 0xffffffff,
+	0x000092cc, 0x00050004, 0xffffffff,
+	0x000092d8, 0x00010006, 0xffffffff,
+	0x000092dc, 0x00090008, 0xffffffff,
+	0x00009294, 0x00000000, 0xffffffff,
+	0x0000802c, 0x40010000, 0xffffffff,
+	0x00003fc4, 0x40010000, 0xffffffff,
+	0x0000915c, 0x00010000, 0xffffffff,
+	0x00009160, 0x00030002, 0xffffffff,
+	0x00009164, 0x00050004, 0xffffffff,
+	0x00009168, 0x00070006, 0xffffffff,
+	0x00009178, 0x00070000, 0xffffffff,
+	0x0000917c, 0x00030002, 0xffffffff,
+	0x00009180, 0x00050004, 0xffffffff,
+	0x0000918c, 0x00010006, 0xffffffff,
+	0x00009190, 0x00090008, 0xffffffff,
+	0x00009194, 0x00070000, 0xffffffff,
+	0x00009198, 0x00030002, 0xffffffff,
+	0x0000919c, 0x00050004, 0xffffffff,
+	0x000091a8, 0x00010006, 0xffffffff,
+	0x000091ac, 0x00090008, 0xffffffff,
+	0x000091b0, 0x00070000, 0xffffffff,
+	0x000091b4, 0x00030002, 0xffffffff,
+	0x000091b8, 0x00050004, 0xffffffff,
+	0x000091c4, 0x00010006, 0xffffffff,
+	0x000091c8, 0x00090008, 0xffffffff,
+	0x000091cc, 0x00070000, 0xffffffff,
+	0x000091d0, 0x00030002, 0xffffffff,
+	0x000091d4, 0x00050004, 0xffffffff,
+	0x000091e0, 0x00010006, 0xffffffff,
+	0x000091e4, 0x00090008, 0xffffffff,
+	0x000091e8, 0x00000000, 0xffffffff,
+	0x000091ec, 0x00070000, 0xffffffff,
+	0x000091f0, 0x00030002, 0xffffffff,
+	0x000091f4, 0x00050004, 0xffffffff,
+	0x00009200, 0x00010006, 0xffffffff,
+	0x00009204, 0x00090008, 0xffffffff,
+	0x00009208, 0x00070000, 0xffffffff,
+	0x0000920c, 0x00030002, 0xffffffff,
+	0x00009210, 0x00050004, 0xffffffff,
+	0x0000921c, 0x00010006, 0xffffffff,
+	0x00009220, 0x00090008, 0xffffffff,
+	0x00009224, 0x00070000, 0xffffffff,
+	0x00009228, 0x00030002, 0xffffffff,
+	0x0000922c, 0x00050004, 0xffffffff,
+	0x00009238, 0x00010006, 0xffffffff,
+	0x0000923c, 0x00090008, 0xffffffff,
+	0x00009240, 0x00070000, 0xffffffff,
+	0x00009244, 0x00030002, 0xffffffff,
+	0x00009248, 0x00050004, 0xffffffff,
+	0x00009254, 0x00010006, 0xffffffff,
+	0x00009258, 0x00090008, 0xffffffff,
+	0x0000925c, 0x00070000, 0xffffffff,
+	0x00009260, 0x00030002, 0xffffffff,
+	0x00009264, 0x00050004, 0xffffffff,
+	0x00009270, 0x00010006, 0xffffffff,
+	0x00009274, 0x00090008, 0xffffffff,
+	0x00009278, 0x00070000, 0xffffffff,
+	0x0000927c, 0x00030002, 0xffffffff,
+	0x00009280, 0x00050004, 0xffffffff,
+	0x0000928c, 0x00010006, 0xffffffff,
+	0x00009290, 0x00090008, 0xffffffff,
+	0x000092a8, 0x00070000, 0xffffffff,
+	0x000092ac, 0x00030002, 0xffffffff,
+	0x000092b0, 0x00050004, 0xffffffff,
+	0x000092bc, 0x00010006, 0xffffffff,
+	0x000092c0, 0x00090008, 0xffffffff,
+	0x000092c4, 0x00070000, 0xffffffff,
+	0x000092c8, 0x00030002, 0xffffffff,
+	0x000092cc, 0x00050004, 0xffffffff,
+	0x000092d8, 0x00010006, 0xffffffff,
+	0x000092dc, 0x00090008, 0xffffffff,
+	0x00009294, 0x00000000, 0xffffffff,
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x00003fc4, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000010, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000011, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000012, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000013, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000014, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000015, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000016, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000017, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000018, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000019, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001a, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x0000001b, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff
+};
+#define CAYMAN_MGCG_DEFAULT_LENGTH sizeof(cayman_mgcg_default) / (3 * sizeof(u32))
+
+static const u32 cayman_mgcg_disable[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000002, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x000008f8, 0x00000003, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xffffffff,
+	0x00009150, 0x00600000, 0xffffffff
+};
+#define CAYMAN_MGCG_DISABLE_LENGTH   sizeof(cayman_mgcg_disable) / (3 * sizeof(u32))
+
+static const u32 cayman_mgcg_enable[] =
+{
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x000008f8, 0x00000002, 0xffffffff,
+	0x000008fc, 0x00600000, 0xffffffff,
+	0x000008f8, 0x00000003, 0xffffffff,
+	0x000008fc, 0x00000000, 0xffffffff,
+	0x00009150, 0x96944200, 0xffffffff
+};
+
+#define CAYMAN_MGCG_ENABLE_LENGTH   sizeof(cayman_mgcg_enable) / (3 * sizeof(u32))
+
+#define NISLANDS_SYSLS_SEQUENCE  100
+
+static const u32 cayman_sysls_default[] =
+{
+	/* Register,   Value,     Mask bits */
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x0000d8bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x000020c0, 0x000c0c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x00002f50, 0x00000404, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x000064ec, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00008dfc, 0x00000000, 0xffffffff
+};
+#define CAYMAN_SYSLS_DEFAULT_LENGTH sizeof(cayman_sysls_default) / (3 * sizeof(u32))
+
+static const u32 cayman_sysls_disable[] =
+{
+	/* Register,   Value,     Mask bits */
+	0x0000d0c0, 0x00000000, 0xffffffff,
+	0x0000d8c0, 0x00000000, 0xffffffff,
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x0000d8bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x00041401, 0xffffffff,
+	0x0000264c, 0x00040400, 0xffffffff,
+	0x00002648, 0x00040400, 0xffffffff,
+	0x00002650, 0x00040400, 0xffffffff,
+	0x000020b8, 0x00040400, 0xffffffff,
+	0x000020bc, 0x00040400, 0xffffffff,
+	0x000020c0, 0x00040c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680000, 0xffffffff,
+	0x00002f50, 0x00000404, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x000064ec, 0x00007ffd, 0xffffffff,
+	0x00000c7c, 0x0000ff00, 0xffffffff,
+	0x00008dfc, 0x0000007f, 0xffffffff
+};
+#define CAYMAN_SYSLS_DISABLE_LENGTH sizeof(cayman_sysls_disable) / (3 * sizeof(u32))
+
+static const u32 cayman_sysls_enable[] =
+{
+	/* Register,   Value,     Mask bits */
+	0x000055e8, 0x00000001, 0xffffffff,
+	0x0000d0bc, 0x00000100, 0xffffffff,
+	0x0000d8bc, 0x00000100, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x000020c0, 0x000c0c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x00002f50, 0x00000903, 0xffffffff,
+	0x000004c8, 0x00000000, 0xffffffff,
+	0x000064ec, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00008dfc, 0x00000000, 0xffffffff
+};
+#define CAYMAN_SYSLS_ENABLE_LENGTH sizeof(cayman_sysls_enable) / (3 * sizeof(u32))
+
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
+struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
+
+struct ni_power_info *ni_get_pi(struct radeon_device *rdev)
+{
+        struct ni_power_info *pi = rdev->pm.dpm.priv;
+
+        return pi;
+}
+
+struct ni_ps *ni_get_ps(struct radeon_ps *rps)
+{
+	struct ni_ps *ps = rps->ps_priv;
+
+	return ps;
+}
+
+static void ni_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients *coeff,
+						     u16 v, s32 t,
+						     u32 ileakage,
+						     u32 *leakage)
+{
+	s64 kt, kv, leakage_w, i_leakage, vddc, temperature;
+
+	i_leakage = div64_s64(drm_int2fixp(ileakage), 1000);
+	vddc = div64_s64(drm_int2fixp(v), 1000);
+	temperature = div64_s64(drm_int2fixp(t), 1000);
+
+	kt = drm_fixp_mul(div64_s64(drm_int2fixp(coeff->at), 1000),
+			  drm_fixp_exp(drm_fixp_mul(div64_s64(drm_int2fixp(coeff->bt), 1000), temperature)));
+	kv = drm_fixp_mul(div64_s64(drm_int2fixp(coeff->av), 1000),
+			  drm_fixp_exp(drm_fixp_mul(div64_s64(drm_int2fixp(coeff->bv), 1000), vddc)));
+
+	leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);
+
+	*leakage = drm_fixp2int(leakage_w * 1000);
+}
+
+static void ni_calculate_leakage_for_v_and_t(struct radeon_device *rdev,
+					     const struct ni_leakage_coeffients *coeff,
+					     u16 v,
+					     s32 t,
+					     u32 i_leakage,
+					     u32 *leakage)
+{
+	ni_calculate_leakage_for_v_and_t_formula(coeff, v, t, i_leakage, leakage);
+}
+
+bool ni_dpm_vblank_too_short(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 vblank_time = r600_dpm_get_vblank_time(rdev);
+	u32 switch_limit = pi->mem_gddr5 ? 450 : 300;
+
+	if (vblank_time < switch_limit)
+		return true;
+	else
+		return false;
+
+}
+
+static void ni_apply_state_adjust_rules(struct radeon_device *rdev,
+					struct radeon_ps *rps)
+{
+	struct ni_ps *ps = ni_get_ps(rps);
+	struct radeon_clock_and_voltage_limits *max_limits;
+	bool disable_mclk_switching;
+	u32 mclk, sclk;
+	u16 vddc, vddci;
+	int i;
+
+	if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
+	    ni_dpm_vblank_too_short(rdev))
+		disable_mclk_switching = true;
+	else
+		disable_mclk_switching = false;
+
+	if (rdev->pm.dpm.ac_power)
+		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
+	else
+		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
+
+	if (rdev->pm.dpm.ac_power == false) {
+		for (i = 0; i < ps->performance_level_count; i++) {
+			if (ps->performance_levels[i].mclk > max_limits->mclk)
+				ps->performance_levels[i].mclk = max_limits->mclk;
+			if (ps->performance_levels[i].sclk > max_limits->sclk)
+				ps->performance_levels[i].sclk = max_limits->sclk;
+			if (ps->performance_levels[i].vddc > max_limits->vddc)
+				ps->performance_levels[i].vddc = max_limits->vddc;
+			if (ps->performance_levels[i].vddci > max_limits->vddci)
+				ps->performance_levels[i].vddci = max_limits->vddci;
+		}
+	}
+
+	/* XXX validate the min clocks required for display */
+
+	if (disable_mclk_switching) {
+		mclk  = ps->performance_levels[ps->performance_level_count - 1].mclk;
+		sclk = ps->performance_levels[0].sclk;
+		vddc = ps->performance_levels[0].vddc;
+		vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
+	} else {
+		sclk = ps->performance_levels[0].sclk;
+		mclk = ps->performance_levels[0].mclk;
+		vddc = ps->performance_levels[0].vddc;
+		vddci = ps->performance_levels[0].vddci;
+	}
+
+	/* adjusted low state */
+	ps->performance_levels[0].sclk = sclk;
+	ps->performance_levels[0].mclk = mclk;
+	ps->performance_levels[0].vddc = vddc;
+	ps->performance_levels[0].vddci = vddci;
+
+	btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
+				  &ps->performance_levels[0].sclk,
+				  &ps->performance_levels[0].mclk);
+
+	for (i = 1; i < ps->performance_level_count; i++) {
+		if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
+			ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
+		if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
+			ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
+	}
+
+	if (disable_mclk_switching) {
+		mclk = ps->performance_levels[0].mclk;
+		for (i = 1; i < ps->performance_level_count; i++) {
+			if (mclk < ps->performance_levels[i].mclk)
+				mclk = ps->performance_levels[i].mclk;
+		}
+		for (i = 0; i < ps->performance_level_count; i++) {
+			ps->performance_levels[i].mclk = mclk;
+			ps->performance_levels[i].vddci = vddci;
+		}
+	} else {
+		for (i = 1; i < ps->performance_level_count; i++) {
+			if (ps->performance_levels[i].mclk < ps->performance_levels[i - 1].mclk)
+				ps->performance_levels[i].mclk = ps->performance_levels[i - 1].mclk;
+			if (ps->performance_levels[i].vddci < ps->performance_levels[i - 1].vddci)
+				ps->performance_levels[i].vddci = ps->performance_levels[i - 1].vddci;
+		}
+	}
+
+	for (i = 1; i < ps->performance_level_count; i++)
+		btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
+					  &ps->performance_levels[i].sclk,
+					  &ps->performance_levels[i].mclk);
+
+	for (i = 0; i < ps->performance_level_count; i++)
+		btc_adjust_clock_combinations(rdev, max_limits,
+					      &ps->performance_levels[i]);
+
+	for (i = 0; i < ps->performance_level_count; i++) {
+		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
+						   ps->performance_levels[i].sclk,
+						   max_limits->vddc,  &ps->performance_levels[i].vddc);
+		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+						   ps->performance_levels[i].mclk,
+						   max_limits->vddci, &ps->performance_levels[i].vddci);
+		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+						   ps->performance_levels[i].mclk,
+						   max_limits->vddc,  &ps->performance_levels[i].vddc);
+		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+						   rdev->clock.current_dispclk,
+						   max_limits->vddc,  &ps->performance_levels[i].vddc);
+	}
+
+	for (i = 0; i < ps->performance_level_count; i++) {
+		btc_apply_voltage_delta_rules(rdev,
+					      max_limits->vddc, max_limits->vddci,
+					      &ps->performance_levels[i].vddc,
+					      &ps->performance_levels[i].vddci);
+	}
+
+	ps->dc_compatible = true;
+	for (i = 0; i < ps->performance_level_count; i++) {
+		if (ps->performance_levels[i].vddc > rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc)
+			ps->dc_compatible = false;
+
+		if (ps->performance_levels[i].vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
+			ps->performance_levels[i].flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
+	}
+}
+
+static void ni_cg_clockgating_default(struct radeon_device *rdev)
+{
+	u32 count;
+	const u32 *ps = NULL;
+
+	ps = (const u32 *)&cayman_cgcg_cgls_default;
+	count = CAYMAN_CGCG_CGLS_DEFAULT_LENGTH;
+
+	btc_program_mgcg_hw_sequence(rdev, ps, count);
+}
+
+static void ni_gfx_clockgating_enable(struct radeon_device *rdev,
+				      bool enable)
+{
+	u32 count;
+	const u32 *ps = NULL;
+
+	if (enable) {
+		ps = (const u32 *)&cayman_cgcg_cgls_enable;
+		count = CAYMAN_CGCG_CGLS_ENABLE_LENGTH;
+	} else {
+		ps = (const u32 *)&cayman_cgcg_cgls_disable;
+		count = CAYMAN_CGCG_CGLS_DISABLE_LENGTH;
+	}
+
+	btc_program_mgcg_hw_sequence(rdev, ps, count);
+}
+
+static void ni_mg_clockgating_default(struct radeon_device *rdev)
+{
+	u32 count;
+	const u32 *ps = NULL;
+
+	ps = (const u32 *)&cayman_mgcg_default;
+	count = CAYMAN_MGCG_DEFAULT_LENGTH;
+
+	btc_program_mgcg_hw_sequence(rdev, ps, count);
+}
+
+static void ni_mg_clockgating_enable(struct radeon_device *rdev,
+				     bool enable)
+{
+	u32 count;
+	const u32 *ps = NULL;
+
+	if (enable) {
+		ps = (const u32 *)&cayman_mgcg_enable;
+		count = CAYMAN_MGCG_ENABLE_LENGTH;
+	} else {
+		ps = (const u32 *)&cayman_mgcg_disable;
+		count = CAYMAN_MGCG_DISABLE_LENGTH;
+	}
+
+	btc_program_mgcg_hw_sequence(rdev, ps, count);
+}
+
+static void ni_ls_clockgating_default(struct radeon_device *rdev)
+{
+	u32 count;
+	const u32 *ps = NULL;
+
+	ps = (const u32 *)&cayman_sysls_default;
+	count = CAYMAN_SYSLS_DEFAULT_LENGTH;
+
+	btc_program_mgcg_hw_sequence(rdev, ps, count);
+}
+
+static void ni_ls_clockgating_enable(struct radeon_device *rdev,
+				     bool enable)
+{
+	u32 count;
+	const u32 *ps = NULL;
+
+	if (enable) {
+		ps = (const u32 *)&cayman_sysls_enable;
+		count = CAYMAN_SYSLS_ENABLE_LENGTH;
+	} else {
+		ps = (const u32 *)&cayman_sysls_disable;
+		count = CAYMAN_SYSLS_DISABLE_LENGTH;
+	}
+
+	btc_program_mgcg_hw_sequence(rdev, ps, count);
+
+}
+
+static int ni_patch_single_dependency_table_based_on_leakage(struct radeon_device *rdev,
+							     struct radeon_clock_voltage_dependency_table *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 i;
+
+	if (table) {
+		for (i = 0; i < table->count; i++) {
+			if (0xff01 == table->entries[i].v) {
+				if (pi->max_vddc == 0)
+					return -EINVAL;
+				table->entries[i].v = pi->max_vddc;
+			}
+		}
+	}
+	return 0;
+}
+
+static int ni_patch_dependency_tables_based_on_leakage(struct radeon_device *rdev)
+{
+	int ret = 0;
+
+	ret = ni_patch_single_dependency_table_based_on_leakage(rdev,
+								&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk);
+
+	ret = ni_patch_single_dependency_table_based_on_leakage(rdev,
+								&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk);
+	return ret;
+}
+
+static void ni_stop_dpm(struct radeon_device *rdev)
+{
+	WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
+}
+
+#if 0
+static int ni_notify_hw_of_power_source(struct radeon_device *rdev,
+					bool ac_power)
+{
+	if (ac_power)
+		return (rv770_send_msg_to_smc(rdev, PPSMC_MSG_RunningOnAC) == PPSMC_Result_OK) ?
+			0 : -EINVAL;
+
+	return 0;
+}
+#endif
+
+static PPSMC_Result ni_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
+						      PPSMC_Msg msg, u32 parameter)
+{
+	WREG32(SMC_SCRATCH0, parameter);
+	return rv770_send_msg_to_smc(rdev, msg);
+}
+
+static int ni_restrict_performance_levels_before_switch(struct radeon_device *rdev)
+{
+	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	return (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) == PPSMC_Result_OK) ?
+		0 : -EINVAL;
+}
+
+int ni_dpm_force_performance_level(struct radeon_device *rdev,
+				   enum radeon_dpm_forced_level level)
+{
+	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
+		if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK)
+			return -EINVAL;
+
+		if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK)
+			return -EINVAL;
+	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
+		if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
+			return -EINVAL;
+
+		if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK)
+			return -EINVAL;
+	} else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) {
+		if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
+			return -EINVAL;
+
+		if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK)
+			return -EINVAL;
+	}
+
+	rdev->pm.dpm.forced_level = level;
+
+	return 0;
+}
+
+static void ni_stop_smc(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK;
+		if (tmp != 1)
+			break;
+		udelay(1);
+	}
+
+	udelay(100);
+
+	r7xx_stop_smc(rdev);
+}
+
+static int ni_process_firmware_header(struct radeon_device *rdev)
+{
+        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+        struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 tmp;
+	int ret;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+					NISLANDS_SMC_FIRMWARE_HEADER_stateTable,
+					&tmp, pi->sram_end);
+
+	if (ret)
+		return ret;
+
+	pi->state_table_start = (u16)tmp;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+					NISLANDS_SMC_FIRMWARE_HEADER_softRegisters,
+					&tmp, pi->sram_end);
+
+	if (ret)
+		return ret;
+
+	pi->soft_regs_start = (u16)tmp;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+					NISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable,
+					&tmp, pi->sram_end);
+
+	if (ret)
+		return ret;
+
+	eg_pi->mc_reg_table_start = (u16)tmp;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+					NISLANDS_SMC_FIRMWARE_HEADER_fanTable,
+					&tmp, pi->sram_end);
+
+	if (ret)
+		return ret;
+
+	ni_pi->fan_table_start = (u16)tmp;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+					NISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable,
+					&tmp, pi->sram_end);
+
+	if (ret)
+		return ret;
+
+	ni_pi->arb_table_start = (u16)tmp;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+					NISLANDS_SMC_FIRMWARE_HEADER_cacTable,
+					&tmp, pi->sram_end);
+
+	if (ret)
+		return ret;
+
+	ni_pi->cac_table_start = (u16)tmp;
+
+	ret = rv770_read_smc_sram_dword(rdev,
+					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+					NISLANDS_SMC_FIRMWARE_HEADER_spllTable,
+					&tmp, pi->sram_end);
+
+	if (ret)
+		return ret;
+
+	ni_pi->spll_table_start = (u16)tmp;
+
+
+	return ret;
+}
+
+static void ni_read_clock_registers(struct radeon_device *rdev)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+
+	ni_pi->clock_registers.cg_spll_func_cntl = RREG32(CG_SPLL_FUNC_CNTL);
+	ni_pi->clock_registers.cg_spll_func_cntl_2 = RREG32(CG_SPLL_FUNC_CNTL_2);
+	ni_pi->clock_registers.cg_spll_func_cntl_3 = RREG32(CG_SPLL_FUNC_CNTL_3);
+	ni_pi->clock_registers.cg_spll_func_cntl_4 = RREG32(CG_SPLL_FUNC_CNTL_4);
+	ni_pi->clock_registers.cg_spll_spread_spectrum = RREG32(CG_SPLL_SPREAD_SPECTRUM);
+	ni_pi->clock_registers.cg_spll_spread_spectrum_2 = RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
+	ni_pi->clock_registers.mpll_ad_func_cntl = RREG32(MPLL_AD_FUNC_CNTL);
+	ni_pi->clock_registers.mpll_ad_func_cntl_2 = RREG32(MPLL_AD_FUNC_CNTL_2);
+	ni_pi->clock_registers.mpll_dq_func_cntl = RREG32(MPLL_DQ_FUNC_CNTL);
+	ni_pi->clock_registers.mpll_dq_func_cntl_2 = RREG32(MPLL_DQ_FUNC_CNTL_2);
+	ni_pi->clock_registers.mclk_pwrmgt_cntl = RREG32(MCLK_PWRMGT_CNTL);
+	ni_pi->clock_registers.dll_cntl = RREG32(DLL_CNTL);
+	ni_pi->clock_registers.mpll_ss1 = RREG32(MPLL_SS1);
+	ni_pi->clock_registers.mpll_ss2 = RREG32(MPLL_SS2);
+}
+
+#if 0
+static int ni_enter_ulp_state(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (pi->gfx_clock_gating) {
+                WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
+		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
+                WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
+		RREG32(GB_ADDR_CONFIG);
+        }
+
+	WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_SwitchToMinimumPower),
+                 ~HOST_SMC_MSG_MASK);
+
+	udelay(25000);
+
+	return 0;
+}
+#endif
+
+static void ni_program_response_times(struct radeon_device *rdev)
+{
+	u32 voltage_response_time, backbias_response_time, acpi_delay_time, vbi_time_out;
+	u32 vddc_dly, bb_dly, acpi_dly, vbi_dly, mclk_switch_limit;
+	u32 reference_clock;
+
+	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mvdd_chg_time, 1);
+
+	voltage_response_time = (u32)rdev->pm.dpm.voltage_response_time;
+	backbias_response_time = (u32)rdev->pm.dpm.backbias_response_time;
+
+	if (voltage_response_time == 0)
+		voltage_response_time = 1000;
+
+	if (backbias_response_time == 0)
+		backbias_response_time = 1000;
+
+	acpi_delay_time = 15000;
+	vbi_time_out = 100000;
+
+	reference_clock = radeon_get_xclk(rdev);
+
+	vddc_dly = (voltage_response_time  * reference_clock) / 1600;
+	bb_dly   = (backbias_response_time * reference_clock) / 1600;
+	acpi_dly = (acpi_delay_time * reference_clock) / 1600;
+	vbi_dly  = (vbi_time_out * reference_clock) / 1600;
+
+	mclk_switch_limit = (460 * reference_clock) / 100;
+
+	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_delay_vreg,  vddc_dly);
+	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_delay_bbias, bb_dly);
+	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_delay_acpi,  acpi_dly);
+	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);
+	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mc_block_delay, 0xAA);
+	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mclk_switch_lim, mclk_switch_limit);
+}
+
+static void ni_populate_smc_voltage_table(struct radeon_device *rdev,
+					  struct atom_voltage_table *voltage_table,
+					  NISLANDS_SMC_STATETABLE *table)
+{
+	unsigned int i;
+
+	for (i = 0; i < voltage_table->count; i++) {
+		table->highSMIO[i] = 0;
+		table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low);
+	}
+}
+
+static void ni_populate_smc_voltage_tables(struct radeon_device *rdev,
+					   NISLANDS_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	unsigned char i;
+
+	if (eg_pi->vddc_voltage_table.count) {
+		ni_populate_smc_voltage_table(rdev, &eg_pi->vddc_voltage_table, table);
+		table->voltageMaskTable.highMask[NISLANDS_SMC_VOLTAGEMASK_VDDC] = 0;
+		table->voltageMaskTable.lowMask[NISLANDS_SMC_VOLTAGEMASK_VDDC] =
+			cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
+
+		for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {
+			if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {
+				table->maxVDDCIndexInPPTable = i;
+				break;
+			}
+		}
+	}
+
+	if (eg_pi->vddci_voltage_table.count) {
+		ni_populate_smc_voltage_table(rdev, &eg_pi->vddci_voltage_table, table);
+
+		table->voltageMaskTable.highMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] = 0;
+		table->voltageMaskTable.lowMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] =
+			cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
+	}
+}
+
+static int ni_populate_voltage_value(struct radeon_device *rdev,
+				     struct atom_voltage_table *table,
+				     u16 value,
+				     NISLANDS_SMC_VOLTAGE_VALUE *voltage)
+{
+	unsigned int i;
+
+	for (i = 0; i < table->count; i++) {
+		if (value <= table->entries[i].value) {
+			voltage->index = (u8)i;
+			voltage->value = cpu_to_be16(table->entries[i].value);
+			break;
+		}
+	}
+
+	if (i >= table->count)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void ni_populate_mvdd_value(struct radeon_device *rdev,
+				   u32 mclk,
+				   NISLANDS_SMC_VOLTAGE_VALUE *voltage)
+{
+        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (!pi->mvdd_control) {
+		voltage->index = eg_pi->mvdd_high_index;
+                voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
+		return;
+	}
+
+	if (mclk <= pi->mvdd_split_frequency) {
+		voltage->index = eg_pi->mvdd_low_index;
+		voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
+	} else {
+		voltage->index = eg_pi->mvdd_high_index;
+		voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
+	}
+}
+
+static int ni_get_std_voltage_value(struct radeon_device *rdev,
+				    NISLANDS_SMC_VOLTAGE_VALUE *voltage,
+				    u16 *std_voltage)
+{
+	if (rdev->pm.dpm.dyn_state.cac_leakage_table.entries &&
+	    ((u32)voltage->index < rdev->pm.dpm.dyn_state.cac_leakage_table.count))
+		*std_voltage = rdev->pm.dpm.dyn_state.cac_leakage_table.entries[voltage->index].vddc;
+	else
+		*std_voltage = be16_to_cpu(voltage->value);
+
+	return 0;
+}
+
+static void ni_populate_std_voltage_value(struct radeon_device *rdev,
+					  u16 value, u8 index,
+					  NISLANDS_SMC_VOLTAGE_VALUE *voltage)
+{
+	voltage->index = index;
+	voltage->value = cpu_to_be16(value);
+}
+
+static u32 ni_get_smc_power_scaling_factor(struct radeon_device *rdev)
+{
+	u32 xclk_period;
+	u32 xclk = radeon_get_xclk(rdev);
+	u32 tmp = RREG32(CG_CAC_CTRL) & TID_CNT_MASK;
+
+	xclk_period = (1000000000UL / xclk);
+	xclk_period /= 10000UL;
+
+	return tmp * xclk_period;
+}
+
+static u32 ni_scale_power_for_smc(u32 power_in_watts, u32 scaling_factor)
+{
+	return (power_in_watts * scaling_factor) << 2;
+}
+
+static u32 ni_calculate_power_boost_limit(struct radeon_device *rdev,
+					  struct radeon_ps *radeon_state,
+					  u32 near_tdp_limit)
+{
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 power_boost_limit = 0;
+	int ret;
+
+	if (ni_pi->enable_power_containment &&
+	    ni_pi->use_power_boost_limit) {
+		NISLANDS_SMC_VOLTAGE_VALUE vddc;
+		u16 std_vddc_med;
+		u16 std_vddc_high;
+		u64 tmp, n, d;
+
+		if (state->performance_level_count < 3)
+			return 0;
+
+		ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
+						state->performance_levels[state->performance_level_count - 2].vddc,
+						&vddc);
+		if (ret)
+			return 0;
+
+		ret = ni_get_std_voltage_value(rdev, &vddc, &std_vddc_med);
+		if (ret)
+			return 0;
+
+		ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
+						state->performance_levels[state->performance_level_count - 1].vddc,
+						&vddc);
+		if (ret)
+			return 0;
+
+		ret = ni_get_std_voltage_value(rdev, &vddc, &std_vddc_high);
+		if (ret)
+			return 0;
+
+		n = ((u64)near_tdp_limit * ((u64)std_vddc_med * (u64)std_vddc_med) * 90);
+		d = ((u64)std_vddc_high * (u64)std_vddc_high * 100);
+		tmp = div64_u64(n, d);
+
+		if (tmp >> 32)
+			return 0;
+		power_boost_limit = (u32)tmp;
+	}
+
+	return power_boost_limit;
+}
+
+static int ni_calculate_adjusted_tdp_limits(struct radeon_device *rdev,
+					    bool adjust_polarity,
+					    u32 tdp_adjustment,
+					    u32 *tdp_limit,
+					    u32 *near_tdp_limit)
+{
+	if (tdp_adjustment > (u32)rdev->pm.dpm.tdp_od_limit)
+		return -EINVAL;
+
+	if (adjust_polarity) {
+		*tdp_limit = ((100 + tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
+		*near_tdp_limit = rdev->pm.dpm.near_tdp_limit + (*tdp_limit - rdev->pm.dpm.tdp_limit);
+	} else {
+		*tdp_limit = ((100 - tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
+		*near_tdp_limit = rdev->pm.dpm.near_tdp_limit - (rdev->pm.dpm.tdp_limit - *tdp_limit);
+	}
+
+	return 0;
+}
+
+static int ni_populate_smc_tdp_limits(struct radeon_device *rdev,
+				      struct radeon_ps *radeon_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+
+	if (ni_pi->enable_power_containment) {
+		NISLANDS_SMC_STATETABLE *smc_table = &ni_pi->smc_statetable;
+		u32 scaling_factor = ni_get_smc_power_scaling_factor(rdev);
+		u32 tdp_limit;
+		u32 near_tdp_limit;
+		u32 power_boost_limit;
+		int ret;
+
+		if (scaling_factor == 0)
+			return -EINVAL;
+
+		memset(smc_table, 0, sizeof(NISLANDS_SMC_STATETABLE));
+
+		ret = ni_calculate_adjusted_tdp_limits(rdev,
+						       false, /* ??? */
+						       rdev->pm.dpm.tdp_adjustment,
+						       &tdp_limit,
+						       &near_tdp_limit);
+		if (ret)
+			return ret;
+
+		power_boost_limit = ni_calculate_power_boost_limit(rdev, radeon_state,
+								   near_tdp_limit);
+
+		smc_table->dpm2Params.TDPLimit =
+			cpu_to_be32(ni_scale_power_for_smc(tdp_limit, scaling_factor));
+		smc_table->dpm2Params.NearTDPLimit =
+			cpu_to_be32(ni_scale_power_for_smc(near_tdp_limit, scaling_factor));
+		smc_table->dpm2Params.SafePowerLimit =
+			cpu_to_be32(ni_scale_power_for_smc((near_tdp_limit * NISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100,
+							   scaling_factor));
+		smc_table->dpm2Params.PowerBoostLimit =
+			cpu_to_be32(ni_scale_power_for_smc(power_boost_limit, scaling_factor));
+
+		ret = rv770_copy_bytes_to_smc(rdev,
+					      (u16)(pi->state_table_start + offsetof(NISLANDS_SMC_STATETABLE, dpm2Params) +
+						    offsetof(PP_NIslands_DPM2Parameters, TDPLimit)),
+					      (u8 *)(&smc_table->dpm2Params.TDPLimit),
+					      sizeof(u32) * 4, pi->sram_end);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+int ni_copy_and_switch_arb_sets(struct radeon_device *rdev,
+				u32 arb_freq_src, u32 arb_freq_dest)
+{
+	u32 mc_arb_dram_timing;
+	u32 mc_arb_dram_timing2;
+	u32 burst_time;
+	u32 mc_cg_config;
+
+	switch (arb_freq_src) {
+        case MC_CG_ARB_FREQ_F0:
+		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING);
+		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
+		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE0_MASK) >> STATE0_SHIFT;
+		break;
+        case MC_CG_ARB_FREQ_F1:
+		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING_1);
+		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_1);
+		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE1_MASK) >> STATE1_SHIFT;
+		break;
+        case MC_CG_ARB_FREQ_F2:
+		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING_2);
+		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_2);
+		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE2_MASK) >> STATE2_SHIFT;
+		break;
+        case MC_CG_ARB_FREQ_F3:
+		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING_3);
+		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_3);
+		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE3_MASK) >> STATE3_SHIFT;
+		break;
+        default:
+		return -EINVAL;
+	}
+
+	switch (arb_freq_dest) {
+        case MC_CG_ARB_FREQ_F0:
+		WREG32(MC_ARB_DRAM_TIMING, mc_arb_dram_timing);
+		WREG32(MC_ARB_DRAM_TIMING2, mc_arb_dram_timing2);
+		WREG32_P(MC_ARB_BURST_TIME, STATE0(burst_time), ~STATE0_MASK);
+		break;
+        case MC_CG_ARB_FREQ_F1:
+		WREG32(MC_ARB_DRAM_TIMING_1, mc_arb_dram_timing);
+		WREG32(MC_ARB_DRAM_TIMING2_1, mc_arb_dram_timing2);
+		WREG32_P(MC_ARB_BURST_TIME, STATE1(burst_time), ~STATE1_MASK);
+		break;
+        case MC_CG_ARB_FREQ_F2:
+		WREG32(MC_ARB_DRAM_TIMING_2, mc_arb_dram_timing);
+		WREG32(MC_ARB_DRAM_TIMING2_2, mc_arb_dram_timing2);
+		WREG32_P(MC_ARB_BURST_TIME, STATE2(burst_time), ~STATE2_MASK);
+		break;
+        case MC_CG_ARB_FREQ_F3:
+		WREG32(MC_ARB_DRAM_TIMING_3, mc_arb_dram_timing);
+		WREG32(MC_ARB_DRAM_TIMING2_3, mc_arb_dram_timing2);
+		WREG32_P(MC_ARB_BURST_TIME, STATE3(burst_time), ~STATE3_MASK);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mc_cg_config = RREG32(MC_CG_CONFIG) | 0x0000000F;
+	WREG32(MC_CG_CONFIG, mc_cg_config);
+	WREG32_P(MC_ARB_CG, CG_ARB_REQ(arb_freq_dest), ~CG_ARB_REQ_MASK);
+
+	return 0;
+}
+
+static int ni_init_arb_table_index(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 tmp;
+	int ret;
+
+	ret = rv770_read_smc_sram_dword(rdev, ni_pi->arb_table_start,
+					&tmp, pi->sram_end);
+	if (ret)
+		return ret;
+
+	tmp &= 0x00FFFFFF;
+	tmp |= ((u32)MC_CG_ARB_FREQ_F1) << 24;
+
+	return rv770_write_smc_sram_dword(rdev, ni_pi->arb_table_start,
+					  tmp, pi->sram_end);
+}
+
+static int ni_initial_switch_from_arb_f0_to_f1(struct radeon_device *rdev)
+{
+	return ni_copy_and_switch_arb_sets(rdev, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
+}
+
+static int ni_force_switch_to_arb_f0(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 tmp;
+	int ret;
+
+	ret = rv770_read_smc_sram_dword(rdev, ni_pi->arb_table_start,
+					&tmp, pi->sram_end);
+	if (ret)
+		return ret;
+
+	tmp = (tmp >> 24) & 0xff;
+
+	if (tmp == MC_CG_ARB_FREQ_F0)
+		return 0;
+
+	return ni_copy_and_switch_arb_sets(rdev, tmp, MC_CG_ARB_FREQ_F0);
+}
+
+static int ni_populate_memory_timing_parameters(struct radeon_device *rdev,
+						struct rv7xx_pl *pl,
+						SMC_NIslands_MCArbDramTimingRegisterSet *arb_regs)
+{
+	u32 dram_timing;
+	u32 dram_timing2;
+
+	arb_regs->mc_arb_rfsh_rate =
+		(u8)rv770_calculate_memory_refresh_rate(rdev, pl->sclk);
+
+
+	radeon_atom_set_engine_dram_timings(rdev,
+                                            pl->sclk,
+                                            pl->mclk);
+
+	dram_timing = RREG32(MC_ARB_DRAM_TIMING);
+	dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
+
+	arb_regs->mc_arb_dram_timing  = cpu_to_be32(dram_timing);
+	arb_regs->mc_arb_dram_timing2 = cpu_to_be32(dram_timing2);
+
+	return 0;
+}
+
+static int ni_do_program_memory_timing_parameters(struct radeon_device *rdev,
+						  struct radeon_ps *radeon_state,
+						  unsigned int first_arb_set)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	SMC_NIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };
+	int i, ret = 0;
+
+	for (i = 0; i < state->performance_level_count; i++) {
+		ret = ni_populate_memory_timing_parameters(rdev, &state->performance_levels[i], &arb_regs);
+		if (ret)
+			break;
+
+		ret = rv770_copy_bytes_to_smc(rdev,
+					      (u16)(ni_pi->arb_table_start +
+						    offsetof(SMC_NIslands_MCArbDramTimingRegisters, data) +
+						    sizeof(SMC_NIslands_MCArbDramTimingRegisterSet) * (first_arb_set + i)),
+					      (u8 *)&arb_regs,
+					      (u16)sizeof(SMC_NIslands_MCArbDramTimingRegisterSet),
+					      pi->sram_end);
+		if (ret)
+			break;
+	}
+	return ret;
+}
+
+static int ni_program_memory_timing_parameters(struct radeon_device *rdev,
+					       struct radeon_ps *radeon_new_state)
+{
+	return ni_do_program_memory_timing_parameters(rdev, radeon_new_state,
+						      NISLANDS_DRIVER_STATE_ARB_INDEX);
+}
+
+static void ni_populate_initial_mvdd_value(struct radeon_device *rdev,
+					   struct NISLANDS_SMC_VOLTAGE_VALUE *voltage)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	voltage->index = eg_pi->mvdd_high_index;
+	voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
+}
+
+static int ni_populate_smc_initial_state(struct radeon_device *rdev,
+					 struct radeon_ps *radeon_initial_state,
+					 NISLANDS_SMC_STATETABLE *table)
+{
+	struct ni_ps *initial_state = ni_get_ps(radeon_initial_state);
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 reg;
+	int ret;
+
+	table->initialState.levels[0].mclk.vMPLL_AD_FUNC_CNTL =
+		cpu_to_be32(ni_pi->clock_registers.mpll_ad_func_cntl);
+	table->initialState.levels[0].mclk.vMPLL_AD_FUNC_CNTL_2 =
+		cpu_to_be32(ni_pi->clock_registers.mpll_ad_func_cntl_2);
+	table->initialState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL =
+		cpu_to_be32(ni_pi->clock_registers.mpll_dq_func_cntl);
+	table->initialState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL_2 =
+		cpu_to_be32(ni_pi->clock_registers.mpll_dq_func_cntl_2);
+	table->initialState.levels[0].mclk.vMCLK_PWRMGT_CNTL =
+		cpu_to_be32(ni_pi->clock_registers.mclk_pwrmgt_cntl);
+	table->initialState.levels[0].mclk.vDLL_CNTL =
+		cpu_to_be32(ni_pi->clock_registers.dll_cntl);
+	table->initialState.levels[0].mclk.vMPLL_SS =
+		cpu_to_be32(ni_pi->clock_registers.mpll_ss1);
+	table->initialState.levels[0].mclk.vMPLL_SS2 =
+		cpu_to_be32(ni_pi->clock_registers.mpll_ss2);
+	table->initialState.levels[0].mclk.mclk_value =
+		cpu_to_be32(initial_state->performance_levels[0].mclk);
+
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
+		cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
+		cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl_2);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
+		cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl_3);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_4 =
+		cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl_4);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
+		cpu_to_be32(ni_pi->clock_registers.cg_spll_spread_spectrum);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =
+		cpu_to_be32(ni_pi->clock_registers.cg_spll_spread_spectrum_2);
+	table->initialState.levels[0].sclk.sclk_value =
+		cpu_to_be32(initial_state->performance_levels[0].sclk);
+	table->initialState.levels[0].arbRefreshState =
+		NISLANDS_INITIAL_STATE_ARB_INDEX;
+
+	table->initialState.levels[0].ACIndex = 0;
+
+	ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
+					initial_state->performance_levels[0].vddc,
+					&table->initialState.levels[0].vddc);
+	if (!ret) {
+		u16 std_vddc;
+
+		ret = ni_get_std_voltage_value(rdev,
+					       &table->initialState.levels[0].vddc,
+					       &std_vddc);
+		if (!ret)
+			ni_populate_std_voltage_value(rdev, std_vddc,
+						      table->initialState.levels[0].vddc.index,
+						      &table->initialState.levels[0].std_vddc);
+	}
+
+	if (eg_pi->vddci_control)
+		ni_populate_voltage_value(rdev,
+					  &eg_pi->vddci_voltage_table,
+					  initial_state->performance_levels[0].vddci,
+					  &table->initialState.levels[0].vddci);
+
+	ni_populate_initial_mvdd_value(rdev, &table->initialState.levels[0].mvdd);
+
+	reg = CG_R(0xffff) | CG_L(0);
+	table->initialState.levels[0].aT = cpu_to_be32(reg);
+
+	table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
+
+	if (pi->boot_in_gen2)
+		table->initialState.levels[0].gen2PCIE = 1;
+	else
+		table->initialState.levels[0].gen2PCIE = 0;
+
+	if (pi->mem_gddr5) {
+		table->initialState.levels[0].strobeMode =
+			cypress_get_strobe_mode_settings(rdev,
+							 initial_state->performance_levels[0].mclk);
+
+		if (initial_state->performance_levels[0].mclk > pi->mclk_edc_enable_threshold)
+			table->initialState.levels[0].mcFlags = NISLANDS_SMC_MC_EDC_RD_FLAG | NISLANDS_SMC_MC_EDC_WR_FLAG;
+		else
+			table->initialState.levels[0].mcFlags =  0;
+	}
+
+	table->initialState.levelCount = 1;
+
+	table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
+
+	table->initialState.levels[0].dpm2.MaxPS = 0;
+	table->initialState.levels[0].dpm2.NearTDPDec = 0;
+	table->initialState.levels[0].dpm2.AboveSafeInc = 0;
+	table->initialState.levels[0].dpm2.BelowSafeInc = 0;
+
+	reg = MIN_POWER_MASK | MAX_POWER_MASK;
+	table->initialState.levels[0].SQPowerThrottle = cpu_to_be32(reg);
+
+	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
+	table->initialState.levels[0].SQPowerThrottle_2 = cpu_to_be32(reg);
+
+	return 0;
+}
+
+static int ni_populate_smc_acpi_state(struct radeon_device *rdev,
+				      NISLANDS_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 mpll_ad_func_cntl   = ni_pi->clock_registers.mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2 = ni_pi->clock_registers.mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl   = ni_pi->clock_registers.mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2 = ni_pi->clock_registers.mpll_dq_func_cntl_2;
+	u32 spll_func_cntl      = ni_pi->clock_registers.cg_spll_func_cntl;
+	u32 spll_func_cntl_2    = ni_pi->clock_registers.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3    = ni_pi->clock_registers.cg_spll_func_cntl_3;
+	u32 spll_func_cntl_4    = ni_pi->clock_registers.cg_spll_func_cntl_4;
+	u32 mclk_pwrmgt_cntl    = ni_pi->clock_registers.mclk_pwrmgt_cntl;
+	u32 dll_cntl            = ni_pi->clock_registers.dll_cntl;
+	u32 reg;
+	int ret;
+
+	table->ACPIState = table->initialState;
+
+	table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
+
+	if (pi->acpi_vddc) {
+		ret = ni_populate_voltage_value(rdev,
+						&eg_pi->vddc_voltage_table,
+						pi->acpi_vddc, &table->ACPIState.levels[0].vddc);
+		if (!ret) {
+			u16 std_vddc;
+
+			ret = ni_get_std_voltage_value(rdev,
+						       &table->ACPIState.levels[0].vddc, &std_vddc);
+			if (!ret)
+				ni_populate_std_voltage_value(rdev, std_vddc,
+							      table->ACPIState.levels[0].vddc.index,
+							      &table->ACPIState.levels[0].std_vddc);
+		}
+
+		if (pi->pcie_gen2) {
+			if (pi->acpi_pcie_gen2)
+				table->ACPIState.levels[0].gen2PCIE = 1;
+			else
+				table->ACPIState.levels[0].gen2PCIE = 0;
+		} else {
+			table->ACPIState.levels[0].gen2PCIE = 0;
+		}
+	} else {
+		ret = ni_populate_voltage_value(rdev,
+						&eg_pi->vddc_voltage_table,
+						pi->min_vddc_in_table,
+						&table->ACPIState.levels[0].vddc);
+		if (!ret) {
+			u16 std_vddc;
+
+			ret = ni_get_std_voltage_value(rdev,
+						       &table->ACPIState.levels[0].vddc,
+						       &std_vddc);
+			if (!ret)
+				ni_populate_std_voltage_value(rdev, std_vddc,
+							      table->ACPIState.levels[0].vddc.index,
+							      &table->ACPIState.levels[0].std_vddc);
+		}
+		table->ACPIState.levels[0].gen2PCIE = 0;
+	}
+
+	if (eg_pi->acpi_vddci) {
+		if (eg_pi->vddci_control)
+			ni_populate_voltage_value(rdev,
+						  &eg_pi->vddci_voltage_table,
+						  eg_pi->acpi_vddci,
+						  &table->ACPIState.levels[0].vddci);
+	}
+
+
+	mpll_ad_func_cntl &= ~PDNB;
+
+	mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
+
+        if (pi->mem_gddr5)
+                mpll_dq_func_cntl &= ~PDNB;
+        mpll_dq_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN | BYPASS;
+
+
+	mclk_pwrmgt_cntl |= (MRDCKA0_RESET |
+			     MRDCKA1_RESET |
+			     MRDCKB0_RESET |
+			     MRDCKB1_RESET |
+			     MRDCKC0_RESET |
+			     MRDCKC1_RESET |
+			     MRDCKD0_RESET |
+			     MRDCKD1_RESET);
+
+	mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB |
+			      MRDCKA1_PDNB |
+			      MRDCKB0_PDNB |
+			      MRDCKB1_PDNB |
+			      MRDCKC0_PDNB |
+			      MRDCKC1_PDNB |
+			      MRDCKD0_PDNB |
+			      MRDCKD1_PDNB);
+
+	dll_cntl |= (MRDCKA0_BYPASS |
+                     MRDCKA1_BYPASS |
+                     MRDCKB0_BYPASS |
+                     MRDCKB1_BYPASS |
+                     MRDCKC0_BYPASS |
+                     MRDCKC1_BYPASS |
+                     MRDCKD0_BYPASS |
+                     MRDCKD1_BYPASS);
+
+        spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(4);
+
+	table->ACPIState.levels[0].mclk.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
+	table->ACPIState.levels[0].mclk.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
+	table->ACPIState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
+	table->ACPIState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
+	table->ACPIState.levels[0].mclk.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	table->ACPIState.levels[0].mclk.vDLL_CNTL = cpu_to_be32(dll_cntl);
+
+	table->ACPIState.levels[0].mclk.mclk_value = 0;
+
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(spll_func_cntl_4);
+
+	table->ACPIState.levels[0].sclk.sclk_value = 0;
+
+	ni_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
+
+	if (eg_pi->dynamic_ac_timing)
+		table->ACPIState.levels[0].ACIndex = 1;
+
+	table->ACPIState.levels[0].dpm2.MaxPS = 0;
+	table->ACPIState.levels[0].dpm2.NearTDPDec = 0;
+	table->ACPIState.levels[0].dpm2.AboveSafeInc = 0;
+	table->ACPIState.levels[0].dpm2.BelowSafeInc = 0;
+
+	reg = MIN_POWER_MASK | MAX_POWER_MASK;
+	table->ACPIState.levels[0].SQPowerThrottle = cpu_to_be32(reg);
+
+	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
+	table->ACPIState.levels[0].SQPowerThrottle_2 = cpu_to_be32(reg);
+
+	return 0;
+}
+
+static int ni_init_smc_table(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	int ret;
+	struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
+	NISLANDS_SMC_STATETABLE *table = &ni_pi->smc_statetable;
+
+	memset(table, 0, sizeof(NISLANDS_SMC_STATETABLE));
+
+	ni_populate_smc_voltage_tables(rdev, table);
+
+	switch (rdev->pm.int_thermal_type) {
+	case THERMAL_TYPE_NI:
+	case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
+		break;
+	case THERMAL_TYPE_NONE:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
+		break;
+	default:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
+		break;
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
+
+	if (pi->mem_gddr5)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
+
+	ret = ni_populate_smc_initial_state(rdev, radeon_boot_state, table);
+	if (ret)
+		return ret;
+
+	ret = ni_populate_smc_acpi_state(rdev, table);
+	if (ret)
+		return ret;
+
+	table->driverState = table->initialState;
+
+	table->ULVState = table->initialState;
+
+	ret = ni_do_program_memory_timing_parameters(rdev, radeon_boot_state,
+						     NISLANDS_INITIAL_STATE_ARB_INDEX);
+	if (ret)
+		return ret;
+
+	return rv770_copy_bytes_to_smc(rdev, pi->state_table_start, (u8 *)table,
+				       sizeof(NISLANDS_SMC_STATETABLE), pi->sram_end);
+}
+
+static int ni_calculate_sclk_params(struct radeon_device *rdev,
+				    u32 engine_clock,
+				    NISLANDS_SMC_SCLK_VALUE *sclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct atom_clock_dividers dividers;
+	u32 spll_func_cntl = ni_pi->clock_registers.cg_spll_func_cntl;
+	u32 spll_func_cntl_2 = ni_pi->clock_registers.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3 = ni_pi->clock_registers.cg_spll_func_cntl_3;
+	u32 spll_func_cntl_4 = ni_pi->clock_registers.cg_spll_func_cntl_4;
+	u32 cg_spll_spread_spectrum = ni_pi->clock_registers.cg_spll_spread_spectrum;
+	u32 cg_spll_spread_spectrum_2 = ni_pi->clock_registers.cg_spll_spread_spectrum_2;
+	u64 tmp;
+	u32 reference_clock = rdev->clock.spll.reference_freq;
+	u32 reference_divider;
+	u32 fbdiv;
+	int ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     engine_clock, false, &dividers);
+	if (ret)
+		return ret;
+
+	reference_divider = 1 + dividers.ref_div;
+
+
+	tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16834;
+	do_div(tmp, reference_clock);
+	fbdiv = (u32) tmp;
+
+	spll_func_cntl &= ~(SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK);
+	spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
+	spll_func_cntl |= SPLL_PDIV_A(dividers.post_div);
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(2);
+
+	spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
+	spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
+	spll_func_cntl_3 |= SPLL_DITHEN;
+
+	if (pi->sclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 vco_freq = engine_clock * dividers.post_div;
+
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+						     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
+			u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
+			u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);
+
+			cg_spll_spread_spectrum &= ~CLK_S_MASK;
+			cg_spll_spread_spectrum |= CLK_S(clk_s);
+			cg_spll_spread_spectrum |= SSEN;
+
+			cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
+			cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
+		}
+	}
+
+	sclk->sclk_value = engine_clock;
+	sclk->vCG_SPLL_FUNC_CNTL = spll_func_cntl;
+	sclk->vCG_SPLL_FUNC_CNTL_2 = spll_func_cntl_2;
+	sclk->vCG_SPLL_FUNC_CNTL_3 = spll_func_cntl_3;
+	sclk->vCG_SPLL_FUNC_CNTL_4 = spll_func_cntl_4;
+	sclk->vCG_SPLL_SPREAD_SPECTRUM = cg_spll_spread_spectrum;
+	sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cg_spll_spread_spectrum_2;
+
+	return 0;
+}
+
+static int ni_populate_sclk_value(struct radeon_device *rdev,
+				  u32 engine_clock,
+				  NISLANDS_SMC_SCLK_VALUE *sclk)
+{
+	NISLANDS_SMC_SCLK_VALUE sclk_tmp;
+	int ret;
+
+	ret = ni_calculate_sclk_params(rdev, engine_clock, &sclk_tmp);
+	if (!ret) {
+		sclk->sclk_value = cpu_to_be32(sclk_tmp.sclk_value);
+		sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL);
+		sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_2);
+		sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_3);
+		sclk->vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_4);
+		sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM);
+		sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM_2);
+	}
+
+	return ret;
+}
+
+static int ni_init_smc_spll_table(struct radeon_device *rdev)
+{
+        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	SMC_NISLANDS_SPLL_DIV_TABLE *spll_table;
+	NISLANDS_SMC_SCLK_VALUE sclk_params;
+	u32 fb_div;
+	u32 p_div;
+	u32 clk_s;
+	u32 clk_v;
+	u32 sclk = 0;
+	int i, ret;
+	u32 tmp;
+
+	if (ni_pi->spll_table_start == 0)
+		return -EINVAL;
+
+	spll_table = kzalloc(sizeof(SMC_NISLANDS_SPLL_DIV_TABLE), GFP_KERNEL);
+	if (spll_table == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < 256; i++) {
+		ret = ni_calculate_sclk_params(rdev, sclk, &sclk_params);
+		if (ret)
+			break;
+
+		p_div = (sclk_params.vCG_SPLL_FUNC_CNTL & SPLL_PDIV_A_MASK) >> SPLL_PDIV_A_SHIFT;
+		fb_div = (sclk_params.vCG_SPLL_FUNC_CNTL_3 & SPLL_FB_DIV_MASK) >> SPLL_FB_DIV_SHIFT;
+		clk_s = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM & CLK_S_MASK) >> CLK_S_SHIFT;
+		clk_v = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM_2 & CLK_V_MASK) >> CLK_V_SHIFT;
+
+		fb_div &= ~0x00001FFF;
+		fb_div >>= 1;
+		clk_v >>= 6;
+
+		if (p_div & ~(SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT))
+			ret = -EINVAL;
+
+		if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))
+			ret = -EINVAL;
+
+		if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))
+			ret = -EINVAL;
+
+		if (clk_v & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT))
+			ret = -EINVAL;
+
+		if (ret)
+			break;
+
+		tmp = ((fb_div << SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_MASK) |
+			((p_div << SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_MASK);
+		spll_table->freq[i] = cpu_to_be32(tmp);
+
+		tmp = ((clk_v << SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK) |
+			((clk_s << SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK);
+		spll_table->ss[i] = cpu_to_be32(tmp);
+
+		sclk += 512;
+	}
+
+	if (!ret)
+		ret = rv770_copy_bytes_to_smc(rdev, ni_pi->spll_table_start, (u8 *)spll_table,
+					      sizeof(SMC_NISLANDS_SPLL_DIV_TABLE), pi->sram_end);
+
+	kfree(spll_table);
+
+	return ret;
+}
+
+static int ni_populate_mclk_value(struct radeon_device *rdev,
+				  u32 engine_clock,
+				  u32 memory_clock,
+				  NISLANDS_SMC_MCLK_VALUE *mclk,
+				  bool strobe_mode,
+				  bool dll_state_on)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 mpll_ad_func_cntl = ni_pi->clock_registers.mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2 = ni_pi->clock_registers.mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl = ni_pi->clock_registers.mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2 = ni_pi->clock_registers.mpll_dq_func_cntl_2;
+	u32 mclk_pwrmgt_cntl = ni_pi->clock_registers.mclk_pwrmgt_cntl;
+	u32 dll_cntl = ni_pi->clock_registers.dll_cntl;
+	u32 mpll_ss1 = ni_pi->clock_registers.mpll_ss1;
+	u32 mpll_ss2 = ni_pi->clock_registers.mpll_ss2;
+	struct atom_clock_dividers dividers;
+	u32 ibias;
+	u32 dll_speed;
+	int ret;
+	u32 mc_seq_misc7;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
+					     memory_clock, strobe_mode, &dividers);
+	if (ret)
+		return ret;
+
+	if (!strobe_mode) {
+		mc_seq_misc7 = RREG32(MC_SEQ_MISC7);
+
+		if (mc_seq_misc7 & 0x8000000)
+			dividers.post_div = 1;
+	}
+
+	ibias = cypress_map_clkf_to_ibias(rdev, dividers.whole_fb_div);
+
+	mpll_ad_func_cntl &= ~(CLKR_MASK |
+			       YCLK_POST_DIV_MASK |
+			       CLKF_MASK |
+			       CLKFRAC_MASK |
+			       IBIAS_MASK);
+	mpll_ad_func_cntl |= CLKR(dividers.ref_div);
+	mpll_ad_func_cntl |= YCLK_POST_DIV(dividers.post_div);
+	mpll_ad_func_cntl |= CLKF(dividers.whole_fb_div);
+	mpll_ad_func_cntl |= CLKFRAC(dividers.frac_fb_div);
+	mpll_ad_func_cntl |= IBIAS(ibias);
+
+	if (dividers.vco_mode)
+		mpll_ad_func_cntl_2 |= VCO_MODE;
+	else
+		mpll_ad_func_cntl_2 &= ~VCO_MODE;
+
+	if (pi->mem_gddr5) {
+		mpll_dq_func_cntl &= ~(CLKR_MASK |
+				       YCLK_POST_DIV_MASK |
+				       CLKF_MASK |
+				       CLKFRAC_MASK |
+				       IBIAS_MASK);
+		mpll_dq_func_cntl |= CLKR(dividers.ref_div);
+		mpll_dq_func_cntl |= YCLK_POST_DIV(dividers.post_div);
+		mpll_dq_func_cntl |= CLKF(dividers.whole_fb_div);
+		mpll_dq_func_cntl |= CLKFRAC(dividers.frac_fb_div);
+		mpll_dq_func_cntl |= IBIAS(ibias);
+
+		if (strobe_mode)
+			mpll_dq_func_cntl &= ~PDNB;
+		else
+			mpll_dq_func_cntl |= PDNB;
+
+		if (dividers.vco_mode)
+			mpll_dq_func_cntl_2 |= VCO_MODE;
+		else
+			mpll_dq_func_cntl_2 &= ~VCO_MODE;
+	}
+
+	if (pi->mclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 vco_freq = memory_clock * dividers.post_div;
+
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+						     ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
+			u32 reference_clock = rdev->clock.mpll.reference_freq;
+			u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
+			u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
+			u32 clk_v = ss.percentage *
+				(0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
+
+			mpll_ss1 &= ~CLKV_MASK;
+			mpll_ss1 |= CLKV(clk_v);
+
+			mpll_ss2 &= ~CLKS_MASK;
+			mpll_ss2 |= CLKS(clk_s);
+		}
+	}
+
+	dll_speed = rv740_get_dll_speed(pi->mem_gddr5,
+					memory_clock);
+
+	mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;
+	mclk_pwrmgt_cntl |= DLL_SPEED(dll_speed);
+	if (dll_state_on)
+		mclk_pwrmgt_cntl |= (MRDCKA0_PDNB |
+				     MRDCKA1_PDNB |
+				     MRDCKB0_PDNB |
+				     MRDCKB1_PDNB |
+				     MRDCKC0_PDNB |
+				     MRDCKC1_PDNB |
+				     MRDCKD0_PDNB |
+				     MRDCKD1_PDNB);
+	else
+		mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB |
+				      MRDCKA1_PDNB |
+				      MRDCKB0_PDNB |
+				      MRDCKB1_PDNB |
+				      MRDCKC0_PDNB |
+				      MRDCKC1_PDNB |
+				      MRDCKD0_PDNB |
+				      MRDCKD1_PDNB);
+
+
+	mclk->mclk_value = cpu_to_be32(memory_clock);
+	mclk->vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
+	mclk->vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
+	mclk->vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
+	mclk->vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
+	mclk->vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	mclk->vDLL_CNTL = cpu_to_be32(dll_cntl);
+	mclk->vMPLL_SS = cpu_to_be32(mpll_ss1);
+	mclk->vMPLL_SS2 = cpu_to_be32(mpll_ss2);
+
+	return 0;
+}
+
+static void ni_populate_smc_sp(struct radeon_device *rdev,
+			       struct radeon_ps *radeon_state,
+			       NISLANDS_SMC_SWSTATE *smc_state)
+{
+	struct ni_ps *ps = ni_get_ps(radeon_state);
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	int i;
+
+	for (i = 0; i < ps->performance_level_count - 1; i++)
+		smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);
+
+	smc_state->levels[ps->performance_level_count - 1].bSP =
+		cpu_to_be32(pi->psp);
+}
+
+static int ni_convert_power_level_to_smc(struct radeon_device *rdev,
+					 struct rv7xx_pl *pl,
+					 NISLANDS_SMC_HW_PERFORMANCE_LEVEL *level)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+        struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	int ret;
+	bool dll_state_on;
+	u16 std_vddc;
+	u32 tmp = RREG32(DC_STUTTER_CNTL);
+
+	level->gen2PCIE = pi->pcie_gen2 ?
+		((pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0) : 0;
+
+	ret = ni_populate_sclk_value(rdev, pl->sclk, &level->sclk);
+	if (ret)
+		return ret;
+
+	level->mcFlags =  0;
+	if (pi->mclk_stutter_mode_threshold &&
+	    (pl->mclk <= pi->mclk_stutter_mode_threshold) &&
+	    !eg_pi->uvd_enabled &&
+	    (tmp & DC_STUTTER_ENABLE_A) &&
+	    (tmp & DC_STUTTER_ENABLE_B))
+		level->mcFlags |= NISLANDS_SMC_MC_STUTTER_EN;
+
+	if (pi->mem_gddr5) {
+		if (pl->mclk > pi->mclk_edc_enable_threshold)
+			level->mcFlags |= NISLANDS_SMC_MC_EDC_RD_FLAG;
+		if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold)
+			level->mcFlags |= NISLANDS_SMC_MC_EDC_WR_FLAG;
+
+		level->strobeMode = cypress_get_strobe_mode_settings(rdev, pl->mclk);
+
+		if (level->strobeMode & NISLANDS_SMC_STROBE_ENABLE) {
+			if (cypress_get_mclk_frequency_ratio(rdev, pl->mclk, true) >=
+			    ((RREG32(MC_SEQ_MISC7) >> 16) & 0xf))
+				dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
+			else
+				dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false;
+		} else {
+			dll_state_on = false;
+			if (pl->mclk > ni_pi->mclk_rtt_mode_threshold)
+				level->mcFlags |= NISLANDS_SMC_MC_RTT_ENABLE;
+		}
+
+		ret = ni_populate_mclk_value(rdev, pl->sclk, pl->mclk,
+					     &level->mclk,
+					     (level->strobeMode & NISLANDS_SMC_STROBE_ENABLE) != 0,
+					     dll_state_on);
+	} else
+		ret = ni_populate_mclk_value(rdev, pl->sclk, pl->mclk, &level->mclk, 1, 1);
+
+	if (ret)
+		return ret;
+
+	ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
+					pl->vddc, &level->vddc);
+	if (ret)
+		return ret;
+
+	ret = ni_get_std_voltage_value(rdev, &level->vddc, &std_vddc);
+	if (ret)
+		return ret;
+
+	ni_populate_std_voltage_value(rdev, std_vddc,
+				      level->vddc.index, &level->std_vddc);
+
+	if (eg_pi->vddci_control) {
+		ret = ni_populate_voltage_value(rdev, &eg_pi->vddci_voltage_table,
+						pl->vddci, &level->vddci);
+		if (ret)
+			return ret;
+	}
+
+	ni_populate_mvdd_value(rdev, pl->mclk, &level->mvdd);
+
+	return ret;
+}
+
+static int ni_populate_smc_t(struct radeon_device *rdev,
+			     struct radeon_ps *radeon_state,
+			     NISLANDS_SMC_SWSTATE *smc_state)
+{
+        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	u32 a_t;
+	u32 t_l, t_h;
+	u32 high_bsp;
+	int i, ret;
+
+	if (state->performance_level_count >= 9)
+		return -EINVAL;
+
+	if (state->performance_level_count < 2) {
+		a_t = CG_R(0xffff) | CG_L(0);
+		smc_state->levels[0].aT = cpu_to_be32(a_t);
+		return 0;
+	}
+
+	smc_state->levels[0].aT = cpu_to_be32(0);
+
+	for (i = 0; i <= state->performance_level_count - 2; i++) {
+		if (eg_pi->uvd_enabled)
+			ret = r600_calculate_at(
+				1000 * (i * (eg_pi->smu_uvd_hs ? 2 : 8) + 2),
+				100 * R600_AH_DFLT,
+				state->performance_levels[i + 1].sclk,
+				state->performance_levels[i].sclk,
+				&t_l,
+				&t_h);
+		else
+			ret = r600_calculate_at(
+				1000 * (i + 1),
+				100 * R600_AH_DFLT,
+				state->performance_levels[i + 1].sclk,
+				state->performance_levels[i].sclk,
+				&t_l,
+				&t_h);
+
+		if (ret) {
+			t_h = (i + 1) * 1000 - 50 * R600_AH_DFLT;
+			t_l = (i + 1) * 1000 + 50 * R600_AH_DFLT;
+		}
+
+		a_t = be32_to_cpu(smc_state->levels[i].aT) & ~CG_R_MASK;
+		a_t |= CG_R(t_l * pi->bsp / 20000);
+		smc_state->levels[i].aT = cpu_to_be32(a_t);
+
+		high_bsp = (i == state->performance_level_count - 2) ?
+			pi->pbsp : pi->bsp;
+
+		a_t = CG_R(0xffff) | CG_L(t_h * high_bsp / 20000);
+		smc_state->levels[i + 1].aT = cpu_to_be32(a_t);
+	}
+
+	return 0;
+}
+
+static int ni_populate_power_containment_values(struct radeon_device *rdev,
+						struct radeon_ps *radeon_state,
+						NISLANDS_SMC_SWSTATE *smc_state)
+{
+        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	u32 prev_sclk;
+	u32 max_sclk;
+	u32 min_sclk;
+	int i, ret;
+	u32 tdp_limit;
+	u32 near_tdp_limit;
+	u32 power_boost_limit;
+	u8 max_ps_percent;
+
+	if (ni_pi->enable_power_containment == false)
+		return 0;
+
+	if (state->performance_level_count == 0)
+		return -EINVAL;
+
+	if (smc_state->levelCount != state->performance_level_count)
+		return -EINVAL;
+
+	ret = ni_calculate_adjusted_tdp_limits(rdev,
+					       false, /* ??? */
+					       rdev->pm.dpm.tdp_adjustment,
+					       &tdp_limit,
+					       &near_tdp_limit);
+	if (ret)
+		return ret;
+
+	power_boost_limit = ni_calculate_power_boost_limit(rdev, radeon_state, near_tdp_limit);
+
+	ret = rv770_write_smc_sram_dword(rdev,
+					 pi->state_table_start +
+					 offsetof(NISLANDS_SMC_STATETABLE, dpm2Params) +
+					 offsetof(PP_NIslands_DPM2Parameters, PowerBoostLimit),
+					 ni_scale_power_for_smc(power_boost_limit, ni_get_smc_power_scaling_factor(rdev)),
+					 pi->sram_end);
+	if (ret)
+		power_boost_limit = 0;
+
+	smc_state->levels[0].dpm2.MaxPS = 0;
+	smc_state->levels[0].dpm2.NearTDPDec = 0;
+	smc_state->levels[0].dpm2.AboveSafeInc = 0;
+	smc_state->levels[0].dpm2.BelowSafeInc = 0;
+	smc_state->levels[0].stateFlags |= power_boost_limit ? PPSMC_STATEFLAG_POWERBOOST : 0;
+
+	for (i = 1; i < state->performance_level_count; i++) {
+		prev_sclk = state->performance_levels[i-1].sclk;
+		max_sclk  = state->performance_levels[i].sclk;
+		max_ps_percent = (i != (state->performance_level_count - 1)) ?
+			NISLANDS_DPM2_MAXPS_PERCENT_M : NISLANDS_DPM2_MAXPS_PERCENT_H;
+
+		if (max_sclk < prev_sclk)
+			return -EINVAL;
+
+		if ((max_ps_percent == 0) || (prev_sclk == max_sclk) || eg_pi->uvd_enabled)
+			min_sclk = max_sclk;
+		else if (1 == i)
+			min_sclk = prev_sclk;
+		else
+			min_sclk = (prev_sclk * (u32)max_ps_percent) / 100;
+
+		if (min_sclk < state->performance_levels[0].sclk)
+			min_sclk = state->performance_levels[0].sclk;
+
+		if (min_sclk == 0)
+			return -EINVAL;
+
+		smc_state->levels[i].dpm2.MaxPS =
+			(u8)((NISLANDS_DPM2_MAX_PULSE_SKIP * (max_sclk - min_sclk)) / max_sclk);
+		smc_state->levels[i].dpm2.NearTDPDec = NISLANDS_DPM2_NEAR_TDP_DEC;
+		smc_state->levels[i].dpm2.AboveSafeInc = NISLANDS_DPM2_ABOVE_SAFE_INC;
+		smc_state->levels[i].dpm2.BelowSafeInc = NISLANDS_DPM2_BELOW_SAFE_INC;
+		smc_state->levels[i].stateFlags |=
+			((i != (state->performance_level_count - 1)) && power_boost_limit) ?
+			PPSMC_STATEFLAG_POWERBOOST : 0;
+	}
+
+	return 0;
+}
+
+static int ni_populate_sq_ramping_values(struct radeon_device *rdev,
+					 struct radeon_ps *radeon_state,
+					 NISLANDS_SMC_SWSTATE *smc_state)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	u32 sq_power_throttle;
+	u32 sq_power_throttle2;
+	bool enable_sq_ramping = ni_pi->enable_sq_ramping;
+	int i;
+
+	if (state->performance_level_count == 0)
+		return -EINVAL;
+
+	if (smc_state->levelCount != state->performance_level_count)
+		return -EINVAL;
+
+	if (rdev->pm.dpm.sq_ramping_threshold == 0)
+		return -EINVAL;
+
+	if (NISLANDS_DPM2_SQ_RAMP_MAX_POWER > (MAX_POWER_MASK >> MAX_POWER_SHIFT))
+		enable_sq_ramping = false;
+
+	if (NISLANDS_DPM2_SQ_RAMP_MIN_POWER > (MIN_POWER_MASK >> MIN_POWER_SHIFT))
+		enable_sq_ramping = false;
+
+	if (NISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA > (MAX_POWER_DELTA_MASK >> MAX_POWER_DELTA_SHIFT))
+		enable_sq_ramping = false;
+
+	if (NISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT))
+		enable_sq_ramping = false;
+
+	if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT))
+		enable_sq_ramping = false;
+
+	for (i = 0; i < state->performance_level_count; i++) {
+		sq_power_throttle  = 0;
+		sq_power_throttle2 = 0;
+
+		if ((state->performance_levels[i].sclk >= rdev->pm.dpm.sq_ramping_threshold) &&
+		    enable_sq_ramping) {
+			sq_power_throttle |= MAX_POWER(NISLANDS_DPM2_SQ_RAMP_MAX_POWER);
+			sq_power_throttle |= MIN_POWER(NISLANDS_DPM2_SQ_RAMP_MIN_POWER);
+			sq_power_throttle2 |= MAX_POWER_DELTA(NISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA);
+			sq_power_throttle2 |= STI_SIZE(NISLANDS_DPM2_SQ_RAMP_STI_SIZE);
+			sq_power_throttle2 |= LTI_RATIO(NISLANDS_DPM2_SQ_RAMP_LTI_RATIO);
+		} else {
+			sq_power_throttle |= MAX_POWER_MASK | MIN_POWER_MASK;
+			sq_power_throttle2 |= MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
+		}
+
+		smc_state->levels[i].SQPowerThrottle   = cpu_to_be32(sq_power_throttle);
+		smc_state->levels[i].SQPowerThrottle_2 = cpu_to_be32(sq_power_throttle2);
+	}
+
+	return 0;
+}
+
+static int ni_enable_power_containment(struct radeon_device *rdev,
+				       struct radeon_ps *radeon_new_state,
+				       bool enable)
+{
+        struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	PPSMC_Result smc_result;
+	int ret = 0;
+
+	if (ni_pi->enable_power_containment) {
+		if (enable) {
+			if (!r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
+				smc_result = rv770_send_msg_to_smc(rdev, PPSMC_TDPClampingActive);
+				if (smc_result != PPSMC_Result_OK) {
+					ret = -EINVAL;
+					ni_pi->pc_enabled = false;
+				} else {
+					ni_pi->pc_enabled = true;
+				}
+			}
+		} else {
+			smc_result = rv770_send_msg_to_smc(rdev, PPSMC_TDPClampingInactive);
+			if (smc_result != PPSMC_Result_OK)
+				ret = -EINVAL;
+			ni_pi->pc_enabled = false;
+		}
+	}
+
+	return ret;
+}
+
+static int ni_convert_power_state_to_smc(struct radeon_device *rdev,
+					 struct radeon_ps *radeon_state,
+					 NISLANDS_SMC_SWSTATE *smc_state)
+{
+        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	int i, ret;
+	u32 threshold = state->performance_levels[state->performance_level_count - 1].sclk * 100 / 100;
+
+	if (!(radeon_state->caps & ATOM_PPLIB_DISALLOW_ON_DC))
+		smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
+
+	smc_state->levelCount = 0;
+
+	if (state->performance_level_count > NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE)
+		return -EINVAL;
+
+	for (i = 0; i < state->performance_level_count; i++) {
+		ret = ni_convert_power_level_to_smc(rdev, &state->performance_levels[i],
+						    &smc_state->levels[i]);
+		smc_state->levels[i].arbRefreshState =
+			(u8)(NISLANDS_DRIVER_STATE_ARB_INDEX + i);
+
+		if (ret)
+			return ret;
+
+		if (ni_pi->enable_power_containment)
+			smc_state->levels[i].displayWatermark =
+				(state->performance_levels[i].sclk < threshold) ?
+				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
+		else
+			smc_state->levels[i].displayWatermark = (i < 2) ?
+				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
+
+		if (eg_pi->dynamic_ac_timing)
+			smc_state->levels[i].ACIndex = NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i;
+		else
+			smc_state->levels[i].ACIndex = 0;
+
+		smc_state->levelCount++;
+	}
+
+	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_watermark_threshold,
+				      cpu_to_be32(threshold / 512));
+
+	ni_populate_smc_sp(rdev, radeon_state, smc_state);
+
+	ret = ni_populate_power_containment_values(rdev, radeon_state, smc_state);
+	if (ret)
+		ni_pi->enable_power_containment = false;
+
+	ret = ni_populate_sq_ramping_values(rdev, radeon_state, smc_state);
+	if (ret)
+		ni_pi->enable_sq_ramping = false;
+
+	return ni_populate_smc_t(rdev, radeon_state, smc_state);
+}
+
+static int ni_upload_sw_state(struct radeon_device *rdev,
+			      struct radeon_ps *radeon_new_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u16 address = pi->state_table_start +
+		offsetof(NISLANDS_SMC_STATETABLE, driverState);
+	u16 state_size = sizeof(NISLANDS_SMC_SWSTATE) +
+		((NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1) * sizeof(NISLANDS_SMC_HW_PERFORMANCE_LEVEL));
+	int ret;
+	NISLANDS_SMC_SWSTATE *smc_state = kzalloc(state_size, GFP_KERNEL);
+
+	if (smc_state == NULL)
+		return -ENOMEM;
+
+	ret = ni_convert_power_state_to_smc(rdev, radeon_new_state, smc_state);
+	if (ret)
+		goto done;
+
+	ret = rv770_copy_bytes_to_smc(rdev, address, (u8 *)smc_state, state_size, pi->sram_end);
+
+done:
+	kfree(smc_state);
+
+	return ret;
+}
+
+static int ni_set_mc_special_registers(struct radeon_device *rdev,
+				       struct ni_mc_reg_table *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u8 i, j, k;
+	u32 temp_reg;
+
+	for (i = 0, j = table->last; i < table->last; i++) {
+		switch (table->mc_reg_address[i].s1) {
+		case MC_SEQ_MISC1 >> 2:
+			if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+			temp_reg = RREG32(MC_PMG_CMD_EMRS);
+			table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
+			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
+			for (k = 0; k < table->num_entries; k++)
+				table->mc_reg_table_entry[k].mc_data[j] =
+					((temp_reg & 0xffff0000)) |
+					((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
+			j++;
+			if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+
+			temp_reg = RREG32(MC_PMG_CMD_MRS);
+			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
+			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
+			for(k = 0; k < table->num_entries; k++) {
+				table->mc_reg_table_entry[k].mc_data[j] =
+					(temp_reg & 0xffff0000) |
+					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+				if (!pi->mem_gddr5)
+					table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
+			}
+			j++;
+			if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+			break;
+		case MC_SEQ_RESERVE_M >> 2:
+			temp_reg = RREG32(MC_PMG_CMD_MRS1);
+			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
+			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+			for (k = 0; k < table->num_entries; k++)
+				table->mc_reg_table_entry[k].mc_data[j] =
+					(temp_reg & 0xffff0000) |
+					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+			j++;
+			if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+			break;
+		default:
+			break;
+		}
+	}
+
+	table->last = j;
+
+	return 0;
+}
+
+static bool ni_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
+{
+	bool result = true;
+
+	switch (in_reg) {
+        case  MC_SEQ_RAS_TIMING >> 2:
+		*out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
+		break;
+        case MC_SEQ_CAS_TIMING >> 2:
+		*out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
+		break;
+        case MC_SEQ_MISC_TIMING >> 2:
+		*out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
+		break;
+        case MC_SEQ_MISC_TIMING2 >> 2:
+		*out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
+		break;
+        case MC_SEQ_RD_CTL_D0 >> 2:
+		*out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
+		break;
+        case MC_SEQ_RD_CTL_D1 >> 2:
+		*out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
+		break;
+        case MC_SEQ_WR_CTL_D0 >> 2:
+		*out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
+		break;
+        case MC_SEQ_WR_CTL_D1 >> 2:
+		*out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
+		break;
+        case MC_PMG_CMD_EMRS >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
+		break;
+        case MC_PMG_CMD_MRS >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
+		break;
+        case MC_PMG_CMD_MRS1 >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+		break;
+        case MC_SEQ_PMG_TIMING >> 2:
+		*out_reg = MC_SEQ_PMG_TIMING_LP >> 2;
+		break;
+        case MC_PMG_CMD_MRS2 >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_MRS2_LP >> 2;
+		break;
+        default:
+		result = false;
+		break;
+	}
+
+	return result;
+}
+
+static void ni_set_valid_flag(struct ni_mc_reg_table *table)
+{
+	u8 i, j;
+
+	for (i = 0; i < table->last; i++) {
+		for (j = 1; j < table->num_entries; j++) {
+			if (table->mc_reg_table_entry[j-1].mc_data[i] != table->mc_reg_table_entry[j].mc_data[i]) {
+				table->valid_flag |= 1 << i;
+				break;
+			}
+		}
+	}
+}
+
+static void ni_set_s0_mc_reg_index(struct ni_mc_reg_table *table)
+{
+	u32 i;
+	u16 address;
+
+	for (i = 0; i < table->last; i++)
+		table->mc_reg_address[i].s0 =
+			ni_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
+			address : table->mc_reg_address[i].s1;
+}
+
+static int ni_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
+				      struct ni_mc_reg_table *ni_table)
+{
+	u8 i, j;
+
+	if (table->last > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+		return -EINVAL;
+	if (table->num_entries > MAX_AC_TIMING_ENTRIES)
+		return -EINVAL;
+
+	for (i = 0; i < table->last; i++)
+		ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
+	ni_table->last = table->last;
+
+	for (i = 0; i < table->num_entries; i++) {
+		ni_table->mc_reg_table_entry[i].mclk_max =
+			table->mc_reg_table_entry[i].mclk_max;
+		for (j = 0; j < table->last; j++)
+			ni_table->mc_reg_table_entry[i].mc_data[j] =
+				table->mc_reg_table_entry[i].mc_data[j];
+	}
+	ni_table->num_entries = table->num_entries;
+
+	return 0;
+}
+
+static int ni_initialize_mc_reg_table(struct radeon_device *rdev)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	int ret;
+	struct atom_mc_reg_table *table;
+	struct ni_mc_reg_table *ni_table = &ni_pi->mc_reg_table;
+	u8 module_index = rv770_get_memory_module_index(rdev);
+
+        table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
+        if (!table)
+                return -ENOMEM;
+
+	WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
+	WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
+	WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
+	WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
+	WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
+	WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
+	WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
+	WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
+	WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
+	WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
+	WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
+	WREG32(MC_SEQ_PMG_TIMING_LP, RREG32(MC_SEQ_PMG_TIMING));
+	WREG32(MC_SEQ_PMG_CMD_MRS2_LP, RREG32(MC_PMG_CMD_MRS2));
+
+	ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
+
+        if (ret)
+                goto init_mc_done;
+
+	ret = ni_copy_vbios_mc_reg_table(table, ni_table);
+
+        if (ret)
+                goto init_mc_done;
+
+	ni_set_s0_mc_reg_index(ni_table);
+
+	ret = ni_set_mc_special_registers(rdev, ni_table);
+
+        if (ret)
+                goto init_mc_done;
+
+	ni_set_valid_flag(ni_table);
+
+init_mc_done:
+        kfree(table);
+
+	return ret;
+}
+
+static void ni_populate_mc_reg_addresses(struct radeon_device *rdev,
+					 SMC_NIslands_MCRegisters *mc_reg_table)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 i, j;
+
+	for (i = 0, j = 0; j < ni_pi->mc_reg_table.last; j++) {
+		if (ni_pi->mc_reg_table.valid_flag & (1 << j)) {
+			if (i >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+				break;
+			mc_reg_table->address[i].s0 =
+				cpu_to_be16(ni_pi->mc_reg_table.mc_reg_address[j].s0);
+			mc_reg_table->address[i].s1 =
+				cpu_to_be16(ni_pi->mc_reg_table.mc_reg_address[j].s1);
+			i++;
+		}
+	}
+	mc_reg_table->last = (u8)i;
+}
+
+
+static void ni_convert_mc_registers(struct ni_mc_reg_entry *entry,
+				    SMC_NIslands_MCRegisterSet *data,
+				    u32 num_entries, u32 valid_flag)
+{
+	u32 i, j;
+
+	for (i = 0, j = 0; j < num_entries; j++) {
+		if (valid_flag & (1 << j)) {
+			data->value[i] = cpu_to_be32(entry->mc_data[j]);
+			i++;
+		}
+	}
+}
+
+static void ni_convert_mc_reg_table_entry_to_smc(struct radeon_device *rdev,
+						 struct rv7xx_pl *pl,
+						 SMC_NIslands_MCRegisterSet *mc_reg_table_data)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 i = 0;
+
+	for (i = 0; i < ni_pi->mc_reg_table.num_entries; i++) {
+		if (pl->mclk <= ni_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max)
+			break;
+	}
+
+	if ((i == ni_pi->mc_reg_table.num_entries) && (i > 0))
+		--i;
+
+	ni_convert_mc_registers(&ni_pi->mc_reg_table.mc_reg_table_entry[i],
+				mc_reg_table_data,
+				ni_pi->mc_reg_table.last,
+				ni_pi->mc_reg_table.valid_flag);
+}
+
+static void ni_convert_mc_reg_table_to_smc(struct radeon_device *rdev,
+					   struct radeon_ps *radeon_state,
+					   SMC_NIslands_MCRegisters *mc_reg_table)
+{
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	int i;
+
+	for (i = 0; i < state->performance_level_count; i++) {
+		ni_convert_mc_reg_table_entry_to_smc(rdev,
+						     &state->performance_levels[i],
+						     &mc_reg_table->data[NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i]);
+	}
+}
+
+static int ni_populate_mc_reg_table(struct radeon_device *rdev,
+				    struct radeon_ps *radeon_boot_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+        struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct ni_ps *boot_state = ni_get_ps(radeon_boot_state);
+	SMC_NIslands_MCRegisters *mc_reg_table = &ni_pi->smc_mc_reg_table;
+
+	memset(mc_reg_table, 0, sizeof(SMC_NIslands_MCRegisters));
+
+	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_seq_index, 1);
+
+	ni_populate_mc_reg_addresses(rdev, mc_reg_table);
+
+	ni_convert_mc_reg_table_entry_to_smc(rdev, &boot_state->performance_levels[0],
+					     &mc_reg_table->data[0]);
+
+	ni_convert_mc_registers(&ni_pi->mc_reg_table.mc_reg_table_entry[0],
+				&mc_reg_table->data[1],
+				ni_pi->mc_reg_table.last,
+				ni_pi->mc_reg_table.valid_flag);
+
+	ni_convert_mc_reg_table_to_smc(rdev, radeon_boot_state, mc_reg_table);
+
+	return rv770_copy_bytes_to_smc(rdev, eg_pi->mc_reg_table_start,
+				       (u8 *)mc_reg_table,
+				       sizeof(SMC_NIslands_MCRegisters),
+				       pi->sram_end);
+}
+
+static int ni_upload_mc_reg_table(struct radeon_device *rdev,
+				  struct radeon_ps *radeon_new_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+        struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct ni_ps *ni_new_state = ni_get_ps(radeon_new_state);
+	SMC_NIslands_MCRegisters *mc_reg_table = &ni_pi->smc_mc_reg_table;
+	u16 address;
+
+	memset(mc_reg_table, 0, sizeof(SMC_NIslands_MCRegisters));
+
+	ni_convert_mc_reg_table_to_smc(rdev, radeon_new_state, mc_reg_table);
+
+	address = eg_pi->mc_reg_table_start +
+		(u16)offsetof(SMC_NIslands_MCRegisters, data[NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT]);
+
+	return rv770_copy_bytes_to_smc(rdev, address,
+				       (u8 *)&mc_reg_table->data[NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT],
+				       sizeof(SMC_NIslands_MCRegisterSet) * ni_new_state->performance_level_count,
+				       pi->sram_end);
+}
+
+static int ni_init_driver_calculated_leakage_table(struct radeon_device *rdev,
+						   PP_NIslands_CACTABLES *cac_tables)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 leakage = 0;
+	unsigned int i, j, table_size;
+	s32 t;
+	u32 smc_leakage, max_leakage = 0;
+	u32 scaling_factor;
+
+	table_size = eg_pi->vddc_voltage_table.count;
+
+	if (SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES < table_size)
+		table_size = SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;
+
+	scaling_factor = ni_get_smc_power_scaling_factor(rdev);
+
+	for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++) {
+		for (j = 0; j < table_size; j++) {
+			t = (1000 * ((i + 1) * 8));
+
+			if (t < ni_pi->cac_data.leakage_minimum_temperature)
+				t = ni_pi->cac_data.leakage_minimum_temperature;
+
+			ni_calculate_leakage_for_v_and_t(rdev,
+							 &ni_pi->cac_data.leakage_coefficients,
+							 eg_pi->vddc_voltage_table.entries[j].value,
+							 t,
+							 ni_pi->cac_data.i_leakage,
+							 &leakage);
+
+			smc_leakage = ni_scale_power_for_smc(leakage, scaling_factor) / 1000;
+			if (smc_leakage > max_leakage)
+				max_leakage = smc_leakage;
+
+			cac_tables->cac_lkge_lut[i][j] = cpu_to_be32(smc_leakage);
+		}
+	}
+
+	for (j = table_size; j < SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
+		for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++)
+			cac_tables->cac_lkge_lut[i][j] = cpu_to_be32(max_leakage);
+	}
+	return 0;
+}
+
+static int ni_init_simplified_leakage_table(struct radeon_device *rdev,
+					    PP_NIslands_CACTABLES *cac_tables)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_cac_leakage_table *leakage_table =
+		&rdev->pm.dpm.dyn_state.cac_leakage_table;
+	u32 i, j, table_size;
+	u32 smc_leakage, max_leakage = 0;
+	u32 scaling_factor;
+
+	if (!leakage_table)
+		return -EINVAL;
+
+	table_size = leakage_table->count;
+
+	if (eg_pi->vddc_voltage_table.count != table_size)
+		table_size = (eg_pi->vddc_voltage_table.count < leakage_table->count) ?
+			eg_pi->vddc_voltage_table.count : leakage_table->count;
+
+	if (SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES < table_size)
+		table_size = SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;
+
+	if (table_size == 0)
+		return -EINVAL;
+
+	scaling_factor = ni_get_smc_power_scaling_factor(rdev);
+
+	for (j = 0; j < table_size; j++) {
+		smc_leakage = leakage_table->entries[j].leakage;
+
+		if (smc_leakage > max_leakage)
+			max_leakage = smc_leakage;
+
+		for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++)
+			cac_tables->cac_lkge_lut[i][j] =
+				cpu_to_be32(ni_scale_power_for_smc(smc_leakage, scaling_factor));
+	}
+
+	for (j = table_size; j < SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
+		for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++)
+			cac_tables->cac_lkge_lut[i][j] =
+				cpu_to_be32(ni_scale_power_for_smc(max_leakage, scaling_factor));
+	}
+	return 0;
+}
+
+static int ni_initialize_smc_cac_tables(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	PP_NIslands_CACTABLES *cac_tables = NULL;
+	int i, ret;
+        u32 reg;
+
+	if (ni_pi->enable_cac == false)
+		return 0;
+
+	cac_tables = kzalloc(sizeof(PP_NIslands_CACTABLES), GFP_KERNEL);
+	if (!cac_tables)
+		return -ENOMEM;
+
+	reg = RREG32(CG_CAC_CTRL) & ~(TID_CNT_MASK | TID_UNIT_MASK);
+	reg |= (TID_CNT(ni_pi->cac_weights->tid_cnt) |
+		TID_UNIT(ni_pi->cac_weights->tid_unit));
+	WREG32(CG_CAC_CTRL, reg);
+
+	for (i = 0; i < NISLANDS_DCCAC_MAX_LEVELS; i++)
+		ni_pi->dc_cac_table[i] = ni_pi->cac_weights->dc_cac[i];
+
+	for (i = 0; i < SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES; i++)
+		cac_tables->cac_bif_lut[i] = ni_pi->cac_weights->pcie_cac[i];
+
+	ni_pi->cac_data.i_leakage = rdev->pm.dpm.cac_leakage;
+	ni_pi->cac_data.pwr_const = 0;
+	ni_pi->cac_data.dc_cac_value = ni_pi->dc_cac_table[NISLANDS_DCCAC_LEVEL_0];
+	ni_pi->cac_data.bif_cac_value = 0;
+	ni_pi->cac_data.mc_wr_weight = ni_pi->cac_weights->mc_write_weight;
+	ni_pi->cac_data.mc_rd_weight = ni_pi->cac_weights->mc_read_weight;
+	ni_pi->cac_data.allow_ovrflw = 0;
+	ni_pi->cac_data.l2num_win_tdp = ni_pi->lta_window_size;
+	ni_pi->cac_data.num_win_tdp = 0;
+	ni_pi->cac_data.lts_truncate_n = ni_pi->lts_truncate;
+
+	if (ni_pi->driver_calculate_cac_leakage)
+		ret = ni_init_driver_calculated_leakage_table(rdev, cac_tables);
+	else
+		ret = ni_init_simplified_leakage_table(rdev, cac_tables);
+
+	if (ret)
+		goto done_free;
+
+	cac_tables->pwr_const      = cpu_to_be32(ni_pi->cac_data.pwr_const);
+	cac_tables->dc_cacValue    = cpu_to_be32(ni_pi->cac_data.dc_cac_value);
+	cac_tables->bif_cacValue   = cpu_to_be32(ni_pi->cac_data.bif_cac_value);
+	cac_tables->AllowOvrflw    = ni_pi->cac_data.allow_ovrflw;
+	cac_tables->MCWrWeight     = ni_pi->cac_data.mc_wr_weight;
+	cac_tables->MCRdWeight     = ni_pi->cac_data.mc_rd_weight;
+	cac_tables->numWin_TDP     = ni_pi->cac_data.num_win_tdp;
+	cac_tables->l2numWin_TDP   = ni_pi->cac_data.l2num_win_tdp;
+	cac_tables->lts_truncate_n = ni_pi->cac_data.lts_truncate_n;
+
+	ret = rv770_copy_bytes_to_smc(rdev, ni_pi->cac_table_start, (u8 *)cac_tables,
+				      sizeof(PP_NIslands_CACTABLES), pi->sram_end);
+
+done_free:
+	if (ret) {
+		ni_pi->enable_cac = false;
+		ni_pi->enable_power_containment = false;
+	}
+
+	kfree(cac_tables);
+
+	return 0;
+}
+
+static int ni_initialize_hardware_cac_manager(struct radeon_device *rdev)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	u32 reg;
+
+	if (!ni_pi->enable_cac ||
+	    !ni_pi->cac_configuration_required)
+		return 0;
+
+	if (ni_pi->cac_weights == NULL)
+		return -EINVAL;
+
+	reg = RREG32_CG(CG_CAC_REGION_1_WEIGHT_0) & ~(WEIGHT_TCP_SIG0_MASK |
+						      WEIGHT_TCP_SIG1_MASK |
+						      WEIGHT_TA_SIG_MASK);
+	reg |= (WEIGHT_TCP_SIG0(ni_pi->cac_weights->weight_tcp_sig0) |
+		WEIGHT_TCP_SIG1(ni_pi->cac_weights->weight_tcp_sig1) |
+		WEIGHT_TA_SIG(ni_pi->cac_weights->weight_ta_sig));
+	WREG32_CG(CG_CAC_REGION_1_WEIGHT_0, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_1_WEIGHT_1) & ~(WEIGHT_TCC_EN0_MASK |
+						      WEIGHT_TCC_EN1_MASK |
+						      WEIGHT_TCC_EN2_MASK);
+	reg |= (WEIGHT_TCC_EN0(ni_pi->cac_weights->weight_tcc_en0) |
+		WEIGHT_TCC_EN1(ni_pi->cac_weights->weight_tcc_en1) |
+		WEIGHT_TCC_EN2(ni_pi->cac_weights->weight_tcc_en2));
+	WREG32_CG(CG_CAC_REGION_1_WEIGHT_1, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_2_WEIGHT_0) & ~(WEIGHT_CB_EN0_MASK |
+						      WEIGHT_CB_EN1_MASK |
+						      WEIGHT_CB_EN2_MASK |
+						      WEIGHT_CB_EN3_MASK);
+	reg |= (WEIGHT_CB_EN0(ni_pi->cac_weights->weight_cb_en0) |
+		WEIGHT_CB_EN1(ni_pi->cac_weights->weight_cb_en1) |
+		WEIGHT_CB_EN2(ni_pi->cac_weights->weight_cb_en2) |
+		WEIGHT_CB_EN3(ni_pi->cac_weights->weight_cb_en3));
+	WREG32_CG(CG_CAC_REGION_2_WEIGHT_0, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_2_WEIGHT_1) & ~(WEIGHT_DB_SIG0_MASK |
+						      WEIGHT_DB_SIG1_MASK |
+						      WEIGHT_DB_SIG2_MASK |
+						      WEIGHT_DB_SIG3_MASK);
+	reg |= (WEIGHT_DB_SIG0(ni_pi->cac_weights->weight_db_sig0) |
+		WEIGHT_DB_SIG1(ni_pi->cac_weights->weight_db_sig1) |
+		WEIGHT_DB_SIG2(ni_pi->cac_weights->weight_db_sig2) |
+		WEIGHT_DB_SIG3(ni_pi->cac_weights->weight_db_sig3));
+	WREG32_CG(CG_CAC_REGION_2_WEIGHT_1, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_2_WEIGHT_2) & ~(WEIGHT_SXM_SIG0_MASK |
+						      WEIGHT_SXM_SIG1_MASK |
+						      WEIGHT_SXM_SIG2_MASK |
+						      WEIGHT_SXS_SIG0_MASK |
+						      WEIGHT_SXS_SIG1_MASK);
+	reg |= (WEIGHT_SXM_SIG0(ni_pi->cac_weights->weight_sxm_sig0) |
+		WEIGHT_SXM_SIG1(ni_pi->cac_weights->weight_sxm_sig1) |
+		WEIGHT_SXM_SIG2(ni_pi->cac_weights->weight_sxm_sig2) |
+		WEIGHT_SXS_SIG0(ni_pi->cac_weights->weight_sxs_sig0) |
+		WEIGHT_SXS_SIG1(ni_pi->cac_weights->weight_sxs_sig1));
+	WREG32_CG(CG_CAC_REGION_2_WEIGHT_2, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_3_WEIGHT_0) & ~(WEIGHT_XBR_0_MASK |
+						      WEIGHT_XBR_1_MASK |
+						      WEIGHT_XBR_2_MASK |
+						      WEIGHT_SPI_SIG0_MASK);
+	reg |= (WEIGHT_XBR_0(ni_pi->cac_weights->weight_xbr_0) |
+		WEIGHT_XBR_1(ni_pi->cac_weights->weight_xbr_1) |
+		WEIGHT_XBR_2(ni_pi->cac_weights->weight_xbr_2) |
+		WEIGHT_SPI_SIG0(ni_pi->cac_weights->weight_spi_sig0));
+	WREG32_CG(CG_CAC_REGION_3_WEIGHT_0, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_3_WEIGHT_1) & ~(WEIGHT_SPI_SIG1_MASK |
+						      WEIGHT_SPI_SIG2_MASK |
+						      WEIGHT_SPI_SIG3_MASK |
+						      WEIGHT_SPI_SIG4_MASK |
+						      WEIGHT_SPI_SIG5_MASK);
+	reg |= (WEIGHT_SPI_SIG1(ni_pi->cac_weights->weight_spi_sig1) |
+		WEIGHT_SPI_SIG2(ni_pi->cac_weights->weight_spi_sig2) |
+		WEIGHT_SPI_SIG3(ni_pi->cac_weights->weight_spi_sig3) |
+		WEIGHT_SPI_SIG4(ni_pi->cac_weights->weight_spi_sig4) |
+		WEIGHT_SPI_SIG5(ni_pi->cac_weights->weight_spi_sig5));
+	WREG32_CG(CG_CAC_REGION_3_WEIGHT_1, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_0) & ~(WEIGHT_LDS_SIG0_MASK |
+						      WEIGHT_LDS_SIG1_MASK |
+						      WEIGHT_SC_MASK);
+	reg |= (WEIGHT_LDS_SIG0(ni_pi->cac_weights->weight_lds_sig0) |
+		WEIGHT_LDS_SIG1(ni_pi->cac_weights->weight_lds_sig1) |
+		WEIGHT_SC(ni_pi->cac_weights->weight_sc));
+	WREG32_CG(CG_CAC_REGION_4_WEIGHT_0, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_1) & ~(WEIGHT_BIF_MASK |
+						      WEIGHT_CP_MASK |
+						      WEIGHT_PA_SIG0_MASK |
+						      WEIGHT_PA_SIG1_MASK |
+						      WEIGHT_VGT_SIG0_MASK);
+	reg |= (WEIGHT_BIF(ni_pi->cac_weights->weight_bif) |
+		WEIGHT_CP(ni_pi->cac_weights->weight_cp) |
+		WEIGHT_PA_SIG0(ni_pi->cac_weights->weight_pa_sig0) |
+		WEIGHT_PA_SIG1(ni_pi->cac_weights->weight_pa_sig1) |
+		WEIGHT_VGT_SIG0(ni_pi->cac_weights->weight_vgt_sig0));
+	WREG32_CG(CG_CAC_REGION_4_WEIGHT_1, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_2) & ~(WEIGHT_VGT_SIG1_MASK |
+						      WEIGHT_VGT_SIG2_MASK |
+						      WEIGHT_DC_SIG0_MASK |
+						      WEIGHT_DC_SIG1_MASK |
+						      WEIGHT_DC_SIG2_MASK);
+	reg |= (WEIGHT_VGT_SIG1(ni_pi->cac_weights->weight_vgt_sig1) |
+		WEIGHT_VGT_SIG2(ni_pi->cac_weights->weight_vgt_sig2) |
+		WEIGHT_DC_SIG0(ni_pi->cac_weights->weight_dc_sig0) |
+		WEIGHT_DC_SIG1(ni_pi->cac_weights->weight_dc_sig1) |
+		WEIGHT_DC_SIG2(ni_pi->cac_weights->weight_dc_sig2));
+	WREG32_CG(CG_CAC_REGION_4_WEIGHT_2, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_3) & ~(WEIGHT_DC_SIG3_MASK |
+						      WEIGHT_UVD_SIG0_MASK |
+						      WEIGHT_UVD_SIG1_MASK |
+						      WEIGHT_SPARE0_MASK |
+						      WEIGHT_SPARE1_MASK);
+	reg |= (WEIGHT_DC_SIG3(ni_pi->cac_weights->weight_dc_sig3) |
+		WEIGHT_UVD_SIG0(ni_pi->cac_weights->weight_uvd_sig0) |
+		WEIGHT_UVD_SIG1(ni_pi->cac_weights->weight_uvd_sig1) |
+		WEIGHT_SPARE0(ni_pi->cac_weights->weight_spare0) |
+		WEIGHT_SPARE1(ni_pi->cac_weights->weight_spare1));
+	WREG32_CG(CG_CAC_REGION_4_WEIGHT_3, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_5_WEIGHT_0) & ~(WEIGHT_SQ_VSP_MASK |
+						      WEIGHT_SQ_VSP0_MASK);
+	reg |= (WEIGHT_SQ_VSP(ni_pi->cac_weights->weight_sq_vsp) |
+		WEIGHT_SQ_VSP0(ni_pi->cac_weights->weight_sq_vsp0));
+	WREG32_CG(CG_CAC_REGION_5_WEIGHT_0, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_5_WEIGHT_1) & ~(WEIGHT_SQ_GPR_MASK);
+	reg |= WEIGHT_SQ_GPR(ni_pi->cac_weights->weight_sq_gpr);
+	WREG32_CG(CG_CAC_REGION_5_WEIGHT_1, reg);
+
+	reg = RREG32_CG(CG_CAC_REGION_4_OVERRIDE_4) & ~(OVR_MODE_SPARE_0_MASK |
+							OVR_VAL_SPARE_0_MASK |
+							OVR_MODE_SPARE_1_MASK |
+							OVR_VAL_SPARE_1_MASK);
+	reg |= (OVR_MODE_SPARE_0(ni_pi->cac_weights->ovr_mode_spare_0) |
+		OVR_VAL_SPARE_0(ni_pi->cac_weights->ovr_val_spare_0) |
+		OVR_MODE_SPARE_1(ni_pi->cac_weights->ovr_mode_spare_1) |
+		OVR_VAL_SPARE_1(ni_pi->cac_weights->ovr_val_spare_1));
+	WREG32_CG(CG_CAC_REGION_4_OVERRIDE_4, reg);
+
+	reg = RREG32(SQ_CAC_THRESHOLD) & ~(VSP_MASK |
+					   VSP0_MASK |
+					   GPR_MASK);
+	reg |= (VSP(ni_pi->cac_weights->vsp) |
+		VSP0(ni_pi->cac_weights->vsp0) |
+		GPR(ni_pi->cac_weights->gpr));
+	WREG32(SQ_CAC_THRESHOLD, reg);
+
+	reg = (MCDW_WR_ENABLE |
+	       MCDX_WR_ENABLE |
+	       MCDY_WR_ENABLE |
+	       MCDZ_WR_ENABLE |
+	       INDEX(0x09D4));
+	WREG32(MC_CG_CONFIG, reg);
+
+	reg = (READ_WEIGHT(ni_pi->cac_weights->mc_read_weight) |
+	       WRITE_WEIGHT(ni_pi->cac_weights->mc_write_weight) |
+	       ALLOW_OVERFLOW);
+	WREG32(MC_CG_DATAPORT, reg);
+
+	return 0;
+}
+
+static int ni_enable_smc_cac(struct radeon_device *rdev,
+			     struct radeon_ps *radeon_new_state,
+			     bool enable)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	int ret = 0;
+	PPSMC_Result smc_result;
+
+	if (ni_pi->enable_cac) {
+		if (enable) {
+			if (!r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
+				smc_result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_CollectCAC_PowerCorreln);
+
+				if (ni_pi->support_cac_long_term_average) {
+					smc_result = rv770_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgEnable);
+					if (PPSMC_Result_OK != smc_result)
+						ni_pi->support_cac_long_term_average = false;
+				}
+
+				smc_result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableCac);
+				if (PPSMC_Result_OK != smc_result)
+					ret = -EINVAL;
+
+				ni_pi->cac_enabled = (PPSMC_Result_OK == smc_result) ? true : false;
+			}
+		} else if (ni_pi->cac_enabled) {
+			smc_result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableCac);
+
+			ni_pi->cac_enabled = false;
+
+			if (ni_pi->support_cac_long_term_average) {
+				smc_result = rv770_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgDisable);
+				if (PPSMC_Result_OK != smc_result)
+					ni_pi->support_cac_long_term_average = false;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int ni_pcie_performance_request(struct radeon_device *rdev,
+				       u8 perf_req, bool advertise)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+#if defined(CONFIG_ACPI)
+	if ((perf_req == PCIE_PERF_REQ_PECI_GEN1) ||
+            (perf_req == PCIE_PERF_REQ_PECI_GEN2)) {
+		if (eg_pi->pcie_performance_request_registered == false)
+			radeon_acpi_pcie_notify_device_ready(rdev);
+		eg_pi->pcie_performance_request_registered = true;
+		return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise);
+	} else if ((perf_req == PCIE_PERF_REQ_REMOVE_REGISTRY) &&
+                   eg_pi->pcie_performance_request_registered) {
+		eg_pi->pcie_performance_request_registered = false;
+		return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise);
+	}
+#endif
+	return 0;
+}
+
+static int ni_advertise_gen2_capability(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 tmp;
+
+        tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+
+        if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+            (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
+                pi->pcie_gen2 = true;
+        else
+		pi->pcie_gen2 = false;
+
+	if (!pi->pcie_gen2)
+		ni_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, true);
+
+	return 0;
+}
+
+static void ni_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
+					    bool enable)
+{
+        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+        u32 tmp, bif;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+
+	if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+	    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+		if (enable) {
+			if (!pi->boot_in_gen2) {
+				bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
+				bif |= CG_CLIENT_REQ(0xd);
+				WREG32(CG_BIF_REQ_AND_RSP, bif);
+			}
+			tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+			tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
+			tmp |= LC_GEN2_EN_STRAP;
+
+			tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT;
+			WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+			udelay(10);
+			tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
+			WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+		} else {
+			if (!pi->boot_in_gen2) {
+				bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
+				bif |= CG_CLIENT_REQ(0xd);
+				WREG32(CG_BIF_REQ_AND_RSP, bif);
+
+				tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+				tmp &= ~LC_GEN2_EN_STRAP;
+			}
+			WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+		}
+	}
+}
+
+static void ni_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
+					bool enable)
+{
+	ni_enable_bif_dynamic_pcie_gen2(rdev, enable);
+
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
+	else
+                WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
+}
+
+void ni_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
+					   struct radeon_ps *new_ps,
+					   struct radeon_ps *old_ps)
+{
+	struct ni_ps *new_state = ni_get_ps(new_ps);
+	struct ni_ps *current_state = ni_get_ps(old_ps);
+
+	if ((new_ps->vclk == old_ps->vclk) &&
+	    (new_ps->dclk == old_ps->dclk))
+		return;
+
+	if (new_state->performance_levels[new_state->performance_level_count - 1].sclk >=
+	    current_state->performance_levels[current_state->performance_level_count - 1].sclk)
+		return;
+
+	radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
+}
+
+void ni_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
+					  struct radeon_ps *new_ps,
+					  struct radeon_ps *old_ps)
+{
+	struct ni_ps *new_state = ni_get_ps(new_ps);
+	struct ni_ps *current_state = ni_get_ps(old_ps);
+
+	if ((new_ps->vclk == old_ps->vclk) &&
+	    (new_ps->dclk == old_ps->dclk))
+		return;
+
+	if (new_state->performance_levels[new_state->performance_level_count - 1].sclk <
+	    current_state->performance_levels[current_state->performance_level_count - 1].sclk)
+		return;
+
+	radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
+}
+
+void ni_dpm_setup_asic(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	ni_read_clock_registers(rdev);
+	btc_read_arb_registers(rdev);
+	rv770_get_memory_type(rdev);
+	if (eg_pi->pcie_performance_request)
+		ni_advertise_gen2_capability(rdev);
+	rv770_get_pcie_gen2_status(rdev);
+	rv770_enable_acpi_pm(rdev);
+}
+
+void ni_update_current_ps(struct radeon_device *rdev,
+			  struct radeon_ps *rps)
+{
+	struct ni_ps *new_ps = ni_get_ps(rps);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+        struct ni_power_info *ni_pi = ni_get_pi(rdev);
+
+	eg_pi->current_rps = *rps;
+	ni_pi->current_ps = *new_ps;
+	eg_pi->current_rps.ps_priv = &ni_pi->current_ps;
+}
+
+void ni_update_requested_ps(struct radeon_device *rdev,
+			    struct radeon_ps *rps)
+{
+	struct ni_ps *new_ps = ni_get_ps(rps);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+        struct ni_power_info *ni_pi = ni_get_pi(rdev);
+
+	eg_pi->requested_rps = *rps;
+	ni_pi->requested_ps = *new_ps;
+	eg_pi->requested_rps.ps_priv = &ni_pi->requested_ps;
+}
+
+int ni_dpm_enable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+	int ret;
+
+	if (pi->gfx_clock_gating)
+		ni_cg_clockgating_default(rdev);
+        if (btc_dpm_enabled(rdev))
+                return -EINVAL;
+	if (pi->mg_clock_gating)
+		ni_mg_clockgating_default(rdev);
+	if (eg_pi->ls_clock_gating)
+		ni_ls_clockgating_default(rdev);
+	if (pi->voltage_control) {
+		rv770_enable_voltage_control(rdev, true);
+		ret = cypress_construct_voltage_tables(rdev);
+		if (ret) {
+			DRM_ERROR("cypress_construct_voltage_tables failed\n");
+			return ret;
+		}
+	}
+	if (eg_pi->dynamic_ac_timing) {
+		ret = ni_initialize_mc_reg_table(rdev);
+		if (ret)
+			eg_pi->dynamic_ac_timing = false;
+	}
+	if (pi->dynamic_ss)
+		cypress_enable_spread_spectrum(rdev, true);
+	if (pi->thermal_protection)
+		rv770_enable_thermal_protection(rdev, true);
+	rv770_setup_bsp(rdev);
+	rv770_program_git(rdev);
+	rv770_program_tp(rdev);
+	rv770_program_tpp(rdev);
+	rv770_program_sstp(rdev);
+	cypress_enable_display_gap(rdev);
+	rv770_program_vc(rdev);
+	if (pi->dynamic_pcie_gen2)
+		ni_enable_dynamic_pcie_gen2(rdev, true);
+	ret = rv770_upload_firmware(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_upload_firmware failed\n");
+		return ret;
+	}
+	ret = ni_process_firmware_header(rdev);
+	if (ret) {
+		DRM_ERROR("ni_process_firmware_header failed\n");
+		return ret;
+	}
+	ret = ni_initial_switch_from_arb_f0_to_f1(rdev);
+	if (ret) {
+		DRM_ERROR("ni_initial_switch_from_arb_f0_to_f1 failed\n");
+		return ret;
+	}
+	ret = ni_init_smc_table(rdev);
+	if (ret) {
+		DRM_ERROR("ni_init_smc_table failed\n");
+		return ret;
+	}
+	ret = ni_init_smc_spll_table(rdev);
+	if (ret) {
+		DRM_ERROR("ni_init_smc_spll_table failed\n");
+		return ret;
+	}
+	ret = ni_init_arb_table_index(rdev);
+	if (ret) {
+		DRM_ERROR("ni_init_arb_table_index failed\n");
+		return ret;
+	}
+	if (eg_pi->dynamic_ac_timing) {
+		ret = ni_populate_mc_reg_table(rdev, boot_ps);
+		if (ret) {
+			DRM_ERROR("ni_populate_mc_reg_table failed\n");
+			return ret;
+		}
+	}
+	ret = ni_initialize_smc_cac_tables(rdev);
+	if (ret) {
+		DRM_ERROR("ni_initialize_smc_cac_tables failed\n");
+		return ret;
+	}
+	ret = ni_initialize_hardware_cac_manager(rdev);
+	if (ret) {
+		DRM_ERROR("ni_initialize_hardware_cac_manager failed\n");
+		return ret;
+	}
+	ret = ni_populate_smc_tdp_limits(rdev, boot_ps);
+	if (ret) {
+		DRM_ERROR("ni_populate_smc_tdp_limits failed\n");
+		return ret;
+	}
+	ni_program_response_times(rdev);
+	r7xx_start_smc(rdev);
+	ret = cypress_notify_smc_display_change(rdev, false);
+	if (ret) {
+		DRM_ERROR("cypress_notify_smc_display_change failed\n");
+		return ret;
+	}
+	cypress_enable_sclk_control(rdev, true);
+	if (eg_pi->memory_transition)
+		cypress_enable_mclk_control(rdev, true);
+	cypress_start_dpm(rdev);
+	if (pi->gfx_clock_gating)
+		ni_gfx_clockgating_enable(rdev, true);
+	if (pi->mg_clock_gating)
+		ni_mg_clockgating_enable(rdev, true);
+	if (eg_pi->ls_clock_gating)
+		ni_ls_clockgating_enable(rdev, true);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		PPSMC_Result result;
+
+		ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, 0xff * 1000);
+		if (ret)
+			return ret;
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+		result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
+
+		if (result != PPSMC_Result_OK)
+			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
+	}
+
+	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+	ni_update_current_ps(rdev, boot_ps);
+
+	return 0;
+}
+
+void ni_dpm_disable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+
+	if (!btc_dpm_enabled(rdev))
+		return;
+	rv770_clear_vc(rdev);
+	if (pi->thermal_protection)
+		rv770_enable_thermal_protection(rdev, false);
+	ni_enable_power_containment(rdev, boot_ps, false);
+	ni_enable_smc_cac(rdev, boot_ps, false);
+	cypress_enable_spread_spectrum(rdev, false);
+	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, false);
+	if (pi->dynamic_pcie_gen2)
+		ni_enable_dynamic_pcie_gen2(rdev, false);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		rdev->irq.dpm_thermal = false;
+		radeon_irq_set(rdev);
+	}
+
+	if (pi->gfx_clock_gating)
+		ni_gfx_clockgating_enable(rdev, false);
+	if (pi->mg_clock_gating)
+		ni_mg_clockgating_enable(rdev, false);
+	if (eg_pi->ls_clock_gating)
+		ni_ls_clockgating_enable(rdev, false);
+	ni_stop_dpm(rdev);
+	btc_reset_to_default(rdev);
+	ni_stop_smc(rdev);
+	ni_force_switch_to_arb_f0(rdev);
+
+	ni_update_current_ps(rdev, boot_ps);
+}
+
+static int ni_power_control_set_level(struct radeon_device *rdev)
+{
+	struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
+	int ret;
+
+	ret = ni_restrict_performance_levels_before_switch(rdev);
+	if (ret)
+		return ret;
+	ret = rv770_halt_smc(rdev);
+	if (ret)
+		return ret;
+	ret = ni_populate_smc_tdp_limits(rdev, new_ps);
+	if (ret)
+		return ret;
+	ret = rv770_resume_smc(rdev);
+	if (ret)
+		return ret;
+	ret = rv770_set_sw_state(rdev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int ni_dpm_pre_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
+	struct radeon_ps *new_ps = &requested_ps;
+
+	ni_update_requested_ps(rdev, new_ps);
+
+	ni_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
+
+	return 0;
+}
+
+int ni_dpm_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *new_ps = &eg_pi->requested_rps;
+	struct radeon_ps *old_ps = &eg_pi->current_rps;
+	int ret;
+
+	ret = ni_restrict_performance_levels_before_switch(rdev);
+	if (ret) {
+		DRM_ERROR("ni_restrict_performance_levels_before_switch failed\n");
+		return ret;
+	}
+	ni_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+	ret = ni_enable_power_containment(rdev, new_ps, false);
+	if (ret) {
+		DRM_ERROR("ni_enable_power_containment failed\n");
+		return ret;
+	}
+	ret = ni_enable_smc_cac(rdev, new_ps, false);
+	if (ret) {
+		DRM_ERROR("ni_enable_smc_cac failed\n");
+		return ret;
+	}
+	ret = rv770_halt_smc(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_halt_smc failed\n");
+		return ret;
+	}
+	if (eg_pi->smu_uvd_hs)
+		btc_notify_uvd_to_smc(rdev, new_ps);
+	ret = ni_upload_sw_state(rdev, new_ps);
+	if (ret) {
+		DRM_ERROR("ni_upload_sw_state failed\n");
+		return ret;
+	}
+	if (eg_pi->dynamic_ac_timing) {
+		ret = ni_upload_mc_reg_table(rdev, new_ps);
+		if (ret) {
+			DRM_ERROR("ni_upload_mc_reg_table failed\n");
+			return ret;
+		}
+	}
+	ret = ni_program_memory_timing_parameters(rdev, new_ps);
+	if (ret) {
+		DRM_ERROR("ni_program_memory_timing_parameters failed\n");
+		return ret;
+	}
+	ret = rv770_resume_smc(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_resume_smc failed\n");
+		return ret;
+	}
+	ret = rv770_set_sw_state(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_set_sw_state failed\n");
+		return ret;
+	}
+	ni_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+	ret = ni_enable_smc_cac(rdev, new_ps, true);
+	if (ret) {
+		DRM_ERROR("ni_enable_smc_cac failed\n");
+		return ret;
+	}
+	ret = ni_enable_power_containment(rdev, new_ps, true);
+	if (ret) {
+		DRM_ERROR("ni_enable_power_containment failed\n");
+		return ret;
+	}
+
+	/* update tdp */
+	ret = ni_power_control_set_level(rdev);
+	if (ret) {
+		DRM_ERROR("ni_power_control_set_level failed\n");
+		return ret;
+	}
+
+	ret = ni_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO);
+	if (ret) {
+		DRM_ERROR("ni_dpm_force_performance_level failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+void ni_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *new_ps = &eg_pi->requested_rps;
+
+	ni_update_current_ps(rdev, new_ps);
+}
+
+void ni_dpm_reset_asic(struct radeon_device *rdev)
+{
+	ni_restrict_performance_levels_before_switch(rdev);
+	rv770_set_boot_state(rdev);
+}
+
+union power_info {
+	struct _ATOM_POWERPLAY_INFO info;
+	struct _ATOM_POWERPLAY_INFO_V2 info_2;
+	struct _ATOM_POWERPLAY_INFO_V3 info_3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
+	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
+	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
+};
+
+union pplib_clock_info {
+	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
+	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
+	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
+	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
+};
+
+union pplib_power_state {
+	struct _ATOM_PPLIB_STATE v1;
+	struct _ATOM_PPLIB_STATE_V2 v2;
+};
+
+static void ni_parse_pplib_non_clock_info(struct radeon_device *rdev,
+					  struct radeon_ps *rps,
+					  struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
+					  u8 table_rev)
+{
+	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
+	rps->class = le16_to_cpu(non_clock_info->usClassification);
+	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
+
+	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
+		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
+		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
+	} else if (r600_is_uvd_state(rps->class, rps->class2)) {
+		rps->vclk = RV770_DEFAULT_VCLK_FREQ;
+		rps->dclk = RV770_DEFAULT_DCLK_FREQ;
+	} else {
+		rps->vclk = 0;
+		rps->dclk = 0;
+	}
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
+		rdev->pm.dpm.boot_ps = rps;
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		rdev->pm.dpm.uvd_ps = rps;
+}
+
+static void ni_parse_pplib_clock_info(struct radeon_device *rdev,
+				      struct radeon_ps *rps, int index,
+				      union pplib_clock_info *clock_info)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_ps *ps = ni_get_ps(rps);
+	u16 vddc;
+	struct rv7xx_pl *pl = &ps->performance_levels[index];
+
+	ps->performance_level_count = index + 1;
+
+	pl->sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
+	pl->sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
+	pl->mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
+	pl->mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
+
+	pl->vddc = le16_to_cpu(clock_info->evergreen.usVDDC);
+	pl->vddci = le16_to_cpu(clock_info->evergreen.usVDDCI);
+	pl->flags = le32_to_cpu(clock_info->evergreen.ulFlags);
+
+	/* patch up vddc if necessary */
+	if (pl->vddc == 0xff01) {
+		if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0)
+			pl->vddc = vddc;
+	}
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
+		pi->acpi_vddc = pl->vddc;
+		eg_pi->acpi_vddci = pl->vddci;
+		if (ps->performance_levels[0].flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
+			pi->acpi_pcie_gen2 = true;
+		else
+			pi->acpi_pcie_gen2 = false;
+	}
+
+	if (rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) {
+		eg_pi->ulv.supported = true;
+		eg_pi->ulv.pl = pl;
+	}
+
+	if (pi->min_vddc_in_table > pl->vddc)
+		pi->min_vddc_in_table = pl->vddc;
+
+	if (pi->max_vddc_in_table < pl->vddc)
+		pi->max_vddc_in_table = pl->vddc;
+
+	/* patch up boot state */
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
+		u16 vddc, vddci, mvdd;
+		radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
+		pl->mclk = rdev->clock.default_mclk;
+		pl->sclk = rdev->clock.default_sclk;
+		pl->vddc = vddc;
+		pl->vddci = vddci;
+	}
+
+	if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
+	    ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
+		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;
+		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;
+		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;
+		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;
+	}
+}
+
+static int ni_parse_power_table(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
+	union pplib_power_state *power_state;
+	int i, j;
+	union pplib_clock_info *clock_info;
+	union power_info *power_info;
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+        u16 data_offset;
+	u8 frev, crev;
+	struct ni_ps *ps;
+
+	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset))
+		return -EINVAL;
+	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+
+	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
+				  power_info->pplib.ucNumStates, GFP_KERNEL);
+	if (!rdev->pm.dpm.ps)
+		return -ENOMEM;
+	rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
+	rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
+	rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
+
+	for (i = 0; i < power_info->pplib.ucNumStates; i++) {
+		power_state = (union pplib_power_state *)
+			(mode_info->atom_context->bios + data_offset +
+			 le16_to_cpu(power_info->pplib.usStateArrayOffset) +
+			 i * power_info->pplib.ucStateEntrySize);
+		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
+			(mode_info->atom_context->bios + data_offset +
+			 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
+			 (power_state->v1.ucNonClockStateIndex *
+			  power_info->pplib.ucNonClockSize));
+		if (power_info->pplib.ucStateEntrySize - 1) {
+			ps = kzalloc(sizeof(struct ni_ps), GFP_KERNEL);
+			if (ps == NULL) {
+				kfree(rdev->pm.dpm.ps);
+				return -ENOMEM;
+			}
+			rdev->pm.dpm.ps[i].ps_priv = ps;
+			ni_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
+							 non_clock_info,
+							 power_info->pplib.ucNonClockSize);
+			for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
+				clock_info = (union pplib_clock_info *)
+					(mode_info->atom_context->bios + data_offset +
+					 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
+					 (power_state->v1.ucClockStateIndices[j] *
+					  power_info->pplib.ucClockInfoSize));
+				ni_parse_pplib_clock_info(rdev,
+							  &rdev->pm.dpm.ps[i], j,
+							  clock_info);
+			}
+		}
+	}
+	rdev->pm.dpm.num_ps = power_info->pplib.ucNumStates;
+	return 0;
+}
+
+int ni_dpm_init(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi;
+	struct evergreen_power_info *eg_pi;
+	struct ni_power_info *ni_pi;
+	struct atom_clock_dividers dividers;
+	int ret;
+
+	ni_pi = kzalloc(sizeof(struct ni_power_info), GFP_KERNEL);
+	if (ni_pi == NULL)
+		return -ENOMEM;
+	rdev->pm.dpm.priv = ni_pi;
+	eg_pi = &ni_pi->eg;
+	pi = &eg_pi->rv7xx;
+
+	rv770_get_max_vddc(rdev);
+
+	eg_pi->ulv.supported = false;
+	pi->acpi_vddc = 0;
+	eg_pi->acpi_vddci = 0;
+	pi->min_vddc_in_table = 0;
+	pi->max_vddc_in_table = 0;
+
+	ret = ni_parse_power_table(rdev);
+	if (ret)
+		return ret;
+	ret = r600_parse_extended_power_table(rdev);
+	if (ret)
+		return ret;
+
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
+		kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL);
+	if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
+		r600_free_extended_power_table(rdev);
+		return -ENOMEM;
+	}
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 720;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 810;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 900;
+
+	ni_patch_dependency_tables_based_on_leakage(rdev);
+
+	if (rdev->pm.dpm.voltage_response_time == 0)
+		rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
+	if (rdev->pm.dpm.backbias_response_time == 0)
+		rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     0, false, &dividers);
+	if (ret)
+		pi->ref_div = dividers.ref_div + 1;
+	else
+		pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
+
+	pi->rlp = RV770_RLP_DFLT;
+	pi->rmp = RV770_RMP_DFLT;
+	pi->lhp = RV770_LHP_DFLT;
+	pi->lmp = RV770_LMP_DFLT;
+
+	eg_pi->ats[0].rlp = RV770_RLP_DFLT;
+	eg_pi->ats[0].rmp = RV770_RMP_DFLT;
+	eg_pi->ats[0].lhp = RV770_LHP_DFLT;
+	eg_pi->ats[0].lmp = RV770_LMP_DFLT;
+
+	eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
+	eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
+	eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
+	eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
+
+	eg_pi->smu_uvd_hs = true;
+
+	if (rdev->pdev->device == 0x6707) {
+		pi->mclk_strobe_mode_threshold = 55000;
+		pi->mclk_edc_enable_threshold = 55000;
+		eg_pi->mclk_edc_wr_enable_threshold = 55000;
+	} else {
+		pi->mclk_strobe_mode_threshold = 40000;
+		pi->mclk_edc_enable_threshold = 40000;
+		eg_pi->mclk_edc_wr_enable_threshold = 40000;
+	}
+	ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;
+
+	pi->voltage_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
+
+	pi->mvdd_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
+
+	eg_pi->vddci_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
+
+	rv770_get_engine_memory_ss(rdev);
+
+	pi->asi = RV770_ASI_DFLT;
+	pi->pasi = CYPRESS_HASI_DFLT;
+	pi->vrc = CYPRESS_VRC_DFLT;
+
+	pi->power_gating = false;
+
+	pi->gfx_clock_gating = true;
+
+	pi->mg_clock_gating = true;
+	pi->mgcgtssm = true;
+	eg_pi->ls_clock_gating = false;
+	eg_pi->sclk_deep_sleep = false;
+
+	pi->dynamic_pcie_gen2 = true;
+
+	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
+		pi->thermal_protection = true;
+	else
+		pi->thermal_protection = false;
+
+	pi->display_gap = true;
+
+	pi->dcodt = true;
+
+	pi->ulps = true;
+
+	eg_pi->dynamic_ac_timing = true;
+	eg_pi->abm = true;
+	eg_pi->mcls = true;
+	eg_pi->light_sleep = true;
+	eg_pi->memory_transition = true;
+#if defined(CONFIG_ACPI)
+	eg_pi->pcie_performance_request =
+		radeon_acpi_is_pcie_performance_request_supported(rdev);
+#else
+	eg_pi->pcie_performance_request = false;
+#endif
+
+	eg_pi->dll_default_on = false;
+
+	eg_pi->sclk_deep_sleep = false;
+
+	pi->mclk_stutter_mode_threshold = 0;
+
+	pi->sram_end = SMC_RAM_END;
+
+	rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 3;
+	rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
+	rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900;
+	rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk);
+	rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk;
+	rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
+	rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
+	rdev->pm.dpm.dyn_state.sclk_mclk_delta = 12500;
+
+	ni_pi->cac_data.leakage_coefficients.at = 516;
+	ni_pi->cac_data.leakage_coefficients.bt = 18;
+	ni_pi->cac_data.leakage_coefficients.av = 51;
+	ni_pi->cac_data.leakage_coefficients.bv = 2957;
+
+	switch (rdev->pdev->device) {
+	case 0x6700:
+	case 0x6701:
+	case 0x6702:
+	case 0x6703:
+	case 0x6718:
+		ni_pi->cac_weights = &cac_weights_cayman_xt;
+		break;
+	case 0x6705:
+	case 0x6719:
+	case 0x671D:
+	case 0x671C:
+	default:
+		ni_pi->cac_weights = &cac_weights_cayman_pro;
+		break;
+	case 0x6704:
+	case 0x6706:
+	case 0x6707:
+	case 0x6708:
+	case 0x6709:
+		ni_pi->cac_weights = &cac_weights_cayman_le;
+		break;
+	}
+
+	if (ni_pi->cac_weights->enable_power_containment_by_default) {
+		ni_pi->enable_power_containment = true;
+		ni_pi->enable_cac = true;
+		ni_pi->enable_sq_ramping = true;
+	} else {
+		ni_pi->enable_power_containment = false;
+		ni_pi->enable_cac = false;
+		ni_pi->enable_sq_ramping = false;
+	}
+
+	ni_pi->driver_calculate_cac_leakage = false;
+	ni_pi->cac_configuration_required = true;
+
+	if (ni_pi->cac_configuration_required) {
+		ni_pi->support_cac_long_term_average = true;
+		ni_pi->lta_window_size = ni_pi->cac_weights->l2_lta_window_size;
+		ni_pi->lts_truncate = ni_pi->cac_weights->lts_truncate;
+	} else {
+		ni_pi->support_cac_long_term_average = false;
+		ni_pi->lta_window_size = 0;
+		ni_pi->lts_truncate = 0;
+	}
+
+	ni_pi->use_power_boost_limit = true;
+
+	return 0;
+}
+
+void ni_dpm_fini(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	}
+	kfree(rdev->pm.dpm.ps);
+	kfree(rdev->pm.dpm.priv);
+	kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
+	r600_free_extended_power_table(rdev);
+}
+
+void ni_dpm_print_power_state(struct radeon_device *rdev,
+			      struct radeon_ps *rps)
+{
+	struct ni_ps *ps = ni_get_ps(rps);
+	struct rv7xx_pl *pl;
+	int i;
+
+	r600_dpm_print_class_info(rps->class, rps->class2);
+	r600_dpm_print_cap_info(rps->caps);
+	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+	for (i = 0; i < ps->performance_level_count; i++) {
+		pl = &ps->performance_levels[i];
+		if (rdev->family >= CHIP_TAHITI)
+			printk("\t\tpower level %d    sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",
+			       i, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);
+		else
+			printk("\t\tpower level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
+			       i, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
+	}
+	r600_dpm_print_ps_status(rdev, rps);
+}
+
+void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						    struct seq_file *m)
+{
+	struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+	struct ni_ps *ps = ni_get_ps(rps);
+	struct rv7xx_pl *pl;
+	u32 current_index =
+		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
+		CURRENT_STATE_INDEX_SHIFT;
+
+	if (current_index >= ps->performance_level_count) {
+		seq_printf(m, "invalid dpm profile %d\n", current_index);
+	} else {
+		pl = &ps->performance_levels[current_index];
+		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+		seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
+			   current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
+	}
+}
+
+u32 ni_dpm_get_sclk(struct radeon_device *rdev, bool low)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_ps *requested_state = ni_get_ps(&eg_pi->requested_rps);
+
+	if (low)
+		return requested_state->performance_levels[0].sclk;
+	else
+		return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk;
+}
+
+u32 ni_dpm_get_mclk(struct radeon_device *rdev, bool low)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_ps *requested_state = ni_get_ps(&eg_pi->requested_rps);
+
+	if (low)
+		return requested_state->performance_levels[0].mclk;
+	else
+		return requested_state->performance_levels[requested_state->performance_level_count - 1].mclk;
+}
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ni_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ni_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ni_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ni_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __NI_DPM_H__
+#define __NI_DPM_H__
+
+#include "cypress_dpm.h"
+#include "btc_dpm.h"
+#include "nislands_smc.h"
+
+struct ni_clock_registers {
+	u32 cg_spll_func_cntl;
+	u32 cg_spll_func_cntl_2;
+	u32 cg_spll_func_cntl_3;
+	u32 cg_spll_func_cntl_4;
+	u32 cg_spll_spread_spectrum;
+	u32 cg_spll_spread_spectrum_2;
+	u32 mclk_pwrmgt_cntl;
+	u32 dll_cntl;
+	u32 mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2;
+	u32 mpll_ss1;
+	u32 mpll_ss2;
+};
+
+struct ni_mc_reg_entry {
+	u32 mclk_max;
+	u32 mc_data[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
+};
+
+struct ni_mc_reg_table {
+	u8 last;
+	u8 num_entries;
+	u16 valid_flag;
+	struct ni_mc_reg_entry mc_reg_table_entry[MAX_AC_TIMING_ENTRIES];
+	SMC_NIslands_MCRegisterAddress mc_reg_address[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
+};
+
+#define NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT 2
+
+enum ni_dc_cac_level
+{
+	NISLANDS_DCCAC_LEVEL_0 = 0,
+	NISLANDS_DCCAC_LEVEL_1,
+	NISLANDS_DCCAC_LEVEL_2,
+	NISLANDS_DCCAC_LEVEL_3,
+	NISLANDS_DCCAC_LEVEL_4,
+	NISLANDS_DCCAC_LEVEL_5,
+	NISLANDS_DCCAC_LEVEL_6,
+	NISLANDS_DCCAC_LEVEL_7,
+	NISLANDS_DCCAC_MAX_LEVELS
+};
+
+struct ni_leakage_coeffients
+{
+	u32 at;
+	u32 bt;
+	u32 av;
+	u32 bv;
+	s32 t_slope;
+	s32 t_intercept;
+	u32 t_ref;
+};
+
+struct ni_cac_data
+{
+	struct ni_leakage_coeffients leakage_coefficients;
+	u32 i_leakage;
+	s32 leakage_minimum_temperature;
+	u32 pwr_const;
+	u32 dc_cac_value;
+	u32 bif_cac_value;
+	u32 lkge_pwr;
+	u8 mc_wr_weight;
+	u8 mc_rd_weight;
+	u8 allow_ovrflw;
+	u8 num_win_tdp;
+	u8 l2num_win_tdp;
+	u8 lts_truncate_n;
+};
+
+struct ni_cac_weights
+{
+	u32 weight_tcp_sig0;
+	u32 weight_tcp_sig1;
+	u32 weight_ta_sig;
+	u32 weight_tcc_en0;
+	u32 weight_tcc_en1;
+	u32 weight_tcc_en2;
+	u32 weight_cb_en0;
+	u32 weight_cb_en1;
+	u32 weight_cb_en2;
+	u32 weight_cb_en3;
+	u32 weight_db_sig0;
+	u32 weight_db_sig1;
+	u32 weight_db_sig2;
+	u32 weight_db_sig3;
+	u32 weight_sxm_sig0;
+	u32 weight_sxm_sig1;
+	u32 weight_sxm_sig2;
+	u32 weight_sxs_sig0;
+	u32 weight_sxs_sig1;
+	u32 weight_xbr_0;
+	u32 weight_xbr_1;
+	u32 weight_xbr_2;
+	u32 weight_spi_sig0;
+	u32 weight_spi_sig1;
+	u32 weight_spi_sig2;
+	u32 weight_spi_sig3;
+	u32 weight_spi_sig4;
+	u32 weight_spi_sig5;
+	u32 weight_lds_sig0;
+	u32 weight_lds_sig1;
+	u32 weight_sc;
+	u32 weight_bif;
+	u32 weight_cp;
+	u32 weight_pa_sig0;
+	u32 weight_pa_sig1;
+	u32 weight_vgt_sig0;
+	u32 weight_vgt_sig1;
+	u32 weight_vgt_sig2;
+	u32 weight_dc_sig0;
+	u32 weight_dc_sig1;
+	u32 weight_dc_sig2;
+	u32 weight_dc_sig3;
+	u32 weight_uvd_sig0;
+	u32 weight_uvd_sig1;
+	u32 weight_spare0;
+	u32 weight_spare1;
+	u32 weight_sq_vsp;
+	u32 weight_sq_vsp0;
+	u32 weight_sq_gpr;
+	u32 ovr_mode_spare_0;
+	u32 ovr_val_spare_0;
+	u32 ovr_mode_spare_1;
+	u32 ovr_val_spare_1;
+	u32 vsp;
+	u32 vsp0;
+	u32 gpr;
+	u8 mc_read_weight;
+	u8 mc_write_weight;
+	u32 tid_cnt;
+	u32 tid_unit;
+	u32 l2_lta_window_size;
+	u32 lts_truncate;
+	u32 dc_cac[NISLANDS_DCCAC_MAX_LEVELS];
+	u32 pcie_cac[SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES];
+	bool enable_power_containment_by_default;
+};
+
+struct ni_ps {
+	u16 performance_level_count;
+	bool dc_compatible;
+	struct rv7xx_pl performance_levels[NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
+};
+
+struct ni_power_info {
+	/* must be first! */
+	struct evergreen_power_info eg;
+	struct ni_clock_registers clock_registers;
+	struct ni_mc_reg_table mc_reg_table;
+	u32 mclk_rtt_mode_threshold;
+	/* flags */
+	bool use_power_boost_limit;
+	bool support_cac_long_term_average;
+	bool cac_enabled;
+	bool cac_configuration_required;
+	bool driver_calculate_cac_leakage;
+	bool pc_enabled;
+	bool enable_power_containment;
+	bool enable_cac;
+	bool enable_sq_ramping;
+	/* smc offsets */
+	u16 arb_table_start;
+	u16 fan_table_start;
+	u16 cac_table_start;
+	u16 spll_table_start;
+	/* CAC stuff */
+	struct ni_cac_data cac_data;
+	u32 dc_cac_table[NISLANDS_DCCAC_MAX_LEVELS];
+	const struct ni_cac_weights *cac_weights;
+	u8 lta_window_size;
+	u8 lts_truncate;
+	struct ni_ps current_ps;
+	struct ni_ps requested_ps;
+	/* scratch structs */
+	SMC_NIslands_MCRegisters smc_mc_reg_table;
+	NISLANDS_SMC_STATETABLE smc_statetable;
+};
+
+#define NISLANDS_INITIAL_STATE_ARB_INDEX    0
+#define NISLANDS_ACPI_STATE_ARB_INDEX       1
+#define NISLANDS_ULV_STATE_ARB_INDEX        2
+#define NISLANDS_DRIVER_STATE_ARB_INDEX     3
+
+#define NISLANDS_DPM2_MAX_PULSE_SKIP        256
+
+#define NISLANDS_DPM2_NEAR_TDP_DEC          10
+#define NISLANDS_DPM2_ABOVE_SAFE_INC        5
+#define NISLANDS_DPM2_BELOW_SAFE_INC        20
+
+#define NISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT            80
+
+#define NISLANDS_DPM2_MAXPS_PERCENT_H                   90
+#define NISLANDS_DPM2_MAXPS_PERCENT_M                   0
+
+#define NISLANDS_DPM2_SQ_RAMP_MAX_POWER                 0x3FFF
+#define NISLANDS_DPM2_SQ_RAMP_MIN_POWER                 0x12
+#define NISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA           0x15
+#define NISLANDS_DPM2_SQ_RAMP_STI_SIZE                  0x1E
+#define NISLANDS_DPM2_SQ_RAMP_LTI_RATIO                 0xF
+
+int ni_copy_and_switch_arb_sets(struct radeon_device *rdev,
+				u32 arb_freq_src, u32 arb_freq_dest);
+void ni_update_current_ps(struct radeon_device *rdev,
+			  struct radeon_ps *rps);
+void ni_update_requested_ps(struct radeon_device *rdev,
+			    struct radeon_ps *rps);
+
+void ni_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
+					   struct radeon_ps *new_ps,
+					   struct radeon_ps *old_ps);
+void ni_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
+					  struct radeon_ps *new_ps,
+					  struct radeon_ps *old_ps);
+
+bool ni_dpm_vblank_too_short(struct radeon_device *rdev);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/nislands_smc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/nislands_smc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/nislands_smc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/nislands_smc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __NISLANDS_SMC_H__
+#define __NISLANDS_SMC_H__
+
+#pragma pack(push, 1)
+
+#define NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE 16
+
+struct PP_NIslands_Dpm2PerfLevel
+{
+    uint8_t     MaxPS;
+    uint8_t     TgtAct;
+    uint8_t     MaxPS_StepInc;
+    uint8_t     MaxPS_StepDec;
+    uint8_t     PSST;
+    uint8_t     NearTDPDec;
+    uint8_t     AboveSafeInc;
+    uint8_t     BelowSafeInc;
+    uint8_t     PSDeltaLimit;
+    uint8_t     PSDeltaWin;
+    uint8_t     Reserved[6];
+};
+
+typedef struct PP_NIslands_Dpm2PerfLevel PP_NIslands_Dpm2PerfLevel;
+
+struct PP_NIslands_DPM2Parameters
+{
+    uint32_t    TDPLimit;
+    uint32_t    NearTDPLimit;
+    uint32_t    SafePowerLimit;
+    uint32_t    PowerBoostLimit;
+};
+typedef struct PP_NIslands_DPM2Parameters PP_NIslands_DPM2Parameters;
+
+struct NISLANDS_SMC_SCLK_VALUE
+{
+    uint32_t        vCG_SPLL_FUNC_CNTL;
+    uint32_t        vCG_SPLL_FUNC_CNTL_2;
+    uint32_t        vCG_SPLL_FUNC_CNTL_3;
+    uint32_t        vCG_SPLL_FUNC_CNTL_4;
+    uint32_t        vCG_SPLL_SPREAD_SPECTRUM;
+    uint32_t        vCG_SPLL_SPREAD_SPECTRUM_2;
+    uint32_t        sclk_value;
+};
+
+typedef struct NISLANDS_SMC_SCLK_VALUE NISLANDS_SMC_SCLK_VALUE;
+
+struct NISLANDS_SMC_MCLK_VALUE
+{
+    uint32_t        vMPLL_FUNC_CNTL;
+    uint32_t        vMPLL_FUNC_CNTL_1;
+    uint32_t        vMPLL_FUNC_CNTL_2;
+    uint32_t        vMPLL_AD_FUNC_CNTL;
+    uint32_t        vMPLL_AD_FUNC_CNTL_2;
+    uint32_t        vMPLL_DQ_FUNC_CNTL;
+    uint32_t        vMPLL_DQ_FUNC_CNTL_2;
+    uint32_t        vMCLK_PWRMGT_CNTL;
+    uint32_t        vDLL_CNTL;
+    uint32_t        vMPLL_SS;
+    uint32_t        vMPLL_SS2;
+    uint32_t        mclk_value;
+};
+
+typedef struct NISLANDS_SMC_MCLK_VALUE NISLANDS_SMC_MCLK_VALUE;
+
+struct NISLANDS_SMC_VOLTAGE_VALUE
+{
+    uint16_t             value;
+    uint8_t              index;
+    uint8_t              padding;
+};
+
+typedef struct NISLANDS_SMC_VOLTAGE_VALUE NISLANDS_SMC_VOLTAGE_VALUE;
+
+struct NISLANDS_SMC_HW_PERFORMANCE_LEVEL
+{
+    uint8_t                     arbValue;
+    uint8_t                     ACIndex;
+    uint8_t                     displayWatermark;
+    uint8_t                     gen2PCIE;
+    uint8_t                     reserved1;
+    uint8_t                     reserved2;
+    uint8_t                     strobeMode;
+    uint8_t                     mcFlags;
+    uint32_t                    aT;
+    uint32_t                    bSP;
+    NISLANDS_SMC_SCLK_VALUE     sclk;
+    NISLANDS_SMC_MCLK_VALUE     mclk;
+    NISLANDS_SMC_VOLTAGE_VALUE  vddc;
+    NISLANDS_SMC_VOLTAGE_VALUE  mvdd;
+    NISLANDS_SMC_VOLTAGE_VALUE  vddci;
+    NISLANDS_SMC_VOLTAGE_VALUE  std_vddc;
+    uint32_t                    powergate_en;
+    uint8_t                     hUp;
+    uint8_t                     hDown;
+    uint8_t                     stateFlags;
+    uint8_t                     arbRefreshState;
+    uint32_t                    SQPowerThrottle;
+    uint32_t                    SQPowerThrottle_2;
+    uint32_t                    reserved[2];
+    PP_NIslands_Dpm2PerfLevel   dpm2;
+};
+
+#define NISLANDS_SMC_STROBE_RATIO    0x0F
+#define NISLANDS_SMC_STROBE_ENABLE   0x10
+
+#define NISLANDS_SMC_MC_EDC_RD_FLAG  0x01
+#define NISLANDS_SMC_MC_EDC_WR_FLAG  0x02
+#define NISLANDS_SMC_MC_RTT_ENABLE   0x04
+#define NISLANDS_SMC_MC_STUTTER_EN   0x08
+
+typedef struct NISLANDS_SMC_HW_PERFORMANCE_LEVEL NISLANDS_SMC_HW_PERFORMANCE_LEVEL;
+
+struct NISLANDS_SMC_SWSTATE
+{
+    uint8_t                             flags;
+    uint8_t                             levelCount;
+    uint8_t                             padding2;
+    uint8_t                             padding3;
+    NISLANDS_SMC_HW_PERFORMANCE_LEVEL   levels[1];
+};
+
+typedef struct NISLANDS_SMC_SWSTATE NISLANDS_SMC_SWSTATE;
+
+#define NISLANDS_SMC_VOLTAGEMASK_VDDC  0
+#define NISLANDS_SMC_VOLTAGEMASK_MVDD  1
+#define NISLANDS_SMC_VOLTAGEMASK_VDDCI 2
+#define NISLANDS_SMC_VOLTAGEMASK_MAX   4
+
+struct NISLANDS_SMC_VOLTAGEMASKTABLE
+{
+    uint8_t  highMask[NISLANDS_SMC_VOLTAGEMASK_MAX];
+    uint32_t lowMask[NISLANDS_SMC_VOLTAGEMASK_MAX];
+};
+
+typedef struct NISLANDS_SMC_VOLTAGEMASKTABLE NISLANDS_SMC_VOLTAGEMASKTABLE;
+
+#define NISLANDS_MAX_NO_VREG_STEPS 32
+
+struct NISLANDS_SMC_STATETABLE
+{
+    uint8_t                             thermalProtectType;
+    uint8_t                             systemFlags;
+    uint8_t                             maxVDDCIndexInPPTable;
+    uint8_t                             extraFlags;
+    uint8_t                             highSMIO[NISLANDS_MAX_NO_VREG_STEPS];
+    uint32_t                            lowSMIO[NISLANDS_MAX_NO_VREG_STEPS];
+    NISLANDS_SMC_VOLTAGEMASKTABLE       voltageMaskTable;
+    PP_NIslands_DPM2Parameters          dpm2Params;
+    NISLANDS_SMC_SWSTATE                initialState;
+    NISLANDS_SMC_SWSTATE                ACPIState;
+    NISLANDS_SMC_SWSTATE                ULVState;
+    NISLANDS_SMC_SWSTATE                driverState;
+    NISLANDS_SMC_HW_PERFORMANCE_LEVEL   dpmLevels[NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1];
+};
+
+typedef struct NISLANDS_SMC_STATETABLE NISLANDS_SMC_STATETABLE;
+
+#define NI_SMC_SOFT_REGISTERS_START        0x108
+
+#define NI_SMC_SOFT_REGISTER_mclk_chg_timeout        0x0
+#define NI_SMC_SOFT_REGISTER_delay_bbias             0xC
+#define NI_SMC_SOFT_REGISTER_delay_vreg              0x10
+#define NI_SMC_SOFT_REGISTER_delay_acpi              0x2C
+#define NI_SMC_SOFT_REGISTER_seq_index               0x64
+#define NI_SMC_SOFT_REGISTER_mvdd_chg_time           0x68
+#define NI_SMC_SOFT_REGISTER_mclk_switch_lim         0x78
+#define NI_SMC_SOFT_REGISTER_watermark_threshold     0x80
+#define NI_SMC_SOFT_REGISTER_mc_block_delay          0x84
+#define NI_SMC_SOFT_REGISTER_uvd_enabled             0x98
+
+#define SMC_NISLANDS_MC_TPP_CAC_NUM_OF_ENTRIES 16
+#define SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16
+#define SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 16
+#define SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES 4
+
+struct SMC_NISLANDS_MC_TPP_CAC_TABLE
+{
+    uint32_t    tpp[SMC_NISLANDS_MC_TPP_CAC_NUM_OF_ENTRIES];
+    uint32_t    cacValue[SMC_NISLANDS_MC_TPP_CAC_NUM_OF_ENTRIES];
+};
+
+typedef struct SMC_NISLANDS_MC_TPP_CAC_TABLE SMC_NISLANDS_MC_TPP_CAC_TABLE;
+
+
+struct PP_NIslands_CACTABLES
+{
+    uint32_t                cac_bif_lut[SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES];
+    uint32_t                cac_lkge_lut[SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES][SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES];
+
+    uint32_t                pwr_const;
+
+    uint32_t                dc_cacValue;
+    uint32_t                bif_cacValue;
+    uint32_t                lkge_pwr;
+
+    uint8_t                 cac_width;
+    uint8_t                 window_size_p2;
+
+    uint8_t                 num_drop_lsb;
+    uint8_t                 padding_0;
+
+    uint32_t                last_power;
+
+    uint8_t                 AllowOvrflw;
+    uint8_t                 MCWrWeight;
+    uint8_t                 MCRdWeight;
+    uint8_t                 padding_1[9];
+
+    uint8_t                 enableWinAvg;
+    uint8_t                 numWin_TDP;
+    uint8_t                 l2numWin_TDP;
+    uint8_t                 WinIndex;
+
+    uint32_t                dynPwr_TDP[4];
+    uint32_t                lkgePwr_TDP[4];
+    uint32_t                power_TDP[4];
+    uint32_t                avg_dynPwr_TDP;
+    uint32_t                avg_lkgePwr_TDP;
+    uint32_t                avg_power_TDP;
+    uint32_t                lts_power_TDP;
+    uint8_t                 lts_truncate_n;
+    uint8_t                 padding_2[7];
+};
+
+typedef struct PP_NIslands_CACTABLES PP_NIslands_CACTABLES;
+
+#define SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE 32
+#define SMC_NISLANDS_MC_REGISTER_ARRAY_SET_COUNT 20
+
+struct SMC_NIslands_MCRegisterAddress
+{
+    uint16_t s0;
+    uint16_t s1;
+};
+
+typedef struct SMC_NIslands_MCRegisterAddress SMC_NIslands_MCRegisterAddress;
+
+
+struct SMC_NIslands_MCRegisterSet
+{
+    uint32_t value[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
+};
+
+typedef struct SMC_NIslands_MCRegisterSet SMC_NIslands_MCRegisterSet;
+
+struct SMC_NIslands_MCRegisters
+{
+    uint8_t                             last;
+    uint8_t                             reserved[3];
+    SMC_NIslands_MCRegisterAddress      address[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
+    SMC_NIslands_MCRegisterSet          data[SMC_NISLANDS_MC_REGISTER_ARRAY_SET_COUNT];
+};
+
+typedef struct SMC_NIslands_MCRegisters SMC_NIslands_MCRegisters;
+
+struct SMC_NIslands_MCArbDramTimingRegisterSet
+{
+    uint32_t mc_arb_dram_timing;
+    uint32_t mc_arb_dram_timing2;
+    uint8_t  mc_arb_rfsh_rate;
+    uint8_t  padding[3];
+};
+
+typedef struct SMC_NIslands_MCArbDramTimingRegisterSet SMC_NIslands_MCArbDramTimingRegisterSet;
+
+struct SMC_NIslands_MCArbDramTimingRegisters
+{
+    uint8_t                                     arb_current;
+    uint8_t                                     reserved[3];
+    SMC_NIslands_MCArbDramTimingRegisterSet     data[20];
+};
+
+typedef struct SMC_NIslands_MCArbDramTimingRegisters SMC_NIslands_MCArbDramTimingRegisters;
+
+struct SMC_NISLANDS_SPLL_DIV_TABLE
+{
+    uint32_t    freq[256];
+    uint32_t    ss[256];
+};
+
+#define SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_MASK  0x01ffffff
+#define SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT 0
+#define SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_MASK   0xfe000000
+#define SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT  25
+#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK   0x000fffff
+#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT  0
+#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK   0xfff00000
+#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT  20
+
+typedef struct SMC_NISLANDS_SPLL_DIV_TABLE SMC_NISLANDS_SPLL_DIV_TABLE;
+
+#define NISLANDS_SMC_FIRMWARE_HEADER_LOCATION 0x100
+
+#define NISLANDS_SMC_FIRMWARE_HEADER_version                   0x0
+#define NISLANDS_SMC_FIRMWARE_HEADER_flags                     0x4
+#define NISLANDS_SMC_FIRMWARE_HEADER_softRegisters             0x8
+#define NISLANDS_SMC_FIRMWARE_HEADER_stateTable                0xC
+#define NISLANDS_SMC_FIRMWARE_HEADER_fanTable                  0x10
+#define NISLANDS_SMC_FIRMWARE_HEADER_cacTable                  0x14
+#define NISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable           0x20
+#define NISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable 0x2C
+#define NISLANDS_SMC_FIRMWARE_HEADER_spllTable                 0x30
+
+#pragma pack(pop)
+
+#endif
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ObjectID.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ObjectID.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ObjectID.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ObjectID.h	2013-08-25 20:43:22.000000000 -0400
@@ -69,6 +69,8 @@
 #define ENCODER_OBJECT_ID_ALMOND                  0x22
 #define ENCODER_OBJECT_ID_TRAVIS                  0x23
 #define ENCODER_OBJECT_ID_NUTMEG                  0x22
+#define ENCODER_OBJECT_ID_HDMI_ANX9805            0x26
+
 /* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */
 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1   0x13
 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1    0x14
@@ -86,6 +88,8 @@
 #define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1        0x20
 #define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2        0x21
 #define ENCODER_OBJECT_ID_INTERNAL_VCE            0x24
+#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY3        0x25
+#define ENCODER_OBJECT_ID_INTERNAL_AMCLK          0x27
 
 #define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO    0xFF
 
@@ -364,6 +368,14 @@
                                                  GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
                                                  ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
 
+#define ENCODER_INTERNAL_UNIPHY3_ENUM_ID1         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_UNIPHY3_ENUM_ID2         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 << OBJECT_ID_SHIFT)
+
 #define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                   ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT)
@@ -392,6 +404,10 @@
                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                   ENCODER_OBJECT_ID_INTERNAL_VCE << OBJECT_ID_SHIFT)
 
+#define ENCODER_HDMI_ANX9805_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                  ENCODER_OBJECT_ID_HDMI_ANX9805 << OBJECT_ID_SHIFT)
+
 /****************************************************/
 /* Connector Object ID definition - Shared with BIOS */
 /****************************************************/
@@ -461,6 +477,14 @@
                                                  GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
 
+#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID5   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID6   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
+
 #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
@@ -473,6 +497,10 @@
                                                  GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
 
+#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID4     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
+
 #define CONNECTOR_VGA_ENUM_ID1                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
@@ -541,6 +569,18 @@
                                                  GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
 
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID4         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID5         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID6         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
+
 #define CONNECTOR_HDMI_TYPE_B_ENUM_ID1         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ppsmc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ppsmc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/ppsmc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/ppsmc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 PP_SMC_H
+#define PP_SMC_H
+
+#pragma pack(push, 1)
+
+#define PPSMC_SWSTATE_FLAG_DC                           0x01
+#define PPSMC_SWSTATE_FLAG_UVD                          0x02
+#define PPSMC_SWSTATE_FLAG_VCE                          0x04
+#define PPSMC_SWSTATE_FLAG_PCIE_X1                      0x08
+
+#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL             0x00
+#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL             0x01
+#define PPSMC_THERMAL_PROTECT_TYPE_NONE                 0xff
+
+#define PPSMC_SYSTEMFLAG_GPIO_DC                        0x01
+#define PPSMC_SYSTEMFLAG_STEPVDDC                       0x02
+#define PPSMC_SYSTEMFLAG_GDDR5                          0x04
+#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP               0x08
+#define PPSMC_SYSTEMFLAG_REGULATOR_HOT                  0x10
+#define PPSMC_SYSTEMFLAG_REGULATOR_HOT_ANALOG           0x20
+#define PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO        0x40
+
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK              0x07
+#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK     0x08
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE   0x00
+#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE  0x01
+#define PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH      0x02
+
+#define PPSMC_DISPLAY_WATERMARK_LOW                     0
+#define PPSMC_DISPLAY_WATERMARK_HIGH                    1
+
+#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP    0x01
+#define PPSMC_STATEFLAG_POWERBOOST         0x02
+#define PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE 0x20
+#define PPSMC_STATEFLAG_DEEPSLEEP_BYPASS   0x40
+
+#define PPSMC_Result_OK             ((uint8_t)0x01)
+#define PPSMC_Result_Failed         ((uint8_t)0xFF)
+
+typedef uint8_t PPSMC_Result;
+
+#define PPSMC_MSG_Halt                      ((uint8_t)0x10)
+#define PPSMC_MSG_Resume                    ((uint8_t)0x11)
+#define PPSMC_MSG_ZeroLevelsDisabled        ((uint8_t)0x13)
+#define PPSMC_MSG_OneLevelsDisabled         ((uint8_t)0x14)
+#define PPSMC_MSG_TwoLevelsDisabled         ((uint8_t)0x15)
+#define PPSMC_MSG_EnableThermalInterrupt    ((uint8_t)0x16)
+#define PPSMC_MSG_RunningOnAC               ((uint8_t)0x17)
+#define PPSMC_MSG_SwitchToSwState           ((uint8_t)0x20)
+#define PPSMC_MSG_SwitchToInitialState      ((uint8_t)0x40)
+#define PPSMC_MSG_NoForcedLevel             ((uint8_t)0x41)
+#define PPSMC_MSG_ForceHigh                 ((uint8_t)0x42)
+#define PPSMC_MSG_ForceMediumOrHigh         ((uint8_t)0x43)
+#define PPSMC_MSG_SwitchToMinimumPower      ((uint8_t)0x51)
+#define PPSMC_MSG_ResumeFromMinimumPower    ((uint8_t)0x52)
+#define PPSMC_MSG_EnableCac                 ((uint8_t)0x53)
+#define PPSMC_MSG_DisableCac                ((uint8_t)0x54)
+#define PPSMC_TDPClampingActive             ((uint8_t)0x59)
+#define PPSMC_TDPClampingInactive           ((uint8_t)0x5A)
+#define PPSMC_MSG_NoDisplay                 ((uint8_t)0x5D)
+#define PPSMC_MSG_HasDisplay                ((uint8_t)0x5E)
+#define PPSMC_MSG_UVDPowerOFF               ((uint8_t)0x60)
+#define PPSMC_MSG_UVDPowerON                ((uint8_t)0x61)
+#define PPSMC_MSG_EnableULV                 ((uint8_t)0x62)
+#define PPSMC_MSG_DisableULV                ((uint8_t)0x63)
+#define PPSMC_MSG_EnterULV                  ((uint8_t)0x64)
+#define PPSMC_MSG_ExitULV                   ((uint8_t)0x65)
+#define PPSMC_CACLongTermAvgEnable          ((uint8_t)0x6E)
+#define PPSMC_CACLongTermAvgDisable         ((uint8_t)0x6F)
+#define PPSMC_MSG_CollectCAC_PowerCorreln   ((uint8_t)0x7A)
+#define PPSMC_FlushDataCache                ((uint8_t)0x80)
+#define PPSMC_MSG_SetEnabledLevels          ((uint8_t)0x82)
+#define PPSMC_MSG_SetForcedLevels           ((uint8_t)0x83)
+#define PPSMC_MSG_ResetToDefaults           ((uint8_t)0x84)
+#define PPSMC_MSG_EnableDTE                 ((uint8_t)0x87)
+#define PPSMC_MSG_DisableDTE                ((uint8_t)0x88)
+#define PPSMC_MSG_ThrottleOVRDSCLKDS        ((uint8_t)0x96)
+#define PPSMC_MSG_CancelThrottleOVRDSCLKDS  ((uint8_t)0x97)
+
+/* TN */
+#define PPSMC_MSG_DPM_Config                ((uint32_t) 0x102)
+#define PPSMC_MSG_DPM_ForceState            ((uint32_t) 0x104)
+#define PPSMC_MSG_PG_SIMD_Config            ((uint32_t) 0x108)
+#define PPSMC_MSG_DPM_N_LevelsDisabled      ((uint32_t) 0x112)
+#define PPSMC_MSG_DCE_RemoveVoltageAdjustment   ((uint32_t) 0x11d)
+#define PPSMC_MSG_DCE_AllowVoltageAdjustment    ((uint32_t) 0x11e)
+#define PPSMC_MSG_UVD_DPM_Config            ((uint32_t) 0x124)
+
+
+typedef uint16_t PPSMC_Msg;
+
+#pragma pack(pop)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r100.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r100.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r100.c	2013-07-01 10:32:12.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r100.c	2013-08-31 17:51:33.000000000 -0400
@@ -39,7 +39,6 @@
 #include "atom.h"
 
 #include <linux/firmware.h>
-#include <linux/platform_device.h>
 #include <linux/module.h>
 
 #include "r100_reg_safe.h"
@@ -983,18 +982,11 @@ void r100_ring_start(struct radeon_devic
 /* Load the microcode for the CP */
 static int r100_cp_init_microcode(struct radeon_device *rdev)
 {
-	struct platform_device *pdev;
 	const char *fw_name = NULL;
 	int err;
 
 	DRM_DEBUG_KMS("\n");
 
-	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
-	err = IS_ERR(pdev);
-	if (err) {
-		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
-		return -EINVAL;
-	}
 	if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
 	    (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
 	    (rdev->family == CHIP_RS200)) {
@@ -1036,8 +1028,7 @@ static int r100_cp_init_microcode(struct
 		fw_name = FIRMWARE_R520;
 	}
 
-	err = reject_firmware(&rdev->me_fw, fw_name, &pdev->dev);
-	platform_device_unregister(pdev);
+	err = reject_firmware(&rdev->me_fw, fw_name, rdev->dev);
 	if (err) {
 		printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
 		       fw_name);
@@ -3071,6 +3062,10 @@ int r100_set_surface_reg(struct radeon_d
 			flags |= RADEON_SURF_TILE_COLOR_BOTH;
 		if (tiling_flags & RADEON_TILING_MACRO)
 			flags |= RADEON_SURF_TILE_COLOR_MACRO;
+		/* setting pitch to 0 disables tiling */
+		if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO))
+				== 0)
+			pitch = 0;
 	} else if (rdev->family <= CHIP_RV280) {
 		if (tiling_flags & (RADEON_TILING_MACRO))
 			flags |= R200_SURF_TILE_COLOR_MACRO;
@@ -3088,13 +3083,6 @@ int r100_set_surface_reg(struct radeon_d
 	if (tiling_flags & RADEON_TILING_SWAP_32BIT)
 		flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP;
 
-	/* when we aren't tiling the pitch seems to needs to be furtherdivided down. - tested on power5 + rn50 server */
-	if (tiling_flags & (RADEON_TILING_SWAP_16BIT | RADEON_TILING_SWAP_32BIT)) {
-		if (!(tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO)))
-			if (ASIC_IS_RN50(rdev))
-				pitch /= 16;
-	}
-
 	/* r100/r200 divide by 16 */
 	if (rdev->family < CHIP_R300)
 		flags |= pitch / 16;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600.c	2013-07-01 10:32:16.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600.c	2013-08-31 17:51:37.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/firmware.h>
-#include <linux/platform_device.h>
 #include <linux/module.h>
 #include <drm/drmP.h>
 #include <drm/radeon_drm.h>
@@ -38,18 +37,7 @@
 #include "r600d.h"
 #include "atom.h"
 #include "avivod.h"
-
-#define PFP_UCODE_SIZE 576
-#define PM4_UCODE_SIZE 1792
-#define RLC_UCODE_SIZE 768
-#define R700_PFP_UCODE_SIZE 848
-#define R700_PM4_UCODE_SIZE 1360
-#define R700_RLC_UCODE_SIZE 1024
-#define EVERGREEN_PFP_UCODE_SIZE 1120
-#define EVERGREEN_PM4_UCODE_SIZE 1376
-#define EVERGREEN_RLC_UCODE_SIZE 768
-#define CAYMAN_RLC_UCODE_SIZE 1024
-#define ARUBA_RLC_UCODE_SIZE 1536
+#include "radeon_ucode.h"
 
 /* Firmware Names */
 /*(DEBLOBBED)*/
@@ -68,6 +56,7 @@ static void r600_gpu_init(struct radeon_
 void r600_fini(struct radeon_device *rdev);
 void r600_irq_disable(struct radeon_device *rdev);
 static void r600_pcie_gen2_enable(struct radeon_device *rdev);
+extern int evergreen_rlc_resume(struct radeon_device *rdev);
 
 /**
  * r600_get_xclk - get the xclk
@@ -2106,22 +2095,15 @@ void r600_cp_stop(struct radeon_device *
 
 int r600_init_microcode(struct radeon_device *rdev)
 {
-	struct platform_device *pdev;
 	const char *chip_name;
 	const char *rlc_chip_name;
-	size_t pfp_req_size, me_req_size, rlc_req_size;
+	const char *smc_chip_name = "RV770";
+	size_t pfp_req_size, me_req_size, rlc_req_size, smc_req_size = 0;
 	char fw_name[30];
 	int err;
 
 	DRM_DEBUG("\n");
 
-	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
-	err = IS_ERR(pdev);
-	if (err) {
-		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
-		return -EINVAL;
-	}
-
 	switch (rdev->family) {
 	case CHIP_R600:
 		chip_name = "R600";
@@ -2155,32 +2137,51 @@ int r600_init_microcode(struct radeon_de
 	case CHIP_RV770:
 		chip_name = "RV770";
 		rlc_chip_name = "R700";
+		smc_chip_name = "RV770";
+		smc_req_size = ALIGN(RV770_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_RV730:
-	case CHIP_RV740:
 		chip_name = "RV730";
 		rlc_chip_name = "R700";
+		smc_chip_name = "RV730";
+		smc_req_size = ALIGN(RV730_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_RV710:
 		chip_name = "RV710";
 		rlc_chip_name = "R700";
+		smc_chip_name = "RV710";
+		smc_req_size = ALIGN(RV710_SMC_UCODE_SIZE, 4);
+		break;
+	case CHIP_RV740:
+		chip_name = "RV730";
+		rlc_chip_name = "R700";
+		smc_chip_name = "RV740";
+		smc_req_size = ALIGN(RV740_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_CEDAR:
 		chip_name = "CEDAR";
 		rlc_chip_name = "CEDAR";
+		smc_chip_name = "CEDAR";
+		smc_req_size = ALIGN(CEDAR_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_REDWOOD:
 		chip_name = "REDWOOD";
 		rlc_chip_name = "REDWOOD";
+		smc_chip_name = "REDWOOD";
+		smc_req_size = ALIGN(REDWOOD_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_JUNIPER:
 		chip_name = "JUNIPER";
 		rlc_chip_name = "JUNIPER";
+		smc_chip_name = "JUNIPER";
+		smc_req_size = ALIGN(JUNIPER_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_CYPRESS:
 	case CHIP_HEMLOCK:
 		chip_name = "CYPRESS";
 		rlc_chip_name = "CYPRESS";
+		smc_chip_name = "CYPRESS";
+		smc_req_size = ALIGN(CYPRESS_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_PALM:
 		chip_name = "PALM";
@@ -2206,15 +2207,15 @@ int r600_init_microcode(struct radeon_de
 		me_req_size = R700_PM4_UCODE_SIZE * 4;
 		rlc_req_size = R700_RLC_UCODE_SIZE * 4;
 	} else {
-		pfp_req_size = PFP_UCODE_SIZE * 4;
-		me_req_size = PM4_UCODE_SIZE * 12;
-		rlc_req_size = RLC_UCODE_SIZE * 4;
+		pfp_req_size = R600_PFP_UCODE_SIZE * 4;
+		me_req_size = R600_PM4_UCODE_SIZE * 12;
+		rlc_req_size = R600_RLC_UCODE_SIZE * 4;
 	}
 
 	DRM_INFO("Loading %s Microcode\n", chip_name);
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
-	err = reject_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->pfp_fw->size != pfp_req_size) {
@@ -2226,7 +2227,7 @@ int r600_init_microcode(struct radeon_de
 	}
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
-	err = reject_firmware(&rdev->me_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->me_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->me_fw->size != me_req_size) {
@@ -2237,7 +2238,7 @@ int r600_init_microcode(struct radeon_de
 	}
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", rlc_chip_name);
-	err = reject_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->rlc_fw->size != rlc_req_size) {
@@ -2247,9 +2248,24 @@ int r600_init_microcode(struct radeon_de
 		err = -EINVAL;
 	}
 
-out:
-	platform_device_unregister(pdev);
+	if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) {
+		snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", smc_chip_name);
+		err = reject_firmware(&rdev->smc_fw, fw_name, rdev->dev);
+		if (err) {
+			printk(KERN_ERR
+			       "smc: error loading firmware \"%s\"\n",
+			       fw_name);
+			release_firmware(rdev->smc_fw);
+			rdev->smc_fw = NULL;
+		} else if (rdev->smc_fw->size != smc_req_size) {
+			printk(KERN_ERR
+			       "smc: Bogus length %zu in firmware \"%s\"\n",
+			       rdev->smc_fw->size, fw_name);
+			err = -EINVAL;
+		}
+	}
 
+out:
 	if (err) {
 		if (err != -EINVAL)
 			printk(KERN_ERR
@@ -2261,6 +2277,8 @@ out:
 		rdev->me_fw = NULL;
 		release_firmware(rdev->rlc_fw);
 		rdev->rlc_fw = NULL;
+		release_firmware(rdev->smc_fw);
+		rdev->smc_fw = NULL;
 	}
 	return err;
 }
@@ -2291,13 +2309,13 @@ static int r600_cp_load_microcode(struct
 
 	fw_data = (const __be32 *)rdev->me_fw->data;
 	WREG32(CP_ME_RAM_WADDR, 0);
-	for (i = 0; i < PM4_UCODE_SIZE * 3; i++)
+	for (i = 0; i < R600_PM4_UCODE_SIZE * 3; i++)
 		WREG32(CP_ME_RAM_DATA,
 		       be32_to_cpup(fw_data++));
 
 	fw_data = (const __be32 *)rdev->pfp_fw->data;
 	WREG32(CP_PFP_UCODE_ADDR, 0);
-	for (i = 0; i < PFP_UCODE_SIZE; i++)
+	for (i = 0; i < R600_PFP_UCODE_SIZE; i++)
 		WREG32(CP_PFP_UCODE_DATA,
 		       be32_to_cpup(fw_data++));
 
@@ -2635,12 +2653,29 @@ int r600_uvd_rbc_start(struct radeon_dev
 	return 0;
 }
 
-void r600_uvd_rbc_stop(struct radeon_device *rdev)
+void r600_uvd_stop(struct radeon_device *rdev)
 {
 	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 
 	/* force RBC into idle state */
 	WREG32(UVD_RBC_RB_CNTL, 0x11010101);
+
+	/* Stall UMC and register bus before resetting VCPU */
+	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
+	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
+	mdelay(1);
+
+	/* put VCPU into reset */
+	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
+	mdelay(5);
+
+	/* disable VCPU clock */
+	WREG32(UVD_VCPU_CNTL, 0x0);
+
+	/* Unstall UMC and register bus */
+	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
+	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
+
 	ring->ready = false;
 }
 
@@ -2660,6 +2695,11 @@ int r600_uvd_init(struct radeon_device *
 	/* disable interupt */
 	WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
 
+	/* Stall UMC and register bus before resetting VCPU */
+	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
+	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
+	mdelay(1);
+
 	/* put LMI, VCPU, RBC etc... into reset */
 	WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
 	       LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
@@ -2689,10 +2729,6 @@ int r600_uvd_init(struct radeon_device *
 	WREG32(UVD_MPC_SET_ALU, 0);
 	WREG32(UVD_MPC_SET_MUX, 0x88);
 
-	/* Stall UMC */
-	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
-	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
-
 	/* take all subblocks out of reset, except VCPU */
 	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
 	mdelay(5);
@@ -2946,7 +2982,7 @@ void r600_uvd_fence_emit(struct radeon_d
 			 struct radeon_fence *fence)
 {
 	struct radeon_ring *ring = &rdev->ring[fence->ring];
-	uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr;
+	uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
 
 	radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
 	radeon_ring_write(ring, fence->seq);
@@ -3072,6 +3108,90 @@ int r600_copy_blit(struct radeon_device
 }
 
 /**
+ * r600_copy_cpdma - copy pages using the CP DMA engine
+ *
+ * @rdev: radeon_device pointer
+ * @src_offset: src GPU address
+ * @dst_offset: dst GPU address
+ * @num_gpu_pages: number of GPU pages to xfer
+ * @fence: radeon fence object
+ *
+ * Copy GPU paging using the CP DMA engine (r6xx+).
+ * Used by the radeon ttm implementation to move pages if
+ * registered as the asic copy callback.
+ */
+int r600_copy_cpdma(struct radeon_device *rdev,
+		    uint64_t src_offset, uint64_t dst_offset,
+		    unsigned num_gpu_pages,
+		    struct radeon_fence **fence)
+{
+	struct radeon_semaphore *sem = NULL;
+	int ring_index = rdev->asic->copy.blit_ring_index;
+	struct radeon_ring *ring = &rdev->ring[ring_index];
+	u32 size_in_bytes, cur_size_in_bytes, tmp;
+	int i, num_loops;
+	int r = 0;
+
+	r = radeon_semaphore_create(rdev, &sem);
+	if (r) {
+		DRM_ERROR("radeon: moving bo (%d).\n", r);
+		return r;
+	}
+
+	size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
+	num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff);
+	r = radeon_ring_lock(rdev, ring, num_loops * 6 + 24);
+	if (r) {
+		DRM_ERROR("radeon: moving bo (%d).\n", r);
+		radeon_semaphore_free(rdev, &sem, NULL);
+		return r;
+	}
+
+	if (radeon_fence_need_sync(*fence, ring->idx)) {
+		radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring,
+					    ring->idx);
+		radeon_fence_note_sync(*fence, ring->idx);
+	} else {
+		radeon_semaphore_free(rdev, &sem, NULL);
+	}
+
+	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+	radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+	radeon_ring_write(ring, WAIT_3D_IDLE_bit);
+	for (i = 0; i < num_loops; i++) {
+		cur_size_in_bytes = size_in_bytes;
+		if (cur_size_in_bytes > 0x1fffff)
+			cur_size_in_bytes = 0x1fffff;
+		size_in_bytes -= cur_size_in_bytes;
+		tmp = upper_32_bits(src_offset) & 0xff;
+		if (size_in_bytes == 0)
+			tmp |= PACKET3_CP_DMA_CP_SYNC;
+		radeon_ring_write(ring, PACKET3(PACKET3_CP_DMA, 4));
+		radeon_ring_write(ring, src_offset & 0xffffffff);
+		radeon_ring_write(ring, tmp);
+		radeon_ring_write(ring, dst_offset & 0xffffffff);
+		radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff);
+		radeon_ring_write(ring, cur_size_in_bytes);
+		src_offset += cur_size_in_bytes;
+		dst_offset += cur_size_in_bytes;
+	}
+	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+	radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+	radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit);
+
+	r = radeon_fence_emit(rdev, fence, ring->idx);
+	if (r) {
+		radeon_ring_unlock_undo(rdev, ring);
+		return r;
+	}
+
+	radeon_ring_unlock_commit(rdev, ring);
+	radeon_semaphore_free(rdev, &sem, *fence);
+
+	return r;
+}
+
+/**
  * r600_copy_dma - copy pages using the DMA engine
  *
  * @rdev: radeon_device pointer
@@ -3166,6 +3286,8 @@ static int r600_startup(struct radeon_de
 	/* enable pcie gen2 link */
 	r600_pcie_gen2_enable(rdev);
 
+	r600_mc_program(rdev);
+
 	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
 		r = r600_init_microcode(rdev);
 		if (r) {
@@ -3178,7 +3300,6 @@ static int r600_startup(struct radeon_de
 	if (r)
 		return r;
 
-	r600_mc_program(rdev);
 	if (rdev->flags & RADEON_IS_AGP) {
 		r600_agp_enable(rdev);
 	} else {
@@ -3749,7 +3870,7 @@ static void r600_rlc_start(struct radeon
 	WREG32(RLC_CNTL, RLC_ENABLE);
 }
 
-static int r600_rlc_init(struct radeon_device *rdev)
+static int r600_rlc_resume(struct radeon_device *rdev)
 {
 	u32 i;
 	const __be32 *fw_data;
@@ -3761,45 +3882,22 @@ static int r600_rlc_init(struct radeon_d
 
 	WREG32(RLC_HB_CNTL, 0);
 
-	if (rdev->family == CHIP_ARUBA) {
-		WREG32(TN_RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
-		WREG32(TN_RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
-	}
-	if (rdev->family <= CHIP_CAYMAN) {
-		WREG32(RLC_HB_BASE, 0);
-		WREG32(RLC_HB_RPTR, 0);
-		WREG32(RLC_HB_WPTR, 0);
-	}
-	if (rdev->family <= CHIP_CAICOS) {
-		WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
-		WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
-	}
+	WREG32(RLC_HB_BASE, 0);
+	WREG32(RLC_HB_RPTR, 0);
+	WREG32(RLC_HB_WPTR, 0);
+	WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
+	WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
 	WREG32(RLC_MC_CNTL, 0);
 	WREG32(RLC_UCODE_CNTL, 0);
 
 	fw_data = (const __be32 *)rdev->rlc_fw->data;
-	if (rdev->family >= CHIP_ARUBA) {
-		for (i = 0; i < ARUBA_RLC_UCODE_SIZE; i++) {
-			WREG32(RLC_UCODE_ADDR, i);
-			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
-		}
-	} else if (rdev->family >= CHIP_CAYMAN) {
-		for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) {
-			WREG32(RLC_UCODE_ADDR, i);
-			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
-		}
-	} else if (rdev->family >= CHIP_CEDAR) {
-		for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) {
-			WREG32(RLC_UCODE_ADDR, i);
-			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
-		}
-	} else if (rdev->family >= CHIP_RV770) {
+	if (rdev->family >= CHIP_RV770) {
 		for (i = 0; i < R700_RLC_UCODE_SIZE; i++) {
 			WREG32(RLC_UCODE_ADDR, i);
 			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
 		}
 	} else {
-		for (i = 0; i < RLC_UCODE_SIZE; i++) {
+		for (i = 0; i < R600_RLC_UCODE_SIZE; i++) {
 			WREG32(RLC_UCODE_ADDR, i);
 			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
 		}
@@ -3907,7 +4005,10 @@ int r600_irq_init(struct radeon_device *
 	r600_disable_interrupts(rdev);
 
 	/* init rlc */
-	ret = r600_rlc_init(rdev);
+	if (rdev->family >= CHIP_CEDAR)
+		ret = evergreen_rlc_resume(rdev);
+	else
+		ret = r600_rlc_resume(rdev);
 	if (ret) {
 		r600_ih_ring_fini(rdev);
 		return ret;
@@ -3988,6 +4089,7 @@ int r600_irq_set(struct radeon_device *r
 	u32 hdmi0, hdmi1;
 	u32 d1grph = 0, d2grph = 0;
 	u32 dma_cntl;
+	u32 thermal_int = 0;
 
 	if (!rdev->irq.installed) {
 		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
@@ -4022,8 +4124,21 @@ int r600_irq_set(struct radeon_device *r
 		hdmi0 = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
 		hdmi1 = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
 	}
+
 	dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
 
+	if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) {
+		thermal_int = RREG32(CG_THERMAL_INT) &
+			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
+	} else if (rdev->family >= CHIP_RV770) {
+		thermal_int = RREG32(RV770_CG_THERMAL_INT) &
+			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
+	}
+	if (rdev->irq.dpm_thermal) {
+		DRM_DEBUG("dpm thermal\n");
+		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
+	}
+
 	if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
 		DRM_DEBUG("r600_irq_set: sw int\n");
 		cp_int_cntl |= RB_INT_ENABLE;
@@ -4105,6 +4220,11 @@ int r600_irq_set(struct radeon_device *r
 		WREG32(HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
 		WREG32(HDMI1_AUDIO_PACKET_CONTROL, hdmi1);
 	}
+	if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) {
+		WREG32(CG_THERMAL_INT, thermal_int);
+	} else if (rdev->family >= CHIP_RV770) {
+		WREG32(RV770_CG_THERMAL_INT, thermal_int);
+	}
 
 	return 0;
 }
@@ -4296,6 +4416,7 @@ int r600_irq_process(struct radeon_devic
 	u32 ring_index;
 	bool queue_hotplug = false;
 	bool queue_hdmi = false;
+	bool queue_thermal = false;
 
 	if (!rdev->ih.enabled || rdev->shutdown)
 		return IRQ_NONE;
@@ -4463,6 +4584,16 @@ restart_ih:
 			DRM_DEBUG("IH: DMA trap\n");
 			radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
 			break;
+		case 230: /* thermal low to high */
+			DRM_DEBUG("IH: thermal low to high\n");
+			rdev->pm.dpm.thermal.high_to_low = false;
+			queue_thermal = true;
+			break;
+		case 231: /* thermal high to low */
+			DRM_DEBUG("IH: thermal high to low\n");
+			rdev->pm.dpm.thermal.high_to_low = true;
+			queue_thermal = true;
+			break;
 		case 233: /* GUI IDLE */
 			DRM_DEBUG("IH: GUI idle\n");
 			break;
@@ -4479,6 +4610,8 @@ restart_ih:
 		schedule_work(&rdev->hotplug_work);
 	if (queue_hdmi)
 		schedule_work(&rdev->audio_work);
+	if (queue_thermal && rdev->pm.dpm_enabled)
+		schedule_work(&rdev->pm.dpm.thermal.work);
 	rdev->ih.rptr = rptr;
 	WREG32(IH_RB_RPTR, rdev->ih.rptr);
 	atomic_set(&rdev->ih.lock, 0);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600d.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600d.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600d.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600d.h	2013-08-25 20:43:22.000000000 -0400
@@ -302,10 +302,25 @@
 #define	GRBM_SOFT_RESET					0x8020
 #define		SOFT_RESET_CP					(1<<0)
 
+#define	CG_THERMAL_CTRL					0x7F0
+#define		DIG_THERM_DPM(x)			((x) << 12)
+#define		DIG_THERM_DPM_MASK			0x000FF000
+#define		DIG_THERM_DPM_SHIFT			12
 #define	CG_THERMAL_STATUS				0x7F4
 #define		ASIC_T(x)			        ((x) << 0)
 #define		ASIC_T_MASK			        0x1FF
 #define		ASIC_T_SHIFT			        0
+#define	CG_THERMAL_INT					0x7F8
+#define		DIG_THERM_INTH(x)			((x) << 8)
+#define		DIG_THERM_INTH_MASK			0x0000FF00
+#define		DIG_THERM_INTH_SHIFT			8
+#define		DIG_THERM_INTL(x)			((x) << 16)
+#define		DIG_THERM_INTL_MASK			0x00FF0000
+#define		DIG_THERM_INTL_SHIFT			16
+#define 	THERM_INT_MASK_HIGH			(1 << 24)
+#define 	THERM_INT_MASK_LOW			(1 << 25)
+
+#define	RV770_CG_THERMAL_INT				0x734
 
 #define	HDP_HOST_PATH_CNTL				0x2C00
 #define	HDP_NONSURFACE_BASE				0x2C04
@@ -587,6 +602,7 @@
 #define		L2_BUSY						(1 << 0)
 
 #define	WAIT_UNTIL					0x8040
+#define         WAIT_CP_DMA_IDLE_bit                            (1 << 8)
 #define         WAIT_2D_IDLE_bit                                (1 << 14)
 #define         WAIT_3D_IDLE_bit                                (1 << 15)
 #define         WAIT_2D_IDLECLEAN_bit                           (1 << 16)
@@ -684,10 +700,6 @@
 #define RLC_UCODE_ADDR                                    0x3f2c
 #define RLC_UCODE_DATA                                    0x3f30
 
-/* new for TN */
-#define TN_RLC_SAVE_AND_RESTORE_BASE                      0x3f10
-#define TN_RLC_CLEAR_STATE_RESTORE_BASE                   0x3f20
-
 #define SRBM_SOFT_RESET                                   0xe60
 #       define SOFT_RESET_DMA                             (1 << 12)
 #       define SOFT_RESET_RLC                             (1 << 13)
@@ -921,6 +933,9 @@
 #define DCCG_AUDIO_DTO0_LOAD              0x051c
 #       define DTO_LOAD                   (1 << 31)
 #define DCCG_AUDIO_DTO0_CNTL              0x0520
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO(x) (((x) & 7) << 0)
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK 7
+#       define DCCG_AUDIO_DTO_WALLCLOCK_RATIO_SHIFT 0
 
 #define DCCG_AUDIO_DTO1_PHASE             0x0524
 #define DCCG_AUDIO_DTO1_MODULE            0x0528
@@ -1148,6 +1163,219 @@
 #       define AFMT_AZ_FORMAT_WTRIG_ACK      (1 << 29)
 #       define AFMT_AZ_AUDIO_ENABLE_CHG_ACK  (1 << 30)
 
+/* Power management */
+#define CG_SPLL_FUNC_CNTL                                 0x600
+#       define SPLL_RESET                                (1 << 0)
+#       define SPLL_SLEEP                                (1 << 1)
+#       define SPLL_REF_DIV(x)                           ((x) << 2)
+#       define SPLL_REF_DIV_MASK                         (7 << 2)
+#       define SPLL_FB_DIV(x)                            ((x) << 5)
+#       define SPLL_FB_DIV_MASK                          (0xff << 5)
+#       define SPLL_PULSEEN                              (1 << 13)
+#       define SPLL_PULSENUM(x)                          ((x) << 14)
+#       define SPLL_PULSENUM_MASK                        (3 << 14)
+#       define SPLL_SW_HILEN(x)                          ((x) << 16)
+#       define SPLL_SW_HILEN_MASK                        (0xf << 16)
+#       define SPLL_SW_LOLEN(x)                          ((x) << 20)
+#       define SPLL_SW_LOLEN_MASK                        (0xf << 20)
+#       define SPLL_DIVEN                                (1 << 24)
+#       define SPLL_BYPASS_EN                            (1 << 25)
+#       define SPLL_CHG_STATUS                           (1 << 29)
+#       define SPLL_CTLREQ                               (1 << 30)
+#       define SPLL_CTLACK                               (1 << 31)
+
+#define GENERAL_PWRMGT                                    0x618
+#       define GLOBAL_PWRMGT_EN                           (1 << 0)
+#       define STATIC_PM_EN                               (1 << 1)
+#       define MOBILE_SU                                  (1 << 2)
+#       define THERMAL_PROTECTION_DIS                     (1 << 3)
+#       define THERMAL_PROTECTION_TYPE                    (1 << 4)
+#       define ENABLE_GEN2PCIE                            (1 << 5)
+#       define SW_GPIO_INDEX(x)                           ((x) << 6)
+#       define SW_GPIO_INDEX_MASK                         (3 << 6)
+#       define LOW_VOLT_D2_ACPI                           (1 << 8)
+#       define LOW_VOLT_D3_ACPI                           (1 << 9)
+#       define VOLT_PWRMGT_EN                             (1 << 10)
+#define CG_TPC                                            0x61c
+#       define TPCC(x)                                    ((x) << 0)
+#       define TPCC_MASK                                  (0x7fffff << 0)
+#       define TPU(x)                                     ((x) << 23)
+#       define TPU_MASK                                   (0x1f << 23)
+#define SCLK_PWRMGT_CNTL                                  0x620
+#       define SCLK_PWRMGT_OFF                            (1 << 0)
+#       define SCLK_TURNOFF                               (1 << 1)
+#       define SPLL_TURNOFF                               (1 << 2)
+#       define SU_SCLK_USE_BCLK                           (1 << 3)
+#       define DYNAMIC_GFX_ISLAND_PWR_DOWN                (1 << 4)
+#       define DYNAMIC_GFX_ISLAND_PWR_LP                  (1 << 5)
+#       define CLK_TURN_ON_STAGGER                        (1 << 6)
+#       define CLK_TURN_OFF_STAGGER                       (1 << 7)
+#       define FIR_FORCE_TREND_SEL                        (1 << 8)
+#       define FIR_TREND_MODE                             (1 << 9)
+#       define DYN_GFX_CLK_OFF_EN                         (1 << 10)
+#       define VDDC3D_TURNOFF_D1                          (1 << 11)
+#       define VDDC3D_TURNOFF_D2                          (1 << 12)
+#       define VDDC3D_TURNOFF_D3                          (1 << 13)
+#       define SPLL_TURNOFF_D2                            (1 << 14)
+#       define SCLK_LOW_D1                                (1 << 15)
+#       define DYN_GFX_CLK_OFF_MC_EN                      (1 << 16)
+#define MCLK_PWRMGT_CNTL                                  0x624
+#       define MPLL_PWRMGT_OFF                            (1 << 0)
+#       define YCLK_TURNOFF                               (1 << 1)
+#       define MPLL_TURNOFF                               (1 << 2)
+#       define SU_MCLK_USE_BCLK                           (1 << 3)
+#       define DLL_READY                                  (1 << 4)
+#       define MC_BUSY                                    (1 << 5)
+#       define MC_INT_CNTL                                (1 << 7)
+#       define MRDCKA_SLEEP                               (1 << 8)
+#       define MRDCKB_SLEEP                               (1 << 9)
+#       define MRDCKC_SLEEP                               (1 << 10)
+#       define MRDCKD_SLEEP                               (1 << 11)
+#       define MRDCKE_SLEEP                               (1 << 12)
+#       define MRDCKF_SLEEP                               (1 << 13)
+#       define MRDCKG_SLEEP                               (1 << 14)
+#       define MRDCKH_SLEEP                               (1 << 15)
+#       define MRDCKA_RESET                               (1 << 16)
+#       define MRDCKB_RESET                               (1 << 17)
+#       define MRDCKC_RESET                               (1 << 18)
+#       define MRDCKD_RESET                               (1 << 19)
+#       define MRDCKE_RESET                               (1 << 20)
+#       define MRDCKF_RESET                               (1 << 21)
+#       define MRDCKG_RESET                               (1 << 22)
+#       define MRDCKH_RESET                               (1 << 23)
+#       define DLL_READY_READ                             (1 << 24)
+#       define USE_DISPLAY_GAP                            (1 << 25)
+#       define USE_DISPLAY_URGENT_NORMAL                  (1 << 26)
+#       define USE_DISPLAY_GAP_CTXSW                      (1 << 27)
+#       define MPLL_TURNOFF_D2                            (1 << 28)
+#       define USE_DISPLAY_URGENT_CTXSW                   (1 << 29)
+
+#define MPLL_TIME                                         0x634
+#       define MPLL_LOCK_TIME(x)                          ((x) << 0)
+#       define MPLL_LOCK_TIME_MASK                        (0xffff << 0)
+#       define MPLL_RESET_TIME(x)                         ((x) << 16)
+#       define MPLL_RESET_TIME_MASK                       (0xffff << 16)
+
+#define SCLK_FREQ_SETTING_STEP_0_PART1                    0x648
+#       define STEP_0_SPLL_POST_DIV(x)                    ((x) << 0)
+#       define STEP_0_SPLL_POST_DIV_MASK                  (0xff << 0)
+#       define STEP_0_SPLL_FB_DIV(x)                      ((x) << 8)
+#       define STEP_0_SPLL_FB_DIV_MASK                    (0xff << 8)
+#       define STEP_0_SPLL_REF_DIV(x)                     ((x) << 16)
+#       define STEP_0_SPLL_REF_DIV_MASK                   (7 << 16)
+#       define STEP_0_SPLL_STEP_TIME(x)                   ((x) << 19)
+#       define STEP_0_SPLL_STEP_TIME_MASK                 (0x1fff << 19)
+#define SCLK_FREQ_SETTING_STEP_0_PART2                    0x64c
+#       define STEP_0_PULSE_HIGH_CNT(x)                   ((x) << 0)
+#       define STEP_0_PULSE_HIGH_CNT_MASK                 (0x1ff << 0)
+#       define STEP_0_POST_DIV_EN                         (1 << 9)
+#       define STEP_0_SPLL_STEP_ENABLE                    (1 << 30)
+#       define STEP_0_SPLL_ENTRY_VALID                    (1 << 31)
+
+#define VID_RT                                            0x6f8
+#       define VID_CRT(x)                                 ((x) << 0)
+#       define VID_CRT_MASK                               (0x1fff << 0)
+#       define VID_CRTU(x)                                ((x) << 13)
+#       define VID_CRTU_MASK                              (7 << 13)
+#       define SSTU(x)                                    ((x) << 16)
+#       define SSTU_MASK                                  (7 << 16)
+#define CTXSW_PROFILE_INDEX                               0x6fc
+#       define CTXSW_FREQ_VIDS_CFG_INDEX(x)               ((x) << 0)
+#       define CTXSW_FREQ_VIDS_CFG_INDEX_MASK             (3 << 0)
+#       define CTXSW_FREQ_VIDS_CFG_INDEX_SHIFT            0
+#       define CTXSW_FREQ_MCLK_CFG_INDEX(x)               ((x) << 2)
+#       define CTXSW_FREQ_MCLK_CFG_INDEX_MASK             (3 << 2)
+#       define CTXSW_FREQ_MCLK_CFG_INDEX_SHIFT            2
+#       define CTXSW_FREQ_SCLK_CFG_INDEX(x)               ((x) << 4)
+#       define CTXSW_FREQ_SCLK_CFG_INDEX_MASK             (0x1f << 4)
+#       define CTXSW_FREQ_SCLK_CFG_INDEX_SHIFT            4
+#       define CTXSW_FREQ_STATE_SPLL_RESET_EN             (1 << 9)
+#       define CTXSW_FREQ_STATE_ENABLE                    (1 << 10)
+#       define CTXSW_FREQ_DISPLAY_WATERMARK               (1 << 11)
+#       define CTXSW_FREQ_GEN2PCIE_VOLT                   (1 << 12)
+
+#define TARGET_AND_CURRENT_PROFILE_INDEX                  0x70c
+#       define TARGET_PROFILE_INDEX_MASK                  (3 << 0)
+#       define TARGET_PROFILE_INDEX_SHIFT                 0
+#       define CURRENT_PROFILE_INDEX_MASK                 (3 << 2)
+#       define CURRENT_PROFILE_INDEX_SHIFT                2
+#       define DYN_PWR_ENTER_INDEX(x)                     ((x) << 4)
+#       define DYN_PWR_ENTER_INDEX_MASK                   (3 << 4)
+#       define DYN_PWR_ENTER_INDEX_SHIFT                  4
+#       define CURR_MCLK_INDEX_MASK                       (3 << 6)
+#       define CURR_MCLK_INDEX_SHIFT                      6
+#       define CURR_SCLK_INDEX_MASK                       (0x1f << 8)
+#       define CURR_SCLK_INDEX_SHIFT                      8
+#       define CURR_VID_INDEX_MASK                        (3 << 13)
+#       define CURR_VID_INDEX_SHIFT                       13
+
+#define LOWER_GPIO_ENABLE                                 0x710
+#define UPPER_GPIO_ENABLE                                 0x714
+#define CTXSW_VID_LOWER_GPIO_CNTL                         0x718
+
+#define VID_UPPER_GPIO_CNTL                               0x740
+#define CG_CTX_CGTT3D_R                                   0x744
+#       define PHC(x)                                     ((x) << 0)
+#       define PHC_MASK                                   (0x1ff << 0)
+#       define SDC(x)                                     ((x) << 9)
+#       define SDC_MASK                                   (0x3fff << 9)
+#define CG_VDDC3D_OOR                                     0x748
+#       define SU(x)                                      ((x) << 23)
+#       define SU_MASK                                    (0xf << 23)
+#define CG_FTV                                            0x74c
+#define CG_FFCT_0                                         0x750
+#       define UTC_0(x)                                   ((x) << 0)
+#       define UTC_0_MASK                                 (0x3ff << 0)
+#       define DTC_0(x)                                   ((x) << 10)
+#       define DTC_0_MASK                                 (0x3ff << 10)
+
+#define CG_BSP                                            0x78c
+#       define BSP(x)                                     ((x) << 0)
+#       define BSP_MASK                                   (0xffff << 0)
+#       define BSU(x)                                     ((x) << 16)
+#       define BSU_MASK                                   (0xf << 16)
+#define CG_RT                                             0x790
+#       define FLS(x)                                     ((x) << 0)
+#       define FLS_MASK                                   (0xffff << 0)
+#       define FMS(x)                                     ((x) << 16)
+#       define FMS_MASK                                   (0xffff << 16)
+#define CG_LT                                             0x794
+#       define FHS(x)                                     ((x) << 0)
+#       define FHS_MASK                                   (0xffff << 0)
+#define CG_GIT                                            0x798
+#       define CG_GICST(x)                                ((x) << 0)
+#       define CG_GICST_MASK                              (0xffff << 0)
+#       define CG_GIPOT(x)                                ((x) << 16)
+#       define CG_GIPOT_MASK                              (0xffff << 16)
+
+#define CG_SSP                                            0x7a8
+#       define CG_SST(x)                                  ((x) << 0)
+#       define CG_SST_MASK                                (0xffff << 0)
+#       define CG_SSTU(x)                                 ((x) << 16)
+#       define CG_SSTU_MASK                               (0xf << 16)
+
+#define CG_RLC_REQ_AND_RSP                                0x7c4
+#       define RLC_CG_REQ_TYPE_MASK                       0xf
+#       define RLC_CG_REQ_TYPE_SHIFT                      0
+#       define CG_RLC_RSP_TYPE_MASK                       0xf0
+#       define CG_RLC_RSP_TYPE_SHIFT                      4
+
+#define CG_FC_T                                           0x7cc
+#       define FC_T(x)                                    ((x) << 0)
+#       define FC_T_MASK                                  (0xffff << 0)
+#       define FC_TU(x)                                   ((x) << 16)
+#       define FC_TU_MASK                                 (0x1f << 16)
+
+#define GPIOPAD_MASK                                      0x1798
+#define GPIOPAD_A                                         0x179c
+#define GPIOPAD_EN                                        0x17a0
+
+#define GRBM_PWR_CNTL                                     0x800c
+#       define REQ_TYPE_MASK                              0xf
+#       define REQ_TYPE_SHIFT                             0
+#       define RSP_TYPE_MASK                              0xf0
+#       define RSP_TYPE_SHIFT                             4
+
 /*
  * UVD
  */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1048 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "r600d.h"
+#include "r600_dpm.h"
+#include "atom.h"
+
+const u32 r600_utc[R600_PM_NUMBER_OF_TC] =
+{
+	R600_UTC_DFLT_00,
+	R600_UTC_DFLT_01,
+	R600_UTC_DFLT_02,
+	R600_UTC_DFLT_03,
+	R600_UTC_DFLT_04,
+	R600_UTC_DFLT_05,
+	R600_UTC_DFLT_06,
+	R600_UTC_DFLT_07,
+	R600_UTC_DFLT_08,
+	R600_UTC_DFLT_09,
+	R600_UTC_DFLT_10,
+	R600_UTC_DFLT_11,
+	R600_UTC_DFLT_12,
+	R600_UTC_DFLT_13,
+	R600_UTC_DFLT_14,
+};
+
+const u32 r600_dtc[R600_PM_NUMBER_OF_TC] =
+{
+	R600_DTC_DFLT_00,
+	R600_DTC_DFLT_01,
+	R600_DTC_DFLT_02,
+	R600_DTC_DFLT_03,
+	R600_DTC_DFLT_04,
+	R600_DTC_DFLT_05,
+	R600_DTC_DFLT_06,
+	R600_DTC_DFLT_07,
+	R600_DTC_DFLT_08,
+	R600_DTC_DFLT_09,
+	R600_DTC_DFLT_10,
+	R600_DTC_DFLT_11,
+	R600_DTC_DFLT_12,
+	R600_DTC_DFLT_13,
+	R600_DTC_DFLT_14,
+};
+
+void r600_dpm_print_class_info(u32 class, u32 class2)
+{
+	printk("\tui class: ");
+	switch (class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
+	case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
+	default:
+		printk("none\n");
+		break;
+	case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
+		printk("battery\n");
+		break;
+	case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
+		printk("balanced\n");
+		break;
+	case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
+		printk("performance\n");
+		break;
+	}
+	printk("\tinternal class: ");
+	if (((class & ~ATOM_PPLIB_CLASSIFICATION_UI_MASK) == 0) &&
+	    (class2 == 0))
+		printk("none");
+	else {
+		if (class & ATOM_PPLIB_CLASSIFICATION_BOOT)
+			printk("boot ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
+			printk("thermal ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
+			printk("limited_pwr ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_REST)
+			printk("rest ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_FORCED)
+			printk("forced ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
+			printk("3d_perf ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE)
+			printk("ovrdrv ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+			printk("uvd ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_3DLOW)
+			printk("3d_low ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_ACPI)
+			printk("acpi ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
+			printk("uvd_hd2 ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
+			printk("uvd_hd ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
+			printk("uvd_sd ");
+		if (class2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
+			printk("limited_pwr2 ");
+		if (class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
+			printk("ulv ");
+		if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
+			printk("uvd_mvc ");
+	}
+	printk("\n");
+}
+
+void r600_dpm_print_cap_info(u32 caps)
+{
+	printk("\tcaps: ");
+	if (caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
+		printk("single_disp ");
+	if (caps & ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK)
+		printk("video ");
+	if (caps & ATOM_PPLIB_DISALLOW_ON_DC)
+		printk("no_dc ");
+	printk("\n");
+}
+
+void r600_dpm_print_ps_status(struct radeon_device *rdev,
+			      struct radeon_ps *rps)
+{
+	printk("\tstatus: ");
+	if (rps == rdev->pm.dpm.current_ps)
+		printk("c ");
+	if (rps == rdev->pm.dpm.requested_ps)
+		printk("r ");
+	if (rps == rdev->pm.dpm.boot_ps)
+		printk("b ");
+	printk("\n");
+}
+
+u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_crtc *crtc;
+	struct radeon_crtc *radeon_crtc;
+	u32 line_time_us, vblank_lines;
+	u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		radeon_crtc = to_radeon_crtc(crtc);
+		if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
+			line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
+				radeon_crtc->hw_mode.clock;
+			vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
+				radeon_crtc->hw_mode.crtc_vdisplay +
+				(radeon_crtc->v_border * 2);
+			vblank_time_us = vblank_lines * line_time_us;
+			break;
+		}
+	}
+
+	return vblank_time_us;
+}
+
+void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
+			    u32 *p, u32 *u)
+{
+	u32 b_c = 0;
+	u32 i_c;
+	u32 tmp;
+
+	i_c = (i * r_c) / 100;
+	tmp = i_c >> p_b;
+
+	while (tmp) {
+		b_c++;
+		tmp >>= 1;
+	}
+
+	*u = (b_c + 1) / 2;
+	*p = i_c / (1 << (2 * (*u)));
+}
+
+int r600_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th)
+{
+	u32 k, a, ah, al;
+	u32 t1;
+
+	if ((fl == 0) || (fh == 0) || (fl > fh))
+		return -EINVAL;
+
+	k = (100 * fh) / fl;
+	t1 = (t * (k - 100));
+	a = (1000 * (100 * h + t1)) / (10000 + (t1 / 100));
+	a = (a + 5) / 10;
+	ah = ((a * t) + 5000) / 10000;
+	al = a - ah;
+
+	*th = t - ah;
+	*tl = t + al;
+
+	return 0;
+}
+
+void r600_gfx_clockgating_enable(struct radeon_device *rdev, bool enable)
+{
+	int i;
+
+	if (enable) {
+		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
+	} else {
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
+
+		WREG32(CG_RLC_REQ_AND_RSP, 0x2);
+
+		for (i = 0; i < rdev->usec_timeout; i++) {
+			if (((RREG32(CG_RLC_REQ_AND_RSP) & CG_RLC_RSP_TYPE_MASK) >> CG_RLC_RSP_TYPE_SHIFT) == 1)
+				break;
+			udelay(1);
+		}
+
+		WREG32(CG_RLC_REQ_AND_RSP, 0x0);
+
+		WREG32(GRBM_PWR_CNTL, 0x1);
+		RREG32(GRBM_PWR_CNTL);
+	}
+}
+
+void r600_dynamicpm_enable(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
+}
+
+void r600_enable_thermal_protection(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
+	else
+		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
+}
+
+void r600_enable_acpi_pm(struct radeon_device *rdev)
+{
+	WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
+}
+
+void r600_enable_dynamic_pcie_gen2(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
+}
+
+bool r600_dynamicpm_enabled(struct radeon_device *rdev)
+{
+	if (RREG32(GENERAL_PWRMGT) & GLOBAL_PWRMGT_EN)
+		return true;
+	else
+		return false;
+}
+
+void r600_enable_sclk_control(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
+	else
+		WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
+}
+
+void r600_enable_mclk_control(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF);
+	else
+		WREG32_P(MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF);
+}
+
+void r600_enable_spll_bypass(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(CG_SPLL_FUNC_CNTL, SPLL_BYPASS_EN, ~SPLL_BYPASS_EN);
+	else
+		WREG32_P(CG_SPLL_FUNC_CNTL, 0, ~SPLL_BYPASS_EN);
+}
+
+void r600_wait_for_spll_change(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(CG_SPLL_FUNC_CNTL) & SPLL_CHG_STATUS)
+			break;
+		udelay(1);
+	}
+}
+
+void r600_set_bsp(struct radeon_device *rdev, u32 u, u32 p)
+{
+	WREG32(CG_BSP, BSP(p) | BSU(u));
+}
+
+void r600_set_at(struct radeon_device *rdev,
+		 u32 l_to_m, u32 m_to_h,
+		 u32 h_to_m, u32 m_to_l)
+{
+	WREG32(CG_RT, FLS(l_to_m) | FMS(m_to_h));
+	WREG32(CG_LT, FHS(h_to_m) | FMS(m_to_l));
+}
+
+void r600_set_tc(struct radeon_device *rdev,
+		 u32 index, u32 u_t, u32 d_t)
+{
+	WREG32(CG_FFCT_0 + (index * 4), UTC_0(u_t) | DTC_0(d_t));
+}
+
+void r600_select_td(struct radeon_device *rdev,
+		    enum r600_td td)
+{
+	if (td == R600_TD_AUTO)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
+	else
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
+	if (td == R600_TD_UP)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
+	if (td == R600_TD_DOWN)
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
+}
+
+void r600_set_vrc(struct radeon_device *rdev, u32 vrv)
+{
+	WREG32(CG_FTV, vrv);
+}
+
+void r600_set_tpu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(CG_TPC, TPU(u), ~TPU_MASK);
+}
+
+void r600_set_tpc(struct radeon_device *rdev, u32 c)
+{
+	WREG32_P(CG_TPC, TPCC(c), ~TPCC_MASK);
+}
+
+void r600_set_sstu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(CG_SSP, CG_SSTU(u), ~CG_SSTU_MASK);
+}
+
+void r600_set_sst(struct radeon_device *rdev, u32 t)
+{
+	WREG32_P(CG_SSP, CG_SST(t), ~CG_SST_MASK);
+}
+
+void r600_set_git(struct radeon_device *rdev, u32 t)
+{
+	WREG32_P(CG_GIT, CG_GICST(t), ~CG_GICST_MASK);
+}
+
+void r600_set_fctu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(CG_FC_T, FC_TU(u), ~FC_TU_MASK);
+}
+
+void r600_set_fct(struct radeon_device *rdev, u32 t)
+{
+	WREG32_P(CG_FC_T, FC_T(t), ~FC_T_MASK);
+}
+
+void r600_set_ctxcgtt3d_rphc(struct radeon_device *rdev, u32 p)
+{
+	WREG32_P(CG_CTX_CGTT3D_R, PHC(p), ~PHC_MASK);
+}
+
+void r600_set_ctxcgtt3d_rsdc(struct radeon_device *rdev, u32 s)
+{
+	WREG32_P(CG_CTX_CGTT3D_R, SDC(s), ~SDC_MASK);
+}
+
+void r600_set_vddc3d_oorsu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(CG_VDDC3D_OOR, SU(u), ~SU_MASK);
+}
+
+void r600_set_vddc3d_oorphc(struct radeon_device *rdev, u32 p)
+{
+	WREG32_P(CG_VDDC3D_OOR, PHC(p), ~PHC_MASK);
+}
+
+void r600_set_vddc3d_oorsdc(struct radeon_device *rdev, u32 s)
+{
+	WREG32_P(CG_VDDC3D_OOR, SDC(s), ~SDC_MASK);
+}
+
+void r600_set_mpll_lock_time(struct radeon_device *rdev, u32 lock_time)
+{
+	WREG32_P(MPLL_TIME, MPLL_LOCK_TIME(lock_time), ~MPLL_LOCK_TIME_MASK);
+}
+
+void r600_set_mpll_reset_time(struct radeon_device *rdev, u32 reset_time)
+{
+	WREG32_P(MPLL_TIME, MPLL_RESET_TIME(reset_time), ~MPLL_RESET_TIME_MASK);
+}
+
+void r600_engine_clock_entry_enable(struct radeon_device *rdev,
+				    u32 index, bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 STEP_0_SPLL_ENTRY_VALID, ~STEP_0_SPLL_ENTRY_VALID);
+	else
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 0, ~STEP_0_SPLL_ENTRY_VALID);
+}
+
+void r600_engine_clock_entry_enable_pulse_skipping(struct radeon_device *rdev,
+						   u32 index, bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 STEP_0_SPLL_STEP_ENABLE, ~STEP_0_SPLL_STEP_ENABLE);
+	else
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 0, ~STEP_0_SPLL_STEP_ENABLE);
+}
+
+void r600_engine_clock_entry_enable_post_divider(struct radeon_device *rdev,
+						 u32 index, bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 STEP_0_POST_DIV_EN, ~STEP_0_POST_DIV_EN);
+	else
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 0, ~STEP_0_POST_DIV_EN);
+}
+
+void r600_engine_clock_entry_set_post_divider(struct radeon_device *rdev,
+					      u32 index, u32 divider)
+{
+	WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
+		 STEP_0_SPLL_POST_DIV(divider), ~STEP_0_SPLL_POST_DIV_MASK);
+}
+
+void r600_engine_clock_entry_set_reference_divider(struct radeon_device *rdev,
+						   u32 index, u32 divider)
+{
+	WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
+		 STEP_0_SPLL_REF_DIV(divider), ~STEP_0_SPLL_REF_DIV_MASK);
+}
+
+void r600_engine_clock_entry_set_feedback_divider(struct radeon_device *rdev,
+						  u32 index, u32 divider)
+{
+	WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
+		 STEP_0_SPLL_FB_DIV(divider), ~STEP_0_SPLL_FB_DIV_MASK);
+}
+
+void r600_engine_clock_entry_set_step_time(struct radeon_device *rdev,
+					   u32 index, u32 step_time)
+{
+	WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
+		 STEP_0_SPLL_STEP_TIME(step_time), ~STEP_0_SPLL_STEP_TIME_MASK);
+}
+
+void r600_vid_rt_set_ssu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(VID_RT, SSTU(u), ~SSTU_MASK);
+}
+
+void r600_vid_rt_set_vru(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(VID_RT, VID_CRTU(u), ~VID_CRTU_MASK);
+}
+
+void r600_vid_rt_set_vrt(struct radeon_device *rdev, u32 rt)
+{
+	WREG32_P(VID_RT, VID_CRT(rt), ~VID_CRT_MASK);
+}
+
+void r600_voltage_control_enable_pins(struct radeon_device *rdev,
+				      u64 mask)
+{
+	WREG32(LOWER_GPIO_ENABLE, mask & 0xffffffff);
+	WREG32(UPPER_GPIO_ENABLE, upper_32_bits(mask));
+}
+
+
+void r600_voltage_control_program_voltages(struct radeon_device *rdev,
+					   enum r600_power_level index, u64 pins)
+{
+	u32 tmp, mask;
+	u32 ix = 3 - (3 & index);
+
+	WREG32(CTXSW_VID_LOWER_GPIO_CNTL + (ix * 4), pins & 0xffffffff);
+
+	mask = 7 << (3 * ix);
+	tmp = RREG32(VID_UPPER_GPIO_CNTL);
+	tmp = (tmp & ~mask) | ((pins >> (32 - (3 * ix))) & mask);
+	WREG32(VID_UPPER_GPIO_CNTL, tmp);
+}
+
+void r600_voltage_control_deactivate_static_control(struct radeon_device *rdev,
+						    u64 mask)
+{
+	u32 gpio;
+
+	gpio = RREG32(GPIOPAD_MASK);
+	gpio &= ~mask;
+	WREG32(GPIOPAD_MASK, gpio);
+
+	gpio = RREG32(GPIOPAD_EN);
+	gpio &= ~mask;
+	WREG32(GPIOPAD_EN, gpio);
+
+	gpio = RREG32(GPIOPAD_A);
+	gpio &= ~mask;
+	WREG32(GPIOPAD_A, gpio);
+}
+
+void r600_power_level_enable(struct radeon_device *rdev,
+			     enum r600_power_level index, bool enable)
+{
+	u32 ix = 3 - (3 & index);
+
+	if (enable)
+		WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), CTXSW_FREQ_STATE_ENABLE,
+			 ~CTXSW_FREQ_STATE_ENABLE);
+	else
+		WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), 0,
+			 ~CTXSW_FREQ_STATE_ENABLE);
+}
+
+void r600_power_level_set_voltage_index(struct radeon_device *rdev,
+					enum r600_power_level index, u32 voltage_index)
+{
+	u32 ix = 3 - (3 & index);
+
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4),
+		 CTXSW_FREQ_VIDS_CFG_INDEX(voltage_index), ~CTXSW_FREQ_VIDS_CFG_INDEX_MASK);
+}
+
+void r600_power_level_set_mem_clock_index(struct radeon_device *rdev,
+					  enum r600_power_level index, u32 mem_clock_index)
+{
+	u32 ix = 3 - (3 & index);
+
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4),
+		 CTXSW_FREQ_MCLK_CFG_INDEX(mem_clock_index), ~CTXSW_FREQ_MCLK_CFG_INDEX_MASK);
+}
+
+void r600_power_level_set_eng_clock_index(struct radeon_device *rdev,
+					  enum r600_power_level index, u32 eng_clock_index)
+{
+	u32 ix = 3 - (3 & index);
+
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4),
+		 CTXSW_FREQ_SCLK_CFG_INDEX(eng_clock_index), ~CTXSW_FREQ_SCLK_CFG_INDEX_MASK);
+}
+
+void r600_power_level_set_watermark_id(struct radeon_device *rdev,
+				       enum r600_power_level index,
+				       enum r600_display_watermark watermark_id)
+{
+	u32 ix = 3 - (3 & index);
+	u32 tmp = 0;
+
+	if (watermark_id == R600_DISPLAY_WATERMARK_HIGH)
+		tmp = CTXSW_FREQ_DISPLAY_WATERMARK;
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), tmp, ~CTXSW_FREQ_DISPLAY_WATERMARK);
+}
+
+void r600_power_level_set_pcie_gen2(struct radeon_device *rdev,
+				    enum r600_power_level index, bool compatible)
+{
+	u32 ix = 3 - (3 & index);
+	u32 tmp = 0;
+
+	if (compatible)
+		tmp = CTXSW_FREQ_GEN2PCIE_VOLT;
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), tmp, ~CTXSW_FREQ_GEN2PCIE_VOLT);
+}
+
+enum r600_power_level r600_power_level_get_current_index(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK;
+	tmp >>= CURRENT_PROFILE_INDEX_SHIFT;
+	return tmp;
+}
+
+enum r600_power_level r600_power_level_get_target_index(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_PROFILE_INDEX_MASK;
+	tmp >>= TARGET_PROFILE_INDEX_SHIFT;
+	return tmp;
+}
+
+void r600_power_level_set_enter_index(struct radeon_device *rdev,
+				      enum r600_power_level index)
+{
+	WREG32_P(TARGET_AND_CURRENT_PROFILE_INDEX, DYN_PWR_ENTER_INDEX(index),
+		 ~DYN_PWR_ENTER_INDEX_MASK);
+}
+
+void r600_wait_for_power_level_unequal(struct radeon_device *rdev,
+				       enum r600_power_level index)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (r600_power_level_get_target_index(rdev) != index)
+			break;
+		udelay(1);
+	}
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (r600_power_level_get_current_index(rdev) != index)
+			break;
+		udelay(1);
+	}
+}
+
+void r600_wait_for_power_level(struct radeon_device *rdev,
+			       enum r600_power_level index)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (r600_power_level_get_target_index(rdev) == index)
+			break;
+		udelay(1);
+	}
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (r600_power_level_get_current_index(rdev) == index)
+			break;
+		udelay(1);
+	}
+}
+
+void r600_start_dpm(struct radeon_device *rdev)
+{
+	r600_enable_sclk_control(rdev, false);
+	r600_enable_mclk_control(rdev, false);
+
+	r600_dynamicpm_enable(rdev, true);
+
+	radeon_wait_for_vblank(rdev, 0);
+	radeon_wait_for_vblank(rdev, 1);
+
+	r600_enable_spll_bypass(rdev, true);
+	r600_wait_for_spll_change(rdev);
+	r600_enable_spll_bypass(rdev, false);
+	r600_wait_for_spll_change(rdev);
+
+	r600_enable_spll_bypass(rdev, true);
+	r600_wait_for_spll_change(rdev);
+	r600_enable_spll_bypass(rdev, false);
+	r600_wait_for_spll_change(rdev);
+
+	r600_enable_sclk_control(rdev, true);
+	r600_enable_mclk_control(rdev, true);
+}
+
+void r600_stop_dpm(struct radeon_device *rdev)
+{
+	r600_dynamicpm_enable(rdev, false);
+}
+
+int r600_dpm_pre_set_power_state(struct radeon_device *rdev)
+{
+	return 0;
+}
+
+void r600_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+
+}
+
+bool r600_is_uvd_state(u32 class, u32 class2)
+{
+	if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		return true;
+	if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
+		return true;
+	if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
+		return true;
+	if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
+		return true;
+	if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
+		return true;
+	return false;
+}
+
+int r600_set_thermal_temperature_range(struct radeon_device *rdev,
+				       int min_temp, int max_temp)
+{
+	int low_temp = 0 * 1000;
+	int high_temp = 255 * 1000;
+
+	if (low_temp < min_temp)
+		low_temp = min_temp;
+	if (high_temp > max_temp)
+		high_temp = max_temp;
+	if (high_temp < low_temp) {
+		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
+		return -EINVAL;
+	}
+
+	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(high_temp / 1000), ~DIG_THERM_INTH_MASK);
+	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(low_temp / 1000), ~DIG_THERM_INTL_MASK);
+	WREG32_P(CG_THERMAL_CTRL, DIG_THERM_DPM(high_temp / 1000), ~DIG_THERM_DPM_MASK);
+
+	rdev->pm.dpm.thermal.min_temp = low_temp;
+	rdev->pm.dpm.thermal.max_temp = high_temp;
+
+	return 0;
+}
+
+bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor)
+{
+	switch (sensor) {
+	case THERMAL_TYPE_RV6XX:
+	case THERMAL_TYPE_RV770:
+	case THERMAL_TYPE_EVERGREEN:
+	case THERMAL_TYPE_SUMO:
+	case THERMAL_TYPE_NI:
+	case THERMAL_TYPE_SI:
+		return true;
+	case THERMAL_TYPE_ADT7473_WITH_INTERNAL:
+	case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
+		return false; /* need special handling */
+	case THERMAL_TYPE_NONE:
+	case THERMAL_TYPE_EXTERNAL:
+	case THERMAL_TYPE_EXTERNAL_GPIO:
+	default:
+		return false;
+	}
+}
+
+union power_info {
+	struct _ATOM_POWERPLAY_INFO info;
+	struct _ATOM_POWERPLAY_INFO_V2 info_2;
+	struct _ATOM_POWERPLAY_INFO_V3 info_3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
+	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
+	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4;
+	struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5;
+};
+
+union fan_info {
+	struct _ATOM_PPLIB_FANTABLE fan;
+	struct _ATOM_PPLIB_FANTABLE2 fan2;
+};
+
+static int r600_parse_clk_voltage_dep_table(struct radeon_clock_voltage_dependency_table *radeon_table,
+					    ATOM_PPLIB_Clock_Voltage_Dependency_Table *atom_table)
+{
+	u32 size = atom_table->ucNumEntries *
+		sizeof(struct radeon_clock_voltage_dependency_entry);
+	int i;
+
+	radeon_table->entries = kzalloc(size, GFP_KERNEL);
+	if (!radeon_table->entries)
+		return -ENOMEM;
+
+	for (i = 0; i < atom_table->ucNumEntries; i++) {
+		radeon_table->entries[i].clk = le16_to_cpu(atom_table->entries[i].usClockLow) |
+			(atom_table->entries[i].ucClockHigh << 16);
+		radeon_table->entries[i].v = le16_to_cpu(atom_table->entries[i].usVoltage);
+	}
+	radeon_table->count = atom_table->ucNumEntries;
+
+	return 0;
+}
+
+/* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 16
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 18
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 20
+#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 22
+
+int r600_parse_extended_power_table(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	union power_info *power_info;
+	union fan_info *fan_info;
+	ATOM_PPLIB_Clock_Voltage_Dependency_Table *dep_table;
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+        u16 data_offset;
+	u8 frev, crev;
+	int ret, i;
+
+	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset))
+		return -EINVAL;
+	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+
+	/* fan table */
+	if (le16_to_cpu(power_info->pplib.usTableSize) >=
+	    sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
+		if (power_info->pplib3.usFanTableOffset) {
+			fan_info = (union fan_info *)(mode_info->atom_context->bios + data_offset +
+						      le16_to_cpu(power_info->pplib3.usFanTableOffset));
+			rdev->pm.dpm.fan.t_hyst = fan_info->fan.ucTHyst;
+			rdev->pm.dpm.fan.t_min = le16_to_cpu(fan_info->fan.usTMin);
+			rdev->pm.dpm.fan.t_med = le16_to_cpu(fan_info->fan.usTMed);
+			rdev->pm.dpm.fan.t_high = le16_to_cpu(fan_info->fan.usTHigh);
+			rdev->pm.dpm.fan.pwm_min = le16_to_cpu(fan_info->fan.usPWMMin);
+			rdev->pm.dpm.fan.pwm_med = le16_to_cpu(fan_info->fan.usPWMMed);
+			rdev->pm.dpm.fan.pwm_high = le16_to_cpu(fan_info->fan.usPWMHigh);
+			if (fan_info->fan.ucFanTableFormat >= 2)
+				rdev->pm.dpm.fan.t_max = le16_to_cpu(fan_info->fan2.usTMax);
+			else
+				rdev->pm.dpm.fan.t_max = 10900;
+			rdev->pm.dpm.fan.cycle_delay = 100000;
+			rdev->pm.dpm.fan.ucode_fan_control = true;
+		}
+	}
+
+	/* clock dependancy tables, shedding tables */
+	if (le16_to_cpu(power_info->pplib.usTableSize) >=
+	    sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE4)) {
+		if (power_info->pplib4.usVddcDependencyOnSCLKOffset) {
+			dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
+				(mode_info->atom_context->bios + data_offset +
+				 le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset));
+			ret = r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
+							       dep_table);
+			if (ret)
+				return ret;
+		}
+		if (power_info->pplib4.usVddciDependencyOnMCLKOffset) {
+			dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
+				(mode_info->atom_context->bios + data_offset +
+				 le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset));
+			ret = r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+							       dep_table);
+			if (ret) {
+				kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
+				return ret;
+			}
+		}
+		if (power_info->pplib4.usVddcDependencyOnMCLKOffset) {
+			dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
+				(mode_info->atom_context->bios + data_offset +
+				 le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset));
+			ret = r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+							       dep_table);
+			if (ret) {
+				kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
+				kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries);
+				return ret;
+			}
+		}
+		if (power_info->pplib4.usMaxClockVoltageOnDCOffset) {
+			ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v =
+				(ATOM_PPLIB_Clock_Voltage_Limit_Table *)
+				(mode_info->atom_context->bios + data_offset +
+				 le16_to_cpu(power_info->pplib4.usMaxClockVoltageOnDCOffset));
+			if (clk_v->ucNumEntries) {
+				rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk =
+					le16_to_cpu(clk_v->entries[0].usSclkLow) |
+					(clk_v->entries[0].ucSclkHigh << 16);
+				rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk =
+					le16_to_cpu(clk_v->entries[0].usMclkLow) |
+					(clk_v->entries[0].ucMclkHigh << 16);
+				rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc =
+					le16_to_cpu(clk_v->entries[0].usVddc);
+				rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddci =
+					le16_to_cpu(clk_v->entries[0].usVddci);
+			}
+		}
+		if (power_info->pplib4.usVddcPhaseShedLimitsTableOffset) {
+			ATOM_PPLIB_PhaseSheddingLimits_Table *psl =
+				(ATOM_PPLIB_PhaseSheddingLimits_Table *)
+				(mode_info->atom_context->bios + data_offset +
+				 le16_to_cpu(power_info->pplib4.usVddcPhaseShedLimitsTableOffset));
+
+			rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries =
+				kzalloc(psl->ucNumEntries *
+					sizeof(struct radeon_phase_shedding_limits_entry),
+					GFP_KERNEL);
+			if (!rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) {
+				kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
+				kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries);
+				kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk.entries);
+				return -ENOMEM;
+			}
+
+			for (i = 0; i < psl->ucNumEntries; i++) {
+				rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].sclk =
+					le16_to_cpu(psl->entries[i].usSclkLow) |
+					(psl->entries[i].ucSclkHigh << 16);
+				rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].mclk =
+					le16_to_cpu(psl->entries[i].usMclkLow) |
+					(psl->entries[i].ucMclkHigh << 16);
+				rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].voltage =
+					le16_to_cpu(psl->entries[i].usVoltage);
+			}
+			rdev->pm.dpm.dyn_state.phase_shedding_limits_table.count =
+				psl->ucNumEntries;
+		}
+	}
+
+	/* cac data */
+	if (le16_to_cpu(power_info->pplib.usTableSize) >=
+	    sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE5)) {
+		rdev->pm.dpm.tdp_limit = le32_to_cpu(power_info->pplib5.ulTDPLimit);
+		rdev->pm.dpm.near_tdp_limit = le32_to_cpu(power_info->pplib5.ulNearTDPLimit);
+		rdev->pm.dpm.near_tdp_limit_adjusted = rdev->pm.dpm.near_tdp_limit;
+		rdev->pm.dpm.tdp_od_limit = le16_to_cpu(power_info->pplib5.usTDPODLimit);
+		if (rdev->pm.dpm.tdp_od_limit)
+			rdev->pm.dpm.power_control = true;
+		else
+			rdev->pm.dpm.power_control = false;
+		rdev->pm.dpm.tdp_adjustment = 0;
+		rdev->pm.dpm.sq_ramping_threshold = le32_to_cpu(power_info->pplib5.ulSQRampingThreshold);
+		rdev->pm.dpm.cac_leakage = le32_to_cpu(power_info->pplib5.ulCACLeakage);
+		rdev->pm.dpm.load_line_slope = le16_to_cpu(power_info->pplib5.usLoadLineSlope);
+		if (power_info->pplib5.usCACLeakageTableOffset) {
+			ATOM_PPLIB_CAC_Leakage_Table *cac_table =
+				(ATOM_PPLIB_CAC_Leakage_Table *)
+				(mode_info->atom_context->bios + data_offset +
+				 le16_to_cpu(power_info->pplib5.usCACLeakageTableOffset));
+			u32 size = cac_table->ucNumEntries * sizeof(struct radeon_cac_leakage_table);
+			rdev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL);
+			if (!rdev->pm.dpm.dyn_state.cac_leakage_table.entries) {
+				kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
+				kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries);
+				kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk.entries);
+				return -ENOMEM;
+			}
+			for (i = 0; i < cac_table->ucNumEntries; i++) {
+				rdev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc =
+					le16_to_cpu(cac_table->entries[i].usVddc);
+				rdev->pm.dpm.dyn_state.cac_leakage_table.entries[i].leakage =
+					le32_to_cpu(cac_table->entries[i].ulLeakageValue);
+			}
+			rdev->pm.dpm.dyn_state.cac_leakage_table.count = cac_table->ucNumEntries;
+		}
+	}
+
+	/* ppm table */
+	if (le16_to_cpu(power_info->pplib.usTableSize) >=
+	    sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
+		ATOM_PPLIB_EXTENDEDHEADER *ext_hdr = (ATOM_PPLIB_EXTENDEDHEADER *)
+			(mode_info->atom_context->bios + data_offset +
+			 le16_to_cpu(power_info->pplib3.usExtendendedHeaderOffset));
+		if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5) &&
+		    ext_hdr->usPPMTableOffset) {
+			ATOM_PPLIB_PPM_Table *ppm = (ATOM_PPLIB_PPM_Table *)
+				(mode_info->atom_context->bios + data_offset +
+				 le16_to_cpu(ext_hdr->usPPMTableOffset));
+			rdev->pm.dpm.dyn_state.ppm_table =
+				kzalloc(sizeof(struct radeon_ppm_table), GFP_KERNEL);
+			if (!rdev->pm.dpm.dyn_state.ppm_table) {
+				kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
+				kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries);
+				kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk.entries);
+				kfree(rdev->pm.dpm.dyn_state.cac_leakage_table.entries);
+				return -ENOMEM;
+			}
+			rdev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign;
+			rdev->pm.dpm.dyn_state.ppm_table->cpu_core_number =
+				le16_to_cpu(ppm->usCpuCoreNumber);
+			rdev->pm.dpm.dyn_state.ppm_table->platform_tdp =
+				le32_to_cpu(ppm->ulPlatformTDP);
+			rdev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdp =
+				le32_to_cpu(ppm->ulSmallACPlatformTDP);
+			rdev->pm.dpm.dyn_state.ppm_table->platform_tdc =
+				le32_to_cpu(ppm->ulPlatformTDC);
+			rdev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdc =
+				le32_to_cpu(ppm->ulSmallACPlatformTDC);
+			rdev->pm.dpm.dyn_state.ppm_table->apu_tdp =
+				le32_to_cpu(ppm->ulApuTDP);
+			rdev->pm.dpm.dyn_state.ppm_table->dgpu_tdp =
+				le32_to_cpu(ppm->ulDGpuTDP);
+			rdev->pm.dpm.dyn_state.ppm_table->dgpu_ulv_power =
+				le32_to_cpu(ppm->ulDGpuUlvPower);
+			rdev->pm.dpm.dyn_state.ppm_table->tj_max =
+				le32_to_cpu(ppm->ulTjmax);
+		}
+	}
+
+	return 0;
+}
+
+void r600_free_extended_power_table(struct radeon_device *rdev)
+{
+	if (rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries)
+		kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
+	if (rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries)
+		kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries);
+	if (rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk.entries)
+		kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk.entries);
+	if (rdev->pm.dpm.dyn_state.cac_leakage_table.entries)
+		kfree(rdev->pm.dpm.dyn_state.cac_leakage_table.entries);
+	if (rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries)
+		kfree(rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries);
+	if (rdev->pm.dpm.dyn_state.ppm_table)
+		kfree(rdev->pm.dpm.dyn_state.ppm_table);
+}
+
+enum radeon_pcie_gen r600_get_pcie_gen_support(struct radeon_device *rdev,
+					       u32 sys_mask,
+					       enum radeon_pcie_gen asic_gen,
+					       enum radeon_pcie_gen default_gen)
+{
+	switch (asic_gen) {
+	case RADEON_PCIE_GEN1:
+		return RADEON_PCIE_GEN1;
+	case RADEON_PCIE_GEN2:
+		return RADEON_PCIE_GEN2;
+	case RADEON_PCIE_GEN3:
+		return RADEON_PCIE_GEN3;
+	default:
+		if ((sys_mask & DRM_PCIE_SPEED_80) && (default_gen == RADEON_PCIE_GEN3))
+			return RADEON_PCIE_GEN3;
+		else if ((sys_mask & DRM_PCIE_SPEED_50) && (default_gen == RADEON_PCIE_GEN2))
+			return RADEON_PCIE_GEN2;
+		else
+			return RADEON_PCIE_GEN1;
+	}
+	return RADEON_PCIE_GEN1;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __R600_DPM_H__
+#define __R600_DPM_H__
+
+#define R600_ASI_DFLT                                10000
+#define R600_BSP_DFLT                                0x41EB
+#define R600_BSU_DFLT                                0x2
+#define R600_AH_DFLT                                 5
+#define R600_RLP_DFLT                                25
+#define R600_RMP_DFLT                                65
+#define R600_LHP_DFLT                                40
+#define R600_LMP_DFLT                                15
+#define R600_TD_DFLT                                 0
+#define R600_UTC_DFLT_00                             0x24
+#define R600_UTC_DFLT_01                             0x22
+#define R600_UTC_DFLT_02                             0x22
+#define R600_UTC_DFLT_03                             0x22
+#define R600_UTC_DFLT_04                             0x22
+#define R600_UTC_DFLT_05                             0x22
+#define R600_UTC_DFLT_06                             0x22
+#define R600_UTC_DFLT_07                             0x22
+#define R600_UTC_DFLT_08                             0x22
+#define R600_UTC_DFLT_09                             0x22
+#define R600_UTC_DFLT_10                             0x22
+#define R600_UTC_DFLT_11                             0x22
+#define R600_UTC_DFLT_12                             0x22
+#define R600_UTC_DFLT_13                             0x22
+#define R600_UTC_DFLT_14                             0x22
+#define R600_DTC_DFLT_00                             0x24
+#define R600_DTC_DFLT_01                             0x22
+#define R600_DTC_DFLT_02                             0x22
+#define R600_DTC_DFLT_03                             0x22
+#define R600_DTC_DFLT_04                             0x22
+#define R600_DTC_DFLT_05                             0x22
+#define R600_DTC_DFLT_06                             0x22
+#define R600_DTC_DFLT_07                             0x22
+#define R600_DTC_DFLT_08                             0x22
+#define R600_DTC_DFLT_09                             0x22
+#define R600_DTC_DFLT_10                             0x22
+#define R600_DTC_DFLT_11                             0x22
+#define R600_DTC_DFLT_12                             0x22
+#define R600_DTC_DFLT_13                             0x22
+#define R600_DTC_DFLT_14                             0x22
+#define R600_VRC_DFLT                                0x0000C003
+#define R600_VOLTAGERESPONSETIME_DFLT                1000
+#define R600_BACKBIASRESPONSETIME_DFLT               1000
+#define R600_VRU_DFLT                                0x3
+#define R600_SPLLSTEPTIME_DFLT                       0x1000
+#define R600_SPLLSTEPUNIT_DFLT                       0x3
+#define R600_TPU_DFLT                                0
+#define R600_TPC_DFLT                                0x200
+#define R600_SSTU_DFLT                               0
+#define R600_SST_DFLT                                0x00C8
+#define R600_GICST_DFLT                              0x200
+#define R600_FCT_DFLT                                0x0400
+#define R600_FCTU_DFLT                               0
+#define R600_CTXCGTT3DRPHC_DFLT                      0x20
+#define R600_CTXCGTT3DRSDC_DFLT                      0x40
+#define R600_VDDC3DOORPHC_DFLT                       0x100
+#define R600_VDDC3DOORSDC_DFLT                       0x7
+#define R600_VDDC3DOORSU_DFLT                        0
+#define R600_MPLLLOCKTIME_DFLT                       100
+#define R600_MPLLRESETTIME_DFLT                      150
+#define R600_VCOSTEPPCT_DFLT                          20
+#define R600_ENDINGVCOSTEPPCT_DFLT                    5
+#define R600_REFERENCEDIVIDER_DFLT                    4
+
+#define R600_PM_NUMBER_OF_TC 15
+#define R600_PM_NUMBER_OF_SCLKS 20
+#define R600_PM_NUMBER_OF_MCLKS 4
+#define R600_PM_NUMBER_OF_VOLTAGE_LEVELS 4
+#define R600_PM_NUMBER_OF_ACTIVITY_LEVELS 3
+
+/* XXX are these ok? */
+#define R600_TEMP_RANGE_MIN (90 * 1000)
+#define R600_TEMP_RANGE_MAX (120 * 1000)
+
+enum r600_power_level {
+	R600_POWER_LEVEL_LOW = 0,
+	R600_POWER_LEVEL_MEDIUM = 1,
+	R600_POWER_LEVEL_HIGH = 2,
+	R600_POWER_LEVEL_CTXSW = 3,
+};
+
+enum r600_td {
+	R600_TD_AUTO,
+	R600_TD_UP,
+	R600_TD_DOWN,
+};
+
+enum r600_display_watermark {
+	R600_DISPLAY_WATERMARK_LOW = 0,
+	R600_DISPLAY_WATERMARK_HIGH = 1,
+};
+
+enum r600_display_gap
+{
+    R600_PM_DISPLAY_GAP_VBLANK_OR_WM = 0,
+    R600_PM_DISPLAY_GAP_VBLANK       = 1,
+    R600_PM_DISPLAY_GAP_WATERMARK    = 2,
+    R600_PM_DISPLAY_GAP_IGNORE       = 3,
+};
+
+extern const u32 r600_utc[R600_PM_NUMBER_OF_TC];
+extern const u32 r600_dtc[R600_PM_NUMBER_OF_TC];
+
+void r600_dpm_print_class_info(u32 class, u32 class2);
+void r600_dpm_print_cap_info(u32 caps);
+void r600_dpm_print_ps_status(struct radeon_device *rdev,
+			      struct radeon_ps *rps);
+u32 r600_dpm_get_vblank_time(struct radeon_device *rdev);
+bool r600_is_uvd_state(u32 class, u32 class2);
+void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
+			    u32 *p, u32 *u);
+int r600_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th);
+void r600_gfx_clockgating_enable(struct radeon_device *rdev, bool enable);
+void r600_dynamicpm_enable(struct radeon_device *rdev, bool enable);
+void r600_enable_thermal_protection(struct radeon_device *rdev, bool enable);
+void r600_enable_acpi_pm(struct radeon_device *rdev);
+void r600_enable_dynamic_pcie_gen2(struct radeon_device *rdev, bool enable);
+bool r600_dynamicpm_enabled(struct radeon_device *rdev);
+void r600_enable_sclk_control(struct radeon_device *rdev, bool enable);
+void r600_enable_mclk_control(struct radeon_device *rdev, bool enable);
+void r600_enable_spll_bypass(struct radeon_device *rdev, bool enable);
+void r600_wait_for_spll_change(struct radeon_device *rdev);
+void r600_set_bsp(struct radeon_device *rdev, u32 u, u32 p);
+void r600_set_at(struct radeon_device *rdev,
+		 u32 l_to_m, u32 m_to_h,
+		 u32 h_to_m, u32 m_to_l);
+void r600_set_tc(struct radeon_device *rdev, u32 index, u32 u_t, u32 d_t);
+void r600_select_td(struct radeon_device *rdev, enum r600_td td);
+void r600_set_vrc(struct radeon_device *rdev, u32 vrv);
+void r600_set_tpu(struct radeon_device *rdev, u32 u);
+void r600_set_tpc(struct radeon_device *rdev, u32 c);
+void r600_set_sstu(struct radeon_device *rdev, u32 u);
+void r600_set_sst(struct radeon_device *rdev, u32 t);
+void r600_set_git(struct radeon_device *rdev, u32 t);
+void r600_set_fctu(struct radeon_device *rdev, u32 u);
+void r600_set_fct(struct radeon_device *rdev, u32 t);
+void r600_set_ctxcgtt3d_rphc(struct radeon_device *rdev, u32 p);
+void r600_set_ctxcgtt3d_rsdc(struct radeon_device *rdev, u32 s);
+void r600_set_vddc3d_oorsu(struct radeon_device *rdev, u32 u);
+void r600_set_vddc3d_oorphc(struct radeon_device *rdev, u32 p);
+void r600_set_vddc3d_oorsdc(struct radeon_device *rdev, u32 s);
+void r600_set_mpll_lock_time(struct radeon_device *rdev, u32 lock_time);
+void r600_set_mpll_reset_time(struct radeon_device *rdev, u32 reset_time);
+void r600_engine_clock_entry_enable(struct radeon_device *rdev,
+				    u32 index, bool enable);
+void r600_engine_clock_entry_enable_pulse_skipping(struct radeon_device *rdev,
+						   u32 index, bool enable);
+void r600_engine_clock_entry_enable_post_divider(struct radeon_device *rdev,
+						 u32 index, bool enable);
+void r600_engine_clock_entry_set_post_divider(struct radeon_device *rdev,
+					      u32 index, u32 divider);
+void r600_engine_clock_entry_set_reference_divider(struct radeon_device *rdev,
+						   u32 index, u32 divider);
+void r600_engine_clock_entry_set_feedback_divider(struct radeon_device *rdev,
+						  u32 index, u32 divider);
+void r600_engine_clock_entry_set_step_time(struct radeon_device *rdev,
+					   u32 index, u32 step_time);
+void r600_vid_rt_set_ssu(struct radeon_device *rdev, u32 u);
+void r600_vid_rt_set_vru(struct radeon_device *rdev, u32 u);
+void r600_vid_rt_set_vrt(struct radeon_device *rdev, u32 rt);
+void r600_voltage_control_enable_pins(struct radeon_device *rdev,
+				      u64 mask);
+void r600_voltage_control_program_voltages(struct radeon_device *rdev,
+					   enum r600_power_level index, u64 pins);
+void r600_voltage_control_deactivate_static_control(struct radeon_device *rdev,
+						    u64 mask);
+void r600_power_level_enable(struct radeon_device *rdev,
+			     enum r600_power_level index, bool enable);
+void r600_power_level_set_voltage_index(struct radeon_device *rdev,
+					enum r600_power_level index, u32 voltage_index);
+void r600_power_level_set_mem_clock_index(struct radeon_device *rdev,
+					  enum r600_power_level index, u32 mem_clock_index);
+void r600_power_level_set_eng_clock_index(struct radeon_device *rdev,
+					  enum r600_power_level index, u32 eng_clock_index);
+void r600_power_level_set_watermark_id(struct radeon_device *rdev,
+				       enum r600_power_level index,
+				       enum r600_display_watermark watermark_id);
+void r600_power_level_set_pcie_gen2(struct radeon_device *rdev,
+				    enum r600_power_level index, bool compatible);
+enum r600_power_level r600_power_level_get_current_index(struct radeon_device *rdev);
+enum r600_power_level r600_power_level_get_target_index(struct radeon_device *rdev);
+void r600_power_level_set_enter_index(struct radeon_device *rdev,
+				      enum r600_power_level index);
+void r600_wait_for_power_level_unequal(struct radeon_device *rdev,
+				       enum r600_power_level index);
+void r600_wait_for_power_level(struct radeon_device *rdev,
+			       enum r600_power_level index);
+void r600_start_dpm(struct radeon_device *rdev);
+void r600_stop_dpm(struct radeon_device *rdev);
+
+int r600_set_thermal_temperature_range(struct radeon_device *rdev,
+				       int min_temp, int max_temp);
+bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor);
+
+int r600_parse_extended_power_table(struct radeon_device *rdev);
+void r600_free_extended_power_table(struct radeon_device *rdev);
+
+enum radeon_pcie_gen r600_get_pcie_gen_support(struct radeon_device *rdev,
+					       u32 sys_mask,
+					       enum radeon_pcie_gen asic_gen,
+					       enum radeon_pcie_gen default_gen);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600_hdmi.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600_hdmi.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600_hdmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600_hdmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -133,14 +133,7 @@ static void r600_hdmi_update_avi_infofra
 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 	uint32_t offset = dig->afmt->offset;
 	uint8_t *frame = buffer + 3;
-
-	/* Our header values (type, version, length) should be alright, Intel
-	 * is using the same. Checksum function also seems to be OK, it works
-	 * fine for audio infoframe. However calculated value is always lower
-	 * by 2 in comparison to fglrx. It breaks displaying anything in case
-	 * of TVs that strictly check the checksum. Hack it manually here to
-	 * workaround this issue. */
-	frame[0x0] += 2;
+	uint8_t *header = buffer;
 
 	WREG32(HDMI0_AVI_INFO0 + offset,
 		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
@@ -149,7 +142,7 @@ static void r600_hdmi_update_avi_infofra
 	WREG32(HDMI0_AVI_INFO2 + offset,
 		frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
 	WREG32(HDMI0_AVI_INFO3 + offset,
-		frame[0xC] | (frame[0xD] << 8));
+		frame[0xC] | (frame[0xD] << 8) | (header[1] << 24));
 }
 
 /*
@@ -233,10 +226,29 @@ void r600_audio_set_dto(struct drm_encod
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 	u32 base_rate = 24000;
+	u32 max_ratio = clock / base_rate;
+	u32 dto_phase;
+	u32 dto_modulo = clock;
+	u32 wallclock_ratio;
+	u32 dto_cntl;
 
 	if (!dig || !dig->afmt)
 		return;
 
+	if (max_ratio >= 8) {
+		dto_phase = 192 * 1000;
+		wallclock_ratio = 3;
+	} else if (max_ratio >= 4) {
+		dto_phase = 96 * 1000;
+		wallclock_ratio = 2;
+	} else if (max_ratio >= 2) {
+		dto_phase = 48 * 1000;
+		wallclock_ratio = 1;
+	} else {
+		dto_phase = 24 * 1000;
+		wallclock_ratio = 0;
+	}
+
 	/* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT.
 	 * doesn't matter which one you use.  Just use the first one.
 	 */
@@ -249,9 +261,21 @@ void r600_audio_set_dto(struct drm_encod
 		/* according to the reg specs, this should DCE3.2 only, but in
 		 * practice it seems to cover DCE3.0 as well.
 		 */
-		WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
-		WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
-		WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
+		if (dig->dig_encoder == 0) {
+			dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+			dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
+			WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
+			WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
+			WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
+			WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
+		} else {
+			dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
+			dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
+			WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl);
+			WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase);
+			WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo);
+			WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
+		}
 	} else {
 		/* according to the reg specs, this should be DCE2.0 and DCE3.0 */
 		WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) |
@@ -273,6 +297,9 @@ void r600_hdmi_setmode(struct drm_encode
 	uint32_t offset;
 	ssize_t err;
 
+	if (!dig || !dig->afmt)
+		return;
+
 	/* Silent, r600_hdmi_enable will raise WARN for us */
 	if (!dig->afmt->enabled)
 		return;
@@ -455,6 +482,9 @@ void r600_hdmi_enable(struct drm_encoder
 	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 	u32 hdmi = HDMI0_ERROR_ACK;
 
+	if (!dig || !dig->afmt)
+		return;
+
 	/* Silent, r600_hdmi_enable will raise WARN for us */
 	if (enable && dig->afmt->enabled)
 		return;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600_reg.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600_reg.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/r600_reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/r600_reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,12 @@
 #define R600_PCIE_PORT_INDEX                0x0038
 #define R600_PCIE_PORT_DATA                 0x003c
 
+#define R600_RCU_INDEX                      0x0100
+#define R600_RCU_DATA                       0x0104
+
+#define R600_UVD_CTX_INDEX                  0xf4a0
+#define R600_UVD_CTX_DATA                   0xf4a4
+
 #define R600_MC_VM_FB_LOCATION			0x2180
 #define		R600_MC_FB_BASE_MASK			0x0000FFFF
 #define		R600_MC_FB_BASE_SHIFT			0
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_acpi.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_acpi.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_acpi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_acpi.c	2013-08-25 20:43:22.000000000 -0400
@@ -78,6 +78,22 @@ struct atcs_verify_interface {
 	u32 function_bits;	/* supported functions bit vector */
 } __packed;
 
+#define ATCS_VALID_FLAGS_MASK	0x3
+
+struct atcs_pref_req_input {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u16 client_id;		/* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
+	u16 valid_flags_mask;	/* valid flags mask */
+	u16 flags;		/* flags */
+	u8 req_type;		/* request type */
+	u8 perf_req;		/* performance request */
+} __packed;
+
+struct atcs_pref_req_output {
+	u16 size;		/* structure size in bytes (includes size field) */
+	u8 ret_val;		/* return value */
+} __packed;
+
 /* Call the ATIF method
  */
 /**
@@ -506,6 +522,135 @@ out:
 }
 
 /**
+ * radeon_acpi_is_pcie_performance_request_supported
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Check if the ATCS pcie_perf_req and pcie_dev_rdy methods
+ * are supported (all asics).
+ * returns true if supported, false if not.
+ */
+bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev)
+{
+	struct radeon_atcs *atcs = &rdev->atcs;
+
+	if (atcs->functions.pcie_perf_req && atcs->functions.pcie_dev_rdy)
+		return true;
+
+	return false;
+}
+
+/**
+ * radeon_acpi_pcie_notify_device_ready
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Executes the PCIE_DEVICE_READY_NOTIFICATION method
+ * (all asics).
+ * returns 0 on success, error on failure.
+ */
+int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev)
+{
+	acpi_handle handle;
+	union acpi_object *info;
+	struct radeon_atcs *atcs = &rdev->atcs;
+
+	/* Get the device handle */
+	handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
+	if (!handle)
+		return -EINVAL;
+
+	if (!atcs->functions.pcie_dev_rdy)
+		return -EINVAL;
+
+	info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION, NULL);
+	if (!info)
+		return -EIO;
+
+	kfree(info);
+
+	return 0;
+}
+
+/**
+ * radeon_acpi_pcie_performance_request
+ *
+ * @rdev: radeon_device pointer
+ * @perf_req: requested perf level (pcie gen speed)
+ * @advertise: set advertise caps flag if set
+ *
+ * Executes the PCIE_PERFORMANCE_REQUEST method to
+ * change the pcie gen speed (all asics).
+ * returns 0 on success, error on failure.
+ */
+int radeon_acpi_pcie_performance_request(struct radeon_device *rdev,
+					 u8 perf_req, bool advertise)
+{
+	acpi_handle handle;
+	union acpi_object *info;
+	struct radeon_atcs *atcs = &rdev->atcs;
+	struct atcs_pref_req_input atcs_input;
+	struct atcs_pref_req_output atcs_output;
+	struct acpi_buffer params;
+	size_t size;
+	u32 retry = 3;
+
+	/* Get the device handle */
+	handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
+	if (!handle)
+		return -EINVAL;
+
+	if (!atcs->functions.pcie_perf_req)
+		return -EINVAL;
+
+	atcs_input.size = sizeof(struct atcs_pref_req_input);
+	/* client id (bit 2-0: func num, 7-3: dev num, 15-8: bus num) */
+	atcs_input.client_id = rdev->pdev->devfn | (rdev->pdev->bus->number << 8);
+	atcs_input.valid_flags_mask = ATCS_VALID_FLAGS_MASK;
+	atcs_input.flags = ATCS_WAIT_FOR_COMPLETION;
+	if (advertise)
+		atcs_input.flags |= ATCS_ADVERTISE_CAPS;
+	atcs_input.req_type = ATCS_PCIE_LINK_SPEED;
+	atcs_input.perf_req = perf_req;
+
+	params.length = sizeof(struct atcs_pref_req_input);
+	params.pointer = &atcs_input;
+
+	while (retry--) {
+		info = radeon_atcs_call(handle, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST, &params);
+		if (!info)
+			return -EIO;
+
+		memset(&atcs_output, 0, sizeof(atcs_output));
+
+		size = *(u16 *) info->buffer.pointer;
+		if (size < 3) {
+			DRM_INFO("ATCS buffer is too small: %zu\n", size);
+			kfree(info);
+			return -EINVAL;
+		}
+		size = min(sizeof(atcs_output), size);
+
+		memcpy(&atcs_output, info->buffer.pointer, size);
+
+		kfree(info);
+
+		switch (atcs_output.ret_val) {
+		case ATCS_REQUEST_REFUSED:
+		default:
+			return -EINVAL;
+		case ATCS_REQUEST_COMPLETE:
+			return 0;
+		case ATCS_REQUEST_IN_PROGRESS:
+			udelay(10);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/**
  * radeon_acpi_event - handle notify events
  *
  * @nb: notifier block
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_asic.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_asic.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_asic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_asic.c	2013-08-25 20:43:22.000000000 -0400
@@ -126,7 +126,11 @@ static void radeon_register_accessor_ini
 		rdev->mc_rreg = &rs780_mc_rreg;
 		rdev->mc_wreg = &rs780_mc_wreg;
 	}
-	if (rdev->family >= CHIP_R600) {
+
+	if (rdev->family >= CHIP_BONAIRE) {
+		rdev->pciep_rreg = &cik_pciep_rreg;
+		rdev->pciep_wreg = &cik_pciep_wreg;
+	} else if (rdev->family >= CHIP_R600) {
 		rdev->pciep_rreg = &r600_pciep_rreg;
 		rdev->pciep_wreg = &r600_pciep_wreg;
 	}
@@ -192,6 +196,9 @@ static struct radeon_asic r100_asic = {
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -268,6 +275,9 @@ static struct radeon_asic r200_asic = {
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -344,6 +354,9 @@ static struct radeon_asic r300_asic = {
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -420,6 +433,9 @@ static struct radeon_asic r300_asic_pcie
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -496,6 +512,9 @@ static struct radeon_asic r420_asic = {
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -572,6 +591,9 @@ static struct radeon_asic rs400_asic = {
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -648,6 +670,9 @@ static struct radeon_asic rs600_asic = {
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -726,6 +751,9 @@ static struct radeon_asic rs690_asic = {
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -804,6 +832,9 @@ static struct radeon_asic rv515_asic = {
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -880,6 +911,9 @@ static struct radeon_asic r520_asic = {
 			.ring_test = &r100_ring_test,
 			.ib_test = &r100_ib_test,
 			.is_lockup = &r100_gpu_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -957,6 +991,9 @@ static struct radeon_asic r600_asic = {
 			.ring_test = &r600_ring_test,
 			.ib_test = &r600_ib_test,
 			.is_lockup = &r600_gfx_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_DMA_INDEX] = {
 			.ib_execute = &r600_dma_ring_ib_execute,
@@ -966,6 +1003,9 @@ static struct radeon_asic r600_asic = {
 			.ring_test = &r600_dma_ring_test,
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &r600_dma_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -986,8 +1026,101 @@ static struct radeon_asic r600_asic = {
 		.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
 		.dma = &r600_copy_dma,
 		.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
-		.copy = &r600_copy_dma,
-		.copy_ring_index = R600_RING_TYPE_DMA_INDEX,
+		.copy = &r600_copy_cpdma,
+		.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+	},
+	.surface = {
+		.set_reg = r600_set_surface_reg,
+		.clear_reg = r600_clear_surface_reg,
+	},
+	.hpd = {
+		.init = &r600_hpd_init,
+		.fini = &r600_hpd_fini,
+		.sense = &r600_hpd_sense,
+		.set_polarity = &r600_hpd_set_polarity,
+	},
+	.pm = {
+		.misc = &r600_pm_misc,
+		.prepare = &rs600_pm_prepare,
+		.finish = &rs600_pm_finish,
+		.init_profile = &r600_pm_init_profile,
+		.get_dynpm_state = &r600_pm_get_dynpm_state,
+		.get_engine_clock = &radeon_atom_get_engine_clock,
+		.set_engine_clock = &radeon_atom_set_engine_clock,
+		.get_memory_clock = &radeon_atom_get_memory_clock,
+		.set_memory_clock = &radeon_atom_set_memory_clock,
+		.get_pcie_lanes = &r600_get_pcie_lanes,
+		.set_pcie_lanes = &r600_set_pcie_lanes,
+		.set_clock_gating = NULL,
+		.get_temperature = &rv6xx_get_temp,
+	},
+	.pflip = {
+		.pre_page_flip = &rs600_pre_page_flip,
+		.page_flip = &rs600_page_flip,
+		.post_page_flip = &rs600_post_page_flip,
+	},
+};
+
+static struct radeon_asic rv6xx_asic = {
+	.init = &r600_init,
+	.fini = &r600_fini,
+	.suspend = &r600_suspend,
+	.resume = &r600_resume,
+	.vga_set_state = &r600_vga_set_state,
+	.asic_reset = &r600_asic_reset,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
+	.gui_idle = &r600_gui_idle,
+	.mc_wait_for_idle = &r600_mc_wait_for_idle,
+	.get_xclk = &r600_get_xclk,
+	.get_gpu_clock_counter = &r600_get_gpu_clock_counter,
+	.gart = {
+		.tlb_flush = &r600_pcie_gart_tlb_flush,
+		.set_page = &rs600_gart_set_page,
+	},
+	.ring = {
+		[RADEON_RING_TYPE_GFX_INDEX] = {
+			.ib_execute = &r600_ring_ib_execute,
+			.emit_fence = &r600_fence_ring_emit,
+			.emit_semaphore = &r600_semaphore_ring_emit,
+			.cs_parse = &r600_cs_parse,
+			.ring_test = &r600_ring_test,
+			.ib_test = &r600_ib_test,
+			.is_lockup = &r600_gfx_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		},
+		[R600_RING_TYPE_DMA_INDEX] = {
+			.ib_execute = &r600_dma_ring_ib_execute,
+			.emit_fence = &r600_dma_fence_ring_emit,
+			.emit_semaphore = &r600_dma_semaphore_ring_emit,
+			.cs_parse = &r600_dma_cs_parse,
+			.ring_test = &r600_dma_ring_test,
+			.ib_test = &r600_dma_ib_test,
+			.is_lockup = &r600_dma_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		}
+	},
+	.irq = {
+		.set = &r600_irq_set,
+		.process = &r600_irq_process,
+	},
+	.display = {
+		.bandwidth_update = &rv515_bandwidth_update,
+		.get_vblank_counter = &rs600_get_vblank_counter,
+		.wait_for_vblank = &avivo_wait_for_vblank,
+		.set_backlight_level = &atombios_set_backlight_level,
+		.get_backlight_level = &atombios_get_backlight_level,
+	},
+	.copy = {
+		.blit = &r600_copy_blit,
+		.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+		.dma = &r600_copy_dma,
+		.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+		.copy = &r600_copy_cpdma,
+		.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
 	},
 	.surface = {
 		.set_reg = r600_set_surface_reg,
@@ -1012,6 +1145,23 @@ static struct radeon_asic r600_asic = {
 		.get_pcie_lanes = &r600_get_pcie_lanes,
 		.set_pcie_lanes = &r600_set_pcie_lanes,
 		.set_clock_gating = NULL,
+		.get_temperature = &rv6xx_get_temp,
+	},
+	.dpm = {
+		.init = &rv6xx_dpm_init,
+		.setup_asic = &rv6xx_setup_asic,
+		.enable = &rv6xx_dpm_enable,
+		.disable = &rv6xx_dpm_disable,
+		.pre_set_power_state = &r600_dpm_pre_set_power_state,
+		.set_power_state = &rv6xx_dpm_set_power_state,
+		.post_set_power_state = &r600_dpm_post_set_power_state,
+		.display_configuration_changed = &rv6xx_dpm_display_configuration_changed,
+		.fini = &rv6xx_dpm_fini,
+		.get_sclk = &rv6xx_dpm_get_sclk,
+		.get_mclk = &rv6xx_dpm_get_mclk,
+		.print_power_state = &rv6xx_dpm_print_power_state,
+		.debugfs_print_current_performance_level = &rv6xx_dpm_debugfs_print_current_performance_level,
+		.force_performance_level = &rv6xx_dpm_force_performance_level,
 	},
 	.pflip = {
 		.pre_page_flip = &rs600_pre_page_flip,
@@ -1045,6 +1195,9 @@ static struct radeon_asic rs780_asic = {
 			.ring_test = &r600_ring_test,
 			.ib_test = &r600_ib_test,
 			.is_lockup = &r600_gfx_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_DMA_INDEX] = {
 			.ib_execute = &r600_dma_ring_ib_execute,
@@ -1054,6 +1207,9 @@ static struct radeon_asic rs780_asic = {
 			.ring_test = &r600_dma_ring_test,
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &r600_dma_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -1074,8 +1230,8 @@ static struct radeon_asic rs780_asic = {
 		.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
 		.dma = &r600_copy_dma,
 		.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
-		.copy = &r600_copy_dma,
-		.copy_ring_index = R600_RING_TYPE_DMA_INDEX,
+		.copy = &r600_copy_cpdma,
+		.copy_ring_index = RADEON_RING_TYPE_GFX_INDEX,
 	},
 	.surface = {
 		.set_reg = r600_set_surface_reg,
@@ -1100,6 +1256,22 @@ static struct radeon_asic rs780_asic = {
 		.get_pcie_lanes = NULL,
 		.set_pcie_lanes = NULL,
 		.set_clock_gating = NULL,
+		.get_temperature = &rv6xx_get_temp,
+	},
+	.dpm = {
+		.init = &rs780_dpm_init,
+		.setup_asic = &rs780_dpm_setup_asic,
+		.enable = &rs780_dpm_enable,
+		.disable = &rs780_dpm_disable,
+		.pre_set_power_state = &r600_dpm_pre_set_power_state,
+		.set_power_state = &rs780_dpm_set_power_state,
+		.post_set_power_state = &r600_dpm_post_set_power_state,
+		.display_configuration_changed = &rs780_dpm_display_configuration_changed,
+		.fini = &rs780_dpm_fini,
+		.get_sclk = &rs780_dpm_get_sclk,
+		.get_mclk = &rs780_dpm_get_mclk,
+		.print_power_state = &rs780_dpm_print_power_state,
+		.debugfs_print_current_performance_level = &rs780_dpm_debugfs_print_current_performance_level,
 	},
 	.pflip = {
 		.pre_page_flip = &rs600_pre_page_flip,
@@ -1133,6 +1305,9 @@ static struct radeon_asic rv770_asic = {
 			.ring_test = &r600_ring_test,
 			.ib_test = &r600_ib_test,
 			.is_lockup = &r600_gfx_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_DMA_INDEX] = {
 			.ib_execute = &r600_dma_ring_ib_execute,
@@ -1142,6 +1317,9 @@ static struct radeon_asic rv770_asic = {
 			.ring_test = &r600_dma_ring_test,
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &r600_dma_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_UVD_INDEX] = {
 			.ib_execute = &r600_uvd_ib_execute,
@@ -1151,6 +1329,9 @@ static struct radeon_asic rv770_asic = {
 			.ring_test = &r600_uvd_ring_test,
 			.ib_test = &r600_uvd_ib_test,
 			.is_lockup = &radeon_ring_test_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -1198,6 +1379,24 @@ static struct radeon_asic rv770_asic = {
 		.set_pcie_lanes = &r600_set_pcie_lanes,
 		.set_clock_gating = &radeon_atom_set_clock_gating,
 		.set_uvd_clocks = &rv770_set_uvd_clocks,
+		.get_temperature = &rv770_get_temp,
+	},
+	.dpm = {
+		.init = &rv770_dpm_init,
+		.setup_asic = &rv770_dpm_setup_asic,
+		.enable = &rv770_dpm_enable,
+		.disable = &rv770_dpm_disable,
+		.pre_set_power_state = &r600_dpm_pre_set_power_state,
+		.set_power_state = &rv770_dpm_set_power_state,
+		.post_set_power_state = &r600_dpm_post_set_power_state,
+		.display_configuration_changed = &rv770_dpm_display_configuration_changed,
+		.fini = &rv770_dpm_fini,
+		.get_sclk = &rv770_dpm_get_sclk,
+		.get_mclk = &rv770_dpm_get_mclk,
+		.print_power_state = &rv770_dpm_print_power_state,
+		.debugfs_print_current_performance_level = &rv770_dpm_debugfs_print_current_performance_level,
+		.force_performance_level = &rv770_dpm_force_performance_level,
+		.vblank_too_short = &rv770_dpm_vblank_too_short,
 	},
 	.pflip = {
 		.pre_page_flip = &rs600_pre_page_flip,
@@ -1231,6 +1430,9 @@ static struct radeon_asic evergreen_asic
 			.ring_test = &r600_ring_test,
 			.ib_test = &r600_ib_test,
 			.is_lockup = &evergreen_gfx_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_DMA_INDEX] = {
 			.ib_execute = &evergreen_dma_ring_ib_execute,
@@ -1240,6 +1442,9 @@ static struct radeon_asic evergreen_asic
 			.ring_test = &r600_dma_ring_test,
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &evergreen_dma_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_UVD_INDEX] = {
 			.ib_execute = &r600_uvd_ib_execute,
@@ -1249,6 +1454,9 @@ static struct radeon_asic evergreen_asic
 			.ring_test = &r600_uvd_ring_test,
 			.ib_test = &r600_uvd_ib_test,
 			.is_lockup = &radeon_ring_test_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -1296,6 +1504,24 @@ static struct radeon_asic evergreen_asic
 		.set_pcie_lanes = &r600_set_pcie_lanes,
 		.set_clock_gating = NULL,
 		.set_uvd_clocks = &evergreen_set_uvd_clocks,
+		.get_temperature = &evergreen_get_temp,
+	},
+	.dpm = {
+		.init = &cypress_dpm_init,
+		.setup_asic = &cypress_dpm_setup_asic,
+		.enable = &cypress_dpm_enable,
+		.disable = &cypress_dpm_disable,
+		.pre_set_power_state = &r600_dpm_pre_set_power_state,
+		.set_power_state = &cypress_dpm_set_power_state,
+		.post_set_power_state = &r600_dpm_post_set_power_state,
+		.display_configuration_changed = &cypress_dpm_display_configuration_changed,
+		.fini = &cypress_dpm_fini,
+		.get_sclk = &rv770_dpm_get_sclk,
+		.get_mclk = &rv770_dpm_get_mclk,
+		.print_power_state = &rv770_dpm_print_power_state,
+		.debugfs_print_current_performance_level = &rv770_dpm_debugfs_print_current_performance_level,
+		.force_performance_level = &rv770_dpm_force_performance_level,
+		.vblank_too_short = &cypress_dpm_vblank_too_short,
 	},
 	.pflip = {
 		.pre_page_flip = &evergreen_pre_page_flip,
@@ -1329,6 +1555,9 @@ static struct radeon_asic sumo_asic = {
 			.ring_test = &r600_ring_test,
 			.ib_test = &r600_ib_test,
 			.is_lockup = &evergreen_gfx_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_DMA_INDEX] = {
 			.ib_execute = &evergreen_dma_ring_ib_execute,
@@ -1338,6 +1567,9 @@ static struct radeon_asic sumo_asic = {
 			.ring_test = &r600_dma_ring_test,
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &evergreen_dma_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_UVD_INDEX] = {
 			.ib_execute = &r600_uvd_ib_execute,
@@ -1347,6 +1579,9 @@ static struct radeon_asic sumo_asic = {
 			.ring_test = &r600_uvd_ring_test,
 			.ib_test = &r600_uvd_ib_test,
 			.is_lockup = &radeon_ring_test_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -1394,6 +1629,23 @@ static struct radeon_asic sumo_asic = {
 		.set_pcie_lanes = NULL,
 		.set_clock_gating = NULL,
 		.set_uvd_clocks = &sumo_set_uvd_clocks,
+		.get_temperature = &sumo_get_temp,
+	},
+	.dpm = {
+		.init = &sumo_dpm_init,
+		.setup_asic = &sumo_dpm_setup_asic,
+		.enable = &sumo_dpm_enable,
+		.disable = &sumo_dpm_disable,
+		.pre_set_power_state = &sumo_dpm_pre_set_power_state,
+		.set_power_state = &sumo_dpm_set_power_state,
+		.post_set_power_state = &sumo_dpm_post_set_power_state,
+		.display_configuration_changed = &sumo_dpm_display_configuration_changed,
+		.fini = &sumo_dpm_fini,
+		.get_sclk = &sumo_dpm_get_sclk,
+		.get_mclk = &sumo_dpm_get_mclk,
+		.print_power_state = &sumo_dpm_print_power_state,
+		.debugfs_print_current_performance_level = &sumo_dpm_debugfs_print_current_performance_level,
+		.force_performance_level = &sumo_dpm_force_performance_level,
 	},
 	.pflip = {
 		.pre_page_flip = &evergreen_pre_page_flip,
@@ -1427,6 +1679,9 @@ static struct radeon_asic btc_asic = {
 			.ring_test = &r600_ring_test,
 			.ib_test = &r600_ib_test,
 			.is_lockup = &evergreen_gfx_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_DMA_INDEX] = {
 			.ib_execute = &evergreen_dma_ring_ib_execute,
@@ -1436,6 +1691,9 @@ static struct radeon_asic btc_asic = {
 			.ring_test = &r600_dma_ring_test,
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &evergreen_dma_is_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_UVD_INDEX] = {
 			.ib_execute = &r600_uvd_ib_execute,
@@ -1445,6 +1703,9 @@ static struct radeon_asic btc_asic = {
 			.ring_test = &r600_uvd_ring_test,
 			.ib_test = &r600_uvd_ib_test,
 			.is_lockup = &radeon_ring_test_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -1492,6 +1753,24 @@ static struct radeon_asic btc_asic = {
 		.set_pcie_lanes = &r600_set_pcie_lanes,
 		.set_clock_gating = NULL,
 		.set_uvd_clocks = &evergreen_set_uvd_clocks,
+		.get_temperature = &evergreen_get_temp,
+	},
+	.dpm = {
+		.init = &btc_dpm_init,
+		.setup_asic = &btc_dpm_setup_asic,
+		.enable = &btc_dpm_enable,
+		.disable = &btc_dpm_disable,
+		.pre_set_power_state = &btc_dpm_pre_set_power_state,
+		.set_power_state = &btc_dpm_set_power_state,
+		.post_set_power_state = &btc_dpm_post_set_power_state,
+		.display_configuration_changed = &cypress_dpm_display_configuration_changed,
+		.fini = &btc_dpm_fini,
+		.get_sclk = &btc_dpm_get_sclk,
+		.get_mclk = &btc_dpm_get_mclk,
+		.print_power_state = &rv770_dpm_print_power_state,
+		.debugfs_print_current_performance_level = &rv770_dpm_debugfs_print_current_performance_level,
+		.force_performance_level = &rv770_dpm_force_performance_level,
+		.vblank_too_short = &btc_dpm_vblank_too_short,
 	},
 	.pflip = {
 		.pre_page_flip = &evergreen_pre_page_flip,
@@ -1533,6 +1812,9 @@ static struct radeon_asic cayman_asic =
 			.ib_test = &r600_ib_test,
 			.is_lockup = &cayman_gfx_is_lockup,
 			.vm_flush = &cayman_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[CAYMAN_RING_TYPE_CP1_INDEX] = {
 			.ib_execute = &cayman_ring_ib_execute,
@@ -1544,6 +1826,9 @@ static struct radeon_asic cayman_asic =
 			.ib_test = &r600_ib_test,
 			.is_lockup = &cayman_gfx_is_lockup,
 			.vm_flush = &cayman_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[CAYMAN_RING_TYPE_CP2_INDEX] = {
 			.ib_execute = &cayman_ring_ib_execute,
@@ -1555,6 +1840,9 @@ static struct radeon_asic cayman_asic =
 			.ib_test = &r600_ib_test,
 			.is_lockup = &cayman_gfx_is_lockup,
 			.vm_flush = &cayman_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_DMA_INDEX] = {
 			.ib_execute = &cayman_dma_ring_ib_execute,
@@ -1566,6 +1854,9 @@ static struct radeon_asic cayman_asic =
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &cayman_dma_is_lockup,
 			.vm_flush = &cayman_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[CAYMAN_RING_TYPE_DMA1_INDEX] = {
 			.ib_execute = &cayman_dma_ring_ib_execute,
@@ -1577,6 +1868,9 @@ static struct radeon_asic cayman_asic =
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &cayman_dma_is_lockup,
 			.vm_flush = &cayman_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_UVD_INDEX] = {
 			.ib_execute = &r600_uvd_ib_execute,
@@ -1586,6 +1880,9 @@ static struct radeon_asic cayman_asic =
 			.ring_test = &r600_uvd_ring_test,
 			.ib_test = &r600_uvd_ib_test,
 			.is_lockup = &radeon_ring_test_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -1633,6 +1930,24 @@ static struct radeon_asic cayman_asic =
 		.set_pcie_lanes = &r600_set_pcie_lanes,
 		.set_clock_gating = NULL,
 		.set_uvd_clocks = &evergreen_set_uvd_clocks,
+		.get_temperature = &evergreen_get_temp,
+	},
+	.dpm = {
+		.init = &ni_dpm_init,
+		.setup_asic = &ni_dpm_setup_asic,
+		.enable = &ni_dpm_enable,
+		.disable = &ni_dpm_disable,
+		.pre_set_power_state = &ni_dpm_pre_set_power_state,
+		.set_power_state = &ni_dpm_set_power_state,
+		.post_set_power_state = &ni_dpm_post_set_power_state,
+		.display_configuration_changed = &cypress_dpm_display_configuration_changed,
+		.fini = &ni_dpm_fini,
+		.get_sclk = &ni_dpm_get_sclk,
+		.get_mclk = &ni_dpm_get_mclk,
+		.print_power_state = &ni_dpm_print_power_state,
+		.debugfs_print_current_performance_level = &ni_dpm_debugfs_print_current_performance_level,
+		.force_performance_level = &ni_dpm_force_performance_level,
+		.vblank_too_short = &ni_dpm_vblank_too_short,
 	},
 	.pflip = {
 		.pre_page_flip = &evergreen_pre_page_flip,
@@ -1674,6 +1989,9 @@ static struct radeon_asic trinity_asic =
 			.ib_test = &r600_ib_test,
 			.is_lockup = &cayman_gfx_is_lockup,
 			.vm_flush = &cayman_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[CAYMAN_RING_TYPE_CP1_INDEX] = {
 			.ib_execute = &cayman_ring_ib_execute,
@@ -1685,6 +2003,9 @@ static struct radeon_asic trinity_asic =
 			.ib_test = &r600_ib_test,
 			.is_lockup = &cayman_gfx_is_lockup,
 			.vm_flush = &cayman_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[CAYMAN_RING_TYPE_CP2_INDEX] = {
 			.ib_execute = &cayman_ring_ib_execute,
@@ -1696,6 +2017,9 @@ static struct radeon_asic trinity_asic =
 			.ib_test = &r600_ib_test,
 			.is_lockup = &cayman_gfx_is_lockup,
 			.vm_flush = &cayman_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_DMA_INDEX] = {
 			.ib_execute = &cayman_dma_ring_ib_execute,
@@ -1707,6 +2031,9 @@ static struct radeon_asic trinity_asic =
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &cayman_dma_is_lockup,
 			.vm_flush = &cayman_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[CAYMAN_RING_TYPE_DMA1_INDEX] = {
 			.ib_execute = &cayman_dma_ring_ib_execute,
@@ -1718,6 +2045,9 @@ static struct radeon_asic trinity_asic =
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &cayman_dma_is_lockup,
 			.vm_flush = &cayman_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_UVD_INDEX] = {
 			.ib_execute = &r600_uvd_ib_execute,
@@ -1727,6 +2057,9 @@ static struct radeon_asic trinity_asic =
 			.ring_test = &r600_uvd_ring_test,
 			.ib_test = &r600_uvd_ib_test,
 			.is_lockup = &radeon_ring_test_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -1772,6 +2105,23 @@ static struct radeon_asic trinity_asic =
 		.set_pcie_lanes = NULL,
 		.set_clock_gating = NULL,
 		.set_uvd_clocks = &sumo_set_uvd_clocks,
+		.get_temperature = &tn_get_temp,
+	},
+	.dpm = {
+		.init = &trinity_dpm_init,
+		.setup_asic = &trinity_dpm_setup_asic,
+		.enable = &trinity_dpm_enable,
+		.disable = &trinity_dpm_disable,
+		.pre_set_power_state = &trinity_dpm_pre_set_power_state,
+		.set_power_state = &trinity_dpm_set_power_state,
+		.post_set_power_state = &trinity_dpm_post_set_power_state,
+		.display_configuration_changed = &trinity_dpm_display_configuration_changed,
+		.fini = &trinity_dpm_fini,
+		.get_sclk = &trinity_dpm_get_sclk,
+		.get_mclk = &trinity_dpm_get_mclk,
+		.print_power_state = &trinity_dpm_print_power_state,
+		.debugfs_print_current_performance_level = &trinity_dpm_debugfs_print_current_performance_level,
+		.force_performance_level = &trinity_dpm_force_performance_level,
 	},
 	.pflip = {
 		.pre_page_flip = &evergreen_pre_page_flip,
@@ -1813,6 +2163,9 @@ static struct radeon_asic si_asic = {
 			.ib_test = &r600_ib_test,
 			.is_lockup = &si_gfx_is_lockup,
 			.vm_flush = &si_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[CAYMAN_RING_TYPE_CP1_INDEX] = {
 			.ib_execute = &si_ring_ib_execute,
@@ -1824,6 +2177,9 @@ static struct radeon_asic si_asic = {
 			.ib_test = &r600_ib_test,
 			.is_lockup = &si_gfx_is_lockup,
 			.vm_flush = &si_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[CAYMAN_RING_TYPE_CP2_INDEX] = {
 			.ib_execute = &si_ring_ib_execute,
@@ -1835,6 +2191,9 @@ static struct radeon_asic si_asic = {
 			.ib_test = &r600_ib_test,
 			.is_lockup = &si_gfx_is_lockup,
 			.vm_flush = &si_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_DMA_INDEX] = {
 			.ib_execute = &cayman_dma_ring_ib_execute,
@@ -1846,6 +2205,9 @@ static struct radeon_asic si_asic = {
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &si_dma_is_lockup,
 			.vm_flush = &si_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[CAYMAN_RING_TYPE_DMA1_INDEX] = {
 			.ib_execute = &cayman_dma_ring_ib_execute,
@@ -1857,6 +2219,9 @@ static struct radeon_asic si_asic = {
 			.ib_test = &r600_dma_ib_test,
 			.is_lockup = &si_dma_is_lockup,
 			.vm_flush = &si_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		},
 		[R600_RING_TYPE_UVD_INDEX] = {
 			.ib_execute = &r600_uvd_ib_execute,
@@ -1866,6 +2231,9 @@ static struct radeon_asic si_asic = {
 			.ring_test = &r600_uvd_ring_test,
 			.ib_test = &r600_uvd_ib_test,
 			.is_lockup = &radeon_ring_test_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
 		}
 	},
 	.irq = {
@@ -1911,6 +2279,334 @@ static struct radeon_asic si_asic = {
 		.set_pcie_lanes = &r600_set_pcie_lanes,
 		.set_clock_gating = NULL,
 		.set_uvd_clocks = &si_set_uvd_clocks,
+		.get_temperature = &si_get_temp,
+	},
+	.dpm = {
+		.init = &si_dpm_init,
+		.setup_asic = &si_dpm_setup_asic,
+		.enable = &si_dpm_enable,
+		.disable = &si_dpm_disable,
+		.pre_set_power_state = &si_dpm_pre_set_power_state,
+		.set_power_state = &si_dpm_set_power_state,
+		.post_set_power_state = &si_dpm_post_set_power_state,
+		.display_configuration_changed = &si_dpm_display_configuration_changed,
+		.fini = &si_dpm_fini,
+		.get_sclk = &ni_dpm_get_sclk,
+		.get_mclk = &ni_dpm_get_mclk,
+		.print_power_state = &ni_dpm_print_power_state,
+		.debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level,
+		.force_performance_level = &si_dpm_force_performance_level,
+		.vblank_too_short = &ni_dpm_vblank_too_short,
+	},
+	.pflip = {
+		.pre_page_flip = &evergreen_pre_page_flip,
+		.page_flip = &evergreen_page_flip,
+		.post_page_flip = &evergreen_post_page_flip,
+	},
+};
+
+static struct radeon_asic ci_asic = {
+	.init = &cik_init,
+	.fini = &cik_fini,
+	.suspend = &cik_suspend,
+	.resume = &cik_resume,
+	.asic_reset = &cik_asic_reset,
+	.vga_set_state = &r600_vga_set_state,
+	.ioctl_wait_idle = NULL,
+	.gui_idle = &r600_gui_idle,
+	.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
+	.get_xclk = &cik_get_xclk,
+	.get_gpu_clock_counter = &cik_get_gpu_clock_counter,
+	.gart = {
+		.tlb_flush = &cik_pcie_gart_tlb_flush,
+		.set_page = &rs600_gart_set_page,
+	},
+	.vm = {
+		.init = &cik_vm_init,
+		.fini = &cik_vm_fini,
+		.pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+		.set_page = &cik_vm_set_page,
+	},
+	.ring = {
+		[RADEON_RING_TYPE_GFX_INDEX] = {
+			.ib_execute = &cik_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_fence_gfx_ring_emit,
+			.emit_semaphore = &cik_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_ring_test,
+			.ib_test = &cik_ib_test,
+			.is_lockup = &cik_gfx_is_lockup,
+			.vm_flush = &cik_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		},
+		[CAYMAN_RING_TYPE_CP1_INDEX] = {
+			.ib_execute = &cik_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_fence_compute_ring_emit,
+			.emit_semaphore = &cik_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_ring_test,
+			.ib_test = &cik_ib_test,
+			.is_lockup = &cik_gfx_is_lockup,
+			.vm_flush = &cik_vm_flush,
+			.get_rptr = &cik_compute_ring_get_rptr,
+			.get_wptr = &cik_compute_ring_get_wptr,
+			.set_wptr = &cik_compute_ring_set_wptr,
+		},
+		[CAYMAN_RING_TYPE_CP2_INDEX] = {
+			.ib_execute = &cik_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_fence_compute_ring_emit,
+			.emit_semaphore = &cik_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_ring_test,
+			.ib_test = &cik_ib_test,
+			.is_lockup = &cik_gfx_is_lockup,
+			.vm_flush = &cik_vm_flush,
+			.get_rptr = &cik_compute_ring_get_rptr,
+			.get_wptr = &cik_compute_ring_get_wptr,
+			.set_wptr = &cik_compute_ring_set_wptr,
+		},
+		[R600_RING_TYPE_DMA_INDEX] = {
+			.ib_execute = &cik_sdma_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_sdma_fence_ring_emit,
+			.emit_semaphore = &cik_sdma_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_sdma_ring_test,
+			.ib_test = &cik_sdma_ib_test,
+			.is_lockup = &cik_sdma_is_lockup,
+			.vm_flush = &cik_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		},
+		[CAYMAN_RING_TYPE_DMA1_INDEX] = {
+			.ib_execute = &cik_sdma_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_sdma_fence_ring_emit,
+			.emit_semaphore = &cik_sdma_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_sdma_ring_test,
+			.ib_test = &cik_sdma_ib_test,
+			.is_lockup = &cik_sdma_is_lockup,
+			.vm_flush = &cik_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		},
+		[R600_RING_TYPE_UVD_INDEX] = {
+			.ib_execute = &r600_uvd_ib_execute,
+			.emit_fence = &r600_uvd_fence_emit,
+			.emit_semaphore = &cayman_uvd_semaphore_emit,
+			.cs_parse = &radeon_uvd_cs_parse,
+			.ring_test = &r600_uvd_ring_test,
+			.ib_test = &r600_uvd_ib_test,
+			.is_lockup = &radeon_ring_test_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		}
+	},
+	.irq = {
+		.set = &cik_irq_set,
+		.process = &cik_irq_process,
+	},
+	.display = {
+		.bandwidth_update = &dce8_bandwidth_update,
+		.get_vblank_counter = &evergreen_get_vblank_counter,
+		.wait_for_vblank = &dce4_wait_for_vblank,
+	},
+	.copy = {
+		.blit = NULL,
+		.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+		.dma = &cik_copy_dma,
+		.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+		.copy = &cik_copy_dma,
+		.copy_ring_index = R600_RING_TYPE_DMA_INDEX,
+	},
+	.surface = {
+		.set_reg = r600_set_surface_reg,
+		.clear_reg = r600_clear_surface_reg,
+	},
+	.hpd = {
+		.init = &evergreen_hpd_init,
+		.fini = &evergreen_hpd_fini,
+		.sense = &evergreen_hpd_sense,
+		.set_polarity = &evergreen_hpd_set_polarity,
+	},
+	.pm = {
+		.misc = &evergreen_pm_misc,
+		.prepare = &evergreen_pm_prepare,
+		.finish = &evergreen_pm_finish,
+		.init_profile = &sumo_pm_init_profile,
+		.get_dynpm_state = &r600_pm_get_dynpm_state,
+		.get_engine_clock = &radeon_atom_get_engine_clock,
+		.set_engine_clock = &radeon_atom_set_engine_clock,
+		.get_memory_clock = &radeon_atom_get_memory_clock,
+		.set_memory_clock = &radeon_atom_set_memory_clock,
+		.get_pcie_lanes = NULL,
+		.set_pcie_lanes = NULL,
+		.set_clock_gating = NULL,
+		.set_uvd_clocks = &cik_set_uvd_clocks,
+	},
+	.pflip = {
+		.pre_page_flip = &evergreen_pre_page_flip,
+		.page_flip = &evergreen_page_flip,
+		.post_page_flip = &evergreen_post_page_flip,
+	},
+};
+
+static struct radeon_asic kv_asic = {
+	.init = &cik_init,
+	.fini = &cik_fini,
+	.suspend = &cik_suspend,
+	.resume = &cik_resume,
+	.asic_reset = &cik_asic_reset,
+	.vga_set_state = &r600_vga_set_state,
+	.ioctl_wait_idle = NULL,
+	.gui_idle = &r600_gui_idle,
+	.mc_wait_for_idle = &evergreen_mc_wait_for_idle,
+	.get_xclk = &cik_get_xclk,
+	.get_gpu_clock_counter = &cik_get_gpu_clock_counter,
+	.gart = {
+		.tlb_flush = &cik_pcie_gart_tlb_flush,
+		.set_page = &rs600_gart_set_page,
+	},
+	.vm = {
+		.init = &cik_vm_init,
+		.fini = &cik_vm_fini,
+		.pt_ring_index = R600_RING_TYPE_DMA_INDEX,
+		.set_page = &cik_vm_set_page,
+	},
+	.ring = {
+		[RADEON_RING_TYPE_GFX_INDEX] = {
+			.ib_execute = &cik_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_fence_gfx_ring_emit,
+			.emit_semaphore = &cik_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_ring_test,
+			.ib_test = &cik_ib_test,
+			.is_lockup = &cik_gfx_is_lockup,
+			.vm_flush = &cik_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		},
+		[CAYMAN_RING_TYPE_CP1_INDEX] = {
+			.ib_execute = &cik_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_fence_compute_ring_emit,
+			.emit_semaphore = &cik_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_ring_test,
+			.ib_test = &cik_ib_test,
+			.is_lockup = &cik_gfx_is_lockup,
+			.vm_flush = &cik_vm_flush,
+			.get_rptr = &cik_compute_ring_get_rptr,
+			.get_wptr = &cik_compute_ring_get_wptr,
+			.set_wptr = &cik_compute_ring_set_wptr,
+		},
+		[CAYMAN_RING_TYPE_CP2_INDEX] = {
+			.ib_execute = &cik_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_fence_compute_ring_emit,
+			.emit_semaphore = &cik_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_ring_test,
+			.ib_test = &cik_ib_test,
+			.is_lockup = &cik_gfx_is_lockup,
+			.vm_flush = &cik_vm_flush,
+			.get_rptr = &cik_compute_ring_get_rptr,
+			.get_wptr = &cik_compute_ring_get_wptr,
+			.set_wptr = &cik_compute_ring_set_wptr,
+		},
+		[R600_RING_TYPE_DMA_INDEX] = {
+			.ib_execute = &cik_sdma_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_sdma_fence_ring_emit,
+			.emit_semaphore = &cik_sdma_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_sdma_ring_test,
+			.ib_test = &cik_sdma_ib_test,
+			.is_lockup = &cik_sdma_is_lockup,
+			.vm_flush = &cik_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		},
+		[CAYMAN_RING_TYPE_DMA1_INDEX] = {
+			.ib_execute = &cik_sdma_ring_ib_execute,
+			.ib_parse = &cik_ib_parse,
+			.emit_fence = &cik_sdma_fence_ring_emit,
+			.emit_semaphore = &cik_sdma_semaphore_ring_emit,
+			.cs_parse = NULL,
+			.ring_test = &cik_sdma_ring_test,
+			.ib_test = &cik_sdma_ib_test,
+			.is_lockup = &cik_sdma_is_lockup,
+			.vm_flush = &cik_dma_vm_flush,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		},
+		[R600_RING_TYPE_UVD_INDEX] = {
+			.ib_execute = &r600_uvd_ib_execute,
+			.emit_fence = &r600_uvd_fence_emit,
+			.emit_semaphore = &cayman_uvd_semaphore_emit,
+			.cs_parse = &radeon_uvd_cs_parse,
+			.ring_test = &r600_uvd_ring_test,
+			.ib_test = &r600_uvd_ib_test,
+			.is_lockup = &radeon_ring_test_lockup,
+			.get_rptr = &radeon_ring_generic_get_rptr,
+			.get_wptr = &radeon_ring_generic_get_wptr,
+			.set_wptr = &radeon_ring_generic_set_wptr,
+		}
+	},
+	.irq = {
+		.set = &cik_irq_set,
+		.process = &cik_irq_process,
+	},
+	.display = {
+		.bandwidth_update = &dce8_bandwidth_update,
+		.get_vblank_counter = &evergreen_get_vblank_counter,
+		.wait_for_vblank = &dce4_wait_for_vblank,
+	},
+	.copy = {
+		.blit = NULL,
+		.blit_ring_index = RADEON_RING_TYPE_GFX_INDEX,
+		.dma = &cik_copy_dma,
+		.dma_ring_index = R600_RING_TYPE_DMA_INDEX,
+		.copy = &cik_copy_dma,
+		.copy_ring_index = R600_RING_TYPE_DMA_INDEX,
+	},
+	.surface = {
+		.set_reg = r600_set_surface_reg,
+		.clear_reg = r600_clear_surface_reg,
+	},
+	.hpd = {
+		.init = &evergreen_hpd_init,
+		.fini = &evergreen_hpd_fini,
+		.sense = &evergreen_hpd_sense,
+		.set_polarity = &evergreen_hpd_set_polarity,
+	},
+	.pm = {
+		.misc = &evergreen_pm_misc,
+		.prepare = &evergreen_pm_prepare,
+		.finish = &evergreen_pm_finish,
+		.init_profile = &sumo_pm_init_profile,
+		.get_dynpm_state = &r600_pm_get_dynpm_state,
+		.get_engine_clock = &radeon_atom_get_engine_clock,
+		.set_engine_clock = &radeon_atom_set_engine_clock,
+		.get_memory_clock = &radeon_atom_get_memory_clock,
+		.set_memory_clock = &radeon_atom_set_memory_clock,
+		.get_pcie_lanes = NULL,
+		.set_pcie_lanes = NULL,
+		.set_clock_gating = NULL,
+		.set_uvd_clocks = &cik_set_uvd_clocks,
 	},
 	.pflip = {
 		.pre_page_flip = &evergreen_pre_page_flip,
@@ -1999,16 +2695,15 @@ int radeon_asic_init(struct radeon_devic
 		rdev->asic = &r520_asic;
 		break;
 	case CHIP_R600:
+		rdev->asic = &r600_asic;
+		break;
 	case CHIP_RV610:
 	case CHIP_RV630:
 	case CHIP_RV620:
 	case CHIP_RV635:
 	case CHIP_RV670:
-		rdev->asic = &r600_asic;
-		if (rdev->family == CHIP_R600)
-			rdev->has_uvd = false;
-		else
-			rdev->has_uvd = true;
+		rdev->asic = &rv6xx_asic;
+		rdev->has_uvd = true;
 		break;
 	case CHIP_RS780:
 	case CHIP_RS880:
@@ -2082,6 +2777,19 @@ int radeon_asic_init(struct radeon_devic
 		else
 			rdev->has_uvd = true;
 		break;
+	case CHIP_BONAIRE:
+		rdev->asic = &ci_asic;
+		rdev->num_crtc = 6;
+		break;
+	case CHIP_KAVERI:
+	case CHIP_KABINI:
+		rdev->asic = &kv_asic;
+		/* set num crtcs */
+		if (rdev->family == CHIP_KAVERI)
+			rdev->num_crtc = 4;
+		else
+			rdev->num_crtc = 2;
+		break;
 	default:
 		/* FIXME: not supported yet */
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_asic.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_asic.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_asic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_asic.h	2013-08-25 20:43:22.000000000 -0400
@@ -47,6 +47,12 @@ u8 atombios_get_backlight_level(struct r
 void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level);
 u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder);
 
+u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev,
+				 struct radeon_ring *ring);
+u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev,
+				 struct radeon_ring *ring);
+void radeon_ring_generic_set_wptr(struct radeon_device *rdev,
+				  struct radeon_ring *ring);
 
 /*
  * r100,rv100,rs100,rv200,rs200
@@ -334,6 +340,9 @@ int r600_uvd_ring_test(struct radeon_dev
 int r600_copy_blit(struct radeon_device *rdev,
 		   uint64_t src_offset, uint64_t dst_offset,
 		   unsigned num_gpu_pages, struct radeon_fence **fence);
+int r600_copy_cpdma(struct radeon_device *rdev,
+		    uint64_t src_offset, uint64_t dst_offset,
+		    unsigned num_gpu_pages, struct radeon_fence **fence);
 int r600_copy_dma(struct radeon_device *rdev,
 		  uint64_t src_offset, uint64_t dst_offset,
 		  unsigned num_gpu_pages, struct radeon_fence **fence);
@@ -395,11 +404,44 @@ void r600_kms_blit_copy(struct radeon_de
 int r600_mc_wait_for_idle(struct radeon_device *rdev);
 u32 r600_get_xclk(struct radeon_device *rdev);
 uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev);
+int rv6xx_get_temp(struct radeon_device *rdev);
+int r600_dpm_pre_set_power_state(struct radeon_device *rdev);
+void r600_dpm_post_set_power_state(struct radeon_device *rdev);
+/* rv6xx dpm */
+int rv6xx_dpm_init(struct radeon_device *rdev);
+int rv6xx_dpm_enable(struct radeon_device *rdev);
+void rv6xx_dpm_disable(struct radeon_device *rdev);
+int rv6xx_dpm_set_power_state(struct radeon_device *rdev);
+void rv6xx_setup_asic(struct radeon_device *rdev);
+void rv6xx_dpm_display_configuration_changed(struct radeon_device *rdev);
+void rv6xx_dpm_fini(struct radeon_device *rdev);
+u32 rv6xx_dpm_get_sclk(struct radeon_device *rdev, bool low);
+u32 rv6xx_dpm_get_mclk(struct radeon_device *rdev, bool low);
+void rv6xx_dpm_print_power_state(struct radeon_device *rdev,
+				 struct radeon_ps *ps);
+void rv6xx_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						       struct seq_file *m);
+int rv6xx_dpm_force_performance_level(struct radeon_device *rdev,
+				      enum radeon_dpm_forced_level level);
+/* rs780 dpm */
+int rs780_dpm_init(struct radeon_device *rdev);
+int rs780_dpm_enable(struct radeon_device *rdev);
+void rs780_dpm_disable(struct radeon_device *rdev);
+int rs780_dpm_set_power_state(struct radeon_device *rdev);
+void rs780_dpm_setup_asic(struct radeon_device *rdev);
+void rs780_dpm_display_configuration_changed(struct radeon_device *rdev);
+void rs780_dpm_fini(struct radeon_device *rdev);
+u32 rs780_dpm_get_sclk(struct radeon_device *rdev, bool low);
+u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low);
+void rs780_dpm_print_power_state(struct radeon_device *rdev,
+				 struct radeon_ps *ps);
+void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						       struct seq_file *m);
 
 /* uvd */
 int r600_uvd_init(struct radeon_device *rdev);
 int r600_uvd_rbc_start(struct radeon_device *rdev);
-void r600_uvd_rbc_stop(struct radeon_device *rdev);
+void r600_uvd_stop(struct radeon_device *rdev);
 int r600_uvd_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
 void r600_uvd_fence_emit(struct radeon_device *rdev,
 			 struct radeon_fence *fence);
@@ -428,6 +470,24 @@ int rv770_copy_dma(struct radeon_device
 u32 rv770_get_xclk(struct radeon_device *rdev);
 int rv770_uvd_resume(struct radeon_device *rdev);
 int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
+int rv770_get_temp(struct radeon_device *rdev);
+/* rv7xx pm */
+int rv770_dpm_init(struct radeon_device *rdev);
+int rv770_dpm_enable(struct radeon_device *rdev);
+void rv770_dpm_disable(struct radeon_device *rdev);
+int rv770_dpm_set_power_state(struct radeon_device *rdev);
+void rv770_dpm_setup_asic(struct radeon_device *rdev);
+void rv770_dpm_display_configuration_changed(struct radeon_device *rdev);
+void rv770_dpm_fini(struct radeon_device *rdev);
+u32 rv770_dpm_get_sclk(struct radeon_device *rdev, bool low);
+u32 rv770_dpm_get_mclk(struct radeon_device *rdev, bool low);
+void rv770_dpm_print_power_state(struct radeon_device *rdev,
+				 struct radeon_ps *ps);
+void rv770_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						       struct seq_file *m);
+int rv770_dpm_force_performance_level(struct radeon_device *rdev,
+				      enum radeon_dpm_forced_level level);
+bool rv770_dpm_vblank_too_short(struct radeon_device *rdev);
 
 /*
  * evergreen
@@ -482,6 +542,45 @@ int evergreen_copy_dma(struct radeon_dev
 		       struct radeon_fence **fence);
 void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable);
 void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
+int evergreen_get_temp(struct radeon_device *rdev);
+int sumo_get_temp(struct radeon_device *rdev);
+int tn_get_temp(struct radeon_device *rdev);
+int cypress_dpm_init(struct radeon_device *rdev);
+void cypress_dpm_setup_asic(struct radeon_device *rdev);
+int cypress_dpm_enable(struct radeon_device *rdev);
+void cypress_dpm_disable(struct radeon_device *rdev);
+int cypress_dpm_set_power_state(struct radeon_device *rdev);
+void cypress_dpm_display_configuration_changed(struct radeon_device *rdev);
+void cypress_dpm_fini(struct radeon_device *rdev);
+bool cypress_dpm_vblank_too_short(struct radeon_device *rdev);
+int btc_dpm_init(struct radeon_device *rdev);
+void btc_dpm_setup_asic(struct radeon_device *rdev);
+int btc_dpm_enable(struct radeon_device *rdev);
+void btc_dpm_disable(struct radeon_device *rdev);
+int btc_dpm_pre_set_power_state(struct radeon_device *rdev);
+int btc_dpm_set_power_state(struct radeon_device *rdev);
+void btc_dpm_post_set_power_state(struct radeon_device *rdev);
+void btc_dpm_fini(struct radeon_device *rdev);
+u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low);
+u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low);
+bool btc_dpm_vblank_too_short(struct radeon_device *rdev);
+int sumo_dpm_init(struct radeon_device *rdev);
+int sumo_dpm_enable(struct radeon_device *rdev);
+void sumo_dpm_disable(struct radeon_device *rdev);
+int sumo_dpm_pre_set_power_state(struct radeon_device *rdev);
+int sumo_dpm_set_power_state(struct radeon_device *rdev);
+void sumo_dpm_post_set_power_state(struct radeon_device *rdev);
+void sumo_dpm_setup_asic(struct radeon_device *rdev);
+void sumo_dpm_display_configuration_changed(struct radeon_device *rdev);
+void sumo_dpm_fini(struct radeon_device *rdev);
+u32 sumo_dpm_get_sclk(struct radeon_device *rdev, bool low);
+u32 sumo_dpm_get_mclk(struct radeon_device *rdev, bool low);
+void sumo_dpm_print_power_state(struct radeon_device *rdev,
+				struct radeon_ps *ps);
+void sumo_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						      struct seq_file *m);
+int sumo_dpm_force_performance_level(struct radeon_device *rdev,
+				     enum radeon_dpm_forced_level level);
 
 /*
  * cayman
@@ -516,6 +615,41 @@ bool cayman_gfx_is_lockup(struct radeon_
 bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
 void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
 
+int ni_dpm_init(struct radeon_device *rdev);
+void ni_dpm_setup_asic(struct radeon_device *rdev);
+int ni_dpm_enable(struct radeon_device *rdev);
+void ni_dpm_disable(struct radeon_device *rdev);
+int ni_dpm_pre_set_power_state(struct radeon_device *rdev);
+int ni_dpm_set_power_state(struct radeon_device *rdev);
+void ni_dpm_post_set_power_state(struct radeon_device *rdev);
+void ni_dpm_fini(struct radeon_device *rdev);
+u32 ni_dpm_get_sclk(struct radeon_device *rdev, bool low);
+u32 ni_dpm_get_mclk(struct radeon_device *rdev, bool low);
+void ni_dpm_print_power_state(struct radeon_device *rdev,
+			      struct radeon_ps *ps);
+void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						    struct seq_file *m);
+int ni_dpm_force_performance_level(struct radeon_device *rdev,
+				   enum radeon_dpm_forced_level level);
+bool ni_dpm_vblank_too_short(struct radeon_device *rdev);
+int trinity_dpm_init(struct radeon_device *rdev);
+int trinity_dpm_enable(struct radeon_device *rdev);
+void trinity_dpm_disable(struct radeon_device *rdev);
+int trinity_dpm_pre_set_power_state(struct radeon_device *rdev);
+int trinity_dpm_set_power_state(struct radeon_device *rdev);
+void trinity_dpm_post_set_power_state(struct radeon_device *rdev);
+void trinity_dpm_setup_asic(struct radeon_device *rdev);
+void trinity_dpm_display_configuration_changed(struct radeon_device *rdev);
+void trinity_dpm_fini(struct radeon_device *rdev);
+u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low);
+u32 trinity_dpm_get_mclk(struct radeon_device *rdev, bool low);
+void trinity_dpm_print_power_state(struct radeon_device *rdev,
+				   struct radeon_ps *ps);
+void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+							 struct seq_file *m);
+int trinity_dpm_force_performance_level(struct radeon_device *rdev,
+					enum radeon_dpm_forced_level level);
+
 /* DCE6 - SI */
 void dce6_bandwidth_update(struct radeon_device *rdev);
 
@@ -552,5 +686,82 @@ void si_dma_vm_flush(struct radeon_devic
 u32 si_get_xclk(struct radeon_device *rdev);
 uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev);
 int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
+int si_get_temp(struct radeon_device *rdev);
+int si_dpm_init(struct radeon_device *rdev);
+void si_dpm_setup_asic(struct radeon_device *rdev);
+int si_dpm_enable(struct radeon_device *rdev);
+void si_dpm_disable(struct radeon_device *rdev);
+int si_dpm_pre_set_power_state(struct radeon_device *rdev);
+int si_dpm_set_power_state(struct radeon_device *rdev);
+void si_dpm_post_set_power_state(struct radeon_device *rdev);
+void si_dpm_fini(struct radeon_device *rdev);
+void si_dpm_display_configuration_changed(struct radeon_device *rdev);
+void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						    struct seq_file *m);
+int si_dpm_force_performance_level(struct radeon_device *rdev,
+				   enum radeon_dpm_forced_level level);
+
+/* DCE8 - CIK */
+void dce8_bandwidth_update(struct radeon_device *rdev);
+
+/*
+ * cik
+ */
+uint64_t cik_get_gpu_clock_counter(struct radeon_device *rdev);
+u32 cik_get_xclk(struct radeon_device *rdev);
+uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg);
+void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
+int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
+int cik_uvd_resume(struct radeon_device *rdev);
+void cik_sdma_fence_ring_emit(struct radeon_device *rdev,
+			      struct radeon_fence *fence);
+void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev,
+				  struct radeon_ring *ring,
+				  struct radeon_semaphore *semaphore,
+				  bool emit_wait);
+void cik_sdma_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
+int cik_copy_dma(struct radeon_device *rdev,
+		 uint64_t src_offset, uint64_t dst_offset,
+		 unsigned num_gpu_pages,
+		 struct radeon_fence **fence);
+int cik_sdma_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
+int cik_sdma_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
+bool cik_sdma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
+void cik_fence_gfx_ring_emit(struct radeon_device *rdev,
+			     struct radeon_fence *fence);
+void cik_fence_compute_ring_emit(struct radeon_device *rdev,
+				 struct radeon_fence *fence);
+void cik_semaphore_ring_emit(struct radeon_device *rdev,
+			     struct radeon_ring *cp,
+			     struct radeon_semaphore *semaphore,
+			     bool emit_wait);
+void cik_pcie_gart_tlb_flush(struct radeon_device *rdev);
+int cik_init(struct radeon_device *rdev);
+void cik_fini(struct radeon_device *rdev);
+int cik_suspend(struct radeon_device *rdev);
+int cik_resume(struct radeon_device *rdev);
+bool cik_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp);
+int cik_asic_reset(struct radeon_device *rdev);
+void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
+int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring);
+int cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring);
+int cik_irq_set(struct radeon_device *rdev);
+int cik_irq_process(struct radeon_device *rdev);
+int cik_vm_init(struct radeon_device *rdev);
+void cik_vm_fini(struct radeon_device *rdev);
+void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+void cik_vm_set_page(struct radeon_device *rdev,
+		     struct radeon_ib *ib,
+		     uint64_t pe,
+		     uint64_t addr, unsigned count,
+		     uint32_t incr, uint32_t flags);
+void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
+u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
+			      struct radeon_ring *ring);
+u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
+			      struct radeon_ring *ring);
+void cik_compute_ring_set_wptr(struct radeon_device *rdev,
+			       struct radeon_ring *ring);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_atombios.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_atombios.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_atombios.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_atombios.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,10 +56,6 @@ extern void
 radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,
 			  uint32_t supported_device);
 
-/* local */
-static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
-				    u16 voltage_id, u16 *voltage);
-
 union atom_supported_devices {
 	struct _ATOM_SUPPORTED_DEVICES_INFO info;
 	struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2;
@@ -1247,6 +1243,7 @@ bool radeon_atom_get_clock_info(struct d
 			}
 			rdev->clock.dp_extclk =
 				le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
+			rdev->clock.current_dispclk = rdev->clock.default_dispclk;
 		}
 		*dcpll = *p1pll;
 
@@ -1269,6 +1266,7 @@ union igp_info {
 	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
 	struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
 	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
 };
 
 bool radeon_atombios_sideport_present(struct radeon_device *rdev)
@@ -1438,6 +1436,22 @@ static void radeon_atombios_get_igp_ss_o
 				break;
 			}
 			break;
+		case 8:
+			switch (id) {
+			case ASIC_INTERNAL_SS_ON_TMDS:
+				percentage = le16_to_cpu(igp_info->info_8.usDVISSPercentage);
+				rate = le16_to_cpu(igp_info->info_8.usDVISSpreadRateIn10Hz);
+				break;
+			case ASIC_INTERNAL_SS_ON_HDMI:
+				percentage = le16_to_cpu(igp_info->info_8.usHDMISSPercentage);
+				rate = le16_to_cpu(igp_info->info_8.usHDMISSpreadRateIn10Hz);
+				break;
+			case ASIC_INTERNAL_SS_ON_LVDS:
+				percentage = le16_to_cpu(igp_info->info_8.usLvdsSSPercentage);
+				rate = le16_to_cpu(igp_info->info_8.usLvdsSSpreadRateIn10Hz);
+				break;
+			}
+			break;
 		default:
 			DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
 			break;
@@ -1499,6 +1513,10 @@ bool radeon_atombios_get_asic_ss_info(st
 						le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage);
 					ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode;
 					ss->rate = le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadRateIn10Hz);
+					if ((crev == 2) &&
+					    ((id == ASIC_INTERNAL_ENGINE_SS) ||
+					     (id == ASIC_INTERNAL_MEMORY_SS)))
+						ss->rate /= 100;
 					return true;
 				}
 			}
@@ -1513,6 +1531,9 @@ bool radeon_atombios_get_asic_ss_info(st
 						le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage);
 					ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode;
 					ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz);
+					if ((id == ASIC_INTERNAL_ENGINE_SS) ||
+					    (id == ASIC_INTERNAL_MEMORY_SS))
+						ss->rate /= 100;
 					if (rdev->flags & RADEON_IS_IGP)
 						radeon_atombios_get_igp_ss_overrides(rdev, ss, id);
 					return true;
@@ -1927,6 +1948,7 @@ static const char *pp_lib_thermal_contro
 	"Northern Islands",
 	"Southern Islands",
 	"lm96163",
+	"Sea Islands",
 };
 
 union power_info {
@@ -1944,6 +1966,7 @@ union pplib_clock_info {
 	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
 	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
 	struct _ATOM_PPLIB_SI_CLOCK_INFO si;
+	struct _ATOM_PPLIB_CI_CLOCK_INFO ci;
 };
 
 union pplib_power_state {
@@ -2209,6 +2232,11 @@ static void radeon_atombios_add_pplib_th
 				 (controller->ucFanParameters &
 				  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
 			rdev->pm.int_thermal_type = THERMAL_TYPE_SI;
+		} else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_CISLANDS) {
+			DRM_INFO("Internal thermal controller %s fan control\n",
+				 (controller->ucFanParameters &
+				  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
+			rdev->pm.int_thermal_type = THERMAL_TYPE_CI;
 		} else if ((controller->ucType ==
 			    ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) ||
 			   (controller->ucType ==
@@ -2241,8 +2269,8 @@ static void radeon_atombios_add_pplib_th
 	}
 }
 
-static void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
-						 u16 *vddc, u16 *vddci)
+void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
+					  u16 *vddc, u16 *vddci, u16 *mvdd)
 {
 	struct radeon_mode_info *mode_info = &rdev->mode_info;
 	int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
@@ -2252,6 +2280,7 @@ static void radeon_atombios_get_default_
 
 	*vddc = 0;
 	*vddci = 0;
+	*mvdd = 0;
 
 	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
 				   &frev, &crev, &data_offset)) {
@@ -2259,8 +2288,10 @@ static void radeon_atombios_get_default_
 			(union firmware_info *)(mode_info->atom_context->bios +
 						data_offset);
 		*vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
-		if ((frev == 2) && (crev >= 2))
+		if ((frev == 2) && (crev >= 2)) {
 			*vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);
+			*mvdd = le16_to_cpu(firmware_info->info_22.usBootUpMVDDCVoltage);
+		}
 	}
 }
 
@@ -2271,9 +2302,9 @@ static void radeon_atombios_parse_pplib_
 	int j;
 	u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
 	u32 misc2 = le16_to_cpu(non_clock_info->usClassification);
-	u16 vddc, vddci;
+	u16 vddc, vddci, mvdd;
 
-	radeon_atombios_get_default_voltages(rdev, &vddc, &vddci);
+	radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
 
 	rdev->pm.power_state[state_index].misc = misc;
 	rdev->pm.power_state[state_index].misc2 = misc2;
@@ -2316,7 +2347,13 @@ static void radeon_atombios_parse_pplib_
 			rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;
 			rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci;
 		} else {
-			/* patch the table values with the default slck/mclk from firmware info */
+			u16 max_vddci = 0;
+
+			if (ASIC_IS_DCE4(rdev))
+				radeon_atom_get_max_voltage(rdev,
+							    SET_VOLTAGE_TYPE_ASIC_VDDCI,
+							    &max_vddci);
+			/* patch the table values with the default sclk/mclk from firmware info */
 			for (j = 0; j < mode_index; j++) {
 				rdev->pm.power_state[state_index].clock_info[j].mclk =
 					rdev->clock.default_mclk;
@@ -2325,6 +2362,9 @@ static void radeon_atombios_parse_pplib_
 				if (vddc)
 					rdev->pm.power_state[state_index].clock_info[j].voltage.voltage =
 						vddc;
+				if (max_vddci)
+					rdev->pm.power_state[state_index].clock_info[j].voltage.vddci =
+						max_vddci;
 			}
 		}
 	}
@@ -2347,6 +2387,15 @@ static bool radeon_atombios_parse_pplib_
 			sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
 			rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
 		}
+	} else if (rdev->family >= CHIP_BONAIRE) {
+		sclk = le16_to_cpu(clock_info->ci.usEngineClockLow);
+		sclk |= clock_info->ci.ucEngineClockHigh << 16;
+		mclk = le16_to_cpu(clock_info->ci.usMemoryClockLow);
+		mclk |= clock_info->ci.ucMemoryClockHigh << 16;
+		rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk;
+		rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk;
+		rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type =
+			VOLTAGE_NONE;
 	} else if (rdev->family >= CHIP_TAHITI) {
 		sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
 		sclk |= clock_info->si.ucEngineClockHigh << 16;
@@ -2392,6 +2441,10 @@ static bool radeon_atombios_parse_pplib_
 	case ATOM_VIRTUAL_VOLTAGE_ID1:
 	case ATOM_VIRTUAL_VOLTAGE_ID2:
 	case ATOM_VIRTUAL_VOLTAGE_ID3:
+	case ATOM_VIRTUAL_VOLTAGE_ID4:
+	case ATOM_VIRTUAL_VOLTAGE_ID5:
+	case ATOM_VIRTUAL_VOLTAGE_ID6:
+	case ATOM_VIRTUAL_VOLTAGE_ID7:
 		if (radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC,
 					     rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage,
 					     &vddc) == 0)
@@ -2667,6 +2720,8 @@ union get_clock_dividers {
 	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3 v3;
 	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 v4;
 	struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 v5;
+	struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6 v6_in;
+	struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6 v6_out;
 };
 
 int radeon_atom_get_clock_dividers(struct radeon_device *rdev,
@@ -2699,7 +2754,8 @@ int radeon_atom_get_clock_dividers(struc
 		break;
 	case 2:
 	case 3:
-		/* r6xx, r7xx, evergreen, ni */
+	case 5:
+		/* r6xx, r7xx, evergreen, ni, si */
 		if (rdev->family <= CHIP_RV770) {
 			args.v2.ucAction = clock_type;
 			args.v2.ulClock = cpu_to_le32(clock);	/* 10 khz */
@@ -2726,12 +2782,15 @@ int radeon_atom_get_clock_dividers(struc
 							     ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false;
 				dividers->enable_dithen = (args.v3.ucCntlFlag &
 							   ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true;
-				dividers->fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
+				dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv);
 				dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac);
 				dividers->ref_div = args.v3.ucRefDiv;
 				dividers->vco_mode = (args.v3.ucCntlFlag &
 						      ATOM_PLL_CNTL_FLAG_MPLL_VCO_MODE) ? 1 : 0;
 			} else {
+				/* for SI we use ComputeMemoryClockParam for memory plls */
+				if (rdev->family >= CHIP_TAHITI)
+					return -EINVAL;
 				args.v5.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
 				if (strobe_mode)
 					args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
@@ -2757,9 +2816,76 @@ int radeon_atom_get_clock_dividers(struc
 
 		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
-		dividers->post_div = args.v4.ucPostDiv;
+		dividers->post_divider = dividers->post_div = args.v4.ucPostDiv;
 		dividers->real_clock = le32_to_cpu(args.v4.ulClock);
 		break;
+	case 6:
+		/* CI */
+		/* COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, COMPUTE_GPUCLK_INPUT_FLAG_SCLK */
+		args.v6_in.ulClock.ulComputeClockFlag = clock_type;
+		args.v6_in.ulClock.ulClockFreq = cpu_to_le32(clock);	/* 10 khz */
+
+		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+		dividers->whole_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDiv);
+		dividers->frac_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDivFrac);
+		dividers->ref_div = args.v6_out.ucPllRefDiv;
+		dividers->post_div = args.v6_out.ucPllPostDiv;
+		dividers->flags = args.v6_out.ucPllCntlFlag;
+		dividers->real_clock = le32_to_cpu(args.v6_out.ulClock.ulClock);
+		dividers->post_divider = args.v6_out.ulClock.ucPostDiv;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev,
+					u32 clock,
+					bool strobe_mode,
+					struct atom_mpll_param *mpll_param)
+{
+	COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1 args;
+	int index = GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam);
+	u8 frev, crev;
+
+	memset(&args, 0, sizeof(args));
+	memset(mpll_param, 0, sizeof(struct atom_mpll_param));
+
+	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+		return -EINVAL;
+
+	switch (frev) {
+	case 2:
+		switch (crev) {
+		case 1:
+			/* SI */
+			args.ulClock = cpu_to_le32(clock);	/* 10 khz */
+			args.ucInputFlag = 0;
+			if (strobe_mode)
+				args.ucInputFlag |= MPLL_INPUT_FLAG_STROBE_MODE_EN;
+
+			atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+			mpll_param->clkfrac = le16_to_cpu(args.ulFbDiv.usFbDivFrac);
+			mpll_param->clkf = le16_to_cpu(args.ulFbDiv.usFbDiv);
+			mpll_param->post_div = args.ucPostDiv;
+			mpll_param->dll_speed = args.ucDllSpeed;
+			mpll_param->bwcntl = args.ucBWCntl;
+			mpll_param->vco_mode =
+				(args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK) ? 1 : 0;
+			mpll_param->yclk_sel =
+				(args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0;
+			mpll_param->qdr =
+				(args.ucPllCntlFlag & MPLL_CNTL_FLAG_QDR_ENABLE) ? 1 : 0;
+			mpll_param->half_rate =
+				(args.ucPllCntlFlag & MPLL_CNTL_FLAG_AD_HALF_RATE) ? 1 : 0;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -2819,6 +2945,48 @@ void radeon_atom_set_memory_clock(struct
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+void radeon_atom_set_engine_dram_timings(struct radeon_device *rdev,
+					 u32 eng_clock, u32 mem_clock)
+{
+	SET_ENGINE_CLOCK_PS_ALLOCATION args;
+	int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
+	u32 tmp;
+
+	memset(&args, 0, sizeof(args));
+
+	tmp = eng_clock & SET_CLOCK_FREQ_MASK;
+	tmp |= (COMPUTE_ENGINE_PLL_PARAM << 24);
+
+	args.ulTargetEngineClock = cpu_to_le32(tmp);
+	if (mem_clock)
+		args.sReserved.ulClock = cpu_to_le32(mem_clock & SET_CLOCK_FREQ_MASK);
+
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+void radeon_atom_update_memory_dll(struct radeon_device *rdev,
+				   u32 mem_clock)
+{
+	u32 args;
+	int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
+
+	args = cpu_to_le32(mem_clock);	/* 10 khz */
+
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
+void radeon_atom_set_ac_timing(struct radeon_device *rdev,
+			       u32 mem_clock)
+{
+	SET_MEMORY_CLOCK_PS_ALLOCATION args;
+	int index = GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings);
+	u32 tmp = mem_clock | (COMPUTE_MEMORY_PLL_PARAM << 24);
+
+	args.ulTargetMemoryClock = cpu_to_le32(tmp);	/* 10 khz */
+
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+}
+
 union set_voltage {
 	struct _SET_VOLTAGE_PS_ALLOCATION alloc;
 	struct _SET_VOLTAGE_PARAMETERS v1;
@@ -2863,8 +3031,8 @@ void radeon_atom_set_voltage(struct rade
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
-static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
-				    u16 voltage_id, u16 *voltage)
+int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
+			     u16 voltage_id, u16 *voltage)
 {
 	union set_voltage args;
 	int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
@@ -2902,6 +3070,693 @@ static int radeon_atom_get_max_vddc(stru
 	return 0;
 }
 
+int radeon_atom_get_leakage_vddc_based_on_leakage_idx(struct radeon_device *rdev,
+						      u16 *voltage,
+						      u16 leakage_idx)
+{
+	return radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC, leakage_idx, voltage);
+}
+
+int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev,
+					  u16 voltage_level, u8 voltage_type,
+					  u32 *gpio_value, u32 *gpio_mask)
+{
+	union set_voltage args;
+	int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
+	u8 frev, crev;
+
+	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+		return -EINVAL;
+
+	switch (crev) {
+	case 1:
+		return -EINVAL;
+	case 2:
+		args.v2.ucVoltageType = voltage_type;
+		args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK;
+		args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
+
+		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+		*gpio_mask = le32_to_cpu(*(u32 *)&args.v2);
+
+		args.v2.ucVoltageType = voltage_type;
+		args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL;
+		args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
+
+		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+		*gpio_value = le32_to_cpu(*(u32 *)&args.v2);
+		break;
+	default:
+		DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+union voltage_object_info {
+	struct _ATOM_VOLTAGE_OBJECT_INFO v1;
+	struct _ATOM_VOLTAGE_OBJECT_INFO_V2 v2;
+	struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1 v3;
+};
+
+union voltage_object {
+	struct _ATOM_VOLTAGE_OBJECT v1;
+	struct _ATOM_VOLTAGE_OBJECT_V2 v2;
+	union _ATOM_VOLTAGE_OBJECT_V3 v3;
+};
+
+static ATOM_VOLTAGE_OBJECT *atom_lookup_voltage_object_v1(ATOM_VOLTAGE_OBJECT_INFO *v1,
+							  u8 voltage_type)
+{
+	u32 size = le16_to_cpu(v1->sHeader.usStructureSize);
+	u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO, asVoltageObj[0]);
+	u8 *start = (u8 *)v1;
+
+	while (offset < size) {
+		ATOM_VOLTAGE_OBJECT *vo = (ATOM_VOLTAGE_OBJECT *)(start + offset);
+		if (vo->ucVoltageType == voltage_type)
+			return vo;
+		offset += offsetof(ATOM_VOLTAGE_OBJECT, asFormula.ucVIDAdjustEntries) +
+			vo->asFormula.ucNumOfVoltageEntries;
+	}
+	return NULL;
+}
+
+static ATOM_VOLTAGE_OBJECT_V2 *atom_lookup_voltage_object_v2(ATOM_VOLTAGE_OBJECT_INFO_V2 *v2,
+							     u8 voltage_type)
+{
+	u32 size = le16_to_cpu(v2->sHeader.usStructureSize);
+	u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V2, asVoltageObj[0]);
+	u8 *start = (u8*)v2;
+
+	while (offset < size) {
+		ATOM_VOLTAGE_OBJECT_V2 *vo = (ATOM_VOLTAGE_OBJECT_V2 *)(start + offset);
+		if (vo->ucVoltageType == voltage_type)
+			return vo;
+		offset += offsetof(ATOM_VOLTAGE_OBJECT_V2, asFormula.asVIDAdjustEntries) +
+			(vo->asFormula.ucNumOfVoltageEntries * sizeof(VOLTAGE_LUT_ENTRY));
+	}
+	return NULL;
+}
+
+static ATOM_VOLTAGE_OBJECT_V3 *atom_lookup_voltage_object_v3(ATOM_VOLTAGE_OBJECT_INFO_V3_1 *v3,
+							     u8 voltage_type, u8 voltage_mode)
+{
+	u32 size = le16_to_cpu(v3->sHeader.usStructureSize);
+	u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]);
+	u8 *start = (u8*)v3;
+
+	while (offset < size) {
+		ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset);
+		if ((vo->asGpioVoltageObj.sHeader.ucVoltageType == voltage_type) &&
+		    (vo->asGpioVoltageObj.sHeader.ucVoltageMode == voltage_mode))
+			return vo;
+		offset += le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize);
+	}
+	return NULL;
+}
+
+bool
+radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
+			    u8 voltage_type, u8 voltage_mode)
+{
+	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
+	u8 frev, crev;
+	u16 data_offset, size;
+	union voltage_object_info *voltage_info;
+	union voltage_object *voltage_object = NULL;
+
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
+				   &frev, &crev, &data_offset)) {
+		voltage_info = (union voltage_object_info *)
+			(rdev->mode_info.atom_context->bios + data_offset);
+
+		switch (frev) {
+		case 1:
+		case 2:
+			switch (crev) {
+			case 1:
+				voltage_object = (union voltage_object *)
+					atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
+				if (voltage_object &&
+				    (voltage_object->v1.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO))
+					return true;
+				break;
+			case 2:
+				voltage_object = (union voltage_object *)
+					atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
+				if (voltage_object &&
+				    (voltage_object->v2.asControl.ucVoltageControlId == VOLTAGE_CONTROLLED_BY_GPIO))
+					return true;
+				break;
+			default:
+				DRM_ERROR("unknown voltage object table\n");
+				return false;
+			}
+			break;
+		case 3:
+			switch (crev) {
+			case 1:
+				if (atom_lookup_voltage_object_v3(&voltage_info->v3,
+								  voltage_type, voltage_mode))
+					return true;
+				break;
+			default:
+				DRM_ERROR("unknown voltage object table\n");
+				return false;
+			}
+			break;
+		default:
+			DRM_ERROR("unknown voltage object table\n");
+			return false;
+		}
+
+	}
+	return false;
+}
+
+int radeon_atom_get_max_voltage(struct radeon_device *rdev,
+				u8 voltage_type, u16 *max_voltage)
+{
+	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
+	u8 frev, crev;
+	u16 data_offset, size;
+	union voltage_object_info *voltage_info;
+	union voltage_object *voltage_object = NULL;
+
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
+				   &frev, &crev, &data_offset)) {
+		voltage_info = (union voltage_object_info *)
+			(rdev->mode_info.atom_context->bios + data_offset);
+
+		switch (crev) {
+		case 1:
+			voltage_object = (union voltage_object *)
+				atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
+			if (voltage_object) {
+				ATOM_VOLTAGE_FORMULA *formula =
+					&voltage_object->v1.asFormula;
+				if (formula->ucFlag & 1)
+					*max_voltage =
+						le16_to_cpu(formula->usVoltageBaseLevel) +
+						formula->ucNumOfVoltageEntries / 2 *
+						le16_to_cpu(formula->usVoltageStep);
+				else
+					*max_voltage =
+						le16_to_cpu(formula->usVoltageBaseLevel) +
+						(formula->ucNumOfVoltageEntries - 1) *
+						le16_to_cpu(formula->usVoltageStep);
+				return 0;
+			}
+			break;
+		case 2:
+			voltage_object = (union voltage_object *)
+				atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
+			if (voltage_object) {
+				ATOM_VOLTAGE_FORMULA_V2 *formula =
+					&voltage_object->v2.asFormula;
+				if (formula->ucNumOfVoltageEntries) {
+					*max_voltage =
+						le16_to_cpu(formula->asVIDAdjustEntries[
+								    formula->ucNumOfVoltageEntries - 1
+								    ].usVoltageValue);
+					return 0;
+				}
+			}
+			break;
+		default:
+			DRM_ERROR("unknown voltage object table\n");
+			return -EINVAL;
+		}
+
+	}
+	return -EINVAL;
+}
+
+int radeon_atom_get_min_voltage(struct radeon_device *rdev,
+				u8 voltage_type, u16 *min_voltage)
+{
+	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
+	u8 frev, crev;
+	u16 data_offset, size;
+	union voltage_object_info *voltage_info;
+	union voltage_object *voltage_object = NULL;
+
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
+				   &frev, &crev, &data_offset)) {
+		voltage_info = (union voltage_object_info *)
+			(rdev->mode_info.atom_context->bios + data_offset);
+
+		switch (crev) {
+		case 1:
+			voltage_object = (union voltage_object *)
+				atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
+			if (voltage_object) {
+				ATOM_VOLTAGE_FORMULA *formula =
+					&voltage_object->v1.asFormula;
+				*min_voltage =
+					le16_to_cpu(formula->usVoltageBaseLevel);
+				return 0;
+			}
+			break;
+		case 2:
+			voltage_object = (union voltage_object *)
+				atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
+			if (voltage_object) {
+				ATOM_VOLTAGE_FORMULA_V2 *formula =
+					&voltage_object->v2.asFormula;
+				if (formula->ucNumOfVoltageEntries) {
+					*min_voltage =
+						le16_to_cpu(formula->asVIDAdjustEntries[
+								    0
+								    ].usVoltageValue);
+					return 0;
+				}
+			}
+			break;
+		default:
+			DRM_ERROR("unknown voltage object table\n");
+			return -EINVAL;
+		}
+
+	}
+	return -EINVAL;
+}
+
+int radeon_atom_get_voltage_step(struct radeon_device *rdev,
+				 u8 voltage_type, u16 *voltage_step)
+{
+	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
+	u8 frev, crev;
+	u16 data_offset, size;
+	union voltage_object_info *voltage_info;
+	union voltage_object *voltage_object = NULL;
+
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
+				   &frev, &crev, &data_offset)) {
+		voltage_info = (union voltage_object_info *)
+			(rdev->mode_info.atom_context->bios + data_offset);
+
+		switch (crev) {
+		case 1:
+			voltage_object = (union voltage_object *)
+				atom_lookup_voltage_object_v1(&voltage_info->v1, voltage_type);
+			if (voltage_object) {
+				ATOM_VOLTAGE_FORMULA *formula =
+					&voltage_object->v1.asFormula;
+				if (formula->ucFlag & 1)
+					*voltage_step =
+						(le16_to_cpu(formula->usVoltageStep) + 1) / 2;
+				else
+					*voltage_step =
+						le16_to_cpu(formula->usVoltageStep);
+				return 0;
+			}
+			break;
+		case 2:
+			return -EINVAL;
+		default:
+			DRM_ERROR("unknown voltage object table\n");
+			return -EINVAL;
+		}
+
+	}
+	return -EINVAL;
+}
+
+int radeon_atom_round_to_true_voltage(struct radeon_device *rdev,
+				      u8 voltage_type,
+				      u16 nominal_voltage,
+				      u16 *true_voltage)
+{
+	u16 min_voltage, max_voltage, voltage_step;
+
+	if (radeon_atom_get_max_voltage(rdev, voltage_type, &max_voltage))
+		return -EINVAL;
+	if (radeon_atom_get_min_voltage(rdev, voltage_type, &min_voltage))
+		return -EINVAL;
+	if (radeon_atom_get_voltage_step(rdev, voltage_type, &voltage_step))
+		return -EINVAL;
+
+	if (nominal_voltage <= min_voltage)
+		*true_voltage = min_voltage;
+	else if (nominal_voltage >= max_voltage)
+		*true_voltage = max_voltage;
+	else
+		*true_voltage = min_voltage +
+			((nominal_voltage - min_voltage) / voltage_step) *
+			voltage_step;
+
+	return 0;
+}
+
+int radeon_atom_get_voltage_table(struct radeon_device *rdev,
+				  u8 voltage_type, u8 voltage_mode,
+				  struct atom_voltage_table *voltage_table)
+{
+	int index = GetIndexIntoMasterTable(DATA, VoltageObjectInfo);
+	u8 frev, crev;
+	u16 data_offset, size;
+	int i, ret;
+	union voltage_object_info *voltage_info;
+	union voltage_object *voltage_object = NULL;
+
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
+				   &frev, &crev, &data_offset)) {
+		voltage_info = (union voltage_object_info *)
+			(rdev->mode_info.atom_context->bios + data_offset);
+
+		switch (frev) {
+		case 1:
+		case 2:
+			switch (crev) {
+			case 1:
+				DRM_ERROR("old table version %d, %d\n", frev, crev);
+				return -EINVAL;
+			case 2:
+				voltage_object = (union voltage_object *)
+					atom_lookup_voltage_object_v2(&voltage_info->v2, voltage_type);
+				if (voltage_object) {
+					ATOM_VOLTAGE_FORMULA_V2 *formula =
+						&voltage_object->v2.asFormula;
+					if (formula->ucNumOfVoltageEntries > MAX_VOLTAGE_ENTRIES)
+						return -EINVAL;
+					for (i = 0; i < formula->ucNumOfVoltageEntries; i++) {
+						voltage_table->entries[i].value =
+							le16_to_cpu(formula->asVIDAdjustEntries[i].usVoltageValue);
+						ret = radeon_atom_get_voltage_gpio_settings(rdev,
+											    voltage_table->entries[i].value,
+											    voltage_type,
+											    &voltage_table->entries[i].smio_low,
+											    &voltage_table->mask_low);
+						if (ret)
+							return ret;
+					}
+					voltage_table->count = formula->ucNumOfVoltageEntries;
+					return 0;
+				}
+				break;
+			default:
+				DRM_ERROR("unknown voltage object table\n");
+				return -EINVAL;
+			}
+			break;
+		case 3:
+			switch (crev) {
+			case 1:
+				voltage_object = (union voltage_object *)
+					atom_lookup_voltage_object_v3(&voltage_info->v3,
+								      voltage_type, voltage_mode);
+				if (voltage_object) {
+					ATOM_GPIO_VOLTAGE_OBJECT_V3 *gpio =
+						&voltage_object->v3.asGpioVoltageObj;
+					if (gpio->ucGpioEntryNum > MAX_VOLTAGE_ENTRIES)
+						return -EINVAL;
+					for (i = 0; i < gpio->ucGpioEntryNum; i++) {
+						voltage_table->entries[i].value =
+							le16_to_cpu(gpio->asVolGpioLut[i].usVoltageValue);
+						voltage_table->entries[i].smio_low =
+							le32_to_cpu(gpio->asVolGpioLut[i].ulVoltageId);
+					}
+					voltage_table->mask_low = le32_to_cpu(gpio->ulGpioMaskVal);
+					voltage_table->count = gpio->ucGpioEntryNum;
+					voltage_table->phase_delay = gpio->ucPhaseDelay;
+					return 0;
+				}
+				break;
+			default:
+				DRM_ERROR("unknown voltage object table\n");
+				return -EINVAL;
+			}
+			break;
+		default:
+			DRM_ERROR("unknown voltage object table\n");
+			return -EINVAL;
+		}
+	}
+	return -EINVAL;
+}
+
+union vram_info {
+	struct _ATOM_VRAM_INFO_V3 v1_3;
+	struct _ATOM_VRAM_INFO_V4 v1_4;
+	struct _ATOM_VRAM_INFO_HEADER_V2_1 v2_1;
+};
+
+int radeon_atom_get_memory_info(struct radeon_device *rdev,
+				u8 module_index, struct atom_memory_info *mem_info)
+{
+	int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
+	u8 frev, crev, i;
+	u16 data_offset, size;
+	union vram_info *vram_info;
+
+	memset(mem_info, 0, sizeof(struct atom_memory_info));
+
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
+				   &frev, &crev, &data_offset)) {
+		vram_info = (union vram_info *)
+			(rdev->mode_info.atom_context->bios + data_offset);
+		switch (frev) {
+		case 1:
+			switch (crev) {
+			case 3:
+				/* r6xx */
+				if (module_index < vram_info->v1_3.ucNumOfVRAMModule) {
+					ATOM_VRAM_MODULE_V3 *vram_module =
+						(ATOM_VRAM_MODULE_V3 *)vram_info->v1_3.aVramInfo;
+
+					for (i = 0; i < module_index; i++) {
+						if (le16_to_cpu(vram_module->usSize) == 0)
+							return -EINVAL;
+						vram_module = (ATOM_VRAM_MODULE_V3 *)
+							((u8 *)vram_module + le16_to_cpu(vram_module->usSize));
+					}
+					mem_info->mem_vendor = vram_module->asMemory.ucMemoryVenderID & 0xf;
+					mem_info->mem_type = vram_module->asMemory.ucMemoryType & 0xf0;
+				} else
+					return -EINVAL;
+				break;
+			case 4:
+				/* r7xx, evergreen */
+				if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
+					ATOM_VRAM_MODULE_V4 *vram_module =
+						(ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
+
+					for (i = 0; i < module_index; i++) {
+						if (le16_to_cpu(vram_module->usModuleSize) == 0)
+							return -EINVAL;
+						vram_module = (ATOM_VRAM_MODULE_V4 *)
+							((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
+					}
+					mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
+					mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
+				} else
+					return -EINVAL;
+				break;
+			default:
+				DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+				return -EINVAL;
+			}
+			break;
+		case 2:
+			switch (crev) {
+			case 1:
+				/* ni */
+				if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
+					ATOM_VRAM_MODULE_V7 *vram_module =
+						(ATOM_VRAM_MODULE_V7 *)vram_info->v2_1.aVramInfo;
+
+					for (i = 0; i < module_index; i++) {
+						if (le16_to_cpu(vram_module->usModuleSize) == 0)
+							return -EINVAL;
+						vram_module = (ATOM_VRAM_MODULE_V7 *)
+							((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
+					}
+					mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
+					mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
+				} else
+					return -EINVAL;
+				break;
+			default:
+				DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+				return -EINVAL;
+			}
+			break;
+		default:
+			DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+			return -EINVAL;
+		}
+		return 0;
+	}
+	return -EINVAL;
+}
+
+int radeon_atom_get_mclk_range_table(struct radeon_device *rdev,
+				     bool gddr5, u8 module_index,
+				     struct atom_memory_clock_range_table *mclk_range_table)
+{
+	int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
+	u8 frev, crev, i;
+	u16 data_offset, size;
+	union vram_info *vram_info;
+	u32 mem_timing_size = gddr5 ?
+		sizeof(ATOM_MEMORY_TIMING_FORMAT_V2) : sizeof(ATOM_MEMORY_TIMING_FORMAT);
+	u8 *p;
+
+	memset(mclk_range_table, 0, sizeof(struct atom_memory_clock_range_table));
+
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
+				   &frev, &crev, &data_offset)) {
+		vram_info = (union vram_info *)
+			(rdev->mode_info.atom_context->bios + data_offset);
+		switch (frev) {
+		case 1:
+			switch (crev) {
+			case 3:
+				DRM_ERROR("old table version %d, %d\n", frev, crev);
+				return -EINVAL;
+			case 4:
+				/* r7xx, evergreen */
+				if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
+					ATOM_VRAM_MODULE_V4 *vram_module =
+						(ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
+
+					for (i = 0; i < module_index; i++) {
+						if (le16_to_cpu(vram_module->usModuleSize) == 0)
+							return -EINVAL;
+						vram_module = (ATOM_VRAM_MODULE_V4 *)
+							((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
+					}
+					mclk_range_table->num_entries = (u8)
+						((le16_to_cpu(vram_module->usModuleSize) - offsetof(ATOM_VRAM_MODULE_V4, asMemTiming)) /
+						 mem_timing_size);
+					p = (u8 *)&vram_module->asMemTiming[0];
+					for (i = 0; i < mclk_range_table->num_entries; i++) {
+						ATOM_MEMORY_TIMING_FORMAT *format = (ATOM_MEMORY_TIMING_FORMAT *)p;
+						mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange);
+						p += mem_timing_size;
+					}
+				} else
+					return -EINVAL;
+				break;
+			default:
+				DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+				return -EINVAL;
+			}
+			break;
+		case 2:
+			DRM_ERROR("new table version %d, %d\n", frev, crev);
+			return -EINVAL;
+		default:
+			DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+			return -EINVAL;
+		}
+		return 0;
+	}
+	return -EINVAL;
+}
+
+#define MEM_ID_MASK           0xff000000
+#define MEM_ID_SHIFT          24
+#define CLOCK_RANGE_MASK      0x00ffffff
+#define CLOCK_RANGE_SHIFT     0
+#define LOW_NIBBLE_MASK       0xf
+#define DATA_EQU_PREV         0
+#define DATA_FROM_TABLE       4
+
+int radeon_atom_init_mc_reg_table(struct radeon_device *rdev,
+				  u8 module_index,
+				  struct atom_mc_reg_table *reg_table)
+{
+	int index = GetIndexIntoMasterTable(DATA, VRAM_Info);
+	u8 frev, crev, num_entries, t_mem_id, num_ranges = 0;
+	u32 i = 0, j;
+	u16 data_offset, size;
+	union vram_info *vram_info;
+
+	memset(reg_table, 0, sizeof(struct atom_mc_reg_table));
+
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
+				   &frev, &crev, &data_offset)) {
+		vram_info = (union vram_info *)
+			(rdev->mode_info.atom_context->bios + data_offset);
+		switch (frev) {
+		case 1:
+			DRM_ERROR("old table version %d, %d\n", frev, crev);
+			return -EINVAL;
+		case 2:
+			switch (crev) {
+			case 1:
+				if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
+					ATOM_INIT_REG_BLOCK *reg_block =
+						(ATOM_INIT_REG_BLOCK *)
+						((u8 *)vram_info + le16_to_cpu(vram_info->v2_1.usMemClkPatchTblOffset));
+					ATOM_MEMORY_SETTING_DATA_BLOCK *reg_data =
+						(ATOM_MEMORY_SETTING_DATA_BLOCK *)
+						((u8 *)reg_block + (2 * sizeof(u16)) +
+						 le16_to_cpu(reg_block->usRegIndexTblSize));
+					ATOM_INIT_REG_INDEX_FORMAT *format = &reg_block->asRegIndexBuf[0];
+					num_entries = (u8)((le16_to_cpu(reg_block->usRegIndexTblSize)) /
+							   sizeof(ATOM_INIT_REG_INDEX_FORMAT)) - 1;
+					if (num_entries > VBIOS_MC_REGISTER_ARRAY_SIZE)
+						return -EINVAL;
+					while (i < num_entries) {
+						if (format->ucPreRegDataLength & ACCESS_PLACEHOLDER)
+							break;
+						reg_table->mc_reg_address[i].s1 =
+							(u16)(le16_to_cpu(format->usRegIndex));
+						reg_table->mc_reg_address[i].pre_reg_data =
+							(u8)(format->ucPreRegDataLength);
+						i++;
+						format = (ATOM_INIT_REG_INDEX_FORMAT *)
+							((u8 *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT));
+					}
+					reg_table->last = i;
+					while ((*(u32 *)reg_data != END_OF_REG_DATA_BLOCK) &&
+					       (num_ranges < VBIOS_MAX_AC_TIMING_ENTRIES)) {
+						t_mem_id = (u8)((*(u32 *)reg_data & MEM_ID_MASK) >> MEM_ID_SHIFT);
+						if (module_index == t_mem_id) {
+							reg_table->mc_reg_table_entry[num_ranges].mclk_max =
+								(u32)((*(u32 *)reg_data & CLOCK_RANGE_MASK) >> CLOCK_RANGE_SHIFT);
+							for (i = 0, j = 1; i < reg_table->last; i++) {
+								if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_FROM_TABLE) {
+									reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
+										(u32)*((u32 *)reg_data + j);
+									j++;
+								} else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
+									reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
+										reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1];
+								}
+							}
+							num_ranges++;
+						}
+						reg_data = (ATOM_MEMORY_SETTING_DATA_BLOCK *)
+							((u8 *)reg_data + le16_to_cpu(reg_block->usRegDataBlkSize));
+					}
+					if (*(u32 *)reg_data != END_OF_REG_DATA_BLOCK)
+						return -EINVAL;
+					reg_table->num_entries = num_ranges;
+				} else
+					return -EINVAL;
+				break;
+			default:
+				DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+				return -EINVAL;
+			}
+			break;
+		default:
+			DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+			return -EINVAL;
+		}
+		return 0;
+	}
+	return -EINVAL;
+}
+
 void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_combios.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_combios.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_combios.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_combios.c	2013-08-25 20:43:22.000000000 -0400
@@ -147,7 +147,7 @@ static uint16_t combios_get_table_offset
 					 enum radeon_combios_table_offset table)
 {
 	struct radeon_device *rdev = dev->dev_private;
-	int rev;
+	int rev, size;
 	uint16_t offset = 0, check_offset;
 
 	if (!rdev->bios)
@@ -156,174 +156,106 @@ static uint16_t combios_get_table_offset
 	switch (table) {
 		/* absolute offset tables */
 	case COMBIOS_ASIC_INIT_1_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0xc);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0xc;
 		break;
 	case COMBIOS_BIOS_SUPPORT_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x14);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x14;
 		break;
 	case COMBIOS_DAC_PROGRAMMING_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x2a);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x2a;
 		break;
 	case COMBIOS_MAX_COLOR_DEPTH_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x2c);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x2c;
 		break;
 	case COMBIOS_CRTC_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x2e);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x2e;
 		break;
 	case COMBIOS_PLL_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x30);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x30;
 		break;
 	case COMBIOS_TV_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x32);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x32;
 		break;
 	case COMBIOS_DFP_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x34);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x34;
 		break;
 	case COMBIOS_HW_CONFIG_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x36);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x36;
 		break;
 	case COMBIOS_MULTIMEDIA_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x38);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x38;
 		break;
 	case COMBIOS_TV_STD_PATCH_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x3e);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x3e;
 		break;
 	case COMBIOS_LCD_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x40);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x40;
 		break;
 	case COMBIOS_MOBILE_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x42);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x42;
 		break;
 	case COMBIOS_PLL_INIT_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x46);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x46;
 		break;
 	case COMBIOS_MEM_CONFIG_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x48);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x48;
 		break;
 	case COMBIOS_SAVE_MASK_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x4a);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x4a;
 		break;
 	case COMBIOS_HARDCODED_EDID_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x4c);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x4c;
 		break;
 	case COMBIOS_ASIC_INIT_2_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x4e);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x4e;
 		break;
 	case COMBIOS_CONNECTOR_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x50);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x50;
 		break;
 	case COMBIOS_DYN_CLK_1_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x52);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x52;
 		break;
 	case COMBIOS_RESERVED_MEM_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x54);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x54;
 		break;
 	case COMBIOS_EXT_TMDS_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x58);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x58;
 		break;
 	case COMBIOS_MEM_CLK_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x5a);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x5a;
 		break;
 	case COMBIOS_EXT_DAC_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x5c);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x5c;
 		break;
 	case COMBIOS_MISC_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x5e);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x5e;
 		break;
 	case COMBIOS_CRT_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x60);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x60;
 		break;
 	case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x62);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x62;
 		break;
 	case COMBIOS_COMPONENT_VIDEO_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x64);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x64;
 		break;
 	case COMBIOS_FAN_SPEED_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x66);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x66;
 		break;
 	case COMBIOS_OVERDRIVE_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x68);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x68;
 		break;
 	case COMBIOS_OEM_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x6a);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x6a;
 		break;
 	case COMBIOS_DYN_CLK_2_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x6c);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x6c;
 		break;
 	case COMBIOS_POWER_CONNECTOR_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x6e);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x6e;
 		break;
 	case COMBIOS_I2C_INFO_TABLE:
-		check_offset = RBIOS16(rdev->bios_header_start + 0x70);
-		if (check_offset)
-			offset = check_offset;
+		check_offset = 0x70;
 		break;
 		/* relative offset tables */
 	case COMBIOS_ASIC_INIT_3_TABLE:	/* offset from misc info */
@@ -439,11 +371,16 @@ static uint16_t combios_get_table_offset
 		}
 		break;
 	default:
+		check_offset = 0;
 		break;
 	}
 
-	return offset;
+	size = RBIOS8(rdev->bios_header_start + 0x6);
+	/* check absolute offset tables */
+	if (table < COMBIOS_ASIC_INIT_3_TABLE && check_offset && check_offset < size)
+		offset = RBIOS16(rdev->bios_header_start + check_offset);
 
+	return offset;
 }
 
 bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev)
@@ -965,16 +902,22 @@ struct radeon_encoder_primary_dac *radeo
 			dac = RBIOS8(dac_info + 0x3) & 0xf;
 			p_dac->ps2_pdac_adj = (bg << 8) | (dac);
 		}
-		/* if the values are all zeros, use the table */
-		if (p_dac->ps2_pdac_adj)
+		/* if the values are zeros, use the table */
+		if ((dac == 0) || (bg == 0))
+			found = 0;
+		else
 			found = 1;
 	}
 
 	/* quirks */
+	/* Radeon 7000 (RV100) */
+	if (((dev->pdev->device == 0x5159) &&
+	    (dev->pdev->subsystem_vendor == 0x174B) &&
+	    (dev->pdev->subsystem_device == 0x7c28)) ||
 	/* Radeon 9100 (R200) */
-	if ((dev->pdev->device == 0x514D) &&
+	   ((dev->pdev->device == 0x514D) &&
 	    (dev->pdev->subsystem_vendor == 0x174B) &&
-	    (dev->pdev->subsystem_device == 0x7149)) {
+	    (dev->pdev->subsystem_device == 0x7149))) {
 		/* vbios value is bad, use the default */
 		found = 0;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_cs.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_cs.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_cs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_cs.c	2013-08-25 20:43:22.000000000 -0400
@@ -106,7 +106,7 @@ static int radeon_cs_parser_relocs(struc
 		radeon_bo_list_add_object(&p->relocs[i].lobj,
 					  &p->validated);
 	}
-	return radeon_bo_list_validate(&p->validated, p->ring);
+	return radeon_bo_list_validate(&p->ticket, &p->validated, p->ring);
 }
 
 static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority)
@@ -314,15 +314,17 @@ int radeon_cs_parser_init(struct radeon_
  * If error is set than unvalidate buffer, otherwise just free memory
  * used by parsing context.
  **/
-static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
+static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bool backoff)
 {
 	unsigned i;
 
 	if (!error) {
-		ttm_eu_fence_buffer_objects(&parser->validated,
+		ttm_eu_fence_buffer_objects(&parser->ticket,
+					    &parser->validated,
 					    parser->ib.fence);
-	} else {
-		ttm_eu_backoff_reservation(&parser->validated);
+	} else if (backoff) {
+		ttm_eu_backoff_reservation(&parser->ticket,
+					   &parser->validated);
 	}
 
 	if (parser->relocs != NULL) {
@@ -535,7 +537,7 @@ int radeon_cs_ioctl(struct drm_device *d
 	r = radeon_cs_parser_init(&parser, data);
 	if (r) {
 		DRM_ERROR("Failed to initialize parser !\n");
-		radeon_cs_parser_fini(&parser, r);
+		radeon_cs_parser_fini(&parser, r, false);
 		up_read(&rdev->exclusive_lock);
 		r = radeon_cs_handle_lockup(rdev, r);
 		return r;
@@ -544,12 +546,13 @@ int radeon_cs_ioctl(struct drm_device *d
 	if (r) {
 		if (r != -ERESTARTSYS)
 			DRM_ERROR("Failed to parse relocation %d!\n", r);
-		radeon_cs_parser_fini(&parser, r);
+		radeon_cs_parser_fini(&parser, r, false);
 		up_read(&rdev->exclusive_lock);
 		r = radeon_cs_handle_lockup(rdev, r);
 		return r;
 	}
 
+	/* XXX pick SD/HD/MVC */
 	if (parser.ring == R600_RING_TYPE_UVD_INDEX)
 		radeon_uvd_note_usage(rdev);
 
@@ -562,7 +565,7 @@ int radeon_cs_ioctl(struct drm_device *d
 		goto out;
 	}
 out:
-	radeon_cs_parser_fini(&parser, r);
+	radeon_cs_parser_fini(&parser, r, true);
 	up_read(&rdev->exclusive_lock);
 	r = radeon_cs_handle_lockup(rdev, r);
 	return r;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_cursor.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_cursor.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_cursor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_cursor.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,9 +27,6 @@
 #include <drm/radeon_drm.h>
 #include "radeon.h"
 
-#define CURSOR_WIDTH 64
-#define CURSOR_HEIGHT 64
-
 static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock)
 {
 	struct radeon_device *rdev = crtc->dev->dev_private;
@@ -167,7 +164,8 @@ int radeon_crtc_cursor_set(struct drm_cr
 		goto unpin;
 	}
 
-	if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
+	if ((width > radeon_crtc->max_cursor_width) ||
+	    (height > radeon_crtc->max_cursor_height)) {
 		DRM_ERROR("bad cursor width or height %d x %d\n", width, height);
 		return -EINVAL;
 	}
@@ -233,11 +231,11 @@ int radeon_crtc_cursor_move(struct drm_c
 	DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
 
 	if (x < 0) {
-		xorigin = min(-x, CURSOR_WIDTH - 1);
+		xorigin = min(-x, radeon_crtc->max_cursor_width - 1);
 		x = 0;
 	}
 	if (y < 0) {
-		yorigin = min(-y, CURSOR_HEIGHT - 1);
+		yorigin = min(-y, radeon_crtc->max_cursor_height - 1);
 		y = 0;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_device.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_device.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_device.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_device.c	2013-08-25 20:43:22.000000000 -0400
@@ -95,6 +95,9 @@ static const char radeon_family_name[][1
 	"VERDE",
 	"OLAND",
 	"HAINAN",
+	"BONAIRE",
+	"KAVERI",
+	"KABINI",
 	"LAST",
 };
 
@@ -229,6 +232,94 @@ void radeon_scratch_free(struct radeon_d
 }
 
 /*
+ * GPU doorbell aperture helpers function.
+ */
+/**
+ * radeon_doorbell_init - Init doorbell driver information.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Init doorbell driver information (CIK)
+ * Returns 0 on success, error on failure.
+ */
+int radeon_doorbell_init(struct radeon_device *rdev)
+{
+	int i;
+
+	/* doorbell bar mapping */
+	rdev->doorbell.base = pci_resource_start(rdev->pdev, 2);
+	rdev->doorbell.size = pci_resource_len(rdev->pdev, 2);
+
+	/* limit to 4 MB for now */
+	if (rdev->doorbell.size > (4 * 1024 * 1024))
+		rdev->doorbell.size = 4 * 1024 * 1024;
+
+	rdev->doorbell.ptr = ioremap(rdev->doorbell.base, rdev->doorbell.size);
+	if (rdev->doorbell.ptr == NULL) {
+		return -ENOMEM;
+	}
+	DRM_INFO("doorbell mmio base: 0x%08X\n", (uint32_t)rdev->doorbell.base);
+	DRM_INFO("doorbell mmio size: %u\n", (unsigned)rdev->doorbell.size);
+
+	rdev->doorbell.num_pages = rdev->doorbell.size / PAGE_SIZE;
+
+	for (i = 0; i < rdev->doorbell.num_pages; i++) {
+		rdev->doorbell.free[i] = true;
+	}
+	return 0;
+}
+
+/**
+ * radeon_doorbell_fini - Tear down doorbell driver information.
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Tear down doorbell driver information (CIK)
+ */
+void radeon_doorbell_fini(struct radeon_device *rdev)
+{
+	iounmap(rdev->doorbell.ptr);
+	rdev->doorbell.ptr = NULL;
+}
+
+/**
+ * radeon_doorbell_get - Allocate a doorbell page
+ *
+ * @rdev: radeon_device pointer
+ * @doorbell: doorbell page number
+ *
+ * Allocate a doorbell page for use by the driver (all asics).
+ * Returns 0 on success or -EINVAL on failure.
+ */
+int radeon_doorbell_get(struct radeon_device *rdev, u32 *doorbell)
+{
+	int i;
+
+	for (i = 0; i < rdev->doorbell.num_pages; i++) {
+		if (rdev->doorbell.free[i]) {
+			rdev->doorbell.free[i] = false;
+			*doorbell = i;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+/**
+ * radeon_doorbell_free - Free a doorbell page
+ *
+ * @rdev: radeon_device pointer
+ * @doorbell: doorbell page number
+ *
+ * Free a doorbell page allocated for use by the driver (all asics)
+ */
+void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell)
+{
+	if (doorbell < rdev->doorbell.num_pages)
+		rdev->doorbell.free[doorbell] = true;
+}
+
+/*
  * radeon_wb_*()
  * Writeback is the the method by which the the GPU updates special pages
  * in memory with the status of certain GPU events (fences, ring pointers,
@@ -1072,6 +1163,7 @@ int radeon_device_init(struct radeon_dev
 	mutex_init(&rdev->gem.mutex);
 	mutex_init(&rdev->pm.mutex);
 	mutex_init(&rdev->gpu_clock_mutex);
+	mutex_init(&rdev->srbm_mutex);
 	init_rwsem(&rdev->pm.mclk_lock);
 	init_rwsem(&rdev->exclusive_lock);
 	init_waitqueue_head(&rdev->irq.vblank_queue);
@@ -1145,8 +1237,13 @@ int radeon_device_init(struct radeon_dev
 	/* Registers mapping */
 	/* TODO: block userspace mapping of io register */
 	spin_lock_init(&rdev->mmio_idx_lock);
-	rdev->rmmio_base = pci_resource_start(rdev->pdev, 2);
-	rdev->rmmio_size = pci_resource_len(rdev->pdev, 2);
+	if (rdev->family >= CHIP_BONAIRE) {
+		rdev->rmmio_base = pci_resource_start(rdev->pdev, 5);
+		rdev->rmmio_size = pci_resource_len(rdev->pdev, 5);
+	} else {
+		rdev->rmmio_base = pci_resource_start(rdev->pdev, 2);
+		rdev->rmmio_size = pci_resource_len(rdev->pdev, 2);
+	}
 	rdev->rmmio = ioremap(rdev->rmmio_base, rdev->rmmio_size);
 	if (rdev->rmmio == NULL) {
 		return -ENOMEM;
@@ -1154,6 +1251,10 @@ int radeon_device_init(struct radeon_dev
 	DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
 	DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
 
+	/* doorbell bar mapping */
+	if (rdev->family >= CHIP_BONAIRE)
+		radeon_doorbell_init(rdev);
+
 	/* io port mapping */
 	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
 		if (pci_resource_flags(rdev->pdev, i) & IORESOURCE_IO) {
@@ -1231,6 +1332,8 @@ void radeon_device_fini(struct radeon_de
 	rdev->rio_mem = NULL;
 	iounmap(rdev->rmmio);
 	rdev->rmmio = NULL;
+	if (rdev->family >= CHIP_BONAIRE)
+		radeon_doorbell_fini(rdev);
 	radeon_debugfs_remove_files(rdev);
 }
 
@@ -1417,6 +1520,7 @@ int radeon_gpu_reset(struct radeon_devic
 	radeon_save_bios_scratch_regs(rdev);
 	/* block TTM */
 	resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev);
+	radeon_pm_suspend(rdev);
 	radeon_suspend(rdev);
 
 	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
@@ -1462,6 +1566,7 @@ retry:
 		}
 	}
 
+	radeon_pm_resume(rdev);
 	drm_helper_resume_force_mode(rdev->ddev);
 
 	ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_display.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_display.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_display.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_display.c	2013-08-25 20:43:22.000000000 -0400
@@ -153,7 +153,13 @@ static void dce5_crtc_load_lut(struct dr
 		NI_OUTPUT_CSC_OVL_MODE(NI_OUTPUT_CSC_BYPASS)));
 	/* XXX match this to the depth of the crtc fmt block, move to modeset? */
 	WREG32(0x6940 + radeon_crtc->crtc_offset, 0);
-
+	if (ASIC_IS_DCE8(rdev)) {
+		/* XXX this only needs to be programmed once per crtc at startup,
+		 * not sure where the best place for it is
+		 */
+		WREG32(CIK_ALPHA_CONTROL + radeon_crtc->crtc_offset,
+		       CIK_CURSOR_ALPHA_BLND_ENA);
+	}
 }
 
 static void legacy_crtc_load_lut(struct drm_crtc *crtc)
@@ -512,6 +518,14 @@ static void radeon_crtc_init(struct drm_
 	radeon_crtc->crtc_id = index;
 	rdev->mode_info.crtcs[index] = radeon_crtc;
 
+	if (rdev->family >= CHIP_BONAIRE) {
+		radeon_crtc->max_cursor_width = CIK_CURSOR_WIDTH;
+		radeon_crtc->max_cursor_height = CIK_CURSOR_HEIGHT;
+	} else {
+		radeon_crtc->max_cursor_width = CURSOR_WIDTH;
+		radeon_crtc->max_cursor_height = CURSOR_HEIGHT;
+	}
+
 #if 0
 	radeon_crtc->mode_set.crtc = &radeon_crtc->base;
 	radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);
@@ -530,7 +544,7 @@ static void radeon_crtc_init(struct drm_
 		radeon_legacy_init_crtc(dev, radeon_crtc);
 }
 
-static const char *encoder_names[37] = {
+static const char *encoder_names[38] = {
 	"NONE",
 	"INTERNAL_LVDS",
 	"INTERNAL_TMDS1",
@@ -567,7 +581,8 @@ static const char *encoder_names[37] = {
 	"INTERNAL_UNIPHY2",
 	"NUTMEG",
 	"TRAVIS",
-	"INTERNAL_VCE"
+	"INTERNAL_VCE",
+	"INTERNAL_UNIPHY3",
 };
 
 static const char *hpd_names[6] = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,9 +74,10 @@
  *   2.31.0 - Add fastfb support for rs690
  *   2.32.0 - new info request for rings working
  *   2.33.0 - Add SI tiling mode array query
+ *   2.34.0 - Add CIK tiling mode array query
  */
 #define KMS_DRIVER_MAJOR	2
-#define KMS_DRIVER_MINOR	33
+#define KMS_DRIVER_MINOR	34
 #define KMS_DRIVER_PATCHLEVEL	0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
@@ -127,6 +128,7 @@ struct drm_gem_object *radeon_gem_prime_
 							size_t size,
 							struct sg_table *sg);
 int radeon_gem_prime_pin(struct drm_gem_object *obj);
+void radeon_gem_prime_unpin(struct drm_gem_object *obj);
 void *radeon_gem_prime_vmap(struct drm_gem_object *obj);
 void radeon_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
 extern long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd,
@@ -164,6 +166,8 @@ int radeon_pcie_gen2 = -1;
 int radeon_msi = -1;
 int radeon_lockup_timeout = 10000;
 int radeon_fastfb = 0;
+int radeon_dpm = -1;
+int radeon_aspm = -1;
 
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -219,6 +223,12 @@ module_param_named(lockup_timeout, radeo
 MODULE_PARM_DESC(fastfb, "Direct FB access for IGP chips (0 = disable, 1 = enable)");
 module_param_named(fastfb, radeon_fastfb, int, 0444);
 
+MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)");
+module_param_named(dpm, radeon_dpm, int, 0444);
+
+MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)");
+module_param_named(aspm, radeon_aspm, int, 0444);
+
 static struct pci_device_id pciidlist[] = {
 	radeon_PCI_IDS
 };
@@ -422,6 +432,7 @@ static struct drm_driver kms_driver = {
 	.gem_prime_export = drm_gem_prime_export,
 	.gem_prime_import = drm_gem_prime_import,
 	.gem_prime_pin = radeon_gem_prime_pin,
+	.gem_prime_unpin = radeon_gem_prime_unpin,
 	.gem_prime_get_sg_table = radeon_gem_prime_get_sg_table,
 	.gem_prime_import_sg_table = radeon_gem_prime_import_sg_table,
 	.gem_prime_vmap = radeon_gem_prime_vmap,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_family.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_family.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_family.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_family.h	2013-08-25 20:43:22.000000000 -0400
@@ -93,6 +93,9 @@ enum radeon_family {
 	CHIP_VERDE,
 	CHIP_OLAND,
 	CHIP_HAINAN,
+	CHIP_BONAIRE,
+	CHIP_KAVERI,
+	CHIP_KABINI,
 	CHIP_LAST,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_fb.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_fb.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_fb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_fb.c	2013-08-25 20:43:22.000000000 -0400
@@ -230,7 +230,7 @@ static int radeonfb_create(struct drm_fb
 
 	ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
 	if (ret) {
-		DRM_ERROR("failed to initalise framebuffer %d\n", ret);
+		DRM_ERROR("failed to initialize framebuffer %d\n", ret);
 		goto out_unref;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_gart.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_gart.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_gart.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_gart.c	2013-08-25 20:43:22.000000000 -0400
@@ -207,7 +207,6 @@ void radeon_gart_table_vram_free(struct
 	if (rdev->gart.robj == NULL) {
 		return;
 	}
-	radeon_gart_table_vram_unpin(rdev);
 	radeon_bo_unref(&rdev->gart.robj);
 }
 
@@ -467,6 +466,7 @@ int radeon_vm_manager_init(struct radeon
 		size *= 2;
 		r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
 					      RADEON_GPU_PAGE_ALIGN(size),
+					      RADEON_VM_PTB_ALIGN_SIZE,
 					      RADEON_GEM_DOMAIN_VRAM);
 		if (r) {
 			dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
@@ -620,10 +620,10 @@ int radeon_vm_alloc_pt(struct radeon_dev
 	}
 
 retry:
-	pd_size = RADEON_GPU_PAGE_ALIGN(radeon_vm_directory_size(rdev));
+	pd_size = radeon_vm_directory_size(rdev);
 	r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager,
 			     &vm->page_directory, pd_size,
-			     RADEON_GPU_PAGE_SIZE, false);
+			     RADEON_VM_PTB_ALIGN_SIZE, false);
 	if (r == -ENOMEM) {
 		r = radeon_vm_evict(rdev, vm);
 		if (r)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon.h	2013-08-25 20:43:22.000000000 -0400
@@ -96,6 +96,8 @@ extern int radeon_pcie_gen2;
 extern int radeon_msi;
 extern int radeon_lockup_timeout;
 extern int radeon_fastfb;
+extern int radeon_dpm;
+extern int radeon_aspm;
 
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -150,6 +152,13 @@ extern int radeon_fastfb;
 #define RADEON_RESET_MC				(1 << 10)
 #define RADEON_RESET_DISPLAY			(1 << 11)
 
+/* max cursor sizes (in pixels) */
+#define CURSOR_WIDTH 64
+#define CURSOR_HEIGHT 64
+
+#define CIK_CURSOR_WIDTH 128
+#define CIK_CURSOR_HEIGHT 128
+
 /*
  * Errata workarounds.
  */
@@ -192,6 +201,7 @@ struct radeon_clock {
 	uint32_t default_mclk;
 	uint32_t default_sclk;
 	uint32_t default_dispclk;
+	uint32_t current_dispclk;
 	uint32_t dp_extclk;
 	uint32_t max_pixel_clock;
 };
@@ -211,13 +221,51 @@ int radeon_atom_get_clock_dividers(struc
 				   u32 clock,
 				   bool strobe_mode,
 				   struct atom_clock_dividers *dividers);
+int radeon_atom_get_memory_pll_dividers(struct radeon_device *rdev,
+					u32 clock,
+					bool strobe_mode,
+					struct atom_mpll_param *mpll_param);
 void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type);
+int radeon_atom_get_voltage_gpio_settings(struct radeon_device *rdev,
+					  u16 voltage_level, u8 voltage_type,
+					  u32 *gpio_value, u32 *gpio_mask);
+void radeon_atom_set_engine_dram_timings(struct radeon_device *rdev,
+					 u32 eng_clock, u32 mem_clock);
+int radeon_atom_get_voltage_step(struct radeon_device *rdev,
+				 u8 voltage_type, u16 *voltage_step);
+int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
+			     u16 voltage_id, u16 *voltage);
+int radeon_atom_get_leakage_vddc_based_on_leakage_idx(struct radeon_device *rdev,
+						      u16 *voltage,
+						      u16 leakage_idx);
+int radeon_atom_round_to_true_voltage(struct radeon_device *rdev,
+				      u8 voltage_type,
+				      u16 nominal_voltage,
+				      u16 *true_voltage);
+int radeon_atom_get_min_voltage(struct radeon_device *rdev,
+				u8 voltage_type, u16 *min_voltage);
+int radeon_atom_get_max_voltage(struct radeon_device *rdev,
+				u8 voltage_type, u16 *max_voltage);
+int radeon_atom_get_voltage_table(struct radeon_device *rdev,
+				  u8 voltage_type, u8 voltage_mode,
+				  struct atom_voltage_table *voltage_table);
+bool radeon_atom_is_voltage_gpio(struct radeon_device *rdev,
+				 u8 voltage_type, u8 voltage_mode);
+void radeon_atom_update_memory_dll(struct radeon_device *rdev,
+				   u32 mem_clock);
+void radeon_atom_set_ac_timing(struct radeon_device *rdev,
+			       u32 mem_clock);
+int radeon_atom_init_mc_reg_table(struct radeon_device *rdev,
+				  u8 module_index,
+				  struct atom_mc_reg_table *reg_table);
+int radeon_atom_get_memory_info(struct radeon_device *rdev,
+				u8 module_index, struct atom_memory_info *mem_info);
+int radeon_atom_get_mclk_range_table(struct radeon_device *rdev,
+				     bool gddr5, u8 module_index,
+				     struct atom_memory_clock_range_table *mclk_range_table);
+int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type,
+			     u16 voltage_id, u16 *voltage);
 void rs690_pm_info(struct radeon_device *rdev);
-extern int rv6xx_get_temp(struct radeon_device *rdev);
-extern int rv770_get_temp(struct radeon_device *rdev);
-extern int evergreen_get_temp(struct radeon_device *rdev);
-extern int sumo_get_temp(struct radeon_device *rdev);
-extern int si_get_temp(struct radeon_device *rdev);
 extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
 				    unsigned *bankh, unsigned *mtaspect,
 				    unsigned *tile_split);
@@ -408,6 +456,7 @@ struct radeon_sa_manager {
 	uint64_t		gpu_addr;
 	void			*cpu_ptr;
 	uint32_t		domain;
+	uint32_t		align;
 };
 
 struct radeon_sa_bo;
@@ -549,6 +598,20 @@ struct radeon_scratch {
 int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg);
 void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg);
 
+/*
+ * GPU doorbell structures, functions & helpers
+ */
+struct radeon_doorbell {
+	u32			num_pages;
+	bool			free[1024];
+	/* doorbell mmio */
+	resource_size_t			base;
+	resource_size_t			size;
+	void __iomem			*ptr;
+};
+
+int radeon_doorbell_get(struct radeon_device *rdev, u32 *page);
+void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell);
 
 /*
  * IRQS.
@@ -600,10 +663,21 @@ struct evergreen_irq_stat_regs {
 	u32 afmt_status6;
 };
 
+struct cik_irq_stat_regs {
+	u32 disp_int;
+	u32 disp_int_cont;
+	u32 disp_int_cont2;
+	u32 disp_int_cont3;
+	u32 disp_int_cont4;
+	u32 disp_int_cont5;
+	u32 disp_int_cont6;
+};
+
 union radeon_irq_stat_regs {
 	struct r500_irq_stat_regs r500;
 	struct r600_irq_stat_regs r600;
 	struct evergreen_irq_stat_regs evergreen;
+	struct cik_irq_stat_regs cik;
 };
 
 #define RADEON_MAX_HPD_PINS 6
@@ -620,6 +694,7 @@ struct radeon_irq {
 	bool				hpd[RADEON_MAX_HPD_PINS];
 	bool				afmt[RADEON_MAX_AFMT_BLOCKS];
 	union radeon_irq_stat_regs	stat_regs;
+	bool				dpm_thermal;
 };
 
 int radeon_irq_kms_init(struct radeon_device *rdev);
@@ -677,6 +752,22 @@ struct radeon_ring {
 	u32			idx;
 	u64			last_semaphore_signal_addr;
 	u64			last_semaphore_wait_addr;
+	/* for CIK queues */
+	u32 me;
+	u32 pipe;
+	u32 queue;
+	struct radeon_bo	*mqd_obj;
+	u32 doorbell_page_num;
+	u32 doorbell_offset;
+	unsigned		wptr_offs;
+};
+
+struct radeon_mec {
+	struct radeon_bo	*hpd_eop_obj;
+	u64			hpd_eop_gpu_addr;
+	u32 num_pipe;
+	u32 num_mec;
+	u32 num_queue;
 };
 
 /*
@@ -694,6 +785,11 @@ struct radeon_ring {
 /* number of entries in page table */
 #define RADEON_VM_PTE_COUNT (1 << RADEON_VM_BLOCK_SIZE)
 
+/* PTBs (Page Table Blocks) need to be aligned to 32K */
+#define RADEON_VM_PTB_ALIGN_SIZE   32768
+#define RADEON_VM_PTB_ALIGN_MASK (RADEON_VM_PTB_ALIGN_SIZE - 1)
+#define RADEON_VM_PTB_ALIGN(a) (((a) + RADEON_VM_PTB_ALIGN_MASK) & ~RADEON_VM_PTB_ALIGN_MASK)
+
 struct radeon_vm {
 	struct list_head		list;
 	struct list_head		va;
@@ -778,15 +874,22 @@ struct r600_blit {
 };
 
 /*
- * SI RLC stuff
+ * RLC stuff
  */
-struct si_rlc {
+#include "clearstate_defs.h"
+
+struct radeon_rlc {
 	/* for power gating */
 	struct radeon_bo	*save_restore_obj;
 	uint64_t		save_restore_gpu_addr;
+	volatile uint32_t	*sr_ptr;
+	u32                     *reg_list;
+	u32                     reg_list_size;
 	/* for clear state */
 	struct radeon_bo	*clear_state_obj;
 	uint64_t		clear_state_gpu_addr;
+	volatile uint32_t	*cs_ptr;
+	struct cs_section_def   *cs_data;
 };
 
 int radeon_ib_get(struct radeon_device *rdev, int ring,
@@ -883,6 +986,7 @@ struct radeon_cs_parser {
 	u32			cs_flags;
 	u32			ring;
 	s32			priority;
+	struct ww_acquire_ctx	ticket;
 };
 
 extern int radeon_cs_finish_pages(struct radeon_cs_parser *p);
@@ -934,6 +1038,8 @@ struct radeon_wb {
 #define CAYMAN_WB_DMA1_RPTR_OFFSET   2304
 #define R600_WB_UVD_RPTR_OFFSET  2560
 #define R600_WB_EVENT_OFFSET     3072
+#define CIK_WB_CP1_WPTR_OFFSET     3328
+#define CIK_WB_CP2_WPTR_OFFSET     3584
 
 /**
  * struct radeon_pm - power management datas
@@ -958,6 +1064,7 @@ struct radeon_wb {
 enum radeon_pm_method {
 	PM_METHOD_PROFILE,
 	PM_METHOD_DYNPM,
+	PM_METHOD_DPM,
 };
 
 enum radeon_dynpm_state {
@@ -983,11 +1090,24 @@ enum radeon_voltage_type {
 };
 
 enum radeon_pm_state_type {
+	/* not used for dpm */
 	POWER_STATE_TYPE_DEFAULT,
 	POWER_STATE_TYPE_POWERSAVE,
+	/* user selectable states */
 	POWER_STATE_TYPE_BATTERY,
 	POWER_STATE_TYPE_BALANCED,
 	POWER_STATE_TYPE_PERFORMANCE,
+	/* internal states */
+	POWER_STATE_TYPE_INTERNAL_UVD,
+	POWER_STATE_TYPE_INTERNAL_UVD_SD,
+	POWER_STATE_TYPE_INTERNAL_UVD_HD,
+	POWER_STATE_TYPE_INTERNAL_UVD_HD2,
+	POWER_STATE_TYPE_INTERNAL_UVD_MVC,
+	POWER_STATE_TYPE_INTERNAL_BOOT,
+	POWER_STATE_TYPE_INTERNAL_THERMAL,
+	POWER_STATE_TYPE_INTERNAL_ACPI,
+	POWER_STATE_TYPE_INTERNAL_ULV,
+	POWER_STATE_TYPE_INTERNAL_3DPERF,
 };
 
 enum radeon_pm_profile_type {
@@ -1016,12 +1136,17 @@ struct radeon_pm_profile {
 
 enum radeon_int_thermal_type {
 	THERMAL_TYPE_NONE,
+	THERMAL_TYPE_EXTERNAL,
+	THERMAL_TYPE_EXTERNAL_GPIO,
 	THERMAL_TYPE_RV6XX,
 	THERMAL_TYPE_RV770,
+	THERMAL_TYPE_ADT7473_WITH_INTERNAL,
 	THERMAL_TYPE_EVERGREEN,
 	THERMAL_TYPE_SUMO,
 	THERMAL_TYPE_NI,
 	THERMAL_TYPE_SI,
+	THERMAL_TYPE_EMC2103_WITH_INTERNAL,
+	THERMAL_TYPE_CI,
 };
 
 struct radeon_voltage {
@@ -1075,6 +1200,201 @@ struct radeon_power_state {
  */
 #define RADEON_MODE_OVERCLOCK_MARGIN 500 /* 5 MHz */
 
+enum radeon_dpm_auto_throttle_src {
+	RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL,
+	RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL
+};
+
+enum radeon_dpm_event_src {
+	RADEON_DPM_EVENT_SRC_ANALOG = 0,
+	RADEON_DPM_EVENT_SRC_EXTERNAL = 1,
+	RADEON_DPM_EVENT_SRC_DIGITAL = 2,
+	RADEON_DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3,
+	RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4
+};
+
+struct radeon_ps {
+	u32 caps; /* vbios flags */
+	u32 class; /* vbios flags */
+	u32 class2; /* vbios flags */
+	/* UVD clocks */
+	u32 vclk;
+	u32 dclk;
+	/* asic priv */
+	void *ps_priv;
+};
+
+struct radeon_dpm_thermal {
+	/* thermal interrupt work */
+	struct work_struct work;
+	/* low temperature threshold */
+	int                min_temp;
+	/* high temperature threshold */
+	int                max_temp;
+	/* was interrupt low to high or high to low */
+	bool               high_to_low;
+};
+
+enum radeon_clk_action
+{
+	RADEON_SCLK_UP = 1,
+	RADEON_SCLK_DOWN
+};
+
+struct radeon_blacklist_clocks
+{
+	u32 sclk;
+	u32 mclk;
+	enum radeon_clk_action action;
+};
+
+struct radeon_clock_and_voltage_limits {
+	u32 sclk;
+	u32 mclk;
+	u32 vddc;
+	u32 vddci;
+};
+
+struct radeon_clock_array {
+	u32 count;
+	u32 *values;
+};
+
+struct radeon_clock_voltage_dependency_entry {
+	u32 clk;
+	u16 v;
+};
+
+struct radeon_clock_voltage_dependency_table {
+	u32 count;
+	struct radeon_clock_voltage_dependency_entry *entries;
+};
+
+struct radeon_cac_leakage_entry {
+	u16 vddc;
+	u32 leakage;
+};
+
+struct radeon_cac_leakage_table {
+	u32 count;
+	struct radeon_cac_leakage_entry *entries;
+};
+
+struct radeon_phase_shedding_limits_entry {
+	u16 voltage;
+	u32 sclk;
+	u32 mclk;
+};
+
+struct radeon_phase_shedding_limits_table {
+	u32 count;
+	struct radeon_phase_shedding_limits_entry *entries;
+};
+
+struct radeon_ppm_table {
+	u8 ppm_design;
+	u16 cpu_core_number;
+	u32 platform_tdp;
+	u32 small_ac_platform_tdp;
+	u32 platform_tdc;
+	u32 small_ac_platform_tdc;
+	u32 apu_tdp;
+	u32 dgpu_tdp;
+	u32 dgpu_ulv_power;
+	u32 tj_max;
+};
+
+struct radeon_dpm_dynamic_state {
+	struct radeon_clock_voltage_dependency_table vddc_dependency_on_sclk;
+	struct radeon_clock_voltage_dependency_table vddci_dependency_on_mclk;
+	struct radeon_clock_voltage_dependency_table vddc_dependency_on_mclk;
+	struct radeon_clock_voltage_dependency_table vddc_dependency_on_dispclk;
+	struct radeon_clock_array valid_sclk_values;
+	struct radeon_clock_array valid_mclk_values;
+	struct radeon_clock_and_voltage_limits max_clock_voltage_on_dc;
+	struct radeon_clock_and_voltage_limits max_clock_voltage_on_ac;
+	u32 mclk_sclk_ratio;
+	u32 sclk_mclk_delta;
+	u16 vddc_vddci_delta;
+	u16 min_vddc_for_pcie_gen2;
+	struct radeon_cac_leakage_table cac_leakage_table;
+	struct radeon_phase_shedding_limits_table phase_shedding_limits_table;
+	struct radeon_ppm_table *ppm_table;
+};
+
+struct radeon_dpm_fan {
+	u16 t_min;
+	u16 t_med;
+	u16 t_high;
+	u16 pwm_min;
+	u16 pwm_med;
+	u16 pwm_high;
+	u8 t_hyst;
+	u32 cycle_delay;
+	u16 t_max;
+	bool ucode_fan_control;
+};
+
+enum radeon_pcie_gen {
+	RADEON_PCIE_GEN1 = 0,
+	RADEON_PCIE_GEN2 = 1,
+	RADEON_PCIE_GEN3 = 2,
+	RADEON_PCIE_GEN_INVALID = 0xffff
+};
+
+enum radeon_dpm_forced_level {
+	RADEON_DPM_FORCED_LEVEL_AUTO = 0,
+	RADEON_DPM_FORCED_LEVEL_LOW = 1,
+	RADEON_DPM_FORCED_LEVEL_HIGH = 2,
+};
+
+struct radeon_dpm {
+	struct radeon_ps        *ps;
+	/* number of valid power states */
+	int                     num_ps;
+	/* current power state that is active */
+	struct radeon_ps        *current_ps;
+	/* requested power state */
+	struct radeon_ps        *requested_ps;
+	/* boot up power state */
+	struct radeon_ps        *boot_ps;
+	/* default uvd power state */
+	struct radeon_ps        *uvd_ps;
+	enum radeon_pm_state_type state;
+	enum radeon_pm_state_type user_state;
+	u32                     platform_caps;
+	u32                     voltage_response_time;
+	u32                     backbias_response_time;
+	void                    *priv;
+	u32			new_active_crtcs;
+	int			new_active_crtc_count;
+	u32			current_active_crtcs;
+	int			current_active_crtc_count;
+	struct radeon_dpm_dynamic_state dyn_state;
+	struct radeon_dpm_fan fan;
+	u32 tdp_limit;
+	u32 near_tdp_limit;
+	u32 near_tdp_limit_adjusted;
+	u32 sq_ramping_threshold;
+	u32 cac_leakage;
+	u16 tdp_od_limit;
+	u32 tdp_adjustment;
+	u16 load_line_slope;
+	bool power_control;
+	bool ac_power;
+	/* special states active */
+	bool                    thermal_active;
+	bool                    uvd_active;
+	/* thermal handling */
+	struct radeon_dpm_thermal thermal;
+	/* forced levels */
+	enum radeon_dpm_forced_level forced_level;
+};
+
+void radeon_dpm_enable_power_state(struct radeon_device *rdev,
+				    enum radeon_pm_state_type dpm_state);
+
+
 struct radeon_pm {
 	struct mutex		mutex;
 	/* write locked while reprogramming mclk */
@@ -1128,6 +1448,9 @@ struct radeon_pm {
 	/* internal thermal controller on rv6xx+ */
 	enum radeon_int_thermal_type int_thermal_type;
 	struct device	        *int_hwmon_dev;
+	/* dpm */
+	bool                    dpm_enabled;
+	struct radeon_dpm       dpm;
 };
 
 int radeon_pm_get_type_index(struct radeon_device *rdev,
@@ -1144,6 +1467,7 @@ struct radeon_uvd {
 	struct radeon_bo	*vcpu_bo;
 	void			*cpu_addr;
 	uint64_t		gpu_addr;
+	void			*saved_bo;
 	atomic_t		handles[RADEON_MAX_UVD_HANDLES];
 	struct drm_file		*filp[RADEON_MAX_UVD_HANDLES];
 	struct delayed_work	idle_work;
@@ -1266,6 +1590,10 @@ struct radeon_asic {
 		int (*ib_test)(struct radeon_device *rdev, struct radeon_ring *cp);
 		bool (*is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp);
 		void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
+
+		u32 (*get_rptr)(struct radeon_device *rdev, struct radeon_ring *ring);
+		u32 (*get_wptr)(struct radeon_device *rdev, struct radeon_ring *ring);
+		void (*set_wptr)(struct radeon_device *rdev, struct radeon_ring *ring);
 	} ring[RADEON_NUM_RINGS];
 	/* irqs */
 	struct {
@@ -1325,7 +1653,7 @@ struct radeon_asic {
 		bool (*sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
 		void (*set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd);
 	} hpd;
-	/* power management */
+	/* static power management */
 	struct {
 		void (*misc)(struct radeon_device *rdev);
 		void (*prepare)(struct radeon_device *rdev);
@@ -1340,7 +1668,26 @@ struct radeon_asic {
 		void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes);
 		void (*set_clock_gating)(struct radeon_device *rdev, int enable);
 		int (*set_uvd_clocks)(struct radeon_device *rdev, u32 vclk, u32 dclk);
+		int (*get_temperature)(struct radeon_device *rdev);
 	} pm;
+	/* dynamic power management */
+	struct {
+		int (*init)(struct radeon_device *rdev);
+		void (*setup_asic)(struct radeon_device *rdev);
+		int (*enable)(struct radeon_device *rdev);
+		void (*disable)(struct radeon_device *rdev);
+		int (*pre_set_power_state)(struct radeon_device *rdev);
+		int (*set_power_state)(struct radeon_device *rdev);
+		void (*post_set_power_state)(struct radeon_device *rdev);
+		void (*display_configuration_changed)(struct radeon_device *rdev);
+		void (*fini)(struct radeon_device *rdev);
+		u32 (*get_sclk)(struct radeon_device *rdev, bool low);
+		u32 (*get_mclk)(struct radeon_device *rdev, bool low);
+		void (*print_power_state)(struct radeon_device *rdev, struct radeon_ps *ps);
+		void (*debugfs_print_current_performance_level)(struct radeon_device *rdev, struct seq_file *m);
+		int (*force_performance_level)(struct radeon_device *rdev, enum radeon_dpm_forced_level level);
+		bool (*vblank_too_short)(struct radeon_device *rdev);
+	} dpm;
 	/* pageflipping */
 	struct {
 		void (*pre_page_flip)(struct radeon_device *rdev, int crtc);
@@ -1505,6 +1852,36 @@ struct si_asic {
 	uint32_t tile_mode_array[32];
 };
 
+struct cik_asic {
+	unsigned max_shader_engines;
+	unsigned max_tile_pipes;
+	unsigned max_cu_per_sh;
+	unsigned max_sh_per_se;
+	unsigned max_backends_per_se;
+	unsigned max_texture_channel_caches;
+	unsigned max_gprs;
+	unsigned max_gs_threads;
+	unsigned max_hw_contexts;
+	unsigned sc_prim_fifo_size_frontend;
+	unsigned sc_prim_fifo_size_backend;
+	unsigned sc_hiz_tile_fifo_size;
+	unsigned sc_earlyz_tile_fifo_size;
+
+	unsigned num_tile_pipes;
+	unsigned num_backends_per_se;
+	unsigned backend_disable_mask_per_asic;
+	unsigned backend_map;
+	unsigned num_texture_channel_caches;
+	unsigned mem_max_burst_length_bytes;
+	unsigned mem_row_size_in_kb;
+	unsigned shader_engine_tile_size;
+	unsigned num_gpus;
+	unsigned multi_gpu_tile_size;
+
+	unsigned tile_config;
+	uint32_t tile_mode_array[32];
+};
+
 union radeon_asic_config {
 	struct r300_asic	r300;
 	struct r100_asic	r100;
@@ -1513,6 +1890,7 @@ union radeon_asic_config {
 	struct evergreen_asic	evergreen;
 	struct cayman_asic	cayman;
 	struct si_asic		si;
+	struct cik_asic		cik;
 };
 
 /*
@@ -1657,6 +2035,7 @@ struct radeon_device {
 	struct radeon_gart		gart;
 	struct radeon_mode_info		mode_info;
 	struct radeon_scratch		scratch;
+	struct radeon_doorbell		doorbell;
 	struct radeon_mman		mman;
 	struct radeon_fence_driver	fence_drv[RADEON_NUM_RINGS];
 	wait_queue_head_t		fence_queue;
@@ -1683,14 +2062,19 @@ struct radeon_device {
 	const struct firmware *rlc_fw;	/* r6/700 RLC firmware */
 	const struct firmware *mc_fw;	/* NI MC firmware */
 	const struct firmware *ce_fw;	/* SI CE firmware */
+	const struct firmware *mec_fw;	/* CIK MEC firmware */
+	const struct firmware *sdma_fw;	/* CIK SDMA firmware */
+	const struct firmware *smc_fw;	/* SMC firmware */
 	const struct firmware *uvd_fw;	/* UVD firmware */
 	struct r600_blit r600_blit;
 	struct r600_vram_scratch vram_scratch;
 	int msi_enabled; /* msi enabled */
 	struct r600_ih ih; /* r6/700 interrupt ring */
-	struct si_rlc rlc;
+	struct radeon_rlc rlc;
+	struct radeon_mec mec;
 	struct work_struct hotplug_work;
 	struct work_struct audio_work;
+	struct work_struct reset_work;
 	int num_crtc; /* number of crtcs */
 	struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */
 	bool audio_enabled;
@@ -1711,6 +2095,8 @@ struct radeon_device {
 	/* ACPI interface */
 	struct radeon_atif		atif;
 	struct radeon_atcs		atcs;
+	/* srbm instance registers */
+	struct mutex			srbm_mutex;
 };
 
 int radeon_device_init(struct radeon_device *rdev,
@@ -1727,6 +2113,9 @@ void r100_mm_wreg(struct radeon_device *
 u32 r100_io_rreg(struct radeon_device *rdev, u32 reg);
 void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v);
 
+u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 offset);
+void cik_mm_wdoorbell(struct radeon_device *rdev, u32 offset, u32 v);
+
 /*
  * Cast helper
  */
@@ -1754,6 +2143,18 @@ void r100_io_wreg(struct radeon_device *
 #define WREG32_PCIE(reg, v) rv370_pcie_wreg(rdev, (reg), (v))
 #define RREG32_PCIE_PORT(reg) rdev->pciep_rreg(rdev, (reg))
 #define WREG32_PCIE_PORT(reg, v) rdev->pciep_wreg(rdev, (reg), (v))
+#define RREG32_SMC(reg) tn_smc_rreg(rdev, (reg))
+#define WREG32_SMC(reg, v) tn_smc_wreg(rdev, (reg), (v))
+#define RREG32_RCU(reg) r600_rcu_rreg(rdev, (reg))
+#define WREG32_RCU(reg, v) r600_rcu_wreg(rdev, (reg), (v))
+#define RREG32_CG(reg) eg_cg_rreg(rdev, (reg))
+#define WREG32_CG(reg, v) eg_cg_wreg(rdev, (reg), (v))
+#define RREG32_PIF_PHY0(reg) eg_pif_phy0_rreg(rdev, (reg))
+#define WREG32_PIF_PHY0(reg, v) eg_pif_phy0_wreg(rdev, (reg), (v))
+#define RREG32_PIF_PHY1(reg) eg_pif_phy1_rreg(rdev, (reg))
+#define WREG32_PIF_PHY1(reg, v) eg_pif_phy1_wreg(rdev, (reg), (v))
+#define RREG32_UVD_CTX(reg) r600_uvd_ctx_rreg(rdev, (reg))
+#define WREG32_UVD_CTX(reg, v) r600_uvd_ctx_wreg(rdev, (reg), (v))
 #define WREG32_P(reg, val, mask)				\
 	do {							\
 		uint32_t tmp_ = RREG32(reg);			\
@@ -1762,7 +2163,7 @@ void r100_io_wreg(struct radeon_device *
 		WREG32(reg, tmp_);				\
 	} while (0)
 #define WREG32_AND(reg, and) WREG32_P(reg, 0, and)
-#define WREG32_OR(reg, or) WREG32_P(reg, or, ~or)
+#define WREG32_OR(reg, or) WREG32_P(reg, or, ~(or))
 #define WREG32_PLL_P(reg, val, mask)				\
 	do {							\
 		uint32_t tmp_ = RREG32_PLL(reg);		\
@@ -1774,6 +2175,9 @@ void r100_io_wreg(struct radeon_device *
 #define RREG32_IO(reg) r100_io_rreg(rdev, (reg))
 #define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v))
 
+#define RDOORBELL32(offset) cik_mm_rdoorbell(rdev, (offset))
+#define WDOORBELL32(offset, v) cik_mm_wdoorbell(rdev, (offset), (v))
+
 /*
  * Indirect registers accessor
  */
@@ -1792,6 +2196,96 @@ static inline void rv370_pcie_wreg(struc
 	WREG32(RADEON_PCIE_DATA, (v));
 }
 
+static inline u32 tn_smc_rreg(struct radeon_device *rdev, u32 reg)
+{
+	u32 r;
+
+	WREG32(TN_SMC_IND_INDEX_0, (reg));
+	r = RREG32(TN_SMC_IND_DATA_0);
+	return r;
+}
+
+static inline void tn_smc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+	WREG32(TN_SMC_IND_INDEX_0, (reg));
+	WREG32(TN_SMC_IND_DATA_0, (v));
+}
+
+static inline u32 r600_rcu_rreg(struct radeon_device *rdev, u32 reg)
+{
+	u32 r;
+
+	WREG32(R600_RCU_INDEX, ((reg) & 0x1fff));
+	r = RREG32(R600_RCU_DATA);
+	return r;
+}
+
+static inline void r600_rcu_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+	WREG32(R600_RCU_INDEX, ((reg) & 0x1fff));
+	WREG32(R600_RCU_DATA, (v));
+}
+
+static inline u32 eg_cg_rreg(struct radeon_device *rdev, u32 reg)
+{
+	u32 r;
+
+	WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0xffff));
+	r = RREG32(EVERGREEN_CG_IND_DATA);
+	return r;
+}
+
+static inline void eg_cg_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+	WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0xffff));
+	WREG32(EVERGREEN_CG_IND_DATA, (v));
+}
+
+static inline u32 eg_pif_phy0_rreg(struct radeon_device *rdev, u32 reg)
+{
+	u32 r;
+
+	WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
+	r = RREG32(EVERGREEN_PIF_PHY0_DATA);
+	return r;
+}
+
+static inline void eg_pif_phy0_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+	WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
+	WREG32(EVERGREEN_PIF_PHY0_DATA, (v));
+}
+
+static inline u32 eg_pif_phy1_rreg(struct radeon_device *rdev, u32 reg)
+{
+	u32 r;
+
+	WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
+	r = RREG32(EVERGREEN_PIF_PHY1_DATA);
+	return r;
+}
+
+static inline void eg_pif_phy1_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+	WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
+	WREG32(EVERGREEN_PIF_PHY1_DATA, (v));
+}
+
+static inline u32 r600_uvd_ctx_rreg(struct radeon_device *rdev, u32 reg)
+{
+	u32 r;
+
+	WREG32(R600_UVD_CTX_INDEX, ((reg) & 0x1ff));
+	r = RREG32(R600_UVD_CTX_DATA);
+	return r;
+}
+
+static inline void r600_uvd_ctx_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+	WREG32(R600_UVD_CTX_INDEX, ((reg) & 0x1ff));
+	WREG32(R600_UVD_CTX_DATA, (v));
+}
+
 void r100_pll_errata_after_index(struct radeon_device *rdev);
 
 
@@ -1840,6 +2334,16 @@ void r100_pll_errata_after_index(struct
 			     (rdev->flags & RADEON_IS_IGP))
 #define ASIC_IS_DCE64(rdev) ((rdev->family == CHIP_OLAND))
 #define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN))
+#define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE))
+
+#define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \
+			      (rdev->ddev->pdev->device == 0x6850) || \
+			      (rdev->ddev->pdev->device == 0x6858) || \
+			      (rdev->ddev->pdev->device == 0x6859) || \
+			      (rdev->ddev->pdev->device == 0x6840) || \
+			      (rdev->ddev->pdev->device == 0x6841) || \
+			      (rdev->ddev->pdev->device == 0x6842) || \
+			      (rdev->ddev->pdev->device == 0x6843))
 
 /*
  * BIOS helpers.
@@ -1892,6 +2396,9 @@ void radeon_ring_write(struct radeon_rin
 #define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib))
 #define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)].is_lockup((rdev), (cp))
 #define radeon_ring_vm_flush(rdev, r, vm) (rdev)->asic->ring[(r)].vm_flush((rdev), (r), (vm))
+#define radeon_ring_get_rptr(rdev, r) (rdev)->asic->ring[(r)->idx].get_rptr((rdev), (r))
+#define radeon_ring_get_wptr(rdev, r) (rdev)->asic->ring[(r)->idx].get_wptr((rdev), (r))
+#define radeon_ring_set_wptr(rdev, r) (rdev)->asic->ring[(r)->idx].set_wptr((rdev), (r))
 #define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev))
 #define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev))
 #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->display.get_vblank_counter((rdev), (crtc))
@@ -1915,6 +2422,7 @@ void radeon_ring_write(struct radeon_rin
 #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->pm.set_pcie_lanes((rdev), (l))
 #define radeon_set_clock_gating(rdev, e) (rdev)->asic->pm.set_clock_gating((rdev), (e))
 #define radeon_set_uvd_clocks(rdev, v, d) (rdev)->asic->pm.set_uvd_clocks((rdev), (v), (d))
+#define radeon_get_temperature(rdev) (rdev)->asic->pm.get_temperature((rdev))
 #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->surface.set_reg((rdev), (r), (f), (p), (o), (s)))
 #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->surface.clear_reg((rdev), (r)))
 #define radeon_bandwidth_update(rdev) (rdev)->asic->display.bandwidth_update((rdev))
@@ -1935,6 +2443,21 @@ void radeon_ring_write(struct radeon_rin
 #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev))
 #define radeon_get_xclk(rdev) (rdev)->asic->get_xclk((rdev))
 #define radeon_get_gpu_clock_counter(rdev) (rdev)->asic->get_gpu_clock_counter((rdev))
+#define radeon_dpm_init(rdev) rdev->asic->dpm.init((rdev))
+#define radeon_dpm_setup_asic(rdev) rdev->asic->dpm.setup_asic((rdev))
+#define radeon_dpm_enable(rdev) rdev->asic->dpm.enable((rdev))
+#define radeon_dpm_disable(rdev) rdev->asic->dpm.disable((rdev))
+#define radeon_dpm_pre_set_power_state(rdev) rdev->asic->dpm.pre_set_power_state((rdev))
+#define radeon_dpm_set_power_state(rdev) rdev->asic->dpm.set_power_state((rdev))
+#define radeon_dpm_post_set_power_state(rdev) rdev->asic->dpm.post_set_power_state((rdev))
+#define radeon_dpm_display_configuration_changed(rdev) rdev->asic->dpm.display_configuration_changed((rdev))
+#define radeon_dpm_fini(rdev) rdev->asic->dpm.fini((rdev))
+#define radeon_dpm_get_sclk(rdev, l) rdev->asic->dpm.get_sclk((rdev), (l))
+#define radeon_dpm_get_mclk(rdev, l) rdev->asic->dpm.get_mclk((rdev), (l))
+#define radeon_dpm_print_power_state(rdev, ps) rdev->asic->dpm.print_power_state((rdev), (ps))
+#define radeon_dpm_debugfs_print_current_performance_level(rdev, m) rdev->asic->dpm.debugfs_print_current_performance_level((rdev), (m))
+#define radeon_dpm_force_performance_level(rdev, l) rdev->asic->dpm.force_performance_level((rdev), (l))
+#define radeon_dpm_vblank_too_short(rdev) rdev->asic->dpm.vblank_too_short((rdev))
 
 /* Common functions */
 /* AGP */
@@ -2054,6 +2577,10 @@ extern int ni_mc_load_microcode(struct r
 #if defined(CONFIG_ACPI)
 extern int radeon_acpi_init(struct radeon_device *rdev);
 extern void radeon_acpi_fini(struct radeon_device *rdev);
+extern bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev);
+extern int radeon_acpi_pcie_performance_request(struct radeon_device *rdev,
+						u8 perf_req, bool advertise);
+extern int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev);
 #else
 static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; }
 static inline void radeon_acpi_fini(struct radeon_device *rdev) { }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_irq_kms.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_irq_kms.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_irq_kms.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_irq_kms.c	2013-08-25 20:43:22.000000000 -0400
@@ -82,6 +82,23 @@ static void radeon_hotplug_work_func(str
 }
 
 /**
+ * radeon_irq_reset_work_func - execute gpu reset
+ *
+ * @work: work struct
+ *
+ * Execute scheduled gpu reset (cayman+).
+ * This function is called when the irq handler
+ * thinks we need a gpu reset.
+ */
+static void radeon_irq_reset_work_func(struct work_struct *work)
+{
+	struct radeon_device *rdev = container_of(work, struct radeon_device,
+						  reset_work);
+
+	radeon_gpu_reset(rdev);
+}
+
+/**
  * radeon_driver_irq_preinstall_kms - drm irq preinstall callback
  *
  * @dev: drm dev pointer
@@ -99,6 +116,7 @@ void radeon_driver_irq_preinstall_kms(st
 	/* Disable *all* interrupts */
 	for (i = 0; i < RADEON_NUM_RINGS; i++)
 		atomic_set(&rdev->irq.ring_int[i], 0);
+	rdev->irq.dpm_thermal = false;
 	for (i = 0; i < RADEON_MAX_HPD_PINS; i++)
 		rdev->irq.hpd[i] = false;
 	for (i = 0; i < RADEON_MAX_CRTCS; i++) {
@@ -146,6 +164,7 @@ void radeon_driver_irq_uninstall_kms(str
 	/* Disable *all* interrupts */
 	for (i = 0; i < RADEON_NUM_RINGS; i++)
 		atomic_set(&rdev->irq.ring_int[i], 0);
+	rdev->irq.dpm_thermal = false;
 	for (i = 0; i < RADEON_MAX_HPD_PINS; i++)
 		rdev->irq.hpd[i] = false;
 	for (i = 0; i < RADEON_MAX_CRTCS; i++) {
@@ -241,9 +260,6 @@ int radeon_irq_kms_init(struct radeon_de
 {
 	int r = 0;
 
-	INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
-	INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
-
 	spin_lock_init(&rdev->irq.lock);
 	r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
 	if (r) {
@@ -265,6 +281,11 @@ int radeon_irq_kms_init(struct radeon_de
 		rdev->irq.installed = false;
 		return r;
 	}
+
+	INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
+	INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
+	INIT_WORK(&rdev->reset_work, radeon_irq_reset_work_func);
+
 	DRM_INFO("radeon: irq initialized.\n");
 	return 0;
 }
@@ -284,8 +305,8 @@ void radeon_irq_kms_fini(struct radeon_d
 		rdev->irq.installed = false;
 		if (rdev->msi_enabled)
 			pci_disable_msi(rdev->pdev);
+		flush_work(&rdev->hotplug_work);
 	}
-	flush_work(&rdev->hotplug_work);
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_kms.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_kms.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_kms.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_kms.c	2013-08-25 20:43:22.000000000 -0400
@@ -229,7 +229,9 @@ int radeon_info_ioctl(struct drm_device
 		*value = rdev->accel_working;
 		break;
 	case RADEON_INFO_TILING_CONFIG:
-		if (rdev->family >= CHIP_TAHITI)
+		if (rdev->family >= CHIP_BONAIRE)
+			*value = rdev->config.cik.tile_config;
+		else if (rdev->family >= CHIP_TAHITI)
 			*value = rdev->config.si.tile_config;
 		else if (rdev->family >= CHIP_CAYMAN)
 			*value = rdev->config.cayman.tile_config;
@@ -281,7 +283,10 @@ int radeon_info_ioctl(struct drm_device
 			*value = rdev->clock.spll.reference_freq * 10;
 		break;
 	case RADEON_INFO_NUM_BACKENDS:
-		if (rdev->family >= CHIP_TAHITI)
+		if (rdev->family >= CHIP_BONAIRE)
+			*value = rdev->config.cik.max_backends_per_se *
+				rdev->config.cik.max_shader_engines;
+		else if (rdev->family >= CHIP_TAHITI)
 			*value = rdev->config.si.max_backends_per_se *
 				rdev->config.si.max_shader_engines;
 		else if (rdev->family >= CHIP_CAYMAN)
@@ -298,7 +303,9 @@ int radeon_info_ioctl(struct drm_device
 		}
 		break;
 	case RADEON_INFO_NUM_TILE_PIPES:
-		if (rdev->family >= CHIP_TAHITI)
+		if (rdev->family >= CHIP_BONAIRE)
+			*value = rdev->config.cik.max_tile_pipes;
+		else if (rdev->family >= CHIP_TAHITI)
 			*value = rdev->config.si.max_tile_pipes;
 		else if (rdev->family >= CHIP_CAYMAN)
 			*value = rdev->config.cayman.max_tile_pipes;
@@ -316,7 +323,9 @@ int radeon_info_ioctl(struct drm_device
 		*value = 1;
 		break;
 	case RADEON_INFO_BACKEND_MAP:
-		if (rdev->family >= CHIP_TAHITI)
+		if (rdev->family >= CHIP_BONAIRE)
+			return -EINVAL;
+		else if (rdev->family >= CHIP_TAHITI)
 			*value = rdev->config.si.backend_map;
 		else if (rdev->family >= CHIP_CAYMAN)
 			*value = rdev->config.cayman.backend_map;
@@ -343,7 +352,9 @@ int radeon_info_ioctl(struct drm_device
 		*value = RADEON_IB_VM_MAX_SIZE;
 		break;
 	case RADEON_INFO_MAX_PIPES:
-		if (rdev->family >= CHIP_TAHITI)
+		if (rdev->family >= CHIP_BONAIRE)
+			*value = rdev->config.cik.max_cu_per_sh;
+		else if (rdev->family >= CHIP_TAHITI)
 			*value = rdev->config.si.max_cu_per_sh;
 		else if (rdev->family >= CHIP_CAYMAN)
 			*value = rdev->config.cayman.max_pipes_per_simd;
@@ -367,7 +378,9 @@ int radeon_info_ioctl(struct drm_device
 		value64 = radeon_get_gpu_clock_counter(rdev);
 		break;
 	case RADEON_INFO_MAX_SE:
-		if (rdev->family >= CHIP_TAHITI)
+		if (rdev->family >= CHIP_BONAIRE)
+			*value = rdev->config.cik.max_shader_engines;
+		else if (rdev->family >= CHIP_TAHITI)
 			*value = rdev->config.si.max_shader_engines;
 		else if (rdev->family >= CHIP_CAYMAN)
 			*value = rdev->config.cayman.max_shader_engines;
@@ -377,7 +390,9 @@ int radeon_info_ioctl(struct drm_device
 			*value = 1;
 		break;
 	case RADEON_INFO_MAX_SH_PER_SE:
-		if (rdev->family >= CHIP_TAHITI)
+		if (rdev->family >= CHIP_BONAIRE)
+			*value = rdev->config.cik.max_sh_per_se;
+		else if (rdev->family >= CHIP_TAHITI)
 			*value = rdev->config.si.max_sh_per_se;
 		else
 			return -EINVAL;
@@ -407,12 +422,16 @@ int radeon_info_ioctl(struct drm_device
 		}
 		break;
 	case RADEON_INFO_SI_TILE_MODE_ARRAY:
-		if (rdev->family < CHIP_TAHITI) {
-			DRM_DEBUG_KMS("tile mode array is si only!\n");
+		if (rdev->family >= CHIP_BONAIRE) {
+			value = rdev->config.cik.tile_mode_array;
+			value_size = sizeof(uint32_t)*32;
+		} else if (rdev->family >= CHIP_TAHITI) {
+			value = rdev->config.si.tile_mode_array;
+			value_size = sizeof(uint32_t)*32;
+		} else {
+			DRM_DEBUG_KMS("tile mode array is si+ only!\n");
 			return -EINVAL;
 		}
-		value = rdev->config.si.tile_mode_array;
-		value_size = sizeof(uint32_t)*32;
 		break;
 	default:
 		DRM_DEBUG_KMS("Invalid request %d\n", info->request);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_mode.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_mode.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_mode.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_mode.h	2013-08-25 20:43:22.000000000 -0400
@@ -307,6 +307,8 @@ struct radeon_crtc {
 	uint64_t cursor_addr;
 	int cursor_width;
 	int cursor_height;
+	int max_cursor_width;
+	int max_cursor_height;
 	uint32_t legacy_display_base_addr;
 	uint32_t legacy_cursor_offset;
 	enum radeon_rmx_type rmx_type;
@@ -329,6 +331,11 @@ struct radeon_crtc {
 	u32 pll_flags;
 	struct drm_encoder *encoder;
 	struct drm_connector *connector;
+	/* for dpm */
+	u32 line_time;
+	u32 wm_low;
+	u32 wm_high;
+	struct drm_display_mode hw_mode;
 };
 
 struct radeon_encoder_primary_dac {
@@ -512,12 +519,99 @@ struct atom_clock_dividers {
 	bool enable_dithen;
 	u32 vco_mode;
 	u32 real_clock;
+	/* added for CI */
+	u32 post_divider;
+	u32 flags;
+};
+
+struct atom_mpll_param {
+	union {
+		struct {
+#ifdef __BIG_ENDIAN
+			u32 reserved : 8;
+			u32 clkfrac : 12;
+			u32 clkf : 12;
+#else
+			u32 clkf : 12;
+			u32 clkfrac : 12;
+			u32 reserved : 8;
+#endif
+		};
+		u32 fb_div;
+	};
+	u32 post_div;
+	u32 bwcntl;
+	u32 dll_speed;
+	u32 vco_mode;
+	u32 yclk_sel;
+	u32 qdr;
+	u32 half_rate;
+};
+
+#define MEM_TYPE_GDDR5  0x50
+#define MEM_TYPE_GDDR4  0x40
+#define MEM_TYPE_GDDR3  0x30
+#define MEM_TYPE_DDR2   0x20
+#define MEM_TYPE_GDDR1  0x10
+#define MEM_TYPE_DDR3   0xb0
+#define MEM_TYPE_MASK   0xf0
+
+struct atom_memory_info {
+	u8 mem_vendor;
+	u8 mem_type;
+};
+
+#define MAX_AC_TIMING_ENTRIES 16
+
+struct atom_memory_clock_range_table
+{
+	u8 num_entries;
+	u8 rsv[3];
+	u32 mclk[MAX_AC_TIMING_ENTRIES];
+};
+
+#define VBIOS_MC_REGISTER_ARRAY_SIZE 32
+#define VBIOS_MAX_AC_TIMING_ENTRIES 20
+
+struct atom_mc_reg_entry {
+	u32 mclk_max;
+	u32 mc_data[VBIOS_MC_REGISTER_ARRAY_SIZE];
+};
+
+struct atom_mc_register_address {
+	u16 s1;
+	u8 pre_reg_data;
+};
+
+struct atom_mc_reg_table {
+	u8 last;
+	u8 num_entries;
+	struct atom_mc_reg_entry mc_reg_table_entry[VBIOS_MAX_AC_TIMING_ENTRIES];
+	struct atom_mc_register_address mc_reg_address[VBIOS_MC_REGISTER_ARRAY_SIZE];
+};
+
+#define MAX_VOLTAGE_ENTRIES 32
+
+struct atom_voltage_table_entry
+{
+	u16 value;
+	u32 smio_low;
+};
+
+struct atom_voltage_table
+{
+	u32 count;
+	u32 mask_low;
+	u32 phase_delay;
+	struct atom_voltage_table_entry entries[MAX_VOLTAGE_ENTRIES];
 };
 
 extern enum radeon_tv_std
 radeon_combios_get_tv_info(struct radeon_device *rdev);
 extern enum radeon_tv_std
 radeon_atombios_get_tv_info(struct radeon_device *rdev);
+extern void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
+						 u16 *vddc, u16 *vddci, u16 *mvdd);
 
 extern struct drm_connector *
 radeon_get_connector_for_encoder(struct drm_encoder *encoder);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_object.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_object.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_object.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_object.c	2013-08-25 20:43:22.000000000 -0400
@@ -322,8 +322,8 @@ int radeon_bo_init(struct radeon_device
 {
 	/* Add an MTRR for the VRAM */
 	if (!rdev->fastfb_working) {
-		rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
-			MTRR_TYPE_WRCOMB, 1);
+		rdev->mc.vram_mtrr = arch_phys_wc_add(rdev->mc.aper_base,
+						      rdev->mc.aper_size);
 	}
 	DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
 		rdev->mc.mc_vram_size >> 20,
@@ -336,6 +336,7 @@ int radeon_bo_init(struct radeon_device
 void radeon_bo_fini(struct radeon_device *rdev)
 {
 	radeon_ttm_fini(rdev);
+	arch_phys_wc_del(rdev->mc.vram_mtrr);
 }
 
 void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
@@ -348,14 +349,15 @@ void radeon_bo_list_add_object(struct ra
 	}
 }
 
-int radeon_bo_list_validate(struct list_head *head, int ring)
+int radeon_bo_list_validate(struct ww_acquire_ctx *ticket,
+			    struct list_head *head, int ring)
 {
 	struct radeon_bo_list *lobj;
 	struct radeon_bo *bo;
 	u32 domain;
 	int r;
 
-	r = ttm_eu_reserve_buffers(head);
+	r = ttm_eu_reserve_buffers(ticket, head);
 	if (unlikely(r != 0)) {
 		return r;
 	}
@@ -375,6 +377,7 @@ int radeon_bo_list_validate(struct list_
 					domain = lobj->alt_domain;
 					goto retry;
 				}
+				ttm_eu_backoff_reservation(ticket, head);
 				return r;
 			}
 		}
@@ -398,7 +401,7 @@ int radeon_bo_get_surface_reg(struct rad
 	int steal;
 	int i;
 
-	BUG_ON(!radeon_bo_is_reserved(bo));
+	lockdep_assert_held(&bo->tbo.resv->lock.base);
 
 	if (!bo->tiling_flags)
 		return 0;
@@ -524,7 +527,8 @@ void radeon_bo_get_tiling_flags(struct r
 				uint32_t *tiling_flags,
 				uint32_t *pitch)
 {
-	BUG_ON(!radeon_bo_is_reserved(bo));
+	lockdep_assert_held(&bo->tbo.resv->lock.base);
+
 	if (tiling_flags)
 		*tiling_flags = bo->tiling_flags;
 	if (pitch)
@@ -534,7 +538,8 @@ void radeon_bo_get_tiling_flags(struct r
 int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
 				bool force_drop)
 {
-	BUG_ON(!radeon_bo_is_reserved(bo) && !force_drop);
+	if (!force_drop)
+		lockdep_assert_held(&bo->tbo.resv->lock.base);
 
 	if (!(bo->tiling_flags & RADEON_TILING_SURFACE))
 		return 0;
@@ -617,26 +622,3 @@ int radeon_bo_wait(struct radeon_bo *bo,
 	ttm_bo_unreserve(&bo->tbo);
 	return r;
 }
-
-
-/**
- * radeon_bo_reserve - reserve bo
- * @bo:		bo structure
- * @no_intr:	don't return -ERESTARTSYS on pending signal
- *
- * Returns:
- * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
- * a signal. Release all buffer reservations and return to user-space.
- */
-int radeon_bo_reserve(struct radeon_bo *bo, bool no_intr)
-{
-	int r;
-
-	r = ttm_bo_reserve(&bo->tbo, !no_intr, false, false, 0);
-	if (unlikely(r != 0)) {
-		if (r != -ERESTARTSYS)
-			dev_err(bo->rdev->dev, "%p reserve failed\n", bo);
-		return r;
-	}
-	return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_object.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_object.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_object.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_object.h	2013-08-25 20:43:22.000000000 -0400
@@ -52,7 +52,27 @@ static inline unsigned radeon_mem_type_t
 	return 0;
 }
 
-int radeon_bo_reserve(struct radeon_bo *bo, bool no_intr);
+/**
+ * radeon_bo_reserve - reserve bo
+ * @bo:		bo structure
+ * @no_intr:	don't return -ERESTARTSYS on pending signal
+ *
+ * Returns:
+ * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
+ * a signal. Release all buffer reservations and return to user-space.
+ */
+static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_intr)
+{
+	int r;
+
+	r = ttm_bo_reserve(&bo->tbo, !no_intr, false, false, 0);
+	if (unlikely(r != 0)) {
+		if (r != -ERESTARTSYS)
+			dev_err(bo->rdev->dev, "%p reserve failed\n", bo);
+		return r;
+	}
+	return 0;
+}
 
 static inline void radeon_bo_unreserve(struct radeon_bo *bo)
 {
@@ -78,11 +98,6 @@ static inline unsigned long radeon_bo_si
 	return bo->tbo.num_pages << PAGE_SHIFT;
 }
 
-static inline bool radeon_bo_is_reserved(struct radeon_bo *bo)
-{
-	return ttm_bo_is_reserved(&bo->tbo);
-}
-
 static inline unsigned radeon_bo_ngpu_pages(struct radeon_bo *bo)
 {
 	return (bo->tbo.num_pages << PAGE_SHIFT) / RADEON_GPU_PAGE_SIZE;
@@ -128,7 +143,8 @@ extern int radeon_bo_init(struct radeon_
 extern void radeon_bo_fini(struct radeon_device *rdev);
 extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
 				struct list_head *head);
-extern int radeon_bo_list_validate(struct list_head *head, int ring);
+extern int radeon_bo_list_validate(struct ww_acquire_ctx *ticket,
+				   struct list_head *head, int ring);
 extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
 				struct vm_area_struct *vma);
 extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
@@ -158,7 +174,7 @@ static inline void * radeon_sa_bo_cpu_ad
 
 extern int radeon_sa_bo_manager_init(struct radeon_device *rdev,
 				     struct radeon_sa_manager *sa_manager,
-				     unsigned size, u32 domain);
+				     unsigned size, u32 align, u32 domain);
 extern void radeon_sa_bo_manager_fini(struct radeon_device *rdev,
 				      struct radeon_sa_manager *sa_manager);
 extern int radeon_sa_bo_manager_start(struct radeon_device *rdev,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_pm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_pm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -388,7 +388,8 @@ static ssize_t radeon_get_pm_method(stru
 	int pm = rdev->pm.pm_method;
 
 	return snprintf(buf, PAGE_SIZE, "%s\n",
-			(pm == PM_METHOD_DYNPM) ? "dynpm" : "profile");
+			(pm == PM_METHOD_DYNPM) ? "dynpm" :
+			(pm == PM_METHOD_PROFILE) ? "profile" : "dpm");
 }
 
 static ssize_t radeon_set_pm_method(struct device *dev,
@@ -399,6 +400,11 @@ static ssize_t radeon_set_pm_method(stru
 	struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
 	struct radeon_device *rdev = ddev->dev_private;
 
+	/* we don't support the legacy modes with dpm */
+	if (rdev->pm.pm_method == PM_METHOD_DPM) {
+		count = -EINVAL;
+		goto fail;
+	}
 
 	if (strncmp("dynpm", buf, strlen("dynpm")) == 0) {
 		mutex_lock(&rdev->pm.mutex);
@@ -423,8 +429,96 @@ fail:
 	return count;
 }
 
+static ssize_t radeon_get_dpm_state(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+	struct radeon_device *rdev = ddev->dev_private;
+	enum radeon_pm_state_type pm = rdev->pm.dpm.user_state;
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			(pm == POWER_STATE_TYPE_BATTERY) ? "battery" :
+			(pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance");
+}
+
+static ssize_t radeon_set_dpm_state(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf,
+				    size_t count)
+{
+	struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+	struct radeon_device *rdev = ddev->dev_private;
+
+	mutex_lock(&rdev->pm.mutex);
+	if (strncmp("battery", buf, strlen("battery")) == 0)
+		rdev->pm.dpm.user_state = POWER_STATE_TYPE_BATTERY;
+	else if (strncmp("balanced", buf, strlen("balanced")) == 0)
+		rdev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED;
+	else if (strncmp("performance", buf, strlen("performance")) == 0)
+		rdev->pm.dpm.user_state = POWER_STATE_TYPE_PERFORMANCE;
+	else {
+		mutex_unlock(&rdev->pm.mutex);
+		count = -EINVAL;
+		goto fail;
+	}
+	mutex_unlock(&rdev->pm.mutex);
+	radeon_pm_compute_clocks(rdev);
+fail:
+	return count;
+}
+
+static ssize_t radeon_get_dpm_forced_performance_level(struct device *dev,
+						       struct device_attribute *attr,
+						       char *buf)
+{
+	struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+	struct radeon_device *rdev = ddev->dev_private;
+	enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level;
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			(level == RADEON_DPM_FORCED_LEVEL_AUTO) ? "auto" :
+			(level == RADEON_DPM_FORCED_LEVEL_LOW) ? "low" : "high");
+}
+
+static ssize_t radeon_set_dpm_forced_performance_level(struct device *dev,
+						       struct device_attribute *attr,
+						       const char *buf,
+						       size_t count)
+{
+	struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+	struct radeon_device *rdev = ddev->dev_private;
+	enum radeon_dpm_forced_level level;
+	int ret = 0;
+
+	mutex_lock(&rdev->pm.mutex);
+	if (strncmp("low", buf, strlen("low")) == 0) {
+		level = RADEON_DPM_FORCED_LEVEL_LOW;
+	} else if (strncmp("high", buf, strlen("high")) == 0) {
+		level = RADEON_DPM_FORCED_LEVEL_HIGH;
+	} else if (strncmp("auto", buf, strlen("auto")) == 0) {
+		level = RADEON_DPM_FORCED_LEVEL_AUTO;
+	} else {
+		mutex_unlock(&rdev->pm.mutex);
+		count = -EINVAL;
+		goto fail;
+	}
+	if (rdev->asic->dpm.force_performance_level) {
+		ret = radeon_dpm_force_performance_level(rdev, level);
+		if (ret)
+			count = -EINVAL;
+	}
+	mutex_unlock(&rdev->pm.mutex);
+fail:
+	return count;
+}
+
 static DEVICE_ATTR(power_profile, S_IRUGO | S_IWUSR, radeon_get_pm_profile, radeon_set_pm_profile);
 static DEVICE_ATTR(power_method, S_IRUGO | S_IWUSR, radeon_get_pm_method, radeon_set_pm_method);
+static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, radeon_get_dpm_state, radeon_set_dpm_state);
+static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
+		   radeon_get_dpm_forced_performance_level,
+		   radeon_set_dpm_forced_performance_level);
 
 static ssize_t radeon_hwmon_show_temp(struct device *dev,
 				      struct device_attribute *attr,
@@ -434,27 +528,10 @@ static ssize_t radeon_hwmon_show_temp(st
 	struct radeon_device *rdev = ddev->dev_private;
 	int temp;
 
-	switch (rdev->pm.int_thermal_type) {
-	case THERMAL_TYPE_RV6XX:
-		temp = rv6xx_get_temp(rdev);
-		break;
-	case THERMAL_TYPE_RV770:
-		temp = rv770_get_temp(rdev);
-		break;
-	case THERMAL_TYPE_EVERGREEN:
-	case THERMAL_TYPE_NI:
-		temp = evergreen_get_temp(rdev);
-		break;
-	case THERMAL_TYPE_SUMO:
-		temp = sumo_get_temp(rdev);
-		break;
-	case THERMAL_TYPE_SI:
-		temp = si_get_temp(rdev);
-		break;
-	default:
+	if (rdev->asic->pm.get_temperature)
+		temp = radeon_get_temperature(rdev);
+	else
 		temp = 0;
-		break;
-	}
 
 	return snprintf(buf, PAGE_SIZE, "%d\n", temp);
 }
@@ -492,8 +569,7 @@ static int radeon_hwmon_init(struct rade
 	case THERMAL_TYPE_NI:
 	case THERMAL_TYPE_SUMO:
 	case THERMAL_TYPE_SI:
-		/* No support for TN yet */
-		if (rdev->family == CHIP_ARUBA)
+		if (rdev->asic->pm.get_temperature == NULL)
 			return err;
 		rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);
 		if (IS_ERR(rdev->pm.int_hwmon_dev)) {
@@ -526,7 +602,289 @@ static void radeon_hwmon_fini(struct rad
 	}
 }
 
-void radeon_pm_suspend(struct radeon_device *rdev)
+static void radeon_dpm_thermal_work_handler(struct work_struct *work)
+{
+	struct radeon_device *rdev =
+		container_of(work, struct radeon_device,
+			     pm.dpm.thermal.work);
+	/* switch to the thermal state */
+	enum radeon_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL;
+
+	if (!rdev->pm.dpm_enabled)
+		return;
+
+	if (rdev->asic->pm.get_temperature) {
+		int temp = radeon_get_temperature(rdev);
+
+		if (temp < rdev->pm.dpm.thermal.min_temp)
+			/* switch back the user state */
+			dpm_state = rdev->pm.dpm.user_state;
+	} else {
+		if (rdev->pm.dpm.thermal.high_to_low)
+			/* switch back the user state */
+			dpm_state = rdev->pm.dpm.user_state;
+	}
+	radeon_dpm_enable_power_state(rdev, dpm_state);
+}
+
+static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
+						     enum radeon_pm_state_type dpm_state)
+{
+	int i;
+	struct radeon_ps *ps;
+	u32 ui_class;
+	bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ?
+		true : false;
+
+	/* check if the vblank period is too short to adjust the mclk */
+	if (single_display && rdev->asic->dpm.vblank_too_short) {
+		if (radeon_dpm_vblank_too_short(rdev))
+			single_display = false;
+	}
+
+	/* certain older asics have a separare 3D performance state,
+	 * so try that first if the user selected performance
+	 */
+	if (dpm_state == POWER_STATE_TYPE_PERFORMANCE)
+		dpm_state = POWER_STATE_TYPE_INTERNAL_3DPERF;
+	/* balanced states don't exist at the moment */
+	if (dpm_state == POWER_STATE_TYPE_BALANCED)
+		dpm_state = POWER_STATE_TYPE_PERFORMANCE;
+
+restart_search:
+	/* Pick the best power state based on current conditions */
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		ps = &rdev->pm.dpm.ps[i];
+		ui_class = ps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK;
+		switch (dpm_state) {
+		/* user states */
+		case POWER_STATE_TYPE_BATTERY:
+			if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) {
+				if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
+					if (single_display)
+						return ps;
+				} else
+					return ps;
+			}
+			break;
+		case POWER_STATE_TYPE_BALANCED:
+			if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_BALANCED) {
+				if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
+					if (single_display)
+						return ps;
+				} else
+					return ps;
+			}
+			break;
+		case POWER_STATE_TYPE_PERFORMANCE:
+			if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
+				if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
+					if (single_display)
+						return ps;
+				} else
+					return ps;
+			}
+			break;
+		/* internal states */
+		case POWER_STATE_TYPE_INTERNAL_UVD:
+			return rdev->pm.dpm.uvd_ps;
+		case POWER_STATE_TYPE_INTERNAL_UVD_SD:
+			if (ps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
+				return ps;
+			break;
+		case POWER_STATE_TYPE_INTERNAL_UVD_HD:
+			if (ps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
+				return ps;
+			break;
+		case POWER_STATE_TYPE_INTERNAL_UVD_HD2:
+			if (ps->class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
+				return ps;
+			break;
+		case POWER_STATE_TYPE_INTERNAL_UVD_MVC:
+			if (ps->class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
+				return ps;
+			break;
+		case POWER_STATE_TYPE_INTERNAL_BOOT:
+			return rdev->pm.dpm.boot_ps;
+		case POWER_STATE_TYPE_INTERNAL_THERMAL:
+			if (ps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
+				return ps;
+			break;
+		case POWER_STATE_TYPE_INTERNAL_ACPI:
+			if (ps->class & ATOM_PPLIB_CLASSIFICATION_ACPI)
+				return ps;
+			break;
+		case POWER_STATE_TYPE_INTERNAL_ULV:
+			if (ps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
+				return ps;
+			break;
+		case POWER_STATE_TYPE_INTERNAL_3DPERF:
+			if (ps->class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
+				return ps;
+			break;
+		default:
+			break;
+		}
+	}
+	/* use a fallback state if we didn't match */
+	switch (dpm_state) {
+	case POWER_STATE_TYPE_INTERNAL_UVD_SD:
+	case POWER_STATE_TYPE_INTERNAL_UVD_HD:
+	case POWER_STATE_TYPE_INTERNAL_UVD_HD2:
+	case POWER_STATE_TYPE_INTERNAL_UVD_MVC:
+		return rdev->pm.dpm.uvd_ps;
+	case POWER_STATE_TYPE_INTERNAL_THERMAL:
+		dpm_state = POWER_STATE_TYPE_INTERNAL_ACPI;
+		goto restart_search;
+	case POWER_STATE_TYPE_INTERNAL_ACPI:
+		dpm_state = POWER_STATE_TYPE_BATTERY;
+		goto restart_search;
+	case POWER_STATE_TYPE_BATTERY:
+	case POWER_STATE_TYPE_BALANCED:
+	case POWER_STATE_TYPE_INTERNAL_3DPERF:
+		dpm_state = POWER_STATE_TYPE_PERFORMANCE;
+		goto restart_search;
+	default:
+		break;
+	}
+
+	return NULL;
+}
+
+static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev)
+{
+	int i;
+	struct radeon_ps *ps;
+	enum radeon_pm_state_type dpm_state;
+	int ret;
+
+	/* if dpm init failed */
+	if (!rdev->pm.dpm_enabled)
+		return;
+
+	if (rdev->pm.dpm.user_state != rdev->pm.dpm.state) {
+		/* add other state override checks here */
+		if ((!rdev->pm.dpm.thermal_active) &&
+		    (!rdev->pm.dpm.uvd_active))
+			rdev->pm.dpm.state = rdev->pm.dpm.user_state;
+	}
+	dpm_state = rdev->pm.dpm.state;
+
+	ps = radeon_dpm_pick_power_state(rdev, dpm_state);
+	if (ps)
+		rdev->pm.dpm.requested_ps = ps;
+	else
+		return;
+
+	/* no need to reprogram if nothing changed unless we are on BTC+ */
+	if (rdev->pm.dpm.current_ps == rdev->pm.dpm.requested_ps) {
+		if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) {
+			/* for pre-BTC and APUs if the num crtcs changed but state is the same,
+			 * all we need to do is update the display configuration.
+			 */
+			if (rdev->pm.dpm.new_active_crtcs != rdev->pm.dpm.current_active_crtcs) {
+				/* update display watermarks based on new power state */
+				radeon_bandwidth_update(rdev);
+				/* update displays */
+				radeon_dpm_display_configuration_changed(rdev);
+				rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
+				rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
+			}
+			return;
+		} else {
+			/* for BTC+ if the num crtcs hasn't changed and state is the same,
+			 * nothing to do, if the num crtcs is > 1 and state is the same,
+			 * update display configuration.
+			 */
+			if (rdev->pm.dpm.new_active_crtcs ==
+			    rdev->pm.dpm.current_active_crtcs) {
+				return;
+			} else {
+				if ((rdev->pm.dpm.current_active_crtc_count > 1) &&
+				    (rdev->pm.dpm.new_active_crtc_count > 1)) {
+					/* update display watermarks based on new power state */
+					radeon_bandwidth_update(rdev);
+					/* update displays */
+					radeon_dpm_display_configuration_changed(rdev);
+					rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
+					rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
+					return;
+				}
+			}
+		}
+	}
+
+	printk("switching from power state:\n");
+	radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps);
+	printk("switching to power state:\n");
+	radeon_dpm_print_power_state(rdev, rdev->pm.dpm.requested_ps);
+
+	mutex_lock(&rdev->ddev->struct_mutex);
+	down_write(&rdev->pm.mclk_lock);
+	mutex_lock(&rdev->ring_lock);
+
+	ret = radeon_dpm_pre_set_power_state(rdev);
+	if (ret)
+		goto done;
+
+	/* update display watermarks based on new power state */
+	radeon_bandwidth_update(rdev);
+	/* update displays */
+	radeon_dpm_display_configuration_changed(rdev);
+
+	rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
+	rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
+
+	/* wait for the rings to drain */
+	for (i = 0; i < RADEON_NUM_RINGS; i++) {
+		struct radeon_ring *ring = &rdev->ring[i];
+		if (ring->ready)
+			radeon_fence_wait_empty_locked(rdev, i);
+	}
+
+	/* program the new power state */
+	radeon_dpm_set_power_state(rdev);
+
+	/* update current power state */
+	rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps;
+
+	radeon_dpm_post_set_power_state(rdev);
+
+done:
+	mutex_unlock(&rdev->ring_lock);
+	up_write(&rdev->pm.mclk_lock);
+	mutex_unlock(&rdev->ddev->struct_mutex);
+}
+
+void radeon_dpm_enable_power_state(struct radeon_device *rdev,
+				   enum radeon_pm_state_type dpm_state)
+{
+	if (!rdev->pm.dpm_enabled)
+		return;
+
+	mutex_lock(&rdev->pm.mutex);
+	switch (dpm_state) {
+	case POWER_STATE_TYPE_INTERNAL_THERMAL:
+		rdev->pm.dpm.thermal_active = true;
+		break;
+	case POWER_STATE_TYPE_INTERNAL_UVD:
+	case POWER_STATE_TYPE_INTERNAL_UVD_SD:
+	case POWER_STATE_TYPE_INTERNAL_UVD_HD:
+	case POWER_STATE_TYPE_INTERNAL_UVD_HD2:
+	case POWER_STATE_TYPE_INTERNAL_UVD_MVC:
+		rdev->pm.dpm.uvd_active = true;
+		break;
+	default:
+		rdev->pm.dpm.thermal_active = false;
+		rdev->pm.dpm.uvd_active = false;
+		break;
+	}
+	rdev->pm.dpm.state = dpm_state;
+	mutex_unlock(&rdev->pm.mutex);
+	radeon_pm_compute_clocks(rdev);
+}
+
+static void radeon_pm_suspend_old(struct radeon_device *rdev)
 {
 	mutex_lock(&rdev->pm.mutex);
 	if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
@@ -538,11 +896,30 @@ void radeon_pm_suspend(struct radeon_dev
 	cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work);
 }
 
-void radeon_pm_resume(struct radeon_device *rdev)
+static void radeon_pm_suspend_dpm(struct radeon_device *rdev)
+{
+	mutex_lock(&rdev->pm.mutex);
+	/* disable dpm */
+	radeon_dpm_disable(rdev);
+	/* reset the power state */
+	rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps = rdev->pm.dpm.boot_ps;
+	rdev->pm.dpm_enabled = false;
+	mutex_unlock(&rdev->pm.mutex);
+}
+
+void radeon_pm_suspend(struct radeon_device *rdev)
+{
+	if (rdev->pm.pm_method == PM_METHOD_DPM)
+		radeon_pm_suspend_dpm(rdev);
+	else
+		radeon_pm_suspend_old(rdev);
+}
+
+static void radeon_pm_resume_old(struct radeon_device *rdev)
 {
 	/* set up the default clocks if the MC ucode is loaded */
 	if ((rdev->family >= CHIP_BARTS) &&
-	    (rdev->family <= CHIP_CAYMAN) &&
+	    (rdev->family <= CHIP_HAINAN) &&
 	    rdev->mc_fw) {
 		if (rdev->pm.default_vddc)
 			radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
@@ -573,12 +950,50 @@ void radeon_pm_resume(struct radeon_devi
 	radeon_pm_compute_clocks(rdev);
 }
 
-int radeon_pm_init(struct radeon_device *rdev)
+static void radeon_pm_resume_dpm(struct radeon_device *rdev)
+{
+	int ret;
+
+	/* asic init will reset to the boot state */
+	mutex_lock(&rdev->pm.mutex);
+	rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps = rdev->pm.dpm.boot_ps;
+	radeon_dpm_setup_asic(rdev);
+	ret = radeon_dpm_enable(rdev);
+	mutex_unlock(&rdev->pm.mutex);
+	if (ret) {
+		DRM_ERROR("radeon: dpm resume failed\n");
+		if ((rdev->family >= CHIP_BARTS) &&
+		    (rdev->family <= CHIP_HAINAN) &&
+		    rdev->mc_fw) {
+			if (rdev->pm.default_vddc)
+				radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
+							SET_VOLTAGE_TYPE_ASIC_VDDC);
+			if (rdev->pm.default_vddci)
+				radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
+							SET_VOLTAGE_TYPE_ASIC_VDDCI);
+			if (rdev->pm.default_sclk)
+				radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
+			if (rdev->pm.default_mclk)
+				radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
+		}
+	} else {
+		rdev->pm.dpm_enabled = true;
+		radeon_pm_compute_clocks(rdev);
+	}
+}
+
+void radeon_pm_resume(struct radeon_device *rdev)
+{
+	if (rdev->pm.pm_method == PM_METHOD_DPM)
+		radeon_pm_resume_dpm(rdev);
+	else
+		radeon_pm_resume_old(rdev);
+}
+
+static int radeon_pm_init_old(struct radeon_device *rdev)
 {
 	int ret;
 
-	/* default to profile method */
-	rdev->pm.pm_method = PM_METHOD_PROFILE;
 	rdev->pm.profile = PM_PROFILE_DEFAULT;
 	rdev->pm.dynpm_state = DYNPM_STATE_DISABLED;
 	rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
@@ -599,7 +1014,7 @@ int radeon_pm_init(struct radeon_device
 		radeon_pm_init_profile(rdev);
 		/* set up the default clocks if the MC ucode is loaded */
 		if ((rdev->family >= CHIP_BARTS) &&
-		    (rdev->family <= CHIP_CAYMAN) &&
+		    (rdev->family <= CHIP_HAINAN) &&
 		    rdev->mc_fw) {
 			if (rdev->pm.default_vddc)
 				radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
@@ -640,7 +1055,152 @@ int radeon_pm_init(struct radeon_device
 	return 0;
 }
 
-void radeon_pm_fini(struct radeon_device *rdev)
+static void radeon_dpm_print_power_states(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		printk("== power state %d ==\n", i);
+		radeon_dpm_print_power_state(rdev, &rdev->pm.dpm.ps[i]);
+	}
+}
+
+static int radeon_pm_init_dpm(struct radeon_device *rdev)
+{
+	int ret;
+
+	/* default to performance state */
+	rdev->pm.dpm.state = POWER_STATE_TYPE_BALANCED;
+	rdev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED;
+	rdev->pm.default_sclk = rdev->clock.default_sclk;
+	rdev->pm.default_mclk = rdev->clock.default_mclk;
+	rdev->pm.current_sclk = rdev->clock.default_sclk;
+	rdev->pm.current_mclk = rdev->clock.default_mclk;
+	rdev->pm.int_thermal_type = THERMAL_TYPE_NONE;
+
+	if (rdev->bios && rdev->is_atom_bios)
+		radeon_atombios_get_power_modes(rdev);
+	else
+		return -EINVAL;
+
+	/* set up the internal thermal sensor if applicable */
+	ret = radeon_hwmon_init(rdev);
+	if (ret)
+		return ret;
+
+	INIT_WORK(&rdev->pm.dpm.thermal.work, radeon_dpm_thermal_work_handler);
+	mutex_lock(&rdev->pm.mutex);
+	radeon_dpm_init(rdev);
+	rdev->pm.dpm.current_ps = rdev->pm.dpm.requested_ps = rdev->pm.dpm.boot_ps;
+	radeon_dpm_print_power_states(rdev);
+	radeon_dpm_setup_asic(rdev);
+	ret = radeon_dpm_enable(rdev);
+	mutex_unlock(&rdev->pm.mutex);
+	if (ret) {
+		rdev->pm.dpm_enabled = false;
+		if ((rdev->family >= CHIP_BARTS) &&
+		    (rdev->family <= CHIP_HAINAN) &&
+		    rdev->mc_fw) {
+			if (rdev->pm.default_vddc)
+				radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
+							SET_VOLTAGE_TYPE_ASIC_VDDC);
+			if (rdev->pm.default_vddci)
+				radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
+							SET_VOLTAGE_TYPE_ASIC_VDDCI);
+			if (rdev->pm.default_sclk)
+				radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
+			if (rdev->pm.default_mclk)
+				radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
+		}
+		DRM_ERROR("radeon: dpm initialization failed\n");
+		return ret;
+	}
+	rdev->pm.dpm_enabled = true;
+	radeon_pm_compute_clocks(rdev);
+
+	if (rdev->pm.num_power_states > 1) {
+		ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
+		if (ret)
+			DRM_ERROR("failed to create device file for dpm state\n");
+		ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
+		if (ret)
+			DRM_ERROR("failed to create device file for dpm state\n");
+		/* XXX: these are noops for dpm but are here for backwards compat */
+		ret = device_create_file(rdev->dev, &dev_attr_power_profile);
+		if (ret)
+			DRM_ERROR("failed to create device file for power profile\n");
+		ret = device_create_file(rdev->dev, &dev_attr_power_method);
+		if (ret)
+			DRM_ERROR("failed to create device file for power method\n");
+
+		if (radeon_debugfs_pm_init(rdev)) {
+			DRM_ERROR("Failed to register debugfs file for dpm!\n");
+		}
+
+		DRM_INFO("radeon: dpm initialized\n");
+	}
+
+	return 0;
+}
+
+int radeon_pm_init(struct radeon_device *rdev)
+{
+	/* enable dpm on rv6xx+ */
+	switch (rdev->family) {
+	case CHIP_RV610:
+	case CHIP_RV630:
+	case CHIP_RV620:
+	case CHIP_RV635:
+	case CHIP_RV670:
+	case CHIP_RS780:
+	case CHIP_RS880:
+	case CHIP_RV770:
+	case CHIP_RV730:
+	case CHIP_RV710:
+	case CHIP_RV740:
+	case CHIP_CEDAR:
+	case CHIP_REDWOOD:
+	case CHIP_JUNIPER:
+	case CHIP_CYPRESS:
+	case CHIP_HEMLOCK:
+	case CHIP_PALM:
+	case CHIP_SUMO:
+	case CHIP_SUMO2:
+	case CHIP_BARTS:
+	case CHIP_TURKS:
+	case CHIP_CAICOS:
+	case CHIP_CAYMAN:
+	case CHIP_ARUBA:
+	case CHIP_TAHITI:
+	case CHIP_PITCAIRN:
+	case CHIP_VERDE:
+	case CHIP_OLAND:
+	case CHIP_HAINAN:
+		/* DPM requires the RLC, RV770+ dGPU requires SMC */
+		if (!rdev->rlc_fw)
+			rdev->pm.pm_method = PM_METHOD_PROFILE;
+		else if ((rdev->family >= CHIP_RV770) &&
+			 (!(rdev->flags & RADEON_IS_IGP)) &&
+			 (!rdev->smc_fw))
+			rdev->pm.pm_method = PM_METHOD_PROFILE;
+		else if (radeon_dpm == 1)
+			rdev->pm.pm_method = PM_METHOD_DPM;
+		else
+			rdev->pm.pm_method = PM_METHOD_PROFILE;
+		break;
+	default:
+		/* default to profile method */
+		rdev->pm.pm_method = PM_METHOD_PROFILE;
+		break;
+	}
+
+	if (rdev->pm.pm_method == PM_METHOD_DPM)
+		return radeon_pm_init_dpm(rdev);
+	else
+		return radeon_pm_init_old(rdev);
+}
+
+static void radeon_pm_fini_old(struct radeon_device *rdev)
 {
 	if (rdev->pm.num_power_states > 1) {
 		mutex_lock(&rdev->pm.mutex);
@@ -668,7 +1228,36 @@ void radeon_pm_fini(struct radeon_device
 	radeon_hwmon_fini(rdev);
 }
 
-void radeon_pm_compute_clocks(struct radeon_device *rdev)
+static void radeon_pm_fini_dpm(struct radeon_device *rdev)
+{
+	if (rdev->pm.num_power_states > 1) {
+		mutex_lock(&rdev->pm.mutex);
+		radeon_dpm_disable(rdev);
+		mutex_unlock(&rdev->pm.mutex);
+
+		device_remove_file(rdev->dev, &dev_attr_power_dpm_state);
+		device_remove_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
+		/* XXX backwards compat */
+		device_remove_file(rdev->dev, &dev_attr_power_profile);
+		device_remove_file(rdev->dev, &dev_attr_power_method);
+	}
+	radeon_dpm_fini(rdev);
+
+	if (rdev->pm.power_state)
+		kfree(rdev->pm.power_state);
+
+	radeon_hwmon_fini(rdev);
+}
+
+void radeon_pm_fini(struct radeon_device *rdev)
+{
+	if (rdev->pm.pm_method == PM_METHOD_DPM)
+		radeon_pm_fini_dpm(rdev);
+	else
+		radeon_pm_fini_old(rdev);
+}
+
+static void radeon_pm_compute_clocks_old(struct radeon_device *rdev)
 {
 	struct drm_device *ddev = rdev->ddev;
 	struct drm_crtc *crtc;
@@ -739,6 +1328,46 @@ void radeon_pm_compute_clocks(struct rad
 	mutex_unlock(&rdev->pm.mutex);
 }
 
+static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
+{
+	struct drm_device *ddev = rdev->ddev;
+	struct drm_crtc *crtc;
+	struct radeon_crtc *radeon_crtc;
+
+	mutex_lock(&rdev->pm.mutex);
+
+	/* update active crtc counts */
+	rdev->pm.dpm.new_active_crtcs = 0;
+	rdev->pm.dpm.new_active_crtc_count = 0;
+	list_for_each_entry(crtc,
+		&ddev->mode_config.crtc_list, head) {
+		radeon_crtc = to_radeon_crtc(crtc);
+		if (crtc->enabled) {
+			rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id);
+			rdev->pm.dpm.new_active_crtc_count++;
+		}
+	}
+
+	/* update battery/ac status */
+	if (power_supply_is_system_supplied() > 0)
+		rdev->pm.dpm.ac_power = true;
+	else
+		rdev->pm.dpm.ac_power = false;
+
+	radeon_dpm_change_power_state_locked(rdev);
+
+	mutex_unlock(&rdev->pm.mutex);
+
+}
+
+void radeon_pm_compute_clocks(struct radeon_device *rdev)
+{
+	if (rdev->pm.pm_method == PM_METHOD_DPM)
+		radeon_pm_compute_clocks_dpm(rdev);
+	else
+		radeon_pm_compute_clocks_old(rdev);
+}
+
 static bool radeon_pm_in_vbl(struct radeon_device *rdev)
 {
 	int  crtc, vpos, hpos, vbl_status;
@@ -842,19 +1471,28 @@ static int radeon_debugfs_pm_info(struct
 	struct drm_device *dev = node->minor->dev;
 	struct radeon_device *rdev = dev->dev_private;
 
-	seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk);
-	/* radeon_get_engine_clock is not reliable on APUs so just print the current clock */
-	if ((rdev->family >= CHIP_PALM) && (rdev->flags & RADEON_IS_IGP))
-		seq_printf(m, "current engine clock: %u0 kHz\n", rdev->pm.current_sclk);
-	else
-		seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
-	seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk);
-	if (rdev->asic->pm.get_memory_clock)
-		seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
-	if (rdev->pm.current_vddc)
-		seq_printf(m, "voltage: %u mV\n", rdev->pm.current_vddc);
-	if (rdev->asic->pm.get_pcie_lanes)
-		seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev));
+	if (rdev->pm.dpm_enabled) {
+		mutex_lock(&rdev->pm.mutex);
+		if (rdev->asic->dpm.debugfs_print_current_performance_level)
+			radeon_dpm_debugfs_print_current_performance_level(rdev, m);
+		else
+			seq_printf(m, "Debugfs support not implemented for this asic\n");
+		mutex_unlock(&rdev->pm.mutex);
+	} else {
+		seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk);
+		/* radeon_get_engine_clock is not reliable on APUs so just print the current clock */
+		if ((rdev->family >= CHIP_PALM) && (rdev->flags & RADEON_IS_IGP))
+			seq_printf(m, "current engine clock: %u0 kHz\n", rdev->pm.current_sclk);
+		else
+			seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
+		seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk);
+		if (rdev->asic->pm.get_memory_clock)
+			seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
+		if (rdev->pm.current_vddc)
+			seq_printf(m, "voltage: %u mV\n", rdev->pm.current_vddc);
+		if (rdev->asic->pm.get_pcie_lanes)
+			seq_printf(m, "PCIE lanes: %d\n", radeon_get_pcie_lanes(rdev));
+	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_prime.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_prime.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_prime.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_prime.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,11 +88,19 @@ int radeon_gem_prime_pin(struct drm_gem_
 
 	/* pin buffer into GTT */
 	ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL);
-	if (ret) {
-		radeon_bo_unreserve(bo);
-		return ret;
-	}
 	radeon_bo_unreserve(bo);
+	return ret;
+}
 
-	return 0;
+void radeon_gem_prime_unpin(struct drm_gem_object *obj)
+{
+	struct radeon_bo *bo = gem_to_radeon_bo(obj);
+	int ret = 0;
+
+	ret = radeon_bo_reserve(bo, false);
+	if (unlikely(ret != 0))
+		return;
+
+	radeon_bo_unpin(bo);
+	radeon_bo_unreserve(bo);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_reg.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_reg.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -57,6 +57,7 @@
 #include "evergreen_reg.h"
 #include "ni_reg.h"
 #include "si_reg.h"
+#include "cik_reg.h"
 
 #define RADEON_MC_AGP_LOCATION		0x014c
 #define		RADEON_MC_AGP_START_MASK	0x0000FFFF
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_ring.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_ring.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_ring.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_ring.c	2013-08-25 20:43:22.000000000 -0400
@@ -224,6 +224,7 @@ int radeon_ib_pool_init(struct radeon_de
 	}
 	r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo,
 				      RADEON_IB_POOL_SIZE*64*1024,
+				      RADEON_GPU_PAGE_SIZE,
 				      RADEON_GEM_DOMAIN_GTT);
 	if (r) {
 		return r;
@@ -357,6 +358,38 @@ bool radeon_ring_supports_scratch_reg(st
 	}
 }
 
+u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev,
+				 struct radeon_ring *ring)
+{
+	u32 rptr;
+
+	if (rdev->wb.enabled && ring != &rdev->ring[R600_RING_TYPE_UVD_INDEX])
+		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+	else
+		rptr = RREG32(ring->rptr_reg);
+	rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+	return rptr;
+}
+
+u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev,
+				 struct radeon_ring *ring)
+{
+	u32 wptr;
+
+	wptr = RREG32(ring->wptr_reg);
+	wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+
+	return wptr;
+}
+
+void radeon_ring_generic_set_wptr(struct radeon_device *rdev,
+				  struct radeon_ring *ring)
+{
+	WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask);
+	(void)RREG32(ring->wptr_reg);
+}
+
 /**
  * radeon_ring_free_size - update the free size
  *
@@ -367,13 +400,7 @@ bool radeon_ring_supports_scratch_reg(st
  */
 void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring)
 {
-	u32 rptr;
-
-	if (rdev->wb.enabled && ring != &rdev->ring[R600_RING_TYPE_UVD_INDEX])
-		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
-	else
-		rptr = RREG32(ring->rptr_reg);
-	ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+	ring->rptr = radeon_ring_get_rptr(rdev, ring);
 	/* This works because ring_size is a power of 2 */
 	ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4));
 	ring->ring_free_dw -= ring->wptr;
@@ -465,8 +492,7 @@ void radeon_ring_commit(struct radeon_de
 		radeon_ring_write(ring, ring->nop);
 	}
 	DRM_MEMORYBARRIER();
-	WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask);
-	(void)RREG32(ring->wptr_reg);
+	radeon_ring_set_wptr(rdev, ring);
 }
 
 /**
@@ -568,7 +594,6 @@ void radeon_ring_lockup_update(struct ra
 bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
 {
 	unsigned long cjiffies, elapsed;
-	uint32_t rptr;
 
 	cjiffies = jiffies;
 	if (!time_after(cjiffies, ring->last_activity)) {
@@ -576,8 +601,7 @@ bool radeon_ring_test_lockup(struct rade
 		radeon_ring_lockup_update(ring);
 		return false;
 	}
-	rptr = RREG32(ring->rptr_reg);
-	ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;
+	ring->rptr = radeon_ring_get_rptr(rdev, ring);
 	if (ring->rptr != ring->last_rptr) {
 		/* CP is still working no lockup */
 		radeon_ring_lockup_update(ring);
@@ -804,9 +828,9 @@ static int radeon_debugfs_ring_info(stru
 
 	radeon_ring_free_size(rdev, ring);
 	count = (ring->ring_size / 4) - ring->ring_free_dw;
-	tmp = RREG32(ring->wptr_reg) >> ring->ptr_reg_shift;
+	tmp = radeon_ring_get_wptr(rdev, ring);
 	seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", ring->wptr_reg, tmp, tmp);
-	tmp = RREG32(ring->rptr_reg) >> ring->ptr_reg_shift;
+	tmp = radeon_ring_get_rptr(rdev, ring);
 	seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", ring->rptr_reg, tmp, tmp);
 	if (ring->rptr_save_reg) {
 		seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_sa.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_sa.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_sa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_sa.c	2013-08-25 20:43:22.000000000 -0400
@@ -49,7 +49,7 @@ static void radeon_sa_bo_try_free(struct
 
 int radeon_sa_bo_manager_init(struct radeon_device *rdev,
 			      struct radeon_sa_manager *sa_manager,
-			      unsigned size, u32 domain)
+			      unsigned size, u32 align, u32 domain)
 {
 	int i, r;
 
@@ -57,13 +57,14 @@ int radeon_sa_bo_manager_init(struct rad
 	sa_manager->bo = NULL;
 	sa_manager->size = size;
 	sa_manager->domain = domain;
+	sa_manager->align = align;
 	sa_manager->hole = &sa_manager->olist;
 	INIT_LIST_HEAD(&sa_manager->olist);
 	for (i = 0; i < RADEON_NUM_RINGS; ++i) {
 		INIT_LIST_HEAD(&sa_manager->flist[i]);
 	}
 
-	r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true,
+	r = radeon_bo_create(rdev, size, align, true,
 			     domain, NULL, &sa_manager->bo);
 	if (r) {
 		dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r);
@@ -317,7 +318,7 @@ int radeon_sa_bo_new(struct radeon_devic
 	unsigned tries[RADEON_NUM_RINGS];
 	int i, r;
 
-	BUG_ON(align > RADEON_GPU_PAGE_SIZE);
+	BUG_ON(align > sa_manager->align);
 	BUG_ON(size > sa_manager->size);
 
 	*sa_bo = kmalloc(sizeof(struct radeon_sa_bo), GFP_KERNEL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_test.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_test.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_test.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_test.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,7 +35,6 @@ static void radeon_do_test_moves(struct
 {
 	struct radeon_bo *vram_obj = NULL;
 	struct radeon_bo **gtt_obj = NULL;
-	struct radeon_fence *fence = NULL;
 	uint64_t gtt_addr, vram_addr;
 	unsigned i, n, size;
 	int r, ring;
@@ -81,37 +80,38 @@ static void radeon_do_test_moves(struct
 	}
 	r = radeon_bo_reserve(vram_obj, false);
 	if (unlikely(r != 0))
-		goto out_cleanup;
+		goto out_unref;
 	r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr);
 	if (r) {
 		DRM_ERROR("Failed to pin VRAM object\n");
-		goto out_cleanup;
+		goto out_unres;
 	}
 	for (i = 0; i < n; i++) {
 		void *gtt_map, *vram_map;
 		void **gtt_start, **gtt_end;
 		void **vram_start, **vram_end;
+		struct radeon_fence *fence = NULL;
 
 		r = radeon_bo_create(rdev, size, PAGE_SIZE, true,
 				     RADEON_GEM_DOMAIN_GTT, NULL, gtt_obj + i);
 		if (r) {
 			DRM_ERROR("Failed to create GTT object %d\n", i);
-			goto out_cleanup;
+			goto out_lclean;
 		}
 
 		r = radeon_bo_reserve(gtt_obj[i], false);
 		if (unlikely(r != 0))
-			goto out_cleanup;
+			goto out_lclean_unref;
 		r = radeon_bo_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, &gtt_addr);
 		if (r) {
 			DRM_ERROR("Failed to pin GTT object %d\n", i);
-			goto out_cleanup;
+			goto out_lclean_unres;
 		}
 
 		r = radeon_bo_kmap(gtt_obj[i], &gtt_map);
 		if (r) {
 			DRM_ERROR("Failed to map GTT object %d\n", i);
-			goto out_cleanup;
+			goto out_lclean_unpin;
 		}
 
 		for (gtt_start = gtt_map, gtt_end = gtt_map + size;
@@ -127,13 +127,13 @@ static void radeon_do_test_moves(struct
 			r = radeon_copy_blit(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
 		if (r) {
 			DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
-			goto out_cleanup;
+			goto out_lclean_unpin;
 		}
 
 		r = radeon_fence_wait(fence, false);
 		if (r) {
 			DRM_ERROR("Failed to wait for GTT->VRAM fence %d\n", i);
-			goto out_cleanup;
+			goto out_lclean_unpin;
 		}
 
 		radeon_fence_unref(&fence);
@@ -141,7 +141,7 @@ static void radeon_do_test_moves(struct
 		r = radeon_bo_kmap(vram_obj, &vram_map);
 		if (r) {
 			DRM_ERROR("Failed to map VRAM object after copy %d\n", i);
-			goto out_cleanup;
+			goto out_lclean_unpin;
 		}
 
 		for (gtt_start = gtt_map, gtt_end = gtt_map + size,
@@ -160,7 +160,7 @@ static void radeon_do_test_moves(struct
 					  (vram_addr - rdev->mc.vram_start +
 					   (void*)gtt_start - gtt_map));
 				radeon_bo_kunmap(vram_obj);
-				goto out_cleanup;
+				goto out_lclean_unpin;
 			}
 			*vram_start = vram_start;
 		}
@@ -173,13 +173,13 @@ static void radeon_do_test_moves(struct
 			r = radeon_copy_blit(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence);
 		if (r) {
 			DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
-			goto out_cleanup;
+			goto out_lclean_unpin;
 		}
 
 		r = radeon_fence_wait(fence, false);
 		if (r) {
 			DRM_ERROR("Failed to wait for VRAM->GTT fence %d\n", i);
-			goto out_cleanup;
+			goto out_lclean_unpin;
 		}
 
 		radeon_fence_unref(&fence);
@@ -187,7 +187,7 @@ static void radeon_do_test_moves(struct
 		r = radeon_bo_kmap(gtt_obj[i], &gtt_map);
 		if (r) {
 			DRM_ERROR("Failed to map GTT object after copy %d\n", i);
-			goto out_cleanup;
+			goto out_lclean_unpin;
 		}
 
 		for (gtt_start = gtt_map, gtt_end = gtt_map + size,
@@ -206,7 +206,7 @@ static void radeon_do_test_moves(struct
 					  (gtt_addr - rdev->mc.gtt_start +
 					   (void*)vram_start - vram_map));
 				radeon_bo_kunmap(gtt_obj[i]);
-				goto out_cleanup;
+				goto out_lclean_unpin;
 			}
 		}
 
@@ -214,31 +214,32 @@ static void radeon_do_test_moves(struct
 
 		DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
 			 gtt_addr - rdev->mc.gtt_start);
-	}
+		continue;
 
-out_cleanup:
-	if (vram_obj) {
-		if (radeon_bo_is_reserved(vram_obj)) {
-			radeon_bo_unpin(vram_obj);
-			radeon_bo_unreserve(vram_obj);
-		}
-		radeon_bo_unref(&vram_obj);
-	}
-	if (gtt_obj) {
-		for (i = 0; i < n; i++) {
-			if (gtt_obj[i]) {
-				if (radeon_bo_is_reserved(gtt_obj[i])) {
-					radeon_bo_unpin(gtt_obj[i]);
-					radeon_bo_unreserve(gtt_obj[i]);
-				}
-				radeon_bo_unref(&gtt_obj[i]);
-			}
+out_lclean_unpin:
+		radeon_bo_unpin(gtt_obj[i]);
+out_lclean_unres:
+		radeon_bo_unreserve(gtt_obj[i]);
+out_lclean_unref:
+		radeon_bo_unref(&gtt_obj[i]);
+out_lclean:
+		for (--i; i >= 0; --i) {
+			radeon_bo_unpin(gtt_obj[i]);
+			radeon_bo_unreserve(gtt_obj[i]);
+			radeon_bo_unref(&gtt_obj[i]);
 		}
-		kfree(gtt_obj);
-	}
-	if (fence) {
-		radeon_fence_unref(&fence);
+		if (fence)
+			radeon_fence_unref(&fence);
+		break;
 	}
+
+	radeon_bo_unpin(vram_obj);
+out_unres:
+	radeon_bo_unreserve(vram_obj);
+out_unref:
+	radeon_bo_unref(&vram_obj);
+out_cleanup:
+	kfree(gtt_obj);
 	if (r) {
 		printk(KERN_WARNING "Error while testing BO move.\n");
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_ucode.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_ucode.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_ucode.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_ucode.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __RADEON_UCODE_H__
+#define __RADEON_UCODE_H__
+
+/* CP */
+#define R600_PFP_UCODE_SIZE          576
+#define R600_PM4_UCODE_SIZE          1792
+#define R700_PFP_UCODE_SIZE          848
+#define R700_PM4_UCODE_SIZE          1360
+#define EVERGREEN_PFP_UCODE_SIZE     1120
+#define EVERGREEN_PM4_UCODE_SIZE     1376
+#define CAYMAN_PFP_UCODE_SIZE        2176
+#define CAYMAN_PM4_UCODE_SIZE        2176
+#define SI_PFP_UCODE_SIZE            2144
+#define SI_PM4_UCODE_SIZE            2144
+#define SI_CE_UCODE_SIZE             2144
+
+/* RLC */
+#define R600_RLC_UCODE_SIZE          768
+#define R700_RLC_UCODE_SIZE          1024
+#define EVERGREEN_RLC_UCODE_SIZE     768
+#define CAYMAN_RLC_UCODE_SIZE        1024
+#define ARUBA_RLC_UCODE_SIZE         1536
+#define SI_RLC_UCODE_SIZE            2048
+
+/* MC */
+#define BTC_MC_UCODE_SIZE            6024
+#define CAYMAN_MC_UCODE_SIZE         6037
+#define SI_MC_UCODE_SIZE             7769
+#define OLAND_MC_UCODE_SIZE          7863
+
+/* SMC */
+#define RV770_SMC_UCODE_START        0x0100
+#define RV770_SMC_UCODE_SIZE         0x410d
+#define RV770_SMC_INT_VECTOR_START   0xffc0
+#define RV770_SMC_INT_VECTOR_SIZE    0x0040
+
+#define RV730_SMC_UCODE_START        0x0100
+#define RV730_SMC_UCODE_SIZE         0x412c
+#define RV730_SMC_INT_VECTOR_START   0xffc0
+#define RV730_SMC_INT_VECTOR_SIZE    0x0040
+
+#define RV710_SMC_UCODE_START        0x0100
+#define RV710_SMC_UCODE_SIZE         0x3f1f
+#define RV710_SMC_INT_VECTOR_START   0xffc0
+#define RV710_SMC_INT_VECTOR_SIZE    0x0040
+
+#define RV740_SMC_UCODE_START        0x0100
+#define RV740_SMC_UCODE_SIZE         0x41c5
+#define RV740_SMC_INT_VECTOR_START   0xffc0
+#define RV740_SMC_INT_VECTOR_SIZE    0x0040
+
+#define CEDAR_SMC_UCODE_START        0x0100
+#define CEDAR_SMC_UCODE_SIZE         0x5d50
+#define CEDAR_SMC_INT_VECTOR_START   0xffc0
+#define CEDAR_SMC_INT_VECTOR_SIZE    0x0040
+
+#define REDWOOD_SMC_UCODE_START      0x0100
+#define REDWOOD_SMC_UCODE_SIZE       0x5f0a
+#define REDWOOD_SMC_INT_VECTOR_START 0xffc0
+#define REDWOOD_SMC_INT_VECTOR_SIZE  0x0040
+
+#define JUNIPER_SMC_UCODE_START      0x0100
+#define JUNIPER_SMC_UCODE_SIZE       0x5f1f
+#define JUNIPER_SMC_INT_VECTOR_START 0xffc0
+#define JUNIPER_SMC_INT_VECTOR_SIZE  0x0040
+
+#define CYPRESS_SMC_UCODE_START      0x0100
+#define CYPRESS_SMC_UCODE_SIZE       0x61f7
+#define CYPRESS_SMC_INT_VECTOR_START 0xffc0
+#define CYPRESS_SMC_INT_VECTOR_SIZE  0x0040
+
+#define BARTS_SMC_UCODE_START        0x0100
+#define BARTS_SMC_UCODE_SIZE         0x6107
+#define BARTS_SMC_INT_VECTOR_START   0xffc0
+#define BARTS_SMC_INT_VECTOR_SIZE    0x0040
+
+#define TURKS_SMC_UCODE_START        0x0100
+#define TURKS_SMC_UCODE_SIZE         0x605b
+#define TURKS_SMC_INT_VECTOR_START   0xffc0
+#define TURKS_SMC_INT_VECTOR_SIZE    0x0040
+
+#define CAICOS_SMC_UCODE_START       0x0100
+#define CAICOS_SMC_UCODE_SIZE        0x5fbd
+#define CAICOS_SMC_INT_VECTOR_START  0xffc0
+#define CAICOS_SMC_INT_VECTOR_SIZE   0x0040
+
+#define CAYMAN_SMC_UCODE_START       0x0100
+#define CAYMAN_SMC_UCODE_SIZE        0x79ec
+#define CAYMAN_SMC_INT_VECTOR_START  0xffc0
+#define CAYMAN_SMC_INT_VECTOR_SIZE   0x0040
+
+#define TAHITI_SMC_UCODE_START       0x10000
+#define TAHITI_SMC_UCODE_SIZE        0xf458
+
+#define PITCAIRN_SMC_UCODE_START     0x10000
+#define PITCAIRN_SMC_UCODE_SIZE      0xe9f4
+
+#define VERDE_SMC_UCODE_START        0x10000
+#define VERDE_SMC_UCODE_SIZE         0xebe4
+
+#define OLAND_SMC_UCODE_START        0x10000
+#define OLAND_SMC_UCODE_SIZE         0xe7b4
+
+#define HAINAN_SMC_UCODE_START       0x10000
+#define HAINAN_SMC_UCODE_SIZE        0xe67C
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_uvd.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_uvd.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/radeon_uvd.c	2013-07-01 10:32:27.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/radeon_uvd.c	2013-08-31 17:51:54.000000000 -0400
@@ -44,6 +44,7 @@
 #define FIRMWARE_CYPRESS	"/*(DEBLOBBED)*/"
 #define FIRMWARE_SUMO		"/*(DEBLOBBED)*/"
 #define FIRMWARE_TAHITI		"/*(DEBLOBBED)*/"
+#define FIRMWARE_BONAIRE	"/*(DEBLOBBED)*/"
 
 /*(DEBLOBBED)*/
 
@@ -51,20 +52,12 @@ static void radeon_uvd_idle_work_handler
 
 int radeon_uvd_init(struct radeon_device *rdev)
 {
-	struct platform_device *pdev;
 	unsigned long bo_size;
 	const char *fw_name;
 	int i, r;
 
 	INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler);
 
-	pdev = platform_device_register_simple("radeon_uvd", 0, NULL, 0);
-	r = IS_ERR(pdev);
-	if (r) {
-		dev_err(rdev->dev, "radeon_uvd: Failed to register firmware\n");
-		return -EINVAL;
-	}
-
 	switch (rdev->family) {
 	case CHIP_RV710:
 	case CHIP_RV730:
@@ -97,20 +90,23 @@ int radeon_uvd_init(struct radeon_device
 		fw_name = FIRMWARE_TAHITI;
 		break;
 
+	case CHIP_BONAIRE:
+	case CHIP_KABINI:
+	case CHIP_KAVERI:
+		fw_name = FIRMWARE_BONAIRE;
+		break;
+
 	default:
 		return -EINVAL;
 	}
 
-	r = reject_firmware(&rdev->uvd_fw, fw_name, &pdev->dev);
+	r = reject_firmware(&rdev->uvd_fw, fw_name, rdev->dev);
 	if (r) {
 		dev_err(rdev->dev, "radeon_uvd: Can't load firmware \"%s\"\n",
 			fw_name);
-		platform_device_unregister(pdev);
 		return r;
 	}
 
-	platform_device_unregister(pdev);
-
 	bo_size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 8) +
 		  RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE;
 	r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true,
@@ -120,16 +116,29 @@ int radeon_uvd_init(struct radeon_device
 		return r;
 	}
 
-	r = radeon_uvd_resume(rdev);
-	if (r)
+	r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
+	if (r) {
+		radeon_bo_unref(&rdev->uvd.vcpu_bo);
+		dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r);
 		return r;
+	}
 
-	memset(rdev->uvd.cpu_addr, 0, bo_size);
-	memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);
+	r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM,
+			  &rdev->uvd.gpu_addr);
+	if (r) {
+		radeon_bo_unreserve(rdev->uvd.vcpu_bo);
+		radeon_bo_unref(&rdev->uvd.vcpu_bo);
+		dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r);
+		return r;
+	}
 
-	r = radeon_uvd_suspend(rdev);
-	if (r)
+	r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr);
+	if (r) {
+		dev_err(rdev->dev, "(%d) UVD map failed\n", r);
 		return r;
+	}
+
+	radeon_bo_unreserve(rdev->uvd.vcpu_bo);
 
 	for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
 		atomic_set(&rdev->uvd.handles[i], 0);
@@ -141,70 +150,73 @@ int radeon_uvd_init(struct radeon_device
 
 void radeon_uvd_fini(struct radeon_device *rdev)
 {
-	radeon_uvd_suspend(rdev);
-	radeon_bo_unref(&rdev->uvd.vcpu_bo);
-}
-
-int radeon_uvd_suspend(struct radeon_device *rdev)
-{
 	int r;
 
 	if (rdev->uvd.vcpu_bo == NULL)
-		return 0;
+		return;
 
 	r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
 	if (!r) {
 		radeon_bo_kunmap(rdev->uvd.vcpu_bo);
 		radeon_bo_unpin(rdev->uvd.vcpu_bo);
-		rdev->uvd.cpu_addr = NULL;
-		if (!radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_CPU, NULL)) {
-			radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr);
-		}
 		radeon_bo_unreserve(rdev->uvd.vcpu_bo);
-
-		if (rdev->uvd.cpu_addr) {
-			radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
-		} else {
-			rdev->fence_drv[R600_RING_TYPE_UVD_INDEX].cpu_addr = NULL;
-		}
 	}
-	return r;
+
+	radeon_bo_unref(&rdev->uvd.vcpu_bo);
+
+	release_firmware(rdev->uvd_fw);
+}
+
+int radeon_uvd_suspend(struct radeon_device *rdev)
+{
+	unsigned size;
+	void *ptr;
+	int i;
+
+	if (rdev->uvd.vcpu_bo == NULL)
+		return 0;
+
+	for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i)
+		if (atomic_read(&rdev->uvd.handles[i]))
+			break;
+
+	if (i == RADEON_MAX_UVD_HANDLES)
+		return 0;
+
+	size = radeon_bo_size(rdev->uvd.vcpu_bo);
+	size -= rdev->uvd_fw->size;
+
+	ptr = rdev->uvd.cpu_addr;
+	ptr += rdev->uvd_fw->size;
+
+	rdev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
+	memcpy(rdev->uvd.saved_bo, ptr, size);
+
+	return 0;
 }
 
 int radeon_uvd_resume(struct radeon_device *rdev)
 {
-	int r;
+	unsigned size;
+	void *ptr;
 
 	if (rdev->uvd.vcpu_bo == NULL)
 		return -EINVAL;
 
-	r = radeon_bo_reserve(rdev->uvd.vcpu_bo, false);
-	if (r) {
-		radeon_bo_unref(&rdev->uvd.vcpu_bo);
-		dev_err(rdev->dev, "(%d) failed to reserve UVD bo\n", r);
-		return r;
-	}
-
-	/* Have been pin in cpu unmap unpin */
-	radeon_bo_kunmap(rdev->uvd.vcpu_bo);
-	radeon_bo_unpin(rdev->uvd.vcpu_bo);
+	memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size);
 
-	r = radeon_bo_pin(rdev->uvd.vcpu_bo, RADEON_GEM_DOMAIN_VRAM,
-			  &rdev->uvd.gpu_addr);
-	if (r) {
-		radeon_bo_unreserve(rdev->uvd.vcpu_bo);
-		radeon_bo_unref(&rdev->uvd.vcpu_bo);
-		dev_err(rdev->dev, "(%d) UVD bo pin failed\n", r);
-		return r;
-	}
+	size = radeon_bo_size(rdev->uvd.vcpu_bo);
+	size -= rdev->uvd_fw->size;
 
-	r = radeon_bo_kmap(rdev->uvd.vcpu_bo, &rdev->uvd.cpu_addr);
-	if (r) {
-		dev_err(rdev->dev, "(%d) UVD map failed\n", r);
-		return r;
-	}
+	ptr = rdev->uvd.cpu_addr;
+	ptr += rdev->uvd_fw->size;
 
-	radeon_bo_unreserve(rdev->uvd.vcpu_bo);
+	if (rdev->uvd.saved_bo != NULL) {
+		memcpy(ptr, rdev->uvd.saved_bo, size);
+		kfree(rdev->uvd.saved_bo);
+		rdev->uvd.saved_bo = NULL;
+	} else
+		memset(ptr, 0, size);
 
 	return 0;
 }
@@ -219,8 +231,8 @@ void radeon_uvd_free_handles(struct rade
 {
 	int i, r;
 	for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
-		if (rdev->uvd.filp[i] == filp) {
-			uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
+		uint32_t handle = atomic_read(&rdev->uvd.handles[i]);
+		if (handle != 0 && rdev->uvd.filp[i] == filp) {
 			struct radeon_fence *fence;
 
 			r = radeon_uvd_get_destroy_msg(rdev,
@@ -340,9 +352,19 @@ static int radeon_uvd_cs_msg(struct rade
 		return -EINVAL;
 	}
 
+	if (bo->tbo.sync_obj) {
+		r = radeon_fence_wait(bo->tbo.sync_obj, false);
+		if (r) {
+			DRM_ERROR("Failed waiting for UVD message (%d)!\n", r);
+			return r;
+		}
+	}
+
 	r = radeon_bo_kmap(bo, &ptr);
-	if (r)
+	if (r) {
+		DRM_ERROR("Failed mapping the UVD message (%d)!\n", r);
 		return r;
+	}
 
 	msg = ptr + offset;
 
@@ -368,8 +390,14 @@ static int radeon_uvd_cs_msg(struct rade
 		radeon_bo_kunmap(bo);
 		return 0;
 	} else {
-		/* it's a create msg, no special handling needed */
 		radeon_bo_kunmap(bo);
+
+		if (msg_type != 0) {
+			DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
+			return -EINVAL;
+		}
+
+		/* it's a create msg, no special handling needed */
 	}
 
 	/* create or decode, validate the handle */
@@ -392,7 +420,7 @@ static int radeon_uvd_cs_msg(struct rade
 
 static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p,
 			       int data0, int data1,
-			       unsigned buf_sizes[])
+			       unsigned buf_sizes[], bool *has_msg_cmd)
 {
 	struct radeon_cs_chunk *relocs_chunk;
 	struct radeon_cs_reloc *reloc;
@@ -421,7 +449,7 @@ static int radeon_uvd_cs_reloc(struct ra
 
 	if (cmd < 0x4) {
 		if ((end - start) < buf_sizes[cmd]) {
-			DRM_ERROR("buffer to small (%d / %d)!\n",
+			DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd,
 				  (unsigned)(end - start), buf_sizes[cmd]);
 			return -EINVAL;
 		}
@@ -446,9 +474,17 @@ static int radeon_uvd_cs_reloc(struct ra
 	}
 
 	if (cmd == 0) {
+		if (*has_msg_cmd) {
+			DRM_ERROR("More than one message in a UVD-IB!\n");
+			return -EINVAL;
+		}
+		*has_msg_cmd = true;
 		r = radeon_uvd_cs_msg(p, reloc->robj, offset, buf_sizes);
 		if (r)
 			return r;
+	} else if (!*has_msg_cmd) {
+		DRM_ERROR("Message needed before other commands are send!\n");
+		return -EINVAL;
 	}
 
 	return 0;
@@ -457,7 +493,8 @@ static int radeon_uvd_cs_reloc(struct ra
 static int radeon_uvd_cs_reg(struct radeon_cs_parser *p,
 			     struct radeon_cs_packet *pkt,
 			     int *data0, int *data1,
-			     unsigned buf_sizes[])
+			     unsigned buf_sizes[],
+			     bool *has_msg_cmd)
 {
 	int i, r;
 
@@ -471,7 +508,8 @@ static int radeon_uvd_cs_reg(struct rade
 			*data1 = p->idx;
 			break;
 		case UVD_GPCOM_VCPU_CMD:
-			r = radeon_uvd_cs_reloc(p, *data0, *data1, buf_sizes);
+			r = radeon_uvd_cs_reloc(p, *data0, *data1,
+						buf_sizes, has_msg_cmd);
 			if (r)
 				return r;
 			break;
@@ -492,6 +530,9 @@ int radeon_uvd_cs_parse(struct radeon_cs
 	struct radeon_cs_packet pkt;
 	int r, data0 = 0, data1 = 0;
 
+	/* does the IB has a msg command */
+	bool has_msg_cmd = false;
+
 	/* minimum buffer sizes */
 	unsigned buf_sizes[] = {
 		[0x00000000]	=	2048,
@@ -518,8 +559,8 @@ int radeon_uvd_cs_parse(struct radeon_cs
 			return r;
 		switch (pkt.type) {
 		case RADEON_PACKET_TYPE0:
-			r = radeon_uvd_cs_reg(p, &pkt, &data0,
-					      &data1, buf_sizes);
+			r = radeon_uvd_cs_reg(p, &pkt, &data0, &data1,
+					      buf_sizes, &has_msg_cmd);
 			if (r)
 				return r;
 			break;
@@ -531,6 +572,12 @@ int radeon_uvd_cs_parse(struct radeon_cs
 			return -EINVAL;
 		}
 	} while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
+
+	if (!has_msg_cmd) {
+		DRM_ERROR("UVD-IBs need a msg command!\n");
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
@@ -539,6 +586,7 @@ static int radeon_uvd_send_msg(struct ra
 			       struct radeon_fence **fence)
 {
 	struct ttm_validate_buffer tv;
+	struct ww_acquire_ctx ticket;
 	struct list_head head;
 	struct radeon_ib ib;
 	uint64_t addr;
@@ -550,7 +598,7 @@ static int radeon_uvd_send_msg(struct ra
 	INIT_LIST_HEAD(&head);
 	list_add(&tv.head, &head);
 
-	r = ttm_eu_reserve_buffers(&head);
+	r = ttm_eu_reserve_buffers(&ticket, &head);
 	if (r)
 		return r;
 
@@ -558,16 +606,12 @@ static int radeon_uvd_send_msg(struct ra
 	radeon_uvd_force_into_uvd_segment(bo);
 
 	r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
-	if (r) {
-		ttm_eu_backoff_reservation(&head);
-		return r;
-	}
+	if (r) 
+		goto err;
 
 	r = radeon_ib_get(rdev, ring, &ib, NULL, 16);
-	if (r) {
-		ttm_eu_backoff_reservation(&head);
-		return r;
-	}
+	if (r)
+		goto err;
 
 	addr = radeon_bo_gpu_offset(bo);
 	ib.ptr[0] = PACKET0(UVD_GPCOM_VCPU_DATA0, 0);
@@ -581,11 +625,9 @@ static int radeon_uvd_send_msg(struct ra
 	ib.length_dw = 16;
 
 	r = radeon_ib_schedule(rdev, &ib, NULL);
-	if (r) {
-		ttm_eu_backoff_reservation(&head);
-		return r;
-	}
-	ttm_eu_fence_buffer_objects(&head, ib.fence);
+	if (r)
+		goto err;
+	ttm_eu_fence_buffer_objects(&ticket, &head, ib.fence);
 
 	if (fence)
 		*fence = radeon_fence_ref(ib.fence);
@@ -593,6 +635,10 @@ static int radeon_uvd_send_msg(struct ra
 	radeon_ib_free(rdev, &ib);
 	radeon_bo_unref(&bo);
 	return 0;
+
+err:
+	ttm_eu_backoff_reservation(&ticket, &head);
+	return r;
 }
 
 /* multiple fence commands without any stream commands in between can
@@ -688,11 +734,19 @@ static void radeon_uvd_idle_work_handler
 	struct radeon_device *rdev =
 		container_of(work, struct radeon_device, uvd.idle_work.work);
 
-	if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0)
-		radeon_set_uvd_clocks(rdev, 0, 0);
-	else
+	if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0) {
+		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
+			mutex_lock(&rdev->pm.mutex);
+			rdev->pm.dpm.uvd_active = false;
+			mutex_unlock(&rdev->pm.mutex);
+			radeon_pm_compute_clocks(rdev);
+		} else {
+			radeon_set_uvd_clocks(rdev, 0, 0);
+		}
+	} else {
 		schedule_delayed_work(&rdev->uvd.idle_work,
 				      msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
+	}
 }
 
 void radeon_uvd_note_usage(struct radeon_device *rdev)
@@ -700,8 +754,14 @@ void radeon_uvd_note_usage(struct radeon
 	bool set_clocks = !cancel_delayed_work_sync(&rdev->uvd.idle_work);
 	set_clocks &= schedule_delayed_work(&rdev->uvd.idle_work,
 					    msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
-	if (set_clocks)
-		radeon_set_uvd_clocks(rdev, 53300, 40000);
+	if (set_clocks) {
+		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
+			/* XXX pick SD/HD/MVC */
+			radeon_dpm_enable_power_state(rdev, POWER_STATE_TYPE_INTERNAL_UVD);
+		} else {
+			radeon_set_uvd_clocks(rdev, 53300, 40000);
+		}
+	}
 }
 
 static unsigned radeon_uvd_calc_upll_post_div(unsigned vco_freq,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rs690.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rs690.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rs690.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rs690.c	2013-08-25 20:43:22.000000000 -0400
@@ -248,13 +248,16 @@ struct rs690_watermark {
 };
 
 static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,
-				  struct radeon_crtc *crtc,
-				  struct rs690_watermark *wm)
+					 struct radeon_crtc *crtc,
+					 struct rs690_watermark *wm,
+					 bool low)
 {
 	struct drm_display_mode *mode = &crtc->base.mode;
 	fixed20_12 a, b, c;
 	fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width;
 	fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency;
+	fixed20_12 sclk, core_bandwidth, max_bandwidth;
+	u32 selected_sclk;
 
 	if (!crtc->base.enabled) {
 		/* FIXME: wouldn't it better to set priority mark to maximum */
@@ -262,6 +265,21 @@ static void rs690_crtc_bandwidth_compute
 		return;
 	}
 
+	if (((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880)) &&
+	    (rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled)
+		selected_sclk = radeon_dpm_get_sclk(rdev, low);
+	else
+		selected_sclk = rdev->pm.current_sclk;
+
+	/* sclk in Mhz */
+	a.full = dfixed_const(100);
+	sclk.full = dfixed_const(selected_sclk);
+	sclk.full = dfixed_div(sclk, a);
+
+	/* core_bandwidth = sclk(Mhz) * 16 */
+	a.full = dfixed_const(16);
+	core_bandwidth.full = dfixed_div(rdev->pm.sclk, a);
+
 	if (crtc->vsc.full > dfixed_const(2))
 		wm->num_line_pair.full = dfixed_const(2);
 	else
@@ -322,36 +340,36 @@ static void rs690_crtc_bandwidth_compute
 	wm->active_time.full = dfixed_div(wm->active_time, a);
 
 	/* Maximun bandwidth is the minimun bandwidth of all component */
-	rdev->pm.max_bandwidth = rdev->pm.core_bandwidth;
+	max_bandwidth = core_bandwidth;
 	if (rdev->mc.igp_sideport_enabled) {
-		if (rdev->pm.max_bandwidth.full > rdev->pm.sideport_bandwidth.full &&
+		if (max_bandwidth.full > rdev->pm.sideport_bandwidth.full &&
 			rdev->pm.sideport_bandwidth.full)
-			rdev->pm.max_bandwidth = rdev->pm.sideport_bandwidth;
+			max_bandwidth = rdev->pm.sideport_bandwidth;
 		read_delay_latency.full = dfixed_const(370 * 800 * 1000);
 		read_delay_latency.full = dfixed_div(read_delay_latency,
 			rdev->pm.igp_sideport_mclk);
 	} else {
-		if (rdev->pm.max_bandwidth.full > rdev->pm.k8_bandwidth.full &&
+		if (max_bandwidth.full > rdev->pm.k8_bandwidth.full &&
 			rdev->pm.k8_bandwidth.full)
-			rdev->pm.max_bandwidth = rdev->pm.k8_bandwidth;
-		if (rdev->pm.max_bandwidth.full > rdev->pm.ht_bandwidth.full &&
+			max_bandwidth = rdev->pm.k8_bandwidth;
+		if (max_bandwidth.full > rdev->pm.ht_bandwidth.full &&
 			rdev->pm.ht_bandwidth.full)
-			rdev->pm.max_bandwidth = rdev->pm.ht_bandwidth;
+			max_bandwidth = rdev->pm.ht_bandwidth;
 		read_delay_latency.full = dfixed_const(5000);
 	}
 
 	/* sclk = system clocks(ns) = 1000 / max_bandwidth / 16 */
 	a.full = dfixed_const(16);
-	rdev->pm.sclk.full = dfixed_mul(rdev->pm.max_bandwidth, a);
+	sclk.full = dfixed_mul(max_bandwidth, a);
 	a.full = dfixed_const(1000);
-	rdev->pm.sclk.full = dfixed_div(a, rdev->pm.sclk);
+	sclk.full = dfixed_div(a, sclk);
 	/* Determine chunk time
 	 * ChunkTime = the time it takes the DCP to send one chunk of data
 	 * to the LB which consists of pipeline delay and inter chunk gap
 	 * sclk = system clock(ns)
 	 */
 	a.full = dfixed_const(256 * 13);
-	chunk_time.full = dfixed_mul(rdev->pm.sclk, a);
+	chunk_time.full = dfixed_mul(sclk, a);
 	a.full = dfixed_const(10);
 	chunk_time.full = dfixed_div(chunk_time, a);
 
@@ -415,175 +433,200 @@ static void rs690_crtc_bandwidth_compute
 	}
 }
 
-void rs690_bandwidth_update(struct radeon_device *rdev)
+static void rs690_compute_mode_priority(struct radeon_device *rdev,
+					struct rs690_watermark *wm0,
+					struct rs690_watermark *wm1,
+					struct drm_display_mode *mode0,
+					struct drm_display_mode *mode1,
+					u32 *d1mode_priority_a_cnt,
+					u32 *d2mode_priority_a_cnt)
 {
-	struct drm_display_mode *mode0 = NULL;
-	struct drm_display_mode *mode1 = NULL;
-	struct rs690_watermark wm0;
-	struct rs690_watermark wm1;
-	u32 tmp;
-	u32 d1mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
-	u32 d2mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
 	fixed20_12 priority_mark02, priority_mark12, fill_rate;
 	fixed20_12 a, b;
 
-	radeon_update_display_priority(rdev);
-
-	if (rdev->mode_info.crtcs[0]->base.enabled)
-		mode0 = &rdev->mode_info.crtcs[0]->base.mode;
-	if (rdev->mode_info.crtcs[1]->base.enabled)
-		mode1 = &rdev->mode_info.crtcs[1]->base.mode;
-	/*
-	 * Set display0/1 priority up in the memory controller for
-	 * modes if the user specifies HIGH for displaypriority
-	 * option.
-	 */
-	if ((rdev->disp_priority == 2) &&
-	    ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))) {
-		tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER);
-		tmp &= C_000104_MC_DISP0R_INIT_LAT;
-		tmp &= C_000104_MC_DISP1R_INIT_LAT;
-		if (mode0)
-			tmp |= S_000104_MC_DISP0R_INIT_LAT(1);
-		if (mode1)
-			tmp |= S_000104_MC_DISP1R_INIT_LAT(1);
-		WREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER, tmp);
-	}
-	rs690_line_buffer_adjust(rdev, mode0, mode1);
-
-	if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))
-		WREG32(R_006C9C_DCP_CONTROL, 0);
-	if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
-		WREG32(R_006C9C_DCP_CONTROL, 2);
-
-	rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0);
-	rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1);
-
-	tmp = (wm0.lb_request_fifo_depth - 1);
-	tmp |= (wm1.lb_request_fifo_depth - 1) << 16;
-	WREG32(R_006D58_LB_MAX_REQ_OUTSTANDING, tmp);
+	*d1mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
+	*d2mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1);
 
 	if (mode0 && mode1) {
-		if (dfixed_trunc(wm0.dbpp) > 64)
-			a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair);
+		if (dfixed_trunc(wm0->dbpp) > 64)
+			a.full = dfixed_mul(wm0->dbpp, wm0->num_line_pair);
 		else
-			a.full = wm0.num_line_pair.full;
-		if (dfixed_trunc(wm1.dbpp) > 64)
-			b.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair);
+			a.full = wm0->num_line_pair.full;
+		if (dfixed_trunc(wm1->dbpp) > 64)
+			b.full = dfixed_mul(wm1->dbpp, wm1->num_line_pair);
 		else
-			b.full = wm1.num_line_pair.full;
+			b.full = wm1->num_line_pair.full;
 		a.full += b.full;
-		fill_rate.full = dfixed_div(wm0.sclk, a);
-		if (wm0.consumption_rate.full > fill_rate.full) {
-			b.full = wm0.consumption_rate.full - fill_rate.full;
-			b.full = dfixed_mul(b, wm0.active_time);
-			a.full = dfixed_mul(wm0.worst_case_latency,
-						wm0.consumption_rate);
+		fill_rate.full = dfixed_div(wm0->sclk, a);
+		if (wm0->consumption_rate.full > fill_rate.full) {
+			b.full = wm0->consumption_rate.full - fill_rate.full;
+			b.full = dfixed_mul(b, wm0->active_time);
+			a.full = dfixed_mul(wm0->worst_case_latency,
+						wm0->consumption_rate);
 			a.full = a.full + b.full;
 			b.full = dfixed_const(16 * 1000);
 			priority_mark02.full = dfixed_div(a, b);
 		} else {
-			a.full = dfixed_mul(wm0.worst_case_latency,
-						wm0.consumption_rate);
+			a.full = dfixed_mul(wm0->worst_case_latency,
+						wm0->consumption_rate);
 			b.full = dfixed_const(16 * 1000);
 			priority_mark02.full = dfixed_div(a, b);
 		}
-		if (wm1.consumption_rate.full > fill_rate.full) {
-			b.full = wm1.consumption_rate.full - fill_rate.full;
-			b.full = dfixed_mul(b, wm1.active_time);
-			a.full = dfixed_mul(wm1.worst_case_latency,
-						wm1.consumption_rate);
+		if (wm1->consumption_rate.full > fill_rate.full) {
+			b.full = wm1->consumption_rate.full - fill_rate.full;
+			b.full = dfixed_mul(b, wm1->active_time);
+			a.full = dfixed_mul(wm1->worst_case_latency,
+						wm1->consumption_rate);
 			a.full = a.full + b.full;
 			b.full = dfixed_const(16 * 1000);
 			priority_mark12.full = dfixed_div(a, b);
 		} else {
-			a.full = dfixed_mul(wm1.worst_case_latency,
-						wm1.consumption_rate);
+			a.full = dfixed_mul(wm1->worst_case_latency,
+						wm1->consumption_rate);
 			b.full = dfixed_const(16 * 1000);
 			priority_mark12.full = dfixed_div(a, b);
 		}
-		if (wm0.priority_mark.full > priority_mark02.full)
-			priority_mark02.full = wm0.priority_mark.full;
+		if (wm0->priority_mark.full > priority_mark02.full)
+			priority_mark02.full = wm0->priority_mark.full;
 		if (dfixed_trunc(priority_mark02) < 0)
 			priority_mark02.full = 0;
-		if (wm0.priority_mark_max.full > priority_mark02.full)
-			priority_mark02.full = wm0.priority_mark_max.full;
-		if (wm1.priority_mark.full > priority_mark12.full)
-			priority_mark12.full = wm1.priority_mark.full;
+		if (wm0->priority_mark_max.full > priority_mark02.full)
+			priority_mark02.full = wm0->priority_mark_max.full;
+		if (wm1->priority_mark.full > priority_mark12.full)
+			priority_mark12.full = wm1->priority_mark.full;
 		if (dfixed_trunc(priority_mark12) < 0)
 			priority_mark12.full = 0;
-		if (wm1.priority_mark_max.full > priority_mark12.full)
-			priority_mark12.full = wm1.priority_mark_max.full;
-		d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
-		d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
+		if (wm1->priority_mark_max.full > priority_mark12.full)
+			priority_mark12.full = wm1->priority_mark_max.full;
+		*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
+		*d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
 		if (rdev->disp_priority == 2) {
-			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
-			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
+			*d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+			*d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
 		}
 	} else if (mode0) {
-		if (dfixed_trunc(wm0.dbpp) > 64)
-			a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair);
+		if (dfixed_trunc(wm0->dbpp) > 64)
+			a.full = dfixed_mul(wm0->dbpp, wm0->num_line_pair);
 		else
-			a.full = wm0.num_line_pair.full;
-		fill_rate.full = dfixed_div(wm0.sclk, a);
-		if (wm0.consumption_rate.full > fill_rate.full) {
-			b.full = wm0.consumption_rate.full - fill_rate.full;
-			b.full = dfixed_mul(b, wm0.active_time);
-			a.full = dfixed_mul(wm0.worst_case_latency,
-						wm0.consumption_rate);
+			a.full = wm0->num_line_pair.full;
+		fill_rate.full = dfixed_div(wm0->sclk, a);
+		if (wm0->consumption_rate.full > fill_rate.full) {
+			b.full = wm0->consumption_rate.full - fill_rate.full;
+			b.full = dfixed_mul(b, wm0->active_time);
+			a.full = dfixed_mul(wm0->worst_case_latency,
+						wm0->consumption_rate);
 			a.full = a.full + b.full;
 			b.full = dfixed_const(16 * 1000);
 			priority_mark02.full = dfixed_div(a, b);
 		} else {
-			a.full = dfixed_mul(wm0.worst_case_latency,
-						wm0.consumption_rate);
+			a.full = dfixed_mul(wm0->worst_case_latency,
+						wm0->consumption_rate);
 			b.full = dfixed_const(16 * 1000);
 			priority_mark02.full = dfixed_div(a, b);
 		}
-		if (wm0.priority_mark.full > priority_mark02.full)
-			priority_mark02.full = wm0.priority_mark.full;
+		if (wm0->priority_mark.full > priority_mark02.full)
+			priority_mark02.full = wm0->priority_mark.full;
 		if (dfixed_trunc(priority_mark02) < 0)
 			priority_mark02.full = 0;
-		if (wm0.priority_mark_max.full > priority_mark02.full)
-			priority_mark02.full = wm0.priority_mark_max.full;
-		d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
+		if (wm0->priority_mark_max.full > priority_mark02.full)
+			priority_mark02.full = wm0->priority_mark_max.full;
+		*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
 		if (rdev->disp_priority == 2)
-			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
+			*d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1);
 	} else if (mode1) {
-		if (dfixed_trunc(wm1.dbpp) > 64)
-			a.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair);
+		if (dfixed_trunc(wm1->dbpp) > 64)
+			a.full = dfixed_mul(wm1->dbpp, wm1->num_line_pair);
 		else
-			a.full = wm1.num_line_pair.full;
-		fill_rate.full = dfixed_div(wm1.sclk, a);
-		if (wm1.consumption_rate.full > fill_rate.full) {
-			b.full = wm1.consumption_rate.full - fill_rate.full;
-			b.full = dfixed_mul(b, wm1.active_time);
-			a.full = dfixed_mul(wm1.worst_case_latency,
-						wm1.consumption_rate);
+			a.full = wm1->num_line_pair.full;
+		fill_rate.full = dfixed_div(wm1->sclk, a);
+		if (wm1->consumption_rate.full > fill_rate.full) {
+			b.full = wm1->consumption_rate.full - fill_rate.full;
+			b.full = dfixed_mul(b, wm1->active_time);
+			a.full = dfixed_mul(wm1->worst_case_latency,
+						wm1->consumption_rate);
 			a.full = a.full + b.full;
 			b.full = dfixed_const(16 * 1000);
 			priority_mark12.full = dfixed_div(a, b);
 		} else {
-			a.full = dfixed_mul(wm1.worst_case_latency,
-						wm1.consumption_rate);
+			a.full = dfixed_mul(wm1->worst_case_latency,
+						wm1->consumption_rate);
 			b.full = dfixed_const(16 * 1000);
 			priority_mark12.full = dfixed_div(a, b);
 		}
-		if (wm1.priority_mark.full > priority_mark12.full)
-			priority_mark12.full = wm1.priority_mark.full;
+		if (wm1->priority_mark.full > priority_mark12.full)
+			priority_mark12.full = wm1->priority_mark.full;
 		if (dfixed_trunc(priority_mark12) < 0)
 			priority_mark12.full = 0;
-		if (wm1.priority_mark_max.full > priority_mark12.full)
-			priority_mark12.full = wm1.priority_mark_max.full;
-		d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
+		if (wm1->priority_mark_max.full > priority_mark12.full)
+			priority_mark12.full = wm1->priority_mark_max.full;
+		*d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
 		if (rdev->disp_priority == 2)
-			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
+			*d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);
+	}
+}
+
+void rs690_bandwidth_update(struct radeon_device *rdev)
+{
+	struct drm_display_mode *mode0 = NULL;
+	struct drm_display_mode *mode1 = NULL;
+	struct rs690_watermark wm0_high, wm0_low;
+	struct rs690_watermark wm1_high, wm1_low;
+	u32 tmp;
+	u32 d1mode_priority_a_cnt, d1mode_priority_b_cnt;
+	u32 d2mode_priority_a_cnt, d2mode_priority_b_cnt;
+
+	radeon_update_display_priority(rdev);
+
+	if (rdev->mode_info.crtcs[0]->base.enabled)
+		mode0 = &rdev->mode_info.crtcs[0]->base.mode;
+	if (rdev->mode_info.crtcs[1]->base.enabled)
+		mode1 = &rdev->mode_info.crtcs[1]->base.mode;
+	/*
+	 * Set display0/1 priority up in the memory controller for
+	 * modes if the user specifies HIGH for displaypriority
+	 * option.
+	 */
+	if ((rdev->disp_priority == 2) &&
+	    ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))) {
+		tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER);
+		tmp &= C_000104_MC_DISP0R_INIT_LAT;
+		tmp &= C_000104_MC_DISP1R_INIT_LAT;
+		if (mode0)
+			tmp |= S_000104_MC_DISP0R_INIT_LAT(1);
+		if (mode1)
+			tmp |= S_000104_MC_DISP1R_INIT_LAT(1);
+		WREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER, tmp);
 	}
+	rs690_line_buffer_adjust(rdev, mode0, mode1);
+
+	if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))
+		WREG32(R_006C9C_DCP_CONTROL, 0);
+	if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
+		WREG32(R_006C9C_DCP_CONTROL, 2);
+
+	rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0_high, false);
+	rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1_high, false);
+
+	rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0_low, true);
+	rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1_low, true);
+
+	tmp = (wm0_high.lb_request_fifo_depth - 1);
+	tmp |= (wm1_high.lb_request_fifo_depth - 1) << 16;
+	WREG32(R_006D58_LB_MAX_REQ_OUTSTANDING, tmp);
+
+	rs690_compute_mode_priority(rdev,
+				    &wm0_high, &wm1_high,
+				    mode0, mode1,
+				    &d1mode_priority_a_cnt, &d2mode_priority_a_cnt);
+	rs690_compute_mode_priority(rdev,
+				    &wm0_low, &wm1_low,
+				    mode0, mode1,
+				    &d1mode_priority_b_cnt, &d2mode_priority_b_cnt);
 
 	WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-	WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+	WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_b_cnt);
 	WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-	WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
+	WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_b_cnt);
 }
 
 uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rs780d.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rs780d.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rs780d.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rs780d.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __RS780D_H__
+#define __RS780D_H__
+
+#define CG_SPLL_FUNC_CNTL                                 0x600
+#       define SPLL_RESET                                (1 << 0)
+#       define SPLL_SLEEP                                (1 << 1)
+#       define SPLL_REF_DIV(x)                           ((x) << 2)
+#       define SPLL_REF_DIV_MASK                         (7 << 2)
+#       define SPLL_REF_DIV_SHIFT                        2
+#       define SPLL_FB_DIV(x)                            ((x) << 5)
+#       define SPLL_FB_DIV_MASK                          (0xff << 2)
+#       define SPLL_FB_DIV_SHIFT                         2
+#       define SPLL_PULSEEN                              (1 << 13)
+#       define SPLL_PULSENUM(x)                          ((x) << 14)
+#       define SPLL_PULSENUM_MASK                        (3 << 14)
+#       define SPLL_SW_HILEN(x)                          ((x) << 16)
+#       define SPLL_SW_HILEN_MASK                        (0xf << 16)
+#       define SPLL_SW_HILEN_SHIFT                       16
+#       define SPLL_SW_LOLEN(x)                          ((x) << 20)
+#       define SPLL_SW_LOLEN_MASK                        (0xf << 20)
+#       define SPLL_SW_LOLEN_SHIFT                       20
+#       define SPLL_DIVEN                                (1 << 24)
+#       define SPLL_BYPASS_EN                            (1 << 25)
+#       define SPLL_CHG_STATUS                           (1 << 29)
+#       define SPLL_CTLREQ                               (1 << 30)
+#       define SPLL_CTLACK                               (1 << 31)
+
+/* RS780/RS880 PM */
+#define	FVTHROT_CNTRL_REG				0x3000
+#define		DONT_WAIT_FOR_FBDIV_WRAP		(1 << 0)
+#define		MINIMUM_CIP(x)				((x) << 1)
+#define		MINIMUM_CIP_SHIFT			1
+#define		MINIMUM_CIP_MASK			0x1fffffe
+#define		REFRESH_RATE_DIVISOR(x)			((x) << 25)
+#define		REFRESH_RATE_DIVISOR_SHIFT		25
+#define		REFRESH_RATE_DIVISOR_MASK		(0x3 << 25)
+#define		ENABLE_FV_THROT				(1 << 27)
+#define		ENABLE_FV_UPDATE			(1 << 28)
+#define		TREND_SEL_MODE				(1 << 29)
+#define		FORCE_TREND_SEL				(1 << 30)
+#define		ENABLE_FV_THROT_IO			(1 << 31)
+#define	FVTHROT_TARGET_REG				0x3004
+#define		TARGET_IDLE_COUNT(x)			((x) << 0)
+#define		TARGET_IDLE_COUNT_MASK			0xffffff
+#define		TARGET_IDLE_COUNT_SHIFT			0
+#define	FVTHROT_CB1					0x3008
+#define	FVTHROT_CB2					0x300c
+#define	FVTHROT_CB3					0x3010
+#define	FVTHROT_CB4					0x3014
+#define	FVTHROT_UTC0					0x3018
+#define	FVTHROT_UTC1					0x301c
+#define	FVTHROT_UTC2					0x3020
+#define	FVTHROT_UTC3					0x3024
+#define	FVTHROT_UTC4					0x3028
+#define	FVTHROT_DTC0					0x302c
+#define	FVTHROT_DTC1					0x3030
+#define	FVTHROT_DTC2					0x3034
+#define	FVTHROT_DTC3					0x3038
+#define	FVTHROT_DTC4					0x303c
+#define	FVTHROT_FBDIV_REG0				0x3040
+#define		MIN_FEEDBACK_DIV(x)			((x) << 0)
+#define		MIN_FEEDBACK_DIV_MASK			0xfff
+#define		MIN_FEEDBACK_DIV_SHIFT			0
+#define		MAX_FEEDBACK_DIV(x)			((x) << 12)
+#define		MAX_FEEDBACK_DIV_MASK			(0xfff << 12)
+#define		MAX_FEEDBACK_DIV_SHIFT			12
+#define	FVTHROT_FBDIV_REG1				0x3044
+#define		MAX_FEEDBACK_STEP(x)			((x) << 0)
+#define		MAX_FEEDBACK_STEP_MASK			0xfff
+#define		MAX_FEEDBACK_STEP_SHIFT			0
+#define		STARTING_FEEDBACK_DIV(x)		((x) << 12)
+#define		STARTING_FEEDBACK_DIV_MASK		(0xfff << 12)
+#define		STARTING_FEEDBACK_DIV_SHIFT		12
+#define		FORCE_FEEDBACK_DIV			(1 << 24)
+#define	FVTHROT_FBDIV_REG2				0x3048
+#define		FORCED_FEEDBACK_DIV(x)			((x) << 0)
+#define		FORCED_FEEDBACK_DIV_MASK		0xfff
+#define		FORCED_FEEDBACK_DIV_SHIFT		0
+#define		FB_DIV_TIMER_VAL(x)			((x) << 12)
+#define		FB_DIV_TIMER_VAL_MASK			(0xffff << 12)
+#define		FB_DIV_TIMER_VAL_SHIFT			12
+#define	FVTHROT_FB_US_REG0				0x304c
+#define	FVTHROT_FB_US_REG1				0x3050
+#define	FVTHROT_FB_DS_REG0				0x3054
+#define	FVTHROT_FB_DS_REG1				0x3058
+#define	FVTHROT_PWM_CTRL_REG0				0x305c
+#define		STARTING_PWM_HIGHTIME(x)		((x) << 0)
+#define		STARTING_PWM_HIGHTIME_MASK		0xfff
+#define		STARTING_PWM_HIGHTIME_SHIFT		0
+#define		NUMBER_OF_CYCLES_IN_PERIOD(x)		((x) << 12)
+#define		NUMBER_OF_CYCLES_IN_PERIOD_MASK		(0xfff << 12)
+#define		NUMBER_OF_CYCLES_IN_PERIOD_SHIFT	12
+#define		FORCE_STARTING_PWM_HIGHTIME		(1 << 24)
+#define		INVERT_PWM_WAVEFORM			(1 << 25)
+#define	FVTHROT_PWM_CTRL_REG1				0x3060
+#define		MIN_PWM_HIGHTIME(x)			((x) << 0)
+#define		MIN_PWM_HIGHTIME_MASK			0xfff
+#define		MIN_PWM_HIGHTIME_SHIFT			0
+#define		MAX_PWM_HIGHTIME(x)			((x) << 12)
+#define		MAX_PWM_HIGHTIME_MASK			(0xfff << 12)
+#define		MAX_PWM_HIGHTIME_SHIFT			12
+#define	FVTHROT_PWM_US_REG0				0x3064
+#define	FVTHROT_PWM_US_REG1				0x3068
+#define	FVTHROT_PWM_DS_REG0				0x306c
+#define	FVTHROT_PWM_DS_REG1				0x3070
+#define	FVTHROT_STATUS_REG0				0x3074
+#define		CURRENT_FEEDBACK_DIV_MASK		0xfff
+#define		CURRENT_FEEDBACK_DIV_SHIFT		0
+#define	FVTHROT_STATUS_REG1				0x3078
+#define	FVTHROT_STATUS_REG2				0x307c
+#define	CG_INTGFX_MISC					0x3080
+#define		FVTHROT_VBLANK_SEL			(1 << 9)
+#define	FVTHROT_PWM_FEEDBACK_DIV_REG1			0x308c
+#define		RANGE0_PWM_FEEDBACK_DIV(x)		((x) << 0)
+#define		RANGE0_PWM_FEEDBACK_DIV_MASK		0xfff
+#define		RANGE0_PWM_FEEDBACK_DIV_SHIFT		0
+#define		RANGE_PWM_FEEDBACK_DIV_EN		(1 << 12)
+#define	FVTHROT_PWM_FEEDBACK_DIV_REG2			0x3090
+#define		RANGE1_PWM_FEEDBACK_DIV(x)		((x) << 0)
+#define		RANGE1_PWM_FEEDBACK_DIV_MASK		0xfff
+#define		RANGE1_PWM_FEEDBACK_DIV_SHIFT		0
+#define		RANGE2_PWM_FEEDBACK_DIV(x)		((x) << 12)
+#define		RANGE2_PWM_FEEDBACK_DIV_MASK		(0xfff << 12)
+#define		RANGE2_PWM_FEEDBACK_DIV_SHIFT		12
+#define	FVTHROT_PWM_FEEDBACK_DIV_REG3			0x3094
+#define		RANGE0_PWM(x)				((x) << 0)
+#define		RANGE0_PWM_MASK				0xfff
+#define		RANGE0_PWM_SHIFT			0
+#define		RANGE1_PWM(x)				((x) << 12)
+#define		RANGE1_PWM_MASK				(0xfff << 12)
+#define		RANGE1_PWM_SHIFT			12
+#define	FVTHROT_PWM_FEEDBACK_DIV_REG4			0x3098
+#define		RANGE2_PWM(x)				((x) << 0)
+#define		RANGE2_PWM_MASK				0xfff
+#define		RANGE2_PWM_SHIFT			0
+#define		RANGE3_PWM(x)				((x) << 12)
+#define		RANGE3_PWM_MASK				(0xfff << 12)
+#define		RANGE3_PWM_SHIFT			12
+#define	FVTHROT_SLOW_CLK_FEEDBACK_DIV_REG1		0x30ac
+#define		RANGE0_SLOW_CLK_FEEDBACK_DIV(x)		((x) << 0)
+#define		RANGE0_SLOW_CLK_FEEDBACK_DIV_MASK	0xfff
+#define		RANGE0_SLOW_CLK_FEEDBACK_DIV_SHIFT	0
+#define		RANGE_SLOW_CLK_FEEDBACK_DIV_EN		(1 << 12)
+
+#define	GFX_MACRO_BYPASS_CNTL				0x30c0
+#define		SPLL_BYPASS_CNTL			(1 << 0)
+#define		UPLL_BYPASS_CNTL			(1 << 1)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rs780_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rs780_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rs780_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rs780_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,988 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "rs780d.h"
+#include "r600_dpm.h"
+#include "rs780_dpm.h"
+#include "atom.h"
+#include <linux/seq_file.h>
+
+static struct igp_ps *rs780_get_ps(struct radeon_ps *rps)
+{
+	struct igp_ps *ps = rps->ps_priv;
+
+	return ps;
+}
+
+static struct igp_power_info *rs780_get_pi(struct radeon_device *rdev)
+{
+	struct igp_power_info *pi = rdev->pm.dpm.priv;
+
+	return pi;
+}
+
+static void rs780_get_pm_mode_parameters(struct radeon_device *rdev)
+{
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+	struct radeon_mode_info *minfo = &rdev->mode_info;
+	struct drm_crtc *crtc;
+	struct radeon_crtc *radeon_crtc;
+	int i;
+
+	/* defaults */
+	pi->crtc_id = 0;
+	pi->refresh_rate = 60;
+
+	for (i = 0; i < rdev->num_crtc; i++) {
+		crtc = (struct drm_crtc *)minfo->crtcs[i];
+		if (crtc && crtc->enabled) {
+			radeon_crtc = to_radeon_crtc(crtc);
+			pi->crtc_id = radeon_crtc->crtc_id;
+			if (crtc->mode.htotal && crtc->mode.vtotal)
+				pi->refresh_rate =
+					(crtc->mode.clock * 1000) /
+					(crtc->mode.htotal * crtc->mode.vtotal);
+			break;
+		}
+	}
+}
+
+static void rs780_voltage_scaling_enable(struct radeon_device *rdev, bool enable);
+
+static int rs780_initialize_dpm_power_state(struct radeon_device *rdev,
+					    struct radeon_ps *boot_ps)
+{
+	struct atom_clock_dividers dividers;
+	struct igp_ps *default_state = rs780_get_ps(boot_ps);
+	int i, ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     default_state->sclk_low, false, &dividers);
+	if (ret)
+		return ret;
+
+	r600_engine_clock_entry_set_reference_divider(rdev, 0, dividers.ref_div);
+	r600_engine_clock_entry_set_feedback_divider(rdev, 0, dividers.fb_div);
+	r600_engine_clock_entry_set_post_divider(rdev, 0, dividers.post_div);
+
+	if (dividers.enable_post_div)
+		r600_engine_clock_entry_enable_post_divider(rdev, 0, true);
+	else
+		r600_engine_clock_entry_enable_post_divider(rdev, 0, false);
+
+	r600_engine_clock_entry_set_step_time(rdev, 0, R600_SST_DFLT);
+	r600_engine_clock_entry_enable_pulse_skipping(rdev, 0, false);
+
+	r600_engine_clock_entry_enable(rdev, 0, true);
+	for (i = 1; i < R600_PM_NUMBER_OF_SCLKS; i++)
+		r600_engine_clock_entry_enable(rdev, i, false);
+
+	r600_enable_mclk_control(rdev, false);
+	r600_voltage_control_enable_pins(rdev, 0);
+
+	return 0;
+}
+
+static int rs780_initialize_dpm_parameters(struct radeon_device *rdev,
+					   struct radeon_ps *boot_ps)
+{
+	int ret = 0;
+	int i;
+
+	r600_set_bsp(rdev, R600_BSU_DFLT, R600_BSP_DFLT);
+
+	r600_set_at(rdev, 0, 0, 0, 0);
+
+	r600_set_git(rdev, R600_GICST_DFLT);
+
+	for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)
+		r600_set_tc(rdev, i, 0, 0);
+
+	r600_select_td(rdev, R600_TD_DFLT);
+	r600_set_vrc(rdev, 0);
+
+	r600_set_tpu(rdev, R600_TPU_DFLT);
+	r600_set_tpc(rdev, R600_TPC_DFLT);
+
+	r600_set_sstu(rdev, R600_SSTU_DFLT);
+	r600_set_sst(rdev, R600_SST_DFLT);
+
+	r600_set_fctu(rdev, R600_FCTU_DFLT);
+	r600_set_fct(rdev, R600_FCT_DFLT);
+
+	r600_set_vddc3d_oorsu(rdev, R600_VDDC3DOORSU_DFLT);
+	r600_set_vddc3d_oorphc(rdev, R600_VDDC3DOORPHC_DFLT);
+	r600_set_vddc3d_oorsdc(rdev, R600_VDDC3DOORSDC_DFLT);
+	r600_set_ctxcgtt3d_rphc(rdev, R600_CTXCGTT3DRPHC_DFLT);
+	r600_set_ctxcgtt3d_rsdc(rdev, R600_CTXCGTT3DRSDC_DFLT);
+
+	r600_vid_rt_set_vru(rdev, R600_VRU_DFLT);
+	r600_vid_rt_set_vrt(rdev, R600_VOLTAGERESPONSETIME_DFLT);
+	r600_vid_rt_set_ssu(rdev, R600_SPLLSTEPUNIT_DFLT);
+
+	ret = rs780_initialize_dpm_power_state(rdev, boot_ps);
+
+	r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_LOW,     0);
+	r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_MEDIUM,  0);
+	r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_HIGH,    0);
+
+	r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_LOW,    0);
+	r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_MEDIUM, 0);
+	r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_HIGH,   0);
+
+	r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_LOW,    0);
+	r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_MEDIUM, 0);
+	r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_HIGH,   0);
+
+	r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_LOW,    R600_DISPLAY_WATERMARK_HIGH);
+	r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_MEDIUM, R600_DISPLAY_WATERMARK_HIGH);
+	r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_HIGH,   R600_DISPLAY_WATERMARK_HIGH);
+
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_CTXSW, false);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, false);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, false);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, true);
+
+	r600_power_level_set_enter_index(rdev, R600_POWER_LEVEL_LOW);
+
+	r600_set_vrc(rdev, RS780_CGFTV_DFLT);
+
+	return ret;
+}
+
+static void rs780_start_dpm(struct radeon_device *rdev)
+{
+	r600_enable_sclk_control(rdev, false);
+	r600_enable_mclk_control(rdev, false);
+
+	r600_dynamicpm_enable(rdev, true);
+
+	radeon_wait_for_vblank(rdev, 0);
+	radeon_wait_for_vblank(rdev, 1);
+
+	r600_enable_spll_bypass(rdev, true);
+	r600_wait_for_spll_change(rdev);
+	r600_enable_spll_bypass(rdev, false);
+	r600_wait_for_spll_change(rdev);
+
+	r600_enable_spll_bypass(rdev, true);
+	r600_wait_for_spll_change(rdev);
+	r600_enable_spll_bypass(rdev, false);
+	r600_wait_for_spll_change(rdev);
+
+	r600_enable_sclk_control(rdev, true);
+}
+
+
+static void rs780_preset_ranges_slow_clk_fbdiv_en(struct radeon_device *rdev)
+{
+	WREG32_P(FVTHROT_SLOW_CLK_FEEDBACK_DIV_REG1, RANGE_SLOW_CLK_FEEDBACK_DIV_EN,
+		 ~RANGE_SLOW_CLK_FEEDBACK_DIV_EN);
+
+	WREG32_P(FVTHROT_SLOW_CLK_FEEDBACK_DIV_REG1,
+		 RANGE0_SLOW_CLK_FEEDBACK_DIV(RS780_SLOWCLKFEEDBACKDIV_DFLT),
+		 ~RANGE0_SLOW_CLK_FEEDBACK_DIV_MASK);
+}
+
+static void rs780_preset_starting_fbdiv(struct radeon_device *rdev)
+{
+	u32 fbdiv = (RREG32(CG_SPLL_FUNC_CNTL) & SPLL_FB_DIV_MASK) >> SPLL_FB_DIV_SHIFT;
+
+	WREG32_P(FVTHROT_FBDIV_REG1, STARTING_FEEDBACK_DIV(fbdiv),
+		 ~STARTING_FEEDBACK_DIV_MASK);
+
+	WREG32_P(FVTHROT_FBDIV_REG2, FORCED_FEEDBACK_DIV(fbdiv),
+		 ~FORCED_FEEDBACK_DIV_MASK);
+
+	WREG32_P(FVTHROT_FBDIV_REG1, FORCE_FEEDBACK_DIV, ~FORCE_FEEDBACK_DIV);
+}
+
+static void rs780_voltage_scaling_init(struct radeon_device *rdev)
+{
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+	struct drm_device *dev = rdev->ddev;
+	u32 fv_throt_pwm_fb_div_range[3];
+	u32 fv_throt_pwm_range[4];
+
+	if (dev->pdev->device == 0x9614) {
+		fv_throt_pwm_fb_div_range[0] = RS780D_FVTHROTPWMFBDIVRANGEREG0_DFLT;
+		fv_throt_pwm_fb_div_range[1] = RS780D_FVTHROTPWMFBDIVRANGEREG1_DFLT;
+		fv_throt_pwm_fb_div_range[2] = RS780D_FVTHROTPWMFBDIVRANGEREG2_DFLT;
+	} else if ((dev->pdev->device == 0x9714) ||
+		   (dev->pdev->device == 0x9715)) {
+		fv_throt_pwm_fb_div_range[0] = RS880D_FVTHROTPWMFBDIVRANGEREG0_DFLT;
+		fv_throt_pwm_fb_div_range[1] = RS880D_FVTHROTPWMFBDIVRANGEREG1_DFLT;
+		fv_throt_pwm_fb_div_range[2] = RS880D_FVTHROTPWMFBDIVRANGEREG2_DFLT;
+	} else {
+		fv_throt_pwm_fb_div_range[0] = RS780_FVTHROTPWMFBDIVRANGEREG0_DFLT;
+		fv_throt_pwm_fb_div_range[1] = RS780_FVTHROTPWMFBDIVRANGEREG1_DFLT;
+		fv_throt_pwm_fb_div_range[2] = RS780_FVTHROTPWMFBDIVRANGEREG2_DFLT;
+	}
+
+	if (pi->pwm_voltage_control) {
+		fv_throt_pwm_range[0] = pi->min_voltage;
+		fv_throt_pwm_range[1] = pi->min_voltage;
+		fv_throt_pwm_range[2] = pi->max_voltage;
+		fv_throt_pwm_range[3] = pi->max_voltage;
+	} else {
+		fv_throt_pwm_range[0] = pi->invert_pwm_required ?
+			RS780_FVTHROTPWMRANGE3_GPIO_DFLT : RS780_FVTHROTPWMRANGE0_GPIO_DFLT;
+		fv_throt_pwm_range[1] = pi->invert_pwm_required ?
+			RS780_FVTHROTPWMRANGE2_GPIO_DFLT : RS780_FVTHROTPWMRANGE1_GPIO_DFLT;
+		fv_throt_pwm_range[2] = pi->invert_pwm_required ?
+			RS780_FVTHROTPWMRANGE1_GPIO_DFLT : RS780_FVTHROTPWMRANGE2_GPIO_DFLT;
+		fv_throt_pwm_range[3] = pi->invert_pwm_required ?
+			RS780_FVTHROTPWMRANGE0_GPIO_DFLT : RS780_FVTHROTPWMRANGE3_GPIO_DFLT;
+	}
+
+	WREG32_P(FVTHROT_PWM_CTRL_REG0,
+		 STARTING_PWM_HIGHTIME(pi->max_voltage),
+		 ~STARTING_PWM_HIGHTIME_MASK);
+
+	WREG32_P(FVTHROT_PWM_CTRL_REG0,
+		 NUMBER_OF_CYCLES_IN_PERIOD(pi->num_of_cycles_in_period),
+		 ~NUMBER_OF_CYCLES_IN_PERIOD_MASK);
+
+	WREG32_P(FVTHROT_PWM_CTRL_REG0, FORCE_STARTING_PWM_HIGHTIME,
+		 ~FORCE_STARTING_PWM_HIGHTIME);
+
+	if (pi->invert_pwm_required)
+		WREG32_P(FVTHROT_PWM_CTRL_REG0, INVERT_PWM_WAVEFORM, ~INVERT_PWM_WAVEFORM);
+	else
+		WREG32_P(FVTHROT_PWM_CTRL_REG0, 0, ~INVERT_PWM_WAVEFORM);
+
+	rs780_voltage_scaling_enable(rdev, true);
+
+	WREG32(FVTHROT_PWM_CTRL_REG1,
+	       (MIN_PWM_HIGHTIME(pi->min_voltage) |
+		MAX_PWM_HIGHTIME(pi->max_voltage)));
+
+	WREG32(FVTHROT_PWM_US_REG0, RS780_FVTHROTPWMUSREG0_DFLT);
+	WREG32(FVTHROT_PWM_US_REG1, RS780_FVTHROTPWMUSREG1_DFLT);
+	WREG32(FVTHROT_PWM_DS_REG0, RS780_FVTHROTPWMDSREG0_DFLT);
+	WREG32(FVTHROT_PWM_DS_REG1, RS780_FVTHROTPWMDSREG1_DFLT);
+
+	WREG32_P(FVTHROT_PWM_FEEDBACK_DIV_REG1,
+		 RANGE0_PWM_FEEDBACK_DIV(fv_throt_pwm_fb_div_range[0]),
+		 ~RANGE0_PWM_FEEDBACK_DIV_MASK);
+
+	WREG32(FVTHROT_PWM_FEEDBACK_DIV_REG2,
+	       (RANGE1_PWM_FEEDBACK_DIV(fv_throt_pwm_fb_div_range[1]) |
+		RANGE2_PWM_FEEDBACK_DIV(fv_throt_pwm_fb_div_range[2])));
+
+	WREG32(FVTHROT_PWM_FEEDBACK_DIV_REG3,
+	       (RANGE0_PWM(fv_throt_pwm_range[1]) |
+		RANGE1_PWM(fv_throt_pwm_range[2])));
+	WREG32(FVTHROT_PWM_FEEDBACK_DIV_REG4,
+	       (RANGE2_PWM(fv_throt_pwm_range[1]) |
+		RANGE3_PWM(fv_throt_pwm_range[2])));
+}
+
+static void rs780_clk_scaling_enable(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(FVTHROT_CNTRL_REG, ENABLE_FV_THROT | ENABLE_FV_UPDATE,
+			 ~(ENABLE_FV_THROT | ENABLE_FV_UPDATE));
+	else
+		WREG32_P(FVTHROT_CNTRL_REG, 0,
+			 ~(ENABLE_FV_THROT | ENABLE_FV_UPDATE));
+}
+
+static void rs780_voltage_scaling_enable(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(FVTHROT_CNTRL_REG, ENABLE_FV_THROT_IO, ~ENABLE_FV_THROT_IO);
+	else
+		WREG32_P(FVTHROT_CNTRL_REG, 0, ~ENABLE_FV_THROT_IO);
+}
+
+static void rs780_set_engine_clock_wfc(struct radeon_device *rdev)
+{
+	WREG32(FVTHROT_UTC0, RS780_FVTHROTUTC0_DFLT);
+	WREG32(FVTHROT_UTC1, RS780_FVTHROTUTC1_DFLT);
+	WREG32(FVTHROT_UTC2, RS780_FVTHROTUTC2_DFLT);
+	WREG32(FVTHROT_UTC3, RS780_FVTHROTUTC3_DFLT);
+	WREG32(FVTHROT_UTC4, RS780_FVTHROTUTC4_DFLT);
+
+	WREG32(FVTHROT_DTC0, RS780_FVTHROTDTC0_DFLT);
+	WREG32(FVTHROT_DTC1, RS780_FVTHROTDTC1_DFLT);
+	WREG32(FVTHROT_DTC2, RS780_FVTHROTDTC2_DFLT);
+	WREG32(FVTHROT_DTC3, RS780_FVTHROTDTC3_DFLT);
+	WREG32(FVTHROT_DTC4, RS780_FVTHROTDTC4_DFLT);
+}
+
+static void rs780_set_engine_clock_sc(struct radeon_device *rdev)
+{
+	WREG32_P(FVTHROT_FBDIV_REG2,
+		 FB_DIV_TIMER_VAL(RS780_FBDIVTIMERVAL_DFLT),
+		 ~FB_DIV_TIMER_VAL_MASK);
+
+	WREG32_P(FVTHROT_CNTRL_REG,
+		 REFRESH_RATE_DIVISOR(0) | MINIMUM_CIP(0xf),
+		 ~(REFRESH_RATE_DIVISOR_MASK | MINIMUM_CIP_MASK));
+}
+
+static void rs780_set_engine_clock_tdc(struct radeon_device *rdev)
+{
+	WREG32_P(FVTHROT_CNTRL_REG, 0, ~(FORCE_TREND_SEL | TREND_SEL_MODE));
+}
+
+static void rs780_set_engine_clock_ssc(struct radeon_device *rdev)
+{
+	WREG32(FVTHROT_FB_US_REG0, RS780_FVTHROTFBUSREG0_DFLT);
+	WREG32(FVTHROT_FB_US_REG1, RS780_FVTHROTFBUSREG1_DFLT);
+	WREG32(FVTHROT_FB_DS_REG0, RS780_FVTHROTFBDSREG0_DFLT);
+	WREG32(FVTHROT_FB_DS_REG1, RS780_FVTHROTFBDSREG1_DFLT);
+
+	WREG32_P(FVTHROT_FBDIV_REG1, MAX_FEEDBACK_STEP(1), ~MAX_FEEDBACK_STEP_MASK);
+}
+
+static void rs780_program_at(struct radeon_device *rdev)
+{
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+
+	WREG32(FVTHROT_TARGET_REG, 30000000 / pi->refresh_rate);
+	WREG32(FVTHROT_CB1, 1000000 * 5 / pi->refresh_rate);
+	WREG32(FVTHROT_CB2, 1000000 * 10 / pi->refresh_rate);
+	WREG32(FVTHROT_CB3, 1000000 * 30 / pi->refresh_rate);
+	WREG32(FVTHROT_CB4, 1000000 * 50 / pi->refresh_rate);
+}
+
+static void rs780_disable_vbios_powersaving(struct radeon_device *rdev)
+{
+	WREG32_P(CG_INTGFX_MISC, 0, ~0xFFF00000);
+}
+
+static void rs780_force_voltage_to_high(struct radeon_device *rdev)
+{
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+	struct igp_ps *current_state = rs780_get_ps(rdev->pm.dpm.current_ps);
+
+	if ((current_state->max_voltage == RS780_VDDC_LEVEL_HIGH) &&
+	    (current_state->min_voltage == RS780_VDDC_LEVEL_HIGH))
+		return;
+
+	WREG32_P(GFX_MACRO_BYPASS_CNTL, SPLL_BYPASS_CNTL, ~SPLL_BYPASS_CNTL);
+
+	udelay(1);
+
+	WREG32_P(FVTHROT_PWM_CTRL_REG0,
+		 STARTING_PWM_HIGHTIME(pi->max_voltage),
+		 ~STARTING_PWM_HIGHTIME_MASK);
+
+	WREG32_P(FVTHROT_PWM_CTRL_REG0,
+		 FORCE_STARTING_PWM_HIGHTIME, ~FORCE_STARTING_PWM_HIGHTIME);
+
+	WREG32_P(FVTHROT_PWM_FEEDBACK_DIV_REG1, 0,
+		~RANGE_PWM_FEEDBACK_DIV_EN);
+
+	udelay(1);
+
+	WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~SPLL_BYPASS_CNTL);
+}
+
+static int rs780_set_engine_clock_scaling(struct radeon_device *rdev,
+					  struct radeon_ps *new_ps,
+					  struct radeon_ps *old_ps)
+{
+	struct atom_clock_dividers min_dividers, max_dividers, current_max_dividers;
+	struct igp_ps *new_state = rs780_get_ps(new_ps);
+	struct igp_ps *old_state = rs780_get_ps(old_ps);
+	int ret;
+
+	if ((new_state->sclk_high == old_state->sclk_high) &&
+	    (new_state->sclk_low == old_state->sclk_low))
+		return 0;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     new_state->sclk_low, false, &min_dividers);
+	if (ret)
+		return ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     new_state->sclk_high, false, &max_dividers);
+	if (ret)
+		return ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     old_state->sclk_high, false, &current_max_dividers);
+	if (ret)
+		return ret;
+
+	WREG32_P(GFX_MACRO_BYPASS_CNTL, SPLL_BYPASS_CNTL, ~SPLL_BYPASS_CNTL);
+
+	WREG32_P(FVTHROT_FBDIV_REG2, FORCED_FEEDBACK_DIV(max_dividers.fb_div),
+		 ~FORCED_FEEDBACK_DIV_MASK);
+	WREG32_P(FVTHROT_FBDIV_REG1, STARTING_FEEDBACK_DIV(max_dividers.fb_div),
+		 ~STARTING_FEEDBACK_DIV_MASK);
+	WREG32_P(FVTHROT_FBDIV_REG1, FORCE_FEEDBACK_DIV, ~FORCE_FEEDBACK_DIV);
+
+	udelay(100);
+
+	WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~SPLL_BYPASS_CNTL);
+
+	if (max_dividers.fb_div > min_dividers.fb_div) {
+		WREG32_P(FVTHROT_FBDIV_REG0,
+			 MIN_FEEDBACK_DIV(min_dividers.fb_div) |
+			 MAX_FEEDBACK_DIV(max_dividers.fb_div),
+			 ~(MIN_FEEDBACK_DIV_MASK | MAX_FEEDBACK_DIV_MASK));
+
+		WREG32_P(FVTHROT_FBDIV_REG1, 0, ~FORCE_FEEDBACK_DIV);
+	}
+
+	return 0;
+}
+
+static void rs780_set_engine_clock_spc(struct radeon_device *rdev,
+				       struct radeon_ps *new_ps,
+				       struct radeon_ps *old_ps)
+{
+	struct igp_ps *new_state = rs780_get_ps(new_ps);
+	struct igp_ps *old_state = rs780_get_ps(old_ps);
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+
+	if ((new_state->sclk_high == old_state->sclk_high) &&
+	    (new_state->sclk_low == old_state->sclk_low))
+		return;
+
+	if (pi->crtc_id == 0)
+		WREG32_P(CG_INTGFX_MISC, 0, ~FVTHROT_VBLANK_SEL);
+	else
+		WREG32_P(CG_INTGFX_MISC, FVTHROT_VBLANK_SEL, ~FVTHROT_VBLANK_SEL);
+
+}
+
+static void rs780_activate_engine_clk_scaling(struct radeon_device *rdev,
+					      struct radeon_ps *new_ps,
+					      struct radeon_ps *old_ps)
+{
+	struct igp_ps *new_state = rs780_get_ps(new_ps);
+	struct igp_ps *old_state = rs780_get_ps(old_ps);
+
+	if ((new_state->sclk_high == old_state->sclk_high) &&
+	    (new_state->sclk_low == old_state->sclk_low))
+		return;
+
+	rs780_clk_scaling_enable(rdev, true);
+}
+
+static u32 rs780_get_voltage_for_vddc_level(struct radeon_device *rdev,
+					    enum rs780_vddc_level vddc)
+{
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+
+	if (vddc == RS780_VDDC_LEVEL_HIGH)
+		return pi->max_voltage;
+	else if (vddc == RS780_VDDC_LEVEL_LOW)
+		return pi->min_voltage;
+	else
+		return pi->max_voltage;
+}
+
+static void rs780_enable_voltage_scaling(struct radeon_device *rdev,
+					 struct radeon_ps *new_ps)
+{
+	struct igp_ps *new_state = rs780_get_ps(new_ps);
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+	enum rs780_vddc_level vddc_high, vddc_low;
+
+	udelay(100);
+
+	if ((new_state->max_voltage == RS780_VDDC_LEVEL_HIGH) &&
+	    (new_state->min_voltage == RS780_VDDC_LEVEL_HIGH))
+		return;
+
+	vddc_high = rs780_get_voltage_for_vddc_level(rdev,
+						     new_state->max_voltage);
+	vddc_low = rs780_get_voltage_for_vddc_level(rdev,
+						    new_state->min_voltage);
+
+	WREG32_P(GFX_MACRO_BYPASS_CNTL, SPLL_BYPASS_CNTL, ~SPLL_BYPASS_CNTL);
+
+	udelay(1);
+	if (vddc_high > vddc_low) {
+		WREG32_P(FVTHROT_PWM_FEEDBACK_DIV_REG1,
+			 RANGE_PWM_FEEDBACK_DIV_EN, ~RANGE_PWM_FEEDBACK_DIV_EN);
+
+		WREG32_P(FVTHROT_PWM_CTRL_REG0, 0, ~FORCE_STARTING_PWM_HIGHTIME);
+	} else if (vddc_high == vddc_low) {
+		if (pi->max_voltage != vddc_high) {
+			WREG32_P(FVTHROT_PWM_CTRL_REG0,
+				 STARTING_PWM_HIGHTIME(vddc_high),
+				 ~STARTING_PWM_HIGHTIME_MASK);
+
+			WREG32_P(FVTHROT_PWM_CTRL_REG0,
+				 FORCE_STARTING_PWM_HIGHTIME,
+				 ~FORCE_STARTING_PWM_HIGHTIME);
+		}
+	}
+
+	WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~SPLL_BYPASS_CNTL);
+}
+
+static void rs780_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
+						     struct radeon_ps *new_ps,
+						     struct radeon_ps *old_ps)
+{
+	struct igp_ps *new_state = rs780_get_ps(new_ps);
+	struct igp_ps *current_state = rs780_get_ps(old_ps);
+
+	if ((new_ps->vclk == old_ps->vclk) &&
+	    (new_ps->dclk == old_ps->dclk))
+		return;
+
+	if (new_state->sclk_high >= current_state->sclk_high)
+		return;
+
+	radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
+}
+
+static void rs780_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
+						    struct radeon_ps *new_ps,
+						    struct radeon_ps *old_ps)
+{
+	struct igp_ps *new_state = rs780_get_ps(new_ps);
+	struct igp_ps *current_state = rs780_get_ps(old_ps);
+
+	if ((new_ps->vclk == old_ps->vclk) &&
+	    (new_ps->dclk == old_ps->dclk))
+		return;
+
+	if (new_state->sclk_high < current_state->sclk_high)
+		return;
+
+	radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
+}
+
+int rs780_dpm_enable(struct radeon_device *rdev)
+{
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+	int ret;
+
+	rs780_get_pm_mode_parameters(rdev);
+	rs780_disable_vbios_powersaving(rdev);
+
+	if (r600_dynamicpm_enabled(rdev))
+		return -EINVAL;
+	ret = rs780_initialize_dpm_parameters(rdev, boot_ps);
+	if (ret)
+		return ret;
+	rs780_start_dpm(rdev);
+
+	rs780_preset_ranges_slow_clk_fbdiv_en(rdev);
+	rs780_preset_starting_fbdiv(rdev);
+	if (pi->voltage_control)
+		rs780_voltage_scaling_init(rdev);
+	rs780_clk_scaling_enable(rdev, true);
+	rs780_set_engine_clock_sc(rdev);
+	rs780_set_engine_clock_wfc(rdev);
+	rs780_program_at(rdev);
+	rs780_set_engine_clock_tdc(rdev);
+	rs780_set_engine_clock_ssc(rdev);
+
+	if (pi->gfx_clock_gating)
+		r600_gfx_clockgating_enable(rdev, true);
+
+	if (rdev->irq.installed && (rdev->pm.int_thermal_type == THERMAL_TYPE_RV6XX)) {
+		ret = r600_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+		if (ret)
+			return ret;
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+	}
+
+	return 0;
+}
+
+void rs780_dpm_disable(struct radeon_device *rdev)
+{
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+
+	r600_dynamicpm_enable(rdev, false);
+
+	rs780_clk_scaling_enable(rdev, false);
+	rs780_voltage_scaling_enable(rdev, false);
+
+	if (pi->gfx_clock_gating)
+		r600_gfx_clockgating_enable(rdev, false);
+
+	if (rdev->irq.installed &&
+	    (rdev->pm.int_thermal_type == THERMAL_TYPE_RV6XX)) {
+		rdev->irq.dpm_thermal = false;
+		radeon_irq_set(rdev);
+	}
+}
+
+int rs780_dpm_set_power_state(struct radeon_device *rdev)
+{
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+	struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
+	struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;
+	int ret;
+
+	rs780_get_pm_mode_parameters(rdev);
+
+	rs780_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+
+	if (pi->voltage_control) {
+		rs780_force_voltage_to_high(rdev);
+		mdelay(5);
+	}
+
+	ret = rs780_set_engine_clock_scaling(rdev, new_ps, old_ps);
+	if (ret)
+		return ret;
+	rs780_set_engine_clock_spc(rdev, new_ps, old_ps);
+
+	rs780_activate_engine_clk_scaling(rdev, new_ps, old_ps);
+
+	if (pi->voltage_control)
+		rs780_enable_voltage_scaling(rdev, new_ps);
+
+	rs780_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+
+	return 0;
+}
+
+void rs780_dpm_setup_asic(struct radeon_device *rdev)
+{
+
+}
+
+void rs780_dpm_display_configuration_changed(struct radeon_device *rdev)
+{
+	rs780_get_pm_mode_parameters(rdev);
+	rs780_program_at(rdev);
+}
+
+union igp_info {
+	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
+};
+
+union power_info {
+	struct _ATOM_POWERPLAY_INFO info;
+	struct _ATOM_POWERPLAY_INFO_V2 info_2;
+	struct _ATOM_POWERPLAY_INFO_V3 info_3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
+	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
+	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
+};
+
+union pplib_clock_info {
+	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
+	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
+	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
+	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
+};
+
+union pplib_power_state {
+	struct _ATOM_PPLIB_STATE v1;
+	struct _ATOM_PPLIB_STATE_V2 v2;
+};
+
+static void rs780_parse_pplib_non_clock_info(struct radeon_device *rdev,
+					     struct radeon_ps *rps,
+					     struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
+					     u8 table_rev)
+{
+	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
+	rps->class = le16_to_cpu(non_clock_info->usClassification);
+	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
+
+	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
+		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
+		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
+	} else if (r600_is_uvd_state(rps->class, rps->class2)) {
+		rps->vclk = RS780_DEFAULT_VCLK_FREQ;
+		rps->dclk = RS780_DEFAULT_DCLK_FREQ;
+	} else {
+		rps->vclk = 0;
+		rps->dclk = 0;
+	}
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
+		rdev->pm.dpm.boot_ps = rps;
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		rdev->pm.dpm.uvd_ps = rps;
+}
+
+static void rs780_parse_pplib_clock_info(struct radeon_device *rdev,
+					 struct radeon_ps *rps,
+					 union pplib_clock_info *clock_info)
+{
+	struct igp_ps *ps = rs780_get_ps(rps);
+	u32 sclk;
+
+	sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow);
+	sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
+	ps->sclk_low = sclk;
+	sclk = le16_to_cpu(clock_info->rs780.usHighEngineClockLow);
+	sclk |= clock_info->rs780.ucHighEngineClockHigh << 16;
+	ps->sclk_high = sclk;
+	switch (le16_to_cpu(clock_info->rs780.usVDDC)) {
+	case ATOM_PPLIB_RS780_VOLTAGE_NONE:
+	default:
+		ps->min_voltage = RS780_VDDC_LEVEL_UNKNOWN;
+		ps->max_voltage = RS780_VDDC_LEVEL_UNKNOWN;
+		break;
+	case ATOM_PPLIB_RS780_VOLTAGE_LOW:
+		ps->min_voltage = RS780_VDDC_LEVEL_LOW;
+		ps->max_voltage = RS780_VDDC_LEVEL_LOW;
+		break;
+	case ATOM_PPLIB_RS780_VOLTAGE_HIGH:
+		ps->min_voltage = RS780_VDDC_LEVEL_HIGH;
+		ps->max_voltage = RS780_VDDC_LEVEL_HIGH;
+		break;
+	case ATOM_PPLIB_RS780_VOLTAGE_VARIABLE:
+		ps->min_voltage = RS780_VDDC_LEVEL_LOW;
+		ps->max_voltage = RS780_VDDC_LEVEL_HIGH;
+		break;
+	}
+	ps->flags = le32_to_cpu(clock_info->rs780.ulFlags);
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
+		ps->sclk_low = rdev->clock.default_sclk;
+		ps->sclk_high = rdev->clock.default_sclk;
+		ps->min_voltage = RS780_VDDC_LEVEL_HIGH;
+		ps->max_voltage = RS780_VDDC_LEVEL_HIGH;
+	}
+}
+
+static int rs780_parse_power_table(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
+	union pplib_power_state *power_state;
+	int i;
+	union pplib_clock_info *clock_info;
+	union power_info *power_info;
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+        u16 data_offset;
+	u8 frev, crev;
+	struct igp_ps *ps;
+
+	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset))
+		return -EINVAL;
+	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+
+	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
+				  power_info->pplib.ucNumStates, GFP_KERNEL);
+	if (!rdev->pm.dpm.ps)
+		return -ENOMEM;
+	rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
+	rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
+	rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
+
+	for (i = 0; i < power_info->pplib.ucNumStates; i++) {
+		power_state = (union pplib_power_state *)
+			(mode_info->atom_context->bios + data_offset +
+			 le16_to_cpu(power_info->pplib.usStateArrayOffset) +
+			 i * power_info->pplib.ucStateEntrySize);
+		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
+			(mode_info->atom_context->bios + data_offset +
+			 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
+			 (power_state->v1.ucNonClockStateIndex *
+			  power_info->pplib.ucNonClockSize));
+		if (power_info->pplib.ucStateEntrySize - 1) {
+			clock_info = (union pplib_clock_info *)
+				(mode_info->atom_context->bios + data_offset +
+				 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
+				 (power_state->v1.ucClockStateIndices[0] *
+				  power_info->pplib.ucClockInfoSize));
+			ps = kzalloc(sizeof(struct igp_ps), GFP_KERNEL);
+			if (ps == NULL) {
+				kfree(rdev->pm.dpm.ps);
+				return -ENOMEM;
+			}
+			rdev->pm.dpm.ps[i].ps_priv = ps;
+			rs780_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
+							 non_clock_info,
+							 power_info->pplib.ucNonClockSize);
+			rs780_parse_pplib_clock_info(rdev,
+						     &rdev->pm.dpm.ps[i],
+						     clock_info);
+		}
+	}
+	rdev->pm.dpm.num_ps = power_info->pplib.ucNumStates;
+	return 0;
+}
+
+int rs780_dpm_init(struct radeon_device *rdev)
+{
+	struct igp_power_info *pi;
+	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
+	union igp_info *info;
+	u16 data_offset;
+	u8 frev, crev;
+	int ret;
+
+	pi = kzalloc(sizeof(struct igp_power_info), GFP_KERNEL);
+	if (pi == NULL)
+		return -ENOMEM;
+	rdev->pm.dpm.priv = pi;
+
+	ret = rs780_parse_power_table(rdev);
+	if (ret)
+		return ret;
+
+	pi->voltage_control = false;
+	pi->gfx_clock_gating = true;
+
+	if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset);
+
+		/* Get various system informations from bios */
+		switch (crev) {
+		case 1:
+			pi->num_of_cycles_in_period =
+				info->info.ucNumberOfCyclesInPeriod;
+			pi->num_of_cycles_in_period |=
+				info->info.ucNumberOfCyclesInPeriodHi << 8;
+			pi->invert_pwm_required =
+				(pi->num_of_cycles_in_period & 0x8000) ? true : false;
+			pi->boot_voltage = info->info.ucStartingPWM_HighTime;
+			pi->max_voltage = info->info.ucMaxNBVoltage;
+			pi->max_voltage |= info->info.ucMaxNBVoltageHigh << 8;
+			pi->min_voltage = info->info.ucMinNBVoltage;
+			pi->min_voltage |= info->info.ucMinNBVoltageHigh << 8;
+			pi->inter_voltage_low =
+				le16_to_cpu(info->info.usInterNBVoltageLow);
+			pi->inter_voltage_high =
+				le16_to_cpu(info->info.usInterNBVoltageHigh);
+			pi->voltage_control = true;
+			pi->bootup_uma_clk = info->info.usK8MemoryClock * 100;
+			break;
+		case 2:
+			pi->num_of_cycles_in_period =
+				le16_to_cpu(info->info_2.usNumberOfCyclesInPeriod);
+			pi->invert_pwm_required =
+				(pi->num_of_cycles_in_period & 0x8000) ? true : false;
+			pi->boot_voltage =
+				le16_to_cpu(info->info_2.usBootUpNBVoltage);
+			pi->max_voltage =
+				le16_to_cpu(info->info_2.usMaxNBVoltage);
+			pi->min_voltage =
+				le16_to_cpu(info->info_2.usMinNBVoltage);
+			pi->system_config =
+				le32_to_cpu(info->info_2.ulSystemConfig);
+			pi->pwm_voltage_control =
+				(pi->system_config & 0x4) ? true : false;
+			pi->voltage_control = true;
+			pi->bootup_uma_clk = le32_to_cpu(info->info_2.ulBootUpUMAClock);
+			break;
+		default:
+			DRM_ERROR("No integrated system info for your GPU\n");
+			return -EINVAL;
+		}
+		if (pi->min_voltage > pi->max_voltage)
+			pi->voltage_control = false;
+		if (pi->pwm_voltage_control) {
+			if ((pi->num_of_cycles_in_period == 0) ||
+			    (pi->max_voltage == 0) ||
+			    (pi->min_voltage == 0))
+				pi->voltage_control = false;
+		} else {
+			if ((pi->num_of_cycles_in_period == 0) ||
+			    (pi->max_voltage == 0))
+				pi->voltage_control = false;
+		}
+
+		return 0;
+	}
+	radeon_dpm_fini(rdev);
+	return -EINVAL;
+}
+
+void rs780_dpm_print_power_state(struct radeon_device *rdev,
+				 struct radeon_ps *rps)
+{
+	struct igp_ps *ps = rs780_get_ps(rps);
+
+	r600_dpm_print_class_info(rps->class, rps->class2);
+	r600_dpm_print_cap_info(rps->caps);
+	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+	printk("\t\tpower level 0    sclk: %u vddc_index: %d\n",
+	       ps->sclk_low, ps->min_voltage);
+	printk("\t\tpower level 1    sclk: %u vddc_index: %d\n",
+	       ps->sclk_high, ps->max_voltage);
+	r600_dpm_print_ps_status(rdev, rps);
+}
+
+void rs780_dpm_fini(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	}
+	kfree(rdev->pm.dpm.ps);
+	kfree(rdev->pm.dpm.priv);
+}
+
+u32 rs780_dpm_get_sclk(struct radeon_device *rdev, bool low)
+{
+	struct igp_ps *requested_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
+
+	if (low)
+		return requested_state->sclk_low;
+	else
+		return requested_state->sclk_high;
+}
+
+u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low)
+{
+	struct igp_power_info *pi = rs780_get_pi(rdev);
+
+	return pi->bootup_uma_clk;
+}
+
+void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						       struct seq_file *m)
+{
+	struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+	struct igp_ps *ps = rs780_get_ps(rps);
+	u32 current_fb_div = RREG32(FVTHROT_STATUS_REG0) & CURRENT_FEEDBACK_DIV_MASK;
+	u32 func_cntl = RREG32(CG_SPLL_FUNC_CNTL);
+	u32 ref_div = ((func_cntl & SPLL_REF_DIV_MASK) >> SPLL_REF_DIV_SHIFT) + 1;
+	u32 post_div = ((func_cntl & SPLL_SW_HILEN_MASK) >> SPLL_SW_HILEN_SHIFT) + 1 +
+		((func_cntl & SPLL_SW_LOLEN_MASK) >> SPLL_SW_LOLEN_SHIFT) + 1;
+	u32 sclk = (rdev->clock.spll.reference_freq * current_fb_div) /
+		(post_div * ref_div);
+
+	seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+
+	/* guess based on the current sclk */
+	if (sclk < (ps->sclk_low + 500))
+		seq_printf(m, "power level 0    sclk: %u vddc_index: %d\n",
+			   ps->sclk_low, ps->min_voltage);
+	else
+		seq_printf(m, "power level 1    sclk: %u vddc_index: %d\n",
+			   ps->sclk_high, ps->max_voltage);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rs780_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rs780_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rs780_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rs780_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __RS780_DPM_H__
+#define __RS780_DPM_H__
+
+enum rs780_vddc_level {
+	RS780_VDDC_LEVEL_UNKNOWN = 0,
+	RS780_VDDC_LEVEL_LOW = 1,
+	RS780_VDDC_LEVEL_HIGH = 2,
+};
+
+struct igp_power_info {
+	/* flags */
+	bool invert_pwm_required;
+	bool pwm_voltage_control;
+	bool voltage_control;
+	bool gfx_clock_gating;
+	/* stored values */
+	u32 system_config;
+	u32 bootup_uma_clk;
+	u16 max_voltage;
+	u16 min_voltage;
+	u16 boot_voltage;
+	u16 inter_voltage_low;
+	u16 inter_voltage_high;
+	u16 num_of_cycles_in_period;
+	/* variable */
+	int crtc_id;
+	int refresh_rate;
+};
+
+struct igp_ps {
+	enum rs780_vddc_level min_voltage;
+	enum rs780_vddc_level max_voltage;
+	u32 sclk_low;
+	u32 sclk_high;
+	u32 flags;
+};
+
+#define RS780_CGFTV_DFLT                 0x0303000f
+#define RS780_FBDIVTIMERVAL_DFLT         0x2710
+
+#define RS780_FVTHROTUTC0_DFLT   0x04010040
+#define RS780_FVTHROTUTC1_DFLT   0x04010040
+#define RS780_FVTHROTUTC2_DFLT   0x04010040
+#define RS780_FVTHROTUTC3_DFLT   0x04010040
+#define RS780_FVTHROTUTC4_DFLT   0x04010040
+
+#define RS780_FVTHROTDTC0_DFLT 0x04010040
+#define RS780_FVTHROTDTC1_DFLT 0x04010040
+#define RS780_FVTHROTDTC2_DFLT 0x04010040
+#define RS780_FVTHROTDTC3_DFLT 0x04010040
+#define RS780_FVTHROTDTC4_DFLT 0x04010040
+
+#define RS780_FVTHROTFBUSREG0_DFLT       0x00001001
+#define RS780_FVTHROTFBUSREG1_DFLT       0x00002002
+#define RS780_FVTHROTFBDSREG0_DFLT       0x00004001
+#define RS780_FVTHROTFBDSREG1_DFLT       0x00020010
+
+#define RS780_FVTHROTPWMUSREG0_DFLT      0x00002001
+#define RS780_FVTHROTPWMUSREG1_DFLT      0x00004003
+#define RS780_FVTHROTPWMDSREG0_DFLT      0x00002001
+#define RS780_FVTHROTPWMDSREG1_DFLT      0x00004003
+
+#define RS780_FVTHROTPWMFBDIVRANGEREG0_DFLT  0x37
+#define RS780_FVTHROTPWMFBDIVRANGEREG1_DFLT  0x4b
+#define RS780_FVTHROTPWMFBDIVRANGEREG2_DFLT  0x8b
+
+#define RS780D_FVTHROTPWMFBDIVRANGEREG0_DFLT  0x8b
+#define RS780D_FVTHROTPWMFBDIVRANGEREG1_DFLT  0x8c
+#define RS780D_FVTHROTPWMFBDIVRANGEREG2_DFLT  0xb5
+
+#define RS880D_FVTHROTPWMFBDIVRANGEREG0_DFLT  0x8d
+#define RS880D_FVTHROTPWMFBDIVRANGEREG1_DFLT  0x8e
+#define RS880D_FVTHROTPWMFBDIVRANGEREG2_DFLT  0xBa
+
+#define RS780_FVTHROTPWMRANGE0_GPIO_DFLT  0x1a
+#define RS780_FVTHROTPWMRANGE1_GPIO_DFLT  0x1a
+#define RS780_FVTHROTPWMRANGE2_GPIO_DFLT  0x0
+#define RS780_FVTHROTPWMRANGE3_GPIO_DFLT  0x0
+
+#define RS780_SLOWCLKFEEDBACKDIV_DFLT 110
+
+#define RS780_CGCLKGATING_DFLT           0x0000E204
+
+#define RS780_DEFAULT_VCLK_FREQ  53300 /* 10 khz */
+#define RS780_DEFAULT_DCLK_FREQ  40000 /* 10 khz */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv515.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv515.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv515.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv515.c	2013-08-25 20:43:22.000000000 -0400
@@ -937,13 +937,16 @@ struct rv515_watermark {
 };
 
 static void rv515_crtc_bandwidth_compute(struct radeon_device *rdev,
-				  struct radeon_crtc *crtc,
-				  struct rv515_watermark *wm)
+					 struct radeon_crtc *crtc,
+					 struct rv515_watermark *wm,
+					 bool low)
 {
 	struct drm_display_mode *mode = &crtc->base.mode;
 	fixed20_12 a, b, c;
 	fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width;
 	fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency;
+	fixed20_12 sclk;
+	u32 selected_sclk;
 
 	if (!crtc->base.enabled) {
 		/* FIXME: wouldn't it better to set priority mark to maximum */
@@ -951,6 +954,18 @@ static void rv515_crtc_bandwidth_compute
 		return;
 	}
 
+	/* rv6xx, rv7xx */
+	if ((rdev->family >= CHIP_RV610) &&
+	    (rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled)
+		selected_sclk = radeon_dpm_get_sclk(rdev, low);
+	else
+		selected_sclk = rdev->pm.current_sclk;
+
+	/* sclk in Mhz */
+	a.full = dfixed_const(100);
+	sclk.full = dfixed_const(selected_sclk);
+	sclk.full = dfixed_div(sclk, a);
+
 	if (crtc->vsc.full > dfixed_const(2))
 		wm->num_line_pair.full = dfixed_const(2);
 	else
@@ -1016,7 +1031,7 @@ static void rv515_crtc_bandwidth_compute
 	 * sclk = system clock(Mhz)
 	 */
 	a.full = dfixed_const(600 * 1000);
-	chunk_time.full = dfixed_div(a, rdev->pm.sclk);
+	chunk_time.full = dfixed_div(a, sclk);
 	read_delay_latency.full = dfixed_const(1000);
 
 	/* Determine the worst case latency
@@ -1077,152 +1092,177 @@ static void rv515_crtc_bandwidth_compute
 	}
 }
 
-void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
+static void rv515_compute_mode_priority(struct radeon_device *rdev,
+					struct rv515_watermark *wm0,
+					struct rv515_watermark *wm1,
+					struct drm_display_mode *mode0,
+					struct drm_display_mode *mode1,
+					u32 *d1mode_priority_a_cnt,
+					u32 *d2mode_priority_a_cnt)
 {
-	struct drm_display_mode *mode0 = NULL;
-	struct drm_display_mode *mode1 = NULL;
-	struct rv515_watermark wm0;
-	struct rv515_watermark wm1;
-	u32 tmp;
-	u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF;
-	u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF;
 	fixed20_12 priority_mark02, priority_mark12, fill_rate;
 	fixed20_12 a, b;
 
-	if (rdev->mode_info.crtcs[0]->base.enabled)
-		mode0 = &rdev->mode_info.crtcs[0]->base.mode;
-	if (rdev->mode_info.crtcs[1]->base.enabled)
-		mode1 = &rdev->mode_info.crtcs[1]->base.mode;
-	rs690_line_buffer_adjust(rdev, mode0, mode1);
-
-	rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0);
-	rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1);
-
-	tmp = wm0.lb_request_fifo_depth;
-	tmp |= wm1.lb_request_fifo_depth << 16;
-	WREG32(LB_MAX_REQ_OUTSTANDING, tmp);
+	*d1mode_priority_a_cnt = MODE_PRIORITY_OFF;
+	*d2mode_priority_a_cnt = MODE_PRIORITY_OFF;
 
 	if (mode0 && mode1) {
-		if (dfixed_trunc(wm0.dbpp) > 64)
-			a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair);
+		if (dfixed_trunc(wm0->dbpp) > 64)
+			a.full = dfixed_div(wm0->dbpp, wm0->num_line_pair);
 		else
-			a.full = wm0.num_line_pair.full;
-		if (dfixed_trunc(wm1.dbpp) > 64)
-			b.full = dfixed_div(wm1.dbpp, wm1.num_line_pair);
+			a.full = wm0->num_line_pair.full;
+		if (dfixed_trunc(wm1->dbpp) > 64)
+			b.full = dfixed_div(wm1->dbpp, wm1->num_line_pair);
 		else
-			b.full = wm1.num_line_pair.full;
+			b.full = wm1->num_line_pair.full;
 		a.full += b.full;
-		fill_rate.full = dfixed_div(wm0.sclk, a);
-		if (wm0.consumption_rate.full > fill_rate.full) {
-			b.full = wm0.consumption_rate.full - fill_rate.full;
-			b.full = dfixed_mul(b, wm0.active_time);
+		fill_rate.full = dfixed_div(wm0->sclk, a);
+		if (wm0->consumption_rate.full > fill_rate.full) {
+			b.full = wm0->consumption_rate.full - fill_rate.full;
+			b.full = dfixed_mul(b, wm0->active_time);
 			a.full = dfixed_const(16);
 			b.full = dfixed_div(b, a);
-			a.full = dfixed_mul(wm0.worst_case_latency,
-						wm0.consumption_rate);
+			a.full = dfixed_mul(wm0->worst_case_latency,
+						wm0->consumption_rate);
 			priority_mark02.full = a.full + b.full;
 		} else {
-			a.full = dfixed_mul(wm0.worst_case_latency,
-						wm0.consumption_rate);
+			a.full = dfixed_mul(wm0->worst_case_latency,
+						wm0->consumption_rate);
 			b.full = dfixed_const(16 * 1000);
 			priority_mark02.full = dfixed_div(a, b);
 		}
-		if (wm1.consumption_rate.full > fill_rate.full) {
-			b.full = wm1.consumption_rate.full - fill_rate.full;
-			b.full = dfixed_mul(b, wm1.active_time);
+		if (wm1->consumption_rate.full > fill_rate.full) {
+			b.full = wm1->consumption_rate.full - fill_rate.full;
+			b.full = dfixed_mul(b, wm1->active_time);
 			a.full = dfixed_const(16);
 			b.full = dfixed_div(b, a);
-			a.full = dfixed_mul(wm1.worst_case_latency,
-						wm1.consumption_rate);
+			a.full = dfixed_mul(wm1->worst_case_latency,
+						wm1->consumption_rate);
 			priority_mark12.full = a.full + b.full;
 		} else {
-			a.full = dfixed_mul(wm1.worst_case_latency,
-						wm1.consumption_rate);
+			a.full = dfixed_mul(wm1->worst_case_latency,
+						wm1->consumption_rate);
 			b.full = dfixed_const(16 * 1000);
 			priority_mark12.full = dfixed_div(a, b);
 		}
-		if (wm0.priority_mark.full > priority_mark02.full)
-			priority_mark02.full = wm0.priority_mark.full;
+		if (wm0->priority_mark.full > priority_mark02.full)
+			priority_mark02.full = wm0->priority_mark.full;
 		if (dfixed_trunc(priority_mark02) < 0)
 			priority_mark02.full = 0;
-		if (wm0.priority_mark_max.full > priority_mark02.full)
-			priority_mark02.full = wm0.priority_mark_max.full;
-		if (wm1.priority_mark.full > priority_mark12.full)
-			priority_mark12.full = wm1.priority_mark.full;
+		if (wm0->priority_mark_max.full > priority_mark02.full)
+			priority_mark02.full = wm0->priority_mark_max.full;
+		if (wm1->priority_mark.full > priority_mark12.full)
+			priority_mark12.full = wm1->priority_mark.full;
 		if (dfixed_trunc(priority_mark12) < 0)
 			priority_mark12.full = 0;
-		if (wm1.priority_mark_max.full > priority_mark12.full)
-			priority_mark12.full = wm1.priority_mark_max.full;
-		d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
-		d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
+		if (wm1->priority_mark_max.full > priority_mark12.full)
+			priority_mark12.full = wm1->priority_mark_max.full;
+		*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
+		*d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
 		if (rdev->disp_priority == 2) {
-			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
-			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+			*d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+			*d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
 		}
 	} else if (mode0) {
-		if (dfixed_trunc(wm0.dbpp) > 64)
-			a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair);
+		if (dfixed_trunc(wm0->dbpp) > 64)
+			a.full = dfixed_div(wm0->dbpp, wm0->num_line_pair);
 		else
-			a.full = wm0.num_line_pair.full;
-		fill_rate.full = dfixed_div(wm0.sclk, a);
-		if (wm0.consumption_rate.full > fill_rate.full) {
-			b.full = wm0.consumption_rate.full - fill_rate.full;
-			b.full = dfixed_mul(b, wm0.active_time);
+			a.full = wm0->num_line_pair.full;
+		fill_rate.full = dfixed_div(wm0->sclk, a);
+		if (wm0->consumption_rate.full > fill_rate.full) {
+			b.full = wm0->consumption_rate.full - fill_rate.full;
+			b.full = dfixed_mul(b, wm0->active_time);
 			a.full = dfixed_const(16);
 			b.full = dfixed_div(b, a);
-			a.full = dfixed_mul(wm0.worst_case_latency,
-						wm0.consumption_rate);
+			a.full = dfixed_mul(wm0->worst_case_latency,
+						wm0->consumption_rate);
 			priority_mark02.full = a.full + b.full;
 		} else {
-			a.full = dfixed_mul(wm0.worst_case_latency,
-						wm0.consumption_rate);
+			a.full = dfixed_mul(wm0->worst_case_latency,
+						wm0->consumption_rate);
 			b.full = dfixed_const(16);
 			priority_mark02.full = dfixed_div(a, b);
 		}
-		if (wm0.priority_mark.full > priority_mark02.full)
-			priority_mark02.full = wm0.priority_mark.full;
+		if (wm0->priority_mark.full > priority_mark02.full)
+			priority_mark02.full = wm0->priority_mark.full;
 		if (dfixed_trunc(priority_mark02) < 0)
 			priority_mark02.full = 0;
-		if (wm0.priority_mark_max.full > priority_mark02.full)
-			priority_mark02.full = wm0.priority_mark_max.full;
-		d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
+		if (wm0->priority_mark_max.full > priority_mark02.full)
+			priority_mark02.full = wm0->priority_mark_max.full;
+		*d1mode_priority_a_cnt = dfixed_trunc(priority_mark02);
 		if (rdev->disp_priority == 2)
-			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+			*d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
 	} else if (mode1) {
-		if (dfixed_trunc(wm1.dbpp) > 64)
-			a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair);
+		if (dfixed_trunc(wm1->dbpp) > 64)
+			a.full = dfixed_div(wm1->dbpp, wm1->num_line_pair);
 		else
-			a.full = wm1.num_line_pair.full;
-		fill_rate.full = dfixed_div(wm1.sclk, a);
-		if (wm1.consumption_rate.full > fill_rate.full) {
-			b.full = wm1.consumption_rate.full - fill_rate.full;
-			b.full = dfixed_mul(b, wm1.active_time);
+			a.full = wm1->num_line_pair.full;
+		fill_rate.full = dfixed_div(wm1->sclk, a);
+		if (wm1->consumption_rate.full > fill_rate.full) {
+			b.full = wm1->consumption_rate.full - fill_rate.full;
+			b.full = dfixed_mul(b, wm1->active_time);
 			a.full = dfixed_const(16);
 			b.full = dfixed_div(b, a);
-			a.full = dfixed_mul(wm1.worst_case_latency,
-						wm1.consumption_rate);
+			a.full = dfixed_mul(wm1->worst_case_latency,
+						wm1->consumption_rate);
 			priority_mark12.full = a.full + b.full;
 		} else {
-			a.full = dfixed_mul(wm1.worst_case_latency,
-						wm1.consumption_rate);
+			a.full = dfixed_mul(wm1->worst_case_latency,
+						wm1->consumption_rate);
 			b.full = dfixed_const(16 * 1000);
 			priority_mark12.full = dfixed_div(a, b);
 		}
-		if (wm1.priority_mark.full > priority_mark12.full)
-			priority_mark12.full = wm1.priority_mark.full;
+		if (wm1->priority_mark.full > priority_mark12.full)
+			priority_mark12.full = wm1->priority_mark.full;
 		if (dfixed_trunc(priority_mark12) < 0)
 			priority_mark12.full = 0;
-		if (wm1.priority_mark_max.full > priority_mark12.full)
-			priority_mark12.full = wm1.priority_mark_max.full;
-		d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
+		if (wm1->priority_mark_max.full > priority_mark12.full)
+			priority_mark12.full = wm1->priority_mark_max.full;
+		*d2mode_priority_a_cnt = dfixed_trunc(priority_mark12);
 		if (rdev->disp_priority == 2)
-			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
+			*d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;
 	}
+}
+
+void rv515_bandwidth_avivo_update(struct radeon_device *rdev)
+{
+	struct drm_display_mode *mode0 = NULL;
+	struct drm_display_mode *mode1 = NULL;
+	struct rv515_watermark wm0_high, wm0_low;
+	struct rv515_watermark wm1_high, wm1_low;
+	u32 tmp;
+	u32 d1mode_priority_a_cnt, d1mode_priority_b_cnt;
+	u32 d2mode_priority_a_cnt, d2mode_priority_b_cnt;
+
+	if (rdev->mode_info.crtcs[0]->base.enabled)
+		mode0 = &rdev->mode_info.crtcs[0]->base.mode;
+	if (rdev->mode_info.crtcs[1]->base.enabled)
+		mode1 = &rdev->mode_info.crtcs[1]->base.mode;
+	rs690_line_buffer_adjust(rdev, mode0, mode1);
+
+	rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0_high, false);
+	rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1_high, false);
+
+	rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0_low, false);
+	rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1_low, false);
+
+	tmp = wm0_high.lb_request_fifo_depth;
+	tmp |= wm1_high.lb_request_fifo_depth << 16;
+	WREG32(LB_MAX_REQ_OUTSTANDING, tmp);
+
+	rv515_compute_mode_priority(rdev,
+				    &wm0_high, &wm1_high,
+				    mode0, mode1,
+				    &d1mode_priority_a_cnt, &d2mode_priority_a_cnt);
+	rv515_compute_mode_priority(rdev,
+				    &wm0_low, &wm1_low,
+				    mode0, mode1,
+				    &d1mode_priority_b_cnt, &d2mode_priority_b_cnt);
 
 	WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt);
-	WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);
+	WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_b_cnt);
 	WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt);
-	WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);
+	WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_b_cnt);
 }
 
 void rv515_bandwidth_update(struct radeon_device *rdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv6xxd.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv6xxd.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv6xxd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv6xxd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 RV6XXD_H
+#define RV6XXD_H
+
+/* RV6xx power management */
+#define SPLL_CNTL_MODE                                    0x60c
+#       define SPLL_DIV_SYNC                              (1 << 5)
+
+#define GENERAL_PWRMGT                                    0x618
+#       define GLOBAL_PWRMGT_EN                           (1 << 0)
+#       define STATIC_PM_EN                               (1 << 1)
+#       define MOBILE_SU                                  (1 << 2)
+#       define THERMAL_PROTECTION_DIS                     (1 << 3)
+#       define THERMAL_PROTECTION_TYPE                    (1 << 4)
+#       define ENABLE_GEN2PCIE                            (1 << 5)
+#       define SW_GPIO_INDEX(x)                           ((x) << 6)
+#       define SW_GPIO_INDEX_MASK                         (3 << 6)
+#       define LOW_VOLT_D2_ACPI                           (1 << 8)
+#       define LOW_VOLT_D3_ACPI                           (1 << 9)
+#       define VOLT_PWRMGT_EN                             (1 << 10)
+#       define BACKBIAS_PAD_EN                            (1 << 16)
+#       define BACKBIAS_VALUE                             (1 << 17)
+#       define BACKBIAS_DPM_CNTL                          (1 << 18)
+#       define DYN_SPREAD_SPECTRUM_EN                     (1 << 21)
+
+#define MCLK_PWRMGT_CNTL                                  0x624
+#       define MPLL_PWRMGT_OFF                            (1 << 0)
+#       define YCLK_TURNOFF                               (1 << 1)
+#       define MPLL_TURNOFF                               (1 << 2)
+#       define SU_MCLK_USE_BCLK                           (1 << 3)
+#       define DLL_READY                                  (1 << 4)
+#       define MC_BUSY                                    (1 << 5)
+#       define MC_INT_CNTL                                (1 << 7)
+#       define MRDCKA_SLEEP                               (1 << 8)
+#       define MRDCKB_SLEEP                               (1 << 9)
+#       define MRDCKC_SLEEP                               (1 << 10)
+#       define MRDCKD_SLEEP                               (1 << 11)
+#       define MRDCKE_SLEEP                               (1 << 12)
+#       define MRDCKF_SLEEP                               (1 << 13)
+#       define MRDCKG_SLEEP                               (1 << 14)
+#       define MRDCKH_SLEEP                               (1 << 15)
+#       define MRDCKA_RESET                               (1 << 16)
+#       define MRDCKB_RESET                               (1 << 17)
+#       define MRDCKC_RESET                               (1 << 18)
+#       define MRDCKD_RESET                               (1 << 19)
+#       define MRDCKE_RESET                               (1 << 20)
+#       define MRDCKF_RESET                               (1 << 21)
+#       define MRDCKG_RESET                               (1 << 22)
+#       define MRDCKH_RESET                               (1 << 23)
+#       define DLL_READY_READ                             (1 << 24)
+#       define USE_DISPLAY_GAP                            (1 << 25)
+#       define USE_DISPLAY_URGENT_NORMAL                  (1 << 26)
+#       define USE_DISPLAY_GAP_CTXSW                      (1 << 27)
+#       define MPLL_TURNOFF_D2                            (1 << 28)
+#       define USE_DISPLAY_URGENT_CTXSW                   (1 << 29)
+
+#define MPLL_FREQ_LEVEL_0                                 0x6e8
+#       define LEVEL0_MPLL_POST_DIV(x)                    ((x) << 0)
+#       define LEVEL0_MPLL_POST_DIV_MASK                  (0xff << 0)
+#       define LEVEL0_MPLL_FB_DIV(x)                      ((x) << 8)
+#       define LEVEL0_MPLL_FB_DIV_MASK                    (0xfff << 8)
+#       define LEVEL0_MPLL_REF_DIV(x)                     ((x) << 20)
+#       define LEVEL0_MPLL_REF_DIV_MASK                   (0x3f << 20)
+#       define LEVEL0_MPLL_DIV_EN                         (1 << 28)
+#       define LEVEL0_DLL_BYPASS                          (1 << 29)
+#       define LEVEL0_DLL_RESET                           (1 << 30)
+
+#define VID_RT                                            0x6f8
+#       define VID_CRT(x)                                 ((x) << 0)
+#       define VID_CRT_MASK                               (0x1fff << 0)
+#       define VID_CRTU(x)                                ((x) << 13)
+#       define VID_CRTU_MASK                              (7 << 13)
+#       define SSTU(x)                                    ((x) << 16)
+#       define SSTU_MASK                                  (7 << 16)
+#       define VID_SWT(x)                                 ((x) << 19)
+#       define VID_SWT_MASK                               (0x1f << 19)
+#       define BRT(x)                                     ((x) << 24)
+#       define BRT_MASK                                   (0xff << 24)
+
+#define TARGET_AND_CURRENT_PROFILE_INDEX                  0x70c
+#       define TARGET_PROFILE_INDEX_MASK                  (3 << 0)
+#       define TARGET_PROFILE_INDEX_SHIFT                 0
+#       define CURRENT_PROFILE_INDEX_MASK                 (3 << 2)
+#       define CURRENT_PROFILE_INDEX_SHIFT                2
+#       define DYN_PWR_ENTER_INDEX(x)                     ((x) << 4)
+#       define DYN_PWR_ENTER_INDEX_MASK                   (3 << 4)
+#       define DYN_PWR_ENTER_INDEX_SHIFT                  4
+#       define CURR_MCLK_INDEX_MASK                       (3 << 6)
+#       define CURR_MCLK_INDEX_SHIFT                      6
+#       define CURR_SCLK_INDEX_MASK                       (0x1f << 8)
+#       define CURR_SCLK_INDEX_SHIFT                      8
+#       define CURR_VID_INDEX_MASK                        (3 << 13)
+#       define CURR_VID_INDEX_SHIFT                       13
+
+#define VID_UPPER_GPIO_CNTL                               0x740
+#       define CTXSW_UPPER_GPIO_VALUES(x)                 ((x) << 0)
+#       define CTXSW_UPPER_GPIO_VALUES_MASK               (7 << 0)
+#       define HIGH_UPPER_GPIO_VALUES(x)                  ((x) << 3)
+#       define HIGH_UPPER_GPIO_VALUES_MASK                (7 << 3)
+#       define MEDIUM_UPPER_GPIO_VALUES(x)                ((x) << 6)
+#       define MEDIUM_UPPER_GPIO_VALUES_MASK              (7 << 6)
+#       define LOW_UPPER_GPIO_VALUES(x)                   ((x) << 9)
+#       define LOW_UPPER_GPIO_VALUES_MASK                 (7 << 9)
+#       define CTXSW_BACKBIAS_VALUE                       (1 << 12)
+#       define HIGH_BACKBIAS_VALUE                        (1 << 13)
+#       define MEDIUM_BACKBIAS_VALUE                      (1 << 14)
+#       define LOW_BACKBIAS_VALUE                         (1 << 15)
+
+#define CG_DISPLAY_GAP_CNTL                               0x7dc
+#       define DISP1_GAP(x)                               ((x) << 0)
+#       define DISP1_GAP_MASK                             (3 << 0)
+#       define DISP2_GAP(x)                               ((x) << 2)
+#       define DISP2_GAP_MASK                             (3 << 2)
+#       define VBI_TIMER_COUNT(x)                         ((x) << 4)
+#       define VBI_TIMER_COUNT_MASK                       (0x3fff << 4)
+#       define VBI_TIMER_UNIT(x)                          ((x) << 20)
+#       define VBI_TIMER_UNIT_MASK                        (7 << 20)
+#       define DISP1_GAP_MCHG(x)                          ((x) << 24)
+#       define DISP1_GAP_MCHG_MASK                        (3 << 24)
+#       define DISP2_GAP_MCHG(x)                          ((x) << 26)
+#       define DISP2_GAP_MCHG_MASK                        (3 << 26)
+
+#define CG_THERMAL_CTRL                                   0x7f0
+#       define DPM_EVENT_SRC(x)                           ((x) << 0)
+#       define DPM_EVENT_SRC_MASK                         (7 << 0)
+#       define THERM_INC_CLK                              (1 << 3)
+#       define TOFFSET(x)                                 ((x) << 4)
+#       define TOFFSET_MASK                               (0xff << 4)
+#       define DIG_THERM_DPM(x)                           ((x) << 12)
+#       define DIG_THERM_DPM_MASK                         (0xff << 12)
+#       define CTF_SEL(x)                                 ((x) << 20)
+#       define CTF_SEL_MASK                               (7 << 20)
+#       define CTF_PAD_POLARITY                           (1 << 23)
+#       define CTF_PAD_EN                                 (1 << 24)
+
+#define CG_SPLL_SPREAD_SPECTRUM_LOW                       0x820
+#       define SSEN                                       (1 << 0)
+#       define CLKS(x)                                    ((x) << 3)
+#       define CLKS_MASK                                  (0xff << 3)
+#       define CLKS_SHIFT                                 3
+#       define CLKV(x)                                    ((x) << 11)
+#       define CLKV_MASK                                  (0x7ff << 11)
+#       define CLKV_SHIFT                                 11
+#define CG_MPLL_SPREAD_SPECTRUM                           0x830
+
+#define CITF_CNTL					0x200c
+#       define BLACKOUT_RD                              (1 << 0)
+#       define BLACKOUT_WR                              (1 << 1)
+
+#define RAMCFG						0x2408
+#define		NOOFBANK_SHIFT					0
+#define		NOOFBANK_MASK					0x00000001
+#define		NOOFRANK_SHIFT					1
+#define		NOOFRANK_MASK					0x00000002
+#define		NOOFROWS_SHIFT					2
+#define		NOOFROWS_MASK					0x0000001C
+#define		NOOFCOLS_SHIFT					5
+#define		NOOFCOLS_MASK					0x00000060
+#define		CHANSIZE_SHIFT					7
+#define		CHANSIZE_MASK					0x00000080
+#define		BURSTLENGTH_SHIFT				8
+#define		BURSTLENGTH_MASK				0x00000100
+#define		CHANSIZE_OVERRIDE				(1 << 10)
+
+#define SQM_RATIO					0x2424
+#       define STATE0(x)                                ((x) << 0)
+#       define STATE0_MASK                              (0xff << 0)
+#       define STATE1(x)                                ((x) << 8)
+#       define STATE1_MASK                              (0xff << 8)
+#       define STATE2(x)                                ((x) << 16)
+#       define STATE2_MASK                              (0xff << 16)
+#       define STATE3(x)                                ((x) << 24)
+#       define STATE3_MASK                              (0xff << 24)
+
+#define ARB_RFSH_CNTL					0x2460
+#       define ENABLE                                   (1 << 0)
+#define ARB_RFSH_RATE					0x2464
+#       define POWERMODE0(x)                            ((x) << 0)
+#       define POWERMODE0_MASK                          (0xff << 0)
+#       define POWERMODE1(x)                            ((x) << 8)
+#       define POWERMODE1_MASK                          (0xff << 8)
+#       define POWERMODE2(x)                            ((x) << 16)
+#       define POWERMODE2_MASK                          (0xff << 16)
+#       define POWERMODE3(x)                            ((x) << 24)
+#       define POWERMODE3_MASK                          (0xff << 24)
+
+#define MC_SEQ_DRAM					0x2608
+#       define CKE_DYN                                  (1 << 12)
+
+#define MC_SEQ_CMD					0x26c4
+
+#define MC_SEQ_RESERVE_S				0x2890
+#define MC_SEQ_RESERVE_M				0x2894
+
+#define LVTMA_DATA_SYNCHRONIZATION                      0x7adc
+#       define LVTMA_PFREQCHG                           (1 << 8)
+#define DCE3_LVTMA_DATA_SYNCHRONIZATION                 0x7f98
+
+/* PCIE indirect regs */
+#define PCIE_P_CNTL                                       0x40
+#       define P_PLL_PWRDN_IN_L1L23                       (1 << 3)
+#       define P_PLL_BUF_PDNB                             (1 << 4)
+#       define P_PLL_PDNB                                 (1 << 9)
+#       define P_ALLOW_PRX_FRONTEND_SHUTOFF               (1 << 12)
+/* PCIE PORT indirect regs */
+#define PCIE_LC_CNTL                                      0xa0
+#       define LC_L0S_INACTIVITY(x)                       ((x) << 8)
+#       define LC_L0S_INACTIVITY_MASK                     (0xf << 8)
+#       define LC_L0S_INACTIVITY_SHIFT                    8
+#       define LC_L1_INACTIVITY(x)                        ((x) << 12)
+#       define LC_L1_INACTIVITY_MASK                      (0xf << 12)
+#       define LC_L1_INACTIVITY_SHIFT                     12
+#       define LC_PMI_TO_L1_DIS                           (1 << 16)
+#       define LC_ASPM_TO_L1_DIS                          (1 << 24)
+#define PCIE_LC_SPEED_CNTL                                0xa4
+#       define LC_GEN2_EN                                 (1 << 0)
+#       define LC_INITIATE_LINK_SPEED_CHANGE              (1 << 7)
+#       define LC_CURRENT_DATA_RATE                       (1 << 11)
+#       define LC_HW_VOLTAGE_IF_CONTROL(x)                ((x) << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_MASK              (3 << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_SHIFT             12
+#       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 23)
+#       define LC_OTHER_SIDE_SUPPORTS_GEN2                (1 << 24)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv6xx_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv6xx_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv6xx_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv6xx_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2122 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "rv6xxd.h"
+#include "r600_dpm.h"
+#include "rv6xx_dpm.h"
+#include "atom.h"
+#include <linux/seq_file.h>
+
+static u32 rv6xx_scale_count_given_unit(struct radeon_device *rdev,
+					u32 unscaled_count, u32 unit);
+
+static struct rv6xx_ps *rv6xx_get_ps(struct radeon_ps *rps)
+{
+	struct rv6xx_ps *ps = rps->ps_priv;
+
+	return ps;
+}
+
+static struct rv6xx_power_info *rv6xx_get_pi(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rdev->pm.dpm.priv;
+
+	return pi;
+}
+
+static void rv6xx_force_pcie_gen1(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int i;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+	tmp &= LC_GEN2_EN;
+	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+	tmp |= LC_INITIATE_LINK_SPEED_CHANGE;
+	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (!(RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL) & LC_CURRENT_DATA_RATE))
+			break;
+		udelay(1);
+	}
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+	tmp &= ~LC_INITIATE_LINK_SPEED_CHANGE;
+	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+}
+
+static void rv6xx_enable_pcie_gen2_support(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+
+	if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+	    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+		tmp |= LC_GEN2_EN;
+		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+	}
+}
+
+static void rv6xx_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
+					       bool enable)
+{
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL) & ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+	if (enable)
+		tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
+	else
+		tmp |= LC_HW_VOLTAGE_IF_CONTROL(0);
+	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+}
+
+static void rv6xx_enable_l0s(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL) & ~LC_L0S_INACTIVITY_MASK;
+	tmp |= LC_L0S_INACTIVITY(3);
+	WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
+}
+
+static void rv6xx_enable_l1(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL);
+	tmp &= ~LC_L1_INACTIVITY_MASK;
+	tmp |= LC_L1_INACTIVITY(4);
+	tmp &= ~LC_PMI_TO_L1_DIS;
+	tmp &= ~LC_ASPM_TO_L1_DIS;
+	WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
+}
+
+static void rv6xx_enable_pll_sleep_in_l1(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL) & ~LC_L1_INACTIVITY_MASK;
+	tmp |= LC_L1_INACTIVITY(8);
+	WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
+
+	/* NOTE, this is a PCIE indirect reg, not PCIE PORT */
+	tmp = RREG32_PCIE(PCIE_P_CNTL);
+	tmp |= P_PLL_PWRDN_IN_L1L23;
+	tmp &= ~P_PLL_BUF_PDNB;
+	tmp &= ~P_PLL_PDNB;
+	tmp |= P_ALLOW_PRX_FRONTEND_SHUTOFF;
+	WREG32_PCIE(PCIE_P_CNTL, tmp);
+}
+
+static int rv6xx_convert_clock_to_stepping(struct radeon_device *rdev,
+					   u32 clock, struct rv6xx_sclk_stepping *step)
+{
+	int ret;
+	struct atom_clock_dividers dividers;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     clock, false, &dividers);
+	if (ret)
+		return ret;
+
+	if (dividers.enable_post_div)
+		step->post_divider = 2 + (dividers.post_div & 0xF) + (dividers.post_div >> 4);
+	else
+		step->post_divider = 1;
+
+	step->vco_frequency = clock * step->post_divider;
+
+	return 0;
+}
+
+static void rv6xx_output_stepping(struct radeon_device *rdev,
+				  u32 step_index, struct rv6xx_sclk_stepping *step)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	u32 ref_clk = rdev->clock.spll.reference_freq;
+	u32 fb_divider;
+	u32 spll_step_count = rv6xx_scale_count_given_unit(rdev,
+							   R600_SPLLSTEPTIME_DFLT *
+							   pi->spll_ref_div,
+							   R600_SPLLSTEPUNIT_DFLT);
+
+	r600_engine_clock_entry_enable(rdev, step_index, true);
+	r600_engine_clock_entry_enable_pulse_skipping(rdev, step_index, false);
+
+	if (step->post_divider == 1)
+		r600_engine_clock_entry_enable_post_divider(rdev, step_index, false);
+	else {
+		u32 lo_len = (step->post_divider - 2) / 2;
+		u32 hi_len = step->post_divider - 2 - lo_len;
+
+		r600_engine_clock_entry_enable_post_divider(rdev, step_index, true);
+		r600_engine_clock_entry_set_post_divider(rdev, step_index, (hi_len << 4) | lo_len);
+	}
+
+	fb_divider = ((step->vco_frequency * pi->spll_ref_div) / ref_clk) >>
+		pi->fb_div_scale;
+
+	r600_engine_clock_entry_set_reference_divider(rdev, step_index,
+						      pi->spll_ref_div - 1);
+	r600_engine_clock_entry_set_feedback_divider(rdev, step_index, fb_divider);
+	r600_engine_clock_entry_set_step_time(rdev, step_index, spll_step_count);
+
+}
+
+static struct rv6xx_sclk_stepping rv6xx_next_vco_step(struct radeon_device *rdev,
+						      struct rv6xx_sclk_stepping *cur,
+						      bool increasing_vco, u32 step_size)
+{
+	struct rv6xx_sclk_stepping next;
+
+	next.post_divider = cur->post_divider;
+
+	if (increasing_vco)
+		next.vco_frequency = (cur->vco_frequency * (100 + step_size)) / 100;
+	else
+		next.vco_frequency = (cur->vco_frequency * 100 + 99 + step_size) / (100 + step_size);
+
+	return next;
+}
+
+static bool rv6xx_can_step_post_div(struct radeon_device *rdev,
+				    struct rv6xx_sclk_stepping *cur,
+                                    struct rv6xx_sclk_stepping *target)
+{
+	return (cur->post_divider > target->post_divider) &&
+		((cur->vco_frequency * target->post_divider) <=
+		 (target->vco_frequency * (cur->post_divider - 1)));
+}
+
+static struct rv6xx_sclk_stepping rv6xx_next_post_div_step(struct radeon_device *rdev,
+							   struct rv6xx_sclk_stepping *cur,
+							   struct rv6xx_sclk_stepping *target)
+{
+	struct rv6xx_sclk_stepping next = *cur;
+
+	while (rv6xx_can_step_post_div(rdev, &next, target))
+		next.post_divider--;
+
+	return next;
+}
+
+static bool rv6xx_reached_stepping_target(struct radeon_device *rdev,
+					  struct rv6xx_sclk_stepping *cur,
+					  struct rv6xx_sclk_stepping *target,
+					  bool increasing_vco)
+{
+	return (increasing_vco && (cur->vco_frequency >= target->vco_frequency)) ||
+		(!increasing_vco && (cur->vco_frequency <= target->vco_frequency));
+}
+
+static void rv6xx_generate_steps(struct radeon_device *rdev,
+				 u32 low, u32 high,
+                                 u32 start_index, u8 *end_index)
+{
+	struct rv6xx_sclk_stepping cur;
+	struct rv6xx_sclk_stepping target;
+	bool increasing_vco;
+	u32 step_index = start_index;
+
+	rv6xx_convert_clock_to_stepping(rdev, low, &cur);
+	rv6xx_convert_clock_to_stepping(rdev, high, &target);
+
+	rv6xx_output_stepping(rdev, step_index++, &cur);
+
+	increasing_vco = (target.vco_frequency >= cur.vco_frequency);
+
+	if (target.post_divider > cur.post_divider)
+		cur.post_divider = target.post_divider;
+
+	while (1) {
+		struct rv6xx_sclk_stepping next;
+
+		if (rv6xx_can_step_post_div(rdev, &cur, &target))
+			next = rv6xx_next_post_div_step(rdev, &cur, &target);
+		else
+			next = rv6xx_next_vco_step(rdev, &cur, increasing_vco, R600_VCOSTEPPCT_DFLT);
+
+		if (rv6xx_reached_stepping_target(rdev, &next, &target, increasing_vco)) {
+			struct rv6xx_sclk_stepping tiny =
+				rv6xx_next_vco_step(rdev, &target, !increasing_vco, R600_ENDINGVCOSTEPPCT_DFLT);
+			tiny.post_divider = next.post_divider;
+
+			if (!rv6xx_reached_stepping_target(rdev, &tiny, &cur, !increasing_vco))
+				rv6xx_output_stepping(rdev, step_index++, &tiny);
+
+			if ((next.post_divider != target.post_divider) &&
+			    (next.vco_frequency != target.vco_frequency)) {
+				struct rv6xx_sclk_stepping final_vco;
+
+				final_vco.vco_frequency = target.vco_frequency;
+				final_vco.post_divider = next.post_divider;
+
+				rv6xx_output_stepping(rdev, step_index++, &final_vco);
+			}
+
+			rv6xx_output_stepping(rdev, step_index++, &target);
+			break;
+		} else
+			rv6xx_output_stepping(rdev, step_index++, &next);
+
+		cur = next;
+	}
+
+	*end_index = (u8)step_index - 1;
+
+}
+
+static void rv6xx_generate_single_step(struct radeon_device *rdev,
+				       u32 clock, u32 index)
+{
+	struct rv6xx_sclk_stepping step;
+
+	rv6xx_convert_clock_to_stepping(rdev, clock, &step);
+	rv6xx_output_stepping(rdev, index, &step);
+}
+
+static void rv6xx_invalidate_intermediate_steps_range(struct radeon_device *rdev,
+						      u32 start_index, u32 end_index)
+{
+	u32 step_index;
+
+	for (step_index = start_index + 1; step_index < end_index; step_index++)
+		r600_engine_clock_entry_enable(rdev, step_index, false);
+}
+
+static void rv6xx_set_engine_spread_spectrum_clk_s(struct radeon_device *rdev,
+						   u32 index, u32 clk_s)
+{
+	WREG32_P(CG_SPLL_SPREAD_SPECTRUM_LOW + (index * 4),
+		 CLKS(clk_s), ~CLKS_MASK);
+}
+
+static void rv6xx_set_engine_spread_spectrum_clk_v(struct radeon_device *rdev,
+						   u32 index, u32 clk_v)
+{
+	WREG32_P(CG_SPLL_SPREAD_SPECTRUM_LOW + (index * 4),
+		 CLKV(clk_v), ~CLKV_MASK);
+}
+
+static void rv6xx_enable_engine_spread_spectrum(struct radeon_device *rdev,
+						u32 index, bool enable)
+{
+	if (enable)
+		WREG32_P(CG_SPLL_SPREAD_SPECTRUM_LOW + (index * 4),
+			 SSEN, ~SSEN);
+	else
+		WREG32_P(CG_SPLL_SPREAD_SPECTRUM_LOW + (index * 4),
+			 0, ~SSEN);
+}
+
+static void rv6xx_set_memory_spread_spectrum_clk_s(struct radeon_device *rdev,
+						   u32 clk_s)
+{
+	WREG32_P(CG_MPLL_SPREAD_SPECTRUM, CLKS(clk_s), ~CLKS_MASK);
+}
+
+static void rv6xx_set_memory_spread_spectrum_clk_v(struct radeon_device *rdev,
+						   u32 clk_v)
+{
+	WREG32_P(CG_MPLL_SPREAD_SPECTRUM, CLKV(clk_v), ~CLKV_MASK);
+}
+
+static void rv6xx_enable_memory_spread_spectrum(struct radeon_device *rdev,
+						bool enable)
+{
+	if (enable)
+		WREG32_P(CG_MPLL_SPREAD_SPECTRUM, SSEN, ~SSEN);
+	else
+		WREG32_P(CG_MPLL_SPREAD_SPECTRUM, 0, ~SSEN);
+}
+
+static void rv6xx_enable_dynamic_spread_spectrum(struct radeon_device *rdev,
+						 bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, ~DYN_SPREAD_SPECTRUM_EN);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~DYN_SPREAD_SPECTRUM_EN);
+}
+
+static void rv6xx_memory_clock_entry_enable_post_divider(struct radeon_device *rdev,
+							 u32 index, bool enable)
+{
+	if (enable)
+		WREG32_P(MPLL_FREQ_LEVEL_0 + (index * 4),
+			 LEVEL0_MPLL_DIV_EN, ~LEVEL0_MPLL_DIV_EN);
+	else
+		WREG32_P(MPLL_FREQ_LEVEL_0 + (index * 4), 0, ~LEVEL0_MPLL_DIV_EN);
+}
+
+static void rv6xx_memory_clock_entry_set_post_divider(struct radeon_device *rdev,
+						      u32 index, u32 divider)
+{
+	WREG32_P(MPLL_FREQ_LEVEL_0 + (index * 4),
+		 LEVEL0_MPLL_POST_DIV(divider), ~LEVEL0_MPLL_POST_DIV_MASK);
+}
+
+static void rv6xx_memory_clock_entry_set_feedback_divider(struct radeon_device *rdev,
+							  u32 index, u32 divider)
+{
+	WREG32_P(MPLL_FREQ_LEVEL_0 + (index * 4), LEVEL0_MPLL_FB_DIV(divider),
+		 ~LEVEL0_MPLL_FB_DIV_MASK);
+}
+
+static void rv6xx_memory_clock_entry_set_reference_divider(struct radeon_device *rdev,
+							   u32 index, u32 divider)
+{
+	WREG32_P(MPLL_FREQ_LEVEL_0 + (index * 4),
+		 LEVEL0_MPLL_REF_DIV(divider), ~LEVEL0_MPLL_REF_DIV_MASK);
+}
+
+static void rv6xx_vid_response_set_brt(struct radeon_device *rdev, u32 rt)
+{
+	WREG32_P(VID_RT, BRT(rt), ~BRT_MASK);
+}
+
+static void rv6xx_enable_engine_feedback_and_reference_sync(struct radeon_device *rdev)
+{
+	WREG32_P(SPLL_CNTL_MODE, SPLL_DIV_SYNC, ~SPLL_DIV_SYNC);
+}
+
+static u64 rv6xx_clocks_per_unit(u32 unit)
+{
+	u64 tmp = 1 << (2 * unit);
+
+	return tmp;
+}
+
+static u32 rv6xx_scale_count_given_unit(struct radeon_device *rdev,
+					u32 unscaled_count, u32 unit)
+{
+	u32 count_per_unit = (u32)rv6xx_clocks_per_unit(unit);
+
+	return (unscaled_count + count_per_unit - 1) / count_per_unit;
+}
+
+static u32 rv6xx_compute_count_for_delay(struct radeon_device *rdev,
+					 u32 delay_us, u32 unit)
+{
+	u32 ref_clk = rdev->clock.spll.reference_freq;
+
+	return rv6xx_scale_count_given_unit(rdev, delay_us * (ref_clk / 100), unit);
+}
+
+static void rv6xx_calculate_engine_speed_stepping_parameters(struct radeon_device *rdev,
+							     struct rv6xx_ps *state)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	pi->hw.sclks[R600_POWER_LEVEL_LOW] =
+		state->low.sclk;
+	pi->hw.sclks[R600_POWER_LEVEL_MEDIUM] =
+		state->medium.sclk;
+	pi->hw.sclks[R600_POWER_LEVEL_HIGH] =
+		state->high.sclk;
+
+	pi->hw.low_sclk_index = R600_POWER_LEVEL_LOW;
+	pi->hw.medium_sclk_index = R600_POWER_LEVEL_MEDIUM;
+	pi->hw.high_sclk_index = R600_POWER_LEVEL_HIGH;
+}
+
+static void rv6xx_calculate_memory_clock_stepping_parameters(struct radeon_device *rdev,
+							     struct rv6xx_ps *state)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	pi->hw.mclks[R600_POWER_LEVEL_CTXSW] =
+		state->high.mclk;
+	pi->hw.mclks[R600_POWER_LEVEL_HIGH] =
+		state->high.mclk;
+	pi->hw.mclks[R600_POWER_LEVEL_MEDIUM] =
+		state->medium.mclk;
+	pi->hw.mclks[R600_POWER_LEVEL_LOW] =
+		state->low.mclk;
+
+	pi->hw.high_mclk_index = R600_POWER_LEVEL_HIGH;
+
+	if (state->high.mclk == state->medium.mclk)
+		pi->hw.medium_mclk_index =
+			pi->hw.high_mclk_index;
+	else
+		pi->hw.medium_mclk_index = R600_POWER_LEVEL_MEDIUM;
+
+
+	if (state->medium.mclk == state->low.mclk)
+		pi->hw.low_mclk_index =
+			pi->hw.medium_mclk_index;
+	else
+		pi->hw.low_mclk_index = R600_POWER_LEVEL_LOW;
+}
+
+static void rv6xx_calculate_voltage_stepping_parameters(struct radeon_device *rdev,
+							struct rv6xx_ps *state)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	pi->hw.vddc[R600_POWER_LEVEL_CTXSW] = state->high.vddc;
+	pi->hw.vddc[R600_POWER_LEVEL_HIGH] = state->high.vddc;
+	pi->hw.vddc[R600_POWER_LEVEL_MEDIUM] = state->medium.vddc;
+	pi->hw.vddc[R600_POWER_LEVEL_LOW] = state->low.vddc;
+
+	pi->hw.backbias[R600_POWER_LEVEL_CTXSW] =
+		(state->high.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ? true : false;
+	pi->hw.backbias[R600_POWER_LEVEL_HIGH] =
+		(state->high.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ? true : false;
+	pi->hw.backbias[R600_POWER_LEVEL_MEDIUM] =
+		(state->medium.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ? true : false;
+	pi->hw.backbias[R600_POWER_LEVEL_LOW] =
+		(state->low.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ? true : false;
+
+	pi->hw.pcie_gen2[R600_POWER_LEVEL_HIGH] =
+		(state->high.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? true : false;
+	pi->hw.pcie_gen2[R600_POWER_LEVEL_MEDIUM] =
+		(state->medium.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? true : false;
+	pi->hw.pcie_gen2[R600_POWER_LEVEL_LOW] =
+		(state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? true : false;
+
+	pi->hw.high_vddc_index = R600_POWER_LEVEL_HIGH;
+
+	if ((state->high.vddc == state->medium.vddc) &&
+	    ((state->high.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ==
+	     (state->medium.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE)))
+		pi->hw.medium_vddc_index =
+			pi->hw.high_vddc_index;
+	else
+		pi->hw.medium_vddc_index = R600_POWER_LEVEL_MEDIUM;
+
+	if ((state->medium.vddc == state->low.vddc) &&
+	    ((state->medium.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ==
+	     (state->low.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE)))
+		pi->hw.low_vddc_index =
+			pi->hw.medium_vddc_index;
+	else
+		pi->hw.medium_vddc_index = R600_POWER_LEVEL_LOW;
+}
+
+static inline u32 rv6xx_calculate_vco_frequency(u32 ref_clock,
+						struct atom_clock_dividers *dividers,
+						u32 fb_divider_scale)
+{
+	return ref_clock * ((dividers->fb_div & ~1) << fb_divider_scale) /
+		(dividers->ref_div + 1);
+}
+
+static inline u32 rv6xx_calculate_spread_spectrum_clk_v(u32 vco_freq, u32 ref_freq,
+							u32 ss_rate, u32 ss_percent,
+							u32 fb_divider_scale)
+{
+	u32 fb_divider = vco_freq / ref_freq;
+
+	return (ss_percent * ss_rate * 4 * (fb_divider * fb_divider) /
+		(5375 * ((vco_freq * 10) / (4096 >> fb_divider_scale))));
+}
+
+static inline u32 rv6xx_calculate_spread_spectrum_clk_s(u32 ss_rate, u32 ref_freq)
+{
+	return (((ref_freq * 10) / (ss_rate * 2)) - 1) / 4;
+}
+
+static void rv6xx_program_engine_spread_spectrum(struct radeon_device *rdev,
+						 u32 clock, enum r600_power_level level)
+{
+	u32 ref_clk = rdev->clock.spll.reference_freq;
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	struct atom_clock_dividers dividers;
+	struct radeon_atom_ss ss;
+	u32 vco_freq, clk_v, clk_s;
+
+	rv6xx_enable_engine_spread_spectrum(rdev, level, false);
+
+	if (clock && pi->sclk_ss) {
+		if (radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, clock, false, &dividers) == 0) {
+			vco_freq = rv6xx_calculate_vco_frequency(ref_clk, &dividers,
+								 pi->fb_div_scale);
+
+			if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+							     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
+				clk_v = rv6xx_calculate_spread_spectrum_clk_v(vco_freq,
+									      (ref_clk / (dividers.ref_div + 1)),
+									      ss.rate,
+									      ss.percentage,
+									      pi->fb_div_scale);
+
+				clk_s = rv6xx_calculate_spread_spectrum_clk_s(ss.rate,
+									      (ref_clk / (dividers.ref_div + 1)));
+
+				rv6xx_set_engine_spread_spectrum_clk_v(rdev, level, clk_v);
+				rv6xx_set_engine_spread_spectrum_clk_s(rdev, level, clk_s);
+				rv6xx_enable_engine_spread_spectrum(rdev, level, true);
+			}
+		}
+	}
+}
+
+static void rv6xx_program_sclk_spread_spectrum_parameters_except_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	rv6xx_program_engine_spread_spectrum(rdev,
+					     pi->hw.sclks[R600_POWER_LEVEL_HIGH],
+					     R600_POWER_LEVEL_HIGH);
+
+	rv6xx_program_engine_spread_spectrum(rdev,
+					     pi->hw.sclks[R600_POWER_LEVEL_MEDIUM],
+					     R600_POWER_LEVEL_MEDIUM);
+
+}
+
+static int rv6xx_program_mclk_stepping_entry(struct radeon_device *rdev,
+					     u32 entry, u32 clock)
+{
+	struct atom_clock_dividers dividers;
+
+	if (radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM, clock, false, &dividers))
+	    return -EINVAL;
+
+
+	rv6xx_memory_clock_entry_set_reference_divider(rdev, entry, dividers.ref_div);
+	rv6xx_memory_clock_entry_set_feedback_divider(rdev, entry, dividers.fb_div);
+	rv6xx_memory_clock_entry_set_post_divider(rdev, entry, dividers.post_div);
+
+	if (dividers.enable_post_div)
+		rv6xx_memory_clock_entry_enable_post_divider(rdev, entry, true);
+	else
+		rv6xx_memory_clock_entry_enable_post_divider(rdev, entry, false);
+
+	return 0;
+}
+
+static void rv6xx_program_mclk_stepping_parameters_except_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	int i;
+
+	for (i = 1; i < R600_PM_NUMBER_OF_MCLKS; i++) {
+		if (pi->hw.mclks[i])
+			rv6xx_program_mclk_stepping_entry(rdev, i,
+							  pi->hw.mclks[i]);
+	}
+}
+
+static void rv6xx_find_memory_clock_with_highest_vco(struct radeon_device *rdev,
+						     u32 requested_memory_clock,
+						     u32 ref_clk,
+						     struct atom_clock_dividers *dividers,
+						     u32 *vco_freq)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	struct atom_clock_dividers req_dividers;
+	u32 vco_freq_temp;
+
+	if (radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
+					   requested_memory_clock, false, &req_dividers) == 0) {
+		vco_freq_temp = rv6xx_calculate_vco_frequency(ref_clk, &req_dividers,
+							      pi->fb_div_scale);
+
+		if (vco_freq_temp > *vco_freq) {
+			*dividers = req_dividers;
+			*vco_freq = vco_freq_temp;
+		}
+	}
+}
+
+static void rv6xx_program_mclk_spread_spectrum_parameters(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	u32 ref_clk = rdev->clock.mpll.reference_freq;
+	struct atom_clock_dividers dividers;
+	struct radeon_atom_ss ss;
+	u32 vco_freq = 0, clk_v, clk_s;
+
+	rv6xx_enable_memory_spread_spectrum(rdev, false);
+
+	if (pi->mclk_ss) {
+		rv6xx_find_memory_clock_with_highest_vco(rdev,
+							 pi->hw.mclks[pi->hw.high_mclk_index],
+							 ref_clk,
+							 &dividers,
+							 &vco_freq);
+
+		rv6xx_find_memory_clock_with_highest_vco(rdev,
+							 pi->hw.mclks[pi->hw.medium_mclk_index],
+							 ref_clk,
+							 &dividers,
+							 &vco_freq);
+
+		rv6xx_find_memory_clock_with_highest_vco(rdev,
+							 pi->hw.mclks[pi->hw.low_mclk_index],
+							 ref_clk,
+							 &dividers,
+							 &vco_freq);
+
+		if (vco_freq) {
+			if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+							     ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
+				clk_v = rv6xx_calculate_spread_spectrum_clk_v(vco_freq,
+									     (ref_clk / (dividers.ref_div + 1)),
+									     ss.rate,
+									     ss.percentage,
+									     pi->fb_div_scale);
+
+				clk_s = rv6xx_calculate_spread_spectrum_clk_s(ss.rate,
+									     (ref_clk / (dividers.ref_div + 1)));
+
+				rv6xx_set_memory_spread_spectrum_clk_v(rdev, clk_v);
+				rv6xx_set_memory_spread_spectrum_clk_s(rdev, clk_s);
+				rv6xx_enable_memory_spread_spectrum(rdev, true);
+			}
+		}
+	}
+}
+
+static int rv6xx_program_voltage_stepping_entry(struct radeon_device *rdev,
+						u32 entry, u16 voltage)
+{
+	u32 mask, set_pins;
+	int ret;
+
+	ret = radeon_atom_get_voltage_gpio_settings(rdev, voltage,
+						    SET_VOLTAGE_TYPE_ASIC_VDDC,
+						    &set_pins, &mask);
+	if (ret)
+		return ret;
+
+	r600_voltage_control_program_voltages(rdev, entry, set_pins);
+
+	return 0;
+}
+
+static void rv6xx_program_voltage_stepping_parameters_except_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	int i;
+
+	for (i = 1; i < R600_PM_NUMBER_OF_VOLTAGE_LEVELS; i++)
+		rv6xx_program_voltage_stepping_entry(rdev, i,
+						     pi->hw.vddc[i]);
+
+}
+
+static void rv6xx_program_backbias_stepping_parameters_except_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	if (pi->hw.backbias[1])
+		WREG32_P(VID_UPPER_GPIO_CNTL, MEDIUM_BACKBIAS_VALUE, ~MEDIUM_BACKBIAS_VALUE);
+	else
+		WREG32_P(VID_UPPER_GPIO_CNTL, 0, ~MEDIUM_BACKBIAS_VALUE);
+
+	if (pi->hw.backbias[2])
+		WREG32_P(VID_UPPER_GPIO_CNTL, HIGH_BACKBIAS_VALUE, ~HIGH_BACKBIAS_VALUE);
+	else
+		WREG32_P(VID_UPPER_GPIO_CNTL, 0, ~HIGH_BACKBIAS_VALUE);
+}
+
+static void rv6xx_program_sclk_spread_spectrum_parameters_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	rv6xx_program_engine_spread_spectrum(rdev,
+					     pi->hw.sclks[R600_POWER_LEVEL_LOW],
+					     R600_POWER_LEVEL_LOW);
+}
+
+static void rv6xx_program_mclk_stepping_parameters_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	if (pi->hw.mclks[0])
+		rv6xx_program_mclk_stepping_entry(rdev, 0,
+						  pi->hw.mclks[0]);
+}
+
+static void rv6xx_program_voltage_stepping_parameters_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	rv6xx_program_voltage_stepping_entry(rdev, 0,
+					     pi->hw.vddc[0]);
+
+}
+
+static void rv6xx_program_backbias_stepping_parameters_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	if (pi->hw.backbias[0])
+		WREG32_P(VID_UPPER_GPIO_CNTL, LOW_BACKBIAS_VALUE, ~LOW_BACKBIAS_VALUE);
+	else
+		WREG32_P(VID_UPPER_GPIO_CNTL, 0, ~LOW_BACKBIAS_VALUE);
+}
+
+static u32 calculate_memory_refresh_rate(struct radeon_device *rdev,
+					 u32 engine_clock)
+{
+	u32 dram_rows, dram_refresh_rate;
+	u32 tmp;
+
+	tmp = (RREG32(RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
+	dram_rows = 1 << (tmp + 10);
+	dram_refresh_rate = 1 << ((RREG32(MC_SEQ_RESERVE_M) & 0x3) + 3);
+
+	return ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64;
+}
+
+static void rv6xx_program_memory_timing_parameters(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	u32 sqm_ratio;
+	u32 arb_refresh_rate;
+	u32 high_clock;
+
+	if (pi->hw.sclks[R600_POWER_LEVEL_HIGH] <
+	    (pi->hw.sclks[R600_POWER_LEVEL_LOW] * 0xFF / 0x40))
+		high_clock = pi->hw.sclks[R600_POWER_LEVEL_HIGH];
+	else
+		high_clock =
+			pi->hw.sclks[R600_POWER_LEVEL_LOW] * 0xFF / 0x40;
+
+	radeon_atom_set_engine_dram_timings(rdev, high_clock, 0);
+
+	sqm_ratio = (STATE0(64 * high_clock / pi->hw.sclks[R600_POWER_LEVEL_LOW]) |
+		     STATE1(64 * high_clock / pi->hw.sclks[R600_POWER_LEVEL_MEDIUM]) |
+		     STATE2(64 * high_clock / pi->hw.sclks[R600_POWER_LEVEL_HIGH]) |
+		     STATE3(64 * high_clock / pi->hw.sclks[R600_POWER_LEVEL_HIGH]));
+	WREG32(SQM_RATIO, sqm_ratio);
+
+	arb_refresh_rate =
+		(POWERMODE0(calculate_memory_refresh_rate(rdev,
+							  pi->hw.sclks[R600_POWER_LEVEL_LOW])) |
+		 POWERMODE1(calculate_memory_refresh_rate(rdev,
+							  pi->hw.sclks[R600_POWER_LEVEL_MEDIUM])) |
+		 POWERMODE2(calculate_memory_refresh_rate(rdev,
+							  pi->hw.sclks[R600_POWER_LEVEL_HIGH])) |
+		 POWERMODE3(calculate_memory_refresh_rate(rdev,
+							  pi->hw.sclks[R600_POWER_LEVEL_HIGH])));
+	WREG32(ARB_RFSH_RATE, arb_refresh_rate);
+}
+
+static void rv6xx_program_mpll_timing_parameters(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	r600_set_mpll_lock_time(rdev, R600_MPLLLOCKTIME_DFLT *
+				pi->mpll_ref_div);
+	r600_set_mpll_reset_time(rdev, R600_MPLLRESETTIME_DFLT);
+}
+
+static void rv6xx_program_bsp(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	u32 ref_clk = rdev->clock.spll.reference_freq;
+
+	r600_calculate_u_and_p(R600_ASI_DFLT,
+			       ref_clk, 16,
+			       &pi->bsp,
+			       &pi->bsu);
+
+	r600_set_bsp(rdev, pi->bsu, pi->bsp);
+}
+
+static void rv6xx_program_at(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	r600_set_at(rdev,
+		    (pi->hw.rp[0] * pi->bsp) / 200,
+		    (pi->hw.rp[1] * pi->bsp) / 200,
+		    (pi->hw.lp[2] * pi->bsp) / 200,
+		    (pi->hw.lp[1] * pi->bsp) / 200);
+}
+
+static void rv6xx_program_git(struct radeon_device *rdev)
+{
+	r600_set_git(rdev, R600_GICST_DFLT);
+}
+
+static void rv6xx_program_tp(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)
+		r600_set_tc(rdev, i, r600_utc[i], r600_dtc[i]);
+
+	r600_select_td(rdev, R600_TD_DFLT);
+}
+
+static void rv6xx_program_vc(struct radeon_device *rdev)
+{
+	r600_set_vrc(rdev, R600_VRC_DFLT);
+}
+
+static void rv6xx_clear_vc(struct radeon_device *rdev)
+{
+	r600_set_vrc(rdev, 0);
+}
+
+static void rv6xx_program_tpp(struct radeon_device *rdev)
+{
+	r600_set_tpu(rdev, R600_TPU_DFLT);
+	r600_set_tpc(rdev, R600_TPC_DFLT);
+}
+
+static void rv6xx_program_sstp(struct radeon_device *rdev)
+{
+	r600_set_sstu(rdev, R600_SSTU_DFLT);
+	r600_set_sst(rdev, R600_SST_DFLT);
+}
+
+static void rv6xx_program_fcp(struct radeon_device *rdev)
+{
+	r600_set_fctu(rdev, R600_FCTU_DFLT);
+	r600_set_fct(rdev, R600_FCT_DFLT);
+}
+
+static void rv6xx_program_vddc3d_parameters(struct radeon_device *rdev)
+{
+	r600_set_vddc3d_oorsu(rdev, R600_VDDC3DOORSU_DFLT);
+	r600_set_vddc3d_oorphc(rdev, R600_VDDC3DOORPHC_DFLT);
+	r600_set_vddc3d_oorsdc(rdev, R600_VDDC3DOORSDC_DFLT);
+	r600_set_ctxcgtt3d_rphc(rdev, R600_CTXCGTT3DRPHC_DFLT);
+	r600_set_ctxcgtt3d_rsdc(rdev, R600_CTXCGTT3DRSDC_DFLT);
+}
+
+static void rv6xx_program_voltage_timing_parameters(struct radeon_device *rdev)
+{
+	u32 rt;
+
+	r600_vid_rt_set_vru(rdev, R600_VRU_DFLT);
+
+	r600_vid_rt_set_vrt(rdev,
+			    rv6xx_compute_count_for_delay(rdev,
+							  rdev->pm.dpm.voltage_response_time,
+							  R600_VRU_DFLT));
+
+	rt = rv6xx_compute_count_for_delay(rdev,
+					   rdev->pm.dpm.backbias_response_time,
+					   R600_VRU_DFLT);
+
+	rv6xx_vid_response_set_brt(rdev, (rt + 0x1F) >> 5);
+}
+
+static void rv6xx_program_engine_speed_parameters(struct radeon_device *rdev)
+{
+	r600_vid_rt_set_ssu(rdev, R600_SPLLSTEPUNIT_DFLT);
+	rv6xx_enable_engine_feedback_and_reference_sync(rdev);
+}
+
+static u64 rv6xx_get_master_voltage_mask(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	u64 master_mask = 0;
+	int i;
+
+	for (i = 0; i < R600_PM_NUMBER_OF_VOLTAGE_LEVELS; i++) {
+		u32 tmp_mask, tmp_set_pins;
+		int ret;
+
+		ret = radeon_atom_get_voltage_gpio_settings(rdev,
+							    pi->hw.vddc[i],
+							    SET_VOLTAGE_TYPE_ASIC_VDDC,
+							    &tmp_set_pins, &tmp_mask);
+
+		if (ret == 0)
+			master_mask |= tmp_mask;
+	}
+
+	return master_mask;
+}
+
+static void rv6xx_program_voltage_gpio_pins(struct radeon_device *rdev)
+{
+	r600_voltage_control_enable_pins(rdev,
+					 rv6xx_get_master_voltage_mask(rdev));
+}
+
+static void rv6xx_enable_static_voltage_control(struct radeon_device *rdev,
+						struct radeon_ps *new_ps,
+						bool enable)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+
+	if (enable)
+		radeon_atom_set_voltage(rdev,
+					new_state->low.vddc,
+					SET_VOLTAGE_TYPE_ASIC_VDDC);
+	else
+		r600_voltage_control_deactivate_static_control(rdev,
+							       rv6xx_get_master_voltage_mask(rdev));
+}
+
+static void rv6xx_enable_display_gap(struct radeon_device *rdev, bool enable)
+{
+	if (enable) {
+		u32 tmp = (DISP1_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM) |
+			   DISP2_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM) |
+			   DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE) |
+			   DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE) |
+			   VBI_TIMER_COUNT(0x3FFF) |
+			   VBI_TIMER_UNIT(7));
+		WREG32(CG_DISPLAY_GAP_CNTL, tmp);
+
+		WREG32_P(MCLK_PWRMGT_CNTL, USE_DISPLAY_GAP, ~USE_DISPLAY_GAP);
+	} else
+		WREG32_P(MCLK_PWRMGT_CNTL, 0, ~USE_DISPLAY_GAP);
+}
+
+static void rv6xx_program_power_level_enter_state(struct radeon_device *rdev)
+{
+	r600_power_level_set_enter_index(rdev, R600_POWER_LEVEL_MEDIUM);
+}
+
+static void rv6xx_calculate_t(u32 l_f, u32 h_f, int h,
+			      int d_l, int d_r, u8 *l, u8 *r)
+{
+	int a_n, a_d, h_r, l_r;
+
+	h_r = d_l;
+	l_r = 100 - d_r;
+
+	a_n = (int)h_f * d_l + (int)l_f * (h - d_r);
+	a_d = (int)l_f * l_r + (int)h_f * h_r;
+
+	if (a_d != 0) {
+		*l = d_l - h_r * a_n / a_d;
+		*r = d_r + l_r * a_n / a_d;
+	}
+}
+
+static void rv6xx_calculate_ap(struct radeon_device *rdev,
+			       struct rv6xx_ps *state)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	pi->hw.lp[0] = 0;
+	pi->hw.rp[R600_PM_NUMBER_OF_ACTIVITY_LEVELS - 1]
+		= 100;
+
+	rv6xx_calculate_t(state->low.sclk,
+			  state->medium.sclk,
+			  R600_AH_DFLT,
+			  R600_LMP_DFLT,
+			  R600_RLP_DFLT,
+			  &pi->hw.lp[1],
+			  &pi->hw.rp[0]);
+
+	rv6xx_calculate_t(state->medium.sclk,
+			  state->high.sclk,
+			  R600_AH_DFLT,
+			  R600_LHP_DFLT,
+			  R600_RMP_DFLT,
+			  &pi->hw.lp[2],
+			  &pi->hw.rp[1]);
+
+}
+
+static void rv6xx_calculate_stepping_parameters(struct radeon_device *rdev,
+						struct radeon_ps *new_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+
+	rv6xx_calculate_engine_speed_stepping_parameters(rdev, new_state);
+	rv6xx_calculate_memory_clock_stepping_parameters(rdev, new_state);
+	rv6xx_calculate_voltage_stepping_parameters(rdev, new_state);
+	rv6xx_calculate_ap(rdev, new_state);
+}
+
+static void rv6xx_program_stepping_parameters_except_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	rv6xx_program_mclk_stepping_parameters_except_lowest_entry(rdev);
+	if (pi->voltage_control)
+		rv6xx_program_voltage_stepping_parameters_except_lowest_entry(rdev);
+	rv6xx_program_backbias_stepping_parameters_except_lowest_entry(rdev);
+	rv6xx_program_sclk_spread_spectrum_parameters_except_lowest_entry(rdev);
+	rv6xx_program_mclk_spread_spectrum_parameters(rdev);
+	rv6xx_program_memory_timing_parameters(rdev);
+}
+
+static void rv6xx_program_stepping_parameters_lowest_entry(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	rv6xx_program_mclk_stepping_parameters_lowest_entry(rdev);
+	if (pi->voltage_control)
+		rv6xx_program_voltage_stepping_parameters_lowest_entry(rdev);
+	rv6xx_program_backbias_stepping_parameters_lowest_entry(rdev);
+	rv6xx_program_sclk_spread_spectrum_parameters_lowest_entry(rdev);
+}
+
+static void rv6xx_program_power_level_low(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_LOW,
+					   pi->hw.low_vddc_index);
+	r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_LOW,
+					     pi->hw.low_mclk_index);
+	r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_LOW,
+					     pi->hw.low_sclk_index);
+	r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_LOW,
+					  R600_DISPLAY_WATERMARK_LOW);
+	r600_power_level_set_pcie_gen2(rdev, R600_POWER_LEVEL_LOW,
+				       pi->hw.pcie_gen2[R600_POWER_LEVEL_LOW]);
+}
+
+static void rv6xx_program_power_level_low_to_lowest_state(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_LOW, 0);
+	r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_LOW, 0);
+	r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_LOW, 0);
+
+	r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_LOW,
+					  R600_DISPLAY_WATERMARK_LOW);
+
+	r600_power_level_set_pcie_gen2(rdev, R600_POWER_LEVEL_LOW,
+				       pi->hw.pcie_gen2[R600_POWER_LEVEL_LOW]);
+
+}
+
+static void rv6xx_program_power_level_medium(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_MEDIUM,
+					  pi->hw.medium_vddc_index);
+	r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_MEDIUM,
+					    pi->hw.medium_mclk_index);
+	r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_MEDIUM,
+					    pi->hw.medium_sclk_index);
+	r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_MEDIUM,
+					 R600_DISPLAY_WATERMARK_LOW);
+	r600_power_level_set_pcie_gen2(rdev, R600_POWER_LEVEL_MEDIUM,
+				      pi->hw.pcie_gen2[R600_POWER_LEVEL_MEDIUM]);
+}
+
+static void rv6xx_program_power_level_medium_for_transition(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	rv6xx_program_mclk_stepping_entry(rdev,
+					  R600_POWER_LEVEL_CTXSW,
+					  pi->hw.mclks[pi->hw.low_mclk_index]);
+
+	r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_MEDIUM, 1);
+
+	r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_MEDIUM,
+					     R600_POWER_LEVEL_CTXSW);
+	r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_MEDIUM,
+					     pi->hw.medium_sclk_index);
+
+	r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_MEDIUM,
+					  R600_DISPLAY_WATERMARK_LOW);
+
+	rv6xx_enable_engine_spread_spectrum(rdev, R600_POWER_LEVEL_MEDIUM, false);
+
+	r600_power_level_set_pcie_gen2(rdev, R600_POWER_LEVEL_MEDIUM,
+				       pi->hw.pcie_gen2[R600_POWER_LEVEL_LOW]);
+}
+
+static void rv6xx_program_power_level_high(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_HIGH,
+					   pi->hw.high_vddc_index);
+	r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_HIGH,
+					     pi->hw.high_mclk_index);
+	r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_HIGH,
+					     pi->hw.high_sclk_index);
+
+	r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_HIGH,
+					  R600_DISPLAY_WATERMARK_HIGH);
+
+	r600_power_level_set_pcie_gen2(rdev, R600_POWER_LEVEL_HIGH,
+				       pi->hw.pcie_gen2[R600_POWER_LEVEL_HIGH]);
+}
+
+static void rv6xx_enable_backbias(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, BACKBIAS_PAD_EN | BACKBIAS_DPM_CNTL,
+			 ~(BACKBIAS_PAD_EN | BACKBIAS_DPM_CNTL));
+	else
+		WREG32_P(GENERAL_PWRMGT, 0,
+			 ~(BACKBIAS_VALUE | BACKBIAS_PAD_EN | BACKBIAS_DPM_CNTL));
+}
+
+static void rv6xx_program_display_gap(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
+
+	tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
+	if (rdev->pm.dpm.new_active_crtcs & 1) {
+		tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
+		tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
+	} else if (rdev->pm.dpm.new_active_crtcs & 2) {
+		tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
+		tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
+	} else {
+		tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
+		tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
+	}
+	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
+}
+
+static void rv6xx_set_sw_voltage_to_safe(struct radeon_device *rdev,
+					 struct radeon_ps *new_ps,
+					 struct radeon_ps *old_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);
+	u16 safe_voltage;
+
+	safe_voltage = (new_state->low.vddc >= old_state->low.vddc) ?
+		new_state->low.vddc : old_state->low.vddc;
+
+	rv6xx_program_voltage_stepping_entry(rdev, R600_POWER_LEVEL_CTXSW,
+					     safe_voltage);
+
+	WREG32_P(GENERAL_PWRMGT, SW_GPIO_INDEX(R600_POWER_LEVEL_CTXSW),
+		 ~SW_GPIO_INDEX_MASK);
+}
+
+static void rv6xx_set_sw_voltage_to_low(struct radeon_device *rdev,
+					struct radeon_ps *old_ps)
+{
+	struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);
+
+	rv6xx_program_voltage_stepping_entry(rdev, R600_POWER_LEVEL_CTXSW,
+					     old_state->low.vddc);
+
+	WREG32_P(GENERAL_PWRMGT, SW_GPIO_INDEX(R600_POWER_LEVEL_CTXSW),
+		~SW_GPIO_INDEX_MASK);
+}
+
+static void rv6xx_set_safe_backbias(struct radeon_device *rdev,
+				    struct radeon_ps *new_ps,
+				    struct radeon_ps *old_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);
+
+	if ((new_state->low.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) &&
+	    (old_state->low.flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE))
+		WREG32_P(GENERAL_PWRMGT, BACKBIAS_VALUE, ~BACKBIAS_VALUE);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~BACKBIAS_VALUE);
+}
+
+static void rv6xx_set_safe_pcie_gen2(struct radeon_device *rdev,
+				     struct radeon_ps *new_ps,
+				     struct radeon_ps *old_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);
+
+	if ((new_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) !=
+	    (old_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2))
+		rv6xx_force_pcie_gen1(rdev);
+}
+
+static void rv6xx_enable_dynamic_voltage_control(struct radeon_device *rdev,
+						 bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, VOLT_PWRMGT_EN, ~VOLT_PWRMGT_EN);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~VOLT_PWRMGT_EN);
+}
+
+static void rv6xx_enable_dynamic_backbias_control(struct radeon_device *rdev,
+						  bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, BACKBIAS_DPM_CNTL, ~BACKBIAS_DPM_CNTL);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~BACKBIAS_DPM_CNTL);
+}
+
+static int rv6xx_step_sw_voltage(struct radeon_device *rdev,
+				 u16 initial_voltage,
+				 u16 target_voltage)
+{
+	u16 current_voltage;
+	u16 true_target_voltage;
+	u16 voltage_step;
+	int signed_voltage_step;
+
+	if ((radeon_atom_get_voltage_step(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
+					  &voltage_step)) ||
+	    (radeon_atom_round_to_true_voltage(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
+					       initial_voltage, &current_voltage)) ||
+	    (radeon_atom_round_to_true_voltage(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
+					       target_voltage, &true_target_voltage)))
+		return -EINVAL;
+
+	if (true_target_voltage < current_voltage)
+		signed_voltage_step = -(int)voltage_step;
+	else
+		signed_voltage_step = voltage_step;
+
+	while (current_voltage != true_target_voltage) {
+		current_voltage += signed_voltage_step;
+		rv6xx_program_voltage_stepping_entry(rdev, R600_POWER_LEVEL_CTXSW,
+						     current_voltage);
+		msleep((rdev->pm.dpm.voltage_response_time + 999) / 1000);
+	}
+
+	return 0;
+}
+
+static int rv6xx_step_voltage_if_increasing(struct radeon_device *rdev,
+					    struct radeon_ps *new_ps,
+					    struct radeon_ps *old_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);
+
+	if (new_state->low.vddc > old_state->low.vddc)
+		return rv6xx_step_sw_voltage(rdev,
+					     old_state->low.vddc,
+					     new_state->low.vddc);
+
+	return 0;
+}
+
+static int rv6xx_step_voltage_if_decreasing(struct radeon_device *rdev,
+					    struct radeon_ps *new_ps,
+					    struct radeon_ps *old_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);
+
+	if (new_state->low.vddc < old_state->low.vddc)
+		return rv6xx_step_sw_voltage(rdev,
+					     old_state->low.vddc,
+					     new_state->low.vddc);
+	else
+		return 0;
+}
+
+static void rv6xx_enable_high(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	if ((pi->restricted_levels < 1) ||
+	    (pi->restricted_levels == 3))
+		r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, true);
+}
+
+static void rv6xx_enable_medium(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	if (pi->restricted_levels < 2)
+		r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, true);
+}
+
+static void rv6xx_set_dpm_event_sources(struct radeon_device *rdev, u32 sources)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	bool want_thermal_protection;
+	enum radeon_dpm_event_src dpm_event_src;
+
+	switch (sources) {
+        case 0:
+        default:
+		want_thermal_protection = false;
+		break;
+        case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL):
+		want_thermal_protection = true;
+		dpm_event_src = RADEON_DPM_EVENT_SRC_DIGITAL;
+		break;
+
+        case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL):
+		want_thermal_protection = true;
+		dpm_event_src = RADEON_DPM_EVENT_SRC_EXTERNAL;
+		break;
+
+        case ((1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL) |
+	      (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL)):
+		want_thermal_protection = true;
+		dpm_event_src = RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL;
+		break;
+	}
+
+	if (want_thermal_protection) {
+		WREG32_P(CG_THERMAL_CTRL, DPM_EVENT_SRC(dpm_event_src), ~DPM_EVENT_SRC_MASK);
+		if (pi->thermal_protection)
+			WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
+	} else {
+		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
+	}
+}
+
+static void rv6xx_enable_auto_throttle_source(struct radeon_device *rdev,
+					      enum radeon_dpm_auto_throttle_src source,
+					      bool enable)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	if (enable) {
+		if (!(pi->active_auto_throttle_sources & (1 << source))) {
+			pi->active_auto_throttle_sources |= 1 << source;
+			rv6xx_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
+		}
+	} else {
+		if (pi->active_auto_throttle_sources & (1 << source)) {
+			pi->active_auto_throttle_sources &= ~(1 << source);
+			rv6xx_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
+		}
+	}
+}
+
+
+static void rv6xx_enable_thermal_protection(struct radeon_device *rdev,
+					    bool enable)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	if (pi->active_auto_throttle_sources)
+		r600_enable_thermal_protection(rdev, enable);
+}
+
+static void rv6xx_generate_transition_stepping(struct radeon_device *rdev,
+					       struct radeon_ps *new_ps,
+					       struct radeon_ps *old_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_ps *old_state = rv6xx_get_ps(old_ps);
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	rv6xx_generate_steps(rdev,
+			     old_state->low.sclk,
+			     new_state->low.sclk,
+			     0, &pi->hw.medium_sclk_index);
+}
+
+static void rv6xx_generate_low_step(struct radeon_device *rdev,
+				    struct radeon_ps *new_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	pi->hw.low_sclk_index = 0;
+	rv6xx_generate_single_step(rdev,
+				   new_state->low.sclk,
+				   0);
+}
+
+static void rv6xx_invalidate_intermediate_steps(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	rv6xx_invalidate_intermediate_steps_range(rdev, 0,
+						  pi->hw.medium_sclk_index);
+}
+
+static void rv6xx_generate_stepping_table(struct radeon_device *rdev,
+					  struct radeon_ps *new_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	pi->hw.low_sclk_index = 0;
+
+	rv6xx_generate_steps(rdev,
+			     new_state->low.sclk,
+			     new_state->medium.sclk,
+			     0,
+			     &pi->hw.medium_sclk_index);
+	rv6xx_generate_steps(rdev,
+			     new_state->medium.sclk,
+			     new_state->high.sclk,
+			     pi->hw.medium_sclk_index,
+			     &pi->hw.high_sclk_index);
+}
+
+static void rv6xx_enable_spread_spectrum(struct radeon_device *rdev,
+					 bool enable)
+{
+	if (enable)
+		rv6xx_enable_dynamic_spread_spectrum(rdev, true);
+	else {
+		rv6xx_enable_engine_spread_spectrum(rdev, R600_POWER_LEVEL_LOW, false);
+		rv6xx_enable_engine_spread_spectrum(rdev, R600_POWER_LEVEL_MEDIUM, false);
+		rv6xx_enable_engine_spread_spectrum(rdev, R600_POWER_LEVEL_HIGH, false);
+		rv6xx_enable_dynamic_spread_spectrum(rdev, false);
+		rv6xx_enable_memory_spread_spectrum(rdev, false);
+	}
+}
+
+static void rv6xx_reset_lvtm_data_sync(struct radeon_device *rdev)
+{
+	if (ASIC_IS_DCE3(rdev))
+		WREG32_P(DCE3_LVTMA_DATA_SYNCHRONIZATION, LVTMA_PFREQCHG, ~LVTMA_PFREQCHG);
+	else
+		WREG32_P(LVTMA_DATA_SYNCHRONIZATION, LVTMA_PFREQCHG, ~LVTMA_PFREQCHG);
+}
+
+static void rv6xx_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
+					   struct radeon_ps *new_ps,
+					   bool enable)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+
+	if (enable) {
+		rv6xx_enable_bif_dynamic_pcie_gen2(rdev, true);
+		rv6xx_enable_pcie_gen2_support(rdev);
+		r600_enable_dynamic_pcie_gen2(rdev, true);
+	} else {
+		if (!(new_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2))
+			rv6xx_force_pcie_gen1(rdev);
+		rv6xx_enable_bif_dynamic_pcie_gen2(rdev, false);
+		r600_enable_dynamic_pcie_gen2(rdev, false);
+	}
+}
+
+static void rv6xx_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
+						     struct radeon_ps *new_ps,
+						     struct radeon_ps *old_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_ps *current_state = rv6xx_get_ps(old_ps);
+
+	if ((new_ps->vclk == old_ps->vclk) &&
+	    (new_ps->dclk == old_ps->dclk))
+		return;
+
+	if (new_state->high.sclk >= current_state->high.sclk)
+		return;
+
+	radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
+}
+
+static void rv6xx_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
+						    struct radeon_ps *new_ps,
+						    struct radeon_ps *old_ps)
+{
+	struct rv6xx_ps *new_state = rv6xx_get_ps(new_ps);
+	struct rv6xx_ps *current_state = rv6xx_get_ps(old_ps);
+
+	if ((new_ps->vclk == old_ps->vclk) &&
+	    (new_ps->dclk == old_ps->dclk))
+		return;
+
+	if (new_state->high.sclk < current_state->high.sclk)
+		return;
+
+	radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
+}
+
+int rv6xx_dpm_enable(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+	int ret;
+
+	if (r600_dynamicpm_enabled(rdev))
+		return -EINVAL;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
+		rv6xx_enable_backbias(rdev, true);
+
+	if (pi->dynamic_ss)
+		rv6xx_enable_spread_spectrum(rdev, true);
+
+	rv6xx_program_mpll_timing_parameters(rdev);
+	rv6xx_program_bsp(rdev);
+	rv6xx_program_git(rdev);
+	rv6xx_program_tp(rdev);
+	rv6xx_program_tpp(rdev);
+	rv6xx_program_sstp(rdev);
+	rv6xx_program_fcp(rdev);
+	rv6xx_program_vddc3d_parameters(rdev);
+	rv6xx_program_voltage_timing_parameters(rdev);
+	rv6xx_program_engine_speed_parameters(rdev);
+
+	rv6xx_enable_display_gap(rdev, true);
+	if (pi->display_gap == false)
+		rv6xx_enable_display_gap(rdev, false);
+
+	rv6xx_program_power_level_enter_state(rdev);
+
+	rv6xx_calculate_stepping_parameters(rdev, boot_ps);
+
+	if (pi->voltage_control)
+		rv6xx_program_voltage_gpio_pins(rdev);
+
+	rv6xx_generate_stepping_table(rdev, boot_ps);
+
+	rv6xx_program_stepping_parameters_except_lowest_entry(rdev);
+	rv6xx_program_stepping_parameters_lowest_entry(rdev);
+
+	rv6xx_program_power_level_low(rdev);
+	rv6xx_program_power_level_medium(rdev);
+	rv6xx_program_power_level_high(rdev);
+	rv6xx_program_vc(rdev);
+	rv6xx_program_at(rdev);
+
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, true);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, true);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, true);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		ret = r600_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+		if (ret)
+			return ret;
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+	}
+
+	rv6xx_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+	r600_start_dpm(rdev);
+
+	if (pi->voltage_control)
+		rv6xx_enable_static_voltage_control(rdev, boot_ps, false);
+
+	if (pi->dynamic_pcie_gen2)
+		rv6xx_enable_dynamic_pcie_gen2(rdev, boot_ps, true);
+
+	if (pi->gfx_clock_gating)
+		r600_gfx_clockgating_enable(rdev, true);
+
+	return 0;
+}
+
+void rv6xx_dpm_disable(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+
+	if (!r600_dynamicpm_enabled(rdev))
+		return;
+
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, true);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, true);
+	rv6xx_enable_display_gap(rdev, false);
+	rv6xx_clear_vc(rdev);
+	r600_set_at(rdev, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
+
+	if (pi->thermal_protection)
+		r600_enable_thermal_protection(rdev, false);
+
+	r600_wait_for_power_level(rdev, R600_POWER_LEVEL_LOW);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, false);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, false);
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
+		rv6xx_enable_backbias(rdev, false);
+
+	rv6xx_enable_spread_spectrum(rdev, false);
+
+	if (pi->voltage_control)
+		rv6xx_enable_static_voltage_control(rdev, boot_ps, true);
+
+	if (pi->dynamic_pcie_gen2)
+		rv6xx_enable_dynamic_pcie_gen2(rdev, boot_ps, false);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		rdev->irq.dpm_thermal = false;
+		radeon_irq_set(rdev);
+	}
+
+	if (pi->gfx_clock_gating)
+		r600_gfx_clockgating_enable(rdev, false);
+
+	r600_stop_dpm(rdev);
+}
+
+int rv6xx_dpm_set_power_state(struct radeon_device *rdev)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+	struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
+	struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;
+	int ret;
+
+	pi->restricted_levels = 0;
+
+	rv6xx_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+
+	rv6xx_clear_vc(rdev);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, true);
+	r600_set_at(rdev, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
+
+	if (pi->thermal_protection)
+		r600_enable_thermal_protection(rdev, false);
+
+	r600_wait_for_power_level(rdev, R600_POWER_LEVEL_LOW);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, false);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, false);
+
+	rv6xx_generate_transition_stepping(rdev, new_ps, old_ps);
+	rv6xx_program_power_level_medium_for_transition(rdev);
+
+	if (pi->voltage_control) {
+		rv6xx_set_sw_voltage_to_safe(rdev, new_ps, old_ps);
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
+			rv6xx_set_sw_voltage_to_low(rdev, old_ps);
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
+		rv6xx_set_safe_backbias(rdev, new_ps, old_ps);
+
+	if (pi->dynamic_pcie_gen2)
+		rv6xx_set_safe_pcie_gen2(rdev, new_ps, old_ps);
+
+	if (pi->voltage_control)
+		rv6xx_enable_dynamic_voltage_control(rdev, false);
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
+		rv6xx_enable_dynamic_backbias_control(rdev, false);
+
+	if (pi->voltage_control) {
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
+			rv6xx_step_voltage_if_increasing(rdev, new_ps, old_ps);
+		msleep((rdev->pm.dpm.voltage_response_time + 999) / 1000);
+	}
+
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, true);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, false);
+	r600_wait_for_power_level_unequal(rdev, R600_POWER_LEVEL_LOW);
+
+	rv6xx_generate_low_step(rdev, new_ps);
+	rv6xx_invalidate_intermediate_steps(rdev);
+	rv6xx_calculate_stepping_parameters(rdev, new_ps);
+	rv6xx_program_stepping_parameters_lowest_entry(rdev);
+	rv6xx_program_power_level_low_to_lowest_state(rdev);
+
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, true);
+	r600_wait_for_power_level(rdev, R600_POWER_LEVEL_LOW);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, false);
+
+	if (pi->voltage_control) {
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC) {
+			ret = rv6xx_step_voltage_if_decreasing(rdev, new_ps, old_ps);
+			if (ret)
+				return ret;
+		}
+		rv6xx_enable_dynamic_voltage_control(rdev, true);
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
+		rv6xx_enable_dynamic_backbias_control(rdev, true);
+
+	if (pi->dynamic_pcie_gen2)
+		rv6xx_enable_dynamic_pcie_gen2(rdev, new_ps, true);
+
+	rv6xx_reset_lvtm_data_sync(rdev);
+
+	rv6xx_generate_stepping_table(rdev, new_ps);
+	rv6xx_program_stepping_parameters_except_lowest_entry(rdev);
+	rv6xx_program_power_level_low(rdev);
+	rv6xx_program_power_level_medium(rdev);
+	rv6xx_program_power_level_high(rdev);
+	rv6xx_enable_medium(rdev);
+	rv6xx_enable_high(rdev);
+
+	if (pi->thermal_protection)
+		rv6xx_enable_thermal_protection(rdev, true);
+	rv6xx_program_vc(rdev);
+	rv6xx_program_at(rdev);
+
+	rv6xx_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+
+	rdev->pm.dpm.forced_level = RADEON_DPM_FORCED_LEVEL_AUTO;
+
+	return 0;
+}
+
+void rv6xx_setup_asic(struct radeon_device *rdev)
+{
+	r600_enable_acpi_pm(rdev);
+
+	if (radeon_aspm != 0) {
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L0s)
+			rv6xx_enable_l0s(rdev);
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L1)
+			rv6xx_enable_l1(rdev);
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1)
+			rv6xx_enable_pll_sleep_in_l1(rdev);
+	}
+}
+
+void rv6xx_dpm_display_configuration_changed(struct radeon_device *rdev)
+{
+	rv6xx_program_display_gap(rdev);
+}
+
+union power_info {
+	struct _ATOM_POWERPLAY_INFO info;
+	struct _ATOM_POWERPLAY_INFO_V2 info_2;
+	struct _ATOM_POWERPLAY_INFO_V3 info_3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
+	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
+	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
+};
+
+union pplib_clock_info {
+	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
+	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
+	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
+	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
+};
+
+union pplib_power_state {
+	struct _ATOM_PPLIB_STATE v1;
+	struct _ATOM_PPLIB_STATE_V2 v2;
+};
+
+static void rv6xx_parse_pplib_non_clock_info(struct radeon_device *rdev,
+					     struct radeon_ps *rps,
+					     struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info)
+{
+	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
+	rps->class = le16_to_cpu(non_clock_info->usClassification);
+	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
+
+	if (r600_is_uvd_state(rps->class, rps->class2)) {
+		rps->vclk = RV6XX_DEFAULT_VCLK_FREQ;
+		rps->dclk = RV6XX_DEFAULT_DCLK_FREQ;
+	} else {
+		rps->vclk = 0;
+		rps->dclk = 0;
+	}
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
+		rdev->pm.dpm.boot_ps = rps;
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		rdev->pm.dpm.uvd_ps = rps;
+}
+
+static void rv6xx_parse_pplib_clock_info(struct radeon_device *rdev,
+					 struct radeon_ps *rps, int index,
+					 union pplib_clock_info *clock_info)
+{
+	struct rv6xx_ps *ps = rv6xx_get_ps(rps);
+	u32 sclk, mclk;
+	u16 vddc;
+	struct rv6xx_pl *pl;
+
+	switch (index) {
+	case 0:
+		pl = &ps->low;
+		break;
+	case 1:
+		pl = &ps->medium;
+		break;
+	case 2:
+	default:
+		pl = &ps->high;
+		break;
+	}
+
+	sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
+	sclk |= clock_info->r600.ucEngineClockHigh << 16;
+	mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);
+	mclk |= clock_info->r600.ucMemoryClockHigh << 16;
+
+	pl->mclk = mclk;
+	pl->sclk = sclk;
+	pl->vddc = le16_to_cpu(clock_info->r600.usVDDC);
+	pl->flags = le32_to_cpu(clock_info->r600.ulFlags);
+
+	/* patch up vddc if necessary */
+	if (pl->vddc == 0xff01) {
+		if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0)
+			pl->vddc = vddc;
+	}
+
+	/* fix up pcie gen2 */
+	if (pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) {
+		if ((rdev->family == CHIP_RV610) || (rdev->family == CHIP_RV630)) {
+			if (pl->vddc < 1100)
+				pl->flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
+		}
+	}
+
+	/* patch up boot state */
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
+		u16 vddc, vddci, mvdd;
+		radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
+		pl->mclk = rdev->clock.default_mclk;
+		pl->sclk = rdev->clock.default_sclk;
+		pl->vddc = vddc;
+	}
+}
+
+static int rv6xx_parse_power_table(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
+	union pplib_power_state *power_state;
+	int i, j;
+	union pplib_clock_info *clock_info;
+	union power_info *power_info;
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+        u16 data_offset;
+	u8 frev, crev;
+	struct rv6xx_ps *ps;
+
+	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset))
+		return -EINVAL;
+	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+
+	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
+				  power_info->pplib.ucNumStates, GFP_KERNEL);
+	if (!rdev->pm.dpm.ps)
+		return -ENOMEM;
+	rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
+	rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
+	rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
+
+	for (i = 0; i < power_info->pplib.ucNumStates; i++) {
+		power_state = (union pplib_power_state *)
+			(mode_info->atom_context->bios + data_offset +
+			 le16_to_cpu(power_info->pplib.usStateArrayOffset) +
+			 i * power_info->pplib.ucStateEntrySize);
+		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
+			(mode_info->atom_context->bios + data_offset +
+			 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
+			 (power_state->v1.ucNonClockStateIndex *
+			  power_info->pplib.ucNonClockSize));
+		if (power_info->pplib.ucStateEntrySize - 1) {
+			ps = kzalloc(sizeof(struct rv6xx_ps), GFP_KERNEL);
+			if (ps == NULL) {
+				kfree(rdev->pm.dpm.ps);
+				return -ENOMEM;
+			}
+			rdev->pm.dpm.ps[i].ps_priv = ps;
+			rv6xx_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
+							 non_clock_info);
+			for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
+				clock_info = (union pplib_clock_info *)
+					(mode_info->atom_context->bios + data_offset +
+					 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
+					 (power_state->v1.ucClockStateIndices[j] *
+					  power_info->pplib.ucClockInfoSize));
+				rv6xx_parse_pplib_clock_info(rdev,
+							     &rdev->pm.dpm.ps[i], j,
+							     clock_info);
+			}
+		}
+	}
+	rdev->pm.dpm.num_ps = power_info->pplib.ucNumStates;
+	return 0;
+}
+
+int rv6xx_dpm_init(struct radeon_device *rdev)
+{
+	struct radeon_atom_ss ss;
+	struct atom_clock_dividers dividers;
+	struct rv6xx_power_info *pi;
+	int ret;
+
+	pi = kzalloc(sizeof(struct rv6xx_power_info), GFP_KERNEL);
+	if (pi == NULL)
+		return -ENOMEM;
+	rdev->pm.dpm.priv = pi;
+
+	ret = rv6xx_parse_power_table(rdev);
+	if (ret)
+		return ret;
+
+	if (rdev->pm.dpm.voltage_response_time == 0)
+		rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
+	if (rdev->pm.dpm.backbias_response_time == 0)
+		rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     0, false, &dividers);
+	if (ret)
+		pi->spll_ref_div = dividers.ref_div + 1;
+	else
+		pi->spll_ref_div = R600_REFERENCEDIVIDER_DFLT;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
+					     0, false, &dividers);
+	if (ret)
+		pi->mpll_ref_div = dividers.ref_div + 1;
+	else
+		pi->mpll_ref_div = R600_REFERENCEDIVIDER_DFLT;
+
+	if (rdev->family >= CHIP_RV670)
+		pi->fb_div_scale = 1;
+	else
+		pi->fb_div_scale = 0;
+
+	pi->voltage_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
+
+	pi->gfx_clock_gating = true;
+
+	pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
+						       ASIC_INTERNAL_ENGINE_SS, 0);
+	pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
+						       ASIC_INTERNAL_MEMORY_SS, 0);
+
+	/* Disable sclk ss, causes hangs on a lot of systems */
+	pi->sclk_ss = false;
+
+	if (pi->sclk_ss || pi->mclk_ss)
+		pi->dynamic_ss = true;
+	else
+		pi->dynamic_ss = false;
+
+	pi->dynamic_pcie_gen2 = true;
+
+	if (pi->gfx_clock_gating &&
+	    (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
+		pi->thermal_protection = true;
+	else
+		pi->thermal_protection = false;
+
+	pi->display_gap = true;
+
+	return 0;
+}
+
+void rv6xx_dpm_print_power_state(struct radeon_device *rdev,
+				 struct radeon_ps *rps)
+{
+	struct rv6xx_ps *ps = rv6xx_get_ps(rps);
+	struct rv6xx_pl *pl;
+
+	r600_dpm_print_class_info(rps->class, rps->class2);
+	r600_dpm_print_cap_info(rps->caps);
+	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+	pl = &ps->low;
+	printk("\t\tpower level 0    sclk: %u mclk: %u vddc: %u\n",
+	       pl->sclk, pl->mclk, pl->vddc);
+	pl = &ps->medium;
+	printk("\t\tpower level 1    sclk: %u mclk: %u vddc: %u\n",
+	       pl->sclk, pl->mclk, pl->vddc);
+	pl = &ps->high;
+	printk("\t\tpower level 2    sclk: %u mclk: %u vddc: %u\n",
+	       pl->sclk, pl->mclk, pl->vddc);
+	r600_dpm_print_ps_status(rdev, rps);
+}
+
+void rv6xx_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						       struct seq_file *m)
+{
+	struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+	struct rv6xx_ps *ps = rv6xx_get_ps(rps);
+	struct rv6xx_pl *pl;
+	u32 current_index =
+		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
+		CURRENT_PROFILE_INDEX_SHIFT;
+
+	if (current_index > 2) {
+		seq_printf(m, "invalid dpm profile %d\n", current_index);
+	} else {
+		if (current_index == 0)
+			pl = &ps->low;
+		else if (current_index == 1)
+			pl = &ps->medium;
+		else /* current_index == 2 */
+			pl = &ps->high;
+		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+		seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u\n",
+			   current_index, pl->sclk, pl->mclk, pl->vddc);
+	}
+}
+
+void rv6xx_dpm_fini(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	}
+	kfree(rdev->pm.dpm.ps);
+	kfree(rdev->pm.dpm.priv);
+}
+
+u32 rv6xx_dpm_get_sclk(struct radeon_device *rdev, bool low)
+{
+	struct rv6xx_ps *requested_state = rv6xx_get_ps(rdev->pm.dpm.requested_ps);
+
+	if (low)
+		return requested_state->low.sclk;
+	else
+		return requested_state->high.sclk;
+}
+
+u32 rv6xx_dpm_get_mclk(struct radeon_device *rdev, bool low)
+{
+	struct rv6xx_ps *requested_state = rv6xx_get_ps(rdev->pm.dpm.requested_ps);
+
+	if (low)
+		return requested_state->low.mclk;
+	else
+		return requested_state->high.mclk;
+}
+
+int rv6xx_dpm_force_performance_level(struct radeon_device *rdev,
+				      enum radeon_dpm_forced_level level)
+{
+	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
+
+	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
+		pi->restricted_levels = 3;
+	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
+		pi->restricted_levels = 2;
+	} else {
+		pi->restricted_levels = 0;
+	}
+
+	rv6xx_clear_vc(rdev);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, true);
+	r600_set_at(rdev, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
+	r600_wait_for_power_level(rdev, R600_POWER_LEVEL_LOW);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, false);
+	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, false);
+	rv6xx_enable_medium(rdev);
+	rv6xx_enable_high(rdev);
+	if (pi->restricted_levels == 3)
+		r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, false);
+	rv6xx_program_vc(rdev);
+	rv6xx_program_at(rdev);
+
+	rdev->pm.dpm.forced_level = level;
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv6xx_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv6xx_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv6xx_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv6xx_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#ifndef __RV6XX_DPM_H__
+#define __RV6XX_DPM_H__
+
+#include "r600_dpm.h"
+
+/* Represents a single SCLK step. */
+struct rv6xx_sclk_stepping
+{
+    u32 vco_frequency;
+    u32 post_divider;
+};
+
+struct rv6xx_pm_hw_state {
+	u32 sclks[R600_PM_NUMBER_OF_ACTIVITY_LEVELS];
+	u32 mclks[R600_PM_NUMBER_OF_MCLKS];
+	u16 vddc[R600_PM_NUMBER_OF_VOLTAGE_LEVELS];
+	bool backbias[R600_PM_NUMBER_OF_VOLTAGE_LEVELS];
+	bool pcie_gen2[R600_PM_NUMBER_OF_ACTIVITY_LEVELS];
+	u8 high_sclk_index;
+	u8 medium_sclk_index;
+	u8 low_sclk_index;
+	u8 high_mclk_index;
+	u8 medium_mclk_index;
+	u8 low_mclk_index;
+	u8 high_vddc_index;
+	u8 medium_vddc_index;
+	u8 low_vddc_index;
+	u8 rp[R600_PM_NUMBER_OF_ACTIVITY_LEVELS];
+	u8 lp[R600_PM_NUMBER_OF_ACTIVITY_LEVELS];
+};
+
+struct rv6xx_power_info {
+	/* flags */
+	bool voltage_control;
+	bool sclk_ss;
+	bool mclk_ss;
+	bool dynamic_ss;
+	bool dynamic_pcie_gen2;
+	bool thermal_protection;
+	bool display_gap;
+	bool gfx_clock_gating;
+	/* clk values */
+	u32 fb_div_scale;
+	u32 spll_ref_div;
+	u32 mpll_ref_div;
+	u32 bsu;
+	u32 bsp;
+	/* */
+	u32 active_auto_throttle_sources;
+	/* current power state */
+	u32 restricted_levels;
+	struct rv6xx_pm_hw_state hw;
+};
+
+struct rv6xx_pl {
+	u32 sclk;
+	u32 mclk;
+	u16 vddc;
+	u32 flags;
+};
+
+struct rv6xx_ps {
+	struct rv6xx_pl high;
+	struct rv6xx_pl medium;
+	struct rv6xx_pl low;
+};
+
+#define RV6XX_DEFAULT_VCLK_FREQ  40000 /* 10 khz */
+#define RV6XX_DEFAULT_DCLK_FREQ  30000 /* 10 khz */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv730d.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv730d.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv730d.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv730d.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 RV730_H
+#define RV730_H
+
+#define	CG_SPLL_FUNC_CNTL				0x600
+#define		SPLL_RESET				(1 << 0)
+#define		SPLL_SLEEP				(1 << 1)
+#define		SPLL_DIVEN				(1 << 2)
+#define		SPLL_BYPASS_EN				(1 << 3)
+#define		SPLL_REF_DIV(x)				((x) << 4)
+#define		SPLL_REF_DIV_MASK			(0x3f << 4)
+#define		SPLL_HILEN(x)				((x) << 12)
+#define		SPLL_HILEN_MASK				(0xf << 12)
+#define		SPLL_LOLEN(x)				((x) << 16)
+#define		SPLL_LOLEN_MASK				(0xf << 16)
+#define	CG_SPLL_FUNC_CNTL_2				0x604
+#define		SCLK_MUX_SEL(x)				((x) << 0)
+#define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define	CG_SPLL_FUNC_CNTL_3				0x608
+#define		SPLL_FB_DIV(x)				((x) << 0)
+#define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
+#define		SPLL_DITHEN				(1 << 28)
+
+#define	CG_MPLL_FUNC_CNTL				0x624
+#define		MPLL_RESET				(1 << 0)
+#define		MPLL_SLEEP				(1 << 1)
+#define		MPLL_DIVEN				(1 << 2)
+#define		MPLL_BYPASS_EN				(1 << 3)
+#define		MPLL_REF_DIV(x)				((x) << 4)
+#define		MPLL_REF_DIV_MASK			(0x3f << 4)
+#define		MPLL_HILEN(x)				((x) << 12)
+#define		MPLL_HILEN_MASK				(0xf << 12)
+#define		MPLL_LOLEN(x)				((x) << 16)
+#define		MPLL_LOLEN_MASK				(0xf << 16)
+#define	CG_MPLL_FUNC_CNTL_2				0x628
+#define		MCLK_MUX_SEL(x)				((x) << 0)
+#define		MCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define	CG_MPLL_FUNC_CNTL_3				0x62c
+#define		MPLL_FB_DIV(x)				((x) << 0)
+#define		MPLL_FB_DIV_MASK			(0x3ffffff << 0)
+#define		MPLL_DITHEN				(1 << 28)
+
+#define	CG_TCI_MPLL_SPREAD_SPECTRUM			0x634
+#define	CG_TCI_MPLL_SPREAD_SPECTRUM_2			0x638
+#define GENERAL_PWRMGT                                  0x63c
+#       define GLOBAL_PWRMGT_EN                         (1 << 0)
+#       define STATIC_PM_EN                             (1 << 1)
+#       define THERMAL_PROTECTION_DIS                   (1 << 2)
+#       define THERMAL_PROTECTION_TYPE                  (1 << 3)
+#       define ENABLE_GEN2PCIE                          (1 << 4)
+#       define ENABLE_GEN2XSP                           (1 << 5)
+#       define SW_SMIO_INDEX(x)                         ((x) << 6)
+#       define SW_SMIO_INDEX_MASK                       (3 << 6)
+#       define LOW_VOLT_D2_ACPI                         (1 << 8)
+#       define LOW_VOLT_D3_ACPI                         (1 << 9)
+#       define VOLT_PWRMGT_EN                           (1 << 10)
+#       define BACKBIAS_PAD_EN                          (1 << 18)
+#       define BACKBIAS_VALUE                           (1 << 19)
+#       define DYN_SPREAD_SPECTRUM_EN                   (1 << 23)
+#       define AC_DC_SW                                 (1 << 24)
+
+#define SCLK_PWRMGT_CNTL                                  0x644
+#       define SCLK_PWRMGT_OFF                            (1 << 0)
+#       define SCLK_LOW_D1                                (1 << 1)
+#       define FIR_RESET                                  (1 << 4)
+#       define FIR_FORCE_TREND_SEL                        (1 << 5)
+#       define FIR_TREND_MODE                             (1 << 6)
+#       define DYN_GFX_CLK_OFF_EN                         (1 << 7)
+#       define GFX_CLK_FORCE_ON                           (1 << 8)
+#       define GFX_CLK_REQUEST_OFF                        (1 << 9)
+#       define GFX_CLK_FORCE_OFF                          (1 << 10)
+#       define GFX_CLK_OFF_ACPI_D1                        (1 << 11)
+#       define GFX_CLK_OFF_ACPI_D2                        (1 << 12)
+#       define GFX_CLK_OFF_ACPI_D3                        (1 << 13)
+
+#define	TCI_MCLK_PWRMGT_CNTL				0x648
+#       define MPLL_PWRMGT_OFF                          (1 << 5)
+#       define DLL_READY                                (1 << 6)
+#       define MC_INT_CNTL                              (1 << 7)
+#       define MRDCKA_SLEEP                             (1 << 8)
+#       define MRDCKB_SLEEP                             (1 << 9)
+#       define MRDCKC_SLEEP                             (1 << 10)
+#       define MRDCKD_SLEEP                             (1 << 11)
+#       define MRDCKE_SLEEP                             (1 << 12)
+#       define MRDCKF_SLEEP                             (1 << 13)
+#       define MRDCKG_SLEEP                             (1 << 14)
+#       define MRDCKH_SLEEP                             (1 << 15)
+#       define MRDCKA_RESET                             (1 << 16)
+#       define MRDCKB_RESET                             (1 << 17)
+#       define MRDCKC_RESET                             (1 << 18)
+#       define MRDCKD_RESET                             (1 << 19)
+#       define MRDCKE_RESET                             (1 << 20)
+#       define MRDCKF_RESET                             (1 << 21)
+#       define MRDCKG_RESET                             (1 << 22)
+#       define MRDCKH_RESET                             (1 << 23)
+#       define DLL_READY_READ                           (1 << 24)
+#       define USE_DISPLAY_GAP                          (1 << 25)
+#       define USE_DISPLAY_URGENT_NORMAL                (1 << 26)
+#       define MPLL_TURNOFF_D2                          (1 << 28)
+#define	TCI_DLL_CNTL					0x64c
+
+#define	CG_PG_CNTL					0x858
+#       define PWRGATE_ENABLE                           (1 << 0)
+
+#define	CG_AT				                0x6d4
+#define		CG_R(x)					((x) << 0)
+#define		CG_R_MASK				(0xffff << 0)
+#define		CG_L(x)					((x) << 16)
+#define		CG_L_MASK				(0xffff << 16)
+
+#define	CG_SPLL_SPREAD_SPECTRUM				0x790
+#define		SSEN					(1 << 0)
+#define		CLK_S(x)				((x) << 4)
+#define		CLK_S_MASK				(0xfff << 4)
+#define	CG_SPLL_SPREAD_SPECTRUM_2			0x794
+#define		CLK_V(x)				((x) << 0)
+#define		CLK_V_MASK				(0x3ffffff << 0)
+
+#define	MC_ARB_DRAM_TIMING				0x2774
+#define	MC_ARB_DRAM_TIMING2				0x2778
+
+#define	MC_ARB_RFSH_RATE				0x27b0
+#define		POWERMODE0(x)				((x) << 0)
+#define		POWERMODE0_MASK				(0xff << 0)
+#define		POWERMODE1(x)				((x) << 8)
+#define		POWERMODE1_MASK				(0xff << 8)
+#define		POWERMODE2(x)				((x) << 16)
+#define		POWERMODE2_MASK				(0xff << 16)
+#define		POWERMODE3(x)				((x) << 24)
+#define		POWERMODE3_MASK				(0xff << 24)
+
+#define	MC_ARB_DRAM_TIMING_1				0x27f0
+#define	MC_ARB_DRAM_TIMING_2				0x27f4
+#define	MC_ARB_DRAM_TIMING_3				0x27f8
+#define	MC_ARB_DRAM_TIMING2_1				0x27fc
+#define	MC_ARB_DRAM_TIMING2_2				0x2800
+#define	MC_ARB_DRAM_TIMING2_3				0x2804
+
+#define	MC4_IO_DQ_PAD_CNTL_D0_I0			0x2978
+#define	MC4_IO_DQ_PAD_CNTL_D0_I1			0x297c
+#define	MC4_IO_QS_PAD_CNTL_D0_I0			0x2980
+#define	MC4_IO_QS_PAD_CNTL_D0_I1			0x2984
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv730_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv730_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv730_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv730_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,508 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "rv730d.h"
+#include "r600_dpm.h"
+#include "rv770_dpm.h"
+#include "atom.h"
+
+#define MC_CG_ARB_FREQ_F0           0x0a
+#define MC_CG_ARB_FREQ_F1           0x0b
+#define MC_CG_ARB_FREQ_F2           0x0c
+#define MC_CG_ARB_FREQ_F3           0x0d
+
+struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
+
+int rv730_populate_sclk_value(struct radeon_device *rdev,
+			      u32 engine_clock,
+			      RV770_SMC_SCLK_VALUE *sclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct atom_clock_dividers dividers;
+	u32 spll_func_cntl = pi->clk_regs.rv730.cg_spll_func_cntl;
+	u32 spll_func_cntl_2 = pi->clk_regs.rv730.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3 = pi->clk_regs.rv730.cg_spll_func_cntl_3;
+	u32 cg_spll_spread_spectrum = pi->clk_regs.rv730.cg_spll_spread_spectrum;
+	u32 cg_spll_spread_spectrum_2 = pi->clk_regs.rv730.cg_spll_spread_spectrum_2;
+	u64 tmp;
+	u32 reference_clock = rdev->clock.spll.reference_freq;
+	u32 reference_divider, post_divider;
+	u32 fbdiv;
+	int ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     engine_clock, false, &dividers);
+	if (ret)
+		return ret;
+
+	reference_divider = 1 + dividers.ref_div;
+
+	if (dividers.enable_post_div)
+		post_divider = ((dividers.post_div >> 4) & 0xf) +
+			(dividers.post_div & 0xf) + 2;
+	else
+		post_divider = 1;
+
+	tmp = (u64) engine_clock * reference_divider * post_divider * 16384;
+	do_div(tmp, reference_clock);
+	fbdiv = (u32) tmp;
+
+	/* set up registers */
+	if (dividers.enable_post_div)
+		spll_func_cntl |= SPLL_DIVEN;
+	else
+		spll_func_cntl &= ~SPLL_DIVEN;
+	spll_func_cntl &= ~(SPLL_HILEN_MASK | SPLL_LOLEN_MASK | SPLL_REF_DIV_MASK);
+	spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
+	spll_func_cntl |= SPLL_HILEN((dividers.post_div >> 4) & 0xf);
+	spll_func_cntl |= SPLL_LOLEN(dividers.post_div & 0xf);
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(2);
+
+	spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
+	spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
+	spll_func_cntl_3 |= SPLL_DITHEN;
+
+	if (pi->sclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 vco_freq = engine_clock * post_divider;
+
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+						     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
+			u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
+			u32 clk_v = ss.percentage * fbdiv / (clk_s * 10000);
+
+			cg_spll_spread_spectrum &= ~CLK_S_MASK;
+			cg_spll_spread_spectrum |= CLK_S(clk_s);
+			cg_spll_spread_spectrum |= SSEN;
+
+			cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
+			cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
+		}
+	}
+
+	sclk->sclk_value = cpu_to_be32(engine_clock);
+	sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
+	sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
+	sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
+	sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum);
+	sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2);
+
+	return 0;
+}
+
+int rv730_populate_mclk_value(struct radeon_device *rdev,
+			      u32 engine_clock, u32 memory_clock,
+			      LPRV7XX_SMC_MCLK_VALUE mclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 mclk_pwrmgt_cntl = pi->clk_regs.rv730.mclk_pwrmgt_cntl;
+	u32 dll_cntl = pi->clk_regs.rv730.dll_cntl;
+	u32 mpll_func_cntl = pi->clk_regs.rv730.mpll_func_cntl;
+	u32 mpll_func_cntl_2 = pi->clk_regs.rv730.mpll_func_cntl2;
+	u32 mpll_func_cntl_3 = pi->clk_regs.rv730.mpll_func_cntl3;
+	u32 mpll_ss = pi->clk_regs.rv730.mpll_ss;
+	u32 mpll_ss2 = pi->clk_regs.rv730.mpll_ss2;
+	struct atom_clock_dividers dividers;
+	u32 post_divider, reference_divider;
+	int ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
+					     memory_clock, false, &dividers);
+	if (ret)
+		return ret;
+
+	reference_divider = dividers.ref_div + 1;
+
+	if (dividers.enable_post_div)
+		post_divider = ((dividers.post_div >> 4) & 0xf) +
+			(dividers.post_div & 0xf) + 2;
+	else
+		post_divider = 1;
+
+	/* setup the registers */
+	if (dividers.enable_post_div)
+		mpll_func_cntl |= MPLL_DIVEN;
+	else
+		mpll_func_cntl &= ~MPLL_DIVEN;
+
+	mpll_func_cntl &= ~(MPLL_REF_DIV_MASK | MPLL_HILEN_MASK | MPLL_LOLEN_MASK);
+	mpll_func_cntl |= MPLL_REF_DIV(dividers.ref_div);
+	mpll_func_cntl |= MPLL_HILEN((dividers.post_div >> 4) & 0xf);
+	mpll_func_cntl |= MPLL_LOLEN(dividers.post_div & 0xf);
+
+	mpll_func_cntl_3 &= ~MPLL_FB_DIV_MASK;
+	mpll_func_cntl_3 |= MPLL_FB_DIV(dividers.fb_div);
+	if (dividers.enable_dithen)
+		mpll_func_cntl_3 |= MPLL_DITHEN;
+	else
+		mpll_func_cntl_3 &= ~MPLL_DITHEN;
+
+	if (pi->mclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 vco_freq = memory_clock * post_divider;
+
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+						     ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
+			u32 reference_clock = rdev->clock.mpll.reference_freq;
+			u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
+			u32 clk_v = ss.percentage * dividers.fb_div / (clk_s * 10000);
+
+			mpll_ss &= ~CLK_S_MASK;
+			mpll_ss |= CLK_S(clk_s);
+			mpll_ss |= SSEN;
+
+			mpll_ss2 &= ~CLK_V_MASK;
+			mpll_ss |= CLK_V(clk_v);
+		}
+	}
+
+
+	mclk->mclk730.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	mclk->mclk730.vDLL_CNTL = cpu_to_be32(dll_cntl);
+	mclk->mclk730.mclk_value = cpu_to_be32(memory_clock);
+	mclk->mclk730.vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl);
+	mclk->mclk730.vMPLL_FUNC_CNTL2 = cpu_to_be32(mpll_func_cntl_2);
+	mclk->mclk730.vMPLL_FUNC_CNTL3 = cpu_to_be32(mpll_func_cntl_3);
+	mclk->mclk730.vMPLL_SS = cpu_to_be32(mpll_ss);
+	mclk->mclk730.vMPLL_SS2 = cpu_to_be32(mpll_ss2);
+
+	return 0;
+}
+
+void rv730_read_clock_registers(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	pi->clk_regs.rv730.cg_spll_func_cntl =
+		RREG32(CG_SPLL_FUNC_CNTL);
+	pi->clk_regs.rv730.cg_spll_func_cntl_2 =
+		RREG32(CG_SPLL_FUNC_CNTL_2);
+	pi->clk_regs.rv730.cg_spll_func_cntl_3 =
+		RREG32(CG_SPLL_FUNC_CNTL_3);
+	pi->clk_regs.rv730.cg_spll_spread_spectrum =
+		RREG32(CG_SPLL_SPREAD_SPECTRUM);
+	pi->clk_regs.rv730.cg_spll_spread_spectrum_2 =
+		RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
+
+	pi->clk_regs.rv730.mclk_pwrmgt_cntl =
+		RREG32(TCI_MCLK_PWRMGT_CNTL);
+	pi->clk_regs.rv730.dll_cntl =
+		RREG32(TCI_DLL_CNTL);
+	pi->clk_regs.rv730.mpll_func_cntl =
+		RREG32(CG_MPLL_FUNC_CNTL);
+	pi->clk_regs.rv730.mpll_func_cntl2 =
+		RREG32(CG_MPLL_FUNC_CNTL_2);
+	pi->clk_regs.rv730.mpll_func_cntl3 =
+		RREG32(CG_MPLL_FUNC_CNTL_3);
+	pi->clk_regs.rv730.mpll_ss =
+		RREG32(CG_TCI_MPLL_SPREAD_SPECTRUM);
+	pi->clk_regs.rv730.mpll_ss2 =
+		RREG32(CG_TCI_MPLL_SPREAD_SPECTRUM_2);
+}
+
+int rv730_populate_smc_acpi_state(struct radeon_device *rdev,
+				  RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 mpll_func_cntl = 0;
+	u32 mpll_func_cntl_2 = 0 ;
+	u32 mpll_func_cntl_3 = 0;
+	u32 mclk_pwrmgt_cntl;
+	u32 dll_cntl;
+	u32 spll_func_cntl;
+	u32 spll_func_cntl_2;
+	u32 spll_func_cntl_3;
+
+	table->ACPIState = table->initialState;
+	table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
+
+	if (pi->acpi_vddc) {
+		rv770_populate_vddc_value(rdev, pi->acpi_vddc,
+					  &table->ACPIState.levels[0].vddc);
+		table->ACPIState.levels[0].gen2PCIE = pi->pcie_gen2 ?
+			pi->acpi_pcie_gen2 : 0;
+		table->ACPIState.levels[0].gen2XSP =
+			pi->acpi_pcie_gen2;
+	} else {
+		rv770_populate_vddc_value(rdev, pi->min_vddc_in_table,
+					  &table->ACPIState.levels[0].vddc);
+		table->ACPIState.levels[0].gen2PCIE = 0;
+	}
+
+	mpll_func_cntl = pi->clk_regs.rv730.mpll_func_cntl;
+	mpll_func_cntl_2 = pi->clk_regs.rv730.mpll_func_cntl2;
+	mpll_func_cntl_3 = pi->clk_regs.rv730.mpll_func_cntl3;
+
+	mpll_func_cntl |= MPLL_RESET | MPLL_BYPASS_EN;
+	mpll_func_cntl &= ~MPLL_SLEEP;
+
+	mpll_func_cntl_2 &= ~MCLK_MUX_SEL_MASK;
+	mpll_func_cntl_2 |= MCLK_MUX_SEL(1);
+
+	mclk_pwrmgt_cntl = (MRDCKA_RESET |
+			    MRDCKB_RESET |
+			    MRDCKC_RESET |
+			    MRDCKD_RESET |
+			    MRDCKE_RESET |
+			    MRDCKF_RESET |
+			    MRDCKG_RESET |
+			    MRDCKH_RESET |
+			    MRDCKA_SLEEP |
+			    MRDCKB_SLEEP |
+			    MRDCKC_SLEEP |
+			    MRDCKD_SLEEP |
+			    MRDCKE_SLEEP |
+			    MRDCKF_SLEEP |
+			    MRDCKG_SLEEP |
+			    MRDCKH_SLEEP);
+
+	dll_cntl = 0xff000000;
+
+	spll_func_cntl = pi->clk_regs.rv730.cg_spll_func_cntl;
+	spll_func_cntl_2 = pi->clk_regs.rv730.cg_spll_func_cntl_2;
+	spll_func_cntl_3 = pi->clk_regs.rv730.cg_spll_func_cntl_3;
+
+	spll_func_cntl |= SPLL_RESET | SPLL_BYPASS_EN;
+	spll_func_cntl &= ~SPLL_SLEEP;
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(4);
+
+	table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl);
+	table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL2 = cpu_to_be32(mpll_func_cntl_2);
+	table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL3 = cpu_to_be32(mpll_func_cntl_3);
+	table->ACPIState.levels[0].mclk.mclk730.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	table->ACPIState.levels[0].mclk.mclk730.vDLL_CNTL = cpu_to_be32(dll_cntl);
+
+	table->ACPIState.levels[0].mclk.mclk730.mclk_value = 0;
+
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
+
+	table->ACPIState.levels[0].sclk.sclk_value = 0;
+
+	rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
+
+	table->ACPIState.levels[1] = table->ACPIState.levels[0];
+	table->ACPIState.levels[2] = table->ACPIState.levels[0];
+
+	return 0;
+}
+
+int rv730_populate_smc_initial_state(struct radeon_device *rdev,
+				     struct radeon_ps *radeon_state,
+				     RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_ps *initial_state = rv770_get_ps(radeon_state);
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 a_t;
+
+	table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL =
+		cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl);
+	table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL2 =
+		cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl2);
+	table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL3 =
+		cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl3);
+	table->initialState.levels[0].mclk.mclk730.vMCLK_PWRMGT_CNTL =
+		cpu_to_be32(pi->clk_regs.rv730.mclk_pwrmgt_cntl);
+	table->initialState.levels[0].mclk.mclk730.vDLL_CNTL =
+		cpu_to_be32(pi->clk_regs.rv730.dll_cntl);
+	table->initialState.levels[0].mclk.mclk730.vMPLL_SS =
+		cpu_to_be32(pi->clk_regs.rv730.mpll_ss);
+	table->initialState.levels[0].mclk.mclk730.vMPLL_SS2 =
+		cpu_to_be32(pi->clk_regs.rv730.mpll_ss2);
+
+	table->initialState.levels[0].mclk.mclk730.mclk_value =
+		cpu_to_be32(initial_state->low.mclk);
+
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
+		cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
+		cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl_2);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
+		cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl_3);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
+		cpu_to_be32(pi->clk_regs.rv730.cg_spll_spread_spectrum);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =
+		cpu_to_be32(pi->clk_regs.rv730.cg_spll_spread_spectrum_2);
+
+	table->initialState.levels[0].sclk.sclk_value =
+		cpu_to_be32(initial_state->low.sclk);
+
+	table->initialState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
+
+	table->initialState.levels[0].seqValue =
+		rv770_get_seq_value(rdev, &initial_state->low);
+
+	rv770_populate_vddc_value(rdev,
+				  initial_state->low.vddc,
+				  &table->initialState.levels[0].vddc);
+	rv770_populate_initial_mvdd_value(rdev,
+					  &table->initialState.levels[0].mvdd);
+
+	a_t = CG_R(0xffff) | CG_L(0);
+
+	table->initialState.levels[0].aT = cpu_to_be32(a_t);
+
+	table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
+
+	if (pi->boot_in_gen2)
+		table->initialState.levels[0].gen2PCIE = 1;
+	else
+		table->initialState.levels[0].gen2PCIE = 0;
+	if (initial_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
+		table->initialState.levels[0].gen2XSP = 1;
+	else
+		table->initialState.levels[0].gen2XSP = 0;
+
+	table->initialState.levels[1] = table->initialState.levels[0];
+	table->initialState.levels[2] = table->initialState.levels[0];
+
+	table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
+
+	return 0;
+}
+
+void rv730_program_memory_timing_parameters(struct radeon_device *rdev,
+					    struct radeon_ps *radeon_state)
+{
+	struct rv7xx_ps *state = rv770_get_ps(radeon_state);
+	u32 arb_refresh_rate = 0;
+	u32 dram_timing = 0;
+	u32 dram_timing2 = 0;
+	u32 old_dram_timing = 0;
+	u32 old_dram_timing2 = 0;
+
+	arb_refresh_rate = RREG32(MC_ARB_RFSH_RATE) &
+		~(POWERMODE1_MASK | POWERMODE2_MASK | POWERMODE3_MASK);
+	arb_refresh_rate |=
+		(POWERMODE1(rv770_calculate_memory_refresh_rate(rdev, state->low.sclk)) |
+		 POWERMODE2(rv770_calculate_memory_refresh_rate(rdev, state->medium.sclk)) |
+		 POWERMODE3(rv770_calculate_memory_refresh_rate(rdev, state->high.sclk)));
+	WREG32(MC_ARB_RFSH_RATE, arb_refresh_rate);
+
+	/* save the boot dram timings */
+	old_dram_timing = RREG32(MC_ARB_DRAM_TIMING);
+	old_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
+
+	radeon_atom_set_engine_dram_timings(rdev,
+					    state->high.sclk,
+					    state->high.mclk);
+
+	dram_timing = RREG32(MC_ARB_DRAM_TIMING);
+	dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
+
+	WREG32(MC_ARB_DRAM_TIMING_3, dram_timing);
+	WREG32(MC_ARB_DRAM_TIMING2_3, dram_timing2);
+
+	radeon_atom_set_engine_dram_timings(rdev,
+					    state->medium.sclk,
+					    state->medium.mclk);
+
+	dram_timing = RREG32(MC_ARB_DRAM_TIMING);
+	dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
+
+	WREG32(MC_ARB_DRAM_TIMING_2, dram_timing);
+	WREG32(MC_ARB_DRAM_TIMING2_2, dram_timing2);
+
+	radeon_atom_set_engine_dram_timings(rdev,
+					    state->low.sclk,
+					    state->low.mclk);
+
+	dram_timing = RREG32(MC_ARB_DRAM_TIMING);
+	dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
+
+	WREG32(MC_ARB_DRAM_TIMING_1, dram_timing);
+	WREG32(MC_ARB_DRAM_TIMING2_1, dram_timing2);
+
+	/* restore the boot dram timings */
+	WREG32(MC_ARB_DRAM_TIMING, old_dram_timing);
+	WREG32(MC_ARB_DRAM_TIMING2, old_dram_timing2);
+
+}
+
+void rv730_start_dpm(struct radeon_device *rdev)
+{
+	WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
+
+	WREG32_P(TCI_MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF);
+
+	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
+}
+
+void rv730_stop_dpm(struct radeon_device *rdev)
+{
+	PPSMC_Result result;
+
+	result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled);
+
+	if (result != PPSMC_Result_OK)
+		DRM_ERROR("Could not force DPM to low\n");
+
+	WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
+
+	WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
+
+	WREG32_P(TCI_MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF);
+}
+
+void rv730_program_dcodt(struct radeon_device *rdev, bool use_dcodt)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 i = use_dcodt ? 0 : 1;
+	u32 mc4_io_pad_cntl;
+
+	mc4_io_pad_cntl = RREG32(MC4_IO_DQ_PAD_CNTL_D0_I0);
+	mc4_io_pad_cntl &= 0xFFFFFF00;
+	mc4_io_pad_cntl |= pi->odt_value_0[i];
+	WREG32(MC4_IO_DQ_PAD_CNTL_D0_I0, mc4_io_pad_cntl);
+	WREG32(MC4_IO_DQ_PAD_CNTL_D0_I1, mc4_io_pad_cntl);
+
+	mc4_io_pad_cntl = RREG32(MC4_IO_QS_PAD_CNTL_D0_I0);
+	mc4_io_pad_cntl &= 0xFFFFFF00;
+	mc4_io_pad_cntl |= pi->odt_value_1[i];
+	WREG32(MC4_IO_QS_PAD_CNTL_D0_I0, mc4_io_pad_cntl);
+	WREG32(MC4_IO_QS_PAD_CNTL_D0_I1, mc4_io_pad_cntl);
+}
+
+void rv730_get_odt_values(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 mc4_io_pad_cntl;
+
+	pi->odt_value_0[0] = (u8)0;
+	pi->odt_value_1[0] = (u8)0x80;
+
+	mc4_io_pad_cntl = RREG32(MC4_IO_DQ_PAD_CNTL_D0_I0);
+	pi->odt_value_0[1] = (u8)(mc4_io_pad_cntl & 0xff);
+
+	mc4_io_pad_cntl = RREG32(MC4_IO_QS_PAD_CNTL_D0_I0);
+	pi->odt_value_1[1] = (u8)(mc4_io_pad_cntl & 0xff);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv740d.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv740d.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv740d.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv740d.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 RV740_H
+#define RV740_H
+
+#define	CG_SPLL_FUNC_CNTL				0x600
+#define		SPLL_RESET				(1 << 0)
+#define		SPLL_SLEEP				(1 << 1)
+#define		SPLL_BYPASS_EN				(1 << 3)
+#define		SPLL_REF_DIV(x)				((x) << 4)
+#define		SPLL_REF_DIV_MASK			(0x3f << 4)
+#define		SPLL_PDIV_A(x)				((x) << 20)
+#define		SPLL_PDIV_A_MASK			(0x7f << 20)
+#define	CG_SPLL_FUNC_CNTL_2				0x604
+#define		SCLK_MUX_SEL(x)				((x) << 0)
+#define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define	CG_SPLL_FUNC_CNTL_3				0x608
+#define		SPLL_FB_DIV(x)				((x) << 0)
+#define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
+#define		SPLL_DITHEN				(1 << 28)
+
+#define	MPLL_CNTL_MODE					0x61c
+#define		SS_SSEN					(1 << 24)
+
+#define	MPLL_AD_FUNC_CNTL				0x624
+#define		CLKF(x)					((x) << 0)
+#define		CLKF_MASK				(0x7f << 0)
+#define		CLKR(x)					((x) << 7)
+#define		CLKR_MASK				(0x1f << 7)
+#define		CLKFRAC(x)				((x) << 12)
+#define		CLKFRAC_MASK				(0x1f << 12)
+#define		YCLK_POST_DIV(x)			((x) << 17)
+#define		YCLK_POST_DIV_MASK			(3 << 17)
+#define		IBIAS(x)				((x) << 20)
+#define		IBIAS_MASK				(0x3ff << 20)
+#define		RESET					(1 << 30)
+#define		PDNB					(1 << 31)
+#define	MPLL_AD_FUNC_CNTL_2				0x628
+#define		BYPASS					(1 << 19)
+#define		BIAS_GEN_PDNB				(1 << 24)
+#define		RESET_EN				(1 << 25)
+#define		VCO_MODE				(1 << 29)
+#define	MPLL_DQ_FUNC_CNTL				0x62c
+#define	MPLL_DQ_FUNC_CNTL_2				0x630
+
+#define	MCLK_PWRMGT_CNTL				0x648
+#define		DLL_SPEED(x)				((x) << 0)
+#define		DLL_SPEED_MASK				(0x1f << 0)
+#       define MPLL_PWRMGT_OFF                          (1 << 5)
+#       define DLL_READY                                (1 << 6)
+#       define MC_INT_CNTL                              (1 << 7)
+#       define MRDCKA0_SLEEP                            (1 << 8)
+#       define MRDCKA1_SLEEP                            (1 << 9)
+#       define MRDCKB0_SLEEP                            (1 << 10)
+#       define MRDCKB1_SLEEP                            (1 << 11)
+#       define MRDCKC0_SLEEP                            (1 << 12)
+#       define MRDCKC1_SLEEP                            (1 << 13)
+#       define MRDCKD0_SLEEP                            (1 << 14)
+#       define MRDCKD1_SLEEP                            (1 << 15)
+#       define MRDCKA0_RESET                            (1 << 16)
+#       define MRDCKA1_RESET                            (1 << 17)
+#       define MRDCKB0_RESET                            (1 << 18)
+#       define MRDCKB1_RESET                            (1 << 19)
+#       define MRDCKC0_RESET                            (1 << 20)
+#       define MRDCKC1_RESET                            (1 << 21)
+#       define MRDCKD0_RESET                            (1 << 22)
+#       define MRDCKD1_RESET                            (1 << 23)
+#       define DLL_READY_READ                           (1 << 24)
+#       define USE_DISPLAY_GAP                          (1 << 25)
+#       define USE_DISPLAY_URGENT_NORMAL                (1 << 26)
+#       define MPLL_TURNOFF_D2                          (1 << 28)
+#define	DLL_CNTL					0x64c
+#       define MRDCKA0_BYPASS                           (1 << 24)
+#       define MRDCKA1_BYPASS                           (1 << 25)
+#       define MRDCKB0_BYPASS                           (1 << 26)
+#       define MRDCKB1_BYPASS                           (1 << 27)
+#       define MRDCKC0_BYPASS                           (1 << 28)
+#       define MRDCKC1_BYPASS                           (1 << 29)
+#       define MRDCKD0_BYPASS                           (1 << 30)
+#       define MRDCKD1_BYPASS                           (1 << 31)
+
+#define	CG_SPLL_SPREAD_SPECTRUM				0x790
+#define		SSEN					(1 << 0)
+#define		CLK_S(x)				((x) << 4)
+#define		CLK_S_MASK				(0xfff << 4)
+#define	CG_SPLL_SPREAD_SPECTRUM_2			0x794
+#define		CLK_V(x)				((x) << 0)
+#define		CLK_V_MASK				(0x3ffffff << 0)
+
+#define	MPLL_SS1					0x85c
+#define		CLKV(x)					((x) << 0)
+#define		CLKV_MASK				(0x3ffffff << 0)
+#define	MPLL_SS2					0x860
+#define		CLKS(x)					((x) << 0)
+#define		CLKS_MASK				(0xfff << 0)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv740_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv740_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv740_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv740_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "rv740d.h"
+#include "r600_dpm.h"
+#include "rv770_dpm.h"
+#include "atom.h"
+
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
+
+u32 rv740_get_decoded_reference_divider(u32 encoded_ref)
+{
+	u32 ref = 0;
+
+	switch (encoded_ref) {
+        case 0:
+		ref = 1;
+		break;
+        case 16:
+		ref = 2;
+		break;
+        case 17:
+		ref = 3;
+		break;
+        case 18:
+		ref = 2;
+		break;
+        case 19:
+		ref = 3;
+		break;
+        case 20:
+		ref = 4;
+		break;
+        case 21:
+		ref = 5;
+		break;
+        default:
+		DRM_ERROR("Invalid encoded Reference Divider\n");
+		ref = 0;
+		break;
+	}
+
+	return ref;
+}
+
+struct dll_speed_setting {
+	u16 min;
+	u16 max;
+	u32 dll_speed;
+};
+
+static struct dll_speed_setting dll_speed_table[16] =
+{
+	{ 270, 320, 0x0f },
+	{ 240, 270, 0x0e },
+	{ 200, 240, 0x0d },
+	{ 180, 200, 0x0c },
+	{ 160, 180, 0x0b },
+	{ 140, 160, 0x0a },
+	{ 120, 140, 0x09 },
+	{ 110, 120, 0x08 },
+	{  95, 110, 0x07 },
+	{  85,  95, 0x06 },
+	{  78,  85, 0x05 },
+	{  70,  78, 0x04 },
+	{  65,  70, 0x03 },
+	{  60,  65, 0x02 },
+	{  42,  60, 0x01 },
+	{  00,  42, 0x00 }
+};
+
+u32 rv740_get_dll_speed(bool is_gddr5, u32 memory_clock)
+{
+	int i;
+	u32 factor;
+	u16 data_rate;
+
+	if (is_gddr5)
+		factor = 4;
+	else
+		factor = 2;
+
+	data_rate = (u16)(memory_clock * factor / 1000);
+
+	if (data_rate < dll_speed_table[0].max) {
+		for (i = 0; i < 16; i++) {
+			if (data_rate > dll_speed_table[i].min &&
+			    data_rate <= dll_speed_table[i].max)
+				return dll_speed_table[i].dll_speed;
+		}
+	}
+
+	DRM_DEBUG_KMS("Target MCLK greater than largest MCLK in DLL speed table\n");
+
+	return 0x0f;
+}
+
+int rv740_populate_sclk_value(struct radeon_device *rdev, u32 engine_clock,
+			      RV770_SMC_SCLK_VALUE *sclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct atom_clock_dividers dividers;
+	u32 spll_func_cntl = pi->clk_regs.rv770.cg_spll_func_cntl;
+	u32 spll_func_cntl_2 = pi->clk_regs.rv770.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3 = pi->clk_regs.rv770.cg_spll_func_cntl_3;
+	u32 cg_spll_spread_spectrum = pi->clk_regs.rv770.cg_spll_spread_spectrum;
+	u32 cg_spll_spread_spectrum_2 = pi->clk_regs.rv770.cg_spll_spread_spectrum_2;
+	u64 tmp;
+	u32 reference_clock = rdev->clock.spll.reference_freq;
+	u32 reference_divider;
+	u32 fbdiv;
+	int ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     engine_clock, false, &dividers);
+	if (ret)
+		return ret;
+
+	reference_divider = 1 + dividers.ref_div;
+
+	tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16384;
+	do_div(tmp, reference_clock);
+	fbdiv = (u32) tmp;
+
+	spll_func_cntl &= ~(SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK);
+	spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
+	spll_func_cntl |= SPLL_PDIV_A(dividers.post_div);
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(2);
+
+	spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
+	spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
+	spll_func_cntl_3 |= SPLL_DITHEN;
+
+	if (pi->sclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 vco_freq = engine_clock * dividers.post_div;
+
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+						     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
+			u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
+			u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);
+
+			cg_spll_spread_spectrum &= ~CLK_S_MASK;
+			cg_spll_spread_spectrum |= CLK_S(clk_s);
+			cg_spll_spread_spectrum |= SSEN;
+
+			cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
+			cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
+		}
+	}
+
+	sclk->sclk_value = cpu_to_be32(engine_clock);
+	sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
+	sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
+	sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
+	sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum);
+	sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2);
+
+	return 0;
+}
+
+int rv740_populate_mclk_value(struct radeon_device *rdev,
+			      u32 engine_clock, u32 memory_clock,
+			      RV7XX_SMC_MCLK_VALUE *mclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 mpll_ad_func_cntl = pi->clk_regs.rv770.mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2 = pi->clk_regs.rv770.mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl = pi->clk_regs.rv770.mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2 = pi->clk_regs.rv770.mpll_dq_func_cntl_2;
+	u32 mclk_pwrmgt_cntl = pi->clk_regs.rv770.mclk_pwrmgt_cntl;
+	u32 dll_cntl = pi->clk_regs.rv770.dll_cntl;
+	u32 mpll_ss1 = pi->clk_regs.rv770.mpll_ss1;
+	u32 mpll_ss2 = pi->clk_regs.rv770.mpll_ss2;
+	struct atom_clock_dividers dividers;
+	u32 ibias;
+	u32 dll_speed;
+	int ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
+					     memory_clock, false, &dividers);
+	if (ret)
+		return ret;
+
+	ibias = rv770_map_clkf_to_ibias(rdev, dividers.whole_fb_div);
+
+	mpll_ad_func_cntl &= ~(CLKR_MASK |
+			       YCLK_POST_DIV_MASK |
+			       CLKF_MASK |
+			       CLKFRAC_MASK |
+			       IBIAS_MASK);
+	mpll_ad_func_cntl |= CLKR(dividers.ref_div);
+	mpll_ad_func_cntl |= YCLK_POST_DIV(dividers.post_div);
+	mpll_ad_func_cntl |= CLKF(dividers.whole_fb_div);
+	mpll_ad_func_cntl |= CLKFRAC(dividers.frac_fb_div);
+	mpll_ad_func_cntl |= IBIAS(ibias);
+
+	if (dividers.vco_mode)
+		mpll_ad_func_cntl_2 |= VCO_MODE;
+	else
+		mpll_ad_func_cntl_2 &= ~VCO_MODE;
+
+	if (pi->mem_gddr5) {
+		mpll_dq_func_cntl &= ~(CLKR_MASK |
+				       YCLK_POST_DIV_MASK |
+				       CLKF_MASK |
+				       CLKFRAC_MASK |
+				       IBIAS_MASK);
+		mpll_dq_func_cntl |= CLKR(dividers.ref_div);
+		mpll_dq_func_cntl |= YCLK_POST_DIV(dividers.post_div);
+		mpll_dq_func_cntl |= CLKF(dividers.whole_fb_div);
+		mpll_dq_func_cntl |= CLKFRAC(dividers.frac_fb_div);
+		mpll_dq_func_cntl |= IBIAS(ibias);
+
+		if (dividers.vco_mode)
+			mpll_dq_func_cntl_2 |= VCO_MODE;
+		else
+			mpll_dq_func_cntl_2 &= ~VCO_MODE;
+	}
+
+	if (pi->mclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 vco_freq = memory_clock * dividers.post_div;
+
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+						     ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
+			u32 reference_clock = rdev->clock.mpll.reference_freq;
+			u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
+			u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
+			u32 clk_v = 0x40000 * ss.percentage *
+				(dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000);
+
+			mpll_ss1 &= ~CLKV_MASK;
+			mpll_ss1 |= CLKV(clk_v);
+
+			mpll_ss2 &= ~CLKS_MASK;
+			mpll_ss2 |= CLKS(clk_s);
+		}
+	}
+
+	dll_speed = rv740_get_dll_speed(pi->mem_gddr5,
+					memory_clock);
+
+	mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;
+	mclk_pwrmgt_cntl |= DLL_SPEED(dll_speed);
+
+	mclk->mclk770.mclk_value = cpu_to_be32(memory_clock);
+	mclk->mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
+	mclk->mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
+	mclk->mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
+	mclk->mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
+	mclk->mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	mclk->mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
+	mclk->mclk770.vMPLL_SS = cpu_to_be32(mpll_ss1);
+	mclk->mclk770.vMPLL_SS2 = cpu_to_be32(mpll_ss2);
+
+	return 0;
+}
+
+void rv740_read_clock_registers(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	pi->clk_regs.rv770.cg_spll_func_cntl =
+		RREG32(CG_SPLL_FUNC_CNTL);
+	pi->clk_regs.rv770.cg_spll_func_cntl_2 =
+		RREG32(CG_SPLL_FUNC_CNTL_2);
+	pi->clk_regs.rv770.cg_spll_func_cntl_3 =
+		RREG32(CG_SPLL_FUNC_CNTL_3);
+	pi->clk_regs.rv770.cg_spll_spread_spectrum =
+		RREG32(CG_SPLL_SPREAD_SPECTRUM);
+	pi->clk_regs.rv770.cg_spll_spread_spectrum_2 =
+		RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
+
+	pi->clk_regs.rv770.mpll_ad_func_cntl =
+		RREG32(MPLL_AD_FUNC_CNTL);
+	pi->clk_regs.rv770.mpll_ad_func_cntl_2 =
+		RREG32(MPLL_AD_FUNC_CNTL_2);
+	pi->clk_regs.rv770.mpll_dq_func_cntl =
+		RREG32(MPLL_DQ_FUNC_CNTL);
+	pi->clk_regs.rv770.mpll_dq_func_cntl_2 =
+		RREG32(MPLL_DQ_FUNC_CNTL_2);
+	pi->clk_regs.rv770.mclk_pwrmgt_cntl =
+		RREG32(MCLK_PWRMGT_CNTL);
+	pi->clk_regs.rv770.dll_cntl = RREG32(DLL_CNTL);
+	pi->clk_regs.rv770.mpll_ss1 = RREG32(MPLL_SS1);
+	pi->clk_regs.rv770.mpll_ss2 = RREG32(MPLL_SS2);
+}
+
+int rv740_populate_smc_acpi_state(struct radeon_device *rdev,
+				  RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 mpll_ad_func_cntl = pi->clk_regs.rv770.mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2 = pi->clk_regs.rv770.mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl = pi->clk_regs.rv770.mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2 = pi->clk_regs.rv770.mpll_dq_func_cntl_2;
+	u32 spll_func_cntl = pi->clk_regs.rv770.cg_spll_func_cntl;
+	u32 spll_func_cntl_2 = pi->clk_regs.rv770.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3 = pi->clk_regs.rv770.cg_spll_func_cntl_3;
+	u32 mclk_pwrmgt_cntl = pi->clk_regs.rv770.mclk_pwrmgt_cntl;
+	u32 dll_cntl = pi->clk_regs.rv770.dll_cntl;
+
+	table->ACPIState = table->initialState;
+
+	table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
+
+	if (pi->acpi_vddc) {
+		rv770_populate_vddc_value(rdev, pi->acpi_vddc,
+					  &table->ACPIState.levels[0].vddc);
+		table->ACPIState.levels[0].gen2PCIE =
+			pi->pcie_gen2 ?
+			pi->acpi_pcie_gen2 : 0;
+		table->ACPIState.levels[0].gen2XSP =
+			pi->acpi_pcie_gen2;
+	} else {
+		rv770_populate_vddc_value(rdev, pi->min_vddc_in_table,
+					  &table->ACPIState.levels[0].vddc);
+		table->ACPIState.levels[0].gen2PCIE = 0;
+	}
+
+	mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
+
+	mpll_dq_func_cntl_2 |= BYPASS | BIAS_GEN_PDNB | RESET_EN;
+
+	mclk_pwrmgt_cntl |= (MRDCKA0_RESET |
+			     MRDCKA1_RESET |
+			     MRDCKB0_RESET |
+			     MRDCKB1_RESET |
+			     MRDCKC0_RESET |
+			     MRDCKC1_RESET |
+			     MRDCKD0_RESET |
+			     MRDCKD1_RESET);
+
+	dll_cntl |= (MRDCKA0_BYPASS |
+		     MRDCKA1_BYPASS |
+		     MRDCKB0_BYPASS |
+		     MRDCKB1_BYPASS |
+		     MRDCKC0_BYPASS |
+		     MRDCKC1_BYPASS |
+		     MRDCKD0_BYPASS |
+		     MRDCKD1_BYPASS);
+
+	spll_func_cntl |= SPLL_RESET | SPLL_SLEEP | SPLL_BYPASS_EN;
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(4);
+
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
+	table->ACPIState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	table->ACPIState.levels[0].mclk.mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
+
+	table->ACPIState.levels[0].mclk.mclk770.mclk_value = 0;
+
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
+
+	table->ACPIState.levels[0].sclk.sclk_value = 0;
+
+	table->ACPIState.levels[1] = table->ACPIState.levels[0];
+	table->ACPIState.levels[2] = table->ACPIState.levels[0];
+
+	rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
+
+	return 0;
+}
+
+void rv740_enable_mclk_spread_spectrum(struct radeon_device *rdev,
+				       bool enable)
+{
+	if (enable)
+		WREG32_P(MPLL_CNTL_MODE, SS_SSEN, ~SS_SSEN);
+	else
+		WREG32_P(MPLL_CNTL_MODE, 0, ~SS_SSEN);
+}
+
+u8 rv740_get_mclk_frequency_ratio(u32 memory_clock)
+{
+	u8 mc_para_index;
+
+	if ((memory_clock < 10000) || (memory_clock > 47500))
+		mc_para_index = 0x00;
+	else
+		mc_para_index = (u8)((memory_clock - 10000) / 2500);
+
+	return mc_para_index;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770.c	2013-08-25 20:43:22.000000000 -0400
@@ -744,10 +744,10 @@ static void rv770_init_golden_registers(
 						 (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers));
 		radeon_program_register_sequence(rdev,
 						 rv730_golden_registers,
-						 (const u32)ARRAY_SIZE(rv770_golden_registers));
+						 (const u32)ARRAY_SIZE(rv730_golden_registers));
 		radeon_program_register_sequence(rdev,
 						 rv730_mgcg_init,
-						 (const u32)ARRAY_SIZE(rv770_mgcg_init));
+						 (const u32)ARRAY_SIZE(rv730_mgcg_init));
 		break;
 	case CHIP_RV710:
 		radeon_program_register_sequence(rdev,
@@ -758,18 +758,18 @@ static void rv770_init_golden_registers(
 						 (const u32)ARRAY_SIZE(r7xx_golden_dyn_gpr_registers));
 		radeon_program_register_sequence(rdev,
 						 rv710_golden_registers,
-						 (const u32)ARRAY_SIZE(rv770_golden_registers));
+						 (const u32)ARRAY_SIZE(rv710_golden_registers));
 		radeon_program_register_sequence(rdev,
 						 rv710_mgcg_init,
-						 (const u32)ARRAY_SIZE(rv770_mgcg_init));
+						 (const u32)ARRAY_SIZE(rv710_mgcg_init));
 		break;
 	case CHIP_RV740:
 		radeon_program_register_sequence(rdev,
 						 rv740_golden_registers,
-						 (const u32)ARRAY_SIZE(rv770_golden_registers));
+						 (const u32)ARRAY_SIZE(rv740_golden_registers));
 		radeon_program_register_sequence(rdev,
 						 rv740_mgcg_init,
-						 (const u32)ARRAY_SIZE(rv770_mgcg_init));
+						 (const u32)ARRAY_SIZE(rv740_mgcg_init));
 		break;
 	default:
 		break;
@@ -1829,6 +1829,8 @@ static int rv770_startup(struct radeon_d
 	/* enable pcie gen2 link */
 	rv770_pcie_gen2_enable(rdev);
 
+	rv770_mc_program(rdev);
+
 	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
 		r = r600_init_microcode(rdev);
 		if (r) {
@@ -1841,7 +1843,6 @@ static int rv770_startup(struct radeon_d
 	if (r)
 		return r;
 
-	rv770_mc_program(rdev);
 	if (rdev->flags & RADEON_IS_AGP) {
 		rv770_agp_enable(rdev);
 	} else {
@@ -1983,6 +1984,7 @@ int rv770_resume(struct radeon_device *r
 int rv770_suspend(struct radeon_device *rdev)
 {
 	r600_audio_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_suspend(rdev);
 	r700_cp_stop(rdev);
 	r600_dma_stop(rdev);
@@ -2098,6 +2100,7 @@ void rv770_fini(struct radeon_device *rd
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	rv770_pcie_gart_fini(rdev);
+	r600_uvd_stop(rdev);
 	radeon_uvd_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770d.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770d.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770d.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770d.h	2013-08-25 20:43:22.000000000 -0400
@@ -62,6 +62,246 @@
 #	define UPLL_FB_DIV(x)				((x) << 0)
 #	define UPLL_FB_DIV_MASK				0x01FFFFFF
 
+/* pm registers */
+#define	SMC_SRAM_ADDR					0x200
+#define		SMC_SRAM_AUTO_INC_DIS				(1 << 16)
+#define	SMC_SRAM_DATA					0x204
+#define	SMC_IO						0x208
+#define		SMC_RST_N					(1 << 0)
+#define		SMC_STOP_MODE					(1 << 2)
+#define		SMC_CLK_EN					(1 << 11)
+#define	SMC_MSG						0x20c
+#define		HOST_SMC_MSG(x)					((x) << 0)
+#define		HOST_SMC_MSG_MASK				(0xff << 0)
+#define		HOST_SMC_MSG_SHIFT				0
+#define		HOST_SMC_RESP(x)				((x) << 8)
+#define		HOST_SMC_RESP_MASK				(0xff << 8)
+#define		HOST_SMC_RESP_SHIFT				8
+#define		SMC_HOST_MSG(x)					((x) << 16)
+#define		SMC_HOST_MSG_MASK				(0xff << 16)
+#define		SMC_HOST_MSG_SHIFT				16
+#define		SMC_HOST_RESP(x)				((x) << 24)
+#define		SMC_HOST_RESP_MASK				(0xff << 24)
+#define		SMC_HOST_RESP_SHIFT				24
+
+#define	SMC_ISR_FFD8_FFDB				0x218
+
+#define	CG_SPLL_FUNC_CNTL				0x600
+#define		SPLL_RESET				(1 << 0)
+#define		SPLL_SLEEP				(1 << 1)
+#define		SPLL_DIVEN				(1 << 2)
+#define		SPLL_BYPASS_EN				(1 << 3)
+#define		SPLL_REF_DIV(x)				((x) << 4)
+#define		SPLL_REF_DIV_MASK			(0x3f << 4)
+#define		SPLL_HILEN(x)				((x) << 12)
+#define		SPLL_HILEN_MASK				(0xf << 12)
+#define		SPLL_LOLEN(x)				((x) << 16)
+#define		SPLL_LOLEN_MASK				(0xf << 16)
+#define	CG_SPLL_FUNC_CNTL_2				0x604
+#define		SCLK_MUX_SEL(x)				((x) << 0)
+#define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define	CG_SPLL_FUNC_CNTL_3				0x608
+#define		SPLL_FB_DIV(x)				((x) << 0)
+#define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
+#define		SPLL_DITHEN				(1 << 28)
+
+#define	SPLL_CNTL_MODE					0x610
+#define		SPLL_DIV_SYNC				(1 << 5)
+
+#define	MPLL_AD_FUNC_CNTL				0x624
+#define		CLKF(x)					((x) << 0)
+#define		CLKF_MASK				(0x7f << 0)
+#define		CLKR(x)					((x) << 7)
+#define		CLKR_MASK				(0x1f << 7)
+#define		CLKFRAC(x)				((x) << 12)
+#define		CLKFRAC_MASK				(0x1f << 12)
+#define		YCLK_POST_DIV(x)			((x) << 17)
+#define		YCLK_POST_DIV_MASK			(3 << 17)
+#define		IBIAS(x)				((x) << 20)
+#define		IBIAS_MASK				(0x3ff << 20)
+#define		RESET					(1 << 30)
+#define		PDNB					(1 << 31)
+#define	MPLL_AD_FUNC_CNTL_2				0x628
+#define		BYPASS					(1 << 19)
+#define		BIAS_GEN_PDNB				(1 << 24)
+#define		RESET_EN				(1 << 25)
+#define		VCO_MODE				(1 << 29)
+#define	MPLL_DQ_FUNC_CNTL				0x62c
+#define	MPLL_DQ_FUNC_CNTL_2				0x630
+
+#define GENERAL_PWRMGT                                  0x63c
+#       define GLOBAL_PWRMGT_EN                         (1 << 0)
+#       define STATIC_PM_EN                             (1 << 1)
+#       define THERMAL_PROTECTION_DIS                   (1 << 2)
+#       define THERMAL_PROTECTION_TYPE                  (1 << 3)
+#       define ENABLE_GEN2PCIE                          (1 << 4)
+#       define ENABLE_GEN2XSP                           (1 << 5)
+#       define SW_SMIO_INDEX(x)                         ((x) << 6)
+#       define SW_SMIO_INDEX_MASK                       (3 << 6)
+#       define SW_SMIO_INDEX_SHIFT                      6
+#       define LOW_VOLT_D2_ACPI                         (1 << 8)
+#       define LOW_VOLT_D3_ACPI                         (1 << 9)
+#       define VOLT_PWRMGT_EN                           (1 << 10)
+#       define BACKBIAS_PAD_EN                          (1 << 18)
+#       define BACKBIAS_VALUE                           (1 << 19)
+#       define DYN_SPREAD_SPECTRUM_EN                   (1 << 23)
+#       define AC_DC_SW                                 (1 << 24)
+
+#define CG_TPC                                            0x640
+#define SCLK_PWRMGT_CNTL                                  0x644
+#       define SCLK_PWRMGT_OFF                            (1 << 0)
+#       define SCLK_LOW_D1                                (1 << 1)
+#       define FIR_RESET                                  (1 << 4)
+#       define FIR_FORCE_TREND_SEL                        (1 << 5)
+#       define FIR_TREND_MODE                             (1 << 6)
+#       define DYN_GFX_CLK_OFF_EN                         (1 << 7)
+#       define GFX_CLK_FORCE_ON                           (1 << 8)
+#       define GFX_CLK_REQUEST_OFF                        (1 << 9)
+#       define GFX_CLK_FORCE_OFF                          (1 << 10)
+#       define GFX_CLK_OFF_ACPI_D1                        (1 << 11)
+#       define GFX_CLK_OFF_ACPI_D2                        (1 << 12)
+#       define GFX_CLK_OFF_ACPI_D3                        (1 << 13)
+#define	MCLK_PWRMGT_CNTL				0x648
+#       define DLL_SPEED(x)				((x) << 0)
+#       define DLL_SPEED_MASK				(0x1f << 0)
+#       define MPLL_PWRMGT_OFF                          (1 << 5)
+#       define DLL_READY                                (1 << 6)
+#       define MC_INT_CNTL                              (1 << 7)
+#       define MRDCKA0_SLEEP                            (1 << 8)
+#       define MRDCKA1_SLEEP                            (1 << 9)
+#       define MRDCKB0_SLEEP                            (1 << 10)
+#       define MRDCKB1_SLEEP                            (1 << 11)
+#       define MRDCKC0_SLEEP                            (1 << 12)
+#       define MRDCKC1_SLEEP                            (1 << 13)
+#       define MRDCKD0_SLEEP                            (1 << 14)
+#       define MRDCKD1_SLEEP                            (1 << 15)
+#       define MRDCKA0_RESET                            (1 << 16)
+#       define MRDCKA1_RESET                            (1 << 17)
+#       define MRDCKB0_RESET                            (1 << 18)
+#       define MRDCKB1_RESET                            (1 << 19)
+#       define MRDCKC0_RESET                            (1 << 20)
+#       define MRDCKC1_RESET                            (1 << 21)
+#       define MRDCKD0_RESET                            (1 << 22)
+#       define MRDCKD1_RESET                            (1 << 23)
+#       define DLL_READY_READ                           (1 << 24)
+#       define USE_DISPLAY_GAP                          (1 << 25)
+#       define USE_DISPLAY_URGENT_NORMAL                (1 << 26)
+#       define MPLL_TURNOFF_D2                          (1 << 28)
+#define	DLL_CNTL					0x64c
+#       define MRDCKA0_BYPASS                           (1 << 24)
+#       define MRDCKA1_BYPASS                           (1 << 25)
+#       define MRDCKB0_BYPASS                           (1 << 26)
+#       define MRDCKB1_BYPASS                           (1 << 27)
+#       define MRDCKC0_BYPASS                           (1 << 28)
+#       define MRDCKC1_BYPASS                           (1 << 29)
+#       define MRDCKD0_BYPASS                           (1 << 30)
+#       define MRDCKD1_BYPASS                           (1 << 31)
+
+#define MPLL_TIME                                         0x654
+#       define MPLL_LOCK_TIME(x)			((x) << 0)
+#       define MPLL_LOCK_TIME_MASK			(0xffff << 0)
+#       define MPLL_RESET_TIME(x)			((x) << 16)
+#       define MPLL_RESET_TIME_MASK			(0xffff << 16)
+
+#define CG_CLKPIN_CNTL                                    0x660
+#       define MUX_TCLK_TO_XCLK                           (1 << 8)
+#       define XTALIN_DIVIDE                              (1 << 9)
+
+#define TARGET_AND_CURRENT_PROFILE_INDEX                  0x66c
+#       define CURRENT_PROFILE_INDEX_MASK                 (0xf << 4)
+#       define CURRENT_PROFILE_INDEX_SHIFT                4
+
+#define S0_VID_LOWER_SMIO_CNTL                            0x678
+#define S1_VID_LOWER_SMIO_CNTL                            0x67c
+#define S2_VID_LOWER_SMIO_CNTL                            0x680
+#define S3_VID_LOWER_SMIO_CNTL                            0x684
+
+#define CG_FTV                                            0x690
+#define CG_FFCT_0                                         0x694
+#       define UTC_0(x)                                   ((x) << 0)
+#       define UTC_0_MASK                                 (0x3ff << 0)
+#       define DTC_0(x)                                   ((x) << 10)
+#       define DTC_0_MASK                                 (0x3ff << 10)
+
+#define CG_BSP                                          0x6d0
+#       define BSP(x)					((x) << 0)
+#       define BSP_MASK					(0xffff << 0)
+#       define BSU(x)					((x) << 16)
+#       define BSU_MASK					(0xf << 16)
+#define CG_AT                                           0x6d4
+#       define CG_R(x)					((x) << 0)
+#       define CG_R_MASK				(0xffff << 0)
+#       define CG_L(x)					((x) << 16)
+#       define CG_L_MASK				(0xffff << 16)
+#define CG_GIT                                          0x6d8
+#       define CG_GICST(x)                              ((x) << 0)
+#       define CG_GICST_MASK                            (0xffff << 0)
+#       define CG_GIPOT(x)                              ((x) << 16)
+#       define CG_GIPOT_MASK                            (0xffff << 16)
+
+#define CG_SSP                                            0x6e8
+#       define SST(x)                                     ((x) << 0)
+#       define SST_MASK                                   (0xffff << 0)
+#       define SSTU(x)                                    ((x) << 16)
+#       define SSTU_MASK                                  (0xf << 16)
+
+#define CG_DISPLAY_GAP_CNTL                               0x714
+#       define DISP1_GAP(x)                               ((x) << 0)
+#       define DISP1_GAP_MASK                             (3 << 0)
+#       define DISP2_GAP(x)                               ((x) << 2)
+#       define DISP2_GAP_MASK                             (3 << 2)
+#       define VBI_TIMER_COUNT(x)                         ((x) << 4)
+#       define VBI_TIMER_COUNT_MASK                       (0x3fff << 4)
+#       define VBI_TIMER_UNIT(x)                          ((x) << 20)
+#       define VBI_TIMER_UNIT_MASK                        (7 << 20)
+#       define DISP1_GAP_MCHG(x)                          ((x) << 24)
+#       define DISP1_GAP_MCHG_MASK                        (3 << 24)
+#       define DISP2_GAP_MCHG(x)                          ((x) << 26)
+#       define DISP2_GAP_MCHG_MASK                        (3 << 26)
+
+#define	CG_SPLL_SPREAD_SPECTRUM				0x790
+#define		SSEN					(1 << 0)
+#define		CLKS(x)					((x) << 4)
+#define		CLKS_MASK				(0xfff << 4)
+#define	CG_SPLL_SPREAD_SPECTRUM_2			0x794
+#define		CLKV(x)					((x) << 0)
+#define		CLKV_MASK				(0x3ffffff << 0)
+#define	CG_MPLL_SPREAD_SPECTRUM				0x798
+#define CG_UPLL_SPREAD_SPECTRUM				0x79c
+#	define SSEN_MASK				0x00000001
+
+#define CG_CGTT_LOCAL_0                                   0x7d0
+#define CG_CGTT_LOCAL_1                                   0x7d4
+
+#define BIOS_SCRATCH_4                                    0x1734
+
+#define MC_SEQ_MISC0                                      0x2a00
+#define         MC_SEQ_MISC0_GDDR5_SHIFT                  28
+#define         MC_SEQ_MISC0_GDDR5_MASK                   0xf0000000
+#define         MC_SEQ_MISC0_GDDR5_VALUE                  5
+
+#define MC_ARB_SQM_RATIO                                  0x2770
+#define		STATE0(x)				((x) << 0)
+#define		STATE0_MASK				(0xff << 0)
+#define		STATE1(x)				((x) << 8)
+#define		STATE1_MASK				(0xff << 8)
+#define		STATE2(x)				((x) << 16)
+#define		STATE2_MASK				(0xff << 16)
+#define		STATE3(x)				((x) << 24)
+#define		STATE3_MASK				(0xff << 24)
+
+#define	MC_ARB_RFSH_RATE				0x27b0
+#define		POWERMODE0(x)				((x) << 0)
+#define		POWERMODE0_MASK				(0xff << 0)
+#define		POWERMODE1(x)				((x) << 8)
+#define		POWERMODE1_MASK				(0xff << 8)
+#define		POWERMODE2(x)				((x) << 16)
+#define		POWERMODE2_MASK				(0xff << 16)
+#define		POWERMODE3(x)				((x) << 24)
+#define		POWERMODE3_MASK				(0xff << 24)
+
+#define CGTS_SM_CTRL_REG                                  0x9150
+
 /* Registers */
 #define	CB_COLOR0_BASE					0x28040
 #define	CB_COLOR1_BASE					0x28044
@@ -86,8 +326,8 @@
 #define	CONFIG_MEMSIZE					0x5428
 
 #define	CP_ME_CNTL					0x86D8
-#define		CP_ME_HALT					(1<<28)
-#define		CP_PFP_HALT					(1<<26)
+#define		CP_ME_HALT					(1 << 28)
+#define		CP_PFP_HALT					(1 << 26)
 #define	CP_ME_RAM_DATA					0xC160
 #define	CP_ME_RAM_RADDR					0xC158
 #define	CP_ME_RAM_WADDR					0xC15C
@@ -157,9 +397,22 @@
 #define		GUI_ACTIVE					(1<<31)
 #define	GRBM_STATUS2					0x8014
 
-#define CG_CLKPIN_CNTL                                    0x660
-#       define MUX_TCLK_TO_XCLK                           (1 << 8)
-#       define XTALIN_DIVIDE                              (1 << 9)
+#define	CG_THERMAL_CTRL					0x72C
+#define 	DPM_EVENT_SRC(x)			((x) << 0)
+#define 	DPM_EVENT_SRC_MASK			(7 << 0)
+#define		DIG_THERM_DPM(x)			((x) << 14)
+#define		DIG_THERM_DPM_MASK			0x003FC000
+#define		DIG_THERM_DPM_SHIFT			14
+
+#define	CG_THERMAL_INT					0x734
+#define		DIG_THERM_INTH(x)			((x) << 8)
+#define		DIG_THERM_INTH_MASK			0x0000FF00
+#define		DIG_THERM_INTH_SHIFT			8
+#define		DIG_THERM_INTL(x)			((x) << 16)
+#define		DIG_THERM_INTL_MASK			0x00FF0000
+#define		DIG_THERM_INTL_SHIFT			16
+#define 	THERM_INT_MASK_HIGH			(1 << 24)
+#define 	THERM_INT_MASK_LOW			(1 << 25)
 
 #define	CG_MULT_THERMAL_STATUS				0x740
 #define		ASIC_T(x)			        ((x) << 16)
@@ -662,7 +915,22 @@
 #define D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH             0x691c
 #define D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH             0x611c
 
-/* PCIE link stuff */
+/* PCIE indirect regs */
+#define PCIE_P_CNTL                                       0x40
+#       define P_PLL_PWRDN_IN_L1L23                       (1 << 3)
+#       define P_PLL_BUF_PDNB                             (1 << 4)
+#       define P_PLL_PDNB                                 (1 << 9)
+#       define P_ALLOW_PRX_FRONTEND_SHUTOFF               (1 << 12)
+/* PCIE PORT regs */
+#define PCIE_LC_CNTL                                      0xa0
+#       define LC_L0S_INACTIVITY(x)                       ((x) << 8)
+#       define LC_L0S_INACTIVITY_MASK                     (0xf << 8)
+#       define LC_L0S_INACTIVITY_SHIFT                    8
+#       define LC_L1_INACTIVITY(x)                        ((x) << 12)
+#       define LC_L1_INACTIVITY_MASK                      (0xf << 12)
+#       define LC_L1_INACTIVITY_SHIFT                     12
+#       define LC_PMI_TO_L1_DIS                           (1 << 16)
+#       define LC_ASPM_TO_L1_DIS                          (1 << 24)
 #define PCIE_LC_TRAINING_CNTL                             0xa1 /* PCIE_P */
 #define PCIE_LC_LINK_WIDTH_CNTL                           0xa2 /* PCIE_P */
 #       define LC_LINK_WIDTH_SHIFT                        0
@@ -690,6 +958,9 @@
 #       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK      (0x3 << 8)
 #       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT     3
 #       define LC_CURRENT_DATA_RATE                       (1 << 11)
+#       define LC_HW_VOLTAGE_IF_CONTROL(x)                ((x) << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_MASK              (3 << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_SHIFT             12
 #       define LC_VOLTAGE_TIMER_SEL_MASK                  (0xf << 14)
 #       define LC_CLR_FAILED_SPD_CHANGE_CNT               (1 << 21)
 #       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 23)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2526 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "rv770d.h"
+#include "r600_dpm.h"
+#include "rv770_dpm.h"
+#include "cypress_dpm.h"
+#include "atom.h"
+#include <linux/seq_file.h>
+
+#define MC_CG_ARB_FREQ_F0           0x0a
+#define MC_CG_ARB_FREQ_F1           0x0b
+#define MC_CG_ARB_FREQ_F2           0x0c
+#define MC_CG_ARB_FREQ_F3           0x0d
+
+#define MC_CG_SEQ_DRAMCONF_S0       0x05
+#define MC_CG_SEQ_DRAMCONF_S1       0x06
+
+#define PCIE_BUS_CLK                10000
+#define TCLK                        (PCIE_BUS_CLK / 10)
+
+#define SMC_RAM_END 0xC000
+
+struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps)
+{
+	struct rv7xx_ps *ps = rps->ps_priv;
+
+	return ps;
+}
+
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rdev->pm.dpm.priv;
+
+	return pi;
+}
+
+struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *pi = rdev->pm.dpm.priv;
+
+	return pi;
+}
+
+static void rv770_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
+					       bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+	if (enable) {
+		tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+		tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
+		tmp |= LC_GEN2_EN_STRAP;
+	} else {
+		if (!pi->boot_in_gen2) {
+			tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+			tmp &= ~LC_GEN2_EN_STRAP;
+		}
+	}
+	if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
+	    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
+		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+
+}
+
+static void rv770_enable_l0s(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL) & ~LC_L0S_INACTIVITY_MASK;
+	tmp |= LC_L0S_INACTIVITY(3);
+	WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
+}
+
+static void rv770_enable_l1(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL);
+	tmp &= ~LC_L1_INACTIVITY_MASK;
+	tmp |= LC_L1_INACTIVITY(4);
+	tmp &= ~LC_PMI_TO_L1_DIS;
+	tmp &= ~LC_ASPM_TO_L1_DIS;
+	WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
+}
+
+static void rv770_enable_pll_sleep_in_l1(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL) & ~LC_L1_INACTIVITY_MASK;
+	tmp |= LC_L1_INACTIVITY(8);
+	WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
+
+	/* NOTE, this is a PCIE indirect reg, not PCIE PORT */
+	tmp = RREG32_PCIE(PCIE_P_CNTL);
+	tmp |= P_PLL_PWRDN_IN_L1L23;
+	tmp &= ~P_PLL_BUF_PDNB;
+	tmp &= ~P_PLL_PDNB;
+	tmp |= P_ALLOW_PRX_FRONTEND_SHUTOFF;
+	WREG32_PCIE(PCIE_P_CNTL, tmp);
+}
+
+static void rv770_gfx_clock_gating_enable(struct radeon_device *rdev,
+					  bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
+	else {
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
+		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
+		RREG32(GB_TILING_CONFIG);
+	}
+}
+
+static void rv770_mg_clock_gating_enable(struct radeon_device *rdev,
+					 bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (enable) {
+		u32 mgcg_cgtt_local0;
+
+		if (rdev->family == CHIP_RV770)
+			mgcg_cgtt_local0 = RV770_MGCGTTLOCAL0_DFLT;
+		else
+			mgcg_cgtt_local0 = RV7XX_MGCGTTLOCAL0_DFLT;
+
+		WREG32(CG_CGTT_LOCAL_0, mgcg_cgtt_local0);
+		WREG32(CG_CGTT_LOCAL_1, (RV770_MGCGTTLOCAL1_DFLT & 0xFFFFCFFF));
+
+		if (pi->mgcgtssm)
+			WREG32(CGTS_SM_CTRL_REG, RV770_MGCGCGTSSMCTRL_DFLT);
+	} else {
+		WREG32(CG_CGTT_LOCAL_0, 0xFFFFFFFF);
+		WREG32(CG_CGTT_LOCAL_1, 0xFFFFCFFF);
+	}
+}
+
+void rv770_restore_cgcg(struct radeon_device *rdev)
+{
+	bool dpm_en = false, cg_en = false;
+
+	if (RREG32(GENERAL_PWRMGT) & GLOBAL_PWRMGT_EN)
+		dpm_en = true;
+	if (RREG32(SCLK_PWRMGT_CNTL) & DYN_GFX_CLK_OFF_EN)
+		cg_en = true;
+
+	if (dpm_en && !cg_en)
+		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
+}
+
+static void rv770_start_dpm(struct radeon_device *rdev)
+{
+	WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
+
+	WREG32_P(MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF);
+
+	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
+}
+
+void rv770_stop_dpm(struct radeon_device *rdev)
+{
+	PPSMC_Result result;
+
+	result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled);
+
+	if (result != PPSMC_Result_OK)
+		DRM_ERROR("Could not force DPM to low.\n");
+
+	WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
+
+	WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
+
+	WREG32_P(MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF);
+}
+
+bool rv770_dpm_enabled(struct radeon_device *rdev)
+{
+	if (RREG32(GENERAL_PWRMGT) & GLOBAL_PWRMGT_EN)
+		return true;
+	else
+		return false;
+}
+
+void rv770_enable_thermal_protection(struct radeon_device *rdev,
+				     bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
+	else
+		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
+}
+
+void rv770_enable_acpi_pm(struct radeon_device *rdev)
+{
+	WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
+}
+
+u8 rv770_get_seq_value(struct radeon_device *rdev,
+		       struct rv7xx_pl *pl)
+{
+	return (pl->flags & ATOM_PPLIB_R600_FLAGS_LOWPOWER) ?
+		MC_CG_SEQ_DRAMCONF_S0 : MC_CG_SEQ_DRAMCONF_S1;
+}
+
+int rv770_read_smc_soft_register(struct radeon_device *rdev,
+				 u16 reg_offset, u32 *value)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	return rv770_read_smc_sram_dword(rdev,
+					 pi->soft_regs_start + reg_offset,
+					 value, pi->sram_end);
+}
+
+int rv770_write_smc_soft_register(struct radeon_device *rdev,
+				  u16 reg_offset, u32 value)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	return rv770_write_smc_sram_dword(rdev,
+					  pi->soft_regs_start + reg_offset,
+					  value, pi->sram_end);
+}
+
+int rv770_populate_smc_t(struct radeon_device *rdev,
+			 struct radeon_ps *radeon_state,
+			 RV770_SMC_SWSTATE *smc_state)
+{
+	struct rv7xx_ps *state = rv770_get_ps(radeon_state);
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	int i;
+	int a_n;
+	int a_d;
+	u8 l[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
+	u8 r[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
+	u32 a_t;
+
+	l[0] = 0;
+	r[2] = 100;
+
+	a_n = (int)state->medium.sclk * pi->lmp +
+		(int)state->low.sclk * (R600_AH_DFLT - pi->rlp);
+	a_d = (int)state->low.sclk * (100 - (int)pi->rlp) +
+		(int)state->medium.sclk * pi->lmp;
+
+	l[1] = (u8)(pi->lmp - (int)pi->lmp * a_n / a_d);
+	r[0] = (u8)(pi->rlp + (100 - (int)pi->rlp) * a_n / a_d);
+
+	a_n = (int)state->high.sclk * pi->lhp + (int)state->medium.sclk *
+		(R600_AH_DFLT - pi->rmp);
+	a_d = (int)state->medium.sclk * (100 - (int)pi->rmp) +
+		(int)state->high.sclk * pi->lhp;
+
+	l[2] = (u8)(pi->lhp - (int)pi->lhp * a_n / a_d);
+	r[1] = (u8)(pi->rmp + (100 - (int)pi->rmp) * a_n / a_d);
+
+	for (i = 0; i < (RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1); i++) {
+		a_t = CG_R(r[i] * pi->bsp / 200) | CG_L(l[i] * pi->bsp / 200);
+		smc_state->levels[i].aT = cpu_to_be32(a_t);
+	}
+
+	a_t = CG_R(r[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1] * pi->pbsp / 200) |
+		CG_L(l[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1] * pi->pbsp / 200);
+
+	smc_state->levels[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1].aT =
+		cpu_to_be32(a_t);
+
+	return 0;
+}
+
+int rv770_populate_smc_sp(struct radeon_device *rdev,
+			  struct radeon_ps *radeon_state,
+			  RV770_SMC_SWSTATE *smc_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	int i;
+
+	for (i = 0; i < (RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1); i++)
+		smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);
+
+	smc_state->levels[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1].bSP =
+		cpu_to_be32(pi->psp);
+
+	return 0;
+}
+
+static void rv770_calculate_fractional_mpll_feedback_divider(u32 memory_clock,
+							     u32 reference_clock,
+							     bool gddr5,
+							     struct atom_clock_dividers *dividers,
+							     u32 *clkf,
+							     u32 *clkfrac)
+{
+	u32 post_divider, reference_divider, feedback_divider8;
+	u32 fyclk;
+
+	if (gddr5)
+		fyclk = (memory_clock * 8) / 2;
+	else
+		fyclk = (memory_clock * 4) / 2;
+
+	post_divider = dividers->post_div;
+	reference_divider = dividers->ref_div;
+
+	feedback_divider8 =
+		(8 * fyclk * reference_divider * post_divider) / reference_clock;
+
+	*clkf = feedback_divider8 / 8;
+	*clkfrac = feedback_divider8 % 8;
+}
+
+static int rv770_encode_yclk_post_div(u32 postdiv, u32 *encoded_postdiv)
+{
+	int ret = 0;
+
+	switch (postdiv) {
+        case 1:
+		*encoded_postdiv = 0;
+		break;
+        case 2:
+		*encoded_postdiv = 1;
+		break;
+        case 4:
+		*encoded_postdiv = 2;
+		break;
+        case 8:
+		*encoded_postdiv = 3;
+		break;
+        case 16:
+		*encoded_postdiv = 4;
+		break;
+        default:
+		ret = -EINVAL;
+		break;
+	}
+
+    return ret;
+}
+
+u32 rv770_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf)
+{
+	if (clkf <= 0x10)
+		return 0x4B;
+	if (clkf <= 0x19)
+		return 0x5B;
+	if (clkf <= 0x21)
+		return 0x2B;
+	if (clkf <= 0x27)
+		return 0x6C;
+	if (clkf <= 0x31)
+		return 0x9D;
+	return 0xC6;
+}
+
+static int rv770_populate_mclk_value(struct radeon_device *rdev,
+				     u32 engine_clock, u32 memory_clock,
+				     RV7XX_SMC_MCLK_VALUE *mclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u8 encoded_reference_dividers[] = { 0, 16, 17, 20, 21 };
+	u32 mpll_ad_func_cntl =
+		pi->clk_regs.rv770.mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2 =
+		pi->clk_regs.rv770.mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl =
+		pi->clk_regs.rv770.mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2 =
+		pi->clk_regs.rv770.mpll_dq_func_cntl_2;
+	u32 mclk_pwrmgt_cntl =
+		pi->clk_regs.rv770.mclk_pwrmgt_cntl;
+	u32 dll_cntl = pi->clk_regs.rv770.dll_cntl;
+	struct atom_clock_dividers dividers;
+	u32 reference_clock = rdev->clock.mpll.reference_freq;
+	u32 clkf, clkfrac;
+	u32 postdiv_yclk;
+	u32 ibias;
+	int ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
+					     memory_clock, false, &dividers);
+	if (ret)
+		return ret;
+
+	if ((dividers.ref_div < 1) || (dividers.ref_div > 5))
+		return -EINVAL;
+
+	rv770_calculate_fractional_mpll_feedback_divider(memory_clock, reference_clock,
+							 pi->mem_gddr5,
+							 &dividers, &clkf, &clkfrac);
+
+	ret = rv770_encode_yclk_post_div(dividers.post_div, &postdiv_yclk);
+	if (ret)
+		return ret;
+
+	ibias = rv770_map_clkf_to_ibias(rdev, clkf);
+
+	mpll_ad_func_cntl &= ~(CLKR_MASK |
+			       YCLK_POST_DIV_MASK |
+			       CLKF_MASK |
+			       CLKFRAC_MASK |
+			       IBIAS_MASK);
+	mpll_ad_func_cntl |= CLKR(encoded_reference_dividers[dividers.ref_div - 1]);
+	mpll_ad_func_cntl |= YCLK_POST_DIV(postdiv_yclk);
+	mpll_ad_func_cntl |= CLKF(clkf);
+	mpll_ad_func_cntl |= CLKFRAC(clkfrac);
+	mpll_ad_func_cntl |= IBIAS(ibias);
+
+	if (dividers.vco_mode)
+		mpll_ad_func_cntl_2 |= VCO_MODE;
+	else
+		mpll_ad_func_cntl_2 &= ~VCO_MODE;
+
+	if (pi->mem_gddr5) {
+		rv770_calculate_fractional_mpll_feedback_divider(memory_clock,
+								 reference_clock,
+								 pi->mem_gddr5,
+								 &dividers, &clkf, &clkfrac);
+
+		ibias = rv770_map_clkf_to_ibias(rdev, clkf);
+
+		ret = rv770_encode_yclk_post_div(dividers.post_div, &postdiv_yclk);
+		if (ret)
+			return ret;
+
+		mpll_dq_func_cntl &= ~(CLKR_MASK |
+				       YCLK_POST_DIV_MASK |
+				       CLKF_MASK |
+				       CLKFRAC_MASK |
+				       IBIAS_MASK);
+		mpll_dq_func_cntl |= CLKR(encoded_reference_dividers[dividers.ref_div - 1]);
+		mpll_dq_func_cntl |= YCLK_POST_DIV(postdiv_yclk);
+		mpll_dq_func_cntl |= CLKF(clkf);
+		mpll_dq_func_cntl |= CLKFRAC(clkfrac);
+		mpll_dq_func_cntl |= IBIAS(ibias);
+
+		if (dividers.vco_mode)
+			mpll_dq_func_cntl_2 |= VCO_MODE;
+		else
+			mpll_dq_func_cntl_2 &= ~VCO_MODE;
+	}
+
+	mclk->mclk770.mclk_value = cpu_to_be32(memory_clock);
+	mclk->mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
+	mclk->mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
+	mclk->mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
+	mclk->mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
+	mclk->mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	mclk->mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
+
+	return 0;
+}
+
+static int rv770_populate_sclk_value(struct radeon_device *rdev,
+				     u32 engine_clock,
+				     RV770_SMC_SCLK_VALUE *sclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct atom_clock_dividers dividers;
+	u32 spll_func_cntl =
+		pi->clk_regs.rv770.cg_spll_func_cntl;
+	u32 spll_func_cntl_2 =
+		pi->clk_regs.rv770.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3 =
+		pi->clk_regs.rv770.cg_spll_func_cntl_3;
+	u32 cg_spll_spread_spectrum =
+		pi->clk_regs.rv770.cg_spll_spread_spectrum;
+	u32 cg_spll_spread_spectrum_2 =
+		pi->clk_regs.rv770.cg_spll_spread_spectrum_2;
+	u64 tmp;
+	u32 reference_clock = rdev->clock.spll.reference_freq;
+	u32 reference_divider, post_divider;
+	u32 fbdiv;
+	int ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     engine_clock, false, &dividers);
+	if (ret)
+		return ret;
+
+	reference_divider = 1 + dividers.ref_div;
+
+	if (dividers.enable_post_div)
+		post_divider = (0x0f & (dividers.post_div >> 4)) + (0x0f & dividers.post_div) + 2;
+	else
+		post_divider = 1;
+
+	tmp = (u64) engine_clock * reference_divider * post_divider * 16384;
+	do_div(tmp, reference_clock);
+	fbdiv = (u32) tmp;
+
+	if (dividers.enable_post_div)
+		spll_func_cntl |= SPLL_DIVEN;
+	else
+		spll_func_cntl &= ~SPLL_DIVEN;
+	spll_func_cntl &= ~(SPLL_HILEN_MASK | SPLL_LOLEN_MASK | SPLL_REF_DIV_MASK);
+	spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
+	spll_func_cntl |= SPLL_HILEN((dividers.post_div >> 4) & 0xf);
+	spll_func_cntl |= SPLL_LOLEN(dividers.post_div & 0xf);
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(2);
+
+	spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
+	spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
+	spll_func_cntl_3 |= SPLL_DITHEN;
+
+	if (pi->sclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 vco_freq = engine_clock * post_divider;
+
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+						     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
+			u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
+			u32 clk_v = ss.percentage * fbdiv / (clk_s * 10000);
+
+			cg_spll_spread_spectrum &= ~CLKS_MASK;
+			cg_spll_spread_spectrum |= CLKS(clk_s);
+			cg_spll_spread_spectrum |= SSEN;
+
+			cg_spll_spread_spectrum_2 &= ~CLKV_MASK;
+			cg_spll_spread_spectrum_2 |= CLKV(clk_v);
+		}
+	}
+
+	sclk->sclk_value = cpu_to_be32(engine_clock);
+	sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
+	sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
+	sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
+	sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum);
+	sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2);
+
+	return 0;
+}
+
+int rv770_populate_vddc_value(struct radeon_device *rdev, u16 vddc,
+			      RV770_SMC_VOLTAGE_VALUE *voltage)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	int i;
+
+	if (!pi->voltage_control) {
+		voltage->index = 0;
+		voltage->value = 0;
+		return 0;
+	}
+
+	for (i = 0; i < pi->valid_vddc_entries; i++) {
+		if (vddc <= pi->vddc_table[i].vddc) {
+			voltage->index = pi->vddc_table[i].vddc_index;
+			voltage->value = cpu_to_be16(vddc);
+			break;
+		}
+	}
+
+	if (i == pi->valid_vddc_entries)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rv770_populate_mvdd_value(struct radeon_device *rdev, u32 mclk,
+			      RV770_SMC_VOLTAGE_VALUE *voltage)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (!pi->mvdd_control) {
+		voltage->index = MVDD_HIGH_INDEX;
+		voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
+		return 0;
+	}
+
+	if (mclk <= pi->mvdd_split_frequency) {
+		voltage->index = MVDD_LOW_INDEX;
+		voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
+	} else {
+		voltage->index = MVDD_HIGH_INDEX;
+		voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
+	}
+
+	return 0;
+}
+
+static int rv770_convert_power_level_to_smc(struct radeon_device *rdev,
+					    struct rv7xx_pl *pl,
+					    RV770_SMC_HW_PERFORMANCE_LEVEL *level,
+					    u8 watermark_level)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	int ret;
+
+	level->gen2PCIE = pi->pcie_gen2 ?
+		((pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0) : 0;
+	level->gen2XSP  = (pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0;
+	level->backbias = (pl->flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ? 1 : 0;
+	level->displayWatermark = watermark_level;
+
+	if (rdev->family == CHIP_RV740)
+		ret = rv740_populate_sclk_value(rdev, pl->sclk,
+						&level->sclk);
+	else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		ret = rv730_populate_sclk_value(rdev, pl->sclk,
+						&level->sclk);
+	else
+		ret = rv770_populate_sclk_value(rdev, pl->sclk,
+						&level->sclk);
+	if (ret)
+		return ret;
+
+	if (rdev->family == CHIP_RV740) {
+		if (pi->mem_gddr5) {
+			if (pl->mclk <= pi->mclk_strobe_mode_threshold)
+				level->strobeMode =
+					rv740_get_mclk_frequency_ratio(pl->mclk) | 0x10;
+			else
+				level->strobeMode = 0;
+
+			if (pl->mclk > pi->mclk_edc_enable_threshold)
+				level->mcFlags = SMC_MC_EDC_RD_FLAG | SMC_MC_EDC_WR_FLAG;
+			else
+				level->mcFlags =  0;
+		}
+		ret = rv740_populate_mclk_value(rdev, pl->sclk,
+						pl->mclk, &level->mclk);
+	} else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		ret = rv730_populate_mclk_value(rdev, pl->sclk,
+						pl->mclk, &level->mclk);
+	else
+		ret = rv770_populate_mclk_value(rdev, pl->sclk,
+						pl->mclk, &level->mclk);
+	if (ret)
+		return ret;
+
+	ret = rv770_populate_vddc_value(rdev, pl->vddc,
+					&level->vddc);
+	if (ret)
+		return ret;
+
+	ret = rv770_populate_mvdd_value(rdev, pl->mclk, &level->mvdd);
+
+	return ret;
+}
+
+static int rv770_convert_power_state_to_smc(struct radeon_device *rdev,
+					    struct radeon_ps *radeon_state,
+					    RV770_SMC_SWSTATE *smc_state)
+{
+	struct rv7xx_ps *state = rv770_get_ps(radeon_state);
+	int ret;
+
+	if (!(radeon_state->caps & ATOM_PPLIB_DISALLOW_ON_DC))
+		smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
+
+	ret = rv770_convert_power_level_to_smc(rdev,
+					       &state->low,
+					       &smc_state->levels[0],
+					       PPSMC_DISPLAY_WATERMARK_LOW);
+	if (ret)
+		return ret;
+
+	ret = rv770_convert_power_level_to_smc(rdev,
+					       &state->medium,
+					       &smc_state->levels[1],
+					       PPSMC_DISPLAY_WATERMARK_LOW);
+	if (ret)
+		return ret;
+
+	ret = rv770_convert_power_level_to_smc(rdev,
+					       &state->high,
+					       &smc_state->levels[2],
+					       PPSMC_DISPLAY_WATERMARK_HIGH);
+	if (ret)
+		return ret;
+
+	smc_state->levels[0].arbValue = MC_CG_ARB_FREQ_F1;
+	smc_state->levels[1].arbValue = MC_CG_ARB_FREQ_F2;
+	smc_state->levels[2].arbValue = MC_CG_ARB_FREQ_F3;
+
+	smc_state->levels[0].seqValue = rv770_get_seq_value(rdev,
+							    &state->low);
+	smc_state->levels[1].seqValue = rv770_get_seq_value(rdev,
+							    &state->medium);
+	smc_state->levels[2].seqValue = rv770_get_seq_value(rdev,
+							    &state->high);
+
+	rv770_populate_smc_sp(rdev, radeon_state, smc_state);
+
+	return rv770_populate_smc_t(rdev, radeon_state, smc_state);
+
+}
+
+u32 rv770_calculate_memory_refresh_rate(struct radeon_device *rdev,
+					u32 engine_clock)
+{
+	u32 dram_rows;
+	u32 dram_refresh_rate;
+	u32 mc_arb_rfsh_rate;
+	u32 tmp;
+
+	tmp = (RREG32(MC_ARB_RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
+	dram_rows = 1 << (tmp + 10);
+	tmp = RREG32(MC_SEQ_MISC0) & 3;
+	dram_refresh_rate = 1 << (tmp + 3);
+	mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64;
+
+	return mc_arb_rfsh_rate;
+}
+
+static void rv770_program_memory_timing_parameters(struct radeon_device *rdev,
+						   struct radeon_ps *radeon_state)
+{
+	struct rv7xx_ps *state = rv770_get_ps(radeon_state);
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 sqm_ratio;
+	u32 arb_refresh_rate;
+	u32 high_clock;
+
+	if (state->high.sclk < (state->low.sclk * 0xFF / 0x40))
+		high_clock = state->high.sclk;
+	else
+		high_clock = (state->low.sclk * 0xFF / 0x40);
+
+	radeon_atom_set_engine_dram_timings(rdev, high_clock,
+					    state->high.mclk);
+
+	sqm_ratio =
+		STATE0(64 * high_clock / pi->boot_sclk) |
+		STATE1(64 * high_clock / state->low.sclk) |
+		STATE2(64 * high_clock / state->medium.sclk) |
+		STATE3(64 * high_clock / state->high.sclk);
+	WREG32(MC_ARB_SQM_RATIO, sqm_ratio);
+
+	arb_refresh_rate =
+		POWERMODE0(rv770_calculate_memory_refresh_rate(rdev, pi->boot_sclk)) |
+		POWERMODE1(rv770_calculate_memory_refresh_rate(rdev, state->low.sclk)) |
+		POWERMODE2(rv770_calculate_memory_refresh_rate(rdev, state->medium.sclk)) |
+		POWERMODE3(rv770_calculate_memory_refresh_rate(rdev, state->high.sclk));
+	WREG32(MC_ARB_RFSH_RATE, arb_refresh_rate);
+}
+
+void rv770_enable_backbias(struct radeon_device *rdev,
+			   bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, BACKBIAS_PAD_EN, ~BACKBIAS_PAD_EN);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~(BACKBIAS_VALUE | BACKBIAS_PAD_EN));
+}
+
+static void rv770_enable_spread_spectrum(struct radeon_device *rdev,
+					 bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (enable) {
+		if (pi->sclk_ss)
+			WREG32_P(GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, ~DYN_SPREAD_SPECTRUM_EN);
+
+		if (pi->mclk_ss) {
+			if (rdev->family == CHIP_RV740)
+				rv740_enable_mclk_spread_spectrum(rdev, true);
+		}
+	} else {
+		WREG32_P(CG_SPLL_SPREAD_SPECTRUM, 0, ~SSEN);
+
+		WREG32_P(GENERAL_PWRMGT, 0, ~DYN_SPREAD_SPECTRUM_EN);
+
+		WREG32_P(CG_MPLL_SPREAD_SPECTRUM, 0, ~SSEN);
+
+		if (rdev->family == CHIP_RV740)
+			rv740_enable_mclk_spread_spectrum(rdev, false);
+	}
+}
+
+static void rv770_program_mpll_timing_parameters(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if ((rdev->family == CHIP_RV770) && !pi->mem_gddr5) {
+		WREG32(MPLL_TIME,
+		       (MPLL_LOCK_TIME(R600_MPLLLOCKTIME_DFLT * pi->ref_div) |
+			MPLL_RESET_TIME(R600_MPLLRESETTIME_DFLT)));
+	}
+}
+
+void rv770_setup_bsp(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 xclk = radeon_get_xclk(rdev);
+
+	r600_calculate_u_and_p(pi->asi,
+			       xclk,
+			       16,
+			       &pi->bsp,
+			       &pi->bsu);
+
+	r600_calculate_u_and_p(pi->pasi,
+			       xclk,
+			       16,
+			       &pi->pbsp,
+			       &pi->pbsu);
+
+	pi->dsp = BSP(pi->bsp) | BSU(pi->bsu);
+	pi->psp = BSP(pi->pbsp) | BSU(pi->pbsu);
+
+	WREG32(CG_BSP, pi->dsp);
+
+}
+
+void rv770_program_git(struct radeon_device *rdev)
+{
+	WREG32_P(CG_GIT, CG_GICST(R600_GICST_DFLT), ~CG_GICST_MASK);
+}
+
+void rv770_program_tp(struct radeon_device *rdev)
+{
+	int i;
+	enum r600_td td = R600_TD_DFLT;
+
+	for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)
+		WREG32(CG_FFCT_0 + (i * 4), (UTC_0(r600_utc[i]) | DTC_0(r600_dtc[i])));
+
+	if (td == R600_TD_AUTO)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
+	else
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
+	if (td == R600_TD_UP)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
+	if (td == R600_TD_DOWN)
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
+}
+
+void rv770_program_tpp(struct radeon_device *rdev)
+{
+	WREG32(CG_TPC, R600_TPC_DFLT);
+}
+
+void rv770_program_sstp(struct radeon_device *rdev)
+{
+	WREG32(CG_SSP, (SSTU(R600_SSTU_DFLT) | SST(R600_SST_DFLT)));
+}
+
+void rv770_program_engine_speed_parameters(struct radeon_device *rdev)
+{
+	WREG32_P(SPLL_CNTL_MODE, SPLL_DIV_SYNC, ~SPLL_DIV_SYNC);
+}
+
+static void rv770_enable_display_gap(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
+
+	tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
+	tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE) |
+		DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE));
+	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
+}
+
+void rv770_program_vc(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	WREG32(CG_FTV, pi->vrc);
+}
+
+void rv770_clear_vc(struct radeon_device *rdev)
+{
+	WREG32(CG_FTV, 0);
+}
+
+int rv770_upload_firmware(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	int ret;
+
+	rv770_reset_smc(rdev);
+	rv770_stop_smc_clock(rdev);
+
+	ret = rv770_load_smc_ucode(rdev, pi->sram_end);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int rv770_populate_smc_acpi_state(struct radeon_device *rdev,
+					 RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	u32 mpll_ad_func_cntl =
+		pi->clk_regs.rv770.mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2 =
+		pi->clk_regs.rv770.mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl =
+		pi->clk_regs.rv770.mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2 =
+		pi->clk_regs.rv770.mpll_dq_func_cntl_2;
+	u32 spll_func_cntl =
+		pi->clk_regs.rv770.cg_spll_func_cntl;
+	u32 spll_func_cntl_2 =
+		pi->clk_regs.rv770.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3 =
+		pi->clk_regs.rv770.cg_spll_func_cntl_3;
+	u32 mclk_pwrmgt_cntl;
+	u32 dll_cntl;
+
+	table->ACPIState = table->initialState;
+
+	table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
+
+	if (pi->acpi_vddc) {
+		rv770_populate_vddc_value(rdev, pi->acpi_vddc,
+					  &table->ACPIState.levels[0].vddc);
+		if (pi->pcie_gen2) {
+			if (pi->acpi_pcie_gen2)
+				table->ACPIState.levels[0].gen2PCIE = 1;
+			else
+				table->ACPIState.levels[0].gen2PCIE = 0;
+		} else
+			table->ACPIState.levels[0].gen2PCIE = 0;
+		if (pi->acpi_pcie_gen2)
+			table->ACPIState.levels[0].gen2XSP = 1;
+		else
+			table->ACPIState.levels[0].gen2XSP = 0;
+	} else {
+		rv770_populate_vddc_value(rdev, pi->min_vddc_in_table,
+					  &table->ACPIState.levels[0].vddc);
+		table->ACPIState.levels[0].gen2PCIE = 0;
+	}
+
+
+	mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
+
+	mpll_dq_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
+
+	mclk_pwrmgt_cntl = (MRDCKA0_RESET |
+			    MRDCKA1_RESET |
+			    MRDCKB0_RESET |
+			    MRDCKB1_RESET |
+			    MRDCKC0_RESET |
+			    MRDCKC1_RESET |
+			    MRDCKD0_RESET |
+			    MRDCKD1_RESET);
+
+	dll_cntl = 0xff000000;
+
+	spll_func_cntl |= SPLL_RESET | SPLL_SLEEP | SPLL_BYPASS_EN;
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(4);
+
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
+	table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
+
+	table->ACPIState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	table->ACPIState.levels[0].mclk.mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
+
+	table->ACPIState.levels[0].mclk.mclk770.mclk_value = 0;
+
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
+
+	table->ACPIState.levels[0].sclk.sclk_value = 0;
+
+	rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
+
+	table->ACPIState.levels[1] = table->ACPIState.levels[0];
+	table->ACPIState.levels[2] = table->ACPIState.levels[0];
+
+	return 0;
+}
+
+int rv770_populate_initial_mvdd_value(struct radeon_device *rdev,
+				      RV770_SMC_VOLTAGE_VALUE *voltage)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if ((pi->s0_vid_lower_smio_cntl & pi->mvdd_mask_low) ==
+	     (pi->mvdd_low_smio[MVDD_LOW_INDEX] & pi->mvdd_mask_low) ) {
+		voltage->index = MVDD_LOW_INDEX;
+		voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
+	} else {
+		voltage->index = MVDD_HIGH_INDEX;
+		voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
+	}
+
+	return 0;
+}
+
+static int rv770_populate_smc_initial_state(struct radeon_device *rdev,
+					    struct radeon_ps *radeon_state,
+					    RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_ps *initial_state = rv770_get_ps(radeon_state);
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 a_t;
+
+	table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl);
+	table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl_2);
+	table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl);
+	table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl_2);
+	table->initialState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.mclk_pwrmgt_cntl);
+	table->initialState.levels[0].mclk.mclk770.vDLL_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.dll_cntl);
+
+	table->initialState.levels[0].mclk.mclk770.vMPLL_SS =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_ss1);
+	table->initialState.levels[0].mclk.mclk770.vMPLL_SS2 =
+		cpu_to_be32(pi->clk_regs.rv770.mpll_ss2);
+
+	table->initialState.levels[0].mclk.mclk770.mclk_value =
+		cpu_to_be32(initial_state->low.mclk);
+
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_2);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_3);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =
+		cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum_2);
+
+	table->initialState.levels[0].sclk.sclk_value =
+		cpu_to_be32(initial_state->low.sclk);
+
+	table->initialState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
+
+	table->initialState.levels[0].seqValue =
+		rv770_get_seq_value(rdev, &initial_state->low);
+
+	rv770_populate_vddc_value(rdev,
+				  initial_state->low.vddc,
+				  &table->initialState.levels[0].vddc);
+	rv770_populate_initial_mvdd_value(rdev,
+					  &table->initialState.levels[0].mvdd);
+
+	a_t = CG_R(0xffff) | CG_L(0);
+	table->initialState.levels[0].aT = cpu_to_be32(a_t);
+
+	table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
+
+	if (pi->boot_in_gen2)
+		table->initialState.levels[0].gen2PCIE = 1;
+	else
+		table->initialState.levels[0].gen2PCIE = 0;
+	if (initial_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
+		table->initialState.levels[0].gen2XSP = 1;
+	else
+		table->initialState.levels[0].gen2XSP = 0;
+
+	if (rdev->family == CHIP_RV740) {
+		if (pi->mem_gddr5) {
+			if (initial_state->low.mclk <= pi->mclk_strobe_mode_threshold)
+				table->initialState.levels[0].strobeMode =
+					rv740_get_mclk_frequency_ratio(initial_state->low.mclk) | 0x10;
+			else
+				table->initialState.levels[0].strobeMode = 0;
+
+			if (initial_state->low.mclk >= pi->mclk_edc_enable_threshold)
+				table->initialState.levels[0].mcFlags = SMC_MC_EDC_RD_FLAG | SMC_MC_EDC_WR_FLAG;
+			else
+				table->initialState.levels[0].mcFlags =  0;
+		}
+	}
+
+	table->initialState.levels[1] = table->initialState.levels[0];
+	table->initialState.levels[2] = table->initialState.levels[0];
+
+	table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
+
+	return 0;
+}
+
+static int rv770_populate_smc_vddc_table(struct radeon_device *rdev,
+					 RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	int i;
+
+	for (i = 0; i < pi->valid_vddc_entries; i++) {
+		table->highSMIO[pi->vddc_table[i].vddc_index] =
+			pi->vddc_table[i].high_smio;
+		table->lowSMIO[pi->vddc_table[i].vddc_index] =
+			cpu_to_be32(pi->vddc_table[i].low_smio);
+	}
+
+	table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_VDDC] = 0;
+	table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_VDDC] =
+		cpu_to_be32(pi->vddc_mask_low);
+
+	for (i = 0;
+	     ((i < pi->valid_vddc_entries) &&
+	      (pi->max_vddc_in_table >
+	       pi->vddc_table[i].vddc));
+	     i++);
+
+	table->maxVDDCIndexInPPTable =
+		pi->vddc_table[i].vddc_index;
+
+	return 0;
+}
+
+static int rv770_populate_smc_mvdd_table(struct radeon_device *rdev,
+					 RV770_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (pi->mvdd_control) {
+		table->lowSMIO[MVDD_HIGH_INDEX] |=
+			cpu_to_be32(pi->mvdd_low_smio[MVDD_HIGH_INDEX]);
+		table->lowSMIO[MVDD_LOW_INDEX] |=
+			cpu_to_be32(pi->mvdd_low_smio[MVDD_LOW_INDEX]);
+
+		table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_MVDD] = 0;
+		table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_MVDD] =
+			cpu_to_be32(pi->mvdd_mask_low);
+	}
+
+	return 0;
+}
+
+static int rv770_init_smc_table(struct radeon_device *rdev,
+				struct radeon_ps *radeon_boot_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state);
+	RV770_SMC_STATETABLE *table = &pi->smc_statetable;
+	int ret;
+
+	memset(table, 0, sizeof(RV770_SMC_STATETABLE));
+
+	pi->boot_sclk = boot_state->low.sclk;
+
+	rv770_populate_smc_vddc_table(rdev, table);
+	rv770_populate_smc_mvdd_table(rdev, table);
+
+	switch (rdev->pm.int_thermal_type) {
+        case THERMAL_TYPE_RV770:
+        case THERMAL_TYPE_ADT7473_WITH_INTERNAL:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
+		break;
+        case THERMAL_TYPE_NONE:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
+		break;
+        case THERMAL_TYPE_EXTERNAL_GPIO:
+        default:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
+		break;
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC) {
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
+
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_DONT_WAIT_FOR_VBLANK_ON_ALERT)
+			table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK;
+
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_GOTO_BOOT_ON_ALERT)
+			table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE;
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
+
+	if (pi->mem_gddr5)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
+
+	if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		ret = rv730_populate_smc_initial_state(rdev, radeon_boot_state, table);
+	else
+		ret = rv770_populate_smc_initial_state(rdev, radeon_boot_state, table);
+	if (ret)
+		return ret;
+
+	if (rdev->family == CHIP_RV740)
+		ret = rv740_populate_smc_acpi_state(rdev, table);
+	else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		ret = rv730_populate_smc_acpi_state(rdev, table);
+	else
+		ret = rv770_populate_smc_acpi_state(rdev, table);
+	if (ret)
+		return ret;
+
+	table->driverState = table->initialState;
+
+	return rv770_copy_bytes_to_smc(rdev,
+				       pi->state_table_start,
+				       (const u8 *)table,
+				       sizeof(RV770_SMC_STATETABLE),
+				       pi->sram_end);
+}
+
+static int rv770_construct_vddc_table(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u16 min, max, step;
+	u32 steps = 0;
+	u8 vddc_index = 0;
+	u32 i;
+
+	radeon_atom_get_min_voltage(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &min);
+	radeon_atom_get_max_voltage(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &max);
+	radeon_atom_get_voltage_step(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &step);
+
+	steps = (max - min) / step + 1;
+
+	if (steps > MAX_NO_VREG_STEPS)
+		return -EINVAL;
+
+	for (i = 0; i < steps; i++) {
+		u32 gpio_pins, gpio_mask;
+
+		pi->vddc_table[i].vddc = (u16)(min + i * step);
+		radeon_atom_get_voltage_gpio_settings(rdev,
+						      pi->vddc_table[i].vddc,
+						      SET_VOLTAGE_TYPE_ASIC_VDDC,
+						      &gpio_pins, &gpio_mask);
+		pi->vddc_table[i].low_smio = gpio_pins & gpio_mask;
+		pi->vddc_table[i].high_smio = 0;
+		pi->vddc_mask_low = gpio_mask;
+		if (i > 0) {
+			if ((pi->vddc_table[i].low_smio !=
+			     pi->vddc_table[i - 1].low_smio ) ||
+			     (pi->vddc_table[i].high_smio !=
+			      pi->vddc_table[i - 1].high_smio))
+				vddc_index++;
+		}
+		pi->vddc_table[i].vddc_index = vddc_index;
+	}
+
+	pi->valid_vddc_entries = (u8)steps;
+
+	return 0;
+}
+
+static u32 rv770_get_mclk_split_point(struct atom_memory_info *memory_info)
+{
+	if (memory_info->mem_type == MEM_TYPE_GDDR3)
+		return 30000;
+
+	return 0;
+}
+
+static int rv770_get_mvdd_pin_configuration(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 gpio_pins, gpio_mask;
+
+	radeon_atom_get_voltage_gpio_settings(rdev,
+					      MVDD_HIGH_VALUE, SET_VOLTAGE_TYPE_ASIC_MVDDC,
+					      &gpio_pins, &gpio_mask);
+	pi->mvdd_mask_low = gpio_mask;
+	pi->mvdd_low_smio[MVDD_HIGH_INDEX] =
+		gpio_pins & gpio_mask;
+
+	radeon_atom_get_voltage_gpio_settings(rdev,
+					      MVDD_LOW_VALUE, SET_VOLTAGE_TYPE_ASIC_MVDDC,
+					      &gpio_pins, &gpio_mask);
+	pi->mvdd_low_smio[MVDD_LOW_INDEX] =
+		gpio_pins & gpio_mask;
+
+	return 0;
+}
+
+u8 rv770_get_memory_module_index(struct radeon_device *rdev)
+{
+	return (u8) ((RREG32(BIOS_SCRATCH_4) >> 16) & 0xff);
+}
+
+static int rv770_get_mvdd_configuration(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u8 memory_module_index;
+	struct atom_memory_info memory_info;
+
+	memory_module_index = rv770_get_memory_module_index(rdev);
+
+	if (radeon_atom_get_memory_info(rdev, memory_module_index, &memory_info)) {
+		pi->mvdd_control = false;
+		return 0;
+	}
+
+	pi->mvdd_split_frequency =
+		rv770_get_mclk_split_point(&memory_info);
+
+	if (pi->mvdd_split_frequency == 0) {
+		pi->mvdd_control = false;
+		return 0;
+	}
+
+	return rv770_get_mvdd_pin_configuration(rdev);
+}
+
+void rv770_enable_voltage_control(struct radeon_device *rdev,
+				  bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, VOLT_PWRMGT_EN, ~VOLT_PWRMGT_EN);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~VOLT_PWRMGT_EN);
+}
+
+static void rv770_program_display_gap(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
+
+	tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
+	if (rdev->pm.dpm.new_active_crtcs & 1) {
+		tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
+		tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
+	} else if (rdev->pm.dpm.new_active_crtcs & 2) {
+		tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
+		tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
+	} else {
+		tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
+		tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
+	}
+	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
+}
+
+static void rv770_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
+					   bool enable)
+{
+	rv770_enable_bif_dynamic_pcie_gen2(rdev, enable);
+
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
+}
+
+static void r7xx_program_memory_timing_parameters(struct radeon_device *rdev,
+						  struct radeon_ps *radeon_new_state)
+{
+	if ((rdev->family == CHIP_RV730) ||
+	    (rdev->family == CHIP_RV710) ||
+	    (rdev->family == CHIP_RV740))
+		rv730_program_memory_timing_parameters(rdev, radeon_new_state);
+	else
+		rv770_program_memory_timing_parameters(rdev, radeon_new_state);
+}
+
+static int rv770_upload_sw_state(struct radeon_device *rdev,
+				 struct radeon_ps *radeon_new_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u16 address = pi->state_table_start +
+		offsetof(RV770_SMC_STATETABLE, driverState);
+	RV770_SMC_SWSTATE state = { 0 };
+	int ret;
+
+	ret = rv770_convert_power_state_to_smc(rdev, radeon_new_state, &state);
+	if (ret)
+		return ret;
+
+	return rv770_copy_bytes_to_smc(rdev, address, (const u8 *)&state,
+				       sizeof(RV770_SMC_SWSTATE),
+				       pi->sram_end);
+}
+
+int rv770_halt_smc(struct radeon_device *rdev)
+{
+	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_Halt) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	if (rv770_wait_for_smc_inactive(rdev) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rv770_resume_smc(struct radeon_device *rdev)
+{
+	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_Resume) != PPSMC_Result_OK)
+		return -EINVAL;
+	return 0;
+}
+
+int rv770_set_sw_state(struct radeon_device *rdev)
+{
+	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToSwState) != PPSMC_Result_OK)
+		return -EINVAL;
+	return 0;
+}
+
+int rv770_set_boot_state(struct radeon_device *rdev)
+{
+	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) != PPSMC_Result_OK)
+		return -EINVAL;
+	return 0;
+}
+
+void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
+					      struct radeon_ps *new_ps,
+					      struct radeon_ps *old_ps)
+{
+	struct rv7xx_ps *new_state = rv770_get_ps(new_ps);
+	struct rv7xx_ps *current_state = rv770_get_ps(old_ps);
+
+	if ((new_ps->vclk == old_ps->vclk) &&
+	    (new_ps->dclk == old_ps->dclk))
+		return;
+
+	if (new_state->high.sclk >= current_state->high.sclk)
+		return;
+
+	radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
+}
+
+void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
+					     struct radeon_ps *new_ps,
+					     struct radeon_ps *old_ps)
+{
+	struct rv7xx_ps *new_state = rv770_get_ps(new_ps);
+	struct rv7xx_ps *current_state = rv770_get_ps(old_ps);
+
+	if ((new_ps->vclk == old_ps->vclk) &&
+	    (new_ps->dclk == old_ps->dclk))
+		return;
+
+	if (new_state->high.sclk < current_state->high.sclk)
+		return;
+
+	radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
+}
+
+int rv770_restrict_performance_levels_before_switch(struct radeon_device *rdev)
+{
+	if (rv770_send_msg_to_smc(rdev, (PPSMC_Msg)(PPSMC_MSG_NoForcedLevel)) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	if (rv770_send_msg_to_smc(rdev, (PPSMC_Msg)(PPSMC_MSG_TwoLevelsDisabled)) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+int rv770_dpm_force_performance_level(struct radeon_device *rdev,
+				      enum radeon_dpm_forced_level level)
+{
+	PPSMC_Msg msg;
+
+	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
+		if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ZeroLevelsDisabled) != PPSMC_Result_OK)
+			return -EINVAL;
+		msg = PPSMC_MSG_ForceHigh;
+	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
+		if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
+			return -EINVAL;
+		msg = (PPSMC_Msg)(PPSMC_MSG_TwoLevelsDisabled);
+	} else {
+		if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
+			return -EINVAL;
+		msg = (PPSMC_Msg)(PPSMC_MSG_ZeroLevelsDisabled);
+	}
+
+	if (rv770_send_msg_to_smc(rdev, msg) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	rdev->pm.dpm.forced_level = level;
+
+	return 0;
+}
+
+void r7xx_start_smc(struct radeon_device *rdev)
+{
+	rv770_start_smc(rdev);
+	rv770_start_smc_clock(rdev);
+}
+
+
+void r7xx_stop_smc(struct radeon_device *rdev)
+{
+	rv770_reset_smc(rdev);
+	rv770_stop_smc_clock(rdev);
+}
+
+static void rv770_read_clock_registers(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	pi->clk_regs.rv770.cg_spll_func_cntl =
+		RREG32(CG_SPLL_FUNC_CNTL);
+	pi->clk_regs.rv770.cg_spll_func_cntl_2 =
+		RREG32(CG_SPLL_FUNC_CNTL_2);
+	pi->clk_regs.rv770.cg_spll_func_cntl_3 =
+		RREG32(CG_SPLL_FUNC_CNTL_3);
+	pi->clk_regs.rv770.cg_spll_spread_spectrum =
+		RREG32(CG_SPLL_SPREAD_SPECTRUM);
+	pi->clk_regs.rv770.cg_spll_spread_spectrum_2 =
+		RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
+	pi->clk_regs.rv770.mpll_ad_func_cntl =
+		RREG32(MPLL_AD_FUNC_CNTL);
+	pi->clk_regs.rv770.mpll_ad_func_cntl_2 =
+		RREG32(MPLL_AD_FUNC_CNTL_2);
+	pi->clk_regs.rv770.mpll_dq_func_cntl =
+		RREG32(MPLL_DQ_FUNC_CNTL);
+	pi->clk_regs.rv770.mpll_dq_func_cntl_2 =
+		RREG32(MPLL_DQ_FUNC_CNTL_2);
+	pi->clk_regs.rv770.mclk_pwrmgt_cntl =
+		RREG32(MCLK_PWRMGT_CNTL);
+	pi->clk_regs.rv770.dll_cntl = RREG32(DLL_CNTL);
+}
+
+static void r7xx_read_clock_registers(struct radeon_device *rdev)
+{
+	if (rdev->family == CHIP_RV740)
+		rv740_read_clock_registers(rdev);
+	else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		rv730_read_clock_registers(rdev);
+	else
+		rv770_read_clock_registers(rdev);
+}
+
+void rv770_read_voltage_smio_registers(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	pi->s0_vid_lower_smio_cntl =
+		RREG32(S0_VID_LOWER_SMIO_CNTL);
+}
+
+void rv770_reset_smio_status(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 sw_smio_index, vid_smio_cntl;
+
+	sw_smio_index =
+		(RREG32(GENERAL_PWRMGT) & SW_SMIO_INDEX_MASK) >> SW_SMIO_INDEX_SHIFT;
+	switch (sw_smio_index) {
+        case 3:
+		vid_smio_cntl = RREG32(S3_VID_LOWER_SMIO_CNTL);
+		break;
+        case 2:
+		vid_smio_cntl = RREG32(S2_VID_LOWER_SMIO_CNTL);
+		break;
+        case 1:
+		vid_smio_cntl = RREG32(S1_VID_LOWER_SMIO_CNTL);
+		break;
+        case 0:
+		return;
+        default:
+		vid_smio_cntl = pi->s0_vid_lower_smio_cntl;
+		break;
+	}
+
+	WREG32(S0_VID_LOWER_SMIO_CNTL, vid_smio_cntl);
+	WREG32_P(GENERAL_PWRMGT, SW_SMIO_INDEX(0), ~SW_SMIO_INDEX_MASK);
+}
+
+void rv770_get_memory_type(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 tmp;
+
+	tmp = RREG32(MC_SEQ_MISC0);
+
+	if (((tmp & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT) ==
+	    MC_SEQ_MISC0_GDDR5_VALUE)
+		pi->mem_gddr5 = true;
+	else
+		pi->mem_gddr5 = false;
+
+}
+
+void rv770_get_pcie_gen2_status(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 tmp;
+
+	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+
+	if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+	    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
+		pi->pcie_gen2 = true;
+	else
+		pi->pcie_gen2 = false;
+
+	if (pi->pcie_gen2) {
+		if (tmp & LC_CURRENT_DATA_RATE)
+			pi->boot_in_gen2 = true;
+		else
+			pi->boot_in_gen2 = false;
+	} else
+		pi->boot_in_gen2 = false;
+}
+
+#if 0
+static int rv770_enter_ulp_state(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (pi->gfx_clock_gating) {
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
+		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
+		RREG32(GB_TILING_CONFIG);
+	}
+
+	WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_SwitchToMinimumPower),
+		 ~HOST_SMC_MSG_MASK);
+
+	udelay(7000);
+
+	return 0;
+}
+
+static int rv770_exit_ulp_state(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	int i;
+
+	WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_ResumeFromMinimumPower),
+		 ~HOST_SMC_MSG_MASK);
+
+	udelay(7000);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (((RREG32(SMC_MSG) & HOST_SMC_RESP_MASK) >> HOST_SMC_RESP_SHIFT) == 1)
+			break;
+		udelay(1000);
+	}
+
+	if (pi->gfx_clock_gating)
+		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
+
+	return 0;
+}
+#endif
+
+static void rv770_get_mclk_odt_threshold(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u8 memory_module_index;
+	struct atom_memory_info memory_info;
+
+	pi->mclk_odt_threshold = 0;
+
+	if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710)) {
+		memory_module_index = rv770_get_memory_module_index(rdev);
+
+		if (radeon_atom_get_memory_info(rdev, memory_module_index, &memory_info))
+			return;
+
+		if (memory_info.mem_type == MEM_TYPE_DDR2 ||
+		    memory_info.mem_type == MEM_TYPE_DDR3)
+			pi->mclk_odt_threshold = 30000;
+	}
+}
+
+void rv770_get_max_vddc(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u16 vddc;
+
+	if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc))
+		pi->max_vddc = 0;
+	else
+		pi->max_vddc = vddc;
+}
+
+void rv770_program_response_times(struct radeon_device *rdev)
+{
+	u32 voltage_response_time, backbias_response_time;
+	u32 acpi_delay_time, vbi_time_out;
+	u32 vddc_dly, bb_dly, acpi_dly, vbi_dly;
+	u32 reference_clock;
+
+	voltage_response_time = (u32)rdev->pm.dpm.voltage_response_time;
+	backbias_response_time = (u32)rdev->pm.dpm.backbias_response_time;
+
+	if (voltage_response_time == 0)
+		voltage_response_time = 1000;
+
+	if (backbias_response_time == 0)
+		backbias_response_time = 1000;
+
+	acpi_delay_time = 15000;
+	vbi_time_out = 100000;
+
+	reference_clock = radeon_get_xclk(rdev);
+
+	vddc_dly = (voltage_response_time  * reference_clock) / 1600;
+	bb_dly = (backbias_response_time * reference_clock) / 1600;
+	acpi_dly = (acpi_delay_time * reference_clock) / 1600;
+	vbi_dly = (vbi_time_out * reference_clock) / 1600;
+
+	rv770_write_smc_soft_register(rdev,
+				      RV770_SMC_SOFT_REGISTER_delay_vreg, vddc_dly);
+	rv770_write_smc_soft_register(rdev,
+				      RV770_SMC_SOFT_REGISTER_delay_bbias, bb_dly);
+	rv770_write_smc_soft_register(rdev,
+				      RV770_SMC_SOFT_REGISTER_delay_acpi, acpi_dly);
+	rv770_write_smc_soft_register(rdev,
+				      RV770_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);
+#if 0
+	/* XXX look up hw revision */
+	if (WEKIVA_A21)
+		rv770_write_smc_soft_register(rdev,
+					      RV770_SMC_SOFT_REGISTER_baby_step_timer,
+					      0x10);
+#endif
+}
+
+static void rv770_program_dcodt_before_state_switch(struct radeon_device *rdev,
+						    struct radeon_ps *radeon_new_state,
+						    struct radeon_ps *radeon_current_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct rv7xx_ps *new_state = rv770_get_ps(radeon_new_state);
+	struct rv7xx_ps *current_state = rv770_get_ps(radeon_current_state);
+	bool current_use_dc = false;
+	bool new_use_dc = false;
+
+	if (pi->mclk_odt_threshold == 0)
+		return;
+
+	if (current_state->high.mclk <= pi->mclk_odt_threshold)
+		current_use_dc = true;
+
+	if (new_state->high.mclk <= pi->mclk_odt_threshold)
+		new_use_dc = true;
+
+	if (current_use_dc == new_use_dc)
+		return;
+
+	if (!current_use_dc && new_use_dc)
+		return;
+
+	if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		rv730_program_dcodt(rdev, new_use_dc);
+}
+
+static void rv770_program_dcodt_after_state_switch(struct radeon_device *rdev,
+						   struct radeon_ps *radeon_new_state,
+						   struct radeon_ps *radeon_current_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct rv7xx_ps *new_state = rv770_get_ps(radeon_new_state);
+	struct rv7xx_ps *current_state = rv770_get_ps(radeon_current_state);
+	bool current_use_dc = false;
+	bool new_use_dc = false;
+
+	if (pi->mclk_odt_threshold == 0)
+		return;
+
+	if (current_state->high.mclk <= pi->mclk_odt_threshold)
+		current_use_dc = true;
+
+	if (new_state->high.mclk <= pi->mclk_odt_threshold)
+		new_use_dc = true;
+
+	if (current_use_dc == new_use_dc)
+		return;
+
+	if (current_use_dc && !new_use_dc)
+		return;
+
+	if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		rv730_program_dcodt(rdev, new_use_dc);
+}
+
+static void rv770_retrieve_odt_values(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (pi->mclk_odt_threshold == 0)
+		return;
+
+	if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		rv730_get_odt_values(rdev);
+}
+
+static void rv770_set_dpm_event_sources(struct radeon_device *rdev, u32 sources)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	bool want_thermal_protection;
+	enum radeon_dpm_event_src dpm_event_src;
+
+	switch (sources) {
+        case 0:
+        default:
+		want_thermal_protection = false;
+		break;
+        case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL):
+		want_thermal_protection = true;
+		dpm_event_src = RADEON_DPM_EVENT_SRC_DIGITAL;
+		break;
+
+        case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL):
+		want_thermal_protection = true;
+		dpm_event_src = RADEON_DPM_EVENT_SRC_EXTERNAL;
+		break;
+
+        case ((1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL) |
+	      (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL)):
+		want_thermal_protection = true;
+		dpm_event_src = RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL;
+		break;
+	}
+
+	if (want_thermal_protection) {
+		WREG32_P(CG_THERMAL_CTRL, DPM_EVENT_SRC(dpm_event_src), ~DPM_EVENT_SRC_MASK);
+		if (pi->thermal_protection)
+			WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
+	} else {
+		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
+	}
+}
+
+void rv770_enable_auto_throttle_source(struct radeon_device *rdev,
+				       enum radeon_dpm_auto_throttle_src source,
+				       bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (enable) {
+		if (!(pi->active_auto_throttle_sources & (1 << source))) {
+			pi->active_auto_throttle_sources |= 1 << source;
+			rv770_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
+		}
+	} else {
+		if (pi->active_auto_throttle_sources & (1 << source)) {
+			pi->active_auto_throttle_sources &= ~(1 << source);
+			rv770_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
+		}
+	}
+}
+
+int rv770_set_thermal_temperature_range(struct radeon_device *rdev,
+					int min_temp, int max_temp)
+{
+	int low_temp = 0 * 1000;
+	int high_temp = 255 * 1000;
+
+	if (low_temp < min_temp)
+		low_temp = min_temp;
+	if (high_temp > max_temp)
+		high_temp = max_temp;
+	if (high_temp < low_temp) {
+		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
+		return -EINVAL;
+	}
+
+	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(high_temp / 1000), ~DIG_THERM_INTH_MASK);
+	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(low_temp / 1000), ~DIG_THERM_INTL_MASK);
+	WREG32_P(CG_THERMAL_CTRL, DIG_THERM_DPM(high_temp / 1000), ~DIG_THERM_DPM_MASK);
+
+	rdev->pm.dpm.thermal.min_temp = low_temp;
+	rdev->pm.dpm.thermal.max_temp = high_temp;
+
+	return 0;
+}
+
+int rv770_dpm_enable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+	int ret;
+
+	if (pi->gfx_clock_gating)
+		rv770_restore_cgcg(rdev);
+
+	if (rv770_dpm_enabled(rdev))
+		return -EINVAL;
+
+	if (pi->voltage_control) {
+		rv770_enable_voltage_control(rdev, true);
+		ret = rv770_construct_vddc_table(rdev);
+		if (ret) {
+			DRM_ERROR("rv770_construct_vddc_table failed\n");
+			return ret;
+		}
+	}
+
+	if (pi->dcodt)
+		rv770_retrieve_odt_values(rdev);
+
+	if (pi->mvdd_control) {
+		ret = rv770_get_mvdd_configuration(rdev);
+		if (ret) {
+			DRM_ERROR("rv770_get_mvdd_configuration failed\n");
+			return ret;
+		}
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
+		rv770_enable_backbias(rdev, true);
+
+	rv770_enable_spread_spectrum(rdev, true);
+
+	if (pi->thermal_protection)
+		rv770_enable_thermal_protection(rdev, true);
+
+	rv770_program_mpll_timing_parameters(rdev);
+	rv770_setup_bsp(rdev);
+	rv770_program_git(rdev);
+	rv770_program_tp(rdev);
+	rv770_program_tpp(rdev);
+	rv770_program_sstp(rdev);
+	rv770_program_engine_speed_parameters(rdev);
+	rv770_enable_display_gap(rdev);
+	rv770_program_vc(rdev);
+
+	if (pi->dynamic_pcie_gen2)
+		rv770_enable_dynamic_pcie_gen2(rdev, true);
+
+	ret = rv770_upload_firmware(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_upload_firmware failed\n");
+		return ret;
+	}
+	ret = rv770_init_smc_table(rdev, boot_ps);
+	if (ret) {
+		DRM_ERROR("rv770_init_smc_table failed\n");
+		return ret;
+	}
+
+	rv770_program_response_times(rdev);
+	r7xx_start_smc(rdev);
+
+	if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		rv730_start_dpm(rdev);
+	else
+		rv770_start_dpm(rdev);
+
+	if (pi->gfx_clock_gating)
+		rv770_gfx_clock_gating_enable(rdev, true);
+
+	if (pi->mg_clock_gating)
+		rv770_mg_clock_gating_enable(rdev, true);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		PPSMC_Result result;
+
+		ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+		if (ret)
+			return ret;
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+		result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
+
+		if (result != PPSMC_Result_OK)
+			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
+	}
+
+	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+	return 0;
+}
+
+void rv770_dpm_disable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (!rv770_dpm_enabled(rdev))
+		return;
+
+	rv770_clear_vc(rdev);
+
+	if (pi->thermal_protection)
+		rv770_enable_thermal_protection(rdev, false);
+
+	rv770_enable_spread_spectrum(rdev, false);
+
+	if (pi->dynamic_pcie_gen2)
+		rv770_enable_dynamic_pcie_gen2(rdev, false);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		rdev->irq.dpm_thermal = false;
+		radeon_irq_set(rdev);
+	}
+
+	if (pi->gfx_clock_gating)
+		rv770_gfx_clock_gating_enable(rdev, false);
+
+	if (pi->mg_clock_gating)
+		rv770_mg_clock_gating_enable(rdev, false);
+
+	if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
+		rv730_stop_dpm(rdev);
+	else
+		rv770_stop_dpm(rdev);
+
+	r7xx_stop_smc(rdev);
+	rv770_reset_smio_status(rdev);
+}
+
+int rv770_dpm_set_power_state(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
+	struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;
+	int ret;
+
+	ret = rv770_restrict_performance_levels_before_switch(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_restrict_performance_levels_before_switch failed\n");
+		return ret;
+	}
+	rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+	ret = rv770_halt_smc(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_halt_smc failed\n");
+		return ret;
+	}
+	ret = rv770_upload_sw_state(rdev, new_ps);
+	if (ret) {
+		DRM_ERROR("rv770_upload_sw_state failed\n");
+		return ret;
+	}
+	r7xx_program_memory_timing_parameters(rdev, new_ps);
+	if (pi->dcodt)
+		rv770_program_dcodt_before_state_switch(rdev, new_ps, old_ps);
+	ret = rv770_resume_smc(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_resume_smc failed\n");
+		return ret;
+	}
+	ret = rv770_set_sw_state(rdev);
+	if (ret) {
+		DRM_ERROR("rv770_set_sw_state failed\n");
+		return ret;
+	}
+	if (pi->dcodt)
+		rv770_program_dcodt_after_state_switch(rdev, new_ps, old_ps);
+	rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+
+	ret = rv770_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO);
+	if (ret) {
+		DRM_ERROR("rv770_dpm_force_performance_level failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+void rv770_dpm_reset_asic(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+
+	rv770_restrict_performance_levels_before_switch(rdev);
+	if (pi->dcodt)
+		rv770_program_dcodt_before_state_switch(rdev, boot_ps, boot_ps);
+	rv770_set_boot_state(rdev);
+	if (pi->dcodt)
+		rv770_program_dcodt_after_state_switch(rdev, boot_ps, boot_ps);
+}
+
+void rv770_dpm_setup_asic(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	r7xx_read_clock_registers(rdev);
+	rv770_read_voltage_smio_registers(rdev);
+	rv770_get_memory_type(rdev);
+	if (pi->dcodt)
+		rv770_get_mclk_odt_threshold(rdev);
+	rv770_get_pcie_gen2_status(rdev);
+
+	rv770_enable_acpi_pm(rdev);
+
+	if (radeon_aspm != 0) {
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L0s)
+			rv770_enable_l0s(rdev);
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L1)
+			rv770_enable_l1(rdev);
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1)
+			rv770_enable_pll_sleep_in_l1(rdev);
+	}
+}
+
+void rv770_dpm_display_configuration_changed(struct radeon_device *rdev)
+{
+	rv770_program_display_gap(rdev);
+}
+
+union power_info {
+	struct _ATOM_POWERPLAY_INFO info;
+	struct _ATOM_POWERPLAY_INFO_V2 info_2;
+	struct _ATOM_POWERPLAY_INFO_V3 info_3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
+	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
+	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
+};
+
+union pplib_clock_info {
+	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
+	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
+	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
+	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
+};
+
+union pplib_power_state {
+	struct _ATOM_PPLIB_STATE v1;
+	struct _ATOM_PPLIB_STATE_V2 v2;
+};
+
+static void rv7xx_parse_pplib_non_clock_info(struct radeon_device *rdev,
+					     struct radeon_ps *rps,
+					     struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
+					     u8 table_rev)
+{
+	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
+	rps->class = le16_to_cpu(non_clock_info->usClassification);
+	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
+
+	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
+		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
+		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
+	} else if (r600_is_uvd_state(rps->class, rps->class2)) {
+		rps->vclk = RV770_DEFAULT_VCLK_FREQ;
+		rps->dclk = RV770_DEFAULT_DCLK_FREQ;
+	} else {
+		rps->vclk = 0;
+		rps->dclk = 0;
+	}
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
+		rdev->pm.dpm.boot_ps = rps;
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		rdev->pm.dpm.uvd_ps = rps;
+}
+
+static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev,
+					 struct radeon_ps *rps, int index,
+					 union pplib_clock_info *clock_info)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct rv7xx_ps *ps = rv770_get_ps(rps);
+	u32 sclk, mclk;
+	u16 vddc;
+	struct rv7xx_pl *pl;
+
+	switch (index) {
+	case 0:
+		pl = &ps->low;
+		break;
+	case 1:
+		pl = &ps->medium;
+		break;
+	case 2:
+	default:
+		pl = &ps->high;
+		break;
+	}
+
+	if (rdev->family >= CHIP_CEDAR) {
+		sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
+		sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
+		mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
+		mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
+
+		pl->vddc = le16_to_cpu(clock_info->evergreen.usVDDC);
+		pl->vddci = le16_to_cpu(clock_info->evergreen.usVDDCI);
+		pl->flags = le32_to_cpu(clock_info->evergreen.ulFlags);
+	} else {
+		sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
+		sclk |= clock_info->r600.ucEngineClockHigh << 16;
+		mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);
+		mclk |= clock_info->r600.ucMemoryClockHigh << 16;
+
+		pl->vddc = le16_to_cpu(clock_info->r600.usVDDC);
+		pl->flags = le32_to_cpu(clock_info->r600.ulFlags);
+	}
+
+	pl->mclk = mclk;
+	pl->sclk = sclk;
+
+	/* patch up vddc if necessary */
+	if (pl->vddc == 0xff01) {
+		if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0)
+			pl->vddc = vddc;
+	}
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
+		pi->acpi_vddc = pl->vddc;
+		if (rdev->family >= CHIP_CEDAR)
+			eg_pi->acpi_vddci = pl->vddci;
+		if (ps->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
+			pi->acpi_pcie_gen2 = true;
+		else
+			pi->acpi_pcie_gen2 = false;
+	}
+
+	if (rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) {
+		if (rdev->family >= CHIP_BARTS) {
+			eg_pi->ulv.supported = true;
+			eg_pi->ulv.pl = pl;
+		}
+	}
+
+	if (pi->min_vddc_in_table > pl->vddc)
+		pi->min_vddc_in_table = pl->vddc;
+
+	if (pi->max_vddc_in_table < pl->vddc)
+		pi->max_vddc_in_table = pl->vddc;
+
+	/* patch up boot state */
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
+		u16 vddc, vddci, mvdd;
+		radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
+		pl->mclk = rdev->clock.default_mclk;
+		pl->sclk = rdev->clock.default_sclk;
+		pl->vddc = vddc;
+		pl->vddci = vddci;
+	}
+
+	if (rdev->family >= CHIP_BARTS) {
+		if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
+		    ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
+			rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;
+			rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;
+			rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;
+			rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;
+		}
+	}
+}
+
+int rv7xx_parse_power_table(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
+	union pplib_power_state *power_state;
+	int i, j;
+	union pplib_clock_info *clock_info;
+	union power_info *power_info;
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+        u16 data_offset;
+	u8 frev, crev;
+	struct rv7xx_ps *ps;
+
+	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset))
+		return -EINVAL;
+	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+
+	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
+				  power_info->pplib.ucNumStates, GFP_KERNEL);
+	if (!rdev->pm.dpm.ps)
+		return -ENOMEM;
+	rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
+	rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
+	rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
+
+	for (i = 0; i < power_info->pplib.ucNumStates; i++) {
+		power_state = (union pplib_power_state *)
+			(mode_info->atom_context->bios + data_offset +
+			 le16_to_cpu(power_info->pplib.usStateArrayOffset) +
+			 i * power_info->pplib.ucStateEntrySize);
+		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
+			(mode_info->atom_context->bios + data_offset +
+			 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
+			 (power_state->v1.ucNonClockStateIndex *
+			  power_info->pplib.ucNonClockSize));
+		if (power_info->pplib.ucStateEntrySize - 1) {
+			ps = kzalloc(sizeof(struct rv7xx_ps), GFP_KERNEL);
+			if (ps == NULL) {
+				kfree(rdev->pm.dpm.ps);
+				return -ENOMEM;
+			}
+			rdev->pm.dpm.ps[i].ps_priv = ps;
+			rv7xx_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
+							 non_clock_info,
+							 power_info->pplib.ucNonClockSize);
+			for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
+				clock_info = (union pplib_clock_info *)
+					(mode_info->atom_context->bios + data_offset +
+					 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
+					 (power_state->v1.ucClockStateIndices[j] *
+					  power_info->pplib.ucClockInfoSize));
+				rv7xx_parse_pplib_clock_info(rdev,
+							     &rdev->pm.dpm.ps[i], j,
+							     clock_info);
+			}
+		}
+	}
+	rdev->pm.dpm.num_ps = power_info->pplib.ucNumStates;
+	return 0;
+}
+
+void rv770_get_engine_memory_ss(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct radeon_atom_ss ss;
+
+	pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
+						       ASIC_INTERNAL_ENGINE_SS, 0);
+	pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
+						       ASIC_INTERNAL_MEMORY_SS, 0);
+
+	if (pi->sclk_ss || pi->mclk_ss)
+		pi->dynamic_ss = true;
+	else
+		pi->dynamic_ss = false;
+}
+
+int rv770_dpm_init(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi;
+	struct atom_clock_dividers dividers;
+	int ret;
+
+	pi = kzalloc(sizeof(struct rv7xx_power_info), GFP_KERNEL);
+	if (pi == NULL)
+		return -ENOMEM;
+	rdev->pm.dpm.priv = pi;
+
+	rv770_get_max_vddc(rdev);
+
+	pi->acpi_vddc = 0;
+	pi->min_vddc_in_table = 0;
+	pi->max_vddc_in_table = 0;
+
+	ret = rv7xx_parse_power_table(rdev);
+	if (ret)
+		return ret;
+
+	if (rdev->pm.dpm.voltage_response_time == 0)
+		rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
+	if (rdev->pm.dpm.backbias_response_time == 0)
+		rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     0, false, &dividers);
+	if (ret)
+		pi->ref_div = dividers.ref_div + 1;
+	else
+		pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
+
+	pi->mclk_strobe_mode_threshold = 30000;
+	pi->mclk_edc_enable_threshold = 30000;
+
+	pi->rlp = RV770_RLP_DFLT;
+	pi->rmp = RV770_RMP_DFLT;
+	pi->lhp = RV770_LHP_DFLT;
+	pi->lmp = RV770_LMP_DFLT;
+
+	pi->voltage_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
+
+	pi->mvdd_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
+
+	rv770_get_engine_memory_ss(rdev);
+
+	pi->asi = RV770_ASI_DFLT;
+	pi->pasi = RV770_HASI_DFLT;
+	pi->vrc = RV770_VRC_DFLT;
+
+	pi->power_gating = false;
+
+	pi->gfx_clock_gating = true;
+
+	pi->mg_clock_gating = true;
+	pi->mgcgtssm = true;
+
+	pi->dynamic_pcie_gen2 = true;
+
+	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
+		pi->thermal_protection = true;
+	else
+		pi->thermal_protection = false;
+
+	pi->display_gap = true;
+
+	if (rdev->flags & RADEON_IS_MOBILITY)
+		pi->dcodt = true;
+	else
+		pi->dcodt = false;
+
+	pi->ulps = true;
+
+	pi->mclk_stutter_mode_threshold = 0;
+
+	pi->sram_end = SMC_RAM_END;
+	pi->state_table_start = RV770_SMC_TABLE_ADDRESS;
+	pi->soft_regs_start = RV770_SMC_SOFT_REGISTERS_START;
+
+	return 0;
+}
+
+void rv770_dpm_print_power_state(struct radeon_device *rdev,
+				 struct radeon_ps *rps)
+{
+	struct rv7xx_ps *ps = rv770_get_ps(rps);
+	struct rv7xx_pl *pl;
+
+	r600_dpm_print_class_info(rps->class, rps->class2);
+	r600_dpm_print_cap_info(rps->caps);
+	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+	if (rdev->family >= CHIP_CEDAR) {
+		pl = &ps->low;
+		printk("\t\tpower level 0    sclk: %u mclk: %u vddc: %u vddci: %u\n",
+		       pl->sclk, pl->mclk, pl->vddc, pl->vddci);
+		pl = &ps->medium;
+		printk("\t\tpower level 1    sclk: %u mclk: %u vddc: %u vddci: %u\n",
+		       pl->sclk, pl->mclk, pl->vddc, pl->vddci);
+		pl = &ps->high;
+		printk("\t\tpower level 2    sclk: %u mclk: %u vddc: %u vddci: %u\n",
+		       pl->sclk, pl->mclk, pl->vddc, pl->vddci);
+	} else {
+		pl = &ps->low;
+		printk("\t\tpower level 0    sclk: %u mclk: %u vddc: %u\n",
+		       pl->sclk, pl->mclk, pl->vddc);
+		pl = &ps->medium;
+		printk("\t\tpower level 1    sclk: %u mclk: %u vddc: %u\n",
+		       pl->sclk, pl->mclk, pl->vddc);
+		pl = &ps->high;
+		printk("\t\tpower level 2    sclk: %u mclk: %u vddc: %u\n",
+		       pl->sclk, pl->mclk, pl->vddc);
+	}
+	r600_dpm_print_ps_status(rdev, rps);
+}
+
+void rv770_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						       struct seq_file *m)
+{
+	struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+	struct rv7xx_ps *ps = rv770_get_ps(rps);
+	struct rv7xx_pl *pl;
+	u32 current_index =
+		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
+		CURRENT_PROFILE_INDEX_SHIFT;
+
+	if (current_index > 2) {
+		seq_printf(m, "invalid dpm profile %d\n", current_index);
+	} else {
+		if (current_index == 0)
+			pl = &ps->low;
+		else if (current_index == 1)
+			pl = &ps->medium;
+		else /* current_index == 2 */
+			pl = &ps->high;
+		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+		if (rdev->family >= CHIP_CEDAR) {
+			seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
+				   current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
+		} else {
+			seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u\n",
+				   current_index, pl->sclk, pl->mclk, pl->vddc);
+		}
+	}
+}
+
+void rv770_dpm_fini(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	}
+	kfree(rdev->pm.dpm.ps);
+	kfree(rdev->pm.dpm.priv);
+}
+
+u32 rv770_dpm_get_sclk(struct radeon_device *rdev, bool low)
+{
+	struct rv7xx_ps *requested_state = rv770_get_ps(rdev->pm.dpm.requested_ps);
+
+	if (low)
+		return requested_state->low.sclk;
+	else
+		return requested_state->high.sclk;
+}
+
+u32 rv770_dpm_get_mclk(struct radeon_device *rdev, bool low)
+{
+	struct rv7xx_ps *requested_state = rv770_get_ps(rdev->pm.dpm.requested_ps);
+
+	if (low)
+		return requested_state->low.mclk;
+	else
+		return requested_state->high.mclk;
+}
+
+bool rv770_dpm_vblank_too_short(struct radeon_device *rdev)
+{
+	u32 vblank_time = r600_dpm_get_vblank_time(rdev);
+
+	if (vblank_time < 300)
+		return true;
+	else
+		return false;
+
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __RV770_DPM_H__
+#define __RV770_DPM_H__
+
+#include "rv770_smc.h"
+
+struct rv770_clock_registers {
+	u32 cg_spll_func_cntl;
+	u32 cg_spll_func_cntl_2;
+	u32 cg_spll_func_cntl_3;
+	u32 cg_spll_spread_spectrum;
+	u32 cg_spll_spread_spectrum_2;
+	u32 mpll_ad_func_cntl;
+	u32 mpll_ad_func_cntl_2;
+	u32 mpll_dq_func_cntl;
+	u32 mpll_dq_func_cntl_2;
+	u32 mclk_pwrmgt_cntl;
+	u32 dll_cntl;
+	u32 mpll_ss1;
+	u32 mpll_ss2;
+};
+
+struct rv730_clock_registers {
+	u32 cg_spll_func_cntl;
+	u32 cg_spll_func_cntl_2;
+	u32 cg_spll_func_cntl_3;
+	u32 cg_spll_spread_spectrum;
+	u32 cg_spll_spread_spectrum_2;
+	u32 mclk_pwrmgt_cntl;
+	u32 dll_cntl;
+	u32 mpll_func_cntl;
+	u32 mpll_func_cntl2;
+	u32 mpll_func_cntl3;
+	u32 mpll_ss;
+	u32 mpll_ss2;
+};
+
+union r7xx_clock_registers {
+	struct rv770_clock_registers rv770;
+	struct rv730_clock_registers rv730;
+};
+
+struct vddc_table_entry {
+	u16 vddc;
+	u8 vddc_index;
+	u8 high_smio;
+	u32 low_smio;
+};
+
+#define MAX_NO_OF_MVDD_VALUES 2
+#define MAX_NO_VREG_STEPS 32
+
+struct rv7xx_power_info {
+	/* flags */
+	bool mem_gddr5;
+	bool pcie_gen2;
+	bool dynamic_pcie_gen2;
+	bool acpi_pcie_gen2;
+	bool boot_in_gen2;
+	bool voltage_control; /* vddc */
+	bool mvdd_control;
+	bool sclk_ss;
+	bool mclk_ss;
+	bool dynamic_ss;
+	bool gfx_clock_gating;
+	bool mg_clock_gating;
+	bool mgcgtssm;
+	bool power_gating;
+	bool thermal_protection;
+	bool display_gap;
+	bool dcodt;
+	bool ulps;
+	/* registers */
+	union r7xx_clock_registers clk_regs;
+	u32 s0_vid_lower_smio_cntl;
+	/* voltage */
+	u32 vddc_mask_low;
+	u32 mvdd_mask_low;
+	u32 mvdd_split_frequency;
+	u32 mvdd_low_smio[MAX_NO_OF_MVDD_VALUES];
+	u16 max_vddc;
+	u16 max_vddc_in_table;
+	u16 min_vddc_in_table;
+	struct vddc_table_entry vddc_table[MAX_NO_VREG_STEPS];
+	u8 valid_vddc_entries;
+	/* dc odt */
+	u32 mclk_odt_threshold;
+	u8 odt_value_0[2];
+	u8 odt_value_1[2];
+	/* stored values */
+	u32 boot_sclk;
+	u16 acpi_vddc;
+	u32 ref_div;
+	u32 active_auto_throttle_sources;
+	u32 mclk_stutter_mode_threshold;
+	u32 mclk_strobe_mode_threshold;
+	u32 mclk_edc_enable_threshold;
+	u32 bsp;
+	u32 bsu;
+	u32 pbsp;
+	u32 pbsu;
+	u32 dsp;
+	u32 psp;
+	u32 asi;
+	u32 pasi;
+	u32 vrc;
+	u32 restricted_levels;
+	u32 rlp;
+	u32 rmp;
+	u32 lhp;
+	u32 lmp;
+	/* smc offsets */
+	u16 state_table_start;
+	u16 soft_regs_start;
+	u16 sram_end;
+	/* scratch structs */
+	RV770_SMC_STATETABLE smc_statetable;
+};
+
+struct rv7xx_pl {
+	u32 sclk;
+	u32 mclk;
+	u16 vddc;
+	u16 vddci; /* eg+ only */
+	u32 flags;
+	enum radeon_pcie_gen pcie_gen; /* si+ only */
+};
+
+struct rv7xx_ps {
+	struct rv7xx_pl high;
+	struct rv7xx_pl medium;
+	struct rv7xx_pl low;
+	bool dc_compatible;
+};
+
+#define RV770_RLP_DFLT                                10
+#define RV770_RMP_DFLT                                25
+#define RV770_LHP_DFLT                                25
+#define RV770_LMP_DFLT                                10
+#define RV770_VRC_DFLT                                0x003f
+#define RV770_ASI_DFLT                                1000
+#define RV770_HASI_DFLT                               200000
+#define RV770_MGCGTTLOCAL0_DFLT                       0x00100000
+#define RV7XX_MGCGTTLOCAL0_DFLT                       0
+#define RV770_MGCGTTLOCAL1_DFLT                       0xFFFF0000
+#define RV770_MGCGCGTSSMCTRL_DFLT                     0x55940000
+
+#define MVDD_LOW_INDEX  0
+#define MVDD_HIGH_INDEX 1
+
+#define MVDD_LOW_VALUE  0
+#define MVDD_HIGH_VALUE 0xffff
+
+#define RV770_DEFAULT_VCLK_FREQ  53300 /* 10 khz */
+#define RV770_DEFAULT_DCLK_FREQ  40000 /* 10 khz */
+
+/* rv730/rv710 */
+int rv730_populate_sclk_value(struct radeon_device *rdev,
+			      u32 engine_clock,
+			      RV770_SMC_SCLK_VALUE *sclk);
+int rv730_populate_mclk_value(struct radeon_device *rdev,
+			      u32 engine_clock, u32 memory_clock,
+			      LPRV7XX_SMC_MCLK_VALUE mclk);
+void rv730_read_clock_registers(struct radeon_device *rdev);
+int rv730_populate_smc_acpi_state(struct radeon_device *rdev,
+				  RV770_SMC_STATETABLE *table);
+int rv730_populate_smc_initial_state(struct radeon_device *rdev,
+				     struct radeon_ps *radeon_initial_state,
+				     RV770_SMC_STATETABLE *table);
+void rv730_program_memory_timing_parameters(struct radeon_device *rdev,
+					    struct radeon_ps *radeon_state);
+void rv730_power_gating_enable(struct radeon_device *rdev,
+			       bool enable);
+void rv730_start_dpm(struct radeon_device *rdev);
+void rv730_stop_dpm(struct radeon_device *rdev);
+void rv730_program_dcodt(struct radeon_device *rdev, bool use_dcodt);
+void rv730_get_odt_values(struct radeon_device *rdev);
+
+/* rv740 */
+int rv740_populate_sclk_value(struct radeon_device *rdev, u32 engine_clock,
+			      RV770_SMC_SCLK_VALUE *sclk);
+int rv740_populate_mclk_value(struct radeon_device *rdev,
+			      u32 engine_clock, u32 memory_clock,
+			      RV7XX_SMC_MCLK_VALUE *mclk);
+void rv740_read_clock_registers(struct radeon_device *rdev);
+int rv740_populate_smc_acpi_state(struct radeon_device *rdev,
+				  RV770_SMC_STATETABLE *table);
+void rv740_enable_mclk_spread_spectrum(struct radeon_device *rdev,
+				       bool enable);
+u8 rv740_get_mclk_frequency_ratio(u32 memory_clock);
+u32 rv740_get_dll_speed(bool is_gddr5, u32 memory_clock);
+u32 rv740_get_decoded_reference_divider(u32 encoded_ref);
+
+/* rv770 */
+u32 rv770_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf);
+int rv770_populate_vddc_value(struct radeon_device *rdev, u16 vddc,
+			      RV770_SMC_VOLTAGE_VALUE *voltage);
+int rv770_populate_mvdd_value(struct radeon_device *rdev, u32 mclk,
+			      RV770_SMC_VOLTAGE_VALUE *voltage);
+u8 rv770_get_seq_value(struct radeon_device *rdev,
+		       struct rv7xx_pl *pl);
+int rv770_populate_initial_mvdd_value(struct radeon_device *rdev,
+				      RV770_SMC_VOLTAGE_VALUE *voltage);
+u32 rv770_calculate_memory_refresh_rate(struct radeon_device *rdev,
+					u32 engine_clock);
+void rv770_program_response_times(struct radeon_device *rdev);
+int rv770_populate_smc_sp(struct radeon_device *rdev,
+			  struct radeon_ps *radeon_state,
+			  RV770_SMC_SWSTATE *smc_state);
+int rv770_populate_smc_t(struct radeon_device *rdev,
+			 struct radeon_ps *radeon_state,
+			 RV770_SMC_SWSTATE *smc_state);
+void rv770_read_voltage_smio_registers(struct radeon_device *rdev);
+void rv770_get_memory_type(struct radeon_device *rdev);
+void r7xx_start_smc(struct radeon_device *rdev);
+u8 rv770_get_memory_module_index(struct radeon_device *rdev);
+void rv770_get_max_vddc(struct radeon_device *rdev);
+void rv770_get_pcie_gen2_status(struct radeon_device *rdev);
+void rv770_enable_acpi_pm(struct radeon_device *rdev);
+void rv770_restore_cgcg(struct radeon_device *rdev);
+bool rv770_dpm_enabled(struct radeon_device *rdev);
+void rv770_enable_voltage_control(struct radeon_device *rdev,
+				  bool enable);
+void rv770_enable_backbias(struct radeon_device *rdev,
+			   bool enable);
+void rv770_enable_thermal_protection(struct radeon_device *rdev,
+				     bool enable);
+void rv770_enable_auto_throttle_source(struct radeon_device *rdev,
+				       enum radeon_dpm_auto_throttle_src source,
+				       bool enable);
+void rv770_setup_bsp(struct radeon_device *rdev);
+void rv770_program_git(struct radeon_device *rdev);
+void rv770_program_tp(struct radeon_device *rdev);
+void rv770_program_tpp(struct radeon_device *rdev);
+void rv770_program_sstp(struct radeon_device *rdev);
+void rv770_program_engine_speed_parameters(struct radeon_device *rdev);
+void rv770_program_vc(struct radeon_device *rdev);
+void rv770_clear_vc(struct radeon_device *rdev);
+int rv770_upload_firmware(struct radeon_device *rdev);
+void rv770_stop_dpm(struct radeon_device *rdev);
+void r7xx_stop_smc(struct radeon_device *rdev);
+void rv770_reset_smio_status(struct radeon_device *rdev);
+int rv770_restrict_performance_levels_before_switch(struct radeon_device *rdev);
+int rv770_dpm_force_performance_level(struct radeon_device *rdev,
+				      enum radeon_dpm_forced_level level);
+int rv770_halt_smc(struct radeon_device *rdev);
+int rv770_resume_smc(struct radeon_device *rdev);
+int rv770_set_sw_state(struct radeon_device *rdev);
+int rv770_set_boot_state(struct radeon_device *rdev);
+int rv7xx_parse_power_table(struct radeon_device *rdev);
+void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
+					      struct radeon_ps *new_ps,
+					      struct radeon_ps *old_ps);
+void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
+					     struct radeon_ps *new_ps,
+					     struct radeon_ps *old_ps);
+void rv770_get_engine_memory_ss(struct radeon_device *rdev);
+
+/* smc */
+int rv770_read_smc_soft_register(struct radeon_device *rdev,
+				 u16 reg_offset, u32 *value);
+int rv770_write_smc_soft_register(struct radeon_device *rdev,
+				  u16 reg_offset, u32 value);
+
+/* thermal */
+int rv770_set_thermal_temperature_range(struct radeon_device *rdev,
+					int min_temp, int max_temp);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770_smc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770_smc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770_smc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770_smc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,621 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include <linux/firmware.h>
+#include "drmP.h"
+#include "radeon.h"
+#include "rv770d.h"
+#include "rv770_dpm.h"
+#include "rv770_smc.h"
+#include "atom.h"
+#include "radeon_ucode.h"
+
+#define FIRST_SMC_INT_VECT_REG 0xFFD8
+#define FIRST_INT_VECT_S19     0xFFC0
+
+static const u8 rv770_smc_int_vectors[] =
+{
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x0C, 0xD7,
+	0x08, 0x2B, 0x08, 0x10,
+	0x03, 0x51, 0x03, 0x51,
+	0x03, 0x51, 0x03, 0x51
+};
+
+static const u8 rv730_smc_int_vectors[] =
+{
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x08, 0x15,
+	0x08, 0x15, 0x0C, 0xBB,
+	0x08, 0x30, 0x08, 0x15,
+	0x03, 0x56, 0x03, 0x56,
+	0x03, 0x56, 0x03, 0x56
+};
+
+static const u8 rv710_smc_int_vectors[] =
+{
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x08, 0x04,
+	0x08, 0x04, 0x0C, 0xCB,
+	0x08, 0x1F, 0x08, 0x04,
+	0x03, 0x51, 0x03, 0x51,
+	0x03, 0x51, 0x03, 0x51
+};
+
+static const u8 rv740_smc_int_vectors[] =
+{
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x08, 0x10,
+	0x08, 0x10, 0x0C, 0xD7,
+	0x08, 0x2B, 0x08, 0x10,
+	0x03, 0x51, 0x03, 0x51,
+	0x03, 0x51, 0x03, 0x51
+};
+
+static const u8 cedar_smc_int_vectors[] =
+{
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x11, 0x8B,
+	0x0B, 0x20, 0x0B, 0x05,
+	0x04, 0xF6, 0x04, 0xF6,
+	0x04, 0xF6, 0x04, 0xF6
+};
+
+static const u8 redwood_smc_int_vectors[] =
+{
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x11, 0x8B,
+	0x0B, 0x20, 0x0B, 0x05,
+	0x04, 0xF6, 0x04, 0xF6,
+	0x04, 0xF6, 0x04, 0xF6
+};
+
+static const u8 juniper_smc_int_vectors[] =
+{
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x11, 0x8B,
+	0x0B, 0x20, 0x0B, 0x05,
+	0x04, 0xF6, 0x04, 0xF6,
+	0x04, 0xF6, 0x04, 0xF6
+};
+
+static const u8 cypress_smc_int_vectors[] =
+{
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x0B, 0x05,
+	0x0B, 0x05, 0x11, 0x8B,
+	0x0B, 0x20, 0x0B, 0x05,
+	0x04, 0xF6, 0x04, 0xF6,
+	0x04, 0xF6, 0x04, 0xF6
+};
+
+static const u8 barts_smc_int_vectors[] =
+{
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x12, 0xAA,
+	0x0C, 0x2F, 0x15, 0xF6,
+	0x15, 0xF6, 0x05, 0x0A,
+	0x05, 0x0A, 0x05, 0x0A
+};
+
+static const u8 turks_smc_int_vectors[] =
+{
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x12, 0xAA,
+	0x0C, 0x2F, 0x15, 0xF6,
+	0x15, 0xF6, 0x05, 0x0A,
+	0x05, 0x0A, 0x05, 0x0A
+};
+
+static const u8 caicos_smc_int_vectors[] =
+{
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x0C, 0x14,
+	0x0C, 0x14, 0x12, 0xAA,
+	0x0C, 0x2F, 0x15, 0xF6,
+	0x15, 0xF6, 0x05, 0x0A,
+	0x05, 0x0A, 0x05, 0x0A
+};
+
+static const u8 cayman_smc_int_vectors[] =
+{
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x12, 0x05,
+	0x12, 0x05, 0x18, 0xEA,
+	0x12, 0x20, 0x1C, 0x34,
+	0x1C, 0x34, 0x08, 0x72,
+	0x08, 0x72, 0x08, 0x72
+};
+
+int rv770_set_smc_sram_address(struct radeon_device *rdev,
+			       u16 smc_address, u16 limit)
+{
+	u32 addr;
+
+	if (smc_address & 3)
+		return -EINVAL;
+	if ((smc_address + 3) > limit)
+		return -EINVAL;
+
+	addr = smc_address;
+	addr |= SMC_SRAM_AUTO_INC_DIS;
+
+	WREG32(SMC_SRAM_ADDR, addr);
+
+	return 0;
+}
+
+int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
+			    u16 smc_start_address, const u8 *src,
+			    u16 byte_count, u16 limit)
+{
+	u32 data, original_data, extra_shift;
+	u16 addr;
+	int ret;
+
+	if (smc_start_address & 3)
+		return -EINVAL;
+	if ((smc_start_address + byte_count) > limit)
+		return -EINVAL;
+
+	addr = smc_start_address;
+
+	while (byte_count >= 4) {
+		/* SMC address space is BE */
+		data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
+
+		ret = rv770_set_smc_sram_address(rdev, addr, limit);
+		if (ret)
+			return ret;
+
+		WREG32(SMC_SRAM_DATA, data);
+
+		src += 4;
+		byte_count -= 4;
+		addr += 4;
+	}
+
+	/* RMW for final bytes */
+	if (byte_count > 0) {
+		data = 0;
+
+		ret = rv770_set_smc_sram_address(rdev, addr, limit);
+		if (ret)
+			return ret;
+
+		original_data = RREG32(SMC_SRAM_DATA);
+
+		extra_shift = 8 * (4 - byte_count);
+
+		while (byte_count > 0) {
+			/* SMC address space is BE */
+			data = (data << 8) + *src++;
+			byte_count--;
+		}
+
+		data <<= extra_shift;
+
+		data |= (original_data & ~((~0UL) << extra_shift));
+
+		ret = rv770_set_smc_sram_address(rdev, addr, limit);
+		if (ret)
+			return ret;
+
+		WREG32(SMC_SRAM_DATA, data);
+	}
+
+	return 0;
+}
+
+static int rv770_program_interrupt_vectors(struct radeon_device *rdev,
+					   u32 smc_first_vector, const u8 *src,
+					   u32 byte_count)
+{
+	u32 tmp, i;
+
+	if (byte_count % 4)
+		return -EINVAL;
+
+	if (smc_first_vector < FIRST_SMC_INT_VECT_REG) {
+		tmp = FIRST_SMC_INT_VECT_REG - smc_first_vector;
+
+		if (tmp > byte_count)
+			return 0;
+
+		byte_count -= tmp;
+		src += tmp;
+		smc_first_vector = FIRST_SMC_INT_VECT_REG;
+	}
+
+	for (i = 0; i < byte_count; i += 4) {
+		/* SMC address space is BE */
+		tmp = (src[i] << 24) | (src[i + 1] << 16) | (src[i + 2] << 8) | src[i + 3];
+
+		WREG32(SMC_ISR_FFD8_FFDB + i, tmp);
+	}
+
+	return 0;
+}
+
+void rv770_start_smc(struct radeon_device *rdev)
+{
+	WREG32_P(SMC_IO, SMC_RST_N, ~SMC_RST_N);
+}
+
+void rv770_reset_smc(struct radeon_device *rdev)
+{
+	WREG32_P(SMC_IO, 0, ~SMC_RST_N);
+}
+
+void rv770_stop_smc_clock(struct radeon_device *rdev)
+{
+	WREG32_P(SMC_IO, 0, ~SMC_CLK_EN);
+}
+
+void rv770_start_smc_clock(struct radeon_device *rdev)
+{
+	WREG32_P(SMC_IO, SMC_CLK_EN, ~SMC_CLK_EN);
+}
+
+bool rv770_is_smc_running(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32(SMC_IO);
+
+	if ((tmp & SMC_RST_N) && (tmp & SMC_CLK_EN))
+		return true;
+	else
+		return false;
+}
+
+PPSMC_Result rv770_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg)
+{
+	u32 tmp;
+	int i;
+	PPSMC_Result result;
+
+	if (!rv770_is_smc_running(rdev))
+		return PPSMC_Result_Failed;
+
+	WREG32_P(SMC_MSG, HOST_SMC_MSG(msg), ~HOST_SMC_MSG_MASK);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(SMC_MSG) & HOST_SMC_RESP_MASK;
+		tmp >>= HOST_SMC_RESP_SHIFT;
+		if (tmp != 0)
+			break;
+		udelay(1);
+	}
+
+	tmp = RREG32(SMC_MSG) & HOST_SMC_RESP_MASK;
+	tmp >>= HOST_SMC_RESP_SHIFT;
+
+	result = (PPSMC_Result)tmp;
+	return result;
+}
+
+PPSMC_Result rv770_wait_for_smc_inactive(struct radeon_device *rdev)
+{
+	int i;
+	PPSMC_Result result = PPSMC_Result_OK;
+
+	if (!rv770_is_smc_running(rdev))
+		return result;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(SMC_IO) & SMC_STOP_MODE)
+			break;
+		udelay(1);
+	}
+
+	return result;
+}
+
+static void rv770_clear_smc_sram(struct radeon_device *rdev, u16 limit)
+{
+	u16 i;
+
+	for (i = 0;  i < limit; i += 4) {
+		rv770_set_smc_sram_address(rdev, i, limit);
+		WREG32(SMC_SRAM_DATA, 0);
+	}
+}
+
+int rv770_load_smc_ucode(struct radeon_device *rdev,
+			 u16 limit)
+{
+	int ret;
+	const u8 *int_vect;
+	u16 int_vect_start_address;
+	u16 int_vect_size;
+	const u8 *ucode_data;
+	u16 ucode_start_address;
+	u16 ucode_size;
+
+	if (!rdev->smc_fw)
+		return -EINVAL;
+
+	rv770_clear_smc_sram(rdev, limit);
+
+	switch (rdev->family) {
+	case CHIP_RV770:
+		ucode_start_address = RV770_SMC_UCODE_START;
+		ucode_size = RV770_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&rv770_smc_int_vectors;
+		int_vect_start_address = RV770_SMC_INT_VECTOR_START;
+		int_vect_size = RV770_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_RV730:
+		ucode_start_address = RV730_SMC_UCODE_START;
+		ucode_size = RV730_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&rv730_smc_int_vectors;
+		int_vect_start_address = RV730_SMC_INT_VECTOR_START;
+		int_vect_size = RV730_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_RV710:
+		ucode_start_address = RV710_SMC_UCODE_START;
+		ucode_size = RV710_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&rv710_smc_int_vectors;
+		int_vect_start_address = RV710_SMC_INT_VECTOR_START;
+		int_vect_size = RV710_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_RV740:
+		ucode_start_address = RV740_SMC_UCODE_START;
+		ucode_size = RV740_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&rv740_smc_int_vectors;
+		int_vect_start_address = RV740_SMC_INT_VECTOR_START;
+		int_vect_size = RV740_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_CEDAR:
+		ucode_start_address = CEDAR_SMC_UCODE_START;
+		ucode_size = CEDAR_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&cedar_smc_int_vectors;
+		int_vect_start_address = CEDAR_SMC_INT_VECTOR_START;
+		int_vect_size = CEDAR_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_REDWOOD:
+		ucode_start_address = REDWOOD_SMC_UCODE_START;
+		ucode_size = REDWOOD_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&redwood_smc_int_vectors;
+		int_vect_start_address = REDWOOD_SMC_INT_VECTOR_START;
+		int_vect_size = REDWOOD_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_JUNIPER:
+		ucode_start_address = JUNIPER_SMC_UCODE_START;
+		ucode_size = JUNIPER_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&juniper_smc_int_vectors;
+		int_vect_start_address = JUNIPER_SMC_INT_VECTOR_START;
+		int_vect_size = JUNIPER_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_CYPRESS:
+	case CHIP_HEMLOCK:
+		ucode_start_address = CYPRESS_SMC_UCODE_START;
+		ucode_size = CYPRESS_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&cypress_smc_int_vectors;
+		int_vect_start_address = CYPRESS_SMC_INT_VECTOR_START;
+		int_vect_size = CYPRESS_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_BARTS:
+		ucode_start_address = BARTS_SMC_UCODE_START;
+		ucode_size = BARTS_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&barts_smc_int_vectors;
+		int_vect_start_address = BARTS_SMC_INT_VECTOR_START;
+		int_vect_size = BARTS_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_TURKS:
+		ucode_start_address = TURKS_SMC_UCODE_START;
+		ucode_size = TURKS_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&turks_smc_int_vectors;
+		int_vect_start_address = TURKS_SMC_INT_VECTOR_START;
+		int_vect_size = TURKS_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_CAICOS:
+		ucode_start_address = CAICOS_SMC_UCODE_START;
+		ucode_size = CAICOS_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&caicos_smc_int_vectors;
+		int_vect_start_address = CAICOS_SMC_INT_VECTOR_START;
+		int_vect_size = CAICOS_SMC_INT_VECTOR_SIZE;
+		break;
+	case CHIP_CAYMAN:
+		ucode_start_address = CAYMAN_SMC_UCODE_START;
+		ucode_size = CAYMAN_SMC_UCODE_SIZE;
+		int_vect = (const u8 *)&cayman_smc_int_vectors;
+		int_vect_start_address = CAYMAN_SMC_INT_VECTOR_START;
+		int_vect_size = CAYMAN_SMC_INT_VECTOR_SIZE;
+		break;
+	default:
+		DRM_ERROR("unknown asic in smc ucode loader\n");
+		BUG();
+	}
+
+	/* load the ucode */
+	ucode_data = (const u8 *)rdev->smc_fw->data;
+	ret = rv770_copy_bytes_to_smc(rdev, ucode_start_address,
+				      ucode_data, ucode_size, limit);
+	if (ret)
+		return ret;
+
+	/* set up the int vectors */
+	ret = rv770_program_interrupt_vectors(rdev, int_vect_start_address,
+					      int_vect, int_vect_size);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int rv770_read_smc_sram_dword(struct radeon_device *rdev,
+			      u16 smc_address, u32 *value, u16 limit)
+{
+	int ret;
+
+	ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
+	if (ret)
+		return ret;
+
+	*value = RREG32(SMC_SRAM_DATA);
+
+	return 0;
+}
+
+int rv770_write_smc_sram_dword(struct radeon_device *rdev,
+			       u16 smc_address, u32 value, u16 limit)
+{
+	int ret;
+
+	ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
+	if (ret)
+		return ret;
+
+	WREG32(SMC_SRAM_DATA, value);
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770_smc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770_smc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/rv770_smc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/rv770_smc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __RV770_SMC_H__
+#define __RV770_SMC_H__
+
+#include "ppsmc.h"
+
+#pragma pack(push, 1)
+
+#define RV770_SMC_TABLE_ADDRESS 0xB000
+
+#define RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE    3
+
+struct RV770_SMC_SCLK_VALUE
+{
+    uint32_t        vCG_SPLL_FUNC_CNTL;
+    uint32_t        vCG_SPLL_FUNC_CNTL_2;
+    uint32_t        vCG_SPLL_FUNC_CNTL_3;
+    uint32_t        vCG_SPLL_SPREAD_SPECTRUM;
+    uint32_t        vCG_SPLL_SPREAD_SPECTRUM_2;
+    uint32_t        sclk_value;
+};
+
+typedef struct RV770_SMC_SCLK_VALUE RV770_SMC_SCLK_VALUE;
+
+struct RV770_SMC_MCLK_VALUE
+{
+    uint32_t        vMPLL_AD_FUNC_CNTL;
+    uint32_t        vMPLL_AD_FUNC_CNTL_2;
+    uint32_t        vMPLL_DQ_FUNC_CNTL;
+    uint32_t        vMPLL_DQ_FUNC_CNTL_2;
+    uint32_t        vMCLK_PWRMGT_CNTL;
+    uint32_t        vDLL_CNTL;
+    uint32_t        vMPLL_SS;
+    uint32_t        vMPLL_SS2;
+    uint32_t        mclk_value;
+};
+
+typedef struct RV770_SMC_MCLK_VALUE RV770_SMC_MCLK_VALUE;
+
+
+struct RV730_SMC_MCLK_VALUE
+{
+    uint32_t        vMCLK_PWRMGT_CNTL;
+    uint32_t        vDLL_CNTL;
+    uint32_t        vMPLL_FUNC_CNTL;
+    uint32_t        vMPLL_FUNC_CNTL2;
+    uint32_t        vMPLL_FUNC_CNTL3;
+    uint32_t        vMPLL_SS;
+    uint32_t        vMPLL_SS2;
+    uint32_t        mclk_value;
+};
+
+typedef struct RV730_SMC_MCLK_VALUE RV730_SMC_MCLK_VALUE;
+
+struct RV770_SMC_VOLTAGE_VALUE
+{
+    uint16_t             value;
+    uint8_t              index;
+    uint8_t              padding;
+};
+
+typedef struct RV770_SMC_VOLTAGE_VALUE RV770_SMC_VOLTAGE_VALUE;
+
+union RV7XX_SMC_MCLK_VALUE
+{
+    RV770_SMC_MCLK_VALUE    mclk770;
+    RV730_SMC_MCLK_VALUE    mclk730;
+};
+
+typedef union RV7XX_SMC_MCLK_VALUE RV7XX_SMC_MCLK_VALUE, *LPRV7XX_SMC_MCLK_VALUE;
+
+struct RV770_SMC_HW_PERFORMANCE_LEVEL
+{
+    uint8_t                 arbValue;
+    union{
+        uint8_t             seqValue;
+        uint8_t             ACIndex;
+    };
+    uint8_t                 displayWatermark;
+    uint8_t                 gen2PCIE;
+    uint8_t                 gen2XSP;
+    uint8_t                 backbias;
+    uint8_t                 strobeMode;
+    uint8_t                 mcFlags;
+    uint32_t                aT;
+    uint32_t                bSP;
+    RV770_SMC_SCLK_VALUE    sclk;
+    RV7XX_SMC_MCLK_VALUE    mclk;
+    RV770_SMC_VOLTAGE_VALUE vddc;
+    RV770_SMC_VOLTAGE_VALUE mvdd;
+    RV770_SMC_VOLTAGE_VALUE vddci;
+    uint8_t                 reserved1;
+    uint8_t                 reserved2;
+    uint8_t                 stateFlags;
+    uint8_t                 padding;
+};
+
+#define SMC_STROBE_RATIO    0x0F
+#define SMC_STROBE_ENABLE   0x10
+
+#define SMC_MC_EDC_RD_FLAG  0x01
+#define SMC_MC_EDC_WR_FLAG  0x02
+#define SMC_MC_RTT_ENABLE   0x04
+#define SMC_MC_STUTTER_EN   0x08
+
+typedef struct RV770_SMC_HW_PERFORMANCE_LEVEL RV770_SMC_HW_PERFORMANCE_LEVEL;
+
+struct RV770_SMC_SWSTATE
+{
+    uint8_t           flags;
+    uint8_t           padding1;
+    uint8_t           padding2;
+    uint8_t           padding3;
+    RV770_SMC_HW_PERFORMANCE_LEVEL levels[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
+};
+
+typedef struct RV770_SMC_SWSTATE RV770_SMC_SWSTATE;
+
+#define RV770_SMC_VOLTAGEMASK_VDDC 0
+#define RV770_SMC_VOLTAGEMASK_MVDD 1
+#define RV770_SMC_VOLTAGEMASK_VDDCI 2
+#define RV770_SMC_VOLTAGEMASK_MAX  4
+
+struct RV770_SMC_VOLTAGEMASKTABLE
+{
+    uint8_t  highMask[RV770_SMC_VOLTAGEMASK_MAX];
+    uint32_t lowMask[RV770_SMC_VOLTAGEMASK_MAX];
+};
+
+typedef struct RV770_SMC_VOLTAGEMASKTABLE RV770_SMC_VOLTAGEMASKTABLE;
+
+#define MAX_NO_VREG_STEPS 32
+
+struct RV770_SMC_STATETABLE
+{
+    uint8_t             thermalProtectType;
+    uint8_t             systemFlags;
+    uint8_t             maxVDDCIndexInPPTable;
+    uint8_t             extraFlags;
+    uint8_t             highSMIO[MAX_NO_VREG_STEPS];
+    uint32_t            lowSMIO[MAX_NO_VREG_STEPS];
+    RV770_SMC_VOLTAGEMASKTABLE voltageMaskTable;
+    RV770_SMC_SWSTATE   initialState;
+    RV770_SMC_SWSTATE   ACPIState;
+    RV770_SMC_SWSTATE   driverState;
+    RV770_SMC_SWSTATE   ULVState;
+};
+
+typedef struct RV770_SMC_STATETABLE RV770_SMC_STATETABLE;
+
+#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP 0x01
+
+#pragma pack(pop)
+
+#define RV770_SMC_SOFT_REGISTERS_START        0x104
+
+#define RV770_SMC_SOFT_REGISTER_mclk_chg_timeout        0x0
+#define RV770_SMC_SOFT_REGISTER_baby_step_timer         0x8
+#define RV770_SMC_SOFT_REGISTER_delay_bbias             0xC
+#define RV770_SMC_SOFT_REGISTER_delay_vreg              0x10
+#define RV770_SMC_SOFT_REGISTER_delay_acpi              0x2C
+#define RV770_SMC_SOFT_REGISTER_seq_index               0x64
+#define RV770_SMC_SOFT_REGISTER_mvdd_chg_time           0x68
+#define RV770_SMC_SOFT_REGISTER_mclk_switch_lim         0x78
+#define RV770_SMC_SOFT_REGISTER_mc_block_delay          0x90
+#define RV770_SMC_SOFT_REGISTER_uvd_enabled             0x9C
+#define RV770_SMC_SOFT_REGISTER_is_asic_lombok          0xA0
+
+int rv770_set_smc_sram_address(struct radeon_device *rdev,
+			       u16 smc_address, u16 limit);
+int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
+			    u16 smc_start_address, const u8 *src,
+			    u16 byte_count, u16 limit);
+void rv770_start_smc(struct radeon_device *rdev);
+void rv770_reset_smc(struct radeon_device *rdev);
+void rv770_stop_smc_clock(struct radeon_device *rdev);
+void rv770_start_smc_clock(struct radeon_device *rdev);
+bool rv770_is_smc_running(struct radeon_device *rdev);
+PPSMC_Result rv770_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg);
+PPSMC_Result rv770_wait_for_smc_inactive(struct radeon_device *rdev);
+int rv770_read_smc_sram_dword(struct radeon_device *rdev,
+			      u16 smc_address, u32 *value, u16 limit);
+int rv770_write_smc_sram_dword(struct radeon_device *rdev,
+			       u16 smc_address, u32 value, u16 limit);
+int rv770_load_smc_ucode(struct radeon_device *rdev,
+			 u16 limit);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/si.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/si.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/si.c	2013-07-01 10:32:25.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/si.c	2013-08-31 17:51:48.000000000 -0400
@@ -22,7 +22,6 @@
  * Authors: Alex Deucher
  */
 #include <linux/firmware.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <drm/drmP.h>
@@ -32,16 +31,14 @@
 #include "sid.h"
 #include "atom.h"
 #include "si_blit_shaders.h"
+#include "clearstate_si.h"
+#include "radeon_ucode.h"
 
-#define SI_PFP_UCODE_SIZE 2144
-#define SI_PM4_UCODE_SIZE 2144
-#define SI_CE_UCODE_SIZE 2144
-#define SI_RLC_UCODE_SIZE 2048
-#define SI_MC_UCODE_SIZE 7769
-#define OLAND_MC_UCODE_SIZE 7863
 
 /*(DEBLOBBED)*/
 
+static void si_pcie_gen3_enable(struct radeon_device *rdev);
+static void si_program_aspm(struct radeon_device *rdev);
 extern int r600_ih_ring_alloc(struct radeon_device *rdev);
 extern void r600_ih_ring_fini(struct radeon_device *rdev);
 extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
@@ -51,6 +48,228 @@ extern u32 evergreen_get_number_of_dram_
 extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
 extern bool evergreen_is_display_hung(struct radeon_device *rdev);
 
+static const u32 verde_rlc_save_restore_register_list[] =
+{
+	(0x8000 << 16) | (0x98f4 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x98f4 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0xe80 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0xe80 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x89bc >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x89bc >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x8c1c >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x8c1c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x98f0 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0xe7c >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x9148 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x9148 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9150 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x897c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8d8c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0xac54 >> 2),
+	0X00000000,
+	0x3,
+	(0x9c00 << 16) | (0x98f8 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9910 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9914 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9918 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x991c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9920 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9924 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9928 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x992c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9930 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9934 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9938 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x993c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9940 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9944 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9948 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x994c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9950 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9954 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9958 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x995c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9960 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9964 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9968 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x996c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9970 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9974 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9978 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x997c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9980 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9984 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9988 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x998c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8c00 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8c14 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8c04 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8c08 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x9b7c >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x9b7c >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0xe84 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0xe84 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x89c0 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x89c0 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x914c >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x914c >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x8c20 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x8c20 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x9354 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x9354 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9060 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9364 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9100 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x913c >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x90e0 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x90e4 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x90e8 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x90e0 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x90e4 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x90e8 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8bcc >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8b24 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x88c4 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8e50 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8c0c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8e58 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8e5c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9508 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x950c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9494 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0xac0c >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0xac10 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0xac14 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0xae00 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0xac08 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x88d4 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x88c8 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x88cc >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x89b0 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8b10 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x8a14 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9830 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9834 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9838 >> 2),
+	0x00000000,
+	(0x9c00 << 16) | (0x9a10 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x9870 >> 2),
+	0x00000000,
+	(0x8000 << 16) | (0x9874 >> 2),
+	0x00000000,
+	(0x8001 << 16) | (0x9870 >> 2),
+	0x00000000,
+	(0x8001 << 16) | (0x9874 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x9870 >> 2),
+	0x00000000,
+	(0x8040 << 16) | (0x9874 >> 2),
+	0x00000000,
+	(0x8041 << 16) | (0x9870 >> 2),
+	0x00000000,
+	(0x8041 << 16) | (0x9874 >> 2),
+	0x00000000,
+	0x00000000
+};
+
 static const u32 tahiti_golden_rlc_registers[] =
 {
 	0xc424, 0xffffffff, 0x00601005,
@@ -1292,22 +1511,15 @@ static int si_mc_load_microcode(struct r
 
 static int si_init_microcode(struct radeon_device *rdev)
 {
-	struct platform_device *pdev;
 	const char *chip_name;
 	const char *rlc_chip_name;
 	size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
+	size_t smc_req_size;
 	char fw_name[30];
 	int err;
 
 	DRM_DEBUG("\n");
 
-	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
-	err = IS_ERR(pdev);
-	if (err) {
-		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
-		return -EINVAL;
-	}
-
 	switch (rdev->family) {
 	case CHIP_TAHITI:
 		chip_name = "TAHITI";
@@ -1317,6 +1529,7 @@ static int si_init_microcode(struct rade
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
 		mc_req_size = SI_MC_UCODE_SIZE * 4;
+		smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_PITCAIRN:
 		chip_name = "PITCAIRN";
@@ -1326,6 +1539,7 @@ static int si_init_microcode(struct rade
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
 		mc_req_size = SI_MC_UCODE_SIZE * 4;
+		smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_VERDE:
 		chip_name = "VERDE";
@@ -1335,6 +1549,7 @@ static int si_init_microcode(struct rade
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
 		mc_req_size = SI_MC_UCODE_SIZE * 4;
+		smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_OLAND:
 		chip_name = "OLAND";
@@ -1344,6 +1559,7 @@ static int si_init_microcode(struct rade
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
 		mc_req_size = OLAND_MC_UCODE_SIZE * 4;
+		smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);
 		break;
 	case CHIP_HAINAN:
 		chip_name = "HAINAN";
@@ -1353,6 +1569,7 @@ static int si_init_microcode(struct rade
 		ce_req_size = SI_CE_UCODE_SIZE * 4;
 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
 		mc_req_size = OLAND_MC_UCODE_SIZE * 4;
+		smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);
 		break;
 	default: BUG();
 	}
@@ -1360,7 +1577,7 @@ static int si_init_microcode(struct rade
 	DRM_INFO("Loading %s Microcode\n", chip_name);
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
-	err = reject_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->pfp_fw->size != pfp_req_size) {
@@ -1372,7 +1589,7 @@ static int si_init_microcode(struct rade
 	}
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
-	err = reject_firmware(&rdev->me_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->me_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->me_fw->size != me_req_size) {
@@ -1383,7 +1600,7 @@ static int si_init_microcode(struct rade
 	}
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
-	err = reject_firmware(&rdev->ce_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->ce_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->ce_fw->size != ce_req_size) {
@@ -1394,7 +1611,7 @@ static int si_init_microcode(struct rade
 	}
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", rlc_chip_name);
-	err = reject_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->rlc_fw->size != rlc_req_size) {
@@ -1405,7 +1622,7 @@ static int si_init_microcode(struct rade
 	}
 
 	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
-	err = reject_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
+	err = reject_firmware(&rdev->mc_fw, fw_name, rdev->dev);
 	if (err)
 		goto out;
 	if (rdev->mc_fw->size != mc_req_size) {
@@ -1415,9 +1632,22 @@ static int si_init_microcode(struct rade
 		err = -EINVAL;
 	}
 
-out:
-	platform_device_unregister(pdev);
+	snprintf(fw_name, sizeof(fw_name), "/*(DEBLOBBED)*/", chip_name);
+	err = reject_firmware(&rdev->smc_fw, fw_name, rdev->dev);
+	if (err) {
+		printk(KERN_ERR
+		       "smc: error loading firmware \"%s\"\n",
+		       fw_name);
+		release_firmware(rdev->smc_fw);
+		rdev->smc_fw = NULL;
+	} else if (rdev->smc_fw->size != smc_req_size) {
+		printk(KERN_ERR
+		       "si_smc: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->smc_fw->size, fw_name);
+		err = -EINVAL;
+	}
 
+out:
 	if (err) {
 		if (err != -EINVAL)
 			printk(KERN_ERR
@@ -1433,6 +1663,8 @@ out:
 		rdev->rlc_fw = NULL;
 		release_firmware(rdev->mc_fw);
 		rdev->mc_fw = NULL;
+		release_firmware(rdev->smc_fw);
+		rdev->smc_fw = NULL;
 	}
 	return err;
 }
@@ -1768,7 +2000,8 @@ static void dce6_program_watermarks(stru
 					 u32 lb_size, u32 num_heads)
 {
 	struct drm_display_mode *mode = &radeon_crtc->base.mode;
-	struct dce6_wm_params wm;
+	struct dce6_wm_params wm_low, wm_high;
+	u32 dram_channels;
 	u32 pixel_period;
 	u32 line_time = 0;
 	u32 latency_watermark_a = 0, latency_watermark_b = 0;
@@ -1784,38 +2017,83 @@ static void dce6_program_watermarks(stru
 		priority_a_cnt = 0;
 		priority_b_cnt = 0;
 
-		wm.yclk = rdev->pm.current_mclk * 10;
-		wm.sclk = rdev->pm.current_sclk * 10;
-		wm.disp_clk = mode->clock;
-		wm.src_width = mode->crtc_hdisplay;
-		wm.active_time = mode->crtc_hdisplay * pixel_period;
-		wm.blank_time = line_time - wm.active_time;
-		wm.interlaced = false;
-		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-			wm.interlaced = true;
-		wm.vsc = radeon_crtc->vsc;
-		wm.vtaps = 1;
-		if (radeon_crtc->rmx_type != RMX_OFF)
-			wm.vtaps = 2;
-		wm.bytes_per_pixel = 4; /* XXX: get this from fb config */
-		wm.lb_size = lb_size;
 		if (rdev->family == CHIP_ARUBA)
-			wm.dram_channels = evergreen_get_number_of_dram_channels(rdev);
+			dram_channels = evergreen_get_number_of_dram_channels(rdev);
 		else
-			wm.dram_channels = si_get_number_of_dram_channels(rdev);
-		wm.num_heads = num_heads;
+			dram_channels = si_get_number_of_dram_channels(rdev);
+
+		/* watermark for high clocks */
+		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
+			wm_high.yclk =
+				radeon_dpm_get_mclk(rdev, false) * 10;
+			wm_high.sclk =
+				radeon_dpm_get_sclk(rdev, false) * 10;
+		} else {
+			wm_high.yclk = rdev->pm.current_mclk * 10;
+			wm_high.sclk = rdev->pm.current_sclk * 10;
+		}
+
+		wm_high.disp_clk = mode->clock;
+		wm_high.src_width = mode->crtc_hdisplay;
+		wm_high.active_time = mode->crtc_hdisplay * pixel_period;
+		wm_high.blank_time = line_time - wm_high.active_time;
+		wm_high.interlaced = false;
+		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+			wm_high.interlaced = true;
+		wm_high.vsc = radeon_crtc->vsc;
+		wm_high.vtaps = 1;
+		if (radeon_crtc->rmx_type != RMX_OFF)
+			wm_high.vtaps = 2;
+		wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
+		wm_high.lb_size = lb_size;
+		wm_high.dram_channels = dram_channels;
+		wm_high.num_heads = num_heads;
+
+		/* watermark for low clocks */
+		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
+			wm_low.yclk =
+				radeon_dpm_get_mclk(rdev, true) * 10;
+			wm_low.sclk =
+				radeon_dpm_get_sclk(rdev, true) * 10;
+		} else {
+			wm_low.yclk = rdev->pm.current_mclk * 10;
+			wm_low.sclk = rdev->pm.current_sclk * 10;
+		}
+
+		wm_low.disp_clk = mode->clock;
+		wm_low.src_width = mode->crtc_hdisplay;
+		wm_low.active_time = mode->crtc_hdisplay * pixel_period;
+		wm_low.blank_time = line_time - wm_low.active_time;
+		wm_low.interlaced = false;
+		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+			wm_low.interlaced = true;
+		wm_low.vsc = radeon_crtc->vsc;
+		wm_low.vtaps = 1;
+		if (radeon_crtc->rmx_type != RMX_OFF)
+			wm_low.vtaps = 2;
+		wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
+		wm_low.lb_size = lb_size;
+		wm_low.dram_channels = dram_channels;
+		wm_low.num_heads = num_heads;
 
 		/* set for high clocks */
-		latency_watermark_a = min(dce6_latency_watermark(&wm), (u32)65535);
+		latency_watermark_a = min(dce6_latency_watermark(&wm_high), (u32)65535);
 		/* set for low clocks */
-		/* wm.yclk = low clk; wm.sclk = low clk */
-		latency_watermark_b = min(dce6_latency_watermark(&wm), (u32)65535);
+		latency_watermark_b = min(dce6_latency_watermark(&wm_low), (u32)65535);
 
 		/* possibly force display priority to high */
 		/* should really do this at mode validation time... */
-		if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm) ||
-		    !dce6_average_bandwidth_vs_available_bandwidth(&wm) ||
-		    !dce6_check_latency_hiding(&wm) ||
+		if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) ||
+		    !dce6_average_bandwidth_vs_available_bandwidth(&wm_high) ||
+		    !dce6_check_latency_hiding(&wm_high) ||
+		    (rdev->disp_priority == 2)) {
+			DRM_DEBUG_KMS("force priority to high\n");
+			priority_a_cnt |= PRIORITY_ALWAYS_ON;
+			priority_b_cnt |= PRIORITY_ALWAYS_ON;
+		}
+		if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) ||
+		    !dce6_average_bandwidth_vs_available_bandwidth(&wm_low) ||
+		    !dce6_check_latency_hiding(&wm_low) ||
 		    (rdev->disp_priority == 2)) {
 			DRM_DEBUG_KMS("force priority to high\n");
 			priority_a_cnt |= PRIORITY_ALWAYS_ON;
@@ -1871,6 +2149,10 @@ static void dce6_program_watermarks(stru
 	WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt);
 	WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt);
 
+	/* save values for DPM */
+	radeon_crtc->line_time = line_time;
+	radeon_crtc->wm_high = latency_watermark_a;
+	radeon_crtc->wm_low = latency_watermark_b;
 }
 
 void dce6_bandwidth_update(struct radeon_device *rdev)
@@ -3511,8 +3793,8 @@ static void si_mc_program(struct radeon_
 	}
 }
 
-static void si_vram_gtt_location(struct radeon_device *rdev,
-				 struct radeon_mc *mc)
+void si_vram_gtt_location(struct radeon_device *rdev,
+			  struct radeon_mc *mc)
 {
 	if (mc->mc_vram_size > 0xFFC0000000ULL) {
 		/* leave room for at least 1024M GTT */
@@ -4083,6 +4365,270 @@ void si_vm_fini(struct radeon_device *rd
 }
 
 /**
+ * si_vm_decode_fault - print human readable fault info
+ *
+ * @rdev: radeon_device pointer
+ * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
+ * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
+ *
+ * Print human readable fault information (SI).
+ */
+static void si_vm_decode_fault(struct radeon_device *rdev,
+			       u32 status, u32 addr)
+{
+	u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
+	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
+	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
+	char *block;
+
+	if (rdev->family == CHIP_TAHITI) {
+		switch (mc_id) {
+		case 160:
+		case 144:
+		case 96:
+		case 80:
+		case 224:
+		case 208:
+		case 32:
+		case 16:
+			block = "CB";
+			break;
+		case 161:
+		case 145:
+		case 97:
+		case 81:
+		case 225:
+		case 209:
+		case 33:
+		case 17:
+			block = "CB_FMASK";
+			break;
+		case 162:
+		case 146:
+		case 98:
+		case 82:
+		case 226:
+		case 210:
+		case 34:
+		case 18:
+			block = "CB_CMASK";
+			break;
+		case 163:
+		case 147:
+		case 99:
+		case 83:
+		case 227:
+		case 211:
+		case 35:
+		case 19:
+			block = "CB_IMMED";
+			break;
+		case 164:
+		case 148:
+		case 100:
+		case 84:
+		case 228:
+		case 212:
+		case 36:
+		case 20:
+			block = "DB";
+			break;
+		case 165:
+		case 149:
+		case 101:
+		case 85:
+		case 229:
+		case 213:
+		case 37:
+		case 21:
+			block = "DB_HTILE";
+			break;
+		case 167:
+		case 151:
+		case 103:
+		case 87:
+		case 231:
+		case 215:
+		case 39:
+		case 23:
+			block = "DB_STEN";
+			break;
+		case 72:
+		case 68:
+		case 64:
+		case 8:
+		case 4:
+		case 0:
+		case 136:
+		case 132:
+		case 128:
+		case 200:
+		case 196:
+		case 192:
+			block = "TC";
+			break;
+		case 112:
+		case 48:
+			block = "CP";
+			break;
+		case 49:
+		case 177:
+		case 50:
+		case 178:
+			block = "SH";
+			break;
+		case 53:
+		case 190:
+			block = "VGT";
+			break;
+		case 117:
+			block = "IH";
+			break;
+		case 51:
+		case 115:
+			block = "RLC";
+			break;
+		case 119:
+		case 183:
+			block = "DMA0";
+			break;
+		case 61:
+			block = "DMA1";
+			break;
+		case 248:
+		case 120:
+			block = "HDP";
+			break;
+		default:
+			block = "unknown";
+			break;
+		}
+	} else {
+		switch (mc_id) {
+		case 32:
+		case 16:
+		case 96:
+		case 80:
+		case 160:
+		case 144:
+		case 224:
+		case 208:
+			block = "CB";
+			break;
+		case 33:
+		case 17:
+		case 97:
+		case 81:
+		case 161:
+		case 145:
+		case 225:
+		case 209:
+			block = "CB_FMASK";
+			break;
+		case 34:
+		case 18:
+		case 98:
+		case 82:
+		case 162:
+		case 146:
+		case 226:
+		case 210:
+			block = "CB_CMASK";
+			break;
+		case 35:
+		case 19:
+		case 99:
+		case 83:
+		case 163:
+		case 147:
+		case 227:
+		case 211:
+			block = "CB_IMMED";
+			break;
+		case 36:
+		case 20:
+		case 100:
+		case 84:
+		case 164:
+		case 148:
+		case 228:
+		case 212:
+			block = "DB";
+			break;
+		case 37:
+		case 21:
+		case 101:
+		case 85:
+		case 165:
+		case 149:
+		case 229:
+		case 213:
+			block = "DB_HTILE";
+			break;
+		case 39:
+		case 23:
+		case 103:
+		case 87:
+		case 167:
+		case 151:
+		case 231:
+		case 215:
+			block = "DB_STEN";
+			break;
+		case 72:
+		case 68:
+		case 8:
+		case 4:
+		case 136:
+		case 132:
+		case 200:
+		case 196:
+			block = "TC";
+			break;
+		case 112:
+		case 48:
+			block = "CP";
+			break;
+		case 49:
+		case 177:
+		case 50:
+		case 178:
+			block = "SH";
+			break;
+		case 53:
+			block = "VGT";
+			break;
+		case 117:
+			block = "IH";
+			break;
+		case 51:
+		case 115:
+			block = "RLC";
+			break;
+		case 119:
+		case 183:
+			block = "DMA0";
+			break;
+		case 61:
+			block = "DMA1";
+			break;
+		case 248:
+		case 120:
+			block = "HDP";
+			break;
+		default:
+			block = "unknown";
+			break;
+		}
+	}
+
+	printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
+	       protections, vmid, addr,
+	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
+	       block, mc_id);
+}
+
+/**
  * si_vm_set_page - update the page tables using the CP
  *
  * @rdev: radeon_device pointer
@@ -4258,6 +4804,446 @@ void si_dma_vm_flush(struct radeon_devic
 }
 
 /*
+ *  Power and clock gating
+ */
+static void si_wait_for_rlc_serdes(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0)
+			break;
+		udelay(1);
+	}
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0)
+			break;
+		udelay(1);
+	}
+}
+
+static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
+					 bool enable)
+{
+	u32 tmp = RREG32(CP_INT_CNTL_RING0);
+	u32 mask;
+	int i;
+
+	if (enable)
+		tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
+	else
+		tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
+	WREG32(CP_INT_CNTL_RING0, tmp);
+
+	if (!enable) {
+		/* read a gfx register */
+		tmp = RREG32(DB_DEPTH_INFO);
+
+		mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS;
+		for (i = 0; i < rdev->usec_timeout; i++) {
+			if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS))
+				break;
+			udelay(1);
+		}
+	}
+}
+
+static void si_set_uvd_dcm(struct radeon_device *rdev,
+			   bool sw_mode)
+{
+	u32 tmp, tmp2;
+
+	tmp = RREG32(UVD_CGC_CTRL);
+	tmp &= ~(CLK_OD_MASK | CG_DT_MASK);
+	tmp |= DCM | CG_DT(1) | CLK_OD(4);
+
+	if (sw_mode) {
+		tmp &= ~0x7ffff800;
+		tmp2 = DYN_OR_EN | DYN_RR_EN | G_DIV_ID(7);
+	} else {
+		tmp |= 0x7ffff800;
+		tmp2 = 0;
+	}
+
+	WREG32(UVD_CGC_CTRL, tmp);
+	WREG32_UVD_CTX(UVD_CGC_CTRL2, tmp2);
+}
+
+static void si_init_uvd_internal_cg(struct radeon_device *rdev)
+{
+	bool hw_mode = true;
+
+	if (hw_mode) {
+		si_set_uvd_dcm(rdev, false);
+	} else {
+		u32 tmp = RREG32(UVD_CGC_CTRL);
+		tmp &= ~DCM;
+		WREG32(UVD_CGC_CTRL, tmp);
+	}
+}
+
+static u32 si_halt_rlc(struct radeon_device *rdev)
+{
+	u32 data, orig;
+
+	orig = data = RREG32(RLC_CNTL);
+
+	if (data & RLC_ENABLE) {
+		data &= ~RLC_ENABLE;
+		WREG32(RLC_CNTL, data);
+
+		si_wait_for_rlc_serdes(rdev);
+	}
+
+	return orig;
+}
+
+static void si_update_rlc(struct radeon_device *rdev, u32 rlc)
+{
+	u32 tmp;
+
+	tmp = RREG32(RLC_CNTL);
+	if (tmp != rlc)
+		WREG32(RLC_CNTL, rlc);
+}
+
+static void si_enable_dma_pg(struct radeon_device *rdev, bool enable)
+{
+	u32 data, orig;
+
+	orig = data = RREG32(DMA_PG);
+	if (enable)
+		data |= PG_CNTL_ENABLE;
+	else
+		data &= ~PG_CNTL_ENABLE;
+	if (orig != data)
+		WREG32(DMA_PG, data);
+}
+
+static void si_init_dma_pg(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	WREG32(DMA_PGFSM_WRITE,  0x00002000);
+	WREG32(DMA_PGFSM_CONFIG, 0x100010ff);
+
+	for (tmp = 0; tmp < 5; tmp++)
+		WREG32(DMA_PGFSM_WRITE, 0);
+}
+
+static void si_enable_gfx_cgpg(struct radeon_device *rdev,
+			       bool enable)
+{
+	u32 tmp;
+
+	if (enable) {
+		tmp = RLC_PUD(0x10) | RLC_PDD(0x10) | RLC_TTPD(0x10) | RLC_MSD(0x10);
+		WREG32(RLC_TTOP_D, tmp);
+
+		tmp = RREG32(RLC_PG_CNTL);
+		tmp |= GFX_PG_ENABLE;
+		WREG32(RLC_PG_CNTL, tmp);
+
+		tmp = RREG32(RLC_AUTO_PG_CTRL);
+		tmp |= AUTO_PG_EN;
+		WREG32(RLC_AUTO_PG_CTRL, tmp);
+	} else {
+		tmp = RREG32(RLC_AUTO_PG_CTRL);
+		tmp &= ~AUTO_PG_EN;
+		WREG32(RLC_AUTO_PG_CTRL, tmp);
+
+		tmp = RREG32(DB_RENDER_CONTROL);
+	}
+}
+
+static void si_init_gfx_cgpg(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
+
+	tmp = RREG32(RLC_PG_CNTL);
+	tmp |= GFX_PG_SRC;
+	WREG32(RLC_PG_CNTL, tmp);
+
+	WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
+
+	tmp = RREG32(RLC_AUTO_PG_CTRL);
+
+	tmp &= ~GRBM_REG_SGIT_MASK;
+	tmp |= GRBM_REG_SGIT(0x700);
+	tmp &= ~PG_AFTER_GRBM_REG_ST_MASK;
+	WREG32(RLC_AUTO_PG_CTRL, tmp);
+}
+
+static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh)
+{
+	u32 mask = 0, tmp, tmp1;
+	int i;
+
+	si_select_se_sh(rdev, se, sh);
+	tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
+	tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG);
+	si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
+
+	tmp &= 0xffff0000;
+
+	tmp |= tmp1;
+	tmp >>= 16;
+
+	for (i = 0; i < rdev->config.si.max_cu_per_sh; i ++) {
+		mask <<= 1;
+		mask |= 1;
+	}
+
+	return (~tmp) & mask;
+}
+
+static void si_init_ao_cu_mask(struct radeon_device *rdev)
+{
+	u32 i, j, k, active_cu_number = 0;
+	u32 mask, counter, cu_bitmap;
+	u32 tmp = 0;
+
+	for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
+		for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
+			mask = 1;
+			cu_bitmap = 0;
+			counter  = 0;
+			for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) {
+				if (si_get_cu_active_bitmap(rdev, i, j) & mask) {
+					if (counter < 2)
+						cu_bitmap |= mask;
+					counter++;
+				}
+				mask <<= 1;
+			}
+
+			active_cu_number += counter;
+			tmp |= (cu_bitmap << (i * 16 + j * 8));
+		}
+	}
+
+	WREG32(RLC_PG_AO_CU_MASK, tmp);
+
+	tmp = RREG32(RLC_MAX_PG_CU);
+	tmp &= ~MAX_PU_CU_MASK;
+	tmp |= MAX_PU_CU(active_cu_number);
+	WREG32(RLC_MAX_PG_CU, tmp);
+}
+
+static void si_enable_cgcg(struct radeon_device *rdev,
+			   bool enable)
+{
+	u32 data, orig, tmp;
+
+	orig = data = RREG32(RLC_CGCG_CGLS_CTRL);
+
+	si_enable_gui_idle_interrupt(rdev, enable);
+
+	if (enable) {
+		WREG32(RLC_GCPM_GENERAL_3, 0x00000080);
+
+		tmp = si_halt_rlc(rdev);
+
+		WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
+		WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
+		WREG32(RLC_SERDES_WR_CTRL, 0x00b000ff);
+
+		si_wait_for_rlc_serdes(rdev);
+
+		si_update_rlc(rdev, tmp);
+
+		WREG32(RLC_SERDES_WR_CTRL, 0x007000ff);
+
+		data |= CGCG_EN | CGLS_EN;
+	} else {
+		RREG32(CB_CGTT_SCLK_CTRL);
+		RREG32(CB_CGTT_SCLK_CTRL);
+		RREG32(CB_CGTT_SCLK_CTRL);
+		RREG32(CB_CGTT_SCLK_CTRL);
+
+		data &= ~(CGCG_EN | CGLS_EN);
+	}
+
+	if (orig != data)
+		WREG32(RLC_CGCG_CGLS_CTRL, data);
+}
+
+static void si_enable_mgcg(struct radeon_device *rdev,
+			   bool enable)
+{
+	u32 data, orig, tmp = 0;
+
+	if (enable) {
+		orig = data = RREG32(CGTS_SM_CTRL_REG);
+		data = 0x96940200;
+		if (orig != data)
+			WREG32(CGTS_SM_CTRL_REG, data);
+
+		orig = data = RREG32(CP_MEM_SLP_CNTL);
+		data |= CP_MEM_LS_EN;
+		if (orig != data)
+			WREG32(CP_MEM_SLP_CNTL, data);
+
+		orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
+		data &= 0xffffffc0;
+		if (orig != data)
+			WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
+
+		tmp = si_halt_rlc(rdev);
+
+		WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
+		WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
+		WREG32(RLC_SERDES_WR_CTRL, 0x00d000ff);
+
+		si_update_rlc(rdev, tmp);
+	} else {
+		orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
+		data |= 0x00000003;
+		if (orig != data)
+			WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
+
+		data = RREG32(CP_MEM_SLP_CNTL);
+		if (data & CP_MEM_LS_EN) {
+			data &= ~CP_MEM_LS_EN;
+			WREG32(CP_MEM_SLP_CNTL, data);
+		}
+		orig = data = RREG32(CGTS_SM_CTRL_REG);
+		data |= LS_OVERRIDE | OVERRIDE;
+		if (orig != data)
+			WREG32(CGTS_SM_CTRL_REG, data);
+
+		tmp = si_halt_rlc(rdev);
+
+		WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
+		WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
+		WREG32(RLC_SERDES_WR_CTRL, 0x00e000ff);
+
+		si_update_rlc(rdev, tmp);
+	}
+}
+
+static void si_enable_uvd_mgcg(struct radeon_device *rdev,
+			       bool enable)
+{
+	u32 orig, data, tmp;
+
+	if (enable) {
+		tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
+		tmp |= 0x3fff;
+		WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
+
+		orig = data = RREG32(UVD_CGC_CTRL);
+		data |= DCM;
+		if (orig != data)
+			WREG32(UVD_CGC_CTRL, data);
+
+		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0);
+		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0);
+	} else {
+		tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
+		tmp &= ~0x3fff;
+		WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
+
+		orig = data = RREG32(UVD_CGC_CTRL);
+		data &= ~DCM;
+		if (orig != data)
+			WREG32(UVD_CGC_CTRL, data);
+
+		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0xffffffff);
+		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0xffffffff);
+	}
+}
+
+static const u32 mc_cg_registers[] =
+{
+	MC_HUB_MISC_HUB_CG,
+	MC_HUB_MISC_SIP_CG,
+	MC_HUB_MISC_VM_CG,
+	MC_XPB_CLK_GAT,
+	ATC_MISC_CG,
+	MC_CITF_MISC_WR_CG,
+	MC_CITF_MISC_RD_CG,
+	MC_CITF_MISC_VM_CG,
+	VM_L2_CG,
+};
+
+static void si_enable_mc_ls(struct radeon_device *rdev,
+			    bool enable)
+{
+	int i;
+	u32 orig, data;
+
+	for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
+		orig = data = RREG32(mc_cg_registers[i]);
+		if (enable)
+			data |= MC_LS_ENABLE;
+		else
+			data &= ~MC_LS_ENABLE;
+		if (data != orig)
+			WREG32(mc_cg_registers[i], data);
+	}
+}
+
+
+static void si_init_cg(struct radeon_device *rdev)
+{
+	si_enable_mgcg(rdev, true);
+	si_enable_cgcg(rdev, false);
+	/* disable MC LS on Tahiti */
+	if (rdev->family == CHIP_TAHITI)
+		si_enable_mc_ls(rdev, false);
+	if (rdev->has_uvd) {
+		si_enable_uvd_mgcg(rdev, true);
+		si_init_uvd_internal_cg(rdev);
+	}
+}
+
+static void si_fini_cg(struct radeon_device *rdev)
+{
+	if (rdev->has_uvd)
+		si_enable_uvd_mgcg(rdev, false);
+	si_enable_cgcg(rdev, false);
+	si_enable_mgcg(rdev, false);
+}
+
+static void si_init_pg(struct radeon_device *rdev)
+{
+	bool has_pg = false;
+#if 0
+	/* only cape verde supports PG */
+	if (rdev->family == CHIP_VERDE)
+		has_pg = true;
+#endif
+	if (has_pg) {
+		si_init_ao_cu_mask(rdev);
+		si_init_dma_pg(rdev);
+		si_enable_dma_pg(rdev, true);
+		si_init_gfx_cgpg(rdev);
+		si_enable_gfx_cgpg(rdev, true);
+	} else {
+		WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
+		WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
+	}
+}
+
+static void si_fini_pg(struct radeon_device *rdev)
+{
+	bool has_pg = false;
+
+	/* only cape verde supports PG */
+	if (rdev->family == CHIP_VERDE)
+		has_pg = true;
+
+	if (has_pg) {
+		si_enable_dma_pg(rdev, false);
+		si_enable_gfx_cgpg(rdev, false);
+	}
+}
+
+/*
  * RLC
  */
 void si_rlc_fini(struct radeon_device *rdev)
@@ -4289,8 +5275,15 @@ void si_rlc_fini(struct radeon_device *r
 	}
 }
 
+#define RLC_CLEAR_STATE_END_MARKER          0x00000001
+
 int si_rlc_init(struct radeon_device *rdev)
 {
+	volatile u32 *dst_ptr;
+	u32 dws, data, i, j, k, reg_num;
+	u32 reg_list_num, reg_list_hdr_blk_index, reg_list_blk_index;
+	u64 reg_list_mc_addr;
+	const struct cs_section_def *cs_data = si_cs_data;
 	int r;
 
 	/* save restore block */
@@ -4311,18 +5304,44 @@ int si_rlc_init(struct radeon_device *rd
 	}
 	r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
 			  &rdev->rlc.save_restore_gpu_addr);
-	radeon_bo_unreserve(rdev->rlc.save_restore_obj);
 	if (r) {
+		radeon_bo_unreserve(rdev->rlc.save_restore_obj);
 		dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
 		si_rlc_fini(rdev);
 		return r;
 	}
 
+	if (rdev->family == CHIP_VERDE) {
+		r = radeon_bo_kmap(rdev->rlc.save_restore_obj, (void **)&rdev->rlc.sr_ptr);
+		if (r) {
+			dev_warn(rdev->dev, "(%d) map RLC sr bo failed\n", r);
+			si_rlc_fini(rdev);
+		return r;
+		}
+		/* write the sr buffer */
+		dst_ptr = rdev->rlc.sr_ptr;
+		for (i = 0; i < ARRAY_SIZE(verde_rlc_save_restore_register_list); i++) {
+			dst_ptr[i] = verde_rlc_save_restore_register_list[i];
+		}
+		radeon_bo_kunmap(rdev->rlc.save_restore_obj);
+	}
+	radeon_bo_unreserve(rdev->rlc.save_restore_obj);
+
 	/* clear state block */
+	reg_list_num = 0;
+	dws = 0;
+	for (i = 0; cs_data[i].section != NULL; i++) {
+		for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
+			reg_list_num++;
+			dws += cs_data[i].section[j].reg_count;
+		}
+	}
+	reg_list_blk_index = (3 * reg_list_num + 2);
+	dws += reg_list_blk_index;
+
 	if (rdev->rlc.clear_state_obj == NULL) {
-		r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
-				     RADEON_GEM_DOMAIN_VRAM, NULL,
-				     &rdev->rlc.clear_state_obj);
+		r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
+				     RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.clear_state_obj);
 		if (r) {
 			dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
 			si_rlc_fini(rdev);
@@ -4336,24 +5355,113 @@ int si_rlc_init(struct radeon_device *rd
 	}
 	r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
 			  &rdev->rlc.clear_state_gpu_addr);
-	radeon_bo_unreserve(rdev->rlc.clear_state_obj);
 	if (r) {
+
+		radeon_bo_unreserve(rdev->rlc.clear_state_obj);
 		dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
 		si_rlc_fini(rdev);
 		return r;
 	}
+	r = radeon_bo_kmap(rdev->rlc.clear_state_obj, (void **)&rdev->rlc.cs_ptr);
+	if (r) {
+		dev_warn(rdev->dev, "(%d) map RLC c bo failed\n", r);
+		si_rlc_fini(rdev);
+		return r;
+	}
+	/* set up the cs buffer */
+	dst_ptr = rdev->rlc.cs_ptr;
+	reg_list_hdr_blk_index = 0;
+	reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4);
+	data = upper_32_bits(reg_list_mc_addr);
+	dst_ptr[reg_list_hdr_blk_index] = data;
+	reg_list_hdr_blk_index++;
+	for (i = 0; cs_data[i].section != NULL; i++) {
+		for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
+			reg_num = cs_data[i].section[j].reg_count;
+			data = reg_list_mc_addr & 0xffffffff;
+			dst_ptr[reg_list_hdr_blk_index] = data;
+			reg_list_hdr_blk_index++;
+
+			data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff;
+			dst_ptr[reg_list_hdr_blk_index] = data;
+			reg_list_hdr_blk_index++;
+
+			data = 0x08000000 | (reg_num * 4);
+			dst_ptr[reg_list_hdr_blk_index] = data;
+			reg_list_hdr_blk_index++;
+
+			for (k = 0; k < reg_num; k++) {
+				data = cs_data[i].section[j].extent[k];
+				dst_ptr[reg_list_blk_index + k] = data;
+			}
+			reg_list_mc_addr += reg_num * 4;
+			reg_list_blk_index += reg_num;
+		}
+	}
+	dst_ptr[reg_list_hdr_blk_index] = RLC_CLEAR_STATE_END_MARKER;
+
+	radeon_bo_kunmap(rdev->rlc.clear_state_obj);
+	radeon_bo_unreserve(rdev->rlc.clear_state_obj);
 
 	return 0;
 }
 
+static void si_rlc_reset(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32(GRBM_SOFT_RESET);
+
+	tmp |= SOFT_RESET_RLC;
+	WREG32(GRBM_SOFT_RESET, tmp);
+	udelay(50);
+	tmp &= ~SOFT_RESET_RLC;
+	WREG32(GRBM_SOFT_RESET, tmp);
+	udelay(50);
+}
+
 static void si_rlc_stop(struct radeon_device *rdev)
 {
 	WREG32(RLC_CNTL, 0);
+
+	si_enable_gui_idle_interrupt(rdev, false);
+
+	si_wait_for_rlc_serdes(rdev);
 }
 
 static void si_rlc_start(struct radeon_device *rdev)
 {
 	WREG32(RLC_CNTL, RLC_ENABLE);
+
+	si_enable_gui_idle_interrupt(rdev, true);
+
+	udelay(50);
+}
+
+static bool si_lbpw_supported(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	/* Enable LBPW only for DDR3 */
+	tmp = RREG32(MC_SEQ_MISC0);
+	if ((tmp & 0xF0000000) == 0xB0000000)
+		return true;
+	return false;
+}
+
+static void si_enable_lbpw(struct radeon_device *rdev, bool enable)
+{
+	u32 tmp;
+
+	tmp = RREG32(RLC_LB_CNTL);
+	if (enable)
+		tmp |= LOAD_BALANCE_ENABLE;
+	else
+		tmp &= ~LOAD_BALANCE_ENABLE;
+	WREG32(RLC_LB_CNTL, tmp);
+
+	if (!enable) {
+		si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
+		WREG32(SPI_LB_CU_MASK, 0x00ff);
+	}
 }
 
 static int si_rlc_resume(struct radeon_device *rdev)
@@ -4366,14 +5474,18 @@ static int si_rlc_resume(struct radeon_d
 
 	si_rlc_stop(rdev);
 
+	si_rlc_reset(rdev);
+
+	si_init_pg(rdev);
+
+	si_init_cg(rdev);
+
 	WREG32(RLC_RL_BASE, 0);
 	WREG32(RLC_RL_SIZE, 0);
 	WREG32(RLC_LB_CNTL, 0);
 	WREG32(RLC_LB_CNTR_MAX, 0xffffffff);
 	WREG32(RLC_LB_CNTR_INIT, 0);
-
-	WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
-	WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
+	WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff);
 
 	WREG32(RLC_MC_CNTL, 0);
 	WREG32(RLC_UCODE_CNTL, 0);
@@ -4385,6 +5497,8 @@ static int si_rlc_resume(struct radeon_d
 	}
 	WREG32(RLC_UCODE_ADDR, 0);
 
+	si_enable_lbpw(rdev, si_lbpw_supported(rdev));
+
 	si_rlc_start(rdev);
 
 	return 0;
@@ -4554,6 +5668,7 @@ int si_irq_set(struct radeon_device *rde
 	u32 grbm_int_cntl = 0;
 	u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
 	u32 dma_cntl, dma_cntl1;
+	u32 thermal_int = 0;
 
 	if (!rdev->irq.installed) {
 		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
@@ -4579,6 +5694,9 @@ int si_irq_set(struct radeon_device *rde
 	dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
 	dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
 
+	thermal_int = RREG32(CG_THERMAL_INT) &
+		~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
+
 	/* enable CP interrupts on all rings */
 	if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
 		DRM_DEBUG("si_irq_set: sw int gfx\n");
@@ -4665,6 +5783,11 @@ int si_irq_set(struct radeon_device *rde
 
 	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
 
+	if (rdev->irq.dpm_thermal) {
+		DRM_DEBUG("dpm thermal\n");
+		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
+	}
+
 	if (rdev->num_crtc >= 2) {
 		WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
 		WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
@@ -4700,6 +5823,8 @@ int si_irq_set(struct radeon_device *rde
 		WREG32(DC_HPD6_INT_CONTROL, hpd6);
 	}
 
+	WREG32(CG_THERMAL_INT, thermal_int);
+
 	return 0;
 }
 
@@ -4864,6 +5989,8 @@ int si_irq_process(struct radeon_device
 	u32 src_id, src_data, ring_id;
 	u32 ring_index;
 	bool queue_hotplug = false;
+	bool queue_thermal = false;
+	u32 status, addr;
 
 	if (!rdev->ih.enabled || rdev->shutdown)
 		return IRQ_NONE;
@@ -5099,11 +6226,14 @@ restart_ih:
 			break;
 		case 146:
 		case 147:
+			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
+			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
 			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
-				RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
+				addr);
 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
-				RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
+				status);
+			si_vm_decode_fault(rdev, status, addr);
 			/* reset addr and status */
 			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
 			break;
@@ -5134,6 +6264,16 @@ restart_ih:
 			DRM_DEBUG("IH: DMA trap\n");
 			radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
 			break;
+		case 230: /* thermal low to high */
+			DRM_DEBUG("IH: thermal low to high\n");
+			rdev->pm.dpm.thermal.high_to_low = false;
+			queue_thermal = true;
+			break;
+		case 231: /* thermal high to low */
+			DRM_DEBUG("IH: thermal high to low\n");
+			rdev->pm.dpm.thermal.high_to_low = true;
+			queue_thermal = true;
+			break;
 		case 233: /* GUI IDLE */
 			DRM_DEBUG("IH: GUI idle\n");
 			break;
@@ -5152,6 +6292,8 @@ restart_ih:
 	}
 	if (queue_hotplug)
 		schedule_work(&rdev->hotplug_work);
+	if (queue_thermal && rdev->pm.dpm_enabled)
+		schedule_work(&rdev->pm.dpm.thermal.work);
 	rdev->ih.rptr = rptr;
 	WREG32(IH_RB_RPTR, rdev->ih.rptr);
 	atomic_set(&rdev->ih.lock, 0);
@@ -5246,6 +6388,13 @@ static int si_startup(struct radeon_devi
 	struct radeon_ring *ring;
 	int r;
 
+	/* enable pcie gen2/3 link */
+	si_pcie_gen3_enable(rdev);
+	/* enable aspm */
+	si_program_aspm(rdev);
+
+	si_mc_program(rdev);
+
 	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
 	    !rdev->rlc_fw || !rdev->mc_fw) {
 		r = si_init_microcode(rdev);
@@ -5265,7 +6414,6 @@ static int si_startup(struct radeon_devi
 	if (r)
 		return r;
 
-	si_mc_program(rdev);
 	r = si_pcie_gart_enable(rdev);
 	if (r)
 		return r;
@@ -5449,7 +6597,7 @@ int si_suspend(struct radeon_device *rde
 	si_cp_enable(rdev, false);
 	cayman_dma_stop(rdev);
 	if (rdev->has_uvd) {
-		r600_uvd_rbc_stop(rdev);
+		r600_uvd_stop(rdev);
 		radeon_uvd_suspend(rdev);
 	}
 	si_irq_suspend(rdev);
@@ -5585,12 +6733,16 @@ void si_fini(struct radeon_device *rdev)
 	cayman_dma_fini(rdev);
 	si_irq_fini(rdev);
 	si_rlc_fini(rdev);
+	si_fini_cg(rdev);
+	si_fini_pg(rdev);
 	radeon_wb_fini(rdev);
 	radeon_vm_manager_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
-	if (rdev->has_uvd)
+	if (rdev->has_uvd) {
+		r600_uvd_stop(rdev);
 		radeon_uvd_fini(rdev);
+	}
 	si_pcie_gart_fini(rdev);
 	r600_vram_scratch_fini(rdev);
 	radeon_gem_fini(rdev);
@@ -5711,3 +6863,364 @@ int si_set_uvd_clocks(struct radeon_devi
 
 	return 0;
 }
+
+static void si_pcie_gen3_enable(struct radeon_device *rdev)
+{
+	struct pci_dev *root = rdev->pdev->bus->self;
+	int bridge_pos, gpu_pos;
+	u32 speed_cntl, mask, current_data_rate;
+	int ret, i;
+	u16 tmp16;
+
+	if (radeon_pcie_gen2 == 0)
+		return;
+
+	if (rdev->flags & RADEON_IS_IGP)
+		return;
+
+	if (!(rdev->flags & RADEON_IS_PCIE))
+		return;
+
+	ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
+	if (ret != 0)
+		return;
+
+	if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
+		return;
+
+	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+	current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >>
+		LC_CURRENT_DATA_RATE_SHIFT;
+	if (mask & DRM_PCIE_SPEED_80) {
+		if (current_data_rate == 2) {
+			DRM_INFO("PCIE gen 3 link speeds already enabled\n");
+			return;
+		}
+		DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n");
+	} else if (mask & DRM_PCIE_SPEED_50) {
+		if (current_data_rate == 1) {
+			DRM_INFO("PCIE gen 2 link speeds already enabled\n");
+			return;
+		}
+		DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
+	}
+
+	bridge_pos = pci_pcie_cap(root);
+	if (!bridge_pos)
+		return;
+
+	gpu_pos = pci_pcie_cap(rdev->pdev);
+	if (!gpu_pos)
+		return;
+
+	if (mask & DRM_PCIE_SPEED_80) {
+		/* re-try equalization if gen3 is not already enabled */
+		if (current_data_rate != 2) {
+			u16 bridge_cfg, gpu_cfg;
+			u16 bridge_cfg2, gpu_cfg2;
+			u32 max_lw, current_lw, tmp;
+
+			pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg);
+			pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg);
+
+			tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
+			pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16);
+
+			tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
+			pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16);
+
+			tmp = RREG32_PCIE(PCIE_LC_STATUS1);
+			max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
+			current_lw = (tmp & LC_OPERATING_LINK_WIDTH_MASK) >> LC_OPERATING_LINK_WIDTH_SHIFT;
+
+			if (current_lw < max_lw) {
+				tmp = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
+				if (tmp & LC_RENEGOTIATION_SUPPORT) {
+					tmp &= ~(LC_LINK_WIDTH_MASK | LC_UPCONFIGURE_DIS);
+					tmp |= (max_lw << LC_LINK_WIDTH_SHIFT);
+					tmp |= LC_UPCONFIGURE_SUPPORT | LC_RENEGOTIATE_EN | LC_RECONFIG_NOW;
+					WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, tmp);
+				}
+			}
+
+			for (i = 0; i < 10; i++) {
+				/* check status */
+				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_DEVSTA, &tmp16);
+				if (tmp16 & PCI_EXP_DEVSTA_TRPND)
+					break;
+
+				pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg);
+				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg);
+
+				pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &bridge_cfg2);
+				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &gpu_cfg2);
+
+				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
+				tmp |= LC_SET_QUIESCE;
+				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
+
+				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
+				tmp |= LC_REDO_EQ;
+				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
+
+				mdelay(100);
+
+				/* linkctl */
+				pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &tmp16);
+				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+				tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
+				pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16);
+
+				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &tmp16);
+				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
+				tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
+				pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16);
+
+				/* linkctl2 */
+				pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &tmp16);
+				tmp16 &= ~((1 << 4) | (7 << 9));
+				tmp16 |= (bridge_cfg2 & ((1 << 4) | (7 << 9)));
+				pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, tmp16);
+
+				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
+				tmp16 &= ~((1 << 4) | (7 << 9));
+				tmp16 |= (gpu_cfg2 & ((1 << 4) | (7 << 9)));
+				pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16);
+
+				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
+				tmp &= ~LC_SET_QUIESCE;
+				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
+			}
+		}
+	}
+
+	/* set the link speed */
+	speed_cntl |= LC_FORCE_EN_SW_SPEED_CHANGE | LC_FORCE_DIS_HW_SPEED_CHANGE;
+	speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE;
+	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+	pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
+	tmp16 &= ~0xf;
+	if (mask & DRM_PCIE_SPEED_80)
+		tmp16 |= 3; /* gen3 */
+	else if (mask & DRM_PCIE_SPEED_50)
+		tmp16 |= 2; /* gen2 */
+	else
+		tmp16 |= 1; /* gen1 */
+	pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16);
+
+	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+	speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE;
+	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+		if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0)
+			break;
+		udelay(1);
+	}
+}
+
+static void si_program_aspm(struct radeon_device *rdev)
+{
+	u32 data, orig;
+	bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
+	bool disable_clkreq = false;
+
+	if (radeon_aspm == 0)
+		return;
+
+	if (!(rdev->flags & RADEON_IS_PCIE))
+		return;
+
+	orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
+	data &= ~LC_XMIT_N_FTS_MASK;
+	data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN;
+	if (orig != data)
+		WREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL, data);
+
+	orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL3);
+	data |= LC_GO_TO_RECOVERY;
+	if (orig != data)
+		WREG32_PCIE_PORT(PCIE_LC_CNTL3, data);
+
+	orig = data = RREG32_PCIE(PCIE_P_CNTL);
+	data |= P_IGNORE_EDB_ERR;
+	if (orig != data)
+		WREG32_PCIE(PCIE_P_CNTL, data);
+
+	orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
+	data &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
+	data |= LC_PMI_TO_L1_DIS;
+	if (!disable_l0s)
+		data |= LC_L0S_INACTIVITY(7);
+
+	if (!disable_l1) {
+		data |= LC_L1_INACTIVITY(7);
+		data &= ~LC_PMI_TO_L1_DIS;
+		if (orig != data)
+			WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
+
+		if (!disable_plloff_in_l1) {
+			bool clk_req_support;
+
+			orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
+			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
+			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
+			if (orig != data)
+				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
+
+			orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
+			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
+			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
+			if (orig != data)
+				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
+
+			orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
+			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
+			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
+			if (orig != data)
+				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
+
+			orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
+			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
+			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
+			if (orig != data)
+				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
+
+			if ((rdev->family != CHIP_OLAND) && (rdev->family != CHIP_HAINAN)) {
+				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
+				data &= ~PLL_RAMP_UP_TIME_0_MASK;
+				if (orig != data)
+					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
+
+				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
+				data &= ~PLL_RAMP_UP_TIME_1_MASK;
+				if (orig != data)
+					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
+
+				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2);
+				data &= ~PLL_RAMP_UP_TIME_2_MASK;
+				if (orig != data)
+					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2, data);
+
+				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3);
+				data &= ~PLL_RAMP_UP_TIME_3_MASK;
+				if (orig != data)
+					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3, data);
+
+				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
+				data &= ~PLL_RAMP_UP_TIME_0_MASK;
+				if (orig != data)
+					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
+
+				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
+				data &= ~PLL_RAMP_UP_TIME_1_MASK;
+				if (orig != data)
+					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
+
+				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2);
+				data &= ~PLL_RAMP_UP_TIME_2_MASK;
+				if (orig != data)
+					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2, data);
+
+				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3);
+				data &= ~PLL_RAMP_UP_TIME_3_MASK;
+				if (orig != data)
+					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3, data);
+			}
+			orig = data = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
+			data &= ~LC_DYN_LANES_PWR_STATE_MASK;
+			data |= LC_DYN_LANES_PWR_STATE(3);
+			if (orig != data)
+				WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
+
+			orig = data = RREG32_PIF_PHY0(PB0_PIF_CNTL);
+			data &= ~LS2_EXIT_TIME_MASK;
+			if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
+				data |= LS2_EXIT_TIME(5);
+			if (orig != data)
+				WREG32_PIF_PHY0(PB0_PIF_CNTL, data);
+
+			orig = data = RREG32_PIF_PHY1(PB1_PIF_CNTL);
+			data &= ~LS2_EXIT_TIME_MASK;
+			if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
+				data |= LS2_EXIT_TIME(5);
+			if (orig != data)
+				WREG32_PIF_PHY1(PB1_PIF_CNTL, data);
+
+			if (!disable_clkreq) {
+				struct pci_dev *root = rdev->pdev->bus->self;
+				u32 lnkcap;
+
+				clk_req_support = false;
+				pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
+				if (lnkcap & PCI_EXP_LNKCAP_CLKPM)
+					clk_req_support = true;
+			} else {
+				clk_req_support = false;
+			}
+
+			if (clk_req_support) {
+				orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL2);
+				data |= LC_ALLOW_PDWN_IN_L1 | LC_ALLOW_PDWN_IN_L23;
+				if (orig != data)
+					WREG32_PCIE_PORT(PCIE_LC_CNTL2, data);
+
+				orig = data = RREG32(THM_CLK_CNTL);
+				data &= ~(CMON_CLK_SEL_MASK | TMON_CLK_SEL_MASK);
+				data |= CMON_CLK_SEL(1) | TMON_CLK_SEL(1);
+				if (orig != data)
+					WREG32(THM_CLK_CNTL, data);
+
+				orig = data = RREG32(MISC_CLK_CNTL);
+				data &= ~(DEEP_SLEEP_CLK_SEL_MASK | ZCLK_SEL_MASK);
+				data |= DEEP_SLEEP_CLK_SEL(1) | ZCLK_SEL(1);
+				if (orig != data)
+					WREG32(MISC_CLK_CNTL, data);
+
+				orig = data = RREG32(CG_CLKPIN_CNTL);
+				data &= ~BCLK_AS_XCLK;
+				if (orig != data)
+					WREG32(CG_CLKPIN_CNTL, data);
+
+				orig = data = RREG32(CG_CLKPIN_CNTL_2);
+				data &= ~FORCE_BIF_REFCLK_EN;
+				if (orig != data)
+					WREG32(CG_CLKPIN_CNTL_2, data);
+
+				orig = data = RREG32(MPLL_BYPASSCLK_SEL);
+				data &= ~MPLL_CLKOUT_SEL_MASK;
+				data |= MPLL_CLKOUT_SEL(4);
+				if (orig != data)
+					WREG32(MPLL_BYPASSCLK_SEL, data);
+
+				orig = data = RREG32(SPLL_CNTL_MODE);
+				data &= ~SPLL_REFCLK_SEL_MASK;
+				if (orig != data)
+					WREG32(SPLL_CNTL_MODE, data);
+			}
+		}
+	} else {
+		if (orig != data)
+			WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
+	}
+
+	orig = data = RREG32_PCIE(PCIE_CNTL2);
+	data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | REPLAY_MEM_LS_EN;
+	if (orig != data)
+		WREG32_PCIE(PCIE_CNTL2, data);
+
+	if (!disable_l0s) {
+		data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
+		if((data & LC_N_FTS_MASK) == LC_N_FTS_MASK) {
+			data = RREG32_PCIE(PCIE_LC_STATUS1);
+			if ((data & LC_REVERSE_XMIT) && (data & LC_REVERSE_RCVR)) {
+				orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
+				data &= ~LC_L0S_INACTIVITY_MASK;
+				if (orig != data)
+					WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
+			}
+		}
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sid.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sid.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sid.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sid.h	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,94 @@
 #define VERDE_GB_ADDR_CONFIG_GOLDEN         0x12010002
 #define HAINAN_GB_ADDR_CONFIG_GOLDEN        0x02010001
 
+#define SI_MAX_SH_GPRS           256
+#define SI_MAX_TEMP_GPRS         16
+#define SI_MAX_SH_THREADS        256
+#define SI_MAX_SH_STACK_ENTRIES  4096
+#define SI_MAX_FRC_EOV_CNT       16384
+#define SI_MAX_BACKENDS          8
+#define SI_MAX_BACKENDS_MASK     0xFF
+#define SI_MAX_BACKENDS_PER_SE_MASK     0x0F
+#define SI_MAX_SIMDS             12
+#define SI_MAX_SIMDS_MASK        0x0FFF
+#define SI_MAX_SIMDS_PER_SE_MASK        0x00FF
+#define SI_MAX_PIPES             8
+#define SI_MAX_PIPES_MASK        0xFF
+#define SI_MAX_PIPES_PER_SIMD_MASK      0x3F
+#define SI_MAX_LDS_NUM           0xFFFF
+#define SI_MAX_TCC               16
+#define SI_MAX_TCC_MASK          0xFFFF
+
+/* SMC IND accessor regs */
+#define SMC_IND_INDEX_0                              0x200
+#define SMC_IND_DATA_0                               0x204
+
+#define SMC_IND_ACCESS_CNTL                          0x228
+#       define AUTO_INCREMENT_IND_0                  (1 << 0)
+#define SMC_MESSAGE_0                                0x22c
+#define SMC_RESP_0                                   0x230
+
+/* CG IND registers are accessed via SMC indirect space + SMC_CG_IND_START */
+#define SMC_CG_IND_START                    0xc0030000
+#define SMC_CG_IND_END                      0xc0040000
+
+#define	CG_CGTT_LOCAL_0				0x400
+#define	CG_CGTT_LOCAL_1				0x401
+
+/* SMC IND registers */
+#define	SMC_SYSCON_RESET_CNTL				0x80000000
+#       define RST_REG                                  (1 << 0)
+#define	SMC_SYSCON_CLOCK_CNTL_0				0x80000004
+#       define CK_DISABLE                               (1 << 0)
+#       define CKEN                                     (1 << 24)
+
+#define VGA_HDP_CONTROL  				0x328
+#define		VGA_MEMORY_DISABLE				(1 << 4)
+
+#define DCCG_DISP_SLOW_SELECT_REG                       0x4fc
+#define		DCCG_DISP1_SLOW_SELECT(x)		((x) << 0)
+#define		DCCG_DISP1_SLOW_SELECT_MASK		(7 << 0)
+#define		DCCG_DISP1_SLOW_SELECT_SHIFT		0
+#define		DCCG_DISP2_SLOW_SELECT(x)		((x) << 4)
+#define		DCCG_DISP2_SLOW_SELECT_MASK		(7 << 4)
+#define		DCCG_DISP2_SLOW_SELECT_SHIFT		4
+
+#define	CG_SPLL_FUNC_CNTL				0x600
+#define		SPLL_RESET				(1 << 0)
+#define		SPLL_SLEEP				(1 << 1)
+#define		SPLL_BYPASS_EN				(1 << 3)
+#define		SPLL_REF_DIV(x)				((x) << 4)
+#define		SPLL_REF_DIV_MASK			(0x3f << 4)
+#define		SPLL_PDIV_A(x)				((x) << 20)
+#define		SPLL_PDIV_A_MASK			(0x7f << 20)
+#define		SPLL_PDIV_A_SHIFT			20
+#define	CG_SPLL_FUNC_CNTL_2				0x604
+#define		SCLK_MUX_SEL(x)				((x) << 0)
+#define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define	CG_SPLL_FUNC_CNTL_3				0x608
+#define		SPLL_FB_DIV(x)				((x) << 0)
+#define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
+#define		SPLL_FB_DIV_SHIFT			0
+#define		SPLL_DITHEN				(1 << 28)
+#define	CG_SPLL_FUNC_CNTL_4				0x60c
+
+#define	SPLL_CNTL_MODE					0x618
+#	define SPLL_REFCLK_SEL(x)			((x) << 8)
+#	define SPLL_REFCLK_SEL_MASK			0xFF00
+
+#define	CG_SPLL_SPREAD_SPECTRUM				0x620
+#define		SSEN					(1 << 0)
+#define		CLK_S(x)				((x) << 4)
+#define		CLK_S_MASK				(0xfff << 4)
+#define		CLK_S_SHIFT				4
+#define	CG_SPLL_SPREAD_SPECTRUM_2			0x624
+#define		CLK_V(x)				((x) << 0)
+#define		CLK_V_MASK				(0x3ffffff << 0)
+#define		CLK_V_SHIFT				0
+
+#define	CG_SPLL_AUTOSCALE_CNTL				0x62c
+#       define AUTOSCALE_ON_SS_CLEAR                    (1 << 9)
+
 /* discrete uvd clocks */
 #define	CG_UPLL_FUNC_CNTL				0x634
 #	define UPLL_RESET_MASK				0x00000001
@@ -59,6 +147,45 @@
 #define	CG_UPLL_SPREAD_SPECTRUM				0x650
 #	define SSEN_MASK				0x00000001
 
+#define	MPLL_BYPASSCLK_SEL				0x65c
+#	define MPLL_CLKOUT_SEL(x)			((x) << 8)
+#	define MPLL_CLKOUT_SEL_MASK			0xFF00
+
+#define CG_CLKPIN_CNTL                                    0x660
+#       define XTALIN_DIVIDE                              (1 << 1)
+#       define BCLK_AS_XCLK                               (1 << 2)
+#define CG_CLKPIN_CNTL_2                                  0x664
+#       define FORCE_BIF_REFCLK_EN                        (1 << 3)
+#       define MUX_TCLK_TO_XCLK                           (1 << 8)
+
+#define	THM_CLK_CNTL					0x66c
+#	define CMON_CLK_SEL(x)				((x) << 0)
+#	define CMON_CLK_SEL_MASK			0xFF
+#	define TMON_CLK_SEL(x)				((x) << 8)
+#	define TMON_CLK_SEL_MASK			0xFF00
+#define	MISC_CLK_CNTL					0x670
+#	define DEEP_SLEEP_CLK_SEL(x)			((x) << 0)
+#	define DEEP_SLEEP_CLK_SEL_MASK			0xFF
+#	define ZCLK_SEL(x)				((x) << 8)
+#	define ZCLK_SEL_MASK				0xFF00
+
+#define	CG_THERMAL_CTRL					0x700
+#define 	DPM_EVENT_SRC(x)			((x) << 0)
+#define 	DPM_EVENT_SRC_MASK			(7 << 0)
+#define		DIG_THERM_DPM(x)			((x) << 14)
+#define		DIG_THERM_DPM_MASK			0x003FC000
+#define		DIG_THERM_DPM_SHIFT			14
+
+#define	CG_THERMAL_INT					0x708
+#define		DIG_THERM_INTH(x)			((x) << 8)
+#define		DIG_THERM_INTH_MASK			0x0000FF00
+#define		DIG_THERM_INTH_SHIFT			8
+#define		DIG_THERM_INTL(x)			((x) << 16)
+#define		DIG_THERM_INTL_MASK			0x00FF0000
+#define		DIG_THERM_INTL_SHIFT			16
+#define 	THERM_INT_MASK_HIGH			(1 << 24)
+#define 	THERM_INT_MASK_LOW			(1 << 25)
+
 #define	CG_MULT_THERMAL_STATUS					0x714
 #define		ASIC_MAX_TEMP(x)				((x) << 0)
 #define		ASIC_MAX_TEMP_MASK				0x000001ff
@@ -67,31 +194,89 @@
 #define		CTF_TEMP_MASK					0x0003fe00
 #define		CTF_TEMP_SHIFT					9
 
-#define SI_MAX_SH_GPRS           256
-#define SI_MAX_TEMP_GPRS         16
-#define SI_MAX_SH_THREADS        256
-#define SI_MAX_SH_STACK_ENTRIES  4096
-#define SI_MAX_FRC_EOV_CNT       16384
-#define SI_MAX_BACKENDS          8
-#define SI_MAX_BACKENDS_MASK     0xFF
-#define SI_MAX_BACKENDS_PER_SE_MASK     0x0F
-#define SI_MAX_SIMDS             12
-#define SI_MAX_SIMDS_MASK        0x0FFF
-#define SI_MAX_SIMDS_PER_SE_MASK        0x00FF
-#define SI_MAX_PIPES             8
-#define SI_MAX_PIPES_MASK        0xFF
-#define SI_MAX_PIPES_PER_SIMD_MASK      0x3F
-#define SI_MAX_LDS_NUM           0xFFFF
-#define SI_MAX_TCC               16
-#define SI_MAX_TCC_MASK          0xFFFF
+#define GENERAL_PWRMGT                                  0x780
+#       define GLOBAL_PWRMGT_EN                         (1 << 0)
+#       define STATIC_PM_EN                             (1 << 1)
+#       define THERMAL_PROTECTION_DIS                   (1 << 2)
+#       define THERMAL_PROTECTION_TYPE                  (1 << 3)
+#       define SW_SMIO_INDEX(x)                         ((x) << 6)
+#       define SW_SMIO_INDEX_MASK                       (1 << 6)
+#       define SW_SMIO_INDEX_SHIFT                      6
+#       define VOLT_PWRMGT_EN                           (1 << 10)
+#       define DYN_SPREAD_SPECTRUM_EN                   (1 << 23)
+#define CG_TPC                                            0x784
+#define SCLK_PWRMGT_CNTL                                  0x788
+#       define SCLK_PWRMGT_OFF                            (1 << 0)
+#       define SCLK_LOW_D1                                (1 << 1)
+#       define FIR_RESET                                  (1 << 4)
+#       define FIR_FORCE_TREND_SEL                        (1 << 5)
+#       define FIR_TREND_MODE                             (1 << 6)
+#       define DYN_GFX_CLK_OFF_EN                         (1 << 7)
+#       define GFX_CLK_FORCE_ON                           (1 << 8)
+#       define GFX_CLK_REQUEST_OFF                        (1 << 9)
+#       define GFX_CLK_FORCE_OFF                          (1 << 10)
+#       define GFX_CLK_OFF_ACPI_D1                        (1 << 11)
+#       define GFX_CLK_OFF_ACPI_D2                        (1 << 12)
+#       define GFX_CLK_OFF_ACPI_D3                        (1 << 13)
+#       define DYN_LIGHT_SLEEP_EN                         (1 << 14)
 
-#define VGA_HDP_CONTROL  				0x328
-#define		VGA_MEMORY_DISABLE				(1 << 4)
+#define TARGET_AND_CURRENT_PROFILE_INDEX                  0x798
+#       define CURRENT_STATE_INDEX_MASK                   (0xf << 4)
+#       define CURRENT_STATE_INDEX_SHIFT                  4
 
-#define CG_CLKPIN_CNTL                                    0x660
-#       define XTALIN_DIVIDE                              (1 << 1)
-#define CG_CLKPIN_CNTL_2                                  0x664
-#       define MUX_TCLK_TO_XCLK                           (1 << 8)
+#define CG_FTV                                            0x7bc
+
+#define CG_FFCT_0                                         0x7c0
+#       define UTC_0(x)                                   ((x) << 0)
+#       define UTC_0_MASK                                 (0x3ff << 0)
+#       define DTC_0(x)                                   ((x) << 10)
+#       define DTC_0_MASK                                 (0x3ff << 10)
+
+#define CG_BSP                                          0x7fc
+#       define BSP(x)					((x) << 0)
+#       define BSP_MASK					(0xffff << 0)
+#       define BSU(x)					((x) << 16)
+#       define BSU_MASK					(0xf << 16)
+#define CG_AT                                           0x800
+#       define CG_R(x)					((x) << 0)
+#       define CG_R_MASK				(0xffff << 0)
+#       define CG_L(x)					((x) << 16)
+#       define CG_L_MASK				(0xffff << 16)
+
+#define CG_GIT                                          0x804
+#       define CG_GICST(x)                              ((x) << 0)
+#       define CG_GICST_MASK                            (0xffff << 0)
+#       define CG_GIPOT(x)                              ((x) << 16)
+#       define CG_GIPOT_MASK                            (0xffff << 16)
+
+#define CG_SSP                                            0x80c
+#       define SST(x)                                     ((x) << 0)
+#       define SST_MASK                                   (0xffff << 0)
+#       define SSTU(x)                                    ((x) << 16)
+#       define SSTU_MASK                                  (0xf << 16)
+
+#define CG_DISPLAY_GAP_CNTL                               0x828
+#       define DISP1_GAP(x)                               ((x) << 0)
+#       define DISP1_GAP_MASK                             (3 << 0)
+#       define DISP2_GAP(x)                               ((x) << 2)
+#       define DISP2_GAP_MASK                             (3 << 2)
+#       define VBI_TIMER_COUNT(x)                         ((x) << 4)
+#       define VBI_TIMER_COUNT_MASK                       (0x3fff << 4)
+#       define VBI_TIMER_UNIT(x)                          ((x) << 20)
+#       define VBI_TIMER_UNIT_MASK                        (7 << 20)
+#       define DISP1_GAP_MCHG(x)                          ((x) << 24)
+#       define DISP1_GAP_MCHG_MASK                        (3 << 24)
+#       define DISP2_GAP_MCHG(x)                          ((x) << 26)
+#       define DISP2_GAP_MCHG_MASK                        (3 << 26)
+
+#define	CG_ULV_CONTROL					0x878
+#define	CG_ULV_PARAMETER				0x87c
+
+#define	SMC_SCRATCH0					0x884
+
+#define	CG_CAC_CTRL					0x8b8
+#	define CAC_WINDOW(x)				((x) << 0)
+#	define CAC_WINDOW_MASK				0x00ffffff
 
 #define DMIF_ADDR_CONFIG  				0xBD4
 
@@ -182,6 +367,20 @@
 
 #define	VM_CONTEXT1_PROTECTION_FAULT_ADDR		0x14FC
 #define	VM_CONTEXT1_PROTECTION_FAULT_STATUS		0x14DC
+#define		PROTECTIONS_MASK			(0xf << 0)
+#define		PROTECTIONS_SHIFT			0
+		/* bit 0: range
+		 * bit 1: pde0
+		 * bit 2: valid
+		 * bit 3: read
+		 * bit 4: write
+		 */
+#define		MEMORY_CLIENT_ID_MASK			(0xff << 12)
+#define		MEMORY_CLIENT_ID_SHIFT			12
+#define		MEMORY_CLIENT_RW_MASK			(1 << 24)
+#define		MEMORY_CLIENT_RW_SHIFT			24
+#define		FAULT_VMID_MASK				(0xf << 25)
+#define		FAULT_VMID_SHIFT			25
 
 #define VM_INVALIDATE_REQUEST				0x1478
 #define VM_INVALIDATE_RESPONSE				0x147c
@@ -203,6 +402,10 @@
 #define	VM_CONTEXT0_PAGE_TABLE_END_ADDR			0x157C
 #define	VM_CONTEXT1_PAGE_TABLE_END_ADDR			0x1580
 
+#define VM_L2_CG           				0x15c0
+#define		MC_CG_ENABLE				(1 << 18)
+#define		MC_LS_ENABLE				(1 << 19)
+
 #define MC_SHARED_CHMAP						0x2004
 #define		NOOFCHAN_SHIFT					12
 #define		NOOFCHAN_MASK					0x0000f000
@@ -228,6 +431,17 @@
 
 #define MC_SHARED_BLACKOUT_CNTL           		0x20ac
 
+#define MC_HUB_MISC_HUB_CG           			0x20b8
+#define MC_HUB_MISC_VM_CG           			0x20bc
+
+#define MC_HUB_MISC_SIP_CG           			0x20c0
+
+#define MC_XPB_CLK_GAT           			0x2478
+
+#define MC_CITF_MISC_RD_CG           			0x2648
+#define MC_CITF_MISC_WR_CG           			0x264c
+#define MC_CITF_MISC_VM_CG           			0x2650
+
 #define	MC_ARB_RAMCFG					0x2760
 #define		NOOFBANK_SHIFT					0
 #define		NOOFBANK_MASK					0x00000003
@@ -243,6 +457,23 @@
 #define		NOOFGROUPS_SHIFT				12
 #define		NOOFGROUPS_MASK					0x00001000
 
+#define	MC_ARB_DRAM_TIMING				0x2774
+#define	MC_ARB_DRAM_TIMING2				0x2778
+
+#define MC_ARB_BURST_TIME                               0x2808
+#define		STATE0(x)				((x) << 0)
+#define		STATE0_MASK				(0x1f << 0)
+#define		STATE0_SHIFT				0
+#define		STATE1(x)				((x) << 5)
+#define		STATE1_MASK				(0x1f << 5)
+#define		STATE1_SHIFT				5
+#define		STATE2(x)				((x) << 10)
+#define		STATE2_MASK				(0x1f << 10)
+#define		STATE2_SHIFT				10
+#define		STATE3(x)				((x) << 15)
+#define		STATE3_MASK				(0x1f << 15)
+#define		STATE3_SHIFT				15
+
 #define	MC_SEQ_TRAIN_WAKEUP_CNTL			0x2808
 #define		TRAIN_DONE_D0      			(1 << 30)
 #define		TRAIN_DONE_D1      			(1 << 31)
@@ -250,13 +481,105 @@
 #define MC_SEQ_SUP_CNTL           			0x28c8
 #define		RUN_MASK      				(1 << 0)
 #define MC_SEQ_SUP_PGM           			0x28cc
+#define MC_PMG_AUTO_CMD           			0x28d0
 
 #define MC_IO_PAD_CNTL_D0           			0x29d0
 #define		MEM_FALL_OUT_CMD      			(1 << 8)
 
+#define MC_SEQ_RAS_TIMING                               0x28a0
+#define MC_SEQ_CAS_TIMING                               0x28a4
+#define MC_SEQ_MISC_TIMING                              0x28a8
+#define MC_SEQ_MISC_TIMING2                             0x28ac
+#define MC_SEQ_PMG_TIMING                               0x28b0
+#define MC_SEQ_RD_CTL_D0                                0x28b4
+#define MC_SEQ_RD_CTL_D1                                0x28b8
+#define MC_SEQ_WR_CTL_D0                                0x28bc
+#define MC_SEQ_WR_CTL_D1                                0x28c0
+
+#define MC_SEQ_MISC0           				0x2a00
+#define 	MC_SEQ_MISC0_VEN_ID_SHIFT               8
+#define 	MC_SEQ_MISC0_VEN_ID_MASK                0x00000f00
+#define 	MC_SEQ_MISC0_VEN_ID_VALUE               3
+#define 	MC_SEQ_MISC0_REV_ID_SHIFT               12
+#define 	MC_SEQ_MISC0_REV_ID_MASK                0x0000f000
+#define 	MC_SEQ_MISC0_REV_ID_VALUE               1
+#define 	MC_SEQ_MISC0_GDDR5_SHIFT                28
+#define 	MC_SEQ_MISC0_GDDR5_MASK                 0xf0000000
+#define 	MC_SEQ_MISC0_GDDR5_VALUE                5
+#define MC_SEQ_MISC1                                    0x2a04
+#define MC_SEQ_RESERVE_M                                0x2a08
+#define MC_PMG_CMD_EMRS                                 0x2a0c
+
 #define MC_SEQ_IO_DEBUG_INDEX           		0x2a44
 #define MC_SEQ_IO_DEBUG_DATA           			0x2a48
 
+#define MC_SEQ_MISC5                                    0x2a54
+#define MC_SEQ_MISC6                                    0x2a58
+
+#define MC_SEQ_MISC7                                    0x2a64
+
+#define MC_SEQ_RAS_TIMING_LP                            0x2a6c
+#define MC_SEQ_CAS_TIMING_LP                            0x2a70
+#define MC_SEQ_MISC_TIMING_LP                           0x2a74
+#define MC_SEQ_MISC_TIMING2_LP                          0x2a78
+#define MC_SEQ_WR_CTL_D0_LP                             0x2a7c
+#define MC_SEQ_WR_CTL_D1_LP                             0x2a80
+#define MC_SEQ_PMG_CMD_EMRS_LP                          0x2a84
+#define MC_SEQ_PMG_CMD_MRS_LP                           0x2a88
+
+#define MC_PMG_CMD_MRS                                  0x2aac
+
+#define MC_SEQ_RD_CTL_D0_LP                             0x2b1c
+#define MC_SEQ_RD_CTL_D1_LP                             0x2b20
+
+#define MC_PMG_CMD_MRS1                                 0x2b44
+#define MC_SEQ_PMG_CMD_MRS1_LP                          0x2b48
+#define MC_SEQ_PMG_TIMING_LP                            0x2b4c
+
+#define MC_SEQ_WR_CTL_2                                 0x2b54
+#define MC_SEQ_WR_CTL_2_LP                              0x2b58
+#define MC_PMG_CMD_MRS2                                 0x2b5c
+#define MC_SEQ_PMG_CMD_MRS2_LP                          0x2b60
+
+#define	MCLK_PWRMGT_CNTL				0x2ba0
+#       define DLL_SPEED(x)				((x) << 0)
+#       define DLL_SPEED_MASK				(0x1f << 0)
+#       define DLL_READY                                (1 << 6)
+#       define MC_INT_CNTL                              (1 << 7)
+#       define MRDCK0_PDNB                              (1 << 8)
+#       define MRDCK1_PDNB                              (1 << 9)
+#       define MRDCK0_RESET                             (1 << 16)
+#       define MRDCK1_RESET                             (1 << 17)
+#       define DLL_READY_READ                           (1 << 24)
+#define	DLL_CNTL					0x2ba4
+#       define MRDCK0_BYPASS                            (1 << 24)
+#       define MRDCK1_BYPASS                            (1 << 25)
+
+#define	MPLL_FUNC_CNTL					0x2bb4
+#define		BWCTRL(x)				((x) << 20)
+#define		BWCTRL_MASK				(0xff << 20)
+#define	MPLL_FUNC_CNTL_1				0x2bb8
+#define		VCO_MODE(x)				((x) << 0)
+#define		VCO_MODE_MASK				(3 << 0)
+#define		CLKFRAC(x)				((x) << 4)
+#define		CLKFRAC_MASK				(0xfff << 4)
+#define		CLKF(x)					((x) << 16)
+#define		CLKF_MASK				(0xfff << 16)
+#define	MPLL_FUNC_CNTL_2				0x2bbc
+#define	MPLL_AD_FUNC_CNTL				0x2bc0
+#define		YCLK_POST_DIV(x)			((x) << 0)
+#define		YCLK_POST_DIV_MASK			(7 << 0)
+#define	MPLL_DQ_FUNC_CNTL				0x2bc4
+#define		YCLK_SEL(x)				((x) << 4)
+#define		YCLK_SEL_MASK				(1 << 4)
+
+#define	MPLL_SS1					0x2bcc
+#define		CLKV(x)					((x) << 0)
+#define		CLKV_MASK				(0x3ffffff << 0)
+#define	MPLL_SS2					0x2bd0
+#define		CLKS(x)					((x) << 0)
+#define		CLKS_MASK				(0xfff << 0)
+
 #define	HDP_HOST_PATH_CNTL				0x2C00
 #define	HDP_NONSURFACE_BASE				0x2C04
 #define	HDP_NONSURFACE_INFO				0x2C08
@@ -266,6 +589,8 @@
 #define HDP_MISC_CNTL					0x2F4C
 #define 	HDP_FLUSH_INVALIDATE_CACHE			(1 << 0)
 
+#define ATC_MISC_CG           				0x3350
+
 #define IH_RB_CNTL                                        0x3e00
 #       define IH_RB_ENABLE                               (1 << 0)
 #       define IH_IB_SIZE(x)                              ((x) << 1) /* log2 */
@@ -424,6 +749,9 @@
 #       define DC_HPDx_RX_INT_TIMER(x)                    ((x) << 16)
 #       define DC_HPDx_EN                                 (1 << 28)
 
+#define DPG_PIPE_STUTTER_CONTROL                          0x6cd4
+#       define STUTTER_ENABLE                             (1 << 0)
+
 /* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */
 #define CRTC_STATUS_FRAME_COUNT                         0x6e98
 
@@ -599,6 +927,24 @@
 
 #define	SQC_CACHES					0x8C08
 
+#define SQ_POWER_THROTTLE                               0x8e58
+#define		MIN_POWER(x)				((x) << 0)
+#define		MIN_POWER_MASK				(0x3fff << 0)
+#define		MIN_POWER_SHIFT				0
+#define		MAX_POWER(x)				((x) << 16)
+#define		MAX_POWER_MASK				(0x3fff << 16)
+#define		MAX_POWER_SHIFT				0
+#define SQ_POWER_THROTTLE2                              0x8e5c
+#define		MAX_POWER_DELTA(x)			((x) << 0)
+#define		MAX_POWER_DELTA_MASK			(0x3fff << 0)
+#define		MAX_POWER_DELTA_SHIFT			0
+#define		STI_SIZE(x)				((x) << 16)
+#define		STI_SIZE_MASK				(0x3ff << 16)
+#define		STI_SIZE_SHIFT				16
+#define		LTI_RATIO(x)				((x) << 27)
+#define		LTI_RATIO_MASK				(0xf << 27)
+#define		LTI_RATIO_SHIFT				27
+
 #define	SX_DEBUG_1					0x9060
 
 #define	SPI_STATIC_THREAD_MGMT_1			0x90E0
@@ -616,6 +962,11 @@
 #define	CGTS_USER_TCC_DISABLE				0x914C
 #define		TCC_DISABLE_MASK				0xFFFF0000
 #define		TCC_DISABLE_SHIFT				16
+#define	CGTS_SM_CTRL_REG				0x9150
+#define		OVERRIDE				(1 << 21)
+#define		LS_OVERRIDE				(1 << 22)
+
+#define	SPI_LB_CU_MASK					0x9354
 
 #define	TA_CNTL_AUX					0x9508
 
@@ -705,6 +1056,8 @@
 #define	CB_PERFCOUNTER3_SELECT0				0x9a38
 #define	CB_PERFCOUNTER3_SELECT1				0x9a3c
 
+#define	CB_CGTT_SCLK_CTRL				0x9a60
+
 #define	GC_USER_RB_BACKEND_DISABLE			0x9B7C
 #define		BACKEND_DISABLE_MASK			0x00FF0000
 #define		BACKEND_DISABLE_SHIFT			16
@@ -762,6 +1115,9 @@
 #       define CP_RINGID1_INT_STAT                      (1 << 30)
 #       define CP_RINGID0_INT_STAT                      (1 << 31)
 
+#define	CP_MEM_SLP_CNTL					0xC1E4
+#       define CP_MEM_LS_EN                             (1 << 0)
+
 #define	CP_DEBUG					0xC1FC
 
 #define RLC_CNTL                                          0xC300
@@ -769,6 +1125,7 @@
 #define RLC_RL_BASE                                       0xC304
 #define RLC_RL_SIZE                                       0xC308
 #define RLC_LB_CNTL                                       0xC30C
+#       define LOAD_BALANCE_ENABLE                        (1 << 0)
 #define RLC_SAVE_AND_RESTORE_BASE                         0xC310
 #define RLC_LB_CNTR_MAX                                   0xC314
 #define RLC_LB_CNTR_INIT                                  0xC318
@@ -783,6 +1140,56 @@
 #define RLC_CAPTURE_GPU_CLOCK_COUNT                       0xC340
 #define RLC_MC_CNTL                                       0xC344
 #define RLC_UCODE_CNTL                                    0xC348
+#define RLC_STAT                                          0xC34C
+#       define RLC_BUSY_STATUS                            (1 << 0)
+#       define GFX_POWER_STATUS                           (1 << 1)
+#       define GFX_CLOCK_STATUS                           (1 << 2)
+#       define GFX_LS_STATUS                              (1 << 3)
+
+#define	RLC_PG_CNTL					0xC35C
+#	define GFX_PG_ENABLE				(1 << 0)
+#	define GFX_PG_SRC				(1 << 1)
+
+#define	RLC_CGTT_MGCG_OVERRIDE				0xC400
+#define	RLC_CGCG_CGLS_CTRL				0xC404
+#	define CGCG_EN					(1 << 0)
+#	define CGLS_EN					(1 << 1)
+
+#define	RLC_TTOP_D					0xC414
+#	define RLC_PUD(x)				((x) << 0)
+#	define RLC_PUD_MASK				(0xff << 0)
+#	define RLC_PDD(x)				((x) << 8)
+#	define RLC_PDD_MASK				(0xff << 8)
+#	define RLC_TTPD(x)				((x) << 16)
+#	define RLC_TTPD_MASK				(0xff << 16)
+#	define RLC_MSD(x)				((x) << 24)
+#	define RLC_MSD_MASK				(0xff << 24)
+
+#define RLC_LB_INIT_CU_MASK                               0xC41C
+
+#define	RLC_PG_AO_CU_MASK				0xC42C
+#define	RLC_MAX_PG_CU					0xC430
+#	define MAX_PU_CU(x)				((x) << 0)
+#	define MAX_PU_CU_MASK				(0xff << 0)
+#define	RLC_AUTO_PG_CTRL				0xC434
+#	define AUTO_PG_EN				(1 << 0)
+#	define GRBM_REG_SGIT(x)				((x) << 3)
+#	define GRBM_REG_SGIT_MASK			(0xffff << 3)
+#	define PG_AFTER_GRBM_REG_ST(x)			((x) << 19)
+#	define PG_AFTER_GRBM_REG_ST_MASK		(0x1fff << 19)
+
+#define RLC_SERDES_WR_MASTER_MASK_0                       0xC454
+#define RLC_SERDES_WR_MASTER_MASK_1                       0xC458
+#define RLC_SERDES_WR_CTRL                                0xC45C
+
+#define RLC_SERDES_MASTER_BUSY_0                          0xC464
+#define RLC_SERDES_MASTER_BUSY_1                          0xC468
+
+#define RLC_GCPM_GENERAL_3                                0xC478
+
+#define	DB_RENDER_CONTROL				0x28000
+
+#define DB_DEPTH_INFO                                   0x2803c
 
 #define PA_SC_RASTER_CONFIG                             0x28350
 #       define RASTER_CONFIG_RB_MAP_0                   0
@@ -829,6 +1236,146 @@
 #       define THREAD_TRACE_FLUSH                       (54 << 0)
 #       define THREAD_TRACE_FINISH                      (55 << 0)
 
+/* PIF PHY0 registers idx/data 0x8/0xc */
+#define PB0_PIF_CNTL                                      0x10
+#       define LS2_EXIT_TIME(x)                           ((x) << 17)
+#       define LS2_EXIT_TIME_MASK                         (0x7 << 17)
+#       define LS2_EXIT_TIME_SHIFT                        17
+#define PB0_PIF_PAIRING                                   0x11
+#       define MULTI_PIF                                  (1 << 25)
+#define PB0_PIF_PWRDOWN_0                                 0x12
+#       define PLL_POWER_STATE_IN_TXS2_0(x)               ((x) << 7)
+#       define PLL_POWER_STATE_IN_TXS2_0_MASK             (0x7 << 7)
+#       define PLL_POWER_STATE_IN_TXS2_0_SHIFT            7
+#       define PLL_POWER_STATE_IN_OFF_0(x)                ((x) << 10)
+#       define PLL_POWER_STATE_IN_OFF_0_MASK              (0x7 << 10)
+#       define PLL_POWER_STATE_IN_OFF_0_SHIFT             10
+#       define PLL_RAMP_UP_TIME_0(x)                      ((x) << 24)
+#       define PLL_RAMP_UP_TIME_0_MASK                    (0x7 << 24)
+#       define PLL_RAMP_UP_TIME_0_SHIFT                   24
+#define PB0_PIF_PWRDOWN_1                                 0x13
+#       define PLL_POWER_STATE_IN_TXS2_1(x)               ((x) << 7)
+#       define PLL_POWER_STATE_IN_TXS2_1_MASK             (0x7 << 7)
+#       define PLL_POWER_STATE_IN_TXS2_1_SHIFT            7
+#       define PLL_POWER_STATE_IN_OFF_1(x)                ((x) << 10)
+#       define PLL_POWER_STATE_IN_OFF_1_MASK              (0x7 << 10)
+#       define PLL_POWER_STATE_IN_OFF_1_SHIFT             10
+#       define PLL_RAMP_UP_TIME_1(x)                      ((x) << 24)
+#       define PLL_RAMP_UP_TIME_1_MASK                    (0x7 << 24)
+#       define PLL_RAMP_UP_TIME_1_SHIFT                   24
+
+#define PB0_PIF_PWRDOWN_2                                 0x17
+#       define PLL_POWER_STATE_IN_TXS2_2(x)               ((x) << 7)
+#       define PLL_POWER_STATE_IN_TXS2_2_MASK             (0x7 << 7)
+#       define PLL_POWER_STATE_IN_TXS2_2_SHIFT            7
+#       define PLL_POWER_STATE_IN_OFF_2(x)                ((x) << 10)
+#       define PLL_POWER_STATE_IN_OFF_2_MASK              (0x7 << 10)
+#       define PLL_POWER_STATE_IN_OFF_2_SHIFT             10
+#       define PLL_RAMP_UP_TIME_2(x)                      ((x) << 24)
+#       define PLL_RAMP_UP_TIME_2_MASK                    (0x7 << 24)
+#       define PLL_RAMP_UP_TIME_2_SHIFT                   24
+#define PB0_PIF_PWRDOWN_3                                 0x18
+#       define PLL_POWER_STATE_IN_TXS2_3(x)               ((x) << 7)
+#       define PLL_POWER_STATE_IN_TXS2_3_MASK             (0x7 << 7)
+#       define PLL_POWER_STATE_IN_TXS2_3_SHIFT            7
+#       define PLL_POWER_STATE_IN_OFF_3(x)                ((x) << 10)
+#       define PLL_POWER_STATE_IN_OFF_3_MASK              (0x7 << 10)
+#       define PLL_POWER_STATE_IN_OFF_3_SHIFT             10
+#       define PLL_RAMP_UP_TIME_3(x)                      ((x) << 24)
+#       define PLL_RAMP_UP_TIME_3_MASK                    (0x7 << 24)
+#       define PLL_RAMP_UP_TIME_3_SHIFT                   24
+/* PIF PHY1 registers idx/data 0x10/0x14 */
+#define PB1_PIF_CNTL                                      0x10
+#define PB1_PIF_PAIRING                                   0x11
+#define PB1_PIF_PWRDOWN_0                                 0x12
+#define PB1_PIF_PWRDOWN_1                                 0x13
+
+#define PB1_PIF_PWRDOWN_2                                 0x17
+#define PB1_PIF_PWRDOWN_3                                 0x18
+/* PCIE registers idx/data 0x30/0x34 */
+#define PCIE_CNTL2                                        0x1c /* PCIE */
+#       define SLV_MEM_LS_EN                              (1 << 16)
+#       define MST_MEM_LS_EN                              (1 << 18)
+#       define REPLAY_MEM_LS_EN                           (1 << 19)
+#define PCIE_LC_STATUS1                                   0x28 /* PCIE */
+#       define LC_REVERSE_RCVR                            (1 << 0)
+#       define LC_REVERSE_XMIT                            (1 << 1)
+#       define LC_OPERATING_LINK_WIDTH_MASK               (0x7 << 2)
+#       define LC_OPERATING_LINK_WIDTH_SHIFT              2
+#       define LC_DETECTED_LINK_WIDTH_MASK                (0x7 << 5)
+#       define LC_DETECTED_LINK_WIDTH_SHIFT               5
+
+#define PCIE_P_CNTL                                       0x40 /* PCIE */
+#       define P_IGNORE_EDB_ERR                           (1 << 6)
+
+/* PCIE PORT registers idx/data 0x38/0x3c */
+#define PCIE_LC_CNTL                                      0xa0
+#       define LC_L0S_INACTIVITY(x)                       ((x) << 8)
+#       define LC_L0S_INACTIVITY_MASK                     (0xf << 8)
+#       define LC_L0S_INACTIVITY_SHIFT                    8
+#       define LC_L1_INACTIVITY(x)                        ((x) << 12)
+#       define LC_L1_INACTIVITY_MASK                      (0xf << 12)
+#       define LC_L1_INACTIVITY_SHIFT                     12
+#       define LC_PMI_TO_L1_DIS                           (1 << 16)
+#       define LC_ASPM_TO_L1_DIS                          (1 << 24)
+#define PCIE_LC_LINK_WIDTH_CNTL                           0xa2 /* PCIE_P */
+#       define LC_LINK_WIDTH_SHIFT                        0
+#       define LC_LINK_WIDTH_MASK                         0x7
+#       define LC_LINK_WIDTH_X0                           0
+#       define LC_LINK_WIDTH_X1                           1
+#       define LC_LINK_WIDTH_X2                           2
+#       define LC_LINK_WIDTH_X4                           3
+#       define LC_LINK_WIDTH_X8                           4
+#       define LC_LINK_WIDTH_X16                          6
+#       define LC_LINK_WIDTH_RD_SHIFT                     4
+#       define LC_LINK_WIDTH_RD_MASK                      0x70
+#       define LC_RECONFIG_ARC_MISSING_ESCAPE             (1 << 7)
+#       define LC_RECONFIG_NOW                            (1 << 8)
+#       define LC_RENEGOTIATION_SUPPORT                   (1 << 9)
+#       define LC_RENEGOTIATE_EN                          (1 << 10)
+#       define LC_SHORT_RECONFIG_EN                       (1 << 11)
+#       define LC_UPCONFIGURE_SUPPORT                     (1 << 12)
+#       define LC_UPCONFIGURE_DIS                         (1 << 13)
+#       define LC_DYN_LANES_PWR_STATE(x)                  ((x) << 21)
+#       define LC_DYN_LANES_PWR_STATE_MASK                (0x3 << 21)
+#       define LC_DYN_LANES_PWR_STATE_SHIFT               21
+#define PCIE_LC_N_FTS_CNTL                                0xa3 /* PCIE_P */
+#       define LC_XMIT_N_FTS(x)                           ((x) << 0)
+#       define LC_XMIT_N_FTS_MASK                         (0xff << 0)
+#       define LC_XMIT_N_FTS_SHIFT                        0
+#       define LC_XMIT_N_FTS_OVERRIDE_EN                  (1 << 8)
+#       define LC_N_FTS_MASK                              (0xff << 24)
+#define PCIE_LC_SPEED_CNTL                                0xa4 /* PCIE_P */
+#       define LC_GEN2_EN_STRAP                           (1 << 0)
+#       define LC_GEN3_EN_STRAP                           (1 << 1)
+#       define LC_TARGET_LINK_SPEED_OVERRIDE_EN           (1 << 2)
+#       define LC_TARGET_LINK_SPEED_OVERRIDE_MASK         (0x3 << 3)
+#       define LC_TARGET_LINK_SPEED_OVERRIDE_SHIFT        3
+#       define LC_FORCE_EN_SW_SPEED_CHANGE                (1 << 5)
+#       define LC_FORCE_DIS_SW_SPEED_CHANGE               (1 << 6)
+#       define LC_FORCE_EN_HW_SPEED_CHANGE                (1 << 7)
+#       define LC_FORCE_DIS_HW_SPEED_CHANGE               (1 << 8)
+#       define LC_INITIATE_LINK_SPEED_CHANGE              (1 << 9)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK      (0x3 << 10)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT     10
+#       define LC_CURRENT_DATA_RATE_MASK                  (0x3 << 13) /* 0/1/2 = gen1/2/3 */
+#       define LC_CURRENT_DATA_RATE_SHIFT                 13
+#       define LC_CLR_FAILED_SPD_CHANGE_CNT               (1 << 16)
+#       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 18)
+#       define LC_OTHER_SIDE_SUPPORTS_GEN2                (1 << 19)
+#       define LC_OTHER_SIDE_EVER_SENT_GEN3               (1 << 20)
+#       define LC_OTHER_SIDE_SUPPORTS_GEN3                (1 << 21)
+
+#define PCIE_LC_CNTL2                                     0xb1
+#       define LC_ALLOW_PDWN_IN_L1                        (1 << 17)
+#       define LC_ALLOW_PDWN_IN_L23                       (1 << 18)
+
+#define PCIE_LC_CNTL3                                     0xb5 /* PCIE_P */
+#       define LC_GO_TO_RECOVERY                          (1 << 30)
+#define PCIE_LC_CNTL4                                     0xb6 /* PCIE_P */
+#       define LC_REDO_EQ                                 (1 << 5)
+#       define LC_SET_QUIESCE                             (1 << 13)
+
 /*
  * UVD
  */
@@ -838,6 +1385,21 @@
 #define UVD_RBC_RB_RPTR					0xF690
 #define UVD_RBC_RB_WPTR					0xF694
 
+#define	UVD_CGC_CTRL					0xF4B0
+#	define DCM					(1 << 0)
+#	define CG_DT(x)					((x) << 2)
+#	define CG_DT_MASK				(0xf << 2)
+#	define CLK_OD(x)				((x) << 6)
+#	define CLK_OD_MASK				(0x1f << 6)
+
+ /* UVD CTX indirect */
+#define	UVD_CGC_MEM_CTRL				0xC0
+#define	UVD_CGC_CTRL2					0xC1
+#	define DYN_OR_EN				(1 << 0)
+#	define DYN_RR_EN				(1 << 1)
+#	define G_DIV_ID(x)				((x) << 2)
+#	define G_DIV_ID_MASK				(0x7 << 2)
+
 /*
  * PM4
  */
@@ -1082,6 +1644,11 @@
 #       define DMA_IDLE                                   (1 << 0)
 #define DMA_TILING_CONFIG  				  0xd0b8
 
+#define	DMA_PG						0xd0d4
+#	define PG_CNTL_ENABLE				(1 << 0)
+#define	DMA_PGFSM_CONFIG				0xd0d8
+#define	DMA_PGFSM_WRITE					0xd0dc
+
 #define DMA_PACKET(cmd, b, t, s, n)	((((cmd) & 0xF) << 28) |	\
 					 (((b) & 0x1) << 26) |		\
 					 (((t) & 0x1) << 23) |		\
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/si_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/si_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/si_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/si_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,6438 @@
+/*
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "drmP.h"
+#include "radeon.h"
+#include "sid.h"
+#include "r600_dpm.h"
+#include "si_dpm.h"
+#include "atom.h"
+#include <linux/math64.h>
+#include <linux/seq_file.h>
+
+#define MC_CG_ARB_FREQ_F0           0x0a
+#define MC_CG_ARB_FREQ_F1           0x0b
+#define MC_CG_ARB_FREQ_F2           0x0c
+#define MC_CG_ARB_FREQ_F3           0x0d
+
+#define SMC_RAM_END                 0x20000
+
+#define SCLK_MIN_DEEPSLEEP_FREQ     1350
+
+static const struct si_cac_config_reg cac_weights_tahiti[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0xc, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0x101, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0xc, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x8fc, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x95, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x34e, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x1a1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0xda, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x46, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x208, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0xe7, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x948, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x167, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x31, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0x18e, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg lcac_tahiti[] =
+{
+	{ 0x143, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x146, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x149, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x149, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14c, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x101, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x101, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8f, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x92, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x92, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x95, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x95, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x152, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x155, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x155, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x158, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x158, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x113, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x116, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x116, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x119, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
+	{ 0x119, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x122, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x122, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x125, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x125, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x128, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x128, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+
+};
+
+static const struct si_cac_config_reg cac_override_tahiti[] =
+{
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_powertune_data powertune_data_tahiti =
+{
+	((1 << 16) | 27027),
+	6,
+	0,
+	4,
+	95,
+	{
+		0UL,
+		0UL,
+		4521550UL,
+		309631529UL,
+		-1270850L,
+		4513710L,
+		40
+	},
+	595000000UL,
+	12,
+	{
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0
+	},
+	true
+};
+
+static const struct si_dte_data dte_data_tahiti =
+{
+	{ 1159409, 0, 0, 0, 0 },
+	{ 777, 0, 0, 0, 0 },
+	2,
+	54000,
+	127000,
+	25,
+	2,
+	10,
+	13,
+	{ 27, 31, 35, 39, 43, 47, 54, 61, 67, 74, 81, 88, 95, 0, 0, 0 },
+	{ 240888759, 221057860, 235370597, 162287531, 158510299, 131423027, 116673180, 103067515, 87941937, 76209048, 68209175, 64090048, 58301890, 0, 0, 0 },
+	{ 12024, 11189, 11451, 8411, 7939, 6666, 5681, 4905, 4241, 3720, 3354, 3122, 2890, 0, 0, 0 },
+	85,
+	false
+};
+
+static const struct si_dte_data dte_data_tahiti_le =
+{
+	{ 0x1E8480, 0x7A1200, 0x2160EC0, 0x3938700, 0 },
+	{ 0x7D, 0x7D, 0x4E4, 0xB00, 0 },
+	0x5,
+	0xAFC8,
+	0x64,
+	0x32,
+	1,
+	0,
+	0x10,
+	{ 0x78, 0x7C, 0x82, 0x88, 0x8E, 0x94, 0x9A, 0xA0, 0xA6, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, 0xC0, 0xC4 },
+	{ 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700, 0x3938700 },
+	{ 0x2AF8, 0x2AF8, 0x29BB, 0x27F9, 0x2637, 0x2475, 0x22B3, 0x20F1, 0x1F2F, 0x1D6D, 0x1734, 0x1414, 0x10F4, 0xDD4, 0xAB4, 0x794 },
+	85,
+	true
+};
+
+static const struct si_dte_data dte_data_tahiti_pro =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
+	5,
+	45000,
+	100,
+	0xA,
+	1,
+	0,
+	0x10,
+	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
+	{ 0x7D0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+static const struct si_dte_data dte_data_new_zealand =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0 },
+	{ 0x29B, 0x3E9, 0x537, 0x7D2, 0 },
+	0x5,
+	0xAFC8,
+	0x69,
+	0x32,
+	1,
+	0,
+	0x10,
+	{ 0x82, 0xA0, 0xB4, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
+	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
+	{ 0xDAC, 0x1388, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685 },
+	85,
+	true
+};
+
+static const struct si_dte_data dte_data_aruba_pro =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
+	5,
+	45000,
+	100,
+	0xA,
+	1,
+	0,
+	0x10,
+	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
+	{ 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+static const struct si_dte_data dte_data_malta =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
+	5,
+	45000,
+	100,
+	0xA,
+	1,
+	0,
+	0x10,
+	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
+	{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+struct si_cac_config_reg cac_weights_pitcairn[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x8a, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x24d, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x19, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0xc11, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0x7f3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x403, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x367, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x4c9, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x45d, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0x36d, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x534, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x5da, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x880, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0x201, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0x9f, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x1f, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x5de, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x7b, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x13, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0xf9, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x66, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x13, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0x186, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg lcac_pitcairn[] =
+{
+	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x143, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x113, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x152, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x146, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x116, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x116, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x155, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x155, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x92, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x92, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x149, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x149, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x101, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x101, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x119, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x119, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x158, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x158, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x95, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x95, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x122, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x122, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x125, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x125, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x128, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x128, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_override_pitcairn[] =
+{
+    { 0xFFFFFFFF }
+};
+
+static const struct si_powertune_data powertune_data_pitcairn =
+{
+	((1 << 16) | 27027),
+	5,
+	0,
+	6,
+	100,
+	{
+		51600000UL,
+		1800000UL,
+		7194395UL,
+		309631529UL,
+		-1270850L,
+		4513710L,
+		100
+	},
+	117830498UL,
+	12,
+	{
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0
+	},
+	true
+};
+
+static const struct si_dte_data dte_data_pitcairn =
+{
+	{ 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0 },
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	0,
+	false
+};
+
+static const struct si_dte_data dte_data_curacao_xt =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
+	5,
+	45000,
+	100,
+	0xA,
+	1,
+	0,
+	0x10,
+	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
+	{ 0x1D17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+static const struct si_dte_data dte_data_curacao_pro =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
+	5,
+	45000,
+	100,
+	0xA,
+	1,
+	0,
+	0x10,
+	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
+	{ 0x1D17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+static const struct si_dte_data dte_data_neptune_xt =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
+	5,
+	45000,
+	100,
+	0xA,
+	1,
+	0,
+	0x10,
+	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
+	{ 0x3A2F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+static const struct si_cac_config_reg cac_weights_chelsea_pro[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x2BD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_weights_chelsea_xt[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x30A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_weights_heathrow[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x362, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_weights_cape_verde_pro[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x315, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_weights_cape_verde[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x3BA, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg lcac_cape_verde[] =
+{
+	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x143, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x113, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x152, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x146, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_override_cape_verde[] =
+{
+    { 0xFFFFFFFF }
+};
+
+static const struct si_powertune_data powertune_data_cape_verde =
+{
+	((1 << 16) | 0x6993),
+	5,
+	0,
+	7,
+	105,
+	{
+		0UL,
+		0UL,
+		7194395UL,
+		309631529UL,
+		-1270850L,
+		4513710L,
+		100
+	},
+	117830498UL,
+	12,
+	{
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0
+	},
+	true
+};
+
+static const struct si_dte_data dte_data_cape_verde =
+{
+	{ 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0 },
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	0,
+	false
+};
+
+static const struct si_dte_data dte_data_venus_xtx =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x71C, 0xAAB, 0xE39, 0x11C7, 0x0 },
+	5,
+	55000,
+	0x69,
+	0xA,
+	1,
+	0,
+	0x3,
+	{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	{ 0xD6D8, 0x88B8, 0x1555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+static const struct si_dte_data dte_data_venus_xt =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0xBDA, 0x11C7, 0x17B4, 0x1DA1, 0x0 },
+	5,
+	55000,
+	0x69,
+	0xA,
+	1,
+	0,
+	0x3,
+	{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	{ 0xAFC8, 0x88B8, 0x238E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+static const struct si_dte_data dte_data_venus_pro =
+{
+	{  0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x11C7, 0x1AAB, 0x238E, 0x2C72, 0x0 },
+	5,
+	55000,
+	0x69,
+	0xA,
+	1,
+	0,
+	0x3,
+	{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	{ 0x88B8, 0x88B8, 0x3555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+struct si_cac_config_reg cac_weights_oland[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x3BA, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_weights_mars_pro[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_weights_mars_xt[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x60, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_weights_oland_pro[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x90, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_weights_oland_xt[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x120, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg lcac_oland[] =
+{
+	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x143, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
+	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg lcac_mars_pro[] =
+{
+	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x143, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_cac_config_reg cac_override_oland[] =
+{
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_powertune_data powertune_data_oland =
+{
+	((1 << 16) | 0x6993),
+	5,
+	0,
+	7,
+	105,
+	{
+		0UL,
+		0UL,
+		7194395UL,
+		309631529UL,
+		-1270850L,
+		4513710L,
+		100
+	},
+	117830498UL,
+	12,
+	{
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0
+	},
+	true
+};
+
+static const struct si_powertune_data powertune_data_mars_pro =
+{
+	((1 << 16) | 0x6993),
+	5,
+	0,
+	7,
+	105,
+	{
+		0UL,
+		0UL,
+		7194395UL,
+		309631529UL,
+		-1270850L,
+		4513710L,
+		100
+	},
+	117830498UL,
+	12,
+	{
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0
+	},
+	true
+};
+
+static const struct si_dte_data dte_data_oland =
+{
+	{ 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0 },
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	0,
+	false
+};
+
+static const struct si_dte_data dte_data_mars_pro =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
+	5,
+	55000,
+	105,
+	0xA,
+	1,
+	0,
+	0x10,
+	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
+	{ 0xF627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+static const struct si_dte_data dte_data_sun_xt =
+{
+	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
+	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
+	5,
+	55000,
+	105,
+	0xA,
+	1,
+	0,
+	0x10,
+	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
+	{ 0xD555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
+	90,
+	true
+};
+
+
+static const struct si_cac_config_reg cac_weights_hainan[] =
+{
+	{ 0x0, 0x0000ffff, 0, 0x2d9, SISLANDS_CACCONFIG_CGIND },
+	{ 0x0, 0xffff0000, 16, 0x22b, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0x0000ffff, 0, 0x21c, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1, 0xffff0000, 16, 0x1dc, SISLANDS_CACCONFIG_CGIND },
+	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0x0000ffff, 0, 0x24e, SISLANDS_CACCONFIG_CGIND },
+	{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0x0000ffff, 0, 0x35e, SISLANDS_CACCONFIG_CGIND },
+	{ 0x5, 0xffff0000, 16, 0x1143, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0x0000ffff, 0, 0xe17, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6, 0xffff0000, 16, 0x441, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0x0000ffff, 0, 0x28b, SISLANDS_CACCONFIG_CGIND },
+	{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x8, 0xffff0000, 16, 0xabe, SISLANDS_CACCONFIG_CGIND },
+	{ 0x9, 0x0000ffff, 0, 0xf11, SISLANDS_CACCONFIG_CGIND },
+	{ 0xa, 0x0000ffff, 0, 0x907, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0x0000ffff, 0, 0xb45, SISLANDS_CACCONFIG_CGIND },
+	{ 0xb, 0xffff0000, 16, 0xd1e, SISLANDS_CACCONFIG_CGIND },
+	{ 0xc, 0x0000ffff, 0, 0xa2c, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0x0000ffff, 0, 0x62, SISLANDS_CACCONFIG_CGIND },
+	{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0xe, 0x0000ffff, 0, 0x1f3, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0x0000ffff, 0, 0x42, SISLANDS_CACCONFIG_CGIND },
+	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0x0000ffff, 0, 0x709, SISLANDS_CACCONFIG_CGIND },
+	{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x12, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x13, 0xffff0000, 16, 0x3a, SISLANDS_CACCONFIG_CGIND },
+	{ 0x14, 0x0000ffff, 0, 0x357, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0x0000ffff, 0, 0x9f, SISLANDS_CACCONFIG_CGIND },
+	{ 0x15, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0x0000ffff, 0, 0x314, SISLANDS_CACCONFIG_CGIND },
+	{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x17, 0x0000ffff, 0, 0x6d, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
+	{ 0x6d, 0x0000ffff, 0, 0x1b9, SISLANDS_CACCONFIG_CGIND },
+	{ 0xFFFFFFFF }
+};
+
+static const struct si_powertune_data powertune_data_hainan =
+{
+	((1 << 16) | 0x6993),
+	5,
+	0,
+	9,
+	105,
+	{
+		0UL,
+		0UL,
+		7194395UL,
+		309631529UL,
+		-1270850L,
+		4513710L,
+		100
+	},
+	117830498UL,
+	12,
+	{
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0
+	},
+	true
+};
+
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
+struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
+struct ni_power_info *ni_get_pi(struct radeon_device *rdev);
+struct ni_ps *ni_get_ps(struct radeon_ps *rps);
+
+static int si_populate_voltage_value(struct radeon_device *rdev,
+				     const struct atom_voltage_table *table,
+				     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage);
+static int si_get_std_voltage_value(struct radeon_device *rdev,
+				    SISLANDS_SMC_VOLTAGE_VALUE *voltage,
+				    u16 *std_voltage);
+static int si_write_smc_soft_register(struct radeon_device *rdev,
+				      u16 reg_offset, u32 value);
+static int si_convert_power_level_to_smc(struct radeon_device *rdev,
+					 struct rv7xx_pl *pl,
+					 SISLANDS_SMC_HW_PERFORMANCE_LEVEL *level);
+static int si_calculate_sclk_params(struct radeon_device *rdev,
+				    u32 engine_clock,
+				    SISLANDS_SMC_SCLK_VALUE *sclk);
+
+static struct si_power_info *si_get_pi(struct radeon_device *rdev)
+{
+        struct si_power_info *pi = rdev->pm.dpm.priv;
+
+        return pi;
+}
+
+static void si_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients *coeff,
+						     u16 v, s32 t, u32 ileakage, u32 *leakage)
+{
+	s64 kt, kv, leakage_w, i_leakage, vddc;
+	s64 temperature, t_slope, t_intercept, av, bv, t_ref;
+	s64 tmp;
+
+	i_leakage = div64_s64(drm_int2fixp(ileakage), 100);
+	vddc = div64_s64(drm_int2fixp(v), 1000);
+	temperature = div64_s64(drm_int2fixp(t), 1000);
+
+	t_slope = div64_s64(drm_int2fixp(coeff->t_slope), 100000000);
+	t_intercept = div64_s64(drm_int2fixp(coeff->t_intercept), 100000000);
+	av = div64_s64(drm_int2fixp(coeff->av), 100000000);
+	bv = div64_s64(drm_int2fixp(coeff->bv), 100000000);
+	t_ref = drm_int2fixp(coeff->t_ref);
+
+	tmp = drm_fixp_mul(t_slope, vddc) + t_intercept;
+	kt = drm_fixp_exp(drm_fixp_mul(tmp, temperature));
+	kt = drm_fixp_div(kt, drm_fixp_exp(drm_fixp_mul(tmp, t_ref)));
+	kv = drm_fixp_mul(av, drm_fixp_exp(drm_fixp_mul(bv, vddc)));
+
+	leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);
+
+	*leakage = drm_fixp2int(leakage_w * 1000);
+}
+
+static void si_calculate_leakage_for_v_and_t(struct radeon_device *rdev,
+					     const struct ni_leakage_coeffients *coeff,
+					     u16 v,
+					     s32 t,
+					     u32 i_leakage,
+					     u32 *leakage)
+{
+	si_calculate_leakage_for_v_and_t_formula(coeff, v, t, i_leakage, leakage);
+}
+
+static void si_calculate_leakage_for_v_formula(const struct ni_leakage_coeffients *coeff,
+					       const u32 fixed_kt, u16 v,
+					       u32 ileakage, u32 *leakage)
+{
+	s64 kt, kv, leakage_w, i_leakage, vddc;
+
+	i_leakage = div64_s64(drm_int2fixp(ileakage), 100);
+	vddc = div64_s64(drm_int2fixp(v), 1000);
+
+	kt = div64_s64(drm_int2fixp(fixed_kt), 100000000);
+	kv = drm_fixp_mul(div64_s64(drm_int2fixp(coeff->av), 100000000),
+			  drm_fixp_exp(drm_fixp_mul(div64_s64(drm_int2fixp(coeff->bv), 100000000), vddc)));
+
+	leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);
+
+	*leakage = drm_fixp2int(leakage_w * 1000);
+}
+
+static void si_calculate_leakage_for_v(struct radeon_device *rdev,
+				       const struct ni_leakage_coeffients *coeff,
+				       const u32 fixed_kt,
+				       u16 v,
+				       u32 i_leakage,
+				       u32 *leakage)
+{
+	si_calculate_leakage_for_v_formula(coeff, fixed_kt, v, i_leakage, leakage);
+}
+
+
+static void si_update_dte_from_pl2(struct radeon_device *rdev,
+				   struct si_dte_data *dte_data)
+{
+	u32 p_limit1 = rdev->pm.dpm.tdp_limit;
+	u32 p_limit2 = rdev->pm.dpm.near_tdp_limit;
+	u32 k = dte_data->k;
+	u32 t_max = dte_data->max_t;
+	u32 t_split[5] = { 10, 15, 20, 25, 30 };
+	u32 t_0 = dte_data->t0;
+	u32 i;
+
+	if (p_limit2 != 0 && p_limit2 <= p_limit1) {
+		dte_data->tdep_count = 3;
+
+		for (i = 0; i < k; i++) {
+			dte_data->r[i] =
+				(t_split[i] * (t_max - t_0/(u32)1000) * (1 << 14)) /
+				(p_limit2  * (u32)100);
+		}
+
+		dte_data->tdep_r[1] = dte_data->r[4] * 2;
+
+		for (i = 2; i < SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE; i++) {
+			dte_data->tdep_r[i] = dte_data->r[4];
+		}
+	} else {
+		DRM_ERROR("Invalid PL2! DTE will not be updated.\n");
+	}
+}
+
+static void si_initialize_powertune_defaults(struct radeon_device *rdev)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	bool update_dte_from_pl2 = false;
+
+	if (rdev->family == CHIP_TAHITI) {
+		si_pi->cac_weights = cac_weights_tahiti;
+		si_pi->lcac_config = lcac_tahiti;
+		si_pi->cac_override = cac_override_tahiti;
+		si_pi->powertune_data = &powertune_data_tahiti;
+		si_pi->dte_data = dte_data_tahiti;
+
+		switch (rdev->pdev->device) {
+		case 0x6798:
+			si_pi->dte_data.enable_dte_by_default = true;
+			break;
+		case 0x6799:
+			si_pi->dte_data = dte_data_new_zealand;
+			break;
+		case 0x6790:
+		case 0x6791:
+		case 0x6792:
+		case 0x679E:
+			si_pi->dte_data = dte_data_aruba_pro;
+			update_dte_from_pl2 = true;
+			break;
+		case 0x679B:
+			si_pi->dte_data = dte_data_malta;
+			update_dte_from_pl2 = true;
+			break;
+		case 0x679A:
+			si_pi->dte_data = dte_data_tahiti_pro;
+			update_dte_from_pl2 = true;
+			break;
+		default:
+			if (si_pi->dte_data.enable_dte_by_default == true)
+				DRM_ERROR("DTE is not enabled!\n");
+			break;
+		}
+	} else if (rdev->family == CHIP_PITCAIRN) {
+		switch (rdev->pdev->device) {
+		case 0x6810:
+		case 0x6818:
+			si_pi->cac_weights = cac_weights_pitcairn;
+			si_pi->lcac_config = lcac_pitcairn;
+			si_pi->cac_override = cac_override_pitcairn;
+			si_pi->powertune_data = &powertune_data_pitcairn;
+			si_pi->dte_data = dte_data_curacao_xt;
+			update_dte_from_pl2 = true;
+			break;
+		case 0x6819:
+		case 0x6811:
+			si_pi->cac_weights = cac_weights_pitcairn;
+			si_pi->lcac_config = lcac_pitcairn;
+			si_pi->cac_override = cac_override_pitcairn;
+			si_pi->powertune_data = &powertune_data_pitcairn;
+			si_pi->dte_data = dte_data_curacao_pro;
+			update_dte_from_pl2 = true;
+			break;
+		case 0x6800:
+		case 0x6806:
+			si_pi->cac_weights = cac_weights_pitcairn;
+			si_pi->lcac_config = lcac_pitcairn;
+			si_pi->cac_override = cac_override_pitcairn;
+			si_pi->powertune_data = &powertune_data_pitcairn;
+			si_pi->dte_data = dte_data_neptune_xt;
+			update_dte_from_pl2 = true;
+			break;
+		default:
+			si_pi->cac_weights = cac_weights_pitcairn;
+			si_pi->lcac_config = lcac_pitcairn;
+			si_pi->cac_override = cac_override_pitcairn;
+			si_pi->powertune_data = &powertune_data_pitcairn;
+			si_pi->dte_data = dte_data_pitcairn;
+			break;
+		}
+	} else if (rdev->family == CHIP_VERDE) {
+		si_pi->lcac_config = lcac_cape_verde;
+		si_pi->cac_override = cac_override_cape_verde;
+		si_pi->powertune_data = &powertune_data_cape_verde;
+
+		switch (rdev->pdev->device) {
+		case 0x683B:
+		case 0x683F:
+		case 0x6829:
+		case 0x6835:
+			si_pi->cac_weights = cac_weights_cape_verde_pro;
+			si_pi->dte_data = dte_data_cape_verde;
+			break;
+		case 0x6825:
+		case 0x6827:
+			si_pi->cac_weights = cac_weights_heathrow;
+			si_pi->dte_data = dte_data_cape_verde;
+			break;
+		case 0x6824:
+		case 0x682D:
+			si_pi->cac_weights = cac_weights_chelsea_xt;
+			si_pi->dte_data = dte_data_cape_verde;
+			break;
+		case 0x682F:
+			si_pi->cac_weights = cac_weights_chelsea_pro;
+			si_pi->dte_data = dte_data_cape_verde;
+			break;
+		case 0x6820:
+			si_pi->cac_weights = cac_weights_heathrow;
+			si_pi->dte_data = dte_data_venus_xtx;
+			break;
+		case 0x6821:
+			si_pi->cac_weights = cac_weights_heathrow;
+			si_pi->dte_data = dte_data_venus_xt;
+			break;
+		case 0x6823:
+			si_pi->cac_weights = cac_weights_chelsea_pro;
+			si_pi->dte_data = dte_data_venus_pro;
+			break;
+		case 0x682B:
+			si_pi->cac_weights = cac_weights_chelsea_pro;
+			si_pi->dte_data = dte_data_venus_pro;
+			break;
+		default:
+			si_pi->cac_weights = cac_weights_cape_verde;
+			si_pi->dte_data = dte_data_cape_verde;
+			break;
+		}
+	} else if (rdev->family == CHIP_OLAND) {
+		switch (rdev->pdev->device) {
+		case 0x6601:
+		case 0x6621:
+		case 0x6603:
+			si_pi->cac_weights = cac_weights_mars_pro;
+			si_pi->lcac_config = lcac_mars_pro;
+			si_pi->cac_override = cac_override_oland;
+			si_pi->powertune_data = &powertune_data_mars_pro;
+			si_pi->dte_data = dte_data_mars_pro;
+			update_dte_from_pl2 = true;
+			break;
+		case 0x6600:
+		case 0x6606:
+		case 0x6620:
+			si_pi->cac_weights = cac_weights_mars_xt;
+			si_pi->lcac_config = lcac_mars_pro;
+			si_pi->cac_override = cac_override_oland;
+			si_pi->powertune_data = &powertune_data_mars_pro;
+			si_pi->dte_data = dte_data_mars_pro;
+			update_dte_from_pl2 = true;
+			break;
+		case 0x6611:
+			si_pi->cac_weights = cac_weights_oland_pro;
+			si_pi->lcac_config = lcac_mars_pro;
+			si_pi->cac_override = cac_override_oland;
+			si_pi->powertune_data = &powertune_data_mars_pro;
+			si_pi->dte_data = dte_data_mars_pro;
+			update_dte_from_pl2 = true;
+			break;
+		case 0x6610:
+			si_pi->cac_weights = cac_weights_oland_xt;
+			si_pi->lcac_config = lcac_mars_pro;
+			si_pi->cac_override = cac_override_oland;
+			si_pi->powertune_data = &powertune_data_mars_pro;
+			si_pi->dte_data = dte_data_mars_pro;
+			update_dte_from_pl2 = true;
+			break;
+		default:
+			si_pi->cac_weights = cac_weights_oland;
+			si_pi->lcac_config = lcac_oland;
+			si_pi->cac_override = cac_override_oland;
+			si_pi->powertune_data = &powertune_data_oland;
+			si_pi->dte_data = dte_data_oland;
+			break;
+		}
+	} else if (rdev->family == CHIP_HAINAN) {
+		si_pi->cac_weights = cac_weights_hainan;
+		si_pi->lcac_config = lcac_oland;
+		si_pi->cac_override = cac_override_oland;
+		si_pi->powertune_data = &powertune_data_hainan;
+		si_pi->dte_data = dte_data_sun_xt;
+		update_dte_from_pl2 = true;
+	} else {
+		DRM_ERROR("Unknown SI asic revision, failed to initialize PowerTune!\n");
+		return;
+	}
+
+	ni_pi->enable_power_containment = false;
+	ni_pi->enable_cac = false;
+	ni_pi->enable_sq_ramping = false;
+	si_pi->enable_dte = false;
+
+	if (si_pi->powertune_data->enable_powertune_by_default) {
+		ni_pi->enable_power_containment= true;
+		ni_pi->enable_cac = true;
+		if (si_pi->dte_data.enable_dte_by_default) {
+			si_pi->enable_dte = true;
+			if (update_dte_from_pl2)
+				si_update_dte_from_pl2(rdev, &si_pi->dte_data);
+
+		}
+		ni_pi->enable_sq_ramping = true;
+	}
+
+	ni_pi->driver_calculate_cac_leakage = true;
+	ni_pi->cac_configuration_required = true;
+
+	if (ni_pi->cac_configuration_required) {
+		ni_pi->support_cac_long_term_average = true;
+		si_pi->dyn_powertune_data.l2_lta_window_size =
+			si_pi->powertune_data->l2_lta_window_size_default;
+		si_pi->dyn_powertune_data.lts_truncate =
+			si_pi->powertune_data->lts_truncate_default;
+	} else {
+		ni_pi->support_cac_long_term_average = false;
+		si_pi->dyn_powertune_data.l2_lta_window_size = 0;
+		si_pi->dyn_powertune_data.lts_truncate = 0;
+	}
+
+	si_pi->dyn_powertune_data.disable_uvd_powertune = false;
+}
+
+static u32 si_get_smc_power_scaling_factor(struct radeon_device *rdev)
+{
+	return 1;
+}
+
+static u32 si_calculate_cac_wintime(struct radeon_device *rdev)
+{
+	u32 xclk;
+	u32 wintime;
+	u32 cac_window;
+	u32 cac_window_size;
+
+	xclk = radeon_get_xclk(rdev);
+
+	if (xclk == 0)
+		return 0;
+
+	cac_window = RREG32(CG_CAC_CTRL) & CAC_WINDOW_MASK;
+	cac_window_size = ((cac_window & 0xFFFF0000) >> 16) * (cac_window & 0x0000FFFF);
+
+	wintime = (cac_window_size * 100) / xclk;
+
+	return wintime;
+}
+
+static u32 si_scale_power_for_smc(u32 power_in_watts, u32 scaling_factor)
+{
+	return power_in_watts;
+}
+
+static int si_calculate_adjusted_tdp_limits(struct radeon_device *rdev,
+					    bool adjust_polarity,
+					    u32 tdp_adjustment,
+					    u32 *tdp_limit,
+					    u32 *near_tdp_limit)
+{
+	u32 adjustment_delta, max_tdp_limit;
+
+	if (tdp_adjustment > (u32)rdev->pm.dpm.tdp_od_limit)
+		return -EINVAL;
+
+	max_tdp_limit = ((100 + 100) * rdev->pm.dpm.tdp_limit) / 100;
+
+	if (adjust_polarity) {
+		*tdp_limit = ((100 + tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
+		*near_tdp_limit = rdev->pm.dpm.near_tdp_limit_adjusted + (*tdp_limit - rdev->pm.dpm.tdp_limit);
+	} else {
+		*tdp_limit = ((100 - tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
+		adjustment_delta  = rdev->pm.dpm.tdp_limit - *tdp_limit;
+		if (adjustment_delta < rdev->pm.dpm.near_tdp_limit_adjusted)
+			*near_tdp_limit = rdev->pm.dpm.near_tdp_limit_adjusted - adjustment_delta;
+		else
+			*near_tdp_limit = 0;
+	}
+
+	if ((*tdp_limit <= 0) || (*tdp_limit > max_tdp_limit))
+		return -EINVAL;
+	if ((*near_tdp_limit <= 0) || (*near_tdp_limit > *tdp_limit))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int si_populate_smc_tdp_limits(struct radeon_device *rdev,
+				      struct radeon_ps *radeon_state)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+
+	if (ni_pi->enable_power_containment) {
+		SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable;
+		PP_SIslands_PAPMParameters *papm_parm;
+		struct radeon_ppm_table *ppm = rdev->pm.dpm.dyn_state.ppm_table;
+		u32 scaling_factor = si_get_smc_power_scaling_factor(rdev);
+		u32 tdp_limit;
+		u32 near_tdp_limit;
+		int ret;
+
+		if (scaling_factor == 0)
+			return -EINVAL;
+
+		memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));
+
+		ret = si_calculate_adjusted_tdp_limits(rdev,
+						       false, /* ??? */
+						       rdev->pm.dpm.tdp_adjustment,
+						       &tdp_limit,
+						       &near_tdp_limit);
+		if (ret)
+			return ret;
+
+		smc_table->dpm2Params.TDPLimit =
+			cpu_to_be32(si_scale_power_for_smc(tdp_limit, scaling_factor) * 1000);
+		smc_table->dpm2Params.NearTDPLimit =
+			cpu_to_be32(si_scale_power_for_smc(near_tdp_limit, scaling_factor) * 1000);
+		smc_table->dpm2Params.SafePowerLimit =
+			cpu_to_be32(si_scale_power_for_smc((near_tdp_limit * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000);
+
+		ret = si_copy_bytes_to_smc(rdev,
+					   (si_pi->state_table_start + offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +
+						 offsetof(PP_SIslands_DPM2Parameters, TDPLimit)),
+					   (u8 *)(&(smc_table->dpm2Params.TDPLimit)),
+					   sizeof(u32) * 3,
+					   si_pi->sram_end);
+		if (ret)
+			return ret;
+
+		if (si_pi->enable_ppm) {
+			papm_parm = &si_pi->papm_parm;
+			memset(papm_parm, 0, sizeof(PP_SIslands_PAPMParameters));
+			papm_parm->NearTDPLimitTherm = cpu_to_be32(ppm->dgpu_tdp);
+			papm_parm->dGPU_T_Limit = cpu_to_be32(ppm->tj_max);
+			papm_parm->dGPU_T_Warning = cpu_to_be32(95);
+			papm_parm->dGPU_T_Hysteresis = cpu_to_be32(5);
+			papm_parm->PlatformPowerLimit = 0xffffffff;
+			papm_parm->NearTDPLimitPAPM = 0xffffffff;
+
+			ret = si_copy_bytes_to_smc(rdev, si_pi->papm_cfg_table_start,
+						   (u8 *)papm_parm,
+						   sizeof(PP_SIslands_PAPMParameters),
+						   si_pi->sram_end);
+			if (ret)
+				return ret;
+		}
+	}
+	return 0;
+}
+
+static int si_populate_smc_tdp_limits_2(struct radeon_device *rdev,
+					struct radeon_ps *radeon_state)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+
+	if (ni_pi->enable_power_containment) {
+		SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable;
+		u32 scaling_factor = si_get_smc_power_scaling_factor(rdev);
+		int ret;
+
+		memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));
+
+		smc_table->dpm2Params.NearTDPLimit =
+			cpu_to_be32(si_scale_power_for_smc(rdev->pm.dpm.near_tdp_limit_adjusted, scaling_factor) * 1000);
+		smc_table->dpm2Params.SafePowerLimit =
+			cpu_to_be32(si_scale_power_for_smc((rdev->pm.dpm.near_tdp_limit_adjusted * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000);
+
+		ret = si_copy_bytes_to_smc(rdev,
+					   (si_pi->state_table_start +
+					    offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +
+					    offsetof(PP_SIslands_DPM2Parameters, NearTDPLimit)),
+					   (u8 *)(&(smc_table->dpm2Params.NearTDPLimit)),
+					   sizeof(u32) * 2,
+					   si_pi->sram_end);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static u16 si_calculate_power_efficiency_ratio(struct radeon_device *rdev,
+					       const u16 prev_std_vddc,
+					       const u16 curr_std_vddc)
+{
+	u64 margin = (u64)SISLANDS_DPM2_PWREFFICIENCYRATIO_MARGIN;
+	u64 prev_vddc = (u64)prev_std_vddc;
+	u64 curr_vddc = (u64)curr_std_vddc;
+	u64 pwr_efficiency_ratio, n, d;
+
+	if ((prev_vddc == 0) || (curr_vddc == 0))
+		return 0;
+
+	n = div64_u64((u64)1024 * curr_vddc * curr_vddc * ((u64)1000 + margin), (u64)1000);
+	d = prev_vddc * prev_vddc;
+	pwr_efficiency_ratio = div64_u64(n, d);
+
+	if (pwr_efficiency_ratio > (u64)0xFFFF)
+		return 0;
+
+	return (u16)pwr_efficiency_ratio;
+}
+
+static bool si_should_disable_uvd_powertune(struct radeon_device *rdev,
+					    struct radeon_ps *radeon_state)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+
+	if (si_pi->dyn_powertune_data.disable_uvd_powertune &&
+	    radeon_state->vclk && radeon_state->dclk)
+		return true;
+
+	return false;
+}
+
+static int si_populate_power_containment_values(struct radeon_device *rdev,
+						struct radeon_ps *radeon_state,
+						SISLANDS_SMC_SWSTATE *smc_state)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	SISLANDS_SMC_VOLTAGE_VALUE vddc;
+	u32 prev_sclk;
+	u32 max_sclk;
+	u32 min_sclk;
+	u16 prev_std_vddc;
+	u16 curr_std_vddc;
+	int i;
+	u16 pwr_efficiency_ratio;
+	u8 max_ps_percent;
+	bool disable_uvd_power_tune;
+	int ret;
+
+	if (ni_pi->enable_power_containment == false)
+		return 0;
+
+	if (state->performance_level_count == 0)
+		return -EINVAL;
+
+	if (smc_state->levelCount != state->performance_level_count)
+		return -EINVAL;
+
+	disable_uvd_power_tune = si_should_disable_uvd_powertune(rdev, radeon_state);
+
+	smc_state->levels[0].dpm2.MaxPS = 0;
+	smc_state->levels[0].dpm2.NearTDPDec = 0;
+	smc_state->levels[0].dpm2.AboveSafeInc = 0;
+	smc_state->levels[0].dpm2.BelowSafeInc = 0;
+	smc_state->levels[0].dpm2.PwrEfficiencyRatio = 0;
+
+	for (i = 1; i < state->performance_level_count; i++) {
+		prev_sclk = state->performance_levels[i-1].sclk;
+		max_sclk  = state->performance_levels[i].sclk;
+		if (i == 1)
+			max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_M;
+		else
+			max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_H;
+
+		if (prev_sclk > max_sclk)
+			return -EINVAL;
+
+		if ((max_ps_percent == 0) ||
+		    (prev_sclk == max_sclk) ||
+		    disable_uvd_power_tune) {
+			min_sclk = max_sclk;
+		} else if (i == 1) {
+			min_sclk = prev_sclk;
+		} else {
+			min_sclk = (prev_sclk * (u32)max_ps_percent) / 100;
+		}
+
+		if (min_sclk < state->performance_levels[0].sclk)
+			min_sclk = state->performance_levels[0].sclk;
+
+		if (min_sclk == 0)
+			return -EINVAL;
+
+		ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
+						state->performance_levels[i-1].vddc, &vddc);
+		if (ret)
+			return ret;
+
+		ret = si_get_std_voltage_value(rdev, &vddc, &prev_std_vddc);
+		if (ret)
+			return ret;
+
+		ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
+						state->performance_levels[i].vddc, &vddc);
+		if (ret)
+			return ret;
+
+		ret = si_get_std_voltage_value(rdev, &vddc, &curr_std_vddc);
+		if (ret)
+			return ret;
+
+		pwr_efficiency_ratio = si_calculate_power_efficiency_ratio(rdev,
+									   prev_std_vddc, curr_std_vddc);
+
+		smc_state->levels[i].dpm2.MaxPS = (u8)((SISLANDS_DPM2_MAX_PULSE_SKIP * (max_sclk - min_sclk)) / max_sclk);
+		smc_state->levels[i].dpm2.NearTDPDec = SISLANDS_DPM2_NEAR_TDP_DEC;
+		smc_state->levels[i].dpm2.AboveSafeInc = SISLANDS_DPM2_ABOVE_SAFE_INC;
+		smc_state->levels[i].dpm2.BelowSafeInc = SISLANDS_DPM2_BELOW_SAFE_INC;
+		smc_state->levels[i].dpm2.PwrEfficiencyRatio = cpu_to_be16(pwr_efficiency_ratio);
+	}
+
+	return 0;
+}
+
+static int si_populate_sq_ramping_values(struct radeon_device *rdev,
+					 struct radeon_ps *radeon_state,
+					 SISLANDS_SMC_SWSTATE *smc_state)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	u32 sq_power_throttle, sq_power_throttle2;
+	bool enable_sq_ramping = ni_pi->enable_sq_ramping;
+	int i;
+
+	if (state->performance_level_count == 0)
+		return -EINVAL;
+
+	if (smc_state->levelCount != state->performance_level_count)
+		return -EINVAL;
+
+	if (rdev->pm.dpm.sq_ramping_threshold == 0)
+		return -EINVAL;
+
+	if (SISLANDS_DPM2_SQ_RAMP_MAX_POWER > (MAX_POWER_MASK >> MAX_POWER_SHIFT))
+		enable_sq_ramping = false;
+
+	if (SISLANDS_DPM2_SQ_RAMP_MIN_POWER > (MIN_POWER_MASK >> MIN_POWER_SHIFT))
+		enable_sq_ramping = false;
+
+	if (SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA > (MAX_POWER_DELTA_MASK >> MAX_POWER_DELTA_SHIFT))
+		enable_sq_ramping = false;
+
+	if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT))
+		enable_sq_ramping = false;
+
+	if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT))
+		enable_sq_ramping = false;
+
+	for (i = 0; i < state->performance_level_count; i++) {
+		sq_power_throttle = 0;
+		sq_power_throttle2 = 0;
+
+		if ((state->performance_levels[i].sclk >= rdev->pm.dpm.sq_ramping_threshold) &&
+		    enable_sq_ramping) {
+			sq_power_throttle |= MAX_POWER(SISLANDS_DPM2_SQ_RAMP_MAX_POWER);
+			sq_power_throttle |= MIN_POWER(SISLANDS_DPM2_SQ_RAMP_MIN_POWER);
+			sq_power_throttle2 |= MAX_POWER_DELTA(SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA);
+			sq_power_throttle2 |= STI_SIZE(SISLANDS_DPM2_SQ_RAMP_STI_SIZE);
+			sq_power_throttle2 |= LTI_RATIO(SISLANDS_DPM2_SQ_RAMP_LTI_RATIO);
+		} else {
+			sq_power_throttle |= MAX_POWER_MASK | MIN_POWER_MASK;
+			sq_power_throttle2 |= MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
+		}
+
+		smc_state->levels[i].SQPowerThrottle = cpu_to_be32(sq_power_throttle);
+		smc_state->levels[i].SQPowerThrottle_2 = cpu_to_be32(sq_power_throttle2);
+	}
+
+	return 0;
+}
+
+static int si_enable_power_containment(struct radeon_device *rdev,
+				       struct radeon_ps *radeon_new_state,
+				       bool enable)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	PPSMC_Result smc_result;
+	int ret = 0;
+
+	if (ni_pi->enable_power_containment) {
+		if (enable) {
+			if (!si_should_disable_uvd_powertune(rdev, radeon_new_state)) {
+				smc_result = si_send_msg_to_smc(rdev, PPSMC_TDPClampingActive);
+				if (smc_result != PPSMC_Result_OK) {
+					ret = -EINVAL;
+					ni_pi->pc_enabled = false;
+				} else {
+					ni_pi->pc_enabled = true;
+				}
+			}
+		} else {
+			smc_result = si_send_msg_to_smc(rdev, PPSMC_TDPClampingInactive);
+			if (smc_result != PPSMC_Result_OK)
+				ret = -EINVAL;
+			ni_pi->pc_enabled = false;
+		}
+	}
+
+	return ret;
+}
+
+static int si_initialize_smc_dte_tables(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	int ret = 0;
+	struct si_dte_data *dte_data = &si_pi->dte_data;
+	Smc_SIslands_DTE_Configuration *dte_tables = NULL;
+	u32 table_size;
+	u8 tdep_count;
+	u32 i;
+
+	if (dte_data == NULL)
+		si_pi->enable_dte = false;
+
+	if (si_pi->enable_dte == false)
+		return 0;
+
+	if (dte_data->k <= 0)
+		return -EINVAL;
+
+	dte_tables = kzalloc(sizeof(Smc_SIslands_DTE_Configuration), GFP_KERNEL);
+	if (dte_tables == NULL) {
+		si_pi->enable_dte = false;
+		return -ENOMEM;
+	}
+
+	table_size = dte_data->k;
+
+	if (table_size > SMC_SISLANDS_DTE_MAX_FILTER_STAGES)
+		table_size = SMC_SISLANDS_DTE_MAX_FILTER_STAGES;
+
+	tdep_count = dte_data->tdep_count;
+	if (tdep_count > SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE)
+		tdep_count = SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE;
+
+	dte_tables->K = cpu_to_be32(table_size);
+	dte_tables->T0 = cpu_to_be32(dte_data->t0);
+	dte_tables->MaxT = cpu_to_be32(dte_data->max_t);
+	dte_tables->WindowSize = dte_data->window_size;
+	dte_tables->temp_select = dte_data->temp_select;
+	dte_tables->DTE_mode = dte_data->dte_mode;
+	dte_tables->Tthreshold = cpu_to_be32(dte_data->t_threshold);
+
+	if (tdep_count > 0)
+		table_size--;
+
+	for (i = 0; i < table_size; i++) {
+		dte_tables->tau[i] = cpu_to_be32(dte_data->tau[i]);
+		dte_tables->R[i]   = cpu_to_be32(dte_data->r[i]);
+	}
+
+	dte_tables->Tdep_count = tdep_count;
+
+	for (i = 0; i < (u32)tdep_count; i++) {
+		dte_tables->T_limits[i] = dte_data->t_limits[i];
+		dte_tables->Tdep_tau[i] = cpu_to_be32(dte_data->tdep_tau[i]);
+		dte_tables->Tdep_R[i] = cpu_to_be32(dte_data->tdep_r[i]);
+	}
+
+	ret = si_copy_bytes_to_smc(rdev, si_pi->dte_table_start, (u8 *)dte_tables,
+				   sizeof(Smc_SIslands_DTE_Configuration), si_pi->sram_end);
+	kfree(dte_tables);
+
+	return ret;
+}
+
+static int si_get_cac_std_voltage_max_min(struct radeon_device *rdev,
+					  u16 *max, u16 *min)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct radeon_cac_leakage_table *table =
+		&rdev->pm.dpm.dyn_state.cac_leakage_table;
+	u32 i;
+	u32 v0_loadline;
+
+
+	if (table == NULL)
+		return -EINVAL;
+
+	*max = 0;
+	*min = 0xFFFF;
+
+	for (i = 0; i < table->count; i++) {
+		if (table->entries[i].vddc > *max)
+			*max = table->entries[i].vddc;
+		if (table->entries[i].vddc < *min)
+			*min = table->entries[i].vddc;
+	}
+
+	if (si_pi->powertune_data->lkge_lut_v0_percent > 100)
+		return -EINVAL;
+
+	v0_loadline = (*min) * (100 - si_pi->powertune_data->lkge_lut_v0_percent) / 100;
+
+	if (v0_loadline > 0xFFFFUL)
+		return -EINVAL;
+
+	*min = (u16)v0_loadline;
+
+	if ((*min > *max) || (*max == 0) || (*min == 0))
+		return -EINVAL;
+
+	return 0;
+}
+
+static u16 si_get_cac_std_voltage_step(u16 max, u16 min)
+{
+	return ((max - min) + (SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1)) /
+		SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;
+}
+
+static int si_init_dte_leakage_table(struct radeon_device *rdev,
+				     PP_SIslands_CacConfig *cac_tables,
+				     u16 vddc_max, u16 vddc_min, u16 vddc_step,
+				     u16 t0, u16 t_step)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 leakage;
+	unsigned int i, j;
+	s32 t;
+	u32 smc_leakage;
+	u32 scaling_factor;
+	u16 voltage;
+
+	scaling_factor = si_get_smc_power_scaling_factor(rdev);
+
+	for (i = 0; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i++) {
+		t = (1000 * (i * t_step + t0));
+
+		for (j = 0; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
+			voltage = vddc_max - (vddc_step * j);
+
+			si_calculate_leakage_for_v_and_t(rdev,
+							 &si_pi->powertune_data->leakage_coefficients,
+							 voltage,
+							 t,
+							 si_pi->dyn_powertune_data.cac_leakage,
+							 &leakage);
+
+			smc_leakage = si_scale_power_for_smc(leakage, scaling_factor) / 4;
+
+			if (smc_leakage > 0xFFFF)
+				smc_leakage = 0xFFFF;
+
+			cac_tables->cac_lkge_lut[i][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES-1-j] =
+				cpu_to_be16((u16)smc_leakage);
+		}
+	}
+	return 0;
+}
+
+static int si_init_simplified_leakage_table(struct radeon_device *rdev,
+					    PP_SIslands_CacConfig *cac_tables,
+					    u16 vddc_max, u16 vddc_min, u16 vddc_step)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 leakage;
+	unsigned int i, j;
+	u32 smc_leakage;
+	u32 scaling_factor;
+	u16 voltage;
+
+	scaling_factor = si_get_smc_power_scaling_factor(rdev);
+
+	for (j = 0; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
+		voltage = vddc_max - (vddc_step * j);
+
+		si_calculate_leakage_for_v(rdev,
+					   &si_pi->powertune_data->leakage_coefficients,
+					   si_pi->powertune_data->fixed_kt,
+					   voltage,
+					   si_pi->dyn_powertune_data.cac_leakage,
+					   &leakage);
+
+		smc_leakage = si_scale_power_for_smc(leakage, scaling_factor) / 4;
+
+		if (smc_leakage > 0xFFFF)
+			smc_leakage = 0xFFFF;
+
+		for (i = 0; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i++)
+			cac_tables->cac_lkge_lut[i][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES-1-j] =
+				cpu_to_be16((u16)smc_leakage);
+	}
+	return 0;
+}
+
+static int si_initialize_smc_cac_tables(struct radeon_device *rdev)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	PP_SIslands_CacConfig *cac_tables = NULL;
+	u16 vddc_max, vddc_min, vddc_step;
+	u16 t0, t_step;
+	u32 load_line_slope, reg;
+	int ret = 0;
+	u32 ticks_per_us = radeon_get_xclk(rdev) / 100;
+
+	if (ni_pi->enable_cac == false)
+		return 0;
+
+	cac_tables = kzalloc(sizeof(PP_SIslands_CacConfig), GFP_KERNEL);
+	if (!cac_tables)
+		return -ENOMEM;
+
+	reg = RREG32(CG_CAC_CTRL) & ~CAC_WINDOW_MASK;
+	reg |= CAC_WINDOW(si_pi->powertune_data->cac_window);
+	WREG32(CG_CAC_CTRL, reg);
+
+	si_pi->dyn_powertune_data.cac_leakage = rdev->pm.dpm.cac_leakage;
+	si_pi->dyn_powertune_data.dc_pwr_value =
+		si_pi->powertune_data->dc_cac[NISLANDS_DCCAC_LEVEL_0];
+	si_pi->dyn_powertune_data.wintime = si_calculate_cac_wintime(rdev);
+	si_pi->dyn_powertune_data.shift_n = si_pi->powertune_data->shift_n_default;
+
+	si_pi->dyn_powertune_data.leakage_minimum_temperature = 80 * 1000;
+
+	ret = si_get_cac_std_voltage_max_min(rdev, &vddc_max, &vddc_min);
+	if (ret)
+		goto done_free;
+
+	vddc_step = si_get_cac_std_voltage_step(vddc_max, vddc_min);
+	vddc_min = vddc_max - (vddc_step * (SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1));
+	t_step = 4;
+	t0 = 60;
+
+	if (si_pi->enable_dte || ni_pi->driver_calculate_cac_leakage)
+		ret = si_init_dte_leakage_table(rdev, cac_tables,
+						vddc_max, vddc_min, vddc_step,
+						t0, t_step);
+	else
+		ret = si_init_simplified_leakage_table(rdev, cac_tables,
+						       vddc_max, vddc_min, vddc_step);
+	if (ret)
+		goto done_free;
+
+	load_line_slope = ((u32)rdev->pm.dpm.load_line_slope << SMC_SISLANDS_SCALE_R) / 100;
+
+	cac_tables->l2numWin_TDP = cpu_to_be32(si_pi->dyn_powertune_data.l2_lta_window_size);
+	cac_tables->lts_truncate_n = si_pi->dyn_powertune_data.lts_truncate;
+	cac_tables->SHIFT_N = si_pi->dyn_powertune_data.shift_n;
+	cac_tables->lkge_lut_V0 = cpu_to_be32((u32)vddc_min);
+	cac_tables->lkge_lut_Vstep = cpu_to_be32((u32)vddc_step);
+	cac_tables->R_LL = cpu_to_be32(load_line_slope);
+	cac_tables->WinTime = cpu_to_be32(si_pi->dyn_powertune_data.wintime);
+	cac_tables->calculation_repeats = cpu_to_be32(2);
+	cac_tables->dc_cac = cpu_to_be32(0);
+	cac_tables->log2_PG_LKG_SCALE = 12;
+	cac_tables->cac_temp = si_pi->powertune_data->operating_temp;
+	cac_tables->lkge_lut_T0 = cpu_to_be32((u32)t0);
+	cac_tables->lkge_lut_Tstep = cpu_to_be32((u32)t_step);
+
+	ret = si_copy_bytes_to_smc(rdev, si_pi->cac_table_start, (u8 *)cac_tables,
+				   sizeof(PP_SIslands_CacConfig), si_pi->sram_end);
+
+	if (ret)
+		goto done_free;
+
+	ret = si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_ticks_per_us, ticks_per_us);
+
+done_free:
+	if (ret) {
+		ni_pi->enable_cac = false;
+		ni_pi->enable_power_containment = false;
+	}
+
+	kfree(cac_tables);
+
+	return 0;
+}
+
+static int si_program_cac_config_registers(struct radeon_device *rdev,
+					   const struct si_cac_config_reg *cac_config_regs)
+{
+	const struct si_cac_config_reg *config_regs = cac_config_regs;
+	u32 data = 0, offset;
+
+	if (!config_regs)
+		return -EINVAL;
+
+	while (config_regs->offset != 0xFFFFFFFF) {
+		switch (config_regs->type) {
+		case SISLANDS_CACCONFIG_CGIND:
+			offset = SMC_CG_IND_START + config_regs->offset;
+			if (offset < SMC_CG_IND_END)
+				data = RREG32_SMC(offset);
+			break;
+		default:
+			data = RREG32(config_regs->offset << 2);
+			break;
+		}
+
+		data &= ~config_regs->mask;
+		data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
+
+		switch (config_regs->type) {
+		case SISLANDS_CACCONFIG_CGIND:
+			offset = SMC_CG_IND_START + config_regs->offset;
+			if (offset < SMC_CG_IND_END)
+				WREG32_SMC(offset, data);
+			break;
+		default:
+			WREG32(config_regs->offset << 2, data);
+			break;
+		}
+		config_regs++;
+	}
+	return 0;
+}
+
+static int si_initialize_hardware_cac_manager(struct radeon_device *rdev)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	int ret;
+
+	if ((ni_pi->enable_cac == false) ||
+	    (ni_pi->cac_configuration_required == false))
+		return 0;
+
+	ret = si_program_cac_config_registers(rdev, si_pi->lcac_config);
+	if (ret)
+		return ret;
+	ret = si_program_cac_config_registers(rdev, si_pi->cac_override);
+	if (ret)
+		return ret;
+	ret = si_program_cac_config_registers(rdev, si_pi->cac_weights);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int si_enable_smc_cac(struct radeon_device *rdev,
+			     struct radeon_ps *radeon_new_state,
+			     bool enable)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	PPSMC_Result smc_result;
+	int ret = 0;
+
+	if (ni_pi->enable_cac) {
+		if (enable) {
+			if (!si_should_disable_uvd_powertune(rdev, radeon_new_state)) {
+				if (ni_pi->support_cac_long_term_average) {
+					smc_result = si_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgEnable);
+					if (smc_result != PPSMC_Result_OK)
+						ni_pi->support_cac_long_term_average = false;
+				}
+
+				smc_result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableCac);
+				if (smc_result != PPSMC_Result_OK) {
+					ret = -EINVAL;
+					ni_pi->cac_enabled = false;
+				} else {
+					ni_pi->cac_enabled = true;
+				}
+
+				if (si_pi->enable_dte) {
+					smc_result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableDTE);
+					if (smc_result != PPSMC_Result_OK)
+						ret = -EINVAL;
+				}
+			}
+		} else if (ni_pi->cac_enabled) {
+			if (si_pi->enable_dte)
+				smc_result = si_send_msg_to_smc(rdev, PPSMC_MSG_DisableDTE);
+
+			smc_result = si_send_msg_to_smc(rdev, PPSMC_MSG_DisableCac);
+
+			ni_pi->cac_enabled = false;
+
+			if (ni_pi->support_cac_long_term_average)
+				smc_result = si_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgDisable);
+		}
+	}
+	return ret;
+}
+
+static int si_init_smc_spll_table(struct radeon_device *rdev)
+{
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	SMC_SISLANDS_SPLL_DIV_TABLE *spll_table;
+	SISLANDS_SMC_SCLK_VALUE sclk_params;
+	u32 fb_div, p_div;
+	u32 clk_s, clk_v;
+	u32 sclk = 0;
+	int ret = 0;
+	u32 tmp;
+	int i;
+
+	if (si_pi->spll_table_start == 0)
+		return -EINVAL;
+
+	spll_table = kzalloc(sizeof(SMC_SISLANDS_SPLL_DIV_TABLE), GFP_KERNEL);
+	if (spll_table == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < 256; i++) {
+		ret = si_calculate_sclk_params(rdev, sclk, &sclk_params);
+		if (ret)
+			break;
+
+		p_div = (sclk_params.vCG_SPLL_FUNC_CNTL & SPLL_PDIV_A_MASK) >> SPLL_PDIV_A_SHIFT;
+		fb_div = (sclk_params.vCG_SPLL_FUNC_CNTL_3 & SPLL_FB_DIV_MASK) >> SPLL_FB_DIV_SHIFT;
+		clk_s = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM & CLK_S_MASK) >> CLK_S_SHIFT;
+		clk_v = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM_2 & CLK_V_MASK) >> CLK_V_SHIFT;
+
+		fb_div &= ~0x00001FFF;
+		fb_div >>= 1;
+		clk_v >>= 6;
+
+		if (p_div & ~(SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT))
+			ret = -EINVAL;
+		if (fb_div & ~(SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT))
+			ret = -EINVAL;
+		if (clk_s & ~(SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))
+			ret = -EINVAL;
+		if (clk_v & ~(SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT))
+			ret = -EINVAL;
+
+		if (ret)
+			break;
+
+		tmp = ((fb_div << SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK) |
+			((p_div << SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK);
+		spll_table->freq[i] = cpu_to_be32(tmp);
+
+		tmp = ((clk_v << SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK) |
+			((clk_s << SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK);
+		spll_table->ss[i] = cpu_to_be32(tmp);
+
+		sclk += 512;
+	}
+
+
+	if (!ret)
+		ret = si_copy_bytes_to_smc(rdev, si_pi->spll_table_start,
+					   (u8 *)spll_table, sizeof(SMC_SISLANDS_SPLL_DIV_TABLE),
+					   si_pi->sram_end);
+
+	if (ret)
+		ni_pi->enable_power_containment = false;
+
+	kfree(spll_table);
+
+	return ret;
+}
+
+static void si_apply_state_adjust_rules(struct radeon_device *rdev,
+					struct radeon_ps *rps)
+{
+	struct ni_ps *ps = ni_get_ps(rps);
+	struct radeon_clock_and_voltage_limits *max_limits;
+	bool disable_mclk_switching = false;
+	bool disable_sclk_switching = false;
+	u32 mclk, sclk;
+	u16 vddc, vddci;
+	int i;
+
+	if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
+	    ni_dpm_vblank_too_short(rdev))
+		disable_mclk_switching = true;
+
+	if (rps->vclk || rps->dclk) {
+		disable_mclk_switching = true;
+		disable_sclk_switching = true;
+	}
+
+	if (rdev->pm.dpm.ac_power)
+		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
+	else
+		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
+
+	for (i = ps->performance_level_count - 2; i >= 0; i--) {
+		if (ps->performance_levels[i].vddc > ps->performance_levels[i+1].vddc)
+			ps->performance_levels[i].vddc = ps->performance_levels[i+1].vddc;
+	}
+	if (rdev->pm.dpm.ac_power == false) {
+		for (i = 0; i < ps->performance_level_count; i++) {
+			if (ps->performance_levels[i].mclk > max_limits->mclk)
+				ps->performance_levels[i].mclk = max_limits->mclk;
+			if (ps->performance_levels[i].sclk > max_limits->sclk)
+				ps->performance_levels[i].sclk = max_limits->sclk;
+			if (ps->performance_levels[i].vddc > max_limits->vddc)
+				ps->performance_levels[i].vddc = max_limits->vddc;
+			if (ps->performance_levels[i].vddci > max_limits->vddci)
+				ps->performance_levels[i].vddci = max_limits->vddci;
+		}
+	}
+
+	/* XXX validate the min clocks required for display */
+
+	if (disable_mclk_switching) {
+		mclk  = ps->performance_levels[ps->performance_level_count - 1].mclk;
+		vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
+	} else {
+		mclk = ps->performance_levels[0].mclk;
+		vddci = ps->performance_levels[0].vddci;
+	}
+
+	if (disable_sclk_switching) {
+		sclk = ps->performance_levels[ps->performance_level_count - 1].sclk;
+		vddc = ps->performance_levels[ps->performance_level_count - 1].vddc;
+	} else {
+		sclk = ps->performance_levels[0].sclk;
+		vddc = ps->performance_levels[0].vddc;
+	}
+
+	/* adjusted low state */
+	ps->performance_levels[0].sclk = sclk;
+	ps->performance_levels[0].mclk = mclk;
+	ps->performance_levels[0].vddc = vddc;
+	ps->performance_levels[0].vddci = vddci;
+
+	if (disable_sclk_switching) {
+		sclk = ps->performance_levels[0].sclk;
+		for (i = 1; i < ps->performance_level_count; i++) {
+			if (sclk < ps->performance_levels[i].sclk)
+				sclk = ps->performance_levels[i].sclk;
+		}
+		for (i = 0; i < ps->performance_level_count; i++) {
+			ps->performance_levels[i].sclk = sclk;
+			ps->performance_levels[i].vddc = vddc;
+		}
+	} else {
+		for (i = 1; i < ps->performance_level_count; i++) {
+			if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
+				ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
+			if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
+				ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
+		}
+	}
+
+	if (disable_mclk_switching) {
+		mclk = ps->performance_levels[0].mclk;
+		for (i = 1; i < ps->performance_level_count; i++) {
+			if (mclk < ps->performance_levels[i].mclk)
+				mclk = ps->performance_levels[i].mclk;
+		}
+		for (i = 0; i < ps->performance_level_count; i++) {
+			ps->performance_levels[i].mclk = mclk;
+			ps->performance_levels[i].vddci = vddci;
+		}
+	} else {
+		for (i = 1; i < ps->performance_level_count; i++) {
+			if (ps->performance_levels[i].mclk < ps->performance_levels[i - 1].mclk)
+				ps->performance_levels[i].mclk = ps->performance_levels[i - 1].mclk;
+			if (ps->performance_levels[i].vddci < ps->performance_levels[i - 1].vddci)
+				ps->performance_levels[i].vddci = ps->performance_levels[i - 1].vddci;
+		}
+	}
+
+        for (i = 0; i < ps->performance_level_count; i++)
+                btc_adjust_clock_combinations(rdev, max_limits,
+                                              &ps->performance_levels[i]);
+
+	for (i = 0; i < ps->performance_level_count; i++) {
+		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
+						   ps->performance_levels[i].sclk,
+						   max_limits->vddc,  &ps->performance_levels[i].vddc);
+		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+						   ps->performance_levels[i].mclk,
+						   max_limits->vddci, &ps->performance_levels[i].vddci);
+		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+						   ps->performance_levels[i].mclk,
+						   max_limits->vddc,  &ps->performance_levels[i].vddc);
+		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+						   rdev->clock.current_dispclk,
+						   max_limits->vddc,  &ps->performance_levels[i].vddc);
+	}
+
+	for (i = 0; i < ps->performance_level_count; i++) {
+		btc_apply_voltage_delta_rules(rdev,
+					      max_limits->vddc, max_limits->vddci,
+					      &ps->performance_levels[i].vddc,
+					      &ps->performance_levels[i].vddci);
+	}
+
+	ps->dc_compatible = true;
+	for (i = 0; i < ps->performance_level_count; i++) {
+		if (ps->performance_levels[i].vddc > rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc)
+			ps->dc_compatible = false;
+	}
+
+}
+
+#if 0
+static int si_read_smc_soft_register(struct radeon_device *rdev,
+				     u16 reg_offset, u32 *value)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+
+	return si_read_smc_sram_dword(rdev,
+				      si_pi->soft_regs_start + reg_offset, value,
+				      si_pi->sram_end);
+}
+#endif
+
+static int si_write_smc_soft_register(struct radeon_device *rdev,
+				      u16 reg_offset, u32 value)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+
+	return si_write_smc_sram_dword(rdev,
+				       si_pi->soft_regs_start + reg_offset,
+				       value, si_pi->sram_end);
+}
+
+static bool si_is_special_1gb_platform(struct radeon_device *rdev)
+{
+	bool ret = false;
+	u32 tmp, width, row, column, bank, density;
+	bool is_memory_gddr5, is_special;
+
+	tmp = RREG32(MC_SEQ_MISC0);
+	is_memory_gddr5 = (MC_SEQ_MISC0_GDDR5_VALUE == ((tmp & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT));
+	is_special = (MC_SEQ_MISC0_REV_ID_VALUE == ((tmp & MC_SEQ_MISC0_REV_ID_MASK) >> MC_SEQ_MISC0_REV_ID_SHIFT))
+		& (MC_SEQ_MISC0_VEN_ID_VALUE == ((tmp & MC_SEQ_MISC0_VEN_ID_MASK) >> MC_SEQ_MISC0_VEN_ID_SHIFT));
+
+	WREG32(MC_SEQ_IO_DEBUG_INDEX, 0xb);
+	width = ((RREG32(MC_SEQ_IO_DEBUG_DATA) >> 1) & 1) ? 16 : 32;
+
+	tmp = RREG32(MC_ARB_RAMCFG);
+	row = ((tmp & NOOFROWS_MASK) >> NOOFROWS_SHIFT) + 10;
+	column = ((tmp & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT) + 8;
+	bank = ((tmp & NOOFBANK_MASK) >> NOOFBANK_SHIFT) + 2;
+
+	density = (1 << (row + column - 20 + bank)) * width;
+
+	if ((rdev->pdev->device == 0x6819) &&
+	    is_memory_gddr5 && is_special && (density == 0x400))
+		ret = true;
+
+	return ret;
+}
+
+static void si_get_leakage_vddc(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u16 vddc, count = 0;
+	int i, ret;
+
+	for (i = 0; i < SISLANDS_MAX_LEAKAGE_COUNT; i++) {
+		ret = radeon_atom_get_leakage_vddc_based_on_leakage_idx(rdev, &vddc, SISLANDS_LEAKAGE_INDEX0 + i);
+
+		if (!ret && (vddc > 0) && (vddc != (SISLANDS_LEAKAGE_INDEX0 + i))) {
+			si_pi->leakage_voltage.entries[count].voltage = vddc;
+			si_pi->leakage_voltage.entries[count].leakage_index =
+				SISLANDS_LEAKAGE_INDEX0 + i;
+			count++;
+		}
+	}
+	si_pi->leakage_voltage.count = count;
+}
+
+static int si_get_leakage_voltage_from_leakage_index(struct radeon_device *rdev,
+						     u32 index, u16 *leakage_voltage)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	int i;
+
+	if (leakage_voltage == NULL)
+		return -EINVAL;
+
+	if ((index & 0xff00) != 0xff00)
+		return -EINVAL;
+
+	if ((index & 0xff) > SISLANDS_MAX_LEAKAGE_COUNT + 1)
+		return -EINVAL;
+
+	if (index < SISLANDS_LEAKAGE_INDEX0)
+		return -EINVAL;
+
+	for (i = 0; i < si_pi->leakage_voltage.count; i++) {
+		if (si_pi->leakage_voltage.entries[i].leakage_index == index) {
+			*leakage_voltage = si_pi->leakage_voltage.entries[i].voltage;
+			return 0;
+		}
+	}
+	return -EAGAIN;
+}
+
+static void si_set_dpm_event_sources(struct radeon_device *rdev, u32 sources)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	bool want_thermal_protection;
+	enum radeon_dpm_event_src dpm_event_src;
+
+	switch (sources) {
+	case 0:
+	default:
+		want_thermal_protection = false;
+                break;
+	case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL):
+		want_thermal_protection = true;
+		dpm_event_src = RADEON_DPM_EVENT_SRC_DIGITAL;
+		break;
+	case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL):
+		want_thermal_protection = true;
+		dpm_event_src = RADEON_DPM_EVENT_SRC_EXTERNAL;
+		break;
+	case ((1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL) |
+	      (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL)):
+		want_thermal_protection = true;
+		dpm_event_src = RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL;
+		break;
+	}
+
+	if (want_thermal_protection) {
+		WREG32_P(CG_THERMAL_CTRL, DPM_EVENT_SRC(dpm_event_src), ~DPM_EVENT_SRC_MASK);
+		if (pi->thermal_protection)
+			WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
+	} else {
+		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
+	}
+}
+
+static void si_enable_auto_throttle_source(struct radeon_device *rdev,
+					   enum radeon_dpm_auto_throttle_src source,
+					   bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (enable) {
+		if (!(pi->active_auto_throttle_sources & (1 << source))) {
+			pi->active_auto_throttle_sources |= 1 << source;
+			si_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
+		}
+	} else {
+		if (pi->active_auto_throttle_sources & (1 << source)) {
+			pi->active_auto_throttle_sources &= ~(1 << source);
+			si_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
+		}
+	}
+}
+
+static void si_start_dpm(struct radeon_device *rdev)
+{
+	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
+}
+
+static void si_stop_dpm(struct radeon_device *rdev)
+{
+	WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
+}
+
+static void si_enable_sclk_control(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
+	else
+		WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
+
+}
+
+#if 0
+static int si_notify_hardware_of_thermal_state(struct radeon_device *rdev,
+					       u32 thermal_level)
+{
+	PPSMC_Result ret;
+
+	if (thermal_level == 0) {
+		ret = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
+		if (ret == PPSMC_Result_OK)
+			return 0;
+		else
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static void si_notify_hardware_vpu_recovery_event(struct radeon_device *rdev)
+{
+	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen, true);
+}
+#endif
+
+#if 0
+static int si_notify_hw_of_powersource(struct radeon_device *rdev, bool ac_power)
+{
+	if (ac_power)
+		return (si_send_msg_to_smc(rdev, PPSMC_MSG_RunningOnAC) == PPSMC_Result_OK) ?
+			0 : -EINVAL;
+
+	return 0;
+}
+#endif
+
+static PPSMC_Result si_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
+						      PPSMC_Msg msg, u32 parameter)
+{
+	WREG32(SMC_SCRATCH0, parameter);
+	return si_send_msg_to_smc(rdev, msg);
+}
+
+static int si_restrict_performance_levels_before_switch(struct radeon_device *rdev)
+{
+	if (si_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	return (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) == PPSMC_Result_OK) ?
+		0 : -EINVAL;
+}
+
+int si_dpm_force_performance_level(struct radeon_device *rdev,
+				   enum radeon_dpm_forced_level level)
+{
+	struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+	struct ni_ps *ps = ni_get_ps(rps);
+	u32 levels = ps->performance_level_count;
+
+	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
+		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)
+			return -EINVAL;
+
+		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK)
+			return -EINVAL;
+	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
+		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
+			return -EINVAL;
+
+		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK)
+			return -EINVAL;
+	} else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) {
+		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
+			return -EINVAL;
+
+		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)
+			return -EINVAL;
+	}
+
+	rdev->pm.dpm.forced_level = level;
+
+	return 0;
+}
+
+static int si_set_boot_state(struct radeon_device *rdev)
+{
+	return (si_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ?
+		0 : -EINVAL;
+}
+
+static int si_set_sw_state(struct radeon_device *rdev)
+{
+	return (si_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToSwState) == PPSMC_Result_OK) ?
+		0 : -EINVAL;
+}
+
+static int si_halt_smc(struct radeon_device *rdev)
+{
+	if (si_send_msg_to_smc(rdev, PPSMC_MSG_Halt) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	return (si_wait_for_smc_inactive(rdev) == PPSMC_Result_OK) ?
+		0 : -EINVAL;
+}
+
+static int si_resume_smc(struct radeon_device *rdev)
+{
+	if (si_send_msg_to_smc(rdev, PPSMC_FlushDataCache) != PPSMC_Result_OK)
+		return -EINVAL;
+
+	return (si_send_msg_to_smc(rdev, PPSMC_MSG_Resume) == PPSMC_Result_OK) ?
+		0 : -EINVAL;
+}
+
+static void si_dpm_start_smc(struct radeon_device *rdev)
+{
+	si_program_jump_on_start(rdev);
+	si_start_smc(rdev);
+	si_start_smc_clock(rdev);
+}
+
+static void si_dpm_stop_smc(struct radeon_device *rdev)
+{
+	si_reset_smc(rdev);
+	si_stop_smc_clock(rdev);
+}
+
+static int si_process_firmware_header(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 tmp;
+	int ret;
+
+	ret = si_read_smc_sram_dword(rdev,
+				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+				     SISLANDS_SMC_FIRMWARE_HEADER_stateTable,
+				     &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+        si_pi->state_table_start = tmp;
+
+	ret = si_read_smc_sram_dword(rdev,
+				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+				     SISLANDS_SMC_FIRMWARE_HEADER_softRegisters,
+				     &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+	si_pi->soft_regs_start = tmp;
+
+	ret = si_read_smc_sram_dword(rdev,
+				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+				     SISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable,
+				     &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+	si_pi->mc_reg_table_start = tmp;
+
+	ret = si_read_smc_sram_dword(rdev,
+				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+				     SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable,
+				     &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+	si_pi->arb_table_start = tmp;
+
+	ret = si_read_smc_sram_dword(rdev,
+				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+				     SISLANDS_SMC_FIRMWARE_HEADER_CacConfigTable,
+				     &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+	si_pi->cac_table_start = tmp;
+
+	ret = si_read_smc_sram_dword(rdev,
+				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+				     SISLANDS_SMC_FIRMWARE_HEADER_DteConfiguration,
+				     &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+	si_pi->dte_table_start = tmp;
+
+	ret = si_read_smc_sram_dword(rdev,
+				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+				     SISLANDS_SMC_FIRMWARE_HEADER_spllTable,
+				     &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+	si_pi->spll_table_start = tmp;
+
+	ret = si_read_smc_sram_dword(rdev,
+				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
+				     SISLANDS_SMC_FIRMWARE_HEADER_PAPMParameters,
+				     &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+	si_pi->papm_cfg_table_start = tmp;
+
+	return ret;
+}
+
+static void si_read_clock_registers(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+
+	si_pi->clock_registers.cg_spll_func_cntl = RREG32(CG_SPLL_FUNC_CNTL);
+	si_pi->clock_registers.cg_spll_func_cntl_2 = RREG32(CG_SPLL_FUNC_CNTL_2);
+	si_pi->clock_registers.cg_spll_func_cntl_3 = RREG32(CG_SPLL_FUNC_CNTL_3);
+	si_pi->clock_registers.cg_spll_func_cntl_4 = RREG32(CG_SPLL_FUNC_CNTL_4);
+	si_pi->clock_registers.cg_spll_spread_spectrum = RREG32(CG_SPLL_SPREAD_SPECTRUM);
+	si_pi->clock_registers.cg_spll_spread_spectrum_2 = RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
+	si_pi->clock_registers.dll_cntl = RREG32(DLL_CNTL);
+	si_pi->clock_registers.mclk_pwrmgt_cntl = RREG32(MCLK_PWRMGT_CNTL);
+	si_pi->clock_registers.mpll_ad_func_cntl = RREG32(MPLL_AD_FUNC_CNTL);
+	si_pi->clock_registers.mpll_dq_func_cntl = RREG32(MPLL_DQ_FUNC_CNTL);
+	si_pi->clock_registers.mpll_func_cntl = RREG32(MPLL_FUNC_CNTL);
+	si_pi->clock_registers.mpll_func_cntl_1 = RREG32(MPLL_FUNC_CNTL_1);
+	si_pi->clock_registers.mpll_func_cntl_2 = RREG32(MPLL_FUNC_CNTL_2);
+	si_pi->clock_registers.mpll_ss1 = RREG32(MPLL_SS1);
+	si_pi->clock_registers.mpll_ss2 = RREG32(MPLL_SS2);
+}
+
+static void si_enable_thermal_protection(struct radeon_device *rdev,
+					  bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
+	else
+		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
+}
+
+static void si_enable_acpi_power_management(struct radeon_device *rdev)
+{
+	WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
+}
+
+#if 0
+static int si_enter_ulp_state(struct radeon_device *rdev)
+{
+	WREG32(SMC_MESSAGE_0, PPSMC_MSG_SwitchToMinimumPower);
+
+	udelay(25000);
+
+	return 0;
+}
+
+static int si_exit_ulp_state(struct radeon_device *rdev)
+{
+	int i;
+
+	WREG32(SMC_MESSAGE_0, PPSMC_MSG_ResumeFromMinimumPower);
+
+	udelay(7000);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(SMC_RESP_0) == 1)
+			break;
+		udelay(1000);
+	}
+
+	return 0;
+}
+#endif
+
+static int si_notify_smc_display_change(struct radeon_device *rdev,
+				     bool has_display)
+{
+	PPSMC_Msg msg = has_display ?
+		PPSMC_MSG_HasDisplay : PPSMC_MSG_NoDisplay;
+
+	return (si_send_msg_to_smc(rdev, msg) == PPSMC_Result_OK) ?
+		0 : -EINVAL;
+}
+
+static void si_program_response_times(struct radeon_device *rdev)
+{
+	u32 voltage_response_time, backbias_response_time, acpi_delay_time, vbi_time_out;
+	u32 vddc_dly, acpi_dly, vbi_dly;
+	u32 reference_clock;
+
+	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_mvdd_chg_time, 1);
+
+	voltage_response_time = (u32)rdev->pm.dpm.voltage_response_time;
+        backbias_response_time = (u32)rdev->pm.dpm.backbias_response_time;
+
+	if (voltage_response_time == 0)
+		voltage_response_time = 1000;
+
+	acpi_delay_time = 15000;
+	vbi_time_out = 100000;
+
+	reference_clock = radeon_get_xclk(rdev);
+
+	vddc_dly = (voltage_response_time  * reference_clock) / 100;
+	acpi_dly = (acpi_delay_time * reference_clock) / 100;
+	vbi_dly  = (vbi_time_out * reference_clock) / 100;
+
+	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_delay_vreg,  vddc_dly);
+	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_delay_acpi,  acpi_dly);
+	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);
+	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_mc_block_delay, 0xAA);
+}
+
+static void si_program_ds_registers(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	u32 tmp = 1; /* XXX: 0x10 on tahiti A0 */
+
+	if (eg_pi->sclk_deep_sleep) {
+		WREG32_P(MISC_CLK_CNTL, DEEP_SLEEP_CLK_SEL(tmp), ~DEEP_SLEEP_CLK_SEL_MASK);
+		WREG32_P(CG_SPLL_AUTOSCALE_CNTL, AUTOSCALE_ON_SS_CLEAR,
+			 ~AUTOSCALE_ON_SS_CLEAR);
+	}
+}
+
+static void si_program_display_gap(struct radeon_device *rdev)
+{
+	u32 tmp, pipe;
+	int i;
+
+	tmp = RREG32(CG_DISPLAY_GAP_CNTL) & ~(DISP1_GAP_MASK | DISP2_GAP_MASK);
+	if (rdev->pm.dpm.new_active_crtc_count > 0)
+		tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM);
+	else
+		tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE);
+
+	if (rdev->pm.dpm.new_active_crtc_count > 1)
+		tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM);
+	else
+		tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE);
+
+	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
+
+	tmp = RREG32(DCCG_DISP_SLOW_SELECT_REG);
+	pipe = (tmp & DCCG_DISP1_SLOW_SELECT_MASK) >> DCCG_DISP1_SLOW_SELECT_SHIFT;
+
+	if ((rdev->pm.dpm.new_active_crtc_count > 0) &&
+	    (!(rdev->pm.dpm.new_active_crtcs & (1 << pipe)))) {
+		/* find the first active crtc */
+		for (i = 0; i < rdev->num_crtc; i++) {
+			if (rdev->pm.dpm.new_active_crtcs & (1 << i))
+				break;
+		}
+		if (i == rdev->num_crtc)
+			pipe = 0;
+		else
+			pipe = i;
+
+		tmp &= ~DCCG_DISP1_SLOW_SELECT_MASK;
+		tmp |= DCCG_DISP1_SLOW_SELECT(pipe);
+		WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp);
+	}
+
+	si_notify_smc_display_change(rdev, rdev->pm.dpm.new_active_crtc_count > 0);
+}
+
+static void si_enable_spread_spectrum(struct radeon_device *rdev, bool enable)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	if (enable) {
+		if (pi->sclk_ss)
+			WREG32_P(GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, ~DYN_SPREAD_SPECTRUM_EN);
+	} else {
+		WREG32_P(CG_SPLL_SPREAD_SPECTRUM, 0, ~SSEN);
+		WREG32_P(GENERAL_PWRMGT, 0, ~DYN_SPREAD_SPECTRUM_EN);
+	}
+}
+
+static void si_setup_bsp(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u32 xclk = radeon_get_xclk(rdev);
+
+	r600_calculate_u_and_p(pi->asi,
+			       xclk,
+			       16,
+			       &pi->bsp,
+			       &pi->bsu);
+
+	r600_calculate_u_and_p(pi->pasi,
+			       xclk,
+			       16,
+			       &pi->pbsp,
+			       &pi->pbsu);
+
+
+        pi->dsp = BSP(pi->bsp) | BSU(pi->bsu);
+	pi->psp = BSP(pi->pbsp) | BSU(pi->pbsu);
+
+	WREG32(CG_BSP, pi->dsp);
+}
+
+static void si_program_git(struct radeon_device *rdev)
+{
+	WREG32_P(CG_GIT, CG_GICST(R600_GICST_DFLT), ~CG_GICST_MASK);
+}
+
+static void si_program_tp(struct radeon_device *rdev)
+{
+	int i;
+	enum r600_td td = R600_TD_DFLT;
+
+	for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)
+		WREG32(CG_FFCT_0 + (i * 4), (UTC_0(r600_utc[i]) | DTC_0(r600_dtc[i])));
+
+	if (td == R600_TD_AUTO)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
+	else
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
+
+	if (td == R600_TD_UP)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
+
+	if (td == R600_TD_DOWN)
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
+}
+
+static void si_program_tpp(struct radeon_device *rdev)
+{
+	WREG32(CG_TPC, R600_TPC_DFLT);
+}
+
+static void si_program_sstp(struct radeon_device *rdev)
+{
+	WREG32(CG_SSP, (SSTU(R600_SSTU_DFLT) | SST(R600_SST_DFLT)));
+}
+
+static void si_enable_display_gap(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
+
+	tmp &= ~(DISP1_GAP_MASK | DISP2_GAP_MASK);
+	tmp |= (DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE) |
+		DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE));
+
+	tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
+	tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK) |
+		DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE));
+	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
+}
+
+static void si_program_vc(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	WREG32(CG_FTV, pi->vrc);
+}
+
+static void si_clear_vc(struct radeon_device *rdev)
+{
+	WREG32(CG_FTV, 0);
+}
+
+static u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock)
+{
+	u8 mc_para_index;
+
+	if (memory_clock < 10000)
+		mc_para_index = 0;
+	else if (memory_clock >= 80000)
+		mc_para_index = 0x0f;
+	else
+		mc_para_index = (u8)((memory_clock - 10000) / 5000 + 1);
+	return mc_para_index;
+}
+
+static u8 si_get_mclk_frequency_ratio(u32 memory_clock, bool strobe_mode)
+{
+	u8 mc_para_index;
+
+	if (strobe_mode) {
+		if (memory_clock < 12500)
+			mc_para_index = 0x00;
+		else if (memory_clock > 47500)
+			mc_para_index = 0x0f;
+		else
+			mc_para_index = (u8)((memory_clock - 10000) / 2500);
+	} else {
+		if (memory_clock < 65000)
+			mc_para_index = 0x00;
+		else if (memory_clock > 135000)
+			mc_para_index = 0x0f;
+		else
+			mc_para_index = (u8)((memory_clock - 60000) / 5000);
+	}
+	return mc_para_index;
+}
+
+static u8 si_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	bool strobe_mode = false;
+	u8 result = 0;
+
+	if (mclk <= pi->mclk_strobe_mode_threshold)
+		strobe_mode = true;
+
+	if (pi->mem_gddr5)
+		result = si_get_mclk_frequency_ratio(mclk, strobe_mode);
+	else
+		result = si_get_ddr3_mclk_frequency_ratio(mclk);
+
+	if (strobe_mode)
+		result |= SISLANDS_SMC_STROBE_ENABLE;
+
+	return result;
+}
+
+static int si_upload_firmware(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	int ret;
+
+	si_reset_smc(rdev);
+	si_stop_smc_clock(rdev);
+
+	ret = si_load_smc_ucode(rdev, si_pi->sram_end);
+
+	return ret;
+}
+
+static bool si_validate_phase_shedding_tables(struct radeon_device *rdev,
+					      const struct atom_voltage_table *table,
+					      const struct radeon_phase_shedding_limits_table *limits)
+{
+	u32 data, num_bits, num_levels;
+
+	if ((table == NULL) || (limits == NULL))
+		return false;
+
+	data = table->mask_low;
+
+	num_bits = hweight32(data);
+
+	if (num_bits == 0)
+		return false;
+
+	num_levels = (1 << num_bits);
+
+	if (table->count != num_levels)
+		return false;
+
+	if (limits->count != (num_levels - 1))
+		return false;
+
+	return true;
+}
+
+static void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev,
+						     struct atom_voltage_table *voltage_table)
+{
+	unsigned int i, diff;
+
+	if (voltage_table->count <= SISLANDS_MAX_NO_VREG_STEPS)
+		return;
+
+	diff = voltage_table->count - SISLANDS_MAX_NO_VREG_STEPS;
+
+	for (i= 0; i < SISLANDS_MAX_NO_VREG_STEPS; i++)
+		voltage_table->entries[i] = voltage_table->entries[i + diff];
+
+	voltage_table->count = SISLANDS_MAX_NO_VREG_STEPS;
+}
+
+static int si_construct_voltage_tables(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	int ret;
+
+	ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDC,
+					    VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddc_voltage_table);
+	if (ret)
+		return ret;
+
+	if (eg_pi->vddc_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
+		si_trim_voltage_table_to_fit_state_table(rdev, &eg_pi->vddc_voltage_table);
+
+	if (eg_pi->vddci_control) {
+		ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDCI,
+						    VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddci_voltage_table);
+		if (ret)
+			return ret;
+
+		if (eg_pi->vddci_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
+			si_trim_voltage_table_to_fit_state_table(rdev, &eg_pi->vddci_voltage_table);
+	}
+
+	if (pi->mvdd_control) {
+		ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_MVDDC,
+						    VOLTAGE_OBJ_GPIO_LUT, &si_pi->mvdd_voltage_table);
+
+		if (ret) {
+			pi->mvdd_control = false;
+			return ret;
+		}
+
+		if (si_pi->mvdd_voltage_table.count == 0) {
+			pi->mvdd_control = false;
+			return -EINVAL;
+		}
+
+		if (si_pi->mvdd_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
+			si_trim_voltage_table_to_fit_state_table(rdev, &si_pi->mvdd_voltage_table);
+	}
+
+	if (si_pi->vddc_phase_shed_control) {
+		ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDC,
+						    VOLTAGE_OBJ_PHASE_LUT, &si_pi->vddc_phase_shed_table);
+		if (ret)
+			si_pi->vddc_phase_shed_control = false;
+
+		if ((si_pi->vddc_phase_shed_table.count == 0) ||
+		    (si_pi->vddc_phase_shed_table.count > SISLANDS_MAX_NO_VREG_STEPS))
+			si_pi->vddc_phase_shed_control = false;
+	}
+
+	return 0;
+}
+
+static void si_populate_smc_voltage_table(struct radeon_device *rdev,
+					  const struct atom_voltage_table *voltage_table,
+					  SISLANDS_SMC_STATETABLE *table)
+{
+	unsigned int i;
+
+	for (i = 0; i < voltage_table->count; i++)
+		table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low);
+}
+
+static int si_populate_smc_voltage_tables(struct radeon_device *rdev,
+					  SISLANDS_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u8 i;
+
+	if (eg_pi->vddc_voltage_table.count) {
+		si_populate_smc_voltage_table(rdev, &eg_pi->vddc_voltage_table, table);
+		table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
+			cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
+
+		for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {
+			if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {
+				table->maxVDDCIndexInPPTable = i;
+				break;
+			}
+		}
+	}
+
+	if (eg_pi->vddci_voltage_table.count) {
+		si_populate_smc_voltage_table(rdev, &eg_pi->vddci_voltage_table, table);
+
+		table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDCI] =
+			cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);
+	}
+
+
+	if (si_pi->mvdd_voltage_table.count) {
+		si_populate_smc_voltage_table(rdev, &si_pi->mvdd_voltage_table, table);
+
+		table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_MVDD] =
+			cpu_to_be32(si_pi->mvdd_voltage_table.mask_low);
+	}
+
+	if (si_pi->vddc_phase_shed_control) {
+		if (si_validate_phase_shedding_tables(rdev, &si_pi->vddc_phase_shed_table,
+						      &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) {
+			si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table);
+
+			table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
+				cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);
+
+			si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,
+						   (u32)si_pi->vddc_phase_shed_table.phase_delay);
+		} else {
+			si_pi->vddc_phase_shed_control = false;
+		}
+	}
+
+	return 0;
+}
+
+static int si_populate_voltage_value(struct radeon_device *rdev,
+				     const struct atom_voltage_table *table,
+				     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage)
+{
+	unsigned int i;
+
+	for (i = 0; i < table->count; i++) {
+		if (value <= table->entries[i].value) {
+			voltage->index = (u8)i;
+			voltage->value = cpu_to_be16(table->entries[i].value);
+			break;
+		}
+	}
+
+	if (i >= table->count)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int si_populate_mvdd_value(struct radeon_device *rdev, u32 mclk,
+				  SISLANDS_SMC_VOLTAGE_VALUE *voltage)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+
+	if (pi->mvdd_control) {
+		if (mclk <= pi->mvdd_split_frequency)
+			voltage->index = 0;
+		else
+			voltage->index = (u8)(si_pi->mvdd_voltage_table.count) - 1;
+
+		voltage->value = cpu_to_be16(si_pi->mvdd_voltage_table.entries[voltage->index].value);
+	}
+	return 0;
+}
+
+static int si_get_std_voltage_value(struct radeon_device *rdev,
+				    SISLANDS_SMC_VOLTAGE_VALUE *voltage,
+				    u16 *std_voltage)
+{
+	u16 v_index;
+	bool voltage_found = false;
+	*std_voltage = be16_to_cpu(voltage->value);
+
+	if (rdev->pm.dpm.dyn_state.cac_leakage_table.entries) {
+		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_NEW_CAC_VOLTAGE) {
+			if (rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries == NULL)
+				return -EINVAL;
+
+			for (v_index = 0; (u32)v_index < rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {
+				if (be16_to_cpu(voltage->value) ==
+				    (u16)rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {
+					voltage_found = true;
+					if ((u32)v_index < rdev->pm.dpm.dyn_state.cac_leakage_table.count)
+						*std_voltage =
+							rdev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;
+					else
+						*std_voltage =
+							rdev->pm.dpm.dyn_state.cac_leakage_table.entries[rdev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;
+					break;
+				}
+			}
+
+			if (!voltage_found) {
+				for (v_index = 0; (u32)v_index < rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {
+					if (be16_to_cpu(voltage->value) <=
+					    (u16)rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {
+						voltage_found = true;
+						if ((u32)v_index < rdev->pm.dpm.dyn_state.cac_leakage_table.count)
+							*std_voltage =
+								rdev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;
+						else
+							*std_voltage =
+								rdev->pm.dpm.dyn_state.cac_leakage_table.entries[rdev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;
+						break;
+					}
+				}
+			}
+		} else {
+			if ((u32)voltage->index < rdev->pm.dpm.dyn_state.cac_leakage_table.count)
+				*std_voltage = rdev->pm.dpm.dyn_state.cac_leakage_table.entries[voltage->index].vddc;
+		}
+	}
+
+	return 0;
+}
+
+static int si_populate_std_voltage_value(struct radeon_device *rdev,
+					 u16 value, u8 index,
+					 SISLANDS_SMC_VOLTAGE_VALUE *voltage)
+{
+	voltage->index = index;
+	voltage->value = cpu_to_be16(value);
+
+	return 0;
+}
+
+static int si_populate_phase_shedding_value(struct radeon_device *rdev,
+					    const struct radeon_phase_shedding_limits_table *limits,
+					    u16 voltage, u32 sclk, u32 mclk,
+					    SISLANDS_SMC_VOLTAGE_VALUE *smc_voltage)
+{
+	unsigned int i;
+
+	for (i = 0; i < limits->count; i++) {
+		if ((voltage <= limits->entries[i].voltage) &&
+		    (sclk <= limits->entries[i].sclk) &&
+		    (mclk <= limits->entries[i].mclk))
+			break;
+	}
+
+	smc_voltage->phase_settings = (u8)i;
+
+	return 0;
+}
+
+static int si_init_arb_table_index(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 tmp;
+	int ret;
+
+	ret = si_read_smc_sram_dword(rdev, si_pi->arb_table_start, &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+	tmp &= 0x00FFFFFF;
+	tmp |= MC_CG_ARB_FREQ_F1 << 24;
+
+	return si_write_smc_sram_dword(rdev, si_pi->arb_table_start,  tmp, si_pi->sram_end);
+}
+
+static int si_initial_switch_from_arb_f0_to_f1(struct radeon_device *rdev)
+{
+	return ni_copy_and_switch_arb_sets(rdev, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
+}
+
+static int si_reset_to_default(struct radeon_device *rdev)
+{
+	return (si_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) == PPSMC_Result_OK) ?
+		0 : -EINVAL;
+}
+
+static int si_force_switch_to_arb_f0(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 tmp;
+	int ret;
+
+	ret = si_read_smc_sram_dword(rdev, si_pi->arb_table_start,
+				     &tmp, si_pi->sram_end);
+	if (ret)
+		return ret;
+
+	tmp = (tmp >> 24) & 0xff;
+
+	if (tmp == MC_CG_ARB_FREQ_F0)
+		return 0;
+
+	return ni_copy_and_switch_arb_sets(rdev, tmp, MC_CG_ARB_FREQ_F0);
+}
+
+static u32 si_calculate_memory_refresh_rate(struct radeon_device *rdev,
+					    u32 engine_clock)
+{
+	u32 dram_rows;
+	u32 dram_refresh_rate;
+	u32 mc_arb_rfsh_rate;
+	u32 tmp = (RREG32(MC_ARB_RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
+
+	if (tmp >= 4)
+		dram_rows = 16384;
+	else
+		dram_rows = 1 << (tmp + 10);
+
+	dram_refresh_rate = 1 << ((RREG32(MC_SEQ_MISC0) & 0x3) + 3);
+	mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64;
+
+	return mc_arb_rfsh_rate;
+}
+
+static int si_populate_memory_timing_parameters(struct radeon_device *rdev,
+						struct rv7xx_pl *pl,
+						SMC_SIslands_MCArbDramTimingRegisterSet *arb_regs)
+{
+	u32 dram_timing;
+	u32 dram_timing2;
+	u32 burst_time;
+
+	arb_regs->mc_arb_rfsh_rate =
+		(u8)si_calculate_memory_refresh_rate(rdev, pl->sclk);
+
+	radeon_atom_set_engine_dram_timings(rdev,
+					    pl->sclk,
+                                            pl->mclk);
+
+	dram_timing  = RREG32(MC_ARB_DRAM_TIMING);
+	dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
+	burst_time = RREG32(MC_ARB_BURST_TIME) & STATE0_MASK;
+
+	arb_regs->mc_arb_dram_timing  = cpu_to_be32(dram_timing);
+	arb_regs->mc_arb_dram_timing2 = cpu_to_be32(dram_timing2);
+	arb_regs->mc_arb_burst_time = (u8)burst_time;
+
+	return 0;
+}
+
+static int si_do_program_memory_timing_parameters(struct radeon_device *rdev,
+						  struct radeon_ps *radeon_state,
+						  unsigned int first_arb_set)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };
+	int i, ret = 0;
+
+	for (i = 0; i < state->performance_level_count; i++) {
+		ret = si_populate_memory_timing_parameters(rdev, &state->performance_levels[i], &arb_regs);
+		if (ret)
+			break;
+		ret = si_copy_bytes_to_smc(rdev,
+					   si_pi->arb_table_start +
+					   offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +
+					   sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * (first_arb_set + i),
+					   (u8 *)&arb_regs,
+					   sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),
+					   si_pi->sram_end);
+		if (ret)
+			break;
+        }
+
+	return ret;
+}
+
+static int si_program_memory_timing_parameters(struct radeon_device *rdev,
+					       struct radeon_ps *radeon_new_state)
+{
+	return si_do_program_memory_timing_parameters(rdev, radeon_new_state,
+						      SISLANDS_DRIVER_STATE_ARB_INDEX);
+}
+
+static int si_populate_initial_mvdd_value(struct radeon_device *rdev,
+					  struct SISLANDS_SMC_VOLTAGE_VALUE *voltage)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+
+	if (pi->mvdd_control)
+		return si_populate_voltage_value(rdev, &si_pi->mvdd_voltage_table,
+						 si_pi->mvdd_bootup_value, voltage);
+
+	return 0;
+}
+
+static int si_populate_smc_initial_state(struct radeon_device *rdev,
+					 struct radeon_ps *radeon_initial_state,
+					 SISLANDS_SMC_STATETABLE *table)
+{
+	struct ni_ps *initial_state = ni_get_ps(radeon_initial_state);
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 reg;
+	int ret;
+
+	table->initialState.levels[0].mclk.vDLL_CNTL =
+		cpu_to_be32(si_pi->clock_registers.dll_cntl);
+	table->initialState.levels[0].mclk.vMCLK_PWRMGT_CNTL =
+		cpu_to_be32(si_pi->clock_registers.mclk_pwrmgt_cntl);
+	table->initialState.levels[0].mclk.vMPLL_AD_FUNC_CNTL =
+		cpu_to_be32(si_pi->clock_registers.mpll_ad_func_cntl);
+	table->initialState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL =
+		cpu_to_be32(si_pi->clock_registers.mpll_dq_func_cntl);
+	table->initialState.levels[0].mclk.vMPLL_FUNC_CNTL =
+		cpu_to_be32(si_pi->clock_registers.mpll_func_cntl);
+	table->initialState.levels[0].mclk.vMPLL_FUNC_CNTL_1 =
+		cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_1);
+	table->initialState.levels[0].mclk.vMPLL_FUNC_CNTL_2 =
+		cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_2);
+	table->initialState.levels[0].mclk.vMPLL_SS =
+		cpu_to_be32(si_pi->clock_registers.mpll_ss1);
+	table->initialState.levels[0].mclk.vMPLL_SS2 =
+		cpu_to_be32(si_pi->clock_registers.mpll_ss2);
+
+	table->initialState.levels[0].mclk.mclk_value =
+		cpu_to_be32(initial_state->performance_levels[0].mclk);
+
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
+		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
+		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_2);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
+		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_3);
+	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_4 =
+		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_4);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
+		cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum);
+	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2  =
+		cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum_2);
+
+	table->initialState.levels[0].sclk.sclk_value =
+		cpu_to_be32(initial_state->performance_levels[0].sclk);
+
+	table->initialState.levels[0].arbRefreshState =
+		SISLANDS_INITIAL_STATE_ARB_INDEX;
+
+	table->initialState.levels[0].ACIndex = 0;
+
+	ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
+					initial_state->performance_levels[0].vddc,
+					&table->initialState.levels[0].vddc);
+
+	if (!ret) {
+		u16 std_vddc;
+
+		ret = si_get_std_voltage_value(rdev,
+					       &table->initialState.levels[0].vddc,
+					       &std_vddc);
+		if (!ret)
+			si_populate_std_voltage_value(rdev, std_vddc,
+						      table->initialState.levels[0].vddc.index,
+						      &table->initialState.levels[0].std_vddc);
+	}
+
+	if (eg_pi->vddci_control)
+		si_populate_voltage_value(rdev,
+					  &eg_pi->vddci_voltage_table,
+					  initial_state->performance_levels[0].vddci,
+					  &table->initialState.levels[0].vddci);
+
+	if (si_pi->vddc_phase_shed_control)
+		si_populate_phase_shedding_value(rdev,
+						 &rdev->pm.dpm.dyn_state.phase_shedding_limits_table,
+						 initial_state->performance_levels[0].vddc,
+						 initial_state->performance_levels[0].sclk,
+						 initial_state->performance_levels[0].mclk,
+						 &table->initialState.levels[0].vddc);
+
+	si_populate_initial_mvdd_value(rdev, &table->initialState.levels[0].mvdd);
+
+	reg = CG_R(0xffff) | CG_L(0);
+	table->initialState.levels[0].aT = cpu_to_be32(reg);
+
+	table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
+
+	table->initialState.levels[0].gen2PCIE = (u8)si_pi->boot_pcie_gen;
+
+	if (pi->mem_gddr5) {
+		table->initialState.levels[0].strobeMode =
+			si_get_strobe_mode_settings(rdev,
+						    initial_state->performance_levels[0].mclk);
+
+		if (initial_state->performance_levels[0].mclk > pi->mclk_edc_enable_threshold)
+			table->initialState.levels[0].mcFlags = SISLANDS_SMC_MC_EDC_RD_FLAG | SISLANDS_SMC_MC_EDC_WR_FLAG;
+		else
+			table->initialState.levels[0].mcFlags =  0;
+	}
+
+	table->initialState.levelCount = 1;
+
+	table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
+
+	table->initialState.levels[0].dpm2.MaxPS = 0;
+	table->initialState.levels[0].dpm2.NearTDPDec = 0;
+	table->initialState.levels[0].dpm2.AboveSafeInc = 0;
+	table->initialState.levels[0].dpm2.BelowSafeInc = 0;
+	table->initialState.levels[0].dpm2.PwrEfficiencyRatio = 0;
+
+	reg = MIN_POWER_MASK | MAX_POWER_MASK;
+	table->initialState.levels[0].SQPowerThrottle = cpu_to_be32(reg);
+
+	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
+	table->initialState.levels[0].SQPowerThrottle_2 = cpu_to_be32(reg);
+
+	return 0;
+}
+
+static int si_populate_smc_acpi_state(struct radeon_device *rdev,
+				      SISLANDS_SMC_STATETABLE *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;
+	u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;
+	u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;
+	u32 dll_cntl = si_pi->clock_registers.dll_cntl;
+	u32 mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;
+	u32 mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;
+	u32 mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;
+	u32 mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;
+	u32 mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;
+	u32 mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;
+	u32 reg;
+	int ret;
+
+	table->ACPIState = table->initialState;
+
+	table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
+
+	if (pi->acpi_vddc) {
+		ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
+						pi->acpi_vddc, &table->ACPIState.levels[0].vddc);
+		if (!ret) {
+			u16 std_vddc;
+
+			ret = si_get_std_voltage_value(rdev,
+						       &table->ACPIState.levels[0].vddc, &std_vddc);
+			if (!ret)
+				si_populate_std_voltage_value(rdev, std_vddc,
+							      table->ACPIState.levels[0].vddc.index,
+							      &table->ACPIState.levels[0].std_vddc);
+		}
+		table->ACPIState.levels[0].gen2PCIE = si_pi->acpi_pcie_gen;
+
+		if (si_pi->vddc_phase_shed_control) {
+			si_populate_phase_shedding_value(rdev,
+							 &rdev->pm.dpm.dyn_state.phase_shedding_limits_table,
+							 pi->acpi_vddc,
+							 0,
+							 0,
+							 &table->ACPIState.levels[0].vddc);
+		}
+	} else {
+		ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
+						pi->min_vddc_in_table, &table->ACPIState.levels[0].vddc);
+		if (!ret) {
+			u16 std_vddc;
+
+			ret = si_get_std_voltage_value(rdev,
+						       &table->ACPIState.levels[0].vddc, &std_vddc);
+
+			if (!ret)
+				si_populate_std_voltage_value(rdev, std_vddc,
+							      table->ACPIState.levels[0].vddc.index,
+							      &table->ACPIState.levels[0].std_vddc);
+		}
+		table->ACPIState.levels[0].gen2PCIE = (u8)r600_get_pcie_gen_support(rdev,
+										    si_pi->sys_pcie_mask,
+										    si_pi->boot_pcie_gen,
+										    RADEON_PCIE_GEN1);
+
+		if (si_pi->vddc_phase_shed_control)
+			si_populate_phase_shedding_value(rdev,
+							 &rdev->pm.dpm.dyn_state.phase_shedding_limits_table,
+							 pi->min_vddc_in_table,
+							 0,
+							 0,
+							 &table->ACPIState.levels[0].vddc);
+	}
+
+	if (pi->acpi_vddc) {
+		if (eg_pi->acpi_vddci)
+			si_populate_voltage_value(rdev, &eg_pi->vddci_voltage_table,
+						  eg_pi->acpi_vddci,
+						  &table->ACPIState.levels[0].vddci);
+	}
+
+	mclk_pwrmgt_cntl |= MRDCK0_RESET | MRDCK1_RESET;
+	mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);
+
+	dll_cntl &= ~(MRDCK0_BYPASS | MRDCK1_BYPASS);
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(4);
+
+	table->ACPIState.levels[0].mclk.vDLL_CNTL =
+		cpu_to_be32(dll_cntl);
+	table->ACPIState.levels[0].mclk.vMCLK_PWRMGT_CNTL =
+		cpu_to_be32(mclk_pwrmgt_cntl);
+	table->ACPIState.levels[0].mclk.vMPLL_AD_FUNC_CNTL =
+		cpu_to_be32(mpll_ad_func_cntl);
+	table->ACPIState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL =
+		cpu_to_be32(mpll_dq_func_cntl);
+	table->ACPIState.levels[0].mclk.vMPLL_FUNC_CNTL =
+		cpu_to_be32(mpll_func_cntl);
+	table->ACPIState.levels[0].mclk.vMPLL_FUNC_CNTL_1 =
+		cpu_to_be32(mpll_func_cntl_1);
+	table->ACPIState.levels[0].mclk.vMPLL_FUNC_CNTL_2 =
+		cpu_to_be32(mpll_func_cntl_2);
+	table->ACPIState.levels[0].mclk.vMPLL_SS =
+		cpu_to_be32(si_pi->clock_registers.mpll_ss1);
+	table->ACPIState.levels[0].mclk.vMPLL_SS2 =
+		cpu_to_be32(si_pi->clock_registers.mpll_ss2);
+
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
+		cpu_to_be32(spll_func_cntl);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
+		cpu_to_be32(spll_func_cntl_2);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
+		cpu_to_be32(spll_func_cntl_3);
+	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_4 =
+		cpu_to_be32(spll_func_cntl_4);
+
+	table->ACPIState.levels[0].mclk.mclk_value = 0;
+	table->ACPIState.levels[0].sclk.sclk_value = 0;
+
+	si_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
+
+	if (eg_pi->dynamic_ac_timing)
+		table->ACPIState.levels[0].ACIndex = 0;
+
+	table->ACPIState.levels[0].dpm2.MaxPS = 0;
+	table->ACPIState.levels[0].dpm2.NearTDPDec = 0;
+	table->ACPIState.levels[0].dpm2.AboveSafeInc = 0;
+	table->ACPIState.levels[0].dpm2.BelowSafeInc = 0;
+	table->ACPIState.levels[0].dpm2.PwrEfficiencyRatio = 0;
+
+	reg = MIN_POWER_MASK | MAX_POWER_MASK;
+	table->ACPIState.levels[0].SQPowerThrottle = cpu_to_be32(reg);
+
+	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
+	table->ACPIState.levels[0].SQPowerThrottle_2 = cpu_to_be32(reg);
+
+	return 0;
+}
+
+static int si_populate_ulv_state(struct radeon_device *rdev,
+				 SISLANDS_SMC_SWSTATE *state)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct si_ulv_param *ulv = &si_pi->ulv;
+	u32 sclk_in_sr = 1350; /* ??? */
+	int ret;
+
+	ret = si_convert_power_level_to_smc(rdev, &ulv->pl,
+					    &state->levels[0]);
+	if (!ret) {
+		if (eg_pi->sclk_deep_sleep) {
+			if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)
+				state->levels[0].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;
+			else
+				state->levels[0].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;
+		}
+		if (ulv->one_pcie_lane_in_ulv)
+			state->flags |= PPSMC_SWSTATE_FLAG_PCIE_X1;
+		state->levels[0].arbRefreshState = (u8)(SISLANDS_ULV_STATE_ARB_INDEX);
+		state->levels[0].ACIndex = 1;
+		state->levels[0].std_vddc = state->levels[0].vddc;
+		state->levelCount = 1;
+
+		state->flags |= PPSMC_SWSTATE_FLAG_DC;
+	}
+
+	return ret;
+}
+
+static int si_program_ulv_memory_timing_parameters(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct si_ulv_param *ulv = &si_pi->ulv;
+	SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };
+	int ret;
+
+	ret = si_populate_memory_timing_parameters(rdev, &ulv->pl,
+						   &arb_regs);
+	if (ret)
+		return ret;
+
+	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_ulv_volt_change_delay,
+				   ulv->volt_change_delay);
+
+	ret = si_copy_bytes_to_smc(rdev,
+				   si_pi->arb_table_start +
+				   offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +
+				   sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * SISLANDS_ULV_STATE_ARB_INDEX,
+				   (u8 *)&arb_regs,
+				   sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),
+				   si_pi->sram_end);
+
+	return ret;
+}
+
+static void si_get_mvdd_configuration(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+
+	pi->mvdd_split_frequency = 30000;
+}
+
+static int si_init_smc_table(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
+	const struct si_ulv_param *ulv = &si_pi->ulv;
+	SISLANDS_SMC_STATETABLE  *table = &si_pi->smc_statetable;
+	int ret;
+	u32 lane_width;
+	u32 vr_hot_gpio;
+
+	si_populate_smc_voltage_tables(rdev, table);
+
+	switch (rdev->pm.int_thermal_type) {
+	case THERMAL_TYPE_SI:
+	case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
+		break;
+	case THERMAL_TYPE_NONE:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
+		break;
+	default:
+		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
+		break;
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT) {
+		if ((rdev->pdev->device != 0x6818) && (rdev->pdev->device != 0x6819))
+			table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
+	}
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
+
+	if (pi->mem_gddr5)
+		table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY)
+		table->systemFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH;
+
+	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE) {
+		table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO;
+		vr_hot_gpio = rdev->pm.dpm.backbias_response_time;
+		si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_vr_hot_gpio,
+					   vr_hot_gpio);
+	}
+
+	ret = si_populate_smc_initial_state(rdev, radeon_boot_state, table);
+	if (ret)
+		return ret;
+
+	ret = si_populate_smc_acpi_state(rdev, table);
+	if (ret)
+		return ret;
+
+	table->driverState = table->initialState;
+
+	ret = si_do_program_memory_timing_parameters(rdev, radeon_boot_state,
+						     SISLANDS_INITIAL_STATE_ARB_INDEX);
+	if (ret)
+		return ret;
+
+	if (ulv->supported && ulv->pl.vddc) {
+		ret = si_populate_ulv_state(rdev, &table->ULVState);
+		if (ret)
+			return ret;
+
+		ret = si_program_ulv_memory_timing_parameters(rdev);
+		if (ret)
+			return ret;
+
+		WREG32(CG_ULV_CONTROL, ulv->cg_ulv_control);
+		WREG32(CG_ULV_PARAMETER, ulv->cg_ulv_parameter);
+
+		lane_width = radeon_get_pcie_lanes(rdev);
+		si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);
+	} else {
+		table->ULVState = table->initialState;
+	}
+
+	return si_copy_bytes_to_smc(rdev, si_pi->state_table_start,
+				    (u8 *)table, sizeof(SISLANDS_SMC_STATETABLE),
+				    si_pi->sram_end);
+}
+
+static int si_calculate_sclk_params(struct radeon_device *rdev,
+				    u32 engine_clock,
+				    SISLANDS_SMC_SCLK_VALUE *sclk)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct atom_clock_dividers dividers;
+	u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;
+	u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;
+	u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;
+	u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;
+	u32 cg_spll_spread_spectrum = si_pi->clock_registers.cg_spll_spread_spectrum;
+	u32 cg_spll_spread_spectrum_2 = si_pi->clock_registers.cg_spll_spread_spectrum_2;
+	u64 tmp;
+	u32 reference_clock = rdev->clock.spll.reference_freq;
+	u32 reference_divider;
+	u32 fbdiv;
+	int ret;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     engine_clock, false, &dividers);
+	if (ret)
+		return ret;
+
+	reference_divider = 1 + dividers.ref_div;
+
+	tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16384;
+	do_div(tmp, reference_clock);
+	fbdiv = (u32) tmp;
+
+	spll_func_cntl &= ~(SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK);
+	spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
+	spll_func_cntl |= SPLL_PDIV_A(dividers.post_div);
+
+	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
+	spll_func_cntl_2 |= SCLK_MUX_SEL(2);
+
+        spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
+        spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
+        spll_func_cntl_3 |= SPLL_DITHEN;
+
+	if (pi->sclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 vco_freq = engine_clock * dividers.post_div;
+
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+						     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
+			u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
+			u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);
+
+			cg_spll_spread_spectrum &= ~CLK_S_MASK;
+			cg_spll_spread_spectrum |= CLK_S(clk_s);
+			cg_spll_spread_spectrum |= SSEN;
+
+			cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
+			cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
+		}
+	}
+
+	sclk->sclk_value = engine_clock;
+	sclk->vCG_SPLL_FUNC_CNTL = spll_func_cntl;
+	sclk->vCG_SPLL_FUNC_CNTL_2 = spll_func_cntl_2;
+	sclk->vCG_SPLL_FUNC_CNTL_3 = spll_func_cntl_3;
+	sclk->vCG_SPLL_FUNC_CNTL_4 = spll_func_cntl_4;
+	sclk->vCG_SPLL_SPREAD_SPECTRUM = cg_spll_spread_spectrum;
+	sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cg_spll_spread_spectrum_2;
+
+	return 0;
+}
+
+static int si_populate_sclk_value(struct radeon_device *rdev,
+				  u32 engine_clock,
+				  SISLANDS_SMC_SCLK_VALUE *sclk)
+{
+	SISLANDS_SMC_SCLK_VALUE sclk_tmp;
+	int ret;
+
+	ret = si_calculate_sclk_params(rdev, engine_clock, &sclk_tmp);
+	if (!ret) {
+		sclk->sclk_value = cpu_to_be32(sclk_tmp.sclk_value);
+		sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL);
+		sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_2);
+		sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_3);
+		sclk->vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_4);
+		sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM);
+		sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM_2);
+	}
+
+	return ret;
+}
+
+static int si_populate_mclk_value(struct radeon_device *rdev,
+				  u32 engine_clock,
+				  u32 memory_clock,
+				  SISLANDS_SMC_MCLK_VALUE *mclk,
+				  bool strobe_mode,
+				  bool dll_state_on)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32  dll_cntl = si_pi->clock_registers.dll_cntl;
+	u32  mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;
+	u32  mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;
+	u32  mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;
+	u32  mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;
+	u32  mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;
+	u32  mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;
+	u32  mpll_ss1 = si_pi->clock_registers.mpll_ss1;
+	u32  mpll_ss2 = si_pi->clock_registers.mpll_ss2;
+	struct atom_mpll_param mpll_param;
+	int ret;
+
+	ret = radeon_atom_get_memory_pll_dividers(rdev, memory_clock, strobe_mode, &mpll_param);
+	if (ret)
+		return ret;
+
+	mpll_func_cntl &= ~BWCTRL_MASK;
+	mpll_func_cntl |= BWCTRL(mpll_param.bwcntl);
+
+	mpll_func_cntl_1 &= ~(CLKF_MASK | CLKFRAC_MASK | VCO_MODE_MASK);
+	mpll_func_cntl_1 |= CLKF(mpll_param.clkf) |
+		CLKFRAC(mpll_param.clkfrac) | VCO_MODE(mpll_param.vco_mode);
+
+	mpll_ad_func_cntl &= ~YCLK_POST_DIV_MASK;
+	mpll_ad_func_cntl |= YCLK_POST_DIV(mpll_param.post_div);
+
+	if (pi->mem_gddr5) {
+		mpll_dq_func_cntl &= ~(YCLK_SEL_MASK | YCLK_POST_DIV_MASK);
+		mpll_dq_func_cntl |= YCLK_SEL(mpll_param.yclk_sel) |
+			YCLK_POST_DIV(mpll_param.post_div);
+	}
+
+	if (pi->mclk_ss) {
+		struct radeon_atom_ss ss;
+		u32 freq_nom;
+		u32 tmp;
+		u32 reference_clock = rdev->clock.mpll.reference_freq;
+
+		if (pi->mem_gddr5)
+			freq_nom = memory_clock * 4;
+		else
+			freq_nom = memory_clock * 2;
+
+		tmp = freq_nom / reference_clock;
+		tmp = tmp * tmp;
+		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
+                                                     ASIC_INTERNAL_MEMORY_SS, freq_nom)) {
+			u32 clks = reference_clock * 5 / ss.rate;
+			u32 clkv = (u32)((((131 * ss.percentage * ss.rate) / 100) * tmp) / freq_nom);
+
+                        mpll_ss1 &= ~CLKV_MASK;
+                        mpll_ss1 |= CLKV(clkv);
+
+                        mpll_ss2 &= ~CLKS_MASK;
+                        mpll_ss2 |= CLKS(clks);
+		}
+	}
+
+	mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;
+	mclk_pwrmgt_cntl |= DLL_SPEED(mpll_param.dll_speed);
+
+	if (dll_state_on)
+		mclk_pwrmgt_cntl |= MRDCK0_PDNB | MRDCK1_PDNB;
+	else
+		mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);
+
+	mclk->mclk_value = cpu_to_be32(memory_clock);
+	mclk->vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl);
+	mclk->vMPLL_FUNC_CNTL_1 = cpu_to_be32(mpll_func_cntl_1);
+	mclk->vMPLL_FUNC_CNTL_2 = cpu_to_be32(mpll_func_cntl_2);
+	mclk->vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
+	mclk->vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
+	mclk->vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
+	mclk->vDLL_CNTL = cpu_to_be32(dll_cntl);
+	mclk->vMPLL_SS = cpu_to_be32(mpll_ss1);
+	mclk->vMPLL_SS2 = cpu_to_be32(mpll_ss2);
+
+	return 0;
+}
+
+static void si_populate_smc_sp(struct radeon_device *rdev,
+			       struct radeon_ps *radeon_state,
+			       SISLANDS_SMC_SWSTATE *smc_state)
+{
+	struct ni_ps *ps = ni_get_ps(radeon_state);
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	int i;
+
+	for (i = 0; i < ps->performance_level_count - 1; i++)
+		smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);
+
+	smc_state->levels[ps->performance_level_count - 1].bSP =
+		cpu_to_be32(pi->psp);
+}
+
+static int si_convert_power_level_to_smc(struct radeon_device *rdev,
+					 struct rv7xx_pl *pl,
+					 SISLANDS_SMC_HW_PERFORMANCE_LEVEL *level)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	int ret;
+	bool dll_state_on;
+	u16 std_vddc;
+	bool gmc_pg = false;
+
+	if (eg_pi->pcie_performance_request &&
+	    (si_pi->force_pcie_gen != RADEON_PCIE_GEN_INVALID))
+		level->gen2PCIE = (u8)si_pi->force_pcie_gen;
+	else
+		level->gen2PCIE = (u8)pl->pcie_gen;
+
+	ret = si_populate_sclk_value(rdev, pl->sclk, &level->sclk);
+	if (ret)
+		return ret;
+
+	level->mcFlags =  0;
+
+	if (pi->mclk_stutter_mode_threshold &&
+	    (pl->mclk <= pi->mclk_stutter_mode_threshold) &&
+	    !eg_pi->uvd_enabled &&
+	    (RREG32(DPG_PIPE_STUTTER_CONTROL) & STUTTER_ENABLE) &&
+	    (rdev->pm.dpm.new_active_crtc_count <= 2)) {
+		level->mcFlags |= SISLANDS_SMC_MC_STUTTER_EN;
+
+		if (gmc_pg)
+			level->mcFlags |= SISLANDS_SMC_MC_PG_EN;
+	}
+
+	if (pi->mem_gddr5) {
+		if (pl->mclk > pi->mclk_edc_enable_threshold)
+			level->mcFlags |= SISLANDS_SMC_MC_EDC_RD_FLAG;
+
+		if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold)
+			level->mcFlags |= SISLANDS_SMC_MC_EDC_WR_FLAG;
+
+		level->strobeMode = si_get_strobe_mode_settings(rdev, pl->mclk);
+
+		if (level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) {
+			if (si_get_mclk_frequency_ratio(pl->mclk, true) >=
+			    ((RREG32(MC_SEQ_MISC7) >> 16) & 0xf))
+				dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
+			else
+				dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false;
+		} else {
+			dll_state_on = false;
+		}
+	} else {
+		level->strobeMode = si_get_strobe_mode_settings(rdev,
+								pl->mclk);
+
+		dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
+	}
+
+	ret = si_populate_mclk_value(rdev,
+				     pl->sclk,
+				     pl->mclk,
+				     &level->mclk,
+				     (level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) != 0, dll_state_on);
+	if (ret)
+		return ret;
+
+	ret = si_populate_voltage_value(rdev,
+					&eg_pi->vddc_voltage_table,
+					pl->vddc, &level->vddc);
+	if (ret)
+		return ret;
+
+
+	ret = si_get_std_voltage_value(rdev, &level->vddc, &std_vddc);
+	if (ret)
+		return ret;
+
+	ret = si_populate_std_voltage_value(rdev, std_vddc,
+					    level->vddc.index, &level->std_vddc);
+	if (ret)
+		return ret;
+
+	if (eg_pi->vddci_control) {
+		ret = si_populate_voltage_value(rdev, &eg_pi->vddci_voltage_table,
+						pl->vddci, &level->vddci);
+		if (ret)
+			return ret;
+	}
+
+	if (si_pi->vddc_phase_shed_control) {
+		ret = si_populate_phase_shedding_value(rdev,
+						       &rdev->pm.dpm.dyn_state.phase_shedding_limits_table,
+						       pl->vddc,
+						       pl->sclk,
+						       pl->mclk,
+						       &level->vddc);
+		if (ret)
+			return ret;
+	}
+
+	level->MaxPoweredUpCU = si_pi->max_cu;
+
+	ret = si_populate_mvdd_value(rdev, pl->mclk, &level->mvdd);
+
+	return ret;
+}
+
+static int si_populate_smc_t(struct radeon_device *rdev,
+			     struct radeon_ps *radeon_state,
+			     SISLANDS_SMC_SWSTATE *smc_state)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	u32 a_t;
+	u32 t_l, t_h;
+	u32 high_bsp;
+	int i, ret;
+
+	if (state->performance_level_count >= 9)
+		return -EINVAL;
+
+	if (state->performance_level_count < 2) {
+		a_t = CG_R(0xffff) | CG_L(0);
+		smc_state->levels[0].aT = cpu_to_be32(a_t);
+		return 0;
+	}
+
+	smc_state->levels[0].aT = cpu_to_be32(0);
+
+	for (i = 0; i <= state->performance_level_count - 2; i++) {
+		ret = r600_calculate_at(
+			(50 / SISLANDS_MAX_HARDWARE_POWERLEVELS) * 100 * (i + 1),
+			100 * R600_AH_DFLT,
+			state->performance_levels[i + 1].sclk,
+			state->performance_levels[i].sclk,
+			&t_l,
+			&t_h);
+
+		if (ret) {
+			t_h = (i + 1) * 1000 - 50 * R600_AH_DFLT;
+			t_l = (i + 1) * 1000 + 50 * R600_AH_DFLT;
+		}
+
+		a_t = be32_to_cpu(smc_state->levels[i].aT) & ~CG_R_MASK;
+		a_t |= CG_R(t_l * pi->bsp / 20000);
+		smc_state->levels[i].aT = cpu_to_be32(a_t);
+
+		high_bsp = (i == state->performance_level_count - 2) ?
+			pi->pbsp : pi->bsp;
+		a_t = CG_R(0xffff) | CG_L(t_h * high_bsp / 20000);
+		smc_state->levels[i + 1].aT = cpu_to_be32(a_t);
+	}
+
+	return 0;
+}
+
+static int si_disable_ulv(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct si_ulv_param *ulv = &si_pi->ulv;
+
+	if (ulv->supported)
+		return (si_send_msg_to_smc(rdev, PPSMC_MSG_DisableULV) == PPSMC_Result_OK) ?
+			0 : -EINVAL;
+
+	return 0;
+}
+
+static bool si_is_state_ulv_compatible(struct radeon_device *rdev,
+				       struct radeon_ps *radeon_state)
+{
+	const struct si_power_info *si_pi = si_get_pi(rdev);
+	const struct si_ulv_param *ulv = &si_pi->ulv;
+	const struct ni_ps *state = ni_get_ps(radeon_state);
+	int i;
+
+	if (state->performance_levels[0].mclk != ulv->pl.mclk)
+		return false;
+
+	/* XXX validate against display requirements! */
+
+	for (i = 0; i < rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count; i++) {
+		if (rdev->clock.current_dispclk <=
+		    rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].clk) {
+			if (ulv->pl.vddc <
+			    rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].v)
+				return false;
+		}
+	}
+
+	if ((radeon_state->vclk != 0) || (radeon_state->dclk != 0))
+		return false;
+
+	return true;
+}
+
+static int si_set_power_state_conditionally_enable_ulv(struct radeon_device *rdev,
+						       struct radeon_ps *radeon_new_state)
+{
+	const struct si_power_info *si_pi = si_get_pi(rdev);
+	const struct si_ulv_param *ulv = &si_pi->ulv;
+
+	if (ulv->supported) {
+		if (si_is_state_ulv_compatible(rdev, radeon_new_state))
+			return (si_send_msg_to_smc(rdev, PPSMC_MSG_EnableULV) == PPSMC_Result_OK) ?
+				0 : -EINVAL;
+	}
+	return 0;
+}
+
+static int si_convert_power_state_to_smc(struct radeon_device *rdev,
+					 struct radeon_ps *radeon_state,
+					 SISLANDS_SMC_SWSTATE *smc_state)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct ni_power_info *ni_pi = ni_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	int i, ret;
+	u32 threshold;
+	u32 sclk_in_sr = 1350; /* ??? */
+
+	if (state->performance_level_count > SISLANDS_MAX_HARDWARE_POWERLEVELS)
+		return -EINVAL;
+
+	threshold = state->performance_levels[state->performance_level_count-1].sclk * 100 / 100;
+
+	if (radeon_state->vclk && radeon_state->dclk) {
+		eg_pi->uvd_enabled = true;
+		if (eg_pi->smu_uvd_hs)
+			smc_state->flags |= PPSMC_SWSTATE_FLAG_UVD;
+	} else {
+		eg_pi->uvd_enabled = false;
+	}
+
+	if (state->dc_compatible)
+		smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
+
+	smc_state->levelCount = 0;
+	for (i = 0; i < state->performance_level_count; i++) {
+		if (eg_pi->sclk_deep_sleep) {
+			if ((i == 0) || si_pi->sclk_deep_sleep_above_low) {
+				if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)
+					smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;
+				else
+					smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;
+			}
+		}
+
+		ret = si_convert_power_level_to_smc(rdev, &state->performance_levels[i],
+						    &smc_state->levels[i]);
+		smc_state->levels[i].arbRefreshState =
+			(u8)(SISLANDS_DRIVER_STATE_ARB_INDEX + i);
+
+		if (ret)
+			return ret;
+
+		if (ni_pi->enable_power_containment)
+			smc_state->levels[i].displayWatermark =
+				(state->performance_levels[i].sclk < threshold) ?
+				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
+		else
+			smc_state->levels[i].displayWatermark = (i < 2) ?
+				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
+
+		if (eg_pi->dynamic_ac_timing)
+			smc_state->levels[i].ACIndex = SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i;
+		else
+			smc_state->levels[i].ACIndex = 0;
+
+		smc_state->levelCount++;
+	}
+
+	si_write_smc_soft_register(rdev,
+				   SI_SMC_SOFT_REGISTER_watermark_threshold,
+				   threshold / 512);
+
+	si_populate_smc_sp(rdev, radeon_state, smc_state);
+
+	ret = si_populate_power_containment_values(rdev, radeon_state, smc_state);
+	if (ret)
+		ni_pi->enable_power_containment = false;
+
+	ret = si_populate_sq_ramping_values(rdev, radeon_state, smc_state);
+        if (ret)
+		ni_pi->enable_sq_ramping = false;
+
+	return si_populate_smc_t(rdev, radeon_state, smc_state);
+}
+
+static int si_upload_sw_state(struct radeon_device *rdev,
+			      struct radeon_ps *radeon_new_state)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct ni_ps *new_state = ni_get_ps(radeon_new_state);
+	int ret;
+	u32 address = si_pi->state_table_start +
+		offsetof(SISLANDS_SMC_STATETABLE, driverState);
+	u32 state_size = sizeof(SISLANDS_SMC_SWSTATE) +
+		((new_state->performance_level_count - 1) *
+		 sizeof(SISLANDS_SMC_HW_PERFORMANCE_LEVEL));
+	SISLANDS_SMC_SWSTATE *smc_state = &si_pi->smc_statetable.driverState;
+
+	memset(smc_state, 0, state_size);
+
+	ret = si_convert_power_state_to_smc(rdev, radeon_new_state, smc_state);
+	if (ret)
+		return ret;
+
+	ret = si_copy_bytes_to_smc(rdev, address, (u8 *)smc_state,
+				   state_size, si_pi->sram_end);
+
+	return ret;
+}
+
+static int si_upload_ulv_state(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct si_ulv_param *ulv = &si_pi->ulv;
+	int ret = 0;
+
+	if (ulv->supported && ulv->pl.vddc) {
+		u32 address = si_pi->state_table_start +
+			offsetof(SISLANDS_SMC_STATETABLE, ULVState);
+		SISLANDS_SMC_SWSTATE *smc_state = &si_pi->smc_statetable.ULVState;
+		u32 state_size = sizeof(SISLANDS_SMC_SWSTATE);
+
+		memset(smc_state, 0, state_size);
+
+		ret = si_populate_ulv_state(rdev, smc_state);
+		if (!ret)
+			ret = si_copy_bytes_to_smc(rdev, address, (u8 *)smc_state,
+						   state_size, si_pi->sram_end);
+	}
+
+	return ret;
+}
+
+static int si_upload_smc_data(struct radeon_device *rdev)
+{
+	struct radeon_crtc *radeon_crtc = NULL;
+	int i;
+
+	if (rdev->pm.dpm.new_active_crtc_count == 0)
+		return 0;
+
+	for (i = 0; i < rdev->num_crtc; i++) {
+		if (rdev->pm.dpm.new_active_crtcs & (1 << i)) {
+			radeon_crtc = rdev->mode_info.crtcs[i];
+			break;
+		}
+	}
+
+	if (radeon_crtc == NULL)
+		return 0;
+
+	if (radeon_crtc->line_time <= 0)
+		return 0;
+
+	if (si_write_smc_soft_register(rdev,
+				       SI_SMC_SOFT_REGISTER_crtc_index,
+				       radeon_crtc->crtc_id) != PPSMC_Result_OK)
+		return 0;
+
+	if (si_write_smc_soft_register(rdev,
+				       SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min,
+				       radeon_crtc->wm_high / radeon_crtc->line_time) != PPSMC_Result_OK)
+		return 0;
+
+	if (si_write_smc_soft_register(rdev,
+				       SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max,
+				       radeon_crtc->wm_low / radeon_crtc->line_time) != PPSMC_Result_OK)
+		return 0;
+
+	return 0;
+}
+
+static int si_set_mc_special_registers(struct radeon_device *rdev,
+				       struct si_mc_reg_table *table)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	u8 i, j, k;
+	u32 temp_reg;
+
+	for (i = 0, j = table->last; i < table->last; i++) {
+		if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
+			return -EINVAL;
+		switch (table->mc_reg_address[i].s1 << 2) {
+		case MC_SEQ_MISC1:
+			temp_reg = RREG32(MC_PMG_CMD_EMRS);
+			table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
+			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
+			for (k = 0; k < table->num_entries; k++)
+				table->mc_reg_table_entry[k].mc_data[j] =
+					((temp_reg & 0xffff0000)) |
+					((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
+			j++;
+			if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+
+			temp_reg = RREG32(MC_PMG_CMD_MRS);
+			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
+			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
+			for (k = 0; k < table->num_entries; k++) {
+				table->mc_reg_table_entry[k].mc_data[j] =
+					(temp_reg & 0xffff0000) |
+					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+				if (!pi->mem_gddr5)
+					table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
+			}
+			j++;
+			if (j > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+
+			if (!pi->mem_gddr5) {
+				table->mc_reg_address[j].s1 = MC_PMG_AUTO_CMD >> 2;
+				table->mc_reg_address[j].s0 = MC_PMG_AUTO_CMD >> 2;
+				for (k = 0; k < table->num_entries; k++)
+					table->mc_reg_table_entry[k].mc_data[j] =
+						(table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;
+				j++;
+				if (j > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
+					return -EINVAL;
+			}
+			break;
+		case MC_SEQ_RESERVE_M:
+			temp_reg = RREG32(MC_PMG_CMD_MRS1);
+			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
+			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+			for(k = 0; k < table->num_entries; k++)
+				table->mc_reg_table_entry[k].mc_data[j] =
+					(temp_reg & 0xffff0000) |
+					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+			j++;
+			if (j > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
+				return -EINVAL;
+			break;
+		default:
+			break;
+		}
+	}
+
+	table->last = j;
+
+	return 0;
+}
+
+static bool si_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
+{
+	bool result = true;
+
+	switch (in_reg) {
+	case  MC_SEQ_RAS_TIMING >> 2:
+		*out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
+		break;
+        case MC_SEQ_CAS_TIMING >> 2:
+		*out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
+		break;
+        case MC_SEQ_MISC_TIMING >> 2:
+		*out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
+		break;
+        case MC_SEQ_MISC_TIMING2 >> 2:
+		*out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
+		break;
+        case MC_SEQ_RD_CTL_D0 >> 2:
+		*out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
+		break;
+        case MC_SEQ_RD_CTL_D1 >> 2:
+		*out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
+		break;
+        case MC_SEQ_WR_CTL_D0 >> 2:
+		*out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
+		break;
+        case MC_SEQ_WR_CTL_D1 >> 2:
+		*out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
+		break;
+        case MC_PMG_CMD_EMRS >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
+		break;
+        case MC_PMG_CMD_MRS >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
+		break;
+        case MC_PMG_CMD_MRS1 >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+		break;
+        case MC_SEQ_PMG_TIMING >> 2:
+		*out_reg = MC_SEQ_PMG_TIMING_LP >> 2;
+		break;
+        case MC_PMG_CMD_MRS2 >> 2:
+		*out_reg = MC_SEQ_PMG_CMD_MRS2_LP >> 2;
+		break;
+        case MC_SEQ_WR_CTL_2 >> 2:
+		*out_reg = MC_SEQ_WR_CTL_2_LP >> 2;
+		break;
+        default:
+		result = false;
+		break;
+	}
+
+	return result;
+}
+
+static void si_set_valid_flag(struct si_mc_reg_table *table)
+{
+	u8 i, j;
+
+	for (i = 0; i < table->last; i++) {
+		for (j = 1; j < table->num_entries; j++) {
+			if (table->mc_reg_table_entry[j-1].mc_data[i] != table->mc_reg_table_entry[j].mc_data[i]) {
+				table->valid_flag |= 1 << i;
+				break;
+			}
+		}
+	}
+}
+
+static void si_set_s0_mc_reg_index(struct si_mc_reg_table *table)
+{
+	u32 i;
+	u16 address;
+
+	for (i = 0; i < table->last; i++)
+		table->mc_reg_address[i].s0 = si_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
+			address : table->mc_reg_address[i].s1;
+
+}
+
+static int si_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
+				      struct si_mc_reg_table *si_table)
+{
+	u8 i, j;
+
+	if (table->last > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
+		return -EINVAL;
+	if (table->num_entries > MAX_AC_TIMING_ENTRIES)
+		return -EINVAL;
+
+	for (i = 0; i < table->last; i++)
+		si_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
+	si_table->last = table->last;
+
+	for (i = 0; i < table->num_entries; i++) {
+		si_table->mc_reg_table_entry[i].mclk_max =
+			table->mc_reg_table_entry[i].mclk_max;
+		for (j = 0; j < table->last; j++) {
+			si_table->mc_reg_table_entry[i].mc_data[j] =
+				table->mc_reg_table_entry[i].mc_data[j];
+		}
+	}
+	si_table->num_entries = table->num_entries;
+
+	return 0;
+}
+
+static int si_initialize_mc_reg_table(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct atom_mc_reg_table *table;
+	struct si_mc_reg_table *si_table = &si_pi->mc_reg_table;
+	u8 module_index = rv770_get_memory_module_index(rdev);
+	int ret;
+
+	table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
+	if (!table)
+		return -ENOMEM;
+
+	WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
+	WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
+	WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
+	WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
+	WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
+	WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
+	WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
+	WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
+	WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
+	WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
+	WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
+	WREG32(MC_SEQ_PMG_TIMING_LP, RREG32(MC_SEQ_PMG_TIMING));
+	WREG32(MC_SEQ_PMG_CMD_MRS2_LP, RREG32(MC_PMG_CMD_MRS2));
+	WREG32(MC_SEQ_WR_CTL_2_LP, RREG32(MC_SEQ_WR_CTL_2));
+
+        ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
+        if (ret)
+                goto init_mc_done;
+
+        ret = si_copy_vbios_mc_reg_table(table, si_table);
+        if (ret)
+                goto init_mc_done;
+
+	si_set_s0_mc_reg_index(si_table);
+
+	ret = si_set_mc_special_registers(rdev, si_table);
+        if (ret)
+                goto init_mc_done;
+
+	si_set_valid_flag(si_table);
+
+init_mc_done:
+	kfree(table);
+
+	return ret;
+
+}
+
+static void si_populate_mc_reg_addresses(struct radeon_device *rdev,
+					 SMC_SIslands_MCRegisters *mc_reg_table)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 i, j;
+
+	for (i = 0, j = 0; j < si_pi->mc_reg_table.last; j++) {
+		if (si_pi->mc_reg_table.valid_flag & (1 << j)) {
+			if (i >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
+				break;
+			mc_reg_table->address[i].s0 =
+				cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s0);
+			mc_reg_table->address[i].s1 =
+				cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s1);
+			i++;
+		}
+	}
+	mc_reg_table->last = (u8)i;
+}
+
+static void si_convert_mc_registers(const struct si_mc_reg_entry *entry,
+				    SMC_SIslands_MCRegisterSet *data,
+				    u32 num_entries, u32 valid_flag)
+{
+	u32 i, j;
+
+	for(i = 0, j = 0; j < num_entries; j++) {
+		if (valid_flag & (1 << j)) {
+			data->value[i] = cpu_to_be32(entry->mc_data[j]);
+			i++;
+		}
+	}
+}
+
+static void si_convert_mc_reg_table_entry_to_smc(struct radeon_device *rdev,
+						 struct rv7xx_pl *pl,
+						 SMC_SIslands_MCRegisterSet *mc_reg_table_data)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 i = 0;
+
+	for (i = 0; i < si_pi->mc_reg_table.num_entries; i++) {
+		if (pl->mclk <= si_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max)
+			break;
+	}
+
+	if ((i == si_pi->mc_reg_table.num_entries) && (i > 0))
+		--i;
+
+	si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[i],
+				mc_reg_table_data, si_pi->mc_reg_table.last,
+				si_pi->mc_reg_table.valid_flag);
+}
+
+static void si_convert_mc_reg_table_to_smc(struct radeon_device *rdev,
+					   struct radeon_ps *radeon_state,
+					   SMC_SIslands_MCRegisters *mc_reg_table)
+{
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	int i;
+
+	for (i = 0; i < state->performance_level_count; i++) {
+		si_convert_mc_reg_table_entry_to_smc(rdev,
+						     &state->performance_levels[i],
+						     &mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i]);
+	}
+}
+
+static int si_populate_mc_reg_table(struct radeon_device *rdev,
+				    struct radeon_ps *radeon_boot_state)
+{
+	struct ni_ps *boot_state = ni_get_ps(radeon_boot_state);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct si_ulv_param *ulv = &si_pi->ulv;
+	SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;
+
+	memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));
+
+	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_seq_index, 1);
+
+	si_populate_mc_reg_addresses(rdev, smc_mc_reg_table);
+
+	si_convert_mc_reg_table_entry_to_smc(rdev, &boot_state->performance_levels[0],
+					     &smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_INITIAL_SLOT]);
+
+	si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],
+				&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ACPI_SLOT],
+				si_pi->mc_reg_table.last,
+				si_pi->mc_reg_table.valid_flag);
+
+	if (ulv->supported && ulv->pl.vddc != 0)
+		si_convert_mc_reg_table_entry_to_smc(rdev, &ulv->pl,
+						     &smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT]);
+	else
+		si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],
+					&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT],
+					si_pi->mc_reg_table.last,
+					si_pi->mc_reg_table.valid_flag);
+
+	si_convert_mc_reg_table_to_smc(rdev, radeon_boot_state, smc_mc_reg_table);
+
+	return si_copy_bytes_to_smc(rdev, si_pi->mc_reg_table_start,
+				    (u8 *)smc_mc_reg_table,
+				    sizeof(SMC_SIslands_MCRegisters), si_pi->sram_end);
+}
+
+static int si_upload_mc_reg_table(struct radeon_device *rdev,
+				  struct radeon_ps *radeon_new_state)
+{
+	struct ni_ps *new_state = ni_get_ps(radeon_new_state);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	u32 address = si_pi->mc_reg_table_start +
+		offsetof(SMC_SIslands_MCRegisters,
+			 data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT]);
+	SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;
+
+	memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));
+
+	si_convert_mc_reg_table_to_smc(rdev, radeon_new_state, smc_mc_reg_table);
+
+
+	return si_copy_bytes_to_smc(rdev, address,
+				    (u8 *)&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT],
+				    sizeof(SMC_SIslands_MCRegisterSet) * new_state->performance_level_count,
+				    si_pi->sram_end);
+
+}
+
+static void si_enable_voltage_control(struct radeon_device *rdev, bool enable)
+{
+        if (enable)
+                WREG32_P(GENERAL_PWRMGT, VOLT_PWRMGT_EN, ~VOLT_PWRMGT_EN);
+        else
+                WREG32_P(GENERAL_PWRMGT, 0, ~VOLT_PWRMGT_EN);
+}
+
+static enum radeon_pcie_gen si_get_maximum_link_speed(struct radeon_device *rdev,
+						      struct radeon_ps *radeon_state)
+{
+	struct ni_ps *state = ni_get_ps(radeon_state);
+	int i;
+	u16 pcie_speed, max_speed = 0;
+
+	for (i = 0; i < state->performance_level_count; i++) {
+		pcie_speed = state->performance_levels[i].pcie_gen;
+		if (max_speed < pcie_speed)
+			max_speed = pcie_speed;
+	}
+	return max_speed;
+}
+
+static u16 si_get_current_pcie_speed(struct radeon_device *rdev)
+{
+	u32 speed_cntl;
+
+	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL) & LC_CURRENT_DATA_RATE_MASK;
+	speed_cntl >>= LC_CURRENT_DATA_RATE_SHIFT;
+
+	return (u16)speed_cntl;
+}
+
+static void si_request_link_speed_change_before_state_change(struct radeon_device *rdev,
+							     struct radeon_ps *radeon_new_state,
+							     struct radeon_ps *radeon_current_state)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	enum radeon_pcie_gen target_link_speed = si_get_maximum_link_speed(rdev, radeon_new_state);
+	enum radeon_pcie_gen current_link_speed;
+
+	if (si_pi->force_pcie_gen == RADEON_PCIE_GEN_INVALID)
+		current_link_speed = si_get_maximum_link_speed(rdev, radeon_current_state);
+	else
+		current_link_speed = si_pi->force_pcie_gen;
+
+	si_pi->force_pcie_gen = RADEON_PCIE_GEN_INVALID;
+	si_pi->pspp_notify_required = false;
+	if (target_link_speed > current_link_speed) {
+		switch (target_link_speed) {
+#if defined(CONFIG_ACPI)
+		case RADEON_PCIE_GEN3:
+			if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN3, false) == 0)
+				break;
+			si_pi->force_pcie_gen = RADEON_PCIE_GEN2;
+			if (current_link_speed == RADEON_PCIE_GEN2)
+				break;
+		case RADEON_PCIE_GEN2:
+			if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, false) == 0)
+				break;
+#endif
+		default:
+			si_pi->force_pcie_gen = si_get_current_pcie_speed(rdev);
+			break;
+		}
+	} else {
+		if (target_link_speed < current_link_speed)
+			si_pi->pspp_notify_required = true;
+	}
+}
+
+static void si_notify_link_speed_change_after_state_change(struct radeon_device *rdev,
+							   struct radeon_ps *radeon_new_state,
+							   struct radeon_ps *radeon_current_state)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	enum radeon_pcie_gen target_link_speed = si_get_maximum_link_speed(rdev, radeon_new_state);
+	u8 request;
+
+	if (si_pi->pspp_notify_required) {
+		if (target_link_speed == RADEON_PCIE_GEN3)
+			request = PCIE_PERF_REQ_PECI_GEN3;
+		else if (target_link_speed == RADEON_PCIE_GEN2)
+			request = PCIE_PERF_REQ_PECI_GEN2;
+		else
+			request = PCIE_PERF_REQ_PECI_GEN1;
+
+		if ((request == PCIE_PERF_REQ_PECI_GEN1) &&
+		    (si_get_current_pcie_speed(rdev) > 0))
+			return;
+
+#if defined(CONFIG_ACPI)
+		radeon_acpi_pcie_performance_request(rdev, request, false);
+#endif
+	}
+}
+
+#if 0
+static int si_ds_request(struct radeon_device *rdev,
+			 bool ds_status_on, u32 count_write)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+	if (eg_pi->sclk_deep_sleep) {
+		if (ds_status_on)
+			return (si_send_msg_to_smc(rdev, PPSMC_MSG_CancelThrottleOVRDSCLKDS) ==
+				PPSMC_Result_OK) ?
+				0 : -EINVAL;
+		else
+			return (si_send_msg_to_smc(rdev, PPSMC_MSG_ThrottleOVRDSCLKDS) ==
+				PPSMC_Result_OK) ? 0 : -EINVAL;
+	}
+	return 0;
+}
+#endif
+
+static void si_set_max_cu_value(struct radeon_device *rdev)
+{
+	struct si_power_info *si_pi = si_get_pi(rdev);
+
+	if (rdev->family == CHIP_VERDE) {
+		switch (rdev->pdev->device) {
+		case 0x6820:
+		case 0x6825:
+		case 0x6821:
+		case 0x6823:
+		case 0x6827:
+			si_pi->max_cu = 10;
+			break;
+		case 0x682D:
+		case 0x6824:
+		case 0x682F:
+		case 0x6826:
+			si_pi->max_cu = 8;
+			break;
+		case 0x6828:
+		case 0x6830:
+		case 0x6831:
+		case 0x6838:
+		case 0x6839:
+		case 0x683D:
+			si_pi->max_cu = 10;
+			break;
+		case 0x683B:
+		case 0x683F:
+		case 0x6829:
+			si_pi->max_cu = 8;
+			break;
+		default:
+			si_pi->max_cu = 0;
+			break;
+		}
+	} else {
+		si_pi->max_cu = 0;
+	}
+}
+
+static int si_patch_single_dependency_table_based_on_leakage(struct radeon_device *rdev,
+							     struct radeon_clock_voltage_dependency_table *table)
+{
+	u32 i;
+	int j;
+	u16 leakage_voltage;
+
+	if (table) {
+		for (i = 0; i < table->count; i++) {
+			switch (si_get_leakage_voltage_from_leakage_index(rdev,
+									  table->entries[i].v,
+									  &leakage_voltage)) {
+			case 0:
+				table->entries[i].v = leakage_voltage;
+				break;
+			case -EAGAIN:
+				return -EINVAL;
+			case -EINVAL:
+			default:
+				break;
+			}
+		}
+
+		for (j = (table->count - 2); j >= 0; j--) {
+			table->entries[j].v = (table->entries[j].v <= table->entries[j + 1].v) ?
+				table->entries[j].v : table->entries[j + 1].v;
+		}
+	}
+	return 0;
+}
+
+static int si_patch_dependency_tables_based_on_leakage(struct radeon_device *rdev)
+{
+	int ret = 0;
+
+	ret = si_patch_single_dependency_table_based_on_leakage(rdev,
+								&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk);
+	ret = si_patch_single_dependency_table_based_on_leakage(rdev,
+								&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk);
+	ret = si_patch_single_dependency_table_based_on_leakage(rdev,
+								&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk);
+	return ret;
+}
+
+static void si_set_pcie_lane_width_in_smc(struct radeon_device *rdev,
+					  struct radeon_ps *radeon_new_state,
+					  struct radeon_ps *radeon_current_state)
+{
+	u32 lane_width;
+	u32 new_lane_width =
+		(radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT;
+	u32 current_lane_width =
+		(radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT;
+
+	if (new_lane_width != current_lane_width) {
+		radeon_set_pcie_lanes(rdev, new_lane_width);
+		lane_width = radeon_get_pcie_lanes(rdev);
+		si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);
+	}
+}
+
+void si_dpm_setup_asic(struct radeon_device *rdev)
+{
+	rv770_get_memory_type(rdev);
+	si_read_clock_registers(rdev);
+	si_enable_acpi_power_management(rdev);
+}
+
+static int si_set_thermal_temperature_range(struct radeon_device *rdev,
+					int min_temp, int max_temp)
+{
+	int low_temp = 0 * 1000;
+	int high_temp = 255 * 1000;
+
+	if (low_temp < min_temp)
+		low_temp = min_temp;
+	if (high_temp > max_temp)
+		high_temp = max_temp;
+	if (high_temp < low_temp) {
+		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
+		return -EINVAL;
+	}
+
+	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(high_temp / 1000), ~DIG_THERM_INTH_MASK);
+	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(low_temp / 1000), ~DIG_THERM_INTL_MASK);
+	WREG32_P(CG_THERMAL_CTRL, DIG_THERM_DPM(high_temp / 1000), ~DIG_THERM_DPM_MASK);
+
+	rdev->pm.dpm.thermal.min_temp = low_temp;
+	rdev->pm.dpm.thermal.max_temp = high_temp;
+
+	return 0;
+}
+
+int si_dpm_enable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+	int ret;
+
+	if (si_is_smc_running(rdev))
+		return -EINVAL;
+	if (pi->voltage_control)
+		si_enable_voltage_control(rdev, true);
+	if (pi->mvdd_control)
+		si_get_mvdd_configuration(rdev);
+	if (pi->voltage_control) {
+		ret = si_construct_voltage_tables(rdev);
+		if (ret) {
+			DRM_ERROR("si_construct_voltage_tables failed\n");
+			return ret;
+		}
+	}
+	if (eg_pi->dynamic_ac_timing) {
+		ret = si_initialize_mc_reg_table(rdev);
+		if (ret)
+			eg_pi->dynamic_ac_timing = false;
+	}
+	if (pi->dynamic_ss)
+		si_enable_spread_spectrum(rdev, true);
+	if (pi->thermal_protection)
+		si_enable_thermal_protection(rdev, true);
+	si_setup_bsp(rdev);
+	si_program_git(rdev);
+	si_program_tp(rdev);
+	si_program_tpp(rdev);
+	si_program_sstp(rdev);
+	si_enable_display_gap(rdev);
+	si_program_vc(rdev);
+	ret = si_upload_firmware(rdev);
+	if (ret) {
+		DRM_ERROR("si_upload_firmware failed\n");
+		return ret;
+	}
+	ret = si_process_firmware_header(rdev);
+	if (ret) {
+		DRM_ERROR("si_process_firmware_header failed\n");
+		return ret;
+	}
+	ret = si_initial_switch_from_arb_f0_to_f1(rdev);
+	if (ret) {
+		DRM_ERROR("si_initial_switch_from_arb_f0_to_f1 failed\n");
+		return ret;
+	}
+	ret = si_init_smc_table(rdev);
+	if (ret) {
+		DRM_ERROR("si_init_smc_table failed\n");
+		return ret;
+	}
+	ret = si_init_smc_spll_table(rdev);
+	if (ret) {
+		DRM_ERROR("si_init_smc_spll_table failed\n");
+		return ret;
+	}
+	ret = si_init_arb_table_index(rdev);
+	if (ret) {
+		DRM_ERROR("si_init_arb_table_index failed\n");
+		return ret;
+	}
+	if (eg_pi->dynamic_ac_timing) {
+		ret = si_populate_mc_reg_table(rdev, boot_ps);
+		if (ret) {
+			DRM_ERROR("si_populate_mc_reg_table failed\n");
+			return ret;
+		}
+	}
+	ret = si_initialize_smc_cac_tables(rdev);
+	if (ret) {
+		DRM_ERROR("si_initialize_smc_cac_tables failed\n");
+		return ret;
+	}
+	ret = si_initialize_hardware_cac_manager(rdev);
+	if (ret) {
+		DRM_ERROR("si_initialize_hardware_cac_manager failed\n");
+		return ret;
+	}
+	ret = si_initialize_smc_dte_tables(rdev);
+	if (ret) {
+		DRM_ERROR("si_initialize_smc_dte_tables failed\n");
+		return ret;
+	}
+	ret = si_populate_smc_tdp_limits(rdev, boot_ps);
+	if (ret) {
+		DRM_ERROR("si_populate_smc_tdp_limits failed\n");
+		return ret;
+	}
+	ret = si_populate_smc_tdp_limits_2(rdev, boot_ps);
+	if (ret) {
+		DRM_ERROR("si_populate_smc_tdp_limits_2 failed\n");
+		return ret;
+	}
+	si_program_response_times(rdev);
+	si_program_ds_registers(rdev);
+	si_dpm_start_smc(rdev);
+	ret = si_notify_smc_display_change(rdev, false);
+	if (ret) {
+		DRM_ERROR("si_notify_smc_display_change failed\n");
+		return ret;
+	}
+	si_enable_sclk_control(rdev, true);
+	si_start_dpm(rdev);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		PPSMC_Result result;
+
+		ret = si_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+		if (ret)
+			return ret;
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+		result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
+
+		if (result != PPSMC_Result_OK)
+			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
+	}
+
+	si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+	ni_update_current_ps(rdev, boot_ps);
+
+	return 0;
+}
+
+void si_dpm_disable(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+
+	if (!si_is_smc_running(rdev))
+		return;
+	si_disable_ulv(rdev);
+	si_clear_vc(rdev);
+	if (pi->thermal_protection)
+		si_enable_thermal_protection(rdev, false);
+	si_enable_power_containment(rdev, boot_ps, false);
+	si_enable_smc_cac(rdev, boot_ps, false);
+	si_enable_spread_spectrum(rdev, false);
+	si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, false);
+	si_stop_dpm(rdev);
+	si_reset_to_default(rdev);
+	si_dpm_stop_smc(rdev);
+	si_force_switch_to_arb_f0(rdev);
+
+	ni_update_current_ps(rdev, boot_ps);
+}
+
+int si_dpm_pre_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
+	struct radeon_ps *new_ps = &requested_ps;
+
+	ni_update_requested_ps(rdev, new_ps);
+
+	si_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
+
+	return 0;
+}
+
+static int si_power_control_set_level(struct radeon_device *rdev)
+{
+	struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
+	int ret;
+
+	ret = si_restrict_performance_levels_before_switch(rdev);
+	if (ret)
+		return ret;
+	ret = si_halt_smc(rdev);
+	if (ret)
+		return ret;
+	ret = si_populate_smc_tdp_limits(rdev, new_ps);
+	if (ret)
+		return ret;
+	ret = si_populate_smc_tdp_limits_2(rdev, new_ps);
+	if (ret)
+		return ret;
+	ret = si_resume_smc(rdev);
+	if (ret)
+		return ret;
+	ret = si_set_sw_state(rdev);
+	if (ret)
+		return ret;
+	return 0;
+}
+
+int si_dpm_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *new_ps = &eg_pi->requested_rps;
+	struct radeon_ps *old_ps = &eg_pi->current_rps;
+	int ret;
+
+	ret = si_disable_ulv(rdev);
+	if (ret) {
+		DRM_ERROR("si_disable_ulv failed\n");
+		return ret;
+	}
+	ret = si_restrict_performance_levels_before_switch(rdev);
+	if (ret) {
+		DRM_ERROR("si_restrict_performance_levels_before_switch failed\n");
+		return ret;
+	}
+	if (eg_pi->pcie_performance_request)
+		si_request_link_speed_change_before_state_change(rdev, new_ps, old_ps);
+	ni_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+	ret = si_enable_power_containment(rdev, new_ps, false);
+	if (ret) {
+		DRM_ERROR("si_enable_power_containment failed\n");
+		return ret;
+	}
+	ret = si_enable_smc_cac(rdev, new_ps, false);
+	if (ret) {
+		DRM_ERROR("si_enable_smc_cac failed\n");
+		return ret;
+	}
+	ret = si_halt_smc(rdev);
+	if (ret) {
+		DRM_ERROR("si_halt_smc failed\n");
+		return ret;
+	}
+	ret = si_upload_sw_state(rdev, new_ps);
+	if (ret) {
+		DRM_ERROR("si_upload_sw_state failed\n");
+		return ret;
+	}
+	ret = si_upload_smc_data(rdev);
+	if (ret) {
+		DRM_ERROR("si_upload_smc_data failed\n");
+		return ret;
+	}
+	ret = si_upload_ulv_state(rdev);
+	if (ret) {
+		DRM_ERROR("si_upload_ulv_state failed\n");
+		return ret;
+	}
+	if (eg_pi->dynamic_ac_timing) {
+		ret = si_upload_mc_reg_table(rdev, new_ps);
+		if (ret) {
+			DRM_ERROR("si_upload_mc_reg_table failed\n");
+			return ret;
+		}
+	}
+	ret = si_program_memory_timing_parameters(rdev, new_ps);
+	if (ret) {
+		DRM_ERROR("si_program_memory_timing_parameters failed\n");
+		return ret;
+	}
+	si_set_pcie_lane_width_in_smc(rdev, new_ps, old_ps);
+
+	ret = si_resume_smc(rdev);
+	if (ret) {
+		DRM_ERROR("si_resume_smc failed\n");
+		return ret;
+	}
+	ret = si_set_sw_state(rdev);
+	if (ret) {
+		DRM_ERROR("si_set_sw_state failed\n");
+		return ret;
+	}
+	ni_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+	if (eg_pi->pcie_performance_request)
+		si_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
+	ret = si_set_power_state_conditionally_enable_ulv(rdev, new_ps);
+	if (ret) {
+		DRM_ERROR("si_set_power_state_conditionally_enable_ulv failed\n");
+		return ret;
+	}
+	ret = si_enable_smc_cac(rdev, new_ps, true);
+	if (ret) {
+		DRM_ERROR("si_enable_smc_cac failed\n");
+		return ret;
+	}
+	ret = si_enable_power_containment(rdev, new_ps, true);
+	if (ret) {
+		DRM_ERROR("si_enable_power_containment failed\n");
+		return ret;
+	}
+
+	ret = si_power_control_set_level(rdev);
+	if (ret) {
+		DRM_ERROR("si_power_control_set_level failed\n");
+		return ret;
+	}
+
+	ret = si_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO);
+	if (ret) {
+		DRM_ERROR("si_dpm_force_performance_level failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+void si_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct radeon_ps *new_ps = &eg_pi->requested_rps;
+
+	ni_update_current_ps(rdev, new_ps);
+}
+
+
+void si_dpm_reset_asic(struct radeon_device *rdev)
+{
+	si_restrict_performance_levels_before_switch(rdev);
+	si_disable_ulv(rdev);
+	si_set_boot_state(rdev);
+}
+
+void si_dpm_display_configuration_changed(struct radeon_device *rdev)
+{
+	si_program_display_gap(rdev);
+}
+
+union power_info {
+	struct _ATOM_POWERPLAY_INFO info;
+	struct _ATOM_POWERPLAY_INFO_V2 info_2;
+	struct _ATOM_POWERPLAY_INFO_V3 info_3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
+	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
+	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
+};
+
+union pplib_clock_info {
+	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
+	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
+	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
+	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
+	struct _ATOM_PPLIB_SI_CLOCK_INFO si;
+};
+
+union pplib_power_state {
+	struct _ATOM_PPLIB_STATE v1;
+	struct _ATOM_PPLIB_STATE_V2 v2;
+};
+
+static void si_parse_pplib_non_clock_info(struct radeon_device *rdev,
+					  struct radeon_ps *rps,
+					  struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
+					  u8 table_rev)
+{
+	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
+	rps->class = le16_to_cpu(non_clock_info->usClassification);
+	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
+
+	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
+		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
+		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
+	} else if (r600_is_uvd_state(rps->class, rps->class2)) {
+		rps->vclk = RV770_DEFAULT_VCLK_FREQ;
+		rps->dclk = RV770_DEFAULT_DCLK_FREQ;
+	} else {
+		rps->vclk = 0;
+		rps->dclk = 0;
+	}
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
+		rdev->pm.dpm.boot_ps = rps;
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		rdev->pm.dpm.uvd_ps = rps;
+}
+
+static void si_parse_pplib_clock_info(struct radeon_device *rdev,
+				      struct radeon_ps *rps, int index,
+				      union pplib_clock_info *clock_info)
+{
+	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	struct si_power_info *si_pi = si_get_pi(rdev);
+	struct ni_ps *ps = ni_get_ps(rps);
+	u16 leakage_voltage;
+	struct rv7xx_pl *pl = &ps->performance_levels[index];
+	int ret;
+
+	ps->performance_level_count = index + 1;
+
+	pl->sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
+	pl->sclk |= clock_info->si.ucEngineClockHigh << 16;
+	pl->mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
+	pl->mclk |= clock_info->si.ucMemoryClockHigh << 16;
+
+	pl->vddc = le16_to_cpu(clock_info->si.usVDDC);
+	pl->vddci = le16_to_cpu(clock_info->si.usVDDCI);
+	pl->flags = le32_to_cpu(clock_info->si.ulFlags);
+	pl->pcie_gen = r600_get_pcie_gen_support(rdev,
+						 si_pi->sys_pcie_mask,
+						 si_pi->boot_pcie_gen,
+						 clock_info->si.ucPCIEGen);
+
+	/* patch up vddc if necessary */
+	ret = si_get_leakage_voltage_from_leakage_index(rdev, pl->vddc,
+							&leakage_voltage);
+	if (ret == 0)
+		pl->vddc = leakage_voltage;
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
+		pi->acpi_vddc = pl->vddc;
+		eg_pi->acpi_vddci = pl->vddci;
+		si_pi->acpi_pcie_gen = pl->pcie_gen;
+	}
+
+	if ((rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) &&
+	    index == 0) {
+		/* XXX disable for A0 tahiti */
+		si_pi->ulv.supported = true;
+		si_pi->ulv.pl = *pl;
+		si_pi->ulv.one_pcie_lane_in_ulv = false;
+		si_pi->ulv.volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT;
+		si_pi->ulv.cg_ulv_parameter = SISLANDS_CGULVPARAMETER_DFLT;
+		si_pi->ulv.cg_ulv_control = SISLANDS_CGULVCONTROL_DFLT;
+	}
+
+	if (pi->min_vddc_in_table > pl->vddc)
+		pi->min_vddc_in_table = pl->vddc;
+
+	if (pi->max_vddc_in_table < pl->vddc)
+		pi->max_vddc_in_table = pl->vddc;
+
+	/* patch up boot state */
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
+		u16 vddc, vddci, mvdd;
+		radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
+		pl->mclk = rdev->clock.default_mclk;
+		pl->sclk = rdev->clock.default_sclk;
+		pl->vddc = vddc;
+		pl->vddci = vddci;
+		si_pi->mvdd_bootup_value = mvdd;
+	}
+
+	if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
+	    ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
+		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;
+		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;
+		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;
+		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;
+	}
+}
+
+static int si_parse_power_table(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
+	union pplib_power_state *power_state;
+	int i, j, k, non_clock_array_index, clock_array_index;
+	union pplib_clock_info *clock_info;
+	struct _StateArray *state_array;
+	struct _ClockInfoArray *clock_info_array;
+	struct _NonClockInfoArray *non_clock_info_array;
+	union power_info *power_info;
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+        u16 data_offset;
+	u8 frev, crev;
+	u8 *power_state_offset;
+	struct ni_ps *ps;
+
+	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset))
+		return -EINVAL;
+	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+
+	state_array = (struct _StateArray *)
+		(mode_info->atom_context->bios + data_offset +
+		 le16_to_cpu(power_info->pplib.usStateArrayOffset));
+	clock_info_array = (struct _ClockInfoArray *)
+		(mode_info->atom_context->bios + data_offset +
+		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
+	non_clock_info_array = (struct _NonClockInfoArray *)
+		(mode_info->atom_context->bios + data_offset +
+		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
+
+	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
+				  state_array->ucNumEntries, GFP_KERNEL);
+	if (!rdev->pm.dpm.ps)
+		return -ENOMEM;
+	power_state_offset = (u8 *)state_array->states;
+	rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
+	rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
+	rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
+	for (i = 0; i < state_array->ucNumEntries; i++) {
+		power_state = (union pplib_power_state *)power_state_offset;
+		non_clock_array_index = power_state->v2.nonClockInfoIndex;
+		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
+			&non_clock_info_array->nonClockInfo[non_clock_array_index];
+		if (!rdev->pm.power_state[i].clock_info)
+			return -EINVAL;
+		ps = kzalloc(sizeof(struct ni_ps), GFP_KERNEL);
+		if (ps == NULL) {
+			kfree(rdev->pm.dpm.ps);
+			return -ENOMEM;
+		}
+		rdev->pm.dpm.ps[i].ps_priv = ps;
+		si_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
+					      non_clock_info,
+					      non_clock_info_array->ucEntrySize);
+		k = 0;
+		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
+			clock_array_index = power_state->v2.clockInfoIndex[j];
+			if (clock_array_index >= clock_info_array->ucNumEntries)
+				continue;
+			if (k >= SISLANDS_MAX_HARDWARE_POWERLEVELS)
+				break;
+			clock_info = (union pplib_clock_info *)
+				&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
+			si_parse_pplib_clock_info(rdev,
+						  &rdev->pm.dpm.ps[i], k,
+						  clock_info);
+			k++;
+		}
+		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
+	}
+	rdev->pm.dpm.num_ps = state_array->ucNumEntries;
+	return 0;
+}
+
+int si_dpm_init(struct radeon_device *rdev)
+{
+	struct rv7xx_power_info *pi;
+	struct evergreen_power_info *eg_pi;
+	struct ni_power_info *ni_pi;
+	struct si_power_info *si_pi;
+	struct atom_clock_dividers dividers;
+	int ret;
+	u32 mask;
+
+	si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL);
+	if (si_pi == NULL)
+		return -ENOMEM;
+	rdev->pm.dpm.priv = si_pi;
+	ni_pi = &si_pi->ni;
+	eg_pi = &ni_pi->eg;
+	pi = &eg_pi->rv7xx;
+
+	ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
+	if (ret)
+		si_pi->sys_pcie_mask = 0;
+	else
+		si_pi->sys_pcie_mask = mask;
+	si_pi->force_pcie_gen = RADEON_PCIE_GEN_INVALID;
+	si_pi->boot_pcie_gen = si_get_current_pcie_speed(rdev);
+
+	si_set_max_cu_value(rdev);
+
+	rv770_get_max_vddc(rdev);
+	si_get_leakage_vddc(rdev);
+	si_patch_dependency_tables_based_on_leakage(rdev);
+
+	pi->acpi_vddc = 0;
+	eg_pi->acpi_vddci = 0;
+	pi->min_vddc_in_table = 0;
+	pi->max_vddc_in_table = 0;
+
+	ret = si_parse_power_table(rdev);
+	if (ret)
+		return ret;
+	ret = r600_parse_extended_power_table(rdev);
+	if (ret)
+		return ret;
+
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
+		kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL);
+	if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
+		r600_free_extended_power_table(rdev);
+		return -ENOMEM;
+	}
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 720;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 810;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
+	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 900;
+
+	if (rdev->pm.dpm.voltage_response_time == 0)
+		rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
+	if (rdev->pm.dpm.backbias_response_time == 0)
+		rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     0, false, &dividers);
+	if (ret)
+		pi->ref_div = dividers.ref_div + 1;
+	else
+		pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
+
+	eg_pi->smu_uvd_hs = false;
+
+	pi->mclk_strobe_mode_threshold = 40000;
+	if (si_is_special_1gb_platform(rdev))
+		pi->mclk_stutter_mode_threshold = 0;
+	else
+		pi->mclk_stutter_mode_threshold = pi->mclk_strobe_mode_threshold;
+	pi->mclk_edc_enable_threshold = 40000;
+	eg_pi->mclk_edc_wr_enable_threshold = 40000;
+
+	ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;
+
+	pi->voltage_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_GPIO_LUT);
+
+	pi->mvdd_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, VOLTAGE_OBJ_GPIO_LUT);
+
+	eg_pi->vddci_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, VOLTAGE_OBJ_GPIO_LUT);
+
+	si_pi->vddc_phase_shed_control =
+		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, VOLTAGE_OBJ_PHASE_LUT);
+
+	rv770_get_engine_memory_ss(rdev);
+
+	pi->asi = RV770_ASI_DFLT;
+	pi->pasi = CYPRESS_HASI_DFLT;
+	pi->vrc = SISLANDS_VRC_DFLT;
+
+	pi->gfx_clock_gating = true;
+
+	eg_pi->sclk_deep_sleep = true;
+	si_pi->sclk_deep_sleep_above_low = false;
+
+	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
+		pi->thermal_protection = true;
+	else
+		pi->thermal_protection = false;
+
+	eg_pi->dynamic_ac_timing = true;
+
+	eg_pi->light_sleep = true;
+#if defined(CONFIG_ACPI)
+	eg_pi->pcie_performance_request =
+		radeon_acpi_is_pcie_performance_request_supported(rdev);
+#else
+	eg_pi->pcie_performance_request = false;
+#endif
+
+	si_pi->sram_end = SMC_RAM_END;
+
+	rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
+	rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
+	rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
+	rdev->pm.dpm.dyn_state.valid_sclk_values.count = 0;
+	rdev->pm.dpm.dyn_state.valid_sclk_values.values = NULL;
+	rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
+	rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
+
+	si_initialize_powertune_defaults(rdev);
+
+	return 0;
+}
+
+void si_dpm_fini(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	}
+	kfree(rdev->pm.dpm.ps);
+	kfree(rdev->pm.dpm.priv);
+	kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
+	r600_free_extended_power_table(rdev);
+}
+
+void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						    struct seq_file *m)
+{
+	struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+	struct ni_ps *ps = ni_get_ps(rps);
+	struct rv7xx_pl *pl;
+	u32 current_index =
+		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
+		CURRENT_STATE_INDEX_SHIFT;
+
+	if (current_index >= ps->performance_level_count) {
+		seq_printf(m, "invalid dpm profile %d\n", current_index);
+	} else {
+		pl = &ps->performance_levels[current_index];
+		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+		seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",
+			   current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/si_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/si_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/si_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/si_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __SI_DPM_H__
+#define __SI_DPM_H__
+
+#include "ni_dpm.h"
+#include "sislands_smc.h"
+
+enum si_cac_config_reg_type
+{
+	SISLANDS_CACCONFIG_MMR = 0,
+	SISLANDS_CACCONFIG_CGIND,
+	SISLANDS_CACCONFIG_MAX
+};
+
+struct si_cac_config_reg
+{
+	u32 offset;
+	u32 mask;
+	u32 shift;
+	u32 value;
+	enum si_cac_config_reg_type type;
+};
+
+struct si_powertune_data
+{
+	u32 cac_window;
+	u32 l2_lta_window_size_default;
+	u8 lts_truncate_default;
+	u8 shift_n_default;
+	u8 operating_temp;
+	struct ni_leakage_coeffients leakage_coefficients;
+	u32 fixed_kt;
+	u32 lkge_lut_v0_percent;
+	u8 dc_cac[NISLANDS_DCCAC_MAX_LEVELS];
+	bool enable_powertune_by_default;
+};
+
+struct si_dyn_powertune_data
+{
+	u32 cac_leakage;
+	s32 leakage_minimum_temperature;
+	u32 wintime;
+	u32 l2_lta_window_size;
+	u8 lts_truncate;
+	u8 shift_n;
+	u8 dc_pwr_value;
+	bool disable_uvd_powertune;
+};
+
+struct si_dte_data
+{
+	u32 tau[SMC_SISLANDS_DTE_MAX_FILTER_STAGES];
+	u32 r[SMC_SISLANDS_DTE_MAX_FILTER_STAGES];
+	u32 k;
+	u32 t0;
+	u32 max_t;
+	u8 window_size;
+	u8 temp_select;
+	u8 dte_mode;
+	u8 tdep_count;
+	u8 t_limits[SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE];
+	u32 tdep_tau[SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE];
+	u32 tdep_r[SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE];
+	u32 t_threshold;
+	bool enable_dte_by_default;
+};
+
+struct si_clock_registers {
+	u32 cg_spll_func_cntl;
+	u32 cg_spll_func_cntl_2;
+	u32 cg_spll_func_cntl_3;
+	u32 cg_spll_func_cntl_4;
+	u32 cg_spll_spread_spectrum;
+	u32 cg_spll_spread_spectrum_2;
+	u32 dll_cntl;
+	u32 mclk_pwrmgt_cntl;
+	u32 mpll_ad_func_cntl;
+	u32 mpll_dq_func_cntl;
+	u32 mpll_func_cntl;
+	u32 mpll_func_cntl_1;
+	u32 mpll_func_cntl_2;
+	u32 mpll_ss1;
+	u32 mpll_ss2;
+};
+
+struct si_mc_reg_entry {
+	u32 mclk_max;
+	u32 mc_data[SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE];
+};
+
+struct si_mc_reg_table {
+	u8 last;
+	u8 num_entries;
+	u16 valid_flag;
+	struct si_mc_reg_entry mc_reg_table_entry[MAX_AC_TIMING_ENTRIES];
+	SMC_NIslands_MCRegisterAddress mc_reg_address[SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE];
+};
+
+#define SISLANDS_MCREGISTERTABLE_INITIAL_SLOT               0
+#define SISLANDS_MCREGISTERTABLE_ACPI_SLOT                  1
+#define SISLANDS_MCREGISTERTABLE_ULV_SLOT                   2
+#define SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT     3
+
+struct si_leakage_voltage_entry
+{
+	u16 voltage;
+	u16 leakage_index;
+};
+
+#define SISLANDS_LEAKAGE_INDEX0     0xff01
+#define SISLANDS_MAX_LEAKAGE_COUNT  4
+
+struct si_leakage_voltage
+{
+	u16 count;
+	struct si_leakage_voltage_entry entries[SISLANDS_MAX_LEAKAGE_COUNT];
+};
+
+#define SISLANDS_MAX_HARDWARE_POWERLEVELS 5
+
+struct si_ulv_param {
+	bool supported;
+	u32 cg_ulv_control;
+	u32 cg_ulv_parameter;
+	u32 volt_change_delay;
+	struct rv7xx_pl pl;
+	bool one_pcie_lane_in_ulv;
+};
+
+struct si_power_info {
+	/* must be first! */
+	struct ni_power_info ni;
+	struct si_clock_registers clock_registers;
+	struct si_mc_reg_table mc_reg_table;
+	struct atom_voltage_table mvdd_voltage_table;
+	struct atom_voltage_table vddc_phase_shed_table;
+	struct si_leakage_voltage leakage_voltage;
+	u16 mvdd_bootup_value;
+	struct si_ulv_param ulv;
+	u32 max_cu;
+	/* pcie gen */
+	enum radeon_pcie_gen force_pcie_gen;
+	enum radeon_pcie_gen boot_pcie_gen;
+	enum radeon_pcie_gen acpi_pcie_gen;
+	u32 sys_pcie_mask;
+	/* flags */
+	bool enable_dte;
+	bool enable_ppm;
+	bool vddc_phase_shed_control;
+	bool pspp_notify_required;
+	bool sclk_deep_sleep_above_low;
+	/* smc offsets */
+	u32 sram_end;
+	u32 state_table_start;
+	u32 soft_regs_start;
+	u32 mc_reg_table_start;
+	u32 arb_table_start;
+	u32 cac_table_start;
+	u32 dte_table_start;
+	u32 spll_table_start;
+	u32 papm_cfg_table_start;
+	/* CAC stuff */
+	const struct si_cac_config_reg *cac_weights;
+	const struct si_cac_config_reg *lcac_config;
+	const struct si_cac_config_reg *cac_override;
+	const struct si_powertune_data *powertune_data;
+	struct si_dyn_powertune_data dyn_powertune_data;
+	/* DTE stuff */
+	struct si_dte_data dte_data;
+	/* scratch structs */
+	SMC_SIslands_MCRegisters smc_mc_reg_table;
+	SISLANDS_SMC_STATETABLE smc_statetable;
+	PP_SIslands_PAPMParameters papm_parm;
+};
+
+#define SISLANDS_INITIAL_STATE_ARB_INDEX    0
+#define SISLANDS_ACPI_STATE_ARB_INDEX       1
+#define SISLANDS_ULV_STATE_ARB_INDEX        2
+#define SISLANDS_DRIVER_STATE_ARB_INDEX     3
+
+#define SISLANDS_DPM2_MAX_PULSE_SKIP        256
+
+#define SISLANDS_DPM2_NEAR_TDP_DEC          10
+#define SISLANDS_DPM2_ABOVE_SAFE_INC        5
+#define SISLANDS_DPM2_BELOW_SAFE_INC        20
+
+#define SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT            80
+
+#define SISLANDS_DPM2_MAXPS_PERCENT_H                   99
+#define SISLANDS_DPM2_MAXPS_PERCENT_M                   99
+
+#define SISLANDS_DPM2_SQ_RAMP_MAX_POWER                 0x3FFF
+#define SISLANDS_DPM2_SQ_RAMP_MIN_POWER                 0x12
+#define SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA           0x15
+#define SISLANDS_DPM2_SQ_RAMP_STI_SIZE                  0x1E
+#define SISLANDS_DPM2_SQ_RAMP_LTI_RATIO                 0xF
+
+#define SISLANDS_DPM2_PWREFFICIENCYRATIO_MARGIN         10
+
+#define SISLANDS_VRC_DFLT                               0xC000B3
+#define SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT             1687
+#define SISLANDS_CGULVPARAMETER_DFLT                    0x00040035
+#define SISLANDS_CGULVCONTROL_DFLT                      0x1f007550
+
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sislands_smc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sislands_smc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sislands_smc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sislands_smc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,397 @@
+/*
+ * Copyright 2013 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 PP_SISLANDS_SMC_H
+#define PP_SISLANDS_SMC_H
+
+#include "ppsmc.h"
+
+#pragma pack(push, 1)
+
+#define SISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE 16
+
+struct PP_SIslands_Dpm2PerfLevel
+{
+    uint8_t MaxPS;
+    uint8_t TgtAct;
+    uint8_t MaxPS_StepInc;
+    uint8_t MaxPS_StepDec;
+    uint8_t PSSamplingTime;
+    uint8_t NearTDPDec;
+    uint8_t AboveSafeInc;
+    uint8_t BelowSafeInc;
+    uint8_t PSDeltaLimit;
+    uint8_t PSDeltaWin;
+    uint16_t PwrEfficiencyRatio;
+    uint8_t Reserved[4];
+};
+
+typedef struct PP_SIslands_Dpm2PerfLevel PP_SIslands_Dpm2PerfLevel;
+
+struct PP_SIslands_DPM2Status
+{
+    uint32_t    dpm2Flags;
+    uint8_t     CurrPSkip;
+    uint8_t     CurrPSkipPowerShift;
+    uint8_t     CurrPSkipTDP;
+    uint8_t     CurrPSkipOCP;
+    uint8_t     MaxSPLLIndex;
+    uint8_t     MinSPLLIndex;
+    uint8_t     CurrSPLLIndex;
+    uint8_t     InfSweepMode;
+    uint8_t     InfSweepDir;
+    uint8_t     TDPexceeded;
+    uint8_t     reserved;
+    uint8_t     SwitchDownThreshold;
+    uint32_t    SwitchDownCounter;
+    uint32_t    SysScalingFactor;
+};
+
+typedef struct PP_SIslands_DPM2Status PP_SIslands_DPM2Status;
+
+struct PP_SIslands_DPM2Parameters
+{
+    uint32_t    TDPLimit;
+    uint32_t    NearTDPLimit;
+    uint32_t    SafePowerLimit;
+    uint32_t    PowerBoostLimit;
+    uint32_t    MinLimitDelta;
+};
+typedef struct PP_SIslands_DPM2Parameters PP_SIslands_DPM2Parameters;
+
+struct PP_SIslands_PAPMStatus
+{
+    uint32_t    EstimatedDGPU_T;
+    uint32_t    EstimatedDGPU_P;
+    uint32_t    EstimatedAPU_T;
+    uint32_t    EstimatedAPU_P;
+    uint8_t     dGPU_T_Limit_Exceeded;
+    uint8_t     reserved[3];
+};
+typedef struct PP_SIslands_PAPMStatus PP_SIslands_PAPMStatus;
+
+struct PP_SIslands_PAPMParameters
+{
+    uint32_t    NearTDPLimitTherm;
+    uint32_t    NearTDPLimitPAPM;
+    uint32_t    PlatformPowerLimit;
+    uint32_t    dGPU_T_Limit;
+    uint32_t    dGPU_T_Warning;
+    uint32_t    dGPU_T_Hysteresis;
+};
+typedef struct PP_SIslands_PAPMParameters PP_SIslands_PAPMParameters;
+
+struct SISLANDS_SMC_SCLK_VALUE
+{
+    uint32_t    vCG_SPLL_FUNC_CNTL;
+    uint32_t    vCG_SPLL_FUNC_CNTL_2;
+    uint32_t    vCG_SPLL_FUNC_CNTL_3;
+    uint32_t    vCG_SPLL_FUNC_CNTL_4;
+    uint32_t    vCG_SPLL_SPREAD_SPECTRUM;
+    uint32_t    vCG_SPLL_SPREAD_SPECTRUM_2;
+    uint32_t    sclk_value;
+};
+
+typedef struct SISLANDS_SMC_SCLK_VALUE SISLANDS_SMC_SCLK_VALUE;
+
+struct SISLANDS_SMC_MCLK_VALUE
+{
+    uint32_t    vMPLL_FUNC_CNTL;
+    uint32_t    vMPLL_FUNC_CNTL_1;
+    uint32_t    vMPLL_FUNC_CNTL_2;
+    uint32_t    vMPLL_AD_FUNC_CNTL;
+    uint32_t    vMPLL_DQ_FUNC_CNTL;
+    uint32_t    vMCLK_PWRMGT_CNTL;
+    uint32_t    vDLL_CNTL;
+    uint32_t    vMPLL_SS;
+    uint32_t    vMPLL_SS2;
+    uint32_t    mclk_value;
+};
+
+typedef struct SISLANDS_SMC_MCLK_VALUE SISLANDS_SMC_MCLK_VALUE;
+
+struct SISLANDS_SMC_VOLTAGE_VALUE
+{
+    uint16_t    value;
+    uint8_t     index;
+    uint8_t     phase_settings;
+};
+
+typedef struct SISLANDS_SMC_VOLTAGE_VALUE SISLANDS_SMC_VOLTAGE_VALUE;
+
+struct SISLANDS_SMC_HW_PERFORMANCE_LEVEL
+{
+    uint8_t                     ACIndex;
+    uint8_t                     displayWatermark;
+    uint8_t                     gen2PCIE;
+    uint8_t                     UVDWatermark;
+    uint8_t                     VCEWatermark;
+    uint8_t                     strobeMode;
+    uint8_t                     mcFlags;
+    uint8_t                     padding;
+    uint32_t                    aT;
+    uint32_t                    bSP;
+    SISLANDS_SMC_SCLK_VALUE     sclk;
+    SISLANDS_SMC_MCLK_VALUE     mclk;
+    SISLANDS_SMC_VOLTAGE_VALUE  vddc;
+    SISLANDS_SMC_VOLTAGE_VALUE  mvdd;
+    SISLANDS_SMC_VOLTAGE_VALUE  vddci;
+    SISLANDS_SMC_VOLTAGE_VALUE  std_vddc;
+    uint8_t                     hysteresisUp;
+    uint8_t                     hysteresisDown;
+    uint8_t                     stateFlags;
+    uint8_t                     arbRefreshState;
+    uint32_t                    SQPowerThrottle;
+    uint32_t                    SQPowerThrottle_2;
+    uint32_t                    MaxPoweredUpCU;
+    SISLANDS_SMC_VOLTAGE_VALUE  high_temp_vddc;
+    SISLANDS_SMC_VOLTAGE_VALUE  low_temp_vddc;
+    uint32_t                    reserved[2];
+    PP_SIslands_Dpm2PerfLevel   dpm2;
+};
+
+#define SISLANDS_SMC_STROBE_RATIO    0x0F
+#define SISLANDS_SMC_STROBE_ENABLE   0x10
+
+#define SISLANDS_SMC_MC_EDC_RD_FLAG  0x01
+#define SISLANDS_SMC_MC_EDC_WR_FLAG  0x02
+#define SISLANDS_SMC_MC_RTT_ENABLE   0x04
+#define SISLANDS_SMC_MC_STUTTER_EN   0x08
+#define SISLANDS_SMC_MC_PG_EN        0x10
+
+typedef struct SISLANDS_SMC_HW_PERFORMANCE_LEVEL SISLANDS_SMC_HW_PERFORMANCE_LEVEL;
+
+struct SISLANDS_SMC_SWSTATE
+{
+    uint8_t                             flags;
+    uint8_t                             levelCount;
+    uint8_t                             padding2;
+    uint8_t                             padding3;
+    SISLANDS_SMC_HW_PERFORMANCE_LEVEL   levels[1];
+};
+
+typedef struct SISLANDS_SMC_SWSTATE SISLANDS_SMC_SWSTATE;
+
+#define SISLANDS_SMC_VOLTAGEMASK_VDDC  0
+#define SISLANDS_SMC_VOLTAGEMASK_MVDD  1
+#define SISLANDS_SMC_VOLTAGEMASK_VDDCI 2
+#define SISLANDS_SMC_VOLTAGEMASK_MAX   4
+
+struct SISLANDS_SMC_VOLTAGEMASKTABLE
+{
+    uint32_t lowMask[SISLANDS_SMC_VOLTAGEMASK_MAX];
+};
+
+typedef struct SISLANDS_SMC_VOLTAGEMASKTABLE SISLANDS_SMC_VOLTAGEMASKTABLE;
+
+#define SISLANDS_MAX_NO_VREG_STEPS 32
+
+struct SISLANDS_SMC_STATETABLE
+{
+    uint8_t                             thermalProtectType;
+    uint8_t                             systemFlags;
+    uint8_t                             maxVDDCIndexInPPTable;
+    uint8_t                             extraFlags;
+    uint32_t                            lowSMIO[SISLANDS_MAX_NO_VREG_STEPS];
+    SISLANDS_SMC_VOLTAGEMASKTABLE       voltageMaskTable;
+    SISLANDS_SMC_VOLTAGEMASKTABLE       phaseMaskTable;
+    PP_SIslands_DPM2Parameters          dpm2Params;
+    SISLANDS_SMC_SWSTATE                initialState;
+    SISLANDS_SMC_SWSTATE                ACPIState;
+    SISLANDS_SMC_SWSTATE                ULVState;
+    SISLANDS_SMC_SWSTATE                driverState;
+    SISLANDS_SMC_HW_PERFORMANCE_LEVEL   dpmLevels[SISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1];
+};
+
+typedef struct SISLANDS_SMC_STATETABLE SISLANDS_SMC_STATETABLE;
+
+#define SI_SMC_SOFT_REGISTER_mclk_chg_timeout         0x0
+#define SI_SMC_SOFT_REGISTER_delay_vreg               0xC
+#define SI_SMC_SOFT_REGISTER_delay_acpi               0x28
+#define SI_SMC_SOFT_REGISTER_seq_index                0x5C
+#define SI_SMC_SOFT_REGISTER_mvdd_chg_time            0x60
+#define SI_SMC_SOFT_REGISTER_mclk_switch_lim          0x70
+#define SI_SMC_SOFT_REGISTER_watermark_threshold      0x78
+#define SI_SMC_SOFT_REGISTER_phase_shedding_delay     0x88
+#define SI_SMC_SOFT_REGISTER_ulv_volt_change_delay    0x8C
+#define SI_SMC_SOFT_REGISTER_mc_block_delay           0x98
+#define SI_SMC_SOFT_REGISTER_ticks_per_us             0xA8
+#define SI_SMC_SOFT_REGISTER_crtc_index               0xC4
+#define SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min 0xC8
+#define SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max 0xCC
+#define SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width  0xF4
+#define SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen   0xFC
+#define SI_SMC_SOFT_REGISTER_vr_hot_gpio              0x100
+
+#define SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16
+#define SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 32
+
+#define SMC_SISLANDS_SCALE_I  7
+#define SMC_SISLANDS_SCALE_R 12
+
+struct PP_SIslands_CacConfig
+{
+    uint16_t   cac_lkge_lut[SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES];
+    uint32_t   lkge_lut_V0;
+    uint32_t   lkge_lut_Vstep;
+    uint32_t   WinTime;
+    uint32_t   R_LL;
+    uint32_t   calculation_repeats;
+    uint32_t   l2numWin_TDP;
+    uint32_t   dc_cac;
+    uint8_t    lts_truncate_n;
+    uint8_t    SHIFT_N;
+    uint8_t    log2_PG_LKG_SCALE;
+    uint8_t    cac_temp;
+    uint32_t   lkge_lut_T0;
+    uint32_t   lkge_lut_Tstep;
+};
+
+typedef struct PP_SIslands_CacConfig PP_SIslands_CacConfig;
+
+#define SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE 16
+#define SMC_SISLANDS_MC_REGISTER_ARRAY_SET_COUNT 20
+
+struct SMC_SIslands_MCRegisterAddress
+{
+    uint16_t s0;
+    uint16_t s1;
+};
+
+typedef struct SMC_SIslands_MCRegisterAddress SMC_SIslands_MCRegisterAddress;
+
+struct SMC_SIslands_MCRegisterSet
+{
+    uint32_t value[SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE];
+};
+
+typedef struct SMC_SIslands_MCRegisterSet SMC_SIslands_MCRegisterSet;
+
+struct SMC_SIslands_MCRegisters
+{
+    uint8_t                             last;
+    uint8_t                             reserved[3];
+    SMC_SIslands_MCRegisterAddress      address[SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE];
+    SMC_SIslands_MCRegisterSet          data[SMC_SISLANDS_MC_REGISTER_ARRAY_SET_COUNT];
+};
+
+typedef struct SMC_SIslands_MCRegisters SMC_SIslands_MCRegisters;
+
+struct SMC_SIslands_MCArbDramTimingRegisterSet
+{
+    uint32_t mc_arb_dram_timing;
+    uint32_t mc_arb_dram_timing2;
+    uint8_t  mc_arb_rfsh_rate;
+    uint8_t  mc_arb_burst_time;
+    uint8_t  padding[2];
+};
+
+typedef struct SMC_SIslands_MCArbDramTimingRegisterSet SMC_SIslands_MCArbDramTimingRegisterSet;
+
+struct SMC_SIslands_MCArbDramTimingRegisters
+{
+    uint8_t                                     arb_current;
+    uint8_t                                     reserved[3];
+    SMC_SIslands_MCArbDramTimingRegisterSet     data[16];
+};
+
+typedef struct SMC_SIslands_MCArbDramTimingRegisters SMC_SIslands_MCArbDramTimingRegisters;
+
+struct SMC_SISLANDS_SPLL_DIV_TABLE
+{
+    uint32_t    freq[256];
+    uint32_t    ss[256];
+};
+
+#define SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK  0x01ffffff
+#define SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT 0
+#define SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK   0xfe000000
+#define SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT  25
+#define SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK   0x000fffff
+#define SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT  0
+#define SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK   0xfff00000
+#define SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT  20
+
+typedef struct SMC_SISLANDS_SPLL_DIV_TABLE SMC_SISLANDS_SPLL_DIV_TABLE;
+
+#define SMC_SISLANDS_DTE_MAX_FILTER_STAGES 5
+
+#define SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE 16
+
+struct Smc_SIslands_DTE_Configuration
+{
+    uint32_t tau[SMC_SISLANDS_DTE_MAX_FILTER_STAGES];
+    uint32_t R[SMC_SISLANDS_DTE_MAX_FILTER_STAGES];
+    uint32_t K;
+    uint32_t T0;
+    uint32_t MaxT;
+    uint8_t  WindowSize;
+    uint8_t  Tdep_count;
+    uint8_t  temp_select;
+    uint8_t  DTE_mode;
+    uint8_t  T_limits[SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE];
+    uint32_t Tdep_tau[SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE];
+    uint32_t Tdep_R[SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE];
+    uint32_t Tthreshold;
+};
+
+typedef struct Smc_SIslands_DTE_Configuration Smc_SIslands_DTE_Configuration;
+
+#define SMC_SISLANDS_DTE_STATUS_FLAG_DTE_ON 1
+
+#define SISLANDS_SMC_FIRMWARE_HEADER_LOCATION 0x10000
+
+#define SISLANDS_SMC_FIRMWARE_HEADER_version                   0x0
+#define SISLANDS_SMC_FIRMWARE_HEADER_flags                     0x4
+#define SISLANDS_SMC_FIRMWARE_HEADER_softRegisters             0xC
+#define SISLANDS_SMC_FIRMWARE_HEADER_stateTable                0x10
+#define SISLANDS_SMC_FIRMWARE_HEADER_fanTable                  0x14
+#define SISLANDS_SMC_FIRMWARE_HEADER_CacConfigTable            0x18
+#define SISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable           0x24
+#define SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable 0x30
+#define SISLANDS_SMC_FIRMWARE_HEADER_spllTable                 0x38
+#define SISLANDS_SMC_FIRMWARE_HEADER_DteConfiguration          0x40
+#define SISLANDS_SMC_FIRMWARE_HEADER_PAPMParameters            0x48
+
+#pragma pack(pop)
+
+int si_set_smc_sram_address(struct radeon_device *rdev,
+			    u32 smc_address, u32 limit);
+int si_copy_bytes_to_smc(struct radeon_device *rdev,
+			 u32 smc_start_address,
+			 const u8 *src, u32 byte_count, u32 limit);
+void si_start_smc(struct radeon_device *rdev);
+void si_reset_smc(struct radeon_device *rdev);
+int si_program_jump_on_start(struct radeon_device *rdev);
+void si_stop_smc_clock(struct radeon_device *rdev);
+void si_start_smc_clock(struct radeon_device *rdev);
+bool si_is_smc_running(struct radeon_device *rdev);
+PPSMC_Result si_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg);
+PPSMC_Result si_wait_for_smc_inactive(struct radeon_device *rdev);
+int si_load_smc_ucode(struct radeon_device *rdev, u32 limit);
+int si_read_smc_sram_dword(struct radeon_device *rdev, u32 smc_address,
+			   u32 *value, u32 limit);
+int si_write_smc_sram_dword(struct radeon_device *rdev, u32 smc_address,
+			    u32 value, u32 limit);
+
+#endif
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/si_smc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/si_smc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/si_smc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/si_smc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include <linux/firmware.h>
+#include "drmP.h"
+#include "radeon.h"
+#include "sid.h"
+#include "ppsmc.h"
+#include "radeon_ucode.h"
+
+int si_set_smc_sram_address(struct radeon_device *rdev,
+			    u32 smc_address, u32 limit)
+{
+	if (smc_address & 3)
+		return -EINVAL;
+	if ((smc_address + 3) > limit)
+		return -EINVAL;
+
+	WREG32(SMC_IND_INDEX_0, smc_address);
+	WREG32_P(SMC_IND_ACCESS_CNTL, 0, ~AUTO_INCREMENT_IND_0);
+
+	return 0;
+}
+
+int si_copy_bytes_to_smc(struct radeon_device *rdev,
+			 u32 smc_start_address,
+			 const u8 *src, u32 byte_count, u32 limit)
+{
+	int ret;
+	u32 data, original_data, addr, extra_shift;
+
+	if (smc_start_address & 3)
+		return -EINVAL;
+	if ((smc_start_address + byte_count) > limit)
+		return -EINVAL;
+
+	addr = smc_start_address;
+
+	while (byte_count >= 4) {
+		/* SMC address space is BE */
+		data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
+
+		ret = si_set_smc_sram_address(rdev, addr, limit);
+		if (ret)
+			return ret;
+
+		WREG32(SMC_IND_DATA_0, data);
+
+		src += 4;
+		byte_count -= 4;
+		addr += 4;
+	}
+
+	/* RMW for the final bytes */
+	if (byte_count > 0) {
+		data = 0;
+
+		ret = si_set_smc_sram_address(rdev, addr, limit);
+		if (ret)
+			return ret;
+
+		original_data = RREG32(SMC_IND_DATA_0);
+
+		extra_shift = 8 * (4 - byte_count);
+
+		while (byte_count > 0) {
+			/* SMC address space is BE */
+			data = (data << 8) + *src++;
+			byte_count--;
+		}
+
+		data <<= extra_shift;
+
+		data |= (original_data & ~((~0UL) << extra_shift));
+
+		ret = si_set_smc_sram_address(rdev, addr, limit);
+		if (ret)
+			return ret;
+
+		WREG32(SMC_IND_DATA_0, data);
+	}
+	return 0;
+}
+
+void si_start_smc(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32_SMC(SMC_SYSCON_RESET_CNTL);
+
+	tmp &= ~RST_REG;
+
+	WREG32_SMC(SMC_SYSCON_RESET_CNTL, tmp);
+}
+
+void si_reset_smc(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	RREG32(CB_CGTT_SCLK_CTRL);
+	RREG32(CB_CGTT_SCLK_CTRL);
+	RREG32(CB_CGTT_SCLK_CTRL);
+	RREG32(CB_CGTT_SCLK_CTRL);
+
+	tmp = RREG32_SMC(SMC_SYSCON_RESET_CNTL);
+	tmp |= RST_REG;
+	WREG32_SMC(SMC_SYSCON_RESET_CNTL, tmp);
+}
+
+int si_program_jump_on_start(struct radeon_device *rdev)
+{
+	static u8 data[] = { 0x0E, 0x00, 0x40, 0x40 };
+
+	return si_copy_bytes_to_smc(rdev, 0x0, data, 4, sizeof(data)+1);
+}
+
+void si_stop_smc_clock(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0);
+
+	tmp |= CK_DISABLE;
+
+	WREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0, tmp);
+}
+
+void si_start_smc_clock(struct radeon_device *rdev)
+{
+	u32 tmp = RREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0);
+
+	tmp &= ~CK_DISABLE;
+
+	WREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0, tmp);
+}
+
+bool si_is_smc_running(struct radeon_device *rdev)
+{
+	u32 rst = RREG32_SMC(SMC_SYSCON_RESET_CNTL);
+	u32 clk = RREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0);
+
+	if (!(rst & RST_REG) && !(clk & CK_DISABLE))
+		return true;
+
+	return false;
+}
+
+PPSMC_Result si_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg)
+{
+	u32 tmp;
+	int i;
+
+	if (!si_is_smc_running(rdev))
+		return PPSMC_Result_Failed;
+
+	WREG32(SMC_MESSAGE_0, msg);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(SMC_RESP_0);
+		if (tmp != 0)
+			break;
+		udelay(1);
+	}
+	tmp = RREG32(SMC_RESP_0);
+
+	return (PPSMC_Result)tmp;
+}
+
+PPSMC_Result si_wait_for_smc_inactive(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int i;
+
+	if (!si_is_smc_running(rdev))
+		return PPSMC_Result_OK;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0);
+		if ((tmp & CKEN) == 0)
+			break;
+		udelay(1);
+	}
+
+	return PPSMC_Result_OK;
+}
+
+int si_load_smc_ucode(struct radeon_device *rdev, u32 limit)
+{
+	u32 ucode_start_address;
+	u32 ucode_size;
+	const u8 *src;
+	u32 data;
+
+	if (!rdev->smc_fw)
+		return -EINVAL;
+
+	switch (rdev->family) {
+	case CHIP_TAHITI:
+		ucode_start_address = TAHITI_SMC_UCODE_START;
+		ucode_size = TAHITI_SMC_UCODE_SIZE;
+		break;
+	case CHIP_PITCAIRN:
+		ucode_start_address = PITCAIRN_SMC_UCODE_START;
+		ucode_size = PITCAIRN_SMC_UCODE_SIZE;
+		break;
+	case CHIP_VERDE:
+		ucode_start_address = VERDE_SMC_UCODE_START;
+		ucode_size = VERDE_SMC_UCODE_SIZE;
+		break;
+	case CHIP_OLAND:
+		ucode_start_address = OLAND_SMC_UCODE_START;
+		ucode_size = OLAND_SMC_UCODE_SIZE;
+		break;
+	case CHIP_HAINAN:
+		ucode_start_address = HAINAN_SMC_UCODE_START;
+		ucode_size = HAINAN_SMC_UCODE_SIZE;
+		break;
+	default:
+		DRM_ERROR("unknown asic in smc ucode loader\n");
+		BUG();
+	}
+
+	if (ucode_size & 3)
+		return -EINVAL;
+
+	src = (const u8 *)rdev->smc_fw->data;
+	WREG32(SMC_IND_INDEX_0, ucode_start_address);
+	WREG32_P(SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, ~AUTO_INCREMENT_IND_0);
+	while (ucode_size >= 4) {
+		/* SMC address space is BE */
+		data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
+
+		WREG32(SMC_IND_DATA_0, data);
+
+		src += 4;
+		ucode_size -= 4;
+	}
+	WREG32_P(SMC_IND_ACCESS_CNTL, 0, ~AUTO_INCREMENT_IND_0);
+
+	return 0;
+}
+
+int si_read_smc_sram_dword(struct radeon_device *rdev, u32 smc_address,
+			   u32 *value, u32 limit)
+{
+	int ret;
+
+	ret = si_set_smc_sram_address(rdev, smc_address, limit);
+	if (ret)
+		return ret;
+
+	*value = RREG32(SMC_IND_DATA_0);
+	return 0;
+}
+
+int si_write_smc_sram_dword(struct radeon_device *rdev, u32 smc_address,
+			    u32 value, u32 limit)
+{
+	int ret;
+
+	ret = si_set_smc_sram_address(rdev, smc_address, limit);
+	if (ret)
+		return ret;
+
+	WREG32(SMC_IND_DATA_0, value);
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sumod.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sumod.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sumod.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sumod.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+#ifndef _SUMOD_H_
+#define _SUMOD_H_
+
+/* pm registers */
+
+/* rcu */
+#define RCU_FW_VERSION                                  0x30c
+
+#define RCU_PWR_GATING_SEQ0                             0x408
+#define RCU_PWR_GATING_SEQ1                             0x40c
+#define RCU_PWR_GATING_CNTL                             0x410
+#       define PWR_GATING_EN                            (1 << 0)
+#       define RSVD_MASK                                (0x3 << 1)
+#       define PCV(x)                                   ((x) << 3)
+#       define PCV_MASK                                 (0x1f << 3)
+#       define PCV_SHIFT                                3
+#       define PCP(x)                                   ((x) << 8)
+#       define PCP_MASK                                 (0xf << 8)
+#       define PCP_SHIFT                                8
+#       define RPW(x)                                   ((x) << 16)
+#       define RPW_MASK                                 (0xf << 16)
+#       define RPW_SHIFT                                16
+#       define ID(x)                                    ((x) << 24)
+#       define ID_MASK                                  (0xf << 24)
+#       define ID_SHIFT                                 24
+#       define PGS(x)                                   ((x) << 28)
+#       define PGS_MASK                                 (0xf << 28)
+#       define PGS_SHIFT                                28
+
+#define RCU_ALTVDDNB_NOTIFY                             0x430
+#define RCU_LCLK_SCALING_CNTL                           0x434
+#       define LCLK_SCALING_EN                          (1 << 0)
+#       define LCLK_SCALING_TYPE                        (1 << 1)
+#       define LCLK_SCALING_TIMER_PRESCALER(x)          ((x) << 4)
+#       define LCLK_SCALING_TIMER_PRESCALER_MASK        (0xf << 4)
+#       define LCLK_SCALING_TIMER_PRESCALER_SHIFT       4
+#       define LCLK_SCALING_TIMER_PERIOD(x)             ((x) << 16)
+#       define LCLK_SCALING_TIMER_PERIOD_MASK           (0xf << 16)
+#       define LCLK_SCALING_TIMER_PERIOD_SHIFT          16
+
+#define RCU_PWR_GATING_CNTL_2                           0x4a0
+#       define MPPU(x)                                  ((x) << 0)
+#       define MPPU_MASK                                (0xffff << 0)
+#       define MPPU_SHIFT                               0
+#       define MPPD(x)                                  ((x) << 16)
+#       define MPPD_MASK                                (0xffff << 16)
+#       define MPPD_SHIFT                               16
+#define RCU_PWR_GATING_CNTL_3                           0x4a4
+#       define DPPU(x)                                  ((x) << 0)
+#       define DPPU_MASK                                (0xffff << 0)
+#       define DPPU_SHIFT                               0
+#       define DPPD(x)                                  ((x) << 16)
+#       define DPPD_MASK                                (0xffff << 16)
+#       define DPPD_SHIFT                               16
+#define RCU_PWR_GATING_CNTL_4                           0x4a8
+#       define RT(x)                                    ((x) << 0)
+#       define RT_MASK                                  (0xffff << 0)
+#       define RT_SHIFT                                 0
+#       define IT(x)                                    ((x) << 16)
+#       define IT_MASK                                  (0xffff << 16)
+#       define IT_SHIFT                                 16
+
+/* yes these two have the same address */
+#define RCU_PWR_GATING_CNTL_5                           0x504
+#define RCU_GPU_BOOST_DISABLE                           0x508
+
+#define MCU_M3ARB_INDEX                                 0x504
+#define MCU_M3ARB_PARAMS                                0x508
+
+#define RCU_GNB_PWR_REP_TIMER_CNTL                      0x50C
+
+#define RCU_SclkDpmTdpLimit01                           0x514
+#define RCU_SclkDpmTdpLimit23                           0x518
+#define RCU_SclkDpmTdpLimit47                           0x51C
+#define RCU_SclkDpmTdpLimitPG                           0x520
+
+#define GNB_TDP_LIMIT                                   0x540
+#define RCU_BOOST_MARGIN                                0x544
+#define RCU_THROTTLE_MARGIN                             0x548
+
+#define SMU_PCIE_PG_ARGS                                0x58C
+#define SMU_PCIE_PG_ARGS_2                              0x598
+#define SMU_PCIE_PG_ARGS_3                              0x59C
+
+/* mmio */
+#define RCU_STATUS                                      0x11c
+#       define GMC_PWR_GATER_BUSY                       (1 << 8)
+#       define GFX_PWR_GATER_BUSY                       (1 << 9)
+#       define UVD_PWR_GATER_BUSY                       (1 << 10)
+#       define PCIE_PWR_GATER_BUSY                      (1 << 11)
+#       define GMC_PWR_GATER_STATE                      (1 << 12)
+#       define GFX_PWR_GATER_STATE                      (1 << 13)
+#       define UVD_PWR_GATER_STATE                      (1 << 14)
+#       define PCIE_PWR_GATER_STATE                     (1 << 15)
+#       define GFX1_PWR_GATER_BUSY                      (1 << 16)
+#       define GFX2_PWR_GATER_BUSY                      (1 << 17)
+#       define GFX1_PWR_GATER_STATE                     (1 << 18)
+#       define GFX2_PWR_GATER_STATE                     (1 << 19)
+
+#define GFX_INT_REQ                                     0x120
+#       define INT_REQ                                  (1 << 0)
+#       define SERV_INDEX(x)                            ((x) << 1)
+#       define SERV_INDEX_MASK                          (0xff << 1)
+#       define SERV_INDEX_SHIFT                         1
+#define GFX_INT_STATUS                                  0x124
+#       define INT_ACK                                  (1 << 0)
+#       define INT_DONE                                 (1 << 1)
+
+#define CG_SCLK_CNTL                                    0x600
+#       define SCLK_DIVIDER(x)                          ((x) << 0)
+#       define SCLK_DIVIDER_MASK                        (0x7f << 0)
+#       define SCLK_DIVIDER_SHIFT                       0
+#define CG_SCLK_STATUS                                  0x604
+#       define SCLK_OVERCLK_DETECT                      (1 << 2)
+
+#define CG_DCLK_CNTL                                    0x610
+#       define DCLK_DIVIDER_MASK                        0x7f
+#       define DCLK_DIR_CNTL_EN                         (1 << 8)
+#define CG_DCLK_STATUS                                  0x614
+#       define DCLK_STATUS                              (1 << 0)
+#define CG_VCLK_CNTL                                    0x618
+#       define VCLK_DIVIDER_MASK                        0x7f
+#       define VCLK_DIR_CNTL_EN                         (1 << 8)
+#define CG_VCLK_STATUS                                  0x61c
+
+#define GENERAL_PWRMGT                                  0x63c
+#       define STATIC_PM_EN                             (1 << 1)
+
+#define SCLK_PWRMGT_CNTL                                0x644
+#       define SCLK_PWRMGT_OFF                          (1 << 0)
+#       define SCLK_LOW_D1                              (1 << 1)
+#       define FIR_RESET                                (1 << 4)
+#       define FIR_FORCE_TREND_SEL                      (1 << 5)
+#       define FIR_TREND_MODE                           (1 << 6)
+#       define DYN_GFX_CLK_OFF_EN                       (1 << 7)
+#       define GFX_CLK_FORCE_ON                         (1 << 8)
+#       define GFX_CLK_REQUEST_OFF                      (1 << 9)
+#       define GFX_CLK_FORCE_OFF                        (1 << 10)
+#       define GFX_CLK_OFF_ACPI_D1                      (1 << 11)
+#       define GFX_CLK_OFF_ACPI_D2                      (1 << 12)
+#       define GFX_CLK_OFF_ACPI_D3                      (1 << 13)
+#       define GFX_VOLTAGE_CHANGE_EN                    (1 << 16)
+#       define GFX_VOLTAGE_CHANGE_MODE                  (1 << 17)
+
+#define TARGET_AND_CURRENT_PROFILE_INDEX                0x66c
+#       define TARG_SCLK_INDEX(x)                       ((x) << 6)
+#       define TARG_SCLK_INDEX_MASK                     (0x7 << 6)
+#       define TARG_SCLK_INDEX_SHIFT                    6
+#       define CURR_SCLK_INDEX(x)                       ((x) << 9)
+#       define CURR_SCLK_INDEX_MASK                     (0x7 << 9)
+#       define CURR_SCLK_INDEX_SHIFT                    9
+#       define TARG_INDEX(x)                            ((x) << 12)
+#       define TARG_INDEX_MASK                          (0x7 << 12)
+#       define TARG_INDEX_SHIFT                         12
+#       define CURR_INDEX(x)                            ((x) << 15)
+#       define CURR_INDEX_MASK                          (0x7 << 15)
+#       define CURR_INDEX_SHIFT                         15
+
+#define CG_SCLK_DPM_CTRL                                0x684
+#       define SCLK_FSTATE_0_DIV(x)                     ((x) << 0)
+#       define SCLK_FSTATE_0_DIV_MASK                   (0x7f << 0)
+#       define SCLK_FSTATE_0_DIV_SHIFT                  0
+#       define SCLK_FSTATE_0_VLD                        (1 << 7)
+#       define SCLK_FSTATE_1_DIV(x)                     ((x) << 8)
+#       define SCLK_FSTATE_1_DIV_MASK                   (0x7f << 8)
+#       define SCLK_FSTATE_1_DIV_SHIFT                  8
+#       define SCLK_FSTATE_1_VLD                        (1 << 15)
+#       define SCLK_FSTATE_2_DIV(x)                     ((x) << 16)
+#       define SCLK_FSTATE_2_DIV_MASK                   (0x7f << 16)
+#       define SCLK_FSTATE_2_DIV_SHIFT                  16
+#       define SCLK_FSTATE_2_VLD                        (1 << 23)
+#       define SCLK_FSTATE_3_DIV(x)                     ((x) << 24)
+#       define SCLK_FSTATE_3_DIV_MASK                   (0x7f << 24)
+#       define SCLK_FSTATE_3_DIV_SHIFT                  24
+#       define SCLK_FSTATE_3_VLD                        (1 << 31)
+#define CG_SCLK_DPM_CTRL_2                              0x688
+#define CG_GCOOR                                        0x68c
+#       define PHC(x)                                   ((x) << 0)
+#       define PHC_MASK                                 (0x1f << 0)
+#       define PHC_SHIFT                                0
+#       define SDC(x)                                   ((x) << 9)
+#       define SDC_MASK                                 (0x3ff << 9)
+#       define SDC_SHIFT                                9
+#       define SU(x)                                    ((x) << 23)
+#       define SU_MASK                                  (0xf << 23)
+#       define SU_SHIFT                                 23
+#       define DIV_ID(x)                                ((x) << 28)
+#       define DIV_ID_MASK                              (0x7 << 28)
+#       define DIV_ID_SHIFT                             28
+
+#define CG_FTV                                          0x690
+#define CG_FFCT_0                                       0x694
+#       define UTC_0(x)                                 ((x) << 0)
+#       define UTC_0_MASK                               (0x3ff << 0)
+#       define UTC_0_SHIFT                              0
+#       define DTC_0(x)                                 ((x) << 10)
+#       define DTC_0_MASK                               (0x3ff << 10)
+#       define DTC_0_SHIFT                              10
+
+#define CG_GIT                                          0x6d8
+#       define CG_GICST(x)                              ((x) << 0)
+#       define CG_GICST_MASK                            (0xffff << 0)
+#       define CG_GICST_SHIFT                           0
+#       define CG_GIPOT(x)                              ((x) << 16)
+#       define CG_GIPOT_MASK                            (0xffff << 16)
+#       define CG_GIPOT_SHIFT                           16
+
+#define CG_SCLK_DPM_CTRL_3                              0x6e0
+#       define FORCE_SCLK_STATE(x)                      ((x) << 0)
+#       define FORCE_SCLK_STATE_MASK                    (0x7 << 0)
+#       define FORCE_SCLK_STATE_SHIFT                   0
+#       define FORCE_SCLK_STATE_EN                      (1 << 3)
+#       define GNB_TT(x)                                ((x) << 8)
+#       define GNB_TT_MASK                              (0xff << 8)
+#       define GNB_TT_SHIFT                             8
+#       define GNB_THERMTHRO_MASK                       (1 << 16)
+#       define CNB_THERMTHRO_MASK_SCLK                  (1 << 17)
+#       define DPM_SCLK_ENABLE                          (1 << 18)
+#       define GNB_SLOW_FSTATE_0_MASK                   (1 << 23)
+#       define GNB_SLOW_FSTATE_0_SHIFT                  23
+#       define FORCE_NB_PSTATE_1                        (1 << 31)
+
+#define CG_SSP                                          0x6e8
+#       define SST(x)                                   ((x) << 0)
+#       define SST_MASK                                 (0xffff << 0)
+#       define SST_SHIFT                                0
+#       define SSTU(x)                                  ((x) << 16)
+#       define SSTU_MASK                                (0xffff << 16)
+#       define SSTU_SHIFT                               16
+
+#define CG_ACPI_CNTL                                    0x70c
+#       define SCLK_ACPI_DIV(x)                         ((x) << 0)
+#       define SCLK_ACPI_DIV_MASK                       (0x7f << 0)
+#       define SCLK_ACPI_DIV_SHIFT                      0
+
+#define CG_SCLK_DPM_CTRL_4                              0x71c
+#       define DC_HDC(x)                                ((x) << 14)
+#       define DC_HDC_MASK                              (0x3fff << 14)
+#       define DC_HDC_SHIFT                             14
+#       define DC_HU(x)                                 ((x) << 28)
+#       define DC_HU_MASK                               (0xf << 28)
+#       define DC_HU_SHIFT                              28
+#define CG_SCLK_DPM_CTRL_5                              0x720
+#       define SCLK_FSTATE_BOOTUP(x)                    ((x) << 0)
+#       define SCLK_FSTATE_BOOTUP_MASK                  (0x7 << 0)
+#       define SCLK_FSTATE_BOOTUP_SHIFT                 0
+#       define TT_TP(x)                                 ((x) << 3)
+#       define TT_TP_MASK                               (0xffff << 3)
+#       define TT_TP_SHIFT                              3
+#       define TT_TU(x)                                 ((x) << 19)
+#       define TT_TU_MASK                               (0xff << 19)
+#       define TT_TU_SHIFT                              19
+#define CG_SCLK_DPM_CTRL_6                              0x724
+#define CG_AT_0                                         0x728
+#       define CG_R(x)                                  ((x) << 0)
+#       define CG_R_MASK                                (0xffff << 0)
+#       define CG_R_SHIFT                               0
+#       define CG_L(x)                                  ((x) << 16)
+#       define CG_L_MASK                                (0xffff << 16)
+#       define CG_L_SHIFT                               16
+#define CG_AT_1                                         0x72c
+#define CG_AT_2                                         0x730
+#define	CG_THERMAL_INT					0x734
+#define		DIG_THERM_INTH(x)			((x) << 8)
+#define		DIG_THERM_INTH_MASK			0x0000FF00
+#define		DIG_THERM_INTH_SHIFT			8
+#define		DIG_THERM_INTL(x)			((x) << 16)
+#define		DIG_THERM_INTL_MASK			0x00FF0000
+#define		DIG_THERM_INTL_SHIFT			16
+#define 	THERM_INT_MASK_HIGH			(1 << 24)
+#define 	THERM_INT_MASK_LOW			(1 << 25)
+#define CG_AT_3                                         0x738
+#define CG_AT_4                                         0x73c
+#define CG_AT_5                                         0x740
+#define CG_AT_6                                         0x744
+#define CG_AT_7                                         0x748
+
+#define CG_BSP_0                                        0x750
+#       define BSP(x)                                   ((x) << 0)
+#       define BSP_MASK                                 (0xffff << 0)
+#       define BSP_SHIFT                                0
+#       define BSU(x)                                   ((x) << 16)
+#       define BSU_MASK                                 (0xf << 16)
+#       define BSU_SHIFT                                16
+
+#define CG_CG_VOLTAGE_CNTL                              0x770
+#       define REQ                                      (1 << 0)
+#       define LEVEL(x)                                 ((x) << 1)
+#       define LEVEL_MASK                               (0x3 << 1)
+#       define LEVEL_SHIFT                              1
+#       define CG_VOLTAGE_EN                            (1 << 3)
+#       define FORCE                                    (1 << 4)
+#       define PERIOD(x)                                ((x) << 8)
+#       define PERIOD_MASK                              (0xffff << 8)
+#       define PERIOD_SHIFT                             8
+#       define UNIT(x)                                  ((x) << 24)
+#       define UNIT_MASK                                (0xf << 24)
+#       define UNIT_SHIFT                               24
+
+#define CG_ACPI_VOLTAGE_CNTL                            0x780
+#       define ACPI_VOLTAGE_EN                          (1 << 8)
+
+#define CG_DPM_VOLTAGE_CNTL                             0x788
+#       define DPM_STATE0_LEVEL_MASK                    (0x3 << 0)
+#       define DPM_STATE0_LEVEL_SHIFT                   0
+#       define DPM_VOLTAGE_EN                           (1 << 16)
+
+#define CG_PWR_GATING_CNTL                              0x7ac
+#       define DYN_PWR_DOWN_EN                          (1 << 0)
+#       define ACPI_PWR_DOWN_EN                         (1 << 1)
+#       define GFX_CLK_OFF_PWR_DOWN_EN                  (1 << 2)
+#       define IOC_DISGPU_PWR_DOWN_EN                   (1 << 3)
+#       define FORCE_POWR_ON                            (1 << 4)
+#       define PGP(x)                                   ((x) << 8)
+#       define PGP_MASK                                 (0xffff << 8)
+#       define PGP_SHIFT                                8
+#       define PGU(x)                                   ((x) << 24)
+#       define PGU_MASK                                 (0xf << 24)
+#       define PGU_SHIFT                                24
+
+#define CG_CGTT_LOCAL_0                                 0x7d0
+#define CG_CGTT_LOCAL_1                                 0x7d4
+
+#define DEEP_SLEEP_CNTL                                 0x818
+#       define R_DIS                                    (1 << 3)
+#       define HS(x)                                    ((x) << 4)
+#       define HS_MASK                                  (0xfff << 4)
+#       define HS_SHIFT                                 4
+#       define ENABLE_DS                                (1 << 31)
+#define DEEP_SLEEP_CNTL2                                0x81c
+#       define LB_UFP_EN                                (1 << 0)
+#       define INOUT_C(x)                               ((x) << 4)
+#       define INOUT_C_MASK                             (0xff << 4)
+#       define INOUT_C_SHIFT                            4
+
+#define CG_SCRATCH2                                     0x824
+
+#define CG_SCLK_DPM_CTRL_11                             0x830
+
+#define HW_REV   					0x5564
+#       define ATI_REV_ID_MASK                          (0xf << 28)
+#       define ATI_REV_ID_SHIFT                         28
+/* 0 = A0, 1 = A1, 2 = B0, 3 = C0, etc. */
+
+#define DOUT_SCRATCH3   				0x611c
+
+#define GB_ADDR_CONFIG  				0x98f8
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sumo_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sumo_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sumo_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sumo_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1888 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "drmP.h"
+#include "radeon.h"
+#include "sumod.h"
+#include "r600_dpm.h"
+#include "cypress_dpm.h"
+#include "sumo_dpm.h"
+#include <linux/seq_file.h>
+
+#define SUMO_MAX_DEEPSLEEP_DIVIDER_ID 5
+#define SUMO_MINIMUM_ENGINE_CLOCK 800
+#define BOOST_DPM_LEVEL 7
+
+static const u32 sumo_utc[SUMO_PM_NUMBER_OF_TC] =
+{
+	SUMO_UTC_DFLT_00,
+	SUMO_UTC_DFLT_01,
+	SUMO_UTC_DFLT_02,
+	SUMO_UTC_DFLT_03,
+	SUMO_UTC_DFLT_04,
+	SUMO_UTC_DFLT_05,
+	SUMO_UTC_DFLT_06,
+	SUMO_UTC_DFLT_07,
+	SUMO_UTC_DFLT_08,
+	SUMO_UTC_DFLT_09,
+	SUMO_UTC_DFLT_10,
+	SUMO_UTC_DFLT_11,
+	SUMO_UTC_DFLT_12,
+	SUMO_UTC_DFLT_13,
+	SUMO_UTC_DFLT_14,
+};
+
+static const u32 sumo_dtc[SUMO_PM_NUMBER_OF_TC] =
+{
+	SUMO_DTC_DFLT_00,
+	SUMO_DTC_DFLT_01,
+	SUMO_DTC_DFLT_02,
+	SUMO_DTC_DFLT_03,
+	SUMO_DTC_DFLT_04,
+	SUMO_DTC_DFLT_05,
+	SUMO_DTC_DFLT_06,
+	SUMO_DTC_DFLT_07,
+	SUMO_DTC_DFLT_08,
+	SUMO_DTC_DFLT_09,
+	SUMO_DTC_DFLT_10,
+	SUMO_DTC_DFLT_11,
+	SUMO_DTC_DFLT_12,
+	SUMO_DTC_DFLT_13,
+	SUMO_DTC_DFLT_14,
+};
+
+struct sumo_ps *sumo_get_ps(struct radeon_ps *rps)
+{
+	struct sumo_ps *ps = rps->ps_priv;
+
+	return ps;
+}
+
+struct sumo_power_info *sumo_get_pi(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = rdev->pm.dpm.priv;
+
+	return pi;
+}
+
+static void sumo_gfx_clockgating_enable(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
+	else {
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
+		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
+		RREG32(GB_ADDR_CONFIG);
+	}
+}
+
+#define CGCG_CGTT_LOCAL0_MASK 0xE5BFFFFF
+#define CGCG_CGTT_LOCAL1_MASK 0xEFFF07FF
+
+static void sumo_mg_clockgating_enable(struct radeon_device *rdev, bool enable)
+{
+	u32 local0;
+	u32 local1;
+
+	local0 = RREG32(CG_CGTT_LOCAL_0);
+	local1 = RREG32(CG_CGTT_LOCAL_1);
+
+	if (enable) {
+		WREG32(CG_CGTT_LOCAL_0, (0 & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
+		WREG32(CG_CGTT_LOCAL_1, (0 & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
+	} else {
+		WREG32(CG_CGTT_LOCAL_0, (0xFFFFFFFF & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
+		WREG32(CG_CGTT_LOCAL_1, (0xFFFFCFFF & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
+	}
+}
+
+static void sumo_program_git(struct radeon_device *rdev)
+{
+	u32 p, u;
+	u32 xclk = radeon_get_xclk(rdev);
+
+	r600_calculate_u_and_p(SUMO_GICST_DFLT,
+			       xclk, 16, &p, &u);
+
+	WREG32_P(CG_GIT, CG_GICST(p), ~CG_GICST_MASK);
+}
+
+static void sumo_program_grsd(struct radeon_device *rdev)
+{
+	u32 p, u;
+	u32 xclk = radeon_get_xclk(rdev);
+	u32 grs = 256 * 25 / 100;
+
+	r600_calculate_u_and_p(1, xclk, 14, &p, &u);
+
+	WREG32(CG_GCOOR, PHC(grs) | SDC(p) | SU(u));
+}
+
+void sumo_gfx_clockgating_initialize(struct radeon_device *rdev)
+{
+	sumo_program_git(rdev);
+	sumo_program_grsd(rdev);
+}
+
+static void sumo_gfx_powergating_initialize(struct radeon_device *rdev)
+{
+	u32 rcu_pwr_gating_cntl;
+	u32 p, u;
+	u32 p_c, p_p, d_p;
+	u32 r_t, i_t;
+	u32 xclk = radeon_get_xclk(rdev);
+
+	if (rdev->family == CHIP_PALM) {
+		p_c = 4;
+		d_p = 10;
+		r_t = 10;
+		i_t = 4;
+		p_p = 50 + 1000/200 + 6 * 32;
+	} else {
+		p_c = 16;
+		d_p = 50;
+		r_t = 50;
+		i_t  = 50;
+		p_p = 113;
+	}
+
+	WREG32(CG_SCRATCH2, 0x01B60A17);
+
+	r600_calculate_u_and_p(SUMO_GFXPOWERGATINGT_DFLT,
+			       xclk, 16, &p, &u);
+
+	WREG32_P(CG_PWR_GATING_CNTL, PGP(p) | PGU(u),
+		 ~(PGP_MASK | PGU_MASK));
+
+	r600_calculate_u_and_p(SUMO_VOLTAGEDROPT_DFLT,
+			       xclk, 16, &p, &u);
+
+	WREG32_P(CG_CG_VOLTAGE_CNTL, PGP(p) | PGU(u),
+		 ~(PGP_MASK | PGU_MASK));
+
+	if (rdev->family == CHIP_PALM) {
+		WREG32_RCU(RCU_PWR_GATING_SEQ0, 0x10103210);
+		WREG32_RCU(RCU_PWR_GATING_SEQ1, 0x10101010);
+	} else {
+		WREG32_RCU(RCU_PWR_GATING_SEQ0, 0x76543210);
+		WREG32_RCU(RCU_PWR_GATING_SEQ1, 0xFEDCBA98);
+	}
+
+	rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL);
+	rcu_pwr_gating_cntl &=
+		~(RSVD_MASK | PCV_MASK | PGS_MASK);
+	rcu_pwr_gating_cntl |= PCV(p_c) | PGS(1) | PWR_GATING_EN;
+	if (rdev->family == CHIP_PALM) {
+		rcu_pwr_gating_cntl &= ~PCP_MASK;
+		rcu_pwr_gating_cntl |= PCP(0x77);
+	}
+	WREG32_RCU(RCU_PWR_GATING_CNTL, rcu_pwr_gating_cntl);
+
+	rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_2);
+	rcu_pwr_gating_cntl &= ~(MPPU_MASK | MPPD_MASK);
+	rcu_pwr_gating_cntl |= MPPU(p_p) | MPPD(50);
+	WREG32_RCU(RCU_PWR_GATING_CNTL_2, rcu_pwr_gating_cntl);
+
+	rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_3);
+	rcu_pwr_gating_cntl &= ~(DPPU_MASK | DPPD_MASK);
+	rcu_pwr_gating_cntl |= DPPU(d_p) | DPPD(50);
+	WREG32_RCU(RCU_PWR_GATING_CNTL_3, rcu_pwr_gating_cntl);
+
+	rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_4);
+	rcu_pwr_gating_cntl &= ~(RT_MASK | IT_MASK);
+	rcu_pwr_gating_cntl |= RT(r_t) | IT(i_t);
+	WREG32_RCU(RCU_PWR_GATING_CNTL_4, rcu_pwr_gating_cntl);
+
+	if (rdev->family == CHIP_PALM)
+		WREG32_RCU(RCU_PWR_GATING_CNTL_5, 0xA02);
+
+	sumo_smu_pg_init(rdev);
+
+	rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL);
+	rcu_pwr_gating_cntl &=
+		~(RSVD_MASK | PCV_MASK | PGS_MASK);
+	rcu_pwr_gating_cntl |= PCV(p_c) | PGS(4) | PWR_GATING_EN;
+	if (rdev->family == CHIP_PALM) {
+		rcu_pwr_gating_cntl &= ~PCP_MASK;
+		rcu_pwr_gating_cntl |= PCP(0x77);
+	}
+	WREG32_RCU(RCU_PWR_GATING_CNTL, rcu_pwr_gating_cntl);
+
+	if (rdev->family == CHIP_PALM) {
+		rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_2);
+		rcu_pwr_gating_cntl &= ~(MPPU_MASK | MPPD_MASK);
+		rcu_pwr_gating_cntl |= MPPU(113) | MPPD(50);
+		WREG32_RCU(RCU_PWR_GATING_CNTL_2, rcu_pwr_gating_cntl);
+
+		rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_3);
+		rcu_pwr_gating_cntl &= ~(DPPU_MASK | DPPD_MASK);
+		rcu_pwr_gating_cntl |= DPPU(16) | DPPD(50);
+		WREG32_RCU(RCU_PWR_GATING_CNTL_3, rcu_pwr_gating_cntl);
+	}
+
+	sumo_smu_pg_init(rdev);
+
+	rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL);
+	rcu_pwr_gating_cntl &=
+		~(RSVD_MASK | PCV_MASK | PGS_MASK);
+	rcu_pwr_gating_cntl |= PGS(5) | PWR_GATING_EN;
+
+	if (rdev->family == CHIP_PALM) {
+		rcu_pwr_gating_cntl |= PCV(4);
+		rcu_pwr_gating_cntl &= ~PCP_MASK;
+		rcu_pwr_gating_cntl |= PCP(0x77);
+	} else
+		rcu_pwr_gating_cntl |= PCV(11);
+	WREG32_RCU(RCU_PWR_GATING_CNTL, rcu_pwr_gating_cntl);
+
+	if (rdev->family == CHIP_PALM) {
+		rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_2);
+		rcu_pwr_gating_cntl &= ~(MPPU_MASK | MPPD_MASK);
+		rcu_pwr_gating_cntl |= MPPU(113) | MPPD(50);
+		WREG32_RCU(RCU_PWR_GATING_CNTL_2, rcu_pwr_gating_cntl);
+
+		rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_3);
+		rcu_pwr_gating_cntl &= ~(DPPU_MASK | DPPD_MASK);
+		rcu_pwr_gating_cntl |= DPPU(22) | DPPD(50);
+		WREG32_RCU(RCU_PWR_GATING_CNTL_3, rcu_pwr_gating_cntl);
+	}
+
+	sumo_smu_pg_init(rdev);
+}
+
+static void sumo_gfx_powergating_enable(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(CG_PWR_GATING_CNTL, DYN_PWR_DOWN_EN, ~DYN_PWR_DOWN_EN);
+	else {
+		WREG32_P(CG_PWR_GATING_CNTL, 0, ~DYN_PWR_DOWN_EN);
+		RREG32(GB_ADDR_CONFIG);
+	}
+}
+
+static int sumo_enable_clock_power_gating(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	if (pi->enable_gfx_clock_gating)
+		sumo_gfx_clockgating_initialize(rdev);
+	if (pi->enable_gfx_power_gating)
+		sumo_gfx_powergating_initialize(rdev);
+	if (pi->enable_mg_clock_gating)
+		sumo_mg_clockgating_enable(rdev, true);
+	if (pi->enable_gfx_clock_gating)
+		sumo_gfx_clockgating_enable(rdev, true);
+	if (pi->enable_gfx_power_gating)
+		sumo_gfx_powergating_enable(rdev, true);
+
+	return 0;
+}
+
+static void sumo_disable_clock_power_gating(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	if (pi->enable_gfx_clock_gating)
+		sumo_gfx_clockgating_enable(rdev, false);
+	if (pi->enable_gfx_power_gating)
+		sumo_gfx_powergating_enable(rdev, false);
+	if (pi->enable_mg_clock_gating)
+		sumo_mg_clockgating_enable(rdev, false);
+}
+
+static void sumo_calculate_bsp(struct radeon_device *rdev,
+			       u32 high_clk)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 xclk = radeon_get_xclk(rdev);
+
+	pi->pasi = 65535 * 100 / high_clk;
+	pi->asi = 65535 * 100 / high_clk;
+
+	r600_calculate_u_and_p(pi->asi,
+			       xclk, 16, &pi->bsp, &pi->bsu);
+
+	r600_calculate_u_and_p(pi->pasi,
+			       xclk, 16, &pi->pbsp, &pi->pbsu);
+
+	pi->dsp = BSP(pi->bsp) | BSU(pi->bsu);
+	pi->psp = BSP(pi->pbsp) | BSU(pi->pbsu);
+}
+
+static void sumo_init_bsp(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	WREG32(CG_BSP_0, pi->psp);
+}
+
+
+static void sumo_program_bsp(struct radeon_device *rdev,
+			     struct radeon_ps *rps)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct sumo_ps *ps = sumo_get_ps(rps);
+	u32 i;
+	u32 highest_engine_clock = ps->levels[ps->num_levels - 1].sclk;
+
+	if (ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
+		highest_engine_clock = pi->boost_pl.sclk;
+
+	sumo_calculate_bsp(rdev, highest_engine_clock);
+
+	for (i = 0; i < ps->num_levels - 1; i++)
+		WREG32(CG_BSP_0 + (i * 4), pi->dsp);
+
+	WREG32(CG_BSP_0 + (i * 4), pi->psp);
+
+	if (ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
+		WREG32(CG_BSP_0 + (BOOST_DPM_LEVEL * 4), pi->psp);
+}
+
+static void sumo_write_at(struct radeon_device *rdev,
+			  u32 index, u32 value)
+{
+	if (index == 0)
+		WREG32(CG_AT_0, value);
+	else if (index == 1)
+		WREG32(CG_AT_1, value);
+	else if (index == 2)
+		WREG32(CG_AT_2, value);
+	else if (index == 3)
+		WREG32(CG_AT_3, value);
+	else if (index == 4)
+		WREG32(CG_AT_4, value);
+	else if (index == 5)
+		WREG32(CG_AT_5, value);
+	else if (index == 6)
+		WREG32(CG_AT_6, value);
+	else if (index == 7)
+		WREG32(CG_AT_7, value);
+}
+
+static void sumo_program_at(struct radeon_device *rdev,
+			    struct radeon_ps *rps)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct sumo_ps *ps = sumo_get_ps(rps);
+	u32 asi;
+	u32 i;
+	u32 m_a;
+	u32 a_t;
+	u32 r[SUMO_MAX_HARDWARE_POWERLEVELS];
+	u32 l[SUMO_MAX_HARDWARE_POWERLEVELS];
+
+	r[0] = SUMO_R_DFLT0;
+	r[1] = SUMO_R_DFLT1;
+	r[2] = SUMO_R_DFLT2;
+	r[3] = SUMO_R_DFLT3;
+	r[4] = SUMO_R_DFLT4;
+
+	l[0] = SUMO_L_DFLT0;
+	l[1] = SUMO_L_DFLT1;
+	l[2] = SUMO_L_DFLT2;
+	l[3] = SUMO_L_DFLT3;
+	l[4] = SUMO_L_DFLT4;
+
+	for (i = 0; i < ps->num_levels; i++) {
+		asi = (i == ps->num_levels - 1) ? pi->pasi : pi->asi;
+
+		m_a = asi * ps->levels[i].sclk / 100;
+
+		a_t = CG_R(m_a * r[i] / 100) | CG_L(m_a * l[i] / 100);
+
+		sumo_write_at(rdev, i, a_t);
+	}
+
+	if (ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE) {
+		asi = pi->pasi;
+
+		m_a = asi * pi->boost_pl.sclk / 100;
+
+		a_t = CG_R(m_a * r[ps->num_levels - 1] / 100) |
+			CG_L(m_a * l[ps->num_levels - 1] / 100);
+
+		sumo_write_at(rdev, BOOST_DPM_LEVEL, a_t);
+	}
+}
+
+static void sumo_program_tp(struct radeon_device *rdev)
+{
+	int i;
+	enum r600_td td = R600_TD_DFLT;
+
+	for (i = 0; i < SUMO_PM_NUMBER_OF_TC; i++) {
+		WREG32_P(CG_FFCT_0 + (i * 4), UTC_0(sumo_utc[i]), ~UTC_0_MASK);
+		WREG32_P(CG_FFCT_0 + (i * 4), DTC_0(sumo_dtc[i]), ~DTC_0_MASK);
+	}
+
+	if (td == R600_TD_AUTO)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
+	else
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
+
+	if (td == R600_TD_UP)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
+
+	if (td == R600_TD_DOWN)
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
+}
+
+void sumo_program_vc(struct radeon_device *rdev, u32 vrc)
+{
+	WREG32(CG_FTV, vrc);
+}
+
+void sumo_clear_vc(struct radeon_device *rdev)
+{
+	WREG32(CG_FTV, 0);
+}
+
+void sumo_program_sstp(struct radeon_device *rdev)
+{
+	u32 p, u;
+	u32 xclk = radeon_get_xclk(rdev);
+
+	r600_calculate_u_and_p(SUMO_SST_DFLT,
+			       xclk, 16, &p, &u);
+
+	WREG32(CG_SSP, SSTU(u) | SST(p));
+}
+
+static void sumo_set_divider_value(struct radeon_device *rdev,
+				   u32 index, u32 divider)
+{
+	u32 reg_index = index / 4;
+	u32 field_index = index % 4;
+
+	if (field_index == 0)
+		WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
+			 SCLK_FSTATE_0_DIV(divider), ~SCLK_FSTATE_0_DIV_MASK);
+	else if (field_index == 1)
+		WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
+			 SCLK_FSTATE_1_DIV(divider), ~SCLK_FSTATE_1_DIV_MASK);
+	else if (field_index == 2)
+		WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
+			 SCLK_FSTATE_2_DIV(divider), ~SCLK_FSTATE_2_DIV_MASK);
+	else if (field_index == 3)
+		WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
+			 SCLK_FSTATE_3_DIV(divider), ~SCLK_FSTATE_3_DIV_MASK);
+}
+
+static void sumo_set_ds_dividers(struct radeon_device *rdev,
+				 u32 index, u32 divider)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	if (pi->enable_sclk_ds) {
+		u32 dpm_ctrl = RREG32(CG_SCLK_DPM_CTRL_6);
+
+		dpm_ctrl &= ~(0x7 << (index * 3));
+		dpm_ctrl |= (divider << (index * 3));
+		WREG32(CG_SCLK_DPM_CTRL_6, dpm_ctrl);
+	}
+}
+
+static void sumo_set_ss_dividers(struct radeon_device *rdev,
+				 u32 index, u32 divider)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	if (pi->enable_sclk_ds) {
+		u32 dpm_ctrl = RREG32(CG_SCLK_DPM_CTRL_11);
+
+		dpm_ctrl &= ~(0x7 << (index * 3));
+		dpm_ctrl |= (divider << (index * 3));
+		WREG32(CG_SCLK_DPM_CTRL_11, dpm_ctrl);
+	}
+}
+
+static void sumo_set_vid(struct radeon_device *rdev, u32 index, u32 vid)
+{
+	u32 voltage_cntl = RREG32(CG_DPM_VOLTAGE_CNTL);
+
+	voltage_cntl &= ~(DPM_STATE0_LEVEL_MASK << (index * 2));
+	voltage_cntl |= (vid << (DPM_STATE0_LEVEL_SHIFT + index * 2));
+	WREG32(CG_DPM_VOLTAGE_CNTL, voltage_cntl);
+}
+
+static void sumo_set_allos_gnb_slow(struct radeon_device *rdev, u32 index, u32 gnb_slow)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 temp = gnb_slow;
+	u32 cg_sclk_dpm_ctrl_3;
+
+	if (pi->driver_nbps_policy_disable)
+		temp = 1;
+
+	cg_sclk_dpm_ctrl_3 = RREG32(CG_SCLK_DPM_CTRL_3);
+	cg_sclk_dpm_ctrl_3 &= ~(GNB_SLOW_FSTATE_0_MASK << index);
+	cg_sclk_dpm_ctrl_3 |= (temp << (GNB_SLOW_FSTATE_0_SHIFT + index));
+
+	WREG32(CG_SCLK_DPM_CTRL_3, cg_sclk_dpm_ctrl_3);
+}
+
+static void sumo_program_power_level(struct radeon_device *rdev,
+				     struct sumo_pl *pl, u32 index)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	int ret;
+	struct atom_clock_dividers dividers;
+	u32 ds_en = RREG32(DEEP_SLEEP_CNTL) & ENABLE_DS;
+
+	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+					     pl->sclk, false, &dividers);
+	if (ret)
+		return;
+
+	sumo_set_divider_value(rdev, index, dividers.post_div);
+
+	sumo_set_vid(rdev, index, pl->vddc_index);
+
+	if (pl->ss_divider_index == 0 || pl->ds_divider_index == 0) {
+		if (ds_en)
+			WREG32_P(DEEP_SLEEP_CNTL, 0, ~ENABLE_DS);
+	} else {
+		sumo_set_ss_dividers(rdev, index, pl->ss_divider_index);
+		sumo_set_ds_dividers(rdev, index, pl->ds_divider_index);
+
+		if (!ds_en)
+			WREG32_P(DEEP_SLEEP_CNTL, ENABLE_DS, ~ENABLE_DS);
+	}
+
+	sumo_set_allos_gnb_slow(rdev, index, pl->allow_gnb_slow);
+
+	if (pi->enable_boost)
+		sumo_set_tdp_limit(rdev, index, pl->sclk_dpm_tdp_limit);
+}
+
+static void sumo_power_level_enable(struct radeon_device *rdev, u32 index, bool enable)
+{
+	u32 reg_index = index / 4;
+	u32 field_index = index % 4;
+
+	if (field_index == 0)
+		WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
+			 enable ? SCLK_FSTATE_0_VLD : 0, ~SCLK_FSTATE_0_VLD);
+	else if (field_index == 1)
+		WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
+			 enable ? SCLK_FSTATE_1_VLD : 0, ~SCLK_FSTATE_1_VLD);
+	else if (field_index == 2)
+		WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
+			 enable ? SCLK_FSTATE_2_VLD : 0, ~SCLK_FSTATE_2_VLD);
+	else if (field_index == 3)
+		WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
+			 enable ? SCLK_FSTATE_3_VLD : 0, ~SCLK_FSTATE_3_VLD);
+}
+
+static bool sumo_dpm_enabled(struct radeon_device *rdev)
+{
+	if (RREG32(CG_SCLK_DPM_CTRL_3) & DPM_SCLK_ENABLE)
+		return true;
+	else
+		return false;
+}
+
+static void sumo_start_dpm(struct radeon_device *rdev)
+{
+	WREG32_P(CG_SCLK_DPM_CTRL_3, DPM_SCLK_ENABLE, ~DPM_SCLK_ENABLE);
+}
+
+static void sumo_stop_dpm(struct radeon_device *rdev)
+{
+	WREG32_P(CG_SCLK_DPM_CTRL_3, 0, ~DPM_SCLK_ENABLE);
+}
+
+static void sumo_set_forced_mode(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(CG_SCLK_DPM_CTRL_3, FORCE_SCLK_STATE_EN, ~FORCE_SCLK_STATE_EN);
+	else
+		WREG32_P(CG_SCLK_DPM_CTRL_3, 0, ~FORCE_SCLK_STATE_EN);
+}
+
+static void sumo_set_forced_mode_enabled(struct radeon_device *rdev)
+{
+	int i;
+
+	sumo_set_forced_mode(rdev, true);
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(CG_SCLK_STATUS) & SCLK_OVERCLK_DETECT)
+			break;
+		udelay(1);
+	}
+}
+
+static void sumo_wait_for_level_0(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_SCLK_INDEX_MASK) == 0)
+			break;
+		udelay(1);
+	}
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_INDEX_MASK) == 0)
+			break;
+		udelay(1);
+	}
+}
+
+static void sumo_set_forced_mode_disabled(struct radeon_device *rdev)
+{
+	sumo_set_forced_mode(rdev, false);
+}
+
+static void sumo_enable_power_level_0(struct radeon_device *rdev)
+{
+	sumo_power_level_enable(rdev, 0, true);
+}
+
+static void sumo_patch_boost_state(struct radeon_device *rdev,
+				   struct radeon_ps *rps)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct sumo_ps *new_ps = sumo_get_ps(rps);
+
+	if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE) {
+		pi->boost_pl = new_ps->levels[new_ps->num_levels - 1];
+		pi->boost_pl.sclk = pi->sys_info.boost_sclk;
+		pi->boost_pl.vddc_index = pi->sys_info.boost_vid_2bit;
+		pi->boost_pl.sclk_dpm_tdp_limit = pi->sys_info.sclk_dpm_tdp_limit_boost;
+	}
+}
+
+static void sumo_pre_notify_alt_vddnb_change(struct radeon_device *rdev,
+					     struct radeon_ps *new_rps,
+					     struct radeon_ps *old_rps)
+{
+	struct sumo_ps *new_ps = sumo_get_ps(new_rps);
+	struct sumo_ps *old_ps = sumo_get_ps(old_rps);
+	u32 nbps1_old = 0;
+	u32 nbps1_new = 0;
+
+	if (old_ps != NULL)
+		nbps1_old = (old_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE) ? 1 : 0;
+
+	nbps1_new = (new_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE) ? 1 : 0;
+
+	if (nbps1_old == 1 && nbps1_new == 0)
+		sumo_smu_notify_alt_vddnb_change(rdev, 0, 0);
+}
+
+static void sumo_post_notify_alt_vddnb_change(struct radeon_device *rdev,
+					      struct radeon_ps *new_rps,
+					      struct radeon_ps *old_rps)
+{
+	struct sumo_ps *new_ps = sumo_get_ps(new_rps);
+	struct sumo_ps *old_ps = sumo_get_ps(old_rps);
+	u32 nbps1_old = 0;
+	u32 nbps1_new = 0;
+
+	if (old_ps != NULL)
+		nbps1_old = (old_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE)? 1 : 0;
+
+	nbps1_new = (new_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE)? 1 : 0;
+
+	if (nbps1_old == 0 && nbps1_new == 1)
+		sumo_smu_notify_alt_vddnb_change(rdev, 1, 1);
+}
+
+static void sumo_enable_boost(struct radeon_device *rdev,
+			      struct radeon_ps *rps,
+			      bool enable)
+{
+	struct sumo_ps *new_ps = sumo_get_ps(rps);
+
+	if (enable) {
+		if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
+			sumo_boost_state_enable(rdev, true);
+	} else
+		sumo_boost_state_enable(rdev, false);
+}
+
+static void sumo_set_forced_level(struct radeon_device *rdev, u32 index)
+{
+	WREG32_P(CG_SCLK_DPM_CTRL_3, FORCE_SCLK_STATE(index), ~FORCE_SCLK_STATE_MASK);
+}
+
+static void sumo_set_forced_level_0(struct radeon_device *rdev)
+{
+	sumo_set_forced_level(rdev, 0);
+}
+
+static void sumo_program_wl(struct radeon_device *rdev,
+			    struct radeon_ps *rps)
+{
+	struct sumo_ps *new_ps = sumo_get_ps(rps);
+	u32 dpm_ctrl4 = RREG32(CG_SCLK_DPM_CTRL_4);
+
+	dpm_ctrl4 &= 0xFFFFFF00;
+	dpm_ctrl4 |= (1 << (new_ps->num_levels - 1));
+
+	if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
+		dpm_ctrl4 |= (1 << BOOST_DPM_LEVEL);
+
+	WREG32(CG_SCLK_DPM_CTRL_4, dpm_ctrl4);
+}
+
+static void sumo_program_power_levels_0_to_n(struct radeon_device *rdev,
+					     struct radeon_ps *new_rps,
+					     struct radeon_ps *old_rps)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct sumo_ps *new_ps = sumo_get_ps(new_rps);
+	struct sumo_ps *old_ps = sumo_get_ps(old_rps);
+	u32 i;
+	u32 n_current_state_levels = (old_ps == NULL) ? 1 : old_ps->num_levels;
+
+	for (i = 0; i < new_ps->num_levels; i++) {
+		sumo_program_power_level(rdev, &new_ps->levels[i], i);
+		sumo_power_level_enable(rdev, i, true);
+	}
+
+	for (i = new_ps->num_levels; i < n_current_state_levels; i++)
+		sumo_power_level_enable(rdev, i, false);
+
+	if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
+		sumo_program_power_level(rdev, &pi->boost_pl, BOOST_DPM_LEVEL);
+}
+
+static void sumo_enable_acpi_pm(struct radeon_device *rdev)
+{
+	WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
+}
+
+static void sumo_program_power_level_enter_state(struct radeon_device *rdev)
+{
+	WREG32_P(CG_SCLK_DPM_CTRL_5, SCLK_FSTATE_BOOTUP(0), ~SCLK_FSTATE_BOOTUP_MASK);
+}
+
+static void sumo_program_acpi_power_level(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct atom_clock_dividers dividers;
+	int ret;
+
+        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+                                             pi->acpi_pl.sclk,
+					     false, &dividers);
+	if (ret)
+		return;
+
+	WREG32_P(CG_ACPI_CNTL, SCLK_ACPI_DIV(dividers.post_div), ~SCLK_ACPI_DIV_MASK);
+	WREG32_P(CG_ACPI_VOLTAGE_CNTL, 0, ~ACPI_VOLTAGE_EN);
+}
+
+static void sumo_program_bootup_state(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 dpm_ctrl4 = RREG32(CG_SCLK_DPM_CTRL_4);
+	u32 i;
+
+	sumo_program_power_level(rdev, &pi->boot_pl, 0);
+
+	dpm_ctrl4 &= 0xFFFFFF00;
+	WREG32(CG_SCLK_DPM_CTRL_4, dpm_ctrl4);
+
+	for (i = 1; i < 8; i++)
+		sumo_power_level_enable(rdev, i, false);
+}
+
+static void sumo_setup_uvd_clocks(struct radeon_device *rdev,
+				  struct radeon_ps *new_rps,
+				  struct radeon_ps *old_rps)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	if (pi->enable_gfx_power_gating) {
+		sumo_gfx_powergating_enable(rdev, false);
+	}
+
+	radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
+
+	if (pi->enable_gfx_power_gating) {
+		if (!pi->disable_gfx_power_gating_in_uvd ||
+		    !r600_is_uvd_state(new_rps->class, new_rps->class2))
+			sumo_gfx_powergating_enable(rdev, true);
+	}
+}
+
+static void sumo_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
+						    struct radeon_ps *new_rps,
+						    struct radeon_ps *old_rps)
+{
+	struct sumo_ps *new_ps = sumo_get_ps(new_rps);
+	struct sumo_ps *current_ps = sumo_get_ps(old_rps);
+
+	if ((new_rps->vclk == old_rps->vclk) &&
+	    (new_rps->dclk == old_rps->dclk))
+		return;
+
+	if (new_ps->levels[new_ps->num_levels - 1].sclk >=
+	    current_ps->levels[current_ps->num_levels - 1].sclk)
+		return;
+
+	sumo_setup_uvd_clocks(rdev, new_rps, old_rps);
+}
+
+static void sumo_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
+						   struct radeon_ps *new_rps,
+						   struct radeon_ps *old_rps)
+{
+	struct sumo_ps *new_ps = sumo_get_ps(new_rps);
+	struct sumo_ps *current_ps = sumo_get_ps(old_rps);
+
+	if ((new_rps->vclk == old_rps->vclk) &&
+	    (new_rps->dclk == old_rps->dclk))
+		return;
+
+	if (new_ps->levels[new_ps->num_levels - 1].sclk <
+	    current_ps->levels[current_ps->num_levels - 1].sclk)
+		return;
+
+	sumo_setup_uvd_clocks(rdev, new_rps, old_rps);
+}
+
+void sumo_take_smu_control(struct radeon_device *rdev, bool enable)
+{
+/* This bit selects who handles display phy powergating.
+ * Clear the bit to let atom handle it.
+ * Set it to let the driver handle it.
+ * For now we just let atom handle it.
+ */
+#if 0
+	u32 v = RREG32(DOUT_SCRATCH3);
+
+	if (enable)
+		v |= 0x4;
+	else
+		v &= 0xFFFFFFFB;
+
+	WREG32(DOUT_SCRATCH3, v);
+#endif
+}
+
+static void sumo_enable_sclk_ds(struct radeon_device *rdev, bool enable)
+{
+	if (enable) {
+		u32 deep_sleep_cntl = RREG32(DEEP_SLEEP_CNTL);
+		u32 deep_sleep_cntl2 = RREG32(DEEP_SLEEP_CNTL2);
+		u32 t = 1;
+
+		deep_sleep_cntl &= ~R_DIS;
+		deep_sleep_cntl &= ~HS_MASK;
+		deep_sleep_cntl |= HS(t > 4095 ? 4095 : t);
+
+		deep_sleep_cntl2 |= LB_UFP_EN;
+		deep_sleep_cntl2 &= INOUT_C_MASK;
+		deep_sleep_cntl2 |= INOUT_C(0xf);
+
+		WREG32(DEEP_SLEEP_CNTL2, deep_sleep_cntl2);
+		WREG32(DEEP_SLEEP_CNTL, deep_sleep_cntl);
+	} else
+		WREG32_P(DEEP_SLEEP_CNTL, 0, ~ENABLE_DS);
+}
+
+static void sumo_program_bootup_at(struct radeon_device *rdev)
+{
+	WREG32_P(CG_AT_0, CG_R(0xffff), ~CG_R_MASK);
+	WREG32_P(CG_AT_0, CG_L(0), ~CG_L_MASK);
+}
+
+static void sumo_reset_am(struct radeon_device *rdev)
+{
+	WREG32_P(SCLK_PWRMGT_CNTL, FIR_RESET, ~FIR_RESET);
+}
+
+static void sumo_start_am(struct radeon_device *rdev)
+{
+	WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_RESET);
+}
+
+static void sumo_program_ttp(struct radeon_device *rdev)
+{
+	u32 xclk = radeon_get_xclk(rdev);
+	u32 p, u;
+	u32 cg_sclk_dpm_ctrl_5 = RREG32(CG_SCLK_DPM_CTRL_5);
+
+	r600_calculate_u_and_p(1000,
+			       xclk, 16, &p, &u);
+
+	cg_sclk_dpm_ctrl_5 &= ~(TT_TP_MASK | TT_TU_MASK);
+	cg_sclk_dpm_ctrl_5 |= TT_TP(p) | TT_TU(u);
+
+	WREG32(CG_SCLK_DPM_CTRL_5, cg_sclk_dpm_ctrl_5);
+}
+
+static void sumo_program_ttt(struct radeon_device *rdev)
+{
+	u32 cg_sclk_dpm_ctrl_3 = RREG32(CG_SCLK_DPM_CTRL_3);
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	cg_sclk_dpm_ctrl_3 &= ~(GNB_TT_MASK | GNB_THERMTHRO_MASK);
+	cg_sclk_dpm_ctrl_3 |= GNB_TT(pi->thermal_auto_throttling + 49);
+
+	WREG32(CG_SCLK_DPM_CTRL_3, cg_sclk_dpm_ctrl_3);
+}
+
+
+static void sumo_enable_voltage_scaling(struct radeon_device *rdev, bool enable)
+{
+	if (enable) {
+		WREG32_P(CG_DPM_VOLTAGE_CNTL, DPM_VOLTAGE_EN, ~DPM_VOLTAGE_EN);
+		WREG32_P(CG_CG_VOLTAGE_CNTL, 0, ~CG_VOLTAGE_EN);
+	} else {
+		WREG32_P(CG_CG_VOLTAGE_CNTL, CG_VOLTAGE_EN, ~CG_VOLTAGE_EN);
+		WREG32_P(CG_DPM_VOLTAGE_CNTL, 0, ~DPM_VOLTAGE_EN);
+	}
+}
+
+static void sumo_override_cnb_thermal_events(struct radeon_device *rdev)
+{
+	WREG32_P(CG_SCLK_DPM_CTRL_3, CNB_THERMTHRO_MASK_SCLK,
+		 ~CNB_THERMTHRO_MASK_SCLK);
+}
+
+static void sumo_program_dc_hto(struct radeon_device *rdev)
+{
+	u32 cg_sclk_dpm_ctrl_4 = RREG32(CG_SCLK_DPM_CTRL_4);
+	u32 p, u;
+	u32 xclk = radeon_get_xclk(rdev);
+
+	r600_calculate_u_and_p(100000,
+			       xclk, 14, &p, &u);
+
+	cg_sclk_dpm_ctrl_4 &= ~(DC_HDC_MASK | DC_HU_MASK);
+	cg_sclk_dpm_ctrl_4 |= DC_HDC(p) | DC_HU(u);
+
+	WREG32(CG_SCLK_DPM_CTRL_4, cg_sclk_dpm_ctrl_4);
+}
+
+static void sumo_force_nbp_state(struct radeon_device *rdev,
+				 struct radeon_ps *rps)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct sumo_ps *new_ps = sumo_get_ps(rps);
+
+	if (!pi->driver_nbps_policy_disable) {
+		if (new_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE)
+			WREG32_P(CG_SCLK_DPM_CTRL_3, FORCE_NB_PSTATE_1, ~FORCE_NB_PSTATE_1);
+		else
+			WREG32_P(CG_SCLK_DPM_CTRL_3, 0, ~FORCE_NB_PSTATE_1);
+	}
+}
+
+u32 sumo_get_sleep_divider_from_id(u32 id)
+{
+	return 1 << id;
+}
+
+u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
+					 u32 sclk,
+					 u32 min_sclk_in_sr)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 i;
+	u32 temp;
+	u32 min = (min_sclk_in_sr > SUMO_MINIMUM_ENGINE_CLOCK) ?
+		min_sclk_in_sr : SUMO_MINIMUM_ENGINE_CLOCK;
+
+	if (sclk < min)
+		return 0;
+
+	if (!pi->enable_sclk_ds)
+		return 0;
+
+	for (i = SUMO_MAX_DEEPSLEEP_DIVIDER_ID;  ; i--) {
+		temp = sclk / sumo_get_sleep_divider_from_id(i);
+
+		if (temp >= min || i == 0)
+			break;
+	}
+	return i;
+}
+
+static u32 sumo_get_valid_engine_clock(struct radeon_device *rdev,
+				       u32 lower_limit)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 i;
+
+	for (i = 0; i < pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries; i++) {
+		if (pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency >= lower_limit)
+			return pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency;
+	}
+
+	return pi->sys_info.sclk_voltage_mapping_table.entries[pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries - 1].sclk_frequency;
+}
+
+static void sumo_patch_thermal_state(struct radeon_device *rdev,
+				     struct sumo_ps *ps,
+				     struct sumo_ps *current_ps)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
+	u32 current_vddc;
+	u32 current_sclk;
+	u32 current_index = 0;
+
+	if (current_ps) {
+		current_vddc = current_ps->levels[current_index].vddc_index;
+		current_sclk = current_ps->levels[current_index].sclk;
+	} else {
+		current_vddc = pi->boot_pl.vddc_index;
+		current_sclk = pi->boot_pl.sclk;
+	}
+
+	ps->levels[0].vddc_index = current_vddc;
+
+	if (ps->levels[0].sclk > current_sclk)
+		ps->levels[0].sclk = current_sclk;
+
+	ps->levels[0].ss_divider_index =
+		sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, sclk_in_sr);
+
+	ps->levels[0].ds_divider_index =
+		sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, SUMO_MINIMUM_ENGINE_CLOCK);
+
+	if (ps->levels[0].ds_divider_index > ps->levels[0].ss_divider_index + 1)
+		ps->levels[0].ds_divider_index = ps->levels[0].ss_divider_index + 1;
+
+	if (ps->levels[0].ss_divider_index == ps->levels[0].ds_divider_index) {
+		if (ps->levels[0].ss_divider_index > 1)
+			ps->levels[0].ss_divider_index = ps->levels[0].ss_divider_index - 1;
+	}
+
+	if (ps->levels[0].ss_divider_index == 0)
+		ps->levels[0].ds_divider_index = 0;
+
+	if (ps->levels[0].ds_divider_index == 0)
+		ps->levels[0].ss_divider_index = 0;
+}
+
+static void sumo_apply_state_adjust_rules(struct radeon_device *rdev,
+					  struct radeon_ps *new_rps,
+					  struct radeon_ps *old_rps)
+{
+	struct sumo_ps *ps = sumo_get_ps(new_rps);
+	struct sumo_ps *current_ps = sumo_get_ps(old_rps);
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 min_voltage = 0; /* ??? */
+	u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */
+	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
+	u32 i;
+
+	if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
+		return sumo_patch_thermal_state(rdev, ps, current_ps);
+
+	if (pi->enable_boost) {
+		if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE)
+			ps->flags |= SUMO_POWERSTATE_FLAGS_BOOST_STATE;
+	}
+
+	if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) ||
+	    (new_rps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) ||
+	    (new_rps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE))
+		ps->flags |= SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE;
+
+	for (i = 0; i < ps->num_levels; i++) {
+		if (ps->levels[i].vddc_index < min_voltage)
+			ps->levels[i].vddc_index = min_voltage;
+
+		if (ps->levels[i].sclk < min_sclk)
+			ps->levels[i].sclk =
+				sumo_get_valid_engine_clock(rdev, min_sclk);
+
+		ps->levels[i].ss_divider_index =
+			sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr);
+
+		ps->levels[i].ds_divider_index =
+			sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, SUMO_MINIMUM_ENGINE_CLOCK);
+
+		if (ps->levels[i].ds_divider_index > ps->levels[i].ss_divider_index + 1)
+			ps->levels[i].ds_divider_index = ps->levels[i].ss_divider_index + 1;
+
+		if (ps->levels[i].ss_divider_index == ps->levels[i].ds_divider_index) {
+			if (ps->levels[i].ss_divider_index > 1)
+				ps->levels[i].ss_divider_index = ps->levels[i].ss_divider_index - 1;
+		}
+
+		if (ps->levels[i].ss_divider_index == 0)
+			ps->levels[i].ds_divider_index = 0;
+
+		if (ps->levels[i].ds_divider_index == 0)
+			ps->levels[i].ss_divider_index = 0;
+
+		if (ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE)
+			ps->levels[i].allow_gnb_slow = 1;
+		else if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE) ||
+			 (new_rps->class2 & ATOM_PPLIB_CLASSIFICATION2_MVC))
+			ps->levels[i].allow_gnb_slow = 0;
+		else if (i == ps->num_levels - 1)
+			ps->levels[i].allow_gnb_slow = 0;
+		else
+			ps->levels[i].allow_gnb_slow = 1;
+	}
+}
+
+static void sumo_cleanup_asic(struct radeon_device *rdev)
+{
+	sumo_take_smu_control(rdev, false);
+}
+
+static int sumo_set_thermal_temperature_range(struct radeon_device *rdev,
+					      int min_temp, int max_temp)
+{
+	int low_temp = 0 * 1000;
+	int high_temp = 255 * 1000;
+
+	if (low_temp < min_temp)
+		low_temp = min_temp;
+	if (high_temp > max_temp)
+		high_temp = max_temp;
+	if (high_temp < low_temp) {
+		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
+		return -EINVAL;
+	}
+
+	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(49 + (high_temp / 1000)), ~DIG_THERM_INTH_MASK);
+	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(49 + (low_temp / 1000)), ~DIG_THERM_INTL_MASK);
+
+	rdev->pm.dpm.thermal.min_temp = low_temp;
+	rdev->pm.dpm.thermal.max_temp = high_temp;
+
+	return 0;
+}
+
+static void sumo_update_current_ps(struct radeon_device *rdev,
+				   struct radeon_ps *rps)
+{
+	struct sumo_ps *new_ps = sumo_get_ps(rps);
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	pi->current_rps = *rps;
+	pi->current_ps = *new_ps;
+	pi->current_rps.ps_priv = &pi->current_ps;
+}
+
+static void sumo_update_requested_ps(struct radeon_device *rdev,
+				     struct radeon_ps *rps)
+{
+	struct sumo_ps *new_ps = sumo_get_ps(rps);
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	pi->requested_rps = *rps;
+	pi->requested_ps = *new_ps;
+	pi->requested_rps.ps_priv = &pi->requested_ps;
+}
+
+int sumo_dpm_enable(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	int ret;
+
+	if (sumo_dpm_enabled(rdev))
+		return -EINVAL;
+
+	ret = sumo_enable_clock_power_gating(rdev);
+	if (ret)
+		return ret;
+	sumo_program_bootup_state(rdev);
+	sumo_init_bsp(rdev);
+	sumo_reset_am(rdev);
+	sumo_program_tp(rdev);
+	sumo_program_bootup_at(rdev);
+	sumo_start_am(rdev);
+	if (pi->enable_auto_thermal_throttling) {
+		sumo_program_ttp(rdev);
+		sumo_program_ttt(rdev);
+	}
+	sumo_program_dc_hto(rdev);
+	sumo_program_power_level_enter_state(rdev);
+	sumo_enable_voltage_scaling(rdev, true);
+	sumo_program_sstp(rdev);
+	sumo_program_vc(rdev, SUMO_VRC_DFLT);
+	sumo_override_cnb_thermal_events(rdev);
+	sumo_start_dpm(rdev);
+	sumo_wait_for_level_0(rdev);
+	if (pi->enable_sclk_ds)
+		sumo_enable_sclk_ds(rdev, true);
+	if (pi->enable_boost)
+		sumo_enable_boost_timer(rdev);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		ret = sumo_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+		if (ret)
+			return ret;
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+	}
+
+	sumo_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
+	return 0;
+}
+
+void sumo_dpm_disable(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	if (!sumo_dpm_enabled(rdev))
+		return;
+	sumo_disable_clock_power_gating(rdev);
+	if (pi->enable_sclk_ds)
+		sumo_enable_sclk_ds(rdev, false);
+	sumo_clear_vc(rdev);
+	sumo_wait_for_level_0(rdev);
+	sumo_stop_dpm(rdev);
+	sumo_enable_voltage_scaling(rdev, false);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		rdev->irq.dpm_thermal = false;
+		radeon_irq_set(rdev);
+	}
+
+	sumo_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+}
+
+int sumo_dpm_pre_set_power_state(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
+	struct radeon_ps *new_ps = &requested_ps;
+
+	sumo_update_requested_ps(rdev, new_ps);
+
+	if (pi->enable_dynamic_patch_ps)
+		sumo_apply_state_adjust_rules(rdev,
+					      &pi->requested_rps,
+					      &pi->current_rps);
+
+	return 0;
+}
+
+int sumo_dpm_set_power_state(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct radeon_ps *new_ps = &pi->requested_rps;
+	struct radeon_ps *old_ps = &pi->current_rps;
+
+	if (pi->enable_dpm)
+		sumo_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+	if (pi->enable_boost) {
+		sumo_enable_boost(rdev, new_ps, false);
+		sumo_patch_boost_state(rdev, new_ps);
+	}
+	if (pi->enable_dpm) {
+		sumo_pre_notify_alt_vddnb_change(rdev, new_ps, old_ps);
+		sumo_enable_power_level_0(rdev);
+		sumo_set_forced_level_0(rdev);
+		sumo_set_forced_mode_enabled(rdev);
+		sumo_wait_for_level_0(rdev);
+		sumo_program_power_levels_0_to_n(rdev, new_ps, old_ps);
+		sumo_program_wl(rdev, new_ps);
+		sumo_program_bsp(rdev, new_ps);
+		sumo_program_at(rdev, new_ps);
+		sumo_force_nbp_state(rdev, new_ps);
+		sumo_set_forced_mode_disabled(rdev);
+		sumo_set_forced_mode_enabled(rdev);
+		sumo_set_forced_mode_disabled(rdev);
+		sumo_post_notify_alt_vddnb_change(rdev, new_ps, old_ps);
+	}
+	if (pi->enable_boost)
+		sumo_enable_boost(rdev, new_ps, true);
+	if (pi->enable_dpm)
+		sumo_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+
+	rdev->pm.dpm.forced_level = RADEON_DPM_FORCED_LEVEL_AUTO;
+
+	return 0;
+}
+
+void sumo_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct radeon_ps *new_ps = &pi->requested_rps;
+
+	sumo_update_current_ps(rdev, new_ps);
+}
+
+void sumo_dpm_reset_asic(struct radeon_device *rdev)
+{
+	sumo_program_bootup_state(rdev);
+	sumo_enable_power_level_0(rdev);
+	sumo_set_forced_level_0(rdev);
+	sumo_set_forced_mode_enabled(rdev);
+	sumo_wait_for_level_0(rdev);
+	sumo_set_forced_mode_disabled(rdev);
+	sumo_set_forced_mode_enabled(rdev);
+	sumo_set_forced_mode_disabled(rdev);
+}
+
+void sumo_dpm_setup_asic(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	sumo_initialize_m3_arb(rdev);
+	pi->fw_version = sumo_get_running_fw_version(rdev);
+	DRM_INFO("Found smc ucode version: 0x%08x\n", pi->fw_version);
+	sumo_program_acpi_power_level(rdev);
+	sumo_enable_acpi_pm(rdev);
+	sumo_take_smu_control(rdev, true);
+}
+
+void sumo_dpm_display_configuration_changed(struct radeon_device *rdev)
+{
+
+}
+
+union power_info {
+	struct _ATOM_POWERPLAY_INFO info;
+	struct _ATOM_POWERPLAY_INFO_V2 info_2;
+	struct _ATOM_POWERPLAY_INFO_V3 info_3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
+	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
+	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
+};
+
+union pplib_clock_info {
+	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
+	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
+	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
+	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
+};
+
+union pplib_power_state {
+	struct _ATOM_PPLIB_STATE v1;
+	struct _ATOM_PPLIB_STATE_V2 v2;
+};
+
+static void sumo_patch_boot_state(struct radeon_device *rdev,
+				  struct sumo_ps *ps)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	ps->num_levels = 1;
+	ps->flags = 0;
+	ps->levels[0] = pi->boot_pl;
+}
+
+static void sumo_parse_pplib_non_clock_info(struct radeon_device *rdev,
+					    struct radeon_ps *rps,
+					    struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
+					    u8 table_rev)
+{
+	struct sumo_ps *ps = sumo_get_ps(rps);
+
+	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
+	rps->class = le16_to_cpu(non_clock_info->usClassification);
+	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
+
+	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
+		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
+		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
+	} else {
+		rps->vclk = 0;
+		rps->dclk = 0;
+	}
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
+		rdev->pm.dpm.boot_ps = rps;
+		sumo_patch_boot_state(rdev, ps);
+	}
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		rdev->pm.dpm.uvd_ps = rps;
+}
+
+static void sumo_parse_pplib_clock_info(struct radeon_device *rdev,
+					struct radeon_ps *rps, int index,
+					union pplib_clock_info *clock_info)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct sumo_ps *ps = sumo_get_ps(rps);
+	struct sumo_pl *pl = &ps->levels[index];
+	u32 sclk;
+
+	sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
+	sclk |= clock_info->sumo.ucEngineClockHigh << 16;
+	pl->sclk = sclk;
+	pl->vddc_index = clock_info->sumo.vddcIndex;
+	pl->sclk_dpm_tdp_limit = clock_info->sumo.tdpLimit;
+
+	ps->num_levels = index + 1;
+
+	if (pi->enable_sclk_ds) {
+		pl->ds_divider_index = 5;
+		pl->ss_divider_index = 4;
+	}
+}
+
+static int sumo_parse_power_table(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
+	union pplib_power_state *power_state;
+	int i, j, k, non_clock_array_index, clock_array_index;
+	union pplib_clock_info *clock_info;
+	struct _StateArray *state_array;
+	struct _ClockInfoArray *clock_info_array;
+	struct _NonClockInfoArray *non_clock_info_array;
+	union power_info *power_info;
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+        u16 data_offset;
+	u8 frev, crev;
+	u8 *power_state_offset;
+	struct sumo_ps *ps;
+
+	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset))
+		return -EINVAL;
+	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+
+	state_array = (struct _StateArray *)
+		(mode_info->atom_context->bios + data_offset +
+		 le16_to_cpu(power_info->pplib.usStateArrayOffset));
+	clock_info_array = (struct _ClockInfoArray *)
+		(mode_info->atom_context->bios + data_offset +
+		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
+	non_clock_info_array = (struct _NonClockInfoArray *)
+		(mode_info->atom_context->bios + data_offset +
+		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
+
+	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
+				  state_array->ucNumEntries, GFP_KERNEL);
+	if (!rdev->pm.dpm.ps)
+		return -ENOMEM;
+	power_state_offset = (u8 *)state_array->states;
+	rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
+	rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
+	rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
+	for (i = 0; i < state_array->ucNumEntries; i++) {
+		power_state = (union pplib_power_state *)power_state_offset;
+		non_clock_array_index = power_state->v2.nonClockInfoIndex;
+		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
+			&non_clock_info_array->nonClockInfo[non_clock_array_index];
+		if (!rdev->pm.power_state[i].clock_info)
+			return -EINVAL;
+		ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL);
+		if (ps == NULL) {
+			kfree(rdev->pm.dpm.ps);
+			return -ENOMEM;
+		}
+		rdev->pm.dpm.ps[i].ps_priv = ps;
+		k = 0;
+		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
+			clock_array_index = power_state->v2.clockInfoIndex[j];
+			if (k >= SUMO_MAX_HARDWARE_POWERLEVELS)
+				break;
+			clock_info = (union pplib_clock_info *)
+				&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
+			sumo_parse_pplib_clock_info(rdev,
+						    &rdev->pm.dpm.ps[i], k,
+						    clock_info);
+			k++;
+		}
+		sumo_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
+						non_clock_info,
+						non_clock_info_array->ucEntrySize);
+		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
+	}
+	rdev->pm.dpm.num_ps = state_array->ucNumEntries;
+	return 0;
+}
+
+u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev,
+			      struct sumo_vid_mapping_table *vid_mapping_table,
+			      u32 vid_2bit)
+{
+	u32 i;
+
+	for (i = 0; i < vid_mapping_table->num_entries; i++) {
+		if (vid_mapping_table->entries[i].vid_2bit == vid_2bit)
+			return vid_mapping_table->entries[i].vid_7bit;
+	}
+
+	return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit;
+}
+
+static u16 sumo_convert_voltage_index_to_value(struct radeon_device *rdev,
+					       u32 vid_2bit)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid_2bit);
+
+	if (vid_7bit > 0x7C)
+		return 0;
+
+	return (15500 - vid_7bit * 125 + 5) / 10;
+}
+
+static void sumo_construct_display_voltage_mapping_table(struct radeon_device *rdev,
+							 struct sumo_disp_clock_voltage_mapping_table *disp_clk_voltage_mapping_table,
+							 ATOM_CLK_VOLT_CAPABILITY *table)
+{
+	u32 i;
+
+	for (i = 0; i < SUMO_MAX_NUMBER_VOLTAGES; i++) {
+		if (table[i].ulMaximumSupportedCLK == 0)
+			break;
+
+		disp_clk_voltage_mapping_table->display_clock_frequency[i] =
+			table[i].ulMaximumSupportedCLK;
+	}
+
+	disp_clk_voltage_mapping_table->num_max_voltage_levels = i;
+
+	if (disp_clk_voltage_mapping_table->num_max_voltage_levels == 0) {
+		disp_clk_voltage_mapping_table->display_clock_frequency[0] = 80000;
+		disp_clk_voltage_mapping_table->num_max_voltage_levels = 1;
+	}
+}
+
+void sumo_construct_sclk_voltage_mapping_table(struct radeon_device *rdev,
+					       struct sumo_sclk_voltage_mapping_table *sclk_voltage_mapping_table,
+					       ATOM_AVAILABLE_SCLK_LIST *table)
+{
+	u32 i;
+	u32 n = 0;
+	u32 prev_sclk = 0;
+
+	for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
+		if (table[i].ulSupportedSCLK > prev_sclk) {
+			sclk_voltage_mapping_table->entries[n].sclk_frequency =
+				table[i].ulSupportedSCLK;
+			sclk_voltage_mapping_table->entries[n].vid_2bit =
+				table[i].usVoltageIndex;
+			prev_sclk = table[i].ulSupportedSCLK;
+			n++;
+		}
+	}
+
+	sclk_voltage_mapping_table->num_max_dpm_entries = n;
+}
+
+void sumo_construct_vid_mapping_table(struct radeon_device *rdev,
+				      struct sumo_vid_mapping_table *vid_mapping_table,
+				      ATOM_AVAILABLE_SCLK_LIST *table)
+{
+	u32 i, j;
+
+	for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
+		if (table[i].ulSupportedSCLK != 0) {
+			vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
+				table[i].usVoltageID;
+			vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
+				table[i].usVoltageIndex;
+		}
+	}
+
+	for (i = 0; i < SUMO_MAX_NUMBER_VOLTAGES; i++) {
+		if (vid_mapping_table->entries[i].vid_7bit == 0) {
+			for (j = i + 1; j < SUMO_MAX_NUMBER_VOLTAGES; j++) {
+				if (vid_mapping_table->entries[j].vid_7bit != 0) {
+					vid_mapping_table->entries[i] =
+						vid_mapping_table->entries[j];
+					vid_mapping_table->entries[j].vid_7bit = 0;
+					break;
+				}
+			}
+
+			if (j == SUMO_MAX_NUMBER_VOLTAGES)
+				break;
+		}
+	}
+
+	vid_mapping_table->num_entries = i;
+}
+
+union igp_info {
+	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
+};
+
+static int sumo_parse_sys_info_table(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
+	union igp_info *igp_info;
+	u8 frev, crev;
+	u16 data_offset;
+	int i;
+
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		igp_info = (union igp_info *)(mode_info->atom_context->bios +
+					      data_offset);
+
+		if (crev != 6) {
+			DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
+			return -EINVAL;
+		}
+		pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_6.ulBootUpEngineClock);
+		pi->sys_info.min_sclk = le32_to_cpu(igp_info->info_6.ulMinEngineClock);
+		pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_6.ulBootUpUMAClock);
+		pi->sys_info.bootup_nb_voltage_index =
+			le16_to_cpu(igp_info->info_6.usBootUpNBVoltage);
+		if (igp_info->info_6.ucHtcTmpLmt == 0)
+			pi->sys_info.htc_tmp_lmt = 203;
+		else
+			pi->sys_info.htc_tmp_lmt = igp_info->info_6.ucHtcTmpLmt;
+		if (igp_info->info_6.ucHtcHystLmt == 0)
+			pi->sys_info.htc_hyst_lmt = 5;
+		else
+			pi->sys_info.htc_hyst_lmt = igp_info->info_6.ucHtcHystLmt;
+		if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) {
+			DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
+		}
+		for (i = 0; i < NUMBER_OF_M3ARB_PARAM_SETS; i++) {
+			pi->sys_info.csr_m3_arb_cntl_default[i] =
+				le32_to_cpu(igp_info->info_6.ulCSR_M3_ARB_CNTL_DEFAULT[i]);
+			pi->sys_info.csr_m3_arb_cntl_uvd[i] =
+				le32_to_cpu(igp_info->info_6.ulCSR_M3_ARB_CNTL_UVD[i]);
+			pi->sys_info.csr_m3_arb_cntl_fs3d[i] =
+				le32_to_cpu(igp_info->info_6.ulCSR_M3_ARB_CNTL_FS3D[i]);
+		}
+		pi->sys_info.sclk_dpm_boost_margin =
+			le32_to_cpu(igp_info->info_6.SclkDpmBoostMargin);
+		pi->sys_info.sclk_dpm_throttle_margin =
+			le32_to_cpu(igp_info->info_6.SclkDpmThrottleMargin);
+		pi->sys_info.sclk_dpm_tdp_limit_pg =
+			le16_to_cpu(igp_info->info_6.SclkDpmTdpLimitPG);
+		pi->sys_info.gnb_tdp_limit = le16_to_cpu(igp_info->info_6.GnbTdpLimit);
+		pi->sys_info.sclk_dpm_tdp_limit_boost =
+			le16_to_cpu(igp_info->info_6.SclkDpmTdpLimitBoost);
+		pi->sys_info.boost_sclk = le32_to_cpu(igp_info->info_6.ulBoostEngineCLock);
+		pi->sys_info.boost_vid_2bit = igp_info->info_6.ulBoostVid_2bit;
+		if (igp_info->info_6.EnableBoost)
+			pi->sys_info.enable_boost = true;
+		else
+			pi->sys_info.enable_boost = false;
+		sumo_construct_display_voltage_mapping_table(rdev,
+							     &pi->sys_info.disp_clk_voltage_mapping_table,
+							     igp_info->info_6.sDISPCLK_Voltage);
+		sumo_construct_sclk_voltage_mapping_table(rdev,
+							  &pi->sys_info.sclk_voltage_mapping_table,
+							  igp_info->info_6.sAvail_SCLK);
+		sumo_construct_vid_mapping_table(rdev, &pi->sys_info.vid_mapping_table,
+						 igp_info->info_6.sAvail_SCLK);
+
+	}
+	return 0;
+}
+
+static void sumo_construct_boot_and_acpi_state(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	pi->boot_pl.sclk = pi->sys_info.bootup_sclk;
+	pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index;
+	pi->boot_pl.ds_divider_index = 0;
+	pi->boot_pl.ss_divider_index = 0;
+	pi->boot_pl.allow_gnb_slow = 1;
+	pi->acpi_pl = pi->boot_pl;
+	pi->current_ps.num_levels = 1;
+	pi->current_ps.levels[0] = pi->boot_pl;
+}
+
+int sumo_dpm_init(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi;
+	u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT;
+	int ret;
+
+	pi = kzalloc(sizeof(struct sumo_power_info), GFP_KERNEL);
+	if (pi == NULL)
+		return -ENOMEM;
+	rdev->pm.dpm.priv = pi;
+
+	pi->driver_nbps_policy_disable = false;
+	if ((rdev->family == CHIP_PALM) && (hw_rev < 3))
+		pi->disable_gfx_power_gating_in_uvd = true;
+	else
+		pi->disable_gfx_power_gating_in_uvd = false;
+	pi->enable_alt_vddnb = true;
+	pi->enable_sclk_ds = true;
+	pi->enable_dynamic_m3_arbiter = false;
+	pi->enable_dynamic_patch_ps = true;
+	/* Some PALM chips don't seem to properly ungate gfx when UVD is in use;
+	 * for now just disable gfx PG.
+	 */
+	if (rdev->family == CHIP_PALM)
+		pi->enable_gfx_power_gating = false;
+	else
+		pi->enable_gfx_power_gating = true;
+	pi->enable_gfx_clock_gating = true;
+	pi->enable_mg_clock_gating = true;
+	pi->enable_auto_thermal_throttling = true;
+
+	ret = sumo_parse_sys_info_table(rdev);
+	if (ret)
+		return ret;
+
+	sumo_construct_boot_and_acpi_state(rdev);
+
+	ret = sumo_parse_power_table(rdev);
+	if (ret)
+		return ret;
+
+	pi->pasi = CYPRESS_HASI_DFLT;
+	pi->asi = RV770_ASI_DFLT;
+	pi->thermal_auto_throttling = pi->sys_info.htc_tmp_lmt;
+	pi->enable_boost = pi->sys_info.enable_boost;
+	pi->enable_dpm = true;
+
+	return 0;
+}
+
+void sumo_dpm_print_power_state(struct radeon_device *rdev,
+				struct radeon_ps *rps)
+{
+	int i;
+	struct sumo_ps *ps = sumo_get_ps(rps);
+
+	r600_dpm_print_class_info(rps->class, rps->class2);
+	r600_dpm_print_cap_info(rps->caps);
+	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+	for (i = 0; i < ps->num_levels; i++) {
+		struct sumo_pl *pl = &ps->levels[i];
+		printk("\t\tpower level %d    sclk: %u vddc: %u\n",
+		       i, pl->sclk,
+		       sumo_convert_voltage_index_to_value(rdev, pl->vddc_index));
+	}
+	r600_dpm_print_ps_status(rdev, rps);
+}
+
+void sumo_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+						      struct seq_file *m)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+	struct sumo_ps *ps = sumo_get_ps(rps);
+	struct sumo_pl *pl;
+	u32 current_index =
+		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_INDEX_MASK) >>
+		CURR_INDEX_SHIFT;
+
+	if (current_index == BOOST_DPM_LEVEL) {
+		pl = &pi->boost_pl;
+		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+		seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
+			   current_index, pl->sclk,
+			   sumo_convert_voltage_index_to_value(rdev, pl->vddc_index));
+	} else if (current_index >= ps->num_levels) {
+		seq_printf(m, "invalid dpm profile %d\n", current_index);
+	} else {
+		pl = &ps->levels[current_index];
+		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+		seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
+			   current_index, pl->sclk,
+			   sumo_convert_voltage_index_to_value(rdev, pl->vddc_index));
+	}
+}
+
+void sumo_dpm_fini(struct radeon_device *rdev)
+{
+	int i;
+
+	sumo_cleanup_asic(rdev); /* ??? */
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	}
+	kfree(rdev->pm.dpm.ps);
+	kfree(rdev->pm.dpm.priv);
+}
+
+u32 sumo_dpm_get_sclk(struct radeon_device *rdev, bool low)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct sumo_ps *requested_state = sumo_get_ps(&pi->requested_rps);
+
+	if (low)
+		return requested_state->levels[0].sclk;
+	else
+		return requested_state->levels[requested_state->num_levels - 1].sclk;
+}
+
+u32 sumo_dpm_get_mclk(struct radeon_device *rdev, bool low)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+
+	return pi->sys_info.bootup_uma_clk;
+}
+
+int sumo_dpm_force_performance_level(struct radeon_device *rdev,
+				     enum radeon_dpm_forced_level level)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	struct radeon_ps *rps = &pi->current_rps;
+	struct sumo_ps *ps = sumo_get_ps(rps);
+	int i;
+
+	if (ps->num_levels <= 1)
+		return 0;
+
+	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
+		if (pi->enable_boost)
+			sumo_enable_boost(rdev, rps, false);
+		sumo_power_level_enable(rdev, ps->num_levels - 1, true);
+		sumo_set_forced_level(rdev, ps->num_levels - 1);
+		sumo_set_forced_mode_enabled(rdev);
+		for (i = 0; i < ps->num_levels - 1; i++) {
+			sumo_power_level_enable(rdev, i, false);
+		}
+		sumo_set_forced_mode(rdev, false);
+		sumo_set_forced_mode_enabled(rdev);
+		sumo_set_forced_mode(rdev, false);
+	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
+		if (pi->enable_boost)
+			sumo_enable_boost(rdev, rps, false);
+		sumo_power_level_enable(rdev, 0, true);
+		sumo_set_forced_level(rdev, 0);
+		sumo_set_forced_mode_enabled(rdev);
+		for (i = 1; i < ps->num_levels; i++) {
+			sumo_power_level_enable(rdev, i, false);
+		}
+		sumo_set_forced_mode(rdev, false);
+		sumo_set_forced_mode_enabled(rdev);
+		sumo_set_forced_mode(rdev, false);
+	} else {
+		for (i = 0; i < ps->num_levels; i++) {
+			sumo_power_level_enable(rdev, i, true);
+		}
+		if (pi->enable_boost)
+			sumo_enable_boost(rdev, rps, true);
+	}
+
+	rdev->pm.dpm.forced_level = level;
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sumo_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sumo_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sumo_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sumo_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __SUMO_DPM_H__
+#define __SUMO_DPM_H__
+
+#include "atom.h"
+
+#define SUMO_MAX_HARDWARE_POWERLEVELS 5
+#define SUMO_PM_NUMBER_OF_TC 15
+
+struct sumo_pl {
+	u32 sclk;
+	u32 vddc_index;
+	u32 ds_divider_index;
+	u32 ss_divider_index;
+	u32 allow_gnb_slow;
+	u32 sclk_dpm_tdp_limit;
+};
+
+/* used for the flags field */
+#define SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE (1 << 0)
+#define SUMO_POWERSTATE_FLAGS_BOOST_STATE       (1 << 1)
+
+struct sumo_ps {
+	struct sumo_pl levels[SUMO_MAX_HARDWARE_POWERLEVELS];
+	u32 num_levels;
+	/* flags */
+	u32 flags;
+};
+
+#define NUMBER_OF_M3ARB_PARAM_SETS 10
+#define SUMO_MAX_NUMBER_VOLTAGES    4
+
+struct sumo_disp_clock_voltage_mapping_table {
+	u32 num_max_voltage_levels;
+	u32 display_clock_frequency[SUMO_MAX_NUMBER_VOLTAGES];
+};
+
+struct sumo_vid_mapping_entry {
+	u16 vid_2bit;
+	u16 vid_7bit;
+};
+
+struct sumo_vid_mapping_table {
+	u32 num_entries;
+	struct sumo_vid_mapping_entry entries[SUMO_MAX_NUMBER_VOLTAGES];
+};
+
+struct sumo_sclk_voltage_mapping_entry {
+	u32 sclk_frequency;
+	u16 vid_2bit;
+	u16 rsv;
+};
+
+struct sumo_sclk_voltage_mapping_table {
+	u32 num_max_dpm_entries;
+	struct sumo_sclk_voltage_mapping_entry entries[SUMO_MAX_HARDWARE_POWERLEVELS];
+};
+
+struct sumo_sys_info {
+	u32 bootup_sclk;
+	u32 min_sclk;
+	u32 bootup_uma_clk;
+	u16 bootup_nb_voltage_index;
+	u8 htc_tmp_lmt;
+	u8 htc_hyst_lmt;
+	struct sumo_sclk_voltage_mapping_table sclk_voltage_mapping_table;
+	struct sumo_disp_clock_voltage_mapping_table disp_clk_voltage_mapping_table;
+	struct sumo_vid_mapping_table vid_mapping_table;
+	u32 csr_m3_arb_cntl_default[NUMBER_OF_M3ARB_PARAM_SETS];
+	u32 csr_m3_arb_cntl_uvd[NUMBER_OF_M3ARB_PARAM_SETS];
+	u32 csr_m3_arb_cntl_fs3d[NUMBER_OF_M3ARB_PARAM_SETS];
+	u32 sclk_dpm_boost_margin;
+	u32 sclk_dpm_throttle_margin;
+	u32 sclk_dpm_tdp_limit_pg;
+	u32 gnb_tdp_limit;
+	u32 sclk_dpm_tdp_limit_boost;
+	u32 boost_sclk;
+	u32 boost_vid_2bit;
+	bool enable_boost;
+};
+
+struct sumo_power_info {
+	u32 asi;
+	u32 pasi;
+	u32 bsp;
+	u32 bsu;
+	u32 pbsp;
+	u32 pbsu;
+	u32 dsp;
+	u32 psp;
+	u32 thermal_auto_throttling;
+	u32 uvd_m3_arbiter;
+	u32 fw_version;
+	struct sumo_sys_info sys_info;
+	struct sumo_pl acpi_pl;
+	struct sumo_pl boot_pl;
+	struct sumo_pl boost_pl;
+	bool disable_gfx_power_gating_in_uvd;
+	bool driver_nbps_policy_disable;
+	bool enable_alt_vddnb;
+	bool enable_dynamic_m3_arbiter;
+	bool enable_gfx_clock_gating;
+	bool enable_gfx_power_gating;
+	bool enable_mg_clock_gating;
+	bool enable_sclk_ds;
+	bool enable_auto_thermal_throttling;
+	bool enable_dynamic_patch_ps;
+	bool enable_dpm;
+	bool enable_boost;
+	struct radeon_ps current_rps;
+	struct sumo_ps current_ps;
+	struct radeon_ps requested_rps;
+	struct sumo_ps requested_ps;
+};
+
+#define SUMO_UTC_DFLT_00                     0x48
+#define SUMO_UTC_DFLT_01                     0x44
+#define SUMO_UTC_DFLT_02                     0x44
+#define SUMO_UTC_DFLT_03                     0x44
+#define SUMO_UTC_DFLT_04                     0x44
+#define SUMO_UTC_DFLT_05                     0x44
+#define SUMO_UTC_DFLT_06                     0x44
+#define SUMO_UTC_DFLT_07                     0x44
+#define SUMO_UTC_DFLT_08                     0x44
+#define SUMO_UTC_DFLT_09                     0x44
+#define SUMO_UTC_DFLT_10                     0x44
+#define SUMO_UTC_DFLT_11                     0x44
+#define SUMO_UTC_DFLT_12                     0x44
+#define SUMO_UTC_DFLT_13                     0x44
+#define SUMO_UTC_DFLT_14                     0x44
+
+#define SUMO_DTC_DFLT_00                     0x48
+#define SUMO_DTC_DFLT_01                     0x44
+#define SUMO_DTC_DFLT_02                     0x44
+#define SUMO_DTC_DFLT_03                     0x44
+#define SUMO_DTC_DFLT_04                     0x44
+#define SUMO_DTC_DFLT_05                     0x44
+#define SUMO_DTC_DFLT_06                     0x44
+#define SUMO_DTC_DFLT_07                     0x44
+#define SUMO_DTC_DFLT_08                     0x44
+#define SUMO_DTC_DFLT_09                     0x44
+#define SUMO_DTC_DFLT_10                     0x44
+#define SUMO_DTC_DFLT_11                     0x44
+#define SUMO_DTC_DFLT_12                     0x44
+#define SUMO_DTC_DFLT_13                     0x44
+#define SUMO_DTC_DFLT_14                     0x44
+
+#define SUMO_AH_DFLT               5
+
+#define SUMO_R_DFLT0               70
+#define SUMO_R_DFLT1               70
+#define SUMO_R_DFLT2               70
+#define SUMO_R_DFLT3               70
+#define SUMO_R_DFLT4               100
+
+#define SUMO_L_DFLT0               0
+#define SUMO_L_DFLT1               20
+#define SUMO_L_DFLT2               20
+#define SUMO_L_DFLT3               20
+#define SUMO_L_DFLT4               20
+#define SUMO_VRC_DFLT              0x30033
+#define SUMO_MGCGTTLOCAL0_DFLT     0
+#define SUMO_MGCGTTLOCAL1_DFLT     0
+#define SUMO_GICST_DFLT            19
+#define SUMO_SST_DFLT              8
+#define SUMO_VOLTAGEDROPT_DFLT     1
+#define SUMO_GFXPOWERGATINGT_DFLT  100
+
+/* sumo_dpm.c */
+void sumo_gfx_clockgating_initialize(struct radeon_device *rdev);
+void sumo_program_vc(struct radeon_device *rdev, u32 vrc);
+void sumo_clear_vc(struct radeon_device *rdev);
+void sumo_program_sstp(struct radeon_device *rdev);
+void sumo_take_smu_control(struct radeon_device *rdev, bool enable);
+void sumo_construct_sclk_voltage_mapping_table(struct radeon_device *rdev,
+					       struct sumo_sclk_voltage_mapping_table *sclk_voltage_mapping_table,
+					       ATOM_AVAILABLE_SCLK_LIST *table);
+void sumo_construct_vid_mapping_table(struct radeon_device *rdev,
+				      struct sumo_vid_mapping_table *vid_mapping_table,
+				      ATOM_AVAILABLE_SCLK_LIST *table);
+u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev,
+			      struct sumo_vid_mapping_table *vid_mapping_table,
+			      u32 vid_2bit);
+u32 sumo_get_sleep_divider_from_id(u32 id);
+u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
+					 u32 sclk,
+					 u32 min_sclk_in_sr);
+
+/* sumo_smc.c */
+void sumo_initialize_m3_arb(struct radeon_device *rdev);
+void sumo_smu_pg_init(struct radeon_device *rdev);
+void sumo_set_tdp_limit(struct radeon_device *rdev, u32 index, u32 tdp_limit);
+void sumo_smu_notify_alt_vddnb_change(struct radeon_device *rdev,
+				      bool powersaving, bool force_nbps1);
+void sumo_boost_state_enable(struct radeon_device *rdev, bool enable);
+void sumo_enable_boost_timer(struct radeon_device *rdev);
+u32 sumo_get_running_fw_version(struct radeon_device *rdev);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sumo_smc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sumo_smc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/sumo_smc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/sumo_smc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "drmP.h"
+#include "radeon.h"
+#include "sumod.h"
+#include "sumo_dpm.h"
+#include "ppsmc.h"
+
+#define SUMO_SMU_SERVICE_ROUTINE_PG_INIT        1
+#define SUMO_SMU_SERVICE_ROUTINE_ALTVDDNB_NOTIFY  27
+#define SUMO_SMU_SERVICE_ROUTINE_GFX_SRV_ID_20  20
+
+struct sumo_ps *sumo_get_ps(struct radeon_ps *rps);
+struct sumo_power_info *sumo_get_pi(struct radeon_device *rdev);
+
+static void sumo_send_msg_to_smu(struct radeon_device *rdev, u32 id)
+{
+	u32 gfx_int_req;
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(GFX_INT_STATUS) & INT_DONE)
+			break;
+		udelay(1);
+	}
+
+	gfx_int_req = SERV_INDEX(id) | INT_REQ;
+	WREG32(GFX_INT_REQ, gfx_int_req);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(GFX_INT_REQ) & INT_REQ)
+			break;
+		udelay(1);
+	}
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(GFX_INT_STATUS) & INT_ACK)
+			break;
+		udelay(1);
+	}
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(GFX_INT_STATUS) & INT_DONE)
+			break;
+		udelay(1);
+	}
+
+	gfx_int_req &= ~INT_REQ;
+	WREG32(GFX_INT_REQ, gfx_int_req);
+}
+
+void sumo_initialize_m3_arb(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 i;
+
+	if (!pi->enable_dynamic_m3_arbiter)
+		return;
+
+	for (i = 0; i < NUMBER_OF_M3ARB_PARAM_SETS; i++)
+		WREG32_RCU(MCU_M3ARB_PARAMS + (i * 4),
+			   pi->sys_info.csr_m3_arb_cntl_default[i]);
+
+	for (; i < NUMBER_OF_M3ARB_PARAM_SETS * 2; i++)
+		WREG32_RCU(MCU_M3ARB_PARAMS + (i * 4),
+			   pi->sys_info.csr_m3_arb_cntl_uvd[i % NUMBER_OF_M3ARB_PARAM_SETS]);
+
+	for (; i < NUMBER_OF_M3ARB_PARAM_SETS * 3; i++)
+		WREG32_RCU(MCU_M3ARB_PARAMS + (i * 4),
+			   pi->sys_info.csr_m3_arb_cntl_fs3d[i % NUMBER_OF_M3ARB_PARAM_SETS]);
+}
+
+static bool sumo_is_alt_vddnb_supported(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	bool return_code = false;
+
+	if (!pi->enable_alt_vddnb)
+		return return_code;
+
+	if ((rdev->family == CHIP_SUMO) || (rdev->family == CHIP_SUMO2)) {
+		if (pi->fw_version >= 0x00010C00)
+			return_code = true;
+	}
+
+	return return_code;
+}
+
+void sumo_smu_notify_alt_vddnb_change(struct radeon_device *rdev,
+				      bool powersaving, bool force_nbps1)
+{
+	u32 param = 0;
+
+	if (!sumo_is_alt_vddnb_supported(rdev))
+		return;
+
+	if (powersaving)
+		param |= 1;
+
+	if (force_nbps1)
+		param |= 2;
+
+	WREG32_RCU(RCU_ALTVDDNB_NOTIFY, param);
+
+	sumo_send_msg_to_smu(rdev, SUMO_SMU_SERVICE_ROUTINE_ALTVDDNB_NOTIFY);
+}
+
+void sumo_smu_pg_init(struct radeon_device *rdev)
+{
+	sumo_send_msg_to_smu(rdev, SUMO_SMU_SERVICE_ROUTINE_PG_INIT);
+}
+
+static u32 sumo_power_of_4(u32 unit)
+{
+	u32 ret = 1;
+	u32 i;
+
+	for (i = 0; i < unit; i++)
+		ret *= 4;
+
+	return ret;
+}
+
+void sumo_enable_boost_timer(struct radeon_device *rdev)
+{
+	struct sumo_power_info *pi = sumo_get_pi(rdev);
+	u32 period, unit, timer_value;
+	u32 xclk = radeon_get_xclk(rdev);
+
+	unit = (RREG32_RCU(RCU_LCLK_SCALING_CNTL) & LCLK_SCALING_TIMER_PRESCALER_MASK)
+		>> LCLK_SCALING_TIMER_PRESCALER_SHIFT;
+
+	period = 100 * (xclk / 100 / sumo_power_of_4(unit));
+
+	timer_value = (period << 16) | (unit << 4);
+
+	WREG32_RCU(RCU_GNB_PWR_REP_TIMER_CNTL, timer_value);
+	WREG32_RCU(RCU_BOOST_MARGIN, pi->sys_info.sclk_dpm_boost_margin);
+	WREG32_RCU(RCU_THROTTLE_MARGIN, pi->sys_info.sclk_dpm_throttle_margin);
+	WREG32_RCU(GNB_TDP_LIMIT, pi->sys_info.gnb_tdp_limit);
+	WREG32_RCU(RCU_SclkDpmTdpLimitPG, pi->sys_info.sclk_dpm_tdp_limit_pg);
+
+	sumo_send_msg_to_smu(rdev, SUMO_SMU_SERVICE_ROUTINE_GFX_SRV_ID_20);
+}
+
+void sumo_set_tdp_limit(struct radeon_device *rdev, u32 index, u32 tdp_limit)
+{
+	u32 regoffset = 0;
+	u32 shift = 0;
+	u32 mask = 0xFFF;
+	u32 sclk_dpm_tdp_limit;
+
+	switch (index) {
+	case 0:
+		regoffset = RCU_SclkDpmTdpLimit01;
+		shift = 16;
+		break;
+	case 1:
+		regoffset = RCU_SclkDpmTdpLimit01;
+		shift = 0;
+		break;
+	case 2:
+		regoffset = RCU_SclkDpmTdpLimit23;
+		shift = 16;
+		break;
+	case 3:
+		regoffset = RCU_SclkDpmTdpLimit23;
+		shift = 0;
+		break;
+	case 4:
+		regoffset = RCU_SclkDpmTdpLimit47;
+		shift = 16;
+		break;
+	case 7:
+		regoffset = RCU_SclkDpmTdpLimit47;
+		shift = 0;
+		break;
+	default:
+		break;
+	}
+
+	sclk_dpm_tdp_limit = RREG32_RCU(regoffset);
+	sclk_dpm_tdp_limit &= ~(mask << shift);
+	sclk_dpm_tdp_limit |= (tdp_limit << shift);
+	WREG32_RCU(regoffset, sclk_dpm_tdp_limit);
+}
+
+void sumo_boost_state_enable(struct radeon_device *rdev, bool enable)
+{
+	u32 boost_disable = RREG32_RCU(RCU_GPU_BOOST_DISABLE);
+
+	boost_disable &= 0xFFFFFFFE;
+	boost_disable |= (enable ? 0 : 1);
+	WREG32_RCU(RCU_GPU_BOOST_DISABLE, boost_disable);
+}
+
+u32 sumo_get_running_fw_version(struct radeon_device *rdev)
+{
+	return RREG32_RCU(RCU_FW_VERSION);
+}
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/trinityd.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/trinityd.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/trinityd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/trinityd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+#ifndef _TRINITYD_H_
+#define _TRINITYD_H_
+
+/* pm registers */
+
+/* cg */
+#define CG_CGTT_LOCAL_0                                 0x0
+#define CG_CGTT_LOCAL_1                                 0x1
+
+/* smc */
+#define SMU_SCLK_DPM_STATE_0_CNTL_0                     0x1f000
+#       define STATE_VALID(x)                           ((x) << 0)
+#       define STATE_VALID_MASK                         (0xff << 0)
+#       define STATE_VALID_SHIFT                        0
+#       define CLK_DIVIDER(x)                           ((x) << 8)
+#       define CLK_DIVIDER_MASK                         (0xff << 8)
+#       define CLK_DIVIDER_SHIFT                        8
+#       define VID(x)                                   ((x) << 16)
+#       define VID_MASK                                 (0xff << 16)
+#       define VID_SHIFT                                16
+#       define LVRT(x)                                  ((x) << 24)
+#       define LVRT_MASK                                (0xff << 24)
+#       define LVRT_SHIFT                               24
+#define SMU_SCLK_DPM_STATE_0_CNTL_1                     0x1f004
+#       define DS_DIV(x)                                ((x) << 0)
+#       define DS_DIV_MASK                              (0xff << 0)
+#       define DS_DIV_SHIFT                             0
+#       define DS_SH_DIV(x)                             ((x) << 8)
+#       define DS_SH_DIV_MASK                           (0xff << 8)
+#       define DS_SH_DIV_SHIFT                          8
+#       define DISPLAY_WM(x)                            ((x) << 16)
+#       define DISPLAY_WM_MASK                          (0xff << 16)
+#       define DISPLAY_WM_SHIFT                         16
+#       define VCE_WM(x)                                ((x) << 24)
+#       define VCE_WM_MASK                              (0xff << 24)
+#       define VCE_WM_SHIFT                             24
+
+#define SMU_SCLK_DPM_STATE_0_CNTL_3                     0x1f00c
+#       define GNB_SLOW(x)                              ((x) << 0)
+#       define GNB_SLOW_MASK                            (0xff << 0)
+#       define GNB_SLOW_SHIFT                           0
+#       define FORCE_NBPS1(x)                           ((x) << 8)
+#       define FORCE_NBPS1_MASK                         (0xff << 8)
+#       define FORCE_NBPS1_SHIFT                        8
+#define SMU_SCLK_DPM_STATE_0_AT                         0x1f010
+#       define AT(x)                                    ((x) << 0)
+#       define AT_MASK                                  (0xff << 0)
+#       define AT_SHIFT                                 0
+
+#define SMU_SCLK_DPM_STATE_0_PG_CNTL                    0x1f014
+#       define PD_SCLK_DIVIDER(x)                       ((x) << 16)
+#       define PD_SCLK_DIVIDER_MASK                     (0xff << 16)
+#       define PD_SCLK_DIVIDER_SHIFT                    16
+
+#define SMU_SCLK_DPM_STATE_1_CNTL_0                     0x1f020
+
+#define SMU_SCLK_DPM_CNTL                               0x1f100
+#       define SCLK_DPM_EN(x)                           ((x) << 0)
+#       define SCLK_DPM_EN_MASK                         (0xff << 0)
+#       define SCLK_DPM_EN_SHIFT                        0
+#       define SCLK_DPM_BOOT_STATE(x)                   ((x) << 16)
+#       define SCLK_DPM_BOOT_STATE_MASK                 (0xff << 16)
+#       define SCLK_DPM_BOOT_STATE_SHIFT                16
+#       define VOLTAGE_CHG_EN(x)                        ((x) << 24)
+#       define VOLTAGE_CHG_EN_MASK                      (0xff << 24)
+#       define VOLTAGE_CHG_EN_SHIFT                     24
+
+#define SMU_SCLK_DPM_TT_CNTL                            0x1f108
+#       define SCLK_TT_EN(x)                            ((x) << 0)
+#       define SCLK_TT_EN_MASK                          (0xff << 0)
+#       define SCLK_TT_EN_SHIFT                         0
+#define SMU_SCLK_DPM_TTT                                0x1f10c
+#       define LT(x)                                    ((x) << 0)
+#       define LT_MASK                                  (0xffff << 0)
+#       define LT_SHIFT                                 0
+#       define HT(x)                                    ((x) << 16)
+#       define HT_MASK                                  (0xffff << 16)
+#       define HT_SHIFT                                 16
+
+#define SMU_UVD_DPM_STATES                              0x1f1a0
+#define SMU_UVD_DPM_CNTL                                0x1f1a4
+
+#define SMU_S_PG_CNTL                                   0x1f118
+#       define DS_PG_EN(x)                              ((x) << 16)
+#       define DS_PG_EN_MASK                            (0xff << 16)
+#       define DS_PG_EN_SHIFT                           16
+
+#define GFX_POWER_GATING_CNTL                           0x1f38c
+#       define PDS_DIV(x)                               ((x) << 0)
+#       define PDS_DIV_MASK                             (0xff << 0)
+#       define PDS_DIV_SHIFT                            0
+#       define SSSD(x)                                  ((x) << 8)
+#       define SSSD_MASK                                (0xff << 8)
+#       define SSSD_SHIFT                               8
+
+#define PM_CONFIG                                       0x1f428
+#       define SVI_Mode                                 (1 << 29)
+
+#define PM_I_CNTL_1                                     0x1f464
+#       define SCLK_DPM(x)                              ((x) << 0)
+#       define SCLK_DPM_MASK                            (0xff << 0)
+#       define SCLK_DPM_SHIFT                           0
+#       define DS_PG_CNTL(x)                            ((x) << 16)
+#       define DS_PG_CNTL_MASK                          (0xff << 16)
+#       define DS_PG_CNTL_SHIFT                         16
+#define PM_TP                                           0x1f468
+
+#define NB_PSTATE_CONFIG                                0x1f5f8
+#       define Dpm0PgNbPsLo(x)                          ((x) << 0)
+#       define Dpm0PgNbPsLo_MASK                        (3 << 0)
+#       define Dpm0PgNbPsLo_SHIFT                       0
+#       define Dpm0PgNbPsHi(x)                          ((x) << 2)
+#       define Dpm0PgNbPsHi_MASK                        (3 << 2)
+#       define Dpm0PgNbPsHi_SHIFT                       2
+#       define DpmXNbPsLo(x)                            ((x) << 4)
+#       define DpmXNbPsLo_MASK                          (3 << 4)
+#       define DpmXNbPsLo_SHIFT                         4
+#       define DpmXNbPsHi(x)                            ((x) << 6)
+#       define DpmXNbPsHi_MASK                          (3 << 6)
+#       define DpmXNbPsHi_SHIFT                         6
+
+#define DC_CAC_VALUE                                    0x1f908
+
+#define GPU_CAC_AVRG_CNTL                               0x1f920
+#       define WINDOW_SIZE(x)                           ((x) << 0)
+#       define WINDOW_SIZE_MASK                         (0xff << 0)
+#       define WINDOW_SIZE_SHIFT                        0
+
+#define CC_SMU_MISC_FUSES                               0xe0001004
+#       define MinSClkDid(x)                   ((x) << 2)
+#       define MinSClkDid_MASK                 (0x7f << 2)
+#       define MinSClkDid_SHIFT                2
+
+#define CC_SMU_TST_EFUSE1_MISC                          0xe000101c
+#       define RB_BACKEND_DISABLE(x)                    ((x) << 16)
+#       define RB_BACKEND_DISABLE_MASK                  (3 << 16)
+#       define RB_BACKEND_DISABLE_SHIFT                 16
+
+#define SMU_SCRATCH_A                                   0xe0003024
+
+#define SMU_SCRATCH0                                    0xe0003040
+
+/* mmio */
+#define SMC_INT_REQ                                     0x220
+
+#define SMC_MESSAGE_0                                   0x22c
+#define SMC_RESP_0                                      0x230
+
+#define GENERAL_PWRMGT                                  0x670
+#       define GLOBAL_PWRMGT_EN                         (1 << 0)
+
+#define SCLK_PWRMGT_CNTL                                0x678
+#       define DYN_PWR_DOWN_EN                          (1 << 2)
+#       define RESET_BUSY_CNT                           (1 << 4)
+#       define RESET_SCLK_CNT                           (1 << 5)
+#       define DYN_GFX_CLK_OFF_EN                       (1 << 7)
+#       define GFX_CLK_FORCE_ON                         (1 << 8)
+#       define DYNAMIC_PM_EN                            (1 << 21)
+
+#define TARGET_AND_CURRENT_PROFILE_INDEX                0x684
+#       define TARGET_STATE(x)                          ((x) << 0)
+#       define TARGET_STATE_MASK                        (0xf << 0)
+#       define TARGET_STATE_SHIFT                       0
+#       define CURRENT_STATE(x)                         ((x) << 4)
+#       define CURRENT_STATE_MASK                       (0xf << 4)
+#       define CURRENT_STATE_SHIFT                      4
+
+#define CG_GIPOTS                                       0x6d8
+#       define CG_GIPOT(x)                              ((x) << 16)
+#       define CG_GIPOT_MASK                            (0xffff << 16)
+#       define CG_GIPOT_SHIFT                           16
+
+#define CG_PG_CTRL                                      0x6e0
+#       define SP(x)                                    ((x) << 0)
+#       define SP_MASK                                  (0xffff << 0)
+#       define SP_SHIFT                                 0
+#       define SU(x)                                    ((x) << 16)
+#       define SU_MASK                                  (0xffff << 16)
+#       define SU_SHIFT                                 16
+
+#define CG_MISC_REG                                     0x708
+
+#define CG_THERMAL_INT_CTRL                             0x738
+#       define DIG_THERM_INTH(x)                        ((x) << 0)
+#       define DIG_THERM_INTH_MASK                      (0xff << 0)
+#       define DIG_THERM_INTH_SHIFT                     0
+#       define DIG_THERM_INTL(x)                        ((x) << 8)
+#       define DIG_THERM_INTL_MASK                      (0xff << 8)
+#       define DIG_THERM_INTL_SHIFT                     8
+#       define THERM_INTH_MASK                          (1 << 24)
+#       define THERM_INTL_MASK                          (1 << 25)
+
+#define CG_CG_VOLTAGE_CNTL                              0x770
+#       define EN                                       (1 << 9)
+
+#define HW_REV   					0x5564
+#       define ATI_REV_ID_MASK                          (0xf << 28)
+#       define ATI_REV_ID_SHIFT                         28
+/* 0 = A0, 1 = A1, 2 = B0, 3 = C0, etc. */
+
+#define CGTS_SM_CTRL_REG                                0x9150
+
+#define GB_ADDR_CONFIG                                  0x98f8
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/trinity_dpm.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/trinity_dpm.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/trinity_dpm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/trinity_dpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1949 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "drmP.h"
+#include "radeon.h"
+#include "trinityd.h"
+#include "r600_dpm.h"
+#include "trinity_dpm.h"
+#include <linux/seq_file.h>
+
+#define TRINITY_MAX_DEEPSLEEP_DIVIDER_ID 5
+#define TRINITY_MINIMUM_ENGINE_CLOCK 800
+#define SCLK_MIN_DIV_INTV_SHIFT     12
+#define TRINITY_DISPCLK_BYPASS_THRESHOLD 10000
+
+#ifndef TRINITY_MGCG_SEQUENCE
+#define TRINITY_MGCG_SEQUENCE  100
+
+static const u32 trinity_mgcg_shls_default[] =
+{
+	/* Register, Value, Mask */
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x00003fc4, 0xc0000000, 0xffffffff,
+	0x00005448, 0x00000100, 0xffffffff,
+	0x000055e4, 0x00000100, 0xffffffff,
+	0x0000160c, 0x00000100, 0xffffffff,
+	0x00008984, 0x06000100, 0xffffffff,
+	0x0000c164, 0x00000100, 0xffffffff,
+	0x00008a18, 0x00000100, 0xffffffff,
+	0x0000897c, 0x06000100, 0xffffffff,
+	0x00008b28, 0x00000100, 0xffffffff,
+	0x00009144, 0x00800200, 0xffffffff,
+	0x00009a60, 0x00000100, 0xffffffff,
+	0x00009868, 0x00000100, 0xffffffff,
+	0x00008d58, 0x00000100, 0xffffffff,
+	0x00009510, 0x00000100, 0xffffffff,
+	0x0000949c, 0x00000100, 0xffffffff,
+	0x00009654, 0x00000100, 0xffffffff,
+	0x00009030, 0x00000100, 0xffffffff,
+	0x00009034, 0x00000100, 0xffffffff,
+	0x00009038, 0x00000100, 0xffffffff,
+	0x0000903c, 0x00000100, 0xffffffff,
+	0x00009040, 0x00000100, 0xffffffff,
+	0x0000a200, 0x00000100, 0xffffffff,
+	0x0000a204, 0x00000100, 0xffffffff,
+	0x0000a208, 0x00000100, 0xffffffff,
+	0x0000a20c, 0x00000100, 0xffffffff,
+	0x00009744, 0x00000100, 0xffffffff,
+	0x00003f80, 0x00000100, 0xffffffff,
+	0x0000a210, 0x00000100, 0xffffffff,
+	0x0000a214, 0x00000100, 0xffffffff,
+	0x000004d8, 0x00000100, 0xffffffff,
+	0x00009664, 0x00000100, 0xffffffff,
+	0x00009698, 0x00000100, 0xffffffff,
+	0x000004d4, 0x00000200, 0xffffffff,
+	0x000004d0, 0x00000000, 0xffffffff,
+	0x000030cc, 0x00000104, 0xffffffff,
+	0x0000d0c0, 0x00000100, 0xffffffff,
+	0x0000d8c0, 0x00000100, 0xffffffff,
+	0x0000951c, 0x00010000, 0xffffffff,
+	0x00009160, 0x00030002, 0xffffffff,
+	0x00009164, 0x00050004, 0xffffffff,
+	0x00009168, 0x00070006, 0xffffffff,
+	0x00009178, 0x00070000, 0xffffffff,
+	0x0000917c, 0x00030002, 0xffffffff,
+	0x00009180, 0x00050004, 0xffffffff,
+	0x0000918c, 0x00010006, 0xffffffff,
+	0x00009190, 0x00090008, 0xffffffff,
+	0x00009194, 0x00070000, 0xffffffff,
+	0x00009198, 0x00030002, 0xffffffff,
+	0x0000919c, 0x00050004, 0xffffffff,
+	0x000091a8, 0x00010006, 0xffffffff,
+	0x000091ac, 0x00090008, 0xffffffff,
+	0x000091b0, 0x00070000, 0xffffffff,
+	0x000091b4, 0x00030002, 0xffffffff,
+	0x000091b8, 0x00050004, 0xffffffff,
+	0x000091c4, 0x00010006, 0xffffffff,
+	0x000091c8, 0x00090008, 0xffffffff,
+	0x000091cc, 0x00070000, 0xffffffff,
+	0x000091d0, 0x00030002, 0xffffffff,
+	0x000091d4, 0x00050004, 0xffffffff,
+	0x000091e0, 0x00010006, 0xffffffff,
+	0x000091e4, 0x00090008, 0xffffffff,
+	0x000091e8, 0x00000000, 0xffffffff,
+	0x000091ec, 0x00070000, 0xffffffff,
+	0x000091f0, 0x00030002, 0xffffffff,
+	0x000091f4, 0x00050004, 0xffffffff,
+	0x00009200, 0x00010006, 0xffffffff,
+	0x00009204, 0x00090008, 0xffffffff,
+	0x00009208, 0x00070000, 0xffffffff,
+	0x0000920c, 0x00030002, 0xffffffff,
+	0x00009210, 0x00050004, 0xffffffff,
+	0x0000921c, 0x00010006, 0xffffffff,
+	0x00009220, 0x00090008, 0xffffffff,
+	0x00009294, 0x00000000, 0xffffffff
+};
+
+static const u32 trinity_mgcg_shls_enable[] =
+{
+	/* Register, Value, Mask */
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0x00000000, 0x000133FF,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0x00000000, 0xE00B03FC,
+	0x00009150, 0x96944200, 0xffffffff
+};
+
+static const u32 trinity_mgcg_shls_disable[] =
+{
+	/* Register, Value, Mask */
+	0x0000802c, 0xc0000000, 0xffffffff,
+	0x00009150, 0x00600000, 0xffffffff,
+	0x000008f8, 0x00000000, 0xffffffff,
+	0x000008fc, 0xffffffff, 0x000133FF,
+	0x000008f8, 0x00000001, 0xffffffff,
+	0x000008fc, 0xffffffff, 0xE00B03FC
+};
+#endif
+
+#ifndef TRINITY_SYSLS_SEQUENCE
+#define TRINITY_SYSLS_SEQUENCE  100
+
+static const u32 trinity_sysls_default[] =
+{
+	/* Register, Value, Mask */
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x0000d8bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x000020c0, 0x000c0c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x00002f50, 0x00000404, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x0000641c, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00006dfc, 0x00000000, 0xffffffff
+};
+
+static const u32 trinity_sysls_disable[] =
+{
+	/* Register, Value, Mask */
+	0x0000d0c0, 0x00000000, 0xffffffff,
+	0x0000d8c0, 0x00000000, 0xffffffff,
+	0x000055e8, 0x00000000, 0xffffffff,
+	0x0000d0bc, 0x00000000, 0xffffffff,
+	0x0000d8bc, 0x00000000, 0xffffffff,
+	0x000015c0, 0x00041401, 0xffffffff,
+	0x0000264c, 0x00040400, 0xffffffff,
+	0x00002648, 0x00040400, 0xffffffff,
+	0x00002650, 0x00040400, 0xffffffff,
+	0x000020b8, 0x00040400, 0xffffffff,
+	0x000020bc, 0x00040400, 0xffffffff,
+	0x000020c0, 0x00040c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680000, 0xffffffff,
+	0x00002f50, 0x00000404, 0xffffffff,
+	0x000004c8, 0x00000001, 0xffffffff,
+	0x0000641c, 0x00007ffd, 0xffffffff,
+	0x00000c7c, 0x0000ff00, 0xffffffff,
+	0x00006dfc, 0x0000007f, 0xffffffff
+};
+
+static const u32 trinity_sysls_enable[] =
+{
+	/* Register, Value, Mask */
+	0x000055e8, 0x00000001, 0xffffffff,
+	0x0000d0bc, 0x00000100, 0xffffffff,
+	0x0000d8bc, 0x00000100, 0xffffffff,
+	0x000015c0, 0x000c1401, 0xffffffff,
+	0x0000264c, 0x000c0400, 0xffffffff,
+	0x00002648, 0x000c0400, 0xffffffff,
+	0x00002650, 0x000c0400, 0xffffffff,
+	0x000020b8, 0x000c0400, 0xffffffff,
+	0x000020bc, 0x000c0400, 0xffffffff,
+	0x000020c0, 0x000c0c80, 0xffffffff,
+	0x0000f4a0, 0x000000c0, 0xffffffff,
+	0x0000f4a4, 0x00680fff, 0xffffffff,
+	0x00002f50, 0x00000903, 0xffffffff,
+	0x000004c8, 0x00000000, 0xffffffff,
+	0x0000641c, 0x00000000, 0xffffffff,
+	0x00000c7c, 0x00000000, 0xffffffff,
+	0x00006dfc, 0x00000000, 0xffffffff
+};
+#endif
+
+static const u32 trinity_override_mgpg_sequences[] =
+{
+	/* Register, Value */
+	0x00000200, 0xE030032C,
+	0x00000204, 0x00000FFF,
+	0x00000200, 0xE0300058,
+	0x00000204, 0x00030301,
+	0x00000200, 0xE0300054,
+	0x00000204, 0x500010FF,
+	0x00000200, 0xE0300074,
+	0x00000204, 0x00030301,
+	0x00000200, 0xE0300070,
+	0x00000204, 0x500010FF,
+	0x00000200, 0xE0300090,
+	0x00000204, 0x00030301,
+	0x00000200, 0xE030008C,
+	0x00000204, 0x500010FF,
+	0x00000200, 0xE03000AC,
+	0x00000204, 0x00030301,
+	0x00000200, 0xE03000A8,
+	0x00000204, 0x500010FF,
+	0x00000200, 0xE03000C8,
+	0x00000204, 0x00030301,
+	0x00000200, 0xE03000C4,
+	0x00000204, 0x500010FF,
+	0x00000200, 0xE03000E4,
+	0x00000204, 0x00030301,
+	0x00000200, 0xE03000E0,
+	0x00000204, 0x500010FF,
+	0x00000200, 0xE0300100,
+	0x00000204, 0x00030301,
+	0x00000200, 0xE03000FC,
+	0x00000204, 0x500010FF,
+	0x00000200, 0xE0300058,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE0300054,
+	0x00000204, 0x600010FF,
+	0x00000200, 0xE0300074,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE0300070,
+	0x00000204, 0x600010FF,
+	0x00000200, 0xE0300090,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE030008C,
+	0x00000204, 0x600010FF,
+	0x00000200, 0xE03000AC,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE03000A8,
+	0x00000204, 0x600010FF,
+	0x00000200, 0xE03000C8,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE03000C4,
+	0x00000204, 0x600010FF,
+	0x00000200, 0xE03000E4,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE03000E0,
+	0x00000204, 0x600010FF,
+	0x00000200, 0xE0300100,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE03000FC,
+	0x00000204, 0x600010FF,
+	0x00000200, 0xE0300058,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE0300054,
+	0x00000204, 0x700010FF,
+	0x00000200, 0xE0300074,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE0300070,
+	0x00000204, 0x700010FF,
+	0x00000200, 0xE0300090,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE030008C,
+	0x00000204, 0x700010FF,
+	0x00000200, 0xE03000AC,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE03000A8,
+	0x00000204, 0x700010FF,
+	0x00000200, 0xE03000C8,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE03000C4,
+	0x00000204, 0x700010FF,
+	0x00000200, 0xE03000E4,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE03000E0,
+	0x00000204, 0x700010FF,
+	0x00000200, 0xE0300100,
+	0x00000204, 0x00030303,
+	0x00000200, 0xE03000FC,
+	0x00000204, 0x700010FF,
+	0x00000200, 0xE0300058,
+	0x00000204, 0x00010303,
+	0x00000200, 0xE0300054,
+	0x00000204, 0x800010FF,
+	0x00000200, 0xE0300074,
+	0x00000204, 0x00010303,
+	0x00000200, 0xE0300070,
+	0x00000204, 0x800010FF,
+	0x00000200, 0xE0300090,
+	0x00000204, 0x00010303,
+	0x00000200, 0xE030008C,
+	0x00000204, 0x800010FF,
+	0x00000200, 0xE03000AC,
+	0x00000204, 0x00010303,
+	0x00000200, 0xE03000A8,
+	0x00000204, 0x800010FF,
+	0x00000200, 0xE03000C4,
+	0x00000204, 0x800010FF,
+	0x00000200, 0xE03000C8,
+	0x00000204, 0x00010303,
+	0x00000200, 0xE03000E4,
+	0x00000204, 0x00010303,
+	0x00000200, 0xE03000E0,
+	0x00000204, 0x800010FF,
+	0x00000200, 0xE0300100,
+	0x00000204, 0x00010303,
+	0x00000200, 0xE03000FC,
+	0x00000204, 0x800010FF,
+	0x00000200, 0x0001f198,
+	0x00000204, 0x0003ffff,
+	0x00000200, 0x0001f19C,
+	0x00000204, 0x3fffffff,
+	0x00000200, 0xE030032C,
+	0x00000204, 0x00000000,
+};
+
+static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
+						   const u32 *seq, u32 count);
+static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev);
+static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
+					     struct radeon_ps *new_rps,
+					     struct radeon_ps *old_rps);
+
+struct trinity_ps *trinity_get_ps(struct radeon_ps *rps)
+{
+	struct trinity_ps *ps = rps->ps_priv;
+
+	return ps;
+}
+
+struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = rdev->pm.dpm.priv;
+
+	return pi;
+}
+
+static void trinity_gfx_powergating_initialize(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 p, u;
+	u32 value;
+	struct atom_clock_dividers dividers;
+	u32 xclk = radeon_get_xclk(rdev);
+	u32 sssd = 1;
+	int ret;
+	u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT;
+
+        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+                                             25000, false, &dividers);
+	if (ret)
+		return;
+
+	value = RREG32_SMC(GFX_POWER_GATING_CNTL);
+	value &= ~(SSSD_MASK | PDS_DIV_MASK);
+	if (sssd)
+		value |= SSSD(1);
+	value |= PDS_DIV(dividers.post_div);
+	WREG32_SMC(GFX_POWER_GATING_CNTL, value);
+
+	r600_calculate_u_and_p(500, xclk, 16, &p, &u);
+
+	WREG32(CG_PG_CTRL, SP(p) | SU(u));
+
+	WREG32_P(CG_GIPOTS, CG_GIPOT(p), ~CG_GIPOT_MASK);
+
+	/* XXX double check hw_rev */
+	if (pi->override_dynamic_mgpg && (hw_rev == 0))
+		trinity_override_dynamic_mg_powergating(rdev);
+
+}
+
+#define CGCG_CGTT_LOCAL0_MASK       0xFFFF33FF
+#define CGCG_CGTT_LOCAL1_MASK       0xFFFB0FFE
+#define CGTS_SM_CTRL_REG_DISABLE    0x00600000
+#define CGTS_SM_CTRL_REG_ENABLE     0x96944200
+
+static void trinity_mg_clockgating_enable(struct radeon_device *rdev,
+					  bool enable)
+{
+	u32 local0;
+	u32 local1;
+
+	if (enable) {
+		local0 = RREG32_CG(CG_CGTT_LOCAL_0);
+		local1 = RREG32_CG(CG_CGTT_LOCAL_1);
+
+		WREG32_CG(CG_CGTT_LOCAL_0,
+			  (0x00380000 & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
+		WREG32_CG(CG_CGTT_LOCAL_1,
+			  (0x0E000000 & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
+
+		WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_ENABLE);
+	} else {
+		WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_DISABLE);
+
+		local0 = RREG32_CG(CG_CGTT_LOCAL_0);
+		local1 = RREG32_CG(CG_CGTT_LOCAL_1);
+
+		WREG32_CG(CG_CGTT_LOCAL_0,
+			  CGCG_CGTT_LOCAL0_MASK | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
+		WREG32_CG(CG_CGTT_LOCAL_1,
+			  CGCG_CGTT_LOCAL1_MASK | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
+	}
+}
+
+static void trinity_mg_clockgating_initialize(struct radeon_device *rdev)
+{
+	u32 count;
+	const u32 *seq = NULL;
+
+	seq = &trinity_mgcg_shls_default[0];
+	count = sizeof(trinity_mgcg_shls_default) / (3 * sizeof(u32));
+
+	trinity_program_clk_gating_hw_sequence(rdev, seq, count);
+}
+
+static void trinity_gfx_clockgating_enable(struct radeon_device *rdev,
+					   bool enable)
+{
+	if (enable) {
+		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
+	} else {
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
+		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
+		RREG32(GB_ADDR_CONFIG);
+	}
+}
+
+static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
+						   const u32 *seq, u32 count)
+{
+	u32 i, length = count * 3;
+
+	for (i = 0; i < length; i += 3)
+		WREG32_P(seq[i], seq[i+1], ~seq[i+2]);
+}
+
+static void trinity_program_override_mgpg_sequences(struct radeon_device *rdev,
+						    const u32 *seq, u32 count)
+{
+	u32  i, length = count * 2;
+
+	for (i = 0; i < length; i += 2)
+		WREG32(seq[i], seq[i+1]);
+
+}
+
+static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev)
+{
+	u32 count;
+	const u32 *seq = NULL;
+
+	seq = &trinity_override_mgpg_sequences[0];
+	count = sizeof(trinity_override_mgpg_sequences) / (2 * sizeof(u32));
+
+	trinity_program_override_mgpg_sequences(rdev, seq, count);
+}
+
+static void trinity_ls_clockgating_enable(struct radeon_device *rdev,
+					  bool enable)
+{
+	u32 count;
+	const u32 *seq = NULL;
+
+	if (enable) {
+		seq = &trinity_sysls_enable[0];
+		count = sizeof(trinity_sysls_enable) / (3 * sizeof(u32));
+	} else {
+		seq = &trinity_sysls_disable[0];
+		count = sizeof(trinity_sysls_disable) / (3 * sizeof(u32));
+	}
+
+	trinity_program_clk_gating_hw_sequence(rdev, seq, count);
+}
+
+static void trinity_gfx_powergating_enable(struct radeon_device *rdev,
+					   bool enable)
+{
+	if (enable) {
+		if (RREG32_SMC(CC_SMU_TST_EFUSE1_MISC) & RB_BACKEND_DISABLE_MASK)
+			WREG32_SMC(SMU_SCRATCH_A, (RREG32_SMC(SMU_SCRATCH_A) | 0x01));
+
+		WREG32_P(SCLK_PWRMGT_CNTL, DYN_PWR_DOWN_EN, ~DYN_PWR_DOWN_EN);
+	} else {
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_PWR_DOWN_EN);
+		RREG32(GB_ADDR_CONFIG);
+	}
+}
+
+static void trinity_gfx_dynamic_mgpg_enable(struct radeon_device *rdev,
+					    bool enable)
+{
+	u32 value;
+
+	if (enable) {
+		value = RREG32_SMC(PM_I_CNTL_1);
+		value &= ~DS_PG_CNTL_MASK;
+		value |= DS_PG_CNTL(1);
+		WREG32_SMC(PM_I_CNTL_1, value);
+
+		value = RREG32_SMC(SMU_S_PG_CNTL);
+		value &= ~DS_PG_EN_MASK;
+		value |= DS_PG_EN(1);
+		WREG32_SMC(SMU_S_PG_CNTL, value);
+	} else {
+		value = RREG32_SMC(SMU_S_PG_CNTL);
+		value &= ~DS_PG_EN_MASK;
+		WREG32_SMC(SMU_S_PG_CNTL, value);
+
+		value = RREG32_SMC(PM_I_CNTL_1);
+		value &= ~DS_PG_CNTL_MASK;
+		WREG32_SMC(PM_I_CNTL_1, value);
+	}
+
+	trinity_gfx_dynamic_mgpg_config(rdev);
+
+}
+
+static void trinity_enable_clock_power_gating(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	if (pi->enable_gfx_clock_gating)
+		sumo_gfx_clockgating_initialize(rdev);
+	if (pi->enable_mg_clock_gating)
+		trinity_mg_clockgating_initialize(rdev);
+	if (pi->enable_gfx_power_gating)
+		trinity_gfx_powergating_initialize(rdev);
+	if (pi->enable_mg_clock_gating) {
+		trinity_ls_clockgating_enable(rdev, true);
+		trinity_mg_clockgating_enable(rdev, true);
+	}
+	if (pi->enable_gfx_clock_gating)
+		trinity_gfx_clockgating_enable(rdev, true);
+	if (pi->enable_gfx_dynamic_mgpg)
+		trinity_gfx_dynamic_mgpg_enable(rdev, true);
+	if (pi->enable_gfx_power_gating)
+		trinity_gfx_powergating_enable(rdev, true);
+}
+
+static void trinity_disable_clock_power_gating(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	if (pi->enable_gfx_power_gating)
+		trinity_gfx_powergating_enable(rdev, false);
+	if (pi->enable_gfx_dynamic_mgpg)
+		trinity_gfx_dynamic_mgpg_enable(rdev, false);
+	if (pi->enable_gfx_clock_gating)
+		trinity_gfx_clockgating_enable(rdev, false);
+	if (pi->enable_mg_clock_gating) {
+		trinity_mg_clockgating_enable(rdev, false);
+		trinity_ls_clockgating_enable(rdev, false);
+	}
+}
+
+static void trinity_set_divider_value(struct radeon_device *rdev,
+				      u32 index, u32 sclk)
+{
+	struct atom_clock_dividers  dividers;
+	int ret;
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+                                             sclk, false, &dividers);
+	if (ret)
+		return;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
+	value &= ~CLK_DIVIDER_MASK;
+	value |= CLK_DIVIDER(dividers.post_div);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
+
+        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+                                             sclk/2, false, &dividers);
+	if (ret)
+		return;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix);
+	value &= ~PD_SCLK_DIVIDER_MASK;
+	value |= PD_SCLK_DIVIDER(dividers.post_div);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix, value);
+}
+
+static void trinity_set_ds_dividers(struct radeon_device *rdev,
+				    u32 index, u32 divider)
+{
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
+	value &= ~DS_DIV_MASK;
+	value |= DS_DIV(divider);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
+}
+
+static void trinity_set_ss_dividers(struct radeon_device *rdev,
+				    u32 index, u32 divider)
+{
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
+	value &= ~DS_SH_DIV_MASK;
+	value |= DS_SH_DIV(divider);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
+}
+
+static void trinity_set_vid(struct radeon_device *rdev, u32 index, u32 vid)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid);
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
+	value &= ~VID_MASK;
+	value |= VID(vid_7bit);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
+	value &= ~LVRT_MASK;
+	value |= LVRT(0);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
+}
+
+static void trinity_set_allos_gnb_slow(struct radeon_device *rdev,
+				       u32 index, u32 gnb_slow)
+{
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
+	value &= ~GNB_SLOW_MASK;
+	value |= GNB_SLOW(gnb_slow);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
+}
+
+static void trinity_set_force_nbp_state(struct radeon_device *rdev,
+					u32 index, u32 force_nbp_state)
+{
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
+	value &= ~FORCE_NBPS1_MASK;
+	value |= FORCE_NBPS1(force_nbp_state);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
+}
+
+static void trinity_set_display_wm(struct radeon_device *rdev,
+				   u32 index, u32 wm)
+{
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
+	value &= ~DISPLAY_WM_MASK;
+	value |= DISPLAY_WM(wm);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
+}
+
+static void trinity_set_vce_wm(struct radeon_device *rdev,
+			       u32 index, u32 wm)
+{
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
+	value &= ~VCE_WM_MASK;
+	value |= VCE_WM(wm);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
+}
+
+static void trinity_set_at(struct radeon_device *rdev,
+			   u32 index, u32 at)
+{
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix);
+	value &= ~AT_MASK;
+	value |= AT(at);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix, value);
+}
+
+static void trinity_program_power_level(struct radeon_device *rdev,
+					struct trinity_pl *pl, u32 index)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	if (index >= SUMO_MAX_HARDWARE_POWERLEVELS)
+		return;
+
+	trinity_set_divider_value(rdev, index, pl->sclk);
+	trinity_set_vid(rdev, index, pl->vddc_index);
+	trinity_set_ss_dividers(rdev, index, pl->ss_divider_index);
+	trinity_set_ds_dividers(rdev, index, pl->ds_divider_index);
+	trinity_set_allos_gnb_slow(rdev, index, pl->allow_gnb_slow);
+	trinity_set_force_nbp_state(rdev, index, pl->force_nbp_state);
+	trinity_set_display_wm(rdev, index, pl->display_wm);
+	trinity_set_vce_wm(rdev, index, pl->vce_wm);
+	trinity_set_at(rdev, index, pi->at[index]);
+}
+
+static void trinity_power_level_enable_disable(struct radeon_device *rdev,
+					       u32 index, bool enable)
+{
+	u32 value;
+	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
+
+	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
+	value &= ~STATE_VALID_MASK;
+	if (enable)
+		value |= STATE_VALID(1);
+	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
+}
+
+static bool trinity_dpm_enabled(struct radeon_device *rdev)
+{
+	if (RREG32_SMC(SMU_SCLK_DPM_CNTL) & SCLK_DPM_EN(1))
+		return true;
+	else
+		return false;
+}
+
+static void trinity_start_dpm(struct radeon_device *rdev)
+{
+	u32 value = RREG32_SMC(SMU_SCLK_DPM_CNTL);
+
+	value &= ~(SCLK_DPM_EN_MASK | SCLK_DPM_BOOT_STATE_MASK | VOLTAGE_CHG_EN_MASK);
+	value |= SCLK_DPM_EN(1) | SCLK_DPM_BOOT_STATE(0) | VOLTAGE_CHG_EN(1);
+	WREG32_SMC(SMU_SCLK_DPM_CNTL, value);
+
+	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
+	WREG32_P(CG_CG_VOLTAGE_CNTL, 0, ~EN);
+
+	trinity_dpm_config(rdev, true);
+}
+
+static void trinity_wait_for_dpm_enabled(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(SCLK_PWRMGT_CNTL) & DYNAMIC_PM_EN)
+			break;
+		udelay(1);
+	}
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_STATE_MASK) == 0)
+			break;
+		udelay(1);
+	}
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
+			break;
+		udelay(1);
+	}
+}
+
+static void trinity_stop_dpm(struct radeon_device *rdev)
+{
+	u32 sclk_dpm_cntl;
+
+	WREG32_P(CG_CG_VOLTAGE_CNTL, EN, ~EN);
+
+	sclk_dpm_cntl = RREG32_SMC(SMU_SCLK_DPM_CNTL);
+	sclk_dpm_cntl &= ~(SCLK_DPM_EN_MASK | VOLTAGE_CHG_EN_MASK);
+	WREG32_SMC(SMU_SCLK_DPM_CNTL, sclk_dpm_cntl);
+
+	trinity_dpm_config(rdev, false);
+}
+
+static void trinity_start_am(struct radeon_device *rdev)
+{
+	WREG32_P(SCLK_PWRMGT_CNTL, 0, ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
+}
+
+static void trinity_reset_am(struct radeon_device *rdev)
+{
+	WREG32_P(SCLK_PWRMGT_CNTL, RESET_SCLK_CNT | RESET_BUSY_CNT,
+		 ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
+}
+
+static void trinity_wait_for_level_0(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
+			break;
+		udelay(1);
+	}
+}
+
+static void trinity_enable_power_level_0(struct radeon_device *rdev)
+{
+	trinity_power_level_enable_disable(rdev, 0, true);
+}
+
+static void trinity_force_level_0(struct radeon_device *rdev)
+{
+	trinity_dpm_force_state(rdev, 0);
+}
+
+static void trinity_unforce_levels(struct radeon_device *rdev)
+{
+	trinity_dpm_no_forced_level(rdev);
+}
+
+static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev,
+						struct radeon_ps *new_rps,
+						struct radeon_ps *old_rps)
+{
+	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
+	struct trinity_ps *old_ps = trinity_get_ps(old_rps);
+	u32 i;
+	u32 n_current_state_levels = (old_ps == NULL) ? 1 : old_ps->num_levels;
+
+	for (i = 0; i < new_ps->num_levels; i++) {
+		trinity_program_power_level(rdev, &new_ps->levels[i], i);
+		trinity_power_level_enable_disable(rdev, i, true);
+	}
+
+	for (i = new_ps->num_levels; i < n_current_state_levels; i++)
+		trinity_power_level_enable_disable(rdev, i, false);
+}
+
+static void trinity_program_bootup_state(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 i;
+
+	trinity_program_power_level(rdev, &pi->boot_pl, 0);
+	trinity_power_level_enable_disable(rdev, 0, true);
+
+	for (i = 1; i < 8; i++)
+		trinity_power_level_enable_disable(rdev, i, false);
+}
+
+static void trinity_setup_uvd_clock_table(struct radeon_device *rdev,
+					  struct radeon_ps *rps)
+{
+	struct trinity_ps *ps = trinity_get_ps(rps);
+	u32 uvdstates = (ps->vclk_low_divider |
+			 ps->vclk_high_divider << 8 |
+			 ps->dclk_low_divider << 16 |
+			 ps->dclk_high_divider << 24);
+
+	WREG32_SMC(SMU_UVD_DPM_STATES, uvdstates);
+}
+
+static void trinity_setup_uvd_dpm_interval(struct radeon_device *rdev,
+					   u32 interval)
+{
+	u32 p, u;
+	u32 tp = RREG32_SMC(PM_TP);
+	u32 val;
+	u32 xclk = radeon_get_xclk(rdev);
+
+	r600_calculate_u_and_p(interval, xclk, 16, &p, &u);
+
+	val = (p + tp - 1) / tp;
+
+	WREG32_SMC(SMU_UVD_DPM_CNTL, val);
+}
+
+static bool trinity_uvd_clocks_zero(struct radeon_ps *rps)
+{
+	if ((rps->vclk == 0) && (rps->dclk == 0))
+		return true;
+	else
+		return false;
+}
+
+static bool trinity_uvd_clocks_equal(struct radeon_ps *rps1,
+				     struct radeon_ps *rps2)
+{
+	struct trinity_ps *ps1 = trinity_get_ps(rps1);
+	struct trinity_ps *ps2 = trinity_get_ps(rps2);
+
+	if ((rps1->vclk == rps2->vclk) &&
+	    (rps1->dclk == rps2->dclk) &&
+	    (ps1->vclk_low_divider == ps2->vclk_low_divider) &&
+	    (ps1->vclk_high_divider == ps2->vclk_high_divider) &&
+	    (ps1->dclk_low_divider == ps2->dclk_low_divider) &&
+	    (ps1->dclk_high_divider == ps2->dclk_high_divider))
+		return true;
+	else
+		return false;
+}
+
+static void trinity_setup_uvd_clocks(struct radeon_device *rdev,
+				     struct radeon_ps *new_rps,
+				     struct radeon_ps *old_rps)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	if (pi->enable_gfx_power_gating) {
+		trinity_gfx_powergating_enable(rdev, false);
+	}
+
+	if (pi->uvd_dpm) {
+		if (trinity_uvd_clocks_zero(new_rps) &&
+		    !trinity_uvd_clocks_zero(old_rps)) {
+			trinity_setup_uvd_dpm_interval(rdev, 0);
+		} else if (!trinity_uvd_clocks_zero(new_rps)) {
+			trinity_setup_uvd_clock_table(rdev, new_rps);
+
+			if (trinity_uvd_clocks_zero(old_rps)) {
+				u32 tmp = RREG32(CG_MISC_REG);
+				tmp &= 0xfffffffd;
+				WREG32(CG_MISC_REG, tmp);
+
+				radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
+
+				trinity_setup_uvd_dpm_interval(rdev, 3000);
+			}
+		}
+		trinity_uvd_dpm_config(rdev);
+	} else {
+		if (trinity_uvd_clocks_zero(new_rps) ||
+		    trinity_uvd_clocks_equal(new_rps, old_rps))
+			return;
+
+		radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
+	}
+
+	if (pi->enable_gfx_power_gating) {
+		trinity_gfx_powergating_enable(rdev, true);
+	}
+}
+
+static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
+						       struct radeon_ps *new_rps,
+						       struct radeon_ps *old_rps)
+{
+	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
+	struct trinity_ps *current_ps = trinity_get_ps(new_rps);
+
+	if (new_ps->levels[new_ps->num_levels - 1].sclk >=
+	    current_ps->levels[current_ps->num_levels - 1].sclk)
+		return;
+
+	trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
+}
+
+static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
+						      struct radeon_ps *new_rps,
+						      struct radeon_ps *old_rps)
+{
+	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
+	struct trinity_ps *current_ps = trinity_get_ps(old_rps);
+
+	if (new_ps->levels[new_ps->num_levels - 1].sclk <
+	    current_ps->levels[current_ps->num_levels - 1].sclk)
+		return;
+
+	trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
+}
+
+static void trinity_program_ttt(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 value = RREG32_SMC(SMU_SCLK_DPM_TTT);
+
+	value &= ~(HT_MASK | LT_MASK);
+	value |= HT((pi->thermal_auto_throttling + 49) * 8);
+	value |= LT((pi->thermal_auto_throttling + 49 - pi->sys_info.htc_hyst_lmt) * 8);
+	WREG32_SMC(SMU_SCLK_DPM_TTT, value);
+}
+
+static void trinity_enable_att(struct radeon_device *rdev)
+{
+	u32 value = RREG32_SMC(SMU_SCLK_DPM_TT_CNTL);
+
+	value &= ~SCLK_TT_EN_MASK;
+	value |= SCLK_TT_EN(1);
+	WREG32_SMC(SMU_SCLK_DPM_TT_CNTL, value);
+}
+
+static void trinity_program_sclk_dpm(struct radeon_device *rdev)
+{
+	u32 p, u;
+	u32 tp = RREG32_SMC(PM_TP);
+	u32 ni;
+	u32 xclk = radeon_get_xclk(rdev);
+	u32 value;
+
+	r600_calculate_u_and_p(400, xclk, 16, &p, &u);
+
+	ni = (p + tp - 1) / tp;
+
+	value = RREG32_SMC(PM_I_CNTL_1);
+	value &= ~SCLK_DPM_MASK;
+	value |= SCLK_DPM(ni);
+	WREG32_SMC(PM_I_CNTL_1, value);
+}
+
+static int trinity_set_thermal_temperature_range(struct radeon_device *rdev,
+						 int min_temp, int max_temp)
+{
+	int low_temp = 0 * 1000;
+	int high_temp = 255 * 1000;
+
+        if (low_temp < min_temp)
+		low_temp = min_temp;
+        if (high_temp > max_temp)
+		high_temp = max_temp;
+        if (high_temp < low_temp) {
+		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
+                return -EINVAL;
+        }
+
+	WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTH(49 + (high_temp / 1000)), ~DIG_THERM_INTH_MASK);
+	WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTL(49 + (low_temp / 1000)), ~DIG_THERM_INTL_MASK);
+
+	rdev->pm.dpm.thermal.min_temp = low_temp;
+	rdev->pm.dpm.thermal.max_temp = high_temp;
+
+	return 0;
+}
+
+static void trinity_update_current_ps(struct radeon_device *rdev,
+				      struct radeon_ps *rps)
+{
+	struct trinity_ps *new_ps = trinity_get_ps(rps);
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	pi->current_rps = *rps;
+	pi->current_ps = *new_ps;
+	pi->current_rps.ps_priv = &pi->current_ps;
+}
+
+static void trinity_update_requested_ps(struct radeon_device *rdev,
+					struct radeon_ps *rps)
+{
+	struct trinity_ps *new_ps = trinity_get_ps(rps);
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	pi->requested_rps = *rps;
+	pi->requested_ps = *new_ps;
+	pi->requested_rps.ps_priv = &pi->requested_ps;
+}
+
+int trinity_dpm_enable(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	int ret;
+
+	trinity_acquire_mutex(rdev);
+
+	if (trinity_dpm_enabled(rdev)) {
+		trinity_release_mutex(rdev);
+		return -EINVAL;
+	}
+
+	trinity_enable_clock_power_gating(rdev);
+	trinity_program_bootup_state(rdev);
+	sumo_program_vc(rdev, 0x00C00033);
+	trinity_start_am(rdev);
+	if (pi->enable_auto_thermal_throttling) {
+		trinity_program_ttt(rdev);
+		trinity_enable_att(rdev);
+	}
+	trinity_program_sclk_dpm(rdev);
+	trinity_start_dpm(rdev);
+	trinity_wait_for_dpm_enabled(rdev);
+	trinity_release_mutex(rdev);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+		if (ret) {
+			trinity_release_mutex(rdev);
+			return ret;
+		}
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+	}
+
+	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
+	return 0;
+}
+
+void trinity_dpm_disable(struct radeon_device *rdev)
+{
+	trinity_acquire_mutex(rdev);
+	if (!trinity_dpm_enabled(rdev)) {
+		trinity_release_mutex(rdev);
+		return;
+	}
+	trinity_disable_clock_power_gating(rdev);
+	sumo_clear_vc(rdev);
+	trinity_wait_for_level_0(rdev);
+	trinity_stop_dpm(rdev);
+	trinity_reset_am(rdev);
+	trinity_release_mutex(rdev);
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		rdev->irq.dpm_thermal = false;
+		radeon_irq_set(rdev);
+	}
+
+	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+}
+
+static void trinity_get_min_sclk_divider(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	pi->min_sclk_did =
+		(RREG32_SMC(CC_SMU_MISC_FUSES) & MinSClkDid_MASK) >> MinSClkDid_SHIFT;
+}
+
+static void trinity_setup_nbp_sim(struct radeon_device *rdev,
+				  struct radeon_ps *rps)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	struct trinity_ps *new_ps = trinity_get_ps(rps);
+	u32 nbpsconfig;
+
+	if (pi->sys_info.nb_dpm_enable) {
+		nbpsconfig = RREG32_SMC(NB_PSTATE_CONFIG);
+		nbpsconfig &= ~(Dpm0PgNbPsLo_MASK | Dpm0PgNbPsHi_MASK | DpmXNbPsLo_MASK | DpmXNbPsHi_MASK);
+		nbpsconfig |= (Dpm0PgNbPsLo(new_ps->Dpm0PgNbPsLo) |
+			       Dpm0PgNbPsHi(new_ps->Dpm0PgNbPsHi) |
+			       DpmXNbPsLo(new_ps->DpmXNbPsLo) |
+			       DpmXNbPsHi(new_ps->DpmXNbPsHi));
+		WREG32_SMC(NB_PSTATE_CONFIG, nbpsconfig);
+	}
+}
+
+int trinity_dpm_force_performance_level(struct radeon_device *rdev,
+					enum radeon_dpm_forced_level level)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	struct radeon_ps *rps = &pi->current_rps;
+	struct trinity_ps *ps = trinity_get_ps(rps);
+	int i, ret;
+
+	if (ps->num_levels <= 1)
+		return 0;
+
+	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
+		/* not supported by the hw */
+		return -EINVAL;
+	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
+		ret = trinity_dpm_n_levels_disabled(rdev, ps->num_levels - 1);
+		if (ret)
+			return ret;
+	} else {
+		for (i = 0; i < ps->num_levels; i++) {
+			ret = trinity_dpm_n_levels_disabled(rdev, 0);
+			if (ret)
+				return ret;
+		}
+	}
+
+	rdev->pm.dpm.forced_level = level;
+
+	return 0;
+}
+
+int trinity_dpm_pre_set_power_state(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
+	struct radeon_ps *new_ps = &requested_ps;
+
+	trinity_update_requested_ps(rdev, new_ps);
+
+	trinity_apply_state_adjust_rules(rdev,
+					 &pi->requested_rps,
+					 &pi->current_rps);
+
+	return 0;
+}
+
+int trinity_dpm_set_power_state(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	struct radeon_ps *new_ps = &pi->requested_rps;
+	struct radeon_ps *old_ps = &pi->current_rps;
+
+	trinity_acquire_mutex(rdev);
+	if (pi->enable_dpm) {
+		trinity_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+		trinity_enable_power_level_0(rdev);
+		trinity_force_level_0(rdev);
+		trinity_wait_for_level_0(rdev);
+		trinity_setup_nbp_sim(rdev, new_ps);
+		trinity_program_power_levels_0_to_n(rdev, new_ps, old_ps);
+		trinity_force_level_0(rdev);
+		trinity_unforce_levels(rdev);
+		trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+		rdev->pm.dpm.forced_level = RADEON_DPM_FORCED_LEVEL_AUTO;
+	}
+	trinity_release_mutex(rdev);
+
+	return 0;
+}
+
+void trinity_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	struct radeon_ps *new_ps = &pi->requested_rps;
+
+	trinity_update_current_ps(rdev, new_ps);
+}
+
+void trinity_dpm_setup_asic(struct radeon_device *rdev)
+{
+	trinity_acquire_mutex(rdev);
+	sumo_program_sstp(rdev);
+	sumo_take_smu_control(rdev, true);
+	trinity_get_min_sclk_divider(rdev);
+	trinity_release_mutex(rdev);
+}
+
+void trinity_dpm_reset_asic(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	trinity_acquire_mutex(rdev);
+	if (pi->enable_dpm) {
+		trinity_enable_power_level_0(rdev);
+		trinity_force_level_0(rdev);
+		trinity_wait_for_level_0(rdev);
+		trinity_program_bootup_state(rdev);
+		trinity_force_level_0(rdev);
+		trinity_unforce_levels(rdev);
+	}
+	trinity_release_mutex(rdev);
+}
+
+static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev,
+						  u32 vid_2bit)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid_2bit);
+	u32 svi_mode = (RREG32_SMC(PM_CONFIG) & SVI_Mode) ? 1 : 0;
+	u32 step = (svi_mode == 0) ? 1250 : 625;
+	u32 delta = vid_7bit * step + 50;
+
+	if (delta > 155000)
+		return 0;
+
+	return (155000 - delta) / 100;
+}
+
+static void trinity_patch_boot_state(struct radeon_device *rdev,
+				     struct trinity_ps *ps)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	ps->num_levels = 1;
+	ps->nbps_flags = 0;
+	ps->bapm_flags = 0;
+	ps->levels[0] = pi->boot_pl;
+}
+
+static u8 trinity_calculate_vce_wm(struct radeon_device *rdev, u32 sclk)
+{
+	if (sclk < 20000)
+		return 1;
+	return 0;
+}
+
+static void trinity_construct_boot_state(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	pi->boot_pl.sclk = pi->sys_info.bootup_sclk;
+	pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index;
+	pi->boot_pl.ds_divider_index = 0;
+	pi->boot_pl.ss_divider_index = 0;
+	pi->boot_pl.allow_gnb_slow = 1;
+	pi->boot_pl.force_nbp_state = 0;
+	pi->boot_pl.display_wm = 0;
+	pi->boot_pl.vce_wm = 0;
+	pi->current_ps.num_levels = 1;
+	pi->current_ps.levels[0] = pi->boot_pl;
+}
+
+static u8 trinity_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
+						  u32 sclk, u32 min_sclk_in_sr)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 i;
+	u32 temp;
+	u32 min = (min_sclk_in_sr > TRINITY_MINIMUM_ENGINE_CLOCK) ?
+		min_sclk_in_sr : TRINITY_MINIMUM_ENGINE_CLOCK;
+
+	if (sclk < min)
+		return 0;
+
+	if (!pi->enable_sclk_ds)
+		return 0;
+
+	for (i = TRINITY_MAX_DEEPSLEEP_DIVIDER_ID;  ; i--) {
+		temp = sclk / sumo_get_sleep_divider_from_id(i);
+		if (temp >= min || i == 0)
+			break;
+	}
+
+	return (u8)i;
+}
+
+static u32 trinity_get_valid_engine_clock(struct radeon_device *rdev,
+					  u32 lower_limit)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 i;
+
+	for (i = 0; i < pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries; i++) {
+		if (pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency >= lower_limit)
+			return pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency;
+	}
+
+	if (i == pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries)
+		DRM_ERROR("engine clock out of range!");
+
+	return 0;
+}
+
+static void trinity_patch_thermal_state(struct radeon_device *rdev,
+					struct trinity_ps *ps,
+					struct trinity_ps *current_ps)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
+	u32 current_vddc;
+	u32 current_sclk;
+	u32 current_index = 0;
+
+	if (current_ps) {
+		current_vddc = current_ps->levels[current_index].vddc_index;
+		current_sclk = current_ps->levels[current_index].sclk;
+	} else {
+		current_vddc = pi->boot_pl.vddc_index;
+		current_sclk = pi->boot_pl.sclk;
+	}
+
+	ps->levels[0].vddc_index = current_vddc;
+
+	if (ps->levels[0].sclk > current_sclk)
+		ps->levels[0].sclk = current_sclk;
+
+	ps->levels[0].ds_divider_index =
+		trinity_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, sclk_in_sr);
+	ps->levels[0].ss_divider_index = ps->levels[0].ds_divider_index;
+	ps->levels[0].allow_gnb_slow = 1;
+	ps->levels[0].force_nbp_state = 0;
+	ps->levels[0].display_wm = 0;
+	ps->levels[0].vce_wm =
+		trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
+}
+
+static u8 trinity_calculate_display_wm(struct radeon_device *rdev,
+				       struct trinity_ps *ps, u32 index)
+{
+	if (ps == NULL || ps->num_levels <= 1)
+		return 0;
+	else if (ps->num_levels == 2) {
+		if (index == 0)
+			return 0;
+		else
+			return 1;
+	} else {
+		if (index == 0)
+			return 0;
+		else if (ps->levels[index].sclk < 30000)
+			return 0;
+		else
+			return 1;
+	}
+}
+
+static u32 trinity_get_uvd_clock_index(struct radeon_device *rdev,
+				       struct radeon_ps *rps)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 i = 0;
+
+	for (i = 0; i < 4; i++) {
+		if ((rps->vclk == pi->sys_info.uvd_clock_table_entries[i].vclk) &&
+		    (rps->dclk == pi->sys_info.uvd_clock_table_entries[i].dclk))
+		    break;
+	}
+
+	if (i >= 4) {
+		DRM_ERROR("UVD clock index not found!\n");
+		i = 3;
+	}
+	return i;
+}
+
+static void trinity_adjust_uvd_state(struct radeon_device *rdev,
+				     struct radeon_ps *rps)
+{
+	struct trinity_ps *ps = trinity_get_ps(rps);
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 high_index = 0;
+	u32 low_index = 0;
+
+	if (pi->uvd_dpm && r600_is_uvd_state(rps->class, rps->class2)) {
+		high_index = trinity_get_uvd_clock_index(rdev, rps);
+
+		switch(high_index) {
+		case 3:
+		case 2:
+			low_index = 1;
+			break;
+		case 1:
+		case 0:
+		default:
+			low_index = 0;
+			break;
+		}
+
+		ps->vclk_low_divider =
+			pi->sys_info.uvd_clock_table_entries[high_index].vclk_did;
+		ps->dclk_low_divider =
+			pi->sys_info.uvd_clock_table_entries[high_index].dclk_did;
+		ps->vclk_high_divider =
+			pi->sys_info.uvd_clock_table_entries[low_index].vclk_did;
+		ps->dclk_high_divider =
+			pi->sys_info.uvd_clock_table_entries[low_index].dclk_did;
+	}
+}
+
+
+
+static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
+					     struct radeon_ps *new_rps,
+					     struct radeon_ps *old_rps)
+{
+	struct trinity_ps *ps = trinity_get_ps(new_rps);
+	struct trinity_ps *current_ps = trinity_get_ps(old_rps);
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 min_voltage = 0; /* ??? */
+	u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */
+	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
+	u32 i;
+	bool force_high;
+	u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
+
+	if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
+		return trinity_patch_thermal_state(rdev, ps, current_ps);
+
+	trinity_adjust_uvd_state(rdev, new_rps);
+
+	for (i = 0; i < ps->num_levels; i++) {
+		if (ps->levels[i].vddc_index < min_voltage)
+			ps->levels[i].vddc_index = min_voltage;
+
+		if (ps->levels[i].sclk < min_sclk)
+			ps->levels[i].sclk =
+				trinity_get_valid_engine_clock(rdev, min_sclk);
+
+		ps->levels[i].ds_divider_index =
+			sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr);
+
+		ps->levels[i].ss_divider_index = ps->levels[i].ds_divider_index;
+
+		ps->levels[i].allow_gnb_slow = 1;
+		ps->levels[i].force_nbp_state = 0;
+		ps->levels[i].display_wm =
+			trinity_calculate_display_wm(rdev, ps, i);
+		ps->levels[i].vce_wm =
+			trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
+	}
+
+	if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
+	    ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY))
+		ps->bapm_flags |= TRINITY_POWERSTATE_FLAGS_BAPM_DISABLE;
+
+	if (pi->sys_info.nb_dpm_enable) {
+		ps->Dpm0PgNbPsLo = 0x1;
+		ps->Dpm0PgNbPsHi = 0x0;
+		ps->DpmXNbPsLo = 0x2;
+		ps->DpmXNbPsHi = 0x1;
+
+		if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
+		    ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)) {
+			force_high = ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE) ||
+				      ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) &&
+				       (pi->sys_info.uma_channel_number == 1)));
+			force_high = (num_active_displays >= 3) || force_high;
+			ps->Dpm0PgNbPsLo = force_high ? 0x2 : 0x3;
+			ps->Dpm0PgNbPsHi = 0x1;
+			ps->DpmXNbPsLo = force_high ? 0x2 : 0x3;
+			ps->DpmXNbPsHi = 0x2;
+			ps->levels[ps->num_levels - 1].allow_gnb_slow = 0;
+		}
+	}
+}
+
+static void trinity_cleanup_asic(struct radeon_device *rdev)
+{
+	sumo_take_smu_control(rdev, false);
+}
+
+#if 0
+static void trinity_pre_display_configuration_change(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	if (pi->voltage_drop_in_dce)
+		trinity_dce_enable_voltage_adjustment(rdev, false);
+}
+#endif
+
+static void trinity_add_dccac_value(struct radeon_device *rdev)
+{
+	u32 gpu_cac_avrg_cntl_window_size;
+	u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
+	u64 disp_clk = rdev->clock.default_dispclk / 100;
+	u32 dc_cac_value;
+
+	gpu_cac_avrg_cntl_window_size =
+		(RREG32_SMC(GPU_CAC_AVRG_CNTL) & WINDOW_SIZE_MASK) >> WINDOW_SIZE_SHIFT;
+
+	dc_cac_value = (u32)((14213 * disp_clk * disp_clk * (u64)num_active_displays) >>
+			     (32 - gpu_cac_avrg_cntl_window_size));
+
+	WREG32_SMC(DC_CAC_VALUE, dc_cac_value);
+}
+
+void trinity_dpm_display_configuration_changed(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	if (pi->voltage_drop_in_dce)
+		trinity_dce_enable_voltage_adjustment(rdev, true);
+	trinity_add_dccac_value(rdev);
+}
+
+union power_info {
+	struct _ATOM_POWERPLAY_INFO info;
+	struct _ATOM_POWERPLAY_INFO_V2 info_2;
+	struct _ATOM_POWERPLAY_INFO_V3 info_3;
+	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
+	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
+	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
+};
+
+union pplib_clock_info {
+	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
+	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
+	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
+	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
+};
+
+union pplib_power_state {
+	struct _ATOM_PPLIB_STATE v1;
+	struct _ATOM_PPLIB_STATE_V2 v2;
+};
+
+static void trinity_parse_pplib_non_clock_info(struct radeon_device *rdev,
+					       struct radeon_ps *rps,
+					       struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
+					       u8 table_rev)
+{
+	struct trinity_ps *ps = trinity_get_ps(rps);
+
+	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
+	rps->class = le16_to_cpu(non_clock_info->usClassification);
+	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
+
+	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
+		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
+		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
+	} else {
+		rps->vclk = 0;
+		rps->dclk = 0;
+	}
+
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
+		rdev->pm.dpm.boot_ps = rps;
+		trinity_patch_boot_state(rdev, ps);
+	}
+	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		rdev->pm.dpm.uvd_ps = rps;
+}
+
+static void trinity_parse_pplib_clock_info(struct radeon_device *rdev,
+					   struct radeon_ps *rps, int index,
+					   union pplib_clock_info *clock_info)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	struct trinity_ps *ps = trinity_get_ps(rps);
+	struct trinity_pl *pl = &ps->levels[index];
+	u32 sclk;
+
+	sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
+	sclk |= clock_info->sumo.ucEngineClockHigh << 16;
+	pl->sclk = sclk;
+	pl->vddc_index = clock_info->sumo.vddcIndex;
+
+	ps->num_levels = index + 1;
+
+	if (pi->enable_sclk_ds) {
+		pl->ds_divider_index = 5;
+		pl->ss_divider_index = 5;
+	}
+}
+
+static int trinity_parse_power_table(struct radeon_device *rdev)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
+	union pplib_power_state *power_state;
+	int i, j, k, non_clock_array_index, clock_array_index;
+	union pplib_clock_info *clock_info;
+	struct _StateArray *state_array;
+	struct _ClockInfoArray *clock_info_array;
+	struct _NonClockInfoArray *non_clock_info_array;
+	union power_info *power_info;
+	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
+        u16 data_offset;
+	u8 frev, crev;
+	u8 *power_state_offset;
+	struct sumo_ps *ps;
+
+	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset))
+		return -EINVAL;
+	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
+
+	state_array = (struct _StateArray *)
+		(mode_info->atom_context->bios + data_offset +
+		 le16_to_cpu(power_info->pplib.usStateArrayOffset));
+	clock_info_array = (struct _ClockInfoArray *)
+		(mode_info->atom_context->bios + data_offset +
+		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
+	non_clock_info_array = (struct _NonClockInfoArray *)
+		(mode_info->atom_context->bios + data_offset +
+		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
+
+	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
+				  state_array->ucNumEntries, GFP_KERNEL);
+	if (!rdev->pm.dpm.ps)
+		return -ENOMEM;
+	power_state_offset = (u8 *)state_array->states;
+	rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
+	rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
+	rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
+	for (i = 0; i < state_array->ucNumEntries; i++) {
+		power_state = (union pplib_power_state *)power_state_offset;
+		non_clock_array_index = power_state->v2.nonClockInfoIndex;
+		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
+			&non_clock_info_array->nonClockInfo[non_clock_array_index];
+		if (!rdev->pm.power_state[i].clock_info)
+			return -EINVAL;
+		ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL);
+		if (ps == NULL) {
+			kfree(rdev->pm.dpm.ps);
+			return -ENOMEM;
+		}
+		rdev->pm.dpm.ps[i].ps_priv = ps;
+		k = 0;
+		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
+			clock_array_index = power_state->v2.clockInfoIndex[j];
+			if (clock_array_index >= clock_info_array->ucNumEntries)
+				continue;
+			if (k >= SUMO_MAX_HARDWARE_POWERLEVELS)
+				break;
+			clock_info = (union pplib_clock_info *)
+				&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
+			trinity_parse_pplib_clock_info(rdev,
+						       &rdev->pm.dpm.ps[i], k,
+						       clock_info);
+			k++;
+		}
+		trinity_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
+						   non_clock_info,
+						   non_clock_info_array->ucEntrySize);
+		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
+	}
+	rdev->pm.dpm.num_ps = state_array->ucNumEntries;
+	return 0;
+}
+
+union igp_info {
+	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
+	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
+};
+
+static u32 trinity_convert_did_to_freq(struct radeon_device *rdev, u8 did)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	u32 divider;
+
+	if (did >= 8 && did <= 0x3f)
+		divider = did * 25;
+	else if (did > 0x3f && did <= 0x5f)
+		divider = (did - 64) * 50 + 1600;
+	else if (did > 0x5f && did <= 0x7e)
+		divider = (did - 96) * 100 + 3200;
+	else if (did == 0x7f)
+		divider = 128 * 100;
+	else
+		return 10000;
+
+	return ((pi->sys_info.dentist_vco_freq * 100) + (divider - 1)) / divider;
+}
+
+static int trinity_parse_sys_info_table(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
+	union igp_info *igp_info;
+	u8 frev, crev;
+	u16 data_offset;
+	int i;
+
+	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
+				   &frev, &crev, &data_offset)) {
+		igp_info = (union igp_info *)(mode_info->atom_context->bios +
+					      data_offset);
+
+		if (crev != 7) {
+			DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
+			return -EINVAL;
+		}
+		pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_7.ulBootUpEngineClock);
+		pi->sys_info.min_sclk = le32_to_cpu(igp_info->info_7.ulMinEngineClock);
+		pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_7.ulBootUpUMAClock);
+		pi->sys_info.dentist_vco_freq = le32_to_cpu(igp_info->info_7.ulDentistVCOFreq);
+		pi->sys_info.bootup_nb_voltage_index =
+			le16_to_cpu(igp_info->info_7.usBootUpNBVoltage);
+		if (igp_info->info_7.ucHtcTmpLmt == 0)
+			pi->sys_info.htc_tmp_lmt = 203;
+		else
+			pi->sys_info.htc_tmp_lmt = igp_info->info_7.ucHtcTmpLmt;
+		if (igp_info->info_7.ucHtcHystLmt == 0)
+			pi->sys_info.htc_hyst_lmt = 5;
+		else
+			pi->sys_info.htc_hyst_lmt = igp_info->info_7.ucHtcHystLmt;
+		if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) {
+			DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
+		}
+
+		if (pi->enable_nbps_policy)
+			pi->sys_info.nb_dpm_enable = igp_info->info_7.ucNBDPMEnable;
+		else
+			pi->sys_info.nb_dpm_enable = 0;
+
+		for (i = 0; i < TRINITY_NUM_NBPSTATES; i++) {
+			pi->sys_info.nbp_mclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateMemclkFreq[i]);
+			pi->sys_info.nbp_nclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateNClkFreq[i]);
+		}
+
+		pi->sys_info.nbp_voltage_index[0] = le16_to_cpu(igp_info->info_7.usNBP0Voltage);
+		pi->sys_info.nbp_voltage_index[1] = le16_to_cpu(igp_info->info_7.usNBP1Voltage);
+		pi->sys_info.nbp_voltage_index[2] = le16_to_cpu(igp_info->info_7.usNBP2Voltage);
+		pi->sys_info.nbp_voltage_index[3] = le16_to_cpu(igp_info->info_7.usNBP3Voltage);
+
+		if (!pi->sys_info.nb_dpm_enable) {
+			for (i = 1; i < TRINITY_NUM_NBPSTATES; i++) {
+				pi->sys_info.nbp_mclk[i] = pi->sys_info.nbp_mclk[0];
+				pi->sys_info.nbp_nclk[i] = pi->sys_info.nbp_nclk[0];
+				pi->sys_info.nbp_voltage_index[i] = pi->sys_info.nbp_voltage_index[0];
+			}
+		}
+
+		pi->sys_info.uma_channel_number = igp_info->info_7.ucUMAChannelNumber;
+
+		sumo_construct_sclk_voltage_mapping_table(rdev,
+							  &pi->sys_info.sclk_voltage_mapping_table,
+							  igp_info->info_7.sAvail_SCLK);
+		sumo_construct_vid_mapping_table(rdev, &pi->sys_info.vid_mapping_table,
+						 igp_info->info_7.sAvail_SCLK);
+
+		pi->sys_info.uvd_clock_table_entries[0].vclk_did =
+			igp_info->info_7.ucDPMState0VclkFid;
+		pi->sys_info.uvd_clock_table_entries[1].vclk_did =
+			igp_info->info_7.ucDPMState1VclkFid;
+		pi->sys_info.uvd_clock_table_entries[2].vclk_did =
+			igp_info->info_7.ucDPMState2VclkFid;
+		pi->sys_info.uvd_clock_table_entries[3].vclk_did =
+			igp_info->info_7.ucDPMState3VclkFid;
+
+		pi->sys_info.uvd_clock_table_entries[0].dclk_did =
+			igp_info->info_7.ucDPMState0DclkFid;
+		pi->sys_info.uvd_clock_table_entries[1].dclk_did =
+			igp_info->info_7.ucDPMState1DclkFid;
+		pi->sys_info.uvd_clock_table_entries[2].dclk_did =
+			igp_info->info_7.ucDPMState2DclkFid;
+		pi->sys_info.uvd_clock_table_entries[3].dclk_did =
+			igp_info->info_7.ucDPMState3DclkFid;
+
+		for (i = 0; i < 4; i++) {
+			pi->sys_info.uvd_clock_table_entries[i].vclk =
+				trinity_convert_did_to_freq(rdev,
+							    pi->sys_info.uvd_clock_table_entries[i].vclk_did);
+			pi->sys_info.uvd_clock_table_entries[i].dclk =
+				trinity_convert_did_to_freq(rdev,
+							    pi->sys_info.uvd_clock_table_entries[i].dclk_did);
+		}
+
+
+
+	}
+	return 0;
+}
+
+int trinity_dpm_init(struct radeon_device *rdev)
+{
+	struct trinity_power_info *pi;
+	int ret, i;
+
+	pi = kzalloc(sizeof(struct trinity_power_info), GFP_KERNEL);
+	if (pi == NULL)
+		return -ENOMEM;
+	rdev->pm.dpm.priv = pi;
+
+	for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
+		pi->at[i] = TRINITY_AT_DFLT;
+
+	pi->enable_nbps_policy = true;
+	pi->enable_sclk_ds = true;
+	pi->enable_gfx_power_gating = true;
+	pi->enable_gfx_clock_gating = true;
+	pi->enable_mg_clock_gating = true;
+	pi->enable_gfx_dynamic_mgpg = true; /* ??? */
+	pi->override_dynamic_mgpg = true;
+	pi->enable_auto_thermal_throttling = true;
+	pi->voltage_drop_in_dce = false; /* need to restructure dpm/modeset interaction */
+	pi->uvd_dpm = true; /* ??? */
+
+	ret = trinity_parse_sys_info_table(rdev);
+	if (ret)
+		return ret;
+
+	trinity_construct_boot_state(rdev);
+
+	ret = trinity_parse_power_table(rdev);
+	if (ret)
+		return ret;
+
+	pi->thermal_auto_throttling = pi->sys_info.htc_tmp_lmt;
+	pi->enable_dpm = true;
+
+	return 0;
+}
+
+void trinity_dpm_print_power_state(struct radeon_device *rdev,
+				   struct radeon_ps *rps)
+{
+	int i;
+	struct trinity_ps *ps = trinity_get_ps(rps);
+
+	r600_dpm_print_class_info(rps->class, rps->class2);
+	r600_dpm_print_cap_info(rps->caps);
+	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+	for (i = 0; i < ps->num_levels; i++) {
+		struct trinity_pl *pl = &ps->levels[i];
+		printk("\t\tpower level %d    sclk: %u vddc: %u\n",
+		       i, pl->sclk,
+		       trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
+	}
+	r600_dpm_print_ps_status(rdev, rps);
+}
+
+void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+							 struct seq_file *m)
+{
+	struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+	struct trinity_ps *ps = trinity_get_ps(rps);
+	struct trinity_pl *pl;
+	u32 current_index =
+		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >>
+		CURRENT_STATE_SHIFT;
+
+	if (current_index >= ps->num_levels) {
+		seq_printf(m, "invalid dpm profile %d\n", current_index);
+	} else {
+		pl = &ps->levels[current_index];
+		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+		seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
+			   current_index, pl->sclk,
+			   trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
+	}
+}
+
+void trinity_dpm_fini(struct radeon_device *rdev)
+{
+	int i;
+
+	trinity_cleanup_asic(rdev); /* ??? */
+
+	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+		kfree(rdev->pm.dpm.ps[i].ps_priv);
+	}
+	kfree(rdev->pm.dpm.ps);
+	kfree(rdev->pm.dpm.priv);
+}
+
+u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+	struct trinity_ps *requested_state = trinity_get_ps(&pi->requested_rps);
+
+	if (low)
+		return requested_state->levels[0].sclk;
+	else
+		return requested_state->levels[requested_state->num_levels - 1].sclk;
+}
+
+u32 trinity_dpm_get_mclk(struct radeon_device *rdev, bool low)
+{
+	struct trinity_power_info *pi = trinity_get_pi(rdev);
+
+	return pi->sys_info.bootup_uma_clk;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/trinity_dpm.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/trinity_dpm.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/trinity_dpm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/trinity_dpm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 __TRINITY_DPM_H__
+#define __TRINITY_DPM_H__
+
+#include "sumo_dpm.h"
+
+#define TRINITY_SIZEOF_DPM_STATE_TABLE (SMU_SCLK_DPM_STATE_1_CNTL_0 - SMU_SCLK_DPM_STATE_0_CNTL_0)
+
+struct trinity_pl {
+	u32 sclk;
+	u8 vddc_index;
+	u8 ds_divider_index;
+	u8 ss_divider_index;
+	u8 allow_gnb_slow;
+	u8 force_nbp_state;
+	u8 display_wm;
+	u8 vce_wm;
+};
+
+#define TRINITY_POWERSTATE_FLAGS_NBPS_FORCEHIGH  (1 << 0)
+#define TRINITY_POWERSTATE_FLAGS_NBPS_LOCKTOHIGH (1 << 1)
+#define TRINITY_POWERSTATE_FLAGS_NBPS_LOCKTOLOW  (1 << 2)
+
+#define TRINITY_POWERSTATE_FLAGS_BAPM_DISABLE    (1 << 0)
+
+struct trinity_ps {
+	u32 num_levels;
+	struct trinity_pl levels[SUMO_MAX_HARDWARE_POWERLEVELS];
+
+	u32 nbps_flags;
+	u32 bapm_flags;
+
+	u8 Dpm0PgNbPsLo;
+	u8 Dpm0PgNbPsHi;
+	u8 DpmXNbPsLo;
+	u8 DpmXNbPsHi;
+
+	u32 vclk_low_divider;
+	u32 vclk_high_divider;
+	u32 dclk_low_divider;
+	u32 dclk_high_divider;
+};
+
+#define TRINITY_NUM_NBPSTATES   4
+
+struct trinity_uvd_clock_table_entry
+{
+	u32 vclk;
+	u32 dclk;
+	u8 vclk_did;
+	u8 dclk_did;
+	u8 rsv[2];
+};
+
+struct trinity_sys_info {
+	u32 bootup_uma_clk;
+	u32 bootup_sclk;
+	u32 min_sclk;
+	u32 dentist_vco_freq;
+	u32 nb_dpm_enable;
+	u32 nbp_mclk[TRINITY_NUM_NBPSTATES];
+	u32 nbp_nclk[TRINITY_NUM_NBPSTATES];
+	u16 nbp_voltage_index[TRINITY_NUM_NBPSTATES];
+	u16 bootup_nb_voltage_index;
+	u8 htc_tmp_lmt;
+	u8 htc_hyst_lmt;
+	struct sumo_sclk_voltage_mapping_table sclk_voltage_mapping_table;
+	struct sumo_vid_mapping_table vid_mapping_table;
+	u32 uma_channel_number;
+	struct trinity_uvd_clock_table_entry uvd_clock_table_entries[4];
+};
+
+struct trinity_power_info {
+	u32 at[SUMO_MAX_HARDWARE_POWERLEVELS];
+	u32 dpm_interval;
+	u32 thermal_auto_throttling;
+	struct trinity_sys_info sys_info;
+	struct trinity_pl boot_pl;
+	u32 min_sclk_did;
+	bool enable_nbps_policy;
+	bool voltage_drop_in_dce;
+	bool override_dynamic_mgpg;
+	bool enable_gfx_clock_gating;
+	bool enable_gfx_power_gating;
+	bool enable_mg_clock_gating;
+	bool enable_gfx_dynamic_mgpg;
+	bool enable_auto_thermal_throttling;
+	bool enable_dpm;
+	bool enable_sclk_ds;
+	bool uvd_dpm;
+	struct radeon_ps current_rps;
+	struct trinity_ps current_ps;
+	struct radeon_ps requested_rps;
+	struct trinity_ps requested_ps;
+};
+
+#define TRINITY_AT_DFLT            30
+
+/* trinity_smc.c */
+int trinity_dpm_config(struct radeon_device *rdev, bool enable);
+int trinity_uvd_dpm_config(struct radeon_device *rdev);
+int trinity_dpm_force_state(struct radeon_device *rdev, u32 n);
+int trinity_dpm_n_levels_disabled(struct radeon_device *rdev, u32 n);
+int trinity_dpm_no_forced_level(struct radeon_device *rdev);
+int trinity_dce_enable_voltage_adjustment(struct radeon_device *rdev,
+					  bool enable);
+int trinity_gfx_dynamic_mgpg_config(struct radeon_device *rdev);
+void trinity_acquire_mutex(struct radeon_device *rdev);
+void trinity_release_mutex(struct radeon_device *rdev);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/radeon/trinity_smc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/trinity_smc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/radeon/trinity_smc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/radeon/trinity_smc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 "drmP.h"
+#include "radeon.h"
+#include "trinityd.h"
+#include "trinity_dpm.h"
+#include "ppsmc.h"
+
+struct trinity_ps *trinity_get_ps(struct radeon_ps *rps);
+struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev);
+
+static int trinity_notify_message_to_smu(struct radeon_device *rdev, u32 id)
+{
+	int i;
+	u32 v = 0;
+
+	WREG32(SMC_MESSAGE_0, id);
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(SMC_RESP_0) != 0)
+			break;
+		udelay(1);
+	}
+	v = RREG32(SMC_RESP_0);
+
+	if (v != 1) {
+		if (v == 0xFF) {
+			DRM_ERROR("SMC failed to handle the message!\n");
+			return -EINVAL;
+		} else if (v == 0xFE) {
+			DRM_ERROR("Unknown SMC message!\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int trinity_dpm_config(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_SMC(SMU_SCRATCH0, 1);
+	else
+		WREG32_SMC(SMU_SCRATCH0, 0);
+
+	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_Config);
+}
+
+int trinity_dpm_force_state(struct radeon_device *rdev, u32 n)
+{
+	WREG32_SMC(SMU_SCRATCH0, n);
+
+	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_ForceState);
+}
+
+int trinity_dpm_n_levels_disabled(struct radeon_device *rdev, u32 n)
+{
+	WREG32_SMC(SMU_SCRATCH0, n);
+
+	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_N_LevelsDisabled);
+}
+
+int trinity_uvd_dpm_config(struct radeon_device *rdev)
+{
+	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_UVD_DPM_Config);
+}
+
+int trinity_dpm_no_forced_level(struct radeon_device *rdev)
+{
+	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel);
+}
+
+int trinity_dce_enable_voltage_adjustment(struct radeon_device *rdev,
+					  bool enable)
+{
+	if (enable)
+		return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DCE_AllowVoltageAdjustment);
+	else
+		return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DCE_RemoveVoltageAdjustment);
+}
+
+int trinity_gfx_dynamic_mgpg_config(struct radeon_device *rdev)
+{
+	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_PG_SIMD_Config);
+}
+
+void trinity_acquire_mutex(struct radeon_device *rdev)
+{
+	int i;
+
+	WREG32(SMC_INT_REQ, 1);
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if ((RREG32(SMC_INT_REQ) & 0xffff) == 1)
+			break;
+		udelay(1);
+	}
+}
+
+void trinity_release_mutex(struct radeon_device *rdev)
+{
+	WREG32(SMC_INT_REQ, 0);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/Kconfig linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/Kconfig
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,9 @@
+config DRM_RCAR_DU
+	tristate "DRM Support for R-Car Display Unit"
+	depends on DRM && ARM
+	select DRM_KMS_HELPER
+	select DRM_KMS_CMA_HELPER
+	select DRM_GEM_CMA_HELPER
+	help
+	  Choose this option if you have an R-Car chipset.
+	  If M is selected the module will be called rcar-du-drm.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/Makefile linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/Makefile
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,8 @@
+rcar-du-drm-y := rcar_du_crtc.o \
+		 rcar_du_drv.o \
+		 rcar_du_kms.o \
+		 rcar_du_lvds.o \
+		 rcar_du_plane.o \
+		 rcar_du_vga.o
+
+obj-$(CONFIG_DRM_RCAR_DU)	+= rcar-du-drm.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_crtc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_crtc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_crtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,595 @@
+/*
+ * rcar_du_crtc.c  --  R-Car Display Unit CRTCs
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include "rcar_du_crtc.h"
+#include "rcar_du_drv.h"
+#include "rcar_du_kms.h"
+#include "rcar_du_lvds.h"
+#include "rcar_du_plane.h"
+#include "rcar_du_regs.h"
+#include "rcar_du_vga.h"
+
+#define to_rcar_crtc(c)	container_of(c, struct rcar_du_crtc, crtc)
+
+static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg)
+{
+	struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
+
+	return rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
+}
+
+static void rcar_du_crtc_write(struct rcar_du_crtc *rcrtc, u32 reg, u32 data)
+{
+	struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
+
+	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, data);
+}
+
+static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr)
+{
+	struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
+
+	rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
+		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr);
+}
+
+static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set)
+{
+	struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
+
+	rcar_du_write(rcdu, rcrtc->mmio_offset + reg,
+		      rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set);
+}
+
+static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg,
+				 u32 clr, u32 set)
+{
+	struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
+	u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg);
+
+	rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set);
+}
+
+static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
+{
+	struct drm_crtc *crtc = &rcrtc->crtc;
+	struct rcar_du_device *rcdu = crtc->dev->dev_private;
+	const struct drm_display_mode *mode = &crtc->mode;
+	unsigned long clk;
+	u32 value;
+	u32 div;
+
+	/* Dot clock */
+	clk = clk_get_rate(rcdu->clock);
+	div = DIV_ROUND_CLOSEST(clk, mode->clock * 1000);
+	div = clamp(div, 1U, 64U) - 1;
+
+	rcar_du_write(rcdu, rcrtc->index ? ESCR2 : ESCR,
+		      ESCR_DCLKSEL_CLKS | div);
+	rcar_du_write(rcdu, rcrtc->index ? OTAR2 : OTAR, 0);
+
+	/* Signal polarities */
+	value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : DSMR_VSL)
+	      | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : DSMR_HSL)
+	      | DSMR_DIPM_DE;
+	rcar_du_crtc_write(rcrtc, DSMR, value);
+
+	/* Display timings */
+	rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - 19);
+	rcar_du_crtc_write(rcrtc, HDER, mode->htotal - mode->hsync_start +
+					mode->hdisplay - 19);
+	rcar_du_crtc_write(rcrtc, HSWR, mode->hsync_end -
+					mode->hsync_start - 1);
+	rcar_du_crtc_write(rcrtc, HCR,  mode->htotal - 1);
+
+	rcar_du_crtc_write(rcrtc, VDSR, mode->vtotal - mode->vsync_end - 2);
+	rcar_du_crtc_write(rcrtc, VDER, mode->vtotal - mode->vsync_end +
+					mode->vdisplay - 2);
+	rcar_du_crtc_write(rcrtc, VSPR, mode->vtotal - mode->vsync_end +
+					mode->vsync_start - 1);
+	rcar_du_crtc_write(rcrtc, VCR,  mode->vtotal - 1);
+
+	rcar_du_crtc_write(rcrtc, DESR,  mode->htotal - mode->hsync_start);
+	rcar_du_crtc_write(rcrtc, DEWR,  mode->hdisplay);
+}
+
+static void rcar_du_crtc_set_routing(struct rcar_du_crtc *rcrtc)
+{
+	struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
+	u32 dorcr = rcar_du_read(rcdu, DORCR);
+
+	dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK);
+
+	/* Set the DU1 pins sources. Select CRTC 0 if explicitly requested and
+	 * CRTC 1 in all other cases to avoid cloning CRTC 0 to DU0 and DU1 by
+	 * default.
+	 */
+	if (rcrtc->outputs & (1 << 1) && rcrtc->index == 0)
+		dorcr |= DORCR_PG2D_DS1;
+	else
+		dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2;
+
+	rcar_du_write(rcdu, DORCR, dorcr);
+}
+
+static void __rcar_du_start_stop(struct rcar_du_device *rcdu, bool start)
+{
+	rcar_du_write(rcdu, DSYSR,
+		      (rcar_du_read(rcdu, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) |
+		      (start ? DSYSR_DEN : DSYSR_DRES));
+}
+
+static void rcar_du_start_stop(struct rcar_du_device *rcdu, bool start)
+{
+	/* Many of the configuration bits are only updated when the display
+	 * reset (DRES) bit in DSYSR is set to 1, disabling *both* CRTCs. Some
+	 * of those bits could be pre-configured, but others (especially the
+	 * bits related to plane assignment to display timing controllers) need
+	 * to be modified at runtime.
+	 *
+	 * Restart the display controller if a start is requested. Sorry for the
+	 * flicker. It should be possible to move most of the "DRES-update" bits
+	 * setup to driver initialization time and minimize the number of cases
+	 * when the display controller will have to be restarted.
+	 */
+	if (start) {
+		if (rcdu->used_crtcs++ != 0)
+			__rcar_du_start_stop(rcdu, false);
+		__rcar_du_start_stop(rcdu, true);
+	} else {
+		if (--rcdu->used_crtcs == 0)
+			__rcar_du_start_stop(rcdu, false);
+	}
+}
+
+void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output)
+{
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+	/* Store the route from the CRTC output to the DU output. The DU will be
+	 * configured when starting the CRTC.
+	 */
+	rcrtc->outputs |= 1 << output;
+}
+
+void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
+{
+	struct rcar_du_device *rcdu = crtc->dev->dev_private;
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+	struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
+	unsigned int num_planes = 0;
+	unsigned int prio = 0;
+	unsigned int i;
+	u32 dptsr = 0;
+	u32 dspr = 0;
+
+	for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) {
+		struct rcar_du_plane *plane = &rcdu->planes.planes[i];
+		unsigned int j;
+
+		if (plane->crtc != &rcrtc->crtc || !plane->enabled)
+			continue;
+
+		/* Insert the plane in the sorted planes array. */
+		for (j = num_planes++; j > 0; --j) {
+			if (planes[j-1]->zpos <= plane->zpos)
+				break;
+			planes[j] = planes[j-1];
+		}
+
+		planes[j] = plane;
+		prio += plane->format->planes * 4;
+	}
+
+	for (i = 0; i < num_planes; ++i) {
+		struct rcar_du_plane *plane = planes[i];
+		unsigned int index = plane->hwindex;
+
+		prio -= 4;
+		dspr |= (index + 1) << prio;
+		dptsr |= DPTSR_PnDK(index) |  DPTSR_PnTS(index);
+
+		if (plane->format->planes == 2) {
+			index = (index + 1) % 8;
+
+			prio -= 4;
+			dspr |= (index + 1) << prio;
+			dptsr |= DPTSR_PnDK(index) |  DPTSR_PnTS(index);
+		}
+	}
+
+	/* Select display timing and dot clock generator 2 for planes associated
+	 * with superposition controller 2.
+	 */
+	if (rcrtc->index) {
+		u32 value = rcar_du_read(rcdu, DPTSR);
+
+		/* The DPTSR register is updated when the display controller is
+		 * stopped. We thus need to restart the DU. Once again, sorry
+		 * for the flicker. One way to mitigate the issue would be to
+		 * pre-associate planes with CRTCs (either with a fixed 4/4
+		 * split, or through a module parameter). Flicker would then
+		 * occur only if we need to break the pre-association.
+		 */
+		if (value != dptsr) {
+			rcar_du_write(rcdu, DPTSR, dptsr);
+			if (rcdu->used_crtcs) {
+				__rcar_du_start_stop(rcdu, false);
+				__rcar_du_start_stop(rcdu, true);
+			}
+		}
+	}
+
+	rcar_du_write(rcdu, rcrtc->index ? DS2PR : DS1PR, dspr);
+}
+
+static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
+{
+	struct drm_crtc *crtc = &rcrtc->crtc;
+	struct rcar_du_device *rcdu = crtc->dev->dev_private;
+	unsigned int i;
+
+	if (rcrtc->started)
+		return;
+
+	if (WARN_ON(rcrtc->plane->format == NULL))
+		return;
+
+	/* Set display off and background to black */
+	rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
+	rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0));
+
+	/* Configure display timings and output routing */
+	rcar_du_crtc_set_display_timing(rcrtc);
+	rcar_du_crtc_set_routing(rcrtc);
+
+	mutex_lock(&rcdu->planes.lock);
+	rcrtc->plane->enabled = true;
+	rcar_du_crtc_update_planes(crtc);
+	mutex_unlock(&rcdu->planes.lock);
+
+	/* Setup planes. */
+	for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) {
+		struct rcar_du_plane *plane = &rcdu->planes.planes[i];
+
+		if (plane->crtc != crtc || !plane->enabled)
+			continue;
+
+		rcar_du_plane_setup(plane);
+	}
+
+	/* Select master sync mode. This enables display operation in master
+	 * sync mode (with the HSYNC and VSYNC signals configured as outputs and
+	 * actively driven).
+	 */
+	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_MASTER);
+
+	rcar_du_start_stop(rcdu, true);
+
+	rcrtc->started = true;
+}
+
+static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
+{
+	struct drm_crtc *crtc = &rcrtc->crtc;
+	struct rcar_du_device *rcdu = crtc->dev->dev_private;
+
+	if (!rcrtc->started)
+		return;
+
+	mutex_lock(&rcdu->planes.lock);
+	rcrtc->plane->enabled = false;
+	rcar_du_crtc_update_planes(crtc);
+	mutex_unlock(&rcdu->planes.lock);
+
+	/* Select switch sync mode. This stops display operation and configures
+	 * the HSYNC and VSYNC signals as inputs.
+	 */
+	rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
+
+	rcar_du_start_stop(rcdu, false);
+
+	rcrtc->started = false;
+}
+
+void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
+{
+	struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
+
+	rcar_du_crtc_stop(rcrtc);
+	rcar_du_put(rcdu);
+}
+
+void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
+{
+	struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private;
+
+	if (rcrtc->dpms != DRM_MODE_DPMS_ON)
+		return;
+
+	rcar_du_get(rcdu);
+	rcar_du_crtc_start(rcrtc);
+}
+
+static void rcar_du_crtc_update_base(struct rcar_du_crtc *rcrtc)
+{
+	struct drm_crtc *crtc = &rcrtc->crtc;
+
+	rcar_du_plane_compute_base(rcrtc->plane, crtc->fb);
+	rcar_du_plane_update_base(rcrtc->plane);
+}
+
+static void rcar_du_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+	struct rcar_du_device *rcdu = crtc->dev->dev_private;
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+	if (rcrtc->dpms == mode)
+		return;
+
+	if (mode == DRM_MODE_DPMS_ON) {
+		rcar_du_get(rcdu);
+		rcar_du_crtc_start(rcrtc);
+	} else {
+		rcar_du_crtc_stop(rcrtc);
+		rcar_du_put(rcdu);
+	}
+
+	rcrtc->dpms = mode;
+}
+
+static bool rcar_du_crtc_mode_fixup(struct drm_crtc *crtc,
+				    const struct drm_display_mode *mode,
+				    struct drm_display_mode *adjusted_mode)
+{
+	/* TODO Fixup modes */
+	return true;
+}
+
+static void rcar_du_crtc_mode_prepare(struct drm_crtc *crtc)
+{
+	struct rcar_du_device *rcdu = crtc->dev->dev_private;
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+	/* We need to access the hardware during mode set, acquire a reference
+	 * to the DU.
+	 */
+	rcar_du_get(rcdu);
+
+	/* Stop the CRTC and release the plane. Force the DPMS mode to off as a
+	 * result.
+	 */
+	rcar_du_crtc_stop(rcrtc);
+	rcar_du_plane_release(rcrtc->plane);
+
+	rcrtc->dpms = DRM_MODE_DPMS_OFF;
+}
+
+static int rcar_du_crtc_mode_set(struct drm_crtc *crtc,
+				 struct drm_display_mode *mode,
+				 struct drm_display_mode *adjusted_mode,
+				 int x, int y,
+				 struct drm_framebuffer *old_fb)
+{
+	struct rcar_du_device *rcdu = crtc->dev->dev_private;
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+	const struct rcar_du_format_info *format;
+	int ret;
+
+	format = rcar_du_format_info(crtc->fb->pixel_format);
+	if (format == NULL) {
+		dev_dbg(rcdu->dev, "mode_set: unsupported format %08x\n",
+			crtc->fb->pixel_format);
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = rcar_du_plane_reserve(rcrtc->plane, format);
+	if (ret < 0)
+		goto error;
+
+	rcrtc->plane->format = format;
+	rcrtc->plane->pitch = crtc->fb->pitches[0];
+
+	rcrtc->plane->src_x = x;
+	rcrtc->plane->src_y = y;
+	rcrtc->plane->width = mode->hdisplay;
+	rcrtc->plane->height = mode->vdisplay;
+
+	rcar_du_plane_compute_base(rcrtc->plane, crtc->fb);
+
+	rcrtc->outputs = 0;
+
+	return 0;
+
+error:
+	/* There's no rollback/abort operation to clean up in case of error. We
+	 * thus need to release the reference to the DU acquired in prepare()
+	 * here.
+	 */
+	rcar_du_put(rcdu);
+	return ret;
+}
+
+static void rcar_du_crtc_mode_commit(struct drm_crtc *crtc)
+{
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+	/* We're done, restart the CRTC and set the DPMS mode to on. The
+	 * reference to the DU acquired at prepare() time will thus be released
+	 * by the DPMS handler (possibly called by the disable() handler).
+	 */
+	rcar_du_crtc_start(rcrtc);
+	rcrtc->dpms = DRM_MODE_DPMS_ON;
+}
+
+static int rcar_du_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+				      struct drm_framebuffer *old_fb)
+{
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+	rcrtc->plane->src_x = x;
+	rcrtc->plane->src_y = y;
+
+	rcar_du_crtc_update_base(to_rcar_crtc(crtc));
+
+	return 0;
+}
+
+static void rcar_du_crtc_disable(struct drm_crtc *crtc)
+{
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+
+	rcar_du_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+	rcar_du_plane_release(rcrtc->plane);
+}
+
+static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
+	.dpms = rcar_du_crtc_dpms,
+	.mode_fixup = rcar_du_crtc_mode_fixup,
+	.prepare = rcar_du_crtc_mode_prepare,
+	.commit = rcar_du_crtc_mode_commit,
+	.mode_set = rcar_du_crtc_mode_set,
+	.mode_set_base = rcar_du_crtc_mode_set_base,
+	.disable = rcar_du_crtc_disable,
+};
+
+void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc,
+				   struct drm_file *file)
+{
+	struct drm_pending_vblank_event *event;
+	struct drm_device *dev = rcrtc->crtc.dev;
+	unsigned long flags;
+
+	/* Destroy the pending vertical blanking event associated with the
+	 * pending page flip, if any, and disable vertical blanking interrupts.
+	 */
+	spin_lock_irqsave(&dev->event_lock, flags);
+	event = rcrtc->event;
+	if (event && event->base.file_priv == file) {
+		rcrtc->event = NULL;
+		event->base.destroy(&event->base);
+		drm_vblank_put(dev, rcrtc->index);
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc)
+{
+	struct drm_pending_vblank_event *event;
+	struct drm_device *dev = rcrtc->crtc.dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	event = rcrtc->event;
+	rcrtc->event = NULL;
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	if (event == NULL)
+		return;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	drm_send_vblank_event(dev, rcrtc->index, event);
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	drm_vblank_put(dev, rcrtc->index);
+}
+
+static int rcar_du_crtc_page_flip(struct drm_crtc *crtc,
+				  struct drm_framebuffer *fb,
+				  struct drm_pending_vblank_event *event)
+{
+	struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+	struct drm_device *dev = rcrtc->crtc.dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	if (rcrtc->event != NULL) {
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		return -EBUSY;
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	crtc->fb = fb;
+	rcar_du_crtc_update_base(rcrtc);
+
+	if (event) {
+		event->pipe = rcrtc->index;
+		drm_vblank_get(dev, rcrtc->index);
+		spin_lock_irqsave(&dev->event_lock, flags);
+		rcrtc->event = event;
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+	}
+
+	return 0;
+}
+
+static const struct drm_crtc_funcs crtc_funcs = {
+	.destroy = drm_crtc_cleanup,
+	.set_config = drm_crtc_helper_set_config,
+	.page_flip = rcar_du_crtc_page_flip,
+};
+
+int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index)
+{
+	struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index];
+	struct drm_crtc *crtc = &rcrtc->crtc;
+	int ret;
+
+	rcrtc->mmio_offset = index ? DISP2_REG_OFFSET : 0;
+	rcrtc->index = index;
+	rcrtc->dpms = DRM_MODE_DPMS_OFF;
+	rcrtc->plane = &rcdu->planes.planes[index];
+
+	rcrtc->plane->crtc = crtc;
+
+	ret = drm_crtc_init(rcdu->ddev, crtc, &crtc_funcs);
+	if (ret < 0)
+		return ret;
+
+	drm_crtc_helper_add(crtc, &crtc_helper_funcs);
+
+	return 0;
+}
+
+void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable)
+{
+	if (enable) {
+		rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
+		rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
+	} else {
+		rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE);
+	}
+}
+
+void rcar_du_crtc_irq(struct rcar_du_crtc *rcrtc)
+{
+	u32 status;
+
+	status = rcar_du_crtc_read(rcrtc, DSSR);
+	rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
+
+	if (status & DSSR_VBK) {
+		drm_handle_vblank(rcrtc->crtc.dev, rcrtc->index);
+		rcar_du_crtc_finish_page_flip(rcrtc);
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_crtc.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_crtc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_crtc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,50 @@
+/*
+ * rcar_du_crtc.h  --  R-Car Display Unit CRTCs
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __RCAR_DU_CRTC_H__
+#define __RCAR_DU_CRTC_H__
+
+#include <linux/mutex.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+
+struct rcar_du_device;
+struct rcar_du_plane;
+
+struct rcar_du_crtc {
+	struct drm_crtc crtc;
+
+	unsigned int mmio_offset;
+	unsigned int index;
+	bool started;
+
+	struct drm_pending_vblank_event *event;
+	unsigned int outputs;
+	int dpms;
+
+	struct rcar_du_plane *plane;
+};
+
+int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index);
+void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable);
+void rcar_du_crtc_irq(struct rcar_du_crtc *rcrtc);
+void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc,
+				   struct drm_file *file);
+void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc);
+void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc);
+
+void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output);
+void rcar_du_crtc_update_planes(struct drm_crtc *crtc);
+
+#endif /* __RCAR_DU_CRTC_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_drv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,330 @@
+/*
+ * rcar_du_drv.c  --  R-Car Display Unit DRM driver
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include "rcar_du_crtc.h"
+#include "rcar_du_drv.h"
+#include "rcar_du_kms.h"
+#include "rcar_du_regs.h"
+
+/* -----------------------------------------------------------------------------
+ * Core device operations
+ */
+
+/*
+ * rcar_du_get - Acquire a reference to the DU
+ *
+ * Acquiring a reference enables the device clock and setup core registers. A
+ * reference must be held before accessing any hardware registers.
+ *
+ * This function must be called with the DRM mode_config lock held.
+ *
+ * Return 0 in case of success or a negative error code otherwise.
+ */
+int rcar_du_get(struct rcar_du_device *rcdu)
+{
+	int ret;
+
+	if (rcdu->use_count)
+		goto done;
+
+	/* Enable clocks before accessing the hardware. */
+	ret = clk_prepare_enable(rcdu->clock);
+	if (ret < 0)
+		return ret;
+
+	/* Enable extended features */
+	rcar_du_write(rcdu, DEFR, DEFR_CODE | DEFR_DEFE);
+	rcar_du_write(rcdu, DEFR2, DEFR2_CODE | DEFR2_DEFE2G);
+	rcar_du_write(rcdu, DEFR3, DEFR3_CODE | DEFR3_DEFE3);
+	rcar_du_write(rcdu, DEFR4, DEFR4_CODE);
+	rcar_du_write(rcdu, DEFR5, DEFR5_CODE | DEFR5_DEFE5);
+
+	/* Use DS1PR and DS2PR to configure planes priorities and connects the
+	 * superposition 0 to DU0 pins. DU1 pins will be configured dynamically.
+	 */
+	rcar_du_write(rcdu, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS);
+
+done:
+	rcdu->use_count++;
+	return 0;
+}
+
+/*
+ * rcar_du_put - Release a reference to the DU
+ *
+ * Releasing the last reference disables the device clock.
+ *
+ * This function must be called with the DRM mode_config lock held.
+ */
+void rcar_du_put(struct rcar_du_device *rcdu)
+{
+	if (--rcdu->use_count)
+		return;
+
+	clk_disable_unprepare(rcdu->clock);
+}
+
+/* -----------------------------------------------------------------------------
+ * DRM operations
+ */
+
+static int rcar_du_unload(struct drm_device *dev)
+{
+	drm_kms_helper_poll_fini(dev);
+	drm_mode_config_cleanup(dev);
+	drm_vblank_cleanup(dev);
+	drm_irq_uninstall(dev);
+
+	dev->dev_private = NULL;
+
+	return 0;
+}
+
+static int rcar_du_load(struct drm_device *dev, unsigned long flags)
+{
+	struct platform_device *pdev = dev->platformdev;
+	struct rcar_du_platform_data *pdata = pdev->dev.platform_data;
+	struct rcar_du_device *rcdu;
+	struct resource *ioarea;
+	struct resource *mem;
+	int ret;
+
+	if (pdata == NULL) {
+		dev_err(dev->dev, "no platform data\n");
+		return -ENODEV;
+	}
+
+	rcdu = devm_kzalloc(&pdev->dev, sizeof(*rcdu), GFP_KERNEL);
+	if (rcdu == NULL) {
+		dev_err(dev->dev, "failed to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	rcdu->dev = &pdev->dev;
+	rcdu->pdata = pdata;
+	rcdu->ddev = dev;
+	dev->dev_private = rcdu;
+
+	/* I/O resources and clocks */
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (mem == NULL) {
+		dev_err(&pdev->dev, "failed to get memory resource\n");
+		return -EINVAL;
+	}
+
+	ioarea = devm_request_mem_region(&pdev->dev, mem->start,
+					 resource_size(mem), pdev->name);
+	if (ioarea == NULL) {
+		dev_err(&pdev->dev, "failed to request memory region\n");
+		return -EBUSY;
+	}
+
+	rcdu->mmio = devm_ioremap_nocache(&pdev->dev, ioarea->start,
+					  resource_size(ioarea));
+	if (rcdu->mmio == NULL) {
+		dev_err(&pdev->dev, "failed to remap memory resource\n");
+		return -ENOMEM;
+	}
+
+	rcdu->clock = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(rcdu->clock)) {
+		dev_err(&pdev->dev, "failed to get clock\n");
+		return -ENOENT;
+	}
+
+	/* DRM/KMS objects */
+	ret = rcar_du_modeset_init(rcdu);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to initialize DRM/KMS\n");
+		goto done;
+	}
+
+	/* IRQ and vblank handling */
+	ret = drm_vblank_init(dev, (1 << rcdu->num_crtcs) - 1);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to initialize vblank\n");
+		goto done;
+	}
+
+	ret = drm_irq_install(dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to install IRQ handler\n");
+		goto done;
+	}
+
+	platform_set_drvdata(pdev, rcdu);
+
+done:
+	if (ret)
+		rcar_du_unload(dev);
+
+	return ret;
+}
+
+static void rcar_du_preclose(struct drm_device *dev, struct drm_file *file)
+{
+	struct rcar_du_device *rcdu = dev->dev_private;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i)
+		rcar_du_crtc_cancel_page_flip(&rcdu->crtcs[i], file);
+}
+
+static irqreturn_t rcar_du_irq(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct rcar_du_device *rcdu = dev->dev_private;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i)
+		rcar_du_crtc_irq(&rcdu->crtcs[i]);
+
+	return IRQ_HANDLED;
+}
+
+static int rcar_du_enable_vblank(struct drm_device *dev, int crtc)
+{
+	struct rcar_du_device *rcdu = dev->dev_private;
+
+	rcar_du_crtc_enable_vblank(&rcdu->crtcs[crtc], true);
+
+	return 0;
+}
+
+static void rcar_du_disable_vblank(struct drm_device *dev, int crtc)
+{
+	struct rcar_du_device *rcdu = dev->dev_private;
+
+	rcar_du_crtc_enable_vblank(&rcdu->crtcs[crtc], false);
+}
+
+static const struct file_operations rcar_du_fops = {
+	.owner		= THIS_MODULE,
+	.open		= drm_open,
+	.release	= drm_release,
+	.unlocked_ioctl	= drm_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= drm_compat_ioctl,
+#endif
+	.poll		= drm_poll,
+	.read		= drm_read,
+	.fasync		= drm_fasync,
+	.llseek		= no_llseek,
+	.mmap		= drm_gem_cma_mmap,
+};
+
+static struct drm_driver rcar_du_driver = {
+	.driver_features	= DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET
+				| DRIVER_PRIME,
+	.load			= rcar_du_load,
+	.unload			= rcar_du_unload,
+	.preclose		= rcar_du_preclose,
+	.irq_handler		= rcar_du_irq,
+	.get_vblank_counter	= drm_vblank_count,
+	.enable_vblank		= rcar_du_enable_vblank,
+	.disable_vblank		= rcar_du_disable_vblank,
+	.gem_free_object	= drm_gem_cma_free_object,
+	.gem_vm_ops		= &drm_gem_cma_vm_ops,
+	.prime_handle_to_fd	= drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle	= drm_gem_prime_fd_to_handle,
+	.gem_prime_import	= drm_gem_prime_import,
+	.gem_prime_export	= drm_gem_prime_export,
+	.gem_prime_get_sg_table	= drm_gem_cma_prime_get_sg_table,
+	.gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+	.gem_prime_vmap		= drm_gem_cma_prime_vmap,
+	.gem_prime_vunmap	= drm_gem_cma_prime_vunmap,
+	.gem_prime_mmap		= drm_gem_cma_prime_mmap,
+	.dumb_create		= rcar_du_dumb_create,
+	.dumb_map_offset	= drm_gem_cma_dumb_map_offset,
+	.dumb_destroy		= drm_gem_cma_dumb_destroy,
+	.fops			= &rcar_du_fops,
+	.name			= "rcar-du",
+	.desc			= "Renesas R-Car Display Unit",
+	.date			= "20130110",
+	.major			= 1,
+	.minor			= 0,
+};
+
+/* -----------------------------------------------------------------------------
+ * Power management
+ */
+
+#if CONFIG_PM_SLEEP
+static int rcar_du_pm_suspend(struct device *dev)
+{
+	struct rcar_du_device *rcdu = dev_get_drvdata(dev);
+
+	drm_kms_helper_poll_disable(rcdu->ddev);
+	/* TODO Suspend the CRTC */
+
+	return 0;
+}
+
+static int rcar_du_pm_resume(struct device *dev)
+{
+	struct rcar_du_device *rcdu = dev_get_drvdata(dev);
+
+	/* TODO Resume the CRTC */
+
+	drm_kms_helper_poll_enable(rcdu->ddev);
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops rcar_du_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(rcar_du_pm_suspend, rcar_du_pm_resume)
+};
+
+/* -----------------------------------------------------------------------------
+ * Platform driver
+ */
+
+static int rcar_du_probe(struct platform_device *pdev)
+{
+	return drm_platform_init(&rcar_du_driver, pdev);
+}
+
+static int rcar_du_remove(struct platform_device *pdev)
+{
+	drm_platform_exit(&rcar_du_driver, pdev);
+
+	return 0;
+}
+
+static struct platform_driver rcar_du_platform_driver = {
+	.probe		= rcar_du_probe,
+	.remove		= rcar_du_remove,
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "rcar-du",
+		.pm	= &rcar_du_pm_ops,
+	},
+};
+
+module_platform_driver(rcar_du_platform_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Renesas R-Car Display Unit DRM Driver");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_drv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ * rcar_du_drv.h  --  R-Car Display Unit DRM driver
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __RCAR_DU_DRV_H__
+#define __RCAR_DU_DRV_H__
+
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/platform_data/rcar-du.h>
+
+#include "rcar_du_crtc.h"
+#include "rcar_du_plane.h"
+
+struct clk;
+struct device;
+struct drm_device;
+
+struct rcar_du_device {
+	struct device *dev;
+	const struct rcar_du_platform_data *pdata;
+
+	void __iomem *mmio;
+	struct clk *clock;
+	unsigned int use_count;
+
+	struct drm_device *ddev;
+
+	struct rcar_du_crtc crtcs[2];
+	unsigned int used_crtcs;
+	unsigned int num_crtcs;
+
+	struct {
+		struct rcar_du_plane planes[RCAR_DU_NUM_SW_PLANES];
+		unsigned int free;
+		struct mutex lock;
+
+		struct drm_property *alpha;
+		struct drm_property *colorkey;
+		struct drm_property *zpos;
+	} planes;
+};
+
+int rcar_du_get(struct rcar_du_device *rcdu);
+void rcar_du_put(struct rcar_du_device *rcdu);
+
+static inline u32 rcar_du_read(struct rcar_du_device *rcdu, u32 reg)
+{
+	return ioread32(rcdu->mmio + reg);
+}
+
+static inline void rcar_du_write(struct rcar_du_device *rcdu, u32 reg, u32 data)
+{
+	iowrite32(data, rcdu->mmio + reg);
+}
+
+#endif /* __RCAR_DU_DRV_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_kms.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_kms.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_kms.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_kms.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,265 @@
+/*
+ * rcar_du_kms.c  --  R-Car Display Unit Mode Setting
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include "rcar_du_crtc.h"
+#include "rcar_du_drv.h"
+#include "rcar_du_kms.h"
+#include "rcar_du_lvds.h"
+#include "rcar_du_regs.h"
+#include "rcar_du_vga.h"
+
+/* -----------------------------------------------------------------------------
+ * Format helpers
+ */
+
+static const struct rcar_du_format_info rcar_du_format_infos[] = {
+	{
+		.fourcc = DRM_FORMAT_RGB565,
+		.bpp = 16,
+		.planes = 1,
+		.pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
+		.edf = PnDDCR4_EDF_NONE,
+	}, {
+		.fourcc = DRM_FORMAT_ARGB1555,
+		.bpp = 16,
+		.planes = 1,
+		.pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB,
+		.edf = PnDDCR4_EDF_NONE,
+	}, {
+		.fourcc = DRM_FORMAT_XRGB1555,
+		.bpp = 16,
+		.planes = 1,
+		.pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB,
+		.edf = PnDDCR4_EDF_NONE,
+	}, {
+		.fourcc = DRM_FORMAT_XRGB8888,
+		.bpp = 32,
+		.planes = 1,
+		.pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
+		.edf = PnDDCR4_EDF_RGB888,
+	}, {
+		.fourcc = DRM_FORMAT_ARGB8888,
+		.bpp = 32,
+		.planes = 1,
+		.pnmr = PnMR_SPIM_ALP | PnMR_DDDF_16BPP,
+		.edf = PnDDCR4_EDF_ARGB8888,
+	}, {
+		.fourcc = DRM_FORMAT_UYVY,
+		.bpp = 16,
+		.planes = 1,
+		.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
+		.edf = PnDDCR4_EDF_NONE,
+	}, {
+		.fourcc = DRM_FORMAT_YUYV,
+		.bpp = 16,
+		.planes = 1,
+		.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
+		.edf = PnDDCR4_EDF_NONE,
+	}, {
+		.fourcc = DRM_FORMAT_NV12,
+		.bpp = 12,
+		.planes = 2,
+		.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
+		.edf = PnDDCR4_EDF_NONE,
+	}, {
+		.fourcc = DRM_FORMAT_NV21,
+		.bpp = 12,
+		.planes = 2,
+		.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
+		.edf = PnDDCR4_EDF_NONE,
+	}, {
+		/* In YUV 4:2:2, only NV16 is supported (NV61 isn't) */
+		.fourcc = DRM_FORMAT_NV16,
+		.bpp = 16,
+		.planes = 2,
+		.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
+		.edf = PnDDCR4_EDF_NONE,
+	},
+};
+
+const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(rcar_du_format_infos); ++i) {
+		if (rcar_du_format_infos[i].fourcc == fourcc)
+			return &rcar_du_format_infos[i];
+	}
+
+	return NULL;
+}
+
+/* -----------------------------------------------------------------------------
+ * Common connector and encoder functions
+ */
+
+struct drm_encoder *
+rcar_du_connector_best_encoder(struct drm_connector *connector)
+{
+	struct rcar_du_connector *rcon = to_rcar_connector(connector);
+
+	return &rcon->encoder->encoder;
+}
+
+void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder)
+{
+}
+
+void rcar_du_encoder_mode_set(struct drm_encoder *encoder,
+			      struct drm_display_mode *mode,
+			      struct drm_display_mode *adjusted_mode)
+{
+	struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
+
+	rcar_du_crtc_route_output(encoder->crtc, renc->output);
+}
+
+void rcar_du_encoder_mode_commit(struct drm_encoder *encoder)
+{
+}
+
+/* -----------------------------------------------------------------------------
+ * Frame buffer
+ */
+
+int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
+			struct drm_mode_create_dumb *args)
+{
+	unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
+	unsigned int align;
+
+	/* The pitch must be aligned to a 16 pixels boundary. */
+	align = 16 * args->bpp / 8;
+	args->pitch = roundup(max(args->pitch, min_pitch), align);
+
+	return drm_gem_cma_dumb_create(file, dev, args);
+}
+
+static struct drm_framebuffer *
+rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
+		  struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	const struct rcar_du_format_info *format;
+	unsigned int align;
+
+	format = rcar_du_format_info(mode_cmd->pixel_format);
+	if (format == NULL) {
+		dev_dbg(dev->dev, "unsupported pixel format %08x\n",
+			mode_cmd->pixel_format);
+		return ERR_PTR(-EINVAL);
+	}
+
+	align = 16 * format->bpp / 8;
+
+	if (mode_cmd->pitches[0] & (align - 1) ||
+	    mode_cmd->pitches[0] >= 8192) {
+		dev_dbg(dev->dev, "invalid pitch value %u\n",
+			mode_cmd->pitches[0]);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (format->planes == 2) {
+		if (mode_cmd->pitches[1] != mode_cmd->pitches[0]) {
+			dev_dbg(dev->dev,
+				"luma and chroma pitches do not match\n");
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
+	return drm_fb_cma_create(dev, file_priv, mode_cmd);
+}
+
+static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = {
+	.fb_create = rcar_du_fb_create,
+};
+
+int rcar_du_modeset_init(struct rcar_du_device *rcdu)
+{
+	struct drm_device *dev = rcdu->ddev;
+	struct drm_encoder *encoder;
+	unsigned int i;
+	int ret;
+
+	drm_mode_config_init(rcdu->ddev);
+
+	rcdu->ddev->mode_config.min_width = 0;
+	rcdu->ddev->mode_config.min_height = 0;
+	rcdu->ddev->mode_config.max_width = 4095;
+	rcdu->ddev->mode_config.max_height = 2047;
+	rcdu->ddev->mode_config.funcs = &rcar_du_mode_config_funcs;
+
+	ret = rcar_du_plane_init(rcdu);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) {
+		ret = rcar_du_crtc_create(rcdu, i);
+		if (ret < 0)
+			return ret;
+	}
+
+	rcdu->used_crtcs = 0;
+	rcdu->num_crtcs = i;
+
+	for (i = 0; i < rcdu->pdata->num_encoders; ++i) {
+		const struct rcar_du_encoder_data *pdata =
+			&rcdu->pdata->encoders[i];
+
+		if (pdata->output >= ARRAY_SIZE(rcdu->crtcs)) {
+			dev_warn(rcdu->dev,
+				 "encoder %u references unexisting output %u, skipping\n",
+				 i, pdata->output);
+			continue;
+		}
+
+		switch (pdata->encoder) {
+		case RCAR_DU_ENCODER_VGA:
+			rcar_du_vga_init(rcdu, &pdata->u.vga, pdata->output);
+			break;
+
+		case RCAR_DU_ENCODER_LVDS:
+			rcar_du_lvds_init(rcdu, &pdata->u.lvds, pdata->output);
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	/* Set the possible CRTCs and possible clones. All encoders can be
+	 * driven by the CRTC associated with the output they're connected to,
+	 * as well as by CRTC 0.
+	 */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
+
+		encoder->possible_crtcs = (1 << 0) | (1 << renc->output);
+		encoder->possible_clones = 1 << 0;
+	}
+
+	ret = rcar_du_plane_register(rcdu);
+	if (ret < 0)
+		return ret;
+
+	drm_kms_helper_poll_init(rcdu->ddev);
+
+	drm_helper_disable_unused_functions(rcdu->ddev);
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_kms.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_kms.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_kms.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_kms.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,62 @@
+/*
+ * rcar_du_kms.h  --  R-Car Display Unit Mode Setting
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __RCAR_DU_KMS_H__
+#define __RCAR_DU_KMS_H__
+
+#include <linux/types.h>
+
+#include <drm/drm_crtc.h>
+
+struct rcar_du_device;
+
+struct rcar_du_format_info {
+	u32 fourcc;
+	unsigned int bpp;
+	unsigned int planes;
+	unsigned int pnmr;
+	unsigned int edf;
+};
+
+struct rcar_du_encoder {
+	struct drm_encoder encoder;
+	unsigned int output;
+};
+
+#define to_rcar_encoder(e) \
+	container_of(e, struct rcar_du_encoder, encoder)
+
+struct rcar_du_connector {
+	struct drm_connector connector;
+	struct rcar_du_encoder *encoder;
+};
+
+#define to_rcar_connector(c) \
+	container_of(c, struct rcar_du_connector, connector)
+
+const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc);
+
+struct drm_encoder *
+rcar_du_connector_best_encoder(struct drm_connector *connector);
+void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder);
+void rcar_du_encoder_mode_set(struct drm_encoder *encoder,
+			      struct drm_display_mode *mode,
+			      struct drm_display_mode *adjusted_mode);
+void rcar_du_encoder_mode_commit(struct drm_encoder *encoder);
+
+int rcar_du_modeset_init(struct rcar_du_device *rcdu);
+
+int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
+			struct drm_mode_create_dumb *args);
+
+#endif /* __RCAR_DU_KMS_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_lvds.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_lvds.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_lvds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_lvds.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,216 @@
+/*
+ * rcar_du_lvds.c  --  R-Car Display Unit LVDS Encoder and Connector
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "rcar_du_drv.h"
+#include "rcar_du_kms.h"
+#include "rcar_du_lvds.h"
+
+struct rcar_du_lvds_connector {
+	struct rcar_du_connector connector;
+
+	const struct rcar_du_panel_data *panel;
+};
+
+#define to_rcar_lvds_connector(c) \
+	container_of(c, struct rcar_du_lvds_connector, connector.connector)
+
+/* -----------------------------------------------------------------------------
+ * Connector
+ */
+
+static int rcar_du_lvds_connector_get_modes(struct drm_connector *connector)
+{
+	struct rcar_du_lvds_connector *lvdscon = to_rcar_lvds_connector(connector);
+	struct drm_display_mode *mode;
+
+	mode = drm_mode_create(connector->dev);
+	if (mode == NULL)
+		return 0;
+
+	mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
+	mode->clock = lvdscon->panel->mode.clock;
+	mode->hdisplay = lvdscon->panel->mode.hdisplay;
+	mode->hsync_start = lvdscon->panel->mode.hsync_start;
+	mode->hsync_end = lvdscon->panel->mode.hsync_end;
+	mode->htotal = lvdscon->panel->mode.htotal;
+	mode->vdisplay = lvdscon->panel->mode.vdisplay;
+	mode->vsync_start = lvdscon->panel->mode.vsync_start;
+	mode->vsync_end = lvdscon->panel->mode.vsync_end;
+	mode->vtotal = lvdscon->panel->mode.vtotal;
+	mode->flags = lvdscon->panel->mode.flags;
+
+	drm_mode_set_name(mode);
+	drm_mode_probed_add(connector, mode);
+
+	return 1;
+}
+
+static int rcar_du_lvds_connector_mode_valid(struct drm_connector *connector,
+					    struct drm_display_mode *mode)
+{
+	return MODE_OK;
+}
+
+static const struct drm_connector_helper_funcs connector_helper_funcs = {
+	.get_modes = rcar_du_lvds_connector_get_modes,
+	.mode_valid = rcar_du_lvds_connector_mode_valid,
+	.best_encoder = rcar_du_connector_best_encoder,
+};
+
+static void rcar_du_lvds_connector_destroy(struct drm_connector *connector)
+{
+	drm_sysfs_connector_remove(connector);
+	drm_connector_cleanup(connector);
+}
+
+static enum drm_connector_status
+rcar_du_lvds_connector_detect(struct drm_connector *connector, bool force)
+{
+	return connector_status_connected;
+}
+
+static const struct drm_connector_funcs connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.detect = rcar_du_lvds_connector_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = rcar_du_lvds_connector_destroy,
+};
+
+static int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu,
+				       struct rcar_du_encoder *renc,
+				       const struct rcar_du_panel_data *panel)
+{
+	struct rcar_du_lvds_connector *lvdscon;
+	struct drm_connector *connector;
+	int ret;
+
+	lvdscon = devm_kzalloc(rcdu->dev, sizeof(*lvdscon), GFP_KERNEL);
+	if (lvdscon == NULL)
+		return -ENOMEM;
+
+	lvdscon->panel = panel;
+
+	connector = &lvdscon->connector.connector;
+	connector->display_info.width_mm = panel->width_mm;
+	connector->display_info.height_mm = panel->height_mm;
+
+	ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
+				 DRM_MODE_CONNECTOR_LVDS);
+	if (ret < 0)
+		return ret;
+
+	drm_connector_helper_add(connector, &connector_helper_funcs);
+	ret = drm_sysfs_connector_add(connector);
+	if (ret < 0)
+		return ret;
+
+	drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+	drm_object_property_set_value(&connector->base,
+		rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
+
+	ret = drm_mode_connector_attach_encoder(connector, &renc->encoder);
+	if (ret < 0)
+		return ret;
+
+	connector->encoder = &renc->encoder;
+	lvdscon->connector.encoder = renc;
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Encoder
+ */
+
+static void rcar_du_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static bool rcar_du_lvds_encoder_mode_fixup(struct drm_encoder *encoder,
+					   const struct drm_display_mode *mode,
+					   struct drm_display_mode *adjusted_mode)
+{
+	const struct drm_display_mode *panel_mode;
+	struct drm_device *dev = encoder->dev;
+	struct drm_connector *connector;
+	bool found = false;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->encoder == encoder) {
+			found = true;
+			break;
+		}
+	}
+
+	if (!found) {
+		dev_dbg(dev->dev, "mode_fixup: no connector found\n");
+		return false;
+	}
+
+	if (list_empty(&connector->modes)) {
+		dev_dbg(dev->dev, "mode_fixup: empty modes list\n");
+		return false;
+	}
+
+	panel_mode = list_first_entry(&connector->modes,
+				      struct drm_display_mode, head);
+
+	/* We're not allowed to modify the resolution. */
+	if (mode->hdisplay != panel_mode->hdisplay ||
+	    mode->vdisplay != panel_mode->vdisplay)
+		return false;
+
+	/* The flat panel mode is fixed, just copy it to the adjusted mode. */
+	drm_mode_copy(adjusted_mode, panel_mode);
+
+	return true;
+}
+
+static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
+	.dpms = rcar_du_lvds_encoder_dpms,
+	.mode_fixup = rcar_du_lvds_encoder_mode_fixup,
+	.prepare = rcar_du_encoder_mode_prepare,
+	.commit = rcar_du_encoder_mode_commit,
+	.mode_set = rcar_du_encoder_mode_set,
+};
+
+static const struct drm_encoder_funcs encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+int rcar_du_lvds_init(struct rcar_du_device *rcdu,
+		      const struct rcar_du_encoder_lvds_data *data,
+		      unsigned int output)
+{
+	struct rcar_du_encoder *renc;
+	int ret;
+
+	renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL);
+	if (renc == NULL)
+		return -ENOMEM;
+
+	renc->output = output;
+
+	ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs,
+			       DRM_MODE_ENCODER_LVDS);
+	if (ret < 0)
+		return ret;
+
+	drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs);
+
+	return rcar_du_lvds_connector_init(rcdu, renc, &data->panel);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_lvds.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_lvds.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_lvds.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_lvds.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * rcar_du_lvds.h  --  R-Car Display Unit LVDS Encoder and Connector
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __RCAR_DU_LVDS_H__
+#define __RCAR_DU_LVDS_H__
+
+struct rcar_du_device;
+struct rcar_du_encoder_lvds_data;
+
+int rcar_du_lvds_init(struct rcar_du_device *rcdu,
+		      const struct rcar_du_encoder_lvds_data *data,
+		      unsigned int output);
+
+#endif /* __RCAR_DU_LVDS_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_plane.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_plane.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_plane.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_plane.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,507 @@
+/*
+ * rcar_du_plane.c  --  R-Car Display Unit Planes
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include "rcar_du_drv.h"
+#include "rcar_du_kms.h"
+#include "rcar_du_plane.h"
+#include "rcar_du_regs.h"
+
+#define RCAR_DU_COLORKEY_NONE		(0 << 24)
+#define RCAR_DU_COLORKEY_SOURCE		(1 << 24)
+#define RCAR_DU_COLORKEY_MASK		(1 << 24)
+
+struct rcar_du_kms_plane {
+	struct drm_plane plane;
+	struct rcar_du_plane *hwplane;
+};
+
+static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane)
+{
+	return container_of(plane, struct rcar_du_kms_plane, plane)->hwplane;
+}
+
+static u32 rcar_du_plane_read(struct rcar_du_device *rcdu,
+			      unsigned int index, u32 reg)
+{
+	return rcar_du_read(rcdu, index * PLANE_OFF + reg);
+}
+
+static void rcar_du_plane_write(struct rcar_du_device *rcdu,
+				unsigned int index, u32 reg, u32 data)
+{
+	rcar_du_write(rcdu, index * PLANE_OFF + reg, data);
+}
+
+int rcar_du_plane_reserve(struct rcar_du_plane *plane,
+			  const struct rcar_du_format_info *format)
+{
+	struct rcar_du_device *rcdu = plane->dev;
+	unsigned int i;
+	int ret = -EBUSY;
+
+	mutex_lock(&rcdu->planes.lock);
+
+	for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) {
+		if (!(rcdu->planes.free & (1 << i)))
+			continue;
+
+		if (format->planes == 1 ||
+		    rcdu->planes.free & (1 << ((i + 1) % 8)))
+			break;
+	}
+
+	if (i == ARRAY_SIZE(rcdu->planes.planes))
+		goto done;
+
+	rcdu->planes.free &= ~(1 << i);
+	if (format->planes == 2)
+		rcdu->planes.free &= ~(1 << ((i + 1) % 8));
+
+	plane->hwindex = i;
+
+	ret = 0;
+
+done:
+	mutex_unlock(&rcdu->planes.lock);
+	return ret;
+}
+
+void rcar_du_plane_release(struct rcar_du_plane *plane)
+{
+	struct rcar_du_device *rcdu = plane->dev;
+
+	if (plane->hwindex == -1)
+		return;
+
+	mutex_lock(&rcdu->planes.lock);
+	rcdu->planes.free |= 1 << plane->hwindex;
+	if (plane->format->planes == 2)
+		rcdu->planes.free |= 1 << ((plane->hwindex + 1) % 8);
+	mutex_unlock(&rcdu->planes.lock);
+
+	plane->hwindex = -1;
+}
+
+void rcar_du_plane_update_base(struct rcar_du_plane *plane)
+{
+	struct rcar_du_device *rcdu = plane->dev;
+	unsigned int index = plane->hwindex;
+
+	/* According to the datasheet the Y position is expressed in raster line
+	 * units. However, 32bpp formats seem to require a doubled Y position
+	 * value. Similarly, for the second plane, NV12 and NV21 formats seem to
+	 * require a halved Y position value.
+	 */
+	rcar_du_plane_write(rcdu, index, PnSPXR, plane->src_x);
+	rcar_du_plane_write(rcdu, index, PnSPYR, plane->src_y *
+			    (plane->format->bpp == 32 ? 2 : 1));
+	rcar_du_plane_write(rcdu, index, PnDSA0R, plane->dma[0]);
+
+	if (plane->format->planes == 2) {
+		index = (index + 1) % 8;
+
+		rcar_du_plane_write(rcdu, index, PnSPXR, plane->src_x);
+		rcar_du_plane_write(rcdu, index, PnSPYR, plane->src_y *
+				    (plane->format->bpp == 16 ? 2 : 1) / 2);
+		rcar_du_plane_write(rcdu, index, PnDSA0R, plane->dma[1]);
+	}
+}
+
+void rcar_du_plane_compute_base(struct rcar_du_plane *plane,
+				struct drm_framebuffer *fb)
+{
+	struct drm_gem_cma_object *gem;
+
+	gem = drm_fb_cma_get_gem_obj(fb, 0);
+	plane->dma[0] = gem->paddr + fb->offsets[0];
+
+	if (plane->format->planes == 2) {
+		gem = drm_fb_cma_get_gem_obj(fb, 1);
+		plane->dma[1] = gem->paddr + fb->offsets[1];
+	}
+}
+
+static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane,
+				     unsigned int index)
+{
+	struct rcar_du_device *rcdu = plane->dev;
+	u32 colorkey;
+	u32 pnmr;
+
+	/* The PnALPHAR register controls alpha-blending in 16bpp formats
+	 * (ARGB1555 and XRGB1555).
+	 *
+	 * For ARGB, set the alpha value to 0, and enable alpha-blending when
+	 * the A bit is 0. This maps A=0 to alpha=0 and A=1 to alpha=255.
+	 *
+	 * For XRGB, set the alpha value to the plane-wide alpha value and
+	 * enable alpha-blending regardless of the X bit value.
+	 */
+	if (plane->format->fourcc != DRM_FORMAT_XRGB1555)
+		rcar_du_plane_write(rcdu, index, PnALPHAR, PnALPHAR_ABIT_0);
+	else
+		rcar_du_plane_write(rcdu, index, PnALPHAR,
+				    PnALPHAR_ABIT_X | plane->alpha);
+
+	pnmr = PnMR_BM_MD | plane->format->pnmr;
+
+	/* Disable color keying when requested. YUV formats have the
+	 * PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying
+	 * automatically.
+	 */
+	if ((plane->colorkey & RCAR_DU_COLORKEY_MASK) == RCAR_DU_COLORKEY_NONE)
+		pnmr |= PnMR_SPIM_TP_OFF;
+
+	/* For packed YUV formats we need to select the U/V order. */
+	if (plane->format->fourcc == DRM_FORMAT_YUYV)
+		pnmr |= PnMR_YCDF_YUYV;
+
+	rcar_du_plane_write(rcdu, index, PnMR, pnmr);
+
+	switch (plane->format->fourcc) {
+	case DRM_FORMAT_RGB565:
+		colorkey = ((plane->colorkey & 0xf80000) >> 8)
+			 | ((plane->colorkey & 0x00fc00) >> 5)
+			 | ((plane->colorkey & 0x0000f8) >> 3);
+		rcar_du_plane_write(rcdu, index, PnTC2R, colorkey);
+		break;
+
+	case DRM_FORMAT_ARGB1555:
+	case DRM_FORMAT_XRGB1555:
+		colorkey = ((plane->colorkey & 0xf80000) >> 9)
+			 | ((plane->colorkey & 0x00f800) >> 6)
+			 | ((plane->colorkey & 0x0000f8) >> 3);
+		rcar_du_plane_write(rcdu, index, PnTC2R, colorkey);
+		break;
+
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_ARGB8888:
+		rcar_du_plane_write(rcdu, index, PnTC3R,
+				    PnTC3R_CODE | (plane->colorkey & 0xffffff));
+		break;
+	}
+}
+
+static void __rcar_du_plane_setup(struct rcar_du_plane *plane,
+				  unsigned int index)
+{
+	struct rcar_du_device *rcdu = plane->dev;
+	u32 ddcr2 = PnDDCR2_CODE;
+	u32 ddcr4;
+	u32 mwr;
+
+	/* Data format
+	 *
+	 * The data format is selected by the DDDF field in PnMR and the EDF
+	 * field in DDCR4.
+	 */
+	ddcr4 = rcar_du_plane_read(rcdu, index, PnDDCR4);
+	ddcr4 &= ~PnDDCR4_EDF_MASK;
+	ddcr4 |= plane->format->edf | PnDDCR4_CODE;
+
+	rcar_du_plane_setup_mode(plane, index);
+
+	if (plane->format->planes == 2) {
+		if (plane->hwindex != index) {
+			if (plane->format->fourcc == DRM_FORMAT_NV12 ||
+			    plane->format->fourcc == DRM_FORMAT_NV21)
+				ddcr2 |= PnDDCR2_Y420;
+
+			if (plane->format->fourcc == DRM_FORMAT_NV21)
+				ddcr2 |= PnDDCR2_NV21;
+
+			ddcr2 |= PnDDCR2_DIVU;
+		} else {
+			ddcr2 |= PnDDCR2_DIVY;
+		}
+	}
+
+	rcar_du_plane_write(rcdu, index, PnDDCR2, ddcr2);
+	rcar_du_plane_write(rcdu, index, PnDDCR4, ddcr4);
+
+	/* Memory pitch (expressed in pixels) */
+	if (plane->format->planes == 2)
+		mwr = plane->pitch;
+	else
+		mwr = plane->pitch * 8 / plane->format->bpp;
+
+	rcar_du_plane_write(rcdu, index, PnMWR, mwr);
+
+	/* Destination position and size */
+	rcar_du_plane_write(rcdu, index, PnDSXR, plane->width);
+	rcar_du_plane_write(rcdu, index, PnDSYR, plane->height);
+	rcar_du_plane_write(rcdu, index, PnDPXR, plane->dst_x);
+	rcar_du_plane_write(rcdu, index, PnDPYR, plane->dst_y);
+
+	/* Wrap-around and blinking, disabled */
+	rcar_du_plane_write(rcdu, index, PnWASPR, 0);
+	rcar_du_plane_write(rcdu, index, PnWAMWR, 4095);
+	rcar_du_plane_write(rcdu, index, PnBTR, 0);
+	rcar_du_plane_write(rcdu, index, PnMLR, 0);
+}
+
+void rcar_du_plane_setup(struct rcar_du_plane *plane)
+{
+	__rcar_du_plane_setup(plane, plane->hwindex);
+	if (plane->format->planes == 2)
+		__rcar_du_plane_setup(plane, (plane->hwindex + 1) % 8);
+
+	rcar_du_plane_update_base(plane);
+}
+
+static int
+rcar_du_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
+		       struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+		       unsigned int crtc_w, unsigned int crtc_h,
+		       uint32_t src_x, uint32_t src_y,
+		       uint32_t src_w, uint32_t src_h)
+{
+	struct rcar_du_plane *rplane = to_rcar_plane(plane);
+	struct rcar_du_device *rcdu = plane->dev->dev_private;
+	const struct rcar_du_format_info *format;
+	unsigned int nplanes;
+	int ret;
+
+	format = rcar_du_format_info(fb->pixel_format);
+	if (format == NULL) {
+		dev_dbg(rcdu->dev, "%s: unsupported format %08x\n", __func__,
+			fb->pixel_format);
+		return -EINVAL;
+	}
+
+	if (src_w >> 16 != crtc_w || src_h >> 16 != crtc_h) {
+		dev_dbg(rcdu->dev, "%s: scaling not supported\n", __func__);
+		return -EINVAL;
+	}
+
+	nplanes = rplane->format ? rplane->format->planes : 0;
+
+	/* Reallocate hardware planes if the number of required planes has
+	 * changed.
+	 */
+	if (format->planes != nplanes) {
+		rcar_du_plane_release(rplane);
+		ret = rcar_du_plane_reserve(rplane, format);
+		if (ret < 0)
+			return ret;
+	}
+
+	rplane->crtc = crtc;
+	rplane->format = format;
+	rplane->pitch = fb->pitches[0];
+
+	rplane->src_x = src_x >> 16;
+	rplane->src_y = src_y >> 16;
+	rplane->dst_x = crtc_x;
+	rplane->dst_y = crtc_y;
+	rplane->width = crtc_w;
+	rplane->height = crtc_h;
+
+	rcar_du_plane_compute_base(rplane, fb);
+	rcar_du_plane_setup(rplane);
+
+	mutex_lock(&rcdu->planes.lock);
+	rplane->enabled = true;
+	rcar_du_crtc_update_planes(rplane->crtc);
+	mutex_unlock(&rcdu->planes.lock);
+
+	return 0;
+}
+
+static int rcar_du_plane_disable(struct drm_plane *plane)
+{
+	struct rcar_du_device *rcdu = plane->dev->dev_private;
+	struct rcar_du_plane *rplane = to_rcar_plane(plane);
+
+	if (!rplane->enabled)
+		return 0;
+
+	mutex_lock(&rcdu->planes.lock);
+	rplane->enabled = false;
+	rcar_du_crtc_update_planes(rplane->crtc);
+	mutex_unlock(&rcdu->planes.lock);
+
+	rcar_du_plane_release(rplane);
+
+	rplane->crtc = NULL;
+	rplane->format = NULL;
+
+	return 0;
+}
+
+/* Both the .set_property and the .update_plane operations are called with the
+ * mode_config lock held. There is this no need to explicitly protect access to
+ * the alpha and colorkey fields and the mode register.
+ */
+static void rcar_du_plane_set_alpha(struct rcar_du_plane *plane, u32 alpha)
+{
+	if (plane->alpha == alpha)
+		return;
+
+	plane->alpha = alpha;
+	if (!plane->enabled || plane->format->fourcc != DRM_FORMAT_XRGB1555)
+		return;
+
+	rcar_du_plane_setup_mode(plane, plane->hwindex);
+}
+
+static void rcar_du_plane_set_colorkey(struct rcar_du_plane *plane,
+				       u32 colorkey)
+{
+	if (plane->colorkey == colorkey)
+		return;
+
+	plane->colorkey = colorkey;
+	if (!plane->enabled)
+		return;
+
+	rcar_du_plane_setup_mode(plane, plane->hwindex);
+}
+
+static void rcar_du_plane_set_zpos(struct rcar_du_plane *plane,
+				   unsigned int zpos)
+{
+	struct rcar_du_device *rcdu = plane->dev;
+
+	mutex_lock(&rcdu->planes.lock);
+	if (plane->zpos == zpos)
+		goto done;
+
+	plane->zpos = zpos;
+	if (!plane->enabled)
+		goto done;
+
+	rcar_du_crtc_update_planes(plane->crtc);
+
+done:
+	mutex_unlock(&rcdu->planes.lock);
+}
+
+static int rcar_du_plane_set_property(struct drm_plane *plane,
+				      struct drm_property *property,
+				      uint64_t value)
+{
+	struct rcar_du_device *rcdu = plane->dev->dev_private;
+	struct rcar_du_plane *rplane = to_rcar_plane(plane);
+
+	if (property == rcdu->planes.alpha)
+		rcar_du_plane_set_alpha(rplane, value);
+	else if (property == rcdu->planes.colorkey)
+		rcar_du_plane_set_colorkey(rplane, value);
+	else if (property == rcdu->planes.zpos)
+		rcar_du_plane_set_zpos(rplane, value);
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static const struct drm_plane_funcs rcar_du_plane_funcs = {
+	.update_plane = rcar_du_plane_update,
+	.disable_plane = rcar_du_plane_disable,
+	.set_property = rcar_du_plane_set_property,
+	.destroy = drm_plane_cleanup,
+};
+
+static const uint32_t formats[] = {
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_NV12,
+	DRM_FORMAT_NV21,
+	DRM_FORMAT_NV16,
+};
+
+int rcar_du_plane_init(struct rcar_du_device *rcdu)
+{
+	unsigned int i;
+
+	mutex_init(&rcdu->planes.lock);
+	rcdu->planes.free = 0xff;
+
+	rcdu->planes.alpha =
+		drm_property_create_range(rcdu->ddev, 0, "alpha", 0, 255);
+	if (rcdu->planes.alpha == NULL)
+		return -ENOMEM;
+
+	/* The color key is expressed as an RGB888 triplet stored in a 32-bit
+	 * integer in XRGB8888 format. Bit 24 is used as a flag to disable (0)
+	 * or enable source color keying (1).
+	 */
+	rcdu->planes.colorkey =
+		drm_property_create_range(rcdu->ddev, 0, "colorkey",
+					  0, 0x01ffffff);
+	if (rcdu->planes.colorkey == NULL)
+		return -ENOMEM;
+
+	rcdu->planes.zpos =
+		drm_property_create_range(rcdu->ddev, 0, "zpos", 1, 7);
+	if (rcdu->planes.zpos == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) {
+		struct rcar_du_plane *plane = &rcdu->planes.planes[i];
+
+		plane->dev = rcdu;
+		plane->hwindex = -1;
+		plane->alpha = 255;
+		plane->colorkey = RCAR_DU_COLORKEY_NONE;
+		plane->zpos = 0;
+	}
+
+	return 0;
+}
+
+int rcar_du_plane_register(struct rcar_du_device *rcdu)
+{
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < RCAR_DU_NUM_KMS_PLANES; ++i) {
+		struct rcar_du_kms_plane *plane;
+
+		plane = devm_kzalloc(rcdu->dev, sizeof(*plane), GFP_KERNEL);
+		if (plane == NULL)
+			return -ENOMEM;
+
+		plane->hwplane = &rcdu->planes.planes[i + 2];
+		plane->hwplane->zpos = 1;
+
+		ret = drm_plane_init(rcdu->ddev, &plane->plane,
+				     (1 << rcdu->num_crtcs) - 1,
+				     &rcar_du_plane_funcs, formats,
+				     ARRAY_SIZE(formats), false);
+		if (ret < 0)
+			return ret;
+
+		drm_object_attach_property(&plane->plane.base,
+					   rcdu->planes.alpha, 255);
+		drm_object_attach_property(&plane->plane.base,
+					   rcdu->planes.colorkey,
+					   RCAR_DU_COLORKEY_NONE);
+		drm_object_attach_property(&plane->plane.base,
+					   rcdu->planes.zpos, 1);
+	}
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_plane.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_plane.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_plane.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_plane.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * rcar_du_plane.h  --  R-Car Display Unit Planes
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __RCAR_DU_PLANE_H__
+#define __RCAR_DU_PLANE_H__
+
+struct drm_crtc;
+struct drm_framebuffer;
+struct rcar_du_device;
+struct rcar_du_format_info;
+
+/* The RCAR DU has 8 hardware planes, shared between KMS planes and CRTCs. As
+ * using KMS planes requires at least one of the CRTCs being enabled, no more
+ * than 7 KMS planes can be available. We thus create 7 KMS planes and
+ * 9 software planes (one for each KMS planes and one for each CRTC).
+ */
+
+#define RCAR_DU_NUM_KMS_PLANES		7
+#define RCAR_DU_NUM_HW_PLANES		8
+#define RCAR_DU_NUM_SW_PLANES		9
+
+struct rcar_du_plane {
+	struct rcar_du_device *dev;
+	struct drm_crtc *crtc;
+
+	bool enabled;
+
+	int hwindex;		/* 0-based, -1 means unused */
+	unsigned int alpha;
+	unsigned int colorkey;
+	unsigned int zpos;
+
+	const struct rcar_du_format_info *format;
+
+	unsigned long dma[2];
+	unsigned int pitch;
+
+	unsigned int width;
+	unsigned int height;
+
+	unsigned int src_x;
+	unsigned int src_y;
+	unsigned int dst_x;
+	unsigned int dst_y;
+};
+
+int rcar_du_plane_init(struct rcar_du_device *rcdu);
+int rcar_du_plane_register(struct rcar_du_device *rcdu);
+void rcar_du_plane_setup(struct rcar_du_plane *plane);
+void rcar_du_plane_update_base(struct rcar_du_plane *plane);
+void rcar_du_plane_compute_base(struct rcar_du_plane *plane,
+				struct drm_framebuffer *fb);
+int rcar_du_plane_reserve(struct rcar_du_plane *plane,
+			  const struct rcar_du_format_info *format);
+void rcar_du_plane_release(struct rcar_du_plane *plane);
+
+#endif /* __RCAR_DU_PLANE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_regs.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_regs.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,445 @@
+/*
+ * rcar_du_regs.h  --  R-Car Display Unit Registers Definitions
+ *
+ * Copyright (C) 2013 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef __RCAR_DU_REGS_H__
+#define __RCAR_DU_REGS_H__
+
+#define DISP2_REG_OFFSET	 0x30000
+
+/* -----------------------------------------------------------------------------
+ * Display Control Registers
+ */
+
+#define DSYSR			0x00000	/* display 1 */
+#define D2SYSR			0x30000	/* display 2 */
+#define DSYSR_ILTS		(1 << 29)
+#define DSYSR_DSEC		(1 << 20)
+#define DSYSR_IUPD		(1 << 16)
+#define DSYSR_DRES		(1 << 9)
+#define DSYSR_DEN		(1 << 8)
+#define DSYSR_TVM_MASTER	(0 << 6)
+#define DSYSR_TVM_SWITCH	(1 << 6)
+#define DSYSR_TVM_TVSYNC	(2 << 6)
+#define DSYSR_TVM_MASK		(3 << 6)
+#define DSYSR_SCM_INT_NONE	(0 << 4)
+#define DSYSR_SCM_INT_SYNC	(2 << 4)
+#define DSYSR_SCM_INT_VIDEO	(3 << 4)
+
+#define DSMR			0x00004
+#define D2SMR			0x30004
+#define DSMR_VSPM		(1 << 28)
+#define DSMR_ODPM		(1 << 27)
+#define DSMR_DIPM_DISP		(0 << 25)
+#define DSMR_DIPM_CSYNC		(1 << 25)
+#define DSMR_DIPM_DE		(3 << 25)
+#define DSMR_DIPM_MASK		(3 << 25)
+#define DSMR_CSPM		(1 << 24)
+#define DSMR_DIL		(1 << 19)
+#define DSMR_VSL		(1 << 18)
+#define DSMR_HSL		(1 << 17)
+#define DSMR_DDIS		(1 << 16)
+#define DSMR_CDEL		(1 << 15)
+#define DSMR_CDEM_CDE		(0 << 13)
+#define DSMR_CDEM_LOW		(2 << 13)
+#define DSMR_CDEM_HIGH		(3 << 13)
+#define DSMR_CDEM_MASK		(3 << 13)
+#define DSMR_CDED		(1 << 12)
+#define DSMR_ODEV		(1 << 8)
+#define DSMR_CSY_VH_OR		(0 << 6)
+#define DSMR_CSY_333		(2 << 6)
+#define DSMR_CSY_222		(3 << 6)
+#define DSMR_CSY_MASK		(3 << 6)
+
+#define DSSR			0x00008
+#define D2SSR			0x30008
+#define DSSR_VC1FB_DSA0		(0 << 30)
+#define DSSR_VC1FB_DSA1		(1 << 30)
+#define DSSR_VC1FB_DSA2		(2 << 30)
+#define DSSR_VC1FB_INIT		(3 << 30)
+#define DSSR_VC1FB_MASK		(3 << 30)
+#define DSSR_VC0FB_DSA0		(0 << 28)
+#define DSSR_VC0FB_DSA1		(1 << 28)
+#define DSSR_VC0FB_DSA2		(2 << 28)
+#define DSSR_VC0FB_INIT		(3 << 28)
+#define DSSR_VC0FB_MASK		(3 << 28)
+#define DSSR_DFB(n)		(1 << ((n)+15))
+#define DSSR_TVR		(1 << 15)
+#define DSSR_FRM		(1 << 14)
+#define DSSR_VBK		(1 << 11)
+#define DSSR_RINT		(1 << 9)
+#define DSSR_HBK		(1 << 8)
+#define DSSR_ADC(n)		(1 << ((n)-1))
+
+#define DSRCR			0x0000c
+#define D2SRCR			0x3000c
+#define DSRCR_TVCL		(1 << 15)
+#define DSRCR_FRCL		(1 << 14)
+#define DSRCR_VBCL		(1 << 11)
+#define DSRCR_RICL		(1 << 9)
+#define DSRCR_HBCL		(1 << 8)
+#define DSRCR_ADCL(n)		(1 << ((n)-1))
+#define DSRCR_MASK		0x0000cbff
+
+#define DIER			0x00010
+#define D2IER			0x30010
+#define DIER_TVE		(1 << 15)
+#define DIER_FRE		(1 << 14)
+#define DIER_VBE		(1 << 11)
+#define DIER_RIE		(1 << 9)
+#define DIER_HBE		(1 << 8)
+#define DIER_ADCE(n)		(1 << ((n)-1))
+
+#define CPCR			0x00014
+#define CPCR_CP4CE		(1 << 19)
+#define CPCR_CP3CE		(1 << 18)
+#define CPCR_CP2CE		(1 << 17)
+#define CPCR_CP1CE		(1 << 16)
+
+#define DPPR			0x00018
+#define DPPR_DPE(n)		(1 << ((n)*4-1))
+#define DPPR_DPS(n, p)		(((p)-1) << DPPR_DPS_SHIFT(n))
+#define DPPR_DPS_SHIFT(n)	(((n)-1)*4)
+#define DPPR_BPP16		(DPPR_DPE(8) | DPPR_DPS(8, 1))	/* plane1 */
+#define DPPR_BPP32_P1		(DPPR_DPE(7) | DPPR_DPS(7, 1))
+#define DPPR_BPP32_P2		(DPPR_DPE(8) | DPPR_DPS(8, 2))
+#define DPPR_BPP32		(DPPR_BPP32_P1 | DPPR_BPP32_P2)	/* plane1 & 2 */
+
+#define DEFR			0x00020
+#define D2EFR			0x30020
+#define DEFR_CODE		(0x7773 << 16)
+#define DEFR_EXSL		(1 << 12)
+#define DEFR_EXVL		(1 << 11)
+#define DEFR_EXUP		(1 << 5)
+#define DEFR_VCUP		(1 << 4)
+#define DEFR_DEFE		(1 << 0)
+
+#define DAPCR			0x00024
+#define DAPCR_CODE		(0x7773 << 16)
+#define DAPCR_AP2E		(1 << 4)
+#define DAPCR_AP1E		(1 << 0)
+
+#define DCPCR			0x00028
+#define DCPCR_CODE		(0x7773 << 16)
+#define DCPCR_CA2B		(1 << 13)
+#define DCPCR_CD2F		(1 << 12)
+#define DCPCR_DC2E		(1 << 8)
+#define DCPCR_CAB		(1 << 5)
+#define DCPCR_CDF		(1 << 4)
+#define DCPCR_DCE		(1 << 0)
+
+#define DEFR2			0x00034
+#define D2EFR2			0x30034
+#define DEFR2_CODE		(0x7775 << 16)
+#define DEFR2_DEFE2G		(1 << 0)
+
+#define DEFR3			0x00038
+#define D2EFR3			0x30038
+#define DEFR3_CODE		(0x7776 << 16)
+#define DEFR3_EVDA		(1 << 14)
+#define DEFR3_EVDM_1		(1 << 12)
+#define DEFR3_EVDM_2		(2 << 12)
+#define DEFR3_EVDM_3		(3 << 12)
+#define DEFR3_VMSM2_EMA		(1 << 6)
+#define DEFR3_VMSM1_ENA		(1 << 4)
+#define DEFR3_DEFE3		(1 << 0)
+
+#define DEFR4			0x0003c
+#define D2EFR4			0x3003c
+#define DEFR4_CODE		(0x7777 << 16)
+#define DEFR4_LRUO		(1 << 5)
+#define DEFR4_SPCE		(1 << 4)
+
+#define DVCSR			0x000d0
+#define DVCSR_VCnFB2_DSA0(n)	(0 << ((n)*2+16))
+#define DVCSR_VCnFB2_DSA1(n)	(1 << ((n)*2+16))
+#define DVCSR_VCnFB2_DSA2(n)	(2 << ((n)*2+16))
+#define DVCSR_VCnFB2_INIT(n)	(3 << ((n)*2+16))
+#define DVCSR_VCnFB2_MASK(n)	(3 << ((n)*2+16))
+#define DVCSR_VCnFB_DSA0(n)	(0 << ((n)*2))
+#define DVCSR_VCnFB_DSA1(n)	(1 << ((n)*2))
+#define DVCSR_VCnFB_DSA2(n)	(2 << ((n)*2))
+#define DVCSR_VCnFB_INIT(n)	(3 << ((n)*2))
+#define DVCSR_VCnFB_MASK(n)	(3 << ((n)*2))
+
+#define DEFR5			0x000e0
+#define DEFR5_CODE		(0x66 << 24)
+#define DEFR5_YCRGB2_DIS	(0 << 14)
+#define DEFR5_YCRGB2_PRI1	(1 << 14)
+#define DEFR5_YCRGB2_PRI2	(2 << 14)
+#define DEFR5_YCRGB2_PRI3	(3 << 14)
+#define DEFR5_YCRGB2_MASK	(3 << 14)
+#define DEFR5_YCRGB1_DIS	(0 << 12)
+#define DEFR5_YCRGB1_PRI1	(1 << 12)
+#define DEFR5_YCRGB1_PRI2	(2 << 12)
+#define DEFR5_YCRGB1_PRI3	(3 << 12)
+#define DEFR5_YCRGB1_MASK	(3 << 12)
+#define DEFR5_DEFE5		(1 << 0)
+
+#define DDLTR			0x000e4
+#define DDLTR_CODE		(0x7766 << 16)
+#define DDLTR_DLAR2		(1 << 6)
+#define DDLTR_DLAY2		(1 << 5)
+#define DDLTR_DLAY1		(1 << 1)
+
+#define DEFR6			0x000e8
+#define DEFR6_CODE		(0x7778 << 16)
+#define DEFR6_ODPM22_D2SMR	(0 << 10)
+#define DEFR6_ODPM22_DISP	(2 << 10)
+#define DEFR6_ODPM22_CDE	(3 << 10)
+#define DEFR6_ODPM22_MASK	(3 << 10)
+#define DEFR6_ODPM12_DSMR	(0 << 8)
+#define DEFR6_ODPM12_DISP	(2 << 8)
+#define DEFR6_ODPM12_CDE	(3 << 8)
+#define DEFR6_ODPM12_MASK	(3 << 8)
+#define DEFR6_TCNE2		(1 << 6)
+#define DEFR6_MLOS1		(1 << 2)
+#define DEFR6_DEFAULT		(DEFR6_CODE | DEFR6_TCNE2)
+
+/* -----------------------------------------------------------------------------
+ * Display Timing Generation Registers
+ */
+
+#define HDSR			0x00040
+#define HDER			0x00044
+#define VDSR			0x00048
+#define VDER			0x0004c
+#define HCR			0x00050
+#define HSWR			0x00054
+#define VCR			0x00058
+#define VSPR			0x0005c
+#define EQWR			0x00060
+#define SPWR			0x00064
+#define CLAMPSR			0x00070
+#define CLAMPWR			0x00074
+#define DESR			0x00078
+#define DEWR			0x0007c
+
+/* -----------------------------------------------------------------------------
+ * Display Attribute Registers
+ */
+
+#define CP1TR			0x00080
+#define CP2TR			0x00084
+#define CP3TR			0x00088
+#define CP4TR			0x0008c
+
+#define DOOR			0x00090
+#define DOOR_RGB(r, g, b)	(((r) << 18) | ((g) << 10) | ((b) << 2))
+#define CDER			0x00094
+#define CDER_RGB(r, g, b)	(((r) << 18) | ((g) << 10) | ((b) << 2))
+#define BPOR			0x00098
+#define BPOR_RGB(r, g, b)	(((r) << 18) | ((g) << 10) | ((b) << 2))
+
+#define RINTOFSR		0x0009c
+
+#define DSHPR			0x000c8
+#define DSHPR_CODE		(0x7776 << 16)
+#define DSHPR_PRIH		(0xa << 4)
+#define DSHPR_PRIL_BPP16	(0x8 << 0)
+#define DSHPR_PRIL_BPP32	(0x9 << 0)
+
+/* -----------------------------------------------------------------------------
+ * Display Plane Registers
+ */
+
+#define PLANE_OFF		0x00100
+
+#define PnMR			0x00100 /* plane 1 */
+#define PnMR_VISL_VIN0		(0 << 26)	/* use Video Input 0 */
+#define PnMR_VISL_VIN1		(1 << 26)	/* use Video Input 1 */
+#define PnMR_VISL_VIN2		(2 << 26)	/* use Video Input 2 */
+#define PnMR_VISL_VIN3		(3 << 26)	/* use Video Input 3 */
+#define PnMR_YCDF_YUYV		(1 << 20)	/* YUYV format */
+#define PnMR_TC_R		(0 << 17)	/* Tranparent color is PnTC1R */
+#define PnMR_TC_CP		(1 << 17)	/* Tranparent color is color palette */
+#define PnMR_WAE		(1 << 16)	/* Wrap around Enable */
+#define PnMR_SPIM_TP		(0 << 12)	/* Transparent Color */
+#define PnMR_SPIM_ALP		(1 << 12)	/* Alpha Blending */
+#define PnMR_SPIM_EOR		(2 << 12)	/* EOR */
+#define PnMR_SPIM_TP_OFF	(1 << 14)	/* No Transparent Color */
+#define PnMR_CPSL_CP1		(0 << 8)	/* Color Palette selected 1 */
+#define PnMR_CPSL_CP2		(1 << 8)	/* Color Palette selected 2 */
+#define PnMR_CPSL_CP3		(2 << 8)	/* Color Palette selected 3 */
+#define PnMR_CPSL_CP4		(3 << 8)	/* Color Palette selected 4 */
+#define PnMR_DC			(1 << 7)	/* Display Area Change */
+#define PnMR_BM_MD		(0 << 4)	/* Manual Display Change Mode */
+#define PnMR_BM_AR		(1 << 4)	/* Auto Rendering Mode */
+#define PnMR_BM_AD		(2 << 4)	/* Auto Display Change Mode */
+#define PnMR_BM_VC		(3 << 4)	/* Video Capture Mode */
+#define PnMR_DDDF_8BPP		(0 << 0)	/* 8bit */
+#define PnMR_DDDF_16BPP		(1 << 0)	/* 16bit or 32bit */
+#define PnMR_DDDF_ARGB		(2 << 0)	/* ARGB */
+#define PnMR_DDDF_YC		(3 << 0)	/* YC */
+#define PnMR_DDDF_MASK		(3 << 0)
+
+#define PnMWR			0x00104
+
+#define PnALPHAR		0x00108
+#define PnALPHAR_ABIT_1		(0 << 12)
+#define PnALPHAR_ABIT_0		(1 << 12)
+#define PnALPHAR_ABIT_X		(2 << 12)
+
+#define PnDSXR			0x00110
+#define PnDSYR			0x00114
+#define PnDPXR			0x00118
+#define PnDPYR			0x0011c
+
+#define PnDSA0R			0x00120
+#define PnDSA1R			0x00124
+#define PnDSA2R			0x00128
+#define PnDSA_MASK		0xfffffff0
+
+#define PnSPXR			0x00130
+#define PnSPYR			0x00134
+#define PnWASPR			0x00138
+#define PnWAMWR			0x0013c
+
+#define PnBTR			0x00140
+
+#define PnTC1R			0x00144
+#define PnTC2R			0x00148
+#define PnTC3R			0x0014c
+#define PnTC3R_CODE		(0x66 << 24)
+
+#define PnMLR			0x00150
+
+#define PnSWAPR			0x00180
+#define PnSWAPR_DIGN		(1 << 4)
+#define PnSWAPR_SPQW		(1 << 3)
+#define PnSWAPR_SPLW		(1 << 2)
+#define PnSWAPR_SPWD		(1 << 1)
+#define PnSWAPR_SPBY		(1 << 0)
+
+#define PnDDCR			0x00184
+#define PnDDCR_CODE		(0x7775 << 16)
+#define PnDDCR_LRGB1		(1 << 11)
+#define PnDDCR_LRGB0		(1 << 10)
+
+#define PnDDCR2			0x00188
+#define PnDDCR2_CODE		(0x7776 << 16)
+#define PnDDCR2_NV21		(1 << 5)
+#define PnDDCR2_Y420		(1 << 4)
+#define PnDDCR2_DIVU		(1 << 1)
+#define PnDDCR2_DIVY		(1 << 0)
+
+#define PnDDCR4			0x00190
+#define PnDDCR4_CODE		(0x7766 << 16)
+#define PnDDCR4_SDFS_RGB	(0 << 4)
+#define PnDDCR4_SDFS_YC		(5 << 4)
+#define PnDDCR4_SDFS_MASK	(7 << 4)
+#define PnDDCR4_EDF_NONE	(0 << 0)
+#define PnDDCR4_EDF_ARGB8888	(1 << 0)
+#define PnDDCR4_EDF_RGB888	(2 << 0)
+#define PnDDCR4_EDF_RGB666	(3 << 0)
+#define PnDDCR4_EDF_MASK	(7 << 0)
+
+#define APnMR			0x0a100
+#define APnMR_WAE		(1 << 16)	/* Wrap around Enable */
+#define APnMR_DC		(1 << 7)	/* Display Area Change */
+#define APnMR_BM_MD		(0 << 4)	/* Manual Display Change Mode */
+#define APnMR_BM_AD		(2 << 4)	/* Auto Display Change Mode */
+
+#define APnMWR			0x0a104
+#define APnDSA0R		0x0a120
+#define APnDSA1R		0x0a124
+#define APnDSA2R		0x0a128
+#define APnMLR			0x0a150
+
+/* -----------------------------------------------------------------------------
+ * Display Capture Registers
+ */
+
+#define DCMWR			0x0c104
+#define DC2MWR			0x0c204
+#define DCSAR			0x0c120
+#define DC2SAR			0x0c220
+#define DCMLR			0x0c150
+#define DC2MLR			0x0c250
+
+/* -----------------------------------------------------------------------------
+ * Color Palette Registers
+ */
+
+#define CP1_000R		0x01000
+#define CP1_255R		0x013fc
+#define CP2_000R		0x02000
+#define CP2_255R		0x023fc
+#define CP3_000R		0x03000
+#define CP3_255R		0x033fc
+#define CP4_000R		0x04000
+#define CP4_255R		0x043fc
+
+/* -----------------------------------------------------------------------------
+ * External Synchronization Control Registers
+ */
+
+#define ESCR			0x10000
+#define ESCR2			0x31000
+#define ESCR_DCLKOINV		(1 << 25)
+#define ESCR_DCLKSEL_DCLKIN	(0 << 20)
+#define ESCR_DCLKSEL_CLKS	(1 << 20)
+#define ESCR_DCLKSEL_MASK	(1 << 20)
+#define ESCR_DCLKDIS		(1 << 16)
+#define ESCR_SYNCSEL_OFF	(0 << 8)
+#define ESCR_SYNCSEL_EXVSYNC	(2 << 8)
+#define ESCR_SYNCSEL_EXHSYNC	(3 << 8)
+#define ESCR_FRQSEL_MASK	(0x3f << 0)
+
+#define OTAR			0x10004
+#define OTAR2			0x31004
+
+/* -----------------------------------------------------------------------------
+ * Dual Display Output Control Registers
+ */
+
+#define DORCR			0x11000
+#define DORCR_PG2T		(1 << 30)
+#define DORCR_DK2S		(1 << 28)
+#define DORCR_PG2D_DS1		(0 << 24)
+#define DORCR_PG2D_DS2		(1 << 24)
+#define DORCR_PG2D_FIX0		(2 << 24)
+#define DORCR_PG2D_DOOR		(3 << 24)
+#define DORCR_PG2D_MASK		(3 << 24)
+#define DORCR_DR1D		(1 << 21)
+#define DORCR_PG1D_DS1		(0 << 16)
+#define DORCR_PG1D_DS2		(1 << 16)
+#define DORCR_PG1D_FIX0		(2 << 16)
+#define DORCR_PG1D_DOOR		(3 << 16)
+#define DORCR_PG1D_MASK		(3 << 16)
+#define DORCR_RGPV		(1 << 4)
+#define DORCR_DPRS		(1 << 0)
+
+#define DPTSR			0x11004
+#define DPTSR_PnDK(n)		(1 << ((n) + 16))
+#define DPTSR_PnTS(n)		(1 << (n))
+
+#define DAPTSR			0x11008
+#define DAPTSR_APnDK(n)		(1 << ((n) + 16))
+#define DAPTSR_APnTS(n)		(1 << (n))
+
+#define DS1PR			0x11020
+#define DS2PR			0x11024
+
+/* -----------------------------------------------------------------------------
+ * YC-RGB Conversion Coefficient Registers
+ */
+
+#define YNCR			0x11080
+#define YNOR			0x11084
+#define CRNOR			0x11088
+#define CBNOR			0x1108c
+#define RCRCR			0x11090
+#define GCRCR			0x11094
+#define GCBCR			0x11098
+#define BCBCR			0x1109c
+
+#endif /* __RCAR_DU_REGS_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_vga.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_vga.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_vga.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_vga.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,149 @@
+/*
+ * rcar_du_vga.c  --  R-Car Display Unit VGA DAC and Connector
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "rcar_du_drv.h"
+#include "rcar_du_kms.h"
+#include "rcar_du_vga.h"
+
+/* -----------------------------------------------------------------------------
+ * Connector
+ */
+
+static int rcar_du_vga_connector_get_modes(struct drm_connector *connector)
+{
+	return 0;
+}
+
+static int rcar_du_vga_connector_mode_valid(struct drm_connector *connector,
+					    struct drm_display_mode *mode)
+{
+	return MODE_OK;
+}
+
+static const struct drm_connector_helper_funcs connector_helper_funcs = {
+	.get_modes = rcar_du_vga_connector_get_modes,
+	.mode_valid = rcar_du_vga_connector_mode_valid,
+	.best_encoder = rcar_du_connector_best_encoder,
+};
+
+static void rcar_du_vga_connector_destroy(struct drm_connector *connector)
+{
+	drm_sysfs_connector_remove(connector);
+	drm_connector_cleanup(connector);
+}
+
+static enum drm_connector_status
+rcar_du_vga_connector_detect(struct drm_connector *connector, bool force)
+{
+	return connector_status_unknown;
+}
+
+static const struct drm_connector_funcs connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.detect = rcar_du_vga_connector_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = rcar_du_vga_connector_destroy,
+};
+
+static int rcar_du_vga_connector_init(struct rcar_du_device *rcdu,
+				      struct rcar_du_encoder *renc)
+{
+	struct rcar_du_connector *rcon;
+	struct drm_connector *connector;
+	int ret;
+
+	rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL);
+	if (rcon == NULL)
+		return -ENOMEM;
+
+	connector = &rcon->connector;
+	connector->display_info.width_mm = 0;
+	connector->display_info.height_mm = 0;
+
+	ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
+				 DRM_MODE_CONNECTOR_VGA);
+	if (ret < 0)
+		return ret;
+
+	drm_connector_helper_add(connector, &connector_helper_funcs);
+	ret = drm_sysfs_connector_add(connector);
+	if (ret < 0)
+		return ret;
+
+	drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+	drm_object_property_set_value(&connector->base,
+		rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF);
+
+	ret = drm_mode_connector_attach_encoder(connector, &renc->encoder);
+	if (ret < 0)
+		return ret;
+
+	connector->encoder = &renc->encoder;
+	rcon->encoder = renc;
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Encoder
+ */
+
+static void rcar_du_vga_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static bool rcar_du_vga_encoder_mode_fixup(struct drm_encoder *encoder,
+					   const struct drm_display_mode *mode,
+					   struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
+	.dpms = rcar_du_vga_encoder_dpms,
+	.mode_fixup = rcar_du_vga_encoder_mode_fixup,
+	.prepare = rcar_du_encoder_mode_prepare,
+	.commit = rcar_du_encoder_mode_commit,
+	.mode_set = rcar_du_encoder_mode_set,
+};
+
+static const struct drm_encoder_funcs encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+int rcar_du_vga_init(struct rcar_du_device *rcdu,
+		     const struct rcar_du_encoder_vga_data *data,
+		     unsigned int output)
+{
+	struct rcar_du_encoder *renc;
+	int ret;
+
+	renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL);
+	if (renc == NULL)
+		return -ENOMEM;
+
+	renc->output = output;
+
+	ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs,
+			       DRM_MODE_ENCODER_DAC);
+	if (ret < 0)
+		return ret;
+
+	drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs);
+
+	return rcar_du_vga_connector_init(rcdu, renc);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_vga.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_vga.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/rcar-du/rcar_du_vga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/rcar-du/rcar_du_vga.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * rcar_du_vga.h  --  R-Car Display Unit VGA DAC and Connector
+ *
+ * Copyright (C) 2013 Renesas Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __RCAR_DU_VGA_H__
+#define __RCAR_DU_VGA_H__
+
+struct rcar_du_device;
+struct rcar_du_encoder_vga_data;
+
+int rcar_du_vga_init(struct rcar_du_device *rcdu,
+		     const struct rcar_du_encoder_vga_data *data,
+		     unsigned int output);
+
+#endif /* __RCAR_DU_VGA_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/savage/savage_bci.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/savage/savage_bci.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/savage/savage_bci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/savage/savage_bci.c	2013-08-25 20:43:22.000000000 -0400
@@ -570,9 +570,6 @@ int savage_driver_firstopen(struct drm_d
 	unsigned int fb_rsrc, aper_rsrc;
 	int ret = 0;
 
-	dev_priv->mtrr[0].handle = -1;
-	dev_priv->mtrr[1].handle = -1;
-	dev_priv->mtrr[2].handle = -1;
 	if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
 		fb_rsrc = 0;
 		fb_base = pci_resource_start(dev->pdev, 0);
@@ -584,21 +581,14 @@ int savage_driver_firstopen(struct drm_d
 		if (pci_resource_len(dev->pdev, 0) == 0x08000000) {
 			/* Don't make MMIO write-cobining! We need 3
 			 * MTRRs. */
-			dev_priv->mtrr[0].base = fb_base;
-			dev_priv->mtrr[0].size = 0x01000000;
-			dev_priv->mtrr[0].handle =
-			    drm_mtrr_add(dev_priv->mtrr[0].base,
-				         dev_priv->mtrr[0].size, DRM_MTRR_WC);
-			dev_priv->mtrr[1].base = fb_base + 0x02000000;
-			dev_priv->mtrr[1].size = 0x02000000;
-			dev_priv->mtrr[1].handle =
-			    drm_mtrr_add(dev_priv->mtrr[1].base,
-					 dev_priv->mtrr[1].size, DRM_MTRR_WC);
-			dev_priv->mtrr[2].base = fb_base + 0x04000000;
-			dev_priv->mtrr[2].size = 0x04000000;
-			dev_priv->mtrr[2].handle =
-			    drm_mtrr_add(dev_priv->mtrr[2].base,
-					 dev_priv->mtrr[2].size, DRM_MTRR_WC);
+			dev_priv->mtrr_handles[0] =
+				arch_phys_wc_add(fb_base, 0x01000000);
+			dev_priv->mtrr_handles[1] =
+				arch_phys_wc_add(fb_base + 0x02000000,
+						 0x02000000);
+			dev_priv->mtrr_handles[2] =
+				arch_phys_wc_add(fb_base + 0x04000000,
+						0x04000000);
 		} else {
 			DRM_ERROR("strange pci_resource_len %08llx\n",
 				  (unsigned long long)
@@ -616,11 +606,9 @@ int savage_driver_firstopen(struct drm_d
 		if (pci_resource_len(dev->pdev, 1) == 0x08000000) {
 			/* Can use one MTRR to cover both fb and
 			 * aperture. */
-			dev_priv->mtrr[0].base = fb_base;
-			dev_priv->mtrr[0].size = 0x08000000;
-			dev_priv->mtrr[0].handle =
-			    drm_mtrr_add(dev_priv->mtrr[0].base,
-					 dev_priv->mtrr[0].size, DRM_MTRR_WC);
+			dev_priv->mtrr_handles[0] =
+				arch_phys_wc_add(fb_base,
+						 0x08000000);
 		} else {
 			DRM_ERROR("strange pci_resource_len %08llx\n",
 				  (unsigned long long)
@@ -660,11 +648,10 @@ void savage_driver_lastclose(struct drm_
 	drm_savage_private_t *dev_priv = dev->dev_private;
 	int i;
 
-	for (i = 0; i < 3; ++i)
-		if (dev_priv->mtrr[i].handle >= 0)
-			drm_mtrr_del(dev_priv->mtrr[i].handle,
-				 dev_priv->mtrr[i].base,
-				 dev_priv->mtrr[i].size, DRM_MTRR_WC);
+	for (i = 0; i < 3; ++i) {
+		arch_phys_wc_del(dev_priv->mtrr_handles[i]);
+		dev_priv->mtrr_handles[i] = 0;
+	}
 }
 
 int savage_driver_unload(struct drm_device *dev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/savage/savage_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/savage/savage_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/savage/savage_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/savage/savage_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -160,10 +160,7 @@ typedef struct drm_savage_private {
 	drm_local_map_t *cmd_dma;
 	drm_local_map_t fake_dma;
 
-	struct {
-		int handle;
-		unsigned long base, size;
-	} mtrr[3];
+	int mtrr_handles[3];
 
 	/* BCI and status-related stuff */
 	volatile uint32_t *status_ptr, *bci_ptr;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/shmobile/Kconfig linux-libre-3.11-rc7-gnu/drivers/gpu/drm/shmobile/Kconfig
--- linux-libre-3.10-gnu/drivers/gpu/drm/shmobile/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/shmobile/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 config DRM_SHMOBILE
 	tristate "DRM Support for SH Mobile"
-	depends on DRM && (SUPERH || ARCH_SHMOBILE)
+	depends on DRM && (ARM || SUPERH)
 	select DRM_KMS_HELPER
 	select DRM_KMS_CMA_HELPER
 	select DRM_GEM_CMA_HELPER
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/shmobile/shmob_drm_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/shmobile/shmob_drm_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/shmobile/shmob_drm_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/shmobile/shmob_drm_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -90,7 +90,7 @@ static int shmob_drm_setup_clocks(struct
 		return -EINVAL;
 	}
 
-	clk = clk_get(sdev->dev, clkname);
+	clk = devm_clk_get(sdev->dev, clkname);
 	if (IS_ERR(clk)) {
 		dev_err(sdev->dev, "cannot get dot clock %s\n", clkname);
 		return PTR_ERR(clk);
@@ -106,21 +106,12 @@ static int shmob_drm_setup_clocks(struct
 
 static int shmob_drm_unload(struct drm_device *dev)
 {
-	struct shmob_drm_device *sdev = dev->dev_private;
-
 	drm_kms_helper_poll_fini(dev);
 	drm_mode_config_cleanup(dev);
 	drm_vblank_cleanup(dev);
 	drm_irq_uninstall(dev);
 
-	if (sdev->clock)
-		clk_put(sdev->clock);
-
-	if (sdev->mmio)
-		iounmap(sdev->mmio);
-
 	dev->dev_private = NULL;
-	kfree(sdev);
 
 	return 0;
 }
@@ -139,7 +130,7 @@ static int shmob_drm_load(struct drm_dev
 		return -EINVAL;
 	}
 
-	sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
+	sdev = devm_kzalloc(&pdev->dev, sizeof(*sdev), GFP_KERNEL);
 	if (sdev == NULL) {
 		dev_err(dev->dev, "failed to allocate private data\n");
 		return -ENOMEM;
@@ -156,29 +147,28 @@ static int shmob_drm_load(struct drm_dev
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
 		dev_err(&pdev->dev, "failed to get memory resource\n");
-		ret = -EINVAL;
-		goto done;
+		return -EINVAL;
 	}
 
-	sdev->mmio = ioremap_nocache(res->start, resource_size(res));
+	sdev->mmio = devm_ioremap_nocache(&pdev->dev, res->start,
+					  resource_size(res));
 	if (sdev->mmio == NULL) {
 		dev_err(&pdev->dev, "failed to remap memory resource\n");
-		ret = -ENOMEM;
-		goto done;
+		return -ENOMEM;
 	}
 
 	ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
 	if (ret < 0)
-		goto done;
+		return ret;
 
 	ret = shmob_drm_init_interface(sdev);
 	if (ret < 0)
-		goto done;
+		return ret;
 
 	ret = shmob_drm_modeset_init(sdev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to initialize mode setting\n");
-		goto done;
+		return ret;
 	}
 
 	for (i = 0; i < 4; ++i) {
@@ -273,7 +263,8 @@ static const struct file_operations shmo
 };
 
 static struct drm_driver shmob_drm_driver = {
-	.driver_features	= DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET,
+	.driver_features	= DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET
+				| DRIVER_PRIME,
 	.load			= shmob_drm_load,
 	.unload			= shmob_drm_unload,
 	.preclose		= shmob_drm_preclose,
@@ -283,6 +274,15 @@ static struct drm_driver shmob_drm_drive
 	.disable_vblank		= shmob_drm_disable_vblank,
 	.gem_free_object	= drm_gem_cma_free_object,
 	.gem_vm_ops		= &drm_gem_cma_vm_ops,
+	.prime_handle_to_fd	= drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle	= drm_gem_prime_fd_to_handle,
+	.gem_prime_import	= drm_gem_prime_import,
+	.gem_prime_export	= drm_gem_prime_export,
+	.gem_prime_get_sg_table	= drm_gem_cma_prime_get_sg_table,
+	.gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+	.gem_prime_vmap		= drm_gem_cma_prime_vmap,
+	.gem_prime_vunmap	= drm_gem_cma_prime_vunmap,
+	.gem_prime_mmap		= drm_gem_cma_prime_mmap,
 	.dumb_create		= drm_gem_cma_dumb_create,
 	.dumb_map_offset	= drm_gem_cma_dumb_map_offset,
 	.dumb_destroy		= drm_gem_cma_dumb_destroy,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/shmobile/shmob_drm_kms.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/shmobile/shmob_drm_kms.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/shmobile/shmob_drm_kms.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/shmobile/shmob_drm_kms.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,7 +116,7 @@ shmob_drm_fb_create(struct drm_device *d
 	}
 
 	if (mode_cmd->pitches[0] & 7 || mode_cmd->pitches[0] >= 65536) {
-		dev_dbg(dev->dev, "valid pitch value %u\n",
+		dev_dbg(dev->dev, "invalid pitch value %u\n",
 			mode_cmd->pitches[0]);
 		return ERR_PTR(-EINVAL);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/shmobile/shmob_drm_plane.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/shmobile/shmob_drm_plane.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/shmobile/shmob_drm_plane.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/shmobile/shmob_drm_plane.c	2013-08-25 20:43:22.000000000 -0400
@@ -166,7 +166,7 @@ void shmob_drm_plane_setup(struct drm_pl
 {
 	struct shmob_drm_plane *splane = to_shmob_plane(plane);
 
-	if (plane->fb == NULL || !plane->enabled)
+	if (plane->fb == NULL)
 		return;
 
 	__shmob_drm_plane_setup(splane, plane->fb);
@@ -221,11 +221,8 @@ static int shmob_drm_plane_disable(struc
 
 static void shmob_drm_plane_destroy(struct drm_plane *plane)
 {
-	struct shmob_drm_plane *splane = to_shmob_plane(plane);
-
 	shmob_drm_plane_disable(plane);
 	drm_plane_cleanup(plane);
-	kfree(splane);
 }
 
 static const struct drm_plane_funcs shmob_drm_plane_funcs = {
@@ -251,7 +248,7 @@ int shmob_drm_plane_create(struct shmob_
 	struct shmob_drm_plane *splane;
 	int ret;
 
-	splane = kzalloc(sizeof(*splane), GFP_KERNEL);
+	splane = devm_kzalloc(sdev->dev, sizeof(*splane), GFP_KERNEL);
 	if (splane == NULL)
 		return -ENOMEM;
 
@@ -261,8 +258,6 @@ int shmob_drm_plane_create(struct shmob_
 	ret = drm_plane_init(sdev->ddev, &splane->plane, 1,
 			     &shmob_drm_plane_funcs, formats,
 			     ARRAY_SIZE(formats), false);
-	if (ret < 0)
-		kfree(splane);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_crtc.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_crtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_crtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,7 +42,8 @@ struct tilcdc_crtc {
 
 static void unref_worker(struct work_struct *work)
 {
-	struct tilcdc_crtc *tilcdc_crtc = container_of(work, struct tilcdc_crtc, work);
+	struct tilcdc_crtc *tilcdc_crtc =
+		container_of(work, struct tilcdc_crtc, work);
 	struct drm_device *dev = tilcdc_crtc->base.dev;
 	struct drm_framebuffer *fb;
 
@@ -55,10 +56,12 @@ static void unref_worker(struct work_str
 static void set_scanout(struct drm_crtc *crtc, int n)
 {
 	static const uint32_t base_reg[] = {
-			LCDC_DMA_FB_BASE_ADDR_0_REG, LCDC_DMA_FB_BASE_ADDR_1_REG,
+			LCDC_DMA_FB_BASE_ADDR_0_REG,
+			LCDC_DMA_FB_BASE_ADDR_1_REG,
 	};
 	static const uint32_t ceil_reg[] = {
-			LCDC_DMA_FB_CEILING_ADDR_0_REG, LCDC_DMA_FB_CEILING_ADDR_1_REG,
+			LCDC_DMA_FB_CEILING_ADDR_0_REG,
+			LCDC_DMA_FB_CEILING_ADDR_1_REG,
 	};
 	static const uint32_t stat[] = {
 			LCDC_END_OF_FRAME0, LCDC_END_OF_FRAME1,
@@ -194,7 +197,8 @@ static void tilcdc_crtc_dpms(struct drm_
 		tilcdc_crtc->frame_done = false;
 		stop(crtc);
 
-		/* if necessary wait for framedone irq which will still come
+		/*
+		 * if necessary wait for framedone irq which will still come
 		 * before putting things to sleep..
 		 */
 		if (priv->rev == 2) {
@@ -289,17 +293,24 @@ static int tilcdc_crtc_mode_set(struct d
 	reg = tilcdc_read(dev, LCDC_RASTER_TIMING_2_REG) & ~0x000fff00;
 	reg |= LCDC_AC_BIAS_FREQUENCY(info->ac_bias) |
 		LCDC_AC_BIAS_TRANSITIONS_PER_INT(info->ac_bias_intrpt);
+
+	/*
+	 * subtract one from hfp, hbp, hsw because the hardware uses
+	 * a value of 0 as 1
+	 */
 	if (priv->rev == 2) {
-		reg |= (hfp & 0x300) >> 8;
-		reg |= (hbp & 0x300) >> 4;
-		reg |= (hsw & 0x3c0) << 21;
+		/* clear bits we're going to set */
+		reg &= ~0x78000033;
+		reg |= ((hfp-1) & 0x300) >> 8;
+		reg |= ((hbp-1) & 0x300) >> 4;
+		reg |= ((hsw-1) & 0x3c0) << 21;
 	}
 	tilcdc_write(dev, LCDC_RASTER_TIMING_2_REG, reg);
 
 	reg = (((mode->hdisplay >> 4) - 1) << 4) |
-		((hbp & 0xff) << 24) |
-		((hfp & 0xff) << 16) |
-		((hsw & 0x3f) << 10);
+		(((hbp-1) & 0xff) << 24) |
+		(((hfp-1) & 0xff) << 16) |
+		(((hsw-1) & 0x3f) << 10);
 	if (priv->rev == 2)
 		reg |= (((mode->hdisplay >> 4) - 1) & 0x40) >> 3;
 	tilcdc_write(dev, LCDC_RASTER_TIMING_0_REG, reg);
@@ -307,9 +318,24 @@ static int tilcdc_crtc_mode_set(struct d
 	reg = ((mode->vdisplay - 1) & 0x3ff) |
 		((vbp & 0xff) << 24) |
 		((vfp & 0xff) << 16) |
-		((vsw & 0x3f) << 10);
+		(((vsw-1) & 0x3f) << 10);
 	tilcdc_write(dev, LCDC_RASTER_TIMING_1_REG, reg);
 
+	/*
+	 * be sure to set Bit 10 for the V2 LCDC controller,
+	 * otherwise limited to 1024 pixels width, stopping
+	 * 1920x1080 being suppoted.
+	 */
+	if (priv->rev == 2) {
+		if ((mode->vdisplay - 1) & 0x400) {
+			tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG,
+				LCDC_LPP_B10);
+		} else {
+			tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG,
+				LCDC_LPP_B10);
+		}
+	}
+
 	/* Configure display type: */
 	reg = tilcdc_read(dev, LCDC_RASTER_CTRL_REG) &
 		~(LCDC_TFT_MODE | LCDC_MONO_8BIT_MODE | LCDC_MONOCHROME_MODE |
@@ -384,10 +410,6 @@ static int tilcdc_crtc_mode_set_base(str
 	return 0;
 }
 
-static void tilcdc_crtc_load_lut(struct drm_crtc *crtc)
-{
-}
-
 static const struct drm_crtc_funcs tilcdc_crtc_funcs = {
 		.destroy        = tilcdc_crtc_destroy,
 		.set_config     = drm_crtc_helper_set_config,
@@ -401,7 +423,6 @@ static const struct drm_crtc_helper_func
 		.commit         = tilcdc_crtc_commit,
 		.mode_set       = tilcdc_crtc_mode_set,
 		.mode_set_base  = tilcdc_crtc_mode_set_base,
-		.load_lut       = tilcdc_crtc_load_lut,
 };
 
 int tilcdc_crtc_max_width(struct drm_crtc *crtc)
@@ -422,7 +443,12 @@ int tilcdc_crtc_mode_valid(struct drm_cr
 {
 	struct tilcdc_drm_private *priv = crtc->dev->dev_private;
 	unsigned int bandwidth;
+	uint32_t hbp, hfp, hsw, vbp, vfp, vsw;
 
+	/*
+	 * check to see if the width is within the range that
+	 * the LCD Controller physically supports
+	 */
 	if (mode->hdisplay > tilcdc_crtc_max_width(crtc))
 		return MODE_VIRTUAL_X;
 
@@ -433,10 +459,70 @@ int tilcdc_crtc_mode_valid(struct drm_cr
 	if (mode->vdisplay > 2048)
 		return MODE_VIRTUAL_Y;
 
+	DBG("Processing mode %dx%d@%d with pixel clock %d",
+		mode->hdisplay, mode->vdisplay,
+		drm_mode_vrefresh(mode), mode->clock);
+
+	hbp = mode->htotal - mode->hsync_end;
+	hfp = mode->hsync_start - mode->hdisplay;
+	hsw = mode->hsync_end - mode->hsync_start;
+	vbp = mode->vtotal - mode->vsync_end;
+	vfp = mode->vsync_start - mode->vdisplay;
+	vsw = mode->vsync_end - mode->vsync_start;
+
+	if ((hbp-1) & ~0x3ff) {
+		DBG("Pruning mode: Horizontal Back Porch out of range");
+		return MODE_HBLANK_WIDE;
+	}
+
+	if ((hfp-1) & ~0x3ff) {
+		DBG("Pruning mode: Horizontal Front Porch out of range");
+		return MODE_HBLANK_WIDE;
+	}
+
+	if ((hsw-1) & ~0x3ff) {
+		DBG("Pruning mode: Horizontal Sync Width out of range");
+		return MODE_HSYNC_WIDE;
+	}
+
+	if (vbp & ~0xff) {
+		DBG("Pruning mode: Vertical Back Porch out of range");
+		return MODE_VBLANK_WIDE;
+	}
+
+	if (vfp & ~0xff) {
+		DBG("Pruning mode: Vertical Front Porch out of range");
+		return MODE_VBLANK_WIDE;
+	}
+
+	if ((vsw-1) & ~0x3f) {
+		DBG("Pruning mode: Vertical Sync Width out of range");
+		return MODE_VSYNC_WIDE;
+	}
+
+	/*
+	 * some devices have a maximum allowed pixel clock
+	 * configured from the DT
+	 */
+	if (mode->clock > priv->max_pixelclock) {
+		DBG("Pruning mode: pixel clock too high");
+		return MODE_CLOCK_HIGH;
+	}
+
+	/*
+	 * some devices further limit the max horizontal resolution
+	 * configured from the DT
+	 */
+	if (mode->hdisplay > priv->max_width)
+		return MODE_BAD_WIDTH;
+
 	/* filter out modes that would require too much memory bandwidth: */
-	bandwidth = mode->hdisplay * mode->vdisplay * drm_mode_vrefresh(mode);
-	if (bandwidth > priv->max_bandwidth)
+	bandwidth = mode->hdisplay * mode->vdisplay *
+		drm_mode_vrefresh(mode);
+	if (bandwidth > priv->max_bandwidth) {
+		DBG("Pruning mode: exceeds defined bandwidth limit");
 		return MODE_BAD;
+	}
 
 	return MODE_OK;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,7 @@
 #include "drm_fb_helper.h"
 
 static LIST_HEAD(module_list);
+static bool slave_probing;
 
 void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
 		const struct tilcdc_module_ops *funcs)
@@ -41,6 +42,11 @@ void tilcdc_module_cleanup(struct tilcdc
 	list_del(&mod->list);
 }
 
+void tilcdc_slave_probedefer(bool defered)
+{
+	slave_probing = defered;
+}
+
 static struct of_device_id tilcdc_of_match[];
 
 static struct drm_framebuffer *tilcdc_fb_create(struct drm_device *dev,
@@ -157,7 +163,9 @@ static int tilcdc_load(struct drm_device
 	struct platform_device *pdev = dev->platformdev;
 	struct device_node *node = pdev->dev.of_node;
 	struct tilcdc_drm_private *priv;
+	struct tilcdc_module *mod;
 	struct resource *res;
+	u32 bpp = 0;
 	int ret;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
@@ -210,7 +218,20 @@ static int tilcdc_load(struct drm_device
 #endif
 
 	if (of_property_read_u32(node, "max-bandwidth", &priv->max_bandwidth))
-		priv->max_bandwidth = 1280 * 1024 * 60;
+		priv->max_bandwidth = TILCDC_DEFAULT_MAX_BANDWIDTH;
+
+	DBG("Maximum Bandwidth Value %d", priv->max_bandwidth);
+
+	if (of_property_read_u32(node, "ti,max-width", &priv->max_width))
+		priv->max_width = TILCDC_DEFAULT_MAX_WIDTH;
+
+	DBG("Maximum Horizontal Pixel Width Value %dpixels", priv->max_width);
+
+	if (of_property_read_u32(node, "ti,max-pixelclock",
+					&priv->max_pixelclock))
+		priv->max_pixelclock = TILCDC_DEFAULT_MAX_PIXELCLOCK;
+
+	DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock);
 
 	pm_runtime_enable(dev->dev);
 
@@ -256,7 +277,15 @@ static int tilcdc_load(struct drm_device
 
 	platform_set_drvdata(pdev, dev);
 
-	priv->fbdev = drm_fbdev_cma_init(dev, 16,
+
+	list_for_each_entry(mod, &module_list, list) {
+		DBG("%s: preferred_bpp: %d", mod->name, mod->preferred_bpp);
+		bpp = mod->preferred_bpp;
+		if (bpp > 0)
+			break;
+	}
+
+	priv->fbdev = drm_fbdev_cma_init(dev, bpp,
 			dev->mode_config.num_crtc,
 			dev->mode_config.num_connector);
 
@@ -557,6 +586,10 @@ static int tilcdc_pdev_probe(struct plat
 		return -ENXIO;
 	}
 
+	/* defer probing if slave is in deferred probing */
+	if (slave_probing == true)
+		return -EPROBE_DEFER;
+
 	return drm_platform_init(&tilcdc_driver, pdev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_drv.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_drv.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -34,6 +34,18 @@
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_fb_cma_helper.h>
 
+/* Defaulting to pixel clock defined on AM335x */
+#define TILCDC_DEFAULT_MAX_PIXELCLOCK  126000
+/* Defaulting to max width as defined on AM335x */
+#define TILCDC_DEFAULT_MAX_WIDTH  2048
+/*
+ * This may need some tweaking, but want to allow at least 1280x1024@60
+ * with optimized DDR & EMIF settings tweaked 1920x1080@24 appears to
+ * be supportable
+ */
+#define TILCDC_DEFAULT_MAX_BANDWIDTH  (1280*1024*60)
+
+
 struct tilcdc_drm_private {
 	void __iomem *mmio;
 
@@ -43,6 +55,16 @@ struct tilcdc_drm_private {
 
 	/* don't attempt resolutions w/ higher W * H * Hz: */
 	uint32_t max_bandwidth;
+	/*
+	 * Pixel Clock will be restricted to some value as
+	 * defined in the device datasheet measured in KHz
+	 */
+	uint32_t max_pixelclock;
+	/*
+	 * Max allowable width is limited on a per device basis
+	 * measured in pixels
+	 */
+	uint32_t max_width;
 
 	/* register contents saved across suspend/resume: */
 	u32 saved_register[12];
@@ -89,12 +111,13 @@ struct tilcdc_module {
 	const char *name;
 	struct list_head list;
 	const struct tilcdc_module_ops *funcs;
+	unsigned int preferred_bpp;
 };
 
 void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
 		const struct tilcdc_module_ops *funcs);
 void tilcdc_module_cleanup(struct tilcdc_module *mod);
-
+void tilcdc_slave_probedefer(bool defered);
 
 /* Panel config that needs to be set in the crtc, but is not coming from
  * the mode timings.  The display module is expected to call
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_panel.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_panel.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_panel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_panel.c	2013-08-25 20:43:22.000000000 -0400
@@ -393,6 +393,8 @@ static int panel_probe(struct platform_d
 		goto fail;
 	}
 
+	mod->preferred_bpp = panel_mod->info->bpp;
+
 	panel_mod->backlight = of_find_backlight_by_node(node);
 	if (panel_mod->backlight)
 		dev_info(&pdev->dev, "found backlight\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_regs.h linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_regs.h
--- linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -80,6 +80,7 @@
 #define LCDC_INVERT_PIXEL_CLOCK                  BIT(22)
 #define LCDC_INVERT_HSYNC                        BIT(21)
 #define LCDC_INVERT_VSYNC                        BIT(20)
+#define LCDC_LPP_B10                             BIT(26)
 
 /* LCDC Block */
 #define LCDC_PID_REG                             0x0
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_slave.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_slave.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_slave.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_slave.c	2013-08-25 20:43:22.000000000 -0400
@@ -298,6 +298,7 @@ static int slave_probe(struct platform_d
 	struct tilcdc_module *mod;
 	struct pinctrl *pinctrl;
 	uint32_t i2c_phandle;
+	struct i2c_adapter *slavei2c;
 	int ret = -EINVAL;
 
 	/* bail out early if no DT data: */
@@ -306,42 +307,48 @@ static int slave_probe(struct platform_d
 		return -ENXIO;
 	}
 
-	slave_mod = kzalloc(sizeof(*slave_mod), GFP_KERNEL);
-	if (!slave_mod)
-		return -ENOMEM;
-
-	mod = &slave_mod->base;
-
-	tilcdc_module_init(mod, "slave", &slave_module_ops);
-
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl))
-		dev_warn(&pdev->dev, "pins are not configured\n");
-
+	/* Bail out early if i2c not specified */
 	if (of_property_read_u32(node, "i2c", &i2c_phandle)) {
 		dev_err(&pdev->dev, "could not get i2c bus phandle\n");
-		goto fail;
+		return ret;
 	}
 
 	i2c_node = of_find_node_by_phandle(i2c_phandle);
 	if (!i2c_node) {
 		dev_err(&pdev->dev, "could not get i2c bus node\n");
-		goto fail;
+		return ret;
 	}
 
-	slave_mod->i2c = of_find_i2c_adapter_by_node(i2c_node);
-	if (!slave_mod->i2c) {
+	/* but defer the probe if it can't be initialized it might come later */
+	slavei2c = of_find_i2c_adapter_by_node(i2c_node);
+	of_node_put(i2c_node);
+
+	if (!slavei2c) {
+		ret = -EPROBE_DEFER;
+		tilcdc_slave_probedefer(true);
 		dev_err(&pdev->dev, "could not get i2c\n");
-		goto fail;
+		return ret;
 	}
 
-	of_node_put(i2c_node);
+	slave_mod = kzalloc(sizeof(*slave_mod), GFP_KERNEL);
+	if (!slave_mod)
+		return -ENOMEM;
 
-	return 0;
+	mod = &slave_mod->base;
 
-fail:
-	slave_destroy(mod);
-	return ret;
+	mod->preferred_bpp = slave_info.bpp;
+
+	slave_mod->i2c = slavei2c;
+
+	tilcdc_module_init(mod, "slave", &slave_module_ops);
+
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl))
+		dev_warn(&pdev->dev, "pins are not configured\n");
+
+	tilcdc_slave_probedefer(false);
+
+	return 0;
 }
 
 static int slave_remove(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c	2013-08-25 20:43:22.000000000 -0400
@@ -354,6 +354,8 @@ static int tfp410_probe(struct platform_
 		goto fail;
 	}
 
+	mod->preferred_bpp = dvi_info.bpp;
+
 	i2c_node = of_find_node_by_phandle(i2c_phandle);
 	if (!i2c_node) {
 		dev_err(&pdev->dev, "could not get i2c bus node\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/ttm/ttm_bo.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ttm/ttm_bo.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/ttm/ttm_bo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ttm/ttm_bo.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,6 +150,9 @@ static void ttm_bo_release_list(struct k
 	if (bo->ttm)
 		ttm_tt_destroy(bo->ttm);
 	atomic_dec(&bo->glob->bo_count);
+	if (bo->resv == &bo->ttm_resv)
+		reservation_object_fini(&bo->ttm_resv);
+
 	if (bo->destroy)
 		bo->destroy(bo);
 	else {
@@ -158,24 +161,12 @@ static void ttm_bo_release_list(struct k
 	ttm_mem_global_free(bdev->glob->mem_glob, acc_size);
 }
 
-static int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo,
-				  bool interruptible)
-{
-	if (interruptible) {
-		return wait_event_interruptible(bo->event_queue,
-					       !ttm_bo_is_reserved(bo));
-	} else {
-		wait_event(bo->event_queue, !ttm_bo_is_reserved(bo));
-		return 0;
-	}
-}
-
 void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
 {
 	struct ttm_bo_device *bdev = bo->bdev;
 	struct ttm_mem_type_manager *man;
 
-	BUG_ON(!ttm_bo_is_reserved(bo));
+	lockdep_assert_held(&bo->resv->lock.base);
 
 	if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
 
@@ -191,6 +182,7 @@ void ttm_bo_add_to_lru(struct ttm_buffer
 		}
 	}
 }
+EXPORT_SYMBOL(ttm_bo_add_to_lru);
 
 int ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
 {
@@ -213,71 +205,6 @@ int ttm_bo_del_from_lru(struct ttm_buffe
 	return put_count;
 }
 
-int ttm_bo_reserve_nolru(struct ttm_buffer_object *bo,
-			  bool interruptible,
-			  bool no_wait, bool use_sequence, uint32_t sequence)
-{
-	int ret;
-
-	while (unlikely(atomic_xchg(&bo->reserved, 1) != 0)) {
-		/**
-		 * Deadlock avoidance for multi-bo reserving.
-		 */
-		if (use_sequence && bo->seq_valid) {
-			/**
-			 * We've already reserved this one.
-			 */
-			if (unlikely(sequence == bo->val_seq))
-				return -EDEADLK;
-			/**
-			 * Already reserved by a thread that will not back
-			 * off for us. We need to back off.
-			 */
-			if (unlikely(sequence - bo->val_seq < (1 << 31)))
-				return -EAGAIN;
-		}
-
-		if (no_wait)
-			return -EBUSY;
-
-		ret = ttm_bo_wait_unreserved(bo, interruptible);
-
-		if (unlikely(ret))
-			return ret;
-	}
-
-	if (use_sequence) {
-		bool wake_up = false;
-		/**
-		 * Wake up waiters that may need to recheck for deadlock,
-		 * if we decreased the sequence number.
-		 */
-		if (unlikely((bo->val_seq - sequence < (1 << 31))
-			     || !bo->seq_valid))
-			wake_up = true;
-
-		/*
-		 * In the worst case with memory ordering these values can be
-		 * seen in the wrong order. However since we call wake_up_all
-		 * in that case, this will hopefully not pose a problem,
-		 * and the worst case would only cause someone to accidentally
-		 * hit -EAGAIN in ttm_bo_reserve when they see old value of
-		 * val_seq. However this would only happen if seq_valid was
-		 * written before val_seq was, and just means some slightly
-		 * increased cpu usage
-		 */
-		bo->val_seq = sequence;
-		bo->seq_valid = true;
-		if (wake_up)
-			wake_up_all(&bo->event_queue);
-	} else {
-		bo->seq_valid = false;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(ttm_bo_reserve);
-
 static void ttm_bo_ref_bug(struct kref *list_kref)
 {
 	BUG();
@@ -290,89 +217,16 @@ void ttm_bo_list_ref_sub(struct ttm_buff
 		 (never_free) ? ttm_bo_ref_bug : ttm_bo_release_list);
 }
 
-int ttm_bo_reserve(struct ttm_buffer_object *bo,
-		   bool interruptible,
-		   bool no_wait, bool use_sequence, uint32_t sequence)
-{
-	struct ttm_bo_global *glob = bo->glob;
-	int put_count = 0;
-	int ret;
-
-	ret = ttm_bo_reserve_nolru(bo, interruptible, no_wait, use_sequence,
-				   sequence);
-	if (likely(ret == 0)) {
-		spin_lock(&glob->lru_lock);
-		put_count = ttm_bo_del_from_lru(bo);
-		spin_unlock(&glob->lru_lock);
-		ttm_bo_list_ref_sub(bo, put_count, true);
-	}
-
-	return ret;
-}
-
-int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo,
-				  bool interruptible, uint32_t sequence)
-{
-	bool wake_up = false;
-	int ret;
-
-	while (unlikely(atomic_xchg(&bo->reserved, 1) != 0)) {
-		WARN_ON(bo->seq_valid && sequence == bo->val_seq);
-
-		ret = ttm_bo_wait_unreserved(bo, interruptible);
-
-		if (unlikely(ret))
-			return ret;
-	}
-
-	if ((bo->val_seq - sequence < (1 << 31)) || !bo->seq_valid)
-		wake_up = true;
-
-	/**
-	 * Wake up waiters that may need to recheck for deadlock,
-	 * if we decreased the sequence number.
-	 */
-	bo->val_seq = sequence;
-	bo->seq_valid = true;
-	if (wake_up)
-		wake_up_all(&bo->event_queue);
-
-	return 0;
-}
-
-int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
-			    bool interruptible, uint32_t sequence)
-{
-	struct ttm_bo_global *glob = bo->glob;
-	int put_count, ret;
-
-	ret = ttm_bo_reserve_slowpath_nolru(bo, interruptible, sequence);
-	if (likely(!ret)) {
-		spin_lock(&glob->lru_lock);
-		put_count = ttm_bo_del_from_lru(bo);
-		spin_unlock(&glob->lru_lock);
-		ttm_bo_list_ref_sub(bo, put_count, true);
-	}
-	return ret;
-}
-EXPORT_SYMBOL(ttm_bo_reserve_slowpath);
-
-void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo)
-{
-	ttm_bo_add_to_lru(bo);
-	atomic_set(&bo->reserved, 0);
-	wake_up_all(&bo->event_queue);
-}
-
-void ttm_bo_unreserve(struct ttm_buffer_object *bo)
+void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo)
 {
-	struct ttm_bo_global *glob = bo->glob;
+	int put_count;
 
-	spin_lock(&glob->lru_lock);
-	ttm_bo_unreserve_locked(bo);
-	spin_unlock(&glob->lru_lock);
+	spin_lock(&bo->glob->lru_lock);
+	put_count = ttm_bo_del_from_lru(bo);
+	spin_unlock(&bo->glob->lru_lock);
+	ttm_bo_list_ref_sub(bo, put_count, true);
 }
-EXPORT_SYMBOL(ttm_bo_unreserve);
+EXPORT_SYMBOL(ttm_bo_del_sub_from_lru);
 
 /*
  * Call bo->mutex locked.
@@ -544,17 +398,7 @@ static void ttm_bo_cleanup_memtype_use(s
 	}
 	ttm_bo_mem_put(bo, &bo->mem);
 
-	atomic_set(&bo->reserved, 0);
-	wake_up_all(&bo->event_queue);
-
-	/*
-	 * Since the final reference to this bo may not be dropped by
-	 * the current task we have to put a memory barrier here to make
-	 * sure the changes done in this function are always visible.
-	 *
-	 * This function only needs protection against the final kref_put.
-	 */
-	smp_mb__before_atomic_dec();
+	ww_mutex_unlock (&bo->resv->lock);
 }
 
 static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
@@ -586,10 +430,8 @@ static void ttm_bo_cleanup_refs_or_queue
 		sync_obj = driver->sync_obj_ref(bo->sync_obj);
 	spin_unlock(&bdev->fence_lock);
 
-	if (!ret) {
-		atomic_set(&bo->reserved, 0);
-		wake_up_all(&bo->event_queue);
-	}
+	if (!ret)
+		ww_mutex_unlock(&bo->resv->lock);
 
 	kref_get(&bo->list_kref);
 	list_add_tail(&bo->ddestroy, &bdev->ddestroy);
@@ -639,8 +481,7 @@ static int ttm_bo_cleanup_refs_and_unloc
 		sync_obj = driver->sync_obj_ref(bo->sync_obj);
 		spin_unlock(&bdev->fence_lock);
 
-		atomic_set(&bo->reserved, 0);
-		wake_up_all(&bo->event_queue);
+		ww_mutex_unlock(&bo->resv->lock);
 		spin_unlock(&glob->lru_lock);
 
 		ret = driver->sync_obj_wait(sync_obj, false, interruptible);
@@ -678,8 +519,7 @@ static int ttm_bo_cleanup_refs_and_unloc
 		spin_unlock(&bdev->fence_lock);
 
 	if (ret || unlikely(list_empty(&bo->ddestroy))) {
-		atomic_set(&bo->reserved, 0);
-		wake_up_all(&bo->event_queue);
+		ww_mutex_unlock(&bo->resv->lock);
 		spin_unlock(&glob->lru_lock);
 		return ret;
 	}
@@ -831,7 +671,7 @@ static int ttm_bo_evict(struct ttm_buffe
 		goto out;
 	}
 
-	BUG_ON(!ttm_bo_is_reserved(bo));
+	lockdep_assert_held(&bo->resv->lock.base);
 
 	evict_mem = bo->mem;
 	evict_mem.mm_node = NULL;
@@ -1121,7 +961,7 @@ int ttm_bo_move_buffer(struct ttm_buffer
 	struct ttm_mem_reg mem;
 	struct ttm_bo_device *bdev = bo->bdev;
 
-	BUG_ON(!ttm_bo_is_reserved(bo));
+	lockdep_assert_held(&bo->resv->lock.base);
 
 	/*
 	 * FIXME: It's possible to pipeline buffer moves.
@@ -1180,7 +1020,7 @@ int ttm_bo_validate(struct ttm_buffer_ob
 {
 	int ret;
 
-	BUG_ON(!ttm_bo_is_reserved(bo));
+	lockdep_assert_held(&bo->resv->lock.base);
 	/* Check that range is valid */
 	if (placement->lpfn || placement->fpfn)
 		if (placement->fpfn > placement->lpfn ||
@@ -1239,6 +1079,7 @@ int ttm_bo_init(struct ttm_bo_device *bd
 	int ret = 0;
 	unsigned long num_pages;
 	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
+	bool locked;
 
 	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
 	if (ret) {
@@ -1265,8 +1106,6 @@ int ttm_bo_init(struct ttm_bo_device *bd
 	kref_init(&bo->kref);
 	kref_init(&bo->list_kref);
 	atomic_set(&bo->cpu_writers, 0);
-	atomic_set(&bo->reserved, 1);
-	init_waitqueue_head(&bo->event_queue);
 	INIT_LIST_HEAD(&bo->lru);
 	INIT_LIST_HEAD(&bo->ddestroy);
 	INIT_LIST_HEAD(&bo->swap);
@@ -1284,37 +1123,34 @@ int ttm_bo_init(struct ttm_bo_device *bd
 	bo->mem.bus.io_reserved_count = 0;
 	bo->priv_flags = 0;
 	bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED);
-	bo->seq_valid = false;
 	bo->persistent_swap_storage = persistent_swap_storage;
 	bo->acc_size = acc_size;
 	bo->sg = sg;
+	bo->resv = &bo->ttm_resv;
+	reservation_object_init(bo->resv);
 	atomic_inc(&bo->glob->bo_count);
 
 	ret = ttm_bo_check_placement(bo, placement);
-	if (unlikely(ret != 0))
-		goto out_err;
 
 	/*
 	 * For ttm_bo_type_device buffers, allocate
 	 * address space from the device.
 	 */
-	if (bo->type == ttm_bo_type_device ||
-	    bo->type == ttm_bo_type_sg) {
+	if (likely(!ret) &&
+	    (bo->type == ttm_bo_type_device ||
+	     bo->type == ttm_bo_type_sg))
 		ret = ttm_bo_setup_vm(bo);
-		if (ret)
-			goto out_err;
-	}
 
-	ret = ttm_bo_validate(bo, placement, interruptible, false);
-	if (ret)
-		goto out_err;
+	locked = ww_mutex_trylock(&bo->resv->lock);
+	WARN_ON(!locked);
 
-	ttm_bo_unreserve(bo);
-	return 0;
+	if (likely(!ret))
+		ret = ttm_bo_validate(bo, placement, interruptible, false);
 
-out_err:
 	ttm_bo_unreserve(bo);
-	ttm_bo_unref(&bo);
+
+	if (unlikely(ret))
+		ttm_bo_unref(&bo);
 
 	return ret;
 }
@@ -1619,9 +1455,7 @@ int ttm_bo_device_init(struct ttm_bo_dev
 		goto out_no_sys;
 
 	bdev->addr_space_rb = RB_ROOT;
-	ret = drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000);
-	if (unlikely(ret != 0))
-		goto out_no_addr_mm;
+	drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000);
 
 	INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);
 	INIT_LIST_HEAD(&bdev->ddestroy);
@@ -1635,8 +1469,6 @@ int ttm_bo_device_init(struct ttm_bo_dev
 	mutex_unlock(&glob->device_list_mutex);
 
 	return 0;
-out_no_addr_mm:
-	ttm_bo_clean_mm(bdev, 0);
 out_no_sys:
 	return ret;
 }
@@ -1927,8 +1759,7 @@ out:
 	 * already swapped buffer.
 	 */
 
-	atomic_set(&bo->reserved, 0);
-	wake_up_all(&bo->event_queue);
+	ww_mutex_unlock(&bo->resv->lock);
 	kref_put(&bo->list_kref, ttm_bo_release_list);
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/ttm/ttm_bo_manager.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ttm/ttm_bo_manager.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/ttm/ttm_bo_manager.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ttm/ttm_bo_manager.c	2013-08-25 20:43:22.000000000 -0400
@@ -103,18 +103,12 @@ static int ttm_bo_man_init(struct ttm_me
 			   unsigned long p_size)
 {
 	struct ttm_range_manager *rman;
-	int ret;
 
 	rman = kzalloc(sizeof(*rman), GFP_KERNEL);
 	if (!rman)
 		return -ENOMEM;
 
-	ret = drm_mm_init(&rman->mm, 0, p_size);
-	if (ret) {
-		kfree(rman);
-		return ret;
-	}
-
+	drm_mm_init(&rman->mm, 0, p_size);
 	spin_lock_init(&rman->lock);
 	man->priv = rman;
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/ttm/ttm_bo_util.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ttm/ttm_bo_util.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/ttm/ttm_bo_util.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ttm/ttm_bo_util.c	2013-08-25 20:43:22.000000000 -0400
@@ -433,6 +433,7 @@ static int ttm_buffer_object_transfer(st
 	struct ttm_buffer_object *fbo;
 	struct ttm_bo_device *bdev = bo->bdev;
 	struct ttm_bo_driver *driver = bdev->driver;
+	int ret;
 
 	fbo = kmalloc(sizeof(*fbo), GFP_KERNEL);
 	if (!fbo)
@@ -445,7 +446,6 @@ static int ttm_buffer_object_transfer(st
 	 * TODO: Explicit member copy would probably be better here.
 	 */
 
-	init_waitqueue_head(&fbo->event_queue);
 	INIT_LIST_HEAD(&fbo->ddestroy);
 	INIT_LIST_HEAD(&fbo->lru);
 	INIT_LIST_HEAD(&fbo->swap);
@@ -463,6 +463,10 @@ static int ttm_buffer_object_transfer(st
 	kref_init(&fbo->kref);
 	fbo->destroy = &ttm_transfered_destroy;
 	fbo->acc_size = 0;
+	fbo->resv = &fbo->ttm_resv;
+	reservation_object_init(fbo->resv);
+	ret = ww_mutex_trylock(&fbo->resv->lock);
+	WARN_ON(!ret);
 
 	*new_obj = fbo;
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/ttm/ttm_execbuf_util.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ttm/ttm_execbuf_util.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/ttm/ttm_execbuf_util.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/ttm/ttm_execbuf_util.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,8 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 
-static void ttm_eu_backoff_reservation_locked(struct list_head *list)
+static void ttm_eu_backoff_reservation_locked(struct list_head *list,
+					      struct ww_acquire_ctx *ticket)
 {
 	struct ttm_validate_buffer *entry;
 
@@ -41,14 +42,12 @@ static void ttm_eu_backoff_reservation_l
 		if (!entry->reserved)
 			continue;
 
+		entry->reserved = false;
 		if (entry->removed) {
 			ttm_bo_add_to_lru(bo);
 			entry->removed = false;
-
 		}
-		entry->reserved = false;
-		atomic_set(&bo->reserved, 0);
-		wake_up_all(&bo->event_queue);
+		ww_mutex_unlock(&bo->resv->lock);
 	}
 }
 
@@ -82,7 +81,8 @@ static void ttm_eu_list_ref_sub(struct l
 	}
 }
 
-void ttm_eu_backoff_reservation(struct list_head *list)
+void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
+				struct list_head *list)
 {
 	struct ttm_validate_buffer *entry;
 	struct ttm_bo_global *glob;
@@ -93,7 +93,8 @@ void ttm_eu_backoff_reservation(struct l
 	entry = list_first_entry(list, struct ttm_validate_buffer, head);
 	glob = entry->bo->glob;
 	spin_lock(&glob->lru_lock);
-	ttm_eu_backoff_reservation_locked(list);
+	ttm_eu_backoff_reservation_locked(list, ticket);
+	ww_acquire_fini(ticket);
 	spin_unlock(&glob->lru_lock);
 }
 EXPORT_SYMBOL(ttm_eu_backoff_reservation);
@@ -110,12 +111,12 @@ EXPORT_SYMBOL(ttm_eu_backoff_reservation
  * buffers in different orders.
  */
 
-int ttm_eu_reserve_buffers(struct list_head *list)
+int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
+			   struct list_head *list)
 {
 	struct ttm_bo_global *glob;
 	struct ttm_validate_buffer *entry;
 	int ret;
-	uint32_t val_seq;
 
 	if (list_empty(list))
 		return 0;
@@ -129,9 +130,7 @@ int ttm_eu_reserve_buffers(struct list_h
 	entry = list_first_entry(list, struct ttm_validate_buffer, head);
 	glob = entry->bo->glob;
 
-	spin_lock(&glob->lru_lock);
-	val_seq = entry->bo->bdev->val_seq++;
-
+	ww_acquire_init(ticket, &reservation_ww_class);
 retry:
 	list_for_each_entry(entry, list, head) {
 		struct ttm_buffer_object *bo = entry->bo;
@@ -140,49 +139,34 @@ retry:
 		if (entry->reserved)
 			continue;
 
-		ret = ttm_bo_reserve_nolru(bo, true, true, true, val_seq);
-		switch (ret) {
-		case 0:
-			break;
-		case -EBUSY:
-			ttm_eu_del_from_lru_locked(list);
-			spin_unlock(&glob->lru_lock);
-			ret = ttm_bo_reserve_nolru(bo, true, false,
-						   true, val_seq);
-			spin_lock(&glob->lru_lock);
-			if (!ret)
-				break;
-
-			if (unlikely(ret != -EAGAIN))
-				goto err;
 
-			/* fallthrough */
-		case -EAGAIN:
-			ttm_eu_backoff_reservation_locked(list);
+		ret = ttm_bo_reserve_nolru(bo, true, false, true, ticket);
 
-			/*
-			 * temporarily increase sequence number every retry,
-			 * to prevent us from seeing our old reservation
-			 * sequence when someone else reserved the buffer,
-			 * but hasn't updated the seq_valid/seqno members yet.
+		if (ret == -EDEADLK) {
+			/* uh oh, we lost out, drop every reservation and try
+			 * to only reserve this buffer, then start over if
+			 * this succeeds.
 			 */
-			val_seq = entry->bo->bdev->val_seq++;
-
+			spin_lock(&glob->lru_lock);
+			ttm_eu_backoff_reservation_locked(list, ticket);
 			spin_unlock(&glob->lru_lock);
 			ttm_eu_list_ref_sub(list);
-			ret = ttm_bo_reserve_slowpath_nolru(bo, true, val_seq);
-			if (unlikely(ret != 0))
-				return ret;
-			spin_lock(&glob->lru_lock);
+			ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
+							       ticket);
+			if (unlikely(ret != 0)) {
+				if (ret == -EINTR)
+					ret = -ERESTARTSYS;
+				goto err_fini;
+			}
+
 			entry->reserved = true;
 			if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
 				ret = -EBUSY;
 				goto err;
 			}
 			goto retry;
-		default:
+		} else if (ret)
 			goto err;
-		}
 
 		entry->reserved = true;
 		if (unlikely(atomic_read(&bo->cpu_writers) > 0)) {
@@ -191,21 +175,27 @@ retry:
 		}
 	}
 
+	ww_acquire_done(ticket);
+	spin_lock(&glob->lru_lock);
 	ttm_eu_del_from_lru_locked(list);
 	spin_unlock(&glob->lru_lock);
 	ttm_eu_list_ref_sub(list);
-
 	return 0;
 
 err:
-	ttm_eu_backoff_reservation_locked(list);
+	spin_lock(&glob->lru_lock);
+	ttm_eu_backoff_reservation_locked(list, ticket);
 	spin_unlock(&glob->lru_lock);
 	ttm_eu_list_ref_sub(list);
+err_fini:
+	ww_acquire_done(ticket);
+	ww_acquire_fini(ticket);
 	return ret;
 }
 EXPORT_SYMBOL(ttm_eu_reserve_buffers);
 
-void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj)
+void ttm_eu_fence_buffer_objects(struct ww_acquire_ctx *ticket,
+				 struct list_head *list, void *sync_obj)
 {
 	struct ttm_validate_buffer *entry;
 	struct ttm_buffer_object *bo;
@@ -228,11 +218,13 @@ void ttm_eu_fence_buffer_objects(struct
 		bo = entry->bo;
 		entry->old_sync_obj = bo->sync_obj;
 		bo->sync_obj = driver->sync_obj_ref(sync_obj);
-		ttm_bo_unreserve_locked(bo);
+		ttm_bo_add_to_lru(bo);
+		ww_mutex_unlock(&bo->resv->lock);
 		entry->reserved = false;
 	}
 	spin_unlock(&bdev->fence_lock);
 	spin_unlock(&glob->lru_lock);
+	ww_acquire_fini(ticket);
 
 	list_for_each_entry(entry, list, head) {
 		if (entry->old_sync_obj)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/udl/udl_fb.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/udl/udl_fb.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/udl/udl_fb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/udl/udl_fb.c	2013-08-25 20:43:22.000000000 -0400
@@ -393,19 +393,6 @@ static struct fb_ops udlfb_ops = {
 	.fb_release = udl_fb_release,
 };
 
-static void udl_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
-			   u16 blue, int regno)
-{
-}
-
-static void udl_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
-			     u16 *blue, int regno)
-{
-	*red = 0;
-	*green = 0;
-	*blue = 0;
-}
-
 static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
 				      struct drm_file *file,
 				      unsigned flags, unsigned color,
@@ -558,8 +545,6 @@ out:
 }
 
 static struct drm_fb_helper_funcs udl_fb_helper_funcs = {
-	.gamma_set = udl_crtc_fb_gamma_set,
-	.gamma_get = udl_crtc_fb_gamma_get,
 	.fb_probe = udlfb_create,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/udl/udl_modeset.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/udl/udl_modeset.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/udl/udl_modeset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/udl/udl_modeset.c	2013-08-25 20:43:22.000000000 -0400
@@ -363,10 +363,6 @@ static void udl_crtc_destroy(struct drm_
 	kfree(crtc);
 }
 
-static void udl_load_lut(struct drm_crtc *crtc)
-{
-}
-
 static void udl_crtc_prepare(struct drm_crtc *crtc)
 {
 }
@@ -383,7 +379,6 @@ static struct drm_crtc_helper_funcs udl_
 	.prepare = udl_crtc_prepare,
 	.commit = udl_crtc_commit,
 	.disable = udl_crtc_disable,
-	.load_lut = udl_load_lut,
 };
 
 static const struct drm_crtc_funcs udl_crtc_funcs = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c	2013-08-25 20:43:22.000000000 -0400
@@ -302,7 +302,7 @@ void vmw_bo_pin(struct ttm_buffer_object
 	uint32_t old_mem_type = bo->mem.mem_type;
 	int ret;
 
-	BUG_ON(!ttm_bo_is_reserved(bo));
+	lockdep_assert_held(&bo->resv->lock.base);
 	BUG_ON(old_mem_type != TTM_PL_VRAM &&
 	       old_mem_type != VMW_PL_GMR);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -565,8 +565,8 @@ static int vmw_driver_load(struct drm_de
 		dev_priv->has_gmr = false;
 	}
 
-	dev_priv->mmio_mtrr = drm_mtrr_add(dev_priv->mmio_start,
-					   dev_priv->mmio_size, DRM_MTRR_WC);
+	dev_priv->mmio_mtrr = arch_phys_wc_add(dev_priv->mmio_start,
+					       dev_priv->mmio_size);
 
 	dev_priv->mmio_virt = ioremap_wc(dev_priv->mmio_start,
 					 dev_priv->mmio_size);
@@ -664,8 +664,7 @@ out_no_device:
 out_err4:
 	iounmap(dev_priv->mmio_virt);
 out_err3:
-	drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start,
-		     dev_priv->mmio_size, DRM_MTRR_WC);
+	arch_phys_wc_del(dev_priv->mmio_mtrr);
 	if (dev_priv->has_gmr)
 		(void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
 	(void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
@@ -709,8 +708,7 @@ static int vmw_driver_unload(struct drm_
 
 	ttm_object_device_release(&dev_priv->tdev);
 	iounmap(dev_priv->mmio_virt);
-	drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start,
-		     dev_priv->mmio_size, DRM_MTRR_WC);
+	arch_phys_wc_del(dev_priv->mmio_mtrr);
 	if (dev_priv->has_gmr)
 		(void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);
 	(void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c	2013-08-25 20:43:22.000000000 -0400
@@ -1432,6 +1432,7 @@ int vmw_execbuf_process(struct drm_file
 	struct vmw_fence_obj *fence = NULL;
 	struct vmw_resource *error_resource;
 	struct list_head resource_list;
+	struct ww_acquire_ctx ticket;
 	uint32_t handle;
 	void *cmd;
 	int ret;
@@ -1488,7 +1489,7 @@ int vmw_execbuf_process(struct drm_file
 	if (unlikely(ret != 0))
 		goto out_err;
 
-	ret = ttm_eu_reserve_buffers(&sw_context->validate_nodes);
+	ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes);
 	if (unlikely(ret != 0))
 		goto out_err;
 
@@ -1537,7 +1538,7 @@ int vmw_execbuf_process(struct drm_file
 		DRM_ERROR("Fence submission error. Syncing.\n");
 
 	vmw_resource_list_unreserve(&sw_context->resource_list, false);
-	ttm_eu_fence_buffer_objects(&sw_context->validate_nodes,
+	ttm_eu_fence_buffer_objects(&ticket, &sw_context->validate_nodes,
 				    (void *) fence);
 
 	if (unlikely(dev_priv->pinned_bo != NULL &&
@@ -1570,7 +1571,7 @@ int vmw_execbuf_process(struct drm_file
 out_err:
 	vmw_resource_relocations_free(&sw_context->res_relocations);
 	vmw_free_relocations(sw_context);
-	ttm_eu_backoff_reservation(&sw_context->validate_nodes);
+	ttm_eu_backoff_reservation(&ticket, &sw_context->validate_nodes);
 	vmw_resource_list_unreserve(&sw_context->resource_list, true);
 	vmw_clear_validations(sw_context);
 	if (unlikely(dev_priv->pinned_bo != NULL &&
@@ -1644,6 +1645,7 @@ void __vmw_execbuf_release_pinned_bo(str
 	struct list_head validate_list;
 	struct ttm_validate_buffer pinned_val, query_val;
 	struct vmw_fence_obj *lfence = NULL;
+	struct ww_acquire_ctx ticket;
 
 	if (dev_priv->pinned_bo == NULL)
 		goto out_unlock;
@@ -1657,7 +1659,7 @@ void __vmw_execbuf_release_pinned_bo(str
 	list_add_tail(&query_val.head, &validate_list);
 
 	do {
-		ret = ttm_eu_reserve_buffers(&validate_list);
+		ret = ttm_eu_reserve_buffers(&ticket, &validate_list);
 	} while (ret == -ERESTARTSYS);
 
 	if (unlikely(ret != 0)) {
@@ -1684,7 +1686,7 @@ void __vmw_execbuf_release_pinned_bo(str
 						  NULL);
 		fence = lfence;
 	}
-	ttm_eu_fence_buffer_objects(&validate_list, (void *) fence);
+	ttm_eu_fence_buffer_objects(&ticket, &validate_list, (void *) fence);
 	if (lfence != NULL)
 		vmw_fence_obj_unreference(&lfence);
 
@@ -1696,7 +1698,7 @@ out_unlock:
 	return;
 
 out_no_emit:
-	ttm_eu_backoff_reservation(&validate_list);
+	ttm_eu_backoff_reservation(&ticket, &validate_list);
 out_no_reserve:
 	ttm_bo_unref(&query_val.bo);
 	ttm_bo_unref(&pinned_val.bo);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c	2013-08-25 20:43:22.000000000 -0400
@@ -174,7 +174,6 @@ int vmw_du_crtc_cursor_set(struct drm_cr
 			   uint32_t handle, uint32_t width, uint32_t height)
 {
 	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
-	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
 	struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
 	struct vmw_surface *surface = NULL;
 	struct vmw_dma_buffer *dmabuf = NULL;
@@ -197,6 +196,8 @@ int vmw_du_crtc_cursor_set(struct drm_cr
 	}
 
 	if (handle) {
+		struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+
 		ret = vmw_user_lookup_handle(dev_priv, tfile,
 					     handle, &surface, &dmabuf);
 		if (ret) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
--- linux-libre-3.10-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c	2013-08-25 20:43:22.000000000 -0400
@@ -958,13 +958,13 @@ void vmw_resource_unreserve(struct vmw_r
 	if (new_backup && new_backup != res->backup) {
 
 		if (res->backup) {
-			BUG_ON(!ttm_bo_is_reserved(&res->backup->base));
+			lockdep_assert_held(&res->backup->base.resv->lock.base);
 			list_del_init(&res->mob_head);
 			vmw_dmabuf_unreference(&res->backup);
 		}
 
 		res->backup = vmw_dmabuf_reference(new_backup);
-		BUG_ON(!ttm_bo_is_reserved(&new_backup->base));
+		lockdep_assert_held(&new_backup->base.resv->lock.base);
 		list_add_tail(&res->mob_head, &new_backup->res_list);
 	}
 	if (new_backup)
@@ -990,9 +990,11 @@ void vmw_resource_unreserve(struct vmw_r
  * @val_buf:        On successful return contains data about the
  *                  reserved and validated backup buffer.
  */
-int vmw_resource_check_buffer(struct vmw_resource *res,
-			      bool interruptible,
-			      struct ttm_validate_buffer *val_buf)
+static int
+vmw_resource_check_buffer(struct vmw_resource *res,
+			  struct ww_acquire_ctx *ticket,
+			  bool interruptible,
+			  struct ttm_validate_buffer *val_buf)
 {
 	struct list_head val_list;
 	bool backup_dirty = false;
@@ -1007,7 +1009,7 @@ int vmw_resource_check_buffer(struct vmw
 	INIT_LIST_HEAD(&val_list);
 	val_buf->bo = ttm_bo_reference(&res->backup->base);
 	list_add_tail(&val_buf->head, &val_list);
-	ret = ttm_eu_reserve_buffers(&val_list);
+	ret = ttm_eu_reserve_buffers(ticket, &val_list);
 	if (unlikely(ret != 0))
 		goto out_no_reserve;
 
@@ -1025,7 +1027,7 @@ int vmw_resource_check_buffer(struct vmw
 	return 0;
 
 out_no_validate:
-	ttm_eu_backoff_reservation(&val_list);
+	ttm_eu_backoff_reservation(ticket, &val_list);
 out_no_reserve:
 	ttm_bo_unref(&val_buf->bo);
 	if (backup_dirty)
@@ -1069,7 +1071,9 @@ int vmw_resource_reserve(struct vmw_reso
  *.
  * @val_buf:        Backup buffer information.
  */
-void vmw_resource_backoff_reservation(struct ttm_validate_buffer *val_buf)
+static void
+vmw_resource_backoff_reservation(struct ww_acquire_ctx *ticket,
+				 struct ttm_validate_buffer *val_buf)
 {
 	struct list_head val_list;
 
@@ -1078,7 +1082,7 @@ void vmw_resource_backoff_reservation(st
 
 	INIT_LIST_HEAD(&val_list);
 	list_add_tail(&val_buf->head, &val_list);
-	ttm_eu_backoff_reservation(&val_list);
+	ttm_eu_backoff_reservation(ticket, &val_list);
 	ttm_bo_unref(&val_buf->bo);
 }
 
@@ -1092,12 +1096,13 @@ int vmw_resource_do_evict(struct vmw_res
 {
 	struct ttm_validate_buffer val_buf;
 	const struct vmw_res_func *func = res->func;
+	struct ww_acquire_ctx ticket;
 	int ret;
 
 	BUG_ON(!func->may_evict);
 
 	val_buf.bo = NULL;
-	ret = vmw_resource_check_buffer(res, true, &val_buf);
+	ret = vmw_resource_check_buffer(res, &ticket, true, &val_buf);
 	if (unlikely(ret != 0))
 		return ret;
 
@@ -1112,7 +1117,7 @@ int vmw_resource_do_evict(struct vmw_res
 	res->backup_dirty = true;
 	res->res_dirty = false;
 out_no_unbind:
-	vmw_resource_backoff_reservation(&val_buf);
+	vmw_resource_backoff_reservation(&ticket, &val_buf);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/host1x/dev.h linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/dev.h
--- linux-libre-3.10-gnu/drivers/gpu/host1x/dev.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/dev.h	2013-08-25 20:43:22.000000000 -0400
@@ -73,7 +73,7 @@ struct host1x_syncpt_ops {
 	void (*restore_wait_base)(struct host1x_syncpt *syncpt);
 	void (*load_wait_base)(struct host1x_syncpt *syncpt);
 	u32 (*load)(struct host1x_syncpt *syncpt);
-	void (*cpu_incr)(struct host1x_syncpt *syncpt);
+	int (*cpu_incr)(struct host1x_syncpt *syncpt);
 	int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr);
 };
 
@@ -157,10 +157,10 @@ static inline u32 host1x_hw_syncpt_load(
 	return host->syncpt_op->load(sp);
 }
 
-static inline void host1x_hw_syncpt_cpu_incr(struct host1x *host,
-					     struct host1x_syncpt *sp)
+static inline int host1x_hw_syncpt_cpu_incr(struct host1x *host,
+					    struct host1x_syncpt *sp)
 {
-	host->syncpt_op->cpu_incr(sp);
+	return host->syncpt_op->cpu_incr(sp);
 }
 
 static inline int host1x_hw_syncpt_patch_wait(struct host1x *host,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/host1x/drm/dc.c linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/drm/dc.c
--- linux-libre-3.10-gnu/drivers/gpu/host1x/drm/dc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/drm/dc.c	2013-08-25 20:43:22.000000000 -0400
@@ -79,6 +79,9 @@ static int tegra_plane_disable(struct dr
 	struct tegra_plane *p = to_tegra_plane(plane);
 	unsigned long value;
 
+	if (!plane->crtc)
+		return 0;
+
 	value = WINDOW_A_SELECT << p->index;
 	tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
 
@@ -140,6 +143,7 @@ static int tegra_dc_add_planes(struct dr
 static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
 			     struct drm_framebuffer *fb)
 {
+	unsigned int format = tegra_dc_format(fb->pixel_format);
 	struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
 	unsigned long value;
 
@@ -150,6 +154,7 @@ static int tegra_dc_set_base(struct tegr
 
 	tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR);
 	tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
+	tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH);
 
 	value = GENERAL_UPDATE | WIN_A_UPDATE;
 	tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/host1x/drm/drm.c linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/drm/drm.c
--- linux-libre-3.10-gnu/drivers/gpu/host1x/drm/drm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/drm/drm.c	2013-08-25 20:43:22.000000000 -0400
@@ -148,6 +148,7 @@ int host1x_drm_init(struct host1x_drm *h
 				dev_err(host1x->dev,
 					"DRM setup failed for %s: %d\n",
 					dev_name(client->dev), err);
+				mutex_unlock(&host1x->clients_lock);
 				return err;
 			}
 		}
@@ -175,6 +176,7 @@ int host1x_drm_exit(struct host1x_drm *h
 				dev_err(host1x->dev,
 					"DRM cleanup failed for %s: %d\n",
 					dev_name(client->dev), err);
+				mutex_unlock(&host1x->clients_lock);
 				return err;
 			}
 		}
@@ -257,6 +259,13 @@ static int tegra_drm_load(struct drm_dev
 	if (err < 0)
 		return err;
 
+	/*
+	 * We don't use the drm_irq_install() helpers provided by the DRM
+	 * core, so we need to set this manually in order to allow the
+	 * DRM_IOCTL_WAIT_VBLANK to operate correctly.
+	 */
+	drm->irq_enabled = 1;
+
 	err = drm_vblank_init(drm, drm->mode_config.num_crtc);
 	if (err < 0)
 		return err;
@@ -378,8 +387,7 @@ static int tegra_syncpt_incr(struct drm_
 	if (!sp)
 		return -EINVAL;
 
-	host1x_syncpt_incr(sp);
-	return 0;
+	return host1x_syncpt_incr(sp);
 }
 
 static int tegra_syncpt_wait(struct drm_device *drm, void *data,
@@ -605,7 +613,7 @@ static void tegra_debugfs_cleanup(struct
 #endif
 
 struct drm_driver tegra_drm_driver = {
-	.driver_features = DRIVER_BUS_PLATFORM | DRIVER_MODESET | DRIVER_GEM,
+	.driver_features = DRIVER_MODESET | DRIVER_GEM,
 	.load = tegra_drm_load,
 	.unload = tegra_drm_unload,
 	.open = tegra_drm_open,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/host1x/drm/gr2d.c linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/drm/gr2d.c
--- linux-libre-3.10-gnu/drivers/gpu/host1x/drm/gr2d.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/drm/gr2d.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,7 +84,7 @@ static struct host1x_bo *host1x_bo_looku
 
 	gem = drm_gem_object_lookup(drm, file, handle);
 	if (!gem)
-		return 0;
+		return NULL;
 
 	mutex_lock(&drm->struct_mutex);
 	drm_gem_object_unreference(gem);
@@ -135,8 +135,10 @@ static int gr2d_submit(struct host1x_drm
 			goto fail;
 
 		bo = host1x_bo_lookup(drm, file, cmdbuf.handle);
-		if (!bo)
+		if (!bo) {
+			err = -ENOENT;
 			goto fail;
+		}
 
 		host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset);
 		num_cmdbufs--;
@@ -158,8 +160,10 @@ static int gr2d_submit(struct host1x_drm
 		reloc->cmdbuf = cmdbuf;
 		reloc->target = target;
 
-		if (!reloc->target || !reloc->cmdbuf)
+		if (!reloc->target || !reloc->cmdbuf) {
+			err = -ENOENT;
 			goto fail;
+		}
 	}
 
 	err = copy_from_user(job->waitchk, waitchks,
@@ -281,7 +285,7 @@ static int gr2d_probe(struct platform_de
 	if (!gr2d->channel)
 		return -ENOMEM;
 
-	*syncpts = host1x_syncpt_request(dev, 0);
+	*syncpts = host1x_syncpt_request(dev, false);
 	if (!(*syncpts)) {
 		host1x_channel_free(gr2d->channel);
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/host1x/hw/cdma_hw.c linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/hw/cdma_hw.c
--- linux-libre-3.10-gnu/drivers/gpu/host1x/hw/cdma_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/hw/cdma_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,7 +44,7 @@ static void cdma_timeout_cpu_incr(struct
 	u32 i;
 
 	for (i = 0; i < syncpt_incrs; i++)
-		host1x_syncpt_cpu_incr(cdma->timeout.syncpt);
+		host1x_syncpt_incr(cdma->timeout.syncpt);
 
 	/* after CPU incr, ensure shadow is up to date */
 	host1x_syncpt_load(cdma->timeout.syncpt);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/host1x/hw/syncpt_hw.c linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/hw/syncpt_hw.c
--- linux-libre-3.10-gnu/drivers/gpu/host1x/hw/syncpt_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/hw/syncpt_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -77,21 +77,19 @@ static u32 syncpt_load(struct host1x_syn
  * Write a cpu syncpoint increment to the hardware, without touching
  * the cache.
  */
-static void syncpt_cpu_incr(struct host1x_syncpt *sp)
+static int syncpt_cpu_incr(struct host1x_syncpt *sp)
 {
 	struct host1x *host = sp->host;
 	u32 reg_offset = sp->id / 32;
 
 	if (!host1x_syncpt_client_managed(sp) &&
-	    host1x_syncpt_idle(sp)) {
-		dev_err(host->dev, "Trying to increment syncpoint id %d beyond max\n",
-			sp->id);
-		host1x_debug_dump(sp->host);
-		return;
-	}
+	    host1x_syncpt_idle(sp))
+		return -EINVAL;
 	host1x_sync_writel(host, BIT_MASK(sp->id),
 			   HOST1X_SYNC_SYNCPT_CPU_INCR(reg_offset));
 	wmb();
+
+	return 0;
 }
 
 /* remove a wait pointed to by patch_addr */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/host1x/job.c linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/job.c
--- linux-libre-3.10-gnu/drivers/gpu/host1x/job.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/job.c	2013-08-25 20:43:22.000000000 -0400
@@ -228,17 +228,15 @@ static unsigned int do_relocs(struct hos
 	void *cmdbuf_page_addr = NULL;
 
 	/* pin & patch the relocs for one gather */
-	while (i < job->num_relocs) {
+	for (i = 0; i < job->num_relocs; i++) {
 		struct host1x_reloc *reloc = &job->relocarray[i];
 		u32 reloc_addr = (job->reloc_addr_phys[i] +
 			reloc->target_offset) >> reloc->shift;
 		u32 *target;
 
 		/* skip all other gathers */
-		if (!(reloc->cmdbuf && cmdbuf == reloc->cmdbuf)) {
-			i++;
+		if (cmdbuf != reloc->cmdbuf)
 			continue;
-		}
 
 		if (last_page != reloc->cmdbuf_offset >> PAGE_SHIFT) {
 			if (cmdbuf_page_addr)
@@ -257,9 +255,6 @@ static unsigned int do_relocs(struct hos
 
 		target = cmdbuf_page_addr + (reloc->cmdbuf_offset & ~PAGE_MASK);
 		*target = reloc_addr;
-
-		/* mark this gather as handled */
-		reloc->cmdbuf = 0;
 	}
 
 	if (cmdbuf_page_addr)
@@ -268,15 +263,15 @@ static unsigned int do_relocs(struct hos
 	return 0;
 }
 
-static int check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf,
+static bool check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf,
 		       unsigned int offset)
 {
 	offset *= sizeof(u32);
 
 	if (reloc->cmdbuf != cmdbuf || reloc->cmdbuf_offset != offset)
-		return -EINVAL;
+		return false;
 
-	return 0;
+	return true;
 }
 
 struct host1x_firewall {
@@ -307,10 +302,10 @@ static int check_mask(struct host1x_fire
 
 		if (mask & 1) {
 			if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) {
-				bool bad_reloc = check_reloc(fw->reloc,
-							     fw->cmdbuf_id,
-							     fw->offset);
-				if (!fw->num_relocs || bad_reloc)
+				if (!fw->num_relocs)
+					return -EINVAL;
+				if (!check_reloc(fw->reloc, fw->cmdbuf_id,
+						 fw->offset))
 					return -EINVAL;
 				fw->reloc++;
 				fw->num_relocs--;
@@ -330,14 +325,14 @@ static int check_incr(struct host1x_fire
 	u32 count = fw->count;
 	u32 reg = fw->reg;
 
-	while (fw) {
+	while (count) {
 		if (fw->words == 0)
 			return -EINVAL;
 
 		if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) {
-			bool bad_reloc = check_reloc(fw->reloc, fw->cmdbuf_id,
-						     fw->offset);
-			if (!fw->num_relocs || bad_reloc)
+			if (!fw->num_relocs)
+				return -EINVAL;
+			if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset))
 				return -EINVAL;
 			fw->reloc++;
 			fw->num_relocs--;
@@ -361,9 +356,9 @@ static int check_nonincr(struct host1x_f
 			return -EINVAL;
 
 		if (is_addr_reg) {
-			bool bad_reloc = check_reloc(fw->reloc, fw->cmdbuf_id,
-						     fw->offset);
-			if (!fw->num_relocs || bad_reloc)
+			if (!fw->num_relocs)
+				return -EINVAL;
+			if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset))
 				return -EINVAL;
 			fw->reloc++;
 			fw->num_relocs--;
@@ -376,69 +371,58 @@ static int check_nonincr(struct host1x_f
 	return 0;
 }
 
-static int validate(struct host1x_job *job, struct device *dev,
-		    struct host1x_job_gather *g)
+static int validate(struct host1x_firewall *fw, struct host1x_job_gather *g)
 {
-	u32 *cmdbuf_base;
+	u32 *cmdbuf_base = (u32 *)fw->job->gather_copy_mapped +
+		(g->offset / sizeof(u32));
 	int err = 0;
-	struct host1x_firewall fw;
-
-	fw.job = job;
-	fw.dev = dev;
-	fw.reloc = job->relocarray;
-	fw.num_relocs = job->num_relocs;
-	fw.cmdbuf_id = g->bo;
-
-	fw.offset = 0;
-	fw.class = 0;
 
-	if (!job->is_addr_reg)
+	if (!fw->job->is_addr_reg)
 		return 0;
 
-	cmdbuf_base = host1x_bo_mmap(g->bo);
-	if (!cmdbuf_base)
-		return -ENOMEM;
+	fw->words = g->words;
+	fw->cmdbuf_id = g->bo;
+	fw->offset = 0;
 
-	fw.words = g->words;
-	while (fw.words && !err) {
-		u32 word = cmdbuf_base[fw.offset];
+	while (fw->words && !err) {
+		u32 word = cmdbuf_base[fw->offset];
 		u32 opcode = (word & 0xf0000000) >> 28;
 
-		fw.mask = 0;
-		fw.reg = 0;
-		fw.count = 0;
-		fw.words--;
-		fw.offset++;
+		fw->mask = 0;
+		fw->reg = 0;
+		fw->count = 0;
+		fw->words--;
+		fw->offset++;
 
 		switch (opcode) {
 		case 0:
-			fw.class = word >> 6 & 0x3ff;
-			fw.mask = word & 0x3f;
-			fw.reg = word >> 16 & 0xfff;
-			err = check_mask(&fw);
+			fw->class = word >> 6 & 0x3ff;
+			fw->mask = word & 0x3f;
+			fw->reg = word >> 16 & 0xfff;
+			err = check_mask(fw);
 			if (err)
 				goto out;
 			break;
 		case 1:
-			fw.reg = word >> 16 & 0xfff;
-			fw.count = word & 0xffff;
-			err = check_incr(&fw);
+			fw->reg = word >> 16 & 0xfff;
+			fw->count = word & 0xffff;
+			err = check_incr(fw);
 			if (err)
 				goto out;
 			break;
 
 		case 2:
-			fw.reg = word >> 16 & 0xfff;
-			fw.count = word & 0xffff;
-			err = check_nonincr(&fw);
+			fw->reg = word >> 16 & 0xfff;
+			fw->count = word & 0xffff;
+			err = check_nonincr(fw);
 			if (err)
 				goto out;
 			break;
 
 		case 3:
-			fw.mask = word & 0xffff;
-			fw.reg = word >> 16 & 0xfff;
-			err = check_mask(&fw);
+			fw->mask = word & 0xffff;
+			fw->reg = word >> 16 & 0xfff;
+			err = check_mask(fw);
 			if (err)
 				goto out;
 			break;
@@ -453,21 +437,26 @@ static int validate(struct host1x_job *j
 	}
 
 	/* No relocs should remain at this point */
-	if (fw.num_relocs)
+	if (fw->num_relocs)
 		err = -EINVAL;
 
 out:
-	host1x_bo_munmap(g->bo, cmdbuf_base);
-
 	return err;
 }
 
 static inline int copy_gathers(struct host1x_job *job, struct device *dev)
 {
+	struct host1x_firewall fw;
 	size_t size = 0;
 	size_t offset = 0;
 	int i;
 
+	fw.job = job;
+	fw.dev = dev;
+	fw.reloc = job->relocarray;
+	fw.num_relocs = job->num_relocs;
+	fw.class = 0;
+
 	for (i = 0; i < job->num_gathers; i++) {
 		struct host1x_job_gather *g = &job->gathers[i];
 		size += g->words * sizeof(u32);
@@ -488,14 +477,19 @@ static inline int copy_gathers(struct ho
 		struct host1x_job_gather *g = &job->gathers[i];
 		void *gather;
 
+		/* Copy the gather */
 		gather = host1x_bo_mmap(g->bo);
 		memcpy(job->gather_copy_mapped + offset, gather + g->offset,
 		       g->words * sizeof(u32));
 		host1x_bo_munmap(g->bo, gather);
 
+		/* Store the location in the buffer */
 		g->base = job->gather_copy;
 		g->offset = offset;
-		g->bo = NULL;
+
+		/* Validate the job */
+		if (validate(&fw, g))
+			return -EINVAL;
 
 		offset += g->words * sizeof(u32);
 	}
@@ -540,20 +534,11 @@ int host1x_job_pin(struct host1x_job *jo
 			if (job->gathers[j].bo == g->bo)
 				job->gathers[j].handled = true;
 
-		err = 0;
-
-		if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL))
-			err = validate(job, dev, g);
-
+		err = do_relocs(job, g->bo);
 		if (err)
-			dev_err(dev, "Job invalid (err=%d)\n", err);
-
-		if (!err)
-			err = do_relocs(job, g->bo);
-
-		if (!err)
-			err = do_waitchks(job, host, g->bo);
+			break;
 
+		err = do_waitchks(job, host, g->bo);
 		if (err)
 			break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/host1x/syncpt.c linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/syncpt.c
--- linux-libre-3.10-gnu/drivers/gpu/host1x/syncpt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/syncpt.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,7 @@
 
 static struct host1x_syncpt *_host1x_syncpt_alloc(struct host1x *host,
 						  struct device *dev,
-						  int client_managed)
+						  bool client_managed)
 {
 	int i;
 	struct host1x_syncpt *sp = host->syncpt;
@@ -40,7 +40,8 @@ static struct host1x_syncpt *_host1x_syn
 
 	for (i = 0; i < host->info->nb_pts && sp->name; i++, sp++)
 		;
-	if (sp->dev)
+
+	if (i >= host->info->nb_pts)
 		return NULL;
 
 	name = kasprintf(GFP_KERNEL, "%02d-%s", sp->id,
@@ -128,22 +129,11 @@ u32 host1x_syncpt_load_wait_base(struct
 }
 
 /*
- * Write a cpu syncpoint increment to the hardware, without touching
- * the cache. Caller is responsible for host being powered.
- */
-void host1x_syncpt_cpu_incr(struct host1x_syncpt *sp)
-{
-	host1x_hw_syncpt_cpu_incr(sp->host, sp);
-}
-
-/*
  * Increment syncpoint value from cpu, updating cache
  */
-void host1x_syncpt_incr(struct host1x_syncpt *sp)
+int host1x_syncpt_incr(struct host1x_syncpt *sp)
 {
-	if (host1x_syncpt_client_managed(sp))
-		host1x_syncpt_incr_max(sp, 1);
-	host1x_syncpt_cpu_incr(sp);
+	return host1x_hw_syncpt_cpu_incr(sp->host, sp);
 }
 
 /*
@@ -331,7 +321,7 @@ int host1x_syncpt_init(struct host1x *ho
 	host1x_syncpt_restore(host);
 
 	/* Allocate sync point to use for clearing waits for expired fences */
-	host->nop_sp = _host1x_syncpt_alloc(host, NULL, 0);
+	host->nop_sp = _host1x_syncpt_alloc(host, NULL, false);
 	if (!host->nop_sp)
 		return -ENOMEM;
 
@@ -339,7 +329,7 @@ int host1x_syncpt_init(struct host1x *ho
 }
 
 struct host1x_syncpt *host1x_syncpt_request(struct device *dev,
-					    int client_managed)
+					    bool client_managed)
 {
 	struct host1x *host = dev_get_drvdata(dev->parent);
 	return _host1x_syncpt_alloc(host, dev, client_managed);
@@ -353,7 +343,7 @@ void host1x_syncpt_free(struct host1x_sy
 	kfree(sp->name);
 	sp->dev = NULL;
 	sp->name = NULL;
-	sp->client_managed = 0;
+	sp->client_managed = false;
 }
 
 void host1x_syncpt_deinit(struct host1x *host)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/gpu/host1x/syncpt.h linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/syncpt.h
--- linux-libre-3.10-gnu/drivers/gpu/host1x/syncpt.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/gpu/host1x/syncpt.h	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,7 @@ struct host1x_syncpt {
 	atomic_t max_val;
 	u32 base_val;
 	const char *name;
-	int client_managed;
+	bool client_managed;
 	struct host1x *host;
 	struct device *dev;
 
@@ -94,7 +94,7 @@ static inline bool host1x_syncpt_check_m
 }
 
 /* Return true if sync point is client managed. */
-static inline int host1x_syncpt_client_managed(struct host1x_syncpt *sp)
+static inline bool host1x_syncpt_client_managed(struct host1x_syncpt *sp)
 {
 	return sp->client_managed;
 }
@@ -115,9 +115,6 @@ static inline bool host1x_syncpt_idle(st
 /* Return pointer to struct denoting sync point id. */
 struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id);
 
-/* Request incrementing a sync point. */
-void host1x_syncpt_cpu_incr(struct host1x_syncpt *sp);
-
 /* Load current value from hardware to the shadow register. */
 u32 host1x_syncpt_load(struct host1x_syncpt *sp);
 
@@ -133,8 +130,8 @@ void host1x_syncpt_restore(struct host1x
 /* Read current wait base value into shadow register and return it. */
 u32 host1x_syncpt_load_wait_base(struct host1x_syncpt *sp);
 
-/* Increment sync point and its max. */
-void host1x_syncpt_incr(struct host1x_syncpt *sp);
+/* Request incrementing a sync point. */
+int host1x_syncpt_incr(struct host1x_syncpt *sp);
 
 /* Indicate future operations by incrementing the sync point max. */
 u32 host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs);
@@ -157,7 +154,7 @@ u32 host1x_syncpt_id(struct host1x_syncp
 
 /* Allocate a sync point for a device. */
 struct host1x_syncpt *host1x_syncpt_request(struct device *dev,
-		int client_managed);
+					    bool client_managed);
 
 /* Free a sync point. */
 void host1x_syncpt_free(struct host1x_syncpt *sp);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-apple.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-apple.c
--- linux-libre-3.10-gnu/drivers/hid/hid-apple.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-apple.c	2013-08-25 20:43:22.000000000 -0400
@@ -524,6 +524,12 @@ static const struct hid_device_id apple_
 		.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),
 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI),
+		.driver_data = APPLE_HAS_FN },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO),
+		.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),
+		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-core.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-core.c
--- linux-libre-3.10-gnu/drivers/hid/hid-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -1293,7 +1293,7 @@ int hid_input_report(struct hid_device *
 
 	if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
 		ret = hdrv->raw_event(hid, report, data, size);
-		if (ret != 0) {
+		if (ret < 0) {
 			ret = ret < 0 ? ret : 0;
 			goto unlock;
 		}
@@ -1547,6 +1547,9 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
@@ -1573,6 +1576,8 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
@@ -1584,10 +1589,14 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
@@ -1680,6 +1689,8 @@ static const struct hid_device_id hid_ha
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
@@ -2042,6 +2053,8 @@ static const struct hid_device_id hid_ig
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_410) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_510) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
@@ -2179,6 +2192,9 @@ static const struct hid_device_id hid_mo
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
 	{ }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-elo.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-elo.c
--- linux-libre-3.10-gnu/drivers/hid/hid-elo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-elo.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,273 @@
+/*
+ * HID driver for ELO usb touchscreen 4000/4500
+ *
+ * Copyright (c) 2013 Jiri Slaby
+ *
+ * Data parsing taken from elousb driver by Vojtech Pavlik.
+ *
+ * This driver is licensed under the terms of GPLv2.
+ */
+
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/workqueue.h>
+
+#include "hid-ids.h"
+
+#define ELO_PERIODIC_READ_INTERVAL	HZ
+#define ELO_SMARTSET_CMD_TIMEOUT	2000 /* msec */
+
+/* Elo SmartSet commands */
+#define ELO_FLUSH_SMARTSET_RESPONSES	0x02 /* Flush all pending smartset responses */
+#define ELO_SEND_SMARTSET_COMMAND	0x05 /* Send a smartset command */
+#define ELO_GET_SMARTSET_RESPONSE	0x06 /* Get a smartset response */
+#define ELO_DIAG			0x64 /* Diagnostics command */
+#define ELO_SMARTSET_PACKET_SIZE	8
+
+struct elo_priv {
+	struct usb_device *usbdev;
+	struct delayed_work work;
+	unsigned char buffer[ELO_SMARTSET_PACKET_SIZE];
+};
+
+static struct workqueue_struct *wq;
+static bool use_fw_quirk = true;
+module_param(use_fw_quirk, bool, S_IRUGO);
+MODULE_PARM_DESC(use_fw_quirk, "Do periodic pokes for broken M firmwares (default = true)");
+
+static void elo_input_configured(struct hid_device *hdev,
+		struct hid_input *hidinput)
+{
+	struct input_dev *input = hidinput->input;
+
+	set_bit(BTN_TOUCH, input->keybit);
+	set_bit(ABS_PRESSURE, input->absbit);
+	input_set_abs_params(input, ABS_PRESSURE, 0, 256, 0, 0);
+}
+
+static void elo_process_data(struct input_dev *input, const u8 *data, int size)
+{
+	int press;
+
+	input_report_abs(input, ABS_X, (data[3] << 8) | data[2]);
+	input_report_abs(input, ABS_Y, (data[5] << 8) | data[4]);
+
+	press = 0;
+	if (data[1] & 0x80)
+		press = (data[7] << 8) | data[6];
+	input_report_abs(input, ABS_PRESSURE, press);
+
+	if (data[1] & 0x03) {
+		input_report_key(input, BTN_TOUCH, 1);
+		input_sync(input);
+	}
+
+	if (data[1] & 0x04)
+		input_report_key(input, BTN_TOUCH, 0);
+
+	input_sync(input);
+}
+
+static int elo_raw_event(struct hid_device *hdev, struct hid_report *report,
+	 u8 *data, int size)
+{
+	struct hid_input *hidinput;
+
+	if (!(hdev->claimed & HID_CLAIMED_INPUT) || list_empty(&hdev->inputs))
+		return 0;
+
+	hidinput = list_first_entry(&hdev->inputs, struct hid_input, list);
+
+	switch (report->id) {
+	case 0:
+		if (data[0] == 'T') {	/* Mandatory ELO packet marker */
+			elo_process_data(hidinput->input, data, size);
+			return 1;
+		}
+		break;
+	default:	/* unknown report */
+		/* Unknown report type; pass upstream */
+		hid_info(hdev, "unknown report type %d\n", report->id);
+		break;
+	}
+
+	return 0;
+}
+
+static int elo_smartset_send_get(struct usb_device *dev, u8 command,
+		void *data)
+{
+	unsigned int pipe;
+	u8 dir;
+
+	if (command == ELO_SEND_SMARTSET_COMMAND) {
+		pipe = usb_sndctrlpipe(dev, 0);
+		dir = USB_DIR_OUT;
+	} else if (command == ELO_GET_SMARTSET_RESPONSE) {
+		pipe = usb_rcvctrlpipe(dev, 0);
+		dir = USB_DIR_IN;
+	} else
+		return -EINVAL;
+
+	return usb_control_msg(dev, pipe, command,
+			dir | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0, 0, data, ELO_SMARTSET_PACKET_SIZE,
+			ELO_SMARTSET_CMD_TIMEOUT);
+}
+
+static int elo_flush_smartset_responses(struct usb_device *dev)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+			ELO_FLUSH_SMARTSET_RESPONSES,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+}
+
+static void elo_work(struct work_struct *work)
+{
+	struct elo_priv *priv = container_of(work, struct elo_priv, work.work);
+	struct usb_device *dev = priv->usbdev;
+	unsigned char *buffer = priv->buffer;
+	int ret;
+
+	ret = elo_flush_smartset_responses(dev);
+	if (ret < 0) {
+		dev_err(&dev->dev, "initial FLUSH_SMARTSET_RESPONSES failed, error %d\n",
+				ret);
+		goto fail;
+	}
+
+	/* send Diagnostics command */
+	*buffer = ELO_DIAG;
+	ret = elo_smartset_send_get(dev, ELO_SEND_SMARTSET_COMMAND, buffer);
+	if (ret < 0) {
+		dev_err(&dev->dev, "send Diagnostics Command failed, error %d\n",
+				ret);
+		goto fail;
+	}
+
+	/* get the result */
+	ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE, buffer);
+	if (ret < 0) {
+		dev_err(&dev->dev, "get Diagnostics Command response failed, error %d\n",
+				ret);
+		goto fail;
+	}
+
+	/* read the ack */
+	if (*buffer != 'A') {
+		ret = elo_smartset_send_get(dev, ELO_GET_SMARTSET_RESPONSE,
+				buffer);
+		if (ret < 0) {
+			dev_err(&dev->dev, "get acknowledge response failed, error %d\n",
+					ret);
+			goto fail;
+		}
+	}
+
+fail:
+	ret = elo_flush_smartset_responses(dev);
+	if (ret < 0)
+		dev_err(&dev->dev, "final FLUSH_SMARTSET_RESPONSES failed, error %d\n",
+				ret);
+	queue_delayed_work(wq, &priv->work, ELO_PERIODIC_READ_INTERVAL);
+}
+
+/*
+ * Not all Elo devices need the periodic HID descriptor reads.
+ * Only firmware version M needs this.
+ */
+static bool elo_broken_firmware(struct usb_device *dev)
+{
+	return use_fw_quirk && le16_to_cpu(dev->descriptor.bcdDevice) == 0x10d;
+}
+
+static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	struct elo_priv *priv;
+	int ret;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	INIT_DELAYED_WORK(&priv->work, elo_work);
+	priv->usbdev = interface_to_usbdev(to_usb_interface(hdev->dev.parent));
+
+	hid_set_drvdata(hdev, priv);
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		hid_err(hdev, "parse failed\n");
+		goto err_free;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+	if (ret) {
+		hid_err(hdev, "hw start failed\n");
+		goto err_free;
+	}
+
+	if (elo_broken_firmware(priv->usbdev)) {
+		hid_info(hdev, "broken firmware found, installing workaround\n");
+		queue_delayed_work(wq, &priv->work, ELO_PERIODIC_READ_INTERVAL);
+	}
+
+	return 0;
+err_free:
+	kfree(priv);
+	return ret;
+}
+
+static void elo_remove(struct hid_device *hdev)
+{
+	struct elo_priv *priv = hid_get_drvdata(hdev);
+
+	hid_hw_stop(hdev);
+	flush_workqueue(wq);
+	kfree(priv);
+}
+
+static const struct hid_device_id elo_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009), },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030), },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, elo_devices);
+
+static struct hid_driver elo_driver = {
+	.name = "elo",
+	.id_table = elo_devices,
+	.probe = elo_probe,
+	.remove = elo_remove,
+	.raw_event = elo_raw_event,
+	.input_configured = elo_input_configured,
+};
+
+static int __init elo_driver_init(void)
+{
+	int ret;
+
+	wq = create_singlethread_workqueue("elousb");
+	if (!wq)
+		return -ENOMEM;
+
+	ret = hid_register_driver(&elo_driver);
+	if (ret)
+		destroy_workqueue(wq);
+
+	return ret;
+}
+module_init(elo_driver_init);
+
+static void __exit elo_driver_exit(void)
+{
+	hid_unregister_driver(&elo_driver);
+	destroy_workqueue(wq);
+}
+module_exit(elo_driver_exit);
+
+MODULE_AUTHOR("Jiri Slaby <jslaby@suse.cz>");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-holtek-mouse.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-holtek-mouse.c
--- linux-libre-3.10-gnu/drivers/hid/hid-holtek-mouse.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-holtek-mouse.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,77 @@
+/*
+ * HID driver for Holtek gaming mice
+ * Copyright (c) 2013 Christian Ohm
+ * Heavily inspired by various other HID drivers that adjust the report
+ * descriptor.
+*/
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "hid-ids.h"
+
+/*
+ * The report descriptor of some Holtek based gaming mice specifies an
+ * excessively large number of consumer usages (2^15), which is more than
+ * HID_MAX_USAGES. This prevents proper parsing of the report descriptor.
+ *
+ * This driver fixes the report descriptor for:
+ * - USB ID 04d9:a067, sold as Sharkoon Drakonia and Perixx MX-2000
+ * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200
+ *   and Zalman ZM-GM1
+ */
+
+static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+		unsigned int *rsize)
+{
+	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+
+	if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+		/* Change usage maximum and logical maximum from 0x7fff to
+		 * 0x2fff, so they don't exceed HID_MAX_USAGES */
+		switch (hdev->product) {
+		case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067:
+			if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f
+					&& rdesc[120] == 0xff && rdesc[121] == 0x7f) {
+				hid_info(hdev, "Fixing up report descriptor\n");
+				rdesc[116] = rdesc[121] = 0x2f;
+			}
+			break;
+		case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A:
+			if (*rsize >= 113 && rdesc[106] == 0xff && rdesc[107] == 0x7f
+					&& rdesc[111] == 0xff && rdesc[112] == 0x7f) {
+				hid_info(hdev, "Fixing up report descriptor\n");
+				rdesc[107] = rdesc[112] = 0x2f;
+			}
+			break;
+		}
+
+	}
+	return rdesc;
+}
+
+static const struct hid_device_id holtek_mouse_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
+			USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
+			USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, holtek_mouse_devices);
+
+static struct hid_driver holtek_mouse_driver = {
+	.name = "holtek_mouse",
+	.id_table = holtek_mouse_devices,
+	.report_fixup = holtek_mouse_report_fixup,
+};
+
+module_hid_driver(holtek_mouse_driver);
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-huion.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-huion.c
--- linux-libre-3.10-gnu/drivers/hid/hid-huion.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-huion.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,177 @@
+/*
+ *  HID driver for Huion devices not fully compliant with HID standard
+ *
+ *  Copyright (c) 2013 Martin Rusko
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include "usbhid/usbhid.h"
+
+#include "hid-ids.h"
+
+/* Original Huion 580 report descriptor size */
+#define HUION_580_RDESC_ORIG_SIZE	177
+
+/* Fixed Huion 580 report descriptor */
+static __u8 huion_580_rdesc_fixed[] = {
+	0x05, 0x0D,         /*  Usage Page (Digitizer),             */
+	0x09, 0x02,         /*  Usage (Pen),                        */
+	0xA1, 0x01,         /*  Collection (Application),           */
+	0x85, 0x07,         /*      Report ID (7),                  */
+	0x09, 0x20,         /*      Usage (Stylus),                 */
+	0xA0,               /*      Collection (Physical),          */
+	0x14,               /*          Logical Minimum (0),        */
+	0x25, 0x01,         /*          Logical Maximum (1),        */
+	0x75, 0x01,         /*          Report Size (1),            */
+	0x09, 0x42,         /*          Usage (Tip Switch),         */
+	0x09, 0x44,         /*          Usage (Barrel Switch),      */
+	0x09, 0x46,         /*          Usage (Tablet Pick),        */
+	0x95, 0x03,         /*          Report Count (3),           */
+	0x81, 0x02,         /*          Input (Variable),           */
+	0x95, 0x03,         /*          Report Count (3),           */
+	0x81, 0x03,         /*          Input (Constant, Variable), */
+	0x09, 0x32,         /*          Usage (In Range),           */
+	0x95, 0x01,         /*          Report Count (1),           */
+	0x81, 0x02,         /*          Input (Variable),           */
+	0x95, 0x01,         /*          Report Count (1),           */
+	0x81, 0x03,         /*          Input (Constant, Variable), */
+	0x75, 0x10,         /*          Report Size (16),           */
+	0x95, 0x01,         /*          Report Count (1),           */
+	0xA4,               /*          Push,                       */
+	0x05, 0x01,         /*          Usage Page (Desktop),       */
+	0x65, 0x13,         /*          Unit (Inch),                */
+	0x55, 0xFD,         /*          Unit Exponent (-3),         */
+	0x34,               /*          Physical Minimum (0),       */
+	0x09, 0x30,         /*          Usage (X),                  */
+	0x46, 0x40, 0x1F,   /*          Physical Maximum (8000),    */
+	0x26, 0x00, 0x7D,   /*          Logical Maximum (32000),    */
+	0x81, 0x02,         /*          Input (Variable),           */
+	0x09, 0x31,         /*          Usage (Y),                  */
+	0x46, 0x88, 0x13,   /*          Physical Maximum (5000),    */
+	0x26, 0x20, 0x4E,   /*          Logical Maximum (20000),    */
+	0x81, 0x02,         /*          Input (Variable),           */
+	0xB4,               /*          Pop,                        */
+	0x09, 0x30,         /*          Usage (Tip Pressure),       */
+	0x26, 0xFF, 0x07,   /*          Logical Maximum (2047),     */
+	0x81, 0x02,         /*          Input (Variable),           */
+	0xC0,               /*      End Collection,                 */
+	0xC0                /*  End Collection                      */
+};
+
+static __u8 *huion_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+		unsigned int *rsize)
+{
+	switch (hdev->product) {
+	case USB_DEVICE_ID_HUION_580:
+		if (*rsize == HUION_580_RDESC_ORIG_SIZE) {
+			rdesc = huion_580_rdesc_fixed;
+			*rsize = sizeof(huion_580_rdesc_fixed);
+		}
+		break;
+	}
+	return rdesc;
+}
+
+/**
+ * Enable fully-functional tablet mode by reading special string
+ * descriptor.
+ *
+ * @hdev:	HID device
+ *
+ * The specific string descriptor and data were discovered by sniffing
+ * the Windows driver traffic.
+ */
+static int huion_tablet_enable(struct hid_device *hdev)
+{
+	int rc;
+	char buf[22];
+
+	rc = usb_string(hid_to_usb_dev(hdev), 0x64, buf, sizeof(buf));
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
+static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+
+	/* Ignore interfaces 1 (mouse) and 2 (keyboard) for Huion 580 tablet,
+	 * as they are not used
+	 */
+	switch (id->product) {
+	case USB_DEVICE_ID_HUION_580:
+		if (intf->cur_altsetting->desc.bInterfaceNumber != 0x00)
+			return -ENODEV;
+		break;
+	}
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		hid_err(hdev, "parse failed\n");
+		goto err;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+	if (ret) {
+		hid_err(hdev, "hw start failed\n");
+		goto err;
+	}
+
+	switch (id->product) {
+	case USB_DEVICE_ID_HUION_580:
+		ret = huion_tablet_enable(hdev);
+		if (ret) {
+			hid_err(hdev, "tablet enabling failed\n");
+			goto enabling_err;
+		}
+		break;
+	}
+
+	return 0;
+enabling_err:
+	hid_hw_stop(hdev);
+err:
+	return ret;
+}
+
+static int huion_raw_event(struct hid_device *hdev, struct hid_report *report,
+			u8 *data, int size)
+{
+	/* If this is a pen input report then invert the in-range bit */
+	if (report->type == HID_INPUT_REPORT && report->id == 0x07 && size >= 2)
+		data[1] ^= 0x40;
+
+	return 0;
+}
+
+static const struct hid_device_id huion_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, huion_devices);
+
+static struct hid_driver huion_driver = {
+	.name = "huion",
+	.id_table = huion_devices,
+	.probe = huion_probe,
+	.report_fixup = huion_report_fixup,
+	.raw_event = huion_raw_event,
+};
+module_hid_driver(huion_driver);
+
+MODULE_AUTHOR("Martin Rusko");
+MODULE_DESCRIPTION("Huion HID driver");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-hyperv.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-hyperv.c
--- linux-libre-3.10-gnu/drivers/hid/hid-hyperv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-hyperv.c	2013-08-25 20:43:22.000000000 -0400
@@ -199,13 +199,11 @@ static void mousevsc_on_receive_device_i
 	if (desc->bLength == 0)
 		goto cleanup;
 
-	input_device->hid_desc = kzalloc(desc->bLength, GFP_ATOMIC);
+	input_device->hid_desc = kmemdup(desc, desc->bLength, GFP_ATOMIC);
 
 	if (!input_device->hid_desc)
 		goto cleanup;
 
-	memcpy(input_device->hid_desc, desc, desc->bLength);
-
 	input_device->report_desc_size = desc->desc[0].wDescriptorLength;
 	if (input_device->report_desc_size == 0) {
 		input_device->dev_info_status = -EINVAL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-ids.h linux-libre-3.11-rc7-gnu/drivers/hid/hid-ids.h
--- linux-libre-3.10-gnu/drivers/hid/hid-ids.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-ids.h	2013-08-25 20:43:22.000000000 -0400
@@ -135,6 +135,9 @@
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS   0x023b
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI  0x0255
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO   0x0256
+#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI	0x0291
+#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO	0x0292
+#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS	0x0293
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY	0x030a
 #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY	0x030b
 #define USB_DEVICE_ID_APPLE_IRCONTROL	0x8240
@@ -248,6 +251,9 @@
 #define USB_DEVICE_ID_CYPRESS_BARCODE_4	0xed81
 #define USB_DEVICE_ID_CYPRESS_TRUETOUCH	0xc001
 
+#define USB_VENDOR_ID_DATA_MODUL	0x7374
+#define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH	0x1201
+
 #define USB_VENDOR_ID_DEALEXTREAME	0x10c5
 #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701	0x819a
 
@@ -272,16 +278,15 @@
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E	0x725e
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262	0x7262
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B	0x726b
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA	0x72aa
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1	0x72a1
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA	0x72aa
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4	0x72c4
+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0	0x72d0
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA	0x72fa
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302	0x7302
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349	0x7349
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7	0x73f7
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001	0xa001
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224      0x7224
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0      0x72d0
-#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4      0x72c4
 
 #define USB_VENDOR_ID_ELECOM		0x056e
 #define USB_DEVICE_ID_ELECOM_BM084	0x0061
@@ -425,6 +430,9 @@
 #define USB_DEVICE_ID_UGCI_FLYING	0x0020
 #define USB_DEVICE_ID_UGCI_FIGHTING	0x0030
 
+#define USB_VENDOR_ID_HUION		0x256c
+#define USB_DEVICE_ID_HUION_580		0x006e
+
 #define USB_VENDOR_ID_IDEACOM		0x1cb6
 #define USB_DEVICE_ID_IDEACOM_IDC6650	0x6650
 #define USB_DEVICE_ID_IDEACOM_IDC6651	0x6651
@@ -440,6 +448,8 @@
 
 #define USB_VENDOR_ID_HOLTEK_ALT		0x04d9
 #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD	0xa055
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067	0xa067
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A	0xa04a
 
 #define USB_VENDOR_ID_IMATION		0x0718
 #define USB_DEVICE_ID_DISC_STAKKA	0xd000
@@ -447,6 +457,10 @@
 #define USB_VENDOR_ID_IRTOUCHSYSTEMS	0x6615
 #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB	0x0070
 
+#define USB_VENDOR_ID_JABRA		0x0b0e
+#define USB_DEVICE_ID_JABRA_SPEAK_410	0x0412
+#define USB_DEVICE_ID_JABRA_SPEAK_510	0x0420
+
 #define USB_VENDOR_ID_JESS		0x0c45
 #define USB_DEVICE_ID_JESS_YUREX	0x1010
 
@@ -467,6 +481,7 @@
 
 #define USB_VENDOR_ID_KYE		0x0458
 #define USB_DEVICE_ID_KYE_ERGO_525V	0x0087
+#define USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE	0x0138
 #define USB_DEVICE_ID_KYE_GPEN_560	0x5003
 #define USB_DEVICE_ID_KYE_EASYPEN_I405X	0x5010
 #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X	0x5011
@@ -734,6 +749,8 @@
 #define USB_DEVICE_ID_SONY_PS3_BDREMOTE		0x0306
 #define USB_DEVICE_ID_SONY_PS3_CONTROLLER	0x0268
 #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER	0x042f
+#define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER		0x0002
+#define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER	0x1000
 
 #define USB_VENDOR_ID_SOUNDGRAPH	0x15c2
 #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST	0x0034
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-input.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-input.c
--- linux-libre-3.10-gnu/drivers/hid/hid-input.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-input.c	2013-08-25 20:43:22.000000000 -0400
@@ -354,10 +354,10 @@ static int hidinput_get_battery_property
 					      dev->battery_report_type);
 
 		if (ret != 2) {
-			if (ret >= 0)
-				ret = -EINVAL;
+			ret = -ENODATA;
 			break;
 		}
+		ret = 0;
 
 		if (dev->battery_min < dev->battery_max &&
 		    buf[1] >= dev->battery_min &&
@@ -1042,9 +1042,14 @@ void hidinput_hid_event(struct hid_devic
 
 	/*
 	 * Ignore out-of-range values as per HID specification,
-	 * section 5.10 and 6.2.25
+	 * section 5.10 and 6.2.25.
+	 *
+	 * The logical_minimum < logical_maximum check is done so that we
+	 * don't unintentionally discard values sent by devices which
+	 * don't specify logical min and max.
 	 */
 	if ((field->flags & HID_MAIN_ITEM_VARIABLE) &&
+	    (field->logical_minimum < field->logical_maximum) &&
 	    (value < field->logical_minimum ||
 	     value > field->logical_maximum)) {
 		dbg_hid("Ignoring out-of-range value %x\n", value);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-kye.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-kye.c
--- linux-libre-3.10-gnu/drivers/hid/hid-kye.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-kye.c	2013-08-25 20:43:22.000000000 -0400
@@ -314,6 +314,25 @@ static __u8 *kye_report_fixup(struct hid
 			*rsize = sizeof(easypen_m610x_rdesc_fixed);
 		}
 		break;
+	case USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE:
+		/*
+		 * the fixup that need to be done:
+		 *   - change Usage Maximum in the Comsumer Control
+		 *     (report ID 3) to a reasonable value
+		 */
+		if (*rsize >= 135 &&
+			/* Usage Page (Consumer Devices) */
+			rdesc[104] == 0x05 && rdesc[105] == 0x0c &&
+			/* Usage (Consumer Control) */
+			rdesc[106] == 0x09 && rdesc[107] == 0x01 &&
+			/*   Usage Maximum > 12287 */
+			rdesc[114] == 0x2a && rdesc[116] > 0x2f) {
+			hid_info(hdev,
+				 "fixing up Genius Gila Gaming Mouse "
+				 "report descriptor\n");
+			rdesc[116] = 0x2f;
+		}
+		break;
 	}
 	return rdesc;
 }
@@ -407,6 +426,8 @@ static const struct hid_device_id kye_de
 				USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
 				USB_DEVICE_ID_KYE_EASYPEN_M610X) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE,
+				USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, kye_devices);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-logitech-dj.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-logitech-dj.c
--- linux-libre-3.10-gnu/drivers/hid/hid-logitech-dj.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-logitech-dj.c	2013-08-25 20:43:22.000000000 -0400
@@ -192,6 +192,7 @@ static struct hid_ll_driver logi_dj_ll_d
 static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
 					size_t count,
 					unsigned char report_type);
+static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
 
 static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
 						struct dj_report *dj_report)
@@ -232,6 +233,7 @@ static void logi_dj_recv_add_djhid_devic
 	if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
 	    SPFUNCTION_DEVICE_LIST_EMPTY) {
 		dbg_hid("%s: device list is empty\n", __func__);
+		djrcv_dev->querying_devices = false;
 		return;
 	}
 
@@ -242,6 +244,12 @@ static void logi_dj_recv_add_djhid_devic
 		return;
 	}
 
+	if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
+		/* The device is already known. No need to reallocate it. */
+		dbg_hid("%s: device is already known\n", __func__);
+		return;
+	}
+
 	dj_hiddev = hid_allocate_device();
 	if (IS_ERR(dj_hiddev)) {
 		dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n",
@@ -305,6 +313,7 @@ static void delayedwork_callback(struct
 	struct dj_report dj_report;
 	unsigned long flags;
 	int count;
+	int retval;
 
 	dbg_hid("%s\n", __func__);
 
@@ -337,6 +346,25 @@ static void delayedwork_callback(struct
 		logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
 		break;
 	default:
+	/* A normal report (i. e. not belonging to a pair/unpair notification)
+	 * arriving here, means that the report arrived but we did not have a
+	 * paired dj_device associated to the report's device_index, this
+	 * means that the original "device paired" notification corresponding
+	 * to this dj_device never arrived to this driver. The reason is that
+	 * hid-core discards all packets coming from a device while probe() is
+	 * executing. */
+	if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
+		/* ok, we don't know the device, just re-ask the
+		 * receiver for the list of connected devices. */
+		retval = logi_dj_recv_query_paired_devices(djrcv_dev);
+		if (!retval) {
+			/* everything went fine, so just leave */
+			break;
+		}
+		dev_err(&djrcv_dev->hdev->dev,
+			"%s:logi_dj_recv_query_paired_devices "
+			"error:%d\n", __func__, retval);
+		}
 		dbg_hid("%s: unexpected report type\n", __func__);
 	}
 }
@@ -367,6 +395,12 @@ static void logi_dj_recv_forward_null_re
 	if (!djdev) {
 		dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
 			" is NULL, index %d\n", dj_report->device_index);
+		kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
+
+		if (schedule_work(&djrcv_dev->work) == 0) {
+			dbg_hid("%s: did not schedule the work item, was already "
+			"queued\n", __func__);
+		}
 		return;
 	}
 
@@ -397,6 +431,12 @@ static void logi_dj_recv_forward_report(
 	if (dj_device == NULL) {
 		dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
 			" is NULL, index %d\n", dj_report->device_index);
+		kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
+
+		if (schedule_work(&djrcv_dev->work) == 0) {
+			dbg_hid("%s: did not schedule the work item, was already "
+			"queued\n", __func__);
+		}
 		return;
 	}
 
@@ -444,6 +484,10 @@ static int logi_dj_recv_query_paired_dev
 	struct dj_report *dj_report;
 	int retval;
 
+	/* no need to protect djrcv_dev->querying_devices */
+	if (djrcv_dev->querying_devices)
+		return 0;
+
 	dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
 	if (!dj_report)
 		return -ENOMEM;
@@ -455,6 +499,7 @@ static int logi_dj_recv_query_paired_dev
 	return retval;
 }
 
+
 static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
 					  unsigned timeout)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-logitech-dj.h linux-libre-3.11-rc7-gnu/drivers/hid/hid-logitech-dj.h
--- linux-libre-3.10-gnu/drivers/hid/hid-logitech-dj.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-logitech-dj.h	2013-08-25 20:43:22.000000000 -0400
@@ -101,6 +101,7 @@ struct dj_receiver_dev {
 	struct work_struct work;
 	struct kfifo notif_fifo;
 	spinlock_t lock;
+	bool querying_devices;
 };
 
 struct dj_device {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-multitouch.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-multitouch.c
--- linux-libre-3.10-gnu/drivers/hid/hid-multitouch.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-multitouch.c	2013-08-25 20:43:22.000000000 -0400
@@ -1111,6 +1111,11 @@ static const struct hid_device_id mt_dev
 		HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
 			USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
 
+	/* Data Modul easyMaxTouch */
+	{ .driver_data = MT_CLS_DEFAULT,
+		MT_USB_DEVICE(USB_VENDOR_ID_DATA_MODUL,
+			USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH) },
+
 	/* eGalax devices (resistive) */
 	{ .driver_data = MT_CLS_EGALAX,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
@@ -1120,34 +1125,40 @@ static const struct hid_device_id mt_dev
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
 
 	/* eGalax devices (capacitive) */
-	{ .driver_data = MT_CLS_EGALAX,
-		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
 	{ .driver_data = MT_CLS_EGALAX_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) },
-	{ .driver_data = MT_CLS_EGALAX_SERIAL,
+	{ .driver_data = MT_CLS_EGALAX,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) },
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
 	{ .driver_data = MT_CLS_EGALAX_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) },
 	{ .driver_data = MT_CLS_EGALAX_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) },
-	{ .driver_data = MT_CLS_EGALAX,
+	{ .driver_data = MT_CLS_EGALAX_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) },
 	{ .driver_data = MT_CLS_EGALAX_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) },
 	{ .driver_data = MT_CLS_EGALAX,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
+	{ .driver_data = MT_CLS_EGALAX,
+		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
 	{ .driver_data = MT_CLS_EGALAX_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) },
 	{ .driver_data = MT_CLS_EGALAX,
+		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4) },
+	{ .driver_data = MT_CLS_EGALAX,
+		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0) },
+	{ .driver_data = MT_CLS_EGALAX,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) },
 	{ .driver_data = MT_CLS_EGALAX,
@@ -1162,15 +1173,6 @@ static const struct hid_device_id mt_dev
 	{ .driver_data = MT_CLS_EGALAX_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_DWAV,
 			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
-	{ .driver_data = MT_CLS_EGALAX,
-		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) },
-	{ .driver_data = MT_CLS_EGALAX,
-		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0) },
-	{ .driver_data = MT_CLS_EGALAX,
-		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4) },
 
 	/* Elo TouchSystems IntelliTouch Plus panel */
 	{ .driver_data = MT_CLS_DUAL_CONTACT_ID,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-ps3remote.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-ps3remote.c
--- linux-libre-3.10-gnu/drivers/hid/hid-ps3remote.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-ps3remote.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,204 +0,0 @@
-/*
- * HID driver for Sony PS3 BD Remote Control
- *
- * Copyright (c) 2012 David Dillow <dave@thedillows.org>
- * Based on a blend of the bluez fakehid user-space code by Marcel Holtmann
- * and other kernel HID drivers.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-/* NOTE: in order for the Sony PS3 BD Remote Control to be found by
- * a Bluetooth host, the key combination Start+Enter has to be kept pressed
- * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
- *
- * There will be no PIN request from the device.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-static __u8 ps3remote_rdesc[] = {
-	0x05, 0x01,          /* GUsagePage Generic Desktop */
-	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
-	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
-
-	 /* Use collection 1 for joypad buttons */
-	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
-
-	  /* Ignore the 1st byte, maybe it is used for a controller
-	   * number but it's not needed for correct operation */
-	  0x75, 0x08,        /* GReportSize 0x08 [8] */
-	  0x95, 0x01,        /* GReportCount 0x01 [1] */
-	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
-
-	  /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
-	   * buttons multiple keypresses are allowed */
-	  0x05, 0x09,        /* GUsagePage Button */
-	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
-	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
-	  0x14,              /* GLogicalMinimum [0] */
-	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
-	  0x75, 0x01,        /* GReportSize 0x01 [1] */
-	  0x95, 0x18,        /* GReportCount 0x18 [24] */
-	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
-
-	  0xC0,              /* MEndCollection */
-
-	 /* Use collection 2 for remote control buttons */
-	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
-
-	  /* 5th byte is used for remote control buttons */
-	  0x05, 0x09,        /* GUsagePage Button */
-	  0x18,              /* LUsageMinimum [No button pressed] */
-	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
-	  0x14,              /* GLogicalMinimum [0] */
-	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
-	  0x75, 0x08,        /* GReportSize 0x08 [8] */
-	  0x95, 0x01,        /* GReportCount 0x01 [1] */
-	  0x80,              /* MInput  */
-
-	  /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
-	   * 0xff and 11th is for press indication */
-	  0x75, 0x08,        /* GReportSize 0x08 [8] */
-	  0x95, 0x06,        /* GReportCount 0x06 [6] */
-	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
-
-	  /* 12th byte is for battery strength */
-	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
-	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
-	  0x14,              /* GLogicalMinimum [0] */
-	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
-	  0x75, 0x08,        /* GReportSize 0x08 [8] */
-	  0x95, 0x01,        /* GReportCount 0x01 [1] */
-	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
-
-	  0xC0,              /* MEndCollection */
-
-	 0xC0                /* MEndCollection [Game Pad] */
-};
-
-static const unsigned int ps3remote_keymap_joypad_buttons[] = {
-	[0x01] = KEY_SELECT,
-	[0x02] = BTN_THUMBL,		/* L3 */
-	[0x03] = BTN_THUMBR,		/* R3 */
-	[0x04] = BTN_START,
-	[0x05] = KEY_UP,
-	[0x06] = KEY_RIGHT,
-	[0x07] = KEY_DOWN,
-	[0x08] = KEY_LEFT,
-	[0x09] = BTN_TL2,		/* L2 */
-	[0x0a] = BTN_TR2,		/* R2 */
-	[0x0b] = BTN_TL,		/* L1 */
-	[0x0c] = BTN_TR,		/* R1 */
-	[0x0d] = KEY_OPTION,		/* options/triangle */
-	[0x0e] = KEY_BACK,		/* back/circle */
-	[0x0f] = BTN_0,			/* cross */
-	[0x10] = KEY_SCREEN,		/* view/square */
-	[0x11] = KEY_HOMEPAGE,		/* PS button */
-	[0x14] = KEY_ENTER,
-};
-static const unsigned int ps3remote_keymap_remote_buttons[] = {
-	[0x00] = KEY_1,
-	[0x01] = KEY_2,
-	[0x02] = KEY_3,
-	[0x03] = KEY_4,
-	[0x04] = KEY_5,
-	[0x05] = KEY_6,
-	[0x06] = KEY_7,
-	[0x07] = KEY_8,
-	[0x08] = KEY_9,
-	[0x09] = KEY_0,
-	[0x0e] = KEY_ESC,		/* return */
-	[0x0f] = KEY_CLEAR,
-	[0x16] = KEY_EJECTCD,
-	[0x1a] = KEY_MENU,		/* top menu */
-	[0x28] = KEY_TIME,
-	[0x30] = KEY_PREVIOUS,
-	[0x31] = KEY_NEXT,
-	[0x32] = KEY_PLAY,
-	[0x33] = KEY_REWIND,		/* scan back */
-	[0x34] = KEY_FORWARD,		/* scan forward */
-	[0x38] = KEY_STOP,
-	[0x39] = KEY_PAUSE,
-	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
-	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
-	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
-	[0x63] = KEY_SUBTITLE,
-	[0x64] = KEY_AUDIO,
-	[0x65] = KEY_ANGLE,
-	[0x70] = KEY_INFO,		/* display */
-	[0x80] = KEY_BLUE,
-	[0x81] = KEY_RED,
-	[0x82] = KEY_GREEN,
-	[0x83] = KEY_YELLOW,
-};
-
-static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
-			     unsigned int *rsize)
-{
-	*rsize = sizeof(ps3remote_rdesc);
-	return ps3remote_rdesc;
-}
-
-static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
-			     struct hid_field *field, struct hid_usage *usage,
-			     unsigned long **bit, int *max)
-{
-	unsigned int key = usage->hid & HID_USAGE;
-
-	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
-		return -1;
-
-	switch (usage->collection_index) {
-	case 1:
-		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
-			return -1;
-
-		key = ps3remote_keymap_joypad_buttons[key];
-		if (!key)
-			return -1;
-		break;
-	case 2:
-		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
-			return -1;
-
-		key = ps3remote_keymap_remote_buttons[key];
-		if (!key)
-			return -1;
-		break;
-	default:
-		return -1;
-	}
-
-	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
-	return 1;
-}
-
-static const struct hid_device_id ps3remote_devices[] = {
-	/* PS3 BD Remote Control */
-	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
-	/* Logitech Harmony Adapter for PS3 */
-	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
-	{ }
-};
-MODULE_DEVICE_TABLE(hid, ps3remote_devices);
-
-static struct hid_driver ps3remote_driver = {
-	.name          = "ps3_remote",
-	.id_table      = ps3remote_devices,
-	.report_fixup  = ps3remote_fixup,
-	.input_mapping = ps3remote_mapping,
-};
-module_hid_driver(ps3remote_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hidraw.c linux-libre-3.11-rc7-gnu/drivers/hid/hidraw.c
--- linux-libre-3.10-gnu/drivers/hid/hidraw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hidraw.c	2013-08-25 20:43:22.000000000 -0400
@@ -518,7 +518,6 @@ int hidraw_connect(struct hid_device *hi
 		goto out;
 	}
 
-	mutex_unlock(&minors_lock);
 	init_waitqueue_head(&dev->wait);
 	INIT_LIST_HEAD(&dev->list);
 
@@ -528,6 +527,7 @@ int hidraw_connect(struct hid_device *hi
 	dev->exist = 1;
 	hid->hidraw = dev;
 
+	mutex_unlock(&minors_lock);
 out:
 	return result;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-roccat.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-roccat.c
--- linux-libre-3.10-gnu/drivers/hid/hid-roccat.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-roccat.c	2013-08-25 20:43:22.000000000 -0400
@@ -366,7 +366,7 @@ void roccat_disconnect(int minor)
 	mutex_lock(&devices_lock);
 	devices[minor] = NULL;
 	mutex_unlock(&devices_lock);
-	
+
 	if (device->open) {
 		hid_hw_close(device->hid);
 		wake_up_interruptible(&device->wait);
@@ -426,13 +426,23 @@ static int __init roccat_init(void)
 
 	if (retval < 0) {
 		pr_warn("can't get major number\n");
-		return retval;
+		goto error;
 	}
 
 	cdev_init(&roccat_cdev, &roccat_ops);
-	cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES);
+	retval = cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES);
 
+	if (retval < 0) {
+		pr_warn("cannot add cdev\n");
+		goto cleanup_alloc_chrdev_region;
+	}
 	return 0;
+
+
+ cleanup_alloc_chrdev_region:
+	unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES);
+ error:
+	return retval;
 }
 
 static void __exit roccat_exit(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-sony.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-sony.c
--- linux-libre-3.10-gnu/drivers/hid/hid-sony.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-sony.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,11 +1,13 @@
 /*
- *  HID driver for some sony "special" devices
+ *  HID driver for Sony / PS2 / PS3 BD devices.
  *
  *  Copyright (c) 1999 Andreas Gal
  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
  *  Copyright (c) 2008 Jiri Slaby
- *  Copyright (c) 2006-2008 Jiri Kosina
+ *  Copyright (c) 2012 David Dillow <dave@thedillows.org>
+ *  Copyright (c) 2006-2013 Jiri Kosina
+ *  Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
  */
 
 /*
@@ -15,17 +17,27 @@
  * any later version.
  */
 
+/* NOTE: in order for the Sony PS3 BD Remote Control to be found by
+ * a Bluetooth host, the key combination Start+Enter has to be kept pressed
+ * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
+ *
+ * There will be no PIN request from the device.
+ */
+
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
+#include <linux/leds.h>
 
 #include "hid-ids.h"
 
 #define VAIO_RDESC_CONSTANT     (1 << 0)
 #define SIXAXIS_CONTROLLER_USB  (1 << 1)
 #define SIXAXIS_CONTROLLER_BT   (1 << 2)
+#define BUZZ_CONTROLLER         (1 << 3)
+#define PS3REMOTE		(1 << 4)
 
 static const u8 sixaxis_rdesc_fixup[] = {
 	0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
@@ -55,10 +67,214 @@ static const u8 sixaxis_rdesc_fixup2[] =
 	0xb1, 0x02, 0xc0, 0xc0,
 };
 
+static __u8 ps3remote_rdesc[] = {
+	0x05, 0x01,          /* GUsagePage Generic Desktop */
+	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
+	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
+
+	 /* Use collection 1 for joypad buttons */
+	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
+
+	  /* Ignore the 1st byte, maybe it is used for a controller
+	   * number but it's not needed for correct operation */
+	  0x75, 0x08,        /* GReportSize 0x08 [8] */
+	  0x95, 0x01,        /* GReportCount 0x01 [1] */
+	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
+
+	  /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
+	   * buttons multiple keypresses are allowed */
+	  0x05, 0x09,        /* GUsagePage Button */
+	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
+	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
+	  0x14,              /* GLogicalMinimum [0] */
+	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
+	  0x75, 0x01,        /* GReportSize 0x01 [1] */
+	  0x95, 0x18,        /* GReportCount 0x18 [24] */
+	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
+
+	  0xC0,              /* MEndCollection */
+
+	 /* Use collection 2 for remote control buttons */
+	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
+
+	  /* 5th byte is used for remote control buttons */
+	  0x05, 0x09,        /* GUsagePage Button */
+	  0x18,              /* LUsageMinimum [No button pressed] */
+	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
+	  0x14,              /* GLogicalMinimum [0] */
+	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
+	  0x75, 0x08,        /* GReportSize 0x08 [8] */
+	  0x95, 0x01,        /* GReportCount 0x01 [1] */
+	  0x80,              /* MInput  */
+
+	  /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
+	   * 0xff and 11th is for press indication */
+	  0x75, 0x08,        /* GReportSize 0x08 [8] */
+	  0x95, 0x06,        /* GReportCount 0x06 [6] */
+	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
+
+	  /* 12th byte is for battery strength */
+	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
+	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
+	  0x14,              /* GLogicalMinimum [0] */
+	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
+	  0x75, 0x08,        /* GReportSize 0x08 [8] */
+	  0x95, 0x01,        /* GReportCount 0x01 [1] */
+	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
+
+	  0xC0,              /* MEndCollection */
+
+	 0xC0                /* MEndCollection [Game Pad] */
+};
+
+static const unsigned int ps3remote_keymap_joypad_buttons[] = {
+	[0x01] = KEY_SELECT,
+	[0x02] = BTN_THUMBL,		/* L3 */
+	[0x03] = BTN_THUMBR,		/* R3 */
+	[0x04] = BTN_START,
+	[0x05] = KEY_UP,
+	[0x06] = KEY_RIGHT,
+	[0x07] = KEY_DOWN,
+	[0x08] = KEY_LEFT,
+	[0x09] = BTN_TL2,		/* L2 */
+	[0x0a] = BTN_TR2,		/* R2 */
+	[0x0b] = BTN_TL,		/* L1 */
+	[0x0c] = BTN_TR,		/* R1 */
+	[0x0d] = KEY_OPTION,		/* options/triangle */
+	[0x0e] = KEY_BACK,		/* back/circle */
+	[0x0f] = BTN_0,			/* cross */
+	[0x10] = KEY_SCREEN,		/* view/square */
+	[0x11] = KEY_HOMEPAGE,		/* PS button */
+	[0x14] = KEY_ENTER,
+};
+static const unsigned int ps3remote_keymap_remote_buttons[] = {
+	[0x00] = KEY_1,
+	[0x01] = KEY_2,
+	[0x02] = KEY_3,
+	[0x03] = KEY_4,
+	[0x04] = KEY_5,
+	[0x05] = KEY_6,
+	[0x06] = KEY_7,
+	[0x07] = KEY_8,
+	[0x08] = KEY_9,
+	[0x09] = KEY_0,
+	[0x0e] = KEY_ESC,		/* return */
+	[0x0f] = KEY_CLEAR,
+	[0x16] = KEY_EJECTCD,
+	[0x1a] = KEY_MENU,		/* top menu */
+	[0x28] = KEY_TIME,
+	[0x30] = KEY_PREVIOUS,
+	[0x31] = KEY_NEXT,
+	[0x32] = KEY_PLAY,
+	[0x33] = KEY_REWIND,		/* scan back */
+	[0x34] = KEY_FORWARD,		/* scan forward */
+	[0x38] = KEY_STOP,
+	[0x39] = KEY_PAUSE,
+	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
+	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
+	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
+	[0x63] = KEY_SUBTITLE,
+	[0x64] = KEY_AUDIO,
+	[0x65] = KEY_ANGLE,
+	[0x70] = KEY_INFO,		/* display */
+	[0x80] = KEY_BLUE,
+	[0x81] = KEY_RED,
+	[0x82] = KEY_GREEN,
+	[0x83] = KEY_YELLOW,
+};
+
+static const unsigned int buzz_keymap[] = {
+	/* The controller has 4 remote buzzers, each with one LED and 5
+	 * buttons.
+	 * 
+	 * We use the mapping chosen by the controller, which is:
+	 *
+	 * Key          Offset
+	 * -------------------
+	 * Buzz              1
+	 * Blue              5
+	 * Orange            4
+	 * Green             3
+	 * Yellow            2
+	 *
+	 * So, for example, the orange button on the third buzzer is mapped to
+	 * BTN_TRIGGER_HAPPY14
+	 */
+	[ 1] = BTN_TRIGGER_HAPPY1,
+	[ 2] = BTN_TRIGGER_HAPPY2,
+	[ 3] = BTN_TRIGGER_HAPPY3,
+	[ 4] = BTN_TRIGGER_HAPPY4,
+	[ 5] = BTN_TRIGGER_HAPPY5,
+	[ 6] = BTN_TRIGGER_HAPPY6,
+	[ 7] = BTN_TRIGGER_HAPPY7,
+	[ 8] = BTN_TRIGGER_HAPPY8,
+	[ 9] = BTN_TRIGGER_HAPPY9,
+	[10] = BTN_TRIGGER_HAPPY10,
+	[11] = BTN_TRIGGER_HAPPY11,
+	[12] = BTN_TRIGGER_HAPPY12,
+	[13] = BTN_TRIGGER_HAPPY13,
+	[14] = BTN_TRIGGER_HAPPY14,
+	[15] = BTN_TRIGGER_HAPPY15,
+	[16] = BTN_TRIGGER_HAPPY16,
+	[17] = BTN_TRIGGER_HAPPY17,
+	[18] = BTN_TRIGGER_HAPPY18,
+	[19] = BTN_TRIGGER_HAPPY19,
+	[20] = BTN_TRIGGER_HAPPY20,
+};
+
 struct sony_sc {
 	unsigned long quirks;
+
+	void *extra;
+};
+
+struct buzz_extra {
+	int led_state;
+	struct led_classdev *leds[4];
 };
 
+static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
+			     unsigned int *rsize)
+{
+	*rsize = sizeof(ps3remote_rdesc);
+	return ps3remote_rdesc;
+}
+
+static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
+			     struct hid_field *field, struct hid_usage *usage,
+			     unsigned long **bit, int *max)
+{
+	unsigned int key = usage->hid & HID_USAGE;
+
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
+		return -1;
+
+	switch (usage->collection_index) {
+	case 1:
+		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
+			return -1;
+
+		key = ps3remote_keymap_joypad_buttons[key];
+		if (!key)
+			return -1;
+		break;
+	case 2:
+		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
+			return -1;
+
+		key = ps3remote_keymap_remote_buttons[key];
+		if (!key)
+			return -1;
+		break;
+	default:
+		return -1;
+	}
+
+	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
+	return 1;
+}
+
+
 /* Sony Vaio VGX has wrongly mouse pointer declared as constant */
 static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int *rsize)
@@ -95,6 +311,10 @@ static __u8 *sony_report_fixup(struct hi
 		*rsize = sizeof(sixaxis_rdesc_fixup2);
 		memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
 	}
+
+	if (sc->quirks & PS3REMOTE)
+		return ps3remote_fixup(hdev, rdesc, rsize);
+
 	return rdesc;
 }
 
@@ -117,6 +337,42 @@ static int sony_raw_event(struct hid_dev
 	return 0;
 }
 
+static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
+			struct hid_field *field, struct hid_usage *usage,
+			unsigned long **bit, int *max)
+{
+	struct sony_sc *sc = hid_get_drvdata(hdev);
+
+	if (sc->quirks & BUZZ_CONTROLLER) {
+		unsigned int key = usage->hid & HID_USAGE;
+
+		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
+			return -1;
+
+		switch (usage->collection_index) {
+		case 1:
+			if (key >= ARRAY_SIZE(buzz_keymap))
+				return -1;
+
+			key = buzz_keymap[key];
+			if (!key)
+				return -1;
+			break;
+		default:
+			return -1;
+		}
+
+		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
+		return 1;
+	}
+
+	if (sc->quirks & PS3REMOTE)
+		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
+
+	/* Let hid-core decide for the others */
+	return 0;
+}
+
 /*
  * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
  * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
@@ -192,11 +448,181 @@ static int sixaxis_set_operational_bt(st
 	return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
 }
 
+static void buzz_set_leds(struct hid_device *hdev, int leds)
+{
+	struct list_head *report_list =
+		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct hid_report *report = list_entry(report_list->next,
+		struct hid_report, list);
+	__s32 *value = report->field[0]->value;
+
+	value[0] = 0x00;
+	value[1] = (leds & 1) ? 0xff : 0x00;
+	value[2] = (leds & 2) ? 0xff : 0x00;
+	value[3] = (leds & 4) ? 0xff : 0x00;
+	value[4] = (leds & 8) ? 0xff : 0x00;
+	value[5] = 0x00;
+	value[6] = 0x00;
+	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
+}
+
+static void buzz_led_set_brightness(struct led_classdev *led,
+				    enum led_brightness value)
+{
+	struct device *dev = led->dev->parent;
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct sony_sc *drv_data;
+	struct buzz_extra *buzz;
+
+	int n;
+
+	drv_data = hid_get_drvdata(hdev);
+	if (!drv_data || !drv_data->extra) {
+		hid_err(hdev, "No device data\n");
+		return;
+	}
+	buzz = drv_data->extra;
+
+	for (n = 0; n < 4; n++) {
+		if (led == buzz->leds[n]) {
+			int on = !! (buzz->led_state & (1 << n));
+			if (value == LED_OFF && on) {
+				buzz->led_state &= ~(1 << n);
+				buzz_set_leds(hdev, buzz->led_state);
+			} else if (value != LED_OFF && !on) {
+				buzz->led_state |= (1 << n);
+				buzz_set_leds(hdev, buzz->led_state);
+			}
+			break;
+		}
+	}
+}
+
+static enum led_brightness buzz_led_get_brightness(struct led_classdev *led)
+{
+	struct device *dev = led->dev->parent;
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct sony_sc *drv_data;
+	struct buzz_extra *buzz;
+
+	int n;
+	int on = 0;
+
+	drv_data = hid_get_drvdata(hdev);
+	if (!drv_data || !drv_data->extra) {
+		hid_err(hdev, "No device data\n");
+		return LED_OFF;
+	}
+	buzz = drv_data->extra;
+
+	for (n = 0; n < 4; n++) {
+		if (led == buzz->leds[n]) {
+			on = !! (buzz->led_state & (1 << n));
+			break;
+		}
+	}
+
+	return on ? LED_FULL : LED_OFF;
+}
+
+static int buzz_init(struct hid_device *hdev)
+{
+	struct sony_sc *drv_data;
+	struct buzz_extra *buzz;
+	int n, ret = 0;
+	struct led_classdev *led;
+	size_t name_sz;
+	char *name;
+
+	drv_data = hid_get_drvdata(hdev);
+	BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
+
+	buzz = kzalloc(sizeof(*buzz), GFP_KERNEL);
+	if (!buzz) {
+		hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
+		return -ENOMEM;
+	}
+	drv_data->extra = buzz;
+
+	/* Clear LEDs as we have no way of reading their initial state. This is
+	 * only relevant if the driver is loaded after somebody actively set the
+	 * LEDs to on */
+	buzz_set_leds(hdev, 0x00);
+
+	name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1;
+
+	for (n = 0; n < 4; n++) {
+		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
+		if (!led) {
+			hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
+			goto error_leds;
+		}
+
+		name = (void *)(&led[1]);
+		snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1);
+		led->name = name;
+		led->brightness = 0;
+		led->max_brightness = 1;
+		led->brightness_get = buzz_led_get_brightness;
+		led->brightness_set = buzz_led_set_brightness;
+
+		if (led_classdev_register(&hdev->dev, led)) {
+			hid_err(hdev, "Failed to register LED %d\n", n);
+			kfree(led);
+			goto error_leds;
+		}
+
+		buzz->leds[n] = led;
+	}
+
+	return ret;
+
+error_leds:
+	for (n = 0; n < 4; n++) {
+		led = buzz->leds[n];
+		buzz->leds[n] = NULL;
+		if (!led)
+			continue;
+		led_classdev_unregister(led);
+		kfree(led);
+	}
+
+	kfree(drv_data->extra);
+	drv_data->extra = NULL;
+	return ret;
+}
+
+static void buzz_remove(struct hid_device *hdev)
+{
+	struct sony_sc *drv_data;
+	struct buzz_extra *buzz;
+	struct led_classdev *led;
+	int n;
+
+	drv_data = hid_get_drvdata(hdev);
+	BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
+
+	buzz = drv_data->extra;
+
+	for (n = 0; n < 4; n++) {
+		led = buzz->leds[n];
+		buzz->leds[n] = NULL;
+		if (!led)
+			continue;
+		led_classdev_unregister(led);
+		kfree(led);
+	}
+
+	kfree(drv_data->extra);
+	drv_data->extra = NULL;
+}
+
 static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
 	int ret;
 	unsigned long quirks = id->driver_data;
 	struct sony_sc *sc;
+	unsigned int connect_mask = HID_CONNECT_DEFAULT;
 
 	sc = kzalloc(sizeof(*sc), GFP_KERNEL);
 	if (sc == NULL) {
@@ -213,8 +639,14 @@ static int sony_probe(struct hid_device
 		goto err_free;
 	}
 
-	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT |
-			HID_CONNECT_HIDDEV_FORCE);
+	if (sc->quirks & VAIO_RDESC_CONSTANT)
+		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
+	else if (sc->quirks & SIXAXIS_CONTROLLER_USB)
+		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
+	else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
+		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
+
+	ret = hid_hw_start(hdev, connect_mask);
 	if (ret) {
 		hid_err(hdev, "hw start failed\n");
 		goto err_free;
@@ -226,6 +658,8 @@ static int sony_probe(struct hid_device
 	}
 	else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
 		ret = sixaxis_set_operational_bt(hdev);
+	else if (sc->quirks & BUZZ_CONTROLLER)
+		ret = buzz_init(hdev);
 	else
 		ret = 0;
 
@@ -242,8 +676,13 @@ err_free:
 
 static void sony_remove(struct hid_device *hdev)
 {
+	struct sony_sc *sc = hid_get_drvdata(hdev);
+
+	if (sc->quirks & BUZZ_CONTROLLER)
+		buzz_remove(hdev);
+
 	hid_hw_stop(hdev);
-	kfree(hid_get_drvdata(hdev));
+	kfree(sc);
 }
 
 static const struct hid_device_id sony_devices[] = {
@@ -257,17 +696,30 @@ static const struct hid_device_id sony_d
 		.driver_data = VAIO_RDESC_CONSTANT },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
 		.driver_data = VAIO_RDESC_CONSTANT },
+	/* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
+	 * Logitech joystick from the device descriptor. */
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
+		.driver_data = BUZZ_CONTROLLER },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
+		.driver_data = BUZZ_CONTROLLER },
+	/* PS3 BD Remote Control */
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
+		.driver_data = PS3REMOTE },
+	/* Logitech Harmony Adapter for PS3 */
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
+		.driver_data = PS3REMOTE },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, sony_devices);
 
 static struct hid_driver sony_driver = {
-	.name = "sony",
-	.id_table = sony_devices,
-	.probe = sony_probe,
-	.remove = sony_remove,
-	.report_fixup = sony_report_fixup,
-	.raw_event = sony_raw_event
+	.name          = "sony",
+	.id_table      = sony_devices,
+	.input_mapping = sony_mapping,
+	.probe         = sony_probe,
+	.remove        = sony_remove,
+	.report_fixup  = sony_report_fixup,
+	.raw_event     = sony_raw_event
 };
 module_hid_driver(sony_driver);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-wacom.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-wacom.c
--- linux-libre-3.10-gnu/drivers/hid/hid-wacom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-wacom.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,6 +46,7 @@ struct wacom_data {
 	__u8 battery_capacity;
 	__u8 power_raw;
 	__u8 ps_connected;
+	__u8 bat_charging;
 	struct power_supply battery;
 	struct power_supply ac;
 	__u8 led_selector;
@@ -62,6 +63,7 @@ static enum power_supply_property wacom_
 	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_SCOPE,
+	POWER_SUPPLY_PROP_STATUS,
 };
 
 static enum power_supply_property wacom_ac_props[] = {
@@ -287,6 +289,15 @@ static int wacom_battery_get_property(st
 	case POWER_SUPPLY_PROP_CAPACITY:
 		val->intval = wdata->battery_capacity;
 		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		if (wdata->bat_charging)
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else
+			if (wdata->battery_capacity == 100 && wdata->ps_connected)
+				val->intval = POWER_SUPPLY_STATUS_FULL;
+			else
+				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -727,7 +738,8 @@ static int wacom_raw_event(struct hid_de
 			if (power_raw != wdata->power_raw) {
 				wdata->power_raw = power_raw;
 				wdata->battery_capacity = batcap_i4[power_raw & 0x07];
-				wdata->ps_connected = power_raw & 0x08;
+				wdata->bat_charging = (power_raw & 0x08) ? 1 : 0;
+				wdata->ps_connected = (power_raw & 0x10) ? 1 : 0;
 			}
 
 			break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-wiimote-core.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote-core.c
--- linux-libre-3.10-gnu/drivers/hid/hid-wiimote-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /*
- * HID driver for Nintendo Wiimote devices
- * Copyright (c) 2011 David Herrmann
+ * HID driver for Nintendo Wii / Wii U peripherals
+ * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com>
  */
 
 /*
@@ -14,53 +14,19 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/input.h>
-#include <linux/leds.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/power_supply.h>
 #include <linux/spinlock.h>
 #include "hid-ids.h"
 #include "hid-wiimote.h"
 
-enum wiiproto_keys {
-	WIIPROTO_KEY_LEFT,
-	WIIPROTO_KEY_RIGHT,
-	WIIPROTO_KEY_UP,
-	WIIPROTO_KEY_DOWN,
-	WIIPROTO_KEY_PLUS,
-	WIIPROTO_KEY_MINUS,
-	WIIPROTO_KEY_ONE,
-	WIIPROTO_KEY_TWO,
-	WIIPROTO_KEY_A,
-	WIIPROTO_KEY_B,
-	WIIPROTO_KEY_HOME,
-	WIIPROTO_KEY_COUNT
-};
-
-static __u16 wiiproto_keymap[] = {
-	KEY_LEFT,	/* WIIPROTO_KEY_LEFT */
-	KEY_RIGHT,	/* WIIPROTO_KEY_RIGHT */
-	KEY_UP,		/* WIIPROTO_KEY_UP */
-	KEY_DOWN,	/* WIIPROTO_KEY_DOWN */
-	KEY_NEXT,	/* WIIPROTO_KEY_PLUS */
-	KEY_PREVIOUS,	/* WIIPROTO_KEY_MINUS */
-	BTN_1,		/* WIIPROTO_KEY_ONE */
-	BTN_2,		/* WIIPROTO_KEY_TWO */
-	BTN_A,		/* WIIPROTO_KEY_A */
-	BTN_B,		/* WIIPROTO_KEY_B */
-	BTN_MODE,	/* WIIPROTO_KEY_HOME */
-};
-
-static enum power_supply_property wiimote_battery_props[] = {
-	POWER_SUPPLY_PROP_CAPACITY,
-	POWER_SUPPLY_PROP_SCOPE,
-};
+/* output queue handling */
 
-static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
-								size_t count)
+static int wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
+			    size_t count)
 {
 	__u8 *buf;
-	ssize_t ret;
+	int ret;
 
 	if (!hdev->hid_output_raw_report)
 		return -ENODEV;
@@ -75,24 +41,33 @@ static ssize_t wiimote_hid_send(struct h
 	return ret;
 }
 
-static void wiimote_worker(struct work_struct *work)
+static void wiimote_queue_worker(struct work_struct *work)
 {
-	struct wiimote_data *wdata = container_of(work, struct wiimote_data,
-									worker);
+	struct wiimote_queue *queue = container_of(work, struct wiimote_queue,
+						   worker);
+	struct wiimote_data *wdata = container_of(queue, struct wiimote_data,
+						  queue);
 	unsigned long flags;
+	int ret;
 
-	spin_lock_irqsave(&wdata->qlock, flags);
+	spin_lock_irqsave(&wdata->queue.lock, flags);
 
-	while (wdata->head != wdata->tail) {
-		spin_unlock_irqrestore(&wdata->qlock, flags);
-		wiimote_hid_send(wdata->hdev, wdata->outq[wdata->tail].data,
-						wdata->outq[wdata->tail].size);
-		spin_lock_irqsave(&wdata->qlock, flags);
+	while (wdata->queue.head != wdata->queue.tail) {
+		spin_unlock_irqrestore(&wdata->queue.lock, flags);
+		ret = wiimote_hid_send(wdata->hdev,
+				 wdata->queue.outq[wdata->queue.tail].data,
+				 wdata->queue.outq[wdata->queue.tail].size);
+		if (ret < 0) {
+			spin_lock_irqsave(&wdata->state.lock, flags);
+			wiimote_cmd_abort(wdata);
+			spin_unlock_irqrestore(&wdata->state.lock, flags);
+		}
+		spin_lock_irqsave(&wdata->queue.lock, flags);
 
-		wdata->tail = (wdata->tail + 1) % WIIMOTE_BUFSIZE;
+		wdata->queue.tail = (wdata->queue.tail + 1) % WIIMOTE_BUFSIZE;
 	}
 
-	spin_unlock_irqrestore(&wdata->qlock, flags);
+	spin_unlock_irqrestore(&wdata->queue.lock, flags);
 }
 
 static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer,
@@ -103,7 +78,9 @@ static void wiimote_queue(struct wiimote
 
 	if (count > HID_MAX_BUFFER_SIZE) {
 		hid_warn(wdata->hdev, "Sending too large output report\n");
-		return;
+
+		spin_lock_irqsave(&wdata->queue.lock, flags);
+		goto out_error;
 	}
 
 	/*
@@ -116,22 +93,28 @@ static void wiimote_queue(struct wiimote
 	 * will reschedule itself until the queue is empty.
 	 */
 
-	spin_lock_irqsave(&wdata->qlock, flags);
+	spin_lock_irqsave(&wdata->queue.lock, flags);
 
-	memcpy(wdata->outq[wdata->head].data, buffer, count);
-	wdata->outq[wdata->head].size = count;
-	newhead = (wdata->head + 1) % WIIMOTE_BUFSIZE;
+	memcpy(wdata->queue.outq[wdata->queue.head].data, buffer, count);
+	wdata->queue.outq[wdata->queue.head].size = count;
+	newhead = (wdata->queue.head + 1) % WIIMOTE_BUFSIZE;
 
-	if (wdata->head == wdata->tail) {
-		wdata->head = newhead;
-		schedule_work(&wdata->worker);
-	} else if (newhead != wdata->tail) {
-		wdata->head = newhead;
+	if (wdata->queue.head == wdata->queue.tail) {
+		wdata->queue.head = newhead;
+		schedule_work(&wdata->queue.worker);
+	} else if (newhead != wdata->queue.tail) {
+		wdata->queue.head = newhead;
 	} else {
 		hid_warn(wdata->hdev, "Output queue is full");
+		goto out_error;
 	}
 
-	spin_unlock_irqrestore(&wdata->qlock, flags);
+	goto out_unlock;
+
+out_error:
+	wiimote_cmd_abort(wdata);
+out_unlock:
+	spin_unlock_irqrestore(&wdata->queue.lock, flags);
 }
 
 /*
@@ -147,7 +130,7 @@ static inline void wiiproto_keep_rumble(
 		*cmd1 |= 0x01;
 }
 
-static void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble)
+void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble)
 {
 	__u8 cmd[2];
 
@@ -167,7 +150,7 @@ static void wiiproto_req_rumble(struct w
 	wiimote_queue(wdata, cmd, sizeof(cmd));
 }
 
-static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
+void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
 {
 	__u8 cmd[2];
 
@@ -196,17 +179,46 @@ static void wiiproto_req_leds(struct wii
  * Check what peripherals of the wiimote are currently
  * active and select a proper DRM that supports all of
  * the requested data inputs.
+ *
+ * Not all combinations are actually supported. The following
+ * combinations work only with limitations:
+ *  - IR cam in extended or full mode disables any data transmission
+ *    of extension controllers. There is no DRM mode that supports
+ *    extension bytes plus extended/full IR.
+ *  - IR cam with accelerometer and extension *_EXT8 is not supported.
+ *    However, all extensions that need *_EXT8 are devices that don't
+ *    support IR cameras. Hence, this shouldn't happen under normal
+ *    operation.
+ *  - *_EXT16 is only supported in combination with buttons and
+ *    accelerometer. No IR or similar can be active simultaneously. As
+ *    above, all modules that require it are mutually exclusive with
+ *    IR/etc. so this doesn't matter.
  */
 static __u8 select_drm(struct wiimote_data *wdata)
 {
 	__u8 ir = wdata->state.flags & WIIPROTO_FLAGS_IR;
-	bool ext = wiiext_active(wdata);
+	bool ext;
 
-	if (ir == WIIPROTO_FLAG_IR_BASIC) {
-		if (wdata->state.flags & WIIPROTO_FLAG_ACCEL)
-			return WIIPROTO_REQ_DRM_KAIE;
+	ext = (wdata->state.flags & WIIPROTO_FLAG_EXT_USED) ||
+	      (wdata->state.flags & WIIPROTO_FLAG_MP_USED);
+
+	/* some 3rd-party balance-boards are hard-coded to KEE, *sigh* */
+	if (wdata->state.devtype == WIIMOTE_DEV_BALANCE_BOARD) {
+		if (ext)
+			return WIIPROTO_REQ_DRM_KEE;
 		else
+			return WIIPROTO_REQ_DRM_K;
+	}
+
+	if (ir == WIIPROTO_FLAG_IR_BASIC) {
+		if (wdata->state.flags & WIIPROTO_FLAG_ACCEL) {
+			if (ext)
+				return WIIPROTO_REQ_DRM_KAIE;
+			else
+				return WIIPROTO_REQ_DRM_KAI;
+		} else {
 			return WIIPROTO_REQ_DRM_KIE;
+		}
 	} else if (ir == WIIPROTO_FLAG_IR_EXT) {
 		return WIIPROTO_REQ_DRM_KAI;
 	} else if (ir == WIIPROTO_FLAG_IR_FULL) {
@@ -219,7 +231,7 @@ static __u8 select_drm(struct wiimote_da
 				return WIIPROTO_REQ_DRM_KA;
 		} else {
 			if (ext)
-				return WIIPROTO_REQ_DRM_KE;
+				return WIIPROTO_REQ_DRM_KEE;
 			else
 				return WIIPROTO_REQ_DRM_K;
 		}
@@ -230,7 +242,9 @@ void wiiproto_req_drm(struct wiimote_dat
 {
 	__u8 cmd[3];
 
-	if (drm == WIIPROTO_REQ_NULL)
+	if (wdata->state.flags & WIIPROTO_FLAG_DRM_LOCKED)
+		drm = wdata->state.drm;
+	else if (drm == WIIPROTO_REQ_NULL)
 		drm = select_drm(wdata);
 
 	cmd[0] = WIIPROTO_REQ_DRM;
@@ -242,7 +256,7 @@ void wiiproto_req_drm(struct wiimote_dat
 	wiimote_queue(wdata, cmd, sizeof(cmd));
 }
 
-static void wiiproto_req_status(struct wiimote_data *wdata)
+void wiiproto_req_status(struct wiimote_data *wdata)
 {
 	__u8 cmd[2];
 
@@ -253,7 +267,7 @@ static void wiiproto_req_status(struct w
 	wiimote_queue(wdata, cmd, sizeof(cmd));
 }
 
-static void wiiproto_req_accel(struct wiimote_data *wdata, __u8 accel)
+void wiiproto_req_accel(struct wiimote_data *wdata, __u8 accel)
 {
 	accel = !!accel;
 	if (accel == !!(wdata->state.flags & WIIPROTO_FLAG_ACCEL))
@@ -267,7 +281,7 @@ static void wiiproto_req_accel(struct wi
 	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
 }
 
-static void wiiproto_req_ir1(struct wiimote_data *wdata, __u8 flags)
+void wiiproto_req_ir1(struct wiimote_data *wdata, __u8 flags)
 {
 	__u8 cmd[2];
 
@@ -278,7 +292,7 @@ static void wiiproto_req_ir1(struct wiim
 	wiimote_queue(wdata, cmd, sizeof(cmd));
 }
 
-static void wiiproto_req_ir2(struct wiimote_data *wdata, __u8 flags)
+void wiiproto_req_ir2(struct wiimote_data *wdata, __u8 flags)
 {
 	__u8 cmd[2];
 
@@ -394,399 +408,998 @@ ssize_t wiimote_cmd_read(struct wiimote_
 	return ret;
 }
 
-static int wiimote_battery_get_property(struct power_supply *psy,
-						enum power_supply_property psp,
-						union power_supply_propval *val)
+/* requires the cmd-mutex to be held */
+static int wiimote_cmd_init_ext(struct wiimote_data *wdata)
 {
-	struct wiimote_data *wdata = container_of(psy,
-						struct wiimote_data, battery);
-	int ret = 0, state;
-	unsigned long flags;
+	__u8 wmem;
+	int ret;
 
-	if (psp == POWER_SUPPLY_PROP_SCOPE) {
-		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
-		return 0;
-	}
+	/* initialize extension */
+	wmem = 0x55;
+	ret = wiimote_cmd_write(wdata, 0xa400f0, &wmem, sizeof(wmem));
+	if (ret)
+		return ret;
 
-	ret = wiimote_cmd_acquire(wdata);
+	/* disable default encryption */
+	wmem = 0x0;
+	ret = wiimote_cmd_write(wdata, 0xa400fb, &wmem, sizeof(wmem));
 	if (ret)
 		return ret;
 
-	spin_lock_irqsave(&wdata->state.lock, flags);
-	wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
-	wiiproto_req_status(wdata);
-	spin_unlock_irqrestore(&wdata->state.lock, flags);
+	return 0;
+}
 
-	ret = wiimote_cmd_wait(wdata);
-	state = wdata->state.cmd_battery;
-	wiimote_cmd_release(wdata);
+/* requires the cmd-mutex to be held */
+static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata, __u8 *rmem)
+{
+	int ret;
+
+	/* read extension ID */
+	ret = wiimote_cmd_read(wdata, 0xa400fa, rmem, 6);
+	if (ret != 6)
+		return WIIMOTE_EXT_NONE;
+
+	hid_dbg(wdata->hdev, "extension ID: %02x:%02x %02x:%02x %02x:%02x\n",
+		rmem[0], rmem[1], rmem[2], rmem[3], rmem[4], rmem[5]);
 
+	if (rmem[0] == 0xff && rmem[1] == 0xff && rmem[2] == 0xff &&
+	    rmem[3] == 0xff && rmem[4] == 0xff && rmem[5] == 0xff)
+		return WIIMOTE_EXT_NONE;
+
+	if (rmem[4] == 0x00 && rmem[5] == 0x00)
+		return WIIMOTE_EXT_NUNCHUK;
+	if (rmem[4] == 0x01 && rmem[5] == 0x01)
+		return WIIMOTE_EXT_CLASSIC_CONTROLLER;
+	if (rmem[4] == 0x04 && rmem[5] == 0x02)
+		return WIIMOTE_EXT_BALANCE_BOARD;
+	if (rmem[4] == 0x01 && rmem[5] == 0x20)
+		return WIIMOTE_EXT_PRO_CONTROLLER;
+
+	return WIIMOTE_EXT_UNKNOWN;
+}
+
+/* requires the cmd-mutex to be held */
+static int wiimote_cmd_init_mp(struct wiimote_data *wdata)
+{
+	__u8 wmem;
+	int ret;
+
+	/* initialize MP */
+	wmem = 0x55;
+	ret = wiimote_cmd_write(wdata, 0xa600f0, &wmem, sizeof(wmem));
 	if (ret)
 		return ret;
 
-	switch (psp) {
-		case POWER_SUPPLY_PROP_CAPACITY:
-			val->intval = state * 100 / 255;
-			break;
-		default:
-			ret = -EINVAL;
-			break;
+	/* disable default encryption */
+	wmem = 0x0;
+	ret = wiimote_cmd_write(wdata, 0xa600fb, &wmem, sizeof(wmem));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/* requires the cmd-mutex to be held */
+static bool wiimote_cmd_map_mp(struct wiimote_data *wdata, __u8 exttype)
+{
+	__u8 wmem;
+
+	/* map MP with correct pass-through mode */
+	switch (exttype) {
+	case WIIMOTE_EXT_CLASSIC_CONTROLLER:
+		wmem = 0x07;
+		break;
+	case WIIMOTE_EXT_NUNCHUK:
+		wmem = 0x05;
+		break;
+	default:
+		wmem = 0x04;
+		break;
 	}
 
-	return ret;
+	return wiimote_cmd_write(wdata, 0xa600fe, &wmem, sizeof(wmem));
 }
 
-static int wiimote_init_ir(struct wiimote_data *wdata, __u16 mode)
+/* requires the cmd-mutex to be held */
+static bool wiimote_cmd_read_mp(struct wiimote_data *wdata, __u8 *rmem)
 {
 	int ret;
-	unsigned long flags;
-	__u8 format = 0;
-	static const __u8 data_enable[] = { 0x01 };
-	static const __u8 data_sens1[] = { 0x02, 0x00, 0x00, 0x71, 0x01,
-						0x00, 0xaa, 0x00, 0x64 };
-	static const __u8 data_sens2[] = { 0x63, 0x03 };
-	static const __u8 data_fin[] = { 0x08 };
 
-	spin_lock_irqsave(&wdata->state.lock, flags);
+	/* read motion plus ID */
+	ret = wiimote_cmd_read(wdata, 0xa600fa, rmem, 6);
+	if (ret != 6)
+		return false;
 
-	if (mode == (wdata->state.flags & WIIPROTO_FLAGS_IR)) {
-		spin_unlock_irqrestore(&wdata->state.lock, flags);
-		return 0;
-	}
+	hid_dbg(wdata->hdev, "motion plus ID: %02x:%02x %02x:%02x %02x:%02x\n",
+		rmem[0], rmem[1], rmem[2], rmem[3], rmem[4], rmem[5]);
 
-	if (mode == 0) {
-		wdata->state.flags &= ~WIIPROTO_FLAGS_IR;
-		wiiproto_req_ir1(wdata, 0);
-		wiiproto_req_ir2(wdata, 0);
-		wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
-		spin_unlock_irqrestore(&wdata->state.lock, flags);
-		return 0;
-	}
+	if (rmem[5] == 0x05)
+		return true;
 
-	spin_unlock_irqrestore(&wdata->state.lock, flags);
+	hid_info(wdata->hdev, "unknown motion plus ID: %02x:%02x %02x:%02x %02x:%02x\n",
+		 rmem[0], rmem[1], rmem[2], rmem[3], rmem[4], rmem[5]);
 
-	ret = wiimote_cmd_acquire(wdata);
-	if (ret)
-		return ret;
+	return false;
+}
 
-	/* send PIXEL CLOCK ENABLE cmd first */
-	spin_lock_irqsave(&wdata->state.lock, flags);
-	wiimote_cmd_set(wdata, WIIPROTO_REQ_IR1, 0);
-	wiiproto_req_ir1(wdata, 0x06);
-	spin_unlock_irqrestore(&wdata->state.lock, flags);
+/* requires the cmd-mutex to be held */
+static __u8 wiimote_cmd_read_mp_mapped(struct wiimote_data *wdata)
+{
+	int ret;
+	__u8 rmem[6];
 
-	ret = wiimote_cmd_wait(wdata);
-	if (ret)
-		goto unlock;
-	if (wdata->state.cmd_err) {
-		ret = -EIO;
-		goto unlock;
+	/* read motion plus ID */
+	ret = wiimote_cmd_read(wdata, 0xa400fa, rmem, 6);
+	if (ret != 6)
+		return WIIMOTE_MP_NONE;
+
+	hid_dbg(wdata->hdev, "mapped motion plus ID: %02x:%02x %02x:%02x %02x:%02x\n",
+		rmem[0], rmem[1], rmem[2], rmem[3], rmem[4], rmem[5]);
+
+	if (rmem[0] == 0xff && rmem[1] == 0xff && rmem[2] == 0xff &&
+	    rmem[3] == 0xff && rmem[4] == 0xff && rmem[5] == 0xff)
+		return WIIMOTE_MP_NONE;
+
+	if (rmem[4] == 0x04 && rmem[5] == 0x05)
+		return WIIMOTE_MP_SINGLE;
+	else if (rmem[4] == 0x05 && rmem[5] == 0x05)
+		return WIIMOTE_MP_PASSTHROUGH_NUNCHUK;
+	else if (rmem[4] == 0x07 && rmem[5] == 0x05)
+		return WIIMOTE_MP_PASSTHROUGH_CLASSIC;
+
+	return WIIMOTE_MP_UNKNOWN;
+}
+
+/* device module handling */
+
+static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = {
+	[WIIMOTE_DEV_PENDING] = (const __u8[]){
+		WIIMOD_NULL,
+	},
+	[WIIMOTE_DEV_UNKNOWN] = (const __u8[]){
+		WIIMOD_NO_MP,
+		WIIMOD_NULL,
+	},
+	[WIIMOTE_DEV_GENERIC] = (const __u8[]){
+		WIIMOD_KEYS,
+		WIIMOD_RUMBLE,
+		WIIMOD_BATTERY,
+		WIIMOD_LED1,
+		WIIMOD_LED2,
+		WIIMOD_LED3,
+		WIIMOD_LED4,
+		WIIMOD_ACCEL,
+		WIIMOD_IR,
+		WIIMOD_NULL,
+	},
+	[WIIMOTE_DEV_GEN10] = (const __u8[]){
+		WIIMOD_KEYS,
+		WIIMOD_RUMBLE,
+		WIIMOD_BATTERY,
+		WIIMOD_LED1,
+		WIIMOD_LED2,
+		WIIMOD_LED3,
+		WIIMOD_LED4,
+		WIIMOD_ACCEL,
+		WIIMOD_IR,
+		WIIMOD_NULL,
+	},
+	[WIIMOTE_DEV_GEN20] = (const __u8[]){
+		WIIMOD_KEYS,
+		WIIMOD_RUMBLE,
+		WIIMOD_BATTERY,
+		WIIMOD_LED1,
+		WIIMOD_LED2,
+		WIIMOD_LED3,
+		WIIMOD_LED4,
+		WIIMOD_ACCEL,
+		WIIMOD_IR,
+		WIIMOD_BUILTIN_MP,
+		WIIMOD_NULL,
+	},
+	[WIIMOTE_DEV_BALANCE_BOARD] = (const __u8[]) {
+		WIIMOD_BATTERY,
+		WIIMOD_LED1,
+		WIIMOD_NO_MP,
+		WIIMOD_NULL,
+	},
+	[WIIMOTE_DEV_PRO_CONTROLLER] = (const __u8[]) {
+		WIIMOD_BATTERY,
+		WIIMOD_LED1,
+		WIIMOD_LED2,
+		WIIMOD_LED3,
+		WIIMOD_LED4,
+		WIIMOD_NO_MP,
+		WIIMOD_NULL,
+	},
+};
+
+static void wiimote_modules_load(struct wiimote_data *wdata,
+				 unsigned int devtype)
+{
+	bool need_input = false;
+	const __u8 *mods, *iter;
+	const struct wiimod_ops *ops;
+	int ret;
+
+	mods = wiimote_devtype_mods[devtype];
+
+	for (iter = mods; *iter != WIIMOD_NULL; ++iter) {
+		if (wiimod_table[*iter]->flags & WIIMOD_FLAG_INPUT) {
+			need_input = true;
+			break;
+		}
 	}
 
-	/* enable IR LOGIC */
-	spin_lock_irqsave(&wdata->state.lock, flags);
-	wiimote_cmd_set(wdata, WIIPROTO_REQ_IR2, 0);
-	wiiproto_req_ir2(wdata, 0x06);
-	spin_unlock_irqrestore(&wdata->state.lock, flags);
+	if (need_input) {
+		wdata->input = input_allocate_device();
+		if (!wdata->input)
+			return;
 
-	ret = wiimote_cmd_wait(wdata);
-	if (ret)
-		goto unlock;
-	if (wdata->state.cmd_err) {
-		ret = -EIO;
-		goto unlock;
+		input_set_drvdata(wdata->input, wdata);
+		wdata->input->dev.parent = &wdata->hdev->dev;
+		wdata->input->id.bustype = wdata->hdev->bus;
+		wdata->input->id.vendor = wdata->hdev->vendor;
+		wdata->input->id.product = wdata->hdev->product;
+		wdata->input->id.version = wdata->hdev->version;
+		wdata->input->name = WIIMOTE_NAME;
 	}
 
-	/* enable IR cam but do not make it send data, yet */
-	ret = wiimote_cmd_write(wdata, 0xb00030, data_enable,
-							sizeof(data_enable));
-	if (ret)
-		goto unlock;
+	for (iter = mods; *iter != WIIMOD_NULL; ++iter) {
+		ops = wiimod_table[*iter];
+		if (!ops->probe)
+			continue;
 
-	/* write first sensitivity block */
-	ret = wiimote_cmd_write(wdata, 0xb00000, data_sens1,
-							sizeof(data_sens1));
-	if (ret)
-		goto unlock;
+		ret = ops->probe(ops, wdata);
+		if (ret)
+			goto error;
+	}
 
-	/* write second sensitivity block */
-	ret = wiimote_cmd_write(wdata, 0xb0001a, data_sens2,
-							sizeof(data_sens2));
-	if (ret)
-		goto unlock;
+	if (wdata->input) {
+		ret = input_register_device(wdata->input);
+		if (ret)
+			goto error;
+	}
 
-	/* put IR cam into desired state */
-	switch (mode) {
-		case WIIPROTO_FLAG_IR_FULL:
-			format = 5;
-			break;
-		case WIIPROTO_FLAG_IR_EXT:
-			format = 3;
-			break;
-		case WIIPROTO_FLAG_IR_BASIC:
-			format = 1;
-			break;
+	spin_lock_irq(&wdata->state.lock);
+	wdata->state.devtype = devtype;
+	spin_unlock_irq(&wdata->state.lock);
+	return;
+
+error:
+	for ( ; iter-- != mods; ) {
+		ops = wiimod_table[*iter];
+		if (ops->remove)
+			ops->remove(ops, wdata);
 	}
-	ret = wiimote_cmd_write(wdata, 0xb00033, &format, sizeof(format));
-	if (ret)
-		goto unlock;
 
-	/* make IR cam send data */
-	ret = wiimote_cmd_write(wdata, 0xb00030, data_fin, sizeof(data_fin));
-	if (ret)
-		goto unlock;
+	if (wdata->input) {
+		input_free_device(wdata->input);
+		wdata->input = NULL;
+	}
+}
+
+static void wiimote_modules_unload(struct wiimote_data *wdata)
+{
+	const __u8 *mods, *iter;
+	const struct wiimod_ops *ops;
+	unsigned long flags;
+
+	mods = wiimote_devtype_mods[wdata->state.devtype];
 
-	/* request new DRM mode compatible to IR mode */
 	spin_lock_irqsave(&wdata->state.lock, flags);
-	wdata->state.flags &= ~WIIPROTO_FLAGS_IR;
-	wdata->state.flags |= mode & WIIPROTO_FLAGS_IR;
-	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	wdata->state.devtype = WIIMOTE_DEV_UNKNOWN;
 	spin_unlock_irqrestore(&wdata->state.lock, flags);
 
-unlock:
-	wiimote_cmd_release(wdata);
-	return ret;
+	/* find end of list */
+	for (iter = mods; *iter != WIIMOD_NULL; ++iter)
+		/* empty */ ;
+
+	if (wdata->input) {
+		input_get_device(wdata->input);
+		input_unregister_device(wdata->input);
+	}
+
+	for ( ; iter-- != mods; ) {
+		ops = wiimod_table[*iter];
+		if (ops->remove)
+			ops->remove(ops, wdata);
+	}
+
+	if (wdata->input) {
+		input_put_device(wdata->input);
+		wdata->input = NULL;
+	}
 }
 
-static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev)
+/* device extension handling */
+
+static void wiimote_ext_load(struct wiimote_data *wdata, unsigned int ext)
 {
-	struct wiimote_data *wdata;
-	struct device *dev = led_dev->dev->parent;
-	int i;
 	unsigned long flags;
-	bool value = false;
+	const struct wiimod_ops *ops;
+	int ret;
 
-	wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
+	ops = wiimod_ext_table[ext];
 
-	for (i = 0; i < 4; ++i) {
-		if (wdata->leds[i] == led_dev) {
-			spin_lock_irqsave(&wdata->state.lock, flags);
-			value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1);
-			spin_unlock_irqrestore(&wdata->state.lock, flags);
-			break;
-		}
+	if (ops->probe) {
+		ret = ops->probe(ops, wdata);
+		if (ret)
+			ext = WIIMOTE_EXT_UNKNOWN;
 	}
 
-	return value ? LED_FULL : LED_OFF;
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.exttype = ext;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
 }
 
-static void wiimote_leds_set(struct led_classdev *led_dev,
-						enum led_brightness value)
+static void wiimote_ext_unload(struct wiimote_data *wdata)
 {
-	struct wiimote_data *wdata;
-	struct device *dev = led_dev->dev->parent;
-	int i;
 	unsigned long flags;
-	__u8 state, flag;
+	const struct wiimod_ops *ops;
 
-	wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
+	ops = wiimod_ext_table[wdata->state.exttype];
 
-	for (i = 0; i < 4; ++i) {
-		if (wdata->leds[i] == led_dev) {
-			flag = WIIPROTO_FLAG_LED(i + 1);
-			spin_lock_irqsave(&wdata->state.lock, flags);
-			state = wdata->state.flags;
-			if (value == LED_OFF)
-				wiiproto_req_leds(wdata, state & ~flag);
-			else
-				wiiproto_req_leds(wdata, state | flag);
-			spin_unlock_irqrestore(&wdata->state.lock, flags);
-			break;
-		}
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.exttype = WIIMOTE_EXT_UNKNOWN;
+	wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	if (ops->remove)
+		ops->remove(ops, wdata);
+}
+
+static void wiimote_mp_load(struct wiimote_data *wdata)
+{
+	unsigned long flags;
+	const struct wiimod_ops *ops;
+	int ret;
+	__u8 mode = 2;
+
+	ops = &wiimod_mp;
+	if (ops->probe) {
+		ret = ops->probe(ops, wdata);
+		if (ret)
+			mode = 1;
 	}
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.mp = mode;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
 }
 
-static int wiimote_ff_play(struct input_dev *dev, void *data,
-							struct ff_effect *eff)
+static void wiimote_mp_unload(struct wiimote_data *wdata)
 {
-	struct wiimote_data *wdata = input_get_drvdata(dev);
-	__u8 value;
 	unsigned long flags;
+	const struct wiimod_ops *ops;
 
-	/*
-	 * The wiimote supports only a single rumble motor so if any magnitude
-	 * is set to non-zero then we start the rumble motor. If both are set to
-	 * zero, we stop the rumble motor.
-	 */
+	if (wdata->state.mp < 2)
+		return;
 
-	if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude)
-		value = 1;
-	else
-		value = 0;
+	ops = &wiimod_mp;
 
 	spin_lock_irqsave(&wdata->state.lock, flags);
-	wiiproto_req_rumble(wdata, value);
+	wdata->state.mp = 0;
+	wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED;
 	spin_unlock_irqrestore(&wdata->state.lock, flags);
 
-	return 0;
+	if (ops->remove)
+		ops->remove(ops, wdata);
 }
 
-static int wiimote_input_open(struct input_dev *dev)
-{
-	struct wiimote_data *wdata = input_get_drvdata(dev);
+/* device (re-)initialization and detection */
 
-	return hid_hw_open(wdata->hdev);
-}
+static const char *wiimote_devtype_names[WIIMOTE_DEV_NUM] = {
+	[WIIMOTE_DEV_PENDING] = "Pending",
+	[WIIMOTE_DEV_UNKNOWN] = "Unknown",
+	[WIIMOTE_DEV_GENERIC] = "Generic",
+	[WIIMOTE_DEV_GEN10] = "Nintendo Wii Remote (Gen 1)",
+	[WIIMOTE_DEV_GEN20] = "Nintendo Wii Remote Plus (Gen 2)",
+	[WIIMOTE_DEV_BALANCE_BOARD] = "Nintendo Wii Balance Board",
+	[WIIMOTE_DEV_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller",
+};
 
-static void wiimote_input_close(struct input_dev *dev)
+/* Try to guess the device type based on all collected information. We
+ * first try to detect by static extension types, then VID/PID and the
+ * device name. If we cannot detect the device, we use
+ * WIIMOTE_DEV_GENERIC so all modules will get probed on the device. */
+static void wiimote_init_set_type(struct wiimote_data *wdata,
+				  __u8 exttype)
 {
-	struct wiimote_data *wdata = input_get_drvdata(dev);
+	__u8 devtype = WIIMOTE_DEV_GENERIC;
+	__u16 vendor, product;
+	const char *name;
 
-	hid_hw_close(wdata->hdev);
+	vendor = wdata->hdev->vendor;
+	product = wdata->hdev->product;
+	name = wdata->hdev->name;
+
+	if (exttype == WIIMOTE_EXT_BALANCE_BOARD) {
+		devtype = WIIMOTE_DEV_BALANCE_BOARD;
+		goto done;
+	} else if (exttype == WIIMOTE_EXT_PRO_CONTROLLER) {
+		devtype = WIIMOTE_DEV_PRO_CONTROLLER;
+		goto done;
+	}
+
+	if (!strcmp(name, "Nintendo RVL-CNT-01")) {
+		devtype = WIIMOTE_DEV_GEN10;
+		goto done;
+	} else if (!strcmp(name, "Nintendo RVL-CNT-01-TR")) {
+		devtype = WIIMOTE_DEV_GEN20;
+		goto done;
+	} else if (!strcmp(name, "Nintendo RVL-WBC-01")) {
+		devtype = WIIMOTE_DEV_BALANCE_BOARD;
+		goto done;
+	} else if (!strcmp(name, "Nintendo RVL-CNT-01-UC")) {
+		devtype = WIIMOTE_DEV_PRO_CONTROLLER;
+		goto done;
+	}
+
+	if (vendor == USB_VENDOR_ID_NINTENDO) {
+		if (product == USB_DEVICE_ID_NINTENDO_WIIMOTE) {
+			devtype = WIIMOTE_DEV_GEN10;
+			goto done;
+		} else if (product == USB_DEVICE_ID_NINTENDO_WIIMOTE2) {
+			devtype = WIIMOTE_DEV_GEN20;
+			goto done;
+		}
+	}
+
+done:
+	if (devtype == WIIMOTE_DEV_GENERIC)
+		hid_info(wdata->hdev, "cannot detect device; NAME: %s VID: %04x PID: %04x EXT: %04x\n",
+			name, vendor, product, exttype);
+	else
+		hid_info(wdata->hdev, "detected device: %s\n",
+			 wiimote_devtype_names[devtype]);
+
+	wiimote_modules_load(wdata, devtype);
 }
 
-static int wiimote_accel_open(struct input_dev *dev)
+static void wiimote_init_detect(struct wiimote_data *wdata)
 {
-	struct wiimote_data *wdata = input_get_drvdata(dev);
+	__u8 exttype = WIIMOTE_EXT_NONE, extdata[6];
+	bool ext;
 	int ret;
-	unsigned long flags;
 
-	ret = hid_hw_open(wdata->hdev);
+	wiimote_cmd_acquire_noint(wdata);
+
+	spin_lock_irq(&wdata->state.lock);
+	wdata->state.devtype = WIIMOTE_DEV_UNKNOWN;
+	wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
+	wiiproto_req_status(wdata);
+	spin_unlock_irq(&wdata->state.lock);
+
+	ret = wiimote_cmd_wait_noint(wdata);
 	if (ret)
-		return ret;
+		goto out_release;
 
-	spin_lock_irqsave(&wdata->state.lock, flags);
-	wiiproto_req_accel(wdata, true);
-	spin_unlock_irqrestore(&wdata->state.lock, flags);
+	spin_lock_irq(&wdata->state.lock);
+	ext = wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED;
+	spin_unlock_irq(&wdata->state.lock);
 
-	return 0;
+	if (!ext)
+		goto out_release;
+
+	wiimote_cmd_init_ext(wdata);
+	exttype = wiimote_cmd_read_ext(wdata, extdata);
+
+out_release:
+	wiimote_cmd_release(wdata);
+	wiimote_init_set_type(wdata, exttype);
+
+	/* schedule MP timer */
+	spin_lock_irq(&wdata->state.lock);
+	if (!(wdata->state.flags & WIIPROTO_FLAG_BUILTIN_MP) &&
+	    !(wdata->state.flags & WIIPROTO_FLAG_NO_MP))
+		mod_timer(&wdata->timer, jiffies + HZ * 4);
+	spin_unlock_irq(&wdata->state.lock);
 }
 
-static void wiimote_accel_close(struct input_dev *dev)
+/*
+ * MP hotplug events are not generated by the wiimote. Therefore, we need
+ * polling to detect it. We use a 4s interval for polling MP registers. This
+ * seems reasonable considering applications can trigger it manually via
+ * sysfs requests.
+ */
+static void wiimote_init_poll_mp(struct wiimote_data *wdata)
 {
-	struct wiimote_data *wdata = input_get_drvdata(dev);
-	unsigned long flags;
+	bool mp;
+	__u8 mpdata[6];
 
-	spin_lock_irqsave(&wdata->state.lock, flags);
-	wiiproto_req_accel(wdata, false);
-	spin_unlock_irqrestore(&wdata->state.lock, flags);
+	wiimote_cmd_acquire_noint(wdata);
+	wiimote_cmd_init_mp(wdata);
+	mp = wiimote_cmd_read_mp(wdata, mpdata);
+	wiimote_cmd_release(wdata);
 
-	hid_hw_close(wdata->hdev);
+	/* load/unload MP module if it changed */
+	if (mp) {
+		if (!wdata->state.mp) {
+			hid_info(wdata->hdev, "detected extension: Nintendo Wii Motion Plus\n");
+			wiimote_mp_load(wdata);
+		}
+	} else if (wdata->state.mp) {
+		wiimote_mp_unload(wdata);
+	}
+
+	mod_timer(&wdata->timer, jiffies + HZ * 4);
 }
 
-static int wiimote_ir_open(struct input_dev *dev)
+/*
+ * Check whether the wiimote is in the expected state. The extension registers
+ * may change during hotplug and initialization so we might get hotplug events
+ * that we caused by remapping some memory.
+ * We use some heuristics here to check known states. If the wiimote is in the
+ * expected state, we can ignore the hotplug event.
+ *
+ * Returns "true" if the device is in expected state, "false" if we should
+ * redo hotplug handling and extension initialization.
+ */
+static bool wiimote_init_check(struct wiimote_data *wdata)
 {
-	struct wiimote_data *wdata = input_get_drvdata(dev);
-	int ret;
+	__u32 flags;
+	__u8 type, data[6];
+	bool ret, poll_mp;
 
-	ret = hid_hw_open(wdata->hdev);
-	if (ret)
-		return ret;
+	spin_lock_irq(&wdata->state.lock);
+	flags = wdata->state.flags;
+	spin_unlock_irq(&wdata->state.lock);
 
-	ret = wiimote_init_ir(wdata, WIIPROTO_FLAG_IR_BASIC);
-	if (ret) {
-		hid_hw_close(wdata->hdev);
-		return ret;
+	wiimote_cmd_acquire_noint(wdata);
+
+	/* If MP is used and active, but the extension is not, we expect:
+	 *   read_mp_mapped() == WIIMOTE_MP_SINGLE
+	 *   state.flags == !EXT_ACTIVE && !MP_PLUGGED && MP_ACTIVE
+	 * We do not check EXT_PLUGGED because it might change during
+	 * initialization of MP without extensions.
+	 *  - If MP is unplugged/replugged, read_mp_mapped() fails
+	 *  - If EXT is plugged, MP_PLUGGED will get set */
+	if (wdata->state.exttype == WIIMOTE_EXT_NONE &&
+	    wdata->state.mp > 0 && (flags & WIIPROTO_FLAG_MP_USED)) {
+		type = wiimote_cmd_read_mp_mapped(wdata);
+		ret = type == WIIMOTE_MP_SINGLE;
+
+		spin_lock_irq(&wdata->state.lock);
+		ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
+		ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED);
+		ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
+		spin_unlock_irq(&wdata->state.lock);
+
+		if (!ret)
+			hid_dbg(wdata->hdev, "state left: !EXT && MP\n");
+
+		/* while MP is mapped, we get EXT_PLUGGED events */
+		poll_mp = false;
+
+		goto out_release;
 	}
 
-	return 0;
+	/* If MP is unused, but the extension port is used, we expect:
+	 *   read_ext == state.exttype
+	 *   state.flags == !MP_ACTIVE && EXT_ACTIVE
+	 * - If MP is plugged/unplugged, our timer detects it
+	 * - If EXT is unplugged/replugged, EXT_ACTIVE will become unset */
+	if (!(flags & WIIPROTO_FLAG_MP_USED) &&
+	    wdata->state.exttype != WIIMOTE_EXT_NONE) {
+		type = wiimote_cmd_read_ext(wdata, data);
+		ret = type == wdata->state.exttype;
+
+		spin_lock_irq(&wdata->state.lock);
+		ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
+		ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
+		spin_unlock_irq(&wdata->state.lock);
+
+		if (!ret)
+			hid_dbg(wdata->hdev, "state left: EXT && !MP\n");
+
+		/* poll MP for hotplug events */
+		poll_mp = true;
+
+		goto out_release;
+	}
+
+	/* If neither MP nor an extension are used, we expect:
+	 *   read_ext() == WIIMOTE_EXT_NONE
+	 *   state.flags == !MP_ACTIVE && !EXT_ACTIVE && !EXT_PLUGGED
+	 * No need to perform any action in this case as everything is
+	 * disabled already.
+	 * - If MP is plugged/unplugged, our timer detects it
+	 * - If EXT is plugged, EXT_PLUGGED will be set */
+	if (!(flags & WIIPROTO_FLAG_MP_USED) &&
+	    wdata->state.exttype == WIIMOTE_EXT_NONE) {
+		type = wiimote_cmd_read_ext(wdata, data);
+		ret = type == wdata->state.exttype;
+
+		spin_lock_irq(&wdata->state.lock);
+		ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
+		ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
+		ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED);
+		spin_unlock_irq(&wdata->state.lock);
+
+		if (!ret)
+			hid_dbg(wdata->hdev, "state left: !EXT && !MP\n");
+
+		/* poll MP for hotplug events */
+		poll_mp = true;
+
+		goto out_release;
+	}
+
+	/* The trickiest part is if both EXT and MP are active. We cannot read
+	 * the EXT ID, anymore, because MP is mapped over it. However, we use
+	 * a handy trick here:
+	 *   - EXT_ACTIVE is unset whenever !MP_PLUGGED is sent
+	 * MP_PLUGGED might be re-sent again before we are scheduled, but
+	 * EXT_ACTIVE will stay unset.
+	 * So it is enough to check for mp_mapped() and MP_ACTIVE and
+	 * EXT_ACTIVE. EXT_PLUGGED is a sanity check. */
+	if (wdata->state.exttype != WIIMOTE_EXT_NONE &&
+	    wdata->state.mp > 0 && (flags & WIIPROTO_FLAG_MP_USED)) {
+		type = wiimote_cmd_read_mp_mapped(wdata);
+		ret = type != WIIMOTE_MP_NONE;
+		ret = ret && type != WIIMOTE_MP_UNKNOWN;
+		ret = ret && type != WIIMOTE_MP_SINGLE;
+
+		spin_lock_irq(&wdata->state.lock);
+		ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED);
+		ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE);
+		ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE);
+		spin_unlock_irq(&wdata->state.lock);
+
+		if (!ret)
+			hid_dbg(wdata->hdev, "state left: EXT && MP\n");
+
+		/* while MP is mapped, we get EXT_PLUGGED events */
+		poll_mp = false;
+
+		goto out_release;
+	}
+
+	/* unknown state */
+	ret = false;
+
+out_release:
+	wiimote_cmd_release(wdata);
+
+	/* only poll for MP if requested and if state didn't change */
+	if (ret && poll_mp && !(flags & WIIPROTO_FLAG_BUILTIN_MP) &&
+	    !(flags & WIIPROTO_FLAG_NO_MP))
+		wiimote_init_poll_mp(wdata);
+
+	return ret;
 }
 
-static void wiimote_ir_close(struct input_dev *dev)
+static const char *wiimote_exttype_names[WIIMOTE_EXT_NUM] = {
+	[WIIMOTE_EXT_NONE] = "None",
+	[WIIMOTE_EXT_UNKNOWN] = "Unknown",
+	[WIIMOTE_EXT_NUNCHUK] = "Nintendo Wii Nunchuk",
+	[WIIMOTE_EXT_CLASSIC_CONTROLLER] = "Nintendo Wii Classic Controller",
+	[WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board",
+	[WIIMOTE_EXT_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller",
+};
+
+/*
+ * Handle hotplug events
+ * If we receive an hotplug event and the device-check failed, we deinitialize
+ * the extension ports, re-read all extension IDs and set the device into
+ * the desired state. This involves mapping MP into the main extension
+ * registers, setting up extension passthrough modes and initializing the
+ * requested extensions.
+ */
+static void wiimote_init_hotplug(struct wiimote_data *wdata)
 {
-	struct wiimote_data *wdata = input_get_drvdata(dev);
+	__u8 exttype, extdata[6], mpdata[6];
+	__u32 flags;
+	bool mp;
 
-	wiimote_init_ir(wdata, 0);
-	hid_hw_close(wdata->hdev);
+	hid_dbg(wdata->hdev, "detect extensions..\n");
+
+	wiimote_cmd_acquire_noint(wdata);
+
+	spin_lock_irq(&wdata->state.lock);
+
+	/* get state snapshot that we will then work on */
+	flags = wdata->state.flags;
+
+	/* disable event forwarding temporarily */
+	wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE;
+	wdata->state.flags &= ~WIIPROTO_FLAG_MP_ACTIVE;
+
+	spin_unlock_irq(&wdata->state.lock);
+
+	/* init extension and MP (deactivates current extension or MP) */
+	wiimote_cmd_init_ext(wdata);
+	if (flags & WIIPROTO_FLAG_NO_MP) {
+		mp = false;
+	} else {
+		wiimote_cmd_init_mp(wdata);
+		mp = wiimote_cmd_read_mp(wdata, mpdata);
+	}
+	exttype = wiimote_cmd_read_ext(wdata, extdata);
+
+	wiimote_cmd_release(wdata);
+
+	/* load/unload extension module if it changed */
+	if (exttype != wdata->state.exttype) {
+		/* unload previous extension */
+		wiimote_ext_unload(wdata);
+
+		if (exttype == WIIMOTE_EXT_UNKNOWN) {
+			hid_info(wdata->hdev, "cannot detect extension; %02x:%02x %02x:%02x %02x:%02x\n",
+				 extdata[0], extdata[1], extdata[2],
+				 extdata[3], extdata[4], extdata[5]);
+		} else if (exttype == WIIMOTE_EXT_NONE) {
+			spin_lock_irq(&wdata->state.lock);
+			wdata->state.exttype = WIIMOTE_EXT_NONE;
+			spin_unlock_irq(&wdata->state.lock);
+		} else {
+			hid_info(wdata->hdev, "detected extension: %s\n",
+				 wiimote_exttype_names[exttype]);
+			/* try loading new extension */
+			wiimote_ext_load(wdata, exttype);
+		}
+	}
+
+	/* load/unload MP module if it changed */
+	if (mp) {
+		if (!wdata->state.mp) {
+			hid_info(wdata->hdev, "detected extension: Nintendo Wii Motion Plus\n");
+			wiimote_mp_load(wdata);
+		}
+	} else if (wdata->state.mp) {
+		wiimote_mp_unload(wdata);
+	}
+
+	/* if MP is not used, do not map or activate it */
+	if (!(flags & WIIPROTO_FLAG_MP_USED))
+		mp = false;
+
+	/* map MP into main extension registers if used */
+	if (mp) {
+		wiimote_cmd_acquire_noint(wdata);
+		wiimote_cmd_map_mp(wdata, exttype);
+		wiimote_cmd_release(wdata);
+
+		/* delete MP hotplug timer */
+		del_timer_sync(&wdata->timer);
+	} else {
+		/* reschedule MP hotplug timer */
+		if (!(flags & WIIPROTO_FLAG_BUILTIN_MP) &&
+		    !(flags & WIIPROTO_FLAG_NO_MP))
+			mod_timer(&wdata->timer, jiffies + HZ * 4);
+	}
+
+	spin_lock_irq(&wdata->state.lock);
+
+	/* enable data forwarding again and set expected hotplug state */
+	if (mp) {
+		wdata->state.flags |= WIIPROTO_FLAG_MP_ACTIVE;
+		if (wdata->state.exttype == WIIMOTE_EXT_NONE) {
+			wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED;
+			wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED;
+		} else {
+			wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED;
+			wdata->state.flags |= WIIPROTO_FLAG_MP_PLUGGED;
+			wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE;
+		}
+	} else if (wdata->state.exttype != WIIMOTE_EXT_NONE) {
+		wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE;
+	}
+
+	/* request status report for hotplug state updates */
+	wiiproto_req_status(wdata);
+
+	spin_unlock_irq(&wdata->state.lock);
+
+	hid_dbg(wdata->hdev, "detected extensions: MP: %d EXT: %d\n",
+		wdata->state.mp, wdata->state.exttype);
 }
 
-static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
+static void wiimote_init_worker(struct work_struct *work)
 {
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_LEFT],
-							!!(payload[0] & 0x01));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_RIGHT],
-							!!(payload[0] & 0x02));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_DOWN],
-							!!(payload[0] & 0x04));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_UP],
-							!!(payload[0] & 0x08));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_PLUS],
-							!!(payload[0] & 0x10));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_TWO],
-							!!(payload[1] & 0x01));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_ONE],
-							!!(payload[1] & 0x02));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_B],
-							!!(payload[1] & 0x04));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_A],
-							!!(payload[1] & 0x08));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_MINUS],
-							!!(payload[1] & 0x10));
-	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_HOME],
-							!!(payload[1] & 0x80));
-	input_sync(wdata->input);
+	struct wiimote_data *wdata = container_of(work, struct wiimote_data,
+						  init_worker);
+	bool changed = false;
+
+	if (wdata->state.devtype == WIIMOTE_DEV_PENDING) {
+		wiimote_init_detect(wdata);
+		changed = true;
+	}
+
+	if (changed || !wiimote_init_check(wdata))
+		wiimote_init_hotplug(wdata);
+
+	if (changed)
+		kobject_uevent(&wdata->hdev->dev.kobj, KOBJ_CHANGE);
 }
 
-static void handler_accel(struct wiimote_data *wdata, const __u8 *payload)
+void __wiimote_schedule(struct wiimote_data *wdata)
 {
-	__u16 x, y, z;
+	if (!(wdata->state.flags & WIIPROTO_FLAG_EXITING))
+		schedule_work(&wdata->init_worker);
+}
 
-	if (!(wdata->state.flags & WIIPROTO_FLAG_ACCEL))
+static void wiimote_schedule(struct wiimote_data *wdata)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	__wiimote_schedule(wdata);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static void wiimote_init_timeout(unsigned long arg)
+{
+	struct wiimote_data *wdata = (void*)arg;
+
+	wiimote_schedule(wdata);
+}
+
+/* protocol handlers */
+
+static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
+{
+	const __u8 *iter, *mods;
+	const struct wiimod_ops *ops;
+
+	ops = wiimod_ext_table[wdata->state.exttype];
+	if (ops->in_keys) {
+		ops->in_keys(wdata, payload);
 		return;
+	}
 
-	/*
-	 * payload is: BB BB XX YY ZZ
-	 * Accelerometer data is encoded into 3 10bit values. XX, YY and ZZ
-	 * contain the upper 8 bits of each value. The lower 2 bits are
-	 * contained in the buttons data BB BB.
-	 * Bits 6 and 7 of the first buttons byte BB is the lower 2 bits of the
-	 * X accel value. Bit 5 of the second buttons byte is the 2nd bit of Y
-	 * accel value and bit 6 is the second bit of the Z value.
-	 * The first bit of Y and Z values is not available and always set to 0.
-	 * 0x200 is returned on no movement.
-	 */
+	mods = wiimote_devtype_mods[wdata->state.devtype];
+	for (iter = mods; *iter != WIIMOD_NULL; ++iter) {
+		ops = wiimod_table[*iter];
+		if (ops->in_keys) {
+			ops->in_keys(wdata, payload);
+			break;
+		}
+	}
+}
 
-	x = payload[2] << 2;
-	y = payload[3] << 2;
-	z = payload[4] << 2;
+static void handler_accel(struct wiimote_data *wdata, const __u8 *payload)
+{
+	const __u8 *iter, *mods;
+	const struct wiimod_ops *ops;
 
-	x |= (payload[0] >> 5) & 0x3;
-	y |= (payload[1] >> 4) & 0x2;
-	z |= (payload[1] >> 5) & 0x2;
+	ops = wiimod_ext_table[wdata->state.exttype];
+	if (ops->in_accel) {
+		ops->in_accel(wdata, payload);
+		return;
+	}
 
-	input_report_abs(wdata->accel, ABS_RX, x - 0x200);
-	input_report_abs(wdata->accel, ABS_RY, y - 0x200);
-	input_report_abs(wdata->accel, ABS_RZ, z - 0x200);
-	input_sync(wdata->accel);
+	mods = wiimote_devtype_mods[wdata->state.devtype];
+	for (iter = mods; *iter != WIIMOD_NULL; ++iter) {
+		ops = wiimod_table[*iter];
+		if (ops->in_accel) {
+			ops->in_accel(wdata, payload);
+			break;
+		}
+	}
 }
 
-#define ir_to_input0(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
-							ABS_HAT0X, ABS_HAT0Y)
-#define ir_to_input1(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
-							ABS_HAT1X, ABS_HAT1Y)
-#define ir_to_input2(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
-							ABS_HAT2X, ABS_HAT2Y)
-#define ir_to_input3(wdata, ir, packed) __ir_to_input((wdata), (ir), (packed), \
-							ABS_HAT3X, ABS_HAT3Y)
+static bool valid_ext_handler(const struct wiimod_ops *ops, size_t len)
+{
+	if (!ops->in_ext)
+		return false;
+	if ((ops->flags & WIIMOD_FLAG_EXT8) && len < 8)
+		return false;
+	if ((ops->flags & WIIMOD_FLAG_EXT16) && len < 16)
+		return false;
 
-static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir,
-						bool packed, __u8 xid, __u8 yid)
+	return true;
+}
+
+static void handler_ext(struct wiimote_data *wdata, const __u8 *payload,
+			size_t len)
 {
-	__u16 x, y;
+	static const __u8 invalid[21] = { 0xff, 0xff, 0xff, 0xff,
+					  0xff, 0xff, 0xff, 0xff,
+					  0xff, 0xff, 0xff, 0xff,
+					  0xff, 0xff, 0xff, 0xff,
+					  0xff, 0xff, 0xff, 0xff,
+					  0xff };
+	const __u8 *iter, *mods;
+	const struct wiimod_ops *ops;
+	bool is_mp;
 
-	if (!(wdata->state.flags & WIIPROTO_FLAGS_IR))
+	if (len > 21)
+		len = 21;
+	if (len < 6 || !memcmp(payload, invalid, len))
 		return;
 
-	/*
-	 * Basic IR data is encoded into 3 bytes. The first two bytes are the
-	 * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits
-	 * of both.
-	 * If data is packed, then the 3rd byte is put first and slightly
-	 * reordered. This allows to interleave packed and non-packed data to
-	 * have two IR sets in 5 bytes instead of 6.
-	 * The resulting 10bit X/Y values are passed to the ABS_HATXY input dev.
-	 */
+	/* if MP is active, track MP slot hotplugging */
+	if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
+		/* this bit is set for invalid events (eg. during hotplug) */
+		if (payload[5] & 0x01)
+			return;
 
-	if (packed) {
-		x = ir[1] | ((ir[0] & 0x03) << 8);
-		y = ir[2] | ((ir[0] & 0x0c) << 6);
+		if (payload[4] & 0x01) {
+			if (!(wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED)) {
+				hid_dbg(wdata->hdev, "MP hotplug: 1\n");
+				wdata->state.flags |= WIIPROTO_FLAG_MP_PLUGGED;
+				__wiimote_schedule(wdata);
+			}
+		} else {
+			if (wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED) {
+				hid_dbg(wdata->hdev, "MP hotplug: 0\n");
+				wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED;
+				wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE;
+				__wiimote_schedule(wdata);
+			}
+		}
+
+		/* detect MP data that is sent interleaved with EXT data */
+		is_mp = payload[5] & 0x02;
 	} else {
-		x = ir[0] | ((ir[2] & 0x30) << 4);
-		y = ir[1] | ((ir[2] & 0xc0) << 2);
+		is_mp = false;
 	}
 
-	input_report_abs(wdata->ir, xid, x);
-	input_report_abs(wdata->ir, yid, y);
+	/* ignore EXT events if no extension is active */
+	if (!(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE) && !is_mp)
+		return;
+
+	/* try forwarding to extension handler, first */
+	ops = wiimod_ext_table[wdata->state.exttype];
+	if (is_mp && ops->in_mp) {
+		ops->in_mp(wdata, payload);
+		return;
+	} else if (!is_mp && valid_ext_handler(ops, len)) {
+		ops->in_ext(wdata, payload);
+		return;
+	}
+
+	/* try forwarding to MP handler */
+	ops = &wiimod_mp;
+	if (is_mp && ops->in_mp) {
+		ops->in_mp(wdata, payload);
+		return;
+	} else if (!is_mp && valid_ext_handler(ops, len)) {
+		ops->in_ext(wdata, payload);
+		return;
+	}
+
+	/* try forwarding to loaded modules */
+	mods = wiimote_devtype_mods[wdata->state.devtype];
+	for (iter = mods; *iter != WIIMOD_NULL; ++iter) {
+		ops = wiimod_table[*iter];
+		if (is_mp && ops->in_mp) {
+			ops->in_mp(wdata, payload);
+			return;
+		} else if (!is_mp && valid_ext_handler(ops, len)) {
+			ops->in_ext(wdata, payload);
+			return;
+		}
+	}
+}
+
+#define ir_to_input0(wdata, ir, packed) handler_ir((wdata), (ir), (packed), 0)
+#define ir_to_input1(wdata, ir, packed) handler_ir((wdata), (ir), (packed), 1)
+#define ir_to_input2(wdata, ir, packed) handler_ir((wdata), (ir), (packed), 2)
+#define ir_to_input3(wdata, ir, packed) handler_ir((wdata), (ir), (packed), 3)
+
+static void handler_ir(struct wiimote_data *wdata, const __u8 *payload,
+		       bool packed, unsigned int id)
+{
+	const __u8 *iter, *mods;
+	const struct wiimod_ops *ops;
+
+	ops = wiimod_ext_table[wdata->state.exttype];
+	if (ops->in_ir) {
+		ops->in_ir(wdata, payload, packed, id);
+		return;
+	}
+
+	mods = wiimote_devtype_mods[wdata->state.devtype];
+	for (iter = mods; *iter != WIIMOD_NULL; ++iter) {
+		ops = wiimod_table[*iter];
+		if (ops->in_ir) {
+			ops->in_ir(wdata, payload, packed, id);
+			break;
+		}
+	}
 }
 
 /* reduced status report with "BB BB" key data only */
@@ -804,12 +1417,27 @@ static void handler_status(struct wiimot
 {
 	handler_status_K(wdata, payload);
 
-	wiiext_event(wdata, payload[2] & 0x02);
+	/* update extension status */
+	if (payload[2] & 0x02) {
+		if (!(wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED)) {
+			hid_dbg(wdata->hdev, "EXT hotplug: 1\n");
+			wdata->state.flags |= WIIPROTO_FLAG_EXT_PLUGGED;
+			__wiimote_schedule(wdata);
+		}
+	} else {
+		if (wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED) {
+			hid_dbg(wdata->hdev, "EXT hotplug: 0\n");
+			wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED;
+			wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED;
+			wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE;
+			wdata->state.flags &= ~WIIPROTO_FLAG_MP_ACTIVE;
+			__wiimote_schedule(wdata);
+		}
+	}
 
-	if (wiimote_cmd_pending(wdata, WIIPROTO_REQ_SREQ, 0)) {
-		wdata->state.cmd_battery = payload[5];
+	wdata->state.cmd_battery = payload[5];
+	if (wiimote_cmd_pending(wdata, WIIPROTO_REQ_SREQ, 0))
 		wiimote_cmd_complete(wdata);
-	}
 }
 
 /* reduced generic report with "BB BB" key data only */
@@ -864,7 +1492,7 @@ static void handler_drm_KA(struct wiimot
 static void handler_drm_KE(struct wiimote_data *wdata, const __u8 *payload)
 {
 	handler_keys(wdata, payload);
-	wiiext_handle(wdata, &payload[2]);
+	handler_ext(wdata, &payload[2], 8);
 }
 
 static void handler_drm_KAI(struct wiimote_data *wdata, const __u8 *payload)
@@ -875,13 +1503,12 @@ static void handler_drm_KAI(struct wiimo
 	ir_to_input1(wdata, &payload[8], false);
 	ir_to_input2(wdata, &payload[11], false);
 	ir_to_input3(wdata, &payload[14], false);
-	input_sync(wdata->ir);
 }
 
 static void handler_drm_KEE(struct wiimote_data *wdata, const __u8 *payload)
 {
 	handler_keys(wdata, payload);
-	wiiext_handle(wdata, &payload[2]);
+	handler_ext(wdata, &payload[2], 19);
 }
 
 static void handler_drm_KIE(struct wiimote_data *wdata, const __u8 *payload)
@@ -891,15 +1518,14 @@ static void handler_drm_KIE(struct wiimo
 	ir_to_input1(wdata, &payload[4], true);
 	ir_to_input2(wdata, &payload[7], false);
 	ir_to_input3(wdata, &payload[9], true);
-	input_sync(wdata->ir);
-	wiiext_handle(wdata, &payload[12]);
+	handler_ext(wdata, &payload[12], 9);
 }
 
 static void handler_drm_KAE(struct wiimote_data *wdata, const __u8 *payload)
 {
 	handler_keys(wdata, payload);
 	handler_accel(wdata, payload);
-	wiiext_handle(wdata, &payload[5]);
+	handler_ext(wdata, &payload[5], 16);
 }
 
 static void handler_drm_KAIE(struct wiimote_data *wdata, const __u8 *payload)
@@ -910,13 +1536,12 @@ static void handler_drm_KAIE(struct wiim
 	ir_to_input1(wdata, &payload[7], true);
 	ir_to_input2(wdata, &payload[10], false);
 	ir_to_input3(wdata, &payload[12], true);
-	input_sync(wdata->ir);
-	wiiext_handle(wdata, &payload[15]);
+	handler_ext(wdata, &payload[15], 6);
 }
 
 static void handler_drm_E(struct wiimote_data *wdata, const __u8 *payload)
 {
-	wiiext_handle(wdata, payload);
+	handler_ext(wdata, payload, 21);
 }
 
 static void handler_drm_SKAI1(struct wiimote_data *wdata, const __u8 *payload)
@@ -929,7 +1554,6 @@ static void handler_drm_SKAI1(struct wii
 
 	ir_to_input0(wdata, &payload[3], false);
 	ir_to_input1(wdata, &payload[12], false);
-	input_sync(wdata->ir);
 }
 
 static void handler_drm_SKAI2(struct wiimote_data *wdata, const __u8 *payload)
@@ -950,7 +1574,6 @@ static void handler_drm_SKAI2(struct wii
 
 	ir_to_input2(wdata, &payload[3], false);
 	ir_to_input3(wdata, &payload[12], false);
-	input_sync(wdata->ir);
 }
 
 struct wiiproto_handler {
@@ -1017,177 +1640,136 @@ static int wiimote_hid_event(struct hid_
 	return 0;
 }
 
-static void wiimote_leds_destroy(struct wiimote_data *wdata)
+static ssize_t wiimote_ext_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
 {
-	int i;
-	struct led_classdev *led;
+	struct wiimote_data *wdata = dev_to_wii(dev);
+	__u8 type;
+	unsigned long flags;
 
-	for (i = 0; i < 4; ++i) {
-		if (wdata->leds[i]) {
-			led = wdata->leds[i];
-			wdata->leds[i] = NULL;
-			led_classdev_unregister(led);
-			kfree(led);
-		}
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	type = wdata->state.exttype;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	switch (type) {
+	case WIIMOTE_EXT_NONE:
+		return sprintf(buf, "none\n");
+	case WIIMOTE_EXT_NUNCHUK:
+		return sprintf(buf, "nunchuk\n");
+	case WIIMOTE_EXT_CLASSIC_CONTROLLER:
+		return sprintf(buf, "classic\n");
+	case WIIMOTE_EXT_BALANCE_BOARD:
+		return sprintf(buf, "balanceboard\n");
+	case WIIMOTE_EXT_PRO_CONTROLLER:
+		return sprintf(buf, "procontroller\n");
+	case WIIMOTE_EXT_UNKNOWN:
+		/* fallthrough */
+	default:
+		return sprintf(buf, "unknown\n");
 	}
 }
 
-static int wiimote_leds_create(struct wiimote_data *wdata)
+static ssize_t wiimote_ext_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
 {
-	int i, ret;
-	struct device *dev = &wdata->hdev->dev;
-	size_t namesz = strlen(dev_name(dev)) + 9;
-	struct led_classdev *led;
-	char *name;
-
-	for (i = 0; i < 4; ++i) {
-		led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
-		if (!led) {
-			ret = -ENOMEM;
-			goto err;
-		}
-		name = (void*)&led[1];
-		snprintf(name, namesz, "%s:blue:p%d", dev_name(dev), i);
-		led->name = name;
-		led->brightness = 0;
-		led->max_brightness = 1;
-		led->brightness_get = wiimote_leds_get;
-		led->brightness_set = wiimote_leds_set;
+	struct wiimote_data *wdata = dev_to_wii(dev);
 
-		ret = led_classdev_register(dev, led);
-		if (ret) {
-			kfree(led);
-			goto err;
-		}
-		wdata->leds[i] = led;
+	if (!strcmp(buf, "scan")) {
+		wiimote_schedule(wdata);
+	} else {
+		return -EINVAL;
 	}
 
-	return 0;
+	return strnlen(buf, PAGE_SIZE);
+}
 
-err:
-	wiimote_leds_destroy(wdata);
-	return ret;
+static DEVICE_ATTR(extension, S_IRUGO | S_IWUSR | S_IWGRP, wiimote_ext_show,
+		   wiimote_ext_store);
+
+static ssize_t wiimote_dev_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct wiimote_data *wdata = dev_to_wii(dev);
+	__u8 type;
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	type = wdata->state.devtype;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	switch (type) {
+	case WIIMOTE_DEV_GENERIC:
+		return sprintf(buf, "generic\n");
+	case WIIMOTE_DEV_GEN10:
+		return sprintf(buf, "gen10\n");
+	case WIIMOTE_DEV_GEN20:
+		return sprintf(buf, "gen20\n");
+	case WIIMOTE_DEV_BALANCE_BOARD:
+		return sprintf(buf, "balanceboard\n");
+	case WIIMOTE_DEV_PRO_CONTROLLER:
+		return sprintf(buf, "procontroller\n");
+	case WIIMOTE_DEV_PENDING:
+		return sprintf(buf, "pending\n");
+	case WIIMOTE_DEV_UNKNOWN:
+		/* fallthrough */
+	default:
+		return sprintf(buf, "unknown\n");
+	}
 }
 
+static DEVICE_ATTR(devtype, S_IRUGO, wiimote_dev_show, NULL);
+
 static struct wiimote_data *wiimote_create(struct hid_device *hdev)
 {
 	struct wiimote_data *wdata;
-	int i;
 
 	wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
 	if (!wdata)
 		return NULL;
 
-	wdata->input = input_allocate_device();
-	if (!wdata->input)
-		goto err;
-
 	wdata->hdev = hdev;
 	hid_set_drvdata(hdev, wdata);
 
-	input_set_drvdata(wdata->input, wdata);
-	wdata->input->open = wiimote_input_open;
-	wdata->input->close = wiimote_input_close;
-	wdata->input->dev.parent = &wdata->hdev->dev;
-	wdata->input->id.bustype = wdata->hdev->bus;
-	wdata->input->id.vendor = wdata->hdev->vendor;
-	wdata->input->id.product = wdata->hdev->product;
-	wdata->input->id.version = wdata->hdev->version;
-	wdata->input->name = WIIMOTE_NAME;
-
-	set_bit(EV_KEY, wdata->input->evbit);
-	for (i = 0; i < WIIPROTO_KEY_COUNT; ++i)
-		set_bit(wiiproto_keymap[i], wdata->input->keybit);
-
-	set_bit(FF_RUMBLE, wdata->input->ffbit);
-	if (input_ff_create_memless(wdata->input, NULL, wiimote_ff_play))
-		goto err_input;
-
-	wdata->accel = input_allocate_device();
-	if (!wdata->accel)
-		goto err_input;
-
-	input_set_drvdata(wdata->accel, wdata);
-	wdata->accel->open = wiimote_accel_open;
-	wdata->accel->close = wiimote_accel_close;
-	wdata->accel->dev.parent = &wdata->hdev->dev;
-	wdata->accel->id.bustype = wdata->hdev->bus;
-	wdata->accel->id.vendor = wdata->hdev->vendor;
-	wdata->accel->id.product = wdata->hdev->product;
-	wdata->accel->id.version = wdata->hdev->version;
-	wdata->accel->name = WIIMOTE_NAME " Accelerometer";
-
-	set_bit(EV_ABS, wdata->accel->evbit);
-	set_bit(ABS_RX, wdata->accel->absbit);
-	set_bit(ABS_RY, wdata->accel->absbit);
-	set_bit(ABS_RZ, wdata->accel->absbit);
-	input_set_abs_params(wdata->accel, ABS_RX, -500, 500, 2, 4);
-	input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4);
-	input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4);
-
-	wdata->ir = input_allocate_device();
-	if (!wdata->ir)
-		goto err_ir;
-
-	input_set_drvdata(wdata->ir, wdata);
-	wdata->ir->open = wiimote_ir_open;
-	wdata->ir->close = wiimote_ir_close;
-	wdata->ir->dev.parent = &wdata->hdev->dev;
-	wdata->ir->id.bustype = wdata->hdev->bus;
-	wdata->ir->id.vendor = wdata->hdev->vendor;
-	wdata->ir->id.product = wdata->hdev->product;
-	wdata->ir->id.version = wdata->hdev->version;
-	wdata->ir->name = WIIMOTE_NAME " IR";
-
-	set_bit(EV_ABS, wdata->ir->evbit);
-	set_bit(ABS_HAT0X, wdata->ir->absbit);
-	set_bit(ABS_HAT0Y, wdata->ir->absbit);
-	set_bit(ABS_HAT1X, wdata->ir->absbit);
-	set_bit(ABS_HAT1Y, wdata->ir->absbit);
-	set_bit(ABS_HAT2X, wdata->ir->absbit);
-	set_bit(ABS_HAT2Y, wdata->ir->absbit);
-	set_bit(ABS_HAT3X, wdata->ir->absbit);
-	set_bit(ABS_HAT3Y, wdata->ir->absbit);
-	input_set_abs_params(wdata->ir, ABS_HAT0X, 0, 1023, 2, 4);
-	input_set_abs_params(wdata->ir, ABS_HAT0Y, 0, 767, 2, 4);
-	input_set_abs_params(wdata->ir, ABS_HAT1X, 0, 1023, 2, 4);
-	input_set_abs_params(wdata->ir, ABS_HAT1Y, 0, 767, 2, 4);
-	input_set_abs_params(wdata->ir, ABS_HAT2X, 0, 1023, 2, 4);
-	input_set_abs_params(wdata->ir, ABS_HAT2Y, 0, 767, 2, 4);
-	input_set_abs_params(wdata->ir, ABS_HAT3X, 0, 1023, 2, 4);
-	input_set_abs_params(wdata->ir, ABS_HAT3Y, 0, 767, 2, 4);
-
-	spin_lock_init(&wdata->qlock);
-	INIT_WORK(&wdata->worker, wiimote_worker);
+	spin_lock_init(&wdata->queue.lock);
+	INIT_WORK(&wdata->queue.worker, wiimote_queue_worker);
 
 	spin_lock_init(&wdata->state.lock);
 	init_completion(&wdata->state.ready);
 	mutex_init(&wdata->state.sync);
 	wdata->state.drm = WIIPROTO_REQ_DRM_K;
+	wdata->state.cmd_battery = 0xff;
 
-	return wdata;
+	INIT_WORK(&wdata->init_worker, wiimote_init_worker);
+	setup_timer(&wdata->timer, wiimote_init_timeout, (long)wdata);
 
-err_ir:
-	input_free_device(wdata->accel);
-err_input:
-	input_free_device(wdata->input);
-err:
-	kfree(wdata);
-	return NULL;
+	return wdata;
 }
 
 static void wiimote_destroy(struct wiimote_data *wdata)
 {
+	unsigned long flags;
+
 	wiidebug_deinit(wdata);
-	wiiext_deinit(wdata);
-	wiimote_leds_destroy(wdata);
 
-	power_supply_unregister(&wdata->battery);
-	kfree(wdata->battery.name);
-	input_unregister_device(wdata->accel);
-	input_unregister_device(wdata->ir);
-	input_unregister_device(wdata->input);
-	cancel_work_sync(&wdata->worker);
+	/* prevent init_worker from being scheduled again */
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_EXITING;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	cancel_work_sync(&wdata->init_worker);
+	del_timer_sync(&wdata->timer);
+
+	device_remove_file(&wdata->hdev->dev, &dev_attr_devtype);
+	device_remove_file(&wdata->hdev->dev, &dev_attr_extension);
+
+	wiimote_mp_unload(wdata);
+	wiimote_ext_unload(wdata);
+	wiimote_modules_unload(wdata);
+	cancel_work_sync(&wdata->queue.worker);
+	hid_hw_close(wdata->hdev);
 	hid_hw_stop(wdata->hdev);
 
 	kfree(wdata);
@@ -1219,62 +1801,32 @@ static int wiimote_hid_probe(struct hid_
 		goto err;
 	}
 
-	ret = input_register_device(wdata->accel);
+	ret = hid_hw_open(hdev);
 	if (ret) {
-		hid_err(hdev, "Cannot register input device\n");
+		hid_err(hdev, "cannot start hardware I/O\n");
 		goto err_stop;
 	}
 
-	ret = input_register_device(wdata->ir);
-	if (ret) {
-		hid_err(hdev, "Cannot register input device\n");
-		goto err_ir;
-	}
-
-	ret = input_register_device(wdata->input);
+	ret = device_create_file(&hdev->dev, &dev_attr_extension);
 	if (ret) {
-		hid_err(hdev, "Cannot register input device\n");
-		goto err_input;
-	}
-
-	wdata->battery.properties = wiimote_battery_props;
-	wdata->battery.num_properties = ARRAY_SIZE(wiimote_battery_props);
-	wdata->battery.get_property = wiimote_battery_get_property;
-	wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
-	wdata->battery.use_for_apm = 0;
-	wdata->battery.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s",
-					wdata->hdev->uniq);
-	if (!wdata->battery.name) {
-		ret = -ENOMEM;
-		goto err_battery_name;
+		hid_err(hdev, "cannot create sysfs attribute\n");
+		goto err_close;
 	}
 
-	ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
+	ret = device_create_file(&hdev->dev, &dev_attr_devtype);
 	if (ret) {
-		hid_err(hdev, "Cannot register battery device\n");
-		goto err_battery;
+		hid_err(hdev, "cannot create sysfs attribute\n");
+		goto err_ext;
 	}
 
-	power_supply_powers(&wdata->battery, &hdev->dev);
-
-	ret = wiimote_leds_create(wdata);
-	if (ret)
-		goto err_free;
-
-	ret = wiiext_init(wdata);
-	if (ret)
-		goto err_free;
-
 	ret = wiidebug_init(wdata);
 	if (ret)
 		goto err_free;
 
 	hid_info(hdev, "New device registered\n");
 
-	/* by default set led1 after device initialization */
-	spin_lock_irq(&wdata->state.lock);
-	wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1);
-	spin_unlock_irq(&wdata->state.lock);
+	/* schedule device detection */
+	wiimote_schedule(wdata);
 
 	return 0;
 
@@ -1282,23 +1834,15 @@ err_free:
 	wiimote_destroy(wdata);
 	return ret;
 
-err_battery:
-	kfree(wdata->battery.name);
-err_battery_name:
-	input_unregister_device(wdata->input);
-	wdata->input = NULL;
-err_input:
-	input_unregister_device(wdata->ir);
-	wdata->ir = NULL;
-err_ir:
-	input_unregister_device(wdata->accel);
-	wdata->accel = NULL;
+err_ext:
+	device_remove_file(&wdata->hdev->dev, &dev_attr_extension);
+err_close:
+	hid_hw_close(hdev);
 err_stop:
 	hid_hw_stop(hdev);
 err:
 	input_free_device(wdata->ir);
 	input_free_device(wdata->accel);
-	input_free_device(wdata->input);
 	kfree(wdata);
 	return ret;
 }
@@ -1331,4 +1875,4 @@ module_hid_driver(wiimote_hid_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
-MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver");
+MODULE_DESCRIPTION("Driver for Nintendo Wii / Wii U peripherals");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-wiimote-debug.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote-debug.c
--- linux-libre-3.10-gnu/drivers/hid/hid-wiimote-debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote-debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 /*
- * Debug support for HID Nintendo Wiimote devices
- * Copyright (c) 2011 David Herrmann
+ * Debug support for HID Nintendo Wii / Wii U peripherals
+ * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com>
  */
 
 /*
@@ -127,7 +127,8 @@ static int wiidebug_drm_open(struct inod
 static ssize_t wiidebug_drm_write(struct file *f, const char __user *u,
 							size_t s, loff_t *off)
 {
-	struct wiimote_debug *dbg = f->private_data;
+	struct seq_file *sf = f->private_data;
+	struct wiimote_debug *dbg = sf->private;
 	unsigned long flags;
 	char buf[16];
 	ssize_t len;
@@ -140,7 +141,7 @@ static ssize_t wiidebug_drm_write(struct
 	if (copy_from_user(buf, u, len))
 		return -EFAULT;
 
-	buf[15] = 0;
+	buf[len] = 0;
 
 	for (i = 0; i < WIIPROTO_REQ_MAX; ++i) {
 		if (!wiidebug_drmmap[i])
@@ -150,10 +151,13 @@ static ssize_t wiidebug_drm_write(struct
 	}
 
 	if (i == WIIPROTO_REQ_MAX)
-		i = simple_strtoul(buf, NULL, 10);
+		i = simple_strtoul(buf, NULL, 16);
 
 	spin_lock_irqsave(&dbg->wdata->state.lock, flags);
+	dbg->wdata->state.flags &= ~WIIPROTO_FLAG_DRM_LOCKED;
 	wiiproto_req_drm(dbg->wdata, (__u8) i);
+	if (i != WIIPROTO_REQ_NULL)
+		dbg->wdata->state.flags |= WIIPROTO_FLAG_DRM_LOCKED;
 	spin_unlock_irqrestore(&dbg->wdata->state.lock, flags);
 
 	return len;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-wiimote-ext.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote-ext.c
--- linux-libre-3.10-gnu/drivers/hid/hid-wiimote-ext.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote-ext.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,849 +0,0 @@
-/*
- * HID driver for Nintendo Wiimote extension devices
- * Copyright (c) 2011 David Herrmann
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/atomic.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include "hid-wiimote.h"
-
-struct wiimote_ext {
-	struct wiimote_data *wdata;
-	struct work_struct worker;
-	struct input_dev *input;
-	struct input_dev *mp_input;
-
-	atomic_t opened;
-	atomic_t mp_opened;
-	bool plugged;
-	bool mp_plugged;
-	bool motionp;
-	__u8 ext_type;
-	__u16 calib[4][3];
-};
-
-enum wiiext_type {
-	WIIEXT_NONE,		/* placeholder */
-	WIIEXT_CLASSIC,		/* Nintendo classic controller */
-	WIIEXT_NUNCHUCK,	/* Nintendo nunchuck controller */
-	WIIEXT_BALANCE_BOARD,	/* Nintendo balance board controller */
-};
-
-enum wiiext_keys {
-	WIIEXT_KEY_C,
-	WIIEXT_KEY_Z,
-	WIIEXT_KEY_A,
-	WIIEXT_KEY_B,
-	WIIEXT_KEY_X,
-	WIIEXT_KEY_Y,
-	WIIEXT_KEY_ZL,
-	WIIEXT_KEY_ZR,
-	WIIEXT_KEY_PLUS,
-	WIIEXT_KEY_MINUS,
-	WIIEXT_KEY_HOME,
-	WIIEXT_KEY_LEFT,
-	WIIEXT_KEY_RIGHT,
-	WIIEXT_KEY_UP,
-	WIIEXT_KEY_DOWN,
-	WIIEXT_KEY_LT,
-	WIIEXT_KEY_RT,
-	WIIEXT_KEY_COUNT
-};
-
-static __u16 wiiext_keymap[] = {
-	BTN_C,		/* WIIEXT_KEY_C */
-	BTN_Z,		/* WIIEXT_KEY_Z */
-	BTN_A,		/* WIIEXT_KEY_A */
-	BTN_B,		/* WIIEXT_KEY_B */
-	BTN_X,		/* WIIEXT_KEY_X */
-	BTN_Y,		/* WIIEXT_KEY_Y */
-	BTN_TL2,	/* WIIEXT_KEY_ZL */
-	BTN_TR2,	/* WIIEXT_KEY_ZR */
-	KEY_NEXT,	/* WIIEXT_KEY_PLUS */
-	KEY_PREVIOUS,	/* WIIEXT_KEY_MINUS */
-	BTN_MODE,	/* WIIEXT_KEY_HOME */
-	KEY_LEFT,	/* WIIEXT_KEY_LEFT */
-	KEY_RIGHT,	/* WIIEXT_KEY_RIGHT */
-	KEY_UP,		/* WIIEXT_KEY_UP */
-	KEY_DOWN,	/* WIIEXT_KEY_DOWN */
-	BTN_TL,		/* WIIEXT_KEY_LT */
-	BTN_TR,		/* WIIEXT_KEY_RT */
-};
-
-/* disable all extensions */
-static void ext_disable(struct wiimote_ext *ext)
-{
-	unsigned long flags;
-	__u8 wmem = 0x55;
-
-	if (!wiimote_cmd_acquire(ext->wdata)) {
-		wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem));
-		wiimote_cmd_release(ext->wdata);
-	}
-
-	spin_lock_irqsave(&ext->wdata->state.lock, flags);
-	ext->motionp = false;
-	ext->ext_type = WIIEXT_NONE;
-	wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL);
-	spin_unlock_irqrestore(&ext->wdata->state.lock, flags);
-}
-
-static bool motionp_read(struct wiimote_ext *ext)
-{
-	__u8 rmem[2], wmem;
-	ssize_t ret;
-	bool avail = false;
-
-	if (!atomic_read(&ext->mp_opened))
-		return false;
-
-	if (wiimote_cmd_acquire(ext->wdata))
-		return false;
-
-	/* initialize motion plus */
-	wmem = 0x55;
-	ret = wiimote_cmd_write(ext->wdata, 0xa600f0, &wmem, sizeof(wmem));
-	if (ret)
-		goto error;
-
-	/* read motion plus ID */
-	ret = wiimote_cmd_read(ext->wdata, 0xa600fe, rmem, 2);
-	if (ret == 2 || rmem[1] == 0x5)
-		avail = true;
-
-error:
-	wiimote_cmd_release(ext->wdata);
-	return avail;
-}
-
-static __u8 ext_read(struct wiimote_ext *ext)
-{
-	ssize_t ret;
-	__u8 buf[24], i, j, offs = 0;
-	__u8 rmem[2], wmem;
-	__u8 type = WIIEXT_NONE;
-
-	if (!ext->plugged || !atomic_read(&ext->opened))
-		return WIIEXT_NONE;
-
-	if (wiimote_cmd_acquire(ext->wdata))
-		return WIIEXT_NONE;
-
-	/* initialize extension */
-	wmem = 0x55;
-	ret = wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem));
-	if (!ret) {
-		/* disable encryption */
-		wmem = 0x0;
-		wiimote_cmd_write(ext->wdata, 0xa400fb, &wmem, sizeof(wmem));
-	}
-
-	/* read extension ID */
-	ret = wiimote_cmd_read(ext->wdata, 0xa400fe, rmem, 2);
-	if (ret == 2) {
-		if (rmem[0] == 0 && rmem[1] == 0)
-			type = WIIEXT_NUNCHUCK;
-		else if (rmem[0] == 0x01 && rmem[1] == 0x01)
-			type = WIIEXT_CLASSIC;
-		else if (rmem[0] == 0x04 && rmem[1] == 0x02)
-			type = WIIEXT_BALANCE_BOARD;
-	}
-
-	/* get balance board calibration data */
-	if (type == WIIEXT_BALANCE_BOARD) {
-		ret = wiimote_cmd_read(ext->wdata, 0xa40024, buf, 12);
-		ret += wiimote_cmd_read(ext->wdata, 0xa40024 + 12,
-					buf + 12, 12);
-
-		if (ret != 24) {
-			type = WIIEXT_NONE;
-		} else {
-			for (i = 0; i < 3; i++) {
-				for (j = 0; j < 4; j++) {
-					ext->calib[j][i] = buf[offs];
-					ext->calib[j][i] <<= 8;
-					ext->calib[j][i] |= buf[offs + 1];
-					offs += 2;
-				}
-			}
-		}
-	}
-
-	wiimote_cmd_release(ext->wdata);
-
-	return type;
-}
-
-static void ext_enable(struct wiimote_ext *ext, bool motionp, __u8 ext_type)
-{
-	unsigned long flags;
-	__u8 wmem;
-	int ret;
-
-	if (motionp) {
-		if (wiimote_cmd_acquire(ext->wdata))
-			return;
-
-		if (ext_type == WIIEXT_CLASSIC)
-			wmem = 0x07;
-		else if (ext_type == WIIEXT_NUNCHUCK)
-			wmem = 0x05;
-		else
-			wmem = 0x04;
-
-		ret = wiimote_cmd_write(ext->wdata, 0xa600fe, &wmem, sizeof(wmem));
-		wiimote_cmd_release(ext->wdata);
-		if (ret)
-			return;
-	}
-
-	spin_lock_irqsave(&ext->wdata->state.lock, flags);
-	ext->motionp = motionp;
-	ext->ext_type = ext_type;
-	wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL);
-	spin_unlock_irqrestore(&ext->wdata->state.lock, flags);
-}
-
-static void wiiext_worker(struct work_struct *work)
-{
-	struct wiimote_ext *ext = container_of(work, struct wiimote_ext,
-									worker);
-	bool motionp;
-	__u8 ext_type;
-
-	ext_disable(ext);
-	motionp = motionp_read(ext);
-	ext_type = ext_read(ext);
-	ext_enable(ext, motionp, ext_type);
-}
-
-/* schedule work only once, otherwise mark for reschedule */
-static void wiiext_schedule(struct wiimote_ext *ext)
-{
-	schedule_work(&ext->worker);
-}
-
-/*
- * Reacts on extension port events
- * Whenever the driver gets an event from the wiimote that an extension has been
- * plugged or unplugged, this funtion shall be called. It checks what extensions
- * are connected and initializes and activates them.
- * This can be called in atomic context. The initialization is done in a
- * separate worker thread. The state.lock spinlock must be held by the caller.
- */
-void wiiext_event(struct wiimote_data *wdata, bool plugged)
-{
-	if (!wdata->ext)
-		return;
-
-	if (wdata->ext->plugged == plugged)
-		return;
-
-	wdata->ext->plugged = plugged;
-
-	if (!plugged)
-		wdata->ext->mp_plugged = false;
-
-	/*
-	 * We need to call wiiext_schedule(wdata->ext) here, however, the
-	 * extension initialization logic is not fully understood and so
-	 * automatic initialization is not supported, yet.
-	 */
-}
-
-/*
- * Returns true if the current DRM mode should contain extension data and false
- * if there is no interest in extension data.
- * All supported extensions send 6 byte extension data so any DRM that contains
- * extension bytes is fine.
- * The caller must hold the state.lock spinlock.
- */
-bool wiiext_active(struct wiimote_data *wdata)
-{
-	if (!wdata->ext)
-		return false;
-
-	return wdata->ext->motionp || wdata->ext->ext_type;
-}
-
-static void handler_motionp(struct wiimote_ext *ext, const __u8 *payload)
-{
-	__s32 x, y, z;
-	bool plugged;
-
-	/*        |   8    7    6    5    4    3 |  2  |  1  |
-	 *   -----+------------------------------+-----+-----+
-	 *    1   |               Yaw Speed <7:0>            |
-	 *    2   |              Roll Speed <7:0>            |
-	 *    3   |             Pitch Speed <7:0>            |
-	 *   -----+------------------------------+-----+-----+
-	 *    4   |       Yaw Speed <13:8>       | Yaw |Pitch|
-	 *   -----+------------------------------+-----+-----+
-	 *    5   |      Roll Speed <13:8>       |Roll | Ext |
-	 *   -----+------------------------------+-----+-----+
-	 *    6   |     Pitch Speed <13:8>       |  1  |  0  |
-	 *   -----+------------------------------+-----+-----+
-	 * The single bits Yaw, Roll, Pitch in the lower right corner specify
-	 * whether the wiimote is rotating fast (0) or slow (1). Speed for slow
-	 * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a
-	 * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast
-	 * and 9 for slow.
-	 * If the wiimote is not rotating the sensor reports 2^13 = 8192.
-	 * Ext specifies whether an extension is connected to the motionp.
-	 */
-
-	x = payload[0];
-	y = payload[1];
-	z = payload[2];
-
-	x |= (((__u16)payload[3]) << 6) & 0xff00;
-	y |= (((__u16)payload[4]) << 6) & 0xff00;
-	z |= (((__u16)payload[5]) << 6) & 0xff00;
-
-	x -= 8192;
-	y -= 8192;
-	z -= 8192;
-
-	if (!(payload[3] & 0x02))
-		x *= 18;
-	else
-		x *= 9;
-	if (!(payload[4] & 0x02))
-		y *= 18;
-	else
-		y *= 9;
-	if (!(payload[3] & 0x01))
-		z *= 18;
-	else
-		z *= 9;
-
-	input_report_abs(ext->mp_input, ABS_RX, x);
-	input_report_abs(ext->mp_input, ABS_RY, y);
-	input_report_abs(ext->mp_input, ABS_RZ, z);
-	input_sync(ext->mp_input);
-
-	plugged = payload[5] & 0x01;
-	if (plugged != ext->mp_plugged)
-		ext->mp_plugged = plugged;
-}
-
-static void handler_nunchuck(struct wiimote_ext *ext, const __u8 *payload)
-{
-	__s16 x, y, z, bx, by;
-
-	/*   Byte |   8    7 |  6    5 |  4    3 |  2 |  1  |
-	 *   -----+----------+---------+---------+----+-----+
-	 *    1   |              Button X <7:0>             |
-	 *    2   |              Button Y <7:0>             |
-	 *   -----+----------+---------+---------+----+-----+
-	 *    3   |               Speed X <9:2>             |
-	 *    4   |               Speed Y <9:2>             |
-	 *    5   |               Speed Z <9:2>             |
-	 *   -----+----------+---------+---------+----+-----+
-	 *    6   | Z <1:0>  | Y <1:0> | X <1:0> | BC | BZ  |
-	 *   -----+----------+---------+---------+----+-----+
-	 * Button X/Y is the analog stick. Speed X, Y and Z are the
-	 * accelerometer data in the same format as the wiimote's accelerometer.
-	 * The 6th byte contains the LSBs of the accelerometer data.
-	 * BC and BZ are the C and Z buttons: 0 means pressed
-	 *
-	 * If reported interleaved with motionp, then the layout changes. The
-	 * 5th and 6th byte changes to:
-	 *   -----+-----------------------------------+-----+
-	 *    5   |            Speed Z <9:3>          | EXT |
-	 *   -----+--------+-----+-----+----+----+----+-----+
-	 *    6   |Z <2:1> |Y <1>|X <1>| BC | BZ | 0  |  0  |
-	 *   -----+--------+-----+-----+----+----+----+-----+
-	 * All three accelerometer values lose their LSB. The other data is
-	 * still available but slightly moved.
-	 *
-	 * Center data for button values is 128. Center value for accelerometer
-	 * values it 512 / 0x200
-	 */
-
-	bx = payload[0];
-	by = payload[1];
-	bx -= 128;
-	by -= 128;
-
-	x = payload[2] << 2;
-	y = payload[3] << 2;
-	z = payload[4] << 2;
-
-	if (ext->motionp) {
-		x |= (payload[5] >> 3) & 0x02;
-		y |= (payload[5] >> 4) & 0x02;
-		z &= ~0x4;
-		z |= (payload[5] >> 5) & 0x06;
-	} else {
-		x |= (payload[5] >> 2) & 0x03;
-		y |= (payload[5] >> 4) & 0x03;
-		z |= (payload[5] >> 6) & 0x03;
-	}
-
-	x -= 0x200;
-	y -= 0x200;
-	z -= 0x200;
-
-	input_report_abs(ext->input, ABS_HAT0X, bx);
-	input_report_abs(ext->input, ABS_HAT0Y, by);
-
-	input_report_abs(ext->input, ABS_RX, x);
-	input_report_abs(ext->input, ABS_RY, y);
-	input_report_abs(ext->input, ABS_RZ, z);
-
-	if (ext->motionp) {
-		input_report_key(ext->input,
-			wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x04));
-		input_report_key(ext->input,
-			wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x08));
-	} else {
-		input_report_key(ext->input,
-			wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x01));
-		input_report_key(ext->input,
-			wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x02));
-	}
-
-	input_sync(ext->input);
-}
-
-static void handler_classic(struct wiimote_ext *ext, const __u8 *payload)
-{
-	__s8 rx, ry, lx, ly, lt, rt;
-
-	/*   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
-	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
-	 *    1   | RX <5:4>  |              LX <5:0>             |
-	 *    2   | RX <3:2>  |              LY <5:0>             |
-	 *   -----+-----+-----+-----+-----------------------------+
-	 *    3   |RX<1>| LT <5:4>  |         RY <5:1>            |
-	 *   -----+-----+-----------+-----------------------------+
-	 *    4   |     LT <3:1>    |         RT <5:1>            |
-	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
-	 *    5   | BDR | BDD | BLT | B-  | BH  | B+  | BRT |  1  |
-	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
-	 *    6   | BZL | BB  | BY  | BA  | BX  | BZR | BDL | BDU |
-	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
-	 * All buttons are 0 if pressed
-	 * RX and RY are right analog stick
-	 * LX and LY are left analog stick
-	 * LT is left trigger, RT is right trigger
-	 * BLT is 0 if left trigger is fully pressed
-	 * BRT is 0 if right trigger is fully pressed
-	 * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons
-	 * BZL is left Z button and BZR is right Z button
-	 * B-, BH, B+ are +, HOME and - buttons
-	 * BB, BY, BA, BX are A, B, X, Y buttons
-	 * LSB of RX, RY, LT, and RT are not transmitted and always 0.
-	 *
-	 * With motionp enabled it changes slightly to this:
-	 *   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
-	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
-	 *    1   | RX <4:3>  |          LX <5:1>           | BDU |
-	 *    2   | RX <2:1>  |          LY <5:1>           | BDL |
-	 *   -----+-----+-----+-----+-----------------------+-----+
-	 *    3   |RX<0>| LT <4:3>  |         RY <4:0>            |
-	 *   -----+-----+-----------+-----------------------------+
-	 *    4   |     LT <2:0>    |         RT <4:0>            |
-	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
-	 *    5   | BDR | BDD | BLT | B-  | BH  | B+  | BRT | EXT |
-	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
-	 *    6   | BZL | BB  | BY  | BA  | BX  | BZR |  0  |  0  |
-	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
-	 * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest
-	 * is the same as before.
-	 */
-
-	if (ext->motionp) {
-		lx = payload[0] & 0x3e;
-		ly = payload[0] & 0x3e;
-	} else {
-		lx = payload[0] & 0x3f;
-		ly = payload[0] & 0x3f;
-	}
-
-	rx = (payload[0] >> 3) & 0x14;
-	rx |= (payload[1] >> 5) & 0x06;
-	rx |= (payload[2] >> 7) & 0x01;
-	ry = payload[2] & 0x1f;
-
-	rt = payload[3] & 0x1f;
-	lt = (payload[2] >> 2) & 0x18;
-	lt |= (payload[3] >> 5) & 0x07;
-
-	rx <<= 1;
-	ry <<= 1;
-	rt <<= 1;
-	lt <<= 1;
-
-	input_report_abs(ext->input, ABS_HAT1X, lx - 0x20);
-	input_report_abs(ext->input, ABS_HAT1Y, ly - 0x20);
-	input_report_abs(ext->input, ABS_HAT2X, rx - 0x20);
-	input_report_abs(ext->input, ABS_HAT2Y, ry - 0x20);
-	input_report_abs(ext->input, ABS_HAT3X, rt - 0x20);
-	input_report_abs(ext->input, ABS_HAT3Y, lt - 0x20);
-
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_RIGHT],
-							!!(payload[4] & 0x80));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_DOWN],
-							!!(payload[4] & 0x40));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LT],
-							!!(payload[4] & 0x20));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_MINUS],
-							!!(payload[4] & 0x10));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_HOME],
-							!!(payload[4] & 0x08));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_PLUS],
-							!!(payload[4] & 0x04));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_RT],
-							!!(payload[4] & 0x02));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_ZL],
-							!!(payload[5] & 0x80));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_B],
-							!!(payload[5] & 0x40));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_Y],
-							!!(payload[5] & 0x20));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_A],
-							!!(payload[5] & 0x10));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_X],
-							!!(payload[5] & 0x08));
-	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_ZR],
-							!!(payload[5] & 0x04));
-
-	if (ext->motionp) {
-		input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_UP],
-							!!(payload[0] & 0x01));
-		input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LEFT],
-							!!(payload[1] & 0x01));
-	} else {
-		input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_UP],
-							!!(payload[5] & 0x01));
-		input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LEFT],
-							!!(payload[5] & 0x02));
-	}
-
-	input_sync(ext->input);
-}
-
-static void handler_balance_board(struct wiimote_ext *ext, const __u8 *payload)
-{
-	__s32 val[4], tmp;
-	unsigned int i;
-
-	/*   Byte |  8  7  6  5  4  3  2  1  |
-	 *   -----+--------------------------+
-	 *    1   |    Top Right <15:8>      |
-	 *    2   |    Top Right  <7:0>      |
-	 *   -----+--------------------------+
-	 *    3   | Bottom Right <15:8>      |
-	 *    4   | Bottom Right  <7:0>      |
-	 *   -----+--------------------------+
-	 *    5   |     Top Left <15:8>      |
-	 *    6   |     Top Left  <7:0>      |
-	 *   -----+--------------------------+
-	 *    7   |  Bottom Left <15:8>      |
-	 *    8   |  Bottom Left  <7:0>      |
-	 *   -----+--------------------------+
-	 *
-	 * These values represent the weight-measurements of the Wii-balance
-	 * board with 16bit precision.
-	 *
-	 * The balance-board is never reported interleaved with motionp.
-	 */
-
-	val[0] = payload[0];
-	val[0] <<= 8;
-	val[0] |= payload[1];
-
-	val[1] = payload[2];
-	val[1] <<= 8;
-	val[1] |= payload[3];
-
-	val[2] = payload[4];
-	val[2] <<= 8;
-	val[2] |= payload[5];
-
-	val[3] = payload[6];
-	val[3] <<= 8;
-	val[3] |= payload[7];
-
-	/* apply calibration data */
-	for (i = 0; i < 4; i++) {
-		if (val[i] < ext->calib[i][1]) {
-			tmp = val[i] - ext->calib[i][0];
-			tmp *= 1700;
-			tmp /= ext->calib[i][1] - ext->calib[i][0];
-		} else {
-			tmp = val[i] - ext->calib[i][1];
-			tmp *= 1700;
-			tmp /= ext->calib[i][2] - ext->calib[i][1];
-			tmp += 1700;
-		}
-		val[i] = tmp;
-	}
-
-	input_report_abs(ext->input, ABS_HAT0X, val[0]);
-	input_report_abs(ext->input, ABS_HAT0Y, val[1]);
-	input_report_abs(ext->input, ABS_HAT1X, val[2]);
-	input_report_abs(ext->input, ABS_HAT1Y, val[3]);
-
-	input_sync(ext->input);
-}
-
-/* call this with state.lock spinlock held */
-void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload)
-{
-	struct wiimote_ext *ext = wdata->ext;
-
-	if (!ext)
-		return;
-
-	if (ext->motionp && (payload[5] & 0x02)) {
-		handler_motionp(ext, payload);
-	} else if (ext->ext_type == WIIEXT_NUNCHUCK) {
-		handler_nunchuck(ext, payload);
-	} else if (ext->ext_type == WIIEXT_CLASSIC) {
-		handler_classic(ext, payload);
-	} else if (ext->ext_type == WIIEXT_BALANCE_BOARD) {
-		handler_balance_board(ext, payload);
-	}
-}
-
-static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr,
-								char *buf)
-{
-	struct wiimote_data *wdata = dev_to_wii(dev);
-	__u8 type = WIIEXT_NONE;
-	bool motionp = false;
-	unsigned long flags;
-
-	spin_lock_irqsave(&wdata->state.lock, flags);
-	if (wdata->ext) {
-		motionp = wdata->ext->motionp;
-		type = wdata->ext->ext_type;
-	}
-	spin_unlock_irqrestore(&wdata->state.lock, flags);
-
-	if (type == WIIEXT_NUNCHUCK) {
-		if (motionp)
-			return sprintf(buf, "motionp+nunchuck\n");
-		else
-			return sprintf(buf, "nunchuck\n");
-	} else if (type == WIIEXT_CLASSIC) {
-		if (motionp)
-			return sprintf(buf, "motionp+classic\n");
-		else
-			return sprintf(buf, "classic\n");
-	} else if (type == WIIEXT_BALANCE_BOARD) {
-		if (motionp)
-			return sprintf(buf, "motionp+balanceboard\n");
-		else
-			return sprintf(buf, "balanceboard\n");
-	} else {
-		if (motionp)
-			return sprintf(buf, "motionp\n");
-		else
-			return sprintf(buf, "none\n");
-	}
-}
-
-static DEVICE_ATTR(extension, S_IRUGO, wiiext_show, NULL);
-
-static int wiiext_input_open(struct input_dev *dev)
-{
-	struct wiimote_ext *ext = input_get_drvdata(dev);
-	int ret;
-
-	ret = hid_hw_open(ext->wdata->hdev);
-	if (ret)
-		return ret;
-
-	atomic_inc(&ext->opened);
-	wiiext_schedule(ext);
-
-	return 0;
-}
-
-static void wiiext_input_close(struct input_dev *dev)
-{
-	struct wiimote_ext *ext = input_get_drvdata(dev);
-
-	atomic_dec(&ext->opened);
-	wiiext_schedule(ext);
-	hid_hw_close(ext->wdata->hdev);
-}
-
-static int wiiext_mp_open(struct input_dev *dev)
-{
-	struct wiimote_ext *ext = input_get_drvdata(dev);
-	int ret;
-
-	ret = hid_hw_open(ext->wdata->hdev);
-	if (ret)
-		return ret;
-
-	atomic_inc(&ext->mp_opened);
-	wiiext_schedule(ext);
-
-	return 0;
-}
-
-static void wiiext_mp_close(struct input_dev *dev)
-{
-	struct wiimote_ext *ext = input_get_drvdata(dev);
-
-	atomic_dec(&ext->mp_opened);
-	wiiext_schedule(ext);
-	hid_hw_close(ext->wdata->hdev);
-}
-
-/* Initializes the extension driver of a wiimote */
-int wiiext_init(struct wiimote_data *wdata)
-{
-	struct wiimote_ext *ext;
-	unsigned long flags;
-	int ret, i;
-
-	ext = kzalloc(sizeof(*ext), GFP_KERNEL);
-	if (!ext)
-		return -ENOMEM;
-
-	ext->wdata = wdata;
-	INIT_WORK(&ext->worker, wiiext_worker);
-
-	ext->input = input_allocate_device();
-	if (!ext->input) {
-		ret = -ENOMEM;
-		goto err_input;
-	}
-
-	input_set_drvdata(ext->input, ext);
-	ext->input->open = wiiext_input_open;
-	ext->input->close = wiiext_input_close;
-	ext->input->dev.parent = &wdata->hdev->dev;
-	ext->input->id.bustype = wdata->hdev->bus;
-	ext->input->id.vendor = wdata->hdev->vendor;
-	ext->input->id.product = wdata->hdev->product;
-	ext->input->id.version = wdata->hdev->version;
-	ext->input->name = WIIMOTE_NAME " Extension";
-
-	set_bit(EV_KEY, ext->input->evbit);
-	for (i = 0; i < WIIEXT_KEY_COUNT; ++i)
-		set_bit(wiiext_keymap[i], ext->input->keybit);
-
-	set_bit(EV_ABS, ext->input->evbit);
-	set_bit(ABS_HAT0X, ext->input->absbit);
-	set_bit(ABS_HAT0Y, ext->input->absbit);
-	set_bit(ABS_HAT1X, ext->input->absbit);
-	set_bit(ABS_HAT1Y, ext->input->absbit);
-	set_bit(ABS_HAT2X, ext->input->absbit);
-	set_bit(ABS_HAT2Y, ext->input->absbit);
-	set_bit(ABS_HAT3X, ext->input->absbit);
-	set_bit(ABS_HAT3Y, ext->input->absbit);
-	input_set_abs_params(ext->input, ABS_HAT0X, -120, 120, 2, 4);
-	input_set_abs_params(ext->input, ABS_HAT0Y, -120, 120, 2, 4);
-	input_set_abs_params(ext->input, ABS_HAT1X, -30, 30, 1, 1);
-	input_set_abs_params(ext->input, ABS_HAT1Y, -30, 30, 1, 1);
-	input_set_abs_params(ext->input, ABS_HAT2X, -30, 30, 1, 1);
-	input_set_abs_params(ext->input, ABS_HAT2Y, -30, 30, 1, 1);
-	input_set_abs_params(ext->input, ABS_HAT3X, -30, 30, 1, 1);
-	input_set_abs_params(ext->input, ABS_HAT3Y, -30, 30, 1, 1);
-	set_bit(ABS_RX, ext->input->absbit);
-	set_bit(ABS_RY, ext->input->absbit);
-	set_bit(ABS_RZ, ext->input->absbit);
-	input_set_abs_params(ext->input, ABS_RX, -500, 500, 2, 4);
-	input_set_abs_params(ext->input, ABS_RY, -500, 500, 2, 4);
-	input_set_abs_params(ext->input, ABS_RZ, -500, 500, 2, 4);
-
-	ret = input_register_device(ext->input);
-	if (ret) {
-		input_free_device(ext->input);
-		goto err_input;
-	}
-
-	ext->mp_input = input_allocate_device();
-	if (!ext->mp_input) {
-		ret = -ENOMEM;
-		goto err_mp;
-	}
-
-	input_set_drvdata(ext->mp_input, ext);
-	ext->mp_input->open = wiiext_mp_open;
-	ext->mp_input->close = wiiext_mp_close;
-	ext->mp_input->dev.parent = &wdata->hdev->dev;
-	ext->mp_input->id.bustype = wdata->hdev->bus;
-	ext->mp_input->id.vendor = wdata->hdev->vendor;
-	ext->mp_input->id.product = wdata->hdev->product;
-	ext->mp_input->id.version = wdata->hdev->version;
-	ext->mp_input->name = WIIMOTE_NAME " Motion+";
-
-	set_bit(EV_ABS, ext->mp_input->evbit);
-	set_bit(ABS_RX, ext->mp_input->absbit);
-	set_bit(ABS_RY, ext->mp_input->absbit);
-	set_bit(ABS_RZ, ext->mp_input->absbit);
-	input_set_abs_params(ext->mp_input, ABS_RX, -160000, 160000, 4, 8);
-	input_set_abs_params(ext->mp_input, ABS_RY, -160000, 160000, 4, 8);
-	input_set_abs_params(ext->mp_input, ABS_RZ, -160000, 160000, 4, 8);
-
-	ret = input_register_device(ext->mp_input);
-	if (ret) {
-		input_free_device(ext->mp_input);
-		goto err_mp;
-	}
-
-	ret = device_create_file(&wdata->hdev->dev, &dev_attr_extension);
-	if (ret)
-		goto err_dev;
-
-	spin_lock_irqsave(&wdata->state.lock, flags);
-	wdata->ext = ext;
-	spin_unlock_irqrestore(&wdata->state.lock, flags);
-
-	return 0;
-
-err_dev:
-	input_unregister_device(ext->mp_input);
-err_mp:
-	input_unregister_device(ext->input);
-err_input:
-	kfree(ext);
-	return ret;
-}
-
-/* Deinitializes the extension driver of a wiimote */
-void wiiext_deinit(struct wiimote_data *wdata)
-{
-	struct wiimote_ext *ext = wdata->ext;
-	unsigned long flags;
-
-	if (!ext)
-		return;
-
-	/*
-	 * We first unset wdata->ext to avoid further input from the wiimote
-	 * core. The worker thread does not access this pointer so it is not
-	 * affected by this.
-	 * We kill the worker after this so it does not get respawned during
-	 * deinitialization.
-	 */
-
-	spin_lock_irqsave(&wdata->state.lock, flags);
-	wdata->ext = NULL;
-	spin_unlock_irqrestore(&wdata->state.lock, flags);
-
-	device_remove_file(&wdata->hdev->dev, &dev_attr_extension);
-	input_unregister_device(ext->mp_input);
-	input_unregister_device(ext->input);
-
-	cancel_work_sync(&ext->worker);
-	kfree(ext);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-wiimote.h linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote.h
--- linux-libre-3.10-gnu/drivers/hid/hid-wiimote.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote.h	2013-08-25 20:43:22.000000000 -0400
@@ -2,8 +2,8 @@
 #define __HID_WIIMOTE_H
 
 /*
- * HID driver for Nintendo Wiimote devices
- * Copyright (c) 2011 David Herrmann
+ * HID driver for Nintendo Wii / Wii U peripherals
+ * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com>
  */
 
 /*
@@ -22,6 +22,7 @@
 #include <linux/mutex.h>
 #include <linux/power_supply.h>
 #include <linux/spinlock.h>
+#include <linux/timer.h>
 
 #define WIIMOTE_NAME "Nintendo Wii Remote"
 #define WIIMOTE_BUFSIZE 32
@@ -35,6 +36,17 @@
 #define WIIPROTO_FLAG_IR_BASIC		0x40
 #define WIIPROTO_FLAG_IR_EXT		0x80
 #define WIIPROTO_FLAG_IR_FULL		0xc0 /* IR_BASIC | IR_EXT */
+#define WIIPROTO_FLAG_EXT_PLUGGED	0x0100
+#define WIIPROTO_FLAG_EXT_USED		0x0200
+#define WIIPROTO_FLAG_EXT_ACTIVE	0x0400
+#define WIIPROTO_FLAG_MP_PLUGGED	0x0800
+#define WIIPROTO_FLAG_MP_USED		0x1000
+#define WIIPROTO_FLAG_MP_ACTIVE		0x2000
+#define WIIPROTO_FLAG_EXITING		0x4000
+#define WIIPROTO_FLAG_DRM_LOCKED	0x8000
+#define WIIPROTO_FLAG_BUILTIN_MP	0x010000
+#define WIIPROTO_FLAG_NO_MP		0x020000
+
 #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
 					WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
 #define WIIPROTO_FLAGS_IR (WIIPROTO_FLAG_IR_BASIC | WIIPROTO_FLAG_IR_EXT | \
@@ -43,16 +55,71 @@
 /* return flag for led \num */
 #define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
 
+enum wiiproto_keys {
+	WIIPROTO_KEY_LEFT,
+	WIIPROTO_KEY_RIGHT,
+	WIIPROTO_KEY_UP,
+	WIIPROTO_KEY_DOWN,
+	WIIPROTO_KEY_PLUS,
+	WIIPROTO_KEY_MINUS,
+	WIIPROTO_KEY_ONE,
+	WIIPROTO_KEY_TWO,
+	WIIPROTO_KEY_A,
+	WIIPROTO_KEY_B,
+	WIIPROTO_KEY_HOME,
+	WIIPROTO_KEY_COUNT
+};
+
+enum wiimote_devtype {
+	WIIMOTE_DEV_PENDING,
+	WIIMOTE_DEV_UNKNOWN,
+	WIIMOTE_DEV_GENERIC,
+	WIIMOTE_DEV_GEN10,
+	WIIMOTE_DEV_GEN20,
+	WIIMOTE_DEV_BALANCE_BOARD,
+	WIIMOTE_DEV_PRO_CONTROLLER,
+	WIIMOTE_DEV_NUM,
+};
+
+enum wiimote_exttype {
+	WIIMOTE_EXT_NONE,
+	WIIMOTE_EXT_UNKNOWN,
+	WIIMOTE_EXT_NUNCHUK,
+	WIIMOTE_EXT_CLASSIC_CONTROLLER,
+	WIIMOTE_EXT_BALANCE_BOARD,
+	WIIMOTE_EXT_PRO_CONTROLLER,
+	WIIMOTE_EXT_NUM,
+};
+
+enum wiimote_mptype {
+	WIIMOTE_MP_NONE,
+	WIIMOTE_MP_UNKNOWN,
+	WIIMOTE_MP_SINGLE,
+	WIIMOTE_MP_PASSTHROUGH_NUNCHUK,
+	WIIMOTE_MP_PASSTHROUGH_CLASSIC,
+};
+
 struct wiimote_buf {
 	__u8 data[HID_MAX_BUFFER_SIZE];
 	size_t size;
 };
 
+struct wiimote_queue {
+	spinlock_t lock;
+	struct work_struct worker;
+	__u8 head;
+	__u8 tail;
+	struct wiimote_buf outq[WIIMOTE_BUFSIZE];
+};
+
 struct wiimote_state {
 	spinlock_t lock;
-	__u8 flags;
+	__u32 flags;
 	__u8 accel_split[2];
 	__u8 drm;
+	__u8 devtype;
+	__u8 exttype;
+	__u8 mp;
 
 	/* synchronous cmd requests */
 	struct mutex sync;
@@ -65,6 +132,9 @@ struct wiimote_state {
 	__u8 cmd_err;
 	__u8 *cmd_read_buf;
 	__u8 cmd_read_size;
+
+	/* calibration data */
+	__u16 calib_bboard[4][3];
 };
 
 struct wiimote_data {
@@ -74,18 +144,63 @@ struct wiimote_data {
 	struct input_dev *accel;
 	struct input_dev *ir;
 	struct power_supply battery;
-	struct wiimote_ext *ext;
+	struct input_dev *mp;
+	struct timer_list timer;
 	struct wiimote_debug *debug;
 
-	spinlock_t qlock;
-	__u8 head;
-	__u8 tail;
-	struct wiimote_buf outq[WIIMOTE_BUFSIZE];
-	struct work_struct worker;
+	union {
+		struct input_dev *input;
+	} extension;
 
+	struct wiimote_queue queue;
 	struct wiimote_state state;
+	struct work_struct init_worker;
 };
 
+/* wiimote modules */
+
+enum wiimod_module {
+	WIIMOD_KEYS,
+	WIIMOD_RUMBLE,
+	WIIMOD_BATTERY,
+	WIIMOD_LED1,
+	WIIMOD_LED2,
+	WIIMOD_LED3,
+	WIIMOD_LED4,
+	WIIMOD_ACCEL,
+	WIIMOD_IR,
+	WIIMOD_BUILTIN_MP,
+	WIIMOD_NO_MP,
+	WIIMOD_NUM,
+	WIIMOD_NULL = WIIMOD_NUM,
+};
+
+#define WIIMOD_FLAG_INPUT		0x0001
+#define WIIMOD_FLAG_EXT8		0x0002
+#define WIIMOD_FLAG_EXT16		0x0004
+
+struct wiimod_ops {
+	__u16 flags;
+	unsigned long arg;
+	int (*probe) (const struct wiimod_ops *ops,
+		      struct wiimote_data *wdata);
+	void (*remove) (const struct wiimod_ops *ops,
+			struct wiimote_data *wdata);
+
+	void (*in_keys) (struct wiimote_data *wdata, const __u8 *keys);
+	void (*in_accel) (struct wiimote_data *wdata, const __u8 *accel);
+	void (*in_ir) (struct wiimote_data *wdata, const __u8 *ir, bool packed,
+		       unsigned int id);
+	void (*in_mp) (struct wiimote_data *wdata, const __u8 *mp);
+	void (*in_ext) (struct wiimote_data *wdata, const __u8 *ext);
+};
+
+extern const struct wiimod_ops *wiimod_table[WIIMOD_NUM];
+extern const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM];
+extern const struct wiimod_ops wiimod_mp;
+
+/* wiimote requests */
+
 enum wiiproto_reqs {
 	WIIPROTO_REQ_NULL = 0x0,
 	WIIPROTO_REQ_RUMBLE = 0x10,
@@ -99,24 +214,55 @@ enum wiiproto_reqs {
 	WIIPROTO_REQ_STATUS = 0x20,
 	WIIPROTO_REQ_DATA = 0x21,
 	WIIPROTO_REQ_RETURN = 0x22,
+
+	/* DRM_K: BB*2 */
 	WIIPROTO_REQ_DRM_K = 0x30,
+
+	/* DRM_KA: BB*2 AA*3 */
 	WIIPROTO_REQ_DRM_KA = 0x31,
+
+	/* DRM_KE: BB*2 EE*8 */
 	WIIPROTO_REQ_DRM_KE = 0x32,
+
+	/* DRM_KAI: BB*2 AA*3 II*12 */
 	WIIPROTO_REQ_DRM_KAI = 0x33,
+
+	/* DRM_KEE: BB*2 EE*19 */
 	WIIPROTO_REQ_DRM_KEE = 0x34,
+
+	/* DRM_KAE: BB*2 AA*3 EE*16 */
 	WIIPROTO_REQ_DRM_KAE = 0x35,
+
+	/* DRM_KIE: BB*2 II*10 EE*9 */
 	WIIPROTO_REQ_DRM_KIE = 0x36,
+
+	/* DRM_KAIE: BB*2 AA*3 II*10 EE*6 */
 	WIIPROTO_REQ_DRM_KAIE = 0x37,
+
+	/* DRM_E: EE*21 */
 	WIIPROTO_REQ_DRM_E = 0x3d,
+
+	/* DRM_SKAI1: BB*2 AA*1 II*18 */
 	WIIPROTO_REQ_DRM_SKAI1 = 0x3e,
+
+	/* DRM_SKAI2: BB*2 AA*1 II*18 */
 	WIIPROTO_REQ_DRM_SKAI2 = 0x3f,
+
 	WIIPROTO_REQ_MAX
 };
 
 #define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \
 									dev))
 
+void __wiimote_schedule(struct wiimote_data *wdata);
+
 extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm);
+extern void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble);
+extern void wiiproto_req_leds(struct wiimote_data *wdata, int leds);
+extern void wiiproto_req_status(struct wiimote_data *wdata);
+extern void wiiproto_req_accel(struct wiimote_data *wdata, __u8 accel);
+extern void wiiproto_req_ir1(struct wiimote_data *wdata, __u8 flags);
+extern void wiiproto_req_ir2(struct wiimote_data *wdata, __u8 flags);
 extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
 						const __u8 *wmem, __u8 size);
 extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset,
@@ -129,24 +275,6 @@ extern ssize_t wiimote_cmd_read(struct w
 extern void wiiproto_req_rmem(struct wiimote_data *wdata, bool eeprom,
 						__u32 offset, __u16 size);
 
-#ifdef CONFIG_HID_WIIMOTE_EXT
-
-extern int wiiext_init(struct wiimote_data *wdata);
-extern void wiiext_deinit(struct wiimote_data *wdata);
-extern void wiiext_event(struct wiimote_data *wdata, bool plugged);
-extern bool wiiext_active(struct wiimote_data *wdata);
-extern void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload);
-
-#else
-
-static inline int wiiext_init(void *u) { return 0; }
-static inline void wiiext_deinit(void *u) { }
-static inline void wiiext_event(void *u, bool p) { }
-static inline bool wiiext_active(void *u) { return false; }
-static inline void wiiext_handle(void *u, const __u8 *p) { }
-
-#endif
-
 #ifdef CONFIG_DEBUG_FS
 
 extern int wiidebug_init(struct wiimote_data *wdata);
@@ -173,11 +301,26 @@ static inline void wiimote_cmd_complete(
 	complete(&wdata->state.ready);
 }
 
+/* requires the state.lock spinlock to be held */
+static inline void wiimote_cmd_abort(struct wiimote_data *wdata)
+{
+	/* Abort synchronous request by waking up the sleeping caller. But
+	 * reset the state.cmd field to an invalid value so no further event
+	 * handlers will work with it. */
+	wdata->state.cmd = WIIPROTO_REQ_MAX;
+	complete(&wdata->state.ready);
+}
+
 static inline int wiimote_cmd_acquire(struct wiimote_data *wdata)
 {
 	return mutex_lock_interruptible(&wdata->state.sync) ? -ERESTARTSYS : 0;
 }
 
+static inline void wiimote_cmd_acquire_noint(struct wiimote_data *wdata)
+{
+	mutex_lock(&wdata->state.sync);
+}
+
 /* requires the state.lock spinlock to be held */
 static inline void wiimote_cmd_set(struct wiimote_data *wdata, int cmd,
 								__u32 opt)
@@ -196,11 +339,31 @@ static inline int wiimote_cmd_wait(struc
 {
 	int ret;
 
+	/* The completion acts as implicit memory barrier so we can safely
+	 * assume that state.cmd is set on success/failure and isn't accessed
+	 * by any other thread, anymore. */
+
 	ret = wait_for_completion_interruptible_timeout(&wdata->state.ready, HZ);
 	if (ret < 0)
 		return -ERESTARTSYS;
 	else if (ret == 0)
 		return -EIO;
+	else if (wdata->state.cmd != WIIPROTO_REQ_NULL)
+		return -EIO;
+	else
+		return 0;
+}
+
+static inline int wiimote_cmd_wait_noint(struct wiimote_data *wdata)
+{
+	unsigned long ret;
+
+	/* no locking needed; see wiimote_cmd_wait() */
+	ret = wait_for_completion_timeout(&wdata->state.ready, HZ);
+	if (!ret)
+		return -EIO;
+	else if (wdata->state.cmd != WIIPROTO_REQ_NULL)
+		return -EIO;
 	else
 		return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/hid-wiimote-modules.c linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote-modules.c
--- linux-libre-3.10-gnu/drivers/hid/hid-wiimote-modules.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/hid/hid-wiimote-modules.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2086 @@
+/*
+ * Device Modules for Nintendo Wii / Wii U HID Driver
+ * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/*
+ * Wiimote Modules
+ * Nintendo devices provide different peripherals and many new devices lack
+ * initial features like the IR camera. Therefore, each peripheral device is
+ * implemented as an independent module and we probe on each device only the
+ * modules for the hardware that really is available.
+ *
+ * Module registration is sequential. Unregistration is done in reverse order.
+ * After device detection, the needed modules are loaded. Users can trigger
+ * re-detection which causes all modules to be unloaded and then reload the
+ * modules for the new detected device.
+ *
+ * wdata->input is a shared input device. It is always initialized prior to
+ * module registration. If at least one registered module is marked as
+ * WIIMOD_FLAG_INPUT, then the input device will get registered after all
+ * modules were registered.
+ * Please note that it is unregistered _before_ the "remove" callbacks are
+ * called. This guarantees that no input interaction is done, anymore. However,
+ * the wiimote core keeps a reference to the input device so it is freed only
+ * after all modules were removed. It is safe to send events to unregistered
+ * input devices.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/input.h>
+#include <linux/spinlock.h>
+#include "hid-wiimote.h"
+
+/*
+ * Keys
+ * The initial Wii Remote provided a bunch of buttons that are reported as
+ * part of the core protocol. Many later devices dropped these and report
+ * invalid data in the core button reports. Load this only on devices which
+ * correctly send button reports.
+ * It uses the shared input device.
+ */
+
+static const __u16 wiimod_keys_map[] = {
+	KEY_LEFT,	/* WIIPROTO_KEY_LEFT */
+	KEY_RIGHT,	/* WIIPROTO_KEY_RIGHT */
+	KEY_UP,		/* WIIPROTO_KEY_UP */
+	KEY_DOWN,	/* WIIPROTO_KEY_DOWN */
+	KEY_NEXT,	/* WIIPROTO_KEY_PLUS */
+	KEY_PREVIOUS,	/* WIIPROTO_KEY_MINUS */
+	BTN_1,		/* WIIPROTO_KEY_ONE */
+	BTN_2,		/* WIIPROTO_KEY_TWO */
+	BTN_A,		/* WIIPROTO_KEY_A */
+	BTN_B,		/* WIIPROTO_KEY_B */
+	BTN_MODE,	/* WIIPROTO_KEY_HOME */
+};
+
+static void wiimod_keys_in_keys(struct wiimote_data *wdata, const __u8 *keys)
+{
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_LEFT],
+							!!(keys[0] & 0x01));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_RIGHT],
+							!!(keys[0] & 0x02));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_DOWN],
+							!!(keys[0] & 0x04));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_UP],
+							!!(keys[0] & 0x08));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_PLUS],
+							!!(keys[0] & 0x10));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_TWO],
+							!!(keys[1] & 0x01));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_ONE],
+							!!(keys[1] & 0x02));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_B],
+							!!(keys[1] & 0x04));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_A],
+							!!(keys[1] & 0x08));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_MINUS],
+							!!(keys[1] & 0x10));
+	input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_HOME],
+							!!(keys[1] & 0x80));
+	input_sync(wdata->input);
+}
+
+static int wiimod_keys_probe(const struct wiimod_ops *ops,
+			     struct wiimote_data *wdata)
+{
+	unsigned int i;
+
+	set_bit(EV_KEY, wdata->input->evbit);
+	for (i = 0; i < WIIPROTO_KEY_COUNT; ++i)
+		set_bit(wiimod_keys_map[i], wdata->input->keybit);
+
+	return 0;
+}
+
+static const struct wiimod_ops wiimod_keys = {
+	.flags = WIIMOD_FLAG_INPUT,
+	.arg = 0,
+	.probe = wiimod_keys_probe,
+	.remove = NULL,
+	.in_keys = wiimod_keys_in_keys,
+};
+
+/*
+ * Rumble
+ * Nearly all devices provide a rumble feature. A small motor for
+ * force-feedback effects. We provide an FF_RUMBLE memless ff device on the
+ * shared input device if this module is loaded.
+ * The rumble motor is controlled via a flag on almost every output report so
+ * the wiimote core handles the rumble flag. But if a device doesn't provide
+ * the rumble motor, this flag shouldn't be set.
+ */
+
+static int wiimod_rumble_play(struct input_dev *dev, void *data,
+			      struct ff_effect *eff)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	__u8 value;
+	unsigned long flags;
+
+	/*
+	 * The wiimote supports only a single rumble motor so if any magnitude
+	 * is set to non-zero then we start the rumble motor. If both are set to
+	 * zero, we stop the rumble motor.
+	 */
+
+	if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude)
+		value = 1;
+	else
+		value = 0;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wiiproto_req_rumble(wdata, value);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static int wiimod_rumble_probe(const struct wiimod_ops *ops,
+			       struct wiimote_data *wdata)
+{
+	set_bit(FF_RUMBLE, wdata->input->ffbit);
+	if (input_ff_create_memless(wdata->input, NULL, wiimod_rumble_play))
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void wiimod_rumble_remove(const struct wiimod_ops *ops,
+				 struct wiimote_data *wdata)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wiiproto_req_rumble(wdata, 0);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static const struct wiimod_ops wiimod_rumble = {
+	.flags = WIIMOD_FLAG_INPUT,
+	.arg = 0,
+	.probe = wiimod_rumble_probe,
+	.remove = wiimod_rumble_remove,
+};
+
+/*
+ * Battery
+ * 1 byte of battery capacity information is sent along every protocol status
+ * report. The wiimote core caches it but we try to update it on every
+ * user-space request.
+ * This is supported by nearly every device so it's almost always enabled.
+ */
+
+static enum power_supply_property wiimod_battery_props[] = {
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_SCOPE,
+};
+
+static int wiimod_battery_get_property(struct power_supply *psy,
+				       enum power_supply_property psp,
+				       union power_supply_propval *val)
+{
+	struct wiimote_data *wdata = container_of(psy, struct wiimote_data,
+						  battery);
+	int ret = 0, state;
+	unsigned long flags;
+
+	if (psp == POWER_SUPPLY_PROP_SCOPE) {
+		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+		return 0;
+	} else if (psp != POWER_SUPPLY_PROP_CAPACITY) {
+		return -EINVAL;
+	}
+
+	ret = wiimote_cmd_acquire(wdata);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
+	wiiproto_req_status(wdata);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	wiimote_cmd_wait(wdata);
+	wiimote_cmd_release(wdata);
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	state = wdata->state.cmd_battery;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	val->intval = state * 100 / 255;
+	return ret;
+}
+
+static int wiimod_battery_probe(const struct wiimod_ops *ops,
+				struct wiimote_data *wdata)
+{
+	int ret;
+
+	wdata->battery.properties = wiimod_battery_props;
+	wdata->battery.num_properties = ARRAY_SIZE(wiimod_battery_props);
+	wdata->battery.get_property = wiimod_battery_get_property;
+	wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+	wdata->battery.use_for_apm = 0;
+	wdata->battery.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s",
+					wdata->hdev->uniq);
+	if (!wdata->battery.name)
+		return -ENOMEM;
+
+	ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
+	if (ret) {
+		hid_err(wdata->hdev, "cannot register battery device\n");
+		goto err_free;
+	}
+
+	power_supply_powers(&wdata->battery, &wdata->hdev->dev);
+	return 0;
+
+err_free:
+	kfree(wdata->battery.name);
+	wdata->battery.name = NULL;
+	return ret;
+}
+
+static void wiimod_battery_remove(const struct wiimod_ops *ops,
+				  struct wiimote_data *wdata)
+{
+	if (!wdata->battery.name)
+		return;
+
+	power_supply_unregister(&wdata->battery);
+	kfree(wdata->battery.name);
+	wdata->battery.name = NULL;
+}
+
+static const struct wiimod_ops wiimod_battery = {
+	.flags = 0,
+	.arg = 0,
+	.probe = wiimod_battery_probe,
+	.remove = wiimod_battery_remove,
+};
+
+/*
+ * LED
+ * 0 to 4 player LEDs are supported by devices. The "arg" field of the
+ * wiimod_ops structure specifies which LED this module controls. This allows
+ * to register a limited number of LEDs.
+ * State is managed by wiimote core.
+ */
+
+static enum led_brightness wiimod_led_get(struct led_classdev *led_dev)
+{
+	struct wiimote_data *wdata;
+	struct device *dev = led_dev->dev->parent;
+	int i;
+	unsigned long flags;
+	bool value = false;
+
+	wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
+
+	for (i = 0; i < 4; ++i) {
+		if (wdata->leds[i] == led_dev) {
+			spin_lock_irqsave(&wdata->state.lock, flags);
+			value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1);
+			spin_unlock_irqrestore(&wdata->state.lock, flags);
+			break;
+		}
+	}
+
+	return value ? LED_FULL : LED_OFF;
+}
+
+static void wiimod_led_set(struct led_classdev *led_dev,
+			   enum led_brightness value)
+{
+	struct wiimote_data *wdata;
+	struct device *dev = led_dev->dev->parent;
+	int i;
+	unsigned long flags;
+	__u8 state, flag;
+
+	wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
+
+	for (i = 0; i < 4; ++i) {
+		if (wdata->leds[i] == led_dev) {
+			flag = WIIPROTO_FLAG_LED(i + 1);
+			spin_lock_irqsave(&wdata->state.lock, flags);
+			state = wdata->state.flags;
+			if (value == LED_OFF)
+				wiiproto_req_leds(wdata, state & ~flag);
+			else
+				wiiproto_req_leds(wdata, state | flag);
+			spin_unlock_irqrestore(&wdata->state.lock, flags);
+			break;
+		}
+	}
+}
+
+static int wiimod_led_probe(const struct wiimod_ops *ops,
+			    struct wiimote_data *wdata)
+{
+	struct device *dev = &wdata->hdev->dev;
+	size_t namesz = strlen(dev_name(dev)) + 9;
+	struct led_classdev *led;
+	unsigned long flags;
+	char *name;
+	int ret;
+
+	led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
+	if (!led)
+		return -ENOMEM;
+
+	name = (void*)&led[1];
+	snprintf(name, namesz, "%s:blue:p%lu", dev_name(dev), ops->arg);
+	led->name = name;
+	led->brightness = 0;
+	led->max_brightness = 1;
+	led->brightness_get = wiimod_led_get;
+	led->brightness_set = wiimod_led_set;
+
+	wdata->leds[ops->arg] = led;
+	ret = led_classdev_register(dev, led);
+	if (ret)
+		goto err_free;
+
+	/* enable LED1 to stop initial LED-blinking */
+	if (ops->arg == 0) {
+		spin_lock_irqsave(&wdata->state.lock, flags);
+		wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1);
+		spin_unlock_irqrestore(&wdata->state.lock, flags);
+	}
+
+	return 0;
+
+err_free:
+	wdata->leds[ops->arg] = NULL;
+	kfree(led);
+	return ret;
+}
+
+static void wiimod_led_remove(const struct wiimod_ops *ops,
+			      struct wiimote_data *wdata)
+{
+	if (!wdata->leds[ops->arg])
+		return;
+
+	led_classdev_unregister(wdata->leds[ops->arg]);
+	kfree(wdata->leds[ops->arg]);
+	wdata->leds[ops->arg] = NULL;
+}
+
+static const struct wiimod_ops wiimod_leds[4] = {
+	{
+		.flags = 0,
+		.arg = 0,
+		.probe = wiimod_led_probe,
+		.remove = wiimod_led_remove,
+	},
+	{
+		.flags = 0,
+		.arg = 1,
+		.probe = wiimod_led_probe,
+		.remove = wiimod_led_remove,
+	},
+	{
+		.flags = 0,
+		.arg = 2,
+		.probe = wiimod_led_probe,
+		.remove = wiimod_led_remove,
+	},
+	{
+		.flags = 0,
+		.arg = 3,
+		.probe = wiimod_led_probe,
+		.remove = wiimod_led_remove,
+	},
+};
+
+/*
+ * Accelerometer
+ * 3 axis accelerometer data is part of nearly all DRMs. If not supported by a
+ * device, it's mostly cleared to 0. This module parses this data and provides
+ * it via a separate input device.
+ */
+
+static void wiimod_accel_in_accel(struct wiimote_data *wdata,
+				  const __u8 *accel)
+{
+	__u16 x, y, z;
+
+	if (!(wdata->state.flags & WIIPROTO_FLAG_ACCEL))
+		return;
+
+	/*
+	 * payload is: BB BB XX YY ZZ
+	 * Accelerometer data is encoded into 3 10bit values. XX, YY and ZZ
+	 * contain the upper 8 bits of each value. The lower 2 bits are
+	 * contained in the buttons data BB BB.
+	 * Bits 6 and 7 of the first buttons byte BB is the lower 2 bits of the
+	 * X accel value. Bit 5 of the second buttons byte is the 2nd bit of Y
+	 * accel value and bit 6 is the second bit of the Z value.
+	 * The first bit of Y and Z values is not available and always set to 0.
+	 * 0x200 is returned on no movement.
+	 */
+
+	x = accel[2] << 2;
+	y = accel[3] << 2;
+	z = accel[4] << 2;
+
+	x |= (accel[0] >> 5) & 0x3;
+	y |= (accel[1] >> 4) & 0x2;
+	z |= (accel[1] >> 5) & 0x2;
+
+	input_report_abs(wdata->accel, ABS_RX, x - 0x200);
+	input_report_abs(wdata->accel, ABS_RY, y - 0x200);
+	input_report_abs(wdata->accel, ABS_RZ, z - 0x200);
+	input_sync(wdata->accel);
+}
+
+static int wiimod_accel_open(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wiiproto_req_accel(wdata, true);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static void wiimod_accel_close(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wiiproto_req_accel(wdata, false);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static int wiimod_accel_probe(const struct wiimod_ops *ops,
+			      struct wiimote_data *wdata)
+{
+	int ret;
+
+	wdata->accel = input_allocate_device();
+	if (!wdata->accel)
+		return -ENOMEM;
+
+	input_set_drvdata(wdata->accel, wdata);
+	wdata->accel->open = wiimod_accel_open;
+	wdata->accel->close = wiimod_accel_close;
+	wdata->accel->dev.parent = &wdata->hdev->dev;
+	wdata->accel->id.bustype = wdata->hdev->bus;
+	wdata->accel->id.vendor = wdata->hdev->vendor;
+	wdata->accel->id.product = wdata->hdev->product;
+	wdata->accel->id.version = wdata->hdev->version;
+	wdata->accel->name = WIIMOTE_NAME " Accelerometer";
+
+	set_bit(EV_ABS, wdata->accel->evbit);
+	set_bit(ABS_RX, wdata->accel->absbit);
+	set_bit(ABS_RY, wdata->accel->absbit);
+	set_bit(ABS_RZ, wdata->accel->absbit);
+	input_set_abs_params(wdata->accel, ABS_RX, -500, 500, 2, 4);
+	input_set_abs_params(wdata->accel, ABS_RY, -500, 500, 2, 4);
+	input_set_abs_params(wdata->accel, ABS_RZ, -500, 500, 2, 4);
+
+	ret = input_register_device(wdata->accel);
+	if (ret) {
+		hid_err(wdata->hdev, "cannot register input device\n");
+		goto err_free;
+	}
+
+	return 0;
+
+err_free:
+	input_free_device(wdata->accel);
+	wdata->accel = NULL;
+	return ret;
+}
+
+static void wiimod_accel_remove(const struct wiimod_ops *ops,
+				struct wiimote_data *wdata)
+{
+	if (!wdata->accel)
+		return;
+
+	input_unregister_device(wdata->accel);
+	wdata->accel = NULL;
+}
+
+static const struct wiimod_ops wiimod_accel = {
+	.flags = 0,
+	.arg = 0,
+	.probe = wiimod_accel_probe,
+	.remove = wiimod_accel_remove,
+	.in_accel = wiimod_accel_in_accel,
+};
+
+/*
+ * IR Cam
+ * Up to 4 IR sources can be tracked by a normal Wii Remote. The IR cam needs
+ * to be initialized with a fairly complex procedure and consumes a lot of
+ * power. Therefore, as long as no application uses the IR input device, it is
+ * kept offline.
+ * Nearly no other device than the normal Wii Remotes supports the IR cam so
+ * you can disable this module for these devices.
+ */
+
+static void wiimod_ir_in_ir(struct wiimote_data *wdata, const __u8 *ir,
+			    bool packed, unsigned int id)
+{
+	__u16 x, y;
+	__u8 xid, yid;
+	bool sync = false;
+
+	if (!(wdata->state.flags & WIIPROTO_FLAGS_IR))
+		return;
+
+	switch (id) {
+	case 0:
+		xid = ABS_HAT0X;
+		yid = ABS_HAT0Y;
+		break;
+	case 1:
+		xid = ABS_HAT1X;
+		yid = ABS_HAT1Y;
+		break;
+	case 2:
+		xid = ABS_HAT2X;
+		yid = ABS_HAT2Y;
+		break;
+	case 3:
+		xid = ABS_HAT3X;
+		yid = ABS_HAT3Y;
+		sync = true;
+		break;
+	default:
+		return;
+	}
+
+	/*
+	 * Basic IR data is encoded into 3 bytes. The first two bytes are the
+	 * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits
+	 * of both.
+	 * If data is packed, then the 3rd byte is put first and slightly
+	 * reordered. This allows to interleave packed and non-packed data to
+	 * have two IR sets in 5 bytes instead of 6.
+	 * The resulting 10bit X/Y values are passed to the ABS_HAT? input dev.
+	 */
+
+	if (packed) {
+		x = ir[1] | ((ir[0] & 0x03) << 8);
+		y = ir[2] | ((ir[0] & 0x0c) << 6);
+	} else {
+		x = ir[0] | ((ir[2] & 0x30) << 4);
+		y = ir[1] | ((ir[2] & 0xc0) << 2);
+	}
+
+	input_report_abs(wdata->ir, xid, x);
+	input_report_abs(wdata->ir, yid, y);
+
+	if (sync)
+		input_sync(wdata->ir);
+}
+
+static int wiimod_ir_change(struct wiimote_data *wdata, __u16 mode)
+{
+	int ret;
+	unsigned long flags;
+	__u8 format = 0;
+	static const __u8 data_enable[] = { 0x01 };
+	static const __u8 data_sens1[] = { 0x02, 0x00, 0x00, 0x71, 0x01,
+						0x00, 0xaa, 0x00, 0x64 };
+	static const __u8 data_sens2[] = { 0x63, 0x03 };
+	static const __u8 data_fin[] = { 0x08 };
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+
+	if (mode == (wdata->state.flags & WIIPROTO_FLAGS_IR)) {
+		spin_unlock_irqrestore(&wdata->state.lock, flags);
+		return 0;
+	}
+
+	if (mode == 0) {
+		wdata->state.flags &= ~WIIPROTO_FLAGS_IR;
+		wiiproto_req_ir1(wdata, 0);
+		wiiproto_req_ir2(wdata, 0);
+		wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+		spin_unlock_irqrestore(&wdata->state.lock, flags);
+		return 0;
+	}
+
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	ret = wiimote_cmd_acquire(wdata);
+	if (ret)
+		return ret;
+
+	/* send PIXEL CLOCK ENABLE cmd first */
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wiimote_cmd_set(wdata, WIIPROTO_REQ_IR1, 0);
+	wiiproto_req_ir1(wdata, 0x06);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	ret = wiimote_cmd_wait(wdata);
+	if (ret)
+		goto unlock;
+	if (wdata->state.cmd_err) {
+		ret = -EIO;
+		goto unlock;
+	}
+
+	/* enable IR LOGIC */
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wiimote_cmd_set(wdata, WIIPROTO_REQ_IR2, 0);
+	wiiproto_req_ir2(wdata, 0x06);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	ret = wiimote_cmd_wait(wdata);
+	if (ret)
+		goto unlock;
+	if (wdata->state.cmd_err) {
+		ret = -EIO;
+		goto unlock;
+	}
+
+	/* enable IR cam but do not make it send data, yet */
+	ret = wiimote_cmd_write(wdata, 0xb00030, data_enable,
+							sizeof(data_enable));
+	if (ret)
+		goto unlock;
+
+	/* write first sensitivity block */
+	ret = wiimote_cmd_write(wdata, 0xb00000, data_sens1,
+							sizeof(data_sens1));
+	if (ret)
+		goto unlock;
+
+	/* write second sensitivity block */
+	ret = wiimote_cmd_write(wdata, 0xb0001a, data_sens2,
+							sizeof(data_sens2));
+	if (ret)
+		goto unlock;
+
+	/* put IR cam into desired state */
+	switch (mode) {
+		case WIIPROTO_FLAG_IR_FULL:
+			format = 5;
+			break;
+		case WIIPROTO_FLAG_IR_EXT:
+			format = 3;
+			break;
+		case WIIPROTO_FLAG_IR_BASIC:
+			format = 1;
+			break;
+	}
+	ret = wiimote_cmd_write(wdata, 0xb00033, &format, sizeof(format));
+	if (ret)
+		goto unlock;
+
+	/* make IR cam send data */
+	ret = wiimote_cmd_write(wdata, 0xb00030, data_fin, sizeof(data_fin));
+	if (ret)
+		goto unlock;
+
+	/* request new DRM mode compatible to IR mode */
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags &= ~WIIPROTO_FLAGS_IR;
+	wdata->state.flags |= mode & WIIPROTO_FLAGS_IR;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+unlock:
+	wiimote_cmd_release(wdata);
+	return ret;
+}
+
+static int wiimod_ir_open(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+
+	return wiimod_ir_change(wdata, WIIPROTO_FLAG_IR_BASIC);
+}
+
+static void wiimod_ir_close(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+
+	wiimod_ir_change(wdata, 0);
+}
+
+static int wiimod_ir_probe(const struct wiimod_ops *ops,
+			   struct wiimote_data *wdata)
+{
+	int ret;
+
+	wdata->ir = input_allocate_device();
+	if (!wdata->ir)
+		return -ENOMEM;
+
+	input_set_drvdata(wdata->ir, wdata);
+	wdata->ir->open = wiimod_ir_open;
+	wdata->ir->close = wiimod_ir_close;
+	wdata->ir->dev.parent = &wdata->hdev->dev;
+	wdata->ir->id.bustype = wdata->hdev->bus;
+	wdata->ir->id.vendor = wdata->hdev->vendor;
+	wdata->ir->id.product = wdata->hdev->product;
+	wdata->ir->id.version = wdata->hdev->version;
+	wdata->ir->name = WIIMOTE_NAME " IR";
+
+	set_bit(EV_ABS, wdata->ir->evbit);
+	set_bit(ABS_HAT0X, wdata->ir->absbit);
+	set_bit(ABS_HAT0Y, wdata->ir->absbit);
+	set_bit(ABS_HAT1X, wdata->ir->absbit);
+	set_bit(ABS_HAT1Y, wdata->ir->absbit);
+	set_bit(ABS_HAT2X, wdata->ir->absbit);
+	set_bit(ABS_HAT2Y, wdata->ir->absbit);
+	set_bit(ABS_HAT3X, wdata->ir->absbit);
+	set_bit(ABS_HAT3Y, wdata->ir->absbit);
+	input_set_abs_params(wdata->ir, ABS_HAT0X, 0, 1023, 2, 4);
+	input_set_abs_params(wdata->ir, ABS_HAT0Y, 0, 767, 2, 4);
+	input_set_abs_params(wdata->ir, ABS_HAT1X, 0, 1023, 2, 4);
+	input_set_abs_params(wdata->ir, ABS_HAT1Y, 0, 767, 2, 4);
+	input_set_abs_params(wdata->ir, ABS_HAT2X, 0, 1023, 2, 4);
+	input_set_abs_params(wdata->ir, ABS_HAT2Y, 0, 767, 2, 4);
+	input_set_abs_params(wdata->ir, ABS_HAT3X, 0, 1023, 2, 4);
+	input_set_abs_params(wdata->ir, ABS_HAT3Y, 0, 767, 2, 4);
+
+	ret = input_register_device(wdata->ir);
+	if (ret) {
+		hid_err(wdata->hdev, "cannot register input device\n");
+		goto err_free;
+	}
+
+	return 0;
+
+err_free:
+	input_free_device(wdata->ir);
+	wdata->ir = NULL;
+	return ret;
+}
+
+static void wiimod_ir_remove(const struct wiimod_ops *ops,
+			     struct wiimote_data *wdata)
+{
+	if (!wdata->ir)
+		return;
+
+	input_unregister_device(wdata->ir);
+	wdata->ir = NULL;
+}
+
+static const struct wiimod_ops wiimod_ir = {
+	.flags = 0,
+	.arg = 0,
+	.probe = wiimod_ir_probe,
+	.remove = wiimod_ir_remove,
+	.in_ir = wiimod_ir_in_ir,
+};
+
+/*
+ * Nunchuk Extension
+ * The Nintendo Wii Nunchuk was the first official extension published by
+ * Nintendo. It provides two additional keys and a separate accelerometer. It
+ * can be hotplugged to standard Wii Remotes.
+ */
+
+enum wiimod_nunchuk_keys {
+	WIIMOD_NUNCHUK_KEY_C,
+	WIIMOD_NUNCHUK_KEY_Z,
+	WIIMOD_NUNCHUK_KEY_NUM,
+};
+
+static const __u16 wiimod_nunchuk_map[] = {
+	BTN_C,		/* WIIMOD_NUNCHUK_KEY_C */
+	BTN_Z,		/* WIIMOD_NUNCHUK_KEY_Z */
+};
+
+static void wiimod_nunchuk_in_ext(struct wiimote_data *wdata, const __u8 *ext)
+{
+	__s16 x, y, z, bx, by;
+
+	/*   Byte |   8    7 |  6    5 |  4    3 |  2 |  1  |
+	 *   -----+----------+---------+---------+----+-----+
+	 *    1   |              Button X <7:0>             |
+	 *    2   |              Button Y <7:0>             |
+	 *   -----+----------+---------+---------+----+-----+
+	 *    3   |               Speed X <9:2>             |
+	 *    4   |               Speed Y <9:2>             |
+	 *    5   |               Speed Z <9:2>             |
+	 *   -----+----------+---------+---------+----+-----+
+	 *    6   | Z <1:0>  | Y <1:0> | X <1:0> | BC | BZ  |
+	 *   -----+----------+---------+---------+----+-----+
+	 * Button X/Y is the analog stick. Speed X, Y and Z are the
+	 * accelerometer data in the same format as the wiimote's accelerometer.
+	 * The 6th byte contains the LSBs of the accelerometer data.
+	 * BC and BZ are the C and Z buttons: 0 means pressed
+	 *
+	 * If reported interleaved with motionp, then the layout changes. The
+	 * 5th and 6th byte changes to:
+	 *   -----+-----------------------------------+-----+
+	 *    5   |            Speed Z <9:3>          | EXT |
+	 *   -----+--------+-----+-----+----+----+----+-----+
+	 *    6   |Z <2:1> |Y <1>|X <1>| BC | BZ | 0  |  0  |
+	 *   -----+--------+-----+-----+----+----+----+-----+
+	 * All three accelerometer values lose their LSB. The other data is
+	 * still available but slightly moved.
+	 *
+	 * Center data for button values is 128. Center value for accelerometer
+	 * values it 512 / 0x200
+	 */
+
+	bx = ext[0];
+	by = ext[1];
+	bx -= 128;
+	by -= 128;
+
+	x = ext[2] << 2;
+	y = ext[3] << 2;
+	z = ext[4] << 2;
+
+	if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
+		x |= (ext[5] >> 3) & 0x02;
+		y |= (ext[5] >> 4) & 0x02;
+		z &= ~0x4;
+		z |= (ext[5] >> 5) & 0x06;
+	} else {
+		x |= (ext[5] >> 2) & 0x03;
+		y |= (ext[5] >> 4) & 0x03;
+		z |= (ext[5] >> 6) & 0x03;
+	}
+
+	x -= 0x200;
+	y -= 0x200;
+	z -= 0x200;
+
+	input_report_abs(wdata->extension.input, ABS_HAT0X, bx);
+	input_report_abs(wdata->extension.input, ABS_HAT0Y, by);
+
+	input_report_abs(wdata->extension.input, ABS_RX, x);
+	input_report_abs(wdata->extension.input, ABS_RY, y);
+	input_report_abs(wdata->extension.input, ABS_RZ, z);
+
+	if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
+		input_report_key(wdata->extension.input,
+			wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z],
+			!(ext[5] & 0x04));
+		input_report_key(wdata->extension.input,
+			wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C],
+			!(ext[5] & 0x08));
+	} else {
+		input_report_key(wdata->extension.input,
+			wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z],
+			!(ext[5] & 0x01));
+		input_report_key(wdata->extension.input,
+			wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C],
+			!(ext[5] & 0x02));
+	}
+
+	input_sync(wdata->extension.input);
+}
+
+static int wiimod_nunchuk_open(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_EXT_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static void wiimod_nunchuk_close(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static int wiimod_nunchuk_probe(const struct wiimod_ops *ops,
+				struct wiimote_data *wdata)
+{
+	int ret, i;
+
+	wdata->extension.input = input_allocate_device();
+	if (!wdata->extension.input)
+		return -ENOMEM;
+
+	input_set_drvdata(wdata->extension.input, wdata);
+	wdata->extension.input->open = wiimod_nunchuk_open;
+	wdata->extension.input->close = wiimod_nunchuk_close;
+	wdata->extension.input->dev.parent = &wdata->hdev->dev;
+	wdata->extension.input->id.bustype = wdata->hdev->bus;
+	wdata->extension.input->id.vendor = wdata->hdev->vendor;
+	wdata->extension.input->id.product = wdata->hdev->product;
+	wdata->extension.input->id.version = wdata->hdev->version;
+	wdata->extension.input->name = WIIMOTE_NAME " Nunchuk";
+
+	set_bit(EV_KEY, wdata->extension.input->evbit);
+	for (i = 0; i < WIIMOD_NUNCHUK_KEY_NUM; ++i)
+		set_bit(wiimod_nunchuk_map[i],
+			wdata->extension.input->keybit);
+
+	set_bit(EV_ABS, wdata->extension.input->evbit);
+	set_bit(ABS_HAT0X, wdata->extension.input->absbit);
+	set_bit(ABS_HAT0Y, wdata->extension.input->absbit);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT0X, -120, 120, 2, 4);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT0Y, -120, 120, 2, 4);
+	set_bit(ABS_RX, wdata->extension.input->absbit);
+	set_bit(ABS_RY, wdata->extension.input->absbit);
+	set_bit(ABS_RZ, wdata->extension.input->absbit);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_RX, -500, 500, 2, 4);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_RY, -500, 500, 2, 4);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_RZ, -500, 500, 2, 4);
+
+	ret = input_register_device(wdata->extension.input);
+	if (ret)
+		goto err_free;
+
+	return 0;
+
+err_free:
+	input_free_device(wdata->extension.input);
+	wdata->extension.input = NULL;
+	return ret;
+}
+
+static void wiimod_nunchuk_remove(const struct wiimod_ops *ops,
+				  struct wiimote_data *wdata)
+{
+	if (!wdata->extension.input)
+		return;
+
+	input_unregister_device(wdata->extension.input);
+	wdata->extension.input = NULL;
+}
+
+static const struct wiimod_ops wiimod_nunchuk = {
+	.flags = 0,
+	.arg = 0,
+	.probe = wiimod_nunchuk_probe,
+	.remove = wiimod_nunchuk_remove,
+	.in_ext = wiimod_nunchuk_in_ext,
+};
+
+/*
+ * Classic Controller
+ * Another official extension from Nintendo. It provides a classic
+ * gamecube-like controller that can be hotplugged on the Wii Remote.
+ * It has several hardware buttons and switches that are all reported via
+ * a normal extension device.
+ */
+
+enum wiimod_classic_keys {
+	WIIMOD_CLASSIC_KEY_A,
+	WIIMOD_CLASSIC_KEY_B,
+	WIIMOD_CLASSIC_KEY_X,
+	WIIMOD_CLASSIC_KEY_Y,
+	WIIMOD_CLASSIC_KEY_ZL,
+	WIIMOD_CLASSIC_KEY_ZR,
+	WIIMOD_CLASSIC_KEY_PLUS,
+	WIIMOD_CLASSIC_KEY_MINUS,
+	WIIMOD_CLASSIC_KEY_HOME,
+	WIIMOD_CLASSIC_KEY_LEFT,
+	WIIMOD_CLASSIC_KEY_RIGHT,
+	WIIMOD_CLASSIC_KEY_UP,
+	WIIMOD_CLASSIC_KEY_DOWN,
+	WIIMOD_CLASSIC_KEY_LT,
+	WIIMOD_CLASSIC_KEY_RT,
+	WIIMOD_CLASSIC_KEY_NUM,
+};
+
+static const __u16 wiimod_classic_map[] = {
+	BTN_A,		/* WIIMOD_CLASSIC_KEY_A */
+	BTN_B,		/* WIIMOD_CLASSIC_KEY_B */
+	BTN_X,		/* WIIMOD_CLASSIC_KEY_X */
+	BTN_Y,		/* WIIMOD_CLASSIC_KEY_Y */
+	BTN_TL2,	/* WIIMOD_CLASSIC_KEY_ZL */
+	BTN_TR2,	/* WIIMOD_CLASSIC_KEY_ZR */
+	KEY_NEXT,	/* WIIMOD_CLASSIC_KEY_PLUS */
+	KEY_PREVIOUS,	/* WIIMOD_CLASSIC_KEY_MINUS */
+	BTN_MODE,	/* WIIMOD_CLASSIC_KEY_HOME */
+	KEY_LEFT,	/* WIIMOD_CLASSIC_KEY_LEFT */
+	KEY_RIGHT,	/* WIIMOD_CLASSIC_KEY_RIGHT */
+	KEY_UP,		/* WIIMOD_CLASSIC_KEY_UP */
+	KEY_DOWN,	/* WIIMOD_CLASSIC_KEY_DOWN */
+	BTN_TL,		/* WIIMOD_CLASSIC_KEY_LT */
+	BTN_TR,		/* WIIMOD_CLASSIC_KEY_RT */
+};
+
+static void wiimod_classic_in_ext(struct wiimote_data *wdata, const __u8 *ext)
+{
+	__s8 rx, ry, lx, ly, lt, rt;
+
+	/*   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *    1   | RX <5:4>  |              LX <5:0>             |
+	 *    2   | RX <3:2>  |              LY <5:0>             |
+	 *   -----+-----+-----+-----+-----------------------------+
+	 *    3   |RX<1>| LT <5:4>  |         RY <5:1>            |
+	 *   -----+-----+-----------+-----------------------------+
+	 *    4   |     LT <3:1>    |         RT <5:1>            |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *    5   | BDR | BDD | BLT | B-  | BH  | B+  | BRT |  1  |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *    6   | BZL | BB  | BY  | BA  | BX  | BZR | BDL | BDU |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 * All buttons are 0 if pressed
+	 * RX and RY are right analog stick
+	 * LX and LY are left analog stick
+	 * LT is left trigger, RT is right trigger
+	 * BLT is 0 if left trigger is fully pressed
+	 * BRT is 0 if right trigger is fully pressed
+	 * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons
+	 * BZL is left Z button and BZR is right Z button
+	 * B-, BH, B+ are +, HOME and - buttons
+	 * BB, BY, BA, BX are A, B, X, Y buttons
+	 * LSB of RX, RY, LT, and RT are not transmitted and always 0.
+	 *
+	 * With motionp enabled it changes slightly to this:
+	 *   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *    1   | RX <5:4>  |          LX <5:1>           | BDU |
+	 *    2   | RX <3:2>  |          LY <5:1>           | BDL |
+	 *   -----+-----+-----+-----+-----------------------+-----+
+	 *    3   |RX<1>| LT <5:4>  |         RY <5:1>            |
+	 *   -----+-----+-----------+-----------------------------+
+	 *    4   |     LT <3:1>    |         RT <5:1>            |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *    5   | BDR | BDD | BLT | B-  | BH  | B+  | BRT | EXT |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *    6   | BZL | BB  | BY  | BA  | BX  | BZR |  0  |  0  |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest
+	 * is the same as before.
+	 */
+
+	if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
+		lx = ext[0] & 0x3e;
+		ly = ext[1] & 0x3e;
+	} else {
+		lx = ext[0] & 0x3f;
+		ly = ext[1] & 0x3f;
+	}
+
+	rx = (ext[0] >> 3) & 0x18;
+	rx |= (ext[1] >> 5) & 0x06;
+	rx |= (ext[2] >> 7) & 0x01;
+	ry = ext[2] & 0x1f;
+
+	rt = ext[3] & 0x1f;
+	lt = (ext[2] >> 2) & 0x18;
+	lt |= (ext[3] >> 5) & 0x07;
+
+	rx <<= 1;
+	ry <<= 1;
+	rt <<= 1;
+	lt <<= 1;
+
+	input_report_abs(wdata->extension.input, ABS_HAT1X, lx - 0x20);
+	input_report_abs(wdata->extension.input, ABS_HAT1Y, ly - 0x20);
+	input_report_abs(wdata->extension.input, ABS_HAT2X, rx - 0x20);
+	input_report_abs(wdata->extension.input, ABS_HAT2Y, ry - 0x20);
+	input_report_abs(wdata->extension.input, ABS_HAT3X, rt);
+	input_report_abs(wdata->extension.input, ABS_HAT3Y, lt);
+
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_RIGHT],
+			 !(ext[4] & 0x80));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_DOWN],
+			 !(ext[4] & 0x40));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LT],
+			 !(ext[4] & 0x20));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_MINUS],
+			 !(ext[4] & 0x10));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_HOME],
+			 !(ext[4] & 0x08));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_PLUS],
+			 !(ext[4] & 0x04));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_RT],
+			 !(ext[4] & 0x02));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZL],
+			 !(ext[5] & 0x80));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_B],
+			 !(ext[5] & 0x40));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_Y],
+			 !(ext[5] & 0x20));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_A],
+			 !(ext[5] & 0x10));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_X],
+			 !(ext[5] & 0x08));
+	input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZR],
+			 !(ext[5] & 0x04));
+
+	if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) {
+		input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT],
+			 !(ext[1] & 0x01));
+		input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP],
+			 !(ext[0] & 0x01));
+	} else {
+		input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT],
+			 !(ext[5] & 0x02));
+		input_report_key(wdata->extension.input,
+			 wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP],
+			 !(ext[5] & 0x01));
+	}
+
+	input_sync(wdata->extension.input);
+}
+
+static int wiimod_classic_open(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_EXT_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static void wiimod_classic_close(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static int wiimod_classic_probe(const struct wiimod_ops *ops,
+				struct wiimote_data *wdata)
+{
+	int ret, i;
+
+	wdata->extension.input = input_allocate_device();
+	if (!wdata->extension.input)
+		return -ENOMEM;
+
+	input_set_drvdata(wdata->extension.input, wdata);
+	wdata->extension.input->open = wiimod_classic_open;
+	wdata->extension.input->close = wiimod_classic_close;
+	wdata->extension.input->dev.parent = &wdata->hdev->dev;
+	wdata->extension.input->id.bustype = wdata->hdev->bus;
+	wdata->extension.input->id.vendor = wdata->hdev->vendor;
+	wdata->extension.input->id.product = wdata->hdev->product;
+	wdata->extension.input->id.version = wdata->hdev->version;
+	wdata->extension.input->name = WIIMOTE_NAME " Classic Controller";
+
+	set_bit(EV_KEY, wdata->extension.input->evbit);
+	for (i = 0; i < WIIMOD_CLASSIC_KEY_NUM; ++i)
+		set_bit(wiimod_classic_map[i],
+			wdata->extension.input->keybit);
+
+	set_bit(EV_ABS, wdata->extension.input->evbit);
+	set_bit(ABS_HAT1X, wdata->extension.input->absbit);
+	set_bit(ABS_HAT1Y, wdata->extension.input->absbit);
+	set_bit(ABS_HAT2X, wdata->extension.input->absbit);
+	set_bit(ABS_HAT2Y, wdata->extension.input->absbit);
+	set_bit(ABS_HAT3X, wdata->extension.input->absbit);
+	set_bit(ABS_HAT3Y, wdata->extension.input->absbit);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT1X, -30, 30, 1, 1);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT1Y, -30, 30, 1, 1);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT2X, -30, 30, 1, 1);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT2Y, -30, 30, 1, 1);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT3X, -30, 30, 1, 1);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT3Y, -30, 30, 1, 1);
+
+	ret = input_register_device(wdata->extension.input);
+	if (ret)
+		goto err_free;
+
+	return 0;
+
+err_free:
+	input_free_device(wdata->extension.input);
+	wdata->extension.input = NULL;
+	return ret;
+}
+
+static void wiimod_classic_remove(const struct wiimod_ops *ops,
+				  struct wiimote_data *wdata)
+{
+	if (!wdata->extension.input)
+		return;
+
+	input_unregister_device(wdata->extension.input);
+	wdata->extension.input = NULL;
+}
+
+static const struct wiimod_ops wiimod_classic = {
+	.flags = 0,
+	.arg = 0,
+	.probe = wiimod_classic_probe,
+	.remove = wiimod_classic_remove,
+	.in_ext = wiimod_classic_in_ext,
+};
+
+/*
+ * Balance Board Extension
+ * The Nintendo Wii Balance Board provides four hardware weight sensor plus a
+ * single push button. No other peripherals are available. However, the
+ * balance-board data is sent via a standard Wii Remote extension. All other
+ * data for non-present hardware is zeroed out.
+ * Some 3rd party devices react allergic if we try to access normal Wii Remote
+ * hardware, so this extension module should be the only module that is loaded
+ * on balance boards.
+ * The balance board needs 8 bytes extension data instead of basic 6 bytes so
+ * it needs the WIIMOD_FLAG_EXT8 flag.
+ */
+
+static void wiimod_bboard_in_keys(struct wiimote_data *wdata, const __u8 *keys)
+{
+	input_report_key(wdata->extension.input, BTN_A,
+			 !!(keys[1] & 0x08));
+	input_sync(wdata->extension.input);
+}
+
+static void wiimod_bboard_in_ext(struct wiimote_data *wdata,
+				 const __u8 *ext)
+{
+	__s32 val[4], tmp, div;
+	unsigned int i;
+	struct wiimote_state *s = &wdata->state;
+
+	/*
+	 * Balance board data layout:
+	 *
+	 *   Byte |  8  7  6  5  4  3  2  1  |
+	 *   -----+--------------------------+
+	 *    1   |    Top Right <15:8>      |
+	 *    2   |    Top Right  <7:0>      |
+	 *   -----+--------------------------+
+	 *    3   | Bottom Right <15:8>      |
+	 *    4   | Bottom Right  <7:0>      |
+	 *   -----+--------------------------+
+	 *    5   |     Top Left <15:8>      |
+	 *    6   |     Top Left  <7:0>      |
+	 *   -----+--------------------------+
+	 *    7   |  Bottom Left <15:8>      |
+	 *    8   |  Bottom Left  <7:0>      |
+	 *   -----+--------------------------+
+	 *
+	 * These values represent the weight-measurements of the Wii-balance
+	 * board with 16bit precision.
+	 *
+	 * The balance-board is never reported interleaved with motionp.
+	 */
+
+	val[0] = ext[0];
+	val[0] <<= 8;
+	val[0] |= ext[1];
+
+	val[1] = ext[2];
+	val[1] <<= 8;
+	val[1] |= ext[3];
+
+	val[2] = ext[4];
+	val[2] <<= 8;
+	val[2] |= ext[5];
+
+	val[3] = ext[6];
+	val[3] <<= 8;
+	val[3] |= ext[7];
+
+	/* apply calibration data */
+	for (i = 0; i < 4; i++) {
+		if (val[i] <= s->calib_bboard[i][0]) {
+			tmp = 0;
+		} else if (val[i] < s->calib_bboard[i][1]) {
+			tmp = val[i] - s->calib_bboard[i][0];
+			tmp *= 1700;
+			div = s->calib_bboard[i][1] - s->calib_bboard[i][0];
+			tmp /= div ? div : 1;
+		} else {
+			tmp = val[i] - s->calib_bboard[i][1];
+			tmp *= 1700;
+			div = s->calib_bboard[i][2] - s->calib_bboard[i][1];
+			tmp /= div ? div : 1;
+			tmp += 1700;
+		}
+		val[i] = tmp;
+	}
+
+	input_report_abs(wdata->extension.input, ABS_HAT0X, val[0]);
+	input_report_abs(wdata->extension.input, ABS_HAT0Y, val[1]);
+	input_report_abs(wdata->extension.input, ABS_HAT1X, val[2]);
+	input_report_abs(wdata->extension.input, ABS_HAT1Y, val[3]);
+	input_sync(wdata->extension.input);
+}
+
+static int wiimod_bboard_open(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_EXT_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static void wiimod_bboard_close(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static ssize_t wiimod_bboard_calib_show(struct device *dev,
+					struct device_attribute *attr,
+					char *out)
+{
+	struct wiimote_data *wdata = dev_to_wii(dev);
+	int i, j, ret;
+	__u16 val;
+	__u8 buf[24], offs;
+
+	ret = wiimote_cmd_acquire(wdata);
+	if (ret)
+		return ret;
+
+	ret = wiimote_cmd_read(wdata, 0xa40024, buf, 12);
+	if (ret != 12) {
+		wiimote_cmd_release(wdata);
+		return ret < 0 ? ret : -EIO;
+	}
+	ret = wiimote_cmd_read(wdata, 0xa40024 + 12, buf + 12, 12);
+	if (ret != 12) {
+		wiimote_cmd_release(wdata);
+		return ret < 0 ? ret : -EIO;
+	}
+
+	wiimote_cmd_release(wdata);
+
+	spin_lock_irq(&wdata->state.lock);
+	offs = 0;
+	for (i = 0; i < 3; ++i) {
+		for (j = 0; j < 4; ++j) {
+			wdata->state.calib_bboard[j][i] = buf[offs];
+			wdata->state.calib_bboard[j][i] <<= 8;
+			wdata->state.calib_bboard[j][i] |= buf[offs + 1];
+			offs += 2;
+		}
+	}
+	spin_unlock_irq(&wdata->state.lock);
+
+	ret = 0;
+	for (i = 0; i < 3; ++i) {
+		for (j = 0; j < 4; ++j) {
+			val = wdata->state.calib_bboard[j][i];
+			if (i == 2 && j == 3)
+				ret += sprintf(&out[ret], "%04x\n", val);
+			else
+				ret += sprintf(&out[ret], "%04x:", val);
+		}
+	}
+
+	return ret;
+}
+
+static DEVICE_ATTR(bboard_calib, S_IRUGO, wiimod_bboard_calib_show, NULL);
+
+static int wiimod_bboard_probe(const struct wiimod_ops *ops,
+			       struct wiimote_data *wdata)
+{
+	int ret, i, j;
+	__u8 buf[24], offs;
+
+	wiimote_cmd_acquire_noint(wdata);
+
+	ret = wiimote_cmd_read(wdata, 0xa40024, buf, 12);
+	if (ret != 12) {
+		wiimote_cmd_release(wdata);
+		return ret < 0 ? ret : -EIO;
+	}
+	ret = wiimote_cmd_read(wdata, 0xa40024 + 12, buf + 12, 12);
+	if (ret != 12) {
+		wiimote_cmd_release(wdata);
+		return ret < 0 ? ret : -EIO;
+	}
+
+	wiimote_cmd_release(wdata);
+
+	offs = 0;
+	for (i = 0; i < 3; ++i) {
+		for (j = 0; j < 4; ++j) {
+			wdata->state.calib_bboard[j][i] = buf[offs];
+			wdata->state.calib_bboard[j][i] <<= 8;
+			wdata->state.calib_bboard[j][i] |= buf[offs + 1];
+			offs += 2;
+		}
+	}
+
+	wdata->extension.input = input_allocate_device();
+	if (!wdata->extension.input)
+		return -ENOMEM;
+
+	ret = device_create_file(&wdata->hdev->dev,
+				 &dev_attr_bboard_calib);
+	if (ret) {
+		hid_err(wdata->hdev, "cannot create sysfs attribute\n");
+		goto err_free;
+	}
+
+	input_set_drvdata(wdata->extension.input, wdata);
+	wdata->extension.input->open = wiimod_bboard_open;
+	wdata->extension.input->close = wiimod_bboard_close;
+	wdata->extension.input->dev.parent = &wdata->hdev->dev;
+	wdata->extension.input->id.bustype = wdata->hdev->bus;
+	wdata->extension.input->id.vendor = wdata->hdev->vendor;
+	wdata->extension.input->id.product = wdata->hdev->product;
+	wdata->extension.input->id.version = wdata->hdev->version;
+	wdata->extension.input->name = WIIMOTE_NAME " Balance Board";
+
+	set_bit(EV_KEY, wdata->extension.input->evbit);
+	set_bit(BTN_A, wdata->extension.input->keybit);
+
+	set_bit(EV_ABS, wdata->extension.input->evbit);
+	set_bit(ABS_HAT0X, wdata->extension.input->absbit);
+	set_bit(ABS_HAT0Y, wdata->extension.input->absbit);
+	set_bit(ABS_HAT1X, wdata->extension.input->absbit);
+	set_bit(ABS_HAT1Y, wdata->extension.input->absbit);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT0X, 0, 65535, 2, 4);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT0Y, 0, 65535, 2, 4);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT1X, 0, 65535, 2, 4);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_HAT1Y, 0, 65535, 2, 4);
+
+	ret = input_register_device(wdata->extension.input);
+	if (ret)
+		goto err_file;
+
+	return 0;
+
+err_file:
+	device_remove_file(&wdata->hdev->dev,
+			   &dev_attr_bboard_calib);
+err_free:
+	input_free_device(wdata->extension.input);
+	wdata->extension.input = NULL;
+	return ret;
+}
+
+static void wiimod_bboard_remove(const struct wiimod_ops *ops,
+				 struct wiimote_data *wdata)
+{
+	if (!wdata->extension.input)
+		return;
+
+	input_unregister_device(wdata->extension.input);
+	wdata->extension.input = NULL;
+	device_remove_file(&wdata->hdev->dev,
+			   &dev_attr_bboard_calib);
+}
+
+static const struct wiimod_ops wiimod_bboard = {
+	.flags = WIIMOD_FLAG_EXT8,
+	.arg = 0,
+	.probe = wiimod_bboard_probe,
+	.remove = wiimod_bboard_remove,
+	.in_keys = wiimod_bboard_in_keys,
+	.in_ext = wiimod_bboard_in_ext,
+};
+
+/*
+ * Pro Controller
+ * Released with the Wii U was the Nintendo Wii U Pro Controller. It does not
+ * work together with the classic Wii, but only with the new Wii U. However, it
+ * uses the same protocol and provides a builtin "classic controller pro"
+ * extension, few standard buttons, a rumble motor, 4 LEDs and a battery.
+ * We provide all these via a standard extension device as the device doesn't
+ * feature an extension port.
+ */
+
+enum wiimod_pro_keys {
+	WIIMOD_PRO_KEY_A,
+	WIIMOD_PRO_KEY_B,
+	WIIMOD_PRO_KEY_X,
+	WIIMOD_PRO_KEY_Y,
+	WIIMOD_PRO_KEY_PLUS,
+	WIIMOD_PRO_KEY_MINUS,
+	WIIMOD_PRO_KEY_HOME,
+	WIIMOD_PRO_KEY_LEFT,
+	WIIMOD_PRO_KEY_RIGHT,
+	WIIMOD_PRO_KEY_UP,
+	WIIMOD_PRO_KEY_DOWN,
+	WIIMOD_PRO_KEY_TL,
+	WIIMOD_PRO_KEY_TR,
+	WIIMOD_PRO_KEY_ZL,
+	WIIMOD_PRO_KEY_ZR,
+	WIIMOD_PRO_KEY_THUMBL,
+	WIIMOD_PRO_KEY_THUMBR,
+	WIIMOD_PRO_KEY_NUM,
+};
+
+static const __u16 wiimod_pro_map[] = {
+	BTN_EAST,	/* WIIMOD_PRO_KEY_A */
+	BTN_SOUTH,	/* WIIMOD_PRO_KEY_B */
+	BTN_NORTH,	/* WIIMOD_PRO_KEY_X */
+	BTN_WEST,	/* WIIMOD_PRO_KEY_Y */
+	BTN_START,	/* WIIMOD_PRO_KEY_PLUS */
+	BTN_SELECT,	/* WIIMOD_PRO_KEY_MINUS */
+	BTN_MODE,	/* WIIMOD_PRO_KEY_HOME */
+	BTN_DPAD_LEFT,	/* WIIMOD_PRO_KEY_LEFT */
+	BTN_DPAD_RIGHT,	/* WIIMOD_PRO_KEY_RIGHT */
+	BTN_DPAD_UP,	/* WIIMOD_PRO_KEY_UP */
+	BTN_DPAD_DOWN,	/* WIIMOD_PRO_KEY_DOWN */
+	BTN_TL,		/* WIIMOD_PRO_KEY_TL */
+	BTN_TR,		/* WIIMOD_PRO_KEY_TR */
+	BTN_TL2,	/* WIIMOD_PRO_KEY_ZL */
+	BTN_TR2,	/* WIIMOD_PRO_KEY_ZR */
+	BTN_THUMBL,	/* WIIMOD_PRO_KEY_THUMBL */
+	BTN_THUMBR,	/* WIIMOD_PRO_KEY_THUMBR */
+};
+
+static void wiimod_pro_in_ext(struct wiimote_data *wdata, const __u8 *ext)
+{
+	__s16 rx, ry, lx, ly;
+
+	/*   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *    1   |                   LX <7:0>                    |
+	 *   -----+-----------------------+-----------------------+
+	 *    2   |  0     0     0     0  |       LX <11:8>       |
+	 *   -----+-----------------------+-----------------------+
+	 *    3   |                   RX <7:0>                    |
+	 *   -----+-----------------------+-----------------------+
+	 *    4   |  0     0     0     0  |       RX <11:8>       |
+	 *   -----+-----------------------+-----------------------+
+	 *    5   |                   LY <7:0>                    |
+	 *   -----+-----------------------+-----------------------+
+	 *    6   |  0     0     0     0  |       LY <11:8>       |
+	 *   -----+-----------------------+-----------------------+
+	 *    7   |                   RY <7:0>                    |
+	 *   -----+-----------------------+-----------------------+
+	 *    8   |  0     0     0     0  |       RY <11:8>       |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *    9   | BDR | BDD | BLT | B-  | BH  | B+  | BRT |  1  |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *   10   | BZL | BB  | BY  | BA  | BX  | BZR | BDL | BDU |
+	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
+	 *   11   |  1  |     BATTERY     | USB |CHARG|LTHUM|RTHUM|
+	 *   -----+-----+-----------------+-----------+-----+-----+
+	 * All buttons are low-active (0 if pressed)
+	 * RX and RY are right analog stick
+	 * LX and LY are left analog stick
+	 * BLT is left trigger, BRT is right trigger.
+	 * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons
+	 * BZL is left Z button and BZR is right Z button
+	 * B-, BH, B+ are +, HOME and - buttons
+	 * BB, BY, BA, BX are A, B, X, Y buttons
+	 *
+	 * Bits marked as 0/1 are unknown and never changed during tests.
+	 *
+	 * Not entirely verified:
+	 *   CHARG: 1 if uncharging, 0 if charging
+	 *   USB: 1 if not connected, 0 if connected
+	 *   BATTERY: battery capacity from 000 (empty) to 100 (full)
+	 */
+
+	lx = (ext[0] & 0xff) | ((ext[1] & 0x0f) << 8);
+	rx = (ext[2] & 0xff) | ((ext[3] & 0x0f) << 8);
+	ly = (ext[4] & 0xff) | ((ext[5] & 0x0f) << 8);
+	ry = (ext[6] & 0xff) | ((ext[7] & 0x0f) << 8);
+
+	input_report_abs(wdata->extension.input, ABS_X, lx - 0x800);
+	input_report_abs(wdata->extension.input, ABS_Y, ly - 0x800);
+	input_report_abs(wdata->extension.input, ABS_RX, rx - 0x800);
+	input_report_abs(wdata->extension.input, ABS_RY, ry - 0x800);
+
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_RIGHT],
+			 !(ext[8] & 0x80));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_DOWN],
+			 !(ext[8] & 0x40));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_TL],
+			 !(ext[8] & 0x20));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_MINUS],
+			 !(ext[8] & 0x10));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_HOME],
+			 !(ext[8] & 0x08));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_PLUS],
+			 !(ext[8] & 0x04));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_TR],
+			 !(ext[8] & 0x02));
+
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_ZL],
+			 !(ext[9] & 0x80));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_B],
+			 !(ext[9] & 0x40));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_Y],
+			 !(ext[9] & 0x20));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_A],
+			 !(ext[9] & 0x10));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_X],
+			 !(ext[9] & 0x08));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_ZR],
+			 !(ext[9] & 0x04));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_LEFT],
+			 !(ext[9] & 0x02));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_UP],
+			 !(ext[9] & 0x01));
+
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_THUMBL],
+			 !(ext[10] & 0x02));
+	input_report_key(wdata->extension.input,
+			 wiimod_pro_map[WIIMOD_PRO_KEY_THUMBR],
+			 !(ext[10] & 0x01));
+
+	input_sync(wdata->extension.input);
+}
+
+static int wiimod_pro_open(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_EXT_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static void wiimod_pro_close(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static int wiimod_pro_play(struct input_dev *dev, void *data,
+			   struct ff_effect *eff)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	__u8 value;
+	unsigned long flags;
+
+	/*
+	 * The wiimote supports only a single rumble motor so if any magnitude
+	 * is set to non-zero then we start the rumble motor. If both are set to
+	 * zero, we stop the rumble motor.
+	 */
+
+	if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude)
+		value = 1;
+	else
+		value = 0;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wiiproto_req_rumble(wdata, value);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static int wiimod_pro_probe(const struct wiimod_ops *ops,
+			    struct wiimote_data *wdata)
+{
+	int ret, i;
+
+	wdata->extension.input = input_allocate_device();
+	if (!wdata->extension.input)
+		return -ENOMEM;
+
+	set_bit(FF_RUMBLE, wdata->extension.input->ffbit);
+	input_set_drvdata(wdata->extension.input, wdata);
+
+	if (input_ff_create_memless(wdata->extension.input, NULL,
+				    wiimod_pro_play)) {
+		ret = -ENOMEM;
+		goto err_free;
+	}
+
+	wdata->extension.input->open = wiimod_pro_open;
+	wdata->extension.input->close = wiimod_pro_close;
+	wdata->extension.input->dev.parent = &wdata->hdev->dev;
+	wdata->extension.input->id.bustype = wdata->hdev->bus;
+	wdata->extension.input->id.vendor = wdata->hdev->vendor;
+	wdata->extension.input->id.product = wdata->hdev->product;
+	wdata->extension.input->id.version = wdata->hdev->version;
+	wdata->extension.input->name = WIIMOTE_NAME " Pro Controller";
+
+	set_bit(EV_KEY, wdata->extension.input->evbit);
+	for (i = 0; i < WIIMOD_PRO_KEY_NUM; ++i)
+		set_bit(wiimod_pro_map[i],
+			wdata->extension.input->keybit);
+
+	set_bit(EV_ABS, wdata->extension.input->evbit);
+	set_bit(ABS_X, wdata->extension.input->absbit);
+	set_bit(ABS_Y, wdata->extension.input->absbit);
+	set_bit(ABS_RX, wdata->extension.input->absbit);
+	set_bit(ABS_RY, wdata->extension.input->absbit);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_X, -0x800, 0x800, 2, 4);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_Y, -0x800, 0x800, 2, 4);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_RX, -0x800, 0x800, 2, 4);
+	input_set_abs_params(wdata->extension.input,
+			     ABS_RY, -0x800, 0x800, 2, 4);
+
+	ret = input_register_device(wdata->extension.input);
+	if (ret)
+		goto err_free;
+
+	return 0;
+
+err_free:
+	input_free_device(wdata->extension.input);
+	wdata->extension.input = NULL;
+	return ret;
+}
+
+static void wiimod_pro_remove(const struct wiimod_ops *ops,
+			      struct wiimote_data *wdata)
+{
+	unsigned long flags;
+
+	if (!wdata->extension.input)
+		return;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wiiproto_req_rumble(wdata, 0);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	input_unregister_device(wdata->extension.input);
+	wdata->extension.input = NULL;
+}
+
+static const struct wiimod_ops wiimod_pro = {
+	.flags = WIIMOD_FLAG_EXT16,
+	.arg = 0,
+	.probe = wiimod_pro_probe,
+	.remove = wiimod_pro_remove,
+	.in_ext = wiimod_pro_in_ext,
+};
+
+/*
+ * Builtin Motion Plus
+ * This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which
+ * disables polling for Motion-Plus. This should be set only for devices which
+ * don't allow MP hotplugging.
+ */
+
+static int wiimod_builtin_mp_probe(const struct wiimod_ops *ops,
+				   struct wiimote_data *wdata)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static void wiimod_builtin_mp_remove(const struct wiimod_ops *ops,
+				     struct wiimote_data *wdata)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static const struct wiimod_ops wiimod_builtin_mp = {
+	.flags = 0,
+	.arg = 0,
+	.probe = wiimod_builtin_mp_probe,
+	.remove = wiimod_builtin_mp_remove,
+};
+
+/*
+ * No Motion Plus
+ * This module simply sets the WIIPROTO_FLAG_NO_MP protocol flag which
+ * disables motion-plus. This is needed for devices that advertise this but we
+ * don't know how to use it (or whether it is actually present).
+ */
+
+static int wiimod_no_mp_probe(const struct wiimod_ops *ops,
+			      struct wiimote_data *wdata)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_NO_MP;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static void wiimod_no_mp_remove(const struct wiimod_ops *ops,
+				struct wiimote_data *wdata)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_NO_MP;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static const struct wiimod_ops wiimod_no_mp = {
+	.flags = 0,
+	.arg = 0,
+	.probe = wiimod_no_mp_probe,
+	.remove = wiimod_no_mp_remove,
+};
+
+/*
+ * Motion Plus
+ * The Motion Plus extension provides rotation sensors (gyro) as a small
+ * extension device for Wii Remotes. Many devices have them built-in so
+ * you cannot see them from the outside.
+ * Motion Plus extensions are special because they are on a separate extension
+ * port and allow other extensions to be used simultaneously. This is all
+ * handled by the Wiimote Core so we don't have to deal with it.
+ */
+
+static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext)
+{
+	__s32 x, y, z;
+
+	/*        |   8    7    6    5    4    3 |  2  |  1  |
+	 *   -----+------------------------------+-----+-----+
+	 *    1   |               Yaw Speed <7:0>            |
+	 *    2   |              Roll Speed <7:0>            |
+	 *    3   |             Pitch Speed <7:0>            |
+	 *   -----+------------------------------+-----+-----+
+	 *    4   |       Yaw Speed <13:8>       | Yaw |Pitch|
+	 *   -----+------------------------------+-----+-----+
+	 *    5   |      Roll Speed <13:8>       |Roll | Ext |
+	 *   -----+------------------------------+-----+-----+
+	 *    6   |     Pitch Speed <13:8>       |  1  |  0  |
+	 *   -----+------------------------------+-----+-----+
+	 * The single bits Yaw, Roll, Pitch in the lower right corner specify
+	 * whether the wiimote is rotating fast (0) or slow (1). Speed for slow
+	 * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a
+	 * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast
+	 * and 9 for slow.
+	 * If the wiimote is not rotating the sensor reports 2^13 = 8192.
+	 * Ext specifies whether an extension is connected to the motionp.
+	 * which is parsed by wiimote-core.
+	 */
+
+	x = ext[0];
+	y = ext[1];
+	z = ext[2];
+
+	x |= (((__u16)ext[3]) << 6) & 0xff00;
+	y |= (((__u16)ext[4]) << 6) & 0xff00;
+	z |= (((__u16)ext[5]) << 6) & 0xff00;
+
+	x -= 8192;
+	y -= 8192;
+	z -= 8192;
+
+	if (!(ext[3] & 0x02))
+		x *= 18;
+	else
+		x *= 9;
+	if (!(ext[4] & 0x02))
+		y *= 18;
+	else
+		y *= 9;
+	if (!(ext[3] & 0x01))
+		z *= 18;
+	else
+		z *= 9;
+
+	input_report_abs(wdata->mp, ABS_RX, x);
+	input_report_abs(wdata->mp, ABS_RY, y);
+	input_report_abs(wdata->mp, ABS_RZ, z);
+	input_sync(wdata->mp);
+}
+
+static int wiimod_mp_open(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags |= WIIPROTO_FLAG_MP_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	__wiimote_schedule(wdata);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	return 0;
+}
+
+static void wiimod_mp_close(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED;
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+	__wiimote_schedule(wdata);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+}
+
+static int wiimod_mp_probe(const struct wiimod_ops *ops,
+			   struct wiimote_data *wdata)
+{
+	int ret;
+
+	wdata->mp = input_allocate_device();
+	if (!wdata->mp)
+		return -ENOMEM;
+
+	input_set_drvdata(wdata->mp, wdata);
+	wdata->mp->open = wiimod_mp_open;
+	wdata->mp->close = wiimod_mp_close;
+	wdata->mp->dev.parent = &wdata->hdev->dev;
+	wdata->mp->id.bustype = wdata->hdev->bus;
+	wdata->mp->id.vendor = wdata->hdev->vendor;
+	wdata->mp->id.product = wdata->hdev->product;
+	wdata->mp->id.version = wdata->hdev->version;
+	wdata->mp->name = WIIMOTE_NAME " Motion Plus";
+
+	set_bit(EV_ABS, wdata->mp->evbit);
+	set_bit(ABS_RX, wdata->mp->absbit);
+	set_bit(ABS_RY, wdata->mp->absbit);
+	set_bit(ABS_RZ, wdata->mp->absbit);
+	input_set_abs_params(wdata->mp,
+			     ABS_RX, -16000, 16000, 4, 8);
+	input_set_abs_params(wdata->mp,
+			     ABS_RY, -16000, 16000, 4, 8);
+	input_set_abs_params(wdata->mp,
+			     ABS_RZ, -16000, 16000, 4, 8);
+
+	ret = input_register_device(wdata->mp);
+	if (ret)
+		goto err_free;
+
+	return 0;
+
+err_free:
+	input_free_device(wdata->mp);
+	wdata->mp = NULL;
+	return ret;
+}
+
+static void wiimod_mp_remove(const struct wiimod_ops *ops,
+			     struct wiimote_data *wdata)
+{
+	if (!wdata->mp)
+		return;
+
+	input_unregister_device(wdata->mp);
+	wdata->mp = NULL;
+}
+
+const struct wiimod_ops wiimod_mp = {
+	.flags = 0,
+	.arg = 0,
+	.probe = wiimod_mp_probe,
+	.remove = wiimod_mp_remove,
+	.in_mp = wiimod_mp_in_mp,
+};
+
+/* module table */
+
+static const struct wiimod_ops wiimod_dummy;
+
+const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = {
+	[WIIMOD_KEYS] = &wiimod_keys,
+	[WIIMOD_RUMBLE] = &wiimod_rumble,
+	[WIIMOD_BATTERY] = &wiimod_battery,
+	[WIIMOD_LED1] = &wiimod_leds[0],
+	[WIIMOD_LED2] = &wiimod_leds[1],
+	[WIIMOD_LED3] = &wiimod_leds[2],
+	[WIIMOD_LED4] = &wiimod_leds[3],
+	[WIIMOD_ACCEL] = &wiimod_accel,
+	[WIIMOD_IR] = &wiimod_ir,
+	[WIIMOD_BUILTIN_MP] = &wiimod_builtin_mp,
+	[WIIMOD_NO_MP] = &wiimod_no_mp,
+};
+
+const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = {
+	[WIIMOTE_EXT_NONE] = &wiimod_dummy,
+	[WIIMOTE_EXT_UNKNOWN] = &wiimod_dummy,
+	[WIIMOTE_EXT_NUNCHUK] = &wiimod_nunchuk,
+	[WIIMOTE_EXT_CLASSIC_CONTROLLER] = &wiimod_classic,
+	[WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard,
+	[WIIMOTE_EXT_PRO_CONTROLLER] = &wiimod_pro,
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/i2c-hid/i2c-hid.c linux-libre-3.11-rc7-gnu/drivers/hid/i2c-hid/i2c-hid.c
--- linux-libre-3.10-gnu/drivers/hid/i2c-hid/i2c-hid.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/i2c-hid/i2c-hid.c	2013-08-25 20:43:22.000000000 -0400
@@ -108,6 +108,7 @@ static const struct i2c_hid_cmd hid_rese
 static const struct i2c_hid_cmd hid_get_report_cmd =	{ I2C_HID_CMD(0x02) };
 static const struct i2c_hid_cmd hid_set_report_cmd =	{ I2C_HID_CMD(0x03) };
 static const struct i2c_hid_cmd hid_set_power_cmd =	{ I2C_HID_CMD(0x08) };
+static const struct i2c_hid_cmd hid_no_cmd =		{ .length = 0 };
 
 /*
  * These definitions are not used here, but are defined by the spec.
@@ -259,8 +260,11 @@ static int i2c_hid_set_report(struct i2c
 {
 	struct i2c_hid *ihid = i2c_get_clientdata(client);
 	u8 *args = ihid->argsbuf;
+	const struct i2c_hid_cmd * hidcmd = &hid_set_report_cmd;
 	int ret;
 	u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister);
+	u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister);
+	u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength);
 
 	/* hidraw already checked that data_len < HID_MAX_BUFFER_SIZE */
 	u16 size =	2			/* size */ +
@@ -278,8 +282,18 @@ static int i2c_hid_set_report(struct i2c
 		reportID = 0x0F;
 	}
 
-	args[index++] = dataRegister & 0xFF;
-	args[index++] = dataRegister >> 8;
+	/*
+	 * use the data register for feature reports or if the device does not
+	 * support the output register
+	 */
+	if (reportType == 0x03 || maxOutputLength == 0) {
+		args[index++] = dataRegister & 0xFF;
+		args[index++] = dataRegister >> 8;
+	} else {
+		args[index++] = outputRegister & 0xFF;
+		args[index++] = outputRegister >> 8;
+		hidcmd = &hid_no_cmd;
+	}
 
 	args[index++] = size & 0xFF;
 	args[index++] = size >> 8;
@@ -289,7 +303,7 @@ static int i2c_hid_set_report(struct i2c
 
 	memcpy(&args[index], buf, data_len);
 
-	ret = __i2c_hid_command(client, &hid_set_report_cmd, reportID,
+	ret = __i2c_hid_command(client, hidcmd, reportID,
 		reportType, args, args_len, NULL, 0);
 	if (ret) {
 		dev_err(&client->dev, "failed to set a report to device.\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/Kconfig linux-libre-3.11-rc7-gnu/drivers/hid/Kconfig
--- linux-libre-3.10-gnu/drivers/hid/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -217,6 +217,13 @@ config HID_ELECOM
 	---help---
 	Support for the ELECOM BM084 (bluetooth mouse).
 
+config HID_ELO
+	tristate "ELO USB 4000/4500 touchscreen"
+	depends on USB_HID
+	---help---
+	Support for the ELO USB 4000/4500 touchscreens. Note that this is for
+	different devices than those handled by CONFIG_TOUCHSCREEN_USB_ELO.
+
 config HID_EZKEY
 	tristate "Ezkey BTC 8193 keyboard" if EXPERT
 	depends on HID
@@ -231,6 +238,9 @@ config HID_HOLTEK
 	Support for Holtek based devices:
 	  - Holtek On Line Grip based game controller
 	  - Trust GXT 18 Gaming Keyboard
+	  - Sharkoon Drakonia / Perixx MX-2000 gaming mice
+	  - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 /
+	    Zalman ZM-GM1
 
 config HOLTEK_FF
 	bool "Holtek On Line Grip force feedback support"
@@ -240,6 +250,12 @@ config HOLTEK_FF
 	  Say Y here if you have a Holtek On Line Grip based game controller
 	  and want to have force feedback support for it.
 
+config HID_HUION
+	tristate "Huion tablets"
+	depends on USB_HID
+	---help---
+	Support for Huion 580 tablet.
+
 config HID_KEYTOUCH
 	tristate "Keytouch HID devices"
 	depends on HID
@@ -561,15 +577,6 @@ config HID_PRIMAX
 	Support for Primax devices that are not fully compliant with the
 	HID standard.
 
-config HID_PS3REMOTE
-	tristate "Sony PS3 BD Remote Control"
-	depends on HID
-	---help---
-	Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech
-	Harmony Adapter for PS3, which connect over Bluetooth.
-
-	Support for the 6-axis controllers is provided by HID_SONY.
-
 config HID_ROCCAT
 	tristate "Roccat device support"
 	depends on USB_HID
@@ -594,12 +601,17 @@ config HID_SAMSUNG
 	Support for Samsung InfraRed remote control or keyboards.
 
 config HID_SONY
-	tristate "Sony PS3 controller"
+	tristate "Sony PS2/3 accessories"
 	depends on USB_HID
+	depends on NEW_LEDS
+	depends on LEDS_CLASS
 	---help---
-	Support for Sony PS3 6-axis controllers.
+	Support for
 
-	Support for the Sony PS3 BD Remote is provided by HID_PS3REMOTE.
+	  * Sony PS3 6-axis controllers
+	  * Buzz controllers
+	  * Sony PS3 Blue-ray Disk Remote Control (Bluetooth)
+	  * Logitech Harmony adapter for Sony Playstation 3 (Bluetooth)
 
 config HID_SPEEDLINK
 	tristate "Speedlink VAD Cezanne mouse support"
@@ -707,22 +719,29 @@ config HID_WACOM
 	Support for Wacom Graphire Bluetooth and Intuos4 WL tablets.
 
 config HID_WIIMOTE
-	tristate "Nintendo Wii Remote support"
+	tristate "Nintendo Wii / Wii U peripherals"
 	depends on HID
 	depends on LEDS_CLASS
 	select POWER_SUPPLY
 	select INPUT_FF_MEMLESS
 	---help---
-	Support for the Nintendo Wii Remote bluetooth device.
+	Support for Nintendo Wii and Wii U Bluetooth peripherals. Supported
+	devices are the Wii Remote and its extension devices, but also devices
+	based on the Wii Remote like the Wii U Pro Controller or the
+	Wii Balance Board.
 
-config HID_WIIMOTE_EXT
-	bool "Nintendo Wii Remote Extension support"
-	depends on HID_WIIMOTE
-	default HID_WIIMOTE
-	---help---
-	Support for extension controllers of the Nintendo Wii Remote. Say yes
-	here if you want to use the Nintendo Motion+, Nunchuck or Classic
-	extension controllers with your Wii Remote.
+	Support for all official Nintendo extensions is available, however, 3rd
+	party extensions might not be supported. Please report these devices to:
+	  http://github.com/dvdhrm/xwiimote/issues
+
+	Other Nintendo Wii U peripherals that are IEEE 802.11 based (including
+	the Wii U Gamepad) might be supported in the future. But currently
+	support is limited to Bluetooth based devices.
+
+	If unsure, say N.
+
+	To compile this driver as a module, choose M here: the
+	module will be called hid-wiimote.
 
 config HID_ZEROPLUS
 	tristate "Zeroplus based game controller support"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hid/Makefile linux-libre-3.11-rc7-gnu/drivers/hid/Makefile
--- linux-libre-3.10-gnu/drivers/hid/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hid/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -28,10 +28,7 @@ ifdef CONFIG_LOGIWHEELS_FF
 	hid-logitech-y	+= hid-lg4ff.o
 endif
 
-hid-wiimote-y		:= hid-wiimote-core.o
-ifdef CONFIG_HID_WIIMOTE_EXT
-	hid-wiimote-y	+= hid-wiimote-ext.o
-endif
+hid-wiimote-y		:= hid-wiimote-core.o hid-wiimote-modules.o
 ifdef CONFIG_DEBUG_FS
 	hid-wiimote-y	+= hid-wiimote-debug.o
 endif
@@ -48,10 +45,13 @@ obj-$(CONFIG_HID_CYPRESS)	+= hid-cypress
 obj-$(CONFIG_HID_DRAGONRISE)	+= hid-dr.o
 obj-$(CONFIG_HID_EMS_FF)	+= hid-emsff.o
 obj-$(CONFIG_HID_ELECOM)	+= hid-elecom.o
+obj-$(CONFIG_HID_ELO)		+= hid-elo.o
 obj-$(CONFIG_HID_EZKEY)		+= hid-ezkey.o
 obj-$(CONFIG_HID_GYRATION)	+= hid-gyration.o
 obj-$(CONFIG_HID_HOLTEK)	+= hid-holtek-kbd.o
+obj-$(CONFIG_HID_HOLTEK)	+= hid-holtek-mouse.o
 obj-$(CONFIG_HID_HOLTEK)	+= hid-holtekff.o
+obj-$(CONFIG_HID_HUION)		+= hid-huion.o
 obj-$(CONFIG_HID_HYPERV_MOUSE)	+= hid-hyperv.o
 obj-$(CONFIG_HID_ICADE)		+= hid-icade.o
 obj-$(CONFIG_HID_KENSINGTON)	+= hid-kensington.o
@@ -92,7 +92,6 @@ hid-picolcd-y			+= hid-picolcd_debugfs.o
 endif
 
 obj-$(CONFIG_HID_PRIMAX)	+= hid-primax.o
-obj-$(CONFIG_HID_PS3REMOTE)	+= hid-ps3remote.o
 obj-$(CONFIG_HID_ROCCAT)	+= hid-roccat.o hid-roccat-common.o \
 	hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
 	hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hsi/hsi.c linux-libre-3.11-rc7-gnu/drivers/hsi/hsi.c
--- linux-libre-3.10-gnu/drivers/hsi/hsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hsi/hsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,7 +75,7 @@ static void hsi_new_client(struct hsi_po
 	cl->device.bus = &hsi_bus_type;
 	cl->device.parent = &port->device;
 	cl->device.release = hsi_client_release;
-	dev_set_name(&cl->device, info->name);
+	dev_set_name(&cl->device, "%s", info->name);
 	cl->device.platform_data = info->platform_data;
 	if (info->archdata)
 		cl->device.archdata = *info->archdata;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hv/channel.c linux-libre-3.11-rc7-gnu/drivers/hv/channel.c
--- linux-libre-3.10-gnu/drivers/hv/channel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hv/channel.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,6 +116,15 @@ int vmbus_open(struct vmbus_channel *new
 	unsigned long flags;
 	int ret, t, err = 0;
 
+	spin_lock_irqsave(&newchannel->sc_lock, flags);
+	if (newchannel->state == CHANNEL_OPEN_STATE) {
+		newchannel->state = CHANNEL_OPENING_STATE;
+	} else {
+		spin_unlock_irqrestore(&newchannel->sc_lock, flags);
+		return -EINVAL;
+	}
+	spin_unlock_irqrestore(&newchannel->sc_lock, flags);
+
 	newchannel->onchannel_callback = onchannelcallback;
 	newchannel->channel_callback_context = context;
 
@@ -216,6 +225,9 @@ int vmbus_open(struct vmbus_channel *new
 	list_del(&open_info->msglistentry);
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
 
+	if (err == 0)
+		newchannel->state = CHANNEL_OPENED_STATE;
+
 	kfree(open_info);
 	return err;
 
@@ -500,15 +512,14 @@ int vmbus_teardown_gpadl(struct vmbus_ch
 }
 EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
 
-/*
- * vmbus_close - Close the specified channel
- */
-void vmbus_close(struct vmbus_channel *channel)
+static void vmbus_close_internal(struct vmbus_channel *channel)
 {
 	struct vmbus_channel_close_channel *msg;
 	int ret;
 	unsigned long flags;
 
+	channel->state = CHANNEL_OPEN_STATE;
+	channel->sc_creation_callback = NULL;
 	/* Stop callback and cancel the timer asap */
 	spin_lock_irqsave(&channel->inbound_lock, flags);
 	channel->onchannel_callback = NULL;
@@ -538,6 +549,37 @@ void vmbus_close(struct vmbus_channel *c
 
 
 }
+
+/*
+ * vmbus_close - Close the specified channel
+ */
+void vmbus_close(struct vmbus_channel *channel)
+{
+	struct list_head *cur, *tmp;
+	struct vmbus_channel *cur_channel;
+
+	if (channel->primary_channel != NULL) {
+		/*
+		 * We will only close sub-channels when
+		 * the primary is closed.
+		 */
+		return;
+	}
+	/*
+	 * Close all the sub-channels first and then close the
+	 * primary channel.
+	 */
+	list_for_each_safe(cur, tmp, &channel->sc_list) {
+		cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
+		if (cur_channel->state != CHANNEL_OPENED_STATE)
+			continue;
+		vmbus_close_internal(cur_channel);
+	}
+	/*
+	 * Now close the primary.
+	 */
+	vmbus_close_internal(channel);
+}
 EXPORT_SYMBOL_GPL(vmbus_close);
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hv/channel_mgmt.c linux-libre-3.11-rc7-gnu/drivers/hv/channel_mgmt.c
--- linux-libre-3.10-gnu/drivers/hv/channel_mgmt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hv/channel_mgmt.c	2013-08-25 20:43:22.000000000 -0400
@@ -115,6 +115,9 @@ static struct vmbus_channel *alloc_chann
 		return NULL;
 
 	spin_lock_init(&channel->inbound_lock);
+	spin_lock_init(&channel->sc_lock);
+
+	INIT_LIST_HEAD(&channel->sc_list);
 
 	channel->controlwq = create_workqueue("hv_vmbus_ctl");
 	if (!channel->controlwq) {
@@ -166,6 +169,7 @@ static void vmbus_process_rescind_offer(
 						     struct vmbus_channel,
 						     work);
 	unsigned long flags;
+	struct vmbus_channel *primary_channel;
 	struct vmbus_channel_relid_released msg;
 
 	vmbus_device_unregister(channel->device_obj);
@@ -174,9 +178,16 @@ static void vmbus_process_rescind_offer(
 	msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
 	vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released));
 
-	spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
-	list_del(&channel->listentry);
-	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
+	if (channel->primary_channel == NULL) {
+		spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
+		list_del(&channel->listentry);
+		spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
+	} else {
+		primary_channel = channel->primary_channel;
+		spin_lock_irqsave(&primary_channel->sc_lock, flags);
+		list_del(&channel->listentry);
+		spin_unlock_irqrestore(&primary_channel->sc_lock, flags);
+	}
 	free_channel(channel);
 }
 
@@ -228,6 +239,24 @@ static void vmbus_process_offer(struct w
 	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
 
 	if (!fnew) {
+		/*
+		 * Check to see if this is a sub-channel.
+		 */
+		if (newchannel->offermsg.offer.sub_channel_index != 0) {
+			/*
+			 * Process the sub-channel.
+			 */
+			newchannel->primary_channel = channel;
+			spin_lock_irqsave(&channel->sc_lock, flags);
+			list_add_tail(&newchannel->sc_list, &channel->sc_list);
+			spin_unlock_irqrestore(&channel->sc_lock, flags);
+			newchannel->state = CHANNEL_OPEN_STATE;
+			if (channel->sc_creation_callback != NULL)
+				channel->sc_creation_callback(newchannel);
+
+			return;
+		}
+
 		free_channel(newchannel);
 		return;
 	}
@@ -685,4 +714,86 @@ cleanup:
 	return ret;
 }
 
-/* eof */
+/*
+ * Retrieve the (sub) channel on which to send an outgoing request.
+ * When a primary channel has multiple sub-channels, we choose a
+ * channel whose VCPU binding is closest to the VCPU on which
+ * this call is being made.
+ */
+struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
+{
+	struct list_head *cur, *tmp;
+	int cur_cpu = hv_context.vp_index[smp_processor_id()];
+	struct vmbus_channel *cur_channel;
+	struct vmbus_channel *outgoing_channel = primary;
+	int cpu_distance, new_cpu_distance;
+
+	if (list_empty(&primary->sc_list))
+		return outgoing_channel;
+
+	list_for_each_safe(cur, tmp, &primary->sc_list) {
+		cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
+		if (cur_channel->state != CHANNEL_OPENED_STATE)
+			continue;
+
+		if (cur_channel->target_vp == cur_cpu)
+			return cur_channel;
+
+		cpu_distance = ((outgoing_channel->target_vp > cur_cpu) ?
+				(outgoing_channel->target_vp - cur_cpu) :
+				(cur_cpu - outgoing_channel->target_vp));
+
+		new_cpu_distance = ((cur_channel->target_vp > cur_cpu) ?
+				(cur_channel->target_vp - cur_cpu) :
+				(cur_cpu - cur_channel->target_vp));
+
+		if (cpu_distance < new_cpu_distance)
+			continue;
+
+		outgoing_channel = cur_channel;
+	}
+
+	return outgoing_channel;
+}
+EXPORT_SYMBOL_GPL(vmbus_get_outgoing_channel);
+
+static void invoke_sc_cb(struct vmbus_channel *primary_channel)
+{
+	struct list_head *cur, *tmp;
+	struct vmbus_channel *cur_channel;
+
+	if (primary_channel->sc_creation_callback == NULL)
+		return;
+
+	list_for_each_safe(cur, tmp, &primary_channel->sc_list) {
+		cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
+
+		primary_channel->sc_creation_callback(cur_channel);
+	}
+}
+
+void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel,
+				void (*sc_cr_cb)(struct vmbus_channel *new_sc))
+{
+	primary_channel->sc_creation_callback = sc_cr_cb;
+}
+EXPORT_SYMBOL_GPL(vmbus_set_sc_create_callback);
+
+bool vmbus_are_subchannels_present(struct vmbus_channel *primary)
+{
+	bool ret;
+
+	ret = !list_empty(&primary->sc_list);
+
+	if (ret) {
+		/*
+		 * Invoke the callback on sub-channel creation.
+		 * This will present a uniform interface to the
+		 * clients.
+		 */
+		invoke_sc_cb(primary);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(vmbus_are_subchannels_present);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hv/connection.c linux-libre-3.11-rc7-gnu/drivers/hv/connection.c
--- linux-libre-3.10-gnu/drivers/hv/connection.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hv/connection.c	2013-08-25 20:43:22.000000000 -0400
@@ -246,12 +246,26 @@ struct vmbus_channel *relid2channel(u32
 	struct vmbus_channel *channel;
 	struct vmbus_channel *found_channel  = NULL;
 	unsigned long flags;
+	struct list_head *cur, *tmp;
+	struct vmbus_channel *cur_sc;
 
 	spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
 	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
 		if (channel->offermsg.child_relid == relid) {
 			found_channel = channel;
 			break;
+		} else if (!list_empty(&channel->sc_list)) {
+			/*
+			 * Deal with sub-channels.
+			 */
+			list_for_each_safe(cur, tmp, &channel->sc_list) {
+				cur_sc = list_entry(cur, struct vmbus_channel,
+							sc_list);
+				if (cur_sc->offermsg.child_relid == relid) {
+					found_channel = cur_sc;
+					break;
+				}
+			}
 		}
 	}
 	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hv/hv_balloon.c linux-libre-3.11-rc7-gnu/drivers/hv/hv_balloon.c
--- linux-libre-3.10-gnu/drivers/hv/hv_balloon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hv/hv_balloon.c	2013-08-25 20:43:22.000000000 -0400
@@ -562,7 +562,7 @@ static void hv_mem_hot_add(unsigned long
 				struct hv_hotadd_state *has)
 {
 	int ret = 0;
-	int i, nid, t;
+	int i, nid;
 	unsigned long start_pfn;
 	unsigned long processed_pfn;
 	unsigned long total_pfn = pfn_count;
@@ -607,14 +607,11 @@ static void hv_mem_hot_add(unsigned long
 
 		/*
 		 * Wait for the memory block to be onlined.
+		 * Since the hot add has succeeded, it is ok to
+		 * proceed even if the pages in the hot added region
+		 * have not been "onlined" within the allowed time.
 		 */
-		t = wait_for_completion_timeout(&dm_device.ol_waitevent, 5*HZ);
-		if (t == 0) {
-			pr_info("hot_add memory timedout\n");
-			has->ha_end_pfn -= HA_CHUNK;
-			has->covered_end_pfn -=  processed_pfn;
-			break;
-		}
+		wait_for_completion_timeout(&dm_device.ol_waitevent, 5*HZ);
 
 	}
 
@@ -978,6 +975,14 @@ static void post_status(struct hv_dynmem
 				dm->num_pages_ballooned +
 				compute_balloon_floor();
 
+	/*
+	 * If our transaction ID is no longer current, just don't
+	 * send the status. This can happen if we were interrupted
+	 * after we picked our transaction ID.
+	 */
+	if (status.hdr.trans_id != atomic_read(&trans_id))
+		return;
+
 	vmbus_sendpacket(dm->dev->channel, &status,
 				sizeof(struct dm_status),
 				(unsigned long)NULL,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hv/hv.c linux-libre-3.11-rc7-gnu/drivers/hv/hv.c
--- linux-libre-3.10-gnu/drivers/hv/hv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hv/hv.c	2013-08-25 20:43:22.000000000 -0400
@@ -265,6 +265,59 @@ u16 hv_signal_event(void *con_id)
 	return status;
 }
 
+
+int hv_synic_alloc(void)
+{
+	size_t size = sizeof(struct tasklet_struct);
+	int cpu;
+
+	for_each_online_cpu(cpu) {
+		hv_context.event_dpc[cpu] = kmalloc(size, GFP_ATOMIC);
+		if (hv_context.event_dpc[cpu] == NULL) {
+			pr_err("Unable to allocate event dpc\n");
+			goto err;
+		}
+		tasklet_init(hv_context.event_dpc[cpu], vmbus_on_event, cpu);
+
+		hv_context.synic_message_page[cpu] =
+			(void *)get_zeroed_page(GFP_ATOMIC);
+
+		if (hv_context.synic_message_page[cpu] == NULL) {
+			pr_err("Unable to allocate SYNIC message page\n");
+			goto err;
+		}
+
+		hv_context.synic_event_page[cpu] =
+			(void *)get_zeroed_page(GFP_ATOMIC);
+
+		if (hv_context.synic_event_page[cpu] == NULL) {
+			pr_err("Unable to allocate SYNIC event page\n");
+			goto err;
+		}
+	}
+
+	return 0;
+err:
+	return -ENOMEM;
+}
+
+void hv_synic_free_cpu(int cpu)
+{
+	kfree(hv_context.event_dpc[cpu]);
+	if (hv_context.synic_message_page[cpu])
+		free_page((unsigned long)hv_context.synic_event_page[cpu]);
+	if (hv_context.synic_message_page[cpu])
+		free_page((unsigned long)hv_context.synic_message_page[cpu]);
+}
+
+void hv_synic_free(void)
+{
+	int cpu;
+
+	for_each_online_cpu(cpu)
+		hv_synic_free_cpu(cpu);
+}
+
 /*
  * hv_synic_init - Initialize the Synthethic Interrupt Controller.
  *
@@ -289,30 +342,6 @@ void hv_synic_init(void *arg)
 	/* Check the version */
 	rdmsrl(HV_X64_MSR_SVERSION, version);
 
-	hv_context.event_dpc[cpu] = kmalloc(sizeof(struct tasklet_struct),
-					    GFP_ATOMIC);
-	if (hv_context.event_dpc[cpu] == NULL) {
-		pr_err("Unable to allocate event dpc\n");
-		goto cleanup;
-	}
-	tasklet_init(hv_context.event_dpc[cpu], vmbus_on_event, cpu);
-
-	hv_context.synic_message_page[cpu] =
-		(void *)get_zeroed_page(GFP_ATOMIC);
-
-	if (hv_context.synic_message_page[cpu] == NULL) {
-		pr_err("Unable to allocate SYNIC message page\n");
-		goto cleanup;
-	}
-
-	hv_context.synic_event_page[cpu] =
-		(void *)get_zeroed_page(GFP_ATOMIC);
-
-	if (hv_context.synic_event_page[cpu] == NULL) {
-		pr_err("Unable to allocate SYNIC event page\n");
-		goto cleanup;
-	}
-
 	/* Setup the Synic's message page */
 	rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
 	simp.simp_enabled = 1;
@@ -355,14 +384,6 @@ void hv_synic_init(void *arg)
 	rdmsrl(HV_X64_MSR_VP_INDEX, vp_index);
 	hv_context.vp_index[cpu] = (u32)vp_index;
 	return;
-
-cleanup:
-	if (hv_context.synic_event_page[cpu])
-		free_page((unsigned long)hv_context.synic_event_page[cpu]);
-
-	if (hv_context.synic_message_page[cpu])
-		free_page((unsigned long)hv_context.synic_message_page[cpu]);
-	return;
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hv/hyperv_vmbus.h linux-libre-3.11-rc7-gnu/drivers/hv/hyperv_vmbus.h
--- linux-libre-3.10-gnu/drivers/hv/hyperv_vmbus.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hv/hyperv_vmbus.h	2013-08-25 20:43:22.000000000 -0400
@@ -527,6 +527,10 @@ extern int hv_post_message(union hv_conn
 
 extern u16 hv_signal_event(void *con_id);
 
+extern int hv_synic_alloc(void);
+
+extern void hv_synic_free(void);
+
 extern void hv_synic_init(void *irqarg);
 
 extern void hv_synic_cleanup(void *arg);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hv/ring_buffer.c linux-libre-3.11-rc7-gnu/drivers/hv/ring_buffer.c
--- linux-libre-3.10-gnu/drivers/hv/ring_buffer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hv/ring_buffer.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,7 @@
 void hv_begin_read(struct hv_ring_buffer_info *rbi)
 {
 	rbi->ring_buffer->interrupt_mask = 1;
-	smp_mb();
+	mb();
 }
 
 u32 hv_end_read(struct hv_ring_buffer_info *rbi)
@@ -41,7 +41,7 @@ u32 hv_end_read(struct hv_ring_buffer_in
 	u32 write;
 
 	rbi->ring_buffer->interrupt_mask = 0;
-	smp_mb();
+	mb();
 
 	/*
 	 * Now check to see if the ring buffer is still empty.
@@ -71,10 +71,12 @@ u32 hv_end_read(struct hv_ring_buffer_in
 
 static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi)
 {
-	smp_mb();
+	mb();
 	if (rbi->ring_buffer->interrupt_mask)
 		return false;
 
+	/* check interrupt_mask before read_index */
+	rmb();
 	/*
 	 * This is the only case we need to signal when the
 	 * ring transitions from being empty to non-empty.
@@ -442,7 +444,7 @@ int hv_ringbuffer_write(struct hv_ring_b
 					     sizeof(u64));
 
 	/* Issue a full memory barrier before updating the write index */
-	smp_mb();
+	mb();
 
 	/* Now, update the write location */
 	hv_set_next_write_location(outring_info, next_write_location);
@@ -549,7 +551,7 @@ int hv_ringbuffer_read(struct hv_ring_bu
 	/* Make sure all reads are done before we update the read index since */
 	/* the writer may start writing to the read area once the read index */
 	/*is updated */
-	smp_mb();
+	mb();
 
 	/* Update the read index */
 	hv_set_next_read_location(inring_info, next_read_location);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hv/vmbus_drv.c linux-libre-3.11-rc7-gnu/drivers/hv/vmbus_drv.c
--- linux-libre-3.10-gnu/drivers/hv/vmbus_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hv/vmbus_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -434,7 +434,7 @@ static void vmbus_on_msg_dpc(unsigned lo
 		 * will not deliver any more messages since there is
 		 * no empty slot
 		 */
-		smp_mb();
+		mb();
 
 		if (msg->header.message_flags.msg_pending) {
 			/*
@@ -563,6 +563,9 @@ static int vmbus_bus_init(int irq)
 	 */
 	hv_register_vmbus_handler(irq, vmbus_isr);
 
+	ret = hv_synic_alloc();
+	if (ret)
+		goto err_alloc;
 	/*
 	 * Initialize the per-cpu interrupt state and
 	 * connect to the host.
@@ -570,13 +573,14 @@ static int vmbus_bus_init(int irq)
 	on_each_cpu(hv_synic_init, NULL, 1);
 	ret = vmbus_connect();
 	if (ret)
-		goto err_irq;
+		goto err_alloc;
 
 	vmbus_request_offers();
 
 	return 0;
 
-err_irq:
+err_alloc:
+	hv_synic_free();
 	free_irq(irq, hv_acpi_dev);
 
 err_unregister:
@@ -686,7 +690,7 @@ int vmbus_device_register(struct hv_devi
 	if (ret)
 		pr_err("Unable to register child device\n");
 	else
-		pr_info("child device %s registered\n",
+		pr_debug("child device %s registered\n",
 			dev_name(&child_device_obj->device));
 
 	return ret;
@@ -698,14 +702,14 @@ int vmbus_device_register(struct hv_devi
  */
 void vmbus_device_unregister(struct hv_device *device_obj)
 {
+	pr_debug("child device %s unregistered\n",
+		dev_name(&device_obj->device));
+
 	/*
 	 * Kick off the process of unregistering the device.
 	 * This will call vmbus_remove() and eventually vmbus_device_release()
 	 */
 	device_unregister(&device_obj->device);
-
-	pr_info("child device %s unregistered\n",
-		dev_name(&device_obj->device));
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/abituguru3.c linux-libre-3.11-rc7-gnu/drivers/hwmon/abituguru3.c
--- linux-libre-3.10-gnu/drivers/hwmon/abituguru3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/abituguru3.c	2013-08-25 20:43:22.000000000 -0400
@@ -1079,7 +1079,6 @@ static int abituguru3_remove(struct plat
 	int i;
 	struct abituguru3_data *data = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	hwmon_device_unregister(data->hwmon_dev);
 	for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++)
 		device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/abx500.c linux-libre-3.11-rc7-gnu/drivers/hwmon/abx500.c
--- linux-libre-3.10-gnu/drivers/hwmon/abx500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/abx500.c	2013-08-25 20:43:22.000000000 -0400
@@ -315,7 +315,7 @@ static SENSOR_DEVICE_ATTR(temp4_max_hyst
 static SENSOR_DEVICE_ATTR(temp4_min_alarm, S_IRUGO, show_min_alarm, NULL, 3);
 static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_max_alarm, NULL, 3);
 
-struct attribute *abx500_temp_attributes[] = {
+static struct attribute *abx500_temp_attributes[] = {
 	&sensor_dev_attr_name.dev_attr.attr,
 
 	&sensor_dev_attr_temp1_label.dev_attr.attr,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/adm1021.c linux-libre-3.11-rc7-gnu/drivers/hwmon/adm1021.c
--- linux-libre-3.10-gnu/drivers/hwmon/adm1021.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/adm1021.c	2013-08-25 20:43:22.000000000 -0400
@@ -284,15 +284,11 @@ static DEVICE_ATTR(low_power, S_IWUSR |
 
 static struct attribute *adm1021_attributes[] = {
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
-	&sensor_dev_attr_temp1_min.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp2_max.dev_attr.attr,
-	&sensor_dev_attr_temp2_min.dev_attr.attr,
 	&sensor_dev_attr_temp2_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
-	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
-	&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp2_fault.dev_attr.attr,
 	&dev_attr_alarms.attr,
 	&dev_attr_low_power.attr,
@@ -303,6 +299,18 @@ static const struct attribute_group adm1
 	.attrs = adm1021_attributes,
 };
 
+static struct attribute *adm1021_min_attributes[] = {
+	&sensor_dev_attr_temp1_min.dev_attr.attr,
+	&sensor_dev_attr_temp2_min.dev_attr.attr,
+	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adm1021_min_group = {
+	.attrs = adm1021_min_attributes,
+};
+
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int adm1021_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
@@ -425,6 +433,12 @@ static int adm1021_probe(struct i2c_clie
 	if (err)
 		return err;
 
+	if (data->type != lm84) {
+		err = sysfs_create_group(&client->dev.kobj, &adm1021_min_group);
+		if (err)
+			goto error;
+	}
+
 	data->hwmon_dev = hwmon_device_register(&client->dev);
 	if (IS_ERR(data->hwmon_dev)) {
 		err = PTR_ERR(data->hwmon_dev);
@@ -434,6 +448,7 @@ static int adm1021_probe(struct i2c_clie
 	return 0;
 
 error:
+	sysfs_remove_group(&client->dev.kobj, &adm1021_min_group);
 	sysfs_remove_group(&client->dev.kobj, &adm1021_group);
 	return err;
 }
@@ -452,6 +467,7 @@ static int adm1021_remove(struct i2c_cli
 	struct adm1021_data *data = i2c_get_clientdata(client);
 
 	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &adm1021_min_group);
 	sysfs_remove_group(&client->dev.kobj, &adm1021_group);
 
 	return 0;
@@ -477,9 +493,11 @@ static struct adm1021_data *adm1021_upda
 			data->temp_max[i] = 1000 *
 				(s8) i2c_smbus_read_byte_data(
 					client, ADM1021_REG_TOS_R(i));
-			data->temp_min[i] = 1000 *
-				(s8) i2c_smbus_read_byte_data(
-					client, ADM1021_REG_THYST_R(i));
+			if (data->type != lm84) {
+				data->temp_min[i] = 1000 *
+				  (s8) i2c_smbus_read_byte_data(client,
+							ADM1021_REG_THYST_R(i));
+			}
 		}
 		data->alarms = i2c_smbus_read_byte_data(client,
 						ADM1021_REG_STATUS) & 0x7c;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/adt7470.c linux-libre-3.11-rc7-gnu/drivers/hwmon/adt7470.c
--- linux-libre-3.10-gnu/drivers/hwmon/adt7470.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/adt7470.c	2013-08-25 20:43:22.000000000 -0400
@@ -215,7 +215,7 @@ static inline int adt7470_write_word_dat
 					  u16 value)
 {
 	return i2c_smbus_write_byte_data(client, reg, value & 0xFF)
-	       && i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
+	       || i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
 }
 
 static void adt7470_init_client(struct i2c_client *client)
@@ -1285,7 +1285,7 @@ static int adt7470_probe(struct i2c_clie
 	}
 
 	init_completion(&data->auto_update_stop);
-	data->auto_update = kthread_run(adt7470_update_thread, client,
+	data->auto_update = kthread_run(adt7470_update_thread, client, "%s",
 					dev_name(data->hwmon_dev));
 	if (IS_ERR(data->auto_update)) {
 		err = PTR_ERR(data->auto_update);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/coretemp.c linux-libre-3.11-rc7-gnu/drivers/hwmon/coretemp.c
--- linux-libre-3.10-gnu/drivers/hwmon/coretemp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/coretemp.c	2013-08-25 20:43:22.000000000 -0400
@@ -195,7 +195,7 @@ struct tjmax {
 	int tjmax;
 };
 
-static const struct tjmax __cpuinitconst tjmax_table[] = {
+static const struct tjmax tjmax_table[] = {
 	{ "CPU  230", 100000 },		/* Model 0x1c, stepping 2	*/
 	{ "CPU  330", 125000 },		/* Model 0x1c, stepping 2	*/
 	{ "CPU CE4110", 110000 },	/* Model 0x1c, stepping 10 Sodaville */
@@ -211,7 +211,7 @@ struct tjmax_model {
 
 #define ANY 0xff
 
-static const struct tjmax_model __cpuinitconst tjmax_model_table[] = {
+static const struct tjmax_model tjmax_model_table[] = {
 	{ 0x1c, 10, 100000 },	/* D4xx, K4xx, N4xx, D5xx, K5xx, N5xx */
 	{ 0x1c, ANY, 90000 },	/* Z5xx, N2xx, possibly others
 				 * Note: Also matches 230 and 330,
@@ -226,8 +226,7 @@ static const struct tjmax_model __cpuini
 	{ 0x36, ANY, 100000 },	/* Atom Cedar Trail/Cedarview (N2xxx, D2xxx) */
 };
 
-static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id,
-				  struct device *dev)
+static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
 {
 	/* The 100C is default for both mobile and non mobile CPUs */
 
@@ -317,8 +316,7 @@ static int __cpuinit adjust_tjmax(struct
 	return tjmax;
 }
 
-static int __cpuinit get_tjmax(struct cpuinfo_x86 *c, u32 id,
-			       struct device *dev)
+static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
 {
 	int err;
 	u32 eax, edx;
@@ -367,8 +365,8 @@ static int create_name_attr(struct platf
 	return device_create_file(dev, &pdata->name_attr);
 }
 
-static int __cpuinit create_core_attrs(struct temp_data *tdata,
-				       struct device *dev, int attr_no)
+static int create_core_attrs(struct temp_data *tdata, struct device *dev,
+			     int attr_no)
 {
 	int err, i;
 	static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev,
@@ -401,7 +399,7 @@ exit_free:
 }
 
 
-static int __cpuinit chk_ucode_version(unsigned int cpu)
+static int chk_ucode_version(unsigned int cpu)
 {
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
@@ -417,7 +415,7 @@ static int __cpuinit chk_ucode_version(u
 	return 0;
 }
 
-static struct platform_device __cpuinit *coretemp_get_pdev(unsigned int cpu)
+static struct platform_device *coretemp_get_pdev(unsigned int cpu)
 {
 	u16 phys_proc_id = TO_PHYS_ID(cpu);
 	struct pdev_entry *p;
@@ -434,8 +432,7 @@ static struct platform_device __cpuinit
 	return NULL;
 }
 
-static struct temp_data __cpuinit *init_temp_data(unsigned int cpu,
-						  int pkg_flag)
+static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag)
 {
 	struct temp_data *tdata;
 
@@ -453,8 +450,8 @@ static struct temp_data __cpuinit *init_
 	return tdata;
 }
 
-static int __cpuinit create_core_data(struct platform_device *pdev,
-				unsigned int cpu, int pkg_flag)
+static int create_core_data(struct platform_device *pdev, unsigned int cpu,
+			    int pkg_flag)
 {
 	struct temp_data *tdata;
 	struct platform_data *pdata = platform_get_drvdata(pdev);
@@ -524,7 +521,7 @@ exit_free:
 	return err;
 }
 
-static void __cpuinit coretemp_add_core(unsigned int cpu, int pkg_flag)
+static void coretemp_add_core(unsigned int cpu, int pkg_flag)
 {
 	struct platform_device *pdev = coretemp_get_pdev(cpu);
 	int err;
@@ -578,7 +575,6 @@ static int coretemp_probe(struct platfor
 
 exit_name:
 	device_remove_file(&pdev->dev, &pdata->name_attr);
-	platform_set_drvdata(pdev, NULL);
 exit_free:
 	kfree(pdata);
 	return err;
@@ -595,7 +591,6 @@ static int coretemp_remove(struct platfo
 
 	device_remove_file(&pdev->dev, &pdata->name_attr);
 	hwmon_device_unregister(pdata->hwmon_dev);
-	platform_set_drvdata(pdev, NULL);
 	kfree(pdata);
 	return 0;
 }
@@ -609,7 +604,7 @@ static struct platform_driver coretemp_d
 	.remove = coretemp_remove,
 };
 
-static int __cpuinit coretemp_device_add(unsigned int cpu)
+static int coretemp_device_add(unsigned int cpu)
 {
 	int err;
 	struct platform_device *pdev;
@@ -653,7 +648,7 @@ exit:
 	return err;
 }
 
-static void __cpuinit coretemp_device_remove(unsigned int cpu)
+static void coretemp_device_remove(unsigned int cpu)
 {
 	struct pdev_entry *p, *n;
 	u16 phys_proc_id = TO_PHYS_ID(cpu);
@@ -669,7 +664,7 @@ static void __cpuinit coretemp_device_re
 	mutex_unlock(&pdev_list_mutex);
 }
 
-static bool __cpuinit is_any_core_online(struct platform_data *pdata)
+static bool is_any_core_online(struct platform_data *pdata)
 {
 	int i;
 
@@ -683,7 +678,7 @@ static bool __cpuinit is_any_core_online
 	return false;
 }
 
-static void __cpuinit get_core_online(unsigned int cpu)
+static void get_core_online(unsigned int cpu)
 {
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	struct platform_device *pdev = coretemp_get_pdev(cpu);
@@ -725,7 +720,7 @@ static void __cpuinit get_core_online(un
 	coretemp_add_core(cpu, 0);
 }
 
-static void __cpuinit put_core_offline(unsigned int cpu)
+static void put_core_offline(unsigned int cpu)
 {
 	int i, indx;
 	struct platform_data *pdata;
@@ -773,7 +768,7 @@ static void __cpuinit put_core_offline(u
 		coretemp_device_remove(cpu);
 }
 
-static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb,
+static int coretemp_cpu_callback(struct notifier_block *nfb,
 				 unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long) hcpu;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/ds1621.c linux-libre-3.11-rc7-gnu/drivers/hwmon/ds1621.c
--- linux-libre-3.10-gnu/drivers/hwmon/ds1621.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/ds1621.c	2013-08-25 20:43:22.000000000 -0400
@@ -6,6 +6,19 @@
  * Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
  * the help of Jean Delvare <khali@linux-fr.org>
  *
+ * The DS1621 device is a digital temperature/thermometer with 9-bit
+ * resolution, a thermal alarm output (Tout), and user-defined minimum
+ * and maximum temperature thresholds (TH and TL).
+ *
+ * The DS1625, DS1631, DS1721, and DS1731 are pin compatible with the DS1621
+ * and similar in operation, with slight variations as noted in the device
+ * datasheets (please refer to www.maximintegrated.com for specific
+ * device information).
+ *
+ * Since the DS1621 was the first chipset supported by this driver,
+ * most comments will refer to this chipset, but are actually general
+ * and concern all supported chipsets, unless mentioned otherwise.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -31,27 +44,62 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
-#include "lm75.h"
+#include <linux/kernel.h>
 
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
-					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
+/* Supported devices */
+enum chips { ds1621, ds1625, ds1631, ds1721, ds1731 };
 
 /* Insmod parameters */
 static int polarity = -1;
 module_param(polarity, int, 0);
 MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low");
 
-/* Many DS1621 constants specified below */
-/* Config register used for detection         */
-/*  7    6    5    4    3    2    1    0      */
-/* |Done|THF |TLF |NVB | X  | X  |POL |1SHOT| */
+/*
+ * The Configuration/Status register
+ *
+ * - DS1621:
+ *   7    6    5    4    3    2    1    0
+ * |Done|THF |TLF |NVB | X  | X  |POL |1SHOT|
+ *
+ * - DS1625:
+ *   7    6    5    4    3    2    1    0
+ * |Done|THF |TLF |NVB | 1  | 0  |POL |1SHOT|
+ *
+ * - DS1631, DS1731:
+ *   7    6    5    4    3    2    1    0
+ * |Done|THF |TLF |NVB | R1 | R0 |POL |1SHOT|
+ *
+ * - DS1721:
+ *   7    6    5    4    3    2    1    0
+ * |Done| X  | X  | U  | R1 | R0 |POL |1SHOT|
+ *
+ * Where:
+ * - 'X' is Reserved
+ * - 'U' is Undefined
+ */
 #define DS1621_REG_CONFIG_NVB		0x10
+#define DS1621_REG_CONFIG_RESOL		0x0C
 #define DS1621_REG_CONFIG_POLARITY	0x02
 #define DS1621_REG_CONFIG_1SHOT		0x01
 #define DS1621_REG_CONFIG_DONE		0x80
 
-/* The DS1621 registers */
+#define DS1621_REG_CONFIG_RESOL_SHIFT	2
+
+/* ds1721 conversion rates: {C/LSB, time(ms), resolution bit setting} */
+static const unsigned short ds1721_convrates[] = {
+	94,	/*  9-bits (0.5,  93.75, RES[0..1] = 0 */
+	188,	/* 10-bits (0.25, 187.5, RES[0..1] = 1 */
+	375,	/* 11-bits (0.125,  375, RES[0..1] = 2 */
+	750,	/* 12-bits (0.0625, 750, RES[0..1] = 3 */
+};
+
+#define DS1621_CONVERSION_MAX	750
+#define DS1625_CONVERSION_MAX	500
+
+#define DS1621_TEMP_MAX	125000
+#define DS1621_TEMP_MIN	(-55000)
+
+/* The DS1621 temperature registers */
 static const u8 DS1621_REG_TEMP[3] = {
 	0xAA,		/* input, word, RO */
 	0xA2,		/* min, word, RW */
@@ -59,6 +107,7 @@ static const u8 DS1621_REG_TEMP[3] = {
 };
 #define DS1621_REG_CONF			0xAC /* byte, RW */
 #define DS1621_COM_START		0xEE /* no data */
+#define DS1721_COM_START		0x51 /* no data */
 #define DS1621_COM_STOP			0x22 /* no data */
 
 /* The DS1621 configuration register */
@@ -75,14 +124,37 @@ struct ds1621_data {
 	struct mutex update_lock;
 	char valid;			/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
+	enum chips kind;		/* device type */
 
 	u16 temp[3];			/* Register values, word */
 	u8 conf;			/* Register encoding, combined */
+	u8 zbits;			/* Resolution encoded as number of
+					 * zero bits */
+	u16 update_interval;		/* Conversion rate in milliseconds */
 };
 
+static inline int DS1621_TEMP_FROM_REG(u16 reg)
+{
+	return DIV_ROUND_CLOSEST(((s16)reg / 16) * 625, 10);
+}
+
+/*
+ * TEMP: 0.001C/bit (-55C to +125C)
+ * REG:
+ *  - 1621, 1625: 0.5C/bit, 7 zero-bits
+ *  - 1631, 1721, 1731: 0.0625C/bit, 4 zero-bits
+ */
+static inline u16 DS1621_TEMP_TO_REG(long temp, u8 zbits)
+{
+	temp = clamp_val(temp, DS1621_TEMP_MIN, DS1621_TEMP_MAX);
+	temp = DIV_ROUND_CLOSEST(temp * (1 << (8 - zbits)), 1000) << zbits;
+	return temp;
+}
+
 static void ds1621_init_client(struct i2c_client *client)
 {
-	u8 conf, new_conf;
+	u8 conf, new_conf, sreg, resol;
+	struct ds1621_data *data = i2c_get_clientdata(client);
 
 	new_conf = conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
 	/* switch to continuous conversion mode */
@@ -97,8 +169,30 @@ static void ds1621_init_client(struct i2
 	if (conf != new_conf)
 		i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf);
 
+	switch (data->kind) {
+	case ds1625:
+		data->update_interval = DS1625_CONVERSION_MAX;
+		data->zbits = 7;
+		sreg = DS1621_COM_START;
+		break;
+	case ds1631:
+	case ds1721:
+	case ds1731:
+		resol = (new_conf & DS1621_REG_CONFIG_RESOL) >>
+			 DS1621_REG_CONFIG_RESOL_SHIFT;
+		data->update_interval = ds1721_convrates[resol];
+		data->zbits = 7 - resol;
+		sreg = DS1721_COM_START;
+		break;
+	default:
+		data->update_interval = DS1621_CONVERSION_MAX;
+		data->zbits = 7;
+		sreg = DS1621_COM_START;
+		break;
+	}
+
 	/* start conversion */
-	i2c_smbus_write_byte(client, DS1621_COM_START);
+	i2c_smbus_write_byte(client, sreg);
 }
 
 static struct ds1621_data *ds1621_update_client(struct device *dev)
@@ -109,8 +203,8 @@ static struct ds1621_data *ds1621_update
 
 	mutex_lock(&data->update_lock);
 
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
+	if (time_after(jiffies, data->last_updated + data->update_interval) ||
+	    !data->valid) {
 		int i;
 
 		dev_dbg(&client->dev, "Starting ds1621 update\n");
@@ -146,7 +240,7 @@ static ssize_t show_temp(struct device *
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct ds1621_data *data = ds1621_update_client(dev);
 	return sprintf(buf, "%d\n",
-		       LM75_TEMP_FROM_REG(data->temp[attr->index]));
+		       DS1621_TEMP_FROM_REG(data->temp[attr->index]));
 }
 
 static ssize_t set_temp(struct device *dev, struct device_attribute *da,
@@ -163,7 +257,7 @@ static ssize_t set_temp(struct device *d
 		return err;
 
 	mutex_lock(&data->update_lock);
-	data->temp[attr->index] = LM75_TEMP_TO_REG(val);
+	data->temp[attr->index] = DS1621_TEMP_TO_REG(val, data->zbits);
 	i2c_smbus_write_word_swapped(client, DS1621_REG_TEMP[attr->index],
 				     data->temp[attr->index]);
 	mutex_unlock(&data->update_lock);
@@ -185,7 +279,47 @@ static ssize_t show_alarm(struct device
 	return sprintf(buf, "%d\n", !!(data->conf & attr->index));
 }
 
+static ssize_t show_convrate(struct device *dev, struct device_attribute *da,
+			  char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct ds1621_data *data = i2c_get_clientdata(client);
+	return scnprintf(buf, PAGE_SIZE, "%hu\n", data->update_interval);
+}
+
+static ssize_t set_convrate(struct device *dev, struct device_attribute *da,
+			    const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct ds1621_data *data = i2c_get_clientdata(client);
+	unsigned long convrate;
+	s32 err;
+	int resol = 0;
+
+	err = kstrtoul(buf, 10, &convrate);
+	if (err)
+		return err;
+
+	/* Convert rate into resolution bits */
+	while (resol < (ARRAY_SIZE(ds1721_convrates) - 1) &&
+	       convrate > ds1721_convrates[resol])
+		resol++;
+
+	mutex_lock(&data->update_lock);
+	data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
+	data->conf &= ~DS1621_REG_CONFIG_RESOL;
+	data->conf |= (resol << DS1621_REG_CONFIG_RESOL_SHIFT);
+	i2c_smbus_write_byte_data(client, DS1621_REG_CONF, data->conf);
+	data->update_interval = ds1721_convrates[resol];
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_convrate,
+		   set_convrate);
+
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp, set_temp, 1);
 static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp, set_temp, 2);
@@ -201,48 +335,29 @@ static struct attribute *ds1621_attribut
 	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
 	&dev_attr_alarms.attr,
+	&dev_attr_update_interval.attr,
 	NULL
 };
 
-static const struct attribute_group ds1621_group = {
-	.attrs = ds1621_attributes,
-};
-
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int ds1621_detect(struct i2c_client *client,
-			 struct i2c_board_info *info)
+static umode_t ds1621_attribute_visible(struct kobject *kobj,
+					struct attribute *attr, int index)
 {
-	struct i2c_adapter *adapter = client->adapter;
-	int conf, temp;
-	int i;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
-				     | I2C_FUNC_SMBUS_WORD_DATA
-				     | I2C_FUNC_SMBUS_WRITE_BYTE))
-		return -ENODEV;
-
-	/*
-	 * Now, we do the remaining detection. It is lousy.
-	 *
-	 * The NVB bit should be low if no EEPROM write has been requested
-	 * during the latest 10ms, which is highly improbable in our case.
-	 */
-	conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
-	if (conf < 0 || conf & DS1621_REG_CONFIG_NVB)
-		return -ENODEV;
-	/* The 7 lowest bits of a temperature should always be 0. */
-	for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) {
-		temp = i2c_smbus_read_word_data(client, DS1621_REG_TEMP[i]);
-		if (temp < 0 || (temp & 0x7f00))
-			return -ENODEV;
-	}
-
-	strlcpy(info->type, "ds1621", I2C_NAME_SIZE);
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct ds1621_data *data = i2c_get_clientdata(client);
 
-	return 0;
+	if (attr == &dev_attr_update_interval.attr)
+		if (data->kind == ds1621 || data->kind == ds1625)
+			/* shhh, we're hiding update_interval */
+			return 0;
+	return attr->mode;
 }
 
+static const struct attribute_group ds1621_group = {
+	.attrs = ds1621_attributes,
+	.is_visible = ds1621_attribute_visible
+};
+
 static int ds1621_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -257,6 +372,8 @@ static int ds1621_probe(struct i2c_clien
 	i2c_set_clientdata(client, data);
 	mutex_init(&data->update_lock);
 
+	data->kind = id->driver_data;
+
 	/* Initialize the DS1621 chip */
 	ds1621_init_client(client);
 
@@ -289,8 +406,11 @@ static int ds1621_remove(struct i2c_clie
 }
 
 static const struct i2c_device_id ds1621_id[] = {
-	{ "ds1621", 0 },
-	{ "ds1625", 0 },
+	{ "ds1621", ds1621 },
+	{ "ds1625", ds1625 },
+	{ "ds1631", ds1631 },
+	{ "ds1721", ds1721 },
+	{ "ds1731", ds1731 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ds1621_id);
@@ -304,8 +424,6 @@ static struct i2c_driver ds1621_driver =
 	.probe		= ds1621_probe,
 	.remove		= ds1621_remove,
 	.id_table	= ds1621_id,
-	.detect		= ds1621_detect,
-	.address_list	= normal_i2c,
 };
 
 module_i2c_driver(ds1621_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/g762.c linux-libre-3.11-rc7-gnu/drivers/hwmon/g762.c
--- linux-libre-3.10-gnu/drivers/hwmon/g762.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/g762.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1149 @@
+/*
+ * g762 - Driver for the Global Mixed-mode Technology Inc. fan speed
+ *        PWM controller chips from G762 family, i.e. G762 and G763
+ *
+ * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
+ *
+ * This work is based on a basic version for 2.6.31 kernel developed
+ * by Olivier Mouchet for LaCie. Updates and correction have been
+ * performed to run on recent kernels. Additional features, like the
+ * ability to configure various characteristics via .dts file or
+ * board init file have been added. Detailed datasheet on which this
+ * development is based is available here:
+ *
+ *  http://natisbad.org/NAS/refs/GMT_EDS-762_763-080710-0.2.pdf
+ *
+ * Headers from previous developments have been kept below:
+ *
+ * Copyright (c) 2009 LaCie
+ *
+ * Author: Olivier Mouchet <olivier.mouchet@gmail.com>
+ *
+ * based on g760a code written by Herbert Valerio Riedel <hvr@gnu.org>
+ * Copyright (C) 2007  Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * g762: minimal datasheet available at:
+ *       http://www.gmt.com.tw/product/datasheet/EDS-762_3.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_data/g762.h>
+
+#define DRVNAME "g762"
+
+static const struct i2c_device_id g762_id[] = {
+	{ "g762", 0 },
+	{ "g763", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, g762_id);
+
+enum g762_regs {
+	G762_REG_SET_CNT  = 0x00,
+	G762_REG_ACT_CNT  = 0x01,
+	G762_REG_FAN_STA  = 0x02,
+	G762_REG_SET_OUT  = 0x03,
+	G762_REG_FAN_CMD1 = 0x04,
+	G762_REG_FAN_CMD2 = 0x05,
+};
+
+/* Config register bits */
+#define G762_REG_FAN_CMD1_DET_FAN_FAIL  0x80 /* enable fan_fail signal */
+#define G762_REG_FAN_CMD1_DET_FAN_OOC   0x40 /* enable fan_out_of_control */
+#define G762_REG_FAN_CMD1_OUT_MODE      0x20 /* out mode: PWM or DC */
+#define G762_REG_FAN_CMD1_FAN_MODE      0x10 /* fan mode: closed/open-loop */
+#define G762_REG_FAN_CMD1_CLK_DIV_ID1   0x08 /* clock divisor value */
+#define G762_REG_FAN_CMD1_CLK_DIV_ID0   0x04
+#define G762_REG_FAN_CMD1_PWM_POLARITY  0x02 /* PWM polarity */
+#define G762_REG_FAN_CMD1_PULSE_PER_REV 0x01 /* pulse per fan revolution */
+
+#define G762_REG_FAN_CMD2_GEAR_MODE_1   0x08 /* fan gear mode */
+#define G762_REG_FAN_CMD2_GEAR_MODE_0   0x04
+#define G762_REG_FAN_CMD2_FAN_STARTV_1  0x02 /* fan startup voltage */
+#define G762_REG_FAN_CMD2_FAN_STARTV_0  0x01
+
+#define G762_REG_FAN_STA_FAIL           0x02 /* fan fail */
+#define G762_REG_FAN_STA_OOC            0x01 /* fan out of control */
+
+/* Config register values */
+#define G762_OUT_MODE_PWM            1
+#define G762_OUT_MODE_DC             0
+
+#define G762_FAN_MODE_CLOSED_LOOP    2
+#define G762_FAN_MODE_OPEN_LOOP      1
+
+#define G762_PWM_POLARITY_NEGATIVE   1
+#define G762_PWM_POLARITY_POSITIVE   0
+
+/* Register data is read (and cached) at most once per second. */
+#define G762_UPDATE_INTERVAL    HZ
+
+/*
+ * Extract pulse count per fan revolution value (2 or 4) from given
+ * FAN_CMD1 register value.
+ */
+#define G762_PULSE_FROM_REG(reg) \
+	((((reg) & G762_REG_FAN_CMD1_PULSE_PER_REV) + 1) << 1)
+
+/*
+ * Extract fan clock divisor (1, 2, 4 or 8) from given FAN_CMD1
+ * register value.
+ */
+#define G762_CLKDIV_FROM_REG(reg) \
+	(1 << (((reg) & (G762_REG_FAN_CMD1_CLK_DIV_ID0 |	\
+			 G762_REG_FAN_CMD1_CLK_DIV_ID1)) >> 2))
+
+/*
+ * Extract fan gear mode multiplier value (0, 2 or 4) from given
+ * FAN_CMD2 register value.
+ */
+#define G762_GEARMULT_FROM_REG(reg) \
+	(1 << (((reg) & (G762_REG_FAN_CMD2_GEAR_MODE_0 |	\
+			 G762_REG_FAN_CMD2_GEAR_MODE_1)) >> 2))
+
+struct g762_data {
+	struct i2c_client *client;
+	struct device *hwmon_dev;
+	struct clk *clk;
+
+	/* update mutex */
+	struct mutex update_lock;
+
+	/* board specific parameters. */
+	u32 clk_freq;
+
+	/* g762 register cache */
+	bool valid;
+	unsigned long last_updated; /* in jiffies */
+
+	u8 set_cnt;  /* controls fan rotation speed in closed-loop mode */
+	u8 act_cnt;  /* provides access to current fan RPM value */
+	u8 fan_sta;  /* bit 0: set when actual fan speed is more than
+		      *        25% outside requested fan speed
+		      * bit 1: set when no transition occurs on fan
+		      *        pin for 0.7s
+		      */
+	u8 set_out;  /* controls fan rotation speed in open-loop mode */
+	u8 fan_cmd1; /*   0: FG_PLS_ID0 FG pulses count per revolution
+		      *      0: 2 counts per revolution
+		      *      1: 4 counts per revolution
+		      *   1: PWM_POLARITY 1: negative_duty
+		      *                   0: positive_duty
+		      * 2,3: [FG_CLOCK_ID0, FG_CLK_ID1]
+		      *         00: Divide fan clock by 1
+		      *         01: Divide fan clock by 2
+		      *         10: Divide fan clock by 4
+		      *         11: Divide fan clock by 8
+		      *   4: FAN_MODE 1:closed-loop, 0:open-loop
+		      *   5: OUT_MODE 1:PWM, 0:DC
+		      *   6: DET_FAN_OOC enable "fan ooc" status
+		      *   7: DET_FAN_FAIL enable "fan fail" status
+		      */
+	u8 fan_cmd2; /* 0,1: FAN_STARTV 0,1,2,3 -> 0,32,64,96 dac_code
+		      * 2,3: FG_GEAR_MODE
+		      *         00: multiplier = 1
+		      *         01: multiplier = 2
+		      *         10: multiplier = 4
+		      *   4: Mask ALERT# (g763 only)
+		      */
+};
+
+/*
+ * Convert count value from fan controller register (FAN_SET_CNT) into fan
+ * speed RPM value. Note that the datasheet documents a basic formula;
+ * influence of additional parameters (fan clock divisor, fan gear mode)
+ * have been infered from examples in the datasheet and tests.
+ */
+static inline unsigned int rpm_from_cnt(u8 cnt, u32 clk_freq, u16 p,
+					u8 clk_div, u8 gear_mult)
+{
+	if (cnt == 0xff)  /* setting cnt to 255 stops the fan */
+		return 0;
+
+	return (clk_freq * 30 * gear_mult) / ((cnt ? cnt : 1) * p * clk_div);
+}
+
+/*
+ * Convert fan RPM value from sysfs into count value for fan controller
+ * register (FAN_SET_CNT).
+ */
+static inline unsigned char cnt_from_rpm(u32 rpm, u32 clk_freq, u16 p,
+					 u8 clk_div, u8 gear_mult)
+{
+	if (!rpm)         /* to stop the fan, set cnt to 255 */
+		return 0xff;
+
+	return clamp_val(((clk_freq * 30 * gear_mult) / (rpm * p * clk_div)),
+			 0, 255);
+}
+
+/* helper to grab and cache data, at most one time per second */
+static struct g762_data *g762_update_client(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = i2c_get_clientdata(client);
+	int ret = 0;
+
+	mutex_lock(&data->update_lock);
+	if (time_before(jiffies, data->last_updated + G762_UPDATE_INTERVAL) &&
+	    likely(data->valid))
+		goto out;
+
+	ret = i2c_smbus_read_byte_data(client, G762_REG_SET_CNT);
+	if (ret < 0)
+		goto out;
+	data->set_cnt = ret;
+
+	ret = i2c_smbus_read_byte_data(client, G762_REG_ACT_CNT);
+	if (ret < 0)
+		goto out;
+	data->act_cnt = ret;
+
+	ret = i2c_smbus_read_byte_data(client, G762_REG_FAN_STA);
+	if (ret < 0)
+		goto out;
+	data->fan_sta = ret;
+
+	ret = i2c_smbus_read_byte_data(client, G762_REG_SET_OUT);
+	if (ret < 0)
+		goto out;
+	data->set_out = ret;
+
+	ret = i2c_smbus_read_byte_data(client, G762_REG_FAN_CMD1);
+	if (ret < 0)
+		goto out;
+	data->fan_cmd1 = ret;
+
+	ret = i2c_smbus_read_byte_data(client, G762_REG_FAN_CMD2);
+	if (ret < 0)
+		goto out;
+	data->fan_cmd2 = ret;
+
+	data->last_updated = jiffies;
+	data->valid = true;
+ out:
+	mutex_unlock(&data->update_lock);
+
+	if (ret < 0) /* upon error, encode it in return value */
+		data = ERR_PTR(ret);
+
+	return data;
+}
+
+/* helpers for writing hardware parameters */
+
+/*
+ * Set input clock frequency received on CLK pin of the chip. Accepted values
+ * are between 0 and 0xffffff. If zero is given, then default frequency
+ * (32,768Hz) is used. Note that clock frequency is a characteristic of the
+ * system but an internal parameter, i.e. value is not passed to the device.
+ */
+static int do_set_clk_freq(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = i2c_get_clientdata(client);
+
+	if (val > 0xffffff)
+		return -EINVAL;
+	if (!val)
+		val = 32768;
+
+	data->clk_freq = val;
+
+	return 0;
+}
+
+/* Set pwm mode. Accepts either 0 (PWM mode) or 1 (DC mode) */
+static int do_set_pwm_mode(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = g762_update_client(dev);
+	int ret;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	switch (val) {
+	case G762_OUT_MODE_PWM:
+		data->fan_cmd1 |=  G762_REG_FAN_CMD1_OUT_MODE;
+		break;
+	case G762_OUT_MODE_DC:
+		data->fan_cmd1 &= ~G762_REG_FAN_CMD1_OUT_MODE;
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+					data->fan_cmd1);
+	data->valid = false;
+ out:
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+/* Set fan clock divisor. Accepts either 1, 2, 4 or 8. */
+static int do_set_fan_div(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = g762_update_client(dev);
+	int ret;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	switch (val) {
+	case 1:
+		data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID0;
+		data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID1;
+		break;
+	case 2:
+		data->fan_cmd1 |=  G762_REG_FAN_CMD1_CLK_DIV_ID0;
+		data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID1;
+		break;
+	case 4:
+		data->fan_cmd1 &= ~G762_REG_FAN_CMD1_CLK_DIV_ID0;
+		data->fan_cmd1 |=  G762_REG_FAN_CMD1_CLK_DIV_ID1;
+		break;
+	case 8:
+		data->fan_cmd1 |=  G762_REG_FAN_CMD1_CLK_DIV_ID0;
+		data->fan_cmd1 |=  G762_REG_FAN_CMD1_CLK_DIV_ID1;
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+					data->fan_cmd1);
+	data->valid = false;
+ out:
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+/* Set fan gear mode. Accepts either 0, 1 or 2. */
+static int do_set_fan_gear_mode(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = g762_update_client(dev);
+	int ret;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	switch (val) {
+	case 0:
+		data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_0;
+		data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_1;
+		break;
+	case 1:
+		data->fan_cmd2 |=  G762_REG_FAN_CMD2_GEAR_MODE_0;
+		data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_1;
+		break;
+	case 2:
+		data->fan_cmd2 &= ~G762_REG_FAN_CMD2_GEAR_MODE_0;
+		data->fan_cmd2 |=  G762_REG_FAN_CMD2_GEAR_MODE_1;
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2,
+					data->fan_cmd2);
+	data->valid = false;
+ out:
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+/* Set number of fan pulses per revolution. Accepts either 2 or 4. */
+static int do_set_fan_pulses(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = g762_update_client(dev);
+	int ret;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	switch (val) {
+	case 2:
+		data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PULSE_PER_REV;
+		break;
+	case 4:
+		data->fan_cmd1 |=  G762_REG_FAN_CMD1_PULSE_PER_REV;
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+					data->fan_cmd1);
+	data->valid = false;
+ out:
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+/* Set fan mode. Accepts either 1 (open-loop) or 2 (closed-loop). */
+static int do_set_pwm_enable(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = g762_update_client(dev);
+	int ret;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	switch (val) {
+	case G762_FAN_MODE_CLOSED_LOOP:
+		data->fan_cmd1 |=  G762_REG_FAN_CMD1_FAN_MODE;
+		break;
+	case G762_FAN_MODE_OPEN_LOOP:
+		data->fan_cmd1 &= ~G762_REG_FAN_CMD1_FAN_MODE;
+		/*
+		 * BUG FIX: if SET_CNT register value is 255 then, for some
+		 * unknown reason, fan will not rotate as expected, no matter
+		 * the value of SET_OUT (to be specific, this seems to happen
+		 * only in PWM mode). To workaround this bug, we give SET_CNT
+		 * value of 254 if it is 255 when switching to open-loop.
+		 */
+		if (data->set_cnt == 0xff)
+			i2c_smbus_write_byte_data(client, G762_REG_SET_CNT,
+						  254);
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+					data->fan_cmd1);
+	data->valid = false;
+ out:
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+/* Set PWM polarity. Accepts either 0 (positive duty) or 1 (negative duty) */
+static int do_set_pwm_polarity(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = g762_update_client(dev);
+	int ret;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	switch (val) {
+	case G762_PWM_POLARITY_POSITIVE:
+		data->fan_cmd1 &= ~G762_REG_FAN_CMD1_PWM_POLARITY;
+		break;
+	case G762_PWM_POLARITY_NEGATIVE:
+		data->fan_cmd1 |=  G762_REG_FAN_CMD1_PWM_POLARITY;
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+					data->fan_cmd1);
+	data->valid = false;
+ out:
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+/*
+ * Set pwm value. Accepts values between 0 (stops the fan) and
+ * 255 (full speed). This only makes sense in open-loop mode.
+ */
+static int do_set_pwm(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = i2c_get_clientdata(client);
+	int ret;
+
+	if (val > 255)
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	ret = i2c_smbus_write_byte_data(client, G762_REG_SET_OUT, val);
+	data->valid = false;
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+/*
+ * Set fan RPM value. Can be called both in closed and open-loop mode
+ * but effect will only be seen after closed-loop mode is configured.
+ */
+static int do_set_fan_target(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = g762_update_client(dev);
+	int ret;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	data->set_cnt = cnt_from_rpm(val, data->clk_freq,
+				     G762_PULSE_FROM_REG(data->fan_cmd1),
+				     G762_CLKDIV_FROM_REG(data->fan_cmd1),
+				     G762_GEARMULT_FROM_REG(data->fan_cmd2));
+	ret = i2c_smbus_write_byte_data(client, G762_REG_SET_CNT,
+					data->set_cnt);
+	data->valid = false;
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+/* Set fan startup voltage. Accepted values are either 0, 1, 2 or 3. */
+static int do_set_fan_startv(struct device *dev, unsigned long val)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = g762_update_client(dev);
+	int ret;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	switch (val) {
+	case 0:
+		data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_0;
+		data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_1;
+		break;
+	case 1:
+		data->fan_cmd2 |=  G762_REG_FAN_CMD2_FAN_STARTV_0;
+		data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_1;
+		break;
+	case 2:
+		data->fan_cmd2 &= ~G762_REG_FAN_CMD2_FAN_STARTV_0;
+		data->fan_cmd2 |=  G762_REG_FAN_CMD2_FAN_STARTV_1;
+		break;
+	case 3:
+		data->fan_cmd2 |=  G762_REG_FAN_CMD2_FAN_STARTV_0;
+		data->fan_cmd2 |=  G762_REG_FAN_CMD2_FAN_STARTV_1;
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2,
+					data->fan_cmd2);
+	data->valid = false;
+ out:
+	mutex_unlock(&data->update_lock);
+
+	return ret;
+}
+
+/*
+ * Helper to import hardware characteristics from .dts file and push
+ * those to the chip.
+ */
+
+#ifdef CONFIG_OF
+static struct of_device_id g762_dt_match[] = {
+	{ .compatible = "gmt,g762" },
+	{ .compatible = "gmt,g763" },
+	{ },
+};
+
+/*
+ * Grab clock (a required property), enable it, get (fixed) clock frequency
+ * and store it. Note: upon success, clock has been prepared and enabled; it
+ * must later be unprepared and disabled (e.g. during module unloading) by a
+ * call to g762_of_clock_disable(). Note that a reference to clock is kept
+ * in our private data structure to be used in this function.
+ */
+static int g762_of_clock_enable(struct i2c_client *client)
+{
+	struct g762_data *data;
+	unsigned long clk_freq;
+	struct clk *clk;
+	int ret;
+
+	if (!client->dev.of_node)
+		return 0;
+
+	clk = of_clk_get(client->dev.of_node, 0);
+	if (IS_ERR(clk)) {
+		dev_err(&client->dev, "failed to get clock\n");
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		dev_err(&client->dev, "failed to enable clock\n");
+		goto clk_put;
+	}
+
+	clk_freq = clk_get_rate(clk);
+	ret = do_set_clk_freq(&client->dev, clk_freq);
+	if (ret) {
+		dev_err(&client->dev, "invalid clock freq %lu\n", clk_freq);
+		goto clk_unprep;
+	}
+
+	data = i2c_get_clientdata(client);
+	data->clk = clk;
+
+	return 0;
+
+ clk_unprep:
+	clk_disable_unprepare(clk);
+
+ clk_put:
+	clk_put(clk);
+
+	return ret;
+}
+
+static void g762_of_clock_disable(struct i2c_client *client)
+{
+	struct g762_data *data = i2c_get_clientdata(client);
+
+	if (!data->clk)
+		return;
+
+	clk_disable_unprepare(data->clk);
+	clk_put(data->clk);
+}
+
+static int g762_of_prop_import_one(struct i2c_client *client,
+				   const char *pname,
+				   int (*psetter)(struct device *dev,
+						  unsigned long val))
+{
+	const __be32 *prop;
+	int len, ret;
+	u32 pval;
+
+	prop = of_get_property(client->dev.of_node, pname, &len);
+	if (!prop || len != sizeof(u32))
+		return 0;
+
+	pval = be32_to_cpu(prop[0]);
+	dev_dbg(&client->dev, "found %s (%d)\n", pname, pval);
+	ret = (*psetter)(&client->dev, pval);
+	if (ret)
+		dev_err(&client->dev, "unable to set %s (%d)\n", pname, pval);
+
+	return ret;
+}
+
+static int g762_of_prop_import(struct i2c_client *client)
+{
+	int ret;
+
+	if (!client->dev.of_node)
+		return 0;
+
+	ret = g762_of_prop_import_one(client, "fan_gear_mode",
+				      do_set_fan_gear_mode);
+	if (ret)
+		return ret;
+
+	ret = g762_of_prop_import_one(client, "pwm_polarity",
+				      do_set_pwm_polarity);
+	if (ret)
+		return ret;
+
+	return g762_of_prop_import_one(client, "fan_startv",
+				       do_set_fan_startv);
+}
+
+#else
+static int g762_of_prop_import(struct i2c_client *client)
+{
+	return 0;
+}
+
+static int g762_of_clock_enable(struct i2c_client *client)
+{
+	return 0;
+}
+
+static void g762_of_clock_disable(struct i2c_client *client) { }
+#endif
+
+/*
+ * Helper to import hardware characteristics from .dts file and push
+ * those to the chip.
+ */
+
+static int g762_pdata_prop_import(struct i2c_client *client)
+{
+	struct g762_platform_data *pdata = client->dev.platform_data;
+	int ret;
+
+	if (!pdata)
+		return 0;
+
+	ret = do_set_fan_gear_mode(&client->dev, pdata->fan_gear_mode);
+	if (ret)
+		return ret;
+
+	ret = do_set_pwm_polarity(&client->dev, pdata->pwm_polarity);
+	if (ret)
+		return ret;
+
+	ret = do_set_fan_startv(&client->dev, pdata->fan_startv);
+	if (ret)
+		return ret;
+
+	return do_set_clk_freq(&client->dev, pdata->clk_freq);
+}
+
+/*
+ * sysfs attributes
+ */
+
+/*
+ * Read function for fan1_input sysfs file. Return current fan RPM value, or
+ * 0 if fan is out of control.
+ */
+static ssize_t get_fan_rpm(struct device *dev, struct device_attribute *da,
+			   char *buf)
+{
+	struct g762_data *data = g762_update_client(dev);
+	unsigned int rpm = 0;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	/* reverse logic: fan out of control reporting is enabled low */
+	if (data->fan_sta & G762_REG_FAN_STA_OOC) {
+		rpm = rpm_from_cnt(data->act_cnt, data->clk_freq,
+				   G762_PULSE_FROM_REG(data->fan_cmd1),
+				   G762_CLKDIV_FROM_REG(data->fan_cmd1),
+				   G762_GEARMULT_FROM_REG(data->fan_cmd2));
+	}
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%u\n", rpm);
+}
+
+/*
+ * Read and write functions for pwm1_mode sysfs file. Get and set fan speed
+ * control mode i.e. PWM (1) or DC (0).
+ */
+static ssize_t get_pwm_mode(struct device *dev, struct device_attribute *da,
+			    char *buf)
+{
+	struct g762_data *data = g762_update_client(dev);
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	return sprintf(buf, "%d\n",
+		       !!(data->fan_cmd1 & G762_REG_FAN_CMD1_OUT_MODE));
+}
+
+static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *da,
+			    const char *buf, size_t count)
+{
+	unsigned long val;
+	int ret;
+
+	if (kstrtoul(buf, 10, &val))
+		return -EINVAL;
+
+	ret = do_set_pwm_mode(dev, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+/*
+ * Read and write functions for fan1_div sysfs file. Get and set fan
+ * controller prescaler value
+ */
+static ssize_t get_fan_div(struct device *dev,
+			   struct device_attribute *da, char *buf)
+{
+	struct g762_data *data = g762_update_client(dev);
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	return sprintf(buf, "%d\n", G762_CLKDIV_FROM_REG(data->fan_cmd1));
+}
+
+static ssize_t set_fan_div(struct device *dev,
+			   struct device_attribute *da,
+			   const char *buf, size_t count)
+{
+	unsigned long val;
+	int ret;
+
+	if (kstrtoul(buf, 10, &val))
+		return -EINVAL;
+
+	ret = do_set_fan_div(dev, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+/*
+ * Read and write functions for fan1_pulses sysfs file. Get and set number
+ * of tachometer pulses per fan revolution.
+ */
+static ssize_t get_fan_pulses(struct device *dev,
+			      struct device_attribute *da, char *buf)
+{
+	struct g762_data *data = g762_update_client(dev);
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	return sprintf(buf, "%d\n", G762_PULSE_FROM_REG(data->fan_cmd1));
+}
+
+static ssize_t set_fan_pulses(struct device *dev,
+			      struct device_attribute *da,
+			      const char *buf, size_t count)
+{
+	unsigned long val;
+	int ret;
+
+	if (kstrtoul(buf, 10, &val))
+		return -EINVAL;
+
+	ret = do_set_fan_pulses(dev, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+/*
+ * Read and write functions for pwm1_enable. Get and set fan speed control mode
+ * (i.e. closed or open-loop).
+ *
+ * Following documentation about hwmon's sysfs interface, a pwm1_enable node
+ * should accept followings:
+ *
+ *  0 : no fan speed control (i.e. fan at full speed)
+ *  1 : manual fan speed control enabled (use pwm[1-*]) (open-loop)
+ *  2+: automatic fan speed control enabled (use fan[1-*]_target) (closed-loop)
+ *
+ * but we do not accept 0 as this mode is not natively supported by the chip
+ * and it is not emulated by g762 driver. -EINVAL is returned in this case.
+ */
+static ssize_t get_pwm_enable(struct device *dev,
+			      struct device_attribute *da, char *buf)
+{
+	struct g762_data *data = g762_update_client(dev);
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	return sprintf(buf, "%d\n",
+		       (!!(data->fan_cmd1 & G762_REG_FAN_CMD1_FAN_MODE)) + 1);
+}
+
+static ssize_t set_pwm_enable(struct device *dev,
+			      struct device_attribute *da,
+			      const char *buf, size_t count)
+{
+	unsigned long val;
+	int ret;
+
+	if (kstrtoul(buf, 10, &val))
+		return -EINVAL;
+
+	ret = do_set_pwm_enable(dev, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+/*
+ * Read and write functions for pwm1 sysfs file. Get and set pwm value
+ * (which affects fan speed) in open-loop mode. 0 stops the fan and 255
+ * makes it run at full speed.
+ */
+static ssize_t get_pwm(struct device *dev, struct device_attribute *da,
+		       char *buf)
+{
+	struct g762_data *data = g762_update_client(dev);
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	return sprintf(buf, "%d\n", data->set_out);
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
+		       const char *buf, size_t count)
+{
+	unsigned long val;
+	int ret;
+
+	if (kstrtoul(buf, 10, &val))
+		return -EINVAL;
+
+	ret = do_set_pwm(dev, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+/*
+ * Read and write function for fan1_target sysfs file. Get/set the fan speed in
+ * closed-loop mode. Speed is given as a RPM value; then the chip will regulate
+ * the fan speed using pulses from fan tachometer.
+ *
+ * Refer to rpm_from_cnt() implementation above to get info about count number
+ * calculation.
+ *
+ * Also note that due to rounding errors it is possible that you don't read
+ * back exactly the value you have set.
+ */
+static ssize_t get_fan_target(struct device *dev, struct device_attribute *da,
+			      char *buf)
+{
+	struct g762_data *data = g762_update_client(dev);
+	unsigned int rpm;
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	mutex_lock(&data->update_lock);
+	rpm = rpm_from_cnt(data->set_cnt, data->clk_freq,
+			   G762_PULSE_FROM_REG(data->fan_cmd1),
+			   G762_CLKDIV_FROM_REG(data->fan_cmd1),
+			   G762_GEARMULT_FROM_REG(data->fan_cmd2));
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%u\n", rpm);
+}
+
+static ssize_t set_fan_target(struct device *dev, struct device_attribute *da,
+			      const char *buf, size_t count)
+{
+	unsigned long val;
+	int ret;
+
+	if (kstrtoul(buf, 10, &val))
+		return -EINVAL;
+
+	ret = do_set_fan_target(dev, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+/* read function for fan1_fault sysfs file. */
+static ssize_t get_fan_failure(struct device *dev, struct device_attribute *da,
+			       char *buf)
+{
+	struct g762_data *data = g762_update_client(dev);
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	return sprintf(buf, "%u\n", !!(data->fan_sta & G762_REG_FAN_STA_FAIL));
+}
+
+/*
+ * read function for fan1_alarm sysfs file. Note that OOC condition is
+ * enabled low
+ */
+static ssize_t get_fan_ooc(struct device *dev, struct device_attribute *da,
+			   char *buf)
+{
+	struct g762_data *data = g762_update_client(dev);
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	return sprintf(buf, "%u\n", !(data->fan_sta & G762_REG_FAN_STA_OOC));
+}
+
+static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm);
+static DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, get_pwm_mode, set_pwm_mode);
+static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
+		   get_pwm_enable, set_pwm_enable);
+static DEVICE_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL);
+static DEVICE_ATTR(fan1_alarm, S_IRUGO, get_fan_ooc, NULL);
+static DEVICE_ATTR(fan1_fault, S_IRUGO, get_fan_failure, NULL);
+static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO,
+		   get_fan_target, set_fan_target);
+static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_fan_div, set_fan_div);
+static DEVICE_ATTR(fan1_pulses, S_IWUSR | S_IRUGO,
+		   get_fan_pulses, set_fan_pulses);
+
+/* Driver data */
+static struct attribute *g762_attributes[] = {
+	&dev_attr_fan1_input.attr,
+	&dev_attr_fan1_alarm.attr,
+	&dev_attr_fan1_fault.attr,
+	&dev_attr_fan1_target.attr,
+	&dev_attr_fan1_div.attr,
+	&dev_attr_fan1_pulses.attr,
+	&dev_attr_pwm1.attr,
+	&dev_attr_pwm1_mode.attr,
+	&dev_attr_pwm1_enable.attr,
+	NULL
+};
+
+static const struct attribute_group g762_group = {
+	.attrs = g762_attributes,
+};
+
+/*
+ * Enable both fan failure detection and fan out of control protection. The
+ * function does not protect change/access to data structure; it must thus
+ * only be called during initialization.
+ */
+static inline int g762_fan_init(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct g762_data *data = g762_update_client(dev);
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_FAIL;
+	data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC;
+	data->valid = false;
+
+	return i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+					 data->fan_cmd1);
+}
+
+static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct g762_data *data;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	data = devm_kzalloc(&client->dev, sizeof(struct g762_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	data->client = client;
+	mutex_init(&data->update_lock);
+
+	/* Enable fan failure detection and fan out of control protection */
+	ret = g762_fan_init(&client->dev);
+	if (ret)
+		return ret;
+
+	/* Get configuration via DT ... */
+	ret = g762_of_clock_enable(client);
+	if (ret)
+		return ret;
+	ret = g762_of_prop_import(client);
+	if (ret)
+		goto clock_dis;
+	/* ... or platform_data */
+	ret = g762_pdata_prop_import(client);
+	if (ret)
+		goto clock_dis;
+
+	/* Register sysfs hooks */
+	ret = sysfs_create_group(&client->dev.kobj, &g762_group);
+	if (ret)
+		goto clock_dis;
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		ret = PTR_ERR(data->hwmon_dev);
+		goto sysfs_rem;
+	}
+
+	return 0;
+
+ sysfs_rem:
+	sysfs_remove_group(&client->dev.kobj, &g762_group);
+
+ clock_dis:
+	g762_of_clock_disable(client);
+
+	return ret;
+}
+
+static int g762_remove(struct i2c_client *client)
+{
+	struct g762_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &g762_group);
+	g762_of_clock_disable(client);
+
+	return 0;
+}
+
+static struct i2c_driver g762_driver = {
+	.driver = {
+		.name = DRVNAME,
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(g762_dt_match),
+	},
+	.probe	  = g762_probe,
+	.remove	  = g762_remove,
+	.id_table = g762_id,
+};
+
+module_i2c_driver(g762_driver);
+
+MODULE_AUTHOR("Arnaud EBALARD <arno@natisbad.org>");
+MODULE_DESCRIPTION("GMT G762/G763 driver");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/i5k_amb.c linux-libre-3.11-rc7-gnu/drivers/hwmon/i5k_amb.c
--- linux-libre-3.10-gnu/drivers/hwmon/i5k_amb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/i5k_amb.c	2013-08-25 20:43:22.000000000 -0400
@@ -556,7 +556,6 @@ static int i5k_amb_probe(struct platform
 
 err_init_failed:
 	iounmap(data->amb_mmio);
-	platform_set_drvdata(pdev, NULL);
 err_map_failed:
 	release_mem_region(data->amb_base, data->amb_len);
 err:
@@ -576,7 +575,6 @@ static int i5k_amb_remove(struct platfor
 	kfree(data->attrs);
 	iounmap(data->amb_mmio);
 	release_mem_region(data->amb_base, data->amb_len);
-	platform_set_drvdata(pdev, NULL);
 	kfree(data);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/iio_hwmon.c linux-libre-3.11-rc7-gnu/drivers/hwmon/iio_hwmon.c
--- linux-libre-3.10-gnu/drivers/hwmon/iio_hwmon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/iio_hwmon.c	2013-08-25 20:43:22.000000000 -0400
@@ -180,6 +180,7 @@ static struct of_device_id iio_hwmon_of_
 	{ .compatible = "iio-hwmon", },
 	{ }
 };
+MODULE_DEVICE_TABLE(of, iio_hwmon_of_match);
 
 static struct platform_driver __refdata iio_hwmon_driver = {
 	.driver = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/ina2xx.c linux-libre-3.11-rc7-gnu/drivers/hwmon/ina2xx.c
--- linux-libre-3.10-gnu/drivers/hwmon/ina2xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/ina2xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/jiffies.h>
+#include <linux/of.h>
 
 #include <linux/platform_data/ina2xx.h>
 
@@ -221,6 +222,7 @@ static int ina2xx_probe(struct i2c_clien
 	struct ina2xx_data *data;
 	struct ina2xx_platform_data *pdata;
 	int ret;
+	u32 val;
 	long shunt = 10000; /* default shunt value 10mOhms */
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
@@ -234,6 +236,9 @@ static int ina2xx_probe(struct i2c_clien
 		pdata =
 		  (struct ina2xx_platform_data *)client->dev.platform_data;
 		shunt = pdata->shunt_uohms;
+	} else if (!of_property_read_u32(client->dev.of_node,
+				"shunt-resistor", &val)) {
+			shunt = val;
 	}
 
 	if (shunt <= 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/Kconfig linux-libre-3.11-rc7-gnu/drivers/hwmon/Kconfig
--- linux-libre-3.10-gnu/drivers/hwmon/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -348,11 +348,16 @@ config SENSORS_DS620
 	  will be called ds620.
 
 config SENSORS_DS1621
-	tristate "Dallas Semiconductor DS1621 and DS1625"
+	tristate "Dallas Semiconductor DS1621 and compatibles"
 	depends on I2C
 	help
-	  If you say yes here you get support for Dallas Semiconductor
-	  DS1621 and DS1625 sensor chips.
+	  If you say yes here you get support for Dallas Semiconductor/Maxim
+	  Integrated DS1621 sensor chips and compatible models including:
+
+	  - Dallas Semiconductor DS1625
+	  - Maxim Integrated DS1631
+	  - Maxim Integrated DS1721
+	  - Maxim Integrated DS1731
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called ds1621.
@@ -456,6 +461,16 @@ config SENSORS_G760A
 	  This driver can also be built as a module.  If so, the module
 	  will be called g760a.
 
+config SENSORS_G762
+	tristate "GMT G762 and G763"
+	depends on I2C
+	help
+	  If you say yes here you get support for Global Mixed-mode
+	  Technology Inc G762 and G763 fan speed PWM controller chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called g762.
+
 config SENSORS_GL518SM
 	tristate "Genesys Logic GL518SM"
 	depends on I2C
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/lm63.c linux-libre-3.11-rc7-gnu/drivers/hwmon/lm63.c
--- linux-libre-3.10-gnu/drivers/hwmon/lm63.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/lm63.c	2013-08-25 20:43:22.000000000 -0400
@@ -247,9 +247,8 @@ static struct lm63_data *lm63_update_dev
 
 	mutex_lock(&data->update_lock);
 
-	next_update = data->last_updated
-	  + msecs_to_jiffies(data->update_interval) + 1;
-
+	next_update = data->last_updated +
+		      msecs_to_jiffies(data->update_interval);
 	if (time_after(jiffies, next_update) || !data->valid) {
 		if (data->config & 0x04) { /* tachometer enabled  */
 			/* order matters for fan1_input */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/lm90.c linux-libre-3.11-rc7-gnu/drivers/hwmon/lm90.c
--- linux-libre-3.10-gnu/drivers/hwmon/lm90.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/lm90.c	2013-08-25 20:43:22.000000000 -0400
@@ -470,8 +470,8 @@ static struct lm90_data *lm90_update_dev
 
 	mutex_lock(&data->update_lock);
 
-	next_update = data->last_updated
-	  + msecs_to_jiffies(data->update_interval) + 1;
+	next_update = data->last_updated +
+		      msecs_to_jiffies(data->update_interval);
 	if (time_after(jiffies, next_update) || !data->valid) {
 		u8 h, l;
 		u8 alarms;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/Makefile linux-libre-3.11-rc7-gnu/drivers/hwmon/Makefile
--- linux-libre-3.10-gnu/drivers/hwmon/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -60,6 +60,7 @@ obj-$(CONFIG_SENSORS_F75375S)	+= f75375s
 obj-$(CONFIG_SENSORS_FAM15H_POWER) += fam15h_power.o
 obj-$(CONFIG_SENSORS_FSCHMD)	+= fschmd.o
 obj-$(CONFIG_SENSORS_G760A)	+= g760a.o
+obj-$(CONFIG_SENSORS_G762)	+= g762.o
 obj-$(CONFIG_SENSORS_GL518SM)	+= gl518sm.o
 obj-$(CONFIG_SENSORS_GL520SM)	+= gl520sm.o
 obj-$(CONFIG_SENSORS_GPIO_FAN)	+= gpio-fan.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/max6697.c linux-libre-3.11-rc7-gnu/drivers/hwmon/max6697.c
--- linux-libre-3.10-gnu/drivers/hwmon/max6697.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/max6697.c	2013-08-25 20:43:22.000000000 -0400
@@ -605,12 +605,12 @@ static int max6697_init_chip(struct i2c_
 		if (ret < 0)
 			return ret;
 		ret = i2c_smbus_write_byte_data(client, MAX6581_REG_IDEALITY,
-						pdata->ideality_mask >> 1);
+						pdata->ideality_value);
 		if (ret < 0)
 			return ret;
 		ret = i2c_smbus_write_byte_data(client,
 						MAX6581_REG_IDEALITY_SELECT,
-						pdata->ideality_value);
+						pdata->ideality_mask >> 1);
 		if (ret < 0)
 			return ret;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/nct6775.c linux-libre-3.11-rc7-gnu/drivers/hwmon/nct6775.c
--- linux-libre-3.10-gnu/drivers/hwmon/nct6775.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/nct6775.c	2013-08-25 20:43:22.000000000 -0400
@@ -199,7 +199,7 @@ static const s8 NCT6775_ALARM_BITS[] = {
 	0, 1, 2, 3, 8, 21, 20, 16,	/* in0.. in7 */
 	17, -1, -1, -1, -1, -1, -1,	/* in8..in14 */
 	-1,				/* unused */
-	6, 7, 11, 10, 23,		/* fan1..fan5 */
+	6, 7, 11, -1, -1,		/* fan1..fan5 */
 	-1, -1, -1,			/* unused */
 	4, 5, 13, -1, -1, -1,		/* temp1..temp6 */
 	12, -1 };			/* intrusion0, intrusion1 */
@@ -625,6 +625,7 @@ struct nct6775_data {
 	u8 has_fan_min;		/* some fans don't have min register */
 	bool has_fan_div;
 
+	u8 num_temp_alarms;	/* 2 or 3 */
 	u8 temp_fixed_num;	/* 3 or 6 */
 	u8 temp_type[NUM_TEMP_FIXED];
 	s8 temp_offset[NUM_TEMP_FIXED];
@@ -1193,6 +1194,42 @@ show_alarm(struct device *dev, struct de
 		       (unsigned int)((data->alarms >> nr) & 0x01));
 }
 
+static int find_temp_source(struct nct6775_data *data, int index, int count)
+{
+	int source = data->temp_src[index];
+	int nr;
+
+	for (nr = 0; nr < count; nr++) {
+		int src;
+
+		src = nct6775_read_value(data,
+					 data->REG_TEMP_SOURCE[nr]) & 0x1f;
+		if (src == source)
+			return nr;
+	}
+	return -1;
+}
+
+static ssize_t
+show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
+	struct nct6775_data *data = nct6775_update_device(dev);
+	unsigned int alarm = 0;
+	int nr;
+
+	/*
+	 * For temperatures, there is no fixed mapping from registers to alarm
+	 * bits. Alarm bits are determined by the temperature source mapping.
+	 */
+	nr = find_temp_source(data, sattr->index, data->num_temp_alarms);
+	if (nr >= 0) {
+		int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE];
+		alarm = (data->alarms >> bit) & 0x01;
+	}
+	return sprintf(buf, "%u\n", alarm);
+}
+
 static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in_reg, NULL, 0, 0);
 static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in_reg, NULL, 1, 0);
 static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in_reg, NULL, 2, 0);
@@ -1874,22 +1911,18 @@ static struct sensor_device_attribute sd
 };
 
 static struct sensor_device_attribute sda_temp_alarm[] = {
-	SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL,
-		    TEMP_ALARM_BASE),
-	SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL,
-		    TEMP_ALARM_BASE + 1),
-	SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL,
-		    TEMP_ALARM_BASE + 2),
-	SENSOR_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL,
-		    TEMP_ALARM_BASE + 3),
-	SENSOR_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL,
-		    TEMP_ALARM_BASE + 4),
-	SENSOR_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL,
-		    TEMP_ALARM_BASE + 5),
+	SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0),
+	SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1),
+	SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2),
+	SENSOR_ATTR(temp4_alarm, S_IRUGO, show_temp_alarm, NULL, 3),
+	SENSOR_ATTR(temp5_alarm, S_IRUGO, show_temp_alarm, NULL, 4),
+	SENSOR_ATTR(temp6_alarm, S_IRUGO, show_temp_alarm, NULL, 5),
+	SENSOR_ATTR(temp7_alarm, S_IRUGO, show_temp_alarm, NULL, 6),
+	SENSOR_ATTR(temp8_alarm, S_IRUGO, show_temp_alarm, NULL, 7),
+	SENSOR_ATTR(temp9_alarm, S_IRUGO, show_temp_alarm, NULL, 8),
+	SENSOR_ATTR(temp10_alarm, S_IRUGO, show_temp_alarm, NULL, 9),
 };
 
-#define NUM_TEMP_ALARM	ARRAY_SIZE(sda_temp_alarm)
-
 static ssize_t
 show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -3215,13 +3248,11 @@ static void nct6775_device_remove_files(
 		device_remove_file(dev, &sda_temp_max[i].dev_attr);
 		device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
 		device_remove_file(dev, &sda_temp_crit[i].dev_attr);
+		device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
 		if (!(data->have_temp_fixed & (1 << i)))
 			continue;
 		device_remove_file(dev, &sda_temp_type[i].dev_attr);
 		device_remove_file(dev, &sda_temp_offset[i].dev_attr);
-		if (i >= NUM_TEMP_ALARM)
-			continue;
-		device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
 	}
 
 	device_remove_file(dev, &sda_caseopen[0].dev_attr);
@@ -3419,6 +3450,7 @@ static int nct6775_probe(struct platform
 		data->auto_pwm_num = 6;
 		data->has_fan_div = true;
 		data->temp_fixed_num = 3;
+		data->num_temp_alarms = 3;
 
 		data->ALARM_BITS = NCT6775_ALARM_BITS;
 
@@ -3483,6 +3515,7 @@ static int nct6775_probe(struct platform
 		data->auto_pwm_num = 4;
 		data->has_fan_div = false;
 		data->temp_fixed_num = 3;
+		data->num_temp_alarms = 3;
 
 		data->ALARM_BITS = NCT6776_ALARM_BITS;
 
@@ -3547,6 +3580,7 @@ static int nct6775_probe(struct platform
 		data->auto_pwm_num = 4;
 		data->has_fan_div = false;
 		data->temp_fixed_num = 6;
+		data->num_temp_alarms = 2;
 
 		data->ALARM_BITS = NCT6779_ALARM_BITS;
 
@@ -3843,10 +3877,12 @@ static int nct6775_probe(struct platform
 						 &sda_fan_input[i].dev_attr);
 			if (err)
 				goto exit_remove;
-			err = device_create_file(dev,
-						 &sda_fan_alarm[i].dev_attr);
-			if (err)
-				goto exit_remove;
+			if (data->ALARM_BITS[FAN_ALARM_BASE + i] >= 0) {
+				err = device_create_file(dev,
+						&sda_fan_alarm[i].dev_attr);
+				if (err)
+					goto exit_remove;
+			}
 			if (data->kind != nct6776 &&
 			    data->kind != nct6779) {
 				err = device_create_file(dev,
@@ -3897,6 +3933,12 @@ static int nct6775_probe(struct platform
 			if (err)
 				goto exit_remove;
 		}
+		if (find_temp_source(data, i, data->num_temp_alarms) >= 0) {
+			err = device_create_file(dev,
+						 &sda_temp_alarm[i].dev_attr);
+			if (err)
+				goto exit_remove;
+		}
 		if (!(data->have_temp_fixed & (1 << i)))
 			continue;
 		err = device_create_file(dev, &sda_temp_type[i].dev_attr);
@@ -3905,12 +3947,6 @@ static int nct6775_probe(struct platform
 		err = device_create_file(dev, &sda_temp_offset[i].dev_attr);
 		if (err)
 			goto exit_remove;
-		if (i >= NUM_TEMP_ALARM ||
-		    data->ALARM_BITS[TEMP_ALARM_BASE + i] < 0)
-			continue;
-		err = device_create_file(dev, &sda_temp_alarm[i].dev_attr);
-		if (err)
-			goto exit_remove;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(sda_caseopen); i++) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/ntc_thermistor.c linux-libre-3.11-rc7-gnu/drivers/hwmon/ntc_thermistor.c
--- linux-libre-3.10-gnu/drivers/hwmon/ntc_thermistor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/ntc_thermistor.c	2013-08-25 20:43:22.000000000 -0400
@@ -514,7 +514,6 @@ static int ntc_thermistor_remove(struct
 	hwmon_device_unregister(data->hwmon_dev);
 	sysfs_remove_group(&data->dev->kobj, &ntc_attr_group);
 	ntc_iio_channel_release(pdata);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/via-cputemp.c linux-libre-3.11-rc7-gnu/drivers/hwmon/via-cputemp.c
--- linux-libre-3.10-gnu/drivers/hwmon/via-cputemp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/via-cputemp.c	2013-08-25 20:43:22.000000000 -0400
@@ -221,7 +221,7 @@ struct pdev_entry {
 static LIST_HEAD(pdev_list);
 static DEFINE_MUTEX(pdev_list_mutex);
 
-static int __cpuinit via_cputemp_device_add(unsigned int cpu)
+static int via_cputemp_device_add(unsigned int cpu)
 {
 	int err;
 	struct platform_device *pdev;
@@ -262,7 +262,7 @@ exit:
 	return err;
 }
 
-static void __cpuinit via_cputemp_device_remove(unsigned int cpu)
+static void via_cputemp_device_remove(unsigned int cpu)
 {
 	struct pdev_entry *p;
 
@@ -279,8 +279,8 @@ static void __cpuinit via_cputemp_device
 	mutex_unlock(&pdev_list_mutex);
 }
 
-static int __cpuinit via_cputemp_cpu_callback(struct notifier_block *nfb,
-				 unsigned long action, void *hcpu)
+static int via_cputemp_cpu_callback(struct notifier_block *nfb,
+				    unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned long) hcpu;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/hwmon/w83627ehf.c linux-libre-3.11-rc7-gnu/drivers/hwmon/w83627ehf.c
--- linux-libre-3.10-gnu/drivers/hwmon/w83627ehf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/hwmon/w83627ehf.c	2013-08-25 20:43:22.000000000 -0400
@@ -2598,7 +2598,6 @@ static int w83627ehf_probe(struct platfo
 exit_remove:
 	w83627ehf_device_remove_files(dev);
 exit_release:
-	platform_set_drvdata(pdev, NULL);
 	release_region(res->start, IOREGION_LENGTH);
 exit:
 	return err;
@@ -2611,7 +2610,6 @@ static int w83627ehf_remove(struct platf
 	hwmon_device_unregister(data->hwmon_dev);
 	w83627ehf_device_remove_files(&pdev->dev);
 	release_region(data->addr, IOREGION_LENGTH);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-bfin-twi.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-bfin-twi.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-bfin-twi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-bfin-twi.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,33 +39,40 @@ static void bfin_twi_handle_interrupt(st
 	unsigned short mast_stat = read_MASTER_STAT(iface);
 
 	if (twi_int_status & XMTSERV) {
+		if (iface->writeNum <= 0) {
+			/* start receive immediately after complete sending in
+			 * combine mode.
+			 */
+			if (iface->cur_mode == TWI_I2C_MODE_COMBINED)
+				write_MASTER_CTL(iface,
+					read_MASTER_CTL(iface) | MDIR);
+			else if (iface->manual_stop)
+				write_MASTER_CTL(iface,
+					read_MASTER_CTL(iface) | STOP);
+			else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+				iface->cur_msg + 1 < iface->msg_num) {
+				if (iface->pmsg[iface->cur_msg + 1].flags &
+					I2C_M_RD)
+					write_MASTER_CTL(iface,
+						read_MASTER_CTL(iface) |
+						MDIR);
+				else
+					write_MASTER_CTL(iface,
+						read_MASTER_CTL(iface) &
+						~MDIR);
+			}
+		}
 		/* Transmit next data */
-		if (iface->writeNum > 0) {
+		while (iface->writeNum > 0 &&
+			(read_FIFO_STAT(iface) & XMTSTAT) != XMT_FULL) {
 			SSYNC();
 			write_XMT_DATA8(iface, *(iface->transPtr++));
 			iface->writeNum--;
 		}
-		/* start receive immediately after complete sending in
-		 * combine mode.
-		 */
-		else if (iface->cur_mode == TWI_I2C_MODE_COMBINED)
-			write_MASTER_CTL(iface,
-				read_MASTER_CTL(iface) | MDIR);
-		else if (iface->manual_stop)
-			write_MASTER_CTL(iface,
-				read_MASTER_CTL(iface) | STOP);
-		else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
-		         iface->cur_msg + 1 < iface->msg_num) {
-			if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)
-				write_MASTER_CTL(iface,
-					read_MASTER_CTL(iface) | MDIR);
-			else
-				write_MASTER_CTL(iface,
-					read_MASTER_CTL(iface) & ~MDIR);
-		}
 	}
 	if (twi_int_status & RCVSERV) {
-		if (iface->readNum > 0) {
+		while (iface->readNum > 0 &&
+			(read_FIFO_STAT(iface) & RCVSTAT)) {
 			/* Receive next data */
 			*(iface->transPtr) = read_RCV_DATA8(iface);
 			if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-cpm.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-cpm.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-cpm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-cpm.c	2013-08-25 20:43:22.000000000 -0400
@@ -338,6 +338,14 @@ static int cpm_i2c_xfer(struct i2c_adapt
 	tptr = 0;
 	rptr = 0;
 
+	/*
+	 * If there was a collision in the last i2c transaction,
+	 * Set I2COM_MASTER as it was cleared during collision.
+	 */
+	if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) {
+		out_8(&cpm->i2c_reg->i2com, I2COM_MASTER);
+	}
+
 	while (tptr < num) {
 		pmsg = &msgs[tptr];
 		dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr);
@@ -646,7 +654,7 @@ static int cpm_i2c_probe(struct platform
 
 	cpm->ofdev = ofdev;
 
-	dev_set_drvdata(&ofdev->dev, cpm);
+	platform_set_drvdata(ofdev, cpm);
 
 	cpm->adap = cpm_ops;
 	i2c_set_adapdata(&cpm->adap, cpm);
@@ -689,7 +697,7 @@ out_free:
 
 static int cpm_i2c_remove(struct platform_device *ofdev)
 {
-	struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);
+	struct cpm_i2c *cpm = platform_get_drvdata(ofdev);
 
 	i2c_del_adapter(&cpm->adap);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-davinci.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-davinci.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-davinci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-davinci.c	2013-08-25 20:43:22.000000000 -0400
@@ -646,13 +646,6 @@ static int davinci_i2c_probe(struct plat
 	struct resource *mem, *irq;
 	int r;
 
-	/* NOTE: driver uses the static register mapping */
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem) {
-		dev_err(&pdev->dev, "no mem resource?\n");
-		return -ENODEV;
-	}
-
 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!irq) {
 		dev_err(&pdev->dev, "no irq resource?\n");
@@ -697,6 +690,7 @@ static int davinci_i2c_probe(struct plat
 		return -ENODEV;
 	clk_prepare_enable(dev->clk);
 
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dev->base = devm_ioremap_resource(&pdev->dev, mem);
 	if (IS_ERR(dev->base)) {
 		r = PTR_ERR(dev->base);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-designware-core.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-designware-core.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-designware-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-designware-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -67,9 +67,12 @@
 #define DW_IC_STATUS		0x70
 #define DW_IC_TXFLR		0x74
 #define DW_IC_RXFLR		0x78
+#define DW_IC_SDA_HOLD		0x7c
 #define DW_IC_TX_ABRT_SOURCE	0x80
 #define DW_IC_ENABLE_STATUS	0x9c
 #define DW_IC_COMP_PARAM_1	0xf4
+#define DW_IC_COMP_VERSION	0xf8
+#define DW_IC_SDA_HOLD_MIN_VERS	0x3131312A
 #define DW_IC_COMP_TYPE		0xfc
 #define DW_IC_COMP_TYPE_VALUE	0x44570140
 
@@ -332,6 +335,16 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
 	dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
 	dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
 
+	/* Configure SDA Hold Time if required */
+	if (dev->sda_hold_time) {
+		reg = dw_readl(dev, DW_IC_COMP_VERSION);
+		if (reg >= DW_IC_SDA_HOLD_MIN_VERS)
+			dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
+		else
+			dev_warn(dev->dev,
+				"Hardware too old to adjust SDA hold time.");
+	}
+
 	/* Configure Tx/Rx FIFO threshold levels */
 	dw_writel(dev, dev->tx_fifo_depth - 1, DW_IC_TX_TL);
 	dw_writel(dev, 0, DW_IC_RX_TL);
@@ -580,14 +593,23 @@ i2c_dw_xfer(struct i2c_adapter *adap, st
 	i2c_dw_xfer_init(dev);
 
 	/* wait for tx to complete */
-	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ);
+	ret = wait_for_completion_timeout(&dev->cmd_complete, HZ);
 	if (ret == 0) {
 		dev_err(dev->dev, "controller timed out\n");
+		/* i2c_dw_init implicitly disables the adapter */
 		i2c_dw_init(dev);
 		ret = -ETIMEDOUT;
 		goto done;
-	} else if (ret < 0)
-		goto done;
+	}
+
+	/*
+	 * We must disable the adapter before unlocking the &dev->lock mutex
+	 * below. Otherwise the hardware might continue generating interrupts
+	 * which in turn causes a race condition with the following transfer.
+	 * Needs some more investigation if the additional interrupts are
+	 * a hardware bug or this driver doesn't handle them correctly yet.
+	 */
+	__i2c_dw_enable(dev, false);
 
 	if (dev->msg_err) {
 		ret = dev->msg_err;
@@ -596,8 +618,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, st
 
 	/* no error */
 	if (likely(!dev->cmd_err)) {
-		/* Disable the adapter */
-		__i2c_dw_enable(dev, false);
 		ret = num;
 		goto done;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-designware-core.h linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-designware-core.h
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-designware-core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-designware-core.h	2013-08-25 20:43:22.000000000 -0400
@@ -90,6 +90,7 @@ struct dw_i2c_dev {
 	unsigned int		tx_fifo_depth;
 	unsigned int		rx_fifo_depth;
 	int			rx_outstanding;
+	u32			sda_hold_time;
 };
 
 #define ACCESS_SWAP		0x00000001
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-designware-platdrv.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-designware-platdrv.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-designware-platdrv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-designware-platdrv.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/of.h>
 #include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
@@ -87,13 +88,6 @@ static int dw_i2c_probe(struct platform_
 	struct resource *mem;
 	int irq, r;
 
-	/* NOTE: driver uses the static register mapping */
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem) {
-		dev_err(&pdev->dev, "no mem resource?\n");
-		return -EINVAL;
-	}
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		dev_err(&pdev->dev, "no irq resource?\n");
@@ -104,6 +98,7 @@ static int dw_i2c_probe(struct platform_
 	if (!dev)
 		return -ENOMEM;
 
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dev->base = devm_ioremap_resource(&pdev->dev, mem);
 	if (IS_ERR(dev->base))
 		return PTR_ERR(dev->base);
@@ -121,6 +116,16 @@ static int dw_i2c_probe(struct platform_
 		return PTR_ERR(dev->clk);
 	clk_prepare_enable(dev->clk);
 
+	if (pdev->dev.of_node) {
+		u32 ht = 0;
+		u32 ic_clk = dev->get_clk_rate_khz(dev);
+
+		of_property_read_u32(pdev->dev.of_node,
+					"i2c-sda-hold-time-ns", &ht);
+		dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,
+					     1000000);
+	}
+
 	dev->functionality =
 		I2C_FUNC_I2C |
 		I2C_FUNC_10BIT_ADDR |
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-i801.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-i801.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-i801.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-i801.c	2013-08-25 20:43:22.000000000 -0400
@@ -58,6 +58,7 @@
   Wellsburg (PCH) MS    0x8d7d     32     hard     yes     yes     yes
   Wellsburg (PCH) MS    0x8d7e     32     hard     yes     yes     yes
   Wellsburg (PCH) MS    0x8d7f     32     hard     yes     yes     yes
+  Coleto Creek (PCH)    0x23b0     32     hard     yes     yes     yes
 
   Features supported by this driver:
   Software PEC                     no
@@ -169,6 +170,7 @@
 #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS	0x1e22
 #define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS	0x1f3c
 #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS	0x2330
+#define PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS	0x23b0
 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS	0x3b30
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS	0x8c22
 #define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS	0x8d22
@@ -817,6 +819,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids)
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) },
 	{ 0, }
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-ibm_iic.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-ibm_iic.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-ibm_iic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-ibm_iic.c	2013-08-25 20:43:22.000000000 -0400
@@ -705,7 +705,7 @@ static int iic_probe(struct platform_dev
 		return -ENOMEM;
 	}
 
-	dev_set_drvdata(&ofdev->dev, dev);
+	platform_set_drvdata(ofdev, dev);
 
 	dev->vaddr = of_iomap(np, 0);
 	if (dev->vaddr == NULL) {
@@ -782,7 +782,7 @@ error_cleanup:
  */
 static int iic_remove(struct platform_device *ofdev)
 {
-	struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev);
+	struct ibm_iic_private *dev = platform_get_drvdata(ofdev);
 
 	i2c_del_adapter(&dev->adap);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-imx.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-imx.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-imx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-imx.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,7 +51,6 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_i2c.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/platform_data/i2c-imx.h>
 
 /** Defines ********************************************************************
@@ -148,6 +147,7 @@ static const struct of_device_id i2c_imx
 	{ .compatible = "fsl,imx21-i2c", .data = &imx_i2c_devtype[IMX21_I2C], },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
 
 static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
 {
@@ -493,24 +493,19 @@ static int __init i2c_imx_probe(struct p
 	struct imx_i2c_struct *i2c_imx;
 	struct resource *res;
 	struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
-	struct pinctrl *pinctrl;
 	void __iomem *base;
 	int irq, ret;
 	u32 bitrate;
 
 	dev_dbg(&pdev->dev, "<%s>\n", __func__);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "can't get device resources\n");
-		return -ENOENT;
-	}
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		dev_err(&pdev->dev, "can't get irq number\n");
 		return -ENOENT;
 	}
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
@@ -535,12 +530,6 @@ static int __init i2c_imx_probe(struct p
 	i2c_imx->adapter.dev.of_node	= pdev->dev.of_node;
 	i2c_imx->base			= base;
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl)) {
-		dev_err(&pdev->dev, "can't get/select pinctrl\n");
-		return PTR_ERR(pinctrl);
-	}
-
 	/* Get I2C clock */
 	i2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(i2c_imx->clk)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-intel-mid.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-intel-mid.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-intel-mid.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-intel-mid.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1121 +0,0 @@
-/*
- * Support for Moorestown/Medfield I2C chip
- *
- * Copyright (c) 2009 Intel Corporation.
- * Copyright (c) 2009 Synopsys. Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License, version
- * 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/pm_runtime.h>
-#include <linux/io.h>
-
-#define DRIVER_NAME	"i2c-intel-mid"
-#define VERSION		"Version 0.5ac2"
-#define PLATFORM	"Moorestown/Medfield"
-
-/* Tables use: 0 Moorestown, 1 Medfield */
-#define NUM_PLATFORMS	2
-enum platform_enum {
-	MOORESTOWN = 0,
-	MEDFIELD = 1,
-};
-
-enum mid_i2c_status {
-	STATUS_IDLE = 0,
-	STATUS_READ_START,
-	STATUS_READ_IN_PROGRESS,
-	STATUS_READ_SUCCESS,
-	STATUS_WRITE_START,
-	STATUS_WRITE_SUCCESS,
-	STATUS_XFER_ABORT,
-	STATUS_STANDBY
-};
-
-/**
- * struct intel_mid_i2c_private	- per device I²C context
- * @adap: core i2c layer adapter information
- * @dev: device reference for power management
- * @base: register base
- * @speed: speed mode for this port
- * @complete: completion object for transaction wait
- * @abort: reason for last abort
- * @rx_buf: pointer into working receive buffer
- * @rx_buf_len: receive buffer length
- * @status: adapter state machine
- * @msg: the message we are currently processing
- * @platform: the MID device type we are part of
- * @lock: transaction serialization
- *
- * We allocate one of these per device we discover, it holds the core
- * i2c layer objects and the data we need to track privately.
- */
-struct intel_mid_i2c_private {
-	struct i2c_adapter adap;
-	struct device *dev;
-	void __iomem *base;
-	int speed;
-	struct completion complete;
-	int abort;
-	u8 *rx_buf;
-	int rx_buf_len;
-	enum mid_i2c_status status;
-	struct i2c_msg *msg;
-	enum platform_enum platform;
-	struct mutex lock;
-};
-
-#define NUM_SPEEDS		3
-
-#define ACTIVE			0
-#define STANDBY			1
-
-
-/* Control register */
-#define IC_CON			0x00
-#define SLV_DIS			(1 << 6)	/* Disable slave mode */
-#define RESTART			(1 << 5)	/* Send a Restart condition */
-#define	ADDR_10BIT		(1 << 4)	/* 10-bit addressing */
-#define	STANDARD_MODE		(1 << 1)	/* standard mode */
-#define FAST_MODE		(2 << 1)	/* fast mode */
-#define HIGH_MODE		(3 << 1)	/* high speed mode */
-#define	MASTER_EN		(1 << 0)	/* Master mode */
-
-/* Target address register */
-#define IC_TAR			0x04
-#define IC_TAR_10BIT_ADDR	(1 << 12)	/* 10-bit addressing */
-#define IC_TAR_SPECIAL		(1 << 11)	/* Perform special I2C cmd */
-#define IC_TAR_GC_OR_START	(1 << 10)	/* 0: Gerneral Call Address */
-						/* 1: START BYTE */
-/* Slave Address Register */
-#define IC_SAR			0x08		/* Not used in Master mode */
-
-/* High Speed Master Mode Code Address Register */
-#define IC_HS_MADDR		0x0c
-
-/* Rx/Tx Data Buffer and Command Register */
-#define IC_DATA_CMD		0x10
-#define IC_RD			(1 << 8)	/* 1: Read 0: Write */
-
-/* Standard Speed Clock SCL High Count Register */
-#define IC_SS_SCL_HCNT		0x14
-
-/* Standard Speed Clock SCL Low Count Register */
-#define IC_SS_SCL_LCNT		0x18
-
-/* Fast Speed Clock SCL High Count Register */
-#define IC_FS_SCL_HCNT		0x1c
-
-/* Fast Spedd Clock SCL Low Count Register */
-#define IC_FS_SCL_LCNT		0x20
-
-/* High Speed Clock SCL High Count Register */
-#define IC_HS_SCL_HCNT		0x24
-
-/* High Speed Clock SCL Low Count Register */
-#define IC_HS_SCL_LCNT		0x28
-
-/* Interrupt Status Register */
-#define IC_INTR_STAT		0x2c		/* Read only */
-#define R_GEN_CALL		(1 << 11)
-#define R_START_DET		(1 << 10)
-#define R_STOP_DET		(1 << 9)
-#define R_ACTIVITY		(1 << 8)
-#define R_RX_DONE		(1 << 7)
-#define	R_TX_ABRT		(1 << 6)
-#define R_RD_REQ		(1 << 5)
-#define R_TX_EMPTY		(1 << 4)
-#define R_TX_OVER		(1 << 3)
-#define	R_RX_FULL		(1 << 2)
-#define	R_RX_OVER		(1 << 1)
-#define R_RX_UNDER		(1 << 0)
-
-/* Interrupt Mask Register */
-#define IC_INTR_MASK		0x30		/* Read and Write */
-#define M_GEN_CALL		(1 << 11)
-#define M_START_DET		(1 << 10)
-#define M_STOP_DET		(1 << 9)
-#define M_ACTIVITY		(1 << 8)
-#define M_RX_DONE		(1 << 7)
-#define	M_TX_ABRT		(1 << 6)
-#define M_RD_REQ		(1 << 5)
-#define M_TX_EMPTY		(1 << 4)
-#define M_TX_OVER		(1 << 3)
-#define	M_RX_FULL		(1 << 2)
-#define	M_RX_OVER		(1 << 1)
-#define M_RX_UNDER		(1 << 0)
-
-/* Raw Interrupt Status Register */
-#define IC_RAW_INTR_STAT	0x34		/* Read Only */
-#define GEN_CALL		(1 << 11)	/* General call */
-#define START_DET		(1 << 10)	/* (RE)START occurred */
-#define STOP_DET		(1 << 9)	/* STOP occurred */
-#define ACTIVITY		(1 << 8)	/* Bus busy */
-#define RX_DONE			(1 << 7)	/* Not used in Master mode */
-#define	TX_ABRT			(1 << 6)	/* Transmit Abort */
-#define RD_REQ			(1 << 5)	/* Not used in Master mode */
-#define TX_EMPTY		(1 << 4)	/* TX FIFO <= threshold */
-#define TX_OVER			(1 << 3)	/* TX FIFO overflow */
-#define	RX_FULL			(1 << 2)	/* RX FIFO >= threshold */
-#define	RX_OVER			(1 << 1)	/* RX FIFO overflow */
-#define RX_UNDER		(1 << 0)	/* RX FIFO empty */
-
-/* Receive FIFO Threshold Register */
-#define IC_RX_TL		0x38
-
-/* Transmit FIFO Treshold Register */
-#define IC_TX_TL		0x3c
-
-/* Clear Combined and Individual Interrupt Register */
-#define IC_CLR_INTR		0x40
-#define CLR_INTR		(1 << 0)
-
-/* Clear RX_UNDER Interrupt Register */
-#define IC_CLR_RX_UNDER		0x44
-#define CLR_RX_UNDER		(1 << 0)
-
-/* Clear RX_OVER Interrupt Register */
-#define IC_CLR_RX_OVER		0x48
-#define CLR_RX_OVER		(1 << 0)
-
-/* Clear TX_OVER Interrupt Register */
-#define IC_CLR_TX_OVER		0x4c
-#define CLR_TX_OVER		(1 << 0)
-
-#define IC_CLR_RD_REQ		0x50
-
-/* Clear TX_ABRT Interrupt Register */
-#define IC_CLR_TX_ABRT		0x54
-#define CLR_TX_ABRT		(1 << 0)
-#define IC_CLR_RX_DONE		0x58
-
-/* Clear ACTIVITY Interrupt Register */
-#define IC_CLR_ACTIVITY		0x5c
-#define CLR_ACTIVITY		(1 << 0)
-
-/* Clear STOP_DET Interrupt Register */
-#define IC_CLR_STOP_DET		0x60
-#define CLR_STOP_DET		(1 << 0)
-
-/* Clear START_DET Interrupt Register */
-#define IC_CLR_START_DET	0x64
-#define CLR_START_DET		(1 << 0)
-
-/* Clear GEN_CALL Interrupt Register */
-#define IC_CLR_GEN_CALL		0x68
-#define CLR_GEN_CALL		(1 << 0)
-
-/* Enable Register */
-#define IC_ENABLE		0x6c
-#define ENABLE			(1 << 0)
-
-/* Status Register */
-#define IC_STATUS		0x70		/* Read Only */
-#define STAT_SLV_ACTIVITY	(1 << 6)	/* Slave not in idle */
-#define STAT_MST_ACTIVITY	(1 << 5)	/* Master not in idle */
-#define STAT_RFF		(1 << 4)	/* RX FIFO Full */
-#define STAT_RFNE		(1 << 3)	/* RX FIFO Not Empty */
-#define STAT_TFE		(1 << 2)	/* TX FIFO Empty */
-#define STAT_TFNF		(1 << 1)	/* TX FIFO Not Full */
-#define STAT_ACTIVITY		(1 << 0)	/* Activity Status */
-
-/* Transmit FIFO Level Register */
-#define IC_TXFLR		0x74		/* Read Only */
-#define TXFLR			(1 << 0)	/* TX FIFO level */
-
-/* Receive FIFO Level Register */
-#define IC_RXFLR		0x78		/* Read Only */
-#define RXFLR			(1 << 0)	/* RX FIFO level */
-
-/* Transmit Abort Source Register */
-#define IC_TX_ABRT_SOURCE	0x80
-#define ABRT_SLVRD_INTX		(1 << 15)
-#define ABRT_SLV_ARBLOST	(1 << 14)
-#define ABRT_SLVFLUSH_TXFIFO	(1 << 13)
-#define	ARB_LOST		(1 << 12)
-#define ABRT_MASTER_DIS		(1 << 11)
-#define ABRT_10B_RD_NORSTRT	(1 << 10)
-#define ABRT_SBYTE_NORSTRT	(1 << 9)
-#define ABRT_HS_NORSTRT		(1 << 8)
-#define ABRT_SBYTE_ACKDET	(1 << 7)
-#define ABRT_HS_ACKDET		(1 << 6)
-#define ABRT_GCALL_READ		(1 << 5)
-#define ABRT_GCALL_NOACK	(1 << 4)
-#define ABRT_TXDATA_NOACK	(1 << 3)
-#define ABRT_10ADDR2_NOACK	(1 << 2)
-#define ABRT_10ADDR1_NOACK	(1 << 1)
-#define ABRT_7B_ADDR_NOACK	(1 << 0)
-
-/* Enable Status Register */
-#define IC_ENABLE_STATUS	0x9c
-#define IC_EN			(1 << 0)	/* I2C in an enabled state */
-
-/* Component Parameter Register 1*/
-#define IC_COMP_PARAM_1		0xf4
-#define APB_DATA_WIDTH		(0x3 << 0)
-
-/* added by xiaolin --begin */
-#define SS_MIN_SCL_HIGH         4000
-#define SS_MIN_SCL_LOW          4700
-#define FS_MIN_SCL_HIGH         600
-#define FS_MIN_SCL_LOW          1300
-#define HS_MIN_SCL_HIGH_100PF   60
-#define HS_MIN_SCL_LOW_100PF    120
-
-#define STANDARD		0
-#define FAST			1
-#define HIGH			2
-
-#define NUM_SPEEDS		3
-
-static int speed_mode[6] = {
-	FAST,
-	FAST,
-	FAST,
-	STANDARD,
-	FAST,
-	FAST
-};
-
-static int ctl_num = 6;
-module_param_array(speed_mode, int, &ctl_num, S_IRUGO);
-MODULE_PARM_DESC(speed_mode, "Set the speed of the i2c interface (0-2)");
-
-/**
- * intel_mid_i2c_disable - Disable I2C controller
- * @adap: struct pointer to i2c_adapter
- *
- * Return Value:
- * 0		success
- * -EBUSY	if device is busy
- * -ETIMEDOUT	if i2c cannot be disabled within the given time
- *
- * I2C bus state should be checked prior to disabling the hardware. If bus is
- * not in idle state, an errno is returned. Write "0" to IC_ENABLE to disable
- * I2C controller.
- */
-static int intel_mid_i2c_disable(struct i2c_adapter *adap)
-{
-	struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
-	int err = 0;
-	int count = 0;
-	int ret1, ret2;
-	static const u16 delay[NUM_SPEEDS] = {100, 25, 3};
-
-	/* Set IC_ENABLE to 0 */
-	writel(0, i2c->base + IC_ENABLE);
-
-	/* Check if device is busy */
-	dev_dbg(&adap->dev, "mrst i2c disable\n");
-	while ((ret1 = readl(i2c->base + IC_ENABLE_STATUS) & 0x1)
-		|| (ret2 = readl(i2c->base + IC_STATUS) & 0x1)) {
-		udelay(delay[i2c->speed]);
-		writel(0, i2c->base + IC_ENABLE);
-		dev_dbg(&adap->dev, "i2c is busy, count is %d speed %d\n",
-			count, i2c->speed);
-		if (count++ > 10) {
-			err = -ETIMEDOUT;
-			break;
-		}
-	}
-
-	/* Clear all interrupts */
-	readl(i2c->base + IC_CLR_INTR);
-	readl(i2c->base + IC_CLR_STOP_DET);
-	readl(i2c->base + IC_CLR_START_DET);
-	readl(i2c->base + IC_CLR_ACTIVITY);
-	readl(i2c->base + IC_CLR_TX_ABRT);
-	readl(i2c->base + IC_CLR_RX_OVER);
-	readl(i2c->base + IC_CLR_RX_UNDER);
-	readl(i2c->base + IC_CLR_TX_OVER);
-	readl(i2c->base + IC_CLR_RX_DONE);
-	readl(i2c->base + IC_CLR_GEN_CALL);
-
-	/* Disable all interupts */
-	writel(0x0000, i2c->base + IC_INTR_MASK);
-
-	return err;
-}
-
-/**
- * intel_mid_i2c_hwinit - Initialize the I2C hardware registers
- * @dev: pci device struct pointer
- *
- * This function will be called in intel_mid_i2c_probe() before device
- * registration.
- *
- * Return Values:
- * 0		success
- * -EBUSY	i2c cannot be disabled
- * -ETIMEDOUT	i2c cannot be disabled
- * -EFAULT	If APB data width is not 32-bit wide
- *
- * I2C should be disabled prior to other register operation. If failed, an
- * errno is returned. Mask and Clear all interrpts, this should be done at
- * first.  Set common registers which will not be modified during normal
- * transfers, including: control register, FIFO threshold and clock freq.
- * Check APB data width at last.
- */
-static int intel_mid_i2c_hwinit(struct intel_mid_i2c_private *i2c)
-{
-	int err;
-
-	static const u16 hcnt[NUM_PLATFORMS][NUM_SPEEDS] = {
-		{ 0x75,  0x15, 0x07 },
-		{ 0x04c,  0x10, 0x06 }
-	};
-	static const u16 lcnt[NUM_PLATFORMS][NUM_SPEEDS] = {
-		{ 0x7C,  0x21, 0x0E },
-		{ 0x053, 0x19, 0x0F }
-	};
-
-	/* Disable i2c first */
-	err = intel_mid_i2c_disable(&i2c->adap);
-	if (err)
-		return err;
-
-	/*
-	 * Setup clock frequency and speed mode
-	 * Enable restart condition,
-	 * enable master FSM, disable slave FSM,
-	 * use target address when initiating transfer
-	 */
-
-	writel((i2c->speed + 1) << 1 | SLV_DIS | RESTART | MASTER_EN,
-		i2c->base + IC_CON);
-	writel(hcnt[i2c->platform][i2c->speed],
-		i2c->base + (IC_SS_SCL_HCNT + (i2c->speed << 3)));
-	writel(lcnt[i2c->platform][i2c->speed],
-		i2c->base + (IC_SS_SCL_LCNT + (i2c->speed << 3)));
-
-	/* Set tranmit & receive FIFO threshold to zero */
-	writel(0x0, i2c->base + IC_RX_TL);
-	writel(0x0, i2c->base + IC_TX_TL);
-
-	return 0;
-}
-
-/**
- * intel_mid_i2c_func - Return the supported three I2C operations.
- * @adapter: i2c_adapter struct pointer
- */
-static u32 intel_mid_i2c_func(struct i2c_adapter *adapter)
-{
-	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
-}
-
-/**
- * intel_mid_i2c_address_neq - To check if the addresses for different i2c messages
- * are equal.
- * @p1: first i2c_msg
- * @p2: second i2c_msg
- *
- * Return Values:
- * 0	 if addresses are equal
- * 1	 if not equal
- *
- * Within a single transfer, the I2C client may need to send its address more
- * than once. So a check if the addresses match is needed.
- */
-static inline bool intel_mid_i2c_address_neq(const struct i2c_msg *p1,
-				       const struct i2c_msg *p2)
-{
-	if (p1->addr != p2->addr)
-		return 1;
-	if ((p1->flags ^ p2->flags) & I2C_M_TEN)
-		return 1;
-	return 0;
-}
-
-/**
- * intel_mid_i2c_abort - To handle transfer abortions and print error messages.
- * @adap: i2c_adapter struct pointer
- *
- * By reading register IC_TX_ABRT_SOURCE, various transfer errors can be
- * distingushed. At present, no circumstances have been found out that
- * multiple errors would be occurred simutaneously, so we simply use the
- * register value directly.
- *
- * At last the error bits are cleared. (Note clear ABRT_SBYTE_NORSTRT bit need
- * a few extra steps)
- */
-static void intel_mid_i2c_abort(struct intel_mid_i2c_private *i2c)
-{
-	/* Read about source register */
-	int abort = i2c->abort;
-	struct i2c_adapter *adap = &i2c->adap;
-
-	/* Single transfer error check:
-	 * According to databook, TX/RX FIFOs would be flushed when
-	 * the abort interrupt occurred.
-	 */
-	if (abort & ABRT_MASTER_DIS)
-		dev_err(&adap->dev,
-		"initiate master operation with master mode disabled.\n");
-	if (abort & ABRT_10B_RD_NORSTRT)
-		dev_err(&adap->dev,
-	"RESTART disabled and master sent READ cmd in 10-bit addressing.\n");
-
-	if (abort & ABRT_SBYTE_NORSTRT) {
-		dev_err(&adap->dev,
-		"RESTART disabled and user is trying to send START byte.\n");
-		writel(~ABRT_SBYTE_NORSTRT, i2c->base + IC_TX_ABRT_SOURCE);
-		writel(RESTART, i2c->base + IC_CON);
-		writel(~IC_TAR_SPECIAL, i2c->base + IC_TAR);
-	}
-
-	if (abort & ABRT_SBYTE_ACKDET)
-		dev_err(&adap->dev,
-			"START byte was not acknowledged.\n");
-	if (abort & ABRT_TXDATA_NOACK)
-		dev_dbg(&adap->dev,
-			"No acknowledgement received from slave.\n");
-	if (abort & ABRT_10ADDR2_NOACK)
-		dev_dbg(&adap->dev,
-	"The 2nd address byte of the 10-bit address was not acknowledged.\n");
-	if (abort & ABRT_10ADDR1_NOACK)
-		dev_dbg(&adap->dev,
-	"The 1st address byte of 10-bit address was not acknowledged.\n");
-	if (abort & ABRT_7B_ADDR_NOACK)
-		dev_dbg(&adap->dev,
-			"I2C slave device not acknowledged.\n");
-
-	/* Clear TX_ABRT bit */
-	readl(i2c->base + IC_CLR_TX_ABRT);
-	i2c->status = STATUS_XFER_ABORT;
-}
-
-/**
- * xfer_read - Internal function to implement master read transfer.
- * @adap: i2c_adapter struct pointer
- * @buf: buffer in i2c_msg
- * @length: number of bytes to be read
- *
- * Return Values:
- * 0		if the read transfer succeeds
- * -ETIMEDOUT	if cannot read the "raw" interrupt register
- * -EINVAL	if a transfer abort occurred
- *
- * For every byte, a "READ" command will be loaded into IC_DATA_CMD prior to
- * data transfer. The actual "read" operation will be performed if an RX_FULL
- * interrupt occurred.
- *
- * Note there may be two interrupt signals captured, one should read
- * IC_RAW_INTR_STAT to separate between errors and actual data.
- */
-static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
-{
-	struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
-	int i = length;
-	int err;
-
-	if (length >= 256) {
-		dev_err(&adap->dev,
-			"I2C FIFO cannot support larger than 256 bytes\n");
-		return -EMSGSIZE;
-	}
-
-	INIT_COMPLETION(i2c->complete);
-
-	readl(i2c->base + IC_CLR_INTR);
-	writel(0x0044, i2c->base + IC_INTR_MASK);
-
-	i2c->status = STATUS_READ_START;
-
-	while (i--)
-		writel(IC_RD, i2c->base + IC_DATA_CMD);
-
-	i2c->status = STATUS_READ_START;
-	err = wait_for_completion_interruptible_timeout(&i2c->complete, HZ);
-	if (!err) {
-		dev_err(&adap->dev, "Timeout for ACK from I2C slave device\n");
-		intel_mid_i2c_hwinit(i2c);
-		return -ETIMEDOUT;
-	}
-	if (i2c->status == STATUS_READ_SUCCESS)
-		return 0;
-	else
-		return -EIO;
-}
-
-/**
- * xfer_write - Internal function to implement master write transfer.
- * @adap: i2c_adapter struct pointer
- * @buf: buffer in i2c_msg
- * @length: number of bytes to be read
- *
- * Return Values:
- * 0	if the read transfer succeeds
- * -ETIMEDOUT	if we cannot read the "raw" interrupt register
- * -EINVAL	if a transfer abort occurred
- *
- * For every byte, a "WRITE" command will be loaded into IC_DATA_CMD prior to
- * data transfer. The actual "write" operation will be performed when the
- * RX_FULL interrupt signal occurs.
- *
- * Note there may be two interrupt signals captured, one should read
- * IC_RAW_INTR_STAT to separate between errors and actual data.
- */
-static int xfer_write(struct i2c_adapter *adap,
-		      unsigned char *buf, int length)
-{
-	struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
-	int i, err;
-
-	if (length >= 256) {
-		dev_err(&adap->dev,
-			"I2C FIFO cannot support larger than 256 bytes\n");
-		return -EMSGSIZE;
-	}
-
-	INIT_COMPLETION(i2c->complete);
-
-	readl(i2c->base + IC_CLR_INTR);
-	writel(0x0050, i2c->base + IC_INTR_MASK);
-
-	i2c->status = STATUS_WRITE_START;
-	for (i = 0; i < length; i++)
-		writel((u16)(*(buf + i)), i2c->base + IC_DATA_CMD);
-
-	i2c->status = STATUS_WRITE_START;
-	err = wait_for_completion_interruptible_timeout(&i2c->complete, HZ);
-	if (!err) {
-		dev_err(&adap->dev, "Timeout for ACK from I2C slave device\n");
-		intel_mid_i2c_hwinit(i2c);
-		return -ETIMEDOUT;
-	} else {
-		if (i2c->status == STATUS_WRITE_SUCCESS)
-			return 0;
-		else
-			return -EIO;
-	}
-}
-
-static int intel_mid_i2c_setup(struct i2c_adapter *adap,  struct i2c_msg *pmsg)
-{
-	struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
-	int err;
-	u32 reg;
-	u32 bit_mask;
-	u32 mode;
-
-	/* Disable device first */
-	err = intel_mid_i2c_disable(adap);
-	if (err) {
-		dev_err(&adap->dev,
-			"Cannot disable i2c controller, timeout\n");
-		return err;
-	}
-
-	mode = (1 + i2c->speed) << 1;
-	/* set the speed mode */
-	reg = readl(i2c->base + IC_CON);
-	if ((reg & 0x06) != mode) {
-		dev_dbg(&adap->dev, "set mode %d\n", i2c->speed);
-		writel((reg & ~0x6) | mode, i2c->base + IC_CON);
-	}
-
-	reg = readl(i2c->base + IC_CON);
-	/* use 7-bit addressing */
-	if (pmsg->flags & I2C_M_TEN) {
-		if ((reg & ADDR_10BIT) != ADDR_10BIT) {
-			dev_dbg(&adap->dev, "set i2c 10 bit address mode\n");
-			writel(reg | ADDR_10BIT, i2c->base + IC_CON);
-		}
-	} else {
-		if ((reg & ADDR_10BIT) != 0x0) {
-			dev_dbg(&adap->dev, "set i2c 7 bit address mode\n");
-			writel(reg & ~ADDR_10BIT, i2c->base + IC_CON);
-		}
-	}
-	/* enable restart conditions */
-	reg = readl(i2c->base + IC_CON);
-	if ((reg & RESTART) != RESTART) {
-		dev_dbg(&adap->dev, "enable restart conditions\n");
-		writel(reg | RESTART, i2c->base + IC_CON);
-	}
-
-	/* enable master FSM */
-	reg = readl(i2c->base + IC_CON);
-	dev_dbg(&adap->dev, "ic_con reg is 0x%x\n", reg);
-	writel(reg | MASTER_EN, i2c->base + IC_CON);
-	if ((reg & SLV_DIS) != SLV_DIS) {
-		dev_dbg(&adap->dev, "enable master FSM\n");
-		writel(reg | SLV_DIS, i2c->base + IC_CON);
-		dev_dbg(&adap->dev, "ic_con reg is 0x%x\n", reg);
-	}
-
-	/* use target address when initiating transfer */
-	reg = readl(i2c->base + IC_TAR);
-	bit_mask = IC_TAR_SPECIAL | IC_TAR_GC_OR_START;
-
-	if ((reg & bit_mask) != 0x0) {
-		dev_dbg(&adap->dev,
-	 "WR: use target address when intiating transfer, i2c_tx_target\n");
-		writel(reg & ~bit_mask, i2c->base + IC_TAR);
-	}
-
-	/* set target address to the I2C slave address */
-	dev_dbg(&adap->dev,
-		"set target address to the I2C slave address, addr is %x\n",
-			pmsg->addr);
-	writel(pmsg->addr | (pmsg->flags & I2C_M_TEN ? IC_TAR_10BIT_ADDR : 0),
-		i2c->base + IC_TAR);
-
-	/* Enable I2C controller */
-	writel(ENABLE, i2c->base + IC_ENABLE);
-
-	return 0;
-}
-
-/**
- * intel_mid_i2c_xfer - Main master transfer routine.
- * @adap: i2c_adapter struct pointer
- * @pmsg: i2c_msg struct pointer
- * @num: number of i2c_msg
- *
- * Return Values:
- * +		number of messages transferred
- * -ETIMEDOUT	If cannot disable I2C controller or read IC_STATUS
- * -EINVAL	If the address in i2c_msg is invalid
- *
- * This function will be registered in i2c-core and exposed to external
- * I2C clients.
- * 1. Disable I2C controller
- * 2. Unmask three interrupts: RX_FULL, TX_EMPTY, TX_ABRT
- * 3. Check if address in i2c_msg is valid
- * 4. Enable I2C controller
- * 5. Perform real transfer (call xfer_read or xfer_write)
- * 6. Wait until the current transfer is finished (check bus state)
- * 7. Mask and clear all interrupts
- */
-static int intel_mid_i2c_xfer(struct i2c_adapter *adap,
-			 struct i2c_msg *pmsg,
-			 int num)
-{
-	struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
-	int i, err = 0;
-
-	/* if number of messages equal 0*/
-	if (num == 0)
-		return 0;
-
-	pm_runtime_get(i2c->dev);
-
-	mutex_lock(&i2c->lock);
-	dev_dbg(&adap->dev, "intel_mid_i2c_xfer, process %d msg(s)\n", num);
-	dev_dbg(&adap->dev, "slave address is %x\n", pmsg->addr);
-
-
-	if (i2c->status != STATUS_IDLE) {
-		dev_err(&adap->dev, "Adapter %d in transfer/standby\n",
-								adap->nr);
-		mutex_unlock(&i2c->lock);
-		pm_runtime_put(i2c->dev);
-		return -1;
-	}
-
-
-	for (i = 1; i < num; i++) {
-		/* Message address equal? */
-		if (unlikely(intel_mid_i2c_address_neq(&pmsg[0], &pmsg[i]))) {
-			dev_err(&adap->dev, "Invalid address in msg[%d]\n", i);
-			mutex_unlock(&i2c->lock);
-			pm_runtime_put(i2c->dev);
-			return -EINVAL;
-		}
-	}
-
-	if (intel_mid_i2c_setup(adap, pmsg)) {
-		mutex_unlock(&i2c->lock);
-		pm_runtime_put(i2c->dev);
-		return -EINVAL;
-	}
-
-	for (i = 0; i < num; i++) {
-		i2c->msg = pmsg;
-		i2c->status = STATUS_IDLE;
-		/* Read or Write */
-		if (pmsg->flags & I2C_M_RD) {
-			dev_dbg(&adap->dev, "I2C_M_RD\n");
-			err = xfer_read(adap, pmsg->buf, pmsg->len);
-		} else {
-			dev_dbg(&adap->dev, "I2C_M_WR\n");
-			err = xfer_write(adap, pmsg->buf, pmsg->len);
-		}
-		if (err < 0)
-			break;
-		dev_dbg(&adap->dev, "msg[%d] transfer complete\n", i);
-		pmsg++;		/* next message */
-	}
-
-	/* Mask interrupts */
-	writel(0x0000, i2c->base + IC_INTR_MASK);
-	/* Clear all interrupts */
-	readl(i2c->base + IC_CLR_INTR);
-
-	i2c->status = STATUS_IDLE;
-	mutex_unlock(&i2c->lock);
-	pm_runtime_put(i2c->dev);
-
-	return err;
-}
-
-static int intel_mid_i2c_runtime_suspend(struct device *dev)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct intel_mid_i2c_private *i2c = pci_get_drvdata(pdev);
-	struct i2c_adapter *adap = to_i2c_adapter(dev);
-	int err;
-
-	if (i2c->status != STATUS_IDLE)
-		return -1;
-
-	intel_mid_i2c_disable(adap);
-
-	err = pci_save_state(pdev);
-	if (err) {
-		dev_err(dev, "pci_save_state failed\n");
-		return err;
-	}
-
-	err = pci_set_power_state(pdev, PCI_D3hot);
-	if (err) {
-		dev_err(dev, "pci_set_power_state failed\n");
-		return err;
-	}
-	i2c->status = STATUS_STANDBY;
-
-	return 0;
-}
-
-static int intel_mid_i2c_runtime_resume(struct device *dev)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct intel_mid_i2c_private *i2c = pci_get_drvdata(pdev);
-	int err;
-
-	if (i2c->status != STATUS_STANDBY)
-		return 0;
-
-	pci_set_power_state(pdev, PCI_D0);
-	pci_restore_state(pdev);
-	err = pci_enable_device(pdev);
-	if (err) {
-		dev_err(dev, "pci_enable_device failed\n");
-		return err;
-	}
-
-	i2c->status = STATUS_IDLE;
-
-	intel_mid_i2c_hwinit(i2c);
-	return err;
-}
-
-static void i2c_isr_read(struct intel_mid_i2c_private *i2c)
-{
-	struct i2c_msg *msg = i2c->msg;
-	int rx_num;
-	u32 len;
-	u8 *buf;
-
-	if (!(msg->flags & I2C_M_RD))
-		return;
-
-	if (i2c->status != STATUS_READ_IN_PROGRESS) {
-		len = msg->len;
-		buf = msg->buf;
-	} else {
-		len = i2c->rx_buf_len;
-		buf = i2c->rx_buf;
-	}
-
-	rx_num = readl(i2c->base + IC_RXFLR);
-
-	for (; len > 0 && rx_num > 0; len--, rx_num--)
-		*buf++ = readl(i2c->base + IC_DATA_CMD);
-
-	if (len > 0) {
-		i2c->status = STATUS_READ_IN_PROGRESS;
-		i2c->rx_buf_len = len;
-		i2c->rx_buf = buf;
-	} else
-		i2c->status = STATUS_READ_SUCCESS;
-
-	return;
-}
-
-static irqreturn_t intel_mid_i2c_isr(int this_irq, void *dev)
-{
-	struct intel_mid_i2c_private *i2c = dev;
-	u32 stat = readl(i2c->base + IC_INTR_STAT);
-
-	if (!stat)
-		return IRQ_NONE;
-
-	dev_dbg(&i2c->adap.dev, "%s, stat = 0x%x\n", __func__, stat);
-	stat &= 0x54;
-
-	if (i2c->status != STATUS_WRITE_START &&
-	    i2c->status != STATUS_READ_START &&
-	    i2c->status != STATUS_READ_IN_PROGRESS)
-		goto err;
-
-	if (stat & TX_ABRT)
-		i2c->abort = readl(i2c->base + IC_TX_ABRT_SOURCE);
-
-	readl(i2c->base + IC_CLR_INTR);
-
-	if (stat & TX_ABRT) {
-		intel_mid_i2c_abort(i2c);
-		goto exit;
-	}
-
-	if (stat & RX_FULL) {
-		i2c_isr_read(i2c);
-		goto exit;
-	}
-
-	if (stat & TX_EMPTY) {
-		if (readl(i2c->base + IC_STATUS) & 0x4)
-			i2c->status = STATUS_WRITE_SUCCESS;
-	}
-
-exit:
-	if (i2c->status == STATUS_READ_SUCCESS ||
-	    i2c->status == STATUS_WRITE_SUCCESS ||
-	    i2c->status == STATUS_XFER_ABORT) {
-		/* Clear all interrupts */
-		readl(i2c->base + IC_CLR_INTR);
-		/* Mask interrupts */
-		writel(0, i2c->base + IC_INTR_MASK);
-		complete(&i2c->complete);
-	}
-err:
-	return IRQ_HANDLED;
-}
-
-static struct i2c_algorithm intel_mid_i2c_algorithm = {
-	.master_xfer	= intel_mid_i2c_xfer,
-	.functionality	= intel_mid_i2c_func,
-};
-
-
-static const struct dev_pm_ops intel_mid_i2c_pm_ops = {
-	.runtime_suspend = intel_mid_i2c_runtime_suspend,
-	.runtime_resume = intel_mid_i2c_runtime_resume,
-};
-
-/**
- * intel_mid_i2c_probe - I2C controller initialization routine
- * @dev: pci device
- * @id: device id
- *
- * Return Values:
- * 0		success
- * -ENODEV	If cannot allocate pci resource
- * -ENOMEM	If the register base remapping failed, or
- *		if kzalloc failed
- *
- * Initialization steps:
- * 1. Request for PCI resource
- * 2. Remap the start address of PCI resource to register base
- * 3. Request for device memory region
- * 4. Fill in the struct members of intel_mid_i2c_private
- * 5. Call intel_mid_i2c_hwinit() for hardware initialization
- * 6. Register I2C adapter in i2c-core
- */
-static int intel_mid_i2c_probe(struct pci_dev *dev,
-				    const struct pci_device_id *id)
-{
-	struct intel_mid_i2c_private *mrst;
-	unsigned long start, len;
-	int err, busnum;
-	void __iomem *base = NULL;
-
-	dev_dbg(&dev->dev, "Get into probe function for I2C\n");
-	err = pci_enable_device(dev);
-	if (err) {
-		dev_err(&dev->dev, "Failed to enable I2C PCI device (%d)\n",
-			err);
-		goto exit;
-	}
-
-	/* Determine the address of the I2C area */
-	start = pci_resource_start(dev, 0);
-	len = pci_resource_len(dev, 0);
-	if (!start || len == 0) {
-		dev_err(&dev->dev, "base address not set\n");
-		err = -ENODEV;
-		goto exit;
-	}
-	dev_dbg(&dev->dev, "%s i2c resource start 0x%lx, len=%ld\n",
-		PLATFORM, start, len);
-
-	err = pci_request_region(dev, 0, DRIVER_NAME);
-	if (err) {
-		dev_err(&dev->dev, "failed to request I2C region "
-			"0x%lx-0x%lx\n", start,
-			(unsigned long)pci_resource_end(dev, 0));
-		goto exit;
-	}
-
-	base = ioremap_nocache(start, len);
-	if (!base) {
-		dev_err(&dev->dev, "I/O memory remapping failed\n");
-		err = -ENOMEM;
-		goto fail0;
-	}
-
-	/* Allocate the per-device data structure, intel_mid_i2c_private */
-	mrst = kzalloc(sizeof(struct intel_mid_i2c_private), GFP_KERNEL);
-	if (mrst == NULL) {
-		dev_err(&dev->dev, "can't allocate interface\n");
-		err = -ENOMEM;
-		goto fail1;
-	}
-
-	/* Initialize struct members */
-	snprintf(mrst->adap.name, sizeof(mrst->adap.name),
-		"Intel MID I2C at %lx", start);
-	mrst->adap.owner = THIS_MODULE;
-	mrst->adap.algo = &intel_mid_i2c_algorithm;
-	mrst->adap.dev.parent = &dev->dev;
-	mrst->dev = &dev->dev;
-	mrst->base = base;
-	mrst->speed = STANDARD;
-	mrst->abort = 0;
-	mrst->rx_buf_len = 0;
-	mrst->status = STATUS_IDLE;
-
-	pci_set_drvdata(dev, mrst);
-	i2c_set_adapdata(&mrst->adap, mrst);
-
-	mrst->adap.nr = busnum = id->driver_data;
-	if (dev->device <= 0x0804)
-		mrst->platform = MOORESTOWN;
-	else
-		mrst->platform = MEDFIELD;
-
-	dev_dbg(&dev->dev, "I2C%d\n", busnum);
-
-	if (ctl_num > busnum) {
-		if (speed_mode[busnum] < 0 || speed_mode[busnum] >= NUM_SPEEDS)
-			dev_warn(&dev->dev, "invalid speed %d ignored.\n",
-							speed_mode[busnum]);
-		else
-			mrst->speed = speed_mode[busnum];
-	}
-
-	/* Initialize i2c controller */
-	err = intel_mid_i2c_hwinit(mrst);
-	if (err < 0) {
-		dev_err(&dev->dev, "I2C interface initialization failed\n");
-		goto fail2;
-	}
-
-	mutex_init(&mrst->lock);
-	init_completion(&mrst->complete);
-
-	/* Clear all interrupts */
-	readl(mrst->base + IC_CLR_INTR);
-	writel(0x0000, mrst->base + IC_INTR_MASK);
-
-	err = request_irq(dev->irq, intel_mid_i2c_isr, IRQF_SHARED,
-					mrst->adap.name, mrst);
-	if (err) {
-		dev_err(&dev->dev, "Failed to request IRQ for I2C controller: "
-			"%s", mrst->adap.name);
-		goto fail2;
-	}
-
-	/* Adapter registration */
-	err = i2c_add_numbered_adapter(&mrst->adap);
-	if (err) {
-		dev_err(&dev->dev, "Adapter %s registration failed\n",
-			mrst->adap.name);
-		goto fail3;
-	}
-
-	dev_dbg(&dev->dev, "%s I2C bus %d driver bind success.\n",
-		(mrst->platform == MOORESTOWN) ? "Moorestown" : "Medfield",
-		busnum);
-
-	pm_runtime_enable(&dev->dev);
-	return 0;
-
-fail3:
-	free_irq(dev->irq, mrst);
-fail2:
-	kfree(mrst);
-fail1:
-	iounmap(base);
-fail0:
-	pci_release_region(dev, 0);
-exit:
-	return err;
-}
-
-static void intel_mid_i2c_remove(struct pci_dev *dev)
-{
-	struct intel_mid_i2c_private *mrst = pci_get_drvdata(dev);
-	intel_mid_i2c_disable(&mrst->adap);
-	i2c_del_adapter(&mrst->adap);
-
-	free_irq(dev->irq, mrst);
-	iounmap(mrst->base);
-	kfree(mrst);
-	pci_release_region(dev, 0);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(intel_mid_i2c_ids) = {
-	/* Moorestown */
-	{ PCI_VDEVICE(INTEL, 0x0802), 0 },
-	{ PCI_VDEVICE(INTEL, 0x0803), 1 },
-	{ PCI_VDEVICE(INTEL, 0x0804), 2 },
-	/* Medfield */
-	{ PCI_VDEVICE(INTEL, 0x0817), 3,},
-	{ PCI_VDEVICE(INTEL, 0x0818), 4 },
-	{ PCI_VDEVICE(INTEL, 0x0819), 5 },
-	{ PCI_VDEVICE(INTEL, 0x082C), 0 },
-	{ PCI_VDEVICE(INTEL, 0x082D), 1 },
-	{ PCI_VDEVICE(INTEL, 0x082E), 2 },
-	{ 0,}
-};
-MODULE_DEVICE_TABLE(pci, intel_mid_i2c_ids);
-
-static struct pci_driver intel_mid_i2c_driver = {
-	.name		= DRIVER_NAME,
-	.id_table	= intel_mid_i2c_ids,
-	.probe		= intel_mid_i2c_probe,
-	.remove		= intel_mid_i2c_remove,
-};
-
-module_pci_driver(intel_mid_i2c_driver);
-
-MODULE_AUTHOR("Ba Zheng <zheng.ba@intel.com>");
-MODULE_DESCRIPTION("I2C driver for Moorestown Platform");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(VERSION);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-iop3xx.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-iop3xx.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-iop3xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-iop3xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -176,7 +176,7 @@ iop3xx_i2c_wait_event(struct i2c_algo_io
 		interrupted = wait_event_interruptible_timeout (
 			iop3xx_adap->waitq,
 			(done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
-			1 * HZ;
+			1 * HZ
 			);
 		if ((rc = iop3xx_i2c_error(sr)) < 0) {
 			*status = sr;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-kempld.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-kempld.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-kempld.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-kempld.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,410 @@
+/*
+ * I2C bus driver for Kontron COM modules
+ *
+ * Copyright (c) 2010-2013 Kontron Europe GmbH
+ * Author: Michael Brunner <michael.brunner@kontron.com>
+ *
+ * The driver is based on the i2c-ocores driver by Peter Korsgaard.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/mfd/kempld.h>
+
+#define KEMPLD_I2C_PRELOW	0x0b
+#define KEMPLD_I2C_PREHIGH	0x0c
+#define KEMPLD_I2C_DATA		0x0e
+
+#define KEMPLD_I2C_CTRL		0x0d
+#define I2C_CTRL_IEN		0x40
+#define I2C_CTRL_EN		0x80
+
+#define KEMPLD_I2C_STAT		0x0f
+#define I2C_STAT_IF		0x01
+#define I2C_STAT_TIP		0x02
+#define I2C_STAT_ARBLOST	0x20
+#define I2C_STAT_BUSY		0x40
+#define I2C_STAT_NACK		0x80
+
+#define KEMPLD_I2C_CMD		0x0f
+#define I2C_CMD_START		0x91
+#define I2C_CMD_STOP		0x41
+#define I2C_CMD_READ		0x21
+#define I2C_CMD_WRITE		0x11
+#define I2C_CMD_READ_ACK	0x21
+#define I2C_CMD_READ_NACK	0x29
+#define I2C_CMD_IACK		0x01
+
+#define KEMPLD_I2C_FREQ_MAX	2700	/* 2.7 mHz */
+#define KEMPLD_I2C_FREQ_STD	100	/* 100 kHz */
+
+enum {
+	STATE_DONE = 0,
+	STATE_INIT,
+	STATE_ADDR,
+	STATE_ADDR10,
+	STATE_START,
+	STATE_WRITE,
+	STATE_READ,
+	STATE_ERROR,
+};
+
+struct kempld_i2c_data {
+	struct device			*dev;
+	struct kempld_device_data	*pld;
+	struct i2c_adapter		adap;
+	struct i2c_msg			*msg;
+	int				pos;
+	int				nmsgs;
+	int				state;
+	bool				was_active;
+};
+
+static unsigned int bus_frequency = KEMPLD_I2C_FREQ_STD;
+module_param(bus_frequency, uint, 0);
+MODULE_PARM_DESC(bus_frequency, "Set I2C bus frequency in kHz (default="
+				__MODULE_STRING(KEMPLD_I2C_FREQ_STD)")");
+
+static int i2c_bus = -1;
+module_param(i2c_bus, int, 0);
+MODULE_PARM_DESC(i2c_bus, "Set I2C bus number (default=-1 for dynamic assignment)");
+
+static bool i2c_gpio_mux;
+module_param(i2c_gpio_mux, bool, 0);
+MODULE_PARM_DESC(i2c_gpio_mux, "Enable I2C port on GPIO out (default=false)");
+
+/*
+ * kempld_get_mutex must be called prior to calling this function.
+ */
+static int kempld_i2c_process(struct kempld_i2c_data *i2c)
+{
+	struct kempld_device_data *pld = i2c->pld;
+	u8 stat = kempld_read8(pld, KEMPLD_I2C_STAT);
+	struct i2c_msg *msg = i2c->msg;
+	u8 addr;
+
+	/* Ready? */
+	if (stat & I2C_STAT_TIP)
+		return -EBUSY;
+
+	if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) {
+		/* Stop has been sent */
+		kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_IACK);
+		if (i2c->state == STATE_ERROR)
+			return -EIO;
+		return 0;
+	}
+
+	/* Error? */
+	if (stat & I2C_STAT_ARBLOST) {
+		i2c->state = STATE_ERROR;
+		kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
+		return -EAGAIN;
+	}
+
+	if (i2c->state == STATE_INIT) {
+		if (stat & I2C_STAT_BUSY)
+			return -EBUSY;
+
+		i2c->state = STATE_ADDR;
+	}
+
+	if (i2c->state == STATE_ADDR) {
+		/* 10 bit address? */
+		if (i2c->msg->flags & I2C_M_TEN) {
+			addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6);
+			i2c->state = STATE_ADDR10;
+		} else {
+			addr = (i2c->msg->addr << 1);
+			i2c->state = STATE_START;
+		}
+
+		/* Set read bit if necessary */
+		addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0;
+
+		kempld_write8(pld, KEMPLD_I2C_DATA, addr);
+		kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_START);
+
+		return 0;
+	}
+
+	/* Second part of 10 bit addressing */
+	if (i2c->state == STATE_ADDR10) {
+		kempld_write8(pld, KEMPLD_I2C_DATA, i2c->msg->addr & 0xff);
+		kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_WRITE);
+
+		i2c->state = STATE_START;
+		return 0;
+	}
+
+	if (i2c->state == STATE_START || i2c->state == STATE_WRITE) {
+		i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
+
+		if (stat & I2C_STAT_NACK) {
+			i2c->state = STATE_ERROR;
+			kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
+			return -ENXIO;
+		}
+	} else {
+		msg->buf[i2c->pos++] = kempld_read8(pld, KEMPLD_I2C_DATA);
+	}
+
+	if (i2c->pos >= msg->len) {
+		i2c->nmsgs--;
+		i2c->msg++;
+		i2c->pos = 0;
+		msg = i2c->msg;
+
+		if (i2c->nmsgs) {
+			if (!(msg->flags & I2C_M_NOSTART)) {
+				i2c->state = STATE_ADDR;
+				return 0;
+			} else {
+				i2c->state = (msg->flags & I2C_M_RD)
+					? STATE_READ : STATE_WRITE;
+			}
+		} else {
+			i2c->state = STATE_DONE;
+			kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
+			return 0;
+		}
+	}
+
+	if (i2c->state == STATE_READ) {
+		kempld_write8(pld, KEMPLD_I2C_CMD, i2c->pos == (msg->len - 1) ?
+			      I2C_CMD_READ_NACK : I2C_CMD_READ_ACK);
+	} else {
+		kempld_write8(pld, KEMPLD_I2C_DATA, msg->buf[i2c->pos++]);
+		kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_WRITE);
+	}
+
+	return 0;
+}
+
+static int kempld_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+				int num)
+{
+	struct kempld_i2c_data *i2c = i2c_get_adapdata(adap);
+	struct kempld_device_data *pld = i2c->pld;
+	unsigned long timeout = jiffies + HZ;
+	int ret;
+
+	i2c->msg = msgs;
+	i2c->pos = 0;
+	i2c->nmsgs = num;
+	i2c->state = STATE_INIT;
+
+	/* Handle the transfer */
+	while (time_before(jiffies, timeout)) {
+		kempld_get_mutex(pld);
+		ret = kempld_i2c_process(i2c);
+		kempld_release_mutex(pld);
+
+		if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR)
+			return (i2c->state == STATE_DONE) ? num : ret;
+
+		if (ret == 0)
+			timeout = jiffies + HZ;
+
+		usleep_range(5, 15);
+	}
+
+	i2c->state = STATE_ERROR;
+
+	return -ETIMEDOUT;
+}
+
+/*
+ * kempld_get_mutex must be called prior to calling this function.
+ */
+static void kempld_i2c_device_init(struct kempld_i2c_data *i2c)
+{
+	struct kempld_device_data *pld = i2c->pld;
+	u16 prescale_corr;
+	long prescale;
+	u8 ctrl;
+	u8 stat;
+	u8 cfg;
+
+	/* Make sure the device is disabled */
+	ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
+	ctrl &= ~(I2C_CTRL_EN | I2C_CTRL_IEN);
+	kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
+
+	if (bus_frequency > KEMPLD_I2C_FREQ_MAX)
+		bus_frequency = KEMPLD_I2C_FREQ_MAX;
+
+	if (pld->info.spec_major == 1)
+		prescale = pld->pld_clock / (bus_frequency * 5) - 1000;
+	else
+		prescale = pld->pld_clock / (bus_frequency * 4) - 3000;
+
+	if (prescale < 0)
+		prescale = 0;
+
+	/* Round to the best matching value */
+	prescale_corr = prescale / 1000;
+	if (prescale % 1000 >= 500)
+		prescale_corr++;
+
+	kempld_write8(pld, KEMPLD_I2C_PRELOW, prescale_corr & 0xff);
+	kempld_write8(pld, KEMPLD_I2C_PREHIGH, prescale_corr >> 8);
+
+	/* Activate I2C bus output on GPIO pins */
+	cfg = kempld_read8(pld, KEMPLD_CFG);
+	if (i2c_gpio_mux)
+		cfg |= KEMPLD_CFG_GPIO_I2C_MUX;
+	else
+		cfg &= ~KEMPLD_CFG_GPIO_I2C_MUX;
+	kempld_write8(pld, KEMPLD_CFG, cfg);
+
+	/* Enable the device */
+	kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_IACK);
+	ctrl |= I2C_CTRL_EN;
+	kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
+
+	stat = kempld_read8(pld, KEMPLD_I2C_STAT);
+	if (stat & I2C_STAT_BUSY)
+		kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
+}
+
+static u32 kempld_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm kempld_i2c_algorithm = {
+	.master_xfer	= kempld_i2c_xfer,
+	.functionality	= kempld_i2c_func,
+};
+
+static struct i2c_adapter kempld_i2c_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "i2c-kempld",
+	.class		= I2C_CLASS_HWMON | I2C_CLASS_SPD,
+	.algo		= &kempld_i2c_algorithm,
+};
+
+static int kempld_i2c_probe(struct platform_device *pdev)
+{
+	struct kempld_device_data *pld = dev_get_drvdata(pdev->dev.parent);
+	struct kempld_i2c_data *i2c;
+	int ret;
+	u8 ctrl;
+
+	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
+
+	i2c->pld = pld;
+	i2c->dev = &pdev->dev;
+	i2c->adap = kempld_i2c_adapter;
+	i2c->adap.dev.parent = i2c->dev;
+	i2c_set_adapdata(&i2c->adap, i2c);
+	platform_set_drvdata(pdev, i2c);
+
+	kempld_get_mutex(pld);
+	ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
+
+	if (ctrl & I2C_CTRL_EN)
+		i2c->was_active = true;
+
+	kempld_i2c_device_init(i2c);
+	kempld_release_mutex(pld);
+
+	/* Add I2C adapter to I2C tree */
+	if (i2c_bus >= -1)
+		i2c->adap.nr = i2c_bus;
+	ret = i2c_add_numbered_adapter(&i2c->adap);
+	if (ret)
+		return ret;
+
+	dev_info(i2c->dev, "I2C bus initialized at %dkHz\n",
+		 bus_frequency);
+
+	return 0;
+}
+
+static int kempld_i2c_remove(struct platform_device *pdev)
+{
+	struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
+	struct kempld_device_data *pld = i2c->pld;
+	u8 ctrl;
+
+	kempld_get_mutex(pld);
+	/*
+	 * Disable I2C logic if it was not activated before the
+	 * driver loaded
+	 */
+	if (!i2c->was_active) {
+		ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
+		ctrl &= ~I2C_CTRL_EN;
+		kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
+	}
+	kempld_release_mutex(pld);
+
+	i2c_del_adapter(&i2c->adap);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int kempld_i2c_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
+	struct kempld_device_data *pld = i2c->pld;
+	u8 ctrl;
+
+	kempld_get_mutex(pld);
+	ctrl = kempld_read8(pld, KEMPLD_I2C_CTRL);
+	ctrl &= ~I2C_CTRL_EN;
+	kempld_write8(pld, KEMPLD_I2C_CTRL, ctrl);
+	kempld_release_mutex(pld);
+
+	return 0;
+}
+
+static int kempld_i2c_resume(struct platform_device *pdev)
+{
+	struct kempld_i2c_data *i2c = platform_get_drvdata(pdev);
+	struct kempld_device_data *pld = i2c->pld;
+
+	kempld_get_mutex(pld);
+	kempld_i2c_device_init(i2c);
+	kempld_release_mutex(pld);
+
+	return 0;
+}
+#else
+#define kempld_i2c_suspend	NULL
+#define kempld_i2c_resume	NULL
+#endif
+
+static struct platform_driver kempld_i2c_driver = {
+	.driver = {
+		.name = "kempld-i2c",
+		.owner = THIS_MODULE,
+	},
+	.probe		= kempld_i2c_probe,
+	.remove		= kempld_i2c_remove,
+	.suspend	= kempld_i2c_suspend,
+	.resume		= kempld_i2c_resume,
+};
+
+module_platform_driver(kempld_i2c_driver);
+
+MODULE_DESCRIPTION("KEM PLD I2C Driver");
+MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:kempld_i2c");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-mpc.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-mpc.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-mpc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-mpc.c	2013-08-25 20:43:22.000000000 -0400
@@ -679,7 +679,7 @@ static int fsl_i2c_probe(struct platform
 	}
 	dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ);
 
-	dev_set_drvdata(&op->dev, i2c);
+	platform_set_drvdata(op, i2c);
 
 	i2c->adap = mpc_ops;
 	i2c_set_adapdata(&i2c->adap, i2c);
@@ -707,7 +707,7 @@ static int fsl_i2c_probe(struct platform
 
 static int fsl_i2c_remove(struct platform_device *op)
 {
-	struct mpc_i2c *i2c = dev_get_drvdata(&op->dev);
+	struct mpc_i2c *i2c = platform_get_drvdata(op);
 
 	i2c_del_adapter(&i2c->adap);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-mv64xxx.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-mv64xxx.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-mv64xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-mv64xxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,19 +19,15 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/of_i2c.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 
-/* Register defines */
-#define	MV64XXX_I2C_REG_SLAVE_ADDR			0x00
-#define	MV64XXX_I2C_REG_DATA				0x04
-#define	MV64XXX_I2C_REG_CONTROL				0x08
-#define	MV64XXX_I2C_REG_STATUS				0x0c
-#define	MV64XXX_I2C_REG_BAUD				0x0c
-#define	MV64XXX_I2C_REG_EXT_SLAVE_ADDR			0x10
-#define	MV64XXX_I2C_REG_SOFT_RESET			0x1c
+#define MV64XXX_I2C_ADDR_ADDR(val)			((val & 0x7f) << 1)
+#define MV64XXX_I2C_BAUD_DIV_N(val)			(val & 0x7)
+#define MV64XXX_I2C_BAUD_DIV_M(val)			((val & 0xf) << 3)
 
 #define	MV64XXX_I2C_REG_CONTROL_ACK			0x00000004
 #define	MV64XXX_I2C_REG_CONTROL_IFLG			0x00000008
@@ -85,15 +81,26 @@ enum {
 	MV64XXX_I2C_ACTION_SEND_STOP,
 };
 
+struct mv64xxx_i2c_regs {
+	u8	addr;
+	u8	ext_addr;
+	u8	data;
+	u8	control;
+	u8	status;
+	u8	clock;
+	u8	soft_reset;
+};
+
 struct mv64xxx_i2c_data {
+	struct i2c_msg		*msgs;
+	int			num_msgs;
 	int			irq;
 	u32			state;
 	u32			action;
 	u32			aborting;
 	u32			cntl_bits;
 	void __iomem		*reg_base;
-	u32			reg_base_p;
-	u32			reg_size;
+	struct mv64xxx_i2c_regs	reg_offsets;
 	u32			addr1;
 	u32			addr2;
 	u32			bytes_left;
@@ -112,6 +119,52 @@ struct mv64xxx_i2c_data {
 	struct i2c_adapter	adapter;
 };
 
+static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
+	.addr		= 0x00,
+	.ext_addr	= 0x10,
+	.data		= 0x04,
+	.control	= 0x08,
+	.status		= 0x0c,
+	.clock		= 0x0c,
+	.soft_reset	= 0x1c,
+};
+
+static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_sun4i = {
+	.addr		= 0x00,
+	.ext_addr	= 0x04,
+	.data		= 0x08,
+	.control	= 0x0c,
+	.status		= 0x10,
+	.clock		= 0x14,
+	.soft_reset	= 0x18,
+};
+
+static void
+mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
+	struct i2c_msg *msg)
+{
+	u32	dir = 0;
+
+	drv_data->msg = msg;
+	drv_data->byte_posn = 0;
+	drv_data->bytes_left = msg->len;
+	drv_data->aborting = 0;
+	drv_data->rc = 0;
+	drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
+		MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
+
+	if (msg->flags & I2C_M_RD)
+		dir = 1;
+
+	if (msg->flags & I2C_M_TEN) {
+		drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
+		drv_data->addr2 = (u32)msg->addr & 0xff;
+	} else {
+		drv_data->addr1 = MV64XXX_I2C_ADDR_ADDR((u32)msg->addr) | dir;
+		drv_data->addr2 = 0;
+	}
+}
+
 /*
  *****************************************************************************
  *
@@ -124,13 +177,13 @@ struct mv64xxx_i2c_data {
 static void
 mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
 {
-	writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET);
-	writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)),
-		drv_data->reg_base + MV64XXX_I2C_REG_BAUD);
-	writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR);
-	writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR);
+	writel(0, drv_data->reg_base + drv_data->reg_offsets.soft_reset);
+	writel(MV64XXX_I2C_BAUD_DIV_M(drv_data->freq_m) | MV64XXX_I2C_BAUD_DIV_N(drv_data->freq_n),
+		drv_data->reg_base + drv_data->reg_offsets.clock);
+	writel(0, drv_data->reg_base + drv_data->reg_offsets.addr);
+	writel(0, drv_data->reg_base + drv_data->reg_offsets.ext_addr);
 	writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP,
-		drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+		drv_data->reg_base + drv_data->reg_offsets.control);
 	drv_data->state = MV64XXX_I2C_STATE_IDLE;
 }
 
@@ -170,7 +223,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data
 		if ((drv_data->bytes_left == 0)
 				|| (drv_data->aborting
 					&& (drv_data->byte_posn != 0))) {
-			if (drv_data->send_stop) {
+			if (drv_data->send_stop || drv_data->aborting) {
 				drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
 				drv_data->state = MV64XXX_I2C_STATE_IDLE;
 			} else {
@@ -227,7 +280,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data
 		/* Doesn't seem to be a device at other end */
 		drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
 		drv_data->state = MV64XXX_I2C_STATE_IDLE;
-		drv_data->rc = -ENODEV;
+		drv_data->rc = -ENXIO;
 		break;
 
 	default:
@@ -247,58 +300,71 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c
 {
 	switch(drv_data->action) {
 	case MV64XXX_I2C_ACTION_SEND_RESTART:
+		/* We should only get here if we have further messages */
+		BUG_ON(drv_data->num_msgs == 0);
+
 		drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
-		drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
 		writel(drv_data->cntl_bits,
-			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
-		drv_data->block = 0;
-		wake_up(&drv_data->waitq);
+			drv_data->reg_base + drv_data->reg_offsets.control);
+
+		drv_data->msgs++;
+		drv_data->num_msgs--;
+
+		/* Setup for the next message */
+		mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
+
+		/*
+		 * We're never at the start of the message here, and by this
+		 * time it's already too late to do any protocol mangling.
+		 * Thankfully, do not advertise support for that feature.
+		 */
+		drv_data->send_stop = drv_data->num_msgs == 1;
 		break;
 
 	case MV64XXX_I2C_ACTION_CONTINUE:
 		writel(drv_data->cntl_bits,
-			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+			drv_data->reg_base + drv_data->reg_offsets.control);
 		break;
 
 	case MV64XXX_I2C_ACTION_SEND_START:
 		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
-			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+			drv_data->reg_base + drv_data->reg_offsets.control);
 		break;
 
 	case MV64XXX_I2C_ACTION_SEND_ADDR_1:
 		writel(drv_data->addr1,
-			drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+			drv_data->reg_base + drv_data->reg_offsets.data);
 		writel(drv_data->cntl_bits,
-			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+			drv_data->reg_base + drv_data->reg_offsets.control);
 		break;
 
 	case MV64XXX_I2C_ACTION_SEND_ADDR_2:
 		writel(drv_data->addr2,
-			drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+			drv_data->reg_base + drv_data->reg_offsets.data);
 		writel(drv_data->cntl_bits,
-			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+			drv_data->reg_base + drv_data->reg_offsets.control);
 		break;
 
 	case MV64XXX_I2C_ACTION_SEND_DATA:
 		writel(drv_data->msg->buf[drv_data->byte_posn++],
-			drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+			drv_data->reg_base + drv_data->reg_offsets.data);
 		writel(drv_data->cntl_bits,
-			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+			drv_data->reg_base + drv_data->reg_offsets.control);
 		break;
 
 	case MV64XXX_I2C_ACTION_RCV_DATA:
 		drv_data->msg->buf[drv_data->byte_posn++] =
-			readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+			readl(drv_data->reg_base + drv_data->reg_offsets.data);
 		writel(drv_data->cntl_bits,
-			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+			drv_data->reg_base + drv_data->reg_offsets.control);
 		break;
 
 	case MV64XXX_I2C_ACTION_RCV_DATA_STOP:
 		drv_data->msg->buf[drv_data->byte_posn++] =
-			readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+			readl(drv_data->reg_base + drv_data->reg_offsets.data);
 		drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
 		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
-			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+			drv_data->reg_base + drv_data->reg_offsets.control);
 		drv_data->block = 0;
 		wake_up(&drv_data->waitq);
 		break;
@@ -313,7 +379,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c
 	case MV64XXX_I2C_ACTION_SEND_STOP:
 		drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
 		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
-			drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+			drv_data->reg_base + drv_data->reg_offsets.control);
 		drv_data->block = 0;
 		wake_up(&drv_data->waitq);
 		break;
@@ -329,9 +395,9 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
 	irqreturn_t	rc = IRQ_NONE;
 
 	spin_lock_irqsave(&drv_data->lock, flags);
-	while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) &
+	while (readl(drv_data->reg_base + drv_data->reg_offsets.control) &
 						MV64XXX_I2C_REG_CONTROL_IFLG) {
-		status = readl(drv_data->reg_base + MV64XXX_I2C_REG_STATUS);
+		status = readl(drv_data->reg_base + drv_data->reg_offsets.status);
 		mv64xxx_i2c_fsm(drv_data, status);
 		mv64xxx_i2c_do_action(drv_data);
 		rc = IRQ_HANDLED;
@@ -349,32 +415,6 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
  *****************************************************************************
  */
 static void
-mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
-	struct i2c_msg *msg)
-{
-	u32	dir = 0;
-
-	drv_data->msg = msg;
-	drv_data->byte_posn = 0;
-	drv_data->bytes_left = msg->len;
-	drv_data->aborting = 0;
-	drv_data->rc = 0;
-	drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
-		MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
-
-	if (msg->flags & I2C_M_RD)
-		dir = 1;
-
-	if (msg->flags & I2C_M_TEN) {
-		drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
-		drv_data->addr2 = (u32)msg->addr & 0xff;
-	} else {
-		drv_data->addr1 = ((u32)msg->addr & 0x7f) << 1 | dir;
-		drv_data->addr2 = 0;
-	}
-}
-
-static void
 mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
 {
 	long		time_left;
@@ -414,36 +454,15 @@ mv64xxx_i2c_wait_for_completion(struct m
 
 static int
 mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
-				int is_first, int is_last)
+				int is_last)
 {
 	unsigned long	flags;
 
 	spin_lock_irqsave(&drv_data->lock, flags);
 	mv64xxx_i2c_prepare_for_io(drv_data, msg);
 
-	if (unlikely(msg->flags & I2C_M_NOSTART)) { /* Skip start/addr phases */
-		if (drv_data->msg->flags & I2C_M_RD) {
-			/* No action to do, wait for slave to send a byte */
-			drv_data->action = MV64XXX_I2C_ACTION_CONTINUE;
-			drv_data->state =
-				MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;
-		} else {
-			drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
-			drv_data->state =
-				MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
-			drv_data->bytes_left--;
-		}
-	} else {
-		if (is_first) {
-			drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
-			drv_data->state =
-				MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
-		} else {
-			drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_1;
-			drv_data->state =
-				MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
-		}
-	}
+	drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
+	drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
 
 	drv_data->send_stop = is_last;
 	drv_data->block = 1;
@@ -471,16 +490,20 @@ static int
 mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 {
 	struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
-	int	i, rc;
+	int rc, ret = num;
 
-	for (i = 0; i < num; i++) {
-		rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[i],
-						i == 0, i + 1 == num);
-		if (rc < 0)
-			return rc;
-	}
+	BUG_ON(drv_data->msgs != NULL);
+	drv_data->msgs = msgs;
+	drv_data->num_msgs = num;
 
-	return num;
+	rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1);
+	if (rc < 0)
+		ret = rc;
+
+	drv_data->num_msgs = 0;
+	drv_data->msgs = NULL;
+
+	return ret;
 }
 
 static const struct i2c_algorithm mv64xxx_i2c_algo = {
@@ -495,39 +518,12 @@ static const struct i2c_algorithm mv64xx
  *
  *****************************************************************************
  */
-static int
-mv64xxx_i2c_map_regs(struct platform_device *pd,
-	struct mv64xxx_i2c_data *drv_data)
-{
-	int size;
-	struct resource	*r = platform_get_resource(pd, IORESOURCE_MEM, 0);
-
-	if (!r)
-		return -ENODEV;
-
-	size = resource_size(r);
-
-	if (!request_mem_region(r->start, size, drv_data->adapter.name))
-		return -EBUSY;
-
-	drv_data->reg_base = ioremap(r->start, size);
-	drv_data->reg_base_p = r->start;
-	drv_data->reg_size = size;
-
-	return 0;
-}
-
-static void
-mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data)
-{
-	if (drv_data->reg_base) {
-		iounmap(drv_data->reg_base);
-		release_mem_region(drv_data->reg_base_p, drv_data->reg_size);
-	}
-
-	drv_data->reg_base = NULL;
-	drv_data->reg_base_p = 0;
-}
+static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
+	{ .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i},
+	{ .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
+	{}
+};
+MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
 
 #ifdef CONFIG_OF
 static int
@@ -562,8 +558,10 @@ mv64xxx_find_baud_factors(const u32 req_
 
 static int
 mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
-		  struct device_node *np)
+		  struct device *dev)
 {
+	const struct of_device_id *device;
+	struct device_node *np = dev->of_node;
 	u32 bus_freq, tclk;
 	int rc = 0;
 
@@ -580,7 +578,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_dat
 		goto out;
 	}
 	tclk = clk_get_rate(drv_data->clk);
-	of_property_read_u32(np, "clock-frequency", &bus_freq);
+
+	rc = of_property_read_u32(np, "clock-frequency", &bus_freq);
+	if (rc)
+		bus_freq = 100000; /* 100kHz by default */
+
 	if (!mv64xxx_find_baud_factors(bus_freq, tclk,
 				       &drv_data->freq_n, &drv_data->freq_m)) {
 		rc = -EINVAL;
@@ -592,6 +594,13 @@ mv64xxx_of_config(struct mv64xxx_i2c_dat
 	 * So hard code the value to 1 second.
 	 */
 	drv_data->adapter.timeout = HZ;
+
+	device = of_match_device(mv64xxx_i2c_of_match_table, dev);
+	if (!device)
+		return -ENODEV;
+
+	memcpy(&drv_data->reg_offsets, device->data, sizeof(drv_data->reg_offsets));
+
 out:
 	return rc;
 #endif
@@ -599,7 +608,7 @@ out:
 #else /* CONFIG_OF */
 static int
 mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
-		  struct device_node *np)
+		  struct device *dev)
 {
 	return -ENODEV;
 }
@@ -610,19 +619,21 @@ mv64xxx_i2c_probe(struct platform_device
 {
 	struct mv64xxx_i2c_data		*drv_data;
 	struct mv64xxx_i2c_pdata	*pdata = pd->dev.platform_data;
+	struct resource	*r;
 	int	rc;
 
 	if ((!pdata && !pd->dev.of_node))
 		return -ENODEV;
 
-	drv_data = kzalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL);
+	drv_data = devm_kzalloc(&pd->dev, sizeof(struct mv64xxx_i2c_data),
+				GFP_KERNEL);
 	if (!drv_data)
 		return -ENOMEM;
 
-	if (mv64xxx_i2c_map_regs(pd, drv_data)) {
-		rc = -ENODEV;
-		goto exit_kfree;
-	}
+	r = platform_get_resource(pd, IORESOURCE_MEM, 0);
+	drv_data->reg_base = devm_ioremap_resource(&pd->dev, r);
+	if (IS_ERR(drv_data->reg_base))
+		return PTR_ERR(drv_data->reg_base);
 
 	strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
 		sizeof(drv_data->adapter.name));
@@ -632,7 +643,7 @@ mv64xxx_i2c_probe(struct platform_device
 
 #if defined(CONFIG_HAVE_CLK)
 	/* Not all platforms have a clk */
-	drv_data->clk = clk_get(&pd->dev, NULL);
+	drv_data->clk = devm_clk_get(&pd->dev, NULL);
 	if (!IS_ERR(drv_data->clk)) {
 		clk_prepare(drv_data->clk);
 		clk_enable(drv_data->clk);
@@ -643,14 +654,15 @@ mv64xxx_i2c_probe(struct platform_device
 		drv_data->freq_n = pdata->freq_n;
 		drv_data->irq = platform_get_irq(pd, 0);
 		drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
+		memcpy(&drv_data->reg_offsets, &mv64xxx_i2c_regs_mv64xxx, sizeof(drv_data->reg_offsets));
 	} else if (pd->dev.of_node) {
-		rc = mv64xxx_of_config(drv_data, pd->dev.of_node);
+		rc = mv64xxx_of_config(drv_data, &pd->dev);
 		if (rc)
-			goto exit_unmap_regs;
+			goto exit_clk;
 	}
 	if (drv_data->irq < 0) {
 		rc = -ENXIO;
-		goto exit_unmap_regs;
+		goto exit_clk;
 	}
 
 	drv_data->adapter.dev.parent = &pd->dev;
@@ -664,13 +676,13 @@ mv64xxx_i2c_probe(struct platform_device
 
 	mv64xxx_i2c_hw_init(drv_data);
 
-	if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
-			MV64XXX_I2C_CTLR_NAME, drv_data)) {
+	rc = request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
+			 MV64XXX_I2C_CTLR_NAME, drv_data);
+	if (rc) {
 		dev_err(&drv_data->adapter.dev,
-			"mv64xxx: Can't register intr handler irq: %d\n",
-			drv_data->irq);
-		rc = -EINVAL;
-		goto exit_unmap_regs;
+			"mv64xxx: Can't register intr handler irq%d: %d\n",
+			drv_data->irq, rc);
+		goto exit_clk;
 	} else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
 		dev_err(&drv_data->adapter.dev,
 			"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
@@ -681,9 +693,9 @@ mv64xxx_i2c_probe(struct platform_device
 
 	return 0;
 
-	exit_free_irq:
-		free_irq(drv_data->irq, drv_data);
-	exit_unmap_regs:
+exit_free_irq:
+	free_irq(drv_data->irq, drv_data);
+exit_clk:
 #if defined(CONFIG_HAVE_CLK)
 	/* Not all platforms have a clk */
 	if (!IS_ERR(drv_data->clk)) {
@@ -691,9 +703,6 @@ mv64xxx_i2c_probe(struct platform_device
 		clk_unprepare(drv_data->clk);
 	}
 #endif
-		mv64xxx_i2c_unmap_regs(drv_data);
-	exit_kfree:
-		kfree(drv_data);
 	return rc;
 }
 
@@ -704,7 +713,6 @@ mv64xxx_i2c_remove(struct platform_devic
 
 	i2c_del_adapter(&drv_data->adapter);
 	free_irq(drv_data->irq, drv_data);
-	mv64xxx_i2c_unmap_regs(drv_data);
 #if defined(CONFIG_HAVE_CLK)
 	/* Not all platforms have a clk */
 	if (!IS_ERR(drv_data->clk)) {
@@ -712,17 +720,10 @@ mv64xxx_i2c_remove(struct platform_devic
 		clk_unprepare(drv_data->clk);
 	}
 #endif
-	kfree(drv_data);
 
 	return 0;
 }
 
-static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
-	{ .compatible = "marvell,mv64xxx-i2c", },
-	{}
-};
-MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
-
 static struct platform_driver mv64xxx_i2c_driver = {
 	.probe	= mv64xxx_i2c_probe,
 	.remove	= mv64xxx_i2c_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-mxs.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-mxs.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-mxs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-mxs.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/platform_device.h>
 #include <linux/jiffies.h>
 #include <linux/io.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/stmp_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -494,7 +493,7 @@ static int mxs_i2c_xfer_msg(struct i2c_a
 	 * based on this empirical measurement and a lot of previous frobbing.
 	 */
 	i2c->cmd_err = 0;
-	if (msg->len < 8) {
+	if (0) {	/* disable PIO mode until a proper fix is made */
 		ret = mxs_i2c_pio_setup_xfer(adap, msg, flags);
 		if (ret)
 			mxs_i2c_reset(i2c);
@@ -638,15 +637,10 @@ static int mxs_i2c_probe(struct platform
 	struct device *dev = &pdev->dev;
 	struct mxs_i2c_dev *i2c;
 	struct i2c_adapter *adap;
-	struct pinctrl *pinctrl;
 	struct resource *res;
 	resource_size_t res_size;
 	int err, irq;
 
-	pinctrl = devm_pinctrl_get_select_default(dev);
-	if (IS_ERR(pinctrl))
-		return PTR_ERR(pinctrl);
-
 	i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL);
 	if (!i2c)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-nomadik.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-nomadik.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-nomadik.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-nomadik.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/amba/bus.h>
-#include <linux/atomic.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
@@ -106,6 +105,16 @@
 /* maximum threshold value */
 #define MAX_I2C_FIFO_THRESHOLD	15
 
+/**
+ * struct i2c_vendor_data - per-vendor variations
+ * @has_mtdws: variant has the MTDWS bit
+ * @fifodepth: variant FIFO depth
+ */
+struct i2c_vendor_data {
+	bool has_mtdws;
+	u32 fifodepth;
+};
+
 enum i2c_status {
 	I2C_NOP,
 	I2C_ON_GOING,
@@ -138,6 +147,7 @@ struct i2c_nmk_client {
 
 /**
  * struct nmk_i2c_dev - private data structure of the controller.
+ * @vendor: vendor data for this variant.
  * @adev: parent amba device.
  * @adap: corresponding I2C adapter.
  * @irq: interrupt line for the controller.
@@ -148,13 +158,10 @@ struct i2c_nmk_client {
  * @stop: stop condition.
  * @xfer_complete: acknowledge completion for a I2C message.
  * @result: controller propogated result.
- * @pinctrl: pinctrl handle.
- * @pins_default: default state for the pins.
- * @pins_idle: idle state for the pins.
- * @pins_sleep: sleep state for the pins.
  * @busy: Busy doing transfer.
  */
 struct nmk_i2c_dev {
+	struct i2c_vendor_data		*vendor;
 	struct amba_device		*adev;
 	struct i2c_adapter		adap;
 	int				irq;
@@ -165,11 +172,6 @@ struct nmk_i2c_dev {
 	int				stop;
 	struct completion		xfer_complete;
 	int				result;
-	/* Three pin states - default, idle & sleep */
-	struct pinctrl			*pinctrl;
-	struct pinctrl_state		*pins_default;
-	struct pinctrl_state		*pins_idle;
-	struct pinctrl_state		*pins_sleep;
 	bool				busy;
 };
 
@@ -431,7 +433,7 @@ static int read_i2c(struct nmk_i2c_dev *
 	irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF |
 			I2C_IT_MAL | I2C_IT_BERR);
 
-	if (dev->stop)
+	if (dev->stop || !dev->vendor->has_mtdws)
 		irq_mask |= I2C_IT_MTD;
 	else
 		irq_mask |= I2C_IT_MTDWS;
@@ -511,7 +513,7 @@ static int write_i2c(struct nmk_i2c_dev
 	 * set the MTDWS bit (Master Transaction Done Without Stop)
 	 * to start repeated start operation
 	 */
-	if (dev->stop)
+	if (dev->stop || !dev->vendor->has_mtdws)
 		irq_mask |= I2C_IT_MTD;
 	else
 		irq_mask |= I2C_IT_MTDWS;
@@ -645,13 +647,7 @@ static int nmk_i2c_xfer(struct i2c_adapt
 	}
 
 	/* Optionaly enable pins to be muxed in and configured */
-	if (!IS_ERR(dev->pins_default)) {
-		status = pinctrl_select_state(dev->pinctrl,
-				dev->pins_default);
-		if (status)
-			dev_err(&dev->adev->dev,
-				"could not set default pins\n");
-	}
+	pinctrl_pm_select_default_state(&dev->adev->dev);
 
 	status = init_hw(dev);
 	if (status)
@@ -681,13 +677,7 @@ out:
 	clk_disable_unprepare(dev->clk);
 out_clk:
 	/* Optionally let pins go into idle state */
-	if (!IS_ERR(dev->pins_idle)) {
-		status = pinctrl_select_state(dev->pinctrl,
-				dev->pins_idle);
-		if (status)
-			dev_err(&dev->adev->dev,
-				"could not set pins to idle state\n");
-	}
+	pinctrl_pm_select_idle_state(&dev->adev->dev);
 
 	pm_runtime_put_sync(&dev->adev->dev);
 
@@ -882,41 +872,22 @@ static int nmk_i2c_suspend(struct device
 {
 	struct amba_device *adev = to_amba_device(dev);
 	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
-	int ret;
 
 	if (nmk_i2c->busy)
 		return -EBUSY;
 
-	if (!IS_ERR(nmk_i2c->pins_sleep)) {
-		ret = pinctrl_select_state(nmk_i2c->pinctrl,
-				nmk_i2c->pins_sleep);
-		if (ret)
-			dev_err(dev, "could not set pins to sleep state\n");
-	}
+	pinctrl_pm_select_sleep_state(dev);
 
 	return 0;
 }
 
 static int nmk_i2c_resume(struct device *dev)
 {
-	struct amba_device *adev = to_amba_device(dev);
-	struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev);
-	int ret;
-
 	/* First go to the default state */
-	if (!IS_ERR(nmk_i2c->pins_default)) {
-		ret = pinctrl_select_state(nmk_i2c->pinctrl,
-				nmk_i2c->pins_default);
-		if (ret)
-			dev_err(dev, "could not set pins to default state\n");
-	}
+	pinctrl_pm_select_default_state(dev);
 	/* Then let's idle the pins until the next transfer happens */
-	if (!IS_ERR(nmk_i2c->pins_idle)) {
-		ret = pinctrl_select_state(nmk_i2c->pinctrl,
-				nmk_i2c->pins_idle);
-		if (ret)
-			dev_err(dev, "could not set pins to idle state\n");
-	}
+	pinctrl_pm_select_idle_state(dev);
+
 	return 0;
 }
 #else
@@ -969,8 +940,6 @@ static void nmk_i2c_of_probe(struct devi
 		pdata->sm = I2C_FREQ_MODE_FAST;
 }
 
-static atomic_t adapter_id = ATOMIC_INIT(0);
-
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
@@ -978,6 +947,8 @@ static int nmk_i2c_probe(struct amba_dev
 	struct device_node *np = adev->dev.of_node;
 	struct nmk_i2c_dev	*dev;
 	struct i2c_adapter *adap;
+	struct i2c_vendor_data *vendor = id->data;
+	u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;
 
 	if (!pdata) {
 		if (np) {
@@ -994,49 +965,33 @@ static int nmk_i2c_probe(struct amba_dev
 			pdata = &u8500_i2c;
 	}
 
+	if (pdata->tft > max_fifo_threshold) {
+		dev_warn(&adev->dev, "requested TX FIFO threshold %u, adjusted down to %u\n",
+			pdata->tft, max_fifo_threshold);
+		pdata->tft = max_fifo_threshold;
+	}
+
+	if (pdata->rft > max_fifo_threshold) {
+		dev_warn(&adev->dev, "requested RX FIFO threshold %u, adjusted down to %u\n",
+			pdata->rft, max_fifo_threshold);
+		pdata->rft = max_fifo_threshold;
+	}
+
 	dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
 	if (!dev) {
 		dev_err(&adev->dev, "cannot allocate memory\n");
 		ret = -ENOMEM;
 		goto err_no_mem;
 	}
+	dev->vendor = vendor;
 	dev->busy = false;
 	dev->adev = adev;
 	amba_set_drvdata(adev, dev);
 
-	dev->pinctrl = devm_pinctrl_get(&adev->dev);
-	if (IS_ERR(dev->pinctrl)) {
-		ret = PTR_ERR(dev->pinctrl);
-		goto err_pinctrl;
-	}
-
-	dev->pins_default = pinctrl_lookup_state(dev->pinctrl,
-						 PINCTRL_STATE_DEFAULT);
-	if (IS_ERR(dev->pins_default)) {
-		dev_err(&adev->dev, "could not get default pinstate\n");
-	} else {
-		ret = pinctrl_select_state(dev->pinctrl,
-					   dev->pins_default);
-		if (ret)
-			dev_dbg(&adev->dev, "could not set default pinstate\n");
-	}
-
-	dev->pins_idle = pinctrl_lookup_state(dev->pinctrl,
-					      PINCTRL_STATE_IDLE);
-	if (IS_ERR(dev->pins_idle)) {
-		dev_dbg(&adev->dev, "could not get idle pinstate\n");
-	} else {
-		/* If possible, let's go to idle until the first transfer */
-		ret = pinctrl_select_state(dev->pinctrl,
-					   dev->pins_idle);
-		if (ret)
-			dev_dbg(&adev->dev, "could not set idle pinstate\n");
-	}
-
-	dev->pins_sleep = pinctrl_lookup_state(dev->pinctrl,
-					       PINCTRL_STATE_SLEEP);
-	if (IS_ERR(dev->pins_sleep))
-		dev_dbg(&adev->dev, "could not get sleep pinstate\n");
+	/* Select default pin state */
+	pinctrl_pm_select_default_state(&adev->dev);
+	/* If possible, let's go to idle until the first transfer */
+	pinctrl_pm_select_idle_state(&adev->dev);
 
 	dev->virtbase = ioremap(adev->res.start, resource_size(&adev->res));
 	if (!dev->virtbase) {
@@ -1068,10 +1023,8 @@ static int nmk_i2c_probe(struct amba_dev
 	adap->class	= I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->algo	= &nmk_i2c_algo;
 	adap->timeout	= msecs_to_jiffies(pdata->timeout);
-	adap->nr = atomic_read(&adapter_id);
 	snprintf(adap->name, sizeof(adap->name),
-		 "Nomadik I2C%d at %pR", adap->nr, &adev->res);
-	atomic_inc(&adapter_id);
+		 "Nomadik I2C at %pR", &adev->res);
 
 	/* fetch the controller configuration from machine */
 	dev->cfg.clk_freq = pdata->clk_freq;
@@ -1086,7 +1039,7 @@ static int nmk_i2c_probe(struct amba_dev
 		 "initialize %s on virtual base %p\n",
 		 adap->name, dev->virtbase);
 
-	ret = i2c_add_numbered_adapter(adap);
+	ret = i2c_add_adapter(adap);
 	if (ret) {
 		dev_err(&adev->dev, "failed to add adapter\n");
 		goto err_add_adap;
@@ -1106,7 +1059,6 @@ static int nmk_i2c_probe(struct amba_dev
 	iounmap(dev->virtbase);
  err_no_ioremap:
 	kfree(dev);
- err_pinctrl:
  err_no_mem:
 
 	return ret;
@@ -1134,14 +1086,26 @@ static int nmk_i2c_remove(struct amba_de
 	return 0;
 }
 
+static struct i2c_vendor_data vendor_stn8815 = {
+	.has_mtdws = false,
+	.fifodepth = 16, /* Guessed from TFTR/RFTR = 7 */
+};
+
+static struct i2c_vendor_data vendor_db8500 = {
+	.has_mtdws = true,
+	.fifodepth = 32, /* Guessed from TFTR/RFTR = 15 */
+};
+
 static struct amba_id nmk_i2c_ids[] = {
 	{
 		.id	= 0x00180024,
 		.mask	= 0x00ffffff,
+		.data	= &vendor_stn8815,
 	},
 	{
 		.id	= 0x00380024,
 		.mask	= 0x00ffffff,
+		.data	= &vendor_db8500,
 	},
 	{},
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-omap.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-omap.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-omap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-omap.c	2013-08-25 20:43:22.000000000 -0400
@@ -180,6 +180,8 @@ enum {
 #define I2C_OMAP_ERRATA_I207		(1 << 0)
 #define I2C_OMAP_ERRATA_I462		(1 << 1)
 
+#define OMAP_I2C_IP_V2_INTERRUPTS_MASK	0x6FFF
+
 struct omap_i2c_dev {
 	spinlock_t		lock;		/* IRQ synchronization */
 	struct device		*dev;
@@ -193,6 +195,7 @@ struct omap_i2c_dev {
 						    long latency);
 	u32			speed;		/* Speed of bus in kHz */
 	u32			flags;
+	u16			scheme;
 	u16			cmd_err;
 	u8			*buf;
 	u8			*regs;
@@ -1082,14 +1085,7 @@ omap_i2c_probe(struct platform_device *p
 	int irq;
 	int r;
 	u32 rev;
-	u16 minor, major, scheme;
-
-	/* NOTE: driver uses the static register mapping */
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem) {
-		dev_err(&pdev->dev, "no mem resource?\n");
-		return -ENODEV;
-	}
+	u16 minor, major;
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -1103,6 +1099,7 @@ omap_i2c_probe(struct platform_device *p
 		return -ENOMEM;
 	}
 
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dev->base = devm_ioremap_resource(&pdev->dev, mem);
 	if (IS_ERR(dev->base))
 		return PTR_ERR(dev->base);
@@ -1159,8 +1156,8 @@ omap_i2c_probe(struct platform_device *p
 	 */
 	rev = __raw_readw(dev->base + 0x04);
 
-	scheme = OMAP_I2C_SCHEME(rev);
-	switch (scheme) {
+	dev->scheme = OMAP_I2C_SCHEME(rev);
+	switch (dev->scheme) {
 	case OMAP_I2C_SCHEME_0:
 		dev->regs = (u8 *)reg_map_ip_v1;
 		dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG);
@@ -1289,7 +1286,11 @@ static int omap_i2c_runtime_suspend(stru
 
 	_dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
 
-	omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
+	if (_dev->scheme == OMAP_I2C_SCHEME_0)
+		omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
+	else
+		omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR,
+				   OMAP_I2C_IP_V2_INTERRUPTS_MASK);
 
 	if (_dev->rev < OMAP_I2C_OMAP1_REV_2) {
 		omap_i2c_read_reg(_dev, OMAP_I2C_IV_REG); /* Read clears */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-piix4.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-piix4.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-piix4.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-piix4.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,7 @@
 	Intel PIIX4, 440MX
 	Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
 	ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
-	AMD Hudson-2
+	AMD Hudson-2, CZ
 	SMSC Victory66
 
    Note: we assume there can only be one device, with one or more
@@ -522,6 +522,7 @@ static DEFINE_PCI_DEVICE_TABLE(piix4_ids
 	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x790b) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
 		     PCI_DEVICE_ID_SERVERWORKS_OSB4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-pxa.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-pxa.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-pxa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-pxa.c	2013-08-25 20:43:22.000000000 -0400
@@ -1160,7 +1160,7 @@ static int i2c_pxa_probe(struct platform
 		i2c->adap.class = plat->class;
 	}
 
-	clk_enable(i2c->clk);
+	clk_prepare_enable(i2c->clk);
 
 	if (i2c->use_pio) {
 		i2c->adap.algo = &i2c_pxa_pio_algorithm;
@@ -1202,7 +1202,7 @@ eadapt:
 	if (!i2c->use_pio)
 		free_irq(irq, i2c);
 ereqirq:
-	clk_disable(i2c->clk);
+	clk_disable_unprepare(i2c->clk);
 	iounmap(i2c->reg_base);
 eremap:
 	clk_put(i2c->clk);
@@ -1221,7 +1221,7 @@ static int i2c_pxa_remove(struct platfor
 	if (!i2c->use_pio)
 		free_irq(i2c->irq, i2c);
 
-	clk_disable(i2c->clk);
+	clk_disable_unprepare(i2c->clk);
 	clk_put(i2c->clk);
 
 	iounmap(i2c->reg_base);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-rcar.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-rcar.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-rcar.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-rcar.c	2013-08-25 20:43:22.000000000 -0400
@@ -623,12 +623,6 @@ static int rcar_i2c_probe(struct platfor
 	u32 bus_speed;
 	int ret;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(dev, "no mmio resources\n");
-		return -ENODEV;
-	}
-
 	priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL);
 	if (!priv) {
 		dev_err(dev, "no mem for private data\n");
@@ -642,6 +636,7 @@ static int rcar_i2c_probe(struct platfor
 	if (ret < 0)
 		return ret;
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	priv->io = devm_ioremap_resource(dev, res);
 	if (IS_ERR(priv->io))
 		return PTR_ERR(priv->io);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-stu300.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-stu300.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-stu300.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-stu300.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/of_i2c.h>
 
 /* the name of this kernel module */
 #define NAME "stu300"
@@ -867,7 +868,6 @@ stu300_probe(struct platform_device *pde
 	struct resource *res;
 	int bus_nr;
 	int ret = 0;
-	char clk_name[] = "I2C0";
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(struct stu300_dev), GFP_KERNEL);
 	if (!dev) {
@@ -876,8 +876,7 @@ stu300_probe(struct platform_device *pde
 	}
 
 	bus_nr = pdev->id;
-	clk_name[3] += (char)bus_nr;
-	dev->clk = devm_clk_get(&pdev->dev, clk_name);
+	dev->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(dev->clk)) {
 		dev_err(&pdev->dev, "could not retrieve i2c bus clock\n");
 		return PTR_ERR(dev->clk);
@@ -923,6 +922,7 @@ stu300_probe(struct platform_device *pde
 	adap->nr = bus_nr;
 	adap->algo = &stu300_algo;
 	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
 	i2c_set_adapdata(adap, dev);
 
 	/* i2c device drivers may be active on return from add_adapter() */
@@ -934,6 +934,10 @@ stu300_probe(struct platform_device *pde
 	}
 
 	platform_set_drvdata(pdev, dev);
+	dev_info(&pdev->dev, "ST DDC I2C @ %p, irq %d\n",
+		 dev->virtbase, dev->irq);
+	of_i2c_register_devices(adap);
+
 	return 0;
 }
 
@@ -978,11 +982,17 @@ stu300_remove(struct platform_device *pd
 	return 0;
 }
 
+static const struct of_device_id stu300_dt_match[] = {
+	{ .compatible = "st,ddci2c" },
+	{},
+};
+
 static struct platform_driver stu300_i2c_driver = {
 	.driver = {
 		.name	= NAME,
 		.owner	= THIS_MODULE,
 		.pm	= STU300_I2C_PM,
+		.of_match_table = stu300_dt_match,
 	},
 	.remove		= __exit_p(stu300_remove),
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/i2c-wmt.c linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-wmt.c
--- linux-libre-3.10-gnu/drivers/i2c/busses/i2c-wmt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/i2c-wmt.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,479 @@
+/*
+ *  Wondermedia I2C Master Mode Driver
+ *
+ *  Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
+ *
+ *  Derived from GPLv2+ licensed source:
+ *  - Copyright (C) 2008 WonderMedia Technologies, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2, or
+ *  (at your option) any later version. as published by the Free Software
+ *  Foundation
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_i2c.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#define REG_CR		0x00
+#define REG_TCR		0x02
+#define REG_CSR		0x04
+#define REG_ISR		0x06
+#define REG_IMR		0x08
+#define REG_CDR		0x0A
+#define REG_TR		0x0C
+#define REG_MCR		0x0E
+#define REG_SLAVE_CR	0x10
+#define REG_SLAVE_SR	0x12
+#define REG_SLAVE_ISR	0x14
+#define REG_SLAVE_IMR	0x16
+#define REG_SLAVE_DR	0x18
+#define REG_SLAVE_TR	0x1A
+
+/* REG_CR Bit fields */
+#define CR_TX_NEXT_ACK		0x0000
+#define CR_ENABLE		0x0001
+#define CR_TX_NEXT_NO_ACK	0x0002
+#define CR_TX_END		0x0004
+#define CR_CPU_RDY		0x0008
+#define SLAV_MODE_SEL		0x8000
+
+/* REG_TCR Bit fields */
+#define TCR_STANDARD_MODE	0x0000
+#define TCR_MASTER_WRITE	0x0000
+#define TCR_HS_MODE		0x2000
+#define TCR_MASTER_READ		0x4000
+#define TCR_FAST_MODE		0x8000
+#define TCR_SLAVE_ADDR_MASK	0x007F
+
+/* REG_ISR Bit fields */
+#define ISR_NACK_ADDR		0x0001
+#define ISR_BYTE_END		0x0002
+#define ISR_SCL_TIMEOUT		0x0004
+#define ISR_WRITE_ALL		0x0007
+
+/* REG_IMR Bit fields */
+#define IMR_ENABLE_ALL		0x0007
+
+/* REG_CSR Bit fields */
+#define CSR_RCV_NOT_ACK		0x0001
+#define CSR_RCV_ACK_MASK	0x0001
+#define CSR_READY_MASK		0x0002
+
+/* REG_TR */
+#define SCL_TIMEOUT(x)		(((x) & 0xFF) << 8)
+#define TR_STD			0x0064
+#define TR_HS			0x0019
+
+/* REG_MCR */
+#define MCR_APB_96M		7
+#define MCR_APB_166M		12
+
+#define I2C_MODE_STANDARD	0
+#define I2C_MODE_FAST		1
+
+#define WMT_I2C_TIMEOUT		(msecs_to_jiffies(1000))
+
+struct wmt_i2c_dev {
+	struct i2c_adapter	adapter;
+	struct completion	complete;
+	struct device		*dev;
+	void __iomem		*base;
+	struct clk		*clk;
+	int			mode;
+	int			irq;
+	u16			cmd_status;
+};
+
+static int wmt_i2c_wait_bus_not_busy(struct wmt_i2c_dev *i2c_dev)
+{
+	unsigned long timeout;
+
+	timeout = jiffies + WMT_I2C_TIMEOUT;
+	while (!(readw(i2c_dev->base + REG_CSR) & CSR_READY_MASK)) {
+		if (time_after(jiffies, timeout)) {
+			dev_warn(i2c_dev->dev, "timeout waiting for bus ready\n");
+			return -EBUSY;
+		}
+		msleep(20);
+	}
+
+	return 0;
+}
+
+static int wmt_check_status(struct wmt_i2c_dev *i2c_dev)
+{
+	int ret = 0;
+
+	if (i2c_dev->cmd_status & ISR_NACK_ADDR)
+		ret = -EIO;
+
+	if (i2c_dev->cmd_status & ISR_SCL_TIMEOUT)
+		ret = -ETIMEDOUT;
+
+	return ret;
+}
+
+static int wmt_i2c_write(struct i2c_adapter *adap, struct i2c_msg *pmsg,
+			 int last)
+{
+	struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
+	u16 val, tcr_val;
+	int ret, wait_result;
+	int xfer_len = 0;
+
+	if (!(pmsg->flags & I2C_M_NOSTART)) {
+		ret = wmt_i2c_wait_bus_not_busy(i2c_dev);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (pmsg->len == 0) {
+		/*
+		 * We still need to run through the while (..) once, so
+		 * start at -1 and break out early from the loop
+		 */
+		xfer_len = -1;
+		writew(0, i2c_dev->base + REG_CDR);
+	} else {
+		writew(pmsg->buf[0] & 0xFF, i2c_dev->base + REG_CDR);
+	}
+
+	if (!(pmsg->flags & I2C_M_NOSTART)) {
+		val = readw(i2c_dev->base + REG_CR);
+		val &= ~CR_TX_END;
+		writew(val, i2c_dev->base + REG_CR);
+
+		val = readw(i2c_dev->base + REG_CR);
+		val |= CR_CPU_RDY;
+		writew(val, i2c_dev->base + REG_CR);
+	}
+
+	INIT_COMPLETION(i2c_dev->complete);
+
+	if (i2c_dev->mode == I2C_MODE_STANDARD)
+		tcr_val = TCR_STANDARD_MODE;
+	else
+		tcr_val = TCR_FAST_MODE;
+
+	tcr_val |= (TCR_MASTER_WRITE | (pmsg->addr & TCR_SLAVE_ADDR_MASK));
+
+	writew(tcr_val, i2c_dev->base + REG_TCR);
+
+	if (pmsg->flags & I2C_M_NOSTART) {
+		val = readw(i2c_dev->base + REG_CR);
+		val |= CR_CPU_RDY;
+		writew(val, i2c_dev->base + REG_CR);
+	}
+
+	while (xfer_len < pmsg->len) {
+		wait_result = wait_for_completion_timeout(&i2c_dev->complete,
+							  500 * HZ / 1000);
+
+		if (wait_result == 0)
+			return -ETIMEDOUT;
+
+		ret = wmt_check_status(i2c_dev);
+		if (ret)
+			return ret;
+
+		xfer_len++;
+
+		val = readw(i2c_dev->base + REG_CSR);
+		if ((val & CSR_RCV_ACK_MASK) == CSR_RCV_NOT_ACK) {
+			dev_dbg(i2c_dev->dev, "write RCV NACK error\n");
+			return -EIO;
+		}
+
+		if (pmsg->len == 0) {
+			val = CR_TX_END | CR_CPU_RDY | CR_ENABLE;
+			writew(val, i2c_dev->base + REG_CR);
+			break;
+		}
+
+		if (xfer_len == pmsg->len) {
+			if (last != 1)
+				writew(CR_ENABLE, i2c_dev->base + REG_CR);
+		} else {
+			writew(pmsg->buf[xfer_len] & 0xFF, i2c_dev->base +
+								REG_CDR);
+			writew(CR_CPU_RDY | CR_ENABLE, i2c_dev->base + REG_CR);
+		}
+	}
+
+	return 0;
+}
+
+static int wmt_i2c_read(struct i2c_adapter *adap, struct i2c_msg *pmsg,
+			int last)
+{
+	struct wmt_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
+	u16 val, tcr_val;
+	int ret, wait_result;
+	u32 xfer_len = 0;
+
+	if (!(pmsg->flags & I2C_M_NOSTART)) {
+		ret = wmt_i2c_wait_bus_not_busy(i2c_dev);
+		if (ret < 0)
+			return ret;
+	}
+
+	val = readw(i2c_dev->base + REG_CR);
+	val &= ~CR_TX_END;
+	writew(val, i2c_dev->base + REG_CR);
+
+	val = readw(i2c_dev->base + REG_CR);
+	val &= ~CR_TX_NEXT_NO_ACK;
+	writew(val, i2c_dev->base + REG_CR);
+
+	if (!(pmsg->flags & I2C_M_NOSTART)) {
+		val = readw(i2c_dev->base + REG_CR);
+		val |= CR_CPU_RDY;
+		writew(val, i2c_dev->base + REG_CR);
+	}
+
+	if (pmsg->len == 1) {
+		val = readw(i2c_dev->base + REG_CR);
+		val |= CR_TX_NEXT_NO_ACK;
+		writew(val, i2c_dev->base + REG_CR);
+	}
+
+	INIT_COMPLETION(i2c_dev->complete);
+
+	if (i2c_dev->mode == I2C_MODE_STANDARD)
+		tcr_val = TCR_STANDARD_MODE;
+	else
+		tcr_val = TCR_FAST_MODE;
+
+	tcr_val |= TCR_MASTER_READ | (pmsg->addr & TCR_SLAVE_ADDR_MASK);
+
+	writew(tcr_val, i2c_dev->base + REG_TCR);
+
+	if (pmsg->flags & I2C_M_NOSTART) {
+		val = readw(i2c_dev->base + REG_CR);
+		val |= CR_CPU_RDY;
+		writew(val, i2c_dev->base + REG_CR);
+	}
+
+	while (xfer_len < pmsg->len) {
+		wait_result = wait_for_completion_timeout(&i2c_dev->complete,
+							  500 * HZ / 1000);
+
+		if (!wait_result)
+			return -ETIMEDOUT;
+
+		ret = wmt_check_status(i2c_dev);
+		if (ret)
+			return ret;
+
+		pmsg->buf[xfer_len] = readw(i2c_dev->base + REG_CDR) >> 8;
+		xfer_len++;
+
+		if (xfer_len == pmsg->len - 1) {
+			val = readw(i2c_dev->base + REG_CR);
+			val |= (CR_TX_NEXT_NO_ACK | CR_CPU_RDY);
+			writew(val, i2c_dev->base + REG_CR);
+		} else {
+			val = readw(i2c_dev->base + REG_CR);
+			val |= CR_CPU_RDY;
+			writew(val, i2c_dev->base + REG_CR);
+		}
+	}
+
+	return 0;
+}
+
+static int wmt_i2c_xfer(struct i2c_adapter *adap,
+			struct i2c_msg msgs[],
+			int num)
+{
+	struct i2c_msg *pmsg;
+	int i, is_last;
+	int ret = 0;
+
+	for (i = 0; ret >= 0 && i < num; i++) {
+		is_last = ((i + 1) == num);
+
+		pmsg = &msgs[i];
+		if (pmsg->flags & I2C_M_RD)
+			ret = wmt_i2c_read(adap, pmsg, is_last);
+		else
+			ret = wmt_i2c_write(adap, pmsg, is_last);
+	}
+
+	return (ret < 0) ? ret : i;
+}
+
+static u32 wmt_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART;
+}
+
+static const struct i2c_algorithm wmt_i2c_algo = {
+	.master_xfer	= wmt_i2c_xfer,
+	.functionality	= wmt_i2c_func,
+};
+
+static irqreturn_t wmt_i2c_isr(int irq, void *data)
+{
+	struct wmt_i2c_dev *i2c_dev = data;
+
+	/* save the status and write-clear it */
+	i2c_dev->cmd_status = readw(i2c_dev->base + REG_ISR);
+	writew(i2c_dev->cmd_status, i2c_dev->base + REG_ISR);
+
+	complete(&i2c_dev->complete);
+
+	return IRQ_HANDLED;
+}
+
+static int wmt_i2c_reset_hardware(struct wmt_i2c_dev *i2c_dev)
+{
+	int err;
+
+	err = clk_prepare_enable(i2c_dev->clk);
+	if (err) {
+		dev_err(i2c_dev->dev, "failed to enable clock\n");
+		return err;
+	}
+
+	err = clk_set_rate(i2c_dev->clk, 20000000);
+	if (err) {
+		dev_err(i2c_dev->dev, "failed to set clock = 20Mhz\n");
+		return err;
+	}
+
+	writew(0, i2c_dev->base + REG_CR);
+	writew(MCR_APB_166M, i2c_dev->base + REG_MCR);
+	writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR);
+	writew(IMR_ENABLE_ALL, i2c_dev->base + REG_IMR);
+	writew(CR_ENABLE, i2c_dev->base + REG_CR);
+	readw(i2c_dev->base + REG_CSR);		/* read clear */
+	writew(ISR_WRITE_ALL, i2c_dev->base + REG_ISR);
+
+	if (i2c_dev->mode == I2C_MODE_STANDARD)
+		writew(SCL_TIMEOUT(128) | TR_STD, i2c_dev->base + REG_TR);
+	else
+		writew(SCL_TIMEOUT(128) | TR_HS, i2c_dev->base + REG_TR);
+
+	return 0;
+}
+
+static int wmt_i2c_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct wmt_i2c_dev *i2c_dev;
+	struct i2c_adapter *adap;
+	struct resource *res;
+	int err;
+	u32 clk_rate;
+
+	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
+	if (!i2c_dev) {
+		dev_err(&pdev->dev, "device memory allocation failed\n");
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	i2c_dev->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(i2c_dev->base))
+		return PTR_ERR(i2c_dev->base);
+
+	i2c_dev->irq = irq_of_parse_and_map(np, 0);
+	if (!i2c_dev->irq) {
+		dev_err(&pdev->dev, "irq missing or invalid\n");
+		return -EINVAL;
+	}
+
+	i2c_dev->clk = of_clk_get(np, 0);
+	if (IS_ERR(i2c_dev->clk)) {
+		dev_err(&pdev->dev, "unable to request clock\n");
+		return PTR_ERR(i2c_dev->clk);
+	}
+
+	i2c_dev->mode = I2C_MODE_STANDARD;
+	err = of_property_read_u32(np, "clock-frequency", &clk_rate);
+	if ((!err) && (clk_rate == 400000))
+		i2c_dev->mode = I2C_MODE_FAST;
+
+	i2c_dev->dev = &pdev->dev;
+
+	err = devm_request_irq(&pdev->dev, i2c_dev->irq, wmt_i2c_isr, 0,
+							"i2c", i2c_dev);
+	if (err) {
+		dev_err(&pdev->dev, "failed to request irq %i\n", i2c_dev->irq);
+		return err;
+	}
+
+	adap = &i2c_dev->adapter;
+	i2c_set_adapdata(adap, i2c_dev);
+	strlcpy(adap->name, "WMT I2C adapter", sizeof(adap->name));
+	adap->owner = THIS_MODULE;
+	adap->algo = &wmt_i2c_algo;
+	adap->dev.parent = &pdev->dev;
+	adap->dev.of_node = pdev->dev.of_node;
+
+	init_completion(&i2c_dev->complete);
+
+	err = wmt_i2c_reset_hardware(i2c_dev);
+	if (err) {
+		dev_err(&pdev->dev, "error initializing hardware\n");
+		return err;
+	}
+
+	err = i2c_add_adapter(adap);
+	if (err) {
+		dev_err(&pdev->dev, "failed to add adapter\n");
+		return err;
+	}
+
+	platform_set_drvdata(pdev, i2c_dev);
+
+	of_i2c_register_devices(adap);
+
+	return 0;
+}
+
+static int wmt_i2c_remove(struct platform_device *pdev)
+{
+	struct wmt_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+	/* Disable interrupts, clock and delete adapter */
+	writew(0, i2c_dev->base + REG_IMR);
+	clk_disable_unprepare(i2c_dev->clk);
+	i2c_del_adapter(&i2c_dev->adapter);
+
+	return 0;
+}
+
+static struct of_device_id wmt_i2c_dt_ids[] = {
+	{ .compatible = "wm,wm8505-i2c" },
+	{ /* Sentinel */ },
+};
+
+static struct platform_driver wmt_i2c_driver = {
+	.probe		= wmt_i2c_probe,
+	.remove		= wmt_i2c_remove,
+	.driver		= {
+		.name	= "wmt-i2c",
+		.owner	= THIS_MODULE,
+		.of_match_table = wmt_i2c_dt_ids,
+	},
+};
+
+module_platform_driver(wmt_i2c_driver);
+
+MODULE_DESCRIPTION("Wondermedia I2C master-mode bus adapter");
+MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, wmt_i2c_dt_ids);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/Kconfig linux-libre-3.11-rc7-gnu/drivers/i2c/busses/Kconfig
--- linux-libre-3.10-gnu/drivers/i2c/busses/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -108,6 +108,7 @@ config I2C_I801
 	    Lynx Point-LP (PCH)
 	    Avoton (SOC)
 	    Wellsburg (PCH)
+	    Coleto Creek (PCH)
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
@@ -150,6 +151,7 @@ config I2C_PIIX4
 	    ATI SB700/SP5100
 	    ATI SB800
 	    AMD Hudson-2
+	    AMD CZ
 	    Serverworks OSB4
 	    Serverworks CSB5
 	    Serverworks CSB6
@@ -474,16 +476,6 @@ config I2C_IMX
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-imx.
 
-config I2C_INTEL_MID
-	tristate "Intel Moorestown/Medfield Platform I2C controller"
-	depends on PCI
-	help
-	  Say Y here if you have an Intel Moorestown/Medfield platform I2C
-	  controller.
-
-	  This support is also available as a module. If so, the module
-	  will be called i2c-intel-mid.
-
 config I2C_IOP3XX
 	tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
 	depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
@@ -494,6 +486,16 @@ config I2C_IOP3XX
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-iop3xx.
 
+config I2C_KEMPLD
+	tristate "Kontron COM I2C Controller"
+	depends on MFD_KEMPLD
+	help
+	  This enables support for the I2C bus interface on some Kontron ETX
+	  and COMexpress (ETXexpress) modules.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called i2c-kempld.
+
 config I2C_MPC
 	tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
 	depends on PPC
@@ -507,10 +509,11 @@ config I2C_MPC
 
 config I2C_MV64XXX
 	tristate "Marvell mv64xxx I2C Controller"
-	depends on (MV64X60 || PLAT_ORION)
+	depends on (MV64X60 || PLAT_ORION || ARCH_SUNXI)
 	help
 	  If you say yes to this option, support will be included for the
 	  built-in I2C interface on the Marvell 64xxx line of host bridges.
+	  This driver is also used for Allwinner SoCs I2C controllers.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-mv64xxx.
@@ -685,7 +688,7 @@ config I2C_SIMTEC
 
 config I2C_SIRF
 	tristate "CSR SiRFprimaII I2C interface"
-	depends on ARCH_PRIMA2
+	depends on ARCH_SIRF
 	help
 	  If you say yes to this option, support will be included for the
 	  CSR SiRFprimaII I2C interface.
@@ -724,9 +727,19 @@ config I2C_VERSATILE
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-versatile.
 
+config I2C_WMT
+	tristate "Wondermedia WM8xxx SoC I2C bus support"
+	depends on ARCH_VT8500
+	help
+	  Say yes if you want to support the I2C bus on Wondermedia 8xxx-series
+	  SoCs.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called i2c-wmt.
+
 config I2C_OCTEON
 	tristate "Cavium OCTEON I2C bus support"
-	depends on CPU_CAVIUM_OCTEON
+	depends on CAVIUM_OCTEON_SOC
 	help
 	  Say yes if you want to support the I2C serial bus on Cavium
 	  OCTEON SOC.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/busses/Makefile linux-libre-3.11-rc7-gnu/drivers/i2c/busses/Makefile
--- linux-libre-3.10-gnu/drivers/i2c/busses/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/busses/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -46,8 +46,8 @@ obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o
 obj-$(CONFIG_I2C_HIGHLANDER)	+= i2c-highlander.o
 obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
 obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
-obj-$(CONFIG_I2C_INTEL_MID)	+= i2c-intel-mid.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
+obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
 obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
 obj-$(CONFIG_I2C_MV64XXX)	+= i2c-mv64xxx.o
 obj-$(CONFIG_I2C_MXS)		+= i2c-mxs.o
@@ -71,6 +71,7 @@ obj-$(CONFIG_I2C_SIRF)		+= i2c-sirf.o
 obj-$(CONFIG_I2C_STU300)	+= i2c-stu300.o
 obj-$(CONFIG_I2C_TEGRA)		+= i2c-tegra.o
 obj-$(CONFIG_I2C_VERSATILE)	+= i2c-versatile.o
+obj-$(CONFIG_I2C_WMT)		+= i2c-wmt.o
 obj-$(CONFIG_I2C_OCTEON)	+= i2c-octeon.o
 obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)		+= i2c-xlr.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/i2c/i2c-core.c linux-libre-3.11-rc7-gnu/drivers/i2c/i2c-core.c
--- linux-libre-3.10-gnu/drivers/i2c/i2c-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/i2c/i2c-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -435,7 +435,7 @@ static const struct dev_pm_ops i2c_devic
 	SET_RUNTIME_PM_OPS(
 		pm_generic_runtime_suspend,
 		pm_generic_runtime_resume,
-		pm_generic_runtime_idle
+		NULL
 	)
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ide/delkin_cb.c linux-libre-3.11-rc7-gnu/drivers/ide/delkin_cb.c
--- linux-libre-3.10-gnu/drivers/ide/delkin_cb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ide/delkin_cb.c	2013-08-25 20:43:22.000000000 -0400
@@ -173,18 +173,7 @@ static struct pci_driver delkin_cb_pci_d
 	.resume		= delkin_cb_resume,
 };
 
-static int __init delkin_cb_init(void)
-{
-	return pci_register_driver(&delkin_cb_pci_driver);
-}
-
-static void __exit delkin_cb_exit(void)
-{
-	pci_unregister_driver(&delkin_cb_pci_driver);
-}
-
-module_init(delkin_cb_init);
-module_exit(delkin_cb_exit);
+module_pci_driver(delkin_cb_pci_driver);
 
 MODULE_AUTHOR("Mark Lord");
 MODULE_DESCRIPTION("Basic support for Delkin/ASKA/Workbit Cardbus IDE");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ide/gayle.c linux-libre-3.11-rc7-gnu/drivers/ide/gayle.c
--- linux-libre-3.10-gnu/drivers/ide/gayle.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ide/gayle.c	2013-08-25 20:43:22.000000000 -0400
@@ -183,20 +183,7 @@ static struct platform_driver amiga_gayl
 	},
 };
 
-static int __init amiga_gayle_ide_init(void)
-{
-	return platform_driver_probe(&amiga_gayle_ide_driver,
-				     amiga_gayle_ide_probe);
-}
-
-module_init(amiga_gayle_ide_init);
-
-static void __exit amiga_gayle_ide_exit(void)
-{
-	platform_driver_unregister(&amiga_gayle_ide_driver);
-}
-
-module_exit(amiga_gayle_ide_exit);
+module_platform_driver_probe(amiga_gayle_ide_driver, amiga_gayle_ide_probe);
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:amiga-gayle-ide");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ide/ide-cd.c linux-libre-3.11-rc7-gnu/drivers/ide/ide-cd.c
--- linux-libre-3.10-gnu/drivers/ide/ide-cd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ide/ide-cd.c	2013-08-25 20:43:22.000000000 -0400
@@ -1756,7 +1756,7 @@ static int ide_cd_probe(ide_drive_t *dri
 
 	info->dev.parent = &drive->gendev;
 	info->dev.release = ide_cd_release;
-	dev_set_name(&info->dev, dev_name(&drive->gendev));
+	dev_set_name(&info->dev, "%s", dev_name(&drive->gendev));
 
 	if (device_register(&info->dev))
 		goto out_free_disk;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ide/ide-gd.c linux-libre-3.11-rc7-gnu/drivers/ide/ide-gd.c
--- linux-libre-3.10-gnu/drivers/ide/ide-gd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ide/ide-gd.c	2013-08-25 20:43:22.000000000 -0400
@@ -392,7 +392,7 @@ static int ide_gd_probe(ide_drive_t *dri
 
 	idkp->dev.parent = &drive->gendev;
 	idkp->dev.release = ide_disk_release;
-	dev_set_name(&idkp->dev, dev_name(&drive->gendev));
+	dev_set_name(&idkp->dev, "%s", dev_name(&drive->gendev));
 
 	if (device_register(&idkp->dev))
 		goto out_free_disk;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ide/ide-probe.c linux-libre-3.11-rc7-gnu/drivers/ide/ide-probe.c
--- linux-libre-3.10-gnu/drivers/ide/ide-probe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ide/ide-probe.c	2013-08-25 20:43:22.000000000 -0400
@@ -545,7 +545,7 @@ static int ide_register_port(ide_hwif_t
 	int ret;
 
 	/* register with global device tree */
-	dev_set_name(&hwif->gendev, hwif->name);
+	dev_set_name(&hwif->gendev, "%s", hwif->name);
 	dev_set_drvdata(&hwif->gendev, hwif);
 	if (hwif->gendev.parent == NULL)
 		hwif->gendev.parent = hwif->dev;
@@ -559,7 +559,7 @@ static int ide_register_port(ide_hwif_t
 	}
 
 	hwif->portdev = device_create(ide_port_class, &hwif->gendev,
-				      MKDEV(0, 0), hwif, hwif->name);
+				      MKDEV(0, 0), hwif, "%s", hwif->name);
 	if (IS_ERR(hwif->portdev)) {
 		ret = PTR_ERR(hwif->portdev);
 		device_unregister(&hwif->gendev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ide/ide-tape.c linux-libre-3.11-rc7-gnu/drivers/ide/ide-tape.c
--- linux-libre-3.10-gnu/drivers/ide/ide-tape.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ide/ide-tape.c	2013-08-25 20:43:22.000000000 -0400
@@ -1985,7 +1985,7 @@ static int ide_tape_probe(ide_drive_t *d
 
 	tape->dev.parent = &drive->gendev;
 	tape->dev.release = ide_tape_release;
-	dev_set_name(&tape->dev, dev_name(&drive->gendev));
+	dev_set_name(&tape->dev, "%s", dev_name(&drive->gendev));
 
 	if (device_register(&tape->dev))
 		goto out_free_disk;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ide/ide-taskfile.c linux-libre-3.11-rc7-gnu/drivers/ide/ide-taskfile.c
--- linux-libre-3.10-gnu/drivers/ide/ide-taskfile.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ide/ide-taskfile.c	2013-08-25 20:43:22.000000000 -0400
@@ -239,9 +239,6 @@ void ide_pio_bytes(ide_drive_t *drive, s
 		unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
 		int page_is_high;
 
-		if (nr_bytes > PAGE_SIZE)
-			nr_bytes = PAGE_SIZE;
-
 		page = sg_page(cursg);
 		offset = cursg->offset + cmd->cursg_ofs;
 
@@ -249,6 +246,8 @@ void ide_pio_bytes(ide_drive_t *drive, s
 		page = nth_page(page, (offset >> PAGE_SHIFT));
 		offset %= PAGE_SIZE;
 
+		nr_bytes = min_t(unsigned, nr_bytes, (PAGE_SIZE - offset));
+
 		page_is_high = PageHighMem(page);
 		if (page_is_high)
 			local_irq_save(flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ide/tx4938ide.c linux-libre-3.11-rc7-gnu/drivers/ide/tx4938ide.c
--- linux-libre-3.10-gnu/drivers/ide/tx4938ide.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ide/tx4938ide.c	2013-08-25 20:43:22.000000000 -0400
@@ -203,18 +203,7 @@ static struct platform_driver tx4938ide_
 	.remove = __exit_p(tx4938ide_remove),
 };
 
-static int __init tx4938ide_init(void)
-{
-	return platform_driver_probe(&tx4938ide_driver, tx4938ide_probe);
-}
-
-static void __exit tx4938ide_exit(void)
-{
-	platform_driver_unregister(&tx4938ide_driver);
-}
-
-module_init(tx4938ide_init);
-module_exit(tx4938ide_exit);
+module_platform_driver_probe(tx4938ide_driver, tx4938ide_probe);
 
 MODULE_DESCRIPTION("TX4938 internal IDE driver");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ide/tx4939ide.c linux-libre-3.11-rc7-gnu/drivers/ide/tx4939ide.c
--- linux-libre-3.10-gnu/drivers/ide/tx4939ide.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ide/tx4939ide.c	2013-08-25 20:43:22.000000000 -0400
@@ -624,18 +624,7 @@ static struct platform_driver tx4939ide_
 	.resume = tx4939ide_resume,
 };
 
-static int __init tx4939ide_init(void)
-{
-	return platform_driver_probe(&tx4939ide_driver, tx4939ide_probe);
-}
-
-static void __exit tx4939ide_exit(void)
-{
-	platform_driver_unregister(&tx4939ide_driver);
-}
-
-module_init(tx4939ide_init);
-module_exit(tx4939ide_exit);
+module_platform_driver_probe(tx4939ide_driver, tx4939ide_probe);
 
 MODULE_DESCRIPTION("TX4939 internal IDE driver");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/accel/Kconfig linux-libre-3.11-rc7-gnu/drivers/iio/accel/Kconfig
--- linux-libre-3.10-gnu/drivers/iio/accel/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/accel/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,6 @@ config IIO_ST_ACCEL_3AXIS
 	select IIO_ST_ACCEL_I2C_3AXIS if (I2C)
 	select IIO_ST_ACCEL_SPI_3AXIS if (SPI_MASTER)
 	select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
-	select IIO_ST_ACCEL_BUFFER if (IIO_TRIGGERED_BUFFER)
 	help
 	  Say yes here to build support for STMicroelectronics accelerometers:
 	  LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/accel/st_accel_core.c linux-libre-3.11-rc7-gnu/drivers/iio/accel/st_accel_core.c
--- linux-libre-3.10-gnu/drivers/iio/accel/st_accel_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/accel/st_accel_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,8 @@
 #include <linux/iio/common/st_sensors.h>
 #include "st_accel.h"
 
+#define ST_ACCEL_NUMBER_DATA_CHANNELS		3
+
 /* DEFAULT VALUE FOR SENSORS */
 #define ST_ACCEL_DEFAULT_OUT_X_L_ADDR		0x28
 #define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR		0x2a
@@ -125,22 +127,34 @@
 #define ST_ACCEL_3_MULTIREAD_BIT		false
 
 static const struct iio_chan_spec st_accel_12bit_channels[] = {
-	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
-		ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
-		ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
-		ST_SENSORS_DEFAULT_12_REALBITS, ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 12, 16,
+			ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 12, 16,
+			ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 12, 16,
+			ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
 static const struct iio_chan_spec st_accel_16bit_channels[] = {
-	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
-		ST_SENSORS_DEFAULT_16_REALBITS, ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
-		ST_SENSORS_DEFAULT_16_REALBITS, ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
-		ST_SENSORS_DEFAULT_16_REALBITS, ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
+			ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
+			ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
+			ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
@@ -442,6 +456,7 @@ int st_accel_common_probe(struct iio_dev
 	if (err < 0)
 		goto st_accel_common_probe_error;
 
+	adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
 	adata->multiread_bit = adata->sensor->multi_read_bit;
 	indio_dev->channels = adata->sensor->ch;
 	indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/adc/at91_adc.c linux-libre-3.11-rc7-gnu/drivers/iio/adc/at91_adc.c
--- linux-libre-3.10-gnu/drivers/iio/adc/at91_adc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/adc/at91_adc.c	2013-08-25 20:43:22.000000000 -0400
@@ -774,11 +774,13 @@ static int at91_adc_remove(struct platfo
 	return 0;
 }
 
+#ifdef CONFIG_OF
 static const struct of_device_id at91_adc_dt_ids[] = {
 	{ .compatible = "atmel,at91sam9260-adc" },
 	{},
 };
 MODULE_DEVICE_TABLE(of, at91_adc_dt_ids);
+#endif
 
 static struct platform_driver at91_adc_driver = {
 	.probe = at91_adc_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/adc/exynos_adc.c linux-libre-3.11-rc7-gnu/drivers/iio/adc/exynos_adc.c
--- linux-libre-3.10-gnu/drivers/iio/adc/exynos_adc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/adc/exynos_adc.c	2013-08-25 20:43:22.000000000 -0400
@@ -270,16 +270,16 @@ static int exynos_adc_probe(struct platf
 	info = iio_priv(indio_dev);
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	info->regs = devm_request_and_ioremap(&pdev->dev, mem);
-	if (!info->regs) {
-		ret = -ENOMEM;
+	info->regs = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(info->regs)) {
+		ret = PTR_ERR(info->regs);
 		goto err_iio;
 	}
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	info->enable_reg = devm_request_and_ioremap(&pdev->dev, mem);
-	if (!info->enable_reg) {
-		ret = -ENOMEM;
+	info->enable_reg = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(info->enable_reg)) {
+		ret = PTR_ERR(info->enable_reg);
 		goto err_iio;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/adc/Kconfig linux-libre-3.11-rc7-gnu/drivers/iio/adc/Kconfig
--- linux-libre-3.10-gnu/drivers/iio/adc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/adc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -133,6 +133,16 @@ config MAX1363
 	  max11646, max11647) Provides direct access via sysfs and buffered
 	  data via the iio dev interface.
 
+config MCP320X
+	tristate "Microchip Technology MCP3204/08"
+	depends on SPI
+	help
+	  Say yes here to build support for Microchip Technology's MCP3204 or
+	  MCP3208 analog to digital converter.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called mcp320x.
+
 config TI_ADC081C
 	tristate "Texas Instruments ADC081C021/027"
 	depends on I2C
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/adc/Makefile linux-libre-3.11-rc7-gnu/drivers/iio/adc/Makefile
--- linux-libre-3.10-gnu/drivers/iio/adc/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/adc/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/adc/max1363.c linux-libre-3.11-rc7-gnu/drivers/iio/adc/max1363.c
--- linux-libre-3.10-gnu/drivers/iio/adc/max1363.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/adc/max1363.c	2013-08-25 20:43:22.000000000 -0400
@@ -660,7 +660,7 @@ static ssize_t max1363_monitor_store_fre
 	unsigned long val;
 	bool found = false;
 
-	ret = strict_strtoul(buf, 10, &val);
+	ret = kstrtoul(buf, 10, &val);
 	if (ret)
 		return -EINVAL;
 	for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/adc/mcp320x.c linux-libre-3.11-rc7-gnu/drivers/iio/adc/mcp320x.c
--- linux-libre-3.10-gnu/drivers/iio/adc/mcp320x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/adc/mcp320x.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2013 Oskar Andero <oskar.andero@gmail.com>
+ *
+ * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
+ * Datasheet can be found here:
+ * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/iio/iio.h>
+#include <linux/regulator/consumer.h>
+
+#define MCP_SINGLE_ENDED	(1 << 3)
+#define MCP_START_BIT		(1 << 4)
+
+enum {
+	mcp3204,
+	mcp3208,
+};
+
+struct mcp320x {
+	struct spi_device *spi;
+	struct spi_message msg;
+	struct spi_transfer transfer[2];
+
+	u8 tx_buf;
+	u8 rx_buf[2];
+
+	struct regulator *reg;
+	struct mutex lock;
+};
+
+static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
+{
+	int ret;
+
+	adc->tx_buf = msg;
+	ret = spi_sync(adc->spi, &adc->msg);
+	if (ret < 0)
+		return ret;
+
+	return ((adc->rx_buf[0] & 0x3f) << 6)  |
+		(adc->rx_buf[1] >> 2);
+}
+
+static int mcp320x_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *channel, int *val,
+			    int *val2, long mask)
+{
+	struct mcp320x *adc = iio_priv(indio_dev);
+	int ret = -EINVAL;
+
+	mutex_lock(&adc->lock);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		if (channel->differential)
+			ret = mcp320x_adc_conversion(adc,
+				MCP_START_BIT | channel->address);
+		else
+			ret = mcp320x_adc_conversion(adc,
+				MCP_START_BIT | MCP_SINGLE_ENDED |
+				channel->address);
+		if (ret < 0)
+			goto out;
+
+		*val = ret;
+		ret = IIO_VAL_INT;
+		break;
+
+	case IIO_CHAN_INFO_SCALE:
+		/* Digital output code = (4096 * Vin) / Vref */
+		ret = regulator_get_voltage(adc->reg);
+		if (ret < 0)
+			goto out;
+
+		*val = ret / 1000;
+		*val2 = 12;
+		ret = IIO_VAL_FRACTIONAL_LOG2;
+		break;
+
+	default:
+		break;
+	}
+
+out:
+	mutex_unlock(&adc->lock);
+
+	return ret;
+}
+
+#define MCP320X_VOLTAGE_CHANNEL(num)				\
+	{							\
+		.type = IIO_VOLTAGE,				\
+		.indexed = 1,					\
+		.channel = (num),				\
+		.address = (num),				\
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
+	}
+
+#define MCP320X_VOLTAGE_CHANNEL_DIFF(num)			\
+	{							\
+		.type = IIO_VOLTAGE,				\
+		.indexed = 1,					\
+		.channel = (num * 2),				\
+		.channel2 = (num * 2 + 1),			\
+		.address = (num * 2),				\
+		.differential = 1,				\
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \
+	}
+
+static const struct iio_chan_spec mcp3204_channels[] = {
+	MCP320X_VOLTAGE_CHANNEL(0),
+	MCP320X_VOLTAGE_CHANNEL(1),
+	MCP320X_VOLTAGE_CHANNEL(2),
+	MCP320X_VOLTAGE_CHANNEL(3),
+	MCP320X_VOLTAGE_CHANNEL_DIFF(0),
+	MCP320X_VOLTAGE_CHANNEL_DIFF(1),
+};
+
+static const struct iio_chan_spec mcp3208_channels[] = {
+	MCP320X_VOLTAGE_CHANNEL(0),
+	MCP320X_VOLTAGE_CHANNEL(1),
+	MCP320X_VOLTAGE_CHANNEL(2),
+	MCP320X_VOLTAGE_CHANNEL(3),
+	MCP320X_VOLTAGE_CHANNEL(4),
+	MCP320X_VOLTAGE_CHANNEL(5),
+	MCP320X_VOLTAGE_CHANNEL(6),
+	MCP320X_VOLTAGE_CHANNEL(7),
+	MCP320X_VOLTAGE_CHANNEL_DIFF(0),
+	MCP320X_VOLTAGE_CHANNEL_DIFF(1),
+	MCP320X_VOLTAGE_CHANNEL_DIFF(2),
+	MCP320X_VOLTAGE_CHANNEL_DIFF(3),
+};
+
+static const struct iio_info mcp320x_info = {
+	.read_raw = mcp320x_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+struct mcp3208_chip_info {
+	const struct iio_chan_spec *channels;
+	unsigned int num_channels;
+};
+
+static const struct mcp3208_chip_info mcp3208_chip_infos[] = {
+	[mcp3204] = {
+		.channels = mcp3204_channels,
+		.num_channels = ARRAY_SIZE(mcp3204_channels)
+	},
+	[mcp3208] = {
+		.channels = mcp3208_channels,
+		.num_channels = ARRAY_SIZE(mcp3208_channels)
+	},
+};
+
+static int mcp320x_probe(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev;
+	struct mcp320x *adc;
+	const struct mcp3208_chip_info *chip_info;
+	int ret;
+
+	indio_dev = iio_device_alloc(sizeof(*adc));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	adc = iio_priv(indio_dev);
+	adc->spi = spi;
+
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &mcp320x_info;
+
+	chip_info = &mcp3208_chip_infos[spi_get_device_id(spi)->driver_data];
+	indio_dev->channels = chip_info->channels;
+	indio_dev->num_channels = chip_info->num_channels;
+
+	adc->transfer[0].tx_buf = &adc->tx_buf;
+	adc->transfer[0].len = sizeof(adc->tx_buf);
+	adc->transfer[1].rx_buf = adc->rx_buf;
+	adc->transfer[1].len = sizeof(adc->rx_buf);
+
+	spi_message_init_with_transfers(&adc->msg, adc->transfer,
+					ARRAY_SIZE(adc->transfer));
+
+	adc->reg = regulator_get(&spi->dev, "vref");
+	if (IS_ERR(adc->reg)) {
+		ret = PTR_ERR(adc->reg);
+		goto iio_free;
+	}
+
+	ret = regulator_enable(adc->reg);
+	if (ret < 0)
+		goto reg_free;
+
+	mutex_init(&adc->lock);
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		goto reg_disable;
+
+	return 0;
+
+reg_disable:
+	regulator_disable(adc->reg);
+reg_free:
+	regulator_put(adc->reg);
+iio_free:
+	iio_device_free(indio_dev);
+
+	return ret;
+}
+
+static int mcp320x_remove(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct mcp320x *adc = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	regulator_disable(adc->reg);
+	regulator_put(adc->reg);
+	iio_device_free(indio_dev);
+
+	return 0;
+}
+
+static const struct spi_device_id mcp320x_id[] = {
+	{ "mcp3204", mcp3204 },
+	{ "mcp3208", mcp3208 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, mcp320x_id);
+
+static struct spi_driver mcp320x_driver = {
+	.driver = {
+		.name = "mcp320x",
+		.owner = THIS_MODULE,
+	},
+	.probe = mcp320x_probe,
+	.remove = mcp320x_remove,
+	.id_table = mcp320x_id,
+};
+module_spi_driver(mcp320x_driver);
+
+MODULE_AUTHOR("Oskar Andero <oskar.andero@gmail.com>");
+MODULE_DESCRIPTION("Microchip Technology MCP3204/08");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/adc/ti_am335x_adc.c linux-libre-3.11-rc7-gnu/drivers/iio/adc/ti_am335x_adc.c
--- linux-libre-3.10-gnu/drivers/iio/adc/ti_am335x_adc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/adc/ti_am335x_adc.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,13 +22,18 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/iio/iio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/iio/machine.h>
+#include <linux/iio/driver.h>
 
 #include <linux/mfd/ti_am335x_tscadc.h>
-#include <linux/platform_data/ti_am335x_adc.h>
 
 struct tiadc_device {
 	struct ti_tscadc_dev *mfd_tscadc;
 	int channels;
+	u8 channel_line[8];
+	u8 channel_step[8];
 };
 
 static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
@@ -42,10 +47,19 @@ static void tiadc_writel(struct tiadc_de
 	writel(val, adc->mfd_tscadc->tscadc_base + reg);
 }
 
+static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
+{
+	u32 step_en;
+
+	step_en = ((1 << adc_dev->channels) - 1);
+	step_en <<= TOTAL_STEPS - adc_dev->channels + 1;
+	return step_en;
+}
+
 static void tiadc_step_config(struct tiadc_device *adc_dev)
 {
 	unsigned int stepconfig;
-	int i, channels = 0, steps;
+	int i, steps;
 
 	/*
 	 * There are 16 configurable steps and 8 analog input
@@ -58,43 +72,62 @@ static void tiadc_step_config(struct tia
 	 */
 
 	steps = TOTAL_STEPS - adc_dev->channels;
-	channels = TOTAL_CHANNELS - adc_dev->channels;
-
 	stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
 
-	for (i = (steps + 1); i <= TOTAL_STEPS; i++) {
-		tiadc_writel(adc_dev, REG_STEPCONFIG(i),
-				stepconfig | STEPCONFIG_INP(channels));
-		tiadc_writel(adc_dev, REG_STEPDELAY(i),
+	for (i = 0; i < adc_dev->channels; i++) {
+		int chan;
+
+		chan = adc_dev->channel_line[i];
+		tiadc_writel(adc_dev, REG_STEPCONFIG(steps),
+				stepconfig | STEPCONFIG_INP(chan));
+		tiadc_writel(adc_dev, REG_STEPDELAY(steps),
 				STEPCONFIG_OPENDLY);
-		channels++;
+		adc_dev->channel_step[i] = steps;
+		steps++;
 	}
-	tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
+
 }
 
+static const char * const chan_name_ain[] = {
+	"AIN0",
+	"AIN1",
+	"AIN2",
+	"AIN3",
+	"AIN4",
+	"AIN5",
+	"AIN6",
+	"AIN7",
+};
+
 static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
 {
+	struct tiadc_device *adc_dev = iio_priv(indio_dev);
 	struct iio_chan_spec *chan_array;
+	struct iio_chan_spec *chan;
 	int i;
 
 	indio_dev->num_channels = channels;
-	chan_array = kcalloc(indio_dev->num_channels,
+	chan_array = kcalloc(channels,
 			sizeof(struct iio_chan_spec), GFP_KERNEL);
-
 	if (chan_array == NULL)
 		return -ENOMEM;
 
-	for (i = 0; i < (indio_dev->num_channels); i++) {
-		struct iio_chan_spec *chan = chan_array + i;
+	chan = chan_array;
+	for (i = 0; i < channels; i++, chan++) {
+
 		chan->type = IIO_VOLTAGE;
 		chan->indexed = 1;
-		chan->channel = i;
+		chan->channel = adc_dev->channel_line[i];
 		chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
+		chan->datasheet_name = chan_name_ain[chan->channel];
+		chan->scan_type.sign = 'u';
+		chan->scan_type.realbits = 12;
+		chan->scan_type.storagebits = 32;
 	}
 
 	indio_dev->channels = chan_array;
 
-	return indio_dev->num_channels;
+	return 0;
 }
 
 static void tiadc_channels_remove(struct iio_dev *indio_dev)
@@ -107,8 +140,22 @@ static int tiadc_read_raw(struct iio_dev
 		int *val, int *val2, long mask)
 {
 	struct tiadc_device *adc_dev = iio_priv(indio_dev);
-	int i;
-	unsigned int fifo1count, readx1;
+	int i, map_val;
+	unsigned int fifo1count, read, stepid;
+	u32 step = UINT_MAX;
+	bool found = false;
+	u32 step_en;
+	unsigned long timeout = jiffies + usecs_to_jiffies
+				(IDLE_TIMEOUT * adc_dev->channels);
+	step_en = get_adc_step_mask(adc_dev);
+	am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
+
+	/* Wait for ADC sequencer to complete sampling */
+	while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) {
+		if (time_after(jiffies, timeout))
+			return -EAGAIN;
+		}
+	map_val = chan->channel + TOTAL_CHANNELS;
 
 	/*
 	 * When the sub-system is first enabled,
@@ -121,32 +168,51 @@ static int tiadc_read_raw(struct iio_dev
 	 * Hence we need to flush out this data.
 	 */
 
+	for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
+		if (chan->channel == adc_dev->channel_line[i]) {
+			step = adc_dev->channel_step[i];
+			break;
+		}
+	}
+	if (WARN_ON_ONCE(step == UINT_MAX))
+		return -EINVAL;
+
 	fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
 	for (i = 0; i < fifo1count; i++) {
-		readx1 = tiadc_readl(adc_dev, REG_FIFO1);
-		if (i == chan->channel)
-			*val = readx1 & 0xfff;
+		read = tiadc_readl(adc_dev, REG_FIFO1);
+		stepid = read & FIFOREAD_CHNLID_MASK;
+		stepid = stepid >> 0x10;
+
+		if (stepid == map_val) {
+			read = read & FIFOREAD_DATA_MASK;
+			found = true;
+			*val = read;
+		}
 	}
-	tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
 
+	if (found == false)
+		return -EBUSY;
 	return IIO_VAL_INT;
 }
 
 static const struct iio_info tiadc_info = {
 	.read_raw = &tiadc_read_raw,
+	.driver_module = THIS_MODULE,
 };
 
 static int tiadc_probe(struct platform_device *pdev)
 {
 	struct iio_dev		*indio_dev;
 	struct tiadc_device	*adc_dev;
-	struct ti_tscadc_dev	*tscadc_dev = pdev->dev.platform_data;
-	struct mfd_tscadc_board	*pdata;
+	struct device_node	*node = pdev->dev.of_node;
+	struct property		*prop;
+	const __be32		*cur;
 	int			err;
+	u32			val;
+	int			channels = 0;
 
-	pdata = tscadc_dev->dev->platform_data;
-	if (!pdata || !pdata->adc_init) {
-		dev_err(&pdev->dev, "Could not find platform data\n");
+	if (!node) {
+		dev_err(&pdev->dev, "Could not find valid DT data.\n");
 		return -EINVAL;
 	}
 
@@ -158,8 +224,13 @@ static int tiadc_probe(struct platform_d
 	}
 	adc_dev = iio_priv(indio_dev);
 
-	adc_dev->mfd_tscadc = tscadc_dev;
-	adc_dev->channels = pdata->adc_init->adc_channels;
+	adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev);
+
+	of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
+		adc_dev->channel_line[channels] = val;
+		channels++;
+	}
+	adc_dev->channels = channels;
 
 	indio_dev->dev.parent = &pdev->dev;
 	indio_dev->name = dev_name(&pdev->dev);
@@ -191,10 +262,15 @@ err_ret:
 static int tiadc_remove(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct tiadc_device *adc_dev = iio_priv(indio_dev);
+	u32 step_en;
 
 	iio_device_unregister(indio_dev);
 	tiadc_channels_remove(indio_dev);
 
+	step_en = get_adc_step_mask(adc_dev);
+	am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en);
+
 	iio_device_free(indio_dev);
 
 	return 0;
@@ -205,9 +281,10 @@ static int tiadc_suspend(struct device *
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct tiadc_device *adc_dev = iio_priv(indio_dev);
-	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
+	struct ti_tscadc_dev *tscadc_dev;
 	unsigned int idle;
 
+	tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
 	if (!device_may_wakeup(tscadc_dev->dev)) {
 		idle = tiadc_readl(adc_dev, REG_CTRL);
 		idle &= ~(CNTRLREG_TSCSSENB);
@@ -243,16 +320,22 @@ static const struct dev_pm_ops tiadc_pm_
 #define TIADC_PM_OPS NULL
 #endif
 
+static const struct of_device_id ti_adc_dt_ids[] = {
+	{ .compatible = "ti,am3359-adc", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ti_adc_dt_ids);
+
 static struct platform_driver tiadc_driver = {
 	.driver = {
-		.name   = "tiadc",
+		.name   = "TI-am335x-adc",
 		.owner	= THIS_MODULE,
 		.pm	= TIADC_PM_OPS,
+		.of_match_table = of_match_ptr(ti_adc_dt_ids),
 	},
 	.probe	= tiadc_probe,
 	.remove	= tiadc_remove,
 };
-
 module_platform_driver(tiadc_driver);
 
 MODULE_DESCRIPTION("TI ADC controller driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/common/st_sensors/st_sensors_buffer.c linux-libre-3.11-rc7-gnu/drivers/iio/common/st_sensors/st_sensors_buffer.c
--- linux-libre-3.10-gnu/drivers/iio/common/st_sensors/st_sensors_buffer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/common/st_sensors/st_sensors_buffer.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,11 +24,20 @@
 
 int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf)
 {
+	u8 *addr;
 	int i, n = 0, len;
-	u8 addr[ST_SENSORS_NUMBER_DATA_CHANNELS];
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
+	unsigned int num_data_channels = sdata->num_data_channels;
+	unsigned int byte_for_channel =
+			indio_dev->channels[0].scan_type.storagebits >> 3;
 
-	for (i = 0; i < ST_SENSORS_NUMBER_DATA_CHANNELS; i++) {
+	addr = kmalloc(num_data_channels, GFP_KERNEL);
+	if (!addr) {
+		len = -ENOMEM;
+		goto st_sensors_get_buffer_element_error;
+	}
+
+	for (i = 0; i < num_data_channels; i++) {
 		if (test_bit(i, indio_dev->active_scan_mask)) {
 			addr[n] = indio_dev->channels[i].address;
 			n++;
@@ -37,52 +46,58 @@ int st_sensors_get_buffer_element(struct
 	switch (n) {
 	case 1:
 		len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
-			addr[0], ST_SENSORS_BYTE_FOR_CHANNEL, buf,
-			sdata->multiread_bit);
+			addr[0], byte_for_channel, buf, sdata->multiread_bit);
 		break;
 	case 2:
-		if ((addr[1] - addr[0]) == ST_SENSORS_BYTE_FOR_CHANNEL) {
+		if ((addr[1] - addr[0]) == byte_for_channel) {
 			len = sdata->tf->read_multiple_byte(&sdata->tb,
-					sdata->dev, addr[0],
-					ST_SENSORS_BYTE_FOR_CHANNEL*n,
-					buf, sdata->multiread_bit);
+				sdata->dev, addr[0], byte_for_channel * n,
+				buf, sdata->multiread_bit);
 		} else {
-			u8 rx_array[ST_SENSORS_BYTE_FOR_CHANNEL*
-				    ST_SENSORS_NUMBER_DATA_CHANNELS];
+			u8 *rx_array;
+			rx_array = kmalloc(byte_for_channel * num_data_channels,
+					   GFP_KERNEL);
+			if (!rx_array) {
+				len = -ENOMEM;
+				goto st_sensors_free_memory;
+			}
+
 			len = sdata->tf->read_multiple_byte(&sdata->tb,
 				sdata->dev, addr[0],
-				ST_SENSORS_BYTE_FOR_CHANNEL*
-				ST_SENSORS_NUMBER_DATA_CHANNELS,
+				byte_for_channel * num_data_channels,
 				rx_array, sdata->multiread_bit);
-			if (len < 0)
-				goto read_data_channels_error;
+			if (len < 0) {
+				kfree(rx_array);
+				goto st_sensors_free_memory;
+			}
 
-			for (i = 0; i < n * ST_SENSORS_NUMBER_DATA_CHANNELS;
-									i++) {
+			for (i = 0; i < n * num_data_channels; i++) {
 				if (i < n)
 					buf[i] = rx_array[i];
 				else
 					buf[i] = rx_array[n + i];
 			}
-			len = ST_SENSORS_BYTE_FOR_CHANNEL*n;
+			kfree(rx_array);
+			len = byte_for_channel * n;
 		}
 		break;
 	case 3:
 		len = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
-			addr[0], ST_SENSORS_BYTE_FOR_CHANNEL*
-			ST_SENSORS_NUMBER_DATA_CHANNELS,
+			addr[0], byte_for_channel * num_data_channels,
 			buf, sdata->multiread_bit);
 		break;
 	default:
 		len = -EINVAL;
-		goto read_data_channels_error;
+		goto st_sensors_free_memory;
 	}
-	if (len != ST_SENSORS_BYTE_FOR_CHANNEL*n) {
+	if (len != byte_for_channel * n) {
 		len = -EIO;
-		goto read_data_channels_error;
+		goto st_sensors_free_memory;
 	}
 
-read_data_channels_error:
+st_sensors_free_memory:
+	kfree(addr);
+st_sensors_get_buffer_element_error:
 	return len;
 }
 EXPORT_SYMBOL(st_sensors_get_buffer_element);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/common/st_sensors/st_sensors_core.c linux-libre-3.11-rc7-gnu/drivers/iio/common/st_sensors/st_sensors_core.c
--- linux-libre-3.10-gnu/drivers/iio/common/st_sensors/st_sensors_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/common/st_sensors/st_sensors_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,11 @@
 
 #define ST_SENSORS_WAI_ADDRESS		0x0f
 
+static inline u32 st_sensors_get_unaligned_le24(const u8 *p)
+{
+	return ((s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8);
+}
+
 static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
 						u8 reg_addr, u8 mask, u8 data)
 {
@@ -112,7 +117,8 @@ st_sensors_match_odr_error:
 	return ret;
 }
 
-static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
+static int st_sensors_set_fullscale(struct iio_dev *indio_dev,
+							unsigned int fs)
 {
 	int err, i = 0;
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
@@ -273,21 +279,33 @@ st_sensors_match_scale_error:
 EXPORT_SYMBOL(st_sensors_set_fullscale_by_gain);
 
 static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
-							u8 ch_addr, int *data)
+				struct iio_chan_spec const *ch, int *data)
 {
 	int err;
-	u8 outdata[ST_SENSORS_BYTE_FOR_CHANNEL];
+	u8 *outdata;
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
+	unsigned int byte_for_channel = ch->scan_type.storagebits >> 3;
+
+	outdata = kmalloc(byte_for_channel, GFP_KERNEL);
+	if (!outdata) {
+		err = -EINVAL;
+		goto st_sensors_read_axis_data_error;
+	}
 
 	err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
-				ch_addr, ST_SENSORS_BYTE_FOR_CHANNEL,
+				ch->address, byte_for_channel,
 				outdata, sdata->multiread_bit);
 	if (err < 0)
-		goto read_error;
+		goto st_sensors_free_memory;
 
-	*data = (s16)get_unaligned_le16(outdata);
+	if (byte_for_channel == 2)
+		*data = (s16)get_unaligned_le16(outdata);
+	else if (byte_for_channel == 3)
+		*data = (s32)st_sensors_get_unaligned_le24(outdata);
 
-read_error:
+st_sensors_free_memory:
+	kfree(outdata);
+st_sensors_read_axis_data_error:
 	return err;
 }
 
@@ -307,7 +325,7 @@ int st_sensors_read_info_raw(struct iio_
 			goto read_error;
 
 		msleep((sdata->sensor->bootime * 1000) / sdata->odr);
-		err = st_sensors_read_axis_data(indio_dev, ch->address, val);
+		err = st_sensors_read_axis_data(indio_dev, ch, val);
 		if (err < 0)
 			goto read_error;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/dac/ad7303.c linux-libre-3.11-rc7-gnu/drivers/iio/dac/ad7303.c
--- linux-libre-3.10-gnu/drivers/iio/dac/ad7303.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/dac/ad7303.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,317 @@
+/*
+ * AD7303 Digital to analog converters driver
+ *
+ * Copyright 2013 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#include <linux/platform_data/ad7303.h>
+
+#define AD7303_CFG_EXTERNAL_VREF BIT(15)
+#define AD7303_CFG_POWER_DOWN(ch) BIT(11 + (ch))
+#define AD7303_CFG_ADDR_OFFSET	10
+
+#define AD7303_CMD_UPDATE_DAC	(0x3 << 8)
+
+/**
+ * struct ad7303_state - driver instance specific data
+ * @spi:		the device for this driver instance
+ * @config:		cached config register value
+ * @dac_cache:		current DAC raw value (chip does not support readback)
+ * @data:		spi transfer buffer
+ */
+
+struct ad7303_state {
+	struct spi_device *spi;
+	uint16_t config;
+	uint8_t dac_cache[2];
+
+	struct regulator *vdd_reg;
+	struct regulator *vref_reg;
+
+	/*
+	 * DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+	__be16 data ____cacheline_aligned;
+};
+
+static int ad7303_write(struct ad7303_state *st, unsigned int chan,
+	uint8_t val)
+{
+	st->data = cpu_to_be16(AD7303_CMD_UPDATE_DAC |
+		(chan << AD7303_CFG_ADDR_OFFSET) |
+		st->config | val);
+
+	return spi_write(st->spi, &st->data, sizeof(st->data));
+}
+
+static ssize_t ad7303_read_dac_powerdown(struct iio_dev *indio_dev,
+	uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+{
+	struct ad7303_state *st = iio_priv(indio_dev);
+
+	return sprintf(buf, "%d\n", (bool)(st->config &
+		AD7303_CFG_POWER_DOWN(chan->channel)));
+}
+
+static ssize_t ad7303_write_dac_powerdown(struct iio_dev *indio_dev,
+	 uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
+	 size_t len)
+{
+	struct ad7303_state *st = iio_priv(indio_dev);
+	bool pwr_down;
+	int ret;
+
+	ret = strtobool(buf, &pwr_down);
+	if (ret)
+		return ret;
+
+	mutex_lock(&indio_dev->mlock);
+
+	if (pwr_down)
+		st->config |= AD7303_CFG_POWER_DOWN(chan->channel);
+	else
+		st->config &= ~AD7303_CFG_POWER_DOWN(chan->channel);
+
+	/* There is no noop cmd which allows us to only update the powerdown
+	 * mode, so just write one of the DAC channels again */
+	ad7303_write(st, chan->channel, st->dac_cache[chan->channel]);
+
+	mutex_unlock(&indio_dev->mlock);
+	return ret ? ret : len;
+}
+
+static int ad7303_get_vref(struct ad7303_state *st,
+	struct iio_chan_spec const *chan)
+{
+	int ret;
+
+	if (st->config & AD7303_CFG_EXTERNAL_VREF)
+		return regulator_get_voltage(st->vref_reg);
+
+	ret = regulator_get_voltage(st->vdd_reg);
+	if (ret < 0)
+		return ret;
+	return ret / 2;
+}
+
+static int ad7303_read_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int *val, int *val2, long info)
+{
+	struct ad7303_state *st = iio_priv(indio_dev);
+	int vref_uv;
+
+	switch (info) {
+	case IIO_CHAN_INFO_RAW:
+		*val = st->dac_cache[chan->channel];
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		vref_uv = ad7303_get_vref(st, chan);
+		if (vref_uv < 0)
+			return vref_uv;
+
+		*val = 2 * vref_uv / 1000;
+		*val2 = chan->scan_type.realbits;
+
+		return IIO_VAL_FRACTIONAL_LOG2;
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+static int ad7303_write_raw(struct iio_dev *indio_dev,
+	struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+	struct ad7303_state *st = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		if (val >= (1 << chan->scan_type.realbits) || val < 0)
+			return -EINVAL;
+
+		mutex_lock(&indio_dev->mlock);
+		ret = ad7303_write(st, chan->address, val);
+		if (ret == 0)
+			st->dac_cache[chan->channel] = val;
+		mutex_unlock(&indio_dev->mlock);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static const struct iio_info ad7303_info = {
+	.read_raw = ad7303_read_raw,
+	.write_raw = ad7303_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
+	{
+		.name = "powerdown",
+		.read = ad7303_read_dac_powerdown,
+		.write = ad7303_write_dac_powerdown,
+	},
+	{ },
+};
+
+#define AD7303_CHANNEL(chan) {					\
+	.type = IIO_VOLTAGE,					\
+	.indexed = 1,						\
+	.output = 1,						\
+	.channel = (chan),					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
+	.address = (chan),					\
+	.scan_type = {						\
+		.sign = 'u',					\
+		.realbits = '8',				\
+		.storagebits = '8',				\
+		.shift = '0',					\
+	},							\
+	.ext_info = ad7303_ext_info,				\
+}
+
+static const struct iio_chan_spec ad7303_channels[] = {
+	AD7303_CHANNEL(0),
+	AD7303_CHANNEL(1),
+};
+
+static int ad7303_probe(struct spi_device *spi)
+{
+	const struct spi_device_id *id = spi_get_device_id(spi);
+	struct iio_dev *indio_dev;
+	struct ad7303_state *st;
+	bool ext_ref;
+	int ret;
+
+	indio_dev = iio_device_alloc(sizeof(*st));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
+	spi_set_drvdata(spi, indio_dev);
+
+	st->spi = spi;
+
+	st->vdd_reg = regulator_get(&spi->dev, "Vdd");
+	if (IS_ERR(st->vdd_reg)) {
+		ret = PTR_ERR(st->vdd_reg);
+		goto err_free;
+	}
+
+	ret = regulator_enable(st->vdd_reg);
+	if (ret)
+		goto err_put_vdd_reg;
+
+	if (spi->dev.of_node) {
+		ext_ref = of_property_read_bool(spi->dev.of_node,
+				"REF-supply");
+	} else {
+		struct ad7303_platform_data *pdata = spi->dev.platform_data;
+		if (pdata && pdata->use_external_ref)
+			ext_ref = true;
+		else
+		    ext_ref = false;
+	}
+
+	if (ext_ref) {
+		st->vref_reg = regulator_get(&spi->dev, "REF");
+		if (IS_ERR(st->vref_reg)) {
+			ret = PTR_ERR(st->vref_reg);
+			goto err_disable_vdd_reg;
+		}
+
+		ret = regulator_enable(st->vref_reg);
+		if (ret)
+			goto err_put_vref_reg;
+
+		st->config |= AD7303_CFG_EXTERNAL_VREF;
+	}
+
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = id->name;
+	indio_dev->info = &ad7303_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = ad7303_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ad7303_channels);
+
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto err_disable_vref_reg;
+
+	return 0;
+
+err_disable_vref_reg:
+	if (st->vref_reg)
+		regulator_disable(st->vref_reg);
+err_put_vref_reg:
+	if (st->vref_reg)
+		regulator_put(st->vref_reg);
+err_disable_vdd_reg:
+	regulator_disable(st->vdd_reg);
+err_put_vdd_reg:
+	regulator_put(st->vdd_reg);
+err_free:
+	iio_device_free(indio_dev);
+
+	return ret;
+}
+
+static int ad7303_remove(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ad7303_state *st = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+
+	if (st->vref_reg) {
+		regulator_disable(st->vref_reg);
+		regulator_put(st->vref_reg);
+	}
+	regulator_disable(st->vdd_reg);
+	regulator_put(st->vdd_reg);
+
+	iio_device_free(indio_dev);
+
+	return 0;
+}
+
+static const struct spi_device_id ad7303_spi_ids[] = {
+	{ "ad7303", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(spi, ad7303_spi_ids);
+
+static struct spi_driver ad7303_driver = {
+	.driver = {
+		.name = "ad7303",
+		.owner = THIS_MODULE,
+	},
+	.probe = ad7303_probe,
+	.remove = ad7303_remove,
+	.id_table = ad7303_spi_ids,
+};
+module_spi_driver(ad7303_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Analog Devices AD7303 DAC driver");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/dac/Kconfig linux-libre-3.11-rc7-gnu/drivers/iio/dac/Kconfig
--- linux-libre-3.10-gnu/drivers/iio/dac/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/dac/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -130,6 +130,16 @@ config AD5686
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad5686.
 
+config AD7303
+	tristate "Analog Devices Analog Devices AD7303 DAC driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD7303 Digital to Analog
+	  Converters (DAC).
+
+	  To compile this driver as module choose M here: the module will be called
+	  ad7303.
+
 config MAX517
 	tristate "Maxim MAX517/518/519 DAC driver"
 	depends on I2C
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/dac/Makefile linux-libre-3.11-rc7-gnu/drivers/iio/dac/Makefile
--- linux-libre-3.10-gnu/drivers/iio/dac/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/dac/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -14,5 +14,6 @@ obj-$(CONFIG_AD5755) += ad5755.o
 obj-$(CONFIG_AD5764) += ad5764.o
 obj-$(CONFIG_AD5791) += ad5791.o
 obj-$(CONFIG_AD5686) += ad5686.o
+obj-$(CONFIG_AD7303) += ad7303.o
 obj-$(CONFIG_MAX517) += max517.o
 obj-$(CONFIG_MCP4725) += mcp4725.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/frequency/adf4350.c linux-libre-3.11-rc7-gnu/drivers/iio/frequency/adf4350.c
--- linux-libre-3.10-gnu/drivers/iio/frequency/adf4350.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/frequency/adf4350.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * ADF4350/ADF4351 SPI Wideband Synthesizer driver
  *
- * Copyright 2012 Analog Devices Inc.
+ * Copyright 2012-2013 Analog Devices Inc.
  *
  * Licensed under the GPL-2.
  */
@@ -17,6 +17,9 @@
 #include <linux/gcd.h>
 #include <linux/gpio.h>
 #include <asm/div64.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -33,6 +36,7 @@ struct adf4350_state {
 	struct spi_device		*spi;
 	struct regulator		*reg;
 	struct adf4350_platform_data	*pdata;
+	struct clk			*clk;
 	unsigned long			clkin;
 	unsigned long			chspc; /* Channel Spacing */
 	unsigned long			fpfd; /* Phase Frequency Detector */
@@ -43,7 +47,7 @@ struct adf4350_state {
 	unsigned			r4_rf_div_sel;
 	unsigned long			regs[6];
 	unsigned long			regs_hw[6];
-
+	unsigned long long		freq_req;
 	/*
 	 * DMA (thus cache coherency maintenance) requires the
 	 * transfer buffers to live in their own cache lines.
@@ -52,7 +56,6 @@ struct adf4350_state {
 };
 
 static struct adf4350_platform_data default_pdata = {
-	.clkin = 122880000,
 	.channel_spacing = 10000,
 	.r2_user_settings = ADF4350_REG2_PD_POLARITY_POS |
 			    ADF4350_REG2_CHARGE_PUMP_CURR_uA(2500),
@@ -235,6 +238,7 @@ static int adf4350_set_freq(struct adf43
 		ADF4350_REG4_MUTE_TILL_LOCK_EN));
 
 	st->regs[ADF4350_REG5] = ADF4350_REG5_LD_PIN_MODE_DIGITAL;
+	st->freq_req = freq;
 
 	return adf4350_sync_config(st);
 }
@@ -246,6 +250,7 @@ static ssize_t adf4350_write(struct iio_
 {
 	struct adf4350_state *st = iio_priv(indio_dev);
 	unsigned long long readin;
+	unsigned long tmp;
 	int ret;
 
 	ret = kstrtoull(buf, 10, &readin);
@@ -258,10 +263,23 @@ static ssize_t adf4350_write(struct iio_
 		ret = adf4350_set_freq(st, readin);
 		break;
 	case ADF4350_FREQ_REFIN:
-		if (readin > ADF4350_MAX_FREQ_REFIN)
+		if (readin > ADF4350_MAX_FREQ_REFIN) {
 			ret = -EINVAL;
-		else
-			st->clkin = readin;
+			break;
+		}
+
+		if (st->clk) {
+			tmp = clk_round_rate(st->clk, readin);
+			if (tmp != readin) {
+				ret = -EINVAL;
+				break;
+			}
+			ret = clk_set_rate(st->clk, tmp);
+			if (ret < 0)
+				break;
+		}
+		st->clkin = readin;
+		ret = adf4350_set_freq(st, st->freq_req);
 		break;
 	case ADF4350_FREQ_RESOLUTION:
 		if (readin == 0)
@@ -308,6 +326,9 @@ static ssize_t adf4350_read(struct iio_d
 			}
 		break;
 	case ADF4350_FREQ_REFIN:
+		if (st->clk)
+			st->clkin = clk_get_rate(st->clk);
+
 		val = st->clkin;
 		break;
 	case ADF4350_FREQ_RESOLUTION:
@@ -318,6 +339,7 @@ static ssize_t adf4350_read(struct iio_d
 		break;
 	default:
 		ret = -EINVAL;
+		val = 0;
 	}
 	mutex_unlock(&indio_dev->mlock);
 
@@ -355,19 +377,153 @@ static const struct iio_info adf4350_inf
 	.driver_module = THIS_MODULE,
 };
 
+#ifdef CONFIG_OF
+static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct adf4350_platform_data *pdata;
+	unsigned int tmp;
+	int ret;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "could not allocate memory for platform data\n");
+		return NULL;
+	}
+
+	strncpy(&pdata->name[0], np->name, SPI_NAME_SIZE - 1);
+
+	tmp = 10000;
+	of_property_read_u32(np, "adi,channel-spacing", &tmp);
+	pdata->channel_spacing = tmp;
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,power-up-frequency", &tmp);
+	pdata->power_up_frequency = tmp;
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,reference-div-factor", &tmp);
+	pdata->ref_div_factor = tmp;
+
+	ret = of_get_gpio(np, 0);
+	if (ret < 0)
+		pdata->gpio_lock_detect = -1;
+	else
+		pdata->gpio_lock_detect = ret;
+
+	pdata->ref_doubler_en = of_property_read_bool(np,
+			"adi,reference-doubler-enable");
+	pdata->ref_div2_en = of_property_read_bool(np,
+			"adi,reference-div2-enable");
+
+	/* r2_user_settings */
+	pdata->r2_user_settings = of_property_read_bool(np,
+			"adi,phase-detector-polarity-positive-enable") ?
+			ADF4350_REG2_PD_POLARITY_POS : 0;
+	pdata->r2_user_settings |= of_property_read_bool(np,
+			"adi,lock-detect-precision-6ns-enable") ?
+			ADF4350_REG2_LDP_6ns : 0;
+	pdata->r2_user_settings |= of_property_read_bool(np,
+			"adi,lock-detect-function-integer-n-enable") ?
+			ADF4350_REG2_LDF_INT_N : 0;
+
+	tmp = 2500;
+	of_property_read_u32(np, "adi,charge-pump-current", &tmp);
+	pdata->r2_user_settings |= ADF4350_REG2_CHARGE_PUMP_CURR_uA(tmp);
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,muxout-select", &tmp);
+	pdata->r2_user_settings |= ADF4350_REG2_MUXOUT(tmp);
+
+	pdata->r2_user_settings |= of_property_read_bool(np,
+			"adi,low-spur-mode-enable") ?
+			ADF4350_REG2_NOISE_MODE(0x3) : 0;
+
+	/* r3_user_settings */
+
+	pdata->r3_user_settings = of_property_read_bool(np,
+			"adi,cycle-slip-reduction-enable") ?
+			ADF4350_REG3_12BIT_CSR_EN : 0;
+	pdata->r3_user_settings |= of_property_read_bool(np,
+			"adi,charge-cancellation-enable") ?
+			ADF4351_REG3_CHARGE_CANCELLATION_EN : 0;
+
+	pdata->r3_user_settings |= of_property_read_bool(np,
+			"adi,anti-backlash-3ns-enable") ?
+			ADF4351_REG3_ANTI_BACKLASH_3ns_EN : 0;
+	pdata->r3_user_settings |= of_property_read_bool(np,
+			"adi,band-select-clock-mode-high-enable") ?
+			ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH : 0;
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,12bit-clk-divider", &tmp);
+	pdata->r3_user_settings |= ADF4350_REG3_12BIT_CLKDIV(tmp);
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,clk-divider-mode", &tmp);
+	pdata->r3_user_settings |= ADF4350_REG3_12BIT_CLKDIV_MODE(tmp);
+
+	/* r4_user_settings */
+
+	pdata->r4_user_settings = of_property_read_bool(np,
+			"adi,aux-output-enable") ?
+			ADF4350_REG4_AUX_OUTPUT_EN : 0;
+	pdata->r4_user_settings |= of_property_read_bool(np,
+			"adi,aux-output-fundamental-enable") ?
+			ADF4350_REG4_AUX_OUTPUT_FUND : 0;
+	pdata->r4_user_settings |= of_property_read_bool(np,
+			"adi,mute-till-lock-enable") ?
+			ADF4350_REG4_MUTE_TILL_LOCK_EN : 0;
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,output-power", &tmp);
+	pdata->r4_user_settings |= ADF4350_REG4_OUTPUT_PWR(tmp);
+
+	tmp = 0;
+	of_property_read_u32(np, "adi,aux-output-power", &tmp);
+	pdata->r4_user_settings |= ADF4350_REG4_AUX_OUTPUT_PWR(tmp);
+
+	return pdata;
+}
+#else
+static
+struct adf4350_platform_data *adf4350_parse_dt(struct device *dev)
+{
+	return NULL;
+}
+#endif
+
 static int adf4350_probe(struct spi_device *spi)
 {
-	struct adf4350_platform_data *pdata = spi->dev.platform_data;
+	struct adf4350_platform_data *pdata;
 	struct iio_dev *indio_dev;
 	struct adf4350_state *st;
+	struct clk *clk = NULL;
 	int ret;
 
+	if (spi->dev.of_node) {
+		pdata = adf4350_parse_dt(&spi->dev);
+		if (pdata == NULL)
+			return -EINVAL;
+	} else {
+		pdata = spi->dev.platform_data;
+	}
+
 	if (!pdata) {
 		dev_warn(&spi->dev, "no platform data? using default\n");
-
 		pdata = &default_pdata;
 	}
 
+	if (!pdata->clkin) {
+		clk = clk_get(&spi->dev, "clkin");
+		if (IS_ERR(clk))
+			return -EPROBE_DEFER;
+
+		ret = clk_prepare_enable(clk);
+		if (ret < 0)
+			return ret;
+	}
+
 	indio_dev = iio_device_alloc(sizeof(*st));
 	if (indio_dev == NULL)
 		return -ENOMEM;
@@ -395,7 +551,12 @@ static int adf4350_probe(struct spi_devi
 	indio_dev->num_channels = 1;
 
 	st->chspc = pdata->channel_spacing;
-	st->clkin = pdata->clkin;
+	if (clk) {
+		st->clk = clk;
+		st->clkin = clk_get_rate(clk);
+	} else {
+		st->clkin = pdata->clkin;
+	}
 
 	st->min_out_freq = spi_get_device_id(spi)->driver_data == 4351 ?
 		ADF4351_MIN_OUT_FREQ : ADF4350_MIN_OUT_FREQ;
@@ -435,6 +596,8 @@ error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
 
+	if (clk)
+		clk_disable_unprepare(clk);
 	iio_device_free(indio_dev);
 
 	return ret;
@@ -451,6 +614,9 @@ static int adf4350_remove(struct spi_dev
 
 	iio_device_unregister(indio_dev);
 
+	if (st->clk)
+		clk_disable_unprepare(st->clk);
+
 	if (!IS_ERR(reg)) {
 		regulator_disable(reg);
 		regulator_put(reg);
@@ -481,6 +647,6 @@ static struct spi_driver adf4350_driver
 };
 module_spi_driver(adf4350_driver);
 
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices ADF4350/ADF4351 PLL");
 MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/gyro/adis16130.c linux-libre-3.11-rc7-gnu/drivers/iio/gyro/adis16130.c
--- linux-libre-3.10-gnu/drivers/iio/gyro/adis16130.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/gyro/adis16130.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,207 @@
+/*
+ * ADIS16130 Digital Output, High Precision Angular Rate Sensor driver
+ *
+ * Copyright 2010 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/mutex.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+
+#define ADIS16130_CON         0x0
+#define ADIS16130_CON_RD      (1 << 6)
+#define ADIS16130_IOP         0x1
+
+/* 1 = data-ready signal low when unread data on all channels; */
+#define ADIS16130_IOP_ALL_RDY (1 << 3)
+#define ADIS16130_IOP_SYNC    (1 << 0) /* 1 = synchronization enabled */
+#define ADIS16130_RATEDATA    0x8 /* Gyroscope output, rate of rotation */
+#define ADIS16130_TEMPDATA    0xA /* Temperature output */
+#define ADIS16130_RATECS      0x28 /* Gyroscope channel setup */
+#define ADIS16130_RATECS_EN   (1 << 3) /* 1 = channel enable; */
+#define ADIS16130_TEMPCS      0x2A /* Temperature channel setup */
+#define ADIS16130_TEMPCS_EN   (1 << 3)
+#define ADIS16130_RATECONV    0x30
+#define ADIS16130_TEMPCONV    0x32
+#define ADIS16130_MODE        0x38
+#define ADIS16130_MODE_24BIT  (1 << 1) /* 1 = 24-bit resolution; */
+
+/**
+ * struct adis16130_state - device instance specific data
+ * @us:			actual spi_device to write data
+ * @buf_lock:		mutex to protect tx and rx
+ * @buf:		unified tx/rx buffer
+ **/
+struct adis16130_state {
+	struct spi_device		*us;
+	struct mutex			buf_lock;
+	u8				buf[4] ____cacheline_aligned;
+};
+
+static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
+{
+	int ret;
+	struct adis16130_state *st = iio_priv(indio_dev);
+	struct spi_message msg;
+	struct spi_transfer xfer = {
+		.tx_buf = st->buf,
+		.rx_buf = st->buf,
+		.len = 4,
+	};
+
+	mutex_lock(&st->buf_lock);
+
+	st->buf[0] = ADIS16130_CON_RD | reg_addr;
+	st->buf[1] = st->buf[2] = st->buf[3] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->us, &msg);
+
+	if (ret == 0)
+		*val = (st->buf[1] << 16) | (st->buf[2] << 8) | st->buf[3];
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+static int adis16130_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	u32 temp;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		/* Take the iio_dev status lock */
+		mutex_lock(&indio_dev->mlock);
+		ret = adis16130_spi_read(indio_dev, chan->address, &temp);
+		mutex_unlock(&indio_dev->mlock);
+		if (ret)
+			return ret;
+		*val = temp;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_ANGL_VEL:
+			/* 0 degree = 838860, 250 degree = 14260608 */
+			*val = 250;
+			*val2 = 336440817; /* RAD_TO_DEGREE(14260608 - 8388608) */
+			return IIO_VAL_FRACTIONAL;
+		case IIO_TEMP:
+			/* 0C = 8036283, 105C = 9516048 */
+			*val = 105000;
+			*val2 = 9516048 - 8036283;
+			return IIO_VAL_FRACTIONAL;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case IIO_CHAN_INFO_OFFSET:
+		switch (chan->type) {
+		case IIO_ANGL_VEL:
+			*val = -8388608;
+			return IIO_VAL_INT;
+		case IIO_TEMP:
+			*val = -8036283;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static const struct iio_chan_spec adis16130_channels[] = {
+	{
+		.type = IIO_ANGL_VEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE) |
+			BIT(IIO_CHAN_INFO_OFFSET),
+		.address = ADIS16130_RATEDATA,
+	}, {
+		.type = IIO_TEMP,
+		.indexed = 1,
+		.channel = 0,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE) |
+			BIT(IIO_CHAN_INFO_OFFSET),
+		.address = ADIS16130_TEMPDATA,
+	}
+};
+
+static const struct iio_info adis16130_info = {
+	.read_raw = &adis16130_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static int adis16130_probe(struct spi_device *spi)
+{
+	int ret;
+	struct adis16130_state *st;
+	struct iio_dev *indio_dev;
+
+	/* setup the industrialio driver allocated elements */
+	indio_dev = iio_device_alloc(sizeof(*st));
+	if (indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	st = iio_priv(indio_dev);
+	/* this is only used for removal purposes */
+	spi_set_drvdata(spi, indio_dev);
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	indio_dev->name = spi->dev.driver->name;
+	indio_dev->channels = adis16130_channels;
+	indio_dev->num_channels = ARRAY_SIZE(adis16130_channels);
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->info = &adis16130_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	return 0;
+
+error_free_dev:
+	iio_device_free(indio_dev);
+
+error_ret:
+	return ret;
+}
+
+static int adis16130_remove(struct spi_device *spi)
+{
+	iio_device_unregister(spi_get_drvdata(spi));
+	iio_device_free(spi_get_drvdata(spi));
+
+	return 0;
+}
+
+static struct spi_driver adis16130_driver = {
+	.driver = {
+		.name = "adis16130",
+		.owner = THIS_MODULE,
+	},
+	.probe = adis16130_probe,
+	.remove = adis16130_remove,
+};
+module_spi_driver(adis16130_driver);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_DESCRIPTION("Analog Devices ADIS16130 High Precision Angular Rate");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:adis16130");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/gyro/Kconfig linux-libre-3.11-rc7-gnu/drivers/iio/gyro/Kconfig
--- linux-libre-3.10-gnu/drivers/iio/gyro/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/gyro/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,13 @@ config ADIS16080
 	  Say yes here to build support for Analog Devices ADIS16080, ADIS16100 Yaw
 	  Rate Gyroscope with SPI.
 
+config ADIS16130
+	tristate "Analog Devices ADIS16130 High Precision Angular Rate Sensor driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices ADIS16130 High Precision
+	  Angular Rate Sensor driver.
+
 config ADIS16136
 	tristate "Analog devices ADIS16136 and similar gyroscopes driver"
 	depends on SPI_MASTER
@@ -47,7 +54,6 @@ config IIO_ST_GYRO_3AXIS
 	select IIO_ST_GYRO_I2C_3AXIS if (I2C)
 	select IIO_ST_GYRO_SPI_3AXIS if (SPI_MASTER)
 	select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
-	select IIO_ST_GYRO_BUFFER if (IIO_TRIGGERED_BUFFER)
 	help
 	  Say yes here to build support for STMicroelectronics gyroscopes:
 	  L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/gyro/Makefile linux-libre-3.11-rc7-gnu/drivers/iio/gyro/Makefile
--- linux-libre-3.10-gnu/drivers/iio/gyro/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/gyro/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_ADIS16080) += adis16080.o
+obj-$(CONFIG_ADIS16130) += adis16130.o
 obj-$(CONFIG_ADIS16136) += adis16136.o
 obj-$(CONFIG_ADXRS450) += adxrs450.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/gyro/st_gyro_core.c linux-libre-3.11-rc7-gnu/drivers/iio/gyro/st_gyro_core.c
--- linux-libre-3.10-gnu/drivers/iio/gyro/st_gyro_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/gyro/st_gyro_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,8 @@
 #include <linux/iio/common/st_sensors.h>
 #include "st_gyro.h"
 
+#define ST_GYRO_NUMBER_DATA_CHANNELS		3
+
 /* DEFAULT VALUE FOR SENSORS */
 #define ST_GYRO_DEFAULT_OUT_X_L_ADDR		0x28
 #define ST_GYRO_DEFAULT_OUT_Y_L_ADDR		0x2a
@@ -86,15 +88,18 @@
 #define ST_GYRO_2_MULTIREAD_BIT			true
 
 static const struct iio_chan_spec st_gyro_16bit_channels[] = {
-	ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_X,
-		IIO_MOD_X, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS,
-						ST_GYRO_DEFAULT_OUT_X_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_Y,
-		IIO_MOD_Y, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS,
-						ST_GYRO_DEFAULT_OUT_Y_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL, ST_SENSORS_SCAN_Z,
-		IIO_MOD_Z, IIO_LE, ST_SENSORS_DEFAULT_16_REALBITS,
-						ST_GYRO_DEFAULT_OUT_Z_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
+			ST_GYRO_DEFAULT_OUT_X_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
+			ST_GYRO_DEFAULT_OUT_Y_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_ANGL_VEL,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
+			ST_GYRO_DEFAULT_OUT_Z_L_ADDR),
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
@@ -310,6 +315,7 @@ int st_gyro_common_probe(struct iio_dev
 	if (err < 0)
 		goto st_gyro_common_probe_error;
 
+	gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
 	gdata->multiread_bit = gdata->sensor->multi_read_bit;
 	indio_dev->channels = gdata->sensor->ch;
 	indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/industrialio-buffer.c linux-libre-3.11-rc7-gnu/drivers/iio/industrialio-buffer.c
--- linux-libre-3.10-gnu/drivers/iio/industrialio-buffer.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/industrialio-buffer.c	2013-08-25 20:43:22.000000000 -0400
@@ -542,8 +542,7 @@ int iio_update_buffers(struct iio_dev *i
 		ret = indio_dev->setup_ops->preenable(indio_dev);
 		if (ret) {
 			printk(KERN_ERR
-			       "Buffer not started:"
-			       "buffer preenable failed\n");
+			       "Buffer not started: buffer preenable failed (%d)\n", ret);
 			goto error_remove_inserted;
 		}
 	}
@@ -556,8 +555,7 @@ int iio_update_buffers(struct iio_dev *i
 			ret = buffer->access->request_update(buffer);
 			if (ret) {
 				printk(KERN_INFO
-				       "Buffer not started:"
-				       "buffer parameter update failed\n");
+				       "Buffer not started: buffer parameter update failed (%d)\n", ret);
 				goto error_run_postdisable;
 			}
 		}
@@ -566,7 +564,7 @@ int iio_update_buffers(struct iio_dev *i
 			->update_scan_mode(indio_dev,
 					   indio_dev->active_scan_mask);
 		if (ret < 0) {
-			printk(KERN_INFO "update scan mode failed\n");
+			printk(KERN_INFO "Buffer not started: update scan mode failed (%d)\n", ret);
 			goto error_run_postdisable;
 		}
 	}
@@ -590,7 +588,7 @@ int iio_update_buffers(struct iio_dev *i
 		ret = indio_dev->setup_ops->postenable(indio_dev);
 		if (ret) {
 			printk(KERN_INFO
-			       "Buffer not started: postenable failed\n");
+			       "Buffer not started: postenable failed (%d)\n", ret);
 			indio_dev->currentmode = INDIO_DIRECT_MODE;
 			if (indio_dev->setup_ops->postdisable)
 				indio_dev->setup_ops->postdisable(indio_dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/industrialio-trigger.c linux-libre-3.11-rc7-gnu/drivers/iio/industrialio-trigger.c
--- linux-libre-3.10-gnu/drivers/iio/industrialio-trigger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/industrialio-trigger.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,7 +104,7 @@ void iio_trigger_unregister(struct iio_t
 
 	ida_simple_remove(&iio_trigger_ida, trig_info->id);
 	/* Possible issue in here */
-	device_unregister(&trig_info->dev);
+	device_del(&trig_info->dev);
 }
 EXPORT_SYMBOL(iio_trigger_unregister);
 
@@ -127,12 +127,17 @@ static struct iio_trigger *iio_trigger_f
 void iio_trigger_poll(struct iio_trigger *trig, s64 time)
 {
 	int i;
-	if (!trig->use_count)
-		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
-			if (trig->subirqs[i].enabled) {
-				trig->use_count++;
+
+	if (!atomic_read(&trig->use_count)) {
+		atomic_set(&trig->use_count, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
+			if (trig->subirqs[i].enabled)
 				generic_handle_irq(trig->subirq_base + i);
-			}
+			else
+				iio_trigger_notify_done(trig);
+		}
+	}
 }
 EXPORT_SYMBOL(iio_trigger_poll);
 
@@ -146,19 +151,24 @@ EXPORT_SYMBOL(iio_trigger_generic_data_r
 void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time)
 {
 	int i;
-	if (!trig->use_count)
-		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
-			if (trig->subirqs[i].enabled) {
-				trig->use_count++;
+
+	if (!atomic_read(&trig->use_count)) {
+		atomic_set(&trig->use_count, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
+			if (trig->subirqs[i].enabled)
 				handle_nested_irq(trig->subirq_base + i);
-			}
+			else
+				iio_trigger_notify_done(trig);
+		}
+	}
 }
 EXPORT_SYMBOL(iio_trigger_poll_chained);
 
 void iio_trigger_notify_done(struct iio_trigger *trig)
 {
-	trig->use_count--;
-	if (trig->use_count == 0 && trig->ops && trig->ops->try_reenable)
+	if (atomic_dec_and_test(&trig->use_count) && trig->ops &&
+		trig->ops->try_reenable)
 		if (trig->ops->try_reenable(trig))
 			/* Missed an interrupt so launch new poll now */
 			iio_trigger_poll(trig, 0);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/inkern.c linux-libre-3.11-rc7-gnu/drivers/iio/inkern.c
--- linux-libre-3.10-gnu/drivers/iio/inkern.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/inkern.c	2013-08-25 20:43:22.000000000 -0400
@@ -451,7 +451,7 @@ static int iio_convert_raw_to_processed_
 	int ret;
 
 	ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_OFFSET);
-	if (ret == 0)
+	if (ret >= 0)
 		raw64 += offset;
 
 	scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/Kconfig linux-libre-3.11-rc7-gnu/drivers/iio/Kconfig
--- linux-libre-3.10-gnu/drivers/iio/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -70,5 +70,9 @@ source "drivers/iio/gyro/Kconfig"
 source "drivers/iio/imu/Kconfig"
 source "drivers/iio/light/Kconfig"
 source "drivers/iio/magnetometer/Kconfig"
+if IIO_TRIGGER
+   source "drivers/iio/trigger/Kconfig"
+endif #IIO_TRIGGER
+source "drivers/iio/pressure/Kconfig"
 
 endif # IIO
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/light/adjd_s311.c linux-libre-3.11-rc7-gnu/drivers/iio/light/adjd_s311.c
--- linux-libre-3.10-gnu/drivers/iio/light/adjd_s311.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/light/adjd_s311.c	2013-08-25 20:43:22.000000000 -0400
@@ -232,7 +232,8 @@ static int adjd_s311_read_raw(struct iio
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
-		ret = adjd_s311_read_data(indio_dev, chan->address, val);
+		ret = adjd_s311_read_data(indio_dev,
+			ADJD_S311_DATA_REG(chan->address), val);
 		if (ret < 0)
 			return ret;
 		return IIO_VAL_INT;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/light/hid-sensor-als.c linux-libre-3.11-rc7-gnu/drivers/iio/light/hid-sensor-als.c
--- linux-libre-3.10-gnu/drivers/iio/light/hid-sensor-als.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/light/hid-sensor-als.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,7 @@
 #include "../common/hid-sensors/hid-sensor-trigger.h"
 
 /*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Accelerometer-3D: 0x200041*/
+/*Usage ID from spec for Ambiant-Light: 0x200041*/
 #define DRIVER_NAME "HID-SENSOR-200041"
 
 #define CHANNEL_SCAN_INDEX_ILLUM 0
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/magnetometer/ak8975.c linux-libre-3.11-rc7-gnu/drivers/iio/magnetometer/ak8975.c
--- linux-libre-3.10-gnu/drivers/iio/magnetometer/ak8975.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/magnetometer/ak8975.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,11 +24,13 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/interrupt.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
-
+#include <linux/bitops.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -82,6 +84,7 @@
  */
 #define AK8975_MAX_CONVERSION_TIMEOUT	500
 #define AK8975_CONVERSION_DONE_POLL_TIME 10
+#define AK8975_DATA_READY_TIMEOUT	((100*HZ)/1000)
 
 /*
  * Per-instance context data for the device.
@@ -94,6 +97,9 @@ struct ak8975_data {
 	long			raw_to_gauss[3];
 	u8			reg_cache[AK8975_MAX_REGS];
 	int			eoc_gpio;
+	int			eoc_irq;
+	wait_queue_head_t	data_ready_queue;
+	unsigned long		flags;
 };
 
 static const int ak8975_index_to_reg[] = {
@@ -123,6 +129,51 @@ static int ak8975_write_data(struct i2c_
 }
 
 /*
+ * Handle data ready irq
+ */
+static irqreturn_t ak8975_irq_handler(int irq, void *data)
+{
+	struct ak8975_data *ak8975 = data;
+
+	set_bit(0, &ak8975->flags);
+	wake_up(&ak8975->data_ready_queue);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Install data ready interrupt handler
+ */
+static int ak8975_setup_irq(struct ak8975_data *data)
+{
+	struct i2c_client *client = data->client;
+	int rc;
+	int irq;
+
+	if (client->irq)
+		irq = client->irq;
+	else
+		irq = gpio_to_irq(data->eoc_gpio);
+
+	rc = request_irq(irq, ak8975_irq_handler,
+			 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+			 dev_name(&client->dev), data);
+	if (rc < 0) {
+		dev_err(&client->dev,
+			"irq %d request failed, (gpio %d): %d\n",
+			irq, data->eoc_gpio, rc);
+		return rc;
+	}
+
+	init_waitqueue_head(&data->data_ready_queue);
+	clear_bit(0, &data->flags);
+	data->eoc_irq = irq;
+
+	return rc;
+}
+
+
+/*
  * Perform some start-of-day setup, including reading the asa calibration
  * values and caching them.
  */
@@ -170,6 +221,16 @@ static int ak8975_setup(struct i2c_clien
 				AK8975_REG_CNTL_MODE_POWER_DOWN,
 				AK8975_REG_CNTL_MODE_MASK,
 				AK8975_REG_CNTL_MODE_SHIFT);
+
+	if (data->eoc_gpio > 0 || client->irq) {
+		ret = ak8975_setup_irq(data);
+		if (ret < 0) {
+			dev_err(&client->dev,
+				"Error setting data ready interrupt\n");
+			return ret;
+		}
+	}
+
 	if (ret < 0) {
 		dev_err(&client->dev, "Error in setting power-down mode\n");
 		return ret;
@@ -266,9 +327,23 @@ static int wait_conversion_complete_poll
 		dev_err(&client->dev, "Conversion timeout happened\n");
 		return -EINVAL;
 	}
+
 	return read_status;
 }
 
+/* Returns 0 if the end of conversion interrupt occured or -ETIME otherwise */
+static int wait_conversion_complete_interrupt(struct ak8975_data *data)
+{
+	int ret;
+
+	ret = wait_event_timeout(data->data_ready_queue,
+				 test_bit(0, &data->flags),
+				 AK8975_DATA_READY_TIMEOUT);
+	clear_bit(0, &data->flags);
+
+	return ret > 0 ? 0 : -ETIME;
+}
+
 /*
  * Emits the raw flux value for the x, y, or z axis.
  */
@@ -294,13 +369,16 @@ static int ak8975_read_axis(struct iio_d
 	}
 
 	/* Wait for the conversion to complete. */
-	if (gpio_is_valid(data->eoc_gpio))
+	if (data->eoc_irq)
+		ret = wait_conversion_complete_interrupt(data);
+	else if (gpio_is_valid(data->eoc_gpio))
 		ret = wait_conversion_complete_gpio(data);
 	else
 		ret = wait_conversion_complete_polled(data);
 	if (ret < 0)
 		goto exit;
 
+	/* This will be executed only for non-interrupt based waiting case */
 	if (ret & AK8975_REG_ST1_DRDY_MASK) {
 		ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2);
 		if (ret < 0) {
@@ -384,10 +462,15 @@ static int ak8975_probe(struct i2c_clien
 	int err;
 
 	/* Grab and set up the supplied GPIO. */
-	if (client->dev.platform_data == NULL)
-		eoc_gpio = -1;
-	else
+	if (client->dev.platform_data)
 		eoc_gpio = *(int *)(client->dev.platform_data);
+	else if (client->dev.of_node)
+		eoc_gpio = of_get_gpio(client->dev.of_node, 0);
+	else
+		eoc_gpio = -1;
+
+	if (eoc_gpio == -EPROBE_DEFER)
+		return -EPROBE_DEFER;
 
 	/* We may not have a GPIO based IRQ to scan, that is fine, we will
 	   poll if so */
@@ -409,6 +492,11 @@ static int ak8975_probe(struct i2c_clien
 	}
 	data = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
+
+	data->client = client;
+	data->eoc_gpio = eoc_gpio;
+	data->eoc_irq = 0;
+
 	/* Perform some basic start-of-day setup of the device. */
 	err = ak8975_setup(client);
 	if (err < 0) {
@@ -433,6 +521,8 @@ static int ak8975_probe(struct i2c_clien
 
 exit_free_iio:
 	iio_device_free(indio_dev);
+	if (data->eoc_irq)
+		free_irq(data->eoc_irq, data);
 exit_gpio:
 	if (gpio_is_valid(eoc_gpio))
 		gpio_free(eoc_gpio);
@@ -447,6 +537,9 @@ static int ak8975_remove(struct i2c_clie
 
 	iio_device_unregister(indio_dev);
 
+	if (data->eoc_irq)
+		free_irq(data->eoc_irq, data);
+
 	if (gpio_is_valid(data->eoc_gpio))
 		gpio_free(data->eoc_gpio);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/magnetometer/Kconfig linux-libre-3.11-rc7-gnu/drivers/iio/magnetometer/Kconfig
--- linux-libre-3.10-gnu/drivers/iio/magnetometer/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/magnetometer/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@ config IIO_ST_MAGN_3AXIS
 	select IIO_ST_MAGN_I2C_3AXIS if (I2C)
 	select IIO_ST_MAGN_SPI_3AXIS if (SPI_MASTER)
 	select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
-	select IIO_ST_MAGN_BUFFER if (IIO_TRIGGERED_BUFFER)
 	help
 	  Say yes here to build support for STMicroelectronics magnetometers:
 	  LSM303DLHC, LSM303DLM, LIS3MDL.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/magnetometer/st_magn_core.c linux-libre-3.11-rc7-gnu/drivers/iio/magnetometer/st_magn_core.c
--- linux-libre-3.10-gnu/drivers/iio/magnetometer/st_magn_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/magnetometer/st_magn_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,8 @@
 #include <linux/iio/common/st_sensors.h>
 #include "st_magn.h"
 
+#define ST_MAGN_NUMBER_DATA_CHANNELS		3
+
 /* DEFAULT VALUE FOR SENSORS */
 #define ST_MAGN_DEFAULT_OUT_X_L_ADDR		0X04
 #define ST_MAGN_DEFAULT_OUT_Y_L_ADDR		0X08
@@ -113,22 +115,34 @@
 #define ST_MAGN_2_OUT_Z_L_ADDR			0x2c
 
 static const struct iio_chan_spec st_magn_16bit_channels[] = {
-	ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
-		ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_X_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
-		ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Y_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
-		ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Z_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
+			ST_MAGN_DEFAULT_OUT_X_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
+			ST_MAGN_DEFAULT_OUT_Y_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
+			ST_MAGN_DEFAULT_OUT_Z_L_ADDR),
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
 static const struct iio_chan_spec st_magn_2_16bit_channels[] = {
-	ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
-		ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_X_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
-		ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Y_L_ADDR),
-	ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
-		ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Z_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
+			ST_MAGN_2_OUT_X_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
+			ST_MAGN_2_OUT_Y_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
+			ST_MAGN_2_OUT_Z_L_ADDR),
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 
@@ -344,6 +358,7 @@ int st_magn_common_probe(struct iio_dev
 	if (err < 0)
 		goto st_magn_common_probe_error;
 
+	mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS;
 	mdata->multiread_bit = mdata->sensor->multi_read_bit;
 	indio_dev->channels = mdata->sensor->ch;
 	indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/Makefile linux-libre-3.11-rc7-gnu/drivers/iio/Makefile
--- linux-libre-3.10-gnu/drivers/iio/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iio/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -21,3 +21,5 @@ obj-y += frequency/
 obj-y += imu/
 obj-y += light/
 obj-y += magnetometer/
+obj-y += trigger/
+obj-y += pressure/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/pressure/Kconfig linux-libre-3.11-rc7-gnu/drivers/iio/pressure/Kconfig
--- linux-libre-3.10-gnu/drivers/iio/pressure/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/pressure/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,35 @@
+#
+# Pressure drivers
+#
+menu "Pressure Sensors"
+
+config IIO_ST_PRESS
+	tristate "STMicroelectronics pressures Driver"
+	depends on (I2C || SPI_MASTER) && SYSFS
+	select IIO_ST_SENSORS_CORE
+	select IIO_ST_PRESS_I2C if (I2C)
+	select IIO_ST_PRESS_SPI if (SPI_MASTER)
+	select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
+	help
+	  Say yes here to build support for STMicroelectronics pressures:
+	  LPS331AP.
+
+	  This driver can also be built as a module. If so, will be created
+	  these modules:
+	  - st_pressure (core functions for the driver [it is mandatory]);
+	  - st_pressure_i2c (necessary for the I2C devices [optional*]);
+	  - st_pressure_spi (necessary for the SPI devices [optional*]);
+
+	  (*) one of these is necessary to do something.
+
+config IIO_ST_PRESS_I2C
+	tristate
+	depends on IIO_ST_PRESS
+	depends on IIO_ST_SENSORS_I2C
+
+config IIO_ST_PRESS_SPI
+	tristate
+	depends on IIO_ST_PRESS
+	depends on IIO_ST_SENSORS_SPI
+
+endmenu
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/pressure/Makefile linux-libre-3.11-rc7-gnu/drivers/iio/pressure/Makefile
--- linux-libre-3.10-gnu/drivers/iio/pressure/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/pressure/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+#
+# Makefile for industrial I/O pressure drivers
+#
+
+obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o
+st_pressure-y := st_pressure_core.o
+st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o
+
+obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o
+obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure_buffer.c linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure_buffer.c
--- linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure_buffer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure_buffer.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,105 @@
+/*
+ * STMicroelectronics pressures driver
+ *
+ * Copyright 2013 STMicroelectronics Inc.
+ *
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#include <linux/iio/common/st_sensors.h>
+#include "st_pressure.h"
+
+int st_press_trig_set_state(struct iio_trigger *trig, bool state)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+
+	return st_sensors_set_dataready_irq(indio_dev, state);
+}
+
+static int st_press_buffer_preenable(struct iio_dev *indio_dev)
+{
+	int err;
+
+	err = st_sensors_set_enable(indio_dev, true);
+	if (err < 0)
+		goto st_press_set_enable_error;
+
+	err = iio_sw_buffer_preenable(indio_dev);
+
+st_press_set_enable_error:
+	return err;
+}
+
+static int st_press_buffer_postenable(struct iio_dev *indio_dev)
+{
+	int err;
+	struct st_sensor_data *pdata = iio_priv(indio_dev);
+
+	pdata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+	if (pdata->buffer_data == NULL) {
+		err = -ENOMEM;
+		goto allocate_memory_error;
+	}
+
+	err = iio_triggered_buffer_postenable(indio_dev);
+	if (err < 0)
+		goto st_press_buffer_postenable_error;
+
+	return err;
+
+st_press_buffer_postenable_error:
+	kfree(pdata->buffer_data);
+allocate_memory_error:
+	return err;
+}
+
+static int st_press_buffer_predisable(struct iio_dev *indio_dev)
+{
+	int err;
+	struct st_sensor_data *pdata = iio_priv(indio_dev);
+
+	err = iio_triggered_buffer_predisable(indio_dev);
+	if (err < 0)
+		goto st_press_buffer_predisable_error;
+
+	err = st_sensors_set_enable(indio_dev, false);
+
+st_press_buffer_predisable_error:
+	kfree(pdata->buffer_data);
+	return err;
+}
+
+static const struct iio_buffer_setup_ops st_press_buffer_setup_ops = {
+	.preenable = &st_press_buffer_preenable,
+	.postenable = &st_press_buffer_postenable,
+	.predisable = &st_press_buffer_predisable,
+};
+
+int st_press_allocate_ring(struct iio_dev *indio_dev)
+{
+	return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+		&st_sensors_trigger_handler, &st_press_buffer_setup_ops);
+}
+
+void st_press_deallocate_ring(struct iio_dev *indio_dev)
+{
+	iio_triggered_buffer_cleanup(indio_dev);
+}
+
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics pressures buffer");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure_core.c linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure_core.c
--- linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,274 @@
+/*
+ * STMicroelectronics pressures driver
+ *
+ * Copyright 2013 STMicroelectronics Inc.
+ *
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/buffer.h>
+#include <asm/unaligned.h>
+
+#include <linux/iio/common/st_sensors.h>
+#include "st_pressure.h"
+
+#define ST_PRESS_LSB_PER_MBAR			4096UL
+#define ST_PRESS_KPASCAL_NANO_SCALE		(100000000UL / \
+						 ST_PRESS_LSB_PER_MBAR)
+#define ST_PRESS_NUMBER_DATA_CHANNELS		1
+
+/* DEFAULT VALUE FOR SENSORS */
+#define ST_PRESS_DEFAULT_OUT_XL_ADDR		0x28
+#define ST_TEMP_DEFAULT_OUT_L_ADDR		0x2b
+
+/* FULLSCALE */
+#define ST_PRESS_FS_AVL_1260MB			1260
+
+/* CUSTOM VALUES FOR SENSOR 1 */
+#define ST_PRESS_1_WAI_EXP			0xbb
+#define ST_PRESS_1_ODR_ADDR			0x20
+#define ST_PRESS_1_ODR_MASK			0x70
+#define ST_PRESS_1_ODR_AVL_1HZ_VAL		0x01
+#define ST_PRESS_1_ODR_AVL_7HZ_VAL		0x05
+#define ST_PRESS_1_ODR_AVL_13HZ_VAL		0x06
+#define ST_PRESS_1_ODR_AVL_25HZ_VAL		0x07
+#define ST_PRESS_1_PW_ADDR			0x20
+#define ST_PRESS_1_PW_MASK			0x80
+#define ST_PRESS_1_FS_ADDR			0x23
+#define ST_PRESS_1_FS_MASK			0x30
+#define ST_PRESS_1_FS_AVL_1260_VAL		0x00
+#define ST_PRESS_1_FS_AVL_TEMP_GAIN		2083000
+#define ST_PRESS_1_FS_AVL_1260_GAIN		ST_PRESS_KPASCAL_NANO_SCALE
+#define ST_PRESS_1_BDU_ADDR			0x20
+#define ST_PRESS_1_BDU_MASK			0x04
+#define ST_PRESS_1_DRDY_IRQ_ADDR		0x22
+#define ST_PRESS_1_DRDY_IRQ_MASK		0x04
+#define ST_PRESS_1_MULTIREAD_BIT		true
+#define ST_PRESS_1_TEMP_OFFSET			42500
+
+static const struct iio_chan_spec st_press_channels[] = {
+	ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24,
+			ST_PRESS_DEFAULT_OUT_XL_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_TEMP,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
+						BIT(IIO_CHAN_INFO_OFFSET),
+			-1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16,
+			ST_TEMP_DEFAULT_OUT_L_ADDR),
+	IIO_CHAN_SOFT_TIMESTAMP(1)
+};
+
+static const struct st_sensors st_press_sensors[] = {
+	{
+		.wai = ST_PRESS_1_WAI_EXP,
+		.sensors_supported = {
+			[0] = LPS331AP_PRESS_DEV_NAME,
+		},
+		.ch = (struct iio_chan_spec *)st_press_channels,
+		.odr = {
+			.addr = ST_PRESS_1_ODR_ADDR,
+			.mask = ST_PRESS_1_ODR_MASK,
+			.odr_avl = {
+				{ 1, ST_PRESS_1_ODR_AVL_1HZ_VAL, },
+				{ 7, ST_PRESS_1_ODR_AVL_7HZ_VAL, },
+				{ 13, ST_PRESS_1_ODR_AVL_13HZ_VAL, },
+				{ 25, ST_PRESS_1_ODR_AVL_25HZ_VAL, },
+			},
+		},
+		.pw = {
+			.addr = ST_PRESS_1_PW_ADDR,
+			.mask = ST_PRESS_1_PW_MASK,
+			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
+			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+		},
+		.fs = {
+			.addr = ST_PRESS_1_FS_ADDR,
+			.mask = ST_PRESS_1_FS_MASK,
+			.fs_avl = {
+				[0] = {
+					.num = ST_PRESS_FS_AVL_1260MB,
+					.value = ST_PRESS_1_FS_AVL_1260_VAL,
+					.gain = ST_PRESS_1_FS_AVL_1260_GAIN,
+					.gain2 = ST_PRESS_1_FS_AVL_TEMP_GAIN,
+				},
+			},
+		},
+		.bdu = {
+			.addr = ST_PRESS_1_BDU_ADDR,
+			.mask = ST_PRESS_1_BDU_MASK,
+		},
+		.drdy_irq = {
+			.addr = ST_PRESS_1_DRDY_IRQ_ADDR,
+			.mask = ST_PRESS_1_DRDY_IRQ_MASK,
+		},
+		.multi_read_bit = ST_PRESS_1_MULTIREAD_BIT,
+		.bootime = 2,
+	},
+};
+
+static int st_press_read_raw(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *ch, int *val,
+							int *val2, long mask)
+{
+	int err;
+	struct st_sensor_data *pdata = iio_priv(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		err = st_sensors_read_info_raw(indio_dev, ch, val);
+		if (err < 0)
+			goto read_error;
+
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		*val = 0;
+
+		switch (ch->type) {
+		case IIO_PRESSURE:
+			*val2 = pdata->current_fullscale->gain;
+			break;
+		case IIO_TEMP:
+			*val2 = pdata->current_fullscale->gain2;
+			break;
+		default:
+			err = -EINVAL;
+			goto read_error;
+		}
+
+		return IIO_VAL_INT_PLUS_NANO;
+	case IIO_CHAN_INFO_OFFSET:
+		switch (ch->type) {
+		case IIO_TEMP:
+			*val = 425;
+			*val2 = 10;
+			break;
+		default:
+			err = -EINVAL;
+			goto read_error;
+		}
+
+		return IIO_VAL_FRACTIONAL;
+	default:
+		return -EINVAL;
+	}
+
+read_error:
+	return err;
+}
+
+static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
+static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
+
+static struct attribute *st_press_attributes[] = {
+	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group st_press_attribute_group = {
+	.attrs = st_press_attributes,
+};
+
+static const struct iio_info press_info = {
+	.driver_module = THIS_MODULE,
+	.attrs = &st_press_attribute_group,
+	.read_raw = &st_press_read_raw,
+};
+
+#ifdef CONFIG_IIO_TRIGGER
+static const struct iio_trigger_ops st_press_trigger_ops = {
+	.owner = THIS_MODULE,
+	.set_trigger_state = ST_PRESS_TRIGGER_SET_STATE,
+};
+#define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops)
+#else
+#define ST_PRESS_TRIGGER_OPS NULL
+#endif
+
+int st_press_common_probe(struct iio_dev *indio_dev)
+{
+	int err;
+	struct st_sensor_data *pdata = iio_priv(indio_dev);
+
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &press_info;
+
+	err = st_sensors_check_device_support(indio_dev,
+				ARRAY_SIZE(st_press_sensors), st_press_sensors);
+	if (err < 0)
+		goto st_press_common_probe_error;
+
+	pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
+	pdata->multiread_bit = pdata->sensor->multi_read_bit;
+	indio_dev->channels = pdata->sensor->ch;
+	indio_dev->num_channels = ARRAY_SIZE(st_press_channels);
+
+	pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
+						&pdata->sensor->fs.fs_avl[0];
+	pdata->odr = pdata->sensor->odr.odr_avl[0].hz;
+
+	err = st_sensors_init_sensor(indio_dev);
+	if (err < 0)
+		goto st_press_common_probe_error;
+
+	if (pdata->get_irq_data_ready(indio_dev) > 0) {
+		err = st_press_allocate_ring(indio_dev);
+		if (err < 0)
+			goto st_press_common_probe_error;
+
+		err = st_sensors_allocate_trigger(indio_dev,
+							ST_PRESS_TRIGGER_OPS);
+		if (err < 0)
+			goto st_press_probe_trigger_error;
+	}
+
+	err = iio_device_register(indio_dev);
+	if (err)
+		goto st_press_device_register_error;
+
+	return err;
+
+st_press_device_register_error:
+	if (pdata->get_irq_data_ready(indio_dev) > 0)
+		st_sensors_deallocate_trigger(indio_dev);
+st_press_probe_trigger_error:
+	if (pdata->get_irq_data_ready(indio_dev) > 0)
+		st_press_deallocate_ring(indio_dev);
+st_press_common_probe_error:
+	return err;
+}
+EXPORT_SYMBOL(st_press_common_probe);
+
+void st_press_common_remove(struct iio_dev *indio_dev)
+{
+	struct st_sensor_data *pdata = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	if (pdata->get_irq_data_ready(indio_dev) > 0) {
+		st_sensors_deallocate_trigger(indio_dev);
+		st_press_deallocate_ring(indio_dev);
+	}
+	iio_device_free(indio_dev);
+}
+EXPORT_SYMBOL(st_press_common_remove);
+
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics pressures driver");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure.h linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure.h
--- linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * STMicroelectronics pressures driver
+ *
+ * Copyright 2013 STMicroelectronics Inc.
+ *
+ * Denis Ciocca <denis.ciocca@st.com>
+ * v. 1.0.0
+ * Licensed under the GPL-2.
+ */
+
+#ifndef ST_PRESS_H
+#define ST_PRESS_H
+
+#include <linux/types.h>
+#include <linux/iio/common/st_sensors.h>
+
+#define LPS331AP_PRESS_DEV_NAME		"lps331ap"
+
+int st_press_common_probe(struct iio_dev *indio_dev);
+void st_press_common_remove(struct iio_dev *indio_dev);
+
+#ifdef CONFIG_IIO_BUFFER
+int st_press_allocate_ring(struct iio_dev *indio_dev);
+void st_press_deallocate_ring(struct iio_dev *indio_dev);
+int st_press_trig_set_state(struct iio_trigger *trig, bool state);
+#define ST_PRESS_TRIGGER_SET_STATE (&st_press_trig_set_state)
+#else /* CONFIG_IIO_BUFFER */
+static inline int st_press_allocate_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void st_press_deallocate_ring(struct iio_dev *indio_dev)
+{
+}
+#define ST_PRESS_TRIGGER_SET_STATE NULL
+#endif /* CONFIG_IIO_BUFFER */
+
+#endif /* ST_PRESS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure_i2c.c linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure_i2c.c
--- linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure_i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure_i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,77 @@
+/*
+ * STMicroelectronics pressures driver
+ *
+ * Copyright 2013 STMicroelectronics Inc.
+ *
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+
+#include <linux/iio/common/st_sensors.h>
+#include <linux/iio/common/st_sensors_i2c.h>
+#include "st_pressure.h"
+
+static int st_press_i2c_probe(struct i2c_client *client,
+						const struct i2c_device_id *id)
+{
+	struct iio_dev *indio_dev;
+	struct st_sensor_data *pdata;
+	int err;
+
+	indio_dev = iio_device_alloc(sizeof(*pdata));
+	if (indio_dev == NULL) {
+		err = -ENOMEM;
+		goto iio_device_alloc_error;
+	}
+
+	pdata = iio_priv(indio_dev);
+	pdata->dev = &client->dev;
+
+	st_sensors_i2c_configure(indio_dev, client, pdata);
+
+	err = st_press_common_probe(indio_dev);
+	if (err < 0)
+		goto st_press_common_probe_error;
+
+	return 0;
+
+st_press_common_probe_error:
+	iio_device_free(indio_dev);
+iio_device_alloc_error:
+	return err;
+}
+
+static int st_press_i2c_remove(struct i2c_client *client)
+{
+	st_press_common_remove(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+static const struct i2c_device_id st_press_id_table[] = {
+	{ LPS331AP_PRESS_DEV_NAME },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, st_press_id_table);
+
+static struct i2c_driver st_press_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "st-press-i2c",
+	},
+	.probe = st_press_i2c_probe,
+	.remove = st_press_i2c_remove,
+	.id_table = st_press_id_table,
+};
+module_i2c_driver(st_press_driver);
+
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics pressures i2c driver");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure_spi.c linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure_spi.c
--- linux-libre-3.10-gnu/drivers/iio/pressure/st_pressure_spi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/pressure/st_pressure_spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,76 @@
+/*
+ * STMicroelectronics pressures driver
+ *
+ * Copyright 2013 STMicroelectronics Inc.
+ *
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+
+#include <linux/iio/common/st_sensors.h>
+#include <linux/iio/common/st_sensors_spi.h>
+#include "st_pressure.h"
+
+static int st_press_spi_probe(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev;
+	struct st_sensor_data *pdata;
+	int err;
+
+	indio_dev = iio_device_alloc(sizeof(*pdata));
+	if (indio_dev == NULL) {
+		err = -ENOMEM;
+		goto iio_device_alloc_error;
+	}
+
+	pdata = iio_priv(indio_dev);
+	pdata->dev = &spi->dev;
+
+	st_sensors_spi_configure(indio_dev, spi, pdata);
+
+	err = st_press_common_probe(indio_dev);
+	if (err < 0)
+		goto st_press_common_probe_error;
+
+	return 0;
+
+st_press_common_probe_error:
+	iio_device_free(indio_dev);
+iio_device_alloc_error:
+	return err;
+}
+
+static int st_press_spi_remove(struct spi_device *spi)
+{
+	st_press_common_remove(spi_get_drvdata(spi));
+
+	return 0;
+}
+
+static const struct spi_device_id st_press_id_table[] = {
+	{ LPS331AP_PRESS_DEV_NAME },
+	{},
+};
+MODULE_DEVICE_TABLE(spi, st_press_id_table);
+
+static struct spi_driver st_press_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "st-press-spi",
+	},
+	.probe = st_press_spi_probe,
+	.remove = st_press_spi_remove,
+	.id_table = st_press_id_table,
+};
+module_spi_driver(st_press_driver);
+
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics pressures spi driver");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/trigger/iio-trig-interrupt.c linux-libre-3.11-rc7-gnu/drivers/iio/trigger/iio-trig-interrupt.c
--- linux-libre-3.10-gnu/drivers/iio/trigger/iio-trig-interrupt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/trigger/iio-trig-interrupt.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,121 @@
+/*
+ * Industrial I/O - generic interrupt based trigger support
+ *
+ * Copyright (c) 2008-2013 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+
+
+struct iio_interrupt_trigger_info {
+	unsigned int irq;
+};
+
+static irqreturn_t iio_interrupt_trigger_poll(int irq, void *private)
+{
+	/* Timestamp not currently provided */
+	iio_trigger_poll(private, 0);
+	return IRQ_HANDLED;
+}
+
+static const struct iio_trigger_ops iio_interrupt_trigger_ops = {
+	.owner = THIS_MODULE,
+};
+
+static int iio_interrupt_trigger_probe(struct platform_device *pdev)
+{
+	struct iio_interrupt_trigger_info *trig_info;
+	struct iio_trigger *trig;
+	unsigned long irqflags;
+	struct resource *irq_res;
+	int irq, ret = 0;
+
+	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+	if (irq_res == NULL)
+		return -ENODEV;
+
+	irqflags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED;
+
+	irq = irq_res->start;
+
+	trig = iio_trigger_alloc("irqtrig%d", irq);
+	if (!trig) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
+	if (!trig_info) {
+		ret = -ENOMEM;
+		goto error_put_trigger;
+	}
+	iio_trigger_set_drvdata(trig, trig_info);
+	trig_info->irq = irq;
+	trig->ops = &iio_interrupt_trigger_ops;
+	ret = request_irq(irq, iio_interrupt_trigger_poll,
+			  irqflags, trig->name, trig);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"request IRQ-%d failed", irq);
+		goto error_free_trig_info;
+	}
+
+	ret = iio_trigger_register(trig);
+	if (ret)
+		goto error_release_irq;
+	platform_set_drvdata(pdev, trig);
+
+	return 0;
+
+/* First clean up the partly allocated trigger */
+error_release_irq:
+	free_irq(irq, trig);
+error_free_trig_info:
+	kfree(trig_info);
+error_put_trigger:
+	iio_trigger_put(trig);
+error_ret:
+	return ret;
+}
+
+static int iio_interrupt_trigger_remove(struct platform_device *pdev)
+{
+	struct iio_trigger *trig;
+	struct iio_interrupt_trigger_info *trig_info;
+
+	trig = platform_get_drvdata(pdev);
+	trig_info = iio_trigger_get_drvdata(trig);
+	iio_trigger_unregister(trig);
+	free_irq(trig_info->irq, trig);
+	kfree(trig_info);
+	iio_trigger_put(trig);
+
+	return 0;
+}
+
+static struct platform_driver iio_interrupt_trigger_driver = {
+	.probe = iio_interrupt_trigger_probe,
+	.remove = iio_interrupt_trigger_remove,
+	.driver = {
+		.name = "iio_interrupt_trigger",
+		.owner = THIS_MODULE,
+	},
+};
+
+module_platform_driver(iio_interrupt_trigger_driver);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
+MODULE_DESCRIPTION("Interrupt trigger for the iio subsystem");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/trigger/iio-trig-sysfs.c linux-libre-3.11-rc7-gnu/drivers/iio/trigger/iio-trig-sysfs.c
--- linux-libre-3.10-gnu/drivers/iio/trigger/iio-trig-sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/trigger/iio-trig-sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/irq_work.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+
+struct iio_sysfs_trig {
+	struct iio_trigger *trig;
+	struct irq_work work;
+	int id;
+	struct list_head l;
+};
+
+static LIST_HEAD(iio_sysfs_trig_list);
+static DEFINE_MUTEX(iio_syfs_trig_list_mut);
+
+static int iio_sysfs_trigger_probe(int id);
+static ssize_t iio_sysfs_trig_add(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
+{
+	int ret;
+	unsigned long input;
+
+	ret = kstrtoul(buf, 10, &input);
+	if (ret)
+		return ret;
+	ret = iio_sysfs_trigger_probe(input);
+	if (ret)
+		return ret;
+	return len;
+}
+static DEVICE_ATTR(add_trigger, S_IWUSR, NULL, &iio_sysfs_trig_add);
+
+static int iio_sysfs_trigger_remove(int id);
+static ssize_t iio_sysfs_trig_remove(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf,
+				     size_t len)
+{
+	int ret;
+	unsigned long input;
+
+	ret = kstrtoul(buf, 10, &input);
+	if (ret)
+		return ret;
+	ret = iio_sysfs_trigger_remove(input);
+	if (ret)
+		return ret;
+	return len;
+}
+
+static DEVICE_ATTR(remove_trigger, S_IWUSR, NULL, &iio_sysfs_trig_remove);
+
+static struct attribute *iio_sysfs_trig_attrs[] = {
+	&dev_attr_add_trigger.attr,
+	&dev_attr_remove_trigger.attr,
+	NULL,
+};
+
+static const struct attribute_group iio_sysfs_trig_group = {
+	.attrs = iio_sysfs_trig_attrs,
+};
+
+static const struct attribute_group *iio_sysfs_trig_groups[] = {
+	&iio_sysfs_trig_group,
+	NULL
+};
+
+
+/* Nothing to actually do upon release */
+static void iio_trigger_sysfs_release(struct device *dev)
+{
+}
+
+static struct device iio_sysfs_trig_dev = {
+	.bus = &iio_bus_type,
+	.groups = iio_sysfs_trig_groups,
+	.release = &iio_trigger_sysfs_release,
+};
+
+static void iio_sysfs_trigger_work(struct irq_work *work)
+{
+	struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig,
+							work);
+
+	iio_trigger_poll(trig->trig, 0);
+}
+
+static ssize_t iio_sysfs_trigger_poll(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct iio_trigger *trig = to_iio_trigger(dev);
+	struct iio_sysfs_trig *sysfs_trig = iio_trigger_get_drvdata(trig);
+
+	irq_work_queue(&sysfs_trig->work);
+
+	return count;
+}
+
+static DEVICE_ATTR(trigger_now, S_IWUSR, NULL, iio_sysfs_trigger_poll);
+
+static struct attribute *iio_sysfs_trigger_attrs[] = {
+	&dev_attr_trigger_now.attr,
+	NULL,
+};
+
+static const struct attribute_group iio_sysfs_trigger_attr_group = {
+	.attrs = iio_sysfs_trigger_attrs,
+};
+
+static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = {
+	&iio_sysfs_trigger_attr_group,
+	NULL
+};
+
+static const struct iio_trigger_ops iio_sysfs_trigger_ops = {
+	.owner = THIS_MODULE,
+};
+
+static int iio_sysfs_trigger_probe(int id)
+{
+	struct iio_sysfs_trig *t;
+	int ret;
+	bool foundit = false;
+	mutex_lock(&iio_syfs_trig_list_mut);
+	list_for_each_entry(t, &iio_sysfs_trig_list, l)
+		if (id == t->id) {
+			foundit = true;
+			break;
+		}
+	if (foundit) {
+		ret = -EINVAL;
+		goto out1;
+	}
+	t = kmalloc(sizeof(*t), GFP_KERNEL);
+	if (t == NULL) {
+		ret = -ENOMEM;
+		goto out1;
+	}
+	t->id = id;
+	t->trig = iio_trigger_alloc("sysfstrig%d", id);
+	if (!t->trig) {
+		ret = -ENOMEM;
+		goto free_t;
+	}
+
+	t->trig->dev.groups = iio_sysfs_trigger_attr_groups;
+	t->trig->ops = &iio_sysfs_trigger_ops;
+	t->trig->dev.parent = &iio_sysfs_trig_dev;
+	iio_trigger_set_drvdata(t->trig, t);
+
+	init_irq_work(&t->work, iio_sysfs_trigger_work);
+
+	ret = iio_trigger_register(t->trig);
+	if (ret)
+		goto out2;
+	list_add(&t->l, &iio_sysfs_trig_list);
+	__module_get(THIS_MODULE);
+	mutex_unlock(&iio_syfs_trig_list_mut);
+	return 0;
+
+out2:
+	iio_trigger_put(t->trig);
+free_t:
+	kfree(t);
+out1:
+	mutex_unlock(&iio_syfs_trig_list_mut);
+	return ret;
+}
+
+static int iio_sysfs_trigger_remove(int id)
+{
+	bool foundit = false;
+	struct iio_sysfs_trig *t;
+	mutex_lock(&iio_syfs_trig_list_mut);
+	list_for_each_entry(t, &iio_sysfs_trig_list, l)
+		if (id == t->id) {
+			foundit = true;
+			break;
+		}
+	if (!foundit) {
+		mutex_unlock(&iio_syfs_trig_list_mut);
+		return -EINVAL;
+	}
+
+	iio_trigger_unregister(t->trig);
+	iio_trigger_free(t->trig);
+
+	list_del(&t->l);
+	kfree(t);
+	module_put(THIS_MODULE);
+	mutex_unlock(&iio_syfs_trig_list_mut);
+	return 0;
+}
+
+
+static int __init iio_sysfs_trig_init(void)
+{
+	device_initialize(&iio_sysfs_trig_dev);
+	dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger");
+	return device_add(&iio_sysfs_trig_dev);
+}
+module_init(iio_sysfs_trig_init);
+
+static void __exit iio_sysfs_trig_exit(void)
+{
+	device_unregister(&iio_sysfs_trig_dev);
+}
+module_exit(iio_sysfs_trig_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Sysfs based trigger for the iio subsystem");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:iio-trig-sysfs");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/trigger/Kconfig linux-libre-3.11-rc7-gnu/drivers/iio/trigger/Kconfig
--- linux-libre-3.10-gnu/drivers/iio/trigger/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/trigger/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,26 @@
+#
+# Industrial I/O standalone triggers
+#
+menu "Triggers - standalone"
+
+config IIO_INTERRUPT_TRIGGER
+	tristate "Generic interrupt trigger"
+	help
+	  Provides support for using an interrupt of any type as an IIO
+	  trigger.  This may be provided by a gpio driver for example.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iio-trig-interrupt.
+
+config IIO_SYSFS_TRIGGER
+	tristate "SYSFS trigger"
+	depends on SYSFS
+	select IRQ_WORK
+	help
+	  Provides support for using SYSFS entry as IIO triggers.
+	  If unsure, say N (but it's safe to say "Y").
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iio-trig-sysfs.
+
+endmenu
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iio/trigger/Makefile linux-libre-3.11-rc7-gnu/drivers/iio/trigger/Makefile
--- linux-libre-3.10-gnu/drivers/iio/trigger/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iio/trigger/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,6 @@
+#
+# Makefile for triggers not associated with iio-devices
+#
+
+obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o
+obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/core/addr.c linux-libre-3.11-rc7-gnu/drivers/infiniband/core/addr.c
--- linux-libre-3.10-gnu/drivers/infiniband/core/addr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/core/addr.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,6 +45,7 @@
 #include <net/addrconf.h>
 #include <net/ip6_route.h>
 #include <rdma/ib_addr.h>
+#include <rdma/ib.h>
 
 MODULE_AUTHOR("Sean Hefty");
 MODULE_DESCRIPTION("IB Address Translation");
@@ -70,6 +71,21 @@ static LIST_HEAD(req_list);
 static DECLARE_DELAYED_WORK(work, process_req);
 static struct workqueue_struct *addr_wq;
 
+int rdma_addr_size(struct sockaddr *addr)
+{
+	switch (addr->sa_family) {
+	case AF_INET:
+		return sizeof(struct sockaddr_in);
+	case AF_INET6:
+		return sizeof(struct sockaddr_in6);
+	case AF_IB:
+		return sizeof(struct sockaddr_ib);
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL(rdma_addr_size);
+
 void rdma_addr_register_client(struct rdma_addr_client *client)
 {
 	atomic_set(&client->refcount, 1);
@@ -369,12 +385,12 @@ int rdma_resolve_ip(struct rdma_addr_cli
 			goto err;
 		}
 
-		memcpy(src_in, src_addr, ip_addr_size(src_addr));
+		memcpy(src_in, src_addr, rdma_addr_size(src_addr));
 	} else {
 		src_in->sa_family = dst_addr->sa_family;
 	}
 
-	memcpy(dst_in, dst_addr, ip_addr_size(dst_addr));
+	memcpy(dst_in, dst_addr, rdma_addr_size(dst_addr));
 	req->addr = addr;
 	req->callback = callback;
 	req->context = context;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/core/cma.c linux-libre-3.11-rc7-gnu/drivers/infiniband/core/cma.c
--- linux-libre-3.10-gnu/drivers/infiniband/core/cma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/core/cma.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,6 +50,7 @@
 #include <rdma/rdma_cm.h>
 #include <rdma/rdma_cm_ib.h>
 #include <rdma/rdma_netlink.h>
+#include <rdma/ib.h>
 #include <rdma/ib_cache.h>
 #include <rdma/ib_cm.h>
 #include <rdma/ib_sa.h>
@@ -79,7 +80,6 @@ static LIST_HEAD(dev_list);
 static LIST_HEAD(listen_any_list);
 static DEFINE_MUTEX(lock);
 static struct workqueue_struct *cma_wq;
-static DEFINE_IDR(sdp_ps);
 static DEFINE_IDR(tcp_ps);
 static DEFINE_IDR(udp_ps);
 static DEFINE_IDR(ipoib_ps);
@@ -195,24 +195,7 @@ struct cma_hdr {
 	union cma_ip_addr dst_addr;
 };
 
-struct sdp_hh {
-	u8 bsdh[16];
-	u8 sdp_version; /* Major version: 7:4 */
-	u8 ip_version;	/* IP version: 7:4 */
-	u8 sdp_specific1[10];
-	__be16 port;
-	__be16 sdp_specific2;
-	union cma_ip_addr src_addr;
-	union cma_ip_addr dst_addr;
-};
-
-struct sdp_hah {
-	u8 bsdh[16];
-	u8 sdp_version;
-};
-
 #define CMA_VERSION 0x00
-#define SDP_MAJ_VERSION 0x2
 
 static int cma_comp(struct rdma_id_private *id_priv, enum rdma_cm_state comp)
 {
@@ -261,21 +244,6 @@ static inline void cma_set_ip_ver(struct
 	hdr->ip_version = (ip_ver << 4) | (hdr->ip_version & 0xF);
 }
 
-static inline u8 sdp_get_majv(u8 sdp_version)
-{
-	return sdp_version >> 4;
-}
-
-static inline u8 sdp_get_ip_ver(struct sdp_hh *hh)
-{
-	return hh->ip_version >> 4;
-}
-
-static inline void sdp_set_ip_ver(struct sdp_hh *hh, u8 ip_ver)
-{
-	hh->ip_version = (ip_ver << 4) | (hh->ip_version & 0xF);
-}
-
 static void cma_attach_to_dev(struct rdma_id_private *id_priv,
 			      struct cma_device *cma_dev)
 {
@@ -310,16 +278,40 @@ static void cma_release_dev(struct rdma_
 	mutex_unlock(&lock);
 }
 
-static int cma_set_qkey(struct rdma_id_private *id_priv)
+static inline struct sockaddr *cma_src_addr(struct rdma_id_private *id_priv)
+{
+	return (struct sockaddr *) &id_priv->id.route.addr.src_addr;
+}
+
+static inline struct sockaddr *cma_dst_addr(struct rdma_id_private *id_priv)
+{
+	return (struct sockaddr *) &id_priv->id.route.addr.dst_addr;
+}
+
+static inline unsigned short cma_family(struct rdma_id_private *id_priv)
+{
+	return id_priv->id.route.addr.src_addr.ss_family;
+}
+
+static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey)
 {
 	struct ib_sa_mcmember_rec rec;
 	int ret = 0;
 
-	if (id_priv->qkey)
+	if (id_priv->qkey) {
+		if (qkey && id_priv->qkey != qkey)
+			return -EINVAL;
 		return 0;
+	}
+
+	if (qkey) {
+		id_priv->qkey = qkey;
+		return 0;
+	}
 
 	switch (id_priv->id.ps) {
 	case RDMA_PS_UDP:
+	case RDMA_PS_IB:
 		id_priv->qkey = RDMA_UDP_QKEY;
 		break;
 	case RDMA_PS_IPOIB:
@@ -358,6 +350,27 @@ static int find_gid_port(struct ib_devic
 	return -EADDRNOTAVAIL;
 }
 
+static void cma_translate_ib(struct sockaddr_ib *sib, struct rdma_dev_addr *dev_addr)
+{
+	dev_addr->dev_type = ARPHRD_INFINIBAND;
+	rdma_addr_set_sgid(dev_addr, (union ib_gid *) &sib->sib_addr);
+	ib_addr_set_pkey(dev_addr, ntohs(sib->sib_pkey));
+}
+
+static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
+{
+	int ret;
+
+	if (addr->sa_family != AF_IB) {
+		ret = rdma_translate_ip(addr, dev_addr);
+	} else {
+		cma_translate_ib((struct sockaddr_ib *) addr, dev_addr);
+		ret = 0;
+	}
+
+	return ret;
+}
+
 static int cma_acquire_dev(struct rdma_id_private *id_priv)
 {
 	struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
@@ -401,6 +414,60 @@ out:
 	return ret;
 }
 
+/*
+ * Select the source IB device and address to reach the destination IB address.
+ */
+static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
+{
+	struct cma_device *cma_dev, *cur_dev;
+	struct sockaddr_ib *addr;
+	union ib_gid gid, sgid, *dgid;
+	u16 pkey, index;
+	u8 p;
+	int i;
+
+	cma_dev = NULL;
+	addr = (struct sockaddr_ib *) cma_dst_addr(id_priv);
+	dgid = (union ib_gid *) &addr->sib_addr;
+	pkey = ntohs(addr->sib_pkey);
+
+	list_for_each_entry(cur_dev, &dev_list, list) {
+		if (rdma_node_get_transport(cur_dev->device->node_type) != RDMA_TRANSPORT_IB)
+			continue;
+
+		for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) {
+			if (ib_find_cached_pkey(cur_dev->device, p, pkey, &index))
+				continue;
+
+			for (i = 0; !ib_get_cached_gid(cur_dev->device, p, i, &gid); i++) {
+				if (!memcmp(&gid, dgid, sizeof(gid))) {
+					cma_dev = cur_dev;
+					sgid = gid;
+					id_priv->id.port_num = p;
+					goto found;
+				}
+
+				if (!cma_dev && (gid.global.subnet_prefix ==
+						 dgid->global.subnet_prefix)) {
+					cma_dev = cur_dev;
+					sgid = gid;
+					id_priv->id.port_num = p;
+				}
+			}
+		}
+	}
+
+	if (!cma_dev)
+		return -ENODEV;
+
+found:
+	cma_attach_to_dev(id_priv, cma_dev);
+	addr = (struct sockaddr_ib *) cma_src_addr(id_priv);
+	memcpy(&addr->sib_addr, &sgid, sizeof sgid);
+	cma_translate_ib(addr, &id_priv->id.route.addr.dev_addr);
+	return 0;
+}
+
 static void cma_deref_id(struct rdma_id_private *id_priv)
 {
 	if (atomic_dec_and_test(&id_priv->refcount))
@@ -630,7 +697,7 @@ static int cma_ib_init_qp_attr(struct rd
 	*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
 
 	if (id_priv->id.qp_type == IB_QPT_UD) {
-		ret = cma_set_qkey(id_priv);
+		ret = cma_set_qkey(id_priv, 0);
 		if (ret)
 			return ret;
 
@@ -679,26 +746,30 @@ EXPORT_SYMBOL(rdma_init_qp_attr);
 
 static inline int cma_zero_addr(struct sockaddr *addr)
 {
-	struct in6_addr *ip6;
-
-	if (addr->sa_family == AF_INET)
-		return ipv4_is_zeronet(
-			((struct sockaddr_in *)addr)->sin_addr.s_addr);
-	else {
-		ip6 = &((struct sockaddr_in6 *) addr)->sin6_addr;
-		return (ip6->s6_addr32[0] | ip6->s6_addr32[1] |
-			ip6->s6_addr32[2] | ip6->s6_addr32[3]) == 0;
+	switch (addr->sa_family) {
+	case AF_INET:
+		return ipv4_is_zeronet(((struct sockaddr_in *)addr)->sin_addr.s_addr);
+	case AF_INET6:
+		return ipv6_addr_any(&((struct sockaddr_in6 *) addr)->sin6_addr);
+	case AF_IB:
+		return ib_addr_any(&((struct sockaddr_ib *) addr)->sib_addr);
+	default:
+		return 0;
 	}
 }
 
 static inline int cma_loopback_addr(struct sockaddr *addr)
 {
-	if (addr->sa_family == AF_INET)
-		return ipv4_is_loopback(
-			((struct sockaddr_in *) addr)->sin_addr.s_addr);
-	else
-		return ipv6_addr_loopback(
-			&((struct sockaddr_in6 *) addr)->sin6_addr);
+	switch (addr->sa_family) {
+	case AF_INET:
+		return ipv4_is_loopback(((struct sockaddr_in *) addr)->sin_addr.s_addr);
+	case AF_INET6:
+		return ipv6_addr_loopback(&((struct sockaddr_in6 *) addr)->sin6_addr);
+	case AF_IB:
+		return ib_addr_loopback(&((struct sockaddr_ib *) addr)->sib_addr);
+	default:
+		return 0;
+	}
 }
 
 static inline int cma_any_addr(struct sockaddr *addr)
@@ -715,18 +786,31 @@ static int cma_addr_cmp(struct sockaddr
 	case AF_INET:
 		return ((struct sockaddr_in *) src)->sin_addr.s_addr !=
 		       ((struct sockaddr_in *) dst)->sin_addr.s_addr;
-	default:
+	case AF_INET6:
 		return ipv6_addr_cmp(&((struct sockaddr_in6 *) src)->sin6_addr,
 				     &((struct sockaddr_in6 *) dst)->sin6_addr);
+	default:
+		return ib_addr_cmp(&((struct sockaddr_ib *) src)->sib_addr,
+				   &((struct sockaddr_ib *) dst)->sib_addr);
 	}
 }
 
-static inline __be16 cma_port(struct sockaddr *addr)
+static __be16 cma_port(struct sockaddr *addr)
 {
-	if (addr->sa_family == AF_INET)
+	struct sockaddr_ib *sib;
+
+	switch (addr->sa_family) {
+	case AF_INET:
 		return ((struct sockaddr_in *) addr)->sin_port;
-	else
+	case AF_INET6:
 		return ((struct sockaddr_in6 *) addr)->sin6_port;
+	case AF_IB:
+		sib = (struct sockaddr_ib *) addr;
+		return htons((u16) (be64_to_cpu(sib->sib_sid) &
+				    be64_to_cpu(sib->sib_sid_mask)));
+	default:
+		return 0;
+	}
 }
 
 static inline int cma_any_port(struct sockaddr *addr)
@@ -734,83 +818,93 @@ static inline int cma_any_port(struct so
 	return !cma_port(addr);
 }
 
-static int cma_get_net_info(void *hdr, enum rdma_port_space ps,
-			    u8 *ip_ver, __be16 *port,
-			    union cma_ip_addr **src, union cma_ip_addr **dst)
+static void cma_save_ib_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id,
+			     struct ib_sa_path_rec *path)
 {
-	switch (ps) {
-	case RDMA_PS_SDP:
-		if (sdp_get_majv(((struct sdp_hh *) hdr)->sdp_version) !=
-		    SDP_MAJ_VERSION)
-			return -EINVAL;
-
-		*ip_ver	= sdp_get_ip_ver(hdr);
-		*port	= ((struct sdp_hh *) hdr)->port;
-		*src	= &((struct sdp_hh *) hdr)->src_addr;
-		*dst	= &((struct sdp_hh *) hdr)->dst_addr;
-		break;
-	default:
-		if (((struct cma_hdr *) hdr)->cma_version != CMA_VERSION)
-			return -EINVAL;
+	struct sockaddr_ib *listen_ib, *ib;
 
-		*ip_ver	= cma_get_ip_ver(hdr);
-		*port	= ((struct cma_hdr *) hdr)->port;
-		*src	= &((struct cma_hdr *) hdr)->src_addr;
-		*dst	= &((struct cma_hdr *) hdr)->dst_addr;
-		break;
-	}
+	listen_ib = (struct sockaddr_ib *) &listen_id->route.addr.src_addr;
+	ib = (struct sockaddr_ib *) &id->route.addr.src_addr;
+	ib->sib_family = listen_ib->sib_family;
+	ib->sib_pkey = path->pkey;
+	ib->sib_flowinfo = path->flow_label;
+	memcpy(&ib->sib_addr, &path->sgid, 16);
+	ib->sib_sid = listen_ib->sib_sid;
+	ib->sib_sid_mask = cpu_to_be64(0xffffffffffffffffULL);
+	ib->sib_scope_id = listen_ib->sib_scope_id;
 
-	if (*ip_ver != 4 && *ip_ver != 6)
-		return -EINVAL;
-	return 0;
+	ib = (struct sockaddr_ib *) &id->route.addr.dst_addr;
+	ib->sib_family = listen_ib->sib_family;
+	ib->sib_pkey = path->pkey;
+	ib->sib_flowinfo = path->flow_label;
+	memcpy(&ib->sib_addr, &path->dgid, 16);
 }
 
-static void cma_save_net_info(struct rdma_addr *addr,
-			      struct rdma_addr *listen_addr,
-			      u8 ip_ver, __be16 port,
-			      union cma_ip_addr *src, union cma_ip_addr *dst)
+static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id,
+			      struct cma_hdr *hdr)
 {
 	struct sockaddr_in *listen4, *ip4;
+
+	listen4 = (struct sockaddr_in *) &listen_id->route.addr.src_addr;
+	ip4 = (struct sockaddr_in *) &id->route.addr.src_addr;
+	ip4->sin_family = listen4->sin_family;
+	ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr;
+	ip4->sin_port = listen4->sin_port;
+
+	ip4 = (struct sockaddr_in *) &id->route.addr.dst_addr;
+	ip4->sin_family = listen4->sin_family;
+	ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr;
+	ip4->sin_port = hdr->port;
+}
+
+static void cma_save_ip6_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id,
+			      struct cma_hdr *hdr)
+{
 	struct sockaddr_in6 *listen6, *ip6;
 
-	switch (ip_ver) {
-	case 4:
-		listen4 = (struct sockaddr_in *) &listen_addr->src_addr;
-		ip4 = (struct sockaddr_in *) &addr->src_addr;
-		ip4->sin_family = listen4->sin_family;
-		ip4->sin_addr.s_addr = dst->ip4.addr;
-		ip4->sin_port = listen4->sin_port;
+	listen6 = (struct sockaddr_in6 *) &listen_id->route.addr.src_addr;
+	ip6 = (struct sockaddr_in6 *) &id->route.addr.src_addr;
+	ip6->sin6_family = listen6->sin6_family;
+	ip6->sin6_addr = hdr->dst_addr.ip6;
+	ip6->sin6_port = listen6->sin6_port;
 
-		ip4 = (struct sockaddr_in *) &addr->dst_addr;
-		ip4->sin_family = listen4->sin_family;
-		ip4->sin_addr.s_addr = src->ip4.addr;
-		ip4->sin_port = port;
+	ip6 = (struct sockaddr_in6 *) &id->route.addr.dst_addr;
+	ip6->sin6_family = listen6->sin6_family;
+	ip6->sin6_addr = hdr->src_addr.ip6;
+	ip6->sin6_port = hdr->port;
+}
+
+static int cma_save_net_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id,
+			     struct ib_cm_event *ib_event)
+{
+	struct cma_hdr *hdr;
+
+	if ((listen_id->route.addr.src_addr.ss_family == AF_IB) &&
+	    (ib_event->event == IB_CM_REQ_RECEIVED)) {
+		cma_save_ib_info(id, listen_id, ib_event->param.req_rcvd.primary_path);
+		return 0;
+	}
+
+	hdr = ib_event->private_data;
+	if (hdr->cma_version != CMA_VERSION)
+		return -EINVAL;
+
+	switch (cma_get_ip_ver(hdr)) {
+	case 4:
+		cma_save_ip4_info(id, listen_id, hdr);
 		break;
 	case 6:
-		listen6 = (struct sockaddr_in6 *) &listen_addr->src_addr;
-		ip6 = (struct sockaddr_in6 *) &addr->src_addr;
-		ip6->sin6_family = listen6->sin6_family;
-		ip6->sin6_addr = dst->ip6;
-		ip6->sin6_port = listen6->sin6_port;
-
-		ip6 = (struct sockaddr_in6 *) &addr->dst_addr;
-		ip6->sin6_family = listen6->sin6_family;
-		ip6->sin6_addr = src->ip6;
-		ip6->sin6_port = port;
+		cma_save_ip6_info(id, listen_id, hdr);
 		break;
 	default:
-		break;
+		return -EINVAL;
 	}
+	return 0;
 }
 
-static inline int cma_user_data_offset(enum rdma_port_space ps)
+static inline int cma_user_data_offset(struct rdma_id_private *id_priv)
 {
-	switch (ps) {
-	case RDMA_PS_SDP:
-		return 0;
-	default:
-		return sizeof(struct cma_hdr);
-	}
+	return cma_family(id_priv) == AF_IB ? 0 : sizeof(struct cma_hdr);
 }
 
 static void cma_cancel_route(struct rdma_id_private *id_priv)
@@ -861,8 +955,7 @@ static void cma_cancel_operation(struct
 		cma_cancel_route(id_priv);
 		break;
 	case RDMA_CM_LISTEN:
-		if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)
-				&& !id_priv->cma_dev)
+		if (cma_any_addr(cma_src_addr(id_priv)) && !id_priv->cma_dev)
 			cma_cancel_listens(id_priv);
 		break;
 	default:
@@ -977,16 +1070,6 @@ reject:
 	return ret;
 }
 
-static int cma_verify_rep(struct rdma_id_private *id_priv, void *data)
-{
-	if (id_priv->id.ps == RDMA_PS_SDP &&
-	    sdp_get_majv(((struct sdp_hah *) data)->sdp_version) !=
-	    SDP_MAJ_VERSION)
-		return -EINVAL;
-
-	return 0;
-}
-
 static void cma_set_rep_event_data(struct rdma_cm_event *event,
 				   struct ib_cm_rep_event_param *rep_data,
 				   void *private_data)
@@ -1021,15 +1104,13 @@ static int cma_ib_handler(struct ib_cm_i
 		event.status = -ETIMEDOUT;
 		break;
 	case IB_CM_REP_RECEIVED:
-		event.status = cma_verify_rep(id_priv, ib_event->private_data);
-		if (event.status)
-			event.event = RDMA_CM_EVENT_CONNECT_ERROR;
-		else if (id_priv->id.qp && id_priv->id.ps != RDMA_PS_SDP) {
+		if (id_priv->id.qp) {
 			event.status = cma_rep_recv(id_priv);
 			event.event = event.status ? RDMA_CM_EVENT_CONNECT_ERROR :
 						     RDMA_CM_EVENT_ESTABLISHED;
-		} else
+		} else {
 			event.event = RDMA_CM_EVENT_CONNECT_RESPONSE;
+		}
 		cma_set_rep_event_data(&event, &ib_event->param.rep_rcvd,
 				       ib_event->private_data);
 		break;
@@ -1085,22 +1166,16 @@ static struct rdma_id_private *cma_new_c
 	struct rdma_id_private *id_priv;
 	struct rdma_cm_id *id;
 	struct rdma_route *rt;
-	union cma_ip_addr *src, *dst;
-	__be16 port;
-	u8 ip_ver;
 	int ret;
 
-	if (cma_get_net_info(ib_event->private_data, listen_id->ps,
-			     &ip_ver, &port, &src, &dst))
-		return NULL;
-
 	id = rdma_create_id(listen_id->event_handler, listen_id->context,
 			    listen_id->ps, ib_event->param.req_rcvd.qp_type);
 	if (IS_ERR(id))
 		return NULL;
 
-	cma_save_net_info(&id->route.addr, &listen_id->route.addr,
-			  ip_ver, port, src, dst);
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (cma_save_net_info(id, listen_id, ib_event))
+		goto err;
 
 	rt = &id->route;
 	rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1;
@@ -1113,19 +1188,17 @@ static struct rdma_id_private *cma_new_c
 	if (rt->num_paths == 2)
 		rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
 
-	if (cma_any_addr((struct sockaddr *) &rt->addr.src_addr)) {
+	if (cma_any_addr(cma_src_addr(id_priv))) {
 		rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND;
 		rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid);
 		ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey));
 	} else {
-		ret = rdma_translate_ip((struct sockaddr *) &rt->addr.src_addr,
-					&rt->addr.dev_addr);
+		ret = cma_translate_addr(cma_src_addr(id_priv), &rt->addr.dev_addr);
 		if (ret)
 			goto err;
 	}
 	rdma_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
 
-	id_priv = container_of(id, struct rdma_id_private, id);
 	id_priv->state = RDMA_CM_CONNECT;
 	return id_priv;
 
@@ -1139,9 +1212,6 @@ static struct rdma_id_private *cma_new_u
 {
 	struct rdma_id_private *id_priv;
 	struct rdma_cm_id *id;
-	union cma_ip_addr *src, *dst;
-	__be16 port;
-	u8 ip_ver;
 	int ret;
 
 	id = rdma_create_id(listen_id->event_handler, listen_id->context,
@@ -1149,22 +1219,16 @@ static struct rdma_id_private *cma_new_u
 	if (IS_ERR(id))
 		return NULL;
 
-
-	if (cma_get_net_info(ib_event->private_data, listen_id->ps,
-			     &ip_ver, &port, &src, &dst))
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (cma_save_net_info(id, listen_id, ib_event))
 		goto err;
 
-	cma_save_net_info(&id->route.addr, &listen_id->route.addr,
-			  ip_ver, port, src, dst);
-
 	if (!cma_any_addr((struct sockaddr *) &id->route.addr.src_addr)) {
-		ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr,
-					&id->route.addr.dev_addr);
+		ret = cma_translate_addr(cma_src_addr(id_priv), &id->route.addr.dev_addr);
 		if (ret)
 			goto err;
 	}
 
-	id_priv = container_of(id, struct rdma_id_private, id);
 	id_priv->state = RDMA_CM_CONNECT;
 	return id_priv;
 err:
@@ -1210,7 +1274,7 @@ static int cma_req_handler(struct ib_cm_
 		return -ECONNABORTED;
 
 	memset(&event, 0, sizeof event);
-	offset = cma_user_data_offset(listen_id->id.ps);
+	offset = cma_user_data_offset(listen_id);
 	event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
 	if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED) {
 		conn_id = cma_new_udp_id(&listen_id->id, ib_event);
@@ -1272,58 +1336,44 @@ err1:
 	return ret;
 }
 
-static __be64 cma_get_service_id(enum rdma_port_space ps, struct sockaddr *addr)
+__be64 rdma_get_service_id(struct rdma_cm_id *id, struct sockaddr *addr)
 {
-	return cpu_to_be64(((u64)ps << 16) + be16_to_cpu(cma_port(addr)));
+	if (addr->sa_family == AF_IB)
+		return ((struct sockaddr_ib *) addr)->sib_sid;
+
+	return cpu_to_be64(((u64)id->ps << 16) + be16_to_cpu(cma_port(addr)));
 }
+EXPORT_SYMBOL(rdma_get_service_id);
 
 static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr,
 				 struct ib_cm_compare_data *compare)
 {
 	struct cma_hdr *cma_data, *cma_mask;
-	struct sdp_hh *sdp_data, *sdp_mask;
 	__be32 ip4_addr;
 	struct in6_addr ip6_addr;
 
 	memset(compare, 0, sizeof *compare);
 	cma_data = (void *) compare->data;
 	cma_mask = (void *) compare->mask;
-	sdp_data = (void *) compare->data;
-	sdp_mask = (void *) compare->mask;
 
 	switch (addr->sa_family) {
 	case AF_INET:
 		ip4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
-		if (ps == RDMA_PS_SDP) {
-			sdp_set_ip_ver(sdp_data, 4);
-			sdp_set_ip_ver(sdp_mask, 0xF);
-			sdp_data->dst_addr.ip4.addr = ip4_addr;
-			sdp_mask->dst_addr.ip4.addr = htonl(~0);
-		} else {
-			cma_set_ip_ver(cma_data, 4);
-			cma_set_ip_ver(cma_mask, 0xF);
-			if (!cma_any_addr(addr)) {
-				cma_data->dst_addr.ip4.addr = ip4_addr;
-				cma_mask->dst_addr.ip4.addr = htonl(~0);
-			}
+		cma_set_ip_ver(cma_data, 4);
+		cma_set_ip_ver(cma_mask, 0xF);
+		if (!cma_any_addr(addr)) {
+			cma_data->dst_addr.ip4.addr = ip4_addr;
+			cma_mask->dst_addr.ip4.addr = htonl(~0);
 		}
 		break;
 	case AF_INET6:
 		ip6_addr = ((struct sockaddr_in6 *) addr)->sin6_addr;
-		if (ps == RDMA_PS_SDP) {
-			sdp_set_ip_ver(sdp_data, 6);
-			sdp_set_ip_ver(sdp_mask, 0xF);
-			sdp_data->dst_addr.ip6 = ip6_addr;
-			memset(&sdp_mask->dst_addr.ip6, 0xFF,
-			       sizeof sdp_mask->dst_addr.ip6);
-		} else {
-			cma_set_ip_ver(cma_data, 6);
-			cma_set_ip_ver(cma_mask, 0xF);
-			if (!cma_any_addr(addr)) {
-				cma_data->dst_addr.ip6 = ip6_addr;
-				memset(&cma_mask->dst_addr.ip6, 0xFF,
-				       sizeof cma_mask->dst_addr.ip6);
-			}
+		cma_set_ip_ver(cma_data, 6);
+		cma_set_ip_ver(cma_mask, 0xF);
+		if (!cma_any_addr(addr)) {
+			cma_data->dst_addr.ip6 = ip6_addr;
+			memset(&cma_mask->dst_addr.ip6, 0xFF,
+			       sizeof cma_mask->dst_addr.ip6);
 		}
 		break;
 	default:
@@ -1347,9 +1397,9 @@ static int cma_iw_handler(struct iw_cm_i
 		event.event = RDMA_CM_EVENT_DISCONNECTED;
 		break;
 	case IW_CM_EVENT_CONNECT_REPLY:
-		sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
+		sin = (struct sockaddr_in *) cma_src_addr(id_priv);
 		*sin = iw_event->local_addr;
-		sin = (struct sockaddr_in *) &id_priv->id.route.addr.dst_addr;
+		sin = (struct sockaddr_in *) cma_dst_addr(id_priv);
 		*sin = iw_event->remote_addr;
 		switch (iw_event->status) {
 		case 0:
@@ -1447,9 +1497,9 @@ static int iw_conn_req_handler(struct iw
 	cm_id->context = conn_id;
 	cm_id->cm_handler = cma_iw_handler;
 
-	sin = (struct sockaddr_in *) &new_cm_id->route.addr.src_addr;
+	sin = (struct sockaddr_in *) cma_src_addr(conn_id);
 	*sin = iw_event->local_addr;
-	sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr;
+	sin = (struct sockaddr_in *) cma_dst_addr(conn_id);
 	*sin = iw_event->remote_addr;
 
 	ret = ib_query_device(conn_id->id.device, &attr);
@@ -1506,8 +1556,8 @@ static int cma_ib_listen(struct rdma_id_
 
 	id_priv->cm_id.ib = id;
 
-	addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
-	svc_id = cma_get_service_id(id_priv->id.ps, addr);
+	addr = cma_src_addr(id_priv);
+	svc_id = rdma_get_service_id(&id_priv->id, addr);
 	if (cma_any_addr(addr) && !id_priv->afonly)
 		ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL);
 	else {
@@ -1537,7 +1587,7 @@ static int cma_iw_listen(struct rdma_id_
 
 	id_priv->cm_id.iw = id;
 
-	sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
+	sin = (struct sockaddr_in *) cma_src_addr(id_priv);
 	id_priv->cm_id.iw->local_addr = *sin;
 
 	ret = iw_cm_listen(id_priv->cm_id.iw, backlog);
@@ -1567,6 +1617,10 @@ static void cma_listen_on_dev(struct rdm
 	struct rdma_cm_id *id;
 	int ret;
 
+	if (cma_family(id_priv) == AF_IB &&
+	    rdma_node_get_transport(cma_dev->device->node_type) != RDMA_TRANSPORT_IB)
+		return;
+
 	id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps,
 			    id_priv->id.qp_type);
 	if (IS_ERR(id))
@@ -1575,8 +1629,8 @@ static void cma_listen_on_dev(struct rdm
 	dev_id_priv = container_of(id, struct rdma_id_private, id);
 
 	dev_id_priv->state = RDMA_CM_ADDR_BOUND;
-	memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr,
-	       ip_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr));
+	memcpy(cma_src_addr(dev_id_priv), cma_src_addr(id_priv),
+	       rdma_addr_size(cma_src_addr(id_priv)));
 
 	cma_attach_to_dev(dev_id_priv, cma_dev);
 	list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list);
@@ -1634,31 +1688,39 @@ static void cma_query_handler(int status
 static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
 			      struct cma_work *work)
 {
-	struct rdma_addr *addr = &id_priv->id.route.addr;
+	struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
 	struct ib_sa_path_rec path_rec;
 	ib_sa_comp_mask comp_mask;
 	struct sockaddr_in6 *sin6;
+	struct sockaddr_ib *sib;
 
 	memset(&path_rec, 0, sizeof path_rec);
-	rdma_addr_get_sgid(&addr->dev_addr, &path_rec.sgid);
-	rdma_addr_get_dgid(&addr->dev_addr, &path_rec.dgid);
-	path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr));
+	rdma_addr_get_sgid(dev_addr, &path_rec.sgid);
+	rdma_addr_get_dgid(dev_addr, &path_rec.dgid);
+	path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
 	path_rec.numb_path = 1;
 	path_rec.reversible = 1;
-	path_rec.service_id = cma_get_service_id(id_priv->id.ps,
-							(struct sockaddr *) &addr->dst_addr);
+	path_rec.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv));
 
 	comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
 		    IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
 		    IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID;
 
-	if (addr->src_addr.ss_family == AF_INET) {
+	switch (cma_family(id_priv)) {
+	case AF_INET:
 		path_rec.qos_class = cpu_to_be16((u16) id_priv->tos);
 		comp_mask |= IB_SA_PATH_REC_QOS_CLASS;
-	} else {
-		sin6 = (struct sockaddr_in6 *) &addr->src_addr;
+		break;
+	case AF_INET6:
+		sin6 = (struct sockaddr_in6 *) cma_src_addr(id_priv);
 		path_rec.traffic_class = (u8) (be32_to_cpu(sin6->sin6_flowinfo) >> 20);
 		comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS;
+		break;
+	case AF_IB:
+		sib = (struct sockaddr_ib *) cma_src_addr(id_priv);
+		path_rec.traffic_class = (u8) (be32_to_cpu(sib->sib_flowinfo) >> 20);
+		comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS;
+		break;
 	}
 
 	id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device,
@@ -1800,14 +1862,9 @@ static int cma_resolve_iboe_route(struct
 	struct rdma_addr *addr = &route->addr;
 	struct cma_work *work;
 	int ret;
-	struct sockaddr_in *src_addr = (struct sockaddr_in *)&route->addr.src_addr;
-	struct sockaddr_in *dst_addr = (struct sockaddr_in *)&route->addr.dst_addr;
 	struct net_device *ndev = NULL;
 	u16 vid;
 
-	if (src_addr->sin_family != dst_addr->sin_family)
-		return -EINVAL;
-
 	work = kzalloc(sizeof *work, GFP_KERNEL);
 	if (!work)
 		return -ENOMEM;
@@ -1913,28 +1970,57 @@ err:
 }
 EXPORT_SYMBOL(rdma_resolve_route);
 
+static void cma_set_loopback(struct sockaddr *addr)
+{
+	switch (addr->sa_family) {
+	case AF_INET:
+		((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+		break;
+	case AF_INET6:
+		ipv6_addr_set(&((struct sockaddr_in6 *) addr)->sin6_addr,
+			      0, 0, 0, htonl(1));
+		break;
+	default:
+		ib_addr_set(&((struct sockaddr_ib *) addr)->sib_addr,
+			    0, 0, 0, htonl(1));
+		break;
+	}
+}
+
 static int cma_bind_loopback(struct rdma_id_private *id_priv)
 {
-	struct cma_device *cma_dev;
+	struct cma_device *cma_dev, *cur_dev;
 	struct ib_port_attr port_attr;
 	union ib_gid gid;
 	u16 pkey;
 	int ret;
 	u8 p;
 
+	cma_dev = NULL;
 	mutex_lock(&lock);
-	if (list_empty(&dev_list)) {
+	list_for_each_entry(cur_dev, &dev_list, list) {
+		if (cma_family(id_priv) == AF_IB &&
+		    rdma_node_get_transport(cur_dev->device->node_type) != RDMA_TRANSPORT_IB)
+			continue;
+
+		if (!cma_dev)
+			cma_dev = cur_dev;
+
+		for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) {
+			if (!ib_query_port(cur_dev->device, p, &port_attr) &&
+			    port_attr.state == IB_PORT_ACTIVE) {
+				cma_dev = cur_dev;
+				goto port_found;
+			}
+		}
+	}
+
+	if (!cma_dev) {
 		ret = -ENODEV;
 		goto out;
 	}
-	list_for_each_entry(cma_dev, &dev_list, list)
-		for (p = 1; p <= cma_dev->device->phys_port_cnt; ++p)
-			if (!ib_query_port(cma_dev->device, p, &port_attr) &&
-			    port_attr.state == IB_PORT_ACTIVE)
-				goto port_found;
 
 	p = 1;
-	cma_dev = list_entry(dev_list.next, struct cma_device, list);
 
 port_found:
 	ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid);
@@ -1953,6 +2039,7 @@ port_found:
 	ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
 	id_priv->id.port_num = p;
 	cma_attach_to_dev(id_priv, cma_dev);
+	cma_set_loopback(cma_src_addr(id_priv));
 out:
 	mutex_unlock(&lock);
 	return ret;
@@ -1980,8 +2067,7 @@ static void addr_handler(int status, str
 		event.event = RDMA_CM_EVENT_ADDR_ERROR;
 		event.status = status;
 	} else {
-		memcpy(&id_priv->id.route.addr.src_addr, src_addr,
-		       ip_addr_size(src_addr));
+		memcpy(cma_src_addr(id_priv), src_addr, rdma_addr_size(src_addr));
 		event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
 	}
 
@@ -2000,7 +2086,6 @@ out:
 static int cma_resolve_loopback(struct rdma_id_private *id_priv)
 {
 	struct cma_work *work;
-	struct sockaddr *src, *dst;
 	union ib_gid gid;
 	int ret;
 
@@ -2017,18 +2102,36 @@ static int cma_resolve_loopback(struct r
 	rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
 	rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
 
-	src = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
-	if (cma_zero_addr(src)) {
-		dst = (struct sockaddr *) &id_priv->id.route.addr.dst_addr;
-		if ((src->sa_family = dst->sa_family) == AF_INET) {
-			((struct sockaddr_in *)src)->sin_addr =
-				((struct sockaddr_in *)dst)->sin_addr;
-		} else {
-			((struct sockaddr_in6 *)src)->sin6_addr =
-				((struct sockaddr_in6 *)dst)->sin6_addr;
-		}
+	work->id = id_priv;
+	INIT_WORK(&work->work, cma_work_handler);
+	work->old_state = RDMA_CM_ADDR_QUERY;
+	work->new_state = RDMA_CM_ADDR_RESOLVED;
+	work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
+	queue_work(cma_wq, &work->work);
+	return 0;
+err:
+	kfree(work);
+	return ret;
+}
+
+static int cma_resolve_ib_addr(struct rdma_id_private *id_priv)
+{
+	struct cma_work *work;
+	int ret;
+
+	work = kzalloc(sizeof *work, GFP_KERNEL);
+	if (!work)
+		return -ENOMEM;
+
+	if (!id_priv->cma_dev) {
+		ret = cma_resolve_ib_dev(id_priv);
+		if (ret)
+			goto err;
 	}
 
+	rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, (union ib_gid *)
+		&(((struct sockaddr_ib *) &id_priv->id.route.addr.dst_addr)->sib_addr));
+
 	work->id = id_priv;
 	INIT_WORK(&work->work, cma_work_handler);
 	work->old_state = RDMA_CM_ADDR_QUERY;
@@ -2046,9 +2149,13 @@ static int cma_bind_addr(struct rdma_cm_
 {
 	if (!src_addr || !src_addr->sa_family) {
 		src_addr = (struct sockaddr *) &id->route.addr.src_addr;
-		if ((src_addr->sa_family = dst_addr->sa_family) == AF_INET6) {
+		src_addr->sa_family = dst_addr->sa_family;
+		if (dst_addr->sa_family == AF_INET6) {
 			((struct sockaddr_in6 *) src_addr)->sin6_scope_id =
 				((struct sockaddr_in6 *) dst_addr)->sin6_scope_id;
+		} else if (dst_addr->sa_family == AF_IB) {
+			((struct sockaddr_ib *) src_addr)->sib_pkey =
+				((struct sockaddr_ib *) dst_addr)->sib_pkey;
 		}
 	}
 	return rdma_bind_addr(id, src_addr);
@@ -2067,17 +2174,25 @@ int rdma_resolve_addr(struct rdma_cm_id
 			return ret;
 	}
 
+	if (cma_family(id_priv) != dst_addr->sa_family)
+		return -EINVAL;
+
 	if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY))
 		return -EINVAL;
 
 	atomic_inc(&id_priv->refcount);
-	memcpy(&id->route.addr.dst_addr, dst_addr, ip_addr_size(dst_addr));
-	if (cma_any_addr(dst_addr))
+	memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
+	if (cma_any_addr(dst_addr)) {
 		ret = cma_resolve_loopback(id_priv);
-	else
-		ret = rdma_resolve_ip(&addr_client, (struct sockaddr *) &id->route.addr.src_addr,
-				      dst_addr, &id->route.addr.dev_addr,
-				      timeout_ms, addr_handler, id_priv);
+	} else {
+		if (dst_addr->sa_family == AF_IB) {
+			ret = cma_resolve_ib_addr(id_priv);
+		} else {
+			ret = rdma_resolve_ip(&addr_client, cma_src_addr(id_priv),
+					      dst_addr, &id->route.addr.dev_addr,
+					      timeout_ms, addr_handler, id_priv);
+		}
+	}
 	if (ret)
 		goto err;
 
@@ -2097,7 +2212,7 @@ int rdma_set_reuseaddr(struct rdma_cm_id
 
 	id_priv = container_of(id, struct rdma_id_private, id);
 	spin_lock_irqsave(&id_priv->lock, flags);
-	if (id_priv->state == RDMA_CM_IDLE) {
+	if (reuse || id_priv->state == RDMA_CM_IDLE) {
 		id_priv->reuseaddr = reuse;
 		ret = 0;
 	} else {
@@ -2131,10 +2246,29 @@ EXPORT_SYMBOL(rdma_set_afonly);
 static void cma_bind_port(struct rdma_bind_list *bind_list,
 			  struct rdma_id_private *id_priv)
 {
-	struct sockaddr_in *sin;
+	struct sockaddr *addr;
+	struct sockaddr_ib *sib;
+	u64 sid, mask;
+	__be16 port;
 
-	sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
-	sin->sin_port = htons(bind_list->port);
+	addr = cma_src_addr(id_priv);
+	port = htons(bind_list->port);
+
+	switch (addr->sa_family) {
+	case AF_INET:
+		((struct sockaddr_in *) addr)->sin_port = port;
+		break;
+	case AF_INET6:
+		((struct sockaddr_in6 *) addr)->sin6_port = port;
+		break;
+	case AF_IB:
+		sib = (struct sockaddr_ib *) addr;
+		sid = be64_to_cpu(sib->sib_sid);
+		mask = be64_to_cpu(sib->sib_sid_mask);
+		sib->sib_sid = cpu_to_be64((sid & mask) | (u64) ntohs(port));
+		sib->sib_sid_mask = cpu_to_be64(~0ULL);
+		break;
+	}
 	id_priv->bind_list = bind_list;
 	hlist_add_head(&id_priv->node, &bind_list->owners);
 }
@@ -2205,7 +2339,7 @@ static int cma_check_port(struct rdma_bi
 	struct rdma_id_private *cur_id;
 	struct sockaddr *addr, *cur_addr;
 
-	addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
+	addr = cma_src_addr(id_priv);
 	hlist_for_each_entry(cur_id, &bind_list->owners, node) {
 		if (id_priv == cur_id)
 			continue;
@@ -2214,7 +2348,7 @@ static int cma_check_port(struct rdma_bi
 		    cur_id->reuseaddr)
 			continue;
 
-		cur_addr = (struct sockaddr *) &cur_id->id.route.addr.src_addr;
+		cur_addr = cma_src_addr(cur_id);
 		if (id_priv->afonly && cur_id->afonly &&
 		    (addr->sa_family != cur_addr->sa_family))
 			continue;
@@ -2234,7 +2368,7 @@ static int cma_use_port(struct idr *ps,
 	unsigned short snum;
 	int ret;
 
-	snum = ntohs(cma_port((struct sockaddr *) &id_priv->id.route.addr.src_addr));
+	snum = ntohs(cma_port(cma_src_addr(id_priv)));
 	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
 		return -EACCES;
 
@@ -2261,33 +2395,67 @@ static int cma_bind_listen(struct rdma_i
 	return ret;
 }
 
-static int cma_get_port(struct rdma_id_private *id_priv)
+static struct idr *cma_select_inet_ps(struct rdma_id_private *id_priv)
 {
-	struct idr *ps;
-	int ret;
-
 	switch (id_priv->id.ps) {
-	case RDMA_PS_SDP:
-		ps = &sdp_ps;
-		break;
 	case RDMA_PS_TCP:
-		ps = &tcp_ps;
-		break;
+		return &tcp_ps;
 	case RDMA_PS_UDP:
-		ps = &udp_ps;
-		break;
+		return &udp_ps;
 	case RDMA_PS_IPOIB:
-		ps = &ipoib_ps;
-		break;
+		return &ipoib_ps;
 	case RDMA_PS_IB:
-		ps = &ib_ps;
-		break;
+		return &ib_ps;
 	default:
-		return -EPROTONOSUPPORT;
+		return NULL;
 	}
+}
+
+static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv)
+{
+	struct idr *ps = NULL;
+	struct sockaddr_ib *sib;
+	u64 sid_ps, mask, sid;
+
+	sib = (struct sockaddr_ib *) cma_src_addr(id_priv);
+	mask = be64_to_cpu(sib->sib_sid_mask) & RDMA_IB_IP_PS_MASK;
+	sid = be64_to_cpu(sib->sib_sid) & mask;
+
+	if ((id_priv->id.ps == RDMA_PS_IB) && (sid == (RDMA_IB_IP_PS_IB & mask))) {
+		sid_ps = RDMA_IB_IP_PS_IB;
+		ps = &ib_ps;
+	} else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_TCP)) &&
+		   (sid == (RDMA_IB_IP_PS_TCP & mask))) {
+		sid_ps = RDMA_IB_IP_PS_TCP;
+		ps = &tcp_ps;
+	} else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_UDP)) &&
+		   (sid == (RDMA_IB_IP_PS_UDP & mask))) {
+		sid_ps = RDMA_IB_IP_PS_UDP;
+		ps = &udp_ps;
+	}
+
+	if (ps) {
+		sib->sib_sid = cpu_to_be64(sid_ps | ntohs(cma_port((struct sockaddr *) sib)));
+		sib->sib_sid_mask = cpu_to_be64(RDMA_IB_IP_PS_MASK |
+						be64_to_cpu(sib->sib_sid_mask));
+	}
+	return ps;
+}
+
+static int cma_get_port(struct rdma_id_private *id_priv)
+{
+	struct idr *ps;
+	int ret;
+
+	if (cma_family(id_priv) != AF_IB)
+		ps = cma_select_inet_ps(id_priv);
+	else
+		ps = cma_select_ib_ps(id_priv);
+	if (!ps)
+		return -EPROTONOSUPPORT;
 
 	mutex_lock(&lock);
-	if (cma_any_port((struct sockaddr *) &id_priv->id.route.addr.src_addr))
+	if (cma_any_port(cma_src_addr(id_priv)))
 		ret = cma_alloc_any_port(ps, id_priv);
 	else
 		ret = cma_use_port(ps, id_priv);
@@ -2322,8 +2490,8 @@ int rdma_listen(struct rdma_cm_id *id, i
 
 	id_priv = container_of(id, struct rdma_id_private, id);
 	if (id_priv->state == RDMA_CM_IDLE) {
-		((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET;
-		ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr);
+		id->route.addr.src_addr.ss_family = AF_INET;
+		ret = rdma_bind_addr(id, cma_src_addr(id_priv));
 		if (ret)
 			return ret;
 	}
@@ -2370,7 +2538,8 @@ int rdma_bind_addr(struct rdma_cm_id *id
 	struct rdma_id_private *id_priv;
 	int ret;
 
-	if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6)
+	if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6 &&
+	    addr->sa_family != AF_IB)
 		return -EAFNOSUPPORT;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
@@ -2382,7 +2551,7 @@ int rdma_bind_addr(struct rdma_cm_id *id
 		goto err1;
 
 	if (!cma_any_addr(addr)) {
-		ret = rdma_translate_ip(addr, &id->route.addr.dev_addr);
+		ret = cma_translate_addr(addr, &id->route.addr.dev_addr);
 		if (ret)
 			goto err1;
 
@@ -2391,7 +2560,7 @@ int rdma_bind_addr(struct rdma_cm_id *id
 			goto err1;
 	}
 
-	memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr));
+	memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr));
 	if (!(id_priv->options & (1 << CMA_OPTION_AFONLY))) {
 		if (addr->sa_family == AF_INET)
 			id_priv->afonly = 1;
@@ -2414,62 +2583,32 @@ err1:
 }
 EXPORT_SYMBOL(rdma_bind_addr);
 
-static int cma_format_hdr(void *hdr, enum rdma_port_space ps,
-			  struct rdma_route *route)
+static int cma_format_hdr(void *hdr, struct rdma_id_private *id_priv)
 {
 	struct cma_hdr *cma_hdr;
-	struct sdp_hh *sdp_hdr;
 
-	if (route->addr.src_addr.ss_family == AF_INET) {
+	cma_hdr = hdr;
+	cma_hdr->cma_version = CMA_VERSION;
+	if (cma_family(id_priv) == AF_INET) {
 		struct sockaddr_in *src4, *dst4;
 
-		src4 = (struct sockaddr_in *) &route->addr.src_addr;
-		dst4 = (struct sockaddr_in *) &route->addr.dst_addr;
+		src4 = (struct sockaddr_in *) cma_src_addr(id_priv);
+		dst4 = (struct sockaddr_in *) cma_dst_addr(id_priv);
 
-		switch (ps) {
-		case RDMA_PS_SDP:
-			sdp_hdr = hdr;
-			if (sdp_get_majv(sdp_hdr->sdp_version) != SDP_MAJ_VERSION)
-				return -EINVAL;
-			sdp_set_ip_ver(sdp_hdr, 4);
-			sdp_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr;
-			sdp_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr;
-			sdp_hdr->port = src4->sin_port;
-			break;
-		default:
-			cma_hdr = hdr;
-			cma_hdr->cma_version = CMA_VERSION;
-			cma_set_ip_ver(cma_hdr, 4);
-			cma_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr;
-			cma_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr;
-			cma_hdr->port = src4->sin_port;
-			break;
-		}
-	} else {
+		cma_set_ip_ver(cma_hdr, 4);
+		cma_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr;
+		cma_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr;
+		cma_hdr->port = src4->sin_port;
+	} else if (cma_family(id_priv) == AF_INET6) {
 		struct sockaddr_in6 *src6, *dst6;
 
-		src6 = (struct sockaddr_in6 *) &route->addr.src_addr;
-		dst6 = (struct sockaddr_in6 *) &route->addr.dst_addr;
+		src6 = (struct sockaddr_in6 *) cma_src_addr(id_priv);
+		dst6 = (struct sockaddr_in6 *) cma_dst_addr(id_priv);
 
-		switch (ps) {
-		case RDMA_PS_SDP:
-			sdp_hdr = hdr;
-			if (sdp_get_majv(sdp_hdr->sdp_version) != SDP_MAJ_VERSION)
-				return -EINVAL;
-			sdp_set_ip_ver(sdp_hdr, 6);
-			sdp_hdr->src_addr.ip6 = src6->sin6_addr;
-			sdp_hdr->dst_addr.ip6 = dst6->sin6_addr;
-			sdp_hdr->port = src6->sin6_port;
-			break;
-		default:
-			cma_hdr = hdr;
-			cma_hdr->cma_version = CMA_VERSION;
-			cma_set_ip_ver(cma_hdr, 6);
-			cma_hdr->src_addr.ip6 = src6->sin6_addr;
-			cma_hdr->dst_addr.ip6 = dst6->sin6_addr;
-			cma_hdr->port = src6->sin6_port;
-			break;
-		}
+		cma_set_ip_ver(cma_hdr, 6);
+		cma_hdr->src_addr.ip6 = src6->sin6_addr;
+		cma_hdr->dst_addr.ip6 = dst6->sin6_addr;
+		cma_hdr->port = src6->sin6_port;
 	}
 	return 0;
 }
@@ -2499,15 +2638,10 @@ static int cma_sidr_rep_handler(struct i
 			event.status = ib_event->param.sidr_rep_rcvd.status;
 			break;
 		}
-		ret = cma_set_qkey(id_priv);
+		ret = cma_set_qkey(id_priv, rep->qkey);
 		if (ret) {
 			event.event = RDMA_CM_EVENT_ADDR_ERROR;
-			event.status = -EINVAL;
-			break;
-		}
-		if (id_priv->qkey != rep->qkey) {
-			event.event = RDMA_CM_EVENT_UNREACHABLE;
-			event.status = -EINVAL;
+			event.status = ret;
 			break;
 		}
 		ib_init_ah_from_path(id_priv->id.device, id_priv->id.port_num,
@@ -2542,27 +2676,34 @@ static int cma_resolve_ib_udp(struct rdm
 			      struct rdma_conn_param *conn_param)
 {
 	struct ib_cm_sidr_req_param req;
-	struct rdma_route *route;
 	struct ib_cm_id	*id;
-	int ret;
+	void *private_data;
+	int offset, ret;
 
-	req.private_data_len = sizeof(struct cma_hdr) +
-			       conn_param->private_data_len;
+	memset(&req, 0, sizeof req);
+	offset = cma_user_data_offset(id_priv);
+	req.private_data_len = offset + conn_param->private_data_len;
 	if (req.private_data_len < conn_param->private_data_len)
 		return -EINVAL;
 
-	req.private_data = kzalloc(req.private_data_len, GFP_ATOMIC);
-	if (!req.private_data)
-		return -ENOMEM;
+	if (req.private_data_len) {
+		private_data = kzalloc(req.private_data_len, GFP_ATOMIC);
+		if (!private_data)
+			return -ENOMEM;
+	} else {
+		private_data = NULL;
+	}
 
 	if (conn_param->private_data && conn_param->private_data_len)
-		memcpy((void *) req.private_data + sizeof(struct cma_hdr),
-		       conn_param->private_data, conn_param->private_data_len);
+		memcpy(private_data + offset, conn_param->private_data,
+		       conn_param->private_data_len);
 
-	route = &id_priv->id.route;
-	ret = cma_format_hdr((void *) req.private_data, id_priv->id.ps, route);
-	if (ret)
-		goto out;
+	if (private_data) {
+		ret = cma_format_hdr(private_data, id_priv);
+		if (ret)
+			goto out;
+		req.private_data = private_data;
+	}
 
 	id = ib_create_cm_id(id_priv->id.device, cma_sidr_rep_handler,
 			     id_priv);
@@ -2572,9 +2713,8 @@ static int cma_resolve_ib_udp(struct rdm
 	}
 	id_priv->cm_id.ib = id;
 
-	req.path = route->path_rec;
-	req.service_id = cma_get_service_id(id_priv->id.ps,
-					    (struct sockaddr *) &route->addr.dst_addr);
+	req.path = id_priv->id.route.path_rec;
+	req.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv));
 	req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8);
 	req.max_cm_retries = CMA_MAX_CM_RETRIES;
 
@@ -2584,7 +2724,7 @@ static int cma_resolve_ib_udp(struct rdm
 		id_priv->cm_id.ib = NULL;
 	}
 out:
-	kfree(req.private_data);
+	kfree(private_data);
 	return ret;
 }
 
@@ -2598,14 +2738,18 @@ static int cma_connect_ib(struct rdma_id
 	int offset, ret;
 
 	memset(&req, 0, sizeof req);
-	offset = cma_user_data_offset(id_priv->id.ps);
+	offset = cma_user_data_offset(id_priv);
 	req.private_data_len = offset + conn_param->private_data_len;
 	if (req.private_data_len < conn_param->private_data_len)
 		return -EINVAL;
 
-	private_data = kzalloc(req.private_data_len, GFP_ATOMIC);
-	if (!private_data)
-		return -ENOMEM;
+	if (req.private_data_len) {
+		private_data = kzalloc(req.private_data_len, GFP_ATOMIC);
+		if (!private_data)
+			return -ENOMEM;
+	} else {
+		private_data = NULL;
+	}
 
 	if (conn_param->private_data && conn_param->private_data_len)
 		memcpy(private_data + offset, conn_param->private_data,
@@ -2619,17 +2763,18 @@ static int cma_connect_ib(struct rdma_id
 	id_priv->cm_id.ib = id;
 
 	route = &id_priv->id.route;
-	ret = cma_format_hdr(private_data, id_priv->id.ps, route);
-	if (ret)
-		goto out;
-	req.private_data = private_data;
+	if (private_data) {
+		ret = cma_format_hdr(private_data, id_priv);
+		if (ret)
+			goto out;
+		req.private_data = private_data;
+	}
 
 	req.primary_path = &route->path_rec[0];
 	if (route->num_paths == 2)
 		req.alternate_path = &route->path_rec[1];
 
-	req.service_id = cma_get_service_id(id_priv->id.ps,
-					    (struct sockaddr *) &route->addr.dst_addr);
+	req.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv));
 	req.qp_num = id_priv->qp_num;
 	req.qp_type = id_priv->id.qp_type;
 	req.starting_psn = id_priv->seq_num;
@@ -2668,10 +2813,10 @@ static int cma_connect_iw(struct rdma_id
 
 	id_priv->cm_id.iw = cm_id;
 
-	sin = (struct sockaddr_in*) &id_priv->id.route.addr.src_addr;
+	sin = (struct sockaddr_in *) cma_src_addr(id_priv);
 	cm_id->local_addr = *sin;
 
-	sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr;
+	sin = (struct sockaddr_in *) cma_dst_addr(id_priv);
 	cm_id->remote_addr = *sin;
 
 	ret = cma_modify_qp_rtr(id_priv, conn_param);
@@ -2789,7 +2934,7 @@ static int cma_accept_iw(struct rdma_id_
 }
 
 static int cma_send_sidr_rep(struct rdma_id_private *id_priv,
-			     enum ib_cm_sidr_status status,
+			     enum ib_cm_sidr_status status, u32 qkey,
 			     const void *private_data, int private_data_len)
 {
 	struct ib_cm_sidr_rep_param rep;
@@ -2798,7 +2943,7 @@ static int cma_send_sidr_rep(struct rdma
 	memset(&rep, 0, sizeof rep);
 	rep.status = status;
 	if (status == IB_SIDR_SUCCESS) {
-		ret = cma_set_qkey(id_priv);
+		ret = cma_set_qkey(id_priv, qkey);
 		if (ret)
 			return ret;
 		rep.qp_num = id_priv->qp_num;
@@ -2832,11 +2977,12 @@ int rdma_accept(struct rdma_cm_id *id, s
 		if (id->qp_type == IB_QPT_UD) {
 			if (conn_param)
 				ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS,
+							conn_param->qkey,
 							conn_param->private_data,
 							conn_param->private_data_len);
 			else
 				ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS,
-							NULL, 0);
+							0, NULL, 0);
 		} else {
 			if (conn_param)
 				ret = cma_accept_ib(id_priv, conn_param);
@@ -2897,7 +3043,7 @@ int rdma_reject(struct rdma_cm_id *id, c
 	switch (rdma_node_get_transport(id->device->node_type)) {
 	case RDMA_TRANSPORT_IB:
 		if (id->qp_type == IB_QPT_UD)
-			ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT,
+			ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT, 0,
 						private_data, private_data_len);
 		else
 			ret = ib_send_cm_rej(id_priv->cm_id.ib,
@@ -2958,6 +3104,8 @@ static int cma_ib_mc_handler(int status,
 	    cma_disable_callback(id_priv, RDMA_CM_ADDR_RESOLVED))
 		return 0;
 
+	if (!status)
+		status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey));
 	mutex_lock(&id_priv->qp_mutex);
 	if (!status && id_priv->id.qp)
 		status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid,
@@ -3004,6 +3152,8 @@ static void cma_set_mgid(struct rdma_id_
 								 0xFF10A01B)) {
 		/* IPv6 address is an SA assigned MGID. */
 		memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
+	} else if (addr->sa_family == AF_IB) {
+		memcpy(mgid, &((struct sockaddr_ib *) addr)->sib_addr, sizeof *mgid);
 	} else if ((addr->sa_family == AF_INET6)) {
 		ipv6_ib_mc_map(&sin6->sin6_addr, dev_addr->broadcast, mc_map);
 		if (id_priv->id.ps == RDMA_PS_UDP)
@@ -3031,9 +3181,12 @@ static int cma_join_ib_multicast(struct
 	if (ret)
 		return ret;
 
+	ret = cma_set_qkey(id_priv, 0);
+	if (ret)
+		return ret;
+
 	cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid);
-	if (id_priv->id.ps == RDMA_PS_UDP)
-		rec.qkey = cpu_to_be32(RDMA_UDP_QKEY);
+	rec.qkey = cpu_to_be32(id_priv->qkey);
 	rdma_addr_get_sgid(dev_addr, &rec.port_gid);
 	rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
 	rec.join_state = 1;
@@ -3170,7 +3323,7 @@ int rdma_join_multicast(struct rdma_cm_i
 	if (!mc)
 		return -ENOMEM;
 
-	memcpy(&mc->addr, addr, ip_addr_size(addr));
+	memcpy(&mc->addr, addr, rdma_addr_size(addr));
 	mc->context = context;
 	mc->id_priv = id_priv;
 
@@ -3215,7 +3368,7 @@ void rdma_leave_multicast(struct rdma_cm
 	id_priv = container_of(id, struct rdma_id_private, id);
 	spin_lock_irq(&id_priv->lock);
 	list_for_each_entry(mc, &id_priv->mc_list, list) {
-		if (!memcmp(&mc->addr, addr, ip_addr_size(addr))) {
+		if (!memcmp(&mc->addr, addr, rdma_addr_size(addr))) {
 			list_del(&mc->list);
 			spin_unlock_irq(&id_priv->lock);
 
@@ -3269,9 +3422,9 @@ static int cma_netdev_change(struct net_
 }
 
 static int cma_netdev_callback(struct notifier_block *self, unsigned long event,
-			       void *ctx)
+			       void *ptr)
 {
-	struct net_device *ndev = (struct net_device *)ctx;
+	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
 	struct cma_device *cma_dev;
 	struct rdma_id_private *id_priv;
 	int ret = NOTIFY_DONE;
@@ -3436,33 +3589,16 @@ static int cma_get_id_stats(struct sk_bu
 			id_stats->bound_dev_if =
 				id->route.addr.dev_addr.bound_dev_if;
 
-			if (id->route.addr.src_addr.ss_family == AF_INET) {
-				if (ibnl_put_attr(skb, nlh,
-						  sizeof(struct sockaddr_in),
-						  &id->route.addr.src_addr,
-						  RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) {
-					goto out;
-				}
-				if (ibnl_put_attr(skb, nlh,
-						  sizeof(struct sockaddr_in),
-						  &id->route.addr.dst_addr,
-						  RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) {
-					goto out;
-				}
-			} else if (id->route.addr.src_addr.ss_family == AF_INET6) {
-				if (ibnl_put_attr(skb, nlh,
-						  sizeof(struct sockaddr_in6),
-						  &id->route.addr.src_addr,
-						  RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) {
-					goto out;
-				}
-				if (ibnl_put_attr(skb, nlh,
-						  sizeof(struct sockaddr_in6),
-						  &id->route.addr.dst_addr,
-						  RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) {
-					goto out;
-				}
-			}
+			if (ibnl_put_attr(skb, nlh,
+					  rdma_addr_size(cma_src_addr(id_priv)),
+					  cma_src_addr(id_priv),
+					  RDMA_NL_RDMA_CM_ATTR_SRC_ADDR))
+				goto out;
+			if (ibnl_put_attr(skb, nlh,
+					  rdma_addr_size(cma_src_addr(id_priv)),
+					  cma_dst_addr(id_priv),
+					  RDMA_NL_RDMA_CM_ATTR_DST_ADDR))
+				goto out;
 
 			id_stats->pid		= id_priv->owner;
 			id_stats->port_space	= id->ps;
@@ -3527,7 +3663,6 @@ static void __exit cma_cleanup(void)
 	rdma_addr_unregister_client(&addr_client);
 	ib_sa_unregister_client(&sa_client);
 	destroy_workqueue(cma_wq);
-	idr_destroy(&sdp_ps);
 	idr_destroy(&tcp_ps);
 	idr_destroy(&udp_ps);
 	idr_destroy(&ipoib_ps);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/core/mad.c linux-libre-3.11-rc7-gnu/drivers/infiniband/core/mad.c
--- linux-libre-3.10-gnu/drivers/infiniband/core/mad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/core/mad.c	2013-08-25 20:43:22.000000000 -0400
@@ -2663,6 +2663,7 @@ static int ib_mad_port_start(struct ib_m
 	int ret, i;
 	struct ib_qp_attr *attr;
 	struct ib_qp *qp;
+	u16 pkey_index;
 
 	attr = kmalloc(sizeof *attr, GFP_KERNEL);
 	if (!attr) {
@@ -2670,6 +2671,11 @@ static int ib_mad_port_start(struct ib_m
 		return -ENOMEM;
 	}
 
+	ret = ib_find_pkey(port_priv->device, port_priv->port_num,
+			   IB_DEFAULT_PKEY_FULL, &pkey_index);
+	if (ret)
+		pkey_index = 0;
+
 	for (i = 0; i < IB_MAD_QPS_CORE; i++) {
 		qp = port_priv->qp_info[i].qp;
 		if (!qp)
@@ -2680,7 +2686,7 @@ static int ib_mad_port_start(struct ib_m
 		 * one is needed for the Reset to Init transition
 		 */
 		attr->qp_state = IB_QPS_INIT;
-		attr->pkey_index = 0;
+		attr->pkey_index = pkey_index;
 		attr->qkey = (qp->qp_num == 0) ? 0 : IB_QP1_QKEY;
 		ret = ib_modify_qp(qp, attr, IB_QP_STATE |
 					     IB_QP_PKEY_INDEX | IB_QP_QKEY);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/core/sa_query.c linux-libre-3.11-rc7-gnu/drivers/infiniband/core/sa_query.c
--- linux-libre-3.10-gnu/drivers/infiniband/core/sa_query.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/core/sa_query.c	2013-08-25 20:43:22.000000000 -0400
@@ -652,6 +652,12 @@ void ib_sa_unpack_path(void *attribute,
 }
 EXPORT_SYMBOL(ib_sa_unpack_path);
 
+void ib_sa_pack_path(struct ib_sa_path_rec *rec, void *attribute)
+{
+	ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, attribute);
+}
+EXPORT_SYMBOL(ib_sa_pack_path);
+
 static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
 				    int status,
 				    struct ib_sa_mad *mad)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/core/sysfs.c linux-libre-3.11-rc7-gnu/drivers/infiniband/core/sysfs.c
--- linux-libre-3.10-gnu/drivers/infiniband/core/sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/core/sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -545,8 +545,10 @@ static int add_port(struct ib_device *de
 
 	p->gid_group.name  = "gids";
 	p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len);
-	if (!p->gid_group.attrs)
+	if (!p->gid_group.attrs) {
+		ret = -ENOMEM;
 		goto err_remove_pma;
+	}
 
 	ret = sysfs_create_group(&p->kobj, &p->gid_group);
 	if (ret)
@@ -555,8 +557,10 @@ static int add_port(struct ib_device *de
 	p->pkey_group.name  = "pkeys";
 	p->pkey_group.attrs = alloc_group_attrs(show_port_pkey,
 						attr.pkey_tbl_len);
-	if (!p->pkey_group.attrs)
+	if (!p->pkey_group.attrs) {
+		ret = -ENOMEM;
 		goto err_remove_gid;
+	}
 
 	ret = sysfs_create_group(&p->kobj, &p->pkey_group);
 	if (ret)
@@ -813,7 +817,7 @@ int ib_device_register_sysfs(struct ib_d
 
 	class_dev->class      = &ib_class;
 	class_dev->parent     = device->dma_device;
-	dev_set_name(class_dev, device->name);
+	dev_set_name(class_dev, "%s", device->name);
 	dev_set_drvdata(class_dev, device);
 
 	INIT_LIST_HEAD(&device->port_list);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/core/ucma.c linux-libre-3.11-rc7-gnu/drivers/infiniband/core/ucma.c
--- linux-libre-3.10-gnu/drivers/infiniband/core/ucma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/core/ucma.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,6 +47,8 @@
 #include <rdma/ib_marshall.h>
 #include <rdma/rdma_cm.h>
 #include <rdma/rdma_cm_ib.h>
+#include <rdma/ib_addr.h>
+#include <rdma/ib.h>
 
 MODULE_AUTHOR("Sean Hefty");
 MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
@@ -510,10 +512,10 @@ static ssize_t ucma_destroy_id(struct uc
 	return ret;
 }
 
-static ssize_t ucma_bind_addr(struct ucma_file *file, const char __user *inbuf,
+static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf,
 			      int in_len, int out_len)
 {
-	struct rdma_ucm_bind_addr cmd;
+	struct rdma_ucm_bind_ip cmd;
 	struct ucma_context *ctx;
 	int ret;
 
@@ -529,24 +531,75 @@ static ssize_t ucma_bind_addr(struct ucm
 	return ret;
 }
 
+static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf,
+			 int in_len, int out_len)
+{
+	struct rdma_ucm_bind cmd;
+	struct sockaddr *addr;
+	struct ucma_context *ctx;
+	int ret;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	addr = (struct sockaddr *) &cmd.addr;
+	if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr)))
+		return -EINVAL;
+
+	ctx = ucma_get_ctx(file, cmd.id);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	ret = rdma_bind_addr(ctx->cm_id, addr);
+	ucma_put_ctx(ctx);
+	return ret;
+}
+
+static ssize_t ucma_resolve_ip(struct ucma_file *file,
+			       const char __user *inbuf,
+			       int in_len, int out_len)
+{
+	struct rdma_ucm_resolve_ip cmd;
+	struct ucma_context *ctx;
+	int ret;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	ctx = ucma_get_ctx(file, cmd.id);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
+				(struct sockaddr *) &cmd.dst_addr,
+				cmd.timeout_ms);
+	ucma_put_ctx(ctx);
+	return ret;
+}
+
 static ssize_t ucma_resolve_addr(struct ucma_file *file,
 				 const char __user *inbuf,
 				 int in_len, int out_len)
 {
 	struct rdma_ucm_resolve_addr cmd;
+	struct sockaddr *src, *dst;
 	struct ucma_context *ctx;
 	int ret;
 
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
+	src = (struct sockaddr *) &cmd.src_addr;
+	dst = (struct sockaddr *) &cmd.dst_addr;
+	if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) ||
+	    !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst)))
+		return -EINVAL;
+
 	ctx = ucma_get_ctx(file, cmd.id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
-				(struct sockaddr *) &cmd.dst_addr,
-				cmd.timeout_ms);
+	ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
 	ucma_put_ctx(ctx);
 	return ret;
 }
@@ -649,7 +702,7 @@ static ssize_t ucma_query_route(struct u
 				const char __user *inbuf,
 				int in_len, int out_len)
 {
-	struct rdma_ucm_query_route cmd;
+	struct rdma_ucm_query cmd;
 	struct rdma_ucm_query_route_resp resp;
 	struct ucma_context *ctx;
 	struct sockaddr *addr;
@@ -709,7 +762,162 @@ out:
 	return ret;
 }
 
-static void ucma_copy_conn_param(struct rdma_conn_param *dst,
+static void ucma_query_device_addr(struct rdma_cm_id *cm_id,
+				   struct rdma_ucm_query_addr_resp *resp)
+{
+	if (!cm_id->device)
+		return;
+
+	resp->node_guid = (__force __u64) cm_id->device->node_guid;
+	resp->port_num = cm_id->port_num;
+	resp->pkey = (__force __u16) cpu_to_be16(
+		     ib_addr_get_pkey(&cm_id->route.addr.dev_addr));
+}
+
+static ssize_t ucma_query_addr(struct ucma_context *ctx,
+			       void __user *response, int out_len)
+{
+	struct rdma_ucm_query_addr_resp resp;
+	struct sockaddr *addr;
+	int ret = 0;
+
+	if (out_len < sizeof(resp))
+		return -ENOSPC;
+
+	memset(&resp, 0, sizeof resp);
+
+	addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr;
+	resp.src_size = rdma_addr_size(addr);
+	memcpy(&resp.src_addr, addr, resp.src_size);
+
+	addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr;
+	resp.dst_size = rdma_addr_size(addr);
+	memcpy(&resp.dst_addr, addr, resp.dst_size);
+
+	ucma_query_device_addr(ctx->cm_id, &resp);
+
+	if (copy_to_user(response, &resp, sizeof(resp)))
+		ret = -EFAULT;
+
+	return ret;
+}
+
+static ssize_t ucma_query_path(struct ucma_context *ctx,
+			       void __user *response, int out_len)
+{
+	struct rdma_ucm_query_path_resp *resp;
+	int i, ret = 0;
+
+	if (out_len < sizeof(*resp))
+		return -ENOSPC;
+
+	resp = kzalloc(out_len, GFP_KERNEL);
+	if (!resp)
+		return -ENOMEM;
+
+	resp->num_paths = ctx->cm_id->route.num_paths;
+	for (i = 0, out_len -= sizeof(*resp);
+	     i < resp->num_paths && out_len > sizeof(struct ib_path_rec_data);
+	     i++, out_len -= sizeof(struct ib_path_rec_data)) {
+
+		resp->path_data[i].flags = IB_PATH_GMP | IB_PATH_PRIMARY |
+					   IB_PATH_BIDIRECTIONAL;
+		ib_sa_pack_path(&ctx->cm_id->route.path_rec[i],
+				&resp->path_data[i].path_rec);
+	}
+
+	if (copy_to_user(response, resp,
+			 sizeof(*resp) + (i * sizeof(struct ib_path_rec_data))))
+		ret = -EFAULT;
+
+	kfree(resp);
+	return ret;
+}
+
+static ssize_t ucma_query_gid(struct ucma_context *ctx,
+			      void __user *response, int out_len)
+{
+	struct rdma_ucm_query_addr_resp resp;
+	struct sockaddr_ib *addr;
+	int ret = 0;
+
+	if (out_len < sizeof(resp))
+		return -ENOSPC;
+
+	memset(&resp, 0, sizeof resp);
+
+	ucma_query_device_addr(ctx->cm_id, &resp);
+
+	addr = (struct sockaddr_ib *) &resp.src_addr;
+	resp.src_size = sizeof(*addr);
+	if (ctx->cm_id->route.addr.src_addr.ss_family == AF_IB) {
+		memcpy(addr, &ctx->cm_id->route.addr.src_addr, resp.src_size);
+	} else {
+		addr->sib_family = AF_IB;
+		addr->sib_pkey = (__force __be16) resp.pkey;
+		rdma_addr_get_sgid(&ctx->cm_id->route.addr.dev_addr,
+				   (union ib_gid *) &addr->sib_addr);
+		addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *)
+						    &ctx->cm_id->route.addr.src_addr);
+	}
+
+	addr = (struct sockaddr_ib *) &resp.dst_addr;
+	resp.dst_size = sizeof(*addr);
+	if (ctx->cm_id->route.addr.dst_addr.ss_family == AF_IB) {
+		memcpy(addr, &ctx->cm_id->route.addr.dst_addr, resp.dst_size);
+	} else {
+		addr->sib_family = AF_IB;
+		addr->sib_pkey = (__force __be16) resp.pkey;
+		rdma_addr_get_dgid(&ctx->cm_id->route.addr.dev_addr,
+				   (union ib_gid *) &addr->sib_addr);
+		addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *)
+						    &ctx->cm_id->route.addr.dst_addr);
+	}
+
+	if (copy_to_user(response, &resp, sizeof(resp)))
+		ret = -EFAULT;
+
+	return ret;
+}
+
+static ssize_t ucma_query(struct ucma_file *file,
+			  const char __user *inbuf,
+			  int in_len, int out_len)
+{
+	struct rdma_ucm_query cmd;
+	struct ucma_context *ctx;
+	void __user *response;
+	int ret;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	response = (void __user *)(unsigned long) cmd.response;
+	ctx = ucma_get_ctx(file, cmd.id);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	switch (cmd.option) {
+	case RDMA_USER_CM_QUERY_ADDR:
+		ret = ucma_query_addr(ctx, response, out_len);
+		break;
+	case RDMA_USER_CM_QUERY_PATH:
+		ret = ucma_query_path(ctx, response, out_len);
+		break;
+	case RDMA_USER_CM_QUERY_GID:
+		ret = ucma_query_gid(ctx, response, out_len);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+
+	ucma_put_ctx(ctx);
+	return ret;
+}
+
+static void ucma_copy_conn_param(struct rdma_cm_id *id,
+				 struct rdma_conn_param *dst,
 				 struct rdma_ucm_conn_param *src)
 {
 	dst->private_data = src->private_data;
@@ -721,6 +929,7 @@ static void ucma_copy_conn_param(struct
 	dst->rnr_retry_count = src->rnr_retry_count;
 	dst->srq = src->srq;
 	dst->qp_num = src->qp_num;
+	dst->qkey = (id->route.addr.src_addr.ss_family == AF_IB) ? src->qkey : 0;
 }
 
 static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf,
@@ -741,7 +950,7 @@ static ssize_t ucma_connect(struct ucma_
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	ucma_copy_conn_param(&conn_param, &cmd.conn_param);
+	ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param);
 	ret = rdma_connect(ctx->cm_id, &conn_param);
 	ucma_put_ctx(ctx);
 	return ret;
@@ -784,7 +993,7 @@ static ssize_t ucma_accept(struct ucma_f
 		return PTR_ERR(ctx);
 
 	if (cmd.conn_param.valid) {
-		ucma_copy_conn_param(&conn_param, &cmd.conn_param);
+		ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param);
 		mutex_lock(&file->mut);
 		ret = rdma_accept(ctx->cm_id, &conn_param);
 		if (!ret)
@@ -1020,23 +1229,23 @@ static ssize_t ucma_notify(struct ucma_f
 	return ret;
 }
 
-static ssize_t ucma_join_multicast(struct ucma_file *file,
-				   const char __user *inbuf,
-				   int in_len, int out_len)
+static ssize_t ucma_process_join(struct ucma_file *file,
+				 struct rdma_ucm_join_mcast *cmd,  int out_len)
 {
-	struct rdma_ucm_join_mcast cmd;
 	struct rdma_ucm_create_id_resp resp;
 	struct ucma_context *ctx;
 	struct ucma_multicast *mc;
+	struct sockaddr *addr;
 	int ret;
 
 	if (out_len < sizeof(resp))
 		return -ENOSPC;
 
-	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
-		return -EFAULT;
+	addr = (struct sockaddr *) &cmd->addr;
+	if (cmd->reserved || !cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr)))
+		return -EINVAL;
 
-	ctx = ucma_get_ctx(file, cmd.id);
+	ctx = ucma_get_ctx(file, cmd->id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
@@ -1047,14 +1256,14 @@ static ssize_t ucma_join_multicast(struc
 		goto err1;
 	}
 
-	mc->uid = cmd.uid;
-	memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr);
+	mc->uid = cmd->uid;
+	memcpy(&mc->addr, addr, cmd->addr_size);
 	ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc);
 	if (ret)
 		goto err2;
 
 	resp.id = mc->id;
-	if (copy_to_user((void __user *)(unsigned long)cmd.response,
+	if (copy_to_user((void __user *)(unsigned long) cmd->response,
 			 &resp, sizeof(resp))) {
 		ret = -EFAULT;
 		goto err3;
@@ -1079,6 +1288,38 @@ err1:
 	return ret;
 }
 
+static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
+				      const char __user *inbuf,
+				      int in_len, int out_len)
+{
+	struct rdma_ucm_join_ip_mcast cmd;
+	struct rdma_ucm_join_mcast join_cmd;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	join_cmd.response = cmd.response;
+	join_cmd.uid = cmd.uid;
+	join_cmd.id = cmd.id;
+	join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
+	join_cmd.reserved = 0;
+	memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size);
+
+	return ucma_process_join(file, &join_cmd, out_len);
+}
+
+static ssize_t ucma_join_multicast(struct ucma_file *file,
+				   const char __user *inbuf,
+				   int in_len, int out_len)
+{
+	struct rdma_ucm_join_mcast cmd;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	return ucma_process_join(file, &cmd, out_len);
+}
+
 static ssize_t ucma_leave_multicast(struct ucma_file *file,
 				    const char __user *inbuf,
 				    int in_len, int out_len)
@@ -1221,25 +1462,29 @@ file_put:
 static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
 				   const char __user *inbuf,
 				   int in_len, int out_len) = {
-	[RDMA_USER_CM_CMD_CREATE_ID]	= ucma_create_id,
-	[RDMA_USER_CM_CMD_DESTROY_ID]	= ucma_destroy_id,
-	[RDMA_USER_CM_CMD_BIND_ADDR]	= ucma_bind_addr,
-	[RDMA_USER_CM_CMD_RESOLVE_ADDR]	= ucma_resolve_addr,
-	[RDMA_USER_CM_CMD_RESOLVE_ROUTE]= ucma_resolve_route,
-	[RDMA_USER_CM_CMD_QUERY_ROUTE]	= ucma_query_route,
-	[RDMA_USER_CM_CMD_CONNECT]	= ucma_connect,
-	[RDMA_USER_CM_CMD_LISTEN]	= ucma_listen,
-	[RDMA_USER_CM_CMD_ACCEPT]	= ucma_accept,
-	[RDMA_USER_CM_CMD_REJECT]	= ucma_reject,
-	[RDMA_USER_CM_CMD_DISCONNECT]	= ucma_disconnect,
-	[RDMA_USER_CM_CMD_INIT_QP_ATTR]	= ucma_init_qp_attr,
-	[RDMA_USER_CM_CMD_GET_EVENT]	= ucma_get_event,
-	[RDMA_USER_CM_CMD_GET_OPTION]	= NULL,
-	[RDMA_USER_CM_CMD_SET_OPTION]	= ucma_set_option,
-	[RDMA_USER_CM_CMD_NOTIFY]	= ucma_notify,
-	[RDMA_USER_CM_CMD_JOIN_MCAST]	= ucma_join_multicast,
-	[RDMA_USER_CM_CMD_LEAVE_MCAST]	= ucma_leave_multicast,
-	[RDMA_USER_CM_CMD_MIGRATE_ID]	= ucma_migrate_id
+	[RDMA_USER_CM_CMD_CREATE_ID] 	 = ucma_create_id,
+	[RDMA_USER_CM_CMD_DESTROY_ID]	 = ucma_destroy_id,
+	[RDMA_USER_CM_CMD_BIND_IP]	 = ucma_bind_ip,
+	[RDMA_USER_CM_CMD_RESOLVE_IP]	 = ucma_resolve_ip,
+	[RDMA_USER_CM_CMD_RESOLVE_ROUTE] = ucma_resolve_route,
+	[RDMA_USER_CM_CMD_QUERY_ROUTE]	 = ucma_query_route,
+	[RDMA_USER_CM_CMD_CONNECT]	 = ucma_connect,
+	[RDMA_USER_CM_CMD_LISTEN]	 = ucma_listen,
+	[RDMA_USER_CM_CMD_ACCEPT]	 = ucma_accept,
+	[RDMA_USER_CM_CMD_REJECT]	 = ucma_reject,
+	[RDMA_USER_CM_CMD_DISCONNECT]	 = ucma_disconnect,
+	[RDMA_USER_CM_CMD_INIT_QP_ATTR]	 = ucma_init_qp_attr,
+	[RDMA_USER_CM_CMD_GET_EVENT]	 = ucma_get_event,
+	[RDMA_USER_CM_CMD_GET_OPTION]	 = NULL,
+	[RDMA_USER_CM_CMD_SET_OPTION]	 = ucma_set_option,
+	[RDMA_USER_CM_CMD_NOTIFY]	 = ucma_notify,
+	[RDMA_USER_CM_CMD_JOIN_IP_MCAST] = ucma_join_ip_multicast,
+	[RDMA_USER_CM_CMD_LEAVE_MCAST]	 = ucma_leave_multicast,
+	[RDMA_USER_CM_CMD_MIGRATE_ID]	 = ucma_migrate_id,
+	[RDMA_USER_CM_CMD_QUERY]	 = ucma_query,
+	[RDMA_USER_CM_CMD_BIND]		 = ucma_bind,
+	[RDMA_USER_CM_CMD_RESOLVE_ADDR]	 = ucma_resolve_addr,
+	[RDMA_USER_CM_CMD_JOIN_MCAST]	 = ucma_join_multicast
 };
 
 static ssize_t ucma_write(struct file *filp, const char __user *buf,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/core/uverbs_cmd.c linux-libre-3.11-rc7-gnu/drivers/infiniband/core/uverbs_cmd.c
--- linux-libre-3.10-gnu/drivers/infiniband/core/uverbs_cmd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/core/uverbs_cmd.c	2013-08-25 20:43:22.000000000 -0400
@@ -334,7 +334,7 @@ ssize_t ib_uverbs_get_context(struct ib_
 
 	resp.num_comp_vectors = file->device->num_comp_vectors;
 
-	ret = get_unused_fd();
+	ret = get_unused_fd_flags(O_CLOEXEC);
 	if (ret < 0)
 		goto err_free;
 	resp.async_fd = ret;
@@ -1184,7 +1184,7 @@ ssize_t ib_uverbs_create_comp_channel(st
 	if (copy_from_user(&cmd, buf, sizeof cmd))
 		return -EFAULT;
 
-	ret = get_unused_fd();
+	ret = get_unused_fd_flags(O_CLOEXEC);
 	if (ret < 0)
 		return ret;
 	resp.fd = ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/cxgb3/iwch_provider.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/cxgb3/iwch_provider.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/cxgb3/iwch_provider.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/cxgb3/iwch_provider.c	2013-08-25 20:43:22.000000000 -0400
@@ -226,6 +226,7 @@ static struct ib_cq *iwch_create_cq(stru
 			mm->len = PAGE_ALIGN(((1UL << uresp.size_log2) + 1) *
 					     sizeof(struct t3_cqe));
 			uresp.memsize = mm->len;
+			uresp.reserved = 0;
 			resplen = sizeof uresp;
 		}
 		if (ib_copy_to_udata(udata, &uresp, resplen)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/cxgb3/iwch_qp.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/cxgb3/iwch_qp.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/cxgb3/iwch_qp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/cxgb3/iwch_qp.c	2013-08-25 20:43:22.000000000 -0400
@@ -883,7 +883,8 @@ u16 iwch_rqes_posted(struct iwch_qp *qhp
 {
 	union t3_wr *wqe = qhp->wq.queue;
 	u16 count = 0;
-	while ((count+1) != 0 && fw_riwrh_opcode((struct fw_riwrh *)wqe) == T3_WR_RCV) {
+
+	while (count < USHRT_MAX && fw_riwrh_opcode((struct fw_riwrh *)wqe) == T3_WR_RCV) {
 		count++;
 		wqe++;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/cxgb4/qp.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/cxgb4/qp.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/cxgb4/qp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/cxgb4/qp.c	2013-08-25 20:43:22.000000000 -0400
@@ -1657,6 +1657,8 @@ struct ib_qp *c4iw_create_qp(struct ib_p
 		if (mm5) {
 			uresp.ma_sync_key = ucontext->key;
 			ucontext->key += PAGE_SIZE;
+		} else {
+			uresp.ma_sync_key =  0;
 		}
 		uresp.sq_key = ucontext->key;
 		ucontext->key += PAGE_SIZE;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/ehca/ehca_main.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ehca/ehca_main.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/ehca/ehca_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ehca/ehca_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -211,6 +211,7 @@ static int ehca_create_slab_caches(void)
 	if (!ctblk_cache) {
 		ehca_gen_err("Cannot create ctblk SLAB cache.");
 		ehca_cleanup_small_qp_cache();
+		ret = -ENOMEM;
 		goto create_slab_caches6;
 	}
 #endif
@@ -713,8 +714,7 @@ static struct attribute_group ehca_dev_a
 	.attrs = ehca_dev_attrs
 };
 
-static int ehca_probe(struct platform_device *dev,
-		      const struct of_device_id *id)
+static int ehca_probe(struct platform_device *dev)
 {
 	struct ehca_shca *shca;
 	const u64 *handle;
@@ -937,7 +937,7 @@ static struct of_device_id ehca_device_t
 };
 MODULE_DEVICE_TABLE(of, ehca_device_table);
 
-static struct of_platform_driver ehca_driver = {
+static struct platform_driver ehca_driver = {
 	.probe       = ehca_probe,
 	.remove      = ehca_remove,
 	.driver = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx4/mad.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx4/mad.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx4/mad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx4/mad.c	2013-08-25 20:43:22.000000000 -0400
@@ -1511,8 +1511,14 @@ static int create_pv_sqp(struct mlx4_ib_
 
 	memset(&attr, 0, sizeof attr);
 	attr.qp_state = IB_QPS_INIT;
-	attr.pkey_index =
-		to_mdev(ctx->ib_dev)->pkeys.virt2phys_pkey[ctx->slave][ctx->port - 1][0];
+	ret = 0;
+	if (create_tun)
+		ret = find_slave_port_pkey_ix(to_mdev(ctx->ib_dev), ctx->slave,
+					      ctx->port, IB_DEFAULT_PKEY_FULL,
+					      &attr.pkey_index);
+	if (ret || !create_tun)
+		attr.pkey_index =
+			to_mdev(ctx->ib_dev)->pkeys.virt2phys_pkey[ctx->slave][ctx->port - 1][0];
 	attr.qkey = IB_QP1_QKEY;
 	attr.port_num = ctx->port;
 	ret = ib_modify_qp(tun_qp->qp, &attr, qp_attr_mask_INIT);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx4/main.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx4/main.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx4/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx4/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1161,7 +1161,7 @@ static void netdev_removed(struct mlx4_i
 static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event,
 				void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct mlx4_ib_dev *ibdev;
 	struct net_device *oldnd;
 	struct mlx4_ib_iboe *iboe;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/ah.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/ah.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/ah.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/ah.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include "mlx5_ib.h"
+
+struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
+			   struct mlx5_ib_ah *ah)
+{
+	if (ah_attr->ah_flags & IB_AH_GRH) {
+		memcpy(ah->av.rgid, &ah_attr->grh.dgid, 16);
+		ah->av.grh_gid_fl = cpu_to_be32(ah_attr->grh.flow_label |
+						(1 << 30) |
+						ah_attr->grh.sgid_index << 20);
+		ah->av.hop_limit = ah_attr->grh.hop_limit;
+		ah->av.tclass = ah_attr->grh.traffic_class;
+	}
+
+	ah->av.rlid = cpu_to_be16(ah_attr->dlid);
+	ah->av.fl_mlid = ah_attr->src_path_bits & 0x7f;
+	ah->av.stat_rate_sl = (ah_attr->static_rate << 4) | (ah_attr->sl & 0xf);
+
+	return &ah->ibah;
+}
+
+struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
+{
+	struct mlx5_ib_ah *ah;
+
+	ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
+	if (!ah)
+		return ERR_PTR(-ENOMEM);
+
+	return create_ib_ah(ah_attr, ah); /* never fails */
+}
+
+int mlx5_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
+{
+	struct mlx5_ib_ah *ah = to_mah(ibah);
+	u32 tmp;
+
+	memset(ah_attr, 0, sizeof(*ah_attr));
+
+	tmp = be32_to_cpu(ah->av.grh_gid_fl);
+	if (tmp & (1 << 30)) {
+		ah_attr->ah_flags = IB_AH_GRH;
+		ah_attr->grh.sgid_index = (tmp >> 20) & 0xff;
+		ah_attr->grh.flow_label = tmp & 0xfffff;
+		memcpy(&ah_attr->grh.dgid, ah->av.rgid, 16);
+		ah_attr->grh.hop_limit = ah->av.hop_limit;
+		ah_attr->grh.traffic_class = ah->av.tclass;
+	}
+	ah_attr->dlid = be16_to_cpu(ah->av.rlid);
+	ah_attr->static_rate = ah->av.stat_rate_sl >> 4;
+	ah_attr->sl = ah->av.stat_rate_sl & 0xf;
+
+	return 0;
+}
+
+int mlx5_ib_destroy_ah(struct ib_ah *ah)
+{
+	kfree(to_mah(ah));
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/cq.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/cq.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/cq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/cq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,843 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kref.h>
+#include <rdma/ib_umem.h>
+#include "mlx5_ib.h"
+#include "user.h"
+
+static void mlx5_ib_cq_comp(struct mlx5_core_cq *cq)
+{
+	struct ib_cq *ibcq = &to_mibcq(cq)->ibcq;
+
+	ibcq->comp_handler(ibcq, ibcq->cq_context);
+}
+
+static void mlx5_ib_cq_event(struct mlx5_core_cq *mcq, enum mlx5_event type)
+{
+	struct mlx5_ib_cq *cq = container_of(mcq, struct mlx5_ib_cq, mcq);
+	struct mlx5_ib_dev *dev = to_mdev(cq->ibcq.device);
+	struct ib_cq *ibcq = &cq->ibcq;
+	struct ib_event event;
+
+	if (type != MLX5_EVENT_TYPE_CQ_ERROR) {
+		mlx5_ib_warn(dev, "Unexpected event type %d on CQ %06x\n",
+			     type, mcq->cqn);
+		return;
+	}
+
+	if (ibcq->event_handler) {
+		event.device     = &dev->ib_dev;
+		event.event      = IB_EVENT_CQ_ERR;
+		event.element.cq = ibcq;
+		ibcq->event_handler(&event, ibcq->cq_context);
+	}
+}
+
+static void *get_cqe_from_buf(struct mlx5_ib_cq_buf *buf, int n, int size)
+{
+	return mlx5_buf_offset(&buf->buf, n * size);
+}
+
+static void *get_cqe(struct mlx5_ib_cq *cq, int n)
+{
+	return get_cqe_from_buf(&cq->buf, n, cq->mcq.cqe_sz);
+}
+
+static void *get_sw_cqe(struct mlx5_ib_cq *cq, int n)
+{
+	void *cqe = get_cqe(cq, n & cq->ibcq.cqe);
+	struct mlx5_cqe64 *cqe64;
+
+	cqe64 = (cq->mcq.cqe_sz == 64) ? cqe : cqe + 64;
+	return ((cqe64->op_own & MLX5_CQE_OWNER_MASK) ^
+		!!(n & (cq->ibcq.cqe + 1))) ? NULL : cqe;
+}
+
+static void *next_cqe_sw(struct mlx5_ib_cq *cq)
+{
+	return get_sw_cqe(cq, cq->mcq.cons_index);
+}
+
+static enum ib_wc_opcode get_umr_comp(struct mlx5_ib_wq *wq, int idx)
+{
+	switch (wq->wr_data[idx]) {
+	case MLX5_IB_WR_UMR:
+		return 0;
+
+	case IB_WR_LOCAL_INV:
+		return IB_WC_LOCAL_INV;
+
+	case IB_WR_FAST_REG_MR:
+		return IB_WC_FAST_REG_MR;
+
+	default:
+		pr_warn("unknown completion status\n");
+		return 0;
+	}
+}
+
+static void handle_good_req(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
+			    struct mlx5_ib_wq *wq, int idx)
+{
+	wc->wc_flags = 0;
+	switch (be32_to_cpu(cqe->sop_drop_qpn) >> 24) {
+	case MLX5_OPCODE_RDMA_WRITE_IMM:
+		wc->wc_flags |= IB_WC_WITH_IMM;
+	case MLX5_OPCODE_RDMA_WRITE:
+		wc->opcode    = IB_WC_RDMA_WRITE;
+		break;
+	case MLX5_OPCODE_SEND_IMM:
+		wc->wc_flags |= IB_WC_WITH_IMM;
+	case MLX5_OPCODE_SEND:
+	case MLX5_OPCODE_SEND_INVAL:
+		wc->opcode    = IB_WC_SEND;
+		break;
+	case MLX5_OPCODE_RDMA_READ:
+		wc->opcode    = IB_WC_RDMA_READ;
+		wc->byte_len  = be32_to_cpu(cqe->byte_cnt);
+		break;
+	case MLX5_OPCODE_ATOMIC_CS:
+		wc->opcode    = IB_WC_COMP_SWAP;
+		wc->byte_len  = 8;
+		break;
+	case MLX5_OPCODE_ATOMIC_FA:
+		wc->opcode    = IB_WC_FETCH_ADD;
+		wc->byte_len  = 8;
+		break;
+	case MLX5_OPCODE_ATOMIC_MASKED_CS:
+		wc->opcode    = IB_WC_MASKED_COMP_SWAP;
+		wc->byte_len  = 8;
+		break;
+	case MLX5_OPCODE_ATOMIC_MASKED_FA:
+		wc->opcode    = IB_WC_MASKED_FETCH_ADD;
+		wc->byte_len  = 8;
+		break;
+	case MLX5_OPCODE_BIND_MW:
+		wc->opcode    = IB_WC_BIND_MW;
+		break;
+	case MLX5_OPCODE_UMR:
+		wc->opcode = get_umr_comp(wq, idx);
+		break;
+	}
+}
+
+enum {
+	MLX5_GRH_IN_BUFFER = 1,
+	MLX5_GRH_IN_CQE	   = 2,
+};
+
+static void handle_responder(struct ib_wc *wc, struct mlx5_cqe64 *cqe,
+			     struct mlx5_ib_qp *qp)
+{
+	struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.device);
+	struct mlx5_ib_srq *srq;
+	struct mlx5_ib_wq *wq;
+	u16 wqe_ctr;
+	u8 g;
+
+	if (qp->ibqp.srq || qp->ibqp.xrcd) {
+		struct mlx5_core_srq *msrq = NULL;
+
+		if (qp->ibqp.xrcd) {
+			msrq = mlx5_core_get_srq(&dev->mdev,
+						 be32_to_cpu(cqe->srqn));
+			srq = to_mibsrq(msrq);
+		} else {
+			srq = to_msrq(qp->ibqp.srq);
+		}
+		if (srq) {
+			wqe_ctr = be16_to_cpu(cqe->wqe_counter);
+			wc->wr_id = srq->wrid[wqe_ctr];
+			mlx5_ib_free_srq_wqe(srq, wqe_ctr);
+			if (msrq && atomic_dec_and_test(&msrq->refcount))
+				complete(&msrq->free);
+		}
+	} else {
+		wq	  = &qp->rq;
+		wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
+		++wq->tail;
+	}
+	wc->byte_len = be32_to_cpu(cqe->byte_cnt);
+
+	switch (cqe->op_own >> 4) {
+	case MLX5_CQE_RESP_WR_IMM:
+		wc->opcode	= IB_WC_RECV_RDMA_WITH_IMM;
+		wc->wc_flags	= IB_WC_WITH_IMM;
+		wc->ex.imm_data = cqe->imm_inval_pkey;
+		break;
+	case MLX5_CQE_RESP_SEND:
+		wc->opcode   = IB_WC_RECV;
+		wc->wc_flags = 0;
+		break;
+	case MLX5_CQE_RESP_SEND_IMM:
+		wc->opcode	= IB_WC_RECV;
+		wc->wc_flags	= IB_WC_WITH_IMM;
+		wc->ex.imm_data = cqe->imm_inval_pkey;
+		break;
+	case MLX5_CQE_RESP_SEND_INV:
+		wc->opcode	= IB_WC_RECV;
+		wc->wc_flags	= IB_WC_WITH_INVALIDATE;
+		wc->ex.invalidate_rkey = be32_to_cpu(cqe->imm_inval_pkey);
+		break;
+	}
+	wc->slid	   = be16_to_cpu(cqe->slid);
+	wc->sl		   = (be32_to_cpu(cqe->flags_rqpn) >> 24) & 0xf;
+	wc->src_qp	   = be32_to_cpu(cqe->flags_rqpn) & 0xffffff;
+	wc->dlid_path_bits = cqe->ml_path;
+	g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3;
+	wc->wc_flags |= g ? IB_WC_GRH : 0;
+	wc->pkey_index     = be32_to_cpu(cqe->imm_inval_pkey) & 0xffff;
+}
+
+static void dump_cqe(struct mlx5_ib_dev *dev, struct mlx5_err_cqe *cqe)
+{
+	__be32 *p = (__be32 *)cqe;
+	int i;
+
+	mlx5_ib_warn(dev, "dump error cqe\n");
+	for (i = 0; i < sizeof(*cqe) / 16; i++, p += 4)
+		pr_info("%08x %08x %08x %08x\n", be32_to_cpu(p[0]),
+			be32_to_cpu(p[1]), be32_to_cpu(p[2]),
+			be32_to_cpu(p[3]));
+}
+
+static void mlx5_handle_error_cqe(struct mlx5_ib_dev *dev,
+				  struct mlx5_err_cqe *cqe,
+				  struct ib_wc *wc)
+{
+	int dump = 1;
+
+	switch (cqe->syndrome) {
+	case MLX5_CQE_SYNDROME_LOCAL_LENGTH_ERR:
+		wc->status = IB_WC_LOC_LEN_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR:
+		wc->status = IB_WC_LOC_QP_OP_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_LOCAL_PROT_ERR:
+		wc->status = IB_WC_LOC_PROT_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_WR_FLUSH_ERR:
+		dump = 0;
+		wc->status = IB_WC_WR_FLUSH_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_MW_BIND_ERR:
+		wc->status = IB_WC_MW_BIND_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_BAD_RESP_ERR:
+		wc->status = IB_WC_BAD_RESP_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_LOCAL_ACCESS_ERR:
+		wc->status = IB_WC_LOC_ACCESS_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_REMOTE_INVAL_REQ_ERR:
+		wc->status = IB_WC_REM_INV_REQ_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_REMOTE_ACCESS_ERR:
+		wc->status = IB_WC_REM_ACCESS_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_REMOTE_OP_ERR:
+		wc->status = IB_WC_REM_OP_ERR;
+		break;
+	case MLX5_CQE_SYNDROME_TRANSPORT_RETRY_EXC_ERR:
+		wc->status = IB_WC_RETRY_EXC_ERR;
+		dump = 0;
+		break;
+	case MLX5_CQE_SYNDROME_RNR_RETRY_EXC_ERR:
+		wc->status = IB_WC_RNR_RETRY_EXC_ERR;
+		dump = 0;
+		break;
+	case MLX5_CQE_SYNDROME_REMOTE_ABORTED_ERR:
+		wc->status = IB_WC_REM_ABORT_ERR;
+		break;
+	default:
+		wc->status = IB_WC_GENERAL_ERR;
+		break;
+	}
+
+	wc->vendor_err = cqe->vendor_err_synd;
+	if (dump)
+		dump_cqe(dev, cqe);
+}
+
+static int is_atomic_response(struct mlx5_ib_qp *qp, uint16_t idx)
+{
+	/* TBD: waiting decision
+	*/
+	return 0;
+}
+
+static void *mlx5_get_atomic_laddr(struct mlx5_ib_qp *qp, uint16_t idx)
+{
+	struct mlx5_wqe_data_seg *dpseg;
+	void *addr;
+
+	dpseg = mlx5_get_send_wqe(qp, idx) + sizeof(struct mlx5_wqe_ctrl_seg) +
+		sizeof(struct mlx5_wqe_raddr_seg) +
+		sizeof(struct mlx5_wqe_atomic_seg);
+	addr = (void *)(unsigned long)be64_to_cpu(dpseg->addr);
+	return addr;
+}
+
+static void handle_atomic(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64,
+			  uint16_t idx)
+{
+	void *addr;
+	int byte_count;
+	int i;
+
+	if (!is_atomic_response(qp, idx))
+		return;
+
+	byte_count = be32_to_cpu(cqe64->byte_cnt);
+	addr = mlx5_get_atomic_laddr(qp, idx);
+
+	if (byte_count == 4) {
+		*(uint32_t *)addr = be32_to_cpu(*((__be32 *)addr));
+	} else {
+		for (i = 0; i < byte_count; i += 8) {
+			*(uint64_t *)addr = be64_to_cpu(*((__be64 *)addr));
+			addr += 8;
+		}
+	}
+
+	return;
+}
+
+static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64,
+			   u16 tail, u16 head)
+{
+	int idx;
+
+	do {
+		idx = tail & (qp->sq.wqe_cnt - 1);
+		handle_atomic(qp, cqe64, idx);
+		if (idx == head)
+			break;
+
+		tail = qp->sq.w_list[idx].next;
+	} while (1);
+	tail = qp->sq.w_list[idx].next;
+	qp->sq.last_poll = tail;
+}
+
+static int mlx5_poll_one(struct mlx5_ib_cq *cq,
+			 struct mlx5_ib_qp **cur_qp,
+			 struct ib_wc *wc)
+{
+	struct mlx5_ib_dev *dev = to_mdev(cq->ibcq.device);
+	struct mlx5_err_cqe *err_cqe;
+	struct mlx5_cqe64 *cqe64;
+	struct mlx5_core_qp *mqp;
+	struct mlx5_ib_wq *wq;
+	uint8_t opcode;
+	uint32_t qpn;
+	u16 wqe_ctr;
+	void *cqe;
+	int idx;
+
+	cqe = next_cqe_sw(cq);
+	if (!cqe)
+		return -EAGAIN;
+
+	cqe64 = (cq->mcq.cqe_sz == 64) ? cqe : cqe + 64;
+
+	++cq->mcq.cons_index;
+
+	/* Make sure we read CQ entry contents after we've checked the
+	 * ownership bit.
+	 */
+	rmb();
+
+	/* TBD: resize CQ */
+
+	qpn = ntohl(cqe64->sop_drop_qpn) & 0xffffff;
+	if (!*cur_qp || (qpn != (*cur_qp)->ibqp.qp_num)) {
+		/* We do not have to take the QP table lock here,
+		 * because CQs will be locked while QPs are removed
+		 * from the table.
+		 */
+		mqp = __mlx5_qp_lookup(&dev->mdev, qpn);
+		if (unlikely(!mqp)) {
+			mlx5_ib_warn(dev, "CQE@CQ %06x for unknown QPN %6x\n",
+				     cq->mcq.cqn, qpn);
+			return -EINVAL;
+		}
+
+		*cur_qp = to_mibqp(mqp);
+	}
+
+	wc->qp  = &(*cur_qp)->ibqp;
+	opcode = cqe64->op_own >> 4;
+	switch (opcode) {
+	case MLX5_CQE_REQ:
+		wq = &(*cur_qp)->sq;
+		wqe_ctr = be16_to_cpu(cqe64->wqe_counter);
+		idx = wqe_ctr & (wq->wqe_cnt - 1);
+		handle_good_req(wc, cqe64, wq, idx);
+		handle_atomics(*cur_qp, cqe64, wq->last_poll, idx);
+		wc->wr_id = wq->wrid[idx];
+		wq->tail = wq->wqe_head[idx] + 1;
+		wc->status = IB_WC_SUCCESS;
+		break;
+	case MLX5_CQE_RESP_WR_IMM:
+	case MLX5_CQE_RESP_SEND:
+	case MLX5_CQE_RESP_SEND_IMM:
+	case MLX5_CQE_RESP_SEND_INV:
+		handle_responder(wc, cqe64, *cur_qp);
+		wc->status = IB_WC_SUCCESS;
+		break;
+	case MLX5_CQE_RESIZE_CQ:
+		break;
+	case MLX5_CQE_REQ_ERR:
+	case MLX5_CQE_RESP_ERR:
+		err_cqe = (struct mlx5_err_cqe *)cqe64;
+		mlx5_handle_error_cqe(dev, err_cqe, wc);
+		mlx5_ib_dbg(dev, "%s error cqe on cqn 0x%x:\n",
+			    opcode == MLX5_CQE_REQ_ERR ?
+			    "Requestor" : "Responder", cq->mcq.cqn);
+		mlx5_ib_dbg(dev, "syndrome 0x%x, vendor syndrome 0x%x\n",
+			    err_cqe->syndrome, err_cqe->vendor_err_synd);
+		if (opcode == MLX5_CQE_REQ_ERR) {
+			wq = &(*cur_qp)->sq;
+			wqe_ctr = be16_to_cpu(cqe64->wqe_counter);
+			idx = wqe_ctr & (wq->wqe_cnt - 1);
+			wc->wr_id = wq->wrid[idx];
+			wq->tail = wq->wqe_head[idx] + 1;
+		} else {
+			struct mlx5_ib_srq *srq;
+
+			if ((*cur_qp)->ibqp.srq) {
+				srq = to_msrq((*cur_qp)->ibqp.srq);
+				wqe_ctr = be16_to_cpu(cqe64->wqe_counter);
+				wc->wr_id = srq->wrid[wqe_ctr];
+				mlx5_ib_free_srq_wqe(srq, wqe_ctr);
+			} else {
+				wq = &(*cur_qp)->rq;
+				wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
+				++wq->tail;
+			}
+		}
+		break;
+	}
+
+	return 0;
+}
+
+int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
+{
+	struct mlx5_ib_cq *cq = to_mcq(ibcq);
+	struct mlx5_ib_qp *cur_qp = NULL;
+	unsigned long flags;
+	int npolled;
+	int err = 0;
+
+	spin_lock_irqsave(&cq->lock, flags);
+
+	for (npolled = 0; npolled < num_entries; npolled++) {
+		err = mlx5_poll_one(cq, &cur_qp, wc + npolled);
+		if (err)
+			break;
+	}
+
+	if (npolled)
+		mlx5_cq_set_ci(&cq->mcq);
+
+	spin_unlock_irqrestore(&cq->lock, flags);
+
+	if (err == 0 || err == -EAGAIN)
+		return npolled;
+	else
+		return err;
+}
+
+int mlx5_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
+{
+	mlx5_cq_arm(&to_mcq(ibcq)->mcq,
+		    (flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
+		    MLX5_CQ_DB_REQ_NOT_SOL : MLX5_CQ_DB_REQ_NOT,
+		    to_mdev(ibcq->device)->mdev.priv.uuari.uars[0].map,
+		    MLX5_GET_DOORBELL_LOCK(&to_mdev(ibcq->device)->mdev.priv.cq_uar_lock));
+
+	return 0;
+}
+
+static int alloc_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf,
+			int nent, int cqe_size)
+{
+	int err;
+
+	err = mlx5_buf_alloc(&dev->mdev, nent * cqe_size,
+			     PAGE_SIZE * 2, &buf->buf);
+	if (err)
+		return err;
+
+	buf->cqe_size = cqe_size;
+
+	return 0;
+}
+
+static void free_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf)
+{
+	mlx5_buf_free(&dev->mdev, &buf->buf);
+}
+
+static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
+			  struct ib_ucontext *context, struct mlx5_ib_cq *cq,
+			  int entries, struct mlx5_create_cq_mbox_in **cqb,
+			  int *cqe_size, int *index, int *inlen)
+{
+	struct mlx5_ib_create_cq ucmd;
+	int page_shift;
+	int npages;
+	int ncont;
+	int err;
+
+	if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)))
+		return -EFAULT;
+
+	if (ucmd.cqe_size != 64 && ucmd.cqe_size != 128)
+		return -EINVAL;
+
+	*cqe_size = ucmd.cqe_size;
+
+	cq->buf.umem = ib_umem_get(context, ucmd.buf_addr,
+				   entries * ucmd.cqe_size,
+				   IB_ACCESS_LOCAL_WRITE, 1);
+	if (IS_ERR(cq->buf.umem)) {
+		err = PTR_ERR(cq->buf.umem);
+		return err;
+	}
+
+	err = mlx5_ib_db_map_user(to_mucontext(context), ucmd.db_addr,
+				  &cq->db);
+	if (err)
+		goto err_umem;
+
+	mlx5_ib_cont_pages(cq->buf.umem, ucmd.buf_addr, &npages, &page_shift,
+			   &ncont, NULL);
+	mlx5_ib_dbg(dev, "addr 0x%llx, size %u, npages %d, page_shift %d, ncont %d\n",
+		    ucmd.buf_addr, entries * ucmd.cqe_size, npages, page_shift, ncont);
+
+	*inlen = sizeof(**cqb) + sizeof(*(*cqb)->pas) * ncont;
+	*cqb = mlx5_vzalloc(*inlen);
+	if (!*cqb) {
+		err = -ENOMEM;
+		goto err_db;
+	}
+	mlx5_ib_populate_pas(dev, cq->buf.umem, page_shift, (*cqb)->pas, 0);
+	(*cqb)->ctx.log_pg_sz = page_shift - PAGE_SHIFT;
+
+	*index = to_mucontext(context)->uuari.uars[0].index;
+
+	return 0;
+
+err_db:
+	mlx5_ib_db_unmap_user(to_mucontext(context), &cq->db);
+
+err_umem:
+	ib_umem_release(cq->buf.umem);
+	return err;
+}
+
+static void destroy_cq_user(struct mlx5_ib_cq *cq, struct ib_ucontext *context)
+{
+	mlx5_ib_db_unmap_user(to_mucontext(context), &cq->db);
+	ib_umem_release(cq->buf.umem);
+}
+
+static void init_cq_buf(struct mlx5_ib_cq *cq, int nent)
+{
+	int i;
+	void *cqe;
+	struct mlx5_cqe64 *cqe64;
+
+	for (i = 0; i < nent; i++) {
+		cqe = get_cqe(cq, i);
+		cqe64 = (cq->buf.cqe_size == 64) ? cqe : cqe + 64;
+		cqe64->op_own = 0xf1;
+	}
+}
+
+static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
+			    int entries, int cqe_size,
+			    struct mlx5_create_cq_mbox_in **cqb,
+			    int *index, int *inlen)
+{
+	int err;
+
+	err = mlx5_db_alloc(&dev->mdev, &cq->db);
+	if (err)
+		return err;
+
+	cq->mcq.set_ci_db  = cq->db.db;
+	cq->mcq.arm_db     = cq->db.db + 1;
+	*cq->mcq.set_ci_db = 0;
+	*cq->mcq.arm_db    = 0;
+	cq->mcq.cqe_sz = cqe_size;
+
+	err = alloc_cq_buf(dev, &cq->buf, entries, cqe_size);
+	if (err)
+		goto err_db;
+
+	init_cq_buf(cq, entries);
+
+	*inlen = sizeof(**cqb) + sizeof(*(*cqb)->pas) * cq->buf.buf.npages;
+	*cqb = mlx5_vzalloc(*inlen);
+	if (!*cqb) {
+		err = -ENOMEM;
+		goto err_buf;
+	}
+	mlx5_fill_page_array(&cq->buf.buf, (*cqb)->pas);
+
+	(*cqb)->ctx.log_pg_sz = cq->buf.buf.page_shift - PAGE_SHIFT;
+	*index = dev->mdev.priv.uuari.uars[0].index;
+
+	return 0;
+
+err_buf:
+	free_cq_buf(dev, &cq->buf);
+
+err_db:
+	mlx5_db_free(&dev->mdev, &cq->db);
+	return err;
+}
+
+static void destroy_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq)
+{
+	free_cq_buf(dev, &cq->buf);
+	mlx5_db_free(&dev->mdev, &cq->db);
+}
+
+struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries,
+				int vector, struct ib_ucontext *context,
+				struct ib_udata *udata)
+{
+	struct mlx5_create_cq_mbox_in *cqb = NULL;
+	struct mlx5_ib_dev *dev = to_mdev(ibdev);
+	struct mlx5_ib_cq *cq;
+	int uninitialized_var(index);
+	int uninitialized_var(inlen);
+	int cqe_size;
+	int irqn;
+	int eqn;
+	int err;
+
+	entries = roundup_pow_of_two(entries + 1);
+	if (entries < 1 || entries > dev->mdev.caps.max_cqes)
+		return ERR_PTR(-EINVAL);
+
+	cq = kzalloc(sizeof(*cq), GFP_KERNEL);
+	if (!cq)
+		return ERR_PTR(-ENOMEM);
+
+	cq->ibcq.cqe = entries - 1;
+	mutex_init(&cq->resize_mutex);
+	spin_lock_init(&cq->lock);
+	cq->resize_buf = NULL;
+	cq->resize_umem = NULL;
+
+	if (context) {
+		err = create_cq_user(dev, udata, context, cq, entries,
+				     &cqb, &cqe_size, &index, &inlen);
+		if (err)
+			goto err_create;
+	} else {
+		/* for now choose 64 bytes till we have a proper interface */
+		cqe_size = 64;
+		err = create_cq_kernel(dev, cq, entries, cqe_size, &cqb,
+				       &index, &inlen);
+		if (err)
+			goto err_create;
+	}
+
+	cq->cqe_size = cqe_size;
+	cqb->ctx.cqe_sz_flags = cqe_sz_to_mlx_sz(cqe_size) << 5;
+	cqb->ctx.log_sz_usr_page = cpu_to_be32((ilog2(entries) << 24) | index);
+	err = mlx5_vector2eqn(dev, vector, &eqn, &irqn);
+	if (err)
+		goto err_cqb;
+
+	cqb->ctx.c_eqn = cpu_to_be16(eqn);
+	cqb->ctx.db_record_addr = cpu_to_be64(cq->db.dma);
+
+	err = mlx5_core_create_cq(&dev->mdev, &cq->mcq, cqb, inlen);
+	if (err)
+		goto err_cqb;
+
+	mlx5_ib_dbg(dev, "cqn 0x%x\n", cq->mcq.cqn);
+	cq->mcq.irqn = irqn;
+	cq->mcq.comp  = mlx5_ib_cq_comp;
+	cq->mcq.event = mlx5_ib_cq_event;
+
+	if (context)
+		if (ib_copy_to_udata(udata, &cq->mcq.cqn, sizeof(__u32))) {
+			err = -EFAULT;
+			goto err_cmd;
+		}
+
+
+	mlx5_vfree(cqb);
+	return &cq->ibcq;
+
+err_cmd:
+	mlx5_core_destroy_cq(&dev->mdev, &cq->mcq);
+
+err_cqb:
+	mlx5_vfree(cqb);
+	if (context)
+		destroy_cq_user(cq, context);
+	else
+		destroy_cq_kernel(dev, cq);
+
+err_create:
+	kfree(cq);
+
+	return ERR_PTR(err);
+}
+
+
+int mlx5_ib_destroy_cq(struct ib_cq *cq)
+{
+	struct mlx5_ib_dev *dev = to_mdev(cq->device);
+	struct mlx5_ib_cq *mcq = to_mcq(cq);
+	struct ib_ucontext *context = NULL;
+
+	if (cq->uobject)
+		context = cq->uobject->context;
+
+	mlx5_core_destroy_cq(&dev->mdev, &mcq->mcq);
+	if (context)
+		destroy_cq_user(mcq, context);
+	else
+		destroy_cq_kernel(dev, mcq);
+
+	kfree(mcq);
+
+	return 0;
+}
+
+static int is_equal_rsn(struct mlx5_cqe64 *cqe64, struct mlx5_ib_srq *srq,
+			u32 rsn)
+{
+	u32 lrsn;
+
+	if (srq)
+		lrsn = be32_to_cpu(cqe64->srqn) & 0xffffff;
+	else
+		lrsn = be32_to_cpu(cqe64->sop_drop_qpn) & 0xffffff;
+
+	return rsn == lrsn;
+}
+
+void __mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 rsn, struct mlx5_ib_srq *srq)
+{
+	struct mlx5_cqe64 *cqe64, *dest64;
+	void *cqe, *dest;
+	u32 prod_index;
+	int nfreed = 0;
+	u8 owner_bit;
+
+	if (!cq)
+		return;
+
+	/* First we need to find the current producer index, so we
+	 * know where to start cleaning from.  It doesn't matter if HW
+	 * adds new entries after this loop -- the QP we're worried
+	 * about is already in RESET, so the new entries won't come
+	 * from our QP and therefore don't need to be checked.
+	 */
+	for (prod_index = cq->mcq.cons_index; get_sw_cqe(cq, prod_index); prod_index++)
+		if (prod_index == cq->mcq.cons_index + cq->ibcq.cqe)
+			break;
+
+	/* Now sweep backwards through the CQ, removing CQ entries
+	 * that match our QP by copying older entries on top of them.
+	 */
+	while ((int) --prod_index - (int) cq->mcq.cons_index >= 0) {
+		cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
+		cqe64 = (cq->mcq.cqe_sz == 64) ? cqe : cqe + 64;
+		if (is_equal_rsn(cqe64, srq, rsn)) {
+			if (srq)
+				mlx5_ib_free_srq_wqe(srq, be16_to_cpu(cqe64->wqe_counter));
+			++nfreed;
+		} else if (nfreed) {
+			dest = get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe);
+			dest64 = (cq->mcq.cqe_sz == 64) ? dest : dest + 64;
+			owner_bit = dest64->op_own & MLX5_CQE_OWNER_MASK;
+			memcpy(dest, cqe, cq->mcq.cqe_sz);
+			dest64->op_own = owner_bit |
+				(dest64->op_own & ~MLX5_CQE_OWNER_MASK);
+		}
+	}
+
+	if (nfreed) {
+		cq->mcq.cons_index += nfreed;
+		/* Make sure update of buffer contents is done before
+		 * updating consumer index.
+		 */
+		wmb();
+		mlx5_cq_set_ci(&cq->mcq);
+	}
+}
+
+void mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq)
+{
+	if (!cq)
+		return;
+
+	spin_lock_irq(&cq->lock);
+	__mlx5_ib_cq_clean(cq, qpn, srq);
+	spin_unlock_irq(&cq->lock);
+}
+
+int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
+{
+	return -ENOSYS;
+}
+
+int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
+{
+	return -ENOSYS;
+}
+
+int mlx5_ib_get_cqe_size(struct mlx5_ib_dev *dev, struct ib_cq *ibcq)
+{
+	struct mlx5_ib_cq *cq;
+
+	if (!ibcq)
+		return 128;
+
+	cq = to_mcq(ibcq);
+	return cq->cqe_size;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/doorbell.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/doorbell.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/doorbell.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/doorbell.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kref.h>
+#include <linux/slab.h>
+#include <rdma/ib_umem.h>
+
+#include "mlx5_ib.h"
+
+struct mlx5_ib_user_db_page {
+	struct list_head	list;
+	struct ib_umem	       *umem;
+	unsigned long		user_virt;
+	int			refcnt;
+};
+
+int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
+			struct mlx5_db *db)
+{
+	struct mlx5_ib_user_db_page *page;
+	struct ib_umem_chunk *chunk;
+	int err = 0;
+
+	mutex_lock(&context->db_page_mutex);
+
+	list_for_each_entry(page, &context->db_page_list, list)
+		if (page->user_virt == (virt & PAGE_MASK))
+			goto found;
+
+	page = kmalloc(sizeof(*page), GFP_KERNEL);
+	if (!page) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	page->user_virt = (virt & PAGE_MASK);
+	page->refcnt    = 0;
+	page->umem      = ib_umem_get(&context->ibucontext, virt & PAGE_MASK,
+				      PAGE_SIZE, 0, 0);
+	if (IS_ERR(page->umem)) {
+		err = PTR_ERR(page->umem);
+		kfree(page);
+		goto out;
+	}
+
+	list_add(&page->list, &context->db_page_list);
+
+found:
+	chunk = list_entry(page->umem->chunk_list.next, struct ib_umem_chunk, list);
+	db->dma		= sg_dma_address(chunk->page_list) + (virt & ~PAGE_MASK);
+	db->u.user_page = page;
+	++page->refcnt;
+
+out:
+	mutex_unlock(&context->db_page_mutex);
+
+	return err;
+}
+
+void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db)
+{
+	mutex_lock(&context->db_page_mutex);
+
+	if (!--db->u.user_page->refcnt) {
+		list_del(&db->u.user_page->list);
+		ib_umem_release(db->u.user_page->umem);
+		kfree(db->u.user_page);
+	}
+
+	mutex_unlock(&context->db_page_mutex);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/Kconfig linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/Kconfig
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+config MLX5_INFINIBAND
+	tristate "Mellanox Connect-IB HCA support"
+	depends on NETDEVICES && ETHERNET && PCI && X86
+	select NET_VENDOR_MELLANOX
+	select MLX5_CORE
+	---help---
+	  This driver provides low-level InfiniBand support for
+	  Mellanox Connect-IB PCI Express host channel adapters (HCAs).
+	  This is required to use InfiniBand protocols such as
+	  IP-over-IB or SRP with these devices.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/mad.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/mad.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/mad.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/mad.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/mlx5/cmd.h>
+#include <rdma/ib_mad.h>
+#include <rdma/ib_smi.h>
+#include "mlx5_ib.h"
+
+enum {
+	MLX5_IB_VENDOR_CLASS1 = 0x9,
+	MLX5_IB_VENDOR_CLASS2 = 0xa
+};
+
+int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
+		 int port, struct ib_wc *in_wc, struct ib_grh *in_grh,
+		 void *in_mad, void *response_mad)
+{
+	u8 op_modifier = 0;
+
+	/* Key check traps can't be generated unless we have in_wc to
+	 * tell us where to send the trap.
+	 */
+	if (ignore_mkey || !in_wc)
+		op_modifier |= 0x1;
+	if (ignore_bkey || !in_wc)
+		op_modifier |= 0x2;
+
+	return mlx5_core_mad_ifc(&dev->mdev, in_mad, response_mad, op_modifier, port);
+}
+
+int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
+			struct ib_wc *in_wc, struct ib_grh *in_grh,
+			struct ib_mad *in_mad, struct ib_mad *out_mad)
+{
+	u16 slid;
+	int err;
+
+	slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
+
+	if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && slid == 0)
+		return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
+
+	if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+	    in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
+		if (in_mad->mad_hdr.method   != IB_MGMT_METHOD_GET &&
+		    in_mad->mad_hdr.method   != IB_MGMT_METHOD_SET &&
+		    in_mad->mad_hdr.method   != IB_MGMT_METHOD_TRAP_REPRESS)
+			return IB_MAD_RESULT_SUCCESS;
+
+		/* Don't process SMInfo queries -- the SMA can't handle them.
+		 */
+		if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO)
+			return IB_MAD_RESULT_SUCCESS;
+	} else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT ||
+		   in_mad->mad_hdr.mgmt_class == MLX5_IB_VENDOR_CLASS1   ||
+		   in_mad->mad_hdr.mgmt_class == MLX5_IB_VENDOR_CLASS2   ||
+		   in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_CONG_MGMT) {
+		if (in_mad->mad_hdr.method  != IB_MGMT_METHOD_GET &&
+		    in_mad->mad_hdr.method  != IB_MGMT_METHOD_SET)
+			return IB_MAD_RESULT_SUCCESS;
+	} else {
+		return IB_MAD_RESULT_SUCCESS;
+	}
+
+	err = mlx5_MAD_IFC(to_mdev(ibdev),
+			   mad_flags & IB_MAD_IGNORE_MKEY,
+			   mad_flags & IB_MAD_IGNORE_BKEY,
+			   port_num, in_wc, in_grh, in_mad, out_mad);
+	if (err)
+		return IB_MAD_RESULT_FAILURE;
+
+	/* set return bit in status of directed route responses */
+	if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+		out_mad->mad_hdr.status |= cpu_to_be16(1 << 15);
+
+	if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS)
+		/* no response for trap repress */
+		return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
+
+	return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
+}
+
+int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port)
+{
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int err = -ENOMEM;
+	u16 packet_error;
+
+	in_mad  = kzalloc(sizeof(*in_mad), GFP_KERNEL);
+	out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	init_query_mad(in_mad);
+	in_mad->attr_id = MLX5_ATTR_EXTENDED_PORT_INFO;
+	in_mad->attr_mod = cpu_to_be32(port);
+
+	err = mlx5_MAD_IFC(dev, 1, 1, 1, NULL, NULL, in_mad, out_mad);
+
+	packet_error = be16_to_cpu(out_mad->status);
+
+	dev->mdev.caps.ext_port_cap[port - 1] = (!err && !packet_error) ?
+		MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO : 0;
+
+out:
+	kfree(in_mad);
+	kfree(out_mad);
+	return err;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/main.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/main.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1507 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <asm-generic/kmap_types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/io-mapping.h>
+#include <linux/sched.h>
+#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_smi.h>
+#include <rdma/ib_umem.h>
+#include "user.h"
+#include "mlx5_ib.h"
+
+#define DRIVER_NAME "mlx5_ib"
+#define DRIVER_VERSION "1.0"
+#define DRIVER_RELDATE	"June 2013"
+
+MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox Connect-IB HCA IB driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+static int prof_sel = 2;
+module_param_named(prof_sel, prof_sel, int, 0444);
+MODULE_PARM_DESC(prof_sel, "profile selector. Valid range 0 - 2");
+
+static char mlx5_version[] =
+	DRIVER_NAME ": Mellanox Connect-IB Infiniband driver v"
+	DRIVER_VERSION " (" DRIVER_RELDATE ")\n";
+
+static struct mlx5_profile profile[] = {
+	[0] = {
+		.mask		= 0,
+	},
+	[1] = {
+		.mask		= MLX5_PROF_MASK_QP_SIZE,
+		.log_max_qp	= 12,
+	},
+	[2] = {
+		.mask		= MLX5_PROF_MASK_QP_SIZE |
+				  MLX5_PROF_MASK_MR_CACHE,
+		.log_max_qp	= 17,
+		.mr_cache[0]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[1]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[2]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[3]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[4]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[5]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[6]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[7]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[8]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[9]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[10]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[11]	= {
+			.size	= 500,
+			.limit	= 250
+		},
+		.mr_cache[12]	= {
+			.size	= 64,
+			.limit	= 32
+		},
+		.mr_cache[13]	= {
+			.size	= 32,
+			.limit	= 16
+		},
+		.mr_cache[14]	= {
+			.size	= 16,
+			.limit	= 8
+		},
+		.mr_cache[15]	= {
+			.size	= 8,
+			.limit	= 4
+		},
+	},
+};
+
+int mlx5_vector2eqn(struct mlx5_ib_dev *dev, int vector, int *eqn, int *irqn)
+{
+	struct mlx5_eq_table *table = &dev->mdev.priv.eq_table;
+	struct mlx5_eq *eq, *n;
+	int err = -ENOENT;
+
+	spin_lock(&table->lock);
+	list_for_each_entry_safe(eq, n, &dev->eqs_list, list) {
+		if (eq->index == vector) {
+			*eqn = eq->eqn;
+			*irqn = eq->irqn;
+			err = 0;
+			break;
+		}
+	}
+	spin_unlock(&table->lock);
+
+	return err;
+}
+
+static int alloc_comp_eqs(struct mlx5_ib_dev *dev)
+{
+	struct mlx5_eq_table *table = &dev->mdev.priv.eq_table;
+	struct mlx5_eq *eq, *n;
+	int ncomp_vec;
+	int nent;
+	int err;
+	int i;
+
+	INIT_LIST_HEAD(&dev->eqs_list);
+	ncomp_vec = table->num_comp_vectors;
+	nent = MLX5_COMP_EQ_SIZE;
+	for (i = 0; i < ncomp_vec; i++) {
+		eq = kzalloc(sizeof(*eq), GFP_KERNEL);
+		if (!eq) {
+			err = -ENOMEM;
+			goto clean;
+		}
+
+		snprintf(eq->name, MLX5_MAX_EQ_NAME, "mlx5_comp%d", i);
+		err = mlx5_create_map_eq(&dev->mdev, eq,
+					 i + MLX5_EQ_VEC_COMP_BASE, nent, 0,
+					 eq->name,
+					 &dev->mdev.priv.uuari.uars[0]);
+		if (err) {
+			kfree(eq);
+			goto clean;
+		}
+		mlx5_ib_dbg(dev, "allocated completion EQN %d\n", eq->eqn);
+		eq->index = i;
+		spin_lock(&table->lock);
+		list_add_tail(&eq->list, &dev->eqs_list);
+		spin_unlock(&table->lock);
+	}
+
+	dev->num_comp_vectors = ncomp_vec;
+	return 0;
+
+clean:
+	spin_lock(&table->lock);
+	list_for_each_entry_safe(eq, n, &dev->eqs_list, list) {
+		list_del(&eq->list);
+		spin_unlock(&table->lock);
+		if (mlx5_destroy_unmap_eq(&dev->mdev, eq))
+			mlx5_ib_warn(dev, "failed to destroy EQ 0x%x\n", eq->eqn);
+		kfree(eq);
+		spin_lock(&table->lock);
+	}
+	spin_unlock(&table->lock);
+	return err;
+}
+
+static void free_comp_eqs(struct mlx5_ib_dev *dev)
+{
+	struct mlx5_eq_table *table = &dev->mdev.priv.eq_table;
+	struct mlx5_eq *eq, *n;
+
+	spin_lock(&table->lock);
+	list_for_each_entry_safe(eq, n, &dev->eqs_list, list) {
+		list_del(&eq->list);
+		spin_unlock(&table->lock);
+		if (mlx5_destroy_unmap_eq(&dev->mdev, eq))
+			mlx5_ib_warn(dev, "failed to destroy EQ 0x%x\n", eq->eqn);
+		kfree(eq);
+		spin_lock(&table->lock);
+	}
+	spin_unlock(&table->lock);
+}
+
+static int mlx5_ib_query_device(struct ib_device *ibdev,
+				struct ib_device_attr *props)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibdev);
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int err = -ENOMEM;
+	int max_rq_sg;
+	int max_sq_sg;
+	u64 flags;
+
+	in_mad  = kzalloc(sizeof(*in_mad), GFP_KERNEL);
+	out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	init_query_mad(in_mad);
+	in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
+
+	err = mlx5_MAD_IFC(to_mdev(ibdev), 1, 1, 1, NULL, NULL, in_mad, out_mad);
+	if (err)
+		goto out;
+
+	memset(props, 0, sizeof(*props));
+
+	props->fw_ver = ((u64)fw_rev_maj(&dev->mdev) << 32) |
+		(fw_rev_min(&dev->mdev) << 16) |
+		fw_rev_sub(&dev->mdev);
+	props->device_cap_flags    = IB_DEVICE_CHANGE_PHY_PORT |
+		IB_DEVICE_PORT_ACTIVE_EVENT		|
+		IB_DEVICE_SYS_IMAGE_GUID		|
+		IB_DEVICE_RC_RNR_NAK_GEN		|
+		IB_DEVICE_BLOCK_MULTICAST_LOOPBACK;
+	flags = dev->mdev.caps.flags;
+	if (flags & MLX5_DEV_CAP_FLAG_BAD_PKEY_CNTR)
+		props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR;
+	if (flags & MLX5_DEV_CAP_FLAG_BAD_QKEY_CNTR)
+		props->device_cap_flags |= IB_DEVICE_BAD_QKEY_CNTR;
+	if (flags & MLX5_DEV_CAP_FLAG_APM)
+		props->device_cap_flags |= IB_DEVICE_AUTO_PATH_MIG;
+	props->device_cap_flags |= IB_DEVICE_LOCAL_DMA_LKEY;
+	if (flags & MLX5_DEV_CAP_FLAG_XRC)
+		props->device_cap_flags |= IB_DEVICE_XRC;
+	props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
+
+	props->vendor_id	   = be32_to_cpup((__be32 *)(out_mad->data + 36)) &
+		0xffffff;
+	props->vendor_part_id	   = be16_to_cpup((__be16 *)(out_mad->data + 30));
+	props->hw_ver		   = be32_to_cpup((__be32 *)(out_mad->data + 32));
+	memcpy(&props->sys_image_guid, out_mad->data +	4, 8);
+
+	props->max_mr_size	   = ~0ull;
+	props->page_size_cap	   = dev->mdev.caps.min_page_sz;
+	props->max_qp		   = 1 << dev->mdev.caps.log_max_qp;
+	props->max_qp_wr	   = dev->mdev.caps.max_wqes;
+	max_rq_sg = dev->mdev.caps.max_rq_desc_sz / sizeof(struct mlx5_wqe_data_seg);
+	max_sq_sg = (dev->mdev.caps.max_sq_desc_sz - sizeof(struct mlx5_wqe_ctrl_seg)) /
+		sizeof(struct mlx5_wqe_data_seg);
+	props->max_sge = min(max_rq_sg, max_sq_sg);
+	props->max_cq		   = 1 << dev->mdev.caps.log_max_cq;
+	props->max_cqe		   = dev->mdev.caps.max_cqes - 1;
+	props->max_mr		   = 1 << dev->mdev.caps.log_max_mkey;
+	props->max_pd		   = 1 << dev->mdev.caps.log_max_pd;
+	props->max_qp_rd_atom	   = dev->mdev.caps.max_ra_req_qp;
+	props->max_qp_init_rd_atom = dev->mdev.caps.max_ra_res_qp;
+	props->max_res_rd_atom	   = props->max_qp_rd_atom * props->max_qp;
+	props->max_srq		   = 1 << dev->mdev.caps.log_max_srq;
+	props->max_srq_wr	   = dev->mdev.caps.max_srq_wqes - 1;
+	props->max_srq_sge	   = max_rq_sg - 1;
+	props->max_fast_reg_page_list_len = (unsigned int)-1;
+	props->local_ca_ack_delay  = dev->mdev.caps.local_ca_ack_delay;
+	props->atomic_cap	   = dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_ATOMIC ?
+		IB_ATOMIC_HCA : IB_ATOMIC_NONE;
+	props->masked_atomic_cap   = IB_ATOMIC_HCA;
+	props->max_pkeys	   = be16_to_cpup((__be16 *)(out_mad->data + 28));
+	props->max_mcast_grp	   = 1 << dev->mdev.caps.log_max_mcg;
+	props->max_mcast_qp_attach = dev->mdev.caps.max_qp_mcg;
+	props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
+					   props->max_mcast_grp;
+	props->max_map_per_fmr = INT_MAX; /* no limit in ConnectIB */
+
+out:
+	kfree(in_mad);
+	kfree(out_mad);
+
+	return err;
+}
+
+int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
+		       struct ib_port_attr *props)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibdev);
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int ext_active_speed;
+	int err = -ENOMEM;
+
+	if (port < 1 || port > dev->mdev.caps.num_ports) {
+		mlx5_ib_warn(dev, "invalid port number %d\n", port);
+		return -EINVAL;
+	}
+
+	in_mad  = kzalloc(sizeof(*in_mad), GFP_KERNEL);
+	out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	memset(props, 0, sizeof(*props));
+
+	init_query_mad(in_mad);
+	in_mad->attr_id  = IB_SMP_ATTR_PORT_INFO;
+	in_mad->attr_mod = cpu_to_be32(port);
+
+	err = mlx5_MAD_IFC(dev, 1, 1, port, NULL, NULL, in_mad, out_mad);
+	if (err) {
+		mlx5_ib_warn(dev, "err %d\n", err);
+		goto out;
+	}
+
+
+	props->lid		= be16_to_cpup((__be16 *)(out_mad->data + 16));
+	props->lmc		= out_mad->data[34] & 0x7;
+	props->sm_lid		= be16_to_cpup((__be16 *)(out_mad->data + 18));
+	props->sm_sl		= out_mad->data[36] & 0xf;
+	props->state		= out_mad->data[32] & 0xf;
+	props->phys_state	= out_mad->data[33] >> 4;
+	props->port_cap_flags	= be32_to_cpup((__be32 *)(out_mad->data + 20));
+	props->gid_tbl_len	= out_mad->data[50];
+	props->max_msg_sz	= 1 << to_mdev(ibdev)->mdev.caps.log_max_msg;
+	props->pkey_tbl_len	= to_mdev(ibdev)->mdev.caps.port[port - 1].pkey_table_len;
+	props->bad_pkey_cntr	= be16_to_cpup((__be16 *)(out_mad->data + 46));
+	props->qkey_viol_cntr	= be16_to_cpup((__be16 *)(out_mad->data + 48));
+	props->active_width	= out_mad->data[31] & 0xf;
+	props->active_speed	= out_mad->data[35] >> 4;
+	props->max_mtu		= out_mad->data[41] & 0xf;
+	props->active_mtu	= out_mad->data[36] >> 4;
+	props->subnet_timeout	= out_mad->data[51] & 0x1f;
+	props->max_vl_num	= out_mad->data[37] >> 4;
+	props->init_type_reply	= out_mad->data[41] >> 4;
+
+	/* Check if extended speeds (EDR/FDR/...) are supported */
+	if (props->port_cap_flags & IB_PORT_EXTENDED_SPEEDS_SUP) {
+		ext_active_speed = out_mad->data[62] >> 4;
+
+		switch (ext_active_speed) {
+		case 1:
+			props->active_speed = 16; /* FDR */
+			break;
+		case 2:
+			props->active_speed = 32; /* EDR */
+			break;
+		}
+	}
+
+	/* If reported active speed is QDR, check if is FDR-10 */
+	if (props->active_speed == 4) {
+		if (dev->mdev.caps.ext_port_cap[port - 1] &
+		    MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO) {
+			init_query_mad(in_mad);
+			in_mad->attr_id = MLX5_ATTR_EXTENDED_PORT_INFO;
+			in_mad->attr_mod = cpu_to_be32(port);
+
+			err = mlx5_MAD_IFC(dev, 1, 1, port,
+					   NULL, NULL, in_mad, out_mad);
+			if (err)
+				goto out;
+
+			/* Checking LinkSpeedActive for FDR-10 */
+			if (out_mad->data[15] & 0x1)
+				props->active_speed = 8;
+		}
+	}
+
+out:
+	kfree(in_mad);
+	kfree(out_mad);
+
+	return err;
+}
+
+static int mlx5_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
+			     union ib_gid *gid)
+{
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int err = -ENOMEM;
+
+	in_mad  = kzalloc(sizeof(*in_mad), GFP_KERNEL);
+	out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	init_query_mad(in_mad);
+	in_mad->attr_id  = IB_SMP_ATTR_PORT_INFO;
+	in_mad->attr_mod = cpu_to_be32(port);
+
+	err = mlx5_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad);
+	if (err)
+		goto out;
+
+	memcpy(gid->raw, out_mad->data + 8, 8);
+
+	init_query_mad(in_mad);
+	in_mad->attr_id  = IB_SMP_ATTR_GUID_INFO;
+	in_mad->attr_mod = cpu_to_be32(index / 8);
+
+	err = mlx5_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad);
+	if (err)
+		goto out;
+
+	memcpy(gid->raw + 8, out_mad->data + (index % 8) * 8, 8);
+
+out:
+	kfree(in_mad);
+	kfree(out_mad);
+	return err;
+}
+
+static int mlx5_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
+			      u16 *pkey)
+{
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int err = -ENOMEM;
+
+	in_mad  = kzalloc(sizeof(*in_mad), GFP_KERNEL);
+	out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	init_query_mad(in_mad);
+	in_mad->attr_id  = IB_SMP_ATTR_PKEY_TABLE;
+	in_mad->attr_mod = cpu_to_be32(index / 32);
+
+	err = mlx5_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad);
+	if (err)
+		goto out;
+
+	*pkey = be16_to_cpu(((__be16 *)out_mad->data)[index % 32]);
+
+out:
+	kfree(in_mad);
+	kfree(out_mad);
+	return err;
+}
+
+struct mlx5_reg_node_desc {
+	u8	desc[64];
+};
+
+static int mlx5_ib_modify_device(struct ib_device *ibdev, int mask,
+				 struct ib_device_modify *props)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibdev);
+	struct mlx5_reg_node_desc in;
+	struct mlx5_reg_node_desc out;
+	int err;
+
+	if (mask & ~IB_DEVICE_MODIFY_NODE_DESC)
+		return -EOPNOTSUPP;
+
+	if (!(mask & IB_DEVICE_MODIFY_NODE_DESC))
+		return 0;
+
+	/*
+	 * If possible, pass node desc to FW, so it can generate
+	 * a 144 trap.  If cmd fails, just ignore.
+	 */
+	memcpy(&in, props->node_desc, 64);
+	err = mlx5_core_access_reg(&dev->mdev, &in, sizeof(in), &out,
+				   sizeof(out), MLX5_REG_NODE_DESC, 0, 1);
+	if (err)
+		return err;
+
+	memcpy(ibdev->node_desc, props->node_desc, 64);
+
+	return err;
+}
+
+static int mlx5_ib_modify_port(struct ib_device *ibdev, u8 port, int mask,
+			       struct ib_port_modify *props)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibdev);
+	struct ib_port_attr attr;
+	u32 tmp;
+	int err;
+
+	mutex_lock(&dev->cap_mask_mutex);
+
+	err = mlx5_ib_query_port(ibdev, port, &attr);
+	if (err)
+		goto out;
+
+	tmp = (attr.port_cap_flags | props->set_port_cap_mask) &
+		~props->clr_port_cap_mask;
+
+	err = mlx5_set_port_caps(&dev->mdev, port, tmp);
+
+out:
+	mutex_unlock(&dev->cap_mask_mutex);
+	return err;
+}
+
+static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
+						  struct ib_udata *udata)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibdev);
+	struct mlx5_ib_alloc_ucontext_req req;
+	struct mlx5_ib_alloc_ucontext_resp resp;
+	struct mlx5_ib_ucontext *context;
+	struct mlx5_uuar_info *uuari;
+	struct mlx5_uar *uars;
+	int num_uars;
+	int uuarn;
+	int err;
+	int i;
+
+	if (!dev->ib_active)
+		return ERR_PTR(-EAGAIN);
+
+	err = ib_copy_from_udata(&req, udata, sizeof(req));
+	if (err)
+		return ERR_PTR(err);
+
+	if (req.total_num_uuars > MLX5_MAX_UUARS)
+		return ERR_PTR(-ENOMEM);
+
+	if (req.total_num_uuars == 0)
+		return ERR_PTR(-EINVAL);
+
+	req.total_num_uuars = ALIGN(req.total_num_uuars, MLX5_BF_REGS_PER_PAGE);
+	if (req.num_low_latency_uuars > req.total_num_uuars - 1)
+		return ERR_PTR(-EINVAL);
+
+	num_uars = req.total_num_uuars / MLX5_BF_REGS_PER_PAGE;
+	resp.qp_tab_size      = 1 << dev->mdev.caps.log_max_qp;
+	resp.bf_reg_size      = dev->mdev.caps.bf_reg_size;
+	resp.cache_line_size  = L1_CACHE_BYTES;
+	resp.max_sq_desc_sz = dev->mdev.caps.max_sq_desc_sz;
+	resp.max_rq_desc_sz = dev->mdev.caps.max_rq_desc_sz;
+	resp.max_send_wqebb = dev->mdev.caps.max_wqes;
+	resp.max_recv_wr = dev->mdev.caps.max_wqes;
+	resp.max_srq_recv_wr = dev->mdev.caps.max_srq_wqes;
+
+	context = kzalloc(sizeof(*context), GFP_KERNEL);
+	if (!context)
+		return ERR_PTR(-ENOMEM);
+
+	uuari = &context->uuari;
+	mutex_init(&uuari->lock);
+	uars = kcalloc(num_uars, sizeof(*uars), GFP_KERNEL);
+	if (!uars) {
+		err = -ENOMEM;
+		goto out_ctx;
+	}
+
+	uuari->bitmap = kcalloc(BITS_TO_LONGS(req.total_num_uuars),
+				sizeof(*uuari->bitmap),
+				GFP_KERNEL);
+	if (!uuari->bitmap) {
+		err = -ENOMEM;
+		goto out_uar_ctx;
+	}
+	/*
+	 * clear all fast path uuars
+	 */
+	for (i = 0; i < req.total_num_uuars; i++) {
+		uuarn = i & 3;
+		if (uuarn == 2 || uuarn == 3)
+			set_bit(i, uuari->bitmap);
+	}
+
+	uuari->count = kcalloc(req.total_num_uuars, sizeof(*uuari->count), GFP_KERNEL);
+	if (!uuari->count) {
+		err = -ENOMEM;
+		goto out_bitmap;
+	}
+
+	for (i = 0; i < num_uars; i++) {
+		err = mlx5_cmd_alloc_uar(&dev->mdev, &uars[i].index);
+		if (err)
+			goto out_count;
+	}
+
+	INIT_LIST_HEAD(&context->db_page_list);
+	mutex_init(&context->db_page_mutex);
+
+	resp.tot_uuars = req.total_num_uuars;
+	resp.num_ports = dev->mdev.caps.num_ports;
+	err = ib_copy_to_udata(udata, &resp,
+			       sizeof(resp) - sizeof(resp.reserved));
+	if (err)
+		goto out_uars;
+
+	uuari->num_low_latency_uuars = req.num_low_latency_uuars;
+	uuari->uars = uars;
+	uuari->num_uars = num_uars;
+	return &context->ibucontext;
+
+out_uars:
+	for (i--; i >= 0; i--)
+		mlx5_cmd_free_uar(&dev->mdev, uars[i].index);
+out_count:
+	kfree(uuari->count);
+
+out_bitmap:
+	kfree(uuari->bitmap);
+
+out_uar_ctx:
+	kfree(uars);
+
+out_ctx:
+	kfree(context);
+	return ERR_PTR(err);
+}
+
+static int mlx5_ib_dealloc_ucontext(struct ib_ucontext *ibcontext)
+{
+	struct mlx5_ib_ucontext *context = to_mucontext(ibcontext);
+	struct mlx5_ib_dev *dev = to_mdev(ibcontext->device);
+	struct mlx5_uuar_info *uuari = &context->uuari;
+	int i;
+
+	for (i = 0; i < uuari->num_uars; i++) {
+		if (mlx5_cmd_free_uar(&dev->mdev, uuari->uars[i].index))
+			mlx5_ib_warn(dev, "failed to free UAR 0x%x\n", uuari->uars[i].index);
+	}
+
+	kfree(uuari->count);
+	kfree(uuari->bitmap);
+	kfree(uuari->uars);
+	kfree(context);
+
+	return 0;
+}
+
+static phys_addr_t uar_index2pfn(struct mlx5_ib_dev *dev, int index)
+{
+	return (pci_resource_start(dev->mdev.pdev, 0) >> PAGE_SHIFT) + index;
+}
+
+static int get_command(unsigned long offset)
+{
+	return (offset >> MLX5_IB_MMAP_CMD_SHIFT) & MLX5_IB_MMAP_CMD_MASK;
+}
+
+static int get_arg(unsigned long offset)
+{
+	return offset & ((1 << MLX5_IB_MMAP_CMD_SHIFT) - 1);
+}
+
+static int get_index(unsigned long offset)
+{
+	return get_arg(offset);
+}
+
+static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma)
+{
+	struct mlx5_ib_ucontext *context = to_mucontext(ibcontext);
+	struct mlx5_ib_dev *dev = to_mdev(ibcontext->device);
+	struct mlx5_uuar_info *uuari = &context->uuari;
+	unsigned long command;
+	unsigned long idx;
+	phys_addr_t pfn;
+
+	command = get_command(vma->vm_pgoff);
+	switch (command) {
+	case MLX5_IB_MMAP_REGULAR_PAGE:
+		if (vma->vm_end - vma->vm_start != PAGE_SIZE)
+			return -EINVAL;
+
+		idx = get_index(vma->vm_pgoff);
+		pfn = uar_index2pfn(dev, uuari->uars[idx].index);
+		mlx5_ib_dbg(dev, "uar idx 0x%lx, pfn 0x%llx\n", idx,
+			    (unsigned long long)pfn);
+
+		if (idx >= uuari->num_uars)
+			return -EINVAL;
+
+		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+		if (io_remap_pfn_range(vma, vma->vm_start, pfn,
+				       PAGE_SIZE, vma->vm_page_prot))
+			return -EAGAIN;
+
+		mlx5_ib_dbg(dev, "mapped WC at 0x%lx, PA 0x%llx\n",
+			    vma->vm_start,
+			    (unsigned long long)pfn << PAGE_SHIFT);
+		break;
+
+	case MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES:
+		return -ENOSYS;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int alloc_pa_mkey(struct mlx5_ib_dev *dev, u32 *key, u32 pdn)
+{
+	struct mlx5_create_mkey_mbox_in *in;
+	struct mlx5_mkey_seg *seg;
+	struct mlx5_core_mr mr;
+	int err;
+
+	in = kzalloc(sizeof(*in), GFP_KERNEL);
+	if (!in)
+		return -ENOMEM;
+
+	seg = &in->seg;
+	seg->flags = MLX5_PERM_LOCAL_READ | MLX5_ACCESS_MODE_PA;
+	seg->flags_pd = cpu_to_be32(pdn | MLX5_MKEY_LEN64);
+	seg->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
+	seg->start_addr = 0;
+
+	err = mlx5_core_create_mkey(&dev->mdev, &mr, in, sizeof(*in));
+	if (err) {
+		mlx5_ib_warn(dev, "failed to create mkey, %d\n", err);
+		goto err_in;
+	}
+
+	kfree(in);
+	*key = mr.key;
+
+	return 0;
+
+err_in:
+	kfree(in);
+
+	return err;
+}
+
+static void free_pa_mkey(struct mlx5_ib_dev *dev, u32 key)
+{
+	struct mlx5_core_mr mr;
+	int err;
+
+	memset(&mr, 0, sizeof(mr));
+	mr.key = key;
+	err = mlx5_core_destroy_mkey(&dev->mdev, &mr);
+	if (err)
+		mlx5_ib_warn(dev, "failed to destroy mkey 0x%x\n", key);
+}
+
+static struct ib_pd *mlx5_ib_alloc_pd(struct ib_device *ibdev,
+				      struct ib_ucontext *context,
+				      struct ib_udata *udata)
+{
+	struct mlx5_ib_alloc_pd_resp resp;
+	struct mlx5_ib_pd *pd;
+	int err;
+
+	pd = kmalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return ERR_PTR(-ENOMEM);
+
+	err = mlx5_core_alloc_pd(&to_mdev(ibdev)->mdev, &pd->pdn);
+	if (err) {
+		kfree(pd);
+		return ERR_PTR(err);
+	}
+
+	if (context) {
+		resp.pdn = pd->pdn;
+		if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
+			mlx5_core_dealloc_pd(&to_mdev(ibdev)->mdev, pd->pdn);
+			kfree(pd);
+			return ERR_PTR(-EFAULT);
+		}
+	} else {
+		err = alloc_pa_mkey(to_mdev(ibdev), &pd->pa_lkey, pd->pdn);
+		if (err) {
+			mlx5_core_dealloc_pd(&to_mdev(ibdev)->mdev, pd->pdn);
+			kfree(pd);
+			return ERR_PTR(err);
+		}
+	}
+
+	return &pd->ibpd;
+}
+
+static int mlx5_ib_dealloc_pd(struct ib_pd *pd)
+{
+	struct mlx5_ib_dev *mdev = to_mdev(pd->device);
+	struct mlx5_ib_pd *mpd = to_mpd(pd);
+
+	if (!pd->uobject)
+		free_pa_mkey(mdev, mpd->pa_lkey);
+
+	mlx5_core_dealloc_pd(&mdev->mdev, mpd->pdn);
+	kfree(mpd);
+
+	return 0;
+}
+
+static int mlx5_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
+	int err;
+
+	err = mlx5_core_attach_mcg(&dev->mdev, gid, ibqp->qp_num);
+	if (err)
+		mlx5_ib_warn(dev, "failed attaching QPN 0x%x, MGID %pI6\n",
+			     ibqp->qp_num, gid->raw);
+
+	return err;
+}
+
+static int mlx5_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
+	int err;
+
+	err = mlx5_core_detach_mcg(&dev->mdev, gid, ibqp->qp_num);
+	if (err)
+		mlx5_ib_warn(dev, "failed detaching QPN 0x%x, MGID %pI6\n",
+			     ibqp->qp_num, gid->raw);
+
+	return err;
+}
+
+static int init_node_data(struct mlx5_ib_dev *dev)
+{
+	struct ib_smp *in_mad  = NULL;
+	struct ib_smp *out_mad = NULL;
+	int err = -ENOMEM;
+
+	in_mad  = kzalloc(sizeof(*in_mad), GFP_KERNEL);
+	out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
+	if (!in_mad || !out_mad)
+		goto out;
+
+	init_query_mad(in_mad);
+	in_mad->attr_id = IB_SMP_ATTR_NODE_DESC;
+
+	err = mlx5_MAD_IFC(dev, 1, 1, 1, NULL, NULL, in_mad, out_mad);
+	if (err)
+		goto out;
+
+	memcpy(dev->ib_dev.node_desc, out_mad->data, 64);
+
+	in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
+
+	err = mlx5_MAD_IFC(dev, 1, 1, 1, NULL, NULL, in_mad, out_mad);
+	if (err)
+		goto out;
+
+	dev->mdev.rev_id = be32_to_cpup((__be32 *)(out_mad->data + 32));
+	memcpy(&dev->ib_dev.node_guid, out_mad->data + 12, 8);
+
+out:
+	kfree(in_mad);
+	kfree(out_mad);
+	return err;
+}
+
+static ssize_t show_fw_pages(struct device *device, struct device_attribute *attr,
+			     char *buf)
+{
+	struct mlx5_ib_dev *dev =
+		container_of(device, struct mlx5_ib_dev, ib_dev.dev);
+
+	return sprintf(buf, "%d\n", dev->mdev.priv.fw_pages);
+}
+
+static ssize_t show_reg_pages(struct device *device,
+			      struct device_attribute *attr, char *buf)
+{
+	struct mlx5_ib_dev *dev =
+		container_of(device, struct mlx5_ib_dev, ib_dev.dev);
+
+	return sprintf(buf, "%d\n", dev->mdev.priv.reg_pages);
+}
+
+static ssize_t show_hca(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct mlx5_ib_dev *dev =
+		container_of(device, struct mlx5_ib_dev, ib_dev.dev);
+	return sprintf(buf, "MT%d\n", dev->mdev.pdev->device);
+}
+
+static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
+			   char *buf)
+{
+	struct mlx5_ib_dev *dev =
+		container_of(device, struct mlx5_ib_dev, ib_dev.dev);
+	return sprintf(buf, "%d.%d.%d\n", fw_rev_maj(&dev->mdev),
+		       fw_rev_min(&dev->mdev), fw_rev_sub(&dev->mdev));
+}
+
+static ssize_t show_rev(struct device *device, struct device_attribute *attr,
+			char *buf)
+{
+	struct mlx5_ib_dev *dev =
+		container_of(device, struct mlx5_ib_dev, ib_dev.dev);
+	return sprintf(buf, "%x\n", dev->mdev.rev_id);
+}
+
+static ssize_t show_board(struct device *device, struct device_attribute *attr,
+			  char *buf)
+{
+	struct mlx5_ib_dev *dev =
+		container_of(device, struct mlx5_ib_dev, ib_dev.dev);
+	return sprintf(buf, "%.*s\n", MLX5_BOARD_ID_LEN,
+		       dev->mdev.board_id);
+}
+
+static DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
+static DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
+static DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
+static DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
+static DEVICE_ATTR(fw_pages, S_IRUGO, show_fw_pages, NULL);
+static DEVICE_ATTR(reg_pages, S_IRUGO, show_reg_pages, NULL);
+
+static struct device_attribute *mlx5_class_attributes[] = {
+	&dev_attr_hw_rev,
+	&dev_attr_fw_ver,
+	&dev_attr_hca_type,
+	&dev_attr_board_id,
+	&dev_attr_fw_pages,
+	&dev_attr_reg_pages,
+};
+
+static void mlx5_ib_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
+			  void *data)
+{
+	struct mlx5_ib_dev *ibdev = container_of(dev, struct mlx5_ib_dev, mdev);
+	struct ib_event ibev;
+	u8 port = 0;
+
+	switch (event) {
+	case MLX5_DEV_EVENT_SYS_ERROR:
+		ibdev->ib_active = false;
+		ibev.event = IB_EVENT_DEVICE_FATAL;
+		break;
+
+	case MLX5_DEV_EVENT_PORT_UP:
+		ibev.event = IB_EVENT_PORT_ACTIVE;
+		port = *(u8 *)data;
+		break;
+
+	case MLX5_DEV_EVENT_PORT_DOWN:
+		ibev.event = IB_EVENT_PORT_ERR;
+		port = *(u8 *)data;
+		break;
+
+	case MLX5_DEV_EVENT_PORT_INITIALIZED:
+		/* not used by ULPs */
+		return;
+
+	case MLX5_DEV_EVENT_LID_CHANGE:
+		ibev.event = IB_EVENT_LID_CHANGE;
+		port = *(u8 *)data;
+		break;
+
+	case MLX5_DEV_EVENT_PKEY_CHANGE:
+		ibev.event = IB_EVENT_PKEY_CHANGE;
+		port = *(u8 *)data;
+		break;
+
+	case MLX5_DEV_EVENT_GUID_CHANGE:
+		ibev.event = IB_EVENT_GID_CHANGE;
+		port = *(u8 *)data;
+		break;
+
+	case MLX5_DEV_EVENT_CLIENT_REREG:
+		ibev.event = IB_EVENT_CLIENT_REREGISTER;
+		port = *(u8 *)data;
+		break;
+	}
+
+	ibev.device	      = &ibdev->ib_dev;
+	ibev.element.port_num = port;
+
+	if (ibdev->ib_active)
+		ib_dispatch_event(&ibev);
+}
+
+static void get_ext_port_caps(struct mlx5_ib_dev *dev)
+{
+	int port;
+
+	for (port = 1; port <= dev->mdev.caps.num_ports; port++)
+		mlx5_query_ext_port_caps(dev, port);
+}
+
+static int get_port_caps(struct mlx5_ib_dev *dev)
+{
+	struct ib_device_attr *dprops = NULL;
+	struct ib_port_attr *pprops = NULL;
+	int err = 0;
+	int port;
+
+	pprops = kmalloc(sizeof(*pprops), GFP_KERNEL);
+	if (!pprops)
+		goto out;
+
+	dprops = kmalloc(sizeof(*dprops), GFP_KERNEL);
+	if (!dprops)
+		goto out;
+
+	err = mlx5_ib_query_device(&dev->ib_dev, dprops);
+	if (err) {
+		mlx5_ib_warn(dev, "query_device failed %d\n", err);
+		goto out;
+	}
+
+	for (port = 1; port <= dev->mdev.caps.num_ports; port++) {
+		err = mlx5_ib_query_port(&dev->ib_dev, port, pprops);
+		if (err) {
+			mlx5_ib_warn(dev, "query_port %d failed %d\n", port, err);
+			break;
+		}
+		dev->mdev.caps.port[port - 1].pkey_table_len = dprops->max_pkeys;
+		dev->mdev.caps.port[port - 1].gid_table_len = pprops->gid_tbl_len;
+		mlx5_ib_dbg(dev, "pkey_table_len %d, gid_table_len %d\n",
+			    dprops->max_pkeys, pprops->gid_tbl_len);
+	}
+
+out:
+	kfree(pprops);
+	kfree(dprops);
+
+	return err;
+}
+
+static void destroy_umrc_res(struct mlx5_ib_dev *dev)
+{
+	int err;
+
+	err = mlx5_mr_cache_cleanup(dev);
+	if (err)
+		mlx5_ib_warn(dev, "mr cache cleanup failed\n");
+
+	mlx5_ib_destroy_qp(dev->umrc.qp);
+	ib_destroy_cq(dev->umrc.cq);
+	ib_dereg_mr(dev->umrc.mr);
+	ib_dealloc_pd(dev->umrc.pd);
+}
+
+enum {
+	MAX_UMR_WR = 128,
+};
+
+static int create_umr_res(struct mlx5_ib_dev *dev)
+{
+	struct ib_qp_init_attr *init_attr = NULL;
+	struct ib_qp_attr *attr = NULL;
+	struct ib_pd *pd;
+	struct ib_cq *cq;
+	struct ib_qp *qp;
+	struct ib_mr *mr;
+	int ret;
+
+	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+	init_attr = kzalloc(sizeof(*init_attr), GFP_KERNEL);
+	if (!attr || !init_attr) {
+		ret = -ENOMEM;
+		goto error_0;
+	}
+
+	pd = ib_alloc_pd(&dev->ib_dev);
+	if (IS_ERR(pd)) {
+		mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n");
+		ret = PTR_ERR(pd);
+		goto error_0;
+	}
+
+	mr = ib_get_dma_mr(pd,  IB_ACCESS_LOCAL_WRITE);
+	if (IS_ERR(mr)) {
+		mlx5_ib_dbg(dev, "Couldn't create DMA MR for sync UMR QP\n");
+		ret = PTR_ERR(mr);
+		goto error_1;
+	}
+
+	cq = ib_create_cq(&dev->ib_dev, mlx5_umr_cq_handler, NULL, NULL, 128,
+			  0);
+	if (IS_ERR(cq)) {
+		mlx5_ib_dbg(dev, "Couldn't create CQ for sync UMR QP\n");
+		ret = PTR_ERR(cq);
+		goto error_2;
+	}
+	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+
+	init_attr->send_cq = cq;
+	init_attr->recv_cq = cq;
+	init_attr->sq_sig_type = IB_SIGNAL_ALL_WR;
+	init_attr->cap.max_send_wr = MAX_UMR_WR;
+	init_attr->cap.max_send_sge = 1;
+	init_attr->qp_type = MLX5_IB_QPT_REG_UMR;
+	init_attr->port_num = 1;
+	qp = mlx5_ib_create_qp(pd, init_attr, NULL);
+	if (IS_ERR(qp)) {
+		mlx5_ib_dbg(dev, "Couldn't create sync UMR QP\n");
+		ret = PTR_ERR(qp);
+		goto error_3;
+	}
+	qp->device     = &dev->ib_dev;
+	qp->real_qp    = qp;
+	qp->uobject    = NULL;
+	qp->qp_type    = MLX5_IB_QPT_REG_UMR;
+
+	attr->qp_state = IB_QPS_INIT;
+	attr->port_num = 1;
+	ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE | IB_QP_PKEY_INDEX |
+				IB_QP_PORT, NULL);
+	if (ret) {
+		mlx5_ib_dbg(dev, "Couldn't modify UMR QP\n");
+		goto error_4;
+	}
+
+	memset(attr, 0, sizeof(*attr));
+	attr->qp_state = IB_QPS_RTR;
+	attr->path_mtu = IB_MTU_256;
+
+	ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE, NULL);
+	if (ret) {
+		mlx5_ib_dbg(dev, "Couldn't modify umr QP to rtr\n");
+		goto error_4;
+	}
+
+	memset(attr, 0, sizeof(*attr));
+	attr->qp_state = IB_QPS_RTS;
+	ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE, NULL);
+	if (ret) {
+		mlx5_ib_dbg(dev, "Couldn't modify umr QP to rts\n");
+		goto error_4;
+	}
+
+	dev->umrc.qp = qp;
+	dev->umrc.cq = cq;
+	dev->umrc.mr = mr;
+	dev->umrc.pd = pd;
+
+	sema_init(&dev->umrc.sem, MAX_UMR_WR);
+	ret = mlx5_mr_cache_init(dev);
+	if (ret) {
+		mlx5_ib_warn(dev, "mr cache init failed %d\n", ret);
+		goto error_4;
+	}
+
+	kfree(attr);
+	kfree(init_attr);
+
+	return 0;
+
+error_4:
+	mlx5_ib_destroy_qp(qp);
+
+error_3:
+	ib_destroy_cq(cq);
+
+error_2:
+	ib_dereg_mr(mr);
+
+error_1:
+	ib_dealloc_pd(pd);
+
+error_0:
+	kfree(attr);
+	kfree(init_attr);
+	return ret;
+}
+
+static int create_dev_resources(struct mlx5_ib_resources *devr)
+{
+	struct ib_srq_init_attr attr;
+	struct mlx5_ib_dev *dev;
+	int ret = 0;
+
+	dev = container_of(devr, struct mlx5_ib_dev, devr);
+
+	devr->p0 = mlx5_ib_alloc_pd(&dev->ib_dev, NULL, NULL);
+	if (IS_ERR(devr->p0)) {
+		ret = PTR_ERR(devr->p0);
+		goto error0;
+	}
+	devr->p0->device  = &dev->ib_dev;
+	devr->p0->uobject = NULL;
+	atomic_set(&devr->p0->usecnt, 0);
+
+	devr->c0 = mlx5_ib_create_cq(&dev->ib_dev, 1, 0, NULL, NULL);
+	if (IS_ERR(devr->c0)) {
+		ret = PTR_ERR(devr->c0);
+		goto error1;
+	}
+	devr->c0->device        = &dev->ib_dev;
+	devr->c0->uobject       = NULL;
+	devr->c0->comp_handler  = NULL;
+	devr->c0->event_handler = NULL;
+	devr->c0->cq_context    = NULL;
+	atomic_set(&devr->c0->usecnt, 0);
+
+	devr->x0 = mlx5_ib_alloc_xrcd(&dev->ib_dev, NULL, NULL);
+	if (IS_ERR(devr->x0)) {
+		ret = PTR_ERR(devr->x0);
+		goto error2;
+	}
+	devr->x0->device = &dev->ib_dev;
+	devr->x0->inode = NULL;
+	atomic_set(&devr->x0->usecnt, 0);
+	mutex_init(&devr->x0->tgt_qp_mutex);
+	INIT_LIST_HEAD(&devr->x0->tgt_qp_list);
+
+	devr->x1 = mlx5_ib_alloc_xrcd(&dev->ib_dev, NULL, NULL);
+	if (IS_ERR(devr->x1)) {
+		ret = PTR_ERR(devr->x1);
+		goto error3;
+	}
+	devr->x1->device = &dev->ib_dev;
+	devr->x1->inode = NULL;
+	atomic_set(&devr->x1->usecnt, 0);
+	mutex_init(&devr->x1->tgt_qp_mutex);
+	INIT_LIST_HEAD(&devr->x1->tgt_qp_list);
+
+	memset(&attr, 0, sizeof(attr));
+	attr.attr.max_sge = 1;
+	attr.attr.max_wr = 1;
+	attr.srq_type = IB_SRQT_XRC;
+	attr.ext.xrc.cq = devr->c0;
+	attr.ext.xrc.xrcd = devr->x0;
+
+	devr->s0 = mlx5_ib_create_srq(devr->p0, &attr, NULL);
+	if (IS_ERR(devr->s0)) {
+		ret = PTR_ERR(devr->s0);
+		goto error4;
+	}
+	devr->s0->device	= &dev->ib_dev;
+	devr->s0->pd		= devr->p0;
+	devr->s0->uobject       = NULL;
+	devr->s0->event_handler = NULL;
+	devr->s0->srq_context   = NULL;
+	devr->s0->srq_type      = IB_SRQT_XRC;
+	devr->s0->ext.xrc.xrcd	= devr->x0;
+	devr->s0->ext.xrc.cq	= devr->c0;
+	atomic_inc(&devr->s0->ext.xrc.xrcd->usecnt);
+	atomic_inc(&devr->s0->ext.xrc.cq->usecnt);
+	atomic_inc(&devr->p0->usecnt);
+	atomic_set(&devr->s0->usecnt, 0);
+
+	return 0;
+
+error4:
+	mlx5_ib_dealloc_xrcd(devr->x1);
+error3:
+	mlx5_ib_dealloc_xrcd(devr->x0);
+error2:
+	mlx5_ib_destroy_cq(devr->c0);
+error1:
+	mlx5_ib_dealloc_pd(devr->p0);
+error0:
+	return ret;
+}
+
+static void destroy_dev_resources(struct mlx5_ib_resources *devr)
+{
+	mlx5_ib_destroy_srq(devr->s0);
+	mlx5_ib_dealloc_xrcd(devr->x0);
+	mlx5_ib_dealloc_xrcd(devr->x1);
+	mlx5_ib_destroy_cq(devr->c0);
+	mlx5_ib_dealloc_pd(devr->p0);
+}
+
+static int init_one(struct pci_dev *pdev,
+		    const struct pci_device_id *id)
+{
+	struct mlx5_core_dev *mdev;
+	struct mlx5_ib_dev *dev;
+	int err;
+	int i;
+
+	printk_once(KERN_INFO "%s", mlx5_version);
+
+	dev = (struct mlx5_ib_dev *)ib_alloc_device(sizeof(*dev));
+	if (!dev)
+		return -ENOMEM;
+
+	mdev = &dev->mdev;
+	mdev->event = mlx5_ib_event;
+	if (prof_sel >= ARRAY_SIZE(profile)) {
+		pr_warn("selected pofile out of range, selceting default\n");
+		prof_sel = 0;
+	}
+	mdev->profile = &profile[prof_sel];
+	err = mlx5_dev_init(mdev, pdev);
+	if (err)
+		goto err_free;
+
+	err = get_port_caps(dev);
+	if (err)
+		goto err_cleanup;
+
+	get_ext_port_caps(dev);
+
+	err = alloc_comp_eqs(dev);
+	if (err)
+		goto err_cleanup;
+
+	MLX5_INIT_DOORBELL_LOCK(&dev->uar_lock);
+
+	strlcpy(dev->ib_dev.name, "mlx5_%d", IB_DEVICE_NAME_MAX);
+	dev->ib_dev.owner		= THIS_MODULE;
+	dev->ib_dev.node_type		= RDMA_NODE_IB_CA;
+	dev->ib_dev.local_dma_lkey	= mdev->caps.reserved_lkey;
+	dev->num_ports		= mdev->caps.num_ports;
+	dev->ib_dev.phys_port_cnt     = dev->num_ports;
+	dev->ib_dev.num_comp_vectors	= dev->num_comp_vectors;
+	dev->ib_dev.dma_device	= &mdev->pdev->dev;
+
+	dev->ib_dev.uverbs_abi_ver	= MLX5_IB_UVERBS_ABI_VERSION;
+	dev->ib_dev.uverbs_cmd_mask	=
+		(1ull << IB_USER_VERBS_CMD_GET_CONTEXT)		|
+		(1ull << IB_USER_VERBS_CMD_QUERY_DEVICE)	|
+		(1ull << IB_USER_VERBS_CMD_QUERY_PORT)		|
+		(1ull << IB_USER_VERBS_CMD_ALLOC_PD)		|
+		(1ull << IB_USER_VERBS_CMD_DEALLOC_PD)		|
+		(1ull << IB_USER_VERBS_CMD_REG_MR)		|
+		(1ull << IB_USER_VERBS_CMD_DEREG_MR)		|
+		(1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL)	|
+		(1ull << IB_USER_VERBS_CMD_CREATE_CQ)		|
+		(1ull << IB_USER_VERBS_CMD_RESIZE_CQ)		|
+		(1ull << IB_USER_VERBS_CMD_DESTROY_CQ)		|
+		(1ull << IB_USER_VERBS_CMD_CREATE_QP)		|
+		(1ull << IB_USER_VERBS_CMD_MODIFY_QP)		|
+		(1ull << IB_USER_VERBS_CMD_QUERY_QP)		|
+		(1ull << IB_USER_VERBS_CMD_DESTROY_QP)		|
+		(1ull << IB_USER_VERBS_CMD_ATTACH_MCAST)	|
+		(1ull << IB_USER_VERBS_CMD_DETACH_MCAST)	|
+		(1ull << IB_USER_VERBS_CMD_CREATE_SRQ)		|
+		(1ull << IB_USER_VERBS_CMD_MODIFY_SRQ)		|
+		(1ull << IB_USER_VERBS_CMD_QUERY_SRQ)		|
+		(1ull << IB_USER_VERBS_CMD_DESTROY_SRQ)		|
+		(1ull << IB_USER_VERBS_CMD_CREATE_XSRQ)		|
+		(1ull << IB_USER_VERBS_CMD_OPEN_QP);
+
+	dev->ib_dev.query_device	= mlx5_ib_query_device;
+	dev->ib_dev.query_port		= mlx5_ib_query_port;
+	dev->ib_dev.query_gid		= mlx5_ib_query_gid;
+	dev->ib_dev.query_pkey		= mlx5_ib_query_pkey;
+	dev->ib_dev.modify_device	= mlx5_ib_modify_device;
+	dev->ib_dev.modify_port		= mlx5_ib_modify_port;
+	dev->ib_dev.alloc_ucontext	= mlx5_ib_alloc_ucontext;
+	dev->ib_dev.dealloc_ucontext	= mlx5_ib_dealloc_ucontext;
+	dev->ib_dev.mmap		= mlx5_ib_mmap;
+	dev->ib_dev.alloc_pd		= mlx5_ib_alloc_pd;
+	dev->ib_dev.dealloc_pd		= mlx5_ib_dealloc_pd;
+	dev->ib_dev.create_ah		= mlx5_ib_create_ah;
+	dev->ib_dev.query_ah		= mlx5_ib_query_ah;
+	dev->ib_dev.destroy_ah		= mlx5_ib_destroy_ah;
+	dev->ib_dev.create_srq		= mlx5_ib_create_srq;
+	dev->ib_dev.modify_srq		= mlx5_ib_modify_srq;
+	dev->ib_dev.query_srq		= mlx5_ib_query_srq;
+	dev->ib_dev.destroy_srq		= mlx5_ib_destroy_srq;
+	dev->ib_dev.post_srq_recv	= mlx5_ib_post_srq_recv;
+	dev->ib_dev.create_qp		= mlx5_ib_create_qp;
+	dev->ib_dev.modify_qp		= mlx5_ib_modify_qp;
+	dev->ib_dev.query_qp		= mlx5_ib_query_qp;
+	dev->ib_dev.destroy_qp		= mlx5_ib_destroy_qp;
+	dev->ib_dev.post_send		= mlx5_ib_post_send;
+	dev->ib_dev.post_recv		= mlx5_ib_post_recv;
+	dev->ib_dev.create_cq		= mlx5_ib_create_cq;
+	dev->ib_dev.modify_cq		= mlx5_ib_modify_cq;
+	dev->ib_dev.resize_cq		= mlx5_ib_resize_cq;
+	dev->ib_dev.destroy_cq		= mlx5_ib_destroy_cq;
+	dev->ib_dev.poll_cq		= mlx5_ib_poll_cq;
+	dev->ib_dev.req_notify_cq	= mlx5_ib_arm_cq;
+	dev->ib_dev.get_dma_mr		= mlx5_ib_get_dma_mr;
+	dev->ib_dev.reg_user_mr		= mlx5_ib_reg_user_mr;
+	dev->ib_dev.dereg_mr		= mlx5_ib_dereg_mr;
+	dev->ib_dev.attach_mcast	= mlx5_ib_mcg_attach;
+	dev->ib_dev.detach_mcast	= mlx5_ib_mcg_detach;
+	dev->ib_dev.process_mad		= mlx5_ib_process_mad;
+	dev->ib_dev.alloc_fast_reg_mr	= mlx5_ib_alloc_fast_reg_mr;
+	dev->ib_dev.alloc_fast_reg_page_list = mlx5_ib_alloc_fast_reg_page_list;
+	dev->ib_dev.free_fast_reg_page_list  = mlx5_ib_free_fast_reg_page_list;
+
+	if (mdev->caps.flags & MLX5_DEV_CAP_FLAG_XRC) {
+		dev->ib_dev.alloc_xrcd = mlx5_ib_alloc_xrcd;
+		dev->ib_dev.dealloc_xrcd = mlx5_ib_dealloc_xrcd;
+		dev->ib_dev.uverbs_cmd_mask |=
+			(1ull << IB_USER_VERBS_CMD_OPEN_XRCD) |
+			(1ull << IB_USER_VERBS_CMD_CLOSE_XRCD);
+	}
+
+	err = init_node_data(dev);
+	if (err)
+		goto err_eqs;
+
+	mutex_init(&dev->cap_mask_mutex);
+	spin_lock_init(&dev->mr_lock);
+
+	err = create_dev_resources(&dev->devr);
+	if (err)
+		goto err_eqs;
+
+	err = ib_register_device(&dev->ib_dev, NULL);
+	if (err)
+		goto err_rsrc;
+
+	err = create_umr_res(dev);
+	if (err)
+		goto err_dev;
+
+	for (i = 0; i < ARRAY_SIZE(mlx5_class_attributes); i++) {
+		err = device_create_file(&dev->ib_dev.dev,
+					 mlx5_class_attributes[i]);
+		if (err)
+			goto err_umrc;
+	}
+
+	dev->ib_active = true;
+
+	return 0;
+
+err_umrc:
+	destroy_umrc_res(dev);
+
+err_dev:
+	ib_unregister_device(&dev->ib_dev);
+
+err_rsrc:
+	destroy_dev_resources(&dev->devr);
+
+err_eqs:
+	free_comp_eqs(dev);
+
+err_cleanup:
+	mlx5_dev_cleanup(mdev);
+
+err_free:
+	ib_dealloc_device((struct ib_device *)dev);
+
+	return err;
+}
+
+static void remove_one(struct pci_dev *pdev)
+{
+	struct mlx5_ib_dev *dev = mlx5_pci2ibdev(pdev);
+
+	destroy_umrc_res(dev);
+	ib_unregister_device(&dev->ib_dev);
+	destroy_dev_resources(&dev->devr);
+	free_comp_eqs(dev);
+	mlx5_dev_cleanup(&dev->mdev);
+	ib_dealloc_device(&dev->ib_dev);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(mlx5_ib_pci_table) = {
+	{ PCI_VDEVICE(MELLANOX, 4113) }, /* MT4113 Connect-IB */
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, mlx5_ib_pci_table);
+
+static struct pci_driver mlx5_ib_driver = {
+	.name		= DRIVER_NAME,
+	.id_table	= mlx5_ib_pci_table,
+	.probe		= init_one,
+	.remove		= remove_one
+};
+
+static int __init mlx5_ib_init(void)
+{
+	return pci_register_driver(&mlx5_ib_driver);
+}
+
+static void __exit mlx5_ib_cleanup(void)
+{
+	pci_unregister_driver(&mlx5_ib_driver);
+}
+
+module_init(mlx5_ib_init);
+module_exit(mlx5_ib_cleanup);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/Makefile linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/Makefile
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3 @@
+obj-$(CONFIG_MLX5_INFINIBAND)	+= mlx5_ib.o
+
+mlx5_ib-y :=	main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/mem.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/mem.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/mem.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/mem.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <rdma/ib_umem.h>
+#include "mlx5_ib.h"
+
+/* @umem: umem object to scan
+ * @addr: ib virtual address requested by the user
+ * @count: number of PAGE_SIZE pages covered by umem
+ * @shift: page shift for the compound pages found in the region
+ * @ncont: number of compund pages
+ * @order: log2 of the number of compound pages
+ */
+void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift,
+			int *ncont, int *order)
+{
+	struct ib_umem_chunk *chunk;
+	unsigned long tmp;
+	unsigned long m;
+	int i, j, k;
+	u64 base = 0;
+	int p = 0;
+	int skip;
+	int mask;
+	u64 len;
+	u64 pfn;
+
+	addr = addr >> PAGE_SHIFT;
+	tmp = (unsigned long)addr;
+	m = find_first_bit(&tmp, sizeof(tmp));
+	skip = 1 << m;
+	mask = skip - 1;
+	i = 0;
+	list_for_each_entry(chunk, &umem->chunk_list, list)
+		for (j = 0; j < chunk->nmap; j++) {
+			len = sg_dma_len(&chunk->page_list[j]) >> PAGE_SHIFT;
+			pfn = sg_dma_address(&chunk->page_list[j]) >> PAGE_SHIFT;
+			for (k = 0; k < len; k++) {
+				if (!(i & mask)) {
+					tmp = (unsigned long)pfn;
+					m = min(m, find_first_bit(&tmp, sizeof(tmp)));
+					skip = 1 << m;
+					mask = skip - 1;
+					base = pfn;
+					p = 0;
+				} else {
+					if (base + p != pfn) {
+						tmp = (unsigned long)p;
+						m = find_first_bit(&tmp, sizeof(tmp));
+						skip = 1 << m;
+						mask = skip - 1;
+						base = pfn;
+						p = 0;
+					}
+				}
+				p++;
+				i++;
+			}
+		}
+
+	if (i) {
+		m = min_t(unsigned long, ilog2(roundup_pow_of_two(i)), m);
+
+		if (order)
+			*order = ilog2(roundup_pow_of_two(i) >> m);
+
+		*ncont = DIV_ROUND_UP(i, (1 << m));
+	} else {
+		m  = 0;
+
+		if (order)
+			*order = 0;
+
+		*ncont = 0;
+	}
+	*shift = PAGE_SHIFT + m;
+	*count = i;
+}
+
+void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem,
+			  int page_shift, __be64 *pas, int umr)
+{
+	int shift = page_shift - PAGE_SHIFT;
+	int mask = (1 << shift) - 1;
+	struct ib_umem_chunk *chunk;
+	int i, j, k;
+	u64 cur = 0;
+	u64 base;
+	int len;
+
+	i = 0;
+	list_for_each_entry(chunk, &umem->chunk_list, list)
+		for (j = 0; j < chunk->nmap; j++) {
+			len = sg_dma_len(&chunk->page_list[j]) >> PAGE_SHIFT;
+			base = sg_dma_address(&chunk->page_list[j]);
+			for (k = 0; k < len; k++) {
+				if (!(i & mask)) {
+					cur = base + (k << PAGE_SHIFT);
+					if (umr)
+						cur |= 3;
+
+					pas[i >> shift] = cpu_to_be64(cur);
+					mlx5_ib_dbg(dev, "pas[%d] 0x%llx\n",
+						    i >> shift, be64_to_cpu(pas[i >> shift]));
+				}  else
+					mlx5_ib_dbg(dev, "=====> 0x%llx\n",
+						    base + (k << PAGE_SHIFT));
+				i++;
+			}
+		}
+}
+
+int mlx5_ib_get_buf_offset(u64 addr, int page_shift, u32 *offset)
+{
+	u64 page_size;
+	u64 page_mask;
+	u64 off_size;
+	u64 off_mask;
+	u64 buf_off;
+
+	page_size = 1 << page_shift;
+	page_mask = page_size - 1;
+	buf_off = addr & page_mask;
+	off_size = page_size >> 6;
+	off_mask = off_size - 1;
+
+	if (buf_off & off_mask)
+		return -EINVAL;
+
+	*offset = buf_off >> ilog2(off_size);
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/mlx5_ib.h linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/mlx5_ib.h
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/mlx5_ib.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/mlx5_ib.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 MLX5_IB_H
+#define MLX5_IB_H
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_smi.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cq.h>
+#include <linux/mlx5/qp.h>
+#include <linux/mlx5/srq.h>
+#include <linux/types.h>
+
+#define mlx5_ib_dbg(dev, format, arg...)				\
+pr_debug("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__,	\
+	 __LINE__, current->pid, ##arg)
+
+#define mlx5_ib_err(dev, format, arg...)				\
+pr_err("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__,	\
+	__LINE__, current->pid, ##arg)
+
+#define mlx5_ib_warn(dev, format, arg...)				\
+pr_warn("%s:%s:%d:(pid %d): " format, (dev)->ib_dev.name, __func__,	\
+	__LINE__, current->pid, ##arg)
+
+enum {
+	MLX5_IB_MMAP_CMD_SHIFT	= 8,
+	MLX5_IB_MMAP_CMD_MASK	= 0xff,
+};
+
+enum mlx5_ib_mmap_cmd {
+	MLX5_IB_MMAP_REGULAR_PAGE		= 0,
+	MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES	= 1, /* always last */
+};
+
+enum {
+	MLX5_RES_SCAT_DATA32_CQE	= 0x1,
+	MLX5_RES_SCAT_DATA64_CQE	= 0x2,
+	MLX5_REQ_SCAT_DATA32_CQE	= 0x11,
+	MLX5_REQ_SCAT_DATA64_CQE	= 0x22,
+};
+
+enum mlx5_ib_latency_class {
+	MLX5_IB_LATENCY_CLASS_LOW,
+	MLX5_IB_LATENCY_CLASS_MEDIUM,
+	MLX5_IB_LATENCY_CLASS_HIGH,
+	MLX5_IB_LATENCY_CLASS_FAST_PATH
+};
+
+enum mlx5_ib_mad_ifc_flags {
+	MLX5_MAD_IFC_IGNORE_MKEY	= 1,
+	MLX5_MAD_IFC_IGNORE_BKEY	= 2,
+	MLX5_MAD_IFC_NET_VIEW		= 4,
+};
+
+struct mlx5_ib_ucontext {
+	struct ib_ucontext	ibucontext;
+	struct list_head	db_page_list;
+
+	/* protect doorbell record alloc/free
+	 */
+	struct mutex		db_page_mutex;
+	struct mlx5_uuar_info	uuari;
+};
+
+static inline struct mlx5_ib_ucontext *to_mucontext(struct ib_ucontext *ibucontext)
+{
+	return container_of(ibucontext, struct mlx5_ib_ucontext, ibucontext);
+}
+
+struct mlx5_ib_pd {
+	struct ib_pd		ibpd;
+	u32			pdn;
+	u32			pa_lkey;
+};
+
+/* Use macros here so that don't have to duplicate
+ * enum ib_send_flags and enum ib_qp_type for low-level driver
+ */
+
+#define MLX5_IB_SEND_UMR_UNREG	IB_SEND_RESERVED_START
+#define MLX5_IB_QPT_REG_UMR	IB_QPT_RESERVED1
+#define MLX5_IB_WR_UMR		IB_WR_RESERVED1
+
+struct wr_list {
+	u16	opcode;
+	u16	next;
+};
+
+struct mlx5_ib_wq {
+	u64		       *wrid;
+	u32		       *wr_data;
+	struct wr_list	       *w_list;
+	unsigned	       *wqe_head;
+	u16		        unsig_count;
+
+	/* serialize post to the work queue
+	 */
+	spinlock_t		lock;
+	int			wqe_cnt;
+	int			max_post;
+	int			max_gs;
+	int			offset;
+	int			wqe_shift;
+	unsigned		head;
+	unsigned		tail;
+	u16			cur_post;
+	u16			last_poll;
+	void		       *qend;
+};
+
+enum {
+	MLX5_QP_USER,
+	MLX5_QP_KERNEL,
+	MLX5_QP_EMPTY
+};
+
+struct mlx5_ib_qp {
+	struct ib_qp		ibqp;
+	struct mlx5_core_qp	mqp;
+	struct mlx5_buf		buf;
+
+	struct mlx5_db		db;
+	struct mlx5_ib_wq	rq;
+
+	u32			doorbell_qpn;
+	u8			sq_signal_bits;
+	u8			fm_cache;
+	int			sq_max_wqes_per_wr;
+	int			sq_spare_wqes;
+	struct mlx5_ib_wq	sq;
+
+	struct ib_umem	       *umem;
+	int			buf_size;
+
+	/* serialize qp state modifications
+	 */
+	struct mutex		mutex;
+	u16			xrcdn;
+	u32			flags;
+	u8			port;
+	u8			alt_port;
+	u8			atomic_rd_en;
+	u8			resp_depth;
+	u8			state;
+	int			mlx_type;
+	int			wq_sig;
+	int			scat_cqe;
+	int			max_inline_data;
+	struct mlx5_bf	       *bf;
+	int			has_rq;
+
+	/* only for user space QPs. For kernel
+	 * we have it from the bf object
+	 */
+	int			uuarn;
+
+	int			create_type;
+	u32			pa_lkey;
+};
+
+struct mlx5_ib_cq_buf {
+	struct mlx5_buf		buf;
+	struct ib_umem		*umem;
+	int			cqe_size;
+};
+
+enum mlx5_ib_qp_flags {
+	MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK     = 1 << 0,
+	MLX5_IB_QP_SIGNATURE_HANDLING           = 1 << 1,
+};
+
+struct mlx5_shared_mr_info {
+	int mr_id;
+	struct ib_umem		*umem;
+};
+
+struct mlx5_ib_cq {
+	struct ib_cq		ibcq;
+	struct mlx5_core_cq	mcq;
+	struct mlx5_ib_cq_buf	buf;
+	struct mlx5_db		db;
+
+	/* serialize access to the CQ
+	 */
+	spinlock_t		lock;
+
+	/* protect resize cq
+	 */
+	struct mutex		resize_mutex;
+	struct mlx5_ib_cq_resize *resize_buf;
+	struct ib_umem	       *resize_umem;
+	int			cqe_size;
+};
+
+struct mlx5_ib_srq {
+	struct ib_srq		ibsrq;
+	struct mlx5_core_srq	msrq;
+	struct mlx5_buf		buf;
+	struct mlx5_db		db;
+	u64		       *wrid;
+	/* protect SRQ hanlding
+	 */
+	spinlock_t		lock;
+	int			head;
+	int			tail;
+	u16			wqe_ctr;
+	struct ib_umem	       *umem;
+	/* serialize arming a SRQ
+	 */
+	struct mutex		mutex;
+	int			wq_sig;
+};
+
+struct mlx5_ib_xrcd {
+	struct ib_xrcd		ibxrcd;
+	u32			xrcdn;
+};
+
+struct mlx5_ib_mr {
+	struct ib_mr		ibmr;
+	struct mlx5_core_mr	mmr;
+	struct ib_umem	       *umem;
+	struct mlx5_shared_mr_info	*smr_info;
+	struct list_head	list;
+	int			order;
+	int			umred;
+	__be64			*pas;
+	dma_addr_t		dma;
+	int			npages;
+	struct completion	done;
+	enum ib_wc_status	status;
+};
+
+struct mlx5_ib_fast_reg_page_list {
+	struct ib_fast_reg_page_list	ibfrpl;
+	__be64			       *mapped_page_list;
+	dma_addr_t			map;
+};
+
+struct umr_common {
+	struct ib_pd	*pd;
+	struct ib_cq	*cq;
+	struct ib_qp	*qp;
+	struct ib_mr	*mr;
+	/* control access to UMR QP
+	 */
+	struct semaphore	sem;
+};
+
+enum {
+	MLX5_FMR_INVALID,
+	MLX5_FMR_VALID,
+	MLX5_FMR_BUSY,
+};
+
+struct mlx5_ib_fmr {
+	struct ib_fmr			ibfmr;
+	struct mlx5_core_mr		mr;
+	int				access_flags;
+	int				state;
+	/* protect fmr state
+	 */
+	spinlock_t			lock;
+	u64				wrid;
+	struct ib_send_wr		wr[2];
+	u8				page_shift;
+	struct ib_fast_reg_page_list	page_list;
+};
+
+struct mlx5_cache_ent {
+	struct list_head	head;
+	/* sync access to the cahce entry
+	 */
+	spinlock_t		lock;
+
+
+	struct dentry	       *dir;
+	char                    name[4];
+	u32                     order;
+	u32			size;
+	u32                     cur;
+	u32                     miss;
+	u32			limit;
+
+	struct dentry          *fsize;
+	struct dentry          *fcur;
+	struct dentry          *fmiss;
+	struct dentry          *flimit;
+
+	struct mlx5_ib_dev     *dev;
+	struct work_struct	work;
+	struct delayed_work	dwork;
+};
+
+struct mlx5_mr_cache {
+	struct workqueue_struct *wq;
+	struct mlx5_cache_ent	ent[MAX_MR_CACHE_ENTRIES];
+	int			stopped;
+	struct dentry		*root;
+	unsigned long		last_add;
+};
+
+struct mlx5_ib_resources {
+	struct ib_cq	*c0;
+	struct ib_xrcd	*x0;
+	struct ib_xrcd	*x1;
+	struct ib_pd	*p0;
+	struct ib_srq	*s0;
+};
+
+struct mlx5_ib_dev {
+	struct ib_device		ib_dev;
+	struct mlx5_core_dev		mdev;
+	MLX5_DECLARE_DOORBELL_LOCK(uar_lock);
+	struct list_head		eqs_list;
+	int				num_ports;
+	int				num_comp_vectors;
+	/* serialize update of capability mask
+	 */
+	struct mutex			cap_mask_mutex;
+	bool				ib_active;
+	struct umr_common		umrc;
+	/* sync used page count stats
+	 */
+	spinlock_t			mr_lock;
+	struct mlx5_ib_resources	devr;
+	struct mlx5_mr_cache		cache;
+};
+
+static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq)
+{
+	return container_of(mcq, struct mlx5_ib_cq, mcq);
+}
+
+static inline struct mlx5_ib_xrcd *to_mxrcd(struct ib_xrcd *ibxrcd)
+{
+	return container_of(ibxrcd, struct mlx5_ib_xrcd, ibxrcd);
+}
+
+static inline struct mlx5_ib_dev *to_mdev(struct ib_device *ibdev)
+{
+	return container_of(ibdev, struct mlx5_ib_dev, ib_dev);
+}
+
+static inline struct mlx5_ib_fmr *to_mfmr(struct ib_fmr *ibfmr)
+{
+	return container_of(ibfmr, struct mlx5_ib_fmr, ibfmr);
+}
+
+static inline struct mlx5_ib_cq *to_mcq(struct ib_cq *ibcq)
+{
+	return container_of(ibcq, struct mlx5_ib_cq, ibcq);
+}
+
+static inline struct mlx5_ib_qp *to_mibqp(struct mlx5_core_qp *mqp)
+{
+	return container_of(mqp, struct mlx5_ib_qp, mqp);
+}
+
+static inline struct mlx5_ib_pd *to_mpd(struct ib_pd *ibpd)
+{
+	return container_of(ibpd, struct mlx5_ib_pd, ibpd);
+}
+
+static inline struct mlx5_ib_srq *to_msrq(struct ib_srq *ibsrq)
+{
+	return container_of(ibsrq, struct mlx5_ib_srq, ibsrq);
+}
+
+static inline struct mlx5_ib_qp *to_mqp(struct ib_qp *ibqp)
+{
+	return container_of(ibqp, struct mlx5_ib_qp, ibqp);
+}
+
+static inline struct mlx5_ib_srq *to_mibsrq(struct mlx5_core_srq *msrq)
+{
+	return container_of(msrq, struct mlx5_ib_srq, msrq);
+}
+
+static inline struct mlx5_ib_mr *to_mmr(struct ib_mr *ibmr)
+{
+	return container_of(ibmr, struct mlx5_ib_mr, ibmr);
+}
+
+static inline struct mlx5_ib_fast_reg_page_list *to_mfrpl(struct ib_fast_reg_page_list *ibfrpl)
+{
+	return container_of(ibfrpl, struct mlx5_ib_fast_reg_page_list, ibfrpl);
+}
+
+struct mlx5_ib_ah {
+	struct ib_ah		ibah;
+	struct mlx5_av		av;
+};
+
+static inline struct mlx5_ib_ah *to_mah(struct ib_ah *ibah)
+{
+	return container_of(ibah, struct mlx5_ib_ah, ibah);
+}
+
+static inline struct mlx5_ib_dev *mlx5_core2ibdev(struct mlx5_core_dev *dev)
+{
+	return container_of(dev, struct mlx5_ib_dev, mdev);
+}
+
+static inline struct mlx5_ib_dev *mlx5_pci2ibdev(struct pci_dev *pdev)
+{
+	return mlx5_core2ibdev(pci2mlx5_core_dev(pdev));
+}
+
+int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
+			struct mlx5_db *db);
+void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db);
+void __mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq);
+void mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq);
+void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index);
+int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
+		 int port, struct ib_wc *in_wc, struct ib_grh *in_grh,
+		 void *in_mad, void *response_mad);
+struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
+			   struct mlx5_ib_ah *ah);
+struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
+int mlx5_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr);
+int mlx5_ib_destroy_ah(struct ib_ah *ah);
+struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
+				  struct ib_srq_init_attr *init_attr,
+				  struct ib_udata *udata);
+int mlx5_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
+		       enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
+int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr);
+int mlx5_ib_destroy_srq(struct ib_srq *srq);
+int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
+			  struct ib_recv_wr **bad_wr);
+struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
+				struct ib_qp_init_attr *init_attr,
+				struct ib_udata *udata);
+int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+		      int attr_mask, struct ib_udata *udata);
+int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
+		     struct ib_qp_init_attr *qp_init_attr);
+int mlx5_ib_destroy_qp(struct ib_qp *qp);
+int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+		      struct ib_send_wr **bad_wr);
+int mlx5_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+		      struct ib_recv_wr **bad_wr);
+void *mlx5_get_send_wqe(struct mlx5_ib_qp *qp, int n);
+struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, int entries,
+				int vector, struct ib_ucontext *context,
+				struct ib_udata *udata);
+int mlx5_ib_destroy_cq(struct ib_cq *cq);
+int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
+int mlx5_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
+int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period);
+int mlx5_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata);
+struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc);
+struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+				  u64 virt_addr, int access_flags,
+				  struct ib_udata *udata);
+int mlx5_ib_dereg_mr(struct ib_mr *ibmr);
+struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd,
+					int max_page_list_len);
+struct ib_fast_reg_page_list *mlx5_ib_alloc_fast_reg_page_list(struct ib_device *ibdev,
+							       int page_list_len);
+void mlx5_ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list);
+struct ib_fmr *mlx5_ib_fmr_alloc(struct ib_pd *pd, int acc,
+				 struct ib_fmr_attr *fmr_attr);
+int mlx5_ib_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
+		      int npages, u64 iova);
+int mlx5_ib_unmap_fmr(struct list_head *fmr_list);
+int mlx5_ib_fmr_dealloc(struct ib_fmr *ibfmr);
+int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
+			struct ib_wc *in_wc, struct ib_grh *in_grh,
+			struct ib_mad *in_mad, struct ib_mad *out_mad);
+struct ib_xrcd *mlx5_ib_alloc_xrcd(struct ib_device *ibdev,
+					  struct ib_ucontext *context,
+					  struct ib_udata *udata);
+int mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd);
+int mlx5_vector2eqn(struct mlx5_ib_dev *dev, int vector, int *eqn, int *irqn);
+int mlx5_ib_get_buf_offset(u64 addr, int page_shift, u32 *offset);
+int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port);
+int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
+		       struct ib_port_attr *props);
+int mlx5_ib_init_fmr(struct mlx5_ib_dev *dev);
+void mlx5_ib_cleanup_fmr(struct mlx5_ib_dev *dev);
+void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift,
+			int *ncont, int *order);
+void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem,
+			  int page_shift, __be64 *pas, int umr);
+void mlx5_ib_copy_pas(u64 *old, u64 *new, int step, int num);
+int mlx5_ib_get_cqe_size(struct mlx5_ib_dev *dev, struct ib_cq *ibcq);
+int mlx5_mr_cache_init(struct mlx5_ib_dev *dev);
+int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev);
+int mlx5_mr_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift);
+void mlx5_umr_cq_handler(struct ib_cq *cq, void *cq_context);
+
+static inline void init_query_mad(struct ib_smp *mad)
+{
+	mad->base_version  = 1;
+	mad->mgmt_class    = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+	mad->class_version = 1;
+	mad->method	   = IB_MGMT_METHOD_GET;
+}
+
+static inline u8 convert_access(int acc)
+{
+	return (acc & IB_ACCESS_REMOTE_ATOMIC ? MLX5_PERM_ATOMIC       : 0) |
+	       (acc & IB_ACCESS_REMOTE_WRITE  ? MLX5_PERM_REMOTE_WRITE : 0) |
+	       (acc & IB_ACCESS_REMOTE_READ   ? MLX5_PERM_REMOTE_READ  : 0) |
+	       (acc & IB_ACCESS_LOCAL_WRITE   ? MLX5_PERM_LOCAL_WRITE  : 0) |
+	       MLX5_PERM_LOCAL_READ;
+}
+
+#endif /* MLX5_IB_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/mr.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/mr.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/mr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/mr.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1007 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+
+#include <linux/kref.h>
+#include <linux/random.h>
+#include <linux/debugfs.h>
+#include <linux/export.h>
+#include <rdma/ib_umem.h>
+#include "mlx5_ib.h"
+
+enum {
+	DEF_CACHE_SIZE	= 10,
+};
+
+static __be64 *mr_align(__be64 *ptr, int align)
+{
+	unsigned long mask = align - 1;
+
+	return (__be64 *)(((unsigned long)ptr + mask) & ~mask);
+}
+
+static int order2idx(struct mlx5_ib_dev *dev, int order)
+{
+	struct mlx5_mr_cache *cache = &dev->cache;
+
+	if (order < cache->ent[0].order)
+		return 0;
+	else
+		return order - cache->ent[0].order;
+}
+
+static int add_keys(struct mlx5_ib_dev *dev, int c, int num)
+{
+	struct device *ddev = dev->ib_dev.dma_device;
+	struct mlx5_mr_cache *cache = &dev->cache;
+	struct mlx5_cache_ent *ent = &cache->ent[c];
+	struct mlx5_create_mkey_mbox_in *in;
+	struct mlx5_ib_mr *mr;
+	int npages = 1 << ent->order;
+	int size = sizeof(u64) * npages;
+	int err = 0;
+	int i;
+
+	in = kzalloc(sizeof(*in), GFP_KERNEL);
+	if (!in)
+		return -ENOMEM;
+
+	for (i = 0; i < num; i++) {
+		mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+		if (!mr) {
+			err = -ENOMEM;
+			goto out;
+		}
+		mr->order = ent->order;
+		mr->umred = 1;
+		mr->pas = kmalloc(size + 0x3f, GFP_KERNEL);
+		if (!mr->pas) {
+			kfree(mr);
+			err = -ENOMEM;
+			goto out;
+		}
+		mr->dma = dma_map_single(ddev, mr_align(mr->pas, 0x40), size,
+					 DMA_TO_DEVICE);
+		if (dma_mapping_error(ddev, mr->dma)) {
+			kfree(mr->pas);
+			kfree(mr);
+			err = -ENOMEM;
+			goto out;
+		}
+
+		in->seg.status = 1 << 6;
+		in->seg.xlt_oct_size = cpu_to_be32((npages + 1) / 2);
+		in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
+		in->seg.flags = MLX5_ACCESS_MODE_MTT | MLX5_PERM_UMR_EN;
+		in->seg.log2_page_size = 12;
+
+		err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in,
+					    sizeof(*in));
+		if (err) {
+			mlx5_ib_warn(dev, "create mkey failed %d\n", err);
+			dma_unmap_single(ddev, mr->dma, size, DMA_TO_DEVICE);
+			kfree(mr->pas);
+			kfree(mr);
+			goto out;
+		}
+		cache->last_add = jiffies;
+
+		spin_lock(&ent->lock);
+		list_add_tail(&mr->list, &ent->head);
+		ent->cur++;
+		ent->size++;
+		spin_unlock(&ent->lock);
+	}
+
+out:
+	kfree(in);
+	return err;
+}
+
+static void remove_keys(struct mlx5_ib_dev *dev, int c, int num)
+{
+	struct device *ddev = dev->ib_dev.dma_device;
+	struct mlx5_mr_cache *cache = &dev->cache;
+	struct mlx5_cache_ent *ent = &cache->ent[c];
+	struct mlx5_ib_mr *mr;
+	int size;
+	int err;
+	int i;
+
+	for (i = 0; i < num; i++) {
+		spin_lock(&ent->lock);
+		if (list_empty(&ent->head)) {
+			spin_unlock(&ent->lock);
+			return;
+		}
+		mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list);
+		list_del(&mr->list);
+		ent->cur--;
+		ent->size--;
+		spin_unlock(&ent->lock);
+		err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
+		if (err) {
+			mlx5_ib_warn(dev, "failed destroy mkey\n");
+		} else {
+			size = ALIGN(sizeof(u64) * (1 << mr->order), 0x40);
+			dma_unmap_single(ddev, mr->dma, size, DMA_TO_DEVICE);
+			kfree(mr->pas);
+			kfree(mr);
+		}
+	}
+}
+
+static ssize_t size_write(struct file *filp, const char __user *buf,
+			  size_t count, loff_t *pos)
+{
+	struct mlx5_cache_ent *ent = filp->private_data;
+	struct mlx5_ib_dev *dev = ent->dev;
+	char lbuf[20];
+	u32 var;
+	int err;
+	int c;
+
+	if (copy_from_user(lbuf, buf, sizeof(lbuf)))
+		return -EFAULT;
+
+	c = order2idx(dev, ent->order);
+	lbuf[sizeof(lbuf) - 1] = 0;
+
+	if (sscanf(lbuf, "%u", &var) != 1)
+		return -EINVAL;
+
+	if (var < ent->limit)
+		return -EINVAL;
+
+	if (var > ent->size) {
+		err = add_keys(dev, c, var - ent->size);
+		if (err)
+			return err;
+	} else if (var < ent->size) {
+		remove_keys(dev, c, ent->size - var);
+	}
+
+	return count;
+}
+
+static ssize_t size_read(struct file *filp, char __user *buf, size_t count,
+			 loff_t *pos)
+{
+	struct mlx5_cache_ent *ent = filp->private_data;
+	char lbuf[20];
+	int err;
+
+	if (*pos)
+		return 0;
+
+	err = snprintf(lbuf, sizeof(lbuf), "%d\n", ent->size);
+	if (err < 0)
+		return err;
+
+	if (copy_to_user(buf, lbuf, err))
+		return -EFAULT;
+
+	*pos += err;
+
+	return err;
+}
+
+static const struct file_operations size_fops = {
+	.owner	= THIS_MODULE,
+	.open	= simple_open,
+	.write	= size_write,
+	.read	= size_read,
+};
+
+static ssize_t limit_write(struct file *filp, const char __user *buf,
+			   size_t count, loff_t *pos)
+{
+	struct mlx5_cache_ent *ent = filp->private_data;
+	struct mlx5_ib_dev *dev = ent->dev;
+	char lbuf[20];
+	u32 var;
+	int err;
+	int c;
+
+	if (copy_from_user(lbuf, buf, sizeof(lbuf)))
+		return -EFAULT;
+
+	c = order2idx(dev, ent->order);
+	lbuf[sizeof(lbuf) - 1] = 0;
+
+	if (sscanf(lbuf, "%u", &var) != 1)
+		return -EINVAL;
+
+	if (var > ent->size)
+		return -EINVAL;
+
+	ent->limit = var;
+
+	if (ent->cur < ent->limit) {
+		err = add_keys(dev, c, 2 * ent->limit - ent->cur);
+		if (err)
+			return err;
+	}
+
+	return count;
+}
+
+static ssize_t limit_read(struct file *filp, char __user *buf, size_t count,
+			  loff_t *pos)
+{
+	struct mlx5_cache_ent *ent = filp->private_data;
+	char lbuf[20];
+	int err;
+
+	if (*pos)
+		return 0;
+
+	err = snprintf(lbuf, sizeof(lbuf), "%d\n", ent->limit);
+	if (err < 0)
+		return err;
+
+	if (copy_to_user(buf, lbuf, err))
+		return -EFAULT;
+
+	*pos += err;
+
+	return err;
+}
+
+static const struct file_operations limit_fops = {
+	.owner	= THIS_MODULE,
+	.open	= simple_open,
+	.write	= limit_write,
+	.read	= limit_read,
+};
+
+static int someone_adding(struct mlx5_mr_cache *cache)
+{
+	int i;
+
+	for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) {
+		if (cache->ent[i].cur < cache->ent[i].limit)
+			return 1;
+	}
+
+	return 0;
+}
+
+static void __cache_work_func(struct mlx5_cache_ent *ent)
+{
+	struct mlx5_ib_dev *dev = ent->dev;
+	struct mlx5_mr_cache *cache = &dev->cache;
+	int i = order2idx(dev, ent->order);
+
+	if (cache->stopped)
+		return;
+
+	ent = &dev->cache.ent[i];
+	if (ent->cur < 2 * ent->limit) {
+		add_keys(dev, i, 1);
+		if (ent->cur < 2 * ent->limit)
+			queue_work(cache->wq, &ent->work);
+	} else if (ent->cur > 2 * ent->limit) {
+		if (!someone_adding(cache) &&
+		    time_after(jiffies, cache->last_add + 60 * HZ)) {
+			remove_keys(dev, i, 1);
+			if (ent->cur > ent->limit)
+				queue_work(cache->wq, &ent->work);
+		} else {
+			queue_delayed_work(cache->wq, &ent->dwork, 60 * HZ);
+		}
+	}
+}
+
+static void delayed_cache_work_func(struct work_struct *work)
+{
+	struct mlx5_cache_ent *ent;
+
+	ent = container_of(work, struct mlx5_cache_ent, dwork.work);
+	__cache_work_func(ent);
+}
+
+static void cache_work_func(struct work_struct *work)
+{
+	struct mlx5_cache_ent *ent;
+
+	ent = container_of(work, struct mlx5_cache_ent, work);
+	__cache_work_func(ent);
+}
+
+static struct mlx5_ib_mr *alloc_cached_mr(struct mlx5_ib_dev *dev, int order)
+{
+	struct mlx5_mr_cache *cache = &dev->cache;
+	struct mlx5_ib_mr *mr = NULL;
+	struct mlx5_cache_ent *ent;
+	int c;
+	int i;
+
+	c = order2idx(dev, order);
+	if (c < 0 || c >= MAX_MR_CACHE_ENTRIES) {
+		mlx5_ib_warn(dev, "order %d, cache index %d\n", order, c);
+		return NULL;
+	}
+
+	for (i = c; i < MAX_MR_CACHE_ENTRIES; i++) {
+		ent = &cache->ent[i];
+
+		mlx5_ib_dbg(dev, "order %d, cache index %d\n", ent->order, i);
+
+		spin_lock(&ent->lock);
+		if (!list_empty(&ent->head)) {
+			mr = list_first_entry(&ent->head, struct mlx5_ib_mr,
+					      list);
+			list_del(&mr->list);
+			ent->cur--;
+			spin_unlock(&ent->lock);
+			if (ent->cur < ent->limit)
+				queue_work(cache->wq, &ent->work);
+			break;
+		}
+		spin_unlock(&ent->lock);
+
+		queue_work(cache->wq, &ent->work);
+
+		if (mr)
+			break;
+	}
+
+	if (!mr)
+		cache->ent[c].miss++;
+
+	return mr;
+}
+
+static void free_cached_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
+{
+	struct mlx5_mr_cache *cache = &dev->cache;
+	struct mlx5_cache_ent *ent;
+	int shrink = 0;
+	int c;
+
+	c = order2idx(dev, mr->order);
+	if (c < 0 || c >= MAX_MR_CACHE_ENTRIES) {
+		mlx5_ib_warn(dev, "order %d, cache index %d\n", mr->order, c);
+		return;
+	}
+	ent = &cache->ent[c];
+	spin_lock(&ent->lock);
+	list_add_tail(&mr->list, &ent->head);
+	ent->cur++;
+	if (ent->cur > 2 * ent->limit)
+		shrink = 1;
+	spin_unlock(&ent->lock);
+
+	if (shrink)
+		queue_work(cache->wq, &ent->work);
+}
+
+static void clean_keys(struct mlx5_ib_dev *dev, int c)
+{
+	struct device *ddev = dev->ib_dev.dma_device;
+	struct mlx5_mr_cache *cache = &dev->cache;
+	struct mlx5_cache_ent *ent = &cache->ent[c];
+	struct mlx5_ib_mr *mr;
+	int size;
+	int err;
+
+	while (1) {
+		spin_lock(&ent->lock);
+		if (list_empty(&ent->head)) {
+			spin_unlock(&ent->lock);
+			return;
+		}
+		mr = list_first_entry(&ent->head, struct mlx5_ib_mr, list);
+		list_del(&mr->list);
+		ent->cur--;
+		ent->size--;
+		spin_unlock(&ent->lock);
+		err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
+		if (err) {
+			mlx5_ib_warn(dev, "failed destroy mkey\n");
+		} else {
+			size = ALIGN(sizeof(u64) * (1 << mr->order), 0x40);
+			dma_unmap_single(ddev, mr->dma, size, DMA_TO_DEVICE);
+			kfree(mr->pas);
+			kfree(mr);
+		}
+	}
+}
+
+static int mlx5_mr_cache_debugfs_init(struct mlx5_ib_dev *dev)
+{
+	struct mlx5_mr_cache *cache = &dev->cache;
+	struct mlx5_cache_ent *ent;
+	int i;
+
+	if (!mlx5_debugfs_root)
+		return 0;
+
+	cache->root = debugfs_create_dir("mr_cache", dev->mdev.priv.dbg_root);
+	if (!cache->root)
+		return -ENOMEM;
+
+	for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) {
+		ent = &cache->ent[i];
+		sprintf(ent->name, "%d", ent->order);
+		ent->dir = debugfs_create_dir(ent->name,  cache->root);
+		if (!ent->dir)
+			return -ENOMEM;
+
+		ent->fsize = debugfs_create_file("size", 0600, ent->dir, ent,
+						 &size_fops);
+		if (!ent->fsize)
+			return -ENOMEM;
+
+		ent->flimit = debugfs_create_file("limit", 0600, ent->dir, ent,
+						  &limit_fops);
+		if (!ent->flimit)
+			return -ENOMEM;
+
+		ent->fcur = debugfs_create_u32("cur", 0400, ent->dir,
+					       &ent->cur);
+		if (!ent->fcur)
+			return -ENOMEM;
+
+		ent->fmiss = debugfs_create_u32("miss", 0600, ent->dir,
+						&ent->miss);
+		if (!ent->fmiss)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
+{
+	if (!mlx5_debugfs_root)
+		return;
+
+	debugfs_remove_recursive(dev->cache.root);
+}
+
+int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
+{
+	struct mlx5_mr_cache *cache = &dev->cache;
+	struct mlx5_cache_ent *ent;
+	int limit;
+	int size;
+	int err;
+	int i;
+
+	cache->wq = create_singlethread_workqueue("mkey_cache");
+	if (!cache->wq) {
+		mlx5_ib_warn(dev, "failed to create work queue\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) {
+		INIT_LIST_HEAD(&cache->ent[i].head);
+		spin_lock_init(&cache->ent[i].lock);
+
+		ent = &cache->ent[i];
+		INIT_LIST_HEAD(&ent->head);
+		spin_lock_init(&ent->lock);
+		ent->order = i + 2;
+		ent->dev = dev;
+
+		if (dev->mdev.profile->mask & MLX5_PROF_MASK_MR_CACHE) {
+			size = dev->mdev.profile->mr_cache[i].size;
+			limit = dev->mdev.profile->mr_cache[i].limit;
+		} else {
+			size = DEF_CACHE_SIZE;
+			limit = 0;
+		}
+		INIT_WORK(&ent->work, cache_work_func);
+		INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func);
+		ent->limit = limit;
+		queue_work(cache->wq, &ent->work);
+	}
+
+	err = mlx5_mr_cache_debugfs_init(dev);
+	if (err)
+		mlx5_ib_warn(dev, "cache debugfs failure\n");
+
+	return 0;
+}
+
+int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev)
+{
+	int i;
+
+	dev->cache.stopped = 1;
+	destroy_workqueue(dev->cache.wq);
+
+	mlx5_mr_cache_debugfs_cleanup(dev);
+
+	for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++)
+		clean_keys(dev, i);
+
+	return 0;
+}
+
+struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc)
+{
+	struct mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct mlx5_core_dev *mdev = &dev->mdev;
+	struct mlx5_create_mkey_mbox_in *in;
+	struct mlx5_mkey_seg *seg;
+	struct mlx5_ib_mr *mr;
+	int err;
+
+	mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+	if (!mr)
+		return ERR_PTR(-ENOMEM);
+
+	in = kzalloc(sizeof(*in), GFP_KERNEL);
+	if (!in) {
+		err = -ENOMEM;
+		goto err_free;
+	}
+
+	seg = &in->seg;
+	seg->flags = convert_access(acc) | MLX5_ACCESS_MODE_PA;
+	seg->flags_pd = cpu_to_be32(to_mpd(pd)->pdn | MLX5_MKEY_LEN64);
+	seg->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
+	seg->start_addr = 0;
+
+	err = mlx5_core_create_mkey(mdev, &mr->mmr, in, sizeof(*in));
+	if (err)
+		goto err_in;
+
+	kfree(in);
+	mr->ibmr.lkey = mr->mmr.key;
+	mr->ibmr.rkey = mr->mmr.key;
+	mr->umem = NULL;
+
+	return &mr->ibmr;
+
+err_in:
+	kfree(in);
+
+err_free:
+	kfree(mr);
+
+	return ERR_PTR(err);
+}
+
+static int get_octo_len(u64 addr, u64 len, int page_size)
+{
+	u64 offset;
+	int npages;
+
+	offset = addr & (page_size - 1);
+	npages = ALIGN(len + offset, page_size) >> ilog2(page_size);
+	return (npages + 1) / 2;
+}
+
+static int use_umr(int order)
+{
+	return order <= 17;
+}
+
+static void prep_umr_reg_wqe(struct ib_pd *pd, struct ib_send_wr *wr,
+			     struct ib_sge *sg, u64 dma, int n, u32 key,
+			     int page_shift, u64 virt_addr, u64 len,
+			     int access_flags)
+{
+	struct mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct ib_mr *mr = dev->umrc.mr;
+
+	sg->addr = dma;
+	sg->length = ALIGN(sizeof(u64) * n, 64);
+	sg->lkey = mr->lkey;
+
+	wr->next = NULL;
+	wr->send_flags = 0;
+	wr->sg_list = sg;
+	if (n)
+		wr->num_sge = 1;
+	else
+		wr->num_sge = 0;
+
+	wr->opcode = MLX5_IB_WR_UMR;
+	wr->wr.fast_reg.page_list_len = n;
+	wr->wr.fast_reg.page_shift = page_shift;
+	wr->wr.fast_reg.rkey = key;
+	wr->wr.fast_reg.iova_start = virt_addr;
+	wr->wr.fast_reg.length = len;
+	wr->wr.fast_reg.access_flags = access_flags;
+	wr->wr.fast_reg.page_list = (struct ib_fast_reg_page_list *)pd;
+}
+
+static void prep_umr_unreg_wqe(struct mlx5_ib_dev *dev,
+			       struct ib_send_wr *wr, u32 key)
+{
+	wr->send_flags = MLX5_IB_SEND_UMR_UNREG;
+	wr->opcode = MLX5_IB_WR_UMR;
+	wr->wr.fast_reg.rkey = key;
+}
+
+void mlx5_umr_cq_handler(struct ib_cq *cq, void *cq_context)
+{
+	struct mlx5_ib_mr *mr;
+	struct ib_wc wc;
+	int err;
+
+	while (1) {
+		err = ib_poll_cq(cq, 1, &wc);
+		if (err < 0) {
+			pr_warn("poll cq error %d\n", err);
+			return;
+		}
+		if (err == 0)
+			break;
+
+		mr = (struct mlx5_ib_mr *)(unsigned long)wc.wr_id;
+		mr->status = wc.status;
+		complete(&mr->done);
+	}
+	ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+}
+
+static struct mlx5_ib_mr *reg_umr(struct ib_pd *pd, struct ib_umem *umem,
+				  u64 virt_addr, u64 len, int npages,
+				  int page_shift, int order, int access_flags)
+{
+	struct mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct umr_common *umrc = &dev->umrc;
+	struct ib_send_wr wr, *bad;
+	struct mlx5_ib_mr *mr;
+	struct ib_sge sg;
+	int err;
+	int i;
+
+	for (i = 0; i < 10; i++) {
+		mr = alloc_cached_mr(dev, order);
+		if (mr)
+			break;
+
+		err = add_keys(dev, order2idx(dev, order), 1);
+		if (err) {
+			mlx5_ib_warn(dev, "add_keys failed\n");
+			break;
+		}
+	}
+
+	if (!mr)
+		return ERR_PTR(-EAGAIN);
+
+	mlx5_ib_populate_pas(dev, umem, page_shift, mr_align(mr->pas, 0x40), 1);
+
+	memset(&wr, 0, sizeof(wr));
+	wr.wr_id = (u64)(unsigned long)mr;
+	prep_umr_reg_wqe(pd, &wr, &sg, mr->dma, npages, mr->mmr.key, page_shift, virt_addr, len, access_flags);
+
+	/* We serialize polls so one process does not kidnap another's
+	 * completion. This is not a problem since wr is completed in
+	 * around 1 usec
+	 */
+	down(&umrc->sem);
+	init_completion(&mr->done);
+	err = ib_post_send(umrc->qp, &wr, &bad);
+	if (err) {
+		mlx5_ib_warn(dev, "post send failed, err %d\n", err);
+		up(&umrc->sem);
+		goto error;
+	}
+	wait_for_completion(&mr->done);
+	up(&umrc->sem);
+
+	if (mr->status != IB_WC_SUCCESS) {
+		mlx5_ib_warn(dev, "reg umr failed\n");
+		err = -EFAULT;
+		goto error;
+	}
+
+	return mr;
+
+error:
+	free_cached_mr(dev, mr);
+	return ERR_PTR(err);
+}
+
+static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr,
+				     u64 length, struct ib_umem *umem,
+				     int npages, int page_shift,
+				     int access_flags)
+{
+	struct mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct mlx5_create_mkey_mbox_in *in;
+	struct mlx5_ib_mr *mr;
+	int inlen;
+	int err;
+
+	mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+	if (!mr)
+		return ERR_PTR(-ENOMEM);
+
+	inlen = sizeof(*in) + sizeof(*in->pas) * ((npages + 1) / 2) * 2;
+	in = mlx5_vzalloc(inlen);
+	if (!in) {
+		err = -ENOMEM;
+		goto err_1;
+	}
+	mlx5_ib_populate_pas(dev, umem, page_shift, in->pas, 0);
+
+	in->seg.flags = convert_access(access_flags) |
+		MLX5_ACCESS_MODE_MTT;
+	in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
+	in->seg.start_addr = cpu_to_be64(virt_addr);
+	in->seg.len = cpu_to_be64(length);
+	in->seg.bsfs_octo_size = 0;
+	in->seg.xlt_oct_size = cpu_to_be32(get_octo_len(virt_addr, length, 1 << page_shift));
+	in->seg.log2_page_size = page_shift;
+	in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
+	in->xlat_oct_act_size = cpu_to_be32(get_octo_len(virt_addr, length, 1 << page_shift));
+	err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, inlen);
+	if (err) {
+		mlx5_ib_warn(dev, "create mkey failed\n");
+		goto err_2;
+	}
+	mr->umem = umem;
+	mlx5_vfree(in);
+
+	mlx5_ib_dbg(dev, "mkey = 0x%x\n", mr->mmr.key);
+
+	return mr;
+
+err_2:
+	mlx5_vfree(in);
+
+err_1:
+	kfree(mr);
+
+	return ERR_PTR(err);
+}
+
+struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+				  u64 virt_addr, int access_flags,
+				  struct ib_udata *udata)
+{
+	struct mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct mlx5_ib_mr *mr = NULL;
+	struct ib_umem *umem;
+	int page_shift;
+	int npages;
+	int ncont;
+	int order;
+	int err;
+
+	mlx5_ib_dbg(dev, "start 0x%llx, virt_addr 0x%llx, length 0x%llx\n",
+		    start, virt_addr, length);
+	umem = ib_umem_get(pd->uobject->context, start, length, access_flags,
+			   0);
+	if (IS_ERR(umem)) {
+		mlx5_ib_dbg(dev, "umem get failed\n");
+		return (void *)umem;
+	}
+
+	mlx5_ib_cont_pages(umem, start, &npages, &page_shift, &ncont, &order);
+	if (!npages) {
+		mlx5_ib_warn(dev, "avoid zero region\n");
+		err = -EINVAL;
+		goto error;
+	}
+
+	mlx5_ib_dbg(dev, "npages %d, ncont %d, order %d, page_shift %d\n",
+		    npages, ncont, order, page_shift);
+
+	if (use_umr(order)) {
+		mr = reg_umr(pd, umem, virt_addr, length, ncont, page_shift,
+			     order, access_flags);
+		if (PTR_ERR(mr) == -EAGAIN) {
+			mlx5_ib_dbg(dev, "cache empty for order %d", order);
+			mr = NULL;
+		}
+	}
+
+	if (!mr)
+		mr = reg_create(pd, virt_addr, length, umem, ncont, page_shift,
+				access_flags);
+
+	if (IS_ERR(mr)) {
+		err = PTR_ERR(mr);
+		goto error;
+	}
+
+	mlx5_ib_dbg(dev, "mkey 0x%x\n", mr->mmr.key);
+
+	mr->umem = umem;
+	mr->npages = npages;
+	spin_lock(&dev->mr_lock);
+	dev->mdev.priv.reg_pages += npages;
+	spin_unlock(&dev->mr_lock);
+	mr->ibmr.lkey = mr->mmr.key;
+	mr->ibmr.rkey = mr->mmr.key;
+
+	return &mr->ibmr;
+
+error:
+	ib_umem_release(umem);
+	return ERR_PTR(err);
+}
+
+static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
+{
+	struct umr_common *umrc = &dev->umrc;
+	struct ib_send_wr wr, *bad;
+	int err;
+
+	memset(&wr, 0, sizeof(wr));
+	wr.wr_id = (u64)(unsigned long)mr;
+	prep_umr_unreg_wqe(dev, &wr, mr->mmr.key);
+
+	down(&umrc->sem);
+	init_completion(&mr->done);
+	err = ib_post_send(umrc->qp, &wr, &bad);
+	if (err) {
+		up(&umrc->sem);
+		mlx5_ib_dbg(dev, "err %d\n", err);
+		goto error;
+	}
+	wait_for_completion(&mr->done);
+	up(&umrc->sem);
+	if (mr->status != IB_WC_SUCCESS) {
+		mlx5_ib_warn(dev, "unreg umr failed\n");
+		err = -EFAULT;
+		goto error;
+	}
+	return 0;
+
+error:
+	return err;
+}
+
+int mlx5_ib_dereg_mr(struct ib_mr *ibmr)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibmr->device);
+	struct mlx5_ib_mr *mr = to_mmr(ibmr);
+	struct ib_umem *umem = mr->umem;
+	int npages = mr->npages;
+	int umred = mr->umred;
+	int err;
+
+	if (!umred) {
+		err = mlx5_core_destroy_mkey(&dev->mdev, &mr->mmr);
+		if (err) {
+			mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
+				     mr->mmr.key, err);
+			return err;
+		}
+	} else {
+		err = unreg_umr(dev, mr);
+		if (err) {
+			mlx5_ib_warn(dev, "failed unregister\n");
+			return err;
+		}
+		free_cached_mr(dev, mr);
+	}
+
+	if (umem) {
+		ib_umem_release(umem);
+		spin_lock(&dev->mr_lock);
+		dev->mdev.priv.reg_pages -= npages;
+		spin_unlock(&dev->mr_lock);
+	}
+
+	if (!umred)
+		kfree(mr);
+
+	return 0;
+}
+
+struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd,
+					int max_page_list_len)
+{
+	struct mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct mlx5_create_mkey_mbox_in *in;
+	struct mlx5_ib_mr *mr;
+	int err;
+
+	mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+	if (!mr)
+		return ERR_PTR(-ENOMEM);
+
+	in = kzalloc(sizeof(*in), GFP_KERNEL);
+	if (!in) {
+		err = -ENOMEM;
+		goto err_free;
+	}
+
+	in->seg.status = 1 << 6; /* free */
+	in->seg.xlt_oct_size = cpu_to_be32((max_page_list_len + 1) / 2);
+	in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
+	in->seg.flags = MLX5_PERM_UMR_EN | MLX5_ACCESS_MODE_MTT;
+	in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
+	/*
+	 * TBD not needed - issue 197292 */
+	in->seg.log2_page_size = PAGE_SHIFT;
+
+	err = mlx5_core_create_mkey(&dev->mdev, &mr->mmr, in, sizeof(*in));
+	kfree(in);
+	if (err)
+		goto err_free;
+
+	mr->ibmr.lkey = mr->mmr.key;
+	mr->ibmr.rkey = mr->mmr.key;
+	mr->umem = NULL;
+
+	return &mr->ibmr;
+
+err_free:
+	kfree(mr);
+	return ERR_PTR(err);
+}
+
+struct ib_fast_reg_page_list *mlx5_ib_alloc_fast_reg_page_list(struct ib_device *ibdev,
+							       int page_list_len)
+{
+	struct mlx5_ib_fast_reg_page_list *mfrpl;
+	int size = page_list_len * sizeof(u64);
+
+	mfrpl = kmalloc(sizeof(*mfrpl), GFP_KERNEL);
+	if (!mfrpl)
+		return ERR_PTR(-ENOMEM);
+
+	mfrpl->ibfrpl.page_list = kmalloc(size, GFP_KERNEL);
+	if (!mfrpl->ibfrpl.page_list)
+		goto err_free;
+
+	mfrpl->mapped_page_list = dma_alloc_coherent(ibdev->dma_device,
+						     size, &mfrpl->map,
+						     GFP_KERNEL);
+	if (!mfrpl->mapped_page_list)
+		goto err_free;
+
+	WARN_ON(mfrpl->map & 0x3f);
+
+	return &mfrpl->ibfrpl;
+
+err_free:
+	kfree(mfrpl->ibfrpl.page_list);
+	kfree(mfrpl);
+	return ERR_PTR(-ENOMEM);
+}
+
+void mlx5_ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
+{
+	struct mlx5_ib_fast_reg_page_list *mfrpl = to_mfrpl(page_list);
+	struct mlx5_ib_dev *dev = to_mdev(page_list->device);
+	int size = page_list->max_page_list_len * sizeof(u64);
+
+	dma_free_coherent(&dev->mdev.pdev->dev, size, mfrpl->mapped_page_list,
+			  mfrpl->map);
+	kfree(mfrpl->ibfrpl.page_list);
+	kfree(mfrpl);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/qp.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/qp.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/qp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/qp.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2524 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <rdma/ib_umem.h>
+#include "mlx5_ib.h"
+#include "user.h"
+
+/* not supported currently */
+static int wq_signature;
+
+enum {
+	MLX5_IB_ACK_REQ_FREQ	= 8,
+};
+
+enum {
+	MLX5_IB_DEFAULT_SCHED_QUEUE	= 0x83,
+	MLX5_IB_DEFAULT_QP0_SCHED_QUEUE	= 0x3f,
+	MLX5_IB_LINK_TYPE_IB		= 0,
+	MLX5_IB_LINK_TYPE_ETH		= 1
+};
+
+enum {
+	MLX5_IB_SQ_STRIDE	= 6,
+	MLX5_IB_CACHE_LINE_SIZE	= 64,
+};
+
+static const u32 mlx5_ib_opcode[] = {
+	[IB_WR_SEND]				= MLX5_OPCODE_SEND,
+	[IB_WR_SEND_WITH_IMM]			= MLX5_OPCODE_SEND_IMM,
+	[IB_WR_RDMA_WRITE]			= MLX5_OPCODE_RDMA_WRITE,
+	[IB_WR_RDMA_WRITE_WITH_IMM]		= MLX5_OPCODE_RDMA_WRITE_IMM,
+	[IB_WR_RDMA_READ]			= MLX5_OPCODE_RDMA_READ,
+	[IB_WR_ATOMIC_CMP_AND_SWP]		= MLX5_OPCODE_ATOMIC_CS,
+	[IB_WR_ATOMIC_FETCH_AND_ADD]		= MLX5_OPCODE_ATOMIC_FA,
+	[IB_WR_SEND_WITH_INV]			= MLX5_OPCODE_SEND_INVAL,
+	[IB_WR_LOCAL_INV]			= MLX5_OPCODE_UMR,
+	[IB_WR_FAST_REG_MR]			= MLX5_OPCODE_UMR,
+	[IB_WR_MASKED_ATOMIC_CMP_AND_SWP]	= MLX5_OPCODE_ATOMIC_MASKED_CS,
+	[IB_WR_MASKED_ATOMIC_FETCH_AND_ADD]	= MLX5_OPCODE_ATOMIC_MASKED_FA,
+	[MLX5_IB_WR_UMR]			= MLX5_OPCODE_UMR,
+};
+
+struct umr_wr {
+	u64				virt_addr;
+	struct ib_pd		       *pd;
+	unsigned int			page_shift;
+	unsigned int			npages;
+	u32				length;
+	int				access_flags;
+	u32				mkey;
+};
+
+static int is_qp0(enum ib_qp_type qp_type)
+{
+	return qp_type == IB_QPT_SMI;
+}
+
+static int is_qp1(enum ib_qp_type qp_type)
+{
+	return qp_type == IB_QPT_GSI;
+}
+
+static int is_sqp(enum ib_qp_type qp_type)
+{
+	return is_qp0(qp_type) || is_qp1(qp_type);
+}
+
+static void *get_wqe(struct mlx5_ib_qp *qp, int offset)
+{
+	return mlx5_buf_offset(&qp->buf, offset);
+}
+
+static void *get_recv_wqe(struct mlx5_ib_qp *qp, int n)
+{
+	return get_wqe(qp, qp->rq.offset + (n << qp->rq.wqe_shift));
+}
+
+void *mlx5_get_send_wqe(struct mlx5_ib_qp *qp, int n)
+{
+	return get_wqe(qp, qp->sq.offset + (n << MLX5_IB_SQ_STRIDE));
+}
+
+static void mlx5_ib_qp_event(struct mlx5_core_qp *qp, int type)
+{
+	struct ib_qp *ibqp = &to_mibqp(qp)->ibqp;
+	struct ib_event event;
+
+	if (type == MLX5_EVENT_TYPE_PATH_MIG)
+		to_mibqp(qp)->port = to_mibqp(qp)->alt_port;
+
+	if (ibqp->event_handler) {
+		event.device     = ibqp->device;
+		event.element.qp = ibqp;
+		switch (type) {
+		case MLX5_EVENT_TYPE_PATH_MIG:
+			event.event = IB_EVENT_PATH_MIG;
+			break;
+		case MLX5_EVENT_TYPE_COMM_EST:
+			event.event = IB_EVENT_COMM_EST;
+			break;
+		case MLX5_EVENT_TYPE_SQ_DRAINED:
+			event.event = IB_EVENT_SQ_DRAINED;
+			break;
+		case MLX5_EVENT_TYPE_SRQ_LAST_WQE:
+			event.event = IB_EVENT_QP_LAST_WQE_REACHED;
+			break;
+		case MLX5_EVENT_TYPE_WQ_CATAS_ERROR:
+			event.event = IB_EVENT_QP_FATAL;
+			break;
+		case MLX5_EVENT_TYPE_PATH_MIG_FAILED:
+			event.event = IB_EVENT_PATH_MIG_ERR;
+			break;
+		case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
+			event.event = IB_EVENT_QP_REQ_ERR;
+			break;
+		case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
+			event.event = IB_EVENT_QP_ACCESS_ERR;
+			break;
+		default:
+			pr_warn("mlx5_ib: Unexpected event type %d on QP %06x\n", type, qp->qpn);
+			return;
+		}
+
+		ibqp->event_handler(&event, ibqp->qp_context);
+	}
+}
+
+static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap,
+		       int has_rq, struct mlx5_ib_qp *qp, struct mlx5_ib_create_qp *ucmd)
+{
+	int wqe_size;
+	int wq_size;
+
+	/* Sanity check RQ size before proceeding */
+	if (cap->max_recv_wr  > dev->mdev.caps.max_wqes)
+		return -EINVAL;
+
+	if (!has_rq) {
+		qp->rq.max_gs = 0;
+		qp->rq.wqe_cnt = 0;
+		qp->rq.wqe_shift = 0;
+	} else {
+		if (ucmd) {
+			qp->rq.wqe_cnt = ucmd->rq_wqe_count;
+			qp->rq.wqe_shift = ucmd->rq_wqe_shift;
+			qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig;
+			qp->rq.max_post = qp->rq.wqe_cnt;
+		} else {
+			wqe_size = qp->wq_sig ? sizeof(struct mlx5_wqe_signature_seg) : 0;
+			wqe_size += cap->max_recv_sge * sizeof(struct mlx5_wqe_data_seg);
+			wqe_size = roundup_pow_of_two(wqe_size);
+			wq_size = roundup_pow_of_two(cap->max_recv_wr) * wqe_size;
+			wq_size = max_t(int, wq_size, MLX5_SEND_WQE_BB);
+			qp->rq.wqe_cnt = wq_size / wqe_size;
+			if (wqe_size > dev->mdev.caps.max_rq_desc_sz) {
+				mlx5_ib_dbg(dev, "wqe_size %d, max %d\n",
+					    wqe_size,
+					    dev->mdev.caps.max_rq_desc_sz);
+				return -EINVAL;
+			}
+			qp->rq.wqe_shift = ilog2(wqe_size);
+			qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig;
+			qp->rq.max_post = qp->rq.wqe_cnt;
+		}
+	}
+
+	return 0;
+}
+
+static int sq_overhead(enum ib_qp_type qp_type)
+{
+	int size = 0;
+
+	switch (qp_type) {
+	case IB_QPT_XRC_INI:
+		size = sizeof(struct mlx5_wqe_xrc_seg);
+		/* fall through */
+	case IB_QPT_RC:
+		size += sizeof(struct mlx5_wqe_ctrl_seg) +
+			sizeof(struct mlx5_wqe_atomic_seg) +
+			sizeof(struct mlx5_wqe_raddr_seg);
+		break;
+
+	case IB_QPT_UC:
+		size = sizeof(struct mlx5_wqe_ctrl_seg) +
+			sizeof(struct mlx5_wqe_raddr_seg);
+		break;
+
+	case IB_QPT_UD:
+	case IB_QPT_SMI:
+	case IB_QPT_GSI:
+		size = sizeof(struct mlx5_wqe_ctrl_seg) +
+			sizeof(struct mlx5_wqe_datagram_seg);
+		break;
+
+	case MLX5_IB_QPT_REG_UMR:
+		size = sizeof(struct mlx5_wqe_ctrl_seg) +
+			sizeof(struct mlx5_wqe_umr_ctrl_seg) +
+			sizeof(struct mlx5_mkey_seg);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return size;
+}
+
+static int calc_send_wqe(struct ib_qp_init_attr *attr)
+{
+	int inl_size = 0;
+	int size;
+
+	size = sq_overhead(attr->qp_type);
+	if (size < 0)
+		return size;
+
+	if (attr->cap.max_inline_data) {
+		inl_size = size + sizeof(struct mlx5_wqe_inline_seg) +
+			attr->cap.max_inline_data;
+	}
+
+	size += attr->cap.max_send_sge * sizeof(struct mlx5_wqe_data_seg);
+
+	return ALIGN(max_t(int, inl_size, size), MLX5_SEND_WQE_BB);
+}
+
+static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,
+			struct mlx5_ib_qp *qp)
+{
+	int wqe_size;
+	int wq_size;
+
+	if (!attr->cap.max_send_wr)
+		return 0;
+
+	wqe_size = calc_send_wqe(attr);
+	mlx5_ib_dbg(dev, "wqe_size %d\n", wqe_size);
+	if (wqe_size < 0)
+		return wqe_size;
+
+	if (wqe_size > dev->mdev.caps.max_sq_desc_sz) {
+		mlx5_ib_dbg(dev, "\n");
+		return -EINVAL;
+	}
+
+	qp->max_inline_data = wqe_size - sq_overhead(attr->qp_type) -
+		sizeof(struct mlx5_wqe_inline_seg);
+	attr->cap.max_inline_data = qp->max_inline_data;
+
+	wq_size = roundup_pow_of_two(attr->cap.max_send_wr * wqe_size);
+	qp->sq.wqe_cnt = wq_size / MLX5_SEND_WQE_BB;
+	qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);
+	qp->sq.max_gs = attr->cap.max_send_sge;
+	qp->sq.max_post = 1 << ilog2(wq_size / wqe_size);
+
+	return wq_size;
+}
+
+static int set_user_buf_size(struct mlx5_ib_dev *dev,
+			    struct mlx5_ib_qp *qp,
+			    struct mlx5_ib_create_qp *ucmd)
+{
+	int desc_sz = 1 << qp->sq.wqe_shift;
+
+	if (desc_sz > dev->mdev.caps.max_sq_desc_sz) {
+		mlx5_ib_warn(dev, "desc_sz %d, max_sq_desc_sz %d\n",
+			     desc_sz, dev->mdev.caps.max_sq_desc_sz);
+		return -EINVAL;
+	}
+
+	if (ucmd->sq_wqe_count && ((1 << ilog2(ucmd->sq_wqe_count)) != ucmd->sq_wqe_count)) {
+		mlx5_ib_warn(dev, "sq_wqe_count %d, sq_wqe_count %d\n",
+			     ucmd->sq_wqe_count, ucmd->sq_wqe_count);
+		return -EINVAL;
+	}
+
+	qp->sq.wqe_cnt = ucmd->sq_wqe_count;
+
+	if (qp->sq.wqe_cnt > dev->mdev.caps.max_wqes) {
+		mlx5_ib_warn(dev, "wqe_cnt %d, max_wqes %d\n",
+			     qp->sq.wqe_cnt, dev->mdev.caps.max_wqes);
+		return -EINVAL;
+	}
+
+	qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
+		(qp->sq.wqe_cnt << 6);
+
+	return 0;
+}
+
+static int qp_has_rq(struct ib_qp_init_attr *attr)
+{
+	if (attr->qp_type == IB_QPT_XRC_INI ||
+	    attr->qp_type == IB_QPT_XRC_TGT || attr->srq ||
+	    attr->qp_type == MLX5_IB_QPT_REG_UMR ||
+	    !attr->cap.max_recv_wr)
+		return 0;
+
+	return 1;
+}
+
+static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari)
+{
+	int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE;
+	int start_uuar;
+	int i;
+
+	start_uuar = nuuars - uuari->num_low_latency_uuars;
+	for (i = start_uuar; i < nuuars; i++) {
+		if (!test_bit(i, uuari->bitmap)) {
+			set_bit(i, uuari->bitmap);
+			uuari->count[i]++;
+			return i;
+		}
+	}
+
+	return -ENOMEM;
+}
+
+static int alloc_med_class_uuar(struct mlx5_uuar_info *uuari)
+{
+	int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE;
+	int minidx = 1;
+	int uuarn;
+	int end;
+	int i;
+
+	end = nuuars - uuari->num_low_latency_uuars;
+
+	for (i = 1; i < end; i++) {
+		uuarn = i & 3;
+		if (uuarn == 2 || uuarn == 3)
+			continue;
+
+		if (uuari->count[i] < uuari->count[minidx])
+			minidx = i;
+	}
+
+	uuari->count[minidx]++;
+	return minidx;
+}
+
+static int alloc_uuar(struct mlx5_uuar_info *uuari,
+		      enum mlx5_ib_latency_class lat)
+{
+	int uuarn = -EINVAL;
+
+	mutex_lock(&uuari->lock);
+	switch (lat) {
+	case MLX5_IB_LATENCY_CLASS_LOW:
+		uuarn = 0;
+		uuari->count[uuarn]++;
+		break;
+
+	case MLX5_IB_LATENCY_CLASS_MEDIUM:
+		uuarn = alloc_med_class_uuar(uuari);
+		break;
+
+	case MLX5_IB_LATENCY_CLASS_HIGH:
+		uuarn = alloc_high_class_uuar(uuari);
+		break;
+
+	case MLX5_IB_LATENCY_CLASS_FAST_PATH:
+		uuarn = 2;
+		break;
+	}
+	mutex_unlock(&uuari->lock);
+
+	return uuarn;
+}
+
+static void free_med_class_uuar(struct mlx5_uuar_info *uuari, int uuarn)
+{
+	clear_bit(uuarn, uuari->bitmap);
+	--uuari->count[uuarn];
+}
+
+static void free_high_class_uuar(struct mlx5_uuar_info *uuari, int uuarn)
+{
+	clear_bit(uuarn, uuari->bitmap);
+	--uuari->count[uuarn];
+}
+
+static void free_uuar(struct mlx5_uuar_info *uuari, int uuarn)
+{
+	int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE;
+	int high_uuar = nuuars - uuari->num_low_latency_uuars;
+
+	mutex_lock(&uuari->lock);
+	if (uuarn == 0) {
+		--uuari->count[uuarn];
+		goto out;
+	}
+
+	if (uuarn < high_uuar) {
+		free_med_class_uuar(uuari, uuarn);
+		goto out;
+	}
+
+	free_high_class_uuar(uuari, uuarn);
+
+out:
+	mutex_unlock(&uuari->lock);
+}
+
+static enum mlx5_qp_state to_mlx5_state(enum ib_qp_state state)
+{
+	switch (state) {
+	case IB_QPS_RESET:	return MLX5_QP_STATE_RST;
+	case IB_QPS_INIT:	return MLX5_QP_STATE_INIT;
+	case IB_QPS_RTR:	return MLX5_QP_STATE_RTR;
+	case IB_QPS_RTS:	return MLX5_QP_STATE_RTS;
+	case IB_QPS_SQD:	return MLX5_QP_STATE_SQD;
+	case IB_QPS_SQE:	return MLX5_QP_STATE_SQER;
+	case IB_QPS_ERR:	return MLX5_QP_STATE_ERR;
+	default:		return -1;
+	}
+}
+
+static int to_mlx5_st(enum ib_qp_type type)
+{
+	switch (type) {
+	case IB_QPT_RC:			return MLX5_QP_ST_RC;
+	case IB_QPT_UC:			return MLX5_QP_ST_UC;
+	case IB_QPT_UD:			return MLX5_QP_ST_UD;
+	case MLX5_IB_QPT_REG_UMR:	return MLX5_QP_ST_REG_UMR;
+	case IB_QPT_XRC_INI:
+	case IB_QPT_XRC_TGT:		return MLX5_QP_ST_XRC;
+	case IB_QPT_SMI:		return MLX5_QP_ST_QP0;
+	case IB_QPT_GSI:		return MLX5_QP_ST_QP1;
+	case IB_QPT_RAW_IPV6:		return MLX5_QP_ST_RAW_IPV6;
+	case IB_QPT_RAW_ETHERTYPE:	return MLX5_QP_ST_RAW_ETHERTYPE;
+	case IB_QPT_RAW_PACKET:
+	case IB_QPT_MAX:
+	default:		return -EINVAL;
+	}
+}
+
+static int uuarn_to_uar_index(struct mlx5_uuar_info *uuari, int uuarn)
+{
+	return uuari->uars[uuarn / MLX5_BF_REGS_PER_PAGE].index;
+}
+
+static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
+			  struct mlx5_ib_qp *qp, struct ib_udata *udata,
+			  struct mlx5_create_qp_mbox_in **in,
+			  struct mlx5_ib_create_qp_resp *resp, int *inlen)
+{
+	struct mlx5_ib_ucontext *context;
+	struct mlx5_ib_create_qp ucmd;
+	int page_shift;
+	int uar_index;
+	int npages;
+	u32 offset;
+	int uuarn;
+	int ncont;
+	int err;
+
+	err = ib_copy_from_udata(&ucmd, udata, sizeof(ucmd));
+	if (err) {
+		mlx5_ib_dbg(dev, "copy failed\n");
+		return err;
+	}
+
+	context = to_mucontext(pd->uobject->context);
+	/*
+	 * TBD: should come from the verbs when we have the API
+	 */
+	uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_HIGH);
+	if (uuarn < 0) {
+		mlx5_ib_dbg(dev, "failed to allocate low latency UUAR\n");
+		mlx5_ib_dbg(dev, "reverting to high latency\n");
+		uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_LOW);
+		if (uuarn < 0) {
+			mlx5_ib_dbg(dev, "uuar allocation failed\n");
+			return uuarn;
+		}
+	}
+
+	uar_index = uuarn_to_uar_index(&context->uuari, uuarn);
+	mlx5_ib_dbg(dev, "uuarn 0x%x, uar_index 0x%x\n", uuarn, uar_index);
+
+	err = set_user_buf_size(dev, qp, &ucmd);
+	if (err)
+		goto err_uuar;
+
+	qp->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr,
+			       qp->buf_size, 0, 0);
+	if (IS_ERR(qp->umem)) {
+		mlx5_ib_dbg(dev, "umem_get failed\n");
+		err = PTR_ERR(qp->umem);
+		goto err_uuar;
+	}
+
+	mlx5_ib_cont_pages(qp->umem, ucmd.buf_addr, &npages, &page_shift,
+			   &ncont, NULL);
+	err = mlx5_ib_get_buf_offset(ucmd.buf_addr, page_shift, &offset);
+	if (err) {
+		mlx5_ib_warn(dev, "bad offset\n");
+		goto err_umem;
+	}
+	mlx5_ib_dbg(dev, "addr 0x%llx, size %d, npages %d, page_shift %d, ncont %d, offset %d\n",
+		    ucmd.buf_addr, qp->buf_size, npages, page_shift, ncont, offset);
+
+	*inlen = sizeof(**in) + sizeof(*(*in)->pas) * ncont;
+	*in = mlx5_vzalloc(*inlen);
+	if (!*in) {
+		err = -ENOMEM;
+		goto err_umem;
+	}
+	mlx5_ib_populate_pas(dev, qp->umem, page_shift, (*in)->pas, 0);
+	(*in)->ctx.log_pg_sz_remote_qpn =
+		cpu_to_be32((page_shift - PAGE_SHIFT) << 24);
+	(*in)->ctx.params2 = cpu_to_be32(offset << 6);
+
+	(*in)->ctx.qp_counter_set_usr_page = cpu_to_be32(uar_index);
+	resp->uuar_index = uuarn;
+	qp->uuarn = uuarn;
+
+	err = mlx5_ib_db_map_user(context, ucmd.db_addr, &qp->db);
+	if (err) {
+		mlx5_ib_dbg(dev, "map failed\n");
+		goto err_free;
+	}
+
+	err = ib_copy_to_udata(udata, resp, sizeof(*resp));
+	if (err) {
+		mlx5_ib_dbg(dev, "copy failed\n");
+		goto err_unmap;
+	}
+	qp->create_type = MLX5_QP_USER;
+
+	return 0;
+
+err_unmap:
+	mlx5_ib_db_unmap_user(context, &qp->db);
+
+err_free:
+	mlx5_vfree(*in);
+
+err_umem:
+	ib_umem_release(qp->umem);
+
+err_uuar:
+	free_uuar(&context->uuari, uuarn);
+	return err;
+}
+
+static void destroy_qp_user(struct ib_pd *pd, struct mlx5_ib_qp *qp)
+{
+	struct mlx5_ib_ucontext *context;
+
+	context = to_mucontext(pd->uobject->context);
+	mlx5_ib_db_unmap_user(context, &qp->db);
+	ib_umem_release(qp->umem);
+	free_uuar(&context->uuari, qp->uuarn);
+}
+
+static int create_kernel_qp(struct mlx5_ib_dev *dev,
+			    struct ib_qp_init_attr *init_attr,
+			    struct mlx5_ib_qp *qp,
+			    struct mlx5_create_qp_mbox_in **in, int *inlen)
+{
+	enum mlx5_ib_latency_class lc = MLX5_IB_LATENCY_CLASS_LOW;
+	struct mlx5_uuar_info *uuari;
+	int uar_index;
+	int uuarn;
+	int err;
+
+	uuari = &dev->mdev.priv.uuari;
+	if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)
+		qp->flags |= MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK;
+
+	if (init_attr->qp_type == MLX5_IB_QPT_REG_UMR)
+		lc = MLX5_IB_LATENCY_CLASS_FAST_PATH;
+
+	uuarn = alloc_uuar(uuari, lc);
+	if (uuarn < 0) {
+		mlx5_ib_dbg(dev, "\n");
+		return -ENOMEM;
+	}
+
+	qp->bf = &uuari->bfs[uuarn];
+	uar_index = qp->bf->uar->index;
+
+	err = calc_sq_size(dev, init_attr, qp);
+	if (err < 0) {
+		mlx5_ib_dbg(dev, "err %d\n", err);
+		goto err_uuar;
+	}
+
+	qp->rq.offset = 0;
+	qp->sq.offset = qp->rq.wqe_cnt << qp->rq.wqe_shift;
+	qp->buf_size = err + (qp->rq.wqe_cnt << qp->rq.wqe_shift);
+
+	err = mlx5_buf_alloc(&dev->mdev, qp->buf_size, PAGE_SIZE * 2, &qp->buf);
+	if (err) {
+		mlx5_ib_dbg(dev, "err %d\n", err);
+		goto err_uuar;
+	}
+
+	qp->sq.qend = mlx5_get_send_wqe(qp, qp->sq.wqe_cnt);
+	*inlen = sizeof(**in) + sizeof(*(*in)->pas) * qp->buf.npages;
+	*in = mlx5_vzalloc(*inlen);
+	if (!*in) {
+		err = -ENOMEM;
+		goto err_buf;
+	}
+	(*in)->ctx.qp_counter_set_usr_page = cpu_to_be32(uar_index);
+	(*in)->ctx.log_pg_sz_remote_qpn = cpu_to_be32((qp->buf.page_shift - PAGE_SHIFT) << 24);
+	/* Set "fast registration enabled" for all kernel QPs */
+	(*in)->ctx.params1 |= cpu_to_be32(1 << 11);
+	(*in)->ctx.sq_crq_size |= cpu_to_be16(1 << 4);
+
+	mlx5_fill_page_array(&qp->buf, (*in)->pas);
+
+	err = mlx5_db_alloc(&dev->mdev, &qp->db);
+	if (err) {
+		mlx5_ib_dbg(dev, "err %d\n", err);
+		goto err_free;
+	}
+
+	qp->db.db[0] = 0;
+	qp->db.db[1] = 0;
+
+	qp->sq.wrid = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wrid), GFP_KERNEL);
+	qp->sq.wr_data = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wr_data), GFP_KERNEL);
+	qp->rq.wrid = kmalloc(qp->rq.wqe_cnt * sizeof(*qp->rq.wrid), GFP_KERNEL);
+	qp->sq.w_list = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.w_list), GFP_KERNEL);
+	qp->sq.wqe_head = kmalloc(qp->sq.wqe_cnt * sizeof(*qp->sq.wqe_head), GFP_KERNEL);
+
+	if (!qp->sq.wrid || !qp->sq.wr_data || !qp->rq.wrid ||
+	    !qp->sq.w_list || !qp->sq.wqe_head) {
+		err = -ENOMEM;
+		goto err_wrid;
+	}
+	qp->create_type = MLX5_QP_KERNEL;
+
+	return 0;
+
+err_wrid:
+	mlx5_db_free(&dev->mdev, &qp->db);
+	kfree(qp->sq.wqe_head);
+	kfree(qp->sq.w_list);
+	kfree(qp->sq.wrid);
+	kfree(qp->sq.wr_data);
+	kfree(qp->rq.wrid);
+
+err_free:
+	mlx5_vfree(*in);
+
+err_buf:
+	mlx5_buf_free(&dev->mdev, &qp->buf);
+
+err_uuar:
+	free_uuar(&dev->mdev.priv.uuari, uuarn);
+	return err;
+}
+
+static void destroy_qp_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
+{
+	mlx5_db_free(&dev->mdev, &qp->db);
+	kfree(qp->sq.wqe_head);
+	kfree(qp->sq.w_list);
+	kfree(qp->sq.wrid);
+	kfree(qp->sq.wr_data);
+	kfree(qp->rq.wrid);
+	mlx5_buf_free(&dev->mdev, &qp->buf);
+	free_uuar(&dev->mdev.priv.uuari, qp->bf->uuarn);
+}
+
+static __be32 get_rx_type(struct mlx5_ib_qp *qp, struct ib_qp_init_attr *attr)
+{
+	if (attr->srq || (attr->qp_type == IB_QPT_XRC_TGT) ||
+	    (attr->qp_type == IB_QPT_XRC_INI))
+		return cpu_to_be32(MLX5_SRQ_RQ);
+	else if (!qp->has_rq)
+		return cpu_to_be32(MLX5_ZERO_LEN_RQ);
+	else
+		return cpu_to_be32(MLX5_NON_ZERO_RQ);
+}
+
+static int is_connected(enum ib_qp_type qp_type)
+{
+	if (qp_type == IB_QPT_RC || qp_type == IB_QPT_UC)
+		return 1;
+
+	return 0;
+}
+
+static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
+			    struct ib_qp_init_attr *init_attr,
+			    struct ib_udata *udata, struct mlx5_ib_qp *qp)
+{
+	struct mlx5_ib_resources *devr = &dev->devr;
+	struct mlx5_ib_create_qp_resp resp;
+	struct mlx5_create_qp_mbox_in *in;
+	struct mlx5_ib_create_qp ucmd;
+	int inlen = sizeof(*in);
+	int err;
+
+	mutex_init(&qp->mutex);
+	spin_lock_init(&qp->sq.lock);
+	spin_lock_init(&qp->rq.lock);
+
+	if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
+		qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;
+
+	if (pd && pd->uobject) {
+		if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
+			mlx5_ib_dbg(dev, "copy failed\n");
+			return -EFAULT;
+		}
+
+		qp->wq_sig = !!(ucmd.flags & MLX5_QP_FLAG_SIGNATURE);
+		qp->scat_cqe = !!(ucmd.flags & MLX5_QP_FLAG_SCATTER_CQE);
+	} else {
+		qp->wq_sig = !!wq_signature;
+	}
+
+	qp->has_rq = qp_has_rq(init_attr);
+	err = set_rq_size(dev, &init_attr->cap, qp->has_rq,
+			  qp, (pd && pd->uobject) ? &ucmd : NULL);
+	if (err) {
+		mlx5_ib_dbg(dev, "err %d\n", err);
+		return err;
+	}
+
+	if (pd) {
+		if (pd->uobject) {
+			mlx5_ib_dbg(dev, "requested sq_wqe_count (%d)\n", ucmd.sq_wqe_count);
+			if (ucmd.rq_wqe_shift != qp->rq.wqe_shift ||
+			    ucmd.rq_wqe_count != qp->rq.wqe_cnt) {
+				mlx5_ib_dbg(dev, "invalid rq params\n");
+				return -EINVAL;
+			}
+			if (ucmd.sq_wqe_count > dev->mdev.caps.max_wqes) {
+				mlx5_ib_dbg(dev, "requested sq_wqe_count (%d) > max allowed (%d)\n",
+					    ucmd.sq_wqe_count, dev->mdev.caps.max_wqes);
+				return -EINVAL;
+			}
+			err = create_user_qp(dev, pd, qp, udata, &in, &resp, &inlen);
+			if (err)
+				mlx5_ib_dbg(dev, "err %d\n", err);
+		} else {
+			err = create_kernel_qp(dev, init_attr, qp, &in, &inlen);
+			if (err)
+				mlx5_ib_dbg(dev, "err %d\n", err);
+			else
+				qp->pa_lkey = to_mpd(pd)->pa_lkey;
+		}
+
+		if (err)
+			return err;
+	} else {
+		in = mlx5_vzalloc(sizeof(*in));
+		if (!in)
+			return -ENOMEM;
+
+		qp->create_type = MLX5_QP_EMPTY;
+	}
+
+	if (is_sqp(init_attr->qp_type))
+		qp->port = init_attr->port_num;
+
+	in->ctx.flags = cpu_to_be32(to_mlx5_st(init_attr->qp_type) << 16 |
+				    MLX5_QP_PM_MIGRATED << 11);
+
+	if (init_attr->qp_type != MLX5_IB_QPT_REG_UMR)
+		in->ctx.flags_pd = cpu_to_be32(to_mpd(pd ? pd : devr->p0)->pdn);
+	else
+		in->ctx.flags_pd = cpu_to_be32(MLX5_QP_LAT_SENSITIVE);
+
+	if (qp->wq_sig)
+		in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_ENABLE_SIG);
+
+	if (qp->scat_cqe && is_connected(init_attr->qp_type)) {
+		int rcqe_sz;
+		int scqe_sz;
+
+		rcqe_sz = mlx5_ib_get_cqe_size(dev, init_attr->recv_cq);
+		scqe_sz = mlx5_ib_get_cqe_size(dev, init_attr->send_cq);
+
+		if (rcqe_sz == 128)
+			in->ctx.cs_res = MLX5_RES_SCAT_DATA64_CQE;
+		else
+			in->ctx.cs_res = MLX5_RES_SCAT_DATA32_CQE;
+
+		if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) {
+			if (scqe_sz == 128)
+				in->ctx.cs_req = MLX5_REQ_SCAT_DATA64_CQE;
+			else
+				in->ctx.cs_req = MLX5_REQ_SCAT_DATA32_CQE;
+		}
+	}
+
+	if (qp->rq.wqe_cnt) {
+		in->ctx.rq_size_stride = (qp->rq.wqe_shift - 4);
+		in->ctx.rq_size_stride |= ilog2(qp->rq.wqe_cnt) << 3;
+	}
+
+	in->ctx.rq_type_srqn = get_rx_type(qp, init_attr);
+
+	if (qp->sq.wqe_cnt)
+		in->ctx.sq_crq_size |= cpu_to_be16(ilog2(qp->sq.wqe_cnt) << 11);
+	else
+		in->ctx.sq_crq_size |= cpu_to_be16(0x8000);
+
+	/* Set default resources */
+	switch (init_attr->qp_type) {
+	case IB_QPT_XRC_TGT:
+		in->ctx.cqn_recv = cpu_to_be32(to_mcq(devr->c0)->mcq.cqn);
+		in->ctx.cqn_send = cpu_to_be32(to_mcq(devr->c0)->mcq.cqn);
+		in->ctx.rq_type_srqn |= cpu_to_be32(to_msrq(devr->s0)->msrq.srqn);
+		in->ctx.xrcd = cpu_to_be32(to_mxrcd(init_attr->xrcd)->xrcdn);
+		break;
+	case IB_QPT_XRC_INI:
+		in->ctx.cqn_recv = cpu_to_be32(to_mcq(devr->c0)->mcq.cqn);
+		in->ctx.xrcd = cpu_to_be32(to_mxrcd(devr->x1)->xrcdn);
+		in->ctx.rq_type_srqn |= cpu_to_be32(to_msrq(devr->s0)->msrq.srqn);
+		break;
+	default:
+		if (init_attr->srq) {
+			in->ctx.xrcd = cpu_to_be32(to_mxrcd(devr->x0)->xrcdn);
+			in->ctx.rq_type_srqn |= cpu_to_be32(to_msrq(init_attr->srq)->msrq.srqn);
+		} else {
+			in->ctx.xrcd = cpu_to_be32(to_mxrcd(devr->x1)->xrcdn);
+			in->ctx.rq_type_srqn |= cpu_to_be32(to_msrq(devr->s0)->msrq.srqn);
+		}
+	}
+
+	if (init_attr->send_cq)
+		in->ctx.cqn_send = cpu_to_be32(to_mcq(init_attr->send_cq)->mcq.cqn);
+
+	if (init_attr->recv_cq)
+		in->ctx.cqn_recv = cpu_to_be32(to_mcq(init_attr->recv_cq)->mcq.cqn);
+
+	in->ctx.db_rec_addr = cpu_to_be64(qp->db.dma);
+
+	err = mlx5_core_create_qp(&dev->mdev, &qp->mqp, in, inlen);
+	if (err) {
+		mlx5_ib_dbg(dev, "create qp failed\n");
+		goto err_create;
+	}
+
+	mlx5_vfree(in);
+	/* Hardware wants QPN written in big-endian order (after
+	 * shifting) for send doorbell.  Precompute this value to save
+	 * a little bit when posting sends.
+	 */
+	qp->doorbell_qpn = swab32(qp->mqp.qpn << 8);
+
+	qp->mqp.event = mlx5_ib_qp_event;
+
+	return 0;
+
+err_create:
+	if (qp->create_type == MLX5_QP_USER)
+		destroy_qp_user(pd, qp);
+	else if (qp->create_type == MLX5_QP_KERNEL)
+		destroy_qp_kernel(dev, qp);
+
+	mlx5_vfree(in);
+	return err;
+}
+
+static void mlx5_ib_lock_cqs(struct mlx5_ib_cq *send_cq, struct mlx5_ib_cq *recv_cq)
+	__acquires(&send_cq->lock) __acquires(&recv_cq->lock)
+{
+	if (send_cq) {
+		if (recv_cq) {
+			if (send_cq->mcq.cqn < recv_cq->mcq.cqn)  {
+				spin_lock_irq(&send_cq->lock);
+				spin_lock_nested(&recv_cq->lock,
+						 SINGLE_DEPTH_NESTING);
+			} else if (send_cq->mcq.cqn == recv_cq->mcq.cqn) {
+				spin_lock_irq(&send_cq->lock);
+				__acquire(&recv_cq->lock);
+			} else {
+				spin_lock_irq(&recv_cq->lock);
+				spin_lock_nested(&send_cq->lock,
+						 SINGLE_DEPTH_NESTING);
+			}
+		} else {
+			spin_lock_irq(&send_cq->lock);
+		}
+	} else if (recv_cq) {
+		spin_lock_irq(&recv_cq->lock);
+	}
+}
+
+static void mlx5_ib_unlock_cqs(struct mlx5_ib_cq *send_cq, struct mlx5_ib_cq *recv_cq)
+	__releases(&send_cq->lock) __releases(&recv_cq->lock)
+{
+	if (send_cq) {
+		if (recv_cq) {
+			if (send_cq->mcq.cqn < recv_cq->mcq.cqn)  {
+				spin_unlock(&recv_cq->lock);
+				spin_unlock_irq(&send_cq->lock);
+			} else if (send_cq->mcq.cqn == recv_cq->mcq.cqn) {
+				__release(&recv_cq->lock);
+				spin_unlock_irq(&send_cq->lock);
+			} else {
+				spin_unlock(&send_cq->lock);
+				spin_unlock_irq(&recv_cq->lock);
+			}
+		} else {
+			spin_unlock_irq(&send_cq->lock);
+		}
+	} else if (recv_cq) {
+		spin_unlock_irq(&recv_cq->lock);
+	}
+}
+
+static struct mlx5_ib_pd *get_pd(struct mlx5_ib_qp *qp)
+{
+	return to_mpd(qp->ibqp.pd);
+}
+
+static void get_cqs(struct mlx5_ib_qp *qp,
+		    struct mlx5_ib_cq **send_cq, struct mlx5_ib_cq **recv_cq)
+{
+	switch (qp->ibqp.qp_type) {
+	case IB_QPT_XRC_TGT:
+		*send_cq = NULL;
+		*recv_cq = NULL;
+		break;
+	case MLX5_IB_QPT_REG_UMR:
+	case IB_QPT_XRC_INI:
+		*send_cq = to_mcq(qp->ibqp.send_cq);
+		*recv_cq = NULL;
+		break;
+
+	case IB_QPT_SMI:
+	case IB_QPT_GSI:
+	case IB_QPT_RC:
+	case IB_QPT_UC:
+	case IB_QPT_UD:
+	case IB_QPT_RAW_IPV6:
+	case IB_QPT_RAW_ETHERTYPE:
+		*send_cq = to_mcq(qp->ibqp.send_cq);
+		*recv_cq = to_mcq(qp->ibqp.recv_cq);
+		break;
+
+	case IB_QPT_RAW_PACKET:
+	case IB_QPT_MAX:
+	default:
+		*send_cq = NULL;
+		*recv_cq = NULL;
+		break;
+	}
+}
+
+static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
+{
+	struct mlx5_ib_cq *send_cq, *recv_cq;
+	struct mlx5_modify_qp_mbox_in *in;
+	int err;
+
+	in = kzalloc(sizeof(*in), GFP_KERNEL);
+	if (!in)
+		return;
+	if (qp->state != IB_QPS_RESET)
+		if (mlx5_core_qp_modify(&dev->mdev, to_mlx5_state(qp->state),
+					MLX5_QP_STATE_RST, in, sizeof(*in), &qp->mqp))
+			mlx5_ib_warn(dev, "mlx5_ib: modify QP %06x to RESET failed\n",
+				     qp->mqp.qpn);
+
+	get_cqs(qp, &send_cq, &recv_cq);
+
+	if (qp->create_type == MLX5_QP_KERNEL) {
+		mlx5_ib_lock_cqs(send_cq, recv_cq);
+		__mlx5_ib_cq_clean(recv_cq, qp->mqp.qpn,
+				   qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);
+		if (send_cq != recv_cq)
+			__mlx5_ib_cq_clean(send_cq, qp->mqp.qpn, NULL);
+		mlx5_ib_unlock_cqs(send_cq, recv_cq);
+	}
+
+	err = mlx5_core_destroy_qp(&dev->mdev, &qp->mqp);
+	if (err)
+		mlx5_ib_warn(dev, "failed to destroy QP 0x%x\n", qp->mqp.qpn);
+	kfree(in);
+
+
+	if (qp->create_type == MLX5_QP_KERNEL)
+		destroy_qp_kernel(dev, qp);
+	else if (qp->create_type == MLX5_QP_USER)
+		destroy_qp_user(&get_pd(qp)->ibpd, qp);
+}
+
+static const char *ib_qp_type_str(enum ib_qp_type type)
+{
+	switch (type) {
+	case IB_QPT_SMI:
+		return "IB_QPT_SMI";
+	case IB_QPT_GSI:
+		return "IB_QPT_GSI";
+	case IB_QPT_RC:
+		return "IB_QPT_RC";
+	case IB_QPT_UC:
+		return "IB_QPT_UC";
+	case IB_QPT_UD:
+		return "IB_QPT_UD";
+	case IB_QPT_RAW_IPV6:
+		return "IB_QPT_RAW_IPV6";
+	case IB_QPT_RAW_ETHERTYPE:
+		return "IB_QPT_RAW_ETHERTYPE";
+	case IB_QPT_XRC_INI:
+		return "IB_QPT_XRC_INI";
+	case IB_QPT_XRC_TGT:
+		return "IB_QPT_XRC_TGT";
+	case IB_QPT_RAW_PACKET:
+		return "IB_QPT_RAW_PACKET";
+	case MLX5_IB_QPT_REG_UMR:
+		return "MLX5_IB_QPT_REG_UMR";
+	case IB_QPT_MAX:
+	default:
+		return "Invalid QP type";
+	}
+}
+
+struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
+				struct ib_qp_init_attr *init_attr,
+				struct ib_udata *udata)
+{
+	struct mlx5_ib_dev *dev;
+	struct mlx5_ib_qp *qp;
+	u16 xrcdn = 0;
+	int err;
+
+	if (pd) {
+		dev = to_mdev(pd->device);
+	} else {
+		/* being cautious here */
+		if (init_attr->qp_type != IB_QPT_XRC_TGT &&
+		    init_attr->qp_type != MLX5_IB_QPT_REG_UMR) {
+			pr_warn("%s: no PD for transport %s\n", __func__,
+				ib_qp_type_str(init_attr->qp_type));
+			return ERR_PTR(-EINVAL);
+		}
+		dev = to_mdev(to_mxrcd(init_attr->xrcd)->ibxrcd.device);
+	}
+
+	switch (init_attr->qp_type) {
+	case IB_QPT_XRC_TGT:
+	case IB_QPT_XRC_INI:
+		if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_XRC)) {
+			mlx5_ib_dbg(dev, "XRC not supported\n");
+			return ERR_PTR(-ENOSYS);
+		}
+		init_attr->recv_cq = NULL;
+		if (init_attr->qp_type == IB_QPT_XRC_TGT) {
+			xrcdn = to_mxrcd(init_attr->xrcd)->xrcdn;
+			init_attr->send_cq = NULL;
+		}
+
+		/* fall through */
+	case IB_QPT_RC:
+	case IB_QPT_UC:
+	case IB_QPT_UD:
+	case IB_QPT_SMI:
+	case IB_QPT_GSI:
+	case MLX5_IB_QPT_REG_UMR:
+		qp = kzalloc(sizeof(*qp), GFP_KERNEL);
+		if (!qp)
+			return ERR_PTR(-ENOMEM);
+
+		err = create_qp_common(dev, pd, init_attr, udata, qp);
+		if (err) {
+			mlx5_ib_dbg(dev, "create_qp_common failed\n");
+			kfree(qp);
+			return ERR_PTR(err);
+		}
+
+		if (is_qp0(init_attr->qp_type))
+			qp->ibqp.qp_num = 0;
+		else if (is_qp1(init_attr->qp_type))
+			qp->ibqp.qp_num = 1;
+		else
+			qp->ibqp.qp_num = qp->mqp.qpn;
+
+		mlx5_ib_dbg(dev, "ib qpnum 0x%x, mlx qpn 0x%x, rcqn 0x%x, scqn 0x%x\n",
+			    qp->ibqp.qp_num, qp->mqp.qpn, to_mcq(init_attr->recv_cq)->mcq.cqn,
+			    to_mcq(init_attr->send_cq)->mcq.cqn);
+
+		qp->xrcdn = xrcdn;
+
+		break;
+
+	case IB_QPT_RAW_IPV6:
+	case IB_QPT_RAW_ETHERTYPE:
+	case IB_QPT_RAW_PACKET:
+	case IB_QPT_MAX:
+	default:
+		mlx5_ib_dbg(dev, "unsupported qp type %d\n",
+			    init_attr->qp_type);
+		/* Don't support raw QPs */
+		return ERR_PTR(-EINVAL);
+	}
+
+	return &qp->ibqp;
+}
+
+int mlx5_ib_destroy_qp(struct ib_qp *qp)
+{
+	struct mlx5_ib_dev *dev = to_mdev(qp->device);
+	struct mlx5_ib_qp *mqp = to_mqp(qp);
+
+	destroy_qp_common(dev, mqp);
+
+	kfree(mqp);
+
+	return 0;
+}
+
+static __be32 to_mlx5_access_flags(struct mlx5_ib_qp *qp, const struct ib_qp_attr *attr,
+				   int attr_mask)
+{
+	u32 hw_access_flags = 0;
+	u8 dest_rd_atomic;
+	u32 access_flags;
+
+	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
+		dest_rd_atomic = attr->max_dest_rd_atomic;
+	else
+		dest_rd_atomic = qp->resp_depth;
+
+	if (attr_mask & IB_QP_ACCESS_FLAGS)
+		access_flags = attr->qp_access_flags;
+	else
+		access_flags = qp->atomic_rd_en;
+
+	if (!dest_rd_atomic)
+		access_flags &= IB_ACCESS_REMOTE_WRITE;
+
+	if (access_flags & IB_ACCESS_REMOTE_READ)
+		hw_access_flags |= MLX5_QP_BIT_RRE;
+	if (access_flags & IB_ACCESS_REMOTE_ATOMIC)
+		hw_access_flags |= (MLX5_QP_BIT_RAE | MLX5_ATOMIC_MODE_CX);
+	if (access_flags & IB_ACCESS_REMOTE_WRITE)
+		hw_access_flags |= MLX5_QP_BIT_RWE;
+
+	return cpu_to_be32(hw_access_flags);
+}
+
+enum {
+	MLX5_PATH_FLAG_FL	= 1 << 0,
+	MLX5_PATH_FLAG_FREE_AR	= 1 << 1,
+	MLX5_PATH_FLAG_COUNTER	= 1 << 2,
+};
+
+static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate)
+{
+	if (rate == IB_RATE_PORT_CURRENT) {
+		return 0;
+	} else if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) {
+		return -EINVAL;
+	} else {
+		while (rate != IB_RATE_2_5_GBPS &&
+		       !(1 << (rate + MLX5_STAT_RATE_OFFSET) &
+			 dev->mdev.caps.stat_rate_support))
+			--rate;
+	}
+
+	return rate + MLX5_STAT_RATE_OFFSET;
+}
+
+static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
+			 struct mlx5_qp_path *path, u8 port, int attr_mask,
+			 u32 path_flags, const struct ib_qp_attr *attr)
+{
+	int err;
+
+	path->fl = (path_flags & MLX5_PATH_FLAG_FL) ? 0x80 : 0;
+	path->free_ar = (path_flags & MLX5_PATH_FLAG_FREE_AR) ? 0x80 : 0;
+
+	if (attr_mask & IB_QP_PKEY_INDEX)
+		path->pkey_index = attr->pkey_index;
+
+	path->grh_mlid	= ah->src_path_bits & 0x7f;
+	path->rlid	= cpu_to_be16(ah->dlid);
+
+	if (ah->ah_flags & IB_AH_GRH) {
+		path->grh_mlid |= 1 << 7;
+		path->mgid_index = ah->grh.sgid_index;
+		path->hop_limit  = ah->grh.hop_limit;
+		path->tclass_flowlabel =
+			cpu_to_be32((ah->grh.traffic_class << 20) |
+				    (ah->grh.flow_label));
+		memcpy(path->rgid, ah->grh.dgid.raw, 16);
+	}
+
+	err = ib_rate_to_mlx5(dev, ah->static_rate);
+	if (err < 0)
+		return err;
+	path->static_rate = err;
+	path->port = port;
+
+	if (ah->ah_flags & IB_AH_GRH) {
+		if (ah->grh.sgid_index >= dev->mdev.caps.port[port - 1].gid_table_len) {
+			pr_err(KERN_ERR "sgid_index (%u) too large. max is %d\n",
+			       ah->grh.sgid_index, dev->mdev.caps.port[port - 1].gid_table_len);
+			return -EINVAL;
+		}
+
+		path->grh_mlid |= 1 << 7;
+		path->mgid_index = ah->grh.sgid_index;
+		path->hop_limit  = ah->grh.hop_limit;
+		path->tclass_flowlabel =
+			cpu_to_be32((ah->grh.traffic_class << 20) |
+				    (ah->grh.flow_label));
+		memcpy(path->rgid, ah->grh.dgid.raw, 16);
+	}
+
+	if (attr_mask & IB_QP_TIMEOUT)
+		path->ackto_lt = attr->timeout << 3;
+
+	path->sl = ah->sl & 0xf;
+
+	return 0;
+}
+
+static enum mlx5_qp_optpar opt_mask[MLX5_QP_NUM_STATE][MLX5_QP_NUM_STATE][MLX5_QP_ST_MAX] = {
+	[MLX5_QP_STATE_INIT] = {
+		[MLX5_QP_STATE_INIT] = {
+			[MLX5_QP_ST_RC] = MLX5_QP_OPTPAR_RRE		|
+					  MLX5_QP_OPTPAR_RAE		|
+					  MLX5_QP_OPTPAR_RWE		|
+					  MLX5_QP_OPTPAR_PKEY_INDEX	|
+					  MLX5_QP_OPTPAR_PRI_PORT,
+			[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_RWE		|
+					  MLX5_QP_OPTPAR_PKEY_INDEX	|
+					  MLX5_QP_OPTPAR_PRI_PORT,
+			[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_PKEY_INDEX	|
+					  MLX5_QP_OPTPAR_Q_KEY		|
+					  MLX5_QP_OPTPAR_PRI_PORT,
+		},
+		[MLX5_QP_STATE_RTR] = {
+			[MLX5_QP_ST_RC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH  |
+					  MLX5_QP_OPTPAR_RRE            |
+					  MLX5_QP_OPTPAR_RAE            |
+					  MLX5_QP_OPTPAR_RWE            |
+					  MLX5_QP_OPTPAR_PKEY_INDEX,
+			[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH  |
+					  MLX5_QP_OPTPAR_RWE            |
+					  MLX5_QP_OPTPAR_PKEY_INDEX,
+			[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_PKEY_INDEX     |
+					  MLX5_QP_OPTPAR_Q_KEY,
+			[MLX5_QP_ST_MLX] = MLX5_QP_OPTPAR_PKEY_INDEX	|
+					   MLX5_QP_OPTPAR_Q_KEY,
+		},
+	},
+	[MLX5_QP_STATE_RTR] = {
+		[MLX5_QP_STATE_RTS] = {
+			[MLX5_QP_ST_RC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH	|
+					  MLX5_QP_OPTPAR_RRE		|
+					  MLX5_QP_OPTPAR_RAE		|
+					  MLX5_QP_OPTPAR_RWE		|
+					  MLX5_QP_OPTPAR_PM_STATE	|
+					  MLX5_QP_OPTPAR_RNR_TIMEOUT,
+			[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH	|
+					  MLX5_QP_OPTPAR_RWE		|
+					  MLX5_QP_OPTPAR_PM_STATE,
+			[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_Q_KEY,
+		},
+	},
+	[MLX5_QP_STATE_RTS] = {
+		[MLX5_QP_STATE_RTS] = {
+			[MLX5_QP_ST_RC] = MLX5_QP_OPTPAR_RRE		|
+					  MLX5_QP_OPTPAR_RAE		|
+					  MLX5_QP_OPTPAR_RWE		|
+					  MLX5_QP_OPTPAR_RNR_TIMEOUT	|
+					  MLX5_QP_OPTPAR_PM_STATE,
+			[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_RWE		|
+					  MLX5_QP_OPTPAR_PM_STATE,
+			[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_Q_KEY		|
+					  MLX5_QP_OPTPAR_SRQN		|
+					  MLX5_QP_OPTPAR_CQN_RCV,
+		},
+	},
+	[MLX5_QP_STATE_SQER] = {
+		[MLX5_QP_STATE_RTS] = {
+			[MLX5_QP_ST_UD]	 = MLX5_QP_OPTPAR_Q_KEY,
+			[MLX5_QP_ST_MLX] = MLX5_QP_OPTPAR_Q_KEY,
+		},
+	},
+};
+
+static int ib_nr_to_mlx5_nr(int ib_mask)
+{
+	switch (ib_mask) {
+	case IB_QP_STATE:
+		return 0;
+	case IB_QP_CUR_STATE:
+		return 0;
+	case IB_QP_EN_SQD_ASYNC_NOTIFY:
+		return 0;
+	case IB_QP_ACCESS_FLAGS:
+		return MLX5_QP_OPTPAR_RWE | MLX5_QP_OPTPAR_RRE |
+			MLX5_QP_OPTPAR_RAE;
+	case IB_QP_PKEY_INDEX:
+		return MLX5_QP_OPTPAR_PKEY_INDEX;
+	case IB_QP_PORT:
+		return MLX5_QP_OPTPAR_PRI_PORT;
+	case IB_QP_QKEY:
+		return MLX5_QP_OPTPAR_Q_KEY;
+	case IB_QP_AV:
+		return MLX5_QP_OPTPAR_PRIMARY_ADDR_PATH |
+			MLX5_QP_OPTPAR_PRI_PORT;
+	case IB_QP_PATH_MTU:
+		return 0;
+	case IB_QP_TIMEOUT:
+		return MLX5_QP_OPTPAR_ACK_TIMEOUT;
+	case IB_QP_RETRY_CNT:
+		return MLX5_QP_OPTPAR_RETRY_COUNT;
+	case IB_QP_RNR_RETRY:
+		return MLX5_QP_OPTPAR_RNR_RETRY;
+	case IB_QP_RQ_PSN:
+		return 0;
+	case IB_QP_MAX_QP_RD_ATOMIC:
+		return MLX5_QP_OPTPAR_SRA_MAX;
+	case IB_QP_ALT_PATH:
+		return MLX5_QP_OPTPAR_ALT_ADDR_PATH;
+	case IB_QP_MIN_RNR_TIMER:
+		return MLX5_QP_OPTPAR_RNR_TIMEOUT;
+	case IB_QP_SQ_PSN:
+		return 0;
+	case IB_QP_MAX_DEST_RD_ATOMIC:
+		return MLX5_QP_OPTPAR_RRA_MAX | MLX5_QP_OPTPAR_RWE |
+			MLX5_QP_OPTPAR_RRE | MLX5_QP_OPTPAR_RAE;
+	case IB_QP_PATH_MIG_STATE:
+		return MLX5_QP_OPTPAR_PM_STATE;
+	case IB_QP_CAP:
+		return 0;
+	case IB_QP_DEST_QPN:
+		return 0;
+	}
+	return 0;
+}
+
+static int ib_mask_to_mlx5_opt(int ib_mask)
+{
+	int result = 0;
+	int i;
+
+	for (i = 0; i < 8 * sizeof(int); i++) {
+		if ((1 << i) & ib_mask)
+			result |= ib_nr_to_mlx5_nr(1 << i);
+	}
+
+	return result;
+}
+
+static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
+			       const struct ib_qp_attr *attr, int attr_mask,
+			       enum ib_qp_state cur_state, enum ib_qp_state new_state)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
+	struct mlx5_ib_qp *qp = to_mqp(ibqp);
+	struct mlx5_ib_cq *send_cq, *recv_cq;
+	struct mlx5_qp_context *context;
+	struct mlx5_modify_qp_mbox_in *in;
+	struct mlx5_ib_pd *pd;
+	enum mlx5_qp_state mlx5_cur, mlx5_new;
+	enum mlx5_qp_optpar optpar;
+	int sqd_event;
+	int mlx5_st;
+	int err;
+
+	in = kzalloc(sizeof(*in), GFP_KERNEL);
+	if (!in)
+		return -ENOMEM;
+
+	context = &in->ctx;
+	err = to_mlx5_st(ibqp->qp_type);
+	if (err < 0)
+		goto out;
+
+	context->flags = cpu_to_be32(err << 16);
+
+	if (!(attr_mask & IB_QP_PATH_MIG_STATE)) {
+		context->flags |= cpu_to_be32(MLX5_QP_PM_MIGRATED << 11);
+	} else {
+		switch (attr->path_mig_state) {
+		case IB_MIG_MIGRATED:
+			context->flags |= cpu_to_be32(MLX5_QP_PM_MIGRATED << 11);
+			break;
+		case IB_MIG_REARM:
+			context->flags |= cpu_to_be32(MLX5_QP_PM_REARM << 11);
+			break;
+		case IB_MIG_ARMED:
+			context->flags |= cpu_to_be32(MLX5_QP_PM_ARMED << 11);
+			break;
+		}
+	}
+
+	if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI) {
+		context->mtu_msgmax = (IB_MTU_256 << 5) | 8;
+	} else if (ibqp->qp_type == IB_QPT_UD ||
+		   ibqp->qp_type == MLX5_IB_QPT_REG_UMR) {
+		context->mtu_msgmax = (IB_MTU_4096 << 5) | 12;
+	} else if (attr_mask & IB_QP_PATH_MTU) {
+		if (attr->path_mtu < IB_MTU_256 ||
+		    attr->path_mtu > IB_MTU_4096) {
+			mlx5_ib_warn(dev, "invalid mtu %d\n", attr->path_mtu);
+			err = -EINVAL;
+			goto out;
+		}
+		context->mtu_msgmax = (attr->path_mtu << 5) | dev->mdev.caps.log_max_msg;
+	}
+
+	if (attr_mask & IB_QP_DEST_QPN)
+		context->log_pg_sz_remote_qpn = cpu_to_be32(attr->dest_qp_num);
+
+	if (attr_mask & IB_QP_PKEY_INDEX)
+		context->pri_path.pkey_index = attr->pkey_index;
+
+	/* todo implement counter_index functionality */
+
+	if (is_sqp(ibqp->qp_type))
+		context->pri_path.port = qp->port;
+
+	if (attr_mask & IB_QP_PORT)
+		context->pri_path.port = attr->port_num;
+
+	if (attr_mask & IB_QP_AV) {
+		err = mlx5_set_path(dev, &attr->ah_attr, &context->pri_path,
+				    attr_mask & IB_QP_PORT ? attr->port_num : qp->port,
+				    attr_mask, 0, attr);
+		if (err)
+			goto out;
+	}
+
+	if (attr_mask & IB_QP_TIMEOUT)
+		context->pri_path.ackto_lt |= attr->timeout << 3;
+
+	if (attr_mask & IB_QP_ALT_PATH) {
+		err = mlx5_set_path(dev, &attr->alt_ah_attr, &context->alt_path,
+				    attr->alt_port_num, attr_mask, 0, attr);
+		if (err)
+			goto out;
+	}
+
+	pd = get_pd(qp);
+	get_cqs(qp, &send_cq, &recv_cq);
+
+	context->flags_pd = cpu_to_be32(pd ? pd->pdn : to_mpd(dev->devr.p0)->pdn);
+	context->cqn_send = send_cq ? cpu_to_be32(send_cq->mcq.cqn) : 0;
+	context->cqn_recv = recv_cq ? cpu_to_be32(recv_cq->mcq.cqn) : 0;
+	context->params1  = cpu_to_be32(MLX5_IB_ACK_REQ_FREQ << 28);
+
+	if (attr_mask & IB_QP_RNR_RETRY)
+		context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
+
+	if (attr_mask & IB_QP_RETRY_CNT)
+		context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
+
+	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
+		if (attr->max_rd_atomic)
+			context->params1 |=
+				cpu_to_be32(fls(attr->max_rd_atomic - 1) << 21);
+	}
+
+	if (attr_mask & IB_QP_SQ_PSN)
+		context->next_send_psn = cpu_to_be32(attr->sq_psn);
+
+	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {
+		if (attr->max_dest_rd_atomic)
+			context->params2 |=
+				cpu_to_be32(fls(attr->max_dest_rd_atomic - 1) << 21);
+	}
+
+	if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC))
+		context->params2 |= to_mlx5_access_flags(qp, attr, attr_mask);
+
+	if (attr_mask & IB_QP_MIN_RNR_TIMER)
+		context->rnr_nextrecvpsn |= cpu_to_be32(attr->min_rnr_timer << 24);
+
+	if (attr_mask & IB_QP_RQ_PSN)
+		context->rnr_nextrecvpsn |= cpu_to_be32(attr->rq_psn);
+
+	if (attr_mask & IB_QP_QKEY)
+		context->qkey = cpu_to_be32(attr->qkey);
+
+	if (qp->rq.wqe_cnt && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
+		context->db_rec_addr = cpu_to_be64(qp->db.dma);
+
+	if (cur_state == IB_QPS_RTS && new_state == IB_QPS_SQD	&&
+	    attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY && attr->en_sqd_async_notify)
+		sqd_event = 1;
+	else
+		sqd_event = 0;
+
+	if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
+		context->sq_crq_size |= cpu_to_be16(1 << 4);
+
+
+	mlx5_cur = to_mlx5_state(cur_state);
+	mlx5_new = to_mlx5_state(new_state);
+	mlx5_st = to_mlx5_st(ibqp->qp_type);
+	if (mlx5_cur < 0 || mlx5_new < 0 || mlx5_st < 0)
+		goto out;
+
+	optpar = ib_mask_to_mlx5_opt(attr_mask);
+	optpar &= opt_mask[mlx5_cur][mlx5_new][mlx5_st];
+	in->optparam = cpu_to_be32(optpar);
+	err = mlx5_core_qp_modify(&dev->mdev, to_mlx5_state(cur_state),
+				  to_mlx5_state(new_state), in, sqd_event,
+				  &qp->mqp);
+	if (err)
+		goto out;
+
+	qp->state = new_state;
+
+	if (attr_mask & IB_QP_ACCESS_FLAGS)
+		qp->atomic_rd_en = attr->qp_access_flags;
+	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
+		qp->resp_depth = attr->max_dest_rd_atomic;
+	if (attr_mask & IB_QP_PORT)
+		qp->port = attr->port_num;
+	if (attr_mask & IB_QP_ALT_PATH)
+		qp->alt_port = attr->alt_port_num;
+
+	/*
+	 * If we moved a kernel QP to RESET, clean up all old CQ
+	 * entries and reinitialize the QP.
+	 */
+	if (new_state == IB_QPS_RESET && !ibqp->uobject) {
+		mlx5_ib_cq_clean(recv_cq, qp->mqp.qpn,
+				 ibqp->srq ? to_msrq(ibqp->srq) : NULL);
+		if (send_cq != recv_cq)
+			mlx5_ib_cq_clean(send_cq, qp->mqp.qpn, NULL);
+
+		qp->rq.head = 0;
+		qp->rq.tail = 0;
+		qp->sq.head = 0;
+		qp->sq.tail = 0;
+		qp->sq.cur_post = 0;
+		qp->sq.last_poll = 0;
+		qp->db.db[MLX5_RCV_DBR] = 0;
+		qp->db.db[MLX5_SND_DBR] = 0;
+	}
+
+out:
+	kfree(in);
+	return err;
+}
+
+int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+		      int attr_mask, struct ib_udata *udata)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
+	struct mlx5_ib_qp *qp = to_mqp(ibqp);
+	enum ib_qp_state cur_state, new_state;
+	int err = -EINVAL;
+	int port;
+
+	mutex_lock(&qp->mutex);
+
+	cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;
+	new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
+
+	if (ibqp->qp_type != MLX5_IB_QPT_REG_UMR &&
+	    !ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask))
+		goto out;
+
+	if ((attr_mask & IB_QP_PORT) &&
+	    (attr->port_num == 0 || attr->port_num > dev->mdev.caps.num_ports))
+		goto out;
+
+	if (attr_mask & IB_QP_PKEY_INDEX) {
+		port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
+		if (attr->pkey_index >= dev->mdev.caps.port[port - 1].pkey_table_len)
+			goto out;
+	}
+
+	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
+	    attr->max_rd_atomic > dev->mdev.caps.max_ra_res_qp)
+		goto out;
+
+	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
+	    attr->max_dest_rd_atomic > dev->mdev.caps.max_ra_req_qp)
+		goto out;
+
+	if (cur_state == new_state && cur_state == IB_QPS_RESET) {
+		err = 0;
+		goto out;
+	}
+
+	err = __mlx5_ib_modify_qp(ibqp, attr, attr_mask, cur_state, new_state);
+
+out:
+	mutex_unlock(&qp->mutex);
+	return err;
+}
+
+static int mlx5_wq_overflow(struct mlx5_ib_wq *wq, int nreq, struct ib_cq *ib_cq)
+{
+	struct mlx5_ib_cq *cq;
+	unsigned cur;
+
+	cur = wq->head - wq->tail;
+	if (likely(cur + nreq < wq->max_post))
+		return 0;
+
+	cq = to_mcq(ib_cq);
+	spin_lock(&cq->lock);
+	cur = wq->head - wq->tail;
+	spin_unlock(&cq->lock);
+
+	return cur + nreq >= wq->max_post;
+}
+
+static __always_inline void set_raddr_seg(struct mlx5_wqe_raddr_seg *rseg,
+					  u64 remote_addr, u32 rkey)
+{
+	rseg->raddr    = cpu_to_be64(remote_addr);
+	rseg->rkey     = cpu_to_be32(rkey);
+	rseg->reserved = 0;
+}
+
+static void set_atomic_seg(struct mlx5_wqe_atomic_seg *aseg, struct ib_send_wr *wr)
+{
+	if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {
+		aseg->swap_add = cpu_to_be64(wr->wr.atomic.swap);
+		aseg->compare  = cpu_to_be64(wr->wr.atomic.compare_add);
+	} else if (wr->opcode == IB_WR_MASKED_ATOMIC_FETCH_AND_ADD) {
+		aseg->swap_add = cpu_to_be64(wr->wr.atomic.compare_add);
+		aseg->compare  = cpu_to_be64(wr->wr.atomic.compare_add_mask);
+	} else {
+		aseg->swap_add = cpu_to_be64(wr->wr.atomic.compare_add);
+		aseg->compare  = 0;
+	}
+}
+
+static void set_masked_atomic_seg(struct mlx5_wqe_masked_atomic_seg *aseg,
+				  struct ib_send_wr *wr)
+{
+	aseg->swap_add		= cpu_to_be64(wr->wr.atomic.swap);
+	aseg->swap_add_mask	= cpu_to_be64(wr->wr.atomic.swap_mask);
+	aseg->compare		= cpu_to_be64(wr->wr.atomic.compare_add);
+	aseg->compare_mask	= cpu_to_be64(wr->wr.atomic.compare_add_mask);
+}
+
+static void set_datagram_seg(struct mlx5_wqe_datagram_seg *dseg,
+			     struct ib_send_wr *wr)
+{
+	memcpy(&dseg->av, &to_mah(wr->wr.ud.ah)->av, sizeof(struct mlx5_av));
+	dseg->av.dqp_dct = cpu_to_be32(wr->wr.ud.remote_qpn | MLX5_EXTENDED_UD_AV);
+	dseg->av.key.qkey.qkey = cpu_to_be32(wr->wr.ud.remote_qkey);
+}
+
+static void set_data_ptr_seg(struct mlx5_wqe_data_seg *dseg, struct ib_sge *sg)
+{
+	dseg->byte_count = cpu_to_be32(sg->length);
+	dseg->lkey       = cpu_to_be32(sg->lkey);
+	dseg->addr       = cpu_to_be64(sg->addr);
+}
+
+static __be16 get_klm_octo(int npages)
+{
+	return cpu_to_be16(ALIGN(npages, 8) / 2);
+}
+
+static __be64 frwr_mkey_mask(void)
+{
+	u64 result;
+
+	result = MLX5_MKEY_MASK_LEN		|
+		MLX5_MKEY_MASK_PAGE_SIZE	|
+		MLX5_MKEY_MASK_START_ADDR	|
+		MLX5_MKEY_MASK_EN_RINVAL	|
+		MLX5_MKEY_MASK_KEY		|
+		MLX5_MKEY_MASK_LR		|
+		MLX5_MKEY_MASK_LW		|
+		MLX5_MKEY_MASK_RR		|
+		MLX5_MKEY_MASK_RW		|
+		MLX5_MKEY_MASK_A		|
+		MLX5_MKEY_MASK_SMALL_FENCE	|
+		MLX5_MKEY_MASK_FREE;
+
+	return cpu_to_be64(result);
+}
+
+static void set_frwr_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
+				 struct ib_send_wr *wr, int li)
+{
+	memset(umr, 0, sizeof(*umr));
+
+	if (li) {
+		umr->mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE);
+		umr->flags = 1 << 7;
+		return;
+	}
+
+	umr->flags = (1 << 5); /* fail if not free */
+	umr->klm_octowords = get_klm_octo(wr->wr.fast_reg.page_list_len);
+	umr->mkey_mask = frwr_mkey_mask();
+}
+
+static void set_reg_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
+				struct ib_send_wr *wr)
+{
+	struct umr_wr *umrwr = (struct umr_wr *)&wr->wr.fast_reg;
+	u64 mask;
+
+	memset(umr, 0, sizeof(*umr));
+
+	if (!(wr->send_flags & MLX5_IB_SEND_UMR_UNREG)) {
+		umr->flags = 1 << 5; /* fail if not free */
+		umr->klm_octowords = get_klm_octo(umrwr->npages);
+		mask =  MLX5_MKEY_MASK_LEN		|
+			MLX5_MKEY_MASK_PAGE_SIZE	|
+			MLX5_MKEY_MASK_START_ADDR	|
+			MLX5_MKEY_MASK_PD		|
+			MLX5_MKEY_MASK_LR		|
+			MLX5_MKEY_MASK_LW		|
+			MLX5_MKEY_MASK_RR		|
+			MLX5_MKEY_MASK_RW		|
+			MLX5_MKEY_MASK_A		|
+			MLX5_MKEY_MASK_FREE;
+		umr->mkey_mask = cpu_to_be64(mask);
+	} else {
+		umr->flags = 2 << 5; /* fail if free */
+		mask = MLX5_MKEY_MASK_FREE;
+		umr->mkey_mask = cpu_to_be64(mask);
+	}
+
+	if (!wr->num_sge)
+		umr->flags |= (1 << 7); /* inline */
+}
+
+static u8 get_umr_flags(int acc)
+{
+	return (acc & IB_ACCESS_REMOTE_ATOMIC ? MLX5_PERM_ATOMIC       : 0) |
+	       (acc & IB_ACCESS_REMOTE_WRITE  ? MLX5_PERM_REMOTE_WRITE : 0) |
+	       (acc & IB_ACCESS_REMOTE_READ   ? MLX5_PERM_REMOTE_READ  : 0) |
+	       (acc & IB_ACCESS_LOCAL_WRITE   ? MLX5_PERM_LOCAL_WRITE  : 0) |
+		MLX5_PERM_LOCAL_READ | MLX5_PERM_UMR_EN | MLX5_ACCESS_MODE_MTT;
+}
+
+static void set_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr,
+			     int li, int *writ)
+{
+	memset(seg, 0, sizeof(*seg));
+	if (li) {
+		seg->status = 1 << 6;
+		return;
+	}
+
+	seg->flags = get_umr_flags(wr->wr.fast_reg.access_flags);
+	*writ = seg->flags & (MLX5_PERM_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE);
+	seg->qpn_mkey7_0 = cpu_to_be32((wr->wr.fast_reg.rkey & 0xff) | 0xffffff00);
+	seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL);
+	seg->start_addr = cpu_to_be64(wr->wr.fast_reg.iova_start);
+	seg->len = cpu_to_be64(wr->wr.fast_reg.length);
+	seg->xlt_oct_size = cpu_to_be32((wr->wr.fast_reg.page_list_len + 1) / 2);
+	seg->log2_page_size = wr->wr.fast_reg.page_shift;
+}
+
+static void set_reg_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr)
+{
+	memset(seg, 0, sizeof(*seg));
+	if (wr->send_flags & MLX5_IB_SEND_UMR_UNREG) {
+		seg->status = 1 << 6;
+		return;
+	}
+
+	seg->flags = convert_access(wr->wr.fast_reg.access_flags);
+	seg->flags_pd = cpu_to_be32(to_mpd((struct ib_pd *)wr->wr.fast_reg.page_list)->pdn);
+	seg->start_addr = cpu_to_be64(wr->wr.fast_reg.iova_start);
+	seg->len = cpu_to_be64(wr->wr.fast_reg.length);
+	seg->log2_page_size = wr->wr.fast_reg.page_shift;
+	seg->qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
+}
+
+static void set_frwr_pages(struct mlx5_wqe_data_seg *dseg,
+			   struct ib_send_wr *wr,
+			   struct mlx5_core_dev *mdev,
+			   struct mlx5_ib_pd *pd,
+			   int writ)
+{
+	struct mlx5_ib_fast_reg_page_list *mfrpl = to_mfrpl(wr->wr.fast_reg.page_list);
+	u64 *page_list = wr->wr.fast_reg.page_list->page_list;
+	u64 perm = MLX5_EN_RD | (writ ? MLX5_EN_WR : 0);
+	int i;
+
+	for (i = 0; i < wr->wr.fast_reg.page_list_len; i++)
+		mfrpl->mapped_page_list[i] = cpu_to_be64(page_list[i] | perm);
+	dseg->addr = cpu_to_be64(mfrpl->map);
+	dseg->byte_count = cpu_to_be32(ALIGN(sizeof(u64) * wr->wr.fast_reg.page_list_len, 64));
+	dseg->lkey = cpu_to_be32(pd->pa_lkey);
+}
+
+static __be32 send_ieth(struct ib_send_wr *wr)
+{
+	switch (wr->opcode) {
+	case IB_WR_SEND_WITH_IMM:
+	case IB_WR_RDMA_WRITE_WITH_IMM:
+		return wr->ex.imm_data;
+
+	case IB_WR_SEND_WITH_INV:
+		return cpu_to_be32(wr->ex.invalidate_rkey);
+
+	default:
+		return 0;
+	}
+}
+
+static u8 calc_sig(void *wqe, int size)
+{
+	u8 *p = wqe;
+	u8 res = 0;
+	int i;
+
+	for (i = 0; i < size; i++)
+		res ^= p[i];
+
+	return ~res;
+}
+
+static u8 wq_sig(void *wqe)
+{
+	return calc_sig(wqe, (*((u8 *)wqe + 8) & 0x3f) << 4);
+}
+
+static int set_data_inl_seg(struct mlx5_ib_qp *qp, struct ib_send_wr *wr,
+			    void *wqe, int *sz)
+{
+	struct mlx5_wqe_inline_seg *seg;
+	void *qend = qp->sq.qend;
+	void *addr;
+	int inl = 0;
+	int copy;
+	int len;
+	int i;
+
+	seg = wqe;
+	wqe += sizeof(*seg);
+	for (i = 0; i < wr->num_sge; i++) {
+		addr = (void *)(unsigned long)(wr->sg_list[i].addr);
+		len  = wr->sg_list[i].length;
+		inl += len;
+
+		if (unlikely(inl > qp->max_inline_data))
+			return -ENOMEM;
+
+		if (unlikely(wqe + len > qend)) {
+			copy = qend - wqe;
+			memcpy(wqe, addr, copy);
+			addr += copy;
+			len -= copy;
+			wqe = mlx5_get_send_wqe(qp, 0);
+		}
+		memcpy(wqe, addr, len);
+		wqe += len;
+	}
+
+	seg->byte_count = cpu_to_be32(inl | MLX5_INLINE_SEG);
+
+	*sz = ALIGN(inl + sizeof(seg->byte_count), 16) / 16;
+
+	return 0;
+}
+
+static int set_frwr_li_wr(void **seg, struct ib_send_wr *wr, int *size,
+			  struct mlx5_core_dev *mdev, struct mlx5_ib_pd *pd, struct mlx5_ib_qp *qp)
+{
+	int writ = 0;
+	int li;
+
+	li = wr->opcode == IB_WR_LOCAL_INV ? 1 : 0;
+	if (unlikely(wr->send_flags & IB_SEND_INLINE))
+		return -EINVAL;
+
+	set_frwr_umr_segment(*seg, wr, li);
+	*seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
+	*size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
+	if (unlikely((*seg == qp->sq.qend)))
+		*seg = mlx5_get_send_wqe(qp, 0);
+	set_mkey_segment(*seg, wr, li, &writ);
+	*seg += sizeof(struct mlx5_mkey_seg);
+	*size += sizeof(struct mlx5_mkey_seg) / 16;
+	if (unlikely((*seg == qp->sq.qend)))
+		*seg = mlx5_get_send_wqe(qp, 0);
+	if (!li) {
+		set_frwr_pages(*seg, wr, mdev, pd, writ);
+		*seg += sizeof(struct mlx5_wqe_data_seg);
+		*size += (sizeof(struct mlx5_wqe_data_seg) / 16);
+	}
+	return 0;
+}
+
+static void dump_wqe(struct mlx5_ib_qp *qp, int idx, int size_16)
+{
+	__be32 *p = NULL;
+	int tidx = idx;
+	int i, j;
+
+	pr_debug("dump wqe at %p\n", mlx5_get_send_wqe(qp, tidx));
+	for (i = 0, j = 0; i < size_16 * 4; i += 4, j += 4) {
+		if ((i & 0xf) == 0) {
+			void *buf = mlx5_get_send_wqe(qp, tidx);
+			tidx = (tidx + 1) & (qp->sq.wqe_cnt - 1);
+			p = buf;
+			j = 0;
+		}
+		pr_debug("%08x %08x %08x %08x\n", be32_to_cpu(p[j]),
+			 be32_to_cpu(p[j + 1]), be32_to_cpu(p[j + 2]),
+			 be32_to_cpu(p[j + 3]));
+	}
+}
+
+static void mlx5_bf_copy(u64 __iomem *dst, u64 *src,
+			 unsigned bytecnt, struct mlx5_ib_qp *qp)
+{
+	while (bytecnt > 0) {
+		__iowrite64_copy(dst++, src++, 8);
+		__iowrite64_copy(dst++, src++, 8);
+		__iowrite64_copy(dst++, src++, 8);
+		__iowrite64_copy(dst++, src++, 8);
+		__iowrite64_copy(dst++, src++, 8);
+		__iowrite64_copy(dst++, src++, 8);
+		__iowrite64_copy(dst++, src++, 8);
+		__iowrite64_copy(dst++, src++, 8);
+		bytecnt -= 64;
+		if (unlikely(src == qp->sq.qend))
+			src = mlx5_get_send_wqe(qp, 0);
+	}
+}
+
+static u8 get_fence(u8 fence, struct ib_send_wr *wr)
+{
+	if (unlikely(wr->opcode == IB_WR_LOCAL_INV &&
+		     wr->send_flags & IB_SEND_FENCE))
+		return MLX5_FENCE_MODE_STRONG_ORDERING;
+
+	if (unlikely(fence)) {
+		if (wr->send_flags & IB_SEND_FENCE)
+			return MLX5_FENCE_MODE_SMALL_AND_FENCE;
+		else
+			return fence;
+
+	} else {
+		return 0;
+	}
+}
+
+int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+		      struct ib_send_wr **bad_wr)
+{
+	struct mlx5_wqe_ctrl_seg *ctrl = NULL;  /* compiler warning */
+	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
+	struct mlx5_core_dev *mdev = &dev->mdev;
+	struct mlx5_ib_qp *qp = to_mqp(ibqp);
+	struct mlx5_wqe_data_seg *dpseg;
+	struct mlx5_wqe_xrc_seg *xrc;
+	struct mlx5_bf *bf = qp->bf;
+	int uninitialized_var(size);
+	void *qend = qp->sq.qend;
+	unsigned long flags;
+	u32 mlx5_opcode;
+	unsigned idx;
+	int err = 0;
+	int inl = 0;
+	int num_sge;
+	void *seg;
+	int nreq;
+	int i;
+	u8 next_fence = 0;
+	u8 opmod = 0;
+	u8 fence;
+
+	spin_lock_irqsave(&qp->sq.lock, flags);
+
+	for (nreq = 0; wr; nreq++, wr = wr->next) {
+		if (unlikely(wr->opcode >= sizeof(mlx5_ib_opcode) / sizeof(mlx5_ib_opcode[0]))) {
+			mlx5_ib_warn(dev, "\n");
+			err = -EINVAL;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		if (unlikely(mlx5_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq))) {
+			mlx5_ib_warn(dev, "\n");
+			err = -ENOMEM;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		fence = qp->fm_cache;
+		num_sge = wr->num_sge;
+		if (unlikely(num_sge > qp->sq.max_gs)) {
+			mlx5_ib_warn(dev, "\n");
+			err = -ENOMEM;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		idx = qp->sq.cur_post & (qp->sq.wqe_cnt - 1);
+		seg = mlx5_get_send_wqe(qp, idx);
+		ctrl = seg;
+		*(uint32_t *)(seg + 8) = 0;
+		ctrl->imm = send_ieth(wr);
+		ctrl->fm_ce_se = qp->sq_signal_bits |
+			(wr->send_flags & IB_SEND_SIGNALED ?
+			 MLX5_WQE_CTRL_CQ_UPDATE : 0) |
+			(wr->send_flags & IB_SEND_SOLICITED ?
+			 MLX5_WQE_CTRL_SOLICITED : 0);
+
+		seg += sizeof(*ctrl);
+		size = sizeof(*ctrl) / 16;
+
+		switch (ibqp->qp_type) {
+		case IB_QPT_XRC_INI:
+			xrc = seg;
+			xrc->xrc_srqn = htonl(wr->xrc_remote_srq_num);
+			seg += sizeof(*xrc);
+			size += sizeof(*xrc) / 16;
+			/* fall through */
+		case IB_QPT_RC:
+			switch (wr->opcode) {
+			case IB_WR_RDMA_READ:
+			case IB_WR_RDMA_WRITE:
+			case IB_WR_RDMA_WRITE_WITH_IMM:
+				set_raddr_seg(seg, wr->wr.rdma.remote_addr,
+					      wr->wr.rdma.rkey);
+				seg  += sizeof(struct mlx5_wqe_raddr_seg);
+				size += sizeof(struct mlx5_wqe_raddr_seg) / 16;
+				break;
+
+			case IB_WR_ATOMIC_CMP_AND_SWP:
+			case IB_WR_ATOMIC_FETCH_AND_ADD:
+				set_raddr_seg(seg, wr->wr.atomic.remote_addr,
+					      wr->wr.atomic.rkey);
+				seg  += sizeof(struct mlx5_wqe_raddr_seg);
+
+				set_atomic_seg(seg, wr);
+				seg  += sizeof(struct mlx5_wqe_atomic_seg);
+
+				size += (sizeof(struct mlx5_wqe_raddr_seg) +
+					 sizeof(struct mlx5_wqe_atomic_seg)) / 16;
+				break;
+
+			case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
+				set_raddr_seg(seg, wr->wr.atomic.remote_addr,
+					      wr->wr.atomic.rkey);
+				seg  += sizeof(struct mlx5_wqe_raddr_seg);
+
+				set_masked_atomic_seg(seg, wr);
+				seg  += sizeof(struct mlx5_wqe_masked_atomic_seg);
+
+				size += (sizeof(struct mlx5_wqe_raddr_seg) +
+					 sizeof(struct mlx5_wqe_masked_atomic_seg)) / 16;
+				break;
+
+			case IB_WR_LOCAL_INV:
+				next_fence = MLX5_FENCE_MODE_INITIATOR_SMALL;
+				qp->sq.wr_data[idx] = IB_WR_LOCAL_INV;
+				ctrl->imm = cpu_to_be32(wr->ex.invalidate_rkey);
+				err = set_frwr_li_wr(&seg, wr, &size, mdev, to_mpd(ibqp->pd), qp);
+				if (err) {
+					mlx5_ib_warn(dev, "\n");
+					*bad_wr = wr;
+					goto out;
+				}
+				num_sge = 0;
+				break;
+
+			case IB_WR_FAST_REG_MR:
+				next_fence = MLX5_FENCE_MODE_INITIATOR_SMALL;
+				qp->sq.wr_data[idx] = IB_WR_FAST_REG_MR;
+				ctrl->imm = cpu_to_be32(wr->wr.fast_reg.rkey);
+				err = set_frwr_li_wr(&seg, wr, &size, mdev, to_mpd(ibqp->pd), qp);
+				if (err) {
+					mlx5_ib_warn(dev, "\n");
+					*bad_wr = wr;
+					goto out;
+				}
+				num_sge = 0;
+				break;
+
+			default:
+				break;
+			}
+			break;
+
+		case IB_QPT_UC:
+			switch (wr->opcode) {
+			case IB_WR_RDMA_WRITE:
+			case IB_WR_RDMA_WRITE_WITH_IMM:
+				set_raddr_seg(seg, wr->wr.rdma.remote_addr,
+					      wr->wr.rdma.rkey);
+				seg  += sizeof(struct mlx5_wqe_raddr_seg);
+				size += sizeof(struct mlx5_wqe_raddr_seg) / 16;
+				break;
+
+			default:
+				break;
+			}
+			break;
+
+		case IB_QPT_UD:
+		case IB_QPT_SMI:
+		case IB_QPT_GSI:
+			set_datagram_seg(seg, wr);
+			seg  += sizeof(struct mlx5_wqe_datagram_seg);
+			size += sizeof(struct mlx5_wqe_datagram_seg) / 16;
+			if (unlikely((seg == qend)))
+				seg = mlx5_get_send_wqe(qp, 0);
+			break;
+
+		case MLX5_IB_QPT_REG_UMR:
+			if (wr->opcode != MLX5_IB_WR_UMR) {
+				err = -EINVAL;
+				mlx5_ib_warn(dev, "bad opcode\n");
+				goto out;
+			}
+			qp->sq.wr_data[idx] = MLX5_IB_WR_UMR;
+			ctrl->imm = cpu_to_be32(wr->wr.fast_reg.rkey);
+			set_reg_umr_segment(seg, wr);
+			seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
+			size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
+			if (unlikely((seg == qend)))
+				seg = mlx5_get_send_wqe(qp, 0);
+			set_reg_mkey_segment(seg, wr);
+			seg += sizeof(struct mlx5_mkey_seg);
+			size += sizeof(struct mlx5_mkey_seg) / 16;
+			if (unlikely((seg == qend)))
+				seg = mlx5_get_send_wqe(qp, 0);
+			break;
+
+		default:
+			break;
+		}
+
+		if (wr->send_flags & IB_SEND_INLINE && num_sge) {
+			int uninitialized_var(sz);
+
+			err = set_data_inl_seg(qp, wr, seg, &sz);
+			if (unlikely(err)) {
+				mlx5_ib_warn(dev, "\n");
+				*bad_wr = wr;
+				goto out;
+			}
+			inl = 1;
+			size += sz;
+		} else {
+			dpseg = seg;
+			for (i = 0; i < num_sge; i++) {
+				if (unlikely(dpseg == qend)) {
+					seg = mlx5_get_send_wqe(qp, 0);
+					dpseg = seg;
+				}
+				if (likely(wr->sg_list[i].length)) {
+					set_data_ptr_seg(dpseg, wr->sg_list + i);
+					size += sizeof(struct mlx5_wqe_data_seg) / 16;
+					dpseg++;
+				}
+			}
+		}
+
+		mlx5_opcode = mlx5_ib_opcode[wr->opcode];
+		ctrl->opmod_idx_opcode = cpu_to_be32(((u32)(qp->sq.cur_post) << 8)	|
+						     mlx5_opcode			|
+						     ((u32)opmod << 24));
+		ctrl->qpn_ds = cpu_to_be32(size | (qp->mqp.qpn << 8));
+		ctrl->fm_ce_se |= get_fence(fence, wr);
+		qp->fm_cache = next_fence;
+		if (unlikely(qp->wq_sig))
+			ctrl->signature = wq_sig(ctrl);
+
+		qp->sq.wrid[idx] = wr->wr_id;
+		qp->sq.w_list[idx].opcode = mlx5_opcode;
+		qp->sq.wqe_head[idx] = qp->sq.head + nreq;
+		qp->sq.cur_post += DIV_ROUND_UP(size * 16, MLX5_SEND_WQE_BB);
+		qp->sq.w_list[idx].next = qp->sq.cur_post;
+
+		if (0)
+			dump_wqe(qp, idx, size);
+	}
+
+out:
+	if (likely(nreq)) {
+		qp->sq.head += nreq;
+
+		/* Make sure that descriptors are written before
+		 * updating doorbell record and ringing the doorbell
+		 */
+		wmb();
+
+		qp->db.db[MLX5_SND_DBR] = cpu_to_be32(qp->sq.cur_post);
+
+		if (bf->need_lock)
+			spin_lock(&bf->lock);
+
+		/* TBD enable WC */
+		if (0 && nreq == 1 && bf->uuarn && inl && size > 1 && size <= bf->buf_size / 16) {
+			mlx5_bf_copy(bf->reg + bf->offset, (u64 *)ctrl, ALIGN(size * 16, 64), qp);
+			/* wc_wmb(); */
+		} else {
+			mlx5_write64((__be32 *)ctrl, bf->regreg + bf->offset,
+				     MLX5_GET_DOORBELL_LOCK(&bf->lock32));
+			/* Make sure doorbells don't leak out of SQ spinlock
+			 * and reach the HCA out of order.
+			 */
+			mmiowb();
+		}
+		bf->offset ^= bf->buf_size;
+		if (bf->need_lock)
+			spin_unlock(&bf->lock);
+	}
+
+	spin_unlock_irqrestore(&qp->sq.lock, flags);
+
+	return err;
+}
+
+static void set_sig_seg(struct mlx5_rwqe_sig *sig, int size)
+{
+	sig->signature = calc_sig(sig, size);
+}
+
+int mlx5_ib_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+		      struct ib_recv_wr **bad_wr)
+{
+	struct mlx5_ib_qp *qp = to_mqp(ibqp);
+	struct mlx5_wqe_data_seg *scat;
+	struct mlx5_rwqe_sig *sig;
+	unsigned long flags;
+	int err = 0;
+	int nreq;
+	int ind;
+	int i;
+
+	spin_lock_irqsave(&qp->rq.lock, flags);
+
+	ind = qp->rq.head & (qp->rq.wqe_cnt - 1);
+
+	for (nreq = 0; wr; nreq++, wr = wr->next) {
+		if (mlx5_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) {
+			err = -ENOMEM;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		if (unlikely(wr->num_sge > qp->rq.max_gs)) {
+			err = -EINVAL;
+			*bad_wr = wr;
+			goto out;
+		}
+
+		scat = get_recv_wqe(qp, ind);
+		if (qp->wq_sig)
+			scat++;
+
+		for (i = 0; i < wr->num_sge; i++)
+			set_data_ptr_seg(scat + i, wr->sg_list + i);
+
+		if (i < qp->rq.max_gs) {
+			scat[i].byte_count = 0;
+			scat[i].lkey       = cpu_to_be32(MLX5_INVALID_LKEY);
+			scat[i].addr       = 0;
+		}
+
+		if (qp->wq_sig) {
+			sig = (struct mlx5_rwqe_sig *)scat;
+			set_sig_seg(sig, (qp->rq.max_gs + 1) << 2);
+		}
+
+		qp->rq.wrid[ind] = wr->wr_id;
+
+		ind = (ind + 1) & (qp->rq.wqe_cnt - 1);
+	}
+
+out:
+	if (likely(nreq)) {
+		qp->rq.head += nreq;
+
+		/* Make sure that descriptors are written before
+		 * doorbell record.
+		 */
+		wmb();
+
+		*qp->db.db = cpu_to_be32(qp->rq.head & 0xffff);
+	}
+
+	spin_unlock_irqrestore(&qp->rq.lock, flags);
+
+	return err;
+}
+
+static inline enum ib_qp_state to_ib_qp_state(enum mlx5_qp_state mlx5_state)
+{
+	switch (mlx5_state) {
+	case MLX5_QP_STATE_RST:      return IB_QPS_RESET;
+	case MLX5_QP_STATE_INIT:     return IB_QPS_INIT;
+	case MLX5_QP_STATE_RTR:      return IB_QPS_RTR;
+	case MLX5_QP_STATE_RTS:      return IB_QPS_RTS;
+	case MLX5_QP_STATE_SQ_DRAINING:
+	case MLX5_QP_STATE_SQD:      return IB_QPS_SQD;
+	case MLX5_QP_STATE_SQER:     return IB_QPS_SQE;
+	case MLX5_QP_STATE_ERR:      return IB_QPS_ERR;
+	default:		     return -1;
+	}
+}
+
+static inline enum ib_mig_state to_ib_mig_state(int mlx5_mig_state)
+{
+	switch (mlx5_mig_state) {
+	case MLX5_QP_PM_ARMED:		return IB_MIG_ARMED;
+	case MLX5_QP_PM_REARM:		return IB_MIG_REARM;
+	case MLX5_QP_PM_MIGRATED:	return IB_MIG_MIGRATED;
+	default: return -1;
+	}
+}
+
+static int to_ib_qp_access_flags(int mlx5_flags)
+{
+	int ib_flags = 0;
+
+	if (mlx5_flags & MLX5_QP_BIT_RRE)
+		ib_flags |= IB_ACCESS_REMOTE_READ;
+	if (mlx5_flags & MLX5_QP_BIT_RWE)
+		ib_flags |= IB_ACCESS_REMOTE_WRITE;
+	if (mlx5_flags & MLX5_QP_BIT_RAE)
+		ib_flags |= IB_ACCESS_REMOTE_ATOMIC;
+
+	return ib_flags;
+}
+
+static void to_ib_ah_attr(struct mlx5_ib_dev *ibdev, struct ib_ah_attr *ib_ah_attr,
+				struct mlx5_qp_path *path)
+{
+	struct mlx5_core_dev *dev = &ibdev->mdev;
+
+	memset(ib_ah_attr, 0, sizeof(*ib_ah_attr));
+	ib_ah_attr->port_num	  = path->port;
+
+	if (ib_ah_attr->port_num == 0 || ib_ah_attr->port_num > dev->caps.num_ports)
+		return;
+
+	ib_ah_attr->sl = path->sl & 0xf;
+
+	ib_ah_attr->dlid	  = be16_to_cpu(path->rlid);
+	ib_ah_attr->src_path_bits = path->grh_mlid & 0x7f;
+	ib_ah_attr->static_rate   = path->static_rate ? path->static_rate - 5 : 0;
+	ib_ah_attr->ah_flags      = (path->grh_mlid & (1 << 7)) ? IB_AH_GRH : 0;
+	if (ib_ah_attr->ah_flags) {
+		ib_ah_attr->grh.sgid_index = path->mgid_index;
+		ib_ah_attr->grh.hop_limit  = path->hop_limit;
+		ib_ah_attr->grh.traffic_class =
+			(be32_to_cpu(path->tclass_flowlabel) >> 20) & 0xff;
+		ib_ah_attr->grh.flow_label =
+			be32_to_cpu(path->tclass_flowlabel) & 0xfffff;
+		memcpy(ib_ah_attr->grh.dgid.raw,
+		       path->rgid, sizeof(ib_ah_attr->grh.dgid.raw));
+	}
+}
+
+int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
+		     struct ib_qp_init_attr *qp_init_attr)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
+	struct mlx5_ib_qp *qp = to_mqp(ibqp);
+	struct mlx5_query_qp_mbox_out *outb;
+	struct mlx5_qp_context *context;
+	int mlx5_state;
+	int err = 0;
+
+	mutex_lock(&qp->mutex);
+	outb = kzalloc(sizeof(*outb), GFP_KERNEL);
+	if (!outb) {
+		err = -ENOMEM;
+		goto out;
+	}
+	context = &outb->ctx;
+	err = mlx5_core_qp_query(&dev->mdev, &qp->mqp, outb, sizeof(*outb));
+	if (err)
+		goto out_free;
+
+	mlx5_state = be32_to_cpu(context->flags) >> 28;
+
+	qp->state		     = to_ib_qp_state(mlx5_state);
+	qp_attr->qp_state	     = qp->state;
+	qp_attr->path_mtu	     = context->mtu_msgmax >> 5;
+	qp_attr->path_mig_state	     =
+		to_ib_mig_state((be32_to_cpu(context->flags) >> 11) & 0x3);
+	qp_attr->qkey		     = be32_to_cpu(context->qkey);
+	qp_attr->rq_psn		     = be32_to_cpu(context->rnr_nextrecvpsn) & 0xffffff;
+	qp_attr->sq_psn		     = be32_to_cpu(context->next_send_psn) & 0xffffff;
+	qp_attr->dest_qp_num	     = be32_to_cpu(context->log_pg_sz_remote_qpn) & 0xffffff;
+	qp_attr->qp_access_flags     =
+		to_ib_qp_access_flags(be32_to_cpu(context->params2));
+
+	if (qp->ibqp.qp_type == IB_QPT_RC || qp->ibqp.qp_type == IB_QPT_UC) {
+		to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path);
+		to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path);
+		qp_attr->alt_pkey_index = context->alt_path.pkey_index & 0x7f;
+		qp_attr->alt_port_num	= qp_attr->alt_ah_attr.port_num;
+	}
+
+	qp_attr->pkey_index = context->pri_path.pkey_index & 0x7f;
+	qp_attr->port_num = context->pri_path.port;
+
+	/* qp_attr->en_sqd_async_notify is only applicable in modify qp */
+	qp_attr->sq_draining = mlx5_state == MLX5_QP_STATE_SQ_DRAINING;
+
+	qp_attr->max_rd_atomic = 1 << ((be32_to_cpu(context->params1) >> 21) & 0x7);
+
+	qp_attr->max_dest_rd_atomic =
+		1 << ((be32_to_cpu(context->params2) >> 21) & 0x7);
+	qp_attr->min_rnr_timer	    =
+		(be32_to_cpu(context->rnr_nextrecvpsn) >> 24) & 0x1f;
+	qp_attr->timeout	    = context->pri_path.ackto_lt >> 3;
+	qp_attr->retry_cnt	    = (be32_to_cpu(context->params1) >> 16) & 0x7;
+	qp_attr->rnr_retry	    = (be32_to_cpu(context->params1) >> 13) & 0x7;
+	qp_attr->alt_timeout	    = context->alt_path.ackto_lt >> 3;
+	qp_attr->cur_qp_state	     = qp_attr->qp_state;
+	qp_attr->cap.max_recv_wr     = qp->rq.wqe_cnt;
+	qp_attr->cap.max_recv_sge    = qp->rq.max_gs;
+
+	if (!ibqp->uobject) {
+		qp_attr->cap.max_send_wr  = qp->sq.wqe_cnt;
+		qp_attr->cap.max_send_sge = qp->sq.max_gs;
+	} else {
+		qp_attr->cap.max_send_wr  = 0;
+		qp_attr->cap.max_send_sge = 0;
+	}
+
+	/* We don't support inline sends for kernel QPs (yet), and we
+	 * don't know what userspace's value should be.
+	 */
+	qp_attr->cap.max_inline_data = 0;
+
+	qp_init_attr->cap	     = qp_attr->cap;
+
+	qp_init_attr->create_flags = 0;
+	if (qp->flags & MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK)
+		qp_init_attr->create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK;
+
+	qp_init_attr->sq_sig_type = qp->sq_signal_bits & MLX5_WQE_CTRL_CQ_UPDATE ?
+		IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
+
+out_free:
+	kfree(outb);
+
+out:
+	mutex_unlock(&qp->mutex);
+	return err;
+}
+
+struct ib_xrcd *mlx5_ib_alloc_xrcd(struct ib_device *ibdev,
+					  struct ib_ucontext *context,
+					  struct ib_udata *udata)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibdev);
+	struct mlx5_ib_xrcd *xrcd;
+	int err;
+
+	if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_XRC))
+		return ERR_PTR(-ENOSYS);
+
+	xrcd = kmalloc(sizeof(*xrcd), GFP_KERNEL);
+	if (!xrcd)
+		return ERR_PTR(-ENOMEM);
+
+	err = mlx5_core_xrcd_alloc(&dev->mdev, &xrcd->xrcdn);
+	if (err) {
+		kfree(xrcd);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return &xrcd->ibxrcd;
+}
+
+int mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd)
+{
+	struct mlx5_ib_dev *dev = to_mdev(xrcd->device);
+	u32 xrcdn = to_mxrcd(xrcd)->xrcdn;
+	int err;
+
+	err = mlx5_core_xrcd_dealloc(&dev->mdev, xrcdn);
+	if (err) {
+		mlx5_ib_warn(dev, "failed to dealloc xrcdn 0x%x\n", xrcdn);
+		return err;
+	}
+
+	kfree(xrcd);
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/srq.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/srq.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/srq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/srq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/mlx5/qp.h>
+#include <linux/mlx5/srq.h>
+#include <linux/slab.h>
+#include <rdma/ib_umem.h>
+
+#include "mlx5_ib.h"
+#include "user.h"
+
+/* not supported currently */
+static int srq_signature;
+
+static void *get_wqe(struct mlx5_ib_srq *srq, int n)
+{
+	return mlx5_buf_offset(&srq->buf, n << srq->msrq.wqe_shift);
+}
+
+static void mlx5_ib_srq_event(struct mlx5_core_srq *srq, enum mlx5_event type)
+{
+	struct ib_event event;
+	struct ib_srq *ibsrq = &to_mibsrq(srq)->ibsrq;
+
+	if (ibsrq->event_handler) {
+		event.device      = ibsrq->device;
+		event.element.srq = ibsrq;
+		switch (type) {
+		case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT:
+			event.event = IB_EVENT_SRQ_LIMIT_REACHED;
+			break;
+		case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
+			event.event = IB_EVENT_SRQ_ERR;
+			break;
+		default:
+			pr_warn("mlx5_ib: Unexpected event type %d on SRQ %06x\n",
+				type, srq->srqn);
+			return;
+		}
+
+		ibsrq->event_handler(&event, ibsrq->srq_context);
+	}
+}
+
+static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
+			   struct mlx5_create_srq_mbox_in **in,
+			   struct ib_udata *udata, int buf_size, int *inlen)
+{
+	struct mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct mlx5_ib_create_srq ucmd;
+	int err;
+	int npages;
+	int page_shift;
+	int ncont;
+	u32 offset;
+
+	if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
+		mlx5_ib_dbg(dev, "failed copy udata\n");
+		return -EFAULT;
+	}
+	srq->wq_sig = !!(ucmd.flags & MLX5_SRQ_FLAG_SIGNATURE);
+
+	srq->umem = ib_umem_get(pd->uobject->context, ucmd.buf_addr, buf_size,
+				0, 0);
+	if (IS_ERR(srq->umem)) {
+		mlx5_ib_dbg(dev, "failed umem get, size %d\n", buf_size);
+		err = PTR_ERR(srq->umem);
+		return err;
+	}
+
+	mlx5_ib_cont_pages(srq->umem, ucmd.buf_addr, &npages,
+			   &page_shift, &ncont, NULL);
+	err = mlx5_ib_get_buf_offset(ucmd.buf_addr, page_shift,
+				     &offset);
+	if (err) {
+		mlx5_ib_warn(dev, "bad offset\n");
+		goto err_umem;
+	}
+
+	*inlen = sizeof(**in) + sizeof(*(*in)->pas) * ncont;
+	*in = mlx5_vzalloc(*inlen);
+	if (!(*in)) {
+		err = -ENOMEM;
+		goto err_umem;
+	}
+
+	mlx5_ib_populate_pas(dev, srq->umem, page_shift, (*in)->pas, 0);
+
+	err = mlx5_ib_db_map_user(to_mucontext(pd->uobject->context),
+				  ucmd.db_addr, &srq->db);
+	if (err) {
+		mlx5_ib_dbg(dev, "map doorbell failed\n");
+		goto err_in;
+	}
+
+	(*in)->ctx.log_pg_sz = page_shift - PAGE_SHIFT;
+	(*in)->ctx.pgoff_cqn = cpu_to_be32(offset << 26);
+
+	return 0;
+
+err_in:
+	mlx5_vfree(*in);
+
+err_umem:
+	ib_umem_release(srq->umem);
+
+	return err;
+}
+
+static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
+			     struct mlx5_create_srq_mbox_in **in, int buf_size,
+			     int *inlen)
+{
+	int err;
+	int i;
+	struct mlx5_wqe_srq_next_seg *next;
+	int page_shift;
+	int npages;
+
+	err = mlx5_db_alloc(&dev->mdev, &srq->db);
+	if (err) {
+		mlx5_ib_warn(dev, "alloc dbell rec failed\n");
+		return err;
+	}
+
+	*srq->db.db = 0;
+
+	if (mlx5_buf_alloc(&dev->mdev, buf_size, PAGE_SIZE * 2, &srq->buf)) {
+		mlx5_ib_dbg(dev, "buf alloc failed\n");
+		err = -ENOMEM;
+		goto err_db;
+	}
+	page_shift = srq->buf.page_shift;
+
+	srq->head    = 0;
+	srq->tail    = srq->msrq.max - 1;
+	srq->wqe_ctr = 0;
+
+	for (i = 0; i < srq->msrq.max; i++) {
+		next = get_wqe(srq, i);
+		next->next_wqe_index =
+			cpu_to_be16((i + 1) & (srq->msrq.max - 1));
+	}
+
+	npages = DIV_ROUND_UP(srq->buf.npages, 1 << (page_shift - PAGE_SHIFT));
+	mlx5_ib_dbg(dev, "buf_size %d, page_shift %d, npages %d, calc npages %d\n",
+		    buf_size, page_shift, srq->buf.npages, npages);
+	*inlen = sizeof(**in) + sizeof(*(*in)->pas) * npages;
+	*in = mlx5_vzalloc(*inlen);
+	if (!*in) {
+		err = -ENOMEM;
+		goto err_buf;
+	}
+	mlx5_fill_page_array(&srq->buf, (*in)->pas);
+
+	srq->wrid = kmalloc(srq->msrq.max * sizeof(u64), GFP_KERNEL);
+	if (!srq->wrid) {
+		mlx5_ib_dbg(dev, "kmalloc failed %lu\n",
+			    (unsigned long)(srq->msrq.max * sizeof(u64)));
+		err = -ENOMEM;
+		goto err_in;
+	}
+	srq->wq_sig = !!srq_signature;
+
+	(*in)->ctx.log_pg_sz = page_shift - PAGE_SHIFT;
+
+	return 0;
+
+err_in:
+	mlx5_vfree(*in);
+
+err_buf:
+	mlx5_buf_free(&dev->mdev, &srq->buf);
+
+err_db:
+	mlx5_db_free(&dev->mdev, &srq->db);
+	return err;
+}
+
+static void destroy_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq)
+{
+	mlx5_ib_db_unmap_user(to_mucontext(pd->uobject->context), &srq->db);
+	ib_umem_release(srq->umem);
+}
+
+
+static void destroy_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq)
+{
+	kfree(srq->wrid);
+	mlx5_buf_free(&dev->mdev, &srq->buf);
+	mlx5_db_free(&dev->mdev, &srq->db);
+}
+
+struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
+				  struct ib_srq_init_attr *init_attr,
+				  struct ib_udata *udata)
+{
+	struct mlx5_ib_dev *dev = to_mdev(pd->device);
+	struct mlx5_ib_srq *srq;
+	int desc_size;
+	int buf_size;
+	int err;
+	struct mlx5_create_srq_mbox_in *uninitialized_var(in);
+	int uninitialized_var(inlen);
+	int is_xrc;
+	u32 flgs, xrcdn;
+
+	/* Sanity check SRQ size before proceeding */
+	if (init_attr->attr.max_wr >= dev->mdev.caps.max_srq_wqes) {
+		mlx5_ib_dbg(dev, "max_wr %d, cap %d\n",
+			    init_attr->attr.max_wr,
+			    dev->mdev.caps.max_srq_wqes);
+		return ERR_PTR(-EINVAL);
+	}
+
+	srq = kmalloc(sizeof(*srq), GFP_KERNEL);
+	if (!srq)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&srq->mutex);
+	spin_lock_init(&srq->lock);
+	srq->msrq.max    = roundup_pow_of_two(init_attr->attr.max_wr + 1);
+	srq->msrq.max_gs = init_attr->attr.max_sge;
+
+	desc_size = sizeof(struct mlx5_wqe_srq_next_seg) +
+		    srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg);
+	desc_size = roundup_pow_of_two(desc_size);
+	desc_size = max_t(int, 32, desc_size);
+	srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) /
+		sizeof(struct mlx5_wqe_data_seg);
+	srq->msrq.wqe_shift = ilog2(desc_size);
+	buf_size = srq->msrq.max * desc_size;
+	mlx5_ib_dbg(dev, "desc_size 0x%x, req wr 0x%x, srq size 0x%x, max_gs 0x%x, max_avail_gather 0x%x\n",
+		    desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs,
+		    srq->msrq.max_avail_gather);
+
+	if (pd->uobject)
+		err = create_srq_user(pd, srq, &in, udata, buf_size, &inlen);
+	else
+		err = create_srq_kernel(dev, srq, &in, buf_size, &inlen);
+
+	if (err) {
+		mlx5_ib_warn(dev, "create srq %s failed, err %d\n",
+			     pd->uobject ? "user" : "kernel", err);
+		goto err_srq;
+	}
+
+	is_xrc = (init_attr->srq_type == IB_SRQT_XRC);
+	in->ctx.state_log_sz = ilog2(srq->msrq.max);
+	flgs = ((srq->msrq.wqe_shift - 4) | (is_xrc << 5) | (srq->wq_sig << 7)) << 24;
+	xrcdn = 0;
+	if (is_xrc) {
+		xrcdn = to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn;
+		in->ctx.pgoff_cqn |= cpu_to_be32(to_mcq(init_attr->ext.xrc.cq)->mcq.cqn);
+	} else if (init_attr->srq_type == IB_SRQT_BASIC) {
+		xrcdn = to_mxrcd(dev->devr.x0)->xrcdn;
+		in->ctx.pgoff_cqn |= cpu_to_be32(to_mcq(dev->devr.c0)->mcq.cqn);
+	}
+
+	in->ctx.flags_xrcd = cpu_to_be32((flgs & 0xFF000000) | (xrcdn & 0xFFFFFF));
+
+	in->ctx.pd = cpu_to_be32(to_mpd(pd)->pdn);
+	in->ctx.db_record = cpu_to_be64(srq->db.dma);
+	err = mlx5_core_create_srq(&dev->mdev, &srq->msrq, in, inlen);
+	mlx5_vfree(in);
+	if (err) {
+		mlx5_ib_dbg(dev, "create SRQ failed, err %d\n", err);
+		goto err_srq;
+	}
+
+	mlx5_ib_dbg(dev, "create SRQ with srqn 0x%x\n", srq->msrq.srqn);
+
+	srq->msrq.event = mlx5_ib_srq_event;
+	srq->ibsrq.ext.xrc.srq_num = srq->msrq.srqn;
+
+	if (pd->uobject)
+		if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof(__u32))) {
+			mlx5_ib_dbg(dev, "copy to user failed\n");
+			err = -EFAULT;
+			goto err_core;
+		}
+
+	init_attr->attr.max_wr = srq->msrq.max - 1;
+
+	return &srq->ibsrq;
+
+err_core:
+	mlx5_core_destroy_srq(&dev->mdev, &srq->msrq);
+	if (pd->uobject)
+		destroy_srq_user(pd, srq);
+	else
+		destroy_srq_kernel(dev, srq);
+
+err_srq:
+	kfree(srq);
+
+	return ERR_PTR(err);
+}
+
+int mlx5_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
+		       enum ib_srq_attr_mask attr_mask, struct ib_udata *udata)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibsrq->device);
+	struct mlx5_ib_srq *srq = to_msrq(ibsrq);
+	int ret;
+
+	/* We don't support resizing SRQs yet */
+	if (attr_mask & IB_SRQ_MAX_WR)
+		return -EINVAL;
+
+	if (attr_mask & IB_SRQ_LIMIT) {
+		if (attr->srq_limit >= srq->msrq.max)
+			return -EINVAL;
+
+		mutex_lock(&srq->mutex);
+		ret = mlx5_core_arm_srq(&dev->mdev, &srq->msrq, attr->srq_limit, 1);
+		mutex_unlock(&srq->mutex);
+
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
+{
+	struct mlx5_ib_dev *dev = to_mdev(ibsrq->device);
+	struct mlx5_ib_srq *srq = to_msrq(ibsrq);
+	int ret;
+	struct mlx5_query_srq_mbox_out *out;
+
+	out = kzalloc(sizeof(*out), GFP_KERNEL);
+	if (!out)
+		return -ENOMEM;
+
+	ret = mlx5_core_query_srq(&dev->mdev, &srq->msrq, out);
+	if (ret)
+		goto out_box;
+
+	srq_attr->srq_limit = be16_to_cpu(out->ctx.lwm);
+	srq_attr->max_wr    = srq->msrq.max - 1;
+	srq_attr->max_sge   = srq->msrq.max_gs;
+
+out_box:
+	kfree(out);
+	return ret;
+}
+
+int mlx5_ib_destroy_srq(struct ib_srq *srq)
+{
+	struct mlx5_ib_dev *dev = to_mdev(srq->device);
+	struct mlx5_ib_srq *msrq = to_msrq(srq);
+
+	mlx5_core_destroy_srq(&dev->mdev, &msrq->msrq);
+
+	if (srq->uobject) {
+		mlx5_ib_db_unmap_user(to_mucontext(srq->uobject->context), &msrq->db);
+		ib_umem_release(msrq->umem);
+	} else {
+		kfree(msrq->wrid);
+		mlx5_buf_free(&dev->mdev, &msrq->buf);
+		mlx5_db_free(&dev->mdev, &msrq->db);
+	}
+
+	kfree(srq);
+	return 0;
+}
+
+void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index)
+{
+	struct mlx5_wqe_srq_next_seg *next;
+
+	/* always called with interrupts disabled. */
+	spin_lock(&srq->lock);
+
+	next = get_wqe(srq, srq->tail);
+	next->next_wqe_index = cpu_to_be16(wqe_index);
+	srq->tail = wqe_index;
+
+	spin_unlock(&srq->lock);
+}
+
+int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
+			  struct ib_recv_wr **bad_wr)
+{
+	struct mlx5_ib_srq *srq = to_msrq(ibsrq);
+	struct mlx5_wqe_srq_next_seg *next;
+	struct mlx5_wqe_data_seg *scat;
+	unsigned long flags;
+	int err = 0;
+	int nreq;
+	int i;
+
+	spin_lock_irqsave(&srq->lock, flags);
+
+	for (nreq = 0; wr; nreq++, wr = wr->next) {
+		if (unlikely(wr->num_sge > srq->msrq.max_gs)) {
+			err = -EINVAL;
+			*bad_wr = wr;
+			break;
+		}
+
+		if (unlikely(srq->head == srq->tail)) {
+			err = -ENOMEM;
+			*bad_wr = wr;
+			break;
+		}
+
+		srq->wrid[srq->head] = wr->wr_id;
+
+		next      = get_wqe(srq, srq->head);
+		srq->head = be16_to_cpu(next->next_wqe_index);
+		scat      = (struct mlx5_wqe_data_seg *)(next + 1);
+
+		for (i = 0; i < wr->num_sge; i++) {
+			scat[i].byte_count = cpu_to_be32(wr->sg_list[i].length);
+			scat[i].lkey       = cpu_to_be32(wr->sg_list[i].lkey);
+			scat[i].addr       = cpu_to_be64(wr->sg_list[i].addr);
+		}
+
+		if (i < srq->msrq.max_avail_gather) {
+			scat[i].byte_count = 0;
+			scat[i].lkey       = cpu_to_be32(MLX5_INVALID_LKEY);
+			scat[i].addr       = 0;
+		}
+	}
+
+	if (likely(nreq)) {
+		srq->wqe_ctr += nreq;
+
+		/* Make sure that descriptors are written before
+		 * doorbell record.
+		 */
+		wmb();
+
+		*srq->db.db = cpu_to_be32(srq->wqe_ctr);
+	}
+
+	spin_unlock_irqrestore(&srq->lock, flags);
+
+	return err;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/user.h linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/user.h
--- linux-libre-3.10-gnu/drivers/infiniband/hw/mlx5/user.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/mlx5/user.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 MLX5_IB_USER_H
+#define MLX5_IB_USER_H
+
+#include <linux/types.h>
+
+enum {
+	MLX5_QP_FLAG_SIGNATURE		= 1 << 0,
+	MLX5_QP_FLAG_SCATTER_CQE	= 1 << 1,
+};
+
+enum {
+	MLX5_SRQ_FLAG_SIGNATURE		= 1 << 0,
+};
+
+
+/* Increment this value if any changes that break userspace ABI
+ * compatibility are made.
+ */
+#define MLX5_IB_UVERBS_ABI_VERSION	1
+
+/* Make sure that all structs defined in this file remain laid out so
+ * that they pack the same way on 32-bit and 64-bit architectures (to
+ * avoid incompatibility between 32-bit userspace and 64-bit kernels).
+ * In particular do not use pointer types -- pass pointers in __u64
+ * instead.
+ */
+
+struct mlx5_ib_alloc_ucontext_req {
+	__u32	total_num_uuars;
+	__u32	num_low_latency_uuars;
+};
+
+struct mlx5_ib_alloc_ucontext_resp {
+	__u32	qp_tab_size;
+	__u32	bf_reg_size;
+	__u32	tot_uuars;
+	__u32	cache_line_size;
+	__u16	max_sq_desc_sz;
+	__u16	max_rq_desc_sz;
+	__u32	max_send_wqebb;
+	__u32	max_recv_wr;
+	__u32	max_srq_recv_wr;
+	__u16	num_ports;
+	__u16	reserved;
+};
+
+struct mlx5_ib_alloc_pd_resp {
+	__u32	pdn;
+};
+
+struct mlx5_ib_create_cq {
+	__u64	buf_addr;
+	__u64	db_addr;
+	__u32	cqe_size;
+};
+
+struct mlx5_ib_create_cq_resp {
+	__u32	cqn;
+	__u32	reserved;
+};
+
+struct mlx5_ib_resize_cq {
+	__u64	buf_addr;
+};
+
+struct mlx5_ib_create_srq {
+	__u64	buf_addr;
+	__u64	db_addr;
+	__u32	flags;
+};
+
+struct mlx5_ib_create_srq_resp {
+	__u32	srqn;
+	__u32	reserved;
+};
+
+struct mlx5_ib_create_qp {
+	__u64	buf_addr;
+	__u64	db_addr;
+	__u32	sq_wqe_count;
+	__u32	rq_wqe_count;
+	__u32	rq_wqe_shift;
+	__u32	flags;
+};
+
+struct mlx5_ib_create_qp_resp {
+	__u32	uuar_index;
+};
+#endif /* MLX5_IB_USER_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/nes/nes_hw.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/nes/nes_hw.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/nes/nes_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/nes/nes_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -3570,10 +3570,10 @@ static void nes_process_iwarp_aeqe(struc
 	tcp_state = (aeq_info & NES_AEQE_TCP_STATE_MASK) >> NES_AEQE_TCP_STATE_SHIFT;
 	iwarp_state = (aeq_info & NES_AEQE_IWARP_STATE_MASK) >> NES_AEQE_IWARP_STATE_SHIFT;
 	nes_debug(NES_DBG_AEQ, "aeid = 0x%04X, qp-cq id = %d, aeqe = %p,"
-			" Tcp state = %d, iWARP state = %d\n",
+			" Tcp state = %s, iWARP state = %s\n",
 			async_event_id,
 			le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe,
-			tcp_state, iwarp_state);
+			nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]);
 
 	aeqe_cq_id = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]);
 	if (aeq_info & NES_AEQE_QP) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/nes/nes_verbs.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/nes/nes_verbs.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/nes/nes_verbs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/nes/nes_verbs.c	2013-08-25 20:43:22.000000000 -0400
@@ -1384,6 +1384,7 @@ static struct ib_qp *nes_create_qp(struc
 
 			if (ibpd->uobject) {
 				uresp.mmap_sq_db_index = nesqp->mmap_sq_db_index;
+				uresp.mmap_rq_db_index = 0;
 				uresp.actual_sq_size = sq_size;
 				uresp.actual_rq_size = rq_size;
 				uresp.qp_id = nesqp->hwqp.qp_id;
@@ -1767,7 +1768,7 @@ static struct ib_cq *nes_create_cq(struc
 		resp.cq_id = nescq->hw_cq.cq_number;
 		resp.cq_size = nescq->hw_cq.cq_size;
 		resp.mmap_db_index = 0;
-		if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
+		if (ib_copy_to_udata(udata, &resp, sizeof resp - sizeof resp.reserved)) {
 			nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
 			kfree(nescq);
 			return ERR_PTR(-EFAULT);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_ah.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_ah.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_ah.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
 #include <net/netevent.h>
 
 #include <rdma/ib_addr.h>
-#include <rdma/ib_cache.h>
 
 #include "ocrdma.h"
 #include "ocrdma_verbs.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma.h linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma.h
--- linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma.h	2013-08-25 20:43:22.000000000 -0400
@@ -42,8 +42,6 @@
 #define OCRDMA_ROCE_DEV_VERSION "1.0.0"
 #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"
 
-#define ocrdma_err(format, arg...) printk(KERN_ERR format, ##arg)
-
 #define OCRDMA_MAX_AH 512
 
 #define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME)
@@ -97,7 +95,6 @@ struct ocrdma_queue_info {
 	u16 id;			/* qid, where to ring the doorbell. */
 	u16 head, tail;
 	bool created;
-	atomic_t used;		/* Number of valid elements in the queue */
 };
 
 struct ocrdma_eq {
@@ -198,7 +195,6 @@ struct ocrdma_cq {
 	struct ocrdma_ucontext *ucontext;
 	dma_addr_t pa;
 	u32 len;
-	atomic_t use_cnt;
 
 	/* head of all qp's sq and rq for which cqes need to be flushed
 	 * by the software.
@@ -210,7 +206,6 @@ struct ocrdma_pd {
 	struct ib_pd ibpd;
 	struct ocrdma_dev *dev;
 	struct ocrdma_ucontext *uctx;
-	atomic_t use_cnt;
 	u32 id;
 	int num_dpp_qp;
 	u32 dpp_page;
@@ -241,16 +236,16 @@ struct ocrdma_srq {
 	struct ib_srq ibsrq;
 	struct ocrdma_dev *dev;
 	u8 __iomem *db;
+	struct ocrdma_qp_hwq_info rq;
+	u64 *rqe_wr_id_tbl;
+	u32 *idx_bit_fields;
+	u32 bit_fields_len;
+
 	/* provide synchronization to multiple context(s) posting rqe */
 	spinlock_t q_lock ____cacheline_aligned;
 
-	struct ocrdma_qp_hwq_info rq;
 	struct ocrdma_pd *pd;
-	atomic_t use_cnt;
 	u32 id;
-	u64 *rqe_wr_id_tbl;
-	u32 *idx_bit_fields;
-	u32 bit_fields_len;
 };
 
 struct ocrdma_qp {
@@ -258,8 +253,6 @@ struct ocrdma_qp {
 	struct ocrdma_dev *dev;
 
 	u8 __iomem *sq_db;
-	/* provide synchronization to multiple context(s) posting wqe, rqe */
-	spinlock_t q_lock ____cacheline_aligned;
 	struct ocrdma_qp_hwq_info sq;
 	struct {
 		uint64_t wrid;
@@ -269,6 +262,9 @@ struct ocrdma_qp {
 		uint8_t  rsvd[3];
 	} *wqe_wr_id_tbl;
 	u32 max_inline_data;
+
+	/* provide synchronization to multiple context(s) posting wqe, rqe */
+	spinlock_t q_lock ____cacheline_aligned;
 	struct ocrdma_cq *sq_cq;
 	/* list maintained per CQ to flush SQ errors */
 	struct list_head sq_entry;
@@ -296,10 +292,6 @@ struct ocrdma_qp {
 	u8 *ird_q_va;
 };
 
-#define OCRDMA_GET_NUM_POSTED_SHIFT_VAL(qp) \
-	(((qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) && \
-		(qp->id < 64)) ? 24 : 16)
-
 struct ocrdma_hw_mr {
 	struct ocrdma_dev *dev;
 	u32 lkey;
@@ -390,4 +382,43 @@ static inline struct ocrdma_srq *get_ocr
 	return container_of(ibsrq, struct ocrdma_srq, ibsrq);
 }
 
+
+static inline int ocrdma_get_num_posted_shift(struct ocrdma_qp *qp)
+{
+	return ((qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY &&
+		 qp->id < 64) ? 24 : 16);
+}
+
+static inline int is_cqe_valid(struct ocrdma_cq *cq, struct ocrdma_cqe *cqe)
+{
+	int cqe_valid;
+	cqe_valid = le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_VALID;
+	return ((cqe_valid == cq->phase) ? 1 : 0);
+}
+
+static inline int is_cqe_for_sq(struct ocrdma_cqe *cqe)
+{
+	return (le32_to_cpu(cqe->flags_status_srcqpn) &
+		OCRDMA_CQE_QTYPE) ? 0 : 1;
+}
+
+static inline int is_cqe_invalidated(struct ocrdma_cqe *cqe)
+{
+	return (le32_to_cpu(cqe->flags_status_srcqpn) &
+		OCRDMA_CQE_INVALIDATE) ? 1 : 0;
+}
+
+static inline int is_cqe_imm(struct ocrdma_cqe *cqe)
+{
+	return (le32_to_cpu(cqe->flags_status_srcqpn) &
+		OCRDMA_CQE_IMM) ? 1 : 0;
+}
+
+static inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe)
+{
+	return (le32_to_cpu(cqe->flags_status_srcqpn) &
+		OCRDMA_CQE_WRITE_IMM) ? 1 : 0;
+}
+
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_hw.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_hw.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,7 +128,6 @@ static inline struct ocrdma_mqe *ocrdma_
 static inline void ocrdma_mq_inc_head(struct ocrdma_dev *dev)
 {
 	dev->mq.sq.head = (dev->mq.sq.head + 1) & (OCRDMA_MQ_LEN - 1);
-	atomic_inc(&dev->mq.sq.used);
 }
 
 static inline void *ocrdma_get_mqe_rsp(struct ocrdma_dev *dev)
@@ -564,32 +563,19 @@ static int ocrdma_mbx_create_mq(struct o
 	memset(cmd, 0, sizeof(*cmd));
 	num_pages = PAGES_4K_SPANNED(mq->va, mq->size);
 
-	if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) {
-		ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_MQ,
-				OCRDMA_SUBSYS_COMMON, sizeof(*cmd));
-		cmd->v0.pages = num_pages;
-		cmd->v0.async_cqid_valid = OCRDMA_CREATE_MQ_ASYNC_CQ_VALID;
-		cmd->v0.async_cqid_valid = (cq->id << 1);
-		cmd->v0.cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) <<
-					     OCRDMA_CREATE_MQ_RING_SIZE_SHIFT);
-		cmd->v0.cqid_ringsize |=
-			(cq->id << OCRDMA_CREATE_MQ_V0_CQ_ID_SHIFT);
-		cmd->v0.valid = OCRDMA_CREATE_MQ_VALID;
-		pa = &cmd->v0.pa[0];
-	} else {
-		ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_MQ_EXT,
-				OCRDMA_SUBSYS_COMMON, sizeof(*cmd));
-		cmd->req.rsvd_version = 1;
-		cmd->v1.cqid_pages = num_pages;
-		cmd->v1.cqid_pages |= (cq->id << OCRDMA_CREATE_MQ_CQ_ID_SHIFT);
-		cmd->v1.async_cqid_valid = OCRDMA_CREATE_MQ_ASYNC_CQ_VALID;
-		cmd->v1.async_event_bitmap = Bit(20);
-		cmd->v1.async_cqid_ringsize = cq->id;
-		cmd->v1.async_cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) <<
-					     OCRDMA_CREATE_MQ_RING_SIZE_SHIFT);
-		cmd->v1.valid = OCRDMA_CREATE_MQ_VALID;
-		pa = &cmd->v1.pa[0];
-	}
+	ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_MQ_EXT,
+			OCRDMA_SUBSYS_COMMON, sizeof(*cmd));
+	cmd->req.rsvd_version = 1;
+	cmd->cqid_pages = num_pages;
+	cmd->cqid_pages |= (cq->id << OCRDMA_CREATE_MQ_CQ_ID_SHIFT);
+	cmd->async_cqid_valid = OCRDMA_CREATE_MQ_ASYNC_CQ_VALID;
+	cmd->async_event_bitmap = Bit(20);
+	cmd->async_cqid_ringsize = cq->id;
+	cmd->async_cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) <<
+				OCRDMA_CREATE_MQ_RING_SIZE_SHIFT);
+	cmd->valid = OCRDMA_CREATE_MQ_VALID;
+	pa = &cmd->pa[0];
+
 	ocrdma_build_q_pages(pa, num_pages, mq->dma, PAGE_SIZE_4K);
 	status = be_roce_mcc_cmd(dev->nic_info.netdev,
 				 cmd, sizeof(*cmd), NULL, NULL);
@@ -745,7 +731,7 @@ static void ocrdma_dispatch_ibevent(stru
 		qp_event = 0;
 		srq_event = 0;
 		dev_event = 0;
-		ocrdma_err("%s() unknown type=0x%x\n", __func__, type);
+		pr_err("%s() unknown type=0x%x\n", __func__, type);
 		break;
 	}
 
@@ -775,8 +761,8 @@ static void ocrdma_process_acqe(struct o
 	if (evt_code == OCRDMA_ASYNC_EVE_CODE)
 		ocrdma_dispatch_ibevent(dev, cqe);
 	else
-		ocrdma_err("%s(%d) invalid evt code=0x%x\n",
-			   __func__, dev->id, evt_code);
+		pr_err("%s(%d) invalid evt code=0x%x\n", __func__,
+		       dev->id, evt_code);
 }
 
 static void ocrdma_process_mcqe(struct ocrdma_dev *dev, struct ocrdma_mcqe *cqe)
@@ -790,8 +776,8 @@ static void ocrdma_process_mcqe(struct o
 		dev->mqe_ctx.cmd_done = true;
 		wake_up(&dev->mqe_ctx.cmd_wait);
 	} else
-		ocrdma_err("%s() cqe for invalid tag0x%x.expected=0x%x\n",
-			   __func__, cqe->tag_lo, dev->mqe_ctx.tag);
+		pr_err("%s() cqe for invalid tag0x%x.expected=0x%x\n",
+		       __func__, cqe->tag_lo, dev->mqe_ctx.tag);
 }
 
 static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id)
@@ -810,7 +796,7 @@ static int ocrdma_mq_cq_handler(struct o
 		else if (cqe->valid_ae_cmpl_cons & OCRDMA_MCQE_CMPL_MASK)
 			ocrdma_process_mcqe(dev, cqe);
 		else
-			ocrdma_err("%s() cqe->compl is not set.\n", __func__);
+			pr_err("%s() cqe->compl is not set.\n", __func__);
 		memset(cqe, 0, sizeof(struct ocrdma_mcqe));
 		ocrdma_mcq_inc_tail(dev);
 	}
@@ -869,7 +855,7 @@ static void ocrdma_qp_cq_handler(struct
 
 	cq = dev->cq_tbl[cq_idx];
 	if (cq == NULL) {
-		ocrdma_err("%s%d invalid id=0x%x\n", __func__, dev->id, cq_idx);
+		pr_err("%s%d invalid id=0x%x\n", __func__, dev->id, cq_idx);
 		return;
 	}
 	spin_lock_irqsave(&cq->cq_lock, flags);
@@ -971,7 +957,7 @@ static int ocrdma_mbx_cmd(struct ocrdma_
 	rsp = ocrdma_get_mqe_rsp(dev);
 	ocrdma_copy_le32_to_cpu(mqe, rsp, (sizeof(*mqe)));
 	if (cqe_status || ext_status) {
-		ocrdma_err
+		pr_err
 		    ("%s() opcode=0x%x, cqe_status=0x%x, ext_status=0x%x\n",
 		     __func__,
 		     (rsp->u.rsp.subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >>
@@ -1353,8 +1339,8 @@ int ocrdma_mbx_create_cq(struct ocrdma_d
 	if (dpp_cq)
 		return -EINVAL;
 	if (entries > dev->attr.max_cqe) {
-		ocrdma_err("%s(%d) max_cqe=0x%x, requester_cqe=0x%x\n",
-			   __func__, dev->id, dev->attr.max_cqe, entries);
+		pr_err("%s(%d) max_cqe=0x%x, requester_cqe=0x%x\n",
+		       __func__, dev->id, dev->attr.max_cqe, entries);
 		return -EINVAL;
 	}
 	if (dpp_cq && (dev->nic_info.dev_family != OCRDMA_GEN2_FAMILY))
@@ -1621,7 +1607,7 @@ int ocrdma_reg_mr(struct ocrdma_dev *dev
 	status = ocrdma_mbx_reg_mr(dev, hwmr, pdid,
 				   cur_pbl_cnt, hwmr->pbe_size, last);
 	if (status) {
-		ocrdma_err("%s() status=%d\n", __func__, status);
+		pr_err("%s() status=%d\n", __func__, status);
 		return status;
 	}
 	/* if there is no more pbls to register then exit. */
@@ -1644,7 +1630,7 @@ int ocrdma_reg_mr(struct ocrdma_dev *dev
 			break;
 	}
 	if (status)
-		ocrdma_err("%s() err. status=%d\n", __func__, status);
+		pr_err("%s() err. status=%d\n", __func__, status);
 
 	return status;
 }
@@ -1841,8 +1827,8 @@ static int ocrdma_set_create_qp_sq_cmd(s
 	status = ocrdma_build_q_conf(&max_wqe_allocated,
 		dev->attr.wqe_size, &hw_pages, &hw_page_size);
 	if (status) {
-		ocrdma_err("%s() req. max_send_wr=0x%x\n", __func__,
-			   max_wqe_allocated);
+		pr_err("%s() req. max_send_wr=0x%x\n", __func__,
+		       max_wqe_allocated);
 		return -EINVAL;
 	}
 	qp->sq.max_cnt = max_wqe_allocated;
@@ -1891,8 +1877,8 @@ static int ocrdma_set_create_qp_rq_cmd(s
 	status = ocrdma_build_q_conf(&max_rqe_allocated, dev->attr.rqe_size,
 				     &hw_pages, &hw_page_size);
 	if (status) {
-		ocrdma_err("%s() req. max_recv_wr=0x%x\n", __func__,
-			   attrs->cap.max_recv_wr + 1);
+		pr_err("%s() req. max_recv_wr=0x%x\n", __func__,
+		       attrs->cap.max_recv_wr + 1);
 		return status;
 	}
 	qp->rq.max_cnt = max_rqe_allocated;
@@ -1900,7 +1886,7 @@ static int ocrdma_set_create_qp_rq_cmd(s
 
 	qp->rq.va = dma_alloc_coherent(&pdev->dev, len, &pa, GFP_KERNEL);
 	if (!qp->rq.va)
-		return status;
+		return -ENOMEM;
 	memset(qp->rq.va, 0, len);
 	qp->rq.pa = pa;
 	qp->rq.len = len;
@@ -2087,10 +2073,10 @@ mbx_err:
 	if (qp->rq.va)
 		dma_free_coherent(&pdev->dev, qp->rq.len, qp->rq.va, qp->rq.pa);
 rq_err:
-	ocrdma_err("%s(%d) rq_err\n", __func__, dev->id);
+	pr_err("%s(%d) rq_err\n", __func__, dev->id);
 	dma_free_coherent(&pdev->dev, qp->sq.len, qp->sq.va, qp->sq.pa);
 sq_err:
-	ocrdma_err("%s(%d) sq_err\n", __func__, dev->id);
+	pr_err("%s(%d) sq_err\n", __func__, dev->id);
 	kfree(cmd);
 	return status;
 }
@@ -2127,7 +2113,7 @@ int ocrdma_resolve_dgid(struct ocrdma_de
 	else if (rdma_link_local_addr(&in6))
 		rdma_get_ll_mac(&in6, mac_addr);
 	else {
-		ocrdma_err("%s() fail to resolve mac_addr.\n", __func__);
+		pr_err("%s() fail to resolve mac_addr.\n", __func__);
 		return -EINVAL;
 	}
 	return 0;
@@ -2362,8 +2348,8 @@ int ocrdma_mbx_create_srq(struct ocrdma_
 				dev->attr.rqe_size,
 				&hw_pages, &hw_page_size);
 	if (status) {
-		ocrdma_err("%s() req. max_wr=0x%x\n", __func__,
-			   srq_attr->attr.max_wr);
+		pr_err("%s() req. max_wr=0x%x\n", __func__,
+		       srq_attr->attr.max_wr);
 		status = -EINVAL;
 		goto ret;
 	}
@@ -2614,7 +2600,7 @@ mq_err:
 	ocrdma_destroy_qp_eqs(dev);
 qpeq_err:
 	ocrdma_destroy_eq(dev, &dev->meq);
-	ocrdma_err("%s() status=%d\n", __func__, status);
+	pr_err("%s() status=%d\n", __func__, status);
 	return status;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_main.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_main.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -378,7 +378,7 @@ static int ocrdma_alloc_resources(struct
 	spin_lock_init(&dev->flush_q_lock);
 	return 0;
 alloc_err:
-	ocrdma_err("%s(%d) error.\n", __func__, dev->id);
+	pr_err("%s(%d) error.\n", __func__, dev->id);
 	return -ENOMEM;
 }
 
@@ -396,7 +396,7 @@ static struct ocrdma_dev *ocrdma_add(str
 
 	dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev));
 	if (!dev) {
-		ocrdma_err("Unable to allocate ib device\n");
+		pr_err("Unable to allocate ib device\n");
 		return NULL;
 	}
 	dev->mbx_cmd = kzalloc(sizeof(struct ocrdma_mqe_emb_cmd), GFP_KERNEL);
@@ -437,7 +437,7 @@ init_err:
 idr_err:
 	kfree(dev->mbx_cmd);
 	ib_dealloc_device(&dev->ibdev);
-	ocrdma_err("%s() leaving. ret=%d\n", __func__, status);
+	pr_err("%s() leaving. ret=%d\n", __func__, status);
 	return NULL;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_sli.h linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_sli.h
--- linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_sli.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_sli.h	2013-08-25 20:43:22.000000000 -0400
@@ -608,16 +608,8 @@ enum {
 	OCRDMA_CREATE_MQ_ASYNC_CQ_VALID		= Bit(0)
 };
 
-struct ocrdma_create_mq_v0 {
-	u32 pages;
-	u32 cqid_ringsize;
-	u32 valid;
-	u32 async_cqid_valid;
-	u32 rsvd;
-	struct ocrdma_pa pa[8];
-} __packed;
-
-struct ocrdma_create_mq_v1 {
+struct ocrdma_create_mq_req {
+	struct ocrdma_mbx_hdr req;
 	u32 cqid_pages;
 	u32 async_event_bitmap;
 	u32 async_cqid_ringsize;
@@ -627,14 +619,6 @@ struct ocrdma_create_mq_v1 {
 	struct ocrdma_pa pa[8];
 } __packed;
 
-struct ocrdma_create_mq_req {
-	struct ocrdma_mbx_hdr req;
-	union {
-		struct ocrdma_create_mq_v0 v0;
-		struct ocrdma_create_mq_v1 v1;
-	};
-} __packed;
-
 struct ocrdma_create_mq_rsp {
 	struct ocrdma_mbx_rsp rsp;
 	u32 id;
@@ -1550,21 +1534,6 @@ struct ocrdma_cqe {
 	u32 flags_status_srcqpn;	/* w3 */
 } __packed;
 
-#define is_cqe_valid(cq, cqe) \
-	(((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_VALID)\
-	== cq->phase) ? 1 : 0)
-#define is_cqe_for_sq(cqe) \
-	((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_QTYPE) ? 0 : 1)
-#define is_cqe_for_rq(cqe) \
-	((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_QTYPE) ? 1 : 0)
-#define is_cqe_invalidated(cqe) \
-	((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_INVALIDATE) ? \
-	1 : 0)
-#define is_cqe_imm(cqe) \
-	((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_IMM) ? 1 : 0)
-#define is_cqe_wr_imm(cqe) \
-	((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_WRITE_IMM) ? 1 : 0)
-
 struct ocrdma_sge {
 	u32 addr_hi;
 	u32 addr_lo;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c	2013-08-25 20:43:22.000000000 -0400
@@ -114,8 +114,8 @@ int ocrdma_query_port(struct ib_device *
 
 	dev = get_ocrdma_dev(ibdev);
 	if (port > 1) {
-		ocrdma_err("%s(%d) invalid_port=0x%x\n", __func__,
-			   dev->id, port);
+		pr_err("%s(%d) invalid_port=0x%x\n", __func__,
+		       dev->id, port);
 		return -EINVAL;
 	}
 	netdev = dev->nic_info.netdev;
@@ -155,8 +155,7 @@ int ocrdma_modify_port(struct ib_device
 
 	dev = get_ocrdma_dev(ibdev);
 	if (port > 1) {
-		ocrdma_err("%s(%d) invalid_port=0x%x\n", __func__,
-			   dev->id, port);
+		pr_err("%s(%d) invalid_port=0x%x\n", __func__, dev->id, port);
 		return -EINVAL;
 	}
 	return 0;
@@ -243,6 +242,7 @@ struct ib_ucontext *ocrdma_alloc_ucontex
 	memset(ctx->ah_tbl.va, 0, map_len);
 	ctx->ah_tbl.len = map_len;
 
+	memset(&resp, 0, sizeof(resp));
 	resp.ah_tbl_len = ctx->ah_tbl.len;
 	resp.ah_tbl_page = ctx->ah_tbl.pa;
 
@@ -254,7 +254,6 @@ struct ib_ucontext *ocrdma_alloc_ucontex
 	resp.wqe_size = dev->attr.wqe_size;
 	resp.rqe_size = dev->attr.rqe_size;
 	resp.dpp_wqe_size = dev->attr.wqe_size;
-	resp.rsvd = 0;
 
 	memcpy(resp.fw_ver, dev->attr.fw_ver, sizeof(resp.fw_ver));
 	status = ib_copy_to_udata(udata, &resp, sizeof(resp));
@@ -339,6 +338,7 @@ static int ocrdma_copy_pd_uresp(struct o
 	struct ocrdma_alloc_pd_uresp rsp;
 	struct ocrdma_ucontext *uctx = get_ocrdma_ucontext(ib_ctx);
 
+	memset(&rsp, 0, sizeof(rsp));
 	rsp.id = pd->id;
 	rsp.dpp_enabled = pd->dpp_enabled;
 	db_page_addr = pd->dev->nic_info.unmapped_db +
@@ -398,7 +398,6 @@ struct ib_pd *ocrdma_alloc_pd(struct ib_
 		kfree(pd);
 		return ERR_PTR(status);
 	}
-	atomic_set(&pd->use_cnt, 0);
 
 	if (udata && context) {
 		status = ocrdma_copy_pd_uresp(pd, context, udata);
@@ -419,12 +418,6 @@ int ocrdma_dealloc_pd(struct ib_pd *ibpd
 	int status;
 	u64 usr_db;
 
-	if (atomic_read(&pd->use_cnt)) {
-		ocrdma_err("%s(%d) pd=0x%x is in use.\n",
-			   __func__, dev->id, pd->id);
-		status = -EFAULT;
-		goto dealloc_err;
-	}
 	status = ocrdma_mbx_dealloc_pd(dev, pd);
 	if (pd->uctx) {
 		u64 dpp_db = dev->nic_info.dpp_unmapped_addr +
@@ -436,7 +429,6 @@ int ocrdma_dealloc_pd(struct ib_pd *ibpd
 		ocrdma_del_mmap(pd->uctx, usr_db, dev->nic_info.db_page_size);
 	}
 	kfree(pd);
-dealloc_err:
 	return status;
 }
 
@@ -450,8 +442,8 @@ static struct ocrdma_mr *ocrdma_alloc_lk
 	struct ocrdma_dev *dev = pd->dev;
 
 	if (acc & IB_ACCESS_REMOTE_WRITE && !(acc & IB_ACCESS_LOCAL_WRITE)) {
-		ocrdma_err("%s(%d) leaving err, invalid access rights\n",
-			   __func__, dev->id);
+		pr_err("%s(%d) leaving err, invalid access rights\n",
+		       __func__, dev->id);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -474,7 +466,6 @@ static struct ocrdma_mr *ocrdma_alloc_lk
 		return ERR_PTR(-ENOMEM);
 	}
 	mr->pd = pd;
-	atomic_inc(&pd->use_cnt);
 	mr->ibmr.lkey = mr->hwmr.lkey;
 	if (mr->hwmr.remote_wr || mr->hwmr.remote_rd)
 		mr->ibmr.rkey = mr->hwmr.lkey;
@@ -664,7 +655,6 @@ struct ib_mr *ocrdma_reg_user_mr(struct
 	if (status)
 		goto mbx_err;
 	mr->pd = pd;
-	atomic_inc(&pd->use_cnt);
 	mr->ibmr.lkey = mr->hwmr.lkey;
 	if (mr->hwmr.remote_wr || mr->hwmr.remote_rd)
 		mr->ibmr.rkey = mr->hwmr.lkey;
@@ -689,7 +679,6 @@ int ocrdma_dereg_mr(struct ib_mr *ib_mr)
 	if (mr->hwmr.fr_mr == 0)
 		ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr);
 
-	atomic_dec(&mr->pd->use_cnt);
 	/* it could be user registered memory. */
 	if (mr->umem)
 		ib_umem_release(mr->umem);
@@ -704,6 +693,7 @@ static int ocrdma_copy_cq_uresp(struct o
 	struct ocrdma_ucontext *uctx;
 	struct ocrdma_create_cq_uresp uresp;
 
+	memset(&uresp, 0, sizeof(uresp));
 	uresp.cq_id = cq->id;
 	uresp.page_size = cq->len;
 	uresp.num_pages = 1;
@@ -714,8 +704,8 @@ static int ocrdma_copy_cq_uresp(struct o
 	uresp.phase_change = cq->phase_change ? 1 : 0;
 	status = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
 	if (status) {
-		ocrdma_err("%s(%d) copy error cqid=0x%x.\n",
-			   __func__, cq->dev->id, cq->id);
+		pr_err("%s(%d) copy error cqid=0x%x.\n",
+		       __func__, cq->dev->id, cq->id);
 		goto err;
 	}
 	uctx = get_ocrdma_ucontext(ib_ctx);
@@ -752,7 +742,6 @@ struct ib_cq *ocrdma_create_cq(struct ib
 
 	spin_lock_init(&cq->cq_lock);
 	spin_lock_init(&cq->comp_handler_lock);
-	atomic_set(&cq->use_cnt, 0);
 	INIT_LIST_HEAD(&cq->sq_head);
 	INIT_LIST_HEAD(&cq->rq_head);
 	cq->dev = dev;
@@ -799,9 +788,6 @@ int ocrdma_destroy_cq(struct ib_cq *ibcq
 	struct ocrdma_cq *cq = get_ocrdma_cq(ibcq);
 	struct ocrdma_dev *dev = cq->dev;
 
-	if (atomic_read(&cq->use_cnt))
-		return -EINVAL;
-
 	status = ocrdma_mbx_destroy_cq(dev, cq);
 
 	if (cq->ucontext) {
@@ -837,57 +823,56 @@ static int ocrdma_check_qp_params(struct
 	if (attrs->qp_type != IB_QPT_GSI &&
 	    attrs->qp_type != IB_QPT_RC &&
 	    attrs->qp_type != IB_QPT_UD) {
-		ocrdma_err("%s(%d) unsupported qp type=0x%x requested\n",
-			   __func__, dev->id, attrs->qp_type);
+		pr_err("%s(%d) unsupported qp type=0x%x requested\n",
+		       __func__, dev->id, attrs->qp_type);
 		return -EINVAL;
 	}
 	if (attrs->cap.max_send_wr > dev->attr.max_wqe) {
-		ocrdma_err("%s(%d) unsupported send_wr=0x%x requested\n",
-			   __func__, dev->id, attrs->cap.max_send_wr);
-		ocrdma_err("%s(%d) supported send_wr=0x%x\n",
-			   __func__, dev->id, dev->attr.max_wqe);
+		pr_err("%s(%d) unsupported send_wr=0x%x requested\n",
+		       __func__, dev->id, attrs->cap.max_send_wr);
+		pr_err("%s(%d) supported send_wr=0x%x\n",
+		       __func__, dev->id, dev->attr.max_wqe);
 		return -EINVAL;
 	}
 	if (!attrs->srq && (attrs->cap.max_recv_wr > dev->attr.max_rqe)) {
-		ocrdma_err("%s(%d) unsupported recv_wr=0x%x requested\n",
-			   __func__, dev->id, attrs->cap.max_recv_wr);
-		ocrdma_err("%s(%d) supported recv_wr=0x%x\n",
-			   __func__, dev->id, dev->attr.max_rqe);
+		pr_err("%s(%d) unsupported recv_wr=0x%x requested\n",
+		       __func__, dev->id, attrs->cap.max_recv_wr);
+		pr_err("%s(%d) supported recv_wr=0x%x\n",
+		       __func__, dev->id, dev->attr.max_rqe);
 		return -EINVAL;
 	}
 	if (attrs->cap.max_inline_data > dev->attr.max_inline_data) {
-		ocrdma_err("%s(%d) unsupported inline data size=0x%x"
-			   " requested\n", __func__, dev->id,
-			   attrs->cap.max_inline_data);
-		ocrdma_err("%s(%d) supported inline data size=0x%x\n",
-			   __func__, dev->id, dev->attr.max_inline_data);
+		pr_err("%s(%d) unsupported inline data size=0x%x requested\n",
+		       __func__, dev->id, attrs->cap.max_inline_data);
+		pr_err("%s(%d) supported inline data size=0x%x\n",
+		       __func__, dev->id, dev->attr.max_inline_data);
 		return -EINVAL;
 	}
 	if (attrs->cap.max_send_sge > dev->attr.max_send_sge) {
-		ocrdma_err("%s(%d) unsupported send_sge=0x%x requested\n",
-			   __func__, dev->id, attrs->cap.max_send_sge);
-		ocrdma_err("%s(%d) supported send_sge=0x%x\n",
-			   __func__, dev->id, dev->attr.max_send_sge);
+		pr_err("%s(%d) unsupported send_sge=0x%x requested\n",
+		       __func__, dev->id, attrs->cap.max_send_sge);
+		pr_err("%s(%d) supported send_sge=0x%x\n",
+		       __func__, dev->id, dev->attr.max_send_sge);
 		return -EINVAL;
 	}
 	if (attrs->cap.max_recv_sge > dev->attr.max_recv_sge) {
-		ocrdma_err("%s(%d) unsupported recv_sge=0x%x requested\n",
-			   __func__, dev->id, attrs->cap.max_recv_sge);
-		ocrdma_err("%s(%d) supported recv_sge=0x%x\n",
-			   __func__, dev->id, dev->attr.max_recv_sge);
+		pr_err("%s(%d) unsupported recv_sge=0x%x requested\n",
+		       __func__, dev->id, attrs->cap.max_recv_sge);
+		pr_err("%s(%d) supported recv_sge=0x%x\n",
+		       __func__, dev->id, dev->attr.max_recv_sge);
 		return -EINVAL;
 	}
 	/* unprivileged user space cannot create special QP */
 	if (ibpd->uobject && attrs->qp_type == IB_QPT_GSI) {
-		ocrdma_err
+		pr_err
 		    ("%s(%d) Userspace can't create special QPs of type=0x%x\n",
 		     __func__, dev->id, attrs->qp_type);
 		return -EINVAL;
 	}
 	/* allow creating only one GSI type of QP */
 	if (attrs->qp_type == IB_QPT_GSI && dev->gsi_qp_created) {
-		ocrdma_err("%s(%d) GSI special QPs already created.\n",
-			   __func__, dev->id);
+		pr_err("%s(%d) GSI special QPs already created.\n",
+		       __func__, dev->id);
 		return -EINVAL;
 	}
 	/* verify consumer QPs are not trying to use GSI QP's CQ */
@@ -896,8 +881,8 @@ static int ocrdma_check_qp_params(struct
 		    (dev->gsi_sqcq == get_ocrdma_cq(attrs->recv_cq)) ||
 		    (dev->gsi_rqcq == get_ocrdma_cq(attrs->send_cq)) ||
 		    (dev->gsi_rqcq == get_ocrdma_cq(attrs->recv_cq))) {
-			ocrdma_err("%s(%d) Consumer QP cannot use GSI CQs.\n",
-				   __func__, dev->id);
+			pr_err("%s(%d) Consumer QP cannot use GSI CQs.\n",
+			       __func__, dev->id);
 			return -EINVAL;
 		}
 	}
@@ -949,7 +934,7 @@ static int ocrdma_copy_qp_uresp(struct o
 	}
 	status = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
 	if (status) {
-		ocrdma_err("%s(%d) user copy error.\n", __func__, dev->id);
+		pr_err("%s(%d) user copy error.\n", __func__, dev->id);
 		goto err;
 	}
 	status = ocrdma_add_mmap(pd->uctx, uresp.sq_page_addr[0],
@@ -1023,15 +1008,6 @@ static void ocrdma_set_qp_init_params(st
 	qp->state = OCRDMA_QPS_RST;
 }
 
-static void ocrdma_set_qp_use_cnt(struct ocrdma_qp *qp, struct ocrdma_pd *pd)
-{
-	atomic_inc(&pd->use_cnt);
-	atomic_inc(&qp->sq_cq->use_cnt);
-	atomic_inc(&qp->rq_cq->use_cnt);
-	if (qp->srq)
-		atomic_inc(&qp->srq->use_cnt);
-	qp->ibqp.qp_num = qp->id;
-}
 
 static void ocrdma_store_gsi_qp_cq(struct ocrdma_dev *dev,
 				   struct ib_qp_init_attr *attrs)
@@ -1099,7 +1075,7 @@ struct ib_qp *ocrdma_create_qp(struct ib
 			goto cpy_err;
 	}
 	ocrdma_store_gsi_qp_cq(dev, attrs);
-	ocrdma_set_qp_use_cnt(qp, pd);
+	qp->ibqp.qp_num = qp->id;
 	mutex_unlock(&dev->dev_lock);
 	return &qp->ibqp;
 
@@ -1112,7 +1088,7 @@ mbx_err:
 	kfree(qp->wqe_wr_id_tbl);
 	kfree(qp->rqe_wr_id_tbl);
 	kfree(qp);
-	ocrdma_err("%s(%d) error=%d\n", __func__, dev->id, status);
+	pr_err("%s(%d) error=%d\n", __func__, dev->id, status);
 gen_err:
 	return ERR_PTR(status);
 }
@@ -1162,10 +1138,10 @@ int ocrdma_modify_qp(struct ib_qp *ibqp,
 	spin_unlock_irqrestore(&qp->q_lock, flags);
 
 	if (!ib_modify_qp_is_ok(old_qps, new_qps, ibqp->qp_type, attr_mask)) {
-		ocrdma_err("%s(%d) invalid attribute mask=0x%x specified for "
-			   "qpn=0x%x of type=0x%x old_qps=0x%x, new_qps=0x%x\n",
-			   __func__, dev->id, attr_mask, qp->id, ibqp->qp_type,
-			   old_qps, new_qps);
+		pr_err("%s(%d) invalid attribute mask=0x%x specified for\n"
+		       "qpn=0x%x of type=0x%x old_qps=0x%x, new_qps=0x%x\n",
+		       __func__, dev->id, attr_mask, qp->id, ibqp->qp_type,
+		       old_qps, new_qps);
 		goto param_err;
 	}
 
@@ -1475,11 +1451,6 @@ int ocrdma_destroy_qp(struct ib_qp *ibqp
 
 	ocrdma_del_flush_qp(qp);
 
-	atomic_dec(&qp->pd->use_cnt);
-	atomic_dec(&qp->sq_cq->use_cnt);
-	atomic_dec(&qp->rq_cq->use_cnt);
-	if (qp->srq)
-		atomic_dec(&qp->srq->use_cnt);
 	kfree(qp->wqe_wr_id_tbl);
 	kfree(qp->rqe_wr_id_tbl);
 	kfree(qp);
@@ -1491,6 +1462,7 @@ static int ocrdma_copy_srq_uresp(struct
 	int status;
 	struct ocrdma_create_srq_uresp uresp;
 
+	memset(&uresp, 0, sizeof(uresp));
 	uresp.rq_dbid = srq->rq.dbid;
 	uresp.num_rq_pages = 1;
 	uresp.rq_page_addr[0] = srq->rq.pa;
@@ -1565,14 +1537,12 @@ struct ib_srq *ocrdma_create_srq(struct
 			goto arm_err;
 	}
 
-	atomic_set(&srq->use_cnt, 0);
 	if (udata) {
 		status = ocrdma_copy_srq_uresp(srq, udata);
 		if (status)
 			goto arm_err;
 	}
 
-	atomic_inc(&pd->use_cnt);
 	return &srq->ibsrq;
 
 arm_err:
@@ -1618,18 +1588,12 @@ int ocrdma_destroy_srq(struct ib_srq *ib
 
 	srq = get_ocrdma_srq(ibsrq);
 	dev = srq->dev;
-	if (atomic_read(&srq->use_cnt)) {
-		ocrdma_err("%s(%d) err, srq=0x%x in use\n",
-			   __func__, dev->id, srq->id);
-		return -EAGAIN;
-	}
 
 	status = ocrdma_mbx_destroy_srq(dev, srq);
 
 	if (srq->pd->uctx)
 		ocrdma_del_mmap(srq->pd->uctx, (u64) srq->rq.pa, srq->rq.len);
 
-	atomic_dec(&srq->pd->use_cnt);
 	kfree(srq->idx_bit_fields);
 	kfree(srq->rqe_wr_id_tbl);
 	kfree(srq);
@@ -1677,9 +1641,9 @@ static int ocrdma_build_inline_sges(stru
 {
 	if (wr->send_flags & IB_SEND_INLINE) {
 		if (wr->sg_list[0].length > qp->max_inline_data) {
-			ocrdma_err("%s() supported_len=0x%x,"
-				" unspported len req=0x%x\n", __func__,
-				qp->max_inline_data, wr->sg_list[0].length);
+			pr_err("%s() supported_len=0x%x,\n"
+			       " unspported len req=0x%x\n", __func__,
+			       qp->max_inline_data, wr->sg_list[0].length);
 			return -EINVAL;
 		}
 		memcpy(sge,
@@ -1773,12 +1737,14 @@ int ocrdma_post_send(struct ib_qp *ibqp,
 	spin_lock_irqsave(&qp->q_lock, flags);
 	if (qp->state != OCRDMA_QPS_RTS && qp->state != OCRDMA_QPS_SQD) {
 		spin_unlock_irqrestore(&qp->q_lock, flags);
+		*bad_wr = wr;
 		return -EINVAL;
 	}
 
 	while (wr) {
 		if (ocrdma_hwq_free_cnt(&qp->sq) == 0 ||
 		    wr->num_sge > qp->sq.max_sges) {
+			*bad_wr = wr;
 			status = -ENOMEM;
 			break;
 		}
@@ -1856,7 +1822,7 @@ int ocrdma_post_send(struct ib_qp *ibqp,
 
 static void ocrdma_ring_rq_db(struct ocrdma_qp *qp)
 {
-	u32 val = qp->rq.dbid | (1 << OCRDMA_GET_NUM_POSTED_SHIFT_VAL(qp));
+	u32 val = qp->rq.dbid | (1 << ocrdma_get_num_posted_shift(qp));
 
 	iowrite32(val, qp->rq_db);
 }
@@ -2094,8 +2060,8 @@ static void ocrdma_update_wc(struct ocrd
 		break;
 	default:
 		ibwc->status = IB_WC_GENERAL_ERR;
-		ocrdma_err("%s() invalid opcode received = 0x%x\n",
-			   __func__, hdr->cw & OCRDMA_WQE_OPCODE_MASK);
+		pr_err("%s() invalid opcode received = 0x%x\n",
+		       __func__, hdr->cw & OCRDMA_WQE_OPCODE_MASK);
 		break;
 	};
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/Kconfig linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/Kconfig
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -5,3 +5,11 @@ config INFINIBAND_QIB
 	This is a low-level driver for Intel PCIe QLE InfiniBand host
 	channel adapters.  This driver does not support the Intel
 	HyperTransport card (model QHT7140).
+
+config INFINIBAND_QIB_DCA
+	bool "QIB DCA support"
+	depends on INFINIBAND_QIB && DCA && SMP && GENERIC_HARDIRQS && !(INFINIBAND_QIB=y && DCA=m)
+	default y
+	---help---
+	Setting this enables DCA support on some Intel chip sets
+	with the iba7322 HCA.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/Makefile linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/Makefile
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -13,3 +13,4 @@ ib_qib-$(CONFIG_PCI_MSI) += qib_iba6120.
 
 ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o
 ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o
+ib_qib-$(CONFIG_DEBUG_FS) += qib_debugfs.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_common.h linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_common.h
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_common.h	2013-08-25 20:43:22.000000000 -0400
@@ -279,7 +279,7 @@ struct qib_base_info {
  * may not be implemented; the user code must deal with this if it
  * cares, or it must abort after initialization reports the difference.
  */
-#define QIB_USER_SWMINOR 11
+#define QIB_USER_SWMINOR 12
 
 #define QIB_USER_SWVERSION ((QIB_USER_SWMAJOR << 16) | QIB_USER_SWMINOR)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_cq.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_cq.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_cq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_cq.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2013 Intel Corporation.  All rights reserved.
  * Copyright (c) 2006, 2007, 2008, 2010 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -34,8 +35,10 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/kthread.h>
 
 #include "qib_verbs.h"
+#include "qib.h"
 
 /**
  * qib_cq_enter - add a new entry to the completion queue
@@ -102,13 +105,18 @@ void qib_cq_enter(struct qib_cq *cq, str
 	if (cq->notify == IB_CQ_NEXT_COMP ||
 	    (cq->notify == IB_CQ_SOLICITED &&
 	     (solicited || entry->status != IB_WC_SUCCESS))) {
-		cq->notify = IB_CQ_NONE;
-		cq->triggered++;
+		struct kthread_worker *worker;
 		/*
 		 * This will cause send_complete() to be called in
 		 * another thread.
 		 */
-		queue_work(qib_cq_wq, &cq->comptask);
+		smp_rmb();
+		worker = cq->dd->worker;
+		if (likely(worker)) {
+			cq->notify = IB_CQ_NONE;
+			cq->triggered++;
+			queue_kthread_work(worker, &cq->comptask);
+		}
 	}
 
 	spin_unlock_irqrestore(&cq->lock, flags);
@@ -163,7 +171,7 @@ bail:
 	return npolled;
 }
 
-static void send_complete(struct work_struct *work)
+static void send_complete(struct kthread_work *work)
 {
 	struct qib_cq *cq = container_of(work, struct qib_cq, comptask);
 
@@ -287,11 +295,12 @@ struct ib_cq *qib_create_cq(struct ib_de
 	 * The number of entries should be >= the number requested or return
 	 * an error.
 	 */
+	cq->dd = dd_from_dev(dev);
 	cq->ibcq.cqe = entries;
 	cq->notify = IB_CQ_NONE;
 	cq->triggered = 0;
 	spin_lock_init(&cq->lock);
-	INIT_WORK(&cq->comptask, send_complete);
+	init_kthread_work(&cq->comptask, send_complete);
 	wc->head = 0;
 	wc->tail = 0;
 	cq->queue = wc;
@@ -323,7 +332,7 @@ int qib_destroy_cq(struct ib_cq *ibcq)
 	struct qib_ibdev *dev = to_idev(ibcq->device);
 	struct qib_cq *cq = to_icq(ibcq);
 
-	flush_work(&cq->comptask);
+	flush_kthread_work(&cq->comptask);
 	spin_lock(&dev->n_cqs_lock);
 	dev->n_cqs_allocated--;
 	spin_unlock(&dev->n_cqs_lock);
@@ -483,3 +492,49 @@ bail_free:
 bail:
 	return ret;
 }
+
+int qib_cq_init(struct qib_devdata *dd)
+{
+	int ret = 0;
+	int cpu;
+	struct task_struct *task;
+
+	if (dd->worker)
+		return 0;
+	dd->worker = kzalloc(sizeof(*dd->worker), GFP_KERNEL);
+	if (!dd->worker)
+		return -ENOMEM;
+	init_kthread_worker(dd->worker);
+	task = kthread_create_on_node(
+		kthread_worker_fn,
+		dd->worker,
+		dd->assigned_node_id,
+		"qib_cq%d", dd->unit);
+	if (IS_ERR(task))
+		goto task_fail;
+	cpu = cpumask_first(cpumask_of_node(dd->assigned_node_id));
+	kthread_bind(task, cpu);
+	wake_up_process(task);
+out:
+	return ret;
+task_fail:
+	ret = PTR_ERR(task);
+	kfree(dd->worker);
+	dd->worker = NULL;
+	goto out;
+}
+
+void qib_cq_exit(struct qib_devdata *dd)
+{
+	struct kthread_worker *worker;
+
+	worker = dd->worker;
+	if (!worker)
+		return;
+	/* blocks future queuing from send_complete() */
+	dd->worker = NULL;
+	smp_wmb();
+	flush_kthread_worker(worker);
+	kthread_stop(worker->task);
+	kfree(worker);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_debugfs.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_debugfs.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,283 @@
+#ifdef CONFIG_DEBUG_FS
+/*
+ * Copyright (c) 2013 Intel Corporation.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/kernel.h>
+#include <linux/export.h>
+
+#include "qib.h"
+#include "qib_verbs.h"
+#include "qib_debugfs.h"
+
+static struct dentry *qib_dbg_root;
+
+#define DEBUGFS_FILE(name) \
+static const struct seq_operations _##name##_seq_ops = { \
+	.start = _##name##_seq_start, \
+	.next  = _##name##_seq_next, \
+	.stop  = _##name##_seq_stop, \
+	.show  = _##name##_seq_show \
+}; \
+static int _##name##_open(struct inode *inode, struct file *s) \
+{ \
+	struct seq_file *seq; \
+	int ret; \
+	ret =  seq_open(s, &_##name##_seq_ops); \
+	if (ret) \
+		return ret; \
+	seq = s->private_data; \
+	seq->private = inode->i_private; \
+	return 0; \
+} \
+static const struct file_operations _##name##_file_ops = { \
+	.owner   = THIS_MODULE, \
+	.open    = _##name##_open, \
+	.read    = seq_read, \
+	.llseek  = seq_lseek, \
+	.release = seq_release \
+};
+
+#define DEBUGFS_FILE_CREATE(name) \
+do { \
+	struct dentry *ent; \
+	ent = debugfs_create_file(#name , 0400, ibd->qib_ibdev_dbg, \
+		ibd, &_##name##_file_ops); \
+	if (!ent) \
+		pr_warn("create of " #name " failed\n"); \
+} while (0)
+
+static void *_opcode_stats_seq_start(struct seq_file *s, loff_t *pos)
+{
+	struct qib_opcode_stats_perctx *opstats;
+
+	if (*pos >= ARRAY_SIZE(opstats->stats))
+		return NULL;
+	return pos;
+}
+
+static void *_opcode_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	struct qib_opcode_stats_perctx *opstats;
+
+	++*pos;
+	if (*pos >= ARRAY_SIZE(opstats->stats))
+		return NULL;
+	return pos;
+}
+
+
+static void _opcode_stats_seq_stop(struct seq_file *s, void *v)
+{
+	/* nothing allocated */
+}
+
+static int _opcode_stats_seq_show(struct seq_file *s, void *v)
+{
+	loff_t *spos = v;
+	loff_t i = *spos, j;
+	u64 n_packets = 0, n_bytes = 0;
+	struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
+	struct qib_devdata *dd = dd_from_dev(ibd);
+
+	for (j = 0; j < dd->first_user_ctxt; j++) {
+		if (!dd->rcd[j])
+			continue;
+		n_packets += dd->rcd[j]->opstats->stats[i].n_packets;
+		n_bytes += dd->rcd[j]->opstats->stats[i].n_bytes;
+	}
+	if (!n_packets && !n_bytes)
+		return SEQ_SKIP;
+	seq_printf(s, "%02llx %llu/%llu\n", i,
+		(unsigned long long) n_packets,
+		(unsigned long long) n_bytes);
+
+	return 0;
+}
+
+DEBUGFS_FILE(opcode_stats)
+
+static void *_ctx_stats_seq_start(struct seq_file *s, loff_t *pos)
+{
+	struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
+	struct qib_devdata *dd = dd_from_dev(ibd);
+
+	if (!*pos)
+		return SEQ_START_TOKEN;
+	if (*pos >= dd->first_user_ctxt)
+		return NULL;
+	return pos;
+}
+
+static void *_ctx_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
+	struct qib_devdata *dd = dd_from_dev(ibd);
+
+	if (v == SEQ_START_TOKEN)
+		return pos;
+
+	++*pos;
+	if (*pos >= dd->first_user_ctxt)
+		return NULL;
+	return pos;
+}
+
+static void _ctx_stats_seq_stop(struct seq_file *s, void *v)
+{
+	/* nothing allocated */
+}
+
+static int _ctx_stats_seq_show(struct seq_file *s, void *v)
+{
+	loff_t *spos;
+	loff_t i, j;
+	u64 n_packets = 0;
+	struct qib_ibdev *ibd = (struct qib_ibdev *)s->private;
+	struct qib_devdata *dd = dd_from_dev(ibd);
+
+	if (v == SEQ_START_TOKEN) {
+		seq_puts(s, "Ctx:npkts\n");
+		return 0;
+	}
+
+	spos = v;
+	i = *spos;
+
+	if (!dd->rcd[i])
+		return SEQ_SKIP;
+
+	for (j = 0; j < ARRAY_SIZE(dd->rcd[i]->opstats->stats); j++)
+		n_packets += dd->rcd[i]->opstats->stats[j].n_packets;
+
+	if (!n_packets)
+		return SEQ_SKIP;
+
+	seq_printf(s, "  %llu:%llu\n", i, n_packets);
+	return 0;
+}
+
+DEBUGFS_FILE(ctx_stats)
+
+static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
+{
+	struct qib_qp_iter *iter;
+	loff_t n = *pos;
+
+	iter = qib_qp_iter_init(s->private);
+	if (!iter)
+		return NULL;
+
+	while (n--) {
+		if (qib_qp_iter_next(iter)) {
+			kfree(iter);
+			return NULL;
+		}
+	}
+
+	return iter;
+}
+
+static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
+				   loff_t *pos)
+{
+	struct qib_qp_iter *iter = iter_ptr;
+
+	(*pos)++;
+
+	if (qib_qp_iter_next(iter)) {
+		kfree(iter);
+		return NULL;
+	}
+
+	return iter;
+}
+
+static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
+{
+	/* nothing for now */
+}
+
+static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr)
+{
+	struct qib_qp_iter *iter = iter_ptr;
+
+	if (!iter)
+		return 0;
+
+	qib_qp_iter_print(s, iter);
+
+	return 0;
+}
+
+DEBUGFS_FILE(qp_stats)
+
+void qib_dbg_ibdev_init(struct qib_ibdev *ibd)
+{
+	char name[10];
+
+	snprintf(name, sizeof(name), "qib%d", dd_from_dev(ibd)->unit);
+	ibd->qib_ibdev_dbg = debugfs_create_dir(name, qib_dbg_root);
+	if (!ibd->qib_ibdev_dbg) {
+		pr_warn("create of %s failed\n", name);
+		return;
+	}
+	DEBUGFS_FILE_CREATE(opcode_stats);
+	DEBUGFS_FILE_CREATE(ctx_stats);
+	DEBUGFS_FILE_CREATE(qp_stats);
+	return;
+}
+
+void qib_dbg_ibdev_exit(struct qib_ibdev *ibd)
+{
+	if (!qib_dbg_root)
+		goto out;
+	debugfs_remove_recursive(ibd->qib_ibdev_dbg);
+out:
+	ibd->qib_ibdev_dbg = NULL;
+}
+
+void qib_dbg_init(void)
+{
+	qib_dbg_root = debugfs_create_dir(QIB_DRV_NAME, NULL);
+	if (!qib_dbg_root)
+		pr_warn("init of debugfs failed\n");
+}
+
+void qib_dbg_exit(void)
+{
+	debugfs_remove_recursive(qib_dbg_root);
+	qib_dbg_root = NULL;
+}
+
+#endif
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_debugfs.h linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_debugfs.h
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_debugfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_debugfs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,45 @@
+#ifndef _QIB_DEBUGFS_H
+#define _QIB_DEBUGFS_H
+
+#ifdef CONFIG_DEBUG_FS
+/*
+ * Copyright (c) 2013 Intel Corporation.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+struct qib_ibdev;
+void qib_dbg_ibdev_init(struct qib_ibdev *ibd);
+void qib_dbg_ibdev_exit(struct qib_ibdev *ibd);
+void qib_dbg_init(void);
+void qib_dbg_exit(void);
+
+#endif
+
+#endif                          /* _QIB_DEBUGFS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_driver.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_driver.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -558,7 +558,6 @@ move_along:
 	}
 
 	rcd->head = l;
-	rcd->pkt_count += i;
 
 	/*
 	 * Iterate over all QPs waiting to respond.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_file_ops.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_file_ops.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_file_ops.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_file_ops.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Intel Corporation. All rights reserved.
+ * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -1155,6 +1155,49 @@ static unsigned int qib_poll(struct file
 	return pollflag;
 }
 
+static void assign_ctxt_affinity(struct file *fp, struct qib_devdata *dd)
+{
+	struct qib_filedata *fd = fp->private_data;
+	const unsigned int weight = cpumask_weight(&current->cpus_allowed);
+	const struct cpumask *local_mask = cpumask_of_pcibus(dd->pcidev->bus);
+	int local_cpu;
+
+	/*
+	 * If process has NOT already set it's affinity, select and
+	 * reserve a processor for it on the local NUMA node.
+	 */
+	if ((weight >= qib_cpulist_count) &&
+		(cpumask_weight(local_mask) <= qib_cpulist_count)) {
+		for_each_cpu(local_cpu, local_mask)
+			if (!test_and_set_bit(local_cpu, qib_cpulist)) {
+				fd->rec_cpu_num = local_cpu;
+				return;
+			}
+	}
+
+	/*
+	 * If process has NOT already set it's affinity, select and
+	 * reserve a processor for it, as a rendevous for all
+	 * users of the driver.  If they don't actually later
+	 * set affinity to this cpu, or set it to some other cpu,
+	 * it just means that sooner or later we don't recommend
+	 * a cpu, and let the scheduler do it's best.
+	 */
+	if (weight >= qib_cpulist_count) {
+		int cpu;
+		cpu = find_first_zero_bit(qib_cpulist,
+					  qib_cpulist_count);
+		if (cpu == qib_cpulist_count)
+			qib_dev_err(dd,
+			"no cpus avail for affinity PID %u\n",
+			current->pid);
+		else {
+			__set_bit(cpu, qib_cpulist);
+			fd->rec_cpu_num = cpu;
+		}
+	}
+}
+
 /*
  * Check that userland and driver are compatible for subcontexts.
  */
@@ -1259,12 +1302,20 @@ bail:
 static int setup_ctxt(struct qib_pportdata *ppd, int ctxt,
 		      struct file *fp, const struct qib_user_info *uinfo)
 {
+	struct qib_filedata *fd = fp->private_data;
 	struct qib_devdata *dd = ppd->dd;
 	struct qib_ctxtdata *rcd;
 	void *ptmp = NULL;
 	int ret;
+	int numa_id;
 
-	rcd = qib_create_ctxtdata(ppd, ctxt);
+	assign_ctxt_affinity(fp, dd);
+
+	numa_id = qib_numa_aware ? ((fd->rec_cpu_num != -1) ?
+		cpu_to_node(fd->rec_cpu_num) :
+		numa_node_id()) : dd->assigned_node_id;
+
+	rcd = qib_create_ctxtdata(ppd, ctxt, numa_id);
 
 	/*
 	 * Allocate memory for use in qib_tid_update() at open to
@@ -1296,6 +1347,9 @@ static int setup_ctxt(struct qib_pportda
 	goto bail;
 
 bailerr:
+	if (fd->rec_cpu_num != -1)
+		__clear_bit(fd->rec_cpu_num, qib_cpulist);
+
 	dd->rcd[ctxt] = NULL;
 	kfree(rcd);
 	kfree(ptmp);
@@ -1485,6 +1539,57 @@ static int qib_open(struct inode *in, st
 	return fp->private_data ? 0 : -ENOMEM;
 }
 
+static int find_hca(unsigned int cpu, int *unit)
+{
+	int ret = 0, devmax, npresent, nup, ndev;
+
+	*unit = -1;
+
+	devmax = qib_count_units(&npresent, &nup);
+	if (!npresent) {
+		ret = -ENXIO;
+		goto done;
+	}
+	if (!nup) {
+		ret = -ENETDOWN;
+		goto done;
+	}
+	for (ndev = 0; ndev < devmax; ndev++) {
+		struct qib_devdata *dd = qib_lookup(ndev);
+		if (dd) {
+			if (pcibus_to_node(dd->pcidev->bus) < 0) {
+				ret = -EINVAL;
+				goto done;
+			}
+			if (cpu_to_node(cpu) ==
+				pcibus_to_node(dd->pcidev->bus)) {
+				*unit = ndev;
+				goto done;
+			}
+		}
+	}
+done:
+	return ret;
+}
+
+static int do_qib_user_sdma_queue_create(struct file *fp)
+{
+	struct qib_filedata *fd = fp->private_data;
+	struct qib_ctxtdata *rcd = fd->rcd;
+	struct qib_devdata *dd = rcd->dd;
+
+	if (dd->flags & QIB_HAS_SEND_DMA)
+
+		fd->pq = qib_user_sdma_queue_create(&dd->pcidev->dev,
+						    dd->unit,
+						    rcd->ctxt,
+						    fd->subctxt);
+		if (!fd->pq)
+			return -ENOMEM;
+
+	return 0;
+}
+
 /*
  * Get ctxt early, so can set affinity prior to memory allocation.
  */
@@ -1517,61 +1622,36 @@ static int qib_assign_ctxt(struct file *
 	if (qib_compatible_subctxts(swmajor, swminor) &&
 	    uinfo->spu_subctxt_cnt) {
 		ret = find_shared_ctxt(fp, uinfo);
-		if (ret) {
-			if (ret > 0)
-				ret = 0;
-			goto done_chk_sdma;
+		if (ret > 0) {
+			ret = do_qib_user_sdma_queue_create(fp);
+			if (!ret)
+				assign_ctxt_affinity(fp, (ctxt_fp(fp))->dd);
+			goto done_ok;
 		}
 	}
 
 	i_minor = iminor(file_inode(fp)) - QIB_USER_MINOR_BASE;
 	if (i_minor)
 		ret = find_free_ctxt(i_minor - 1, fp, uinfo);
-	else
-		ret = get_a_ctxt(fp, uinfo, alg);
-
-done_chk_sdma:
-	if (!ret) {
-		struct qib_filedata *fd = fp->private_data;
-		const struct qib_ctxtdata *rcd = fd->rcd;
-		const struct qib_devdata *dd = rcd->dd;
-		unsigned int weight;
-
-		if (dd->flags & QIB_HAS_SEND_DMA) {
-			fd->pq = qib_user_sdma_queue_create(&dd->pcidev->dev,
-							    dd->unit,
-							    rcd->ctxt,
-							    fd->subctxt);
-			if (!fd->pq)
-				ret = -ENOMEM;
-		}
+	else {
+		int unit;
+		const unsigned int cpu = cpumask_first(&current->cpus_allowed);
+		const unsigned int weight =
+			cpumask_weight(&current->cpus_allowed);
 
-		/*
-		 * If process has NOT already set it's affinity, select and
-		 * reserve a processor for it, as a rendezvous for all
-		 * users of the driver.  If they don't actually later
-		 * set affinity to this cpu, or set it to some other cpu,
-		 * it just means that sooner or later we don't recommend
-		 * a cpu, and let the scheduler do it's best.
-		 */
-		weight = cpumask_weight(tsk_cpus_allowed(current));
-		if (!ret && weight >= qib_cpulist_count) {
-			int cpu;
-			cpu = find_first_zero_bit(qib_cpulist,
-						  qib_cpulist_count);
-			if (cpu != qib_cpulist_count) {
-				__set_bit(cpu, qib_cpulist);
-				fd->rec_cpu_num = cpu;
-			}
-		} else if (weight == 1 &&
-			test_bit(cpumask_first(tsk_cpus_allowed(current)),
-				 qib_cpulist))
-			qib_devinfo(dd->pcidev,
-				"%s PID %u affinity set to cpu %d; already allocated\n",
-				current->comm, current->pid,
-				cpumask_first(tsk_cpus_allowed(current)));
+		if (weight == 1 && !test_bit(cpu, qib_cpulist))
+			if (!find_hca(cpu, &unit) && unit >= 0)
+				if (!find_free_ctxt(unit, fp, uinfo)) {
+					ret = 0;
+					goto done_chk_sdma;
+				}
+		ret = get_a_ctxt(fp, uinfo, alg);
 	}
 
+done_chk_sdma:
+	if (!ret)
+		ret = do_qib_user_sdma_queue_create(fp);
+done_ok:
 	mutex_unlock(&qib_mutex);
 
 done:
@@ -2208,7 +2288,7 @@ int qib_cdev_init(int minor, const char
 		goto err_cdev;
 	}
 
-	device = device_create(qib_class, NULL, dev, NULL, name);
+	device = device_create(qib_class, NULL, dev, NULL, "%s", name);
 	if (!IS_ERR(device))
 		goto done;
 	ret = PTR_ERR(device);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib.h linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib.h
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef _QIB_KERNEL_H
 #define _QIB_KERNEL_H
 /*
- * Copyright (c) 2012 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2012, 2013 Intel Corporation.  All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -51,6 +51,7 @@
 #include <linux/completion.h>
 #include <linux/kref.h>
 #include <linux/sched.h>
+#include <linux/kthread.h>
 
 #include "qib_common.h"
 #include "qib_verbs.h"
@@ -114,6 +115,11 @@ struct qib_eep_log_mask {
 /*
  * Below contains all data related to a single context (formerly called port).
  */
+
+#ifdef CONFIG_DEBUG_FS
+struct qib_opcode_stats_perctx;
+#endif
+
 struct qib_ctxtdata {
 	void **rcvegrbuf;
 	dma_addr_t *rcvegrbuf_phys;
@@ -154,6 +160,8 @@ struct qib_ctxtdata {
 	 */
 	/* instead of calculating it */
 	unsigned ctxt;
+	/* local node of context */
+	int node_id;
 	/* non-zero if ctxt is being shared. */
 	u16 subctxt_cnt;
 	/* non-zero if ctxt is being shared. */
@@ -222,12 +230,15 @@ struct qib_ctxtdata {
 	u8 redirect_seq_cnt;
 	/* ctxt rcvhdrq head offset */
 	u32 head;
-	u32 pkt_count;
 	/* lookaside fields */
 	struct qib_qp *lookaside_qp;
 	u32 lookaside_qpn;
 	/* QPs waiting for context processing */
 	struct list_head qp_wait_list;
+#ifdef CONFIG_DEBUG_FS
+	/* verbs stats per CTX */
+	struct qib_opcode_stats_perctx *opstats;
+#endif
 };
 
 struct qib_sge_state;
@@ -428,9 +439,19 @@ struct qib_verbs_txreq {
 #define ACTIVITY_TIMER 5
 
 #define MAX_NAME_SIZE 64
+
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+struct qib_irq_notify;
+#endif
+
 struct qib_msix_entry {
 	struct msix_entry msix;
 	void *arg;
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	int dca;
+	int rcv;
+	struct qib_irq_notify *notifier;
+#endif
 	char name[MAX_NAME_SIZE];
 	cpumask_var_t mask;
 };
@@ -828,6 +849,9 @@ struct qib_devdata {
 		struct qib_ctxtdata *);
 	void (*f_writescratch)(struct qib_devdata *, u32);
 	int (*f_tempsense_rd)(struct qib_devdata *, int regnum);
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	int (*f_notify_dca)(struct qib_devdata *, unsigned long event);
+#endif
 
 	char *boardname; /* human readable board info */
 
@@ -1075,6 +1099,10 @@ struct qib_devdata {
 	u16 psxmitwait_check_rate;
 	/* high volume overflow errors defered to tasklet */
 	struct tasklet_struct error_tasklet;
+	/* per device cq worker */
+	struct kthread_worker *worker;
+
+	int assigned_node_id; /* NUMA node closest to HCA */
 };
 
 /* hol_state values */
@@ -1154,7 +1182,7 @@ int qib_create_rcvhdrq(struct qib_devdat
 int qib_setup_eagerbufs(struct qib_ctxtdata *);
 void qib_set_ctxtcnt(struct qib_devdata *);
 int qib_create_ctxts(struct qib_devdata *dd);
-struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *, u32);
+struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *, u32, int);
 void qib_init_pportdata(struct qib_pportdata *, struct qib_devdata *, u8, u8);
 void qib_free_ctxtdata(struct qib_devdata *, struct qib_ctxtdata *);
 
@@ -1320,7 +1348,7 @@ static inline int __qib_sdma_running(str
 	return ppd->sdma_state.current_state == qib_sdma_state_s99_running;
 }
 int qib_sdma_running(struct qib_pportdata *);
-
+void dump_sdma_state(struct qib_pportdata *ppd);
 void __qib_sdma_process_event(struct qib_pportdata *, enum qib_sdma_events);
 void qib_sdma_process_event(struct qib_pportdata *, enum qib_sdma_events);
 
@@ -1445,6 +1473,7 @@ extern unsigned qib_n_krcv_queues;
 extern unsigned qib_sdma_fetch_arb;
 extern unsigned qib_compat_ddr_negotiate;
 extern int qib_special_trigger;
+extern unsigned qib_numa_aware;
 
 extern struct mutex qib_mutex;
 
@@ -1474,27 +1503,23 @@ extern struct mutex qib_mutex;
  * first to avoid possible serial port delays from printk.
  */
 #define qib_early_err(dev, fmt, ...) \
-	do { \
-		dev_err(dev, fmt, ##__VA_ARGS__); \
-	} while (0)
+	dev_err(dev, fmt, ##__VA_ARGS__)
 
 #define qib_dev_err(dd, fmt, ...) \
-	do { \
-		dev_err(&(dd)->pcidev->dev, "%s: " fmt, \
-			qib_get_unit_name((dd)->unit), ##__VA_ARGS__); \
-	} while (0)
+	dev_err(&(dd)->pcidev->dev, "%s: " fmt, \
+		qib_get_unit_name((dd)->unit), ##__VA_ARGS__)
+
+#define qib_dev_warn(dd, fmt, ...) \
+	dev_warn(&(dd)->pcidev->dev, "%s: " fmt, \
+		qib_get_unit_name((dd)->unit), ##__VA_ARGS__)
 
 #define qib_dev_porterr(dd, port, fmt, ...) \
-	do { \
-		dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \
-			qib_get_unit_name((dd)->unit), (dd)->unit, (port), \
-			##__VA_ARGS__); \
-	} while (0)
+	dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \
+		qib_get_unit_name((dd)->unit), (dd)->unit, (port), \
+		##__VA_ARGS__)
 
 #define qib_devinfo(pcidev, fmt, ...) \
-	do { \
-		dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__); \
-	} while (0)
+	dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__)
 
 /*
  * this is used for formatting hw error messages...
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_iba6120.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_iba6120.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_iba6120.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_iba6120.c	2013-08-25 20:43:22.000000000 -0400
@@ -3464,6 +3464,13 @@ static int qib_6120_tempsense_rd(struct
 	return -ENXIO;
 }
 
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+static int qib_6120_notify_dca(struct qib_devdata *dd, unsigned long event)
+{
+	return 0;
+}
+#endif
+
 /* Dummy function, as 6120 boards never disable EEPROM Write */
 static int qib_6120_eeprom_wen(struct qib_devdata *dd, int wen)
 {
@@ -3539,6 +3546,9 @@ struct qib_devdata *qib_init_iba6120_fun
 	dd->f_xgxs_reset        = qib_6120_xgxs_reset;
 	dd->f_writescratch      = writescratch;
 	dd->f_tempsense_rd	= qib_6120_tempsense_rd;
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	dd->f_notify_dca = qib_6120_notify_dca;
+#endif
 	/*
 	 * Do remaining pcie setup and save pcie values in dd.
 	 * Any error printing is already done by the init code.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_iba7220.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_iba7220.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_iba7220.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_iba7220.c	2013-08-25 20:43:22.000000000 -0400
@@ -4513,6 +4513,13 @@ bail:
 	return ret;
 }
 
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+static int qib_7220_notify_dca(struct qib_devdata *dd, unsigned long event)
+{
+	return 0;
+}
+#endif
+
 /* Dummy function, as 7220 boards never disable EEPROM Write */
 static int qib_7220_eeprom_wen(struct qib_devdata *dd, int wen)
 {
@@ -4587,6 +4594,9 @@ struct qib_devdata *qib_init_iba7220_fun
 	dd->f_xgxs_reset        = qib_7220_xgxs_reset;
 	dd->f_writescratch      = writescratch;
 	dd->f_tempsense_rd	= qib_7220_tempsense_rd;
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	dd->f_notify_dca = qib_7220_notify_dca;
+#endif
 	/*
 	 * Do remaining pcie setup and save pcie values in dd.
 	 * Any error printing is already done by the init code.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_iba7322.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_iba7322.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_iba7322.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_iba7322.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,6 +44,9 @@
 #include <linux/module.h>
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_smi.h>
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+#include <linux/dca.h>
+#endif
 
 #include "qib.h"
 #include "qib_7322_regs.h"
@@ -80,6 +83,7 @@ static void ibsd_wr_allchans(struct qib_
 static void serdes_7322_los_enable(struct qib_pportdata *, int);
 static int serdes_7322_init_old(struct qib_pportdata *);
 static int serdes_7322_init_new(struct qib_pportdata *);
+static void dump_sdma_7322_state(struct qib_pportdata *);
 
 #define BMASK(msb, lsb) (((1 << ((msb) + 1 - (lsb))) - 1) << (lsb))
 
@@ -519,6 +523,14 @@ static const u8 qib_7322_physportstate[0
 	[0x17] = IB_PHYSPORTSTATE_CFG_TRAIN
 };
 
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+struct qib_irq_notify {
+	int rcv;
+	void *arg;
+	struct irq_affinity_notify notify;
+};
+#endif
+
 struct qib_chip_specific {
 	u64 __iomem *cregbase;
 	u64 *cntrs;
@@ -546,6 +558,12 @@ struct qib_chip_specific {
 	u32 lastbuf_for_pio;
 	u32 stay_in_freeze;
 	u32 recovery_ports_initted;
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	u32 dca_ctrl;
+	int rhdr_cpu[18];
+	int sdma_cpu[2];
+	u64 dca_rcvhdr_ctrl[5]; /* B, C, D, E, F */
+#endif
 	struct qib_msix_entry *msix_entries;
 	unsigned long *sendchkenable;
 	unsigned long *sendgrhchk;
@@ -573,7 +591,7 @@ struct vendor_txdds_ent {
 static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *);
 
 #define TXDDS_TABLE_SZ 16 /* number of entries per speed in onchip table */
-#define TXDDS_EXTRA_SZ 13 /* number of extra tx settings entries */
+#define TXDDS_EXTRA_SZ 18 /* number of extra tx settings entries */
 #define TXDDS_MFG_SZ 2    /* number of mfg tx settings entries */
 #define SERDES_CHANS 4 /* yes, it's obvious, but one less magic number */
 
@@ -635,6 +653,7 @@ struct qib_chippport_specific {
 	u8 ibmalfusesnap;
 	struct qib_qsfp_data qsfp_data;
 	char epmsgbuf[192]; /* for port error interrupt msg buffer */
+	char sdmamsgbuf[192]; /* for per-port sdma error messages */
 };
 
 static struct {
@@ -642,27 +661,75 @@ static struct {
 	irq_handler_t handler;
 	int lsb;
 	int port; /* 0 if not port-specific, else port # */
+	int dca;
 } irq_table[] = {
-	{ "", qib_7322intr, -1, 0 },
+	{ "", qib_7322intr, -1, 0, 0 },
 	{ " (buf avail)", qib_7322bufavail,
-		SYM_LSB(IntStatus, SendBufAvail), 0 },
+		SYM_LSB(IntStatus, SendBufAvail), 0, 0},
 	{ " (sdma 0)", sdma_intr,
-		SYM_LSB(IntStatus, SDmaInt_0), 1 },
+		SYM_LSB(IntStatus, SDmaInt_0), 1, 1 },
 	{ " (sdma 1)", sdma_intr,
-		SYM_LSB(IntStatus, SDmaInt_1), 2 },
+		SYM_LSB(IntStatus, SDmaInt_1), 2, 1 },
 	{ " (sdmaI 0)", sdma_idle_intr,
-		SYM_LSB(IntStatus, SDmaIdleInt_0), 1 },
+		SYM_LSB(IntStatus, SDmaIdleInt_0), 1, 1},
 	{ " (sdmaI 1)", sdma_idle_intr,
-		SYM_LSB(IntStatus, SDmaIdleInt_1), 2 },
+		SYM_LSB(IntStatus, SDmaIdleInt_1), 2, 1},
 	{ " (sdmaP 0)", sdma_progress_intr,
-		SYM_LSB(IntStatus, SDmaProgressInt_0), 1 },
+		SYM_LSB(IntStatus, SDmaProgressInt_0), 1, 1 },
 	{ " (sdmaP 1)", sdma_progress_intr,
-		SYM_LSB(IntStatus, SDmaProgressInt_1), 2 },
+		SYM_LSB(IntStatus, SDmaProgressInt_1), 2, 1 },
 	{ " (sdmaC 0)", sdma_cleanup_intr,
-		SYM_LSB(IntStatus, SDmaCleanupDone_0), 1 },
+		SYM_LSB(IntStatus, SDmaCleanupDone_0), 1, 0 },
 	{ " (sdmaC 1)", sdma_cleanup_intr,
-		SYM_LSB(IntStatus, SDmaCleanupDone_1), 2 },
+		SYM_LSB(IntStatus, SDmaCleanupDone_1), 2 , 0},
+};
+
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+
+static const struct dca_reg_map {
+	int     shadow_inx;
+	int     lsb;
+	u64     mask;
+	u16     regno;
+} dca_rcvhdr_reg_map[] = {
+	{ 0, SYM_LSB(DCACtrlB, RcvHdrq0DCAOPH),
+	   ~SYM_MASK(DCACtrlB, RcvHdrq0DCAOPH) , KREG_IDX(DCACtrlB) },
+	{ 0, SYM_LSB(DCACtrlB, RcvHdrq1DCAOPH),
+	   ~SYM_MASK(DCACtrlB, RcvHdrq1DCAOPH) , KREG_IDX(DCACtrlB) },
+	{ 0, SYM_LSB(DCACtrlB, RcvHdrq2DCAOPH),
+	   ~SYM_MASK(DCACtrlB, RcvHdrq2DCAOPH) , KREG_IDX(DCACtrlB) },
+	{ 0, SYM_LSB(DCACtrlB, RcvHdrq3DCAOPH),
+	   ~SYM_MASK(DCACtrlB, RcvHdrq3DCAOPH) , KREG_IDX(DCACtrlB) },
+	{ 1, SYM_LSB(DCACtrlC, RcvHdrq4DCAOPH),
+	   ~SYM_MASK(DCACtrlC, RcvHdrq4DCAOPH) , KREG_IDX(DCACtrlC) },
+	{ 1, SYM_LSB(DCACtrlC, RcvHdrq5DCAOPH),
+	   ~SYM_MASK(DCACtrlC, RcvHdrq5DCAOPH) , KREG_IDX(DCACtrlC) },
+	{ 1, SYM_LSB(DCACtrlC, RcvHdrq6DCAOPH),
+	   ~SYM_MASK(DCACtrlC, RcvHdrq6DCAOPH) , KREG_IDX(DCACtrlC) },
+	{ 1, SYM_LSB(DCACtrlC, RcvHdrq7DCAOPH),
+	   ~SYM_MASK(DCACtrlC, RcvHdrq7DCAOPH) , KREG_IDX(DCACtrlC) },
+	{ 2, SYM_LSB(DCACtrlD, RcvHdrq8DCAOPH),
+	   ~SYM_MASK(DCACtrlD, RcvHdrq8DCAOPH) , KREG_IDX(DCACtrlD) },
+	{ 2, SYM_LSB(DCACtrlD, RcvHdrq9DCAOPH),
+	   ~SYM_MASK(DCACtrlD, RcvHdrq9DCAOPH) , KREG_IDX(DCACtrlD) },
+	{ 2, SYM_LSB(DCACtrlD, RcvHdrq10DCAOPH),
+	   ~SYM_MASK(DCACtrlD, RcvHdrq10DCAOPH) , KREG_IDX(DCACtrlD) },
+	{ 2, SYM_LSB(DCACtrlD, RcvHdrq11DCAOPH),
+	   ~SYM_MASK(DCACtrlD, RcvHdrq11DCAOPH) , KREG_IDX(DCACtrlD) },
+	{ 3, SYM_LSB(DCACtrlE, RcvHdrq12DCAOPH),
+	   ~SYM_MASK(DCACtrlE, RcvHdrq12DCAOPH) , KREG_IDX(DCACtrlE) },
+	{ 3, SYM_LSB(DCACtrlE, RcvHdrq13DCAOPH),
+	   ~SYM_MASK(DCACtrlE, RcvHdrq13DCAOPH) , KREG_IDX(DCACtrlE) },
+	{ 3, SYM_LSB(DCACtrlE, RcvHdrq14DCAOPH),
+	   ~SYM_MASK(DCACtrlE, RcvHdrq14DCAOPH) , KREG_IDX(DCACtrlE) },
+	{ 3, SYM_LSB(DCACtrlE, RcvHdrq15DCAOPH),
+	   ~SYM_MASK(DCACtrlE, RcvHdrq15DCAOPH) , KREG_IDX(DCACtrlE) },
+	{ 4, SYM_LSB(DCACtrlF, RcvHdrq16DCAOPH),
+	   ~SYM_MASK(DCACtrlF, RcvHdrq16DCAOPH) , KREG_IDX(DCACtrlF) },
+	{ 4, SYM_LSB(DCACtrlF, RcvHdrq17DCAOPH),
+	   ~SYM_MASK(DCACtrlF, RcvHdrq17DCAOPH) , KREG_IDX(DCACtrlF) },
 };
+#endif
 
 /* ibcctrl bits */
 #define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1
@@ -686,6 +753,13 @@ static void write_7322_init_portregs(str
 static void setup_7322_link_recovery(struct qib_pportdata *, u32);
 static void check_7322_rxe_status(struct qib_pportdata *);
 static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *);
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+static void qib_setup_dca(struct qib_devdata *dd);
+static void setup_dca_notifier(struct qib_devdata *dd,
+			       struct qib_msix_entry *m);
+static void reset_dca_notifier(struct qib_devdata *dd,
+			       struct qib_msix_entry *m);
+#endif
 
 /**
  * qib_read_ureg32 - read 32-bit virtualized per-context register
@@ -1522,6 +1596,8 @@ static void sdma_7322_p_errors(struct qi
 	struct qib_devdata *dd = ppd->dd;
 
 	errs &= QIB_E_P_SDMAERRS;
+	err_decode(ppd->cpspec->sdmamsgbuf, sizeof(ppd->cpspec->sdmamsgbuf),
+		   errs, qib_7322p_error_msgs);
 
 	if (errs & QIB_E_P_SDMAUNEXPDATA)
 		qib_dev_err(dd, "IB%u:%u SDmaUnexpData\n", dd->unit,
@@ -1529,6 +1605,15 @@ static void sdma_7322_p_errors(struct qi
 
 	spin_lock_irqsave(&ppd->sdma_lock, flags);
 
+	if (errs != QIB_E_P_SDMAHALT) {
+		/* SDMA errors have QIB_E_P_SDMAHALT and another bit set */
+		qib_dev_porterr(dd, ppd->port,
+			"SDMA %s 0x%016llx %s\n",
+			qib_sdma_state_names[ppd->sdma_state.current_state],
+			errs, ppd->cpspec->sdmamsgbuf);
+		dump_sdma_7322_state(ppd);
+	}
+
 	switch (ppd->sdma_state.current_state) {
 	case qib_sdma_state_s00_hw_down:
 		break;
@@ -2084,6 +2169,29 @@ static void qib_7322_handle_hwerrors(str
 
 	qib_dev_err(dd, "%s hardware error\n", msg);
 
+	if (hwerrs &
+		   (SYM_MASK(HwErrMask, SDmaMemReadErrMask_0) |
+		    SYM_MASK(HwErrMask, SDmaMemReadErrMask_1))) {
+		int pidx = 0;
+		int err;
+		unsigned long flags;
+		struct qib_pportdata *ppd = dd->pport;
+		for (; pidx < dd->num_pports; ++pidx, ppd++) {
+			err = 0;
+			if (pidx == 0 && (hwerrs &
+				SYM_MASK(HwErrMask, SDmaMemReadErrMask_0)))
+				err++;
+			if (pidx == 1 && (hwerrs &
+				SYM_MASK(HwErrMask, SDmaMemReadErrMask_1)))
+				err++;
+			if (err) {
+				spin_lock_irqsave(&ppd->sdma_lock, flags);
+				dump_sdma_7322_state(ppd);
+				spin_unlock_irqrestore(&ppd->sdma_lock, flags);
+			}
+		}
+	}
+
 	if (isfatal && !dd->diag_client) {
 		qib_dev_err(dd,
 			"Fatal Hardware Error, no longer usable, SN %.16s\n",
@@ -2558,6 +2666,162 @@ static void qib_setup_7322_setextled(str
 		qib_write_kreg_port(ppd, krp_rcvpktledcnt, ledblink);
 }
 
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+
+static int qib_7322_notify_dca(struct qib_devdata *dd, unsigned long event)
+{
+	switch (event) {
+	case DCA_PROVIDER_ADD:
+		if (dd->flags & QIB_DCA_ENABLED)
+			break;
+		if (!dca_add_requester(&dd->pcidev->dev)) {
+			qib_devinfo(dd->pcidev, "DCA enabled\n");
+			dd->flags |= QIB_DCA_ENABLED;
+			qib_setup_dca(dd);
+		}
+		break;
+	case DCA_PROVIDER_REMOVE:
+		if (dd->flags & QIB_DCA_ENABLED) {
+			dca_remove_requester(&dd->pcidev->dev);
+			dd->flags &= ~QIB_DCA_ENABLED;
+			dd->cspec->dca_ctrl = 0;
+			qib_write_kreg(dd, KREG_IDX(DCACtrlA),
+				dd->cspec->dca_ctrl);
+		}
+		break;
+	}
+	return 0;
+}
+
+static void qib_update_rhdrq_dca(struct qib_ctxtdata *rcd, int cpu)
+{
+	struct qib_devdata *dd = rcd->dd;
+	struct qib_chip_specific *cspec = dd->cspec;
+
+	if (!(dd->flags & QIB_DCA_ENABLED))
+		return;
+	if (cspec->rhdr_cpu[rcd->ctxt] != cpu) {
+		const struct dca_reg_map *rmp;
+
+		cspec->rhdr_cpu[rcd->ctxt] = cpu;
+		rmp = &dca_rcvhdr_reg_map[rcd->ctxt];
+		cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] &= rmp->mask;
+		cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] |=
+			(u64) dca3_get_tag(&dd->pcidev->dev, cpu) << rmp->lsb;
+		qib_devinfo(dd->pcidev,
+			"Ctxt %d cpu %d dca %llx\n", rcd->ctxt, cpu,
+			(long long) cspec->dca_rcvhdr_ctrl[rmp->shadow_inx]);
+		qib_write_kreg(dd, rmp->regno,
+			       cspec->dca_rcvhdr_ctrl[rmp->shadow_inx]);
+		cspec->dca_ctrl |= SYM_MASK(DCACtrlA, RcvHdrqDCAEnable);
+		qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl);
+	}
+}
+
+static void qib_update_sdma_dca(struct qib_pportdata *ppd, int cpu)
+{
+	struct qib_devdata *dd = ppd->dd;
+	struct qib_chip_specific *cspec = dd->cspec;
+	unsigned pidx = ppd->port - 1;
+
+	if (!(dd->flags & QIB_DCA_ENABLED))
+		return;
+	if (cspec->sdma_cpu[pidx] != cpu) {
+		cspec->sdma_cpu[pidx] = cpu;
+		cspec->dca_rcvhdr_ctrl[4] &= ~(ppd->hw_pidx ?
+			SYM_MASK(DCACtrlF, SendDma1DCAOPH) :
+			SYM_MASK(DCACtrlF, SendDma0DCAOPH));
+		cspec->dca_rcvhdr_ctrl[4] |=
+			(u64) dca3_get_tag(&dd->pcidev->dev, cpu) <<
+				(ppd->hw_pidx ?
+					SYM_LSB(DCACtrlF, SendDma1DCAOPH) :
+					SYM_LSB(DCACtrlF, SendDma0DCAOPH));
+		qib_devinfo(dd->pcidev,
+			"sdma %d cpu %d dca %llx\n", ppd->hw_pidx, cpu,
+			(long long) cspec->dca_rcvhdr_ctrl[4]);
+		qib_write_kreg(dd, KREG_IDX(DCACtrlF),
+			       cspec->dca_rcvhdr_ctrl[4]);
+		cspec->dca_ctrl |= ppd->hw_pidx ?
+			SYM_MASK(DCACtrlA, SendDMAHead1DCAEnable) :
+			SYM_MASK(DCACtrlA, SendDMAHead0DCAEnable);
+		qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl);
+	}
+}
+
+static void qib_setup_dca(struct qib_devdata *dd)
+{
+	struct qib_chip_specific *cspec = dd->cspec;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(cspec->rhdr_cpu); i++)
+		cspec->rhdr_cpu[i] = -1;
+	for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++)
+		cspec->sdma_cpu[i] = -1;
+	cspec->dca_rcvhdr_ctrl[0] =
+		(1ULL << SYM_LSB(DCACtrlB, RcvHdrq0DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlB, RcvHdrq1DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlB, RcvHdrq2DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlB, RcvHdrq3DCAXfrCnt));
+	cspec->dca_rcvhdr_ctrl[1] =
+		(1ULL << SYM_LSB(DCACtrlC, RcvHdrq4DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlC, RcvHdrq5DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlC, RcvHdrq6DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlC, RcvHdrq7DCAXfrCnt));
+	cspec->dca_rcvhdr_ctrl[2] =
+		(1ULL << SYM_LSB(DCACtrlD, RcvHdrq8DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlD, RcvHdrq9DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlD, RcvHdrq10DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlD, RcvHdrq11DCAXfrCnt));
+	cspec->dca_rcvhdr_ctrl[3] =
+		(1ULL << SYM_LSB(DCACtrlE, RcvHdrq12DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlE, RcvHdrq13DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlE, RcvHdrq14DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlE, RcvHdrq15DCAXfrCnt));
+	cspec->dca_rcvhdr_ctrl[4] =
+		(1ULL << SYM_LSB(DCACtrlF, RcvHdrq16DCAXfrCnt)) |
+		(1ULL << SYM_LSB(DCACtrlF, RcvHdrq17DCAXfrCnt));
+	for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++)
+		qib_write_kreg(dd, KREG_IDX(DCACtrlB) + i,
+			       cspec->dca_rcvhdr_ctrl[i]);
+	for (i = 0; i < cspec->num_msix_entries; i++)
+		setup_dca_notifier(dd, &cspec->msix_entries[i]);
+}
+
+static void qib_irq_notifier_notify(struct irq_affinity_notify *notify,
+			     const cpumask_t *mask)
+{
+	struct qib_irq_notify *n =
+		container_of(notify, struct qib_irq_notify, notify);
+	int cpu = cpumask_first(mask);
+
+	if (n->rcv) {
+		struct qib_ctxtdata *rcd = (struct qib_ctxtdata *)n->arg;
+		qib_update_rhdrq_dca(rcd, cpu);
+	} else {
+		struct qib_pportdata *ppd = (struct qib_pportdata *)n->arg;
+		qib_update_sdma_dca(ppd, cpu);
+	}
+}
+
+static void qib_irq_notifier_release(struct kref *ref)
+{
+	struct qib_irq_notify *n =
+		container_of(ref, struct qib_irq_notify, notify.kref);
+	struct qib_devdata *dd;
+
+	if (n->rcv) {
+		struct qib_ctxtdata *rcd = (struct qib_ctxtdata *)n->arg;
+		dd = rcd->dd;
+	} else {
+		struct qib_pportdata *ppd = (struct qib_pportdata *)n->arg;
+		dd = ppd->dd;
+	}
+	qib_devinfo(dd->pcidev,
+		"release on HCA notify 0x%p n 0x%p\n", ref, n);
+	kfree(n);
+}
+#endif
+
 /*
  * Disable MSIx interrupt if enabled, call generic MSIx code
  * to cleanup, and clear pending MSIx interrupts.
@@ -2575,6 +2839,9 @@ static void qib_7322_nomsix(struct qib_d
 
 		dd->cspec->num_msix_entries = 0;
 		for (i = 0; i < n; i++) {
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+			reset_dca_notifier(dd, &dd->cspec->msix_entries[i]);
+#endif
 			irq_set_affinity_hint(
 			  dd->cspec->msix_entries[i].msix.vector, NULL);
 			free_cpumask_var(dd->cspec->msix_entries[i].mask);
@@ -2602,6 +2869,15 @@ static void qib_setup_7322_cleanup(struc
 {
 	int i;
 
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	if (dd->flags & QIB_DCA_ENABLED) {
+		dca_remove_requester(&dd->pcidev->dev);
+		dd->flags &= ~QIB_DCA_ENABLED;
+		dd->cspec->dca_ctrl = 0;
+		qib_write_kreg(dd, KREG_IDX(DCACtrlA), dd->cspec->dca_ctrl);
+	}
+#endif
+
 	qib_7322_free_irq(dd);
 	kfree(dd->cspec->cntrs);
 	kfree(dd->cspec->sendchkenable);
@@ -3068,6 +3344,53 @@ static irqreturn_t sdma_cleanup_intr(int
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+
+static void reset_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m)
+{
+	if (!m->dca)
+		return;
+	qib_devinfo(dd->pcidev,
+		"Disabling notifier on HCA %d irq %d\n",
+		dd->unit,
+		m->msix.vector);
+	irq_set_affinity_notifier(
+		m->msix.vector,
+		NULL);
+	m->notifier = NULL;
+}
+
+static void setup_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m)
+{
+	struct qib_irq_notify *n;
+
+	if (!m->dca)
+		return;
+	n = kzalloc(sizeof(*n), GFP_KERNEL);
+	if (n) {
+		int ret;
+
+		m->notifier = n;
+		n->notify.irq = m->msix.vector;
+		n->notify.notify = qib_irq_notifier_notify;
+		n->notify.release = qib_irq_notifier_release;
+		n->arg = m->arg;
+		n->rcv = m->rcv;
+		qib_devinfo(dd->pcidev,
+			"set notifier irq %d rcv %d notify %p\n",
+			n->notify.irq, n->rcv, &n->notify);
+		ret = irq_set_affinity_notifier(
+				n->notify.irq,
+				&n->notify);
+		if (ret) {
+			m->notifier = NULL;
+			kfree(n);
+		}
+	}
+}
+
+#endif
+
 /*
  * Set up our chip-specific interrupt handler.
  * The interrupt type has already been setup, so
@@ -3149,6 +3472,9 @@ try_intx:
 		void *arg;
 		u64 val;
 		int lsb, reg, sh;
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+		int dca = 0;
+#endif
 
 		dd->cspec->msix_entries[msixnum].
 			name[sizeof(dd->cspec->msix_entries[msixnum].name) - 1]
@@ -3161,6 +3487,9 @@ try_intx:
 				arg = dd->pport + irq_table[i].port - 1;
 			} else
 				arg = dd;
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+			dca = irq_table[i].dca;
+#endif
 			lsb = irq_table[i].lsb;
 			handler = irq_table[i].handler;
 			snprintf(dd->cspec->msix_entries[msixnum].name,
@@ -3178,6 +3507,9 @@ try_intx:
 				continue;
 			if (qib_krcvq01_no_msi && ctxt < 2)
 				continue;
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+			dca = 1;
+#endif
 			lsb = QIB_I_RCVAVAIL_LSB + ctxt;
 			handler = qib_7322pintr;
 			snprintf(dd->cspec->msix_entries[msixnum].name,
@@ -3203,6 +3535,11 @@ try_intx:
 			goto try_intx;
 		}
 		dd->cspec->msix_entries[msixnum].arg = arg;
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+		dd->cspec->msix_entries[msixnum].dca = dca;
+		dd->cspec->msix_entries[msixnum].rcv =
+			handler == qib_7322pintr;
+#endif
 		if (lsb >= 0) {
 			reg = lsb / IBA7322_REDIRECT_VEC_PER_REG;
 			sh = (lsb % IBA7322_REDIRECT_VEC_PER_REG) *
@@ -6452,6 +6789,86 @@ static void qib_sdma_set_7322_desc_cnt(s
 	qib_write_kreg_port(ppd, krp_senddmadesccnt, cnt);
 }
 
+/*
+ * sdma_lock should be acquired before calling this routine
+ */
+static void dump_sdma_7322_state(struct qib_pportdata *ppd)
+{
+	u64 reg, reg1, reg2;
+
+	reg = qib_read_kreg_port(ppd, krp_senddmastatus);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmastatus: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_sendctrl);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA sendctrl: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmabase);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmabase: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmabufmask0);
+	reg1 = qib_read_kreg_port(ppd, krp_senddmabufmask1);
+	reg2 = qib_read_kreg_port(ppd, krp_senddmabufmask2);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmabufmask 0:%llx  1:%llx  2:%llx\n",
+		 reg, reg1, reg2);
+
+	/* get bufuse bits, clear them, and print them again if non-zero */
+	reg = qib_read_kreg_port(ppd, krp_senddmabuf_use0);
+	qib_write_kreg_port(ppd, krp_senddmabuf_use0, reg);
+	reg1 = qib_read_kreg_port(ppd, krp_senddmabuf_use1);
+	qib_write_kreg_port(ppd, krp_senddmabuf_use0, reg1);
+	reg2 = qib_read_kreg_port(ppd, krp_senddmabuf_use2);
+	qib_write_kreg_port(ppd, krp_senddmabuf_use0, reg2);
+	/* 0 and 1 should always be zero, so print as short form */
+	qib_dev_porterr(ppd->dd, ppd->port,
+		 "SDMA current senddmabuf_use 0:%llx  1:%llx  2:%llx\n",
+		 reg, reg1, reg2);
+	reg = qib_read_kreg_port(ppd, krp_senddmabuf_use0);
+	reg1 = qib_read_kreg_port(ppd, krp_senddmabuf_use1);
+	reg2 = qib_read_kreg_port(ppd, krp_senddmabuf_use2);
+	/* 0 and 1 should always be zero, so print as short form */
+	qib_dev_porterr(ppd->dd, ppd->port,
+		 "SDMA cleared senddmabuf_use 0:%llx  1:%llx  2:%llx\n",
+		 reg, reg1, reg2);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmatail);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmatail: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmahead);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmahead: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmaheadaddr);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmaheadaddr: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmalengen);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmalengen: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmadesccnt);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmadesccnt: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmaidlecnt);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmaidlecnt: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmaprioritythld);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmapriorityhld: 0x%016llx\n", reg);
+
+	reg = qib_read_kreg_port(ppd, krp_senddmareloadcnt);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA senddmareloadcnt: 0x%016llx\n", reg);
+
+	dump_sdma_state(ppd);
+}
+
 static struct sdma_set_state_action sdma_7322_action_table[] = {
 	[qib_sdma_state_s00_hw_down] = {
 		.go_s99_running_tofalse = 1,
@@ -6885,6 +7302,9 @@ struct qib_devdata *qib_init_iba7322_fun
 	dd->f_sdma_init_early   = qib_7322_sdma_init_early;
 	dd->f_writescratch      = writescratch;
 	dd->f_tempsense_rd	= qib_7322_tempsense_rd;
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	dd->f_notify_dca	= qib_7322_notify_dca;
+#endif
 	/*
 	 * Do remaining PCIe setup and save PCIe values in dd.
 	 * Any error printing is already done by the init code.
@@ -6921,7 +7341,7 @@ struct qib_devdata *qib_init_iba7322_fun
 		actual_cnt -= dd->num_pports;
 
 	tabsize = actual_cnt;
-	dd->cspec->msix_entries = kmalloc(tabsize *
+	dd->cspec->msix_entries = kzalloc(tabsize *
 			sizeof(struct qib_msix_entry), GFP_KERNEL);
 	if (!dd->cspec->msix_entries) {
 		qib_dev_err(dd, "No memory for MSIx table\n");
@@ -6941,7 +7361,13 @@ struct qib_devdata *qib_init_iba7322_fun
 
 	/* clear diagctrl register, in case diags were running and crashed */
 	qib_write_kreg(dd, kr_hwdiagctrl, 0);
-
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	if (!dca_add_requester(&pdev->dev)) {
+		qib_devinfo(dd->pcidev, "DCA enabled\n");
+		dd->flags |= QIB_DCA_ENABLED;
+		qib_setup_dca(dd);
+	}
+#endif
 	goto bail;
 
 bail_cleanup:
@@ -7156,15 +7582,20 @@ static const struct txdds_ent txdds_extr
 	{  0, 0, 0,  1 },	/* QMH7342 backplane settings */
 	{  0, 0, 0,  2 },	/* QMH7342 backplane settings */
 	{  0, 0, 0,  2 },	/* QMH7342 backplane settings */
-	{  0, 0, 0, 11 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 11 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 11 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 11 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 11 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 11 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 11 },	/* QME7342 backplane settings */
 	{  0, 0, 0,  3 },	/* QMH7342 backplane settings */
 	{  0, 0, 0,  4 },	/* QMH7342 backplane settings */
+	{  0, 1, 4, 15 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 3, 15 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0, 12 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0, 11 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0,  9 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0, 14 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 2, 15 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0, 11 },       /* QME7342 backplane settings 1.1 */
+	{  0, 1, 0,  7 },       /* QME7342 backplane settings 1.1 */
+	{  0, 1, 0,  9 },       /* QME7342 backplane settings 1.1 */
+	{  0, 1, 0,  6 },       /* QME7342 backplane settings 1.1 */
+	{  0, 1, 0,  8 },       /* QME7342 backplane settings 1.1 */
 };
 
 static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = {
@@ -7173,15 +7604,20 @@ static const struct txdds_ent txdds_extr
 	{  0, 0, 0,  7 },	/* QMH7342 backplane settings */
 	{  0, 0, 0,  8 },	/* QMH7342 backplane settings */
 	{  0, 0, 0,  8 },	/* QMH7342 backplane settings */
-	{  0, 0, 0, 13 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 13 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 13 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 13 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 13 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 13 },	/* QME7342 backplane settings */
-	{  0, 0, 0, 13 },	/* QME7342 backplane settings */
 	{  0, 0, 0,  9 },	/* QMH7342 backplane settings */
 	{  0, 0, 0, 10 },	/* QMH7342 backplane settings */
+	{  0, 1, 4, 15 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 3, 15 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0, 12 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0, 11 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0,  9 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0, 14 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 2, 15 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1, 0, 11 },       /* QME7342 backplane settings 1.1 */
+	{  0, 1, 0,  7 },       /* QME7342 backplane settings 1.1 */
+	{  0, 1, 0,  9 },       /* QME7342 backplane settings 1.1 */
+	{  0, 1, 0,  6 },       /* QME7342 backplane settings 1.1 */
+	{  0, 1, 0,  8 },       /* QME7342 backplane settings 1.1 */
 };
 
 static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = {
@@ -7190,15 +7626,20 @@ static const struct txdds_ent txdds_extr
 	{  0, 1,  0,  5 },	/* QMH7342 backplane settings */
 	{  0, 1,  0,  6 },	/* QMH7342 backplane settings */
 	{  0, 1,  0,  8 },	/* QMH7342 backplane settings */
-	{  0, 1, 12, 10 },	/* QME7342 backplane setting */
-	{  0, 1, 12, 11 },	/* QME7342 backplane setting */
-	{  0, 1, 12, 12 },	/* QME7342 backplane setting */
-	{  0, 1, 12, 14 },	/* QME7342 backplane setting */
-	{  0, 1, 12,  6 },	/* QME7342 backplane setting */
-	{  0, 1, 12,  7 },	/* QME7342 backplane setting */
-	{  0, 1, 12,  8 },	/* QME7342 backplane setting */
 	{  0, 1,  0, 10 },	/* QMH7342 backplane settings */
 	{  0, 1,  0, 12 },	/* QMH7342 backplane settings */
+	{  0, 1,  4, 15 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1,  3, 15 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1,  0, 12 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1,  0, 11 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1,  0,  9 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1,  0, 14 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1,  2, 15 },	/* QME7342 backplane settings 1.0 */
+	{  0, 1,  0, 11 },      /* QME7342 backplane settings 1.1 */
+	{  0, 1,  0,  7 },      /* QME7342 backplane settings 1.1 */
+	{  0, 1,  0,  9 },      /* QME7342 backplane settings 1.1 */
+	{  0, 1,  0,  6 },      /* QME7342 backplane settings 1.1 */
+	{  0, 1,  0,  8 },      /* QME7342 backplane settings 1.1 */
 };
 
 static const struct txdds_ent txdds_extra_mfg[TXDDS_MFG_SZ] = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_init.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_init.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_init.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,10 +39,17 @@
 #include <linux/idr.h>
 #include <linux/module.h>
 #include <linux/printk.h>
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+#include <linux/dca.h>
+#endif
 
 #include "qib.h"
 #include "qib_common.h"
 #include "qib_mad.h"
+#ifdef CONFIG_DEBUG_FS
+#include "qib_debugfs.h"
+#include "qib_verbs.h"
+#endif
 
 #undef pr_fmt
 #define pr_fmt(fmt) QIB_DRV_NAME ": " fmt
@@ -64,6 +71,11 @@ ushort qib_cfgctxts;
 module_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO);
 MODULE_PARM_DESC(cfgctxts, "Set max number of contexts to use");
 
+unsigned qib_numa_aware;
+module_param_named(numa_aware, qib_numa_aware, uint, S_IRUGO);
+MODULE_PARM_DESC(numa_aware,
+	"0 -> PSM allocation close to HCA, 1 -> PSM allocation local to process");
+
 /*
  * If set, do not write to any regs if avoidable, hack to allow
  * check for deranged default register values.
@@ -89,8 +101,6 @@ unsigned qib_wc_pat = 1; /* default (1)
 module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO);
 MODULE_PARM_DESC(wc_pat, "enable write-combining via PAT mechanism");
 
-struct workqueue_struct *qib_cq_wq;
-
 static void verify_interrupt(unsigned long);
 
 static struct idr qib_unit_table;
@@ -121,6 +131,11 @@ int qib_create_ctxts(struct qib_devdata
 {
 	unsigned i;
 	int ret;
+	int local_node_id = pcibus_to_node(dd->pcidev->bus);
+
+	if (local_node_id < 0)
+		local_node_id = numa_node_id();
+	dd->assigned_node_id = local_node_id;
 
 	/*
 	 * Allocate full ctxtcnt array, rather than just cfgctxts, because
@@ -143,7 +158,8 @@ int qib_create_ctxts(struct qib_devdata
 			continue;
 
 		ppd = dd->pport + (i % dd->num_pports);
-		rcd = qib_create_ctxtdata(ppd, i);
+
+		rcd = qib_create_ctxtdata(ppd, i, dd->assigned_node_id);
 		if (!rcd) {
 			qib_dev_err(dd,
 				"Unable to allocate ctxtdata for Kernel ctxt, failing\n");
@@ -161,20 +177,33 @@ done:
 /*
  * Common code for user and kernel context setup.
  */
-struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *ppd, u32 ctxt)
+struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *ppd, u32 ctxt,
+	int node_id)
 {
 	struct qib_devdata *dd = ppd->dd;
 	struct qib_ctxtdata *rcd;
 
-	rcd = kzalloc(sizeof(*rcd), GFP_KERNEL);
+	rcd = kzalloc_node(sizeof(*rcd), GFP_KERNEL, node_id);
 	if (rcd) {
 		INIT_LIST_HEAD(&rcd->qp_wait_list);
+		rcd->node_id = node_id;
 		rcd->ppd = ppd;
 		rcd->dd = dd;
 		rcd->cnt = 1;
 		rcd->ctxt = ctxt;
 		dd->rcd[ctxt] = rcd;
-
+#ifdef CONFIG_DEBUG_FS
+		if (ctxt < dd->first_user_ctxt) { /* N/A for PSM contexts */
+			rcd->opstats = kzalloc_node(sizeof(*rcd->opstats),
+				GFP_KERNEL, node_id);
+			if (!rcd->opstats) {
+				kfree(rcd);
+				qib_dev_err(dd,
+					"Unable to allocate per ctxt stats buffer\n");
+				return NULL;
+			}
+		}
+#endif
 		dd->f_init_ctxt(rcd);
 
 		/*
@@ -429,6 +458,7 @@ static int loadtime_init(struct qib_devd
 	dd->intrchk_timer.function = verify_interrupt;
 	dd->intrchk_timer.data = (unsigned long) dd;
 
+	ret = qib_cq_init(dd);
 done:
 	return ret;
 }
@@ -944,6 +974,10 @@ void qib_free_ctxtdata(struct qib_devdat
 	vfree(rcd->subctxt_uregbase);
 	vfree(rcd->subctxt_rcvegrbuf);
 	vfree(rcd->subctxt_rcvhdr_base);
+#ifdef CONFIG_DEBUG_FS
+	kfree(rcd->opstats);
+	rcd->opstats = NULL;
+#endif
 	kfree(rcd);
 }
 
@@ -1033,7 +1067,6 @@ done:
 	dd->f_set_armlaunch(dd, 1);
 }
 
-
 void qib_free_devdata(struct qib_devdata *dd)
 {
 	unsigned long flags;
@@ -1043,6 +1076,9 @@ void qib_free_devdata(struct qib_devdata
 	list_del(&dd->list);
 	spin_unlock_irqrestore(&qib_devs_lock, flags);
 
+#ifdef CONFIG_DEBUG_FS
+	qib_dbg_ibdev_exit(&dd->verbs_dev);
+#endif
 	ib_dealloc_device(&dd->verbs_dev.ibdev);
 }
 
@@ -1066,6 +1102,10 @@ struct qib_devdata *qib_alloc_devdata(st
 		goto bail;
 	}
 
+#ifdef CONFIG_DEBUG_FS
+	qib_dbg_ibdev_init(&dd->verbs_dev);
+#endif
+
 	idr_preload(GFP_KERNEL);
 	spin_lock_irqsave(&qib_devs_lock, flags);
 
@@ -1081,6 +1121,9 @@ struct qib_devdata *qib_alloc_devdata(st
 	if (ret < 0) {
 		qib_early_err(&pdev->dev,
 			      "Could not allocate unit ID: error %d\n", -ret);
+#ifdef CONFIG_DEBUG_FS
+		qib_dbg_ibdev_exit(&dd->verbs_dev);
+#endif
 		ib_dealloc_device(&dd->verbs_dev.ibdev);
 		dd = ERR_PTR(ret);
 		goto bail;
@@ -1158,6 +1201,35 @@ struct pci_driver qib_driver = {
 	.err_handler = &qib_pci_err_handler,
 };
 
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+
+static int qib_notify_dca(struct notifier_block *, unsigned long, void *);
+static struct notifier_block dca_notifier = {
+	.notifier_call  = qib_notify_dca,
+	.next           = NULL,
+	.priority       = 0
+};
+
+static int qib_notify_dca_device(struct device *device, void *data)
+{
+	struct qib_devdata *dd = dev_get_drvdata(device);
+	unsigned long event = *(unsigned long *)data;
+
+	return dd->f_notify_dca(dd, event);
+}
+
+static int qib_notify_dca(struct notifier_block *nb, unsigned long event,
+					  void *p)
+{
+	int rval;
+
+	rval = driver_for_each_device(&qib_driver.driver, NULL,
+				      &event, qib_notify_dca_device);
+	return rval ? NOTIFY_BAD : NOTIFY_DONE;
+}
+
+#endif
+
 /*
  * Do all the generic driver unit- and chip-independent memory
  * allocation and initialization.
@@ -1170,22 +1242,22 @@ static int __init qlogic_ib_init(void)
 	if (ret)
 		goto bail;
 
-	qib_cq_wq = create_singlethread_workqueue("qib_cq");
-	if (!qib_cq_wq) {
-		ret = -ENOMEM;
-		goto bail_dev;
-	}
-
 	/*
 	 * These must be called before the driver is registered with
 	 * the PCI subsystem.
 	 */
 	idr_init(&qib_unit_table);
 
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	dca_register_notify(&dca_notifier);
+#endif
+#ifdef CONFIG_DEBUG_FS
+	qib_dbg_init();
+#endif
 	ret = pci_register_driver(&qib_driver);
 	if (ret < 0) {
 		pr_err("Unable to register driver: error %d\n", -ret);
-		goto bail_unit;
+		goto bail_dev;
 	}
 
 	/* not fatal if it doesn't work */
@@ -1193,10 +1265,14 @@ static int __init qlogic_ib_init(void)
 		pr_err("Unable to register ipathfs\n");
 	goto bail; /* all OK */
 
-bail_unit:
-	idr_destroy(&qib_unit_table);
-	destroy_workqueue(qib_cq_wq);
 bail_dev:
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	dca_unregister_notify(&dca_notifier);
+#endif
+#ifdef CONFIG_DEBUG_FS
+	qib_dbg_exit();
+#endif
+	idr_destroy(&qib_unit_table);
 	qib_dev_cleanup();
 bail:
 	return ret;
@@ -1217,9 +1293,13 @@ static void __exit qlogic_ib_cleanup(voi
 			"Unable to cleanup counter filesystem: error %d\n",
 			-ret);
 
+#ifdef CONFIG_INFINIBAND_QIB_DCA
+	dca_unregister_notify(&dca_notifier);
+#endif
 	pci_unregister_driver(&qib_driver);
-
-	destroy_workqueue(qib_cq_wq);
+#ifdef CONFIG_DEBUG_FS
+	qib_dbg_exit();
+#endif
 
 	qib_cpulist_count = 0;
 	kfree(qib_cpulist);
@@ -1270,7 +1350,7 @@ static void cleanup_device_data(struct q
 	if (dd->pageshadow) {
 		struct page **tmpp = dd->pageshadow;
 		dma_addr_t *tmpd = dd->physshadow;
-		int i, cnt = 0;
+		int i;
 
 		for (ctxt = 0; ctxt < dd->cfgctxts; ctxt++) {
 			int ctxt_tidbase = ctxt * dd->rcvtidcnt;
@@ -1283,13 +1363,13 @@ static void cleanup_device_data(struct q
 					       PAGE_SIZE, PCI_DMA_FROMDEVICE);
 				qib_release_user_pages(&tmpp[i], 1);
 				tmpp[i] = NULL;
-				cnt++;
 			}
 		}
 
-		tmpp = dd->pageshadow;
 		dd->pageshadow = NULL;
 		vfree(tmpp);
+		dd->physshadow = NULL;
+		vfree(tmpd);
 	}
 
 	/*
@@ -1311,6 +1391,7 @@ static void cleanup_device_data(struct q
 	}
 	kfree(tmp);
 	kfree(dd->boardname);
+	qib_cq_exit(dd);
 }
 
 /*
@@ -1483,6 +1564,7 @@ static void qib_remove_one(struct pci_de
 int qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd)
 {
 	unsigned amt;
+	int old_node_id;
 
 	if (!rcd->rcvhdrq) {
 		dma_addr_t phys_hdrqtail;
@@ -1492,9 +1574,13 @@ int qib_create_rcvhdrq(struct qib_devdat
 			    sizeof(u32), PAGE_SIZE);
 		gfp_flags = (rcd->ctxt >= dd->first_user_ctxt) ?
 			GFP_USER : GFP_KERNEL;
+
+		old_node_id = dev_to_node(&dd->pcidev->dev);
+		set_dev_node(&dd->pcidev->dev, rcd->node_id);
 		rcd->rcvhdrq = dma_alloc_coherent(
 			&dd->pcidev->dev, amt, &rcd->rcvhdrq_phys,
 			gfp_flags | __GFP_COMP);
+		set_dev_node(&dd->pcidev->dev, old_node_id);
 
 		if (!rcd->rcvhdrq) {
 			qib_dev_err(dd,
@@ -1510,9 +1596,11 @@ int qib_create_rcvhdrq(struct qib_devdat
 		}
 
 		if (!(dd->flags & QIB_NODMA_RTAIL)) {
+			set_dev_node(&dd->pcidev->dev, rcd->node_id);
 			rcd->rcvhdrtail_kvaddr = dma_alloc_coherent(
 				&dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail,
 				gfp_flags);
+			set_dev_node(&dd->pcidev->dev, old_node_id);
 			if (!rcd->rcvhdrtail_kvaddr)
 				goto bail_free;
 			rcd->rcvhdrqtailaddr_phys = phys_hdrqtail;
@@ -1556,6 +1644,7 @@ int qib_setup_eagerbufs(struct qib_ctxtd
 	unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff;
 	size_t size;
 	gfp_t gfp_flags;
+	int old_node_id;
 
 	/*
 	 * GFP_USER, but without GFP_FS, so buffer cache can be
@@ -1574,25 +1663,29 @@ int qib_setup_eagerbufs(struct qib_ctxtd
 	size = rcd->rcvegrbuf_size;
 	if (!rcd->rcvegrbuf) {
 		rcd->rcvegrbuf =
-			kzalloc(chunk * sizeof(rcd->rcvegrbuf[0]),
-				GFP_KERNEL);
+			kzalloc_node(chunk * sizeof(rcd->rcvegrbuf[0]),
+				GFP_KERNEL, rcd->node_id);
 		if (!rcd->rcvegrbuf)
 			goto bail;
 	}
 	if (!rcd->rcvegrbuf_phys) {
 		rcd->rcvegrbuf_phys =
-			kmalloc(chunk * sizeof(rcd->rcvegrbuf_phys[0]),
-				GFP_KERNEL);
+			kmalloc_node(chunk * sizeof(rcd->rcvegrbuf_phys[0]),
+				GFP_KERNEL, rcd->node_id);
 		if (!rcd->rcvegrbuf_phys)
 			goto bail_rcvegrbuf;
 	}
 	for (e = 0; e < rcd->rcvegrbuf_chunks; e++) {
 		if (rcd->rcvegrbuf[e])
 			continue;
+
+		old_node_id = dev_to_node(&dd->pcidev->dev);
+		set_dev_node(&dd->pcidev->dev, rcd->node_id);
 		rcd->rcvegrbuf[e] =
 			dma_alloc_coherent(&dd->pcidev->dev, size,
 					   &rcd->rcvegrbuf_phys[e],
 					   gfp_flags);
+		set_dev_node(&dd->pcidev->dev, old_node_id);
 		if (!rcd->rcvegrbuf[e])
 			goto bail_rcvegrbuf_phys;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_qp.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_qp.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_qp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_qp.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2012, 2013 Intel Corporation.  All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation.  * All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -35,6 +35,9 @@
 #include <linux/err.h>
 #include <linux/vmalloc.h>
 #include <linux/jhash.h>
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+#endif
 
 #include "qib.h"
 
@@ -222,8 +225,8 @@ static void insert_qp(struct qib_ibdev *
 	unsigned long flags;
 	unsigned n = qpn_hash(dev, qp->ibqp.qp_num);
 
-	spin_lock_irqsave(&dev->qpt_lock, flags);
 	atomic_inc(&qp->refcount);
+	spin_lock_irqsave(&dev->qpt_lock, flags);
 
 	if (qp->ibqp.qp_num == 0)
 		rcu_assign_pointer(ibp->qp0, qp);
@@ -235,7 +238,6 @@ static void insert_qp(struct qib_ibdev *
 	}
 
 	spin_unlock_irqrestore(&dev->qpt_lock, flags);
-	synchronize_rcu();
 }
 
 /*
@@ -247,36 +249,39 @@ static void remove_qp(struct qib_ibdev *
 	struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
 	unsigned n = qpn_hash(dev, qp->ibqp.qp_num);
 	unsigned long flags;
+	int removed = 1;
 
 	spin_lock_irqsave(&dev->qpt_lock, flags);
 
 	if (rcu_dereference_protected(ibp->qp0,
 			lockdep_is_held(&dev->qpt_lock)) == qp) {
-		atomic_dec(&qp->refcount);
 		rcu_assign_pointer(ibp->qp0, NULL);
 	} else if (rcu_dereference_protected(ibp->qp1,
 			lockdep_is_held(&dev->qpt_lock)) == qp) {
-		atomic_dec(&qp->refcount);
 		rcu_assign_pointer(ibp->qp1, NULL);
 	} else {
 		struct qib_qp *q;
 		struct qib_qp __rcu **qpp;
 
+		removed = 0;
 		qpp = &dev->qp_table[n];
 		for (; (q = rcu_dereference_protected(*qpp,
 				lockdep_is_held(&dev->qpt_lock))) != NULL;
 				qpp = &q->next)
 			if (q == qp) {
-				atomic_dec(&qp->refcount);
 				rcu_assign_pointer(*qpp,
 					rcu_dereference_protected(qp->next,
 					 lockdep_is_held(&dev->qpt_lock)));
+				removed = 1;
 				break;
 			}
 	}
 
 	spin_unlock_irqrestore(&dev->qpt_lock, flags);
-	synchronize_rcu();
+	if (removed) {
+		synchronize_rcu();
+		atomic_dec(&qp->refcount);
+	}
 }
 
 /**
@@ -334,26 +339,25 @@ struct qib_qp *qib_lookup_qpn(struct qib
 {
 	struct qib_qp *qp = NULL;
 
+	rcu_read_lock();
 	if (unlikely(qpn <= 1)) {
-		rcu_read_lock();
 		if (qpn == 0)
 			qp = rcu_dereference(ibp->qp0);
 		else
 			qp = rcu_dereference(ibp->qp1);
+		if (qp)
+			atomic_inc(&qp->refcount);
 	} else {
 		struct qib_ibdev *dev = &ppd_from_ibp(ibp)->dd->verbs_dev;
 		unsigned n = qpn_hash(dev, qpn);
 
-		rcu_read_lock();
 		for (qp = rcu_dereference(dev->qp_table[n]); qp;
 			qp = rcu_dereference(qp->next))
-			if (qp->ibqp.qp_num == qpn)
+			if (qp->ibqp.qp_num == qpn) {
+				atomic_inc(&qp->refcount);
 				break;
+			}
 	}
-	if (qp)
-		if (unlikely(!atomic_inc_not_zero(&qp->refcount)))
-			qp = NULL;
-
 	rcu_read_unlock();
 	return qp;
 }
@@ -1286,3 +1290,94 @@ void qib_get_credit(struct qib_qp *qp, u
 		}
 	}
 }
+
+#ifdef CONFIG_DEBUG_FS
+
+struct qib_qp_iter {
+	struct qib_ibdev *dev;
+	struct qib_qp *qp;
+	int n;
+};
+
+struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev)
+{
+	struct qib_qp_iter *iter;
+
+	iter = kzalloc(sizeof(*iter), GFP_KERNEL);
+	if (!iter)
+		return NULL;
+
+	iter->dev = dev;
+	if (qib_qp_iter_next(iter)) {
+		kfree(iter);
+		return NULL;
+	}
+
+	return iter;
+}
+
+int qib_qp_iter_next(struct qib_qp_iter *iter)
+{
+	struct qib_ibdev *dev = iter->dev;
+	int n = iter->n;
+	int ret = 1;
+	struct qib_qp *pqp = iter->qp;
+	struct qib_qp *qp;
+
+	rcu_read_lock();
+	for (; n < dev->qp_table_size; n++) {
+		if (pqp)
+			qp = rcu_dereference(pqp->next);
+		else
+			qp = rcu_dereference(dev->qp_table[n]);
+		pqp = qp;
+		if (qp) {
+			if (iter->qp)
+				atomic_dec(&iter->qp->refcount);
+			atomic_inc(&qp->refcount);
+			rcu_read_unlock();
+			iter->qp = qp;
+			iter->n = n;
+			return 0;
+		}
+	}
+	rcu_read_unlock();
+	if (iter->qp)
+		atomic_dec(&iter->qp->refcount);
+	return ret;
+}
+
+static const char * const qp_type_str[] = {
+	"SMI", "GSI", "RC", "UC", "UD",
+};
+
+void qib_qp_iter_print(struct seq_file *s, struct qib_qp_iter *iter)
+{
+	struct qib_swqe *wqe;
+	struct qib_qp *qp = iter->qp;
+
+	wqe = get_swqe_ptr(qp, qp->s_last);
+	seq_printf(s,
+		   "N %d QP%u %s %u %u %u f=%x %u %u %u %u %u PSN %x %x %x %x %x (%u %u %u %u %u %u) QP%u LID %x\n",
+		   iter->n,
+		   qp->ibqp.qp_num,
+		   qp_type_str[qp->ibqp.qp_type],
+		   qp->state,
+		   wqe->wr.opcode,
+		   qp->s_hdrwords,
+		   qp->s_flags,
+		   atomic_read(&qp->s_dma_busy),
+		   !list_empty(&qp->iowait),
+		   qp->timeout,
+		   wqe->ssn,
+		   qp->s_lsn,
+		   qp->s_last_psn,
+		   qp->s_psn, qp->s_next_psn,
+		   qp->s_sending_psn, qp->s_sending_hpsn,
+		   qp->s_last, qp->s_acked, qp->s_cur,
+		   qp->s_tail, qp->s_head, qp->s_size,
+		   qp->remote_qpn,
+		   qp->remote_ah_attr.dlid);
+}
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_sdma.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_sdma.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_sdma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_sdma.c	2013-08-25 20:43:22.000000000 -0400
@@ -708,6 +708,62 @@ unlock:
 	return ret;
 }
 
+/*
+ * sdma_lock should be acquired before calling this routine
+ */
+void dump_sdma_state(struct qib_pportdata *ppd)
+{
+	struct qib_sdma_desc *descq;
+	struct qib_sdma_txreq *txp, *txpnext;
+	__le64 *descqp;
+	u64 desc[2];
+	u64 addr;
+	u16 gen, dwlen, dwoffset;
+	u16 head, tail, cnt;
+
+	head = ppd->sdma_descq_head;
+	tail = ppd->sdma_descq_tail;
+	cnt = qib_sdma_descq_freecnt(ppd);
+	descq = ppd->sdma_descq;
+
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA ppd->sdma_descq_head: %u\n", head);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA ppd->sdma_descq_tail: %u\n", tail);
+	qib_dev_porterr(ppd->dd, ppd->port,
+		"SDMA sdma_descq_freecnt: %u\n", cnt);
+
+	/* print info for each entry in the descriptor queue */
+	while (head != tail) {
+		char flags[6] = { 'x', 'x', 'x', 'x', 'x', 0 };
+
+		descqp = &descq[head].qw[0];
+		desc[0] = le64_to_cpu(descqp[0]);
+		desc[1] = le64_to_cpu(descqp[1]);
+		flags[0] = (desc[0] & 1<<15) ? 'I' : '-';
+		flags[1] = (desc[0] & 1<<14) ? 'L' : 'S';
+		flags[2] = (desc[0] & 1<<13) ? 'H' : '-';
+		flags[3] = (desc[0] & 1<<12) ? 'F' : '-';
+		flags[4] = (desc[0] & 1<<11) ? 'L' : '-';
+		addr = (desc[1] << 32) | ((desc[0] >> 32) & 0xfffffffcULL);
+		gen = (desc[0] >> 30) & 3ULL;
+		dwlen = (desc[0] >> 14) & (0x7ffULL << 2);
+		dwoffset = (desc[0] & 0x7ffULL) << 2;
+		qib_dev_porterr(ppd->dd, ppd->port,
+			"SDMA sdmadesc[%u]: flags:%s addr:0x%016llx gen:%u len:%u bytes offset:%u bytes\n",
+			 head, flags, addr, gen, dwlen, dwoffset);
+		if (++head == ppd->sdma_descq_cnt)
+			head = 0;
+	}
+
+	/* print dma descriptor indices from the TX requests */
+	list_for_each_entry_safe(txp, txpnext, &ppd->sdma_activelist,
+				 list)
+		qib_dev_porterr(ppd->dd, ppd->port,
+			"SDMA txp->start_idx: %u txp->next_descq_idx: %u\n",
+			txp->start_idx, txp->next_descq_idx);
+}
+
 void qib_sdma_process_event(struct qib_pportdata *ppd,
 	enum qib_sdma_events event)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_verbs.c linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_verbs.c
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_verbs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_verbs.c	2013-08-25 20:43:22.000000000 -0400
@@ -645,9 +645,11 @@ void qib_ib_rcv(struct qib_ctxtdata *rcd
 	} else
 		goto drop;
 
-	opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
-	ibp->opstats[opcode & 0x7f].n_bytes += tlen;
-	ibp->opstats[opcode & 0x7f].n_packets++;
+	opcode = (be32_to_cpu(ohdr->bth[0]) >> 24) & 0x7f;
+#ifdef CONFIG_DEBUG_FS
+	rcd->opstats->stats[opcode].n_bytes += tlen;
+	rcd->opstats->stats[opcode].n_packets++;
+#endif
 
 	/* Get the destination QP number. */
 	qp_num = be32_to_cpu(ohdr->bth[1]) & QIB_QPN_MASK;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_verbs.h linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_verbs.h
--- linux-libre-3.10-gnu/drivers/infiniband/hw/qib/qib_verbs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/hw/qib/qib_verbs.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2012, 2013 Intel Corporation.  All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -41,6 +41,7 @@
 #include <linux/interrupt.h>
 #include <linux/kref.h>
 #include <linux/workqueue.h>
+#include <linux/kthread.h>
 #include <linux/completion.h>
 #include <rdma/ib_pack.h>
 #include <rdma/ib_user_verbs.h>
@@ -267,7 +268,8 @@ struct qib_cq_wc {
  */
 struct qib_cq {
 	struct ib_cq ibcq;
-	struct work_struct comptask;
+	struct kthread_work comptask;
+	struct qib_devdata *dd;
 	spinlock_t lock; /* protect changes in this struct */
 	u8 notify;
 	u8 triggered;
@@ -658,6 +660,10 @@ struct qib_opcode_stats {
 	u64 n_bytes;            /* total number of bytes */
 };
 
+struct qib_opcode_stats_perctx {
+	struct qib_opcode_stats stats[128];
+};
+
 struct qib_ibport {
 	struct qib_qp __rcu *qp0;
 	struct qib_qp __rcu *qp1;
@@ -724,7 +730,6 @@ struct qib_ibport {
 	u8 vl_high_limit;
 	u8 sl_to_vl[16];
 
-	struct qib_opcode_stats opstats[128];
 };
 
 
@@ -768,6 +773,10 @@ struct qib_ibdev {
 	spinlock_t n_srqs_lock;
 	u32 n_mcast_grps_allocated; /* number of mcast groups allocated */
 	spinlock_t n_mcast_grps_lock;
+#ifdef CONFIG_DEBUG_FS
+	/* per HCA debugfs */
+	struct dentry *qib_ibdev_dbg;
+#endif
 };
 
 struct qib_verbs_counters {
@@ -832,8 +841,6 @@ static inline int qib_send_ok(struct qib
 		 !(qp->s_flags & QIB_S_ANY_WAIT_SEND));
 }
 
-extern struct workqueue_struct *qib_cq_wq;
-
 /*
  * This must be called with s_lock held.
  */
@@ -910,6 +917,18 @@ void qib_init_qpn_table(struct qib_devda
 
 void qib_free_qpn_table(struct qib_qpn_table *qpt);
 
+#ifdef CONFIG_DEBUG_FS
+
+struct qib_qp_iter;
+
+struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev);
+
+int qib_qp_iter_next(struct qib_qp_iter *iter);
+
+void qib_qp_iter_print(struct seq_file *s, struct qib_qp_iter *iter);
+
+#endif
+
 void qib_get_credit(struct qib_qp *qp, u32 aeth);
 
 unsigned qib_pkt_delay(u32 plen, u8 snd_mult, u8 rcv_mult);
@@ -972,6 +991,10 @@ int qib_query_srq(struct ib_srq *ibsrq,
 
 int qib_destroy_srq(struct ib_srq *ibsrq);
 
+int qib_cq_init(struct qib_devdata *dd);
+
+void qib_cq_exit(struct qib_devdata *dd);
+
 void qib_cq_enter(struct qib_cq *cq, struct ib_wc *entry, int sig);
 
 int qib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/Kconfig linux-libre-3.11-rc7-gnu/drivers/infiniband/Kconfig
--- linux-libre-3.10-gnu/drivers/infiniband/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -50,6 +50,7 @@ source "drivers/infiniband/hw/amso1100/K
 source "drivers/infiniband/hw/cxgb3/Kconfig"
 source "drivers/infiniband/hw/cxgb4/Kconfig"
 source "drivers/infiniband/hw/mlx4/Kconfig"
+source "drivers/infiniband/hw/mlx5/Kconfig"
 source "drivers/infiniband/hw/nes/Kconfig"
 source "drivers/infiniband/hw/ocrdma/Kconfig"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/Makefile linux-libre-3.11-rc7-gnu/drivers/infiniband/Makefile
--- linux-libre-3.10-gnu/drivers/infiniband/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -7,6 +7,7 @@ obj-$(CONFIG_INFINIBAND_AMSO1100)	+= hw/
 obj-$(CONFIG_INFINIBAND_CXGB3)		+= hw/cxgb3/
 obj-$(CONFIG_INFINIBAND_CXGB4)		+= hw/cxgb4/
 obj-$(CONFIG_MLX4_INFINIBAND)		+= hw/mlx4/
+obj-$(CONFIG_MLX5_INFINIBAND)		+= hw/mlx5/
 obj-$(CONFIG_INFINIBAND_NES)		+= hw/nes/
 obj-$(CONFIG_INFINIBAND_OCRDMA)		+= hw/ocrdma/
 obj-$(CONFIG_INFINIBAND_IPOIB)		+= ulp/ipoib/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- linux-libre-3.10-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2013-08-25 20:43:22.000000000 -0400
@@ -932,12 +932,47 @@ int ipoib_ib_dev_init(struct net_device
 	return 0;
 }
 
+/*
+ * Takes whatever value which is in pkey index 0 and updates priv->pkey
+ * returns 0 if the pkey value was changed.
+ */
+static inline int update_parent_pkey(struct ipoib_dev_priv *priv)
+{
+	int result;
+	u16 prev_pkey;
+
+	prev_pkey = priv->pkey;
+	result = ib_query_pkey(priv->ca, priv->port, 0, &priv->pkey);
+	if (result) {
+		ipoib_warn(priv, "ib_query_pkey port %d failed (ret = %d)\n",
+			   priv->port, result);
+		return result;
+	}
+
+	priv->pkey |= 0x8000;
+
+	if (prev_pkey != priv->pkey) {
+		ipoib_dbg(priv, "pkey changed from 0x%x to 0x%x\n",
+			  prev_pkey, priv->pkey);
+		/*
+		 * Update the pkey in the broadcast address, while making sure to set
+		 * the full membership bit, so that we join the right broadcast group.
+		 */
+		priv->dev->broadcast[8] = priv->pkey >> 8;
+		priv->dev->broadcast[9] = priv->pkey & 0xff;
+		return 0;
+	}
+
+	return 1;
+}
+
 static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
 				enum ipoib_flush_level level)
 {
 	struct ipoib_dev_priv *cpriv;
 	struct net_device *dev = priv->dev;
 	u16 new_index;
+	int result;
 
 	mutex_lock(&priv->vlan_mutex);
 
@@ -951,6 +986,10 @@ static void __ipoib_ib_dev_flush(struct
 	mutex_unlock(&priv->vlan_mutex);
 
 	if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) {
+		/* for non-child devices must check/update the pkey value here */
+		if (level == IPOIB_FLUSH_HEAVY &&
+		    !test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags))
+			update_parent_pkey(priv);
 		ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n");
 		return;
 	}
@@ -961,21 +1000,32 @@ static void __ipoib_ib_dev_flush(struct
 	}
 
 	if (level == IPOIB_FLUSH_HEAVY) {
-		if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) {
-			clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
-			ipoib_ib_dev_down(dev, 0);
-			ipoib_ib_dev_stop(dev, 0);
-			if (ipoib_pkey_dev_delay_open(dev))
+		/* child devices chase their origin pkey value, while non-child
+		 * (parent) devices should always takes what present in pkey index 0
+		 */
+		if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
+			if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) {
+				clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+				ipoib_ib_dev_down(dev, 0);
+				ipoib_ib_dev_stop(dev, 0);
+				if (ipoib_pkey_dev_delay_open(dev))
+					return;
+			}
+			/* restart QP only if P_Key index is changed */
+			if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) &&
+			    new_index == priv->pkey_index) {
+				ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n");
 				return;
+			}
+			priv->pkey_index = new_index;
+		} else {
+			result = update_parent_pkey(priv);
+			/* restart QP only if P_Key value changed */
+			if (result) {
+				ipoib_dbg(priv, "Not flushing - P_Key value not changed.\n");
+				return;
+			}
 		}
-
-		/* restart QP only if P_Key index is changed */
-		if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) &&
-		    new_index == priv->pkey_index) {
-			ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n");
-			return;
-		}
-		priv->pkey_index = new_index;
 	}
 
 	if (level == IPOIB_FLUSH_LIGHT) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- linux-libre-3.10-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/ipoib/ipoib_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1461,7 +1461,7 @@ static ssize_t create_child(struct devic
 	if (sscanf(buf, "%i", &pkey) != 1)
 		return -EINVAL;
 
-	if (pkey < 0 || pkey > 0xffff)
+	if (pkey <= 0 || pkey > 0xffff || pkey == 0x8000)
 		return -EINVAL;
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/ulp/ipoib/ipoib_netlink.c linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
--- linux-libre-3.10-gnu/drivers/infiniband/ulp/ipoib/ipoib_netlink.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/ipoib/ipoib_netlink.c	2013-08-25 20:43:22.000000000 -0400
@@ -119,6 +119,15 @@ static int ipoib_new_child_link(struct n
 	} else
 		child_pkey  = nla_get_u16(data[IFLA_IPOIB_PKEY]);
 
+	if (child_pkey == 0 || child_pkey == 0x8000)
+		return -EINVAL;
+
+	/*
+	 * Set the full membership bit, so that we join the right
+	 * broadcast group, etc.
+	 */
+	child_pkey |= 0x8000;
+
 	err = __ipoib_vlan_add(ppriv, netdev_priv(dev), child_pkey, IPOIB_RTNL_CHILD);
 
 	if (!err && data)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/ulp/isert/ib_isert.c linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/isert/ib_isert.c
--- linux-libre-3.10-gnu/drivers/infiniband/ulp/isert/ib_isert.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/isert/ib_isert.c	2013-08-25 20:43:22.000000000 -0400
@@ -388,6 +388,7 @@ isert_connect_request(struct rdma_cm_id
 	init_waitqueue_head(&isert_conn->conn_wait_comp_err);
 	kref_init(&isert_conn->conn_kref);
 	kref_get(&isert_conn->conn_kref);
+	mutex_init(&isert_conn->conn_mutex);
 
 	cma_id->context = isert_conn;
 	isert_conn->conn_cm_id = cma_id;
@@ -540,15 +541,32 @@ isert_disconnect_work(struct work_struct
 				struct isert_conn, conn_logout_work);
 
 	pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
-
+	mutex_lock(&isert_conn->conn_mutex);
 	isert_conn->state = ISER_CONN_DOWN;
 
 	if (isert_conn->post_recv_buf_count == 0 &&
 	    atomic_read(&isert_conn->post_send_buf_count) == 0) {
 		pr_debug("Calling wake_up(&isert_conn->conn_wait);\n");
-		wake_up(&isert_conn->conn_wait);
+		mutex_unlock(&isert_conn->conn_mutex);
+		goto wake_up;
+	}
+	if (!isert_conn->conn_cm_id) {
+		mutex_unlock(&isert_conn->conn_mutex);
+		isert_put_conn(isert_conn);
+		return;
+	}
+	if (!isert_conn->logout_posted) {
+		pr_debug("Calling rdma_disconnect for !logout_posted from"
+			 " isert_disconnect_work\n");
+		rdma_disconnect(isert_conn->conn_cm_id);
+		mutex_unlock(&isert_conn->conn_mutex);
+		iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+		goto wake_up;
 	}
+	mutex_unlock(&isert_conn->conn_mutex);
 
+wake_up:
+	wake_up(&isert_conn->conn_wait);
 	isert_put_conn(isert_conn);
 }
 
@@ -934,16 +952,11 @@ isert_handle_scsi_cmd(struct isert_conn
 	}
 
 sequence_cmd:
-	rc = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
+	rc = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
 
 	if (!rc && dump_payload == false && unsol_data)
 		iscsit_set_unsoliticed_dataout(cmd);
 
-	if (rc == CMDSN_ERROR_CANNOT_RECOVER)
-		return iscsit_add_reject_from_cmd(
-			   ISCSI_REASON_PROTOCOL_ERROR,
-			   1, 0, (unsigned char *)hdr, cmd);
-
 	return 0;
 }
 
@@ -1001,17 +1014,71 @@ isert_handle_iscsi_dataout(struct isert_
 }
 
 static int
+isert_handle_nop_out(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
+		     struct iser_rx_desc *rx_desc, unsigned char *buf)
+{
+	struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
+	struct iscsi_conn *conn = isert_conn->conn;
+	struct iscsi_nopout *hdr = (struct iscsi_nopout *)buf;
+	int rc;
+
+	rc = iscsit_setup_nop_out(conn, cmd, hdr);
+	if (rc < 0)
+		return rc;
+	/*
+	 * FIXME: Add support for NOPOUT payload using unsolicited RDMA payload
+	 */
+
+	return iscsit_process_nop_out(conn, cmd, hdr);
+}
+
+static int
+isert_handle_text_cmd(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
+		      struct iser_rx_desc *rx_desc, struct iscsi_text *hdr)
+{
+	struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
+	struct iscsi_conn *conn = isert_conn->conn;
+	u32 payload_length = ntoh24(hdr->dlength);
+	int rc;
+	unsigned char *text_in;
+
+	rc = iscsit_setup_text_cmd(conn, cmd, hdr);
+	if (rc < 0)
+		return rc;
+
+	text_in = kzalloc(payload_length, GFP_KERNEL);
+	if (!text_in) {
+		pr_err("Unable to allocate text_in of payload_length: %u\n",
+		       payload_length);
+		return -ENOMEM;
+	}
+	cmd->text_in_ptr = text_in;
+
+	memcpy(cmd->text_in_ptr, &rx_desc->data[0], payload_length);
+
+	return iscsit_process_text_cmd(conn, cmd, hdr);
+}
+
+static int
 isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
 		uint32_t read_stag, uint64_t read_va,
 		uint32_t write_stag, uint64_t write_va)
 {
 	struct iscsi_hdr *hdr = &rx_desc->iscsi_header;
 	struct iscsi_conn *conn = isert_conn->conn;
+	struct iscsi_session *sess = conn->sess;
 	struct iscsi_cmd *cmd;
 	struct isert_cmd *isert_cmd;
 	int ret = -EINVAL;
 	u8 opcode = (hdr->opcode & ISCSI_OPCODE_MASK);
 
+	if (sess->sess_ops->SessionType &&
+	   (!(opcode & ISCSI_OP_TEXT) || !(opcode & ISCSI_OP_LOGOUT))) {
+		pr_err("Got illegal opcode: 0x%02x in SessionType=Discovery,"
+		       " ignoring\n", opcode);
+		return 0;
+	}
+
 	switch (opcode) {
 	case ISCSI_OP_SCSI_CMD:
 		cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
@@ -1032,7 +1099,9 @@ isert_rx_opcode(struct isert_conn *isert
 		if (!cmd)
 			break;
 
-		ret = iscsit_handle_nop_out(conn, cmd, (unsigned char *)hdr);
+		isert_cmd = container_of(cmd, struct isert_cmd, iscsi_cmd);
+		ret = isert_handle_nop_out(isert_conn, isert_cmd,
+					   rx_desc, (unsigned char *)hdr);
 		break;
 	case ISCSI_OP_SCSI_DATA_OUT:
 		ret = isert_handle_iscsi_dataout(isert_conn, rx_desc,
@@ -1057,6 +1126,15 @@ isert_rx_opcode(struct isert_conn *isert
 						    SECONDS_FOR_LOGOUT_COMP *
 						    HZ);
 		break;
+	case ISCSI_OP_TEXT:
+		cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
+		if (!cmd)
+			break;
+
+		isert_cmd = container_of(cmd, struct isert_cmd, iscsi_cmd);
+		ret = isert_handle_text_cmd(isert_conn, isert_cmd,
+					    rx_desc, (struct iscsi_text *)hdr);
+		break;
 	default:
 		pr_err("Got unknown iSCSI OpCode: 0x%02x\n", opcode);
 		dump_stack();
@@ -1184,14 +1262,12 @@ isert_put_cmd(struct isert_cmd *isert_cm
 {
 	struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
 	struct isert_conn *isert_conn = isert_cmd->conn;
-	struct iscsi_conn *conn;
+	struct iscsi_conn *conn = isert_conn->conn;
 
 	pr_debug("Entering isert_put_cmd: %p\n", isert_cmd);
 
 	switch (cmd->iscsi_opcode) {
 	case ISCSI_OP_SCSI_CMD:
-		conn = isert_conn->conn;
-
 		spin_lock_bh(&conn->cmd_lock);
 		if (!list_empty(&cmd->i_conn_node))
 			list_del(&cmd->i_conn_node);
@@ -1201,16 +1277,19 @@ isert_put_cmd(struct isert_cmd *isert_cm
 			iscsit_stop_dataout_timer(cmd);
 
 		isert_unmap_cmd(isert_cmd, isert_conn);
-		/*
-		 * Fall-through
-		 */
+		transport_generic_free_cmd(&cmd->se_cmd, 0);
+		break;
 	case ISCSI_OP_SCSI_TMFUNC:
+		spin_lock_bh(&conn->cmd_lock);
+		if (!list_empty(&cmd->i_conn_node))
+			list_del(&cmd->i_conn_node);
+		spin_unlock_bh(&conn->cmd_lock);
+
 		transport_generic_free_cmd(&cmd->se_cmd, 0);
 		break;
 	case ISCSI_OP_REJECT:
 	case ISCSI_OP_NOOP_OUT:
-		conn = isert_conn->conn;
-
+	case ISCSI_OP_TEXT:
 		spin_lock_bh(&conn->cmd_lock);
 		if (!list_empty(&cmd->i_conn_node))
 			list_del(&cmd->i_conn_node);
@@ -1222,6 +1301,9 @@ isert_put_cmd(struct isert_cmd *isert_cm
 		 * associated cmd->se_cmd needs to be released.
 		 */
 		if (cmd->se_cmd.se_tfo != NULL) {
+			pr_debug("Calling transport_generic_free_cmd from"
+				 " isert_put_cmd for 0x%02x\n",
+				 cmd->iscsi_opcode);
 			transport_generic_free_cmd(&cmd->se_cmd, 0);
 			break;
 		}
@@ -1249,11 +1331,11 @@ static void
 isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd,
 		     struct ib_device *ib_dev)
 {
-	if (isert_cmd->sense_buf_dma != 0) {
-		pr_debug("Calling ib_dma_unmap_single for isert_cmd->sense_buf_dma\n");
-		ib_dma_unmap_single(ib_dev, isert_cmd->sense_buf_dma,
-				    isert_cmd->sense_buf_len, DMA_TO_DEVICE);
-		isert_cmd->sense_buf_dma = 0;
+	if (isert_cmd->pdu_buf_dma != 0) {
+		pr_debug("Calling ib_dma_unmap_single for isert_cmd->pdu_buf_dma\n");
+		ib_dma_unmap_single(ib_dev, isert_cmd->pdu_buf_dma,
+				    isert_cmd->pdu_buf_len, DMA_TO_DEVICE);
+		isert_cmd->pdu_buf_dma = 0;
 	}
 
 	isert_unmap_tx_desc(tx_desc, ib_dev);
@@ -1318,8 +1400,8 @@ isert_do_control_comp(struct work_struct
 		atomic_dec(&isert_conn->post_send_buf_count);
 
 		cmd->i_state = ISTATE_SENT_STATUS;
-		complete(&cmd->reject_comp);
 		isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
+		break;
 	case ISTATE_SEND_LOGOUTRSP:
 		pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
 		/*
@@ -1329,6 +1411,11 @@ isert_do_control_comp(struct work_struct
 		isert_conn->logout_posted = true;
 		iscsit_logout_post_handler(cmd, cmd->conn);
 		break;
+	case ISTATE_SEND_TEXTRSP:
+		atomic_dec(&isert_conn->post_send_buf_count);
+		cmd->i_state = ISTATE_SENT_STATUS;
+		isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
+		break;
 	default:
 		pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state);
 		dump_stack();
@@ -1345,7 +1432,9 @@ isert_response_completion(struct iser_tx
 	struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
 
 	if (cmd->i_state == ISTATE_SEND_TASKMGTRSP ||
-	    cmd->i_state == ISTATE_SEND_LOGOUTRSP) {
+	    cmd->i_state == ISTATE_SEND_LOGOUTRSP ||
+	    cmd->i_state == ISTATE_SEND_REJECT ||
+	    cmd->i_state == ISTATE_SEND_TEXTRSP) {
 		isert_unmap_tx_desc(tx_desc, ib_dev);
 
 		INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp);
@@ -1419,7 +1508,11 @@ isert_cq_comp_err(struct iser_tx_desc *t
 		pr_debug("isert_cq_comp_err >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
 		pr_debug("Calling wake_up from isert_cq_comp_err\n");
 
-		isert_conn->state = ISER_CONN_TERMINATING;
+		mutex_lock(&isert_conn->conn_mutex);
+		if (isert_conn->state != ISER_CONN_DOWN)
+			isert_conn->state = ISER_CONN_TERMINATING;
+		mutex_unlock(&isert_conn->conn_mutex);
+
 		wake_up(&isert_conn->conn_wait_comp_err);
 	}
 }
@@ -1445,6 +1538,7 @@ isert_cq_tx_work(struct work_struct *wor
 		} else {
 			pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n");
 			pr_debug("TX wc.status: 0x%08x\n", wc.status);
+			pr_debug("TX wc.vendor_err: 0x%08x\n", wc.vendor_err);
 			atomic_dec(&isert_conn->post_send_buf_count);
 			isert_cq_comp_err(tx_desc, isert_conn);
 		}
@@ -1484,9 +1578,11 @@ isert_cq_rx_work(struct work_struct *wor
 			isert_rx_completion(rx_desc, isert_conn, xfer_len);
 		} else {
 			pr_debug("RX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n");
-			if (wc.status != IB_WC_WR_FLUSH_ERR)
+			if (wc.status != IB_WC_WR_FLUSH_ERR) {
 				pr_debug("RX wc.status: 0x%08x\n", wc.status);
-
+				pr_debug("RX wc.vendor_err: 0x%08x\n",
+					 wc.vendor_err);
+			}
 			isert_conn->post_recv_buf_count--;
 			isert_cq_comp_err(NULL, isert_conn);
 		}
@@ -1543,7 +1639,7 @@ isert_put_response(struct iscsi_conn *co
 	    (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
 		struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
 		struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1];
-		u32 padding, sense_len;
+		u32 padding, pdu_len;
 
 		put_unaligned_be16(cmd->se_cmd.scsi_sense_length,
 				   cmd->sense_buffer);
@@ -1551,15 +1647,15 @@ isert_put_response(struct iscsi_conn *co
 
 		padding = -(cmd->se_cmd.scsi_sense_length) & 3;
 		hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length);
-		sense_len = cmd->se_cmd.scsi_sense_length + padding;
+		pdu_len = cmd->se_cmd.scsi_sense_length + padding;
 
-		isert_cmd->sense_buf_dma = ib_dma_map_single(ib_dev,
-				(void *)cmd->sense_buffer, sense_len,
+		isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
+				(void *)cmd->sense_buffer, pdu_len,
 				DMA_TO_DEVICE);
 
-		isert_cmd->sense_buf_len = sense_len;
-		tx_dsg->addr	= isert_cmd->sense_buf_dma;
-		tx_dsg->length	= sense_len;
+		isert_cmd->pdu_buf_len = pdu_len;
+		tx_dsg->addr	= isert_cmd->pdu_buf_dma;
+		tx_dsg->length	= pdu_len;
 		tx_dsg->lkey	= isert_conn->conn_mr->lkey;
 		isert_cmd->tx_desc.num_sge = 2;
 	}
@@ -1587,7 +1683,7 @@ isert_put_nopin(struct iscsi_cmd *cmd, s
 	isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc);
 	isert_init_send_wr(isert_cmd, send_wr);
 
-	pr_debug("Posting NOPIN Reponse IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n");
+	pr_debug("Posting NOPIN Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n");
 
 	return isert_post_response(isert_conn, isert_cmd);
 }
@@ -1637,11 +1733,25 @@ isert_put_reject(struct iscsi_cmd *cmd,
 				struct isert_cmd, iscsi_cmd);
 	struct isert_conn *isert_conn = (struct isert_conn *)conn->context;
 	struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr;
+	struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
+	struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1];
+	struct iscsi_reject *hdr =
+		(struct iscsi_reject *)&isert_cmd->tx_desc.iscsi_header;
 
 	isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc);
-	iscsit_build_reject(cmd, conn, (struct iscsi_reject *)
-				&isert_cmd->tx_desc.iscsi_header);
+	iscsit_build_reject(cmd, conn, hdr);
 	isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc);
+
+	hton24(hdr->dlength, ISCSI_HDR_LEN);
+	isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
+			(void *)cmd->buf_ptr, ISCSI_HDR_LEN,
+			DMA_TO_DEVICE);
+	isert_cmd->pdu_buf_len = ISCSI_HDR_LEN;
+	tx_dsg->addr	= isert_cmd->pdu_buf_dma;
+	tx_dsg->length	= ISCSI_HDR_LEN;
+	tx_dsg->lkey	= isert_conn->conn_mr->lkey;
+	isert_cmd->tx_desc.num_sge = 2;
+
 	isert_init_send_wr(isert_cmd, send_wr);
 
 	pr_debug("Posting Reject IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n");
@@ -1650,6 +1760,47 @@ isert_put_reject(struct iscsi_cmd *cmd,
 }
 
 static int
+isert_put_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
+{
+	struct isert_cmd *isert_cmd = container_of(cmd,
+				struct isert_cmd, iscsi_cmd);
+	struct isert_conn *isert_conn = (struct isert_conn *)conn->context;
+	struct ib_send_wr *send_wr = &isert_cmd->tx_desc.send_wr;
+	struct iscsi_text_rsp *hdr =
+		(struct iscsi_text_rsp *)&isert_cmd->tx_desc.iscsi_header;
+	u32 txt_rsp_len;
+	int rc;
+
+	isert_create_send_desc(isert_conn, isert_cmd, &isert_cmd->tx_desc);
+	rc = iscsit_build_text_rsp(cmd, conn, hdr);
+	if (rc < 0)
+		return rc;
+
+	txt_rsp_len = rc;
+	isert_init_tx_hdrs(isert_conn, &isert_cmd->tx_desc);
+
+	if (txt_rsp_len) {
+		struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
+		struct ib_sge *tx_dsg = &isert_cmd->tx_desc.tx_sg[1];
+		void *txt_rsp_buf = cmd->buf_ptr;
+
+		isert_cmd->pdu_buf_dma = ib_dma_map_single(ib_dev,
+				txt_rsp_buf, txt_rsp_len, DMA_TO_DEVICE);
+
+		isert_cmd->pdu_buf_len = txt_rsp_len;
+		tx_dsg->addr	= isert_cmd->pdu_buf_dma;
+		tx_dsg->length	= txt_rsp_len;
+		tx_dsg->lkey	= isert_conn->conn_mr->lkey;
+		isert_cmd->tx_desc.num_sge = 2;
+	}
+	isert_init_send_wr(isert_cmd, send_wr);
+
+	pr_debug("Posting Text Response IB_WR_SEND >>>>>>>>>>>>>>>>>>>>>>\n");
+
+	return isert_post_response(isert_conn, isert_cmd);
+}
+
+static int
 isert_build_rdma_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
 		    struct ib_sge *ib_sge, struct ib_send_wr *send_wr,
 		    u32 data_left, u32 offset)
@@ -1947,6 +2098,9 @@ isert_response_queue(struct iscsi_conn *
 	case ISTATE_SEND_REJECT:
 		ret = isert_put_reject(cmd, conn);
 		break;
+	case ISTATE_SEND_TEXTRSP:
+		ret = isert_put_text_rsp(cmd, conn);
+		break;
 	case ISTATE_SEND_STATUS:
 		/*
 		 * Special case for sending non GOOD SCSI status from TX thread
@@ -2175,6 +2329,17 @@ isert_free_np(struct iscsi_np *np)
 	kfree(isert_np);
 }
 
+static int isert_check_state(struct isert_conn *isert_conn, int state)
+{
+	int ret;
+
+	mutex_lock(&isert_conn->conn_mutex);
+	ret = (isert_conn->state == state);
+	mutex_unlock(&isert_conn->conn_mutex);
+
+	return ret;
+}
+
 static void isert_free_conn(struct iscsi_conn *conn)
 {
 	struct isert_conn *isert_conn = conn->context;
@@ -2184,26 +2349,43 @@ static void isert_free_conn(struct iscsi
 	 * Decrement post_send_buf_count for special case when called
 	 * from isert_do_control_comp() -> iscsit_logout_post_handler()
 	 */
+	mutex_lock(&isert_conn->conn_mutex);
 	if (isert_conn->logout_posted)
 		atomic_dec(&isert_conn->post_send_buf_count);
 
-	if (isert_conn->conn_cm_id)
+	if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) {
+		pr_debug("Calling rdma_disconnect from isert_free_conn\n");
 		rdma_disconnect(isert_conn->conn_cm_id);
+	}
 	/*
 	 * Only wait for conn_wait_comp_err if the isert_conn made it
 	 * into full feature phase..
 	 */
-	if (isert_conn->state > ISER_CONN_INIT) {
+	if (isert_conn->state == ISER_CONN_UP) {
 		pr_debug("isert_free_conn: Before wait_event comp_err %d\n",
 			 isert_conn->state);
+		mutex_unlock(&isert_conn->conn_mutex);
+
 		wait_event(isert_conn->conn_wait_comp_err,
-			   isert_conn->state == ISER_CONN_TERMINATING);
-		pr_debug("isert_free_conn: After wait_event #1 >>>>>>>>>>>>\n");
+			  (isert_check_state(isert_conn, ISER_CONN_TERMINATING)));
+
+		wait_event(isert_conn->conn_wait,
+			  (isert_check_state(isert_conn, ISER_CONN_DOWN)));
+
+		isert_put_conn(isert_conn);
+		return;
+	}
+	if (isert_conn->state == ISER_CONN_INIT) {
+		mutex_unlock(&isert_conn->conn_mutex);
+		isert_put_conn(isert_conn);
+		return;
 	}
+	pr_debug("isert_free_conn: wait_event conn_wait %d\n",
+		 isert_conn->state);
+	mutex_unlock(&isert_conn->conn_mutex);
 
-	pr_debug("isert_free_conn: wait_event conn_wait %d\n", isert_conn->state);
-	wait_event(isert_conn->conn_wait, isert_conn->state == ISER_CONN_DOWN);
-	pr_debug("isert_free_conn: After wait_event #2 >>>>>>>>>>>>>>>>>>>>\n");
+	wait_event(isert_conn->conn_wait,
+		  (isert_check_state(isert_conn, ISER_CONN_DOWN)));
 
 	isert_put_conn(isert_conn);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/ulp/isert/ib_isert.h linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/isert/ib_isert.h
--- linux-libre-3.10-gnu/drivers/infiniband/ulp/isert/ib_isert.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/isert/ib_isert.h	2013-08-25 20:43:22.000000000 -0400
@@ -61,8 +61,8 @@ struct isert_cmd {
 	uint32_t		write_stag;
 	uint64_t		read_va;
 	uint64_t		write_va;
-	u64			sense_buf_dma;
-	u32			sense_buf_len;
+	u64			pdu_buf_dma;
+	u32			pdu_buf_len;
 	u32			read_va_off;
 	u32			write_va_off;
 	u32			rdma_wr_num;
@@ -102,6 +102,7 @@ struct isert_conn {
 	struct ib_qp		*conn_qp;
 	struct isert_device	*conn_device;
 	struct work_struct	conn_logout_work;
+	struct mutex		conn_mutex;
 	wait_queue_head_t	conn_wait;
 	wait_queue_head_t	conn_wait_comp_err;
 	struct kref		conn_kref;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/ulp/srp/ib_srp.c linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/srp/ib_srp.c
--- linux-libre-3.10-gnu/drivers/infiniband/ulp/srp/ib_srp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/srp/ib_srp.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,8 +53,8 @@
 
 #define DRV_NAME	"ib_srp"
 #define PFX		DRV_NAME ": "
-#define DRV_VERSION	"0.2"
-#define DRV_RELDATE	"November 1, 2005"
+#define DRV_VERSION	"1.0"
+#define DRV_RELDATE	"July 1, 2013"
 
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator "
@@ -231,14 +231,16 @@ static int srp_create_target_ib(struct s
 		return -ENOMEM;
 
 	recv_cq = ib_create_cq(target->srp_host->srp_dev->dev,
-			       srp_recv_completion, NULL, target, SRP_RQ_SIZE, 0);
+			       srp_recv_completion, NULL, target, SRP_RQ_SIZE,
+			       target->comp_vector);
 	if (IS_ERR(recv_cq)) {
 		ret = PTR_ERR(recv_cq);
 		goto err;
 	}
 
 	send_cq = ib_create_cq(target->srp_host->srp_dev->dev,
-			       srp_send_completion, NULL, target, SRP_SQ_SIZE, 0);
+			       srp_send_completion, NULL, target, SRP_SQ_SIZE,
+			       target->comp_vector);
 	if (IS_ERR(send_cq)) {
 		ret = PTR_ERR(send_cq);
 		goto err_recv_cq;
@@ -542,11 +544,11 @@ static void srp_remove_work(struct work_
 
 	WARN_ON_ONCE(target->state != SRP_TARGET_REMOVED);
 
+	srp_remove_target(target);
+
 	spin_lock(&target->srp_host->target_lock);
 	list_del(&target->list);
 	spin_unlock(&target->srp_host->target_lock);
-
-	srp_remove_target(target);
 }
 
 static void srp_rport_delete(struct srp_rport *rport)
@@ -1744,18 +1746,24 @@ static int srp_abort(struct scsi_cmnd *s
 {
 	struct srp_target_port *target = host_to_target(scmnd->device->host);
 	struct srp_request *req = (struct srp_request *) scmnd->host_scribble;
+	int ret;
 
 	shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n");
 
 	if (!req || !srp_claim_req(target, req, scmnd))
 		return FAILED;
-	srp_send_tsk_mgmt(target, req->index, scmnd->device->lun,
-			  SRP_TSK_ABORT_TASK);
+	if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun,
+			      SRP_TSK_ABORT_TASK) == 0)
+		ret = SUCCESS;
+	else if (target->transport_offline)
+		ret = FAST_IO_FAIL;
+	else
+		ret = FAILED;
 	srp_free_req(target, req, scmnd, 0);
 	scmnd->result = DID_ABORT << 16;
 	scmnd->scsi_done(scmnd);
 
-	return SUCCESS;
+	return ret;
 }
 
 static int srp_reset_device(struct scsi_cmnd *scmnd)
@@ -1891,6 +1899,14 @@ static ssize_t show_local_ib_device(stru
 	return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name);
 }
 
+static ssize_t show_comp_vector(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct srp_target_port *target = host_to_target(class_to_shost(dev));
+
+	return sprintf(buf, "%d\n", target->comp_vector);
+}
+
 static ssize_t show_cmd_sg_entries(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 {
@@ -1917,6 +1933,7 @@ static DEVICE_ATTR(req_lim,         S_IR
 static DEVICE_ATTR(zero_req_lim,    S_IRUGO, show_zero_req_lim,	   NULL);
 static DEVICE_ATTR(local_ib_port,   S_IRUGO, show_local_ib_port,   NULL);
 static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL);
+static DEVICE_ATTR(comp_vector,     S_IRUGO, show_comp_vector,     NULL);
 static DEVICE_ATTR(cmd_sg_entries,  S_IRUGO, show_cmd_sg_entries,  NULL);
 static DEVICE_ATTR(allow_ext_sg,    S_IRUGO, show_allow_ext_sg,    NULL);
 
@@ -1931,6 +1948,7 @@ static struct device_attribute *srp_host
 	&dev_attr_zero_req_lim,
 	&dev_attr_local_ib_port,
 	&dev_attr_local_ib_device,
+	&dev_attr_comp_vector,
 	&dev_attr_cmd_sg_entries,
 	&dev_attr_allow_ext_sg,
 	NULL
@@ -1946,6 +1964,7 @@ static struct scsi_host_template srp_tem
 	.eh_abort_handler		= srp_abort,
 	.eh_device_reset_handler	= srp_reset_device,
 	.eh_host_reset_handler		= srp_reset_host,
+	.skip_settle_delay		= true,
 	.sg_tablesize			= SRP_DEF_SG_TABLESIZE,
 	.can_queue			= SRP_CMD_SQ_SIZE,
 	.this_id			= -1,
@@ -2001,6 +2020,36 @@ static struct class srp_class = {
 	.dev_release = srp_release_dev
 };
 
+/**
+ * srp_conn_unique() - check whether the connection to a target is unique
+ */
+static bool srp_conn_unique(struct srp_host *host,
+			    struct srp_target_port *target)
+{
+	struct srp_target_port *t;
+	bool ret = false;
+
+	if (target->state == SRP_TARGET_REMOVED)
+		goto out;
+
+	ret = true;
+
+	spin_lock(&host->target_lock);
+	list_for_each_entry(t, &host->target_list, list) {
+		if (t != target &&
+		    target->id_ext == t->id_ext &&
+		    target->ioc_guid == t->ioc_guid &&
+		    target->initiator_ext == t->initiator_ext) {
+			ret = false;
+			break;
+		}
+	}
+	spin_unlock(&host->target_lock);
+
+out:
+	return ret;
+}
+
 /*
  * Target ports are added by writing
  *
@@ -2023,6 +2072,7 @@ enum {
 	SRP_OPT_CMD_SG_ENTRIES	= 1 << 9,
 	SRP_OPT_ALLOW_EXT_SG	= 1 << 10,
 	SRP_OPT_SG_TABLESIZE	= 1 << 11,
+	SRP_OPT_COMP_VECTOR	= 1 << 12,
 	SRP_OPT_ALL		= (SRP_OPT_ID_EXT	|
 				   SRP_OPT_IOC_GUID	|
 				   SRP_OPT_DGID		|
@@ -2043,6 +2093,7 @@ static const match_table_t srp_opt_token
 	{ SRP_OPT_CMD_SG_ENTRIES,	"cmd_sg_entries=%u"	},
 	{ SRP_OPT_ALLOW_EXT_SG,		"allow_ext_sg=%u"	},
 	{ SRP_OPT_SG_TABLESIZE,		"sg_tablesize=%u"	},
+	{ SRP_OPT_COMP_VECTOR,		"comp_vector=%u"	},
 	{ SRP_OPT_ERR,			NULL 			}
 };
 
@@ -2198,6 +2249,14 @@ static int srp_parse_options(const char
 			target->sg_tablesize = token;
 			break;
 
+		case SRP_OPT_COMP_VECTOR:
+			if (match_int(args, &token) || token < 0) {
+				pr_warn("bad comp_vector parameter '%s'\n", p);
+				goto out;
+			}
+			target->comp_vector = token;
+			break;
+
 		default:
 			pr_warn("unknown parameter or missing value '%s' in target creation request\n",
 				p);
@@ -2257,6 +2316,16 @@ static ssize_t srp_create_target(struct
 	if (ret)
 		goto err;
 
+	if (!srp_conn_unique(target->srp_host, target)) {
+		shost_printk(KERN_INFO, target->scsi_host,
+			     PFX "Already connected to target port with id_ext=%016llx;ioc_guid=%016llx;initiator_ext=%016llx\n",
+			     be64_to_cpu(target->id_ext),
+			     be64_to_cpu(target->ioc_guid),
+			     be64_to_cpu(target->initiator_ext));
+		ret = -EEXIST;
+		goto err;
+	}
+
 	if (!host->srp_dev->fmr_pool && !target->allow_ext_sg &&
 				target->cmd_sg_cnt < target->sg_tablesize) {
 		pr_warn("No FMR pool and no external indirect descriptors, limiting sg_tablesize to cmd_sg_cnt\n");
@@ -2507,6 +2576,8 @@ static void srp_remove_one(struct ib_dev
 	struct srp_target_port *target;
 
 	srp_dev = ib_get_client_data(device, &srp_client);
+	if (!srp_dev)
+		return;
 
 	list_for_each_entry_safe(host, tmp_host, &srp_dev->dev_list, list) {
 		device_unregister(&host->dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/ulp/srp/ib_srp.h linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/srp/ib_srp.h
--- linux-libre-3.10-gnu/drivers/infiniband/ulp/srp/ib_srp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/srp/ib_srp.h	2013-08-25 20:43:22.000000000 -0400
@@ -156,6 +156,7 @@ struct srp_target_port {
 	char			target_name[32];
 	unsigned int		scsi_id;
 	unsigned int		sg_tablesize;
+	int			comp_vector;
 
 	struct ib_sa_path_rec	path;
 	__be16			orig_dgid[8];
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/infiniband/ulp/srpt/ib_srpt.c linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/srpt/ib_srpt.c
--- linux-libre-3.10-gnu/drivers/infiniband/ulp/srpt/ib_srpt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/infiniband/ulp/srpt/ib_srpt.c	2013-08-25 20:43:22.000000000 -0400
@@ -3011,7 +3011,7 @@ static u8 tcm_to_srp_tsk_mgmt_status(con
  * Callback function called by the TCM core. Must not block since it can be
  * invoked on the context of the IB completion handler.
  */
-static int srpt_queue_response(struct se_cmd *cmd)
+static void srpt_queue_response(struct se_cmd *cmd)
 {
 	struct srpt_rdma_ch *ch;
 	struct srpt_send_ioctx *ioctx;
@@ -3022,8 +3022,6 @@ static int srpt_queue_response(struct se
 	int resp_len;
 	u8 srp_tm_status;
 
-	ret = 0;
-
 	ioctx = container_of(cmd, struct srpt_send_ioctx, cmd);
 	ch = ioctx->ch;
 	BUG_ON(!ch);
@@ -3049,7 +3047,7 @@ static int srpt_queue_response(struct se
 		     || WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) {
 		atomic_inc(&ch->req_lim_delta);
 		srpt_abort_cmd(ioctx);
-		goto out;
+		return;
 	}
 
 	dir = ioctx->cmd.data_direction;
@@ -3061,7 +3059,7 @@ static int srpt_queue_response(struct se
 		if (ret) {
 			printk(KERN_ERR "xfer_data failed for tag %llu\n",
 			       ioctx->tag);
-			goto out;
+			return;
 		}
 	}
 
@@ -3082,9 +3080,17 @@ static int srpt_queue_response(struct se
 		srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
 		target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
 	}
+}
 
-out:
-	return ret;
+static int srpt_queue_data_in(struct se_cmd *cmd)
+{
+	srpt_queue_response(cmd);
+	return 0;
+}
+
+static void srpt_queue_tm_rsp(struct se_cmd *cmd)
+{
+	srpt_queue_response(cmd);
 }
 
 static int srpt_queue_status(struct se_cmd *cmd)
@@ -3097,7 +3103,8 @@ static int srpt_queue_status(struct se_c
 	    (SCF_TRANSPORT_TASK_SENSE | SCF_EMULATED_TASK_SENSE))
 		WARN_ON(cmd->scsi_status != SAM_STAT_CHECK_CONDITION);
 	ioctx->queue_status_only = true;
-	return srpt_queue_response(cmd);
+	srpt_queue_response(cmd);
+	return 0;
 }
 
 static void srpt_refresh_port_work(struct work_struct *work)
@@ -3930,9 +3937,9 @@ static struct target_core_fabric_ops srp
 	.set_default_node_attributes	= srpt_set_default_node_attrs,
 	.get_task_tag			= srpt_get_task_tag,
 	.get_cmd_state			= srpt_get_tcm_cmd_state,
-	.queue_data_in			= srpt_queue_response,
+	.queue_data_in			= srpt_queue_data_in,
 	.queue_status			= srpt_queue_status,
-	.queue_tm_rsp			= srpt_queue_response,
+	.queue_tm_rsp			= srpt_queue_tm_rsp,
 	/*
 	 * Setup function pointers for generic logic in
 	 * target_core_fabric_configfs.c
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/evdev.c linux-libre-3.11-rc7-gnu/drivers/input/evdev.c
--- linux-libre-3.10-gnu/drivers/input/evdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/evdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -52,6 +52,82 @@ struct evdev_client {
 	struct input_event buffer[];
 };
 
+/* flush queued events of type @type, caller must hold client->buffer_lock */
+static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
+{
+	unsigned int i, head, num;
+	unsigned int mask = client->bufsize - 1;
+	bool is_report;
+	struct input_event *ev;
+
+	BUG_ON(type == EV_SYN);
+
+	head = client->tail;
+	client->packet_head = client->tail;
+
+	/* init to 1 so a leading SYN_REPORT will not be dropped */
+	num = 1;
+
+	for (i = client->tail; i != client->head; i = (i + 1) & mask) {
+		ev = &client->buffer[i];
+		is_report = ev->type == EV_SYN && ev->code == SYN_REPORT;
+
+		if (ev->type == type) {
+			/* drop matched entry */
+			continue;
+		} else if (is_report && !num) {
+			/* drop empty SYN_REPORT groups */
+			continue;
+		} else if (head != i) {
+			/* move entry to fill the gap */
+			client->buffer[head].time = ev->time;
+			client->buffer[head].type = ev->type;
+			client->buffer[head].code = ev->code;
+			client->buffer[head].value = ev->value;
+		}
+
+		num++;
+		head = (head + 1) & mask;
+
+		if (is_report) {
+			num = 0;
+			client->packet_head = head;
+		}
+	}
+
+	client->head = head;
+}
+
+/* queue SYN_DROPPED event */
+static void evdev_queue_syn_dropped(struct evdev_client *client)
+{
+	unsigned long flags;
+	struct input_event ev;
+	ktime_t time;
+
+	time = ktime_get();
+	if (client->clkid != CLOCK_MONOTONIC)
+		time = ktime_sub(time, ktime_get_monotonic_offset());
+
+	ev.time = ktime_to_timeval(time);
+	ev.type = EV_SYN;
+	ev.code = SYN_DROPPED;
+	ev.value = 0;
+
+	spin_lock_irqsave(&client->buffer_lock, flags);
+
+	client->buffer[client->head++] = ev;
+	client->head &= client->bufsize - 1;
+
+	if (unlikely(client->head == client->tail)) {
+		/* drop queue but keep our SYN_DROPPED event */
+		client->tail = (client->head - 1) & (client->bufsize - 1);
+		client->packet_head = client->tail;
+	}
+
+	spin_unlock_irqrestore(&client->buffer_lock, flags);
+}
+
 static void __pass_event(struct evdev_client *client,
 			 const struct input_event *event)
 {
@@ -650,6 +726,51 @@ static int evdev_handle_set_keycode_v2(s
 	return input_set_keycode(dev, &ke);
 }
 
+/*
+ * If we transfer state to the user, we should flush all pending events
+ * of the same type from the client's queue. Otherwise, they might end up
+ * with duplicate events, which can screw up client's state tracking.
+ * If bits_to_user fails after flushing the queue, we queue a SYN_DROPPED
+ * event so user-space will notice missing events.
+ *
+ * LOCKING:
+ * We need to take event_lock before buffer_lock to avoid dead-locks. But we
+ * need the even_lock only to guarantee consistent state. We can safely release
+ * it while flushing the queue. This allows input-core to handle filters while
+ * we flush the queue.
+ */
+static int evdev_handle_get_val(struct evdev_client *client,
+				struct input_dev *dev, unsigned int type,
+				unsigned long *bits, unsigned int max,
+				unsigned int size, void __user *p, int compat)
+{
+	int ret;
+	unsigned long *mem;
+
+	mem = kmalloc(sizeof(unsigned long) * max, GFP_KERNEL);
+	if (!mem)
+		return -ENOMEM;
+
+	spin_lock_irq(&dev->event_lock);
+	spin_lock(&client->buffer_lock);
+
+	memcpy(mem, bits, sizeof(unsigned long) * max);
+
+	spin_unlock(&dev->event_lock);
+
+	__evdev_flush_queue(client, type);
+
+	spin_unlock_irq(&client->buffer_lock);
+
+	ret = bits_to_user(mem, max, size, p, compat);
+	if (ret < 0)
+		evdev_queue_syn_dropped(client);
+
+	kfree(mem);
+
+	return ret;
+}
+
 static int evdev_handle_mt_request(struct input_dev *dev,
 				   unsigned int size,
 				   int __user *ip)
@@ -771,16 +892,20 @@ static long evdev_do_ioctl(struct file *
 		return evdev_handle_mt_request(dev, size, ip);
 
 	case EVIOCGKEY(0):
-		return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
+		return evdev_handle_get_val(client, dev, EV_KEY, dev->key,
+					    KEY_MAX, size, p, compat_mode);
 
 	case EVIOCGLED(0):
-		return bits_to_user(dev->led, LED_MAX, size, p, compat_mode);
+		return evdev_handle_get_val(client, dev, EV_LED, dev->led,
+					    LED_MAX, size, p, compat_mode);
 
 	case EVIOCGSND(0):
-		return bits_to_user(dev->snd, SND_MAX, size, p, compat_mode);
+		return evdev_handle_get_val(client, dev, EV_SND, dev->snd,
+					    SND_MAX, size, p, compat_mode);
 
 	case EVIOCGSW(0):
-		return bits_to_user(dev->sw, SW_MAX, size, p, compat_mode);
+		return evdev_handle_get_val(client, dev, EV_SW, dev->sw,
+					    SW_MAX, size, p, compat_mode);
 
 	case EVIOCGNAME(0):
 		return str_to_user(dev->name, size, p);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/amikbd.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/amikbd.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/amikbd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/amikbd.c	2013-08-25 20:43:22.000000000 -0400
@@ -246,7 +246,6 @@ static int __exit amikbd_remove(struct p
 {
 	struct input_dev *dev = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	free_irq(IRQ_AMIGA_CIAA_SP, dev);
 	input_unregister_device(dev);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/bf54x-keys.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/bf54x-keys.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/bf54x-keys.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/bf54x-keys.c	2013-08-25 20:43:22.000000000 -0400
@@ -326,7 +326,6 @@ out0:
 	kfree(bf54x_kpad->keycode);
 out:
 	kfree(bf54x_kpad);
-	platform_set_drvdata(pdev, NULL);
 
 	return error;
 }
@@ -346,7 +345,6 @@ static int bfin_kpad_remove(struct platf
 
 	kfree(bf54x_kpad->keycode);
 	kfree(bf54x_kpad);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/cros_ec_keyb.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/cros_ec_keyb.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/cros_ec_keyb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/cros_ec_keyb.c	2013-08-25 20:43:22.000000000 -0400
@@ -206,33 +206,6 @@ static int cros_ec_keyb_work(struct noti
 	return NOTIFY_DONE;
 }
 
-/* Clear any keys in the buffer */
-static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
-{
-	uint8_t old_state[ckdev->cols];
-	uint8_t new_state[ckdev->cols];
-	unsigned long duration;
-	int i, ret;
-
-	/*
-	 * Keep reading until we see that the scan state does not change.
-	 * That indicates that we are done.
-	 *
-	 * Assume that the EC keyscan buffer is at most 32 deep.
-	 */
-	duration = jiffies;
-	ret = cros_ec_keyb_get_state(ckdev, new_state);
-	for (i = 1; !ret && i < 32; i++) {
-		memcpy(old_state, new_state, sizeof(old_state));
-		ret = cros_ec_keyb_get_state(ckdev, new_state);
-		if (0 == memcmp(old_state, new_state, sizeof(old_state)))
-			break;
-	}
-	duration = jiffies - duration;
-	dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i,
-		jiffies_to_usecs(duration));
-}
-
 static int cros_ec_keyb_probe(struct platform_device *pdev)
 {
 	struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent);
@@ -299,6 +272,33 @@ static int cros_ec_keyb_probe(struct pla
 }
 
 #ifdef CONFIG_PM_SLEEP
+/* Clear any keys in the buffer */
+static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
+{
+	uint8_t old_state[ckdev->cols];
+	uint8_t new_state[ckdev->cols];
+	unsigned long duration;
+	int i, ret;
+
+	/*
+	 * Keep reading until we see that the scan state does not change.
+	 * That indicates that we are done.
+	 *
+	 * Assume that the EC keyscan buffer is at most 32 deep.
+	 */
+	duration = jiffies;
+	ret = cros_ec_keyb_get_state(ckdev, new_state);
+	for (i = 1; !ret && i < 32; i++) {
+		memcpy(old_state, new_state, sizeof(old_state));
+		ret = cros_ec_keyb_get_state(ckdev, new_state);
+		if (0 == memcmp(old_state, new_state, sizeof(old_state)))
+			break;
+	}
+	duration = jiffies - duration;
+	dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i,
+		jiffies_to_usecs(duration));
+}
+
 static int cros_ec_keyb_resume(struct device *dev)
 {
 	struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/davinci_keyscan.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/davinci_keyscan.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/davinci_keyscan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/davinci_keyscan.c	2013-08-25 20:43:22.000000000 -0400
@@ -314,8 +314,6 @@ static int davinci_ks_remove(struct plat
 	iounmap(davinci_ks->base);
 	release_mem_region(davinci_ks->pbase, davinci_ks->base_size);
 
-	platform_set_drvdata(pdev, NULL);
-
 	kfree(davinci_ks);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/ep93xx_keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/ep93xx_keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/ep93xx_keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/ep93xx_keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -329,8 +329,7 @@ static int ep93xx_keypad_probe(struct pl
 	return 0;
 
 failed_free_irq:
-	free_irq(keypad->irq, pdev);
-	platform_set_drvdata(pdev, NULL);
+	free_irq(keypad->irq, keypad);
 failed_free_dev:
 	input_free_device(input_dev);
 failed_put_clk:
@@ -351,9 +350,7 @@ static int ep93xx_keypad_remove(struct p
 	struct ep93xx_keypad *keypad = platform_get_drvdata(pdev);
 	struct resource *res;
 
-	free_irq(keypad->irq, pdev);
-
-	platform_set_drvdata(pdev, NULL);
+	free_irq(keypad->irq, keypad);
 
 	if (keypad->enabled)
 		clk_disable(keypad->clk);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/gpio_keys.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/gpio_keys.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/gpio_keys.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/gpio_keys.c	2013-08-25 20:43:22.000000000 -0400
@@ -767,7 +767,6 @@ static int gpio_keys_probe(struct platfo
 	while (--i >= 0)
 		gpio_remove_key(&ddata->data[i]);
 
-	platform_set_drvdata(pdev, NULL);
  fail1:
 	input_free_device(input);
 	kfree(ddata);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/gpio_keys_polled.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/gpio_keys_polled.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/gpio_keys_polled.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/gpio_keys_polled.c	2013-08-25 20:43:22.000000000 -0400
@@ -324,7 +324,6 @@ err_free_gpio:
 
 err_free_bdev:
 	kfree(bdev);
-	platform_set_drvdata(pdev, NULL);
 
 err_free_pdata:
 	/* If we have no platform_data, we allocated pdata dynamically.  */
@@ -355,7 +354,6 @@ static int gpio_keys_polled_remove(struc
 		kfree(pdata);
 
 	kfree(bdev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/jornada680_kbd.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/jornada680_kbd.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/jornada680_kbd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/jornada680_kbd.c	2013-08-25 20:43:22.000000000 -0400
@@ -233,7 +233,6 @@ static int jornada680kbd_probe(struct pl
  failed:
 	printk(KERN_ERR "Jornadakbd: failed to register driver, error: %d\n",
 		error);
-	platform_set_drvdata(pdev, NULL);
 	input_free_polled_device(poll_dev);
 	kfree(jornadakbd);
 	return error;
@@ -244,7 +243,6 @@ static int jornada680kbd_remove(struct p
 {
 	struct jornadakbd *jornadakbd = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	input_unregister_polled_device(jornadakbd->poll_dev);
 	input_free_polled_device(jornadakbd->poll_dev);
 	kfree(jornadakbd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/jornada720_kbd.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/jornada720_kbd.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/jornada720_kbd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/jornada720_kbd.c	2013-08-25 20:43:22.000000000 -0400
@@ -146,7 +146,6 @@ static int jornada720_kbd_probe(struct p
  fail2:	/* IRQ, DEVICE, MEMORY */
 	free_irq(IRQ_GPIO0, pdev);
  fail1:	/* DEVICE, MEMORY */
-	platform_set_drvdata(pdev, NULL);
 	input_free_device(input_dev);
 	kfree(jornadakbd);
 	return err;
@@ -157,7 +156,6 @@ static int jornada720_kbd_remove(struct
 	struct jornadakbd *jornadakbd = platform_get_drvdata(pdev);
 
 	free_irq(IRQ_GPIO0, pdev);
-	platform_set_drvdata(pdev, NULL);
 	input_unregister_device(jornadakbd->input);
 	kfree(jornadakbd);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/Kconfig linux-libre-3.11-rc7-gnu/drivers/input/keyboard/Kconfig
--- linux-libre-3.10-gnu/drivers/input/keyboard/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -418,6 +418,16 @@ config KEYBOARD_NOMADIK
 	  To compile this driver as a module, choose M here: the
 	  module will be called nmk-ske-keypad.
 
+config KEYBOARD_NSPIRE
+	tristate "TI-NSPIRE built-in keyboard"
+	depends on ARCH_NSPIRE && OF
+	select INPUT_MATRIXKMAP
+	help
+	  Say Y here if you want to use the built-in keypad on TI-NSPIRE.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called nspire-keypad.
+
 config KEYBOARD_TEGRA
 	tristate "NVIDIA Tegra internal matrix keyboard controller support"
 	depends on ARCH_TEGRA && OF
@@ -442,6 +452,7 @@ config KEYBOARD_OPENCORES
 config KEYBOARD_PXA27x
 	tristate "PXA27x/PXA3xx keypad support"
 	depends on PXA27x || PXA3xx || ARCH_MMP
+	select INPUT_MATRIXKMAP
 	help
 	  Enable support for PXA27x/PXA3xx keypad controller.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/Makefile linux-libre-3.11-rc7-gnu/drivers/input/keyboard/Makefile
--- linux-libre-3.10-gnu/drivers/input/keyboard/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,7 @@ obj-$(CONFIG_KEYBOARD_MCS)		+= mcs_touch
 obj-$(CONFIG_KEYBOARD_MPR121)		+= mpr121_touchkey.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
 obj-$(CONFIG_KEYBOARD_NOMADIK)		+= nomadik-ske-keypad.o
+obj-$(CONFIG_KEYBOARD_NSPIRE)		+= nspire-keypad.o
 obj-$(CONFIG_KEYBOARD_OMAP)		+= omap-keypad.o
 obj-$(CONFIG_KEYBOARD_OMAP4)		+= omap4-keypad.o
 obj-$(CONFIG_KEYBOARD_OPENCORES)	+= opencores-kbd.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/matrix_keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/matrix_keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/matrix_keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/matrix_keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -549,8 +549,6 @@ static int matrix_keypad_remove(struct p
 	input_unregister_device(keypad->input_dev);
 	kfree(keypad);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/nspire-keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/nspire-keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/nspire-keypad.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/nspire-keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,283 @@
+/*
+ *  Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/input/matrix_keypad.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#define KEYPAD_SCAN_MODE	0x00
+#define KEYPAD_CNTL		0x04
+#define KEYPAD_INT		0x08
+#define KEYPAD_INTMSK		0x0C
+
+#define KEYPAD_DATA		0x10
+#define KEYPAD_GPIO		0x30
+
+#define KEYPAD_UNKNOWN_INT	0x40
+#define KEYPAD_UNKNOWN_INT_STS	0x44
+
+#define KEYPAD_BITMASK_COLS	11
+#define KEYPAD_BITMASK_ROWS	8
+
+struct nspire_keypad {
+	void __iomem *reg_base;
+	u32 int_mask;
+
+	struct input_dev *input;
+	struct clk *clk;
+
+	struct matrix_keymap_data *keymap;
+	int row_shift;
+
+	/* Maximum delay estimated assuming 33MHz APB */
+	u32 scan_interval;	/* In microseconds (~2000us max) */
+	u32 row_delay;		/* In microseconds (~500us max) */
+
+	u16 state[KEYPAD_BITMASK_ROWS];
+
+	bool active_low;
+};
+
+static irqreturn_t nspire_keypad_irq(int irq, void *dev_id)
+{
+	struct nspire_keypad *keypad = dev_id;
+	struct input_dev *input = keypad->input;
+	unsigned short *keymap = input->keycode;
+	unsigned int code;
+	int row, col;
+	u32 int_sts;
+	u16 state[8];
+	u16 bits, changed;
+
+	int_sts = readl(keypad->reg_base + KEYPAD_INT) & keypad->int_mask;
+	if (!int_sts)
+		return IRQ_NONE;
+
+	memcpy_fromio(state, keypad->reg_base + KEYPAD_DATA, sizeof(state));
+
+	for (row = 0; row < KEYPAD_BITMASK_ROWS; row++) {
+		bits = state[row];
+		if (keypad->active_low)
+			bits = ~bits;
+
+		changed = bits ^ keypad->state[row];
+		if (!changed)
+			continue;
+
+		keypad->state[row] = bits;
+
+		for (col = 0; col < KEYPAD_BITMASK_COLS; col++) {
+			if (!(changed & (1U << col)))
+				continue;
+
+			code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
+			input_event(input, EV_MSC, MSC_SCAN, code);
+			input_report_key(input, keymap[code],
+					 bits & (1U << col));
+		}
+	}
+
+	input_sync(input);
+
+	writel(0x3, keypad->reg_base + KEYPAD_INT);
+
+	return IRQ_HANDLED;
+}
+
+static int nspire_keypad_chip_init(struct nspire_keypad *keypad)
+{
+	unsigned long val = 0, cycles_per_us, delay_cycles, row_delay_cycles;
+
+	cycles_per_us = (clk_get_rate(keypad->clk) / 1000000);
+	if (cycles_per_us == 0)
+		cycles_per_us = 1;
+
+	delay_cycles = cycles_per_us * keypad->scan_interval;
+	WARN_ON(delay_cycles >= (1 << 16)); /* Overflow */
+	delay_cycles &= 0xffff;
+
+	row_delay_cycles = cycles_per_us * keypad->row_delay;
+	WARN_ON(row_delay_cycles >= (1 << 14)); /* Overflow */
+	row_delay_cycles &= 0x3fff;
+
+	val |= 3 << 0; /* Set scan mode to 3 (continuous scan) */
+	val |= row_delay_cycles << 2; /* Delay between scanning each row */
+	val |= delay_cycles << 16; /* Delay between scans */
+	writel(val, keypad->reg_base + KEYPAD_SCAN_MODE);
+
+	val = (KEYPAD_BITMASK_ROWS & 0xff) | (KEYPAD_BITMASK_COLS & 0xff)<<8;
+	writel(val, keypad->reg_base + KEYPAD_CNTL);
+
+	/* Enable interrupts */
+	keypad->int_mask = 1 << 1;
+	writel(keypad->int_mask, keypad->reg_base + KEYPAD_INTMSK);
+
+	/* Disable GPIO interrupts to prevent hanging on touchpad */
+	/* Possibly used to detect touchpad events */
+	writel(0, keypad->reg_base + KEYPAD_UNKNOWN_INT);
+	/* Acknowledge existing interrupts */
+	writel(~0, keypad->reg_base + KEYPAD_UNKNOWN_INT_STS);
+
+	return 0;
+}
+
+static int nspire_keypad_open(struct input_dev *input)
+{
+	struct nspire_keypad *keypad = input_get_drvdata(input);
+	int error;
+
+	error = clk_prepare_enable(keypad->clk);
+	if (error)
+		return error;
+
+	error = nspire_keypad_chip_init(keypad);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static void nspire_keypad_close(struct input_dev *input)
+{
+	struct nspire_keypad *keypad = input_get_drvdata(input);
+
+	clk_disable_unprepare(keypad->clk);
+}
+
+static int nspire_keypad_probe(struct platform_device *pdev)
+{
+	const struct device_node *of_node = pdev->dev.of_node;
+	struct nspire_keypad *keypad;
+	struct input_dev *input;
+	struct resource *res;
+	int irq;
+	int error;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get keypad irq\n");
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "missing platform resources\n");
+		return -EINVAL;
+	}
+
+	keypad = devm_kzalloc(&pdev->dev, sizeof(struct nspire_keypad),
+			      GFP_KERNEL);
+	if (!keypad) {
+		dev_err(&pdev->dev, "failed to allocate keypad memory\n");
+		return -ENOMEM;
+	}
+
+	keypad->row_shift = get_count_order(KEYPAD_BITMASK_COLS);
+
+	error = of_property_read_u32(of_node, "scan-interval",
+				     &keypad->scan_interval);
+	if (error) {
+		dev_err(&pdev->dev, "failed to get scan-interval\n");
+		return error;
+	}
+
+	error = of_property_read_u32(of_node, "row-delay",
+				     &keypad->row_delay);
+	if (error) {
+		dev_err(&pdev->dev, "failed to get row-delay\n");
+		return error;
+	}
+
+	keypad->active_low = of_property_read_bool(of_node, "active-low");
+
+	keypad->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(keypad->clk)) {
+		dev_err(&pdev->dev, "unable to get clock\n");
+		return PTR_ERR(keypad->clk);
+	}
+
+	keypad->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(keypad->reg_base))
+		return PTR_ERR(keypad->reg_base);
+
+	keypad->input = input = devm_input_allocate_device(&pdev->dev);
+	if (!input) {
+		dev_err(&pdev->dev, "failed to allocate input device\n");
+		return -ENOMEM;
+	}
+
+	input_set_drvdata(input, keypad);
+
+	input->id.bustype = BUS_HOST;
+	input->name = "nspire-keypad";
+	input->open = nspire_keypad_open;
+	input->close = nspire_keypad_close;
+
+	__set_bit(EV_KEY, input->evbit);
+	__set_bit(EV_REP, input->evbit);
+	input_set_capability(input, EV_MSC, MSC_SCAN);
+
+	error = matrix_keypad_build_keymap(NULL, NULL,
+					   KEYPAD_BITMASK_ROWS,
+					   KEYPAD_BITMASK_COLS,
+					   NULL, input);
+	if (error) {
+		dev_err(&pdev->dev, "building keymap failed\n");
+		return error;
+	}
+
+	error = devm_request_irq(&pdev->dev, irq, nspire_keypad_irq, 0,
+				 "nspire_keypad", keypad);
+	if (error) {
+		dev_err(&pdev->dev, "allocate irq %d failed\n", irq);
+		return error;
+	}
+
+	error = input_register_device(input);
+	if (error) {
+		dev_err(&pdev->dev,
+			"unable to register input device: %d\n", error);
+		return error;
+	}
+
+	platform_set_drvdata(pdev, keypad);
+
+	dev_dbg(&pdev->dev,
+		"TI-NSPIRE keypad at %pR (scan_interval=%uus, row_delay=%uus%s)\n",
+		res, keypad->row_delay, keypad->scan_interval,
+		keypad->active_low ? ", active_low" : "");
+
+	return 0;
+}
+
+static const struct of_device_id nspire_keypad_dt_match[] = {
+	{ .compatible = "ti,nspire-keypad" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, nspire_keypad_dt_match);
+
+static struct platform_driver nspire_keypad_driver = {
+	.driver = {
+		.name = "nspire-keypad",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(nspire_keypad_dt_match),
+	},
+	.probe = nspire_keypad_probe,
+};
+
+module_platform_driver(nspire_keypad_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TI-NSPIRE Keypad Driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/omap4-keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/omap4-keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/omap4-keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/omap4-keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -419,8 +419,6 @@ static int omap4_keypad_remove(struct pl
 	kfree(keypad_data->keymap);
 	kfree(keypad_data);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/opencores-kbd.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/opencores-kbd.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/opencores-kbd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/opencores-kbd.c	2013-08-25 20:43:22.000000000 -0400
@@ -151,8 +151,6 @@ static int opencores_kbd_remove(struct p
 	input_unregister_device(opencores_kbd->input);
 	kfree(opencores_kbd);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/pmic8xxx-keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/pmic8xxx-keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/pmic8xxx-keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/pmic8xxx-keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -707,7 +707,6 @@ err_gpio_config:
 err_get_irq:
 	input_free_device(kp->input);
 err_alloc_device:
-	platform_set_drvdata(pdev, NULL);
 	kfree(kp);
 	return rc;
 }
@@ -722,7 +721,6 @@ static int pmic8xxx_kp_remove(struct pla
 	input_unregister_device(kp->input);
 	kfree(kp);
 
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/pxa27x_keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/pxa27x_keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/pxa27x_keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/pxa27x_keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -100,7 +100,7 @@
 #define MAX_KEYPAD_KEYS		(MAX_MATRIX_KEY_NUM + MAX_DIRECT_KEY_NUM)
 
 struct pxa27x_keypad {
-	struct pxa27x_keypad_platform_data *pdata;
+	const struct pxa27x_keypad_platform_data *pdata;
 
 	struct clk *clk;
 	struct input_dev *input_dev;
@@ -118,25 +118,254 @@ struct pxa27x_keypad {
 	unsigned int direct_key_mask;
 };
 
-static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
+#ifdef CONFIG_OF
+static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad,
+				struct pxa27x_keypad_platform_data *pdata)
 {
-	struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
 	struct input_dev *input_dev = keypad->input_dev;
-	unsigned short keycode;
+	struct device *dev = input_dev->dev.parent;
+	u32 rows, cols;
+	int error;
+
+	error = matrix_keypad_parse_of_params(dev, &rows, &cols);
+	if (error)
+		return error;
+
+	if (rows > MAX_MATRIX_KEY_ROWS || cols > MAX_MATRIX_KEY_COLS) {
+		dev_err(dev, "rows or cols exceeds maximum value\n");
+		return -EINVAL;
+	}
+
+	pdata->matrix_key_rows = rows;
+	pdata->matrix_key_cols = cols;
+
+	error = matrix_keypad_build_keymap(NULL, NULL,
+					   pdata->matrix_key_rows,
+					   pdata->matrix_key_cols,
+					   keypad->keycodes, input_dev);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static int pxa27x_keypad_direct_key_parse_dt(struct pxa27x_keypad *keypad,
+				struct pxa27x_keypad_platform_data *pdata)
+{
+	struct input_dev *input_dev = keypad->input_dev;
+	struct device *dev = input_dev->dev.parent;
+	struct device_node *np = dev->of_node;
+	const __be16 *prop;
+	unsigned short code;
+	unsigned int proplen, size;
 	int i;
+	int error;
 
-	for (i = 0; i < pdata->matrix_key_map_size; i++) {
-		unsigned int key = pdata->matrix_key_map[i];
-		unsigned int row = KEY_ROW(key);
-		unsigned int col = KEY_COL(key);
-		unsigned int scancode = MATRIX_SCAN_CODE(row, col,
-							 MATRIX_ROW_SHIFT);
+	error = of_property_read_u32(np, "marvell,direct-key-count",
+				     &pdata->direct_key_num);
+	if (error) {
+		/*
+		 * If do not have marvel,direct-key-count defined,
+		 * it means direct key is not supported.
+		 */
+		return error == -EINVAL ? 0 : error;
+	}
 
-		keycode = KEY_VAL(key);
-		keypad->keycodes[scancode] = keycode;
-		__set_bit(keycode, input_dev->keybit);
+	error = of_property_read_u32(np, "marvell,direct-key-mask",
+				     &pdata->direct_key_mask);
+	if (error) {
+		if (error != -EINVAL)
+			return error;
+
+		/*
+		 * If marvell,direct-key-mask is not defined, driver will use
+		 * default value. Default value is set when configure the keypad.
+		 */
+		pdata->direct_key_mask = 0;
+	}
+
+	pdata->direct_key_low_active = of_property_read_bool(np,
+					"marvell,direct-key-low-active");
+
+	prop = of_get_property(np, "marvell,direct-key-map", &proplen);
+	if (!prop)
+		return -EINVAL;
+
+	if (proplen % sizeof(u16))
+		return -EINVAL;
+
+	size = proplen / sizeof(u16);
+
+	/* Only MAX_DIRECT_KEY_NUM is accepted.*/
+	if (size > MAX_DIRECT_KEY_NUM)
+		return -EINVAL;
+
+	for (i = 0; i < size; i++) {
+		code = be16_to_cpup(prop + i);
+		keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = code;
+		__set_bit(code, input_dev->keybit);
+	}
+
+	return 0;
+}
+
+static int pxa27x_keypad_rotary_parse_dt(struct pxa27x_keypad *keypad,
+				struct pxa27x_keypad_platform_data *pdata)
+{
+	const __be32 *prop;
+	int i, relkey_ret;
+	unsigned int code, proplen;
+	const char *rotaryname[2] = {
+			"marvell,rotary0", "marvell,rotary1"};
+	const char relkeyname[] = {"marvell,rotary-rel-key"};
+	struct input_dev *input_dev = keypad->input_dev;
+	struct device *dev = input_dev->dev.parent;
+	struct device_node *np = dev->of_node;
+
+	relkey_ret = of_property_read_u32(np, relkeyname, &code);
+	/* if can read correct rotary key-code, we do not need this. */
+	if (relkey_ret == 0) {
+		unsigned short relcode;
+
+		/* rotary0 taks lower half, rotary1 taks upper half. */
+		relcode = code & 0xffff;
+		pdata->rotary0_rel_code = (code & 0xffff);
+		__set_bit(relcode, input_dev->relbit);
+
+		relcode = code >> 16;
+		pdata->rotary1_rel_code = relcode;
+		__set_bit(relcode, input_dev->relbit);
+	}
+
+	for (i = 0; i < 2; i++) {
+		prop = of_get_property(np, rotaryname[i], &proplen);
+		/*
+		 * If the prop is not set, it means keypad does not need
+		 * initialize the rotaryX.
+		 */
+		if (!prop)
+			continue;
+
+		code = be32_to_cpup(prop);
+		/*
+		 * Not all up/down key code are valid.
+		 * Now we depends on direct-rel-code.
+		 */
+		if ((!(code & 0xffff) || !(code >> 16)) && relkey_ret) {
+			return relkey_ret;
+		} else {
+			unsigned int n = MAX_MATRIX_KEY_NUM + (i << 1);
+			unsigned short keycode;
+
+			keycode = code & 0xffff;
+			keypad->keycodes[n] = keycode;
+			__set_bit(keycode, input_dev->keybit);
+
+			keycode = code >> 16;
+			keypad->keycodes[n + 1] = keycode;
+			__set_bit(keycode, input_dev->keybit);
+
+			if (i == 0)
+				pdata->rotary0_rel_code = -1;
+			else
+				pdata->rotary1_rel_code = -1;
+		}
+		if (i == 0)
+			pdata->enable_rotary0 = 1;
+		else
+			pdata->enable_rotary1 = 1;
+	}
+
+	keypad->rotary_rel_code[0] = pdata->rotary0_rel_code;
+	keypad->rotary_rel_code[1] = pdata->rotary1_rel_code;
+
+	return 0;
+}
+
+static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad)
+{
+	struct input_dev *input_dev = keypad->input_dev;
+	struct device *dev = input_dev->dev.parent;
+	struct device_node *np = dev->of_node;
+	struct pxa27x_keypad_platform_data *pdata;
+	int error;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "failed to allocate memory for pdata\n");
+		return -ENOMEM;
+	}
+
+	error = pxa27x_keypad_matrix_key_parse_dt(keypad, pdata);
+	if (error) {
+		dev_err(dev, "failed to parse matrix key\n");
+		return error;
+	}
+
+	error = pxa27x_keypad_direct_key_parse_dt(keypad, pdata);
+	if (error) {
+		dev_err(dev, "failed to parse direct key\n");
+		return error;
+	}
+
+	error = pxa27x_keypad_rotary_parse_dt(keypad, pdata);
+	if (error) {
+		dev_err(dev, "failed to parse rotary key\n");
+		return error;
+	}
+
+	error = of_property_read_u32(np, "marvell,debounce-interval",
+				     &pdata->debounce_interval);
+	if (error) {
+		dev_err(dev, "failed to parse debpunce-interval\n");
+		return error;
 	}
 
+	/*
+	 * The keycodes may not only includes matrix key but also the direct
+	 * key or rotary key.
+	 */
+	input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
+
+	keypad->pdata = pdata;
+	return 0;
+}
+
+#else
+
+static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad)
+{
+	dev_info(keypad->input_dev->dev.parent, "missing platform data\n");
+
+	return -EINVAL;
+}
+
+#endif
+
+static int pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
+{
+	const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+	struct input_dev *input_dev = keypad->input_dev;
+	const struct matrix_keymap_data *keymap_data =
+				pdata ? pdata->matrix_keymap_data : NULL;
+	unsigned short keycode;
+	int i;
+	int error;
+
+	error = matrix_keypad_build_keymap(keymap_data, NULL,
+					   pdata->matrix_key_rows,
+					   pdata->matrix_key_cols,
+					   keypad->keycodes, input_dev);
+	if (error)
+		return error;
+
+	/*
+	 * The keycodes may not only include matrix keys but also the direct
+	 * or rotary keys.
+	 */
+	input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
+
+	/* For direct keys. */
 	for (i = 0; i < pdata->direct_key_num; i++) {
 		keycode = pdata->direct_key_map[i];
 		keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = keycode;
@@ -178,11 +407,13 @@ static void pxa27x_keypad_build_keycode(
 	}
 
 	__clear_bit(KEY_RESERVED, input_dev->keybit);
+
+	return 0;
 }
 
 static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad)
 {
-	struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+	const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
 	struct input_dev *input_dev = keypad->input_dev;
 	int row, col, num_keys_pressed = 0;
 	uint32_t new_state[MAX_MATRIX_KEY_COLS];
@@ -284,7 +515,7 @@ static void report_rotary_event(struct p
 
 static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad)
 {
-	struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+	const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
 	uint32_t kprec;
 
 	/* read and reset to default count value */
@@ -300,7 +531,7 @@ static void pxa27x_keypad_scan_rotary(st
 
 static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
 {
-	struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+	const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
 	struct input_dev *input_dev = keypad->input_dev;
 	unsigned int new_state;
 	uint32_t kpdk, bits_changed;
@@ -340,7 +571,7 @@ static void pxa27x_keypad_scan_direct(st
 
 static void clear_wakeup_event(struct pxa27x_keypad *keypad)
 {
-	struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+	const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
 
 	if (pdata->clear_wakeup_event)
 		(pdata->clear_wakeup_event)();
@@ -364,7 +595,7 @@ static irqreturn_t pxa27x_keypad_irq_han
 
 static void pxa27x_keypad_config(struct pxa27x_keypad *keypad)
 {
-	struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+	const struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
 	unsigned int mask = 0, direct_key_num = 0;
 	unsigned long kpc = 0;
 
@@ -431,7 +662,7 @@ static void pxa27x_keypad_close(struct i
 	clk_disable_unprepare(keypad->clk);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int pxa27x_keypad_suspend(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -475,25 +706,25 @@ static int pxa27x_keypad_resume(struct d
 
 	return 0;
 }
-
-static const struct dev_pm_ops pxa27x_keypad_pm_ops = {
-	.suspend	= pxa27x_keypad_suspend,
-	.resume		= pxa27x_keypad_resume,
-};
 #endif
 
+static SIMPLE_DEV_PM_OPS(pxa27x_keypad_pm_ops,
+			 pxa27x_keypad_suspend, pxa27x_keypad_resume);
+
+
 static int pxa27x_keypad_probe(struct platform_device *pdev)
 {
-	struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data;
+	const struct pxa27x_keypad_platform_data *pdata =
+					dev_get_platdata(&pdev->dev);
+	struct device_node *np = pdev->dev.of_node;
 	struct pxa27x_keypad *keypad;
 	struct input_dev *input_dev;
 	struct resource *res;
 	int irq, error;
 
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "no platform data defined\n");
+	/* Driver need build keycode from device tree or pdata */
+	if (!np && !pdata)
 		return -EINVAL;
-	}
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -555,7 +786,14 @@ static int pxa27x_keypad_probe(struct pl
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 
-	pxa27x_keypad_build_keycode(keypad);
+	if (pdata)
+		error = pxa27x_keypad_build_keycode(keypad);
+	else
+		error = pxa27x_keypad_build_keycode_from_dt(keypad);
+	if (error) {
+		dev_err(&pdev->dev, "failed to build keycode\n");
+		goto failed_put_clk;
+	}
 
 	if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) ||
 	    (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) {
@@ -582,7 +820,7 @@ static int pxa27x_keypad_probe(struct pl
 	return 0;
 
 failed_free_irq:
-	free_irq(irq, pdev);
+	free_irq(irq, keypad);
 failed_put_clk:
 	clk_put(keypad->clk);
 failed_free_io:
@@ -600,7 +838,7 @@ static int pxa27x_keypad_remove(struct p
 	struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
 	struct resource *res;
 
-	free_irq(keypad->irq, pdev);
+	free_irq(keypad->irq, keypad);
 	clk_put(keypad->clk);
 
 	input_unregister_device(keypad->input_dev);
@@ -609,7 +847,6 @@ static int pxa27x_keypad_remove(struct p
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, resource_size(res));
 
-	platform_set_drvdata(pdev, NULL);
 	kfree(keypad);
 
 	return 0;
@@ -618,15 +855,22 @@ static int pxa27x_keypad_remove(struct p
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:pxa27x-keypad");
 
+#ifdef CONFIG_OF
+static const struct of_device_id pxa27x_keypad_dt_match[] = {
+	{ .compatible = "marvell,pxa27x-keypad" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, pxa27x_keypad_dt_match);
+#endif
+
 static struct platform_driver pxa27x_keypad_driver = {
 	.probe		= pxa27x_keypad_probe,
 	.remove		= pxa27x_keypad_remove,
 	.driver		= {
 		.name	= "pxa27x-keypad",
+		.of_match_table = of_match_ptr(pxa27x_keypad_dt_match),
 		.owner	= THIS_MODULE,
-#ifdef CONFIG_PM
 		.pm	= &pxa27x_keypad_pm_ops,
-#endif
 	},
 };
 module_platform_driver(pxa27x_keypad_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/pxa930_rotary.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/pxa930_rotary.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/pxa930_rotary.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/pxa930_rotary.c	2013-08-25 20:43:22.000000000 -0400
@@ -181,7 +181,6 @@ static int pxa930_rotary_remove(struct p
 	free_irq(platform_get_irq(pdev, 0), r);
 	input_unregister_device(r->input_dev);
 	iounmap(r->mmio_base);
-	platform_set_drvdata(pdev, NULL);
 	kfree(r);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/samsung-keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/samsung-keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/samsung-keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/samsung-keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/of.h>
-#include <linux/of_gpio.h>
 #include <linux/sched.h>
 #include <linux/input/samsung-keypad.h>
 
@@ -79,10 +78,6 @@ struct samsung_keypad {
 	unsigned int rows;
 	unsigned int cols;
 	unsigned int row_state[SAMSUNG_MAX_COLS];
-#ifdef CONFIG_OF
-	int row_gpios[SAMSUNG_MAX_ROWS];
-	int col_gpios[SAMSUNG_MAX_COLS];
-#endif
 	unsigned short keycodes[];
 };
 
@@ -304,45 +299,6 @@ static struct samsung_keypad_platdata *s
 
 	return pdata;
 }
-
-static void samsung_keypad_parse_dt_gpio(struct device *dev,
-				struct samsung_keypad *keypad)
-{
-	struct device_node *np = dev->of_node;
-	int gpio, error, row, col;
-
-	for (row = 0; row < keypad->rows; row++) {
-		gpio = of_get_named_gpio(np, "row-gpios", row);
-		keypad->row_gpios[row] = gpio;
-		if (!gpio_is_valid(gpio)) {
-			dev_err(dev, "keypad row[%d]: invalid gpio %d\n",
-					row, gpio);
-			continue;
-		}
-
-		error = devm_gpio_request(dev, gpio, "keypad-row");
-		if (error)
-			dev_err(dev,
-				"keypad row[%d] gpio request failed: %d\n",
-				row, error);
-	}
-
-	for (col = 0; col < keypad->cols; col++) {
-		gpio = of_get_named_gpio(np, "col-gpios", col);
-		keypad->col_gpios[col] = gpio;
-		if (!gpio_is_valid(gpio)) {
-			dev_err(dev, "keypad column[%d]: invalid gpio %d\n",
-					col, gpio);
-			continue;
-		}
-
-		error = devm_gpio_request(dev, gpio, "keypad-col");
-		if (error)
-			dev_err(dev,
-				"keypad column[%d] gpio request failed: %d\n",
-				col, error);
-	}
-}
 #else
 static
 struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev)
@@ -424,15 +380,11 @@ static int samsung_keypad_probe(struct p
 	keypad->stopped = true;
 	init_waitqueue_head(&keypad->wait);
 
-	if (pdev->dev.of_node) {
-#ifdef CONFIG_OF
-		samsung_keypad_parse_dt_gpio(&pdev->dev, keypad);
+	if (pdev->dev.of_node)
 		keypad->type = of_device_is_compatible(pdev->dev.of_node,
 					"samsung,s5pv210-keypad");
-#endif
-	} else {
+	else
 		keypad->type = platform_get_device_id(pdev)->driver_data;
-	}
 
 	input_dev->name = pdev->name;
 	input_dev->id.bustype = BUS_HOST;
@@ -487,7 +439,6 @@ static int samsung_keypad_probe(struct p
 err_disable_runtime_pm:
 	pm_runtime_disable(&pdev->dev);
 	device_init_wakeup(&pdev->dev, 0);
-	platform_set_drvdata(pdev, NULL);
 err_unprepare_clk:
 	clk_unprepare(keypad->clk);
 	return error;
@@ -499,7 +450,6 @@ static int samsung_keypad_remove(struct
 
 	pm_runtime_disable(&pdev->dev);
 	device_init_wakeup(&pdev->dev, 0);
-	platform_set_drvdata(pdev, NULL);
 
 	input_unregister_device(keypad->input_dev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/sh_keysc.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/sh_keysc.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/sh_keysc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/sh_keysc.c	2013-08-25 20:43:22.000000000 -0400
@@ -266,7 +266,6 @@ static int sh_keysc_probe(struct platfor
  err2:
 	iounmap(priv->iomem_base);
  err1:
-	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
  err0:
 	return error;
@@ -285,7 +284,6 @@ static int sh_keysc_remove(struct platfo
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
-	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/spear-keyboard.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/spear-keyboard.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/spear-keyboard.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/spear-keyboard.c	2013-08-25 20:43:22.000000000 -0400
@@ -290,7 +290,6 @@ static int spear_kbd_remove(struct platf
 	clk_unprepare(kbd->clk);
 
 	device_init_wakeup(&pdev->dev, 0);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/tnetv107x-keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/tnetv107x-keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/tnetv107x-keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/tnetv107x-keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -296,7 +296,6 @@ error_clk:
 error_map:
 	release_mem_region(kp->res->start, resource_size(kp->res));
 error_res:
-	platform_set_drvdata(pdev, NULL);
 	kfree(kp);
 	return error;
 }
@@ -311,7 +310,6 @@ static int keypad_remove(struct platform
 	clk_put(kp->clk);
 	iounmap(kp->regs);
 	release_mem_region(kp->res->start, resource_size(kp->res));
-	platform_set_drvdata(pdev, NULL);
 	kfree(kp);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/twl4030_keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/twl4030_keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/twl4030_keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/twl4030_keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -422,7 +422,7 @@ static int twl4030_kp_probe(struct platf
 err3:
 	/* mask all events - we don't care about the result */
 	(void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1);
-	free_irq(kp->irq, NULL);
+	free_irq(kp->irq, kp);
 err2:
 	input_unregister_device(input);
 	input = NULL;
@@ -438,7 +438,6 @@ static int twl4030_kp_remove(struct plat
 
 	free_irq(kp->irq, kp);
 	input_unregister_device(kp->input);
-	platform_set_drvdata(pdev, NULL);
 	kfree(kp);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/keyboard/w90p910_keypad.c linux-libre-3.11-rc7-gnu/drivers/input/keyboard/w90p910_keypad.c
--- linux-libre-3.10-gnu/drivers/input/keyboard/w90p910_keypad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/keyboard/w90p910_keypad.c	2013-08-25 20:43:22.000000000 -0400
@@ -221,7 +221,7 @@ static int w90p910_keypad_probe(struct p
 	return 0;
 
 failed_free_irq:
-	free_irq(irq, pdev);
+	free_irq(irq, keypad);
 failed_put_clk:
 	clk_put(keypad->clk);
 failed_free_io:
@@ -239,7 +239,7 @@ static int w90p910_keypad_remove(struct
 	struct w90p910_keypad *keypad = platform_get_drvdata(pdev);
 	struct resource *res;
 
-	free_irq(keypad->irq, pdev);
+	free_irq(keypad->irq, keypad);
 
 	clk_put(keypad->clk);
 
@@ -249,7 +249,6 @@ static int w90p910_keypad_remove(struct
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, resource_size(res));
 
-	platform_set_drvdata(pdev, NULL);
 	kfree(keypad);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/ab8500-ponkey.c linux-libre-3.11-rc7-gnu/drivers/input/misc/ab8500-ponkey.c
--- linux-libre-3.10-gnu/drivers/input/misc/ab8500-ponkey.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/ab8500-ponkey.c	2013-08-25 20:43:22.000000000 -0400
@@ -127,8 +127,6 @@ static int ab8500_ponkey_remove(struct p
 	input_unregister_device(ponkey->idev);
 	kfree(ponkey);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/bfin_rotary.c linux-libre-3.11-rc7-gnu/drivers/input/misc/bfin_rotary.c
--- linux-libre-3.10-gnu/drivers/input/misc/bfin_rotary.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/bfin_rotary.c	2013-08-25 20:43:22.000000000 -0400
@@ -208,7 +208,6 @@ static int bfin_rotary_remove(struct pla
 	peripheral_free_list(per_cnt);
 
 	kfree(rotary);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/da9055_onkey.c linux-libre-3.11-rc7-gnu/drivers/input/misc/da9055_onkey.c
--- linux-libre-3.10-gnu/drivers/input/misc/da9055_onkey.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/da9055_onkey.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,7 @@ static void da9055_onkey_query(struct da
 	} else {
 		key_stat &= DA9055_NOKEY_STS;
 		/*
-		 * Onkey status bit is cleared when onkey button is relased.
+		 * Onkey status bit is cleared when onkey button is released.
 		 */
 		if (!key_stat) {
 			input_report_key(onkey->input, KEY_POWER, 0);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/gpio_tilt_polled.c linux-libre-3.11-rc7-gnu/drivers/input/misc/gpio_tilt_polled.c
--- linux-libre-3.10-gnu/drivers/input/misc/gpio_tilt_polled.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/gpio_tilt_polled.c	2013-08-25 20:43:22.000000000 -0400
@@ -184,8 +184,6 @@ static int gpio_tilt_polled_remove(struc
 	struct gpio_tilt_polled_dev *tdev = platform_get_drvdata(pdev);
 	const struct gpio_tilt_platform_data *pdata = tdev->pdata;
 
-	platform_set_drvdata(pdev, NULL);
-
 	input_unregister_polled_device(tdev->poll_dev);
 	input_free_polled_device(tdev->poll_dev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/ixp4xx-beeper.c linux-libre-3.11-rc7-gnu/drivers/input/misc/ixp4xx-beeper.c
--- linux-libre-3.10-gnu/drivers/input/misc/ixp4xx-beeper.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/ixp4xx-beeper.c	2013-08-25 20:43:22.000000000 -0400
@@ -125,7 +125,7 @@ static int ixp4xx_spkr_probe(struct plat
 	return 0;
 
  err_free_irq:
-	free_irq(IRQ_IXP4XX_TIMER2, dev);
+	free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id);
  err_free_device:
 	input_free_device(input_dev);
 
@@ -138,13 +138,12 @@ static int ixp4xx_spkr_remove(struct pla
 	unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
 
 	input_unregister_device(input_dev);
-	platform_set_drvdata(dev, NULL);
 
 	/* turn the speaker off */
 	disable_irq(IRQ_IXP4XX_TIMER2);
 	ixp4xx_spkr_control(pin, 0);
 
-	free_irq(IRQ_IXP4XX_TIMER2, dev);
+	free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/Kconfig linux-libre-3.11-rc7-gnu/drivers/input/misc/Kconfig
--- linux-libre-3.10-gnu/drivers/input/misc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -637,4 +637,14 @@ config INPUT_XEN_KBDDEV_FRONTEND
 	  To compile this driver as a module, choose M here: the
 	  module will be called xen-kbdfront.
 
+config INPUT_SIRFSOC_ONKEY
+	bool "CSR SiRFSoC power on/off/suspend key support"
+	depends on ARCH_SIRF && OF
+	default y
+	help
+	  Say Y here if you want to support for the SiRFSoC power on/off/suspend key
+	  in Linux, after you press the onkey, system will suspend.
+
+	  If unsure, say N.
+
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/m68kspkr.c linux-libre-3.11-rc7-gnu/drivers/input/misc/m68kspkr.c
--- linux-libre-3.10-gnu/drivers/input/misc/m68kspkr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/m68kspkr.c	2013-08-25 20:43:22.000000000 -0400
@@ -85,7 +85,6 @@ static int m68kspkr_remove(struct platfo
 	struct input_dev *input_dev = platform_get_drvdata(dev);
 
 	input_unregister_device(input_dev);
-	platform_set_drvdata(dev, NULL);
 	/* turn off the speaker */
 	m68kspkr_event(NULL, EV_SND, SND_BELL, 0);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/Makefile linux-libre-3.11-rc7-gnu/drivers/input/misc/Makefile
--- linux-libre-3.10-gnu/drivers/input/misc/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -51,6 +51,7 @@ obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb53
 obj-$(CONFIG_INPUT_RETU_PWRBUTTON)	+= retu-pwrbutton.o
 obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
 obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
+obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)	+= sirfsoc-onkey.o
 obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)	+= twl4030-pwrbutton.o
 obj-$(CONFIG_INPUT_TWL4030_VIBRA)	+= twl4030-vibra.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/max8925_onkey.c linux-libre-3.11-rc7-gnu/drivers/input/misc/max8925_onkey.c
--- linux-libre-3.10-gnu/drivers/input/misc/max8925_onkey.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/max8925_onkey.c	2013-08-25 20:43:22.000000000 -0400
@@ -148,8 +148,6 @@ static int max8925_onkey_remove(struct p
 	input_unregister_device(info->idev);
 	kfree(info);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/mc13783-pwrbutton.c linux-libre-3.11-rc7-gnu/drivers/input/misc/mc13783-pwrbutton.c
--- linux-libre-3.10-gnu/drivers/input/misc/mc13783-pwrbutton.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/mc13783-pwrbutton.c	2013-08-25 20:43:22.000000000 -0400
@@ -250,7 +250,6 @@ static int mc13783_pwrbutton_remove(stru
 
 	input_unregister_device(priv->pwr);
 	kfree(priv);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/pcspkr.c linux-libre-3.11-rc7-gnu/drivers/input/misc/pcspkr.c
--- linux-libre-3.10-gnu/drivers/input/misc/pcspkr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/pcspkr.c	2013-08-25 20:43:22.000000000 -0400
@@ -100,7 +100,6 @@ static int pcspkr_remove(struct platform
 	struct input_dev *pcspkr_dev = platform_get_drvdata(dev);
 
 	input_unregister_device(pcspkr_dev);
-	platform_set_drvdata(dev, NULL);
 	/* turn off the speaker */
 	pcspkr_event(NULL, EV_SND, SND_BELL, 0);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/pm8xxx-vibrator.c linux-libre-3.11-rc7-gnu/drivers/input/misc/pm8xxx-vibrator.c
--- linux-libre-3.10-gnu/drivers/input/misc/pm8xxx-vibrator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/pm8xxx-vibrator.c	2013-08-25 20:43:22.000000000 -0400
@@ -249,8 +249,6 @@ static int pm8xxx_vib_remove(struct plat
 	input_unregister_device(vib->vib_input_dev);
 	kfree(vib);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/pmic8xxx-pwrkey.c linux-libre-3.11-rc7-gnu/drivers/input/misc/pmic8xxx-pwrkey.c
--- linux-libre-3.10-gnu/drivers/input/misc/pmic8xxx-pwrkey.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/pmic8xxx-pwrkey.c	2013-08-25 20:43:22.000000000 -0400
@@ -175,9 +175,8 @@ static int pmic8xxx_pwrkey_probe(struct
 	return 0;
 
 free_press_irq:
-	free_irq(key_press_irq, NULL);
+	free_irq(key_press_irq, pwrkey);
 unreg_input_dev:
-	platform_set_drvdata(pdev, NULL);
 	input_unregister_device(pwr);
 	pwr = NULL;
 free_input_dev:
@@ -198,7 +197,6 @@ static int pmic8xxx_pwrkey_remove(struct
 	free_irq(key_press_irq, pwrkey);
 	free_irq(key_release_irq, pwrkey);
 	input_unregister_device(pwrkey->pwr);
-	platform_set_drvdata(pdev, NULL);
 	kfree(pwrkey);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/pwm-beeper.c linux-libre-3.11-rc7-gnu/drivers/input/misc/pwm-beeper.c
--- linux-libre-3.10-gnu/drivers/input/misc/pwm-beeper.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/pwm-beeper.c	2013-08-25 20:43:22.000000000 -0400
@@ -133,7 +133,6 @@ static int pwm_beeper_remove(struct plat
 {
 	struct pwm_beeper *beeper = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	input_unregister_device(beeper->input);
 
 	pwm_disable(beeper->pwm);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/rotary_encoder.c linux-libre-3.11-rc7-gnu/drivers/input/misc/rotary_encoder.c
--- linux-libre-3.10-gnu/drivers/input/misc/rotary_encoder.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/rotary_encoder.c	2013-08-25 20:43:22.000000000 -0400
@@ -317,8 +317,6 @@ static int rotary_encoder_remove(struct
 	if (!dev_get_platdata(&pdev->dev))
 		kfree(pdata);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/sgi_btns.c linux-libre-3.11-rc7-gnu/drivers/input/misc/sgi_btns.c
--- linux-libre-3.10-gnu/drivers/input/misc/sgi_btns.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/sgi_btns.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,7 +128,7 @@ static int sgi_buttons_probe(struct plat
 	__clear_bit(KEY_RESERVED, input->keybit);
 
 	bdev->poll_dev = poll_dev;
-	dev_set_drvdata(&pdev->dev, bdev);
+	platform_set_drvdata(pdev, bdev);
 
 	error = input_register_polled_device(poll_dev);
 	if (error)
@@ -139,19 +139,16 @@ static int sgi_buttons_probe(struct plat
  err_free_mem:
 	input_free_polled_device(poll_dev);
 	kfree(bdev);
-	dev_set_drvdata(&pdev->dev, NULL);
 	return error;
 }
 
 static int sgi_buttons_remove(struct platform_device *pdev)
 {
-	struct device *dev = &pdev->dev;
-	struct buttons_dev *bdev = dev_get_drvdata(dev);
+	struct buttons_dev *bdev = platform_get_drvdata(pdev);
 
 	input_unregister_polled_device(bdev->poll_dev);
 	input_free_polled_device(bdev->poll_dev);
 	kfree(bdev);
-	dev_set_drvdata(dev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/sirfsoc-onkey.c linux-libre-3.11-rc7-gnu/drivers/input/misc/sirfsoc-onkey.c
--- linux-libre-3.10-gnu/drivers/input/misc/sirfsoc-onkey.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/sirfsoc-onkey.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,165 @@
+/*
+ * Power key driver for SiRF PrimaII
+ *
+ * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/rtc/sirfsoc_rtciobrg.h>
+#include <linux/of.h>
+
+struct sirfsoc_pwrc_drvdata {
+	u32			pwrc_base;
+	struct input_dev	*input;
+};
+
+#define PWRC_ON_KEY_BIT			(1 << 0)
+
+#define PWRC_INT_STATUS			0xc
+#define PWRC_INT_MASK			0x10
+
+static irqreturn_t sirfsoc_pwrc_isr(int irq, void *dev_id)
+{
+	struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_id;
+	u32 int_status;
+
+	int_status = sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base +
+							PWRC_INT_STATUS);
+	sirfsoc_rtc_iobrg_writel(int_status & ~PWRC_ON_KEY_BIT,
+				 pwrcdrv->pwrc_base + PWRC_INT_STATUS);
+
+	/*
+	 * For a typical Linux system, we report KEY_SUSPEND to trigger apm-power.c
+	 * to queue a SUSPEND APM event
+	 */
+	input_event(pwrcdrv->input, EV_PWR, KEY_SUSPEND, 1);
+	input_sync(pwrcdrv->input);
+
+	/*
+	 * Todo: report KEY_POWER event for Android platforms, Android PowerManager
+	 * will handle the suspend and powerdown/hibernation
+	 */
+
+	return IRQ_HANDLED;
+}
+
+static const struct of_device_id sirfsoc_pwrc_of_match[] = {
+	{ .compatible = "sirf,prima2-pwrc" },
+	{},
+}
+MODULE_DEVICE_TABLE(of, sirfsoc_pwrc_of_match);
+
+static int sirfsoc_pwrc_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct sirfsoc_pwrc_drvdata *pwrcdrv;
+	int irq;
+	int error;
+
+	pwrcdrv = devm_kzalloc(&pdev->dev, sizeof(struct sirfsoc_pwrc_drvdata),
+			       GFP_KERNEL);
+	if (!pwrcdrv) {
+		dev_info(&pdev->dev, "Not enough memory for the device data\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * we can't use of_iomap because pwrc is not mapped in memory,
+	 * the so-called base address is only offset in rtciobrg
+	 */
+	error = of_property_read_u32(np, "reg", &pwrcdrv->pwrc_base);
+	if (error) {
+		dev_err(&pdev->dev,
+			"unable to find base address of pwrc node in dtb\n");
+		return error;
+	}
+
+	pwrcdrv->input = devm_input_allocate_device(&pdev->dev);
+	if (!pwrcdrv->input)
+		return -ENOMEM;
+
+	pwrcdrv->input->name = "sirfsoc pwrckey";
+	pwrcdrv->input->phys = "pwrc/input0";
+	pwrcdrv->input->evbit[0] = BIT_MASK(EV_PWR);
+
+	irq = platform_get_irq(pdev, 0);
+	error = devm_request_irq(&pdev->dev, irq,
+				 sirfsoc_pwrc_isr, IRQF_SHARED,
+				 "sirfsoc_pwrc_int", pwrcdrv);
+	if (error) {
+		dev_err(&pdev->dev, "unable to claim irq %d, error: %d\n",
+			irq, error);
+		return error;
+	}
+
+	sirfsoc_rtc_iobrg_writel(
+		sirfsoc_rtc_iobrg_readl(pwrcdrv->pwrc_base + PWRC_INT_MASK) |
+			PWRC_ON_KEY_BIT,
+		pwrcdrv->pwrc_base + PWRC_INT_MASK);
+
+	error = input_register_device(pwrcdrv->input);
+	if (error) {
+		dev_err(&pdev->dev,
+			"unable to register input device, error: %d\n",
+			error);
+		return error;
+	}
+
+	platform_set_drvdata(pdev, pwrcdrv);
+	device_init_wakeup(&pdev->dev, 1);
+
+	return 0;
+}
+
+static int sirfsoc_pwrc_remove(struct platform_device *pdev)
+{
+	device_init_wakeup(&pdev->dev, 0);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwrc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sirfsoc_pwrc_drvdata *pwrcdrv = platform_get_drvdata(pdev);
+
+	/*
+	 * Do not mask pwrc interrupt as we want pwrc work as a wakeup source
+	 * if users touch X_ONKEY_B, see arch/arm/mach-prima2/pm.c
+	 */
+	sirfsoc_rtc_iobrg_writel(
+		sirfsoc_rtc_iobrg_readl(
+		pwrcdrv->pwrc_base + PWRC_INT_MASK) | PWRC_ON_KEY_BIT,
+		pwrcdrv->pwrc_base + PWRC_INT_MASK);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, pwrc_resume);
+
+static struct platform_driver sirfsoc_pwrc_driver = {
+	.probe		= sirfsoc_pwrc_probe,
+	.remove		= sirfsoc_pwrc_remove,
+	.driver		= {
+		.name	= "sirfsoc-pwrc",
+		.owner	= THIS_MODULE,
+		.pm	= &sirfsoc_pwrc_pm_ops,
+		.of_match_table = of_match_ptr(sirfsoc_pwrc_of_match),
+	}
+};
+
+module_platform_driver(sirfsoc_pwrc_driver);
+
+MODULE_LICENSE("GPLv2");
+MODULE_AUTHOR("Binghua Duan <Binghua.Duan@csr.com>, Xianglong Du <Xianglong.Du@csr.com>");
+MODULE_DESCRIPTION("CSR Prima2 PWRC Driver");
+MODULE_ALIAS("platform:sirfsoc-pwrc");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/misc/sparcspkr.c linux-libre-3.11-rc7-gnu/drivers/input/misc/sparcspkr.c
--- linux-libre-3.10-gnu/drivers/input/misc/sparcspkr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/misc/sparcspkr.c	2013-08-25 20:43:22.000000000 -0400
@@ -175,7 +175,7 @@ static int sparcspkr_probe(struct device
 
 static void sparcspkr_shutdown(struct platform_device *dev)
 {
-	struct sparcspkr_state *state = dev_get_drvdata(&dev->dev);
+	struct sparcspkr_state *state = platform_get_drvdata(dev);
 	struct input_dev *input_dev = state->input_dev;
 
 	/* turn off the speaker */
@@ -211,7 +211,7 @@ static int bbc_beep_probe(struct platfor
 	if (!info->regs)
 		goto out_free;
 
-	dev_set_drvdata(&op->dev, state);
+	platform_set_drvdata(op, state);
 
 	err = sparcspkr_probe(&op->dev);
 	if (err)
@@ -220,7 +220,6 @@ static int bbc_beep_probe(struct platfor
 	return 0;
 
 out_clear_drvdata:
-	dev_set_drvdata(&op->dev, NULL);
 	of_iounmap(&op->resource[0], info->regs, 6);
 
 out_free:
@@ -231,7 +230,7 @@ out_err:
 
 static int bbc_remove(struct platform_device *op)
 {
-	struct sparcspkr_state *state = dev_get_drvdata(&op->dev);
+	struct sparcspkr_state *state = platform_get_drvdata(op);
 	struct input_dev *input_dev = state->input_dev;
 	struct bbc_beep_info *info = &state->u.bbc;
 
@@ -242,7 +241,6 @@ static int bbc_remove(struct platform_de
 
 	of_iounmap(&op->resource[0], info->regs, 6);
 
-	dev_set_drvdata(&op->dev, NULL);
 	kfree(state);
 
 	return 0;
@@ -290,7 +288,7 @@ static int grover_beep_probe(struct plat
 	if (!info->enable_reg)
 		goto out_unmap_freq_regs;
 
-	dev_set_drvdata(&op->dev, state);
+	platform_set_drvdata(op, state);
 
 	err = sparcspkr_probe(&op->dev);
 	if (err)
@@ -299,7 +297,6 @@ static int grover_beep_probe(struct plat
 	return 0;
 
 out_clear_drvdata:
-	dev_set_drvdata(&op->dev, NULL);
 	of_iounmap(&op->resource[3], info->enable_reg, 1);
 
 out_unmap_freq_regs:
@@ -312,7 +309,7 @@ out_err:
 
 static int grover_remove(struct platform_device *op)
 {
-	struct sparcspkr_state *state = dev_get_drvdata(&op->dev);
+	struct sparcspkr_state *state = platform_get_drvdata(op);
 	struct grover_beep_info *info = &state->u.grover;
 	struct input_dev *input_dev = state->input_dev;
 
@@ -324,7 +321,6 @@ static int grover_remove(struct platform
 	of_iounmap(&op->resource[3], info->enable_reg, 1);
 	of_iounmap(&op->resource[2], info->freq_regs, 2);
 
-	dev_set_drvdata(&op->dev, NULL);
 	kfree(state);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/mouse/amimouse.c linux-libre-3.11-rc7-gnu/drivers/input/mouse/amimouse.c
--- linux-libre-3.10-gnu/drivers/input/mouse/amimouse.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/mouse/amimouse.c	2013-08-25 20:43:22.000000000 -0400
@@ -133,7 +133,6 @@ static int __exit amimouse_remove(struct
 {
 	struct input_dev *dev = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	input_unregister_device(dev);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/mouse/bcm5974.c linux-libre-3.11-rc7-gnu/drivers/input/mouse/bcm5974.c
--- linux-libre-3.10-gnu/drivers/input/mouse/bcm5974.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/mouse/bcm5974.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,6 +88,10 @@
 #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI	0x0259
 #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO	0x025a
 #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS	0x025b
+/* MacbookAir6,2 (unibody, June 2013) */
+#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI	0x0291
+#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO	0x0292
+#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS	0x0293
 
 #define BCM5974_DEVICE(prod) {					\
 	.match_flags = (USB_DEVICE_ID_MATCH_DEVICE |		\
@@ -145,6 +149,10 @@ static const struct usb_device_id bcm597
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI),
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO),
 	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),
+	/* MacbookAir6,2 */
+	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI),
+	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ISO),
+	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),
 	/* Terminating entry */
 	{}
 };
@@ -172,15 +180,18 @@ struct bt_data {
 /* trackpad header types */
 enum tp_type {
 	TYPE1,			/* plain trackpad */
-	TYPE2			/* button integrated in trackpad */
+	TYPE2,			/* button integrated in trackpad */
+	TYPE3			/* additional header fields since June 2013 */
 };
 
 /* trackpad finger data offsets, le16-aligned */
 #define FINGER_TYPE1		(13 * sizeof(__le16))
 #define FINGER_TYPE2		(15 * sizeof(__le16))
+#define FINGER_TYPE3		(19 * sizeof(__le16))
 
 /* trackpad button data offsets */
 #define BUTTON_TYPE2		15
+#define BUTTON_TYPE3		23
 
 /* list of device capability bits */
 #define HAS_INTEGRATED_BUTTON	1
@@ -400,6 +411,19 @@ static const struct bcm5974_config bcm59
 		{ SN_COORD, -150, 6730 },
 		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
 	},
+	{
+		USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI,
+		USB_DEVICE_ID_APPLE_WELLSPRING8_ISO,
+		USB_DEVICE_ID_APPLE_WELLSPRING8_JIS,
+		HAS_INTEGRATED_BUTTON,
+		0, sizeof(struct bt_data),
+		0x83, TYPE3, FINGER_TYPE3, FINGER_TYPE3 + SIZEOF_ALL_FINGERS,
+		{ SN_PRESSURE, 0, 300 },
+		{ SN_WIDTH, 0, 2048 },
+		{ SN_COORD, -4620, 5140 },
+		{ SN_COORD, -150, 6600 },
+		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
+	},
 	{}
 };
 
@@ -557,6 +581,9 @@ static int report_tp_state(struct bcm597
 		input_report_key(input, BTN_LEFT, ibt);
 	}
 
+	if (c->tp_type == TYPE3)
+		input_report_key(input, BTN_LEFT, dev->tp_data[BUTTON_TYPE3]);
+
 	input_sync(input);
 
 	return 0;
@@ -572,9 +599,14 @@ static int report_tp_state(struct bcm597
 
 static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
 {
-	char *data = kmalloc(8, GFP_KERNEL);
 	int retval = 0, size;
+	char *data;
 
+	/* Type 3 does not require a mode switch */
+	if (dev->cfg.tp_type == TYPE3)
+		return 0;
+
+	data = kmalloc(8, GFP_KERNEL);
 	if (!data) {
 		dev_err(&dev->intf->dev, "out of memory\n");
 		retval = -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/mouse/elantech.c linux-libre-3.11-rc7-gnu/drivers/input/mouse/elantech.c
--- linux-libre-3.10-gnu/drivers/input/mouse/elantech.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/mouse/elantech.c	2013-08-25 20:43:22.000000000 -0400
@@ -694,18 +694,18 @@ static int elantech_packet_check_v3(stru
 static int elantech_packet_check_v4(struct psmouse *psmouse)
 {
 	unsigned char *packet = psmouse->packet;
+	unsigned char packet_type = packet[3] & 0x03;
 
-	if ((packet[0] & 0x0c) == 0x04 &&
-	    (packet[3] & 0x1f) == 0x11)
+	switch (packet_type) {
+	case 0:
+		return PACKET_V4_STATUS;
+
+	case 1:
 		return PACKET_V4_HEAD;
 
-	if ((packet[0] & 0x0c) == 0x04 &&
-	    (packet[3] & 0x1f) == 0x12)
+	case 2:
 		return PACKET_V4_MOTION;
-
-	if ((packet[0] & 0x0c) == 0x04 &&
-	    (packet[3] & 0x1f) == 0x10)
-		return PACKET_V4_STATUS;
+	}
 
 	return PACKET_UNKNOWN;
 }
@@ -1282,6 +1282,7 @@ static int elantech_set_properties(struc
 			etd->hw_version = 3;
 			break;
 		case 6:
+		case 7:
 			etd->hw_version = 4;
 			break;
 		default:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/mouse/gpio_mouse.c linux-libre-3.11-rc7-gnu/drivers/input/mouse/gpio_mouse.c
--- linux-libre-3.10-gnu/drivers/input/mouse/gpio_mouse.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/mouse/gpio_mouse.c	2013-08-25 20:43:22.000000000 -0400
@@ -138,7 +138,6 @@ static int gpio_mouse_probe(struct platf
 
  out_free_polldev:
 	input_free_polled_device(input_poll);
-	platform_set_drvdata(pdev, NULL);
 
  out_free_gpios:
 	while (--i >= 0) {
@@ -165,8 +164,6 @@ static int gpio_mouse_remove(struct plat
 			gpio_free(pin);
 	}
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/mouse/navpoint.c linux-libre-3.11-rc7-gnu/drivers/input/mouse/navpoint.c
--- linux-libre-3.10-gnu/drivers/input/mouse/navpoint.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/mouse/navpoint.c	2013-08-25 20:43:22.000000000 -0400
@@ -287,7 +287,7 @@ static int navpoint_probe(struct platfor
 	return 0;
 
 err_free_irq:
-	free_irq(ssp->irq, &pdev->dev);
+	free_irq(ssp->irq, navpoint);
 err_free_mem:
 	input_free_device(input);
 	kfree(navpoint);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/serio/altera_ps2.c linux-libre-3.11-rc7-gnu/drivers/input/serio/altera_ps2.c
--- linux-libre-3.10-gnu/drivers/input/serio/altera_ps2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/serio/altera_ps2.c	2013-08-25 20:43:22.000000000 -0400
@@ -163,7 +163,6 @@ static int altera_ps2_remove(struct plat
 {
 	struct ps2if *ps2if = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	serio_unregister_port(ps2if->io);
 	free_irq(ps2if->irq, ps2if);
 	iounmap(ps2if->base);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/serio/at32psif.c linux-libre-3.11-rc7-gnu/drivers/input/serio/at32psif.c
--- linux-libre-3.10-gnu/drivers/input/serio/at32psif.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/serio/at32psif.c	2013-08-25 20:43:22.000000000 -0400
@@ -314,8 +314,6 @@ static int __exit psif_remove(struct pla
 	clk_put(psif->pclk);
 	kfree(psif);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/serio/Kconfig linux-libre-3.11-rc7-gnu/drivers/input/serio/Kconfig
--- linux-libre-3.10-gnu/drivers/input/serio/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/serio/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -256,4 +256,14 @@ config SERIO_APBPS2
 	  To compile this driver as a module, choose M here: the module will
 	  be called apbps2.
 
+config SERIO_OLPC_APSP
+	tristate "OLPC AP-SP input support"
+	depends on OF
+	help
+	  Say Y here if you want support for the keyboard and touchpad included
+	  in the OLPC XO-1.75 and XO-4 laptops.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called olpc_apsp.
+
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/serio/Makefile linux-libre-3.11-rc7-gnu/drivers/input/serio/Makefile
--- linux-libre-3.10-gnu/drivers/input/serio/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/serio/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -27,3 +27,4 @@ obj-$(CONFIG_SERIO_XILINX_XPS_PS2)	+= xi
 obj-$(CONFIG_SERIO_ALTERA_PS2)	+= altera_ps2.o
 obj-$(CONFIG_SERIO_ARC_PS2)	+= arc_ps2.o
 obj-$(CONFIG_SERIO_APBPS2)	+= apbps2.o
+obj-$(CONFIG_SERIO_OLPC_APSP)	+= olpc_apsp.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/serio/olpc_apsp.c linux-libre-3.11-rc7-gnu/drivers/input/serio/olpc_apsp.c
--- linux-libre-3.10-gnu/drivers/input/serio/olpc_apsp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/input/serio/olpc_apsp.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,287 @@
+/*
+ * OLPC serio driver for multiplexed input from Marvell MMP security processor
+ *
+ * Copyright (C) 2011-2013 One Laptop Per Child
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+/*
+ * The OLPC XO-1.75 and XO-4 laptops do not have a hardware PS/2 controller.
+ * Instead, the OLPC firmware runs a bit-banging PS/2 implementation on an
+ * otherwise-unused slow processor which is included in the Marvell MMP2/MMP3
+ * SoC, known as the "Security Processor" (SP) or "Wireless Trusted Module"
+ * (WTM). This firmware then reports its results via the WTM registers,
+ * which we read from the Application Processor (AP, i.e. main CPU) in this
+ * driver.
+ *
+ * On the hardware side we have a PS/2 mouse and an AT keyboard, the data
+ * is multiplexed through this system. We create a serio port for each one,
+ * and demultiplex the data accordingly.
+ */
+
+/* WTM register offsets */
+#define SECURE_PROCESSOR_COMMAND	0x40
+#define COMMAND_RETURN_STATUS		0x80
+#define COMMAND_FIFO_STATUS		0xc4
+#define PJ_RST_INTERRUPT		0xc8
+#define PJ_INTERRUPT_MASK		0xcc
+
+/*
+ * The upper byte of SECURE_PROCESSOR_COMMAND and COMMAND_RETURN_STATUS is
+ * used to identify which port (device) is being talked to. The lower byte
+ * is the data being sent/received.
+ */
+#define PORT_MASK	0xff00
+#define DATA_MASK	0x00ff
+#define PORT_SHIFT	8
+#define KEYBOARD_PORT	0
+#define TOUCHPAD_PORT	1
+
+/* COMMAND_FIFO_STATUS */
+#define CMD_CNTR_MASK		0x7 /* Number of pending/unprocessed commands */
+#define MAX_PENDING_CMDS	4   /* from device specs */
+
+/* PJ_RST_INTERRUPT */
+#define SP_COMMAND_COMPLETE_RESET	0x1
+
+/* PJ_INTERRUPT_MASK */
+#define INT_0	(1 << 0)
+
+/* COMMAND_FIFO_STATUS */
+#define CMD_STS_MASK	0x100
+
+struct olpc_apsp {
+	struct device *dev;
+	struct serio *kbio;
+	struct serio *padio;
+	void __iomem *base;
+	int open_count;
+	int irq;
+};
+
+static int olpc_apsp_write(struct serio *port, unsigned char val)
+{
+	struct olpc_apsp *priv = port->port_data;
+	unsigned int i;
+	u32 which = 0;
+
+	if (port == priv->padio)
+		which = TOUCHPAD_PORT << PORT_SHIFT;
+	else
+		which = KEYBOARD_PORT << PORT_SHIFT;
+
+	dev_dbg(priv->dev, "olpc_apsp_write which=%x val=%x\n", which, val);
+	for (i = 0; i < 50; i++) {
+		u32 sts = readl(priv->base + COMMAND_FIFO_STATUS);
+		if ((sts & CMD_CNTR_MASK) < MAX_PENDING_CMDS) {
+			writel(which | val,
+			       priv->base + SECURE_PROCESSOR_COMMAND);
+			return 0;
+		}
+		/* SP busy. This has not been seen in practice. */
+		mdelay(1);
+	}
+
+	dev_dbg(priv->dev, "olpc_apsp_write timeout, status=%x\n",
+		readl(priv->base + COMMAND_FIFO_STATUS));
+
+	return -ETIMEDOUT;
+}
+
+static irqreturn_t olpc_apsp_rx(int irq, void *dev_id)
+{
+	struct olpc_apsp *priv = dev_id;
+	unsigned int w, tmp;
+	struct serio *serio;
+
+	/*
+	 * Write 1 to PJ_RST_INTERRUPT to acknowledge and clear the interrupt
+	 * Write 0xff00 to SECURE_PROCESSOR_COMMAND.
+	 */
+	tmp = readl(priv->base + PJ_RST_INTERRUPT);
+	if (!(tmp & SP_COMMAND_COMPLETE_RESET)) {
+		dev_warn(priv->dev, "spurious interrupt?\n");
+		return IRQ_NONE;
+	}
+
+	w = readl(priv->base + COMMAND_RETURN_STATUS);
+	dev_dbg(priv->dev, "olpc_apsp_rx %x\n", w);
+
+	if (w >> PORT_SHIFT == KEYBOARD_PORT)
+		serio = priv->kbio;
+	else
+		serio = priv->padio;
+
+	serio_interrupt(serio, w & DATA_MASK, 0);
+
+	/* Ack and clear interrupt */
+	writel(tmp | SP_COMMAND_COMPLETE_RESET, priv->base + PJ_RST_INTERRUPT);
+	writel(PORT_MASK, priv->base + SECURE_PROCESSOR_COMMAND);
+
+	pm_wakeup_event(priv->dev, 1000);
+	return IRQ_HANDLED;
+}
+
+static int olpc_apsp_open(struct serio *port)
+{
+	struct olpc_apsp *priv = port->port_data;
+	unsigned int tmp;
+
+	if (priv->open_count++ == 0) {
+		/* Enable interrupt 0 by clearing its bit */
+		tmp = readl(priv->base + PJ_INTERRUPT_MASK);
+		writel(tmp & ~INT_0, priv->base + PJ_INTERRUPT_MASK);
+	}
+
+	return 0;
+}
+
+static void olpc_apsp_close(struct serio *port)
+{
+	struct olpc_apsp *priv = port->port_data;
+	unsigned int tmp;
+
+	if (--priv->open_count == 0) {
+		/* Disable interrupt 0 */
+		tmp = readl(priv->base + PJ_INTERRUPT_MASK);
+		writel(tmp | INT_0, priv->base + PJ_INTERRUPT_MASK);
+	}
+}
+
+static int olpc_apsp_probe(struct platform_device *pdev)
+{
+	struct serio *kb_serio, *pad_serio;
+	struct olpc_apsp *priv;
+	struct resource *res;
+	struct device_node *np;
+	unsigned long l;
+	int error;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct olpc_apsp), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	np = pdev->dev.of_node;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENOENT;
+
+	priv->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->base)) {
+		dev_err(&pdev->dev, "Failed to map WTM registers\n");
+		return PTR_ERR(priv->base);
+	}
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (priv->irq < 0)
+		return priv->irq;
+
+	l = readl(priv->base + COMMAND_FIFO_STATUS);
+	if (!(l & CMD_STS_MASK)) {
+		dev_err(&pdev->dev, "SP cannot accept commands.\n");
+		return -EIO;
+	}
+
+	/* KEYBOARD */
+	kb_serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!kb_serio)
+		return -ENOMEM;
+	kb_serio->id.type	= SERIO_8042_XL;
+	kb_serio->write		= olpc_apsp_write;
+	kb_serio->open		= olpc_apsp_open;
+	kb_serio->close		= olpc_apsp_close;
+	kb_serio->port_data	= priv;
+	kb_serio->dev.parent	= &pdev->dev;
+	strlcpy(kb_serio->name, "sp keyboard", sizeof(kb_serio->name));
+	strlcpy(kb_serio->phys, "sp/serio0", sizeof(kb_serio->phys));
+	priv->kbio		= kb_serio;
+	serio_register_port(kb_serio);
+
+	/* TOUCHPAD */
+	pad_serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!pad_serio) {
+		error = -ENOMEM;
+		goto err_pad;
+	}
+	pad_serio->id.type	= SERIO_8042;
+	pad_serio->write	= olpc_apsp_write;
+	pad_serio->open		= olpc_apsp_open;
+	pad_serio->close	= olpc_apsp_close;
+	pad_serio->port_data	= priv;
+	pad_serio->dev.parent	= &pdev->dev;
+	strlcpy(pad_serio->name, "sp touchpad", sizeof(pad_serio->name));
+	strlcpy(pad_serio->phys, "sp/serio1", sizeof(pad_serio->phys));
+	priv->padio		= pad_serio;
+	serio_register_port(pad_serio);
+
+	error = request_irq(priv->irq, olpc_apsp_rx, 0, "olpc-apsp", priv);
+	if (error) {
+		dev_err(&pdev->dev, "Failed to request IRQ\n");
+		goto err_irq;
+	}
+
+	priv->dev = &pdev->dev;
+	device_init_wakeup(priv->dev, 1);
+	platform_set_drvdata(pdev, priv);
+
+	dev_dbg(&pdev->dev, "probed successfully.\n");
+	return 0;
+
+err_irq:
+	serio_unregister_port(pad_serio);
+err_pad:
+	serio_unregister_port(kb_serio);
+	return error;
+}
+
+static int olpc_apsp_remove(struct platform_device *pdev)
+{
+	struct olpc_apsp *priv = platform_get_drvdata(pdev);
+
+	free_irq(priv->irq, priv);
+
+	serio_unregister_port(priv->kbio);
+	serio_unregister_port(priv->padio);
+
+	return 0;
+}
+
+static struct of_device_id olpc_apsp_dt_ids[] = {
+	{ .compatible = "olpc,ap-sp", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, olpc_apsp_dt_ids);
+
+static struct platform_driver olpc_apsp_driver = {
+	.probe		= olpc_apsp_probe,
+	.remove		= olpc_apsp_remove,
+	.driver		= {
+		.name	= "olpc-apsp",
+		.owner	= THIS_MODULE,
+		.of_match_table = olpc_apsp_dt_ids,
+	},
+};
+
+MODULE_DESCRIPTION("OLPC AP-SP serio driver");
+MODULE_LICENSE("GPL");
+module_platform_driver(olpc_apsp_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/serio/q40kbd.c linux-libre-3.11-rc7-gnu/drivers/input/serio/q40kbd.c
--- linux-libre-3.10-gnu/drivers/input/serio/q40kbd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/serio/q40kbd.c	2013-08-25 20:43:22.000000000 -0400
@@ -181,7 +181,6 @@ static int q40kbd_remove(struct platform
 	free_irq(Q40_IRQ_KEYBOARD, q40kbd);
 	kfree(q40kbd);
 
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/serio/xilinx_ps2.c linux-libre-3.11-rc7-gnu/drivers/input/serio/xilinx_ps2.c
--- linux-libre-3.10-gnu/drivers/input/serio/xilinx_ps2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/serio/xilinx_ps2.c	2013-08-25 20:43:22.000000000 -0400
@@ -349,8 +349,6 @@ static int xps2_of_remove(struct platfor
 
 	kfree(drvdata);
 
-	platform_set_drvdata(of_dev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/88pm860x-ts.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/88pm860x-ts.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/88pm860x-ts.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/88pm860x-ts.c	2013-08-25 20:43:22.000000000 -0400
@@ -237,7 +237,7 @@ static int pm860x_touch_probe(struct pla
 	touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
 	if (touch == NULL)
 		return -ENOMEM;
-	dev_set_drvdata(&pdev->dev, touch);
+	platform_set_drvdata(pdev, touch);
 
 	touch->idev = input_allocate_device();
 	if (touch->idev == NULL) {
@@ -299,7 +299,6 @@ static int pm860x_touch_remove(struct pl
 
 	input_unregister_device(touch->idev);
 	free_irq(touch->irq, touch);
-	platform_set_drvdata(pdev, NULL);
 	kfree(touch);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/ads7846.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/ads7846.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/ads7846.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/ads7846.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,9 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
@@ -961,9 +964,9 @@ static int ads7846_resume(struct device
 static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume);
 
 static int ads7846_setup_pendown(struct spi_device *spi,
-					   struct ads7846 *ts)
+				 struct ads7846 *ts,
+				 const struct ads7846_platform_data *pdata)
 {
-	struct ads7846_platform_data *pdata = spi->dev.platform_data;
 	int err;
 
 	/*
@@ -1003,7 +1006,7 @@ static int ads7846_setup_pendown(struct
  * use formula #2 for pressure, not #3.
  */
 static void ads7846_setup_spi_msg(struct ads7846 *ts,
-				const struct ads7846_platform_data *pdata)
+				  const struct ads7846_platform_data *pdata)
 {
 	struct spi_message *m = &ts->msg[0];
 	struct spi_transfer *x = ts->xfer;
@@ -1201,33 +1204,107 @@ static void ads7846_setup_spi_msg(struct
 	spi_message_add_tail(x, m);
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id ads7846_dt_ids[] = {
+	{ .compatible = "ti,tsc2046",	.data = (void *) 7846 },
+	{ .compatible = "ti,ads7843",	.data = (void *) 7843 },
+	{ .compatible = "ti,ads7845",	.data = (void *) 7845 },
+	{ .compatible = "ti,ads7846",	.data = (void *) 7846 },
+	{ .compatible = "ti,ads7873",	.data = (void *) 7873 },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ads7846_dt_ids);
+
+static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev)
+{
+	struct ads7846_platform_data *pdata;
+	struct device_node *node = dev->of_node;
+	const struct of_device_id *match;
+
+	if (!node) {
+		dev_err(dev, "Device does not have associated DT data\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	match = of_match_device(ads7846_dt_ids, dev);
+	if (!match) {
+		dev_err(dev, "Unknown device model\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	pdata->model = (unsigned long)match->data;
+
+	of_property_read_u16(node, "ti,vref-delay-usecs",
+			     &pdata->vref_delay_usecs);
+	of_property_read_u16(node, "ti,vref-mv", &pdata->vref_mv);
+	pdata->keep_vref_on = of_property_read_bool(node, "ti,keep-vref-on");
+
+	pdata->swap_xy = of_property_read_bool(node, "ti,swap-xy");
+
+	of_property_read_u16(node, "ti,settle-delay-usec",
+			     &pdata->settle_delay_usecs);
+	of_property_read_u16(node, "ti,penirq-recheck-delay-usecs",
+			     &pdata->penirq_recheck_delay_usecs);
+
+	of_property_read_u16(node, "ti,x-plate-ohms", &pdata->x_plate_ohms);
+	of_property_read_u16(node, "ti,y-plate-ohms", &pdata->y_plate_ohms);
+
+	of_property_read_u16(node, "ti,x-min", &pdata->x_min);
+	of_property_read_u16(node, "ti,y-min", &pdata->y_min);
+	of_property_read_u16(node, "ti,x-max", &pdata->x_max);
+	of_property_read_u16(node, "ti,y-max", &pdata->y_max);
+
+	of_property_read_u16(node, "ti,pressure-min", &pdata->pressure_min);
+	of_property_read_u16(node, "ti,pressure-max", &pdata->pressure_max);
+
+	of_property_read_u16(node, "ti,debounce-max", &pdata->debounce_max);
+	of_property_read_u16(node, "ti,debounce-tol", &pdata->debounce_tol);
+	of_property_read_u16(node, "ti,debounce-rep", &pdata->debounce_rep);
+
+	of_property_read_u32(node, "ti,pendown-gpio-debounce",
+			     &pdata->gpio_pendown_debounce);
+
+	pdata->wakeup = of_property_read_bool(node, "linux,wakeup");
+
+	pdata->gpio_pendown = of_get_named_gpio(dev->of_node, "pendown-gpio", 0);
+
+	return pdata;
+}
+#else
+static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev)
+{
+	dev_err(dev, "no platform data defined\n");
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
 static int ads7846_probe(struct spi_device *spi)
 {
+	const struct ads7846_platform_data *pdata;
 	struct ads7846 *ts;
 	struct ads7846_packet *packet;
 	struct input_dev *input_dev;
-	struct ads7846_platform_data *pdata = spi->dev.platform_data;
 	unsigned long irq_flags;
 	int err;
 
 	if (!spi->irq) {
 		dev_dbg(&spi->dev, "no IRQ?\n");
-		return -ENODEV;
-	}
-
-	if (!pdata) {
-		dev_dbg(&spi->dev, "no platform data?\n");
-		return -ENODEV;
+		return -EINVAL;
 	}
 
 	/* don't exceed max specified sample rate */
 	if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) {
-		dev_dbg(&spi->dev, "f(sample) %d KHz?\n",
+		dev_err(&spi->dev, "f(sample) %d KHz?\n",
 				(spi->max_speed_hz/SAMPLE_BITS)/1000);
 		return -EINVAL;
 	}
 
-	/* We'd set TX word size 8 bits and RX word size to 13 bits ... except
+	/*
+	 * We'd set TX word size 8 bits and RX word size to 13 bits ... except
 	 * that even if the hardware can do that, the SPI controller driver
 	 * may not.  So we stick to very-portable 8 bit words, both RX and TX.
 	 */
@@ -1250,17 +1327,25 @@ static int ads7846_probe(struct spi_devi
 	ts->packet = packet;
 	ts->spi = spi;
 	ts->input = input_dev;
-	ts->vref_mv = pdata->vref_mv;
-	ts->swap_xy = pdata->swap_xy;
 
 	mutex_init(&ts->lock);
 	init_waitqueue_head(&ts->wait);
 
+	pdata = dev_get_platdata(&spi->dev);
+	if (!pdata) {
+		pdata = ads7846_probe_dt(&spi->dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+	}
+
 	ts->model = pdata->model ? : 7846;
 	ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
 	ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
 	ts->pressure_max = pdata->pressure_max ? : ~0;
 
+	ts->vref_mv = pdata->vref_mv;
+	ts->swap_xy = pdata->swap_xy;
+
 	if (pdata->filter != NULL) {
 		if (pdata->filter_init != NULL) {
 			err = pdata->filter_init(pdata, &ts->filter_data);
@@ -1281,7 +1366,7 @@ static int ads7846_probe(struct spi_devi
 		ts->filter = ads7846_no_filter;
 	}
 
-	err = ads7846_setup_pendown(spi, ts);
+	err = ads7846_setup_pendown(spi, ts, pdata);
 	if (err)
 		goto err_cleanup_filter;
 
@@ -1370,6 +1455,13 @@ static int ads7846_probe(struct spi_devi
 
 	device_init_wakeup(&spi->dev, pdata->wakeup);
 
+	/*
+	 * If device does not carry platform data we must have allocated it
+	 * when parsing DT data.
+	 */
+	if (!dev_get_platdata(&spi->dev))
+		devm_kfree(&spi->dev, (void *)pdata);
+
 	return 0;
 
  err_remove_attr_group:
@@ -1437,6 +1529,7 @@ static struct spi_driver ads7846_driver
 		.name	= "ads7846",
 		.owner	= THIS_MODULE,
 		.pm	= &ads7846_pm,
+		.of_match_table = of_match_ptr(ads7846_dt_ids),
 	},
 	.probe		= ads7846_probe,
 	.remove		= ads7846_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/atmel_tsadcc.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/atmel_tsadcc.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/atmel_tsadcc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/atmel_tsadcc.c	2013-08-25 20:43:22.000000000 -0400
@@ -183,10 +183,13 @@ static int atmel_tsadcc_probe(struct pla
 	struct input_dev	*input_dev;
 	struct resource		*res;
 	struct at91_tsadcc_data *pdata = pdev->dev.platform_data;
-	int		err = 0;
+	int		err;
 	unsigned int	prsc;
 	unsigned int	reg;
 
+	if (!pdata)
+		return -EINVAL;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "no mmio resource defined.\n");
@@ -265,9 +268,6 @@ static int atmel_tsadcc_probe(struct pla
 	prsc = clk_get_rate(ts_dev->clk);
 	dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc);
 
-	if (!pdata)
-		goto err_fail;
-
 	if (!pdata->adc_clock)
 		pdata->adc_clock = ADC_DEFAULT_CLOCK;
 
@@ -325,7 +325,7 @@ err_free_mem:
 
 static int atmel_tsadcc_remove(struct platform_device *pdev)
 {
-	struct atmel_tsadcc *ts_dev = dev_get_drvdata(&pdev->dev);
+	struct atmel_tsadcc *ts_dev = platform_get_drvdata(pdev);
 	struct resource *res;
 
 	free_irq(ts_dev->irq, ts_dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/atmel-wm97xx.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/atmel-wm97xx.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/atmel-wm97xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/atmel-wm97xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -372,7 +372,6 @@ static int __init atmel_wm97xx_probe(str
 err_irq:
 	free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx);
 err:
-	platform_set_drvdata(pdev, NULL);
 	kfree(atmel_wm97xx);
 	return ret;
 }
@@ -386,7 +385,6 @@ static int __exit atmel_wm97xx_remove(st
 	free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx);
 	del_timer_sync(&atmel_wm97xx->pen_timer);
 	wm97xx_unregister_mach_ops(wm);
-	platform_set_drvdata(pdev, NULL);
 	kfree(atmel_wm97xx);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp4_core.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp4_core.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp4_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp4_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2166 @@
+/*
+ * cyttsp4_core.c
+ * Cypress TrueTouch(TM) Standard Product V4 Core driver module.
+ * For use with Cypress Txx4xx parts.
+ * Supported parts include:
+ * TMA4XX
+ * TMA1036
+ *
+ * Copyright (C) 2012 Cypress Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
+ *
+ */
+
+#include "cyttsp4_core.h"
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/input/mt.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+/* Timeout in ms. */
+#define CY_CORE_REQUEST_EXCLUSIVE_TIMEOUT	500
+#define CY_CORE_SLEEP_REQUEST_EXCLUSIVE_TIMEOUT	5000
+#define CY_CORE_MODE_CHANGE_TIMEOUT		1000
+#define CY_CORE_RESET_AND_WAIT_TIMEOUT		500
+#define CY_CORE_WAKEUP_TIMEOUT			500
+
+#define CY_CORE_STARTUP_RETRY_COUNT		3
+
+static const u8 ldr_exit[] = {
+	0xFF, 0x01, 0x3B, 0x00, 0x00, 0x4F, 0x6D, 0x17
+};
+
+static const u8 ldr_err_app[] = {
+	0x01, 0x02, 0x00, 0x00, 0x55, 0xDD, 0x17
+};
+
+static inline size_t merge_bytes(u8 high, u8 low)
+{
+	return (high << 8) + low;
+}
+
+#ifdef VERBOSE_DEBUG
+static void cyttsp4_pr_buf(struct device *dev, u8 *pr_buf, u8 *dptr, int size,
+		const char *data_name)
+{
+	int i, k;
+	const char fmt[] = "%02X ";
+	int max;
+
+	if (!size)
+		return;
+
+	max = (CY_MAX_PRBUF_SIZE - 1) - sizeof(CY_PR_TRUNCATED);
+
+	pr_buf[0] = 0;
+	for (i = k = 0; i < size && k < max; i++, k += 3)
+		scnprintf(pr_buf + k, CY_MAX_PRBUF_SIZE, fmt, dptr[i]);
+
+	dev_vdbg(dev, "%s:  %s[0..%d]=%s%s\n", __func__, data_name, size - 1,
+			pr_buf, size <= max ? "" : CY_PR_TRUNCATED);
+}
+#else
+#define cyttsp4_pr_buf(dev, pr_buf, dptr, size, data_name) do { } while (0)
+#endif
+
+static int cyttsp4_load_status_regs(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	struct device *dev = cd->dev;
+	int rc;
+
+	rc = cyttsp4_adap_read(cd, CY_REG_BASE, si->si_ofs.mode_size,
+			si->xy_mode);
+	if (rc < 0)
+		dev_err(dev, "%s: fail read mode regs r=%d\n",
+			__func__, rc);
+	else
+		cyttsp4_pr_buf(dev, cd->pr_buf, si->xy_mode,
+			si->si_ofs.mode_size, "xy_mode");
+
+	return rc;
+}
+
+static int cyttsp4_handshake(struct cyttsp4 *cd, u8 mode)
+{
+	u8 cmd = mode ^ CY_HST_TOGGLE;
+	int rc;
+
+	/*
+	 * Mode change issued, handshaking now will cause endless mode change
+	 * requests, for sync mode modechange will do same with handshake
+	 * */
+	if (mode & CY_HST_MODE_CHANGE)
+		return 0;
+
+	rc = cyttsp4_adap_write(cd, CY_REG_BASE, sizeof(cmd), &cmd);
+	if (rc < 0)
+		dev_err(cd->dev, "%s: bus write fail on handshake (ret=%d)\n",
+				__func__, rc);
+
+	return rc;
+}
+
+static int cyttsp4_hw_soft_reset(struct cyttsp4 *cd)
+{
+	u8 cmd = CY_HST_RESET;
+	int rc = cyttsp4_adap_write(cd, CY_REG_BASE, sizeof(cmd), &cmd);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: FAILED to execute SOFT reset\n",
+				__func__);
+		return rc;
+	}
+	return 0;
+}
+
+static int cyttsp4_hw_hard_reset(struct cyttsp4 *cd)
+{
+	if (cd->cpdata->xres) {
+		cd->cpdata->xres(cd->cpdata, cd->dev);
+		dev_dbg(cd->dev, "%s: execute HARD reset\n", __func__);
+		return 0;
+	}
+	dev_err(cd->dev, "%s: FAILED to execute HARD reset\n", __func__);
+	return -ENOSYS;
+}
+
+static int cyttsp4_hw_reset(struct cyttsp4 *cd)
+{
+	int rc = cyttsp4_hw_hard_reset(cd);
+	if (rc == -ENOSYS)
+		rc = cyttsp4_hw_soft_reset(cd);
+	return rc;
+}
+
+/*
+ * Gets number of bits for a touch filed as parameter,
+ * sets maximum value for field which is used as bit mask
+ * and returns number of bytes required for that field
+ */
+static int cyttsp4_bits_2_bytes(unsigned int nbits, size_t *max)
+{
+	*max = 1UL << nbits;
+	return (nbits + 7) / 8;
+}
+
+static int cyttsp4_si_data_offsets(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	int rc = cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(si->si_data),
+			&si->si_data);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail read sysinfo data offsets r=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	/* Print sysinfo data offsets */
+	cyttsp4_pr_buf(cd->dev, cd->pr_buf, (u8 *)&si->si_data,
+		       sizeof(si->si_data), "sysinfo_data_offsets");
+
+	/* convert sysinfo data offset bytes into integers */
+
+	si->si_ofs.map_sz = merge_bytes(si->si_data.map_szh,
+			si->si_data.map_szl);
+	si->si_ofs.map_sz = merge_bytes(si->si_data.map_szh,
+			si->si_data.map_szl);
+	si->si_ofs.cydata_ofs = merge_bytes(si->si_data.cydata_ofsh,
+			si->si_data.cydata_ofsl);
+	si->si_ofs.test_ofs = merge_bytes(si->si_data.test_ofsh,
+			si->si_data.test_ofsl);
+	si->si_ofs.pcfg_ofs = merge_bytes(si->si_data.pcfg_ofsh,
+			si->si_data.pcfg_ofsl);
+	si->si_ofs.opcfg_ofs = merge_bytes(si->si_data.opcfg_ofsh,
+			si->si_data.opcfg_ofsl);
+	si->si_ofs.ddata_ofs = merge_bytes(si->si_data.ddata_ofsh,
+			si->si_data.ddata_ofsl);
+	si->si_ofs.mdata_ofs = merge_bytes(si->si_data.mdata_ofsh,
+			si->si_data.mdata_ofsl);
+	return rc;
+}
+
+static int cyttsp4_si_get_cydata(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	int read_offset;
+	int mfgid_sz, calc_mfgid_sz;
+	void *p;
+	int rc;
+
+	si->si_ofs.cydata_size = si->si_ofs.test_ofs - si->si_ofs.cydata_ofs;
+	dev_dbg(cd->dev, "%s: cydata size: %Zd\n", __func__,
+			si->si_ofs.cydata_size);
+
+	p = krealloc(si->si_ptrs.cydata, si->si_ofs.cydata_size, GFP_KERNEL);
+	if (p == NULL) {
+		dev_err(cd->dev, "%s: fail alloc cydata memory\n", __func__);
+		return -ENOMEM;
+	}
+	si->si_ptrs.cydata = p;
+
+	read_offset = si->si_ofs.cydata_ofs;
+
+	/* Read the CYDA registers up to MFGID field */
+	rc = cyttsp4_adap_read(cd, read_offset,
+			offsetof(struct cyttsp4_cydata, mfgid_sz)
+				+ sizeof(si->si_ptrs.cydata->mfgid_sz),
+			si->si_ptrs.cydata);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail read cydata r=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	/* Check MFGID size */
+	mfgid_sz = si->si_ptrs.cydata->mfgid_sz;
+	calc_mfgid_sz = si->si_ofs.cydata_size - sizeof(struct cyttsp4_cydata);
+	if (mfgid_sz != calc_mfgid_sz) {
+		dev_err(cd->dev, "%s: mismatch in MFGID size, reported:%d calculated:%d\n",
+			__func__, mfgid_sz, calc_mfgid_sz);
+		return -EINVAL;
+	}
+
+	read_offset += offsetof(struct cyttsp4_cydata, mfgid_sz)
+			+ sizeof(si->si_ptrs.cydata->mfgid_sz);
+
+	/* Read the CYDA registers for MFGID field */
+	rc = cyttsp4_adap_read(cd, read_offset, si->si_ptrs.cydata->mfgid_sz,
+			si->si_ptrs.cydata->mfg_id);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail read cydata r=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	read_offset += si->si_ptrs.cydata->mfgid_sz;
+
+	/* Read the rest of the CYDA registers */
+	rc = cyttsp4_adap_read(cd, read_offset,
+			sizeof(struct cyttsp4_cydata)
+				- offsetof(struct cyttsp4_cydata, cyito_idh),
+			&si->si_ptrs.cydata->cyito_idh);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail read cydata r=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	cyttsp4_pr_buf(cd->dev, cd->pr_buf, (u8 *)si->si_ptrs.cydata,
+		si->si_ofs.cydata_size, "sysinfo_cydata");
+	return rc;
+}
+
+static int cyttsp4_si_get_test_data(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	void *p;
+	int rc;
+
+	si->si_ofs.test_size = si->si_ofs.pcfg_ofs - si->si_ofs.test_ofs;
+
+	p = krealloc(si->si_ptrs.test, si->si_ofs.test_size, GFP_KERNEL);
+	if (p == NULL) {
+		dev_err(cd->dev, "%s: fail alloc test memory\n", __func__);
+		return -ENOMEM;
+	}
+	si->si_ptrs.test = p;
+
+	rc = cyttsp4_adap_read(cd, si->si_ofs.test_ofs, si->si_ofs.test_size,
+			si->si_ptrs.test);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail read test data r=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	cyttsp4_pr_buf(cd->dev, cd->pr_buf,
+		       (u8 *)si->si_ptrs.test, si->si_ofs.test_size,
+		       "sysinfo_test_data");
+	if (si->si_ptrs.test->post_codel &
+	    CY_POST_CODEL_WDG_RST)
+		dev_info(cd->dev, "%s: %s codel=%02X\n",
+			 __func__, "Reset was a WATCHDOG RESET",
+			 si->si_ptrs.test->post_codel);
+
+	if (!(si->si_ptrs.test->post_codel &
+	      CY_POST_CODEL_CFG_DATA_CRC_FAIL))
+		dev_info(cd->dev, "%s: %s codel=%02X\n", __func__,
+			 "Config Data CRC FAIL",
+			 si->si_ptrs.test->post_codel);
+
+	if (!(si->si_ptrs.test->post_codel &
+	      CY_POST_CODEL_PANEL_TEST_FAIL))
+		dev_info(cd->dev, "%s: %s codel=%02X\n",
+			 __func__, "PANEL TEST FAIL",
+			 si->si_ptrs.test->post_codel);
+
+	dev_info(cd->dev, "%s: SCANNING is %s codel=%02X\n",
+		 __func__, si->si_ptrs.test->post_codel & 0x08 ?
+		 "ENABLED" : "DISABLED",
+		 si->si_ptrs.test->post_codel);
+	return rc;
+}
+
+static int cyttsp4_si_get_pcfg_data(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	void *p;
+	int rc;
+
+	si->si_ofs.pcfg_size = si->si_ofs.opcfg_ofs - si->si_ofs.pcfg_ofs;
+
+	p = krealloc(si->si_ptrs.pcfg, si->si_ofs.pcfg_size, GFP_KERNEL);
+	if (p == NULL) {
+		rc = -ENOMEM;
+		dev_err(cd->dev, "%s: fail alloc pcfg memory r=%d\n",
+			__func__, rc);
+		return rc;
+	}
+	si->si_ptrs.pcfg = p;
+
+	rc = cyttsp4_adap_read(cd, si->si_ofs.pcfg_ofs, si->si_ofs.pcfg_size,
+			si->si_ptrs.pcfg);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail read pcfg data r=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	si->si_ofs.max_x = merge_bytes((si->si_ptrs.pcfg->res_xh
+			& CY_PCFG_RESOLUTION_X_MASK), si->si_ptrs.pcfg->res_xl);
+	si->si_ofs.x_origin = !!(si->si_ptrs.pcfg->res_xh
+			& CY_PCFG_ORIGIN_X_MASK);
+	si->si_ofs.max_y = merge_bytes((si->si_ptrs.pcfg->res_yh
+			& CY_PCFG_RESOLUTION_Y_MASK), si->si_ptrs.pcfg->res_yl);
+	si->si_ofs.y_origin = !!(si->si_ptrs.pcfg->res_yh
+			& CY_PCFG_ORIGIN_Y_MASK);
+	si->si_ofs.max_p = merge_bytes(si->si_ptrs.pcfg->max_zh,
+			si->si_ptrs.pcfg->max_zl);
+
+	cyttsp4_pr_buf(cd->dev, cd->pr_buf,
+		       (u8 *)si->si_ptrs.pcfg,
+		       si->si_ofs.pcfg_size, "sysinfo_pcfg_data");
+	return rc;
+}
+
+static int cyttsp4_si_get_opcfg_data(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	struct cyttsp4_tch_abs_params *tch;
+	struct cyttsp4_tch_rec_params *tch_old, *tch_new;
+	enum cyttsp4_tch_abs abs;
+	int i;
+	void *p;
+	int rc;
+
+	si->si_ofs.opcfg_size = si->si_ofs.ddata_ofs - si->si_ofs.opcfg_ofs;
+
+	p = krealloc(si->si_ptrs.opcfg, si->si_ofs.opcfg_size, GFP_KERNEL);
+	if (p == NULL) {
+		dev_err(cd->dev, "%s: fail alloc opcfg memory\n", __func__);
+		rc = -ENOMEM;
+		goto cyttsp4_si_get_opcfg_data_exit;
+	}
+	si->si_ptrs.opcfg = p;
+
+	rc = cyttsp4_adap_read(cd, si->si_ofs.opcfg_ofs, si->si_ofs.opcfg_size,
+			si->si_ptrs.opcfg);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail read opcfg data r=%d\n",
+			__func__, rc);
+		goto cyttsp4_si_get_opcfg_data_exit;
+	}
+	si->si_ofs.cmd_ofs = si->si_ptrs.opcfg->cmd_ofs;
+	si->si_ofs.rep_ofs = si->si_ptrs.opcfg->rep_ofs;
+	si->si_ofs.rep_sz = (si->si_ptrs.opcfg->rep_szh * 256) +
+		si->si_ptrs.opcfg->rep_szl;
+	si->si_ofs.num_btns = si->si_ptrs.opcfg->num_btns;
+	si->si_ofs.num_btn_regs = (si->si_ofs.num_btns +
+		CY_NUM_BTN_PER_REG - 1) / CY_NUM_BTN_PER_REG;
+	si->si_ofs.tt_stat_ofs = si->si_ptrs.opcfg->tt_stat_ofs;
+	si->si_ofs.obj_cfg0 = si->si_ptrs.opcfg->obj_cfg0;
+	si->si_ofs.max_tchs = si->si_ptrs.opcfg->max_tchs &
+		CY_BYTE_OFS_MASK;
+	si->si_ofs.tch_rec_size = si->si_ptrs.opcfg->tch_rec_size &
+		CY_BYTE_OFS_MASK;
+
+	/* Get the old touch fields */
+	for (abs = CY_TCH_X; abs < CY_NUM_TCH_FIELDS; abs++) {
+		tch = &si->si_ofs.tch_abs[abs];
+		tch_old = &si->si_ptrs.opcfg->tch_rec_old[abs];
+
+		tch->ofs = tch_old->loc & CY_BYTE_OFS_MASK;
+		tch->size = cyttsp4_bits_2_bytes(tch_old->size,
+						 &tch->max);
+		tch->bofs = (tch_old->loc & CY_BOFS_MASK) >> CY_BOFS_SHIFT;
+	}
+
+	/* button fields */
+	si->si_ofs.btn_rec_size = si->si_ptrs.opcfg->btn_rec_size;
+	si->si_ofs.btn_diff_ofs = si->si_ptrs.opcfg->btn_diff_ofs;
+	si->si_ofs.btn_diff_size = si->si_ptrs.opcfg->btn_diff_size;
+
+	if (si->si_ofs.tch_rec_size > CY_TMA1036_TCH_REC_SIZE) {
+		/* Get the extended touch fields */
+		for (i = 0; i < CY_NUM_EXT_TCH_FIELDS; abs++, i++) {
+			tch = &si->si_ofs.tch_abs[abs];
+			tch_new = &si->si_ptrs.opcfg->tch_rec_new[i];
+
+			tch->ofs = tch_new->loc & CY_BYTE_OFS_MASK;
+			tch->size = cyttsp4_bits_2_bytes(tch_new->size,
+							 &tch->max);
+			tch->bofs = (tch_new->loc & CY_BOFS_MASK) >> CY_BOFS_SHIFT;
+		}
+	}
+
+	for (abs = 0; abs < CY_TCH_NUM_ABS; abs++) {
+		dev_dbg(cd->dev, "%s: tch_rec_%s\n", __func__,
+			cyttsp4_tch_abs_string[abs]);
+		dev_dbg(cd->dev, "%s:     ofs =%2Zd\n", __func__,
+			si->si_ofs.tch_abs[abs].ofs);
+		dev_dbg(cd->dev, "%s:     siz =%2Zd\n", __func__,
+			si->si_ofs.tch_abs[abs].size);
+		dev_dbg(cd->dev, "%s:     max =%2Zd\n", __func__,
+			si->si_ofs.tch_abs[abs].max);
+		dev_dbg(cd->dev, "%s:     bofs=%2Zd\n", __func__,
+			si->si_ofs.tch_abs[abs].bofs);
+	}
+
+	si->si_ofs.mode_size = si->si_ofs.tt_stat_ofs + 1;
+	si->si_ofs.data_size = si->si_ofs.max_tchs *
+		si->si_ptrs.opcfg->tch_rec_size;
+
+	cyttsp4_pr_buf(cd->dev, cd->pr_buf, (u8 *)si->si_ptrs.opcfg,
+		si->si_ofs.opcfg_size, "sysinfo_opcfg_data");
+
+cyttsp4_si_get_opcfg_data_exit:
+	return rc;
+}
+
+static int cyttsp4_si_get_ddata(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	void *p;
+	int rc;
+
+	si->si_ofs.ddata_size = si->si_ofs.mdata_ofs - si->si_ofs.ddata_ofs;
+
+	p = krealloc(si->si_ptrs.ddata, si->si_ofs.ddata_size, GFP_KERNEL);
+	if (p == NULL) {
+		dev_err(cd->dev, "%s: fail alloc ddata memory\n", __func__);
+		return -ENOMEM;
+	}
+	si->si_ptrs.ddata = p;
+
+	rc = cyttsp4_adap_read(cd, si->si_ofs.ddata_ofs, si->si_ofs.ddata_size,
+			si->si_ptrs.ddata);
+	if (rc < 0)
+		dev_err(cd->dev, "%s: fail read ddata data r=%d\n",
+			__func__, rc);
+	else
+		cyttsp4_pr_buf(cd->dev, cd->pr_buf,
+			       (u8 *)si->si_ptrs.ddata,
+			       si->si_ofs.ddata_size, "sysinfo_ddata");
+	return rc;
+}
+
+static int cyttsp4_si_get_mdata(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	void *p;
+	int rc;
+
+	si->si_ofs.mdata_size = si->si_ofs.map_sz - si->si_ofs.mdata_ofs;
+
+	p = krealloc(si->si_ptrs.mdata, si->si_ofs.mdata_size, GFP_KERNEL);
+	if (p == NULL) {
+		dev_err(cd->dev, "%s: fail alloc mdata memory\n", __func__);
+		return -ENOMEM;
+	}
+	si->si_ptrs.mdata = p;
+
+	rc = cyttsp4_adap_read(cd, si->si_ofs.mdata_ofs, si->si_ofs.mdata_size,
+			si->si_ptrs.mdata);
+	if (rc < 0)
+		dev_err(cd->dev, "%s: fail read mdata data r=%d\n",
+			__func__, rc);
+	else
+		cyttsp4_pr_buf(cd->dev, cd->pr_buf,
+			       (u8 *)si->si_ptrs.mdata,
+			       si->si_ofs.mdata_size, "sysinfo_mdata");
+	return rc;
+}
+
+static int cyttsp4_si_get_btn_data(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	int btn;
+	int num_defined_keys;
+	u16 *key_table;
+	void *p;
+	int rc = 0;
+
+	if (si->si_ofs.num_btns) {
+		si->si_ofs.btn_keys_size = si->si_ofs.num_btns *
+			sizeof(struct cyttsp4_btn);
+
+		p = krealloc(si->btn, si->si_ofs.btn_keys_size,
+				GFP_KERNEL|__GFP_ZERO);
+		if (p == NULL) {
+			dev_err(cd->dev, "%s: %s\n", __func__,
+				"fail alloc btn_keys memory");
+			return -ENOMEM;
+		}
+		si->btn = p;
+
+		if (cd->cpdata->sett[CY_IC_GRPNUM_BTN_KEYS] == NULL)
+			num_defined_keys = 0;
+		else if (cd->cpdata->sett[CY_IC_GRPNUM_BTN_KEYS]->data == NULL)
+			num_defined_keys = 0;
+		else
+			num_defined_keys = cd->cpdata->sett
+				[CY_IC_GRPNUM_BTN_KEYS]->size;
+
+		for (btn = 0; btn < si->si_ofs.num_btns &&
+			btn < num_defined_keys; btn++) {
+			key_table = (u16 *)cd->cpdata->sett
+				[CY_IC_GRPNUM_BTN_KEYS]->data;
+			si->btn[btn].key_code = key_table[btn];
+			si->btn[btn].state = CY_BTN_RELEASED;
+			si->btn[btn].enabled = true;
+		}
+		for (; btn < si->si_ofs.num_btns; btn++) {
+			si->btn[btn].key_code = KEY_RESERVED;
+			si->btn[btn].state = CY_BTN_RELEASED;
+			si->btn[btn].enabled = true;
+		}
+
+		return rc;
+	}
+
+	si->si_ofs.btn_keys_size = 0;
+	kfree(si->btn);
+	si->btn = NULL;
+	return rc;
+}
+
+static int cyttsp4_si_get_op_data_ptrs(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	void *p;
+
+	p = krealloc(si->xy_mode, si->si_ofs.mode_size, GFP_KERNEL|__GFP_ZERO);
+	if (p == NULL)
+		return -ENOMEM;
+	si->xy_mode = p;
+
+	p = krealloc(si->xy_data, si->si_ofs.data_size, GFP_KERNEL|__GFP_ZERO);
+	if (p == NULL)
+		return -ENOMEM;
+	si->xy_data = p;
+
+	p = krealloc(si->btn_rec_data,
+			si->si_ofs.btn_rec_size * si->si_ofs.num_btns,
+			GFP_KERNEL|__GFP_ZERO);
+	if (p == NULL)
+		return -ENOMEM;
+	si->btn_rec_data = p;
+
+	return 0;
+}
+
+static void cyttsp4_si_put_log_data(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	dev_dbg(cd->dev, "%s: cydata_ofs =%4Zd siz=%4Zd\n", __func__,
+		si->si_ofs.cydata_ofs, si->si_ofs.cydata_size);
+	dev_dbg(cd->dev, "%s: test_ofs   =%4Zd siz=%4Zd\n", __func__,
+		si->si_ofs.test_ofs, si->si_ofs.test_size);
+	dev_dbg(cd->dev, "%s: pcfg_ofs   =%4Zd siz=%4Zd\n", __func__,
+		si->si_ofs.pcfg_ofs, si->si_ofs.pcfg_size);
+	dev_dbg(cd->dev, "%s: opcfg_ofs  =%4Zd siz=%4Zd\n", __func__,
+		si->si_ofs.opcfg_ofs, si->si_ofs.opcfg_size);
+	dev_dbg(cd->dev, "%s: ddata_ofs  =%4Zd siz=%4Zd\n", __func__,
+		si->si_ofs.ddata_ofs, si->si_ofs.ddata_size);
+	dev_dbg(cd->dev, "%s: mdata_ofs  =%4Zd siz=%4Zd\n", __func__,
+		si->si_ofs.mdata_ofs, si->si_ofs.mdata_size);
+
+	dev_dbg(cd->dev, "%s: cmd_ofs       =%4Zd\n", __func__,
+		si->si_ofs.cmd_ofs);
+	dev_dbg(cd->dev, "%s: rep_ofs       =%4Zd\n", __func__,
+		si->si_ofs.rep_ofs);
+	dev_dbg(cd->dev, "%s: rep_sz        =%4Zd\n", __func__,
+		si->si_ofs.rep_sz);
+	dev_dbg(cd->dev, "%s: num_btns      =%4Zd\n", __func__,
+		si->si_ofs.num_btns);
+	dev_dbg(cd->dev, "%s: num_btn_regs  =%4Zd\n", __func__,
+		si->si_ofs.num_btn_regs);
+	dev_dbg(cd->dev, "%s: tt_stat_ofs   =%4Zd\n", __func__,
+		si->si_ofs.tt_stat_ofs);
+	dev_dbg(cd->dev, "%s: tch_rec_size  =%4Zd\n", __func__,
+		si->si_ofs.tch_rec_size);
+	dev_dbg(cd->dev, "%s: max_tchs      =%4Zd\n", __func__,
+		si->si_ofs.max_tchs);
+	dev_dbg(cd->dev, "%s: mode_size     =%4Zd\n", __func__,
+		si->si_ofs.mode_size);
+	dev_dbg(cd->dev, "%s: data_size     =%4Zd\n", __func__,
+		si->si_ofs.data_size);
+	dev_dbg(cd->dev, "%s: map_sz        =%4Zd\n", __func__,
+		si->si_ofs.map_sz);
+
+	dev_dbg(cd->dev, "%s: btn_rec_size   =%2Zd\n", __func__,
+		si->si_ofs.btn_rec_size);
+	dev_dbg(cd->dev, "%s: btn_diff_ofs   =%2Zd\n", __func__,
+		si->si_ofs.btn_diff_ofs);
+	dev_dbg(cd->dev, "%s: btn_diff_size  =%2Zd\n", __func__,
+		si->si_ofs.btn_diff_size);
+
+	dev_dbg(cd->dev, "%s: max_x    = 0x%04ZX (%Zd)\n", __func__,
+		si->si_ofs.max_x, si->si_ofs.max_x);
+	dev_dbg(cd->dev, "%s: x_origin = %Zd (%s)\n", __func__,
+		si->si_ofs.x_origin,
+		si->si_ofs.x_origin == CY_NORMAL_ORIGIN ?
+		"left corner" : "right corner");
+	dev_dbg(cd->dev, "%s: max_y    = 0x%04ZX (%Zd)\n", __func__,
+		si->si_ofs.max_y, si->si_ofs.max_y);
+	dev_dbg(cd->dev, "%s: y_origin = %Zd (%s)\n", __func__,
+		si->si_ofs.y_origin,
+		si->si_ofs.y_origin == CY_NORMAL_ORIGIN ?
+		"upper corner" : "lower corner");
+	dev_dbg(cd->dev, "%s: max_p    = 0x%04ZX (%Zd)\n", __func__,
+		si->si_ofs.max_p, si->si_ofs.max_p);
+
+	dev_dbg(cd->dev, "%s: xy_mode=%p xy_data=%p\n", __func__,
+		si->xy_mode, si->xy_data);
+}
+
+static int cyttsp4_get_sysinfo_regs(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+	int rc;
+
+	rc = cyttsp4_si_data_offsets(cd);
+	if (rc < 0)
+		return rc;
+
+	rc = cyttsp4_si_get_cydata(cd);
+	if (rc < 0)
+		return rc;
+
+	rc = cyttsp4_si_get_test_data(cd);
+	if (rc < 0)
+		return rc;
+
+	rc = cyttsp4_si_get_pcfg_data(cd);
+	if (rc < 0)
+		return rc;
+
+	rc = cyttsp4_si_get_opcfg_data(cd);
+	if (rc < 0)
+		return rc;
+
+	rc = cyttsp4_si_get_ddata(cd);
+	if (rc < 0)
+		return rc;
+
+	rc = cyttsp4_si_get_mdata(cd);
+	if (rc < 0)
+		return rc;
+
+	rc = cyttsp4_si_get_btn_data(cd);
+	if (rc < 0)
+		return rc;
+
+	rc = cyttsp4_si_get_op_data_ptrs(cd);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: failed to get_op_data\n",
+			__func__);
+		return rc;
+	}
+
+	cyttsp4_si_put_log_data(cd);
+
+	/* provide flow control handshake */
+	rc = cyttsp4_handshake(cd, si->si_data.hst_mode);
+	if (rc < 0)
+		dev_err(cd->dev, "%s: handshake fail on sysinfo reg\n",
+			__func__);
+
+	si->ready = true;
+	return rc;
+}
+
+static void cyttsp4_queue_startup_(struct cyttsp4 *cd)
+{
+	if (cd->startup_state == STARTUP_NONE) {
+		cd->startup_state = STARTUP_QUEUED;
+		schedule_work(&cd->startup_work);
+		dev_dbg(cd->dev, "%s: cyttsp4_startup queued\n", __func__);
+	} else {
+		dev_dbg(cd->dev, "%s: startup_state = %d\n", __func__,
+			cd->startup_state);
+	}
+}
+
+static void cyttsp4_report_slot_liftoff(struct cyttsp4_mt_data *md,
+		int max_slots)
+{
+	int t;
+
+	if (md->num_prv_tch == 0)
+		return;
+
+	for (t = 0; t < max_slots; t++) {
+		input_mt_slot(md->input, t);
+		input_mt_report_slot_state(md->input,
+			MT_TOOL_FINGER, false);
+	}
+}
+
+static void cyttsp4_lift_all(struct cyttsp4_mt_data *md)
+{
+	if (!md->si)
+		return;
+
+	if (md->num_prv_tch != 0) {
+		cyttsp4_report_slot_liftoff(md,
+				md->si->si_ofs.tch_abs[CY_TCH_T].max);
+		input_sync(md->input);
+		md->num_prv_tch = 0;
+	}
+}
+
+static void cyttsp4_get_touch_axis(struct cyttsp4_mt_data *md,
+	int *axis, int size, int max, u8 *xy_data, int bofs)
+{
+	int nbyte;
+	int next;
+
+	for (nbyte = 0, *axis = 0, next = 0; nbyte < size; nbyte++) {
+		dev_vdbg(&md->input->dev,
+			"%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p"
+			" xy_data[%d]=%02X(%d) bofs=%d\n",
+			__func__, *axis, *axis, size, max, xy_data, next,
+			xy_data[next], xy_data[next], bofs);
+		*axis = (*axis * 256) + (xy_data[next] >> bofs);
+		next++;
+	}
+
+	*axis &= max - 1;
+
+	dev_vdbg(&md->input->dev,
+		"%s: *axis=%02X(%d) size=%d max=%08X xy_data=%p"
+		" xy_data[%d]=%02X(%d)\n",
+		__func__, *axis, *axis, size, max, xy_data, next,
+		xy_data[next], xy_data[next]);
+}
+
+static void cyttsp4_get_touch(struct cyttsp4_mt_data *md,
+	struct cyttsp4_touch *touch, u8 *xy_data)
+{
+	struct device *dev = &md->input->dev;
+	struct cyttsp4_sysinfo *si = md->si;
+	enum cyttsp4_tch_abs abs;
+	int tmp;
+	bool flipped;
+
+	for (abs = CY_TCH_X; abs < CY_TCH_NUM_ABS; abs++) {
+		cyttsp4_get_touch_axis(md, &touch->abs[abs],
+			si->si_ofs.tch_abs[abs].size,
+			si->si_ofs.tch_abs[abs].max,
+			xy_data + si->si_ofs.tch_abs[abs].ofs,
+			si->si_ofs.tch_abs[abs].bofs);
+		dev_vdbg(dev, "%s: get %s=%04X(%d)\n", __func__,
+			cyttsp4_tch_abs_string[abs],
+			touch->abs[abs], touch->abs[abs]);
+	}
+
+	if (md->pdata->flags & CY_FLAG_FLIP) {
+		tmp = touch->abs[CY_TCH_X];
+		touch->abs[CY_TCH_X] = touch->abs[CY_TCH_Y];
+		touch->abs[CY_TCH_Y] = tmp;
+		flipped = true;
+	} else
+		flipped = false;
+
+	if (md->pdata->flags & CY_FLAG_INV_X) {
+		if (flipped)
+			touch->abs[CY_TCH_X] = md->si->si_ofs.max_y -
+				touch->abs[CY_TCH_X];
+		else
+			touch->abs[CY_TCH_X] = md->si->si_ofs.max_x -
+				touch->abs[CY_TCH_X];
+	}
+	if (md->pdata->flags & CY_FLAG_INV_Y) {
+		if (flipped)
+			touch->abs[CY_TCH_Y] = md->si->si_ofs.max_x -
+				touch->abs[CY_TCH_Y];
+		else
+			touch->abs[CY_TCH_Y] = md->si->si_ofs.max_y -
+				touch->abs[CY_TCH_Y];
+	}
+
+	dev_vdbg(dev, "%s: flip=%s inv-x=%s inv-y=%s x=%04X(%d) y=%04X(%d)\n",
+		__func__, flipped ? "true" : "false",
+		md->pdata->flags & CY_FLAG_INV_X ? "true" : "false",
+		md->pdata->flags & CY_FLAG_INV_Y ? "true" : "false",
+		touch->abs[CY_TCH_X], touch->abs[CY_TCH_X],
+		touch->abs[CY_TCH_Y], touch->abs[CY_TCH_Y]);
+}
+
+static void cyttsp4_final_sync(struct input_dev *input, int max_slots, int *ids)
+{
+	int t;
+
+	for (t = 0; t < max_slots; t++) {
+		if (ids[t])
+			continue;
+		input_mt_slot(input, t);
+		input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+	}
+
+	input_sync(input);
+}
+
+static void cyttsp4_get_mt_touches(struct cyttsp4_mt_data *md, int num_cur_tch)
+{
+	struct device *dev = &md->input->dev;
+	struct cyttsp4_sysinfo *si = md->si;
+	struct cyttsp4_touch tch;
+	int sig;
+	int i, j, t = 0;
+	int ids[max(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)];
+
+	memset(ids, 0, si->si_ofs.tch_abs[CY_TCH_T].max * sizeof(int));
+	for (i = 0; i < num_cur_tch; i++) {
+		cyttsp4_get_touch(md, &tch, si->xy_data +
+			(i * si->si_ofs.tch_rec_size));
+		if ((tch.abs[CY_TCH_T] < md->pdata->frmwrk->abs
+			[(CY_ABS_ID_OST * CY_NUM_ABS_SET) + CY_MIN_OST]) ||
+			(tch.abs[CY_TCH_T] > md->pdata->frmwrk->abs
+			[(CY_ABS_ID_OST * CY_NUM_ABS_SET) + CY_MAX_OST])) {
+			dev_err(dev, "%s: tch=%d -> bad trk_id=%d max_id=%d\n",
+				__func__, i, tch.abs[CY_TCH_T],
+				md->pdata->frmwrk->abs[(CY_ABS_ID_OST *
+				CY_NUM_ABS_SET) + CY_MAX_OST]);
+			continue;
+		}
+
+		/* use 0 based track id's */
+		sig = md->pdata->frmwrk->abs
+			[(CY_ABS_ID_OST * CY_NUM_ABS_SET) + 0];
+		if (sig != CY_IGNORE_VALUE) {
+			t = tch.abs[CY_TCH_T] - md->pdata->frmwrk->abs
+				[(CY_ABS_ID_OST * CY_NUM_ABS_SET) + CY_MIN_OST];
+			if (tch.abs[CY_TCH_E] == CY_EV_LIFTOFF) {
+				dev_dbg(dev, "%s: t=%d e=%d lift-off\n",
+					__func__, t, tch.abs[CY_TCH_E]);
+				goto cyttsp4_get_mt_touches_pr_tch;
+			}
+			input_mt_slot(md->input, t);
+			input_mt_report_slot_state(md->input, MT_TOOL_FINGER,
+					true);
+			ids[t] = true;
+		}
+
+		/* all devices: position and pressure fields */
+		for (j = 0; j <= CY_ABS_W_OST; j++) {
+			sig = md->pdata->frmwrk->abs[((CY_ABS_X_OST + j) *
+				CY_NUM_ABS_SET) + 0];
+			if (sig != CY_IGNORE_VALUE)
+				input_report_abs(md->input, sig,
+					tch.abs[CY_TCH_X + j]);
+		}
+		if (si->si_ofs.tch_rec_size > CY_TMA1036_TCH_REC_SIZE) {
+			/*
+			 * TMA400 size and orientation fields:
+			 * if pressure is non-zero and major touch
+			 * signal is zero, then set major and minor touch
+			 * signals to minimum non-zero value
+			 */
+			if (tch.abs[CY_TCH_P] > 0 && tch.abs[CY_TCH_MAJ] == 0)
+				tch.abs[CY_TCH_MAJ] = tch.abs[CY_TCH_MIN] = 1;
+
+			/* Get the extended touch fields */
+			for (j = 0; j < CY_NUM_EXT_TCH_FIELDS; j++) {
+				sig = md->pdata->frmwrk->abs
+					[((CY_ABS_MAJ_OST + j) *
+					CY_NUM_ABS_SET) + 0];
+				if (sig != CY_IGNORE_VALUE)
+					input_report_abs(md->input, sig,
+						tch.abs[CY_TCH_MAJ + j]);
+			}
+		}
+
+cyttsp4_get_mt_touches_pr_tch:
+		if (si->si_ofs.tch_rec_size > CY_TMA1036_TCH_REC_SIZE)
+			dev_dbg(dev,
+				"%s: t=%d x=%d y=%d z=%d M=%d m=%d o=%d e=%d\n",
+				__func__, t,
+				tch.abs[CY_TCH_X],
+				tch.abs[CY_TCH_Y],
+				tch.abs[CY_TCH_P],
+				tch.abs[CY_TCH_MAJ],
+				tch.abs[CY_TCH_MIN],
+				tch.abs[CY_TCH_OR],
+				tch.abs[CY_TCH_E]);
+		else
+			dev_dbg(dev,
+				"%s: t=%d x=%d y=%d z=%d e=%d\n", __func__,
+				t,
+				tch.abs[CY_TCH_X],
+				tch.abs[CY_TCH_Y],
+				tch.abs[CY_TCH_P],
+				tch.abs[CY_TCH_E]);
+	}
+
+	cyttsp4_final_sync(md->input, si->si_ofs.tch_abs[CY_TCH_T].max, ids);
+
+	md->num_prv_tch = num_cur_tch;
+
+	return;
+}
+
+/* read xy_data for all current touches */
+static int cyttsp4_xy_worker(struct cyttsp4 *cd)
+{
+	struct cyttsp4_mt_data *md = &cd->md;
+	struct device *dev = &md->input->dev;
+	struct cyttsp4_sysinfo *si = md->si;
+	u8 num_cur_tch;
+	u8 hst_mode;
+	u8 rep_len;
+	u8 rep_stat;
+	u8 tt_stat;
+	int rc = 0;
+
+	/*
+	 * Get event data from cyttsp4 device.
+	 * The event data includes all data
+	 * for all active touches.
+	 * Event data also includes button data
+	 */
+	/*
+	 * Use 2 reads:
+	 * 1st read to get mode + button bytes + touch count (core)
+	 * 2nd read (optional) to get touch 1 - touch n data
+	 */
+	hst_mode = si->xy_mode[CY_REG_BASE];
+	rep_len = si->xy_mode[si->si_ofs.rep_ofs];
+	rep_stat = si->xy_mode[si->si_ofs.rep_ofs + 1];
+	tt_stat = si->xy_mode[si->si_ofs.tt_stat_ofs];
+	dev_vdbg(dev, "%s: %s%02X %s%d %s%02X %s%02X\n", __func__,
+		"hst_mode=", hst_mode, "rep_len=", rep_len,
+		"rep_stat=", rep_stat, "tt_stat=", tt_stat);
+
+	num_cur_tch = GET_NUM_TOUCHES(tt_stat);
+	dev_vdbg(dev, "%s: num_cur_tch=%d\n", __func__, num_cur_tch);
+
+	if (rep_len == 0 && num_cur_tch > 0) {
+		dev_err(dev, "%s: report length error rep_len=%d num_tch=%d\n",
+			__func__, rep_len, num_cur_tch);
+		goto cyttsp4_xy_worker_exit;
+	}
+
+	/* read touches */
+	if (num_cur_tch > 0) {
+		rc = cyttsp4_adap_read(cd, si->si_ofs.tt_stat_ofs + 1,
+				num_cur_tch * si->si_ofs.tch_rec_size,
+				si->xy_data);
+		if (rc < 0) {
+			dev_err(dev, "%s: read fail on touch regs r=%d\n",
+				__func__, rc);
+			goto cyttsp4_xy_worker_exit;
+		}
+	}
+
+	/* print xy data */
+	cyttsp4_pr_buf(dev, cd->pr_buf, si->xy_data, num_cur_tch *
+		si->si_ofs.tch_rec_size, "xy_data");
+
+	/* check any error conditions */
+	if (IS_BAD_PKT(rep_stat)) {
+		dev_dbg(dev, "%s: Invalid buffer detected\n", __func__);
+		rc = 0;
+		goto cyttsp4_xy_worker_exit;
+	}
+
+	if (IS_LARGE_AREA(tt_stat))
+		dev_dbg(dev, "%s: Large area detected\n", __func__);
+
+	if (num_cur_tch > si->si_ofs.max_tchs) {
+		dev_err(dev, "%s: too many tch; set to max tch (n=%d c=%Zd)\n",
+				__func__, num_cur_tch, si->si_ofs.max_tchs);
+		num_cur_tch = si->si_ofs.max_tchs;
+	}
+
+	/* extract xy_data for all currently reported touches */
+	dev_vdbg(dev, "%s: extract data num_cur_tch=%d\n", __func__,
+		num_cur_tch);
+	if (num_cur_tch)
+		cyttsp4_get_mt_touches(md, num_cur_tch);
+	else
+		cyttsp4_lift_all(md);
+
+	rc = 0;
+
+cyttsp4_xy_worker_exit:
+	return rc;
+}
+
+static int cyttsp4_mt_attention(struct cyttsp4 *cd)
+{
+	struct device *dev = cd->dev;
+	struct cyttsp4_mt_data *md = &cd->md;
+	int rc = 0;
+
+	if (!md->si)
+		return 0;
+
+	mutex_lock(&md->report_lock);
+	if (!md->is_suspended) {
+		/* core handles handshake */
+		rc = cyttsp4_xy_worker(cd);
+	} else {
+		dev_vdbg(dev, "%s: Ignoring report while suspended\n",
+			__func__);
+	}
+	mutex_unlock(&md->report_lock);
+	if (rc < 0)
+		dev_err(dev, "%s: xy_worker error r=%d\n", __func__, rc);
+
+	return rc;
+}
+
+static irqreturn_t cyttsp4_irq(int irq, void *handle)
+{
+	struct cyttsp4 *cd = handle;
+	struct device *dev = cd->dev;
+	enum cyttsp4_mode cur_mode;
+	u8 cmd_ofs = cd->sysinfo.si_ofs.cmd_ofs;
+	u8 mode[3];
+	int rc;
+
+	/*
+	 * Check whether this IRQ should be ignored (external)
+	 * This should be the very first thing to check since
+	 * ignore_irq may be set for a very short period of time
+	 */
+	if (atomic_read(&cd->ignore_irq)) {
+		dev_vdbg(dev, "%s: Ignoring IRQ\n", __func__);
+		return IRQ_HANDLED;
+	}
+
+	dev_dbg(dev, "%s int:0x%x\n", __func__, cd->int_status);
+
+	mutex_lock(&cd->system_lock);
+
+	/* Just to debug */
+	if (cd->sleep_state == SS_SLEEP_ON || cd->sleep_state == SS_SLEEPING)
+		dev_vdbg(dev, "%s: Received IRQ while in sleep\n", __func__);
+
+	rc = cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(mode), mode);
+	if (rc) {
+		dev_err(cd->dev, "%s: Fail read adapter r=%d\n", __func__, rc);
+		goto cyttsp4_irq_exit;
+	}
+	dev_vdbg(dev, "%s mode[0-2]:0x%X 0x%X 0x%X\n", __func__,
+			mode[0], mode[1], mode[2]);
+
+	if (IS_BOOTLOADER(mode[0], mode[1])) {
+		cur_mode = CY_MODE_BOOTLOADER;
+		dev_vdbg(dev, "%s: bl running\n", __func__);
+		if (cd->mode == CY_MODE_BOOTLOADER) {
+			/* Signal bootloader heartbeat heard */
+			wake_up(&cd->wait_q);
+			goto cyttsp4_irq_exit;
+		}
+
+		/* switch to bootloader */
+		dev_dbg(dev, "%s: restart switch to bl m=%d -> m=%d\n",
+			__func__, cd->mode, cur_mode);
+
+		/* catch operation->bl glitch */
+		if (cd->mode != CY_MODE_UNKNOWN) {
+			/* Incase startup_state do not let startup_() */
+			cd->mode = CY_MODE_UNKNOWN;
+			cyttsp4_queue_startup_(cd);
+			goto cyttsp4_irq_exit;
+		}
+
+		/*
+		 * do not wake thread on this switch since
+		 * it is possible to get an early heartbeat
+		 * prior to performing the reset
+		 */
+		cd->mode = cur_mode;
+
+		goto cyttsp4_irq_exit;
+	}
+
+	switch (mode[0] & CY_HST_MODE) {
+	case CY_HST_OPERATE:
+		cur_mode = CY_MODE_OPERATIONAL;
+		dev_vdbg(dev, "%s: operational\n", __func__);
+		break;
+	case CY_HST_CAT:
+		cur_mode = CY_MODE_CAT;
+		dev_vdbg(dev, "%s: CaT\n", __func__);
+		break;
+	case CY_HST_SYSINFO:
+		cur_mode = CY_MODE_SYSINFO;
+		dev_vdbg(dev, "%s: sysinfo\n", __func__);
+		break;
+	default:
+		cur_mode = CY_MODE_UNKNOWN;
+		dev_err(dev, "%s: unknown HST mode 0x%02X\n", __func__,
+			mode[0]);
+		break;
+	}
+
+	/* Check whether this IRQ should be ignored (internal) */
+	if (cd->int_status & CY_INT_IGNORE) {
+		dev_vdbg(dev, "%s: Ignoring IRQ\n", __func__);
+		goto cyttsp4_irq_exit;
+	}
+
+	/* Check for wake up interrupt */
+	if (cd->int_status & CY_INT_AWAKE) {
+		cd->int_status &= ~CY_INT_AWAKE;
+		wake_up(&cd->wait_q);
+		dev_vdbg(dev, "%s: Received wake up interrupt\n", __func__);
+		goto cyttsp4_irq_handshake;
+	}
+
+	/* Expecting mode change interrupt */
+	if ((cd->int_status & CY_INT_MODE_CHANGE)
+			&& (mode[0] & CY_HST_MODE_CHANGE) == 0) {
+		cd->int_status &= ~CY_INT_MODE_CHANGE;
+		dev_dbg(dev, "%s: finish mode switch m=%d -> m=%d\n",
+				__func__, cd->mode, cur_mode);
+		cd->mode = cur_mode;
+		wake_up(&cd->wait_q);
+		goto cyttsp4_irq_handshake;
+	}
+
+	/* compare current core mode to current device mode */
+	dev_vdbg(dev, "%s: cd->mode=%d cur_mode=%d\n",
+			__func__, cd->mode, cur_mode);
+	if ((mode[0] & CY_HST_MODE_CHANGE) == 0 && cd->mode != cur_mode) {
+		/* Unexpected mode change occurred */
+		dev_err(dev, "%s %d->%d 0x%x\n", __func__, cd->mode,
+				cur_mode, cd->int_status);
+		dev_dbg(dev, "%s: Unexpected mode change, startup\n",
+				__func__);
+		cyttsp4_queue_startup_(cd);
+		goto cyttsp4_irq_exit;
+	}
+
+	/* Expecting command complete interrupt */
+	dev_vdbg(dev, "%s: command byte:0x%x\n", __func__, mode[cmd_ofs]);
+	if ((cd->int_status & CY_INT_EXEC_CMD)
+			&& mode[cmd_ofs] & CY_CMD_COMPLETE) {
+		cd->int_status &= ~CY_INT_EXEC_CMD;
+		dev_vdbg(dev, "%s: Received command complete interrupt\n",
+				__func__);
+		wake_up(&cd->wait_q);
+		/*
+		 * It is possible to receive a single interrupt for
+		 * command complete and touch/button status report.
+		 * Continue processing for a possible status report.
+		 */
+	}
+
+	/* This should be status report, read status regs */
+	if (cd->mode == CY_MODE_OPERATIONAL) {
+		dev_vdbg(dev, "%s: Read status registers\n", __func__);
+		rc = cyttsp4_load_status_regs(cd);
+		if (rc < 0)
+			dev_err(dev, "%s: fail read mode regs r=%d\n",
+				__func__, rc);
+	}
+
+	cyttsp4_mt_attention(cd);
+
+cyttsp4_irq_handshake:
+	/* handshake the event */
+	dev_vdbg(dev, "%s: Handshake mode=0x%02X r=%d\n",
+			__func__, mode[0], rc);
+	rc = cyttsp4_handshake(cd, mode[0]);
+	if (rc < 0)
+		dev_err(dev, "%s: Fail handshake mode=0x%02X r=%d\n",
+				__func__, mode[0], rc);
+
+	/*
+	 * a non-zero udelay period is required for using
+	 * IRQF_TRIGGER_LOW in order to delay until the
+	 * device completes isr deassert
+	 */
+	udelay(cd->cpdata->level_irq_udelay);
+
+cyttsp4_irq_exit:
+	mutex_unlock(&cd->system_lock);
+	return IRQ_HANDLED;
+}
+
+static void cyttsp4_start_wd_timer(struct cyttsp4 *cd)
+{
+	if (!CY_WATCHDOG_TIMEOUT)
+		return;
+
+	mod_timer(&cd->watchdog_timer, jiffies +
+			msecs_to_jiffies(CY_WATCHDOG_TIMEOUT));
+}
+
+static void cyttsp4_stop_wd_timer(struct cyttsp4 *cd)
+{
+	if (!CY_WATCHDOG_TIMEOUT)
+		return;
+
+	/*
+	 * Ensure we wait until the watchdog timer
+	 * running on a different CPU finishes
+	 */
+	del_timer_sync(&cd->watchdog_timer);
+	cancel_work_sync(&cd->watchdog_work);
+	del_timer_sync(&cd->watchdog_timer);
+}
+
+static void cyttsp4_watchdog_timer(unsigned long handle)
+{
+	struct cyttsp4 *cd = (struct cyttsp4 *)handle;
+
+	dev_vdbg(cd->dev, "%s: Watchdog timer triggered\n", __func__);
+
+	if (!cd)
+		return;
+
+	if (!work_pending(&cd->watchdog_work))
+		schedule_work(&cd->watchdog_work);
+
+	return;
+}
+
+static int cyttsp4_request_exclusive(struct cyttsp4 *cd, void *ownptr,
+		int timeout_ms)
+{
+	int t = msecs_to_jiffies(timeout_ms);
+	bool with_timeout = (timeout_ms != 0);
+
+	mutex_lock(&cd->system_lock);
+	if (!cd->exclusive_dev && cd->exclusive_waits == 0) {
+		cd->exclusive_dev = ownptr;
+		goto exit;
+	}
+
+	cd->exclusive_waits++;
+wait:
+	mutex_unlock(&cd->system_lock);
+	if (with_timeout) {
+		t = wait_event_timeout(cd->wait_q, !cd->exclusive_dev, t);
+		if (IS_TMO(t)) {
+			dev_err(cd->dev, "%s: tmo waiting exclusive access\n",
+				__func__);
+			mutex_lock(&cd->system_lock);
+			cd->exclusive_waits--;
+			mutex_unlock(&cd->system_lock);
+			return -ETIME;
+		}
+	} else {
+		wait_event(cd->wait_q, !cd->exclusive_dev);
+	}
+	mutex_lock(&cd->system_lock);
+	if (cd->exclusive_dev)
+		goto wait;
+	cd->exclusive_dev = ownptr;
+	cd->exclusive_waits--;
+exit:
+	mutex_unlock(&cd->system_lock);
+
+	return 0;
+}
+
+/*
+ * returns error if was not owned
+ */
+static int cyttsp4_release_exclusive(struct cyttsp4 *cd, void *ownptr)
+{
+	mutex_lock(&cd->system_lock);
+	if (cd->exclusive_dev != ownptr) {
+		mutex_unlock(&cd->system_lock);
+		return -EINVAL;
+	}
+
+	dev_vdbg(cd->dev, "%s: exclusive_dev %p freed\n",
+		__func__, cd->exclusive_dev);
+	cd->exclusive_dev = NULL;
+	wake_up(&cd->wait_q);
+	mutex_unlock(&cd->system_lock);
+	return 0;
+}
+
+static int cyttsp4_wait_bl_heartbeat(struct cyttsp4 *cd)
+{
+	long t;
+	int rc = 0;
+
+	/* wait heartbeat */
+	dev_vdbg(cd->dev, "%s: wait heartbeat...\n", __func__);
+	t = wait_event_timeout(cd->wait_q, cd->mode == CY_MODE_BOOTLOADER,
+			msecs_to_jiffies(CY_CORE_RESET_AND_WAIT_TIMEOUT));
+	if (IS_TMO(t)) {
+		dev_err(cd->dev, "%s: tmo waiting bl heartbeat cd->mode=%d\n",
+			__func__, cd->mode);
+		rc = -ETIME;
+	}
+
+	return rc;
+}
+
+static int cyttsp4_wait_sysinfo_mode(struct cyttsp4 *cd)
+{
+	long t;
+
+	dev_vdbg(cd->dev, "%s: wait sysinfo...\n", __func__);
+
+	t = wait_event_timeout(cd->wait_q, cd->mode == CY_MODE_SYSINFO,
+			msecs_to_jiffies(CY_CORE_MODE_CHANGE_TIMEOUT));
+	if (IS_TMO(t)) {
+		dev_err(cd->dev, "%s: tmo waiting exit bl cd->mode=%d\n",
+			__func__, cd->mode);
+		mutex_lock(&cd->system_lock);
+		cd->int_status &= ~CY_INT_MODE_CHANGE;
+		mutex_unlock(&cd->system_lock);
+		return -ETIME;
+	}
+
+	return 0;
+}
+
+static int cyttsp4_reset_and_wait(struct cyttsp4 *cd)
+{
+	int rc;
+
+	/* reset hardware */
+	mutex_lock(&cd->system_lock);
+	dev_dbg(cd->dev, "%s: reset hw...\n", __func__);
+	rc = cyttsp4_hw_reset(cd);
+	cd->mode = CY_MODE_UNKNOWN;
+	mutex_unlock(&cd->system_lock);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s:Fail hw reset r=%d\n", __func__, rc);
+		return rc;
+	}
+
+	return cyttsp4_wait_bl_heartbeat(cd);
+}
+
+/*
+ * returns err if refused or timeout; block until mode change complete
+ * bit is set (mode change interrupt)
+ */
+static int cyttsp4_set_mode(struct cyttsp4 *cd, int new_mode)
+{
+	u8 new_dev_mode;
+	u8 mode;
+	long t;
+	int rc;
+
+	switch (new_mode) {
+	case CY_MODE_OPERATIONAL:
+		new_dev_mode = CY_HST_OPERATE;
+		break;
+	case CY_MODE_SYSINFO:
+		new_dev_mode = CY_HST_SYSINFO;
+		break;
+	case CY_MODE_CAT:
+		new_dev_mode = CY_HST_CAT;
+		break;
+	default:
+		dev_err(cd->dev, "%s: invalid mode: %02X(%d)\n",
+			__func__, new_mode, new_mode);
+		return -EINVAL;
+	}
+
+	/* change mode */
+	dev_dbg(cd->dev, "%s: %s=%p new_dev_mode=%02X new_mode=%d\n",
+			__func__, "have exclusive", cd->exclusive_dev,
+			new_dev_mode, new_mode);
+
+	mutex_lock(&cd->system_lock);
+	rc = cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(mode), &mode);
+	if (rc < 0) {
+		mutex_unlock(&cd->system_lock);
+		dev_err(cd->dev, "%s: Fail read mode r=%d\n",
+			__func__, rc);
+		goto exit;
+	}
+
+	/* Clear device mode bits and set to new mode */
+	mode &= ~CY_HST_MODE;
+	mode |= new_dev_mode | CY_HST_MODE_CHANGE;
+
+	cd->int_status |= CY_INT_MODE_CHANGE;
+	rc = cyttsp4_adap_write(cd, CY_REG_BASE, sizeof(mode), &mode);
+	mutex_unlock(&cd->system_lock);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: Fail write mode change r=%d\n",
+				__func__, rc);
+		goto exit;
+	}
+
+	/* wait for mode change done interrupt */
+	t = wait_event_timeout(cd->wait_q,
+			(cd->int_status & CY_INT_MODE_CHANGE) == 0,
+			msecs_to_jiffies(CY_CORE_MODE_CHANGE_TIMEOUT));
+	dev_dbg(cd->dev, "%s: back from wait t=%ld cd->mode=%d\n",
+			__func__, t, cd->mode);
+
+	if (IS_TMO(t)) {
+		dev_err(cd->dev, "%s: %s\n", __func__,
+				"tmo waiting mode change");
+		mutex_lock(&cd->system_lock);
+		cd->int_status &= ~CY_INT_MODE_CHANGE;
+		mutex_unlock(&cd->system_lock);
+		rc = -EINVAL;
+	}
+
+exit:
+	return rc;
+}
+
+static void cyttsp4_watchdog_work(struct work_struct *work)
+{
+	struct cyttsp4 *cd =
+		container_of(work, struct cyttsp4, watchdog_work);
+	u8 *mode;
+	int retval;
+
+	mutex_lock(&cd->system_lock);
+	retval = cyttsp4_load_status_regs(cd);
+	if (retval < 0) {
+		dev_err(cd->dev,
+			"%s: failed to access device in watchdog timer r=%d\n",
+			__func__, retval);
+		cyttsp4_queue_startup_(cd);
+		goto cyttsp4_timer_watchdog_exit_error;
+	}
+	mode = &cd->sysinfo.xy_mode[CY_REG_BASE];
+	if (IS_BOOTLOADER(mode[0], mode[1])) {
+		dev_err(cd->dev,
+			"%s: device found in bootloader mode when operational mode\n",
+			__func__);
+		cyttsp4_queue_startup_(cd);
+		goto cyttsp4_timer_watchdog_exit_error;
+	}
+
+	cyttsp4_start_wd_timer(cd);
+cyttsp4_timer_watchdog_exit_error:
+	mutex_unlock(&cd->system_lock);
+	return;
+}
+
+static int cyttsp4_core_sleep_(struct cyttsp4 *cd)
+{
+	enum cyttsp4_sleep_state ss = SS_SLEEP_ON;
+	enum cyttsp4_int_state int_status = CY_INT_IGNORE;
+	int rc = 0;
+	u8 mode[2];
+
+	/* Already in sleep mode? */
+	mutex_lock(&cd->system_lock);
+	if (cd->sleep_state == SS_SLEEP_ON) {
+		mutex_unlock(&cd->system_lock);
+		return 0;
+	}
+	cd->sleep_state = SS_SLEEPING;
+	mutex_unlock(&cd->system_lock);
+
+	cyttsp4_stop_wd_timer(cd);
+
+	/* Wait until currently running IRQ handler exits and disable IRQ */
+	disable_irq(cd->irq);
+
+	dev_vdbg(cd->dev, "%s: write DEEP SLEEP...\n", __func__);
+	mutex_lock(&cd->system_lock);
+	rc = cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(mode), &mode);
+	if (rc) {
+		mutex_unlock(&cd->system_lock);
+		dev_err(cd->dev, "%s: Fail read adapter r=%d\n", __func__, rc);
+		goto error;
+	}
+
+	if (IS_BOOTLOADER(mode[0], mode[1])) {
+		mutex_unlock(&cd->system_lock);
+		dev_err(cd->dev, "%s: Device in BOOTLADER mode.\n", __func__);
+		rc = -EINVAL;
+		goto error;
+	}
+
+	mode[0] |= CY_HST_SLEEP;
+	rc = cyttsp4_adap_write(cd, CY_REG_BASE, sizeof(mode[0]), &mode[0]);
+	mutex_unlock(&cd->system_lock);
+	if (rc) {
+		dev_err(cd->dev, "%s: Fail write adapter r=%d\n", __func__, rc);
+		goto error;
+	}
+	dev_vdbg(cd->dev, "%s: write DEEP SLEEP succeeded\n", __func__);
+
+	if (cd->cpdata->power) {
+		dev_dbg(cd->dev, "%s: Power down HW\n", __func__);
+		rc = cd->cpdata->power(cd->cpdata, 0, cd->dev, &cd->ignore_irq);
+	} else {
+		dev_dbg(cd->dev, "%s: No power function\n", __func__);
+		rc = 0;
+	}
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: HW Power down fails r=%d\n",
+				__func__, rc);
+		goto error;
+	}
+
+	/* Give time to FW to sleep */
+	msleep(50);
+
+	goto exit;
+
+error:
+	ss = SS_SLEEP_OFF;
+	int_status = CY_INT_NONE;
+	cyttsp4_start_wd_timer(cd);
+
+exit:
+	mutex_lock(&cd->system_lock);
+	cd->sleep_state = ss;
+	cd->int_status |= int_status;
+	mutex_unlock(&cd->system_lock);
+	enable_irq(cd->irq);
+	return rc;
+}
+
+static int cyttsp4_core_sleep(struct cyttsp4 *cd)
+{
+	int rc;
+
+	rc = cyttsp4_request_exclusive(cd, cd->dev,
+			CY_CORE_SLEEP_REQUEST_EXCLUSIVE_TIMEOUT);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
+				__func__, cd->exclusive_dev, cd->dev);
+		return 0;
+	}
+
+	rc = cyttsp4_core_sleep_(cd);
+
+	if (cyttsp4_release_exclusive(cd, cd->dev) < 0)
+		dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
+	else
+		dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__);
+
+	return rc;
+}
+
+static int cyttsp4_core_wake_(struct cyttsp4 *cd)
+{
+	struct device *dev = cd->dev;
+	int rc;
+	u8 mode;
+	int t;
+
+	/* Already woken? */
+	mutex_lock(&cd->system_lock);
+	if (cd->sleep_state == SS_SLEEP_OFF) {
+		mutex_unlock(&cd->system_lock);
+		return 0;
+	}
+	cd->int_status &= ~CY_INT_IGNORE;
+	cd->int_status |= CY_INT_AWAKE;
+	cd->sleep_state = SS_WAKING;
+
+	if (cd->cpdata->power) {
+		dev_dbg(dev, "%s: Power up HW\n", __func__);
+		rc = cd->cpdata->power(cd->cpdata, 1, dev, &cd->ignore_irq);
+	} else {
+		dev_dbg(dev, "%s: No power function\n", __func__);
+		rc = -ENOSYS;
+	}
+	if (rc < 0) {
+		dev_err(dev, "%s: HW Power up fails r=%d\n",
+				__func__, rc);
+
+		/* Initiate a read transaction to wake up */
+		cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(mode), &mode);
+	} else
+		dev_vdbg(cd->dev, "%s: HW power up succeeds\n",
+			__func__);
+	mutex_unlock(&cd->system_lock);
+
+	t = wait_event_timeout(cd->wait_q,
+			(cd->int_status & CY_INT_AWAKE) == 0,
+			msecs_to_jiffies(CY_CORE_WAKEUP_TIMEOUT));
+	if (IS_TMO(t)) {
+		dev_err(dev, "%s: TMO waiting for wakeup\n", __func__);
+		mutex_lock(&cd->system_lock);
+		cd->int_status &= ~CY_INT_AWAKE;
+		/* Try starting up */
+		cyttsp4_queue_startup_(cd);
+		mutex_unlock(&cd->system_lock);
+	}
+
+	mutex_lock(&cd->system_lock);
+	cd->sleep_state = SS_SLEEP_OFF;
+	mutex_unlock(&cd->system_lock);
+
+	cyttsp4_start_wd_timer(cd);
+
+	return 0;
+}
+
+static int cyttsp4_core_wake(struct cyttsp4 *cd)
+{
+	int rc;
+
+	rc = cyttsp4_request_exclusive(cd, cd->dev,
+			CY_CORE_REQUEST_EXCLUSIVE_TIMEOUT);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
+				__func__, cd->exclusive_dev, cd->dev);
+		return 0;
+	}
+
+	rc = cyttsp4_core_wake_(cd);
+
+	if (cyttsp4_release_exclusive(cd, cd->dev) < 0)
+		dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
+	else
+		dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__);
+
+	return rc;
+}
+
+static int cyttsp4_startup_(struct cyttsp4 *cd)
+{
+	int retry = CY_CORE_STARTUP_RETRY_COUNT;
+	int rc;
+
+	cyttsp4_stop_wd_timer(cd);
+
+reset:
+	if (retry != CY_CORE_STARTUP_RETRY_COUNT)
+		dev_dbg(cd->dev, "%s: Retry %d\n", __func__,
+			CY_CORE_STARTUP_RETRY_COUNT - retry);
+
+	/* reset hardware and wait for heartbeat */
+	rc = cyttsp4_reset_and_wait(cd);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: Error on h/w reset r=%d\n", __func__, rc);
+		if (retry--)
+			goto reset;
+		goto exit;
+	}
+
+	/* exit bl into sysinfo mode */
+	dev_vdbg(cd->dev, "%s: write exit ldr...\n", __func__);
+	mutex_lock(&cd->system_lock);
+	cd->int_status &= ~CY_INT_IGNORE;
+	cd->int_status |= CY_INT_MODE_CHANGE;
+
+	rc = cyttsp4_adap_write(cd, CY_REG_BASE, sizeof(ldr_exit),
+			(u8 *)ldr_exit);
+	mutex_unlock(&cd->system_lock);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: Fail write r=%d\n", __func__, rc);
+		if (retry--)
+			goto reset;
+		goto exit;
+	}
+
+	rc = cyttsp4_wait_sysinfo_mode(cd);
+	if (rc < 0) {
+		u8 buf[sizeof(ldr_err_app)];
+		int rc1;
+
+		/* Check for invalid/corrupted touch application */
+		rc1 = cyttsp4_adap_read(cd, CY_REG_BASE, sizeof(ldr_err_app),
+				buf);
+		if (rc1) {
+			dev_err(cd->dev, "%s: Fail read r=%d\n", __func__, rc1);
+		} else if (!memcmp(buf, ldr_err_app, sizeof(ldr_err_app))) {
+			dev_err(cd->dev, "%s: Error launching touch application\n",
+				__func__);
+			mutex_lock(&cd->system_lock);
+			cd->invalid_touch_app = true;
+			mutex_unlock(&cd->system_lock);
+			goto exit_no_wd;
+		}
+
+		if (retry--)
+			goto reset;
+		goto exit;
+	}
+
+	mutex_lock(&cd->system_lock);
+	cd->invalid_touch_app = false;
+	mutex_unlock(&cd->system_lock);
+
+	/* read sysinfo data */
+	dev_vdbg(cd->dev, "%s: get sysinfo regs..\n", __func__);
+	rc = cyttsp4_get_sysinfo_regs(cd);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: failed to get sysinfo regs rc=%d\n",
+			__func__, rc);
+		if (retry--)
+			goto reset;
+		goto exit;
+	}
+
+	rc = cyttsp4_set_mode(cd, CY_MODE_OPERATIONAL);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: failed to set mode to operational rc=%d\n",
+			__func__, rc);
+		if (retry--)
+			goto reset;
+		goto exit;
+	}
+
+	cyttsp4_lift_all(&cd->md);
+
+	/* restore to sleep if was suspended */
+	mutex_lock(&cd->system_lock);
+	if (cd->sleep_state == SS_SLEEP_ON) {
+		cd->sleep_state = SS_SLEEP_OFF;
+		mutex_unlock(&cd->system_lock);
+		cyttsp4_core_sleep_(cd);
+		goto exit_no_wd;
+	}
+	mutex_unlock(&cd->system_lock);
+
+exit:
+	cyttsp4_start_wd_timer(cd);
+exit_no_wd:
+	return rc;
+}
+
+static int cyttsp4_startup(struct cyttsp4 *cd)
+{
+	int rc;
+
+	mutex_lock(&cd->system_lock);
+	cd->startup_state = STARTUP_RUNNING;
+	mutex_unlock(&cd->system_lock);
+
+	rc = cyttsp4_request_exclusive(cd, cd->dev,
+			CY_CORE_REQUEST_EXCLUSIVE_TIMEOUT);
+	if (rc < 0) {
+		dev_err(cd->dev, "%s: fail get exclusive ex=%p own=%p\n",
+				__func__, cd->exclusive_dev, cd->dev);
+		goto exit;
+	}
+
+	rc = cyttsp4_startup_(cd);
+
+	if (cyttsp4_release_exclusive(cd, cd->dev) < 0)
+		/* Don't return fail code, mode is already changed. */
+		dev_err(cd->dev, "%s: fail to release exclusive\n", __func__);
+	else
+		dev_vdbg(cd->dev, "%s: pass release exclusive\n", __func__);
+
+exit:
+	mutex_lock(&cd->system_lock);
+	cd->startup_state = STARTUP_NONE;
+	mutex_unlock(&cd->system_lock);
+
+	/* Wake the waiters for end of startup */
+	wake_up(&cd->wait_q);
+
+	return rc;
+}
+
+static void cyttsp4_startup_work_function(struct work_struct *work)
+{
+	struct cyttsp4 *cd =  container_of(work, struct cyttsp4, startup_work);
+	int rc;
+
+	rc = cyttsp4_startup(cd);
+	if (rc < 0)
+		dev_err(cd->dev, "%s: Fail queued startup r=%d\n",
+			__func__, rc);
+}
+
+static void cyttsp4_free_si_ptrs(struct cyttsp4 *cd)
+{
+	struct cyttsp4_sysinfo *si = &cd->sysinfo;
+
+	if (!si)
+		return;
+
+	kfree(si->si_ptrs.cydata);
+	kfree(si->si_ptrs.test);
+	kfree(si->si_ptrs.pcfg);
+	kfree(si->si_ptrs.opcfg);
+	kfree(si->si_ptrs.ddata);
+	kfree(si->si_ptrs.mdata);
+	kfree(si->btn);
+	kfree(si->xy_mode);
+	kfree(si->xy_data);
+	kfree(si->btn_rec_data);
+}
+
+#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME)
+static int cyttsp4_core_suspend(struct device *dev)
+{
+	struct cyttsp4 *cd = dev_get_drvdata(dev);
+	struct cyttsp4_mt_data *md = &cd->md;
+	int rc;
+
+	md->is_suspended = true;
+
+	rc = cyttsp4_core_sleep(cd);
+	if (rc < 0) {
+		dev_err(dev, "%s: Error on sleep\n", __func__);
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+static int cyttsp4_core_resume(struct device *dev)
+{
+	struct cyttsp4 *cd = dev_get_drvdata(dev);
+	struct cyttsp4_mt_data *md = &cd->md;
+	int rc;
+
+	md->is_suspended = false;
+
+	rc = cyttsp4_core_wake(cd);
+	if (rc < 0) {
+		dev_err(dev, "%s: Error on wake\n", __func__);
+		return -EAGAIN;
+	}
+
+	return 0;
+}
+#endif
+
+const struct dev_pm_ops cyttsp4_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(cyttsp4_core_suspend, cyttsp4_core_resume)
+	SET_RUNTIME_PM_OPS(cyttsp4_core_suspend, cyttsp4_core_resume, NULL)
+};
+EXPORT_SYMBOL_GPL(cyttsp4_pm_ops);
+
+static int cyttsp4_mt_open(struct input_dev *input)
+{
+	pm_runtime_get(input->dev.parent);
+	return 0;
+}
+
+static void cyttsp4_mt_close(struct input_dev *input)
+{
+	struct cyttsp4_mt_data *md = input_get_drvdata(input);
+	mutex_lock(&md->report_lock);
+	if (!md->is_suspended)
+		pm_runtime_put(input->dev.parent);
+	mutex_unlock(&md->report_lock);
+}
+
+
+static int cyttsp4_setup_input_device(struct cyttsp4 *cd)
+{
+	struct device *dev = cd->dev;
+	struct cyttsp4_mt_data *md = &cd->md;
+	int signal = CY_IGNORE_VALUE;
+	int max_x, max_y, max_p, min, max;
+	int max_x_tmp, max_y_tmp;
+	int i;
+	int rc;
+
+	dev_vdbg(dev, "%s: Initialize event signals\n", __func__);
+	__set_bit(EV_ABS, md->input->evbit);
+	__set_bit(EV_REL, md->input->evbit);
+	__set_bit(EV_KEY, md->input->evbit);
+
+	max_x_tmp = md->si->si_ofs.max_x;
+	max_y_tmp = md->si->si_ofs.max_y;
+
+	/* get maximum values from the sysinfo data */
+	if (md->pdata->flags & CY_FLAG_FLIP) {
+		max_x = max_y_tmp - 1;
+		max_y = max_x_tmp - 1;
+	} else {
+		max_x = max_x_tmp - 1;
+		max_y = max_y_tmp - 1;
+	}
+	max_p = md->si->si_ofs.max_p;
+
+	/* set event signal capabilities */
+	for (i = 0; i < (md->pdata->frmwrk->size / CY_NUM_ABS_SET); i++) {
+		signal = md->pdata->frmwrk->abs
+			[(i * CY_NUM_ABS_SET) + CY_SIGNAL_OST];
+		if (signal != CY_IGNORE_VALUE) {
+			__set_bit(signal, md->input->absbit);
+			min = md->pdata->frmwrk->abs
+				[(i * CY_NUM_ABS_SET) + CY_MIN_OST];
+			max = md->pdata->frmwrk->abs
+				[(i * CY_NUM_ABS_SET) + CY_MAX_OST];
+			if (i == CY_ABS_ID_OST) {
+				/* shift track ids down to start at 0 */
+				max = max - min;
+				min = min - min;
+			} else if (i == CY_ABS_X_OST)
+				max = max_x;
+			else if (i == CY_ABS_Y_OST)
+				max = max_y;
+			else if (i == CY_ABS_P_OST)
+				max = max_p;
+			input_set_abs_params(md->input, signal, min, max,
+				md->pdata->frmwrk->abs
+				[(i * CY_NUM_ABS_SET) + CY_FUZZ_OST],
+				md->pdata->frmwrk->abs
+				[(i * CY_NUM_ABS_SET) + CY_FLAT_OST]);
+			dev_dbg(dev, "%s: register signal=%02X min=%d max=%d\n",
+				__func__, signal, min, max);
+			if ((i == CY_ABS_ID_OST) &&
+				(md->si->si_ofs.tch_rec_size <
+				CY_TMA4XX_TCH_REC_SIZE))
+				break;
+		}
+	}
+
+	input_mt_init_slots(md->input, md->si->si_ofs.tch_abs[CY_TCH_T].max,
+			INPUT_MT_DIRECT);
+	rc = input_register_device(md->input);
+	if (rc < 0)
+		dev_err(dev, "%s: Error, failed register input device r=%d\n",
+			__func__, rc);
+	return rc;
+}
+
+static int cyttsp4_mt_probe(struct cyttsp4 *cd)
+{
+	struct device *dev = cd->dev;
+	struct cyttsp4_mt_data *md = &cd->md;
+	struct cyttsp4_mt_platform_data *pdata = cd->pdata->mt_pdata;
+	int rc = 0;
+
+	mutex_init(&md->report_lock);
+	md->pdata = pdata;
+	/* Create the input device and register it. */
+	dev_vdbg(dev, "%s: Create the input device and register it\n",
+		__func__);
+	md->input = input_allocate_device();
+	if (md->input == NULL) {
+		dev_err(dev, "%s: Error, failed to allocate input device\n",
+			__func__);
+		rc = -ENOSYS;
+		goto error_alloc_failed;
+	}
+
+	md->input->name = pdata->inp_dev_name;
+	scnprintf(md->phys, sizeof(md->phys)-1, "%s", dev_name(dev));
+	md->input->phys = md->phys;
+	md->input->id.bustype = cd->bus_ops->bustype;
+	md->input->dev.parent = dev;
+	md->input->open = cyttsp4_mt_open;
+	md->input->close = cyttsp4_mt_close;
+	input_set_drvdata(md->input, md);
+
+	/* get sysinfo */
+	md->si = &cd->sysinfo;
+	if (!md->si) {
+		dev_err(dev, "%s: Fail get sysinfo pointer from core p=%p\n",
+			__func__, md->si);
+		goto error_get_sysinfo;
+	}
+
+	rc = cyttsp4_setup_input_device(cd);
+	if (rc)
+		goto error_init_input;
+
+	return 0;
+
+error_init_input:
+	input_free_device(md->input);
+error_get_sysinfo:
+	input_set_drvdata(md->input, NULL);
+error_alloc_failed:
+	dev_err(dev, "%s failed.\n", __func__);
+	return rc;
+}
+
+struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops,
+		struct device *dev, u16 irq, size_t xfer_buf_size)
+{
+	struct cyttsp4 *cd;
+	struct cyttsp4_platform_data *pdata = dev_get_platdata(dev);
+	unsigned long irq_flags;
+	int rc = 0;
+
+	if (!pdata || !pdata->core_pdata || !pdata->mt_pdata) {
+		dev_err(dev, "%s: Missing platform data\n", __func__);
+		rc = -ENODEV;
+		goto error_no_pdata;
+	}
+
+	cd = kzalloc(sizeof(*cd), GFP_KERNEL);
+	if (!cd) {
+		dev_err(dev, "%s: Error, kzalloc\n", __func__);
+		rc = -ENOMEM;
+		goto error_alloc_data;
+	}
+
+	cd->xfer_buf = kzalloc(xfer_buf_size, GFP_KERNEL);
+	if (!cd->xfer_buf) {
+		dev_err(dev, "%s: Error, kzalloc\n", __func__);
+		rc = -ENOMEM;
+		goto error_free_cd;
+	}
+
+	/* Initialize device info */
+	cd->dev = dev;
+	cd->pdata = pdata;
+	cd->cpdata = pdata->core_pdata;
+	cd->bus_ops = ops;
+
+	/* Initialize mutexes and spinlocks */
+	mutex_init(&cd->system_lock);
+	mutex_init(&cd->adap_lock);
+
+	/* Initialize wait queue */
+	init_waitqueue_head(&cd->wait_q);
+
+	/* Initialize works */
+	INIT_WORK(&cd->startup_work, cyttsp4_startup_work_function);
+	INIT_WORK(&cd->watchdog_work, cyttsp4_watchdog_work);
+
+	/* Initialize IRQ */
+	cd->irq = gpio_to_irq(cd->cpdata->irq_gpio);
+	if (cd->irq < 0) {
+		rc = -EINVAL;
+		goto error_free_xfer;
+	}
+
+	dev_set_drvdata(dev, cd);
+
+	/* Call platform init function */
+	if (cd->cpdata->init) {
+		dev_dbg(cd->dev, "%s: Init HW\n", __func__);
+		rc = cd->cpdata->init(cd->cpdata, 1, cd->dev);
+	} else {
+		dev_dbg(cd->dev, "%s: No HW INIT function\n", __func__);
+		rc = 0;
+	}
+	if (rc < 0)
+		dev_err(cd->dev, "%s: HW Init fail r=%d\n", __func__, rc);
+
+	dev_dbg(dev, "%s: initialize threaded irq=%d\n", __func__, cd->irq);
+	if (cd->cpdata->level_irq_udelay > 0)
+		/* use level triggered interrupts */
+		irq_flags = IRQF_TRIGGER_LOW | IRQF_ONESHOT;
+	else
+		/* use edge triggered interrupts */
+		irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+
+	rc = request_threaded_irq(cd->irq, NULL, cyttsp4_irq, irq_flags,
+		dev_name(dev), cd);
+	if (rc < 0) {
+		dev_err(dev, "%s: Error, could not request irq\n", __func__);
+		goto error_request_irq;
+	}
+
+	/* Setup watchdog timer */
+	setup_timer(&cd->watchdog_timer, cyttsp4_watchdog_timer,
+		(unsigned long)cd);
+
+	/*
+	 * call startup directly to ensure that the device
+	 * is tested before leaving the probe
+	 */
+	rc = cyttsp4_startup(cd);
+
+	/* Do not fail probe if startup fails but the device is detected */
+	if (rc < 0 && cd->mode == CY_MODE_UNKNOWN) {
+		dev_err(cd->dev, "%s: Fail initial startup r=%d\n",
+			__func__, rc);
+		goto error_startup;
+	}
+
+	rc = cyttsp4_mt_probe(cd);
+	if (rc < 0) {
+		dev_err(dev, "%s: Error, fail mt probe\n", __func__);
+		goto error_startup;
+	}
+
+	pm_runtime_enable(dev);
+
+	return cd;
+
+error_startup:
+	cancel_work_sync(&cd->startup_work);
+	cyttsp4_stop_wd_timer(cd);
+	pm_runtime_disable(dev);
+	cyttsp4_free_si_ptrs(cd);
+	free_irq(cd->irq, cd);
+error_request_irq:
+	if (cd->cpdata->init)
+		cd->cpdata->init(cd->cpdata, 0, dev);
+	dev_set_drvdata(dev, NULL);
+error_free_xfer:
+	kfree(cd->xfer_buf);
+error_free_cd:
+	kfree(cd);
+error_alloc_data:
+error_no_pdata:
+	dev_err(dev, "%s failed.\n", __func__);
+	return ERR_PTR(rc);
+}
+EXPORT_SYMBOL_GPL(cyttsp4_probe);
+
+static void cyttsp4_mt_release(struct cyttsp4_mt_data *md)
+{
+	input_unregister_device(md->input);
+	input_set_drvdata(md->input, NULL);
+}
+
+int cyttsp4_remove(struct cyttsp4 *cd)
+{
+	struct device *dev = cd->dev;
+
+	cyttsp4_mt_release(&cd->md);
+
+	/*
+	 * Suspend the device before freeing the startup_work and stopping
+	 * the watchdog since sleep function restarts watchdog on failure
+	 */
+	pm_runtime_suspend(dev);
+	pm_runtime_disable(dev);
+
+	cancel_work_sync(&cd->startup_work);
+
+	cyttsp4_stop_wd_timer(cd);
+
+	free_irq(cd->irq, cd);
+	if (cd->cpdata->init)
+		cd->cpdata->init(cd->cpdata, 0, dev);
+	dev_set_drvdata(dev, NULL);
+	cyttsp4_free_si_ptrs(cd);
+	kfree(cd);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cyttsp4_remove);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard touchscreen core driver");
+MODULE_AUTHOR("Cypress");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp4_core.h linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp4_core.h
--- linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp4_core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp4_core.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,472 @@
+/*
+ * cyttsp4_core.h
+ * Cypress TrueTouch(TM) Standard Product V4 Core driver module.
+ * For use with Cypress Txx4xx parts.
+ * Supported parts include:
+ * TMA4XX
+ * TMA1036
+ *
+ * Copyright (C) 2012 Cypress Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
+ *
+ */
+
+#ifndef _LINUX_CYTTSP4_CORE_H
+#define _LINUX_CYTTSP4_CORE_H
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/limits.h>
+#include <linux/module.h>
+#include <linux/stringify.h>
+#include <linux/types.h>
+#include <linux/platform_data/cyttsp4.h>
+
+#define CY_REG_BASE			0x00
+
+#define CY_POST_CODEL_WDG_RST		0x01
+#define CY_POST_CODEL_CFG_DATA_CRC_FAIL	0x02
+#define CY_POST_CODEL_PANEL_TEST_FAIL	0x04
+
+#define CY_NUM_BTN_PER_REG		4
+
+/* touch record system information offset masks and shifts */
+#define CY_BYTE_OFS_MASK		0x1F
+#define CY_BOFS_MASK			0xE0
+#define CY_BOFS_SHIFT			5
+
+#define CY_TMA1036_TCH_REC_SIZE		6
+#define CY_TMA4XX_TCH_REC_SIZE		9
+#define CY_TMA1036_MAX_TCH		0x0E
+#define CY_TMA4XX_MAX_TCH		0x1E
+
+#define CY_NORMAL_ORIGIN		0	/* upper, left corner */
+#define CY_INVERT_ORIGIN		1	/* lower, right corner */
+
+/* helpers */
+#define GET_NUM_TOUCHES(x)		((x) & 0x1F)
+#define IS_LARGE_AREA(x)		((x) & 0x20)
+#define IS_BAD_PKT(x)			((x) & 0x20)
+#define IS_BOOTLOADER(hst_mode, reset_detect)	\
+		((hst_mode) & 0x01 || (reset_detect) != 0)
+#define IS_TMO(t)			((t) == 0)
+
+
+enum cyttsp_cmd_bits {
+	CY_CMD_COMPLETE = (1 << 6),
+};
+
+/* Timeout in ms. */
+#define CY_WATCHDOG_TIMEOUT		1000
+
+#define CY_MAX_PRINT_SIZE		512
+#ifdef VERBOSE_DEBUG
+#define CY_MAX_PRBUF_SIZE		PIPE_BUF
+#define CY_PR_TRUNCATED			" truncated..."
+#endif
+
+enum cyttsp4_ic_grpnum {
+	CY_IC_GRPNUM_RESERVED,
+	CY_IC_GRPNUM_CMD_REGS,
+	CY_IC_GRPNUM_TCH_REP,
+	CY_IC_GRPNUM_DATA_REC,
+	CY_IC_GRPNUM_TEST_REC,
+	CY_IC_GRPNUM_PCFG_REC,
+	CY_IC_GRPNUM_TCH_PARM_VAL,
+	CY_IC_GRPNUM_TCH_PARM_SIZE,
+	CY_IC_GRPNUM_RESERVED1,
+	CY_IC_GRPNUM_RESERVED2,
+	CY_IC_GRPNUM_OPCFG_REC,
+	CY_IC_GRPNUM_DDATA_REC,
+	CY_IC_GRPNUM_MDATA_REC,
+	CY_IC_GRPNUM_TEST_REGS,
+	CY_IC_GRPNUM_BTN_KEYS,
+	CY_IC_GRPNUM_TTHE_REGS,
+	CY_IC_GRPNUM_NUM
+};
+
+enum cyttsp4_int_state {
+	CY_INT_NONE,
+	CY_INT_IGNORE      = (1 << 0),
+	CY_INT_MODE_CHANGE = (1 << 1),
+	CY_INT_EXEC_CMD    = (1 << 2),
+	CY_INT_AWAKE       = (1 << 3),
+};
+
+enum cyttsp4_mode {
+	CY_MODE_UNKNOWN,
+	CY_MODE_BOOTLOADER   = (1 << 1),
+	CY_MODE_OPERATIONAL  = (1 << 2),
+	CY_MODE_SYSINFO      = (1 << 3),
+	CY_MODE_CAT          = (1 << 4),
+	CY_MODE_STARTUP      = (1 << 5),
+	CY_MODE_LOADER       = (1 << 6),
+	CY_MODE_CHANGE_MODE  = (1 << 7),
+	CY_MODE_CHANGED      = (1 << 8),
+	CY_MODE_CMD_COMPLETE = (1 << 9),
+};
+
+enum cyttsp4_sleep_state {
+	SS_SLEEP_OFF,
+	SS_SLEEP_ON,
+	SS_SLEEPING,
+	SS_WAKING,
+};
+
+enum cyttsp4_startup_state {
+	STARTUP_NONE,
+	STARTUP_QUEUED,
+	STARTUP_RUNNING,
+};
+
+#define CY_NUM_REVCTRL			8
+struct cyttsp4_cydata {
+	u8 ttpidh;
+	u8 ttpidl;
+	u8 fw_ver_major;
+	u8 fw_ver_minor;
+	u8 revctrl[CY_NUM_REVCTRL];
+	u8 blver_major;
+	u8 blver_minor;
+	u8 jtag_si_id3;
+	u8 jtag_si_id2;
+	u8 jtag_si_id1;
+	u8 jtag_si_id0;
+	u8 mfgid_sz;
+	u8 cyito_idh;
+	u8 cyito_idl;
+	u8 cyito_verh;
+	u8 cyito_verl;
+	u8 ttsp_ver_major;
+	u8 ttsp_ver_minor;
+	u8 device_info;
+	u8 mfg_id[];
+} __packed;
+
+struct cyttsp4_test {
+	u8 post_codeh;
+	u8 post_codel;
+} __packed;
+
+struct cyttsp4_pcfg {
+	u8 electrodes_x;
+	u8 electrodes_y;
+	u8 len_xh;
+	u8 len_xl;
+	u8 len_yh;
+	u8 len_yl;
+	u8 res_xh;
+	u8 res_xl;
+	u8 res_yh;
+	u8 res_yl;
+	u8 max_zh;
+	u8 max_zl;
+	u8 panel_info0;
+} __packed;
+
+struct cyttsp4_tch_rec_params {
+	u8 loc;
+	u8 size;
+} __packed;
+
+#define CY_NUM_TCH_FIELDS		7
+#define CY_NUM_EXT_TCH_FIELDS		3
+struct cyttsp4_opcfg {
+	u8 cmd_ofs;
+	u8 rep_ofs;
+	u8 rep_szh;
+	u8 rep_szl;
+	u8 num_btns;
+	u8 tt_stat_ofs;
+	u8 obj_cfg0;
+	u8 max_tchs;
+	u8 tch_rec_size;
+	struct cyttsp4_tch_rec_params tch_rec_old[CY_NUM_TCH_FIELDS];
+	u8 btn_rec_size;	/* btn record size (in bytes) */
+	u8 btn_diff_ofs;	/* btn data loc, diff counts  */
+	u8 btn_diff_size;	/* btn size of diff counts (in bits) */
+	struct cyttsp4_tch_rec_params tch_rec_new[CY_NUM_EXT_TCH_FIELDS];
+} __packed;
+
+struct cyttsp4_sysinfo_ptr {
+	struct cyttsp4_cydata *cydata;
+	struct cyttsp4_test *test;
+	struct cyttsp4_pcfg *pcfg;
+	struct cyttsp4_opcfg *opcfg;
+	struct cyttsp4_ddata *ddata;
+	struct cyttsp4_mdata *mdata;
+} __packed;
+
+struct cyttsp4_sysinfo_data {
+	u8 hst_mode;
+	u8 reserved;
+	u8 map_szh;
+	u8 map_szl;
+	u8 cydata_ofsh;
+	u8 cydata_ofsl;
+	u8 test_ofsh;
+	u8 test_ofsl;
+	u8 pcfg_ofsh;
+	u8 pcfg_ofsl;
+	u8 opcfg_ofsh;
+	u8 opcfg_ofsl;
+	u8 ddata_ofsh;
+	u8 ddata_ofsl;
+	u8 mdata_ofsh;
+	u8 mdata_ofsl;
+} __packed;
+
+enum cyttsp4_tch_abs {	/* for ordering within the extracted touch data array */
+	CY_TCH_X,	/* X */
+	CY_TCH_Y,	/* Y */
+	CY_TCH_P,	/* P (Z) */
+	CY_TCH_T,	/* TOUCH ID */
+	CY_TCH_E,	/* EVENT ID */
+	CY_TCH_O,	/* OBJECT ID */
+	CY_TCH_W,	/* SIZE */
+	CY_TCH_MAJ,	/* TOUCH_MAJOR */
+	CY_TCH_MIN,	/* TOUCH_MINOR */
+	CY_TCH_OR,	/* ORIENTATION */
+	CY_TCH_NUM_ABS
+};
+
+static const char * const cyttsp4_tch_abs_string[] = {
+	[CY_TCH_X]	= "X",
+	[CY_TCH_Y]	= "Y",
+	[CY_TCH_P]	= "P",
+	[CY_TCH_T]	= "T",
+	[CY_TCH_E]	= "E",
+	[CY_TCH_O]	= "O",
+	[CY_TCH_W]	= "W",
+	[CY_TCH_MAJ]	= "MAJ",
+	[CY_TCH_MIN]	= "MIN",
+	[CY_TCH_OR]	= "OR",
+	[CY_TCH_NUM_ABS] = "INVALID"
+};
+
+struct cyttsp4_touch {
+	int abs[CY_TCH_NUM_ABS];
+};
+
+struct cyttsp4_tch_abs_params {
+	size_t ofs;	/* abs byte offset */
+	size_t size;	/* size in bits */
+	size_t max;	/* max value */
+	size_t bofs;	/* bit offset */
+};
+
+struct cyttsp4_sysinfo_ofs {
+	size_t chip_type;
+	size_t cmd_ofs;
+	size_t rep_ofs;
+	size_t rep_sz;
+	size_t num_btns;
+	size_t num_btn_regs;	/* ceil(num_btns/4) */
+	size_t tt_stat_ofs;
+	size_t tch_rec_size;
+	size_t obj_cfg0;
+	size_t max_tchs;
+	size_t mode_size;
+	size_t data_size;
+	size_t map_sz;
+	size_t max_x;
+	size_t x_origin;	/* left or right corner */
+	size_t max_y;
+	size_t y_origin;	/* upper or lower corner */
+	size_t max_p;
+	size_t cydata_ofs;
+	size_t test_ofs;
+	size_t pcfg_ofs;
+	size_t opcfg_ofs;
+	size_t ddata_ofs;
+	size_t mdata_ofs;
+	size_t cydata_size;
+	size_t test_size;
+	size_t pcfg_size;
+	size_t opcfg_size;
+	size_t ddata_size;
+	size_t mdata_size;
+	size_t btn_keys_size;
+	struct cyttsp4_tch_abs_params tch_abs[CY_TCH_NUM_ABS];
+	size_t btn_rec_size; /* btn record size (in bytes) */
+	size_t btn_diff_ofs;/* btn data loc ,diff counts, (Op-Mode byte ofs) */
+	size_t btn_diff_size;/* btn size of diff counts (in bits) */
+};
+
+enum cyttsp4_btn_state {
+	CY_BTN_RELEASED,
+	CY_BTN_PRESSED,
+	CY_BTN_NUM_STATE
+};
+
+struct cyttsp4_btn {
+	bool enabled;
+	int state;	/* CY_BTN_PRESSED, CY_BTN_RELEASED */
+	int key_code;
+};
+
+struct cyttsp4_sysinfo {
+	bool ready;
+	struct cyttsp4_sysinfo_data si_data;
+	struct cyttsp4_sysinfo_ptr si_ptrs;
+	struct cyttsp4_sysinfo_ofs si_ofs;
+	struct cyttsp4_btn *btn;	/* button states */
+	u8 *btn_rec_data;		/* button diff count data */
+	u8 *xy_mode;			/* operational mode and status regs */
+	u8 *xy_data;			/* operational touch regs */
+};
+
+struct cyttsp4_mt_data {
+	struct cyttsp4_mt_platform_data *pdata;
+	struct cyttsp4_sysinfo *si;
+	struct input_dev *input;
+	struct mutex report_lock;
+	bool is_suspended;
+	char phys[NAME_MAX];
+	int num_prv_tch;
+};
+
+struct cyttsp4 {
+	struct device *dev;
+	struct mutex system_lock;
+	struct mutex adap_lock;
+	enum cyttsp4_mode mode;
+	enum cyttsp4_sleep_state sleep_state;
+	enum cyttsp4_startup_state startup_state;
+	int int_status;
+	wait_queue_head_t wait_q;
+	int irq;
+	struct work_struct startup_work;
+	struct work_struct watchdog_work;
+	struct timer_list watchdog_timer;
+	struct cyttsp4_sysinfo sysinfo;
+	void *exclusive_dev;
+	int exclusive_waits;
+	atomic_t ignore_irq;
+	bool invalid_touch_app;
+	struct cyttsp4_mt_data md;
+	struct cyttsp4_platform_data *pdata;
+	struct cyttsp4_core_platform_data *cpdata;
+	const struct cyttsp4_bus_ops *bus_ops;
+	u8 *xfer_buf;
+#ifdef VERBOSE_DEBUG
+	u8 pr_buf[CY_MAX_PRBUF_SIZE];
+#endif
+};
+
+struct cyttsp4_bus_ops {
+	u16 bustype;
+	int (*write)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length,
+			const void *values);
+	int (*read)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length,
+			void *values);
+};
+
+enum cyttsp4_hst_mode_bits {
+	CY_HST_TOGGLE      = (1 << 7),
+	CY_HST_MODE_CHANGE = (1 << 3),
+	CY_HST_MODE        = (7 << 4),
+	CY_HST_OPERATE     = (0 << 4),
+	CY_HST_SYSINFO     = (1 << 4),
+	CY_HST_CAT         = (2 << 4),
+	CY_HST_LOWPOW      = (1 << 2),
+	CY_HST_SLEEP       = (1 << 1),
+	CY_HST_RESET       = (1 << 0),
+};
+
+/* abs settings */
+#define CY_IGNORE_VALUE			0xFFFF
+
+/* abs signal capabilities offsets in the frameworks array */
+enum cyttsp4_sig_caps {
+	CY_SIGNAL_OST,
+	CY_MIN_OST,
+	CY_MAX_OST,
+	CY_FUZZ_OST,
+	CY_FLAT_OST,
+	CY_NUM_ABS_SET	/* number of signal capability fields */
+};
+
+/* abs axis signal offsets in the framworks array  */
+enum cyttsp4_sig_ost {
+	CY_ABS_X_OST,
+	CY_ABS_Y_OST,
+	CY_ABS_P_OST,
+	CY_ABS_W_OST,
+	CY_ABS_ID_OST,
+	CY_ABS_MAJ_OST,
+	CY_ABS_MIN_OST,
+	CY_ABS_OR_OST,
+	CY_NUM_ABS_OST	/* number of abs signals */
+};
+
+enum cyttsp4_flags {
+	CY_FLAG_NONE = 0x00,
+	CY_FLAG_HOVER = 0x04,
+	CY_FLAG_FLIP = 0x08,
+	CY_FLAG_INV_X = 0x10,
+	CY_FLAG_INV_Y = 0x20,
+	CY_FLAG_VKEYS = 0x40,
+};
+
+enum cyttsp4_object_id {
+	CY_OBJ_STANDARD_FINGER,
+	CY_OBJ_LARGE_OBJECT,
+	CY_OBJ_STYLUS,
+	CY_OBJ_HOVER,
+};
+
+enum cyttsp4_event_id {
+	CY_EV_NO_EVENT,
+	CY_EV_TOUCHDOWN,
+	CY_EV_MOVE,		/* significant displacement (> act dist) */
+	CY_EV_LIFTOFF,		/* record reports last position */
+};
+
+/* x-axis resolution of panel in pixels */
+#define CY_PCFG_RESOLUTION_X_MASK	0x7F
+
+/* y-axis resolution of panel in pixels */
+#define CY_PCFG_RESOLUTION_Y_MASK	0x7F
+
+/* x-axis, 0:origin is on left side of panel, 1: right */
+#define CY_PCFG_ORIGIN_X_MASK		0x80
+
+/* y-axis, 0:origin is on top side of panel, 1: bottom */
+#define CY_PCFG_ORIGIN_Y_MASK		0x80
+
+static inline int cyttsp4_adap_read(struct cyttsp4 *ts, u16 addr, int size,
+		void *buf)
+{
+	return ts->bus_ops->read(ts->dev, ts->xfer_buf, addr, size, buf);
+}
+
+static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u16 addr, int size,
+		const void *buf)
+{
+	return ts->bus_ops->write(ts->dev, ts->xfer_buf, addr, size, buf);
+}
+
+extern struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops,
+		struct device *dev, u16 irq, size_t xfer_buf_size);
+extern int cyttsp4_remove(struct cyttsp4 *ts);
+int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u16 addr,
+		u8 length, const void *values);
+int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr,
+		u8 length, void *values);
+extern const struct dev_pm_ops cyttsp4_pm_ops;
+
+#endif /* _LINUX_CYTTSP4_CORE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp4_i2c.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp4_i2c.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp4_i2c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp4_i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,90 @@
+/*
+ * cyttsp_i2c.c
+ * Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver.
+ * For use with Cypress  Txx4xx parts.
+ * Supported parts include:
+ * TMA4XX
+ * TMA1036
+ *
+ * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
+ * Copyright (C) 2013 Cypress Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
+ *
+ */
+
+#include "cyttsp4_core.h"
+
+#include <linux/i2c.h>
+#include <linux/input.h>
+
+#define CYTTSP4_I2C_DATA_SIZE	(3 * 256)
+
+static const struct cyttsp4_bus_ops cyttsp4_i2c_bus_ops = {
+	.bustype	= BUS_I2C,
+	.write		= cyttsp_i2c_write_block_data,
+	.read           = cyttsp_i2c_read_block_data,
+};
+
+static int cyttsp4_i2c_probe(struct i2c_client *client,
+				      const struct i2c_device_id *id)
+{
+	struct cyttsp4 *ts;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_err(&client->dev, "I2C functionality not Supported\n");
+		return -EIO;
+	}
+
+	ts = cyttsp4_probe(&cyttsp4_i2c_bus_ops, &client->dev, client->irq,
+			  CYTTSP4_I2C_DATA_SIZE);
+
+	if (IS_ERR(ts))
+		return PTR_ERR(ts);
+
+	return 0;
+}
+
+static int cyttsp4_i2c_remove(struct i2c_client *client)
+{
+	struct cyttsp4 *ts = i2c_get_clientdata(client);
+
+	cyttsp4_remove(ts);
+
+	return 0;
+}
+
+static const struct i2c_device_id cyttsp4_i2c_id[] = {
+	{ CYTTSP4_I2C_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, cyttsp4_i2c_id);
+
+static struct i2c_driver cyttsp4_i2c_driver = {
+	.driver = {
+		.name	= CYTTSP4_I2C_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= &cyttsp4_pm_ops,
+	},
+	.probe		= cyttsp4_i2c_probe,
+	.remove		= cyttsp4_i2c_remove,
+	.id_table	= cyttsp4_i2c_id,
+};
+
+module_i2c_driver(cyttsp4_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) I2C driver");
+MODULE_AUTHOR("Cypress");
+MODULE_ALIAS("i2c:cyttsp4");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp4_spi.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp4_spi.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp4_spi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp4_spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,203 @@
+/*
+ * Source for:
+ * Cypress TrueTouch(TM) Standard Product (TTSP) SPI touchscreen driver.
+ * For use with Cypress Txx4xx parts.
+ * Supported parts include:
+ * TMA4XX
+ * TMA1036
+ *
+ * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
+ * Copyright (C) 2013 Cypress Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
+ *
+ */
+
+#include "cyttsp4_core.h"
+
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+
+#define CY_SPI_WR_OP		0x00 /* r/~w */
+#define CY_SPI_RD_OP		0x01
+#define CY_SPI_BITS_PER_WORD	8
+#define CY_SPI_A8_BIT		0x02
+#define CY_SPI_WR_HEADER_BYTES	2
+#define CY_SPI_RD_HEADER_BYTES	1
+#define CY_SPI_CMD_BYTES	2
+#define CY_SPI_SYNC_BYTE	0
+#define CY_SPI_SYNC_ACK		0x62 /* from TRM *A protocol */
+#define CY_SPI_DATA_SIZE	(2 * 256)
+
+#define CY_SPI_DATA_BUF_SIZE	(CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
+
+static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
+			   u8 op, u16 reg, u8 *buf, int length)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct spi_message msg;
+	struct spi_transfer xfer[2];
+	u8 *wr_buf = &xfer_buf[0];
+	u8 rd_buf[CY_SPI_CMD_BYTES];
+	int retval;
+	int i;
+
+	if (length > CY_SPI_DATA_SIZE) {
+		dev_err(dev, "%s: length %d is too big.\n",
+			__func__, length);
+		return -EINVAL;
+	}
+
+	memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE);
+	memset(rd_buf, 0, CY_SPI_CMD_BYTES);
+
+	wr_buf[0] = op + (((reg >> 8) & 0x1) ? CY_SPI_A8_BIT : 0);
+	if (op == CY_SPI_WR_OP) {
+		wr_buf[1] = reg & 0xFF;
+		if (length > 0)
+			memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length);
+	}
+
+	memset(xfer, 0, sizeof(xfer));
+	spi_message_init(&msg);
+
+	/*
+	  We set both TX and RX buffers because Cypress TTSP
+	  requires full duplex operation.
+	*/
+	xfer[0].tx_buf = wr_buf;
+	xfer[0].rx_buf = rd_buf;
+	switch (op) {
+	case CY_SPI_WR_OP:
+		xfer[0].len = length + CY_SPI_CMD_BYTES;
+		spi_message_add_tail(&xfer[0], &msg);
+		break;
+
+	case CY_SPI_RD_OP:
+		xfer[0].len = CY_SPI_RD_HEADER_BYTES;
+		spi_message_add_tail(&xfer[0], &msg);
+
+		xfer[1].rx_buf = buf;
+		xfer[1].len = length;
+		spi_message_add_tail(&xfer[1], &msg);
+		break;
+
+	default:
+		dev_err(dev, "%s: bad operation code=%d\n", __func__, op);
+		return -EINVAL;
+	}
+
+	retval = spi_sync(spi, &msg);
+	if (retval < 0) {
+		dev_dbg(dev, "%s: spi_sync() error %d, len=%d, op=%d\n",
+			__func__, retval, xfer[1].len, op);
+
+		/*
+		 * do not return here since was a bad ACK sequence
+		 * let the following ACK check handle any errors and
+		 * allow silent retries
+		 */
+	}
+
+	if (rd_buf[CY_SPI_SYNC_BYTE] != CY_SPI_SYNC_ACK) {
+		dev_dbg(dev, "%s: operation %d failed\n", __func__, op);
+
+		for (i = 0; i < CY_SPI_CMD_BYTES; i++)
+			dev_dbg(dev, "%s: test rd_buf[%d]:0x%02x\n",
+				__func__, i, rd_buf[i]);
+		for (i = 0; i < length; i++)
+			dev_dbg(dev, "%s: test buf[%d]:0x%02x\n",
+				__func__, i, buf[i]);
+
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf,
+				      u16 addr, u8 length, void *data)
+{
+	int rc;
+
+	rc = cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, NULL, 0);
+	if (rc)
+		return rc;
+	else
+		return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data,
+				length);
+}
+
+static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf,
+				       u16 addr, u8 length, const void *data)
+{
+	return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data,
+			length);
+}
+
+static const struct cyttsp4_bus_ops cyttsp_spi_bus_ops = {
+	.bustype	= BUS_SPI,
+	.write		= cyttsp_spi_write_block_data,
+	.read		= cyttsp_spi_read_block_data,
+};
+
+static int cyttsp4_spi_probe(struct spi_device *spi)
+{
+	struct cyttsp4 *ts;
+	int error;
+
+	/* Set up SPI*/
+	spi->bits_per_word = CY_SPI_BITS_PER_WORD;
+	spi->mode = SPI_MODE_0;
+	error = spi_setup(spi);
+	if (error < 0) {
+		dev_err(&spi->dev, "%s: SPI setup error %d\n",
+			__func__, error);
+		return error;
+	}
+
+	ts = cyttsp4_probe(&cyttsp_spi_bus_ops, &spi->dev, spi->irq,
+			  CY_SPI_DATA_BUF_SIZE);
+
+	if (IS_ERR(ts))
+		return PTR_ERR(ts);
+
+	return 0;
+}
+
+static int cyttsp4_spi_remove(struct spi_device *spi)
+{
+	struct cyttsp4 *ts = spi_get_drvdata(spi);
+	cyttsp4_remove(ts);
+
+	return 0;
+}
+
+static struct spi_driver cyttsp4_spi_driver = {
+	.driver = {
+		.name	= CYTTSP4_SPI_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= &cyttsp4_pm_ops,
+	},
+	.probe  = cyttsp4_spi_probe,
+	.remove = cyttsp4_spi_remove,
+};
+
+module_spi_driver(cyttsp4_spi_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver");
+MODULE_AUTHOR("Cypress");
+MODULE_ALIAS("spi:cyttsp4");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_core.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_core.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,7 +84,8 @@ static int ttsp_read_block_data(struct c
 	int tries;
 
 	for (tries = 0; tries < CY_NUM_RETRY; tries++) {
-		error = ts->bus_ops->read(ts, command, length, buf);
+		error = ts->bus_ops->read(ts->dev, ts->xfer_buf, command,
+				length, buf);
 		if (!error)
 			return 0;
 
@@ -101,7 +102,8 @@ static int ttsp_write_block_data(struct
 	int tries;
 
 	for (tries = 0; tries < CY_NUM_RETRY; tries++) {
-		error = ts->bus_ops->write(ts, command, length, buf);
+		error = ts->bus_ops->write(ts->dev, ts->xfer_buf, command,
+				length, buf);
 		if (!error)
 			return 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_core.h linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_core.h
--- linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_core.h	2013-08-25 20:43:22.000000000 -0400
@@ -112,9 +112,10 @@ struct cyttsp;
 
 struct cyttsp_bus_ops {
 	u16 bustype;
-	int (*write)(struct cyttsp *ts,
-		     u8 addr, u8 length, const void *values);
-	int (*read)(struct cyttsp *ts, u8 addr, u8 length, void *values);
+	int (*write)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length,
+			const void *values);
+	int (*read)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length,
+			void *values);
 };
 
 enum cyttsp_state {
@@ -144,6 +145,10 @@ struct cyttsp *cyttsp_probe(const struct
 			    struct device *dev, int irq, size_t xfer_buf_size);
 void cyttsp_remove(struct cyttsp *ts);
 
+int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u16 addr,
+		u8 length, const void *values);
+int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr,
+		u8 length, void *values);
 extern const struct dev_pm_ops cyttsp_pm_ops;
 
 #endif /* __CYTTSP_CORE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_i2c.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_i2c.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_i2c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Source for:
+ * cyttsp_i2c.c
  * Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver.
  * For use with Cypress Txx3xx parts.
  * Supported parts include:
@@ -19,11 +19,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contact Cypress Semiconductor at www.cypress.com <kev@cypress.com>
+ * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
  *
  */
 
@@ -34,47 +30,6 @@
 
 #define CY_I2C_DATA_SIZE	128
 
-static int cyttsp_i2c_read_block_data(struct cyttsp *ts,
-				      u8 addr, u8 length, void *values)
-{
-	struct i2c_client *client = to_i2c_client(ts->dev);
-	struct i2c_msg msgs[] = {
-		{
-			.addr = client->addr,
-			.flags = 0,
-			.len = 1,
-			.buf = &addr,
-		},
-		{
-			.addr = client->addr,
-			.flags = I2C_M_RD,
-			.len = length,
-			.buf = values,
-		},
-	};
-	int retval;
-
-	retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-	if (retval < 0)
-		return retval;
-
-	return retval != ARRAY_SIZE(msgs) ? -EIO : 0;
-}
-
-static int cyttsp_i2c_write_block_data(struct cyttsp *ts,
-				       u8 addr, u8 length, const void *values)
-{
-	struct i2c_client *client = to_i2c_client(ts->dev);
-	int retval;
-
-	ts->xfer_buf[0] = addr;
-	memcpy(&ts->xfer_buf[1], values, length);
-
-	retval = i2c_master_send(client, ts->xfer_buf, length + 1);
-
-	return retval < 0 ? retval : 0;
-}
-
 static const struct cyttsp_bus_ops cyttsp_i2c_bus_ops = {
 	.bustype	= BUS_I2C,
 	.write		= cyttsp_i2c_write_block_data,
@@ -98,7 +53,6 @@ static int cyttsp_i2c_probe(struct i2c_c
 		return PTR_ERR(ts);
 
 	i2c_set_clientdata(client, ts);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_i2c_common.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_i2c_common.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_i2c_common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_i2c_common.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * cyttsp_i2c_common.c
+ * Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver.
+ * For use with Cypress Txx3xx and Txx4xx parts.
+ * Supported parts include:
+ * CY8CTST341
+ * CY8CTMA340
+ * TMA4XX
+ * TMA1036
+ *
+ * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf,
+				      u16 addr, u8 length, void *values)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	u8 client_addr = client->addr | ((addr >> 8) & 0x1);
+	u8 addr_lo = addr & 0xFF;
+	struct i2c_msg msgs[] = {
+		{
+			.addr = client_addr,
+			.flags = 0,
+			.len = 1,
+			.buf = &addr_lo,
+		},
+		{
+			.addr = client_addr,
+			.flags = I2C_M_RD,
+			.len = length,
+			.buf = values,
+		},
+	};
+	int retval;
+
+	retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (retval < 0)
+		return retval;
+
+	return retval != ARRAY_SIZE(msgs) ? -EIO : 0;
+}
+EXPORT_SYMBOL_GPL(cyttsp_i2c_read_block_data);
+
+int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf,
+				       u16 addr, u8 length, const void *values)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	u8 client_addr = client->addr | ((addr >> 8) & 0x1);
+	u8 addr_lo = addr & 0xFF;
+	struct i2c_msg msgs[] = {
+		{
+			.addr = client_addr,
+			.flags = 0,
+			.len = length + 1,
+			.buf = xfer_buf,
+		},
+	};
+	int retval;
+
+	xfer_buf[0] = addr_lo;
+	memcpy(&xfer_buf[1], values, length);
+
+	retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (retval < 0)
+		return retval;
+
+	return retval != ARRAY_SIZE(msgs) ? -EIO : 0;
+}
+EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cypress");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_spi.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_spi.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/cyttsp_spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/cyttsp_spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,7 @@
  *
  * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
  * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
+ * Copyright (C) 2013 Cypress Semiconductor
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -19,11 +20,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contact Cypress Semiconductor at www.cypress.com <kev@cypress.com>
+ * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
  *
  */
 
@@ -43,19 +40,19 @@
 #define CY_SPI_DATA_BUF_SIZE	(CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
 #define CY_SPI_BITS_PER_WORD	8
 
-static int cyttsp_spi_xfer(struct cyttsp *ts,
-			   u8 op, u8 reg, u8 *buf, int length)
+static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf,
+			   u8 op, u16 reg, u8 *buf, int length)
 {
-	struct spi_device *spi = to_spi_device(ts->dev);
+	struct spi_device *spi = to_spi_device(dev);
 	struct spi_message msg;
 	struct spi_transfer xfer[2];
-	u8 *wr_buf = &ts->xfer_buf[0];
-	u8 *rd_buf = &ts->xfer_buf[CY_SPI_DATA_BUF_SIZE];
+	u8 *wr_buf = &xfer_buf[0];
+	u8 *rd_buf = &xfer_buf[CY_SPI_DATA_BUF_SIZE];
 	int retval;
 	int i;
 
 	if (length > CY_SPI_DATA_SIZE) {
-		dev_err(ts->dev, "%s: length %d is too big.\n",
+		dev_err(dev, "%s: length %d is too big.\n",
 			__func__, length);
 		return -EINVAL;
 	}
@@ -95,13 +92,13 @@ static int cyttsp_spi_xfer(struct cyttsp
 		break;
 
 	default:
-		dev_err(ts->dev, "%s: bad operation code=%d\n", __func__, op);
+		dev_err(dev, "%s: bad operation code=%d\n", __func__, op);
 		return -EINVAL;
 	}
 
 	retval = spi_sync(spi, &msg);
 	if (retval < 0) {
-		dev_dbg(ts->dev, "%s: spi_sync() error %d, len=%d, op=%d\n",
+		dev_dbg(dev, "%s: spi_sync() error %d, len=%d, op=%d\n",
 			__func__, retval, xfer[1].len, op);
 
 		/*
@@ -113,14 +110,13 @@ static int cyttsp_spi_xfer(struct cyttsp
 
 	if (rd_buf[CY_SPI_SYNC_BYTE] != CY_SPI_SYNC_ACK1 ||
 	    rd_buf[CY_SPI_SYNC_BYTE + 1] != CY_SPI_SYNC_ACK2) {
-
-		dev_dbg(ts->dev, "%s: operation %d failed\n", __func__, op);
+		dev_dbg(dev, "%s: operation %d failed\n", __func__, op);
 
 		for (i = 0; i < CY_SPI_CMD_BYTES; i++)
-			dev_dbg(ts->dev, "%s: test rd_buf[%d]:0x%02x\n",
+			dev_dbg(dev, "%s: test rd_buf[%d]:0x%02x\n",
 				__func__, i, rd_buf[i]);
 		for (i = 0; i < length; i++)
-			dev_dbg(ts->dev, "%s: test buf[%d]:0x%02x\n",
+			dev_dbg(dev, "%s: test buf[%d]:0x%02x\n",
 				__func__, i, buf[i]);
 
 		return -EIO;
@@ -129,16 +125,18 @@ static int cyttsp_spi_xfer(struct cyttsp
 	return 0;
 }
 
-static int cyttsp_spi_read_block_data(struct cyttsp *ts,
-				      u8 addr, u8 length, void *data)
+static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf,
+				      u16 addr, u8 length, void *data)
 {
-	return cyttsp_spi_xfer(ts, CY_SPI_RD_OP, addr, data, length);
+	return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data,
+			length);
 }
 
-static int cyttsp_spi_write_block_data(struct cyttsp *ts,
-				       u8 addr, u8 length, const void *data)
+static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf,
+				       u16 addr, u8 length, const void *data)
 {
-	return cyttsp_spi_xfer(ts, CY_SPI_WR_OP, addr, (void *)data, length);
+	return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data,
+			length);
 }
 
 static const struct cyttsp_bus_ops cyttsp_spi_bus_ops = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/da9052_tsi.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/da9052_tsi.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/da9052_tsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/da9052_tsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -329,8 +329,6 @@ static int  da9052_ts_remove(struct plat
 	input_unregister_device(tsi->dev);
 	kfree(tsi);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/egalax_ts.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/egalax_ts.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/egalax_ts.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/egalax_ts.c	2013-08-25 20:43:22.000000000 -0400
@@ -166,24 +166,22 @@ static int egalax_firmware_version(struc
 }
 
 static int egalax_ts_probe(struct i2c_client *client,
-				       const struct i2c_device_id *id)
+			   const struct i2c_device_id *id)
 {
 	struct egalax_ts *ts;
 	struct input_dev *input_dev;
-	int ret;
 	int error;
 
-	ts = kzalloc(sizeof(struct egalax_ts), GFP_KERNEL);
+	ts = devm_kzalloc(&client->dev, sizeof(struct egalax_ts), GFP_KERNEL);
 	if (!ts) {
 		dev_err(&client->dev, "Failed to allocate memory\n");
 		return -ENOMEM;
 	}
 
-	input_dev = input_allocate_device();
+	input_dev = devm_input_allocate_device(&client->dev);
 	if (!input_dev) {
 		dev_err(&client->dev, "Failed to allocate memory\n");
-		error = -ENOMEM;
-		goto err_free_ts;
+		return -ENOMEM;
 	}
 
 	ts->client = client;
@@ -193,19 +191,17 @@ static int egalax_ts_probe(struct i2c_cl
 	error = egalax_wake_up_device(client);
 	if (error) {
 		dev_err(&client->dev, "Failed to wake up the controller\n");
-		goto err_free_dev;
+		return error;
 	}
 
-	ret = egalax_firmware_version(client);
-	if (ret < 0) {
+	error = egalax_firmware_version(client);
+	if (error < 0) {
 		dev_err(&client->dev, "Failed to read firmware version\n");
-		error = -EIO;
-		goto err_free_dev;
+		return error;
 	}
 
 	input_dev->name = "EETI eGalax Touch Screen";
 	input_dev->id.bustype = BUS_I2C;
-	input_dev->dev.parent = &client->dev;
 
 	__set_bit(EV_ABS, input_dev->evbit);
 	__set_bit(EV_KEY, input_dev->evbit);
@@ -221,41 +217,21 @@ static int egalax_ts_probe(struct i2c_cl
 
 	input_set_drvdata(input_dev, ts);
 
-	error = request_threaded_irq(client->irq, NULL, egalax_ts_interrupt,
-				     IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-				     "egalax_ts", ts);
+	error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+					  egalax_ts_interrupt,
+					  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					  "egalax_ts", ts);
 	if (error < 0) {
 		dev_err(&client->dev, "Failed to register interrupt\n");
-		goto err_free_dev;
+		return error;
 	}
 
 	error = input_register_device(ts->input_dev);
 	if (error)
-		goto err_free_irq;
+		return error;
 
 	i2c_set_clientdata(client, ts);
 	return 0;
-
-err_free_irq:
-	free_irq(client->irq, ts);
-err_free_dev:
-	input_free_device(input_dev);
-err_free_ts:
-	kfree(ts);
-
-	return error;
-}
-
-static int egalax_ts_remove(struct i2c_client *client)
-{
-	struct egalax_ts *ts = i2c_get_clientdata(client);
-
-	free_irq(client->irq, ts);
-
-	input_unregister_device(ts->input_dev);
-	kfree(ts);
-
-	return 0;
 }
 
 static const struct i2c_device_id egalax_ts_id[] = {
@@ -301,7 +277,6 @@ static struct i2c_driver egalax_ts_drive
 	},
 	.id_table	= egalax_ts_id,
 	.probe		= egalax_ts_probe,
-	.remove		= egalax_ts_remove,
 };
 
 module_i2c_driver(egalax_ts_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/intel-mid-touch.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/intel-mid-touch.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/intel-mid-touch.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/intel-mid-touch.c	2013-08-25 20:43:22.000000000 -0400
@@ -651,8 +651,6 @@ static int mrstouch_remove(struct platfo
 	input_unregister_device(tsdev->input);
 	kfree(tsdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/jornada720_ts.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/jornada720_ts.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/jornada720_ts.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/jornada720_ts.c	2013-08-25 20:43:22.000000000 -0400
@@ -145,7 +145,6 @@ static int jornada720_ts_probe(struct pl
  fail2:
 	free_irq(IRQ_GPIO9, pdev);
  fail1:
-	platform_set_drvdata(pdev, NULL);
 	input_free_device(input_dev);
 	kfree(jornada_ts);
 	return error;
@@ -156,7 +155,6 @@ static int jornada720_ts_remove(struct p
 	struct jornada_ts *jornada_ts = platform_get_drvdata(pdev);
 
 	free_irq(IRQ_GPIO9, pdev);
-	platform_set_drvdata(pdev, NULL);
 	input_unregister_device(jornada_ts->dev);
 	kfree(jornada_ts);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/Kconfig linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/Kconfig
--- linux-libre-3.10-gnu/drivers/input/touchscreen/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -167,6 +167,36 @@ config TOUCHSCREEN_CYTTSP_SPI
 	  To compile this driver as a module, choose M here: the
 	  module will be called cyttsp_spi.
 
+config TOUCHSCREEN_CYTTSP4_CORE
+	tristate "Cypress TrueTouch Gen4 Touchscreen Driver"
+	help
+	  Core driver for Cypress TrueTouch(tm) Standard Product
+	  Generation4 touchscreen controllers.
+
+	  Say Y here if you have a Cypress Gen4 touchscreen.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here.
+
+config TOUCHSCREEN_CYTTSP4_I2C
+	tristate "support I2C bus connection"
+	depends on TOUCHSCREEN_CYTTSP4_CORE && I2C
+	help
+	  Say Y here if the touchscreen is connected via I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cyttsp4_i2c.
+
+config TOUCHSCREEN_CYTTSP4_SPI
+	tristate "support SPI bus connection"
+	depends on TOUCHSCREEN_CYTTSP4_CORE && SPI_MASTER
+	help
+	  Say Y here if the touchscreen is connected via SPI bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cyttsp4_spi.
+
 config TOUCHSCREEN_DA9034
 	tristate "Touchscreen support for Dialog Semiconductor DA9034"
 	depends on PMIC_DA903X
@@ -879,6 +909,7 @@ config TOUCHSCREEN_STMPE
 config TOUCHSCREEN_TPS6507X
 	tristate "TPS6507x based touchscreens"
 	depends on I2C
+	select INPUT_POLLDEV
 	help
 	  Say Y here if you have a TPS6507x based touchscreen
 	  controller.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/Makefile linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/Makefile
--- linux-libre-3.10-gnu/drivers/input/touchscreen/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -18,8 +18,11 @@ obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR)	+=
 obj-$(CONFIG_TOUCHSCREEN_BU21013)	+= bu21013_ts.o
 obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110)	+= cy8ctmg110_ts.o
 obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE)	+= cyttsp_core.o
-obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C)	+= cyttsp_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C)	+= cyttsp_i2c.o cyttsp_i2c_common.o
 obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI)	+= cyttsp_spi.o
+obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_CORE)	+= cyttsp4_core.o
+obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_I2C)	+= cyttsp4_i2c.o cyttsp_i2c_common.o
+obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_SPI)	+= cyttsp4_spi.o
 obj-$(CONFIG_TOUCHSCREEN_DA9034)	+= da9034-ts.o
 obj-$(CONFIG_TOUCHSCREEN_DA9052)	+= da9052_tsi.o
 obj-$(CONFIG_TOUCHSCREEN_DYNAPRO)	+= dynapro.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/mc13783_ts.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/mc13783_ts.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/mc13783_ts.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/mc13783_ts.c	2013-08-25 20:43:22.000000000 -0400
@@ -233,8 +233,6 @@ static int mc13783_ts_remove(struct plat
 {
 	struct mc13783_ts_priv *priv = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	destroy_workqueue(priv->workq);
 	input_unregister_device(priv->idev);
 	kfree(priv);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/ti_am335x_tsc.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/ti_am335x_tsc.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/ti_am335x_tsc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/ti_am335x_tsc.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,8 +24,9 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
-#include <linux/input/ti_am335x_tsc.h>
 #include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <linux/mfd/ti_am335x_tscadc.h>
 
@@ -33,6 +34,13 @@
 #define SEQ_SETTLE		275
 #define MAX_12BIT		((1 << 12) - 1)
 
+static const int config_pins[] = {
+	STEPCONFIG_XPP,
+	STEPCONFIG_XNN,
+	STEPCONFIG_YPP,
+	STEPCONFIG_YNN,
+};
+
 struct titsc {
 	struct input_dev	*input;
 	struct ti_tscadc_dev	*mfd_tscadc;
@@ -40,7 +48,10 @@ struct titsc {
 	unsigned int		wires;
 	unsigned int		x_plate_resistance;
 	bool			pen_down;
-	int			steps_to_configure;
+	int			coordinate_readouts;
+	u32			config_inp[4];
+	u32			bit_xp, bit_xn, bit_yp, bit_yn;
+	u32			inp_xp, inp_xn, inp_yp, inp_yn;
 };
 
 static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
@@ -54,92 +65,153 @@ static void titsc_writel(struct titsc *t
 	writel(val, tsc->mfd_tscadc->tscadc_base + reg);
 }
 
+static int titsc_config_wires(struct titsc *ts_dev)
+{
+	u32 analog_line[4];
+	u32 wire_order[4];
+	int i, bit_cfg;
+
+	for (i = 0; i < 4; i++) {
+		/*
+		 * Get the order in which TSC wires are attached
+		 * w.r.t. each of the analog input lines on the EVM.
+		 */
+		analog_line[i] = (ts_dev->config_inp[i] & 0xF0) >> 4;
+		wire_order[i] = ts_dev->config_inp[i] & 0x0F;
+		if (WARN_ON(analog_line[i] > 7))
+			return -EINVAL;
+		if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins)))
+			return -EINVAL;
+	}
+
+	for (i = 0; i < 4; i++) {
+		int an_line;
+		int wi_order;
+
+		an_line = analog_line[i];
+		wi_order = wire_order[i];
+		bit_cfg = config_pins[wi_order];
+		if (bit_cfg == 0)
+			return -EINVAL;
+		switch (wi_order) {
+		case 0:
+			ts_dev->bit_xp = bit_cfg;
+			ts_dev->inp_xp = an_line;
+			break;
+
+		case 1:
+			ts_dev->bit_xn = bit_cfg;
+			ts_dev->inp_xn = an_line;
+			break;
+
+		case 2:
+			ts_dev->bit_yp = bit_cfg;
+			ts_dev->inp_yp = an_line;
+			break;
+		case 3:
+			ts_dev->bit_yn = bit_cfg;
+			ts_dev->inp_yn = an_line;
+			break;
+		}
+	}
+	return 0;
+}
+
 static void titsc_step_config(struct titsc *ts_dev)
 {
 	unsigned int	config;
-	int i, total_steps;
-
-	/* Configure the Step registers */
-	total_steps = 2 * ts_dev->steps_to_configure;
+	int i;
+	int end_step;
+	u32 stepenable;
 
 	config = STEPCONFIG_MODE_HWSYNC |
-			STEPCONFIG_AVG_16 | STEPCONFIG_XPP;
+			STEPCONFIG_AVG_16 | ts_dev->bit_xp;
 	switch (ts_dev->wires) {
 	case 4:
-		config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN;
+		config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn;
 		break;
 	case 5:
-		config |= STEPCONFIG_YNN |
-				STEPCONFIG_INP_AN4 | STEPCONFIG_XNN |
-				STEPCONFIG_YPP;
+		config |= ts_dev->bit_yn |
+				STEPCONFIG_INP_AN4 | ts_dev->bit_xn |
+				ts_dev->bit_yp;
 		break;
 	case 8:
-		config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN;
+		config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn;
 		break;
 	}
 
-	for (i = 1; i <= ts_dev->steps_to_configure; i++) {
+	/* 1 … coordinate_readouts is for X */
+	end_step = ts_dev->coordinate_readouts;
+	for (i = 0; i < end_step; i++) {
 		titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
 		titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
 	}
 
 	config = 0;
 	config = STEPCONFIG_MODE_HWSYNC |
-			STEPCONFIG_AVG_16 | STEPCONFIG_YNN |
-			STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1;
+			STEPCONFIG_AVG_16 | ts_dev->bit_yn |
+			STEPCONFIG_INM_ADCREFM;
 	switch (ts_dev->wires) {
 	case 4:
-		config |= STEPCONFIG_YPP;
+		config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
 		break;
 	case 5:
-		config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 |
-				STEPCONFIG_XNP | STEPCONFIG_YPN;
+		config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 |
+				ts_dev->bit_xn | ts_dev->bit_yp;
 		break;
 	case 8:
-		config |= STEPCONFIG_YPP;
+		config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
 		break;
 	}
 
-	for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) {
+	/* coordinate_readouts … coordinate_readouts * 2 is for Y */
+	end_step = ts_dev->coordinate_readouts * 2;
+	for (i = ts_dev->coordinate_readouts; i < end_step; i++) {
 		titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
 		titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
 	}
 
-	config = 0;
 	/* Charge step configuration */
-	config = STEPCONFIG_XPP | STEPCONFIG_YNN |
+	config = ts_dev->bit_xp | ts_dev->bit_yn |
 			STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR |
-			STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1;
+			STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp);
 
 	titsc_writel(ts_dev, REG_CHARGECONFIG, config);
 	titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
 
-	config = 0;
-	/* Configure to calculate pressure */
+	/* coordinate_readouts * 2 … coordinate_readouts * 2 + 2 is for Z */
 	config = STEPCONFIG_MODE_HWSYNC |
-			STEPCONFIG_AVG_16 | STEPCONFIG_YPP |
-			STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM;
-	titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config);
-	titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1),
+			STEPCONFIG_AVG_16 | ts_dev->bit_yp |
+			ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
+			STEPCONFIG_INP(ts_dev->inp_xp);
+	titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
+	titsc_writel(ts_dev, REG_STEPDELAY(end_step),
 			STEPCONFIG_OPENDLY);
 
-	config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1;
-	titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config);
-	titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
+	end_step++;
+	config |= STEPCONFIG_INP(ts_dev->inp_yn);
+	titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
+	titsc_writel(ts_dev, REG_STEPDELAY(end_step),
 			STEPCONFIG_OPENDLY);
 
-	titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
+	/* The steps1 … end and bit 0 for TS_Charge */
+	stepenable = (1 << (end_step + 2)) - 1;
+	am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable);
 }
 
 static void titsc_read_coordinates(struct titsc *ts_dev,
-				    unsigned int *x, unsigned int *y)
+		u32 *x, u32 *y, u32 *z1, u32 *z2)
 {
 	unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT);
 	unsigned int prev_val_x = ~0, prev_val_y = ~0;
 	unsigned int prev_diff_x = ~0, prev_diff_y = ~0;
 	unsigned int read, diff;
 	unsigned int i, channel;
+	unsigned int creads = ts_dev->coordinate_readouts;
 
+	*z1 = *z2 = 0;
+	if (fifocount % (creads * 2 + 2))
+		fifocount -= fifocount % (creads * 2 + 2);
 	/*
 	 * Delta filter is used to remove large variations in sampled
 	 * values from ADC. The filter tries to predict where the next
@@ -148,32 +220,32 @@ static void titsc_read_coordinates(struc
 	 * algorithm compares the difference with that of a present value,
 	 * if true the value is reported to the sub system.
 	 */
-	for (i = 0; i < fifocount - 1; i++) {
+	for (i = 0; i < fifocount; i++) {
 		read = titsc_readl(ts_dev, REG_FIFO0);
-		channel = read & 0xf0000;
-		channel = channel >> 0x10;
-		if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) {
-			read &= 0xfff;
+
+		channel = (read & 0xf0000) >> 16;
+		read &= 0xfff;
+		if (channel < creads) {
 			diff = abs(read - prev_val_x);
 			if (diff < prev_diff_x) {
 				prev_diff_x = diff;
 				*x = read;
 			}
 			prev_val_x = read;
-		}
 
-		read = titsc_readl(ts_dev, REG_FIFO1);
-		channel = read & 0xf0000;
-		channel = channel >> 0x10;
-		if ((channel >= ts_dev->steps_to_configure) &&
-			(channel < (2 * ts_dev->steps_to_configure - 1))) {
-			read &= 0xfff;
+		} else if (channel < creads * 2) {
 			diff = abs(read - prev_val_y);
 			if (diff < prev_diff_y) {
 				prev_diff_y = diff;
 				*y = read;
 			}
 			prev_val_y = read;
+
+		} else if (channel < creads * 2 + 1) {
+			*z1 = read;
+
+		} else if (channel < creads * 2 + 2) {
+			*z2 = read;
 		}
 	}
 }
@@ -186,23 +258,11 @@ static irqreturn_t titsc_irq(int irq, vo
 	unsigned int x = 0, y = 0;
 	unsigned int z1, z2, z;
 	unsigned int fsm;
-	unsigned int fifo1count, fifo0count;
-	int i;
 
 	status = titsc_readl(ts_dev, REG_IRQSTATUS);
 	if (status & IRQENB_FIFO0THRES) {
-		titsc_read_coordinates(ts_dev, &x, &y);
-
-		z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff;
-		z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff;
-
-		fifo1count = titsc_readl(ts_dev, REG_FIFO1CNT);
-		for (i = 0; i < fifo1count; i++)
-			titsc_readl(ts_dev, REG_FIFO1);
 
-		fifo0count = titsc_readl(ts_dev, REG_FIFO0CNT);
-		for (i = 0; i < fifo0count; i++)
-			titsc_readl(ts_dev, REG_FIFO0);
+		titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
 
 		if (ts_dev->pen_down && z1 != 0 && z2 != 0) {
 			/*
@@ -210,10 +270,10 @@ static irqreturn_t titsc_irq(int irq, vo
 			 * Resistance(touch) = x plate resistance *
 			 * x postion/4096 * ((z2 / z1) - 1)
 			 */
-			z = z2 - z1;
+			z = z1 - z2;
 			z *= x;
 			z *= ts_dev->x_plate_resistance;
-			z /= z1;
+			z /= z2;
 			z = (z + 2047) >> 12;
 
 			if (z <= MAX_12BIT) {
@@ -248,10 +308,53 @@ static irqreturn_t titsc_irq(int irq, vo
 		irqclr |= IRQENB_PENUP;
 	}
 
-	titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
+	if (status & IRQENB_HW_PEN) {
 
-	titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
-	return IRQ_HANDLED;
+		titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00);
+		titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
+	}
+
+	if (irqclr) {
+		titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
+		am335x_tsc_se_update(ts_dev->mfd_tscadc);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+
+static int titsc_parse_dt(struct platform_device *pdev,
+					struct titsc *ts_dev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	int err;
+
+	if (!node)
+		return -EINVAL;
+
+	err = of_property_read_u32(node, "ti,wires", &ts_dev->wires);
+	if (err < 0)
+		return err;
+	switch (ts_dev->wires) {
+	case 4:
+	case 5:
+	case 8:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	err = of_property_read_u32(node, "ti,x-plate-resistance",
+			&ts_dev->x_plate_resistance);
+	if (err < 0)
+		return err;
+
+	err = of_property_read_u32(node, "ti,coordiante-readouts",
+			&ts_dev->coordinate_readouts);
+	if (err < 0)
+		return err;
+
+	return of_property_read_u32_array(node, "ti,wire-config",
+			ts_dev->config_inp, ARRAY_SIZE(ts_dev->config_inp));
 }
 
 /*
@@ -262,17 +365,9 @@ static int titsc_probe(struct platform_d
 {
 	struct titsc *ts_dev;
 	struct input_dev *input_dev;
-	struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
-	struct mfd_tscadc_board	*pdata;
+	struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev);
 	int err;
 
-	pdata = tscadc_dev->dev->platform_data;
-
-	if (!pdata) {
-		dev_err(&pdev->dev, "Could not find platform data\n");
-		return -EINVAL;
-	}
-
 	/* Allocate memory for device */
 	ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL);
 	input_dev = input_allocate_device();
@@ -286,9 +381,12 @@ static int titsc_probe(struct platform_d
 	ts_dev->mfd_tscadc = tscadc_dev;
 	ts_dev->input = input_dev;
 	ts_dev->irq = tscadc_dev->irq;
-	ts_dev->wires = pdata->tsc_init->wires;
-	ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance;
-	ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure;
+
+	err = titsc_parse_dt(pdev, ts_dev);
+	if (err) {
+		dev_err(&pdev->dev, "Could not find valid DT data.\n");
+		goto err_free_mem;
+	}
 
 	err = request_irq(ts_dev->irq, titsc_irq,
 			  0, pdev->dev.driver->name, ts_dev);
@@ -298,8 +396,14 @@ static int titsc_probe(struct platform_d
 	}
 
 	titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
+	err = titsc_config_wires(ts_dev);
+	if (err) {
+		dev_err(&pdev->dev, "wrong i/p wire configuration\n");
+		goto err_free_irq;
+	}
 	titsc_step_config(ts_dev);
-	titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure);
+	titsc_writel(ts_dev, REG_FIFO0THR,
+			ts_dev->coordinate_readouts * 2 + 2 - 1);
 
 	input_dev->name = "ti-tsc";
 	input_dev->dev.parent = &pdev->dev;
@@ -329,14 +433,18 @@ err_free_mem:
 
 static int titsc_remove(struct platform_device *pdev)
 {
-	struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
-	struct titsc *ts_dev = tscadc_dev->tsc;
+	struct titsc *ts_dev = platform_get_drvdata(pdev);
+	u32 steps;
 
 	free_irq(ts_dev->irq, ts_dev);
 
+	/* total steps followed by the enable mask */
+	steps = 2 * ts_dev->coordinate_readouts + 2;
+	steps = (1 << steps) - 1;
+	am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps);
+
 	input_unregister_device(ts_dev->input);
 
-	platform_set_drvdata(pdev, NULL);
 	kfree(ts_dev);
 	return 0;
 }
@@ -344,10 +452,11 @@ static int titsc_remove(struct platform_
 #ifdef CONFIG_PM
 static int titsc_suspend(struct device *dev)
 {
-	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
-	struct titsc *ts_dev = tscadc_dev->tsc;
+	struct titsc *ts_dev = dev_get_drvdata(dev);
+	struct ti_tscadc_dev *tscadc_dev;
 	unsigned int idle;
 
+	tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
 	if (device_may_wakeup(tscadc_dev->dev)) {
 		idle = titsc_readl(ts_dev, REG_IRQENABLE);
 		titsc_writel(ts_dev, REG_IRQENABLE,
@@ -359,9 +468,10 @@ static int titsc_suspend(struct device *
 
 static int titsc_resume(struct device *dev)
 {
-	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
-	struct titsc *ts_dev = tscadc_dev->tsc;
+	struct titsc *ts_dev = dev_get_drvdata(dev);
+	struct ti_tscadc_dev *tscadc_dev;
 
+	tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
 	if (device_may_wakeup(tscadc_dev->dev)) {
 		titsc_writel(ts_dev, REG_IRQWAKEUP,
 				0x00);
@@ -369,7 +479,7 @@ static int titsc_resume(struct device *d
 	}
 	titsc_step_config(ts_dev);
 	titsc_writel(ts_dev, REG_FIFO0THR,
-			ts_dev->steps_to_configure);
+			ts_dev->coordinate_readouts * 2 + 2 - 1);
 	return 0;
 }
 
@@ -382,13 +492,20 @@ static const struct dev_pm_ops titsc_pm_
 #define TITSC_PM_OPS NULL
 #endif
 
+static const struct of_device_id ti_tsc_dt_ids[] = {
+	{ .compatible = "ti,am3359-tsc", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ti_tsc_dt_ids);
+
 static struct platform_driver ti_tsc_driver = {
 	.probe	= titsc_probe,
 	.remove	= titsc_remove,
 	.driver	= {
-		.name   = "tsc",
+		.name   = "TI-am335x-tsc",
 		.owner	= THIS_MODULE,
 		.pm	= TITSC_PM_OPS,
+		.of_match_table = of_match_ptr(ti_tsc_dt_ids),
 	},
 };
 module_platform_driver(ti_tsc_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/tnetv107x-ts.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/tnetv107x-ts.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/tnetv107x-ts.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/tnetv107x-ts.c	2013-08-25 20:43:22.000000000 -0400
@@ -351,7 +351,6 @@ error_clk:
 error_map:
 	release_mem_region(ts->res->start, resource_size(ts->res));
 error_res:
-	platform_set_drvdata(pdev, NULL);
 	kfree(ts);
 
 	return error;
@@ -366,7 +365,6 @@ static int tsc_remove(struct platform_de
 	clk_put(ts->clk);
 	iounmap(ts->regs);
 	release_mem_region(ts->res->start, resource_size(ts->res));
-	platform_set_drvdata(pdev, NULL);
 	kfree(ts);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/tps6507x-ts.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/tps6507x-ts.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/tps6507x-ts.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/tps6507x-ts.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/workqueue.h>
 #include <linux/slab.h>
 #include <linux/input.h>
+#include <linux/input-polldev.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/tps6507x.h>
 #include <linux/input/tps6507x-ts.h>
@@ -38,20 +39,13 @@ struct ts_event {
 };
 
 struct tps6507x_ts {
-	struct input_dev	*input_dev;
 	struct device		*dev;
+	struct input_polled_dev	*poll_dev;
+	struct tps6507x_dev	*mfd;
 	char			phys[32];
-	struct delayed_work	work;
-	unsigned		polling;	/* polling is active */
 	struct ts_event		tc;
-	struct tps6507x_dev	*mfd;
-	u16			model;
-	unsigned		pendown;
-	int			irq;
-	void			(*clear_penirq)(void);
-	unsigned long		poll_period;	/* ms */
 	u16			min_pressure;
-	int			vref;		/* non-zero to leave vref on */
+	bool			pendown;
 };
 
 static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data)
@@ -161,18 +155,15 @@ static s32 tps6507x_adc_standby(struct t
 	return ret;
 }
 
-static void tps6507x_ts_handler(struct work_struct *work)
+static void tps6507x_ts_poll(struct input_polled_dev *poll_dev)
 {
-	struct tps6507x_ts *tsc =  container_of(work,
-				struct tps6507x_ts, work.work);
-	struct input_dev *input_dev = tsc->input_dev;
-	int pendown;
-	int schd;
-	int poll = 0;
+	struct tps6507x_ts *tsc = poll_dev->private;
+	struct input_dev *input_dev = poll_dev->input;
+	bool pendown;
 	s32 ret;
 
-	ret =  tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE,
-				       &tsc->tc.pressure);
+	ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE,
+				      &tsc->tc.pressure);
 	if (ret)
 		goto done;
 
@@ -183,7 +174,7 @@ static void tps6507x_ts_handler(struct w
 		input_report_key(input_dev, BTN_TOUCH, 0);
 		input_report_abs(input_dev, ABS_PRESSURE, 0);
 		input_sync(input_dev);
-		tsc->pendown = 0;
+		tsc->pendown = false;
 	}
 
 	if (pendown) {
@@ -208,76 +199,69 @@ static void tps6507x_ts_handler(struct w
 		input_report_abs(input_dev, ABS_Y, tsc->tc.y);
 		input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure);
 		input_sync(input_dev);
-		tsc->pendown = 1;
-		poll = 1;
+		tsc->pendown = true;
 	}
 
 done:
-	/* always poll if not using interrupts */
-	poll = 1;
-
-	if (poll) {
-		schd = schedule_delayed_work(&tsc->work,
-					msecs_to_jiffies(tsc->poll_period));
-		if (schd)
-			tsc->polling = 1;
-		else {
-			tsc->polling = 0;
-			dev_err(tsc->dev, "re-schedule failed");
-		}
-	} else
-		tsc->polling = 0;
-
-	ret = tps6507x_adc_standby(tsc);
+	tps6507x_adc_standby(tsc);
 }
 
 static int tps6507x_ts_probe(struct platform_device *pdev)
 {
-	int error;
-	struct tps6507x_ts *tsc;
 	struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
-	struct touchscreen_init_data *init_data;
+	const struct tps6507x_board *tps_board;
+	const struct touchscreen_init_data *init_data;
+	struct tps6507x_ts *tsc;
+	struct input_polled_dev *poll_dev;
 	struct input_dev *input_dev;
-	struct tps6507x_board *tps_board;
-	int schd;
+	int error;
 
-	/**
+	/*
 	 * tps_board points to pmic related constants
 	 * coming from the board-evm file.
 	 */
-
-	tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data;
-
+	tps_board = dev_get_platdata(tps6507x_dev->dev);
 	if (!tps_board) {
 		dev_err(tps6507x_dev->dev,
 			"Could not find tps6507x platform data\n");
-		return -EIO;
+		return -ENODEV;
 	}
 
-	/**
+	/*
 	 * init_data points to array of regulator_init structures
 	 * coming from the board-evm file.
 	 */
-
 	init_data = tps_board->tps6507x_ts_init_data;
 
 	tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL);
 	if (!tsc) {
 		dev_err(tps6507x_dev->dev, "failed to allocate driver data\n");
-		error = -ENOMEM;
-		goto err0;
+		return -ENOMEM;
 	}
 
-	tps6507x_dev->ts = tsc;
 	tsc->mfd = tps6507x_dev;
 	tsc->dev = tps6507x_dev->dev;
-	input_dev = input_allocate_device();
-	if (!input_dev) {
-		dev_err(tsc->dev, "Failed to allocate input device.\n");
+	tsc->min_pressure = init_data ?
+			init_data->min_pressure : TPS_DEFAULT_MIN_PRESSURE;
+
+	snprintf(tsc->phys, sizeof(tsc->phys),
+		 "%s/input0", dev_name(tsc->dev));
+
+	poll_dev = input_allocate_polled_device();
+	if (!poll_dev) {
+		dev_err(tsc->dev, "Failed to allocate polled input device.\n");
 		error = -ENOMEM;
-		goto err1;
+		goto err_free_mem;
 	}
 
+	tsc->poll_dev = poll_dev;
+
+	poll_dev->private = tsc;
+	poll_dev->poll = tps6507x_ts_poll;
+	poll_dev->poll_interval = init_data ?
+			init_data->poll_period : TSC_DEFAULT_POLL_PERIOD;
+
+	input_dev = poll_dev->input;
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
@@ -286,76 +270,42 @@ static int tps6507x_ts_probe(struct plat
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0);
 
 	input_dev->name = "TPS6507x Touchscreen";
-	input_dev->id.bustype = BUS_I2C;
-	input_dev->dev.parent = tsc->dev;
-
-	snprintf(tsc->phys, sizeof(tsc->phys),
-		 "%s/input0", dev_name(tsc->dev));
 	input_dev->phys = tsc->phys;
-
-	dev_dbg(tsc->dev, "device: %s\n", input_dev->phys);
-
-	input_set_drvdata(input_dev, tsc);
-
-	tsc->input_dev = input_dev;
-
-	INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler);
-
+	input_dev->dev.parent = tsc->dev;
+	input_dev->id.bustype = BUS_I2C;
 	if (init_data) {
-		tsc->poll_period = init_data->poll_period;
-		tsc->vref = init_data->vref;
-		tsc->min_pressure = init_data->min_pressure;
 		input_dev->id.vendor = init_data->vendor;
 		input_dev->id.product = init_data->product;
 		input_dev->id.version = init_data->version;
-	} else {
-		tsc->poll_period = TSC_DEFAULT_POLL_PERIOD;
-		tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE;
 	}
 
 	error = tps6507x_adc_standby(tsc);
 	if (error)
-		goto err2;
+		goto err_free_polled_dev;
 
-	error = input_register_device(input_dev);
+	error = input_register_polled_device(poll_dev);
 	if (error)
-		goto err2;
-
-	schd = schedule_delayed_work(&tsc->work,
-				     msecs_to_jiffies(tsc->poll_period));
+		goto err_free_polled_dev;
 
-	if (schd)
-		tsc->polling = 1;
-	else {
-		tsc->polling = 0;
-		dev_err(tsc->dev, "schedule failed");
-		goto err2;
-	 }
-	platform_set_drvdata(pdev, tps6507x_dev);
+	platform_set_drvdata(pdev, tsc);
 
 	return 0;
 
-err2:
-	cancel_delayed_work_sync(&tsc->work);
-	input_free_device(input_dev);
-err1:
+err_free_polled_dev:
+	input_free_polled_device(poll_dev);
+err_free_mem:
 	kfree(tsc);
-	tps6507x_dev->ts = NULL;
-err0:
 	return error;
 }
 
 static int tps6507x_ts_remove(struct platform_device *pdev)
 {
-	struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
-	struct tps6507x_ts *tsc = tps6507x_dev->ts;
-	struct input_dev *input_dev = tsc->input_dev;
-
-	cancel_delayed_work_sync(&tsc->work);
+	struct tps6507x_ts *tsc = platform_get_drvdata(pdev);
+	struct input_polled_dev *poll_dev = tsc->poll_dev;
 
-	input_unregister_device(input_dev);
+	input_unregister_polled_device(poll_dev);
+	input_free_polled_device(poll_dev);
 
-	tps6507x_dev->ts = NULL;
 	kfree(tsc);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/w90p910_ts.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/w90p910_ts.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/w90p910_ts.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/w90p910_ts.c	2013-08-25 20:43:22.000000000 -0400
@@ -318,8 +318,6 @@ static int w90x900ts_remove(struct platf
 	input_unregister_device(w90p910_ts->input);
 	kfree(w90p910_ts);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/input/touchscreen/wacom_i2c.c linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/wacom_i2c.c
--- linux-libre-3.10-gnu/drivers/input/touchscreen/wacom_i2c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/input/touchscreen/wacom_i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Wacom Penabled Driver for I2C
  *
- * Copyright (c) 2011 Tatsunosuke Tobita, Wacom.
+ * Copyright (c) 2011 - 2013 Tatsunosuke Tobita, Wacom.
  * <tobita.tatsunosuke@wacom.co.jp>
  *
  * This program is free software; you can redistribute it
@@ -27,7 +27,6 @@
 #define WACOM_CMD_THROW0	0x05
 #define WACOM_CMD_THROW1	0x00
 #define WACOM_QUERY_SIZE	19
-#define WACOM_RETRY_CNT		100
 
 struct wacom_features {
 	int x_max;
@@ -40,6 +39,8 @@ struct wacom_i2c {
 	struct i2c_client *client;
 	struct input_dev *input;
 	u8 data[WACOM_QUERY_SIZE];
+	bool prox;
+	int tool;
 };
 
 static int wacom_query_device(struct i2c_client *client,
@@ -112,9 +113,14 @@ static irqreturn_t wacom_i2c_irq(int irq
 	y = le16_to_cpup((__le16 *)&data[6]);
 	pressure = le16_to_cpup((__le16 *)&data[8]);
 
+	if (!wac_i2c->prox)
+		wac_i2c->tool = (data[3] & 0x0c) ?
+			BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+
+	wac_i2c->prox = data[3] & 0x20;
+
 	input_report_key(input, BTN_TOUCH, tsw || ers);
-	input_report_key(input, BTN_TOOL_PEN, tsw);
-	input_report_key(input, BTN_TOOL_RUBBER, ers);
+	input_report_key(input, wac_i2c->tool, wac_i2c->prox);
 	input_report_key(input, BTN_STYLUS, f1);
 	input_report_key(input, BTN_STYLUS2, f2);
 	input_report_abs(input, ABS_X, x);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/amd_iommu.c linux-libre-3.11-rc7-gnu/drivers/iommu/amd_iommu.c
--- linux-libre-3.10-gnu/drivers/iommu/amd_iommu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/amd_iommu.c	2013-08-25 20:43:22.000000000 -0400
@@ -287,14 +287,27 @@ static struct pci_dev *get_isolation_roo
 
 	/*
 	 * If it's a multifunction device that does not support our
-	 * required ACS flags, add to the same group as function 0.
+	 * required ACS flags, add to the same group as lowest numbered
+	 * function that also does not suport the required ACS flags.
 	 */
 	if (dma_pdev->multifunction &&
-	    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS))
-		swap_pci_ref(&dma_pdev,
-			     pci_get_slot(dma_pdev->bus,
-					  PCI_DEVFN(PCI_SLOT(dma_pdev->devfn),
-					  0)));
+	    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
+		u8 i, slot = PCI_SLOT(dma_pdev->devfn);
+
+		for (i = 0; i < 8; i++) {
+			struct pci_dev *tmp;
+
+			tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
+			if (!tmp)
+				continue;
+
+			if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
+				swap_pci_ref(&dma_pdev, tmp);
+				break;
+			}
+			pci_dev_put(tmp);
+		}
+	}
 
 	/*
 	 * Devices on the root bus go through the iommu.  If that's not us,
@@ -1484,6 +1497,10 @@ static unsigned long iommu_unmap_page(st
 
 			/* Large PTE found which maps this address */
 			unmap_size = PTE_PAGE_SIZE(*pte);
+
+			/* Only unmap from the first pte in the page */
+			if ((unmap_size - 1) & bus_addr)
+				break;
 			count      = PAGE_SIZE_PTE_COUNT(unmap_size);
 			for (i = 0; i < count; i++)
 				pte[i] = 0ULL;
@@ -1493,7 +1510,7 @@ static unsigned long iommu_unmap_page(st
 		unmapped += unmap_size;
 	}
 
-	BUG_ON(!is_power_of_2(unmapped));
+	BUG_ON(unmapped && !is_power_of_2(unmapped));
 
 	return unmapped;
 }
@@ -1893,34 +1910,59 @@ static void domain_id_free(int id)
 	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 }
 
-static void free_pagetable(struct protection_domain *domain)
-{
-	int i, j;
-	u64 *p1, *p2, *p3;
-
-	p1 = domain->pt_root;
-
-	if (!p1)
-		return;
+#define DEFINE_FREE_PT_FN(LVL, FN)				\
+static void free_pt_##LVL (unsigned long __pt)			\
+{								\
+	unsigned long p;					\
+	u64 *pt;						\
+	int i;							\
+								\
+	pt = (u64 *)__pt;					\
+								\
+	for (i = 0; i < 512; ++i) {				\
+		if (!IOMMU_PTE_PRESENT(pt[i]))			\
+			continue;				\
+								\
+		p = (unsigned long)IOMMU_PTE_PAGE(pt[i]);	\
+		FN(p);						\
+	}							\
+	free_page((unsigned long)pt);				\
+}
 
-	for (i = 0; i < 512; ++i) {
-		if (!IOMMU_PTE_PRESENT(p1[i]))
-			continue;
+DEFINE_FREE_PT_FN(l2, free_page)
+DEFINE_FREE_PT_FN(l3, free_pt_l2)
+DEFINE_FREE_PT_FN(l4, free_pt_l3)
+DEFINE_FREE_PT_FN(l5, free_pt_l4)
+DEFINE_FREE_PT_FN(l6, free_pt_l5)
 
-		p2 = IOMMU_PTE_PAGE(p1[i]);
-		for (j = 0; j < 512; ++j) {
-			if (!IOMMU_PTE_PRESENT(p2[j]))
-				continue;
-			p3 = IOMMU_PTE_PAGE(p2[j]);
-			free_page((unsigned long)p3);
-		}
+static void free_pagetable(struct protection_domain *domain)
+{
+	unsigned long root = (unsigned long)domain->pt_root;
 
-		free_page((unsigned long)p2);
+	switch (domain->mode) {
+	case PAGE_MODE_NONE:
+		break;
+	case PAGE_MODE_1_LEVEL:
+		free_page(root);
+		break;
+	case PAGE_MODE_2_LEVEL:
+		free_pt_l2(root);
+		break;
+	case PAGE_MODE_3_LEVEL:
+		free_pt_l3(root);
+		break;
+	case PAGE_MODE_4_LEVEL:
+		free_pt_l4(root);
+		break;
+	case PAGE_MODE_5_LEVEL:
+		free_pt_l5(root);
+		break;
+	case PAGE_MODE_6_LEVEL:
+		free_pt_l6(root);
+		break;
+	default:
+		BUG();
 	}
-
-	free_page((unsigned long)p1);
-
-	domain->pt_root = NULL;
 }
 
 static void free_gcr3_tbl_level1(u64 *tbl)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/amd_iommu_init.c linux-libre-3.11-rc7-gnu/drivers/iommu/amd_iommu_init.c
--- linux-libre-3.10-gnu/drivers/iommu/amd_iommu_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/amd_iommu_init.c	2013-08-25 20:43:22.000000000 -0400
@@ -99,7 +99,7 @@ struct ivhd_header {
 	u64 mmio_phys;
 	u16 pci_seg;
 	u16 info;
-	u32 reserved;
+	u32 efr;
 } __attribute__((packed));
 
 /*
@@ -154,6 +154,7 @@ bool amd_iommu_iotlb_sup __read_mostly =
 u32 amd_iommu_max_pasids __read_mostly = ~0;
 
 bool amd_iommu_v2_present __read_mostly;
+bool amd_iommu_pc_present __read_mostly;
 
 bool amd_iommu_force_isolation __read_mostly;
 
@@ -369,23 +370,23 @@ static void iommu_disable(struct amd_iom
  * mapping and unmapping functions for the IOMMU MMIO space. Each AMD IOMMU in
  * the system has one.
  */
-static u8 __iomem * __init iommu_map_mmio_space(u64 address)
+static u8 __iomem * __init iommu_map_mmio_space(u64 address, u64 end)
 {
-	if (!request_mem_region(address, MMIO_REGION_LENGTH, "amd_iommu")) {
-		pr_err("AMD-Vi: Can not reserve memory region %llx for mmio\n",
-			address);
+	if (!request_mem_region(address, end, "amd_iommu")) {
+		pr_err("AMD-Vi: Can not reserve memory region %llx-%llx for mmio\n",
+			address, end);
 		pr_err("AMD-Vi: This is a BIOS bug. Please contact your hardware vendor\n");
 		return NULL;
 	}
 
-	return (u8 __iomem *)ioremap_nocache(address, MMIO_REGION_LENGTH);
+	return (u8 __iomem *)ioremap_nocache(address, end);
 }
 
 static void __init iommu_unmap_mmio_space(struct amd_iommu *iommu)
 {
 	if (iommu->mmio_base)
 		iounmap(iommu->mmio_base);
-	release_mem_region(iommu->mmio_phys, MMIO_REGION_LENGTH);
+	release_mem_region(iommu->mmio_phys, iommu->mmio_phys_end);
 }
 
 /****************************************************************************
@@ -1085,7 +1086,18 @@ static int __init init_iommu_one(struct
 	iommu->cap_ptr = h->cap_ptr;
 	iommu->pci_seg = h->pci_seg;
 	iommu->mmio_phys = h->mmio_phys;
-	iommu->mmio_base = iommu_map_mmio_space(h->mmio_phys);
+
+	/* Check if IVHD EFR contains proper max banks/counters */
+	if ((h->efr != 0) &&
+	    ((h->efr & (0xF << 13)) != 0) &&
+	    ((h->efr & (0x3F << 17)) != 0)) {
+		iommu->mmio_phys_end = MMIO_REG_END_OFFSET;
+	} else {
+		iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
+	}
+
+	iommu->mmio_base = iommu_map_mmio_space(iommu->mmio_phys,
+						iommu->mmio_phys_end);
 	if (!iommu->mmio_base)
 		return -ENOMEM;
 
@@ -1160,6 +1172,33 @@ static int __init init_iommu_all(struct
 	return 0;
 }
 
+
+static void init_iommu_perf_ctr(struct amd_iommu *iommu)
+{
+	u64 val = 0xabcd, val2 = 0;
+
+	if (!iommu_feature(iommu, FEATURE_PC))
+		return;
+
+	amd_iommu_pc_present = true;
+
+	/* Check if the performance counters can be written to */
+	if ((0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val, true)) ||
+	    (0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val2, false)) ||
+	    (val != val2)) {
+		pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n");
+		amd_iommu_pc_present = false;
+		return;
+	}
+
+	pr_info("AMD-Vi: IOMMU performance counters supported\n");
+
+	val = readl(iommu->mmio_base + MMIO_CNTR_CONF_OFFSET);
+	iommu->max_banks = (u8) ((val >> 12) & 0x3f);
+	iommu->max_counters = (u8) ((val >> 7) & 0xf);
+}
+
+
 static int iommu_init_pci(struct amd_iommu *iommu)
 {
 	int cap_ptr = iommu->cap_ptr;
@@ -1226,6 +1265,8 @@ static int iommu_init_pci(struct amd_iom
 	if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))
 		amd_iommu_np_cache = true;
 
+	init_iommu_perf_ctr(iommu);
+
 	if (is_rd890_iommu(iommu->dev)) {
 		int i, j;
 
@@ -1278,7 +1319,7 @@ static void print_iommu_info(void)
 				if (iommu_feature(iommu, (1ULL << i)))
 					pr_cont(" %s", feat_str[i]);
 			}
-		pr_cont("\n");
+			pr_cont("\n");
 		}
 	}
 	if (irq_remapping_enabled)
@@ -2232,3 +2273,84 @@ bool amd_iommu_v2_supported(void)
 	return amd_iommu_v2_present;
 }
 EXPORT_SYMBOL(amd_iommu_v2_supported);
+
+/****************************************************************************
+ *
+ * IOMMU EFR Performance Counter support functionality. This code allows
+ * access to the IOMMU PC functionality.
+ *
+ ****************************************************************************/
+
+u8 amd_iommu_pc_get_max_banks(u16 devid)
+{
+	struct amd_iommu *iommu;
+	u8 ret = 0;
+
+	/* locate the iommu governing the devid */
+	iommu = amd_iommu_rlookup_table[devid];
+	if (iommu)
+		ret = iommu->max_banks;
+
+	return ret;
+}
+EXPORT_SYMBOL(amd_iommu_pc_get_max_banks);
+
+bool amd_iommu_pc_supported(void)
+{
+	return amd_iommu_pc_present;
+}
+EXPORT_SYMBOL(amd_iommu_pc_supported);
+
+u8 amd_iommu_pc_get_max_counters(u16 devid)
+{
+	struct amd_iommu *iommu;
+	u8 ret = 0;
+
+	/* locate the iommu governing the devid */
+	iommu = amd_iommu_rlookup_table[devid];
+	if (iommu)
+		ret = iommu->max_counters;
+
+	return ret;
+}
+EXPORT_SYMBOL(amd_iommu_pc_get_max_counters);
+
+int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
+				    u64 *value, bool is_write)
+{
+	struct amd_iommu *iommu;
+	u32 offset;
+	u32 max_offset_lim;
+
+	/* Make sure the IOMMU PC resource is available */
+	if (!amd_iommu_pc_present)
+		return -ENODEV;
+
+	/* Locate the iommu associated with the device ID */
+	iommu = amd_iommu_rlookup_table[devid];
+
+	/* Check for valid iommu and pc register indexing */
+	if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7)))
+		return -ENODEV;
+
+	offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn);
+
+	/* Limit the offset to the hw defined mmio region aperture */
+	max_offset_lim = (u32)(((0x40|iommu->max_banks) << 12) |
+				(iommu->max_counters << 8) | 0x28);
+	if ((offset < MMIO_CNTR_REG_OFFSET) ||
+	    (offset > max_offset_lim))
+		return -EINVAL;
+
+	if (is_write) {
+		writel((u32)*value, iommu->mmio_base + offset);
+		writel((*value >> 32), iommu->mmio_base + offset + 4);
+	} else {
+		*value = readl(iommu->mmio_base + offset + 4);
+		*value <<= 32;
+		*value = readl(iommu->mmio_base + offset);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/amd_iommu_proto.h linux-libre-3.11-rc7-gnu/drivers/iommu/amd_iommu_proto.h
--- linux-libre-3.10-gnu/drivers/iommu/amd_iommu_proto.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/amd_iommu_proto.h	2013-08-25 20:43:22.000000000 -0400
@@ -56,6 +56,13 @@ extern int amd_iommu_domain_set_gcr3(str
 extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid);
 extern struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev);
 
+/* IOMMU Performance Counter functions */
+extern bool amd_iommu_pc_supported(void);
+extern u8 amd_iommu_pc_get_max_banks(u16 devid);
+extern u8 amd_iommu_pc_get_max_counters(u16 devid);
+extern int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
+				    u64 *value, bool is_write);
+
 #define PPR_SUCCESS			0x0
 #define PPR_INVALID			0x1
 #define PPR_FAILURE			0xf
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/amd_iommu_types.h linux-libre-3.11-rc7-gnu/drivers/iommu/amd_iommu_types.h
--- linux-libre-3.10-gnu/drivers/iommu/amd_iommu_types.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/amd_iommu_types.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,9 +38,6 @@
 #define ALIAS_TABLE_ENTRY_SIZE		2
 #define RLOOKUP_TABLE_ENTRY_SIZE	(sizeof(void *))
 
-/* Length of the MMIO region for the AMD IOMMU */
-#define MMIO_REGION_LENGTH       0x4000
-
 /* Capability offsets used by the driver */
 #define MMIO_CAP_HDR_OFFSET	0x00
 #define MMIO_RANGE_OFFSET	0x0c
@@ -78,6 +75,10 @@
 #define MMIO_STATUS_OFFSET	0x2020
 #define MMIO_PPR_HEAD_OFFSET	0x2030
 #define MMIO_PPR_TAIL_OFFSET	0x2038
+#define MMIO_CNTR_CONF_OFFSET	0x4000
+#define MMIO_CNTR_REG_OFFSET	0x40000
+#define MMIO_REG_END_OFFSET	0x80000
+
 
 
 /* Extended Feature Bits */
@@ -507,6 +508,10 @@ struct amd_iommu {
 
 	/* physical address of MMIO space */
 	u64 mmio_phys;
+
+	/* physical end address of MMIO space */
+	u64 mmio_phys_end;
+
 	/* virtual address of MMIO space */
 	u8 __iomem *mmio_base;
 
@@ -584,6 +589,10 @@ struct amd_iommu {
 
 	/* The l2 indirect registers */
 	u32 stored_l2[0x83];
+
+	/* The maximum PC banks and counters/bank (PCSup=1) */
+	u8 max_banks;
+	u8 max_counters;
 };
 
 struct devid_map {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/arm-smmu.c linux-libre-3.11-rc7-gnu/drivers/iommu/arm-smmu.c
--- linux-libre-3.10-gnu/drivers/iommu/arm-smmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/arm-smmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1969 @@
+/*
+ * IOMMU API for ARM architected SMMU implementations.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2013 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ *
+ * This driver currently supports:
+ *	- SMMUv1 and v2 implementations
+ *	- Stream-matching and stream-indexing
+ *	- v7/v8 long-descriptor format
+ *	- Non-secure access to the SMMU
+ *	- 4k and 64k pages, with contiguous pte hints.
+ *	- Up to 39-bit addressing
+ *	- Context fault reporting
+ */
+
+#define pr_fmt(fmt) "arm-smmu: " fmt
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iommu.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <linux/amba/bus.h>
+
+#include <asm/pgalloc.h>
+
+/* Maximum number of stream IDs assigned to a single device */
+#define MAX_MASTER_STREAMIDS		8
+
+/* Maximum number of context banks per SMMU */
+#define ARM_SMMU_MAX_CBS		128
+
+/* Maximum number of mapping groups per SMMU */
+#define ARM_SMMU_MAX_SMRS		128
+
+/* Number of VMIDs per SMMU */
+#define ARM_SMMU_NUM_VMIDS		256
+
+/* SMMU global address space */
+#define ARM_SMMU_GR0(smmu)		((smmu)->base)
+#define ARM_SMMU_GR1(smmu)		((smmu)->base + (smmu)->pagesize)
+
+/* Page table bits */
+#define ARM_SMMU_PTE_PAGE		(((pteval_t)3) << 0)
+#define ARM_SMMU_PTE_CONT		(((pteval_t)1) << 52)
+#define ARM_SMMU_PTE_AF			(((pteval_t)1) << 10)
+#define ARM_SMMU_PTE_SH_NS		(((pteval_t)0) << 8)
+#define ARM_SMMU_PTE_SH_OS		(((pteval_t)2) << 8)
+#define ARM_SMMU_PTE_SH_IS		(((pteval_t)3) << 8)
+
+#if PAGE_SIZE == SZ_4K
+#define ARM_SMMU_PTE_CONT_ENTRIES	16
+#elif PAGE_SIZE == SZ_64K
+#define ARM_SMMU_PTE_CONT_ENTRIES	32
+#else
+#define ARM_SMMU_PTE_CONT_ENTRIES	1
+#endif
+
+#define ARM_SMMU_PTE_CONT_SIZE		(PAGE_SIZE * ARM_SMMU_PTE_CONT_ENTRIES)
+#define ARM_SMMU_PTE_CONT_MASK		(~(ARM_SMMU_PTE_CONT_SIZE - 1))
+#define ARM_SMMU_PTE_HWTABLE_SIZE	(PTRS_PER_PTE * sizeof(pte_t))
+
+/* Stage-1 PTE */
+#define ARM_SMMU_PTE_AP_UNPRIV		(((pteval_t)1) << 6)
+#define ARM_SMMU_PTE_AP_RDONLY		(((pteval_t)2) << 6)
+#define ARM_SMMU_PTE_ATTRINDX_SHIFT	2
+
+/* Stage-2 PTE */
+#define ARM_SMMU_PTE_HAP_FAULT		(((pteval_t)0) << 6)
+#define ARM_SMMU_PTE_HAP_READ		(((pteval_t)1) << 6)
+#define ARM_SMMU_PTE_HAP_WRITE		(((pteval_t)2) << 6)
+#define ARM_SMMU_PTE_MEMATTR_OIWB	(((pteval_t)0xf) << 2)
+#define ARM_SMMU_PTE_MEMATTR_NC		(((pteval_t)0x5) << 2)
+#define ARM_SMMU_PTE_MEMATTR_DEV	(((pteval_t)0x1) << 2)
+
+/* Configuration registers */
+#define ARM_SMMU_GR0_sCR0		0x0
+#define sCR0_CLIENTPD			(1 << 0)
+#define sCR0_GFRE			(1 << 1)
+#define sCR0_GFIE			(1 << 2)
+#define sCR0_GCFGFRE			(1 << 4)
+#define sCR0_GCFGFIE			(1 << 5)
+#define sCR0_USFCFG			(1 << 10)
+#define sCR0_VMIDPNE			(1 << 11)
+#define sCR0_PTM			(1 << 12)
+#define sCR0_FB				(1 << 13)
+#define sCR0_BSU_SHIFT			14
+#define sCR0_BSU_MASK			0x3
+
+/* Identification registers */
+#define ARM_SMMU_GR0_ID0		0x20
+#define ARM_SMMU_GR0_ID1		0x24
+#define ARM_SMMU_GR0_ID2		0x28
+#define ARM_SMMU_GR0_ID3		0x2c
+#define ARM_SMMU_GR0_ID4		0x30
+#define ARM_SMMU_GR0_ID5		0x34
+#define ARM_SMMU_GR0_ID6		0x38
+#define ARM_SMMU_GR0_ID7		0x3c
+#define ARM_SMMU_GR0_sGFSR		0x48
+#define ARM_SMMU_GR0_sGFSYNR0		0x50
+#define ARM_SMMU_GR0_sGFSYNR1		0x54
+#define ARM_SMMU_GR0_sGFSYNR2		0x58
+#define ARM_SMMU_GR0_PIDR0		0xfe0
+#define ARM_SMMU_GR0_PIDR1		0xfe4
+#define ARM_SMMU_GR0_PIDR2		0xfe8
+
+#define ID0_S1TS			(1 << 30)
+#define ID0_S2TS			(1 << 29)
+#define ID0_NTS				(1 << 28)
+#define ID0_SMS				(1 << 27)
+#define ID0_PTFS_SHIFT			24
+#define ID0_PTFS_MASK			0x2
+#define ID0_PTFS_V8_ONLY		0x2
+#define ID0_CTTW			(1 << 14)
+#define ID0_NUMIRPT_SHIFT		16
+#define ID0_NUMIRPT_MASK		0xff
+#define ID0_NUMSMRG_SHIFT		0
+#define ID0_NUMSMRG_MASK		0xff
+
+#define ID1_PAGESIZE			(1 << 31)
+#define ID1_NUMPAGENDXB_SHIFT		28
+#define ID1_NUMPAGENDXB_MASK		7
+#define ID1_NUMS2CB_SHIFT		16
+#define ID1_NUMS2CB_MASK		0xff
+#define ID1_NUMCB_SHIFT			0
+#define ID1_NUMCB_MASK			0xff
+
+#define ID2_OAS_SHIFT			4
+#define ID2_OAS_MASK			0xf
+#define ID2_IAS_SHIFT			0
+#define ID2_IAS_MASK			0xf
+#define ID2_UBS_SHIFT			8
+#define ID2_UBS_MASK			0xf
+#define ID2_PTFS_4K			(1 << 12)
+#define ID2_PTFS_16K			(1 << 13)
+#define ID2_PTFS_64K			(1 << 14)
+
+#define PIDR2_ARCH_SHIFT		4
+#define PIDR2_ARCH_MASK			0xf
+
+/* Global TLB invalidation */
+#define ARM_SMMU_GR0_STLBIALL		0x60
+#define ARM_SMMU_GR0_TLBIVMID		0x64
+#define ARM_SMMU_GR0_TLBIALLNSNH	0x68
+#define ARM_SMMU_GR0_TLBIALLH		0x6c
+#define ARM_SMMU_GR0_sTLBGSYNC		0x70
+#define ARM_SMMU_GR0_sTLBGSTATUS	0x74
+#define sTLBGSTATUS_GSACTIVE		(1 << 0)
+#define TLB_LOOP_TIMEOUT		1000000	/* 1s! */
+
+/* Stream mapping registers */
+#define ARM_SMMU_GR0_SMR(n)		(0x800 + ((n) << 2))
+#define SMR_VALID			(1 << 31)
+#define SMR_MASK_SHIFT			16
+#define SMR_MASK_MASK			0x7fff
+#define SMR_ID_SHIFT			0
+#define SMR_ID_MASK			0x7fff
+
+#define ARM_SMMU_GR0_S2CR(n)		(0xc00 + ((n) << 2))
+#define S2CR_CBNDX_SHIFT		0
+#define S2CR_CBNDX_MASK			0xff
+#define S2CR_TYPE_SHIFT			16
+#define S2CR_TYPE_MASK			0x3
+#define S2CR_TYPE_TRANS			(0 << S2CR_TYPE_SHIFT)
+#define S2CR_TYPE_BYPASS		(1 << S2CR_TYPE_SHIFT)
+#define S2CR_TYPE_FAULT			(2 << S2CR_TYPE_SHIFT)
+
+/* Context bank attribute registers */
+#define ARM_SMMU_GR1_CBAR(n)		(0x0 + ((n) << 2))
+#define CBAR_VMID_SHIFT			0
+#define CBAR_VMID_MASK			0xff
+#define CBAR_S1_MEMATTR_SHIFT		12
+#define CBAR_S1_MEMATTR_MASK		0xf
+#define CBAR_S1_MEMATTR_WB		0xf
+#define CBAR_TYPE_SHIFT			16
+#define CBAR_TYPE_MASK			0x3
+#define CBAR_TYPE_S2_TRANS		(0 << CBAR_TYPE_SHIFT)
+#define CBAR_TYPE_S1_TRANS_S2_BYPASS	(1 << CBAR_TYPE_SHIFT)
+#define CBAR_TYPE_S1_TRANS_S2_FAULT	(2 << CBAR_TYPE_SHIFT)
+#define CBAR_TYPE_S1_TRANS_S2_TRANS	(3 << CBAR_TYPE_SHIFT)
+#define CBAR_IRPTNDX_SHIFT		24
+#define CBAR_IRPTNDX_MASK		0xff
+
+#define ARM_SMMU_GR1_CBA2R(n)		(0x800 + ((n) << 2))
+#define CBA2R_RW64_32BIT		(0 << 0)
+#define CBA2R_RW64_64BIT		(1 << 0)
+
+/* Translation context bank */
+#define ARM_SMMU_CB_BASE(smmu)		((smmu)->base + ((smmu)->size >> 1))
+#define ARM_SMMU_CB(smmu, n)		((n) * (smmu)->pagesize)
+
+#define ARM_SMMU_CB_SCTLR		0x0
+#define ARM_SMMU_CB_RESUME		0x8
+#define ARM_SMMU_CB_TTBCR2		0x10
+#define ARM_SMMU_CB_TTBR0_LO		0x20
+#define ARM_SMMU_CB_TTBR0_HI		0x24
+#define ARM_SMMU_CB_TTBCR		0x30
+#define ARM_SMMU_CB_S1_MAIR0		0x38
+#define ARM_SMMU_CB_FSR			0x58
+#define ARM_SMMU_CB_FAR_LO		0x60
+#define ARM_SMMU_CB_FAR_HI		0x64
+#define ARM_SMMU_CB_FSYNR0		0x68
+
+#define SCTLR_S1_ASIDPNE		(1 << 12)
+#define SCTLR_CFCFG			(1 << 7)
+#define SCTLR_CFIE			(1 << 6)
+#define SCTLR_CFRE			(1 << 5)
+#define SCTLR_E				(1 << 4)
+#define SCTLR_AFE			(1 << 2)
+#define SCTLR_TRE			(1 << 1)
+#define SCTLR_M				(1 << 0)
+#define SCTLR_EAE_SBOP			(SCTLR_AFE | SCTLR_TRE)
+
+#define RESUME_RETRY			(0 << 0)
+#define RESUME_TERMINATE		(1 << 0)
+
+#define TTBCR_EAE			(1 << 31)
+
+#define TTBCR_PASIZE_SHIFT		16
+#define TTBCR_PASIZE_MASK		0x7
+
+#define TTBCR_TG0_4K			(0 << 14)
+#define TTBCR_TG0_64K			(1 << 14)
+
+#define TTBCR_SH0_SHIFT			12
+#define TTBCR_SH0_MASK			0x3
+#define TTBCR_SH_NS			0
+#define TTBCR_SH_OS			2
+#define TTBCR_SH_IS			3
+
+#define TTBCR_ORGN0_SHIFT		10
+#define TTBCR_IRGN0_SHIFT		8
+#define TTBCR_RGN_MASK			0x3
+#define TTBCR_RGN_NC			0
+#define TTBCR_RGN_WBWA			1
+#define TTBCR_RGN_WT			2
+#define TTBCR_RGN_WB			3
+
+#define TTBCR_SL0_SHIFT			6
+#define TTBCR_SL0_MASK			0x3
+#define TTBCR_SL0_LVL_2			0
+#define TTBCR_SL0_LVL_1			1
+
+#define TTBCR_T1SZ_SHIFT		16
+#define TTBCR_T0SZ_SHIFT		0
+#define TTBCR_SZ_MASK			0xf
+
+#define TTBCR2_SEP_SHIFT		15
+#define TTBCR2_SEP_MASK			0x7
+
+#define TTBCR2_PASIZE_SHIFT		0
+#define TTBCR2_PASIZE_MASK		0x7
+
+/* Common definitions for PASize and SEP fields */
+#define TTBCR2_ADDR_32			0
+#define TTBCR2_ADDR_36			1
+#define TTBCR2_ADDR_40			2
+#define TTBCR2_ADDR_42			3
+#define TTBCR2_ADDR_44			4
+#define TTBCR2_ADDR_48			5
+
+#define MAIR_ATTR_SHIFT(n)		((n) << 3)
+#define MAIR_ATTR_MASK			0xff
+#define MAIR_ATTR_DEVICE		0x04
+#define MAIR_ATTR_NC			0x44
+#define MAIR_ATTR_WBRWA			0xff
+#define MAIR_ATTR_IDX_NC		0
+#define MAIR_ATTR_IDX_CACHE		1
+#define MAIR_ATTR_IDX_DEV		2
+
+#define FSR_MULTI			(1 << 31)
+#define FSR_SS				(1 << 30)
+#define FSR_UUT				(1 << 8)
+#define FSR_ASF				(1 << 7)
+#define FSR_TLBLKF			(1 << 6)
+#define FSR_TLBMCF			(1 << 5)
+#define FSR_EF				(1 << 4)
+#define FSR_PF				(1 << 3)
+#define FSR_AFF				(1 << 2)
+#define FSR_TF				(1 << 1)
+
+#define FSR_IGN				(FSR_AFF | FSR_ASF | FSR_TLBMCF |	\
+					 FSR_TLBLKF)
+#define FSR_FAULT			(FSR_MULTI | FSR_SS | FSR_UUT |		\
+					 FSR_EF | FSR_PF | FSR_TF)
+
+#define FSYNR0_WNR			(1 << 4)
+
+struct arm_smmu_smr {
+	u8				idx;
+	u16				mask;
+	u16				id;
+};
+
+struct arm_smmu_master {
+	struct device_node		*of_node;
+
+	/*
+	 * The following is specific to the master's position in the
+	 * SMMU chain.
+	 */
+	struct rb_node			node;
+	int				num_streamids;
+	u16				streamids[MAX_MASTER_STREAMIDS];
+
+	/*
+	 * We only need to allocate these on the root SMMU, as we
+	 * configure unmatched streams to bypass translation.
+	 */
+	struct arm_smmu_smr		*smrs;
+};
+
+struct arm_smmu_device {
+	struct device			*dev;
+	struct device_node		*parent_of_node;
+
+	void __iomem			*base;
+	unsigned long			size;
+	unsigned long			pagesize;
+
+#define ARM_SMMU_FEAT_COHERENT_WALK	(1 << 0)
+#define ARM_SMMU_FEAT_STREAM_MATCH	(1 << 1)
+#define ARM_SMMU_FEAT_TRANS_S1		(1 << 2)
+#define ARM_SMMU_FEAT_TRANS_S2		(1 << 3)
+#define ARM_SMMU_FEAT_TRANS_NESTED	(1 << 4)
+	u32				features;
+	int				version;
+
+	u32				num_context_banks;
+	u32				num_s2_context_banks;
+	DECLARE_BITMAP(context_map, ARM_SMMU_MAX_CBS);
+	atomic_t			irptndx;
+
+	u32				num_mapping_groups;
+	DECLARE_BITMAP(smr_map, ARM_SMMU_MAX_SMRS);
+
+	unsigned long			input_size;
+	unsigned long			s1_output_size;
+	unsigned long			s2_output_size;
+
+	u32				num_global_irqs;
+	u32				num_context_irqs;
+	unsigned int			*irqs;
+
+	DECLARE_BITMAP(vmid_map, ARM_SMMU_NUM_VMIDS);
+
+	struct list_head		list;
+	struct rb_root			masters;
+};
+
+struct arm_smmu_cfg {
+	struct arm_smmu_device		*smmu;
+	u8				vmid;
+	u8				cbndx;
+	u8				irptndx;
+	u32				cbar;
+	pgd_t				*pgd;
+};
+
+struct arm_smmu_domain {
+	/*
+	 * A domain can span across multiple, chained SMMUs and requires
+	 * all devices within the domain to follow the same translation
+	 * path.
+	 */
+	struct arm_smmu_device		*leaf_smmu;
+	struct arm_smmu_cfg		root_cfg;
+	phys_addr_t			output_mask;
+
+	spinlock_t			lock;
+};
+
+static DEFINE_SPINLOCK(arm_smmu_devices_lock);
+static LIST_HEAD(arm_smmu_devices);
+
+static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu,
+						struct device_node *dev_node)
+{
+	struct rb_node *node = smmu->masters.rb_node;
+
+	while (node) {
+		struct arm_smmu_master *master;
+		master = container_of(node, struct arm_smmu_master, node);
+
+		if (dev_node < master->of_node)
+			node = node->rb_left;
+		else if (dev_node > master->of_node)
+			node = node->rb_right;
+		else
+			return master;
+	}
+
+	return NULL;
+}
+
+static int insert_smmu_master(struct arm_smmu_device *smmu,
+			      struct arm_smmu_master *master)
+{
+	struct rb_node **new, *parent;
+
+	new = &smmu->masters.rb_node;
+	parent = NULL;
+	while (*new) {
+		struct arm_smmu_master *this;
+		this = container_of(*new, struct arm_smmu_master, node);
+
+		parent = *new;
+		if (master->of_node < this->of_node)
+			new = &((*new)->rb_left);
+		else if (master->of_node > this->of_node)
+			new = &((*new)->rb_right);
+		else
+			return -EEXIST;
+	}
+
+	rb_link_node(&master->node, parent, new);
+	rb_insert_color(&master->node, &smmu->masters);
+	return 0;
+}
+
+static int register_smmu_master(struct arm_smmu_device *smmu,
+				struct device *dev,
+				struct of_phandle_args *masterspec)
+{
+	int i;
+	struct arm_smmu_master *master;
+
+	master = find_smmu_master(smmu, masterspec->np);
+	if (master) {
+		dev_err(dev,
+			"rejecting multiple registrations for master device %s\n",
+			masterspec->np->name);
+		return -EBUSY;
+	}
+
+	if (masterspec->args_count > MAX_MASTER_STREAMIDS) {
+		dev_err(dev,
+			"reached maximum number (%d) of stream IDs for master device %s\n",
+			MAX_MASTER_STREAMIDS, masterspec->np->name);
+		return -ENOSPC;
+	}
+
+	master = devm_kzalloc(dev, sizeof(*master), GFP_KERNEL);
+	if (!master)
+		return -ENOMEM;
+
+	master->of_node		= masterspec->np;
+	master->num_streamids	= masterspec->args_count;
+
+	for (i = 0; i < master->num_streamids; ++i)
+		master->streamids[i] = masterspec->args[i];
+
+	return insert_smmu_master(smmu, master);
+}
+
+static struct arm_smmu_device *find_parent_smmu(struct arm_smmu_device *smmu)
+{
+	struct arm_smmu_device *parent;
+
+	if (!smmu->parent_of_node)
+		return NULL;
+
+	spin_lock(&arm_smmu_devices_lock);
+	list_for_each_entry(parent, &arm_smmu_devices, list)
+		if (parent->dev->of_node == smmu->parent_of_node)
+			goto out_unlock;
+
+	parent = NULL;
+	dev_warn(smmu->dev,
+		 "Failed to find SMMU parent despite parent in DT\n");
+out_unlock:
+	spin_unlock(&arm_smmu_devices_lock);
+	return parent;
+}
+
+static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end)
+{
+	int idx;
+
+	do {
+		idx = find_next_zero_bit(map, end, start);
+		if (idx == end)
+			return -ENOSPC;
+	} while (test_and_set_bit(idx, map));
+
+	return idx;
+}
+
+static void __arm_smmu_free_bitmap(unsigned long *map, int idx)
+{
+	clear_bit(idx, map);
+}
+
+/* Wait for any pending TLB invalidations to complete */
+static void arm_smmu_tlb_sync(struct arm_smmu_device *smmu)
+{
+	int count = 0;
+	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+
+	writel_relaxed(0, gr0_base + ARM_SMMU_GR0_sTLBGSYNC);
+	while (readl_relaxed(gr0_base + ARM_SMMU_GR0_sTLBGSTATUS)
+	       & sTLBGSTATUS_GSACTIVE) {
+		cpu_relax();
+		if (++count == TLB_LOOP_TIMEOUT) {
+			dev_err_ratelimited(smmu->dev,
+			"TLB sync timed out -- SMMU may be deadlocked\n");
+			return;
+		}
+		udelay(1);
+	}
+}
+
+static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
+{
+	int flags, ret;
+	u32 fsr, far, fsynr, resume;
+	unsigned long iova;
+	struct iommu_domain *domain = dev;
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
+	struct arm_smmu_device *smmu = root_cfg->smmu;
+	void __iomem *cb_base;
+
+	cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, root_cfg->cbndx);
+	fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
+
+	if (!(fsr & FSR_FAULT))
+		return IRQ_NONE;
+
+	if (fsr & FSR_IGN)
+		dev_err_ratelimited(smmu->dev,
+				    "Unexpected context fault (fsr 0x%u)\n",
+				    fsr);
+
+	fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
+	flags = fsynr & FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ;
+
+	far = readl_relaxed(cb_base + ARM_SMMU_CB_FAR_LO);
+	iova = far;
+#ifdef CONFIG_64BIT
+	far = readl_relaxed(cb_base + ARM_SMMU_CB_FAR_HI);
+	iova |= ((unsigned long)far << 32);
+#endif
+
+	if (!report_iommu_fault(domain, smmu->dev, iova, flags)) {
+		ret = IRQ_HANDLED;
+		resume = RESUME_RETRY;
+	} else {
+		ret = IRQ_NONE;
+		resume = RESUME_TERMINATE;
+	}
+
+	/* Clear the faulting FSR */
+	writel(fsr, cb_base + ARM_SMMU_CB_FSR);
+
+	/* Retry or terminate any stalled transactions */
+	if (fsr & FSR_SS)
+		writel_relaxed(resume, cb_base + ARM_SMMU_CB_RESUME);
+
+	return ret;
+}
+
+static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
+{
+	u32 gfsr, gfsynr0, gfsynr1, gfsynr2;
+	struct arm_smmu_device *smmu = dev;
+	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+
+	gfsr = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSR);
+	gfsynr0 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR0);
+	gfsynr1 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR1);
+	gfsynr2 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR2);
+
+	dev_err_ratelimited(smmu->dev,
+		"Unexpected global fault, this could be serious\n");
+	dev_err_ratelimited(smmu->dev,
+		"\tGFSR 0x%08x, GFSYNR0 0x%08x, GFSYNR1 0x%08x, GFSYNR2 0x%08x\n",
+		gfsr, gfsynr0, gfsynr1, gfsynr2);
+
+	writel(gfsr, gr0_base + ARM_SMMU_GR0_sGFSR);
+	return IRQ_NONE;
+}
+
+static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain)
+{
+	u32 reg;
+	bool stage1;
+	struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
+	struct arm_smmu_device *smmu = root_cfg->smmu;
+	void __iomem *cb_base, *gr0_base, *gr1_base;
+
+	gr0_base = ARM_SMMU_GR0(smmu);
+	gr1_base = ARM_SMMU_GR1(smmu);
+	stage1 = root_cfg->cbar != CBAR_TYPE_S2_TRANS;
+	cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, root_cfg->cbndx);
+
+	/* CBAR */
+	reg = root_cfg->cbar |
+	      (root_cfg->vmid << CBAR_VMID_SHIFT);
+	if (smmu->version == 1)
+	      reg |= root_cfg->irptndx << CBAR_IRPTNDX_SHIFT;
+
+	/* Use the weakest memory type, so it is overridden by the pte */
+	if (stage1)
+		reg |= (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
+	writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(root_cfg->cbndx));
+
+	if (smmu->version > 1) {
+		/* CBA2R */
+#ifdef CONFIG_64BIT
+		reg = CBA2R_RW64_64BIT;
+#else
+		reg = CBA2R_RW64_32BIT;
+#endif
+		writel_relaxed(reg,
+			       gr1_base + ARM_SMMU_GR1_CBA2R(root_cfg->cbndx));
+
+		/* TTBCR2 */
+		switch (smmu->input_size) {
+		case 32:
+			reg = (TTBCR2_ADDR_32 << TTBCR2_SEP_SHIFT);
+			break;
+		case 36:
+			reg = (TTBCR2_ADDR_36 << TTBCR2_SEP_SHIFT);
+			break;
+		case 39:
+			reg = (TTBCR2_ADDR_40 << TTBCR2_SEP_SHIFT);
+			break;
+		case 42:
+			reg = (TTBCR2_ADDR_42 << TTBCR2_SEP_SHIFT);
+			break;
+		case 44:
+			reg = (TTBCR2_ADDR_44 << TTBCR2_SEP_SHIFT);
+			break;
+		case 48:
+			reg = (TTBCR2_ADDR_48 << TTBCR2_SEP_SHIFT);
+			break;
+		}
+
+		switch (smmu->s1_output_size) {
+		case 32:
+			reg |= (TTBCR2_ADDR_32 << TTBCR2_PASIZE_SHIFT);
+			break;
+		case 36:
+			reg |= (TTBCR2_ADDR_36 << TTBCR2_PASIZE_SHIFT);
+			break;
+		case 39:
+			reg |= (TTBCR2_ADDR_40 << TTBCR2_PASIZE_SHIFT);
+			break;
+		case 42:
+			reg |= (TTBCR2_ADDR_42 << TTBCR2_PASIZE_SHIFT);
+			break;
+		case 44:
+			reg |= (TTBCR2_ADDR_44 << TTBCR2_PASIZE_SHIFT);
+			break;
+		case 48:
+			reg |= (TTBCR2_ADDR_48 << TTBCR2_PASIZE_SHIFT);
+			break;
+		}
+
+		if (stage1)
+			writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR2);
+	}
+
+	/* TTBR0 */
+	reg = __pa(root_cfg->pgd);
+#ifndef __BIG_ENDIAN
+	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
+	reg = (phys_addr_t)__pa(root_cfg->pgd) >> 32;
+	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
+#else
+	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
+	reg = (phys_addr_t)__pa(root_cfg->pgd) >> 32;
+	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
+#endif
+
+	/*
+	 * TTBCR
+	 * We use long descriptor, with inner-shareable WBWA tables in TTBR0.
+	 */
+	if (smmu->version > 1) {
+		if (PAGE_SIZE == SZ_4K)
+			reg = TTBCR_TG0_4K;
+		else
+			reg = TTBCR_TG0_64K;
+
+		if (!stage1) {
+			switch (smmu->s2_output_size) {
+			case 32:
+				reg |= (TTBCR2_ADDR_32 << TTBCR_PASIZE_SHIFT);
+				break;
+			case 36:
+				reg |= (TTBCR2_ADDR_36 << TTBCR_PASIZE_SHIFT);
+				break;
+			case 40:
+				reg |= (TTBCR2_ADDR_40 << TTBCR_PASIZE_SHIFT);
+				break;
+			case 42:
+				reg |= (TTBCR2_ADDR_42 << TTBCR_PASIZE_SHIFT);
+				break;
+			case 44:
+				reg |= (TTBCR2_ADDR_44 << TTBCR_PASIZE_SHIFT);
+				break;
+			case 48:
+				reg |= (TTBCR2_ADDR_48 << TTBCR_PASIZE_SHIFT);
+				break;
+			}
+		} else {
+			reg |= (64 - smmu->s1_output_size) << TTBCR_T0SZ_SHIFT;
+		}
+	} else {
+		reg = 0;
+	}
+
+	reg |= TTBCR_EAE |
+	      (TTBCR_SH_IS << TTBCR_SH0_SHIFT) |
+	      (TTBCR_RGN_WBWA << TTBCR_ORGN0_SHIFT) |
+	      (TTBCR_RGN_WBWA << TTBCR_IRGN0_SHIFT) |
+	      (TTBCR_SL0_LVL_1 << TTBCR_SL0_SHIFT);
+	writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR);
+
+	/* MAIR0 (stage-1 only) */
+	if (stage1) {
+		reg = (MAIR_ATTR_NC << MAIR_ATTR_SHIFT(MAIR_ATTR_IDX_NC)) |
+		      (MAIR_ATTR_WBRWA << MAIR_ATTR_SHIFT(MAIR_ATTR_IDX_CACHE)) |
+		      (MAIR_ATTR_DEVICE << MAIR_ATTR_SHIFT(MAIR_ATTR_IDX_DEV));
+		writel_relaxed(reg, cb_base + ARM_SMMU_CB_S1_MAIR0);
+	}
+
+	/* Nuke the TLB */
+	writel_relaxed(root_cfg->vmid, gr0_base + ARM_SMMU_GR0_TLBIVMID);
+	arm_smmu_tlb_sync(smmu);
+
+	/* SCTLR */
+	reg = SCTLR_CFCFG | SCTLR_CFIE | SCTLR_CFRE | SCTLR_M | SCTLR_EAE_SBOP;
+	if (stage1)
+		reg |= SCTLR_S1_ASIDPNE;
+#ifdef __BIG_ENDIAN
+	reg |= SCTLR_E;
+#endif
+	writel(reg, cb_base + ARM_SMMU_CB_SCTLR);
+}
+
+static int arm_smmu_init_domain_context(struct iommu_domain *domain,
+					struct device *dev)
+{
+	int irq, ret, start;
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
+	struct arm_smmu_device *smmu, *parent;
+
+	/*
+	 * Walk the SMMU chain to find the root device for this chain.
+	 * We assume that no masters have translations which terminate
+	 * early, and therefore check that the root SMMU does indeed have
+	 * a StreamID for the master in question.
+	 */
+	parent = dev->archdata.iommu;
+	smmu_domain->output_mask = -1;
+	do {
+		smmu = parent;
+		smmu_domain->output_mask &= (1ULL << smmu->s2_output_size) - 1;
+	} while ((parent = find_parent_smmu(smmu)));
+
+	if (!find_smmu_master(smmu, dev->of_node)) {
+		dev_err(dev, "unable to find root SMMU for device\n");
+		return -ENODEV;
+	}
+
+	ret = __arm_smmu_alloc_bitmap(smmu->vmid_map, 0, ARM_SMMU_NUM_VMIDS);
+	if (IS_ERR_VALUE(ret))
+		return ret;
+
+	root_cfg->vmid = ret;
+	if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) {
+		/*
+		 * We will likely want to change this if/when KVM gets
+		 * involved.
+		 */
+		root_cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
+		start = smmu->num_s2_context_banks;
+	} else if (smmu->features & ARM_SMMU_FEAT_TRANS_S2) {
+		root_cfg->cbar = CBAR_TYPE_S2_TRANS;
+		start = 0;
+	} else {
+		root_cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
+		start = smmu->num_s2_context_banks;
+	}
+
+	ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
+				      smmu->num_context_banks);
+	if (IS_ERR_VALUE(ret))
+		goto out_free_vmid;
+
+	root_cfg->cbndx = ret;
+
+	if (smmu->version == 1) {
+		root_cfg->irptndx = atomic_inc_return(&smmu->irptndx);
+		root_cfg->irptndx %= smmu->num_context_irqs;
+	} else {
+		root_cfg->irptndx = root_cfg->cbndx;
+	}
+
+	irq = smmu->irqs[smmu->num_global_irqs + root_cfg->irptndx];
+	ret = request_irq(irq, arm_smmu_context_fault, IRQF_SHARED,
+			  "arm-smmu-context-fault", domain);
+	if (IS_ERR_VALUE(ret)) {
+		dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
+			root_cfg->irptndx, irq);
+		root_cfg->irptndx = -1;
+		goto out_free_context;
+	}
+
+	root_cfg->smmu = smmu;
+	arm_smmu_init_context_bank(smmu_domain);
+	return ret;
+
+out_free_context:
+	__arm_smmu_free_bitmap(smmu->context_map, root_cfg->cbndx);
+out_free_vmid:
+	__arm_smmu_free_bitmap(smmu->vmid_map, root_cfg->vmid);
+	return ret;
+}
+
+static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
+{
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
+	struct arm_smmu_device *smmu = root_cfg->smmu;
+	int irq;
+
+	if (!smmu)
+		return;
+
+	if (root_cfg->irptndx != -1) {
+		irq = smmu->irqs[smmu->num_global_irqs + root_cfg->irptndx];
+		free_irq(irq, domain);
+	}
+
+	__arm_smmu_free_bitmap(smmu->vmid_map, root_cfg->vmid);
+	__arm_smmu_free_bitmap(smmu->context_map, root_cfg->cbndx);
+}
+
+static int arm_smmu_domain_init(struct iommu_domain *domain)
+{
+	struct arm_smmu_domain *smmu_domain;
+	pgd_t *pgd;
+
+	/*
+	 * Allocate the domain and initialise some of its data structures.
+	 * We can't really do anything meaningful until we've added a
+	 * master.
+	 */
+	smmu_domain = kzalloc(sizeof(*smmu_domain), GFP_KERNEL);
+	if (!smmu_domain)
+		return -ENOMEM;
+
+	pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
+	if (!pgd)
+		goto out_free_domain;
+	smmu_domain->root_cfg.pgd = pgd;
+
+	spin_lock_init(&smmu_domain->lock);
+	domain->priv = smmu_domain;
+	return 0;
+
+out_free_domain:
+	kfree(smmu_domain);
+	return -ENOMEM;
+}
+
+static void arm_smmu_free_ptes(pmd_t *pmd)
+{
+	pgtable_t table = pmd_pgtable(*pmd);
+	pgtable_page_dtor(table);
+	__free_page(table);
+}
+
+static void arm_smmu_free_pmds(pud_t *pud)
+{
+	int i;
+	pmd_t *pmd, *pmd_base = pmd_offset(pud, 0);
+
+	pmd = pmd_base;
+	for (i = 0; i < PTRS_PER_PMD; ++i) {
+		if (pmd_none(*pmd))
+			continue;
+
+		arm_smmu_free_ptes(pmd);
+		pmd++;
+	}
+
+	pmd_free(NULL, pmd_base);
+}
+
+static void arm_smmu_free_puds(pgd_t *pgd)
+{
+	int i;
+	pud_t *pud, *pud_base = pud_offset(pgd, 0);
+
+	pud = pud_base;
+	for (i = 0; i < PTRS_PER_PUD; ++i) {
+		if (pud_none(*pud))
+			continue;
+
+		arm_smmu_free_pmds(pud);
+		pud++;
+	}
+
+	pud_free(NULL, pud_base);
+}
+
+static void arm_smmu_free_pgtables(struct arm_smmu_domain *smmu_domain)
+{
+	int i;
+	struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
+	pgd_t *pgd, *pgd_base = root_cfg->pgd;
+
+	/*
+	 * Recursively free the page tables for this domain. We don't
+	 * care about speculative TLB filling, because the TLB will be
+	 * nuked next time this context bank is re-allocated and no devices
+	 * currently map to these tables.
+	 */
+	pgd = pgd_base;
+	for (i = 0; i < PTRS_PER_PGD; ++i) {
+		if (pgd_none(*pgd))
+			continue;
+		arm_smmu_free_puds(pgd);
+		pgd++;
+	}
+
+	kfree(pgd_base);
+}
+
+static void arm_smmu_domain_destroy(struct iommu_domain *domain)
+{
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+	arm_smmu_destroy_domain_context(domain);
+	arm_smmu_free_pgtables(smmu_domain);
+	kfree(smmu_domain);
+}
+
+static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu,
+					  struct arm_smmu_master *master)
+{
+	int i;
+	struct arm_smmu_smr *smrs;
+	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+
+	if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH))
+		return 0;
+
+	if (master->smrs)
+		return -EEXIST;
+
+	smrs = kmalloc(sizeof(*smrs) * master->num_streamids, GFP_KERNEL);
+	if (!smrs) {
+		dev_err(smmu->dev, "failed to allocate %d SMRs for master %s\n",
+			master->num_streamids, master->of_node->name);
+		return -ENOMEM;
+	}
+
+	/* Allocate the SMRs on the root SMMU */
+	for (i = 0; i < master->num_streamids; ++i) {
+		int idx = __arm_smmu_alloc_bitmap(smmu->smr_map, 0,
+						  smmu->num_mapping_groups);
+		if (IS_ERR_VALUE(idx)) {
+			dev_err(smmu->dev, "failed to allocate free SMR\n");
+			goto err_free_smrs;
+		}
+
+		smrs[i] = (struct arm_smmu_smr) {
+			.idx	= idx,
+			.mask	= 0, /* We don't currently share SMRs */
+			.id	= master->streamids[i],
+		};
+	}
+
+	/* It worked! Now, poke the actual hardware */
+	for (i = 0; i < master->num_streamids; ++i) {
+		u32 reg = SMR_VALID | smrs[i].id << SMR_ID_SHIFT |
+			  smrs[i].mask << SMR_MASK_SHIFT;
+		writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_SMR(smrs[i].idx));
+	}
+
+	master->smrs = smrs;
+	return 0;
+
+err_free_smrs:
+	while (--i >= 0)
+		__arm_smmu_free_bitmap(smmu->smr_map, smrs[i].idx);
+	kfree(smrs);
+	return -ENOSPC;
+}
+
+static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu,
+				      struct arm_smmu_master *master)
+{
+	int i;
+	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+	struct arm_smmu_smr *smrs = master->smrs;
+
+	/* Invalidate the SMRs before freeing back to the allocator */
+	for (i = 0; i < master->num_streamids; ++i) {
+		u8 idx = smrs[i].idx;
+		writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(idx));
+		__arm_smmu_free_bitmap(smmu->smr_map, idx);
+	}
+
+	master->smrs = NULL;
+	kfree(smrs);
+}
+
+static void arm_smmu_bypass_stream_mapping(struct arm_smmu_device *smmu,
+					   struct arm_smmu_master *master)
+{
+	int i;
+	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+
+	for (i = 0; i < master->num_streamids; ++i) {
+		u16 sid = master->streamids[i];
+		writel_relaxed(S2CR_TYPE_BYPASS,
+			       gr0_base + ARM_SMMU_GR0_S2CR(sid));
+	}
+}
+
+static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain,
+				      struct arm_smmu_master *master)
+{
+	int i, ret;
+	struct arm_smmu_device *parent, *smmu = smmu_domain->root_cfg.smmu;
+	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+
+	ret = arm_smmu_master_configure_smrs(smmu, master);
+	if (ret)
+		return ret;
+
+	/* Bypass the leaves */
+	smmu = smmu_domain->leaf_smmu;
+	while ((parent = find_parent_smmu(smmu))) {
+		/*
+		 * We won't have a StreamID match for anything but the root
+		 * smmu, so we only need to worry about StreamID indexing,
+		 * where we must install bypass entries in the S2CRs.
+		 */
+		if (smmu->features & ARM_SMMU_FEAT_STREAM_MATCH)
+			continue;
+
+		arm_smmu_bypass_stream_mapping(smmu, master);
+		smmu = parent;
+	}
+
+	/* Now we're at the root, time to point at our context bank */
+	for (i = 0; i < master->num_streamids; ++i) {
+		u32 idx, s2cr;
+		idx = master->smrs ? master->smrs[i].idx : master->streamids[i];
+		s2cr = (S2CR_TYPE_TRANS << S2CR_TYPE_SHIFT) |
+		       (smmu_domain->root_cfg.cbndx << S2CR_CBNDX_SHIFT);
+		writel_relaxed(s2cr, gr0_base + ARM_SMMU_GR0_S2CR(idx));
+	}
+
+	return 0;
+}
+
+static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain,
+					  struct arm_smmu_master *master)
+{
+	struct arm_smmu_device *smmu = smmu_domain->root_cfg.smmu;
+
+	/*
+	 * We *must* clear the S2CR first, because freeing the SMR means
+	 * that it can be re-allocated immediately.
+	 */
+	arm_smmu_bypass_stream_mapping(smmu, master);
+	arm_smmu_master_free_smrs(smmu, master);
+}
+
+static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
+{
+	int ret = -EINVAL;
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_device *device_smmu = dev->archdata.iommu;
+	struct arm_smmu_master *master;
+
+	if (!device_smmu) {
+		dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n");
+		return -ENXIO;
+	}
+
+	/*
+	 * Sanity check the domain. We don't currently support domains
+	 * that cross between different SMMU chains.
+	 */
+	spin_lock(&smmu_domain->lock);
+	if (!smmu_domain->leaf_smmu) {
+		/* Now that we have a master, we can finalise the domain */
+		ret = arm_smmu_init_domain_context(domain, dev);
+		if (IS_ERR_VALUE(ret))
+			goto err_unlock;
+
+		smmu_domain->leaf_smmu = device_smmu;
+	} else if (smmu_domain->leaf_smmu != device_smmu) {
+		dev_err(dev,
+			"cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n",
+			dev_name(smmu_domain->leaf_smmu->dev),
+			dev_name(device_smmu->dev));
+		goto err_unlock;
+	}
+	spin_unlock(&smmu_domain->lock);
+
+	/* Looks ok, so add the device to the domain */
+	master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node);
+	if (!master)
+		return -ENODEV;
+
+	return arm_smmu_domain_add_master(smmu_domain, master);
+
+err_unlock:
+	spin_unlock(&smmu_domain->lock);
+	return ret;
+}
+
+static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
+{
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_master *master;
+
+	master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node);
+	if (master)
+		arm_smmu_domain_remove_master(smmu_domain, master);
+}
+
+static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr,
+				   size_t size)
+{
+	unsigned long offset = (unsigned long)addr & ~PAGE_MASK;
+
+	/*
+	 * If the SMMU can't walk tables in the CPU caches, treat them
+	 * like non-coherent DMA since we need to flush the new entries
+	 * all the way out to memory. There's no possibility of recursion
+	 * here as the SMMU table walker will not be wired through another
+	 * SMMU.
+	 */
+	if (!(smmu->features & ARM_SMMU_FEAT_COHERENT_WALK))
+		dma_map_page(smmu->dev, virt_to_page(addr), offset, size,
+			     DMA_TO_DEVICE);
+}
+
+static bool arm_smmu_pte_is_contiguous_range(unsigned long addr,
+					     unsigned long end)
+{
+	return !(addr & ~ARM_SMMU_PTE_CONT_MASK) &&
+		(addr + ARM_SMMU_PTE_CONT_SIZE <= end);
+}
+
+static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd,
+				   unsigned long addr, unsigned long end,
+				   unsigned long pfn, int flags, int stage)
+{
+	pte_t *pte, *start;
+	pteval_t pteval = ARM_SMMU_PTE_PAGE | ARM_SMMU_PTE_AF;
+
+	if (pmd_none(*pmd)) {
+		/* Allocate a new set of tables */
+		pgtable_t table = alloc_page(PGALLOC_GFP);
+		if (!table)
+			return -ENOMEM;
+
+		arm_smmu_flush_pgtable(smmu, page_address(table),
+				       ARM_SMMU_PTE_HWTABLE_SIZE);
+		pgtable_page_ctor(table);
+		pmd_populate(NULL, pmd, table);
+		arm_smmu_flush_pgtable(smmu, pmd, sizeof(*pmd));
+	}
+
+	if (stage == 1) {
+		pteval |= ARM_SMMU_PTE_AP_UNPRIV;
+		if (!(flags & IOMMU_WRITE) && (flags & IOMMU_READ))
+			pteval |= ARM_SMMU_PTE_AP_RDONLY;
+
+		if (flags & IOMMU_CACHE)
+			pteval |= (MAIR_ATTR_IDX_CACHE <<
+				   ARM_SMMU_PTE_ATTRINDX_SHIFT);
+	} else {
+		pteval |= ARM_SMMU_PTE_HAP_FAULT;
+		if (flags & IOMMU_READ)
+			pteval |= ARM_SMMU_PTE_HAP_READ;
+		if (flags & IOMMU_WRITE)
+			pteval |= ARM_SMMU_PTE_HAP_WRITE;
+		if (flags & IOMMU_CACHE)
+			pteval |= ARM_SMMU_PTE_MEMATTR_OIWB;
+		else
+			pteval |= ARM_SMMU_PTE_MEMATTR_NC;
+	}
+
+	/* If no access, create a faulting entry to avoid TLB fills */
+	if (!(flags & (IOMMU_READ | IOMMU_WRITE)))
+		pteval &= ~ARM_SMMU_PTE_PAGE;
+
+	pteval |= ARM_SMMU_PTE_SH_IS;
+	start = pmd_page_vaddr(*pmd) + pte_index(addr);
+	pte = start;
+
+	/*
+	 * Install the page table entries. This is fairly complicated
+	 * since we attempt to make use of the contiguous hint in the
+	 * ptes where possible. The contiguous hint indicates a series
+	 * of ARM_SMMU_PTE_CONT_ENTRIES ptes mapping a physically
+	 * contiguous region with the following constraints:
+	 *
+	 *   - The region start is aligned to ARM_SMMU_PTE_CONT_SIZE
+	 *   - Each pte in the region has the contiguous hint bit set
+	 *
+	 * This complicates unmapping (also handled by this code, when
+	 * neither IOMMU_READ or IOMMU_WRITE are set) because it is
+	 * possible, yet highly unlikely, that a client may unmap only
+	 * part of a contiguous range. This requires clearing of the
+	 * contiguous hint bits in the range before installing the new
+	 * faulting entries.
+	 *
+	 * Note that re-mapping an address range without first unmapping
+	 * it is not supported, so TLB invalidation is not required here
+	 * and is instead performed at unmap and domain-init time.
+	 */
+	do {
+		int i = 1;
+		pteval &= ~ARM_SMMU_PTE_CONT;
+
+		if (arm_smmu_pte_is_contiguous_range(addr, end)) {
+			i = ARM_SMMU_PTE_CONT_ENTRIES;
+			pteval |= ARM_SMMU_PTE_CONT;
+		} else if (pte_val(*pte) &
+			   (ARM_SMMU_PTE_CONT | ARM_SMMU_PTE_PAGE)) {
+			int j;
+			pte_t *cont_start;
+			unsigned long idx = pte_index(addr);
+
+			idx &= ~(ARM_SMMU_PTE_CONT_ENTRIES - 1);
+			cont_start = pmd_page_vaddr(*pmd) + idx;
+			for (j = 0; j < ARM_SMMU_PTE_CONT_ENTRIES; ++j)
+				pte_val(*(cont_start + j)) &= ~ARM_SMMU_PTE_CONT;
+
+			arm_smmu_flush_pgtable(smmu, cont_start,
+					       sizeof(*pte) *
+					       ARM_SMMU_PTE_CONT_ENTRIES);
+		}
+
+		do {
+			*pte = pfn_pte(pfn, __pgprot(pteval));
+		} while (pte++, pfn++, addr += PAGE_SIZE, --i);
+	} while (addr != end);
+
+	arm_smmu_flush_pgtable(smmu, start, sizeof(*pte) * (pte - start));
+	return 0;
+}
+
+static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud,
+				   unsigned long addr, unsigned long end,
+				   phys_addr_t phys, int flags, int stage)
+{
+	int ret;
+	pmd_t *pmd;
+	unsigned long next, pfn = __phys_to_pfn(phys);
+
+#ifndef __PAGETABLE_PMD_FOLDED
+	if (pud_none(*pud)) {
+		pmd = pmd_alloc_one(NULL, addr);
+		if (!pmd)
+			return -ENOMEM;
+	} else
+#endif
+		pmd = pmd_offset(pud, addr);
+
+	do {
+		next = pmd_addr_end(addr, end);
+		ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn,
+					      flags, stage);
+		pud_populate(NULL, pud, pmd);
+		arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud));
+		phys += next - addr;
+	} while (pmd++, addr = next, addr < end);
+
+	return ret;
+}
+
+static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd,
+				   unsigned long addr, unsigned long end,
+				   phys_addr_t phys, int flags, int stage)
+{
+	int ret = 0;
+	pud_t *pud;
+	unsigned long next;
+
+#ifndef __PAGETABLE_PUD_FOLDED
+	if (pgd_none(*pgd)) {
+		pud = pud_alloc_one(NULL, addr);
+		if (!pud)
+			return -ENOMEM;
+	} else
+#endif
+		pud = pud_offset(pgd, addr);
+
+	do {
+		next = pud_addr_end(addr, end);
+		ret = arm_smmu_alloc_init_pmd(smmu, pud, addr, next, phys,
+					      flags, stage);
+		pgd_populate(NULL, pud, pgd);
+		arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd));
+		phys += next - addr;
+	} while (pud++, addr = next, addr < end);
+
+	return ret;
+}
+
+static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain,
+				   unsigned long iova, phys_addr_t paddr,
+				   size_t size, int flags)
+{
+	int ret, stage;
+	unsigned long end;
+	phys_addr_t input_mask, output_mask;
+	struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
+	pgd_t *pgd = root_cfg->pgd;
+	struct arm_smmu_device *smmu = root_cfg->smmu;
+
+	if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) {
+		stage = 2;
+		output_mask = (1ULL << smmu->s2_output_size) - 1;
+	} else {
+		stage = 1;
+		output_mask = (1ULL << smmu->s1_output_size) - 1;
+	}
+
+	if (!pgd)
+		return -EINVAL;
+
+	if (size & ~PAGE_MASK)
+		return -EINVAL;
+
+	input_mask = (1ULL << smmu->input_size) - 1;
+	if ((phys_addr_t)iova & ~input_mask)
+		return -ERANGE;
+
+	if (paddr & ~output_mask)
+		return -ERANGE;
+
+	spin_lock(&smmu_domain->lock);
+	pgd += pgd_index(iova);
+	end = iova + size;
+	do {
+		unsigned long next = pgd_addr_end(iova, end);
+
+		ret = arm_smmu_alloc_init_pud(smmu, pgd, iova, next, paddr,
+					      flags, stage);
+		if (ret)
+			goto out_unlock;
+
+		paddr += next - iova;
+		iova = next;
+	} while (pgd++, iova != end);
+
+out_unlock:
+	spin_unlock(&smmu_domain->lock);
+
+	/* Ensure new page tables are visible to the hardware walker */
+	if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+		dsb();
+
+	return ret;
+}
+
+static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
+			phys_addr_t paddr, size_t size, int flags)
+{
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_device *smmu = smmu_domain->leaf_smmu;
+
+	if (!smmu_domain || !smmu)
+		return -ENODEV;
+
+	/* Check for silent address truncation up the SMMU chain. */
+	if ((phys_addr_t)iova & ~smmu_domain->output_mask)
+		return -ERANGE;
+
+	return arm_smmu_handle_mapping(smmu_domain, iova, paddr, size, flags);
+}
+
+static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
+			     size_t size)
+{
+	int ret;
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
+	struct arm_smmu_device *smmu = root_cfg->smmu;
+	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+
+	ret = arm_smmu_handle_mapping(smmu_domain, iova, 0, size, 0);
+	writel_relaxed(root_cfg->vmid, gr0_base + ARM_SMMU_GR0_TLBIVMID);
+	arm_smmu_tlb_sync(smmu);
+	return ret ? ret : size;
+}
+
+static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
+					 dma_addr_t iova)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+	struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg;
+	struct arm_smmu_device *smmu = root_cfg->smmu;
+
+	spin_lock(&smmu_domain->lock);
+	pgd = root_cfg->pgd;
+	if (!pgd)
+		goto err_unlock;
+
+	pgd += pgd_index(iova);
+	if (pgd_none_or_clear_bad(pgd))
+		goto err_unlock;
+
+	pud = pud_offset(pgd, iova);
+	if (pud_none_or_clear_bad(pud))
+		goto err_unlock;
+
+	pmd = pmd_offset(pud, iova);
+	if (pmd_none_or_clear_bad(pmd))
+		goto err_unlock;
+
+	pte = pmd_page_vaddr(*pmd) + pte_index(iova);
+	if (pte_none(pte))
+		goto err_unlock;
+
+	spin_unlock(&smmu_domain->lock);
+	return __pfn_to_phys(pte_pfn(*pte)) | (iova & ~PAGE_MASK);
+
+err_unlock:
+	spin_unlock(&smmu_domain->lock);
+	dev_warn(smmu->dev,
+		 "invalid (corrupt?) page tables detected for iova 0x%llx\n",
+		 (unsigned long long)iova);
+	return -EINVAL;
+}
+
+static int arm_smmu_domain_has_cap(struct iommu_domain *domain,
+				   unsigned long cap)
+{
+	unsigned long caps = 0;
+	struct arm_smmu_domain *smmu_domain = domain->priv;
+
+	if (smmu_domain->root_cfg.smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+		caps |= IOMMU_CAP_CACHE_COHERENCY;
+
+	return !!(cap & caps);
+}
+
+static int arm_smmu_add_device(struct device *dev)
+{
+	struct arm_smmu_device *child, *parent, *smmu;
+	struct arm_smmu_master *master = NULL;
+
+	spin_lock(&arm_smmu_devices_lock);
+	list_for_each_entry(parent, &arm_smmu_devices, list) {
+		smmu = parent;
+
+		/* Try to find a child of the current SMMU. */
+		list_for_each_entry(child, &arm_smmu_devices, list) {
+			if (child->parent_of_node == parent->dev->of_node) {
+				/* Does the child sit above our master? */
+				master = find_smmu_master(child, dev->of_node);
+				if (master) {
+					smmu = NULL;
+					break;
+				}
+			}
+		}
+
+		/* We found some children, so keep searching. */
+		if (!smmu) {
+			master = NULL;
+			continue;
+		}
+
+		master = find_smmu_master(smmu, dev->of_node);
+		if (master)
+			break;
+	}
+	spin_unlock(&arm_smmu_devices_lock);
+
+	if (!master)
+		return -ENODEV;
+
+	dev->archdata.iommu = smmu;
+	return 0;
+}
+
+static void arm_smmu_remove_device(struct device *dev)
+{
+	dev->archdata.iommu = NULL;
+}
+
+static struct iommu_ops arm_smmu_ops = {
+	.domain_init	= arm_smmu_domain_init,
+	.domain_destroy	= arm_smmu_domain_destroy,
+	.attach_dev	= arm_smmu_attach_dev,
+	.detach_dev	= arm_smmu_detach_dev,
+	.map		= arm_smmu_map,
+	.unmap		= arm_smmu_unmap,
+	.iova_to_phys	= arm_smmu_iova_to_phys,
+	.domain_has_cap	= arm_smmu_domain_has_cap,
+	.add_device	= arm_smmu_add_device,
+	.remove_device	= arm_smmu_remove_device,
+	.pgsize_bitmap	= (SECTION_SIZE |
+			   ARM_SMMU_PTE_CONT_SIZE |
+			   PAGE_SIZE),
+};
+
+static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
+{
+	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+	int i = 0;
+	u32 scr0 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sCR0);
+
+	/* Mark all SMRn as invalid and all S2CRn as bypass */
+	for (i = 0; i < smmu->num_mapping_groups; ++i) {
+		writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(i));
+		writel_relaxed(S2CR_TYPE_BYPASS, gr0_base + ARM_SMMU_GR0_S2CR(i));
+	}
+
+	/* Invalidate the TLB, just in case */
+	writel_relaxed(0, gr0_base + ARM_SMMU_GR0_STLBIALL);
+	writel_relaxed(0, gr0_base + ARM_SMMU_GR0_TLBIALLH);
+	writel_relaxed(0, gr0_base + ARM_SMMU_GR0_TLBIALLNSNH);
+
+	/* Enable fault reporting */
+	scr0 |= (sCR0_GFRE | sCR0_GFIE | sCR0_GCFGFRE | sCR0_GCFGFIE);
+
+	/* Disable TLB broadcasting. */
+	scr0 |= (sCR0_VMIDPNE | sCR0_PTM);
+
+	/* Enable client access, but bypass when no mapping is found */
+	scr0 &= ~(sCR0_CLIENTPD | sCR0_USFCFG);
+
+	/* Disable forced broadcasting */
+	scr0 &= ~sCR0_FB;
+
+	/* Don't upgrade barriers */
+	scr0 &= ~(sCR0_BSU_MASK << sCR0_BSU_SHIFT);
+
+	/* Push the button */
+	arm_smmu_tlb_sync(smmu);
+	writel(scr0, gr0_base + ARM_SMMU_GR0_sCR0);
+}
+
+static int arm_smmu_id_size_to_bits(int size)
+{
+	switch (size) {
+	case 0:
+		return 32;
+	case 1:
+		return 36;
+	case 2:
+		return 40;
+	case 3:
+		return 42;
+	case 4:
+		return 44;
+	case 5:
+	default:
+		return 48;
+	}
+}
+
+static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
+{
+	unsigned long size;
+	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+	u32 id;
+
+	dev_notice(smmu->dev, "probing hardware configuration...\n");
+
+	/* Primecell ID */
+	id = readl_relaxed(gr0_base + ARM_SMMU_GR0_PIDR2);
+	smmu->version = ((id >> PIDR2_ARCH_SHIFT) & PIDR2_ARCH_MASK) + 1;
+	dev_notice(smmu->dev, "SMMUv%d with:\n", smmu->version);
+
+	/* ID0 */
+	id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID0);
+#ifndef CONFIG_64BIT
+	if (((id >> ID0_PTFS_SHIFT) & ID0_PTFS_MASK) == ID0_PTFS_V8_ONLY) {
+		dev_err(smmu->dev, "\tno v7 descriptor support!\n");
+		return -ENODEV;
+	}
+#endif
+	if (id & ID0_S1TS) {
+		smmu->features |= ARM_SMMU_FEAT_TRANS_S1;
+		dev_notice(smmu->dev, "\tstage 1 translation\n");
+	}
+
+	if (id & ID0_S2TS) {
+		smmu->features |= ARM_SMMU_FEAT_TRANS_S2;
+		dev_notice(smmu->dev, "\tstage 2 translation\n");
+	}
+
+	if (id & ID0_NTS) {
+		smmu->features |= ARM_SMMU_FEAT_TRANS_NESTED;
+		dev_notice(smmu->dev, "\tnested translation\n");
+	}
+
+	if (!(smmu->features &
+		(ARM_SMMU_FEAT_TRANS_S1 | ARM_SMMU_FEAT_TRANS_S2 |
+		 ARM_SMMU_FEAT_TRANS_NESTED))) {
+		dev_err(smmu->dev, "\tno translation support!\n");
+		return -ENODEV;
+	}
+
+	if (id & ID0_CTTW) {
+		smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
+		dev_notice(smmu->dev, "\tcoherent table walk\n");
+	}
+
+	if (id & ID0_SMS) {
+		u32 smr, sid, mask;
+
+		smmu->features |= ARM_SMMU_FEAT_STREAM_MATCH;
+		smmu->num_mapping_groups = (id >> ID0_NUMSMRG_SHIFT) &
+					   ID0_NUMSMRG_MASK;
+		if (smmu->num_mapping_groups == 0) {
+			dev_err(smmu->dev,
+				"stream-matching supported, but no SMRs present!\n");
+			return -ENODEV;
+		}
+
+		smr = SMR_MASK_MASK << SMR_MASK_SHIFT;
+		smr |= (SMR_ID_MASK << SMR_ID_SHIFT);
+		writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
+		smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
+
+		mask = (smr >> SMR_MASK_SHIFT) & SMR_MASK_MASK;
+		sid = (smr >> SMR_ID_SHIFT) & SMR_ID_MASK;
+		if ((mask & sid) != sid) {
+			dev_err(smmu->dev,
+				"SMR mask bits (0x%x) insufficient for ID field (0x%x)\n",
+				mask, sid);
+			return -ENODEV;
+		}
+
+		dev_notice(smmu->dev,
+			   "\tstream matching with %u register groups, mask 0x%x",
+			   smmu->num_mapping_groups, mask);
+	}
+
+	/* ID1 */
+	id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID1);
+	smmu->pagesize = (id & ID1_PAGESIZE) ? SZ_64K : SZ_4K;
+
+	/* Check that we ioremapped enough */
+	size = 1 << (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1);
+	size *= (smmu->pagesize << 1);
+	if (smmu->size < size)
+		dev_warn(smmu->dev,
+			 "device is 0x%lx bytes but only mapped 0x%lx!\n",
+			 size, smmu->size);
+
+	smmu->num_s2_context_banks = (id >> ID1_NUMS2CB_SHIFT) &
+				      ID1_NUMS2CB_MASK;
+	smmu->num_context_banks = (id >> ID1_NUMCB_SHIFT) & ID1_NUMCB_MASK;
+	if (smmu->num_s2_context_banks > smmu->num_context_banks) {
+		dev_err(smmu->dev, "impossible number of S2 context banks!\n");
+		return -ENODEV;
+	}
+	dev_notice(smmu->dev, "\t%u context banks (%u stage-2 only)\n",
+		   smmu->num_context_banks, smmu->num_s2_context_banks);
+
+	/* ID2 */
+	id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID2);
+	size = arm_smmu_id_size_to_bits((id >> ID2_IAS_SHIFT) & ID2_IAS_MASK);
+
+	/*
+	 * Stage-1 output limited by stage-2 input size due to pgd
+	 * allocation (PTRS_PER_PGD).
+	 */
+#ifdef CONFIG_64BIT
+	/* Current maximum output size of 39 bits */
+	smmu->s1_output_size = min(39UL, size);
+#else
+	smmu->s1_output_size = min(32UL, size);
+#endif
+
+	/* The stage-2 output mask is also applied for bypass */
+	size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK);
+	smmu->s2_output_size = min((unsigned long)PHYS_MASK_SHIFT, size);
+
+	if (smmu->version == 1) {
+		smmu->input_size = 32;
+	} else {
+#ifdef CONFIG_64BIT
+		size = (id >> ID2_UBS_SHIFT) & ID2_UBS_MASK;
+		size = min(39, arm_smmu_id_size_to_bits(size));
+#else
+		size = 32;
+#endif
+		smmu->input_size = size;
+
+		if ((PAGE_SIZE == SZ_4K && !(id & ID2_PTFS_4K)) ||
+		    (PAGE_SIZE == SZ_64K && !(id & ID2_PTFS_64K)) ||
+		    (PAGE_SIZE != SZ_4K && PAGE_SIZE != SZ_64K)) {
+			dev_err(smmu->dev, "CPU page size 0x%lx unsupported\n",
+				PAGE_SIZE);
+			return -ENODEV;
+		}
+	}
+
+	dev_notice(smmu->dev,
+		   "\t%lu-bit VA, %lu-bit IPA, %lu-bit PA\n",
+		   smmu->input_size, smmu->s1_output_size, smmu->s2_output_size);
+	return 0;
+}
+
+static int arm_smmu_device_dt_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct arm_smmu_device *smmu;
+	struct device_node *dev_node;
+	struct device *dev = &pdev->dev;
+	struct rb_node *node;
+	struct of_phandle_args masterspec;
+	int num_irqs, i, err;
+
+	smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
+	if (!smmu) {
+		dev_err(dev, "failed to allocate arm_smmu_device\n");
+		return -ENOMEM;
+	}
+	smmu->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "missing base address/size\n");
+		return -ENODEV;
+	}
+
+	smmu->size = resource_size(res);
+	smmu->base = devm_request_and_ioremap(dev, res);
+	if (!smmu->base)
+		return -EADDRNOTAVAIL;
+
+	if (of_property_read_u32(dev->of_node, "#global-interrupts",
+				 &smmu->num_global_irqs)) {
+		dev_err(dev, "missing #global-interrupts property\n");
+		return -ENODEV;
+	}
+
+	num_irqs = 0;
+	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) {
+		num_irqs++;
+		if (num_irqs > smmu->num_global_irqs)
+			smmu->num_context_irqs++;
+	}
+
+	if (num_irqs < smmu->num_global_irqs) {
+		dev_warn(dev, "found %d interrupts but expected at least %d\n",
+			 num_irqs, smmu->num_global_irqs);
+		smmu->num_global_irqs = num_irqs;
+	}
+	smmu->num_context_irqs = num_irqs - smmu->num_global_irqs;
+
+	smmu->irqs = devm_kzalloc(dev, sizeof(*smmu->irqs) * num_irqs,
+				  GFP_KERNEL);
+	if (!smmu->irqs) {
+		dev_err(dev, "failed to allocate %d irqs\n", num_irqs);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < num_irqs; ++i) {
+		int irq = platform_get_irq(pdev, i);
+		if (irq < 0) {
+			dev_err(dev, "failed to get irq index %d\n", i);
+			return -ENODEV;
+		}
+		smmu->irqs[i] = irq;
+	}
+
+	i = 0;
+	smmu->masters = RB_ROOT;
+	while (!of_parse_phandle_with_args(dev->of_node, "mmu-masters",
+					   "#stream-id-cells", i,
+					   &masterspec)) {
+		err = register_smmu_master(smmu, dev, &masterspec);
+		if (err) {
+			dev_err(dev, "failed to add master %s\n",
+				masterspec.np->name);
+			goto out_put_masters;
+		}
+
+		i++;
+	}
+	dev_notice(dev, "registered %d master devices\n", i);
+
+	if ((dev_node = of_parse_phandle(dev->of_node, "smmu-parent", 0)))
+		smmu->parent_of_node = dev_node;
+
+	err = arm_smmu_device_cfg_probe(smmu);
+	if (err)
+		goto out_put_parent;
+
+	if (smmu->version > 1 &&
+	    smmu->num_context_banks != smmu->num_context_irqs) {
+		dev_err(dev,
+			"found only %d context interrupt(s) but %d required\n",
+			smmu->num_context_irqs, smmu->num_context_banks);
+		goto out_put_parent;
+	}
+
+	arm_smmu_device_reset(smmu);
+
+	for (i = 0; i < smmu->num_global_irqs; ++i) {
+		err = request_irq(smmu->irqs[i],
+				  arm_smmu_global_fault,
+				  IRQF_SHARED,
+				  "arm-smmu global fault",
+				  smmu);
+		if (err) {
+			dev_err(dev, "failed to request global IRQ %d (%u)\n",
+				i, smmu->irqs[i]);
+			goto out_free_irqs;
+		}
+	}
+
+	INIT_LIST_HEAD(&smmu->list);
+	spin_lock(&arm_smmu_devices_lock);
+	list_add(&smmu->list, &arm_smmu_devices);
+	spin_unlock(&arm_smmu_devices_lock);
+	return 0;
+
+out_free_irqs:
+	while (i--)
+		free_irq(smmu->irqs[i], smmu);
+
+out_put_parent:
+	if (smmu->parent_of_node)
+		of_node_put(smmu->parent_of_node);
+
+out_put_masters:
+	for (node = rb_first(&smmu->masters); node; node = rb_next(node)) {
+		struct arm_smmu_master *master;
+		master = container_of(node, struct arm_smmu_master, node);
+		of_node_put(master->of_node);
+	}
+
+	return err;
+}
+
+static int arm_smmu_device_remove(struct platform_device *pdev)
+{
+	int i;
+	struct device *dev = &pdev->dev;
+	struct arm_smmu_device *curr, *smmu = NULL;
+	struct rb_node *node;
+
+	spin_lock(&arm_smmu_devices_lock);
+	list_for_each_entry(curr, &arm_smmu_devices, list) {
+		if (curr->dev == dev) {
+			smmu = curr;
+			list_del(&smmu->list);
+			break;
+		}
+	}
+	spin_unlock(&arm_smmu_devices_lock);
+
+	if (!smmu)
+		return -ENODEV;
+
+	if (smmu->parent_of_node)
+		of_node_put(smmu->parent_of_node);
+
+	for (node = rb_first(&smmu->masters); node; node = rb_next(node)) {
+		struct arm_smmu_master *master;
+		master = container_of(node, struct arm_smmu_master, node);
+		of_node_put(master->of_node);
+	}
+
+	if (!bitmap_empty(smmu->vmid_map, ARM_SMMU_NUM_VMIDS))
+		dev_err(dev, "removing device with active domains!\n");
+
+	for (i = 0; i < smmu->num_global_irqs; ++i)
+		free_irq(smmu->irqs[i], smmu);
+
+	/* Turn the thing off */
+	writel(sCR0_CLIENTPD, ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_sCR0);
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id arm_smmu_of_match[] = {
+	{ .compatible = "arm,smmu-v1", },
+	{ .compatible = "arm,smmu-v2", },
+	{ .compatible = "arm,mmu-400", },
+	{ .compatible = "arm,mmu-500", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
+#endif
+
+static struct platform_driver arm_smmu_driver = {
+	.driver	= {
+		.owner		= THIS_MODULE,
+		.name		= "arm-smmu",
+		.of_match_table	= of_match_ptr(arm_smmu_of_match),
+	},
+	.probe	= arm_smmu_device_dt_probe,
+	.remove	= arm_smmu_device_remove,
+};
+
+static int __init arm_smmu_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&arm_smmu_driver);
+	if (ret)
+		return ret;
+
+	/* Oh, for a proper bus abstraction */
+	if (!iommu_present(&platform_bus_type));
+		bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+
+	if (!iommu_present(&amba_bustype));
+		bus_set_iommu(&amba_bustype, &arm_smmu_ops);
+
+	return 0;
+}
+
+static void __exit arm_smmu_exit(void)
+{
+	return platform_driver_unregister(&arm_smmu_driver);
+}
+
+module_init(arm_smmu_init);
+module_exit(arm_smmu_exit);
+
+MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
+MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/dmar.c linux-libre-3.11-rc7-gnu/drivers/iommu/dmar.c
--- linux-libre-3.10-gnu/drivers/iommu/dmar.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/dmar.c	2013-08-25 20:43:22.000000000 -0400
@@ -309,6 +309,7 @@ parse_dmar_table(void)
 	struct acpi_table_dmar *dmar;
 	struct acpi_dmar_header *entry_header;
 	int ret = 0;
+	int drhd_count = 0;
 
 	/*
 	 * Do it again, earlier dmar_tbl mapping could be mapped with
@@ -347,6 +348,7 @@ parse_dmar_table(void)
 
 		switch (entry_header->type) {
 		case ACPI_DMAR_TYPE_HARDWARE_UNIT:
+			drhd_count++;
 			ret = dmar_parse_one_drhd(entry_header);
 			break;
 		case ACPI_DMAR_TYPE_RESERVED_MEMORY:
@@ -371,6 +373,8 @@ parse_dmar_table(void)
 
 		entry_header = ((void *)entry_header + entry_header->length);
 	}
+	if (drhd_count == 0)
+		pr_warn(FW_BUG "No DRHD structure found in DMAR table\n");
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/intel-iommu.c linux-libre-3.11-rc7-gnu/drivers/iommu/intel-iommu.c
--- linux-libre-3.10-gnu/drivers/iommu/intel-iommu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/intel-iommu.c	2013-08-25 20:43:22.000000000 -0400
@@ -4182,14 +4182,27 @@ static int intel_iommu_add_device(struct
 
 	/*
 	 * If it's a multifunction device that does not support our
-	 * required ACS flags, add to the same group as function 0.
+	 * required ACS flags, add to the same group as lowest numbered
+	 * function that also does not suport the required ACS flags.
 	 */
 	if (dma_pdev->multifunction &&
-	    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS))
-		swap_pci_ref(&dma_pdev,
-			     pci_get_slot(dma_pdev->bus,
-					  PCI_DEVFN(PCI_SLOT(dma_pdev->devfn),
-					  0)));
+	    !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
+		u8 i, slot = PCI_SLOT(dma_pdev->devfn);
+
+		for (i = 0; i < 8; i++) {
+			struct pci_dev *tmp;
+
+			tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
+			if (!tmp)
+				continue;
+
+			if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
+				swap_pci_ref(&dma_pdev, tmp);
+				break;
+			}
+			pci_dev_put(tmp);
+		}
+	}
 
 	/*
 	 * Devices on the root bus go through the iommu.  If that's not us,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/intel_irq_remapping.c linux-libre-3.11-rc7-gnu/drivers/iommu/intel_irq_remapping.c
--- linux-libre-3.10-gnu/drivers/iommu/intel_irq_remapping.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/intel_irq_remapping.c	2013-08-25 20:43:22.000000000 -0400
@@ -664,8 +664,7 @@ error:
 	 */
 
 	if (x2apic_present)
-		WARN(1, KERN_WARNING
-			"Failed to enable irq remapping.  You are vulnerable to irq-injection attacks.\n");
+		pr_warn("Failed to enable irq remapping.  You are vulnerable to irq-injection attacks.\n");
 
 	return -1;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/iommu.c linux-libre-3.11-rc7-gnu/drivers/iommu/iommu.c
--- linux-libre-3.10-gnu/drivers/iommu/iommu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/iommu.c	2013-08-25 20:43:22.000000000 -0400
@@ -754,6 +754,38 @@ int iommu_domain_has_cap(struct iommu_do
 }
 EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
 
+static size_t iommu_pgsize(struct iommu_domain *domain,
+			   unsigned long addr_merge, size_t size)
+{
+	unsigned int pgsize_idx;
+	size_t pgsize;
+
+	/* Max page size that still fits into 'size' */
+	pgsize_idx = __fls(size);
+
+	/* need to consider alignment requirements ? */
+	if (likely(addr_merge)) {
+		/* Max page size allowed by address */
+		unsigned int align_pgsize_idx = __ffs(addr_merge);
+		pgsize_idx = min(pgsize_idx, align_pgsize_idx);
+	}
+
+	/* build a mask of acceptable page sizes */
+	pgsize = (1UL << (pgsize_idx + 1)) - 1;
+
+	/* throw away page sizes not supported by the hardware */
+	pgsize &= domain->ops->pgsize_bitmap;
+
+	/* make sure we're still sane */
+	BUG_ON(!pgsize);
+
+	/* pick the biggest page */
+	pgsize_idx = __fls(pgsize);
+	pgsize = 1UL << pgsize_idx;
+
+	return pgsize;
+}
+
 int iommu_map(struct iommu_domain *domain, unsigned long iova,
 	      phys_addr_t paddr, size_t size, int prot)
 {
@@ -775,45 +807,18 @@ int iommu_map(struct iommu_domain *domai
 	 * size of the smallest page supported by the hardware
 	 */
 	if (!IS_ALIGNED(iova | paddr | size, min_pagesz)) {
-		pr_err("unaligned: iova 0x%lx pa 0x%lx size 0x%lx min_pagesz "
-			"0x%x\n", iova, (unsigned long)paddr,
-			(unsigned long)size, min_pagesz);
+		pr_err("unaligned: iova 0x%lx pa 0x%pa size 0x%zx min_pagesz 0x%x\n",
+		       iova, &paddr, size, min_pagesz);
 		return -EINVAL;
 	}
 
-	pr_debug("map: iova 0x%lx pa 0x%lx size 0x%lx\n", iova,
-				(unsigned long)paddr, (unsigned long)size);
+	pr_debug("map: iova 0x%lx pa 0x%pa size 0x%zx\n", iova, &paddr, size);
 
 	while (size) {
-		unsigned long pgsize, addr_merge = iova | paddr;
-		unsigned int pgsize_idx;
-
-		/* Max page size that still fits into 'size' */
-		pgsize_idx = __fls(size);
-
-		/* need to consider alignment requirements ? */
-		if (likely(addr_merge)) {
-			/* Max page size allowed by both iova and paddr */
-			unsigned int align_pgsize_idx = __ffs(addr_merge);
-
-			pgsize_idx = min(pgsize_idx, align_pgsize_idx);
-		}
-
-		/* build a mask of acceptable page sizes */
-		pgsize = (1UL << (pgsize_idx + 1)) - 1;
-
-		/* throw away page sizes not supported by the hardware */
-		pgsize &= domain->ops->pgsize_bitmap;
-
-		/* make sure we're still sane */
-		BUG_ON(!pgsize);
-
-		/* pick the biggest page */
-		pgsize_idx = __fls(pgsize);
-		pgsize = 1UL << pgsize_idx;
+		size_t pgsize = iommu_pgsize(domain, iova | paddr, size);
 
-		pr_debug("mapping: iova 0x%lx pa 0x%lx pgsize %lu\n", iova,
-					(unsigned long)paddr, pgsize);
+		pr_debug("mapping: iova 0x%lx pa 0x%pa pgsize 0x%zx\n",
+			 iova, &paddr, pgsize);
 
 		ret = domain->ops->map(domain, iova, paddr, pgsize, prot);
 		if (ret)
@@ -850,27 +855,26 @@ size_t iommu_unmap(struct iommu_domain *
 	 * by the hardware
 	 */
 	if (!IS_ALIGNED(iova | size, min_pagesz)) {
-		pr_err("unaligned: iova 0x%lx size 0x%lx min_pagesz 0x%x\n",
-					iova, (unsigned long)size, min_pagesz);
+		pr_err("unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%x\n",
+		       iova, size, min_pagesz);
 		return -EINVAL;
 	}
 
-	pr_debug("unmap this: iova 0x%lx size 0x%lx\n", iova,
-							(unsigned long)size);
+	pr_debug("unmap this: iova 0x%lx size 0x%zx\n", iova, size);
 
 	/*
 	 * Keep iterating until we either unmap 'size' bytes (or more)
 	 * or we hit an area that isn't mapped.
 	 */
 	while (unmapped < size) {
-		size_t left = size - unmapped;
+		size_t pgsize = iommu_pgsize(domain, iova, size - unmapped);
 
-		unmapped_page = domain->ops->unmap(domain, iova, left);
+		unmapped_page = domain->ops->unmap(domain, iova, pgsize);
 		if (!unmapped_page)
 			break;
 
-		pr_debug("unmapped: iova 0x%lx size %lx\n", iova,
-					(unsigned long)unmapped_page);
+		pr_debug("unmapped: iova 0x%lx size 0x%zx\n",
+			 iova, unmapped_page);
 
 		iova += unmapped_page;
 		unmapped += unmapped_page;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/irq_remapping.c linux-libre-3.11-rc7-gnu/drivers/iommu/irq_remapping.c
--- linux-libre-3.10-gnu/drivers/iommu/irq_remapping.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/irq_remapping.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,26 +51,27 @@ static void irq_remapping_disable_io_api
 
 static int do_setup_msi_irqs(struct pci_dev *dev, int nvec)
 {
-	int node, ret, sub_handle, index = 0;
+	int node, ret, sub_handle, nvec_pow2, index = 0;
 	unsigned int irq;
 	struct msi_desc *msidesc;
 
-	nvec = __roundup_pow_of_two(nvec);
-
 	WARN_ON(!list_is_singular(&dev->msi_list));
 	msidesc = list_entry(dev->msi_list.next, struct msi_desc, list);
 	WARN_ON(msidesc->irq);
 	WARN_ON(msidesc->msi_attrib.multiple);
+	WARN_ON(msidesc->nvec_used);
 
 	node = dev_to_node(&dev->dev);
 	irq = __create_irqs(get_nr_irqs_gsi(), nvec, node);
 	if (irq == 0)
 		return -ENOSPC;
 
-	msidesc->msi_attrib.multiple = ilog2(nvec);
+	nvec_pow2 = __roundup_pow_of_two(nvec);
+	msidesc->nvec_used = nvec;
+	msidesc->msi_attrib.multiple = ilog2(nvec_pow2);
 	for (sub_handle = 0; sub_handle < nvec; sub_handle++) {
 		if (!sub_handle) {
-			index = msi_alloc_remapped_irq(dev, irq, nvec);
+			index = msi_alloc_remapped_irq(dev, irq, nvec_pow2);
 			if (index < 0) {
 				ret = index;
 				goto error;
@@ -95,6 +96,7 @@ error:
 	 * IRQs from tearing down again in default_teardown_msi_irqs()
 	 */
 	msidesc->irq = 0;
+	msidesc->nvec_used = 0;
 	msidesc->msi_attrib.multiple = 0;
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/Kconfig linux-libre-3.11-rc7-gnu/drivers/iommu/Kconfig
--- linux-libre-3.10-gnu/drivers/iommu/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -261,4 +261,25 @@ config SHMOBILE_IOMMU_L1SIZE
 	default 256 if SHMOBILE_IOMMU_ADDRSIZE_64MB
 	default 128 if SHMOBILE_IOMMU_ADDRSIZE_32MB
 
+config SPAPR_TCE_IOMMU
+	bool "sPAPR TCE IOMMU Support"
+	depends on PPC_POWERNV || PPC_PSERIES
+	select IOMMU_API
+	help
+	  Enables bits of IOMMU API required by VFIO. The iommu_ops
+	  is not implemented as it is not necessary for VFIO.
+
+config ARM_SMMU
+	bool "ARM Ltd. System MMU (SMMU) Support"
+	depends on ARM64 || (ARM_LPAE && OF)
+	select IOMMU_API
+	select ARM_DMA_USE_IOMMU if ARM
+	help
+	  Support for implementations of the ARM System MMU architecture
+	  versions 1 and 2. The driver supports both v7l and v8l table
+	  formats with 4k and 64k page sizes.
+
+	  Say Y here if your SoC includes an IOMMU device implementing
+	  the ARM SMMU architecture.
+
 endif # IOMMU_SUPPORT
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/Makefile linux-libre-3.11-rc7-gnu/drivers/iommu/Makefile
--- linux-libre-3.10-gnu/drivers/iommu/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,6 +3,7 @@ obj-$(CONFIG_OF_IOMMU)	+= of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
+obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o
 obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/msm_iommu_dev.c linux-libre-3.11-rc7-gnu/drivers/iommu/msm_iommu_dev.c
--- linux-libre-3.10-gnu/drivers/iommu/msm_iommu_dev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/msm_iommu_dev.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
 
 #include <mach/iommu_hw-8xxx.h>
 #include <mach/iommu.h>
-#include <mach/clk.h>
 
 struct iommu_ctx_iter_data {
 	/* input */
@@ -160,7 +159,7 @@ static int msm_iommu_probe(struct platfo
 		goto fail;
 	}
 
-	ret = clk_enable(iommu_pclk);
+	ret = clk_prepare_enable(iommu_pclk);
 	if (ret)
 		goto fail_enable;
 
@@ -168,9 +167,9 @@ static int msm_iommu_probe(struct platfo
 
 	if (!IS_ERR(iommu_clk))	{
 		if (clk_get_rate(iommu_clk) == 0)
-			clk_set_min_rate(iommu_clk, 1);
+			clk_set_rate(iommu_clk, 1);
 
-		ret = clk_enable(iommu_clk);
+		ret = clk_prepare_enable(iommu_clk);
 		if (ret) {
 			clk_put(iommu_clk);
 			goto fail_pclk;
@@ -261,7 +260,7 @@ fail_clk:
 		clk_put(iommu_clk);
 	}
 fail_pclk:
-	clk_disable(iommu_pclk);
+	clk_disable_unprepare(iommu_pclk);
 fail_enable:
 	clk_put(iommu_pclk);
 fail:
@@ -275,8 +274,11 @@ static int msm_iommu_remove(struct platf
 
 	drv = platform_get_drvdata(pdev);
 	if (drv) {
-		if (drv->clk)
+		if (drv->clk) {
+			clk_unprepare(drv->clk);
 			clk_put(drv->clk);
+		}
+		clk_unprepare(drv->pclk);
 		clk_put(drv->pclk);
 		memset(drv, 0, sizeof(*drv));
 		kfree(drv);
@@ -289,39 +291,34 @@ static int msm_iommu_ctx_probe(struct pl
 {
 	struct msm_iommu_ctx_dev *c = pdev->dev.platform_data;
 	struct msm_iommu_drvdata *drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL;
+	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 	int i, ret;
-	if (!c || !pdev->dev.parent) {
-		ret = -EINVAL;
-		goto fail;
-	}
 
-	drvdata = dev_get_drvdata(pdev->dev.parent);
+	if (!c || !pdev->dev.parent)
+		return -EINVAL;
 
-	if (!drvdata) {
-		ret = -ENODEV;
-		goto fail;
-	}
+	drvdata = dev_get_drvdata(pdev->dev.parent);
+	if (!drvdata)
+		return -ENODEV;
 
 	ctx_drvdata = kzalloc(sizeof(*ctx_drvdata), GFP_KERNEL);
-	if (!ctx_drvdata) {
-		ret = -ENOMEM;
-		goto fail;
-	}
+	if (!ctx_drvdata)
+		return -ENOMEM;
+
 	ctx_drvdata->num = c->num;
 	ctx_drvdata->pdev = pdev;
 
 	INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
 	platform_set_drvdata(pdev, ctx_drvdata);
 
-	ret = clk_enable(drvdata->pclk);
+	ret = clk_prepare_enable(drvdata->pclk);
 	if (ret)
 		goto fail;
 
 	if (drvdata->clk) {
-		ret = clk_enable(drvdata->clk);
+		ret = clk_prepare_enable(drvdata->clk);
 		if (ret) {
-			clk_disable(drvdata->pclk);
+			clk_disable_unprepare(drvdata->pclk);
 			goto fail;
 		}
 	}
@@ -401,6 +398,7 @@ static int __init msm_iommu_driver_init(
 
 	ret = platform_driver_register(&msm_iommu_ctx_driver);
 	if (ret != 0) {
+		platform_driver_unregister(&msm_iommu_driver);
 		pr_err("Failed to register IOMMU context driver\n");
 		goto error;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/omap-iommu.c linux-libre-3.11-rc7-gnu/drivers/iommu/omap-iommu.c
--- linux-libre-3.10-gnu/drivers/iommu/omap-iommu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/omap-iommu.c	2013-08-25 20:43:22.000000000 -0400
@@ -833,16 +833,15 @@ static irqreturn_t iommu_fault_handler(i
 	iopgd = iopgd_offset(obj, da);
 
 	if (!iopgd_is_table(*iopgd)) {
-		dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p "
-			"*pgd:px%08x\n", obj->name, errs, da, iopgd, *iopgd);
+		dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p *pgd:px%08x\n",
+				obj->name, errs, da, iopgd, *iopgd);
 		return IRQ_NONE;
 	}
 
 	iopte = iopte_offset(iopgd, da);
 
-	dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p *pgd:0x%08x "
-		"pte:0x%p *pte:0x%08x\n", obj->name, errs, da, iopgd, *iopgd,
-		iopte, *iopte);
+	dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p *pgd:0x%08x pte:0x%p *pte:0x%08x\n",
+			obj->name, errs, da, iopgd, *iopgd, iopte, *iopte);
 
 	return IRQ_NONE;
 }
@@ -1235,14 +1234,16 @@ static phys_addr_t omap_iommu_iova_to_ph
 		else if (iopte_is_large(*pte))
 			ret = omap_iommu_translate(*pte, da, IOLARGE_MASK);
 		else
-			dev_err(dev, "bogus pte 0x%x, da 0x%lx", *pte, da);
+			dev_err(dev, "bogus pte 0x%x, da 0x%llx", *pte,
+							(unsigned long long)da);
 	} else {
 		if (iopgd_is_section(*pgd))
 			ret = omap_iommu_translate(*pgd, da, IOSECTION_MASK);
 		else if (iopgd_is_super(*pgd))
 			ret = omap_iommu_translate(*pgd, da, IOSUPER_MASK);
 		else
-			dev_err(dev, "bogus pgd 0x%x, da 0x%lx", *pgd, da);
+			dev_err(dev, "bogus pgd 0x%x, da 0x%llx", *pgd,
+							(unsigned long long)da);
 	}
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/omap-iopgtable.h linux-libre-3.11-rc7-gnu/drivers/iommu/omap-iopgtable.h
--- linux-libre-3.10-gnu/drivers/iommu/omap-iopgtable.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/omap-iopgtable.h	2013-08-25 20:43:22.000000000 -0400
@@ -95,4 +95,4 @@ static inline phys_addr_t omap_iommu_tra
 #define iopte_offset(iopgd, da)	(iopgd_page_vaddr(iopgd) + iopte_index(da))
 
 #define to_iommu(dev)							\
-	(struct omap_iommu *)platform_get_drvdata(to_platform_device(dev))
+	((struct omap_iommu *)platform_get_drvdata(to_platform_device(dev)))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/iommu/omap-iovmm.c linux-libre-3.11-rc7-gnu/drivers/iommu/omap-iovmm.c
--- linux-libre-3.10-gnu/drivers/iommu/omap-iovmm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/iommu/omap-iovmm.c	2013-08-25 20:43:22.000000000 -0400
@@ -102,8 +102,8 @@ static size_t sgtable_len(const struct s
 		}
 
 		if (i && sg->offset) {
-			pr_err("%s: sg[%d] offset not allowed in internal "
-					"entries\n", __func__, i);
+			pr_err("%s: sg[%d] offset not allowed in internal entries\n",
+				__func__, i);
 			return 0;
 		}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/exynos-combiner.c linux-libre-3.11-rc7-gnu/drivers/irqchip/exynos-combiner.c
--- linux-libre-3.10-gnu/drivers/irqchip/exynos-combiner.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/exynos-combiner.c	2013-08-25 20:43:22.000000000 -0400
@@ -204,10 +204,10 @@ static unsigned int combiner_lookup_irq(
 	return 0;
 }
 
-void __init combiner_init(void __iomem *combiner_base,
-			  struct device_node *np,
-			  unsigned int max_nr,
-			  int irq_base)
+static void __init combiner_init(void __iomem *combiner_base,
+				 struct device_node *np,
+				 unsigned int max_nr,
+				 int irq_base)
 {
 	int i, irq;
 	unsigned int nr_irq;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/irq-gic.c linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-gic.c
--- linux-libre-3.10-gnu/drivers/irqchip/irq-gic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-gic.c	2013-08-25 20:43:22.000000000 -0400
@@ -414,7 +414,7 @@ static void __init gic_dist_init(struct
 	writel_relaxed(1, base + GIC_DIST_CTRL);
 }
 
-static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
+static void gic_cpu_init(struct gic_chip_data *gic)
 {
 	void __iomem *dist_base = gic_data_dist_base(gic);
 	void __iomem *base = gic_data_cpu_base(gic);
@@ -702,8 +702,8 @@ static int gic_irq_domain_xlate(struct i
 }
 
 #ifdef CONFIG_SMP
-static int __cpuinit gic_secondary_init(struct notifier_block *nfb,
-					unsigned long action, void *hcpu)
+static int gic_secondary_init(struct notifier_block *nfb, unsigned long action,
+			      void *hcpu)
 {
 	if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
 		gic_cpu_init(&gic_data[0]);
@@ -714,7 +714,7 @@ static int __cpuinit gic_secondary_init(
  * Notifier for enabling the GIC CPU interface. Set an arbitrarily high
  * priority because the GIC needs to be up before the ARM generic timers.
  */
-static struct notifier_block __cpuinitdata gic_cpu_notifier = {
+static struct notifier_block gic_cpu_notifier = {
 	.notifier_call = gic_secondary_init,
 	.priority = 100,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/irq-moxart.c linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-moxart.c
--- linux-libre-3.10-gnu/drivers/irqchip/irq-moxart.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-moxart.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,117 @@
+/*
+ * MOXA ART SoCs IRQ chip driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define IRQ_SOURCE_REG		0
+#define IRQ_MASK_REG		0x04
+#define IRQ_CLEAR_REG		0x08
+#define IRQ_MODE_REG		0x0c
+#define IRQ_LEVEL_REG		0x10
+#define IRQ_STATUS_REG		0x14
+
+#define FIQ_SOURCE_REG		0x20
+#define FIQ_MASK_REG		0x24
+#define FIQ_CLEAR_REG		0x28
+#define FIQ_MODE_REG		0x2c
+#define FIQ_LEVEL_REG		0x30
+#define FIQ_STATUS_REG		0x34
+
+
+struct moxart_irq_data {
+	void __iomem *base;
+	struct irq_domain *domain;
+	unsigned int interrupt_mask;
+};
+
+static struct moxart_irq_data intc;
+
+static asmlinkage void __exception_irq_entry handle_irq(struct pt_regs *regs)
+{
+	u32 irqstat;
+	int hwirq;
+
+	irqstat = readl(intc.base + IRQ_STATUS_REG);
+
+	while (irqstat) {
+		hwirq = ffs(irqstat) - 1;
+		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
+		irqstat &= ~(1 << hwirq);
+	}
+}
+
+static int __init moxart_of_intc_init(struct device_node *node,
+				      struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+	struct irq_chip_generic *gc;
+
+	intc.base = of_iomap(node, 0);
+	if (!intc.base) {
+		pr_err("%s: unable to map IC registers\n",
+		       node->full_name);
+		return -EINVAL;
+	}
+
+	intc.domain = irq_domain_add_linear(node, 32, &irq_generic_chip_ops,
+					    intc.base);
+	if (!intc.domain) {
+		pr_err("%s: unable to create IRQ domain\n", node->full_name);
+		return -EINVAL;
+	}
+
+	ret = irq_alloc_domain_generic_chips(intc.domain, 32, 1,
+					     "MOXARTINTC", handle_edge_irq,
+					     clr, 0, IRQ_GC_INIT_MASK_CACHE);
+	if (ret) {
+		pr_err("%s: could not allocate generic chip\n",
+		       node->full_name);
+		irq_domain_remove(intc.domain);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(node, "interrupt-mask",
+				   &intc.interrupt_mask);
+	if (ret)
+		pr_err("%s: could not read interrupt-mask DT property\n",
+		       node->full_name);
+
+	gc = irq_get_domain_generic_chip(intc.domain, 0);
+
+	gc->reg_base = intc.base;
+	gc->chip_types[0].regs.mask = IRQ_MASK_REG;
+	gc->chip_types[0].regs.ack = IRQ_CLEAR_REG;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+	writel(0, intc.base + IRQ_MASK_REG);
+	writel(0xffffffff, intc.base + IRQ_CLEAR_REG);
+
+	writel(intc.interrupt_mask, intc.base + IRQ_MODE_REG);
+	writel(intc.interrupt_mask, intc.base + IRQ_LEVEL_REG);
+
+	set_handle_irq(handle_irq);
+
+	return 0;
+}
+IRQCHIP_DECLARE(moxa_moxart_ic, "moxa,moxart-ic", moxart_of_intc_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/irq-nvic.c linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-nvic.c
--- linux-libre-3.10-gnu/drivers/irqchip/irq-nvic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-nvic.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,117 @@
+/*
+ * drivers/irq/irq-nvic.c
+ *
+ * Copyright (C) 2008 ARM Limited, All Rights Reserved.
+ * Copyright (C) 2013 Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Support for the Nested Vectored Interrupt Controller found on the
+ * ARMv7-M CPUs (Cortex-M3/M4)
+ */
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+
+#include <asm/v7m.h>
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define NVIC_ISER		0x000
+#define NVIC_ICER		0x080
+#define NVIC_IPR		0x300
+
+#define NVIC_MAX_BANKS		16
+/*
+ * Each bank handles 32 irqs. Only the 16th (= last) bank handles only
+ * 16 irqs.
+ */
+#define NVIC_MAX_IRQ		((NVIC_MAX_BANKS - 1) * 32 + 16)
+
+static struct irq_domain *nvic_irq_domain;
+
+asmlinkage void __exception_irq_entry
+nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
+{
+	unsigned int irq = irq_linear_revmap(nvic_irq_domain, hwirq);
+
+	handle_IRQ(irq, regs);
+}
+
+static void nvic_eoi(struct irq_data *d)
+{
+	/*
+	 * This is a no-op as end of interrupt is signaled by the exception
+	 * return sequence.
+	 */
+}
+
+static int __init nvic_of_init(struct device_node *node,
+			       struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	unsigned int irqs, i, ret, numbanks;
+	void __iomem *nvic_base;
+
+	numbanks = (readl_relaxed(V7M_SCS_ICTR) &
+		    V7M_SCS_ICTR_INTLINESNUM_MASK) + 1;
+
+	nvic_base = of_iomap(node, 0);
+	if (!nvic_base) {
+		pr_warn("unable to map nvic registers\n");
+		return -ENOMEM;
+	}
+
+	irqs = numbanks * 32;
+	if (irqs > NVIC_MAX_IRQ)
+		irqs = NVIC_MAX_IRQ;
+
+	nvic_irq_domain =
+		irq_domain_add_linear(node, irqs, &irq_generic_chip_ops, NULL);
+	if (!nvic_irq_domain) {
+		pr_warn("Failed to allocate irq domain\n");
+		return -ENOMEM;
+	}
+
+	ret = irq_alloc_domain_generic_chips(nvic_irq_domain, 32, 1,
+					     "nvic_irq", handle_fasteoi_irq,
+					     clr, 0, IRQ_GC_INIT_MASK_CACHE);
+	if (ret) {
+		pr_warn("Failed to allocate irq chips\n");
+		irq_domain_remove(nvic_irq_domain);
+		return ret;
+	}
+
+	for (i = 0; i < numbanks; ++i) {
+		struct irq_chip_generic *gc;
+
+		gc = irq_get_domain_generic_chip(nvic_irq_domain, 32 * i);
+		gc->reg_base = nvic_base + 4 * i;
+		gc->chip_types[0].regs.enable = NVIC_ISER;
+		gc->chip_types[0].regs.disable = NVIC_ICER;
+		gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg;
+		gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg;
+		gc->chip_types[0].chip.irq_eoi = nvic_eoi;
+
+		/* disable interrupts */
+		writel_relaxed(~0, gc->reg_base + NVIC_ICER);
+	}
+
+	/* Set priority on all interrupts */
+	for (i = 0; i < irqs; i += 4)
+		writel_relaxed(0, nvic_base + NVIC_IPR + i);
+
+	return 0;
+}
+IRQCHIP_DECLARE(armv7m_nvic, "arm,armv7m-nvic", nvic_of_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/irq-orion.c linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-orion.c
--- linux-libre-3.10-gnu/drivers/irqchip/irq-orion.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-orion.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,192 @@
+/*
+ * Marvell Orion SoCs IRQ chip driver.
+ *
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+
+#include "irqchip.h"
+
+/*
+ * Orion SoC main interrupt controller
+ */
+#define ORION_IRQS_PER_CHIP		32
+
+#define ORION_IRQ_CAUSE			0x00
+#define ORION_IRQ_MASK			0x04
+#define ORION_IRQ_FIQ_MASK		0x08
+#define ORION_IRQ_ENDP_MASK		0x0c
+
+static struct irq_domain *orion_irq_domain;
+
+static asmlinkage void
+__exception_irq_entry orion_handle_irq(struct pt_regs *regs)
+{
+	struct irq_domain_chip_generic *dgc = orion_irq_domain->gc;
+	int n, base = 0;
+
+	for (n = 0; n < dgc->num_chips; n++, base += ORION_IRQS_PER_CHIP) {
+		struct irq_chip_generic *gc =
+			irq_get_domain_generic_chip(orion_irq_domain, base);
+		u32 stat = readl_relaxed(gc->reg_base + ORION_IRQ_CAUSE) &
+			gc->mask_cache;
+		while (stat) {
+			u32 hwirq = ffs(stat) - 1;
+			u32 irq = irq_find_mapping(orion_irq_domain,
+						   gc->irq_base + hwirq);
+			handle_IRQ(irq, regs);
+			stat &= ~(1 << hwirq);
+		}
+	}
+}
+
+static int __init orion_irq_init(struct device_node *np,
+				 struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int n, ret, base, num_chips = 0;
+	struct resource r;
+
+	/* count number of irq chips by valid reg addresses */
+	while (of_address_to_resource(np, num_chips, &r) == 0)
+		num_chips++;
+
+	orion_irq_domain = irq_domain_add_linear(np,
+				num_chips * ORION_IRQS_PER_CHIP,
+				&irq_generic_chip_ops, NULL);
+	if (!orion_irq_domain)
+		panic("%s: unable to add irq domain\n", np->name);
+
+	ret = irq_alloc_domain_generic_chips(orion_irq_domain,
+				ORION_IRQS_PER_CHIP, 1, np->name,
+				handle_level_irq, clr, 0,
+				IRQ_GC_INIT_MASK_CACHE);
+	if (ret)
+		panic("%s: unable to alloc irq domain gc\n", np->name);
+
+	for (n = 0, base = 0; n < num_chips; n++, base += ORION_IRQS_PER_CHIP) {
+		struct irq_chip_generic *gc =
+			irq_get_domain_generic_chip(orion_irq_domain, base);
+
+		of_address_to_resource(np, n, &r);
+
+		if (!request_mem_region(r.start, resource_size(&r), np->name))
+			panic("%s: unable to request mem region %d",
+			      np->name, n);
+
+		gc->reg_base = ioremap(r.start, resource_size(&r));
+		if (!gc->reg_base)
+			panic("%s: unable to map resource %d", np->name, n);
+
+		gc->chip_types[0].regs.mask = ORION_IRQ_MASK;
+		gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+		gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+		/* mask all interrupts */
+		writel(0, gc->reg_base + ORION_IRQ_MASK);
+	}
+
+	set_handle_irq(orion_handle_irq);
+	return 0;
+}
+IRQCHIP_DECLARE(orion_intc, "marvell,orion-intc", orion_irq_init);
+
+/*
+ * Orion SoC bridge interrupt controller
+ */
+#define ORION_BRIDGE_IRQ_CAUSE	0x00
+#define ORION_BRIDGE_IRQ_MASK	0x04
+
+static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_domain *d = irq_get_handler_data(irq);
+	struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, irq);
+	u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) &
+		   gc->mask_cache;
+
+	while (stat) {
+		u32 hwirq = ffs(stat) - 1;
+
+		generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq));
+		stat &= ~(1 << hwirq);
+	}
+}
+
+static int __init orion_bridge_irq_init(struct device_node *np,
+					struct device_node *parent)
+{
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	struct resource r;
+	struct irq_domain *domain;
+	struct irq_chip_generic *gc;
+	int ret, irq, nrirqs = 32;
+
+	/* get optional number of interrupts provided */
+	of_property_read_u32(np, "marvell,#interrupts", &nrirqs);
+
+	domain = irq_domain_add_linear(np, nrirqs,
+				       &irq_generic_chip_ops, NULL);
+	if (!domain) {
+		pr_err("%s: unable to add irq domain\n", np->name);
+		return -ENOMEM;
+	}
+
+	ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name,
+			     handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE);
+	if (ret) {
+		pr_err("%s: unable to alloc irq domain gc\n", np->name);
+		return ret;
+	}
+
+	ret = of_address_to_resource(np, 0, &r);
+	if (ret) {
+		pr_err("%s: unable to get resource\n", np->name);
+		return ret;
+	}
+
+	if (!request_mem_region(r.start, resource_size(&r), np->name)) {
+		pr_err("%s: unable to request mem region\n", np->name);
+		return -ENOMEM;
+	}
+
+	/* Map the parent interrupt for the chained handler */
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq <= 0) {
+		pr_err("%s: unable to parse irq\n", np->name);
+		return -EINVAL;
+	}
+
+	gc = irq_get_domain_generic_chip(domain, 0);
+	gc->reg_base = ioremap(r.start, resource_size(&r));
+	if (!gc->reg_base) {
+		pr_err("%s: unable to map resource\n", np->name);
+		return -ENOMEM;
+	}
+
+	gc->chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE;
+	gc->chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK;
+	gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+
+	/* mask all interrupts */
+	writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK);
+
+	irq_set_handler_data(irq, domain);
+	irq_set_chained_handler(irq, orion_bridge_irq_handler);
+
+	return 0;
+}
+IRQCHIP_DECLARE(orion_bridge_intc,
+		"marvell,orion-bridge-intc", orion_bridge_irq_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/irq-renesas-intc-irqpin.c linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-renesas-intc-irqpin.c
--- linux-libre-3.10-gnu/drivers/irqchip/irq-renesas-intc-irqpin.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-renesas-intc-irqpin.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
@@ -347,8 +348,14 @@ static int intc_irqpin_probe(struct plat
 	}
 
 	/* deal with driver instance configuration */
-	if (pdata)
+	if (pdata) {
 		memcpy(&p->config, pdata, sizeof(*pdata));
+	} else {
+		of_property_read_u32(pdev->dev.of_node, "sense-bitfield-width",
+				     &p->config.sense_bitfield_width);
+		p->config.control_parent = of_property_read_bool(pdev->dev.of_node,
+								 "control-parent");
+	}
 	if (!p->config.sense_bitfield_width)
 		p->config.sense_bitfield_width = 4; /* default to 4 bits */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/irq-renesas-irqc.c linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-renesas-irqc.c
--- linux-libre-3.10-gnu/drivers/irqchip/irq-renesas-irqc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-renesas-irqc.c	2013-08-25 20:43:22.000000000 -0400
@@ -248,8 +248,8 @@ static int irqc_probe(struct platform_de
 
 	return 0;
 err3:
-	for (; k >= 0; k--)
-		free_irq(p->irq[k - 1].requested_irq, &p->irq[k - 1]);
+	while (--k >= 0)
+		free_irq(p->irq[k].requested_irq, &p->irq[k]);
 
 	irq_domain_remove(p->irq_domain);
 err2:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/irq-sun4i.c linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-sun4i.c
--- linux-libre-3.10-gnu/drivers/irqchip/irq-sun4i.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-sun4i.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,7 @@ static struct irq_domain *sun4i_irq_doma
 
 static asmlinkage void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs);
 
-void sun4i_irq_ack(struct irq_data *irqd)
+static void sun4i_irq_ack(struct irq_data *irqd)
 {
 	unsigned int irq = irqd_to_hwirq(irqd);
 	unsigned int irq_off = irq % 32;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/irq-tb10x.c linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-tb10x.c
--- linux-libre-3.10-gnu/drivers/irqchip/irq-tb10x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-tb10x.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,195 @@
+/*
+ * Abilis Systems interrupt controller driver
+ *
+ * Copyright (C) Abilis Systems 2012
+ *
+ * Author: Christian Ruppert <christian.ruppert@abilis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include "irqchip.h"
+
+#define AB_IRQCTL_INT_ENABLE   0x00
+#define AB_IRQCTL_INT_STATUS   0x04
+#define AB_IRQCTL_SRC_MODE     0x08
+#define AB_IRQCTL_SRC_POLARITY 0x0C
+#define AB_IRQCTL_INT_MODE     0x10
+#define AB_IRQCTL_INT_POLARITY 0x14
+#define AB_IRQCTL_INT_FORCE    0x18
+
+#define AB_IRQCTL_MAXIRQ       32
+
+static inline void ab_irqctl_writereg(struct irq_chip_generic *gc, u32 reg,
+	u32 val)
+{
+	irq_reg_writel(val, gc->reg_base + reg);
+}
+
+static inline u32 ab_irqctl_readreg(struct irq_chip_generic *gc, u32 reg)
+{
+	return irq_reg_readl(gc->reg_base + reg);
+}
+
+static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type)
+{
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+	uint32_t im, mod, pol;
+
+	im = data->mask;
+
+	irq_gc_lock(gc);
+
+	mod = ab_irqctl_readreg(gc, AB_IRQCTL_SRC_MODE) | im;
+	pol = ab_irqctl_readreg(gc, AB_IRQCTL_SRC_POLARITY) | im;
+
+	switch (flow_type & IRQF_TRIGGER_MASK) {
+	case IRQ_TYPE_EDGE_FALLING:
+		pol ^= im;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		mod ^= im;
+		break;
+	case IRQ_TYPE_NONE:
+		flow_type = IRQ_TYPE_LEVEL_LOW;
+	case IRQ_TYPE_LEVEL_LOW:
+		mod ^= im;
+		pol ^= im;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		break;
+	default:
+		irq_gc_unlock(gc);
+		pr_err("%s: Cannot assign multiple trigger modes to IRQ %d.\n",
+			__func__, data->irq);
+		return -EBADR;
+	}
+
+	irqd_set_trigger_type(data, flow_type);
+	irq_setup_alt_chip(data, flow_type);
+
+	ab_irqctl_writereg(gc, AB_IRQCTL_SRC_MODE, mod);
+	ab_irqctl_writereg(gc, AB_IRQCTL_SRC_POLARITY, pol);
+	ab_irqctl_writereg(gc, AB_IRQCTL_INT_STATUS, im);
+
+	irq_gc_unlock(gc);
+
+	return IRQ_SET_MASK_OK;
+}
+
+static void tb10x_irq_cascade(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_domain *domain = irq_desc_get_handler_data(desc);
+
+	generic_handle_irq(irq_find_mapping(domain, irq));
+}
+
+static int __init of_tb10x_init_irq(struct device_node *ictl,
+					struct device_node *parent)
+{
+	int i, ret, nrirqs = of_irq_count(ictl);
+	struct resource mem;
+	struct irq_chip_generic *gc;
+	struct irq_domain *domain;
+	void __iomem *reg_base;
+
+	if (of_address_to_resource(ictl, 0, &mem)) {
+		pr_err("%s: No registers declared in DeviceTree.\n",
+			ictl->name);
+		return -EINVAL;
+	}
+
+	if (!request_mem_region(mem.start, resource_size(&mem),
+		ictl->name)) {
+		pr_err("%s: Request mem region failed.\n", ictl->name);
+		return -EBUSY;
+	}
+
+	reg_base = ioremap(mem.start, resource_size(&mem));
+	if (!reg_base) {
+		ret = -EBUSY;
+		pr_err("%s: ioremap failed.\n", ictl->name);
+		goto ioremap_fail;
+	}
+
+	domain = irq_domain_add_linear(ictl, AB_IRQCTL_MAXIRQ,
+					&irq_generic_chip_ops, NULL);
+	if (!domain) {
+		ret = -ENOMEM;
+		pr_err("%s: Could not register interrupt domain.\n",
+			ictl->name);
+		goto irq_domain_add_fail;
+	}
+
+	ret = irq_alloc_domain_generic_chips(domain, AB_IRQCTL_MAXIRQ,
+				2, ictl->name, handle_level_irq,
+				IRQ_NOREQUEST, IRQ_NOPROBE,
+				IRQ_GC_INIT_MASK_CACHE);
+	if (ret) {
+		pr_err("%s: Could not allocate generic interrupt chip.\n",
+			ictl->name);
+		goto gc_alloc_fail;
+	}
+
+	gc = domain->gc->gc[0];
+	gc->reg_base                         = reg_base;
+
+	gc->chip_types[0].type               = IRQ_TYPE_LEVEL_MASK;
+	gc->chip_types[0].chip.irq_mask      = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask    = irq_gc_mask_set_bit;
+	gc->chip_types[0].chip.irq_set_type  = tb10x_irq_set_type;
+	gc->chip_types[0].regs.mask          = AB_IRQCTL_INT_ENABLE;
+
+	gc->chip_types[1].type               = IRQ_TYPE_EDGE_BOTH;
+	gc->chip_types[1].chip.name          = gc->chip_types[0].chip.name;
+	gc->chip_types[1].chip.irq_ack       = irq_gc_ack_set_bit;
+	gc->chip_types[1].chip.irq_mask      = irq_gc_mask_clr_bit;
+	gc->chip_types[1].chip.irq_unmask    = irq_gc_mask_set_bit;
+	gc->chip_types[1].chip.irq_set_type  = tb10x_irq_set_type;
+	gc->chip_types[1].regs.ack           = AB_IRQCTL_INT_STATUS;
+	gc->chip_types[1].regs.mask          = AB_IRQCTL_INT_ENABLE;
+	gc->chip_types[1].handler            = handle_edge_irq;
+
+	for (i = 0; i < nrirqs; i++) {
+		unsigned int irq = irq_of_parse_and_map(ictl, i);
+
+		irq_set_handler_data(irq, domain);
+		irq_set_chained_handler(irq, tb10x_irq_cascade);
+	}
+
+	ab_irqctl_writereg(gc, AB_IRQCTL_INT_ENABLE, 0);
+	ab_irqctl_writereg(gc, AB_IRQCTL_INT_MODE, 0);
+	ab_irqctl_writereg(gc, AB_IRQCTL_INT_POLARITY, 0);
+	ab_irqctl_writereg(gc, AB_IRQCTL_INT_STATUS, ~0UL);
+
+	return 0;
+
+gc_alloc_fail:
+	irq_domain_remove(domain);
+irq_domain_add_fail:
+	iounmap(reg_base);
+ioremap_fail:
+	release_mem_region(mem.start, resource_size(&mem));
+	return ret;
+}
+IRQCHIP_DECLARE(tb10x_intc, "abilis,tb10x-ictl", of_tb10x_init_irq);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/irq-vt8500.c linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-vt8500.c
--- linux-libre-3.10-gnu/drivers/irqchip/irq-vt8500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/irq-vt8500.c	2013-08-25 20:43:22.000000000 -0400
@@ -178,7 +178,8 @@ static struct irq_domain_ops vt8500_irq_
 	.xlate = irq_domain_xlate_onecell,
 };
 
-asmlinkage void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs)
+static asmlinkage
+void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs)
 {
 	u32 stat, i;
 	int irqnr, virq;
@@ -203,7 +204,8 @@ asmlinkage void __exception_irq_entry vt
 	}
 }
 
-int __init vt8500_irq_init(struct device_node *node, struct device_node *parent)
+static int __init vt8500_irq_init(struct device_node *node,
+				  struct device_node *parent)
 {
 	int irq, i;
 	struct device_node *np = node;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/Kconfig linux-libre-3.11-rc7-gnu/drivers/irqchip/Kconfig
--- linux-libre-3.10-gnu/drivers/irqchip/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,11 @@ config ARM_GIC
 config GIC_NON_BANKED
 	bool
 
+config ARM_NVIC
+	bool
+	select IRQ_DOMAIN
+	select GENERIC_IRQ_CHIP
+
 config ARM_VIC
 	bool
 	select IRQ_DOMAIN
@@ -25,6 +30,11 @@ config ARM_VIC_NR
 	  The maximum number of VICs available in the system, for
 	  power management.
 
+config ORION_IRQCHIP
+	bool
+	select IRQ_DOMAIN
+	select MULTI_IRQ_HANDLER
+
 config RENESAS_INTC_IRQPIN
 	bool
 	select IRQ_DOMAIN
@@ -33,6 +43,11 @@ config RENESAS_IRQC
 	bool
 	select IRQ_DOMAIN
 
+config TB10X_IRQC
+	bool
+	select IRQ_DOMAIN
+	select GENERIC_IRQ_CHIP
+
 config VERSATILE_FPGA_IRQ
 	bool
 	select IRQ_DOMAIN
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/irqchip/Makefile linux-libre-3.11-rc7-gnu/drivers/irqchip/Makefile
--- linux-libre-3.10-gnu/drivers/irqchip/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/irqchip/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -7,12 +7,16 @@ obj-$(CONFIG_ARCH_MXS)			+= irq-mxs.o
 obj-$(CONFIG_ARCH_S3C24XX)		+= irq-s3c24xx.o
 obj-$(CONFIG_METAG)			+= irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)	+= irq-metag.o
+obj-$(CONFIG_ARCH_MOXART)		+= irq-moxart.o
+obj-$(CONFIG_ORION_IRQCHIP)		+= irq-orion.o
 obj-$(CONFIG_ARCH_SUNXI)		+= irq-sun4i.o
 obj-$(CONFIG_ARCH_SPEAR3XX)		+= spear-shirq.o
 obj-$(CONFIG_ARM_GIC)			+= irq-gic.o
+obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
 obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
 obj-$(CONFIG_SIRF_IRQ)			+= irq-sirfsoc.o
 obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)		+= irq-renesas-irqc.o
 obj-$(CONFIG_VERSATILE_FPGA_IRQ)	+= irq-versatile-fpga.o
 obj-$(CONFIG_ARCH_VT8500)		+= irq-vt8500.o
+obj-$(CONFIG_TB10X_IRQC)		+= irq-tb10x.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/isdn/i4l/isdn_net.c linux-libre-3.11-rc7-gnu/drivers/isdn/i4l/isdn_net.c
--- linux-libre-3.10-gnu/drivers/isdn/i4l/isdn_net.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/isdn/i4l/isdn_net.c	2013-08-25 20:43:22.000000000 -0400
@@ -885,7 +885,7 @@ isdn_net_log_skb(struct sk_buff *skb, is
 
 	addinfo[0] = '\0';
 	/* This check stolen from 2.1.72 dev_queue_xmit_nit() */
-	if (p < skb->data || skb->network_header >= skb->tail) {
+	if (p < skb->data || skb_network_header(skb) >= skb_tail_pointer(skb)) {
 		/* fall back to old isdn_net_log_packet method() */
 		char *buf = skb->data;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/isdn/mISDN/dsp_pipeline.c linux-libre-3.11-rc7-gnu/drivers/isdn/mISDN/dsp_pipeline.c
--- linux-libre-3.10-gnu/drivers/isdn/mISDN/dsp_pipeline.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/isdn/mISDN/dsp_pipeline.c	2013-08-25 20:43:22.000000000 -0400
@@ -102,7 +102,7 @@ int mISDN_dsp_element_register(struct mI
 	entry->dev.class = elements_class;
 	entry->dev.release = mISDN_dsp_dev_release;
 	dev_set_drvdata(&entry->dev, elem);
-	dev_set_name(&entry->dev, elem->name);
+	dev_set_name(&entry->dev, "%s", elem->name);
 	ret = device_register(&entry->dev);
 	if (ret) {
 		printk(KERN_ERR "%s: failed to register %s\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/Kconfig linux-libre-3.11-rc7-gnu/drivers/Kconfig
--- linux-libre-3.10-gnu/drivers/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -52,8 +52,6 @@ source "drivers/i2c/Kconfig"
 
 source "drivers/spi/Kconfig"
 
-source "drivers/ssbi/Kconfig"
-
 source "drivers/hsi/Kconfig"
 
 source "drivers/pps/Kconfig"
@@ -166,4 +164,6 @@ source "drivers/ipack/Kconfig"
 
 source "drivers/reset/Kconfig"
 
+source "drivers/fmc/Kconfig"
+
 endmenu
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/Kconfig linux-libre-3.11-rc7-gnu/drivers/leds/Kconfig
--- linux-libre-3.10-gnu/drivers/leds/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -388,12 +388,12 @@ config LEDS_DELL_NETBOOKS
 	  notebooks that have an external LED.
 
 config LEDS_MC13783
-	tristate "LED Support for MC13783 PMIC"
+	tristate "LED Support for MC13XXX PMIC"
 	depends on LEDS_CLASS
-	depends on MFD_MC13783
+	depends on MFD_MC13XXX
 	help
 	  This option enable support for on-chip LED drivers found
-	  on Freescale Semiconductor MC13783 PMIC.
+	  on Freescale Semiconductor MC13783/MC13892 PMIC.
 
 config LEDS_NS2
 	tristate "LED support for Network Space v2 GPIO LEDs"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/led-class.c linux-libre-3.11-rc7-gnu/drivers/leds/led-class.c
--- linux-libre-3.10-gnu/drivers/leds/led-class.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/led-class.c	2013-08-25 20:43:22.000000000 -0400
@@ -156,7 +156,7 @@ void led_classdev_resume(struct led_clas
 }
 EXPORT_SYMBOL_GPL(led_classdev_resume);
 
-static int led_suspend(struct device *dev, pm_message_t state)
+static int led_suspend(struct device *dev)
 {
 	struct led_classdev *led_cdev = dev_get_drvdata(dev);
 
@@ -176,6 +176,11 @@ static int led_resume(struct device *dev
 	return 0;
 }
 
+static const struct dev_pm_ops leds_class_dev_pm_ops = {
+	.suspend        = led_suspend,
+	.resume         = led_resume,
+};
+
 /**
  * led_classdev_register - register a new object of led_classdev class.
  * @parent: The device to register.
@@ -252,8 +257,7 @@ static int __init leds_init(void)
 	leds_class = class_create(THIS_MODULE, "leds");
 	if (IS_ERR(leds_class))
 		return PTR_ERR(leds_class);
-	leds_class->suspend = led_suspend;
-	leds_class->resume = led_resume;
+	leds_class->pm = &leds_class_dev_pm_ops;
 	leds_class->dev_attrs = led_class_attrs;
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-88pm860x.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-88pm860x.c
--- linux-libre-3.10-gnu/drivers/leds/leds-88pm860x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-88pm860x.c	2013-08-25 20:43:22.000000000 -0400
@@ -204,7 +204,7 @@ static int pm860x_led_probe(struct platf
 		sprintf(data->name, "led1-blue");
 		break;
 	}
-	dev_set_drvdata(&pdev->dev, data);
+	platform_set_drvdata(pdev, data);
 	data->chip = chip;
 	data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
 	data->port = pdev->id;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-atmel-pwm.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-atmel-pwm.c
--- linux-libre-3.10-gnu/drivers/leds/leds-atmel-pwm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-atmel-pwm.c	2013-08-25 20:43:22.000000000 -0400
@@ -129,7 +129,6 @@ static int pwmled_remove(struct platform
 		pwm_channel_free(&led->pwmc);
 	}
 
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-gpio.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-gpio.c
--- linux-libre-3.10-gnu/drivers/leds/leds-gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-gpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/module.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/err.h>
 
 struct gpio_led_data {
@@ -236,13 +235,8 @@ static int gpio_led_probe(struct platfor
 {
 	struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
 	struct gpio_leds_priv *priv;
-	struct pinctrl *pinctrl;
 	int i, ret = 0;
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl))
-		dev_warn(&pdev->dev,
-			"pins are not configured from the driver\n");
 
 	if (pdata && pdata->num_leds) {
 		priv = devm_kzalloc(&pdev->dev,
@@ -282,8 +276,6 @@ static int gpio_led_remove(struct platfo
 	for (i = 0; i < priv->num_leds; i++)
 		delete_gpio_led(&priv->leds[i]);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-lp5521.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp5521.c
--- linux-libre-3.10-gnu/drivers/leds/leds-lp5521.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp5521.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/mutex.h>
 #include <linux/platform_data/leds-lp55xx.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 
 #include "leds-lp55xx-common.h"
 
@@ -416,12 +417,20 @@ static int lp5521_probe(struct i2c_clien
 	int ret;
 	struct lp55xx_chip *chip;
 	struct lp55xx_led *led;
-	struct lp55xx_platform_data *pdata = client->dev.platform_data;
+	struct lp55xx_platform_data *pdata;
+	struct device_node *np = client->dev.of_node;
 
-	if (!pdata) {
-		dev_err(&client->dev, "no platform data\n");
-		return -EINVAL;
+	if (!client->dev.platform_data) {
+		if (np) {
+			ret = lp55xx_of_populate_pdata(&client->dev, np);
+			if (ret < 0)
+				return ret;
+		} else {
+			dev_err(&client->dev, "no platform data\n");
+			return -EINVAL;
+		}
 	}
+	pdata = client->dev.platform_data;
 
 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
@@ -485,9 +494,18 @@ static const struct i2c_device_id lp5521
 };
 MODULE_DEVICE_TABLE(i2c, lp5521_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id of_lp5521_leds_match[] = {
+	{ .compatible = "national,lp5521", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, of_lp5521_leds_match);
+#endif
 static struct i2c_driver lp5521_driver = {
 	.driver = {
 		.name	= "lp5521",
+		.of_match_table = of_match_ptr(of_lp5521_leds_match),
 	},
 	.probe		= lp5521_probe,
 	.remove		= lp5521_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-lp5523.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp5523.c
--- linux-libre-3.10-gnu/drivers/leds/leds-lp5523.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp5523.c	2013-08-25 20:43:22.000000000 -0400
@@ -429,12 +429,20 @@ static int lp5523_probe(struct i2c_clien
 	int ret;
 	struct lp55xx_chip *chip;
 	struct lp55xx_led *led;
-	struct lp55xx_platform_data *pdata = client->dev.platform_data;
+	struct lp55xx_platform_data *pdata;
+	struct device_node *np = client->dev.of_node;
 
-	if (!pdata) {
-		dev_err(&client->dev, "no platform data\n");
-		return -EINVAL;
+	if (!client->dev.platform_data) {
+		if (np) {
+			ret = lp55xx_of_populate_pdata(&client->dev, np);
+			if (ret < 0)
+				return ret;
+		} else {
+			dev_err(&client->dev, "no platform data\n");
+			return -EINVAL;
+		}
 	}
+	pdata = client->dev.platform_data;
 
 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
@@ -500,9 +508,19 @@ static const struct i2c_device_id lp5523
 
 MODULE_DEVICE_TABLE(i2c, lp5523_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id of_lp5523_leds_match[] = {
+	{ .compatible = "national,lp5523", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, of_lp5523_leds_match);
+#endif
+
 static struct i2c_driver lp5523_driver = {
 	.driver = {
 		.name	= "lp5523x",
+		.of_match_table = of_match_ptr(of_lp5523_leds_match),
 	},
 	.probe		= lp5523_probe,
 	.remove		= lp5523_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-lp5562.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp5562.c
--- linux-libre-3.10-gnu/drivers/leds/leds-lp5562.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp5562.c	2013-08-25 20:43:22.000000000 -0400
@@ -515,12 +515,20 @@ static int lp5562_probe(struct i2c_clien
 	int ret;
 	struct lp55xx_chip *chip;
 	struct lp55xx_led *led;
-	struct lp55xx_platform_data *pdata = client->dev.platform_data;
+	struct lp55xx_platform_data *pdata;
+	struct device_node *np = client->dev.of_node;
 
-	if (!pdata) {
-		dev_err(&client->dev, "no platform data\n");
-		return -EINVAL;
+	if (!client->dev.platform_data) {
+		if (np) {
+			ret = lp55xx_of_populate_pdata(&client->dev, np);
+			if (ret < 0)
+				return ret;
+		} else {
+			dev_err(&client->dev, "no platform data\n");
+			return -EINVAL;
+		}
 	}
+	pdata = client->dev.platform_data;
 
 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
@@ -583,9 +591,19 @@ static const struct i2c_device_id lp5562
 };
 MODULE_DEVICE_TABLE(i2c, lp5562_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id of_lp5562_leds_match[] = {
+	{ .compatible = "ti,lp5562", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, of_lp5562_leds_match);
+#endif
+
 static struct i2c_driver lp5562_driver = {
 	.driver = {
 		.name	= "lp5562",
+		.of_match_table = of_match_ptr(of_lp5562_leds_match),
 	},
 	.probe		= lp5562_probe,
 	.remove		= lp5562_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-lp55xx-common.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp55xx-common.c
--- linux-libre-3.10-gnu/drivers/leds/leds-lp55xx-common.c	2013-07-01 10:41:53.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp55xx-common.c	2013-08-31 18:01:41.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/leds.h>
 #include <linux/module.h>
 #include <linux/platform_data/leds-lp55xx.h>
+#include <linux/slab.h>
 
 #include "leds-lp55xx-common.h"
 
@@ -554,6 +555,50 @@ void lp55xx_unregister_sysfs(struct lp55
 }
 EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs);
 
+int lp55xx_of_populate_pdata(struct device *dev, struct device_node *np)
+{
+	struct device_node *child;
+	struct lp55xx_platform_data *pdata;
+	struct lp55xx_led_config *cfg;
+	int num_channels;
+	int i = 0;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	num_channels = of_get_child_count(np);
+	if (num_channels == 0) {
+		dev_err(dev, "no LED channels\n");
+		return -EINVAL;
+	}
+
+	cfg = devm_kzalloc(dev, sizeof(*cfg) * num_channels, GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+
+	pdata->led_config = &cfg[0];
+	pdata->num_channels = num_channels;
+
+	for_each_child_of_node(np, child) {
+		cfg[i].chan_nr = i;
+
+		of_property_read_string(child, "chan-name", &cfg[i].name);
+		of_property_read_u8(child, "led-cur", &cfg[i].led_current);
+		of_property_read_u8(child, "max-cur", &cfg[i].max_current);
+
+		i++;
+	}
+
+	of_property_read_string(np, "label", &pdata->label);
+	of_property_read_u8(np, "clock-mode", &pdata->clock_mode);
+
+	dev->platform_data = pdata;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lp55xx_of_populate_pdata);
+
 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
 MODULE_DESCRIPTION("LP55xx Common Driver");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-lp55xx-common.h linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp55xx-common.h
--- linux-libre-3.10-gnu/drivers/leds/leds-lp55xx-common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-lp55xx-common.h	2013-08-25 20:43:22.000000000 -0400
@@ -135,4 +135,8 @@ extern void lp55xx_unregister_leds(struc
 extern int lp55xx_register_sysfs(struct lp55xx_chip *chip);
 extern void lp55xx_unregister_sysfs(struct lp55xx_chip *chip);
 
+/* common device tree population function */
+extern int lp55xx_of_populate_pdata(struct device *dev,
+				    struct device_node *np);
+
 #endif /* _LEDS_LP55XX_COMMON_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-mc13783.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-mc13783.c
--- linux-libre-3.10-gnu/drivers/leds/leds-mc13783.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-mc13783.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * LEDs driver for Freescale MC13783
+ * LEDs driver for Freescale MC13783/MC13892
  *
  * Copyright (C) 2010 Philippe Rétornaz
  *
@@ -22,9 +22,16 @@
 #include <linux/leds.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/mc13xxx.h>
-#include <linux/slab.h>
 
-struct mc13783_led {
+#define MC13XXX_REG_LED_CONTROL(x)	(51 + (x))
+
+struct mc13xxx_led_devtype {
+	int	led_min;
+	int	led_max;
+	int	num_regs;
+};
+
+struct mc13xxx_led {
 	struct led_classdev	cdev;
 	struct work_struct	work;
 	struct mc13xxx		*master;
@@ -32,66 +39,35 @@ struct mc13783_led {
 	int			id;
 };
 
-#define MC13783_REG_LED_CONTROL_0	51
-#define MC13783_LED_C0_ENABLE_BIT	(1 << 0)
-#define MC13783_LED_C0_TRIODE_MD_BIT	(1 << 7)
-#define MC13783_LED_C0_TRIODE_AD_BIT	(1 << 8)
-#define MC13783_LED_C0_TRIODE_KP_BIT	(1 << 9)
-#define MC13783_LED_C0_BOOST_BIT	(1 << 10)
-#define MC13783_LED_C0_ABMODE_MASK	0x7
-#define MC13783_LED_C0_ABMODE		11
-#define MC13783_LED_C0_ABREF_MASK	0x3
-#define MC13783_LED_C0_ABREF		14
-
-#define MC13783_REG_LED_CONTROL_1	52
-#define MC13783_LED_C1_TC1HALF_BIT	(1 << 18)
-
-#define MC13783_REG_LED_CONTROL_2	53
-#define MC13783_LED_C2_BL_P_MASK	0xf
-#define MC13783_LED_C2_MD_P		9
-#define MC13783_LED_C2_AD_P		13
-#define MC13783_LED_C2_KP_P		17
-#define MC13783_LED_C2_BL_C_MASK	0x7
-#define MC13783_LED_C2_MD_C		0
-#define MC13783_LED_C2_AD_C		3
-#define MC13783_LED_C2_KP_C		6
-
-#define MC13783_REG_LED_CONTROL_3	54
-#define MC13783_LED_C3_TC_P		6
-#define MC13783_LED_C3_TC_P_MASK	0x1f
-
-#define MC13783_REG_LED_CONTROL_4	55
-#define MC13783_REG_LED_CONTROL_5	56
-
-#define MC13783_LED_Cx_PERIOD		21
-#define MC13783_LED_Cx_PERIOD_MASK	0x3
-#define MC13783_LED_Cx_SLEWLIM_BIT      (1 << 23)
-#define MC13783_LED_Cx_TRIODE_TC_BIT	(1 << 23)
-#define MC13783_LED_Cx_TC_C_MASK	0x3
+struct mc13xxx_leds {
+	struct mc13xxx_led_devtype	*devtype;
+	int				num_leds;
+	struct mc13xxx_led		led[0];
+};
 
-static void mc13783_led_work(struct work_struct *work)
+static void mc13xxx_led_work(struct work_struct *work)
 {
-	struct mc13783_led *led = container_of(work, struct mc13783_led, work);
-	int reg = 0;
-	int mask = 0;
-	int value = 0;
-	int bank, off, shift;
+	struct mc13xxx_led *led = container_of(work, struct mc13xxx_led, work);
+	int reg, mask, value, bank, off, shift;
 
 	switch (led->id) {
 	case MC13783_LED_MD:
-		reg = MC13783_REG_LED_CONTROL_2;
-		mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_MD_P;
-		value = (led->new_brightness >> 4) << MC13783_LED_C2_MD_P;
+		reg = MC13XXX_REG_LED_CONTROL(2);
+		shift = 9;
+		mask = 0x0f;
+		value = led->new_brightness >> 4;
 		break;
 	case MC13783_LED_AD:
-		reg = MC13783_REG_LED_CONTROL_2;
-		mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_AD_P;
-		value = (led->new_brightness >> 4) << MC13783_LED_C2_AD_P;
+		reg = MC13XXX_REG_LED_CONTROL(2);
+		shift = 13;
+		mask = 0x0f;
+		value = led->new_brightness >> 4;
 		break;
 	case MC13783_LED_KP:
-		reg = MC13783_REG_LED_CONTROL_2;
-		mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_KP_P;
-		value = (led->new_brightness >> 4) << MC13783_LED_C2_KP_P;
+		reg = MC13XXX_REG_LED_CONTROL(2);
+		shift = 17;
+		mask = 0x0f;
+		value = led->new_brightness >> 4;
 		break;
 	case MC13783_LED_R1:
 	case MC13783_LED_G1:
@@ -103,57 +79,78 @@ static void mc13783_led_work(struct work
 	case MC13783_LED_G3:
 	case MC13783_LED_B3:
 		off = led->id - MC13783_LED_R1;
-		bank = off/3;
-		reg = MC13783_REG_LED_CONTROL_3 + off/3;
-		shift = (off - bank * 3) * 5 + MC13783_LED_C3_TC_P;
-		value = (led->new_brightness >> 3) << shift;
-		mask = MC13783_LED_C3_TC_P_MASK << shift;
+		bank = off / 3;
+		reg = MC13XXX_REG_LED_CONTROL(3) + bank;
+		shift = (off - bank * 3) * 5 + 6;
+		value = led->new_brightness >> 3;
+		mask = 0x1f;
+		break;
+	case MC13892_LED_MD:
+		reg = MC13XXX_REG_LED_CONTROL(0);
+		shift = 3;
+		mask = 0x3f;
+		value = led->new_brightness >> 2;
+		break;
+	case MC13892_LED_AD:
+		reg = MC13XXX_REG_LED_CONTROL(0);
+		shift = 15;
+		mask = 0x3f;
+		value = led->new_brightness >> 2;
+		break;
+	case MC13892_LED_KP:
+		reg = MC13XXX_REG_LED_CONTROL(1);
+		shift = 3;
+		mask = 0x3f;
+		value = led->new_brightness >> 2;
+		break;
+	case MC13892_LED_R:
+	case MC13892_LED_G:
+	case MC13892_LED_B:
+		off = led->id - MC13892_LED_R;
+		bank = off / 2;
+		reg = MC13XXX_REG_LED_CONTROL(2) + bank;
+		shift = (off - bank * 2) * 12 + 3;
+		value = led->new_brightness >> 2;
+		mask = 0x3f;
 		break;
+	default:
+		BUG();
 	}
 
 	mc13xxx_lock(led->master);
-
-	mc13xxx_reg_rmw(led->master, reg, mask, value);
-
+	mc13xxx_reg_rmw(led->master, reg, mask << shift, value << shift);
 	mc13xxx_unlock(led->master);
 }
 
-static void mc13783_led_set(struct led_classdev *led_cdev,
-			   enum led_brightness value)
+static void mc13xxx_led_set(struct led_classdev *led_cdev,
+			    enum led_brightness value)
 {
-	struct mc13783_led *led;
+	struct mc13xxx_led *led =
+		container_of(led_cdev, struct mc13xxx_led, cdev);
 
-	led = container_of(led_cdev, struct mc13783_led, cdev);
 	led->new_brightness = value;
 	schedule_work(&led->work);
 }
 
-static int mc13783_led_setup(struct mc13783_led *led, int max_current)
+static int __init mc13xxx_led_setup(struct mc13xxx_led *led, int max_current)
 {
-	int shift = 0;
-	int mask = 0;
-	int value = 0;
-	int reg = 0;
-	int ret, bank;
+	int shift, mask, reg, ret, bank;
 
 	switch (led->id) {
 	case MC13783_LED_MD:
-		shift = MC13783_LED_C2_MD_C;
-		mask = MC13783_LED_C2_BL_C_MASK;
-		value = max_current & MC13783_LED_C2_BL_C_MASK;
-		reg = MC13783_REG_LED_CONTROL_2;
+		reg = MC13XXX_REG_LED_CONTROL(2);
+		shift = 0;
+		mask = 0x07;
 		break;
 	case MC13783_LED_AD:
-		shift = MC13783_LED_C2_AD_C;
-		mask = MC13783_LED_C2_BL_C_MASK;
-		value = max_current & MC13783_LED_C2_BL_C_MASK;
-		reg = MC13783_REG_LED_CONTROL_2;
+		reg = MC13XXX_REG_LED_CONTROL(2);
+		shift = 3;
+		mask = 0x07;
 		break;
 	case MC13783_LED_KP:
-		shift = MC13783_LED_C2_KP_C;
-		mask = MC13783_LED_C2_BL_C_MASK;
-		value = max_current & MC13783_LED_C2_BL_C_MASK;
-		reg = MC13783_REG_LED_CONTROL_2;
+		reg = MC13XXX_REG_LED_CONTROL(2);
+		shift = 6;
+		mask = 0x07;
 		break;
 	case MC13783_LED_R1:
 	case MC13783_LED_G1:
@@ -164,229 +161,195 @@ static int mc13783_led_setup(struct mc13
 	case MC13783_LED_R3:
 	case MC13783_LED_G3:
 	case MC13783_LED_B3:
-		bank = (led->id - MC13783_LED_R1)/3;
-		reg = MC13783_REG_LED_CONTROL_3 + bank;
+		bank = (led->id - MC13783_LED_R1) / 3;
+		reg = MC13XXX_REG_LED_CONTROL(3) + bank;
 		shift = ((led->id - MC13783_LED_R1) - bank * 3) * 2;
-		mask = MC13783_LED_Cx_TC_C_MASK;
-		value = max_current & MC13783_LED_Cx_TC_C_MASK;
+		mask = 0x03;
+		break;
+	case MC13892_LED_MD:
+		reg = MC13XXX_REG_LED_CONTROL(0);
+		shift = 9;
+		mask = 0x07;
+		break;
+	case MC13892_LED_AD:
+		reg = MC13XXX_REG_LED_CONTROL(0);
+		shift = 21;
+		mask = 0x07;
 		break;
+	case MC13892_LED_KP:
+		reg = MC13XXX_REG_LED_CONTROL(1);
+		shift = 9;
+		mask = 0x07;
+		break;
+	case MC13892_LED_R:
+	case MC13892_LED_G:
+	case MC13892_LED_B:
+		bank = (led->id - MC13892_LED_R) / 2;
+		reg = MC13XXX_REG_LED_CONTROL(2) + bank;
+		shift = ((led->id - MC13892_LED_R) - bank * 2) * 12 + 9;
+		mask = 0x07;
+		break;
+	default:
+		BUG();
 	}
 
 	mc13xxx_lock(led->master);
-
 	ret = mc13xxx_reg_rmw(led->master, reg, mask << shift,
-						value << shift);
-
+			      max_current << shift);
 	mc13xxx_unlock(led->master);
-	return ret;
-}
-
-static int mc13783_leds_prepare(struct platform_device *pdev)
-{
-	struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent);
-	int ret = 0;
-	int reg = 0;
-
-	mc13xxx_lock(dev);
-
-	if (pdata->flags & MC13783_LED_TC1HALF)
-		reg |= MC13783_LED_C1_TC1HALF_BIT;
-
-	if (pdata->flags & MC13783_LED_SLEWLIMTC)
-		reg |= MC13783_LED_Cx_SLEWLIM_BIT;
-
-	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg);
-	if (ret)
-		goto out;
-
-	reg = (pdata->bl_period & MC13783_LED_Cx_PERIOD_MASK) <<
-							MC13783_LED_Cx_PERIOD;
-
-	if (pdata->flags & MC13783_LED_SLEWLIMBL)
-		reg |= MC13783_LED_Cx_SLEWLIM_BIT;
-
-	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg);
-	if (ret)
-		goto out;
 
-	reg = (pdata->tc1_period & MC13783_LED_Cx_PERIOD_MASK) <<
-							MC13783_LED_Cx_PERIOD;
-
-	if (pdata->flags & MC13783_LED_TRIODE_TC1)
-		reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
-
-	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg);
-	if (ret)
-		goto out;
-
-	reg = (pdata->tc2_period & MC13783_LED_Cx_PERIOD_MASK) <<
-							MC13783_LED_Cx_PERIOD;
-
-	if (pdata->flags & MC13783_LED_TRIODE_TC2)
-		reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
-
-	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg);
-	if (ret)
-		goto out;
-
-	reg = (pdata->tc3_period & MC13783_LED_Cx_PERIOD_MASK) <<
-							MC13783_LED_Cx_PERIOD;
-
-	if (pdata->flags & MC13783_LED_TRIODE_TC3)
-		reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
-
-	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg);
-	if (ret)
-		goto out;
-
-	reg = MC13783_LED_C0_ENABLE_BIT;
-	if (pdata->flags & MC13783_LED_TRIODE_MD)
-		reg |= MC13783_LED_C0_TRIODE_MD_BIT;
-	if (pdata->flags & MC13783_LED_TRIODE_AD)
-		reg |= MC13783_LED_C0_TRIODE_AD_BIT;
-	if (pdata->flags & MC13783_LED_TRIODE_KP)
-		reg |= MC13783_LED_C0_TRIODE_KP_BIT;
-	if (pdata->flags & MC13783_LED_BOOST_EN)
-		reg |= MC13783_LED_C0_BOOST_BIT;
-
-	reg |= (pdata->abmode & MC13783_LED_C0_ABMODE_MASK) <<
-							MC13783_LED_C0_ABMODE;
-	reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) <<
-							MC13783_LED_C0_ABREF;
-
-	ret = mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg);
-
-out:
-	mc13xxx_unlock(dev);
 	return ret;
 }
 
-static int mc13783_led_probe(struct platform_device *pdev)
+static int __init mc13xxx_led_probe(struct platform_device *pdev)
 {
 	struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	struct mc13xxx_led_platform_data *led_cur;
-	struct mc13783_led *led, *led_dat;
-	int ret, i;
-	int init_led = 0;
+	struct mc13xxx *mcdev = dev_get_drvdata(pdev->dev.parent);
+	struct mc13xxx_led_devtype *devtype =
+		(struct mc13xxx_led_devtype *)pdev->id_entry->driver_data;
+	struct mc13xxx_leds *leds;
+	int i, id, num_leds, ret = -ENODATA;
+	u32 reg, init_led = 0;
 
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "missing platform data\n");
+	if (!pdata) {
+		dev_err(&pdev->dev, "Missing platform data\n");
 		return -ENODEV;
 	}
 
-	if (pdata->num_leds < 1 || pdata->num_leds > (MC13783_LED_MAX + 1)) {
-		dev_err(&pdev->dev, "Invalid led count %d\n", pdata->num_leds);
+	num_leds = pdata->num_leds;
+
+	if ((num_leds < 1) ||
+	    (num_leds > (devtype->led_max - devtype->led_min + 1))) {
+		dev_err(&pdev->dev, "Invalid LED count %d\n", num_leds);
 		return -EINVAL;
 	}
 
-	led = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*led),
-				GFP_KERNEL);
-	if (led == NULL) {
-		dev_err(&pdev->dev, "failed to alloc memory\n");
+	leds = devm_kzalloc(&pdev->dev, num_leds * sizeof(struct mc13xxx_led) +
+			    sizeof(struct mc13xxx_leds), GFP_KERNEL);
+	if (!leds)
 		return -ENOMEM;
+
+	leds->devtype = devtype;
+	leds->num_leds = num_leds;
+	platform_set_drvdata(pdev, leds);
+
+	mc13xxx_lock(mcdev);
+	for (i = 0; i < devtype->num_regs; i++) {
+		reg = pdata->led_control[i];
+		WARN_ON(reg >= (1 << 24));
+		ret = mc13xxx_reg_write(mcdev, MC13XXX_REG_LED_CONTROL(i), reg);
+		if (ret)
+			break;
 	}
+	mc13xxx_unlock(mcdev);
 
-	ret = mc13783_leds_prepare(pdev);
 	if (ret) {
-		dev_err(&pdev->dev, "unable to init led driver\n");
+		dev_err(&pdev->dev, "Unable to init LED driver\n");
 		return ret;
 	}
 
-	for (i = 0; i < pdata->num_leds; i++) {
-		led_dat = &led[i];
-		led_cur = &pdata->led[i];
+	for (i = 0; i < num_leds; i++) {
+		const char *name, *trig;
+		char max_current;
 
-		if (led_cur->id > MC13783_LED_MAX || led_cur->id < 0) {
-			dev_err(&pdev->dev, "invalid id %d\n", led_cur->id);
-			ret = -EINVAL;
-			goto err_register;
+		ret = -EINVAL;
+
+		id = pdata->led[i].id;
+		name = pdata->led[i].name;
+		trig = pdata->led[i].default_trigger;
+		max_current = pdata->led[i].max_current;
+
+		if ((id > devtype->led_max) || (id < devtype->led_min)) {
+			dev_err(&pdev->dev, "Invalid ID %i\n", id);
+			break;
 		}
 
-		if (init_led & (1 << led_cur->id)) {
-			dev_err(&pdev->dev, "led %d already initialized\n",
-					led_cur->id);
-			ret = -EINVAL;
-			goto err_register;
+		if (init_led & (1 << id)) {
+			dev_warn(&pdev->dev,
+				 "LED %i already initialized\n", id);
+			break;
 		}
 
-		init_led |= 1 << led_cur->id;
-		led_dat->cdev.name = led_cur->name;
-		led_dat->cdev.default_trigger = led_cur->default_trigger;
-		led_dat->cdev.brightness_set = mc13783_led_set;
-		led_dat->cdev.brightness = LED_OFF;
-		led_dat->id = led_cur->id;
-		led_dat->master = dev_get_drvdata(pdev->dev.parent);
+		init_led |= 1 << id;
+		leds->led[i].id = id;
+		leds->led[i].master = mcdev;
+		leds->led[i].cdev.name = name;
+		leds->led[i].cdev.default_trigger = trig;
+		leds->led[i].cdev.brightness_set = mc13xxx_led_set;
+		leds->led[i].cdev.brightness = LED_OFF;
 
-		INIT_WORK(&led_dat->work, mc13783_led_work);
+		INIT_WORK(&leds->led[i].work, mc13xxx_led_work);
 
-		ret = led_classdev_register(pdev->dev.parent, &led_dat->cdev);
+		ret = mc13xxx_led_setup(&leds->led[i], max_current);
 		if (ret) {
-			dev_err(&pdev->dev, "failed to register led %d\n",
-					led_dat->id);
-			goto err_register;
+			dev_err(&pdev->dev, "Unable to setup LED %i\n", id);
+			break;
 		}
-
-		ret = mc13783_led_setup(led_dat, led_cur->max_current);
+		ret = led_classdev_register(pdev->dev.parent,
+					    &leds->led[i].cdev);
 		if (ret) {
-			dev_err(&pdev->dev, "unable to init led %d\n",
-					led_dat->id);
-			i++;
-			goto err_register;
+			dev_err(&pdev->dev, "Failed to register LED %i\n", id);
+			break;
 		}
 	}
 
-	platform_set_drvdata(pdev, led);
-	return 0;
-
-err_register:
-	for (i = i - 1; i >= 0; i--) {
-		led_classdev_unregister(&led[i].cdev);
-		cancel_work_sync(&led[i].work);
-	}
+	if (ret)
+		while (--i >= 0) {
+			led_classdev_unregister(&leds->led[i].cdev);
+			cancel_work_sync(&leds->led[i].work);
+		}
 
 	return ret;
 }
 
-static int mc13783_led_remove(struct platform_device *pdev)
+static int mc13xxx_led_remove(struct platform_device *pdev)
 {
-	struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
-	struct mc13783_led *led = platform_get_drvdata(pdev);
-	struct mc13xxx *dev = dev_get_drvdata(pdev->dev.parent);
+	struct mc13xxx *mcdev = dev_get_drvdata(pdev->dev.parent);
+	struct mc13xxx_leds *leds = platform_get_drvdata(pdev);
 	int i;
 
-	for (i = 0; i < pdata->num_leds; i++) {
-		led_classdev_unregister(&led[i].cdev);
-		cancel_work_sync(&led[i].work);
+	for (i = 0; i < leds->num_leds; i++) {
+		led_classdev_unregister(&leds->led[i].cdev);
+		cancel_work_sync(&leds->led[i].work);
 	}
 
-	mc13xxx_lock(dev);
-
-	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0);
-	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0);
-	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0);
-	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0);
-	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0);
-	mc13xxx_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0);
-
-	mc13xxx_unlock(dev);
+	mc13xxx_lock(mcdev);
+	for (i = 0; i < leds->devtype->num_regs; i++)
+		mc13xxx_reg_write(mcdev, MC13XXX_REG_LED_CONTROL(i), 0);
+	mc13xxx_unlock(mcdev);
 
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
-static struct platform_driver mc13783_led_driver = {
+static const struct mc13xxx_led_devtype mc13783_led_devtype = {
+	.led_min	= MC13783_LED_MD,
+	.led_max	= MC13783_LED_B3,
+	.num_regs	= 6,
+};
+
+static const struct mc13xxx_led_devtype mc13892_led_devtype = {
+	.led_min	= MC13892_LED_MD,
+	.led_max	= MC13892_LED_B,
+	.num_regs	= 4,
+};
+
+static const struct platform_device_id mc13xxx_led_id_table[] = {
+	{ "mc13783-led", (kernel_ulong_t)&mc13783_led_devtype, },
+	{ "mc13892-led", (kernel_ulong_t)&mc13892_led_devtype, },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, mc13xxx_led_id_table);
+
+static struct platform_driver mc13xxx_led_driver = {
 	.driver	= {
-		.name	= "mc13783-led",
+		.name	= "mc13xxx-led",
 		.owner	= THIS_MODULE,
 	},
-	.probe		= mc13783_led_probe,
-	.remove		= mc13783_led_remove,
+	.remove		= mc13xxx_led_remove,
+	.id_table	= mc13xxx_led_id_table,
 };
+module_platform_driver_probe(mc13xxx_led_driver, mc13xxx_led_probe);
 
-module_platform_driver(mc13783_led_driver);
-
-MODULE_DESCRIPTION("LEDs driver for Freescale MC13783 PMIC");
+MODULE_DESCRIPTION("LEDs driver for Freescale MC13XXX PMIC");
 MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch>");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:mc13783-led");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-ns2.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-ns2.c
--- linux-libre-3.10-gnu/drivers/leds/leds-ns2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-ns2.c	2013-08-25 20:43:22.000000000 -0400
@@ -374,8 +374,6 @@ static int ns2_led_remove(struct platfor
 	for (i = 0; i < priv->num_leds; i++)
 		delete_ns2_led(&priv->leds_data[i]);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-renesas-tpu.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-renesas-tpu.c
--- linux-libre-3.10-gnu/drivers/leds/leds-renesas-tpu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-renesas-tpu.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,7 +63,7 @@ static DEFINE_SPINLOCK(r_tpu_lock);
 #define TGRC 8 /* Timer general register C (+0x20) */
 #define TGRD 9 /* Timer general register D (+0x24) */
 
-static inline unsigned short r_tpu_read(struct r_tpu_priv *p, int reg_nr)
+static inline u16 r_tpu_read(struct r_tpu_priv *p, int reg_nr)
 {
 	struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
 	void __iomem *base = p->mapbase;
@@ -75,8 +75,7 @@ static inline unsigned short r_tpu_read(
 	return ioread16(base + offs);
 }
 
-static inline void r_tpu_write(struct r_tpu_priv *p, int reg_nr,
-			       unsigned short value)
+static inline void r_tpu_write(struct r_tpu_priv *p, int reg_nr, u16 value)
 {
 	struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
 	void __iomem *base = p->mapbase;
@@ -93,7 +92,8 @@ static inline void r_tpu_write(struct r_
 static void r_tpu_start_stop_ch(struct r_tpu_priv *p, int start)
 {
 	struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data;
-	unsigned long flags, value;
+	unsigned long flags;
+	u16 value;
 
 	/* start stop register shared by multiple timer channels */
 	spin_lock_irqsave(&r_tpu_lock, flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-sunfire.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-sunfire.c
--- linux-libre-3.10-gnu/drivers/leds/leds-sunfire.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-sunfire.c	2013-08-25 20:43:22.000000000 -0400
@@ -159,14 +159,14 @@ static int sunfire_led_generic_probe(str
 		}
 	}
 
-	dev_set_drvdata(&pdev->dev, p);
+	platform_set_drvdata(pdev, p);
 
 	return 0;
 }
 
 static int sunfire_led_generic_remove(struct platform_device *pdev)
 {
-	struct sunfire_drvdata *p = dev_get_drvdata(&pdev->dev);
+	struct sunfire_drvdata *p = platform_get_drvdata(pdev);
 	int i;
 
 	for (i = 0; i < NUM_LEDS_PER_BOARD; i++)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/leds/leds-wm831x-status.c linux-libre-3.11-rc7-gnu/drivers/leds/leds-wm831x-status.c
--- linux-libre-3.10-gnu/drivers/leds/leds-wm831x-status.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/leds/leds-wm831x-status.c	2013-08-25 20:43:22.000000000 -0400
@@ -241,7 +241,7 @@ static int wm831x_status_probe(struct pl
 			       GFP_KERNEL);
 	if (!drvdata)
 		return -ENOMEM;
-	dev_set_drvdata(&pdev->dev, drvdata);
+	platform_set_drvdata(pdev, drvdata);
 
 	drvdata->wm831x = wm831x;
 	drvdata->reg = res->start;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/lguest/page_tables.c linux-libre-3.11-rc7-gnu/drivers/lguest/page_tables.c
--- linux-libre-3.10-gnu/drivers/lguest/page_tables.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/lguest/page_tables.c	2013-08-25 20:43:22.000000000 -0400
@@ -70,7 +70,7 @@
 /*H:320
  * The page table code is curly enough to need helper functions to keep it
  * clear and clean.  The kernel itself provides many of them; one advantage
- * of insisting that the Guest and Host use the same CONFIG_PAE setting.
+ * of insisting that the Guest and Host use the same CONFIG_X86_PAE setting.
  *
  * There are two functions which return pointers to the shadow (aka "real")
  * page tables.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/lguest/x86/core.c linux-libre-3.11-rc7-gnu/drivers/lguest/x86/core.c
--- linux-libre-3.10-gnu/drivers/lguest/x86/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/lguest/x86/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -700,7 +700,7 @@ void lguest_arch_setup_regs(struct lg_cp
 	 * interrupts are enabled.  We always leave interrupts enabled while
 	 * running the Guest.
 	 */
-	regs->eflags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+	regs->eflags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
 
 	/*
 	 * The "Extended Instruction Pointer" register says where the Guest is
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/macintosh/adb.c linux-libre-3.11-rc7-gnu/drivers/macintosh/adb.c
--- linux-libre-3.10-gnu/drivers/macintosh/adb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/macintosh/adb.c	2013-08-25 20:43:22.000000000 -0400
@@ -697,7 +697,7 @@ static ssize_t adb_read(struct file *fil
 	int ret = 0;
 	struct adbdev_state *state = file->private_data;
 	struct adb_request *req;
-	wait_queue_t wait = __WAITQUEUE_INITIALIZER(wait,current);
+	DECLARE_WAITQUEUE(wait,current);
 	unsigned long flags;
 
 	if (count < 2)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/macintosh/mac_hid.c linux-libre-3.11-rc7-gnu/drivers/macintosh/mac_hid.c
--- linux-libre-3.10-gnu/drivers/macintosh/mac_hid.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/macintosh/mac_hid.c	2013-08-25 20:43:22.000000000 -0400
@@ -181,7 +181,7 @@ static void mac_hid_stop_emulation(void)
 	mac_hid_destroy_emumouse();
 }
 
-static int mac_hid_toggle_emumouse(ctl_table *table, int write,
+static int mac_hid_toggle_emumouse(struct ctl_table *table, int write,
 				   void __user *buffer, size_t *lenp,
 				   loff_t *ppos)
 {
@@ -214,7 +214,7 @@ static int mac_hid_toggle_emumouse(ctl_t
 }
 
 /* file(s) in /proc/sys/dev/mac_hid */
-static ctl_table mac_hid_files[] = {
+static struct ctl_table mac_hid_files[] = {
 	{
 		.procname	= "mouse_button_emulation",
 		.data		= &mouse_emulate_buttons,
@@ -240,7 +240,7 @@ static ctl_table mac_hid_files[] = {
 };
 
 /* dir in /proc/sys/dev */
-static ctl_table mac_hid_dir[] = {
+static struct ctl_table mac_hid_dir[] = {
 	{
 		.procname	= "mac_hid",
 		.maxlen		= 0,
@@ -251,7 +251,7 @@ static ctl_table mac_hid_dir[] = {
 };
 
 /* /proc/sys/dev itself, in case that is not there yet */
-static ctl_table mac_hid_root_dir[] = {
+static struct ctl_table mac_hid_root_dir[] = {
 	{
 		.procname	= "dev",
 		.maxlen		= 0,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/macintosh/via-cuda.c linux-libre-3.11-rc7-gnu/drivers/macintosh/via-cuda.c
--- linux-libre-3.10-gnu/drivers/macintosh/via-cuda.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/macintosh/via-cuda.c	2013-08-25 20:43:22.000000000 -0400
@@ -259,7 +259,7 @@ cuda_probe(void)
     } while (0)
 
 static int
-cuda_init_via(void)
+__init cuda_init_via(void)
 {
     out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ);	/* TACK & TIP out */
     out_8(&via[B], in_8(&via[B]) | TACK | TIP);			/* negate them */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/macintosh/windfarm_pm121.c linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_pm121.c
--- linux-libre-3.10-gnu/drivers/macintosh/windfarm_pm121.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_pm121.c	2013-08-25 20:43:22.000000000 -0400
@@ -276,6 +276,7 @@ static const char *loop_names[N_LOOPS] =
 
 static unsigned int pm121_failure_state;
 static int pm121_readjust, pm121_skipping;
+static bool pm121_overtemp;
 static s32 average_power;
 
 struct pm121_correction {
@@ -847,6 +848,7 @@ static void pm121_tick(void)
 	if (new_failure & FAILURE_OVERTEMP) {
 		wf_set_overtemp();
 		pm121_skipping = 2;
+		pm121_overtemp = true;
 	}
 
 	/* We only clear the overtemp condition if overtemp is cleared
@@ -855,8 +857,10 @@ static void pm121_tick(void)
 	 * the control loop levels, but we don't want to keep it clear
 	 * here in this case
 	 */
-	if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
+	if (!pm121_failure_state && pm121_overtemp) {
 		wf_clear_overtemp();
+		pm121_overtemp = false;
+	}
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/macintosh/windfarm_pm81.c linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_pm81.c
--- linux-libre-3.10-gnu/drivers/macintosh/windfarm_pm81.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_pm81.c	2013-08-25 20:43:22.000000000 -0400
@@ -149,6 +149,7 @@ static int wf_smu_all_controls_ok, wf_sm
 
 static unsigned int wf_smu_failure_state;
 static int wf_smu_readjust, wf_smu_skipping;
+static bool wf_smu_overtemp;
 
 /*
  * ****** System Fans Control Loop ******
@@ -593,6 +594,7 @@ static void wf_smu_tick(void)
 	if (new_failure & FAILURE_OVERTEMP) {
 		wf_set_overtemp();
 		wf_smu_skipping = 2;
+		wf_smu_overtemp = true;
 	}
 
 	/* We only clear the overtemp condition if overtemp is cleared
@@ -601,8 +603,10 @@ static void wf_smu_tick(void)
 	 * the control loop levels, but we don't want to keep it clear
 	 * here in this case
 	 */
-	if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
+	if (!wf_smu_failure_state && wf_smu_overtemp) {
 		wf_clear_overtemp();
+		wf_smu_overtemp = false;
+	}
 }
 
 static void wf_smu_new_control(struct wf_control *ct)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/macintosh/windfarm_pm91.c linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_pm91.c
--- linux-libre-3.10-gnu/drivers/macintosh/windfarm_pm91.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_pm91.c	2013-08-25 20:43:22.000000000 -0400
@@ -76,6 +76,7 @@ static struct wf_control *cpufreq_clamp;
 
 /* Set to kick the control loop into life */
 static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started;
+static bool wf_smu_overtemp;
 
 /* Failure handling.. could be nicer */
 #define FAILURE_FAN		0x01
@@ -517,6 +518,7 @@ static void wf_smu_tick(void)
 	if (new_failure & FAILURE_OVERTEMP) {
 		wf_set_overtemp();
 		wf_smu_skipping = 2;
+		wf_smu_overtemp = true;
 	}
 
 	/* We only clear the overtemp condition if overtemp is cleared
@@ -525,8 +527,10 @@ static void wf_smu_tick(void)
 	 * the control loop levels, but we don't want to keep it clear
 	 * here in this case
 	 */
-	if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
+	if (!wf_smu_failure_state && wf_smu_overtemp) {
 		wf_clear_overtemp();
+		wf_smu_overtemp = false;
+	}
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/macintosh/windfarm_rm31.c linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_rm31.c
--- linux-libre-3.10-gnu/drivers/macintosh/windfarm_rm31.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_rm31.c	2013-08-25 20:43:22.000000000 -0400
@@ -439,15 +439,15 @@ static void backside_setup_pid(void)
 
 /* Slots fan */
 static const struct wf_pid_param slots_param = {
-	.interval	= 5,
-	.history_len	= 2,
-	.gd		= 30 << 20,
-	.gp		= 5 << 20,
-	.gr		= 0,
-	.itarget	= 40 << 16,
-	.additive	= 1,
-	.min		= 300,
-	.max		= 4000,
+	.interval	= 1,
+	.history_len	= 20,
+	.gd		= 0,
+	.gp		= 0,
+	.gr		= 0x00100000,
+	.itarget	= 3200000,
+	.additive	= 0,
+	.min		= 20,
+	.max		= 100,
 };
 
 static void slots_fan_tick(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/macintosh/windfarm_smu_sat.c linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_smu_sat.c
--- linux-libre-3.10-gnu/drivers/macintosh/windfarm_smu_sat.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/macintosh/windfarm_smu_sat.c	2013-08-25 20:43:22.000000000 -0400
@@ -343,7 +343,6 @@ static int wf_sat_remove(struct i2c_clie
 		wf_unregister_sensor(&sens->sens);
 	}
 	sat->i2c = NULL;
-	i2c_set_clientdata(client, NULL);
 	kref_put(&sat->ref, wf_sat_release);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mailbox/Kconfig linux-libre-3.11-rc7-gnu/drivers/mailbox/Kconfig
--- linux-libre-3.10-gnu/drivers/mailbox/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mailbox/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -16,4 +16,38 @@ config PL320_MBOX
 	  Management Engine, primarily for cpufreq. Say Y here if you want
 	  to use the PL320 IPCM support.
 
+config OMAP_MBOX
+	tristate
+	help
+	  This option is selected by any OMAP architecture specific mailbox
+	  driver such as CONFIG_OMAP1_MBOX or CONFIG_OMAP2PLUS_MBOX. This
+	  enables the common OMAP mailbox framework code.
+
+config OMAP1_MBOX
+	tristate "OMAP1 Mailbox framework support"
+	depends on ARCH_OMAP1
+	select OMAP_MBOX
+	help
+	  Mailbox implementation for OMAP chips with hardware for
+	  interprocessor communication involving DSP in OMAP1. Say Y here
+	  if you want to use OMAP1 Mailbox framework support.
+
+config OMAP2PLUS_MBOX
+	tristate "OMAP2+ Mailbox framework support"
+	depends on ARCH_OMAP2PLUS
+	select OMAP_MBOX
+	help
+	  Mailbox implementation for OMAP family chips with hardware for
+	  interprocessor communication involving DSP, IVA1.0 and IVA2 in
+	  OMAP2/3; or IPU, IVA HD and DSP in OMAP4/5. Say Y here if you
+	  want to use OMAP2+ Mailbox framework support.
+
+config OMAP_MBOX_KFIFO_SIZE
+	int "Mailbox kfifo default buffer size (bytes)"
+	depends on OMAP2PLUS_MBOX || OMAP1_MBOX
+	default 256
+	help
+	  Specify the default size of mailbox's kfifo buffers (bytes).
+	  This can also be changed at runtime (via the mbox_kfifo_size
+	  module parameter).
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mailbox/mailbox-omap1.c linux-libre-3.11-rc7-gnu/drivers/mailbox/mailbox-omap1.c
--- linux-libre-3.10-gnu/drivers/mailbox/mailbox-omap1.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/mailbox/mailbox-omap1.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,203 @@
+/*
+ * Mailbox reservation modules for OMAP1
+ *
+ * Copyright (C) 2006-2009 Nokia Corporation
+ * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include "omap-mbox.h"
+
+#define MAILBOX_ARM2DSP1		0x00
+#define MAILBOX_ARM2DSP1b		0x04
+#define MAILBOX_DSP2ARM1		0x08
+#define MAILBOX_DSP2ARM1b		0x0c
+#define MAILBOX_DSP2ARM2		0x10
+#define MAILBOX_DSP2ARM2b		0x14
+#define MAILBOX_ARM2DSP1_Flag		0x18
+#define MAILBOX_DSP2ARM1_Flag		0x1c
+#define MAILBOX_DSP2ARM2_Flag		0x20
+
+static void __iomem *mbox_base;
+
+struct omap_mbox1_fifo {
+	unsigned long cmd;
+	unsigned long data;
+	unsigned long flag;
+};
+
+struct omap_mbox1_priv {
+	struct omap_mbox1_fifo tx_fifo;
+	struct omap_mbox1_fifo rx_fifo;
+};
+
+static inline int mbox_read_reg(size_t ofs)
+{
+	return __raw_readw(mbox_base + ofs);
+}
+
+static inline void mbox_write_reg(u32 val, size_t ofs)
+{
+	__raw_writew(val, mbox_base + ofs);
+}
+
+/* msg */
+static mbox_msg_t omap1_mbox_fifo_read(struct omap_mbox *mbox)
+{
+	struct omap_mbox1_fifo *fifo =
+		&((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
+	mbox_msg_t msg;
+
+	msg = mbox_read_reg(fifo->data);
+	msg |= ((mbox_msg_t) mbox_read_reg(fifo->cmd)) << 16;
+
+	return msg;
+}
+
+static void
+omap1_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+	struct omap_mbox1_fifo *fifo =
+		&((struct omap_mbox1_priv *)mbox->priv)->tx_fifo;
+
+	mbox_write_reg(msg & 0xffff, fifo->data);
+	mbox_write_reg(msg >> 16, fifo->cmd);
+}
+
+static int omap1_mbox_fifo_empty(struct omap_mbox *mbox)
+{
+	return 0;
+}
+
+static int omap1_mbox_fifo_full(struct omap_mbox *mbox)
+{
+	struct omap_mbox1_fifo *fifo =
+		&((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
+
+	return mbox_read_reg(fifo->flag);
+}
+
+/* irq */
+static void
+omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	if (irq == IRQ_RX)
+		enable_irq(mbox->irq);
+}
+
+static void
+omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	if (irq == IRQ_RX)
+		disable_irq(mbox->irq);
+}
+
+static int
+omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	if (irq == IRQ_TX)
+		return 0;
+	return 1;
+}
+
+static struct omap_mbox_ops omap1_mbox_ops = {
+	.type		= OMAP_MBOX_TYPE1,
+	.fifo_read	= omap1_mbox_fifo_read,
+	.fifo_write	= omap1_mbox_fifo_write,
+	.fifo_empty	= omap1_mbox_fifo_empty,
+	.fifo_full	= omap1_mbox_fifo_full,
+	.enable_irq	= omap1_mbox_enable_irq,
+	.disable_irq	= omap1_mbox_disable_irq,
+	.is_irq		= omap1_mbox_is_irq,
+};
+
+/* FIXME: the following struct should be created automatically by the user id */
+
+/* DSP */
+static struct omap_mbox1_priv omap1_mbox_dsp_priv = {
+	.tx_fifo = {
+		.cmd	= MAILBOX_ARM2DSP1b,
+		.data	= MAILBOX_ARM2DSP1,
+		.flag	= MAILBOX_ARM2DSP1_Flag,
+	},
+	.rx_fifo = {
+		.cmd	= MAILBOX_DSP2ARM1b,
+		.data	= MAILBOX_DSP2ARM1,
+		.flag	= MAILBOX_DSP2ARM1_Flag,
+	},
+};
+
+static struct omap_mbox mbox_dsp_info = {
+	.name	= "dsp",
+	.ops	= &omap1_mbox_ops,
+	.priv	= &omap1_mbox_dsp_priv,
+};
+
+static struct omap_mbox *omap1_mboxes[] = { &mbox_dsp_info, NULL };
+
+static int omap1_mbox_probe(struct platform_device *pdev)
+{
+	struct resource *mem;
+	int ret;
+	struct omap_mbox **list;
+
+	list = omap1_mboxes;
+	list[0]->irq = platform_get_irq_byname(pdev, "dsp");
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem)
+		return -ENOENT;
+
+	mbox_base = ioremap(mem->start, resource_size(mem));
+	if (!mbox_base)
+		return -ENOMEM;
+
+	ret = omap_mbox_register(&pdev->dev, list);
+	if (ret) {
+		iounmap(mbox_base);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int omap1_mbox_remove(struct platform_device *pdev)
+{
+	omap_mbox_unregister();
+	iounmap(mbox_base);
+	return 0;
+}
+
+static struct platform_driver omap1_mbox_driver = {
+	.probe	= omap1_mbox_probe,
+	.remove	= omap1_mbox_remove,
+	.driver	= {
+		.name	= "omap-mailbox",
+	},
+};
+
+static int __init omap1_mbox_init(void)
+{
+	return platform_driver_register(&omap1_mbox_driver);
+}
+
+static void __exit omap1_mbox_exit(void)
+{
+	platform_driver_unregister(&omap1_mbox_driver);
+}
+
+module_init(omap1_mbox_init);
+module_exit(omap1_mbox_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: omap1 architecture specific functions");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
+MODULE_ALIAS("platform:omap1-mailbox");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mailbox/mailbox-omap2.c linux-libre-3.11-rc7-gnu/drivers/mailbox/mailbox-omap2.c
--- linux-libre-3.10-gnu/drivers/mailbox/mailbox-omap2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/mailbox/mailbox-omap2.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,358 @@
+/*
+ * Mailbox reservation modules for OMAP2/3
+ *
+ * Copyright (C) 2006-2009 Nokia Corporation
+ * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *        and  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_data/mailbox-omap.h>
+
+#include "omap-mbox.h"
+
+#define MAILBOX_REVISION		0x000
+#define MAILBOX_MESSAGE(m)		(0x040 + 4 * (m))
+#define MAILBOX_FIFOSTATUS(m)		(0x080 + 4 * (m))
+#define MAILBOX_MSGSTATUS(m)		(0x0c0 + 4 * (m))
+#define MAILBOX_IRQSTATUS(u)		(0x100 + 8 * (u))
+#define MAILBOX_IRQENABLE(u)		(0x104 + 8 * (u))
+
+#define OMAP4_MAILBOX_IRQSTATUS(u)	(0x104 + 0x10 * (u))
+#define OMAP4_MAILBOX_IRQENABLE(u)	(0x108 + 0x10 * (u))
+#define OMAP4_MAILBOX_IRQENABLE_CLR(u)	(0x10c + 0x10 * (u))
+
+#define MAILBOX_IRQ_NEWMSG(m)		(1 << (2 * (m)))
+#define MAILBOX_IRQ_NOTFULL(m)		(1 << (2 * (m) + 1))
+
+#define MBOX_REG_SIZE			0x120
+
+#define OMAP4_MBOX_REG_SIZE		0x130
+
+#define MBOX_NR_REGS			(MBOX_REG_SIZE / sizeof(u32))
+#define OMAP4_MBOX_NR_REGS		(OMAP4_MBOX_REG_SIZE / sizeof(u32))
+
+static void __iomem *mbox_base;
+
+struct omap_mbox2_fifo {
+	unsigned long msg;
+	unsigned long fifo_stat;
+	unsigned long msg_stat;
+};
+
+struct omap_mbox2_priv {
+	struct omap_mbox2_fifo tx_fifo;
+	struct omap_mbox2_fifo rx_fifo;
+	unsigned long irqenable;
+	unsigned long irqstatus;
+	u32 newmsg_bit;
+	u32 notfull_bit;
+	u32 ctx[OMAP4_MBOX_NR_REGS];
+	unsigned long irqdisable;
+	u32 intr_type;
+};
+
+static inline unsigned int mbox_read_reg(size_t ofs)
+{
+	return __raw_readl(mbox_base + ofs);
+}
+
+static inline void mbox_write_reg(u32 val, size_t ofs)
+{
+	__raw_writel(val, mbox_base + ofs);
+}
+
+/* Mailbox H/W preparations */
+static int omap2_mbox_startup(struct omap_mbox *mbox)
+{
+	u32 l;
+
+	pm_runtime_enable(mbox->dev->parent);
+	pm_runtime_get_sync(mbox->dev->parent);
+
+	l = mbox_read_reg(MAILBOX_REVISION);
+	pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
+
+	return 0;
+}
+
+static void omap2_mbox_shutdown(struct omap_mbox *mbox)
+{
+	pm_runtime_put_sync(mbox->dev->parent);
+	pm_runtime_disable(mbox->dev->parent);
+}
+
+/* Mailbox FIFO handle functions */
+static mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox)
+{
+	struct omap_mbox2_fifo *fifo =
+		&((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
+	return (mbox_msg_t) mbox_read_reg(fifo->msg);
+}
+
+static void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+	struct omap_mbox2_fifo *fifo =
+		&((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
+	mbox_write_reg(msg, fifo->msg);
+}
+
+static int omap2_mbox_fifo_empty(struct omap_mbox *mbox)
+{
+	struct omap_mbox2_fifo *fifo =
+		&((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
+	return (mbox_read_reg(fifo->msg_stat) == 0);
+}
+
+static int omap2_mbox_fifo_full(struct omap_mbox *mbox)
+{
+	struct omap_mbox2_fifo *fifo =
+		&((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
+	return mbox_read_reg(fifo->fifo_stat);
+}
+
+/* Mailbox IRQ handle functions */
+static void omap2_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	struct omap_mbox2_priv *p = mbox->priv;
+	u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+
+	l = mbox_read_reg(p->irqenable);
+	l |= bit;
+	mbox_write_reg(l, p->irqenable);
+}
+
+static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	struct omap_mbox2_priv *p = mbox->priv;
+	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+
+	/*
+	 * Read and update the interrupt configuration register for pre-OMAP4.
+	 * OMAP4 and later SoCs have a dedicated interrupt disabling register.
+	 */
+	if (!p->intr_type)
+		bit = mbox_read_reg(p->irqdisable) & ~bit;
+
+	mbox_write_reg(bit, p->irqdisable);
+}
+
+static void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	struct omap_mbox2_priv *p = mbox->priv;
+	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+
+	mbox_write_reg(bit, p->irqstatus);
+
+	/* Flush posted write for irq status to avoid spurious interrupts */
+	mbox_read_reg(p->irqstatus);
+}
+
+static int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	struct omap_mbox2_priv *p = mbox->priv;
+	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+	u32 enable = mbox_read_reg(p->irqenable);
+	u32 status = mbox_read_reg(p->irqstatus);
+
+	return (int)(enable & status & bit);
+}
+
+static void omap2_mbox_save_ctx(struct omap_mbox *mbox)
+{
+	int i;
+	struct omap_mbox2_priv *p = mbox->priv;
+	int nr_regs;
+
+	if (p->intr_type)
+		nr_regs = OMAP4_MBOX_NR_REGS;
+	else
+		nr_regs = MBOX_NR_REGS;
+	for (i = 0; i < nr_regs; i++) {
+		p->ctx[i] = mbox_read_reg(i * sizeof(u32));
+
+		dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
+			i, p->ctx[i]);
+	}
+}
+
+static void omap2_mbox_restore_ctx(struct omap_mbox *mbox)
+{
+	int i;
+	struct omap_mbox2_priv *p = mbox->priv;
+	int nr_regs;
+
+	if (p->intr_type)
+		nr_regs = OMAP4_MBOX_NR_REGS;
+	else
+		nr_regs = MBOX_NR_REGS;
+	for (i = 0; i < nr_regs; i++) {
+		mbox_write_reg(p->ctx[i], i * sizeof(u32));
+
+		dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
+			i, p->ctx[i]);
+	}
+}
+
+static struct omap_mbox_ops omap2_mbox_ops = {
+	.type		= OMAP_MBOX_TYPE2,
+	.startup	= omap2_mbox_startup,
+	.shutdown	= omap2_mbox_shutdown,
+	.fifo_read	= omap2_mbox_fifo_read,
+	.fifo_write	= omap2_mbox_fifo_write,
+	.fifo_empty	= omap2_mbox_fifo_empty,
+	.fifo_full	= omap2_mbox_fifo_full,
+	.enable_irq	= omap2_mbox_enable_irq,
+	.disable_irq	= omap2_mbox_disable_irq,
+	.ack_irq	= omap2_mbox_ack_irq,
+	.is_irq		= omap2_mbox_is_irq,
+	.save_ctx	= omap2_mbox_save_ctx,
+	.restore_ctx	= omap2_mbox_restore_ctx,
+};
+
+static int omap2_mbox_probe(struct platform_device *pdev)
+{
+	struct resource *mem;
+	int ret;
+	struct omap_mbox **list, *mbox, *mboxblk;
+	struct omap_mbox2_priv *priv, *privblk;
+	struct omap_mbox_pdata *pdata = pdev->dev.platform_data;
+	struct omap_mbox_dev_info *info;
+	int i;
+
+	if (!pdata || !pdata->info_cnt || !pdata->info) {
+		pr_err("%s: platform not supported\n", __func__);
+		return -ENODEV;
+	}
+
+	/* allocate one extra for marking end of list */
+	list = kzalloc((pdata->info_cnt + 1) * sizeof(*list), GFP_KERNEL);
+	if (!list)
+		return -ENOMEM;
+
+	mboxblk = mbox = kzalloc(pdata->info_cnt * sizeof(*mbox), GFP_KERNEL);
+	if (!mboxblk) {
+		ret = -ENOMEM;
+		goto free_list;
+	}
+
+	privblk = priv = kzalloc(pdata->info_cnt * sizeof(*priv), GFP_KERNEL);
+	if (!privblk) {
+		ret = -ENOMEM;
+		goto free_mboxblk;
+	}
+
+	info = pdata->info;
+	for (i = 0; i < pdata->info_cnt; i++, info++, priv++) {
+		priv->tx_fifo.msg = MAILBOX_MESSAGE(info->tx_id);
+		priv->tx_fifo.fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id);
+		priv->rx_fifo.msg =  MAILBOX_MESSAGE(info->rx_id);
+		priv->rx_fifo.msg_stat =  MAILBOX_MSGSTATUS(info->rx_id);
+		priv->notfull_bit = MAILBOX_IRQ_NOTFULL(info->tx_id);
+		priv->newmsg_bit = MAILBOX_IRQ_NEWMSG(info->rx_id);
+		if (pdata->intr_type) {
+			priv->irqenable = OMAP4_MAILBOX_IRQENABLE(info->usr_id);
+			priv->irqstatus = OMAP4_MAILBOX_IRQSTATUS(info->usr_id);
+			priv->irqdisable =
+				OMAP4_MAILBOX_IRQENABLE_CLR(info->usr_id);
+		} else {
+			priv->irqenable = MAILBOX_IRQENABLE(info->usr_id);
+			priv->irqstatus = MAILBOX_IRQSTATUS(info->usr_id);
+			priv->irqdisable = MAILBOX_IRQENABLE(info->usr_id);
+		}
+		priv->intr_type = pdata->intr_type;
+
+		mbox->priv = priv;
+		mbox->name = info->name;
+		mbox->ops = &omap2_mbox_ops;
+		mbox->irq = platform_get_irq(pdev, info->irq_id);
+		if (mbox->irq < 0) {
+			ret = mbox->irq;
+			goto free_privblk;
+		}
+		list[i] = mbox++;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		ret = -ENOENT;
+		goto free_privblk;
+	}
+
+	mbox_base = ioremap(mem->start, resource_size(mem));
+	if (!mbox_base) {
+		ret = -ENOMEM;
+		goto free_privblk;
+	}
+
+	ret = omap_mbox_register(&pdev->dev, list);
+	if (ret)
+		goto unmap_mbox;
+	platform_set_drvdata(pdev, list);
+
+	return 0;
+
+unmap_mbox:
+	iounmap(mbox_base);
+free_privblk:
+	kfree(privblk);
+free_mboxblk:
+	kfree(mboxblk);
+free_list:
+	kfree(list);
+	return ret;
+}
+
+static int omap2_mbox_remove(struct platform_device *pdev)
+{
+	struct omap_mbox2_priv *privblk;
+	struct omap_mbox **list = platform_get_drvdata(pdev);
+	struct omap_mbox *mboxblk = list[0];
+
+	privblk = mboxblk->priv;
+	omap_mbox_unregister();
+	iounmap(mbox_base);
+	kfree(privblk);
+	kfree(mboxblk);
+	kfree(list);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver omap2_mbox_driver = {
+	.probe	= omap2_mbox_probe,
+	.remove	= omap2_mbox_remove,
+	.driver	= {
+		.name = "omap-mailbox",
+	},
+};
+
+static int __init omap2_mbox_init(void)
+{
+	return platform_driver_register(&omap2_mbox_driver);
+}
+
+static void __exit omap2_mbox_exit(void)
+{
+	platform_driver_unregister(&omap2_mbox_driver);
+}
+
+module_init(omap2_mbox_init);
+module_exit(omap2_mbox_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: omap2/3/4 architecture specific functions");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
+MODULE_AUTHOR("Paul Mundt");
+MODULE_ALIAS("platform:omap2-mailbox");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mailbox/Makefile linux-libre-3.11-rc7-gnu/drivers/mailbox/Makefile
--- linux-libre-3.10-gnu/drivers/mailbox/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mailbox/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1 +1,7 @@
 obj-$(CONFIG_PL320_MBOX)	+= pl320-ipc.o
+
+obj-$(CONFIG_OMAP_MBOX)		+= omap-mailbox.o
+obj-$(CONFIG_OMAP1_MBOX)	+= mailbox_omap1.o
+mailbox_omap1-objs		:= mailbox-omap1.o
+obj-$(CONFIG_OMAP2PLUS_MBOX)	+= mailbox_omap2.o
+mailbox_omap2-objs		:= mailbox-omap2.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mailbox/omap-mailbox.c linux-libre-3.11-rc7-gnu/drivers/mailbox/omap-mailbox.c
--- linux-libre-3.10-gnu/drivers/mailbox/omap-mailbox.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/mailbox/omap-mailbox.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,469 @@
+/*
+ * OMAP mailbox driver
+ *
+ * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/kfifo.h>
+#include <linux/err.h>
+#include <linux/notifier.h>
+#include <linux/module.h>
+
+#include "omap-mbox.h"
+
+static struct omap_mbox **mboxes;
+
+static int mbox_configured;
+static DEFINE_MUTEX(mbox_configured_lock);
+
+static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
+module_param(mbox_kfifo_size, uint, S_IRUGO);
+MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
+
+/* Mailbox FIFO handle functions */
+static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
+{
+	return mbox->ops->fifo_read(mbox);
+}
+static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+	mbox->ops->fifo_write(mbox, msg);
+}
+static inline int mbox_fifo_empty(struct omap_mbox *mbox)
+{
+	return mbox->ops->fifo_empty(mbox);
+}
+static inline int mbox_fifo_full(struct omap_mbox *mbox)
+{
+	return mbox->ops->fifo_full(mbox);
+}
+
+/* Mailbox IRQ handle functions */
+static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	if (mbox->ops->ack_irq)
+		mbox->ops->ack_irq(mbox, irq);
+}
+static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	return mbox->ops->is_irq(mbox, irq);
+}
+
+/*
+ * message sender
+ */
+static int __mbox_poll_for_space(struct omap_mbox *mbox)
+{
+	int ret = 0, i = 1000;
+
+	while (mbox_fifo_full(mbox)) {
+		if (mbox->ops->type == OMAP_MBOX_TYPE2)
+			return -1;
+		if (--i == 0)
+			return -1;
+		udelay(1);
+	}
+	return ret;
+}
+
+int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+	struct omap_mbox_queue *mq = mbox->txq;
+	int ret = 0, len;
+
+	spin_lock_bh(&mq->lock);
+
+	if (kfifo_avail(&mq->fifo) < sizeof(msg)) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (kfifo_is_empty(&mq->fifo) && !__mbox_poll_for_space(mbox)) {
+		mbox_fifo_write(mbox, msg);
+		goto out;
+	}
+
+	len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+	WARN_ON(len != sizeof(msg));
+
+	tasklet_schedule(&mbox->txq->tasklet);
+
+out:
+	spin_unlock_bh(&mq->lock);
+	return ret;
+}
+EXPORT_SYMBOL(omap_mbox_msg_send);
+
+void omap_mbox_save_ctx(struct omap_mbox *mbox)
+{
+	if (!mbox->ops->save_ctx) {
+		dev_err(mbox->dev, "%s:\tno save\n", __func__);
+		return;
+	}
+
+	mbox->ops->save_ctx(mbox);
+}
+EXPORT_SYMBOL(omap_mbox_save_ctx);
+
+void omap_mbox_restore_ctx(struct omap_mbox *mbox)
+{
+	if (!mbox->ops->restore_ctx) {
+		dev_err(mbox->dev, "%s:\tno restore\n", __func__);
+		return;
+	}
+
+	mbox->ops->restore_ctx(mbox);
+}
+EXPORT_SYMBOL(omap_mbox_restore_ctx);
+
+void omap_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	mbox->ops->enable_irq(mbox, irq);
+}
+EXPORT_SYMBOL(omap_mbox_enable_irq);
+
+void omap_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+	mbox->ops->disable_irq(mbox, irq);
+}
+EXPORT_SYMBOL(omap_mbox_disable_irq);
+
+static void mbox_tx_tasklet(unsigned long tx_data)
+{
+	struct omap_mbox *mbox = (struct omap_mbox *)tx_data;
+	struct omap_mbox_queue *mq = mbox->txq;
+	mbox_msg_t msg;
+	int ret;
+
+	while (kfifo_len(&mq->fifo)) {
+		if (__mbox_poll_for_space(mbox)) {
+			omap_mbox_enable_irq(mbox, IRQ_TX);
+			break;
+		}
+
+		ret = kfifo_out(&mq->fifo, (unsigned char *)&msg,
+								sizeof(msg));
+		WARN_ON(ret != sizeof(msg));
+
+		mbox_fifo_write(mbox, msg);
+	}
+}
+
+/*
+ * Message receiver(workqueue)
+ */
+static void mbox_rx_work(struct work_struct *work)
+{
+	struct omap_mbox_queue *mq =
+			container_of(work, struct omap_mbox_queue, work);
+	mbox_msg_t msg;
+	int len;
+
+	while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
+		len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+		WARN_ON(len != sizeof(msg));
+
+		blocking_notifier_call_chain(&mq->mbox->notifier, len,
+								(void *)msg);
+		spin_lock_irq(&mq->lock);
+		if (mq->full) {
+			mq->full = false;
+			omap_mbox_enable_irq(mq->mbox, IRQ_RX);
+		}
+		spin_unlock_irq(&mq->lock);
+	}
+}
+
+/*
+ * Mailbox interrupt handler
+ */
+static void __mbox_tx_interrupt(struct omap_mbox *mbox)
+{
+	omap_mbox_disable_irq(mbox, IRQ_TX);
+	ack_mbox_irq(mbox, IRQ_TX);
+	tasklet_schedule(&mbox->txq->tasklet);
+}
+
+static void __mbox_rx_interrupt(struct omap_mbox *mbox)
+{
+	struct omap_mbox_queue *mq = mbox->rxq;
+	mbox_msg_t msg;
+	int len;
+
+	while (!mbox_fifo_empty(mbox)) {
+		if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
+			omap_mbox_disable_irq(mbox, IRQ_RX);
+			mq->full = true;
+			goto nomem;
+		}
+
+		msg = mbox_fifo_read(mbox);
+
+		len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+		WARN_ON(len != sizeof(msg));
+
+		if (mbox->ops->type == OMAP_MBOX_TYPE1)
+			break;
+	}
+
+	/* no more messages in the fifo. clear IRQ source. */
+	ack_mbox_irq(mbox, IRQ_RX);
+nomem:
+	schedule_work(&mbox->rxq->work);
+}
+
+static irqreturn_t mbox_interrupt(int irq, void *p)
+{
+	struct omap_mbox *mbox = p;
+
+	if (is_mbox_irq(mbox, IRQ_TX))
+		__mbox_tx_interrupt(mbox);
+
+	if (is_mbox_irq(mbox, IRQ_RX))
+		__mbox_rx_interrupt(mbox);
+
+	return IRQ_HANDLED;
+}
+
+static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
+					void (*work) (struct work_struct *),
+					void (*tasklet)(unsigned long))
+{
+	struct omap_mbox_queue *mq;
+
+	mq = kzalloc(sizeof(struct omap_mbox_queue), GFP_KERNEL);
+	if (!mq)
+		return NULL;
+
+	spin_lock_init(&mq->lock);
+
+	if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL))
+		goto error;
+
+	if (work)
+		INIT_WORK(&mq->work, work);
+
+	if (tasklet)
+		tasklet_init(&mq->tasklet, tasklet, (unsigned long)mbox);
+	return mq;
+error:
+	kfree(mq);
+	return NULL;
+}
+
+static void mbox_queue_free(struct omap_mbox_queue *q)
+{
+	kfifo_free(&q->fifo);
+	kfree(q);
+}
+
+static int omap_mbox_startup(struct omap_mbox *mbox)
+{
+	int ret = 0;
+	struct omap_mbox_queue *mq;
+
+	mutex_lock(&mbox_configured_lock);
+	if (!mbox_configured++) {
+		if (likely(mbox->ops->startup)) {
+			ret = mbox->ops->startup(mbox);
+			if (unlikely(ret))
+				goto fail_startup;
+		} else
+			goto fail_startup;
+	}
+
+	if (!mbox->use_count++) {
+		mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
+		if (!mq) {
+			ret = -ENOMEM;
+			goto fail_alloc_txq;
+		}
+		mbox->txq = mq;
+
+		mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
+		if (!mq) {
+			ret = -ENOMEM;
+			goto fail_alloc_rxq;
+		}
+		mbox->rxq = mq;
+		mq->mbox = mbox;
+		ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
+							mbox->name, mbox);
+		if (unlikely(ret)) {
+			pr_err("failed to register mailbox interrupt:%d\n",
+									ret);
+			goto fail_request_irq;
+		}
+
+		omap_mbox_enable_irq(mbox, IRQ_RX);
+	}
+	mutex_unlock(&mbox_configured_lock);
+	return 0;
+
+fail_request_irq:
+	mbox_queue_free(mbox->rxq);
+fail_alloc_rxq:
+	mbox_queue_free(mbox->txq);
+fail_alloc_txq:
+	if (mbox->ops->shutdown)
+		mbox->ops->shutdown(mbox);
+	mbox->use_count--;
+fail_startup:
+	mbox_configured--;
+	mutex_unlock(&mbox_configured_lock);
+	return ret;
+}
+
+static void omap_mbox_fini(struct omap_mbox *mbox)
+{
+	mutex_lock(&mbox_configured_lock);
+
+	if (!--mbox->use_count) {
+		omap_mbox_disable_irq(mbox, IRQ_RX);
+		free_irq(mbox->irq, mbox);
+		tasklet_kill(&mbox->txq->tasklet);
+		flush_work(&mbox->rxq->work);
+		mbox_queue_free(mbox->txq);
+		mbox_queue_free(mbox->rxq);
+	}
+
+	if (likely(mbox->ops->shutdown)) {
+		if (!--mbox_configured)
+			mbox->ops->shutdown(mbox);
+	}
+
+	mutex_unlock(&mbox_configured_lock);
+}
+
+struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb)
+{
+	struct omap_mbox *_mbox, *mbox = NULL;
+	int i, ret;
+
+	if (!mboxes)
+		return ERR_PTR(-EINVAL);
+
+	for (i = 0; (_mbox = mboxes[i]); i++) {
+		if (!strcmp(_mbox->name, name)) {
+			mbox = _mbox;
+			break;
+		}
+	}
+
+	if (!mbox)
+		return ERR_PTR(-ENOENT);
+
+	if (nb)
+		blocking_notifier_chain_register(&mbox->notifier, nb);
+
+	ret = omap_mbox_startup(mbox);
+	if (ret) {
+		blocking_notifier_chain_unregister(&mbox->notifier, nb);
+		return ERR_PTR(-ENODEV);
+	}
+
+	return mbox;
+}
+EXPORT_SYMBOL(omap_mbox_get);
+
+void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb)
+{
+	blocking_notifier_chain_unregister(&mbox->notifier, nb);
+	omap_mbox_fini(mbox);
+}
+EXPORT_SYMBOL(omap_mbox_put);
+
+static struct class omap_mbox_class = { .name = "mbox", };
+
+int omap_mbox_register(struct device *parent, struct omap_mbox **list)
+{
+	int ret;
+	int i;
+
+	mboxes = list;
+	if (!mboxes)
+		return -EINVAL;
+
+	for (i = 0; mboxes[i]; i++) {
+		struct omap_mbox *mbox = mboxes[i];
+		mbox->dev = device_create(&omap_mbox_class,
+				parent, 0, mbox, "%s", mbox->name);
+		if (IS_ERR(mbox->dev)) {
+			ret = PTR_ERR(mbox->dev);
+			goto err_out;
+		}
+
+		BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
+	}
+	return 0;
+
+err_out:
+	while (i--)
+		device_unregister(mboxes[i]->dev);
+	return ret;
+}
+EXPORT_SYMBOL(omap_mbox_register);
+
+int omap_mbox_unregister(void)
+{
+	int i;
+
+	if (!mboxes)
+		return -EINVAL;
+
+	for (i = 0; mboxes[i]; i++)
+		device_unregister(mboxes[i]->dev);
+	mboxes = NULL;
+	return 0;
+}
+EXPORT_SYMBOL(omap_mbox_unregister);
+
+static int __init omap_mbox_init(void)
+{
+	int err;
+
+	err = class_register(&omap_mbox_class);
+	if (err)
+		return err;
+
+	/* kfifo size sanity check: alignment and minimal size */
+	mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
+	mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
+							sizeof(mbox_msg_t));
+
+	return 0;
+}
+subsys_initcall(omap_mbox_init);
+
+static void __exit omap_mbox_exit(void)
+{
+	class_unregister(&omap_mbox_class);
+}
+module_exit(omap_mbox_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
+MODULE_AUTHOR("Toshihiro Kobayashi");
+MODULE_AUTHOR("Hiroshi DOYU");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mailbox/omap-mbox.h linux-libre-3.11-rc7-gnu/drivers/mailbox/omap-mbox.h
--- linux-libre-3.10-gnu/drivers/mailbox/omap-mbox.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/mailbox/omap-mbox.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * omap-mbox.h: OMAP mailbox internal definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef OMAP_MBOX_H
+#define OMAP_MBOX_H
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/kfifo.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/omap-mailbox.h>
+
+typedef int __bitwise omap_mbox_type_t;
+#define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1)
+#define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2)
+
+struct omap_mbox_ops {
+	omap_mbox_type_t	type;
+	int		(*startup)(struct omap_mbox *mbox);
+	void		(*shutdown)(struct omap_mbox *mbox);
+	/* fifo */
+	mbox_msg_t	(*fifo_read)(struct omap_mbox *mbox);
+	void		(*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
+	int		(*fifo_empty)(struct omap_mbox *mbox);
+	int		(*fifo_full)(struct omap_mbox *mbox);
+	/* irq */
+	void		(*enable_irq)(struct omap_mbox *mbox,
+						omap_mbox_irq_t irq);
+	void		(*disable_irq)(struct omap_mbox *mbox,
+						omap_mbox_irq_t irq);
+	void		(*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+	int		(*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+	/* ctx */
+	void		(*save_ctx)(struct omap_mbox *mbox);
+	void		(*restore_ctx)(struct omap_mbox *mbox);
+};
+
+struct omap_mbox_queue {
+	spinlock_t		lock;
+	struct kfifo		fifo;
+	struct work_struct	work;
+	struct tasklet_struct	tasklet;
+	struct omap_mbox	*mbox;
+	bool full;
+};
+
+struct omap_mbox {
+	const char		*name;
+	unsigned int		irq;
+	struct omap_mbox_queue	*txq, *rxq;
+	struct omap_mbox_ops	*ops;
+	struct device		*dev;
+	void			*priv;
+	int			use_count;
+	struct blocking_notifier_head	notifier;
+};
+
+int omap_mbox_register(struct device *parent, struct omap_mbox **);
+int omap_mbox_unregister(void);
+
+#endif /* OMAP_MBOX_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/Makefile linux-libre-3.11-rc7-gnu/drivers/Makefile
--- linux-libre-3.10-gnu/drivers/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -117,7 +117,6 @@ obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
 obj-$(CONFIG_SUPERH)		+= sh/
 obj-$(CONFIG_ARCH_SHMOBILE)	+= sh/
-obj-$(CONFIG_SSBI)		+= ssbi/
 ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
 obj-y				+= clocksource/
 endif
@@ -152,3 +151,4 @@ obj-$(CONFIG_IIO)		+= iio/
 obj-$(CONFIG_VME_BUS)		+= vme/
 obj-$(CONFIG_IPACK_BUS)		+= ipack/
 obj-$(CONFIG_NTB)		+= ntb/
+obj-$(CONFIG_FMC)		+= fmc/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/alloc.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/alloc.c
--- linux-libre-3.10-gnu/drivers/md/bcache/alloc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/alloc.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,7 +63,10 @@
 #include "bcache.h"
 #include "btree.h"
 
+#include <linux/freezer.h>
+#include <linux/kthread.h>
 #include <linux/random.h>
+#include <trace/events/bcache.h>
 
 #define MAX_IN_FLIGHT_DISCARDS		8U
 
@@ -151,7 +154,7 @@ static void discard_finish(struct work_s
 	mutex_unlock(&ca->set->bucket_lock);
 
 	closure_wake_up(&ca->set->bucket_wait);
-	wake_up(&ca->set->alloc_wait);
+	wake_up_process(ca->alloc_thread);
 
 	closure_put(&ca->set->cl);
 }
@@ -350,38 +353,30 @@ static void invalidate_buckets(struct ca
 		break;
 	}
 
-	pr_debug("free %zu/%zu free_inc %zu/%zu unused %zu/%zu",
-		 fifo_used(&ca->free), ca->free.size,
-		 fifo_used(&ca->free_inc), ca->free_inc.size,
-		 fifo_used(&ca->unused), ca->unused.size);
+	trace_bcache_alloc_invalidate(ca);
 }
 
 #define allocator_wait(ca, cond)					\
 do {									\
-	DEFINE_WAIT(__wait);						\
-									\
 	while (1) {							\
-		prepare_to_wait(&ca->set->alloc_wait,			\
-				&__wait, TASK_INTERRUPTIBLE);		\
+		set_current_state(TASK_INTERRUPTIBLE);			\
 		if (cond)						\
 			break;						\
 									\
 		mutex_unlock(&(ca)->set->bucket_lock);			\
-		if (test_bit(CACHE_SET_STOPPING_2, &ca->set->flags)) {	\
-			finish_wait(&ca->set->alloc_wait, &__wait);	\
-			closure_return(cl);				\
-		}							\
+		if (kthread_should_stop())				\
+			return 0;					\
 									\
+		try_to_freeze();					\
 		schedule();						\
 		mutex_lock(&(ca)->set->bucket_lock);			\
 	}								\
-									\
-	finish_wait(&ca->set->alloc_wait, &__wait);			\
+	__set_current_state(TASK_RUNNING);				\
 } while (0)
 
-void bch_allocator_thread(struct closure *cl)
+static int bch_allocator_thread(void *arg)
 {
-	struct cache *ca = container_of(cl, struct cache, alloc);
+	struct cache *ca = arg;
 
 	mutex_lock(&ca->set->bucket_lock);
 
@@ -442,7 +437,7 @@ long bch_bucket_alloc(struct cache *ca,
 {
 	long r = -1;
 again:
-	wake_up(&ca->set->alloc_wait);
+	wake_up_process(ca->alloc_thread);
 
 	if (fifo_used(&ca->free) > ca->watermark[watermark] &&
 	    fifo_pop(&ca->free, r)) {
@@ -476,9 +471,7 @@ again:
 		return r;
 	}
 
-	pr_debug("alloc failure: blocked %i free %zu free_inc %zu unused %zu",
-		 atomic_read(&ca->set->prio_blocked), fifo_used(&ca->free),
-		 fifo_used(&ca->free_inc), fifo_used(&ca->unused));
+	trace_bcache_alloc_fail(ca);
 
 	if (cl) {
 		closure_wait(&ca->set->bucket_wait, cl);
@@ -552,6 +545,17 @@ int bch_bucket_alloc_set(struct cache_se
 
 /* Init */
 
+int bch_cache_allocator_start(struct cache *ca)
+{
+	struct task_struct *k = kthread_run(bch_allocator_thread,
+					    ca, "bcache_allocator");
+	if (IS_ERR(k))
+		return PTR_ERR(k);
+
+	ca->alloc_thread = k;
+	return 0;
+}
+
 void bch_cache_allocator_exit(struct cache *ca)
 {
 	struct discard *d;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/bcache.h linux-libre-3.11-rc7-gnu/drivers/md/bcache/bcache.h
--- linux-libre-3.10-gnu/drivers/md/bcache/bcache.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/bcache.h	2013-08-25 20:43:22.000000000 -0400
@@ -178,7 +178,6 @@
 #define pr_fmt(fmt) "bcache: %s() " fmt "\n", __func__
 
 #include <linux/bio.h>
-#include <linux/blktrace_api.h>
 #include <linux/kobject.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
@@ -388,8 +387,6 @@ struct keybuf_key {
 typedef bool (keybuf_pred_fn)(struct keybuf *, struct bkey *);
 
 struct keybuf {
-	keybuf_pred_fn		*key_predicate;
-
 	struct bkey		last_scanned;
 	spinlock_t		lock;
 
@@ -437,9 +434,12 @@ struct bcache_device {
 
 	/* If nonzero, we're detaching/unregistering from cache set */
 	atomic_t		detaching;
+	int			flush_done;
+
+	uint64_t		nr_stripes;
+	unsigned		stripe_size_bits;
+	atomic_t		*stripe_sectors_dirty;
 
-	atomic_long_t		sectors_dirty;
-	unsigned long		sectors_dirty_gc;
 	unsigned long		sectors_dirty_last;
 	long			sectors_dirty_derivative;
 
@@ -531,6 +531,7 @@ struct cached_dev {
 	unsigned		sequential_merge:1;
 	unsigned		verify:1;
 
+	unsigned		partial_stripes_expensive:1;
 	unsigned		writeback_metadata:1;
 	unsigned		writeback_running:1;
 	unsigned char		writeback_percent;
@@ -565,8 +566,7 @@ struct cache {
 
 	unsigned		watermark[WATERMARK_MAX];
 
-	struct closure		alloc;
-	struct workqueue_struct	*alloc_workqueue;
+	struct task_struct	*alloc_thread;
 
 	struct closure		prio;
 	struct prio_set		*disk_buckets;
@@ -664,13 +664,9 @@ struct gc_stat {
  * CACHE_SET_STOPPING always gets set first when we're closing down a cache set;
  * we'll continue to run normally for awhile with CACHE_SET_STOPPING set (i.e.
  * flushing dirty data).
- *
- * CACHE_SET_STOPPING_2 gets set at the last phase, when it's time to shut down
- * the allocation thread.
  */
 #define CACHE_SET_UNREGISTERING		0
 #define	CACHE_SET_STOPPING		1
-#define	CACHE_SET_STOPPING_2		2
 
 struct cache_set {
 	struct closure		cl;
@@ -703,9 +699,6 @@ struct cache_set {
 	/* For the btree cache */
 	struct shrinker		shrink;
 
-	/* For the allocator itself */
-	wait_queue_head_t	alloc_wait;
-
 	/* For the btree cache and anything allocation related */
 	struct mutex		bucket_lock;
 
@@ -823,10 +816,9 @@ struct cache_set {
 
 	/*
 	 * A btree node on disk could have too many bsets for an iterator to fit
-	 * on the stack - this is a single element mempool for btree_read_work()
+	 * on the stack - have to dynamically allocate them
 	 */
-	struct mutex		fill_lock;
-	struct btree_iter	*fill_iter;
+	mempool_t		*fill_iter;
 
 	/*
 	 * btree_sort() is a merge sort and requires temporary space - single
@@ -834,6 +826,7 @@ struct cache_set {
 	 */
 	struct mutex		sort_lock;
 	struct bset		*sort;
+	unsigned		sort_crit_factor;
 
 	/* List of buckets we're currently writing data to */
 	struct list_head	data_buckets;
@@ -906,8 +899,6 @@ static inline unsigned local_clock_us(vo
 	return local_clock() >> 10;
 }
 
-#define MAX_BSETS		4U
-
 #define BTREE_PRIO		USHRT_MAX
 #define INITIAL_PRIO		32768
 
@@ -1112,23 +1103,6 @@ static inline void __bkey_put(struct cac
 		atomic_dec_bug(&PTR_BUCKET(c, k, i)->pin);
 }
 
-/* Blktrace macros */
-
-#define blktrace_msg(c, fmt, ...)					\
-do {									\
-	struct request_queue *q = bdev_get_queue(c->bdev);		\
-	if (q)								\
-		blk_add_trace_msg(q, fmt, ##__VA_ARGS__);		\
-} while (0)
-
-#define blktrace_msg_all(s, fmt, ...)					\
-do {									\
-	struct cache *_c;						\
-	unsigned i;							\
-	for_each_cache(_c, (s), i)					\
-		blktrace_msg(_c, fmt, ##__VA_ARGS__);			\
-} while (0)
-
 static inline void cached_dev_put(struct cached_dev *dc)
 {
 	if (atomic_dec_and_test(&dc->count))
@@ -1173,10 +1147,16 @@ static inline uint8_t bucket_disk_gen(st
 	static struct kobj_attribute ksysfs_##n =			\
 		__ATTR(n, S_IWUSR|S_IRUSR, show, store)
 
-/* Forward declarations */
+static inline void wake_up_allocators(struct cache_set *c)
+{
+	struct cache *ca;
+	unsigned i;
 
-void bch_writeback_queue(struct cached_dev *);
-void bch_writeback_add(struct cached_dev *, unsigned);
+	for_each_cache(ca, c, i)
+		wake_up_process(ca->alloc_thread);
+}
+
+/* Forward declarations */
 
 void bch_count_io_errors(struct cache *, int, const char *);
 void bch_bbio_count_io_errors(struct cache_set *, struct bio *,
@@ -1193,7 +1173,6 @@ void bch_submit_bbio(struct bio *, struc
 uint8_t bch_inc_gen(struct cache *, struct bucket *);
 void bch_rescale_priorities(struct cache_set *, int);
 bool bch_bucket_add_unused(struct cache *, struct bucket *);
-void bch_allocator_thread(struct closure *);
 
 long bch_bucket_alloc(struct cache *, unsigned, struct closure *);
 void bch_bucket_free(struct cache_set *, struct bkey *);
@@ -1241,9 +1220,9 @@ void bch_cache_set_stop(struct cache_set
 struct cache_set *bch_cache_set_alloc(struct cache_sb *);
 void bch_btree_cache_free(struct cache_set *);
 int bch_btree_cache_alloc(struct cache_set *);
-void bch_cached_dev_writeback_init(struct cached_dev *);
 void bch_moving_init_cache_set(struct cache_set *);
 
+int bch_cache_allocator_start(struct cache *ca);
 void bch_cache_allocator_exit(struct cache *ca);
 int bch_cache_allocator_init(struct cache *ca);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/bset.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/bset.c
--- linux-libre-3.10-gnu/drivers/md/bcache/bset.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/bset.c	2013-08-25 20:43:22.000000000 -0400
@@ -78,6 +78,7 @@ struct bkey *bch_keylist_pop(struct keyl
 bool __bch_ptr_invalid(struct cache_set *c, int level, const struct bkey *k)
 {
 	unsigned i;
+	char buf[80];
 
 	if (level && (!KEY_PTRS(k) || !KEY_SIZE(k) || KEY_DIRTY(k)))
 		goto bad;
@@ -102,7 +103,8 @@ bool __bch_ptr_invalid(struct cache_set
 
 	return false;
 bad:
-	cache_bug(c, "spotted bad key %s: %s", pkey(k), bch_ptr_status(c, k));
+	bch_bkey_to_text(buf, sizeof(buf), k);
+	cache_bug(c, "spotted bad key %s: %s", buf, bch_ptr_status(c, k));
 	return true;
 }
 
@@ -162,10 +164,16 @@ bool bch_ptr_bad(struct btree *b, const
 #ifdef CONFIG_BCACHE_EDEBUG
 bug:
 	mutex_unlock(&b->c->bucket_lock);
-	btree_bug(b,
+
+	{
+		char buf[80];
+
+		bch_bkey_to_text(buf, sizeof(buf), k);
+		btree_bug(b,
 "inconsistent pointer %s: bucket %zu pin %i prio %i gen %i last_gc %i mark %llu gc_gen %i",
-		  pkey(k), PTR_BUCKET_NR(b->c, k, i), atomic_read(&g->pin),
-		  g->prio, g->gen, g->last_gc, GC_MARK(g), g->gc_gen);
+			  buf, PTR_BUCKET_NR(b->c, k, i), atomic_read(&g->pin),
+			  g->prio, g->gen, g->last_gc, GC_MARK(g), g->gc_gen);
+	}
 	return true;
 #endif
 }
@@ -395,7 +403,7 @@ void inorder_test(void)
 #endif
 
 /*
- * Cacheline/offset <-> bkey pointer arithmatic:
+ * Cacheline/offset <-> bkey pointer arithmetic:
  *
  * t->tree is a binary search tree in an array; each node corresponds to a key
  * in one cacheline in t->set (BSET_CACHELINE bytes).
@@ -404,7 +412,7 @@ void inorder_test(void)
  * the binary tree points to; to_inorder() gives us the cacheline, and then
  * bkey_float->m gives us the offset within that cacheline, in units of 8 bytes.
  *
- * cacheline_to_bkey() and friends abstract out all the pointer arithmatic to
+ * cacheline_to_bkey() and friends abstract out all the pointer arithmetic to
  * make this work.
  *
  * To construct the bfloat for an arbitrary key we need to know what the key
@@ -1084,33 +1092,39 @@ void bch_btree_sort_into(struct btree *b
 	new->sets->size = 0;
 }
 
+#define SORT_CRIT	(4096 / sizeof(uint64_t))
+
 void bch_btree_sort_lazy(struct btree *b)
 {
-	if (b->nsets) {
-		unsigned i, j, keys = 0, total;
-
-		for (i = 0; i <= b->nsets; i++)
-			keys += b->sets[i].data->keys;
+	unsigned crit = SORT_CRIT;
+	int i;
 
-		total = keys;
+	/* Don't sort if nothing to do */
+	if (!b->nsets)
+		goto out;
 
-		for (j = 0; j < b->nsets; j++) {
-			if (keys * 2 < total ||
-			    keys < 1000) {
-				bch_btree_sort_partial(b, j);
-				return;
-			}
+	/* If not a leaf node, always sort */
+	if (b->level) {
+		bch_btree_sort(b);
+		return;
+	}
 
-			keys -= b->sets[j].data->keys;
-		}
+	for (i = b->nsets - 1; i >= 0; --i) {
+		crit *= b->c->sort_crit_factor;
 
-		/* Must sort if b->nsets == 3 or we'll overflow */
-		if (b->nsets >= (MAX_BSETS - 1) - b->level) {
-			bch_btree_sort(b);
+		if (b->sets[i].data->keys < crit) {
+			bch_btree_sort_partial(b, i);
 			return;
 		}
 	}
 
+	/* Sort if we'd overflow */
+	if (b->nsets + 1 == MAX_BSETS) {
+		bch_btree_sort(b);
+		return;
+	}
+
+out:
 	bset_build_written_tree(b);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/bset.h linux-libre-3.11-rc7-gnu/drivers/md/bcache/bset.h
--- linux-libre-3.10-gnu/drivers/md/bcache/bset.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/bset.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,8 @@
 #ifndef _BCACHE_BSET_H
 #define _BCACHE_BSET_H
 
+#include <linux/slab.h>
+
 /*
  * BKEYS:
  *
@@ -142,6 +144,8 @@
 
 /* Btree key comparison/iteration */
 
+#define MAX_BSETS		4U
+
 struct btree_iter {
 	size_t size, used;
 	struct btree_iter_set {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/btree.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/btree.c
--- linux-libre-3.10-gnu/drivers/md/bcache/btree.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/btree.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@
 #include "btree.h"
 #include "debug.h"
 #include "request.h"
+#include "writeback.h"
 
 #include <linux/slab.h>
 #include <linux/bitops.h>
@@ -134,44 +135,17 @@ static uint64_t btree_csum_set(struct bt
 	return crc ^ 0xffffffffffffffffULL;
 }
 
-static void btree_bio_endio(struct bio *bio, int error)
-{
-	struct closure *cl = bio->bi_private;
-	struct btree *b = container_of(cl, struct btree, io.cl);
-
-	if (error)
-		set_btree_node_io_error(b);
-
-	bch_bbio_count_io_errors(b->c, bio, error, (bio->bi_rw & WRITE)
-				 ? "writing btree" : "reading btree");
-	closure_put(cl);
-}
-
-static void btree_bio_init(struct btree *b)
-{
-	BUG_ON(b->bio);
-	b->bio = bch_bbio_alloc(b->c);
-
-	b->bio->bi_end_io	= btree_bio_endio;
-	b->bio->bi_private	= &b->io.cl;
-}
-
-void bch_btree_read_done(struct closure *cl)
+static void bch_btree_node_read_done(struct btree *b)
 {
-	struct btree *b = container_of(cl, struct btree, io.cl);
-	struct bset *i = b->sets[0].data;
-	struct btree_iter *iter = b->c->fill_iter;
 	const char *err = "bad btree header";
-	BUG_ON(b->nsets || b->written);
-
-	bch_bbio_free(b->bio, b->c);
-	b->bio = NULL;
+	struct bset *i = b->sets[0].data;
+	struct btree_iter *iter;
 
-	mutex_lock(&b->c->fill_lock);
+	iter = mempool_alloc(b->c->fill_iter, GFP_NOWAIT);
+	iter->size = b->c->sb.bucket_size / b->c->sb.block_size;
 	iter->used = 0;
 
-	if (btree_node_io_error(b) ||
-	    !i->seq)
+	if (!i->seq)
 		goto err;
 
 	for (;
@@ -228,17 +202,8 @@ void bch_btree_read_done(struct closure
 	if (b->written < btree_blocks(b))
 		bch_bset_init_next(b);
 out:
-
-	mutex_unlock(&b->c->fill_lock);
-
-	spin_lock(&b->c->btree_read_time_lock);
-	bch_time_stats_update(&b->c->btree_read_time, b->io_start_time);
-	spin_unlock(&b->c->btree_read_time_lock);
-
-	smp_wmb(); /* read_done is our write lock */
-	set_btree_node_read_done(b);
-
-	closure_return(cl);
+	mempool_free(iter, b->c->fill_iter);
+	return;
 err:
 	set_btree_node_io_error(b);
 	bch_cache_set_error(b->c, "%s at bucket %zu, block %zu, %u keys",
@@ -247,48 +212,69 @@ err:
 	goto out;
 }
 
-void bch_btree_read(struct btree *b)
+static void btree_node_read_endio(struct bio *bio, int error)
 {
-	BUG_ON(b->nsets || b->written);
+	struct closure *cl = bio->bi_private;
+	closure_put(cl);
+}
 
-	if (!closure_trylock(&b->io.cl, &b->c->cl))
-		BUG();
+void bch_btree_node_read(struct btree *b)
+{
+	uint64_t start_time = local_clock();
+	struct closure cl;
+	struct bio *bio;
 
-	b->io_start_time = local_clock();
+	trace_bcache_btree_read(b);
 
-	btree_bio_init(b);
-	b->bio->bi_rw	= REQ_META|READ_SYNC;
-	b->bio->bi_size	= KEY_SIZE(&b->key) << 9;
+	closure_init_stack(&cl);
 
-	bch_bio_map(b->bio, b->sets[0].data);
+	bio = bch_bbio_alloc(b->c);
+	bio->bi_rw	= REQ_META|READ_SYNC;
+	bio->bi_size	= KEY_SIZE(&b->key) << 9;
+	bio->bi_end_io	= btree_node_read_endio;
+	bio->bi_private	= &cl;
 
-	pr_debug("%s", pbtree(b));
-	trace_bcache_btree_read(b->bio);
-	bch_submit_bbio(b->bio, b->c, &b->key, 0);
+	bch_bio_map(bio, b->sets[0].data);
 
-	continue_at(&b->io.cl, bch_btree_read_done, system_wq);
+	bch_submit_bbio(bio, b->c, &b->key, 0);
+	closure_sync(&cl);
+
+	if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+		set_btree_node_io_error(b);
+
+	bch_bbio_free(bio, b->c);
+
+	if (btree_node_io_error(b))
+		goto err;
+
+	bch_btree_node_read_done(b);
+
+	spin_lock(&b->c->btree_read_time_lock);
+	bch_time_stats_update(&b->c->btree_read_time, start_time);
+	spin_unlock(&b->c->btree_read_time_lock);
+
+	return;
+err:
+	bch_cache_set_error(b->c, "io error reading bucket %lu",
+			    PTR_BUCKET_NR(b->c, &b->key, 0));
 }
 
 static void btree_complete_write(struct btree *b, struct btree_write *w)
 {
 	if (w->prio_blocked &&
 	    !atomic_sub_return(w->prio_blocked, &b->c->prio_blocked))
-		wake_up(&b->c->alloc_wait);
+		wake_up_allocators(b->c);
 
 	if (w->journal) {
 		atomic_dec_bug(w->journal);
 		__closure_wake_up(&b->c->journal.wait);
 	}
 
-	if (w->owner)
-		closure_put(w->owner);
-
 	w->prio_blocked	= 0;
 	w->journal	= NULL;
-	w->owner	= NULL;
 }
 
-static void __btree_write_done(struct closure *cl)
+static void __btree_node_write_done(struct closure *cl)
 {
 	struct btree *b = container_of(cl, struct btree, io.cl);
 	struct btree_write *w = btree_prev_write(b);
@@ -304,7 +290,7 @@ static void __btree_write_done(struct cl
 	closure_return(cl);
 }
 
-static void btree_write_done(struct closure *cl)
+static void btree_node_write_done(struct closure *cl)
 {
 	struct btree *b = container_of(cl, struct btree, io.cl);
 	struct bio_vec *bv;
@@ -313,10 +299,22 @@ static void btree_write_done(struct clos
 	__bio_for_each_segment(bv, b->bio, n, 0)
 		__free_page(bv->bv_page);
 
-	__btree_write_done(cl);
+	__btree_node_write_done(cl);
 }
 
-static void do_btree_write(struct btree *b)
+static void btree_node_write_endio(struct bio *bio, int error)
+{
+	struct closure *cl = bio->bi_private;
+	struct btree *b = container_of(cl, struct btree, io.cl);
+
+	if (error)
+		set_btree_node_io_error(b);
+
+	bch_bbio_count_io_errors(b->c, bio, error, "writing btree");
+	closure_put(cl);
+}
+
+static void do_btree_node_write(struct btree *b)
 {
 	struct closure *cl = &b->io.cl;
 	struct bset *i = b->sets[b->nsets].data;
@@ -325,15 +323,34 @@ static void do_btree_write(struct btree
 	i->version	= BCACHE_BSET_VERSION;
 	i->csum		= btree_csum_set(b, i);
 
-	btree_bio_init(b);
-	b->bio->bi_rw	= REQ_META|WRITE_SYNC;
-	b->bio->bi_size	= set_blocks(i, b->c) * block_bytes(b->c);
+	BUG_ON(b->bio);
+	b->bio = bch_bbio_alloc(b->c);
+
+	b->bio->bi_end_io	= btree_node_write_endio;
+	b->bio->bi_private	= &b->io.cl;
+	b->bio->bi_rw		= REQ_META|WRITE_SYNC|REQ_FUA;
+	b->bio->bi_size		= set_blocks(i, b->c) * block_bytes(b->c);
 	bch_bio_map(b->bio, i);
 
+	/*
+	 * If we're appending to a leaf node, we don't technically need FUA -
+	 * this write just needs to be persisted before the next journal write,
+	 * which will be marked FLUSH|FUA.
+	 *
+	 * Similarly if we're writing a new btree root - the pointer is going to
+	 * be in the next journal entry.
+	 *
+	 * But if we're writing a new btree node (that isn't a root) or
+	 * appending to a non leaf btree node, we need either FUA or a flush
+	 * when we write the parent with the new pointer. FUA is cheaper than a
+	 * flush, and writes appending to leaf nodes aren't blocking anything so
+	 * just make all btree node writes FUA to keep things sane.
+	 */
+
 	bkey_copy(&k.key, &b->key);
 	SET_PTR_OFFSET(&k.key, 0, PTR_OFFSET(&k.key, 0) + bset_offset(b, i));
 
-	if (!bch_bio_alloc_pages(b->bio, GFP_NOIO)) {
+	if (!bio_alloc_pages(b->bio, GFP_NOIO)) {
 		int j;
 		struct bio_vec *bv;
 		void *base = (void *) ((unsigned long) i & ~(PAGE_SIZE - 1));
@@ -342,40 +359,41 @@ static void do_btree_write(struct btree
 			memcpy(page_address(bv->bv_page),
 			       base + j * PAGE_SIZE, PAGE_SIZE);
 
-		trace_bcache_btree_write(b->bio);
 		bch_submit_bbio(b->bio, b->c, &k.key, 0);
 
-		continue_at(cl, btree_write_done, NULL);
+		continue_at(cl, btree_node_write_done, NULL);
 	} else {
 		b->bio->bi_vcnt = 0;
 		bch_bio_map(b->bio, i);
 
-		trace_bcache_btree_write(b->bio);
 		bch_submit_bbio(b->bio, b->c, &k.key, 0);
 
 		closure_sync(cl);
-		__btree_write_done(cl);
+		__btree_node_write_done(cl);
 	}
 }
 
-static void __btree_write(struct btree *b)
+void bch_btree_node_write(struct btree *b, struct closure *parent)
 {
 	struct bset *i = b->sets[b->nsets].data;
 
+	trace_bcache_btree_write(b);
+
 	BUG_ON(current->bio_list);
+	BUG_ON(b->written >= btree_blocks(b));
+	BUG_ON(b->written && !i->keys);
+	BUG_ON(b->sets->data->seq != i->seq);
+	bch_check_key_order(b, i);
 
-	closure_lock(&b->io, &b->c->cl);
 	cancel_delayed_work(&b->work);
 
+	/* If caller isn't waiting for write, parent refcount is cache set */
+	closure_lock(&b->io, parent ?: &b->c->cl);
+
 	clear_bit(BTREE_NODE_dirty,	 &b->flags);
 	change_bit(BTREE_NODE_write_idx, &b->flags);
 
-	bch_check_key_order(b, i);
-	BUG_ON(b->written && !i->keys);
-
-	do_btree_write(b);
-
-	pr_debug("%s block %i keys %i", pbtree(b), b->written, i->keys);
+	do_btree_node_write(b);
 
 	b->written += set_blocks(i, b->c);
 	atomic_long_add(set_blocks(i, b->c) * b->c->sb.block_size,
@@ -387,37 +405,31 @@ static void __btree_write(struct btree *
 		bch_bset_init_next(b);
 }
 
-static void btree_write_work(struct work_struct *w)
+static void btree_node_write_work(struct work_struct *w)
 {
 	struct btree *b = container_of(to_delayed_work(w), struct btree, work);
 
-	down_write(&b->lock);
+	rw_lock(true, b, b->level);
 
 	if (btree_node_dirty(b))
-		__btree_write(b);
-	up_write(&b->lock);
+		bch_btree_node_write(b, NULL);
+	rw_unlock(true, b);
 }
 
-void bch_btree_write(struct btree *b, bool now, struct btree_op *op)
+static void bch_btree_leaf_dirty(struct btree *b, struct btree_op *op)
 {
 	struct bset *i = b->sets[b->nsets].data;
 	struct btree_write *w = btree_current_write(b);
 
-	BUG_ON(b->written &&
-	       (b->written >= btree_blocks(b) ||
-		i->seq != b->sets[0].data->seq ||
-		!i->keys));
+	BUG_ON(!b->written);
+	BUG_ON(!i->keys);
 
-	if (!btree_node_dirty(b)) {
-		set_btree_node_dirty(b);
-		queue_delayed_work(btree_io_wq, &b->work,
-				   msecs_to_jiffies(30000));
-	}
+	if (!btree_node_dirty(b))
+		queue_delayed_work(btree_io_wq, &b->work, 30 * HZ);
 
-	w->prio_blocked += b->prio_blocked;
-	b->prio_blocked = 0;
+	set_btree_node_dirty(b);
 
-	if (op && op->journal && !b->level) {
+	if (op && op->journal) {
 		if (w->journal &&
 		    journal_pin_cmp(b->c, w, op)) {
 			atomic_dec_bug(w->journal);
@@ -430,23 +442,10 @@ void bch_btree_write(struct btree *b, bo
 		}
 	}
 
-	if (current->bio_list)
-		return;
-
 	/* Force write if set is too big */
-	if (now ||
-	    b->level ||
-	    set_bytes(i) > PAGE_SIZE - 48) {
-		if (op && now) {
-			/* Must wait on multiple writes */
-			BUG_ON(w->owner);
-			w->owner = &op->cl;
-			closure_get(&op->cl);
-		}
-
-		__btree_write(b);
-	}
-	BUG_ON(!b->written);
+	if (set_bytes(i) > PAGE_SIZE - 48 &&
+	    !current->bio_list)
+		bch_btree_node_write(b, NULL);
 }
 
 /*
@@ -559,7 +558,7 @@ static struct btree *mca_bucket_alloc(st
 	init_rwsem(&b->lock);
 	lockdep_set_novalidate_class(&b->lock);
 	INIT_LIST_HEAD(&b->list);
-	INIT_DELAYED_WORK(&b->work, btree_write_work);
+	INIT_DELAYED_WORK(&b->work, btree_node_write_work);
 	b->c = c;
 	closure_init_unlocked(&b->io);
 
@@ -582,7 +581,7 @@ static int mca_reap(struct btree *b, str
 	BUG_ON(btree_node_dirty(b) && !b->sets[0].data);
 
 	if (cl && btree_node_dirty(b))
-		bch_btree_write(b, true, NULL);
+		bch_btree_node_write(b, NULL);
 
 	if (cl)
 		closure_wait_event_async(&b->io.wait, cl,
@@ -623,6 +622,13 @@ static int bch_mca_shrink(struct shrinke
 	else if (!mutex_trylock(&c->bucket_lock))
 		return -1;
 
+	/*
+	 * It's _really_ critical that we don't free too many btree nodes - we
+	 * have to always leave ourselves a reserve. The reserve is how we
+	 * guarantee that allocating memory for a new btree node can always
+	 * succeed, so that inserting keys into the btree can always succeed and
+	 * IO can always make forward progress:
+	 */
 	nr /= c->btree_pages;
 	nr = min_t(unsigned long, nr, mca_can_free(c));
 
@@ -766,6 +772,8 @@ static struct btree *mca_cannibalize(str
 	int ret = -ENOMEM;
 	struct btree *i;
 
+	trace_bcache_btree_cache_cannibalize(c);
+
 	if (!cl)
 		return ERR_PTR(-ENOMEM);
 
@@ -784,7 +792,6 @@ static struct btree *mca_cannibalize(str
 		return ERR_PTR(-EAGAIN);
 	}
 
-	/* XXX: tracepoint */
 	c->try_harder = cl;
 	c->try_harder_start = local_clock();
 retry:
@@ -905,6 +912,9 @@ retry:
 	b = mca_find(c, k);
 
 	if (!b) {
+		if (current->bio_list)
+			return ERR_PTR(-EAGAIN);
+
 		mutex_lock(&c->bucket_lock);
 		b = mca_alloc(c, k, level, &op->cl);
 		mutex_unlock(&c->bucket_lock);
@@ -914,7 +924,7 @@ retry:
 		if (IS_ERR(b))
 			return b;
 
-		bch_btree_read(b);
+		bch_btree_node_read(b);
 
 		if (!write)
 			downgrade_write(&b->lock);
@@ -937,15 +947,12 @@ retry:
 	for (; i <= b->nsets; i++)
 		prefetch(b->sets[i].data);
 
-	if (!closure_wait_event(&b->io.wait, &op->cl,
-				btree_node_read_done(b))) {
-		rw_unlock(write, b);
-		b = ERR_PTR(-EAGAIN);
-	} else if (btree_node_io_error(b)) {
+	if (btree_node_io_error(b)) {
 		rw_unlock(write, b);
-		b = ERR_PTR(-EIO);
-	} else
-		BUG_ON(!b->written);
+		return ERR_PTR(-EIO);
+	}
+
+	BUG_ON(!b->written);
 
 	return b;
 }
@@ -959,7 +966,7 @@ static void btree_node_prefetch(struct c
 	mutex_unlock(&c->bucket_lock);
 
 	if (!IS_ERR_OR_NULL(b)) {
-		bch_btree_read(b);
+		bch_btree_node_read(b);
 		rw_unlock(true, b);
 	}
 }
@@ -970,24 +977,19 @@ static void btree_node_free(struct btree
 {
 	unsigned i;
 
+	trace_bcache_btree_node_free(b);
+
 	/*
 	 * The BUG_ON() in btree_node_get() implies that we must have a write
 	 * lock on parent to free or even invalidate a node
 	 */
 	BUG_ON(op->lock <= b->level);
 	BUG_ON(b == b->c->root);
-	pr_debug("bucket %s", pbtree(b));
 
 	if (btree_node_dirty(b))
 		btree_complete_write(b, btree_current_write(b));
 	clear_bit(BTREE_NODE_dirty, &b->flags);
 
-	if (b->prio_blocked &&
-	    !atomic_sub_return(b->prio_blocked, &b->c->prio_blocked))
-		wake_up(&b->c->alloc_wait);
-
-	b->prio_blocked = 0;
-
 	cancel_delayed_work(&b->work);
 
 	mutex_lock(&b->c->bucket_lock);
@@ -1028,17 +1030,20 @@ retry:
 		goto retry;
 	}
 
-	set_btree_node_read_done(b);
 	b->accessed = 1;
 	bch_bset_init_next(b);
 
 	mutex_unlock(&c->bucket_lock);
+
+	trace_bcache_btree_node_alloc(b);
 	return b;
 err_free:
 	bch_bucket_free(c, &k.key);
 	__bkey_put(c, &k.key);
 err:
 	mutex_unlock(&c->bucket_lock);
+
+	trace_bcache_btree_node_alloc_fail(b);
 	return b;
 }
 
@@ -1137,11 +1142,8 @@ static int btree_gc_mark_node(struct btr
 		gc->nkeys++;
 
 		gc->data += KEY_SIZE(k);
-		if (KEY_DIRTY(k)) {
+		if (KEY_DIRTY(k))
 			gc->dirty += KEY_SIZE(k);
-			if (d)
-				d->sectors_dirty_gc += KEY_SIZE(k);
-		}
 	}
 
 	for (t = b->sets; t <= &b->sets[b->nsets]; t++)
@@ -1166,14 +1168,11 @@ static struct btree *btree_gc_alloc(stru
 
 	if (!IS_ERR_OR_NULL(n)) {
 		swap(b, n);
+		__bkey_put(b->c, &b->key);
 
 		memcpy(k->ptr, b->key.ptr,
 		       sizeof(uint64_t) * KEY_PTRS(&b->key));
 
-		__bkey_put(b->c, &b->key);
-		atomic_inc(&b->c->prio_blocked);
-		b->prio_blocked++;
-
 		btree_node_free(n, op);
 		up_write(&n->lock);
 	}
@@ -1278,7 +1277,7 @@ static void btree_gc_coalesce(struct btr
 	btree_node_free(r->b, op);
 	up_write(&r->b->lock);
 
-	pr_debug("coalesced %u nodes", nodes);
+	trace_bcache_btree_gc_coalesce(nodes);
 
 	gc->nodes--;
 	nodes--;
@@ -1293,14 +1292,9 @@ static int btree_gc_recurse(struct btree
 	void write(struct btree *r)
 	{
 		if (!r->written)
-			bch_btree_write(r, true, op);
-		else if (btree_node_dirty(r)) {
-			BUG_ON(btree_current_write(r)->owner);
-			btree_current_write(r)->owner = writes;
-			closure_get(writes);
-
-			bch_btree_write(r, true, NULL);
-		}
+			bch_btree_node_write(r, &op->cl);
+		else if (btree_node_dirty(r))
+			bch_btree_node_write(r, writes);
 
 		up_write(&r->lock);
 	}
@@ -1386,9 +1380,7 @@ static int bch_btree_gc_root(struct btre
 		ret = btree_gc_recurse(b, op, writes, gc);
 
 	if (!b->written || btree_node_dirty(b)) {
-		atomic_inc(&b->c->prio_blocked);
-		b->prio_blocked++;
-		bch_btree_write(b, true, n ? op : NULL);
+		bch_btree_node_write(b, n ? &op->cl : NULL);
 	}
 
 	if (!IS_ERR_OR_NULL(n)) {
@@ -1405,7 +1397,6 @@ static void btree_gc_start(struct cache_
 {
 	struct cache *ca;
 	struct bucket *b;
-	struct bcache_device **d;
 	unsigned i;
 
 	if (!c->gc_mark_valid)
@@ -1419,16 +1410,12 @@ static void btree_gc_start(struct cache_
 	for_each_cache(ca, c, i)
 		for_each_bucket(b, ca) {
 			b->gc_gen = b->gen;
-			if (!atomic_read(&b->pin))
+			if (!atomic_read(&b->pin)) {
 				SET_GC_MARK(b, GC_MARK_RECLAIMABLE);
+				SET_GC_SECTORS_USED(b, 0);
+			}
 		}
 
-	for (d = c->devices;
-	     d < c->devices + c->nr_uuids;
-	     d++)
-		if (*d)
-			(*d)->sectors_dirty_gc = 0;
-
 	mutex_unlock(&c->bucket_lock);
 }
 
@@ -1437,7 +1424,6 @@ size_t bch_btree_gc_finish(struct cache_
 	size_t available = 0;
 	struct bucket *b;
 	struct cache *ca;
-	struct bcache_device **d;
 	unsigned i;
 
 	mutex_lock(&c->bucket_lock);
@@ -1480,22 +1466,6 @@ size_t bch_btree_gc_finish(struct cache_
 		}
 	}
 
-	for (d = c->devices;
-	     d < c->devices + c->nr_uuids;
-	     d++)
-		if (*d) {
-			unsigned long last =
-				atomic_long_read(&((*d)->sectors_dirty));
-			long difference = (*d)->sectors_dirty_gc - last;
-
-			pr_debug("sectors dirty off by %li", difference);
-
-			(*d)->sectors_dirty_last += difference;
-
-			atomic_long_set(&((*d)->sectors_dirty),
-					(*d)->sectors_dirty_gc);
-		}
-
 	mutex_unlock(&c->bucket_lock);
 	return available;
 }
@@ -1508,10 +1478,9 @@ static void bch_btree_gc(struct closure
 	struct gc_stat stats;
 	struct closure writes;
 	struct btree_op op;
-
 	uint64_t start_time = local_clock();
-	trace_bcache_gc_start(c->sb.set_uuid);
-	blktrace_msg_all(c, "Starting gc");
+
+	trace_bcache_gc_start(c);
 
 	memset(&stats, 0, sizeof(struct gc_stat));
 	closure_init_stack(&writes);
@@ -1520,14 +1489,14 @@ static void bch_btree_gc(struct closure
 
 	btree_gc_start(c);
 
+	atomic_inc(&c->prio_blocked);
+
 	ret = btree_root(gc_root, c, &op, &writes, &stats);
 	closure_sync(&op.cl);
 	closure_sync(&writes);
 
 	if (ret) {
-		blktrace_msg_all(c, "Stopped gc");
 		pr_warn("gc failed!");
-
 		continue_at(cl, bch_btree_gc, bch_gc_wq);
 	}
 
@@ -1537,6 +1506,9 @@ static void bch_btree_gc(struct closure
 
 	available = bch_btree_gc_finish(c);
 
+	atomic_dec(&c->prio_blocked);
+	wake_up_allocators(c);
+
 	bch_time_stats_update(&c->btree_gc_time, start_time);
 
 	stats.key_bytes *= sizeof(uint64_t);
@@ -1544,10 +1516,8 @@ static void bch_btree_gc(struct closure
 	stats.data	<<= 9;
 	stats.in_use	= (c->nbuckets - available) * 100 / c->nbuckets;
 	memcpy(&c->gc_stats, &stats, sizeof(struct gc_stat));
-	blktrace_msg_all(c, "Finished gc");
 
-	trace_bcache_gc_end(c->sb.set_uuid);
-	wake_up(&c->alloc_wait);
+	trace_bcache_gc_end(c);
 
 	continue_at(cl, bch_moving_gc, bch_gc_wq);
 }
@@ -1654,14 +1624,14 @@ static bool fix_overlapping_extents(stru
 				    struct btree_iter *iter,
 				    struct btree_op *op)
 {
-	void subtract_dirty(struct bkey *k, int sectors)
+	void subtract_dirty(struct bkey *k, uint64_t offset, int sectors)
 	{
-		struct bcache_device *d = b->c->devices[KEY_INODE(k)];
-
-		if (KEY_DIRTY(k) && d)
-			atomic_long_sub(sectors, &d->sectors_dirty);
+		if (KEY_DIRTY(k))
+			bcache_dev_sectors_dirty_add(b->c, KEY_INODE(k),
+						     offset, -sectors);
 	}
 
+	uint64_t old_offset;
 	unsigned old_size, sectors_found = 0;
 
 	while (1) {
@@ -1673,6 +1643,7 @@ static bool fix_overlapping_extents(stru
 		if (bkey_cmp(k, &START_KEY(insert)) <= 0)
 			continue;
 
+		old_offset = KEY_START(k);
 		old_size = KEY_SIZE(k);
 
 		/*
@@ -1728,7 +1699,7 @@ static bool fix_overlapping_extents(stru
 
 			struct bkey *top;
 
-			subtract_dirty(k, KEY_SIZE(insert));
+			subtract_dirty(k, KEY_START(insert), KEY_SIZE(insert));
 
 			if (bkey_written(b, k)) {
 				/*
@@ -1775,7 +1746,7 @@ static bool fix_overlapping_extents(stru
 			}
 		}
 
-		subtract_dirty(k, old_size - KEY_SIZE(k));
+		subtract_dirty(k, old_offset, old_size - KEY_SIZE(k));
 	}
 
 check_failed:
@@ -1798,7 +1769,7 @@ static bool btree_insert_key(struct btre
 {
 	struct bset *i = b->sets[b->nsets].data;
 	struct bkey *m, *prev;
-	const char *status = "insert";
+	unsigned status = BTREE_INSERT_STATUS_INSERT;
 
 	BUG_ON(bkey_cmp(k, &b->key) > 0);
 	BUG_ON(b->level && !KEY_PTRS(k));
@@ -1831,17 +1802,17 @@ static bool btree_insert_key(struct btre
 			goto insert;
 
 		/* prev is in the tree, if we merge we're done */
-		status = "back merging";
+		status = BTREE_INSERT_STATUS_BACK_MERGE;
 		if (prev &&
 		    bch_bkey_try_merge(b, prev, k))
 			goto merged;
 
-		status = "overwrote front";
+		status = BTREE_INSERT_STATUS_OVERWROTE;
 		if (m != end(i) &&
 		    KEY_PTRS(m) == KEY_PTRS(k) && !KEY_SIZE(m))
 			goto copy;
 
-		status = "front merge";
+		status = BTREE_INSERT_STATUS_FRONT_MERGE;
 		if (m != end(i) &&
 		    bch_bkey_try_merge(b, k, m))
 			goto copy;
@@ -1851,21 +1822,21 @@ static bool btree_insert_key(struct btre
 insert:	shift_keys(b, m, k);
 copy:	bkey_copy(m, k);
 merged:
-	bch_check_keys(b, "%s for %s at %s: %s", status,
-		       op_type(op), pbtree(b), pkey(k));
-	bch_check_key_order_msg(b, i, "%s for %s at %s: %s", status,
-				op_type(op), pbtree(b), pkey(k));
+	if (KEY_DIRTY(k))
+		bcache_dev_sectors_dirty_add(b->c, KEY_INODE(k),
+					     KEY_START(k), KEY_SIZE(k));
+
+	bch_check_keys(b, "%u for %s", status, op_type(op));
 
 	if (b->level && !KEY_OFFSET(k))
-		b->prio_blocked++;
+		btree_current_write(b)->prio_blocked++;
 
-	pr_debug("%s for %s at %s: %s", status,
-		 op_type(op), pbtree(b), pkey(k));
+	trace_bcache_btree_insert_key(b, k, op->type, status);
 
 	return true;
 }
 
-bool bch_btree_insert_keys(struct btree *b, struct btree_op *op)
+static bool bch_btree_insert_keys(struct btree *b, struct btree_op *op)
 {
 	bool ret = false;
 	struct bkey *k;
@@ -1896,7 +1867,7 @@ bool bch_btree_insert_check_key(struct b
 	    should_split(b))
 		goto out;
 
-	op->replace = KEY(op->inode, bio_end(bio), bio_sectors(bio));
+	op->replace = KEY(op->inode, bio_end_sector(bio), bio_sectors(bio));
 
 	SET_KEY_PTRS(&op->replace, 1);
 	get_random_bytes(&op->replace.ptr[0], sizeof(uint64_t));
@@ -1907,7 +1878,6 @@ bool bch_btree_insert_check_key(struct b
 
 	BUG_ON(op->type != BTREE_INSERT);
 	BUG_ON(!btree_insert_key(b, op, &tmp.k));
-	bch_btree_write(b, false, NULL);
 	ret = true;
 out:
 	downgrade_write(&b->lock);
@@ -1929,12 +1899,11 @@ static int btree_split(struct btree *b,
 
 	split = set_blocks(n1->sets[0].data, n1->c) > (btree_blocks(b) * 4) / 5;
 
-	pr_debug("%ssplitting at %s keys %i", split ? "" : "not ",
-		 pbtree(b), n1->sets[0].data->keys);
-
 	if (split) {
 		unsigned keys = 0;
 
+		trace_bcache_btree_node_split(b, n1->sets[0].data->keys);
+
 		n2 = bch_btree_node_alloc(b->c, b->level, &op->cl);
 		if (IS_ERR(n2))
 			goto err_free1;
@@ -1967,18 +1936,21 @@ static int btree_split(struct btree *b,
 		bkey_copy_key(&n2->key, &b->key);
 
 		bch_keylist_add(&op->keys, &n2->key);
-		bch_btree_write(n2, true, op);
+		bch_btree_node_write(n2, &op->cl);
 		rw_unlock(true, n2);
-	} else
+	} else {
+		trace_bcache_btree_node_compact(b, n1->sets[0].data->keys);
+
 		bch_btree_insert_keys(n1, op);
+	}
 
 	bch_keylist_add(&op->keys, &n1->key);
-	bch_btree_write(n1, true, op);
+	bch_btree_node_write(n1, &op->cl);
 
 	if (n3) {
 		bkey_copy_key(&n3->key, &MAX_KEY);
 		bch_btree_insert_keys(n3, op);
-		bch_btree_write(n3, true, op);
+		bch_btree_node_write(n3, &op->cl);
 
 		closure_sync(&op->cl);
 		bch_btree_set_root(n3);
@@ -2082,8 +2054,12 @@ static int bch_btree_insert_recurse(stru
 
 		BUG_ON(write_block(b) != b->sets[b->nsets].data);
 
-		if (bch_btree_insert_keys(b, op))
-			bch_btree_write(b, false, op);
+		if (bch_btree_insert_keys(b, op)) {
+			if (!b->level)
+				bch_btree_leaf_dirty(b, op);
+			else
+				bch_btree_node_write(b, &op->cl);
+		}
 	}
 
 	return 0;
@@ -2140,6 +2116,11 @@ int bch_btree_insert(struct btree_op *op
 void bch_btree_set_root(struct btree *b)
 {
 	unsigned i;
+	struct closure cl;
+
+	closure_init_stack(&cl);
+
+	trace_bcache_btree_set_root(b);
 
 	BUG_ON(!b->written);
 
@@ -2153,8 +2134,8 @@ void bch_btree_set_root(struct btree *b)
 	b->c->root = b;
 	__bkey_put(b->c, &b->key);
 
-	bch_journal_meta(b->c, NULL);
-	pr_debug("%s for %pf", pbtree(b), __builtin_return_address(0));
+	bch_journal_meta(b->c, &cl);
+	closure_sync(&cl);
 }
 
 /* Cache lookup */
@@ -2215,9 +2196,6 @@ static int submit_partial_cache_hit(stru
 					 KEY_OFFSET(k) - bio->bi_sector);
 
 		n = bch_bio_split(bio, sectors, GFP_NOIO, s->d->bio_split);
-		if (!n)
-			return -EAGAIN;
-
 		if (n == bio)
 			op->lookup_done = true;
 
@@ -2240,7 +2218,6 @@ static int submit_partial_cache_hit(stru
 		n->bi_end_io	= bch_cache_read_endio;
 		n->bi_private	= &s->cl;
 
-		trace_bcache_cache_hit(n);
 		__bch_submit_bbio(n, b->c);
 	}
 
@@ -2257,9 +2234,6 @@ int bch_btree_search_recurse(struct btre
 	struct btree_iter iter;
 	bch_btree_iter_init(b, &iter, &KEY(op->inode, bio->bi_sector, 0));
 
-	pr_debug("at %s searching for %u:%llu", pbtree(b), op->inode,
-		 (uint64_t) bio->bi_sector);
-
 	do {
 		k = bch_btree_iter_next_filter(&iter, b, bch_ptr_bad);
 		if (!k) {
@@ -2303,7 +2277,8 @@ static inline int keybuf_nonoverlapping_
 }
 
 static int bch_btree_refill_keybuf(struct btree *b, struct btree_op *op,
-				   struct keybuf *buf, struct bkey *end)
+				   struct keybuf *buf, struct bkey *end,
+				   keybuf_pred_fn *pred)
 {
 	struct btree_iter iter;
 	bch_btree_iter_init(b, &iter, &buf->last_scanned);
@@ -2322,11 +2297,9 @@ static int bch_btree_refill_keybuf(struc
 			if (bkey_cmp(&buf->last_scanned, end) >= 0)
 				break;
 
-			if (buf->key_predicate(buf, k)) {
+			if (pred(buf, k)) {
 				struct keybuf_key *w;
 
-				pr_debug("%s", pkey(k));
-
 				spin_lock(&buf->lock);
 
 				w = array_alloc(&buf->freelist);
@@ -2343,7 +2316,7 @@ static int bch_btree_refill_keybuf(struc
 			if (!k)
 				break;
 
-			btree(refill_keybuf, k, b, op, buf, end);
+			btree(refill_keybuf, k, b, op, buf, end, pred);
 			/*
 			 * Might get an error here, but can't really do anything
 			 * and it'll get logged elsewhere. Just read what we
@@ -2361,7 +2334,7 @@ static int bch_btree_refill_keybuf(struc
 }
 
 void bch_refill_keybuf(struct cache_set *c, struct keybuf *buf,
-			  struct bkey *end)
+		       struct bkey *end, keybuf_pred_fn *pred)
 {
 	struct bkey start = buf->last_scanned;
 	struct btree_op op;
@@ -2369,7 +2342,7 @@ void bch_refill_keybuf(struct cache_set
 
 	cond_resched();
 
-	btree_root(refill_keybuf, c, &op, buf, end);
+	btree_root(refill_keybuf, c, &op, buf, end, pred);
 	closure_sync(&op.cl);
 
 	pr_debug("found %s keys from %llu:%llu to %llu:%llu",
@@ -2455,7 +2428,8 @@ struct keybuf_key *bch_keybuf_next(struc
 
 struct keybuf_key *bch_keybuf_next_rescan(struct cache_set *c,
 					     struct keybuf *buf,
-					     struct bkey *end)
+					     struct bkey *end,
+					     keybuf_pred_fn *pred)
 {
 	struct keybuf_key *ret;
 
@@ -2469,15 +2443,14 @@ struct keybuf_key *bch_keybuf_next_resca
 			break;
 		}
 
-		bch_refill_keybuf(c, buf, end);
+		bch_refill_keybuf(c, buf, end, pred);
 	}
 
 	return ret;
 }
 
-void bch_keybuf_init(struct keybuf *buf, keybuf_pred_fn *fn)
+void bch_keybuf_init(struct keybuf *buf)
 {
-	buf->key_predicate	= fn;
 	buf->last_scanned	= MAX_KEY;
 	buf->keys		= RB_ROOT;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/btree.h linux-libre-3.11-rc7-gnu/drivers/md/bcache/btree.h
--- linux-libre-3.10-gnu/drivers/md/bcache/btree.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/btree.h	2013-08-25 20:43:22.000000000 -0400
@@ -102,7 +102,6 @@
 #include "debug.h"
 
 struct btree_write {
-	struct closure		*owner;
 	atomic_t		*journal;
 
 	/* If btree_split() frees a btree node, it writes a new pointer to that
@@ -142,16 +141,12 @@ struct btree {
 	 */
 	struct bset_tree	sets[MAX_BSETS];
 
-	/* Used to refcount bio splits, also protects b->bio */
+	/* For outstanding btree writes, used as a lock - protects write_idx */
 	struct closure_with_waitlist	io;
 
-	/* Gets transferred to w->prio_blocked - see the comment there */
-	int			prio_blocked;
-
 	struct list_head	list;
 	struct delayed_work	work;
 
-	uint64_t		io_start_time;
 	struct btree_write	writes[2];
 	struct bio		*bio;
 };
@@ -164,13 +159,11 @@ static inline void set_btree_node_ ## fl
 {	set_bit(BTREE_NODE_ ## flag, &b->flags); }			\
 
 enum btree_flags {
-	BTREE_NODE_read_done,
 	BTREE_NODE_io_error,
 	BTREE_NODE_dirty,
 	BTREE_NODE_write_idx,
 };
 
-BTREE_FLAG(read_done);
 BTREE_FLAG(io_error);
 BTREE_FLAG(dirty);
 BTREE_FLAG(write_idx);
@@ -278,6 +271,13 @@ struct btree_op {
 	BKEY_PADDED(replace);
 };
 
+enum {
+	BTREE_INSERT_STATUS_INSERT,
+	BTREE_INSERT_STATUS_BACK_MERGE,
+	BTREE_INSERT_STATUS_OVERWROTE,
+	BTREE_INSERT_STATUS_FRONT_MERGE,
+};
+
 void bch_btree_op_init_stack(struct btree_op *);
 
 static inline void rw_lock(bool w, struct btree *b, int level)
@@ -293,9 +293,7 @@ static inline void rw_unlock(bool w, str
 #ifdef CONFIG_BCACHE_EDEBUG
 	unsigned i;
 
-	if (w &&
-	    b->key.ptr[0] &&
-	    btree_node_read_done(b))
+	if (w && b->key.ptr[0])
 		for (i = 0; i <= b->nsets; i++)
 			bch_check_key_order(b, b->sets[i].data);
 #endif
@@ -370,9 +368,8 @@ static inline bool should_split(struct b
 		 > btree_blocks(b));
 }
 
-void bch_btree_read_done(struct closure *);
-void bch_btree_read(struct btree *);
-void bch_btree_write(struct btree *b, bool now, struct btree_op *op);
+void bch_btree_node_read(struct btree *);
+void bch_btree_node_write(struct btree *, struct closure *);
 
 void bch_cannibalize_unlock(struct cache_set *, struct closure *);
 void bch_btree_set_root(struct btree *);
@@ -380,7 +377,6 @@ struct btree *bch_btree_node_alloc(struc
 struct btree *bch_btree_node_get(struct cache_set *, struct bkey *,
 				int, struct btree_op *);
 
-bool bch_btree_insert_keys(struct btree *, struct btree_op *);
 bool bch_btree_insert_check_key(struct btree *, struct btree_op *,
 				   struct bio *);
 int bch_btree_insert(struct btree_op *, struct cache_set *);
@@ -393,13 +389,14 @@ void bch_moving_gc(struct closure *);
 int bch_btree_check(struct cache_set *, struct btree_op *);
 uint8_t __bch_btree_mark_key(struct cache_set *, int, struct bkey *);
 
-void bch_keybuf_init(struct keybuf *, keybuf_pred_fn *);
-void bch_refill_keybuf(struct cache_set *, struct keybuf *, struct bkey *);
+void bch_keybuf_init(struct keybuf *);
+void bch_refill_keybuf(struct cache_set *, struct keybuf *, struct bkey *,
+		       keybuf_pred_fn *);
 bool bch_keybuf_check_overlapping(struct keybuf *, struct bkey *,
 				  struct bkey *);
 void bch_keybuf_del(struct keybuf *, struct keybuf_key *);
 struct keybuf_key *bch_keybuf_next(struct keybuf *);
-struct keybuf_key *bch_keybuf_next_rescan(struct cache_set *,
-					  struct keybuf *, struct bkey *);
+struct keybuf_key *bch_keybuf_next_rescan(struct cache_set *, struct keybuf *,
+					  struct bkey *, keybuf_pred_fn *);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/closure.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/closure.c
--- linux-libre-3.10-gnu/drivers/md/bcache/closure.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/closure.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,16 +66,18 @@ static inline void closure_put_after_sub
 		} else {
 			struct closure *parent = cl->parent;
 			struct closure_waitlist *wait = closure_waitlist(cl);
+			closure_fn *destructor = cl->fn;
 
 			closure_debug_destroy(cl);
 
+			smp_mb();
 			atomic_set(&cl->remaining, -1);
 
 			if (wait)
 				closure_wake_up(wait);
 
-			if (cl->fn)
-				cl->fn(cl);
+			if (destructor)
+				destructor(cl);
 
 			if (parent)
 				closure_put(parent);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/debug.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/debug.c
--- linux-libre-3.10-gnu/drivers/md/bcache/debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,11 +47,10 @@ const char *bch_ptr_status(struct cache_
 	return "";
 }
 
-struct keyprint_hack bch_pkey(const struct bkey *k)
+int bch_bkey_to_text(char *buf, size_t size, const struct bkey *k)
 {
 	unsigned i = 0;
-	struct keyprint_hack r;
-	char *out = r.s, *end = r.s + KEYHACK_SIZE;
+	char *out = buf, *end = buf + size;
 
 #define p(...)	(out += scnprintf(out, end - out, __VA_ARGS__))
 
@@ -75,16 +74,14 @@ struct keyprint_hack bch_pkey(const stru
 	if (KEY_CSUM(k))
 		p(" cs%llu %llx", KEY_CSUM(k), k->ptr[1]);
 #undef p
-	return r;
+	return out - buf;
 }
 
-struct keyprint_hack bch_pbtree(const struct btree *b)
+int bch_btree_to_text(char *buf, size_t size, const struct btree *b)
 {
-	struct keyprint_hack r;
-
-	snprintf(r.s, 40, "%zu level %i/%i", PTR_BUCKET_NR(b->c, &b->key, 0),
-		 b->level, b->c->root ? b->c->root->level : -1);
-	return r;
+	return scnprintf(buf, size, "%zu level %i/%i",
+			 PTR_BUCKET_NR(b->c, &b->key, 0),
+			 b->level, b->c->root ? b->c->root->level : -1);
 }
 
 #if defined(CONFIG_BCACHE_DEBUG) || defined(CONFIG_BCACHE_EDEBUG)
@@ -100,10 +97,12 @@ static void dump_bset(struct btree *b, s
 {
 	struct bkey *k;
 	unsigned j;
+	char buf[80];
 
 	for (k = i->start; k < end(i); k = bkey_next(k)) {
+		bch_bkey_to_text(buf, sizeof(buf), k);
 		printk(KERN_ERR "block %zu key %zi/%u: %s", index(i, b),
-		       (uint64_t *) k - i->d, i->keys, pkey(k));
+		       (uint64_t *) k - i->d, i->keys, buf);
 
 		for (j = 0; j < KEY_PTRS(k); j++) {
 			size_t n = PTR_BUCKET_NR(b->c, k, j);
@@ -144,7 +143,7 @@ void bch_btree_verify(struct btree *b, s
 	v->written = 0;
 	v->level = b->level;
 
-	bch_btree_read(v);
+	bch_btree_node_read(v);
 	closure_wait_event(&v->io.wait, &cl,
 			   atomic_read(&b->io.cl.remaining) == -1);
 
@@ -200,7 +199,7 @@ void bch_data_verify(struct search *s)
 	if (!check)
 		return;
 
-	if (bch_bio_alloc_pages(check, GFP_NOIO))
+	if (bio_alloc_pages(check, GFP_NOIO))
 		goto out_put;
 
 	check->bi_rw		= READ_SYNC;
@@ -252,6 +251,7 @@ static void vdump_bucket_and_panic(struc
 				   va_list args)
 {
 	unsigned i;
+	char buf[80];
 
 	console_lock();
 
@@ -262,7 +262,8 @@ static void vdump_bucket_and_panic(struc
 
 	console_unlock();
 
-	panic("at %s\n", pbtree(b));
+	bch_btree_to_text(buf, sizeof(buf), b);
+	panic("at %s\n", buf);
 }
 
 void bch_check_key_order_msg(struct btree *b, struct bset *i,
@@ -337,6 +338,7 @@ static ssize_t bch_dump_read(struct file
 {
 	struct dump_iterator *i = file->private_data;
 	ssize_t ret = 0;
+	char kbuf[80];
 
 	while (size) {
 		struct keybuf_key *w;
@@ -355,11 +357,12 @@ static ssize_t bch_dump_read(struct file
 		if (i->bytes)
 			break;
 
-		w = bch_keybuf_next_rescan(i->c, &i->keys, &MAX_KEY);
+		w = bch_keybuf_next_rescan(i->c, &i->keys, &MAX_KEY, dump_pred);
 		if (!w)
 			break;
 
-		i->bytes = snprintf(i->buf, PAGE_SIZE, "%s\n", pkey(&w->key));
+		bch_bkey_to_text(kbuf, sizeof(kbuf), &w->key);
+		i->bytes = snprintf(i->buf, PAGE_SIZE, "%s\n", kbuf);
 		bch_keybuf_del(&i->keys, w);
 	}
 
@@ -377,7 +380,7 @@ static int bch_dump_open(struct inode *i
 
 	file->private_data = i;
 	i->c = c;
-	bch_keybuf_init(&i->keys, dump_pred);
+	bch_keybuf_init(&i->keys);
 	i->keys.last_scanned = KEY(0, 0, 0);
 
 	return 0;
@@ -409,142 +412,6 @@ void bch_debug_init_cache_set(struct cac
 
 #endif
 
-/* Fuzz tester has rotted: */
-#if 0
-
-static ssize_t btree_fuzz(struct kobject *k, struct kobj_attribute *a,
-			  const char *buffer, size_t size)
-{
-	void dump(struct btree *b)
-	{
-		struct bset *i;
-
-		for (i = b->sets[0].data;
-		     index(i, b) < btree_blocks(b) &&
-		     i->seq == b->sets[0].data->seq;
-		     i = ((void *) i) + set_blocks(i, b->c) * block_bytes(b->c))
-			dump_bset(b, i);
-	}
-
-	struct cache_sb *sb;
-	struct cache_set *c;
-	struct btree *all[3], *b, *fill, *orig;
-	int j;
-
-	struct btree_op op;
-	bch_btree_op_init_stack(&op);
-
-	sb = kzalloc(sizeof(struct cache_sb), GFP_KERNEL);
-	if (!sb)
-		return -ENOMEM;
-
-	sb->bucket_size = 128;
-	sb->block_size = 4;
-
-	c = bch_cache_set_alloc(sb);
-	if (!c)
-		return -ENOMEM;
-
-	for (j = 0; j < 3; j++) {
-		BUG_ON(list_empty(&c->btree_cache));
-		all[j] = list_first_entry(&c->btree_cache, struct btree, list);
-		list_del_init(&all[j]->list);
-
-		all[j]->key = KEY(0, 0, c->sb.bucket_size);
-		bkey_copy_key(&all[j]->key, &MAX_KEY);
-	}
-
-	b = all[0];
-	fill = all[1];
-	orig = all[2];
-
-	while (1) {
-		for (j = 0; j < 3; j++)
-			all[j]->written = all[j]->nsets = 0;
-
-		bch_bset_init_next(b);
-
-		while (1) {
-			struct bset *i = write_block(b);
-			struct bkey *k = op.keys.top;
-			unsigned rand;
-
-			bkey_init(k);
-			rand = get_random_int();
-
-			op.type = rand & 1
-				? BTREE_INSERT
-				: BTREE_REPLACE;
-			rand >>= 1;
-
-			SET_KEY_SIZE(k, bucket_remainder(c, rand));
-			rand >>= c->bucket_bits;
-			rand &= 1024 * 512 - 1;
-			rand += c->sb.bucket_size;
-			SET_KEY_OFFSET(k, rand);
-#if 0
-			SET_KEY_PTRS(k, 1);
-#endif
-			bch_keylist_push(&op.keys);
-			bch_btree_insert_keys(b, &op);
-
-			if (should_split(b) ||
-			    set_blocks(i, b->c) !=
-			    __set_blocks(i, i->keys + 15, b->c)) {
-				i->csum = csum_set(i);
-
-				memcpy(write_block(fill),
-				       i, set_bytes(i));
-
-				b->written += set_blocks(i, b->c);
-				fill->written = b->written;
-				if (b->written == btree_blocks(b))
-					break;
-
-				bch_btree_sort_lazy(b);
-				bch_bset_init_next(b);
-			}
-		}
-
-		memcpy(orig->sets[0].data,
-		       fill->sets[0].data,
-		       btree_bytes(c));
-
-		bch_btree_sort(b);
-		fill->written = 0;
-		bch_btree_read_done(&fill->io.cl);
-
-		if (b->sets[0].data->keys != fill->sets[0].data->keys ||
-		    memcmp(b->sets[0].data->start,
-			   fill->sets[0].data->start,
-			   b->sets[0].data->keys * sizeof(uint64_t))) {
-			struct bset *i = b->sets[0].data;
-			struct bkey *k, *l;
-
-			for (k = i->start,
-			     l = fill->sets[0].data->start;
-			     k < end(i);
-			     k = bkey_next(k), l = bkey_next(l))
-				if (bkey_cmp(k, l) ||
-				    KEY_SIZE(k) != KEY_SIZE(l))
-					pr_err("key %zi differs: %s != %s",
-					       (uint64_t *) k - i->d,
-					       pkey(k), pkey(l));
-
-			for (j = 0; j < 3; j++) {
-				pr_err("**** Set %i ****", j);
-				dump(all[j]);
-			}
-			panic("\n");
-		}
-
-		pr_info("fuzz complete: %i keys", b->sets[0].data->keys);
-	}
-}
-
-kobj_attribute_write(fuzz, btree_fuzz);
-#endif
-
 void bch_debug_exit(void)
 {
 	if (!IS_ERR_OR_NULL(debug))
@@ -554,11 +421,6 @@ void bch_debug_exit(void)
 int __init bch_debug_init(struct kobject *kobj)
 {
 	int ret = 0;
-#if 0
-	ret = sysfs_create_file(kobj, &ksysfs_fuzz.attr);
-	if (ret)
-		return ret;
-#endif
 
 	debug = debugfs_create_dir("bcache", NULL);
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/debug.h linux-libre-3.11-rc7-gnu/drivers/md/bcache/debug.h
--- linux-libre-3.10-gnu/drivers/md/bcache/debug.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/debug.h	2013-08-25 20:43:22.000000000 -0400
@@ -3,15 +3,8 @@
 
 /* Btree/bkey debug printing */
 
-#define KEYHACK_SIZE 80
-struct keyprint_hack {
-	char s[KEYHACK_SIZE];
-};
-
-struct keyprint_hack bch_pkey(const struct bkey *k);
-struct keyprint_hack bch_pbtree(const struct btree *b);
-#define pkey(k)		(&bch_pkey(k).s[0])
-#define pbtree(b)	(&bch_pbtree(b).s[0])
+int bch_bkey_to_text(char *buf, size_t size, const struct bkey *k);
+int bch_btree_to_text(char *buf, size_t size, const struct btree *b);
 
 #ifdef CONFIG_BCACHE_EDEBUG
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/io.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/io.c
--- linux-libre-3.10-gnu/drivers/md/bcache/io.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/io.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,8 @@
 #include "bset.h"
 #include "debug.h"
 
+#include <linux/blkdev.h>
+
 static void bch_bi_idx_hack_endio(struct bio *bio, int error)
 {
 	struct bio *p = bio->bi_private;
@@ -66,13 +68,6 @@ static void bch_generic_make_request_hac
  * The newly allocated bio will point to @bio's bi_io_vec, if the split was on a
  * bvec boundry; it is the caller's responsibility to ensure that @bio is not
  * freed before the split.
- *
- * If bch_bio_split() is running under generic_make_request(), it's not safe to
- * allocate more than one bio from the same bio set. Therefore, if it is running
- * under generic_make_request() it masks out __GFP_WAIT when doing the
- * allocation. The caller must check for failure if there's any possibility of
- * it being called from under generic_make_request(); it is then the caller's
- * responsibility to retry from a safe context (by e.g. punting to workqueue).
  */
 struct bio *bch_bio_split(struct bio *bio, int sectors,
 			  gfp_t gfp, struct bio_set *bs)
@@ -83,20 +78,13 @@ struct bio *bch_bio_split(struct bio *bi
 
 	BUG_ON(sectors <= 0);
 
-	/*
-	 * If we're being called from underneath generic_make_request() and we
-	 * already allocated any bios from this bio set, we risk deadlock if we
-	 * use the mempool. So instead, we possibly fail and let the caller punt
-	 * to workqueue or somesuch and retry in a safe context.
-	 */
-	if (current->bio_list)
-		gfp &= ~__GFP_WAIT;
-
 	if (sectors >= bio_sectors(bio))
 		return bio;
 
 	if (bio->bi_rw & REQ_DISCARD) {
 		ret = bio_alloc_bioset(gfp, 1, bs);
+		if (!ret)
+			return NULL;
 		idx = 0;
 		goto out;
 	}
@@ -160,17 +148,18 @@ static unsigned bch_bio_max_sectors(stru
 	struct request_queue *q = bdev_get_queue(bio->bi_bdev);
 	unsigned max_segments = min_t(unsigned, BIO_MAX_PAGES,
 				      queue_max_segments(q));
-	struct bio_vec *bv, *end = bio_iovec(bio) +
-		min_t(int, bio_segments(bio), max_segments);
 
 	if (bio->bi_rw & REQ_DISCARD)
 		return min(ret, q->limits.max_discard_sectors);
 
 	if (bio_segments(bio) > max_segments ||
 	    q->merge_bvec_fn) {
+		struct bio_vec *bv;
+		int i, seg = 0;
+
 		ret = 0;
 
-		for (bv = bio_iovec(bio); bv < end; bv++) {
+		bio_for_each_segment(bv, bio, i) {
 			struct bvec_merge_data bvm = {
 				.bi_bdev	= bio->bi_bdev,
 				.bi_sector	= bio->bi_sector,
@@ -178,10 +167,14 @@ static unsigned bch_bio_max_sectors(stru
 				.bi_rw		= bio->bi_rw,
 			};
 
+			if (seg == max_segments)
+				break;
+
 			if (q->merge_bvec_fn &&
 			    q->merge_bvec_fn(q, &bvm, bv) < (int) bv->bv_len)
 				break;
 
+			seg++;
 			ret += bv->bv_len >> 9;
 		}
 	}
@@ -218,30 +211,10 @@ static void bch_bio_submit_split_endio(s
 	closure_put(cl);
 }
 
-static void __bch_bio_submit_split(struct closure *cl)
-{
-	struct bio_split_hook *s = container_of(cl, struct bio_split_hook, cl);
-	struct bio *bio = s->bio, *n;
-
-	do {
-		n = bch_bio_split(bio, bch_bio_max_sectors(bio),
-				  GFP_NOIO, s->p->bio_split);
-		if (!n)
-			continue_at(cl, __bch_bio_submit_split, system_wq);
-
-		n->bi_end_io	= bch_bio_submit_split_endio;
-		n->bi_private	= cl;
-
-		closure_get(cl);
-		bch_generic_make_request_hack(n);
-	} while (n != bio);
-
-	continue_at(cl, bch_bio_submit_split_done, NULL);
-}
-
 void bch_generic_make_request(struct bio *bio, struct bio_split_pool *p)
 {
 	struct bio_split_hook *s;
+	struct bio *n;
 
 	if (!bio_has_data(bio) && !(bio->bi_rw & REQ_DISCARD))
 		goto submit;
@@ -250,6 +223,7 @@ void bch_generic_make_request(struct bio
 		goto submit;
 
 	s = mempool_alloc(p->bio_split_hook, GFP_NOIO);
+	closure_init(&s->cl, NULL);
 
 	s->bio		= bio;
 	s->p		= p;
@@ -257,8 +231,18 @@ void bch_generic_make_request(struct bio
 	s->bi_private	= bio->bi_private;
 	bio_get(bio);
 
-	closure_call(&s->cl, __bch_bio_submit_split, NULL, NULL);
-	return;
+	do {
+		n = bch_bio_split(bio, bch_bio_max_sectors(bio),
+				  GFP_NOIO, s->p->bio_split);
+
+		n->bi_end_io	= bch_bio_submit_split_endio;
+		n->bi_private	= &s->cl;
+
+		closure_get(&s->cl);
+		bch_generic_make_request_hack(n);
+	} while (n != bio);
+
+	continue_at(&s->cl, bch_bio_submit_split_done, NULL);
 submit:
 	bch_generic_make_request_hack(bio);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/journal.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/journal.c
--- linux-libre-3.10-gnu/drivers/md/bcache/journal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/journal.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,8 @@
 #include "debug.h"
 #include "request.h"
 
+#include <trace/events/bcache.h>
+
 /*
  * Journal replay/recovery:
  *
@@ -182,9 +184,14 @@ bsearch:
 		pr_debug("starting binary search, l %u r %u", l, r);
 
 		while (l + 1 < r) {
+			seq = list_entry(list->prev, struct journal_replay,
+					 list)->j.seq;
+
 			m = (l + r) >> 1;
+			read_bucket(m);
 
-			if (read_bucket(m))
+			if (seq != list_entry(list->prev, struct journal_replay,
+					      list)->j.seq)
 				l = m;
 			else
 				r = m;
@@ -300,7 +307,8 @@ int bch_journal_replay(struct cache_set
 		for (k = i->j.start;
 		     k < end(&i->j);
 		     k = bkey_next(k)) {
-			pr_debug("%s", pkey(k));
+			trace_bcache_journal_replay_key(k);
+
 			bkey_copy(op->keys.top, k);
 			bch_keylist_push(&op->keys);
 
@@ -384,7 +392,7 @@ out:
 		return;
 found:
 	if (btree_node_dirty(best))
-		bch_btree_write(best, true, NULL);
+		bch_btree_node_write(best, NULL);
 	rw_unlock(true, best);
 }
 
@@ -617,7 +625,7 @@ static void journal_write_unlocked(struc
 		bio_reset(bio);
 		bio->bi_sector	= PTR_OFFSET(k, i);
 		bio->bi_bdev	= ca->bdev;
-		bio->bi_rw	= REQ_WRITE|REQ_SYNC|REQ_META|REQ_FLUSH;
+		bio->bi_rw	= REQ_WRITE|REQ_SYNC|REQ_META|REQ_FLUSH|REQ_FUA;
 		bio->bi_size	= sectors << 9;
 
 		bio->bi_end_io	= journal_write_endio;
@@ -712,7 +720,8 @@ void bch_journal(struct closure *cl)
 	spin_lock(&c->journal.lock);
 
 	if (journal_full(&c->journal)) {
-		/* XXX: tracepoint */
+		trace_bcache_journal_full(c);
+
 		closure_wait(&c->journal.wait, cl);
 
 		journal_reclaim(c);
@@ -728,13 +737,15 @@ void bch_journal(struct closure *cl)
 
 	if (b * c->sb.block_size > PAGE_SECTORS << JSET_BITS ||
 	    b > c->journal.blocks_free) {
-		/* XXX: If we were inserting so many keys that they won't fit in
+		trace_bcache_journal_entry_full(c);
+
+		/*
+		 * XXX: If we were inserting so many keys that they won't fit in
 		 * an _empty_ journal write, we'll deadlock. For now, handle
 		 * this in bch_keylist_realloc() - but something to think about.
 		 */
 		BUG_ON(!w->data->keys);
 
-		/* XXX: tracepoint */
 		BUG_ON(!closure_wait(&w->wait, cl));
 
 		closure_flush(&c->journal.io);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/movinggc.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/movinggc.c
--- linux-libre-3.10-gnu/drivers/md/bcache/movinggc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/movinggc.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,8 @@
 #include "debug.h"
 #include "request.h"
 
+#include <trace/events/bcache.h>
+
 struct moving_io {
 	struct keybuf_key	*w;
 	struct search		s;
@@ -44,14 +46,14 @@ static void write_moving_finish(struct c
 {
 	struct moving_io *io = container_of(cl, struct moving_io, s.cl);
 	struct bio *bio = &io->bio.bio;
-	struct bio_vec *bv = bio_iovec_idx(bio, bio->bi_vcnt);
+	struct bio_vec *bv;
+	int i;
 
-	while (bv-- != bio->bi_io_vec)
+	bio_for_each_segment_all(bv, bio, i)
 		__free_page(bv->bv_page);
 
-	pr_debug("%s %s", io->s.op.insert_collision
-		 ? "collision moving" : "moved",
-		 pkey(&io->w->key));
+	if (io->s.op.insert_collision)
+		trace_bcache_gc_copy_collision(&io->w->key);
 
 	bch_keybuf_del(&io->s.op.c->moving_gc_keys, io->w);
 
@@ -94,8 +96,6 @@ static void write_moving(struct closure
 	struct moving_io *io = container_of(s, struct moving_io, s);
 
 	if (!s->error) {
-		trace_bcache_write_moving(&io->bio.bio);
-
 		moving_init(io);
 
 		io->bio.bio.bi_sector	= KEY_START(&io->w->key);
@@ -122,7 +122,6 @@ static void read_moving_submit(struct cl
 	struct moving_io *io = container_of(s, struct moving_io, s);
 	struct bio *bio = &io->bio.bio;
 
-	trace_bcache_read_moving(bio);
 	bch_submit_bbio(bio, s->op.c, &io->w->key, 0);
 
 	continue_at(cl, write_moving, bch_gc_wq);
@@ -138,7 +137,8 @@ static void read_moving(struct closure *
 	/* XXX: if we error, background writeback could stall indefinitely */
 
 	while (!test_bit(CACHE_SET_STOPPING, &c->flags)) {
-		w = bch_keybuf_next_rescan(c, &c->moving_gc_keys, &MAX_KEY);
+		w = bch_keybuf_next_rescan(c, &c->moving_gc_keys,
+					   &MAX_KEY, moving_pred);
 		if (!w)
 			break;
 
@@ -159,10 +159,10 @@ static void read_moving(struct closure *
 		bio->bi_rw	= READ;
 		bio->bi_end_io	= read_moving_endio;
 
-		if (bch_bio_alloc_pages(bio, GFP_KERNEL))
+		if (bio_alloc_pages(bio, GFP_KERNEL))
 			goto err;
 
-		pr_debug("%s", pkey(&w->key));
+		trace_bcache_gc_copy(&w->key);
 
 		closure_call(&io->s.cl, read_moving_submit, NULL, &c->gc.cl);
 
@@ -250,5 +250,5 @@ void bch_moving_gc(struct closure *cl)
 
 void bch_moving_init_cache_set(struct cache_set *c)
 {
-	bch_keybuf_init(&c->moving_gc_keys, moving_pred);
+	bch_keybuf_init(&c->moving_gc_keys);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/request.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/request.c
--- linux-libre-3.10-gnu/drivers/md/bcache/request.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/request.c	2013-08-25 20:43:22.000000000 -0400
@@ -10,6 +10,7 @@
 #include "btree.h"
 #include "debug.h"
 #include "request.h"
+#include "writeback.h"
 
 #include <linux/cgroup.h>
 #include <linux/module.h>
@@ -21,8 +22,6 @@
 
 #define CUTOFF_CACHE_ADD	95
 #define CUTOFF_CACHE_READA	90
-#define CUTOFF_WRITEBACK	50
-#define CUTOFF_WRITEBACK_SYNC	75
 
 struct kmem_cache *bch_search_cache;
 
@@ -489,6 +488,12 @@ static void bch_insert_data_loop(struct
 		bch_queue_gc(op->c);
 	}
 
+	/*
+	 * Journal writes are marked REQ_FLUSH; if the original write was a
+	 * flush, it'll wait on the journal write.
+	 */
+	bio->bi_rw &= ~(REQ_FLUSH|REQ_FUA);
+
 	do {
 		unsigned i;
 		struct bkey *k;
@@ -510,10 +515,6 @@ static void bch_insert_data_loop(struct
 			goto err;
 
 		n = bch_bio_split(bio, KEY_SIZE(k), GFP_NOIO, split);
-		if (!n) {
-			__bkey_put(op->c, k);
-			continue_at(cl, bch_insert_data_loop, bcache_wq);
-		}
 
 		n->bi_end_io	= bch_insert_data_endio;
 		n->bi_private	= cl;
@@ -530,10 +531,9 @@ static void bch_insert_data_loop(struct
 		if (KEY_CSUM(k))
 			bio_csum(n, k);
 
-		pr_debug("%s", pkey(k));
+		trace_bcache_cache_insert(k);
 		bch_keylist_push(&op->keys);
 
-		trace_bcache_cache_insert(n, n->bi_sector, n->bi_bdev);
 		n->bi_rw |= REQ_WRITE;
 		bch_submit_bbio(n, op->c, k, 0);
 	} while (n != bio);
@@ -716,7 +716,7 @@ static struct search *search_alloc(struc
 	s->task			= current;
 	s->orig_bio		= bio;
 	s->write		= (bio->bi_rw & REQ_WRITE) != 0;
-	s->op.flush_journal	= (bio->bi_rw & REQ_FLUSH) != 0;
+	s->op.flush_journal	= (bio->bi_rw & (REQ_FLUSH|REQ_FUA)) != 0;
 	s->op.skip		= (bio->bi_rw & REQ_DISCARD) != 0;
 	s->recoverable		= 1;
 	s->start_time		= jiffies;
@@ -784,11 +784,8 @@ static void request_read_error(struct cl
 	int i;
 
 	if (s->recoverable) {
-		/* The cache read failed, but we can retry from the backing
-		 * device.
-		 */
-		pr_debug("recovering at sector %llu",
-			 (uint64_t) s->orig_bio->bi_sector);
+		/* Retry from the backing device: */
+		trace_bcache_read_retry(s->orig_bio);
 
 		s->error = 0;
 		bv = s->bio.bio.bi_io_vec;
@@ -806,7 +803,6 @@ static void request_read_error(struct cl
 
 		/* XXX: invalidate cache */
 
-		trace_bcache_read_retry(&s->bio.bio);
 		closure_bio_submit(&s->bio.bio, &s->cl, s->d);
 	}
 
@@ -827,53 +823,13 @@ static void request_read_done(struct clo
 	 */
 
 	if (s->op.cache_bio) {
-		struct bio_vec *src, *dst;
-		unsigned src_offset, dst_offset, bytes;
-		void *dst_ptr;
-
 		bio_reset(s->op.cache_bio);
 		s->op.cache_bio->bi_sector	= s->cache_miss->bi_sector;
 		s->op.cache_bio->bi_bdev	= s->cache_miss->bi_bdev;
 		s->op.cache_bio->bi_size	= s->cache_bio_sectors << 9;
 		bch_bio_map(s->op.cache_bio, NULL);
 
-		src = bio_iovec(s->op.cache_bio);
-		dst = bio_iovec(s->cache_miss);
-		src_offset = src->bv_offset;
-		dst_offset = dst->bv_offset;
-		dst_ptr = kmap(dst->bv_page);
-
-		while (1) {
-			if (dst_offset == dst->bv_offset + dst->bv_len) {
-				kunmap(dst->bv_page);
-				dst++;
-				if (dst == bio_iovec_idx(s->cache_miss,
-						s->cache_miss->bi_vcnt))
-					break;
-
-				dst_offset = dst->bv_offset;
-				dst_ptr = kmap(dst->bv_page);
-			}
-
-			if (src_offset == src->bv_offset + src->bv_len) {
-				src++;
-				if (src == bio_iovec_idx(s->op.cache_bio,
-						 s->op.cache_bio->bi_vcnt))
-					BUG();
-
-				src_offset = src->bv_offset;
-			}
-
-			bytes = min(dst->bv_offset + dst->bv_len - dst_offset,
-				    src->bv_offset + src->bv_len - src_offset);
-
-			memcpy(dst_ptr + dst_offset,
-			       page_address(src->bv_page) + src_offset,
-			       bytes);
-
-			src_offset	+= bytes;
-			dst_offset	+= bytes;
-		}
+		bio_copy_data(s->cache_miss, s->op.cache_bio);
 
 		bio_put(s->cache_miss);
 		s->cache_miss = NULL;
@@ -899,6 +855,7 @@ static void request_read_done_bh(struct
 	struct cached_dev *dc = container_of(s->d, struct cached_dev, disk);
 
 	bch_mark_cache_accounting(s, !s->cache_miss, s->op.skip);
+	trace_bcache_read(s->orig_bio, !s->cache_miss, s->op.skip);
 
 	if (s->error)
 		continue_at_nobarrier(cl, request_read_error, bcache_wq);
@@ -917,9 +874,6 @@ static int cached_dev_cache_miss(struct
 	struct bio *miss;
 
 	miss = bch_bio_split(bio, sectors, GFP_NOIO, s->d->bio_split);
-	if (!miss)
-		return -EAGAIN;
-
 	if (miss == bio)
 		s->op.lookup_done = true;
 
@@ -938,8 +892,9 @@ static int cached_dev_cache_miss(struct
 		reada = min(dc->readahead >> 9,
 			    sectors - bio_sectors(miss));
 
-		if (bio_end(miss) + reada > bdev_sectors(miss->bi_bdev))
-			reada = bdev_sectors(miss->bi_bdev) - bio_end(miss);
+		if (bio_end_sector(miss) + reada > bdev_sectors(miss->bi_bdev))
+			reada = bdev_sectors(miss->bi_bdev) -
+				bio_end_sector(miss);
 	}
 
 	s->cache_bio_sectors = bio_sectors(miss) + reada;
@@ -963,13 +918,12 @@ static int cached_dev_cache_miss(struct
 		goto out_put;
 
 	bch_bio_map(s->op.cache_bio, NULL);
-	if (bch_bio_alloc_pages(s->op.cache_bio, __GFP_NOWARN|GFP_NOIO))
+	if (bio_alloc_pages(s->op.cache_bio, __GFP_NOWARN|GFP_NOIO))
 		goto out_put;
 
 	s->cache_miss = miss;
 	bio_get(s->op.cache_bio);
 
-	trace_bcache_cache_miss(s->orig_bio);
 	closure_bio_submit(s->op.cache_bio, &s->cl, s->d);
 
 	return ret;
@@ -1002,24 +956,13 @@ static void cached_dev_write_complete(st
 	cached_dev_bio_complete(cl);
 }
 
-static bool should_writeback(struct cached_dev *dc, struct bio *bio)
-{
-	unsigned threshold = (bio->bi_rw & REQ_SYNC)
-		? CUTOFF_WRITEBACK_SYNC
-		: CUTOFF_WRITEBACK;
-
-	return !atomic_read(&dc->disk.detaching) &&
-		cache_mode(dc, bio) == CACHE_MODE_WRITEBACK &&
-		dc->disk.c->gc_stats.in_use < threshold;
-}
-
 static void request_write(struct cached_dev *dc, struct search *s)
 {
 	struct closure *cl = &s->cl;
 	struct bio *bio = &s->bio.bio;
 	struct bkey start, end;
 	start = KEY(dc->disk.id, bio->bi_sector, 0);
-	end = KEY(dc->disk.id, bio_end(bio), 0);
+	end = KEY(dc->disk.id, bio_end_sector(bio), 0);
 
 	bch_keybuf_check_overlapping(&s->op.c->moving_gc_keys, &start, &end);
 
@@ -1034,22 +977,37 @@ static void request_write(struct cached_
 	if (bio->bi_rw & REQ_DISCARD)
 		goto skip;
 
+	if (should_writeback(dc, s->orig_bio,
+			     cache_mode(dc, bio),
+			     s->op.skip)) {
+		s->op.skip = false;
+		s->writeback = true;
+	}
+
 	if (s->op.skip)
 		goto skip;
 
-	if (should_writeback(dc, s->orig_bio))
-		s->writeback = true;
+	trace_bcache_write(s->orig_bio, s->writeback, s->op.skip);
 
 	if (!s->writeback) {
 		s->op.cache_bio = bio_clone_bioset(bio, GFP_NOIO,
 						   dc->disk.bio_split);
 
-		trace_bcache_writethrough(s->orig_bio);
 		closure_bio_submit(bio, cl, s->d);
 	} else {
-		s->op.cache_bio = bio;
-		trace_bcache_writeback(s->orig_bio);
-		bch_writeback_add(dc, bio_sectors(bio));
+		bch_writeback_add(dc);
+
+		if (s->op.flush_journal) {
+			/* Also need to send a flush to the backing device */
+			s->op.cache_bio = bio_clone_bioset(bio, GFP_NOIO,
+							   dc->disk.bio_split);
+
+			bio->bi_size = 0;
+			bio->bi_vcnt = 0;
+			closure_bio_submit(bio, cl, s->d);
+		} else {
+			s->op.cache_bio = bio;
+		}
 	}
 out:
 	closure_call(&s->op.cl, bch_insert_data, NULL, cl);
@@ -1058,7 +1016,6 @@ skip:
 	s->op.skip = true;
 	s->op.cache_bio = s->orig_bio;
 	bio_get(s->op.cache_bio);
-	trace_bcache_write_skip(s->orig_bio);
 
 	if ((bio->bi_rw & REQ_DISCARD) &&
 	    !blk_queue_discard(bdev_get_queue(dc->bdev)))
@@ -1088,9 +1045,10 @@ static void request_nodata(struct cached
 
 /* Cached devices - read & write stuff */
 
-int bch_get_congested(struct cache_set *c)
+unsigned bch_get_congested(struct cache_set *c)
 {
 	int i;
+	long rand;
 
 	if (!c->congested_read_threshold_us &&
 	    !c->congested_write_threshold_us)
@@ -1106,7 +1064,13 @@ int bch_get_congested(struct cache_set *
 
 	i += CONGESTED_MAX;
 
-	return i <= 0 ? 1 : fract_exp_two(i, 6);
+	if (i > 0)
+		i = fract_exp_two(i, 6);
+
+	rand = get_random_int();
+	i -= bitmap_weight(&rand, BITS_PER_LONG);
+
+	return i > 0 ? i : 1;
 }
 
 static void add_sequential(struct task_struct *t)
@@ -1126,10 +1090,8 @@ static void check_should_skip(struct cac
 {
 	struct cache_set *c = s->op.c;
 	struct bio *bio = &s->bio.bio;
-
-	long rand;
-	int cutoff = bch_get_congested(c);
 	unsigned mode = cache_mode(dc, bio);
+	unsigned sectors, congested = bch_get_congested(c);
 
 	if (atomic_read(&dc->disk.detaching) ||
 	    c->gc_stats.in_use > CUTOFF_CACHE_ADD ||
@@ -1147,17 +1109,14 @@ static void check_should_skip(struct cac
 		goto skip;
 	}
 
-	if (!cutoff) {
-		cutoff = dc->sequential_cutoff >> 9;
-
-		if (!cutoff)
-			goto rescale;
+	if (!congested && !dc->sequential_cutoff)
+		goto rescale;
 
-		if (mode == CACHE_MODE_WRITEBACK &&
-		    (bio->bi_rw & REQ_WRITE) &&
-		    (bio->bi_rw & REQ_SYNC))
-			goto rescale;
-	}
+	if (!congested &&
+	    mode == CACHE_MODE_WRITEBACK &&
+	    (bio->bi_rw & REQ_WRITE) &&
+	    (bio->bi_rw & REQ_SYNC))
+		goto rescale;
 
 	if (dc->sequential_merge) {
 		struct io *i;
@@ -1177,7 +1136,7 @@ found:
 		if (i->sequential + bio->bi_size > i->sequential)
 			i->sequential	+= bio->bi_size;
 
-		i->last			 = bio_end(bio);
+		i->last			 = bio_end_sector(bio);
 		i->jiffies		 = jiffies + msecs_to_jiffies(5000);
 		s->task->sequential_io	 = i->sequential;
 
@@ -1192,12 +1151,19 @@ found:
 		add_sequential(s->task);
 	}
 
-	rand = get_random_int();
-	cutoff -= bitmap_weight(&rand, BITS_PER_LONG);
+	sectors = max(s->task->sequential_io,
+		      s->task->sequential_io_avg) >> 9;
 
-	if (cutoff <= (int) (max(s->task->sequential_io,
-				 s->task->sequential_io_avg) >> 9))
+	if (dc->sequential_cutoff &&
+	    sectors >= dc->sequential_cutoff >> 9) {
+		trace_bcache_bypass_sequential(s->orig_bio);
+		goto skip;
+	}
+
+	if (congested && sectors >= congested) {
+		trace_bcache_bypass_congested(s->orig_bio);
 		goto skip;
+	}
 
 rescale:
 	bch_rescale_priorities(c, bio_sectors(bio));
@@ -1288,30 +1254,25 @@ void bch_cached_dev_request_init(struct
 static int flash_dev_cache_miss(struct btree *b, struct search *s,
 				struct bio *bio, unsigned sectors)
 {
+	struct bio_vec *bv;
+	int i;
+
 	/* Zero fill bio */
 
-	while (bio->bi_idx != bio->bi_vcnt) {
-		struct bio_vec *bv = bio_iovec(bio);
+	bio_for_each_segment(bv, bio, i) {
 		unsigned j = min(bv->bv_len >> 9, sectors);
 
 		void *p = kmap(bv->bv_page);
 		memset(p + bv->bv_offset, 0, j << 9);
 		kunmap(bv->bv_page);
 
-		bv->bv_len	-= j << 9;
-		bv->bv_offset	+= j << 9;
-
-		if (bv->bv_len)
-			return 0;
-
-		bio->bi_sector	+= j;
-		bio->bi_size	-= j << 9;
-
-		bio->bi_idx++;
-		sectors		-= j;
+		sectors	-= j;
 	}
 
-	s->op.lookup_done = true;
+	bio_advance(bio, min(sectors << 9, bio->bi_size));
+
+	if (!bio->bi_size)
+		s->op.lookup_done = true;
 
 	return 0;
 }
@@ -1338,8 +1299,8 @@ static void flash_dev_make_request(struc
 		closure_call(&s->op.cl, btree_read_async, NULL, cl);
 	} else if (bio_has_data(bio) || s->op.skip) {
 		bch_keybuf_check_overlapping(&s->op.c->moving_gc_keys,
-					     &KEY(d->id, bio->bi_sector, 0),
-					     &KEY(d->id, bio_end(bio), 0));
+					&KEY(d->id, bio->bi_sector, 0),
+					&KEY(d->id, bio_end_sector(bio), 0));
 
 		s->writeback	= true;
 		s->op.cache_bio	= bio;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/request.h linux-libre-3.11-rc7-gnu/drivers/md/bcache/request.h
--- linux-libre-3.10-gnu/drivers/md/bcache/request.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/request.h	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,7 @@ struct search {
 };
 
 void bch_cache_read_endio(struct bio *, int);
-int bch_get_congested(struct cache_set *);
+unsigned bch_get_congested(struct cache_set *);
 void bch_insert_data(struct closure *cl);
 void bch_btree_insert_async(struct closure *);
 void bch_cache_read_endio(struct bio *, int);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/super.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/super.c
--- linux-libre-3.10-gnu/drivers/md/bcache/super.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/super.c	2013-08-25 20:43:22.000000000 -0400
@@ -10,10 +10,13 @@
 #include "btree.h"
 #include "debug.h"
 #include "request.h"
+#include "writeback.h"
 
+#include <linux/blkdev.h>
 #include <linux/buffer_head.h>
 #include <linux/debugfs.h>
 #include <linux/genhd.h>
+#include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/random.h>
 #include <linux/reboot.h>
@@ -342,6 +345,7 @@ static void uuid_io(struct cache_set *c,
 	struct closure *cl = &c->uuid_write.cl;
 	struct uuid_entry *u;
 	unsigned i;
+	char buf[80];
 
 	BUG_ON(!parent);
 	closure_lock(&c->uuid_write, parent);
@@ -362,8 +366,8 @@ static void uuid_io(struct cache_set *c,
 			break;
 	}
 
-	pr_debug("%s UUIDs at %s", rw & REQ_WRITE ? "wrote" : "read",
-		 pkey(&c->uuid_bucket));
+	bch_bkey_to_text(buf, sizeof(buf), k);
+	pr_debug("%s UUIDs at %s", rw & REQ_WRITE ? "wrote" : "read", buf);
 
 	for (u = c->uuids; u < c->uuids + c->nr_uuids; u++)
 		if (!bch_is_zero(u->uuid, 16))
@@ -543,7 +547,6 @@ void bch_prio_write(struct cache *ca)
 
 	pr_debug("free %zu, free_inc %zu, unused %zu", fifo_used(&ca->free),
 		 fifo_used(&ca->free_inc), fifo_used(&ca->unused));
-	blktrace_msg(ca, "Starting priorities: " buckets_free(ca));
 
 	for (i = prio_buckets(ca) - 1; i >= 0; --i) {
 		long bucket;
@@ -704,7 +707,8 @@ static void bcache_device_detach(struct
 		atomic_set(&d->detaching, 0);
 	}
 
-	bcache_device_unlink(d);
+	if (!d->flush_done)
+		bcache_device_unlink(d);
 
 	d->c->devices[d->id] = NULL;
 	closure_put(&d->c->caching);
@@ -743,13 +747,35 @@ static void bcache_device_free(struct bc
 		mempool_destroy(d->unaligned_bvec);
 	if (d->bio_split)
 		bioset_free(d->bio_split);
+	if (is_vmalloc_addr(d->stripe_sectors_dirty))
+		vfree(d->stripe_sectors_dirty);
+	else
+		kfree(d->stripe_sectors_dirty);
 
 	closure_debug_destroy(&d->cl);
 }
 
-static int bcache_device_init(struct bcache_device *d, unsigned block_size)
+static int bcache_device_init(struct bcache_device *d, unsigned block_size,
+			      sector_t sectors)
 {
 	struct request_queue *q;
+	size_t n;
+
+	if (!d->stripe_size_bits)
+		d->stripe_size_bits = 31;
+
+	d->nr_stripes = round_up(sectors, 1 << d->stripe_size_bits) >>
+		d->stripe_size_bits;
+
+	if (!d->nr_stripes || d->nr_stripes > SIZE_MAX / sizeof(atomic_t))
+		return -ENOMEM;
+
+	n = d->nr_stripes * sizeof(atomic_t);
+	d->stripe_sectors_dirty = n < PAGE_SIZE << 6
+		? kzalloc(n, GFP_KERNEL)
+		: vzalloc(n);
+	if (!d->stripe_sectors_dirty)
+		return -ENOMEM;
 
 	if (!(d->bio_split = bioset_create(4, offsetof(struct bbio, bio))) ||
 	    !(d->unaligned_bvec = mempool_create_kmalloc_pool(1,
@@ -759,6 +785,7 @@ static int bcache_device_init(struct bca
 	    !(q = blk_alloc_queue(GFP_KERNEL)))
 		return -ENOMEM;
 
+	set_capacity(d->disk, sectors);
 	snprintf(d->disk->disk_name, DISK_NAME_LEN, "bcache%i", bcache_minor);
 
 	d->disk->major		= bcache_major;
@@ -781,6 +808,8 @@ static int bcache_device_init(struct bca
 	set_bit(QUEUE_FLAG_NONROT,	&d->disk->queue->queue_flags);
 	set_bit(QUEUE_FLAG_DISCARD,	&d->disk->queue->queue_flags);
 
+	blk_queue_flush(q, REQ_FLUSH|REQ_FUA);
+
 	return 0;
 }
 
@@ -800,6 +829,17 @@ static void calc_cached_dev_sectors(stru
 void bch_cached_dev_run(struct cached_dev *dc)
 {
 	struct bcache_device *d = &dc->disk;
+	char buf[SB_LABEL_SIZE + 1];
+	char *env[] = {
+		"DRIVER=bcache",
+		kasprintf(GFP_KERNEL, "CACHED_UUID=%pU", dc->sb.uuid),
+		NULL,
+		NULL,
+	};
+
+	memcpy(buf, dc->sb.label, SB_LABEL_SIZE);
+	buf[SB_LABEL_SIZE] = '\0';
+	env[2] = kasprintf(GFP_KERNEL, "CACHED_LABEL=%s", buf);
 
 	if (atomic_xchg(&dc->running, 1))
 		return;
@@ -816,10 +856,12 @@ void bch_cached_dev_run(struct cached_de
 
 	add_disk(d->disk);
 	bd_link_disk_holder(dc->bdev, dc->disk.disk);
-#if 0
-	char *env[] = { "SYMLINK=label" , NULL };
+	/* won't show up in the uevent file, use udevadm monitor -e instead
+	 * only class / kset properties are persistent */
 	kobject_uevent_env(&disk_to_dev(d->disk)->kobj, KOBJ_CHANGE, env);
-#endif
+	kfree(env[1]);
+	kfree(env[2]);
+
 	if (sysfs_create_link(&d->kobj, &disk_to_dev(d->disk)->kobj, "dev") ||
 	    sysfs_create_link(&disk_to_dev(d->disk)->kobj, &d->kobj, "bcache"))
 		pr_debug("error creating sysfs link");
@@ -960,6 +1002,7 @@ int bch_cached_dev_attach(struct cached_
 	atomic_set(&dc->count, 1);
 
 	if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) {
+		bch_sectors_dirty_init(dc);
 		atomic_set(&dc->has_dirty, 1);
 		atomic_inc(&dc->count);
 		bch_writeback_queue(dc);
@@ -1014,6 +1057,14 @@ static void cached_dev_flush(struct clos
 	struct cached_dev *dc = container_of(cl, struct cached_dev, disk.cl);
 	struct bcache_device *d = &dc->disk;
 
+	mutex_lock(&bch_register_lock);
+	d->flush_done = 1;
+
+	if (d->c)
+		bcache_device_unlink(d);
+
+	mutex_unlock(&bch_register_lock);
+
 	bch_cache_accounting_destroy(&dc->accounting);
 	kobject_del(&d->kobj);
 
@@ -1045,7 +1096,8 @@ static int cached_dev_init(struct cached
 		hlist_add_head(&io->hash, dc->io_hash + RECENT_IO);
 	}
 
-	ret = bcache_device_init(&dc->disk, block_size);
+	ret = bcache_device_init(&dc->disk, block_size,
+			 dc->bdev->bd_part->nr_sects - dc->sb.data_offset);
 	if (ret)
 		return ret;
 
@@ -1144,11 +1196,10 @@ static int flash_dev_run(struct cache_se
 
 	kobject_init(&d->kobj, &bch_flash_dev_ktype);
 
-	if (bcache_device_init(d, block_bytes(c)))
+	if (bcache_device_init(d, block_bytes(c), u->sectors))
 		goto err;
 
 	bcache_device_attach(d, c, u - c->uuids);
-	set_capacity(d->disk, u->sectors);
 	bch_flash_dev_request_init(d);
 	add_disk(d->disk);
 
@@ -1255,9 +1306,10 @@ static void cache_set_free(struct closur
 	free_pages((unsigned long) c->uuids, ilog2(bucket_pages(c)));
 	free_pages((unsigned long) c->sort, ilog2(bucket_pages(c)));
 
-	kfree(c->fill_iter);
 	if (c->bio_split)
 		bioset_free(c->bio_split);
+	if (c->fill_iter)
+		mempool_destroy(c->fill_iter);
 	if (c->bio_meta)
 		mempool_destroy(c->bio_meta);
 	if (c->search)
@@ -1278,11 +1330,9 @@ static void cache_set_free(struct closur
 static void cache_set_flush(struct closure *cl)
 {
 	struct cache_set *c = container_of(cl, struct cache_set, caching);
+	struct cache *ca;
 	struct btree *b;
-
-	/* Shut down allocator threads */
-	set_bit(CACHE_SET_STOPPING_2, &c->flags);
-	wake_up(&c->alloc_wait);
+	unsigned i;
 
 	bch_cache_accounting_destroy(&c->accounting);
 
@@ -1295,7 +1345,11 @@ static void cache_set_flush(struct closu
 	/* Should skip this if we're unregistering because of an error */
 	list_for_each_entry(b, &c->btree_cache, list)
 		if (btree_node_dirty(b))
-			bch_btree_write(b, true, NULL);
+			bch_btree_node_write(b, NULL);
+
+	for_each_cache(ca, c, i)
+		if (ca->alloc_thread)
+			kthread_stop(ca->alloc_thread);
 
 	closure_return(cl);
 }
@@ -1303,18 +1357,22 @@ static void cache_set_flush(struct closu
 static void __cache_set_unregister(struct closure *cl)
 {
 	struct cache_set *c = container_of(cl, struct cache_set, caching);
-	struct cached_dev *dc, *t;
+	struct cached_dev *dc;
 	size_t i;
 
 	mutex_lock(&bch_register_lock);
 
-	if (test_bit(CACHE_SET_UNREGISTERING, &c->flags))
-		list_for_each_entry_safe(dc, t, &c->cached_devs, list)
-			bch_cached_dev_detach(dc);
-
 	for (i = 0; i < c->nr_uuids; i++)
-		if (c->devices[i] && UUID_FLASH_ONLY(&c->uuids[i]))
-			bcache_device_stop(c->devices[i]);
+		if (c->devices[i]) {
+			if (!UUID_FLASH_ONLY(&c->uuids[i]) &&
+			    test_bit(CACHE_SET_UNREGISTERING, &c->flags)) {
+				dc = container_of(c->devices[i],
+						  struct cached_dev, disk);
+				bch_cached_dev_detach(dc);
+			} else {
+				bcache_device_stop(c->devices[i]);
+			}
+		}
 
 	mutex_unlock(&bch_register_lock);
 
@@ -1373,9 +1431,9 @@ struct cache_set *bch_cache_set_alloc(st
 		c->btree_pages = max_t(int, c->btree_pages / 4,
 				       BTREE_MAX_PAGES);
 
-	init_waitqueue_head(&c->alloc_wait);
+	c->sort_crit_factor = int_sqrt(c->btree_pages);
+
 	mutex_init(&c->bucket_lock);
-	mutex_init(&c->fill_lock);
 	mutex_init(&c->sort_lock);
 	spin_lock_init(&c->sort_time_lock);
 	closure_init_unlocked(&c->sb_write);
@@ -1401,8 +1459,8 @@ struct cache_set *bch_cache_set_alloc(st
 	    !(c->bio_meta = mempool_create_kmalloc_pool(2,
 				sizeof(struct bbio) + sizeof(struct bio_vec) *
 				bucket_pages(c))) ||
+	    !(c->fill_iter = mempool_create_kmalloc_pool(1, iter_size)) ||
 	    !(c->bio_split = bioset_create(4, offsetof(struct bbio, bio))) ||
-	    !(c->fill_iter = kmalloc(iter_size, GFP_KERNEL)) ||
 	    !(c->sort = alloc_bucket_pages(GFP_KERNEL, c)) ||
 	    !(c->uuids = alloc_bucket_pages(GFP_KERNEL, c)) ||
 	    bch_journal_alloc(c) ||
@@ -1410,8 +1468,6 @@ struct cache_set *bch_cache_set_alloc(st
 	    bch_open_buckets_alloc(c))
 		goto err;
 
-	c->fill_iter->size = sb->bucket_size / sb->block_size;
-
 	c->congested_read_threshold_us	= 2000;
 	c->congested_write_threshold_us	= 20000;
 	c->error_limit	= 8 << IO_ERROR_SHIFT;
@@ -1496,9 +1552,10 @@ static void run_cache_set(struct cache_s
 		 */
 		bch_journal_next(&c->journal);
 
+		err = "error starting allocator thread";
 		for_each_cache(ca, c, i)
-			closure_call(&ca->alloc, bch_allocator_thread,
-				     system_wq, &c->cl);
+			if (bch_cache_allocator_start(ca))
+				goto err;
 
 		/*
 		 * First place it's safe to allocate: btree_check() and
@@ -1531,17 +1588,16 @@ static void run_cache_set(struct cache_s
 
 		bch_btree_gc_finish(c);
 
+		err = "error starting allocator thread";
 		for_each_cache(ca, c, i)
-			closure_call(&ca->alloc, bch_allocator_thread,
-				     ca->alloc_workqueue, &c->cl);
+			if (bch_cache_allocator_start(ca))
+				goto err;
 
 		mutex_lock(&c->bucket_lock);
 		for_each_cache(ca, c, i)
 			bch_prio_write(ca);
 		mutex_unlock(&c->bucket_lock);
 
-		wake_up(&c->alloc_wait);
-
 		err = "cannot allocate new UUID bucket";
 		if (__uuid_write(c))
 			goto err_unlock_gc;
@@ -1552,7 +1608,7 @@ static void run_cache_set(struct cache_s
 			goto err_unlock_gc;
 
 		bkey_copy_key(&c->root->key, &MAX_KEY);
-		bch_btree_write(c->root, true, &op);
+		bch_btree_node_write(c->root, &op.cl);
 
 		bch_btree_set_root(c->root);
 		rw_unlock(true, c->root);
@@ -1673,9 +1729,6 @@ void bch_cache_release(struct kobject *k
 
 	bio_split_pool_free(&ca->bio_split_hook);
 
-	if (ca->alloc_workqueue)
-		destroy_workqueue(ca->alloc_workqueue);
-
 	free_pages((unsigned long) ca->disk_buckets, ilog2(bucket_pages(ca)));
 	kfree(ca->prio_buckets);
 	vfree(ca->buckets);
@@ -1723,7 +1776,6 @@ static int cache_alloc(struct cache_sb *
 	    !(ca->prio_buckets	= kzalloc(sizeof(uint64_t) * prio_buckets(ca) *
 					  2, GFP_KERNEL)) ||
 	    !(ca->disk_buckets	= alloc_bucket_pages(GFP_KERNEL, ca)) ||
-	    !(ca->alloc_workqueue = alloc_workqueue("bch_allocator", 0, 1)) ||
 	    bio_split_pool_init(&ca->bio_split_hook))
 		return -ENOMEM;
 
@@ -1786,6 +1838,36 @@ static ssize_t register_bcache(struct ko
 kobj_attribute_write(register,		register_bcache);
 kobj_attribute_write(register_quiet,	register_bcache);
 
+static bool bch_is_open_backing(struct block_device *bdev) {
+	struct cache_set *c, *tc;
+	struct cached_dev *dc, *t;
+
+	list_for_each_entry_safe(c, tc, &bch_cache_sets, list)
+		list_for_each_entry_safe(dc, t, &c->cached_devs, list)
+			if (dc->bdev == bdev)
+				return true;
+	list_for_each_entry_safe(dc, t, &uncached_devices, list)
+		if (dc->bdev == bdev)
+			return true;
+	return false;
+}
+
+static bool bch_is_open_cache(struct block_device *bdev) {
+	struct cache_set *c, *tc;
+	struct cache *ca;
+	unsigned i;
+
+	list_for_each_entry_safe(c, tc, &bch_cache_sets, list)
+		for_each_cache(ca, c, i)
+			if (ca->bdev == bdev)
+				return true;
+	return false;
+}
+
+static bool bch_is_open(struct block_device *bdev) {
+	return bch_is_open_cache(bdev) || bch_is_open_backing(bdev);
+}
+
 static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
 			       const char *buffer, size_t size)
 {
@@ -1810,8 +1892,13 @@ static ssize_t register_bcache(struct ko
 				  FMODE_READ|FMODE_WRITE|FMODE_EXCL,
 				  sb);
 	if (IS_ERR(bdev)) {
-		if (bdev == ERR_PTR(-EBUSY))
-			err = "device busy";
+		if (bdev == ERR_PTR(-EBUSY)) {
+			bdev = lookup_bdev(strim(path));
+			if (!IS_ERR(bdev) && bch_is_open(bdev))
+				err = "device already registered";
+			else
+				err = "device busy";
+		}
 		goto err;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/sysfs.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/sysfs.c
--- linux-libre-3.10-gnu/drivers/md/bcache/sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,7 +9,9 @@
 #include "sysfs.h"
 #include "btree.h"
 #include "request.h"
+#include "writeback.h"
 
+#include <linux/blkdev.h>
 #include <linux/sort.h>
 
 static const char * const cache_replacement_policies[] = {
@@ -79,6 +81,9 @@ rw_attribute(writeback_rate_p_term_inver
 rw_attribute(writeback_rate_d_smooth);
 read_attribute(writeback_rate_debug);
 
+read_attribute(stripe_size);
+read_attribute(partial_stripes_expensive);
+
 rw_attribute(synchronous);
 rw_attribute(journal_delay_ms);
 rw_attribute(discard);
@@ -127,7 +132,7 @@ SHOW(__bch_cached_dev)
 		char derivative[20];
 		char target[20];
 		bch_hprint(dirty,
-		       atomic_long_read(&dc->disk.sectors_dirty) << 9);
+			   bcache_dev_sectors_dirty(&dc->disk) << 9);
 		bch_hprint(derivative,	dc->writeback_rate_derivative << 9);
 		bch_hprint(target,	dc->writeback_rate_target << 9);
 
@@ -143,7 +148,10 @@ SHOW(__bch_cached_dev)
 	}
 
 	sysfs_hprint(dirty_data,
-		     atomic_long_read(&dc->disk.sectors_dirty) << 9);
+		     bcache_dev_sectors_dirty(&dc->disk) << 9);
+
+	sysfs_hprint(stripe_size,	(1 << dc->disk.stripe_size_bits) << 9);
+	var_printf(partial_stripes_expensive,	"%u");
 
 	var_printf(sequential_merge,	"%i");
 	var_hprint(sequential_cutoff);
@@ -170,6 +178,7 @@ STORE(__cached_dev)
 					     disk.kobj);
 	unsigned v = size;
 	struct cache_set *c;
+	struct kobj_uevent_env *env;
 
 #define d_strtoul(var)		sysfs_strtoul(var, dc->var)
 #define d_strtoi_h(var)		sysfs_hatoi(var, dc->var)
@@ -214,6 +223,7 @@ STORE(__cached_dev)
 	}
 
 	if (attr == &sysfs_label) {
+		/* note: endlines are preserved */
 		memcpy(dc->sb.label, buf, SB_LABEL_SIZE);
 		bch_write_bdev_super(dc, NULL);
 		if (dc->disk.c) {
@@ -221,6 +231,15 @@ STORE(__cached_dev)
 			       buf, SB_LABEL_SIZE);
 			bch_uuid_write(dc->disk.c);
 		}
+		env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
+		if (!env)
+			return -ENOMEM;
+		add_uevent_var(env, "DRIVER=bcache");
+		add_uevent_var(env, "CACHED_UUID=%pU", dc->sb.uuid),
+		add_uevent_var(env, "CACHED_LABEL=%s", buf);
+		kobject_uevent_env(
+			&disk_to_dev(dc->disk.disk)->kobj, KOBJ_CHANGE, env->envp);
+		kfree(env);
 	}
 
 	if (attr == &sysfs_attach) {
@@ -284,6 +303,8 @@ static struct attribute *bch_cached_dev_
 	&sysfs_writeback_rate_d_smooth,
 	&sysfs_writeback_rate_debug,
 	&sysfs_dirty_data,
+	&sysfs_stripe_size,
+	&sysfs_partial_stripes_expensive,
 	&sysfs_sequential_cutoff,
 	&sysfs_sequential_merge,
 	&sysfs_clear_stats,
@@ -665,12 +686,10 @@ SHOW(__bch_cache)
 		int cmp(const void *l, const void *r)
 		{	return *((uint16_t *) r) - *((uint16_t *) l); }
 
-		/* Number of quantiles we compute */
-		const unsigned nq = 31;
-
 		size_t n = ca->sb.nbuckets, i, unused, btree;
 		uint64_t sum = 0;
-		uint16_t q[nq], *p, *cached;
+		/* Compute 31 quantiles */
+		uint16_t q[31], *p, *cached;
 		ssize_t ret;
 
 		cached = p = vmalloc(ca->sb.nbuckets * sizeof(uint16_t));
@@ -703,26 +722,29 @@ SHOW(__bch_cache)
 		if (n)
 			do_div(sum, n);
 
-		for (i = 0; i < nq; i++)
-			q[i] = INITIAL_PRIO - cached[n * (i + 1) / (nq + 1)];
+		for (i = 0; i < ARRAY_SIZE(q); i++)
+			q[i] = INITIAL_PRIO - cached[n * (i + 1) /
+				(ARRAY_SIZE(q) + 1)];
 
 		vfree(p);
 
-		ret = snprintf(buf, PAGE_SIZE,
-			       "Unused:		%zu%%\n"
-			       "Metadata:	%zu%%\n"
-			       "Average:	%llu\n"
-			       "Sectors per Q:	%zu\n"
-			       "Quantiles:	[",
-			       unused * 100 / (size_t) ca->sb.nbuckets,
-			       btree * 100 / (size_t) ca->sb.nbuckets, sum,
-			       n * ca->sb.bucket_size / (nq + 1));
+		ret = scnprintf(buf, PAGE_SIZE,
+				"Unused:		%zu%%\n"
+				"Metadata:	%zu%%\n"
+				"Average:	%llu\n"
+				"Sectors per Q:	%zu\n"
+				"Quantiles:	[",
+				unused * 100 / (size_t) ca->sb.nbuckets,
+				btree * 100 / (size_t) ca->sb.nbuckets, sum,
+				n * ca->sb.bucket_size / (ARRAY_SIZE(q) + 1));
 
-		for (i = 0; i < nq && ret < (ssize_t) PAGE_SIZE; i++)
-			ret += snprintf(buf + ret, PAGE_SIZE - ret,
-					i < nq - 1 ? "%u " : "%u]\n", q[i]);
+		for (i = 0; i < ARRAY_SIZE(q); i++)
+			ret += scnprintf(buf + ret, PAGE_SIZE - ret,
+					 "%u ", q[i]);
+		ret--;
+
+		ret += scnprintf(buf + ret, PAGE_SIZE - ret, "]\n");
 
-		buf[PAGE_SIZE - 1] = '\0';
 		return ret;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/trace.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/trace.c
--- linux-libre-3.10-gnu/drivers/md/bcache/trace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/trace.c	2013-08-25 20:43:22.000000000 -0400
@@ -2,6 +2,7 @@
 #include "btree.h"
 #include "request.h"
 
+#include <linux/blktrace_api.h>
 #include <linux/module.h>
 
 #define CREATE_TRACE_POINTS
@@ -9,18 +10,44 @@
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_request_start);
 EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_request_end);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_passthrough);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_cache_hit);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_cache_miss);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_bypass_sequential);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_bypass_congested);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_read);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_write);
 EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_read_retry);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_writethrough);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_writeback);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_write_skip);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_cache_insert);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_journal_replay_key);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_journal_write);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_journal_full);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_journal_entry_full);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_cache_cannibalize);
+
 EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_read);
 EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_write);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_write_dirty);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_read_dirty);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_journal_write);
-EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_cache_insert);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_node_alloc);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_node_alloc_fail);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_node_free);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_gc_coalesce);
 EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_gc_start);
 EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_gc_end);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_gc_copy);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_gc_copy_collision);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_insert_key);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_node_split);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_node_compact);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_btree_set_root);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_alloc_invalidate);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_alloc_fail);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_writeback);
+EXPORT_TRACEPOINT_SYMBOL_GPL(bcache_writeback_collision);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/util.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/util.c
--- linux-libre-3.10-gnu/drivers/md/bcache/util.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/util.c	2013-08-25 20:43:22.000000000 -0400
@@ -228,23 +228,6 @@ start:		bv->bv_len	= min_t(size_t, PAGE_
 	}
 }
 
-int bch_bio_alloc_pages(struct bio *bio, gfp_t gfp)
-{
-	int i;
-	struct bio_vec *bv;
-
-	bio_for_each_segment(bv, bio, i) {
-		bv->bv_page = alloc_page(gfp);
-		if (!bv->bv_page) {
-			while (bv-- != bio->bi_io_vec + bio->bi_idx)
-				__free_page(bv->bv_page);
-			return -ENOMEM;
-		}
-	}
-
-	return 0;
-}
-
 /*
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group (Any
  * use permitted, subject to terms of PostgreSQL license; see.)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/util.h linux-libre-3.11-rc7-gnu/drivers/md/bcache/util.h
--- linux-libre-3.10-gnu/drivers/md/bcache/util.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/util.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,8 +15,6 @@
 
 struct closure;
 
-#include <trace/events/bcache.h>
-
 #ifdef CONFIG_BCACHE_EDEBUG
 
 #define atomic_dec_bug(v)	BUG_ON(atomic_dec_return(v) < 0)
@@ -566,12 +564,8 @@ static inline unsigned fract_exp_two(uns
 	return x;
 }
 
-#define bio_end(bio)	((bio)->bi_sector + bio_sectors(bio))
-
 void bch_bio_map(struct bio *bio, void *base);
 
-int bch_bio_alloc_pages(struct bio *bio, gfp_t gfp);
-
 static inline sector_t bdev_sectors(struct block_device *bdev)
 {
 	return bdev->bd_inode->i_size >> 9;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/writeback.c linux-libre-3.11-rc7-gnu/drivers/md/bcache/writeback.c
--- linux-libre-3.10-gnu/drivers/md/bcache/writeback.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/writeback.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,9 @@
 #include "bcache.h"
 #include "btree.h"
 #include "debug.h"
+#include "writeback.h"
+
+#include <trace/events/bcache.h>
 
 static struct workqueue_struct *dirty_wq;
 
@@ -36,7 +39,7 @@ static void __update_writeback_rate(stru
 
 	int change = 0;
 	int64_t error;
-	int64_t dirty = atomic_long_read(&dc->disk.sectors_dirty);
+	int64_t dirty = bcache_dev_sectors_dirty(&dc->disk);
 	int64_t derivative = dirty - dc->disk.sectors_dirty_last;
 
 	dc->disk.sectors_dirty_last = dirty;
@@ -105,6 +108,31 @@ static bool dirty_pred(struct keybuf *bu
 	return KEY_DIRTY(k);
 }
 
+static bool dirty_full_stripe_pred(struct keybuf *buf, struct bkey *k)
+{
+	uint64_t stripe;
+	unsigned nr_sectors = KEY_SIZE(k);
+	struct cached_dev *dc = container_of(buf, struct cached_dev,
+					     writeback_keys);
+	unsigned stripe_size = 1 << dc->disk.stripe_size_bits;
+
+	if (!KEY_DIRTY(k))
+		return false;
+
+	stripe = KEY_START(k) >> dc->disk.stripe_size_bits;
+	while (1) {
+		if (atomic_read(dc->disk.stripe_sectors_dirty + stripe) !=
+		    stripe_size)
+			return false;
+
+		if (nr_sectors <= stripe_size)
+			return true;
+
+		nr_sectors -= stripe_size;
+		stripe++;
+	}
+}
+
 static void dirty_init(struct keybuf_key *w)
 {
 	struct dirty_io *io = w->private;
@@ -149,7 +177,22 @@ static void refill_dirty(struct closure
 		searched_from_start = true;
 	}
 
-	bch_refill_keybuf(dc->disk.c, buf, &end);
+	if (dc->partial_stripes_expensive) {
+		uint64_t i;
+
+		for (i = 0; i < dc->disk.nr_stripes; i++)
+			if (atomic_read(dc->disk.stripe_sectors_dirty + i) ==
+			    1 << dc->disk.stripe_size_bits)
+				goto full_stripes;
+
+		goto normal_refill;
+full_stripes:
+		bch_refill_keybuf(dc->disk.c, buf, &end,
+				  dirty_full_stripe_pred);
+	} else {
+normal_refill:
+		bch_refill_keybuf(dc->disk.c, buf, &end, dirty_pred);
+	}
 
 	if (bkey_cmp(&buf->last_scanned, &end) >= 0 && searched_from_start) {
 		/* Searched the entire btree  - delay awhile */
@@ -181,10 +224,8 @@ void bch_writeback_queue(struct cached_d
 	}
 }
 
-void bch_writeback_add(struct cached_dev *dc, unsigned sectors)
+void bch_writeback_add(struct cached_dev *dc)
 {
-	atomic_long_add(sectors, &dc->disk.sectors_dirty);
-
 	if (!atomic_read(&dc->has_dirty) &&
 	    !atomic_xchg(&dc->has_dirty, 1)) {
 		atomic_inc(&dc->count);
@@ -203,6 +244,34 @@ void bch_writeback_add(struct cached_dev
 	}
 }
 
+void bcache_dev_sectors_dirty_add(struct cache_set *c, unsigned inode,
+				  uint64_t offset, int nr_sectors)
+{
+	struct bcache_device *d = c->devices[inode];
+	unsigned stripe_size, stripe_offset;
+	uint64_t stripe;
+
+	if (!d)
+		return;
+
+	stripe_size = 1 << d->stripe_size_bits;
+	stripe = offset >> d->stripe_size_bits;
+	stripe_offset = offset & (stripe_size - 1);
+
+	while (nr_sectors) {
+		int s = min_t(unsigned, abs(nr_sectors),
+			      stripe_size - stripe_offset);
+
+		if (nr_sectors < 0)
+			s = -s;
+
+		atomic_add(s, d->stripe_sectors_dirty + stripe);
+		nr_sectors -= s;
+		stripe_offset = 0;
+		stripe++;
+	}
+}
+
 /* Background writeback - IO loop */
 
 static void dirty_io_destructor(struct closure *cl)
@@ -216,9 +285,10 @@ static void write_dirty_finish(struct cl
 	struct dirty_io *io = container_of(cl, struct dirty_io, cl);
 	struct keybuf_key *w = io->bio.bi_private;
 	struct cached_dev *dc = io->dc;
-	struct bio_vec *bv = bio_iovec_idx(&io->bio, io->bio.bi_vcnt);
+	struct bio_vec *bv;
+	int i;
 
-	while (bv-- != io->bio.bi_io_vec)
+	bio_for_each_segment_all(bv, &io->bio, i)
 		__free_page(bv->bv_page);
 
 	/* This is kind of a dumb way of signalling errors. */
@@ -236,10 +306,12 @@ static void write_dirty_finish(struct cl
 		for (i = 0; i < KEY_PTRS(&w->key); i++)
 			atomic_inc(&PTR_BUCKET(dc->disk.c, &w->key, i)->pin);
 
-		pr_debug("clearing %s", pkey(&w->key));
 		bch_btree_insert(&op, dc->disk.c);
 		closure_sync(&op.cl);
 
+		if (op.insert_collision)
+			trace_bcache_writeback_collision(&w->key);
+
 		atomic_long_inc(op.insert_collision
 				? &dc->disk.c->writeback_keys_failed
 				: &dc->disk.c->writeback_keys_done);
@@ -275,7 +347,6 @@ static void write_dirty(struct closure *
 	io->bio.bi_bdev		= io->dc->bdev;
 	io->bio.bi_end_io	= dirty_endio;
 
-	trace_bcache_write_dirty(&io->bio);
 	closure_bio_submit(&io->bio, cl, &io->dc->disk);
 
 	continue_at(cl, write_dirty_finish, dirty_wq);
@@ -296,7 +367,6 @@ static void read_dirty_submit(struct clo
 {
 	struct dirty_io *io = container_of(cl, struct dirty_io, cl);
 
-	trace_bcache_read_dirty(&io->bio);
 	closure_bio_submit(&io->bio, cl, &io->dc->disk);
 
 	continue_at(cl, write_dirty, dirty_wq);
@@ -349,10 +419,10 @@ static void read_dirty(struct closure *c
 		io->bio.bi_rw		= READ;
 		io->bio.bi_end_io	= read_dirty_endio;
 
-		if (bch_bio_alloc_pages(&io->bio, GFP_KERNEL))
+		if (bio_alloc_pages(&io->bio, GFP_KERNEL))
 			goto err_free;
 
-		pr_debug("%s", pkey(&w->key));
+		trace_bcache_writeback(&w->key);
 
 		closure_call(&io->cl, read_dirty_submit, NULL, &dc->disk.cl);
 
@@ -375,12 +445,49 @@ err:
 	refill_dirty(cl);
 }
 
+/* Init */
+
+static int bch_btree_sectors_dirty_init(struct btree *b, struct btree_op *op,
+					struct cached_dev *dc)
+{
+	struct bkey *k;
+	struct btree_iter iter;
+
+	bch_btree_iter_init(b, &iter, &KEY(dc->disk.id, 0, 0));
+	while ((k = bch_btree_iter_next_filter(&iter, b, bch_ptr_bad)))
+		if (!b->level) {
+			if (KEY_INODE(k) > dc->disk.id)
+				break;
+
+			if (KEY_DIRTY(k))
+				bcache_dev_sectors_dirty_add(b->c, dc->disk.id,
+							     KEY_START(k),
+							     KEY_SIZE(k));
+		} else {
+			btree(sectors_dirty_init, k, b, op, dc);
+			if (KEY_INODE(k) > dc->disk.id)
+				break;
+
+			cond_resched();
+		}
+
+	return 0;
+}
+
+void bch_sectors_dirty_init(struct cached_dev *dc)
+{
+	struct btree_op op;
+
+	bch_btree_op_init_stack(&op);
+	btree_root(sectors_dirty_init, dc->disk.c, &op, dc);
+}
+
 void bch_cached_dev_writeback_init(struct cached_dev *dc)
 {
 	closure_init_unlocked(&dc->writeback);
 	init_rwsem(&dc->writeback_lock);
 
-	bch_keybuf_init(&dc->writeback_keys, dirty_pred);
+	bch_keybuf_init(&dc->writeback_keys);
 
 	dc->writeback_metadata		= true;
 	dc->writeback_running		= true;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bcache/writeback.h linux-libre-3.11-rc7-gnu/drivers/md/bcache/writeback.h
--- linux-libre-3.10-gnu/drivers/md/bcache/writeback.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/md/bcache/writeback.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,64 @@
+#ifndef _BCACHE_WRITEBACK_H
+#define _BCACHE_WRITEBACK_H
+
+#define CUTOFF_WRITEBACK	40
+#define CUTOFF_WRITEBACK_SYNC	70
+
+static inline uint64_t bcache_dev_sectors_dirty(struct bcache_device *d)
+{
+	uint64_t i, ret = 0;
+
+	for (i = 0; i < d->nr_stripes; i++)
+		ret += atomic_read(d->stripe_sectors_dirty + i);
+
+	return ret;
+}
+
+static inline bool bcache_dev_stripe_dirty(struct bcache_device *d,
+					   uint64_t offset,
+					   unsigned nr_sectors)
+{
+	uint64_t stripe = offset >> d->stripe_size_bits;
+
+	while (1) {
+		if (atomic_read(d->stripe_sectors_dirty + stripe))
+			return true;
+
+		if (nr_sectors <= 1 << d->stripe_size_bits)
+			return false;
+
+		nr_sectors -= 1 << d->stripe_size_bits;
+		stripe++;
+	}
+}
+
+static inline bool should_writeback(struct cached_dev *dc, struct bio *bio,
+				    unsigned cache_mode, bool would_skip)
+{
+	unsigned in_use = dc->disk.c->gc_stats.in_use;
+
+	if (cache_mode != CACHE_MODE_WRITEBACK ||
+	    atomic_read(&dc->disk.detaching) ||
+	    in_use > CUTOFF_WRITEBACK_SYNC)
+		return false;
+
+	if (dc->partial_stripes_expensive &&
+	    bcache_dev_stripe_dirty(&dc->disk, bio->bi_sector,
+				    bio_sectors(bio)))
+		return true;
+
+	if (would_skip)
+		return false;
+
+	return bio->bi_rw & REQ_SYNC ||
+		in_use <= CUTOFF_WRITEBACK;
+}
+
+void bcache_dev_sectors_dirty_add(struct cache_set *, unsigned, uint64_t, int);
+void bch_writeback_queue(struct cached_dev *);
+void bch_writeback_add(struct cached_dev *);
+
+void bch_sectors_dirty_init(struct cached_dev *dc);
+void bch_cached_dev_writeback_init(struct cached_dev *);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/bitmap.c linux-libre-3.11-rc7-gnu/drivers/md/bitmap.c
--- linux-libre-3.10-gnu/drivers/md/bitmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/bitmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -2002,9 +2002,9 @@ location_store(struct mddev *mddev, cons
 		} else {
 			int rv;
 			if (buf[0] == '+')
-				rv = strict_strtoll(buf+1, 10, &offset);
+				rv = kstrtoll(buf+1, 10, &offset);
 			else
-				rv = strict_strtoll(buf, 10, &offset);
+				rv = kstrtoll(buf, 10, &offset);
 			if (rv)
 				return rv;
 			if (offset == 0)
@@ -2139,7 +2139,7 @@ static ssize_t
 backlog_store(struct mddev *mddev, const char *buf, size_t len)
 {
 	unsigned long backlog;
-	int rv = strict_strtoul(buf, 10, &backlog);
+	int rv = kstrtoul(buf, 10, &backlog);
 	if (rv)
 		return rv;
 	if (backlog > COUNTER_MAX)
@@ -2165,7 +2165,7 @@ chunksize_store(struct mddev *mddev, con
 	unsigned long csize;
 	if (mddev->bitmap)
 		return -EBUSY;
-	rv = strict_strtoul(buf, 10, &csize);
+	rv = kstrtoul(buf, 10, &csize);
 	if (rv)
 		return rv;
 	if (csize < 512 ||
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-bufio.c linux-libre-3.11-rc7-gnu/drivers/md/dm-bufio.c
--- linux-libre-3.10-gnu/drivers/md/dm-bufio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-bufio.c	2013-08-25 20:43:22.000000000 -0400
@@ -145,6 +145,7 @@ struct dm_buffer {
 	unsigned long state;
 	unsigned long last_accessed;
 	struct dm_bufio_client *c;
+	struct list_head write_list;
 	struct bio bio;
 	struct bio_vec bio_vec[DM_BUFIO_INLINE_VECS];
 };
@@ -349,7 +350,7 @@ static void *alloc_buffer_data(struct dm
 	if (gfp_mask & __GFP_NORETRY)
 		noio_flag = memalloc_noio_save();
 
-	ptr = __vmalloc(c->block_size, gfp_mask, PAGE_KERNEL);
+	ptr = __vmalloc(c->block_size, gfp_mask | __GFP_HIGHMEM, PAGE_KERNEL);
 
 	if (gfp_mask & __GFP_NORETRY)
 		memalloc_noio_restore(noio_flag);
@@ -630,7 +631,8 @@ static int do_io_schedule(void *word)
  * - Submit our write and don't wait on it. We set B_WRITING indicating
  *   that there is a write in progress.
  */
-static void __write_dirty_buffer(struct dm_buffer *b)
+static void __write_dirty_buffer(struct dm_buffer *b,
+				 struct list_head *write_list)
 {
 	if (!test_bit(B_DIRTY, &b->state))
 		return;
@@ -639,7 +641,24 @@ static void __write_dirty_buffer(struct
 	wait_on_bit_lock(&b->state, B_WRITING,
 			 do_io_schedule, TASK_UNINTERRUPTIBLE);
 
-	submit_io(b, WRITE, b->block, write_endio);
+	if (!write_list)
+		submit_io(b, WRITE, b->block, write_endio);
+	else
+		list_add_tail(&b->write_list, write_list);
+}
+
+static void __flush_write_list(struct list_head *write_list)
+{
+	struct blk_plug plug;
+	blk_start_plug(&plug);
+	while (!list_empty(write_list)) {
+		struct dm_buffer *b =
+			list_entry(write_list->next, struct dm_buffer, write_list);
+		list_del(&b->write_list);
+		submit_io(b, WRITE, b->block, write_endio);
+		dm_bufio_cond_resched();
+	}
+	blk_finish_plug(&plug);
 }
 
 /*
@@ -655,7 +674,7 @@ static void __make_buffer_clean(struct d
 		return;
 
 	wait_on_bit(&b->state, B_READING, do_io_schedule, TASK_UNINTERRUPTIBLE);
-	__write_dirty_buffer(b);
+	__write_dirty_buffer(b, NULL);
 	wait_on_bit(&b->state, B_WRITING, do_io_schedule, TASK_UNINTERRUPTIBLE);
 }
 
@@ -802,7 +821,8 @@ static void __free_buffer_wake(struct dm
 	wake_up(&c->free_buffer_wait);
 }
 
-static void __write_dirty_buffers_async(struct dm_bufio_client *c, int no_wait)
+static void __write_dirty_buffers_async(struct dm_bufio_client *c, int no_wait,
+					struct list_head *write_list)
 {
 	struct dm_buffer *b, *tmp;
 
@@ -818,7 +838,7 @@ static void __write_dirty_buffers_async(
 		if (no_wait && test_bit(B_WRITING, &b->state))
 			return;
 
-		__write_dirty_buffer(b);
+		__write_dirty_buffer(b, write_list);
 		dm_bufio_cond_resched();
 	}
 }
@@ -853,7 +873,8 @@ static void __get_memory_limit(struct dm
  * If we are over threshold_buffers, start freeing buffers.
  * If we're over "limit_buffers", block until we get under the limit.
  */
-static void __check_watermark(struct dm_bufio_client *c)
+static void __check_watermark(struct dm_bufio_client *c,
+			      struct list_head *write_list)
 {
 	unsigned long threshold_buffers, limit_buffers;
 
@@ -872,7 +893,7 @@ static void __check_watermark(struct dm_
 	}
 
 	if (c->n_buffers[LIST_DIRTY] > threshold_buffers)
-		__write_dirty_buffers_async(c, 1);
+		__write_dirty_buffers_async(c, 1, write_list);
 }
 
 /*
@@ -897,7 +918,8 @@ static struct dm_buffer *__find(struct d
  *--------------------------------------------------------------*/
 
 static struct dm_buffer *__bufio_new(struct dm_bufio_client *c, sector_t block,
-				     enum new_flag nf, int *need_submit)
+				     enum new_flag nf, int *need_submit,
+				     struct list_head *write_list)
 {
 	struct dm_buffer *b, *new_b = NULL;
 
@@ -924,7 +946,7 @@ static struct dm_buffer *__bufio_new(str
 		goto found_buffer;
 	}
 
-	__check_watermark(c);
+	__check_watermark(c, write_list);
 
 	b = new_b;
 	b->hold_count = 1;
@@ -992,10 +1014,14 @@ static void *new_read(struct dm_bufio_cl
 	int need_submit;
 	struct dm_buffer *b;
 
+	LIST_HEAD(write_list);
+
 	dm_bufio_lock(c);
-	b = __bufio_new(c, block, nf, &need_submit);
+	b = __bufio_new(c, block, nf, &need_submit, &write_list);
 	dm_bufio_unlock(c);
 
+	__flush_write_list(&write_list);
+
 	if (!b)
 		return b;
 
@@ -1047,6 +1073,8 @@ void dm_bufio_prefetch(struct dm_bufio_c
 {
 	struct blk_plug plug;
 
+	LIST_HEAD(write_list);
+
 	BUG_ON(dm_bufio_in_request());
 
 	blk_start_plug(&plug);
@@ -1055,7 +1083,15 @@ void dm_bufio_prefetch(struct dm_bufio_c
 	for (; n_blocks--; block++) {
 		int need_submit;
 		struct dm_buffer *b;
-		b = __bufio_new(c, block, NF_PREFETCH, &need_submit);
+		b = __bufio_new(c, block, NF_PREFETCH, &need_submit,
+				&write_list);
+		if (unlikely(!list_empty(&write_list))) {
+			dm_bufio_unlock(c);
+			blk_finish_plug(&plug);
+			__flush_write_list(&write_list);
+			blk_start_plug(&plug);
+			dm_bufio_lock(c);
+		}
 		if (unlikely(b != NULL)) {
 			dm_bufio_unlock(c);
 
@@ -1069,7 +1105,6 @@ void dm_bufio_prefetch(struct dm_bufio_c
 				goto flush_plug;
 			dm_bufio_lock(c);
 		}
-
 	}
 
 	dm_bufio_unlock(c);
@@ -1126,11 +1161,14 @@ EXPORT_SYMBOL_GPL(dm_bufio_mark_buffer_d
 
 void dm_bufio_write_dirty_buffers_async(struct dm_bufio_client *c)
 {
+	LIST_HEAD(write_list);
+
 	BUG_ON(dm_bufio_in_request());
 
 	dm_bufio_lock(c);
-	__write_dirty_buffers_async(c, 0);
+	__write_dirty_buffers_async(c, 0, &write_list);
 	dm_bufio_unlock(c);
+	__flush_write_list(&write_list);
 }
 EXPORT_SYMBOL_GPL(dm_bufio_write_dirty_buffers_async);
 
@@ -1147,8 +1185,13 @@ int dm_bufio_write_dirty_buffers(struct
 	unsigned long buffers_processed = 0;
 	struct dm_buffer *b, *tmp;
 
+	LIST_HEAD(write_list);
+
+	dm_bufio_lock(c);
+	__write_dirty_buffers_async(c, 0, &write_list);
+	dm_bufio_unlock(c);
+	__flush_write_list(&write_list);
 	dm_bufio_lock(c);
-	__write_dirty_buffers_async(c, 0);
 
 again:
 	list_for_each_entry_safe_reverse(b, tmp, &c->lru[LIST_DIRTY], lru_list) {
@@ -1274,7 +1317,7 @@ retry:
 	BUG_ON(!b->hold_count);
 	BUG_ON(test_bit(B_READING, &b->state));
 
-	__write_dirty_buffer(b);
+	__write_dirty_buffer(b, NULL);
 	if (b->hold_count == 1) {
 		wait_on_bit(&b->state, B_WRITING,
 			    do_io_schedule, TASK_UNINTERRUPTIBLE);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm.c linux-libre-3.11-rc7-gnu/drivers/md/dm.c
--- linux-libre-3.10-gnu/drivers/md/dm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm.c	2013-08-25 20:43:22.000000000 -0400
@@ -117,15 +117,29 @@ EXPORT_SYMBOL_GPL(dm_get_rq_mapinfo);
 #define DMF_MERGE_IS_OPTIONAL 6
 
 /*
+ * A dummy definition to make RCU happy.
+ * struct dm_table should never be dereferenced in this file.
+ */
+struct dm_table {
+	int undefined__;
+};
+
+/*
  * Work processed by per-device workqueue.
  */
 struct mapped_device {
-	struct rw_semaphore io_lock;
+	struct srcu_struct io_barrier;
 	struct mutex suspend_lock;
-	rwlock_t map_lock;
 	atomic_t holders;
 	atomic_t open_count;
 
+	/*
+	 * The current mapping.
+	 * Use dm_get_live_table{_fast} or take suspend_lock for
+	 * dereference.
+	 */
+	struct dm_table *map;
+
 	unsigned long flags;
 
 	struct request_queue *queue;
@@ -155,11 +169,6 @@ struct mapped_device {
 	struct workqueue_struct *wq;
 
 	/*
-	 * The current mapping.
-	 */
-	struct dm_table *map;
-
-	/*
 	 * io objects are allocated from here.
 	 */
 	mempool_t *io_pool;
@@ -386,10 +395,14 @@ static int dm_blk_ioctl(struct block_dev
 			unsigned int cmd, unsigned long arg)
 {
 	struct mapped_device *md = bdev->bd_disk->private_data;
-	struct dm_table *map = dm_get_live_table(md);
+	int srcu_idx;
+	struct dm_table *map;
 	struct dm_target *tgt;
 	int r = -ENOTTY;
 
+retry:
+	map = dm_get_live_table(md, &srcu_idx);
+
 	if (!map || !dm_table_get_size(map))
 		goto out;
 
@@ -408,7 +421,12 @@ static int dm_blk_ioctl(struct block_dev
 		r = tgt->type->ioctl(tgt, cmd, arg);
 
 out:
-	dm_table_put(map);
+	dm_put_live_table(md, srcu_idx);
+
+	if (r == -ENOTCONN) {
+		msleep(10);
+		goto retry;
+	}
 
 	return r;
 }
@@ -502,20 +520,39 @@ static void queue_io(struct mapped_devic
 /*
  * Everyone (including functions in this file), should use this
  * function to access the md->map field, and make sure they call
- * dm_table_put() when finished.
+ * dm_put_live_table() when finished.
  */
-struct dm_table *dm_get_live_table(struct mapped_device *md)
+struct dm_table *dm_get_live_table(struct mapped_device *md, int *srcu_idx) __acquires(md->io_barrier)
 {
-	struct dm_table *t;
-	unsigned long flags;
+	*srcu_idx = srcu_read_lock(&md->io_barrier);
 
-	read_lock_irqsave(&md->map_lock, flags);
-	t = md->map;
-	if (t)
-		dm_table_get(t);
-	read_unlock_irqrestore(&md->map_lock, flags);
+	return srcu_dereference(md->map, &md->io_barrier);
+}
 
-	return t;
+void dm_put_live_table(struct mapped_device *md, int srcu_idx) __releases(md->io_barrier)
+{
+	srcu_read_unlock(&md->io_barrier, srcu_idx);
+}
+
+void dm_sync_table(struct mapped_device *md)
+{
+	synchronize_srcu(&md->io_barrier);
+	synchronize_rcu_expedited();
+}
+
+/*
+ * A fast alternative to dm_get_live_table/dm_put_live_table.
+ * The caller must not block between these two functions.
+ */
+static struct dm_table *dm_get_live_table_fast(struct mapped_device *md) __acquires(RCU)
+{
+	rcu_read_lock();
+	return rcu_dereference(md->map);
+}
+
+static void dm_put_live_table_fast(struct mapped_device *md) __releases(RCU)
+{
+	rcu_read_unlock();
 }
 
 /*
@@ -1349,17 +1386,18 @@ static int __split_and_process_non_flush
 /*
  * Entry point to split a bio into clones and submit them to the targets.
  */
-static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
+static void __split_and_process_bio(struct mapped_device *md,
+				    struct dm_table *map, struct bio *bio)
 {
 	struct clone_info ci;
 	int error = 0;
 
-	ci.map = dm_get_live_table(md);
-	if (unlikely(!ci.map)) {
+	if (unlikely(!map)) {
 		bio_io_error(bio);
 		return;
 	}
 
+	ci.map = map;
 	ci.md = md;
 	ci.io = alloc_io(md);
 	ci.io->error = 0;
@@ -1386,7 +1424,6 @@ static void __split_and_process_bio(stru
 
 	/* drop the extra reference count */
 	dec_pending(ci.io, error);
-	dm_table_put(ci.map);
 }
 /*-----------------------------------------------------------------
  * CRUD END
@@ -1397,7 +1434,7 @@ static int dm_merge_bvec(struct request_
 			 struct bio_vec *biovec)
 {
 	struct mapped_device *md = q->queuedata;
-	struct dm_table *map = dm_get_live_table(md);
+	struct dm_table *map = dm_get_live_table_fast(md);
 	struct dm_target *ti;
 	sector_t max_sectors;
 	int max_size = 0;
@@ -1407,7 +1444,7 @@ static int dm_merge_bvec(struct request_
 
 	ti = dm_table_find_target(map, bvm->bi_sector);
 	if (!dm_target_is_valid(ti))
-		goto out_table;
+		goto out;
 
 	/*
 	 * Find maximum amount of I/O that won't need splitting
@@ -1436,10 +1473,8 @@ static int dm_merge_bvec(struct request_
 
 		max_size = 0;
 
-out_table:
-	dm_table_put(map);
-
 out:
+	dm_put_live_table_fast(md);
 	/*
 	 * Always allow an entire first page
 	 */
@@ -1458,8 +1493,10 @@ static void _dm_request(struct request_q
 	int rw = bio_data_dir(bio);
 	struct mapped_device *md = q->queuedata;
 	int cpu;
+	int srcu_idx;
+	struct dm_table *map;
 
-	down_read(&md->io_lock);
+	map = dm_get_live_table(md, &srcu_idx);
 
 	cpu = part_stat_lock();
 	part_stat_inc(cpu, &dm_disk(md)->part0, ios[rw]);
@@ -1468,7 +1505,7 @@ static void _dm_request(struct request_q
 
 	/* if we're suspended, we have to queue this io for later */
 	if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) {
-		up_read(&md->io_lock);
+		dm_put_live_table(md, srcu_idx);
 
 		if (bio_rw(bio) != READA)
 			queue_io(md, bio);
@@ -1477,8 +1514,8 @@ static void _dm_request(struct request_q
 		return;
 	}
 
-	__split_and_process_bio(md, bio);
-	up_read(&md->io_lock);
+	__split_and_process_bio(md, map, bio);
+	dm_put_live_table(md, srcu_idx);
 	return;
 }
 
@@ -1664,7 +1701,8 @@ static struct request *dm_start_request(
 static void dm_request_fn(struct request_queue *q)
 {
 	struct mapped_device *md = q->queuedata;
-	struct dm_table *map = dm_get_live_table(md);
+	int srcu_idx;
+	struct dm_table *map = dm_get_live_table(md, &srcu_idx);
 	struct dm_target *ti;
 	struct request *rq, *clone;
 	sector_t pos;
@@ -1719,7 +1757,7 @@ requeued:
 delay_and_out:
 	blk_delay_queue(q, HZ / 10);
 out:
-	dm_table_put(map);
+	dm_put_live_table(md, srcu_idx);
 }
 
 int dm_underlying_device_busy(struct request_queue *q)
@@ -1732,14 +1770,14 @@ static int dm_lld_busy(struct request_qu
 {
 	int r;
 	struct mapped_device *md = q->queuedata;
-	struct dm_table *map = dm_get_live_table(md);
+	struct dm_table *map = dm_get_live_table_fast(md);
 
 	if (!map || test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))
 		r = 1;
 	else
 		r = dm_table_any_busy_target(map);
 
-	dm_table_put(map);
+	dm_put_live_table_fast(md);
 
 	return r;
 }
@@ -1751,7 +1789,7 @@ static int dm_any_congested(void *conges
 	struct dm_table *map;
 
 	if (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) {
-		map = dm_get_live_table(md);
+		map = dm_get_live_table_fast(md);
 		if (map) {
 			/*
 			 * Request-based dm cares about only own queue for
@@ -1762,9 +1800,8 @@ static int dm_any_congested(void *conges
 				    bdi_bits;
 			else
 				r = dm_table_any_congested(map, bdi_bits);
-
-			dm_table_put(map);
 		}
+		dm_put_live_table_fast(md);
 	}
 
 	return r;
@@ -1869,12 +1906,14 @@ static struct mapped_device *alloc_dev(i
 	if (r < 0)
 		goto bad_minor;
 
+	r = init_srcu_struct(&md->io_barrier);
+	if (r < 0)
+		goto bad_io_barrier;
+
 	md->type = DM_TYPE_NONE;
-	init_rwsem(&md->io_lock);
 	mutex_init(&md->suspend_lock);
 	mutex_init(&md->type_lock);
 	spin_lock_init(&md->deferred_lock);
-	rwlock_init(&md->map_lock);
 	atomic_set(&md->holders, 1);
 	atomic_set(&md->open_count, 0);
 	atomic_set(&md->event_nr, 0);
@@ -1937,6 +1976,8 @@ bad_thread:
 bad_disk:
 	blk_cleanup_queue(md->queue);
 bad_queue:
+	cleanup_srcu_struct(&md->io_barrier);
+bad_io_barrier:
 	free_minor(minor);
 bad_minor:
 	module_put(THIS_MODULE);
@@ -1960,6 +2001,7 @@ static void free_dev(struct mapped_devic
 		bioset_free(md->bs);
 	blk_integrity_unregister(md->disk);
 	del_gendisk(md->disk);
+	cleanup_srcu_struct(&md->io_barrier);
 	free_minor(minor);
 
 	spin_lock(&_minor_lock);
@@ -2102,7 +2144,6 @@ static struct dm_table *__bind(struct ma
 	struct dm_table *old_map;
 	struct request_queue *q = md->queue;
 	sector_t size;
-	unsigned long flags;
 	int merge_is_optional;
 
 	size = dm_table_get_size(t);
@@ -2131,9 +2172,8 @@ static struct dm_table *__bind(struct ma
 
 	merge_is_optional = dm_table_merge_is_optional(t);
 
-	write_lock_irqsave(&md->map_lock, flags);
 	old_map = md->map;
-	md->map = t;
+	rcu_assign_pointer(md->map, t);
 	md->immutable_target_type = dm_table_get_immutable_target_type(t);
 
 	dm_table_set_restrictions(t, q, limits);
@@ -2141,7 +2181,7 @@ static struct dm_table *__bind(struct ma
 		set_bit(DMF_MERGE_IS_OPTIONAL, &md->flags);
 	else
 		clear_bit(DMF_MERGE_IS_OPTIONAL, &md->flags);
-	write_unlock_irqrestore(&md->map_lock, flags);
+	dm_sync_table(md);
 
 	return old_map;
 }
@@ -2152,15 +2192,13 @@ static struct dm_table *__bind(struct ma
 static struct dm_table *__unbind(struct mapped_device *md)
 {
 	struct dm_table *map = md->map;
-	unsigned long flags;
 
 	if (!map)
 		return NULL;
 
 	dm_table_event_callback(map, NULL, NULL);
-	write_lock_irqsave(&md->map_lock, flags);
-	md->map = NULL;
-	write_unlock_irqrestore(&md->map_lock, flags);
+	rcu_assign_pointer(md->map, NULL);
+	dm_sync_table(md);
 
 	return map;
 }
@@ -2312,11 +2350,12 @@ EXPORT_SYMBOL_GPL(dm_device_name);
 static void __dm_destroy(struct mapped_device *md, bool wait)
 {
 	struct dm_table *map;
+	int srcu_idx;
 
 	might_sleep();
 
 	spin_lock(&_minor_lock);
-	map = dm_get_live_table(md);
+	map = dm_get_live_table(md, &srcu_idx);
 	idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md))));
 	set_bit(DMF_FREEING, &md->flags);
 	spin_unlock(&_minor_lock);
@@ -2326,6 +2365,9 @@ static void __dm_destroy(struct mapped_d
 		dm_table_postsuspend_targets(map);
 	}
 
+	/* dm_put_live_table must be before msleep, otherwise deadlock is possible */
+	dm_put_live_table(md, srcu_idx);
+
 	/*
 	 * Rare, but there may be I/O requests still going to complete,
 	 * for example.  Wait for all references to disappear.
@@ -2340,7 +2382,6 @@ static void __dm_destroy(struct mapped_d
 		       dm_device_name(md), atomic_read(&md->holders));
 
 	dm_sysfs_exit(md);
-	dm_table_put(map);
 	dm_table_destroy(__unbind(md));
 	free_dev(md);
 }
@@ -2397,8 +2438,10 @@ static void dm_wq_work(struct work_struc
 	struct mapped_device *md = container_of(work, struct mapped_device,
 						work);
 	struct bio *c;
+	int srcu_idx;
+	struct dm_table *map;
 
-	down_read(&md->io_lock);
+	map = dm_get_live_table(md, &srcu_idx);
 
 	while (!test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) {
 		spin_lock_irq(&md->deferred_lock);
@@ -2408,17 +2451,13 @@ static void dm_wq_work(struct work_struc
 		if (!c)
 			break;
 
-		up_read(&md->io_lock);
-
 		if (dm_request_based(md))
 			generic_make_request(c);
 		else
-			__split_and_process_bio(md, c);
-
-		down_read(&md->io_lock);
+			__split_and_process_bio(md, map, c);
 	}
 
-	up_read(&md->io_lock);
+	dm_put_live_table(md, srcu_idx);
 }
 
 static void dm_queue_flush(struct mapped_device *md)
@@ -2450,10 +2489,10 @@ struct dm_table *dm_swap_table(struct ma
 	 * reappear.
 	 */
 	if (dm_table_has_no_data_devices(table)) {
-		live_map = dm_get_live_table(md);
+		live_map = dm_get_live_table_fast(md);
 		if (live_map)
 			limits = md->queue->limits;
-		dm_table_put(live_map);
+		dm_put_live_table_fast(md);
 	}
 
 	if (!live_map) {
@@ -2533,7 +2572,7 @@ int dm_suspend(struct mapped_device *md,
 		goto out_unlock;
 	}
 
-	map = dm_get_live_table(md);
+	map = md->map;
 
 	/*
 	 * DMF_NOFLUSH_SUSPENDING must be set before presuspend.
@@ -2554,7 +2593,7 @@ int dm_suspend(struct mapped_device *md,
 	if (!noflush && do_lockfs) {
 		r = lock_fs(md);
 		if (r)
-			goto out;
+			goto out_unlock;
 	}
 
 	/*
@@ -2569,9 +2608,8 @@ int dm_suspend(struct mapped_device *md,
 	 * (dm_wq_work), we set BMF_BLOCK_IO_FOR_SUSPEND and call
 	 * flush_workqueue(md->wq).
 	 */
-	down_write(&md->io_lock);
 	set_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags);
-	up_write(&md->io_lock);
+	synchronize_srcu(&md->io_barrier);
 
 	/*
 	 * Stop md->queue before flushing md->wq in case request-based
@@ -2589,10 +2627,9 @@ int dm_suspend(struct mapped_device *md,
 	 */
 	r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE);
 
-	down_write(&md->io_lock);
 	if (noflush)
 		clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
-	up_write(&md->io_lock);
+	synchronize_srcu(&md->io_barrier);
 
 	/* were we interrupted ? */
 	if (r < 0) {
@@ -2602,7 +2639,7 @@ int dm_suspend(struct mapped_device *md,
 			start_queue(md->queue);
 
 		unlock_fs(md);
-		goto out; /* pushback list is already flushed, so skip flush */
+		goto out_unlock; /* pushback list is already flushed, so skip flush */
 	}
 
 	/*
@@ -2615,9 +2652,6 @@ int dm_suspend(struct mapped_device *md,
 
 	dm_table_postsuspend_targets(map);
 
-out:
-	dm_table_put(map);
-
 out_unlock:
 	mutex_unlock(&md->suspend_lock);
 	return r;
@@ -2632,7 +2666,7 @@ int dm_resume(struct mapped_device *md)
 	if (!dm_suspended_md(md))
 		goto out;
 
-	map = dm_get_live_table(md);
+	map = md->map;
 	if (!map || !dm_table_get_size(map))
 		goto out;
 
@@ -2656,7 +2690,6 @@ int dm_resume(struct mapped_device *md)
 
 	r = 0;
 out:
-	dm_table_put(map);
 	mutex_unlock(&md->suspend_lock);
 
 	return r;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-cache-policy-mq.c linux-libre-3.11-rc7-gnu/drivers/md/dm-cache-policy-mq.c
--- linux-libre-3.10-gnu/drivers/md/dm-cache-policy-mq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-cache-policy-mq.c	2013-08-25 20:43:22.000000000 -0400
@@ -959,23 +959,21 @@ out:
 	return r;
 }
 
-static void remove_mapping(struct mq_policy *mq, dm_oblock_t oblock)
+static void mq_remove_mapping(struct dm_cache_policy *p, dm_oblock_t oblock)
 {
-	struct entry *e = hash_lookup(mq, oblock);
+	struct mq_policy *mq = to_mq_policy(p);
+	struct entry *e;
+
+	mutex_lock(&mq->lock);
+
+	e = hash_lookup(mq, oblock);
 
 	BUG_ON(!e || !e->in_cache);
 
 	del(mq, e);
 	e->in_cache = false;
 	push(mq, e);
-}
-
-static void mq_remove_mapping(struct dm_cache_policy *p, dm_oblock_t oblock)
-{
-	struct mq_policy *mq = to_mq_policy(p);
 
-	mutex_lock(&mq->lock);
-	remove_mapping(mq, oblock);
 	mutex_unlock(&mq->lock);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-cache-target.c linux-libre-3.11-rc7-gnu/drivers/md/dm-cache-target.c
--- linux-libre-3.10-gnu/drivers/md/dm-cache-target.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-cache-target.c	2013-08-25 20:43:22.000000000 -0400
@@ -425,6 +425,10 @@ static bool block_size_is_power_of_two(s
 	return cache->sectors_per_block_shift >= 0;
 }
 
+/* gcc on ARM generates spurious references to __udivdi3 and __umoddi3 */
+#if defined(CONFIG_ARM) && __GNUC__ == 4 && __GNUC_MINOR__ <= 6
+__always_inline
+#endif
 static dm_block_t block_div(dm_block_t b, uint32_t n)
 {
 	do_div(b, n);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-flakey.c linux-libre-3.11-rc7-gnu/drivers/md/dm-flakey.c
--- linux-libre-3.10-gnu/drivers/md/dm-flakey.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-flakey.c	2013-08-25 20:43:22.000000000 -0400
@@ -176,7 +176,7 @@ static int flakey_ctr(struct dm_target *
 
 	fc = kzalloc(sizeof(*fc), GFP_KERNEL);
 	if (!fc) {
-		ti->error = "Cannot allocate linear context";
+		ti->error = "Cannot allocate context";
 		return -ENOMEM;
 	}
 	fc->start_time = jiffies;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-ioctl.c linux-libre-3.11-rc7-gnu/drivers/md/dm-ioctl.c
--- linux-libre-3.10-gnu/drivers/md/dm-ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,14 @@ struct hash_cell {
 	struct dm_table *new_map;
 };
 
+/*
+ * A dummy definition to make RCU happy.
+ * struct dm_table should never be dereferenced in this file.
+ */
+struct dm_table {
+	int undefined__;
+};
+
 struct vers_iter {
     size_t param_size;
     struct dm_target_versions *vers, *old_vers;
@@ -242,9 +250,10 @@ static int dm_hash_insert(const char *na
 	return -EBUSY;
 }
 
-static void __hash_remove(struct hash_cell *hc)
+static struct dm_table *__hash_remove(struct hash_cell *hc)
 {
 	struct dm_table *table;
+	int srcu_idx;
 
 	/* remove from the dev hash */
 	list_del(&hc->uuid_list);
@@ -253,16 +262,18 @@ static void __hash_remove(struct hash_ce
 	dm_set_mdptr(hc->md, NULL);
 	mutex_unlock(&dm_hash_cells_mutex);
 
-	table = dm_get_live_table(hc->md);
-	if (table) {
+	table = dm_get_live_table(hc->md, &srcu_idx);
+	if (table)
 		dm_table_event(table);
-		dm_table_put(table);
-	}
+	dm_put_live_table(hc->md, srcu_idx);
 
+	table = NULL;
 	if (hc->new_map)
-		dm_table_destroy(hc->new_map);
+		table = hc->new_map;
 	dm_put(hc->md);
 	free_cell(hc);
+
+	return table;
 }
 
 static void dm_hash_remove_all(int keep_open_devices)
@@ -270,6 +281,7 @@ static void dm_hash_remove_all(int keep_
 	int i, dev_skipped;
 	struct hash_cell *hc;
 	struct mapped_device *md;
+	struct dm_table *t;
 
 retry:
 	dev_skipped = 0;
@@ -287,10 +299,14 @@ retry:
 				continue;
 			}
 
-			__hash_remove(hc);
+			t = __hash_remove(hc);
 
 			up_write(&_hash_lock);
 
+			if (t) {
+				dm_sync_table(md);
+				dm_table_destroy(t);
+			}
 			dm_put(md);
 			if (likely(keep_open_devices))
 				dm_destroy(md);
@@ -356,6 +372,7 @@ static struct mapped_device *dm_hash_ren
 	struct dm_table *table;
 	struct mapped_device *md;
 	unsigned change_uuid = (param->flags & DM_UUID_FLAG) ? 1 : 0;
+	int srcu_idx;
 
 	/*
 	 * duplicate new.
@@ -418,11 +435,10 @@ static struct mapped_device *dm_hash_ren
 	/*
 	 * Wake up any dm event waiters.
 	 */
-	table = dm_get_live_table(hc->md);
-	if (table) {
+	table = dm_get_live_table(hc->md, &srcu_idx);
+	if (table)
 		dm_table_event(table);
-		dm_table_put(table);
-	}
+	dm_put_live_table(hc->md, srcu_idx);
 
 	if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, param->event_nr))
 		param->flags |= DM_UEVENT_GENERATED_FLAG;
@@ -620,11 +636,14 @@ static int check_name(const char *name)
  * _hash_lock without first calling dm_table_put, because dm_table_destroy
  * waits for this dm_table_put and could be called under this lock.
  */
-static struct dm_table *dm_get_inactive_table(struct mapped_device *md)
+static struct dm_table *dm_get_inactive_table(struct mapped_device *md, int *srcu_idx)
 {
 	struct hash_cell *hc;
 	struct dm_table *table = NULL;
 
+	/* increment rcu count, we don't care about the table pointer */
+	dm_get_live_table(md, srcu_idx);
+
 	down_read(&_hash_lock);
 	hc = dm_get_mdptr(md);
 	if (!hc || hc->md != md) {
@@ -633,8 +652,6 @@ static struct dm_table *dm_get_inactive_
 	}
 
 	table = hc->new_map;
-	if (table)
-		dm_table_get(table);
 
 out:
 	up_read(&_hash_lock);
@@ -643,10 +660,11 @@ out:
 }
 
 static struct dm_table *dm_get_live_or_inactive_table(struct mapped_device *md,
-						      struct dm_ioctl *param)
+						      struct dm_ioctl *param,
+						      int *srcu_idx)
 {
 	return (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) ?
-		dm_get_inactive_table(md) : dm_get_live_table(md);
+		dm_get_inactive_table(md, srcu_idx) : dm_get_live_table(md, srcu_idx);
 }
 
 /*
@@ -657,6 +675,7 @@ static void __dev_status(struct mapped_d
 {
 	struct gendisk *disk = dm_disk(md);
 	struct dm_table *table;
+	int srcu_idx;
 
 	param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG |
 			  DM_ACTIVE_PRESENT_FLAG);
@@ -676,26 +695,27 @@ static void __dev_status(struct mapped_d
 	param->event_nr = dm_get_event_nr(md);
 	param->target_count = 0;
 
-	table = dm_get_live_table(md);
+	table = dm_get_live_table(md, &srcu_idx);
 	if (table) {
 		if (!(param->flags & DM_QUERY_INACTIVE_TABLE_FLAG)) {
 			if (get_disk_ro(disk))
 				param->flags |= DM_READONLY_FLAG;
 			param->target_count = dm_table_get_num_targets(table);
 		}
-		dm_table_put(table);
 
 		param->flags |= DM_ACTIVE_PRESENT_FLAG;
 	}
+	dm_put_live_table(md, srcu_idx);
 
 	if (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) {
-		table = dm_get_inactive_table(md);
+		int srcu_idx;
+		table = dm_get_inactive_table(md, &srcu_idx);
 		if (table) {
 			if (!(dm_table_get_mode(table) & FMODE_WRITE))
 				param->flags |= DM_READONLY_FLAG;
 			param->target_count = dm_table_get_num_targets(table);
-			dm_table_put(table);
 		}
+		dm_put_live_table(md, srcu_idx);
 	}
 }
 
@@ -796,6 +816,7 @@ static int dev_remove(struct dm_ioctl *p
 	struct hash_cell *hc;
 	struct mapped_device *md;
 	int r;
+	struct dm_table *t;
 
 	down_write(&_hash_lock);
 	hc = __find_device_hash_cell(param);
@@ -819,9 +840,14 @@ static int dev_remove(struct dm_ioctl *p
 		return r;
 	}
 
-	__hash_remove(hc);
+	t = __hash_remove(hc);
 	up_write(&_hash_lock);
 
+	if (t) {
+		dm_sync_table(md);
+		dm_table_destroy(t);
+	}
+
 	if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr))
 		param->flags |= DM_UEVENT_GENERATED_FLAG;
 
@@ -986,6 +1012,7 @@ static int do_resume(struct dm_ioctl *pa
 
 		old_map = dm_swap_table(md, new_map);
 		if (IS_ERR(old_map)) {
+			dm_sync_table(md);
 			dm_table_destroy(new_map);
 			dm_put(md);
 			return PTR_ERR(old_map);
@@ -1003,6 +1030,10 @@ static int do_resume(struct dm_ioctl *pa
 			param->flags |= DM_UEVENT_GENERATED_FLAG;
 	}
 
+	/*
+	 * Since dm_swap_table synchronizes RCU, nobody should be in
+	 * read-side critical section already.
+	 */
 	if (old_map)
 		dm_table_destroy(old_map);
 
@@ -1125,6 +1156,7 @@ static int dev_wait(struct dm_ioctl *par
 	int r = 0;
 	struct mapped_device *md;
 	struct dm_table *table;
+	int srcu_idx;
 
 	md = find_device(param);
 	if (!md)
@@ -1145,11 +1177,10 @@ static int dev_wait(struct dm_ioctl *par
 	 */
 	__dev_status(md, param);
 
-	table = dm_get_live_or_inactive_table(md, param);
-	if (table) {
+	table = dm_get_live_or_inactive_table(md, param, &srcu_idx);
+	if (table)
 		retrieve_status(table, param, param_size);
-		dm_table_put(table);
-	}
+	dm_put_live_table(md, srcu_idx);
 
 out:
 	dm_put(md);
@@ -1221,7 +1252,7 @@ static int table_load(struct dm_ioctl *p
 {
 	int r;
 	struct hash_cell *hc;
-	struct dm_table *t;
+	struct dm_table *t, *old_map = NULL;
 	struct mapped_device *md;
 	struct target_type *immutable_target_type;
 
@@ -1277,14 +1308,14 @@ static int table_load(struct dm_ioctl *p
 	hc = dm_get_mdptr(md);
 	if (!hc || hc->md != md) {
 		DMWARN("device has been removed from the dev hash table.");
-		dm_table_destroy(t);
 		up_write(&_hash_lock);
+		dm_table_destroy(t);
 		r = -ENXIO;
 		goto out;
 	}
 
 	if (hc->new_map)
-		dm_table_destroy(hc->new_map);
+		old_map = hc->new_map;
 	hc->new_map = t;
 	up_write(&_hash_lock);
 
@@ -1292,6 +1323,11 @@ static int table_load(struct dm_ioctl *p
 	__dev_status(md, param);
 
 out:
+	if (old_map) {
+		dm_sync_table(md);
+		dm_table_destroy(old_map);
+	}
+
 	dm_put(md);
 
 	return r;
@@ -1301,6 +1337,7 @@ static int table_clear(struct dm_ioctl *
 {
 	struct hash_cell *hc;
 	struct mapped_device *md;
+	struct dm_table *old_map = NULL;
 
 	down_write(&_hash_lock);
 
@@ -1312,7 +1349,7 @@ static int table_clear(struct dm_ioctl *
 	}
 
 	if (hc->new_map) {
-		dm_table_destroy(hc->new_map);
+		old_map = hc->new_map;
 		hc->new_map = NULL;
 	}
 
@@ -1321,6 +1358,10 @@ static int table_clear(struct dm_ioctl *
 	__dev_status(hc->md, param);
 	md = hc->md;
 	up_write(&_hash_lock);
+	if (old_map) {
+		dm_sync_table(md);
+		dm_table_destroy(old_map);
+	}
 	dm_put(md);
 
 	return 0;
@@ -1370,6 +1411,7 @@ static int table_deps(struct dm_ioctl *p
 {
 	struct mapped_device *md;
 	struct dm_table *table;
+	int srcu_idx;
 
 	md = find_device(param);
 	if (!md)
@@ -1377,11 +1419,10 @@ static int table_deps(struct dm_ioctl *p
 
 	__dev_status(md, param);
 
-	table = dm_get_live_or_inactive_table(md, param);
-	if (table) {
+	table = dm_get_live_or_inactive_table(md, param, &srcu_idx);
+	if (table)
 		retrieve_deps(table, param, param_size);
-		dm_table_put(table);
-	}
+	dm_put_live_table(md, srcu_idx);
 
 	dm_put(md);
 
@@ -1396,6 +1437,7 @@ static int table_status(struct dm_ioctl
 {
 	struct mapped_device *md;
 	struct dm_table *table;
+	int srcu_idx;
 
 	md = find_device(param);
 	if (!md)
@@ -1403,11 +1445,10 @@ static int table_status(struct dm_ioctl
 
 	__dev_status(md, param);
 
-	table = dm_get_live_or_inactive_table(md, param);
-	if (table) {
+	table = dm_get_live_or_inactive_table(md, param, &srcu_idx);
+	if (table)
 		retrieve_status(table, param, param_size);
-		dm_table_put(table);
-	}
+	dm_put_live_table(md, srcu_idx);
 
 	dm_put(md);
 
@@ -1443,6 +1484,7 @@ static int target_message(struct dm_ioct
 	struct dm_target_msg *tmsg = (void *) param + param->data_start;
 	size_t maxlen;
 	char *result = get_result_buffer(param, param_size, &maxlen);
+	int srcu_idx;
 
 	md = find_device(param);
 	if (!md)
@@ -1470,9 +1512,9 @@ static int target_message(struct dm_ioct
 	if (r <= 1)
 		goto out_argv;
 
-	table = dm_get_live_table(md);
+	table = dm_get_live_table(md, &srcu_idx);
 	if (!table)
-		goto out_argv;
+		goto out_table;
 
 	if (dm_deleting_md(md)) {
 		r = -ENXIO;
@@ -1491,7 +1533,7 @@ static int target_message(struct dm_ioct
 	}
 
  out_table:
-	dm_table_put(table);
+	dm_put_live_table(md, srcu_idx);
  out_argv:
 	kfree(argv);
  out:
@@ -1644,7 +1686,10 @@ static int copy_params(struct dm_ioctl _
 	}
 
 	if (!dmi) {
-		dmi = __vmalloc(param_kernel->data_size, GFP_NOIO | __GFP_REPEAT | __GFP_HIGH, PAGE_KERNEL);
+		unsigned noio_flag;
+		noio_flag = memalloc_noio_save();
+		dmi = __vmalloc(param_kernel->data_size, GFP_NOIO | __GFP_REPEAT | __GFP_HIGH | __GFP_HIGHMEM, PAGE_KERNEL);
+		memalloc_noio_restore(noio_flag);
 		if (dmi)
 			*param_flags |= DM_PARAMS_VMALLOC;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-mpath.c linux-libre-3.11-rc7-gnu/drivers/md/dm-mpath.c
--- linux-libre-3.10-gnu/drivers/md/dm-mpath.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-mpath.c	2013-08-25 20:43:22.000000000 -0400
@@ -1561,7 +1561,6 @@ static int multipath_ioctl(struct dm_tar
 	unsigned long flags;
 	int r;
 
-again:
 	bdev = NULL;
 	mode = 0;
 	r = 0;
@@ -1579,7 +1578,7 @@ again:
 	}
 
 	if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path))
-		r = -EAGAIN;
+		r = -ENOTCONN;
 	else if (!bdev)
 		r = -EIO;
 
@@ -1591,11 +1590,8 @@ again:
 	if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
 		r = scsi_verify_blk_ioctl(NULL, cmd);
 
-	if (r == -EAGAIN && !fatal_signal_pending(current)) {
+	if (r == -ENOTCONN && !fatal_signal_pending(current))
 		queue_work(kmultipathd, &m->process_queued_ios);
-		msleep(10);
-		goto again;
-	}
 
 	return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-raid.c linux-libre-3.11-rc7-gnu/drivers/md/dm-raid.c
--- linux-libre-3.10-gnu/drivers/md/dm-raid.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-raid.c	2013-08-25 20:43:22.000000000 -0400
@@ -380,7 +380,7 @@ static int validate_region_size(struct r
 static int validate_raid_redundancy(struct raid_set *rs)
 {
 	unsigned i, rebuild_cnt = 0;
-	unsigned rebuilds_per_group, copies, d;
+	unsigned rebuilds_per_group = 0, copies, d;
 	unsigned group_size, last_group_start;
 
 	for (i = 0; i < rs->md.raid_disks; i++)
@@ -504,7 +504,7 @@ static int parse_raid_params(struct raid
 	 * First, parse the in-order required arguments
 	 * "chunk_size" is the only argument of this type.
 	 */
-	if ((strict_strtoul(argv[0], 10, &value) < 0)) {
+	if ((kstrtoul(argv[0], 10, &value) < 0)) {
 		rs->ti->error = "Bad chunk size";
 		return -EINVAL;
 	} else if (rs->raid_type->level == 1) {
@@ -585,7 +585,7 @@ static int parse_raid_params(struct raid
 			continue;
 		}
 
-		if (strict_strtoul(argv[i], 10, &value) < 0) {
+		if (kstrtoul(argv[i], 10, &value) < 0) {
 			rs->ti->error = "Bad numerical argument given in raid params";
 			return -EINVAL;
 		}
@@ -1181,7 +1181,7 @@ static int raid_ctr(struct dm_target *ti
 	argv++;
 
 	/* number of RAID parameters */
-	if (strict_strtoul(argv[0], 10, &num_raid_params) < 0) {
+	if (kstrtoul(argv[0], 10, &num_raid_params) < 0) {
 		ti->error = "Cannot understand number of RAID parameters";
 		return -EINVAL;
 	}
@@ -1194,7 +1194,7 @@ static int raid_ctr(struct dm_target *ti
 		return -EINVAL;
 	}
 
-	if ((strict_strtoul(argv[num_raid_params], 10, &num_raid_devs) < 0) ||
+	if ((kstrtoul(argv[num_raid_params], 10, &num_raid_devs) < 0) ||
 	    (num_raid_devs >= INT_MAX)) {
 		ti->error = "Cannot understand number of raid devices";
 		return -EINVAL;
@@ -1388,6 +1388,7 @@ static void raid_status(struct dm_target
 		 *   performing a "check" of the array.
 		 */
 		DMEMIT(" %llu",
+		       (strcmp(rs->md.last_sync_action, "check")) ? 0 :
 		       (unsigned long long)
 		       atomic64_read(&rs->md.resync_mismatches));
 		break;
@@ -1572,6 +1573,62 @@ static void raid_postsuspend(struct dm_t
 	mddev_suspend(&rs->md);
 }
 
+static void attempt_restore_of_faulty_devices(struct raid_set *rs)
+{
+	int i;
+	uint64_t failed_devices, cleared_failed_devices = 0;
+	unsigned long flags;
+	struct dm_raid_superblock *sb;
+	struct md_rdev *r;
+
+	for (i = 0; i < rs->md.raid_disks; i++) {
+		r = &rs->dev[i].rdev;
+		if (test_bit(Faulty, &r->flags) && r->sb_page &&
+		    sync_page_io(r, 0, r->sb_size, r->sb_page, READ, 1)) {
+			DMINFO("Faulty %s device #%d has readable super block."
+			       "  Attempting to revive it.",
+			       rs->raid_type->name, i);
+
+			/*
+			 * Faulty bit may be set, but sometimes the array can
+			 * be suspended before the personalities can respond
+			 * by removing the device from the array (i.e. calling
+			 * 'hot_remove_disk').  If they haven't yet removed
+			 * the failed device, its 'raid_disk' number will be
+			 * '>= 0' - meaning we must call this function
+			 * ourselves.
+			 */
+			if ((r->raid_disk >= 0) &&
+			    (r->mddev->pers->hot_remove_disk(r->mddev, r) != 0))
+				/* Failed to revive this device, try next */
+				continue;
+
+			r->raid_disk = i;
+			r->saved_raid_disk = i;
+			flags = r->flags;
+			clear_bit(Faulty, &r->flags);
+			clear_bit(WriteErrorSeen, &r->flags);
+			clear_bit(In_sync, &r->flags);
+			if (r->mddev->pers->hot_add_disk(r->mddev, r)) {
+				r->raid_disk = -1;
+				r->saved_raid_disk = -1;
+				r->flags = flags;
+			} else {
+				r->recovery_offset = 0;
+				cleared_failed_devices |= 1 << i;
+			}
+		}
+	}
+	if (cleared_failed_devices) {
+		rdev_for_each(r, &rs->md) {
+			sb = page_address(r->sb_page);
+			failed_devices = le64_to_cpu(sb->failed_devices);
+			failed_devices &= ~cleared_failed_devices;
+			sb->failed_devices = cpu_to_le64(failed_devices);
+		}
+	}
+}
+
 static void raid_resume(struct dm_target *ti)
 {
 	struct raid_set *rs = ti->private;
@@ -1580,6 +1637,13 @@ static void raid_resume(struct dm_target
 	if (!rs->bitmap_loaded) {
 		bitmap_load(&rs->md);
 		rs->bitmap_loaded = 1;
+	} else {
+		/*
+		 * A secondary resume while the device is active.
+		 * Take this opportunity to check whether any failed
+		 * devices are reachable again.
+		 */
+		attempt_restore_of_faulty_devices(rs);
 	}
 
 	clear_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
@@ -1588,7 +1652,7 @@ static void raid_resume(struct dm_target
 
 static struct target_type raid_target = {
 	.name = "raid",
-	.version = {1, 5, 0},
+	.version = {1, 5, 2},
 	.module = THIS_MODULE,
 	.ctr = raid_ctr,
 	.dtr = raid_dtr,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-switch.c linux-libre-3.11-rc7-gnu/drivers/md/dm-switch.c
--- linux-libre-3.10-gnu/drivers/md/dm-switch.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-switch.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2010-2012 by Dell Inc.  All rights reserved.
+ * Copyright (C) 2011-2013 Red Hat, Inc.
+ *
+ * This file is released under the GPL.
+ *
+ * dm-switch is a device-mapper target that maps IO to underlying block
+ * devices efficiently when there are a large number of fixed-sized
+ * address regions but there is no simple pattern to allow for a compact
+ * mapping representation such as dm-stripe.
+ */
+
+#include <linux/device-mapper.h>
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+
+#define DM_MSG_PREFIX "switch"
+
+/*
+ * One region_table_slot_t holds <region_entries_per_slot> region table
+ * entries each of which is <region_table_entry_bits> in size.
+ */
+typedef unsigned long region_table_slot_t;
+
+/*
+ * A device with the offset to its start sector.
+ */
+struct switch_path {
+	struct dm_dev *dmdev;
+	sector_t start;
+};
+
+/*
+ * Context block for a dm switch device.
+ */
+struct switch_ctx {
+	struct dm_target *ti;
+
+	unsigned nr_paths;		/* Number of paths in path_list. */
+
+	unsigned region_size;		/* Region size in 512-byte sectors */
+	unsigned long nr_regions;	/* Number of regions making up the device */
+	signed char region_size_bits;	/* log2 of region_size or -1 */
+
+	unsigned char region_table_entry_bits;	/* Number of bits in one region table entry */
+	unsigned char region_entries_per_slot;	/* Number of entries in one region table slot */
+	signed char region_entries_per_slot_bits;	/* log2 of region_entries_per_slot or -1 */
+
+	region_table_slot_t *region_table;	/* Region table */
+
+	/*
+	 * Array of dm devices to switch between.
+	 */
+	struct switch_path path_list[0];
+};
+
+static struct switch_ctx *alloc_switch_ctx(struct dm_target *ti, unsigned nr_paths,
+					   unsigned region_size)
+{
+	struct switch_ctx *sctx;
+
+	sctx = kzalloc(sizeof(struct switch_ctx) + nr_paths * sizeof(struct switch_path),
+		       GFP_KERNEL);
+	if (!sctx)
+		return NULL;
+
+	sctx->ti = ti;
+	sctx->region_size = region_size;
+
+	ti->private = sctx;
+
+	return sctx;
+}
+
+static int alloc_region_table(struct dm_target *ti, unsigned nr_paths)
+{
+	struct switch_ctx *sctx = ti->private;
+	sector_t nr_regions = ti->len;
+	sector_t nr_slots;
+
+	if (!(sctx->region_size & (sctx->region_size - 1)))
+		sctx->region_size_bits = __ffs(sctx->region_size);
+	else
+		sctx->region_size_bits = -1;
+
+	sctx->region_table_entry_bits = 1;
+	while (sctx->region_table_entry_bits < sizeof(region_table_slot_t) * 8 &&
+	       (region_table_slot_t)1 << sctx->region_table_entry_bits < nr_paths)
+		sctx->region_table_entry_bits++;
+
+	sctx->region_entries_per_slot = (sizeof(region_table_slot_t) * 8) / sctx->region_table_entry_bits;
+	if (!(sctx->region_entries_per_slot & (sctx->region_entries_per_slot - 1)))
+		sctx->region_entries_per_slot_bits = __ffs(sctx->region_entries_per_slot);
+	else
+		sctx->region_entries_per_slot_bits = -1;
+
+	if (sector_div(nr_regions, sctx->region_size))
+		nr_regions++;
+
+	sctx->nr_regions = nr_regions;
+	if (sctx->nr_regions != nr_regions || sctx->nr_regions >= ULONG_MAX) {
+		ti->error = "Region table too large";
+		return -EINVAL;
+	}
+
+	nr_slots = nr_regions;
+	if (sector_div(nr_slots, sctx->region_entries_per_slot))
+		nr_slots++;
+
+	if (nr_slots > ULONG_MAX / sizeof(region_table_slot_t)) {
+		ti->error = "Region table too large";
+		return -EINVAL;
+	}
+
+	sctx->region_table = vmalloc(nr_slots * sizeof(region_table_slot_t));
+	if (!sctx->region_table) {
+		ti->error = "Cannot allocate region table";
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void switch_get_position(struct switch_ctx *sctx, unsigned long region_nr,
+				unsigned long *region_index, unsigned *bit)
+{
+	if (sctx->region_entries_per_slot_bits >= 0) {
+		*region_index = region_nr >> sctx->region_entries_per_slot_bits;
+		*bit = region_nr & (sctx->region_entries_per_slot - 1);
+	} else {
+		*region_index = region_nr / sctx->region_entries_per_slot;
+		*bit = region_nr % sctx->region_entries_per_slot;
+	}
+
+	*bit *= sctx->region_table_entry_bits;
+}
+
+/*
+ * Find which path to use at given offset.
+ */
+static unsigned switch_get_path_nr(struct switch_ctx *sctx, sector_t offset)
+{
+	unsigned long region_index;
+	unsigned bit, path_nr;
+	sector_t p;
+
+	p = offset;
+	if (sctx->region_size_bits >= 0)
+		p >>= sctx->region_size_bits;
+	else
+		sector_div(p, sctx->region_size);
+
+	switch_get_position(sctx, p, &region_index, &bit);
+	path_nr = (ACCESS_ONCE(sctx->region_table[region_index]) >> bit) &
+	       ((1 << sctx->region_table_entry_bits) - 1);
+
+	/* This can only happen if the processor uses non-atomic stores. */
+	if (unlikely(path_nr >= sctx->nr_paths))
+		path_nr = 0;
+
+	return path_nr;
+}
+
+static void switch_region_table_write(struct switch_ctx *sctx, unsigned long region_nr,
+				      unsigned value)
+{
+	unsigned long region_index;
+	unsigned bit;
+	region_table_slot_t pte;
+
+	switch_get_position(sctx, region_nr, &region_index, &bit);
+
+	pte = sctx->region_table[region_index];
+	pte &= ~((((region_table_slot_t)1 << sctx->region_table_entry_bits) - 1) << bit);
+	pte |= (region_table_slot_t)value << bit;
+	sctx->region_table[region_index] = pte;
+}
+
+/*
+ * Fill the region table with an initial round robin pattern.
+ */
+static void initialise_region_table(struct switch_ctx *sctx)
+{
+	unsigned path_nr = 0;
+	unsigned long region_nr;
+
+	for (region_nr = 0; region_nr < sctx->nr_regions; region_nr++) {
+		switch_region_table_write(sctx, region_nr, path_nr);
+		if (++path_nr >= sctx->nr_paths)
+			path_nr = 0;
+	}
+}
+
+static int parse_path(struct dm_arg_set *as, struct dm_target *ti)
+{
+	struct switch_ctx *sctx = ti->private;
+	unsigned long long start;
+	int r;
+
+	r = dm_get_device(ti, dm_shift_arg(as), dm_table_get_mode(ti->table),
+			  &sctx->path_list[sctx->nr_paths].dmdev);
+	if (r) {
+		ti->error = "Device lookup failed";
+		return r;
+	}
+
+	if (kstrtoull(dm_shift_arg(as), 10, &start) || start != (sector_t)start) {
+		ti->error = "Invalid device starting offset";
+		dm_put_device(ti, sctx->path_list[sctx->nr_paths].dmdev);
+		return -EINVAL;
+	}
+
+	sctx->path_list[sctx->nr_paths].start = start;
+
+	sctx->nr_paths++;
+
+	return 0;
+}
+
+/*
+ * Destructor: Don't free the dm_target, just the ti->private data (if any).
+ */
+static void switch_dtr(struct dm_target *ti)
+{
+	struct switch_ctx *sctx = ti->private;
+
+	while (sctx->nr_paths--)
+		dm_put_device(ti, sctx->path_list[sctx->nr_paths].dmdev);
+
+	vfree(sctx->region_table);
+	kfree(sctx);
+}
+
+/*
+ * Constructor arguments:
+ *   <num_paths> <region_size> <num_optional_args> [<optional_args>...]
+ *   [<dev_path> <offset>]+
+ *
+ * Optional args are to allow for future extension: currently this
+ * parameter must be 0.
+ */
+static int switch_ctr(struct dm_target *ti, unsigned argc, char **argv)
+{
+	static struct dm_arg _args[] = {
+		{1, (KMALLOC_MAX_SIZE - sizeof(struct switch_ctx)) / sizeof(struct switch_path), "Invalid number of paths"},
+		{1, UINT_MAX, "Invalid region size"},
+		{0, 0, "Invalid number of optional args"},
+	};
+
+	struct switch_ctx *sctx;
+	struct dm_arg_set as;
+	unsigned nr_paths, region_size, nr_optional_args;
+	int r;
+
+	as.argc = argc;
+	as.argv = argv;
+
+	r = dm_read_arg(_args, &as, &nr_paths, &ti->error);
+	if (r)
+		return -EINVAL;
+
+	r = dm_read_arg(_args + 1, &as, &region_size, &ti->error);
+	if (r)
+		return r;
+
+	r = dm_read_arg_group(_args + 2, &as, &nr_optional_args, &ti->error);
+	if (r)
+		return r;
+	/* parse optional arguments here, if we add any */
+
+	if (as.argc != nr_paths * 2) {
+		ti->error = "Incorrect number of path arguments";
+		return -EINVAL;
+	}
+
+	sctx = alloc_switch_ctx(ti, nr_paths, region_size);
+	if (!sctx) {
+		ti->error = "Cannot allocate redirection context";
+		return -ENOMEM;
+	}
+
+	r = dm_set_target_max_io_len(ti, region_size);
+	if (r)
+		goto error;
+
+	while (as.argc) {
+		r = parse_path(&as, ti);
+		if (r)
+			goto error;
+	}
+
+	r = alloc_region_table(ti, nr_paths);
+	if (r)
+		goto error;
+
+	initialise_region_table(sctx);
+
+	/* For UNMAP, sending the request down any path is sufficient */
+	ti->num_discard_bios = 1;
+
+	return 0;
+
+error:
+	switch_dtr(ti);
+
+	return r;
+}
+
+static int switch_map(struct dm_target *ti, struct bio *bio)
+{
+	struct switch_ctx *sctx = ti->private;
+	sector_t offset = dm_target_offset(ti, bio->bi_sector);
+	unsigned path_nr = switch_get_path_nr(sctx, offset);
+
+	bio->bi_bdev = sctx->path_list[path_nr].dmdev->bdev;
+	bio->bi_sector = sctx->path_list[path_nr].start + offset;
+
+	return DM_MAPIO_REMAPPED;
+}
+
+/*
+ * We need to parse hex numbers in the message as quickly as possible.
+ *
+ * This table-based hex parser improves performance.
+ * It improves a time to load 1000000 entries compared to the condition-based
+ * parser.
+ *		table-based parser	condition-based parser
+ * PA-RISC	0.29s			0.31s
+ * Opteron	0.0495s			0.0498s
+ */
+static const unsigned char hex_table[256] = {
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
+255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
+};
+
+static __always_inline unsigned long parse_hex(const char **string)
+{
+	unsigned char d;
+	unsigned long r = 0;
+
+	while ((d = hex_table[(unsigned char)**string]) < 16) {
+		r = (r << 4) | d;
+		(*string)++;
+	}
+
+	return r;
+}
+
+static int process_set_region_mappings(struct switch_ctx *sctx,
+			     unsigned argc, char **argv)
+{
+	unsigned i;
+	unsigned long region_index = 0;
+
+	for (i = 1; i < argc; i++) {
+		unsigned long path_nr;
+		const char *string = argv[i];
+
+		if (*string == ':')
+			region_index++;
+		else {
+			region_index = parse_hex(&string);
+			if (unlikely(*string != ':')) {
+				DMWARN("invalid set_region_mappings argument: '%s'", argv[i]);
+				return -EINVAL;
+			}
+		}
+
+		string++;
+		if (unlikely(!*string)) {
+			DMWARN("invalid set_region_mappings argument: '%s'", argv[i]);
+			return -EINVAL;
+		}
+
+		path_nr = parse_hex(&string);
+		if (unlikely(*string)) {
+			DMWARN("invalid set_region_mappings argument: '%s'", argv[i]);
+			return -EINVAL;
+		}
+		if (unlikely(region_index >= sctx->nr_regions)) {
+			DMWARN("invalid set_region_mappings region number: %lu >= %lu", region_index, sctx->nr_regions);
+			return -EINVAL;
+		}
+		if (unlikely(path_nr >= sctx->nr_paths)) {
+			DMWARN("invalid set_region_mappings device: %lu >= %u", path_nr, sctx->nr_paths);
+			return -EINVAL;
+		}
+
+		switch_region_table_write(sctx, region_index, path_nr);
+	}
+
+	return 0;
+}
+
+/*
+ * Messages are processed one-at-a-time.
+ *
+ * Only set_region_mappings is supported.
+ */
+static int switch_message(struct dm_target *ti, unsigned argc, char **argv)
+{
+	static DEFINE_MUTEX(message_mutex);
+
+	struct switch_ctx *sctx = ti->private;
+	int r = -EINVAL;
+
+	mutex_lock(&message_mutex);
+
+	if (!strcasecmp(argv[0], "set_region_mappings"))
+		r = process_set_region_mappings(sctx, argc, argv);
+	else
+		DMWARN("Unrecognised message received.");
+
+	mutex_unlock(&message_mutex);
+
+	return r;
+}
+
+static void switch_status(struct dm_target *ti, status_type_t type,
+			  unsigned status_flags, char *result, unsigned maxlen)
+{
+	struct switch_ctx *sctx = ti->private;
+	unsigned sz = 0;
+	int path_nr;
+
+	switch (type) {
+	case STATUSTYPE_INFO:
+		result[0] = '\0';
+		break;
+
+	case STATUSTYPE_TABLE:
+		DMEMIT("%u %u 0", sctx->nr_paths, sctx->region_size);
+		for (path_nr = 0; path_nr < sctx->nr_paths; path_nr++)
+			DMEMIT(" %s %llu", sctx->path_list[path_nr].dmdev->name,
+			       (unsigned long long)sctx->path_list[path_nr].start);
+		break;
+	}
+}
+
+/*
+ * Switch ioctl:
+ *
+ * Passthrough all ioctls to the path for sector 0
+ */
+static int switch_ioctl(struct dm_target *ti, unsigned cmd,
+			unsigned long arg)
+{
+	struct switch_ctx *sctx = ti->private;
+	struct block_device *bdev;
+	fmode_t mode;
+	unsigned path_nr;
+	int r = 0;
+
+	path_nr = switch_get_path_nr(sctx, 0);
+
+	bdev = sctx->path_list[path_nr].dmdev->bdev;
+	mode = sctx->path_list[path_nr].dmdev->mode;
+
+	/*
+	 * Only pass ioctls through if the device sizes match exactly.
+	 */
+	if (ti->len + sctx->path_list[path_nr].start != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
+		r = scsi_verify_blk_ioctl(NULL, cmd);
+
+	return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
+}
+
+static int switch_iterate_devices(struct dm_target *ti,
+				  iterate_devices_callout_fn fn, void *data)
+{
+	struct switch_ctx *sctx = ti->private;
+	int path_nr;
+	int r;
+
+	for (path_nr = 0; path_nr < sctx->nr_paths; path_nr++) {
+		r = fn(ti, sctx->path_list[path_nr].dmdev,
+			 sctx->path_list[path_nr].start, ti->len, data);
+		if (r)
+			return r;
+	}
+
+	return 0;
+}
+
+static struct target_type switch_target = {
+	.name = "switch",
+	.version = {1, 0, 0},
+	.module = THIS_MODULE,
+	.ctr = switch_ctr,
+	.dtr = switch_dtr,
+	.map = switch_map,
+	.message = switch_message,
+	.status = switch_status,
+	.ioctl = switch_ioctl,
+	.iterate_devices = switch_iterate_devices,
+};
+
+static int __init dm_switch_init(void)
+{
+	int r;
+
+	r = dm_register_target(&switch_target);
+	if (r < 0)
+		DMERR("dm_register_target() failed %d", r);
+
+	return r;
+}
+
+static void __exit dm_switch_exit(void)
+{
+	dm_unregister_target(&switch_target);
+}
+
+module_init(dm_switch_init);
+module_exit(dm_switch_exit);
+
+MODULE_DESCRIPTION(DM_NAME " dynamic path switching target");
+MODULE_AUTHOR("Kevin D. O'Kelley <Kevin_OKelley@dell.com>");
+MODULE_AUTHOR("Narendran Ganapathy <Narendran_Ganapathy@dell.com>");
+MODULE_AUTHOR("Jim Ramsay <Jim_Ramsay@dell.com>");
+MODULE_AUTHOR("Mikulas Patocka <mpatocka@redhat.com>");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-table.c linux-libre-3.11-rc7-gnu/drivers/md/dm-table.c
--- linux-libre-3.10-gnu/drivers/md/dm-table.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-table.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,22 +26,8 @@
 #define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t))
 #define CHILDREN_PER_NODE (KEYS_PER_NODE + 1)
 
-/*
- * The table has always exactly one reference from either mapped_device->map
- * or hash_cell->new_map. This reference is not counted in table->holders.
- * A pair of dm_create_table/dm_destroy_table functions is used for table
- * creation/destruction.
- *
- * Temporary references from the other code increase table->holders. A pair
- * of dm_table_get/dm_table_put functions is used to manipulate it.
- *
- * When the table is about to be destroyed, we wait for table->holders to
- * drop to zero.
- */
-
 struct dm_table {
 	struct mapped_device *md;
-	atomic_t holders;
 	unsigned type;
 
 	/* btree table */
@@ -208,7 +194,6 @@ int dm_table_create(struct dm_table **re
 
 	INIT_LIST_HEAD(&t->devices);
 	INIT_LIST_HEAD(&t->target_callbacks);
-	atomic_set(&t->holders, 0);
 
 	if (!num_targets)
 		num_targets = KEYS_PER_NODE;
@@ -246,10 +231,6 @@ void dm_table_destroy(struct dm_table *t
 	if (!t)
 		return;
 
-	while (atomic_read(&t->holders))
-		msleep(1);
-	smp_mb();
-
 	/* free the indexes */
 	if (t->depth >= 2)
 		vfree(t->index[t->depth - 2]);
@@ -274,22 +255,6 @@ void dm_table_destroy(struct dm_table *t
 	kfree(t);
 }
 
-void dm_table_get(struct dm_table *t)
-{
-	atomic_inc(&t->holders);
-}
-EXPORT_SYMBOL(dm_table_get);
-
-void dm_table_put(struct dm_table *t)
-{
-	if (!t)
-		return;
-
-	smp_mb__before_atomic_dec();
-	atomic_dec(&t->holders);
-}
-EXPORT_SYMBOL(dm_table_put);
-
 /*
  * Checks to see if we need to extend highs or targets.
  */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/dm-verity.c linux-libre-3.11-rc7-gnu/drivers/md/dm-verity.c
--- linux-libre-3.10-gnu/drivers/md/dm-verity.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/dm-verity.c	2013-08-25 20:43:22.000000000 -0400
@@ -451,7 +451,7 @@ static void verity_prefetch_io(struct wo
 				goto no_prefetch_cluster;
 
 			if (unlikely(cluster & (cluster - 1)))
-				cluster = 1 << (fls(cluster) - 1);
+				cluster = 1 << __fls(cluster);
 
 			hash_block_start &= ~(sector_t)(cluster - 1);
 			hash_block_end |= cluster - 1;
@@ -695,8 +695,8 @@ static int verity_ctr(struct dm_target *
 		goto bad;
 	}
 
-	if (sscanf(argv[0], "%d%c", &num, &dummy) != 1 ||
-	    num < 0 || num > 1) {
+	if (sscanf(argv[0], "%u%c", &num, &dummy) != 1 ||
+	    num > 1) {
 		ti->error = "Invalid version";
 		r = -EINVAL;
 		goto bad;
@@ -723,7 +723,7 @@ static int verity_ctr(struct dm_target *
 		r = -EINVAL;
 		goto bad;
 	}
-	v->data_dev_block_bits = ffs(num) - 1;
+	v->data_dev_block_bits = __ffs(num);
 
 	if (sscanf(argv[4], "%u%c", &num, &dummy) != 1 ||
 	    !num || (num & (num - 1)) ||
@@ -733,7 +733,7 @@ static int verity_ctr(struct dm_target *
 		r = -EINVAL;
 		goto bad;
 	}
-	v->hash_dev_block_bits = ffs(num) - 1;
+	v->hash_dev_block_bits = __ffs(num);
 
 	if (sscanf(argv[5], "%llu%c", &num_ll, &dummy) != 1 ||
 	    (sector_t)(num_ll << (v->data_dev_block_bits - SECTOR_SHIFT))
@@ -812,7 +812,7 @@ static int verity_ctr(struct dm_target *
 	}
 
 	v->hash_per_block_bits =
-		fls((1 << v->hash_dev_block_bits) / v->digest_size) - 1;
+		__fls((1 << v->hash_dev_block_bits) / v->digest_size);
 
 	v->levels = 0;
 	if (v->data_blocks)
@@ -831,9 +831,8 @@ static int verity_ctr(struct dm_target *
 	for (i = v->levels - 1; i >= 0; i--) {
 		sector_t s;
 		v->hash_level_block[i] = hash_position;
-		s = verity_position_at_level(v, v->data_blocks, i);
-		s = (s >> v->hash_per_block_bits) +
-		    !!(s & ((1 << v->hash_per_block_bits) - 1));
+		s = (v->data_blocks + ((sector_t)1 << ((i + 1) * v->hash_per_block_bits)) - 1)
+					>> ((i + 1) * v->hash_per_block_bits);
 		if (hash_position + s < hash_position) {
 			ti->error = "Hash device offset overflow";
 			r = -E2BIG;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/Kconfig linux-libre-3.11-rc7-gnu/drivers/md/Kconfig
--- linux-libre-3.10-gnu/drivers/md/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -412,4 +412,18 @@ config DM_VERITY
 
 	  If unsure, say N.
 
+config DM_SWITCH
+	tristate "Switch target support (EXPERIMENTAL)"
+	depends on BLK_DEV_DM
+	---help---
+	  This device-mapper target creates a device that supports an arbitrary
+	  mapping of fixed-size regions of I/O across a fixed set of paths.
+	  The path used for any specific region can be switched dynamically
+	  by sending the target a message.
+
+	  To compile this code as a module, choose M here: the module will
+	  be called dm-switch.
+
+	  If unsure, say N.
+
 endif # MD
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/Makefile linux-libre-3.11-rc7-gnu/drivers/md/Makefile
--- linux-libre-3.10-gnu/drivers/md/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -40,6 +40,7 @@ obj-$(CONFIG_DM_FLAKEY)		+= dm-flakey.o
 obj-$(CONFIG_DM_MULTIPATH)	+= dm-multipath.o dm-round-robin.o
 obj-$(CONFIG_DM_MULTIPATH_QL)	+= dm-queue-length.o
 obj-$(CONFIG_DM_MULTIPATH_ST)	+= dm-service-time.o
+obj-$(CONFIG_DM_SWITCH)		+= dm-switch.o
 obj-$(CONFIG_DM_SNAPSHOT)	+= dm-snapshot.o
 obj-$(CONFIG_DM_PERSISTENT_DATA)	+= persistent-data/
 obj-$(CONFIG_DM_MIRROR)		+= dm-mirror.o dm-log.o dm-region-hash.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/md.c linux-libre-3.11-rc7-gnu/drivers/md/md.c
--- linux-libre-3.10-gnu/drivers/md/md.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/md.c	2013-08-25 20:43:22.000000000 -0400
@@ -521,6 +521,7 @@ void mddev_init(struct mddev *mddev)
 	init_waitqueue_head(&mddev->recovery_wait);
 	mddev->reshape_position = MaxSector;
 	mddev->reshape_backwards = 0;
+	mddev->last_sync_action = "none";
 	mddev->resync_min = 0;
 	mddev->resync_max = MaxSector;
 	mddev->level = LEVEL_NONE;
@@ -2867,7 +2868,7 @@ static ssize_t
 offset_store(struct md_rdev *rdev, const char *buf, size_t len)
 {
 	unsigned long long offset;
-	if (strict_strtoull(buf, 10, &offset) < 0)
+	if (kstrtoull(buf, 10, &offset) < 0)
 		return -EINVAL;
 	if (rdev->mddev->pers && rdev->raid_disk >= 0)
 		return -EBUSY;
@@ -2895,7 +2896,7 @@ static ssize_t new_offset_store(struct m
 	unsigned long long new_offset;
 	struct mddev *mddev = rdev->mddev;
 
-	if (strict_strtoull(buf, 10, &new_offset) < 0)
+	if (kstrtoull(buf, 10, &new_offset) < 0)
 		return -EINVAL;
 
 	if (mddev->sync_thread)
@@ -2961,7 +2962,7 @@ static int strict_blocks_to_sectors(cons
 	unsigned long long blocks;
 	sector_t new;
 
-	if (strict_strtoull(buf, 10, &blocks) < 0)
+	if (kstrtoull(buf, 10, &blocks) < 0)
 		return -EINVAL;
 
 	if (blocks & 1ULL << (8 * sizeof(blocks) - 1))
@@ -3069,7 +3070,7 @@ static ssize_t recovery_start_store(stru
 
 	if (cmd_match(buf, "none"))
 		recovery_start = MaxSector;
-	else if (strict_strtoull(buf, 10, &recovery_start))
+	else if (kstrtoull(buf, 10, &recovery_start))
 		return -EINVAL;
 
 	if (rdev->mddev->pers &&
@@ -3497,7 +3498,7 @@ level_store(struct mddev *mddev, const c
 	if (clevel[len-1] == '\n')
 		len--;
 	clevel[len] = 0;
-	if (strict_strtol(clevel, 10, &level))
+	if (kstrtol(clevel, 10, &level))
 		level = LEVEL_NONE;
 
 	if (request_module("md-%s", clevel) != 0)
@@ -4272,6 +4273,17 @@ action_store(struct mddev *mddev, const
 	return len;
 }
 
+static struct md_sysfs_entry md_scan_mode =
+__ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
+
+static ssize_t
+last_sync_action_show(struct mddev *mddev, char *page)
+{
+	return sprintf(page, "%s\n", mddev->last_sync_action);
+}
+
+static struct md_sysfs_entry md_last_scan_mode = __ATTR_RO(last_sync_action);
+
 static ssize_t
 mismatch_cnt_show(struct mddev *mddev, char *page)
 {
@@ -4280,10 +4292,6 @@ mismatch_cnt_show(struct mddev *mddev, c
 		       atomic64_read(&mddev->resync_mismatches));
 }
 
-static struct md_sysfs_entry md_scan_mode =
-__ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
-
-
 static struct md_sysfs_entry md_mismatches = __ATTR_RO(mismatch_cnt);
 
 static ssize_t
@@ -4356,7 +4364,7 @@ sync_force_parallel_store(struct mddev *
 {
 	long n;
 
-	if (strict_strtol(buf, 10, &n))
+	if (kstrtol(buf, 10, &n))
 		return -EINVAL;
 
 	if (n != 0 && n != 1)
@@ -4424,7 +4432,7 @@ static ssize_t
 min_sync_store(struct mddev *mddev, const char *buf, size_t len)
 {
 	unsigned long long min;
-	if (strict_strtoull(buf, 10, &min))
+	if (kstrtoull(buf, 10, &min))
 		return -EINVAL;
 	if (min > mddev->resync_max)
 		return -EINVAL;
@@ -4461,7 +4469,7 @@ max_sync_store(struct mddev *mddev, cons
 		mddev->resync_max = MaxSector;
 	else {
 		unsigned long long max;
-		if (strict_strtoull(buf, 10, &max))
+		if (kstrtoull(buf, 10, &max))
 			return -EINVAL;
 		if (max < mddev->resync_min)
 			return -EINVAL;
@@ -4686,6 +4694,7 @@ static struct attribute *md_default_attr
 
 static struct attribute *md_redundancy_attrs[] = {
 	&md_scan_mode.attr,
+	&md_last_scan_mode.attr,
 	&md_mismatches.attr,
 	&md_sync_min.attr,
 	&md_sync_max.attr,
@@ -6405,6 +6414,12 @@ static int md_ioctl(struct block_device
 		/* need to ensure md_delayed_delete() has completed */
 		flush_workqueue(md_misc_wq);
 
+	if (cmd == HOT_REMOVE_DISK)
+		/* need to ensure recovery thread has run */
+		wait_event_interruptible_timeout(mddev->sb_wait,
+						 !test_bit(MD_RECOVERY_NEEDED,
+							   &mddev->flags),
+						 msecs_to_jiffies(5000));
 	err = mddev_lock(mddev);
 	if (err) {
 		printk(KERN_INFO 
@@ -7323,7 +7338,7 @@ void md_do_sync(struct md_thread *thread
 	sector_t last_check;
 	int skipped = 0;
 	struct md_rdev *rdev;
-	char *desc;
+	char *desc, *action = NULL;
 	struct blk_plug plug;
 
 	/* just incase thread restarts... */
@@ -7333,17 +7348,21 @@ void md_do_sync(struct md_thread *thread
 		return;
 
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
-		if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
+		if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) {
 			desc = "data-check";
-		else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+			action = "check";
+		} else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
 			desc = "requested-resync";
-		else
+			action = "repair";
+		} else
 			desc = "resync";
 	} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
 		desc = "reshape";
 	else
 		desc = "recovery";
 
+	mddev->last_sync_action = action ?: desc;
+
 	/* we overload curr_resync somewhat here.
 	 * 0 == not engaged in resync at all
 	 * 2 == checking that there is no conflict with another sync
@@ -7697,20 +7716,6 @@ static int remove_and_add_spares(struct
 			continue;
 
 		rdev->recovery_offset = 0;
-		if (rdev->saved_raid_disk >= 0 && mddev->in_sync) {
-			spin_lock_irq(&mddev->write_lock);
-			if (mddev->in_sync)
-				/* OK, this device, which is in_sync,
-				 * will definitely be noticed before
-				 * the next write, so recovery isn't
-				 * needed.
-				 */
-				rdev->recovery_offset = mddev->recovery_cp;
-			spin_unlock_irq(&mddev->write_lock);
-		}
-		if (mddev->ro && rdev->recovery_offset != MaxSector)
-			/* not safe to add this disk now */
-			continue;
 		if (mddev->pers->
 		    hot_add_disk(mddev, rdev) == 0) {
 			if (sysfs_link_rdev(mddev, rdev))
@@ -7892,6 +7897,8 @@ void md_check_recovery(struct mddev *mdd
 			md_new_event(mddev);
 		}
 	unlock:
+		wake_up(&mddev->sb_wait);
+
 		if (!mddev->sync_thread) {
 			clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
 			if (test_and_clear_bit(MD_RECOVERY_RECOVER,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/md.h linux-libre-3.11-rc7-gnu/drivers/md/md.h
--- linux-libre-3.10-gnu/drivers/md/md.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/md.h	2013-08-25 20:43:22.000000000 -0400
@@ -268,6 +268,14 @@ struct mddev {
 
 	struct md_thread		*thread;	/* management thread */
 	struct md_thread		*sync_thread;	/* doing resync or reconstruct */
+
+	/* 'last_sync_action' is initialized to "none".  It is set when a
+	 * sync operation (i.e "data-check", "requested-resync", "resync",
+	 * "recovery", or "reshape") is started.  It holds this value even
+	 * when the sync thread is "frozen" (interrupted) or "idle" (stopped
+	 * or finished).  It is overwritten when a new sync operation is begun.
+	 */
+	char				*last_sync_action;
 	sector_t			curr_resync;	/* last block scheduled */
 	/* As resync requests can complete out of order, we cannot easily track
 	 * how much resync has been completed.  So we occasionally pause until
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/raid0.c linux-libre-3.11-rc7-gnu/drivers/md/raid0.c
--- linux-libre-3.10-gnu/drivers/md/raid0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/raid0.c	2013-08-25 20:43:22.000000000 -0400
@@ -597,6 +597,7 @@ static void *raid0_takeover_raid45(struc
 			       mdname(mddev));
 			return ERR_PTR(-EINVAL);
 		}
+		rdev->sectors = mddev->dev_sectors;
 	}
 
 	/* Set new parameters */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/raid10.c linux-libre-3.11-rc7-gnu/drivers/md/raid10.c
--- linux-libre-3.10-gnu/drivers/md/raid10.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/raid10.c	2013-08-25 20:43:22.000000000 -0400
@@ -97,7 +97,7 @@ static int max_queued_requests = 1024;
 
 static void allow_barrier(struct r10conf *conf);
 static void lower_barrier(struct r10conf *conf);
-static int enough(struct r10conf *conf, int ignore);
+static int _enough(struct r10conf *conf, int previous, int ignore);
 static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
 				int *skipped);
 static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio);
@@ -392,11 +392,9 @@ static void raid10_end_read_request(stru
 		 * than fail the last device.  Here we redefine
 		 * "uptodate" to mean "Don't want to retry"
 		 */
-		unsigned long flags;
-		spin_lock_irqsave(&conf->device_lock, flags);
-		if (!enough(conf, rdev->raid_disk))
+		if (!_enough(conf, test_bit(R10BIO_Previous, &r10_bio->state),
+			     rdev->raid_disk))
 			uptodate = 1;
-		spin_unlock_irqrestore(&conf->device_lock, flags);
 	}
 	if (uptodate) {
 		raid_end_bio_io(r10_bio);
@@ -1632,37 +1630,58 @@ static void status(struct seq_file *seq,
  * Don't consider the device numbered 'ignore'
  * as we might be about to remove it.
  */
-static int _enough(struct r10conf *conf, struct geom *geo, int ignore)
+static int _enough(struct r10conf *conf, int previous, int ignore)
 {
 	int first = 0;
+	int has_enough = 0;
+	int disks, ncopies;
+	if (previous) {
+		disks = conf->prev.raid_disks;
+		ncopies = conf->prev.near_copies;
+	} else {
+		disks = conf->geo.raid_disks;
+		ncopies = conf->geo.near_copies;
+	}
 
+	rcu_read_lock();
 	do {
 		int n = conf->copies;
 		int cnt = 0;
 		int this = first;
 		while (n--) {
-			if (conf->mirrors[this].rdev &&
-			    this != ignore)
+			struct md_rdev *rdev;
+			if (this != ignore &&
+			    (rdev = rcu_dereference(conf->mirrors[this].rdev)) &&
+			    test_bit(In_sync, &rdev->flags))
 				cnt++;
-			this = (this+1) % geo->raid_disks;
+			this = (this+1) % disks;
 		}
 		if (cnt == 0)
-			return 0;
-		first = (first + geo->near_copies) % geo->raid_disks;
+			goto out;
+		first = (first + ncopies) % disks;
 	} while (first != 0);
-	return 1;
+	has_enough = 1;
+out:
+	rcu_read_unlock();
+	return has_enough;
 }
 
 static int enough(struct r10conf *conf, int ignore)
 {
-	return _enough(conf, &conf->geo, ignore) &&
-		_enough(conf, &conf->prev, ignore);
+	/* when calling 'enough', both 'prev' and 'geo' must
+	 * be stable.
+	 * This is ensured if ->reconfig_mutex or ->device_lock
+	 * is held.
+	 */
+	return _enough(conf, 0, ignore) &&
+		_enough(conf, 1, ignore);
 }
 
 static void error(struct mddev *mddev, struct md_rdev *rdev)
 {
 	char b[BDEVNAME_SIZE];
 	struct r10conf *conf = mddev->private;
+	unsigned long flags;
 
 	/*
 	 * If it is not operational, then we have already marked it as dead
@@ -1670,18 +1689,18 @@ static void error(struct mddev *mddev, s
 	 * next level up know.
 	 * else mark the drive as failed
 	 */
+	spin_lock_irqsave(&conf->device_lock, flags);
 	if (test_bit(In_sync, &rdev->flags)
-	    && !enough(conf, rdev->raid_disk))
+	    && !enough(conf, rdev->raid_disk)) {
 		/*
 		 * Don't fail the drive, just return an IO error.
 		 */
+		spin_unlock_irqrestore(&conf->device_lock, flags);
 		return;
+	}
 	if (test_and_clear_bit(In_sync, &rdev->flags)) {
-		unsigned long flags;
-		spin_lock_irqsave(&conf->device_lock, flags);
 		mddev->degraded++;
-		spin_unlock_irqrestore(&conf->device_lock, flags);
-		/*
+			/*
 		 * if recovery is running, make sure it aborts.
 		 */
 		set_bit(MD_RECOVERY_INTR, &mddev->recovery);
@@ -1689,6 +1708,7 @@ static void error(struct mddev *mddev, s
 	set_bit(Blocked, &rdev->flags);
 	set_bit(Faulty, &rdev->flags);
 	set_bit(MD_CHANGE_DEVS, &mddev->flags);
+	spin_unlock_irqrestore(&conf->device_lock, flags);
 	printk(KERN_ALERT
 	       "md/raid10:%s: Disk failure on %s, disabling device.\n"
 	       "md/raid10:%s: Operation continuing on %d devices.\n",
@@ -1791,7 +1811,7 @@ static int raid10_add_disk(struct mddev
 		 * very different from resync
 		 */
 		return -EBUSY;
-	if (rdev->saved_raid_disk < 0 && !_enough(conf, &conf->prev, -1))
+	if (rdev->saved_raid_disk < 0 && !_enough(conf, 1, -1))
 		return -EINVAL;
 
 	if (rdev->raid_disk >= 0)
@@ -1819,15 +1839,17 @@ static int raid10_add_disk(struct mddev
 			set_bit(Replacement, &rdev->flags);
 			rdev->raid_disk = mirror;
 			err = 0;
-			disk_stack_limits(mddev->gendisk, rdev->bdev,
-					  rdev->data_offset << 9);
+			if (mddev->gendisk)
+				disk_stack_limits(mddev->gendisk, rdev->bdev,
+						  rdev->data_offset << 9);
 			conf->fullsync = 1;
 			rcu_assign_pointer(p->replacement, rdev);
 			break;
 		}
 
-		disk_stack_limits(mddev->gendisk, rdev->bdev,
-				  rdev->data_offset << 9);
+		if (mddev->gendisk)
+			disk_stack_limits(mddev->gendisk, rdev->bdev,
+					  rdev->data_offset << 9);
 
 		p->head_position = 0;
 		p->recovery_disabled = mddev->recovery_disabled - 1;
@@ -2075,11 +2097,17 @@ static void sync_request_write(struct md
 			 * both 'first' and 'i', so we just compare them.
 			 * All vec entries are PAGE_SIZE;
 			 */
-			for (j = 0; j < vcnt; j++)
+			int sectors = r10_bio->sectors;
+			for (j = 0; j < vcnt; j++) {
+				int len = PAGE_SIZE;
+				if (sectors < (len / 512))
+					len = sectors * 512;
 				if (memcmp(page_address(fbio->bi_io_vec[j].bv_page),
 					   page_address(tbio->bi_io_vec[j].bv_page),
-					   fbio->bi_io_vec[j].bv_len))
+					   len))
 					break;
+				sectors -= len/512;
+			}
 			if (j == vcnt)
 				continue;
 			atomic64_add(r10_bio->sectors, &mddev->resync_mismatches);
@@ -2262,12 +2290,18 @@ static void recovery_request_write(struc
 	d = r10_bio->devs[1].devnum;
 	wbio = r10_bio->devs[1].bio;
 	wbio2 = r10_bio->devs[1].repl_bio;
+	/* Need to test wbio2->bi_end_io before we call
+	 * generic_make_request as if the former is NULL,
+	 * the latter is free to free wbio2.
+	 */
+	if (wbio2 && !wbio2->bi_end_io)
+		wbio2 = NULL;
 	if (wbio->bi_end_io) {
 		atomic_inc(&conf->mirrors[d].rdev->nr_pending);
 		md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio));
 		generic_make_request(wbio);
 	}
-	if (wbio2 && wbio2->bi_end_io) {
+	if (wbio2) {
 		atomic_inc(&conf->mirrors[d].replacement->nr_pending);
 		md_sync_acct(conf->mirrors[d].replacement->bdev,
 			     bio_sectors(wbio2));
@@ -2909,14 +2943,13 @@ static sector_t sync_request(struct mdde
 	 */
 	if (mddev->bitmap == NULL &&
 	    mddev->recovery_cp == MaxSector &&
+	    mddev->reshape_position == MaxSector &&
+	    !test_bit(MD_RECOVERY_SYNC, &mddev->recovery) &&
 	    !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
+	    !test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
 	    conf->fullsync == 0) {
 		*skipped = 1;
-		max_sector = mddev->dev_sectors;
-		if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) ||
-		    test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
-			max_sector = mddev->resync_max_sectors;
-		return max_sector - sector_nr;
+		return mddev->dev_sectors - sector_nr;
 	}
 
  skipped:
@@ -3386,6 +3419,7 @@ static sector_t sync_request(struct mdde
 
 		if (bio->bi_end_io == end_sync_read) {
 			md_sync_acct(bio->bi_bdev, nr_sectors);
+			set_bit(BIO_UPTODATE, &bio->bi_flags);
 			generic_make_request(bio);
 		}
 	}
@@ -3532,7 +3566,7 @@ static struct r10conf *setup_conf(struct
 
 	/* FIXME calc properly */
 	conf->mirrors = kzalloc(sizeof(struct raid10_info)*(mddev->raid_disks +
-							    max(0,mddev->delta_disks)),
+							    max(0,-mddev->delta_disks)),
 				GFP_KERNEL);
 	if (!conf->mirrors)
 		goto out;
@@ -3691,7 +3725,7 @@ static int run(struct mddev *mddev)
 		    conf->geo.far_offset == 0)
 			goto out_free_conf;
 		if (conf->prev.far_copies != 1 &&
-		    conf->geo.far_offset == 0)
+		    conf->prev.far_offset == 0)
 			goto out_free_conf;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/raid1.c linux-libre-3.11-rc7-gnu/drivers/md/raid1.c
--- linux-libre-3.10-gnu/drivers/md/raid1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/raid1.c	2013-08-25 20:43:22.000000000 -0400
@@ -1519,8 +1519,9 @@ static int raid1_add_disk(struct mddev *
 		p = conf->mirrors+mirror;
 		if (!p->rdev) {
 
-			disk_stack_limits(mddev->gendisk, rdev->bdev,
-					  rdev->data_offset << 9);
+			if (mddev->gendisk)
+				disk_stack_limits(mddev->gendisk, rdev->bdev,
+						  rdev->data_offset << 9);
 
 			p->head_position = 0;
 			rdev->raid_disk = mirror;
@@ -1559,7 +1560,7 @@ static int raid1_add_disk(struct mddev *
 		clear_bit(Unmerged, &rdev->flags);
 	}
 	md_integrity_add_rdev(rdev, mddev);
-	if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
+	if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
 		queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
 	print_conf(conf);
 	return err;
@@ -1848,6 +1849,36 @@ static int process_checks(struct r1bio *
 	int i;
 	int vcnt;
 
+	/* Fix variable parts of all bios */
+	vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
+	for (i = 0; i < conf->raid_disks * 2; i++) {
+		int j;
+		int size;
+		struct bio *b = r1_bio->bios[i];
+		if (b->bi_end_io != end_sync_read)
+			continue;
+		/* fixup the bio for reuse */
+		bio_reset(b);
+		b->bi_vcnt = vcnt;
+		b->bi_size = r1_bio->sectors << 9;
+		b->bi_sector = r1_bio->sector +
+			conf->mirrors[i].rdev->data_offset;
+		b->bi_bdev = conf->mirrors[i].rdev->bdev;
+		b->bi_end_io = end_sync_read;
+		b->bi_private = r1_bio;
+
+		size = b->bi_size;
+		for (j = 0; j < vcnt ; j++) {
+			struct bio_vec *bi;
+			bi = &b->bi_io_vec[j];
+			bi->bv_offset = 0;
+			if (size > PAGE_SIZE)
+				bi->bv_len = PAGE_SIZE;
+			else
+				bi->bv_len = size;
+			size -= PAGE_SIZE;
+		}
+	}
 	for (primary = 0; primary < conf->raid_disks * 2; primary++)
 		if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
 		    test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) {
@@ -1856,12 +1887,10 @@ static int process_checks(struct r1bio *
 			break;
 		}
 	r1_bio->read_disk = primary;
-	vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
 	for (i = 0; i < conf->raid_disks * 2; i++) {
 		int j;
 		struct bio *pbio = r1_bio->bios[primary];
 		struct bio *sbio = r1_bio->bios[i];
-		int size;
 
 		if (sbio->bi_end_io != end_sync_read)
 			continue;
@@ -1887,27 +1916,6 @@ static int process_checks(struct r1bio *
 			rdev_dec_pending(conf->mirrors[i].rdev, mddev);
 			continue;
 		}
-		/* fixup the bio for reuse */
-		bio_reset(sbio);
-		sbio->bi_vcnt = vcnt;
-		sbio->bi_size = r1_bio->sectors << 9;
-		sbio->bi_sector = r1_bio->sector +
-			conf->mirrors[i].rdev->data_offset;
-		sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
-		sbio->bi_end_io = end_sync_read;
-		sbio->bi_private = r1_bio;
-
-		size = sbio->bi_size;
-		for (j = 0; j < vcnt ; j++) {
-			struct bio_vec *bi;
-			bi = &sbio->bi_io_vec[j];
-			bi->bv_offset = 0;
-			if (size > PAGE_SIZE)
-				bi->bv_len = PAGE_SIZE;
-			else
-				bi->bv_len = size;
-			size -= PAGE_SIZE;
-		}
 
 		bio_copy_data(sbio, pbio);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/raid5.c linux-libre-3.11-rc7-gnu/drivers/md/raid5.c
--- linux-libre-3.10-gnu/drivers/md/raid5.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/raid5.c	2013-08-25 20:43:22.000000000 -0400
@@ -3462,6 +3462,7 @@ static void handle_stripe(struct stripe_
 		    test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
 			set_bit(STRIPE_SYNCING, &sh->state);
 			clear_bit(STRIPE_INSYNC, &sh->state);
+			clear_bit(STRIPE_REPLACED, &sh->state);
 		}
 		spin_unlock(&sh->stripe_lock);
 	}
@@ -3607,19 +3608,23 @@ static void handle_stripe(struct stripe_
 			handle_parity_checks5(conf, sh, &s, disks);
 	}
 
-	if (s.replacing && s.locked == 0
-	    && !test_bit(STRIPE_INSYNC, &sh->state)) {
+	if ((s.replacing || s.syncing) && s.locked == 0
+	    && !test_bit(STRIPE_COMPUTE_RUN, &sh->state)
+	    && !test_bit(STRIPE_REPLACED, &sh->state)) {
 		/* Write out to replacement devices where possible */
 		for (i = 0; i < conf->raid_disks; i++)
-			if (test_bit(R5_UPTODATE, &sh->dev[i].flags) &&
-			    test_bit(R5_NeedReplace, &sh->dev[i].flags)) {
+			if (test_bit(R5_NeedReplace, &sh->dev[i].flags)) {
+				WARN_ON(!test_bit(R5_UPTODATE, &sh->dev[i].flags));
 				set_bit(R5_WantReplace, &sh->dev[i].flags);
 				set_bit(R5_LOCKED, &sh->dev[i].flags);
 				s.locked++;
 			}
-		set_bit(STRIPE_INSYNC, &sh->state);
+		if (s.replacing)
+			set_bit(STRIPE_INSYNC, &sh->state);
+		set_bit(STRIPE_REPLACED, &sh->state);
 	}
 	if ((s.syncing || s.replacing) && s.locked == 0 &&
+	    !test_bit(STRIPE_COMPUTE_RUN, &sh->state) &&
 	    test_bit(STRIPE_INSYNC, &sh->state)) {
 		md_done_sync(conf->mddev, STRIPE_SECTORS, 1);
 		clear_bit(STRIPE_SYNCING, &sh->state);
@@ -4924,7 +4929,7 @@ raid5_store_stripe_cache_size(struct mdd
 	if (!conf)
 		return -ENODEV;
 
-	if (strict_strtoul(page, 10, &new))
+	if (kstrtoul(page, 10, &new))
 		return -EINVAL;
 	err = raid5_set_cache_size(mddev, new);
 	if (err)
@@ -4957,7 +4962,7 @@ raid5_store_preread_threshold(struct mdd
 	if (!conf)
 		return -ENODEV;
 
-	if (strict_strtoul(page, 10, &new))
+	if (kstrtoul(page, 10, &new))
 		return -EINVAL;
 	if (new > conf->max_nr_stripes)
 		return -EINVAL;
@@ -5914,7 +5919,7 @@ static int check_reshape(struct mddev *m
 		return 0; /* nothing to do */
 	if (has_failed(conf))
 		return -EINVAL;
-	if (mddev->delta_disks < 0) {
+	if (mddev->delta_disks < 0 && mddev->reshape_position == MaxSector) {
 		/* We might be able to shrink, but the devices must
 		 * be made bigger first.
 		 * For raid6, 4 is the minimum size.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/md/raid5.h linux-libre-3.11-rc7-gnu/drivers/md/raid5.h
--- linux-libre-3.10-gnu/drivers/md/raid5.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/md/raid5.h	2013-08-25 20:43:22.000000000 -0400
@@ -306,6 +306,7 @@ enum {
 	STRIPE_SYNC_REQUESTED,
 	STRIPE_SYNCING,
 	STRIPE_INSYNC,
+	STRIPE_REPLACED,
 	STRIPE_PREREAD_ACTIVE,
 	STRIPE_DELAYED,
 	STRIPE_DEGRADED,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/common/saa7146/saa7146_video.c linux-libre-3.11-rc7-gnu/drivers/media/common/saa7146/saa7146_video.c
--- linux-libre-3.10-gnu/drivers/media/common/saa7146/saa7146_video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/common/saa7146/saa7146_video.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,6 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <media/saa7146_vv.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-ctrls.h>
 #include <linux/module.h>
@@ -988,26 +987,6 @@ static int vidioc_streamoff(struct file
 	return err;
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *__fh,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa7146_fh *fh = __fh;
-	struct saa7146_dev *dev = fh->dev;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
-		if (v4l2_chip_match_host(&chip->match))
-			chip->ident = V4L2_IDENT_SAA7146;
-		return 0;
-	}
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-	return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
-			core, g_chip_ident, chip);
-}
-
 const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
 	.vidioc_querycap             = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap     = vidioc_enum_fmt_vid_cap,
@@ -1018,7 +997,6 @@ const struct v4l2_ioctl_ops saa7146_vide
 	.vidioc_g_fmt_vid_overlay    = vidioc_g_fmt_vid_overlay,
 	.vidioc_try_fmt_vid_overlay  = vidioc_try_fmt_vid_overlay,
 	.vidioc_s_fmt_vid_overlay    = vidioc_s_fmt_vid_overlay,
-	.vidioc_g_chip_ident         = vidioc_g_chip_ident,
 
 	.vidioc_overlay 	     = vidioc_overlay,
 	.vidioc_g_fbuf  	     = vidioc_g_fbuf,
@@ -1039,7 +1017,6 @@ const struct v4l2_ioctl_ops saa7146_vide
 const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
 	.vidioc_querycap             = vidioc_querycap,
 	.vidioc_g_fmt_vbi_cap        = vidioc_g_fmt_vbi_cap,
-	.vidioc_g_chip_ident         = vidioc_g_chip_ident,
 
 	.vidioc_reqbufs              = vidioc_reqbufs,
 	.vidioc_querybuf             = vidioc_querybuf,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/common/siano/smscoreapi.c linux-libre-3.11-rc7-gnu/drivers/media/common/siano/smscoreapi.c
--- linux-libre-3.10-gnu/drivers/media/common/siano/smscoreapi.c	2013-07-01 10:34:30.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/common/siano/smscoreapi.c	2013-08-31 17:54:00.000000000 -0400
@@ -1154,7 +1154,7 @@ static int smscore_load_firmware_from_fi
 
 	char *fw_filename = smscore_get_fw_filename(coredev, mode);
 	if (!fw_filename) {
-		sms_info("mode %d not supported on this device", mode);
+		sms_err("mode %d not supported on this device", mode);
 		return -ENOENT;
 	}
 	sms_debug("Firmware name: %s", fw_filename);
@@ -1165,23 +1165,24 @@ static int smscore_load_firmware_from_fi
 
 	rc = reject_firmware(&fw, fw_filename, coredev->device);
 	if (rc < 0) {
-		sms_info("failed to open \"%s\"", fw_filename);
+		sms_err("failed to open firmware file \"%s\"", fw_filename);
 		return rc;
 	}
 	sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size);
 	fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
 			 GFP_KERNEL | GFP_DMA);
 	if (!fw_buf) {
-		sms_info("failed to allocate firmware buffer");
-		return -ENOMEM;
-	}
-	memcpy(fw_buf, fw->data, fw->size);
-	fw_buf_size = fw->size;
+		sms_err("failed to allocate firmware buffer");
+		rc = -ENOMEM;
+	} else {
+		memcpy(fw_buf, fw->data, fw->size);
+		fw_buf_size = fw->size;
 
-	rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
-		smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
-		: loadfirmware_handler(coredev->context, fw_buf,
-		fw_buf_size);
+		rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
+			smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
+			: loadfirmware_handler(coredev->context, fw_buf,
+			fw_buf_size);
+	}
 
 	kfree(fw_buf);
 	release_firmware(fw);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/common/siano/smsdvb-main.c linux-libre-3.11-rc7-gnu/drivers/media/common/siano/smsdvb-main.c
--- linux-libre-3.10-gnu/drivers/media/common/siano/smsdvb-main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/common/siano/smsdvb-main.c	2013-08-25 20:43:22.000000000 -0400
@@ -140,6 +140,7 @@ static void smsdvb_stats_not_ready(struc
 	case DEVICE_MODE_ISDBT:
 	case DEVICE_MODE_ISDBT_BDA:
 		n_layers = 4;
+		break;
 	default:
 		n_layers = 1;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/common/tveeprom.c linux-libre-3.11-rc7-gnu/drivers/media/common/tveeprom.c
--- linux-libre-3.10-gnu/drivers/media/common/tveeprom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/common/tveeprom.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,7 +40,6 @@
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
 MODULE_AUTHOR("John Klar");
@@ -67,13 +66,10 @@ MODULE_PARM_DESC(debug, "Debug level (0-
  * The Hauppauge eeprom uses an 8bit field to determine which
  * tuner formats the tuner supports.
  */
-static struct HAUPPAUGE_TUNER_FMT
-{
+static const struct {
 	int	id;
-	char *name;
-}
-hauppauge_tuner_fmt[] =
-{
+	const char * const name;
+} hauppauge_tuner_fmt[] = {
 	{ V4L2_STD_UNKNOWN,                   " UNKNOWN" },
 	{ V4L2_STD_UNKNOWN,                   " FM" },
 	{ V4L2_STD_B|V4L2_STD_GH,             " PAL(B/G)" },
@@ -88,13 +84,10 @@ hauppauge_tuner_fmt[] =
    supplying this information. Note that many tuners where only used for
    testing and never made it to the outside world. So you will only see
    a subset in actual produced cards. */
-static struct HAUPPAUGE_TUNER
-{
+static const struct {
 	int  id;
-	char *name;
-}
-hauppauge_tuner[] =
-{
+	const char * const name;
+} hauppauge_tuner[] = {
 	/* 0-9 */
 	{ TUNER_ABSENT,			"None" },
 	{ TUNER_ABSENT,			"External" },
@@ -298,69 +291,66 @@ hauppauge_tuner[] =
 	{ TUNER_ABSENT,                 "NXP 18272S"},
 };
 
-/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
+/* Use TVEEPROM_AUDPROC_INTERNAL for those audio 'chips' that are
  * internal to a video chip, i.e. not a separate audio chip. */
-static struct HAUPPAUGE_AUDIOIC
-{
+static const struct {
 	u32   id;
-	char *name;
-}
-audioIC[] =
-{
+	const char * const name;
+} audio_ic[] = {
 	/* 0-4 */
-	{ V4L2_IDENT_NONE,      "None"      },
-	{ V4L2_IDENT_UNKNOWN,   "TEA6300"   },
-	{ V4L2_IDENT_UNKNOWN,   "TEA6320"   },
-	{ V4L2_IDENT_UNKNOWN,   "TDA9850"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3400C"  },
+	{ TVEEPROM_AUDPROC_NONE,  "None"      },
+	{ TVEEPROM_AUDPROC_OTHER, "TEA6300"   },
+	{ TVEEPROM_AUDPROC_OTHER, "TEA6320"   },
+	{ TVEEPROM_AUDPROC_OTHER, "TDA9850"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3400C"  },
 	/* 5-9 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP3410D"  },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3415"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3430"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3438"   },
-	{ V4L2_IDENT_UNKNOWN,   "CS5331"    },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3410D"  },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3415"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3430"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3438"   },
+	{ TVEEPROM_AUDPROC_OTHER, "CS5331"    },
 	/* 10-14 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP3435"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3440"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3445"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3411"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3416"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3435"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3440"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3445"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3411"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3416"   },
 	/* 15-19 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP3425"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3451"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3418"   },
-	{ V4L2_IDENT_UNKNOWN,   "Type 0x12" },
-	{ V4L2_IDENT_UNKNOWN,   "OKI7716"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3425"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3451"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3418"   },
+	{ TVEEPROM_AUDPROC_OTHER, "Type 0x12" },
+	{ TVEEPROM_AUDPROC_OTHER, "OKI7716"   },
 	/* 20-24 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP4410"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4420"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4440"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4450"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4408"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4410"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4420"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4440"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4450"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4408"   },
 	/* 25-29 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP4418"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4428"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4448"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4458"   },
-	{ V4L2_IDENT_MSPX4XX,   "Type 0x1d" },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4418"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4428"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4448"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4458"   },
+	{ TVEEPROM_AUDPROC_MSP,   "Type 0x1d" },
 	/* 30-34 */
-	{ V4L2_IDENT_AMBIGUOUS, "CX880"     },
-	{ V4L2_IDENT_AMBIGUOUS, "CX881"     },
-	{ V4L2_IDENT_AMBIGUOUS, "CX883"     },
-	{ V4L2_IDENT_AMBIGUOUS, "CX882"     },
-	{ V4L2_IDENT_AMBIGUOUS, "CX25840"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX880"     },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX881"     },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX883"     },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX882"     },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX25840"   },
 	/* 35-39 */
-	{ V4L2_IDENT_AMBIGUOUS, "CX25841"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX25842"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX25843"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX23418"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX23885"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX25841"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX25842"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX25843"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX23418"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX23885"   },
 	/* 40-44 */
-	{ V4L2_IDENT_AMBIGUOUS, "CX23888"   },
-	{ V4L2_IDENT_AMBIGUOUS, "SAA7131"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX23887"   },
-	{ V4L2_IDENT_AMBIGUOUS, "SAA7164"   },
-	{ V4L2_IDENT_AMBIGUOUS, "AU8522"    },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX23888"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "SAA7131"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX23887"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "SAA7164"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "AU8522"    },
 };
 
 /* This list is supplied by Hauppauge. Thanks! */
@@ -453,11 +443,11 @@ void tveeprom_hauppauge_analog(struct i2
 	int i, j, len, done, beenhere, tag, start;
 
 	int tuner1 = 0, t_format1 = 0, audioic = -1;
-	char *t_name1 = NULL;
+	const char *t_name1 = NULL;
 	const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
 
 	int tuner2 = 0, t_format2 = 0;
-	char *t_name2 = NULL;
+	const char *t_name2 = NULL;
 	const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
 
 	memset(tvee, 0, sizeof(*tvee));
@@ -545,10 +535,10 @@ void tveeprom_hauppauge_analog(struct i2
 			to indicate 4052 mux was removed in favor of using MSP
 			inputs directly. */
 			audioic = eeprom_data[i+2] & 0x7f;
-			if (audioic < ARRAY_SIZE(audioIC))
-				tvee->audio_processor = audioIC[audioic].id;
+			if (audioic < ARRAY_SIZE(audio_ic))
+				tvee->audio_processor = audio_ic[audioic].id;
 			else
-				tvee->audio_processor = V4L2_IDENT_UNKNOWN;
+				tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
 			break;
 
 		/* case 0x03: tag 'EEInfo' */
@@ -578,10 +568,10 @@ void tveeprom_hauppauge_analog(struct i2
 			to indicate 4052 mux was removed in favor of using MSP
 			inputs directly. */
 			audioic = eeprom_data[i+1] & 0x7f;
-			if (audioic < ARRAY_SIZE(audioIC))
-				tvee->audio_processor = audioIC[audioic].id;
+			if (audioic < ARRAY_SIZE(audio_ic))
+				tvee->audio_processor = audio_ic[audioic].id;
 			else
-				tvee->audio_processor = V4L2_IDENT_UNKNOWN;
+				tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
 
 			break;
 
@@ -726,11 +716,11 @@ void tveeprom_hauppauge_analog(struct i2
 			t_fmt_name2[6], t_fmt_name2[7], t_format2);
 	if (audioic < 0) {
 		tveeprom_info("audio processor is unknown (no idx)\n");
-		tvee->audio_processor = V4L2_IDENT_UNKNOWN;
+		tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
 	} else {
-		if (audioic < ARRAY_SIZE(audioIC))
+		if (audioic < ARRAY_SIZE(audio_ic))
 			tveeprom_info("audio processor is %s (idx %d)\n",
-					audioIC[audioic].name, audioic);
+					audio_ic[audioic].name, audioic);
 		else
 			tveeprom_info("audio processor is unknown (idx %d)\n",
 								audioic);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-core/dmxdev.c linux-libre-3.11-rc7-gnu/drivers/media/dvb-core/dmxdev.c
--- linux-libre-3.10-gnu/drivers/media/dvb-core/dmxdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-core/dmxdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -377,10 +377,8 @@ static int dvb_dmxdev_section_callback(c
 		ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
 					      buffer2_len);
 	}
-	if (ret < 0) {
-		dvb_ringbuffer_flush(&dmxdevfilter->buffer);
+	if (ret < 0)
 		dmxdevfilter->buffer.error = ret;
-	}
 	if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
 		dmxdevfilter->state = DMXDEV_STATE_DONE;
 	spin_unlock(&dmxdevfilter->dev->lock);
@@ -416,10 +414,8 @@ static int dvb_dmxdev_ts_callback(const
 	ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
 	if (ret == buffer1_len)
 		ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
-	if (ret < 0) {
-		dvb_ringbuffer_flush(buffer);
+	if (ret < 0)
 		buffer->error = ret;
-	}
 	spin_unlock(&dmxdevfilter->dev->lock);
 	wake_up(&buffer->queue);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-core/dvb-usb-ids.h linux-libre-3.11-rc7-gnu/drivers/media/dvb-core/dvb-usb-ids.h
--- linux-libre-3.10-gnu/drivers/media/dvb-core/dvb-usb-ids.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-core/dvb-usb-ids.h	2013-08-25 20:43:22.000000000 -0400
@@ -367,4 +367,6 @@
 #define USB_PID_TECHNISAT_USB2_HDCI_V2			0x0002
 #define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2		0x0004
 #define USB_PID_TECHNISAT_USB2_DVB_S2			0x0500
+#define USB_PID_CPYTO_REDI_PC50A			0xa803
+#define USB_PID_CTVDIGDUAL_V2				0xe410
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-frontends/au8522_decoder.c linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/au8522_decoder.c
--- linux-libre-3.10-gnu/drivers/media/dvb-frontends/au8522_decoder.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/au8522_decoder.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,7 +35,6 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-device.h>
 #include "au8522.h"
 #include "au8522_priv.h"
@@ -524,13 +523,8 @@ static int au8522_s_ctrl(struct v4l2_ctr
 static int au8522_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct au8522_state *state = to_state(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = au8522_readreg(state, reg->reg & 0xffff);
 	return 0;
 }
@@ -538,13 +532,8 @@ static int au8522_g_register(struct v4l2
 static int au8522_s_register(struct v4l2_subdev *sd,
 			     const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct au8522_state *state = to_state(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	au8522_writereg(state, reg->reg, reg->val & 0xff);
 	return 0;
 }
@@ -636,20 +625,10 @@ static int au8522_g_tuner(struct v4l2_su
 	return 0;
 }
 
-static int au8522_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *chip)
-{
-	struct au8522_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops au8522_core_ops = {
 	.log_status = v4l2_ctrl_subdev_log_status,
-	.g_chip_ident = au8522_g_chip_ident,
 	.reset = au8522_reset,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = au8522_g_register,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-frontends/dib8000.c linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/dib8000.c
--- linux-libre-3.10-gnu/drivers/media/dvb-frontends/dib8000.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/dib8000.c	2013-08-25 20:43:22.000000000 -0400
@@ -3406,7 +3406,7 @@ static int dib8000_set_frontend(struct d
 {
 	struct dib8000_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
-	int l, i, active, time, ret, time_slave = FE_CALLBACK_TIME_NEVER;
+	int l, i, active, time, time_slave = FE_CALLBACK_TIME_NEVER;
 	u8 exit_condition, index_frontend;
 	u32 delay, callback_time;
 
@@ -3553,7 +3553,7 @@ static int dib8000_set_frontend(struct d
 		}
 	}
 
-	return ret;
+	return 0;
 }
 
 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-frontends/drxk.h linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/drxk.h
--- linux-libre-3.10-gnu/drivers/media/dvb-frontends/drxk.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/drxk.h	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
 /**
  * struct drxk_config - Configure the initial parameters for DRX-K
  *
- * @adr:		I2C Address of the DRX-K
+ * @adr:		I2C address of the DRX-K
  * @parallel_ts:	True means that the device uses parallel TS,
  * 			Serial otherwise.
  * @dynamic_clk:	True means that the clock will be dynamically
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-frontends/drxk_hard.c linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/drxk_hard.c
--- linux-libre-3.10-gnu/drivers/media/dvb-frontends/drxk_hard.c	2013-07-01 10:34:25.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/drxk_hard.c	2013-08-31 17:53:55.000000000 -0400
@@ -21,6 +21,8 @@
  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -34,35 +36,36 @@
 #include "dvb_frontend.h"
 #include "drxk.h"
 #include "drxk_hard.h"
+#include "dvb_math.h"
 
-static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
-static int PowerDownQAM(struct drxk_state *state);
-static int SetDVBTStandard(struct drxk_state *state,
-			   enum OperationMode oMode);
-static int SetQAMStandard(struct drxk_state *state,
-			  enum OperationMode oMode);
-static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
-		  s32 tunerFreqOffset);
-static int SetDVBTStandard(struct drxk_state *state,
-			   enum OperationMode oMode);
-static int DVBTStart(struct drxk_state *state);
-static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
-		   s32 tunerFreqOffset);
-static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
-static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
-static int SwitchAntennaToQAM(struct drxk_state *state);
-static int SwitchAntennaToDVBT(struct drxk_state *state);
+static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
+static int power_down_qam(struct drxk_state *state);
+static int set_dvbt_standard(struct drxk_state *state,
+			   enum operation_mode o_mode);
+static int set_qam_standard(struct drxk_state *state,
+			  enum operation_mode o_mode);
+static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
+		  s32 tuner_freq_offset);
+static int set_dvbt_standard(struct drxk_state *state,
+			   enum operation_mode o_mode);
+static int dvbt_start(struct drxk_state *state);
+static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
+		   s32 tuner_freq_offset);
+static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
+static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
+static int switch_antenna_to_qam(struct drxk_state *state);
+static int switch_antenna_to_dvbt(struct drxk_state *state);
 
-static bool IsDVBT(struct drxk_state *state)
+static bool is_dvbt(struct drxk_state *state)
 {
-	return state->m_OperationMode == OM_DVBT;
+	return state->m_operation_mode == OM_DVBT;
 }
 
-static bool IsQAM(struct drxk_state *state)
+static bool is_qam(struct drxk_state *state)
 {
-	return state->m_OperationMode == OM_QAM_ITU_A ||
-	    state->m_OperationMode == OM_QAM_ITU_B ||
-	    state->m_OperationMode == OM_QAM_ITU_C;
+	return state->m_operation_mode == OM_QAM_ITU_A ||
+	    state->m_operation_mode == OM_QAM_ITU_B ||
+	    state->m_operation_mode == OM_QAM_ITU_C;
 }
 
 #define NOA1ROM 0
@@ -165,7 +168,7 @@ MODULE_PARM_DESC(debug, "enable debug me
 
 #define dprintk(level, fmt, arg...) do {			\
 if (debug >= level)						\
-	printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg);	\
+	pr_debug(fmt, ##arg);					\
 } while (0)
 
 
@@ -186,8 +189,10 @@ static inline u32 Frac28a(u32 a, u32 c)
 	u32 R0 = 0;
 
 	R0 = (a % c) << 4;	/* 32-28 == 4 shifts possible at max */
-	Q1 = a / c;		/* integer part, only the 4 least significant bits
-				   will be visible in the result */
+	Q1 = a / c;		/*
+				 * integer part, only the 4 least significant
+				 * bits will be visible in the result
+				 */
 
 	/* division using radix 16, 7 nibbles in the result */
 	for (i = 0; i < 7; i++) {
@@ -201,98 +206,9 @@ static inline u32 Frac28a(u32 a, u32 c)
 	return Q1;
 }
 
-static u32 Log10Times100(u32 x)
+static inline u32 log10times100(u32 value)
 {
-	static const u8 scale = 15;
-	static const u8 indexWidth = 5;
-	u8 i = 0;
-	u32 y = 0;
-	u32 d = 0;
-	u32 k = 0;
-	u32 r = 0;
-	/*
-	   log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
-	   0 <= n < ((1<<INDEXWIDTH)+1)
-	 */
-
-	static const u32 log2lut[] = {
-		0,		/* 0.000000 */
-		290941,		/* 290941.300628 */
-		573196,		/* 573196.476418 */
-		847269,		/* 847269.179851 */
-		1113620,	/* 1113620.489452 */
-		1372674,	/* 1372673.576986 */
-		1624818,	/* 1624817.752104 */
-		1870412,	/* 1870411.981536 */
-		2109788,	/* 2109787.962654 */
-		2343253,	/* 2343252.817465 */
-		2571091,	/* 2571091.461923 */
-		2793569,	/* 2793568.696416 */
-		3010931,	/* 3010931.055901 */
-		3223408,	/* 3223408.452106 */
-		3431216,	/* 3431215.635215 */
-		3634553,	/* 3634553.498355 */
-		3833610,	/* 3833610.244726 */
-		4028562,	/* 4028562.434393 */
-		4219576,	/* 4219575.925308 */
-		4406807,	/* 4406806.721144 */
-		4590402,	/* 4590401.736809 */
-		4770499,	/* 4770499.491025 */
-		4947231,	/* 4947230.734179 */
-		5120719,	/* 5120719.018555 */
-		5291081,	/* 5291081.217197 */
-		5458428,	/* 5458427.996830 */
-		5622864,	/* 5622864.249668 */
-		5784489,	/* 5784489.488298 */
-		5943398,	/* 5943398.207380 */
-		6099680,	/* 6099680.215452 */
-		6253421,	/* 6253420.939751 */
-		6404702,	/* 6404701.706649 */
-		6553600,	/* 6553600.000000 */
-	};
-
-
-	if (x == 0)
-		return 0;
-
-	/* Scale x (normalize) */
-	/* computing y in log(x/y) = log(x) - log(y) */
-	if ((x & ((0xffffffff) << (scale + 1))) == 0) {
-		for (k = scale; k > 0; k--) {
-			if (x & (((u32) 1) << scale))
-				break;
-			x <<= 1;
-		}
-	} else {
-		for (k = scale; k < 31; k++) {
-			if ((x & (((u32) (-1)) << (scale + 1))) == 0)
-				break;
-			x >>= 1;
-		}
-	}
-	/*
-	   Now x has binary point between bit[scale] and bit[scale-1]
-	   and 1.0 <= x < 2.0 */
-
-	/* correction for divison: log(x) = log(x/y)+log(y) */
-	y = k * ((((u32) 1) << scale) * 200);
-
-	/* remove integer part */
-	x &= ((((u32) 1) << scale) - 1);
-	/* get index */
-	i = (u8) (x >> (scale - indexWidth));
-	/* compute delta (x - a) */
-	d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
-	/* compute log, multiplication (d* (..)) must be within range ! */
-	y += log2lut[i] +
-	    ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
-	/* Conver to log10() */
-	y /= 108853;		/* (log2(10) << scale) */
-	r = (y >> 1);
-	/* rounding */
-	if (y & ((u32) 1))
-		r++;
-	return r;
+	return (100L * intlog10(value)) >> 24;
 }
 
 /****************************************************************************/
@@ -344,15 +260,15 @@ static int i2c_write(struct drxk_state *
 	if (debug > 2) {
 		int i;
 		for (i = 0; i < len; i++)
-			printk(KERN_CONT " %02x", data[i]);
-		printk(KERN_CONT "\n");
+			pr_cont(" %02x", data[i]);
+		pr_cont("\n");
 	}
 	status = drxk_i2c_transfer(state, &msg, 1);
 	if (status >= 0 && status != 1)
 		status = -EIO;
 
 	if (status < 0)
-		printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
+		pr_err("i2c write error at addr 0x%02x\n", adr);
 
 	return status;
 }
@@ -371,22 +287,22 @@ static int i2c_read(struct drxk_state *s
 	status = drxk_i2c_transfer(state, msgs, 2);
 	if (status != 2) {
 		if (debug > 2)
-			printk(KERN_CONT ": ERROR!\n");
+			pr_cont(": ERROR!\n");
 		if (status >= 0)
 			status = -EIO;
 
-		printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
+		pr_err("i2c read error at addr 0x%02x\n", adr);
 		return status;
 	}
 	if (debug > 2) {
 		int i;
 		dprintk(2, ": read from");
 		for (i = 0; i < len; i++)
-			printk(KERN_CONT " %02x", msg[i]);
-		printk(KERN_CONT ", value = ");
+			pr_cont(" %02x", msg[i]);
+		pr_cont(", value = ");
 		for (i = 0; i < alen; i++)
-			printk(KERN_CONT " %02x", answ[i]);
-		printk(KERN_CONT "\n");
+			pr_cont(" %02x", answ[i]);
+		pr_cont("\n");
 	}
 	return 0;
 }
@@ -520,55 +436,55 @@ static int write32(struct drxk_state *st
 	return write32_flags(state, reg, data, 0);
 }
 
-static int write_block(struct drxk_state *state, u32 Address,
-		      const int BlockSize, const u8 pBlock[])
+static int write_block(struct drxk_state *state, u32 address,
+		      const int block_size, const u8 p_block[])
 {
-	int status = 0, BlkSize = BlockSize;
-	u8 Flags = 0;
+	int status = 0, blk_size = block_size;
+	u8 flags = 0;
 
 	if (state->single_master)
-		Flags |= 0xC0;
+		flags |= 0xC0;
 
-	while (BlkSize > 0) {
-		int Chunk = BlkSize > state->m_ChunkSize ?
-		    state->m_ChunkSize : BlkSize;
-		u8 *AdrBuf = &state->Chunk[0];
-		u32 AdrLength = 0;
+	while (blk_size > 0) {
+		int chunk = blk_size > state->m_chunk_size ?
+		    state->m_chunk_size : blk_size;
+		u8 *adr_buf = &state->chunk[0];
+		u32 adr_length = 0;
 
-		if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
-			AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
-			AdrBuf[1] = ((Address >> 16) & 0xFF);
-			AdrBuf[2] = ((Address >> 24) & 0xFF);
-			AdrBuf[3] = ((Address >> 7) & 0xFF);
-			AdrBuf[2] |= Flags;
-			AdrLength = 4;
-			if (Chunk == state->m_ChunkSize)
-				Chunk -= 2;
+		if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
+			adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
+			adr_buf[1] = ((address >> 16) & 0xFF);
+			adr_buf[2] = ((address >> 24) & 0xFF);
+			adr_buf[3] = ((address >> 7) & 0xFF);
+			adr_buf[2] |= flags;
+			adr_length = 4;
+			if (chunk == state->m_chunk_size)
+				chunk -= 2;
 		} else {
-			AdrBuf[0] = ((Address << 1) & 0xFF);
-			AdrBuf[1] = (((Address >> 16) & 0x0F) |
-				     ((Address >> 18) & 0xF0));
-			AdrLength = 2;
+			adr_buf[0] = ((address << 1) & 0xFF);
+			adr_buf[1] = (((address >> 16) & 0x0F) |
+				     ((address >> 18) & 0xF0));
+			adr_length = 2;
 		}
-		memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
-		dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
+		memcpy(&state->chunk[adr_length], p_block, chunk);
+		dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
 		if (debug > 1) {
 			int i;
-			if (pBlock)
-				for (i = 0; i < Chunk; i++)
-					printk(KERN_CONT " %02x", pBlock[i]);
-			printk(KERN_CONT "\n");
+			if (p_block)
+				for (i = 0; i < chunk; i++)
+					pr_cont(" %02x", p_block[i]);
+			pr_cont("\n");
 		}
 		status = i2c_write(state, state->demod_address,
-				   &state->Chunk[0], Chunk + AdrLength);
+				   &state->chunk[0], chunk + adr_length);
 		if (status < 0) {
-			printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
-			       __func__, Address);
+			pr_err("%s: i2c write error at addr 0x%02x\n",
+			       __func__, address);
 			break;
 		}
-		pBlock += Chunk;
-		Address += (Chunk >> 1);
-		BlkSize -= Chunk;
+		p_block += chunk;
+		address += (chunk >> 1);
+		blk_size -= chunk;
 	}
 	return status;
 }
@@ -577,11 +493,11 @@ static int write_block(struct drxk_state
 #define DRXK_MAX_RETRIES_POWERUP 20
 #endif
 
-static int PowerUpDevice(struct drxk_state *state)
+static int power_up_device(struct drxk_state *state)
 {
 	int status;
 	u8 data = 0;
-	u16 retryCount = 0;
+	u16 retry_count = 0;
 
 	dprintk(1, "\n");
 
@@ -591,15 +507,15 @@ static int PowerUpDevice(struct drxk_sta
 			data = 0;
 			status = i2c_write(state, state->demod_address,
 					   &data, 1);
-			msleep(10);
-			retryCount++;
+			usleep_range(10000, 11000);
+			retry_count++;
 			if (status < 0)
 				continue;
 			status = i2c_read1(state, state->demod_address,
 					   &data);
 		} while (status < 0 &&
-			 (retryCount < DRXK_MAX_RETRIES_POWERUP));
-		if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
+			 (retry_count < DRXK_MAX_RETRIES_POWERUP));
+		if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
 			goto error;
 	}
 
@@ -615,11 +531,11 @@ static int PowerUpDevice(struct drxk_sta
 	if (status < 0)
 		goto error;
 
-	state->m_currentPowerMode = DRX_POWER_UP;
+	state->m_current_power_mode = DRX_POWER_UP;
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -631,106 +547,106 @@ static int init_state(struct drxk_state
 	 * FIXME: most (all?) of the values bellow should be moved into
 	 * struct drxk_config, as they are probably board-specific
 	 */
-	u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
-	u32 ulVSBIfAgcOutputLevel = 0;
-	u32 ulVSBIfAgcMinLevel = 0;
-	u32 ulVSBIfAgcMaxLevel = 0x7FFF;
-	u32 ulVSBIfAgcSpeed = 3;
+	u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
+	u32 ul_vsb_if_agc_output_level = 0;
+	u32 ul_vsb_if_agc_min_level = 0;
+	u32 ul_vsb_if_agc_max_level = 0x7FFF;
+	u32 ul_vsb_if_agc_speed = 3;
 
-	u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
-	u32 ulVSBRfAgcOutputLevel = 0;
-	u32 ulVSBRfAgcMinLevel = 0;
-	u32 ulVSBRfAgcMaxLevel = 0x7FFF;
-	u32 ulVSBRfAgcSpeed = 3;
-	u32 ulVSBRfAgcTop = 9500;
-	u32 ulVSBRfAgcCutOffCurrent = 4000;
+	u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
+	u32 ul_vsb_rf_agc_output_level = 0;
+	u32 ul_vsb_rf_agc_min_level = 0;
+	u32 ul_vsb_rf_agc_max_level = 0x7FFF;
+	u32 ul_vsb_rf_agc_speed = 3;
+	u32 ul_vsb_rf_agc_top = 9500;
+	u32 ul_vsb_rf_agc_cut_off_current = 4000;
 
-	u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
-	u32 ulATVIfAgcOutputLevel = 0;
-	u32 ulATVIfAgcMinLevel = 0;
-	u32 ulATVIfAgcMaxLevel = 0;
-	u32 ulATVIfAgcSpeed = 3;
+	u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
+	u32 ul_atv_if_agc_output_level = 0;
+	u32 ul_atv_if_agc_min_level = 0;
+	u32 ul_atv_if_agc_max_level = 0;
+	u32 ul_atv_if_agc_speed = 3;
 
-	u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
-	u32 ulATVRfAgcOutputLevel = 0;
-	u32 ulATVRfAgcMinLevel = 0;
-	u32 ulATVRfAgcMaxLevel = 0;
-	u32 ulATVRfAgcTop = 9500;
-	u32 ulATVRfAgcCutOffCurrent = 4000;
-	u32 ulATVRfAgcSpeed = 3;
+	u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
+	u32 ul_atv_rf_agc_output_level = 0;
+	u32 ul_atv_rf_agc_min_level = 0;
+	u32 ul_atv_rf_agc_max_level = 0;
+	u32 ul_atv_rf_agc_top = 9500;
+	u32 ul_atv_rf_agc_cut_off_current = 4000;
+	u32 ul_atv_rf_agc_speed = 3;
 
 	u32 ulQual83 = DEFAULT_MER_83;
 	u32 ulQual93 = DEFAULT_MER_93;
 
-	u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
-	u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
+	u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
+	u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
 
 	/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
 	/* io_pad_cfg_mode output mode is drive always */
 	/* io_pad_cfg_drive is set to power 2 (23 mA) */
-	u32 ulGPIOCfg = 0x0113;
-	u32 ulInvertTSClock = 0;
-	u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
-	u32 ulDVBTBitrate = 50000000;
-	u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
+	u32 ul_gpio_cfg = 0x0113;
+	u32 ul_invert_ts_clock = 0;
+	u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
+	u32 ul_dvbt_bitrate = 50000000;
+	u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
 
-	u32 ulInsertRSByte = 0;
+	u32 ul_insert_rs_byte = 0;
 
-	u32 ulRfMirror = 1;
-	u32 ulPowerDown = 0;
+	u32 ul_rf_mirror = 1;
+	u32 ul_power_down = 0;
 
 	dprintk(1, "\n");
 
-	state->m_hasLNA = false;
-	state->m_hasDVBT = false;
-	state->m_hasDVBC = false;
-	state->m_hasATV = false;
-	state->m_hasOOB = false;
-	state->m_hasAudio = false;
+	state->m_has_lna = false;
+	state->m_has_dvbt = false;
+	state->m_has_dvbc = false;
+	state->m_has_atv = false;
+	state->m_has_oob = false;
+	state->m_has_audio = false;
 
-	if (!state->m_ChunkSize)
-		state->m_ChunkSize = 124;
+	if (!state->m_chunk_size)
+		state->m_chunk_size = 124;
 
-	state->m_oscClockFreq = 0;
-	state->m_smartAntInverted = false;
-	state->m_bPDownOpenBridge = false;
+	state->m_osc_clock_freq = 0;
+	state->m_smart_ant_inverted = false;
+	state->m_b_p_down_open_bridge = false;
 
 	/* real system clock frequency in kHz */
-	state->m_sysClockFreq = 151875;
+	state->m_sys_clock_freq = 151875;
 	/* Timing div, 250ns/Psys */
 	/* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
-	state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
+	state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
 				   HI_I2C_DELAY) / 1000;
 	/* Clipping */
-	if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
-		state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
-	state->m_HICfgWakeUpKey = (state->demod_address << 1);
+	if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
+		state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
+	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
 	/* port/bridge/power down ctrl */
-	state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
+	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
 
-	state->m_bPowerDown = (ulPowerDown != 0);
+	state->m_b_power_down = (ul_power_down != 0);
 
-	state->m_DRXK_A3_PATCH_CODE = false;
+	state->m_drxk_a3_patch_code = false;
 
 	/* Init AGC and PGA parameters */
 	/* VSB IF */
-	state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
-	state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
-	state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
-	state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
-	state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
-	state->m_vsbPgaCfg = 140;
+	state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode;
+	state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level;
+	state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level;
+	state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level;
+	state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed;
+	state->m_vsb_pga_cfg = 140;
 
 	/* VSB RF */
-	state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
-	state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
-	state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
-	state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
-	state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
-	state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
-	state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
-	state->m_vsbPreSawCfg.reference = 0x07;
-	state->m_vsbPreSawCfg.usePreSaw = true;
+	state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode;
+	state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level;
+	state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level;
+	state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level;
+	state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed;
+	state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top;
+	state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current;
+	state->m_vsb_pre_saw_cfg.reference = 0x07;
+	state->m_vsb_pre_saw_cfg.use_pre_saw = true;
 
 	state->m_Quality83percent = DEFAULT_MER_83;
 	state->m_Quality93percent = DEFAULT_MER_93;
@@ -740,127 +656,127 @@ static int init_state(struct drxk_state
 	}
 
 	/* ATV IF */
-	state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
-	state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
-	state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
-	state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
-	state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
+	state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode;
+	state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level;
+	state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level;
+	state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level;
+	state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed;
 
 	/* ATV RF */
-	state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
-	state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
-	state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
-	state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
-	state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
-	state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
-	state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
-	state->m_atvPreSawCfg.reference = 0x04;
-	state->m_atvPreSawCfg.usePreSaw = true;
+	state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode;
+	state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level;
+	state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level;
+	state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level;
+	state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed;
+	state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top;
+	state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current;
+	state->m_atv_pre_saw_cfg.reference = 0x04;
+	state->m_atv_pre_saw_cfg.use_pre_saw = true;
 
 
 	/* DVBT RF */
-	state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
-	state->m_dvbtRfAgcCfg.outputLevel = 0;
-	state->m_dvbtRfAgcCfg.minOutputLevel = 0;
-	state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
-	state->m_dvbtRfAgcCfg.top = 0x2100;
-	state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
-	state->m_dvbtRfAgcCfg.speed = 1;
+	state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
+	state->m_dvbt_rf_agc_cfg.output_level = 0;
+	state->m_dvbt_rf_agc_cfg.min_output_level = 0;
+	state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
+	state->m_dvbt_rf_agc_cfg.top = 0x2100;
+	state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
+	state->m_dvbt_rf_agc_cfg.speed = 1;
 
 
 	/* DVBT IF */
-	state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
-	state->m_dvbtIfAgcCfg.outputLevel = 0;
-	state->m_dvbtIfAgcCfg.minOutputLevel = 0;
-	state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
-	state->m_dvbtIfAgcCfg.top = 13424;
-	state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
-	state->m_dvbtIfAgcCfg.speed = 3;
-	state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
-	state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
+	state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
+	state->m_dvbt_if_agc_cfg.output_level = 0;
+	state->m_dvbt_if_agc_cfg.min_output_level = 0;
+	state->m_dvbt_if_agc_cfg.max_output_level = 9000;
+	state->m_dvbt_if_agc_cfg.top = 13424;
+	state->m_dvbt_if_agc_cfg.cut_off_current = 0;
+	state->m_dvbt_if_agc_cfg.speed = 3;
+	state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
+	state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
 	/* state->m_dvbtPgaCfg = 140; */
 
-	state->m_dvbtPreSawCfg.reference = 4;
-	state->m_dvbtPreSawCfg.usePreSaw = false;
+	state->m_dvbt_pre_saw_cfg.reference = 4;
+	state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
 
 	/* QAM RF */
-	state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
-	state->m_qamRfAgcCfg.outputLevel = 0;
-	state->m_qamRfAgcCfg.minOutputLevel = 6023;
-	state->m_qamRfAgcCfg.maxOutputLevel = 27000;
-	state->m_qamRfAgcCfg.top = 0x2380;
-	state->m_qamRfAgcCfg.cutOffCurrent = 4000;
-	state->m_qamRfAgcCfg.speed = 3;
+	state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
+	state->m_qam_rf_agc_cfg.output_level = 0;
+	state->m_qam_rf_agc_cfg.min_output_level = 6023;
+	state->m_qam_rf_agc_cfg.max_output_level = 27000;
+	state->m_qam_rf_agc_cfg.top = 0x2380;
+	state->m_qam_rf_agc_cfg.cut_off_current = 4000;
+	state->m_qam_rf_agc_cfg.speed = 3;
 
 	/* QAM IF */
-	state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
-	state->m_qamIfAgcCfg.outputLevel = 0;
-	state->m_qamIfAgcCfg.minOutputLevel = 0;
-	state->m_qamIfAgcCfg.maxOutputLevel = 9000;
-	state->m_qamIfAgcCfg.top = 0x0511;
-	state->m_qamIfAgcCfg.cutOffCurrent = 0;
-	state->m_qamIfAgcCfg.speed = 3;
-	state->m_qamIfAgcCfg.IngainTgtMax = 5119;
-	state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
+	state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
+	state->m_qam_if_agc_cfg.output_level = 0;
+	state->m_qam_if_agc_cfg.min_output_level = 0;
+	state->m_qam_if_agc_cfg.max_output_level = 9000;
+	state->m_qam_if_agc_cfg.top = 0x0511;
+	state->m_qam_if_agc_cfg.cut_off_current = 0;
+	state->m_qam_if_agc_cfg.speed = 3;
+	state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
+	state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
 
-	state->m_qamPgaCfg = 140;
-	state->m_qamPreSawCfg.reference = 4;
-	state->m_qamPreSawCfg.usePreSaw = false;
+	state->m_qam_pga_cfg = 140;
+	state->m_qam_pre_saw_cfg.reference = 4;
+	state->m_qam_pre_saw_cfg.use_pre_saw = false;
 
-	state->m_OperationMode = OM_NONE;
-	state->m_DrxkState = DRXK_UNINITIALIZED;
+	state->m_operation_mode = OM_NONE;
+	state->m_drxk_state = DRXK_UNINITIALIZED;
 
 	/* MPEG output configuration */
-	state->m_enableMPEGOutput = true;	/* If TRUE; enable MPEG ouput */
-	state->m_insertRSByte = false;	/* If TRUE; insert RS byte */
-	state->m_invertDATA = false;	/* If TRUE; invert DATA signals */
-	state->m_invertERR = false;	/* If TRUE; invert ERR signal */
-	state->m_invertSTR = false;	/* If TRUE; invert STR signals */
-	state->m_invertVAL = false;	/* If TRUE; invert VAL signals */
-	state->m_invertCLK = (ulInvertTSClock != 0);	/* If TRUE; invert CLK signals */
+	state->m_enable_mpeg_output = true;	/* If TRUE; enable MPEG ouput */
+	state->m_insert_rs_byte = false;	/* If TRUE; insert RS byte */
+	state->m_invert_data = false;	/* If TRUE; invert DATA signals */
+	state->m_invert_err = false;	/* If TRUE; invert ERR signal */
+	state->m_invert_str = false;	/* If TRUE; invert STR signals */
+	state->m_invert_val = false;	/* If TRUE; invert VAL signals */
+	state->m_invert_clk = (ul_invert_ts_clock != 0);	/* If TRUE; invert CLK signals */
 
 	/* If TRUE; static MPEG clockrate will be used;
 	   otherwise clockrate will adapt to the bitrate of the TS */
 
-	state->m_DVBTBitrate = ulDVBTBitrate;
-	state->m_DVBCBitrate = ulDVBCBitrate;
+	state->m_dvbt_bitrate = ul_dvbt_bitrate;
+	state->m_dvbc_bitrate = ul_dvbc_bitrate;
 
-	state->m_TSDataStrength = (ulTSDataStrength & 0x07);
+	state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
 
 	/* Maximum bitrate in b/s in case static clockrate is selected */
-	state->m_mpegTsStaticBitrate = 19392658;
-	state->m_disableTEIhandling = false;
+	state->m_mpeg_ts_static_bitrate = 19392658;
+	state->m_disable_te_ihandling = false;
 
-	if (ulInsertRSByte)
-		state->m_insertRSByte = true;
+	if (ul_insert_rs_byte)
+		state->m_insert_rs_byte = true;
 
-	state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
-	if (ulMpegLockTimeOut < 10000)
-		state->m_MpegLockTimeOut = ulMpegLockTimeOut;
-	state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
-	if (ulDemodLockTimeOut < 10000)
-		state->m_DemodLockTimeOut = ulDemodLockTimeOut;
+	state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
+	if (ul_mpeg_lock_time_out < 10000)
+		state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
+	state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
+	if (ul_demod_lock_time_out < 10000)
+		state->m_demod_lock_time_out = ul_demod_lock_time_out;
 
 	/* QAM defaults */
-	state->m_Constellation = DRX_CONSTELLATION_AUTO;
-	state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
-	state->m_fecRsPlen = 204 * 8;	/* fecRsPlen  annex A */
-	state->m_fecRsPrescale = 1;
+	state->m_constellation = DRX_CONSTELLATION_AUTO;
+	state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
+	state->m_fec_rs_plen = 204 * 8;	/* fecRsPlen  annex A */
+	state->m_fec_rs_prescale = 1;
 
-	state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
-	state->m_agcFastClipCtrlDelay = 0;
+	state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
+	state->m_agcfast_clip_ctrl_delay = 0;
 
-	state->m_GPIOCfg = (ulGPIOCfg);
+	state->m_gpio_cfg = ul_gpio_cfg;
 
-	state->m_bPowerDown = false;
-	state->m_currentPowerMode = DRX_POWER_DOWN;
+	state->m_b_power_down = false;
+	state->m_current_power_mode = DRX_POWER_DOWN;
 
-	state->m_rfmirror = (ulRfMirror == 0);
-	state->m_IfAgcPol = false;
+	state->m_rfmirror = (ul_rf_mirror == 0);
+	state->m_if_agc_pol = false;
 	return 0;
 }
 
-static int DRXX_Open(struct drxk_state *state)
+static int drxx_open(struct drxk_state *state)
 {
 	int status = 0;
 	u32 jtag = 0;
@@ -869,7 +785,8 @@ static int DRXX_Open(struct drxk_state *
 
 	dprintk(1, "\n");
 	/* stop lock indicator process */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 	/* Check device id */
@@ -888,14 +805,14 @@ static int DRXX_Open(struct drxk_state *
 	status = write16(state, SIO_TOP_COMM_KEY__A, key);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int GetDeviceCapabilities(struct drxk_state *state)
+static int get_device_capabilities(struct drxk_state *state)
 {
-	u16 sioPdrOhwCfg = 0;
-	u32 sioTopJtagidLo = 0;
+	u16 sio_pdr_ohw_cfg = 0;
+	u32 sio_top_jtagid_lo = 0;
 	int status;
 	const char *spin = "";
 
@@ -903,197 +820,196 @@ static int GetDeviceCapabilities(struct
 
 	/* driver 0.9.0 */
 	/* stop lock indicator process */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
 	if (status < 0)
 		goto error;
-	status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
+	status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
 	if (status < 0)
 		goto error;
 
-	switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
+	switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
 	case 0:
 		/* ignore (bypass ?) */
 		break;
 	case 1:
 		/* 27 MHz */
-		state->m_oscClockFreq = 27000;
+		state->m_osc_clock_freq = 27000;
 		break;
 	case 2:
 		/* 20.25 MHz */
-		state->m_oscClockFreq = 20250;
+		state->m_osc_clock_freq = 20250;
 		break;
 	case 3:
 		/* 4 MHz */
-		state->m_oscClockFreq = 20250;
+		state->m_osc_clock_freq = 20250;
 		break;
 	default:
-		printk(KERN_ERR "drxk: Clock Frequency is unknown\n");
+		pr_err("Clock Frequency is unknown\n");
 		return -EINVAL;
 	}
 	/*
 		Determine device capabilities
 		Based on pinning v14
 		*/
-	status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
+	status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
 	if (status < 0)
 		goto error;
 
-	printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo);
+	pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
 
 	/* driver 0.9.0 */
-	switch ((sioTopJtagidLo >> 29) & 0xF) {
+	switch ((sio_top_jtagid_lo >> 29) & 0xF) {
 	case 0:
-		state->m_deviceSpin = DRXK_SPIN_A1;
+		state->m_device_spin = DRXK_SPIN_A1;
 		spin = "A1";
 		break;
 	case 2:
-		state->m_deviceSpin = DRXK_SPIN_A2;
+		state->m_device_spin = DRXK_SPIN_A2;
 		spin = "A2";
 		break;
 	case 3:
-		state->m_deviceSpin = DRXK_SPIN_A3;
+		state->m_device_spin = DRXK_SPIN_A3;
 		spin = "A3";
 		break;
 	default:
-		state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
+		state->m_device_spin = DRXK_SPIN_UNKNOWN;
 		status = -EINVAL;
-		printk(KERN_ERR "drxk: Spin %d unknown\n",
-		       (sioTopJtagidLo >> 29) & 0xF);
+		pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
 		goto error2;
 	}
-	switch ((sioTopJtagidLo >> 12) & 0xFF) {
+	switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
 	case 0x13:
 		/* typeId = DRX3913K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = false;
-		state->m_hasAudio = false;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = false;
-		state->m_hasGPIO1 = false;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = false;
+		state->m_has_audio = false;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = false;
+		state->m_has_gpio1 = false;
+		state->m_has_irqn = false;
 		break;
 	case 0x15:
 		/* typeId = DRX3915K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = false;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = false;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = false;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = false;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x16:
 		/* typeId = DRX3916K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = false;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = false;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = false;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = false;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x18:
 		/* typeId = DRX3918K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = true;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = false;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = true;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = false;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x21:
 		/* typeId = DRX3921K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = true;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = true;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x23:
 		/* typeId = DRX3923K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = true;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = true;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x25:
 		/* typeId = DRX3925K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = true;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = true;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x26:
 		/* typeId = DRX3926K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = false;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = false;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	default:
-		printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
-			((sioTopJtagidLo >> 12) & 0xFF));
+		pr_err("DeviceID 0x%02x not supported\n",
+			((sio_top_jtagid_lo >> 12) & 0xFF));
 		status = -EINVAL;
 		goto error2;
 	}
 
-	printk(KERN_INFO
-	       "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
-	       ((sioTopJtagidLo >> 12) & 0xFF), spin,
-	       state->m_oscClockFreq / 1000,
-	       state->m_oscClockFreq % 1000);
+	pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
+	       ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
+	       state->m_osc_clock_freq / 1000,
+	       state->m_osc_clock_freq % 1000);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 error2:
 	return status;
 }
 
-static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
+static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
 {
 	int status;
 	bool powerdown_cmd;
@@ -1105,37 +1021,37 @@ static int HI_Command(struct drxk_state
 	if (status < 0)
 		goto error;
 	if (cmd == SIO_HI_RA_RAM_CMD_RESET)
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	powerdown_cmd =
 	    (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
-		    ((state->m_HICfgCtrl) &
+		    ((state->m_hi_cfg_ctrl) &
 		     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
 		    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
 	if (powerdown_cmd == false) {
 		/* Wait until command rdy */
-		u32 retryCount = 0;
-		u16 waitCmd;
+		u32 retry_count = 0;
+		u16 wait_cmd;
 
 		do {
-			msleep(1);
-			retryCount += 1;
+			usleep_range(1000, 2000);
+			retry_count += 1;
 			status = read16(state, SIO_HI_RA_RAM_CMD__A,
-					  &waitCmd);
-		} while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
-			 && (waitCmd != 0));
+					  &wait_cmd);
+		} while ((status < 0) && (retry_count < DRXK_MAX_RETRIES)
+			 && (wait_cmd != 0));
 		if (status < 0)
 			goto error;
-		status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
+		status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int HI_CfgCommand(struct drxk_state *state)
+static int hi_cfg_command(struct drxk_state *state)
 {
 	int status;
 
@@ -1143,61 +1059,68 @@ static int HI_CfgCommand(struct drxk_sta
 
 	mutex_lock(&state->mutex);
 
-	status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
+	status = write16(state, SIO_HI_RA_RAM_PAR_6__A,
+			 state->m_hi_cfg_timeout);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
+	status = write16(state, SIO_HI_RA_RAM_PAR_5__A,
+			 state->m_hi_cfg_ctrl);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
+	status = write16(state, SIO_HI_RA_RAM_PAR_4__A,
+			 state->m_hi_cfg_wake_up_key);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
+	status = write16(state, SIO_HI_RA_RAM_PAR_3__A,
+			 state->m_hi_cfg_bridge_delay);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
+	status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
+			 state->m_hi_cfg_timing_div);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
+	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
+			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
 	if (status < 0)
 		goto error;
-	status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
+	status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
 	if (status < 0)
 		goto error;
 
-	state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+	state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
 error:
 	mutex_unlock(&state->mutex);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int InitHI(struct drxk_state *state)
+static int init_hi(struct drxk_state *state)
 {
 	dprintk(1, "\n");
 
-	state->m_HICfgWakeUpKey = (state->demod_address << 1);
-	state->m_HICfgTimeout = 0x96FF;
+	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
+	state->m_hi_cfg_timeout = 0x96FF;
 	/* port/bridge/power down ctrl */
-	state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
+	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
 
-	return HI_CfgCommand(state);
+	return hi_cfg_command(state);
 }
 
-static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
+static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
 {
 	int status = -1;
-	u16 sioPdrMclkCfg = 0;
-	u16 sioPdrMdxCfg = 0;
+	u16 sio_pdr_mclk_cfg = 0;
+	u16 sio_pdr_mdx_cfg = 0;
 	u16 err_cfg = 0;
 
 	dprintk(1, ": mpeg %s, %s mode\n",
-		mpegEnable ? "enable" : "disable",
-		state->m_enableParallel ? "parallel" : "serial");
+		mpeg_enable ? "enable" : "disable",
+		state->m_enable_parallel ? "parallel" : "serial");
 
 	/* stop lock indicator process */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 
@@ -1206,7 +1129,7 @@ static int MPEGTSConfigurePins(struct dr
 	if (status < 0)
 		goto error;
 
-	if (mpegEnable == false) {
+	if (mpeg_enable == false) {
 		/*  Set MPEG TS pads to inputmode */
 		status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
 		if (status < 0)
@@ -1246,19 +1169,19 @@ static int MPEGTSConfigurePins(struct dr
 			goto error;
 	} else {
 		/* Enable MPEG output */
-		sioPdrMdxCfg =
-			((state->m_TSDataStrength <<
+		sio_pdr_mdx_cfg =
+			((state->m_ts_data_strength <<
 			SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
-		sioPdrMclkCfg = ((state->m_TSClockkStrength <<
+		sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
 					SIO_PDR_MCLK_CFG_DRIVE__B) |
 					0x0003);
 
-		status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
+		status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
 		if (status < 0)
 			goto error;
 
 		if (state->enable_merr_cfg)
-			err_cfg = sioPdrMdxCfg;
+			err_cfg = sio_pdr_mdx_cfg;
 
 		status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
 		if (status < 0)
@@ -1267,31 +1190,38 @@ static int MPEGTSConfigurePins(struct dr
 		if (status < 0)
 			goto error;
 
-		if (state->m_enableParallel == true) {
+		if (state->m_enable_parallel == true) {
 			/* paralel -> enable MD1 to MD7 */
-			status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD1_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD2_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD3_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD4_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD5_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD6_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD7_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
 		} else {
-			sioPdrMdxCfg = ((state->m_TSDataStrength <<
+			sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
 						SIO_PDR_MD0_CFG_DRIVE__B)
 					| 0x0003);
 			/* serial -> disable MD1 to MD7 */
@@ -1317,10 +1247,10 @@ static int MPEGTSConfigurePins(struct dr
 			if (status < 0)
 				goto error;
 		}
-		status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
+		status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
 		if (status < 0)
 			goto error;
-		status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
+		status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
 		if (status < 0)
 			goto error;
 	}
@@ -1332,21 +1262,21 @@ static int MPEGTSConfigurePins(struct dr
 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int MPEGTSDisable(struct drxk_state *state)
+static int mpegts_disable(struct drxk_state *state)
 {
 	dprintk(1, "\n");
 
-	return MPEGTSConfigurePins(state, false);
+	return mpegts_configure_pins(state, false);
 }
 
-static int BLChainCmd(struct drxk_state *state,
-		      u16 romOffset, u16 nrOfElements, u32 timeOut)
+static int bl_chain_cmd(struct drxk_state *state,
+		      u16 rom_offset, u16 nr_of_elements, u32 time_out)
 {
-	u16 blStatus = 0;
+	u16 bl_status = 0;
 	int status;
 	unsigned long end;
 
@@ -1355,46 +1285,46 @@ static int BLChainCmd(struct drxk_state
 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
+	status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
+	status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
 	if (status < 0)
 		goto error;
 
-	end = jiffies + msecs_to_jiffies(timeOut);
+	end = jiffies + msecs_to_jiffies(time_out);
 	do {
-		msleep(1);
-		status = read16(state, SIO_BL_STATUS__A, &blStatus);
+		usleep_range(1000, 2000);
+		status = read16(state, SIO_BL_STATUS__A, &bl_status);
 		if (status < 0)
 			goto error;
-	} while ((blStatus == 0x1) &&
+	} while ((bl_status == 0x1) &&
 			((time_is_after_jiffies(end))));
 
-	if (blStatus == 0x1) {
-		printk(KERN_ERR "drxk: SIO not ready\n");
+	if (bl_status == 0x1) {
+		pr_err("SIO not ready\n");
 		status = -EINVAL;
 		goto error2;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 error2:
 	mutex_unlock(&state->mutex);
 	return status;
 }
 
 
-static int DownloadMicrocode(struct drxk_state *state,
-			     const u8 pMCImage[], u32 Length)
+static int download_microcode(struct drxk_state *state,
+			     const u8 p_mc_image[], u32 length)
 {
-	const u8 *pSrc = pMCImage;
-	u32 Address;
-	u16 nBlocks;
-	u16 BlockSize;
+	const u8 *p_src = p_mc_image;
+	u32 address;
+	u16 n_blocks;
+	u16 block_size;
 	u32 offset = 0;
 	u32 i;
 	int status = 0;
@@ -1404,130 +1334,131 @@ static int DownloadMicrocode(struct drxk
 	/* down the drain (we don't care about MAGIC_WORD) */
 #if 0
 	/* For future reference */
-	Drain = (pSrc[0] << 8) | pSrc[1];
+	drain = (p_src[0] << 8) | p_src[1];
 #endif
-	pSrc += sizeof(u16);
+	p_src += sizeof(u16);
 	offset += sizeof(u16);
-	nBlocks = (pSrc[0] << 8) | pSrc[1];
-	pSrc += sizeof(u16);
+	n_blocks = (p_src[0] << 8) | p_src[1];
+	p_src += sizeof(u16);
 	offset += sizeof(u16);
 
-	for (i = 0; i < nBlocks; i += 1) {
-		Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
-		    (pSrc[2] << 8) | pSrc[3];
-		pSrc += sizeof(u32);
+	for (i = 0; i < n_blocks; i += 1) {
+		address = (p_src[0] << 24) | (p_src[1] << 16) |
+		    (p_src[2] << 8) | p_src[3];
+		p_src += sizeof(u32);
 		offset += sizeof(u32);
 
-		BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
-		pSrc += sizeof(u16);
+		block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
+		p_src += sizeof(u16);
 		offset += sizeof(u16);
 
 #if 0
 		/* For future reference */
-		Flags = (pSrc[0] << 8) | pSrc[1];
+		flags = (p_src[0] << 8) | p_src[1];
 #endif
-		pSrc += sizeof(u16);
+		p_src += sizeof(u16);
 		offset += sizeof(u16);
 
 #if 0
 		/* For future reference */
-		BlockCRC = (pSrc[0] << 8) | pSrc[1];
+		block_crc = (p_src[0] << 8) | p_src[1];
 #endif
-		pSrc += sizeof(u16);
+		p_src += sizeof(u16);
 		offset += sizeof(u16);
 
-		if (offset + BlockSize > Length) {
-			printk(KERN_ERR "drxk: Firmware is corrupted.\n");
+		if (offset + block_size > length) {
+			pr_err("Firmware is corrupted.\n");
 			return -EINVAL;
 		}
 
-		status = write_block(state, Address, BlockSize, pSrc);
+		status = write_block(state, address, block_size, p_src);
 		if (status < 0) {
-			printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
+			pr_err("Error %d while loading firmware\n", status);
 			break;
 		}
-		pSrc += BlockSize;
-		offset += BlockSize;
+		p_src += block_size;
+		offset += block_size;
 	}
 	return status;
 }
 
-static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
+static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
 {
 	int status;
 	u16 data = 0;
-	u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
-	u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
+	u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
+	u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
 	unsigned long end;
 
 	dprintk(1, "\n");
 
 	if (enable == false) {
-		desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
-		desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
+		desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
+		desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
 	}
 
 	status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
-	if (status >= 0 && data == desiredStatus) {
+	if (status >= 0 && data == desired_status) {
 		/* tokenring already has correct status */
 		return status;
 	}
 	/* Disable/enable dvbt tokenring bridge   */
-	status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
+	status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
 
 	end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
 	do {
 		status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
-		if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
+		if ((status >= 0 && data == desired_status)
+		    || time_is_after_jiffies(end))
 			break;
-		msleep(1);
+		usleep_range(1000, 2000);
 	} while (1);
-	if (data != desiredStatus) {
-		printk(KERN_ERR "drxk: SIO not ready\n");
+	if (data != desired_status) {
+		pr_err("SIO not ready\n");
 		return -EINVAL;
 	}
 	return status;
 }
 
-static int MPEGTSStop(struct drxk_state *state)
+static int mpegts_stop(struct drxk_state *state)
 {
 	int status = 0;
-	u16 fecOcSncMode = 0;
-	u16 fecOcIprMode = 0;
+	u16 fec_oc_snc_mode = 0;
+	u16 fec_oc_ipr_mode = 0;
 
 	dprintk(1, "\n");
 
 	/* Gracefull shutdown (byte boundaries) */
-	status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
+	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
 	if (status < 0)
 		goto error;
-	fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
-	status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
+	fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
+	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
 	if (status < 0)
 		goto error;
 
 	/* Suppress MCLK during absence of data */
-	status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
+	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
 	if (status < 0)
 		goto error;
-	fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
-	status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
+	fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
+	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
 static int scu_command(struct drxk_state *state,
-		       u16 cmd, u8 parameterLen,
-		       u16 *parameter, u8 resultLen, u16 *result)
+		       u16 cmd, u8 parameter_len,
+		       u16 *parameter, u8 result_len, u16 *result)
 {
 #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
 #error DRXK register mapping no longer compatible with this routine!
 #endif
-	u16 curCmd = 0;
+	u16 cur_cmd = 0;
 	int status = -EINVAL;
 	unsigned long end;
 	u8 buffer[34];
@@ -1537,9 +1468,9 @@ static int scu_command(struct drxk_state
 
 	dprintk(1, "\n");
 
-	if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
-	    ((resultLen > 0) && (result == NULL))) {
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+	if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
+	    ((result_len > 0) && (result == NULL))) {
+		pr_err("Error %d on %s\n", status, __func__);
 		return status;
 	}
 
@@ -1547,7 +1478,7 @@ static int scu_command(struct drxk_state
 
 	/* assume that the command register is ready
 		since it is checked afterwards */
-	for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
+	for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
 		buffer[cnt++] = (parameter[ii] & 0xFF);
 		buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
 	}
@@ -1555,27 +1486,28 @@ static int scu_command(struct drxk_state
 	buffer[cnt++] = ((cmd >> 8) & 0xFF);
 
 	write_block(state, SCU_RAM_PARAM_0__A -
-			(parameterLen - 1), cnt, buffer);
+			(parameter_len - 1), cnt, buffer);
 	/* Wait until SCU has processed command */
 	end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
 	do {
-		msleep(1);
-		status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
+		usleep_range(1000, 2000);
+		status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
 		if (status < 0)
 			goto error;
-	} while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
-	if (curCmd != DRX_SCU_READY) {
-		printk(KERN_ERR "drxk: SCU not ready\n");
+	} while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
+	if (cur_cmd != DRX_SCU_READY) {
+		pr_err("SCU not ready\n");
 		status = -EIO;
 		goto error2;
 	}
 	/* read results */
-	if ((resultLen > 0) && (result != NULL)) {
+	if ((result_len > 0) && (result != NULL)) {
 		s16 err;
 		int ii;
 
-		for (ii = resultLen - 1; ii >= 0; ii -= 1) {
-			status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
+		for (ii = result_len - 1; ii >= 0; ii -= 1) {
+			status = read16(state, SCU_RAM_PARAM_0__A - ii,
+					&result[ii]);
 			if (status < 0)
 				goto error;
 		}
@@ -1603,7 +1535,7 @@ static int scu_command(struct drxk_state
 			sprintf(errname, "ERROR: %d\n", err);
 			p = errname;
 		}
-		printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
+		pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
 		print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
 		status = -EINVAL;
 		goto error2;
@@ -1611,13 +1543,13 @@ static int scu_command(struct drxk_state
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 error2:
 	mutex_unlock(&state->mutex);
 	return status;
 }
 
-static int SetIqmAf(struct drxk_state *state, bool active)
+static int set_iqm_af(struct drxk_state *state, bool active)
 {
 	u16 data = 0;
 	int status;
@@ -1647,14 +1579,14 @@ static int SetIqmAf(struct drxk_state *s
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
+static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
 {
 	int status = 0;
-	u16 sioCcPwdMode = 0;
+	u16 sio_cc_pwd_mode = 0;
 
 	dprintk(1, "\n");
 
@@ -1664,19 +1596,19 @@ static int CtrlPowerMode(struct drxk_sta
 
 	switch (*mode) {
 	case DRX_POWER_UP:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
 		break;
 	case DRXK_POWER_DOWN_OFDM:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
 		break;
 	case DRXK_POWER_DOWN_CORE:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
 		break;
 	case DRXK_POWER_DOWN_PLL:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
 		break;
 	case DRX_POWER_DOWN:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
 		break;
 	default:
 		/* Unknow sleep mode */
@@ -1684,15 +1616,15 @@ static int CtrlPowerMode(struct drxk_sta
 	}
 
 	/* If already in requested power mode, do nothing */
-	if (state->m_currentPowerMode == *mode)
+	if (state->m_current_power_mode == *mode)
 		return 0;
 
 	/* For next steps make sure to start from DRX_POWER_UP mode */
-	if (state->m_currentPowerMode != DRX_POWER_UP) {
-		status = PowerUpDevice(state);
+	if (state->m_current_power_mode != DRX_POWER_UP) {
+		status = power_up_device(state);
 		if (status < 0)
 			goto error;
-		status = DVBTEnableOFDMTokenRing(state, true);
+		status = dvbt_enable_ofdm_token_ring(state, true);
 		if (status < 0)
 			goto error;
 	}
@@ -1709,31 +1641,31 @@ static int CtrlPowerMode(struct drxk_sta
 		/* Power down device */
 		/* stop all comm_exec */
 		/* Stop and power down previous standard */
-		switch (state->m_OperationMode) {
+		switch (state->m_operation_mode) {
 		case OM_DVBT:
-			status = MPEGTSStop(state);
+			status = mpegts_stop(state);
 			if (status < 0)
 				goto error;
-			status = PowerDownDVBT(state, false);
+			status = power_down_dvbt(state, false);
 			if (status < 0)
 				goto error;
 			break;
 		case OM_QAM_ITU_A:
 		case OM_QAM_ITU_C:
-			status = MPEGTSStop(state);
+			status = mpegts_stop(state);
 			if (status < 0)
 				goto error;
-			status = PowerDownQAM(state);
+			status = power_down_qam(state);
 			if (status < 0)
 				goto error;
 			break;
 		default:
 			break;
 		}
-		status = DVBTEnableOFDMTokenRing(state, false);
+		status = dvbt_enable_ofdm_token_ring(state, false);
 		if (status < 0)
 			goto error;
-		status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
+		status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
 		if (status < 0)
 			goto error;
 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
@@ -1741,26 +1673,26 @@ static int CtrlPowerMode(struct drxk_sta
 			goto error;
 
 		if (*mode != DRXK_POWER_DOWN_OFDM) {
-			state->m_HICfgCtrl |=
+			state->m_hi_cfg_ctrl |=
 				SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
-			status = HI_CfgCommand(state);
+			status = hi_cfg_command(state);
 			if (status < 0)
 				goto error;
 		}
 	}
-	state->m_currentPowerMode = *mode;
+	state->m_current_power_mode = *mode;
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
+static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
 {
-	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
-	u16 cmdResult = 0;
+	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
+	u16 cmd_result = 0;
 	u16 data = 0;
 	int status;
 
@@ -1771,11 +1703,17 @@ static int PowerDownDVBT(struct drxk_sta
 		goto error;
 	if (data == SCU_COMM_EXEC_ACTIVE) {
 		/* Send OFDM stop command */
-		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+		status = scu_command(state,
+				     SCU_RAM_COMMAND_STANDARD_OFDM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
+				     0, NULL, 1, &cmd_result);
 		if (status < 0)
 			goto error;
 		/* Send OFDM reset command */
-		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+		status = scu_command(state,
+				     SCU_RAM_COMMAND_STANDARD_OFDM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
+				     0, NULL, 1, &cmd_result);
 		if (status < 0)
 			goto error;
 	}
@@ -1792,24 +1730,24 @@ static int PowerDownDVBT(struct drxk_sta
 		goto error;
 
 	/* powerdown AFE                   */
-	status = SetIqmAf(state, false);
+	status = set_iqm_af(state, false);
 	if (status < 0)
 		goto error;
 
 	/* powerdown to OFDM mode          */
-	if (setPowerMode) {
-		status = CtrlPowerMode(state, &powerMode);
+	if (set_power_mode) {
+		status = ctrl_power_mode(state, &power_mode);
 		if (status < 0)
 			goto error;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetOperationMode(struct drxk_state *state,
-			    enum OperationMode oMode)
+static int setoperation_mode(struct drxk_state *state,
+			    enum operation_mode o_mode)
 {
 	int status = 0;
 
@@ -1821,36 +1759,37 @@ static int SetOperationMode(struct drxk_
 	 */
 
 	/* disable HW lock indicator */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 
 	/* Device is already at the required mode */
-	if (state->m_OperationMode == oMode)
+	if (state->m_operation_mode == o_mode)
 		return 0;
 
-	switch (state->m_OperationMode) {
+	switch (state->m_operation_mode) {
 		/* OM_NONE was added for start up */
 	case OM_NONE:
 		break;
 	case OM_DVBT:
-		status = MPEGTSStop(state);
+		status = mpegts_stop(state);
 		if (status < 0)
 			goto error;
-		status = PowerDownDVBT(state, true);
+		status = power_down_dvbt(state, true);
 		if (status < 0)
 			goto error;
-		state->m_OperationMode = OM_NONE;
+		state->m_operation_mode = OM_NONE;
 		break;
 	case OM_QAM_ITU_A:	/* fallthrough */
 	case OM_QAM_ITU_C:
-		status = MPEGTSStop(state);
+		status = mpegts_stop(state);
 		if (status < 0)
 			goto error;
-		status = PowerDownQAM(state);
+		status = power_down_qam(state);
 		if (status < 0)
 			goto error;
-		state->m_OperationMode = OM_NONE;
+		state->m_operation_mode = OM_NONE;
 		break;
 	case OM_QAM_ITU_B:
 	default:
@@ -1861,20 +1800,20 @@ static int SetOperationMode(struct drxk_
 	/*
 		Power up new standard
 		*/
-	switch (oMode) {
+	switch (o_mode) {
 	case OM_DVBT:
 		dprintk(1, ": DVB-T\n");
-		state->m_OperationMode = oMode;
-		status = SetDVBTStandard(state, oMode);
+		state->m_operation_mode = o_mode;
+		status = set_dvbt_standard(state, o_mode);
 		if (status < 0)
 			goto error;
 		break;
 	case OM_QAM_ITU_A:	/* fallthrough */
 	case OM_QAM_ITU_C:
 		dprintk(1, ": DVB-C Annex %c\n",
-			(state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
-		state->m_OperationMode = oMode;
-		status = SetQAMStandard(state, oMode);
+			(state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
+		state->m_operation_mode = o_mode;
+		status = set_qam_standard(state, o_mode);
 		if (status < 0)
 			goto error;
 		break;
@@ -1884,121 +1823,121 @@ static int SetOperationMode(struct drxk_
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int Start(struct drxk_state *state, s32 offsetFreq,
-		 s32 IntermediateFrequency)
+static int start(struct drxk_state *state, s32 offset_freq,
+		 s32 intermediate_frequency)
 {
 	int status = -EINVAL;
 
-	u16 IFreqkHz;
-	s32 OffsetkHz = offsetFreq / 1000;
+	u16 i_freqk_hz;
+	s32 offsetk_hz = offset_freq / 1000;
 
 	dprintk(1, "\n");
-	if (state->m_DrxkState != DRXK_STOPPED &&
-		state->m_DrxkState != DRXK_DTV_STARTED)
+	if (state->m_drxk_state != DRXK_STOPPED &&
+		state->m_drxk_state != DRXK_DTV_STARTED)
 		goto error;
 
-	state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
+	state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
 
-	if (IntermediateFrequency < 0) {
-		state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
-		IntermediateFrequency = -IntermediateFrequency;
+	if (intermediate_frequency < 0) {
+		state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
+		intermediate_frequency = -intermediate_frequency;
 	}
 
-	switch (state->m_OperationMode) {
+	switch (state->m_operation_mode) {
 	case OM_QAM_ITU_A:
 	case OM_QAM_ITU_C:
-		IFreqkHz = (IntermediateFrequency / 1000);
-		status = SetQAM(state, IFreqkHz, OffsetkHz);
+		i_freqk_hz = (intermediate_frequency / 1000);
+		status = set_qam(state, i_freqk_hz, offsetk_hz);
 		if (status < 0)
 			goto error;
-		state->m_DrxkState = DRXK_DTV_STARTED;
+		state->m_drxk_state = DRXK_DTV_STARTED;
 		break;
 	case OM_DVBT:
-		IFreqkHz = (IntermediateFrequency / 1000);
-		status = MPEGTSStop(state);
+		i_freqk_hz = (intermediate_frequency / 1000);
+		status = mpegts_stop(state);
 		if (status < 0)
 			goto error;
-		status = SetDVBT(state, IFreqkHz, OffsetkHz);
+		status = set_dvbt(state, i_freqk_hz, offsetk_hz);
 		if (status < 0)
 			goto error;
-		status = DVBTStart(state);
+		status = dvbt_start(state);
 		if (status < 0)
 			goto error;
-		state->m_DrxkState = DRXK_DTV_STARTED;
+		state->m_drxk_state = DRXK_DTV_STARTED;
 		break;
 	default:
 		break;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int ShutDown(struct drxk_state *state)
+static int shut_down(struct drxk_state *state)
 {
 	dprintk(1, "\n");
 
-	MPEGTSStop(state);
+	mpegts_stop(state);
 	return 0;
 }
 
-static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus)
+static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
 {
 	int status = -EINVAL;
 
 	dprintk(1, "\n");
 
-	if (pLockStatus == NULL)
+	if (p_lock_status == NULL)
 		goto error;
 
-	*pLockStatus = NOT_LOCKED;
+	*p_lock_status = NOT_LOCKED;
 
 	/* define the SCU command code */
-	switch (state->m_OperationMode) {
+	switch (state->m_operation_mode) {
 	case OM_QAM_ITU_A:
 	case OM_QAM_ITU_B:
 	case OM_QAM_ITU_C:
-		status = GetQAMLockStatus(state, pLockStatus);
+		status = get_qam_lock_status(state, p_lock_status);
 		break;
 	case OM_DVBT:
-		status = GetDVBTLockStatus(state, pLockStatus);
+		status = get_dvbt_lock_status(state, p_lock_status);
 		break;
 	default:
 		break;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int MPEGTSStart(struct drxk_state *state)
+static int mpegts_start(struct drxk_state *state)
 {
 	int status;
 
-	u16 fecOcSncMode = 0;
+	u16 fec_oc_snc_mode = 0;
 
 	/* Allow OC to sync again */
-	status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
+	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
 	if (status < 0)
 		goto error;
-	fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
-	status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
+	fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
+	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
 	if (status < 0)
 		goto error;
 	status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int MPEGTSDtoInit(struct drxk_state *state)
+static int mpegts_dto_init(struct drxk_state *state)
 {
 	int status;
 
@@ -2040,68 +1979,68 @@ static int MPEGTSDtoInit(struct drxk_sta
 	status = write16(state, FEC_OC_SNC_HWM__A, 12);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int MPEGTSDtoSetup(struct drxk_state *state,
-			  enum OperationMode oMode)
+static int mpegts_dto_setup(struct drxk_state *state,
+			  enum operation_mode o_mode)
 {
 	int status;
 
-	u16 fecOcRegMode = 0;	/* FEC_OC_MODE       register value */
-	u16 fecOcRegIprMode = 0;	/* FEC_OC_IPR_MODE   register value */
-	u16 fecOcDtoMode = 0;	/* FEC_OC_IPR_INVERT register value */
-	u16 fecOcFctMode = 0;	/* FEC_OC_IPR_INVERT register value */
-	u16 fecOcDtoPeriod = 2;	/* FEC_OC_IPR_INVERT register value */
-	u16 fecOcDtoBurstLen = 188;	/* FEC_OC_IPR_INVERT register value */
-	u32 fecOcRcnCtlRate = 0;	/* FEC_OC_IPR_INVERT register value */
-	u16 fecOcTmdMode = 0;
-	u16 fecOcTmdIntUpdRate = 0;
-	u32 maxBitRate = 0;
-	bool staticCLK = false;
+	u16 fec_oc_reg_mode = 0;	/* FEC_OC_MODE       register value */
+	u16 fec_oc_reg_ipr_mode = 0;	/* FEC_OC_IPR_MODE   register value */
+	u16 fec_oc_dto_mode = 0;	/* FEC_OC_IPR_INVERT register value */
+	u16 fec_oc_fct_mode = 0;	/* FEC_OC_IPR_INVERT register value */
+	u16 fec_oc_dto_period = 2;	/* FEC_OC_IPR_INVERT register value */
+	u16 fec_oc_dto_burst_len = 188;	/* FEC_OC_IPR_INVERT register value */
+	u32 fec_oc_rcn_ctl_rate = 0;	/* FEC_OC_IPR_INVERT register value */
+	u16 fec_oc_tmd_mode = 0;
+	u16 fec_oc_tmd_int_upd_rate = 0;
+	u32 max_bit_rate = 0;
+	bool static_clk = false;
 
 	dprintk(1, "\n");
 
 	/* Check insertion of the Reed-Solomon parity bytes */
-	status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
+	status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
 	if (status < 0)
 		goto error;
-	status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
+	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
 	if (status < 0)
 		goto error;
-	fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
-	fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
-	if (state->m_insertRSByte == true) {
+	fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
+	fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
+	if (state->m_insert_rs_byte == true) {
 		/* enable parity symbol forward */
-		fecOcRegMode |= FEC_OC_MODE_PARITY__M;
+		fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
 		/* MVAL disable during parity bytes */
-		fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
+		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
 		/* TS burst length to 204 */
-		fecOcDtoBurstLen = 204;
+		fec_oc_dto_burst_len = 204;
 	}
 
 	/* Check serial or parrallel output */
-	fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
-	if (state->m_enableParallel == false) {
+	fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
+	if (state->m_enable_parallel == false) {
 		/* MPEG data output is serial -> set ipr_mode[0] */
-		fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
+		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
 	}
 
-	switch (oMode) {
+	switch (o_mode) {
 	case OM_DVBT:
-		maxBitRate = state->m_DVBTBitrate;
-		fecOcTmdMode = 3;
-		fecOcRcnCtlRate = 0xC00000;
-		staticCLK = state->m_DVBTStaticCLK;
+		max_bit_rate = state->m_dvbt_bitrate;
+		fec_oc_tmd_mode = 3;
+		fec_oc_rcn_ctl_rate = 0xC00000;
+		static_clk = state->m_dvbt_static_clk;
 		break;
 	case OM_QAM_ITU_A:	/* fallthrough */
 	case OM_QAM_ITU_C:
-		fecOcTmdMode = 0x0004;
-		fecOcRcnCtlRate = 0xD2B4EE;	/* good for >63 Mb/s */
-		maxBitRate = state->m_DVBCBitrate;
-		staticCLK = state->m_DVBCStaticCLK;
+		fec_oc_tmd_mode = 0x0004;
+		fec_oc_rcn_ctl_rate = 0xD2B4EE;	/* good for >63 Mb/s */
+		max_bit_rate = state->m_dvbc_bitrate;
+		static_clk = state->m_dvbc_static_clk;
 		break;
 	default:
 		status = -EINVAL;
@@ -2110,83 +2049,84 @@ static int MPEGTSDtoSetup(struct drxk_st
 		goto error;
 
 	/* Configure DTO's */
-	if (staticCLK) {
-		u32 bitRate = 0;
+	if (static_clk) {
+		u32 bit_rate = 0;
 
 		/* Rational DTO for MCLK source (static MCLK rate),
 			Dynamic DTO for optimal grouping
 			(avoid intra-packet gaps),
 			DTO offset enable to sync TS burst with MSTRT */
-		fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
+		fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
 				FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
-		fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
+		fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
 				FEC_OC_FCT_MODE_VIRT_ENA__M);
 
 		/* Check user defined bitrate */
-		bitRate = maxBitRate;
-		if (bitRate > 75900000UL) {	/* max is 75.9 Mb/s */
-			bitRate = 75900000UL;
+		bit_rate = max_bit_rate;
+		if (bit_rate > 75900000UL) {	/* max is 75.9 Mb/s */
+			bit_rate = 75900000UL;
 		}
 		/* Rational DTO period:
 			dto_period = (Fsys / bitrate) - 2
 
-			Result should be floored,
+			result should be floored,
 			to make sure >= requested bitrate
 			*/
-		fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
-						* 1000) / bitRate);
-		if (fecOcDtoPeriod <= 2)
-			fecOcDtoPeriod = 0;
+		fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
+						* 1000) / bit_rate);
+		if (fec_oc_dto_period <= 2)
+			fec_oc_dto_period = 0;
 		else
-			fecOcDtoPeriod -= 2;
-		fecOcTmdIntUpdRate = 8;
+			fec_oc_dto_period -= 2;
+		fec_oc_tmd_int_upd_rate = 8;
 	} else {
-		/* (commonAttr->staticCLK == false) => dynamic mode */
-		fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
-		fecOcFctMode = FEC_OC_FCT_MODE__PRE;
-		fecOcTmdIntUpdRate = 5;
+		/* (commonAttr->static_clk == false) => dynamic mode */
+		fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
+		fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
+		fec_oc_tmd_int_upd_rate = 5;
 	}
 
 	/* Write appropriate registers with requested configuration */
-	status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
+	status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
+	status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
+	status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
+	status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
+	status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
+	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
 	if (status < 0)
 		goto error;
 
 	/* Rate integration settings */
-	status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
+	status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
+	status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A,
+			 fec_oc_tmd_int_upd_rate);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
+	status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int MPEGTSConfigurePolarity(struct drxk_state *state)
+static int mpegts_configure_polarity(struct drxk_state *state)
 {
-	u16 fecOcRegIprInvert = 0;
+	u16 fec_oc_reg_ipr_invert = 0;
 
 	/* Data mask for the output data byte */
-	u16 InvertDataMask =
+	u16 invert_data_mask =
 	    FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
 	    FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
 	    FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
@@ -2195,40 +2135,40 @@ static int MPEGTSConfigurePolarity(struc
 	dprintk(1, "\n");
 
 	/* Control selective inversion of output bits */
-	fecOcRegIprInvert &= (~(InvertDataMask));
-	if (state->m_invertDATA == true)
-		fecOcRegIprInvert |= InvertDataMask;
-	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
-	if (state->m_invertERR == true)
-		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
-	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
-	if (state->m_invertSTR == true)
-		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
-	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
-	if (state->m_invertVAL == true)
-		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
-	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
-	if (state->m_invertCLK == true)
-		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
+	fec_oc_reg_ipr_invert &= (~(invert_data_mask));
+	if (state->m_invert_data == true)
+		fec_oc_reg_ipr_invert |= invert_data_mask;
+	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
+	if (state->m_invert_err == true)
+		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
+	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
+	if (state->m_invert_str == true)
+		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
+	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
+	if (state->m_invert_val == true)
+		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
+	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
+	if (state->m_invert_clk == true)
+		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
 
-	return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
+	return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
 }
 
 #define   SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
 
-static int SetAgcRf(struct drxk_state *state,
-		    struct SCfgAgc *pAgcCfg, bool isDTV)
+static int set_agc_rf(struct drxk_state *state,
+		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
 {
 	int status = -EINVAL;
 	u16 data = 0;
-	struct SCfgAgc *pIfAgcSettings;
+	struct s_cfg_agc *p_if_agc_settings;
 
 	dprintk(1, "\n");
 
-	if (pAgcCfg == NULL)
+	if (p_agc_cfg == NULL)
 		goto error;
 
-	switch (pAgcCfg->ctrlMode) {
+	switch (p_agc_cfg->ctrl_mode) {
 	case DRXK_AGC_CTRL_AUTO:
 		/* Enable RF AGC DAC */
 		status = read16(state, IQM_AF_STDBY__A, &data);
@@ -2246,7 +2186,7 @@ static int SetAgcRf(struct drxk_state *s
 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
 
 		/* Polarity */
-		if (state->m_RfAgcPol)
+		if (state->m_rf_agc_pol)
 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
 		else
 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
@@ -2260,7 +2200,7 @@ static int SetAgcRf(struct drxk_state *s
 			goto error;
 
 		data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
-		data |= (~(pAgcCfg->speed <<
+		data |= (~(p_agc_cfg->speed <<
 				SCU_RAM_AGC_KI_RED_RAGC_RED__B)
 				& SCU_RAM_AGC_KI_RED_RAGC_RED__M);
 
@@ -2268,30 +2208,34 @@ static int SetAgcRf(struct drxk_state *s
 		if (status < 0)
 			goto error;
 
-		if (IsDVBT(state))
-			pIfAgcSettings = &state->m_dvbtIfAgcCfg;
-		else if (IsQAM(state))
-			pIfAgcSettings = &state->m_qamIfAgcCfg;
+		if (is_dvbt(state))
+			p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
+		else if (is_qam(state))
+			p_if_agc_settings = &state->m_qam_if_agc_cfg;
 		else
-			pIfAgcSettings = &state->m_atvIfAgcCfg;
-		if (pIfAgcSettings == NULL) {
+			p_if_agc_settings = &state->m_atv_if_agc_cfg;
+		if (p_if_agc_settings == NULL) {
 			status = -EINVAL;
 			goto error;
 		}
 
 		/* Set TOP, only if IF-AGC is in AUTO mode */
-		if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
-			status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
+		if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO)
+			status = write16(state,
+					 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+					 p_agc_cfg->top);
 			if (status < 0)
 				goto error;
 
 		/* Cut-Off current */
-		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
+		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
+				 p_agc_cfg->cut_off_current);
 		if (status < 0)
 			goto error;
 
 		/* Max. output level */
-		status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
+		status = write16(state, SCU_RAM_AGC_RF_MAX__A,
+				 p_agc_cfg->max_output_level);
 		if (status < 0)
 			goto error;
 
@@ -2312,7 +2256,7 @@ static int SetAgcRf(struct drxk_state *s
 		if (status < 0)
 			goto error;
 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
-		if (state->m_RfAgcPol)
+		if (state->m_rf_agc_pol)
 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
 		else
 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
@@ -2326,7 +2270,8 @@ static int SetAgcRf(struct drxk_state *s
 			goto error;
 
 		/* Write value to output pin */
-		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
+		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A,
+				 p_agc_cfg->output_level);
 		if (status < 0)
 			goto error;
 		break;
@@ -2357,22 +2302,22 @@ static int SetAgcRf(struct drxk_state *s
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
 #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
 
-static int SetAgcIf(struct drxk_state *state,
-		    struct SCfgAgc *pAgcCfg, bool isDTV)
+static int set_agc_if(struct drxk_state *state,
+		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
 {
 	u16 data = 0;
 	int status = 0;
-	struct SCfgAgc *pRfAgcSettings;
+	struct s_cfg_agc *p_rf_agc_settings;
 
 	dprintk(1, "\n");
 
-	switch (pAgcCfg->ctrlMode) {
+	switch (p_agc_cfg->ctrl_mode) {
 	case DRXK_AGC_CTRL_AUTO:
 
 		/* Enable IF AGC DAC */
@@ -2392,7 +2337,7 @@ static int SetAgcIf(struct drxk_state *s
 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
 
 		/* Polarity */
-		if (state->m_IfAgcPol)
+		if (state->m_if_agc_pol)
 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
 		else
 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
@@ -2405,7 +2350,7 @@ static int SetAgcIf(struct drxk_state *s
 		if (status < 0)
 			goto error;
 		data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
-		data |= (~(pAgcCfg->speed <<
+		data |= (~(p_agc_cfg->speed <<
 				SCU_RAM_AGC_KI_RED_IAGC_RED__B)
 				& SCU_RAM_AGC_KI_RED_IAGC_RED__M);
 
@@ -2413,14 +2358,15 @@ static int SetAgcIf(struct drxk_state *s
 		if (status < 0)
 			goto error;
 
-		if (IsQAM(state))
-			pRfAgcSettings = &state->m_qamRfAgcCfg;
+		if (is_qam(state))
+			p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
 		else
-			pRfAgcSettings = &state->m_atvRfAgcCfg;
-		if (pRfAgcSettings == NULL)
+			p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
+		if (p_rf_agc_settings == NULL)
 			return -1;
 		/* Restore TOP */
-		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
+		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+				 p_rf_agc_settings->top);
 		if (status < 0)
 			goto error;
 		break;
@@ -2444,7 +2390,7 @@ static int SetAgcIf(struct drxk_state *s
 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
 
 		/* Polarity */
-		if (state->m_IfAgcPol)
+		if (state->m_if_agc_pol)
 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
 		else
 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
@@ -2453,7 +2399,8 @@ static int SetAgcIf(struct drxk_state *s
 			goto error;
 
 		/* Write value to output pin */
-		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
+		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+				 p_agc_cfg->output_level);
 		if (status < 0)
 			goto error;
 		break;
@@ -2478,176 +2425,181 @@ static int SetAgcIf(struct drxk_state *s
 		if (status < 0)
 			goto error;
 		break;
-	}		/* switch (agcSettingsIf->ctrlMode) */
+	}		/* switch (agcSettingsIf->ctrl_mode) */
 
 	/* always set the top to support
 		configurations without if-loop */
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int GetQAMSignalToNoise(struct drxk_state *state,
-			       s32 *pSignalToNoise)
+static int get_qam_signal_to_noise(struct drxk_state *state,
+			       s32 *p_signal_to_noise)
 {
 	int status = 0;
-	u16 qamSlErrPower = 0;	/* accum. error between
+	u16 qam_sl_err_power = 0;	/* accum. error between
 					raw and sliced symbols */
-	u32 qamSlSigPower = 0;	/* used for MER, depends of
+	u32 qam_sl_sig_power = 0;	/* used for MER, depends of
 					QAM modulation */
-	u32 qamSlMer = 0;	/* QAM MER */
+	u32 qam_sl_mer = 0;	/* QAM MER */
 
 	dprintk(1, "\n");
 
 	/* MER calculation */
 
 	/* get the register value needed for MER */
-	status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
+	status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
 	if (status < 0) {
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 		return -EINVAL;
 	}
 
 	switch (state->props.modulation) {
 	case QAM_16:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
 		break;
 	case QAM_32:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
 		break;
 	case QAM_64:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
 		break;
 	case QAM_128:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
 		break;
 	default:
 	case QAM_256:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
 		break;
 	}
 
-	if (qamSlErrPower > 0) {
-		qamSlMer = Log10Times100(qamSlSigPower) -
-			Log10Times100((u32) qamSlErrPower);
+	if (qam_sl_err_power > 0) {
+		qam_sl_mer = log10times100(qam_sl_sig_power) -
+			log10times100((u32) qam_sl_err_power);
 	}
-	*pSignalToNoise = qamSlMer;
+	*p_signal_to_noise = qam_sl_mer;
 
 	return status;
 }
 
-static int GetDVBTSignalToNoise(struct drxk_state *state,
-				s32 *pSignalToNoise)
+static int get_dvbt_signal_to_noise(struct drxk_state *state,
+				s32 *p_signal_to_noise)
 {
 	int status;
-	u16 regData = 0;
-	u32 EqRegTdSqrErrI = 0;
-	u32 EqRegTdSqrErrQ = 0;
-	u16 EqRegTdSqrErrExp = 0;
-	u16 EqRegTdTpsPwrOfs = 0;
-	u16 EqRegTdReqSmbCnt = 0;
-	u32 tpsCnt = 0;
-	u32 SqrErrIQ = 0;
+	u16 reg_data = 0;
+	u32 eq_reg_td_sqr_err_i = 0;
+	u32 eq_reg_td_sqr_err_q = 0;
+	u16 eq_reg_td_sqr_err_exp = 0;
+	u16 eq_reg_td_tps_pwr_ofs = 0;
+	u16 eq_reg_td_req_smb_cnt = 0;
+	u32 tps_cnt = 0;
+	u32 sqr_err_iq = 0;
 	u32 a = 0;
 	u32 b = 0;
 	u32 c = 0;
-	u32 iMER = 0;
-	u16 transmissionParams = 0;
+	u32 i_mer = 0;
+	u16 transmission_params = 0;
 
 	dprintk(1, "\n");
 
-	status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
+	status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
+			&eq_reg_td_tps_pwr_ofs);
 	if (status < 0)
 		goto error;
-	status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
+	status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
+			&eq_reg_td_req_smb_cnt);
 	if (status < 0)
 		goto error;
-	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
+	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
+			&eq_reg_td_sqr_err_exp);
 	if (status < 0)
 		goto error;
-	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
+	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
+			&reg_data);
 	if (status < 0)
 		goto error;
 	/* Extend SQR_ERR_I operational range */
-	EqRegTdSqrErrI = (u32) regData;
-	if ((EqRegTdSqrErrExp > 11) &&
-		(EqRegTdSqrErrI < 0x00000FFFUL)) {
-		EqRegTdSqrErrI += 0x00010000UL;
+	eq_reg_td_sqr_err_i = (u32) reg_data;
+	if ((eq_reg_td_sqr_err_exp > 11) &&
+		(eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
+		eq_reg_td_sqr_err_i += 0x00010000UL;
 	}
-	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
+	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &reg_data);
 	if (status < 0)
 		goto error;
 	/* Extend SQR_ERR_Q operational range */
-	EqRegTdSqrErrQ = (u32) regData;
-	if ((EqRegTdSqrErrExp > 11) &&
-		(EqRegTdSqrErrQ < 0x00000FFFUL))
-		EqRegTdSqrErrQ += 0x00010000UL;
+	eq_reg_td_sqr_err_q = (u32) reg_data;
+	if ((eq_reg_td_sqr_err_exp > 11) &&
+		(eq_reg_td_sqr_err_q < 0x00000FFFUL))
+		eq_reg_td_sqr_err_q += 0x00010000UL;
 
-	status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
+	status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A,
+			&transmission_params);
 	if (status < 0)
 		goto error;
 
 	/* Check input data for MER */
 
 	/* MER calculation (in 0.1 dB) without math.h */
-	if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
-		iMER = 0;
-	else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
+	if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
+		i_mer = 0;
+	else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
 		/* No error at all, this must be the HW reset value
 			* Apparently no first measurement yet
 			* Set MER to 0.0 */
-		iMER = 0;
+		i_mer = 0;
 	} else {
-		SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
-			EqRegTdSqrErrExp;
-		if ((transmissionParams &
+		sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
+			eq_reg_td_sqr_err_exp;
+		if ((transmission_params &
 			OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
 			== OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
-			tpsCnt = 17;
+			tps_cnt = 17;
 		else
-			tpsCnt = 68;
+			tps_cnt = 68;
 
 		/* IMER = 100 * log10 (x)
-			where x = (EqRegTdTpsPwrOfs^2 *
-			EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
+			where x = (eq_reg_td_tps_pwr_ofs^2 *
+			eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
 
 			=> IMER = a + b -c
-			where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
-			b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
-			c = 100 * log10 (SqrErrIQ)
+			where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
+			b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
+			c = 100 * log10 (sqr_err_iq)
 			*/
 
 		/* log(x) x = 9bits * 9bits->18 bits  */
-		a = Log10Times100(EqRegTdTpsPwrOfs *
-					EqRegTdTpsPwrOfs);
+		a = log10times100(eq_reg_td_tps_pwr_ofs *
+					eq_reg_td_tps_pwr_ofs);
 		/* log(x) x = 16bits * 7bits->23 bits  */
-		b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
+		b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
 		/* log(x) x = (16bits + 16bits) << 15 ->32 bits  */
-		c = Log10Times100(SqrErrIQ);
+		c = log10times100(sqr_err_iq);
 
-		iMER = a + b - c;
+		i_mer = a + b - c;
 	}
-	*pSignalToNoise = iMER;
+	*p_signal_to_noise = i_mer;
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
+static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
 {
 	dprintk(1, "\n");
 
-	*pSignalToNoise = 0;
-	switch (state->m_OperationMode) {
+	*p_signal_to_noise = 0;
+	switch (state->m_operation_mode) {
 	case OM_DVBT:
-		return GetDVBTSignalToNoise(state, pSignalToNoise);
+		return get_dvbt_signal_to_noise(state, p_signal_to_noise);
 	case OM_QAM_ITU_A:
 	case OM_QAM_ITU_C:
-		return GetQAMSignalToNoise(state, pSignalToNoise);
+		return get_qam_signal_to_noise(state, p_signal_to_noise);
 	default:
 		break;
 	}
@@ -2655,7 +2607,7 @@ static int GetSignalToNoise(struct drxk_
 }
 
 #if 0
-static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
+static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
 {
 	/* SNR Values for quasi errorfree reception rom Nordig 2.2 */
 	int status = 0;
@@ -2680,102 +2632,104 @@ static int GetDVBTQuality(struct drxk_st
 		225,		/* 64-QAM 7/8 */
 	};
 
-	*pQuality = 0;
+	*p_quality = 0;
 
 	do {
-		s32 SignalToNoise = 0;
-		u16 Constellation = 0;
-		u16 CodeRate = 0;
-		u32 SignalToNoiseRel;
-		u32 BERQuality;
+		s32 signal_to_noise = 0;
+		u16 constellation = 0;
+		u16 code_rate = 0;
+		u32 signal_to_noise_rel;
+		u32 ber_quality;
 
-		status = GetDVBTSignalToNoise(state, &SignalToNoise);
+		status = get_dvbt_signal_to_noise(state, &signal_to_noise);
 		if (status < 0)
 			break;
-		status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
+		status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A,
+				&constellation);
 		if (status < 0)
 			break;
-		Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
+		constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
 
-		status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
+		status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
+				&code_rate);
 		if (status < 0)
 			break;
-		CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
+		code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
 
-		if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
-		    CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
+		if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
+		    code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
 			break;
-		SignalToNoiseRel = SignalToNoise -
-		    QE_SN[Constellation * 5 + CodeRate];
-		BERQuality = 100;
+		signal_to_noise_rel = signal_to_noise -
+		    QE_SN[constellation * 5 + code_rate];
+		ber_quality = 100;
 
-		if (SignalToNoiseRel < -70)
-			*pQuality = 0;
-		else if (SignalToNoiseRel < 30)
-			*pQuality = ((SignalToNoiseRel + 70) *
-				     BERQuality) / 100;
+		if (signal_to_noise_rel < -70)
+			*p_quality = 0;
+		else if (signal_to_noise_rel < 30)
+			*p_quality = ((signal_to_noise_rel + 70) *
+				     ber_quality) / 100;
 		else
-			*pQuality = BERQuality;
+			*p_quality = ber_quality;
 	} while (0);
 	return 0;
 };
 
-static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
+static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
 {
 	int status = 0;
-	*pQuality = 0;
+	*p_quality = 0;
 
 	dprintk(1, "\n");
 
 	do {
-		u32 SignalToNoise = 0;
-		u32 BERQuality = 100;
-		u32 SignalToNoiseRel = 0;
+		u32 signal_to_noise = 0;
+		u32 ber_quality = 100;
+		u32 signal_to_noise_rel = 0;
 
-		status = GetQAMSignalToNoise(state, &SignalToNoise);
+		status = get_qam_signal_to_noise(state, &signal_to_noise);
 		if (status < 0)
 			break;
 
 		switch (state->props.modulation) {
 		case QAM_16:
-			SignalToNoiseRel = SignalToNoise - 200;
+			signal_to_noise_rel = signal_to_noise - 200;
 			break;
 		case QAM_32:
-			SignalToNoiseRel = SignalToNoise - 230;
+			signal_to_noise_rel = signal_to_noise - 230;
 			break;	/* Not in NorDig */
 		case QAM_64:
-			SignalToNoiseRel = SignalToNoise - 260;
+			signal_to_noise_rel = signal_to_noise - 260;
 			break;
 		case QAM_128:
-			SignalToNoiseRel = SignalToNoise - 290;
+			signal_to_noise_rel = signal_to_noise - 290;
 			break;
 		default:
 		case QAM_256:
-			SignalToNoiseRel = SignalToNoise - 320;
+			signal_to_noise_rel = signal_to_noise - 320;
 			break;
 		}
 
-		if (SignalToNoiseRel < -70)
-			*pQuality = 0;
-		else if (SignalToNoiseRel < 30)
-			*pQuality = ((SignalToNoiseRel + 70) *
-				     BERQuality) / 100;
+		if (signal_to_noise_rel < -70)
+			*p_quality = 0;
+		else if (signal_to_noise_rel < 30)
+			*p_quality = ((signal_to_noise_rel + 70) *
+				     ber_quality) / 100;
 		else
-			*pQuality = BERQuality;
+			*p_quality = ber_quality;
 	} while (0);
 
 	return status;
 }
 
-static int GetQuality(struct drxk_state *state, s32 *pQuality)
+static int get_quality(struct drxk_state *state, s32 *p_quality)
 {
 	dprintk(1, "\n");
 
-	switch (state->m_OperationMode) {
+	switch (state->m_operation_mode) {
 	case OM_DVBT:
-		return GetDVBTQuality(state, pQuality);
+		return get_dvbt_quality(state, p_quality);
 	case OM_QAM_ITU_A:
-		return GetDVBCQuality(state, pQuality);
+		return get_dvbc_quality(state, p_quality);
 	default:
 		break;
 	}
@@ -2797,65 +2751,68 @@ static int GetQuality(struct drxk_state
 #define DRXDAP_FASI_ADDR2BANK(addr)   (((addr) >> 16) & 0x3F)
 #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
 
-static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
+static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
 {
 	int status = -EINVAL;
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return 0;
-	if (state->m_DrxkState == DRXK_POWERED_DOWN)
+	if (state->m_drxk_state == DRXK_POWERED_DOWN)
 		goto error;
 
 	if (state->no_i2c_bridge)
 		return 0;
 
-	status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
+	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
+			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
 	if (status < 0)
 		goto error;
-	if (bEnableBridge) {
-		status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
+	if (b_enable_bridge) {
+		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
+				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
 		if (status < 0)
 			goto error;
 	} else {
-		status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
+		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
+				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
 		if (status < 0)
 			goto error;
 	}
 
-	status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
+	status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetPreSaw(struct drxk_state *state,
-		     struct SCfgPreSaw *pPreSawCfg)
+static int set_pre_saw(struct drxk_state *state,
+		     struct s_cfg_pre_saw *p_pre_saw_cfg)
 {
 	int status = -EINVAL;
 
 	dprintk(1, "\n");
 
-	if ((pPreSawCfg == NULL)
-	    || (pPreSawCfg->reference > IQM_AF_PDREF__M))
+	if ((p_pre_saw_cfg == NULL)
+	    || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
 		goto error;
 
-	status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
+	status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
-		       u16 romOffset, u16 nrOfElements, u32 timeOut)
+static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
+		       u16 rom_offset, u16 nr_of_elements, u32 time_out)
 {
-	u16 blStatus = 0;
-	u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
-	u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
+	u16 bl_status = 0;
+	u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
+	u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
 	int status;
 	unsigned long end;
 
@@ -2871,44 +2828,44 @@ static int BLDirectCmd(struct drxk_state
 	status = write16(state, SIO_BL_TGT_ADDR__A, offset);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
+	status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
+	status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
 	if (status < 0)
 		goto error;
 
-	end = jiffies + msecs_to_jiffies(timeOut);
+	end = jiffies + msecs_to_jiffies(time_out);
 	do {
-		status = read16(state, SIO_BL_STATUS__A, &blStatus);
+		status = read16(state, SIO_BL_STATUS__A, &bl_status);
 		if (status < 0)
 			goto error;
-	} while ((blStatus == 0x1) && time_is_after_jiffies(end));
-	if (blStatus == 0x1) {
-		printk(KERN_ERR "drxk: SIO not ready\n");
+	} while ((bl_status == 0x1) && time_is_after_jiffies(end));
+	if (bl_status == 0x1) {
+		pr_err("SIO not ready\n");
 		status = -EINVAL;
 		goto error2;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 error2:
 	mutex_unlock(&state->mutex);
 	return status;
 
 }
 
-static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
+static int adc_sync_measurement(struct drxk_state *state, u16 *count)
 {
 	u16 data = 0;
 	int status;
 
 	dprintk(1, "\n");
 
-	/* Start measurement */
+	/* start measurement */
 	status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
 	if (status < 0)
 		goto error;
@@ -2935,42 +2892,42 @@ static int ADCSyncMeasurement(struct drx
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int ADCSynchronization(struct drxk_state *state)
+static int adc_synchronization(struct drxk_state *state)
 {
 	u16 count = 0;
 	int status;
 
 	dprintk(1, "\n");
 
-	status = ADCSyncMeasurement(state, &count);
+	status = adc_sync_measurement(state, &count);
 	if (status < 0)
 		goto error;
 
 	if (count == 1) {
 		/* Try sampling on a diffrent edge */
-		u16 clkNeg = 0;
+		u16 clk_neg = 0;
 
-		status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
+		status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
 		if (status < 0)
 			goto error;
-		if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
+		if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
 			IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
-			clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
-			clkNeg |=
+			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
+			clk_neg |=
 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
 		} else {
-			clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
-			clkNeg |=
+			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
+			clk_neg |=
 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
 		}
-		status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
+		status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
 		if (status < 0)
 			goto error;
-		status = ADCSyncMeasurement(state, &count);
+		status = adc_sync_measurement(state, &count);
 		if (status < 0)
 			goto error;
 	}
@@ -2979,25 +2936,25 @@ static int ADCSynchronization(struct drx
 		status = -EINVAL;
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetFrequencyShifter(struct drxk_state *state,
-			       u16 intermediateFreqkHz,
-			       s32 tunerFreqOffset, bool isDTV)
+static int set_frequency_shifter(struct drxk_state *state,
+			       u16 intermediate_freqk_hz,
+			       s32 tuner_freq_offset, bool is_dtv)
 {
-	bool selectPosImage = false;
-	u32 rfFreqResidual = tunerFreqOffset;
-	u32 fmFrequencyShift = 0;
-	bool tunerMirror = !state->m_bMirrorFreqSpect;
-	u32 adcFreq;
-	bool adcFlip;
+	bool select_pos_image = false;
+	u32 rf_freq_residual = tuner_freq_offset;
+	u32 fm_frequency_shift = 0;
+	bool tuner_mirror = !state->m_b_mirror_freq_spect;
+	u32 adc_freq;
+	bool adc_flip;
 	int status;
-	u32 ifFreqActual;
-	u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
-	u32 frequencyShift;
-	bool imageToSelect;
+	u32 if_freq_actual;
+	u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
+	u32 frequency_shift;
+	bool image_to_select;
 
 	dprintk(1, "\n");
 
@@ -3005,121 +2962,125 @@ static int SetFrequencyShifter(struct dr
 	   Program frequency shifter
 	   No need to account for mirroring on RF
 	 */
-	if (isDTV) {
-		if ((state->m_OperationMode == OM_QAM_ITU_A) ||
-		    (state->m_OperationMode == OM_QAM_ITU_C) ||
-		    (state->m_OperationMode == OM_DVBT))
-			selectPosImage = true;
+	if (is_dtv) {
+		if ((state->m_operation_mode == OM_QAM_ITU_A) ||
+		    (state->m_operation_mode == OM_QAM_ITU_C) ||
+		    (state->m_operation_mode == OM_DVBT))
+			select_pos_image = true;
 		else
-			selectPosImage = false;
+			select_pos_image = false;
 	}
-	if (tunerMirror)
+	if (tuner_mirror)
 		/* tuner doesn't mirror */
-		ifFreqActual = intermediateFreqkHz +
-		    rfFreqResidual + fmFrequencyShift;
+		if_freq_actual = intermediate_freqk_hz +
+		    rf_freq_residual + fm_frequency_shift;
 	else
 		/* tuner mirrors */
-		ifFreqActual = intermediateFreqkHz -
-		    rfFreqResidual - fmFrequencyShift;
-	if (ifFreqActual > samplingFrequency / 2) {
+		if_freq_actual = intermediate_freqk_hz -
+		    rf_freq_residual - fm_frequency_shift;
+	if (if_freq_actual > sampling_frequency / 2) {
 		/* adc mirrors */
-		adcFreq = samplingFrequency - ifFreqActual;
-		adcFlip = true;
+		adc_freq = sampling_frequency - if_freq_actual;
+		adc_flip = true;
 	} else {
 		/* adc doesn't mirror */
-		adcFreq = ifFreqActual;
-		adcFlip = false;
+		adc_freq = if_freq_actual;
+		adc_flip = false;
 	}
 
-	frequencyShift = adcFreq;
-	imageToSelect = state->m_rfmirror ^ tunerMirror ^
-	    adcFlip ^ selectPosImage;
-	state->m_IqmFsRateOfs =
-	    Frac28a((frequencyShift), samplingFrequency);
+	frequency_shift = adc_freq;
+	image_to_select = state->m_rfmirror ^ tuner_mirror ^
+	    adc_flip ^ select_pos_image;
+	state->m_iqm_fs_rate_ofs =
+	    Frac28a((frequency_shift), sampling_frequency);
 
-	if (imageToSelect)
-		state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
+	if (image_to_select)
+		state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
 
 	/* Program frequency shifter with tuner offset compensation */
-	/* frequencyShift += tunerFreqOffset; TODO */
+	/* frequency_shift += tuner_freq_offset; TODO */
 	status = write32(state, IQM_FS_RATE_OFS_LO__A,
-			 state->m_IqmFsRateOfs);
+			 state->m_iqm_fs_rate_ofs);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int InitAGC(struct drxk_state *state, bool isDTV)
+static int init_agc(struct drxk_state *state, bool is_dtv)
 {
-	u16 ingainTgt = 0;
-	u16 ingainTgtMin = 0;
-	u16 ingainTgtMax = 0;
-	u16 clpCyclen = 0;
-	u16 clpSumMin = 0;
-	u16 clpDirTo = 0;
-	u16 snsSumMin = 0;
-	u16 snsSumMax = 0;
-	u16 clpSumMax = 0;
-	u16 snsDirTo = 0;
-	u16 kiInnergainMin = 0;
-	u16 ifIaccuHiTgt = 0;
-	u16 ifIaccuHiTgtMin = 0;
-	u16 ifIaccuHiTgtMax = 0;
+	u16 ingain_tgt = 0;
+	u16 ingain_tgt_min = 0;
+	u16 ingain_tgt_max = 0;
+	u16 clp_cyclen = 0;
+	u16 clp_sum_min = 0;
+	u16 clp_dir_to = 0;
+	u16 sns_sum_min = 0;
+	u16 sns_sum_max = 0;
+	u16 clp_sum_max = 0;
+	u16 sns_dir_to = 0;
+	u16 ki_innergain_min = 0;
+	u16 if_iaccu_hi_tgt = 0;
+	u16 if_iaccu_hi_tgt_min = 0;
+	u16 if_iaccu_hi_tgt_max = 0;
 	u16 data = 0;
-	u16 fastClpCtrlDelay = 0;
-	u16 clpCtrlMode = 0;
+	u16 fast_clp_ctrl_delay = 0;
+	u16 clp_ctrl_mode = 0;
 	int status = 0;
 
 	dprintk(1, "\n");
 
 	/* Common settings */
-	snsSumMax = 1023;
-	ifIaccuHiTgtMin = 2047;
-	clpCyclen = 500;
-	clpSumMax = 1023;
+	sns_sum_max = 1023;
+	if_iaccu_hi_tgt_min = 2047;
+	clp_cyclen = 500;
+	clp_sum_max = 1023;
 
 	/* AGCInit() not available for DVBT; init done in microcode */
-	if (!IsQAM(state)) {
-		printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
+	if (!is_qam(state)) {
+		pr_err("%s: mode %d is not DVB-C\n",
+		       __func__, state->m_operation_mode);
 		return -EINVAL;
 	}
 
 	/* FIXME: Analog TV AGC require different settings */
 
 	/* Standard specific settings */
-	clpSumMin = 8;
-	clpDirTo = (u16) -9;
-	clpCtrlMode = 0;
-	snsSumMin = 8;
-	snsDirTo = (u16) -9;
-	kiInnergainMin = (u16) -1030;
-	ifIaccuHiTgtMax = 0x2380;
-	ifIaccuHiTgt = 0x2380;
-	ingainTgtMin = 0x0511;
-	ingainTgt = 0x0511;
-	ingainTgtMax = 5119;
-	fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
+	clp_sum_min = 8;
+	clp_dir_to = (u16) -9;
+	clp_ctrl_mode = 0;
+	sns_sum_min = 8;
+	sns_dir_to = (u16) -9;
+	ki_innergain_min = (u16) -1030;
+	if_iaccu_hi_tgt_max = 0x2380;
+	if_iaccu_hi_tgt = 0x2380;
+	ingain_tgt_min = 0x0511;
+	ingain_tgt = 0x0511;
+	ingain_tgt_max = 5119;
+	fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
 
-	status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
+	status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
+			 fast_clp_ctrl_delay);
 	if (status < 0)
 		goto error;
 
-	status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
+	status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
+	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
+			 if_iaccu_hi_tgt_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
+	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+			 if_iaccu_hi_tgt_max);
 	if (status < 0)
 		goto error;
 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
@@ -3134,20 +3095,22 @@ static int InitAGC(struct drxk_state *st
 	status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
+	status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
+	status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
 	if (status < 0)
 		goto error;
 
-	status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
+	status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
+			 ki_innergain_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
+	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
+			 if_iaccu_hi_tgt);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
+	status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
 	if (status < 0)
 		goto error;
 
@@ -3164,16 +3127,16 @@ static int InitAGC(struct drxk_state *st
 	status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
+	status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
+	status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
+	status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
+	status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
 	if (status < 0)
 		goto error;
 	status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
@@ -3233,38 +3196,39 @@ static int InitAGC(struct drxk_state *st
 	status = write16(state, SCU_RAM_AGC_KI__A, data);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
+static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
 {
 	int status;
 
 	dprintk(1, "\n");
-	if (packetErr == NULL)
+	if (packet_err == NULL)
 		status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
 	else
-		status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
+		status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
+				packet_err);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int DVBTScCommand(struct drxk_state *state,
+static int dvbt_sc_command(struct drxk_state *state,
 			 u16 cmd, u16 subcmd,
 			 u16 param0, u16 param1, u16 param2,
 			 u16 param3, u16 param4)
 {
-	u16 curCmd = 0;
-	u16 errCode = 0;
-	u16 retryCnt = 0;
-	u16 scExec = 0;
+	u16 cur_cmd = 0;
+	u16 err_code = 0;
+	u16 retry_cnt = 0;
+	u16 sc_exec = 0;
 	int status;
 
 	dprintk(1, "\n");
-	status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
-	if (scExec != 1) {
+	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
+	if (sc_exec != 1) {
 		/* SC is not running */
 		status = -EINVAL;
 	}
@@ -3272,13 +3236,13 @@ static int DVBTScCommand(struct drxk_sta
 		goto error;
 
 	/* Wait until sc is ready to receive command */
-	retryCnt = 0;
+	retry_cnt = 0;
 	do {
-		msleep(1);
-		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
-		retryCnt++;
-	} while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
-	if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
+		usleep_range(1000, 2000);
+		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
+		retry_cnt++;
+	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
+	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
 		goto error;
 
 	/* Write sub-command */
@@ -3324,18 +3288,18 @@ static int DVBTScCommand(struct drxk_sta
 		goto error;
 
 	/* Wait until sc is ready processing command */
-	retryCnt = 0;
+	retry_cnt = 0;
 	do {
-		msleep(1);
-		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
-		retryCnt++;
-	} while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
-	if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
+		usleep_range(1000, 2000);
+		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
+		retry_cnt++;
+	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
+	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
 		goto error;
 
 	/* Check for illegal cmd */
-	status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
-	if (errCode == 0xFFFF) {
+	status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
+	if (err_code == 0xFFFF) {
 		/* illegal command */
 		status = -EINVAL;
 	}
@@ -3367,23 +3331,23 @@ static int DVBTScCommand(struct drxk_sta
 	}			/* switch (cmd->cmd) */
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int PowerUpDVBT(struct drxk_state *state)
+static int power_up_dvbt(struct drxk_state *state)
 {
-	enum DRXPowerMode powerMode = DRX_POWER_UP;
+	enum drx_power_mode power_mode = DRX_POWER_UP;
 	int status;
 
 	dprintk(1, "\n");
-	status = CtrlPowerMode(state, &powerMode);
+	status = ctrl_power_mode(state, &power_mode);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
+static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
 {
 	int status;
 
@@ -3393,12 +3357,12 @@ static int DVBTCtrlSetIncEnable(struct d
 	else
 		status = write16(state, IQM_CF_BYPASSDET__A, 1);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
 #define DEFAULT_FR_THRES_8K     4000
-static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
+static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
 {
 
 	int status;
@@ -3413,13 +3377,13 @@ static int DVBTCtrlSetFrEnable(struct dr
 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
 	}
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
-				    struct DRXKCfgDvbtEchoThres_t *echoThres)
+static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
+				struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
 {
 	u16 data = 0;
 	int status;
@@ -3429,16 +3393,16 @@ static int DVBTCtrlSetEchoThreshold(stru
 	if (status < 0)
 		goto error;
 
-	switch (echoThres->fftMode) {
+	switch (echo_thres->fft_mode) {
 	case DRX_FFTMODE_2K:
 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
-		data |= ((echoThres->threshold <<
+		data |= ((echo_thres->threshold <<
 			OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
 			& (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
 		break;
 	case DRX_FFTMODE_8K:
 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
-		data |= ((echoThres->threshold <<
+		data |= ((echo_thres->threshold <<
 			OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
 			& (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
 		break;
@@ -3449,12 +3413,12 @@ static int DVBTCtrlSetEchoThreshold(stru
 	status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
-			       enum DRXKCfgDvbtSqiSpeed *speed)
+static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
+			       enum drxk_cfg_dvbt_sqi_speed *speed)
 {
 	int status = -EINVAL;
 
@@ -3472,7 +3436,7 @@ static int DVBTCtrlSetSqiSpeed(struct dr
 			   (u16) *speed);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -3486,32 +3450,33 @@ error:
 * Called in DVBTSetStandard
 *
 */
-static int DVBTActivatePresets(struct drxk_state *state)
+static int dvbt_activate_presets(struct drxk_state *state)
 {
 	int status;
 	bool setincenable = false;
 	bool setfrenable = true;
 
-	struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
-	struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
+	struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
+	struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
 
 	dprintk(1, "\n");
-	status = DVBTCtrlSetIncEnable(state, &setincenable);
+	status = dvbt_ctrl_set_inc_enable(state, &setincenable);
 	if (status < 0)
 		goto error;
-	status = DVBTCtrlSetFrEnable(state, &setfrenable);
+	status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
 	if (status < 0)
 		goto error;
-	status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
+	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
 	if (status < 0)
 		goto error;
-	status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
+	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
+			 state->m_dvbt_if_agc_cfg.ingain_tgt_max);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -3525,25 +3490,30 @@ error:
 * For ROM code channel filter taps are loaded from the bootloader. For microcode
 * the DVB-T taps from the drxk_filters.h are used.
 */
-static int SetDVBTStandard(struct drxk_state *state,
-			   enum OperationMode oMode)
+static int set_dvbt_standard(struct drxk_state *state,
+			   enum operation_mode o_mode)
 {
-	u16 cmdResult = 0;
+	u16 cmd_result = 0;
 	u16 data = 0;
 	int status;
 
 	dprintk(1, "\n");
 
-	PowerUpDVBT(state);
+	power_up_dvbt(state);
 	/* added antenna switch */
-	SwitchAntennaToDVBT(state);
+	switch_antenna_to_dvbt(state);
 	/* send OFDM reset command */
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+	status = scu_command(state,
+			     SCU_RAM_COMMAND_STANDARD_OFDM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
+			     0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
 	/* send OFDM setenv command */
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
+			     0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
@@ -3575,7 +3545,7 @@ static int SetDVBTStandard(struct drxk_s
 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
 	if (status < 0)
 		goto error;
-	status = SetIqmAf(state, true);
+	status = set_iqm_af(state, true);
 	if (status < 0)
 		goto error;
 
@@ -3597,7 +3567,7 @@ static int SetDVBTStandard(struct drxk_s
 	status = write16(state, IQM_RC_STRETCH__A, 16);
 	if (status < 0)
 		goto error;
-	status = write16(state, IQM_CF_OUT_ENA__A, 0x4);	/* enable output 2 */
+	status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
 	if (status < 0)
 		goto error;
 	status = write16(state, IQM_CF_DS_ENA__A, 0x4);	/* decimate output 2 */
@@ -3618,7 +3588,8 @@ static int SetDVBTStandard(struct drxk_s
 	if (status < 0)
 		goto error;
 
-	status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+	status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT,
+			      DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
 	if (status < 0)
 		goto error;
 
@@ -3637,10 +3608,10 @@ static int SetDVBTStandard(struct drxk_s
 		goto error;
 
 	/* IQM will not be reset from here, sync ADC and update/init AGC */
-	status = ADCSynchronization(state);
+	status = adc_synchronization(state);
 	if (status < 0)
 		goto error;
-	status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
+	status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
 	if (status < 0)
 		goto error;
 
@@ -3649,10 +3620,10 @@ static int SetDVBTStandard(struct drxk_s
 	if (status < 0)
 		goto error;
 
-	status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
+	status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
 	if (status < 0)
 		goto error;
-	status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
+	status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
 	if (status < 0)
 		goto error;
 
@@ -3670,9 +3641,10 @@ static int SetDVBTStandard(struct drxk_s
 	if (status < 0)
 		goto error;
 
-	if (!state->m_DRXK_A3_ROM_CODE) {
-		/* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay  */
-		status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
+	if (!state->m_drxk_a3_rom_code) {
+		/* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay  */
+		status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
+				 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
 		if (status < 0)
 			goto error;
 	}
@@ -3707,41 +3679,43 @@ static int SetDVBTStandard(struct drxk_s
 		goto error;
 
 	/* Setup MPEG bus */
-	status = MPEGTSDtoSetup(state, OM_DVBT);
+	status = mpegts_dto_setup(state, OM_DVBT);
 	if (status < 0)
 		goto error;
 	/* Set DVBT Presets */
-	status = DVBTActivatePresets(state);
+	status = dvbt_activate_presets(state);
 	if (status < 0)
 		goto error;
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
 /*============================================================================*/
 /**
-* \brief Start dvbt demodulating for channel.
+* \brief start dvbt demodulating for channel.
 * \param demod instance of demodulator.
 * \return DRXStatus_t.
 */
-static int DVBTStart(struct drxk_state *state)
+static int dvbt_start(struct drxk_state *state)
 {
 	u16 param1;
 	int status;
-	/* DRXKOfdmScCmd_t scCmd; */
+	/* drxk_ofdm_sc_cmd_t scCmd; */
 
 	dprintk(1, "\n");
-	/* Start correct processes to get in lock */
+	/* start correct processes to get in lock */
 	/* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
 	param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
-	status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
+	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0,
+				 OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1,
+				 0, 0, 0);
 	if (status < 0)
 		goto error;
-	/* Start FEC OC */
-	status = MPEGTSStart(state);
+	/* start FEC OC */
+	status = mpegts_start(state);
 	if (status < 0)
 		goto error;
 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
@@ -3749,7 +3723,7 @@ static int DVBTStart(struct drxk_state *
 		goto error;
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -3762,20 +3736,23 @@ error:
 * \return DRXStatus_t.
 * // original DVBTSetChannel()
 */
-static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
-		   s32 tunerFreqOffset)
+static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
+		   s32 tuner_freq_offset)
 {
-	u16 cmdResult = 0;
-	u16 transmissionParams = 0;
-	u16 operationMode = 0;
-	u32 iqmRcRateOfs = 0;
+	u16 cmd_result = 0;
+	u16 transmission_params = 0;
+	u16 operation_mode = 0;
+	u32 iqm_rc_rate_ofs = 0;
 	u32 bandwidth = 0;
 	u16 param1;
 	int status;
 
-	dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
+	dprintk(1, "IF =%d, TFO = %d\n",
+		intermediate_freqk_hz, tuner_freq_offset);
 
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
+			    | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
+			    0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
@@ -3798,19 +3775,19 @@ static int SetDVBT(struct drxk_state *st
 	if (status < 0)
 		goto error;
 
-	/*== Write channel settings to device =====================================*/
+	/*== Write channel settings to device ================================*/
 
 	/* mode */
 	switch (state->props.transmission_mode) {
 	case TRANSMISSION_MODE_AUTO:
 	default:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
 		/* fall through , try first guess DRX_FFTMODE_8K */
 	case TRANSMISSION_MODE_8K:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
 		break;
 	case TRANSMISSION_MODE_2K:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
 		break;
 	}
 
@@ -3818,19 +3795,19 @@ static int SetDVBT(struct drxk_state *st
 	switch (state->props.guard_interval) {
 	default:
 	case GUARD_INTERVAL_AUTO:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
 		/* fall through , try first guess DRX_GUARD_1DIV4 */
 	case GUARD_INTERVAL_1_4:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
 		break;
 	case GUARD_INTERVAL_1_32:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
 		break;
 	case GUARD_INTERVAL_1_16:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
 		break;
 	case GUARD_INTERVAL_1_8:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
 		break;
 	}
 
@@ -3839,18 +3816,18 @@ static int SetDVBT(struct drxk_state *st
 	case HIERARCHY_AUTO:
 	case HIERARCHY_NONE:
 	default:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
 		/* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
-		/* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
+		/* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
 		/* break; */
 	case HIERARCHY_1:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
 		break;
 	case HIERARCHY_2:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
 		break;
 	case HIERARCHY_4:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
 		break;
 	}
 
@@ -3859,16 +3836,16 @@ static int SetDVBT(struct drxk_state *st
 	switch (state->props.modulation) {
 	case QAM_AUTO:
 	default:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
 		/* fall through , try first guess DRX_CONSTELLATION_QAM64 */
 	case QAM_64:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
 		break;
 	case QPSK:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
 		break;
 	case QAM_16:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
 		break;
 	}
 #if 0
@@ -3876,13 +3853,13 @@ static int SetDVBT(struct drxk_state *st
 	/* Priority (only for hierarchical channels) */
 	switch (channel->priority) {
 	case DRX_PRIORITY_LOW:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
-		WR16(devAddr, OFDM_EC_SB_PRIOR__A,
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
+		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
 			OFDM_EC_SB_PRIOR_LO);
 		break;
 	case DRX_PRIORITY_HIGH:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
-		WR16(devAddr, OFDM_EC_SB_PRIOR__A,
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
+		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
 			OFDM_EC_SB_PRIOR_HI));
 		break;
 	case DRX_PRIORITY_UNKNOWN:	/* fall through */
@@ -3892,7 +3869,7 @@ static int SetDVBT(struct drxk_state *st
 	}
 #else
 	/* Set Priorty high */
-	transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
+	transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
 	status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
 	if (status < 0)
 		goto error;
@@ -3902,90 +3879,111 @@ static int SetDVBT(struct drxk_state *st
 	switch (state->props.code_rate_HP) {
 	case FEC_AUTO:
 	default:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
 		/* fall through , try first guess DRX_CODERATE_2DIV3 */
 	case FEC_2_3:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
 		break;
 	case FEC_1_2:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
 		break;
 	case FEC_3_4:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
 		break;
 	case FEC_5_6:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
 		break;
 	case FEC_7_8:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
 		break;
 	}
 
-	/* SAW filter selection: normaly not necesarry, but if wanted
-		the application can select a SAW filter via the driver by using UIOs */
+	/*
+	 * SAW filter selection: normaly not necesarry, but if wanted
+	 * the application can select a SAW filter via the driver by
+	 * using UIOs
+	 */
+
 	/* First determine real bandwidth (Hz) */
 	/* Also set delay for impulse noise cruncher */
-	/* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
-		by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
-		functions */
+	/*
+	 * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
+	 * changed by SC for fix for some 8K,1/8 guard but is restored by
+	 * InitEC and ResetEC functions
+	 */
 	switch (state->props.bandwidth_hz) {
 	case 0:
 		state->props.bandwidth_hz = 8000000;
 		/* fall though */
 	case 8000000:
 		bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
-		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
+		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
+				 3052);
 		if (status < 0)
 			goto error;
 		/* cochannel protection for PAL 8 MHz */
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
+				 7);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
+				 7);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
+				 7);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
+				 1);
 		if (status < 0)
 			goto error;
 		break;
 	case 7000000:
 		bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
-		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
+		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
+				 3491);
 		if (status < 0)
 			goto error;
 		/* cochannel protection for PAL 7 MHz */
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
+				 8);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
+				 8);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
+				 4);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
+				 1);
 		if (status < 0)
 			goto error;
 		break;
 	case 6000000:
 		bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
-		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
+		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
+				 4073);
 		if (status < 0)
 			goto error;
 		/* cochannel protection for NTSC 6 MHz */
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
+				 19);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
+				 19);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
+				 14);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
+				 1);
 		if (status < 0)
 			goto error;
 		break;
@@ -3994,46 +3992,50 @@ static int SetDVBT(struct drxk_state *st
 		goto error;
 	}
 
-	if (iqmRcRateOfs == 0) {
+	if (iqm_rc_rate_ofs == 0) {
 		/* Now compute IQM_RC_RATE_OFS
 			(((SysFreq/BandWidth)/2)/2) -1) * 2^23)
 			=>
 			((SysFreq / BandWidth) * (2^21)) - (2^23)
 			*/
 		/* (SysFreq / BandWidth) * (2^28)  */
-		/* assert (MAX(sysClk)/MIN(bandwidth) < 16)
-			=> assert(MAX(sysClk) < 16*MIN(bandwidth))
-			=> assert(109714272 > 48000000) = true so Frac 28 can be used  */
-		iqmRcRateOfs = Frac28a((u32)
-					((state->m_sysClockFreq *
+		/*
+		 * assert (MAX(sysClk)/MIN(bandwidth) < 16)
+		 *	=> assert(MAX(sysClk) < 16*MIN(bandwidth))
+		 *	=> assert(109714272 > 48000000) = true
+		 * so Frac 28 can be used
+		 */
+		iqm_rc_rate_ofs = Frac28a((u32)
+					((state->m_sys_clock_freq *
 						1000) / 3), bandwidth);
-		/* (SysFreq / BandWidth) * (2^21), rounding before truncating  */
-		if ((iqmRcRateOfs & 0x7fL) >= 0x40)
-			iqmRcRateOfs += 0x80L;
-		iqmRcRateOfs = iqmRcRateOfs >> 7;
+		/* (SysFreq / BandWidth) * (2^21), rounding before truncating */
+		if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
+			iqm_rc_rate_ofs += 0x80L;
+		iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
 		/* ((SysFreq / BandWidth) * (2^21)) - (2^23)  */
-		iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
+		iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
 	}
 
-	iqmRcRateOfs &=
+	iqm_rc_rate_ofs &=
 		((((u32) IQM_RC_RATE_OFS_HI__M) <<
 		IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
-	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
+	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
 	if (status < 0)
 		goto error;
 
 	/* Bandwidth setting done */
 
 #if 0
-	status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
+	status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
 	if (status < 0)
 		goto error;
 #endif
-	status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
+	status = set_frequency_shifter(state, intermediate_freqk_hz,
+				       tuner_freq_offset, true);
 	if (status < 0)
 		goto error;
 
-	/*== Start SC, write channel settings to SC ===============================*/
+	/*== start SC, write channel settings to SC ==========================*/
 
 	/* Activate SCU to enable SCU commands */
 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
@@ -4049,7 +4051,9 @@ static int SetDVBT(struct drxk_state *st
 		goto error;
 
 
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
+			     0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
@@ -4059,16 +4063,16 @@ static int SetDVBT(struct drxk_state *st
 			OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
 			OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
 			OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
-	status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
-				0, transmissionParams, param1, 0, 0, 0);
+	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
+				0, transmission_params, param1, 0, 0, 0);
 	if (status < 0)
 		goto error;
 
-	if (!state->m_DRXK_A3_ROM_CODE)
-		status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
+	if (!state->m_drxk_a3_rom_code)
+		status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -4083,7 +4087,7 @@ error:
 * \return DRXStatus_t.
 *
 */
-static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
+static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
 {
 	int status;
 	const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
@@ -4091,58 +4095,58 @@ static int GetDVBTLockStatus(struct drxk
 	const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
 	const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
 
-	u16 ScRaRamLock = 0;
-	u16 ScCommExec = 0;
+	u16 sc_ra_ram_lock = 0;
+	u16 sc_comm_exec = 0;
 
 	dprintk(1, "\n");
 
-	*pLockStatus = NOT_LOCKED;
+	*p_lock_status = NOT_LOCKED;
 	/* driver 0.9.0 */
 	/* Check if SC is running */
-	status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
+	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
 	if (status < 0)
 		goto end;
-	if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
+	if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
 		goto end;
 
-	status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
+	status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
 	if (status < 0)
 		goto end;
 
-	if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
-		*pLockStatus = MPEG_LOCK;
-	else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
-		*pLockStatus = FEC_LOCK;
-	else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
-		*pLockStatus = DEMOD_LOCK;
-	else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
-		*pLockStatus = NEVER_LOCK;
+	if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
+		*p_lock_status = MPEG_LOCK;
+	else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
+		*p_lock_status = FEC_LOCK;
+	else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
+		*p_lock_status = DEMOD_LOCK;
+	else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
+		*p_lock_status = NEVER_LOCK;
 end:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int PowerUpQAM(struct drxk_state *state)
+static int power_up_qam(struct drxk_state *state)
 {
-	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
+	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
 	int status;
 
 	dprintk(1, "\n");
-	status = CtrlPowerMode(state, &powerMode);
+	status = ctrl_power_mode(state, &power_mode);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
 
 /** Power Down QAM */
-static int PowerDownQAM(struct drxk_state *state)
+static int power_down_qam(struct drxk_state *state)
 {
 	u16 data = 0;
-	u16 cmdResult;
+	u16 cmd_result;
 	int status = 0;
 
 	dprintk(1, "\n");
@@ -4158,16 +4162,18 @@ static int PowerDownQAM(struct drxk_stat
 		status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
 		if (status < 0)
 			goto error;
-		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
+				     0, NULL, 1, &cmd_result);
 		if (status < 0)
 			goto error;
 	}
 	/* powerdown AFE                   */
-	status = SetIqmAf(state, false);
+	status = set_iqm_af(state, false);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -4185,20 +4191,20 @@ error:
 *  The implementation does not check this.
 *
 */
-static int SetQAMMeasurement(struct drxk_state *state,
-			     enum EDrxkConstellation modulation,
-			     u32 symbolRate)
+static int set_qam_measurement(struct drxk_state *state,
+			     enum e_drxk_constellation modulation,
+			     u32 symbol_rate)
 {
-	u32 fecBitsDesired = 0;	/* BER accounting period */
-	u32 fecRsPeriodTotal = 0;	/* Total period */
-	u16 fecRsPrescale = 0;	/* ReedSolomon Measurement Prescale */
-	u16 fecRsPeriod = 0;	/* Value for corresponding I2C register */
+	u32 fec_bits_desired = 0;	/* BER accounting period */
+	u32 fec_rs_period_total = 0;	/* Total period */
+	u16 fec_rs_prescale = 0;	/* ReedSolomon Measurement Prescale */
+	u16 fec_rs_period = 0;	/* Value for corresponding I2C register */
 	int status = 0;
 
 	dprintk(1, "\n");
 
-	fecRsPrescale = 1;
-	/* fecBitsDesired = symbolRate [kHz] *
+	fec_rs_prescale = 1;
+	/* fec_bits_desired = symbol_rate [kHz] *
 		FrameLenght [ms] *
 		(modulation + 1) *
 		SyncLoss (== 1) *
@@ -4206,19 +4212,19 @@ static int SetQAMMeasurement(struct drxk
 		*/
 	switch (modulation) {
 	case DRX_CONSTELLATION_QAM16:
-		fecBitsDesired = 4 * symbolRate;
+		fec_bits_desired = 4 * symbol_rate;
 		break;
 	case DRX_CONSTELLATION_QAM32:
-		fecBitsDesired = 5 * symbolRate;
+		fec_bits_desired = 5 * symbol_rate;
 		break;
 	case DRX_CONSTELLATION_QAM64:
-		fecBitsDesired = 6 * symbolRate;
+		fec_bits_desired = 6 * symbol_rate;
 		break;
 	case DRX_CONSTELLATION_QAM128:
-		fecBitsDesired = 7 * symbolRate;
+		fec_bits_desired = 7 * symbol_rate;
 		break;
 	case DRX_CONSTELLATION_QAM256:
-		fecBitsDesired = 8 * symbolRate;
+		fec_bits_desired = 8 * symbol_rate;
 		break;
 	default:
 		status = -EINVAL;
@@ -4226,40 +4232,41 @@ static int SetQAMMeasurement(struct drxk
 	if (status < 0)
 		goto error;
 
-	fecBitsDesired /= 1000;	/* symbolRate [Hz] -> symbolRate [kHz]  */
-	fecBitsDesired *= 500;	/* meas. period [ms] */
+	fec_bits_desired /= 1000;	/* symbol_rate [Hz] -> symbol_rate [kHz] */
+	fec_bits_desired *= 500;	/* meas. period [ms] */
 
 	/* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
-	/* fecRsPeriodTotal = fecBitsDesired / 1632 */
-	fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1;	/* roughly ceil */
+	/* fec_rs_period_total = fec_bits_desired / 1632 */
+	fec_rs_period_total = (fec_bits_desired / 1632UL) + 1;	/* roughly ceil */
 
-	/* fecRsPeriodTotal =  fecRsPrescale * fecRsPeriod  */
-	fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
-	if (fecRsPrescale == 0) {
+	/* fec_rs_period_total =  fec_rs_prescale * fec_rs_period  */
+	fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
+	if (fec_rs_prescale == 0) {
 		/* Divide by zero (though impossible) */
 		status = -EINVAL;
 		if (status < 0)
 			goto error;
 	}
-	fecRsPeriod =
-		((u16) fecRsPeriodTotal +
-		(fecRsPrescale >> 1)) / fecRsPrescale;
+	fec_rs_period =
+		((u16) fec_rs_period_total +
+		(fec_rs_prescale >> 1)) / fec_rs_prescale;
 
 	/* write corresponding registers */
-	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
+	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
+	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A,
+			 fec_rs_prescale);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
+	status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetQAM16(struct drxk_state *state)
+static int set_qam16(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -4315,7 +4322,8 @@ static int SetQAM16(struct drxk_state *s
 		goto error;
 
 	/* QAM Slicer Settings */
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM16);
 	if (status < 0)
 		goto error;
 
@@ -4441,7 +4449,7 @@ static int SetQAM16(struct drxk_state *s
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -4452,7 +4460,7 @@ error:
 * \param demod instance of demod.
 * \return DRXStatus_t.
 */
-static int SetQAM32(struct drxk_state *state)
+static int set_qam32(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -4511,7 +4519,8 @@ static int SetQAM32(struct drxk_state *s
 
 	/* QAM Slicer Settings */
 
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM32);
 	if (status < 0)
 		goto error;
 
@@ -4636,7 +4645,7 @@ static int SetQAM32(struct drxk_state *s
 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -4647,7 +4656,7 @@ error:
 * \param demod instance of demod.
 * \return DRXStatus_t.
 */
-static int SetQAM64(struct drxk_state *state)
+static int set_qam64(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -4704,7 +4713,8 @@ static int SetQAM64(struct drxk_state *s
 		goto error;
 
 	/* QAM Slicer Settings */
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM64);
 	if (status < 0)
 		goto error;
 
@@ -4829,7 +4839,7 @@ static int SetQAM64(struct drxk_state *s
 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -4841,7 +4851,7 @@ error:
 * \param demod: instance of demod.
 * \return DRXStatus_t.
 */
-static int SetQAM128(struct drxk_state *state)
+static int set_qam128(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -4900,7 +4910,8 @@ static int SetQAM128(struct drxk_state *
 
 	/* QAM Slicer Settings */
 
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM128);
 	if (status < 0)
 		goto error;
 
@@ -5025,7 +5036,7 @@ static int SetQAM128(struct drxk_state *
 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -5037,7 +5048,7 @@ error:
 * \param demod: instance of demod.
 * \return DRXStatus_t.
 */
-static int SetQAM256(struct drxk_state *state)
+static int set_qam256(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -5095,7 +5106,8 @@ static int SetQAM256(struct drxk_state *
 
 	/* QAM Slicer Settings */
 
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM256);
 	if (status < 0)
 		goto error;
 
@@ -5220,7 +5232,7 @@ static int SetQAM256(struct drxk_state *
 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -5232,10 +5244,10 @@ error:
 * \param channel: pointer to channel data.
 * \return DRXStatus_t.
 */
-static int QAMResetQAM(struct drxk_state *state)
+static int qam_reset_qam(struct drxk_state *state)
 {
 	int status;
-	u16 cmdResult;
+	u16 cmd_result;
 
 	dprintk(1, "\n");
 	/* Stop QAM comstate->m_exec */
@@ -5243,10 +5255,12 @@ static int QAMResetQAM(struct drxk_state
 	if (status < 0)
 		goto error;
 
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
+			     0, NULL, 1, &cmd_result);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -5258,18 +5272,18 @@ error:
 * \param channel: pointer to channel data.
 * \return DRXStatus_t.
 */
-static int QAMSetSymbolrate(struct drxk_state *state)
+static int qam_set_symbolrate(struct drxk_state *state)
 {
-	u32 adcFrequency = 0;
-	u32 symbFreq = 0;
-	u32 iqmRcRate = 0;
+	u32 adc_frequency = 0;
+	u32 symb_freq = 0;
+	u32 iqm_rc_rate = 0;
 	u16 ratesel = 0;
-	u32 lcSymbRate = 0;
+	u32 lc_symb_rate = 0;
 	int status;
 
 	dprintk(1, "\n");
 	/* Select & calculate correct IQM rate */
-	adcFrequency = (state->m_sysClockFreq * 1000) / 3;
+	adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
 	ratesel = 0;
 	/* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
 	if (state->props.symbol_rate <= 1188750)
@@ -5285,38 +5299,38 @@ static int QAMSetSymbolrate(struct drxk_
 	/*
 		IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
 		*/
-	symbFreq = state->props.symbol_rate * (1 << ratesel);
-	if (symbFreq == 0) {
+	symb_freq = state->props.symbol_rate * (1 << ratesel);
+	if (symb_freq == 0) {
 		/* Divide by zero */
 		status = -EINVAL;
 		goto error;
 	}
-	iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
-		(Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
+	iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
+		(Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
 		(1 << 23);
-	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
+	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
 	if (status < 0)
 		goto error;
-	state->m_iqmRcRate = iqmRcRate;
+	state->m_iqm_rc_rate = iqm_rc_rate;
 	/*
-		LcSymbFreq = round (.125 *  symbolrate / adcFreq * (1<<15))
+		LcSymbFreq = round (.125 *  symbolrate / adc_freq * (1<<15))
 		*/
-	symbFreq = state->props.symbol_rate;
-	if (adcFrequency == 0) {
+	symb_freq = state->props.symbol_rate;
+	if (adc_frequency == 0) {
 		/* Divide by zero */
 		status = -EINVAL;
 		goto error;
 	}
-	lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
-		(Frac28a((symbFreq % adcFrequency), adcFrequency) >>
+	lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
+		(Frac28a((symb_freq % adc_frequency), adc_frequency) >>
 		16);
-	if (lcSymbRate > 511)
-		lcSymbRate = 511;
-	status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
+	if (lc_symb_rate > 511)
+		lc_symb_rate = 511;
+	status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -5329,34 +5343,36 @@ error:
 * \return DRXStatus_t.
 */
 
-static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
+static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
 {
 	int status;
-	u16 Result[2] = { 0, 0 };
+	u16 result[2] = { 0, 0 };
 
 	dprintk(1, "\n");
-	*pLockStatus = NOT_LOCKED;
+	*p_lock_status = NOT_LOCKED;
 	status = scu_command(state,
 			SCU_RAM_COMMAND_STANDARD_QAM |
 			SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
-			Result);
+			result);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
-	if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
+	if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
 		/* 0x0000 NOT LOCKED */
-	} else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
+	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
 		/* 0x4000 DEMOD LOCKED */
-		*pLockStatus = DEMOD_LOCK;
-	} else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
+		*p_lock_status = DEMOD_LOCK;
+	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
 		/* 0x8000 DEMOD + FEC LOCKED (system lock) */
-		*pLockStatus = MPEG_LOCK;
+		*p_lock_status = MPEG_LOCK;
 	} else {
 		/* 0xC000 NEVER LOCKED */
 		/* (system will never be able to lock to the signal) */
-		/* TODO: check this, intermediate & standard specific lock states are not
-		   taken into account here */
-		*pLockStatus = NEVER_LOCK;
+		/*
+		 * TODO: check this, intermediate & standard specific lock
+		 * states are not taken into account here
+		 */
+		*p_lock_status = NEVER_LOCK;
 	}
 	return status;
 }
@@ -5368,68 +5384,70 @@ static int GetQAMLockStatus(struct drxk_
 #define QAM_LOCKRANGE__M      0x10
 #define QAM_LOCKRANGE_NORMAL  0x10
 
-static int QAMDemodulatorCommand(struct drxk_state *state,
-				 int numberOfParameters)
+static int qam_demodulator_command(struct drxk_state *state,
+				 int number_of_parameters)
 {
 	int status;
-	u16 cmdResult;
-	u16 setParamParameters[4] = { 0, 0, 0, 0 };
+	u16 cmd_result;
+	u16 set_param_parameters[4] = { 0, 0, 0, 0 };
 
-	setParamParameters[0] = state->m_Constellation;	/* modulation     */
-	setParamParameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
+	set_param_parameters[0] = state->m_constellation;	/* modulation     */
+	set_param_parameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
 
-	if (numberOfParameters == 2) {
-		u16 setEnvParameters[1] = { 0 };
+	if (number_of_parameters == 2) {
+		u16 set_env_parameters[1] = { 0 };
 
-		if (state->m_OperationMode == OM_QAM_ITU_C)
-			setEnvParameters[0] = QAM_TOP_ANNEX_C;
+		if (state->m_operation_mode == OM_QAM_ITU_C)
+			set_env_parameters[0] = QAM_TOP_ANNEX_C;
 		else
-			setEnvParameters[0] = QAM_TOP_ANNEX_A;
+			set_env_parameters[0] = QAM_TOP_ANNEX_A;
 
 		status = scu_command(state,
-				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
-				     1, setEnvParameters, 1, &cmdResult);
+				     SCU_RAM_COMMAND_STANDARD_QAM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
+				     1, set_env_parameters, 1, &cmd_result);
 		if (status < 0)
 			goto error;
 
 		status = scu_command(state,
-				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
-				     numberOfParameters, setParamParameters,
-				     1, &cmdResult);
-	} else if (numberOfParameters == 4) {
-		if (state->m_OperationMode == OM_QAM_ITU_C)
-			setParamParameters[2] = QAM_TOP_ANNEX_C;
+				     SCU_RAM_COMMAND_STANDARD_QAM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
+				     number_of_parameters, set_param_parameters,
+				     1, &cmd_result);
+	} else if (number_of_parameters == 4) {
+		if (state->m_operation_mode == OM_QAM_ITU_C)
+			set_param_parameters[2] = QAM_TOP_ANNEX_C;
 		else
-			setParamParameters[2] = QAM_TOP_ANNEX_A;
+			set_param_parameters[2] = QAM_TOP_ANNEX_A;
 
-		setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
+		set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
 		/* Env parameters */
 		/* check for LOCKRANGE Extented */
-		/* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
+		/* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
 
 		status = scu_command(state,
-				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
-				     numberOfParameters, setParamParameters,
-				     1, &cmdResult);
+				     SCU_RAM_COMMAND_STANDARD_QAM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
+				     number_of_parameters, set_param_parameters,
+				     1, &cmd_result);
 	} else {
-		printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
-			"count %d\n", numberOfParameters);
+		pr_warn("Unknown QAM demodulator parameter count %d\n",
+			number_of_parameters);
 		status = -EINVAL;
 	}
 
 error:
 	if (status < 0)
-		printk(KERN_WARNING "drxk: Warning %d on %s\n",
-		       status, __func__);
+		pr_warn("Warning %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
-		  s32 tunerFreqOffset)
+static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
+		  s32 tuner_freq_offset)
 {
 	int status;
-	u16 cmdResult;
-	int qamDemodParamCount = state->qam_demod_parameter_count;
+	u16 cmd_result;
+	int qam_demod_param_count = state->qam_demod_parameter_count;
 
 	dprintk(1, "\n");
 	/*
@@ -5444,7 +5462,7 @@ static int SetQAM(struct drxk_state *sta
 	status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
 	if (status < 0)
 		goto error;
-	status = QAMResetQAM(state);
+	status = qam_reset_qam(state);
 	if (status < 0)
 		goto error;
 
@@ -5453,27 +5471,27 @@ static int SetQAM(struct drxk_state *sta
 	 *	-set params; resets IQM,QAM,FEC HW; initializes some
 	 *       SCU variables
 	 */
-	status = QAMSetSymbolrate(state);
+	status = qam_set_symbolrate(state);
 	if (status < 0)
 		goto error;
 
 	/* Set params */
 	switch (state->props.modulation) {
 	case QAM_256:
-		state->m_Constellation = DRX_CONSTELLATION_QAM256;
+		state->m_constellation = DRX_CONSTELLATION_QAM256;
 		break;
 	case QAM_AUTO:
 	case QAM_64:
-		state->m_Constellation = DRX_CONSTELLATION_QAM64;
+		state->m_constellation = DRX_CONSTELLATION_QAM64;
 		break;
 	case QAM_16:
-		state->m_Constellation = DRX_CONSTELLATION_QAM16;
+		state->m_constellation = DRX_CONSTELLATION_QAM16;
 		break;
 	case QAM_32:
-		state->m_Constellation = DRX_CONSTELLATION_QAM32;
+		state->m_constellation = DRX_CONSTELLATION_QAM32;
 		break;
 	case QAM_128:
-		state->m_Constellation = DRX_CONSTELLATION_QAM128;
+		state->m_constellation = DRX_CONSTELLATION_QAM128;
 		break;
 	default:
 		status = -EINVAL;
@@ -5486,8 +5504,8 @@ static int SetQAM(struct drxk_state *sta
 	 * the correct command. */
 	if (state->qam_demod_parameter_count == 4
 		|| !state->qam_demod_parameter_count) {
-		qamDemodParamCount = 4;
-		status = QAMDemodulatorCommand(state, qamDemodParamCount);
+		qam_demod_param_count = 4;
+		status = qam_demodulator_command(state, qam_demod_param_count);
 	}
 
 	/* Use the 2-parameter command if it was requested or if we're
@@ -5495,27 +5513,27 @@ static int SetQAM(struct drxk_state *sta
 	 * failed. */
 	if (state->qam_demod_parameter_count == 2
 		|| (!state->qam_demod_parameter_count && status < 0)) {
-		qamDemodParamCount = 2;
-		status = QAMDemodulatorCommand(state, qamDemodParamCount);
+		qam_demod_param_count = 2;
+		status = qam_demodulator_command(state, qam_demod_param_count);
 	}
 
 	if (status < 0) {
-		dprintk(1, "Could not set demodulator parameters. Make "
-			"sure qam_demod_parameter_count (%d) is correct for "
-			"your firmware (%s).\n",
+		dprintk(1, "Could not set demodulator parameters.\n");
+		dprintk(1,
+			"Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n",
 			state->qam_demod_parameter_count,
 			state->microcode_name);
 		goto error;
 	} else if (!state->qam_demod_parameter_count) {
-		dprintk(1, "Auto-probing the correct QAM demodulator command "
-			"parameters was successful - using %d parameters.\n",
-			qamDemodParamCount);
+		dprintk(1,
+			"Auto-probing the QAM command parameters was successful - using %d parameters.\n",
+			qam_demod_param_count);
 
 		/*
 		 * One of our commands was successful. We don't need to
 		 * auto-probe anymore, now that we got the correct command.
 		 */
-		state->qam_demod_parameter_count = qamDemodParamCount;
+		state->qam_demod_parameter_count = qam_demod_param_count;
 	}
 
 	/*
@@ -5523,16 +5541,18 @@ static int SetQAM(struct drxk_state *sta
 	 * signal setup modulation independent registers
 	 */
 #if 0
-	status = SetFrequency(channel, tunerFreqOffset));
+	status = set_frequency(channel, tuner_freq_offset));
 	if (status < 0)
 		goto error;
 #endif
-	status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
+	status = set_frequency_shifter(state, intermediate_freqk_hz,
+				       tuner_freq_offset, true);
 	if (status < 0)
 		goto error;
 
 	/* Setup BER measurement */
-	status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
+	status = set_qam_measurement(state, state->m_constellation,
+				     state->props.symbol_rate);
 	if (status < 0)
 		goto error;
 
@@ -5605,7 +5625,8 @@ static int SetQAM(struct drxk_state *sta
 		goto error;
 
 	/* Mirroring, QAM-block starting point not inverted */
-	status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
+	status = write16(state, QAM_SY_SP_INV__A,
+			 QAM_SY_SP_INV_SPECTRUM_INV_DIS);
 	if (status < 0)
 		goto error;
 
@@ -5617,20 +5638,20 @@ static int SetQAM(struct drxk_state *sta
 	/* STEP 4: modulation specific setup */
 	switch (state->props.modulation) {
 	case QAM_16:
-		status = SetQAM16(state);
+		status = set_qam16(state);
 		break;
 	case QAM_32:
-		status = SetQAM32(state);
+		status = set_qam32(state);
 		break;
 	case QAM_AUTO:
 	case QAM_64:
-		status = SetQAM64(state);
+		status = set_qam64(state);
 		break;
 	case QAM_128:
-		status = SetQAM128(state);
+		status = set_qam128(state);
 		break;
 	case QAM_256:
-		status = SetQAM256(state);
+		status = set_qam256(state);
 		break;
 	default:
 		status = -EINVAL;
@@ -5647,12 +5668,12 @@ static int SetQAM(struct drxk_state *sta
 	/* Re-configure MPEG output, requires knowledge of channel bitrate */
 	/* extAttr->currentChannel.modulation = channel->modulation; */
 	/* extAttr->currentChannel.symbolrate    = channel->symbolrate; */
-	status = MPEGTSDtoSetup(state, state->m_OperationMode);
+	status = mpegts_dto_setup(state, state->m_operation_mode);
 	if (status < 0)
 		goto error;
 
-	/* Start processes */
-	status = MPEGTSStart(state);
+	/* start processes */
+	status = mpegts_start(state);
 	if (status < 0)
 		goto error;
 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
@@ -5666,7 +5687,9 @@ static int SetQAM(struct drxk_state *sta
 		goto error;
 
 	/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
+			     0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
@@ -5675,12 +5698,12 @@ static int SetQAM(struct drxk_state *sta
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetQAMStandard(struct drxk_state *state,
-			  enum OperationMode oMode)
+static int set_qam_standard(struct drxk_state *state,
+			  enum operation_mode o_mode)
 {
 	int status;
 #ifdef DRXK_QAM_TAPS
@@ -5692,14 +5715,14 @@ static int SetQAMStandard(struct drxk_st
 	dprintk(1, "\n");
 
 	/* added antenna switch */
-	SwitchAntennaToQAM(state);
+	switch_antenna_to_qam(state);
 
 	/* Ensure correct power-up mode */
-	status = PowerUpQAM(state);
+	status = power_up_qam(state);
 	if (status < 0)
 		goto error;
 	/* Reset QAM block */
-	status = QAMResetQAM(state);
+	status = qam_reset_qam(state);
 	if (status < 0)
 		goto error;
 
@@ -5714,15 +5737,24 @@ static int SetQAMStandard(struct drxk_st
 
 	/* Upload IQM Channel Filter settings by
 		boot loader from ROM table */
-	switch (oMode) {
+	switch (o_mode) {
 	case OM_QAM_ITU_A:
-		status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+		status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
+				      DRXK_BLCC_NR_ELEMENTS_TAPS,
+			DRXK_BLC_TIMEOUT);
 		break;
 	case OM_QAM_ITU_C:
-		status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+		status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A,
+				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
+				       DRXK_BLDC_NR_ELEMENTS_TAPS,
+				       DRXK_BLC_TIMEOUT);
 		if (status < 0)
 			goto error;
-		status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+		status = bl_direct_cmd(state,
+				       IQM_CF_TAP_IM0__A,
+				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
+				       DRXK_BLDC_NR_ELEMENTS_TAPS,
+				       DRXK_BLC_TIMEOUT);
 		break;
 	default:
 		status = -EINVAL;
@@ -5730,13 +5762,14 @@ static int SetQAMStandard(struct drxk_st
 	if (status < 0)
 		goto error;
 
-	status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
+	status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B);
 	if (status < 0)
 		goto error;
 	status = write16(state, IQM_CF_SYMMETRIC__A, 0);
 	if (status < 0)
 		goto error;
-	status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
+	status = write16(state, IQM_CF_MIDTAP__A,
+		     ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
 	if (status < 0)
 		goto error;
 
@@ -5793,7 +5826,7 @@ static int SetQAMStandard(struct drxk_st
 		goto error;
 
 	/* turn on IQMAF. Must be done before setAgc**() */
-	status = SetIqmAf(state, true);
+	status = set_iqm_af(state, true);
 	if (status < 0)
 		goto error;
 	status = write16(state, IQM_AF_START_LOCK__A, 0x01);
@@ -5801,7 +5834,7 @@ static int SetQAMStandard(struct drxk_st
 		goto error;
 
 	/* IQM will not be reset from here, sync ADC and update/init AGC */
-	status = ADCSynchronization(state);
+	status = adc_synchronization(state);
 	if (status < 0)
 		goto error;
 
@@ -5818,18 +5851,18 @@ static int SetQAMStandard(struct drxk_st
 	/* No more resets of the IQM, current standard correctly set =>
 		now AGCs can be configured. */
 
-	status = InitAGC(state, true);
+	status = init_agc(state, true);
 	if (status < 0)
 		goto error;
-	status = SetPreSaw(state, &(state->m_qamPreSawCfg));
+	status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
 	if (status < 0)
 		goto error;
 
 	/* Configure AGC's */
-	status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
+	status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
 	if (status < 0)
 		goto error;
-	status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
+	status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
 	if (status < 0)
 		goto error;
 
@@ -5837,18 +5870,19 @@ static int SetQAMStandard(struct drxk_st
 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int WriteGPIO(struct drxk_state *state)
+static int write_gpio(struct drxk_state *state)
 {
 	int status;
 	u16 value = 0;
 
 	dprintk(1, "\n");
 	/* stop lock indicator process */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 
@@ -5857,10 +5891,11 @@ static int WriteGPIO(struct drxk_state *
 	if (status < 0)
 		goto error;
 
-	if (state->m_hasSAWSW) {
-		if (state->UIO_mask & 0x0001) { /* UIO-1 */
+	if (state->m_has_sawsw) {
+		if (state->uio_mask & 0x0001) { /* UIO-1 */
 			/* write to io pad configuration register - output mode */
-			status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
+			status = write16(state, SIO_PDR_SMA_TX_CFG__A,
+					 state->m_gpio_cfg);
 			if (status < 0)
 				goto error;
 
@@ -5868,7 +5903,7 @@ static int WriteGPIO(struct drxk_state *
 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
 			if (status < 0)
 				goto error;
-			if ((state->m_GPIO & 0x0001) == 0)
+			if ((state->m_gpio & 0x0001) == 0)
 				value &= 0x7FFF;	/* write zero to 15th bit - 1st UIO */
 			else
 				value |= 0x8000;	/* write one to 15th bit - 1st UIO */
@@ -5877,9 +5912,10 @@ static int WriteGPIO(struct drxk_state *
 			if (status < 0)
 				goto error;
 		}
-		if (state->UIO_mask & 0x0002) { /* UIO-2 */
+		if (state->uio_mask & 0x0002) { /* UIO-2 */
 			/* write to io pad configuration register - output mode */
-			status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
+			status = write16(state, SIO_PDR_SMA_RX_CFG__A,
+					 state->m_gpio_cfg);
 			if (status < 0)
 				goto error;
 
@@ -5887,7 +5923,7 @@ static int WriteGPIO(struct drxk_state *
 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
 			if (status < 0)
 				goto error;
-			if ((state->m_GPIO & 0x0002) == 0)
+			if ((state->m_gpio & 0x0002) == 0)
 				value &= 0xBFFF;	/* write zero to 14th bit - 2st UIO */
 			else
 				value |= 0x4000;	/* write one to 14th bit - 2st UIO */
@@ -5896,9 +5932,10 @@ static int WriteGPIO(struct drxk_state *
 			if (status < 0)
 				goto error;
 		}
-		if (state->UIO_mask & 0x0004) { /* UIO-3 */
+		if (state->uio_mask & 0x0004) { /* UIO-3 */
 			/* write to io pad configuration register - output mode */
-			status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
+			status = write16(state, SIO_PDR_GPIO_CFG__A,
+					 state->m_gpio_cfg);
 			if (status < 0)
 				goto error;
 
@@ -5906,7 +5943,7 @@ static int WriteGPIO(struct drxk_state *
 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
 			if (status < 0)
 				goto error;
-			if ((state->m_GPIO & 0x0004) == 0)
+			if ((state->m_gpio & 0x0004) == 0)
 				value &= 0xFFFB;            /* write zero to 2nd bit - 3rd UIO */
 			else
 				value |= 0x0004;            /* write one to 2nd bit - 3rd UIO */
@@ -5920,11 +5957,11 @@ static int WriteGPIO(struct drxk_state *
 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SwitchAntennaToQAM(struct drxk_state *state)
+static int switch_antenna_to_qam(struct drxk_state *state)
 {
 	int status = 0;
 	bool gpio_state;
@@ -5934,22 +5971,22 @@ static int SwitchAntennaToQAM(struct drx
 	if (!state->antenna_gpio)
 		return 0;
 
-	gpio_state = state->m_GPIO & state->antenna_gpio;
+	gpio_state = state->m_gpio & state->antenna_gpio;
 
 	if (state->antenna_dvbt ^ gpio_state) {
 		/* Antenna is on DVB-T mode. Switch */
 		if (state->antenna_dvbt)
-			state->m_GPIO &= ~state->antenna_gpio;
+			state->m_gpio &= ~state->antenna_gpio;
 		else
-			state->m_GPIO |= state->antenna_gpio;
-		status = WriteGPIO(state);
+			state->m_gpio |= state->antenna_gpio;
+		status = write_gpio(state);
 	}
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SwitchAntennaToDVBT(struct drxk_state *state)
+static int switch_antenna_to_dvbt(struct drxk_state *state)
 {
 	int status = 0;
 	bool gpio_state;
@@ -5959,23 +5996,23 @@ static int SwitchAntennaToDVBT(struct dr
 	if (!state->antenna_gpio)
 		return 0;
 
-	gpio_state = state->m_GPIO & state->antenna_gpio;
+	gpio_state = state->m_gpio & state->antenna_gpio;
 
 	if (!(state->antenna_dvbt ^ gpio_state)) {
 		/* Antenna is on DVB-C mode. Switch */
 		if (state->antenna_dvbt)
-			state->m_GPIO |= state->antenna_gpio;
+			state->m_gpio |= state->antenna_gpio;
 		else
-			state->m_GPIO &= ~state->antenna_gpio;
-		status = WriteGPIO(state);
+			state->m_gpio &= ~state->antenna_gpio;
+		status = write_gpio(state);
 	}
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
 
-static int PowerDownDevice(struct drxk_state *state)
+static int power_down_device(struct drxk_state *state)
 {
 	/* Power down to requested mode */
 	/* Backup some register settings */
@@ -5986,28 +6023,29 @@ static int PowerDownDevice(struct drxk_s
 	int status;
 
 	dprintk(1, "\n");
-	if (state->m_bPDownOpenBridge) {
+	if (state->m_b_p_down_open_bridge) {
 		/* Open I2C bridge before power down of DRXK */
 		status = ConfigureI2CBridge(state, true);
 		if (status < 0)
 			goto error;
 	}
 	/* driver 0.9.0 */
-	status = DVBTEnableOFDMTokenRing(state, false);
+	status = dvbt_enable_ofdm_token_ring(state, false);
 	if (status < 0)
 		goto error;
 
-	status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
+	status = write16(state, SIO_CC_PWD_MODE__A,
+			 SIO_CC_PWD_MODE_LEVEL_CLOCK);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
 	if (status < 0)
 		goto error;
-	state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
-	status = HI_CfgCommand(state);
+	state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+	status = hi_cfg_command(state);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -6015,50 +6053,56 @@ error:
 static int init_drxk(struct drxk_state *state)
 {
 	int status = 0, n = 0;
-	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
-	u16 driverVersion;
+	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
+	u16 driver_version;
 
 	dprintk(1, "\n");
-	if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
+	if ((state->m_drxk_state == DRXK_UNINITIALIZED)) {
 		drxk_i2c_lock(state);
-		status = PowerUpDevice(state);
+		status = power_up_device(state);
 		if (status < 0)
 			goto error;
-		status = DRXX_Open(state);
+		status = drxx_open(state);
 		if (status < 0)
 			goto error;
 		/* Soft reset of OFDM-, sys- and osc-clockdomain */
-		status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
+		status = write16(state, SIO_CC_SOFT_RST__A,
+				 SIO_CC_SOFT_RST_OFDM__M
+				 | SIO_CC_SOFT_RST_SYS__M
+				 | SIO_CC_SOFT_RST_OSC__M);
 		if (status < 0)
 			goto error;
 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
 		if (status < 0)
 			goto error;
-		/* TODO is this needed, if yes how much delay in worst case scenario */
-		msleep(1);
-		state->m_DRXK_A3_PATCH_CODE = true;
-		status = GetDeviceCapabilities(state);
+		/*
+		 * TODO is this needed? If yes, how much delay in
+		 * worst case scenario
+		 */
+		usleep_range(1000, 2000);
+		state->m_drxk_a3_patch_code = true;
+		status = get_device_capabilities(state);
 		if (status < 0)
 			goto error;
 
 		/* Bridge delay, uses oscilator clock */
 		/* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
 		/* SDA brdige delay */
-		state->m_HICfgBridgeDelay =
-			(u16) ((state->m_oscClockFreq / 1000) *
+		state->m_hi_cfg_bridge_delay =
+			(u16) ((state->m_osc_clock_freq / 1000) *
 				HI_I2C_BRIDGE_DELAY) / 1000;
 		/* Clipping */
-		if (state->m_HICfgBridgeDelay >
+		if (state->m_hi_cfg_bridge_delay >
 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
-			state->m_HICfgBridgeDelay =
+			state->m_hi_cfg_bridge_delay =
 				SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
 		}
 		/* SCL bridge delay, same as SDA for now */
-		state->m_HICfgBridgeDelay +=
-			state->m_HICfgBridgeDelay <<
+		state->m_hi_cfg_bridge_delay +=
+			state->m_hi_cfg_bridge_delay <<
 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
 
-		status = InitHI(state);
+		status = init_hi(state);
 		if (status < 0)
 			goto error;
 		/* disable various processes */
@@ -6067,13 +6111,14 @@ static int init_drxk(struct drxk_state *
 			&& !(state->m_DRXK_A2_ROM_CODE))
 #endif
 		{
-			status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+			status = write16(state, SCU_RAM_GPIO__A,
+					 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 			if (status < 0)
 				goto error;
 		}
 
 		/* disable MPEG port */
-		status = MPEGTSDisable(state);
+		status = mpegts_disable(state);
 		if (status < 0)
 			goto error;
 
@@ -6086,27 +6131,30 @@ static int init_drxk(struct drxk_state *
 			goto error;
 
 		/* enable token-ring bus through OFDM block for possible ucode upload */
-		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
+		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
+				 SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
 		if (status < 0)
 			goto error;
 
 		/* include boot loader section */
-		status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
+		status = write16(state, SIO_BL_COMM_EXEC__A,
+				 SIO_BL_COMM_EXEC_ACTIVE);
 		if (status < 0)
 			goto error;
-		status = BLChainCmd(state, 0, 6, 100);
+		status = bl_chain_cmd(state, 0, 6, 100);
 		if (status < 0)
 			goto error;
 
 		if (state->fw) {
-			status = DownloadMicrocode(state, state->fw->data,
+			status = download_microcode(state, state->fw->data,
 						   state->fw->size);
 			if (status < 0)
 				goto error;
 		}
 
 		/* disable token-ring bus through OFDM block for possible ucode upload */
-		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
+		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
+				 SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
 		if (status < 0)
 			goto error;
 
@@ -6114,14 +6162,14 @@ static int init_drxk(struct drxk_state *
 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
 		if (status < 0)
 			goto error;
-		status = DRXX_Open(state);
+		status = drxx_open(state);
 		if (status < 0)
 			goto error;
 		/* added for test */
 		msleep(30);
 
-		powerMode = DRXK_POWER_DOWN_OFDM;
-		status = CtrlPowerMode(state, &powerMode);
+		power_mode = DRXK_POWER_DOWN_OFDM;
+		status = ctrl_power_mode(state, &power_mode);
 		if (status < 0)
 			goto error;
 
@@ -6131,33 +6179,38 @@ static int init_drxk(struct drxk_state *
 			Not using SCU command interface for SCU register access since no
 			microcode may be present.
 			*/
-		driverVersion =
+		driver_version =
 			(((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
 			(((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
 			((DRXK_VERSION_MAJOR % 10) << 4) +
 			(DRXK_VERSION_MINOR % 10);
-		status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
+		status = write16(state, SCU_RAM_DRIVER_VER_HI__A,
+				 driver_version);
 		if (status < 0)
 			goto error;
-		driverVersion =
+		driver_version =
 			(((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
 			(((DRXK_VERSION_PATCH / 100) % 10) << 8) +
 			(((DRXK_VERSION_PATCH / 10) % 10) << 4) +
 			(DRXK_VERSION_PATCH % 10);
-		status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
+		status = write16(state, SCU_RAM_DRIVER_VER_LO__A,
+				 driver_version);
 		if (status < 0)
 			goto error;
 
-		printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
+		pr_info("DRXK driver version %d.%d.%d\n",
 			DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
 			DRXK_VERSION_PATCH);
 
-		/* Dirty fix of default values for ROM/PATCH microcode
-			Dirty because this fix makes it impossible to setup suitable values
-			before calling DRX_Open. This solution requires changes to RF AGC speed
-			to be done via the CTRL function after calling DRX_Open */
+		/*
+		 * Dirty fix of default values for ROM/PATCH microcode
+		 * Dirty because this fix makes it impossible to setup
+		 * suitable values before calling DRX_Open. This solution
+		 * requires changes to RF AGC speed to be done via the CTRL
+		 * function after calling DRX_Open
+		 */
 
-		/* m_dvbtRfAgcCfg.speed = 3; */
+		/* m_dvbt_rf_agc_cfg.speed = 3; */
 
 		/* Reset driver debug flags to 0 */
 		status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
@@ -6170,42 +6223,42 @@ static int init_drxk(struct drxk_state *
 		if (status < 0)
 			goto error;
 		/* MPEGTS functions are still the same */
-		status = MPEGTSDtoInit(state);
+		status = mpegts_dto_init(state);
 		if (status < 0)
 			goto error;
-		status = MPEGTSStop(state);
+		status = mpegts_stop(state);
 		if (status < 0)
 			goto error;
-		status = MPEGTSConfigurePolarity(state);
+		status = mpegts_configure_polarity(state);
 		if (status < 0)
 			goto error;
-		status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
+		status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
 		if (status < 0)
 			goto error;
 		/* added: configure GPIO */
-		status = WriteGPIO(state);
+		status = write_gpio(state);
 		if (status < 0)
 			goto error;
 
-		state->m_DrxkState = DRXK_STOPPED;
+		state->m_drxk_state = DRXK_STOPPED;
 
-		if (state->m_bPowerDown) {
-			status = PowerDownDevice(state);
+		if (state->m_b_power_down) {
+			status = power_down_device(state);
 			if (status < 0)
 				goto error;
-			state->m_DrxkState = DRXK_POWERED_DOWN;
+			state->m_drxk_state = DRXK_POWERED_DOWN;
 		} else
-			state->m_DrxkState = DRXK_STOPPED;
+			state->m_drxk_state = DRXK_STOPPED;
 
 		/* Initialize the supported delivery systems */
 		n = 0;
-		if (state->m_hasDVBC) {
+		if (state->m_has_dvbc) {
 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
 			strlcat(state->frontend.ops.info.name, " DVB-C",
 				sizeof(state->frontend.ops.info.name));
 		}
-		if (state->m_hasDVBT) {
+		if (state->m_has_dvbt) {
 			state->frontend.ops.delsys[n++] = SYS_DVBT;
 			strlcat(state->frontend.ops.info.name, " DVB-T",
 				sizeof(state->frontend.ops.info.name));
@@ -6214,9 +6267,9 @@ static int init_drxk(struct drxk_state *
 	}
 error:
 	if (status < 0) {
-		state->m_DrxkState = DRXK_NO_DEV;
+		state->m_drxk_state = DRXK_NO_DEV;
 		drxk_i2c_unlock(state);
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	}
 
 	return status;
@@ -6229,11 +6282,9 @@ static void load_firmware_cb(const struc
 
 	dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
 	if (!fw) {
-		printk(KERN_ERR
-		       "drxk: Could not load firmware file %s.\n",
+		pr_err("Could not load firmware file %s.\n",
 			state->microcode_name);
-		printk(KERN_INFO
-		       "drxk: Copy %s to your hotplug directory!\n",
+		pr_info("Copy %s to your hotplug directory!\n",
 			state->microcode_name);
 		state->microcode_name = NULL;
 
@@ -6270,12 +6321,12 @@ static int drxk_sleep(struct dvb_fronten
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return 0;
 
-	ShutDown(state);
+	shut_down(state);
 	return 0;
 }
 
@@ -6285,7 +6336,7 @@ static int drxk_gate_ctrl(struct dvb_fro
 
 	dprintk(1, ": %s\n", enable ? "enable" : "disable");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
 
 	return ConfigureI2CBridge(state, enable ? true : false);
@@ -6300,15 +6351,14 @@ static int drxk_set_parameters(struct dv
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
 
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
 	if (!fe->ops.tuner_ops.get_if_frequency) {
-		printk(KERN_ERR
-		       "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
+		pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
 		return -EINVAL;
 	}
 
@@ -6323,22 +6373,23 @@ static int drxk_set_parameters(struct dv
 	state->props = *p;
 
 	if (old_delsys != delsys) {
-		ShutDown(state);
+		shut_down(state);
 		switch (delsys) {
 		case SYS_DVBC_ANNEX_A:
 		case SYS_DVBC_ANNEX_C:
-			if (!state->m_hasDVBC)
+			if (!state->m_has_dvbc)
 				return -EINVAL;
-			state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
+			state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ?
+						true : false;
 			if (state->m_itut_annex_c)
-				SetOperationMode(state, OM_QAM_ITU_C);
+				setoperation_mode(state, OM_QAM_ITU_C);
 			else
-				SetOperationMode(state, OM_QAM_ITU_A);
+				setoperation_mode(state, OM_QAM_ITU_A);
 			break;
 		case SYS_DVBT:
-			if (!state->m_hasDVBT)
+			if (!state->m_has_dvbt)
 				return -EINVAL;
-			SetOperationMode(state, OM_DVBT);
+			setoperation_mode(state, OM_DVBT);
 			break;
 		default:
 			return -EINVAL;
@@ -6346,7 +6397,7 @@ static int drxk_set_parameters(struct dv
 	}
 
 	fe->ops.tuner_ops.get_if_frequency(fe, &IF);
-	Start(state, 0, IF);
+	start(state, 0, IF);
 
 	/* After set_frontend, stats aren't avaliable */
 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
@@ -6366,31 +6417,31 @@ static int drxk_set_parameters(struct dv
 static int get_strength(struct drxk_state *state, u64 *strength)
 {
 	int status;
-	struct SCfgAgc   rfAgc, ifAgc;
-	u32          totalGain  = 0;
+	struct s_cfg_agc   rf_agc, if_agc;
+	u32          total_gain  = 0;
 	u32          atten      = 0;
-	u32          agcRange   = 0;
+	u32          agc_range   = 0;
 	u16            scu_lvl  = 0;
 	u16            scu_coc  = 0;
 	/* FIXME: those are part of the tuner presets */
-	u16 tunerRfGain         = 50; /* Default value on az6007 driver */
-	u16 tunerIfGain         = 40; /* Default value on az6007 driver */
+	u16 tuner_rf_gain         = 50; /* Default value on az6007 driver */
+	u16 tuner_if_gain         = 40; /* Default value on az6007 driver */
 
 	*strength = 0;
 
-	if (IsDVBT(state)) {
-		rfAgc = state->m_dvbtRfAgcCfg;
-		ifAgc = state->m_dvbtIfAgcCfg;
-	} else if (IsQAM(state)) {
-		rfAgc = state->m_qamRfAgcCfg;
-		ifAgc = state->m_qamIfAgcCfg;
+	if (is_dvbt(state)) {
+		rf_agc = state->m_dvbt_rf_agc_cfg;
+		if_agc = state->m_dvbt_if_agc_cfg;
+	} else if (is_qam(state)) {
+		rf_agc = state->m_qam_rf_agc_cfg;
+		if_agc = state->m_qam_if_agc_cfg;
 	} else {
-		rfAgc = state->m_atvRfAgcCfg;
-		ifAgc = state->m_atvIfAgcCfg;
+		rf_agc = state->m_atv_rf_agc_cfg;
+		if_agc = state->m_atv_if_agc_cfg;
 	}
 
-	if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
-		/* SCU outputLevel */
+	if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
+		/* SCU output_level */
 		status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
 		if (status < 0)
 			return status;
@@ -6401,54 +6452,54 @@ static int get_strength(struct drxk_stat
 			return status;
 
 		if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
-			rfAgc.outputLevel = scu_lvl + scu_coc;
+			rf_agc.output_level = scu_lvl + scu_coc;
 		else
-			rfAgc.outputLevel = 0xffff;
+			rf_agc.output_level = 0xffff;
 
 		/* Take RF gain into account */
-		totalGain += tunerRfGain;
+		total_gain += tuner_rf_gain;
 
 		/* clip output value */
-		if (rfAgc.outputLevel < rfAgc.minOutputLevel)
-			rfAgc.outputLevel = rfAgc.minOutputLevel;
-		if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
-			rfAgc.outputLevel = rfAgc.maxOutputLevel;
+		if (rf_agc.output_level < rf_agc.min_output_level)
+			rf_agc.output_level = rf_agc.min_output_level;
+		if (rf_agc.output_level > rf_agc.max_output_level)
+			rf_agc.output_level = rf_agc.max_output_level;
 
-		agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
-		if (agcRange > 0) {
+		agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
+		if (agc_range > 0) {
 			atten += 100UL *
-				((u32)(tunerRfGain)) *
-				((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
-				/ agcRange;
+				((u32)(tuner_rf_gain)) *
+				((u32)(rf_agc.output_level - rf_agc.min_output_level))
+				/ agc_range;
 		}
 	}
 
-	if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
+	if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
 		status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
-				&ifAgc.outputLevel);
+				&if_agc.output_level);
 		if (status < 0)
 			return status;
 
 		status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
-				&ifAgc.top);
+				&if_agc.top);
 		if (status < 0)
 			return status;
 
 		/* Take IF gain into account */
-		totalGain += (u32) tunerIfGain;
+		total_gain += (u32) tuner_if_gain;
 
 		/* clip output value */
-		if (ifAgc.outputLevel < ifAgc.minOutputLevel)
-			ifAgc.outputLevel = ifAgc.minOutputLevel;
-		if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
-			ifAgc.outputLevel = ifAgc.maxOutputLevel;
+		if (if_agc.output_level < if_agc.min_output_level)
+			if_agc.output_level = if_agc.min_output_level;
+		if (if_agc.output_level > if_agc.max_output_level)
+			if_agc.output_level = if_agc.max_output_level;
 
-		agcRange  = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
-		if (agcRange > 0) {
+		agc_range  = (u32)(if_agc.max_output_level - if_agc.min_output_level);
+		if (agc_range > 0) {
 			atten += 100UL *
-				((u32)(tunerIfGain)) *
-				((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
-				/ agcRange;
+				((u32)(tuner_if_gain)) *
+				((u32)(if_agc.output_level - if_agc.min_output_level))
+				/ agc_range;
 		}
 	}
 
@@ -6456,8 +6507,8 @@ static int get_strength(struct drxk_stat
 	 * Convert to 0..65535 scale.
 	 * If it can't be measured (AGC is disabled), just show 100%.
 	 */
-	if (totalGain > 0)
-		*strength = (65535UL * atten / totalGain / 100);
+	if (total_gain > 0)
+		*strength = (65535UL * atten / total_gain / 100);
 	else
 		*strength = 65535;
 
@@ -6480,14 +6531,14 @@ static int drxk_get_stats(struct dvb_fro
 	u32 pkt_error_count;
 	s32 cnr;
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
 	/* get status */
 	state->fe_status = 0;
-	GetLockStatus(state, &stat);
+	get_lock_status(state, &stat);
 	if (stat == MPEG_LOCK)
 		state->fe_status |= 0x1f;
 	if (stat == FEC_LOCK)
@@ -6503,7 +6554,7 @@ static int drxk_get_stats(struct dvb_fro
 
 
 	if (stat >= DEMOD_LOCK) {
-		GetSignalToNoise(state, &cnr);
+		get_signal_to_noise(state, &cnr);
 		c->cnr.stat[0].svalue = cnr * 100;
 		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
 	} else {
@@ -6524,9 +6575,11 @@ static int drxk_get_stats(struct dvb_fro
 
 	/* BER measurement is valid if at least FEC lock is achieved */
 
-	/* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
-		to set nr of symbols or bits over which
-		to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
+	/*
+	 * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be
+	 * written to set nr of symbols or bits over which to measure
+	 * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg().
+	 */
 
 	/* Read registers for post/preViterbi BER calculation */
 	status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
@@ -6610,9 +6663,9 @@ static int drxk_read_signal_strength(str
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
 	*strength = c->strength.stat[0].uvalue;
@@ -6626,12 +6679,12 @@ static int drxk_read_snr(struct dvb_fron
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
-	GetSignalToNoise(state, &snr2);
+	get_signal_to_noise(state, &snr2);
 
 	/* No negative SNR, clip to zero */
 	if (snr2 < 0)
@@ -6647,27 +6700,27 @@ static int drxk_read_ucblocks(struct dvb
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
-	DVBTQAMGetAccPktErr(state, &err);
+	dvbtqam_get_acc_pkt_err(state, &err);
 	*ucblocks = (u32) err;
 	return 0;
 }
 
-static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
-				    *sets)
+static int drxk_get_tune_settings(struct dvb_frontend *fe,
+				  struct dvb_frontend_tune_settings *sets)
 {
 	struct drxk_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
 	switch (p->delivery_system) {
@@ -6737,36 +6790,36 @@ struct dvb_frontend *drxk_attach(const s
 	state->no_i2c_bridge = config->no_i2c_bridge;
 	state->antenna_gpio = config->antenna_gpio;
 	state->antenna_dvbt = config->antenna_dvbt;
-	state->m_ChunkSize = config->chunk_size;
+	state->m_chunk_size = config->chunk_size;
 	state->enable_merr_cfg = config->enable_merr_cfg;
 
 	if (config->dynamic_clk) {
-		state->m_DVBTStaticCLK = 0;
-		state->m_DVBCStaticCLK = 0;
+		state->m_dvbt_static_clk = 0;
+		state->m_dvbc_static_clk = 0;
 	} else {
-		state->m_DVBTStaticCLK = 1;
-		state->m_DVBCStaticCLK = 1;
+		state->m_dvbt_static_clk = 1;
+		state->m_dvbc_static_clk = 1;
 	}
 
 
 	if (config->mpeg_out_clk_strength)
-		state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
+		state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
 	else
-		state->m_TSClockkStrength = 0x06;
+		state->m_ts_clockk_strength = 0x06;
 
 	if (config->parallel_ts)
-		state->m_enableParallel = true;
+		state->m_enable_parallel = true;
 	else
-		state->m_enableParallel = false;
+		state->m_enable_parallel = false;
 
 	/* NOTE: as more UIO bits will be used, add them to the mask */
-	state->UIO_mask = config->antenna_gpio;
+	state->uio_mask = config->antenna_gpio;
 
 	/* Default gpio to DVB-C */
 	if (!state->antenna_dvbt && state->antenna_gpio)
-		state->m_GPIO |= state->antenna_gpio;
+		state->m_gpio |= state->antenna_gpio;
 	else
-		state->m_GPIO &= ~state->antenna_gpio;
+		state->m_gpio &= ~state->antenna_gpio;
 
 	mutex_init(&state->mutex);
 
@@ -6792,8 +6845,7 @@ struct dvb_frontend *drxk_attach(const s
 					      GFP_KERNEL,
 					      state, load_firmware_cb);
 			if (status < 0) {
-				printk(KERN_ERR
-				       "drxk: failed to request a firmware\n");
+				pr_err("failed to request a firmware\n");
 				return NULL;
 			}
 		}
@@ -6821,11 +6873,11 @@ struct dvb_frontend *drxk_attach(const s
 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
 
-	printk(KERN_INFO "drxk: frontend initialized.\n");
+	pr_info("frontend initialized.\n");
 	return &state->frontend;
 
 error:
-	printk(KERN_ERR "drxk: not found\n");
+	pr_err("not found\n");
 	kfree(state);
 	return NULL;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-frontends/drxk_hard.h linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/drxk_hard.h
--- linux-libre-3.10-gnu/drivers/media/dvb-frontends/drxk_hard.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/drxk_hard.h	2013-08-25 20:43:22.000000000 -0400
@@ -46,7 +46,7 @@
 #define     IQM_RC_ADJ_SEL_B_QAM                                            0x1
 #define     IQM_RC_ADJ_SEL_B_VSB                                            0x2
 
-enum OperationMode {
+enum operation_mode {
 	OM_NONE,
 	OM_QAM_ITU_A,
 	OM_QAM_ITU_B,
@@ -54,7 +54,7 @@ enum OperationMode {
 	OM_DVBT
 };
 
-enum DRXPowerMode {
+enum drx_power_mode {
 	DRX_POWER_UP = 0,
 	DRX_POWER_MODE_1,
 	DRX_POWER_MODE_2,
@@ -77,24 +77,29 @@ enum DRXPowerMode {
 };
 
 
-/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */
+/* Intermediate power mode for DRXK, power down OFDM clock domain */
 #ifndef DRXK_POWER_DOWN_OFDM
 #define DRXK_POWER_DOWN_OFDM        DRX_POWER_MODE_1
 #endif
 
-/** /brief Intermediate power mode for DRXK, power down core (sysclk) */
+/* Intermediate power mode for DRXK, power down core (sysclk) */
 #ifndef DRXK_POWER_DOWN_CORE
 #define DRXK_POWER_DOWN_CORE        DRX_POWER_MODE_9
 #endif
 
-/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */
+/* Intermediate power mode for DRXK, power down pll (only osc runs) */
 #ifndef DRXK_POWER_DOWN_PLL
 #define DRXK_POWER_DOWN_PLL         DRX_POWER_MODE_10
 #endif
 
 
-enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
-enum EDrxkState {
+enum agc_ctrl_mode {
+	DRXK_AGC_CTRL_AUTO = 0,
+	DRXK_AGC_CTRL_USER,
+	DRXK_AGC_CTRL_OFF
+};
+
+enum e_drxk_state {
 	DRXK_UNINITIALIZED = 0,
 	DRXK_STOPPED,
 	DRXK_DTV_STARTED,
@@ -103,7 +108,7 @@ enum EDrxkState {
 	DRXK_NO_DEV			/* If drxk init failed */
 };
 
-enum EDrxkCoefArrayIndex {
+enum e_drxk_coef_array_index {
 	DRXK_COEF_IDX_MN = 0,
 	DRXK_COEF_IDX_FM    ,
 	DRXK_COEF_IDX_L     ,
@@ -113,13 +118,13 @@ enum EDrxkCoefArrayIndex {
 	DRXK_COEF_IDX_I     ,
 	DRXK_COEF_IDX_MAX
 };
-enum EDrxkSifAttenuation {
+enum e_drxk_sif_attenuation {
 	DRXK_SIF_ATTENUATION_0DB,
 	DRXK_SIF_ATTENUATION_3DB,
 	DRXK_SIF_ATTENUATION_6DB,
 	DRXK_SIF_ATTENUATION_9DB
 };
-enum EDrxkConstellation {
+enum e_drxk_constellation {
 	DRX_CONSTELLATION_BPSK = 0,
 	DRX_CONSTELLATION_QPSK,
 	DRX_CONSTELLATION_PSK8,
@@ -133,7 +138,7 @@ enum EDrxkConstellation {
 	DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
 	DRX_CONSTELLATION_AUTO    = DRX_AUTO
 };
-enum EDrxkInterleaveMode {
+enum e_drxk_interleave_mode {
 	DRXK_QAM_I12_J17    = 16,
 	DRXK_QAM_I_UNKNOWN  = DRX_UNKNOWN
 };
@@ -144,14 +149,14 @@ enum {
 	DRXK_SPIN_UNKNOWN
 };
 
-enum DRXKCfgDvbtSqiSpeed {
+enum drxk_cfg_dvbt_sqi_speed {
 	DRXK_DVBT_SQI_SPEED_FAST = 0,
 	DRXK_DVBT_SQI_SPEED_MEDIUM,
 	DRXK_DVBT_SQI_SPEED_SLOW,
 	DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
 } ;
 
-enum DRXFftmode_t {
+enum drx_fftmode_t {
 	DRX_FFTMODE_2K = 0,
 	DRX_FFTMODE_4K,
 	DRX_FFTMODE_8K,
@@ -159,47 +164,47 @@ enum DRXFftmode_t {
 	DRX_FFTMODE_AUTO    = DRX_AUTO
 };
 
-enum DRXMPEGStrWidth_t {
+enum drxmpeg_str_width_t {
 	DRX_MPEG_STR_WIDTH_1,
 	DRX_MPEG_STR_WIDTH_8
 };
 
-enum DRXQamLockRange_t {
+enum drx_qam_lock_range_t {
 	DRX_QAM_LOCKRANGE_NORMAL,
 	DRX_QAM_LOCKRANGE_EXTENDED
 };
 
-struct DRXKCfgDvbtEchoThres_t {
+struct drxk_cfg_dvbt_echo_thres_t {
 	u16             threshold;
-	enum DRXFftmode_t      fftMode;
+	enum drx_fftmode_t      fft_mode;
 } ;
 
-struct SCfgAgc {
-	enum AGC_CTRL_MODE     ctrlMode;        /* off, user, auto */
-	u16            outputLevel;     /* range dependent on AGC */
-	u16            minOutputLevel;  /* range dependent on AGC */
-	u16            maxOutputLevel;  /* range dependent on AGC */
+struct s_cfg_agc {
+	enum agc_ctrl_mode     ctrl_mode;        /* off, user, auto */
+	u16            output_level;     /* range dependent on AGC */
+	u16            min_output_level;  /* range dependent on AGC */
+	u16            max_output_level;  /* range dependent on AGC */
 	u16            speed;           /* range dependent on AGC */
 	u16            top;             /* rf-agc take over point */
-	u16            cutOffCurrent;   /* rf-agc is accelerated if output current
+	u16            cut_off_current;   /* rf-agc is accelerated if output current
 					   is below cut-off current */
-	u16            IngainTgtMax;
-	u16            FastClipCtrlDelay;
+	u16            ingain_tgt_max;
+	u16            fast_clip_ctrl_delay;
 };
 
-struct SCfgPreSaw {
+struct s_cfg_pre_saw {
 	u16        reference; /* pre SAW reference value, range 0 .. 31 */
-	bool          usePreSaw; /* TRUE algorithms must use pre SAW sense */
+	bool          use_pre_saw; /* TRUE algorithms must use pre SAW sense */
 };
 
-struct DRXKOfdmScCmd_t {
-	u16 cmd;        /**< Command number */
-	u16 subcmd;     /**< Sub-command parameter*/
-	u16 param0;     /**< General purpous param */
-	u16 param1;     /**< General purpous param */
-	u16 param2;     /**< General purpous param */
-	u16 param3;     /**< General purpous param */
-	u16 param4;     /**< General purpous param */
+struct drxk_ofdm_sc_cmd_t {
+	u16 cmd;        /* Command number */
+	u16 subcmd;     /* Sub-command parameter*/
+	u16 param0;     /* General purpous param */
+	u16 param1;     /* General purpous param */
+	u16 param2;     /* General purpous param */
+	u16 param3;     /* General purpous param */
+	u16 param4;     /* General purpous param */
 };
 
 struct drxk_state {
@@ -213,121 +218,121 @@ struct drxk_state {
 
 	struct mutex mutex;
 
-	u32    m_Instance;           /**< Channel 1,2,3 or 4 */
+	u32    m_instance;           /* Channel 1,2,3 or 4 */
 
-	int    m_ChunkSize;
-	u8 Chunk[256];
+	int    m_chunk_size;
+	u8 chunk[256];
 
-	bool   m_hasLNA;
-	bool   m_hasDVBT;
-	bool   m_hasDVBC;
-	bool   m_hasAudio;
-	bool   m_hasATV;
-	bool   m_hasOOB;
-	bool   m_hasSAWSW;         /**< TRUE if mat_tx is available */
-	bool   m_hasGPIO1;         /**< TRUE if mat_rx is available */
-	bool   m_hasGPIO2;         /**< TRUE if GPIO is available */
-	bool   m_hasIRQN;          /**< TRUE if IRQN is available */
-	u16    m_oscClockFreq;
-	u16    m_HICfgTimingDiv;
-	u16    m_HICfgBridgeDelay;
-	u16    m_HICfgWakeUpKey;
-	u16    m_HICfgTimeout;
-	u16    m_HICfgCtrl;
-	s32    m_sysClockFreq;      /**< system clock frequency in kHz */
+	bool   m_has_lna;
+	bool   m_has_dvbt;
+	bool   m_has_dvbc;
+	bool   m_has_audio;
+	bool   m_has_atv;
+	bool   m_has_oob;
+	bool   m_has_sawsw;         /* TRUE if mat_tx is available */
+	bool   m_has_gpio1;         /* TRUE if mat_rx is available */
+	bool   m_has_gpio2;         /* TRUE if GPIO is available */
+	bool   m_has_irqn;          /* TRUE if IRQN is available */
+	u16    m_osc_clock_freq;
+	u16    m_hi_cfg_timing_div;
+	u16    m_hi_cfg_bridge_delay;
+	u16    m_hi_cfg_wake_up_key;
+	u16    m_hi_cfg_timeout;
+	u16    m_hi_cfg_ctrl;
+	s32    m_sys_clock_freq;      /* system clock frequency in kHz */
 
-	enum EDrxkState    m_DrxkState;      /**< State of Drxk (init,stopped,started) */
-	enum OperationMode m_OperationMode;  /**< digital standards */
-	struct SCfgAgc     m_vsbRfAgcCfg;    /**< settings for VSB RF-AGC */
-	struct SCfgAgc     m_vsbIfAgcCfg;    /**< settings for VSB IF-AGC */
-	u16                m_vsbPgaCfg;      /**< settings for VSB PGA */
-	struct SCfgPreSaw  m_vsbPreSawCfg;   /**< settings for pre SAW sense */
-	s32    m_Quality83percent;  /**< MER level (*0.1 dB) for 83% quality indication */
-	s32    m_Quality93percent;  /**< MER level (*0.1 dB) for 93% quality indication */
-	bool   m_smartAntInverted;
-	bool   m_bDebugEnableBridge;
-	bool   m_bPDownOpenBridge;  /**< only open DRXK bridge before power-down once it has been accessed */
-	bool   m_bPowerDown;        /**< Power down when not used */
+	enum e_drxk_state    m_drxk_state;      /* State of Drxk (init,stopped,started) */
+	enum operation_mode m_operation_mode;  /* digital standards */
+	struct s_cfg_agc     m_vsb_rf_agc_cfg;    /* settings for VSB RF-AGC */
+	struct s_cfg_agc     m_vsb_if_agc_cfg;    /* settings for VSB IF-AGC */
+	u16                m_vsb_pga_cfg;      /* settings for VSB PGA */
+	struct s_cfg_pre_saw  m_vsb_pre_saw_cfg;   /* settings for pre SAW sense */
+	s32    m_Quality83percent;  /* MER level (*0.1 dB) for 83% quality indication */
+	s32    m_Quality93percent;  /* MER level (*0.1 dB) for 93% quality indication */
+	bool   m_smart_ant_inverted;
+	bool   m_b_debug_enable_bridge;
+	bool   m_b_p_down_open_bridge;  /* only open DRXK bridge before power-down once it has been accessed */
+	bool   m_b_power_down;        /* Power down when not used */
 
-	u32    m_IqmFsRateOfs;      /**< frequency shift as written to DRXK register (28bit fixpoint) */
+	u32    m_iqm_fs_rate_ofs;      /* frequency shift as written to DRXK register (28bit fixpoint) */
 
-	bool   m_enableMPEGOutput;  /**< If TRUE, enable MPEG output */
-	bool   m_insertRSByte;      /**< If TRUE, insert RS byte */
-	bool   m_enableParallel;    /**< If TRUE, parallel out otherwise serial */
-	bool   m_invertDATA;        /**< If TRUE, invert DATA signals */
-	bool   m_invertERR;         /**< If TRUE, invert ERR signal */
-	bool   m_invertSTR;         /**< If TRUE, invert STR signals */
-	bool   m_invertVAL;         /**< If TRUE, invert VAL signals */
-	bool   m_invertCLK;         /**< If TRUE, invert CLK signals */
-	bool   m_DVBCStaticCLK;
-	bool   m_DVBTStaticCLK;     /**< If TRUE, static MPEG clockrate will
+	bool   m_enable_mpeg_output;  /* If TRUE, enable MPEG output */
+	bool   m_insert_rs_byte;      /* If TRUE, insert RS byte */
+	bool   m_enable_parallel;    /* If TRUE, parallel out otherwise serial */
+	bool   m_invert_data;        /* If TRUE, invert DATA signals */
+	bool   m_invert_err;         /* If TRUE, invert ERR signal */
+	bool   m_invert_str;         /* If TRUE, invert STR signals */
+	bool   m_invert_val;         /* If TRUE, invert VAL signals */
+	bool   m_invert_clk;         /* If TRUE, invert CLK signals */
+	bool   m_dvbc_static_clk;
+	bool   m_dvbt_static_clk;     /* If TRUE, static MPEG clockrate will
 					 be used, otherwise clockrate will
 					 adapt to the bitrate of the TS */
-	u32    m_DVBTBitrate;
-	u32    m_DVBCBitrate;
+	u32    m_dvbt_bitrate;
+	u32    m_dvbc_bitrate;
 
-	u8     m_TSDataStrength;
-	u8     m_TSClockkStrength;
+	u8     m_ts_data_strength;
+	u8     m_ts_clockk_strength;
 
 	bool   m_itut_annex_c;      /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */
 
-	enum DRXMPEGStrWidth_t  m_widthSTR;    /**< MPEG start width */
-	u32    m_mpegTsStaticBitrate;          /**< Maximum bitrate in b/s in case
+	enum drxmpeg_str_width_t  m_width_str;    /* MPEG start width */
+	u32    m_mpeg_ts_static_bitrate;          /* Maximum bitrate in b/s in case
 						    static clockrate is selected */
 
-	/* LARGE_INTEGER   m_StartTime; */     /**< Contains the time of the last demod start */
-	s32    m_MpegLockTimeOut;      /**< WaitForLockStatus Timeout (counts from start time) */
-	s32    m_DemodLockTimeOut;     /**< WaitForLockStatus Timeout (counts from start time) */
+	/* LARGE_INTEGER   m_startTime; */     /* Contains the time of the last demod start */
+	s32    m_mpeg_lock_time_out;      /* WaitForLockStatus Timeout (counts from start time) */
+	s32    m_demod_lock_time_out;     /* WaitForLockStatus Timeout (counts from start time) */
 
-	bool   m_disableTEIhandling;
+	bool   m_disable_te_ihandling;
 
-	bool   m_RfAgcPol;
-	bool   m_IfAgcPol;
+	bool   m_rf_agc_pol;
+	bool   m_if_agc_pol;
 
-	struct SCfgAgc    m_atvRfAgcCfg;  /**< settings for ATV RF-AGC */
-	struct SCfgAgc    m_atvIfAgcCfg;  /**< settings for ATV IF-AGC */
-	struct SCfgPreSaw m_atvPreSawCfg; /**< settings for ATV pre SAW sense */
-	bool              m_phaseCorrectionBypass;
-	s16               m_atvTopVidPeak;
-	u16               m_atvTopNoiseTh;
-	enum EDrxkSifAttenuation m_sifAttenuation;
-	bool              m_enableCVBSOutput;
-	bool              m_enableSIFOutput;
-	bool              m_bMirrorFreqSpect;
-	enum EDrxkConstellation  m_Constellation; /**< Constellation type of the channel */
-	u32               m_CurrSymbolRate;       /**< Current QAM symbol rate */
-	struct SCfgAgc    m_qamRfAgcCfg;          /**< settings for QAM RF-AGC */
-	struct SCfgAgc    m_qamIfAgcCfg;          /**< settings for QAM IF-AGC */
-	u16               m_qamPgaCfg;            /**< settings for QAM PGA */
-	struct SCfgPreSaw m_qamPreSawCfg;         /**< settings for QAM pre SAW sense */
-	enum EDrxkInterleaveMode m_qamInterleaveMode; /**< QAM Interleave mode */
-	u16               m_fecRsPlen;
-	u16               m_fecRsPrescale;
+	struct s_cfg_agc    m_atv_rf_agc_cfg;  /* settings for ATV RF-AGC */
+	struct s_cfg_agc    m_atv_if_agc_cfg;  /* settings for ATV IF-AGC */
+	struct s_cfg_pre_saw m_atv_pre_saw_cfg; /* settings for ATV pre SAW sense */
+	bool              m_phase_correction_bypass;
+	s16               m_atv_top_vid_peak;
+	u16               m_atv_top_noise_th;
+	enum e_drxk_sif_attenuation m_sif_attenuation;
+	bool              m_enable_cvbs_output;
+	bool              m_enable_sif_output;
+	bool              m_b_mirror_freq_spect;
+	enum e_drxk_constellation  m_constellation; /* constellation type of the channel */
+	u32               m_curr_symbol_rate;       /* Current QAM symbol rate */
+	struct s_cfg_agc    m_qam_rf_agc_cfg;          /* settings for QAM RF-AGC */
+	struct s_cfg_agc    m_qam_if_agc_cfg;          /* settings for QAM IF-AGC */
+	u16               m_qam_pga_cfg;            /* settings for QAM PGA */
+	struct s_cfg_pre_saw m_qam_pre_saw_cfg;         /* settings for QAM pre SAW sense */
+	enum e_drxk_interleave_mode m_qam_interleave_mode; /* QAM Interleave mode */
+	u16               m_fec_rs_plen;
+	u16               m_fec_rs_prescale;
 
-	enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
+	enum drxk_cfg_dvbt_sqi_speed m_sqi_speed;
 
-	u16               m_GPIO;
-	u16               m_GPIOCfg;
+	u16               m_gpio;
+	u16               m_gpio_cfg;
 
-	struct SCfgAgc    m_dvbtRfAgcCfg;     /**< settings for QAM RF-AGC */
-	struct SCfgAgc    m_dvbtIfAgcCfg;     /**< settings for QAM IF-AGC */
-	struct SCfgPreSaw m_dvbtPreSawCfg;    /**< settings for QAM pre SAW sense */
+	struct s_cfg_agc    m_dvbt_rf_agc_cfg;     /* settings for QAM RF-AGC */
+	struct s_cfg_agc    m_dvbt_if_agc_cfg;     /* settings for QAM IF-AGC */
+	struct s_cfg_pre_saw m_dvbt_pre_saw_cfg;    /* settings for QAM pre SAW sense */
 
-	u16               m_agcFastClipCtrlDelay;
-	bool              m_adcCompPassed;
+	u16               m_agcfast_clip_ctrl_delay;
+	bool              m_adc_comp_passed;
 	u16               m_adcCompCoef[64];
-	u16               m_adcState;
+	u16               m_adc_state;
 
 	u8               *m_microcode;
 	int               m_microcode_length;
-	bool		  m_DRXK_A3_ROM_CODE;
-	bool              m_DRXK_A3_PATCH_CODE;
+	bool		  m_drxk_a3_rom_code;
+	bool              m_drxk_a3_patch_code;
 
 	bool              m_rfmirror;
-	u8                m_deviceSpin;
-	u32               m_iqmRcRate;
+	u8                m_device_spin;
+	u32               m_iqm_rc_rate;
 
-	enum DRXPowerMode m_currentPowerMode;
+	enum drx_power_mode m_current_power_mode;
 
 	/* when true, avoids other devices to use the I2C bus */
 	bool		  drxk_i2c_exclusive_lock;
@@ -337,7 +342,7 @@ struct drxk_state {
 	 * at struct drxk_config.
 	 */
 
-	u16	UIO_mask;	/* Bits used by UIO */
+	u16	uio_mask;	/* Bits used by UIO */
 
 	bool	enable_merr_cfg;
 	bool	single_master;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-frontends/stb0899_algo.c linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/stb0899_algo.c
--- linux-libre-3.10-gnu/drivers/media/dvb-frontends/stb0899_algo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/stb0899_algo.c	2013-08-25 20:43:22.000000000 -0400
@@ -226,8 +226,8 @@ static enum stb0899_status stb0899_searc
 			next_loop--;
 
 		if (next_loop) {
-			STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
-			STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+			STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
+			STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
 			stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency		*/
 		}
 		internal->direction = -internal->direction;	/* Change zigzag direction		*/
@@ -235,7 +235,7 @@ static enum stb0899_status stb0899_searc
 
 	if (internal->status == TIMINGOK) {
 		stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency		*/
-		internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+		internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
 		dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
 	}
 
@@ -306,8 +306,8 @@ static enum stb0899_status stb0899_searc
 				STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
 				stb0899_write_reg(state, STB0899_CFD, reg);
 
-				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
-				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
 				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
 			}
 		}
@@ -317,7 +317,7 @@ static enum stb0899_status stb0899_searc
 
 	if (internal->status == CARRIEROK) {
 		stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
-		internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+		internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
 		dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
 	} else {
 		internal->derot_freq = last_derot_freq;
@@ -412,8 +412,8 @@ static enum stb0899_status stb0899_searc
 				STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
 				stb0899_write_reg(state, STB0899_CFD, reg);
 
-				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
-				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
 				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
 
 				stb0899_check_carrier(state);
@@ -425,7 +425,15 @@ static enum stb0899_status stb0899_searc
 
 	if (internal->status == DATAOK) {
 		stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
-		internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+
+		/* store autodetected IQ swapping as default for DVB-S2 tuning */
+		reg = stb0899_read_reg(state, STB0899_IQSWAP);
+		if (STB0899_GETFIELD(SYM, reg))
+			internal->inversion = IQ_SWAP_ON;
+		else
+			internal->inversion = IQ_SWAP_OFF;
+
+		internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
 		dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
 	}
 
@@ -444,7 +452,7 @@ static enum stb0899_status stb0899_check
 	int range_offst, tp_freq;
 
 	range_offst = internal->srch_range / 2000;
-	tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000;
+	tp_freq = internal->freq - (internal->derot_freq * internal->mclk) / 1000;
 
 	if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
 		internal->status = RANGEOK;
@@ -638,7 +646,7 @@ enum stb0899_status stb0899_dvbs_algo(st
 							"RANGE OK ! derot freq=%d, mclk=%d",
 							internal->derot_freq, internal->mclk);
 
-						internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000);
+						internal->freq = params->freq - ((internal->derot_freq * internal->mclk) / 1000);
 						reg = stb0899_read_reg(state, STB0899_PLPARM);
 						internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
 						dprintk(state->verbose, FE_DEBUG, 1,
@@ -1373,9 +1381,6 @@ enum stb0899_status stb0899_dvbs2_algo(s
 	case IQ_SWAP_ON:
 		STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
 		break;
-	case IQ_SWAP_AUTO:	/* use last successful search first	*/
-		STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
-		break;
 	}
 	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
 	stb0899_dvbs2_reacquire(state);
@@ -1405,41 +1410,39 @@ enum stb0899_status stb0899_dvbs2_algo(s
 	}
 
 	if (internal->status != DVBS2_FEC_LOCK) {
-		if (internal->inversion == IQ_SWAP_AUTO) {
-			reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
-			iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
-			/* IQ Spectrum Inversion	*/
-			STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
-			stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
-			/* start acquistion process	*/
-			stb0899_dvbs2_reacquire(state);
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+		iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
+		/* IQ Spectrum Inversion	*/
+		STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
+		/* start acquistion process	*/
+		stb0899_dvbs2_reacquire(state);
 
-			/* Wait for demod lock (UWP and CSM)	*/
-			internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
-			if (internal->status == DVBS2_DEMOD_LOCK) {
-				i = 0;
-				/* Demod Locked, check FEC	*/
-				internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
-				/*try thrice for false locks, (UWP and CSM Locked but no FEC)	*/
-				while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
-					/*	Read the frequency offset*/
-					offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+		/* Wait for demod lock (UWP and CSM)	*/
+		internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
+		if (internal->status == DVBS2_DEMOD_LOCK) {
+			i = 0;
+			/* Demod Locked, check FEC	*/
+			internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+			/*try thrice for false locks, (UWP and CSM Locked but no FEC)	*/
+			while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+				/*	Read the frequency offset*/
+				offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
 
-					/* Set the Nominal frequency to the found frequency offset for the next reacquire*/
-					reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
-					STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
-					stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+				/* Set the Nominal frequency to the found frequency offset for the next reacquire*/
+				reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+				STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
+				stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
 
-					stb0899_dvbs2_reacquire(state);
-					internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
-					i++;
-				}
+				stb0899_dvbs2_reacquire(state);
+				internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+				i++;
 			}
+		}
 /*
-			if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
-				pParams->IQLocked = !iqSpectrum;
+		if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
+			pParams->IQLocked = !iqSpectrum;
 */
-		}
 	}
 	if (internal->status == DVBS2_FEC_LOCK) {
 		dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
@@ -1487,13 +1490,21 @@ enum stb0899_status stb0899_dvbs2_algo(s
 		/* Store signal parameters	*/
 		offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
 
+		/* sign extend 30 bit value before using it in calculations */
+		if (offsetfreq & (1 << 29))
+			offsetfreq |= -1 << 30;
+
 		offsetfreq = offsetfreq / ((1 << 30) / 1000);
 		offsetfreq *= (internal->master_clk / 1000000);
+
+		/* store current inversion for next run */
 		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
 		if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
-			offsetfreq *= -1;
+			internal->inversion = IQ_SWAP_ON;
+		else
+			internal->inversion = IQ_SWAP_OFF;
 
-		internal->freq = internal->freq - offsetfreq;
+		internal->freq = internal->freq + offsetfreq;
 		internal->srate = stb0899_dvbs2_get_srate(state);
 
 		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-frontends/stb0899_drv.c linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/stb0899_drv.c
--- linux-libre-3.10-gnu/drivers/media/dvb-frontends/stb0899_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/stb0899_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -1618,19 +1618,18 @@ static struct dvb_frontend_ops stb0899_o
 struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
 {
 	struct stb0899_state *state = NULL;
-	enum stb0899_inversion inversion;
 
 	state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
 	if (state == NULL)
 		goto error;
 
-	inversion				= config->inversion;
 	state->verbose				= &verbose;
 	state->config				= config;
 	state->i2c				= i2c;
 	state->frontend.ops			= stb0899_ops;
 	state->frontend.demodulator_priv	= state;
-	state->internal.inversion		= inversion;
+	/* use configured inversion as default -- we'll later autodetect inversion */
+	state->internal.inversion		= config->inversion;
 
 	stb0899_wakeup(&state->frontend);
 	if (stb0899_get_dev_id(state) == -ENODEV) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-frontends/stb0899_drv.h linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/stb0899_drv.h
--- linux-libre-3.10-gnu/drivers/media/dvb-frontends/stb0899_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/stb0899_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -45,9 +45,8 @@ struct stb0899_s2_reg {
 };
 
 enum stb0899_inversion {
-	IQ_SWAP_OFF	= 0,
-	IQ_SWAP_ON,
-	IQ_SWAP_AUTO
+	IQ_SWAP_OFF	= +1, /* inversion affects the sign of e. g. */
+	IQ_SWAP_ON	= -1, /* the derotator frequency register    */
 };
 
 #define STB0899_GPIO00				0xf140
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/dvb-frontends/stv0367.c linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/stv0367.c
--- linux-libre-3.10-gnu/drivers/media/dvb-frontends/stv0367.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/dvb-frontends/stv0367.c	2013-08-25 20:43:22.000000000 -0400
@@ -2919,7 +2919,7 @@ enum stv0367_cab_signal_type stv0367cab_
 	if (tuner_lock == 0)
 		return FE_367CAB_NOTUNER;
 #endif
-	/* Relase the TRL to start demodulator acquisition */
+	/* Release the TRL to start demodulator acquisition */
 	/* Wait for QAM lock */
 	LockTime = 0;
 	stv0367_writereg(state, R367CAB_CTRL_1, 0x00);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/firewire/firedtv-fw.c linux-libre-3.11-rc7-gnu/drivers/media/firewire/firedtv-fw.c
--- linux-libre-3.10-gnu/drivers/media/firewire/firedtv-fw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/firewire/firedtv-fw.c	2013-08-25 20:43:22.000000000 -0400
@@ -248,7 +248,7 @@ static const char * const model_names[]
 /* Adjust the template string if models with longer names appear. */
 #define MAX_MODEL_NAME_LEN sizeof("FireDTV ????")
 
-static int node_probe(struct device *dev)
+static int node_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
 {
 	struct firedtv *fdtv;
 	char name[MAX_MODEL_NAME_LEN];
@@ -258,8 +258,8 @@ static int node_probe(struct device *dev
 	if (!fdtv)
 		return -ENOMEM;
 
-	dev_set_drvdata(dev, fdtv);
-	fdtv->device		= dev;
+	dev_set_drvdata(&unit->device, fdtv);
+	fdtv->device		= &unit->device;
 	fdtv->isochannel	= -1;
 	fdtv->voltage		= 0xff;
 	fdtv->tone		= 0xff;
@@ -269,7 +269,7 @@ static int node_probe(struct device *dev
 	mutex_init(&fdtv->demux_mutex);
 	INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
 
-	name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
+	name_len = fw_csr_string(unit->directory, CSR_MODEL,
 				 name, sizeof(name));
 	for (i = ARRAY_SIZE(model_names); --i; )
 		if (strlen(model_names[i]) <= name_len &&
@@ -277,7 +277,7 @@ static int node_probe(struct device *dev
 			break;
 	fdtv->type = i;
 
-	err = fdtv_register_rc(fdtv, dev);
+	err = fdtv_register_rc(fdtv, &unit->device);
 	if (err)
 		goto fail_free;
 
@@ -307,9 +307,9 @@ fail_free:
 	return err;
 }
 
-static int node_remove(struct device *dev)
+static void node_remove(struct fw_unit *unit)
 {
-	struct firedtv *fdtv = dev_get_drvdata(dev);
+	struct firedtv *fdtv = dev_get_drvdata(&unit->device);
 
 	fdtv_dvb_unregister(fdtv);
 
@@ -320,7 +320,6 @@ static int node_remove(struct device *de
 	fdtv_unregister_rc(fdtv);
 
 	kfree(fdtv);
-	return 0;
 }
 
 static void node_update(struct fw_unit *unit)
@@ -391,10 +390,10 @@ static struct fw_driver fdtv_driver = {
 		.owner  = THIS_MODULE,
 		.name   = "firedtv",
 		.bus    = &fw_bus_type,
-		.probe  = node_probe,
-		.remove = node_remove,
 	},
+	.probe    = node_probe,
 	.update   = node_update,
+	.remove   = node_remove,
 	.id_table = fdtv_id_table,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ad9389b.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/ad9389b.c
--- linux-libre-3.10-gnu/drivers/media/i2c/ad9389b.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ad9389b.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/workqueue.h>
 #include <linux/v4l2-dv-timings.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 #include <media/ad9389b.h>
@@ -343,12 +342,6 @@ static const struct v4l2_ctrl_ops ad9389
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ad9389b_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = ad9389b_rd(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -356,24 +349,11 @@ static int ad9389b_g_register(struct v4l
 
 static int ad9389b_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	ad9389b_wr(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int ad9389b_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_AD9389B, 0);
-}
-
 static int ad9389b_log_status(struct v4l2_subdev *sd)
 {
 	struct ad9389b_state *state = get_ad9389b_state(sd);
@@ -600,7 +580,6 @@ static int ad9389b_isr(struct v4l2_subde
 
 static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
 	.log_status = ad9389b_log_status,
-	.g_chip_ident = ad9389b_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = ad9389b_g_register,
 	.s_register = ad9389b_s_register,
@@ -1188,15 +1167,14 @@ static int ad9389b_probe(struct i2c_clie
 	v4l_dbg(1, debug, client, "detecting ad9389b client on address 0x%x\n",
 			client->addr << 1);
 
-	state = kzalloc(sizeof(struct ad9389b_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return -ENOMEM;
 
 	/* Platform data */
 	if (pdata == NULL) {
 		v4l_err(client, "No platform data!\n");
-		err = -ENODEV;
-		goto err_free;
+		return -ENODEV;
 	}
 	memcpy(&state->pdata, pdata, sizeof(state->pdata));
 
@@ -1251,12 +1229,14 @@ static int ad9389b_probe(struct i2c_clie
 	state->edid_i2c_client = i2c_new_dummy(client->adapter, (0x7e>>1));
 	if (state->edid_i2c_client == NULL) {
 		v4l2_err(sd, "failed to register edid i2c client\n");
+		err = -ENOMEM;
 		goto err_entity;
 	}
 
 	state->work_queue = create_singlethread_workqueue(sd->name);
 	if (state->work_queue == NULL) {
 		v4l2_err(sd, "could not create workqueue\n");
+		err = -ENOMEM;
 		goto err_unreg;
 	}
 
@@ -1276,8 +1256,6 @@ err_entity:
 	media_entity_cleanup(&sd->entity);
 err_hdl:
 	v4l2_ctrl_handler_free(&state->hdl);
-err_free:
-	kfree(state);
 	return err;
 }
 
@@ -1302,15 +1280,14 @@ static int ad9389b_remove(struct i2c_cli
 	v4l2_device_unregister_subdev(sd);
 	media_entity_cleanup(&sd->entity);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	kfree(get_ad9389b_state(sd));
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_device_id ad9389b_id[] = {
-	{ "ad9389b", V4L2_IDENT_AD9389B },
-	{ "ad9889b", V4L2_IDENT_AD9389B },
+	{ "ad9389b", 0 },
+	{ "ad9889b", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ad9389b_id);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/adp1653.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/adp1653.c
--- linux-libre-3.10-gnu/drivers/media/i2c/adp1653.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/adp1653.c	2013-08-25 20:43:22.000000000 -0400
@@ -417,7 +417,7 @@ static int adp1653_probe(struct i2c_clie
 	if (client->dev.platform_data == NULL)
 		return -ENODEV;
 
-	flash = kzalloc(sizeof(*flash), GFP_KERNEL);
+	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
 	if (flash == NULL)
 		return -ENOMEM;
 
@@ -443,7 +443,6 @@ static int adp1653_probe(struct i2c_clie
 
 free_and_quit:
 	v4l2_ctrl_handler_free(&flash->ctrls);
-	kfree(flash);
 	return ret;
 }
 
@@ -455,7 +454,7 @@ static int adp1653_remove(struct i2c_cli
 	v4l2_device_unregister_subdev(&flash->subdev);
 	v4l2_ctrl_handler_free(&flash->ctrls);
 	media_entity_cleanup(&flash->subdev.entity);
-	kfree(flash);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/adv7170.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7170.c
--- linux-libre-3.10-gnu/drivers/media/i2c/adv7170.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7170.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
 MODULE_AUTHOR("Maxim Yevtyushkin");
@@ -317,19 +316,8 @@ static int adv7170_s_fmt(struct v4l2_sub
 	return ret;
 }
 
-static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7170, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops adv7170_core_ops = {
-	.g_chip_ident = adv7170_g_chip_ident,
-};
-
 static const struct v4l2_subdev_video_ops adv7170_video_ops = {
 	.s_std_output = adv7170_s_std_output,
 	.s_routing = adv7170_s_routing,
@@ -339,7 +327,6 @@ static const struct v4l2_subdev_video_op
 };
 
 static const struct v4l2_subdev_ops adv7170_ops = {
-	.core = &adv7170_core_ops,
 	.video = &adv7170_video_ops,
 };
 
@@ -359,7 +346,7 @@ static int adv7170_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	sd = &encoder->sd;
@@ -384,7 +371,6 @@ static int adv7170_remove(struct i2c_cli
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_adv7170(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/adv7175.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7175.c
--- linux-libre-3.10-gnu/drivers/media/i2c/adv7175.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7175.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
 MODULE_AUTHOR("Dave Perks");
@@ -355,13 +354,6 @@ static int adv7175_s_fmt(struct v4l2_sub
 	return ret;
 }
 
-static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
-}
-
 static int adv7175_s_power(struct v4l2_subdev *sd, int on)
 {
 	if (on)
@@ -375,7 +367,6 @@ static int adv7175_s_power(struct v4l2_s
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops adv7175_core_ops = {
-	.g_chip_ident = adv7175_g_chip_ident,
 	.init = adv7175_init,
 	.s_power = adv7175_s_power,
 };
@@ -409,7 +400,7 @@ static int adv7175_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	sd = &encoder->sd;
@@ -434,7 +425,6 @@ static int adv7175_remove(struct i2c_cli
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_adv7175(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/adv7180.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7180.c
--- linux-libre-3.10-gnu/drivers/media/i2c/adv7180.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7180.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,8 @@
 /*
  * adv7180.c Analog Devices ADV7180 video decoder driver
  * Copyright (c) 2009 Intel Corporation
+ * Copyright (C) 2013 Cogent Embedded, Inc.
+ * Copyright (C) 2013 Renesas Solutions Corp.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -27,7 +29,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/mutex.h>
 
 #define ADV7180_INPUT_CONTROL_REG			0x00
@@ -272,14 +273,6 @@ static int adv7180_g_input_status(struct
 	return ret;
 }
 
-static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
-}
-
 static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 {
 	struct adv7180_state *state = to_state(sd);
@@ -397,14 +390,57 @@ static void adv7180_exit_controls(struct
 	v4l2_ctrl_handler_free(&state->ctrl_hdl);
 }
 
+static int adv7180_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+				 enum v4l2_mbus_pixelcode *code)
+{
+	if (index > 0)
+		return -EINVAL;
+
+	*code = V4L2_MBUS_FMT_YUYV8_2X8;
+
+	return 0;
+}
+
+static int adv7180_mbus_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_mbus_framefmt *fmt)
+{
+	struct adv7180_state *state = to_state(sd);
+
+	fmt->code = V4L2_MBUS_FMT_YUYV8_2X8;
+	fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	fmt->field = V4L2_FIELD_INTERLACED;
+	fmt->width = 720;
+	fmt->height = state->curr_norm & V4L2_STD_525_60 ? 480 : 576;
+
+	return 0;
+}
+
+static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
+				 struct v4l2_mbus_config *cfg)
+{
+	/*
+	 * The ADV7180 sensor supports BT.601/656 output modes.
+	 * The BT.656 is default and not yet configurable by s/w.
+	 */
+	cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
+		     V4L2_MBUS_DATA_ACTIVE_HIGH;
+	cfg->type = V4L2_MBUS_BT656;
+
+	return 0;
+}
+
 static const struct v4l2_subdev_video_ops adv7180_video_ops = {
 	.querystd = adv7180_querystd,
 	.g_input_status = adv7180_g_input_status,
 	.s_routing = adv7180_s_routing,
+	.enum_mbus_fmt = adv7180_enum_mbus_fmt,
+	.try_mbus_fmt = adv7180_mbus_fmt,
+	.g_mbus_fmt = adv7180_mbus_fmt,
+	.s_mbus_fmt = adv7180_mbus_fmt,
+	.g_mbus_config = adv7180_g_mbus_config,
 };
 
 static const struct v4l2_subdev_core_ops adv7180_core_ops = {
-	.g_chip_ident = adv7180_g_chip_ident,
 	.s_std = adv7180_s_std,
 };
 
@@ -555,7 +591,7 @@ static int adv7180_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 		 client->addr, client->adapter->name);
 
-	state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL) {
 		ret = -ENOMEM;
 		goto err;
@@ -582,7 +618,6 @@ err_free_ctrl:
 err_unreg_subdev:
 	mutex_destroy(&state->mutex);
 	v4l2_device_unregister_subdev(sd);
-	kfree(state);
 err:
 	printk(KERN_ERR KBUILD_MODNAME ": Failed to probe: %d\n", ret);
 	return ret;
@@ -607,7 +642,6 @@ static int adv7180_remove(struct i2c_cli
 
 	mutex_destroy(&state->mutex);
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
@@ -616,9 +650,10 @@ static const struct i2c_device_id adv718
 	{},
 };
 
-#ifdef CONFIG_PM
-static int adv7180_suspend(struct i2c_client *client, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int adv7180_suspend(struct device *dev)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	int ret;
 
 	ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
@@ -628,8 +663,9 @@ static int adv7180_suspend(struct i2c_cl
 	return 0;
 }
 
-static int adv7180_resume(struct i2c_client *client)
+static int adv7180_resume(struct device *dev)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct adv7180_state *state = to_state(sd);
 	int ret;
@@ -643,6 +679,12 @@ static int adv7180_resume(struct i2c_cli
 		return ret;
 	return 0;
 }
+
+static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume);
+#define ADV7180_PM_OPS (&adv7180_pm_ops)
+
+#else
+#define ADV7180_PM_OPS NULL
 #endif
 
 MODULE_DEVICE_TABLE(i2c, adv7180_id);
@@ -651,13 +693,10 @@ static struct i2c_driver adv7180_driver
 	.driver = {
 		   .owner = THIS_MODULE,
 		   .name = KBUILD_MODNAME,
+		   .pm = ADV7180_PM_OPS,
 		   },
 	.probe = adv7180_probe,
 	.remove = adv7180_remove,
-#ifdef CONFIG_PM
-	.suspend = adv7180_suspend,
-	.resume = adv7180_resume,
-#endif
 	.id_table = adv7180_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/adv7183.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7183.c
--- linux-libre-3.10-gnu/drivers/media/i2c/adv7183.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7183.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/videodev2.h>
 
 #include <media/adv7183.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 
@@ -375,28 +374,28 @@ static int adv7183_querystd(struct v4l2_
 	reg = adv7183_read(sd, ADV7183_STATUS_1);
 	switch ((reg >> 0x4) & 0x7) {
 	case 0:
-		*std = V4L2_STD_NTSC;
+		*std &= V4L2_STD_NTSC;
 		break;
 	case 1:
-		*std = V4L2_STD_NTSC_443;
+		*std &= V4L2_STD_NTSC_443;
 		break;
 	case 2:
-		*std = V4L2_STD_PAL_M;
+		*std &= V4L2_STD_PAL_M;
 		break;
 	case 3:
-		*std = V4L2_STD_PAL_60;
+		*std &= V4L2_STD_PAL_60;
 		break;
 	case 4:
-		*std = V4L2_STD_PAL;
+		*std &= V4L2_STD_PAL;
 		break;
 	case 5:
-		*std = V4L2_STD_SECAM;
+		*std &= V4L2_STD_SECAM;
 		break;
 	case 6:
-		*std = V4L2_STD_PAL_Nc;
+		*std &= V4L2_STD_PAL_Nc;
 		break;
 	case 7:
-		*std = V4L2_STD_SECAM;
+		*std &= V4L2_STD_SECAM;
 		break;
 	default:
 		*std = V4L2_STD_UNKNOWN;
@@ -474,34 +473,16 @@ static int adv7183_s_stream(struct v4l2_
 	struct adv7183 *decoder = to_adv7183(sd);
 
 	if (enable)
-		gpio_direction_output(decoder->oe_pin, 0);
+		gpio_set_value(decoder->oe_pin, 0);
 	else
-		gpio_direction_output(decoder->oe_pin, 1);
+		gpio_set_value(decoder->oe_pin, 1);
 	udelay(1);
 	return 0;
 }
 
-static int adv7183_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	int rev;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	/* 0x11 for adv7183, 0x13 for adv7183b */
-	rev = adv7183_read(sd, ADV7183_IDENT);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7183, rev);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int adv7183_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = adv7183_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -509,12 +490,6 @@ static int adv7183_g_register(struct v4l
 
 static int adv7183_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	adv7183_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
@@ -529,7 +504,6 @@ static const struct v4l2_subdev_core_ops
 	.g_std = adv7183_g_std,
 	.s_std = adv7183_s_std,
 	.reset = adv7183_reset,
-	.g_chip_ident = adv7183_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = adv7183_g_register,
 	.s_register = adv7183_s_register,
@@ -573,23 +547,24 @@ static int adv7183_probe(struct i2c_clie
 	if (pin_array == NULL)
 		return -EINVAL;
 
-	decoder = kzalloc(sizeof(struct adv7183), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (decoder == NULL)
 		return -ENOMEM;
 
 	decoder->reset_pin = pin_array[0];
 	decoder->oe_pin = pin_array[1];
 
-	if (gpio_request(decoder->reset_pin, "ADV7183 Reset")) {
+	if (devm_gpio_request_one(&client->dev, decoder->reset_pin,
+				  GPIOF_OUT_INIT_LOW, "ADV7183 Reset")) {
 		v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin);
-		ret = -EBUSY;
-		goto err_free_decoder;
+		return -EBUSY;
 	}
 
-	if (gpio_request(decoder->oe_pin, "ADV7183 Output Enable")) {
+	if (devm_gpio_request_one(&client->dev, decoder->oe_pin,
+				  GPIOF_OUT_INIT_HIGH,
+				  "ADV7183 Output Enable")) {
 		v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin);
-		ret = -EBUSY;
-		goto err_free_reset;
+		return -EBUSY;
 	}
 
 	sd = &decoder->sd;
@@ -611,7 +586,7 @@ static int adv7183_probe(struct i2c_clie
 		ret = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		goto err_free_oe;
+		return ret;
 	}
 
 	/* v4l2 doesn't support an autodetect standard, pick PAL as default */
@@ -619,12 +594,10 @@ static int adv7183_probe(struct i2c_clie
 	decoder->input = ADV7183_COMPOSITE4;
 	decoder->output = ADV7183_8BIT_OUT;
 
-	gpio_direction_output(decoder->oe_pin, 1);
 	/* reset chip */
-	gpio_direction_output(decoder->reset_pin, 0);
 	/* reset pulse width at least 5ms */
 	mdelay(10);
-	gpio_direction_output(decoder->reset_pin, 1);
+	gpio_set_value(decoder->reset_pin, 1);
 	/* wait 5ms before any further i2c writes are performed */
 	mdelay(5);
 
@@ -638,29 +611,18 @@ static int adv7183_probe(struct i2c_clie
 	ret = v4l2_ctrl_handler_setup(hdl);
 	if (ret) {
 		v4l2_ctrl_handler_free(hdl);
-		goto err_free_oe;
+		return ret;
 	}
 
 	return 0;
-err_free_oe:
-	gpio_free(decoder->oe_pin);
-err_free_reset:
-	gpio_free(decoder->reset_pin);
-err_free_decoder:
-	kfree(decoder);
-	return ret;
 }
 
 static int adv7183_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct adv7183 *decoder = to_adv7183(sd);
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	gpio_free(decoder->oe_pin);
-	gpio_free(decoder->reset_pin);
-	kfree(decoder);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/adv7343.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7343.c
--- linux-libre-3.10-gnu/drivers/media/i2c/adv7343.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7343.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,6 @@
 
 #include <media/adv7343.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #include "adv7343_regs.h"
@@ -311,21 +310,12 @@ static int adv7343_s_ctrl(struct v4l2_ct
 	return -EINVAL;
 }
 
-static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0);
-}
-
 static const struct v4l2_ctrl_ops adv7343_ctrl_ops = {
 	.s_ctrl = adv7343_s_ctrl,
 };
 
 static const struct v4l2_subdev_core_ops adv7343_core_ops = {
 	.log_status = adv7343_log_status,
-	.g_chip_ident = adv7343_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/adv7393.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7393.c
--- linux-libre-3.10-gnu/drivers/media/i2c/adv7393.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7393.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,6 @@
 
 #include <media/adv7393.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #include "adv7393_regs.h"
@@ -301,21 +300,12 @@ static int adv7393_s_ctrl(struct v4l2_ct
 	return -EINVAL;
 }
 
-static int adv7393_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7393, 0);
-}
-
 static const struct v4l2_ctrl_ops adv7393_ctrl_ops = {
 	.s_ctrl = adv7393_s_ctrl,
 };
 
 static const struct v4l2_subdev_core_ops adv7393_core_ops = {
 	.log_status = adv7393_log_status,
-	.g_chip_ident = adv7393_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -410,7 +400,7 @@ static int adv7393_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct adv7393_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 
@@ -444,16 +434,13 @@ static int adv7393_probe(struct i2c_clie
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&state->hdl);
 
 	err = adv7393_initialize(&state->sd);
-	if (err) {
+	if (err)
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
-	}
 	return err;
 }
 
@@ -464,7 +451,6 @@ static int adv7393_remove(struct i2c_cli
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/adv7604.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7604.c
--- linux-libre-3.10-gnu/drivers/media/i2c/adv7604.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/adv7604.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,6 @@
 #include <linux/v4l2-dv-timings.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/adv7604.h>
 
 static int debug;
@@ -643,12 +642,6 @@ static void adv7604_inv_register(struct
 static int adv7604_g_register(struct v4l2_subdev *sd,
 					struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 1;
 	switch (reg->reg >> 8) {
 	case 0:
@@ -701,12 +694,6 @@ static int adv7604_g_register(struct v4l
 static int adv7604_s_register(struct v4l2_subdev *sd,
 					const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	switch (reg->reg >> 8) {
 	case 0:
 		io_write(sd, reg->reg & 0xff, reg->val & 0xff);
@@ -984,14 +971,6 @@ static int adv7604_s_ctrl(struct v4l2_ct
 	return -EINVAL;
 }
 
-static int adv7604_g_chip_ident(struct v4l2_subdev *sd,
-					struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7604, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static inline bool no_power(struct v4l2_subdev *sd)
@@ -1787,7 +1766,6 @@ static const struct v4l2_subdev_core_ops
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
-	.g_chip_ident = adv7604_g_chip_ident,
 	.interrupt_service_routine = adv7604_isr,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = adv7604_g_register,
@@ -1968,7 +1946,7 @@ static int adv7604_probe(struct i2c_clie
 	v4l_dbg(1, debug, client, "detecting adv7604 client on address 0x%x\n",
 			client->addr << 1);
 
-	state = kzalloc(sizeof(struct adv7604_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (!state) {
 		v4l_err(client, "Could not allocate adv7604_state memory!\n");
 		return -ENOMEM;
@@ -1977,8 +1955,7 @@ static int adv7604_probe(struct i2c_clie
 	/* platform data */
 	if (!pdata) {
 		v4l_err(client, "No platform data!\n");
-		err = -ENODEV;
-		goto err_state;
+		return -ENODEV;
 	}
 	memcpy(&state->pdata, pdata, sizeof(state->pdata));
 
@@ -1991,8 +1968,7 @@ static int adv7604_probe(struct i2c_clie
 	if (adv_smbus_read_byte_data_check(client, 0xfb, false) != 0x68) {
 		v4l2_info(sd, "not an adv7604 on address 0x%x\n",
 				client->addr << 1);
-		err = -ENODEV;
-		goto err_state;
+		return -ENODEV;
 	}
 
 	/* control handlers */
@@ -2093,8 +2069,6 @@ err_i2c:
 	adv7604_unregister_clients(state);
 err_hdl:
 	v4l2_ctrl_handler_free(hdl);
-err_state:
-	kfree(state);
 	return err;
 }
 
@@ -2111,7 +2085,6 @@ static int adv7604_remove(struct i2c_cli
 	media_entity_cleanup(&sd->entity);
 	adv7604_unregister_clients(to_state(sd));
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ak881x.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/ak881x.c
--- linux-libre-3.10-gnu/drivers/media/i2c/ak881x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ak881x.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 
 #include <media/ak881x.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 
@@ -33,7 +32,6 @@ struct ak881x {
 	struct v4l2_subdev subdev;
 	struct ak881x_pdata *pdata;
 	unsigned int lines;
-	int id;	/* DEVICE_ID code V4L2_IDENT_AK881X code from v4l2-chip-ident.h */
 	char revision;	/* DEVICE_REVISION content */
 };
 
@@ -62,36 +60,16 @@ static struct ak881x *to_ak881x(const st
 	return container_of(i2c_get_clientdata(client), struct ak881x, subdev);
 }
 
-static int ak881x_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ak881x *ak881x = to_ak881x(client);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= ak881x->id;
-	id->revision	= ak881x->revision;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ak881x_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
+	if (reg->reg > 0x26)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
+	reg->size = 1;
 	reg->val = reg_read(client, reg->reg);
 
 	if (reg->val > 0xffff)
@@ -105,12 +83,9 @@ static int ak881x_s_register(struct v4l2
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
+	if (reg->reg > 0x26)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -229,7 +204,6 @@ static int ak881x_s_stream(struct v4l2_s
 }
 
 static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = {
-	.g_chip_ident	= ak881x_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= ak881x_g_register,
 	.s_register	= ak881x_s_register,
@@ -264,7 +238,7 @@ static int ak881x_probe(struct i2c_clien
 		return -EIO;
 	}
 
-	ak881x = kzalloc(sizeof(struct ak881x), GFP_KERNEL);
+	ak881x = devm_kzalloc(&client->dev, sizeof(*ak881x), GFP_KERNEL);
 	if (!ak881x)
 		return -ENOMEM;
 
@@ -274,15 +248,11 @@ static int ak881x_probe(struct i2c_clien
 
 	switch (data) {
 	case 0x13:
-		ak881x->id = V4L2_IDENT_AK8813;
-		break;
 	case 0x14:
-		ak881x->id = V4L2_IDENT_AK8814;
 		break;
 	default:
 		dev_err(&client->dev,
 			"No ak881x chip detected, register read %x\n", data);
-		kfree(ak881x);
 		return -ENODEV;
 	}
 
@@ -331,7 +301,6 @@ static int ak881x_remove(struct i2c_clie
 	struct ak881x *ak881x = to_ak881x(client);
 
 	v4l2_device_unregister_subdev(&ak881x->subdev);
-	kfree(ak881x);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/as3645a.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/as3645a.c
--- linux-libre-3.10-gnu/drivers/media/i2c/as3645a.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/as3645a.c	2013-08-25 20:43:22.000000000 -0400
@@ -813,7 +813,7 @@ static int as3645a_probe(struct i2c_clie
 	if (client->dev.platform_data == NULL)
 		return -ENODEV;
 
-	flash = kzalloc(sizeof(*flash), GFP_KERNEL);
+	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
 	if (flash == NULL)
 		return -ENOMEM;
 
@@ -838,10 +838,8 @@ static int as3645a_probe(struct i2c_clie
 	flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
 
 done:
-	if (ret < 0) {
+	if (ret < 0)
 		v4l2_ctrl_handler_free(&flash->ctrls);
-		kfree(flash);
-	}
 
 	return ret;
 }
@@ -855,7 +853,6 @@ static int as3645a_remove(struct i2c_cli
 	v4l2_ctrl_handler_free(&flash->ctrls);
 	media_entity_cleanup(&flash->subdev.entity);
 	mutex_destroy(&flash->power_lock);
-	kfree(flash);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/bt819.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/bt819.c
--- linux-libre-3.10-gnu/drivers/media/i2c/bt819.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/bt819.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/bt819.h>
 
@@ -57,7 +56,6 @@ struct bt819 {
 	unsigned char reg[32];
 
 	v4l2_std_id norm;
-	int ident;
 	int input;
 	int enable;
 };
@@ -217,15 +215,17 @@ static int bt819_status(struct v4l2_subd
 	struct bt819 *decoder = to_bt819(sd);
 	int status = bt819_read(decoder, 0x00);
 	int res = V4L2_IN_ST_NO_SIGNAL;
-	v4l2_std_id std;
+	v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
 
 	if ((status & 0x80))
 		res = 0;
+	else
+		std = V4L2_STD_UNKNOWN;
 
 	if ((status & 0x10))
-		std = V4L2_STD_PAL;
+		std &= V4L2_STD_PAL;
 	else
-		std = V4L2_STD_NTSC;
+		std &= V4L2_STD_NTSC;
 	if (pstd)
 		*pstd = std;
 	if (pstatus)
@@ -373,14 +373,6 @@ static int bt819_s_ctrl(struct v4l2_ctrl
 	return 0;
 }
 
-static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct bt819 *decoder = to_bt819(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
@@ -388,7 +380,6 @@ static const struct v4l2_ctrl_ops bt819_
 };
 
 static const struct v4l2_subdev_core_ops bt819_core_ops = {
-	.g_chip_ident = bt819_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -425,7 +416,7 @@ static int bt819_probe(struct i2c_client
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (decoder == NULL)
 		return -ENOMEM;
 	sd = &decoder->sd;
@@ -435,15 +426,12 @@ static int bt819_probe(struct i2c_client
 	switch (ver & 0xf0) {
 	case 0x70:
 		name = "bt819a";
-		decoder->ident = V4L2_IDENT_BT819A;
 		break;
 	case 0x60:
 		name = "bt817a";
-		decoder->ident = V4L2_IDENT_BT817A;
 		break;
 	case 0x20:
 		name = "bt815a";
-		decoder->ident = V4L2_IDENT_BT815A;
 		break;
 	default:
 		v4l2_dbg(1, debug, sd,
@@ -476,7 +464,6 @@ static int bt819_probe(struct i2c_client
 		int err = decoder->hdl.error;
 
 		v4l2_ctrl_handler_free(&decoder->hdl);
-		kfree(decoder);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&decoder->hdl);
@@ -490,7 +477,6 @@ static int bt819_remove(struct i2c_clien
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&decoder->hdl);
-	kfree(decoder);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/bt856.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/bt856.c
--- linux-libre-3.10-gnu/drivers/media/i2c/bt856.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/bt856.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
 MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -177,17 +176,9 @@ static int bt856_s_routing(struct v4l2_s
 	return 0;
 }
 
-static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops bt856_core_ops = {
-	.g_chip_ident = bt856_g_chip_ident,
 	.init = bt856_init,
 };
 
@@ -216,7 +207,7 @@ static int bt856_probe(struct i2c_client
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	sd = &encoder->sd;
@@ -250,7 +241,6 @@ static int bt856_remove(struct i2c_clien
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_bt856(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/bt866.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/bt866.c
--- linux-libre-3.10-gnu/drivers/media/i2c/bt866.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/bt866.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
 MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -175,26 +174,14 @@ static int bt866_s_routing(struct v4l2_s
 	bt866_write(client, 0xdc, val);
 #endif
 
-static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops bt866_core_ops = {
-	.g_chip_ident = bt866_g_chip_ident,
-};
-
 static const struct v4l2_subdev_video_ops bt866_video_ops = {
 	.s_std_output = bt866_s_std_output,
 	.s_routing = bt866_s_routing,
 };
 
 static const struct v4l2_subdev_ops bt866_ops = {
-	.core = &bt866_core_ops,
 	.video = &bt866_video_ops,
 };
 
@@ -207,7 +194,7 @@ static int bt866_probe(struct i2c_client
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	sd = &encoder->sd;
@@ -220,7 +207,6 @@ static int bt866_remove(struct i2c_clien
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_bt866(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/cs5345.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/cs5345.c
--- linux-libre-3.10-gnu/drivers/media/i2c/cs5345.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/cs5345.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC");
@@ -99,12 +98,6 @@ static int cs5345_s_ctrl(struct v4l2_ctr
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 1;
 	reg->val = cs5345_read(sd, reg->reg & 0x1f);
 	return 0;
@@ -112,24 +105,11 @@ static int cs5345_g_register(struct v4l2
 
 static int cs5345_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	cs5345_write(sd, reg->reg & 0x1f, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int cs5345_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_CS5345, 0);
-}
-
 static int cs5345_log_status(struct v4l2_subdev *sd)
 {
 	u8 v = cs5345_read(sd, 0x09) & 7;
@@ -152,7 +132,6 @@ static const struct v4l2_ctrl_ops cs5345
 
 static const struct v4l2_subdev_core_ops cs5345_core_ops = {
 	.log_status = cs5345_log_status,
-	.g_chip_ident = cs5345_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -190,7 +169,7 @@ static int cs5345_probe(struct i2c_clien
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct cs5345_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -206,7 +185,6 @@ static int cs5345_probe(struct i2c_clien
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	/* set volume/mute */
@@ -227,7 +205,6 @@ static int cs5345_remove(struct i2c_clie
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/cs53l32a.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/cs53l32a.c
--- linux-libre-3.10-gnu/drivers/media/i2c/cs53l32a.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/cs53l32a.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
@@ -104,14 +103,6 @@ static int cs53l32a_s_ctrl(struct v4l2_c
 	return -EINVAL;
 }
 
-static int cs53l32a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client,
-			chip, V4L2_IDENT_CS53l32A, 0);
-}
-
 static int cs53l32a_log_status(struct v4l2_subdev *sd)
 {
 	struct cs53l32a_state *state = to_state(sd);
@@ -130,7 +121,6 @@ static const struct v4l2_ctrl_ops cs53l3
 
 static const struct v4l2_subdev_core_ops cs53l32a_core_ops = {
 	.log_status = cs53l32a_log_status,
-	.g_chip_ident = cs53l32a_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -175,7 +165,7 @@ static int cs53l32a_probe(struct i2c_cli
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct cs53l32a_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -197,7 +187,6 @@ static int cs53l32a_probe(struct i2c_cli
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 
@@ -228,7 +217,6 @@ static int cs53l32a_remove(struct i2c_cl
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/cx25840/cx25840-core.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/cx25840/cx25840-core.c
--- linux-libre-3.10-gnu/drivers/media/i2c/cx25840/cx25840-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/cx25840/cx25840-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,7 +45,6 @@
 #include <linux/delay.h>
 #include <linux/math64.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/cx25840.h>
 
 #include "cx25840-core.h"
@@ -498,7 +497,7 @@ static void cx23885_initialize(struct i2
 
 	/* Sys PLL */
 	switch (state->id) {
-	case V4L2_IDENT_CX23888_AV:
+	case CX23888_AV:
 		/*
 		 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
 		 * 572.73 MHz before post divide
@@ -511,7 +510,7 @@ static void cx23885_initialize(struct i2
 		cx25840_write4(client, 0x42c, 0x42600000);
 		cx25840_write4(client, 0x44c, 0x161f1000);
 		break;
-	case V4L2_IDENT_CX23887_AV:
+	case CX23887_AV:
 		/*
 		 * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
 		 * 572.73 MHz before post divide
@@ -519,7 +518,7 @@ static void cx23885_initialize(struct i2
 		cx25840_write4(client, 0x11c, 0x01d1744c);
 		cx25840_write4(client, 0x118, 0x00000416);
 		break;
-	case V4L2_IDENT_CX23885_AV:
+	case CX23885_AV:
 	default:
 		/*
 		 * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
@@ -546,7 +545,7 @@ static void cx23885_initialize(struct i2
 
 	/* HVR1850 */
 	switch (state->id) {
-	case V4L2_IDENT_CX23888_AV:
+	case CX23888_AV:
 		/* 888/HVR1250 specific */
 		cx25840_write4(client, 0x10c, 0x13333333);
 		cx25840_write4(client, 0x108, 0x00000515);
@@ -570,7 +569,7 @@ static void cx23885_initialize(struct i2
 	 * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
 	 */
 	switch (state->id) {
-	case V4L2_IDENT_CX23888_AV:
+	case CX23888_AV:
 		/*
 		 * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
 		 * 368.64 MHz before post divide
@@ -580,7 +579,7 @@ static void cx23885_initialize(struct i2
 		cx25840_write4(client, 0x114, 0x017dbf48);
 		cx25840_write4(client, 0x110, 0x000a030e);
 		break;
-	case V4L2_IDENT_CX23887_AV:
+	case CX23887_AV:
 		/*
 		 * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
 		 * 368.64 MHz before post divide
@@ -589,7 +588,7 @@ static void cx23885_initialize(struct i2
 		cx25840_write4(client, 0x114, 0x017dbf48);
 		cx25840_write4(client, 0x110, 0x000a030e);
 		break;
-	case V4L2_IDENT_CX23885_AV:
+	case CX23885_AV:
 	default:
 		/*
 		 * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
@@ -1662,10 +1661,6 @@ static int cx25840_g_register(struct v4l
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 1;
 	reg->val = cx25840_read(client, reg->reg & 0x0fff);
 	return 0;
@@ -1675,10 +1670,6 @@ static int cx25840_s_register(struct v4l
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
 	return 0;
 }
@@ -1938,14 +1929,6 @@ static int cx25840_reset(struct v4l2_sub
 	return 0;
 }
 
-static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct cx25840_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
-}
-
 static int cx25840_log_status(struct v4l2_subdev *sd)
 {
 	struct cx25840_state *state = to_state(sd);
@@ -5051,7 +5034,6 @@ static const struct v4l2_ctrl_ops cx2584
 
 static const struct v4l2_subdev_core_ops cx25840_core_ops = {
 	.log_status = cx25840_log_status,
-	.g_chip_ident = cx25840_g_chip_ident,
 	.g_ctrl = v4l2_subdev_g_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -5128,18 +5110,18 @@ static u32 get_cx2388x_ident(struct i2c_
 		ret = cx25840_read4(client, 0x300);
 		if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
 			/* No DIF */
-			ret = V4L2_IDENT_CX23885_AV;
+			ret = CX23885_AV;
 		} else {
 			/* CX23887 has a broken DIF, but the registers
 			 * appear valid (but unused), good enough to detect. */
-			ret = V4L2_IDENT_CX23887_AV;
+			ret = CX23887_AV;
 		}
 	} else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
 		/* DIF PLL Freq Word reg exists; chip must be a CX23888 */
-		ret = V4L2_IDENT_CX23888_AV;
+		ret = CX23888_AV;
 	} else {
 		v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
-		ret = V4L2_IDENT_CX23887_AV;
+		ret = CX23887_AV;
 	}
 
 	/* Back into digital power down */
@@ -5153,7 +5135,7 @@ static int cx25840_probe(struct i2c_clie
 	struct cx25840_state *state;
 	struct v4l2_subdev *sd;
 	int default_volume;
-	u32 id = V4L2_IDENT_NONE;
+	u32 id;
 	u16 device_id;
 
 	/* Check if the adapter supports the needed features */
@@ -5169,14 +5151,14 @@ static int cx25840_probe(struct i2c_clie
 	/* The high byte of the device ID should be
 	 * 0x83 for the cx2583x and 0x84 for the cx2584x */
 	if ((device_id & 0xff00) == 0x8300) {
-		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
+		id = CX25836 + ((device_id >> 4) & 0xf) - 6;
 	} else if ((device_id & 0xff00) == 0x8400) {
-		id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
+		id = CX25840 + ((device_id >> 4) & 0xf);
 	} else if (device_id == 0x0000) {
 		id = get_cx2388x_ident(client);
 	} else if ((device_id & 0xfff0) == 0x5A30) {
 		/* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
-		id = V4L2_IDENT_CX2310X_AV;
+		id = CX2310X_AV;
 	} else if ((device_id & 0xff) == (device_id >> 8)) {
 		v4l_err(client,
 			"likely a confused/unresponsive cx2388[578] A/V decoder"
@@ -5190,7 +5172,7 @@ static int cx25840_probe(struct i2c_clie
 		return -ENODEV;
 	}
 
-	state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 
@@ -5198,26 +5180,26 @@ static int cx25840_probe(struct i2c_clie
 	v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
 
 	switch (id) {
-	case V4L2_IDENT_CX23885_AV:
+	case CX23885_AV:
 		v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
 			 client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX23887_AV:
+	case CX23887_AV:
 		v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
 			 client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX23888_AV:
+	case CX23888_AV:
 		v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
 			 client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX2310X_AV:
+	case CX2310X_AV:
 		v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
 			 device_id, client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX25840:
-	case V4L2_IDENT_CX25841:
-	case V4L2_IDENT_CX25842:
-	case V4L2_IDENT_CX25843:
+	case CX25840:
+	case CX25841:
+	case CX25842:
+	case CX25843:
 		/* Note: revision '(device_id & 0x0f) == 2' was never built. The
 		   marking skips from 0x1 == 22 to 0x3 == 23. */
 		v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
@@ -5226,8 +5208,8 @@ static int cx25840_probe(struct i2c_clie
 						: (device_id & 0x0f),
 			 client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX25836:
-	case V4L2_IDENT_CX25837:
+	case CX25836:
+	case CX25837:
 	default:
 		v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
 			 (device_id & 0xfff0) >> 4, device_id & 0x0f,
@@ -5292,7 +5274,6 @@ static int cx25840_probe(struct i2c_clie
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	if (!is_cx2583x(state))
@@ -5317,7 +5298,6 @@ static int cx25840_remove(struct i2c_cli
 	cx25840_ir_remove(sd);
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/cx25840/cx25840-core.h linux-libre-3.11-rc7-gnu/drivers/media/i2c/cx25840/cx25840-core.h
--- linux-libre-3.10-gnu/drivers/media/i2c/cx25840/cx25840-core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/cx25840/cx25840-core.h	2013-08-25 20:43:22.000000000 -0400
@@ -23,12 +23,24 @@
 
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <linux/i2c.h>
 
 struct cx25840_ir_state;
 
+enum cx25840_model {
+	CX23885_AV,
+	CX23887_AV,
+	CX23888_AV,
+	CX2310X_AV,
+	CX25840,
+	CX25841,
+	CX25842,
+	CX25843,
+	CX25836,
+	CX25837,
+};
+
 struct cx25840_state {
 	struct i2c_client *c;
 	struct v4l2_subdev sd;
@@ -46,7 +58,7 @@ struct cx25840_state {
 	u32 audclk_freq;
 	int audmode;
 	int vbi_line_offset;
-	u32 id;
+	enum cx25840_model id;
 	u32 rev;
 	int is_initialized;
 	wait_queue_head_t fw_wait;    /* wake up when the fw load is finished */
@@ -66,35 +78,35 @@ static inline struct v4l2_subdev *to_sd(
 
 static inline bool is_cx2583x(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX25836 ||
-	       state->id == V4L2_IDENT_CX25837;
+	return state->id == CX25836 ||
+	       state->id == CX25837;
 }
 
 static inline bool is_cx231xx(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX2310X_AV;
+	return state->id == CX2310X_AV;
 }
 
 static inline bool is_cx2388x(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX23885_AV ||
-	       state->id == V4L2_IDENT_CX23887_AV ||
-	       state->id == V4L2_IDENT_CX23888_AV;
+	return state->id == CX23885_AV ||
+	       state->id == CX23887_AV ||
+	       state->id == CX23888_AV;
 }
 
 static inline bool is_cx23885(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX23885_AV;
+	return state->id == CX23885_AV;
 }
 
 static inline bool is_cx23887(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX23887_AV;
+	return state->id == CX23887_AV;
 }
 
 static inline bool is_cx23888(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX23888_AV;
+	return state->id == CX23888_AV;
 }
 
 /* ----------------------------------------------------------------------- */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/cx25840/cx25840-ir.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/cx25840/cx25840-ir.c
--- linux-libre-3.10-gnu/drivers/media/i2c/cx25840/cx25840-ir.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/cx25840/cx25840-ir.c	2013-08-25 20:43:22.000000000 -0400
@@ -1230,16 +1230,14 @@ int cx25840_ir_probe(struct v4l2_subdev
 	if (!(is_cx23885(state) || is_cx23887(state)))
 		return 0;
 
-	ir_state = kzalloc(sizeof(struct cx25840_ir_state), GFP_KERNEL);
+	ir_state = devm_kzalloc(&state->c->dev, sizeof(*ir_state), GFP_KERNEL);
 	if (ir_state == NULL)
 		return -ENOMEM;
 
 	spin_lock_init(&ir_state->rx_kfifo_lock);
 	if (kfifo_alloc(&ir_state->rx_kfifo,
-			CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL)) {
-		kfree(ir_state);
+			CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL))
 		return -ENOMEM;
-	}
 
 	ir_state->c = state->c;
 	state->ir_state = ir_state;
@@ -1273,7 +1271,6 @@ int cx25840_ir_remove(struct v4l2_subdev
 	cx25840_ir_tx_shutdown(sd);
 
 	kfifo_free(&ir_state->rx_kfifo);
-	kfree(ir_state);
 	state->ir_state = NULL;
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ir-kbd-i2c.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/ir-kbd-i2c.c
--- linux-libre-3.10-gnu/drivers/media/i2c/ir-kbd-i2c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ir-kbd-i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -295,7 +295,7 @@ static int ir_probe(struct i2c_client *c
 	unsigned short addr = client->addr;
 	int err;
 
-	ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
+	ir = devm_kzalloc(&client->dev, sizeof(*ir), GFP_KERNEL);
 	if (!ir)
 		return -ENOMEM;
 
@@ -398,10 +398,8 @@ static int ir_probe(struct i2c_client *c
 		 * internally
 		 */
 		rc = rc_allocate_device();
-		if (!rc) {
-			err = -ENOMEM;
-			goto err_out_free;
-		}
+		if (!rc)
+			return -ENOMEM;
 	}
 	ir->rc = rc;
 
@@ -454,7 +452,6 @@ static int ir_probe(struct i2c_client *c
  err_out_free:
 	/* Only frees rc if it were allocated internally */
 	rc_free_device(rc);
-	kfree(ir);
 	return err;
 }
 
@@ -470,7 +467,6 @@ static int ir_remove(struct i2c_client *
 		rc_unregister_device(ir->rc);
 
 	/* free memory */
-	kfree(ir);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/i2c/Kconfig
--- linux-libre-3.10-gnu/drivers/media/i2c/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -245,6 +245,15 @@ config VIDEO_KS0127
 	  To compile this driver as a module, choose M here: the
 	  module will be called ks0127.
 
+config VIDEO_ML86V7667
+	tristate "OKI ML86V7667 video decoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the OKI Semiconductor ML86V7667 video decoder.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ml86v7667.
+
 config VIDEO_SAA7110
 	tristate "Philips SAA7110 video decoder"
 	depends on VIDEO_V4L2 && I2C
@@ -425,6 +434,15 @@ config VIDEO_AK881X
 	help
 	  Video output driver for AKM AK8813 and AK8814 TV encoders
 
+config VIDEO_THS8200
+	tristate "Texas Instruments THS8200 video encoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the Texas Instruments THS8200 video encoder.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ths8200.
+
 comment "Camera sensor devices"
 
 config VIDEO_APTINA_PLL
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ks0127.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/ks0127.c
--- linux-libre-3.10-gnu/drivers/media/i2c/ks0127.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ks0127.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,7 +42,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include "ks0127.h"
 
 MODULE_DESCRIPTION("KS0127 video decoder driver");
@@ -200,7 +199,6 @@ struct adjust {
 struct ks0127 {
 	struct v4l2_subdev sd;
 	v4l2_std_id	norm;
-	int		ident;
 	u8 		regs[256];
 };
 
@@ -371,12 +369,9 @@ static void ks0127_and_or(struct v4l2_su
 ****************************************************************************/
 static void ks0127_init(struct v4l2_subdev *sd)
 {
-	struct ks0127 *ks = to_ks0127(sd);
 	u8 *table = reg_defaults;
 	int i;
 
-	ks->ident = V4L2_IDENT_KS0127;
-
 	v4l2_dbg(1, debug, sd, "reset\n");
 	msleep(1);
 
@@ -397,7 +392,6 @@ static void ks0127_init(struct v4l2_subd
 
 
 	if ((ks0127_read(sd, KS_STAT) & 0x80) == 0) {
-		ks->ident = V4L2_IDENT_KS0122S;
 		v4l2_dbg(1, debug, sd, "ks0122s found\n");
 		return;
 	}
@@ -408,7 +402,6 @@ static void ks0127_init(struct v4l2_subd
 		break;
 
 	case 9:
-		ks->ident = V4L2_IDENT_KS0127B;
 		v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n");
 		break;
 
@@ -616,17 +609,24 @@ static int ks0127_status(struct v4l2_sub
 {
 	int stat = V4L2_IN_ST_NO_SIGNAL;
 	u8 status;
-	v4l2_std_id std = V4L2_STD_ALL;
+	v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
 
 	status = ks0127_read(sd, KS_STAT);
 	if (!(status & 0x20))		 /* NOVID not set */
 		stat = 0;
-	if (!(status & 0x01))		      /* CLOCK set */
+	if (!(status & 0x01)) {		      /* CLOCK set */
 		stat |= V4L2_IN_ST_NO_COLOR;
-	if ((status & 0x08))		   /* PALDET set */
-		std = V4L2_STD_PAL;
+		std = V4L2_STD_UNKNOWN;
+	} else {
+		if ((status & 0x08))		   /* PALDET set */
+			std &= V4L2_STD_PAL;
+		else
+			std &= V4L2_STD_NTSC;
+	}
+	if ((status & 0x10))		   /* PALDET set */
+		std &= V4L2_STD_525_60;
 	else
-		std = V4L2_STD_NTSC;
+		std &= V4L2_STD_625_50;
 	if (pstd)
 		*pstd = std;
 	if (pstatus)
@@ -646,18 +646,9 @@ static int ks0127_g_input_status(struct
 	return ks0127_status(sd, status, NULL);
 }
 
-static int ks0127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ks0127 *ks = to_ks0127(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, ks->ident, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops ks0127_core_ops = {
-	.g_chip_ident = ks0127_g_chip_ident,
 	.s_std = ks0127_s_std,
 };
 
@@ -685,7 +676,7 @@ static int ks0127_probe(struct i2c_clien
 		client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
 		client->addr << 1, client->adapter->name);
 
-	ks = kzalloc(sizeof(*ks), GFP_KERNEL);
+	ks = devm_kzalloc(&client->dev, sizeof(*ks), GFP_KERNEL);
 	if (ks == NULL)
 		return -ENOMEM;
 	sd = &ks->sd;
@@ -708,7 +699,6 @@ static int ks0127_remove(struct i2c_clie
 	v4l2_device_unregister_subdev(sd);
 	ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */
 	ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */
-	kfree(to_ks0127(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/m52790.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/m52790.c
--- linux-libre-3.10-gnu/drivers/media/i2c/m52790.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/m52790.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/videodev2.h>
 #include <media/m52790.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch");
 MODULE_AUTHOR("Hans Verkuil");
@@ -83,12 +82,7 @@ static int m52790_s_routing(struct v4l2_
 static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
 	struct m52790_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	if (reg->reg != 0)
 		return -EINVAL;
 	reg->size = 1;
@@ -99,12 +93,7 @@ static int m52790_g_register(struct v4l2
 static int m52790_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
 	struct m52790_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	if (reg->reg != 0)
 		return -EINVAL;
 	state->input = reg->val & 0x0303;
@@ -114,13 +103,6 @@ static int m52790_s_register(struct v4l2
 }
 #endif
 
-static int m52790_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_M52790, 0);
-}
-
 static int m52790_log_status(struct v4l2_subdev *sd)
 {
 	struct m52790_state *state = to_state(sd);
@@ -136,7 +118,6 @@ static int m52790_log_status(struct v4l2
 
 static const struct v4l2_subdev_core_ops m52790_core_ops = {
 	.log_status = m52790_log_status,
-	.g_chip_ident = m52790_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = m52790_g_register,
 	.s_register = m52790_s_register,
@@ -174,7 +155,7 @@ static int m52790_probe(struct i2c_clien
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct m52790_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 
@@ -191,7 +172,6 @@ static int m52790_remove(struct i2c_clie
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/m5mols/m5mols_core.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/m5mols/m5mols_core.c
--- linux-libre-3.10-gnu/drivers/media/i2c/m5mols/m5mols_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/m5mols/m5mols_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -930,6 +930,7 @@ static int m5mols_probe(struct i2c_clien
 			const struct i2c_device_id *id)
 {
 	const struct m5mols_platform_data *pdata = client->dev.platform_data;
+	unsigned long gpio_flags;
 	struct m5mols_info *info;
 	struct v4l2_subdev *sd;
 	int ret;
@@ -949,24 +950,27 @@ static int m5mols_probe(struct i2c_clien
 		return -EINVAL;
 	}
 
-	info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
+	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
 	info->pdata = pdata;
 	info->set_power	= pdata->set_power;
 
-	ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
+	gpio_flags = pdata->reset_polarity
+		   ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+	ret = devm_gpio_request_one(&client->dev, pdata->gpio_reset, gpio_flags,
+				    "M5MOLS_NRST");
 	if (ret) {
 		dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
-		goto out_free;
+		return ret;
 	}
-	gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity);
 
-	ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
+	ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies),
+				      supplies);
 	if (ret) {
 		dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
-		goto out_gpio;
+		return ret;
 	}
 
 	sd = &info->sd;
@@ -978,17 +982,17 @@ static int m5mols_probe(struct i2c_clien
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
 	if (ret < 0)
-		goto out_reg;
+		return ret;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
 
 	init_waitqueue_head(&info->irq_waitq);
 	mutex_init(&info->lock);
 
-	ret = request_irq(client->irq, m5mols_irq_handler,
-			  IRQF_TRIGGER_RISING, MODULE_NAME, sd);
+	ret = devm_request_irq(&client->dev, client->irq, m5mols_irq_handler,
+			       IRQF_TRIGGER_RISING, MODULE_NAME, sd);
 	if (ret) {
 		dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
-		goto out_me;
+		goto error;
 	}
 	info->res_type = M5MOLS_RESTYPE_MONITOR;
 	info->ffmt[0] = m5mols_default_ffmt[0];
@@ -996,7 +1000,7 @@ static int m5mols_probe(struct i2c_clien
 
 	ret = m5mols_sensor_power(info, true);
 	if (ret)
-		goto out_irq;
+		goto error;
 
 	ret = m5mols_fw_start(sd);
 	if (!ret)
@@ -1005,32 +1009,19 @@ static int m5mols_probe(struct i2c_clien
 	ret = m5mols_sensor_power(info, false);
 	if (!ret)
 		return 0;
-out_irq:
-	free_irq(client->irq, sd);
-out_me:
+error:
 	media_entity_cleanup(&sd->entity);
-out_reg:
-	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
-out_gpio:
-	gpio_free(pdata->gpio_reset);
-out_free:
-	kfree(info);
 	return ret;
 }
 
 static int m5mols_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct m5mols_info *info = to_m5mols(sd);
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	free_irq(client->irq, sd);
-
-	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
-	gpio_free(info->pdata->gpio_reset);
 	media_entity_cleanup(&sd->entity);
-	kfree(info);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/Makefile linux-libre-3.11-rc7-gnu/drivers/media/i2c/Makefile
--- linux-libre-3.10-gnu/drivers/media/i2c/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -34,6 +34,7 @@ obj-$(CONFIG_VIDEO_BT856) += bt856.o
 obj-$(CONFIG_VIDEO_BT866) += bt866.o
 obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
 obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
+obj-$(CONFIG_VIDEO_THS8200) += ths8200.o
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
 obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
 obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
@@ -70,3 +71,4 @@ obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 obj-$(CONFIG_VIDEO_SMIAPP_PLL)	+= smiapp-pll.o
 obj-$(CONFIG_VIDEO_AK881X)		+= ak881x.o
 obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
+obj-$(CONFIG_VIDEO_ML86V7667)	+= ml86v7667.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ml86v7667.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/ml86v7667.c
--- linux-libre-3.10-gnu/drivers/media/i2c/ml86v7667.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ml86v7667.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,431 @@
+/*
+ * OKI Semiconductor ML86V7667 video decoder driver
+ *
+ * Author: Vladimir Barinov <source@cogentembedded.com>
+ * Copyright (C) 2013 Cogent Embedded, Inc.
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+
+#define DRV_NAME "ml86v7667"
+
+/* Subaddresses */
+#define MRA_REG			0x00 /* Mode Register A */
+#define MRC_REG			0x02 /* Mode Register C */
+#define LUMC_REG		0x0C /* Luminance Control */
+#define CLC_REG			0x10 /* Contrast level control */
+#define SSEPL_REG		0x11 /* Sync separation level */
+#define CHRCA_REG		0x12 /* Chrominance Control A */
+#define ACCC_REG		0x14 /* ACC Loop filter & Chrominance control */
+#define ACCRC_REG		0x15 /* ACC Reference level control */
+#define HUE_REG			0x16 /* Hue control */
+#define ADC2_REG		0x1F /* ADC Register 2 */
+#define PLLR1_REG		0x20 /* PLL Register 1 */
+#define STATUS_REG		0x2C /* STATUS Register */
+
+/* Mode Register A register bits */
+#define MRA_OUTPUT_MODE_MASK	(3 << 6)
+#define MRA_ITUR_BT601		(1 << 6)
+#define MRA_ITUR_BT656		(0 << 6)
+#define MRA_INPUT_MODE_MASK	(7 << 3)
+#define MRA_PAL_BT601		(4 << 3)
+#define MRA_NTSC_BT601		(0 << 3)
+#define MRA_REGISTER_MODE	(1 << 0)
+
+/* Mode Register C register bits */
+#define MRC_AUTOSELECT		(1 << 7)
+
+/* Luminance Control register bits */
+#define LUMC_ONOFF_SHIFT	7
+#define LUMC_ONOFF_MASK		(1 << 7)
+
+/* Contrast level control register bits */
+#define CLC_CONTRAST_ONOFF	(1 << 7)
+#define CLC_CONTRAST_MASK	0x0F
+
+/* Sync separation level register bits */
+#define SSEPL_LUMINANCE_ONOFF	(1 << 7)
+#define SSEPL_LUMINANCE_MASK	0x7F
+
+/* Chrominance Control A register bits */
+#define CHRCA_MODE_SHIFT	6
+#define CHRCA_MODE_MASK		(1 << 6)
+
+/* ACC Loop filter & Chrominance control register bits */
+#define ACCC_CHROMA_CR_SHIFT	3
+#define ACCC_CHROMA_CR_MASK	(7 << 3)
+#define ACCC_CHROMA_CB_SHIFT	0
+#define ACCC_CHROMA_CB_MASK	(7 << 0)
+
+/* ACC Reference level control register bits */
+#define ACCRC_CHROMA_MASK	0xfc
+#define ACCRC_CHROMA_SHIFT	2
+
+/* ADC Register 2 register bits */
+#define ADC2_CLAMP_VOLTAGE_MASK	(7 << 1)
+#define ADC2_CLAMP_VOLTAGE(n)	((n & 7) << 1)
+
+/* PLL Register 1 register bits */
+#define PLLR1_FIXED_CLOCK	(1 << 7)
+
+/* STATUS Register register bits */
+#define STATUS_HLOCK_DETECT	(1 << 3)
+#define STATUS_NTSCPAL		(1 << 2)
+
+struct ml86v7667_priv {
+	struct v4l2_subdev		sd;
+	struct v4l2_ctrl_handler	hdl;
+	v4l2_std_id			std;
+};
+
+static inline struct ml86v7667_priv *to_ml86v7667(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct ml86v7667_priv, sd);
+}
+
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+	return &container_of(ctrl->handler, struct ml86v7667_priv, hdl)->sd;
+}
+
+static int ml86v7667_mask_set(struct i2c_client *client, const u8 reg,
+			      const u8 mask, const u8 data)
+{
+	int val = i2c_smbus_read_byte_data(client, reg);
+	if (val < 0)
+		return val;
+
+	val = (val & ~mask) | (data & mask);
+	return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+static int ml86v7667_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct v4l2_subdev *sd = to_sd(ctrl);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret = -EINVAL;
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ret = ml86v7667_mask_set(client, SSEPL_REG,
+					 SSEPL_LUMINANCE_MASK, ctrl->val);
+		break;
+	case V4L2_CID_CONTRAST:
+		ret = ml86v7667_mask_set(client, CLC_REG,
+					 CLC_CONTRAST_MASK, ctrl->val);
+		break;
+	case V4L2_CID_CHROMA_GAIN:
+		ret = ml86v7667_mask_set(client, ACCRC_REG, ACCRC_CHROMA_MASK,
+					 ctrl->val << ACCRC_CHROMA_SHIFT);
+		break;
+	case V4L2_CID_HUE:
+		ret = ml86v7667_mask_set(client, HUE_REG, ~0, ctrl->val);
+		break;
+	case V4L2_CID_RED_BALANCE:
+		ret = ml86v7667_mask_set(client, ACCC_REG,
+					 ACCC_CHROMA_CR_MASK,
+					 ctrl->val << ACCC_CHROMA_CR_SHIFT);
+		break;
+	case V4L2_CID_BLUE_BALANCE:
+		ret = ml86v7667_mask_set(client, ACCC_REG,
+					 ACCC_CHROMA_CB_MASK,
+					 ctrl->val << ACCC_CHROMA_CB_SHIFT);
+		break;
+	case V4L2_CID_SHARPNESS:
+		ret = ml86v7667_mask_set(client, LUMC_REG,
+					 LUMC_ONOFF_MASK,
+					 ctrl->val << LUMC_ONOFF_SHIFT);
+		break;
+	case V4L2_CID_COLOR_KILLER:
+		ret = ml86v7667_mask_set(client, CHRCA_REG,
+					 CHRCA_MODE_MASK,
+					 ctrl->val << CHRCA_MODE_SHIFT);
+		break;
+	}
+
+	return ret;
+}
+
+static int ml86v7667_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int status;
+
+	status = i2c_smbus_read_byte_data(client, STATUS_REG);
+	if (status < 0)
+		return status;
+
+	if (status & STATUS_HLOCK_DETECT)
+		*std &= status & STATUS_NTSCPAL ? V4L2_STD_625_50 : V4L2_STD_525_60;
+	else
+		*std = V4L2_STD_UNKNOWN;
+
+	return 0;
+}
+
+static int ml86v7667_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int status_reg;
+
+	status_reg = i2c_smbus_read_byte_data(client, STATUS_REG);
+	if (status_reg < 0)
+		return status_reg;
+
+	*status = status_reg & STATUS_HLOCK_DETECT ? 0 : V4L2_IN_ST_NO_SIGNAL;
+
+	return 0;
+}
+
+static int ml86v7667_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+				   enum v4l2_mbus_pixelcode *code)
+{
+	if (index > 0)
+		return -EINVAL;
+
+	*code = V4L2_MBUS_FMT_YUYV8_2X8;
+
+	return 0;
+}
+
+static int ml86v7667_mbus_fmt(struct v4l2_subdev *sd,
+			      struct v4l2_mbus_framefmt *fmt)
+{
+	struct ml86v7667_priv *priv = to_ml86v7667(sd);
+
+	fmt->code = V4L2_MBUS_FMT_YUYV8_2X8;
+	fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	fmt->field = V4L2_FIELD_INTERLACED;
+	fmt->width = 720;
+	fmt->height = priv->std & V4L2_STD_525_60 ? 480 : 576;
+
+	return 0;
+}
+
+static int ml86v7667_g_mbus_config(struct v4l2_subdev *sd,
+				   struct v4l2_mbus_config *cfg)
+{
+	cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
+		     V4L2_MBUS_DATA_ACTIVE_HIGH;
+	cfg->type = V4L2_MBUS_BT656;
+
+	return 0;
+}
+
+static int ml86v7667_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct ml86v7667_priv *priv = to_ml86v7667(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+	int ret;
+	u8 mode;
+
+	/* PAL/NTSC ITU-R BT.601 input mode */
+	mode = std & V4L2_STD_525_60 ? MRA_NTSC_BT601 : MRA_PAL_BT601;
+	ret = ml86v7667_mask_set(client, MRA_REG, MRA_INPUT_MODE_MASK, mode);
+	if (ret < 0)
+		return ret;
+
+	priv->std = std;
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ml86v7667_g_register(struct v4l2_subdev *sd,
+				struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(client, (u8)reg->reg);
+	if (ret < 0)
+		return ret;
+
+	reg->val = ret;
+	reg->size = sizeof(u8);
+
+	return 0;
+}
+
+static int ml86v7667_s_register(struct v4l2_subdev *sd,
+				const struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return i2c_smbus_write_byte_data(client, (u8)reg->reg, (u8)reg->val);
+}
+#endif
+
+static const struct v4l2_ctrl_ops ml86v7667_ctrl_ops = {
+	.s_ctrl = ml86v7667_s_ctrl,
+};
+
+static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
+	.querystd = ml86v7667_querystd,
+	.g_input_status = ml86v7667_g_input_status,
+	.enum_mbus_fmt = ml86v7667_enum_mbus_fmt,
+	.try_mbus_fmt = ml86v7667_mbus_fmt,
+	.g_mbus_fmt = ml86v7667_mbus_fmt,
+	.s_mbus_fmt = ml86v7667_mbus_fmt,
+	.g_mbus_config = ml86v7667_g_mbus_config,
+};
+
+static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = {
+	.s_std = ml86v7667_s_std,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = ml86v7667_g_register,
+	.s_register = ml86v7667_s_register,
+#endif
+};
+
+static struct v4l2_subdev_ops ml86v7667_subdev_ops = {
+	.core = &ml86v7667_subdev_core_ops,
+	.video = &ml86v7667_subdev_video_ops,
+};
+
+static int ml86v7667_init(struct ml86v7667_priv *priv)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+	int val;
+	int ret;
+
+	/* BT.656-4 output mode, register mode */
+	ret = ml86v7667_mask_set(client, MRA_REG,
+				 MRA_OUTPUT_MODE_MASK | MRA_REGISTER_MODE,
+				 MRA_ITUR_BT656 | MRA_REGISTER_MODE);
+
+	/* PLL circuit fixed clock, 32MHz */
+	ret |= ml86v7667_mask_set(client, PLLR1_REG, PLLR1_FIXED_CLOCK,
+				  PLLR1_FIXED_CLOCK);
+
+	/* ADC2 clamping voltage maximum  */
+	ret |= ml86v7667_mask_set(client, ADC2_REG, ADC2_CLAMP_VOLTAGE_MASK,
+				  ADC2_CLAMP_VOLTAGE(7));
+
+	/* enable luminance function */
+	ret |= ml86v7667_mask_set(client, SSEPL_REG, SSEPL_LUMINANCE_ONOFF,
+				  SSEPL_LUMINANCE_ONOFF);
+
+	/* enable contrast function */
+	ret |= ml86v7667_mask_set(client, CLC_REG, CLC_CONTRAST_ONOFF, 0);
+
+	/*
+	 * PAL/NTSC autodetection is enabled after reset,
+	 * set the autodetected std in manual std mode and
+	 * disable autodetection
+	 */
+	val = i2c_smbus_read_byte_data(client, STATUS_REG);
+	if (val < 0)
+		return val;
+
+	priv->std = val & STATUS_NTSCPAL ? V4L2_STD_625_50 : V4L2_STD_525_60;
+	ret |= ml86v7667_mask_set(client, MRC_REG, MRC_AUTOSELECT, 0);
+
+	val = priv->std & V4L2_STD_525_60 ? MRA_NTSC_BT601 : MRA_PAL_BT601;
+	ret |= ml86v7667_mask_set(client, MRA_REG, MRA_INPUT_MODE_MASK, val);
+
+	return ret;
+}
+
+static int ml86v7667_probe(struct i2c_client *client,
+			   const struct i2c_device_id *did)
+{
+	struct ml86v7667_priv *priv;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	v4l2_i2c_subdev_init(&priv->sd, client, &ml86v7667_subdev_ops);
+
+	v4l2_ctrl_handler_init(&priv->hdl, 8);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_BRIGHTNESS, -64, 63, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_CONTRAST, -8, 7, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_CHROMA_GAIN, -32, 31, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_HUE, -128, 127, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_RED_BALANCE, -4, 3, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_BLUE_BALANCE, -4, 3, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_SHARPNESS, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_COLOR_KILLER, 0, 1, 1, 0);
+	priv->sd.ctrl_handler = &priv->hdl;
+
+	ret = priv->hdl.error;
+	if (ret)
+		goto cleanup;
+
+	v4l2_ctrl_handler_setup(&priv->hdl);
+
+	ret = ml86v7667_init(priv);
+	if (ret)
+		goto cleanup;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+		 client->addr, client->adapter->name);
+	return 0;
+
+cleanup:
+	v4l2_ctrl_handler_free(&priv->hdl);
+	v4l2_device_unregister_subdev(&priv->sd);
+	v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
+		client->addr, client->adapter->name);
+	return ret;
+}
+
+static int ml86v7667_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ml86v7667_priv *priv = to_ml86v7667(sd);
+
+	v4l2_ctrl_handler_free(&priv->hdl);
+	v4l2_device_unregister_subdev(&priv->sd);
+
+	return 0;
+}
+
+static const struct i2c_device_id ml86v7667_id[] = {
+	{DRV_NAME, 0},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, ml86v7667_id);
+
+static struct i2c_driver ml86v7667_i2c_driver = {
+	.driver = {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ml86v7667_probe,
+	.remove		= ml86v7667_remove,
+	.id_table	= ml86v7667_id,
+};
+
+module_i2c_driver(ml86v7667_i2c_driver);
+
+MODULE_DESCRIPTION("OKI Semiconductor ML86V7667 video decoder driver");
+MODULE_AUTHOR("Vladimir Barinov");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/msp3400-driver.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/msp3400-driver.c
--- linux-libre-3.10-gnu/drivers/media/i2c/msp3400-driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/msp3400-driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -570,15 +570,6 @@ static int msp_s_i2s_clock_freq(struct v
 	return 0;
 }
 
-static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct msp_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->ident,
-			(state->rev1 << 16) | state->rev2);
-}
-
 static int msp_log_status(struct v4l2_subdev *sd)
 {
 	struct msp_state *state = to_state(sd);
@@ -651,7 +642,6 @@ static const struct v4l2_ctrl_ops msp_ct
 
 static const struct v4l2_subdev_core_ops msp_core_ops = {
 	.log_status = msp_log_status,
-	.g_chip_ident = msp_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -707,7 +697,7 @@ static int msp_probe(struct i2c_client *
 		return -ENODEV;
 	}
 
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return -ENOMEM;
 
@@ -732,7 +722,6 @@ static int msp_probe(struct i2c_client *
 	if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) {
 		v4l_dbg(1, msp_debug, client,
 				"not an msp3400 (cannot read chip version)\n");
-		kfree(state);
 		return -ENODEV;
 	}
 
@@ -827,7 +816,6 @@ static int msp_probe(struct i2c_client *
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(state);
 		return err;
 	}
 
@@ -889,7 +877,6 @@ static int msp_remove(struct i2c_client
 	msp_reset(client);
 
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/mt9m032.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9m032.c
--- linux-libre-3.10-gnu/drivers/media/i2c/mt9m032.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9m032.c	2013-08-25 20:43:22.000000000 -0400
@@ -554,10 +554,8 @@ static int mt9m032_g_register(struct v4l
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
 	int val;
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
 
 	val = mt9m032_read(client, reg->reg);
 	if (val < 0)
@@ -575,12 +573,9 @@ static int mt9m032_s_register(struct v4l
 	struct mt9m032 *sensor = to_mt9m032(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	return mt9m032_write(client, reg->reg, reg->val);
 }
 #endif
@@ -730,7 +725,7 @@ static int mt9m032_probe(struct i2c_clie
 	if (!client->dev.platform_data)
 		return -ENODEV;
 
-	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
+	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
 	if (sensor == NULL)
 		return -ENOMEM;
 
@@ -860,7 +855,6 @@ error_ctrl:
 	v4l2_ctrl_handler_free(&sensor->ctrls);
 error_sensor:
 	mutex_destroy(&sensor->lock);
-	kfree(sensor);
 	return ret;
 }
 
@@ -873,7 +867,6 @@ static int mt9m032_remove(struct i2c_cli
 	v4l2_ctrl_handler_free(&sensor->ctrls);
 	media_entity_cleanup(&subdev->entity);
 	mutex_destroy(&sensor->lock);
-	kfree(sensor);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/mt9p031.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9p031.c
--- linux-libre-3.10-gnu/drivers/media/i2c/mt9p031.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9p031.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,18 +16,19 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/gpio.h>
-#include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
 #include <linux/pm.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 
 #include <media/mt9p031.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-of.h>
 #include <media/v4l2-subdev.h>
 
 #include "aptina-pll.h"
@@ -124,9 +125,7 @@ struct mt9p031 {
 	int power_count;
 
 	struct clk *clk;
-	struct regulator *vaa;
-	struct regulator *vdd;
-	struct regulator *vdd_io;
+	struct regulator_bulk_data regulators[3];
 
 	enum mt9p031_model model;
 	struct aptina_pll pll;
@@ -271,23 +270,26 @@ static inline int mt9p031_pll_disable(st
 
 static int mt9p031_power_on(struct mt9p031 *mt9p031)
 {
+	int ret;
+
 	/* Ensure RESET_BAR is low */
-	if (mt9p031->reset != -1) {
+	if (gpio_is_valid(mt9p031->reset)) {
 		gpio_set_value(mt9p031->reset, 0);
 		usleep_range(1000, 2000);
 	}
 
 	/* Bring up the supplies */
-	regulator_enable(mt9p031->vdd);
-	regulator_enable(mt9p031->vdd_io);
-	regulator_enable(mt9p031->vaa);
+	ret = regulator_bulk_enable(ARRAY_SIZE(mt9p031->regulators),
+				   mt9p031->regulators);
+	if (ret < 0)
+		return ret;
 
 	/* Emable clock */
 	if (mt9p031->clk)
 		clk_prepare_enable(mt9p031->clk);
 
 	/* Now RESET_BAR must be high */
-	if (mt9p031->reset != -1) {
+	if (gpio_is_valid(mt9p031->reset)) {
 		gpio_set_value(mt9p031->reset, 1);
 		usleep_range(1000, 2000);
 	}
@@ -297,14 +299,13 @@ static int mt9p031_power_on(struct mt9p0
 
 static void mt9p031_power_off(struct mt9p031 *mt9p031)
 {
-	if (mt9p031->reset != -1) {
+	if (gpio_is_valid(mt9p031->reset)) {
 		gpio_set_value(mt9p031->reset, 0);
 		usleep_range(1000, 2000);
 	}
 
-	regulator_disable(mt9p031->vaa);
-	regulator_disable(mt9p031->vdd_io);
-	regulator_disable(mt9p031->vdd);
+	regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
+			       mt9p031->regulators);
 
 	if (mt9p031->clk)
 		clk_disable_unprepare(mt9p031->clk);
@@ -849,18 +850,18 @@ static int mt9p031_registered(struct v4l
 
 	/* Read out the chip version register */
 	data = mt9p031_read(client, MT9P031_CHIP_VERSION);
+	mt9p031_power_off(mt9p031);
+
 	if (data != MT9P031_CHIP_VERSION_VALUE) {
 		dev_err(&client->dev, "MT9P031 not detected, wrong version "
 			"0x%04x\n", data);
 		return -ENODEV;
 	}
 
-	mt9p031_power_off(mt9p031);
-
 	dev_info(&client->dev, "MT9P031 detected at address 0x%02x\n",
 		 client->addr);
 
-	return ret;
+	return 0;
 }
 
 static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
@@ -928,10 +929,36 @@ static const struct v4l2_subdev_internal
  * Driver initialization and probing
  */
 
+static struct mt9p031_platform_data *
+mt9p031_get_pdata(struct i2c_client *client)
+{
+	struct mt9p031_platform_data *pdata;
+	struct device_node *np;
+
+	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
+		return client->dev.platform_data;
+
+	np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	if (!np)
+		return NULL;
+
+	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		goto done;
+
+	pdata->reset = of_get_named_gpio(client->dev.of_node, "reset-gpios", 0);
+	of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq);
+	of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq);
+
+done:
+	of_node_put(np);
+	return pdata;
+}
+
 static int mt9p031_probe(struct i2c_client *client,
 			 const struct i2c_device_id *did)
 {
-	struct mt9p031_platform_data *pdata = client->dev.platform_data;
+	struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client);
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 	struct mt9p031 *mt9p031;
 	unsigned int i;
@@ -958,14 +985,14 @@ static int mt9p031_probe(struct i2c_clie
 	mt9p031->model = did->driver_data;
 	mt9p031->reset = -1;
 
-	mt9p031->vaa = devm_regulator_get(&client->dev, "vaa");
-	mt9p031->vdd = devm_regulator_get(&client->dev, "vdd");
-	mt9p031->vdd_io = devm_regulator_get(&client->dev, "vdd_io");
+	mt9p031->regulators[0].supply = "vdd";
+	mt9p031->regulators[1].supply = "vdd_io";
+	mt9p031->regulators[2].supply = "vaa";
 
-	if (IS_ERR(mt9p031->vaa) || IS_ERR(mt9p031->vdd) ||
-	    IS_ERR(mt9p031->vdd_io)) {
+	ret = devm_regulator_bulk_get(&client->dev, 3, mt9p031->regulators);
+	if (ret < 0) {
 		dev_err(&client->dev, "Unable to get regulators\n");
-		return -ENODEV;
+		return ret;
 	}
 
 	v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6);
@@ -1031,7 +1058,7 @@ static int mt9p031_probe(struct i2c_clie
 	mt9p031->format.field = V4L2_FIELD_NONE;
 	mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
 
-	if (pdata->reset != -1) {
+	if (gpio_is_valid(pdata->reset)) {
 		ret = devm_gpio_request_one(&client->dev, pdata->reset,
 					    GPIOF_OUT_INIT_LOW, "mt9p031_rst");
 		if (ret < 0)
@@ -1070,8 +1097,18 @@ static const struct i2c_device_id mt9p03
 };
 MODULE_DEVICE_TABLE(i2c, mt9p031_id);
 
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id mt9p031_of_match[] = {
+	{ .compatible = "aptina,mt9p031", },
+	{ .compatible = "aptina,mt9p031m", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt9p031_of_match);
+#endif
+
 static struct i2c_driver mt9p031_i2c_driver = {
 	.driver = {
+		.of_match_table = of_match_ptr(mt9p031_of_match),
 		.name = "mt9p031",
 	},
 	.probe          = mt9p031_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/mt9t001.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9t001.c
--- linux-libre-3.10-gnu/drivers/media/i2c/mt9t001.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9t001.c	2013-08-25 20:43:22.000000000 -0400
@@ -740,7 +740,7 @@ static int mt9t001_probe(struct i2c_clie
 	if (ret < 0)
 		return ret;
 
-	mt9t001 = kzalloc(sizeof(*mt9t001), GFP_KERNEL);
+	mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL);
 	if (!mt9t001)
 		return -ENOMEM;
 
@@ -801,7 +801,6 @@ done:
 	if (ret < 0) {
 		v4l2_ctrl_handler_free(&mt9t001->ctrls);
 		media_entity_cleanup(&mt9t001->subdev.entity);
-		kfree(mt9t001);
 	}
 
 	return ret;
@@ -815,7 +814,6 @@ static int mt9t001_remove(struct i2c_cli
 	v4l2_ctrl_handler_free(&mt9t001->ctrls);
 	v4l2_device_unregister_subdev(subdev);
 	media_entity_cleanup(&subdev->entity);
-	kfree(mt9t001);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/mt9v011.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9v011.c
--- linux-libre-3.10-gnu/drivers/media/i2c/mt9v011.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9v011.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <asm/div64.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/mt9v011.h>
 
@@ -407,13 +406,6 @@ static int mt9v011_s_mbus_fmt(struct v4l
 static int mt9v011_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	reg->val = mt9v011_read(sd, reg->reg & 0xff);
 	reg->size = 2;
 
@@ -423,31 +415,12 @@ static int mt9v011_g_register(struct v4l
 static int mt9v011_s_register(struct v4l2_subdev *sd,
 			      const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	mt9v011_write(sd, reg->reg & 0xff, reg->val & 0xffff);
 
 	return 0;
 }
 #endif
 
-static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	u16 version;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011,
-					  version);
-}
-
 static int mt9v011_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct mt9v011 *core =
@@ -489,7 +462,6 @@ static struct v4l2_ctrl_ops mt9v011_ctrl
 
 static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
 	.reset = mt9v011_reset,
-	.g_chip_ident = mt9v011_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = mt9v011_g_register,
 	.s_register = mt9v011_s_register,
@@ -526,7 +498,7 @@ static int mt9v011_probe(struct i2c_clie
 	     I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
 		return -EIO;
 
-	core = kzalloc(sizeof(struct mt9v011), GFP_KERNEL);
+	core = devm_kzalloc(&c->dev, sizeof(struct mt9v011), GFP_KERNEL);
 	if (!core)
 		return -ENOMEM;
 
@@ -539,7 +511,6 @@ static int mt9v011_probe(struct i2c_clie
 	    (version != MT9V011_REV_B_VERSION)) {
 		v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n",
 			  version);
-		kfree(core);
 		return -EINVAL;
 	}
 
@@ -562,7 +533,6 @@ static int mt9v011_probe(struct i2c_clie
 
 		v4l2_err(sd, "control initialization error %d\n", ret);
 		v4l2_ctrl_handler_free(&core->ctrls);
-		kfree(core);
 		return ret;
 	}
 	core->sd.ctrl_handler = &core->ctrls;
@@ -598,7 +568,7 @@ static int mt9v011_remove(struct i2c_cli
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&core->ctrls);
-	kfree(to_mt9v011(sd));
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/mt9v032.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9v032.c
--- linux-libre-3.10-gnu/drivers/media/i2c/mt9v032.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/mt9v032.c	2013-08-25 20:43:22.000000000 -0400
@@ -744,7 +744,7 @@ static int mt9v032_probe(struct i2c_clie
 		return -EIO;
 	}
 
-	mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL);
+	mt9v032 = devm_kzalloc(&client->dev, sizeof(*mt9v032), GFP_KERNEL);
 	if (!mt9v032)
 		return -ENOMEM;
 
@@ -830,8 +830,9 @@ static int mt9v032_probe(struct i2c_clie
 
 	mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
+
 	if (ret < 0)
-		kfree(mt9v032);
+		v4l2_ctrl_handler_free(&mt9v032->ctrls);
 
 	return ret;
 }
@@ -841,9 +842,10 @@ static int mt9v032_remove(struct i2c_cli
 	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
 	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
 
+	v4l2_ctrl_handler_free(&mt9v032->ctrls);
 	v4l2_device_unregister_subdev(subdev);
 	media_entity_cleanup(&subdev->entity);
-	kfree(mt9v032);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/noon010pc30.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/noon010pc30.c
--- linux-libre-3.10-gnu/drivers/media/i2c/noon010pc30.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/noon010pc30.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/slab.h>
 #include <linux/regulator/consumer.h>
 #include <media/noon010pc30.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/videodev2.h>
 #include <linux/module.h>
 #include <media/v4l2-ctrls.h>
@@ -712,7 +711,7 @@ static int noon010_probe(struct i2c_clie
 		return -EIO;
 	}
 
-	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -746,57 +745,50 @@ static int noon010_probe(struct i2c_clie
 	info->curr_win		= &noon010_sizes[0];
 
 	if (gpio_is_valid(pdata->gpio_nreset)) {
-		ret = gpio_request(pdata->gpio_nreset, "NOON010PC30 NRST");
+		ret = devm_gpio_request_one(&client->dev, pdata->gpio_nreset,
+					    GPIOF_OUT_INIT_LOW,
+					    "NOON010PC30 NRST");
 		if (ret) {
 			dev_err(&client->dev, "GPIO request error: %d\n", ret);
 			goto np_err;
 		}
 		info->gpio_nreset = pdata->gpio_nreset;
-		gpio_direction_output(info->gpio_nreset, 0);
 		gpio_export(info->gpio_nreset, 0);
 	}
 
 	if (gpio_is_valid(pdata->gpio_nstby)) {
-		ret = gpio_request(pdata->gpio_nstby, "NOON010PC30 NSTBY");
+		ret = devm_gpio_request_one(&client->dev, pdata->gpio_nstby,
+					    GPIOF_OUT_INIT_LOW,
+					    "NOON010PC30 NSTBY");
 		if (ret) {
 			dev_err(&client->dev, "GPIO request error: %d\n", ret);
-			goto np_gpio_err;
+			goto np_err;
 		}
 		info->gpio_nstby = pdata->gpio_nstby;
-		gpio_direction_output(info->gpio_nstby, 0);
 		gpio_export(info->gpio_nstby, 0);
 	}
 
 	for (i = 0; i < NOON010_NUM_SUPPLIES; i++)
 		info->supply[i].supply = noon010_supply_name[i];
 
-	ret = regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
+	ret = devm_regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
 				 info->supply);
 	if (ret)
-		goto np_reg_err;
+		goto np_err;
 
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
 	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
 	if (ret < 0)
-		goto np_me_err;
+		goto np_err;
 
 	ret = noon010_detect(client, info);
 	if (!ret)
 		return 0;
 
-np_me_err:
-	regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
-np_reg_err:
-	if (gpio_is_valid(info->gpio_nstby))
-		gpio_free(info->gpio_nstby);
-np_gpio_err:
-	if (gpio_is_valid(info->gpio_nreset))
-		gpio_free(info->gpio_nreset);
 np_err:
 	v4l2_ctrl_handler_free(&info->hdl);
 	v4l2_device_unregister_subdev(sd);
-	kfree(info);
 	return ret;
 }
 
@@ -807,17 +799,8 @@ static int noon010_remove(struct i2c_cli
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&info->hdl);
-
-	regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
-
-	if (gpio_is_valid(info->gpio_nreset))
-		gpio_free(info->gpio_nreset);
-
-	if (gpio_is_valid(info->gpio_nstby))
-		gpio_free(info->gpio_nstby);
-
 	media_entity_cleanup(&sd->entity);
-	kfree(info);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ov7640.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/ov7640.c
--- linux-libre-3.10-gnu/drivers/media/i2c/ov7640.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ov7640.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/slab.h>
 
 MODULE_DESCRIPTION("OmniVision ov7640 sensor driver");
@@ -59,7 +58,7 @@ static int ov7640_probe(struct i2c_clien
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 	v4l2_i2c_subdev_init(sd, client, &ov7640_ops);
@@ -71,7 +70,6 @@ static int ov7640_probe(struct i2c_clien
 
 	if (write_regs(client, initial_registers) < 0) {
 		v4l_err(client, "error initializing OV7640\n");
-		kfree(sd);
 		return -ENODEV;
 	}
 
@@ -84,7 +82,7 @@ static int ov7640_remove(struct i2c_clie
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ov7670.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/ov7670.c
--- linux-libre-3.10-gnu/drivers/media/i2c/ov7670.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ov7670.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-mediabus.h>
 #include <media/ov7670.h>
@@ -1462,25 +1461,12 @@ static const struct v4l2_ctrl_ops ov7670
 	.g_volatile_ctrl = ov7670_g_volatile_ctrl,
 };
 
-static int ov7670_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	unsigned char val = 0;
 	int ret;
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	ret = ov7670_read(sd, reg->reg & 0xff, &val);
 	reg->val = val;
 	reg->size = 1;
@@ -1489,12 +1475,6 @@ static int ov7670_g_register(struct v4l2
 
 static int ov7670_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	ov7670_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
@@ -1503,7 +1483,6 @@ static int ov7670_s_register(struct v4l2
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops ov7670_core_ops = {
-	.g_chip_ident = ov7670_g_chip_ident,
 	.reset = ov7670_reset,
 	.init = ov7670_init,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1552,7 +1531,7 @@ static int ov7670_probe(struct i2c_clien
 	struct ov7670_info *info;
 	int ret;
 
-	info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL);
+	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 	if (info == NULL)
 		return -ENOMEM;
 	sd = &info->sd;
@@ -1590,7 +1569,6 @@ static int ov7670_probe(struct i2c_clien
 		v4l_dbg(1, debug, client,
 			"chip found @ 0x%x (%s) is not an ov7670 chip.\n",
 			client->addr << 1, client->adapter->name);
-		kfree(info);
 		return ret;
 	}
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
@@ -1635,7 +1613,6 @@ static int ov7670_probe(struct i2c_clien
 		int err = info->hdl.error;
 
 		v4l2_ctrl_handler_free(&info->hdl);
-		kfree(info);
 		return err;
 	}
 	/*
@@ -1659,7 +1636,6 @@ static int ov7670_remove(struct i2c_clie
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&info->hdl);
-	kfree(info);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/s5c73m3/s5c73m3-core.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/s5c73m3/s5c73m3-core.c
--- linux-libre-3.10-gnu/drivers/media/i2c/s5c73m3/s5c73m3-core.c	2013-07-01 10:35:39.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/s5c73m3/s5c73m3-core.c	2013-08-31 17:55:10.000000000 -0400
@@ -1385,9 +1385,12 @@ static int __s5c73m3_power_off(struct s5
 	}
 	return 0;
 err:
-	for (++i; i < S5C73M3_MAX_SUPPLIES; i++)
-		regulator_enable(state->supplies[i].consumer);
-
+	for (++i; i < S5C73M3_MAX_SUPPLIES; i++) {
+		int r = regulator_enable(state->supplies[i].consumer);
+		if (r < 0)
+			v4l2_err(&state->oif_sd, "Failed to reenable %s: %d\n",
+				 state->supplies[i].supply, r);
+	}
 	return ret;
 }
 
@@ -1511,59 +1514,40 @@ static const struct v4l2_subdev_ops oif_
 	.video	= &s5c73m3_oif_video_ops,
 };
 
-static int s5c73m3_configure_gpio(int nr, int val, const char *name)
-{
-	unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-	int ret;
-
-	if (!gpio_is_valid(nr))
-		return 0;
-	ret = gpio_request_one(nr, flags, name);
-	if (!ret)
-		gpio_export(nr, 0);
-	return ret;
-}
-
-static int s5c73m3_free_gpios(struct s5c73m3 *state)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(state->gpio); i++) {
-		if (!gpio_is_valid(state->gpio[i].gpio))
-			continue;
-		gpio_free(state->gpio[i].gpio);
-		state->gpio[i].gpio = -EINVAL;
-	}
-	return 0;
-}
-
 static int s5c73m3_configure_gpios(struct s5c73m3 *state,
 				   const struct s5c73m3_platform_data *pdata)
 {
-	const struct s5c73m3_gpio *gpio = &pdata->gpio_stby;
+	struct device *dev = &state->i2c_client->dev;
+	const struct s5c73m3_gpio *gpio;
+	unsigned long flags;
 	int ret;
 
 	state->gpio[STBY].gpio = -EINVAL;
 	state->gpio[RST].gpio  = -EINVAL;
 
-	ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_STBY");
-	if (ret) {
-		s5c73m3_free_gpios(state);
-		return ret;
+	gpio = &pdata->gpio_stby;
+	if (gpio_is_valid(gpio->gpio)) {
+		flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+		      | GPIOF_EXPORT;
+		ret = devm_gpio_request_one(dev, gpio->gpio, flags,
+					    "S5C73M3_STBY");
+		if (ret < 0)
+			return ret;
+
+		state->gpio[STBY] = *gpio;
 	}
-	state->gpio[STBY] = *gpio;
-	if (gpio_is_valid(gpio->gpio))
-		gpio_set_value(gpio->gpio, 0);
 
 	gpio = &pdata->gpio_reset;
-	ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_RST");
-	if (ret) {
-		s5c73m3_free_gpios(state);
-		return ret;
+	if (gpio_is_valid(gpio->gpio)) {
+		flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+		      | GPIOF_EXPORT;
+		ret = devm_gpio_request_one(dev, gpio->gpio, flags,
+					    "S5C73M3_RST");
+		if (ret < 0)
+			return ret;
+
+		state->gpio[RST] = *gpio;
 	}
-	state->gpio[RST] = *gpio;
-	if (gpio_is_valid(gpio->gpio))
-		gpio_set_value(gpio->gpio, 0);
 
 	return 0;
 }
@@ -1626,10 +1610,11 @@ static int s5c73m3_probe(struct i2c_clie
 
 	state->mclk_frequency = pdata->mclk_frequency;
 	state->bus_type = pdata->bus_type;
+	state->i2c_client = client;
 
 	ret = s5c73m3_configure_gpios(state, pdata);
 	if (ret)
-		goto out_err1;
+		goto out_err;
 
 	for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++)
 		state->supplies[i].supply = s5c73m3_supply_names[i];
@@ -1638,12 +1623,12 @@ static int s5c73m3_probe(struct i2c_clie
 			       state->supplies);
 	if (ret) {
 		dev_err(dev, "failed to get regulators\n");
-		goto out_err2;
+		goto out_err;
 	}
 
 	ret = s5c73m3_init_controls(state);
 	if (ret)
-		goto out_err2;
+		goto out_err;
 
 	state->sensor_pix_size[RES_ISP] = &s5c73m3_isp_resolutions[1];
 	state->sensor_pix_size[RES_JPEG] = &s5c73m3_jpeg_resolutions[1];
@@ -1659,16 +1644,12 @@ static int s5c73m3_probe(struct i2c_clie
 
 	ret = s5c73m3_register_spi_driver(state);
 	if (ret < 0)
-		goto out_err2;
-
-	state->i2c_client = client;
+		goto out_err;
 
 	v4l2_info(sd, "%s: completed succesfully\n", __func__);
 	return 0;
 
-out_err2:
-	s5c73m3_free_gpios(state);
-out_err1:
+out_err:
 	media_entity_cleanup(&sd->entity);
 	return ret;
 }
@@ -1688,7 +1669,6 @@ static int s5c73m3_remove(struct i2c_cli
 	media_entity_cleanup(&sensor_sd->entity);
 
 	s5c73m3_unregister_spi_driver(state);
-	s5c73m3_free_gpios(state);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/s5c73m3/s5c73m3-spi.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
--- linux-libre-3.10-gnu/drivers/media/i2c/s5c73m3/s5c73m3-spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/s5c73m3/s5c73m3-spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -73,7 +73,7 @@ int s5c73m3_spi_write(struct s5c73m3 *st
 
 	memset(padding, 0, sizeof(padding));
 
-	for (i = 0; i < count ; i++) {
+	for (i = 0; i < count; i++) {
 		r = spi_xmit(spi_dev, (void *)addr + j, tx_size, SPI_DIR_TX);
 		if (r < 0)
 			return r;
@@ -98,7 +98,7 @@ int s5c73m3_spi_read(struct s5c73m3 *sta
 	unsigned int i, j = 0;
 	int r = 0;
 
-	for (i = 0; i < count ; i++) {
+	for (i = 0; i < count; i++) {
 		r = spi_xmit(spi_dev, addr + j, tx_size, SPI_DIR_RX);
 		if (r < 0)
 			return r;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/s5k6aa.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/s5k6aa.c
--- linux-libre-3.10-gnu/drivers/media/i2c/s5k6aa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/s5k6aa.c	2013-08-25 20:43:22.000000000 -0400
@@ -1491,58 +1491,41 @@ static const struct v4l2_subdev_ops s5k6
 /*
  * GPIO setup
  */
-static int s5k6aa_configure_gpio(int nr, int val, const char *name)
-{
-	unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-	int ret;
-
-	if (!gpio_is_valid(nr))
-		return 0;
-	ret = gpio_request_one(nr, flags, name);
-	if (!ret)
-		gpio_export(nr, 0);
-	return ret;
-}
-
-static void s5k6aa_free_gpios(struct s5k6aa *s5k6aa)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(s5k6aa->gpio); i++) {
-		if (!gpio_is_valid(s5k6aa->gpio[i].gpio))
-			continue;
-		gpio_free(s5k6aa->gpio[i].gpio);
-		s5k6aa->gpio[i].gpio = -EINVAL;
-	}
-}
 
 static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
 				  const struct s5k6aa_platform_data *pdata)
 {
-	const struct s5k6aa_gpio *gpio = &pdata->gpio_stby;
+	struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+	const struct s5k6aa_gpio *gpio;
+	unsigned long flags;
 	int ret;
 
 	s5k6aa->gpio[STBY].gpio = -EINVAL;
 	s5k6aa->gpio[RST].gpio  = -EINVAL;
 
-	ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_STBY");
-	if (ret) {
-		s5k6aa_free_gpios(s5k6aa);
-		return ret;
+	gpio = &pdata->gpio_stby;
+	if (gpio_is_valid(gpio->gpio)) {
+		flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+		      | GPIOF_EXPORT;
+		ret = devm_gpio_request_one(&client->dev, gpio->gpio, flags,
+					    "S5K6AA_STBY");
+		if (ret < 0)
+			return ret;
+
+		s5k6aa->gpio[STBY] = *gpio;
 	}
-	s5k6aa->gpio[STBY] = *gpio;
-	if (gpio_is_valid(gpio->gpio))
-		gpio_set_value(gpio->gpio, 0);
 
 	gpio = &pdata->gpio_reset;
-	ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_RST");
-	if (ret) {
-		s5k6aa_free_gpios(s5k6aa);
-		return ret;
+	if (gpio_is_valid(gpio->gpio)) {
+		flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+		      | GPIOF_EXPORT;
+		ret = devm_gpio_request_one(&client->dev, gpio->gpio, flags,
+					    "S5K6AA_RST");
+		if (ret < 0)
+			return ret;
+
+		s5k6aa->gpio[RST] = *gpio;
 	}
-	s5k6aa->gpio[RST] = *gpio;
-	if (gpio_is_valid(gpio->gpio))
-		gpio_set_value(gpio->gpio, 0);
 
 	return 0;
 }
@@ -1593,7 +1576,7 @@ static int s5k6aa_probe(struct i2c_clien
 
 	ret = s5k6aa_configure_gpios(s5k6aa, pdata);
 	if (ret)
-		goto out_err2;
+		goto out_err;
 
 	for (i = 0; i < S5K6AA_NUM_SUPPLIES; i++)
 		s5k6aa->supplies[i].supply = s5k6aa_supply_names[i];
@@ -1602,12 +1585,12 @@ static int s5k6aa_probe(struct i2c_clien
 				 s5k6aa->supplies);
 	if (ret) {
 		dev_err(&client->dev, "Failed to get regulators\n");
-		goto out_err3;
+		goto out_err;
 	}
 
 	ret = s5k6aa_initialize_ctrls(s5k6aa);
 	if (ret)
-		goto out_err3;
+		goto out_err;
 
 	s5k6aa_presets_data_init(s5k6aa);
 
@@ -1618,9 +1601,7 @@ static int s5k6aa_probe(struct i2c_clien
 
 	return 0;
 
-out_err3:
-	s5k6aa_free_gpios(s5k6aa);
-out_err2:
+out_err:
 	media_entity_cleanup(&s5k6aa->sd.entity);
 	return ret;
 }
@@ -1628,12 +1609,10 @@ out_err2:
 static int s5k6aa_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct s5k6aa *s5k6aa = to_s5k6aa(sd);
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
 	media_entity_cleanup(&sd->entity);
-	s5k6aa_free_gpios(s5k6aa);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/saa6588.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa6588.c
--- linux-libre-3.10-gnu/drivers/media/i2c/saa6588.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa6588.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,6 @@
 
 #include <media/saa6588.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 
 /* insmod options */
@@ -443,17 +442,9 @@ static int saa6588_s_tuner(struct v4l2_s
 	return 0;
 }
 
-static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops saa6588_core_ops = {
-	.g_chip_ident = saa6588_g_chip_ident,
 	.ioctl = saa6588_ioctl,
 };
 
@@ -478,17 +469,15 @@ static int saa6588_probe(struct i2c_clie
 	v4l_info(client, "saa6588 found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	s = kzalloc(sizeof(*s), GFP_KERNEL);
+	s = devm_kzalloc(&client->dev, sizeof(*s), GFP_KERNEL);
 	if (s == NULL)
 		return -ENOMEM;
 
 	s->buf_size = bufblocks * 3;
 
-	s->buffer = kmalloc(s->buf_size, GFP_KERNEL);
-	if (s->buffer == NULL) {
-		kfree(s);
+	s->buffer = devm_kzalloc(&client->dev, s->buf_size, GFP_KERNEL);
+	if (s->buffer == NULL)
 		return -ENOMEM;
-	}
 	sd = &s->sd;
 	v4l2_i2c_subdev_init(sd, client, &saa6588_ops);
 	spin_lock_init(&s->lock);
@@ -516,8 +505,6 @@ static int saa6588_remove(struct i2c_cli
 
 	cancel_delayed_work_sync(&s->work);
 
-	kfree(s->buffer);
-	kfree(s);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/saa7110.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7110.c
--- linux-libre-3.10-gnu/drivers/media/i2c/saa7110.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7110.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,7 +35,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
@@ -203,7 +202,7 @@ static v4l2_std_id determine_norm(struct
 	status = saa7110_read(sd);
 	if (status & 0x40) {
 		v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status);
-		return decoder->norm;	/* no change*/
+		return V4L2_STD_UNKNOWN;
 	}
 	if ((status & 3) == 0) {
 		saa7110_write(sd, 0x06, 0x83);
@@ -265,7 +264,7 @@ static int saa7110_g_input_status(struct
 
 static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
 {
-	*(v4l2_std_id *)std = determine_norm(sd);
+	*std &= determine_norm(sd);
 	return 0;
 }
 
@@ -352,13 +351,6 @@ static int saa7110_s_ctrl(struct v4l2_ct
 	return 0;
 }
 
-static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7110, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
@@ -366,7 +358,6 @@ static const struct v4l2_ctrl_ops saa711
 };
 
 static const struct v4l2_subdev_core_ops saa7110_core_ops = {
-	.g_chip_ident = saa7110_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -406,7 +397,7 @@ static int saa7110_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (!decoder)
 		return -ENOMEM;
 	sd = &decoder->sd;
@@ -428,7 +419,6 @@ static int saa7110_probe(struct i2c_clie
 		int err = decoder->hdl.error;
 
 		v4l2_ctrl_handler_free(&decoder->hdl);
-		kfree(decoder);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&decoder->hdl);
@@ -469,7 +459,6 @@ static int saa7110_remove(struct i2c_cli
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&decoder->hdl);
-	kfree(decoder);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/saa7115.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7115.c
--- linux-libre-3.10-gnu/drivers/media/i2c/saa7115.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7115.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,7 +46,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/saa7115.h>
 #include <asm/div64.h>
 
@@ -63,6 +62,16 @@ module_param(debug, bool, 0644);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 
+enum saa711x_model {
+	SAA7111A,
+	SAA7111,
+	SAA7113,
+	GM7113C,
+	SAA7114,
+	SAA7115,
+	SAA7118,
+};
+
 struct saa711x_state {
 	struct v4l2_subdev sd;
 	struct v4l2_ctrl_handler hdl;
@@ -80,7 +89,7 @@ struct saa711x_state {
 	int radio;
 	int width;
 	int height;
-	u32 ident;
+	enum saa711x_model ident;
 	u32 audclk_freq;
 	u32 crystal_freq;
 	bool ucgc;
@@ -111,10 +120,10 @@ static inline int saa711x_write(struct v
 /* Sanity routine to check if a register is present */
 static int saa711x_has_reg(const int id, const u8 reg)
 {
-	if (id == V4L2_IDENT_SAA7111)
+	if (id == SAA7111)
 		return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
 		       (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
-	if (id == V4L2_IDENT_SAA7111A)
+	if (id == SAA7111A)
 		return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
 		       reg != 0x14 && reg != 0x18 && reg != 0x19 &&
 		       reg != 0x1d && reg != 0x1e;
@@ -127,16 +136,18 @@ static int saa711x_has_reg(const int id,
 		return 0;
 
 	switch (id) {
-	case V4L2_IDENT_SAA7113:
+	case GM7113C:
+		return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && reg < 0x20;
+	case SAA7113:
 		return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
 		       reg != 0x5d && reg < 0x63;
-	case V4L2_IDENT_SAA7114:
+	case SAA7114:
 		return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
 		       (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
 		       reg != 0x81 && reg < 0xf0;
-	case V4L2_IDENT_SAA7115:
+	case SAA7115:
 		return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
-	case V4L2_IDENT_SAA7118:
+	case SAA7118:
 		return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
 		       (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
 		       (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
@@ -214,7 +225,10 @@ static const unsigned char saa7111_init[
 	0x00, 0x00
 };
 
-/* SAA7113 init codes */
+/* SAA7113/GM7113C init codes
+ * It's important that R_14... R_17 == 0x00
+ * for the gm7113c chip to deliver stable video
+ */
 static const unsigned char saa7113_init[] = {
 	R_01_INC_DELAY, 0x08,
 	R_02_INPUT_CNTL_1, 0xc2,
@@ -448,6 +462,24 @@ static const unsigned char saa7115_cfg_5
 
 /* ============== SAA7715 VIDEO templates (end) =======  */
 
+/* ============== GM7113C VIDEO templates =============  */
+static const unsigned char gm7113c_cfg_60hz_video[] = {
+	R_08_SYNC_CNTL, 0x68,			/* 0xBO: auto detection, 0x68 = NTSC */
+	R_0E_CHROMA_CNTL_1, 0x07,		/* video autodetection is on */
+
+	0x00, 0x00
+};
+
+static const unsigned char gm7113c_cfg_50hz_video[] = {
+	R_08_SYNC_CNTL, 0x28,			/* 0x28 = PAL */
+	R_0E_CHROMA_CNTL_1, 0x07,
+
+	0x00, 0x00
+};
+
+/* ============== GM7113C VIDEO templates (end) =======  */
+
+
 static const unsigned char saa7115_cfg_vbi_on[] = {
 	R_80_GLOBAL_CNTL_1, 0x00,			/* reset tasks */
 	R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,		/* reset scaler */
@@ -932,11 +964,17 @@ static void saa711x_set_v4lstd(struct v4
 	// This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
 	if (std & V4L2_STD_525_60) {
 		v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
-		saa711x_writeregs(sd, saa7115_cfg_60hz_video);
+		if (state->ident == GM7113C)
+			saa711x_writeregs(sd, gm7113c_cfg_60hz_video);
+		else
+			saa711x_writeregs(sd, saa7115_cfg_60hz_video);
 		saa711x_set_size(sd, 720, 480);
 	} else {
 		v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
-		saa711x_writeregs(sd, saa7115_cfg_50hz_video);
+		if (state->ident == GM7113C)
+			saa711x_writeregs(sd, gm7113c_cfg_50hz_video);
+		else
+			saa711x_writeregs(sd, saa7115_cfg_50hz_video);
 		saa711x_set_size(sd, 720, 576);
 	}
 
@@ -949,7 +987,8 @@ static void saa711x_set_v4lstd(struct v4
 	011 NTSC N (3.58MHz)            PAL M (3.58MHz)
 	100 reserved                    NTSC-Japan (3.58MHz)
 	*/
-	if (state->ident <= V4L2_IDENT_SAA7113) {
+	if (state->ident <= SAA7113 ||
+	    state->ident == GM7113C) {
 		u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
 
 		if (std == V4L2_STD_PAL_M) {
@@ -968,9 +1007,8 @@ static void saa711x_set_v4lstd(struct v4
 		/* restart task B if needed */
 		int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
 
-		if (taskb && state->ident == V4L2_IDENT_SAA7114) {
+		if (taskb && state->ident == SAA7114)
 			saa711x_writeregs(sd, saa7115_cfg_vbi_on);
-		}
 
 		/* switch audio mode too! */
 		saa711x_s_clock_freq(sd, state->audclk_freq);
@@ -992,7 +1030,7 @@ static void saa711x_set_lcr(struct v4l2_
 
 #else
 	/* SAA7113 and SAA7118 also should support VBI - Need testing */
-	if (state->ident != V4L2_IDENT_SAA7115)
+	if (state->ident != SAA7115)
 		return;
 #endif
 
@@ -1214,13 +1252,14 @@ static int saa711x_s_routing(struct v4l2
 			     u32 input, u32 output, u32 config)
 {
 	struct saa711x_state *state = to_state(sd);
-	u8 mask = (state->ident <= V4L2_IDENT_SAA7111A) ? 0xf8 : 0xf0;
+	u8 mask = (state->ident <= SAA7111A) ? 0xf8 : 0xf0;
 
 	v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
 		input, output);
 
 	/* saa7111/3 does not have these inputs */
-	if (state->ident <= V4L2_IDENT_SAA7113 &&
+	if ((state->ident <= SAA7113 ||
+	     state->ident == GM7113C) &&
 	    (input == SAA7115_COMPOSITE4 ||
 	     input == SAA7115_COMPOSITE5)) {
 		return -EINVAL;
@@ -1235,7 +1274,7 @@ static int saa711x_s_routing(struct v4l2
 	state->input = input;
 
 	/* saa7111 has slightly different input numbering */
-	if (state->ident <= V4L2_IDENT_SAA7111A) {
+	if (state->ident <= SAA7111A) {
 		if (input >= SAA7115_COMPOSITE4)
 			input -= 2;
 		/* saa7111 specific */
@@ -1258,13 +1297,13 @@ static int saa711x_s_routing(struct v4l2
 			(state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
 
 	state->output = output;
-	if (state->ident == V4L2_IDENT_SAA7114 ||
-			state->ident == V4L2_IDENT_SAA7115) {
+	if (state->ident == SAA7114 ||
+			state->ident == SAA7115) {
 		saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
 				(saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
 				(state->output & 0x01));
 	}
-	if (state->ident > V4L2_IDENT_SAA7111A) {
+	if (state->ident > SAA7111A) {
 		if (config & SAA7115_IDQ_IS_DEFAULT)
 			saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x20);
 		else
@@ -1277,7 +1316,7 @@ static int saa711x_s_gpio(struct v4l2_su
 {
 	struct saa711x_state *state = to_state(sd);
 
-	if (state->ident > V4L2_IDENT_SAA7111A)
+	if (state->ident > SAA7111A)
 		return -EINVAL;
 	saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
 		(val ? 0x80 : 0));
@@ -1367,7 +1406,7 @@ static int saa711x_querystd(struct v4l2_
 
 	reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
 
-	if (state->ident == V4L2_IDENT_SAA7115) {
+	if (state->ident == SAA7115) {
 		reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
 
 		v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
@@ -1389,6 +1428,7 @@ static int saa711x_querystd(struct v4l2_
 			*std &= V4L2_STD_SECAM;
 			break;
 		default:
+			*std = V4L2_STD_UNKNOWN;
 			/* Can't detect anything */
 			break;
 		}
@@ -1397,8 +1437,10 @@ static int saa711x_querystd(struct v4l2_
 	v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f);
 
 	/* horizontal/vertical not locked */
-	if (reg1f & 0x40)
+	if (reg1f & 0x40) {
+		*std = V4L2_STD_UNKNOWN;
 		goto ret;
+	}
 
 	if (reg1f & 0x20)
 		*std &= V4L2_STD_525_60;
@@ -1418,7 +1460,7 @@ static int saa711x_g_input_status(struct
 	int reg1f;
 
 	*status = V4L2_IN_ST_NO_SIGNAL;
-	if (state->ident == V4L2_IDENT_SAA7115)
+	if (state->ident == SAA7115)
 		reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
 	reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
 	if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
@@ -1429,12 +1471,6 @@ static int saa711x_g_input_status(struct
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = saa711x_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -1442,25 +1478,11 @@ static int saa711x_g_register(struct v4l
 
 static int saa711x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa711x_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
-}
-
 static int saa711x_log_status(struct v4l2_subdev *sd)
 {
 	struct saa711x_state *state = to_state(sd);
@@ -1469,7 +1491,7 @@ static int saa711x_log_status(struct v4l
 	int vcr;
 
 	v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
-	if (state->ident != V4L2_IDENT_SAA7115) {
+	if (state->ident != SAA7115) {
 		/* status for the saa7114 */
 		reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
 		signalOk = (reg1f & 0xc1) == 0x81;
@@ -1520,7 +1542,6 @@ static const struct v4l2_ctrl_ops saa711
 
 static const struct v4l2_subdev_core_ops saa711x_core_ops = {
 	.log_status = saa711x_log_status,
-	.g_chip_ident = saa711x_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -1571,55 +1592,145 @@ static const struct v4l2_subdev_ops saa7
 	.vbi = &saa711x_vbi_ops,
 };
 
+#define CHIP_VER_SIZE	16
+
 /* ----------------------------------------------------------------------- */
 
-static int saa711x_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
+/**
+ * saa711x_detect_chip - Detects the saa711x (or clone) variant
+ * @client:		I2C client structure.
+ * @id:			I2C device ID structure.
+ * @name:		Name of the device to be filled.
+ *
+ * Detects the Philips/NXP saa711x chip, or some clone of it.
+ * if 'id' is NULL or id->driver_data is equal to 1, it auto-probes
+ * the analog demod.
+ * If the tuner is not found, it returns -ENODEV.
+ * If auto-detection is disabled and the tuner doesn't match what it was
+ *	requred, it returns -EINVAL and fills 'name'.
+ * If the chip is found, it returns the chip ID and fills 'name'.
+ */
+static int saa711x_detect_chip(struct i2c_client *client,
+			       const struct i2c_device_id *id,
+			       char *name)
 {
-	struct saa711x_state *state;
-	struct v4l2_subdev *sd;
-	struct v4l2_ctrl_handler *hdl;
-	int i;
-	char name[17];
+	char chip_ver[CHIP_VER_SIZE];
 	char chip_id;
-	int autodetect = !id || id->driver_data == 1;
+	int i;
+	int autodetect;
 
-	/* Check if the adapter supports the needed features */
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -EIO;
+	autodetect = !id || id->driver_data == 1;
 
-	for (i = 0; i < 0x0f; i++) {
+	/* Read the chip version register */
+	for (i = 0; i < CHIP_VER_SIZE; i++) {
 		i2c_smbus_write_byte_data(client, 0, i);
-		name[i] = (i2c_smbus_read_byte_data(client, 0) & 0x0f) + '0';
+		chip_ver[i] = i2c_smbus_read_byte_data(client, 0);
+		name[i] = (chip_ver[i] & 0x0f) + '0';
 		if (name[i] > '9')
 			name[i] += 'a' - '9' - 1;
 	}
 	name[i] = '\0';
 
-	chip_id = name[5];
+	/* Check if it is a Philips/NXP chip */
+	if (!memcmp(name + 1, "f711", 4)) {
+		chip_id = name[5];
+		snprintf(name, CHIP_VER_SIZE, "saa711%c", chip_id);
 
-	/* Check whether this chip is part of the saa711x series */
-	if (memcmp(name + 1, "f711", 4)) {
-		v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
-			client->addr << 1, name);
-		return -ENODEV;
+		if (!autodetect && strcmp(name, id->name))
+			return -EINVAL;
+
+		switch (chip_id) {
+		case '1':
+			if (chip_ver[0] & 0xf0) {
+				snprintf(name, CHIP_VER_SIZE, "saa711%ca", chip_id);
+				v4l_info(client, "saa7111a variant found\n");
+				return SAA7111A;
+			}
+			return SAA7111;
+		case '3':
+			return SAA7113;
+		case '4':
+			return SAA7114;
+		case '5':
+			return SAA7115;
+		case '8':
+			return SAA7118;
+		default:
+			v4l2_info(client,
+				  "WARNING: Philips/NXP chip unknown - Falling back to saa7111\n");
+			return SAA7111;
+		}
 	}
 
-	/* Safety check */
-	if (!autodetect && id->name[6] != chip_id) {
-		v4l_warn(client, "found saa711%c while %s was expected\n",
-			 chip_id, id->name);
+	/* Check if it is a gm7113c */
+	if (!memcmp(name, "0000", 4)) {
+		chip_id = 0;
+		for (i = 0; i < 4; i++) {
+			chip_id = chip_id << 1;
+			chip_id |= (chip_ver[i] & 0x80) ? 1 : 0;
+		}
+
+		/*
+		 * Note: From the datasheet, only versions 1 and 2
+		 * exists. However, tests on a device labeled as:
+		 * "GM7113C 1145" returned "10" on all 16 chip
+		 * version (reg 0x00) reads. So, we need to also
+		 * accept at least verion 0. For now, let's just
+		 * assume that a device that returns "0000" for
+		 * the lower nibble is a gm7113c.
+		 */
+
+		strlcpy(name, "gm7113c", CHIP_VER_SIZE);
+
+		if (!autodetect && strcmp(name, id->name))
+			return -EINVAL;
+
+		v4l_dbg(1, debug, client,
+			"It seems to be a %s chip (%*ph) @ 0x%x.\n",
+			name, 16, chip_ver, client->addr << 1);
+
+		return GM7113C;
 	}
-	snprintf(client->name, sizeof(client->name), "saa711%c", chip_id);
-	v4l_info(client, "saa711%c found (%s) @ 0x%x (%s)\n", chip_id, name,
-		 client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
+	/* Chip was not discovered. Return its ID and don't bind */
+	v4l_dbg(1, debug, client, "chip %*ph @ 0x%x is unknown.\n",
+		16, chip_ver, client->addr << 1);
+	return -ENODEV;
+}
+
+static int saa711x_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct saa711x_state *state;
+	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *hdl;
+	int ident;
+	char name[CHIP_VER_SIZE + 1];
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	ident = saa711x_detect_chip(client, id, name);
+	if (ident == -EINVAL) {
+		/* Chip exists, but doesn't match */
+		v4l_warn(client, "found %s while %s was expected\n",
+			 name, id->name);
+		return -ENODEV;
+	}
+	if (ident < 0)
+		return ident;
+
+	strlcpy(client->name, name, sizeof(client->name));
+
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
 
+	v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+		 client->addr << 1, client->adapter->name);
 	hdl = &state->hdl;
 	v4l2_ctrl_handler_init(hdl, 6);
 	/* add in ascending ID order */
@@ -1640,7 +1751,6 @@ static int saa711x_probe(struct i2c_clie
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(state);
 		return err;
 	}
 	v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
@@ -1649,31 +1759,7 @@ static int saa711x_probe(struct i2c_clie
 	state->output = SAA7115_IPORT_ON;
 	state->enable = 1;
 	state->radio = 0;
-	switch (chip_id) {
-	case '1':
-		state->ident = V4L2_IDENT_SAA7111;
-		if (saa711x_read(sd, R_00_CHIP_VERSION) & 0xf0) {
-			v4l_info(client, "saa7111a variant found\n");
-			state->ident = V4L2_IDENT_SAA7111A;
-		}
-		break;
-	case '3':
-		state->ident = V4L2_IDENT_SAA7113;
-		break;
-	case '4':
-		state->ident = V4L2_IDENT_SAA7114;
-		break;
-	case '5':
-		state->ident = V4L2_IDENT_SAA7115;
-		break;
-	case '8':
-		state->ident = V4L2_IDENT_SAA7118;
-		break;
-	default:
-		state->ident = V4L2_IDENT_SAA7111;
-		v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
-		break;
-	}
+	state->ident = ident;
 
 	state->audclk_freq = 48000;
 
@@ -1682,18 +1768,19 @@ static int saa711x_probe(struct i2c_clie
 	/* init to 60hz/48khz */
 	state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
 	switch (state->ident) {
-	case V4L2_IDENT_SAA7111:
-	case V4L2_IDENT_SAA7111A:
+	case SAA7111:
+	case SAA7111A:
 		saa711x_writeregs(sd, saa7111_init);
 		break;
-	case V4L2_IDENT_SAA7113:
+	case GM7113C:
+	case SAA7113:
 		saa711x_writeregs(sd, saa7113_init);
 		break;
 	default:
 		state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
 		saa711x_writeregs(sd, saa7115_init_auto_input);
 	}
-	if (state->ident > V4L2_IDENT_SAA7111A)
+	if (state->ident > SAA7111A)
 		saa711x_writeregs(sd, saa7115_init_misc);
 	saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
 	v4l2_ctrl_handler_setup(hdl);
@@ -1712,7 +1799,6 @@ static int saa711x_remove(struct i2c_cli
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	kfree(to_state(sd));
 	return 0;
 }
 
@@ -1723,6 +1809,7 @@ static const struct i2c_device_id saa711
 	{ "saa7114", 0 },
 	{ "saa7115", 0 },
 	{ "saa7118", 0 },
+	{ "gm7113c", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, saa711x_id);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/saa7127.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7127.c
--- linux-libre-3.10-gnu/drivers/media/i2c/saa7127.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7127.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/saa7127.h>
 
 static int debug;
@@ -251,10 +250,15 @@ static struct i2c_reg_value saa7127_init
  **********************************************************************
  */
 
+enum saa712x_model {
+	SAA7127,
+	SAA7129,
+};
+
 struct saa7127_state {
 	struct v4l2_subdev sd;
 	v4l2_std_id std;
-	u32 ident;
+	enum saa712x_model ident;
 	enum saa7127_input_type input_type;
 	enum saa7127_output_type output_type;
 	int video_enable;
@@ -482,7 +486,7 @@ static int saa7127_set_std(struct v4l2_s
 		inittab = saa7127_init_config_60hz;
 		state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
 
-	} else if (state->ident == V4L2_IDENT_SAA7129 &&
+	} else if (state->ident == SAA7129 &&
 		   (std & V4L2_STD_SECAM) &&
 		   !(std & (V4L2_STD_625_50 & ~V4L2_STD_SECAM))) {
 
@@ -517,7 +521,7 @@ static int saa7127_set_output_type(struc
 		break;
 
 	case SAA7127_OUTPUT_TYPE_COMPOSITE:
-		if (state->ident == V4L2_IDENT_SAA7129)
+		if (state->ident == SAA7129)
 			state->reg_2d = 0x20;	/* CVBS only */
 		else
 			state->reg_2d = 0x08;	/* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
@@ -525,7 +529,7 @@ static int saa7127_set_output_type(struc
 		break;
 
 	case SAA7127_OUTPUT_TYPE_SVIDEO:
-		if (state->ident == V4L2_IDENT_SAA7129)
+		if (state->ident == SAA7129)
 			state->reg_2d = 0x18;	/* Y + C */
 		else
 			state->reg_2d = 0xff;   /*11111111  croma -> R, luma -> CVBS + G + B */
@@ -543,7 +547,7 @@ static int saa7127_set_output_type(struc
 		break;
 
 	case SAA7127_OUTPUT_TYPE_BOTH:
-		if (state->ident == V4L2_IDENT_SAA7129)
+		if (state->ident == SAA7129)
 			state->reg_2d = 0x38;
 		else
 			state->reg_2d = 0xbf;
@@ -661,12 +665,6 @@ static int saa7127_s_vbi_data(struct v4l
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int saa7127_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = saa7127_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -674,25 +672,11 @@ static int saa7127_g_register(struct v4l
 
 static int saa7127_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	saa7127_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int saa7127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa7127_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
-}
-
 static int saa7127_log_status(struct v4l2_subdev *sd)
 {
 	struct saa7127_state *state = to_state(sd);
@@ -712,7 +696,6 @@ static int saa7127_log_status(struct v4l
 
 static const struct v4l2_subdev_core_ops saa7127_core_ops = {
 	.log_status = saa7127_log_status,
-	.g_chip_ident = saa7127_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = saa7127_g_register,
 	.s_register = saa7127_s_register,
@@ -752,7 +735,7 @@ static int saa7127_probe(struct i2c_clie
 	v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n",
 			client->addr << 1);
 
-	state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 
@@ -767,7 +750,6 @@ static int saa7127_probe(struct i2c_clie
 	if ((saa7127_read(sd, 0) & 0xe4) != 0 ||
 			(saa7127_read(sd, 0x29) & 0x3f) != 0x1d) {
 		v4l2_dbg(1, debug, sd, "saa7127 not found\n");
-		kfree(state);
 		return -ENODEV;
 	}
 
@@ -782,10 +764,10 @@ static int saa7127_probe(struct i2c_clie
 		if (saa7127_read(sd, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
 			saa7127_write(sd, SAA7129_REG_FADE_KEY_COL2,
 					read_result);
-			state->ident = V4L2_IDENT_SAA7129;
+			state->ident = SAA7129;
 			strlcpy(client->name, "saa7129", I2C_NAME_SIZE);
 		} else {
-			state->ident = V4L2_IDENT_SAA7127;
+			state->ident = SAA7127;
 			strlcpy(client->name, "saa7127", I2C_NAME_SIZE);
 		}
 	}
@@ -809,7 +791,7 @@ static int saa7127_probe(struct i2c_clie
 		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
 	saa7127_set_video_enable(sd, 1);
 
-	if (state->ident == V4L2_IDENT_SAA7129)
+	if (state->ident == SAA7129)
 		saa7127_write_inittab(sd, saa7129_init_config_extra);
 	return 0;
 }
@@ -823,7 +805,6 @@ static int saa7127_remove(struct i2c_cli
 	v4l2_device_unregister_subdev(sd);
 	/* Turn off TV output */
 	saa7127_set_video_enable(sd, 0);
-	kfree(to_state(sd));
 	return 0;
 }
 
@@ -831,10 +812,10 @@ static int saa7127_remove(struct i2c_cli
 
 static struct i2c_device_id saa7127_id[] = {
 	{ "saa7127_auto", 0 },	/* auto-detection */
-	{ "saa7126", V4L2_IDENT_SAA7127 },
-	{ "saa7127", V4L2_IDENT_SAA7127 },
-	{ "saa7128", V4L2_IDENT_SAA7129 },
-	{ "saa7129", V4L2_IDENT_SAA7129 },
+	{ "saa7126", SAA7127 },
+	{ "saa7127", SAA7127 },
+	{ "saa7128", SAA7129 },
+	{ "saa7129", SAA7129 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, saa7127_id);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/saa717x.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa717x.c
--- linux-libre-3.10-gnu/drivers/media/i2c/saa717x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa717x.c	2013-08-25 20:43:22.000000000 -0400
@@ -977,12 +977,6 @@ static int saa717x_s_video_routing(struc
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = saa717x_read(sd, reg->reg);
 	reg->size = 1;
 	return 0;
@@ -990,14 +984,9 @@ static int saa717x_g_register(struct v4l
 
 static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	u16 addr = reg->reg & 0xffff;
 	u8 val = reg->val & 0xff;
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	saa717x_write(sd, addr, val);
 	return 0;
 }
@@ -1262,7 +1251,7 @@ static int saa717x_probe(struct i2c_clie
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 
-	decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (decoder == NULL)
 		return -ENOMEM;
 
@@ -1276,7 +1265,6 @@ static int saa717x_probe(struct i2c_clie
 		id = saa717x_read(sd, 0x5a0);
 	if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
 		v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
-		kfree(decoder);
 		return -ENODEV;
 	}
 	if (id == 0xc2)
@@ -1316,7 +1304,6 @@ static int saa717x_probe(struct i2c_clie
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(decoder);
 		return err;
 	}
 
@@ -1353,7 +1340,6 @@ static int saa717x_remove(struct i2c_cli
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/saa7185.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7185.c
--- linux-libre-3.10-gnu/drivers/media/i2c/saa7185.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7185.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
 MODULE_AUTHOR("Dave Perks");
@@ -285,17 +284,9 @@ static int saa7185_s_routing(struct v4l2
 	return 0;
 }
 
-static int saa7185_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7185, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops saa7185_core_ops = {
-	.g_chip_ident = saa7185_g_chip_ident,
 	.init = saa7185_init,
 };
 
@@ -326,7 +317,7 @@ static int saa7185_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	encoder->norm = V4L2_STD_NTSC;
@@ -352,7 +343,6 @@ static int saa7185_remove(struct i2c_cli
 	v4l2_device_unregister_subdev(sd);
 	/* SW: output off is active */
 	saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40);
-	kfree(encoder);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/saa7191.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7191.c
--- linux-libre-3.10-gnu/drivers/media/i2c/saa7191.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/saa7191.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 #include "saa7191.h"
 
@@ -272,7 +271,7 @@ static int saa7191_querystd(struct v4l2_
 
 	dprintk("SAA7191 extended signal auto-detection...\n");
 
-	*norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
+	*norm &= V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
 	stdc &= ~SAA7191_STDC_SECS;
 	ctl3 &= ~(SAA7191_CTL3_FSEL);
 
@@ -303,7 +302,7 @@ static int saa7191_querystd(struct v4l2_
 	if (status & SAA7191_STATUS_FIDT) {
 		/* 60Hz signal -> NTSC */
 		dprintk("60Hz signal: NTSC\n");
-		*norm = V4L2_STD_NTSC;
+		*norm &= V4L2_STD_NTSC;
 		return 0;
 	}
 
@@ -325,12 +324,13 @@ static int saa7191_querystd(struct v4l2_
 	if (status & SAA7191_STATUS_FIDT) {
 		dprintk("No 50Hz signal\n");
 		saa7191_s_std(sd, old_norm);
-		return -EAGAIN;
+		*norm = V4L2_STD_UNKNOWN;
+		return 0;
 	}
 
 	if (status & SAA7191_STATUS_CODE) {
 		dprintk("PAL\n");
-		*norm = V4L2_STD_PAL;
+		*norm &= V4L2_STD_PAL;
 		return saa7191_s_std(sd, old_norm);
 	}
 
@@ -350,18 +350,19 @@ static int saa7191_querystd(struct v4l2_
 	/* not 50Hz ? */
 	if (status & SAA7191_STATUS_FIDT) {
 		dprintk("No 50Hz signal\n");
-		err = -EAGAIN;
+		*norm = V4L2_STD_UNKNOWN;
 		goto out;
 	}
 
 	if (status & SAA7191_STATUS_CODE) {
 		/* Color detected -> SECAM */
 		dprintk("SECAM\n");
-		*norm = V4L2_STD_SECAM;
+		*norm &= V4L2_STD_SECAM;
 		return saa7191_s_std(sd, old_norm);
 	}
 
 	dprintk("No color detected with SECAM - Going back to PAL.\n");
+	*norm = V4L2_STD_UNKNOWN;
 
 out:
 	return saa7191_s_std(sd, old_norm);
@@ -567,18 +568,9 @@ static int saa7191_g_input_status(struct
 }
 
 
-static int saa7191_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops saa7191_core_ops = {
-	.g_chip_ident = saa7191_g_chip_ident,
 	.g_ctrl = saa7191_g_ctrl,
 	.s_ctrl = saa7191_s_ctrl,
 	.s_std = saa7191_s_std,
@@ -605,7 +597,7 @@ static int saa7191_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (!decoder)
 		return -ENOMEM;
 
@@ -615,7 +607,6 @@ static int saa7191_probe(struct i2c_clie
 	err = saa7191_write_block(sd, sizeof(initseq), initseq);
 	if (err) {
 		printk(KERN_ERR "SAA7191 initialization failed\n");
-		kfree(decoder);
 		return err;
 	}
 
@@ -636,7 +627,6 @@ static int saa7191_remove(struct i2c_cli
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_saa7191(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/smiapp/smiapp-core.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/smiapp/smiapp-core.c
--- linux-libre-3.10-gnu/drivers/media/i2c/smiapp/smiapp-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/smiapp/smiapp-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -2383,8 +2383,9 @@ static int smiapp_registered(struct v4l2
 	}
 
 	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) {
-		if (gpio_request_one(sensor->platform_data->xshutdown, 0,
-				     "SMIA++ xshutdown") != 0) {
+		if (devm_gpio_request_one(&client->dev,
+					  sensor->platform_data->xshutdown, 0,
+					  "SMIA++ xshutdown") != 0) {
 			dev_err(&client->dev,
 				"unable to acquire reset gpio %d\n",
 				sensor->platform_data->xshutdown);
@@ -2393,10 +2394,8 @@ static int smiapp_registered(struct v4l2
 	}
 
 	rval = smiapp_power_on(sensor);
-	if (rval) {
-		rval = -ENODEV;
-		goto out_smiapp_power_on;
-	}
+	if (rval)
+		return -ENODEV;
 
 	rval = smiapp_identify_module(subdev);
 	if (rval) {
@@ -2656,11 +2655,6 @@ out_ident_release:
 
 out_power_off:
 	smiapp_power_off(sensor);
-
-out_smiapp_power_on:
-	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
-		gpio_free(sensor->platform_data->xshutdown);
-
 	return rval;
 }
 
@@ -2854,12 +2848,10 @@ static int smiapp_remove(struct i2c_clie
 		device_remove_file(&client->dev, &dev_attr_nvm);
 
 	for (i = 0; i < sensor->ssds_used; i++) {
-		media_entity_cleanup(&sensor->ssds[i].sd.entity);
 		v4l2_device_unregister_subdev(&sensor->ssds[i].sd);
+		media_entity_cleanup(&sensor->ssds[i].sd.entity);
 	}
 	smiapp_free_controls(sensor);
-	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
-		gpio_free(sensor->platform_data->xshutdown);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/imx074.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/imx074.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/imx074.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/imx074.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,8 +18,9 @@
 #include <linux/module.h>
 
 #include <media/soc_camera.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
 
 /* IMX074 registers */
 
@@ -77,6 +78,7 @@ struct imx074_datafmt {
 struct imx074 {
 	struct v4l2_subdev		subdev;
 	const struct imx074_datafmt	*fmt;
+	struct v4l2_clk			*clk;
 };
 
 static const struct imx074_datafmt imx074_colour_fmts[] = {
@@ -251,29 +253,13 @@ static int imx074_s_stream(struct v4l2_s
 	return reg_write(client, MODE_SELECT, !!enable);
 }
 
-static int imx074_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= V4L2_IDENT_IMX074;
-	id->revision	= 0;
-
-	return 0;
-}
-
 static int imx074_s_power(struct v4l2_subdev *sd, int on)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct imx074 *priv = to_imx074(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static int imx074_g_mbus_config(struct v4l2_subdev *sd,
@@ -299,7 +285,6 @@ static struct v4l2_subdev_video_ops imx0
 };
 
 static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
-	.g_chip_ident	= imx074_g_chip_ident,
 	.s_power	= imx074_s_power,
 };
 
@@ -431,6 +416,7 @@ static int imx074_probe(struct i2c_clien
 	struct imx074 *priv;
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	int ret;
 
 	if (!ssdd) {
 		dev_err(&client->dev, "IMX074: missing platform data!\n");
@@ -451,12 +437,35 @@ static int imx074_probe(struct i2c_clien
 
 	priv->fmt	= &imx074_colour_fmts[0];
 
-	return imx074_video_probe(client);
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		dev_info(&client->dev, "Error %ld getting clock\n", PTR_ERR(priv->clk));
+		return -EPROBE_DEFER;
+	}
+
+	ret = soc_camera_power_init(&client->dev, ssdd);
+	if (ret < 0)
+		goto epwrinit;
+
+	ret = imx074_video_probe(client);
+	if (ret < 0)
+		goto eprobe;
+
+	return v4l2_async_register_subdev(&priv->subdev);
+
+epwrinit:
+eprobe:
+	v4l2_clk_put(priv->clk);
+	return ret;
 }
 
 static int imx074_remove(struct i2c_client *client)
 {
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct imx074 *priv = to_imx074(client);
+
+	v4l2_async_unregister_subdev(&priv->subdev);
+	v4l2_clk_put(priv->clk);
 
 	if (ssdd->free_bus)
 		ssdd->free_bus(ssdd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9m001.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9m001.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9m001.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9m001.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,8 +16,8 @@
 
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 /*
@@ -94,10 +94,10 @@ struct mt9m001 {
 		struct v4l2_ctrl *exposure;
 	};
 	struct v4l2_rect rect;	/* Sensor window */
+	struct v4l2_clk *clk;
 	const struct mt9m001_datafmt *fmt;
 	const struct mt9m001_datafmt *fmts;
 	int num_fmts;
-	int model;	/* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
 	unsigned int total_h;
 	unsigned short y_skip_top;	/* Lines to skip at the top */
 };
@@ -320,36 +320,15 @@ static int mt9m001_try_fmt(struct v4l2_s
 	return 0;
 }
 
-static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9m001 *mt9m001 = to_mt9m001(client);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= mt9m001->model;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9m001_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	reg->size = 2;
 	reg->val = reg_read(client, reg->reg);
 
@@ -364,12 +343,9 @@ static int mt9m001_s_register(struct v4l
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -381,8 +357,9 @@ static int mt9m001_s_power(struct v4l2_s
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, mt9m001->clk, on);
 }
 
 static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -505,11 +482,9 @@ static int mt9m001_video_probe(struct so
 	switch (data) {
 	case 0x8411:
 	case 0x8421:
-		mt9m001->model = V4L2_IDENT_MT9M001C12ST;
 		mt9m001->fmts = mt9m001_colour_fmts;
 		break;
 	case 0x8431:
-		mt9m001->model = V4L2_IDENT_MT9M001C12STM;
 		mt9m001->fmts = mt9m001_monochrome_fmts;
 		break;
 	default:
@@ -580,7 +555,6 @@ static const struct v4l2_ctrl_ops mt9m00
 };
 
 static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
-	.g_chip_ident	= mt9m001_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9m001_g_register,
 	.s_register	= mt9m001_s_register,
@@ -710,9 +684,18 @@ static int mt9m001_probe(struct i2c_clie
 	mt9m001->rect.width	= MT9M001_MAX_WIDTH;
 	mt9m001->rect.height	= MT9M001_MAX_HEIGHT;
 
+	mt9m001->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(mt9m001->clk)) {
+		ret = PTR_ERR(mt9m001->clk);
+		goto eclkget;
+	}
+
 	ret = mt9m001_video_probe(ssdd, client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(mt9m001->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&mt9m001->hdl);
+	}
 
 	return ret;
 }
@@ -722,6 +705,7 @@ static int mt9m001_remove(struct i2c_cli
 	struct mt9m001 *mt9m001 = to_mt9m001(client);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 
+	v4l2_clk_put(mt9m001->clk);
 	v4l2_device_unregister_subdev(&mt9m001->subdev);
 	v4l2_ctrl_handler_free(&mt9m001->hdl);
 	mt9m001_video_remove(ssdd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9m111.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9m111.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9m111.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9m111.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,9 +17,9 @@
 #include <linux/module.h>
 
 #include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 
 /*
  * MT9M111, MT9M112 and MT9M131:
@@ -205,10 +205,9 @@ struct mt9m111 {
 	struct v4l2_subdev subdev;
 	struct v4l2_ctrl_handler hdl;
 	struct v4l2_ctrl *gain;
-	int model;	/* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code
-			 * from v4l2-chip-ident.h */
 	struct mt9m111_context *ctx;
 	struct v4l2_rect rect;	/* cropping rectangle */
+	struct v4l2_clk *clk;
 	int width;		/* output */
 	int height;		/* sizes */
 	struct mutex power_lock; /* lock to protect power_count */
@@ -600,24 +599,6 @@ static int mt9m111_s_fmt(struct v4l2_sub
 	return ret;
 }
 
-static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= mt9m111->model;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9m111_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
@@ -625,10 +606,8 @@ static int mt9m111_g_register(struct v4l
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int val;
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
+	if (reg->reg > 0x2ff)
 		return -EINVAL;
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
 
 	val = mt9m111_reg_read(client, reg->reg);
 	reg->size = 2;
@@ -645,12 +624,9 @@ static int mt9m111_s_register(struct v4l
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
+	if (reg->reg > 0x2ff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (mt9m111_reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -801,14 +777,14 @@ static int mt9m111_power_on(struct mt9m1
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 	int ret;
 
-	ret = soc_camera_power_on(&client->dev, ssdd);
+	ret = soc_camera_power_on(&client->dev, ssdd, mt9m111->clk);
 	if (ret < 0)
 		return ret;
 
 	ret = mt9m111_resume(mt9m111);
 	if (ret < 0) {
 		dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
-		soc_camera_power_off(&client->dev, ssdd);
+		soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
 	}
 
 	return ret;
@@ -820,7 +796,7 @@ static void mt9m111_power_off(struct mt9
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 
 	mt9m111_suspend(mt9m111);
-	soc_camera_power_off(&client->dev, ssdd);
+	soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
 }
 
 static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
@@ -856,7 +832,6 @@ static const struct v4l2_ctrl_ops mt9m11
 };
 
 static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
-	.g_chip_ident	= mt9m111_g_chip_ident,
 	.s_power	= mt9m111_s_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9m111_g_register,
@@ -923,12 +898,10 @@ static int mt9m111_video_probe(struct i2
 
 	switch (data) {
 	case 0x143a: /* MT9M111 or MT9M131 */
-		mt9m111->model = V4L2_IDENT_MT9M111;
 		dev_info(&client->dev,
 			"Detected a MT9M111/MT9M131 chip ID %x\n", data);
 		break;
 	case 0x148c: /* MT9M112 */
-		mt9m111->model = V4L2_IDENT_MT9M112;
 		dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
 		break;
 	default:
@@ -1002,9 +975,18 @@ static int mt9m111_probe(struct i2c_clie
 	mt9m111->lastpage	= -1;
 	mutex_init(&mt9m111->power_lock);
 
+	mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(mt9m111->clk)) {
+		ret = PTR_ERR(mt9m111->clk);
+		goto eclkget;
+	}
+
 	ret = mt9m111_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(mt9m111->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&mt9m111->hdl);
+	}
 
 	return ret;
 }
@@ -1013,6 +995,7 @@ static int mt9m111_remove(struct i2c_cli
 {
 	struct mt9m111 *mt9m111 = to_mt9m111(client);
 
+	v4l2_clk_put(mt9m111->clk);
 	v4l2_device_unregister_subdev(&mt9m111->subdev);
 	v4l2_ctrl_handler_free(&mt9m111->hdl);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9t031.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9t031.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9t031.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9t031.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,7 @@
 #include <linux/module.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-ctrls.h>
 
@@ -76,7 +76,7 @@ struct mt9t031 {
 		struct v4l2_ctrl *exposure;
 	};
 	struct v4l2_rect rect;	/* Sensor window */
-	int model;	/* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
+	struct v4l2_clk *clk;
 	u16 xskip;
 	u16 yskip;
 	unsigned int total_h;
@@ -391,36 +391,16 @@ static int mt9t031_try_fmt(struct v4l2_s
 	return 0;
 }
 
-static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9t031 *mt9t031 = to_mt9t031(client);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= mt9t031->model;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9t031_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
+	reg->size = 1;
 	reg->val = reg_read(client, reg->reg);
 
 	if (reg->val > 0xffff)
@@ -434,12 +414,9 @@ static int mt9t031_s_register(struct v4l
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -595,7 +572,7 @@ static int mt9t031_runtime_resume(struct
 	return 0;
 }
 
-static struct dev_pm_ops mt9t031_dev_pm_ops = {
+static const struct dev_pm_ops mt9t031_dev_pm_ops = {
 	.runtime_suspend	= mt9t031_runtime_suspend,
 	.runtime_resume		= mt9t031_runtime_resume,
 };
@@ -610,16 +587,17 @@ static int mt9t031_s_power(struct v4l2_s
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 	struct video_device *vdev = soc_camera_i2c_to_vdev(client);
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
 	int ret;
 
 	if (on) {
-		ret = soc_camera_power_on(&client->dev, ssdd);
+		ret = soc_camera_power_on(&client->dev, ssdd, mt9t031->clk);
 		if (ret < 0)
 			return ret;
 		vdev->dev.type = &mt9t031_dev_type;
 	} else {
 		vdev->dev.type = NULL;
-		soc_camera_power_off(&client->dev, ssdd);
+		soc_camera_power_off(&client->dev, ssdd, mt9t031->clk);
 	}
 
 	return 0;
@@ -650,7 +628,6 @@ static int mt9t031_video_probe(struct i2
 
 	switch (data) {
 	case 0x1621:
-		mt9t031->model = V4L2_IDENT_MT9T031;
 		break;
 	default:
 		dev_err(&client->dev,
@@ -685,7 +662,6 @@ static const struct v4l2_ctrl_ops mt9t03
 };
 
 static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
-	.g_chip_ident	= mt9t031_g_chip_ident,
 	.s_power	= mt9t031_s_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9t031_g_register,
@@ -812,9 +788,18 @@ static int mt9t031_probe(struct i2c_clie
 	mt9t031->xskip = 1;
 	mt9t031->yskip = 1;
 
+	mt9t031->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(mt9t031->clk)) {
+		ret = PTR_ERR(mt9t031->clk);
+		goto eclkget;
+	}
+
 	ret = mt9t031_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(mt9t031->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&mt9t031->hdl);
+	}
 
 	return ret;
 }
@@ -823,6 +808,7 @@ static int mt9t031_remove(struct i2c_cli
 {
 	struct mt9t031 *mt9t031 = to_mt9t031(client);
 
+	v4l2_clk_put(mt9t031->clk);
 	v4l2_device_unregister_subdev(&mt9t031->subdev);
 	v4l2_ctrl_handler_free(&mt9t031->hdl);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9t112.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9t112.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9t112.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9t112.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@
 
 #include <media/mt9t112.h>
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-common.h>
 
 /* you can check PLL/clock info */
@@ -90,8 +90,8 @@ struct mt9t112_priv {
 	struct mt9t112_camera_info	*info;
 	struct i2c_client		*client;
 	struct v4l2_rect		 frame;
+	struct v4l2_clk			*clk;
 	const struct mt9t112_format	*format;
-	int				 model;
 	int				 num_formats;
 	u32				 flags;
 /* for flags */
@@ -738,17 +738,6 @@ static int mt9t112_init_camera(const str
 /************************************************************************
 			v4l2_subdev_core_ops
 ************************************************************************/
-static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9t112_priv *priv = to_mt9t112(client);
-
-	id->ident    = priv->model;
-	id->revision = 0;
-
-	return 0;
-}
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9t112_g_register(struct v4l2_subdev *sd,
@@ -781,12 +770,12 @@ static int mt9t112_s_power(struct v4l2_s
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct mt9t112_priv *priv = to_mt9t112(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
-	.g_chip_ident	= mt9t112_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9t112_g_register,
 	.s_register	= mt9t112_s_register,
@@ -1061,12 +1050,10 @@ static int mt9t112_camera_probe(struct i
 	switch (chipid) {
 	case 0x2680:
 		devname = "mt9t111";
-		priv->model = V4L2_IDENT_MT9T111;
 		priv->num_formats = 1;
 		break;
 	case 0x2682:
 		devname = "mt9t112";
-		priv->model = V4L2_IDENT_MT9T112;
 		priv->num_formats = ARRAY_SIZE(mt9t112_cfmts);
 		break;
 	default:
@@ -1108,18 +1095,26 @@ static int mt9t112_probe(struct i2c_clie
 
 	v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
 	ret = mt9t112_camera_probe(client);
-	if (ret)
-		return ret;
 
 	/* Cannot fail: using the default supported pixel code */
-	mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
+	if (!ret)
+		mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
+	else
+		v4l2_clk_put(priv->clk);
 
 	return ret;
 }
 
 static int mt9t112_remove(struct i2c_client *client)
 {
+	struct mt9t112_priv *priv = to_mt9t112(client);
+
+	v4l2_clk_put(priv->clk);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9v022.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9v022.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/mt9v022.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/mt9v022.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,7 +19,7 @@
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
 #include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
 
 /*
@@ -133,6 +133,11 @@ static const struct mt9v02x_register mt9
 	.pixclk_fv_lv			= MT9V024_PIXCLK_FV_LV,
 };
 
+enum mt9v022_model {
+	MT9V022IX7ATM,
+	MT9V022IX7ATC,
+};
+
 struct mt9v022 {
 	struct v4l2_subdev subdev;
 	struct v4l2_ctrl_handler hdl;
@@ -149,11 +154,12 @@ struct mt9v022 {
 	struct v4l2_ctrl *hblank;
 	struct v4l2_ctrl *vblank;
 	struct v4l2_rect rect;	/* Sensor window */
+	struct v4l2_clk *clk;
 	const struct mt9v022_datafmt *fmt;
 	const struct mt9v022_datafmt *fmts;
 	const struct mt9v02x_register *reg;
 	int num_fmts;
-	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
+	enum mt9v022_model model;
 	u16 chip_control;
 	u16 chip_version;
 	unsigned short y_skip_top;	/* Lines to skip at the top */
@@ -406,12 +412,12 @@ static int mt9v022_s_fmt(struct v4l2_sub
 	switch (mf->code) {
 	case V4L2_MBUS_FMT_Y8_1X8:
 	case V4L2_MBUS_FMT_Y10_1X10:
-		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
+		if (mt9v022->model != MT9V022IX7ATM)
 			return -EINVAL;
 		break;
 	case V4L2_MBUS_FMT_SBGGR8_1X8:
 	case V4L2_MBUS_FMT_SBGGR10_1X10:
-		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
+		if (mt9v022->model != MT9V022IX7ATC)
 			return -EINVAL;
 		break;
 	default:
@@ -457,36 +463,15 @@ static int mt9v022_try_fmt(struct v4l2_s
 	return 0;
 }
 
-static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9v022 *mt9v022 = to_mt9v022(client);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= mt9v022->model;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9v022_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	reg->size = 2;
 	reg->val = reg_read(client, reg->reg);
 
@@ -501,12 +486,9 @@ static int mt9v022_s_register(struct v4l
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -518,8 +500,9 @@ static int mt9v022_s_power(struct v4l2_s
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, mt9v022->clk, on);
 }
 
 static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -706,11 +689,11 @@ static int mt9v022_video_probe(struct i2
 	if (sensor_type && (!strcmp("colour", sensor_type) ||
 			    !strcmp("color", sensor_type))) {
 		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
-		mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
+		mt9v022->model = MT9V022IX7ATC;
 		mt9v022->fmts = mt9v022_colour_fmts;
 	} else {
 		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
-		mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
+		mt9v022->model = MT9V022IX7ATM;
 		mt9v022->fmts = mt9v022_monochrome_fmts;
 	}
 
@@ -740,7 +723,7 @@ static int mt9v022_video_probe(struct i2
 	mt9v022->fmt = &mt9v022->fmts[0];
 
 	dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
-		 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
+		 data, mt9v022->model == MT9V022IX7ATM ?
 		 "monochrome" : "colour");
 
 	ret = mt9v022_init(client);
@@ -768,7 +751,6 @@ static const struct v4l2_ctrl_ops mt9v02
 };
 
 static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
-	.g_chip_ident	= mt9v022_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9v022_g_register,
 	.s_register	= mt9v022_s_register,
@@ -957,9 +939,18 @@ static int mt9v022_probe(struct i2c_clie
 	mt9v022->rect.width	= MT9V022_MAX_WIDTH;
 	mt9v022->rect.height	= MT9V022_MAX_HEIGHT;
 
+	mt9v022->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(mt9v022->clk)) {
+		ret = PTR_ERR(mt9v022->clk);
+		goto eclkget;
+	}
+
 	ret = mt9v022_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(mt9v022->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&mt9v022->hdl);
+	}
 
 	return ret;
 }
@@ -969,6 +960,7 @@ static int mt9v022_remove(struct i2c_cli
 	struct mt9v022 *mt9v022 = to_mt9v022(client);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 
+	v4l2_clk_put(mt9v022->clk);
 	v4l2_device_unregister_subdev(&mt9v022->subdev);
 	if (ssdd->free_bus)
 		ssdd->free_bus(ssdd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov2640.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov2640.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov2640.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov2640.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,7 @@
 #include <linux/videodev2.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-ctrls.h>
 
@@ -303,8 +303,8 @@ struct ov2640_priv {
 	struct v4l2_subdev		subdev;
 	struct v4l2_ctrl_handler	hdl;
 	enum v4l2_mbus_pixelcode	cfmt_code;
+	struct v4l2_clk			*clk;
 	const struct ov2640_win_size	*win;
-	int				model;
 };
 
 /*
@@ -723,18 +723,6 @@ static int ov2640_s_ctrl(struct v4l2_ctr
 	return -EINVAL;
 }
 
-static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ov2640_priv *priv = to_ov2640(client);
-
-	id->ident    = priv->model;
-	id->revision = 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov2640_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
@@ -772,8 +760,9 @@ static int ov2640_s_power(struct v4l2_su
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov2640_priv *priv = to_ov2640(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 /* Select the nearest higher resolution for capture */
@@ -1009,7 +998,6 @@ static int ov2640_video_probe(struct i2c
 	switch (VERSION(pid, ver)) {
 	case PID_OV2640:
 		devname     = "ov2640";
-		priv->model = V4L2_IDENT_OV2640;
 		break;
 	default:
 		dev_err(&client->dev,
@@ -1034,7 +1022,6 @@ static const struct v4l2_ctrl_ops ov2640
 };
 
 static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
-	.g_chip_ident	= ov2640_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= ov2640_g_register,
 	.s_register	= ov2640_s_register,
@@ -1113,11 +1100,20 @@ static int ov2640_probe(struct i2c_clien
 	if (priv->hdl.error)
 		return priv->hdl.error;
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
+
 	ret = ov2640_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
-	else
+	} else {
 		dev_info(&adapter->dev, "OV2640 Probed\n");
+	}
 
 	return ret;
 }
@@ -1126,6 +1122,7 @@ static int ov2640_remove(struct i2c_clie
 {
 	struct ov2640_priv       *priv = to_ov2640(client);
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov5642.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov5642.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov5642.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov5642.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@
 #include <linux/v4l2-mediabus.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
 
 /* OV5642 registers */
@@ -610,6 +610,7 @@ struct ov5642 {
 	struct v4l2_subdev		subdev;
 	const struct ov5642_datafmt	*fmt;
 	struct v4l2_rect                crop_rect;
+	struct v4l2_clk			*clk;
 
 	/* blanking information */
 	int total_width;
@@ -848,23 +849,6 @@ static int ov5642_enum_fmt(struct v4l2_s
 	return 0;
 }
 
-static int ov5642_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= V4L2_IDENT_OV5642;
-	id->revision	= 0;
-
-	return 0;
-}
-
 static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -935,12 +919,13 @@ static int ov5642_s_power(struct v4l2_su
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov5642 *priv = to_ov5642(client);
 	int ret;
 
 	if (!on)
-		return soc_camera_power_off(&client->dev, ssdd);
+		return soc_camera_power_off(&client->dev, ssdd, priv->clk);
 
-	ret = soc_camera_power_on(&client->dev, ssdd);
+	ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
 	if (ret < 0)
 		return ret;
 
@@ -966,7 +951,6 @@ static struct v4l2_subdev_video_ops ov56
 
 static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
 	.s_power	= ov5642_s_power,
-	.g_chip_ident	= ov5642_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= ov5642_get_register,
 	.s_register	= ov5642_set_register,
@@ -1021,6 +1005,7 @@ static int ov5642_probe(struct i2c_clien
 {
 	struct ov5642 *priv;
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	int ret;
 
 	if (!ssdd) {
 		dev_err(&client->dev, "OV5642: missing platform data!\n");
@@ -1042,13 +1027,23 @@ static int ov5642_probe(struct i2c_clien
 	priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
 	priv->total_height = BLANKING_MIN_HEIGHT;
 
-	return ov5642_video_probe(client);
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
+	ret = ov5642_video_probe(client);
+	if (ret < 0)
+		v4l2_clk_put(priv->clk);
+
+	return ret;
 }
 
 static int ov5642_remove(struct i2c_client *client)
 {
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov5642 *priv = to_ov5642(client);
 
+	v4l2_clk_put(priv->clk);
 	if (ssdd->free_bus)
 		ssdd->free_bus(ssdd);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov6650.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov6650.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov6650.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov6650.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,7 @@
 #include <linux/module.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
 
 /* Register definitions */
@@ -196,6 +196,7 @@ struct ov6650 {
 		struct v4l2_ctrl *blue;
 		struct v4l2_ctrl *red;
 	};
+	struct v4l2_clk		*clk;
 	bool			half_scale;	/* scale down output by 2 */
 	struct v4l2_rect	rect;		/* sensor cropping window */
 	unsigned long		pclk_limit;	/* from host */
@@ -390,16 +391,6 @@ static int ov6550_s_ctrl(struct v4l2_ctr
 	return -EINVAL;
 }
 
-/* Get chip identification */
-static int ov6650_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	id->ident	= V4L2_IDENT_OV6650;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov6650_get_register(struct v4l2_subdev *sd,
 				struct v4l2_dbg_register *reg)
@@ -436,8 +427,9 @@ static int ov6650_s_power(struct v4l2_su
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov6650 *priv = to_ov6650(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
@@ -879,7 +871,6 @@ static const struct v4l2_ctrl_ops ov6550
 };
 
 static struct v4l2_subdev_core_ops ov6650_core_ops = {
-	.g_chip_ident		= ov6650_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register		= ov6650_get_register,
 	.s_register		= ov6650_set_register,
@@ -1025,9 +1016,18 @@ static int ov6650_probe(struct i2c_clien
 	priv->code	  = V4L2_MBUS_FMT_YUYV8_2X8;
 	priv->colorspace  = V4L2_COLORSPACE_JPEG;
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
+
 	ret = ov6650_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
+	}
 
 	return ret;
 }
@@ -1036,6 +1036,7 @@ static int ov6650_remove(struct i2c_clie
 {
 	struct ov6650 *priv = to_ov6650(client);
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov772x.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov772x.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov772x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov772x.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,8 +26,8 @@
 
 #include <media/ov772x.h>
 #include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-subdev.h>
 
 /*
@@ -396,10 +396,10 @@ struct ov772x_win_size {
 struct ov772x_priv {
 	struct v4l2_subdev                subdev;
 	struct v4l2_ctrl_handler	  hdl;
+	struct v4l2_clk			 *clk;
 	struct ov772x_camera_info        *info;
 	const struct ov772x_color_format *cfmt;
 	const struct ov772x_win_size     *win;
-	int                               model;
 	unsigned short                    flag_vflip:1;
 	unsigned short                    flag_hflip:1;
 	/* band_filter = COM8[5] ? 256 - BDBASE : 0 */
@@ -620,17 +620,6 @@ static int ov772x_s_ctrl(struct v4l2_ctr
 	return -EINVAL;
 }
 
-static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct ov772x_priv *priv = to_ov772x(sd);
-
-	id->ident    = priv->model;
-	id->revision = 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov772x_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
@@ -668,8 +657,9 @@ static int ov772x_s_power(struct v4l2_su
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov772x_priv *priv = to_ov772x(sd);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
@@ -965,11 +955,9 @@ static int ov772x_video_probe(struct ov7
 	switch (VERSION(pid, ver)) {
 	case OV7720:
 		devname     = "ov7720";
-		priv->model = V4L2_IDENT_OV7720;
 		break;
 	case OV7725:
 		devname     = "ov7725";
-		priv->model = V4L2_IDENT_OV7725;
 		break;
 	default:
 		dev_err(&client->dev,
@@ -997,7 +985,6 @@ static const struct v4l2_ctrl_ops ov772x
 };
 
 static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
-	.g_chip_ident	= ov772x_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= ov772x_g_register,
 	.s_register	= ov772x_s_register,
@@ -1088,13 +1075,22 @@ static int ov772x_probe(struct i2c_clien
 	if (priv->hdl.error)
 		return priv->hdl.error;
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
+
 	ret = ov772x_video_probe(priv);
 	if (ret < 0) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
 	} else {
 		priv->cfmt = &ov772x_cfmts[0];
 		priv->win = &ov772x_win_sizes[0];
 	}
+
 	return ret;
 }
 
@@ -1102,6 +1098,7 @@ static int ov772x_remove(struct i2c_clie
 {
 	struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client));
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov9640.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov9640.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov9640.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov9640.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,7 @@
 #include <linux/videodev2.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 
@@ -61,7 +61,7 @@ static const struct ov9640_reg ov9640_re
 
 /* Configurations
  * NOTE: for YUV, alter the following registers:
- * 		COM12 |= OV9640_COM12_YUV_AVG
+ *		COM12 |= OV9640_COM12_YUV_AVG
  *
  *	 for RGB, alter the following registers:
  *		COM7  |= OV9640_COM7_RGB
@@ -287,18 +287,6 @@ static int ov9640_s_ctrl(struct v4l2_ctr
 	return -EINVAL;
 }
 
-/* Get chip identification */
-static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct ov9640_priv *priv = to_ov9640_sensor(sd);
-
-	id->ident	= priv->model;
-	id->revision	= priv->revision;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov9640_get_register(struct v4l2_subdev *sd,
 				struct v4l2_dbg_register *reg)
@@ -337,8 +325,9 @@ static int ov9640_s_power(struct v4l2_su
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov9640_priv *priv = to_ov9640_sensor(sd);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 /* select nearest higher resolution for capture */
@@ -615,12 +604,10 @@ static int ov9640_video_probe(struct i2c
 	switch (VERSION(pid, ver)) {
 	case OV9640_V2:
 		devname		= "ov9640";
-		priv->model	= V4L2_IDENT_OV9640;
 		priv->revision	= 2;
 		break;
 	case OV9640_V3:
 		devname		= "ov9640";
-		priv->model	= V4L2_IDENT_OV9640;
 		priv->revision	= 3;
 		break;
 	default:
@@ -644,7 +631,6 @@ static const struct v4l2_ctrl_ops ov9640
 };
 
 static struct v4l2_subdev_core_ops ov9640_core_ops = {
-	.g_chip_ident		= ov9640_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register		= ov9640_get_register,
 	.s_register		= ov9640_set_register,
@@ -716,10 +702,18 @@ static int ov9640_probe(struct i2c_clien
 	if (priv->hdl.error)
 		return priv->hdl.error;
 
-	ret = ov9640_video_probe(client);
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
 
-	if (ret)
+	ret = ov9640_video_probe(client);
+	if (ret) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
+	}
 
 	return ret;
 }
@@ -729,6 +723,7 @@ static int ov9640_remove(struct i2c_clie
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct ov9640_priv *priv = to_ov9640_sensor(sd);
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov9640.h linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov9640.h
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov9640.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov9640.h	2013-08-25 20:43:22.000000000 -0400
@@ -199,6 +199,7 @@ struct ov9640_reg {
 struct ov9640_priv {
 	struct v4l2_subdev		subdev;
 	struct v4l2_ctrl_handler	hdl;
+	struct v4l2_clk			*clk;
 
 	int				model;
 	int				revision;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov9740.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov9740.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/ov9740.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/ov9740.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/v4l2-mediabus.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
 
 #define to_ov9740(sd)		container_of(sd, struct ov9740_priv, subdev)
@@ -196,8 +196,8 @@ struct ov9740_reg {
 struct ov9740_priv {
 	struct v4l2_subdev		subdev;
 	struct v4l2_ctrl_handler	hdl;
+	struct v4l2_clk			*clk;
 
-	int				ident;
 	u16				model;
 	u8				revision;
 	u8				manid;
@@ -772,18 +772,6 @@ static int ov9740_s_ctrl(struct v4l2_ctr
 	return 0;
 }
 
-/* Get chip identification */
-static int ov9740_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct ov9740_priv *priv = to_ov9740(sd);
-
-	id->ident = priv->ident;
-	id->revision = priv->revision;
-
-	return 0;
-}
-
 static int ov9740_s_power(struct v4l2_subdev *sd, int on)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -792,7 +780,7 @@ static int ov9740_s_power(struct v4l2_su
 	int ret;
 
 	if (on) {
-		ret = soc_camera_power_on(&client->dev, ssdd);
+		ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
 		if (ret < 0)
 			return ret;
 
@@ -806,7 +794,7 @@ static int ov9740_s_power(struct v4l2_su
 			priv->current_enable = true;
 		}
 
-		soc_camera_power_off(&client->dev, ssdd);
+		soc_camera_power_off(&client->dev, ssdd, priv->clk);
 	}
 
 	return 0;
@@ -887,8 +875,6 @@ static int ov9740_video_probe(struct i2c
 		goto done;
 	}
 
-	priv->ident = V4L2_IDENT_OV9740;
-
 	dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, "
 		 "Manufacturer 0x%02x, SMIA Version 0x%02x\n",
 		 priv->model, priv->revision, priv->manid, priv->smiaver);
@@ -927,7 +913,6 @@ static struct v4l2_subdev_video_ops ov97
 };
 
 static struct v4l2_subdev_core_ops ov9740_core_ops = {
-	.g_chip_ident		= ov9740_g_chip_ident,
 	.s_power		= ov9740_s_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register		= ov9740_get_register,
@@ -975,9 +960,18 @@ static int ov9740_probe(struct i2c_clien
 	if (priv->hdl.error)
 		return priv->hdl.error;
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
+
 	ret = ov9740_video_probe(client);
-	if (ret < 0)
+	if (ret < 0) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
+	}
 
 	return ret;
 }
@@ -986,6 +980,7 @@ static int ov9740_remove(struct i2c_clie
 {
 	struct ov9740_priv *priv = i2c_get_clientdata(client);
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/rj54n1cb0c.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/rj54n1cb0c.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/rj54n1cb0c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/rj54n1cb0c.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,8 +17,8 @@
 
 #include <media/rj54n1cb0c.h>
 #include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #define RJ54N1_DEV_CODE			0x0400
@@ -151,6 +151,7 @@ struct rj54n1_clock_div {
 struct rj54n1 {
 	struct v4l2_subdev subdev;
 	struct v4l2_ctrl_handler hdl;
+	struct v4l2_clk *clk;
 	struct rj54n1_clock_div clk_div;
 	const struct rj54n1_datafmt *fmt;
 	struct v4l2_rect rect;	/* Sensor window */
@@ -1120,37 +1121,16 @@ static int rj54n1_s_fmt(struct v4l2_subd
 	return 0;
 }
 
-static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= V4L2_IDENT_RJ54N1CB0C;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int rj54n1_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
-	    reg->reg < 0x400 || reg->reg > 0x1fff)
+	if (reg->reg < 0x400 || reg->reg > 0x1fff)
 		/* Registers > 0x0800 are only available from Sharp support */
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	reg->size = 1;
 	reg->val = reg_read(client, reg->reg);
 
@@ -1165,14 +1145,10 @@ static int rj54n1_s_register(struct v4l2
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
-	    reg->reg < 0x400 || reg->reg > 0x1fff)
+	if (reg->reg < 0x400 || reg->reg > 0x1fff)
 		/* Registers >= 0x0800 are only available from Sharp support */
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -1184,8 +1160,9 @@ static int rj54n1_s_power(struct v4l2_su
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, rj54n1->clk, on);
 }
 
 static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -1233,7 +1210,6 @@ static const struct v4l2_ctrl_ops rj54n1
 };
 
 static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
-	.g_chip_ident	= rj54n1_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= rj54n1_g_register,
 	.s_register	= rj54n1_s_register,
@@ -1382,9 +1358,18 @@ static int rj54n1_probe(struct i2c_clien
 	rj54n1->tgclk_mhz	= (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
 		(clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
 
+	rj54n1->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(rj54n1->clk)) {
+		ret = PTR_ERR(rj54n1->clk);
+		goto eclkget;
+	}
+
 	ret = rj54n1_video_probe(client, rj54n1_priv);
-	if (ret < 0)
+	if (ret < 0) {
+		v4l2_clk_put(rj54n1->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&rj54n1->hdl);
+	}
 
 	return ret;
 }
@@ -1394,6 +1379,7 @@ static int rj54n1_remove(struct i2c_clie
 	struct rj54n1 *rj54n1 = to_rj54n1(client);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 
+	v4l2_clk_put(rj54n1->clk);
 	v4l2_device_unregister_subdev(&rj54n1->subdev);
 	if (ssdd->free_bus)
 		ssdd->free_bus(ssdd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/tw9910.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/tw9910.c
--- linux-libre-3.10-gnu/drivers/media/i2c/soc_camera/tw9910.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/soc_camera/tw9910.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@
 
 #include <media/soc_camera.h>
 #include <media/tw9910.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
 
 #define GET_ID(val)  ((val & 0xF8) >> 3)
@@ -228,6 +228,7 @@ struct tw9910_scale_ctrl {
 
 struct tw9910_priv {
 	struct v4l2_subdev		subdev;
+	struct v4l2_clk			*clk;
 	struct tw9910_video_info	*info;
 	const struct tw9910_scale_ctrl	*scale;
 	v4l2_std_id			norm;
@@ -518,18 +519,6 @@ static int tw9910_s_std(struct v4l2_subd
 	return 0;
 }
 
-static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct tw9910_priv *priv = to_tw9910(client);
-
-	id->ident = V4L2_IDENT_TW9910;
-	id->revision = priv->revision;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int tw9910_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
@@ -540,6 +529,7 @@ static int tw9910_g_register(struct v4l2
 	if (reg->reg > 0xff)
 		return -EINVAL;
 
+	reg->size = 1;
 	ret = i2c_smbus_read_byte_data(client, reg->reg);
 	if (ret < 0)
 		return ret;
@@ -570,8 +560,9 @@ static int tw9910_s_power(struct v4l2_su
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct tw9910_priv *priv = to_tw9910(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
@@ -823,7 +814,6 @@ done:
 }
 
 static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
-	.g_chip_ident	= tw9910_g_chip_ident,
 	.s_std		= tw9910_s_std,
 	.g_std		= tw9910_g_std,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -912,6 +902,7 @@ static int tw9910_probe(struct i2c_clien
 	struct i2c_adapter		*adapter =
 		to_i2c_adapter(client->dev.parent);
 	struct soc_camera_subdev_desc	*ssdd = soc_camera_i2c_to_desc(client);
+	int ret;
 
 	if (!ssdd || !ssdd->drv_priv) {
 		dev_err(&client->dev, "TW9910: missing platform data!\n");
@@ -935,11 +926,21 @@ static int tw9910_probe(struct i2c_clien
 
 	v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
 
-	return tw9910_video_probe(client);
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
+	ret = tw9910_video_probe(client);
+	if (ret < 0)
+		v4l2_clk_put(priv->clk);
+
+	return ret;
 }
 
 static int tw9910_remove(struct i2c_client *client)
 {
+	struct tw9910_priv *priv = to_tw9910(client);
+	v4l2_clk_put(priv->clk);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/sony-btf-mpx.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/sony-btf-mpx.c
--- linux-libre-3.10-gnu/drivers/media/i2c/sony-btf-mpx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/sony-btf-mpx.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,7 @@ MODULE_LICENSE("GPL v2");
 
 static int debug;
 module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on\n");
+MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on");
 
 /* #define MPX_DEBUG */
 
@@ -355,7 +355,7 @@ static int sony_btf_mpx_probe(struct i2c
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	t = kzalloc(sizeof(struct sony_btf_mpx), GFP_KERNEL);
+	t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
 	if (t == NULL)
 		return -ENOMEM;
 
@@ -374,7 +374,6 @@ static int sony_btf_mpx_remove(struct i2
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/sr030pc30.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/sr030pc30.c
--- linux-libre-3.10-gnu/drivers/media/i2c/sr030pc30.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/sr030pc30.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-mediabus.h>
+#include <media/v4l2-ctrls.h>
 #include <media/sr030pc30.h>
 
 static int debug;
@@ -142,17 +143,24 @@ module_param(debug, int, 0644);
 
 struct sr030pc30_info {
 	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler hdl;
 	const struct sr030pc30_platform_data *pdata;
 	const struct sr030pc30_format *curr_fmt;
 	const struct sr030pc30_frmsize *curr_win;
-	unsigned int auto_wb:1;
-	unsigned int auto_exp:1;
 	unsigned int hflip:1;
 	unsigned int vflip:1;
 	unsigned int sleep:1;
-	unsigned int exposure;
-	u8 blue_balance;
-	u8 red_balance;
+	struct {
+		/* auto whitebalance control cluster */
+		struct v4l2_ctrl *awb;
+		struct v4l2_ctrl *red;
+		struct v4l2_ctrl *blue;
+	};
+	struct {
+		/* auto exposure control cluster */
+		struct v4l2_ctrl *autoexp;
+		struct v4l2_ctrl *exp;
+	};
 	u8 i2c_reg_page;
 };
 
@@ -173,52 +181,6 @@ struct i2c_regval {
 	u16 val;
 };
 
-static const struct v4l2_queryctrl sr030pc30_ctrl[] = {
-	{
-		.id		= V4L2_CID_AUTO_WHITE_BALANCE,
-		.type		= V4L2_CTRL_TYPE_BOOLEAN,
-		.name		= "Auto White Balance",
-		.minimum	= 0,
-		.maximum	= 1,
-		.step		= 1,
-		.default_value	= 1,
-	}, {
-		.id		= V4L2_CID_RED_BALANCE,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Red Balance",
-		.minimum	= 0,
-		.maximum	= 127,
-		.step		= 1,
-		.default_value	= 64,
-		.flags		= 0,
-	}, {
-		.id		= V4L2_CID_BLUE_BALANCE,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Blue Balance",
-		.minimum	= 0,
-		.maximum	= 127,
-		.step		= 1,
-		.default_value	= 64,
-	}, {
-		.id		= V4L2_CID_EXPOSURE_AUTO,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Auto Exposure",
-		.minimum	= 0,
-		.maximum	= 1,
-		.step		= 1,
-		.default_value	= 1,
-	}, {
-		.id		= V4L2_CID_EXPOSURE,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Exposure",
-		.minimum	= EXPOS_MIN_MS,
-		.maximum	= EXPOS_MAX_MS,
-		.step		= 1,
-		.default_value	= 1,
-	}, {
-	}
-};
-
 /* supported resolutions */
 static const struct sr030pc30_frmsize sr030pc30_sizes[] = {
 	{
@@ -394,48 +356,6 @@ static int sr030pc30_pwr_ctrl(struct v4l
 	return ret;
 }
 
-static inline int sr030pc30_enable_autoexposure(struct v4l2_subdev *sd, int on)
-{
-	struct sr030pc30_info *info = to_sr030pc30(sd);
-	/* auto anti-flicker is also enabled here */
-	int ret = cam_i2c_write(sd, AE_CTL1_REG, on ? 0xDC : 0x0C);
-	if (!ret)
-		info->auto_exp = on;
-	return ret;
-}
-
-static int sr030pc30_set_exposure(struct v4l2_subdev *sd, int value)
-{
-	struct sr030pc30_info *info = to_sr030pc30(sd);
-
-	unsigned long expos = value * info->pdata->clk_rate / (8 * 1000);
-
-	int ret = cam_i2c_write(sd, EXP_TIMEH_REG, expos >> 16 & 0xFF);
-	if (!ret)
-		ret = cam_i2c_write(sd, EXP_TIMEM_REG, expos >> 8 & 0xFF);
-	if (!ret)
-		ret = cam_i2c_write(sd, EXP_TIMEL_REG, expos & 0xFF);
-	if (!ret) { /* Turn off AE */
-		info->exposure = value;
-		ret = sr030pc30_enable_autoexposure(sd, 0);
-	}
-	return ret;
-}
-
-/* Automatic white balance control */
-static int sr030pc30_enable_autowhitebalance(struct v4l2_subdev *sd, int on)
-{
-	struct sr030pc30_info *info = to_sr030pc30(sd);
-
-	int ret = cam_i2c_write(sd, AWB_CTL2_REG, on ? 0x2E : 0x2F);
-	if (!ret)
-		ret = cam_i2c_write(sd, AWB_CTL1_REG, on ? 0xFB : 0x7B);
-	if (!ret)
-		info->auto_wb = on;
-
-	return ret;
-}
-
 static int sr030pc30_set_flip(struct v4l2_subdev *sd)
 {
 	struct sr030pc30_info *info = to_sr030pc30(sd);
@@ -498,107 +418,56 @@ static int sr030pc30_try_frame_size(stru
 	return -EINVAL;
 }
 
-static int sr030pc30_queryctrl(struct v4l2_subdev *sd,
-			       struct v4l2_queryctrl *qc)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++)
-		if (qc->id == sr030pc30_ctrl[i].id) {
-			*qc = sr030pc30_ctrl[i];
-			v4l2_dbg(1, debug, sd, "%s id: %d\n",
-				 __func__, qc->id);
-			return 0;
-		}
-
-	return -EINVAL;
-}
-
-static inline int sr030pc30_set_bluebalance(struct v4l2_subdev *sd, int value)
-{
-	int ret = cam_i2c_write(sd, MWB_BGAIN_REG, value);
-	if (!ret)
-		to_sr030pc30(sd)->blue_balance = value;
-	return ret;
-}
-
-static inline int sr030pc30_set_redbalance(struct v4l2_subdev *sd, int value)
-{
-	int ret = cam_i2c_write(sd, MWB_RGAIN_REG, value);
-	if (!ret)
-		to_sr030pc30(sd)->red_balance = value;
-	return ret;
-}
-
-static int sr030pc30_s_ctrl(struct v4l2_subdev *sd,
-			    struct v4l2_control *ctrl)
+static int sr030pc30_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	int i, ret = 0;
-
-	for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++)
-		if (ctrl->id == sr030pc30_ctrl[i].id)
-			break;
-
-	if (i == ARRAY_SIZE(sr030pc30_ctrl))
-		return -EINVAL;
-
-	if (ctrl->value < sr030pc30_ctrl[i].minimum ||
-		ctrl->value > sr030pc30_ctrl[i].maximum)
-			return -ERANGE;
+	struct sr030pc30_info *info =
+		container_of(ctrl->handler, struct sr030pc30_info, hdl);
+	struct v4l2_subdev *sd = &info->sd;
+	int ret = 0;
 
 	v4l2_dbg(1, debug, sd, "%s: ctrl_id: %d, value: %d\n",
-			 __func__, ctrl->id, ctrl->value);
+			 __func__, ctrl->id, ctrl->val);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUTO_WHITE_BALANCE:
-		sr030pc30_enable_autowhitebalance(sd, ctrl->value);
-		break;
-	case V4L2_CID_BLUE_BALANCE:
-		ret = sr030pc30_set_bluebalance(sd, ctrl->value);
-		break;
-	case V4L2_CID_RED_BALANCE:
-		ret = sr030pc30_set_redbalance(sd, ctrl->value);
-		break;
-	case V4L2_CID_EXPOSURE_AUTO:
-		sr030pc30_enable_autoexposure(sd,
-			ctrl->value == V4L2_EXPOSURE_AUTO);
-		break;
-	case V4L2_CID_EXPOSURE:
-		ret = sr030pc30_set_exposure(sd, ctrl->value);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return ret;
-}
+		if (ctrl->is_new) {
+			ret = cam_i2c_write(sd, AWB_CTL2_REG,
+					ctrl->val ? 0x2E : 0x2F);
+			if (!ret)
+				ret = cam_i2c_write(sd, AWB_CTL1_REG,
+						ctrl->val ? 0xFB : 0x7B);
+		}
+		if (!ret && info->blue->is_new)
+			ret = cam_i2c_write(sd, MWB_BGAIN_REG, info->blue->val);
+		if (!ret && info->red->is_new)
+			ret = cam_i2c_write(sd, MWB_RGAIN_REG, info->red->val);
+		return ret;
 
-static int sr030pc30_g_ctrl(struct v4l2_subdev *sd,
-			    struct v4l2_control *ctrl)
-{
-	struct sr030pc30_info *info = to_sr030pc30(sd);
+	case V4L2_CID_EXPOSURE_AUTO:
+		/* auto anti-flicker is also enabled here */
+		if (ctrl->is_new)
+			ret = cam_i2c_write(sd, AE_CTL1_REG,
+				ctrl->val == V4L2_EXPOSURE_AUTO ? 0xDC : 0x0C);
+		if (info->exp->is_new) {
+			unsigned long expos = info->exp->val;
 
-	v4l2_dbg(1, debug, sd, "%s: id: %d\n", __func__, ctrl->id);
+			expos = expos * info->pdata->clk_rate / (8 * 1000);
 
-	switch (ctrl->id) {
-	case V4L2_CID_AUTO_WHITE_BALANCE:
-		ctrl->value = info->auto_wb;
-		break;
-	case V4L2_CID_BLUE_BALANCE:
-		ctrl->value = info->blue_balance;
-		break;
-	case V4L2_CID_RED_BALANCE:
-		ctrl->value = info->red_balance;
-		break;
-	case V4L2_CID_EXPOSURE_AUTO:
-		ctrl->value = info->auto_exp;
-		break;
-	case V4L2_CID_EXPOSURE:
-		ctrl->value = info->exposure;
-		break;
+			if (!ret)
+				ret = cam_i2c_write(sd, EXP_TIMEH_REG,
+						expos >> 16 & 0xFF);
+			if (!ret)
+				ret = cam_i2c_write(sd, EXP_TIMEM_REG,
+						expos >> 8 & 0xFF);
+			if (!ret)
+				ret = cam_i2c_write(sd, EXP_TIMEL_REG,
+						expos & 0xFF);
+		}
+		return ret;
 	default:
 		return -EINVAL;
 	}
+
 	return 0;
 }
 
@@ -752,11 +621,19 @@ static int sr030pc30_s_power(struct v4l2
 	return ret;
 }
 
+static const struct v4l2_ctrl_ops sr030pc30_ctrl_ops = {
+	.s_ctrl = sr030pc30_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops sr030pc30_core_ops = {
 	.s_power	= sr030pc30_s_power,
-	.queryctrl	= sr030pc30_queryctrl,
-	.s_ctrl		= sr030pc30_s_ctrl,
-	.g_ctrl		= sr030pc30_g_ctrl,
+	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+	.g_ctrl = v4l2_subdev_g_ctrl,
+	.s_ctrl = v4l2_subdev_s_ctrl,
+	.queryctrl = v4l2_subdev_queryctrl,
+	.querymenu = v4l2_subdev_querymenu,
 };
 
 static const struct v4l2_subdev_video_ops sr030pc30_video_ops = {
@@ -807,6 +684,7 @@ static int sr030pc30_probe(struct i2c_cl
 {
 	struct sr030pc30_info *info;
 	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *hdl;
 	const struct sr030pc30_platform_data *pdata
 		= client->dev.platform_data;
 	int ret;
@@ -820,7 +698,7 @@ static int sr030pc30_probe(struct i2c_cl
 	if (ret)
 		return ret;
 
-	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -830,10 +708,31 @@ static int sr030pc30_probe(struct i2c_cl
 
 	v4l2_i2c_subdev_init(sd, client, &sr030pc30_ops);
 
+	hdl = &info->hdl;
+	v4l2_ctrl_handler_init(hdl, 6);
+	info->awb = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
+	info->red = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_RED_BALANCE, 0, 127, 1, 64);
+	info->blue = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_BLUE_BALANCE, 0, 127, 1, 64);
+	info->autoexp = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_EXPOSURE_AUTO, 0, 1, 1, 1);
+	info->exp = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_EXPOSURE, EXPOS_MIN_MS, EXPOS_MAX_MS, 1, 30);
+	sd->ctrl_handler = hdl;
+	if (hdl->error) {
+		int err = hdl->error;
+
+		v4l2_ctrl_handler_free(hdl);
+		return err;
+	}
+	v4l2_ctrl_auto_cluster(3, &info->awb, 0, false);
+	v4l2_ctrl_auto_cluster(2, &info->autoexp, V4L2_EXPOSURE_MANUAL, false);
+	v4l2_ctrl_handler_setup(hdl);
+
 	info->i2c_reg_page	= -1;
 	info->hflip		= 1;
-	info->auto_exp		= 1;
-	info->exposure		= 30;
 
 	return 0;
 }
@@ -841,10 +740,9 @@ static int sr030pc30_probe(struct i2c_cl
 static int sr030pc30_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct sr030pc30_info *info = to_sr030pc30(sd);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(info);
+	v4l2_ctrl_handler_free(sd->ctrl_handler);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tda7432.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tda7432.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tda7432.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tda7432.c	2013-08-25 20:43:22.000000000 -0400
@@ -359,7 +359,7 @@ static int tda7432_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	t = kzalloc(sizeof(*t), GFP_KERNEL);
+	t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
 	if (!t)
 		return -ENOMEM;
 	sd = &t->sd;
@@ -380,7 +380,6 @@ static int tda7432_probe(struct i2c_clie
 		int err = t->hdl.error;
 
 		v4l2_ctrl_handler_free(&t->hdl);
-		kfree(t);
 		return err;
 	}
 	v4l2_ctrl_cluster(2, &t->bass);
@@ -406,7 +405,6 @@ static int tda7432_remove(struct i2c_cli
 	tda7432_set(sd);
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&t->hdl);
-	kfree(t);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tda9840.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tda9840.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tda9840.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tda9840.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,6 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
 MODULE_DESCRIPTION("tda9840 driver");
@@ -145,26 +144,14 @@ static int tda9840_g_tuner(struct v4l2_s
 	return 0;
 }
 
-static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops tda9840_core_ops = {
-	.g_chip_ident = tda9840_g_chip_ident,
-};
-
 static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
 	.s_tuner = tda9840_s_tuner,
 	.g_tuner = tda9840_g_tuner,
 };
 
 static const struct v4l2_subdev_ops tda9840_ops = {
-	.core = &tda9840_core_ops,
 	.tuner = &tda9840_tuner_ops,
 };
 
@@ -184,7 +171,7 @@ static int tda9840_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 	v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
@@ -201,7 +188,6 @@ static int tda9840_remove(struct i2c_cli
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tea6415c.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tea6415c.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tea6415c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tea6415c.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include "tea6415c.h"
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -119,25 +118,13 @@ static int tea6415c_s_routing(struct v4l
 	return ret;
 }
 
-static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops tea6415c_core_ops = {
-	.g_chip_ident = tea6415c_g_chip_ident,
-};
-
 static const struct v4l2_subdev_video_ops tea6415c_video_ops = {
 	.s_routing = tea6415c_s_routing,
 };
 
 static const struct v4l2_subdev_ops tea6415c_ops = {
-	.core = &tea6415c_core_ops,
 	.video = &tea6415c_video_ops,
 };
 
@@ -152,7 +139,7 @@ static int tea6415c_probe(struct i2c_cli
 
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 	v4l2_i2c_subdev_init(sd, client, &tea6415c_ops);
@@ -164,7 +151,6 @@ static int tea6415c_remove(struct i2c_cl
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tea6420.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tea6420.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tea6420.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tea6420.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include "tea6420.h"
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -90,25 +89,13 @@ static int tea6420_s_routing(struct v4l2
 	return 0;
 }
 
-static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops tea6420_core_ops = {
-	.g_chip_ident = tea6420_g_chip_ident,
-};
-
 static const struct v4l2_subdev_audio_ops tea6420_audio_ops = {
 	.s_routing = tea6420_s_routing,
 };
 
 static const struct v4l2_subdev_ops tea6420_ops = {
-	.core = &tea6420_core_ops,
 	.audio = &tea6420_audio_ops,
 };
 
@@ -125,7 +112,7 @@ static int tea6420_probe(struct i2c_clie
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 	v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
@@ -146,7 +133,6 @@ static int tea6420_remove(struct i2c_cli
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ths7303.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/ths7303.c
--- linux-libre-3.10-gnu/drivers/media/i2c/ths7303.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ths7303.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 
 #include <media/ths7303.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-device.h>
 
 #define THS7303_CHANNEL_1	1
@@ -35,11 +34,10 @@
 
 struct ths7303_state {
 	struct v4l2_subdev		sd;
-	struct ths7303_platform_data	pdata;
+	const struct ths7303_platform_data *pdata;
 	struct v4l2_bt_timings		bt;
 	int std_id;
 	int stream_on;
-	int driver_data;
 };
 
 enum ths7303_filter_mode {
@@ -89,7 +87,7 @@ int ths7303_setval(struct v4l2_subdev *s
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct ths7303_state *state = to_state(sd);
-	struct ths7303_platform_data *pdata = &state->pdata;
+	const struct ths7303_platform_data *pdata = state->pdata;
 	u8 val, sel = 0;
 	int err, disable = 0;
 
@@ -212,15 +210,6 @@ static int ths7303_s_dv_timings(struct v
 	return ths7303_config(sd);
 }
 
-static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ths7303_state *state = to_state(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->driver_data, 0);
-}
-
 static const struct v4l2_subdev_video_ops ths7303_video_ops = {
 	.s_stream	= ths7303_s_stream,
 	.s_std_output	= ths7303_s_std_output,
@@ -232,13 +221,6 @@ static const struct v4l2_subdev_video_op
 static int ths7303_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	reg->size = 1;
 	reg->val = ths7303_read(sd, reg->reg);
 	return 0;
@@ -247,13 +229,6 @@ static int ths7303_g_register(struct v4l
 static int ths7303_s_register(struct v4l2_subdev *sd,
 			      const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	ths7303_write(sd, reg->reg, reg->val);
 	return 0;
 }
@@ -340,7 +315,6 @@ static int ths7303_log_status(struct v4l
 }
 
 static const struct v4l2_subdev_core_ops ths7303_core_ops = {
-	.g_chip_ident = ths7303_g_chip_ident,
 	.log_status = ths7303_log_status,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = ths7303_g_register,
@@ -353,32 +327,6 @@ static const struct v4l2_subdev_ops ths7
 	.video 	= &ths7303_video_ops,
 };
 
-static int ths7303_setup(struct v4l2_subdev *sd)
-{
-	struct ths7303_state *state = to_state(sd);
-	struct ths7303_platform_data *pdata = &state->pdata;
-	int ret;
-	u8 mask;
-
-	state->stream_on = pdata->init_enable;
-
-	mask = state->stream_on ? 0xff : 0xf8;
-
-	ret = ths7303_write(sd, THS7303_CHANNEL_1, pdata->ch_1 & mask);
-	if (ret)
-		return ret;
-
-	ret = ths7303_write(sd, THS7303_CHANNEL_2, pdata->ch_2 & mask);
-	if (ret)
-		return ret;
-
-	ret = ths7303_write(sd, THS7303_CHANNEL_3, pdata->ch_3 & mask);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
 static int ths7303_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -386,6 +334,11 @@ static int ths7303_probe(struct i2c_clie
 	struct ths7303_state *state;
 	struct v4l2_subdev *sd;
 
+	if (pdata == NULL) {
+		dev_err(&client->dev, "No platform data\n");
+		return -EINVAL;
+	}
+
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
@@ -397,20 +350,14 @@ static int ths7303_probe(struct i2c_clie
 	if (!state)
 		return -ENOMEM;
 
-	if (!pdata)
-		v4l_warn(client, "No platform data, using default data!\n");
-	else
-		state->pdata = *pdata;
-
+	state->pdata = pdata;
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
 
-	/* store the driver data to differntiate the chip */
-	state->driver_data = (int)id->driver_data;
-
-	if (ths7303_setup(sd) < 0) {
-		v4l_err(client, "init failed\n");
-		return -EIO;
+	/* set to default 480I_576I filter mode */
+	if (ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I) < 0) {
+		v4l_err(client, "Setting to 480I_576I filter mode failed!\n");
+		return -EINVAL;
 	}
 
 	return 0;
@@ -426,8 +373,8 @@ static int ths7303_remove(struct i2c_cli
 }
 
 static const struct i2c_device_id ths7303_id[] = {
-	{"ths7303", V4L2_IDENT_THS7303},
-	{"ths7353", V4L2_IDENT_THS7353},
+	{"ths7303", 0},
+	{"ths7353", 0},
 	{},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ths8200.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/ths8200.c
--- linux-libre-3.10-gnu/drivers/media/i2c/ths8200.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ths8200.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,556 @@
+/*
+ * ths8200 - Texas Instruments THS8200 video encoder driver
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/v4l2-dv-timings.h>
+
+#include <media/v4l2-device.h>
+
+#include "ths8200_regs.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+
+MODULE_DESCRIPTION("Texas Instruments THS8200 video encoder driver");
+MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>");
+MODULE_AUTHOR("Martin Bugge <martin.bugge@cisco.com>");
+MODULE_LICENSE("GPL v2");
+
+struct ths8200_state {
+	struct v4l2_subdev sd;
+	uint8_t chip_version;
+	/* Is the ths8200 powered on? */
+	bool power_on;
+	struct v4l2_dv_timings dv_timings;
+};
+
+static const struct v4l2_dv_timings ths8200_timings[] = {
+	V4L2_DV_BT_CEA_720X480P59_94,
+	V4L2_DV_BT_CEA_1280X720P24,
+	V4L2_DV_BT_CEA_1280X720P25,
+	V4L2_DV_BT_CEA_1280X720P30,
+	V4L2_DV_BT_CEA_1280X720P50,
+	V4L2_DV_BT_CEA_1280X720P60,
+	V4L2_DV_BT_CEA_1920X1080P24,
+	V4L2_DV_BT_CEA_1920X1080P25,
+	V4L2_DV_BT_CEA_1920X1080P30,
+	V4L2_DV_BT_CEA_1920X1080P50,
+	V4L2_DV_BT_CEA_1920X1080P60,
+};
+
+static inline struct ths8200_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct ths8200_state, sd);
+}
+
+static inline unsigned hblanking(const struct v4l2_bt_timings *t)
+{
+	return t->hfrontporch + t->hsync + t->hbackporch;
+}
+
+static inline unsigned htotal(const struct v4l2_bt_timings *t)
+{
+	return t->width + t->hfrontporch + t->hsync + t->hbackporch;
+}
+
+static inline unsigned vblanking(const struct v4l2_bt_timings *t)
+{
+	return t->vfrontporch + t->vsync + t->vbackporch;
+}
+
+static inline unsigned vtotal(const struct v4l2_bt_timings *t)
+{
+	return t->height + t->vfrontporch + t->vsync + t->vbackporch;
+}
+
+static int ths8200_read(struct v4l2_subdev *sd, u8 reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int ths8200_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		ret = i2c_smbus_write_byte_data(client, reg, val);
+		if (ret == 0)
+			return 0;
+	}
+	v4l2_err(sd, "I2C Write Problem\n");
+	return ret;
+}
+
+/* To set specific bits in the register, a clear-mask is given (to be AND-ed),
+ * and then the value-mask (to be OR-ed).
+ */
+static inline void
+ths8200_write_and_or(struct v4l2_subdev *sd, u8 reg,
+		     uint8_t clr_mask, uint8_t val_mask)
+{
+	ths8200_write(sd, reg, (ths8200_read(sd, reg) & clr_mask) | val_mask);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+static int ths8200_g_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
+{
+	reg->val = ths8200_read(sd, reg->reg & 0xff);
+	reg->size = 1;
+
+	return 0;
+}
+
+static int ths8200_s_register(struct v4l2_subdev *sd,
+			      const struct v4l2_dbg_register *reg)
+{
+	ths8200_write(sd, reg->reg & 0xff, reg->val & 0xff);
+
+	return 0;
+}
+#endif
+
+static void ths8200_print_timings(struct v4l2_subdev *sd,
+				  struct v4l2_dv_timings *timings,
+				  const char *txt, bool detailed)
+{
+	struct v4l2_bt_timings *bt = &timings->bt;
+	u32 htot, vtot;
+
+	if (timings->type != V4L2_DV_BT_656_1120)
+		return;
+
+	htot = htotal(bt);
+	vtot = vtotal(bt);
+
+	v4l2_info(sd, "%s %dx%d%s%d (%dx%d)",
+		  txt, bt->width, bt->height, bt->interlaced ? "i" : "p",
+		  (htot * vtot) > 0 ? ((u32)bt->pixelclock / (htot * vtot)) : 0,
+		  htot, vtot);
+
+	if (detailed) {
+		v4l2_info(sd, "    horizontal: fp = %d, %ssync = %d, bp = %d\n",
+			  bt->hfrontporch,
+			  (bt->polarities & V4L2_DV_HSYNC_POS_POL) ? "+" : "-",
+			  bt->hsync, bt->hbackporch);
+		v4l2_info(sd, "    vertical: fp = %d, %ssync = %d, bp = %d\n",
+			  bt->vfrontporch,
+			  (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-",
+			  bt->vsync, bt->vbackporch);
+		v4l2_info(sd,
+			  "    pixelclock: %lld, flags: 0x%x, standards: 0x%x\n",
+			  bt->pixelclock, bt->flags, bt->standards);
+	}
+}
+
+static int ths8200_log_status(struct v4l2_subdev *sd)
+{
+	struct ths8200_state *state = to_state(sd);
+	uint8_t reg_03 = ths8200_read(sd, THS8200_CHIP_CTL);
+
+	v4l2_info(sd, "----- Chip status -----\n");
+	v4l2_info(sd, "version: %u\n", state->chip_version);
+	v4l2_info(sd, "power: %s\n", (reg_03 & 0x0c) ? "off" : "on");
+	v4l2_info(sd, "reset: %s\n", (reg_03 & 0x01) ? "off" : "on");
+	v4l2_info(sd, "test pattern: %s\n",
+		  (reg_03 & 0x20) ? "enabled" : "disabled");
+	v4l2_info(sd, "format: %ux%u\n",
+		  ths8200_read(sd, THS8200_DTG2_PIXEL_CNT_MSB) * 256 +
+		  ths8200_read(sd, THS8200_DTG2_PIXEL_CNT_LSB),
+		  (ths8200_read(sd, THS8200_DTG2_LINE_CNT_MSB) & 0x07) * 256 +
+		  ths8200_read(sd, THS8200_DTG2_LINE_CNT_LSB));
+	ths8200_print_timings(sd, &state->dv_timings,
+			      "Configured format:", true);
+
+	return 0;
+}
+
+/* Power up/down ths8200 */
+static int ths8200_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct ths8200_state *state = to_state(sd);
+
+	v4l2_dbg(1, debug, sd, "%s: power %s\n", __func__, on ? "on" : "off");
+
+	state->power_on = on;
+
+	/* Power up/down - leave in reset state until input video is present */
+	ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0xf2, (on ? 0x00 : 0x0c));
+
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops ths8200_core_ops = {
+	.log_status = ths8200_log_status,
+	.s_power = ths8200_s_power,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = ths8200_g_register,
+	.s_register = ths8200_s_register,
+#endif
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev video operations
+ */
+
+static int ths8200_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct ths8200_state *state = to_state(sd);
+
+	if (enable && !state->power_on)
+		ths8200_s_power(sd, true);
+
+	ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0xfe,
+			     (enable ? 0x01 : 0x00));
+
+	v4l2_dbg(1, debug, sd, "%s: %sable\n",
+		 __func__, (enable ? "en" : "dis"));
+
+	return 0;
+}
+
+static void ths8200_core_init(struct v4l2_subdev *sd)
+{
+	/* setup clocks */
+	ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0x3f, 0xc0);
+
+	/**** Data path control (DATA) ****/
+	/* Set FSADJ 700 mV,
+	 * bypass 422-444 interpolation,
+	 * input format 30 bit RGB444
+	 */
+	ths8200_write(sd, THS8200_DATA_CNTL, 0x70);
+
+	/* DTG Mode (Video blocked during blanking
+	 * VESA slave
+	 */
+	ths8200_write(sd, THS8200_DTG1_MODE, 0x87);
+
+	/**** Display Timing Generator Control, Part 1 (DTG1). ****/
+
+	/* Disable embedded syncs on the output by setting
+	 * the amplitude to zero for all channels.
+	 */
+	ths8200_write(sd, THS8200_DTG1_Y_SYNC_MSB, 0x2a);
+	ths8200_write(sd, THS8200_DTG1_CBCR_SYNC_MSB, 0x2a);
+}
+
+static void ths8200_setup(struct v4l2_subdev *sd, struct v4l2_bt_timings *bt)
+{
+	uint8_t polarity = 0;
+	uint16_t line_start_active_video = (bt->vsync + bt->vbackporch);
+	uint16_t line_start_front_porch  = (vtotal(bt) - bt->vfrontporch);
+
+	/*** System ****/
+	/* Set chip in reset while it is configured */
+	ths8200_s_stream(sd, false);
+
+	/* configure video output timings */
+	ths8200_write(sd, THS8200_DTG1_SPEC_A, bt->hsync);
+	ths8200_write(sd, THS8200_DTG1_SPEC_B, bt->hfrontporch);
+
+	/* Zero for progressive scan formats.*/
+	if (!bt->interlaced)
+		ths8200_write(sd, THS8200_DTG1_SPEC_C, 0x00);
+
+	/* Distance from leading edge of h sync to start of active video.
+	 * MSB in 0x2b
+	 */
+	ths8200_write(sd, THS8200_DTG1_SPEC_D_LSB,
+		      (bt->hbackporch + bt->hsync) & 0xff);
+	/* Zero for SDTV-mode. MSB in 0x2b */
+	ths8200_write(sd, THS8200_DTG1_SPEC_E_LSB, 0x00);
+	/*
+	 * MSB for dtg1_spec(d/e/h). See comment for
+	 * corresponding LSB registers.
+	 */
+	ths8200_write(sd, THS8200_DTG1_SPEC_DEH_MSB,
+		      ((bt->hbackporch + bt->hsync) & 0x100) >> 1);
+
+	/* h front porch */
+	ths8200_write(sd, THS8200_DTG1_SPEC_K_LSB, (bt->hfrontporch) & 0xff);
+	ths8200_write(sd, THS8200_DTG1_SPEC_K_MSB,
+		      ((bt->hfrontporch) & 0x700) >> 8);
+
+	/* Half the line length. Used to calculate SDTV line types. */
+	ths8200_write(sd, THS8200_DTG1_SPEC_G_LSB, (htotal(bt)/2) & 0xff);
+	ths8200_write(sd, THS8200_DTG1_SPEC_G_MSB,
+		      ((htotal(bt)/2) >> 8) & 0x0f);
+
+	/* Total pixels per line (ex. 720p: 1650) */
+	ths8200_write(sd, THS8200_DTG1_TOT_PIXELS_MSB, htotal(bt) >> 8);
+	ths8200_write(sd, THS8200_DTG1_TOT_PIXELS_LSB, htotal(bt) & 0xff);
+
+	/* Frame height and field height */
+	/* Field height should be programmed higher than frame_size for
+	 * progressive scan formats
+	 */
+	ths8200_write(sd, THS8200_DTG1_FRAME_FIELD_SZ_MSB,
+		      ((vtotal(bt) >> 4) & 0xf0) + 0x7);
+	ths8200_write(sd, THS8200_DTG1_FRAME_SZ_LSB, vtotal(bt) & 0xff);
+
+	/* Should be programmed higher than frame_size
+	 * for progressive formats
+	 */
+	if (!bt->interlaced)
+		ths8200_write(sd, THS8200_DTG1_FIELD_SZ_LSB, 0xff);
+
+	/**** Display Timing Generator Control, Part 2 (DTG2). ****/
+	/* Set breakpoint line numbers and types
+	 * THS8200 generates line types with different properties. A line type
+	 * that sets all the RGB-outputs to zero is used in the blanking areas,
+	 * while a line type that enable the RGB-outputs is used in active video
+	 * area. The line numbers for start of active video, start of front
+	 * porch and after the last line in the frame must be set with the
+	 * corresponding line types.
+	 *
+	 * Line types:
+	 * 0x9 - Full normal sync pulse: Blocks data when dtg1_pass is off.
+	 *       Used in blanking area.
+	 * 0x0 - Active video: Video data is always passed. Used in active
+	 *       video area.
+	 */
+	ths8200_write_and_or(sd, THS8200_DTG2_BP1_2_MSB, 0x88,
+			     ((line_start_active_video >> 4) & 0x70) +
+			     ((line_start_front_porch >> 8) & 0x07));
+	ths8200_write(sd, THS8200_DTG2_BP3_4_MSB, ((vtotal(bt)) >> 4) & 0x70);
+	ths8200_write(sd, THS8200_DTG2_BP1_LSB, line_start_active_video & 0xff);
+	ths8200_write(sd, THS8200_DTG2_BP2_LSB, line_start_front_porch & 0xff);
+	ths8200_write(sd, THS8200_DTG2_BP3_LSB, (vtotal(bt)) & 0xff);
+
+	/* line types */
+	ths8200_write(sd, THS8200_DTG2_LINETYPE1, 0x90);
+	ths8200_write(sd, THS8200_DTG2_LINETYPE2, 0x90);
+
+	/* h sync width transmitted */
+	ths8200_write(sd, THS8200_DTG2_HLENGTH_LSB, bt->hsync & 0xff);
+	ths8200_write_and_or(sd, THS8200_DTG2_HLENGTH_LSB_HDLY_MSB, 0x3f,
+			     (bt->hsync >> 2) & 0xc0);
+
+	/* The pixel value h sync is asserted on */
+	ths8200_write_and_or(sd, THS8200_DTG2_HLENGTH_LSB_HDLY_MSB, 0xe0,
+			     (htotal(bt) >> 8) & 0x1f);
+	ths8200_write(sd, THS8200_DTG2_HLENGTH_HDLY_LSB, htotal(bt));
+
+	/* v sync width transmitted */
+	ths8200_write(sd, THS8200_DTG2_VLENGTH1_LSB, (bt->vsync) & 0xff);
+	ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0x3f,
+			     ((bt->vsync) >> 2) & 0xc0);
+
+	/* The pixel value v sync is asserted on */
+	ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0xf8,
+			     (vtotal(bt)>>8) & 0x7);
+	ths8200_write(sd, THS8200_DTG2_VDLY1_LSB, vtotal(bt));
+
+	/* For progressive video vlength2 must be set to all 0 and vdly2 must
+	 * be set to all 1.
+	 */
+	ths8200_write(sd, THS8200_DTG2_VLENGTH2_LSB, 0x00);
+	ths8200_write(sd, THS8200_DTG2_VLENGTH2_MSB_VDLY2_MSB, 0x07);
+	ths8200_write(sd, THS8200_DTG2_VDLY2_LSB, 0xff);
+
+	/* Internal delay factors to synchronize the sync pulses and the data */
+	/* Experimental values delays (hor 4, ver 1) */
+	ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_MSB, (htotal(bt)>>8) & 0x1f);
+	ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_LSB, (htotal(bt) - 4) & 0xff);
+	ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_MSB, 0);
+	ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_LSB, 1);
+
+	/* Polarity of received and transmitted sync signals */
+	if (bt->polarities & V4L2_DV_HSYNC_POS_POL) {
+		polarity |= 0x01; /* HS_IN */
+		polarity |= 0x08; /* HS_OUT */
+	}
+	if (bt->polarities & V4L2_DV_VSYNC_POS_POL) {
+		polarity |= 0x02; /* VS_IN */
+		polarity |= 0x10; /* VS_OUT */
+	}
+
+	/* RGB mode, no embedded timings */
+	/* Timing of video input bus is derived from HS, VS, and FID dedicated
+	 * inputs
+	 */
+	ths8200_write(sd, THS8200_DTG2_CNTL, 0x47 | polarity);
+
+	/* leave reset */
+	ths8200_s_stream(sd, true);
+
+	v4l2_dbg(1, debug, sd, "%s: frame %dx%d, polarity %d\n"
+		 "horizontal: front porch %d, back porch %d, sync %d\n"
+		 "vertical: sync %d\n", __func__, htotal(bt), vtotal(bt),
+		 polarity, bt->hfrontporch, bt->hbackporch,
+		 bt->hsync, bt->vsync);
+}
+
+static int ths8200_s_dv_timings(struct v4l2_subdev *sd,
+				struct v4l2_dv_timings *timings)
+{
+	struct ths8200_state *state = to_state(sd);
+	int i;
+
+	v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+	if (timings->type != V4L2_DV_BT_656_1120)
+		return -EINVAL;
+
+	/* TODO Support interlaced formats */
+	if (timings->bt.interlaced) {
+		v4l2_dbg(1, debug, sd, "TODO Support interlaced formats\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ths8200_timings); i++) {
+		if (v4l_match_dv_timings(&ths8200_timings[i], timings, 10))
+			break;
+	}
+
+	if (i == ARRAY_SIZE(ths8200_timings)) {
+		v4l2_dbg(1, debug, sd, "Unsupported format\n");
+		return -EINVAL;
+	}
+
+	timings->bt.flags &= ~V4L2_DV_FL_REDUCED_FPS;
+
+	/* save timings */
+	state->dv_timings = *timings;
+
+	ths8200_setup(sd, &timings->bt);
+
+	return 0;
+}
+
+static int ths8200_g_dv_timings(struct v4l2_subdev *sd,
+				struct v4l2_dv_timings *timings)
+{
+	struct ths8200_state *state = to_state(sd);
+
+	v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+	*timings = state->dv_timings;
+
+	return 0;
+}
+
+static int ths8200_enum_dv_timings(struct v4l2_subdev *sd,
+				   struct v4l2_enum_dv_timings *timings)
+{
+	/* Check requested format index is within range */
+	if (timings->index >= ARRAY_SIZE(ths8200_timings))
+		return -EINVAL;
+
+	timings->timings = ths8200_timings[timings->index];
+
+	return 0;
+}
+
+static int ths8200_dv_timings_cap(struct v4l2_subdev *sd,
+				  struct v4l2_dv_timings_cap *cap)
+{
+	cap->type = V4L2_DV_BT_656_1120;
+	cap->bt.max_width = 1920;
+	cap->bt.max_height = 1080;
+	cap->bt.min_pixelclock = 27000000;
+	cap->bt.max_pixelclock = 148500000;
+	cap->bt.standards = V4L2_DV_BT_STD_CEA861;
+	cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE;
+
+	return 0;
+}
+
+/* Specific video subsystem operation handlers */
+static const struct v4l2_subdev_video_ops ths8200_video_ops = {
+	.s_stream = ths8200_s_stream,
+	.s_dv_timings = ths8200_s_dv_timings,
+	.g_dv_timings = ths8200_g_dv_timings,
+	.enum_dv_timings = ths8200_enum_dv_timings,
+	.dv_timings_cap = ths8200_dv_timings_cap,
+};
+
+/* V4L2 top level operation handlers */
+static const struct v4l2_subdev_ops ths8200_ops = {
+	.core  = &ths8200_core_ops,
+	.video = &ths8200_video_ops,
+};
+
+static int ths8200_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct ths8200_state *state;
+	struct v4l2_subdev *sd;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	sd = &state->sd;
+	v4l2_i2c_subdev_init(sd, client, &ths8200_ops);
+
+	state->chip_version = ths8200_read(sd, THS8200_VERSION);
+	v4l2_dbg(1, debug, sd, "chip version 0x%x\n", state->chip_version);
+
+	ths8200_core_init(sd);
+
+	v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
+		  client->addr << 1, client->adapter->name);
+
+	return 0;
+}
+
+static int ths8200_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_dbg(1, debug, sd, "%s removed @ 0x%x (%s)\n", client->name,
+		 client->addr << 1, client->adapter->name);
+
+	ths8200_s_power(sd, false);
+
+	v4l2_device_unregister_subdev(sd);
+
+	return 0;
+}
+
+static struct i2c_device_id ths8200_id[] = {
+	{ "ths8200", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, ths8200_id);
+
+static struct i2c_driver ths8200_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "ths8200",
+	},
+	.probe = ths8200_probe,
+	.remove = ths8200_remove,
+	.id_table = ths8200_id,
+};
+
+module_i2c_driver(ths8200_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/ths8200_regs.h linux-libre-3.11-rc7-gnu/drivers/media/i2c/ths8200_regs.h
--- linux-libre-3.10-gnu/drivers/media/i2c/ths8200_regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/ths8200_regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,161 @@
+/*
+ * ths8200 - Texas Instruments THS8200 video encoder driver
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef THS8200_REGS_H
+#define THS8200_REGS_H
+
+/* Register offset macros */
+#define THS8200_VERSION				0x02
+#define THS8200_CHIP_CTL			0x03
+#define THS8200_CSC_R11				0x04
+#define THS8200_CSC_R12				0x05
+#define THS8200_CSC_R21				0x06
+#define THS8200_CSC_R22				0x07
+#define THS8200_CSC_R31				0x08
+#define THS8200_CSC_R32				0x09
+#define THS8200_CSC_G11				0x0a
+#define THS8200_CSC_G12				0x0b
+#define THS8200_CSC_G21				0x0c
+#define THS8200_CSC_G22				0x0d
+#define THS8200_CSC_G31				0x0e
+#define THS8200_CSC_G32				0x0f
+#define THS8200_CSC_B11				0x10
+#define THS8200_CSC_B12				0x11
+#define THS8200_CSC_B21				0x12
+#define THS8200_CSC_B22				0x13
+#define THS8200_CSC_B31				0x14
+#define THS8200_CSC_B32				0x15
+#define THS8200_CSC_OFFS1			0x16
+#define THS8200_CSC_OFFS12			0x17
+#define THS8200_CSC_OFFS23			0x18
+#define THS8200_CSC_OFFS3			0x19
+#define THS8200_TST_CNTL1			0x1a
+#define THS8200_TST_CNTL2			0x1b
+#define THS8200_DATA_CNTL			0x1c
+#define THS8200_DTG1_Y_SYNC1_LSB		0x1d
+#define THS8200_DTG1_Y_SYNC2_LSB		0x1e
+#define THS8200_DTG1_Y_SYNC3_LSB		0x1f
+#define THS8200_DTG1_CBCR_SYNC1_LSB		0x20
+#define THS8200_DTG1_CBCR_SYNC2_LSB		0x21
+#define THS8200_DTG1_CBCR_SYNC3_LSB		0x22
+#define THS8200_DTG1_Y_SYNC_MSB			0x23
+#define THS8200_DTG1_CBCR_SYNC_MSB		0x24
+#define THS8200_DTG1_SPEC_A			0x25
+#define THS8200_DTG1_SPEC_B			0x26
+#define THS8200_DTG1_SPEC_C			0x27
+#define THS8200_DTG1_SPEC_D_LSB			0x28
+#define THS8200_DTG1_SPEC_D1			0x29
+#define THS8200_DTG1_SPEC_E_LSB			0x2a
+#define THS8200_DTG1_SPEC_DEH_MSB		0x2b
+#define THS8200_DTG1_SPEC_H_LSB			0x2c
+#define THS8200_DTG1_SPEC_I_MSB			0x2d
+#define THS8200_DTG1_SPEC_I_LSB			0x2e
+#define THS8200_DTG1_SPEC_K_LSB			0x2f
+#define THS8200_DTG1_SPEC_K_MSB			0x30
+#define THS8200_DTG1_SPEC_K1			0x31
+#define THS8200_DTG1_SPEC_G_LSB			0x32
+#define THS8200_DTG1_SPEC_G_MSB			0x33
+#define THS8200_DTG1_TOT_PIXELS_MSB		0x34
+#define THS8200_DTG1_TOT_PIXELS_LSB		0x35
+#define THS8200_DTG1_FLD_FLIP_LINECNT_MSB	0x36
+#define THS8200_DTG1_LINECNT_LSB		0x37
+#define THS8200_DTG1_MODE			0x38
+#define THS8200_DTG1_FRAME_FIELD_SZ_MSB		0x39
+#define THS8200_DTG1_FRAME_SZ_LSB		0x3a
+#define THS8200_DTG1_FIELD_SZ_LSB		0x3b
+#define THS8200_DTG1_VESA_CBAR_SIZE		0x3c
+#define THS8200_DAC_CNTL_MSB			0x3d
+#define THS8200_DAC1_CNTL_LSB			0x3e
+#define THS8200_DAC2_CNTL_LSB			0x3f
+#define THS8200_DAC3_CNTL_LSB			0x40
+#define THS8200_CSM_CLIP_GY_LOW			0x41
+#define THS8200_CSM_CLIP_BCB_LOW		0x42
+#define THS8200_CSM_CLIP_RCR_LOW		0x43
+#define THS8200_CSM_CLIP_GY_HIGH		0x44
+#define THS8200_CSM_CLIP_BCB_HIGH		0x45
+#define THS8200_CSM_CLIP_RCR_HIGH		0x46
+#define THS8200_CSM_SHIFT_GY			0x47
+#define THS8200_CSM_SHIFT_BCB			0x48
+#define THS8200_CSM_SHIFT_RCR			0x49
+#define THS8200_CSM_GY_CNTL_MULT_MSB		0x4a
+#define THS8200_CSM_MULT_BCB_RCR_MSB		0x4b
+#define THS8200_CSM_MULT_GY_LSB			0x4c
+#define THS8200_CSM_MULT_BCB_LSB		0x4d
+#define THS8200_CSM_MULT_RCR_LSB		0x4e
+#define THS8200_CSM_MULT_RCR_BCB_CNTL		0x4f
+#define THS8200_CSM_MULT_RCR_LSB		0x4e
+#define THS8200_DTG2_BP1_2_MSB			0x50
+#define THS8200_DTG2_BP3_4_MSB			0x51
+#define THS8200_DTG2_BP5_6_MSB			0x52
+#define THS8200_DTG2_BP7_8_MSB			0x53
+#define THS8200_DTG2_BP9_10_MSB			0x54
+#define THS8200_DTG2_BP11_12_MSB		0x55
+#define THS8200_DTG2_BP13_14_MSB		0x56
+#define THS8200_DTG2_BP15_16_MSB		0x57
+#define THS8200_DTG2_BP1_LSB			0x58
+#define THS8200_DTG2_BP2_LSB			0x59
+#define THS8200_DTG2_BP3_LSB			0x5a
+#define THS8200_DTG2_BP4_LSB			0x5b
+#define THS8200_DTG2_BP5_LSB			0x5c
+#define THS8200_DTG2_BP6_LSB			0x5d
+#define THS8200_DTG2_BP7_LSB			0x5e
+#define THS8200_DTG2_BP8_LSB			0x5f
+#define THS8200_DTG2_BP9_LSB			0x60
+#define THS8200_DTG2_BP10_LSB			0x61
+#define THS8200_DTG2_BP11_LSB			0x62
+#define THS8200_DTG2_BP12_LSB			0x63
+#define THS8200_DTG2_BP13_LSB			0x64
+#define THS8200_DTG2_BP14_LSB			0x65
+#define THS8200_DTG2_BP15_LSB			0x66
+#define THS8200_DTG2_BP16_LSB			0x67
+#define THS8200_DTG2_LINETYPE1			0x68
+#define THS8200_DTG2_LINETYPE2			0x69
+#define THS8200_DTG2_LINETYPE3			0x6a
+#define THS8200_DTG2_LINETYPE4			0x6b
+#define THS8200_DTG2_LINETYPE5			0x6c
+#define THS8200_DTG2_LINETYPE6			0x6d
+#define THS8200_DTG2_LINETYPE7			0x6e
+#define THS8200_DTG2_LINETYPE8			0x6f
+#define THS8200_DTG2_HLENGTH_LSB		0x70
+#define THS8200_DTG2_HLENGTH_LSB_HDLY_MSB	0x71
+#define THS8200_DTG2_HLENGTH_HDLY_LSB		0x72
+#define THS8200_DTG2_VLENGTH1_LSB		0x73
+#define THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB	0x74
+#define THS8200_DTG2_VDLY1_LSB			0x75
+#define THS8200_DTG2_VLENGTH2_LSB		0x76
+#define THS8200_DTG2_VLENGTH2_MSB_VDLY2_MSB	0x77
+#define THS8200_DTG2_VDLY2_LSB			0x78
+#define THS8200_DTG2_HS_IN_DLY_MSB		0x79
+#define THS8200_DTG2_HS_IN_DLY_LSB		0x7a
+#define THS8200_DTG2_VS_IN_DLY_MSB		0x7b
+#define THS8200_DTG2_VS_IN_DLY_LSB		0x7c
+#define THS8200_DTG2_PIXEL_CNT_MSB		0x7d
+#define THS8200_DTG2_PIXEL_CNT_LSB		0x7e
+#define THS8200_DTG2_LINE_CNT_MSB		0x7f
+#define THS8200_DTG2_LINE_CNT_LSB		0x80
+#define THS8200_DTG2_CNTL			0x82
+#define THS8200_CGMS_CNTL_HEADER		0x83
+#define THS8200_CGMS_PAYLOAD_MSB		0x84
+#define THS8200_CGMS_PAYLOAD_LSB		0x85
+#define THS8200_MISC_PPL_LSB			0x86
+#define THS8200_MISC_PPL_MSB			0x87
+#define THS8200_MISC_LPF_MSB			0x88
+#define THS8200_MISC_LPF_LSB			0x89
+
+#endif /* THS8200_REGS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tlv320aic23b.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tlv320aic23b.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tlv320aic23b.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tlv320aic23b.c	2013-08-25 20:43:22.000000000 -0400
@@ -162,7 +162,7 @@ static int tlv320aic23b_probe(struct i2c
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -191,7 +191,6 @@ static int tlv320aic23b_probe(struct i2c
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&state->hdl);
@@ -205,7 +204,6 @@ static int tlv320aic23b_remove(struct i2
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tvaudio.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tvaudio.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tvaudio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tvaudio.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,6 @@
 
 #include <media/tvaudio.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #include <media/i2c-addr.h>
@@ -1838,13 +1837,6 @@ static int tvaudio_s_frequency(struct v4
 	return 0;
 }
 
-static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVAUDIO, 0);
-}
-
 static int tvaudio_log_status(struct v4l2_subdev *sd)
 {
 	struct CHIPSTATE *chip = to_state(sd);
@@ -1863,7 +1855,6 @@ static const struct v4l2_ctrl_ops tvaudi
 
 static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
 	.log_status = tvaudio_log_status,
-	.g_chip_ident = tvaudio_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -1910,7 +1901,7 @@ static int tvaudio_probe(struct i2c_clie
 		printk("\n");
 	}
 
-	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
 	sd = &chip->sd;
@@ -1930,7 +1921,6 @@ static int tvaudio_probe(struct i2c_clie
 	}
 	if (desc->name == NULL) {
 		v4l2_dbg(1, debug, sd, "no matching chip description found\n");
-		kfree(chip);
 		return -EIO;
 	}
 	v4l2_info(sd, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name);
@@ -2001,7 +1991,6 @@ static int tvaudio_probe(struct i2c_clie
 		int err = chip->hdl.error;
 
 		v4l2_ctrl_handler_free(&chip->hdl);
-		kfree(chip);
 		return err;
 	}
 	/* set controls to the default values */
@@ -2020,7 +2009,8 @@ static int tvaudio_probe(struct i2c_clie
 		/* start async thread */
 		chip->wt.function = chip_thread_wake;
 		chip->wt.data     = (unsigned long)chip;
-		chip->thread = kthread_run(chip_thread, chip, client->name);
+		chip->thread = kthread_run(chip_thread, chip, "%s",
+					   client->name);
 		if (IS_ERR(chip->thread)) {
 			v4l2_warn(sd, "failed to create kthread\n");
 			chip->thread = NULL;
@@ -2043,7 +2033,6 @@ static int tvaudio_remove(struct i2c_cli
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&chip->hdl);
-	kfree(chip);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tvp514x.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tvp514x.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tvp514x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tvp514x.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-mediabus.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-of.h>
 #include <media/v4l2-ctrls.h>
 #include <media/tvp514x.h>
 #include <media/media-entity.h>
@@ -123,6 +123,8 @@ struct tvp514x_decoder {
 	/* mc related members */
 	struct media_pad pad;
 	struct v4l2_mbus_framefmt format;
+
+	struct tvp514x_reg *int_seq;
 };
 
 /* TVP514x default register values */
@@ -543,8 +545,6 @@ static int tvp514x_querystd(struct v4l2_
 	if (std_id == NULL)
 		return -EINVAL;
 
-	*std_id = V4L2_STD_UNKNOWN;
-
 	/* To query the standard the TVP514x must power on the ADCs. */
 	if (!decoder->streaming) {
 		tvp514x_s_stream(sd, 1);
@@ -553,8 +553,10 @@ static int tvp514x_querystd(struct v4l2_
 
 	/* query the current standard */
 	current_std = tvp514x_query_current_std(sd);
-	if (current_std == STD_INVALID)
+	if (current_std == STD_INVALID) {
+		*std_id = V4L2_STD_UNKNOWN;
 		return 0;
+	}
 
 	input_sel = decoder->input;
 
@@ -595,10 +597,12 @@ static int tvp514x_querystd(struct v4l2_
 	}
 	/* check whether signal is locked */
 	sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1);
-	if (lock_mask != (sync_lock_status & lock_mask))
+	if (lock_mask != (sync_lock_status & lock_mask)) {
+		*std_id = V4L2_STD_UNKNOWN;
 		return 0;	/* No input detected */
+	}
 
-	*std_id = decoder->std_list[current_std].standard.id;
+	*std_id &= decoder->std_list[current_std].standard.id;
 
 	v4l2_dbg(1, debug, sd, "Current STD: %s\n",
 			decoder->std_list[current_std].standard.name);
@@ -862,7 +866,6 @@ tvp514x_s_parm(struct v4l2_subdev *sd, s
 static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
 {
 	int err = 0;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct tvp514x_decoder *decoder = to_decoder(sd);
 
 	if (decoder->streaming == enable)
@@ -882,11 +885,8 @@ static int tvp514x_s_stream(struct v4l2_
 	}
 	case 1:
 	{
-		struct tvp514x_reg *int_seq = (struct tvp514x_reg *)
-				client->driver->id_table->driver_data;
-
 		/* Power Up Sequence */
-		err = tvp514x_write_regs(sd, int_seq);
+		err = tvp514x_write_regs(sd, decoder->int_seq);
 		if (err) {
 			v4l2_err(sd, "Unable to turn on decoder\n");
 			return err;
@@ -1055,6 +1055,42 @@ static struct tvp514x_decoder tvp514x_de
 
 };
 
+static struct tvp514x_platform_data *
+tvp514x_get_pdata(struct i2c_client *client)
+{
+	struct tvp514x_platform_data *pdata;
+	struct v4l2_of_endpoint bus_cfg;
+	struct device_node *endpoint;
+	unsigned int flags;
+
+	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
+		return client->dev.platform_data;
+
+	endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	if (!endpoint)
+		return NULL;
+
+	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		goto done;
+
+	v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+	flags = bus_cfg.bus.parallel.flags;
+
+	if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+		pdata->hs_polarity = 1;
+
+	if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+		pdata->vs_polarity = 1;
+
+	if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+		pdata->clk_polarity = 1;
+
+done:
+	of_node_put(endpoint);
+	return pdata;
+}
+
 /**
  * tvp514x_probe() - decoder driver i2c probe handler
  * @client: i2c driver client device structure
@@ -1066,19 +1102,20 @@ static struct tvp514x_decoder tvp514x_de
 static int
 tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
+	struct tvp514x_platform_data *pdata = tvp514x_get_pdata(client);
 	struct tvp514x_decoder *decoder;
 	struct v4l2_subdev *sd;
 	int ret;
 
+	if (pdata == NULL) {
+		dev_err(&client->dev, "No platform data\n");
+		return -EINVAL;
+	}
+
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 
-	if (!client->dev.platform_data) {
-		v4l2_err(client, "No platform data!!\n");
-		return -ENODEV;
-	}
-
 	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (!decoder)
 		return -ENOMEM;
@@ -1089,8 +1126,10 @@ tvp514x_probe(struct i2c_client *client,
 	memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
 			sizeof(tvp514x_reg_list_default));
 
+	decoder->int_seq = (struct tvp514x_reg *)id->driver_data;
+
 	/* Copy board specific information here */
-	decoder->pdata = client->dev.platform_data;
+	decoder->pdata = pdata;
 
 	/**
 	 * Fetch platform specific data, and configure the
@@ -1109,7 +1148,6 @@ tvp514x_probe(struct i2c_client *client,
 	/* Register with V4L2 layer as slave device */
 	sd = &decoder->sd;
 	v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
-	strlcpy(sd->name, TVP514X_MODULE_NAME, sizeof(sd->name));
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	decoder->pad.flags = MEDIA_PAD_FL_SOURCE;
@@ -1120,7 +1158,6 @@ tvp514x_probe(struct i2c_client *client,
 	if (ret < 0) {
 		v4l2_err(sd, "%s decoder driver failed to register !!\n",
 			 sd->name);
-		kfree(decoder);
 		return ret;
 	}
 #endif
@@ -1231,8 +1268,20 @@ static const struct i2c_device_id tvp514
 
 MODULE_DEVICE_TABLE(i2c, tvp514x_id);
 
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id tvp514x_of_match[] = {
+	{ .compatible = "ti,tvp5146", },
+	{ .compatible = "ti,tvp5146m2", },
+	{ .compatible = "ti,tvp5147", },
+	{ .compatible = "ti,tvp5147m1", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, tvp514x_of_match);
+#endif
+
 static struct i2c_driver tvp514x_driver = {
 	.driver = {
+		.of_match_table = of_match_ptr(tvp514x_of_match),
 		.owner = THIS_MODULE,
 		.name = TVP514X_MODULE_NAME,
 	},
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tvp5150.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tvp5150.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tvp5150.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tvp5150.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <media/v4l2-device.h>
 #include <media/tvp5150.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #include "tvp5150_reg.h"
@@ -727,13 +726,11 @@ static int tvp5150_set_std(struct v4l2_s
 
 	/* First tests should be against specific std */
 
-	if (std == V4L2_STD_ALL) {
-		fmt = VIDEO_STD_AUTO_SWITCH_BIT;	/* Autodetect mode */
-	} else if (std & V4L2_STD_NTSC_443) {
+	if (std == V4L2_STD_NTSC_443) {
 		fmt = VIDEO_STD_NTSC_4_43_BIT;
-	} else if (std & V4L2_STD_PAL_M) {
+	} else if (std == V4L2_STD_PAL_M) {
 		fmt = VIDEO_STD_PAL_M_BIT;
-	} else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
+	} else if (std == V4L2_STD_PAL_N || std == V4L2_STD_PAL_Nc) {
 		fmt = VIDEO_STD_PAL_COMBINATION_N_BIT;
 	} else {
 		/* Then, test against generic ones */
@@ -1031,31 +1028,11 @@ static int tvp5150_g_sliced_fmt(struct v
 	return 0;
 }
 
-static int tvp5150_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	int rev;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	rev = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER) << 8 |
-	      tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP5150,
-					  rev);
-}
-
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
 	int res;
 
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	res = tvp5150_read(sd, reg->reg & 0xff);
 	if (res < 0) {
 		v4l2_err(sd, "%s: failed with error = %d\n", __func__, res);
@@ -1069,12 +1046,6 @@ static int tvp5150_g_register(struct v4l
 
 static int tvp5150_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	tvp5150_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
@@ -1098,7 +1069,6 @@ static const struct v4l2_subdev_core_ops
 	.log_status = tvp5150_log_status,
 	.s_std = tvp5150_s_std,
 	.reset = tvp5150_reset,
-	.g_chip_ident = tvp5150_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = tvp5150_g_register,
 	.s_register = tvp5150_s_register,
@@ -1152,10 +1122,9 @@ static int tvp5150_probe(struct i2c_clie
 	     I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
 		return -EIO;
 
-	core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL);
-	if (!core) {
+	core = devm_kzalloc(&c->dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
 		return -ENOMEM;
-	}
 	sd = &core->sd;
 	v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
 
@@ -1166,7 +1135,7 @@ static int tvp5150_probe(struct i2c_clie
 	for (i = 0; i < 4; i++) {
 		res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i);
 		if (res < 0)
-			goto free_core;
+			return res;
 		tvp5150_id[i] = res;
 	}
 
@@ -1209,7 +1178,7 @@ static int tvp5150_probe(struct i2c_clie
 	if (core->hdl.error) {
 		res = core->hdl.error;
 		v4l2_ctrl_handler_free(&core->hdl);
-		goto free_core;
+		return res;
 	}
 	v4l2_ctrl_handler_setup(&core->hdl);
 
@@ -1225,10 +1194,6 @@ static int tvp5150_probe(struct i2c_clie
 	if (debug > 1)
 		tvp5150_log_status(sd);
 	return 0;
-
-free_core:
-	kfree(core);
-	return res;
 }
 
 static int tvp5150_remove(struct i2c_client *c)
@@ -1242,7 +1207,6 @@ static int tvp5150_remove(struct i2c_cli
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&decoder->hdl);
-	kfree(to_tvp5150(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tvp7002.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tvp7002.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tvp7002.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tvp7002.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/v4l2-dv-timings.h>
 #include <media/tvp7002.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 #include "tvp7002_reg.h"
@@ -41,9 +40,6 @@ MODULE_DESCRIPTION("TI TVP7002 Video and
 MODULE_AUTHOR("Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>");
 MODULE_LICENSE("GPL");
 
-/* Module Name */
-#define TVP7002_MODULE_NAME	"tvp7002"
-
 /* I2C retry attempts */
 #define I2C_RETRY_COUNT		(5)
 
@@ -424,6 +420,7 @@ struct tvp7002 {
 	int streaming;
 
 	const struct tvp7002_timings_definition *current_timings;
+	struct media_pad pad;
 };
 
 /*
@@ -535,29 +532,6 @@ static inline void tvp7002_write_err(str
 }
 
 /*
- * tvp7002_g_chip_ident() - Get chip identification number
- * @sd: ptr to v4l2_subdev struct
- * @chip: ptr to v4l2_dbg_chip_ident struct
- *
- * Obtains the chip's identification number.
- * Returns zero or -EINVAL if read operation fails.
- */
-static int tvp7002_g_chip_ident(struct v4l2_subdev *sd,
-					struct v4l2_dbg_chip_ident *chip)
-{
-	u8 rev;
-	int error;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	error = tvp7002_read(sd, TVP7002_CHIP_REV, &rev);
-
-	if (error < 0)
-		return error;
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP7002, rev);
-}
-
-/*
  * tvp7002_write_inittab() - Write initialization values
  * @sd: ptr to v4l2_subdev struct
  * @regs: ptr to i2c_reg_value struct
@@ -738,23 +712,17 @@ static int tvp7002_query_dv_timings(stru
  *
  * Get the value of a TVP7002 decoder device register.
  * Returns zero when successful, -EINVAL if register read fails or
- * access to I2C client fails, -EPERM if the call is not allowed
- * by disabled CAP_SYS_ADMIN.
+ * access to I2C client fails.
  */
 static int tvp7002_g_register(struct v4l2_subdev *sd,
 						struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	u8 val;
 	int ret;
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	ret = tvp7002_read(sd, reg->reg & 0xff, &val);
 	reg->val = val;
+	reg->size = 1;
 	return ret;
 }
 
@@ -764,19 +732,11 @@ static int tvp7002_g_register(struct v4l
  * @reg: ptr to v4l2_dbg_register struct
  *
  * Get the value of a TVP7002 decoder device register.
- * Returns zero when successful, -EINVAL if register read fails or
- * -EPERM if call not allowed.
+ * Returns zero when successful, -EINVAL if register read fails.
  */
 static int tvp7002_s_register(struct v4l2_subdev *sd,
 						const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	return tvp7002_write(sd, reg->reg & 0xff, reg->val & 0xff);
 }
 #endif
@@ -880,9 +840,67 @@ static const struct v4l2_ctrl_ops tvp700
 	.s_ctrl = tvp7002_s_ctrl,
 };
 
+/*
+ * tvp7002_enum_mbus_code() - Enum supported digital video format on pad
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @fh: file handle for the subdev
+ * @code: pointer to subdev enum mbus code struct
+ *
+ * Enumerate supported digital video formats for pad.
+ */
+static int
+tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_mbus_code_enum *code)
+{
+	/* Check requested format index is within range */
+	if (code->index != 0)
+		return -EINVAL;
+
+	code->code = V4L2_MBUS_FMT_YUYV10_1X20;
+
+	return 0;
+}
+
+/*
+ * tvp7002_get_pad_format() - get video format on pad
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @fh: file handle for the subdev
+ * @fmt: pointer to subdev format struct
+ *
+ * get video format for pad.
+ */
+static int
+tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_format *fmt)
+{
+	struct tvp7002 *tvp7002 = to_tvp7002(sd);
+
+	fmt->format.code = V4L2_MBUS_FMT_YUYV10_1X20;
+	fmt->format.width = tvp7002->current_timings->timings.bt.width;
+	fmt->format.height = tvp7002->current_timings->timings.bt.height;
+	fmt->format.field = tvp7002->current_timings->scanmode;
+	fmt->format.colorspace = tvp7002->current_timings->color_space;
+
+	return 0;
+}
+
+/*
+ * tvp7002_set_pad_format() - set video format on pad
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @fh: file handle for the subdev
+ * @fmt: pointer to subdev format struct
+ *
+ * set video format for pad.
+ */
+static int
+tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_format *fmt)
+{
+	return tvp7002_get_pad_format(sd, fh, fmt);
+}
+
 /* V4L2 core operation handlers */
 static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
-	.g_chip_ident = tvp7002_g_chip_ident,
 	.log_status = tvp7002_log_status,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
@@ -910,10 +928,18 @@ static const struct v4l2_subdev_video_op
 	.enum_mbus_fmt = tvp7002_enum_mbus_fmt,
 };
 
+/* media pad related operation handlers */
+static const struct v4l2_subdev_pad_ops tvp7002_pad_ops = {
+	.enum_mbus_code = tvp7002_enum_mbus_code,
+	.get_fmt = tvp7002_get_pad_format,
+	.set_fmt = tvp7002_set_pad_format,
+};
+
 /* V4L2 top level operation handlers */
 static const struct v4l2_subdev_ops tvp7002_ops = {
 	.core = &tvp7002_core_ops,
 	.video = &tvp7002_video_ops,
+	.pad = &tvp7002_pad_ops,
 };
 
 /*
@@ -993,19 +1019,34 @@ static int tvp7002_probe(struct i2c_clie
 	timings = device->current_timings->timings;
 	error = tvp7002_s_dv_timings(sd, &timings);
 
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	device->pad.flags = MEDIA_PAD_FL_SOURCE;
+	device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
+
+	error = media_entity_init(&device->sd.entity, 1, &device->pad, 0);
+	if (error < 0)
+		return error;
+#endif
+
 	v4l2_ctrl_handler_init(&device->hdl, 1);
 	v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops,
 			V4L2_CID_GAIN, 0, 255, 1, 0);
 	sd->ctrl_handler = &device->hdl;
 	if (device->hdl.error) {
-		int err = device->hdl.error;
-
-		v4l2_ctrl_handler_free(&device->hdl);
-		return err;
+		error = device->hdl.error;
+		goto error;
 	}
 	v4l2_ctrl_handler_setup(&device->hdl);
 
 	return 0;
+
+error:
+	v4l2_ctrl_handler_free(&device->hdl);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&device->sd.entity);
+#endif
+	return error;
 }
 
 /*
@@ -1022,7 +1063,9 @@ static int tvp7002_remove(struct i2c_cli
 
 	v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter"
 				"on address 0x%x\n", c->addr);
-
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&device->sd.entity);
+#endif
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&device->hdl);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tw2804.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tw2804.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tw2804.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tw2804.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/slab.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #define TW2804_REG_AUTOGAIN		0x02
@@ -368,8 +367,7 @@ static int tw2804_probe(struct i2c_clien
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	state = kzalloc(sizeof(struct tw2804), GFP_KERNEL);
-
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -410,7 +408,6 @@ static int tw2804_probe(struct i2c_clien
 	err = state->hdl.error;
 	if (err) {
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 
@@ -427,7 +424,6 @@ static int tw2804_remove(struct i2c_clie
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tw9903.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tw9903.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tw9903.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tw9903.c	2013-08-25 20:43:22.000000000 -0400
@@ -215,7 +215,7 @@ static int tw9903_probe(struct i2c_clien
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	dec = kzalloc(sizeof(struct tw9903), GFP_KERNEL);
+	dec = devm_kzalloc(&client->dev, sizeof(*dec), GFP_KERNEL);
 	if (dec == NULL)
 		return -ENOMEM;
 	sd = &dec->sd;
@@ -233,7 +233,6 @@ static int tw9903_probe(struct i2c_clien
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(dec);
 		return err;
 	}
 
@@ -242,7 +241,6 @@ static int tw9903_probe(struct i2c_clien
 
 	if (write_regs(sd, initial_registers) < 0) {
 		v4l2_err(client, "error initializing TW9903\n");
-		kfree(dec);
 		return -EINVAL;
 	}
 
@@ -255,7 +253,6 @@ static int tw9903_remove(struct i2c_clie
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&to_state(sd)->hdl);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/tw9906.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/tw9906.c
--- linux-libre-3.10-gnu/drivers/media/i2c/tw9906.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/tw9906.c	2013-08-25 20:43:22.000000000 -0400
@@ -183,7 +183,7 @@ static int tw9906_probe(struct i2c_clien
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	dec = kzalloc(sizeof(struct tw9906), GFP_KERNEL);
+	dec = devm_kzalloc(&client->dev, sizeof(*dec), GFP_KERNEL);
 	if (dec == NULL)
 		return -ENOMEM;
 	sd = &dec->sd;
@@ -201,7 +201,6 @@ static int tw9906_probe(struct i2c_clien
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(dec);
 		return err;
 	}
 
@@ -210,7 +209,6 @@ static int tw9906_probe(struct i2c_clien
 
 	if (write_regs(sd, initial_registers) < 0) {
 		v4l2_err(client, "error initializing TW9906\n");
-		kfree(dec);
 		return -EINVAL;
 	}
 
@@ -223,7 +221,6 @@ static int tw9906_remove(struct i2c_clie
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&to_state(sd)->hdl);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/uda1342.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/uda1342.c
--- linux-libre-3.10-gnu/drivers/media/i2c/uda1342.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/uda1342.c	2013-08-25 20:43:22.000000000 -0400
@@ -69,7 +69,7 @@ static int uda1342_probe(struct i2c_clie
 	dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n",
 		client->addr, adapter->name);
 
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 
@@ -89,7 +89,6 @@ static int uda1342_remove(struct i2c_cli
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/upd64031a.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/upd64031a.c
--- linux-libre-3.10-gnu/drivers/media/i2c/upd64031a.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/upd64031a.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/upd64031a.h>
 
 /* --------------------- read registers functions define -------------------- */
@@ -147,13 +146,6 @@ static int upd64031a_s_routing(struct v4
 	return upd64031a_s_frequency(sd, NULL);
 }
 
-static int upd64031a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64031A, 0);
-}
-
 static int upd64031a_log_status(struct v4l2_subdev *sd)
 {
 	v4l2_info(sd, "Status: SA00=0x%02x SA01=0x%02x\n",
@@ -164,12 +156,6 @@ static int upd64031a_log_status(struct v
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = upd64031a_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -177,12 +163,6 @@ static int upd64031a_g_register(struct v
 
 static int upd64031a_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	upd64031a_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
@@ -192,7 +172,6 @@ static int upd64031a_s_register(struct v
 
 static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
 	.log_status = upd64031a_log_status,
-	.g_chip_ident = upd64031a_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = upd64031a_g_register,
 	.s_register = upd64031a_s_register,
@@ -230,7 +209,7 @@ static int upd64031a_probe(struct i2c_cl
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct upd64031a_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -249,7 +228,6 @@ static int upd64031a_remove(struct i2c_c
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/upd64083.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/upd64083.c
--- linux-libre-3.10-gnu/drivers/media/i2c/upd64083.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/upd64083.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/upd64083.h>
 
 MODULE_DESCRIPTION("uPD64083 driver");
@@ -122,12 +121,6 @@ static int upd64083_s_routing(struct v4l
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int upd64083_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = upd64083_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -135,24 +128,11 @@ static int upd64083_g_register(struct v4
 
 static int upd64083_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	upd64083_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int upd64083_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64083, 0);
-}
-
 static int upd64083_log_status(struct v4l2_subdev *sd)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -169,7 +149,6 @@ static int upd64083_log_status(struct v4
 
 static const struct v4l2_subdev_core_ops upd64083_core_ops = {
 	.log_status = upd64083_log_status,
-	.g_chip_ident = upd64083_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = upd64083_g_register,
 	.s_register = upd64083_s_register,
@@ -202,7 +181,7 @@ static int upd64083_probe(struct i2c_cli
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct upd64083_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -221,7 +200,6 @@ static int upd64083_remove(struct i2c_cl
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/vp27smpx.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/vp27smpx.c
--- linux-libre-3.10-gnu/drivers/media/i2c/vp27smpx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/vp27smpx.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("vp27smpx driver");
 MODULE_AUTHOR("Hans Verkuil");
@@ -112,13 +111,6 @@ static int vp27smpx_g_tuner(struct v4l2_
 	return 0;
 }
 
-static int vp27smpx_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VP27SMPX, 0);
-}
-
 static int vp27smpx_log_status(struct v4l2_subdev *sd)
 {
 	struct vp27smpx_state *state = to_state(sd);
@@ -132,7 +124,6 @@ static int vp27smpx_log_status(struct v4
 
 static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
 	.log_status = vp27smpx_log_status,
-	.g_chip_ident = vp27smpx_g_chip_ident,
 	.s_std = vp27smpx_s_std,
 };
 
@@ -169,7 +160,7 @@ static int vp27smpx_probe(struct i2c_cli
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -186,7 +177,6 @@ static int vp27smpx_remove(struct i2c_cl
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/vpx3220.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/vpx3220.c
--- linux-libre-3.10-gnu/drivers/media/i2c/vpx3220.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/vpx3220.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
@@ -49,7 +48,6 @@ struct vpx3220 {
 	unsigned char reg[255];
 
 	v4l2_std_id norm;
-	int ident;
 	int input;
 	int enable;
 };
@@ -297,7 +295,7 @@ static int vpx3220_init(struct v4l2_subd
 static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
 {
 	int res = V4L2_IN_ST_NO_SIGNAL, status;
-	v4l2_std_id std = 0;
+	v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
 
 	status = vpx3220_fp_read(sd, 0x0f3);
 
@@ -314,19 +312,21 @@ static int vpx3220_status(struct v4l2_su
 		case 0x10:
 		case 0x14:
 		case 0x18:
-			std = V4L2_STD_PAL;
+			std &= V4L2_STD_PAL;
 			break;
 
 		case 0x08:
-			std = V4L2_STD_SECAM;
+			std &= V4L2_STD_SECAM;
 			break;
 
 		case 0x04:
 		case 0x0c:
 		case 0x1c:
-			std = V4L2_STD_NTSC;
+			std &= V4L2_STD_NTSC;
 			break;
 		}
+	} else {
+		std = V4L2_STD_UNKNOWN;
 	}
 	if (pstd)
 		*pstd = std;
@@ -442,14 +442,6 @@ static int vpx3220_s_ctrl(struct v4l2_ct
 	return -EINVAL;
 }
 
-static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct vpx3220 *decoder = to_vpx3220(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_ctrl_ops vpx3220_ctrl_ops = {
@@ -457,7 +449,6 @@ static const struct v4l2_ctrl_ops vpx322
 };
 
 static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
-	.g_chip_ident = vpx3220_g_chip_ident,
 	.init = vpx3220_init,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
@@ -499,7 +490,7 @@ static int vpx3220_probe(struct i2c_clie
 		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
 		return -ENODEV;
 
-	decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (decoder == NULL)
 		return -ENOMEM;
 	sd = &decoder->sd;
@@ -521,7 +512,6 @@ static int vpx3220_probe(struct i2c_clie
 		int err = decoder->hdl.error;
 
 		v4l2_ctrl_handler_free(&decoder->hdl);
-		kfree(decoder);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&decoder->hdl);
@@ -529,7 +519,6 @@ static int vpx3220_probe(struct i2c_clie
 	ver = i2c_smbus_read_byte_data(client, 0x00);
 	pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
 		i2c_smbus_read_byte_data(client, 0x01);
-	decoder->ident = V4L2_IDENT_VPX3220A;
 	if (ver == 0xec) {
 		switch (pn) {
 		case 0x4680:
@@ -537,11 +526,9 @@ static int vpx3220_probe(struct i2c_clie
 			break;
 		case 0x4260:
 			name = "vpx3216b";
-			decoder->ident = V4L2_IDENT_VPX3216B;
 			break;
 		case 0x4280:
 			name = "vpx3214c";
-			decoder->ident = V4L2_IDENT_VPX3214C;
 			break;
 		}
 	}
@@ -566,7 +553,7 @@ static int vpx3220_remove(struct i2c_cli
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&decoder->hdl);
-	kfree(decoder);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/vs6624.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/vs6624.c
--- linux-libre-3.10-gnu/drivers/media/i2c/vs6624.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/vs6624.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/types.h>
 #include <linux/videodev2.h>
 
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-mediabus.h>
@@ -722,27 +721,9 @@ static int vs6624_s_stream(struct v4l2_s
 	return 0;
 }
 
-static int vs6624_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	int rev;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	rev = (vs6624_read(sd, VS6624_FW_VSN_MAJOR) << 8)
-		| vs6624_read(sd, VS6624_FW_VSN_MINOR);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VS6624, rev);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int vs6624_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = vs6624_read(sd, reg->reg & 0xffff);
 	reg->size = 1;
 	return 0;
@@ -750,12 +731,6 @@ static int vs6624_g_register(struct v4l2
 
 static int vs6624_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	vs6624_write(sd, reg->reg & 0xffff, reg->val & 0xff);
 	return 0;
 }
@@ -766,7 +741,6 @@ static const struct v4l2_ctrl_ops vs6624
 };
 
 static const struct v4l2_subdev_core_ops vs6624_core_ops = {
-	.g_chip_ident = vs6624_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = vs6624_g_register,
 	.s_register = vs6624_s_register,
@@ -805,20 +779,18 @@ static int vs6624_probe(struct i2c_clien
 	if (ce == NULL)
 		return -EINVAL;
 
-	ret = gpio_request(*ce, "VS6624 Chip Enable");
+	ret = devm_gpio_request_one(&client->dev, *ce, GPIOF_OUT_INIT_HIGH,
+				    "VS6624 Chip Enable");
 	if (ret) {
 		v4l_err(client, "failed to request GPIO %d\n", *ce);
 		return ret;
 	}
-	gpio_direction_output(*ce, 1);
 	/* wait 100ms before any further i2c writes are performed */
 	mdelay(100);
 
-	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
-	if (sensor == NULL) {
-		gpio_free(*ce);
+	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
+	if (sensor == NULL)
 		return -ENOMEM;
-	}
 
 	sd = &sensor->sd;
 	v4l2_i2c_subdev_init(sd, client, &vs6624_ops);
@@ -866,30 +838,22 @@ static int vs6624_probe(struct i2c_clien
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(sensor);
-		gpio_free(*ce);
 		return err;
 	}
 
 	/* initialize the hardware to the default control values */
 	ret = v4l2_ctrl_handler_setup(hdl);
-	if (ret) {
+	if (ret)
 		v4l2_ctrl_handler_free(hdl);
-		kfree(sensor);
-		gpio_free(*ce);
-	}
 	return ret;
 }
 
 static int vs6624_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct vs6624 *sensor = to_vs6624(sd);
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	gpio_free(sensor->ce_pin);
-	kfree(sensor);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/wm8739.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/wm8739.c
--- linux-libre-3.10-gnu/drivers/media/i2c/wm8739.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/wm8739.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("wm8739 driver");
@@ -160,13 +159,6 @@ static int wm8739_s_clock_freq(struct v4
 	return 0;
 }
 
-static int wm8739_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8739, 0);
-}
-
 static int wm8739_log_status(struct v4l2_subdev *sd)
 {
 	struct wm8739_state *state = to_state(sd);
@@ -184,7 +176,6 @@ static const struct v4l2_ctrl_ops wm8739
 
 static const struct v4l2_subdev_core_ops wm8739_core_ops = {
 	.log_status = wm8739_log_status,
-	.g_chip_ident = wm8739_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -220,7 +211,7 @@ static int wm8739_probe(struct i2c_clien
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct wm8739_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -237,7 +228,6 @@ static int wm8739_probe(struct i2c_clien
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	v4l2_ctrl_cluster(3, &state->volume);
@@ -271,7 +261,6 @@ static int wm8739_remove(struct i2c_clie
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/i2c/wm8775.c linux-libre-3.11-rc7-gnu/drivers/media/i2c/wm8775.c
--- linux-libre-3.10-gnu/drivers/media/i2c/wm8775.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/i2c/wm8775.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,7 +33,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/wm8775.h>
 
@@ -158,13 +157,6 @@ static int wm8775_s_ctrl(struct v4l2_ctr
 	return -EINVAL;
 }
 
-static int wm8775_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8775, 0);
-}
-
 static int wm8775_log_status(struct v4l2_subdev *sd)
 {
 	struct wm8775_state *state = to_state(sd);
@@ -188,7 +180,6 @@ static const struct v4l2_ctrl_ops wm8775
 
 static const struct v4l2_subdev_core_ops wm8775_core_ops = {
 	.log_status = wm8775_log_status,
-	.g_chip_ident = wm8775_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -241,7 +232,7 @@ static int wm8775_probe(struct i2c_clien
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct wm8775_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -261,7 +252,6 @@ static int wm8775_probe(struct i2c_clien
 	err = state->hdl.error;
 	if (err) {
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 
@@ -319,7 +309,6 @@ static int wm8775_remove(struct i2c_clie
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/media-device.c linux-libre-3.11-rc7-gnu/drivers/media/media-device.c
--- linux-libre-3.10-gnu/drivers/media/media-device.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/media-device.c	2013-08-25 20:43:22.000000000 -0400
@@ -142,6 +142,8 @@ static long __media_device_enum_links(st
 
 		for (p = 0; p < entity->num_pads; p++) {
 			struct media_pad_desc pad;
+
+			memset(&pad, 0, sizeof(pad));
 			media_device_kpad_to_upad(&entity->pads[p], &pad);
 			if (copy_to_user(&links->pads[p], &pad, sizeof(pad)))
 				return -EFAULT;
@@ -159,6 +161,7 @@ static long __media_device_enum_links(st
 			if (entity->links[l].source->entity != entity)
 				continue;
 
+			memset(&link, 0, sizeof(link));
 			media_device_kpad_to_upad(entity->links[l].source,
 						  &link.source);
 			media_device_kpad_to_upad(entity->links[l].sink,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/media-entity.c linux-libre-3.11-rc7-gnu/drivers/media/media-entity.c
--- linux-libre-3.10-gnu/drivers/media/media-entity.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/media-entity.c	2013-08-25 20:43:22.000000000 -0400
@@ -429,6 +429,56 @@ media_entity_create_link(struct media_en
 }
 EXPORT_SYMBOL_GPL(media_entity_create_link);
 
+void __media_entity_remove_links(struct media_entity *entity)
+{
+	unsigned int i;
+
+	for (i = 0; i < entity->num_links; i++) {
+		struct media_link *link = &entity->links[i];
+		struct media_entity *remote;
+		unsigned int r = 0;
+
+		if (link->source->entity == entity)
+			remote = link->sink->entity;
+		else
+			remote = link->source->entity;
+
+		while (r < remote->num_links) {
+			struct media_link *rlink = &remote->links[r];
+
+			if (rlink != link->reverse) {
+				r++;
+				continue;
+			}
+
+			if (link->source->entity == entity)
+				remote->num_backlinks--;
+
+			if (--remote->num_links == 0)
+				break;
+
+			/* Insert last entry in place of the dropped link. */
+			*rlink = remote->links[remote->num_links];
+		}
+	}
+
+	entity->num_links = 0;
+	entity->num_backlinks = 0;
+}
+EXPORT_SYMBOL_GPL(__media_entity_remove_links);
+
+void media_entity_remove_links(struct media_entity *entity)
+{
+	/* Do nothing if the entity is not registered. */
+	if (entity->parent == NULL)
+		return;
+
+	mutex_lock(&entity->parent->graph_mutex);
+	__media_entity_remove_links(entity);
+	mutex_unlock(&entity->parent->graph_mutex);
+}
+EXPORT_SYMBOL_GPL(media_entity_remove_links);
+
 static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
 {
 	int ret;
@@ -496,25 +546,17 @@ int __media_entity_setup_link(struct med
 
 	mdev = source->parent;
 
-	if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) {
-		ret = mdev->link_notify(link->source, link->sink,
-					MEDIA_LNK_FL_ENABLED);
+	if (mdev->link_notify) {
+		ret = mdev->link_notify(link, flags,
+					MEDIA_DEV_NOTIFY_PRE_LINK_CH);
 		if (ret < 0)
 			return ret;
 	}
 
 	ret = __media_entity_setup_link_notify(link, flags);
-	if (ret < 0)
-		goto err;
-
-	if (!(flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
-		mdev->link_notify(link->source, link->sink, 0);
 
-	return 0;
-
-err:
-	if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
-		mdev->link_notify(link->source, link->sink, 0);
+	if (mdev->link_notify)
+		mdev->link_notify(link, flags, MEDIA_DEV_NOTIFY_POST_LINK_CH);
 
 	return ret;
 }
@@ -560,17 +602,16 @@ media_entity_find_link(struct media_pad
 EXPORT_SYMBOL_GPL(media_entity_find_link);
 
 /**
- * media_entity_remote_source - Find the source pad at the remote end of a link
- * @pad: Sink pad at the local end of the link
+ * media_entity_remote_pad - Find the pad at the remote end of a link
+ * @pad: Pad at the local end of the link
  *
- * Search for a remote source pad connected to the given sink pad by iterating
- * over all links originating or terminating at that pad until an enabled link
- * is found.
+ * Search for a remote pad connected to the given pad by iterating over all
+ * links originating or terminating at that pad until an enabled link is found.
  *
  * Return a pointer to the pad at the remote end of the first found enabled
  * link, or NULL if no enabled link has been found.
  */
-struct media_pad *media_entity_remote_source(struct media_pad *pad)
+struct media_pad *media_entity_remote_pad(struct media_pad *pad)
 {
 	unsigned int i;
 
@@ -590,4 +631,4 @@ struct media_pad *media_entity_remote_so
 	return NULL;
 
 }
-EXPORT_SYMBOL_GPL(media_entity_remote_source);
+EXPORT_SYMBOL_GPL(media_entity_remote_pad);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/parport/bw-qcam.c linux-libre-3.11-rc7-gnu/drivers/media/parport/bw-qcam.c
--- linux-libre-3.10-gnu/drivers/media/parport/bw-qcam.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/parport/bw-qcam.c	2013-08-25 20:43:22.000000000 -0400
@@ -687,6 +687,7 @@ static int buffer_finish(struct vb2_buff
 
 	parport_release(qcam->pdev);
 	mutex_unlock(&qcam->lock);
+	v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
 	if (len != size)
 		vb->state = VB2_BUF_STATE_ERROR;
 	vb2_set_plane_payload(vb, 0, len);
@@ -964,6 +965,7 @@ static struct qcam *qcam_init(struct par
 	q->drv_priv = qcam;
 	q->ops = &qcam_video_qops;
 	q->mem_ops = &vb2_vmalloc_memops;
+	q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 	err = vb2_queue_init(q);
 	if (err < 0) {
 		v4l2_err(v4l2_dev, "couldn't init vb2_queue for %s.\n", port->name);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/b2c2/flexcop-pci.c linux-libre-3.11-rc7-gnu/drivers/media/pci/b2c2/flexcop-pci.c
--- linux-libre-3.10-gnu/drivers/media/pci/b2c2/flexcop-pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/b2c2/flexcop-pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -432,18 +432,7 @@ static struct pci_driver flexcop_pci_dri
 	.remove   = flexcop_pci_remove,
 };
 
-static int __init flexcop_pci_module_init(void)
-{
-	return pci_register_driver(&flexcop_pci_driver);
-}
-
-static void __exit flexcop_pci_module_exit(void)
-{
-	pci_unregister_driver(&flexcop_pci_driver);
-}
-
-module_init(flexcop_pci_module_init);
-module_exit(flexcop_pci_module_exit);
+module_pci_driver(flexcop_pci_driver);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_NAME);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/bt8xx/bttv-cards.c linux-libre-3.11-rc7-gnu/drivers/media/pci/bt8xx/bttv-cards.c
--- linux-libre-3.10-gnu/drivers/media/pci/bt8xx/bttv-cards.c	2013-07-01 10:34:45.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/bt8xx/bttv-cards.c	2013-08-31 17:54:16.000000000 -0400
@@ -131,7 +131,7 @@ MODULE_PARM_DESC(vsfx,"set VSFX pci conf
 		 "[yet another chipset flaw workaround]");
 MODULE_PARM_DESC(latency,"pci latency timer");
 MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
-MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
+MODULE_PARM_DESC(pll, "specify installed crystal (0=none, 28=28 MHz, 35=35 MHz, 14=14 MHz)");
 MODULE_PARM_DESC(tuner,"specify installed tuner type");
 MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore");
 MODULE_PARM_DESC(audiodev, "specify audio device:\n"
@@ -2705,7 +2705,7 @@ struct tvcard bttv_tvcards[] = {
 		.has_radio      = 1,
 		.has_remote     = 1,
 	},
-		[BTTV_BOARD_VD012] = {
+	[BTTV_BOARD_VD012] = {
 		/* D.Heer@Phytec.de */
 		.name           = "PHYTEC VD-012 (bt878)",
 		.video_inputs   = 4,
@@ -2718,7 +2718,7 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
-		[BTTV_BOARD_VD012_X1] = {
+	[BTTV_BOARD_VD012_X1] = {
 		/* D.Heer@Phytec.de */
 		.name           = "PHYTEC VD-012-X1 (bt878)",
 		.video_inputs   = 4,
@@ -2731,7 +2731,7 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
-		[BTTV_BOARD_VD012_X2] = {
+	[BTTV_BOARD_VD012_X2] = {
 		/* D.Heer@Phytec.de */
 		.name           = "PHYTEC VD-012-X2 (bt878)",
 		.video_inputs   = 4,
@@ -2744,7 +2744,7 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
-		[BTTV_BOARD_GEOVISION_GV800S] = {
+	[BTTV_BOARD_GEOVISION_GV800S] = {
 		/* Bruno Christo <bchristo@inf.ufsm.br>
 		 *
 		 * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
@@ -2771,7 +2771,7 @@ struct tvcard bttv_tvcards[] = {
 		.no_tda7432	= 1,
 		.muxsel_hook    = gv800s_muxsel,
 	},
-		[BTTV_BOARD_GEOVISION_GV800S_SL] = {
+	[BTTV_BOARD_GEOVISION_GV800S_SL] = {
 		/* Bruno Christo <bchristo@inf.ufsm.br>
 		 *
 		 * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
@@ -2808,6 +2808,7 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
+	/* ---- card 0xa0---------------------------------- */
 	[BTTV_BOARD_TVT_TD3116] = {
 		.name           = "Tongwei Video Technology TD-3116",
 		.video_inputs   = 16,
@@ -2825,6 +2826,35 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.tuner_type     = TUNER_ABSENT,
 	},
+	[BTTV_BOARD_ADLINK_MPG24] = {
+		/* Adlink MPG24 */
+		.name           = "Adlink MPG24",
+		.video_inputs   = 1,
+		/* .audio_inputs= 1, */
+		.svhs           = NO_SVHS,
+		.muxsel         = MUXSEL(2, 2, 2, 2),
+		.tuner_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.pll            = PLL_28,
+	},
+	[BTTV_BOARD_BT848_CAP_14] = {
+		.name		= "Bt848 Capture 14MHz",
+		.video_inputs	= 4,
+		.svhs		= 2,
+		.muxsel		= MUXSEL(2, 3, 1, 0),
+		.pll		= PLL_14,
+		.tuner_type	= TUNER_ABSENT,
+	},
+	[BTTV_BOARD_CYBERVISION_CV06] = {
+		.name		= "CyberVision CV06 (SV)",
+		.video_inputs	= 4,
+		/* .audio_inputs= 0, */
+		.svhs		= NO_SVHS,
+		.muxsel		= MUXSEL(2, 3, 1, 0),
+		.pll		= PLL_28,
+		.tuner_type	= TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
+	},
 
 };
 
@@ -3390,6 +3420,10 @@ void bttv_init_card2(struct bttv *btv)
 			btv->pll.pll_ifreq=35468950;
 			btv->pll.pll_crystal=BT848_IFORM_XT1;
 		}
+		if (PLL_14 == bttv_tvcards[btv->c.type].pll) {
+			btv->pll.pll_ifreq = 14318181;
+			btv->pll.pll_crystal = BT848_IFORM_XT0;
+		}
 		/* insmod options can override */
 		switch (pll[btv->c.nr]) {
 		case 0: /* none */
@@ -3409,6 +3443,12 @@ void bttv_init_card2(struct bttv *btv)
 			btv->pll.pll_ofreq   = 0;
 			btv->pll.pll_crystal = BT848_IFORM_XT1;
 			break;
+		case 3: /* 14 MHz */
+		case 14:
+			btv->pll.pll_ifreq   = 14318181;
+			btv->pll.pll_ofreq   = 0;
+			btv->pll.pll_crystal = BT848_IFORM_XT0;
+			break;
 		}
 	}
 	btv->pll.pll_current = -1;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/bt8xx/bttv-driver.c linux-libre-3.11-rc7-gnu/drivers/media/pci/bt8xx/bttv-driver.c
--- linux-libre-3.10-gnu/drivers/media/pci/bt8xx/bttv-driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/bt8xx/bttv-driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,7 +50,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/tvaudio.h>
 #include <media/msp3400.h>
 
@@ -1761,9 +1760,9 @@ static int bttv_querystd(struct file *fi
 	struct bttv *btv = fh->btv;
 
 	if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML)
-		*id = V4L2_STD_625_50;
+		*id &= V4L2_STD_625_50;
 	else
-		*id = V4L2_STD_525_60;
+		*id &= V4L2_STD_525_60;
 	return 0;
 }
 
@@ -1907,28 +1906,6 @@ static int bttv_log_status(struct file *
 	return 0;
 }
 
-static int bttv_g_chip_ident(struct file *file, void *f, struct v4l2_dbg_chip_ident *chip)
-{
-	struct bttv_fh *fh  = f;
-	struct bttv *btv = fh->btv;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
-		if (v4l2_chip_match_host(&chip->match)) {
-			chip->ident = btv->id;
-			if (chip->ident == PCI_DEVICE_ID_FUSION879)
-				chip->ident = V4L2_IDENT_BT879;
-		}
-		return 0;
-	}
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-	/* TODO: is this correct? */
-	return bttv_call_all_err(btv, core, g_chip_ident, chip);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int bttv_g_register(struct file *file, void *f,
 					struct v4l2_dbg_register *reg)
@@ -1936,16 +1913,6 @@ static int bttv_g_register(struct file *
 	struct bttv_fh *fh = f;
 	struct bttv *btv = fh->btv;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (!v4l2_chip_match_host(&reg->match)) {
-		/* TODO: subdev errors should not be ignored, this should become a
-		   subdev helper function. */
-		bttv_call_all(btv, core, g_register, reg);
-		return 0;
-	}
-
 	/* bt848 has a 12-bit register space */
 	reg->reg &= 0xfff;
 	reg->val = btread(reg->reg);
@@ -1960,16 +1927,6 @@ static int bttv_s_register(struct file *
 	struct bttv_fh *fh = f;
 	struct bttv *btv = fh->btv;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (!v4l2_chip_match_host(&reg->match)) {
-		/* TODO: subdev errors should not be ignored, this should become a
-		   subdev helper function. */
-		bttv_call_all(btv, core, s_register, reg);
-		return 0;
-	}
-
 	/* bt848 has a 12-bit register space */
 	btwrite(reg->val, reg->reg & 0xfff);
 
@@ -3209,7 +3166,6 @@ static const struct v4l2_ioctl_ops bttv_
 	.vidioc_querystd		= bttv_querystd,
 	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident		= bttv_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register		= bttv_g_register,
 	.vidioc_s_register		= bttv_s_register,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/bt8xx/bttv.h linux-libre-3.11-rc7-gnu/drivers/media/pci/bt8xx/bttv.h
--- linux-libre-3.10-gnu/drivers/media/pci/bt8xx/bttv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/bt8xx/bttv.h	2013-08-25 20:43:22.000000000 -0400
@@ -185,6 +185,9 @@
 #define BTTV_BOARD_PV183                   0x9f
 #define BTTV_BOARD_TVT_TD3116		   0xa0
 #define BTTV_BOARD_APOSONIC_WDVR           0xa1
+#define BTTV_BOARD_ADLINK_MPG24            0xa2
+#define BTTV_BOARD_BT848_CAP_14            0xa3
+#define BTTV_BOARD_CYBERVISION_CV06        0xa4
 
 /* more card-specific defines */
 #define PT2254_L_CHANNEL 0x10
@@ -232,6 +235,7 @@ struct tvcard {
 #define PLL_NONE 0
 #define PLL_28   1
 #define PLL_35   2
+#define PLL_14   3
 
 	/* i2c audio flags */
 	unsigned int no_msp34xx:1;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx18/cx18-av-core.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx18/cx18-av-core.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx18/cx18-av-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx18/cx18-av-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@
  *  02110-1301, USA.
  */
 
-#include <media/v4l2-chip-ident.h>
 #include "cx18-driver.h"
 #include "cx18-io.h"
 #include "cx18-cards.h"
@@ -1231,35 +1230,14 @@ static int cx18_av_log_status(struct v4l
 	return 0;
 }
 
-static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
-{
-	return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1;
-}
-
-static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct cx18_av_state *state = to_cx18_av_state(sd);
-
-	if (cx18_av_dbg_match(&chip->match)) {
-		chip->ident = state->id;
-		chip->revision = state->rev;
-	}
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cx18_av_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
 	struct cx18 *cx = v4l2_get_subdevdata(sd);
 
-	if (!cx18_av_dbg_match(&reg->match))
-		return -EINVAL;
 	if ((reg->reg & 0x3) != 0)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 4;
 	reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
 	return 0;
@@ -1270,12 +1248,8 @@ static int cx18_av_s_register(struct v4l
 {
 	struct cx18 *cx = v4l2_get_subdevdata(sd);
 
-	if (!cx18_av_dbg_match(&reg->match))
-		return -EINVAL;
 	if ((reg->reg & 0x3) != 0)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
 	return 0;
 }
@@ -1286,17 +1260,9 @@ static const struct v4l2_ctrl_ops cx18_a
 };
 
 static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
-	.g_chip_ident = cx18_av_g_chip_ident,
 	.log_status = cx18_av_log_status,
 	.load_fw = cx18_av_load_fw,
 	.reset = cx18_av_reset,
-	.g_ctrl = v4l2_subdev_g_ctrl,
-	.s_ctrl = v4l2_subdev_s_ctrl,
-	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
-	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
-	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
-	.queryctrl = v4l2_subdev_queryctrl,
-	.querymenu = v4l2_subdev_querymenu,
 	.s_std = cx18_av_s_std,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = cx18_av_g_register,
@@ -1344,8 +1310,6 @@ int cx18_av_probe(struct cx18 *cx)
 	int err;
 
 	state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
-	state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
-		    ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
 
 	state->vid_input = CX18_AV_COMPOSITE7;
 	state->aud_input = CX18_AV_AUDIO8;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx18/cx18-av-core.h linux-libre-3.11-rc7-gnu/drivers/media/pci/cx18/cx18-av-core.h
--- linux-libre-3.10-gnu/drivers/media/pci/cx18/cx18-av-core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx18/cx18-av-core.h	2013-08-25 20:43:22.000000000 -0400
@@ -104,7 +104,6 @@ struct cx18_av_state {
 	enum cx18_av_audio_input aud_input;
 	u32 audclk_freq;
 	int audmode;
-	u32 id;
 	u32 rev;
 	int is_initialized;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx18/cx18-driver.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx18/cx18-driver.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx18/cx18-driver.c	2013-07-01 10:35:02.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx18/cx18-driver.c	2013-08-31 17:54:33.000000000 -0400
@@ -695,7 +695,7 @@ static int cx18_create_in_workq(struct c
 {
 	snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in",
 		 cx->v4l2_dev.name);
-	cx->in_work_queue = alloc_ordered_workqueue(cx->in_workq_name, 0);
+	cx->in_work_queue = alloc_ordered_workqueue("%s", 0, cx->in_workq_name);
 	if (cx->in_work_queue == NULL) {
 		CX18_ERR("Unable to create incoming mailbox handler thread\n");
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx18/cx18-ioctl.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx18/cx18-ioctl.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx18/cx18-ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx18/cx18-ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,6 @@
 #include "cx18-cards.h"
 #include "cx18-av-core.h"
 #include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
 
 u16 cx18_service2vbi(int type)
 {
@@ -362,73 +361,18 @@ static int cx18_s_fmt_sliced_vbi_cap(str
 	return 0;
 }
 
-static int cx18_g_chip_ident(struct file *file, void *fh,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct cx18 *cx = fh2id(fh)->cx;
-	int err = 0;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	switch (chip->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		switch (chip->match.addr) {
-		case 0:
-			chip->ident = V4L2_IDENT_CX23418;
-			chip->revision = cx18_read_reg(cx, 0xC72028);
-			break;
-		case 1:
-			/*
-			 * The A/V decoder is always present, but in the rare
-			 * case that the card doesn't have analog, we don't
-			 * use it.  We find it w/o using the cx->sd_av pointer
-			 */
-			cx18_call_hw(cx, CX18_HW_418_AV,
-				     core, g_chip_ident, chip);
-			break;
-		default:
-			/*
-			 * Could return ident = V4L2_IDENT_UNKNOWN if we had
-			 * other host chips at higher addresses, but we don't
-			 */
-			err = -EINVAL; /* per V4L2 spec */
-			break;
-		}
-		break;
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
-		cx18_call_all(cx, core, g_chip_ident, chip);
-		break;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/*
-		 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
-		 * to look if a chip is at the address with no driver.  That's a
-		 * dangerous thing to do with EEPROMs anyway.
-		 */
-		cx18_call_all(cx, core, g_chip_ident, chip);
-		break;
-	default:
-		err = -EINVAL;
-		break;
-	}
-	return err;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cx18_g_register(struct file *file, void *fh,
 				struct v4l2_dbg_register *reg)
 {
 	struct cx18 *cx = fh2id(fh)->cx;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
-			return -EINVAL;
-		reg->size = 4;
-		reg->val = cx18_read_enc(cx, reg->reg);
-		return 0;
-	}
-	/* FIXME - errors shouldn't be ignored */
-	cx18_call_all(cx, core, g_register, reg);
+	if (reg->reg & 0x3)
+		return -EINVAL;
+	if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
+		return -EINVAL;
+	reg->size = 4;
+	reg->val = cx18_read_enc(cx, reg->reg);
 	return 0;
 }
 
@@ -437,14 +381,11 @@ static int cx18_s_register(struct file *
 {
 	struct cx18 *cx = fh2id(fh)->cx;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
-			return -EINVAL;
-		cx18_write_enc(cx, reg->val, reg->reg);
-		return 0;
-	}
-	/* FIXME - errors shouldn't be ignored */
-	cx18_call_all(cx, core, s_register, reg);
+	if (reg->reg & 0x3)
+		return -EINVAL;
+	if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
+		return -EINVAL;
+	cx18_write_enc(cx, reg->val, reg->reg);
 	return 0;
 }
 #endif
@@ -1162,7 +1103,6 @@ static const struct v4l2_ioctl_ops cx18_
 	.vidioc_try_fmt_vbi_cap         = cx18_try_fmt_vbi_cap,
 	.vidioc_try_fmt_sliced_vbi_cap  = cx18_try_fmt_sliced_vbi_cap,
 	.vidioc_g_sliced_vbi_cap        = cx18_g_sliced_vbi_cap,
-	.vidioc_g_chip_ident            = cx18_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register              = cx18_g_register,
 	.vidioc_s_register              = cx18_s_register,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23885-417.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23885-417.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23885-417.c	2013-07-01 10:35:07.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23885-417.c	2013-08-31 17:54:38.000000000 -0400
@@ -1217,8 +1217,7 @@ static int vidioc_g_std(struct file *fil
 	struct cx23885_fh  *fh  = file->private_data;
 	struct cx23885_dev *dev = fh->dev;
 
-	call_all(dev, core, g_std, id);
-
+	*id = dev->tvnorm;
 	return 0;
 }
 
@@ -1661,7 +1660,6 @@ static struct v4l2_file_operations mpeg_
 };
 
 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
-	.vidioc_querystd	 = vidioc_g_std,
 	.vidioc_g_std		 = vidioc_g_std,
 	.vidioc_s_std		 = vidioc_s_std,
 	.vidioc_enum_input	 = vidioc_enum_input,
@@ -1690,8 +1688,8 @@ static const struct v4l2_ioctl_ops mpeg_
 	.vidioc_log_status	 = vidioc_log_status,
 	.vidioc_querymenu	 = vidioc_querymenu,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
-	.vidioc_g_chip_ident	 = cx23885_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info	 = cx23885_g_chip_info,
 	.vidioc_g_register	 = cx23885_g_register,
 	.vidioc_s_register	 = cx23885_s_register,
 #endif
@@ -1702,7 +1700,6 @@ static struct video_device cx23885_mpeg_
 	.fops          = &mpeg_fops,
 	.ioctl_ops     = &mpeg_ioctl_ops,
 	.tvnorms       = CX23885_NORMS,
-	.current_norm  = V4L2_STD_NTSC_M,
 };
 
 void cx23885_417_unregister(struct cx23885_dev *dev)
@@ -1735,7 +1732,7 @@ static struct video_device *cx23885_vide
 	*vfd = *template;
 	snprintf(vfd->name, sizeof(vfd->name), "%s (%s)",
 		cx23885_boards[tsport->dev->board].name, type);
-	vfd->parent  = &pci->dev;
+	vfd->v4l2_dev = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	return vfd;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23885-ioctl.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23885-ioctl.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23885-ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23885-ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,93 +24,21 @@
 #include "cx23885.h"
 #include "cx23885-ioctl.h"
 
-#include <media/v4l2-chip-ident.h>
-
-int cx23885_g_chip_ident(struct file *file, void *fh,
-			 struct v4l2_dbg_chip_ident *chip)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+int cx23885_g_chip_info(struct file *file, void *fh,
+			 struct v4l2_dbg_chip_info *chip)
 {
 	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
-	int err = 0;
-	u8 rev;
 
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	switch (chip->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		switch (chip->match.addr) {
-		case 0:
-			rev = cx_read(RDR_CFG2) & 0xff;
-			switch (dev->pci->device) {
-			case 0x8852:
-				/* rev 0x04 could be '885 or '888. Pick '888. */
-				if (rev == 0x04)
-					chip->ident = V4L2_IDENT_CX23888;
-				else
-					chip->ident = V4L2_IDENT_CX23885;
-				break;
-			case 0x8880:
-				if (rev == 0x0e || rev == 0x0f)
-					chip->ident = V4L2_IDENT_CX23887;
-				else
-					chip->ident = V4L2_IDENT_CX23888;
-				break;
-			default:
-				chip->ident = V4L2_IDENT_UNKNOWN;
-				break;
-			}
-			chip->revision = (dev->pci->device << 16) | (rev << 8) |
-					 (dev->hwrevision & 0xff);
-			break;
-		case 1:
-			if (dev->v4l_device != NULL) {
-				chip->ident = V4L2_IDENT_CX23417;
-				chip->revision = 0;
-			}
-			break;
-		case 2:
-			/*
-			 * The integrated IR controller on the CX23888 is
-			 * host chip 2.  It may not be used/initialized or sd_ir
-			 * may be pointing at the cx25840 subdevice for the
-			 * IR controller on the CX23885.  Thus we find it
-			 * without using the dev->sd_ir pointer.
-			 */
-			call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident,
-				chip);
-			break;
-		default:
-			err = -EINVAL; /* per V4L2 spec */
-			break;
-		}
-		break;
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
-		call_all(dev, core, g_chip_ident, chip);
-		break;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/*
-		 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
-		 * to look if a chip is at the address with no driver.  That's a
-		 * dangerous thing to do with EEPROMs anyway.
-		 */
-		call_all(dev, core, g_chip_ident, chip);
-		break;
-	default:
-		err = -EINVAL;
-		break;
-	}
-	return err;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx23885_g_host_register(struct cx23885_dev *dev,
-				   struct v4l2_dbg_register *reg)
-{
-	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
+	if (chip->match.addr > 1)
 		return -EINVAL;
-
-	reg->size = 4;
-	reg->val = cx_read(reg->reg);
+	if (chip->match.addr == 1) {
+		if (dev->v4l_device == NULL)
+			return -EINVAL;
+		strlcpy(chip->name, "cx23417", sizeof(chip->name));
+	} else {
+		strlcpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name));
+	}
 	return 0;
 }
 
@@ -138,32 +66,16 @@ int cx23885_g_register(struct file *file
 {
 	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
-		switch (reg->match.addr) {
-		case 0:
-			return cx23885_g_host_register(dev, reg);
-		case 1:
-			return cx23417_g_register(dev, reg);
-		default:
-			break;
-		}
-	}
-
-	/* FIXME - any error returns should not be ignored */
-	call_all(dev, core, g_register, reg);
-	return 0;
-}
+	if (reg->match.addr > 1)
+		return -EINVAL;
+	if (reg->match.addr)
+		return cx23417_g_register(dev, reg);
 
-static int cx23885_s_host_register(struct cx23885_dev *dev,
-				   const struct v4l2_dbg_register *reg)
-{
 	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
 		return -EINVAL;
 
-	cx_write(reg->reg, reg->val);
+	reg->size = 4;
+	reg->val = cx_read(reg->reg);
 	return 0;
 }
 
@@ -186,22 +98,15 @@ int cx23885_s_register(struct file *file
 {
 	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
+	if (reg->match.addr > 1)
+		return -EINVAL;
+	if (reg->match.addr)
+		return cx23417_s_register(dev, reg);
 
-	if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
-		switch (reg->match.addr) {
-		case 0:
-			return cx23885_s_host_register(dev, reg);
-		case 1:
-			return cx23417_s_register(dev, reg);
-		default:
-			break;
-		}
-	}
+	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
+		return -EINVAL;
 
-	/* FIXME - any error returns should not be ignored */
-	call_all(dev, core, s_register, reg);
+	cx_write(reg->reg, reg->val);
 	return 0;
 }
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23885-ioctl.h linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23885-ioctl.h
--- linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23885-ioctl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23885-ioctl.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,8 +24,8 @@
 #ifndef _CX23885_IOCTL_H_
 #define _CX23885_IOCTL_H_
 
-int cx23885_g_chip_ident(struct file *file, void *fh,
-			 struct v4l2_dbg_chip_ident *chip);
+int cx23885_g_chip_info(struct file *file, void *fh,
+			 struct v4l2_dbg_chip_info *chip);
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 int cx23885_g_register(struct file *file, void *fh,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23885-video.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23885-video.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23885-video.c	2013-07-01 10:35:13.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23885-video.c	2013-08-31 17:54:44.000000000 -0400
@@ -1254,8 +1254,7 @@ static int vidioc_g_std(struct file *fil
 	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
 	dprintk(1, "%s()\n", __func__);
 
-	call_all(dev, core, g_std, id);
-
+	*id = dev->tvnorm;
 	return 0;
 }
 
@@ -1743,7 +1742,6 @@ static const struct v4l2_ioctl_ops video
 	.vidioc_dqbuf         = vidioc_dqbuf,
 	.vidioc_s_std         = vidioc_s_std,
 	.vidioc_g_std         = vidioc_g_std,
-	.vidioc_querystd      = vidioc_g_std,
 	.vidioc_enum_input    = vidioc_enum_input,
 	.vidioc_g_input       = vidioc_g_input,
 	.vidioc_s_input       = vidioc_s_input,
@@ -1757,8 +1755,8 @@ static const struct v4l2_ioctl_ops video
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.vidioc_g_frequency   = vidioc_g_frequency,
 	.vidioc_s_frequency   = vidioc_s_frequency,
-	.vidioc_g_chip_ident  = cx23885_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info   = cx23885_g_chip_info,
 	.vidioc_g_register    = cx23885_g_register,
 	.vidioc_s_register    = cx23885_s_register,
 #endif
@@ -1773,7 +1771,6 @@ static struct video_device cx23885_video
 	.fops                 = &video_fops,
 	.ioctl_ops 	      = &video_ioctl_ops,
 	.tvnorms              = CX23885_NORMS,
-	.current_norm         = V4L2_STD_NTSC_M,
 };
 
 static const struct v4l2_file_operations radio_fops = {
@@ -1822,7 +1819,7 @@ int cx23885_video_register(struct cx2388
 	cx23885_vbi_template = cx23885_video_template;
 	strcpy(cx23885_vbi_template.name, "cx23885-vbi");
 
-	dev->tvnorm = cx23885_video_template.current_norm;
+	dev->tvnorm = V4L2_STD_NTSC_M;
 
 	/* init video dma queues */
 	INIT_LIST_HEAD(&dev->vidq.active);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23888-ir.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23888-ir.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx23885/cx23888-ir.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx23885/cx23888-ir.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/slab.h>
 
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/rc-core.h>
 
 #include "cx23885.h"
@@ -131,8 +130,6 @@ union cx23888_ir_fifo_rec {
 struct cx23888_ir_state {
 	struct v4l2_subdev sd;
 	struct cx23885_dev *dev;
-	u32 id;
-	u32 rev;
 
 	struct v4l2_subdev_ir_parameters rx_params;
 	struct mutex rx_params_lock;
@@ -1086,23 +1083,6 @@ static int cx23888_ir_log_status(struct
 	return 0;
 }
 
-static inline int cx23888_ir_dbg_match(const struct v4l2_dbg_match *match)
-{
-	return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 2;
-}
-
-static int cx23888_ir_g_chip_ident(struct v4l2_subdev *sd,
-				   struct v4l2_dbg_chip_ident *chip)
-{
-	struct cx23888_ir_state *state = to_state(sd);
-
-	if (cx23888_ir_dbg_match(&chip->match)) {
-		chip->ident = state->id;
-		chip->revision = state->rev;
-	}
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cx23888_ir_g_register(struct v4l2_subdev *sd,
 				 struct v4l2_dbg_register *reg)
@@ -1110,14 +1090,10 @@ static int cx23888_ir_g_register(struct
 	struct cx23888_ir_state *state = to_state(sd);
 	u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
 
-	if (!cx23888_ir_dbg_match(&reg->match))
-		return -EINVAL;
 	if ((addr & 0x3) != 0)
 		return -EINVAL;
 	if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 4;
 	reg->val = cx23888_ir_read4(state->dev, addr);
 	return 0;
@@ -1129,21 +1105,16 @@ static int cx23888_ir_s_register(struct
 	struct cx23888_ir_state *state = to_state(sd);
 	u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
 
-	if (!cx23888_ir_dbg_match(&reg->match))
-		return -EINVAL;
 	if ((addr & 0x3) != 0)
 		return -EINVAL;
 	if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	cx23888_ir_write4(state->dev, addr, reg->val);
 	return 0;
 }
 #endif
 
 static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = {
-	.g_chip_ident = cx23888_ir_g_chip_ident,
 	.log_status = cx23888_ir_log_status,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = cx23888_ir_g_register,
@@ -1217,8 +1188,6 @@ int cx23888_ir_probe(struct cx23885_dev
 		return -ENOMEM;
 
 	state->dev = dev;
-	state->id = V4L2_IDENT_CX23888_IR;
-	state->rev = 0;
 	sd = &state->sd;
 
 	v4l2_subdev_init(sd, &cx23888_ir_controller_ops);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx88/cx88-cards.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx88/cx88-cards.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx88/cx88-cards.c	2013-07-01 10:32:41.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx88/cx88-cards.c	2013-08-31 17:52:10.000000000 -0400
@@ -744,7 +744,7 @@ static const struct cx88_board cx88_boar
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		/* Some variants use a tda9874 and so need the tvaudio module. */
-		.audio_chip     = V4L2_IDENT_TVAUDIO,
+		.audio_chip     = CX88_AUDIO_TVAUDIO,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -976,7 +976,7 @@ static const struct cx88_board cx88_boar
 		.radio_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.audio_chip	= V4L2_IDENT_WM8775,
+		.audio_chip	= CX88_AUDIO_WM8775,
 		.i2sinputcntl   = 2,
 		.input		= {{
 			.type	= CX88_VMUX_DVB,
@@ -1014,7 +1014,7 @@ static const struct cx88_board cx88_boar
 		.radio_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.audio_chip = V4L2_IDENT_WM8775,
+		.audio_chip = CX88_AUDIO_WM8775,
 		.input		= {{
 			.type	= CX88_VMUX_DVB,
 			.vmux	= 0,
@@ -1376,7 +1376,7 @@ static const struct cx88_board cx88_boar
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-		.audio_chip     = V4L2_IDENT_WM8775,
+		.audio_chip     = CX88_AUDIO_WM8775,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -1461,7 +1461,7 @@ static const struct cx88_board cx88_boar
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-		.audio_chip     = V4L2_IDENT_WM8775,
+		.audio_chip     = CX88_AUDIO_WM8775,
 		/*
 		 * gpio0 as reported by Mike Crash <mike AT mikecrash.com>
 		 */
@@ -1929,7 +1929,7 @@ static const struct cx88_board cx88_boar
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-		.audio_chip     = V4L2_IDENT_WM8775,
+		.audio_chip     = CX88_AUDIO_WM8775,
 		/*
 		 * GPIO0 (WINTV2000)
 		 *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx88/cx88-core.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx88/cx88-core.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx88/cx88-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx88/cx88-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -1034,7 +1034,14 @@ struct video_device *cx88_vdev_init(stru
 	if (NULL == vfd)
 		return NULL;
 	*vfd = *template_;
+	/*
+	 * The dev pointer of v4l2_device is NULL, instead we set the
+	 * video_device dev_parent pointer to the correct PCI bus device.
+	 * This driver is a rare example where there is one v4l2_device,
+	 * but the video nodes have different parent (PCI) devices.
+	 */
 	vfd->v4l2_dev = &core->v4l2_dev;
+	vfd->dev_parent = &pci->dev;
 	vfd->release = video_device_release;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 		 core->name, type, core->board.name);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx88/cx88.h linux-libre-3.11-rc7-gnu/drivers/media/pci/cx88/cx88.h
--- linux-libre-3.10-gnu/drivers/media/pci/cx88/cx88.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx88/cx88.h	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,6 @@
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/cx2341x.h>
 #include <media/videobuf-dvb.h>
 #include <media/ir-kbd-i2c.h>
@@ -259,6 +258,11 @@ struct cx88_input {
 	unsigned int    audioroute:4;
 };
 
+enum cx88_audio_chip {
+	CX88_AUDIO_WM8775,
+	CX88_AUDIO_TVAUDIO,
+};
+
 struct cx88_board {
 	const char              *name;
 	unsigned int            tuner_type;
@@ -269,7 +273,7 @@ struct cx88_board {
 	struct cx88_input       input[MAX_CX88_INPUT];
 	struct cx88_input       radio;
 	enum cx88_board_type    mpeg;
-	unsigned int            audio_chip;
+	enum cx88_audio_chip	audio_chip;
 	int			num_frontends;
 
 	/* Used for I2S devices */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/cx88/cx88-video.c linux-libre-3.11-rc7-gnu/drivers/media/pci/cx88/cx88-video.c
--- linux-libre-3.10-gnu/drivers/media/pci/cx88/cx88-video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/cx88/cx88-video.c	2013-08-25 20:43:22.000000000 -0400
@@ -1353,26 +1353,14 @@ static int vidioc_s_frequency (struct fi
 	return cx88_set_freq(core, f);
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	if (!v4l2_chip_match_host(&chip->match))
-		return -EINVAL;
-	chip->revision = 0;
-	chip->ident = V4L2_IDENT_UNKNOWN;
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int vidioc_g_register (struct file *file, void *fh,
 				struct v4l2_dbg_register *reg)
 {
 	struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
 	/* cx2388x has a 24-bit register space */
-	reg->val = cx_read(reg->reg & 0xffffff);
+	reg->val = cx_read(reg->reg & 0xfffffc);
 	reg->size = 4;
 	return 0;
 }
@@ -1382,9 +1370,7 @@ static int vidioc_s_register (struct fil
 {
 	struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-	cx_write(reg->reg & 0xffffff, reg->val);
+	cx_write(reg->reg & 0xfffffc, reg->val);
 	return 0;
 }
 #endif
@@ -1578,7 +1564,6 @@ static const struct v4l2_ioctl_ops video
 	.vidioc_s_frequency   = vidioc_s_frequency,
 	.vidioc_subscribe_event      = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event    = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident  = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
@@ -1612,7 +1597,6 @@ static const struct v4l2_ioctl_ops vbi_i
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.vidioc_g_frequency   = vidioc_g_frequency,
 	.vidioc_s_frequency   = vidioc_s_frequency,
-	.vidioc_g_chip_ident  = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
@@ -1643,7 +1627,6 @@ static const struct v4l2_ioctl_ops radio
 	.vidioc_s_frequency   = vidioc_s_frequency,
 	.vidioc_subscribe_event      = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event    = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident  = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
@@ -1794,7 +1777,7 @@ static int cx8800_initdev(struct pci_dev
 
 	/* load and configure helper modules */
 
-	if (core->board.audio_chip == V4L2_IDENT_WM8775) {
+	if (core->board.audio_chip == CX88_AUDIO_WM8775) {
 		struct i2c_board_info wm8775_info = {
 			.type = "wm8775",
 			.addr = 0x36 >> 1,
@@ -1815,7 +1798,7 @@ static int cx8800_initdev(struct pci_dev
 		}
 	}
 
-	if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
+	if (core->board.audio_chip == CX88_AUDIO_TVAUDIO) {
 		/* This probes for a tda9874 as is used on some
 		   Pixelview Ultra boards. */
 		v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/dm1105/dm1105.c linux-libre-3.11-rc7-gnu/drivers/media/pci/dm1105/dm1105.c
--- linux-libre-3.10-gnu/drivers/media/pci/dm1105/dm1105.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/dm1105/dm1105.c	2013-08-25 20:43:22.000000000 -0400
@@ -1241,18 +1241,7 @@ static struct pci_driver dm1105_driver =
 	.remove = dm1105_remove,
 };
 
-static int __init dm1105_init(void)
-{
-	return pci_register_driver(&dm1105_driver);
-}
-
-static void __exit dm1105_exit(void)
-{
-	pci_unregister_driver(&dm1105_driver);
-}
-
-module_init(dm1105_init);
-module_exit(dm1105_exit);
+module_pci_driver(dm1105_driver);
 
 MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
 MODULE_DESCRIPTION("SDMC DM1105 DVB driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/ivtv/ivtv-driver.c linux-libre-3.11-rc7-gnu/drivers/media/pci/ivtv/ivtv-driver.c
--- linux-libre-3.10-gnu/drivers/media/pci/ivtv/ivtv-driver.c	2013-07-01 10:32:41.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/ivtv/ivtv-driver.c	2013-08-31 17:52:10.000000000 -0400
@@ -58,7 +58,6 @@
 #include <linux/dma-mapping.h>
 #include <media/tveeprom.h>
 #include <media/saa7115.h>
-#include <media/v4l2-chip-ident.h>
 #include "tuner-xc2028.h"
 
 /* If you have already X v4l cards, then set this to X. This way
@@ -753,7 +752,7 @@ static int ivtv_init_struct1(struct ivtv
 
 	init_kthread_worker(&itv->irq_worker);
 	itv->irq_worker_task = kthread_run(kthread_worker_fn, &itv->irq_worker,
-					   itv->v4l2_dev.name);
+					   "%s", itv->v4l2_dev.name);
 	if (IS_ERR(itv->irq_worker_task)) {
 		IVTV_ERR("Could not create ivtv task\n");
 		return -1;
@@ -968,15 +967,10 @@ static void ivtv_load_and_init_modules(s
 	}
 
 	if (hw & IVTV_HW_SAA711X) {
-		struct v4l2_dbg_chip_ident v;
-
 		/* determine the exact saa711x model */
 		itv->hw_flags &= ~IVTV_HW_SAA711X;
 
-		v.match.type = V4L2_CHIP_MATCH_I2C_DRIVER;
-		strlcpy(v.match.name, "saa7115", sizeof(v.match.name));
-		ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v);
-		if (v.ident == V4L2_IDENT_SAA7114) {
+		if (strstr(itv->sd_video->name, "saa7114")) {
 			itv->hw_flags |= IVTV_HW_SAA7114;
 			/* VBI is not yet supported by the saa7114 driver. */
 			itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/ivtv/ivtv-ioctl.c linux-libre-3.11-rc7-gnu/drivers/media/pci/ivtv/ivtv-ioctl.c
--- linux-libre-3.10-gnu/drivers/media/pci/ivtv/ivtv-ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/ivtv/ivtv-ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,7 +34,6 @@
 #include "ivtv-cards.h"
 #include <media/saa7127.h>
 #include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-event.h>
 #include <linux/dvb/audio.h>
 
@@ -692,31 +691,13 @@ static int ivtv_s_fmt_vid_out_overlay(st
 	return ret;
 }
 
-static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
-{
-	struct ivtv *itv = fh2id(fh)->itv;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
-		if (v4l2_chip_match_host(&chip->match))
-			chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
-		return 0;
-	}
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-	/* TODO: is this correct? */
-	return ivtv_call_all_err(itv, core, g_chip_ident, chip);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ivtv_itvc(struct ivtv *itv, bool get, u64 reg, u64 *val)
 {
 	volatile u8 __iomem *reg_start;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
+	if (reg & 0x3)
+		return -EINVAL;
 	if (reg >= IVTV_REG_OFFSET && reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
 		reg_start = itv->reg_mem - IVTV_REG_OFFSET;
 	else if (itv->has_cx23415 && reg >= IVTV_DECODER_OFFSET &&
@@ -738,29 +719,16 @@ static int ivtv_g_register(struct file *
 {
 	struct ivtv *itv = fh2id(fh)->itv;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		reg->size = 4;
-		return ivtv_itvc(itv, true, reg->reg, &reg->val);
-	}
-	/* TODO: subdev errors should not be ignored, this should become a
-	   subdev helper function. */
-	ivtv_call_all(itv, core, g_register, reg);
-	return 0;
+	reg->size = 4;
+	return ivtv_itvc(itv, true, reg->reg, &reg->val);
 }
 
 static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
 {
 	struct ivtv *itv = fh2id(fh)->itv;
+	u64 val = reg->val;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		u64 val = reg->val;
-
-		return ivtv_itvc(itv, false, reg->reg, &val);
-	}
-	/* TODO: subdev errors should not be ignored, this should become a
-	   subdev helper function. */
-	ivtv_call_all(itv, core, s_register, reg);
-	return 0;
+	return ivtv_itvc(itv, false, reg->reg, &val);
 }
 #endif
 
@@ -1914,7 +1882,6 @@ static const struct v4l2_ioctl_ops ivtv_
 	.vidioc_try_fmt_vid_out_overlay     = ivtv_try_fmt_vid_out_overlay,
 	.vidioc_try_fmt_sliced_vbi_out 	    = ivtv_try_fmt_sliced_vbi_out,
 	.vidioc_g_sliced_vbi_cap 	    = ivtv_g_sliced_vbi_cap,
-	.vidioc_g_chip_ident 		    = ivtv_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register 		    = ivtv_g_register,
 	.vidioc_s_register 		    = ivtv_s_register,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/pci/Kconfig
--- linux-libre-3.10-gnu/drivers/media/pci/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,7 @@
+if PCI && MEDIA_SUPPORT
+
 menuconfig MEDIA_PCI_SUPPORT
 	bool "Media PCI Adapters"
-	depends on PCI && MEDIA_SUPPORT
 	help
 	  Enable media drivers for PCI/PCIe bus.
 	  If you have such devices, say Y.
@@ -45,3 +46,4 @@ source "drivers/media/pci/ddbridge/Kconf
 endif
 
 endif #MEDIA_PCI_SUPPORT
+endif #PCI
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/mantis/hopper_cards.c linux-libre-3.11-rc7-gnu/drivers/media/pci/mantis/hopper_cards.c
--- linux-libre-3.10-gnu/drivers/media/pci/mantis/hopper_cards.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/mantis/hopper_cards.c	2013-08-25 20:43:22.000000000 -0400
@@ -260,18 +260,7 @@ static struct pci_driver hopper_pci_driv
 	.remove		= hopper_pci_remove,
 };
 
-static int hopper_init(void)
-{
-	return pci_register_driver(&hopper_pci_driver);
-}
-
-static void hopper_exit(void)
-{
-	return pci_unregister_driver(&hopper_pci_driver);
-}
-
-module_init(hopper_init);
-module_exit(hopper_exit);
+module_pci_driver(hopper_pci_driver);
 
 MODULE_DESCRIPTION("HOPPER driver");
 MODULE_AUTHOR("Manu Abraham");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/mantis/mantis_cards.c linux-libre-3.11-rc7-gnu/drivers/media/pci/mantis/mantis_cards.c
--- linux-libre-3.10-gnu/drivers/media/pci/mantis/mantis_cards.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/mantis/mantis_cards.c	2013-08-25 20:43:22.000000000 -0400
@@ -290,18 +290,7 @@ static struct pci_driver mantis_pci_driv
 	.remove		= mantis_pci_remove,
 };
 
-static int mantis_init(void)
-{
-	return pci_register_driver(&mantis_pci_driver);
-}
-
-static void mantis_exit(void)
-{
-	return pci_unregister_driver(&mantis_pci_driver);
-}
-
-module_init(mantis_init);
-module_exit(mantis_exit);
+module_pci_driver(mantis_pci_driver);
 
 MODULE_DESCRIPTION("MANTIS driver");
 MODULE_AUTHOR("Manu Abraham");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/mantis/mantis_vp1041.c linux-libre-3.11-rc7-gnu/drivers/media/pci/mantis/mantis_vp1041.c
--- linux-libre-3.10-gnu/drivers/media/pci/mantis/mantis_vp1041.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/mantis/mantis_vp1041.c	2013-08-25 20:43:22.000000000 -0400
@@ -273,7 +273,7 @@ struct stb0899_config vp1041_stb0899_con
 	.demod_address 		= 0x68, /*  0xd0 >> 1 */
 
 	.xtal_freq		= 27000000,
-	.inversion		= IQ_SWAP_ON, /* 1 */
+	.inversion		= IQ_SWAP_ON,
 
 	.lo_clk			= 76500000,
 	.hi_clk			= 99000000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/pluto2/pluto2.c linux-libre-3.11-rc7-gnu/drivers/media/pci/pluto2/pluto2.c
--- linux-libre-3.10-gnu/drivers/media/pci/pluto2/pluto2.c	2013-07-01 10:34:27.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/pluto2/pluto2.c	2013-08-31 17:53:58.000000000 -0400
@@ -796,18 +796,7 @@ static struct pci_driver pluto2_driver =
 	.remove = pluto2_remove,
 };
 
-static int __init pluto2_init(void)
-{
-	return pci_register_driver(&pluto2_driver);
-}
-
-static void __exit pluto2_exit(void)
-{
-	pci_unregister_driver(&pluto2_driver);
-}
-
-module_init(pluto2_init);
-module_exit(pluto2_exit);
+module_pci_driver(pluto2_driver);
 
 MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
 MODULE_DESCRIPTION("Pluto2 driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/pt1/pt1.c linux-libre-3.11-rc7-gnu/drivers/media/pci/pt1/pt1.c
--- linux-libre-3.10-gnu/drivers/media/pci/pt1/pt1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/pt1/pt1.c	2013-08-25 20:43:22.000000000 -0400
@@ -1225,20 +1225,7 @@ static struct pci_driver pt1_driver = {
 	.id_table	= pt1_id_table,
 };
 
-
-static int __init pt1_init(void)
-{
-	return pci_register_driver(&pt1_driver);
-}
-
-
-static void __exit pt1_cleanup(void)
-{
-	pci_unregister_driver(&pt1_driver);
-}
-
-module_init(pt1_init);
-module_exit(pt1_cleanup);
+module_pci_driver(pt1_driver);
 
 MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>");
 MODULE_DESCRIPTION("Earthsoft PT1/PT2 Driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa6752hs.c linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa6752hs.c
--- linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa6752hs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa6752hs.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,8 +34,8 @@
 #include <linux/types.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
 
@@ -92,7 +92,12 @@ static const struct v4l2_format v4l2_for
 
 struct saa6752hs_state {
 	struct v4l2_subdev            sd;
-	int 			      chip;
+	struct v4l2_ctrl_handler      hdl;
+	struct { /* video bitrate mode control cluster */
+		struct v4l2_ctrl *video_bitrate_mode;
+		struct v4l2_ctrl *video_bitrate;
+		struct v4l2_ctrl *video_bitrate_peak;
+	};
 	u32 			      revision;
 	int 			      has_ac3;
 	struct saa6752hs_mpeg_params  params;
@@ -362,316 +367,72 @@ static int saa6752hs_set_bitrate(struct
 	return 0;
 }
 
-
-static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
-		struct v4l2_ext_control *ctrl)
+static int saa6752hs_try_ctrl(struct v4l2_ctrl *ctrl)
 {
+	struct saa6752hs_state *h =
+		container_of(ctrl->handler, struct saa6752hs_state, hdl);
+
 	switch (ctrl->id) {
-	case V4L2_CID_MPEG_STREAM_TYPE:
-		ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_PMT:
-		ctrl->value = params->ts_pid_pmt;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
-		ctrl->value = params->ts_pid_audio;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
-		ctrl->value = params->ts_pid_video;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_PCR:
-		ctrl->value = params->ts_pid_pcr;
-		break;
-	case V4L2_CID_MPEG_AUDIO_ENCODING:
-		ctrl->value = params->au_encoding;
-		break;
-	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		ctrl->value = params->au_l2_bitrate;
-		break;
-	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-		if (!has_ac3)
-			return -EINVAL;
-		ctrl->value = params->au_ac3_bitrate;
-		break;
-	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
-		ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
-		break;
-	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
-		break;
-	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		ctrl->value = params->vi_aspect;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		ctrl->value = params->vi_bitrate * 1000;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-		ctrl->value = params->vi_bitrate_peak * 1000;
-		break;
 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		ctrl->value = params->vi_bitrate_mode;
+		/* peak bitrate shall be >= normal bitrate */
+		if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
+		    h->video_bitrate_peak->val < h->video_bitrate->val)
+			h->video_bitrate_peak->val = h->video_bitrate->val;
 		break;
-	default:
-		return -EINVAL;
 	}
 	return 0;
 }
 
-static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
-		struct v4l2_ext_control *ctrl, int set)
+static int saa6752hs_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	int old = 0, new;
+	struct saa6752hs_state *h =
+		container_of(ctrl->handler, struct saa6752hs_state, hdl);
+	struct saa6752hs_mpeg_params *params = &h->params;
 
-	new = ctrl->value;
 	switch (ctrl->id) {
 	case V4L2_CID_MPEG_STREAM_TYPE:
-		old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
-		if (set && new != old)
-			return -ERANGE;
-		new = old;
 		break;
 	case V4L2_CID_MPEG_STREAM_PID_PMT:
-		old = params->ts_pid_pmt;
-		if (set && new > MPEG_PID_MAX)
-			return -ERANGE;
-		if (new > MPEG_PID_MAX)
-			new = MPEG_PID_MAX;
-		params->ts_pid_pmt = new;
+		params->ts_pid_pmt = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
-		old = params->ts_pid_audio;
-		if (set && new > MPEG_PID_MAX)
-			return -ERANGE;
-		if (new > MPEG_PID_MAX)
-			new = MPEG_PID_MAX;
-		params->ts_pid_audio = new;
+		params->ts_pid_audio = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
-		old = params->ts_pid_video;
-		if (set && new > MPEG_PID_MAX)
-			return -ERANGE;
-		if (new > MPEG_PID_MAX)
-			new = MPEG_PID_MAX;
-		params->ts_pid_video = new;
+		params->ts_pid_video = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_STREAM_PID_PCR:
-		old = params->ts_pid_pcr;
-		if (set && new > MPEG_PID_MAX)
-			return -ERANGE;
-		if (new > MPEG_PID_MAX)
-			new = MPEG_PID_MAX;
-		params->ts_pid_pcr = new;
+		params->ts_pid_pcr = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_AUDIO_ENCODING:
-		old = params->au_encoding;
-		if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
-		    (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
-			return -ERANGE;
-		params->au_encoding = new;
+		params->au_encoding = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		old = params->au_l2_bitrate;
-		if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
-			   new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
-			return -ERANGE;
-		if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
-			new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
-		else
-			new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
-		params->au_l2_bitrate = new;
+		params->au_l2_bitrate = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-		if (!has_ac3)
-			return -EINVAL;
-		old = params->au_ac3_bitrate;
-		if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
-			   new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
-			return -ERANGE;
-		if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
-			new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
-		else
-			new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
-		params->au_ac3_bitrate = new;
+		params->au_ac3_bitrate = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
-		old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
-		if (set && new != old)
-			return -ERANGE;
-		new = old;
 		break;
 	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
-		if (set && new != old)
-			return -ERANGE;
-		new = old;
 		break;
 	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		old = params->vi_aspect;
-		if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
-			   new != V4L2_MPEG_VIDEO_ASPECT_4x3)
-			return -ERANGE;
-		if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
-			new = V4L2_MPEG_VIDEO_ASPECT_4x3;
-		params->vi_aspect = new;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		old = params->vi_bitrate * 1000;
-		new = 1000 * (new / 1000);
-		if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-			return -ERANGE;
-		if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-			new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
-		params->vi_bitrate = new / 1000;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-		old = params->vi_bitrate_peak * 1000;
-		new = 1000 * (new / 1000);
-		if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-			return -ERANGE;
-		if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-			new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
-		params->vi_bitrate_peak = new / 1000;
+		params->vi_aspect = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		old = params->vi_bitrate_mode;
-		params->vi_bitrate_mode = new;
+		params->vi_bitrate_mode = ctrl->val;
+		params->vi_bitrate = h->video_bitrate->val / 1000;
+		params->vi_bitrate_peak = h->video_bitrate_peak->val / 1000;
+		v4l2_ctrl_activate(h->video_bitrate_peak,
+				ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
 		break;
 	default:
 		return -EINVAL;
 	}
-	ctrl->value = new;
 	return 0;
 }
 
-
-static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
-{
-	struct saa6752hs_state *h = to_state(sd);
-	struct saa6752hs_mpeg_params *params = &h->params;
-	int err;
-
-	switch (qctrl->id) {
-	case V4L2_CID_MPEG_AUDIO_ENCODING:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
-				h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 :
-					V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
-				1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
-
-	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_L2_BITRATE_256K,
-				V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
-				V4L2_MPEG_AUDIO_L2_BITRATE_256K);
-
-	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-		if (!h->has_ac3)
-			return -EINVAL;
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
-				V4L2_MPEG_AUDIO_AC3_BITRATE_384K, 1,
-				V4L2_MPEG_AUDIO_AC3_BITRATE_256K);
-
-	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
-				V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, 1,
-				V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
-
-	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
-
-	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_VIDEO_ASPECT_4x3,
-				V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
-				V4L2_MPEG_VIDEO_ASPECT_4x3);
-
-	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-		err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
-		if (err == 0 &&
-		    params->vi_bitrate_mode ==
-				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
-			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
-		return err;
-
-	case V4L2_CID_MPEG_STREAM_TYPE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_TS, 1,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
-
-	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
-				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
-				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
-	case V4L2_CID_MPEG_STREAM_PID_PMT:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
-	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
-	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
-	case V4L2_CID_MPEG_STREAM_PID_PCR:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
-
-	default:
-		break;
-	}
-	return -EINVAL;
-}
-
-static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu)
-{
-	static const u32 mpeg_audio_encoding[] = {
-		V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
-		V4L2_CTRL_MENU_IDS_END
-	};
-	static const u32 mpeg_audio_ac3_encoding[] = {
-		V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
-		V4L2_MPEG_AUDIO_ENCODING_AC3,
-		V4L2_CTRL_MENU_IDS_END
-	};
-	static u32 mpeg_audio_l2_bitrate[] = {
-		V4L2_MPEG_AUDIO_L2_BITRATE_256K,
-		V4L2_MPEG_AUDIO_L2_BITRATE_384K,
-		V4L2_CTRL_MENU_IDS_END
-	};
-	static u32 mpeg_audio_ac3_bitrate[] = {
-		V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
-		V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
-		V4L2_CTRL_MENU_IDS_END
-	};
-	struct saa6752hs_state *h = to_state(sd);
-	struct v4l2_queryctrl qctrl;
-	int err;
-
-	qctrl.id = qmenu->id;
-	err = saa6752hs_queryctrl(sd, &qctrl);
-	if (err)
-		return err;
-	switch (qmenu->id) {
-	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		return v4l2_ctrl_query_menu_valid_items(qmenu,
-				mpeg_audio_l2_bitrate);
-	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-		if (!h->has_ac3)
-			return -EINVAL;
-		return v4l2_ctrl_query_menu_valid_items(qmenu,
-				mpeg_audio_ac3_bitrate);
-	case V4L2_CID_MPEG_AUDIO_ENCODING:
-		return v4l2_ctrl_query_menu_valid_items(qmenu,
-			h->has_ac3 ? mpeg_audio_ac3_encoding :
-				mpeg_audio_encoding);
-	}
-	return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
-}
-
 static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes)
 {
 	unsigned char buf[9], buf2[4];
@@ -793,58 +554,6 @@ static int saa6752hs_init(struct v4l2_su
 	return 0;
 }
 
-static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set)
-{
-	struct saa6752hs_state *h = to_state(sd);
-	struct saa6752hs_mpeg_params params;
-	int i;
-
-	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-
-	params = h->params;
-	for (i = 0; i < ctrls->count; i++) {
-		int err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, set);
-
-		if (err) {
-			ctrls->error_idx = i;
-			return err;
-		}
-	}
-	if (set)
-		h->params = params;
-	return 0;
-}
-
-static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
-	return saa6752hs_do_ext_ctrls(sd, ctrls, 1);
-}
-
-static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
-	return saa6752hs_do_ext_ctrls(sd, ctrls, 0);
-}
-
-static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
-	struct saa6752hs_state *h = to_state(sd);
-	int i;
-
-	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-
-	for (i = 0; i < ctrls->count; i++) {
-		int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i);
-
-		if (err) {
-			ctrls->error_idx = i;
-			return err;
-		}
-	}
-	return 0;
-}
-
 static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
 {
 	struct saa6752hs_state *h = to_state(sd);
@@ -859,25 +568,11 @@ static int saa6752hs_g_mbus_fmt(struct v
 	return 0;
 }
 
-static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
+static int saa6752hs_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
 {
-	struct saa6752hs_state *h = to_state(sd);
 	int dist_352, dist_480, dist_720;
 
-	if (f->code != V4L2_MBUS_FMT_FIXED)
-		return -EINVAL;
-
-	/*
-	  FIXME: translate and round width/height into EMPRESS
-	  subsample type:
-
-	  type   |   PAL   |  NTSC
-	  ---------------------------
-	  SIF    | 352x288 | 352x240
-	  1/2 D1 | 352x576 | 352x480
-	  2/3 D1 | 480x576 | 480x480
-	  D1     | 720x576 | 720x480
-	*/
+	f->code = V4L2_MBUS_FMT_FIXED;
 
 	dist_352 = abs(f->width - 352);
 	dist_480 = abs(f->width - 480);
@@ -885,59 +580,82 @@ static int saa6752hs_s_mbus_fmt(struct v
 	if (dist_720 < dist_480) {
 		f->width = 720;
 		f->height = 576;
-		h->video_format = SAA6752HS_VF_D1;
 	} else if (dist_480 < dist_352) {
 		f->width = 480;
 		f->height = 576;
-		h->video_format = SAA6752HS_VF_2_3_D1;
 	} else {
 		f->width = 352;
-		if (abs(f->height - 576) <
-		    abs(f->height - 288)) {
+		if (abs(f->height - 576) < abs(f->height - 288))
 			f->height = 576;
-			h->video_format = SAA6752HS_VF_1_2_D1;
-		} else {
+		else
 			f->height = 288;
-			h->video_format = SAA6752HS_VF_SIF;
-		}
 	}
 	f->field = V4L2_FIELD_INTERLACED;
 	f->colorspace = V4L2_COLORSPACE_SMPTE170M;
 	return 0;
 }
 
-static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
 {
 	struct saa6752hs_state *h = to_state(sd);
 
-	h->standard = std;
+	if (f->code != V4L2_MBUS_FMT_FIXED)
+		return -EINVAL;
+
+	/*
+	  FIXME: translate and round width/height into EMPRESS
+	  subsample type:
+
+	  type   |   PAL   |  NTSC
+	  ---------------------------
+	  SIF    | 352x288 | 352x240
+	  1/2 D1 | 352x576 | 352x480
+	  2/3 D1 | 480x576 | 480x480
+	  D1     | 720x576 | 720x480
+	*/
+
+	saa6752hs_try_mbus_fmt(sd, f);
+	if (f->width == 720)
+		h->video_format = SAA6752HS_VF_D1;
+	else if (f->width == 480)
+		h->video_format = SAA6752HS_VF_2_3_D1;
+	else if (f->height == 576)
+		h->video_format = SAA6752HS_VF_1_2_D1;
+	else
+		h->video_format = SAA6752HS_VF_SIF;
 	return 0;
 }
 
-static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct saa6752hs_state *h = to_state(sd);
 
-	return v4l2_chip_ident_i2c_client(client,
-			chip, h->chip, h->revision);
+	h->standard = std;
+	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
+static const struct v4l2_ctrl_ops saa6752hs_ctrl_ops = {
+	.try_ctrl = saa6752hs_try_ctrl,
+	.s_ctrl = saa6752hs_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
-	.g_chip_ident = saa6752hs_g_chip_ident,
 	.init = saa6752hs_init,
-	.queryctrl = saa6752hs_queryctrl,
-	.querymenu = saa6752hs_querymenu,
-	.g_ext_ctrls = saa6752hs_g_ext_ctrls,
-	.s_ext_ctrls = saa6752hs_s_ext_ctrls,
-	.try_ext_ctrls = saa6752hs_try_ext_ctrls,
+	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+	.g_ctrl = v4l2_subdev_g_ctrl,
+	.s_ctrl = v4l2_subdev_s_ctrl,
+	.queryctrl = v4l2_subdev_queryctrl,
+	.querymenu = v4l2_subdev_querymenu,
 	.s_std = saa6752hs_s_std,
 };
 
 static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
 	.s_mbus_fmt = saa6752hs_s_mbus_fmt,
+	.try_mbus_fmt = saa6752hs_try_mbus_fmt,
 	.g_mbus_fmt = saa6752hs_g_mbus_fmt,
 };
 
@@ -951,6 +669,7 @@ static int saa6752hs_probe(struct i2c_cl
 {
 	struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
 	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *hdl;
 	u8 addr = 0x13;
 	u8 data[12];
 
@@ -963,15 +682,88 @@ static int saa6752hs_probe(struct i2c_cl
 
 	i2c_master_send(client, &addr, 1);
 	i2c_master_recv(client, data, sizeof(data));
-	h->chip = V4L2_IDENT_SAA6752HS;
 	h->revision = (data[8] << 8) | data[9];
 	h->has_ac3 = 0;
 	if (h->revision == 0x0206) {
-		h->chip = V4L2_IDENT_SAA6752HS_AC3;
 		h->has_ac3 = 1;
-		v4l_info(client, "support AC-3\n");
+		v4l_info(client, "supports AC-3\n");
 	}
 	h->params = param_defaults;
+
+	hdl = &h->hdl;
+	v4l2_ctrl_handler_init(hdl, 14);
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_AUDIO_ENCODING,
+		h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 :
+			V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+		0x0d, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+		V4L2_MPEG_AUDIO_L2_BITRATE_384K,
+		~((1 << V4L2_MPEG_AUDIO_L2_BITRATE_256K) |
+		  (1 << V4L2_MPEG_AUDIO_L2_BITRATE_384K)),
+		V4L2_MPEG_AUDIO_L2_BITRATE_256K);
+
+	if (h->has_ac3)
+		v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+			V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
+			V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
+			~((1 << V4L2_MPEG_AUDIO_AC3_BITRATE_256K) |
+			  (1 << V4L2_MPEG_AUDIO_AC3_BITRATE_384K)),
+			V4L2_MPEG_AUDIO_AC3_BITRATE_256K);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
+		V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
+		~(1 << V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000),
+		V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_ENCODING,
+		V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
+		~(1 << V4L2_MPEG_VIDEO_ENCODING_MPEG_2),
+		V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_ASPECT,
+		V4L2_MPEG_VIDEO_ASPECT_16x9, 0x01,
+		V4L2_MPEG_VIDEO_ASPECT_4x3);
+
+	h->video_bitrate_peak = v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+		1000000, 27000000, 1000, 8000000);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_TYPE,
+		V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
+		~(1 << V4L2_MPEG_STREAM_TYPE_MPEG2_TS),
+		V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
+
+	h->video_bitrate_mode = v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
+		V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
+	h->video_bitrate = v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_BITRATE, 1000000, 27000000, 1000, 6000000);
+	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_PID_PMT, 0, (1 << 14) - 1, 1, 16);
+	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_PID_AUDIO, 0, (1 << 14) - 1, 1, 260);
+	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_PID_VIDEO, 0, (1 << 14) - 1, 1, 256);
+	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_PID_PCR, 0, (1 << 14) - 1, 1, 259);
+	sd->ctrl_handler = hdl;
+	if (hdl->error) {
+		int err = hdl->error;
+
+		v4l2_ctrl_handler_free(hdl);
+		kfree(h);
+		return err;
+	}
+	v4l2_ctrl_cluster(3, &h->video_bitrate_mode);
+	v4l2_ctrl_handler_setup(hdl);
 	h->standard = 0; /* Assume 625 input lines */
 	return 0;
 }
@@ -981,6 +773,7 @@ static int saa6752hs_remove(struct i2c_c
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&to_state(sd)->hdl);
 	kfree(to_state(sd));
 	return 0;
 }
@@ -1002,11 +795,3 @@ static struct i2c_driver saa6752hs_drive
 };
 
 module_i2c_driver(saa6752hs_driver);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa7134-alsa.c linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa7134-alsa.c
--- linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa7134-alsa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa7134-alsa.c	2013-08-25 20:43:22.000000000 -0400
@@ -172,7 +172,9 @@ static void saa7134_irq_alsa_done(struct
 		dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
 			dev->dmasound.bufsize, dev->dmasound.blocks);
 		spin_unlock(&dev->slock);
+		snd_pcm_stream_lock(dev->dmasound.substream);
 		snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
+		snd_pcm_stream_unlock(dev->dmasound.substream);
 		return;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa7134-empress.c linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa7134-empress.c
--- linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa7134-empress.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa7134-empress.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,6 @@
 
 #include <media/saa6752hs.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 
 /* ------------------------------------------------------------------ */
 
@@ -213,7 +212,7 @@ static int empress_enum_fmt_vid_cap(stru
 
 	strlcpy(f->description, "MPEG TS", sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
-
+	f->flags = V4L2_FMT_FLAG_COMPRESSED;
 	return 0;
 }
 
@@ -228,6 +227,8 @@ static int empress_g_fmt_vid_cap(struct
 	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
+	f->fmt.pix.bytesperline = 0;
+	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -244,6 +245,8 @@ static int empress_s_fmt_vid_cap(struct
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
+	f->fmt.pix.bytesperline = 0;
+	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -252,9 +255,16 @@ static int empress_try_fmt_vid_cap(struc
 				struct v4l2_format *f)
 {
 	struct saa7134_dev *dev = file->private_data;
+	struct v4l2_mbus_framefmt mbus_fmt;
+
+	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
+	saa_call_all(dev, video, try_mbus_fmt, &mbus_fmt);
+	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
+	f->fmt.pix.bytesperline = 0;
+	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -413,21 +423,6 @@ static int empress_querymenu(struct file
 	return saa_call_empress(dev, core, querymenu, c);
 }
 
-static int empress_g_chip_ident(struct file *file, void *fh,
-	       struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa7134_dev *dev = file->private_data;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    !strcmp(chip->match.name, "saa6752hs"))
-		return saa_call_empress(dev, core, g_chip_ident, chip);
-	if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR)
-		return saa_call_empress(dev, core, g_chip_ident, chip);
-	return -EINVAL;
-}
-
 static int empress_s_std(struct file *file, void *priv, v4l2_std_id id)
 {
 	struct saa7134_dev *dev = file->private_data;
@@ -475,7 +470,6 @@ static const struct v4l2_ioctl_ops ts_io
 	.vidioc_querymenu		= empress_querymenu,
 	.vidioc_g_ctrl			= empress_g_ctrl,
 	.vidioc_s_ctrl			= empress_s_ctrl,
-	.vidioc_g_chip_ident 		= empress_g_chip_ident,
 	.vidioc_s_std			= empress_s_std,
 	.vidioc_g_std			= empress_g_std,
 };
@@ -488,7 +482,6 @@ static struct video_device saa7134_empre
 	.ioctl_ops     = &ts_ioctl_ops,
 
 	.tvnorms			= SAA7134_NORMS,
-	.current_norm			= V4L2_STD_PAL,
 };
 
 static void empress_signal_update(struct work_struct *work)
@@ -518,7 +511,7 @@ static int empress_init(struct saa7134_d
 	if (NULL == dev->empress_dev)
 		return -ENOMEM;
 	*(dev->empress_dev) = saa7134_empress_template;
-	dev->empress_dev->parent  = &dev->pci->dev;
+	dev->empress_dev->v4l2_dev  = &dev->v4l2_dev;
 	dev->empress_dev->release = video_device_release;
 	snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
 		 "%s empress (%s)", dev->name,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa7134.h linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa7134.h
--- linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa7134.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa7134.h	2013-08-25 20:43:22.000000000 -0400
@@ -471,19 +471,9 @@ struct saa7134_dmaqueue {
 struct saa7134_fh {
 	struct v4l2_fh             fh;
 	struct saa7134_dev         *dev;
-	unsigned int               radio;
-	enum v4l2_buf_type         type;
 	unsigned int               resources;
-	struct pm_qos_request	   qos_request;
-
-	/* video overlay */
-	struct v4l2_window         win;
-	struct v4l2_clip           clips[8];
-	unsigned int               nclips;
 
 	/* video capture */
-	struct saa7134_format      *fmt;
-	unsigned int               width,height;
 	struct videobuf_queue      cap;
 	struct saa7134_pgtable     pt_cap;
 
@@ -592,12 +582,19 @@ struct saa7134_dev {
 	struct saa7134_format      *ovfmt;
 	unsigned int               ovenable;
 	enum v4l2_field            ovfield;
+	struct v4l2_window         win;
+	struct v4l2_clip           clips[8];
+	unsigned int               nclips;
+
 
 	/* video+ts+vbi capture */
 	struct saa7134_dmaqueue    video_q;
 	struct saa7134_dmaqueue    vbi_q;
 	unsigned int               video_fieldcount;
 	unsigned int               vbi_fieldcount;
+	struct saa7134_format      *fmt;
+	unsigned int               width, height;
+	struct pm_qos_request	   qos_request;
 
 	/* various v4l controls */
 	struct saa7134_tvnorm      *tvnorm;              /* video */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa7134-video.c linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa7134-video.c
--- linux-libre-3.10-gnu/drivers/media/pci/saa7134/saa7134-video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7134/saa7134-video.c	2013-08-25 20:43:22.000000000 -0400
@@ -825,20 +825,22 @@ static int setup_clipping(struct saa7134
 	return 0;
 }
 
-static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
+static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win, bool try)
 {
 	enum v4l2_field field;
 	int maxw, maxh;
 
-	if (NULL == dev->ovbuf.base)
-		return -EINVAL;
-	if (NULL == dev->ovfmt)
-		return -EINVAL;
-	if (win->w.width < 48 || win->w.height <  32)
-		return -EINVAL;
-	if (win->clipcount > 2048)
+	if (!try && (dev->ovbuf.base == NULL || dev->ovfmt == NULL))
 		return -EINVAL;
+	if (win->w.width < 48)
+		win->w.width = 48;
+	if (win->w.height < 32)
+		win->w.height = 32;
+	if (win->clipcount > 8)
+		win->clipcount = 8;
 
+	win->chromakey = 0;
+	win->global_alpha = 0;
 	field = win->field;
 	maxw  = dev->crop_current.width;
 	maxh  = dev->crop_current.height;
@@ -853,10 +855,9 @@ static int verify_preview(struct saa7134
 	case V4L2_FIELD_BOTTOM:
 		maxh = maxh / 2;
 		break;
-	case V4L2_FIELD_INTERLACED:
-		break;
 	default:
-		return -EINVAL;
+		field = V4L2_FIELD_INTERLACED;
+		break;
 	}
 
 	win->field = field;
@@ -872,20 +873,20 @@ static int start_preview(struct saa7134_
 	unsigned long base,control,bpl;
 	int err;
 
-	err = verify_preview(dev,&fh->win);
+	err = verify_preview(dev, &dev->win, false);
 	if (0 != err)
 		return err;
 
-	dev->ovfield = fh->win.field;
+	dev->ovfield = dev->win.field;
 	dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
-		fh->win.w.width,fh->win.w.height,
-		fh->win.w.left,fh->win.w.top,
-		dev->ovfmt->name,v4l2_field_names[dev->ovfield]);
+		dev->win.w.width, dev->win.w.height,
+		dev->win.w.left, dev->win.w.top,
+		dev->ovfmt->name, v4l2_field_names[dev->ovfield]);
 
 	/* setup window + clipping */
-	set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height,
+	set_size(dev, TASK_B, dev->win.w.width, dev->win.w.height,
 		 V4L2_FIELD_HAS_BOTH(dev->ovfield));
-	setup_clipping(dev,fh->clips,fh->nclips,
+	setup_clipping(dev, dev->clips, dev->nclips,
 		       V4L2_FIELD_HAS_BOTH(dev->ovfield));
 	if (dev->ovfmt->yuv)
 		saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03);
@@ -895,8 +896,8 @@ static int start_preview(struct saa7134_
 
 	/* dma: setup channel 1 (= Video Task B) */
 	base  = (unsigned long)dev->ovbuf.base;
-	base += dev->ovbuf.fmt.bytesperline * fh->win.w.top;
-	base += dev->ovfmt->depth/8         * fh->win.w.left;
+	base += dev->ovbuf.fmt.bytesperline * dev->win.w.top;
+	base += dev->ovfmt->depth/8         * dev->win.w.left;
 	bpl   = dev->ovbuf.fmt.bytesperline;
 	control = SAA7134_RS_CONTROL_BURST_16;
 	if (dev->ovfmt->bswap)
@@ -1024,38 +1025,38 @@ static int buffer_prepare(struct videobu
 	int err;
 
 	/* sanity checks */
-	if (NULL == fh->fmt)
+	if (NULL == dev->fmt)
 		return -EINVAL;
-	if (fh->width    < 48 ||
-	    fh->height   < 32 ||
-	    fh->width/4  > dev->crop_current.width  ||
-	    fh->height/4 > dev->crop_current.height ||
-	    fh->width    > dev->crop_bounds.width  ||
-	    fh->height   > dev->crop_bounds.height)
+	if (dev->width    < 48 ||
+	    dev->height   < 32 ||
+	    dev->width/4  > dev->crop_current.width  ||
+	    dev->height/4 > dev->crop_current.height ||
+	    dev->width    > dev->crop_bounds.width  ||
+	    dev->height   > dev->crop_bounds.height)
 		return -EINVAL;
-	size = (fh->width * fh->height * fh->fmt->depth) >> 3;
+	size = (dev->width * dev->height * dev->fmt->depth) >> 3;
 	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
 		return -EINVAL;
 
 	dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
-		vb->i,fh->width,fh->height,size,v4l2_field_names[field],
-		fh->fmt->name);
-	if (buf->vb.width  != fh->width  ||
-	    buf->vb.height != fh->height ||
+		vb->i, dev->width, dev->height, size, v4l2_field_names[field],
+		dev->fmt->name);
+	if (buf->vb.width  != dev->width  ||
+	    buf->vb.height != dev->height ||
 	    buf->vb.size   != size       ||
 	    buf->vb.field  != field      ||
-	    buf->fmt       != fh->fmt) {
+	    buf->fmt       != dev->fmt) {
 		saa7134_dma_free(q,buf);
 	}
 
 	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
 		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
-		buf->vb.width  = fh->width;
-		buf->vb.height = fh->height;
+		buf->vb.width  = dev->width;
+		buf->vb.height = dev->height;
 		buf->vb.size   = size;
 		buf->vb.field  = field;
-		buf->fmt       = fh->fmt;
+		buf->fmt       = dev->fmt;
 		buf->pt        = &fh->pt_cap;
 		dev->video_q.curr = NULL;
 
@@ -1082,8 +1083,9 @@ static int
 buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
 {
 	struct saa7134_fh *fh = q->priv_data;
+	struct saa7134_dev *dev = fh->dev;
 
-	*size = fh->fmt->depth * fh->width * fh->height >> 3;
+	*size = dev->fmt->depth * dev->width * dev->height >> 3;
 	if (0 == *count)
 		*count = gbuffers;
 	*count = saa7134_buffer_count(*size,*count);
@@ -1287,15 +1289,17 @@ static int saa7134_s_ctrl(struct file *f
 
 /* ------------------------------------------------------------------ */
 
-static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
+static struct videobuf_queue *saa7134_queue(struct file *file)
 {
-	struct videobuf_queue* q = NULL;
+	struct video_device *vdev = video_devdata(file);
+	struct saa7134_fh *fh = file->private_data;
+	struct videobuf_queue *q = NULL;
 
-	switch (fh->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	switch (vdev->vfl_type) {
+	case VFL_TYPE_GRABBER:
 		q = &fh->cap;
 		break;
-	case V4L2_BUF_TYPE_VBI_CAPTURE:
+	case VFL_TYPE_VBI:
 		q = &fh->vbi;
 		break;
 	default:
@@ -1304,12 +1308,14 @@ static struct videobuf_queue* saa7134_qu
 	return q;
 }
 
-static int saa7134_resource(struct saa7134_fh *fh)
+static int saa7134_resource(struct file *file)
 {
-	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_GRABBER)
 		return RESOURCE_VIDEO;
 
-	if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+	if (vdev->vfl_type == VFL_TYPE_VBI)
 		return RESOURCE_VBI;
 
 	BUG();
@@ -1321,23 +1327,6 @@ static int video_open(struct file *file)
 	struct video_device *vdev = video_devdata(file);
 	struct saa7134_dev *dev = video_drvdata(file);
 	struct saa7134_fh *fh;
-	enum v4l2_buf_type type = 0;
-	int radio = 0;
-
-	switch (vdev->vfl_type) {
-	case VFL_TYPE_GRABBER:
-		type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		break;
-	case VFL_TYPE_VBI:
-		type = V4L2_BUF_TYPE_VBI_CAPTURE;
-		break;
-	case VFL_TYPE_RADIO:
-		radio = 1;
-		break;
-	}
-
-	dprintk("open dev=%s radio=%d type=%s\n", video_device_node_name(vdev),
-		radio, v4l2_type_names[type]);
 
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh),GFP_KERNEL);
@@ -1347,11 +1336,6 @@ static int video_open(struct file *file)
 	v4l2_fh_init(&fh->fh, vdev);
 	file->private_data = fh;
 	fh->dev      = dev;
-	fh->radio    = radio;
-	fh->type     = type;
-	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
-	fh->width    = 720;
-	fh->height   = 576;
 
 	videobuf_queue_sg_init(&fh->cap, &video_qops,
 			    &dev->pci->dev, &dev->slock,
@@ -1368,7 +1352,7 @@ static int video_open(struct file *file)
 	saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
 	saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
 
-	if (fh->radio) {
+	if (vdev->vfl_type == VFL_TYPE_RADIO) {
 		/* switch to radio mode */
 		saa7134_tvaudio_setinput(dev,&card(dev).radio);
 		saa_call_all(dev, tuner, s_radio);
@@ -1384,19 +1368,20 @@ static int video_open(struct file *file)
 static ssize_t
 video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct saa7134_fh *fh = file->private_data;
 
-	switch (fh->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	switch (vdev->vfl_type) {
+	case VFL_TYPE_GRABBER:
 		if (res_locked(fh->dev,RESOURCE_VIDEO))
 			return -EBUSY;
-		return videobuf_read_one(saa7134_queue(fh),
+		return videobuf_read_one(saa7134_queue(file),
 					 data, count, ppos,
 					 file->f_flags & O_NONBLOCK);
-	case V4L2_BUF_TYPE_VBI_CAPTURE:
+	case VFL_TYPE_VBI:
 		if (!res_get(fh->dev,fh,RESOURCE_VBI))
 			return -EBUSY;
-		return videobuf_read_stream(saa7134_queue(fh),
+		return videobuf_read_stream(saa7134_queue(file),
 					    data, count, ppos, 1,
 					    file->f_flags & O_NONBLOCK);
 		break;
@@ -1409,11 +1394,12 @@ video_read(struct file *file, char __use
 static unsigned int
 video_poll(struct file *file, struct poll_table_struct *wait)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct saa7134_fh *fh = file->private_data;
 	struct videobuf_buffer *buf = NULL;
 	unsigned int rc = 0;
 
-	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
+	if (vdev->vfl_type == VFL_TYPE_VBI)
 		return videobuf_poll_stream(file, &fh->vbi, wait);
 
 	if (res_check(fh,RESOURCE_VIDEO)) {
@@ -1451,6 +1437,7 @@ err:
 
 static int video_release(struct file *file)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct saa7134_fh  *fh  = file->private_data;
 	struct saa7134_dev *dev = fh->dev;
 	struct saa6588_command cmd;
@@ -1489,7 +1476,7 @@ static int video_release(struct file *fi
 	saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
 
 	saa_call_all(dev, core, s_power, 0);
-	if (fh->radio)
+	if (vdev->vfl_type == VFL_TYPE_RADIO)
 		saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
 
 	/* free stuff */
@@ -1507,9 +1494,7 @@ static int video_release(struct file *fi
 
 static int video_mmap(struct file *file, struct vm_area_struct * vma)
 {
-	struct saa7134_fh *fh = file->private_data;
-
-	return videobuf_mmap_mapper(saa7134_queue(fh), vma);
+	return videobuf_mmap_mapper(saa7134_queue(file), vma);
 }
 
 static ssize_t radio_read(struct file *file, char __user *data,
@@ -1570,15 +1555,18 @@ static int saa7134_g_fmt_vid_cap(struct
 				struct v4l2_format *f)
 {
 	struct saa7134_fh *fh = priv;
+	struct saa7134_dev *dev = fh->dev;
 
-	f->fmt.pix.width        = fh->width;
-	f->fmt.pix.height       = fh->height;
+	f->fmt.pix.width        = dev->width;
+	f->fmt.pix.height       = dev->height;
 	f->fmt.pix.field        = fh->cap.field;
-	f->fmt.pix.pixelformat  = fh->fmt->fourcc;
+	f->fmt.pix.pixelformat  = dev->fmt->fourcc;
 	f->fmt.pix.bytesperline =
-		(f->fmt.pix.width * fh->fmt->depth) >> 3;
+		(f->fmt.pix.width * dev->fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
 		f->fmt.pix.height * f->fmt.pix.bytesperline;
+	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
+	f->fmt.pix.priv = 0;
 	return 0;
 }
 
@@ -1586,14 +1574,33 @@ static int saa7134_g_fmt_vid_overlay(str
 				struct v4l2_format *f)
 {
 	struct saa7134_fh *fh = priv;
+	struct saa7134_dev *dev = fh->dev;
+	struct v4l2_clip __user *clips = f->fmt.win.clips;
+	u32 clipcount = f->fmt.win.clipcount;
+	int err = 0;
+	int i;
 
 	if (saa7134_no_overlay > 0) {
 		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
 		return -EINVAL;
 	}
-	f->fmt.win = fh->win;
+	mutex_lock(&dev->lock);
+	f->fmt.win = dev->win;
+	f->fmt.win.clips = clips;
+	if (clips == NULL)
+		clipcount = 0;
+	if (dev->nclips < clipcount)
+		clipcount = dev->nclips;
+	f->fmt.win.clipcount = clipcount;
 
-	return 0;
+	for (i = 0; !err && i < clipcount; i++) {
+		if (copy_to_user(&f->fmt.win.clips[i].c, &dev->clips[i].c,
+					sizeof(struct v4l2_rect)))
+			err = -EFAULT;
+	}
+	mutex_unlock(&dev->lock);
+
+	return err;
 }
 
 static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
@@ -1623,10 +1630,9 @@ static int saa7134_try_fmt_vid_cap(struc
 	case V4L2_FIELD_BOTTOM:
 		maxh = maxh / 2;
 		break;
-	case V4L2_FIELD_INTERLACED:
-		break;
 	default:
-		return -EINVAL;
+		field = V4L2_FIELD_INTERLACED;
+		break;
 	}
 
 	f->fmt.pix.field = field;
@@ -1643,6 +1649,8 @@ static int saa7134_try_fmt_vid_cap(struc
 		(f->fmt.pix.width * fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
 		f->fmt.pix.height * f->fmt.pix.bytesperline;
+	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
+	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -1658,22 +1666,25 @@ static int saa7134_try_fmt_vid_overlay(s
 		return -EINVAL;
 	}
 
-	return verify_preview(dev, &f->fmt.win);
+	if (f->fmt.win.clips == NULL)
+		f->fmt.win.clipcount = 0;
+	return verify_preview(dev, &f->fmt.win, true);
 }
 
 static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,
 					struct v4l2_format *f)
 {
 	struct saa7134_fh *fh = priv;
+	struct saa7134_dev *dev = fh->dev;
 	int err;
 
 	err = saa7134_try_fmt_vid_cap(file, priv, f);
 	if (0 != err)
 		return err;
 
-	fh->fmt       = format_by_fourcc(f->fmt.pix.pixelformat);
-	fh->width     = f->fmt.pix.width;
-	fh->height    = f->fmt.pix.height;
+	dev->fmt       = format_by_fourcc(f->fmt.pix.pixelformat);
+	dev->width     = f->fmt.pix.width;
+	dev->height    = f->fmt.pix.height;
 	fh->cap.field = f->fmt.pix.field;
 	return 0;
 }
@@ -1690,20 +1701,19 @@ static int saa7134_s_fmt_vid_overlay(str
 		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
 		return -EINVAL;
 	}
-	err = verify_preview(dev, &f->fmt.win);
+	if (f->fmt.win.clips == NULL)
+		f->fmt.win.clipcount = 0;
+	err = verify_preview(dev, &f->fmt.win, true);
 	if (0 != err)
 		return err;
 
 	mutex_lock(&dev->lock);
 
-	fh->win    = f->fmt.win;
-	fh->nclips = f->fmt.win.clipcount;
-
-	if (fh->nclips > 8)
-		fh->nclips = 8;
+	dev->win    = f->fmt.win;
+	dev->nclips = f->fmt.win.clipcount;
 
-	if (copy_from_user(fh->clips, f->fmt.win.clips,
-			   sizeof(struct v4l2_clip)*fh->nclips)) {
+	if (copy_from_user(dev->clips, f->fmt.win.clips,
+			   sizeof(struct v4l2_clip) * dev->nclips)) {
 		mutex_unlock(&dev->lock);
 		return -EFAULT;
 	}
@@ -2057,7 +2067,6 @@ static int saa7134_g_frequency(struct fi
 	if (0 != f->tuner)
 		return -EINVAL;
 
-	f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 	saa_call_all(dev, tuner, g_frequency, f);
 
 	return 0;
@@ -2071,10 +2080,6 @@ static int saa7134_s_frequency(struct fi
 
 	if (0 != f->tuner)
 		return -EINVAL;
-	if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
-		return -EINVAL;
-	if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
-		return -EINVAL;
 	mutex_lock(&dev->lock);
 
 	saa_call_all(dev, tuner, s_frequency, f);
@@ -2186,27 +2191,23 @@ static int saa7134_overlay(struct file *
 static int saa7134_reqbufs(struct file *file, void *priv,
 					struct v4l2_requestbuffers *p)
 {
-	struct saa7134_fh *fh = priv;
-	return videobuf_reqbufs(saa7134_queue(fh), p);
+	return videobuf_reqbufs(saa7134_queue(file), p);
 }
 
 static int saa7134_querybuf(struct file *file, void *priv,
 					struct v4l2_buffer *b)
 {
-	struct saa7134_fh *fh = priv;
-	return videobuf_querybuf(saa7134_queue(fh), b);
+	return videobuf_querybuf(saa7134_queue(file), b);
 }
 
 static int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 {
-	struct saa7134_fh *fh = priv;
-	return videobuf_qbuf(saa7134_queue(fh), b);
+	return videobuf_qbuf(saa7134_queue(file), b);
 }
 
 static int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 {
-	struct saa7134_fh *fh = priv;
-	return videobuf_dqbuf(saa7134_queue(fh), b,
+	return videobuf_dqbuf(saa7134_queue(file), b,
 				file->f_flags & O_NONBLOCK);
 }
 
@@ -2215,7 +2216,7 @@ static int saa7134_streamon(struct file
 {
 	struct saa7134_fh *fh = priv;
 	struct saa7134_dev *dev = fh->dev;
-	int res = saa7134_resource(fh);
+	int res = saa7134_resource(file);
 
 	if (!res_get(dev, fh, res))
 		return -EBUSY;
@@ -2227,11 +2228,11 @@ static int saa7134_streamon(struct file
 	 * Unfortunately, I lack register-level documentation to check the
 	 * Linux FIFO setup and confirm the perfect value.
 	 */
-	pm_qos_add_request(&fh->qos_request,
+	pm_qos_add_request(&dev->qos_request,
 			   PM_QOS_CPU_DMA_LATENCY,
 			   20);
 
-	return videobuf_streamon(saa7134_queue(fh));
+	return videobuf_streamon(saa7134_queue(file));
 }
 
 static int saa7134_streamoff(struct file *file, void *priv,
@@ -2240,11 +2241,11 @@ static int saa7134_streamoff(struct file
 	int err;
 	struct saa7134_fh *fh = priv;
 	struct saa7134_dev *dev = fh->dev;
-	int res = saa7134_resource(fh);
+	int res = saa7134_resource(file);
 
-	pm_qos_remove_request(&fh->qos_request);
+	pm_qos_remove_request(&dev->qos_request);
 
-	err = videobuf_streamoff(saa7134_queue(fh));
+	err = videobuf_streamoff(saa7134_queue(file));
 	if (err < 0)
 		return err;
 	res_free(dev, fh, res);
@@ -2258,9 +2259,7 @@ static int vidioc_g_register (struct fil
 	struct saa7134_fh *fh = priv;
 	struct saa7134_dev *dev = fh->dev;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-	reg->val = saa_readb(reg->reg);
+	reg->val = saa_readb(reg->reg & 0xffffff);
 	reg->size = 1;
 	return 0;
 }
@@ -2271,9 +2270,7 @@ static int vidioc_s_register (struct fil
 	struct saa7134_fh *fh = priv;
 	struct saa7134_dev *dev = fh->dev;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-	saa_writeb(reg->reg&0xffffff, reg->val);
+	saa_writeb(reg->reg & 0xffffff, reg->val);
 	return 0;
 }
 #endif
@@ -2287,9 +2284,7 @@ static int radio_g_tuner(struct file *fi
 	if (0 != t->index)
 		return -EINVAL;
 
-	memset(t, 0, sizeof(*t));
 	strcpy(t->name, "Radio");
-	t->type = V4L2_TUNER_RADIO;
 
 	saa_call_all(dev, tuner, g_tuner, t);
 	t->audmode &= V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO;
@@ -2443,7 +2438,6 @@ struct video_device saa7134_video_templa
 	.fops				= &video_fops,
 	.ioctl_ops 			= &video_ioctl_ops,
 	.tvnorms			= SAA7134_NORMS,
-	.current_norm			= V4L2_STD_PAL,
 };
 
 struct video_device saa7134_radio_template = {
@@ -2480,6 +2474,16 @@ int saa7134_video_init1(struct saa7134_d
 	dev->video_q.timeout.function = saa7134_buffer_timeout;
 	dev->video_q.timeout.data     = (unsigned long)(&dev->video_q);
 	dev->video_q.dev              = dev;
+	dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
+	dev->width    = 720;
+	dev->height   = 576;
+	dev->win.w.width = dev->width;
+	dev->win.w.height = dev->height;
+	dev->win.field = V4L2_FIELD_INTERLACED;
+	dev->ovbuf.fmt.width = dev->width;
+	dev->ovbuf.fmt.height = dev->height;
+	dev->ovbuf.fmt.pixelformat = dev->fmt->fourcc;
+	dev->ovbuf.fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
 	if (saa7134_boards[dev->board].video_out)
 		saa7134_videoport_init(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7146/mxb.c linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7146/mxb.c
--- linux-libre-3.10-gnu/drivers/media/pci/saa7146/mxb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7146/mxb.c	2013-08-25 20:43:22.000000000 -0400
@@ -669,14 +669,10 @@ static int vidioc_g_register(struct file
 {
 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-	if (v4l2_chip_match_host(&reg->match)) {
-		reg->val = saa7146_read(dev, reg->reg);
-		reg->size = 4;
-		return 0;
-	}
-	call_all(dev, core, g_register, reg);
+	if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
+		return -EINVAL;
+	reg->val = saa7146_read(dev, reg->reg);
+	reg->size = 4;
 	return 0;
 }
 
@@ -684,13 +680,10 @@ static int vidioc_s_register(struct file
 {
 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-	if (v4l2_chip_match_host(&reg->match)) {
-		saa7146_write(dev, reg->reg, reg->val);
-		return 0;
-	}
-	return call_all(dev, core, s_register, reg);
+	if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
+		return -EINVAL;
+	saa7146_write(dev, reg->reg, reg->val);
+	return 0;
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7164/saa7164-core.c linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7164/saa7164-core.c
--- linux-libre-3.10-gnu/drivers/media/pci/saa7164/saa7164-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7164/saa7164-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -1196,6 +1196,12 @@ static int saa7164_initdev(struct pci_de
 	if (NULL == dev)
 		return -ENOMEM;
 
+	err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+	if (err < 0) {
+		dev_err(&pci_dev->dev, "v4l2_device_register failed\n");
+		goto fail_free;
+	}
+
 	/* pci init */
 	dev->pci = pci_dev;
 	if (pci_enable_device(pci_dev)) {
@@ -1367,6 +1373,7 @@ fail_fw:
 fail_irq:
 	saa7164_dev_unregister(dev);
 fail_free:
+	v4l2_device_unregister(&dev->v4l2_dev);
 	kfree(dev);
 	return err;
 }
@@ -1439,6 +1446,7 @@ static void saa7164_finidev(struct pci_d
 	mutex_unlock(&devlist);
 
 	saa7164_dev_unregister(dev);
+	v4l2_device_unregister(&dev->v4l2_dev);
 	kfree(dev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7164/saa7164-encoder.c linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7164/saa7164-encoder.c
--- linux-libre-3.10-gnu/drivers/media/pci/saa7164/saa7164-encoder.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7164/saa7164-encoder.c	2013-08-25 20:43:22.000000000 -0400
@@ -228,6 +228,7 @@ static int vidioc_s_std(struct file *fil
 		return -EINVAL;
 
 	port->encodernorm = saa7164_tvnorms[i];
+	port->std = id;
 
 	/* Update the audio decoder while is not running in
 	 * auto detect mode.
@@ -239,6 +240,15 @@ static int vidioc_s_std(struct file *fil
 	return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+	struct saa7164_encoder_fh *fh = file->private_data;
+	struct saa7164_port *port = fh->port;
+
+	*id = port->std;
+	return 0;
+}
+
 static int vidioc_enum_input(struct file *file, void *priv,
 	struct v4l2_input *i)
 {
@@ -1288,46 +1298,9 @@ static const struct v4l2_file_operations
 	.unlocked_ioctl	= video_ioctl2,
 };
 
-static int saa7164_g_chip_ident(struct file *file, void *fh,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
-	struct saa7164_dev *dev = port->dev;
-	dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
-	return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int saa7164_g_register(struct file *file, void *fh,
-			      struct v4l2_dbg_register *reg)
-{
-	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
-	struct saa7164_dev *dev = port->dev;
-	dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	return 0;
-}
-
-static int saa7164_s_register(struct file *file, void *fh,
-			      const struct v4l2_dbg_register *reg)
-{
-	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
-	struct saa7164_dev *dev = port->dev;
-	dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	return 0;
-}
-#endif
-
 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_s_std		 = vidioc_s_std,
+	.vidioc_g_std		 = vidioc_g_std,
 	.vidioc_enum_input	 = vidioc_enum_input,
 	.vidioc_g_input		 = vidioc_g_input,
 	.vidioc_s_input		 = vidioc_s_input,
@@ -1346,11 +1319,6 @@ static const struct v4l2_ioctl_ops mpeg_
 	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
 	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
-	.vidioc_g_chip_ident	 = saa7164_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register	 = saa7164_g_register,
-	.vidioc_s_register	 = saa7164_s_register,
-#endif
 };
 
 static struct video_device saa7164_mpeg_template = {
@@ -1359,7 +1327,6 @@ static struct video_device saa7164_mpeg_
 	.ioctl_ops     = &mpeg_ioctl_ops,
 	.minor         = -1,
 	.tvnorms       = SAA7164_NORMS,
-	.current_norm  = V4L2_STD_NTSC_M,
 };
 
 static struct video_device *saa7164_encoder_alloc(
@@ -1381,7 +1348,7 @@ static struct video_device *saa7164_enco
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
 		type, saa7164_boards[dev->board].name);
 
-	vfd->parent  = &pci->dev;
+	vfd->v4l2_dev  = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	return vfd;
 }
@@ -1426,6 +1393,7 @@ int saa7164_encoder_register(struct saa7
 	port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
 	port->encoder_params.refdist = 1;
 	port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE;
+	port->std = V4L2_STD_NTSC_M;
 
 	if (port->encodernorm.id & V4L2_STD_525_60)
 		port->height = 480;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7164/saa7164.h linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7164/saa7164.h
--- linux-libre-3.10-gnu/drivers/media/pci/saa7164/saa7164.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7164/saa7164.h	2013-08-25 20:43:22.000000000 -0400
@@ -63,7 +63,7 @@
 #include <dmxdev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-device.h>
 
 #include "saa7164-reg.h"
 #include "saa7164-types.h"
@@ -376,6 +376,7 @@ struct saa7164_port {
 	/* Encoder */
 	/* Defaults established in saa7164-encoder.c */
 	struct saa7164_tvnorm encodernorm;
+	v4l2_std_id std;
 	u32 height;
 	u32 width;
 	u32 freq;
@@ -427,6 +428,8 @@ struct saa7164_dev {
 	struct list_head	devlist;
 	atomic_t		refcount;
 
+	struct v4l2_device v4l2_dev;
+
 	/* pci stuff */
 	struct pci_dev	*pci;
 	unsigned char	pci_rev, pci_lat;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/saa7164/saa7164-vbi.c linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7164/saa7164-vbi.c
--- linux-libre-3.10-gnu/drivers/media/pci/saa7164/saa7164-vbi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/saa7164/saa7164-vbi.c	2013-08-25 20:43:22.000000000 -0400
@@ -200,6 +200,7 @@ static int vidioc_s_std(struct file *fil
 		return -EINVAL;
 
 	port->encodernorm = saa7164_tvnorms[i];
+	port->std = id;
 
 	/* Update the audio decoder while is not running in
 	 * auto detect mode.
@@ -211,6 +212,15 @@ static int vidioc_s_std(struct file *fil
 	return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+	struct saa7164_encoder_fh *fh = file->private_data;
+	struct saa7164_port *port = fh->port;
+
+	*id = port->std;
+	return 0;
+}
+
 static int vidioc_enum_input(struct file *file, void *priv,
 	struct v4l2_input *i)
 {
@@ -1236,6 +1246,7 @@ static const struct v4l2_file_operations
 
 static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
 	.vidioc_s_std		 = vidioc_s_std,
+	.vidioc_g_std		 = vidioc_g_std,
 	.vidioc_enum_input	 = vidioc_enum_input,
 	.vidioc_g_input		 = vidioc_g_input,
 	.vidioc_s_input		 = vidioc_s_input,
@@ -1254,15 +1265,6 @@ static const struct v4l2_ioctl_ops vbi_i
 	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
 	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
-#if 0
-	.vidioc_g_chip_ident	 = saa7164_g_chip_ident,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-#if 0
-	.vidioc_g_register	 = saa7164_g_register,
-	.vidioc_s_register	 = saa7164_s_register,
-#endif
-#endif
 	.vidioc_g_fmt_vbi_cap	 = saa7164_vbi_fmt,
 	.vidioc_try_fmt_vbi_cap	 = saa7164_vbi_fmt,
 	.vidioc_s_fmt_vbi_cap	 = saa7164_vbi_fmt,
@@ -1274,7 +1276,6 @@ static struct video_device saa7164_vbi_t
 	.ioctl_ops     = &vbi_ioctl_ops,
 	.minor         = -1,
 	.tvnorms       = SAA7164_NORMS,
-	.current_norm  = V4L2_STD_NTSC_M,
 };
 
 static struct video_device *saa7164_vbi_alloc(
@@ -1296,7 +1297,7 @@ static struct video_device *saa7164_vbi_
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
 		type, saa7164_boards[dev->board].name);
 
-	vfd->parent  = &pci->dev;
+	vfd->v4l2_dev  = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	return vfd;
 }
@@ -1333,6 +1334,7 @@ int saa7164_vbi_register(struct saa7164_
 		goto failed;
 	}
 
+	port->std = V4L2_STD_NTSC_M;
 	video_set_drvdata(port->v4l_device, port);
 	result = video_register_device(port->v4l_device,
 		VFL_TYPE_VBI, -1);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/sta2x11/sta2x11_vip.c linux-libre-3.11-rc7-gnu/drivers/media/pci/sta2x11/sta2x11_vip.c
--- linux-libre-3.10-gnu/drivers/media/pci/sta2x11/sta2x11_vip.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/sta2x11/sta2x11_vip.c	2013-08-25 20:43:22.000000000 -0400
@@ -1047,7 +1047,8 @@ static int sta2x11_vip_init_one(struct p
 	ret = sta2x11_vip_init_controls(vip);
 	if (ret)
 		goto free_mem;
-	if (v4l2_device_register(&pdev->dev, &vip->v4l2_dev))
+	ret = v4l2_device_register(&pdev->dev, &vip->v4l2_dev);
+	if (ret)
 		goto free_mem;
 
 	dev_dbg(&pdev->dev, "BAR #0 at 0x%lx 0x%lx irq %d\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/ttpci/budget-av.c linux-libre-3.11-rc7-gnu/drivers/media/pci/ttpci/budget-av.c
--- linux-libre-3.10-gnu/drivers/media/pci/ttpci/budget-av.c	2013-07-01 10:34:22.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/ttpci/budget-av.c	2013-08-31 17:53:52.000000000 -0400
@@ -1128,7 +1128,7 @@ static struct stb0899_config knc1_dvbs2_
 //	.ts_pfbit_toggle	= STB0899_MPEG_NORMAL,	/* DirecTV, MPEG toggling seq	*/
 
 	.xtal_freq		= 27000000,
-	.inversion		= IQ_SWAP_OFF, /* 1 */
+	.inversion		= IQ_SWAP_OFF,
 
 	.lo_clk			= 76500000,
 	.hi_clk			= 90000000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/ttpci/budget-ci.c linux-libre-3.11-rc7-gnu/drivers/media/pci/ttpci/budget-ci.c
--- linux-libre-3.10-gnu/drivers/media/pci/ttpci/budget-ci.c	2013-07-01 10:34:22.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/ttpci/budget-ci.c	2013-08-31 17:53:52.000000000 -0400
@@ -1280,7 +1280,7 @@ static struct stb0899_config tt3200_conf
 	.demod_address 		= 0x68,
 
 	.xtal_freq		= 27000000,
-	.inversion		= IQ_SWAP_ON, /* 1 */
+	.inversion		= IQ_SWAP_ON,
 
 	.lo_clk			= 76500000,
 	.hi_clk			= 99000000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/zoran/zoran_card.c linux-libre-3.11-rc7-gnu/drivers/media/pci/zoran/zoran_card.c
--- linux-libre-3.10-gnu/drivers/media/pci/zoran/zoran_card.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/zoran/zoran_card.c	2013-08-25 20:43:22.000000000 -0400
@@ -1050,7 +1050,7 @@ static int zr36057_init (struct zoran *z
 	 *   Now add the template and register the device unit.
 	 */
 	memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
-	zr->video_dev->parent = &zr->pci_dev->dev;
+	zr->video_dev->v4l2_dev = &zr->v4l2_dev;
 	strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
 	/* It's not a mem2mem device, but you can both capture and output from
 	   one and the same device. This should really be split up into two
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/pci/zoran/zoran_driver.c linux-libre-3.11-rc7-gnu/drivers/media/pci/zoran/zoran_driver.c
--- linux-libre-3.10-gnu/drivers/media/pci/zoran/zoran_driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/pci/zoran/zoran_driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -1456,29 +1456,6 @@ zoran_set_norm (struct zoran *zr,
 		return -EINVAL;
 	}
 
-	if (norm == V4L2_STD_ALL) {
-		unsigned int status = 0;
-		v4l2_std_id std = 0;
-
-		decoder_call(zr, video, querystd, &std);
-		decoder_call(zr, core, s_std, std);
-
-		/* let changes come into effect */
-		ssleep(2);
-
-		decoder_call(zr, video, g_input_status, &status);
-		if (status & V4L2_IN_ST_NO_SIGNAL) {
-			dprintk(1,
-				KERN_ERR
-				"%s: %s - no norm detected\n",
-				ZR_DEVNAME(zr), __func__);
-			/* reset norm */
-			decoder_call(zr, core, s_std, zr->norm);
-			return -EIO;
-		}
-
-		norm = std;
-	}
 	if (norm & V4L2_STD_SECAM)
 		zr->timing = zr->card.tvn[2];
 	else if (norm & V4L2_STD_NTSC)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/blackfin/bfin_capture.c linux-libre-3.11-rc7-gnu/drivers/media/platform/blackfin/bfin_capture.c
--- linux-libre-3.10-gnu/drivers/media/platform/blackfin/bfin_capture.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/blackfin/bfin_capture.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/time.h>
 #include <linux/types.h>
 
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
@@ -649,18 +648,30 @@ static int bcap_s_std(struct file *file,
 	return 0;
 }
 
-static int bcap_g_dv_timings(struct file *file, void *priv,
+static int bcap_enum_dv_timings(struct file *file, void *priv,
+				struct v4l2_enum_dv_timings *timings)
+{
+	struct bcap_device *bcap_dev = video_drvdata(file);
+
+	return v4l2_subdev_call(bcap_dev->sd, video,
+			enum_dv_timings, timings);
+}
+
+static int bcap_query_dv_timings(struct file *file, void *priv,
 				struct v4l2_dv_timings *timings)
 {
 	struct bcap_device *bcap_dev = video_drvdata(file);
-	int ret;
 
-	ret = v4l2_subdev_call(bcap_dev->sd, video,
-				g_dv_timings, timings);
-	if (ret < 0)
-		return ret;
+	return v4l2_subdev_call(bcap_dev->sd, video,
+				query_dv_timings, timings);
+}
 
-	bcap_dev->dv_timings = *timings;
+static int bcap_g_dv_timings(struct file *file, void *priv,
+				struct v4l2_dv_timings *timings)
+{
+	struct bcap_device *bcap_dev = video_drvdata(file);
+
+	*timings = bcap_dev->dv_timings;
 	return 0;
 }
 
@@ -864,41 +875,6 @@ static int bcap_s_parm(struct file *file
 	return v4l2_subdev_call(bcap_dev->sd, video, s_parm, a);
 }
 
-static int bcap_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct bcap_device *bcap_dev = video_drvdata(file);
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-			chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	return v4l2_subdev_call(bcap_dev->sd, core,
-			g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int bcap_dbg_g_register(struct file *file, void *priv,
-		struct v4l2_dbg_register *reg)
-{
-	struct bcap_device *bcap_dev = video_drvdata(file);
-
-	return v4l2_subdev_call(bcap_dev->sd, core,
-			g_register, reg);
-}
-
-static int bcap_dbg_s_register(struct file *file, void *priv,
-		const struct v4l2_dbg_register *reg)
-{
-	struct bcap_device *bcap_dev = video_drvdata(file);
-
-	return v4l2_subdev_call(bcap_dev->sd, core,
-			s_register, reg);
-}
-#endif
-
 static int bcap_log_status(struct file *file, void *priv)
 {
 	struct bcap_device *bcap_dev = video_drvdata(file);
@@ -921,6 +897,8 @@ static const struct v4l2_ioctl_ops bcap_
 	.vidioc_g_std            = bcap_g_std,
 	.vidioc_s_dv_timings     = bcap_s_dv_timings,
 	.vidioc_g_dv_timings     = bcap_g_dv_timings,
+	.vidioc_query_dv_timings = bcap_query_dv_timings,
+	.vidioc_enum_dv_timings  = bcap_enum_dv_timings,
 	.vidioc_reqbufs          = bcap_reqbufs,
 	.vidioc_querybuf         = bcap_querybuf,
 	.vidioc_qbuf             = bcap_qbuf,
@@ -929,11 +907,6 @@ static const struct v4l2_ioctl_ops bcap_
 	.vidioc_streamoff        = bcap_streamoff,
 	.vidioc_g_parm           = bcap_g_parm,
 	.vidioc_s_parm           = bcap_s_parm,
-	.vidioc_g_chip_ident     = bcap_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register       = bcap_dbg_g_register,
-	.vidioc_s_register       = bcap_dbg_s_register,
-#endif
 	.vidioc_log_status       = bcap_log_status,
 };
 
@@ -960,7 +933,7 @@ static int bcap_probe(struct platform_de
 	int ret;
 
 	config = pdev->dev.platform_data;
-	if (!config) {
+	if (!config || !config->num_inputs) {
 		v4l2_err(pdev->dev.driver, "Unable to get board config\n");
 		return -ENODEV;
 	}
@@ -1031,7 +1004,9 @@ static int bcap_probe(struct platform_de
 	q->mem_ops = &vb2_dma_contig_memops;
 	q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
-	vb2_queue_init(q);
+	ret = vb2_queue_init(q);
+	if (ret)
+		goto err_free_handler;
 
 	mutex_init(&bcap_dev->mutex);
 	init_completion(&bcap_dev->comp);
@@ -1067,11 +1042,6 @@ static int bcap_probe(struct platform_de
 						 NULL);
 	if (bcap_dev->sd) {
 		int i;
-		if (!config->num_inputs) {
-			v4l2_err(&bcap_dev->v4l2_dev,
-					"Unable to work without input\n");
-			goto err_unreg_vdev;
-		}
 
 		/* update tvnorms from the sub devices */
 		for (i = 0; i < config->num_inputs; i++)
@@ -1079,6 +1049,7 @@ static int bcap_probe(struct platform_de
 	} else {
 		v4l2_err(&bcap_dev->v4l2_dev,
 				"Unable to register sub device\n");
+		ret = -ENODEV;
 		goto err_unreg_vdev;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/blackfin/ppi.c linux-libre-3.11-rc7-gnu/drivers/media/platform/blackfin/ppi.c
--- linux-libre-3.10-gnu/drivers/media/platform/blackfin/ppi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/blackfin/ppi.c	2013-08-25 20:43:22.000000000 -0400
@@ -266,6 +266,18 @@ static int ppi_set_params(struct ppi_if
 		bfin_write32(&reg->vcnt, params->height);
 		if (params->int_mask)
 			bfin_write32(&reg->imsk, params->int_mask & 0xFF);
+		if (ppi->ppi_control & PORT_DIR) {
+			u32 hsync_width, vsync_width, vsync_period;
+
+			hsync_width = params->hsync
+					* params->bpp / params->dlen;
+			vsync_width = params->vsync * samples_per_line;
+			vsync_period = samples_per_line * params->frame;
+			bfin_write32(&reg->fs1_wlhb, hsync_width);
+			bfin_write32(&reg->fs1_paspl, samples_per_line);
+			bfin_write32(&reg->fs2_wlvb, vsync_width);
+			bfin_write32(&reg->fs2_palpf, vsync_period);
+		}
 		break;
 	}
 	default:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/coda.c linux-libre-3.11-rc7-gnu/drivers/media/platform/coda.c
--- linux-libre-3.10-gnu/drivers/media/platform/coda.c	2013-07-01 10:34:49.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/coda.c	2013-08-31 17:54:20.000000000 -0400
@@ -49,16 +49,14 @@
 
 #define CODA_MAX_FRAMEBUFFERS	2
 
-#define MAX_W		720
-#define MAX_H		576
-#define CODA_MAX_FRAME_SIZE	0x90000
+#define MAX_W		8192
+#define MAX_H		8192
+#define CODA_MAX_FRAME_SIZE	0x100000
 #define FMO_SLICE_SAVE_BUF_SIZE         (32)
 #define CODA_DEFAULT_GAMMA		4096
 
 #define MIN_W 176
 #define MIN_H 144
-#define MAX_W 720
-#define MAX_H 576
 
 #define S_ALIGN		1 /* multiple of 2 */
 #define W_ALIGN		1 /* multiple of 2 */
@@ -67,7 +65,7 @@
 #define fh_to_ctx(__fh)	container_of(__fh, struct coda_ctx, fh)
 
 static int coda_debug;
-module_param(coda_debug, int, 0);
+module_param(coda_debug, int, 0644);
 MODULE_PARM_DESC(coda_debug, "Debug level (0-1)");
 
 enum {
@@ -75,11 +73,6 @@ enum {
 	V4L2_M2M_DST = 1,
 };
 
-enum coda_fmt_type {
-	CODA_FMT_ENC,
-	CODA_FMT_RAW,
-};
-
 enum coda_inst_type {
 	CODA_INST_ENCODER,
 	CODA_INST_DECODER,
@@ -93,14 +86,21 @@ enum coda_product {
 struct coda_fmt {
 	char *name;
 	u32 fourcc;
-	enum coda_fmt_type type;
+};
+
+struct coda_codec {
+	u32 mode;
+	u32 src_fourcc;
+	u32 dst_fourcc;
+	u32 max_w;
+	u32 max_h;
 };
 
 struct coda_devtype {
 	char			*firmware;
 	enum coda_product	product;
-	struct coda_fmt		*formats;
-	unsigned int		num_formats;
+	struct coda_codec	*codecs;
+	unsigned int		num_codecs;
 	size_t			workbuf_size;
 };
 
@@ -109,7 +109,7 @@ struct coda_q_data {
 	unsigned int		width;
 	unsigned int		height;
 	unsigned int		sizeimage;
-	struct coda_fmt	*fmt;
+	unsigned int		fourcc;
 };
 
 struct coda_aux_buf {
@@ -137,12 +137,12 @@ struct coda_dev {
 
 	spinlock_t		irqlock;
 	struct mutex		dev_mutex;
+	struct mutex		coda_mutex;
 	struct v4l2_m2m_dev	*m2m_dev;
 	struct vb2_alloc_ctx	*alloc_ctx;
 	struct list_head	instances;
 	unsigned long		instance_mask;
 	struct delayed_work	timeout;
-	struct completion	done;
 };
 
 struct coda_params {
@@ -164,11 +164,12 @@ struct coda_ctx {
 	struct coda_dev			*dev;
 	struct list_head		list;
 	int				aborting;
-	int				rawstreamon;
-	int				compstreamon;
+	int				streamon_out;
+	int				streamon_cap;
 	u32				isequence;
 	struct coda_q_data		q_data[2];
 	enum coda_inst_type		inst_type;
+	struct coda_codec		*codec;
 	enum v4l2_colorspace		colorspace;
 	struct coda_params		params;
 	struct v4l2_m2m_ctx		*m2m_ctx;
@@ -257,62 +258,89 @@ static struct coda_q_data *get_q_data(st
 }
 
 /*
- * Add one array of supported formats for each version of Coda:
- *  i.MX27 -> codadx6
- *  i.MX51 -> coda7
- *  i.MX6  -> coda960
+ * Array of all formats supported by any version of Coda:
  */
-static struct coda_fmt codadx6_formats[] = {
+static struct coda_fmt coda_formats[] = {
 	{
-		.name = "YUV 4:2:0 Planar",
+		.name = "YUV 4:2:0 Planar, YCbCr",
 		.fourcc = V4L2_PIX_FMT_YUV420,
-		.type = CODA_FMT_RAW,
-	},
-	{
-		.name = "H264 Encoded Stream",
-		.fourcc = V4L2_PIX_FMT_H264,
-		.type = CODA_FMT_ENC,
-	},
-	{
-		.name = "MPEG4 Encoded Stream",
-		.fourcc = V4L2_PIX_FMT_MPEG4,
-		.type = CODA_FMT_ENC,
 	},
-};
-
-static struct coda_fmt coda7_formats[] = {
 	{
-		.name = "YUV 4:2:0 Planar",
-		.fourcc = V4L2_PIX_FMT_YUV420,
-		.type = CODA_FMT_RAW,
+		.name = "YUV 4:2:0 Planar, YCrCb",
+		.fourcc = V4L2_PIX_FMT_YVU420,
 	},
 	{
 		.name = "H264 Encoded Stream",
 		.fourcc = V4L2_PIX_FMT_H264,
-		.type = CODA_FMT_ENC,
 	},
 	{
 		.name = "MPEG4 Encoded Stream",
 		.fourcc = V4L2_PIX_FMT_MPEG4,
-		.type = CODA_FMT_ENC,
 	},
 };
 
-static struct coda_fmt *find_format(struct coda_dev *dev, struct v4l2_format *f)
+#define CODA_CODEC(mode, src_fourcc, dst_fourcc, max_w, max_h) \
+	{ mode, src_fourcc, dst_fourcc, max_w, max_h }
+
+/*
+ * Arrays of codecs supported by each given version of Coda:
+ *  i.MX27 -> codadx6
+ *  i.MX5x -> coda7
+ *  i.MX6  -> coda960
+ * Use V4L2_PIX_FMT_YUV420 as placeholder for all supported YUV 4:2:0 variants
+ */
+static struct coda_codec codadx6_codecs[] = {
+	CODA_CODEC(CODADX6_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264,  720, 576),
+	CODA_CODEC(CODADX6_MODE_ENCODE_MP4,  V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 720, 576),
+};
+
+static struct coda_codec coda7_codecs[] = {
+	CODA_CODEC(CODA7_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264,   1280, 720),
+	CODA_CODEC(CODA7_MODE_ENCODE_MP4,  V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4,  1280, 720),
+};
+
+static bool coda_format_is_yuv(u32 fourcc)
 {
-	struct coda_fmt *formats = dev->devtype->formats;
-	int num_formats = dev->devtype->num_formats;
-	unsigned int k;
+	switch (fourcc) {
+	case V4L2_PIX_FMT_YUV420:
+	case V4L2_PIX_FMT_YVU420:
+		return true;
+	default:
+		return false;
+	}
+}
 
-	for (k = 0; k < num_formats; k++) {
-		if (formats[k].fourcc == f->fmt.pix.pixelformat)
+/*
+ * Normalize all supported YUV 4:2:0 formats to the value used in the codec
+ * tables.
+ */
+static u32 coda_format_normalize_yuv(u32 fourcc)
+{
+	return coda_format_is_yuv(fourcc) ? V4L2_PIX_FMT_YUV420 : fourcc;
+}
+
+static struct coda_codec *coda_find_codec(struct coda_dev *dev, int src_fourcc,
+					  int dst_fourcc)
+{
+	struct coda_codec *codecs = dev->devtype->codecs;
+	int num_codecs = dev->devtype->num_codecs;
+	int k;
+
+	src_fourcc = coda_format_normalize_yuv(src_fourcc);
+	dst_fourcc = coda_format_normalize_yuv(dst_fourcc);
+	if (src_fourcc == dst_fourcc)
+		return NULL;
+
+	for (k = 0; k < num_codecs; k++) {
+		if (codecs[k].src_fourcc == src_fourcc &&
+		    codecs[k].dst_fourcc == dst_fourcc)
 			break;
 	}
 
-	if (k == num_formats)
+	if (k == num_codecs)
 		return NULL;
 
-	return &formats[k];
+	return &codecs[k];
 }
 
 /*
@@ -323,7 +351,7 @@ static int vidioc_querycap(struct file *
 {
 	strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver));
 	strlcpy(cap->card, CODA_NAME, sizeof(cap->card));
-	strlcpy(cap->bus_info, CODA_NAME, sizeof(cap->bus_info));
+	strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info));
 	/*
 	 * This is only a mem-to-mem video device. The capture and output
 	 * device capability flags are left only for backward compatibility
@@ -337,17 +365,34 @@ static int vidioc_querycap(struct file *
 }
 
 static int enum_fmt(void *priv, struct v4l2_fmtdesc *f,
-			enum coda_fmt_type type)
+			enum v4l2_buf_type type)
 {
 	struct coda_ctx *ctx = fh_to_ctx(priv);
-	struct coda_dev *dev = ctx->dev;
-	struct coda_fmt *formats = dev->devtype->formats;
+	struct coda_codec *codecs = ctx->dev->devtype->codecs;
+	struct coda_fmt *formats = coda_formats;
 	struct coda_fmt *fmt;
-	int num_formats = dev->devtype->num_formats;
-	int i, num = 0;
+	int num_codecs = ctx->dev->devtype->num_codecs;
+	int num_formats = ARRAY_SIZE(coda_formats);
+	int i, k, num = 0;
 
 	for (i = 0; i < num_formats; i++) {
-		if (formats[i].type == type) {
+		/* Both uncompressed formats are always supported */
+		if (coda_format_is_yuv(formats[i].fourcc)) {
+			if (num == f->index)
+				break;
+			++num;
+			continue;
+		}
+		/* Compressed formats may be supported, check the codec list */
+		for (k = 0; k < num_codecs; k++) {
+			if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+			    formats[i].fourcc == codecs[k].dst_fourcc)
+				break;
+			if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+			    formats[i].fourcc == codecs[k].src_fourcc)
+				break;
+		}
+		if (k < num_codecs) {
 			if (num == f->index)
 				break;
 			++num;
@@ -368,13 +413,13 @@ static int enum_fmt(void *priv, struct v
 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
 				   struct v4l2_fmtdesc *f)
 {
-	return enum_fmt(priv, f, CODA_FMT_ENC);
+	return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 }
 
 static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
 				   struct v4l2_fmtdesc *f)
 {
-	return enum_fmt(priv, f, CODA_FMT_RAW);
+	return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT);
 }
 
 static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
@@ -390,10 +435,10 @@ static int vidioc_g_fmt(struct file *fil
 	q_data = get_q_data(ctx, f->type);
 
 	f->fmt.pix.field	= V4L2_FIELD_NONE;
-	f->fmt.pix.pixelformat	= q_data->fmt->fourcc;
+	f->fmt.pix.pixelformat	= q_data->fourcc;
 	f->fmt.pix.width	= q_data->width;
 	f->fmt.pix.height	= q_data->height;
-	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
+	if (coda_format_is_yuv(f->fmt.pix.pixelformat))
 		f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
 	else /* encoded formats h.264/mpeg4 */
 		f->fmt.pix.bytesperline = 0;
@@ -404,8 +449,9 @@ static int vidioc_g_fmt(struct file *fil
 	return 0;
 }
 
-static int vidioc_try_fmt(struct coda_dev *dev, struct v4l2_format *f)
+static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f)
 {
+	unsigned int max_w, max_h;
 	enum v4l2_field field;
 
 	field = f->fmt.pix.field;
@@ -418,12 +464,21 @@ static int vidioc_try_fmt(struct coda_de
 	 * if any of the dimensions is unsupported */
 	f->fmt.pix.field = field;
 
-	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
-		v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
-				      W_ALIGN, &f->fmt.pix.height,
-				      MIN_H, MAX_H, H_ALIGN, S_ALIGN);
-		f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
-		f->fmt.pix.sizeimage = f->fmt.pix.width *
+	if (codec) {
+		max_w = codec->max_w;
+		max_h = codec->max_h;
+	} else {
+		max_w = MAX_W;
+		max_h = MAX_H;
+	}
+	v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w,
+			      W_ALIGN, &f->fmt.pix.height,
+			      MIN_H, max_h, H_ALIGN, S_ALIGN);
+
+	if (coda_format_is_yuv(f->fmt.pix.pixelformat)) {
+		/* Frame stride must be multiple of 8 */
+		f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8);
+		f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
 					f->fmt.pix.height * 3 / 2;
 	} else { /*encoded formats h.264/mpeg4 */
 		f->fmt.pix.bytesperline = 0;
@@ -436,57 +491,38 @@ static int vidioc_try_fmt(struct coda_de
 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 				  struct v4l2_format *f)
 {
-	int ret;
-	struct coda_fmt *fmt;
 	struct coda_ctx *ctx = fh_to_ctx(priv);
+	struct coda_codec *codec = NULL;
 
-	fmt = find_format(ctx->dev, f);
-	/*
-	 * Since decoding support is not implemented yet do not allow
-	 * CODA_FMT_RAW formats in the capture interface.
-	 */
-	if (!fmt || !(fmt->type == CODA_FMT_ENC))
-		f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
+	/* Determine codec by the encoded format */
+	codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420,
+				f->fmt.pix.pixelformat);
 
 	f->fmt.pix.colorspace = ctx->colorspace;
 
-	ret = vidioc_try_fmt(ctx->dev, f);
-	if (ret < 0)
-		return ret;
-
-	return 0;
+	return vidioc_try_fmt(codec, f);
 }
 
 static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
 				  struct v4l2_format *f)
 {
 	struct coda_ctx *ctx = fh_to_ctx(priv);
-	struct coda_fmt *fmt;
-	int ret;
+	struct coda_codec *codec;
 
-	fmt = find_format(ctx->dev, f);
-	/*
-	 * Since decoding support is not implemented yet do not allow
-	 * CODA_FMT formats in the capture interface.
-	 */
-	if (!fmt || !(fmt->type == CODA_FMT_RAW))
-		f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+	/* Determine codec by encoded format, returns NULL if raw or invalid */
+	codec = coda_find_codec(ctx->dev, f->fmt.pix.pixelformat,
+				V4L2_PIX_FMT_YUV420);
 
 	if (!f->fmt.pix.colorspace)
 		f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
 
-	ret = vidioc_try_fmt(ctx->dev, f);
-	if (ret < 0)
-		return ret;
-
-	return 0;
+	return vidioc_try_fmt(codec, f);
 }
 
 static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
 {
 	struct coda_q_data *q_data;
 	struct vb2_queue *vq;
-	int ret;
 
 	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
 	if (!vq)
@@ -501,18 +537,14 @@ static int vidioc_s_fmt(struct coda_ctx
 		return -EBUSY;
 	}
 
-	ret = vidioc_try_fmt(ctx->dev, f);
-	if (ret)
-		return ret;
-
-	q_data->fmt = find_format(ctx->dev, f);
+	q_data->fourcc = f->fmt.pix.pixelformat;
 	q_data->width = f->fmt.pix.width;
 	q_data->height = f->fmt.pix.height;
 	q_data->sizeimage = f->fmt.pix.sizeimage;
 
 	v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 		"Setting format for type %d, wxh: %dx%d, fmt: %d\n",
-		f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
+		f->type, q_data->width, q_data->height, q_data->fourcc);
 
 	return 0;
 }
@@ -520,13 +552,14 @@ static int vidioc_s_fmt(struct coda_ctx
 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
+	struct coda_ctx *ctx = fh_to_ctx(priv);
 	int ret;
 
 	ret = vidioc_try_fmt_vid_cap(file, priv, f);
 	if (ret)
 		return ret;
 
-	return vidioc_s_fmt(fh_to_ctx(priv), f);
+	return vidioc_s_fmt(ctx, f);
 }
 
 static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
@@ -569,6 +602,14 @@ static int vidioc_qbuf(struct file *file
 	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
 }
 
+static int vidioc_expbuf(struct file *file, void *priv,
+			 struct v4l2_exportbuffer *eb)
+{
+	struct coda_ctx *ctx = fh_to_ctx(priv);
+
+	return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
+}
+
 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 {
 	struct coda_ctx *ctx = fh_to_ctx(priv);
@@ -617,6 +658,7 @@ static const struct v4l2_ioctl_ops coda_
 	.vidioc_querybuf	= vidioc_querybuf,
 
 	.vidioc_qbuf		= vidioc_qbuf,
+	.vidioc_expbuf		= vidioc_expbuf,
 	.vidioc_dqbuf		= vidioc_dqbuf,
 	.vidioc_create_bufs	= vidioc_create_bufs,
 
@@ -639,11 +681,13 @@ static void coda_device_run(void *m2m_pr
 	u32 pic_stream_buffer_addr, pic_stream_buffer_size;
 	u32 dst_fourcc;
 
+	mutex_lock(&dev->coda_mutex);
+
 	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
 	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
 	q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
 	q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	dst_fourcc = q_data_dst->fmt->fourcc;
+	dst_fourcc = q_data_dst->fourcc;
 
 	src_buf->v4l2_buf.sequence = ctx->isequence;
 	dst_buf->v4l2_buf.sequence = ctx->isequence;
@@ -725,9 +769,20 @@ static void coda_device_run(void *m2m_pr
 
 
 	picture_y = vb2_dma_contig_plane_dma_addr(src_buf, 0);
-	picture_cb = picture_y + q_data_src->width * q_data_src->height;
-	picture_cr = picture_cb + q_data_src->width / 2 *
-			q_data_src->height / 2;
+	switch (q_data_src->fourcc) {
+	case V4L2_PIX_FMT_YVU420:
+		/* Switch Cb and Cr for YVU420 format */
+		picture_cr = picture_y + q_data_src->width * q_data_src->height;
+		picture_cb = picture_cr + q_data_src->width / 2 *
+				q_data_src->height / 2;
+		break;
+	case V4L2_PIX_FMT_YUV420:
+	default:
+		picture_cb = picture_y + q_data_src->width * q_data_src->height;
+		picture_cr = picture_cb + q_data_src->width / 2 *
+				q_data_src->height / 2;
+		break;
+	}
 
 	coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y);
 	coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB);
@@ -748,7 +803,6 @@ static void coda_device_run(void *m2m_pr
 	/* 1 second timeout in case CODA locks up */
 	schedule_delayed_work(&dev->timeout, HZ);
 
-	INIT_COMPLETION(dev->done);
 	coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
 }
 
@@ -767,6 +821,12 @@ static int coda_job_ready(void *m2m_priv
 		return 0;
 	}
 
+	if (ctx->aborting) {
+		v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+			 "not ready: aborting\n");
+		return 0;
+	}
+
 	v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 			"job ready\n");
 	return 1;
@@ -775,14 +835,11 @@ static int coda_job_ready(void *m2m_priv
 static void coda_job_abort(void *priv)
 {
 	struct coda_ctx *ctx = priv;
-	struct coda_dev *dev = ctx->dev;
 
 	ctx->aborting = 1;
 
 	v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 		 "Aborting task\n");
-
-	v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx);
 }
 
 static void coda_lock(void *m2m_priv)
@@ -809,7 +866,12 @@ static struct v4l2_m2m_ops coda_m2m_ops
 
 static void set_default_params(struct coda_ctx *ctx)
 {
-	struct coda_dev *dev = ctx->dev;
+	int max_w;
+	int max_h;
+
+	ctx->codec = &ctx->dev->devtype->codecs[0];
+	max_w = ctx->codec->max_w;
+	max_h = ctx->codec->max_h;
 
 	ctx->params.codec_mode = CODA_MODE_INVALID;
 	ctx->colorspace = V4L2_COLORSPACE_REC709;
@@ -817,13 +879,13 @@ static void set_default_params(struct co
 	ctx->aborting = 0;
 
 	/* Default formats for output and input queues */
-	ctx->q_data[V4L2_M2M_SRC].fmt = &dev->devtype->formats[0];
-	ctx->q_data[V4L2_M2M_DST].fmt = &dev->devtype->formats[1];
-	ctx->q_data[V4L2_M2M_SRC].width = MAX_W;
-	ctx->q_data[V4L2_M2M_SRC].height = MAX_H;
-	ctx->q_data[V4L2_M2M_SRC].sizeimage = (MAX_W * MAX_H * 3) / 2;
-	ctx->q_data[V4L2_M2M_DST].width = MAX_W;
-	ctx->q_data[V4L2_M2M_DST].height = MAX_H;
+	ctx->q_data[V4L2_M2M_SRC].fourcc = ctx->codec->src_fourcc;
+	ctx->q_data[V4L2_M2M_DST].fourcc = ctx->codec->dst_fourcc;
+	ctx->q_data[V4L2_M2M_SRC].width = max_w;
+	ctx->q_data[V4L2_M2M_SRC].height = max_h;
+	ctx->q_data[V4L2_M2M_SRC].sizeimage = (max_w * max_h * 3) / 2;
+	ctx->q_data[V4L2_M2M_DST].width = max_w;
+	ctx->q_data[V4L2_M2M_DST].height = max_h;
 	ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE;
 }
 
@@ -868,8 +930,6 @@ static int coda_buf_prepare(struct vb2_b
 		return -EINVAL;
 	}
 
-	vb2_set_plane_payload(vb, 0, q_data->sizeimage);
-
 	return 0;
 }
 
@@ -906,21 +966,34 @@ static void coda_free_framebuffers(struc
 	}
 }
 
+static void coda_parabuf_write(struct coda_ctx *ctx, int index, u32 value)
+{
+	struct coda_dev *dev = ctx->dev;
+	u32 *p = ctx->parabuf.vaddr;
+
+	if (dev->devtype->product == CODA_DX6)
+		p[index] = value;
+	else
+		p[index ^ 1] = value;
+}
+
 static int coda_alloc_framebuffers(struct coda_ctx *ctx, struct coda_q_data *q_data, u32 fourcc)
 {
 	struct coda_dev *dev = ctx->dev;
 
 	int height = q_data->height;
-	int width = q_data->width;
-	u32 *p;
+	dma_addr_t paddr;
+	int ysize;
 	int i;
 
+	ysize = round_up(q_data->width, 8) * height;
+
 	/* Allocate frame buffers */
 	ctx->num_internal_frames = CODA_MAX_FRAMEBUFFERS;
 	for (i = 0; i < ctx->num_internal_frames; i++) {
 		ctx->internal_frames[i].size = q_data->sizeimage;
 		if (fourcc == V4L2_PIX_FMT_H264 && dev->devtype->product != CODA_DX6)
-			ctx->internal_frames[i].size += width / 2 * height / 2;
+			ctx->internal_frames[i].size += ysize/4;
 		ctx->internal_frames[i].vaddr = dma_alloc_coherent(
 				&dev->plat_dev->dev, ctx->internal_frames[i].size,
 				&ctx->internal_frames[i].paddr, GFP_KERNEL);
@@ -931,32 +1004,14 @@ static int coda_alloc_framebuffers(struc
 	}
 
 	/* Register frame buffers in the parameter buffer */
-	p = ctx->parabuf.vaddr;
-
-	if (dev->devtype->product == CODA_DX6) {
-		for (i = 0; i < ctx->num_internal_frames; i++) {
-			p[i * 3] = ctx->internal_frames[i].paddr; /* Y */
-			p[i * 3 + 1] = p[i * 3] + width * height; /* Cb */
-			p[i * 3 + 2] = p[i * 3 + 1] + width / 2 * height / 2; /* Cr */
-		}
-	} else {
-		for (i = 0; i < ctx->num_internal_frames; i += 2) {
-			p[i * 3 + 1] = ctx->internal_frames[i].paddr; /* Y */
-			p[i * 3] = p[i * 3 + 1] + width * height; /* Cb */
-			p[i * 3 + 3] = p[i * 3] + (width / 2) * (height / 2); /* Cr */
-
-			if (fourcc == V4L2_PIX_FMT_H264)
-				p[96 + i + 1] = p[i * 3 + 3] + (width / 2) * (height / 2);
-
-			if (i + 1 < ctx->num_internal_frames) {
-				p[i * 3 + 2] = ctx->internal_frames[i+1].paddr; /* Y */
-				p[i * 3 + 5] = p[i * 3 + 2] + width * height ; /* Cb */
-				p[i * 3 + 4] = p[i * 3 + 5] + (width / 2) * (height / 2); /* Cr */
+	for (i = 0; i < ctx->num_internal_frames; i++) {
+		paddr = ctx->internal_frames[i].paddr;
+		coda_parabuf_write(ctx, i * 3 + 0, paddr); /* Y */
+		coda_parabuf_write(ctx, i * 3 + 1, paddr + ysize); /* Cb */
+		coda_parabuf_write(ctx, i * 3 + 2, paddr + ysize + ysize/4); /* Cr */
 
-				if (fourcc == V4L2_PIX_FMT_H264)
-					p[96 + i] = p[i * 3 + 4] + (width / 2) * (height / 2);
-			}
-		}
+		if (dev->devtype->product != CODA_DX6 && fourcc == V4L2_PIX_FMT_H264)
+			coda_parabuf_write(ctx, 96 + i, ctx->internal_frames[i].paddr + ysize + ysize/4 + ysize/4);
 	}
 
 	return 0;
@@ -980,6 +1035,28 @@ static int coda_h264_padding(int size, c
 	return nal_size;
 }
 
+static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
+			      int header_code, u8 *header, int *size)
+{
+	struct coda_dev *dev = ctx->dev;
+	int ret;
+
+	coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0),
+		   CODA_CMD_ENC_HEADER_BB_START);
+	coda_write(dev, vb2_plane_size(buf, 0), CODA_CMD_ENC_HEADER_BB_SIZE);
+	coda_write(dev, header_code, CODA_CMD_ENC_HEADER_CODE);
+	ret = coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER);
+	if (ret < 0) {
+		v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
+		return ret;
+	}
+	*size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
+		coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+	memcpy(header, vb2_plane_vaddr(buf, 0), *size);
+
+	return 0;
+}
+
 static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct coda_ctx *ctx = vb2_get_drv_priv(q);
@@ -990,43 +1067,38 @@ static int coda_start_streaming(struct v
 	struct vb2_buffer *buf;
 	u32 dst_fourcc;
 	u32 value;
-	int ret;
+	int ret = 0;
 
 	if (count < 1)
 		return -EINVAL;
 
 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		ctx->rawstreamon = 1;
+		ctx->streamon_out = 1;
 	else
-		ctx->compstreamon = 1;
+		ctx->streamon_cap = 1;
+
+	q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	if (ctx->streamon_out) {
+		if (coda_format_is_yuv(q_data_src->fourcc))
+			ctx->inst_type = CODA_INST_ENCODER;
+		else
+			ctx->inst_type = CODA_INST_DECODER;
+	}
 
 	/* Don't start the coda unless both queues are on */
-	if (!(ctx->rawstreamon & ctx->compstreamon))
+	if (!(ctx->streamon_out & ctx->streamon_cap))
 		return 0;
 
-	if (coda_isbusy(dev))
-		if (wait_for_completion_interruptible_timeout(&dev->done, HZ) <= 0)
-			return -EBUSY;
-
 	ctx->gopcounter = ctx->params.gop_size - 1;
-
-	q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
 	buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
 	bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
 	q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 	bitstream_size = q_data_dst->sizeimage;
-	dst_fourcc = q_data_dst->fmt->fourcc;
+	dst_fourcc = q_data_dst->fourcc;
 
-	/* Find out whether coda must encode or decode */
-	if (q_data_src->fmt->type == CODA_FMT_RAW &&
-	    q_data_dst->fmt->type == CODA_FMT_ENC) {
-		ctx->inst_type = CODA_INST_ENCODER;
-	} else if (q_data_src->fmt->type == CODA_FMT_ENC &&
-		   q_data_dst->fmt->type == CODA_FMT_RAW) {
-		ctx->inst_type = CODA_INST_DECODER;
-		v4l2_err(v4l2_dev, "decoding not supported.\n");
-		return -EINVAL;
-	} else {
+	ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc,
+				     q_data_dst->fourcc);
+	if (!ctx->codec) {
 		v4l2_err(v4l2_dev, "couldn't tell instance type.\n");
 		return -EINVAL;
 	}
@@ -1035,6 +1107,9 @@ static int coda_start_streaming(struct v
 		v4l2_err(v4l2_dev, "coda is not initialized.\n");
 		return -EFAULT;
 	}
+
+	mutex_lock(&dev->coda_mutex);
+
 	coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR);
 	coda_write(dev, bitstream_buf, CODA_REG_BIT_RD_PTR(ctx->idx));
 	coda_write(dev, bitstream_buf, CODA_REG_BIT_WR_PTR(ctx->idx));
@@ -1057,38 +1132,31 @@ static int coda_start_streaming(struct v
 	switch (dev->devtype->product) {
 	case CODA_DX6:
 		value = (q_data_src->width & CODADX6_PICWIDTH_MASK) << CODADX6_PICWIDTH_OFFSET;
+		value |= (q_data_src->height & CODADX6_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
 		break;
 	default:
 		value = (q_data_src->width & CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET;
+		value |= (q_data_src->height & CODA7_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
 	}
-	value |= (q_data_src->height & CODA_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
 	coda_write(dev, value, CODA_CMD_ENC_SEQ_SRC_SIZE);
 	coda_write(dev, ctx->params.framerate,
 		   CODA_CMD_ENC_SEQ_SRC_F_RATE);
 
+	ctx->params.codec_mode = ctx->codec->mode;
 	switch (dst_fourcc) {
 	case V4L2_PIX_FMT_MPEG4:
-		if (dev->devtype->product == CODA_DX6)
-			ctx->params.codec_mode = CODADX6_MODE_ENCODE_MP4;
-		else
-			ctx->params.codec_mode = CODA7_MODE_ENCODE_MP4;
-
 		coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
 		coda_write(dev, 0, CODA_CMD_ENC_SEQ_MP4_PARA);
 		break;
 	case V4L2_PIX_FMT_H264:
-		if (dev->devtype->product == CODA_DX6)
-			ctx->params.codec_mode = CODADX6_MODE_ENCODE_H264;
-		else
-			ctx->params.codec_mode = CODA7_MODE_ENCODE_H264;
-
 		coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
 		coda_write(dev, 0, CODA_CMD_ENC_SEQ_264_PARA);
 		break;
 	default:
 		v4l2_err(v4l2_dev,
 			 "dst format (0x%08x) invalid.\n", dst_fourcc);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	switch (ctx->params.slice_mode) {
@@ -1129,8 +1197,14 @@ static int coda_start_streaming(struct v
 	value = (CODA_DEFAULT_GAMMA & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET;
 	coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_GAMMA);
 
-	value  = (CODA_DEFAULT_GAMMA > 0) << CODA_OPTION_GAMMA_OFFSET;
-	value |= (0 & CODA_OPTION_SLICEREPORT_MASK) << CODA_OPTION_SLICEREPORT_OFFSET;
+	if (CODA_DEFAULT_GAMMA > 0) {
+		if (dev->devtype->product == CODA_DX6)
+			value  = 1 << CODADX6_OPTION_GAMMA_OFFSET;
+		else
+			value  = 1 << CODA7_OPTION_GAMMA_OFFSET;
+	} else {
+		value = 0;
+	}
 	coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION);
 
 	if (dst_fourcc == V4L2_PIX_FMT_H264) {
@@ -1145,17 +1219,23 @@ static int coda_start_streaming(struct v
 		}
 	}
 
-	if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
+	ret = coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT);
+	if (ret < 0) {
 		v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT timeout\n");
-		return -ETIMEDOUT;
+		goto out;
 	}
 
-	if (coda_read(dev, CODA_RET_ENC_SEQ_SUCCESS) == 0)
-		return -EFAULT;
+	if (coda_read(dev, CODA_RET_ENC_SEQ_SUCCESS) == 0) {
+		v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT failed\n");
+		ret = -EFAULT;
+		goto out;
+	}
 
 	ret = coda_alloc_framebuffers(ctx, q_data_src, dst_fourcc);
-	if (ret < 0)
-		return ret;
+	if (ret < 0) {
+		v4l2_err(v4l2_dev, "failed to allocate framebuffers\n");
+		goto out;
+	}
 
 	coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM);
 	coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
@@ -1167,9 +1247,10 @@ static int coda_start_streaming(struct v
 		coda_write(dev, dev->iram_paddr + 68 * 1024, CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
 		coda_write(dev, 0x0, CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
 	}
-	if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
+	ret = coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF);
+	if (ret < 0) {
 		v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
-		return -ETIMEDOUT;
+		goto out;
 	}
 
 	/* Save stream headers */
@@ -1180,33 +1261,22 @@ static int coda_start_streaming(struct v
 		 * Get SPS in the first frame and copy it to an
 		 * intermediate buffer.
 		 */
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_H264_SPS, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[0]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_SPS,
+					 &ctx->vpu_header[0][0],
+					 &ctx->vpu_header_size[0]);
+		if (ret < 0)
+			goto out;
 
 		/*
 		 * Get PPS in the first frame and copy it to an
 		 * intermediate buffer.
 		 */
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_H264_PPS, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[1]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_PPS,
+					 &ctx->vpu_header[1][0],
+					 &ctx->vpu_header_size[1]);
+		if (ret < 0)
+			goto out;
+
 		/*
 		 * Length of H.264 headers is variable and thus it might not be
 		 * aligned for the coda to append the encoded frame. In that is
@@ -1222,48 +1292,32 @@ static int coda_start_streaming(struct v
 		 * Get VOS in the first frame and copy it to an
 		 * intermediate buffer
 		 */
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_MP4V_VOS, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[0]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOS,
+					 &ctx->vpu_header[0][0],
+					 &ctx->vpu_header_size[0]);
+		if (ret < 0)
+			goto out;
 
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_MP4V_VIS, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[1]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VIS,
+					 &ctx->vpu_header[1][0],
+					 &ctx->vpu_header_size[1]);
+		if (ret < 0)
+			goto out;
 
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_MP4V_VOL, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[2] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[2][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[2]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOL,
+					 &ctx->vpu_header[2][0],
+					 &ctx->vpu_header_size[2]);
+		if (ret < 0)
+			goto out;
 		break;
 	default:
 		/* No more formats need to save headers at the moment */
 		break;
 	}
 
-	return 0;
+out:
+	mutex_unlock(&dev->coda_mutex);
+	return ret;
 }
 
 static int coda_stop_streaming(struct vb2_queue *q)
@@ -1274,26 +1328,20 @@ static int coda_stop_streaming(struct vb
 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
 		v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 			 "%s: output\n", __func__);
-		ctx->rawstreamon = 0;
+		ctx->streamon_out = 0;
 	} else {
 		v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 			 "%s: capture\n", __func__);
-		ctx->compstreamon = 0;
+		ctx->streamon_cap = 0;
 	}
 
 	/* Don't stop the coda unless both queues are off */
-	if (ctx->rawstreamon || ctx->compstreamon)
+	if (ctx->streamon_out || ctx->streamon_cap)
 		return 0;
 
-	if (coda_isbusy(dev)) {
-		if (wait_for_completion_interruptible_timeout(&dev->done, HZ) <= 0) {
-			v4l2_warn(&dev->v4l2_dev,
-				  "%s: timeout, sending SEQ_END anyway\n", __func__);
-		}
-	}
-
 	cancel_delayed_work(&dev->timeout);
 
+	mutex_lock(&dev->coda_mutex);
 	v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
 		 "%s: sent command 'SEQ_END' to coda\n", __func__);
 	if (coda_command_sync(ctx, CODA_COMMAND_SEQ_END)) {
@@ -1301,6 +1349,7 @@ static int coda_stop_streaming(struct vb
 			 "CODA_COMMAND_SEQ_END failed\n");
 		return -ETIMEDOUT;
 	}
+	mutex_unlock(&dev->coda_mutex);
 
 	coda_free_framebuffers(ctx);
 
@@ -1431,7 +1480,7 @@ static int coda_queue_init(void *priv, s
 	int ret;
 
 	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
 	src_vq->drv_priv = ctx;
 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	src_vq->ops = &coda_qops;
@@ -1443,7 +1492,7 @@ static int coda_queue_init(void *priv, s
 		return ret;
 
 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
 	dst_vq->drv_priv = ctx;
 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	dst_vq->ops = &coda_qops;
@@ -1484,7 +1533,7 @@ static int coda_open(struct file *file)
 	ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
 					 &coda_queue_init);
 	if (IS_ERR(ctx->m2m_ctx)) {
-		int ret = PTR_ERR(ctx->m2m_ctx);
+		ret = PTR_ERR(ctx->m2m_ctx);
 
 		v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n",
 			 __func__, ret);
@@ -1596,12 +1645,14 @@ static irqreturn_t coda_irq_handler(int
 	ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
 	if (ctx == NULL) {
 		v4l2_err(&dev->v4l2_dev, "Instance released before the end of transaction\n");
+		mutex_unlock(&dev->coda_mutex);
 		return IRQ_HANDLED;
 	}
 
 	if (ctx->aborting) {
 		v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 			 "task has been aborted\n");
+		mutex_unlock(&dev->coda_mutex);
 		return IRQ_HANDLED;
 	}
 
@@ -1611,8 +1662,6 @@ static irqreturn_t coda_irq_handler(int
 		return IRQ_NONE;
 	}
 
-	complete(&dev->done);
-
 	src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
 	dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
 
@@ -1660,6 +1709,8 @@ static irqreturn_t coda_irq_handler(int
 		(dst_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) ?
 		"KEYFRAME" : "PFRAME");
 
+	mutex_unlock(&dev->coda_mutex);
+
 	v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
 
 	return IRQ_HANDLED;
@@ -1671,12 +1722,7 @@ static void coda_timeout(struct work_str
 	struct coda_dev *dev = container_of(to_delayed_work(work),
 					    struct coda_dev, timeout);
 
-	if (completion_done(&dev->done))
-		return;
-
-	complete(&dev->done);
-
-	v4l2_err(&dev->v4l2_dev, "CODA PIC_RUN timeout, stopping all streams\n");
+	dev_err(&dev->plat_dev->dev, "CODA PIC_RUN timeout, stopping all streams\n");
 
 	mutex_lock(&dev->dev_mutex);
 	list_for_each_entry(ctx, &dev->instances, list) {
@@ -1684,6 +1730,10 @@ static void coda_timeout(struct work_str
 		v4l2_m2m_streamoff(NULL, ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 	}
 	mutex_unlock(&dev->dev_mutex);
+
+	mutex_unlock(&dev->coda_mutex);
+	ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
+	v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
 }
 
 static u32 coda_supported_firmwares[] = {
@@ -1748,6 +1798,10 @@ static int coda_hw_init(struct coda_dev
 		}
 	}
 
+	/* Clear registers */
+	for (i = 0; i < 64; i++)
+		coda_write(dev, 0, CODA_REG_BIT_CODE_BUF_ADDR + i * 4);
+
 	/* Tell the BIT where to find everything it needs */
 	coda_write(dev, dev->workbuf.paddr,
 		      CODA_REG_BIT_WORK_BUF_ADDR);
@@ -1912,15 +1966,15 @@ enum coda_platform {
 static const struct coda_devtype coda_devdata[] = {
 	[CODA_IMX27] = {
 		/*(DEBLOBBED)*/"/*(DEBLOBBED)*/",
-		.product     = CODA_DX6,
-		.formats     = codadx6_formats,
-		.num_formats = ARRAY_SIZE(codadx6_formats),
+		.product    = CODA_DX6,
+		.codecs     = codadx6_codecs,
+		.num_codecs = ARRAY_SIZE(codadx6_codecs),
 	},
 	[CODA_IMX53] = {
 		/*(DEBLOBBED)*/"/*(DEBLOBBED)*/",
-		.product     = CODA_7541,
-		.formats     = coda7_formats,
-		.num_formats = ARRAY_SIZE(coda7_formats),
+		.product    = CODA_7541,
+		.codecs     = coda7_codecs,
+		.num_codecs = ARRAY_SIZE(coda7_codecs),
 	},
 };
 
@@ -1933,7 +1987,7 @@ MODULE_DEVICE_TABLE(platform, coda_platf
 
 #ifdef CONFIG_OF
 static const struct of_device_id coda_dt_ids[] = {
-	{ .compatible = "fsl,imx27-vpu", .data = &coda_platform_ids[CODA_IMX27] },
+	{ .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] },
 	{ .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] },
 	{ /* sentinel */ }
 };
@@ -1962,8 +2016,6 @@ static int coda_probe(struct platform_de
 	spin_lock_init(&dev->irqlock);
 	INIT_LIST_HEAD(&dev->instances);
 	INIT_DELAYED_WORK(&dev->timeout, coda_timeout);
-	init_completion(&dev->done);
-	complete(&dev->done);
 
 	dev->plat_dev = pdev;
 	dev->clk_per = devm_clk_get(&pdev->dev, "per");
@@ -1985,17 +2037,9 @@ static int coda_probe(struct platform_de
 		return -ENOENT;
 	}
 
-	if (devm_request_mem_region(&pdev->dev, res->start,
-			resource_size(res), CODA_NAME) == NULL) {
-		dev_err(&pdev->dev, "failed to request memory region\n");
-		return -ENOENT;
-	}
-	dev->regs_base = devm_ioremap(&pdev->dev, res->start,
-				      resource_size(res));
-	if (!dev->regs_base) {
-		dev_err(&pdev->dev, "failed to ioremap address region\n");
-		return -ENOENT;
-	}
+	dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dev->regs_base))
+		return PTR_ERR(dev->regs_base);
 
 	/* IRQ */
 	irq = platform_get_irq(pdev, 0);
@@ -2025,6 +2069,7 @@ static int coda_probe(struct platform_de
 		return ret;
 
 	mutex_init(&dev->dev_mutex);
+	mutex_init(&dev->coda_mutex);
 
 	pdev_id = of_id ? of_id->data : platform_get_device_id(pdev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/coda.h linux-libre-3.11-rc7-gnu/drivers/media/platform/coda.h
--- linux-libre-3.10-gnu/drivers/media/platform/coda.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/coda.h	2013-08-25 20:43:22.000000000 -0400
@@ -96,16 +96,12 @@
 #define CODA_CMD_ENC_SEQ_BB_START				0x180
 #define CODA_CMD_ENC_SEQ_BB_SIZE				0x184
 #define CODA_CMD_ENC_SEQ_OPTION				0x188
-#define		CODA_OPTION_GAMMA_OFFSET			7
-#define		CODA_OPTION_GAMMA_MASK				0x01
+#define		CODA7_OPTION_GAMMA_OFFSET			8
+#define		CODADX6_OPTION_GAMMA_OFFSET			7
 #define		CODA_OPTION_LIMITQP_OFFSET			6
-#define		CODA_OPTION_LIMITQP_MASK			0x01
 #define		CODA_OPTION_RCINTRAQP_OFFSET			5
-#define		CODA_OPTION_RCINTRAQP_MASK			0x01
 #define		CODA_OPTION_FMO_OFFSET				4
-#define		CODA_OPTION_FMO_MASK				0x01
 #define		CODA_OPTION_SLICEREPORT_OFFSET			1
-#define		CODA_OPTION_SLICEREPORT_MASK			0x01
 #define CODA_CMD_ENC_SEQ_COD_STD				0x18c
 #define		CODA_STD_MPEG4					0
 #define		CODA_STD_H263					1
@@ -117,7 +113,8 @@
 #define		CODADX6_PICWIDTH_OFFSET				10
 #define		CODADX6_PICWIDTH_MASK				0x3ff
 #define		CODA_PICHEIGHT_OFFSET				0
-#define		CODA_PICHEIGHT_MASK				0x3ff
+#define		CODADX6_PICHEIGHT_MASK				0x3ff
+#define		CODA7_PICHEIGHT_MASK				0xffff
 #define CODA_CMD_ENC_SEQ_SRC_F_RATE				0x194
 #define CODA_CMD_ENC_SEQ_MP4_PARA				0x198
 #define		CODA_MP4PARAM_VERID_OFFSET			6
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/davinci/vpbe_display.c linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpbe_display.c
--- linux-libre-3.10-gnu/drivers/media/platform/davinci/vpbe_display.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpbe_display.c	2013-08-25 20:43:22.000000000 -0400
@@ -944,7 +944,7 @@ static int vpbe_display_s_fmt(struct fil
 	cfg->interlaced = vpbe_dev->current_timings.interlaced;
 
 	if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
-		cfg->pixfmt = PIXFMT_YCbCrI;
+		cfg->pixfmt = PIXFMT_YCBCRI;
 
 	/* Change of the default pixel format for both video windows */
 	if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
@@ -1593,31 +1593,6 @@ static int vpbe_display_release(struct f
 	return 0;
 }
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vpbe_display_g_register(struct file *file, void *priv,
-			struct v4l2_dbg_register *reg)
-{
-	struct v4l2_dbg_match *match = &reg->match;
-	struct vpbe_fh *fh = file->private_data;
-	struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
-	if (match->type >= 2) {
-		v4l2_subdev_call(vpbe_dev->venc,
-				 core,
-				 g_register,
-				 reg);
-	}
-
-	return 0;
-}
-
-static int vpbe_display_s_register(struct file *file, void *priv,
-			const struct v4l2_dbg_register *reg)
-{
-	return 0;
-}
-#endif
-
 /* vpbe capture ioctl operations */
 static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
 	.vidioc_querycap	 = vpbe_display_querycap,
@@ -1644,10 +1619,6 @@ static const struct v4l2_ioctl_ops vpbe_
 	.vidioc_s_dv_timings	 = vpbe_display_s_dv_timings,
 	.vidioc_g_dv_timings	 = vpbe_display_g_dv_timings,
 	.vidioc_enum_dv_timings	 = vpbe_display_enum_dv_timings,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register	 = vpbe_display_g_register,
-	.vidioc_s_register	 = vpbe_display_s_register,
-#endif
 };
 
 static struct v4l2_file_operations vpbe_fops = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/davinci/vpbe_osd.c linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpbe_osd.c
--- linux-libre-3.10-gnu/drivers/media/platform/davinci/vpbe_osd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpbe_osd.c	2013-08-25 20:43:22.000000000 -0400
@@ -119,7 +119,7 @@ static inline u32 osd_modify(struct osd_
 #define is_rgb_pixfmt(pixfmt) \
 	(((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888))
 #define is_yc_pixfmt(pixfmt) \
-	(((pixfmt) == PIXFMT_YCbCrI) || ((pixfmt) == PIXFMT_YCrCbI) || \
+	(((pixfmt) == PIXFMT_YCBCRI) || ((pixfmt) == PIXFMT_YCRCBI) || \
 	((pixfmt) == PIXFMT_NV12))
 #define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X
 #define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5)
@@ -360,8 +360,8 @@ static void _osd_enable_color_key(struct
 			osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
 				  OSD_TRANSPVALL);
 		break;
-	case PIXFMT_YCbCrI:
-	case PIXFMT_YCrCbI:
+	case PIXFMT_YCBCRI:
+	case PIXFMT_YCRCBI:
 		if (sd->vpbe_type == VPBE_VERSION_3)
 			osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
 				   OSD_TRANSPVALU);
@@ -813,8 +813,8 @@ static int try_layer_config(struct osd_s
 		if (osd->vpbe_type == VPBE_VERSION_1)
 			bad_config = !is_vid_win(layer);
 		break;
-	case PIXFMT_YCbCrI:
-	case PIXFMT_YCrCbI:
+	case PIXFMT_YCBCRI:
+	case PIXFMT_YCRCBI:
 		bad_config = !is_vid_win(layer);
 		break;
 	case PIXFMT_RGB888:
@@ -950,9 +950,9 @@ static void _osd_set_cbcr_order(struct o
 	 * The caller must ensure that all windows using YC pixfmt use the same
 	 * Cb/Cr order.
 	 */
-	if (pixfmt == PIXFMT_YCbCrI)
+	if (pixfmt == PIXFMT_YCBCRI)
 		osd_clear(sd, OSD_MODE_CS, OSD_MODE);
-	else if (pixfmt == PIXFMT_YCrCbI)
+	else if (pixfmt == PIXFMT_YCRCBI)
 		osd_set(sd, OSD_MODE_CS, OSD_MODE);
 }
 
@@ -981,8 +981,8 @@ static void _osd_set_layer_config(struct
 				winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
 				_osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
 				break;
-			case PIXFMT_YCbCrI:
-			case PIXFMT_YCrCbI:
+			case PIXFMT_YCBCRI:
+			case PIXFMT_YCRCBI:
 				winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
 				break;
 			default:
@@ -1128,8 +1128,8 @@ static void _osd_set_layer_config(struct
 					_osd_enable_rgb888_pixblend(sd,
 							OSDWIN_OSD1);
 					break;
-				case PIXFMT_YCbCrI:
-				case PIXFMT_YCrCbI:
+				case PIXFMT_YCBCRI:
+				case PIXFMT_YCRCBI:
 					winmd |=
 					    (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
 					break;
@@ -1508,7 +1508,7 @@ static int osd_initialize(struct osd_sta
 	_osd_init(osd);
 
 	/* set default Cb/Cr order */
-	osd->yc_pixfmt = PIXFMT_YCbCrI;
+	osd->yc_pixfmt = PIXFMT_YCBCRI;
 
 	if (osd->vpbe_type == VPBE_VERSION_3) {
 		/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif.c linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif.c
--- linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,30 +17,26 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/err.h>
 #include <linux/pm_runtime.h>
+#include <linux/spinlock.h>
 #include <linux/v4l2-dv-timings.h>
 
-#include <mach/hardware.h>
-
 #include "vpif.h"
 
 MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
 MODULE_LICENSE("GPL");
 
-#define VPIF_CH0_MAX_MODES	(22)
-#define VPIF_CH1_MAX_MODES	(02)
-#define VPIF_CH2_MAX_MODES	(15)
-#define VPIF_CH3_MAX_MODES	(02)
+#define VPIF_CH0_MAX_MODES	22
+#define VPIF_CH1_MAX_MODES	2
+#define VPIF_CH2_MAX_MODES	15
+#define VPIF_CH3_MAX_MODES	2
 
-static resource_size_t	res_len;
-static struct resource	*res;
 spinlock_t vpif_lock;
 
 void __iomem *vpif_base;
@@ -423,23 +419,12 @@ EXPORT_SYMBOL(vpif_channel_getfid);
 
 static int vpif_probe(struct platform_device *pdev)
 {
-	int status = 0;
+	static struct resource	*res;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENOENT;
-
-	res_len = resource_size(res);
-
-	res = request_mem_region(res->start, res_len, res->name);
-	if (!res)
-		return -EBUSY;
-
-	vpif_base = ioremap(res->start, res_len);
-	if (!vpif_base) {
-		status = -EBUSY;
-		goto fail;
-	}
+	vpif_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(vpif_base))
+		return PTR_ERR(vpif_base);
 
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get(&pdev->dev);
@@ -447,17 +432,11 @@ static int vpif_probe(struct platform_de
 	spin_lock_init(&vpif_lock);
 	dev_info(&pdev->dev, "vpif probe success\n");
 	return 0;
-
-fail:
-	release_mem_region(res->start, res_len);
-	return status;
 }
 
 static int vpif_remove(struct platform_device *pdev)
 {
 	pm_runtime_disable(&pdev->dev);
-	iounmap(vpif_base);
-	release_mem_region(res->start, res_len);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif_capture.c linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif_capture.c
--- linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif_capture.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif_capture.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,28 +18,16 @@
  * TODO : add support for VBI & HBI data service
  *	  add static buffer allocation
  */
-#include <linux/kernel.h>
-#include <linux/init.h>
+
 #include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/i2c.h>
 #include <linux/platform_device.h>
-#include <linux/io.h>
 #include <linux/slab.h>
-#include <media/v4l2-device.h>
+
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 
-#include "vpif_capture.h"
 #include "vpif.h"
+#include "vpif_capture.h"
 
 MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
 MODULE_LICENSE("GPL");
@@ -1874,66 +1862,6 @@ static int vpif_g_dv_timings(struct file
 }
 
 /*
- * vpif_g_chip_ident() - Identify the chip
- * @file: file ptr
- * @priv: file handle
- * @chip: chip identity
- *
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-			chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
-		vpif_dbg(2, debug, "match_type is invalid.\n");
-		return -EINVAL;
-	}
-
-	return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
-			g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * vpif_dbg_g_register() - Read register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be read
- *
- * Debugging only
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_dbg_g_register(struct file *file, void *priv,
-		struct v4l2_dbg_register *reg){
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_subdev_call(ch->sd, core, g_register, reg);
-}
-
-/*
- * vpif_dbg_s_register() - Write to register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be modified
- *
- * Debugging only
- * Returns zero or -EINVAL if write operations fails.
- */
-static int vpif_dbg_s_register(struct file *file, void *priv,
-		const struct v4l2_dbg_register *reg)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_subdev_call(ch->sd, core, s_register, reg);
-}
-#endif
-
-/*
  * vpif_log_status() - Status information
  * @file: file ptr
  * @priv: file handle
@@ -1974,11 +1902,6 @@ static const struct v4l2_ioctl_ops vpif_
 	.vidioc_query_dv_timings        = vpif_query_dv_timings,
 	.vidioc_s_dv_timings            = vpif_s_dv_timings,
 	.vidioc_g_dv_timings            = vpif_g_dv_timings,
-	.vidioc_g_chip_ident		= vpif_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register		= vpif_dbg_g_register,
-	.vidioc_s_register		= vpif_dbg_s_register,
-#endif
 	.vidioc_log_status		= vpif_log_status,
 };
 
@@ -2092,16 +2015,13 @@ static __init int vpif_probe(struct plat
 	}
 
 	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
-		for (i = res->start; i <= res->end; i++) {
-			if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
-					"VPIF_Capture", (void *)
-					(&vpif_obj.dev[res_idx]->channel_id))) {
-				err = -EBUSY;
-				for (j = 0; j < i; j++)
-					free_irq(j, (void *)
-					(&vpif_obj.dev[res_idx]->channel_id));
-				goto vpif_int_err;
-			}
+		err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
+					IRQF_SHARED, "VPIF_Capture",
+					(void *)(&vpif_obj.dev[res_idx]->
+					channel_id));
+		if (err) {
+			err = -EINVAL;
+			goto vpif_unregister;
 		}
 		res_idx++;
 	}
@@ -2117,7 +2037,7 @@ static __init int vpif_probe(struct plat
 				video_device_release(ch->video_dev);
 			}
 			err = -ENOMEM;
-			goto vpif_int_err;
+			goto vpif_unregister;
 		}
 
 		/* Initialize field of video device */
@@ -2170,6 +2090,7 @@ static __init int vpif_probe(struct plat
 
 		if (!vpif_obj.sd[i]) {
 			vpif_err("Error registering v4l2 subdevice\n");
+			err = -ENODEV;
 			goto probe_subdev_out;
 		}
 		v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
@@ -2217,13 +2138,9 @@ vpif_sd_error:
 		/* Note: does nothing if ch->video_dev == NULL */
 		video_device_release(ch->video_dev);
 	}
-vpif_int_err:
+vpif_unregister:
 	v4l2_device_unregister(&vpif_obj.v4l2_dev);
-	for (i = 0; i < res_idx; i++) {
-		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
-		for (j = res->start; j <= res->end; j++)
-			free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
-	}
+
 	return err;
 }
 
@@ -2235,17 +2152,19 @@ vpif_int_err:
  */
 static int vpif_remove(struct platform_device *device)
 {
-	int i;
 	struct channel_obj *ch;
+	int i;
 
 	v4l2_device_unregister(&vpif_obj.v4l2_dev);
 
+	kfree(vpif_obj.sd);
 	/* un-register device */
 	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
 		/* Get the pointer to the channel object */
 		ch = vpif_obj.dev[i];
 		/* Unregister video device */
 		video_unregister_device(ch->video_dev);
+		kfree(vpif_obj.dev[i]);
 	}
 	return 0;
 }
@@ -2336,47 +2255,4 @@ static __refdata struct platform_driver
 	.remove = vpif_remove,
 };
 
-/**
- * vpif_init: initialize the vpif driver
- *
- * This function registers device and driver to the kernel, requests irq
- * handler and allocates memory
- * for channel objects
- */
-static __init int vpif_init(void)
-{
-	return platform_driver_register(&vpif_driver);
-}
-
-/**
- * vpif_cleanup : This function clean up the vpif capture resources
- *
- * This will un-registers device and driver to the kernel, frees
- * requested irq handler and de-allocates memory allocated for channel
- * objects.
- */
-static void vpif_cleanup(void)
-{
-	struct platform_device *pdev;
-	struct resource *res;
-	int irq_num;
-	int i = 0;
-
-	pdev = container_of(vpif_dev, struct platform_device, dev);
-	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
-		for (irq_num = res->start; irq_num <= res->end; irq_num++)
-			free_irq(irq_num,
-				 (void *)(&vpif_obj.dev[i]->channel_id));
-		i++;
-	}
-
-	platform_driver_unregister(&vpif_driver);
-
-	kfree(vpif_obj.sd);
-	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
-		kfree(vpif_obj.dev[i]);
-}
-
-/* Function for module initialization and cleanup */
-module_init(vpif_init);
-module_exit(vpif_cleanup);
+module_platform_driver(vpif_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif_capture.h linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif_capture.h
--- linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif_capture.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif_capture.h	2013-08-25 20:43:22.000000000 -0400
@@ -22,11 +22,8 @@
 #ifdef __KERNEL__
 
 /* Header files */
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
 #include <media/videobuf2-dma-contig.h>
-#include <media/davinci/vpif_types.h>
+#include <media/v4l2-device.h>
 
 #include "vpif.h"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif_display.c linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif_display.c
--- linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif_display.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif_display.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,33 +14,15 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/i2c.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/io.h>
 #include <linux/slab.h>
 
-#include <asm/irq.h>
-#include <asm/page.h>
-
-#include <media/adv7343.h>
-#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 
-#include "vpif_display.h"
 #include "vpif.h"
+#include "vpif_display.h"
 
 MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
 MODULE_LICENSE("GPL");
@@ -1518,66 +1500,6 @@ static int vpif_g_dv_timings(struct file
 }
 
 /*
- * vpif_g_chip_ident() - Identify the chip
- * @file: file ptr
- * @priv: file handle
- * @chip: chip identity
- *
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-			chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
-		vpif_dbg(2, debug, "match_type is invalid.\n");
-		return -EINVAL;
-	}
-
-	return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
-			g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * vpif_dbg_g_register() - Read register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be read
- *
- * Debugging only
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_dbg_g_register(struct file *file, void *priv,
-		struct v4l2_dbg_register *reg){
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_subdev_call(ch->sd, core, g_register, reg);
-}
-
-/*
- * vpif_dbg_s_register() - Write to register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be modified
- *
- * Debugging only
- * Returns zero or -EINVAL if write operations fails.
- */
-static int vpif_dbg_s_register(struct file *file, void *priv,
-		const struct v4l2_dbg_register *reg)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_subdev_call(ch->sd, core, s_register, reg);
-}
-#endif
-
-/*
  * vpif_log_status() - Status information
  * @file: file ptr
  * @priv: file handle
@@ -1616,11 +1538,6 @@ static const struct v4l2_ioctl_ops vpif_
 	.vidioc_enum_dv_timings         = vpif_enum_dv_timings,
 	.vidioc_s_dv_timings            = vpif_s_dv_timings,
 	.vidioc_g_dv_timings            = vpif_g_dv_timings,
-	.vidioc_g_chip_ident		= vpif_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register		= vpif_dbg_g_register,
-	.vidioc_s_register		= vpif_dbg_s_register,
-#endif
 	.vidioc_log_status		= vpif_log_status,
 };
 
@@ -1734,16 +1651,14 @@ static __init int vpif_probe(struct plat
 	}
 
 	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
-		for (i = res->start; i <= res->end; i++) {
-			if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
-					"VPIF_Display", (void *)
-					(&vpif_obj.dev[res_idx]->channel_id))) {
-				err = -EBUSY;
-				for (j = 0; j < i; j++)
-					free_irq(j, (void *)
-					(&vpif_obj.dev[res_idx]->channel_id));
-				goto vpif_int_err;
-			}
+		err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
+					IRQF_SHARED, "VPIF_Display",
+					(void *)(&vpif_obj.dev[res_idx]->
+					channel_id));
+		if (err) {
+			err = -EINVAL;
+			vpif_err("VPIF IRQ request failed\n");
+			goto vpif_unregister;
 		}
 		res_idx++;
 	}
@@ -1760,7 +1675,7 @@ static __init int vpif_probe(struct plat
 				video_device_release(ch->video_dev);
 			}
 			err = -ENOMEM;
-			goto vpif_int_err;
+			goto vpif_unregister;
 		}
 
 		/* Initialize field of video device */
@@ -1813,6 +1728,7 @@ static __init int vpif_probe(struct plat
 						NULL);
 		if (!vpif_obj.sd[i]) {
 			vpif_err("Error registering v4l2 subdevice\n");
+			err = -ENODEV;
 			goto probe_subdev_out;
 		}
 
@@ -1893,14 +1809,8 @@ vpif_sd_error:
 		/* Note: does nothing if ch->video_dev == NULL */
 		video_device_release(ch->video_dev);
 	}
-vpif_int_err:
+vpif_unregister:
 	v4l2_device_unregister(&vpif_obj.v4l2_dev);
-	vpif_err("VPIF IRQ request failed\n");
-	for (i = 0; i < res_idx; i++) {
-		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
-		for (j = res->start; j <= res->end; j++)
-			free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
-	}
 
 	return err;
 }
@@ -1915,6 +1825,7 @@ static int vpif_remove(struct platform_d
 
 	v4l2_device_unregister(&vpif_obj.v4l2_dev);
 
+	kfree(vpif_obj.sd);
 	/* un-register device */
 	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
 		/* Get the pointer to the channel object */
@@ -1923,6 +1834,7 @@ static int vpif_remove(struct platform_d
 		video_unregister_device(ch->video_dev);
 
 		ch->video_dev = NULL;
+		kfree(vpif_obj.dev[i]);
 	}
 
 	return 0;
@@ -2008,37 +1920,4 @@ static __refdata struct platform_driver
 	.remove	= vpif_remove,
 };
 
-static __init int vpif_init(void)
-{
-	return platform_driver_register(&vpif_driver);
-}
-
-/*
- * vpif_cleanup: This function un-registers device and driver to the kernel,
- * frees requested irq handler and de-allocates memory allocated for channel
- * objects.
- */
-static void vpif_cleanup(void)
-{
-	struct platform_device *pdev;
-	struct resource *res;
-	int irq_num;
-	int i = 0;
-
-	pdev = container_of(vpif_dev, struct platform_device, dev);
-
-	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
-		for (irq_num = res->start; irq_num <= res->end; irq_num++)
-			free_irq(irq_num,
-				 (void *)(&vpif_obj.dev[i]->channel_id));
-		i++;
-	}
-
-	platform_driver_unregister(&vpif_driver);
-	kfree(vpif_obj.sd);
-	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
-		kfree(vpif_obj.dev[i]);
-}
-
-module_init(vpif_init);
-module_exit(vpif_cleanup);
+module_platform_driver(vpif_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif_display.h linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif_display.h
--- linux-libre-3.10-gnu/drivers/media/platform/davinci/vpif_display.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/davinci/vpif_display.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,8 @@
 #define DAVINCIHD_DISPLAY_H
 
 /* Header files */
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
 #include <media/videobuf2-dma-contig.h>
-#include <media/davinci/vpif_types.h>
+#include <media/v4l2-device.h>
 
 #include "vpif.h"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/common.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/common.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,53 @@
+/*
+ * Samsung S5P/EXYNOS4 SoC Camera Subsystem driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <media/s5p_fimc.h>
+#include "common.h"
+
+/* Called with the media graph mutex held or entity->stream_count > 0. */
+struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)
+{
+	struct media_pad *pad = &entity->pads[0];
+	struct v4l2_subdev *sd;
+
+	while (pad->flags & MEDIA_PAD_FL_SINK) {
+		/* source pad */
+		pad = media_entity_remote_pad(pad);
+		if (pad == NULL ||
+		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+			break;
+
+		sd = media_entity_to_v4l2_subdev(pad->entity);
+
+		if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR ||
+		    sd->grp_id == GRP_ID_SENSOR)
+			return sd;
+		/* sink pad */
+		pad = &sd->entity.pads[0];
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(fimc_find_remote_sensor);
+
+void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
+						unsigned int caps)
+{
+	strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver));
+	strlcpy(cap->card, dev->driver->name, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+				"platform:%s", dev_name(dev));
+	cap->device_caps = caps;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+}
+EXPORT_SYMBOL(__fimc_vidioc_querycap);
+
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/common.h linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/common.h
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/videodev2.h>
+#include <media/media-entity.h>
+#include <media/v4l2-subdev.h>
+
+struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity);
+void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
+			    unsigned int caps);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-capture.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-capture.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-capture.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-capture.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,9 +27,10 @@
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-contig.h>
 
-#include "media-dev.h"
+#include "common.h"
 #include "fimc-core.h"
 #include "fimc-reg.h"
+#include "media-dev.h"
 
 static int fimc_capture_hw_init(struct fimc_dev *fimc)
 {
@@ -119,8 +120,7 @@ static int fimc_capture_state_cleanup(st
 	spin_unlock_irqrestore(&fimc->slock, flags);
 
 	if (streaming)
-		return fimc_pipeline_call(fimc, set_stream,
-					  &fimc->pipeline, 0);
+		return fimc_pipeline_call(&cap->ve, set_stream, 0);
 	else
 		return 0;
 }
@@ -178,8 +178,9 @@ static int fimc_capture_config_update(st
 
 void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
 {
-	struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
 	struct fimc_vid_cap *cap = &fimc->vid_cap;
+	struct fimc_pipeline *p = to_fimc_pipeline(cap->ve.pipe);
+	struct v4l2_subdev *csis = p->subdevs[IDX_CSIS];
 	struct fimc_frame *f = &cap->ctx->d_frame;
 	struct fimc_vid_buffer *v_buf;
 	struct timeval *tv;
@@ -287,8 +288,7 @@ static int start_streaming(struct vb2_qu
 		fimc_activate_capture(ctx);
 
 		if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
-			return fimc_pipeline_call(fimc, set_stream,
-						  &fimc->pipeline, 1);
+			return fimc_pipeline_call(&vid_cap->ve, set_stream, 1);
 	}
 
 	return 0;
@@ -312,7 +312,7 @@ int fimc_capture_suspend(struct fimc_dev
 	int ret = fimc_stop_capture(fimc, suspend);
 	if (ret)
 		return ret;
-	return fimc_pipeline_call(fimc, close, &fimc->pipeline);
+	return fimc_pipeline_call(&fimc->vid_cap.ve, close);
 }
 
 static void buffer_queue(struct vb2_buffer *vb);
@@ -320,6 +320,7 @@ static void buffer_queue(struct vb2_buff
 int fimc_capture_resume(struct fimc_dev *fimc)
 {
 	struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
+	struct exynos_video_entity *ve = &vid_cap->ve;
 	struct fimc_vid_buffer *buf;
 	int i;
 
@@ -328,8 +329,7 @@ int fimc_capture_resume(struct fimc_dev
 
 	INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
 	vid_cap->buf_index = 0;
-	fimc_pipeline_call(fimc, open, &fimc->pipeline,
-			   &vid_cap->vfd.entity, false);
+	fimc_pipeline_call(ve, open, &ve->vdev.entity, false);
 	fimc_capture_hw_init(fimc);
 
 	clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
@@ -397,7 +397,7 @@ static int buffer_prepare(struct vb2_buf
 		unsigned long size = ctx->d_frame.payload[i];
 
 		if (vb2_plane_size(vb, i) < size) {
-			v4l2_err(&ctx->fimc_dev->vid_cap.vfd,
+			v4l2_err(&ctx->fimc_dev->vid_cap.ve.vdev,
 				 "User buffer too small (%ld < %ld)\n",
 				 vb2_plane_size(vb, i), size);
 			return -EINVAL;
@@ -415,6 +415,7 @@ static void buffer_queue(struct vb2_buff
 	struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct fimc_dev *fimc = ctx->fimc_dev;
 	struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
+	struct exynos_video_entity *ve = &vid_cap->ve;
 	unsigned long flags;
 	int min_bufs;
 
@@ -452,9 +453,9 @@ static void buffer_queue(struct vb2_buff
 		if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
 			return;
 
-		ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1);
+		ret = fimc_pipeline_call(ve, set_stream, 1);
 		if (ret < 0)
-			v4l2_err(&vid_cap->vfd, "stream on failed: %d\n", ret);
+			v4l2_err(&ve->vdev, "stream on failed: %d\n", ret);
 		return;
 	}
 	spin_unlock_irqrestore(&fimc->slock, flags);
@@ -470,44 +471,17 @@ static struct vb2_ops fimc_capture_qops
 	.stop_streaming		= stop_streaming,
 };
 
-/**
- * fimc_capture_ctrls_create - initialize the control handler
- * Initialize the capture video node control handler and fill it
- * with the FIMC controls. Inherit any sensor's controls if the
- * 'user_subdev_api' flag is false (default behaviour).
- * This function need to be called with the graph mutex held.
- */
-int fimc_capture_ctrls_create(struct fimc_dev *fimc)
-{
-	struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
-	struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
-	int ret;
-
-	if (WARN_ON(vid_cap->ctx == NULL))
-		return -ENXIO;
-	if (vid_cap->ctx->ctrls.ready)
-		return 0;
-
-	ret = fimc_ctrls_create(vid_cap->ctx);
-
-	if (ret || vid_cap->user_subdev_api || !sensor ||
-	    !vid_cap->ctx->ctrls.ready)
-		return ret;
-
-	return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
-				     sensor->ctrl_handler, NULL);
-}
-
 static int fimc_capture_set_default_format(struct fimc_dev *fimc);
 
 static int fimc_capture_open(struct file *file)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	struct exynos_video_entity *ve = &vc->ve;
 	int ret = -EBUSY;
 
 	dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
 
-	fimc_md_graph_lock(fimc);
 	mutex_lock(&fimc->lock);
 
 	if (fimc_m2m_active(fimc))
@@ -520,31 +494,42 @@ static int fimc_capture_open(struct file
 
 	ret = v4l2_fh_open(file);
 	if (ret) {
-		pm_runtime_put(&fimc->pdev->dev);
+		pm_runtime_put_sync(&fimc->pdev->dev);
 		goto unlock;
 	}
 
 	if (v4l2_fh_is_singular_file(file)) {
-		ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
-					 &fimc->vid_cap.vfd.entity, true);
+		fimc_md_graph_lock(ve);
 
-		if (!ret && !fimc->vid_cap.user_subdev_api)
-			ret = fimc_capture_set_default_format(fimc);
+		ret = fimc_pipeline_call(ve, open, &ve->vdev.entity, true);
 
-		if (!ret)
-			ret = fimc_capture_ctrls_create(fimc);
+		if (ret == 0 && vc->user_subdev_api && vc->inh_sensor_ctrls) {
+			/*
+			 * Recreate controls of the the video node to drop
+			 * any controls inherited from the sensor subdev.
+			 */
+			fimc_ctrls_delete(vc->ctx);
+
+			ret = fimc_ctrls_create(vc->ctx);
+			if (ret == 0)
+				vc->inh_sensor_ctrls = false;
+		}
+		if (ret == 0)
+			ve->vdev.entity.use_count++;
+
+		fimc_md_graph_unlock(ve);
+
+		if (ret == 0)
+			ret = fimc_capture_set_default_format(fimc);
 
 		if (ret < 0) {
 			clear_bit(ST_CAPT_BUSY, &fimc->state);
 			pm_runtime_put_sync(&fimc->pdev->dev);
 			v4l2_fh_release(file);
-		} else {
-			fimc->vid_cap.refcnt++;
 		}
 	}
 unlock:
 	mutex_unlock(&fimc->lock);
-	fimc_md_graph_unlock(fimc);
 	return ret;
 }
 
@@ -552,30 +537,31 @@ static int fimc_capture_release(struct f
 {
 	struct fimc_dev *fimc = video_drvdata(file);
 	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	bool close = v4l2_fh_is_singular_file(file);
 	int ret;
 
 	dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
 
 	mutex_lock(&fimc->lock);
 
-	if (v4l2_fh_is_singular_file(file)) {
-		if (vc->streaming) {
-			media_entity_pipeline_stop(&vc->vfd.entity);
-			vc->streaming = false;
-		}
-		clear_bit(ST_CAPT_BUSY, &fimc->state);
-		fimc_stop_capture(fimc, false);
-		fimc_pipeline_call(fimc, close, &fimc->pipeline);
-		clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
-		fimc->vid_cap.refcnt--;
+	if (close && vc->streaming) {
+		media_entity_pipeline_stop(&vc->ve.vdev.entity);
+		vc->streaming = false;
 	}
 
-	pm_runtime_put(&fimc->pdev->dev);
+	ret = vb2_fop_release(file);
 
-	if (v4l2_fh_is_singular_file(file))
-		fimc_ctrls_delete(fimc->vid_cap.ctx);
+	if (close) {
+		clear_bit(ST_CAPT_BUSY, &fimc->state);
+		fimc_pipeline_call(&vc->ve, close);
+		clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
 
-	ret = vb2_fop_release(file);
+		fimc_md_graph_lock(&vc->ve);
+		vc->ve.vdev.entity.use_count--;
+		fimc_md_graph_unlock(&vc->ve);
+	}
+
+	pm_runtime_put_sync(&fimc->pdev->dev);
 	mutex_unlock(&fimc->lock);
 
 	return ret;
@@ -773,7 +759,7 @@ static struct media_entity *fimc_pipelin
 	struct media_pad *pad = &me->pads[0];
 
 	while (!(pad->flags & MEDIA_PAD_FL_SOURCE)) {
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (!pad)
 			break;
 		me = pad->entity;
@@ -797,7 +783,8 @@ static int fimc_pipeline_try_format(stru
 				    bool set)
 {
 	struct fimc_dev *fimc = ctx->fimc_dev;
-	struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
+	struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe);
+	struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
 	struct v4l2_subdev_format sfmt;
 	struct v4l2_mbus_framefmt *mf = &sfmt.format;
 	struct media_entity *me;
@@ -845,7 +832,7 @@ static int fimc_pipeline_try_format(stru
 					return ret;
 			}
 
-			pad = media_entity_remote_source(&me->pads[sfmt.pad]);
+			pad = media_entity_remote_pad(&me->pads[sfmt.pad]);
 			if (!pad)
 				return -EINVAL;
 			me = pad->entity;
@@ -929,57 +916,101 @@ static int fimc_cap_g_fmt_mplane(struct
 	return 0;
 }
 
-static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
-				   struct v4l2_format *f)
+/*
+ * Try or set format on the fimc.X.capture video node and additionally
+ * on the whole pipeline if @try is false.
+ * Locking: the caller must _not_ hold the graph mutex.
+ */
+static int __video_try_or_set_format(struct fimc_dev *fimc,
+				     struct v4l2_format *f, bool try,
+				     struct fimc_fmt **inp_fmt,
+				     struct fimc_fmt **out_fmt)
 {
 	struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
-	struct fimc_dev *fimc = video_drvdata(file);
-	struct fimc_ctx *ctx = fimc->vid_cap.ctx;
-	struct v4l2_mbus_framefmt mf;
-	struct fimc_fmt *ffmt = NULL;
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	struct exynos_video_entity *ve = &vc->ve;
+	struct fimc_ctx *ctx = vc->ctx;
+	unsigned int width = 0, height = 0;
 	int ret = 0;
 
-	fimc_md_graph_lock(fimc);
-	mutex_lock(&fimc->lock);
-
+	/* Pre-configure format at the camera input interface, for JPEG only */
 	if (fimc_jpeg_fourcc(pix->pixelformat)) {
 		fimc_capture_try_format(ctx, &pix->width, &pix->height,
 					NULL, &pix->pixelformat,
 					FIMC_SD_PAD_SINK_CAM);
-		ctx->s_frame.f_width  = pix->width;
-		ctx->s_frame.f_height = pix->height;
+		if (try) {
+			width = pix->width;
+			height = pix->height;
+		} else {
+			ctx->s_frame.f_width = pix->width;
+			ctx->s_frame.f_height = pix->height;
+		}
 	}
-	ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
-				       NULL, &pix->pixelformat,
-				       FIMC_SD_PAD_SOURCE);
-	if (!ffmt) {
-		ret = -EINVAL;
-		goto unlock;
+
+	/* Try the format at the scaler and the DMA output */
+	*out_fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
+					  NULL, &pix->pixelformat,
+					  FIMC_SD_PAD_SOURCE);
+	if (*out_fmt == NULL)
+		return -EINVAL;
+
+	/* Restore image width/height for JPEG (no resizing supported). */
+	if (try && fimc_jpeg_fourcc(pix->pixelformat)) {
+		pix->width = width;
+		pix->height = height;
 	}
 
-	if (!fimc->vid_cap.user_subdev_api) {
-		mf.width = pix->width;
-		mf.height = pix->height;
-		mf.code = ffmt->mbus_code;
-		fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
-		pix->width = mf.width;
-		pix->height = mf.height;
-		if (ffmt)
-			pix->pixelformat = ffmt->fourcc;
+	/* Try to match format at the host and the sensor */
+	if (!vc->user_subdev_api) {
+		struct v4l2_mbus_framefmt mbus_fmt;
+		struct v4l2_mbus_framefmt *mf;
+
+		mf = try ? &mbus_fmt : &fimc->vid_cap.ci_fmt;
+
+		mf->code = (*out_fmt)->mbus_code;
+		mf->width = pix->width;
+		mf->height = pix->height;
+
+		fimc_md_graph_lock(ve);
+		ret = fimc_pipeline_try_format(ctx, mf, inp_fmt, try);
+		fimc_md_graph_unlock(ve);
+
+		if (ret < 0)
+			return ret;
+
+		pix->width = mf->width;
+		pix->height = mf->height;
 	}
 
-	fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
+	fimc_adjust_mplane_format(*out_fmt, pix->width, pix->height, pix);
 
-	if (ffmt->flags & FMT_FLAGS_COMPRESSED)
-		fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
-					pix->plane_fmt, ffmt->memplanes, true);
-unlock:
-	mutex_unlock(&fimc->lock);
-	fimc_md_graph_unlock(fimc);
+	if ((*out_fmt)->flags & FMT_FLAGS_COMPRESSED) {
+		struct v4l2_subdev *sensor;
+
+		fimc_md_graph_lock(ve);
+
+		sensor = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
+		if (sensor)
+			fimc_get_sensor_frame_desc(sensor, pix->plane_fmt,
+						   (*out_fmt)->memplanes, try);
+		else
+			ret = -EPIPE;
+
+		fimc_md_graph_unlock(ve);
+	}
 
 	return ret;
 }
 
+static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+				   struct v4l2_format *f)
+{
+	struct fimc_dev *fimc = video_drvdata(file);
+	struct fimc_fmt *out_fmt = NULL, *inp_fmt = NULL;
+
+	return __video_try_or_set_format(fimc, f, true, &inp_fmt, &out_fmt);
+}
+
 static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx,
 					enum fimc_color_fmt color)
 {
@@ -997,57 +1028,23 @@ static void fimc_capture_mark_jpeg_xfer(
 static int __fimc_capture_set_format(struct fimc_dev *fimc,
 				     struct v4l2_format *f)
 {
-	struct fimc_ctx *ctx = fimc->vid_cap.ctx;
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	struct fimc_ctx *ctx = vc->ctx;
 	struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
-	struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.ci_fmt;
 	struct fimc_frame *ff = &ctx->d_frame;
-	struct fimc_fmt *s_fmt = NULL;
+	struct fimc_fmt *inp_fmt = NULL;
 	int ret, i;
 
 	if (vb2_is_busy(&fimc->vid_cap.vbq))
 		return -EBUSY;
 
-	/* Pre-configure format at camera interface input, for JPEG only */
-	if (fimc_jpeg_fourcc(pix->pixelformat)) {
-		fimc_capture_try_format(ctx, &pix->width, &pix->height,
-					NULL, &pix->pixelformat,
-					FIMC_SD_PAD_SINK_CAM);
-		ctx->s_frame.f_width  = pix->width;
-		ctx->s_frame.f_height = pix->height;
-	}
-	/* Try the format at the scaler and the DMA output */
-	ff->fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
-					  NULL, &pix->pixelformat,
-					  FIMC_SD_PAD_SOURCE);
-	if (!ff->fmt)
-		return -EINVAL;
+	ret = __video_try_or_set_format(fimc, f, false, &inp_fmt, &ff->fmt);
+	if (ret < 0)
+		return ret;
 
 	/* Update RGB Alpha control state and value range */
 	fimc_alpha_ctrl_update(ctx);
 
-	/* Try to match format at the host and the sensor */
-	if (!fimc->vid_cap.user_subdev_api) {
-		mf->code   = ff->fmt->mbus_code;
-		mf->width  = pix->width;
-		mf->height = pix->height;
-		ret = fimc_pipeline_try_format(ctx, mf, &s_fmt, true);
-		if (ret)
-			return ret;
-
-		pix->width  = mf->width;
-		pix->height = mf->height;
-	}
-
-	fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
-
-	if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) {
-		ret = fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
-					pix->plane_fmt, ff->fmt->memplanes,
-					true);
-		if (ret < 0)
-			return ret;
-	}
-
 	for (i = 0; i < ff->fmt->memplanes; i++) {
 		ff->bytesperline[i] = pix->plane_fmt[i].bytesperline;
 		ff->payload[i] = pix->plane_fmt[i].sizeimage;
@@ -1061,8 +1058,8 @@ static int __fimc_capture_set_format(str
 	fimc_capture_mark_jpeg_xfer(ctx, ff->fmt->color);
 
 	/* Reset cropping and set format at the camera interface input */
-	if (!fimc->vid_cap.user_subdev_api) {
-		ctx->s_frame.fmt = s_fmt;
+	if (!vc->user_subdev_api) {
+		ctx->s_frame.fmt = inp_fmt;
 		set_frame_bounds(&ctx->s_frame, pix->width, pix->height);
 		set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height);
 	}
@@ -1074,37 +1071,28 @@ static int fimc_cap_s_fmt_mplane(struct
 				 struct v4l2_format *f)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
-	int ret;
 
-	fimc_md_graph_lock(fimc);
-	mutex_lock(&fimc->lock);
-	/*
-	 * The graph is walked within __fimc_capture_set_format() to set
-	 * the format at subdevs thus the graph mutex needs to be held at
-	 * this point and acquired before the video mutex, to avoid  AB-BA
-	 * deadlock when fimc_md_link_notify() is called by other thread.
-	 * Ideally the graph walking and setting format at the whole pipeline
-	 * should be removed from this driver and handled in userspace only.
-	 */
-	ret = __fimc_capture_set_format(fimc, f);
-
-	mutex_unlock(&fimc->lock);
-	fimc_md_graph_unlock(fimc);
-	return ret;
+	return __fimc_capture_set_format(fimc, f);
 }
 
 static int fimc_cap_enum_input(struct file *file, void *priv,
 			       struct v4l2_input *i)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
-	struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
+	struct exynos_video_entity *ve = &fimc->vid_cap.ve;
+	struct v4l2_subdev *sd;
 
 	if (i->index != 0)
 		return -EINVAL;
 
 	i->type = V4L2_INPUT_TYPE_CAMERA;
+	fimc_md_graph_lock(ve);
+	sd = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
+	fimc_md_graph_unlock(ve);
+
 	if (sd)
 		strlcpy(i->name, sd->name, sizeof(i->name));
+
 	return 0;
 }
 
@@ -1130,6 +1118,7 @@ static int fimc_pipeline_validate(struct
 	struct v4l2_subdev_format sink_fmt, src_fmt;
 	struct fimc_vid_cap *vc = &fimc->vid_cap;
 	struct v4l2_subdev *sd = &vc->subdev;
+	struct fimc_pipeline *p = to_fimc_pipeline(vc->ve.pipe);
 	struct media_pad *sink_pad, *src_pad;
 	int i, ret;
 
@@ -1146,7 +1135,7 @@ static int fimc_pipeline_validate(struct
 
 			if (p->flags & MEDIA_PAD_FL_SINK) {
 				sink_pad = p;
-				src_pad = media_entity_remote_source(sink_pad);
+				src_pad = media_entity_remote_pad(sink_pad);
 				if (src_pad)
 					break;
 			}
@@ -1183,7 +1172,7 @@ static int fimc_pipeline_validate(struct
 		    src_fmt.format.code != sink_fmt.format.code)
 			return -EPIPE;
 
-		if (sd == fimc->pipeline.subdevs[IDX_SENSOR] &&
+		if (sd == p->subdevs[IDX_SENSOR] &&
 		    fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
 			struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES];
 			struct fimc_frame *frame = &vc->ctx->d_frame;
@@ -1207,9 +1196,8 @@ static int fimc_cap_streamon(struct file
 			     enum v4l2_buf_type type)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
-	struct fimc_pipeline *p = &fimc->pipeline;
 	struct fimc_vid_cap *vc = &fimc->vid_cap;
-	struct media_entity *entity = &vc->vfd.entity;
+	struct media_entity *entity = &vc->ve.vdev.entity;
 	struct fimc_source_info *si = NULL;
 	struct v4l2_subdev *sd;
 	int ret;
@@ -1217,11 +1205,11 @@ static int fimc_cap_streamon(struct file
 	if (fimc_capture_active(fimc))
 		return -EBUSY;
 
-	ret = media_entity_pipeline_start(entity, p->m_pipeline);
+	ret = media_entity_pipeline_start(entity, &vc->ve.pipe->mp);
 	if (ret < 0)
 		return ret;
 
-	sd = p->subdevs[IDX_SENSOR];
+	sd = __fimc_md_get_subdev(vc->ve.pipe, IDX_SENSOR);
 	if (sd)
 		si = v4l2_get_subdev_hostdata(sd);
 
@@ -1259,14 +1247,15 @@ static int fimc_cap_streamoff(struct fil
 			    enum v4l2_buf_type type)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
 	int ret;
 
 	ret = vb2_ioctl_streamoff(file, priv, type);
 	if (ret < 0)
 		return ret;
 
-	media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity);
-	fimc->vid_cap.streaming = false;
+	media_entity_pipeline_stop(&vc->ve.vdev.entity);
+	vc->streaming = false;
 	return 0;
 }
 
@@ -1405,6 +1394,8 @@ static int fimc_link_setup(struct media_
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	struct v4l2_subdev *sensor;
 
 	if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 		return -EINVAL;
@@ -1416,15 +1407,26 @@ static int fimc_link_setup(struct media_
 	    local->entity->name, remote->entity->name, flags,
 	    fimc->vid_cap.input);
 
-	if (flags & MEDIA_LNK_FL_ENABLED) {
-		if (fimc->vid_cap.input != 0)
-			return -EBUSY;
-		fimc->vid_cap.input = sd->grp_id;
+	if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+		fimc->vid_cap.input = 0;
 		return 0;
 	}
 
-	fimc->vid_cap.input = 0;
-	return 0;
+	if (vc->input != 0)
+		return -EBUSY;
+
+	vc->input = sd->grp_id;
+
+	if (vc->user_subdev_api || vc->inh_sensor_ctrls)
+		return 0;
+
+	/* Inherit V4L2 controls from the image sensor subdev. */
+	sensor = fimc_find_remote_sensor(&vc->subdev.entity);
+	if (sensor == NULL)
+		return 0;
+
+	return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler,
+				     sensor->ctrl_handler, NULL);
 }
 
 static const struct media_entity_operations fimc_sd_media_ops = {
@@ -1720,8 +1722,8 @@ static int fimc_capture_set_default_form
 	struct v4l2_format fmt = {
 		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
 		.fmt.pix_mp = {
-			.width		= 640,
-			.height		= 480,
+			.width		= FIMC_DEFAULT_WIDTH,
+			.height		= FIMC_DEFAULT_HEIGHT,
 			.pixelformat	= V4L2_PIX_FMT_YUYV,
 			.field		= V4L2_FIELD_NONE,
 			.colorspace	= V4L2_COLORSPACE_JPEG,
@@ -1735,10 +1737,11 @@ static int fimc_capture_set_default_form
 static int fimc_register_capture_device(struct fimc_dev *fimc,
 				 struct v4l2_device *v4l2_dev)
 {
-	struct video_device *vfd = &fimc->vid_cap.vfd;
+	struct video_device *vfd = &fimc->vid_cap.ve.vdev;
 	struct vb2_queue *q = &fimc->vid_cap.vbq;
 	struct fimc_ctx *ctx;
 	struct fimc_vid_cap *vid_cap;
+	struct fimc_fmt *fmt;
 	int ret = -ENOMEM;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -1784,22 +1787,34 @@ static int fimc_register_capture_device(
 
 	ret = vb2_queue_init(q);
 	if (ret)
-		goto err_ent;
+		goto err_free_ctx;
+
+	/* Default format configuration */
+	fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
+	vid_cap->ci_fmt.width = FIMC_DEFAULT_WIDTH;
+	vid_cap->ci_fmt.height = FIMC_DEFAULT_HEIGHT;
+	vid_cap->ci_fmt.code = fmt->mbus_code;
+
+	ctx->s_frame.width = FIMC_DEFAULT_WIDTH;
+	ctx->s_frame.height = FIMC_DEFAULT_HEIGHT;
+	ctx->s_frame.fmt = fmt;
+
+	fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_WRITEBACK, 0);
+	vid_cap->wb_fmt = vid_cap->ci_fmt;
+	vid_cap->wb_fmt.code = fmt->mbus_code;
 
 	vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
 	ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
 	if (ret)
-		goto err_ent;
-	/*
-	 * For proper order of acquiring/releasing the video
-	 * and the graph mutex.
-	 */
-	v4l2_disable_ioctl_locking(vfd, VIDIOC_TRY_FMT);
-	v4l2_disable_ioctl_locking(vfd, VIDIOC_S_FMT);
+		goto err_free_ctx;
+
+	ret = fimc_ctrls_create(ctx);
+	if (ret)
+		goto err_me_cleanup;
 
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
 	if (ret)
-		goto err_vd;
+		goto err_ctrl_free;
 
 	v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
 		  vfd->name, video_device_node_name(vfd));
@@ -1807,9 +1822,11 @@ static int fimc_register_capture_device(
 	vfd->ctrl_handler = &ctx->ctrls.handler;
 	return 0;
 
-err_vd:
+err_ctrl_free:
+	fimc_ctrls_delete(ctx);
+err_me_cleanup:
 	media_entity_cleanup(&vfd->entity);
-err_ent:
+err_free_ctx:
 	kfree(ctx);
 	return ret;
 }
@@ -1826,12 +1843,12 @@ static int fimc_capture_subdev_registere
 	if (ret)
 		return ret;
 
-	fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
+	fimc->vid_cap.ve.pipe = v4l2_get_subdev_hostdata(sd);
 
 	ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
 	if (ret) {
 		fimc_unregister_m2m_device(fimc);
-		fimc->pipeline_ops = NULL;
+		fimc->vid_cap.ve.pipe = NULL;
 	}
 
 	return ret;
@@ -1840,19 +1857,26 @@ static int fimc_capture_subdev_registere
 static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
 {
 	struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
+	struct video_device *vdev;
 
 	if (fimc == NULL)
 		return;
 
+	mutex_lock(&fimc->lock);
+
 	fimc_unregister_m2m_device(fimc);
+	vdev = &fimc->vid_cap.ve.vdev;
 
-	if (video_is_registered(&fimc->vid_cap.vfd)) {
-		video_unregister_device(&fimc->vid_cap.vfd);
-		media_entity_cleanup(&fimc->vid_cap.vfd.entity);
-		fimc->pipeline_ops = NULL;
+	if (video_is_registered(vdev)) {
+		video_unregister_device(vdev);
+		media_entity_cleanup(&vdev->entity);
+		fimc_ctrls_delete(fimc->vid_cap.ctx);
+		fimc->vid_cap.ve.pipe = NULL;
 	}
 	kfree(fimc->vid_cap.ctx);
 	fimc->vid_cap.ctx = NULL;
+
+	mutex_unlock(&fimc->lock);
 }
 
 static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-core.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-core.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -213,17 +213,6 @@ struct fimc_fmt *fimc_get_format(unsigne
 	return &fimc_formats[index];
 }
 
-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
-						unsigned int caps)
-{
-	strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver));
-	strlcpy(cap->card, dev->driver->name, sizeof(cap->card));
-	snprintf(cap->bus_info, sizeof(cap->bus_info),
-				"platform:%s", dev_name(dev));
-	cap->device_caps = caps;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-}
-
 int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
 			    int dw, int dh, int rotation)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-core.h linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-core.h
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-core.h	2013-08-25 20:43:22.000000000 -0400
@@ -48,6 +48,8 @@
 #define FIMC_DEF_MIN_SIZE	16
 #define FIMC_DEF_HEIGHT_ALIGN	2
 #define FIMC_DEF_HOR_OFFS_ALIGN	1
+#define FIMC_DEFAULT_WIDTH	640
+#define FIMC_DEFAULT_HEIGHT	480
 
 /* indices to the clocks array */
 enum {
@@ -283,8 +285,8 @@ struct fimc_m2m_device {
 /**
  * struct fimc_vid_cap - camera capture device information
  * @ctx: hardware context data
- * @vfd: video device node for camera capture mode
  * @subdev: subdev exposing the FIMC processing block
+ * @ve: exynos video device entity structure
  * @vd_pad: fimc video capture node pad
  * @sd_pads: fimc video processing block pads
  * @ci_fmt: image format at the FIMC camera input (and the scaler output)
@@ -298,15 +300,16 @@ struct fimc_m2m_device {
  * @frame_count: the frame counter for statistics
  * @reqbufs_count: the number of buffers requested in REQBUFS ioctl
  * @input_index: input (camera sensor) index
- * @refcnt: driver's private reference counter
  * @input: capture input type, grp_id of the attached subdev
  * @user_subdev_api: true if subdevs are not configured by the host driver
+ * @inh_sensor_ctrls: a flag indicating v4l2 controls are inherited from
+ * 		      an image sensor subdev
  */
 struct fimc_vid_cap {
 	struct fimc_ctx			*ctx;
 	struct vb2_alloc_ctx		*alloc_ctx;
-	struct video_device		vfd;
 	struct v4l2_subdev		subdev;
+	struct exynos_video_entity	ve;
 	struct media_pad		vd_pad;
 	struct media_pad		sd_pads[FIMC_SD_PADS_NUM];
 	struct v4l2_mbus_framefmt	ci_fmt;
@@ -321,9 +324,9 @@ struct fimc_vid_cap {
 	unsigned int			reqbufs_count;
 	bool				streaming;
 	int				input_index;
-	int				refcnt;
 	u32				input;
 	bool				user_subdev_api;
+	bool				inh_sensor_ctrls;
 };
 
 /**
@@ -434,8 +437,6 @@ struct fimc_dev {
 	struct fimc_vid_cap		vid_cap;
 	unsigned long			state;
 	struct vb2_alloc_ctx		*alloc_ctx;
-	struct fimc_pipeline		pipeline;
-	const struct fimc_pipeline_ops	*pipeline_ops;
 };
 
 /**
@@ -620,8 +621,6 @@ static inline struct fimc_frame *ctx_get
 /* fimc-core.c */
 int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
 				struct v4l2_fmtdesc *f);
-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
-						unsigned int caps);
 int fimc_ctrls_create(struct fimc_ctx *ctx);
 void fimc_ctrls_delete(struct fimc_ctx *ctx);
 void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is.c	2013-07-01 10:35:17.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is.c	2013-08-31 17:54:48.000000000 -0400
@@ -129,7 +129,7 @@ static int fimc_is_setup_clocks(struct f
 					ATCLK_MCUISP_FREQUENCY);
 }
 
-int fimc_is_enable_clocks(struct fimc_is *is)
+static int fimc_is_enable_clocks(struct fimc_is *is)
 {
 	int i, ret;
 
@@ -149,7 +149,7 @@ int fimc_is_enable_clocks(struct fimc_is
 	return 0;
 }
 
-void fimc_is_disable_clocks(struct fimc_is *is)
+static void fimc_is_disable_clocks(struct fimc_is *is)
 {
 	int i;
 
@@ -527,8 +527,8 @@ static void fimc_is_general_irq_handler(
 			break;
 
 		case HIC_SET_PARAMETER:
-			is->config[is->config_index].p_region_index1 = 0;
-			is->config[is->config_index].p_region_index2 = 0;
+			is->config[is->config_index].p_region_index[0] = 0;
+			is->config[is->config_index].p_region_index[1] = 0;
 			set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
 			pr_debug("HIC_SET_PARAMETER\n");
 			break;
@@ -587,8 +587,8 @@ static void fimc_is_general_irq_handler(
 
 		switch (is->i2h_cmd.args[0]) {
 		case HIC_SET_PARAMETER:
-			is->config[is->config_index].p_region_index1 = 0;
-			is->config[is->config_index].p_region_index2 = 0;
+			is->config[is->config_index].p_region_index[0] = 0;
+			is->config[is->config_index].p_region_index[1] = 0;
 			set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
 			break;
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is.h linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is.h
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is.h	2013-07-01 10:35:19.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is.h	2013-08-31 17:54:50.000000000 -0400
@@ -225,8 +225,7 @@ struct chain_config {
 	struct drc_param	drc;
 	struct fd_param		fd;
 
-	unsigned long		p_region_index1;
-	unsigned long		p_region_index2;
+	unsigned long		p_region_index[2];
 };
 
 /**
@@ -302,10 +301,7 @@ static inline void fimc_is_set_param_bit
 {
 	struct chain_config *cfg = &is->config[is->config_index];
 
-	if (num >= 32)
-		set_bit(num - 32, &cfg->p_region_index2);
-	else
-		set_bit(num, &cfg->p_region_index1);
+	set_bit(num, &cfg->p_region_index[0]);
 }
 
 static inline void fimc_is_set_param_ctrl_cmd(struct fimc_is *is, int cmd)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is-i2c.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is-i2c.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is-i2c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is-i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -96,7 +96,7 @@ static int fimc_is_i2c_resume(struct dev
 	return clk_prepare_enable(isp_i2c->clock);
 }
 
-UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend,
+static UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend,
 		     fimc_is_i2c_resume, NULL);
 
 static const struct of_device_id fimc_is_i2c_of_match[] = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is-param.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is-param.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is-param.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is-param.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,7 @@ static void __hw_param_copy(void *dst, v
 	memcpy(dst, src, FIMC_IS_PARAM_MAX_SIZE);
 }
 
-void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
+static void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
 {
 	struct param_global_shotmode *dst, *src;
 
@@ -47,7 +47,7 @@ void __fimc_is_hw_update_param_global_sh
 	__hw_param_copy(dst, src);
 }
 
-void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
+static void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
 {
 	struct param_sensor_framerate *dst, *src;
 
@@ -168,8 +168,8 @@ unsigned int __get_pending_param_count(s
 	unsigned int count;
 
 	spin_lock_irqsave(&is->slock, flags);
-	count = hweight32(config->p_region_index1);
-	count += hweight32(config->p_region_index2);
+	count = hweight32(config->p_region_index[0]);
+	count += hweight32(config->p_region_index[1]);
 	spin_unlock_irqrestore(&is->slock, flags);
 
 	return count;
@@ -177,31 +177,30 @@ unsigned int __get_pending_param_count(s
 
 int __is_hw_update_params(struct fimc_is *is)
 {
-	unsigned long *p_index1, *p_index2;
+	unsigned long *p_index;
 	int i, id, ret = 0;
 
 	id = is->config_index;
-	p_index1 = &is->config[id].p_region_index1;
-	p_index2 = &is->config[id].p_region_index2;
+	p_index = &is->config[id].p_region_index[0];
 
-	if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index1))
+	if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index))
 		__fimc_is_hw_update_param_global_shotmode(is);
 
-	if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index1))
+	if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index))
 		__fimc_is_hw_update_param_sensor_framerate(is);
 
 	for (i = PARAM_ISP_CONTROL; i < PARAM_DRC_CONTROL; i++) {
-		if (test_bit(i, p_index1))
+		if (test_bit(i, p_index))
 			ret = __fimc_is_hw_update_param(is, i);
 	}
 
 	for (i = PARAM_DRC_CONTROL; i < PARAM_SCALERC_CONTROL; i++) {
-		if (test_bit(i, p_index1))
+		if (test_bit(i, p_index))
 			ret = __fimc_is_hw_update_param(is, i);
 	}
 
 	for (i = PARAM_FD_CONTROL; i <= PARAM_FD_CONFIG; i++) {
-		if (test_bit((i - 32), p_index2))
+		if (test_bit(i, p_index))
 			ret = __fimc_is_hw_update_param(is, i);
 	}
 
@@ -243,7 +242,7 @@ void __is_set_frame_size(struct fimc_is
 	fd->otf_input.height = mf->height;
 
 	if (test_bit(PARAM_ISP_OTF_INPUT,
-		      &is->config[index].p_region_index1))
+		      &is->config[index].p_region_index[0]))
 		return;
 
 	/* Update field */
@@ -368,7 +367,7 @@ void __is_set_isp_adjust(struct fimc_is
 	unsigned long *p_index;
 	struct isp_param *isp;
 
-	p_index = &is->config[index].p_region_index1;
+	p_index = &is->config[index].p_region_index[0];
 	isp = &is->config[index].isp;
 
 	switch (cmd) {
@@ -415,7 +414,7 @@ void __is_set_isp_metering(struct fimc_i
 	struct isp_param *isp;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index1;
+	p_index = &is->config[index].p_region_index[0];
 	isp = &is->config[index].isp;
 
 	switch (id) {
@@ -476,7 +475,7 @@ void __is_set_fd_control(struct fimc_is
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->control.cmd = val;
@@ -491,7 +490,7 @@ void __is_set_fd_config_maxface(struct f
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.max_number = val;
@@ -511,7 +510,7 @@ void __is_set_fd_config_rollangle(struct
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.roll_angle = val;
@@ -531,7 +530,7 @@ void __is_set_fd_config_yawangle(struct
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.yaw_angle = val;
@@ -551,7 +550,7 @@ void __is_set_fd_config_smilemode(struct
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.smile_mode = val;
@@ -571,7 +570,7 @@ void __is_set_fd_config_blinkmode(struct
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.blink_mode = val;
@@ -591,7 +590,7 @@ void __is_set_fd_config_eyedetect(struct
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.eye_detect = val;
@@ -611,7 +610,7 @@ void __is_set_fd_config_mouthdetect(stru
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.mouth_detect = val;
@@ -631,7 +630,7 @@ void __is_set_fd_config_orientation(stru
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.orientation = val;
@@ -651,7 +650,7 @@ void __is_set_fd_config_orientation_val(
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.orientation_value = val;
@@ -672,7 +671,7 @@ void fimc_is_set_initial_params(struct f
 	struct isp_param *isp;
 	struct drc_param *drc;
 	struct fd_param *fd;
-	unsigned long *p_index1, *p_index2;
+	unsigned long *p_index;
 	unsigned int index;
 
 	index = is->config_index;
@@ -681,8 +680,7 @@ void fimc_is_set_initial_params(struct f
 	isp = &is->config[index].isp;
 	drc = &is->config[index].drc;
 	fd = &is->config[index].fd;
-	p_index1 = &is->config[index].p_region_index1;
-	p_index2 = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[0];
 
 	/* Global */
 	global->shotmode.cmd = 1;
@@ -695,7 +693,7 @@ void fimc_is_set_initial_params(struct f
 	fimc_is_set_param_bit(is, PARAM_ISP_CONTROL);
 
 	isp->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
-	if (!test_bit(PARAM_ISP_OTF_INPUT, p_index1)) {
+	if (!test_bit(PARAM_ISP_OTF_INPUT, p_index)) {
 		isp->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		isp->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT);
@@ -738,20 +736,20 @@ void fimc_is_set_initial_params(struct f
 	isp->aa.target = ISP_AA_TARGET_AE | ISP_AA_TARGET_AWB;
 	fimc_is_set_param_bit(is, PARAM_ISP_AA);
 
-	if (!test_bit(PARAM_ISP_FLASH, p_index1))
+	if (!test_bit(PARAM_ISP_FLASH, p_index))
 		__is_set_isp_flash(is, ISP_FLASH_COMMAND_DISABLE,
 						ISP_FLASH_REDEYE_DISABLE);
 
-	if (!test_bit(PARAM_ISP_AWB, p_index1))
+	if (!test_bit(PARAM_ISP_AWB, p_index))
 		__is_set_isp_awb(is, ISP_AWB_COMMAND_AUTO, 0);
 
-	if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index1))
+	if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index))
 		__is_set_isp_effect(is, ISP_IMAGE_EFFECT_DISABLE);
 
-	if (!test_bit(PARAM_ISP_ISO, p_index1))
+	if (!test_bit(PARAM_ISP_ISO, p_index))
 		__is_set_isp_iso(is, ISP_ISO_COMMAND_AUTO, 0);
 
-	if (!test_bit(PARAM_ISP_ADJUST, p_index1)) {
+	if (!test_bit(PARAM_ISP_ADJUST, p_index)) {
 		__is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_CONTRAST, 0);
 		__is_set_isp_adjust(is,
 				ISP_ADJUST_COMMAND_MANUAL_SATURATION, 0);
@@ -762,7 +760,7 @@ void fimc_is_set_initial_params(struct f
 		__is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_HUE, 0);
 	}
 
-	if (!test_bit(PARAM_ISP_METERING, p_index1)) {
+	if (!test_bit(PARAM_ISP_METERING, p_index)) {
 		__is_set_isp_metering(is, 0, ISP_METERING_COMMAND_CENTER);
 		__is_set_isp_metering(is, 1, 0);
 		__is_set_isp_metering(is, 2, 0);
@@ -770,11 +768,11 @@ void fimc_is_set_initial_params(struct f
 		__is_set_isp_metering(is, 4, 0);
 	}
 
-	if (!test_bit(PARAM_ISP_AFC, p_index1))
+	if (!test_bit(PARAM_ISP_AFC, p_index))
 		__is_set_isp_afc(is, ISP_AFC_COMMAND_AUTO, 0);
 
 	isp->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
-	if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index1)) {
+	if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index)) {
 		isp->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		isp->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_ISP_OTF_OUTPUT);
@@ -784,7 +782,7 @@ void fimc_is_set_initial_params(struct f
 	isp->otf_output.order = 0;
 	isp->otf_output.err = OTF_OUTPUT_ERROR_NONE;
 
-	if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index1)) {
+	if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index)) {
 		isp->dma1_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
 		isp->dma1_output.width = 0;
 		isp->dma1_output.height = 0;
@@ -800,7 +798,7 @@ void fimc_is_set_initial_params(struct f
 		fimc_is_set_param_bit(is, PARAM_ISP_DMA1_OUTPUT);
 	}
 
-	if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index1)) {
+	if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index)) {
 		isp->dma2_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
 		isp->dma2_output.width = 0;
 		isp->dma2_output.height = 0;
@@ -817,7 +815,7 @@ void fimc_is_set_initial_params(struct f
 	}
 
 	/* Sensor */
-	if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index1)) {
+	if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index)) {
 		if (is->config_index == 0)
 			__is_set_sensor(is, 0);
 	}
@@ -827,7 +825,7 @@ void fimc_is_set_initial_params(struct f
 	__is_set_drc_control(is, CONTROL_BYPASS_ENABLE);
 
 	drc->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
-	if (!test_bit(PARAM_DRC_OTF_INPUT, p_index1)) {
+	if (!test_bit(PARAM_DRC_OTF_INPUT, p_index)) {
 		drc->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		drc->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_DRC_OTF_INPUT);
@@ -850,7 +848,7 @@ void fimc_is_set_initial_params(struct f
 	fimc_is_set_param_bit(is, PARAM_DRC_DMA_INPUT);
 
 	drc->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
-	if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index1)) {
+	if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index)) {
 		drc->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		drc->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_DRC_OTF_OUTPUT);
@@ -865,7 +863,7 @@ void fimc_is_set_initial_params(struct f
 	fd->control.bypass = CONTROL_BYPASS_DISABLE;
 
 	fd->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
-	if (!test_bit((PARAM_FD_OTF_INPUT - 32), p_index2)) {
+	if (!test_bit(PARAM_FD_OTF_INPUT, p_index)) {
 		fd->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		fd->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_FD_OTF_INPUT);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-isp.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-isp.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-isp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-isp.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,8 +30,8 @@
 #include "fimc-is-regs.h"
 #include "fimc-is.h"
 
-static int debug;
-module_param_named(debug_isp, debug, int, S_IRUGO | S_IWUSR);
+int fimc_isp_debug;
+module_param_named(debug_isp, fimc_isp_debug, int, S_IRUGO | S_IWUSR);
 
 static const struct fimc_fmt fimc_isp_formats[FIMC_ISP_NUM_FORMATS] = {
 	{
@@ -128,57 +128,70 @@ static int fimc_isp_subdev_get_fmt(struc
 				   struct v4l2_subdev_format *fmt)
 {
 	struct fimc_isp *isp = v4l2_get_subdevdata(sd);
-	struct fimc_is *is = fimc_isp_to_is(isp);
 	struct v4l2_mbus_framefmt *mf = &fmt->format;
-	struct v4l2_mbus_framefmt cur_fmt;
 
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		mf = v4l2_subdev_get_try_format(fh, fmt->pad);
-		fmt->format = *mf;
+		*mf = *v4l2_subdev_get_try_format(fh, fmt->pad);
 		return 0;
 	}
 
 	mf->colorspace = V4L2_COLORSPACE_SRGB;
 
 	mutex_lock(&isp->subdev_lock);
-	__is_get_frame_size(is, &cur_fmt);
 
 	if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
-		/* full camera input frame size */
-		mf->width = cur_fmt.width + FIMC_ISP_CAC_MARGIN_WIDTH;
-		mf->height = cur_fmt.height + FIMC_ISP_CAC_MARGIN_HEIGHT;
-		mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
+		/* ISP OTF input image format */
+		*mf = isp->sink_fmt;
 	} else {
-		/* crop size */
-		mf->width = cur_fmt.width;
-		mf->height = cur_fmt.height;
-		mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+		/* ISP OTF output image format */
+		*mf = isp->src_fmt;
+
+		if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
+			mf->colorspace = V4L2_COLORSPACE_JPEG;
+			mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+		}
 	}
 
 	mutex_unlock(&isp->subdev_lock);
 
-	v4l2_dbg(1, debug, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n",
-		 __func__, fmt->pad, mf->code, mf->width, mf->height);
+	isp_dbg(1, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n", __func__,
+		fmt->pad, mf->code, mf->width, mf->height);
 
 	return 0;
 }
 
 static void __isp_subdev_try_format(struct fimc_isp *isp,
-				   struct v4l2_subdev_format *fmt)
+				    struct v4l2_subdev_fh *fh,
+				    struct v4l2_subdev_format *fmt)
 {
 	struct v4l2_mbus_framefmt *mf = &fmt->format;
+	struct v4l2_mbus_framefmt *format;
+
+	mf->colorspace = V4L2_COLORSPACE_SRGB;
 
 	if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
 		v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
 				FIMC_ISP_SINK_WIDTH_MAX, 0,
 				&mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
 				FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
-		isp->subdev_fmt = *mf;
+		mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
 	} else {
+		if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+			format = v4l2_subdev_get_try_format(fh,
+						FIMC_ISP_SD_PAD_SINK);
+		else
+			format = &isp->sink_fmt;
+
 		/* Allow changing format only on sink pad */
-		mf->width = isp->subdev_fmt.width - FIMC_ISP_CAC_MARGIN_WIDTH;
-		mf->height = isp->subdev_fmt.height - FIMC_ISP_CAC_MARGIN_HEIGHT;
-		mf->code = isp->subdev_fmt.code;
+		mf->width = format->width - FIMC_ISP_CAC_MARGIN_WIDTH;
+		mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT;
+
+		if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
+			mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+			mf->colorspace = V4L2_COLORSPACE_JPEG;
+		} else {
+			mf->code = format->code;
+		}
 	}
 }
 
@@ -191,27 +204,50 @@ static int fimc_isp_subdev_set_fmt(struc
 	struct v4l2_mbus_framefmt *mf = &fmt->format;
 	int ret = 0;
 
-	v4l2_dbg(1, debug, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
+	isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
 		 __func__, fmt->pad, mf->code, mf->width, mf->height);
 
-	mf->colorspace = V4L2_COLORSPACE_SRGB;
-
 	mutex_lock(&isp->subdev_lock);
-	__isp_subdev_try_format(isp, fmt);
+	__isp_subdev_try_format(isp, fh, fmt);
 
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
 		mf = v4l2_subdev_get_try_format(fh, fmt->pad);
 		*mf = fmt->format;
-		mutex_unlock(&isp->subdev_lock);
-		return 0;
+
+		/* Propagate format to the source pads */
+		if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+			struct v4l2_subdev_format format = *fmt;
+			unsigned int pad;
+
+			for (pad = FIMC_ISP_SD_PAD_SRC_FIFO;
+					pad < FIMC_ISP_SD_PADS_NUM; pad++) {
+				format.pad = pad;
+				__isp_subdev_try_format(isp, fh, &format);
+				mf = v4l2_subdev_get_try_format(fh, pad);
+				*mf = format.format;
+			}
+		}
+	} else {
+		if (sd->entity.stream_count == 0) {
+			if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+				struct v4l2_subdev_format format = *fmt;
+
+				isp->sink_fmt = *mf;
+
+				format.pad = FIMC_ISP_SD_PAD_SRC_DMA;
+				__isp_subdev_try_format(isp, fh, &format);
+
+				isp->src_fmt = format.format;
+				__is_set_frame_size(is, &isp->src_fmt);
+			} else {
+				isp->src_fmt = *mf;
+			}
+		} else {
+			ret = -EBUSY;
+		}
 	}
 
-	if (sd->entity.stream_count == 0)
-		__is_set_frame_size(is, mf);
-	else
-		ret = -EBUSY;
 	mutex_unlock(&isp->subdev_lock);
-
 	return ret;
 }
 
@@ -221,7 +257,7 @@ static int fimc_isp_subdev_s_stream(stru
 	struct fimc_is *is = fimc_isp_to_is(isp);
 	int ret;
 
-	v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on);
+	isp_dbg(1, sd, "%s: on: %d\n", __func__, on);
 
 	if (!test_bit(IS_ST_INIT_DONE, &is->state))
 		return -EBUSY;
@@ -235,8 +271,8 @@ static int fimc_isp_subdev_s_stream(stru
 				return ret;
 		}
 
-		v4l2_dbg(1, debug, sd, "changing mode to %d\n",
-						is->config_index);
+		isp_dbg(1, sd, "changing mode to %d\n", is->config_index);
+
 		ret = fimc_is_itf_mode_change(is);
 		if (ret)
 			return -EINVAL;
@@ -317,8 +353,8 @@ static int fimc_isp_subdev_s_power(struc
 		clear_bit(IS_ST_PWR_ON, &is->state);
 		clear_bit(IS_ST_INIT_DONE, &is->state);
 		is->state = 0;
-		is->config[is->config_index].p_region_index1 = 0;
-		is->config[is->config_index].p_region_index2 = 0;
+		is->config[is->config_index].p_region_index[0] = 0;
+		is->config[is->config_index].p_region_index[1] = 0;
 		set_bit(IS_ST_IDLE, &is->state);
 		wmb();
 	}
@@ -609,6 +645,22 @@ static const struct v4l2_ctrl_ops fimc_i
 	.s_ctrl	= fimc_is_s_ctrl,
 };
 
+static void __isp_subdev_set_default_format(struct fimc_isp *isp)
+{
+	struct fimc_is *is = fimc_isp_to_is(isp);
+
+	isp->sink_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH +
+				FIMC_ISP_CAC_MARGIN_WIDTH;
+	isp->sink_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT +
+				FIMC_ISP_CAC_MARGIN_HEIGHT;
+	isp->sink_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10;
+
+	isp->src_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH;
+	isp->src_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT;
+	isp->src_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10;
+	__is_set_frame_size(is, &isp->src_fmt);
+}
+
 int fimc_isp_subdev_create(struct fimc_isp *isp)
 {
 	const struct v4l2_ctrl_ops *ops = &fimc_isp_ctrl_ops;
@@ -689,6 +741,8 @@ int fimc_isp_subdev_create(struct fimc_i
 	sd->entity.ops = &fimc_is_subdev_media_ops;
 	v4l2_set_subdevdata(sd, isp);
 
+	__isp_subdev_set_default_format(isp);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-isp.h linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-isp.h
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-isp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-isp.h	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,11 @@
 #include <media/v4l2-mediabus.h>
 #include <media/s5p_fimc.h>
 
+extern int fimc_isp_debug;
+
+#define isp_dbg(level, dev, fmt, arg...) \
+	v4l2_dbg(level, fimc_isp_debug, dev, fmt, ## arg)
+
 /* FIXME: revisit these constraints */
 #define FIMC_ISP_SINK_WIDTH_MIN		(16 + 8)
 #define FIMC_ISP_SINK_HEIGHT_MIN	(12 + 8)
@@ -118,7 +123,6 @@ struct fimc_is_video {
 	unsigned int		frame_count;
 	unsigned int		reqbufs_count;
 	int			streaming;
-	unsigned long		payload[FIMC_ISP_MAX_PLANES];
 	const struct fimc_fmt	*format;
 };
 
@@ -128,15 +132,9 @@ struct fimc_is_video {
  * @alloc_ctx: videobuf2 memory allocator context
  * @subdev: ISP v4l2_subdev
  * @subdev_pads: the ISP subdev media pads
- * @ctrl_handler: v4l2 controls handler
  * @test_pattern: test pattern controls
- * @pipeline: video capture pipeline data structure
+ * @ctrls: v4l2 controls structure
  * @video_lock: mutex serializing video device and the subdev operations
- * @fmt: pointer to color format description structure
- * @payload: image size in bytes (w x h x bpp)
- * @inp_frame: camera input frame structure
- * @out_frame: DMA output frame structure
- * @source_subdev_grp_id: group id of remote source subdev
  * @cac_margin_x: horizontal CAC margin in pixels
  * @cac_margin_y: vertical CAC margin in pixels
  * @state: driver state flags
@@ -147,17 +145,14 @@ struct fimc_isp {
 	struct vb2_alloc_ctx		*alloc_ctx;
 	struct v4l2_subdev		subdev;
 	struct media_pad		subdev_pads[FIMC_ISP_SD_PADS_NUM];
-	struct v4l2_mbus_framefmt	subdev_fmt;
+	struct v4l2_mbus_framefmt	src_fmt;
+	struct v4l2_mbus_framefmt	sink_fmt;
 	struct v4l2_ctrl		*test_pattern;
 	struct fimc_isp_ctrls		ctrls;
 
 	struct mutex			video_lock;
 	struct mutex			subdev_lock;
 
-	struct fimc_isp_frame		inp_frame;
-	struct fimc_isp_frame		out_frame;
-	unsigned int			source_subdev_grp_id;
-
 	unsigned int			cac_margin_x;
 	unsigned int			cac_margin_y;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is-regs.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is-regs.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-is-regs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-is-regs.c	2013-08-25 20:43:22.000000000 -0400
@@ -89,8 +89,8 @@ int fimc_is_hw_set_param(struct fimc_is
 	mcuctl_write(is->config_index, is, MCUCTL_REG_ISSR(2));
 
 	mcuctl_write(param_count, is, MCUCTL_REG_ISSR(3));
-	mcuctl_write(config->p_region_index1, is, MCUCTL_REG_ISSR(4));
-	mcuctl_write(config->p_region_index2, is, MCUCTL_REG_ISSR(5));
+	mcuctl_write(config->p_region_index[0], is, MCUCTL_REG_ISSR(4));
+	mcuctl_write(config->p_region_index[1], is, MCUCTL_REG_ISSR(5));
 
 	fimc_is_hw_set_intgr0_gd0(is);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-lite.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-lite.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-lite.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-lite.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * Samsung EXYNOS FIMC-LITE (camera host interface) driver
 *
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -32,6 +32,7 @@
 #include <media/videobuf2-dma-contig.h>
 #include <media/s5p_fimc.h>
 
+#include "common.h"
 #include "fimc-core.h"
 #include "fimc-lite.h"
 #include "fimc-lite-reg.h"
@@ -43,6 +44,7 @@ static const struct fimc_fmt fimc_lite_f
 	{
 		.name		= "YUV 4:2:2 packed, YCbYCr",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_YCBYCR422,
 		.memplanes	= 1,
@@ -51,6 +53,7 @@ static const struct fimc_fmt fimc_lite_f
 	}, {
 		.name		= "YUV 4:2:2 packed, CbYCrY",
 		.fourcc		= V4L2_PIX_FMT_UYVY,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_CBYCRY422,
 		.memplanes	= 1,
@@ -59,6 +62,7 @@ static const struct fimc_fmt fimc_lite_f
 	}, {
 		.name		= "YUV 4:2:2 packed, CrYCbY",
 		.fourcc		= V4L2_PIX_FMT_VYUY,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_CRYCBY422,
 		.memplanes	= 1,
@@ -67,6 +71,7 @@ static const struct fimc_fmt fimc_lite_f
 	}, {
 		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.fourcc		= V4L2_PIX_FMT_YVYU,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_YCRYCB422,
 		.memplanes	= 1,
@@ -75,6 +80,7 @@ static const struct fimc_fmt fimc_lite_f
 	}, {
 		.name		= "RAW8 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
 		.depth		= { 8 },
 		.color		= FIMC_FMT_RAW8,
 		.memplanes	= 1,
@@ -83,6 +89,7 @@ static const struct fimc_fmt fimc_lite_f
 	}, {
 		.name		= "RAW10 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG10,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
 		.depth		= { 10 },
 		.color		= FIMC_FMT_RAW10,
 		.memplanes	= 1,
@@ -91,6 +98,7 @@ static const struct fimc_fmt fimc_lite_f
 	}, {
 		.name		= "RAW12 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG12,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
 		.depth		= { 12 },
 		.color		= FIMC_FMT_RAW12,
 		.memplanes	= 1,
@@ -131,30 +139,6 @@ static const struct fimc_fmt *fimc_lite_
 	return def_fmt;
 }
 
-/* Called with the media graph mutex held or @me stream_count > 0. */
-static struct v4l2_subdev *__find_remote_sensor(struct media_entity *me)
-{
-	struct media_pad *pad = &me->pads[0];
-	struct v4l2_subdev *sd;
-
-	while (pad->flags & MEDIA_PAD_FL_SINK) {
-		/* source pad */
-		pad = media_entity_remote_source(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
-			break;
-
-		sd = media_entity_to_v4l2_subdev(pad->entity);
-
-		if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR ||
-		    sd->grp_id == GRP_ID_SENSOR)
-			return sd;
-		/* sink pad */
-		pad = &sd->entity.pads[0];
-	}
-	return NULL;
-}
-
 static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
 {
 	struct fimc_source_info *si;
@@ -176,6 +160,7 @@ static int fimc_lite_hw_init(struct fimc
 	flite_hw_set_camera_bus(fimc, si);
 	flite_hw_set_source_format(fimc, &fimc->inp_frame);
 	flite_hw_set_window_offset(fimc, &fimc->inp_frame);
+	flite_hw_set_dma_buf_mask(fimc, 0);
 	flite_hw_set_output_dma(fimc, &fimc->out_frame, !isp_output);
 	flite_hw_set_interrupt_mask(fimc);
 	flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
@@ -233,7 +218,7 @@ static int fimc_lite_reinit(struct fimc_
 	if (!streaming)
 		return 0;
 
-	return fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 0);
+	return fimc_pipeline_call(&fimc->ve, set_stream, 0);
 }
 
 static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
@@ -299,19 +284,23 @@ static irqreturn_t flite_irq_handler(int
 
 	if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
 	    test_bit(ST_FLITE_RUN, &fimc->state) &&
-	    !list_empty(&fimc->active_buf_q) &&
 	    !list_empty(&fimc->pending_buf_q)) {
+		vbuf = fimc_lite_pending_queue_pop(fimc);
+		flite_hw_set_dma_buffer(fimc, vbuf);
+		fimc_lite_active_queue_add(fimc, vbuf);
+	}
+
+	if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMEND) &&
+	    test_bit(ST_FLITE_RUN, &fimc->state) &&
+	    !list_empty(&fimc->active_buf_q)) {
 		vbuf = fimc_lite_active_queue_pop(fimc);
 		ktime_get_ts(&ts);
 		tv = &vbuf->vb.v4l2_buf.timestamp;
 		tv->tv_sec = ts.tv_sec;
 		tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 		vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
+		flite_hw_mask_dma_buffer(fimc, vbuf->index);
 		vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
-
-		vbuf = fimc_lite_pending_queue_pop(fimc);
-		flite_hw_set_output_addr(fimc, vbuf->paddr);
-		fimc_lite_active_queue_add(fimc, vbuf);
 	}
 
 	if (test_bit(ST_FLITE_CONFIG, &fimc->state))
@@ -330,10 +319,16 @@ done:
 static int start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct fimc_lite *fimc = q->drv_priv;
+	unsigned long flags;
 	int ret;
 
+	spin_lock_irqsave(&fimc->slock, flags);
+
+	fimc->buf_index = 0;
 	fimc->frame_count = 0;
 
+	spin_unlock_irqrestore(&fimc->slock, flags);
+
 	ret = fimc_lite_hw_init(fimc, false);
 	if (ret) {
 		fimc_lite_reinit(fimc, false);
@@ -347,8 +342,7 @@ static int start_streaming(struct vb2_qu
 		flite_hw_capture_start(fimc);
 
 		if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
-			fimc_pipeline_call(fimc, set_stream,
-					   &fimc->pipeline, 1);
+			fimc_pipeline_call(&fimc->ve, set_stream, 1);
 	}
 	if (debug > 0)
 		flite_hw_dump_regs(fimc, __func__);
@@ -415,7 +409,7 @@ static int buffer_prepare(struct vb2_buf
 		unsigned long size = fimc->payload[i];
 
 		if (vb2_plane_size(vb, i) < size) {
-			v4l2_err(&fimc->vfd,
+			v4l2_err(&fimc->ve.vdev,
 				 "User buffer too small (%ld < %ld)\n",
 				 vb2_plane_size(vb, i), size);
 			return -EINVAL;
@@ -436,10 +430,14 @@ static void buffer_queue(struct vb2_buff
 	spin_lock_irqsave(&fimc->slock, flags);
 	buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
 
+	buf->index = fimc->buf_index++;
+	if (fimc->buf_index >= fimc->reqbufs_count)
+		fimc->buf_index = 0;
+
 	if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
 	    !test_bit(ST_FLITE_STREAM, &fimc->state) &&
 	    list_empty(&fimc->active_buf_q)) {
-		flite_hw_set_output_addr(fimc, buf->paddr);
+		flite_hw_set_dma_buffer(fimc, buf);
 		fimc_lite_active_queue_add(fimc, buf);
 	} else {
 		fimc_lite_pending_queue_add(fimc, buf);
@@ -452,8 +450,7 @@ static void buffer_queue(struct vb2_buff
 		spin_unlock_irqrestore(&fimc->slock, flags);
 
 		if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
-			fimc_pipeline_call(fimc, set_stream,
-					   &fimc->pipeline, 1);
+			fimc_pipeline_call(&fimc->ve, set_stream, 1);
 		return;
 	}
 	spin_unlock_irqrestore(&fimc->slock, flags);
@@ -481,11 +478,9 @@ static void fimc_lite_clear_event_counte
 static int fimc_lite_open(struct file *file)
 {
 	struct fimc_lite *fimc = video_drvdata(file);
-	struct media_entity *me = &fimc->vfd.entity;
+	struct media_entity *me = &fimc->ve.vdev.entity;
 	int ret;
 
-	mutex_lock(&me->parent->graph_mutex);
-
 	mutex_lock(&fimc->lock);
 	if (atomic_read(&fimc->out_path) != FIMC_IO_DMA) {
 		ret = -EBUSY;
@@ -505,11 +500,18 @@ static int fimc_lite_open(struct file *f
 	    atomic_read(&fimc->out_path) != FIMC_IO_DMA)
 		goto unlock;
 
-	ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
-						me, true);
+	mutex_lock(&me->parent->graph_mutex);
+
+	ret = fimc_pipeline_call(&fimc->ve, open, me, true);
+
+	/* Mark video pipeline ending at this video node as in use. */
+	if (ret == 0)
+		me->use_count++;
+
+	mutex_unlock(&me->parent->graph_mutex);
+
 	if (!ret) {
 		fimc_lite_clear_event_counters(fimc);
-		fimc->ref_count++;
 		goto unlock;
 	}
 
@@ -519,26 +521,29 @@ err_pm:
 	clear_bit(ST_FLITE_IN_USE, &fimc->state);
 unlock:
 	mutex_unlock(&fimc->lock);
-	mutex_unlock(&me->parent->graph_mutex);
 	return ret;
 }
 
 static int fimc_lite_release(struct file *file)
 {
 	struct fimc_lite *fimc = video_drvdata(file);
+	struct media_entity *entity = &fimc->ve.vdev.entity;
 
 	mutex_lock(&fimc->lock);
 
 	if (v4l2_fh_is_singular_file(file) &&
 	    atomic_read(&fimc->out_path) == FIMC_IO_DMA) {
 		if (fimc->streaming) {
-			media_entity_pipeline_stop(&fimc->vfd.entity);
+			media_entity_pipeline_stop(entity);
 			fimc->streaming = false;
 		}
-		clear_bit(ST_FLITE_IN_USE, &fimc->state);
 		fimc_lite_stop_capture(fimc, false);
-		fimc_pipeline_call(fimc, close, &fimc->pipeline);
-		fimc->ref_count--;
+		fimc_pipeline_call(&fimc->ve, close);
+		clear_bit(ST_FLITE_IN_USE, &fimc->state);
+
+		mutex_lock(&entity->parent->graph_mutex);
+		entity->use_count--;
+		mutex_unlock(&entity->parent->graph_mutex);
 	}
 
 	vb2_fop_release(file);
@@ -562,37 +567,54 @@ static const struct v4l2_file_operations
  * Format and crop negotiation helpers
  */
 
-static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
-					u32 *width, u32 *height,
-					u32 *code, u32 *fourcc, int pad)
+static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
+					struct v4l2_subdev_fh *fh,
+					struct v4l2_subdev_format *format)
 {
 	struct flite_drvdata *dd = fimc->dd;
-	const struct fimc_fmt *fmt;
-	unsigned int flags = 0;
+	struct v4l2_mbus_framefmt *mf = &format->format;
+	const struct fimc_fmt *fmt = NULL;
 
-	if (pad == FLITE_SD_PAD_SINK) {
-		v4l_bound_align_image(width, 8, dd->max_width,
-				      ffs(dd->out_width_align) - 1,
-				      height, 0, dd->max_height, 0, 0);
+	if (format->pad == FLITE_SD_PAD_SINK) {
+		v4l_bound_align_image(&mf->width, 8, dd->max_width,
+				ffs(dd->out_width_align) - 1,
+				&mf->height, 0, dd->max_height, 0, 0);
+
+		fmt = fimc_lite_find_format(NULL, &mf->code, 0, 0);
+		if (WARN_ON(!fmt))
+			return NULL;
+
+		mf->colorspace = fmt->colorspace;
+		mf->code = fmt->mbus_code;
 	} else {
-		v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
-				      ffs(dd->out_width_align) - 1,
-				      height, 0, fimc->inp_frame.rect.height,
-				      0, 0);
-		flags = fimc->inp_frame.fmt->flags;
-	}
+		struct flite_frame *sink = &fimc->inp_frame;
+		struct v4l2_mbus_framefmt *sink_fmt;
+		struct v4l2_rect *rect;
 
-	fmt = fimc_lite_find_format(fourcc, code, flags, 0);
-	if (WARN_ON(!fmt))
-		return NULL;
+		if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+			sink_fmt = v4l2_subdev_get_try_format(fh,
+						FLITE_SD_PAD_SINK);
 
-	if (code)
-		*code = fmt->mbus_code;
-	if (fourcc)
-		*fourcc = fmt->fourcc;
+			mf->code = sink_fmt->code;
+			mf->colorspace = sink_fmt->colorspace;
 
-	v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
-		 code ? *code : 0, *width, *height);
+			rect = v4l2_subdev_get_try_crop(fh,
+						FLITE_SD_PAD_SINK);
+		} else {
+			mf->code = sink->fmt->mbus_code;
+			mf->colorspace = sink->fmt->colorspace;
+			rect = &sink->rect;
+		}
+
+		/* Allow changing format only on sink pad */
+		mf->width = rect->width;
+		mf->height = rect->height;
+	}
+
+	mf->field = V4L2_FIELD_NONE;
+
+	v4l2_dbg(1, debug, &fimc->subdev, "code: %#x (%d), %dx%d\n",
+		 mf->code, mf->colorspace, mf->width, mf->height);
 
 	return fmt;
 }
@@ -637,13 +659,18 @@ static void fimc_lite_try_compose(struct
 /*
  * Video node ioctl operations
  */
-static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
+static int fimc_lite_querycap(struct file *file, void *priv,
 					struct v4l2_capability *cap)
 {
+	struct fimc_lite *fimc = video_drvdata(file);
+
 	strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
-	cap->bus_info[0] = 0;
-	cap->card[0] = 0;
-	cap->capabilities = V4L2_CAP_STREAMING;
+	strlcpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+					dev_name(&fimc->pdev->dev));
+
+	cap->device_caps = V4L2_CAP_STREAMING;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -679,7 +706,7 @@ static int fimc_lite_g_fmt_mplane(struct
 	pixm->width = frame->f_width;
 	pixm->height = frame->f_height;
 	pixm->field = V4L2_FIELD_NONE;
-	pixm->colorspace = V4L2_COLORSPACE_JPEG;
+	pixm->colorspace = fmt->colorspace;
 	return 0;
 }
 
@@ -722,7 +749,7 @@ static int fimc_lite_try_fmt(struct fimc
 						fmt->depth[0]) / 8;
 	pixm->num_planes = fmt->memplanes;
 	pixm->pixelformat = fmt->fourcc;
-	pixm->colorspace = V4L2_COLORSPACE_JPEG;
+	pixm->colorspace = fmt->colorspace;
 	pixm->field = V4L2_FIELD_NONE;
 	return 0;
 }
@@ -786,7 +813,7 @@ static int fimc_pipeline_validate(struct
 				return -EPIPE;
 		}
 		/* Retrieve format at the source pad */
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (pad == NULL ||
 		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 			break;
@@ -810,14 +837,13 @@ static int fimc_lite_streamon(struct fil
 			      enum v4l2_buf_type type)
 {
 	struct fimc_lite *fimc = video_drvdata(file);
-	struct media_entity *entity = &fimc->vfd.entity;
-	struct fimc_pipeline *p = &fimc->pipeline;
+	struct media_entity *entity = &fimc->ve.vdev.entity;
 	int ret;
 
 	if (fimc_lite_active(fimc))
 		return -EBUSY;
 
-	ret = media_entity_pipeline_start(entity, p->m_pipeline);
+	ret = media_entity_pipeline_start(entity, &fimc->ve.pipe->mp);
 	if (ret < 0)
 		return ret;
 
@@ -825,7 +851,7 @@ static int fimc_lite_streamon(struct fil
 	if (ret < 0)
 		goto err_p_stop;
 
-	fimc->sensor = __find_remote_sensor(&fimc->subdev.entity);
+	fimc->sensor = fimc_find_remote_sensor(&fimc->subdev.entity);
 
 	ret = vb2_ioctl_streamon(file, priv, type);
 	if (!ret) {
@@ -848,7 +874,7 @@ static int fimc_lite_streamoff(struct fi
 	if (ret < 0)
 		return ret;
 
-	media_entity_pipeline_stop(&fimc->vfd.entity);
+	media_entity_pipeline_stop(&fimc->ve.vdev.entity);
 	fimc->streaming = false;
 	return 0;
 }
@@ -938,7 +964,7 @@ static int fimc_lite_s_selection(struct
 }
 
 static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
-	.vidioc_querycap		= fimc_vidioc_querycap_capture,
+	.vidioc_querycap		= fimc_lite_querycap,
 	.vidioc_enum_fmt_vid_cap_mplane	= fimc_lite_enum_fmt_mplane,
 	.vidioc_try_fmt_vid_cap_mplane	= fimc_lite_try_fmt_mplane,
 	.vidioc_s_fmt_vid_cap_mplane	= fimc_lite_s_fmt_mplane,
@@ -972,8 +998,6 @@ static int fimc_lite_link_setup(struct m
 		 __func__, remote->entity->name, local->entity->name,
 		 flags, fimc->source_subdev_grp_id);
 
-	mutex_lock(&fimc->lock);
-
 	switch (local->index) {
 	case FLITE_SD_PAD_SINK:
 		if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) {
@@ -1015,7 +1039,6 @@ static int fimc_lite_link_setup(struct m
 	}
 	mb();
 
-	mutex_unlock(&fimc->lock);
 	return ret;
 }
 
@@ -1036,6 +1059,15 @@ static int fimc_lite_subdev_enum_mbus_co
 	return 0;
 }
 
+static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt(
+			struct v4l2_subdev_fh *fh, unsigned int pad)
+{
+	if (pad != FLITE_SD_PAD_SINK)
+		pad = FLITE_SD_PAD_SOURCE_DMA;
+
+	return v4l2_subdev_get_try_format(fh, pad);
+}
+
 static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
 				    struct v4l2_subdev_fh *fh,
 				    struct v4l2_subdev_format *fmt)
@@ -1045,13 +1077,13 @@ static int fimc_lite_subdev_get_fmt(stru
 	struct flite_frame *f = &fimc->inp_frame;
 
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+		mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
 		fmt->format = *mf;
 		return 0;
 	}
-	mf->colorspace = V4L2_COLORSPACE_JPEG;
 
 	mutex_lock(&fimc->lock);
+	mf->colorspace = f->fmt->colorspace;
 	mf->code = f->fmt->mbus_code;
 
 	if (fmt->pad == FLITE_SD_PAD_SINK) {
@@ -1080,7 +1112,6 @@ static int fimc_lite_subdev_set_fmt(stru
 	v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d\n",
 		 fmt->pad, mf->code, mf->width, mf->height);
 
-	mf->colorspace = V4L2_COLORSPACE_JPEG;
 	mutex_lock(&fimc->lock);
 
 	if ((atomic_read(&fimc->out_path) == FIMC_IO_ISP &&
@@ -1091,12 +1122,20 @@ static int fimc_lite_subdev_set_fmt(stru
 		return -EBUSY;
 	}
 
-	ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
-				    &mf->code, NULL, fmt->pad);
+	ffmt = fimc_lite_subdev_try_fmt(fimc, fh, fmt);
 
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+		struct v4l2_mbus_framefmt *src_fmt;
+
+		mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
 		*mf = fmt->format;
+
+		if (fmt->pad == FLITE_SD_PAD_SINK) {
+			unsigned int pad = FLITE_SD_PAD_SOURCE_DMA;
+			src_fmt = __fimc_lite_subdev_get_try_fmt(fh, pad);
+			*src_fmt = *mf;
+		}
+
 		mutex_unlock(&fimc->lock);
 		return 0;
 	}
@@ -1114,11 +1153,6 @@ static int fimc_lite_subdev_set_fmt(stru
 		source->rect = sink->rect;
 		source->f_width = mf->width;
 		source->f_height = mf->height;
-	} else {
-		/* Allow changing format only on sink pad */
-		mf->code = sink->fmt->mbus_code;
-		mf->width = sink->rect.width;
-		mf->height = sink->rect.height;
 	}
 
 	mutex_unlock(&fimc->lock);
@@ -1207,7 +1241,7 @@ static int fimc_lite_subdev_s_stream(str
 	 * The pipeline links are protected through entity.stream_count
 	 * so there is no need to take the media graph mutex here.
 	 */
-	fimc->sensor = __find_remote_sensor(&sd->entity);
+	fimc->sensor = fimc_find_remote_sensor(&sd->entity);
 
 	if (atomic_read(&fimc->out_path) != FIMC_IO_ISP)
 		return -ENOIOCTLCMD;
@@ -1252,13 +1286,10 @@ static int fimc_lite_subdev_registered(s
 {
 	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
 	struct vb2_queue *q = &fimc->vb_queue;
-	struct video_device *vfd = &fimc->vfd;
+	struct video_device *vfd = &fimc->ve.vdev;
 	int ret;
 
 	memset(vfd, 0, sizeof(*vfd));
-
-	fimc->inp_frame.fmt = &fimc_lite_formats[0];
-	fimc->out_frame.fmt = &fimc_lite_formats[0];
 	atomic_set(&fimc->out_path, FIMC_IO_DMA);
 
 	snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
@@ -1295,12 +1326,12 @@ static int fimc_lite_subdev_registered(s
 		return ret;
 
 	video_set_drvdata(vfd, fimc);
-	fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
+	fimc->ve.pipe = v4l2_get_subdev_hostdata(sd);
 
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
 		media_entity_cleanup(&vfd->entity);
-		fimc->pipeline_ops = NULL;
+		fimc->ve.pipe = NULL;
 		return ret;
 	}
 
@@ -1316,11 +1347,15 @@ static void fimc_lite_subdev_unregistere
 	if (fimc == NULL)
 		return;
 
-	if (video_is_registered(&fimc->vfd)) {
-		video_unregister_device(&fimc->vfd);
-		media_entity_cleanup(&fimc->vfd.entity);
-		fimc->pipeline_ops = NULL;
+	mutex_lock(&fimc->lock);
+
+	if (video_is_registered(&fimc->ve.vdev)) {
+		video_unregister_device(&fimc->ve.vdev);
+		media_entity_cleanup(&fimc->ve.vdev.entity);
+		fimc->ve.pipe = NULL;
 	}
+
+	mutex_unlock(&fimc->lock);
 }
 
 static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
@@ -1370,6 +1405,23 @@ static const struct v4l2_ctrl_config fim
 	.step	= 1,
 };
 
+static void fimc_lite_set_default_config(struct fimc_lite *fimc)
+{
+	struct flite_frame *sink = &fimc->inp_frame;
+	struct flite_frame *source = &fimc->out_frame;
+
+	sink->fmt = &fimc_lite_formats[0];
+	sink->f_width = FLITE_DEFAULT_WIDTH;
+	sink->f_height = FLITE_DEFAULT_HEIGHT;
+
+	sink->rect.width = FLITE_DEFAULT_WIDTH;
+	sink->rect.height = FLITE_DEFAULT_HEIGHT;
+	sink->rect.left = 0;
+	sink->rect.top = 0;
+
+	*source = *sink;
+}
+
 static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
 {
 	struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
@@ -1417,12 +1469,12 @@ static void fimc_lite_unregister_capture
 
 static void fimc_lite_clk_put(struct fimc_lite *fimc)
 {
-	if (IS_ERR_OR_NULL(fimc->clock))
+	if (IS_ERR(fimc->clock))
 		return;
 
 	clk_unprepare(fimc->clock);
 	clk_put(fimc->clock);
-	fimc->clock = NULL;
+	fimc->clock = ERR_PTR(-EINVAL);
 }
 
 static int fimc_lite_clk_get(struct fimc_lite *fimc)
@@ -1436,7 +1488,7 @@ static int fimc_lite_clk_get(struct fimc
 	ret = clk_prepare(fimc->clock);
 	if (ret < 0) {
 		clk_put(fimc->clock);
-		fimc->clock = NULL;
+		fimc->clock = ERR_PTR(-EINVAL);
 	}
 	return ret;
 }
@@ -1461,13 +1513,14 @@ static int fimc_lite_probe(struct platfo
 		if (of_id)
 			drv_data = (struct flite_drvdata *)of_id->data;
 		fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
-	} else {
-		drv_data = fimc_lite_get_drvdata(pdev);
-		fimc->index = pdev->id;
 	}
 
-	if (!drv_data || fimc->index < 0 || fimc->index >= FIMC_LITE_MAX_DEVS)
+	if (!drv_data || fimc->index >= drv_data->num_instances ||
+						fimc->index < 0) {
+		dev_err(dev, "Wrong %s node alias\n",
+					dev->of_node->full_name);
 		return -EINVAL;
+	}
 
 	fimc->dd = drv_data;
 	fimc->pdev = pdev;
@@ -1514,8 +1567,11 @@ static int fimc_lite_probe(struct platfo
 		ret = PTR_ERR(fimc->alloc_ctx);
 		goto err_pm;
 	}
+
 	pm_runtime_put(dev);
 
+	fimc_lite_set_default_config(fimc);
+
 	dev_dbg(dev, "FIMC-LITE.%d registered successfully\n",
 		fimc->index);
 	return 0;
@@ -1565,8 +1621,8 @@ static int fimc_lite_resume(struct devic
 		return 0;
 
 	INIT_LIST_HEAD(&fimc->active_buf_q);
-	fimc_pipeline_call(fimc, open, &fimc->pipeline,
-			   &fimc->vfd.entity, false);
+	fimc_pipeline_call(&fimc->ve, open,
+			   &fimc->ve.vdev.entity, false);
 	fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP);
 	clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
 
@@ -1592,7 +1648,7 @@ static int fimc_lite_suspend(struct devi
 	if (ret < 0 || !fimc_lite_active(fimc))
 		return ret;
 
-	return fimc_pipeline_call(fimc, close, &fimc->pipeline);
+	return fimc_pipeline_call(&fimc->ve, close);
 }
 #endif /* CONFIG_PM_SLEEP */
 
@@ -1624,22 +1680,30 @@ static struct flite_drvdata fimc_lite_dr
 	.out_width_align	= 8,
 	.win_hor_offs_align	= 2,
 	.out_hor_offs_align	= 8,
+	.max_dma_bufs		= 1,
+	.num_instances		= 2,
 };
 
-static struct platform_device_id fimc_lite_driver_ids[] = {
-	{
-		.name		= "exynos-fimc-lite",
-		.driver_data	= (unsigned long)&fimc_lite_drvdata_exynos4,
-	},
-	{ /* sentinel */ },
+/* EXYNOS5250 */
+static struct flite_drvdata fimc_lite_drvdata_exynos5 = {
+	.max_width		= 8192,
+	.max_height		= 8192,
+	.out_width_align	= 8,
+	.win_hor_offs_align	= 2,
+	.out_hor_offs_align	= 8,
+	.max_dma_bufs		= 32,
+	.num_instances		= 3,
 };
-MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids);
 
 static const struct of_device_id flite_of_match[] = {
 	{
 		.compatible = "samsung,exynos4212-fimc-lite",
 		.data = &fimc_lite_drvdata_exynos4,
 	},
+	{
+		.compatible = "samsung,exynos5250-fimc-lite",
+		.data = &fimc_lite_drvdata_exynos5,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, flite_of_match);
@@ -1647,7 +1711,6 @@ MODULE_DEVICE_TABLE(of, flite_of_match);
 static struct platform_driver fimc_lite_driver = {
 	.probe		= fimc_lite_probe,
 	.remove		= fimc_lite_remove,
-	.id_table	= fimc_lite_driver_ids,
 	.driver = {
 		.of_match_table = flite_of_match,
 		.name		= FIMC_LITE_DRV_NAME,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-lite.h linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-lite.h
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-lite.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-lite.h	2013-08-25 20:43:22.000000000 -0400
@@ -27,8 +27,10 @@
 
 #define FIMC_LITE_DRV_NAME	"exynos-fimc-lite"
 #define FLITE_CLK_NAME		"flite"
-#define FIMC_LITE_MAX_DEVS	2
+#define FIMC_LITE_MAX_DEVS	3
 #define FLITE_REQ_BUFS_MIN	2
+#define FLITE_DEFAULT_WIDTH	640
+#define FLITE_DEFAULT_HEIGHT	480
 
 /* Bit index definitions for struct fimc_lite::state */
 enum {
@@ -48,17 +50,28 @@ enum {
 #define FLITE_SD_PAD_SOURCE_ISP	2
 #define FLITE_SD_PADS_NUM	3
 
+/**
+ * struct flite_drvdata - FIMC-LITE IP variant data structure
+ * @max_width: maximum camera interface input width in pixels
+ * @max_height: maximum camera interface input height in pixels
+ * @out_width_align: minimum output width alignment in pixels
+ * @win_hor_offs_align: minimum camera interface crop window horizontal
+ * 			offset alignment in pixels
+ * @out_hor_offs_align: minimum output DMA compose rectangle horizontal
+ * 			offset alignment in pixels
+ * @max_dma_bufs: number of output DMA buffer start address registers
+ * @num_instances: total number of FIMC-LITE IP instances available
+ */
 struct flite_drvdata {
 	unsigned short max_width;
 	unsigned short max_height;
 	unsigned short out_width_align;
 	unsigned short win_hor_offs_align;
 	unsigned short out_hor_offs_align;
+	unsigned short max_dma_bufs;
+	unsigned short num_instances;
 };
 
-#define fimc_lite_get_drvdata(_pdev) \
-	((struct flite_drvdata *) platform_get_device_id(_pdev)->driver_data)
-
 struct fimc_lite_events {
 	unsigned int data_overflow;
 };
@@ -83,20 +96,22 @@ struct flite_frame {
  * struct flite_buffer - video buffer structure
  * @vb:    vb2 buffer
  * @list:  list head for the buffers queue
- * @paddr: precalculated physical address
+ * @paddr: DMA buffer start address
+ * @index: DMA start address register's index
  */
 struct flite_buffer {
 	struct vb2_buffer vb;
 	struct list_head list;
 	dma_addr_t paddr;
+	unsigned short index;
 };
 
 /**
  * struct fimc_lite - fimc lite structure
  * @pdev: pointer to FIMC-LITE platform device
  * @dd: SoC specific driver data structure
+ * @ve: exynos video device entity structure
  * @v4l2_dev: pointer to top the level v4l2_device
- * @vfd: video device node
  * @fh: v4l2 file handle
  * @alloc_ctx: videobuf2 memory allocator context
  * @subdev: FIMC-LITE subdev
@@ -122,16 +137,16 @@ struct flite_buffer {
  * @pending_buf_q: pending buffers queue head
  * @active_buf_q: the queue head of buffers scheduled in hardware
  * @vb_queue: vb2 buffers queue
+ * @buf_index: helps to keep track of the DMA start address register index
  * @active_buf_count: number of video buffers scheduled in hardware
  * @frame_count: the captured frames counter
  * @reqbufs_count: the number of buffers requested with REQBUFS ioctl
- * @ref_count: driver's private reference counter
  */
 struct fimc_lite {
 	struct platform_device	*pdev;
 	struct flite_drvdata	*dd;
+	struct exynos_video_entity ve;
 	struct v4l2_device	*v4l2_dev;
-	struct video_device	vfd;
 	struct v4l2_fh		fh;
 	struct vb2_alloc_ctx	*alloc_ctx;
 	struct v4l2_subdev	subdev;
@@ -141,8 +156,6 @@ struct fimc_lite {
 	struct v4l2_ctrl_handler ctrl_handler;
 	struct v4l2_ctrl	*test_pattern;
 	int			index;
-	struct fimc_pipeline	pipeline;
-	const struct fimc_pipeline_ops *pipeline_ops;
 
 	struct mutex		lock;
 	spinlock_t		slock;
@@ -161,9 +174,9 @@ struct fimc_lite {
 	struct list_head	pending_buf_q;
 	struct list_head	active_buf_q;
 	struct vb2_queue	vb_queue;
+	unsigned short		buf_index;
 	unsigned int		frame_count;
 	unsigned int		reqbufs_count;
-	int			ref_count;
 
 	struct fimc_lite_events	events;
 	bool			streaming;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-lite-reg.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-lite-reg.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-lite-reg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-lite-reg.c	2013-08-25 20:43:22.000000000 -0400
@@ -2,15 +2,16 @@
  * Register interface file for EXYNOS FIMC-LITE (camera interface) driver
  *
  * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
 */
 
-#include <linux/io.h>
+#include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 #include <media/s5p_fimc.h>
 
 #include "fimc-lite-reg.h"
@@ -68,7 +69,8 @@ void flite_hw_set_interrupt_mask(struct
 	if (atomic_read(&dev->out_path) == FIMC_IO_DMA) {
 		intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
 			 FLITE_REG_CIGCTRL_IRQ_LASTEN |
-			 FLITE_REG_CIGCTRL_IRQ_STARTEN;
+			 FLITE_REG_CIGCTRL_IRQ_STARTEN |
+			 FLITE_REG_CIGCTRL_IRQ_ENDEN;
 	} else {
 		/* An output to the FIMC-IS */
 		intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
@@ -137,7 +139,7 @@ void flite_hw_set_source_format(struct f
 	}
 
 	if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
-		v4l2_err(&dev->vfd,
+		v4l2_err(&dev->ve.vdev,
 			 "Unsupported pixel code, falling back to %#08x\n",
 			 src_pixfmt_map[i][0]);
 	}
@@ -215,6 +217,18 @@ void flite_hw_set_camera_bus(struct fimc
 	flite_hw_set_camera_port(dev, si->mux_id);
 }
 
+static void flite_hw_set_pack12(struct fimc_lite *dev, int on)
+{
+	u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
+
+	cfg &= ~FLITE_REG_CIODMAFMT_PACK12;
+
+	if (on)
+		cfg |= FLITE_REG_CIODMAFMT_PACK12;
+
+	writel(cfg, dev->regs + FLITE_REG_CIODMAFMT);
+}
+
 static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
 {
 	static const u32 pixcode[4][2] = {
@@ -250,6 +264,38 @@ void flite_hw_set_dma_window(struct fimc
 	writel(cfg, dev->regs + FLITE_REG_CIOOFF);
 }
 
+void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf)
+{
+	unsigned int index;
+	u32 cfg;
+
+	if (dev->dd->max_dma_bufs == 1)
+		index = 0;
+	else
+		index = buf->index;
+
+	if (index == 0)
+		writel(buf->paddr, dev->regs + FLITE_REG_CIOSA);
+	else
+		writel(buf->paddr, dev->regs + FLITE_REG_CIOSAN(index - 1));
+
+	cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
+	cfg |= BIT(index);
+	writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
+}
+
+void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index)
+{
+	u32 cfg;
+
+	if (dev->dd->max_dma_bufs == 1)
+		index = 0;
+
+	cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
+	cfg &= ~BIT(index);
+	writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
+}
+
 /* Enable/disable output DMA, set output pixel size and offsets (composition) */
 void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
 			     bool enable)
@@ -267,6 +313,7 @@ void flite_hw_set_output_dma(struct fimc
 
 	flite_hw_set_out_order(dev, f);
 	flite_hw_set_dma_window(dev, f);
+	flite_hw_set_pack12(dev, 0);
 }
 
 void flite_hw_dump_regs(struct fimc_lite *dev, const char *label)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-lite-reg.h linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-lite-reg.h
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-lite-reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-lite-reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -120,6 +120,9 @@
 /* b0: 1 - camera B, 0 - camera A */
 #define FLITE_REG_CIGENERAL_CAM_B		(1 << 0)
 
+#define FLITE_REG_CIFCNTSEQ			0x100
+#define FLITE_REG_CIOSAN(x)			(0x200 + (4 * (x)))
+
 /* ----------------------------------------------------------------------------
  * Function declarations
  */
@@ -142,9 +145,12 @@ void flite_hw_set_output_dma(struct fimc
 void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
 void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
 void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
+void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf);
+void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index);
 
-static inline void flite_hw_set_output_addr(struct fimc_lite *dev, u32 paddr)
+static inline void flite_hw_set_dma_buf_mask(struct fimc_lite *dev, u32 mask)
 {
-	writel(paddr, dev->regs + FLITE_REG_CIOSA);
+	writel(mask, dev->regs + FLITE_REG_CIFCNTSEQ);
 }
+
 #endif /* FIMC_LITE_REG_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-m2m.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-m2m.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-m2m.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-m2m.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,7 @@
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-contig.h>
 
+#include "common.h"
 #include "fimc-core.h"
 #include "fimc-reg.h"
 #include "media-dev.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-reg.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-reg.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/fimc-reg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/fimc-reg.c	2013-08-25 20:43:22.000000000 -0400
@@ -618,7 +618,7 @@ int fimc_hw_set_camera_source(struct fim
 		}
 
 		if (i == ARRAY_SIZE(pix_desc)) {
-			v4l2_err(&vc->vfd,
+			v4l2_err(&vc->ve.vdev,
 				 "Camera color format not supported: %d\n",
 				 vc->ci_fmt.code);
 			return -EINVAL;
@@ -698,7 +698,7 @@ int fimc_hw_set_camera_type(struct fimc_
 			cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
 			break;
 		default:
-			v4l2_err(&vid_cap->vfd,
+			v4l2_err(&vid_cap->ve.vdev,
 				 "Not supported camera pixel format: %#x\n",
 				 vid_cap->ci_fmt.code);
 			return -EINVAL;
@@ -721,7 +721,8 @@ int fimc_hw_set_camera_type(struct fimc_
 			WARN_ONCE(1, "ISP Writeback input is not supported\n");
 		break;
 	default:
-		v4l2_err(&vid_cap->vfd, "Invalid FIMC bus type selected: %d\n",
+		v4l2_err(&vid_cap->ve.vdev,
+			 "Invalid FIMC bus type selected: %d\n",
 			 source->fimc_bus_type);
 		return -EINVAL;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/Kconfig
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,19 +1,24 @@
 
 config VIDEO_SAMSUNG_EXYNOS4_IS
 	bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver"
-	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && PLAT_S5P && PM_RUNTIME
+	depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && PM_RUNTIME
+	depends on (PLAT_S5P || ARCH_EXYNOS)
 	help
 	  Say Y here to enable camera host interface devices for
 	  Samsung S5P and EXYNOS SoC series.
 
 if VIDEO_SAMSUNG_EXYNOS4_IS
 
+config VIDEO_EXYNOS4_IS_COMMON
+       tristate
+
 config VIDEO_S5P_FIMC
 	tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"
 	depends on I2C
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_MEM2MEM_DEV
 	select MFD_SYSCON if OF
+	select VIDEO_EXYNOS4_IS_COMMON
 	help
 	  This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
 	  interface and video postprocessor (FIMC) devices.
@@ -38,6 +43,7 @@ config VIDEO_EXYNOS_FIMC_LITE
 	tristate "EXYNOS FIMC-LITE camera interface driver"
 	depends on I2C
 	select VIDEOBUF2_DMA_CONTIG
+	select VIDEO_EXYNOS4_IS_COMMON
 	help
 	  This is a V4L2 driver for Samsung EXYNOS4/5 SoC FIMC-LITE camera
 	  host interface.
@@ -58,4 +64,4 @@ config VIDEO_EXYNOS4_FIMC_IS
 	  To compile this driver as a module, choose M here: the
 	  module will be called exynos4-fimc-is.
 
-endif # VIDEO_SAMSUNG_S5P_FIMC
+endif # VIDEO_SAMSUNG_EXYNOS4_IS
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/Makefile linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/Makefile
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,10 +1,13 @@
 s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o media-dev.o
 exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o
+s5p-csis-objs := mipi-csis.o
+exynos4-is-common-objs := common.o
+
 exynos-fimc-is-objs := fimc-is.o fimc-isp.o fimc-is-sensor.o fimc-is-regs.o
 exynos-fimc-is-objs += fimc-is-param.o fimc-is-errno.o fimc-is-i2c.o
-s5p-csis-objs := mipi-csis.o
 
 obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS)	+= s5p-csis.o
 obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE)	+= exynos-fimc-lite.o
 obj-$(CONFIG_VIDEO_EXYNOS4_FIMC_IS)	+= exynos-fimc-is.o
 obj-$(CONFIG_VIDEO_S5P_FIMC)		+= s5p-fimc.o
+obj-$(CONFIG_VIDEO_EXYNOS4_IS_COMMON)	+= exynos4-is-common.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/media-dev.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/media-dev.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/media-dev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/media-dev.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,8 +1,8 @@
 /*
  * S5P/EXYNOS4 SoC series camera host interface media device driver
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
@@ -39,6 +39,26 @@
 static int __fimc_md_set_camclk(struct fimc_md *fmd,
 				struct fimc_source_info *si,
 				bool on);
+
+/* Set up image sensor subdev -> FIMC capture node notifications. */
+static void __setup_sensor_notification(struct fimc_md *fmd,
+					struct v4l2_subdev *sensor,
+					struct v4l2_subdev *fimc_sd)
+{
+	struct fimc_source_info *src_inf;
+	struct fimc_sensor_info *md_si;
+	unsigned long flags;
+
+	src_inf = v4l2_get_subdev_hostdata(sensor);
+	if (!src_inf || WARN_ON(fmd == NULL))
+		return;
+
+	md_si = source_to_sensor_info(src_inf);
+	spin_lock_irqsave(&fmd->slock, flags);
+	md_si->host = v4l2_get_subdevdata(fimc_sd);
+	spin_unlock_irqrestore(&fmd->slock, flags);
+}
+
 /**
  * fimc_pipeline_prepare - update pipeline information with subdevice pointers
  * @me: media entity terminating the pipeline
@@ -46,9 +66,11 @@ static int __fimc_md_set_camclk(struct f
  * Caller holds the graph mutex.
  */
 static void fimc_pipeline_prepare(struct fimc_pipeline *p,
-				  struct media_entity *me)
+					struct media_entity *me)
 {
+	struct fimc_md *fmd = entity_to_fimc_mdev(me);
 	struct v4l2_subdev *sd;
+	struct v4l2_subdev *sensor = NULL;
 	int i;
 
 	for (i = 0; i < IDX_MAX; i++)
@@ -62,7 +84,7 @@ static void fimc_pipeline_prepare(struct
 			struct media_pad *spad = &me->pads[i];
 			if (!(spad->flags & MEDIA_PAD_FL_SINK))
 				continue;
-			pad = media_entity_remote_source(spad);
+			pad = media_entity_remote_pad(spad);
 			if (pad)
 				break;
 		}
@@ -73,8 +95,10 @@ static void fimc_pipeline_prepare(struct
 		sd = media_entity_to_v4l2_subdev(pad->entity);
 
 		switch (sd->grp_id) {
-		case GRP_ID_FIMC_IS_SENSOR:
 		case GRP_ID_SENSOR:
+			sensor = sd;
+			/* fall through */
+		case GRP_ID_FIMC_IS_SENSOR:
 			p->subdevs[IDX_SENSOR] = sd;
 			break;
 		case GRP_ID_CSIS:
@@ -84,7 +108,7 @@ static void fimc_pipeline_prepare(struct
 			p->subdevs[IDX_FLITE] = sd;
 			break;
 		case GRP_ID_FIMC:
-			/* No need to control FIMC subdev through subdev ops */
+			p->subdevs[IDX_FIMC] = sd;
 			break;
 		case GRP_ID_FIMC_IS:
 			p->subdevs[IDX_IS_ISP] = sd;
@@ -96,6 +120,9 @@ static void fimc_pipeline_prepare(struct
 		if (me->num_pads == 1)
 			break;
 	}
+
+	if (sensor && p->subdevs[IDX_FIMC])
+		__setup_sensor_notification(fmd, sensor, p->subdevs[IDX_FIMC]);
 }
 
 /**
@@ -168,10 +195,11 @@ error:
  *
  * Called with the graph mutex held.
  */
-static int __fimc_pipeline_open(struct fimc_pipeline *p,
+static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
 				struct media_entity *me, bool prepare)
 {
 	struct fimc_md *fmd = entity_to_fimc_mdev(me);
+	struct fimc_pipeline *p = to_fimc_pipeline(ep);
 	struct v4l2_subdev *sd;
 	int ret;
 
@@ -214,20 +242,21 @@ err_wbclk:
  *
  * Disable power of all subdevs and turn the external sensor clock off.
  */
-static int __fimc_pipeline_close(struct fimc_pipeline *p)
+static int __fimc_pipeline_close(struct exynos_media_pipeline *ep)
 {
+	struct fimc_pipeline *p = to_fimc_pipeline(ep);
 	struct v4l2_subdev *sd = p ? p->subdevs[IDX_SENSOR] : NULL;
 	struct fimc_md *fmd;
-	int ret = 0;
-
-	if (WARN_ON(sd == NULL))
-		return -EINVAL;
+	int ret;
 
-	if (p->subdevs[IDX_SENSOR]) {
-		ret = fimc_pipeline_s_power(p, 0);
-		fimc_md_set_camclk(sd, false);
+	if (sd == NULL) {
+		pr_warn("%s(): No sensor subdev\n", __func__);
+		return 0;
 	}
 
+	ret = fimc_pipeline_s_power(p, 0);
+	fimc_md_set_camclk(sd, false);
+
 	fmd = entity_to_fimc_mdev(&sd->entity);
 
 	/* Disable PXLASYNC clock if this pipeline includes FIMC-IS */
@@ -242,12 +271,13 @@ static int __fimc_pipeline_close(struct
  * @pipeline: video pipeline structure
  * @on: passed as the s_stream() callback argument
  */
-static int __fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
+static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on)
 {
 	static const u8 seq[2][IDX_MAX] = {
 		{ IDX_FIMC, IDX_SENSOR, IDX_IS_ISP, IDX_CSIS, IDX_FLITE },
 		{ IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP },
 	};
+	struct fimc_pipeline *p = to_fimc_pipeline(ep);
 	int i, ret = 0;
 
 	if (p->subdevs[IDX_SENSOR] == NULL)
@@ -271,12 +301,38 @@ error:
 }
 
 /* Media pipeline operations for the FIMC/FIMC-LITE video device driver */
-static const struct fimc_pipeline_ops fimc_pipeline_ops = {
+static const struct exynos_media_pipeline_ops fimc_pipeline_ops = {
 	.open		= __fimc_pipeline_open,
 	.close		= __fimc_pipeline_close,
 	.set_stream	= __fimc_pipeline_s_stream,
 };
 
+static struct exynos_media_pipeline *fimc_md_pipeline_create(
+						struct fimc_md *fmd)
+{
+	struct fimc_pipeline *p;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return NULL;
+
+	list_add_tail(&p->list, &fmd->pipelines);
+
+	p->ep.ops = &fimc_pipeline_ops;
+	return &p->ep;
+}
+
+static void fimc_md_pipelines_free(struct fimc_md *fmd)
+{
+	while (!list_empty(&fmd->pipelines)) {
+		struct fimc_pipeline *p;
+
+		p = list_entry(fmd->pipelines.next, typeof(*p), list);
+		list_del(&p->list);
+		kfree(p);
+	}
+}
+
 /*
  * Sensor subdevice helper functions
  */
@@ -592,6 +648,7 @@ static int register_fimc_lite_entity(str
 				     struct fimc_lite *fimc_lite)
 {
 	struct v4l2_subdev *sd;
+	struct exynos_media_pipeline *ep;
 	int ret;
 
 	if (WARN_ON(fimc_lite->index >= FIMC_LITE_MAX_DEVS ||
@@ -600,7 +657,12 @@ static int register_fimc_lite_entity(str
 
 	sd = &fimc_lite->subdev;
 	sd->grp_id = GRP_ID_FLITE;
-	v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
+
+	ep = fimc_md_pipeline_create(fmd);
+	if (!ep)
+		return -ENOMEM;
+
+	v4l2_set_subdev_hostdata(sd, ep);
 
 	ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
 	if (!ret)
@@ -614,6 +676,7 @@ static int register_fimc_lite_entity(str
 static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc)
 {
 	struct v4l2_subdev *sd;
+	struct exynos_media_pipeline *ep;
 	int ret;
 
 	if (WARN_ON(fimc->id >= FIMC_MAX_DEVS || fmd->fimc[fimc->id]))
@@ -621,7 +684,12 @@ static int register_fimc_entity(struct f
 
 	sd = &fimc->vid_cap.subdev;
 	sd->grp_id = GRP_ID_FIMC;
-	v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
+
+	ep = fimc_md_pipeline_create(fmd);
+	if (!ep)
+		return -ENOMEM;
+
+	v4l2_set_subdev_hostdata(sd, ep);
 
 	ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
 	if (!ret) {
@@ -736,8 +804,6 @@ static int fimc_md_pdev_match(struct dev
 
 	if (!strcmp(pdev->name, CSIS_DRIVER_NAME)) {
 		plat_entity = IDX_CSIS;
-	} else if (!strcmp(pdev->name, FIMC_LITE_DRV_NAME)) {
-		plat_entity = IDX_FLITE;
 	} else {
 		p = strstr(pdev->name, "fimc");
 		if (p && *(p + 4) == 0)
@@ -797,17 +863,19 @@ static void fimc_md_unregister_entities(
 	int i;
 
 	for (i = 0; i < FIMC_MAX_DEVS; i++) {
-		if (fmd->fimc[i] == NULL)
+		struct fimc_dev *dev = fmd->fimc[i];
+		if (dev == NULL)
 			continue;
-		v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
-		fmd->fimc[i]->pipeline_ops = NULL;
+		v4l2_device_unregister_subdev(&dev->vid_cap.subdev);
+		dev->vid_cap.ve.pipe = NULL;
 		fmd->fimc[i] = NULL;
 	}
 	for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
-		if (fmd->fimc_lite[i] == NULL)
+		struct fimc_lite *dev = fmd->fimc_lite[i];
+		if (dev == NULL)
 			continue;
-		v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
-		fmd->fimc_lite[i]->pipeline_ops = NULL;
+		v4l2_device_unregister_subdev(&dev->subdev);
+		dev->ve.pipe = NULL;
 		fmd->fimc_lite[i] = NULL;
 	}
 	for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
@@ -880,18 +948,6 @@ static int __fimc_md_create_fimc_sink_li
 
 		v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]\n",
 			  source->name, flags ? '=' : '-', sink->name);
-
-		if (flags == 0 || sensor == NULL)
-			continue;
-
-		if (!WARN_ON(si == NULL)) {
-			unsigned long irq_flags;
-			struct fimc_sensor_info *inf = source_to_sensor_info(si);
-
-			spin_lock_irqsave(&fmd->slock, irq_flags);
-			inf->host = fmd->fimc[i];
-			spin_unlock_irqrestore(&fmd->slock, irq_flags);
-		}
 	}
 
 	for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
@@ -929,7 +985,7 @@ static int __fimc_md_create_flite_source
 			continue;
 
 		source = &fimc->subdev.entity;
-		sink = &fimc->vfd.entity;
+		sink = &fimc->ve.vdev.entity;
 		/* FIMC-LITE's subdev and video node */
 		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
 					       sink, 0, 0);
@@ -1066,7 +1122,7 @@ static int fimc_md_create_links(struct f
 			continue;
 
 		source = &fmd->fimc[i]->vid_cap.subdev.entity;
-		sink = &fmd->fimc[i]->vid_cap.vfd.entity;
+		sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
 
 		ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
 					      sink, 0, flags);
@@ -1231,66 +1287,98 @@ int fimc_md_set_camclk(struct v4l2_subde
 	return __fimc_md_set_camclk(fmd, si, on);
 }
 
-static int fimc_md_link_notify(struct media_pad *source,
-			       struct media_pad *sink, u32 flags)
+static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
 {
-	struct fimc_lite *fimc_lite = NULL;
-	struct fimc_dev *fimc = NULL;
-	struct fimc_pipeline *pipeline;
-	struct v4l2_subdev *sd;
-	struct mutex *lock;
-	int i, ret = 0;
-	int ref_count;
+	struct exynos_video_entity *ve;
+	struct fimc_pipeline *p;
+	struct video_device *vdev;
+	int ret;
 
-	if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	vdev = media_entity_to_video_device(entity);
+	if (vdev->entity.use_count == 0)
 		return 0;
 
-	sd = media_entity_to_v4l2_subdev(sink->entity);
-
-	switch (sd->grp_id) {
-	case GRP_ID_FLITE:
-		fimc_lite = v4l2_get_subdevdata(sd);
-		if (WARN_ON(fimc_lite == NULL))
-			return 0;
-		pipeline = &fimc_lite->pipeline;
-		lock = &fimc_lite->lock;
-		break;
-	case GRP_ID_FIMC:
-		fimc = v4l2_get_subdevdata(sd);
-		if (WARN_ON(fimc == NULL))
-			return 0;
-		pipeline = &fimc->pipeline;
-		lock = &fimc->lock;
-		break;
-	default:
+	ve = vdev_to_exynos_video_entity(vdev);
+	p = to_fimc_pipeline(ve->pipe);
+	/*
+	 * Nothing to do if we are disabling the pipeline, some link
+	 * has been disconnected and p->subdevs array is cleared now.
+	 */
+	if (!enable && p->subdevs[IDX_SENSOR] == NULL)
 		return 0;
+
+	if (enable)
+		ret = __fimc_pipeline_open(ve->pipe, entity, true);
+	else
+		ret = __fimc_pipeline_close(ve->pipe);
+
+	if (ret == 0 && !enable)
+		memset(p->subdevs, 0, sizeof(p->subdevs));
+
+	return ret;
+}
+
+/* Locking: called with entity->parent->graph_mutex mutex held. */
+static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
+{
+	struct media_entity *entity_err = entity;
+	struct media_entity_graph graph;
+	int ret;
+
+	/*
+	 * Walk current graph and call the pipeline open/close routine for each
+	 * opened video node that belongs to the graph of entities connected
+	 * through active links. This is needed as we cannot power on/off the
+	 * subdevs in random order.
+	 */
+	media_entity_graph_walk_start(&graph, entity);
+
+	while ((entity = media_entity_graph_walk_next(&graph))) {
+		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+			continue;
+
+		ret  = __fimc_md_modify_pipeline(entity, enable);
+
+		if (ret < 0)
+			goto err;
 	}
 
-	mutex_lock(lock);
-	ref_count = fimc ? fimc->vid_cap.refcnt : fimc_lite->ref_count;
+	return 0;
+ err:
+	media_entity_graph_walk_start(&graph, entity_err);
 
-	if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-		if (ref_count > 0) {
-			ret = __fimc_pipeline_close(pipeline);
-			if (!ret && fimc)
-				fimc_ctrls_delete(fimc->vid_cap.ctx);
-		}
-		for (i = 0; i < IDX_MAX; i++)
-			pipeline->subdevs[i] = NULL;
-	} else if (ref_count > 0) {
-		/*
-		 * Link activation. Enable power of pipeline elements only if
-		 * the pipeline is already in use, i.e. its video node is open.
-		 * Recreate the controls destroyed during the link deactivation.
-		 */
-		ret = __fimc_pipeline_open(pipeline,
-					   source->entity, true);
-		if (!ret && fimc)
-			ret = fimc_capture_ctrls_create(fimc);
+	while ((entity_err = media_entity_graph_walk_next(&graph))) {
+		if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE)
+			continue;
+
+		__fimc_md_modify_pipeline(entity_err, !enable);
+
+		if (entity_err == entity)
+			break;
 	}
 
-	mutex_unlock(lock);
-	return ret ? -EPIPE : ret;
+	return ret;
+}
+
+static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
+				unsigned int notification)
+{
+	struct media_entity *sink = link->sink->entity;
+	int ret = 0;
+
+	/* Before link disconnection */
+	if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
+		if (!(flags & MEDIA_LNK_FL_ENABLED))
+			ret = __fimc_md_modify_pipelines(sink, false);
+		else
+			; /* TODO: Link state change validation */
+	/* After link activation */
+	} else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+		   (link->flags & MEDIA_LNK_FL_ENABLED)) {
+		ret = __fimc_md_modify_pipelines(sink, true);
+	}
+
+	return ret ? -EPIPE : 0;
 }
 
 static ssize_t fimc_md_sysfs_show(struct device *dev,
@@ -1370,6 +1458,7 @@ static int fimc_md_probe(struct platform
 
 	spin_lock_init(&fmd->slock);
 	fmd->pdev = pdev;
+	INIT_LIST_HEAD(&fmd->pipelines);
 
 	strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
 		sizeof(fmd->media_dev.model));
@@ -1457,6 +1546,7 @@ static int fimc_md_remove(struct platfor
 		return 0;
 	device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
 	fimc_md_unregister_entities(fmd);
+	fimc_md_pipelines_free(fmd);
 	media_device_unregister(&fmd->media_dev);
 	fimc_md_put_clocks(fmd);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/media-dev.h linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/media-dev.h
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/media-dev.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/media-dev.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
 #include <media/media-entity.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
+#include <media/s5p_fimc.h>
 
 #include "fimc-core.h"
 #include "fimc-lite.h"
@@ -40,6 +41,29 @@ enum {
 	FIMC_MAX_WBCLKS
 };
 
+enum fimc_subdev_index {
+	IDX_SENSOR,
+	IDX_CSIS,
+	IDX_FLITE,
+	IDX_IS_ISP,
+	IDX_FIMC,
+	IDX_MAX,
+};
+
+/*
+ * This structure represents a chain of media entities, including a data
+ * source entity (e.g. an image sensor subdevice), a data capture entity
+ * - a video capture device node and any remaining entities.
+ */
+struct fimc_pipeline {
+	struct exynos_media_pipeline ep;
+	struct list_head list;
+	struct media_entity *vdev_entity;
+	struct v4l2_subdev *subdevs[IDX_MAX];
+};
+
+#define to_fimc_pipeline(_ep) container_of(_ep, struct fimc_pipeline, ep)
+
 struct fimc_csis_info {
 	struct v4l2_subdev *sd;
 	int id;
@@ -104,17 +128,11 @@ struct fimc_md {
 		struct pinctrl_state *state_idle;
 	} pinctl;
 	bool user_subdev_api;
+
 	spinlock_t slock;
+	struct list_head pipelines;
 };
 
-#define is_subdev_pad(pad) (pad == NULL || \
-	media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV)
-
-#define me_subtype(me) \
-	((me->type) & (MEDIA_ENT_TYPE_MASK | MEDIA_ENT_SUBTYPE_MASK))
-
-#define subdev_has_devnode(__sd) (__sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)
-
 static inline
 struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
 {
@@ -127,14 +145,14 @@ static inline struct fimc_md *entity_to_
 		container_of(me->parent, struct fimc_md, media_dev);
 }
 
-static inline void fimc_md_graph_lock(struct fimc_dev *fimc)
+static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
 {
-	mutex_lock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
+	mutex_lock(&ve->vdev.entity.parent->graph_mutex);
 }
 
-static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
+static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
 {
-	mutex_unlock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
+	mutex_unlock(&ve->vdev.entity.parent->graph_mutex);
 }
 
 int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
@@ -149,4 +167,16 @@ static inline bool fimc_md_is_isp_availa
 #define fimc_md_is_isp_available(node) (false)
 #endif /* CONFIG_OF */
 
+static inline struct v4l2_subdev *__fimc_md_get_subdev(
+				struct exynos_media_pipeline *ep,
+				unsigned int index)
+{
+	struct fimc_pipeline *p = to_fimc_pipeline(ep);
+
+	if (!p || index >= IDX_MAX)
+		return NULL;
+	else
+		return p->subdevs[index];
+}
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/mipi-csis.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/mipi-csis.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos4-is/mipi-csis.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos4-is/mipi-csis.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,8 +1,8 @@
 /*
- * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
+ * Samsung S5P/EXYNOS SoC series MIPI-CSI receiver driver
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -66,11 +66,12 @@ MODULE_PARM_DESC(debug, "Debug level (0-
 
 /* Interrupt mask */
 #define S5PCSIS_INTMSK			0x10
-#define S5PCSIS_INTMSK_EN_ALL		0xf000103f
 #define S5PCSIS_INTMSK_EVEN_BEFORE	(1 << 31)
 #define S5PCSIS_INTMSK_EVEN_AFTER	(1 << 30)
 #define S5PCSIS_INTMSK_ODD_BEFORE	(1 << 29)
 #define S5PCSIS_INTMSK_ODD_AFTER	(1 << 28)
+#define S5PCSIS_INTMSK_FRAME_START	(1 << 27)
+#define S5PCSIS_INTMSK_FRAME_END	(1 << 26)
 #define S5PCSIS_INTMSK_ERR_SOT_HS	(1 << 12)
 #define S5PCSIS_INTMSK_ERR_LOST_FS	(1 << 5)
 #define S5PCSIS_INTMSK_ERR_LOST_FE	(1 << 4)
@@ -78,6 +79,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-
 #define S5PCSIS_INTMSK_ERR_ECC		(1 << 2)
 #define S5PCSIS_INTMSK_ERR_CRC		(1 << 1)
 #define S5PCSIS_INTMSK_ERR_UNKNOWN	(1 << 0)
+#define S5PCSIS_INTMSK_EXYNOS4_EN_ALL	0xf000103f
+#define S5PCSIS_INTMSK_EXYNOS5_EN_ALL	0xfc00103f
 
 /* Interrupt source */
 #define S5PCSIS_INTSRC			0x14
@@ -88,6 +91,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-
 #define S5PCSIS_INTSRC_ODD_AFTER	(1 << 28)
 #define S5PCSIS_INTSRC_ODD		(0x3 << 28)
 #define S5PCSIS_INTSRC_NON_IMAGE_DATA	(0xff << 28)
+#define S5PCSIS_INTSRC_FRAME_START	(1 << 27)
+#define S5PCSIS_INTSRC_FRAME_END	(1 << 26)
 #define S5PCSIS_INTSRC_ERR_SOT_HS	(0xf << 12)
 #define S5PCSIS_INTSRC_ERR_LOST_FS	(1 << 5)
 #define S5PCSIS_INTSRC_ERR_LOST_FE	(1 << 4)
@@ -151,6 +156,9 @@ static const struct s5pcsis_event s5pcsi
 	{ S5PCSIS_INTSRC_EVEN_AFTER,	"Non-image data after even frame" },
 	{ S5PCSIS_INTSRC_ODD_BEFORE,	"Non-image data before odd frame" },
 	{ S5PCSIS_INTSRC_ODD_AFTER,	"Non-image data after odd frame" },
+	/* Frame start/end */
+	{ S5PCSIS_INTSRC_FRAME_START,	"Frame Start" },
+	{ S5PCSIS_INTSRC_FRAME_END,	"Frame End" },
 };
 #define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
 
@@ -159,6 +167,11 @@ struct csis_pktbuf {
 	unsigned int len;
 };
 
+struct csis_drvdata {
+	/* Mask of all used interrupts in S5PCSIS_INTMSK register */
+	u32 interrupt_mask;
+};
+
 /**
  * struct csis_state - the driver's internal state data structure
  * @lock: mutex serializing the subdev and power management operations,
@@ -171,6 +184,7 @@ struct csis_pktbuf {
  * @supplies: CSIS regulator supplies
  * @clock: CSIS clocks
  * @irq: requested s5p-mipi-csis irq number
+ * @interrupt_mask: interrupt mask of the all used interrupts
  * @flags: the state variable for power and streaming control
  * @clock_frequency: device bus clock frequency
  * @hs_settle: HS-RX settle time
@@ -193,6 +207,7 @@ struct csis_state {
 	struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
 	struct clk *clock[NUM_CSIS_CLOCKS];
 	int irq;
+	u32 interrupt_mask;
 	u32 flags;
 
 	u32 clk_frequency;
@@ -274,9 +289,10 @@ static const struct csis_pix_format *fin
 static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
 {
 	u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
-
-	val = on ? val | S5PCSIS_INTMSK_EN_ALL :
-		   val & ~S5PCSIS_INTMSK_EN_ALL;
+	if (on)
+		val |= state->interrupt_mask;
+	else
+		val &= ~state->interrupt_mask;
 	s5pcsis_write(state, S5PCSIS_INTMSK, val);
 }
 
@@ -771,8 +787,12 @@ static int s5pcsis_parse_dt(struct platf
 #define s5pcsis_parse_dt(pdev, state) (-ENOSYS)
 #endif
 
+static const struct of_device_id s5pcsis_of_match[];
+
 static int s5pcsis_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *of_id;
+	const struct csis_drvdata *drv_data;
 	struct device *dev = &pdev->dev;
 	struct resource *mem_res;
 	struct csis_state *state;
@@ -787,10 +807,19 @@ static int s5pcsis_probe(struct platform
 	spin_lock_init(&state->slock);
 	state->pdev = pdev;
 
-	if (dev->of_node)
+	if (dev->of_node) {
+		of_id = of_match_node(s5pcsis_of_match, dev->of_node);
+		if (WARN_ON(of_id == NULL))
+			return -EINVAL;
+
+		drv_data = of_id->data;
+		state->interrupt_mask = drv_data->interrupt_mask;
+
 		ret = s5pcsis_parse_dt(pdev, state);
-	else
+	} else {
 		ret = s5pcsis_get_platform_data(pdev, state);
+	}
+
 	if (ret < 0)
 		return ret;
 
@@ -994,9 +1023,25 @@ static const struct dev_pm_ops s5pcsis_p
 	SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
 };
 
+static const struct csis_drvdata exynos4_csis_drvdata = {
+	.interrupt_mask = S5PCSIS_INTMSK_EXYNOS4_EN_ALL,
+};
+
+static const struct csis_drvdata exynos5_csis_drvdata = {
+	.interrupt_mask = S5PCSIS_INTMSK_EXYNOS5_EN_ALL,
+};
+
 static const struct of_device_id s5pcsis_of_match[] = {
-	{ .compatible = "samsung,s5pv210-csis" },
-	{ .compatible = "samsung,exynos4210-csis" },
+	{
+		.compatible = "samsung,s5pv210-csis",
+		.data = &exynos4_csis_drvdata,
+	}, {
+		.compatible = "samsung,exynos4210-csis",
+		.data = &exynos4_csis_drvdata,
+	}, {
+		.compatible = "samsung,exynos5250-csis",
+		.data = &exynos5_csis_drvdata,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, s5pcsis_of_match);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/exynos-gsc/gsc-core.c linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos-gsc/gsc-core.c
--- linux-libre-3.10-gnu/drivers/media/platform/exynos-gsc/gsc-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/exynos-gsc/gsc-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -988,7 +988,7 @@ static void *gsc_get_drv_data(struct pla
 
 	if (pdev->dev.of_node) {
 		const struct of_device_id *match;
-		match = of_match_node(of_match_ptr(exynos_gsc_match),
+		match = of_match_node(exynos_gsc_match,
 					pdev->dev.of_node);
 		if (match)
 			driver_data = (struct gsc_driverdata *)match->data;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/fsl-viu.c linux-libre-3.11-rc7-gnu/drivers/media/platform/fsl-viu.c
--- linux-libre-3.10-gnu/drivers/media/platform/fsl-viu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/fsl-viu.c	2013-08-25 20:43:22.000000000 -0400
@@ -1475,7 +1475,6 @@ static struct video_device viu_template
 	.release	= video_device_release,
 
 	.tvnorms        = V4L2_STD_NTSC_M | V4L2_STD_PAL,
-	.current_norm   = V4L2_STD_NTSC_M,
 };
 
 static int viu_of_probe(struct platform_device *op)
@@ -1546,6 +1545,7 @@ static int viu_of_probe(struct platform_
 	viu_dev->vidq.timeout.function = viu_vid_timeout;
 	viu_dev->vidq.timeout.data     = (unsigned long)viu_dev;
 	init_timer(&viu_dev->vidq.timeout);
+	viu_dev->std = V4L2_STD_NTSC_M;
 	viu_dev->first = 1;
 
 	/* Allocate memory for video device */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/indycam.c linux-libre-3.11-rc7-gnu/drivers/media/platform/indycam.c
--- linux-libre-3.10-gnu/drivers/media/platform/indycam.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/indycam.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 #include "indycam.h"
 
@@ -283,20 +282,9 @@ static int indycam_s_ctrl(struct v4l2_su
 
 /* I2C-interface */
 
-static int indycam_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct indycam *camera = to_indycam(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM,
-		       camera->version);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops indycam_core_ops = {
-	.g_chip_ident = indycam_g_chip_ident,
 	.g_ctrl = indycam_g_ctrl,
 	.s_ctrl = indycam_s_ctrl,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/platform/Kconfig
--- linux-libre-3.10-gnu/drivers/media/platform/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,7 @@ source "drivers/media/platform/blackfin/
 config VIDEO_SH_VOU
 	tristate "SuperH VOU video output driver"
 	depends on MEDIA_CAMERA_SUPPORT
-	depends on VIDEO_DEV && ARCH_SHMOBILE
+	depends on VIDEO_DEV && ARCH_SHMOBILE && I2C
 	select VIDEOBUF_DMA_CONTIG
 	help
 	  Support for the Video Output Unit (VOU) on SuperH SoCs.
@@ -159,7 +159,7 @@ config VIDEO_MEM2MEM_DEINTERLACE
 
 config VIDEO_SAMSUNG_S5P_G2D
 	tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver"
-	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+	depends on VIDEO_DEV && VIDEO_V4L2 && (PLAT_S5P || ARCH_EXYNOS)
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_MEM2MEM_DEV
 	default n
@@ -169,7 +169,7 @@ config VIDEO_SAMSUNG_S5P_G2D
 
 config VIDEO_SAMSUNG_S5P_JPEG
 	tristate "Samsung S5P/Exynos4 JPEG codec driver"
-	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+	depends on VIDEO_DEV && VIDEO_V4L2 && (PLAT_S5P || ARCH_EXYNOS)
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_MEM2MEM_DEV
 	---help---
@@ -177,7 +177,7 @@ config VIDEO_SAMSUNG_S5P_JPEG
 
 config VIDEO_SAMSUNG_S5P_MFC
 	tristate "Samsung S5P MFC Video Codec"
-	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+	depends on VIDEO_DEV && VIDEO_V4L2 && (PLAT_S5P || ARCH_EXYNOS)
 	select VIDEOBUF2_DMA_CONTIG
 	default n
 	help
@@ -220,7 +220,7 @@ if V4L_TEST_DRIVERS
 config VIDEO_VIVI
 	tristate "Virtual Video Driver"
 	depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
-	depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
+	select FONT_SUPPORT
 	select FONT_8x16
 	select VIDEOBUF2_VMALLOC
 	default n
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/m2m-deinterlace.c linux-libre-3.11-rc7-gnu/drivers/media/platform/m2m-deinterlace.c
--- linux-libre-3.10-gnu/drivers/media/platform/m2m-deinterlace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/m2m-deinterlace.c	2013-08-25 20:43:22.000000000 -0400
@@ -1033,6 +1033,7 @@ static int deinterlace_probe(struct plat
 
 	*vfd = deinterlace_videodev;
 	vfd->lock = &pcdev->dev_mutex;
+	vfd->v4l2_dev = &pcdev->v4l2_dev;
 
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
 	if (ret) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/marvell-ccic/cafe-driver.c linux-libre-3.11-rc7-gnu/drivers/media/platform/marvell-ccic/cafe-driver.c
--- linux-libre-3.10-gnu/drivers/media/platform/marvell-ccic/cafe-driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/marvell-ccic/cafe-driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/device.h>
 #include <linux/wait.h>
 #include <linux/delay.h>
@@ -469,7 +468,7 @@ static int cafe_pci_probe(struct pci_dev
 		goto out;
 	cam->pdev = pdev;
 	mcam = &cam->mcam;
-	mcam->chip_id = V4L2_IDENT_CAFE;
+	mcam->chip_id = MCAM_CAFE;
 	spin_lock_init(&mcam->dev_lock);
 	init_waitqueue_head(&cam->smbus_wait);
 	mcam->plat_power_up = cafe_ctlr_power_up;
@@ -501,6 +500,7 @@ static int cafe_pci_probe(struct pci_dev
 		printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n");
 		goto out_disable;
 	}
+	mcam->regs_size = pci_resource_len(pdev, 0);
 	ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
 	if (ret)
 		goto out_iounmap;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/marvell-ccic/mcam-core.c linux-libre-3.11-rc7-gnu/drivers/media/platform/marvell-ccic/mcam-core.c
--- linux-libre-3.10-gnu/drivers/media/platform/marvell-ccic/mcam-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/marvell-ccic/mcam-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,6 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/ov7670.h>
 #include <media/videobuf2-vmalloc.h>
 #include <media/videobuf2-dma-contig.h>
@@ -336,7 +335,7 @@ static void mcam_ctlr_dma_vmalloc(struct
 		mcam_reg_clear_bit(cam, REG_CTRL1, C1_TWOBUFS);
 	} else
 		mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS);
-	if (cam->chip_id == V4L2_IDENT_CAFE)
+	if (cam->chip_id == MCAM_CAFE)
 		mcam_reg_write(cam, REG_UBAR, 0); /* 32 bits only */
 }
 
@@ -796,7 +795,6 @@ static int __mcam_cam_reset(struct mcam_
  */
 static int mcam_cam_init(struct mcam_camera *cam)
 {
-	struct v4l2_dbg_chip_ident chip;
 	int ret;
 
 	mutex_lock(&cam->s_mutex);
@@ -804,24 +802,8 @@ static int mcam_cam_init(struct mcam_cam
 		cam_warn(cam, "Cam init with device in funky state %d",
 				cam->state);
 	ret = __mcam_cam_reset(cam);
-	if (ret)
-		goto out;
-	chip.ident = V4L2_IDENT_NONE;
-	chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
-	chip.match.addr = cam->sensor_addr;
-	ret = sensor_call(cam, core, g_chip_ident, &chip);
-	if (ret)
-		goto out;
-	cam->sensor_type = chip.ident;
-	if (cam->sensor_type != V4L2_IDENT_OV7670) {
-		cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type);
-		ret = -EINVAL;
-		goto out;
-	}
-/* Get/set parameters? */
-	ret = 0;
+	/* Get/set parameters? */
 	cam->state = S_IDLE;
-out:
 	mcam_ctlr_power_down(cam);
 	mutex_unlock(&cam->s_mutex);
 	return ret;
@@ -1362,6 +1344,12 @@ static int mcam_vidioc_s_std(struct file
 	return 0;
 }
 
+static int mcam_vidioc_g_std(struct file *filp, void *priv, v4l2_std_id *a)
+{
+	*a = V4L2_STD_NTSC_M;
+	return 0;
+}
+
 /*
  * G/S_PARM.  Most of this is done by the sensor, but we are
  * the level which controls the number of read buffers.
@@ -1392,20 +1380,6 @@ static int mcam_vidioc_s_parm(struct fil
 	return ret;
 }
 
-static int mcam_vidioc_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct mcam_camera *cam = priv;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (v4l2_chip_match_host(&chip->match)) {
-		chip->ident = cam->chip_id;
-		return 0;
-	}
-	return sensor_call(cam, core, g_chip_ident, chip);
-}
-
 static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv,
 		struct v4l2_frmsizeenum *sizes)
 {
@@ -1436,12 +1410,11 @@ static int mcam_vidioc_g_register(struct
 {
 	struct mcam_camera *cam = priv;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		reg->val = mcam_reg_read(cam, reg->reg);
-		reg->size = 4;
-		return 0;
-	}
-	return sensor_call(cam, core, g_register, reg);
+	if (reg->reg > cam->regs_size - 4)
+		return -EINVAL;
+	reg->val = mcam_reg_read(cam, reg->reg);
+	reg->size = 4;
+	return 0;
 }
 
 static int mcam_vidioc_s_register(struct file *file, void *priv,
@@ -1449,11 +1422,10 @@ static int mcam_vidioc_s_register(struct
 {
 	struct mcam_camera *cam = priv;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		mcam_reg_write(cam, reg->reg, reg->val);
-		return 0;
-	}
-	return sensor_call(cam, core, s_register, reg);
+	if (reg->reg > cam->regs_size - 4)
+		return -EINVAL;
+	mcam_reg_write(cam, reg->reg, reg->val);
+	return 0;
 }
 #endif
 
@@ -1467,6 +1439,7 @@ static const struct v4l2_ioctl_ops mcam_
 	.vidioc_g_input		= mcam_vidioc_g_input,
 	.vidioc_s_input		= mcam_vidioc_s_input,
 	.vidioc_s_std		= mcam_vidioc_s_std,
+	.vidioc_g_std		= mcam_vidioc_g_std,
 	.vidioc_reqbufs		= mcam_vidioc_reqbufs,
 	.vidioc_querybuf	= mcam_vidioc_querybuf,
 	.vidioc_qbuf		= mcam_vidioc_qbuf,
@@ -1477,7 +1450,6 @@ static const struct v4l2_ioctl_ops mcam_
 	.vidioc_s_parm		= mcam_vidioc_s_parm,
 	.vidioc_enum_framesizes = mcam_vidioc_enum_framesizes,
 	.vidioc_enum_frameintervals = mcam_vidioc_enum_frameintervals,
-	.vidioc_g_chip_ident	= mcam_vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register	= mcam_vidioc_g_register,
 	.vidioc_s_register	= mcam_vidioc_s_register,
@@ -1593,7 +1565,6 @@ static const struct v4l2_file_operations
 static struct video_device mcam_v4l_template = {
 	.name = "mcam",
 	.tvnorms = V4L2_STD_NTSC_M,
-	.current_norm = V4L2_STD_NTSC_M,  /* make mplayer happy */
 
 	.fops = &mcam_v4l_fops,
 	.ioctl_ops = &mcam_v4l_ioctl_ops,
@@ -1695,7 +1666,7 @@ int mccic_register(struct mcam_camera *c
 	if (buffer_mode >= 0)
 		cam->buffer_mode = buffer_mode;
 	if (cam->buffer_mode == B_DMA_sg &&
-			cam->chip_id == V4L2_IDENT_CAFE) {
+			cam->chip_id == MCAM_CAFE) {
 		printk(KERN_ERR "marvell-cam: Cafe can't do S/G I/O, "
 			"attempting vmalloc mode instead\n");
 		cam->buffer_mode = B_vmalloc;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/marvell-ccic/mcam-core.h linux-libre-3.11-rc7-gnu/drivers/media/platform/marvell-ccic/mcam-core.h
--- linux-libre-3.10-gnu/drivers/media/platform/marvell-ccic/mcam-core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/marvell-ccic/mcam-core.h	2013-08-25 20:43:22.000000000 -0400
@@ -53,6 +53,11 @@ enum mcam_buffer_mode {
 	B_DMA_sg = 2
 };
 
+enum mcam_chip_id {
+	MCAM_CAFE,
+	MCAM_ARMADA610,
+};
+
 /*
  * Is a given buffer mode supported by the current kernel configuration?
  */
@@ -96,9 +101,10 @@ struct mcam_camera {
 	 */
 	struct i2c_adapter *i2c_adapter;
 	unsigned char __iomem *regs;
+	unsigned regs_size; /* size in bytes of the register space */
 	spinlock_t dev_lock;
 	struct device *dev; /* For messages, dma alloc */
-	unsigned int chip_id;
+	enum mcam_chip_id chip_id;
 	short int clock_speed;	/* Sensor clock speed, default 30 */
 	short int use_smbus;	/* SMBUS or straight I2c? */
 	enum mcam_buffer_mode buffer_mode;
@@ -152,7 +158,6 @@ struct mcam_camera {
 	void (*frame_complete)(struct mcam_camera *cam, int frame);
 
 	/* Current operating parameters */
-	u32 sensor_type;		/* Currently ov7670 only */
 	struct v4l2_pix_format pix_format;
 	enum v4l2_mbus_pixelcode mbus_code;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/marvell-ccic/mmp-driver.c linux-libre-3.11-rc7-gnu/drivers/media/platform/marvell-ccic/mmp-driver.c
--- linux-libre-3.10-gnu/drivers/media/platform/marvell-ccic/mmp-driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/marvell-ccic/mmp-driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/mmp-camera.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
@@ -185,7 +184,7 @@ static int mmpcam_probe(struct platform_
 	mcam->plat_power_down = mmpcam_power_down;
 	mcam->dev = &pdev->dev;
 	mcam->use_smbus = 0;
-	mcam->chip_id = V4L2_IDENT_ARMADA610;
+	mcam->chip_id = MCAM_ARMADA610;
 	mcam->buffer_mode = B_DMA_sg;
 	spin_lock_init(&mcam->dev_lock);
 	/*
@@ -203,6 +202,7 @@ static int mmpcam_probe(struct platform_
 		ret = -ENODEV;
 		goto out_free;
 	}
+	mcam->regs_size = resource_size(res);
 	/*
 	 * Power/clock memory is elsewhere; get it too.  Perhaps this
 	 * should really be managed outside of this driver?
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/mem2mem_testdev.c linux-libre-3.11-rc7-gnu/drivers/media/platform/mem2mem_testdev.c
--- linux-libre-3.10-gnu/drivers/media/platform/mem2mem_testdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/mem2mem_testdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -1051,6 +1051,7 @@ static int m2mtest_probe(struct platform
 
 	*vfd = m2mtest_videodev;
 	vfd->lock = &dev->dev_mutex;
+	vfd->v4l2_dev = &dev->v4l2_dev;
 
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
 	if (ret) {
@@ -1061,7 +1062,7 @@ static int m2mtest_probe(struct platform
 	video_set_drvdata(vfd, dev);
 	snprintf(vfd->name, sizeof(vfd->name), "%s", m2mtest_videodev.name);
 	dev->vfd = vfd;
-	v4l2_info(&dev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME
+	v4l2_info(&dev->v4l2_dev,
 			"Device registered as /dev/video%d\n", vfd->num);
 
 	setup_timer(&dev->timer, device_isr, (long)dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/mx2_emmaprp.c linux-libre-3.11-rc7-gnu/drivers/media/platform/mx2_emmaprp.c
--- linux-libre-3.10-gnu/drivers/media/platform/mx2_emmaprp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/mx2_emmaprp.c	2013-08-25 20:43:22.000000000 -0400
@@ -937,6 +937,7 @@ static int emmaprp_probe(struct platform
 
 	*vfd = emmaprp_videodev;
 	vfd->lock = &pcdev->dev_mutex;
+	vfd->v4l2_dev = &pcdev->v4l2_dev;
 
 	video_set_drvdata(vfd, pcdev);
 	snprintf(vfd->name, sizeof(vfd->name), "%s", emmaprp_videodev.name);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/omap/omap_vout.c linux-libre-3.11-rc7-gnu/drivers/media/platform/omap/omap_vout.c
--- linux-libre-3.10-gnu/drivers/media/platform/omap/omap_vout.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/omap/omap_vout.c	2013-08-25 20:43:22.000000000 -0400
@@ -335,8 +335,6 @@ static int video_mode_to_dss_mode(struct
 	ovl = ovid->overlays[0];
 
 	switch (pix->pixelformat) {
-	case 0:
-		break;
 	case V4L2_PIX_FMT_YUYV:
 		mode = OMAP_DSS_COLOR_YUV2;
 		break;
@@ -358,6 +356,7 @@ static int video_mode_to_dss_mode(struct
 		break;
 	default:
 		mode = -EINVAL;
+		break;
 	}
 	return mode;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/omap24xxcam.c linux-libre-3.11-rc7-gnu/drivers/media/platform/omap24xxcam.c
--- linux-libre-3.10-gnu/drivers/media/platform/omap24xxcam.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/omap24xxcam.c	2013-08-25 20:43:22.000000000 -0400
@@ -1656,7 +1656,7 @@ static int omap24xxcam_device_register(s
 	}
 	vfd->release = video_device_release;
 
-	vfd->parent = cam->dev;
+	vfd->v4l2_dev = &cam->v4l2_dev;
 
 	strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
 	vfd->fops		 = &omap24xxcam_fops;
@@ -1752,6 +1752,11 @@ static int omap24xxcam_probe(struct plat
 
 	cam->dev = &pdev->dev;
 
+	if (v4l2_device_register(&pdev->dev, &cam->v4l2_dev)) {
+		dev_err(&pdev->dev, "v4l2_device_register failed\n");
+		goto err;
+	}
+
 	/*
 	 * Impose a lower limit on the amount of memory allocated for
 	 * capture. We require at least enough memory to double-buffer
@@ -1849,6 +1854,8 @@ static int omap24xxcam_remove(struct pla
 		cam->mmio_base_phys = 0;
 	}
 
+	v4l2_device_unregister(&cam->v4l2_dev);
+
 	kfree(cam);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/omap24xxcam.h linux-libre-3.11-rc7-gnu/drivers/media/platform/omap24xxcam.h
--- linux-libre-3.10-gnu/drivers/media/platform/omap24xxcam.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/omap24xxcam.h	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include <media/videobuf-dma-sg.h>
 #include <media/v4l2-int-device.h>
+#include <media/v4l2-device.h>
 
 /*
  *
@@ -462,6 +463,8 @@ struct omap24xxcam_device {
 	 */
 	struct mutex mutex;
 
+	struct v4l2_device v4l2_dev;
+
 	/*** general driver state information ***/
 	atomic_t users;
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/omap3isp/isp.c linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/isp.c
--- linux-libre-3.10-gnu/drivers/media/platform/omap3isp/isp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/isp.c	2013-08-25 20:43:22.000000000 -0400
@@ -792,9 +792,9 @@ int omap3isp_pipeline_pm_use(struct medi
 
 /*
  * isp_pipeline_link_notify - Link management notification callback
- * @source: Pad at the start of the link
- * @sink: Pad at the end of the link
+ * @link: The link
  * @flags: New link flags that will be applied
+ * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*)
  *
  * React to link management on powered pipelines by updating the use count of
  * all entities in the source and sink sides of the link. Entities are powered
@@ -804,29 +804,38 @@ int omap3isp_pipeline_pm_use(struct medi
  * off is assumed to never fail. This function will not fail for disconnection
  * events.
  */
-static int isp_pipeline_link_notify(struct media_pad *source,
-				    struct media_pad *sink, u32 flags)
+static int isp_pipeline_link_notify(struct media_link *link, u32 flags,
+				    unsigned int notification)
 {
-	int source_use = isp_pipeline_pm_use_count(source->entity);
-	int sink_use = isp_pipeline_pm_use_count(sink->entity);
+	struct media_entity *source = link->source->entity;
+	struct media_entity *sink = link->sink->entity;
+	int source_use = isp_pipeline_pm_use_count(source);
+	int sink_use = isp_pipeline_pm_use_count(sink);
 	int ret;
 
-	if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+	if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+	    !(link->flags & MEDIA_LNK_FL_ENABLED)) {
 		/* Powering off entities is assumed to never fail. */
-		isp_pipeline_pm_power(source->entity, -sink_use);
-		isp_pipeline_pm_power(sink->entity, -source_use);
+		isp_pipeline_pm_power(source, -sink_use);
+		isp_pipeline_pm_power(sink, -source_use);
 		return 0;
 	}
 
-	ret = isp_pipeline_pm_power(source->entity, sink_use);
-	if (ret < 0)
-		return ret;
+	if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+		(flags & MEDIA_LNK_FL_ENABLED)) {
 
-	ret = isp_pipeline_pm_power(sink->entity, source_use);
-	if (ret < 0)
-		isp_pipeline_pm_power(source->entity, -sink_use);
+		ret = isp_pipeline_pm_power(source, sink_use);
+		if (ret < 0)
+			return ret;
 
-	return ret;
+		ret = isp_pipeline_pm_power(sink, source_use);
+		if (ret < 0)
+			isp_pipeline_pm_power(source, -sink_use);
+
+		return ret;
+	}
+
+	return 0;
 }
 
 /* -----------------------------------------------------------------------------
@@ -877,7 +886,7 @@ static int isp_pipeline_enable(struct is
 		if (!(pad->flags & MEDIA_PAD_FL_SINK))
 			break;
 
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (pad == NULL ||
 		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 			break;
@@ -967,7 +976,7 @@ static int isp_pipeline_disable(struct i
 		if (!(pad->flags & MEDIA_PAD_FL_SINK))
 			break;
 
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (pad == NULL ||
 		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 			break;
@@ -1083,7 +1092,7 @@ static int isp_pipeline_is_last(struct m
 	pipe = to_isp_pipeline(me);
 	if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)
 		return 0;
-	pad = media_entity_remote_source(&pipe->output->pad);
+	pad = media_entity_remote_pad(&pipe->output->pad);
 	return pad->entity == me;
 }
 
@@ -2249,6 +2258,7 @@ static int isp_probe(struct platform_dev
 	ret = iommu_attach_device(isp->domain, &pdev->dev);
 	if (ret) {
 		dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret);
+		ret = -EPROBE_DEFER;
 		goto free_domain;
 	}
 
@@ -2287,12 +2297,11 @@ detach_dev:
 	iommu_detach_device(isp->domain, &pdev->dev);
 free_domain:
 	iommu_domain_free(isp->domain);
+	isp->domain = NULL;
 error_isp:
 	isp_xclk_cleanup(isp);
 	omap3isp_put(isp);
 error:
-	platform_set_drvdata(pdev, NULL);
-
 	mutex_destroy(&isp->isp_mutex);
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispccdc.c linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispccdc.c
--- linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispccdc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispccdc.c	2013-08-25 20:43:22.000000000 -0400
@@ -1120,7 +1120,7 @@ static void ccdc_configure(struct isp_cc
 	u32 syn_mode;
 	u32 ccdc_pattern;
 
-	pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
+	pad = media_entity_remote_pad(&ccdc->pads[CCDC_PAD_SINK]);
 	sensor = media_entity_to_v4l2_subdev(pad->entity);
 	if (ccdc->input == CCDC_INPUT_PARALLEL)
 		pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispccp2.c linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispccp2.c
--- linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispccp2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispccp2.c	2013-08-25 20:43:22.000000000 -0400
@@ -158,13 +158,17 @@ static void ccp2_pwr_cfg(struct isp_ccp2
  * @ccp2: pointer to ISP CCP2 device
  * @enable: enable/disable flag
  */
-static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
+static int ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
 {
 	struct isp_device *isp = to_isp_device(ccp2);
+	int ret;
 	int i;
 
-	if (enable && ccp2->vdds_csib)
-		regulator_enable(ccp2->vdds_csib);
+	if (enable && ccp2->vdds_csib) {
+		ret = regulator_enable(ccp2->vdds_csib);
+		if (ret < 0)
+			return ret;
+	}
 
 	/* Enable/Disable all the LCx channels */
 	for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
@@ -179,6 +183,8 @@ static void ccp2_if_enable(struct isp_cc
 
 	if (!enable && ccp2->vdds_csib)
 		regulator_disable(ccp2->vdds_csib);
+
+	return 0;
 }
 
 /*
@@ -360,7 +366,7 @@ static int ccp2_if_configure(struct isp_
 
 	ccp2_pwr_cfg(ccp2);
 
-	pad = media_entity_remote_source(&ccp2->pads[CCP2_PAD_SINK]);
+	pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]);
 	sensor = media_entity_to_v4l2_subdev(pad->entity);
 	pdata = sensor->host_priv;
 
@@ -851,7 +857,12 @@ static int ccp2_s_stream(struct v4l2_sub
 		ccp2_print_status(ccp2);
 
 		/* Enable CSI1/CCP2 interface */
-		ccp2_if_enable(ccp2, 1);
+		ret = ccp2_if_enable(ccp2, 1);
+		if (ret < 0) {
+			if (ccp2->phy)
+				omap3isp_csiphy_release(ccp2->phy);
+			return ret;
+		}
 		break;
 
 	case ISP_PIPELINE_STREAM_SINGLESHOT:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispcsi2.c linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispcsi2.c
--- linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispcsi2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispcsi2.c	2013-08-25 20:43:22.000000000 -0400
@@ -573,7 +573,7 @@ static int csi2_configure(struct isp_csi
 	if (csi2->contexts[0].enabled || csi2->ctrl.if_enable)
 		return -EBUSY;
 
-	pad = media_entity_remote_source(&csi2->pads[CSI2_PAD_SINK]);
+	pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]);
 	sensor = media_entity_to_v4l2_subdev(pad->entity);
 	pdata = sensor->host_priv;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispqueue.h linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispqueue.h
--- linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispqueue.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispqueue.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/mm_types.h>
 #include <linux/mutex.h>
 #include <linux/videodev2.h>
 #include <linux/wait.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispvideo.c linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispvideo.c
--- linux-libre-3.10-gnu/drivers/media/platform/omap3isp/ispvideo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/omap3isp/ispvideo.c	2013-08-25 20:43:22.000000000 -0400
@@ -219,7 +219,7 @@ isp_video_remote_subdev(struct isp_video
 {
 	struct media_pad *remote;
 
-	remote = media_entity_remote_source(&video->pad);
+	remote = media_entity_remote_pad(&video->pad);
 
 	if (remote == NULL ||
 	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
@@ -314,7 +314,7 @@ static int isp_video_validate_pipeline(s
 		 * entity can be found, and stop checking the pipeline if the
 		 * source entity isn't a subdev.
 		 */
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (pad == NULL)
 			return -EPIPE;
 
@@ -901,7 +901,7 @@ static int isp_video_check_external_subd
 			continue;
 
 		/* ISP entities have always sink pad == 0. Find source. */
-		source_pad = media_entity_remote_source(&ents[i]->pads[0]);
+		source_pad = media_entity_remote_pad(&ents[i]->pads[0]);
 		if (source_pad == NULL)
 			continue;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s3c-camif/camif-capture.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s3c-camif/camif-capture.c
--- linux-libre-3.10-gnu/drivers/media/platform/s3c-camif/camif-capture.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s3c-camif/camif-capture.c	2013-08-25 20:43:22.000000000 -0400
@@ -845,7 +845,7 @@ static int camif_pipeline_validate(struc
 	int ret;
 
 	/* Retrieve format at the sensor subdev source pad */
-	pad = media_entity_remote_source(&camif->pads[0]);
+	pad = media_entity_remote_pad(&camif->pads[0]);
 	if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 		return -EPIPE;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s3c-camif/camif-core.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s3c-camif/camif-core.c
--- linux-libre-3.10-gnu/drivers/media/platform/s3c-camif/camif-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s3c-camif/camif-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -341,10 +341,11 @@ static void camif_clk_put(struct camif_d
 	int i;
 
 	for (i = 0; i < CLK_MAX_NUM; i++) {
-		if (IS_ERR_OR_NULL(camif->clock[i]))
+		if (IS_ERR(camif->clock[i]))
 			continue;
 		clk_unprepare(camif->clock[i]);
 		clk_put(camif->clock[i]);
+		camif->clock[i] = ERR_PTR(-EINVAL);
 	}
 }
 
@@ -352,6 +353,9 @@ static int camif_clk_get(struct camif_de
 {
 	int ret, i;
 
+	for (i = 1; i < CLK_MAX_NUM; i++)
+		camif->clock[i] = ERR_PTR(-EINVAL);
+
 	for (i = 0; i < CLK_MAX_NUM; i++) {
 		camif->clock[i] = clk_get(camif->dev, camif_clocks[i]);
 		if (IS_ERR(camif->clock[i])) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s3c-camif/camif-regs.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s3c-camif/camif-regs.c
--- linux-libre-3.10-gnu/drivers/media/platform/s3c-camif/camif-regs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s3c-camif/camif-regs.c	2013-08-25 20:43:22.000000000 -0400
@@ -379,7 +379,7 @@ static void camif_hw_set_prescaler(struc
 	camif_write(camif, S3C_CAMIF_REG_CISCPREDST(vp->id, vp->offset), cfg);
 }
 
-void camif_s3c244x_hw_set_scaler(struct camif_vp *vp)
+static void camif_s3c244x_hw_set_scaler(struct camif_vp *vp)
 {
 	struct camif_dev *camif = vp->camif;
 	struct camif_scaler *scaler = &vp->scaler;
@@ -426,7 +426,7 @@ void camif_s3c244x_hw_set_scaler(struct
 		 scaler->main_h_ratio, scaler->main_v_ratio);
 }
 
-void camif_s3c64xx_hw_set_scaler(struct camif_vp *vp)
+static void camif_s3c64xx_hw_set_scaler(struct camif_vp *vp)
 {
 	struct camif_dev *camif = vp->camif;
 	struct camif_scaler *scaler = &vp->scaler;
@@ -601,6 +601,6 @@ void camif_hw_dump_regs(struct camif_dev
 	pr_info("--- %s ---\n", label);
 	for (i = 0; i < ARRAY_SIZE(registers); i++) {
 		u32 cfg = readl(camif->io_base + registers[i].offset);
-		printk(KERN_INFO "%s:\t0x%08x\n", registers[i].name, cfg);
+		dev_info(camif->dev, "%s:\t0x%08x\n", registers[i].name, cfg);
 	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-g2d/g2d.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-g2d/g2d.c
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-g2d/g2d.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-g2d/g2d.c	2013-08-25 20:43:22.000000000 -0400
@@ -784,6 +784,7 @@ static int g2d_probe(struct platform_dev
 	}
 	*vfd = g2d_videodev;
 	vfd->lock = &dev->mutex;
+	vfd->v4l2_dev = &dev->v4l2_dev;
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
 	if (ret) {
 		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-mfc/s5p_mfc.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-mfc/s5p_mfc.c
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-mfc/s5p_mfc.c	2013-07-01 10:35:44.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-mfc/s5p_mfc.c	2013-08-31 17:55:15.000000000 -0400
@@ -1424,7 +1424,7 @@ static void *mfc_get_drv_data(struct pla
 
 	if (pdev->dev.of_node) {
 		const struct of_device_id *match;
-		match = of_match_node(of_match_ptr(exynos_mfc_match),
+		match = of_match_node(exynos_mfc_match,
 				pdev->dev.of_node);
 		if (match)
 			driver_data = (struct s5p_mfc_variant *)match->data;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c	2013-08-25 20:43:22.000000000 -0400
@@ -344,7 +344,7 @@ static int vidioc_g_fmt(struct file *fil
 		pix_mp->num_planes = 2;
 		/* Set pixelformat to the format in which MFC
 		   outputs the decoded frame */
-		pix_mp->pixelformat = V4L2_PIX_FMT_NV12MT;
+		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
 		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
 		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
 		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
@@ -382,10 +382,16 @@ static int vidioc_try_fmt(struct file *f
 			mfc_err("Unsupported format for source.\n");
 			return -EINVAL;
 		}
-		if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
-			mfc_err("Not supported format.\n");
+		if (fmt->codec_mode == S5P_FIMV_CODEC_NONE) {
+			mfc_err("Unknown codec\n");
 			return -EINVAL;
 		}
+		if (!IS_MFCV6(dev)) {
+			if (fmt->fourcc == V4L2_PIX_FMT_VP8) {
+				mfc_err("Not supported format.\n");
+				return -EINVAL;
+			}
+		}
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		fmt = find_format(f, MFC_FMT_RAW);
 		if (!fmt) {
@@ -411,7 +417,6 @@ static int vidioc_s_fmt(struct file *fil
 	struct s5p_mfc_dev *dev = video_drvdata(file);
 	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
 	int ret = 0;
-	struct s5p_mfc_fmt *fmt;
 	struct v4l2_pix_format_mplane *pix_mp;
 
 	mfc_debug_enter();
@@ -425,54 +430,32 @@ static int vidioc_s_fmt(struct file *fil
 		goto out;
 	}
 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		fmt = find_format(f, MFC_FMT_RAW);
-		if (!fmt) {
-			mfc_err("Unsupported format for source.\n");
-			return -EINVAL;
-		}
-		if (!IS_MFCV6(dev) && (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) {
-			mfc_err("Not supported format.\n");
-			return -EINVAL;
-		} else if (IS_MFCV6(dev) &&
-				(fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
-			mfc_err("Not supported format.\n");
-			return -EINVAL;
-		}
-		ctx->dst_fmt = fmt;
-		mfc_debug_leave();
-		return ret;
-	} else if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		mfc_err("Wrong type error for S_FMT : %d", f->type);
-		return -EINVAL;
-	}
-	fmt = find_format(f, MFC_FMT_DEC);
-	if (!fmt || fmt->codec_mode == S5P_MFC_CODEC_NONE) {
-		mfc_err("Unknown codec\n");
-		ret = -EINVAL;
+		/* dst_fmt is validated by call to vidioc_try_fmt */
+		ctx->dst_fmt = find_format(f, MFC_FMT_RAW);
+		ret = 0;
 		goto out;
-	}
-	if (fmt->type != MFC_FMT_DEC) {
-		mfc_err("Wrong format selected, you should choose "
-					"format for decoding\n");
+	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		/* src_fmt is validated by call to vidioc_try_fmt */
+		ctx->src_fmt = find_format(f, MFC_FMT_DEC);
+		ctx->codec_mode = ctx->src_fmt->codec_mode;
+		mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
+		pix_mp->height = 0;
+		pix_mp->width = 0;
+		if (pix_mp->plane_fmt[0].sizeimage)
+			ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
+		else
+			pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
+								DEF_CPB_SIZE;
+		pix_mp->plane_fmt[0].bytesperline = 0;
+		ctx->state = MFCINST_INIT;
+		ret = 0;
+		goto out;
+	} else {
+		mfc_err("Wrong type error for S_FMT : %d", f->type);
 		ret = -EINVAL;
 		goto out;
 	}
-	if (!IS_MFCV6(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) {
-		mfc_err("Not supported format.\n");
-		return -EINVAL;
-	}
-	ctx->src_fmt = fmt;
-	ctx->codec_mode = fmt->codec_mode;
-	mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
-	pix_mp->height = 0;
-	pix_mp->width = 0;
-	if (pix_mp->plane_fmt[0].sizeimage)
-		ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
-	else
-		pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
-								DEF_CPB_SIZE;
-	pix_mp->plane_fmt[0].bytesperline = 0;
-	ctx->state = MFCINST_INIT;
+
 out:
 	mfc_debug_leave();
 	return ret;
@@ -954,7 +937,7 @@ static int s5p_mfc_queue_setup(struct vb
 		psize[0] = ctx->dec_src_buf_size;
 		allocators[0] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
 	} else {
-		mfc_err("This video node is dedicated to decoding. Decoding not initalised\n");
+		mfc_err("This video node is dedicated to decoding. Decoding not initialized\n");
 		return -EINVAL;
 	}
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c	2013-08-25 20:43:22.000000000 -0400
@@ -906,6 +906,7 @@ static int vidioc_g_fmt(struct file *fil
 
 static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
 {
+	struct s5p_mfc_dev *dev = video_drvdata(file);
 	struct s5p_mfc_fmt *fmt;
 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
 
@@ -930,6 +931,18 @@ static int vidioc_try_fmt(struct file *f
 			return -EINVAL;
 		}
 
+		if (!IS_MFCV6(dev)) {
+			if (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) {
+				mfc_err("Not supported format.\n");
+				return -EINVAL;
+			}
+		} else if (IS_MFCV6(dev)) {
+			if (fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
+				mfc_err("Not supported format.\n");
+				return -EINVAL;
+			}
+		}
+
 		if (fmt->num_planes != pix_fmt_mp->num_planes) {
 			mfc_err("failed to try output format\n");
 			return -EINVAL;
@@ -947,7 +960,6 @@ static int vidioc_s_fmt(struct file *fil
 {
 	struct s5p_mfc_dev *dev = video_drvdata(file);
 	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
-	struct s5p_mfc_fmt *fmt;
 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
 	int ret = 0;
 
@@ -960,13 +972,9 @@ static int vidioc_s_fmt(struct file *fil
 		goto out;
 	}
 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		fmt = find_format(f, MFC_FMT_ENC);
-		if (!fmt) {
-			mfc_err("failed to set capture format\n");
-			return -EINVAL;
-		}
+		/* dst_fmt is validated by call to vidioc_try_fmt */
+		ctx->dst_fmt = find_format(f, MFC_FMT_ENC);
 		ctx->state = MFCINST_INIT;
-		ctx->dst_fmt = fmt;
 		ctx->codec_mode = ctx->dst_fmt->codec_mode;
 		ctx->enc_dst_buf_size =	pix_fmt_mp->plane_fmt[0].sizeimage;
 		pix_fmt_mp->plane_fmt[0].bytesperline = 0;
@@ -987,28 +995,8 @@ static int vidioc_s_fmt(struct file *fil
 		}
 		mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		fmt = find_format(f, MFC_FMT_RAW);
-		if (!fmt) {
-			mfc_err("failed to set output format\n");
-			return -EINVAL;
-		}
-
-		if (!IS_MFCV6(dev) &&
-				(fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)) {
-			mfc_err("Not supported format.\n");
-			return -EINVAL;
-		} else if (IS_MFCV6(dev) &&
-				(fmt->fourcc == V4L2_PIX_FMT_NV12MT)) {
-			mfc_err("Not supported format.\n");
-			return -EINVAL;
-		}
-
-		if (fmt->num_planes != pix_fmt_mp->num_planes) {
-			mfc_err("failed to set output format\n");
-			ret = -EINVAL;
-			goto out;
-		}
-		ctx->src_fmt = fmt;
+		/* src_fmt is validated by call to vidioc_try_fmt */
+		ctx->src_fmt = find_format(f, MFC_FMT_RAW);
 		ctx->img_width = pix_fmt_mp->width;
 		ctx->img_height = pix_fmt_mp->height;
 		mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/hdmi_drv.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/hdmi_drv.c
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/hdmi_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/hdmi_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -576,16 +576,22 @@ static int hdmi_s_stream(struct v4l2_sub
 	return hdmi_streamoff(hdev);
 }
 
-static void hdmi_resource_poweron(struct hdmi_resources *res)
+static int hdmi_resource_poweron(struct hdmi_resources *res)
 {
+	int ret;
+
 	/* turn HDMI power on */
-	regulator_bulk_enable(res->regul_count, res->regul_bulk);
+	ret = regulator_bulk_enable(res->regul_count, res->regul_bulk);
+	if (ret < 0)
+		return ret;
 	/* power-on hdmi physical interface */
 	clk_enable(res->hdmiphy);
 	/* use VPP as parent clock; HDMIPHY is not working yet */
 	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
 	/* turn clocks on */
 	clk_enable(res->sclk_hdmi);
+
+	return 0;
 }
 
 static void hdmi_resource_poweroff(struct hdmi_resources *res)
@@ -728,11 +734,13 @@ static int hdmi_runtime_resume(struct de
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
-	int ret = 0;
+	int ret;
 
 	dev_dbg(dev, "%s\n", __func__);
 
-	hdmi_resource_poweron(&hdev->res);
+	ret = hdmi_resource_poweron(&hdev->res);
+	if (ret < 0)
+		return ret;
 
 	/* starting MHL */
 	ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1);
@@ -755,6 +763,15 @@ static const struct dev_pm_ops hdmi_pm_o
 	.runtime_resume	 = hdmi_runtime_resume,
 };
 
+static void hdmi_resource_clear_clocks(struct hdmi_resources *res)
+{
+	res->hdmi	 = ERR_PTR(-EINVAL);
+	res->sclk_hdmi	 = ERR_PTR(-EINVAL);
+	res->sclk_pixel	 = ERR_PTR(-EINVAL);
+	res->sclk_hdmiphy = ERR_PTR(-EINVAL);
+	res->hdmiphy	 = ERR_PTR(-EINVAL);
+}
+
 static void hdmi_resources_cleanup(struct hdmi_device *hdev)
 {
 	struct hdmi_resources *res = &hdev->res;
@@ -765,17 +782,18 @@ static void hdmi_resources_cleanup(struc
 		regulator_bulk_free(res->regul_count, res->regul_bulk);
 	/* kfree is NULL-safe */
 	kfree(res->regul_bulk);
-	if (!IS_ERR_OR_NULL(res->hdmiphy))
+	if (!IS_ERR(res->hdmiphy))
 		clk_put(res->hdmiphy);
-	if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
+	if (!IS_ERR(res->sclk_hdmiphy))
 		clk_put(res->sclk_hdmiphy);
-	if (!IS_ERR_OR_NULL(res->sclk_pixel))
+	if (!IS_ERR(res->sclk_pixel))
 		clk_put(res->sclk_pixel);
-	if (!IS_ERR_OR_NULL(res->sclk_hdmi))
+	if (!IS_ERR(res->sclk_hdmi))
 		clk_put(res->sclk_hdmi);
-	if (!IS_ERR_OR_NULL(res->hdmi))
+	if (!IS_ERR(res->hdmi))
 		clk_put(res->hdmi);
 	memset(res, 0, sizeof(*res));
+	hdmi_resource_clear_clocks(res);
 }
 
 static int hdmi_resources_init(struct hdmi_device *hdev)
@@ -793,8 +811,9 @@ static int hdmi_resources_init(struct hd
 	dev_dbg(dev, "HDMI resource init\n");
 
 	memset(res, 0, sizeof(*res));
-	/* get clocks, power */
+	hdmi_resource_clear_clocks(res);
 
+	/* get clocks, power */
 	res->hdmi = clk_get(dev, "hdmi");
 	if (IS_ERR(res->hdmi)) {
 		dev_err(dev, "failed to get clock 'hdmi'\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/Kconfig
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
 
 config VIDEO_SAMSUNG_S5P_TV
 	bool "Samsung TV driver for S5P platform"
-	depends on PLAT_S5P && PM_RUNTIME
+	depends on (PLAT_S5P || ARCH_EXYNOS) && PM_RUNTIME
 	default n
 	---help---
 	  Say Y here to enable selecting the TV output devices for
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/mixer_drv.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/mixer_drv.c
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/mixer_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/mixer_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -211,6 +211,15 @@ fail:
 	return ret;
 }
 
+static void mxr_resource_clear_clocks(struct mxr_resources *res)
+{
+	res->mixer	= ERR_PTR(-EINVAL);
+	res->vp		= ERR_PTR(-EINVAL);
+	res->sclk_mixer	= ERR_PTR(-EINVAL);
+	res->sclk_hdmi	= ERR_PTR(-EINVAL);
+	res->sclk_dac	= ERR_PTR(-EINVAL);
+}
+
 static void mxr_release_plat_resources(struct mxr_device *mdev)
 {
 	free_irq(mdev->res.irq, mdev);
@@ -222,15 +231,15 @@ static void mxr_release_clocks(struct mx
 {
 	struct mxr_resources *res = &mdev->res;
 
-	if (!IS_ERR_OR_NULL(res->sclk_dac))
+	if (!IS_ERR(res->sclk_dac))
 		clk_put(res->sclk_dac);
-	if (!IS_ERR_OR_NULL(res->sclk_hdmi))
+	if (!IS_ERR(res->sclk_hdmi))
 		clk_put(res->sclk_hdmi);
-	if (!IS_ERR_OR_NULL(res->sclk_mixer))
+	if (!IS_ERR(res->sclk_mixer))
 		clk_put(res->sclk_mixer);
-	if (!IS_ERR_OR_NULL(res->vp))
+	if (!IS_ERR(res->vp))
 		clk_put(res->vp);
-	if (!IS_ERR_OR_NULL(res->mixer))
+	if (!IS_ERR(res->mixer))
 		clk_put(res->mixer);
 }
 
@@ -239,6 +248,8 @@ static int mxr_acquire_clocks(struct mxr
 	struct mxr_resources *res = &mdev->res;
 	struct device *dev = mdev->dev;
 
+	mxr_resource_clear_clocks(res);
+
 	res->mixer = clk_get(dev, "mixer");
 	if (IS_ERR(res->mixer)) {
 		mxr_err(mdev, "failed to get clock 'mixer'\n");
@@ -299,6 +310,7 @@ static void mxr_release_resources(struct
 	mxr_release_clocks(mdev);
 	mxr_release_plat_resources(mdev);
 	memset(&mdev->res, 0, sizeof(mdev->res));
+	mxr_resource_clear_clocks(&mdev->res);
 }
 
 static void mxr_release_layers(struct mxr_device *mdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/mixer_video.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/mixer_video.c
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/mixer_video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/mixer_video.c	2013-08-25 20:43:22.000000000 -0400
@@ -81,8 +81,9 @@ int mxr_acquire_video(struct mxr_device
 	}
 
 	mdev->alloc_ctx = vb2_dma_contig_init_ctx(mdev->dev);
-	if (IS_ERR_OR_NULL(mdev->alloc_ctx)) {
+	if (IS_ERR(mdev->alloc_ctx)) {
 		mxr_err(mdev, "could not acquire vb2 allocator\n");
+		ret = PTR_ERR(mdev->alloc_ctx);
 		goto fail_v4l2_dev;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/sdo_drv.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/sdo_drv.c
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/sdo_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/sdo_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -262,11 +262,21 @@ static int sdo_runtime_resume(struct dev
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct sdo_device *sdev = sd_to_sdev(sd);
+	int ret;
 
 	dev_info(dev, "resume\n");
-	clk_enable(sdev->sclk_dac);
-	regulator_enable(sdev->vdac);
-	regulator_enable(sdev->vdet);
+
+	ret = clk_enable(sdev->sclk_dac);
+	if (ret < 0)
+		return ret;
+
+	ret = regulator_enable(sdev->vdac);
+	if (ret < 0)
+		goto dac_clk_dis;
+
+	ret = regulator_enable(sdev->vdet);
+	if (ret < 0)
+		goto vdac_r_dis;
 
 	/* software reset */
 	sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_SW_RESET);
@@ -285,6 +295,12 @@ static int sdo_runtime_resume(struct dev
 		SDO_COMPENSATION_CVBS_COMP_OFF);
 	sdo_reg_debug(sdev);
 	return 0;
+
+vdac_r_dis:
+	regulator_disable(sdev->vdac);
+dac_clk_dis:
+	clk_disable(sdev->sclk_dac);
+	return ret;
 }
 
 static const struct dev_pm_ops sdo_pm_ops = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/sii9234_drv.c linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/sii9234_drv.c
--- linux-libre-3.10-gnu/drivers/media/platform/s5p-tv/sii9234_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/s5p-tv/sii9234_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -249,7 +249,9 @@ static int sii9234_runtime_resume(struct
 	int ret;
 
 	dev_info(dev, "resume start\n");
-	regulator_enable(ctx->power);
+	ret = regulator_enable(ctx->power);
+	if (ret < 0)
+		return ret;
 
 	ret = sii9234_reset(ctx);
 	if (ret)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/sh_veu.c linux-libre-3.11-rc7-gnu/drivers/media/platform/sh_veu.c
--- linux-libre-3.10-gnu/drivers/media/platform/sh_veu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/sh_veu.c	2013-08-25 20:43:22.000000000 -0400
@@ -359,10 +359,7 @@ static int sh_veu_context_init(struct sh
 	veu->m2m_ctx = v4l2_m2m_ctx_init(veu->m2m_dev, veu,
 					 sh_veu_queue_init);
 
-	if (IS_ERR(veu->m2m_ctx))
-		return PTR_ERR(veu->m2m_ctx);
-
-	return 0;
+	return PTR_RET(veu->m2m_ctx);
 }
 
 static int sh_veu_querycap(struct file *file, void *priv,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/sh_vou.c linux-libre-3.11-rc7-gnu/drivers/media/platform/sh_vou.c
--- linux-libre-3.10-gnu/drivers/media/platform/sh_vou.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/sh_vou.c	2013-08-25 20:43:22.000000000 -0400
@@ -1248,32 +1248,6 @@ static unsigned int sh_vou_poll(struct f
 	return res;
 }
 
-static int sh_vou_g_chip_ident(struct file *file, void *fh,
-				   struct v4l2_dbg_chip_ident *id)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-
-	return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_chip_ident, id);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int sh_vou_g_register(struct file *file, void *fh,
-				 struct v4l2_dbg_register *reg)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-
-	return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_register, reg);
-}
-
-static int sh_vou_s_register(struct file *file, void *fh,
-				 const struct v4l2_dbg_register *reg)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-
-	return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, s_register, reg);
-}
-#endif
-
 /* sh_vou display ioctl operations */
 static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
 	.vidioc_querycap        	= sh_vou_querycap,
@@ -1292,11 +1266,6 @@ static const struct v4l2_ioctl_ops sh_vo
 	.vidioc_cropcap			= sh_vou_cropcap,
 	.vidioc_g_crop			= sh_vou_g_crop,
 	.vidioc_s_crop			= sh_vou_s_crop,
-	.vidioc_g_chip_ident		= sh_vou_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register		= sh_vou_g_register,
-	.vidioc_s_register		= sh_vou_s_register,
-#endif
 };
 
 static const struct v4l2_file_operations sh_vou_fops = {
@@ -1313,7 +1282,6 @@ static const struct video_device sh_vou_
 	.fops		= &sh_vou_fops,
 	.ioctl_ops	= &sh_vou_ioctl_ops,
 	.tvnorms	= V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */
-	.current_norm	= V4L2_STD_NTSC_M,
 	.vfl_dir	= VFL_DIR_TX,
 };
 
@@ -1352,7 +1320,7 @@ static int sh_vou_probe(struct platform_
 	pix = &vou_dev->pix;
 
 	/* Fill in defaults */
-	vou_dev->std		= sh_vou_video_template.current_norm;
+	vou_dev->std		= V4L2_STD_NTSC_M;
 	rect->left		= 0;
 	rect->top		= 0;
 	rect->width		= VOU_MAX_IMAGE_WIDTH;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/atmel-isi.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/atmel-isi.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/atmel-isi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/atmel-isi.c	2013-08-25 20:43:22.000000000 -0400
@@ -102,7 +102,6 @@ struct atmel_isi {
 	struct list_head		video_buffer_list;
 	struct frame_buffer		*active;
 
-	struct soc_camera_device	*icd;
 	struct soc_camera_host		soc_host;
 };
 
@@ -367,7 +366,7 @@ static void start_dma(struct atmel_isi *
 
 	/* Check if already in a frame */
 	if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
-		dev_err(isi->icd->parent, "Already in frame handling.\n");
+		dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
 		return;
 	}
 
@@ -746,16 +745,26 @@ static int isi_camera_get_formats(struct
 	return formats;
 }
 
-/* Called with .host_lock held */
 static int isi_camera_add_device(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
+		 icd->devnum);
+
+	return 0;
+}
+
+static void isi_camera_remove_device(struct soc_camera_device *icd)
+{
+	dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
+
+/* Called with .host_lock held */
+static int isi_camera_clock_start(struct soc_camera_host *ici)
+{
 	struct atmel_isi *isi = ici->priv;
 	int ret;
 
-	if (isi->icd)
-		return -EBUSY;
-
 	ret = clk_enable(isi->pclk);
 	if (ret)
 		return ret;
@@ -766,25 +775,16 @@ static int isi_camera_add_device(struct
 		return ret;
 	}
 
-	isi->icd = icd;
-	dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
-		 icd->devnum);
 	return 0;
 }
+
 /* Called with .host_lock held */
-static void isi_camera_remove_device(struct soc_camera_device *icd)
+static void isi_camera_clock_stop(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct atmel_isi *isi = ici->priv;
 
-	BUG_ON(icd != isi->icd);
-
 	clk_disable(isi->mck);
 	clk_disable(isi->pclk);
-	isi->icd = NULL;
-
-	dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
-		 icd->devnum);
 }
 
 static unsigned int isi_camera_poll(struct file *file, poll_table *pt)
@@ -888,6 +888,8 @@ static struct soc_camera_host_ops isi_so
 	.owner		= THIS_MODULE,
 	.add		= isi_camera_add_device,
 	.remove		= isi_camera_remove_device,
+	.clock_start	= isi_camera_clock_start,
+	.clock_stop	= isi_camera_clock_stop,
 	.set_fmt	= isi_camera_set_fmt,
 	.try_fmt	= isi_camera_try_fmt,
 	.get_formats	= isi_camera_get_formats,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/Kconfig
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,9 @@ config SOC_CAMERA
 	  over a bus like PCI or USB. For example some i2c camera connected
 	  directly to the data bus of an SoC.
 
+config SOC_CAMERA_SCALE_CROP
+	tristate
+
 config SOC_CAMERA_PLATFORM
 	tristate "platform camera support"
 	depends on SOC_CAMERA
@@ -27,14 +30,10 @@ config VIDEO_MX1
 	---help---
 	  This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
 
-config MX3_VIDEO
-	bool
-
 config VIDEO_MX3
 	tristate "i.MX3x Camera Sensor Interface driver"
 	depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
 	select VIDEOBUF2_DMA_CONTIG
-	select MX3_VIDEO
 	---help---
 	  This is a v4l2 driver for the i.MX3x Camera Sensor Interface
 
@@ -55,6 +54,7 @@ config VIDEO_SH_MOBILE_CEU
 	tristate "SuperH Mobile CEU Interface driver"
 	depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
 	select VIDEOBUF2_DMA_CONTIG
+	select SOC_CAMERA_SCALE_CROP
 	---help---
 	  This is a v4l2 driver for the SuperH Mobile CEU Interface
 
@@ -66,14 +66,10 @@ config VIDEO_OMAP1
 	---help---
 	  This is a v4l2 driver for the TI OMAP1 camera interface
 
-config VIDEO_MX2_HOSTSUPPORT
-	bool
-
 config VIDEO_MX2
 	tristate "i.MX27 Camera Sensor Interface driver"
 	depends on VIDEO_DEV && SOC_CAMERA && MACH_MX27
 	select VIDEOBUF2_DMA_CONTIG
-	select VIDEO_MX2_HOSTSUPPORT
 	---help---
 	  This is a v4l2 driver for the i.MX27 Camera Sensor Interface
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/Makefile linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/Makefile
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,8 @@
 obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o soc_mediabus.o
+obj-$(CONFIG_SOC_CAMERA_SCALE_CROP)	+= soc_scale_crop.o
+
+# a platform subdevice driver stub, allowing to support cameras by adding a
+# couple of callback functions to the board code
 obj-$(CONFIG_SOC_CAMERA_PLATFORM)	+= soc_camera_platform.o
 
 # soc-camera host drivers have to be linked after camera drivers
@@ -10,5 +14,3 @@ obj-$(CONFIG_VIDEO_OMAP1)		+= omap1_came
 obj-$(CONFIG_VIDEO_PXA27x)		+= pxa_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2)	+= sh_mobile_csi2.o
-
-ccflags-y += -I$(srctree)/drivers/media/i2c/soc_camera
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/mx1_camera.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/mx1_camera.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/mx1_camera.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/mx1_camera.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,7 +104,6 @@ struct mx1_buffer {
  */
 struct mx1_camera_dev {
 	struct soc_camera_host		soc_host;
-	struct soc_camera_device	*icd;
 	struct mx1_camera_pdata		*pdata;
 	struct mx1_buffer		*active;
 	struct resource			*res;
@@ -220,7 +219,7 @@ out:
 static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
 {
 	struct videobuf_buffer *vbuf = &pcdev->active->vb;
-	struct device *dev = pcdev->icd->parent;
+	struct device *dev = pcdev->soc_host.icd->parent;
 	int ret;
 
 	if (unlikely(!pcdev->active)) {
@@ -331,7 +330,7 @@ static void mx1_camera_wakeup(struct mx1
 static void mx1_camera_dma_irq(int channel, void *data)
 {
 	struct mx1_camera_dev *pcdev = data;
-	struct device *dev = pcdev->icd->parent;
+	struct device *dev = pcdev->soc_host.icd->parent;
 	struct mx1_buffer *buf;
 	struct videobuf_buffer *vb;
 	unsigned long flags;
@@ -389,7 +388,7 @@ static int mclk_get_divisor(struct mx1_c
 	 */
 	div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
 
-	dev_dbg(pcdev->icd->parent,
+	dev_dbg(pcdev->soc_host.icd->parent,
 		"System clock %lukHz, target freq %dkHz, divisor %lu\n",
 		lcdclk / 1000, mclk / 1000, div);
 
@@ -400,7 +399,7 @@ static void mx1_camera_activate(struct m
 {
 	unsigned int csicr1 = CSICR1_EN;
 
-	dev_dbg(pcdev->icd->parent, "Activate device\n");
+	dev_dbg(pcdev->soc_host.v4l2_dev.dev, "Activate device\n");
 
 	clk_prepare_enable(pcdev->clk);
 
@@ -416,7 +415,7 @@ static void mx1_camera_activate(struct m
 
 static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
 {
-	dev_dbg(pcdev->icd->parent, "Deactivate device\n");
+	dev_dbg(pcdev->soc_host.v4l2_dev.dev, "Deactivate device\n");
 
 	/* Disable all CSI interface */
 	__raw_writel(0x00, pcdev->base + CSICR1);
@@ -424,36 +423,38 @@ static void mx1_camera_deactivate(struct
 	clk_disable_unprepare(pcdev->clk);
 }
 
+static int mx1_camera_add_device(struct soc_camera_device *icd)
+{
+	dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
+		 icd->devnum);
+
+	return 0;
+}
+
+static void mx1_camera_remove_device(struct soc_camera_device *icd)
+{
+	dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
+
 /*
  * The following two functions absolutely depend on the fact, that
  * there can be only one camera on i.MX1/i.MXL camera sensor interface
  */
-static int mx1_camera_add_device(struct soc_camera_device *icd)
+static int mx1_camera_clock_start(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx1_camera_dev *pcdev = ici->priv;
 
-	if (pcdev->icd)
-		return -EBUSY;
-
-	dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
-		 icd->devnum);
-
 	mx1_camera_activate(pcdev);
 
-	pcdev->icd = icd;
-
 	return 0;
 }
 
-static void mx1_camera_remove_device(struct soc_camera_device *icd)
+static void mx1_camera_clock_stop(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx1_camera_dev *pcdev = ici->priv;
 	unsigned int csicr1;
 
-	BUG_ON(icd != pcdev->icd);
-
 	/* disable interrupts */
 	csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
 	__raw_writel(csicr1, pcdev->base + CSICR1);
@@ -461,12 +462,7 @@ static void mx1_camera_remove_device(str
 	/* Stop DMA engine */
 	imx_dma_disable(pcdev->dma_chan);
 
-	dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
-		 icd->devnum);
-
 	mx1_camera_deactivate(pcdev);
-
-	pcdev->icd = NULL;
 }
 
 static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
@@ -679,6 +675,8 @@ static struct soc_camera_host_ops mx1_so
 	.owner		= THIS_MODULE,
 	.add		= mx1_camera_add_device,
 	.remove		= mx1_camera_remove_device,
+	.clock_start	= mx1_camera_clock_start,
+	.clock_stop	= mx1_camera_clock_stop,
 	.set_bus_param	= mx1_camera_set_bus_param,
 	.set_fmt	= mx1_camera_set_fmt,
 	.try_fmt	= mx1_camera_try_fmt,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/mx2_camera.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/mx2_camera.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/mx2_camera.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/mx2_camera.c	2013-08-25 20:43:22.000000000 -0400
@@ -236,7 +236,6 @@ enum mx2_camera_type {
 struct mx2_camera_dev {
 	struct device		*dev;
 	struct soc_camera_host	soc_host;
-	struct soc_camera_device *icd;
 	struct clk		*clk_emma_ahb, *clk_emma_ipg;
 	struct clk		*clk_csi_ahb, *clk_csi_per;
 
@@ -394,8 +393,8 @@ static void mx27_update_emma_buf(struct
 		writel(phys, pcdev->base_emma +
 			PRP_DEST_Y_PTR - 0x14 * bufnum);
 		if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
-			u32 imgsize = pcdev->icd->user_height *
-					pcdev->icd->user_width;
+			u32 imgsize = pcdev->soc_host.icd->user_height *
+					pcdev->soc_host.icd->user_width;
 
 			writel(phys + imgsize, pcdev->base_emma +
 				PRP_DEST_CB_PTR - 0x14 * bufnum);
@@ -413,20 +412,30 @@ static void mx2_camera_deactivate(struct
 	writel(0, pcdev->base_emma + PRP_CNTL);
 }
 
+static int mx2_camera_add_device(struct soc_camera_device *icd)
+{
+	dev_info(icd->parent, "Camera driver attached to camera %d\n",
+		 icd->devnum);
+
+	return 0;
+}
+
+static void mx2_camera_remove_device(struct soc_camera_device *icd)
+{
+	dev_info(icd->parent, "Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
+
 /*
  * The following two functions absolutely depend on the fact, that
  * there can be only one camera on mx2 camera sensor interface
  */
-static int mx2_camera_add_device(struct soc_camera_device *icd)
+static int mx2_camera_clock_start(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx2_camera_dev *pcdev = ici->priv;
 	int ret;
 	u32 csicr1;
 
-	if (pcdev->icd)
-		return -EBUSY;
-
 	ret = clk_prepare_enable(pcdev->clk_csi_ahb);
 	if (ret < 0)
 		return ret;
@@ -441,12 +450,8 @@ static int mx2_camera_add_device(struct
 	pcdev->csicr1 = csicr1;
 	writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
 
-	pcdev->icd = icd;
 	pcdev->frame_count = 0;
 
-	dev_info(icd->parent, "Camera driver attached to camera %d\n",
-		 icd->devnum);
-
 	return 0;
 
 exit_csi_ahb:
@@ -455,19 +460,11 @@ exit_csi_ahb:
 	return ret;
 }
 
-static void mx2_camera_remove_device(struct soc_camera_device *icd)
+static void mx2_camera_clock_stop(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx2_camera_dev *pcdev = ici->priv;
 
-	BUG_ON(icd != pcdev->icd);
-
-	dev_info(icd->parent, "Camera driver detached from camera %d\n",
-		 icd->devnum);
-
 	mx2_camera_deactivate(pcdev);
-
-	pcdev->icd = NULL;
 }
 
 /*
@@ -1280,6 +1277,8 @@ static struct soc_camera_host_ops mx2_so
 	.owner		= THIS_MODULE,
 	.add		= mx2_camera_add_device,
 	.remove		= mx2_camera_remove_device,
+	.clock_start	= mx2_camera_clock_start,
+	.clock_stop	= mx2_camera_clock_stop,
 	.set_fmt	= mx2_camera_set_fmt,
 	.set_crop	= mx2_camera_set_crop,
 	.get_formats	= mx2_camera_get_formats,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/mx3_camera.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/mx3_camera.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/mx3_camera.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/mx3_camera.c	2013-08-25 20:43:22.000000000 -0400
@@ -94,7 +94,6 @@ struct mx3_camera_dev {
 	 * Interface. If anyone ever builds hardware to enable more than one
 	 * camera _simultaneously_, they will have to modify this driver too
 	 */
-	struct soc_camera_device *icd;
 	struct clk		*clk;
 
 	void __iomem		*base;
@@ -461,8 +460,7 @@ static int mx3_camera_init_videobuf(stru
 }
 
 /* First part of ipu_csi_init_interface() */
-static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
-				struct soc_camera_device *icd)
+static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam)
 {
 	u32 conf;
 	long rate;
@@ -506,51 +504,49 @@ static void mx3_camera_activate(struct m
 
 	clk_prepare_enable(mx3_cam->clk);
 	rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
-	dev_dbg(icd->parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
+	dev_dbg(mx3_cam->soc_host.v4l2_dev.dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
 	if (rate)
 		clk_set_rate(mx3_cam->clk, rate);
 }
 
-/* Called with .host_lock held */
 static int mx3_camera_add_device(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct mx3_camera_dev *mx3_cam = ici->priv;
+	dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
+		 icd->devnum);
 
-	if (mx3_cam->icd)
-		return -EBUSY;
+	return 0;
+}
 
-	mx3_camera_activate(mx3_cam, icd);
+static void mx3_camera_remove_device(struct soc_camera_device *icd)
+{
+	dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
 
-	mx3_cam->buf_total = 0;
-	mx3_cam->icd = icd;
+/* Called with .host_lock held */
+static int mx3_camera_clock_start(struct soc_camera_host *ici)
+{
+	struct mx3_camera_dev *mx3_cam = ici->priv;
 
-	dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
-		 icd->devnum);
+	mx3_camera_activate(mx3_cam);
+
+	mx3_cam->buf_total = 0;
 
 	return 0;
 }
 
 /* Called with .host_lock held */
-static void mx3_camera_remove_device(struct soc_camera_device *icd)
+static void mx3_camera_clock_stop(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
 	struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
 
-	BUG_ON(icd != mx3_cam->icd);
-
 	if (*ichan) {
 		dma_release_channel(&(*ichan)->dma_chan);
 		*ichan = NULL;
 	}
 
 	clk_disable_unprepare(mx3_cam->clk);
-
-	mx3_cam->icd = NULL;
-
-	dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
-		 icd->devnum);
 }
 
 static int test_platform_param(struct mx3_camera_dev *mx3_cam,
@@ -1133,6 +1129,8 @@ static struct soc_camera_host_ops mx3_so
 	.owner		= THIS_MODULE,
 	.add		= mx3_camera_add_device,
 	.remove		= mx3_camera_remove_device,
+	.clock_start	= mx3_camera_clock_start,
+	.clock_stop	= mx3_camera_clock_stop,
 	.set_crop	= mx3_camera_set_crop,
 	.set_fmt	= mx3_camera_set_fmt,
 	.try_fmt	= mx3_camera_try_fmt,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/omap1_camera.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/omap1_camera.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/omap1_camera.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/omap1_camera.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,7 +150,6 @@ struct omap1_cam_buf {
 
 struct omap1_cam_dev {
 	struct soc_camera_host		soc_host;
-	struct soc_camera_device	*icd;
 	struct clk			*clk;
 
 	unsigned int			irq;
@@ -564,7 +563,7 @@ static void videobuf_done(struct omap1_c
 {
 	struct omap1_cam_buf *buf = pcdev->active;
 	struct videobuf_buffer *vb;
-	struct device *dev = pcdev->icd->parent;
+	struct device *dev = pcdev->soc_host.icd->parent;
 
 	if (WARN_ON(!buf)) {
 		suspend_capture(pcdev);
@@ -790,7 +789,7 @@ out:
 static irqreturn_t cam_isr(int irq, void *data)
 {
 	struct omap1_cam_dev *pcdev = data;
-	struct device *dev = pcdev->icd->parent;
+	struct device *dev = pcdev->soc_host.icd->parent;
 	struct omap1_cam_buf *buf = pcdev->active;
 	u32 it_status;
 	unsigned long flags;
@@ -894,19 +893,29 @@ static void sensor_reset(struct omap1_ca
 		CAM_WRITE(pcdev, GPIO, !reset);
 }
 
+static int omap1_cam_add_device(struct soc_camera_device *icd)
+{
+	dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
+			icd->devnum);
+
+	return 0;
+}
+
+static void omap1_cam_remove_device(struct soc_camera_device *icd)
+{
+	dev_dbg(icd->parent,
+		"OMAP1 Camera driver detached from camera %d\n", icd->devnum);
+}
+
 /*
  * The following two functions absolutely depend on the fact, that
  * there can be only one camera on OMAP1 camera sensor interface
  */
-static int omap1_cam_add_device(struct soc_camera_device *icd)
+static int omap1_cam_clock_start(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct omap1_cam_dev *pcdev = ici->priv;
 	u32 ctrlclock;
 
-	if (pcdev->icd)
-		return -EBUSY;
-
 	clk_enable(pcdev->clk);
 
 	/* setup sensor clock */
@@ -941,21 +950,14 @@ static int omap1_cam_add_device(struct s
 
 	sensor_reset(pcdev, false);
 
-	pcdev->icd = icd;
-
-	dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
-			icd->devnum);
 	return 0;
 }
 
-static void omap1_cam_remove_device(struct soc_camera_device *icd)
+static void omap1_cam_clock_stop(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct omap1_cam_dev *pcdev = ici->priv;
 	u32 ctrlclock;
 
-	BUG_ON(icd != pcdev->icd);
-
 	suspend_capture(pcdev);
 	disable_capture(pcdev);
 
@@ -973,11 +975,6 @@ static void omap1_cam_remove_device(stru
 	CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~MCLK_EN);
 
 	clk_disable(pcdev->clk);
-
-	pcdev->icd = NULL;
-
-	dev_dbg(icd->parent,
-		"OMAP1 Camera driver detached from camera %d\n", icd->devnum);
 }
 
 /* Duplicate standard formats based on host capability of byte swapping */
@@ -1535,6 +1532,8 @@ static struct soc_camera_host_ops omap1_
 	.owner		= THIS_MODULE,
 	.add		= omap1_cam_add_device,
 	.remove		= omap1_cam_remove_device,
+	.clock_start	= omap1_cam_clock_start,
+	.clock_stop	= omap1_cam_clock_stop,
 	.get_formats	= omap1_cam_get_formats,
 	.set_crop	= omap1_cam_set_crop,
 	.set_fmt	= omap1_cam_set_fmt,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/pxa_camera.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/pxa_camera.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/pxa_camera.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/pxa_camera.c	2013-08-25 20:43:22.000000000 -0400
@@ -200,7 +200,6 @@ struct pxa_camera_dev {
 	 * interface. If anyone ever builds hardware to enable more than
 	 * one camera, they will have to modify this driver too
 	 */
-	struct soc_camera_device *icd;
 	struct clk		*clk;
 
 	unsigned int		irq;
@@ -956,40 +955,39 @@ static irqreturn_t pxa_camera_irq(int ir
 	return IRQ_HANDLED;
 }
 
+static int pxa_camera_add_device(struct soc_camera_device *icd)
+{
+	dev_info(icd->parent, "PXA Camera driver attached to camera %d\n",
+		 icd->devnum);
+
+	return 0;
+}
+
+static void pxa_camera_remove_device(struct soc_camera_device *icd)
+{
+	dev_info(icd->parent, "PXA Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
+
 /*
  * The following two functions absolutely depend on the fact, that
  * there can be only one camera on PXA quick capture interface
  * Called with .host_lock held
  */
-static int pxa_camera_add_device(struct soc_camera_device *icd)
+static int pxa_camera_clock_start(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
 
-	if (pcdev->icd)
-		return -EBUSY;
-
 	pxa_camera_activate(pcdev);
 
-	pcdev->icd = icd;
-
-	dev_info(icd->parent, "PXA Camera driver attached to camera %d\n",
-		 icd->devnum);
-
 	return 0;
 }
 
 /* Called with .host_lock held */
-static void pxa_camera_remove_device(struct soc_camera_device *icd)
+static void pxa_camera_clock_stop(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
 
-	BUG_ON(icd != pcdev->icd);
-
-	dev_info(icd->parent, "PXA Camera driver detached from camera %d\n",
-		 icd->devnum);
-
 	/* disable capture, disable interrupts */
 	__raw_writel(0x3ff, pcdev->base + CICR0);
 
@@ -999,8 +997,6 @@ static void pxa_camera_remove_device(str
 	DCSR(pcdev->dma_chans[2]) = 0;
 
 	pxa_camera_deactivate(pcdev);
-
-	pcdev->icd = NULL;
 }
 
 static int test_platform_param(struct pxa_camera_dev *pcdev,
@@ -1596,8 +1592,8 @@ static int pxa_camera_suspend(struct dev
 	pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3);
 	pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4);
 
-	if (pcdev->icd) {
-		struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
+	if (pcdev->soc_host.icd) {
+		struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
 		ret = v4l2_subdev_call(sd, core, s_power, 0);
 		if (ret == -ENOIOCTLCMD)
 			ret = 0;
@@ -1622,8 +1618,8 @@ static int pxa_camera_resume(struct devi
 	__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3);
 	__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4);
 
-	if (pcdev->icd) {
-		struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
+	if (pcdev->soc_host.icd) {
+		struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
 		ret = v4l2_subdev_call(sd, core, s_power, 1);
 		if (ret == -ENOIOCTLCMD)
 			ret = 0;
@@ -1640,6 +1636,8 @@ static struct soc_camera_host_ops pxa_so
 	.owner		= THIS_MODULE,
 	.add		= pxa_camera_add_device,
 	.remove		= pxa_camera_remove_device,
+	.clock_start	= pxa_camera_clock_start,
+	.clock_stop	= pxa_camera_clock_stop,
 	.set_crop	= pxa_camera_set_crop,
 	.get_formats	= pxa_camera_get_formats,
 	.put_formats	= pxa_camera_put_formats,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/moduleparam.h>
+#include <linux/of.h>
 #include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/device.h>
@@ -35,6 +36,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/sched.h>
 
+#include <media/v4l2-async.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
 #include <media/soc_camera.h>
@@ -44,6 +46,8 @@
 #include <media/v4l2-mediabus.h>
 #include <media/soc_mediabus.h>
 
+#include "soc_scale_crop.h"
+
 /* register offsets for sh7722 / sh7723 */
 
 #define CAPSR  0x00 /* Capture start register */
@@ -95,7 +99,10 @@ struct sh_mobile_ceu_buffer {
 
 struct sh_mobile_ceu_dev {
 	struct soc_camera_host ici;
-	struct soc_camera_device *icd;
+	/* Asynchronous CSI2 linking */
+	struct v4l2_async_subdev *csi2_asd;
+	struct v4l2_subdev *csi2_sd;
+	/* Synchronous probing compatibility */
 	struct platform_device *csi2_pdev;
 
 	unsigned int irq;
@@ -119,6 +126,7 @@ struct sh_mobile_ceu_dev {
 
 	enum v4l2_field field;
 	int sequence;
+	unsigned long flags;
 
 	unsigned int image_mode:1;
 	unsigned int is_16bit:1;
@@ -163,7 +171,6 @@ static u32 ceu_read(struct sh_mobile_ceu
 static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
 {
 	int i, success = 0;
-	struct soc_camera_device *icd = pcdev->icd;
 
 	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
 
@@ -185,9 +192,8 @@ static int sh_mobile_ceu_soft_reset(stru
 		udelay(1);
 	}
 
-
 	if (2 != success) {
-		dev_warn(icd->pdev, "soft reset time out\n");
+		dev_warn(pcdev->ici.v4l2_dev.dev, "soft reset time out\n");
 		return -EIO;
 	}
 
@@ -277,7 +283,7 @@ static int sh_mobile_ceu_videobuf_setup(
  */
 static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 {
-	struct soc_camera_device *icd = pcdev->icd;
+	struct soc_camera_device *icd = pcdev->ici.icd;
 	dma_addr_t phys_addr_top, phys_addr_bottom;
 	unsigned long top1, top2;
 	unsigned long bottom1, bottom2;
@@ -534,72 +540,92 @@ static struct v4l2_subdev *find_csi2(str
 {
 	struct v4l2_subdev *sd;
 
-	if (!pcdev->csi2_pdev)
-		return NULL;
+	if (pcdev->csi2_sd)
+		return pcdev->csi2_sd;
 
-	v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
-		if (&pcdev->csi2_pdev->dev == v4l2_get_subdevdata(sd))
-			return sd;
+	if (pcdev->csi2_asd) {
+		char name[] = "sh-mobile-csi2";
+		v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
+			if (!strncmp(name, sd->name, sizeof(name) - 1)) {
+				pcdev->csi2_sd = sd;
+				return sd;
+			}
+	}
 
 	return NULL;
 }
 
-/* Called with .host_lock held */
+static struct v4l2_subdev *csi2_subdev(struct sh_mobile_ceu_dev *pcdev,
+				       struct soc_camera_device *icd)
+{
+	struct v4l2_subdev *sd = pcdev->csi2_sd;
+
+	return sd && sd->grp_id == soc_camera_grp_id(icd) ? sd : NULL;
+}
+
 static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	struct v4l2_subdev *csi2_sd;
+	struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
 	int ret;
 
-	if (pcdev->icd)
-		return -EBUSY;
-
-	dev_info(icd->parent,
-		 "SuperH Mobile CEU driver attached to camera %d\n",
-		 icd->devnum);
-
-	pm_runtime_get_sync(ici->v4l2_dev.dev);
-
-	pcdev->buf_total = 0;
-
-	ret = sh_mobile_ceu_soft_reset(pcdev);
-
-	csi2_sd = find_csi2(pcdev);
 	if (csi2_sd) {
 		csi2_sd->grp_id = soc_camera_grp_id(icd);
 		v4l2_set_subdev_hostdata(csi2_sd, icd);
 	}
 
 	ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
-	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
-		pm_runtime_put(ici->v4l2_dev.dev);
+	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
 		return ret;
-	}
 
 	/*
 	 * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
 	 * has not found this soc-camera device among its clients
 	 */
-	if (ret == -ENODEV && csi2_sd)
+	if (csi2_sd && ret == -ENODEV)
 		csi2_sd->grp_id = 0;
-	pcdev->icd = icd;
+
+	dev_info(icd->parent,
+		 "SuperH Mobile CEU%s driver attached to camera %d\n",
+		 csi2_sd && csi2_sd->grp_id ? "/CSI-2" : "", icd->devnum);
 
 	return 0;
 }
 
-/* Called with .host_lock held */
 static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
 	struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
 
-	BUG_ON(icd != pcdev->icd);
+	dev_info(icd->parent,
+		 "SuperH Mobile CEU driver detached from camera %d\n",
+		 icd->devnum);
 
 	v4l2_subdev_call(csi2_sd, core, s_power, 0);
-	if (csi2_sd)
-		csi2_sd->grp_id = 0;
+}
+
+/* Called with .host_lock held */
+static int sh_mobile_ceu_clock_start(struct soc_camera_host *ici)
+{
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	int ret;
+
+	pm_runtime_get_sync(ici->v4l2_dev.dev);
+
+	pcdev->buf_total = 0;
+
+	ret = sh_mobile_ceu_soft_reset(pcdev);
+
+	return 0;
+}
+
+/* Called with .host_lock held */
+static void sh_mobile_ceu_clock_stop(struct soc_camera_host *ici)
+{
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+
 	/* disable capture, disable interrupts */
 	ceu_write(pcdev, CEIER, 0);
 	sh_mobile_ceu_soft_reset(pcdev);
@@ -614,12 +640,6 @@ static void sh_mobile_ceu_remove_device(
 	spin_unlock_irq(&pcdev->lock);
 
 	pm_runtime_put(ici->v4l2_dev.dev);
-
-	dev_info(icd->parent,
-		 "SuperH Mobile CEU driver detached from camera %d\n",
-		 icd->devnum);
-
-	pcdev->icd = NULL;
 }
 
 /*
@@ -705,7 +725,7 @@ static void sh_mobile_ceu_set_rect(struc
 	}
 
 	/* CSI2 special configuration */
-	if (pcdev->pdata->csi2) {
+	if (csi2_subdev(pcdev, icd)) {
 		in_width = ((in_width - 2) * 2);
 		left_offset *= 2;
 	}
@@ -762,13 +782,7 @@ static void capture_restore(struct sh_mo
 static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev,
 					   struct soc_camera_device *icd)
 {
-	if (pcdev->csi2_pdev) {
-		struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
-		if (csi2_sd && csi2_sd->grp_id == soc_camera_grp_id(icd))
-			return csi2_sd;
-	}
-
-	return soc_camera_to_subdev(icd);
+	return csi2_subdev(pcdev, icd) ? : soc_camera_to_subdev(icd);
 }
 
 #define CEU_BUS_FLAGS (V4L2_MBUS_MASTER |	\
@@ -809,7 +823,7 @@ static int sh_mobile_ceu_set_bus_param(s
 	/* Make choises, based on platform preferences */
 	if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
 	    (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
-		if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
+		if (pcdev->flags & SH_CEU_FLAG_HSYNC_LOW)
 			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
 		else
 			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
@@ -817,7 +831,7 @@ static int sh_mobile_ceu_set_bus_param(s
 
 	if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
 	    (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
-		if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
+		if (pcdev->flags & SH_CEU_FLAG_VSYNC_LOW)
 			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
 		else
 			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
@@ -872,11 +886,11 @@ static int sh_mobile_ceu_set_bus_param(s
 	value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
 	value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
 
-	if (pcdev->pdata->csi2) /* CSI2 mode */
+	if (csi2_subdev(pcdev, icd)) /* CSI2 mode */
 		value |= 3 << 12;
 	else if (pcdev->is_16bit)
 		value |= 1 << 12;
-	else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT)
+	else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT)
 		value |= 2 << 12;
 
 	ceu_write(pcdev, CAMCR, value);
@@ -993,8 +1007,6 @@ static bool sh_mobile_ceu_packing_suppor
 		 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
 }
 
-static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
-
 static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl)
 {
 	return container_of(ctrl->handler, struct soc_camera_device,
@@ -1051,7 +1063,7 @@ static int sh_mobile_ceu_get_formats(str
 		return 0;
 	}
 
-	if (!pcdev->pdata->csi2) {
+	if (!csi2_subdev(pcdev, icd)) {
 		/* Are there any restrictions in the CSI-2 case? */
 		ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
 		if (ret < 0)
@@ -1072,7 +1084,7 @@ static int sh_mobile_ceu_get_formats(str
 		/* FIXME: subwindow is lost between close / open */
 
 		/* Cache current client geometry */
-		ret = client_g_rect(sd, &rect);
+		ret = soc_camera_client_g_rect(sd, &rect);
 		if (ret < 0)
 			return ret;
 
@@ -1182,334 +1194,8 @@ static void sh_mobile_ceu_put_formats(st
 	icd->host_priv = NULL;
 }
 
-/* Check if any dimension of r1 is smaller than respective one of r2 */
-static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
-{
-	return r1->width < r2->width || r1->height < r2->height;
-}
-
-/* Check if r1 fails to cover r2 */
-static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
-{
-	return r1->left > r2->left || r1->top > r2->top ||
-		r1->left + r1->width < r2->left + r2->width ||
-		r1->top + r1->height < r2->top + r2->height;
-}
-
-static unsigned int scale_down(unsigned int size, unsigned int scale)
-{
-	return (size * 4096 + scale / 2) / scale;
-}
-
-static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
-{
-	return (input * 4096 + output / 2) / output;
-}
-
-/* Get and store current client crop */
-static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
-{
-	struct v4l2_crop crop;
-	struct v4l2_cropcap cap;
-	int ret;
-
-	crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	ret = v4l2_subdev_call(sd, video, g_crop, &crop);
-	if (!ret) {
-		*rect = crop.c;
-		return ret;
-	}
-
-	/* Camera driver doesn't support .g_crop(), assume default rectangle */
-	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
-	if (!ret)
-		*rect = cap.defrect;
-
-	return ret;
-}
-
-/* Client crop has changed, update our sub-rectangle to remain within the area */
-static void update_subrect(struct sh_mobile_ceu_cam *cam)
-{
-	struct v4l2_rect *rect = &cam->rect, *subrect = &cam->subrect;
-
-	if (rect->width < subrect->width)
-		subrect->width = rect->width;
-
-	if (rect->height < subrect->height)
-		subrect->height = rect->height;
-
-	if (rect->left > subrect->left)
-		subrect->left = rect->left;
-	else if (rect->left + rect->width >
-		 subrect->left + subrect->width)
-		subrect->left = rect->left + rect->width -
-			subrect->width;
-
-	if (rect->top > subrect->top)
-		subrect->top = rect->top;
-	else if (rect->top + rect->height >
-		 subrect->top + subrect->height)
-		subrect->top = rect->top + rect->height -
-			subrect->height;
-}
-
-/*
- * The common for both scaling and cropping iterative approach is:
- * 1. try if the client can produce exactly what requested by the user
- * 2. if (1) failed, try to double the client image until we get one big enough
- * 3. if (2) failed, try to request the maximum image
- */
-static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
-			 struct v4l2_crop *cam_crop)
-{
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-	struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
-	struct device *dev = sd->v4l2_dev->dev;
-	struct sh_mobile_ceu_cam *cam = icd->host_priv;
-	struct v4l2_cropcap cap;
-	int ret;
-	unsigned int width, height;
-
-	v4l2_subdev_call(sd, video, s_crop, crop);
-	ret = client_g_rect(sd, cam_rect);
-	if (ret < 0)
-		return ret;
-
-	/*
-	 * Now cam_crop contains the current camera input rectangle, and it must
-	 * be within camera cropcap bounds
-	 */
-	if (!memcmp(rect, cam_rect, sizeof(*rect))) {
-		/* Even if camera S_CROP failed, but camera rectangle matches */
-		dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
-			rect->width, rect->height, rect->left, rect->top);
-		cam->rect = *cam_rect;
-		return 0;
-	}
-
-	/* Try to fix cropping, that camera hasn't managed to set */
-	dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
-		cam_rect->width, cam_rect->height,
-		cam_rect->left, cam_rect->top,
-		rect->width, rect->height, rect->left, rect->top);
-
-	/* We need sensor maximum rectangle */
-	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
-	if (ret < 0)
-		return ret;
-
-	/* Put user requested rectangle within sensor bounds */
-	soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
-			      cap.bounds.width);
-	soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
-			      cap.bounds.height);
-
-	/*
-	 * Popular special case - some cameras can only handle fixed sizes like
-	 * QVGA, VGA,... Take care to avoid infinite loop.
-	 */
-	width = max(cam_rect->width, 2);
-	height = max(cam_rect->height, 2);
-
-	/*
-	 * Loop as long as sensor is not covering the requested rectangle and
-	 * is still within its bounds
-	 */
-	while (!ret && (is_smaller(cam_rect, rect) ||
-			is_inside(cam_rect, rect)) &&
-	       (cap.bounds.width > width || cap.bounds.height > height)) {
-
-		width *= 2;
-		height *= 2;
-
-		cam_rect->width = width;
-		cam_rect->height = height;
-
-		/*
-		 * We do not know what capabilities the camera has to set up
-		 * left and top borders. We could try to be smarter in iterating
-		 * them, e.g., if camera current left is to the right of the
-		 * target left, set it to the middle point between the current
-		 * left and minimum left. But that would add too much
-		 * complexity: we would have to iterate each border separately.
-		 * Instead we just drop to the left and top bounds.
-		 */
-		if (cam_rect->left > rect->left)
-			cam_rect->left = cap.bounds.left;
-
-		if (cam_rect->left + cam_rect->width < rect->left + rect->width)
-			cam_rect->width = rect->left + rect->width -
-				cam_rect->left;
-
-		if (cam_rect->top > rect->top)
-			cam_rect->top = cap.bounds.top;
-
-		if (cam_rect->top + cam_rect->height < rect->top + rect->height)
-			cam_rect->height = rect->top + rect->height -
-				cam_rect->top;
-
-		v4l2_subdev_call(sd, video, s_crop, cam_crop);
-		ret = client_g_rect(sd, cam_rect);
-		dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
-			cam_rect->width, cam_rect->height,
-			cam_rect->left, cam_rect->top);
-	}
-
-	/* S_CROP must not modify the rectangle */
-	if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
-		/*
-		 * The camera failed to configure a suitable cropping,
-		 * we cannot use the current rectangle, set to max
-		 */
-		*cam_rect = cap.bounds;
-		v4l2_subdev_call(sd, video, s_crop, cam_crop);
-		ret = client_g_rect(sd, cam_rect);
-		dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
-			cam_rect->width, cam_rect->height,
-			cam_rect->left, cam_rect->top);
-	}
-
-	if (!ret) {
-		cam->rect = *cam_rect;
-		update_subrect(cam);
-	}
-
-	return ret;
-}
-
-/* Iterative s_mbus_fmt, also updates cached client crop on success */
-static int client_s_fmt(struct soc_camera_device *icd,
-			struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
-{
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	struct sh_mobile_ceu_cam *cam = icd->host_priv;
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-	struct device *dev = icd->parent;
-	unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
-	unsigned int max_width, max_height;
-	struct v4l2_cropcap cap;
-	bool ceu_1to1;
-	int ret;
-
-	ret = v4l2_device_call_until_err(sd->v4l2_dev,
-					 soc_camera_grp_id(icd), video,
-					 s_mbus_fmt, mf);
-	if (ret < 0)
-		return ret;
-
-	dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
-
-	if (width == mf->width && height == mf->height) {
-		/* Perfect! The client has done it all. */
-		ceu_1to1 = true;
-		goto update_cache;
-	}
-
-	ceu_1to1 = false;
-	if (!ceu_can_scale)
-		goto update_cache;
-
-	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
-	if (ret < 0)
-		return ret;
-
-	max_width = min(cap.bounds.width, pcdev->max_width);
-	max_height = min(cap.bounds.height, pcdev->max_height);
-
-	/* Camera set a format, but geometry is not precise, try to improve */
-	tmp_w = mf->width;
-	tmp_h = mf->height;
-
-	/* width <= max_width && height <= max_height - guaranteed by try_fmt */
-	while ((width > tmp_w || height > tmp_h) &&
-	       tmp_w < max_width && tmp_h < max_height) {
-		tmp_w = min(2 * tmp_w, max_width);
-		tmp_h = min(2 * tmp_h, max_height);
-		mf->width = tmp_w;
-		mf->height = tmp_h;
-		ret = v4l2_device_call_until_err(sd->v4l2_dev,
-					soc_camera_grp_id(icd), video,
-					s_mbus_fmt, mf);
-		dev_geo(dev, "Camera scaled to %ux%u\n",
-			mf->width, mf->height);
-		if (ret < 0) {
-			/* This shouldn't happen */
-			dev_err(dev, "Client failed to set format: %d\n", ret);
-			return ret;
-		}
-	}
-
-update_cache:
-	/* Update cache */
-	ret = client_g_rect(sd, &cam->rect);
-	if (ret < 0)
-		return ret;
-
-	if (ceu_1to1)
-		cam->subrect = cam->rect;
-	else
-		update_subrect(cam);
-
-	return 0;
-}
-
-/**
- * @width	- on output: user width, mapped back to input
- * @height	- on output: user height, mapped back to input
- * @mf		- in- / output camera output window
- */
-static int client_scale(struct soc_camera_device *icd,
-			struct v4l2_mbus_framefmt *mf,
-			unsigned int *width, unsigned int *height,
-			bool ceu_can_scale)
-{
-	struct sh_mobile_ceu_cam *cam = icd->host_priv;
-	struct device *dev = icd->parent;
-	struct v4l2_mbus_framefmt mf_tmp = *mf;
-	unsigned int scale_h, scale_v;
-	int ret;
-
-	/*
-	 * 5. Apply iterative camera S_FMT for camera user window (also updates
-	 *    client crop cache and the imaginary sub-rectangle).
-	 */
-	ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale);
-	if (ret < 0)
-		return ret;
-
-	dev_geo(dev, "5: camera scaled to %ux%u\n",
-		mf_tmp.width, mf_tmp.height);
-
-	/* 6. Retrieve camera output window (g_fmt) */
-
-	/* unneeded - it is already in "mf_tmp" */
-
-	/* 7. Calculate new client scales. */
-	scale_h = calc_generic_scale(cam->rect.width, mf_tmp.width);
-	scale_v = calc_generic_scale(cam->rect.height, mf_tmp.height);
-
-	mf->width	= mf_tmp.width;
-	mf->height	= mf_tmp.height;
-	mf->colorspace	= mf_tmp.colorspace;
-
-	/*
-	 * 8. Calculate new CEU crop - apply camera scales to previously
-	 *    updated "effective" crop.
-	 */
-	*width = scale_down(cam->subrect.width, scale_h);
-	*height = scale_down(cam->subrect.height, scale_v);
-
-	dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
-
-	return 0;
-}
+#define scale_down(size, scale) soc_camera_shift_scale(size, 12, scale)
+#define calc_generic_scale(in, out) soc_camera_calc_scale(in, 12, out)
 
 /*
  * CEU can scale and crop, but we don't want to waste bandwidth and kill the
@@ -1547,7 +1233,8 @@ static int sh_mobile_ceu_set_crop(struct
 	 * 1. - 2. Apply iterative camera S_CROP for new input window, read back
 	 * actual camera rectangle.
 	 */
-	ret = client_s_crop(icd, &a_writable, &cam_crop);
+	ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
+				       &cam->rect, &cam->subrect);
 	if (ret < 0)
 		return ret;
 
@@ -1666,55 +1353,6 @@ static int sh_mobile_ceu_get_crop(struct
 	return 0;
 }
 
-/*
- * Calculate real client output window by applying new scales to the current
- * client crop. New scales are calculated from the requested output format and
- * CEU crop, mapped backed onto the client input (subrect).
- */
-static void calculate_client_output(struct soc_camera_device *icd,
-		const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
-{
-	struct sh_mobile_ceu_cam *cam = icd->host_priv;
-	struct device *dev = icd->parent;
-	struct v4l2_rect *cam_subrect = &cam->subrect;
-	unsigned int scale_v, scale_h;
-
-	if (cam_subrect->width == cam->rect.width &&
-	    cam_subrect->height == cam->rect.height) {
-		/* No sub-cropping */
-		mf->width	= pix->width;
-		mf->height	= pix->height;
-		return;
-	}
-
-	/* 1.-2. Current camera scales and subwin - cached. */
-
-	dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
-		cam_subrect->width, cam_subrect->height,
-		cam_subrect->left, cam_subrect->top);
-
-	/*
-	 * 3. Calculate new combined scales from input sub-window to requested
-	 *    user window.
-	 */
-
-	/*
-	 * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
-	 * (128x96) or larger than VGA
-	 */
-	scale_h = calc_generic_scale(cam_subrect->width, pix->width);
-	scale_v = calc_generic_scale(cam_subrect->height, pix->height);
-
-	dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
-
-	/*
-	 * 4. Calculate desired client output window by applying combined scales
-	 *    to client (real) input window.
-	 */
-	mf->width	= scale_down(cam->rect.width, scale_h);
-	mf->height	= scale_down(cam->rect.height, scale_v);
-}
-
 /* Similar to set_crop multistage iterative algorithm */
 static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
 				 struct v4l2_format *f)
@@ -1727,8 +1365,8 @@ static int sh_mobile_ceu_set_fmt(struct
 	struct v4l2_mbus_framefmt mf;
 	__u32 pixfmt = pix->pixelformat;
 	const struct soc_camera_format_xlate *xlate;
-	/* Keep Compiler Happy */
-	unsigned int ceu_sub_width = 0, ceu_sub_height = 0;
+	unsigned int ceu_sub_width = pcdev->max_width,
+		ceu_sub_height = pcdev->max_height;
 	u16 scale_v, scale_h;
 	int ret;
 	bool image_mode;
@@ -1755,7 +1393,7 @@ static int sh_mobile_ceu_set_fmt(struct
 	}
 
 	/* 1.-4. Calculate desired client output geometry */
-	calculate_client_output(icd, pix, &mf);
+	soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf, 12);
 	mf.field	= pix->field;
 	mf.colorspace	= pix->colorspace;
 	mf.code		= xlate->code;
@@ -1777,8 +1415,9 @@ static int sh_mobile_ceu_set_fmt(struct
 	dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
 
 	/* 5. - 9. */
-	ret = client_scale(icd, &mf, &ceu_sub_width, &ceu_sub_height,
-			   image_mode && V4L2_FIELD_NONE == field);
+	ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
+				&mf, &ceu_sub_width, &ceu_sub_height,
+				image_mode && V4L2_FIELD_NONE == field, 12);
 
 	dev_geo(dev, "5-9: client scale return %d\n", ret);
 
@@ -2036,6 +1675,8 @@ static struct soc_camera_host_ops sh_mob
 	.owner		= THIS_MODULE,
 	.add		= sh_mobile_ceu_add_device,
 	.remove		= sh_mobile_ceu_remove_device,
+	.clock_start	= sh_mobile_ceu_clock_start,
+	.clock_stop	= sh_mobile_ceu_clock_stop,
 	.get_formats	= sh_mobile_ceu_get_formats,
 	.put_formats	= sh_mobile_ceu_put_formats,
 	.get_crop	= sh_mobile_ceu_get_crop,
@@ -2079,7 +1720,7 @@ static int sh_mobile_ceu_probe(struct pl
 	struct resource *res;
 	void __iomem *base;
 	unsigned int irq;
-	int err = 0;
+	int err, i;
 	struct bus_wait wait = {
 		.completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion),
 		.notifier.notifier_call = bus_notify,
@@ -2104,13 +1745,36 @@ static int sh_mobile_ceu_probe(struct pl
 	init_completion(&pcdev->complete);
 
 	pcdev->pdata = pdev->dev.platform_data;
-	if (!pcdev->pdata) {
+	if (!pcdev->pdata && !pdev->dev.of_node) {
 		dev_err(&pdev->dev, "CEU platform data not set.\n");
 		return -EINVAL;
 	}
 
-	pcdev->max_width = pcdev->pdata->max_width ? : 2560;
-	pcdev->max_height = pcdev->pdata->max_height ? : 1920;
+	/* TODO: implement per-device bus flags */
+	if (pcdev->pdata) {
+		pcdev->max_width = pcdev->pdata->max_width;
+		pcdev->max_height = pcdev->pdata->max_height;
+		pcdev->flags = pcdev->pdata->flags;
+	}
+
+	if (!pcdev->max_width) {
+		unsigned int v;
+		err = of_property_read_u32(pdev->dev.of_node, "renesas,max-width", &v);
+		if (!err)
+			pcdev->max_width = v;
+
+		if (!pcdev->max_width)
+			pcdev->max_width = 2560;
+	}
+	if (!pcdev->max_height) {
+		unsigned int v;
+		err = of_property_read_u32(pdev->dev.of_node, "renesas,max-height", &v);
+		if (!err)
+			pcdev->max_height = v;
+
+		if (!pcdev->max_height)
+			pcdev->max_height = 1920;
+	}
 
 	base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(base))
@@ -2160,31 +1824,60 @@ static int sh_mobile_ceu_probe(struct pl
 		goto exit_free_clk;
 	}
 
-	err = soc_camera_host_register(&pcdev->ici);
-	if (err)
-		goto exit_free_ctx;
+	if (pcdev->pdata && pcdev->pdata->asd_sizes) {
+		struct v4l2_async_subdev **asd;
+		char name[] = "sh-mobile-csi2";
+		int j;
 
-	/* CSI2 interfacing */
-	csi2 = pcdev->pdata->csi2;
+		/*
+		 * CSI2 interfacing: several groups can use CSI2, pick up the
+		 * first one
+		 */
+		asd = pcdev->pdata->asd;
+		for (j = 0; pcdev->pdata->asd_sizes[j]; j++) {
+			for (i = 0; i < pcdev->pdata->asd_sizes[j]; i++, asd++) {
+				dev_dbg(&pdev->dev, "%s(): subdev #%d, type %u\n",
+					__func__, i, (*asd)->bus_type);
+				if ((*asd)->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
+				    !strncmp(name, (*asd)->match.platform.name,
+					     sizeof(name) - 1)) {
+					pcdev->csi2_asd = *asd;
+					break;
+				}
+			}
+			if (pcdev->csi2_asd)
+				break;
+		}
+
+		pcdev->ici.asd = pcdev->pdata->asd;
+		pcdev->ici.asd_sizes = pcdev->pdata->asd_sizes;
+	}
+
+	/* Legacy CSI2 interfacing */
+	csi2 = pcdev->pdata ? pcdev->pdata->csi2 : NULL;
 	if (csi2) {
+		/*
+		 * TODO: remove this once all users are converted to
+		 * asynchronous CSI2 probing. If it has to be kept, csi2
+		 * platform device resources have to be added, using
+		 * platform_device_add_resources()
+		 */
 		struct platform_device *csi2_pdev =
 			platform_device_alloc("sh-mobile-csi2", csi2->id);
 		struct sh_csi2_pdata *csi2_pdata = csi2->platform_data;
 
 		if (!csi2_pdev) {
 			err = -ENOMEM;
-			goto exit_host_unregister;
+			goto exit_free_ctx;
 		}
 
 		pcdev->csi2_pdev		= csi2_pdev;
 
-		err = platform_device_add_data(csi2_pdev, csi2_pdata, sizeof(*csi2_pdata));
+		err = platform_device_add_data(csi2_pdev, csi2_pdata,
+					       sizeof(*csi2_pdata));
 		if (err < 0)
 			goto exit_pdev_put;
 
-		csi2_pdata			= csi2_pdev->dev.platform_data;
-		csi2_pdata->v4l2_dev		= &pcdev->ici.v4l2_dev;
-
 		csi2_pdev->resource		= csi2->resource;
 		csi2_pdev->num_resources	= csi2->num_resources;
 
@@ -2226,17 +1919,38 @@ static int sh_mobile_ceu_probe(struct pl
 			err = -ENODEV;
 			goto exit_pdev_unregister;
 		}
+
+		pcdev->csi2_sd = platform_get_drvdata(csi2_pdev);
+	}
+
+	err = soc_camera_host_register(&pcdev->ici);
+	if (err)
+		goto exit_csi2_unregister;
+
+	if (csi2) {
+		err = v4l2_device_register_subdev(&pcdev->ici.v4l2_dev,
+						  pcdev->csi2_sd);
+		dev_dbg(&pdev->dev, "%s(): ret(register_subdev) = %d\n",
+			__func__, err);
+		if (err < 0)
+			goto exit_host_unregister;
+		/* v4l2_device_register_subdev() took a reference too */
+		module_put(pcdev->csi2_sd->owner);
 	}
 
 	return 0;
 
-exit_pdev_unregister:
-	platform_device_del(pcdev->csi2_pdev);
-exit_pdev_put:
-	pcdev->csi2_pdev->resource = NULL;
-	platform_device_put(pcdev->csi2_pdev);
 exit_host_unregister:
 	soc_camera_host_unregister(&pcdev->ici);
+exit_csi2_unregister:
+	if (csi2) {
+		module_put(pcdev->csi2_pdev->dev.driver->owner);
+exit_pdev_unregister:
+		platform_device_del(pcdev->csi2_pdev);
+exit_pdev_put:
+		pcdev->csi2_pdev->resource = NULL;
+		platform_device_put(pcdev->csi2_pdev);
+	}
 exit_free_ctx:
 	vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
 exit_free_clk:
@@ -2287,10 +2001,18 @@ static const struct dev_pm_ops sh_mobile
 	.runtime_resume = sh_mobile_ceu_runtime_nop,
 };
 
+static const struct of_device_id sh_mobile_ceu_of_match[] = {
+	{ .compatible = "renesas,sh-mobile-ceu" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match);
+
 static struct platform_driver sh_mobile_ceu_driver = {
 	.driver		= {
 		.name	= "sh_mobile_ceu",
+		.owner	= THIS_MODULE,
 		.pm	= &sh_mobile_ceu_dev_pm_ops,
+		.of_match_table = sh_mobile_ceu_of_match,
 	},
 	.probe		= sh_mobile_ceu_probe,
 	.remove		= sh_mobile_ceu_remove,
@@ -2314,5 +2036,5 @@ module_exit(sh_mobile_ceu_exit);
 MODULE_DESCRIPTION("SuperH Mobile CEU driver");
 MODULE_AUTHOR("Magnus Damm");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.6");
+MODULE_VERSION("0.1.0");
 MODULE_ALIAS("platform:sh_mobile_ceu");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/sh_mobile_csi2.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/sh_mobile_csi2.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/sh_mobile_csi2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/sh_mobile_csi2.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,6 @@
 
 struct sh_csi2 {
 	struct v4l2_subdev		subdev;
-	struct list_head		list;
 	unsigned int			irq;
 	unsigned long			mipi_flags;
 	void __iomem			*base;
@@ -44,6 +43,8 @@ struct sh_csi2 {
 	struct sh_csi2_client_config	*client;
 };
 
+static void sh_csi2_hwinit(struct sh_csi2 *priv);
+
 static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
 			   struct v4l2_mbus_framefmt *mf)
 {
@@ -132,10 +133,58 @@ static int sh_csi2_s_fmt(struct v4l2_sub
 static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd,
 				 struct v4l2_mbus_config *cfg)
 {
-	cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
-		V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
-		V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
-	cfg->type = V4L2_MBUS_PARALLEL;
+	struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
+
+	if (!priv->mipi_flags) {
+		struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
+		struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
+		struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
+		unsigned long common_flags, csi2_flags;
+		struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,};
+		int ret;
+
+		/* Check if we can support this camera */
+		csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
+			V4L2_MBUS_CSI2_1_LANE;
+
+		switch (pdata->type) {
+		case SH_CSI2C:
+			if (priv->client->lanes != 1)
+				csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
+			break;
+		case SH_CSI2I:
+			switch (priv->client->lanes) {
+			default:
+				csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
+			case 3:
+				csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
+			case 2:
+				csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
+			}
+		}
+
+		ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &client_cfg);
+		if (ret == -ENOIOCTLCMD)
+			common_flags = csi2_flags;
+		else if (!ret)
+			common_flags = soc_mbus_config_compatible(&client_cfg,
+								  csi2_flags);
+		else
+			common_flags = 0;
+
+		if (!common_flags)
+			return -EINVAL;
+
+		/* All good: camera MIPI configuration supported */
+		priv->mipi_flags = common_flags;
+	}
+
+	if (cfg) {
+		cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
+			V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+			V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
+		cfg->type = V4L2_MBUS_PARALLEL;
+	}
 
 	return 0;
 }
@@ -146,8 +195,17 @@ static int sh_csi2_s_mbus_config(struct
 	struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
 	struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
 	struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
-	struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,
-					      .flags = priv->mipi_flags};
+	struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,};
+	int ret = sh_csi2_g_mbus_config(sd, NULL);
+
+	if (ret < 0)
+		return ret;
+
+	pm_runtime_get_sync(&priv->pdev->dev);
+
+	sh_csi2_hwinit(priv);
+
+	client_cfg.flags = priv->mipi_flags;
 
 	return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg);
 }
@@ -202,19 +260,19 @@ static void sh_csi2_hwinit(struct sh_csi
 
 static int sh_csi2_client_connect(struct sh_csi2 *priv)
 {
-	struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
-	struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev);
-	struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
 	struct device *dev = v4l2_get_subdevdata(&priv->subdev);
-	struct v4l2_mbus_config cfg;
-	unsigned long common_flags, csi2_flags;
-	int i, ret;
+	struct sh_csi2_pdata *pdata = dev->platform_data;
+	struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev);
+	int i;
 
 	if (priv->client)
 		return -EBUSY;
 
 	for (i = 0; i < pdata->num_clients; i++)
-		if (&pdata->clients[i].pdev->dev == icd->pdev)
+		if ((pdata->clients[i].pdev &&
+		     &pdata->clients[i].pdev->dev == icd->pdev) ||
+		    (icd->control &&
+		     strcmp(pdata->clients[i].name, dev_name(icd->control))))
 			break;
 
 	dev_dbg(dev, "%s(%p): found #%d\n", __func__, dev, i);
@@ -222,46 +280,8 @@ static int sh_csi2_client_connect(struct
 	if (i == pdata->num_clients)
 		return -ENODEV;
 
-	/* Check if we can support this camera */
-	csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_1_LANE;
-
-	switch (pdata->type) {
-	case SH_CSI2C:
-		if (pdata->clients[i].lanes != 1)
-			csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
-		break;
-	case SH_CSI2I:
-		switch (pdata->clients[i].lanes) {
-		default:
-			csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
-		case 3:
-			csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
-		case 2:
-			csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
-		}
-	}
-
-	cfg.type = V4L2_MBUS_CSI2;
-	ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &cfg);
-	if (ret == -ENOIOCTLCMD)
-		common_flags = csi2_flags;
-	else if (!ret)
-		common_flags = soc_mbus_config_compatible(&cfg,
-							  csi2_flags);
-	else
-		common_flags = 0;
-
-	if (!common_flags)
-		return -EINVAL;
-
-	/* All good: camera MIPI configuration supported */
-	priv->mipi_flags = common_flags;
 	priv->client = pdata->clients + i;
 
-	pm_runtime_get_sync(dev);
-
-	sh_csi2_hwinit(priv);
-
 	return 0;
 }
 
@@ -304,11 +324,18 @@ static int sh_csi2_probe(struct platform
 	/* Platform data specify the PHY, lanes, ECC, CRC */
 	struct sh_csi2_pdata *pdata = pdev->dev.platform_data;
 
+	if (!pdata)
+		return -EINVAL;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_csi2), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	/* Interrupt unused so far */
 	irq = platform_get_irq(pdev, 0);
 
-	if (!res || (int)irq <= 0 || !pdata) {
+	if (!res || (int)irq <= 0) {
 		dev_err(&pdev->dev, "Not enough CSI2 platform resources.\n");
 		return -ENODEV;
 	}
@@ -319,10 +346,6 @@ static int sh_csi2_probe(struct platform
 		return -EINVAL;
 	}
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_csi2), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
 	priv->irq = irq;
 
 	priv->base = devm_ioremap_resource(&pdev->dev, res);
@@ -330,37 +353,35 @@ static int sh_csi2_probe(struct platform
 		return PTR_ERR(priv->base);
 
 	priv->pdev = pdev;
-	platform_set_drvdata(pdev, priv);
+	priv->subdev.owner = THIS_MODULE;
+	priv->subdev.dev = &pdev->dev;
+	platform_set_drvdata(pdev, &priv->subdev);
 
 	v4l2_subdev_init(&priv->subdev, &sh_csi2_subdev_ops);
 	v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
 
 	snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.mipi-csi",
-		 dev_name(pdata->v4l2_dev->dev));
-	ret = v4l2_device_register_subdev(pdata->v4l2_dev, &priv->subdev);
-	dev_dbg(&pdev->dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret);
+		 dev_name(&pdev->dev));
+
+	ret = v4l2_async_register_subdev(&priv->subdev);
 	if (ret < 0)
-		goto esdreg;
+		return ret;
 
 	pm_runtime_enable(&pdev->dev);
 
 	dev_dbg(&pdev->dev, "CSI2 probed.\n");
 
 	return 0;
-
-esdreg:
-	platform_set_drvdata(pdev, NULL);
-
-	return ret;
 }
 
 static int sh_csi2_remove(struct platform_device *pdev)
 {
-	struct sh_csi2 *priv = platform_get_drvdata(pdev);
+	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
+	struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev);
 
-	v4l2_device_unregister_subdev(&priv->subdev);
+	v4l2_async_unregister_subdev(&priv->subdev);
+	v4l2_device_unregister_subdev(subdev);
 	pm_runtime_disable(&pdev->dev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/soc_camera.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/soc_camera.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/soc_camera.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/soc_camera.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,21 +21,23 @@
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/mutex.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
-#include <linux/pm_runtime.h>
 #include <linux/vmalloc.h>
 
 #include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-dev.h>
 #include <media/videobuf-core.h>
 #include <media/videobuf2-core.h>
-#include <media/soc_mediabus.h>
 
 /* Default to VGA resolution */
 #define DEFAULT_WIDTH	640
@@ -46,17 +48,39 @@
 	 (icd)->vb_vidq.streaming :			\
 	 vb2_is_streaming(&(icd)->vb2_vidq))
 
+#define MAP_MAX_NUM 32
+static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
 static LIST_HEAD(hosts);
 static LIST_HEAD(devices);
-static DEFINE_MUTEX(list_lock);		/* Protects the list of hosts */
+/*
+ * Protects lists and bitmaps of hosts and devices.
+ * Lock nesting: Ok to take ->host_lock under list_lock.
+ */
+static DEFINE_MUTEX(list_lock);
 
-int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd)
+struct soc_camera_async_client {
+	struct v4l2_async_subdev *sensor;
+	struct v4l2_async_notifier notifier;
+	struct platform_device *pdev;
+	struct list_head list;		/* needed for clean up */
+};
+
+static int soc_camera_video_start(struct soc_camera_device *icd);
+static int video_dev_create(struct soc_camera_device *icd);
+
+int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+			struct v4l2_clk *clk)
 {
-	int ret = regulator_bulk_enable(ssdd->num_regulators,
+	int ret = clk ? v4l2_clk_enable(clk) : 0;
+	if (ret < 0) {
+		dev_err(dev, "Cannot enable clock: %d\n", ret);
+		return ret;
+	}
+	ret = regulator_bulk_enable(ssdd->num_regulators,
 					ssdd->regulators);
 	if (ret < 0) {
 		dev_err(dev, "Cannot enable regulators\n");
-		return ret;
+		goto eregenable;
 	}
 
 	if (ssdd->power) {
@@ -64,16 +88,25 @@ int soc_camera_power_on(struct device *d
 		if (ret < 0) {
 			dev_err(dev,
 				"Platform failed to power-on the camera.\n");
-			regulator_bulk_disable(ssdd->num_regulators,
-					       ssdd->regulators);
+			goto epwron;
 		}
 	}
 
+	return 0;
+
+epwron:
+	regulator_bulk_disable(ssdd->num_regulators,
+			       ssdd->regulators);
+eregenable:
+	if (clk)
+		v4l2_clk_disable(clk);
+
 	return ret;
 }
 EXPORT_SYMBOL(soc_camera_power_on);
 
-int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd)
+int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+			 struct v4l2_clk *clk)
 {
 	int ret = 0;
 	int err;
@@ -94,10 +127,21 @@ int soc_camera_power_off(struct device *
 		ret = ret ? : err;
 	}
 
+	if (clk)
+		v4l2_clk_disable(clk);
+
 	return ret;
 }
 EXPORT_SYMBOL(soc_camera_power_off);
 
+int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd)
+{
+
+	return devm_regulator_bulk_get(dev, ssdd->num_regulators,
+				       ssdd->regulators);
+}
+EXPORT_SYMBOL(soc_camera_power_init);
+
 static int __soc_camera_power_on(struct soc_camera_device *icd)
 {
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -235,7 +279,6 @@ static int soc_camera_enum_input(struct
 
 	/* default is camera */
 	inp->type = V4L2_INPUT_TYPE_CAMERA;
-	inp->std  = V4L2_STD_UNKNOWN;
 	strcpy(inp->name, "Camera");
 
 	return 0;
@@ -505,6 +548,58 @@ static int soc_camera_set_fmt(struct soc
 	return ici->ops->set_bus_param(icd);
 }
 
+static int soc_camera_add_device(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	int ret;
+
+	if (ici->icd)
+		return -EBUSY;
+
+	if (!icd->clk) {
+		mutex_lock(&ici->clk_lock);
+		ret = ici->ops->clock_start(ici);
+		mutex_unlock(&ici->clk_lock);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (ici->ops->add) {
+		ret = ici->ops->add(icd);
+		if (ret < 0)
+			goto eadd;
+	}
+
+	ici->icd = icd;
+
+	return 0;
+
+eadd:
+	if (!icd->clk) {
+		mutex_lock(&ici->clk_lock);
+		ici->ops->clock_stop(ici);
+		mutex_unlock(&ici->clk_lock);
+	}
+	return ret;
+}
+
+static void soc_camera_remove_device(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+	if (WARN_ON(icd != ici->icd))
+		return;
+
+	if (ici->ops->remove)
+		ici->ops->remove(icd);
+	if (!icd->clk) {
+		mutex_lock(&ici->clk_lock);
+		ici->ops->clock_stop(ici);
+		mutex_unlock(&ici->clk_lock);
+	}
+	ici->icd = NULL;
+}
+
 static int soc_camera_open(struct file *file)
 {
 	struct video_device *vdev = video_devdata(file);
@@ -525,7 +620,7 @@ static int soc_camera_open(struct file *
 		return -ENODEV;
 	}
 
-	icd = dev_get_drvdata(vdev->parent);
+	icd = video_get_drvdata(vdev);
 	ici = to_soc_camera_host(icd->parent);
 
 	ret = try_module_get(ici->ops->owner) ? 0 : -ENODEV;
@@ -568,7 +663,7 @@ static int soc_camera_open(struct file *
 		if (sdesc->subdev_desc.reset)
 			sdesc->subdev_desc.reset(icd->pdev);
 
-		ret = ici->ops->add(icd);
+		ret = soc_camera_add_device(icd);
 		if (ret < 0) {
 			dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret);
 			goto eiciadd;
@@ -610,8 +705,8 @@ static int soc_camera_open(struct file *
 	return 0;
 
 	/*
-	 * First four errors are entered with the .host_lock held
-	 * and use_count == 1
+	 * All errors are entered with the .host_lock held, first four also
+	 * with use_count == 1
 	 */
 einitvb:
 esfmt:
@@ -619,7 +714,7 @@ esfmt:
 eresume:
 	__soc_camera_power_off(icd);
 epower:
-	ici->ops->remove(icd);
+	soc_camera_remove_device(icd);
 eiciadd:
 	icd->use_count--;
 	mutex_unlock(&ici->host_lock);
@@ -645,7 +740,7 @@ static int soc_camera_close(struct file
 			vb2_queue_release(&icd->vb2_vidq);
 		__soc_camera_power_off(icd);
 
-		ici->ops->remove(icd);
+		soc_camera_remove_device(icd);
 	}
 
 	if (icd->streamer == file)
@@ -1036,76 +1131,225 @@ static int soc_camera_s_parm(struct file
 	return -ENOIOCTLCMD;
 }
 
-static int soc_camera_g_chip_ident(struct file *file, void *fh,
-				   struct v4l2_dbg_chip_ident *id)
+static int soc_camera_probe(struct soc_camera_host *ici,
+			    struct soc_camera_device *icd);
+
+/* So far this function cannot fail */
+static void scan_add_host(struct soc_camera_host *ici)
 {
-	struct soc_camera_device *icd = file->private_data;
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct soc_camera_device *icd;
 
-	return v4l2_subdev_call(sd, core, g_chip_ident, id);
+	mutex_lock(&list_lock);
+
+	list_for_each_entry(icd, &devices, list)
+		if (icd->iface == ici->nr) {
+			struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
+			struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc;
+
+			/* The camera could have been already on, try to reset */
+			if (ssdd->reset)
+				ssdd->reset(icd->pdev);
+
+			icd->parent = ici->v4l2_dev.dev;
+
+			/* Ignore errors */
+			soc_camera_probe(ici, icd);
+		}
+
+	mutex_unlock(&list_lock);
 }
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int soc_camera_g_register(struct file *file, void *fh,
-				 struct v4l2_dbg_register *reg)
+/*
+ * It is invalid to call v4l2_clk_enable() after a successful probing
+ * asynchronously outside of V4L2 operations, i.e. with .host_lock not held.
+ */
+static int soc_camera_clk_enable(struct v4l2_clk *clk)
 {
-	struct soc_camera_device *icd = file->private_data;
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct soc_camera_device *icd = clk->priv;
+	struct soc_camera_host *ici;
+	int ret;
 
-	return v4l2_subdev_call(sd, core, g_register, reg);
+	if (!icd || !icd->parent)
+		return -ENODEV;
+
+	ici = to_soc_camera_host(icd->parent);
+
+	if (!try_module_get(ici->ops->owner))
+		return -ENODEV;
+
+	/*
+	 * If a different client is currently being probed, the host will tell
+	 * you to go
+	 */
+	mutex_lock(&ici->clk_lock);
+	ret = ici->ops->clock_start(ici);
+	mutex_unlock(&ici->clk_lock);
+	return ret;
 }
 
-static int soc_camera_s_register(struct file *file, void *fh,
-				 const struct v4l2_dbg_register *reg)
+static void soc_camera_clk_disable(struct v4l2_clk *clk)
 {
-	struct soc_camera_device *icd = file->private_data;
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct soc_camera_device *icd = clk->priv;
+	struct soc_camera_host *ici;
 
-	return v4l2_subdev_call(sd, core, s_register, reg);
+	if (!icd || !icd->parent)
+		return;
+
+	ici = to_soc_camera_host(icd->parent);
+
+	mutex_lock(&ici->clk_lock);
+	ici->ops->clock_stop(ici);
+	mutex_unlock(&ici->clk_lock);
+
+	module_put(ici->ops->owner);
 }
-#endif
 
-static int soc_camera_probe(struct soc_camera_device *icd);
+/*
+ * Eventually, it would be more logical to make the respective host the clock
+ * owner, but then we would have to copy this struct for each ici. Besides, it
+ * would introduce the circular dependency problem, unless we port all client
+ * drivers to release the clock, when not in use.
+ */
+static const struct v4l2_clk_ops soc_camera_clk_ops = {
+	.owner = THIS_MODULE,
+	.enable = soc_camera_clk_enable,
+	.disable = soc_camera_clk_disable,
+};
 
-/* So far this function cannot fail */
-static void scan_add_host(struct soc_camera_host *ici)
+static int soc_camera_dyn_pdev(struct soc_camera_desc *sdesc,
+			       struct soc_camera_async_client *sasc)
 {
-	struct soc_camera_device *icd;
+	struct platform_device *pdev;
+	int ret, i;
 
 	mutex_lock(&list_lock);
+	i = find_first_zero_bit(device_map, MAP_MAX_NUM);
+	if (i < MAP_MAX_NUM)
+		set_bit(i, device_map);
+	mutex_unlock(&list_lock);
+	if (i >= MAP_MAX_NUM)
+		return -ENOMEM;
 
-	list_for_each_entry(icd, &devices, list) {
-		if (icd->iface == ici->nr) {
-			icd->parent = ici->v4l2_dev.dev;
-			soc_camera_probe(icd);
-		}
+	pdev = platform_device_alloc("soc-camera-pdrv", i);
+	if (!pdev)
+		return -ENOMEM;
+
+	ret = platform_device_add_data(pdev, sdesc, sizeof(*sdesc));
+	if (ret < 0) {
+		platform_device_put(pdev);
+		return ret;
 	}
 
-	mutex_unlock(&list_lock);
+	sasc->pdev = pdev;
+
+	return 0;
+}
+
+static struct soc_camera_device *soc_camera_add_pdev(struct soc_camera_async_client *sasc)
+{
+	struct platform_device *pdev = sasc->pdev;
+	int ret;
+
+	ret = platform_device_add(pdev);
+	if (ret < 0 || !pdev->dev.driver)
+		return NULL;
+
+	return platform_get_drvdata(pdev);
+}
+
+/* Locking: called with .host_lock held */
+static int soc_camera_probe_finish(struct soc_camera_device *icd)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct v4l2_mbus_framefmt mf;
+	int ret;
+
+	sd->grp_id = soc_camera_grp_id(icd);
+	v4l2_set_subdev_hostdata(sd, icd);
+
+	ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL);
+	if (ret < 0)
+		return ret;
+
+	ret = soc_camera_add_device(icd);
+	if (ret < 0) {
+		dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret);
+		return ret;
+	}
+
+	/* At this point client .probe() should have run already */
+	ret = soc_camera_init_user_formats(icd);
+	if (ret < 0)
+		goto eusrfmt;
+
+	icd->field = V4L2_FIELD_ANY;
+
+	ret = soc_camera_video_start(icd);
+	if (ret < 0)
+		goto evidstart;
+
+	/* Try to improve our guess of a reasonable window format */
+	if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
+		icd->user_width		= mf.width;
+		icd->user_height	= mf.height;
+		icd->colorspace		= mf.colorspace;
+		icd->field		= mf.field;
+	}
+	soc_camera_remove_device(icd);
+
+	return 0;
+
+evidstart:
+	soc_camera_free_user_formats(icd);
+eusrfmt:
+	soc_camera_remove_device(icd);
+
+	return ret;
 }
 
 #ifdef CONFIG_I2C_BOARDINFO
-static int soc_camera_init_i2c(struct soc_camera_device *icd,
+static int soc_camera_i2c_init(struct soc_camera_device *icd,
 			       struct soc_camera_desc *sdesc)
 {
 	struct i2c_client *client;
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct soc_camera_host *ici;
 	struct soc_camera_host_desc *shd = &sdesc->host_desc;
-	struct i2c_adapter *adap = i2c_get_adapter(shd->i2c_adapter_id);
+	struct i2c_adapter *adap;
 	struct v4l2_subdev *subdev;
+	char clk_name[V4L2_SUBDEV_NAME_SIZE];
+	int ret;
+
+	/* First find out how we link the main client */
+	if (icd->sasc) {
+		/* Async non-OF probing handled by the subdevice list */
+		return -EPROBE_DEFER;
+	}
 
+	ici = to_soc_camera_host(icd->parent);
+	adap = i2c_get_adapter(shd->i2c_adapter_id);
 	if (!adap) {
 		dev_err(icd->pdev, "Cannot get I2C adapter #%d. No driver?\n",
 			shd->i2c_adapter_id);
-		goto ei2cga;
+		return -ENODEV;
 	}
 
 	shd->board_info->platform_data = &sdesc->subdev_desc;
 
+	snprintf(clk_name, sizeof(clk_name), "%d-%04x",
+		 shd->i2c_adapter_id, shd->board_info->addr);
+
+	icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd);
+	if (IS_ERR(icd->clk)) {
+		ret = PTR_ERR(icd->clk);
+		goto eclkreg;
+	}
+
 	subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
 				shd->board_info, NULL);
-	if (!subdev)
+	if (!subdev) {
+		ret = -ENODEV;
 		goto ei2cnd;
+	}
 
 	client = v4l2_get_subdevdata(subdev);
 
@@ -1114,39 +1358,203 @@ static int soc_camera_init_i2c(struct so
 
 	return 0;
 ei2cnd:
+	v4l2_clk_unregister(icd->clk);
+eclkreg:
+	icd->clk = NULL;
 	i2c_put_adapter(adap);
-ei2cga:
-	return -ENODEV;
+	return ret;
 }
 
-static void soc_camera_free_i2c(struct soc_camera_device *icd)
+static void soc_camera_i2c_free(struct soc_camera_device *icd)
 {
 	struct i2c_client *client =
 		to_i2c_client(to_soc_camera_control(icd));
-	struct i2c_adapter *adap = client->adapter;
+	struct i2c_adapter *adap;
 
 	icd->control = NULL;
+	if (icd->sasc)
+		return;
+
+	adap = client->adapter;
 	v4l2_device_unregister_subdev(i2c_get_clientdata(client));
 	i2c_unregister_device(client);
 	i2c_put_adapter(adap);
+	v4l2_clk_unregister(icd->clk);
+	icd->clk = NULL;
+}
+
+/*
+ * V4L2 asynchronous notifier callbacks. They are all called under a v4l2-async
+ * internal global mutex, therefore cannot race against other asynchronous
+ * events. Until notifier->complete() (soc_camera_async_complete()) is called,
+ * the video device node is not registered and no V4L fops can occur. Unloading
+ * of the host driver also calls a v4l2-async function, so also there we're
+ * protected.
+ */
+static int soc_camera_async_bound(struct v4l2_async_notifier *notifier,
+				  struct v4l2_subdev *sd,
+				  struct v4l2_async_subdev *asd)
+{
+	struct soc_camera_async_client *sasc = container_of(notifier,
+					struct soc_camera_async_client, notifier);
+	struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
+
+	if (asd == sasc->sensor && !WARN_ON(icd->control)) {
+		struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+		/*
+		 * Only now we get subdevice-specific information like
+		 * regulators, flags, callbacks, etc.
+		 */
+		if (client) {
+			struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
+			struct soc_camera_subdev_desc *ssdd =
+				soc_camera_i2c_to_desc(client);
+			if (ssdd) {
+				memcpy(&sdesc->subdev_desc, ssdd,
+				       sizeof(sdesc->subdev_desc));
+				if (ssdd->reset)
+					ssdd->reset(icd->pdev);
+			}
+
+			icd->control = &client->dev;
+		}
+	}
+
+	return 0;
+}
+
+static void soc_camera_async_unbind(struct v4l2_async_notifier *notifier,
+				    struct v4l2_subdev *sd,
+				    struct v4l2_async_subdev *asd)
+{
+	struct soc_camera_async_client *sasc = container_of(notifier,
+					struct soc_camera_async_client, notifier);
+	struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
+
+	if (icd->clk) {
+		v4l2_clk_unregister(icd->clk);
+		icd->clk = NULL;
+	}
+}
+
+static int soc_camera_async_complete(struct v4l2_async_notifier *notifier)
+{
+	struct soc_camera_async_client *sasc = container_of(notifier,
+					struct soc_camera_async_client, notifier);
+	struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
+
+	if (to_soc_camera_control(icd)) {
+		struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+		int ret;
+
+		mutex_lock(&list_lock);
+		ret = soc_camera_probe(ici, icd);
+		mutex_unlock(&list_lock);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int scan_async_group(struct soc_camera_host *ici,
+			    struct v4l2_async_subdev **asd, unsigned int size)
+{
+	struct soc_camera_async_subdev *sasd;
+	struct soc_camera_async_client *sasc;
+	struct soc_camera_device *icd;
+	struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,};
+	char clk_name[V4L2_SUBDEV_NAME_SIZE];
+	int ret, i;
+
+	/* First look for a sensor */
+	for (i = 0; i < size; i++) {
+		sasd = container_of(asd[i], struct soc_camera_async_subdev, asd);
+		if (sasd->role == SOCAM_SUBDEV_DATA_SOURCE)
+			break;
+	}
+
+	if (i == size || asd[i]->bus_type != V4L2_ASYNC_BUS_I2C) {
+		/* All useless */
+		dev_err(ici->v4l2_dev.dev, "No I2C data source found!\n");
+		return -ENODEV;
+	}
+
+	/* Or shall this be managed by the soc-camera device? */
+	sasc = devm_kzalloc(ici->v4l2_dev.dev, sizeof(*sasc), GFP_KERNEL);
+	if (!sasc)
+		return -ENOMEM;
+
+	/* HACK: just need a != NULL */
+	sdesc.host_desc.board_info = ERR_PTR(-ENODATA);
+
+	ret = soc_camera_dyn_pdev(&sdesc, sasc);
+	if (ret < 0)
+		return ret;
+
+	sasc->sensor = &sasd->asd;
+
+	icd = soc_camera_add_pdev(sasc);
+	if (!icd) {
+		platform_device_put(sasc->pdev);
+		return -ENOMEM;
+	}
+
+	sasc->notifier.subdev = asd;
+	sasc->notifier.num_subdevs = size;
+	sasc->notifier.bound = soc_camera_async_bound;
+	sasc->notifier.unbind = soc_camera_async_unbind;
+	sasc->notifier.complete = soc_camera_async_complete;
+
+	icd->sasc = sasc;
+	icd->parent = ici->v4l2_dev.dev;
+
+	snprintf(clk_name, sizeof(clk_name), "%d-%04x",
+		 sasd->asd.match.i2c.adapter_id, sasd->asd.match.i2c.address);
+
+	icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd);
+	if (IS_ERR(icd->clk)) {
+		ret = PTR_ERR(icd->clk);
+		goto eclkreg;
+	}
+
+	ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier);
+	if (!ret)
+		return 0;
+
+	v4l2_clk_unregister(icd->clk);
+eclkreg:
+	icd->clk = NULL;
+	platform_device_unregister(sasc->pdev);
+	dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret);
+
+	return ret;
+}
+
+static void scan_async_host(struct soc_camera_host *ici)
+{
+	struct v4l2_async_subdev **asd;
+	int j;
+
+	for (j = 0, asd = ici->asd; ici->asd_sizes[j]; j++) {
+		scan_async_group(ici, asd, ici->asd_sizes[j]);
+		asd += ici->asd_sizes[j];
+	}
 }
 #else
-#define soc_camera_init_i2c(icd, sdesc)	(-ENODEV)
-#define soc_camera_free_i2c(icd)	do {} while (0)
+#define soc_camera_i2c_init(icd, sdesc)	(-ENODEV)
+#define soc_camera_i2c_free(icd)	do {} while (0)
+#define scan_async_host(ici)		do {} while (0)
 #endif
 
-static int soc_camera_video_start(struct soc_camera_device *icd);
-static int video_dev_create(struct soc_camera_device *icd);
 /* Called during host-driver probe */
-static int soc_camera_probe(struct soc_camera_device *icd)
+static int soc_camera_probe(struct soc_camera_host *ici,
+			    struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
 	struct soc_camera_host_desc *shd = &sdesc->host_desc;
-	struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc;
 	struct device *control = NULL;
-	struct v4l2_subdev *sd;
-	struct v4l2_mbus_framefmt mf;
 	int ret;
 
 	dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev));
@@ -1162,30 +1570,32 @@ static int soc_camera_probe(struct soc_c
 	if (ret < 0)
 		return ret;
 
-	/* The camera could have been already on, try to reset */
-	if (ssdd->reset)
-		ssdd->reset(icd->pdev);
-
-	mutex_lock(&ici->host_lock);
-	ret = ici->ops->add(icd);
-	mutex_unlock(&ici->host_lock);
-	if (ret < 0)
-		goto eadd;
-
 	/* Must have icd->vdev before registering the device */
 	ret = video_dev_create(icd);
 	if (ret < 0)
 		goto evdc;
 
+	/*
+	 * ..._video_start() will create a device node, video_register_device()
+	 * itself is protected against concurrent open() calls, but we also have
+	 * to protect our data also during client probing.
+	 */
+
 	/* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
 	if (shd->board_info) {
-		ret = soc_camera_init_i2c(icd, sdesc);
-		if (ret < 0)
-			goto eadddev;
+		ret = soc_camera_i2c_init(icd, sdesc);
+		if (ret < 0 && ret != -EPROBE_DEFER)
+			goto eadd;
 	} else if (!shd->add_device || !shd->del_device) {
 		ret = -EINVAL;
-		goto eadddev;
+		goto eadd;
 	} else {
+		mutex_lock(&ici->clk_lock);
+		ret = ici->ops->clock_start(ici);
+		mutex_unlock(&ici->clk_lock);
+		if (ret < 0)
+			goto eadd;
+
 		if (shd->module_name)
 			ret = request_module(shd->module_name);
 
@@ -1206,81 +1616,49 @@ static int soc_camera_probe(struct soc_c
 		}
 	}
 
-	sd = soc_camera_to_subdev(icd);
-	sd->grp_id = soc_camera_grp_id(icd);
-	v4l2_set_subdev_hostdata(sd, icd);
-
-	ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL);
-	if (ret < 0)
-		goto ectrl;
-
-	/* At this point client .probe() should have run already */
-	ret = soc_camera_init_user_formats(icd);
-	if (ret < 0)
-		goto eiufmt;
-
-	icd->field = V4L2_FIELD_ANY;
-
-	/*
-	 * ..._video_start() will create a device node, video_register_device()
-	 * itself is protected against concurrent open() calls, but we also have
-	 * to protect our data.
-	 */
 	mutex_lock(&ici->host_lock);
-
-	ret = soc_camera_video_start(icd);
-	if (ret < 0)
-		goto evidstart;
-
-	/* Try to improve our guess of a reasonable window format */
-	if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
-		icd->user_width		= mf.width;
-		icd->user_height	= mf.height;
-		icd->colorspace		= mf.colorspace;
-		icd->field		= mf.field;
-	}
-
-	ici->ops->remove(icd);
-
+	ret = soc_camera_probe_finish(icd);
 	mutex_unlock(&ici->host_lock);
+	if (ret < 0)
+		goto efinish;
 
 	return 0;
 
-evidstart:
-	mutex_unlock(&ici->host_lock);
-	soc_camera_free_user_formats(icd);
-eiufmt:
-ectrl:
+efinish:
 	if (shd->board_info) {
-		soc_camera_free_i2c(icd);
+		soc_camera_i2c_free(icd);
 	} else {
 		shd->del_device(icd);
 		module_put(control->driver->owner);
-	}
 enodrv:
 eadddev:
+		mutex_lock(&ici->clk_lock);
+		ici->ops->clock_stop(ici);
+		mutex_unlock(&ici->clk_lock);
+	}
+eadd:
 	video_device_release(icd->vdev);
 	icd->vdev = NULL;
+	if (icd->vdev) {
+		video_device_release(icd->vdev);
+		icd->vdev = NULL;
+	}
 evdc:
-	mutex_lock(&ici->host_lock);
-	ici->ops->remove(icd);
-	mutex_unlock(&ici->host_lock);
-eadd:
 	v4l2_ctrl_handler_free(&icd->ctrl_handler);
 	return ret;
 }
 
 /*
  * This is called on device_unregister, which only means we have to disconnect
- * from the host, but not remove ourselves from the device list
+ * from the host, but not remove ourselves from the device list. With
+ * asynchronous client probing this can also be called without
+ * soc_camera_probe_finish() having run. Careful with clean up.
  */
 static int soc_camera_remove(struct soc_camera_device *icd)
 {
 	struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
 	struct video_device *vdev = icd->vdev;
 
-	BUG_ON(!icd->parent);
-
 	v4l2_ctrl_handler_free(&icd->ctrl_handler);
 	if (vdev) {
 		video_unregister_device(vdev);
@@ -1288,15 +1666,27 @@ static int soc_camera_remove(struct soc_
 	}
 
 	if (sdesc->host_desc.board_info) {
-		soc_camera_free_i2c(icd);
+		soc_camera_i2c_free(icd);
 	} else {
-		struct device_driver *drv = to_soc_camera_control(icd)->driver;
+		struct device *dev = to_soc_camera_control(icd);
+		struct device_driver *drv = dev ? dev->driver : NULL;
 		if (drv) {
 			sdesc->host_desc.del_device(icd);
 			module_put(drv->owner);
 		}
 	}
-	soc_camera_free_user_formats(icd);
+
+	if (icd->num_user_formats)
+		soc_camera_free_user_formats(icd);
+
+	if (icd->clk) {
+		/* For the synchronous case */
+		v4l2_clk_unregister(icd->clk);
+		icd->clk = NULL;
+	}
+
+	if (icd->sasc)
+		platform_device_unregister(icd->sasc->pdev);
 
 	return 0;
 }
@@ -1372,8 +1762,8 @@ int soc_camera_host_register(struct soc_
 	    ((!ici->ops->init_videobuf ||
 	      !ici->ops->reqbufs) &&
 	     !ici->ops->init_videobuf2) ||
-	    !ici->ops->add ||
-	    !ici->ops->remove ||
+	    !ici->ops->clock_start ||
+	    !ici->ops->clock_stop ||
 	    !ici->ops->poll ||
 	    !ici->v4l2_dev.dev)
 		return -EINVAL;
@@ -1407,7 +1797,18 @@ int soc_camera_host_register(struct soc_
 	mutex_unlock(&list_lock);
 
 	mutex_init(&ici->host_lock);
-	scan_add_host(ici);
+	mutex_init(&ici->clk_lock);
+
+	if (ici->asd_sizes)
+		/*
+		 * No OF, host with a list of subdevices. Don't try to mix
+		 * modes by initialising some groups statically and some
+		 * dynamically!
+		 */
+		scan_async_host(ici);
+	else
+		/* Legacy: static platform devices from board data */
+		scan_add_host(ici);
 
 	return 0;
 
@@ -1420,13 +1821,30 @@ EXPORT_SYMBOL(soc_camera_host_register);
 /* Unregister all clients! */
 void soc_camera_host_unregister(struct soc_camera_host *ici)
 {
-	struct soc_camera_device *icd;
+	struct soc_camera_device *icd, *tmp;
+	struct soc_camera_async_client *sasc;
+	LIST_HEAD(notifiers);
 
 	mutex_lock(&list_lock);
-
 	list_del(&ici->list);
 	list_for_each_entry(icd, &devices, list)
-		if (icd->iface == ici->nr && to_soc_camera_control(icd))
+		if (icd->iface == ici->nr && icd->sasc) {
+			/* as long as we hold the device, sasc won't be freed */
+			get_device(icd->pdev);
+			list_add(&icd->sasc->list, &notifiers);
+		}
+	mutex_unlock(&list_lock);
+
+	list_for_each_entry(sasc, &notifiers, list) {
+		/* Must call unlocked to avoid AB-BA dead-lock */
+		v4l2_async_notifier_unregister(&sasc->notifier);
+		put_device(&sasc->pdev->dev);
+	}
+
+	mutex_lock(&list_lock);
+
+	list_for_each_entry_safe(icd, tmp, &devices, list)
+		if (icd->iface == ici->nr)
 			soc_camera_remove(icd);
 
 	mutex_unlock(&list_lock);
@@ -1441,6 +1859,7 @@ static int soc_camera_device_register(st
 	struct soc_camera_device *ix;
 	int num = -1, i;
 
+	mutex_lock(&list_lock);
 	for (i = 0; i < 256 && num < 0; i++) {
 		num = i;
 		/* Check if this index is available on this interface */
@@ -1452,18 +1871,34 @@ static int soc_camera_device_register(st
 		}
 	}
 
-	if (num < 0)
+	if (num < 0) {
 		/*
 		 * ok, we have 256 cameras on this host...
 		 * man, stay reasonable...
 		 */
+		mutex_unlock(&list_lock);
 		return -ENOMEM;
+	}
 
 	icd->devnum		= num;
 	icd->use_count		= 0;
 	icd->host_priv		= NULL;
 
+	/*
+	 * Dynamically allocated devices set the bit earlier, but it doesn't hurt setting
+	 * it again
+	 */
+	i = to_platform_device(icd->pdev)->id;
+	if (i < 0)
+		/* One static (legacy) soc-camera platform device */
+		i = 0;
+	if (i >= MAP_MAX_NUM) {
+		mutex_unlock(&list_lock);
+		return -EBUSY;
+	}
+	set_bit(i, device_map);
 	list_add_tail(&icd->list, &devices);
+	mutex_unlock(&list_lock);
 
 	return 0;
 }
@@ -1495,11 +1930,6 @@ static const struct v4l2_ioctl_ops soc_c
 	.vidioc_s_selection	 = soc_camera_s_selection,
 	.vidioc_g_parm		 = soc_camera_g_parm,
 	.vidioc_s_parm		 = soc_camera_s_parm,
-	.vidioc_g_chip_ident     = soc_camera_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register	 = soc_camera_g_register,
-	.vidioc_s_register	 = soc_camera_s_register,
-#endif
 };
 
 static int video_dev_create(struct soc_camera_device *icd)
@@ -1512,12 +1942,10 @@ static int video_dev_create(struct soc_c
 
 	strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
 
-	vdev->parent		= icd->pdev;
-	vdev->current_norm	= V4L2_STD_UNKNOWN;
+	vdev->v4l2_dev		= &ici->v4l2_dev;
 	vdev->fops		= &soc_camera_fops;
 	vdev->ioctl_ops		= &soc_camera_ioctl_ops;
 	vdev->release		= video_device_release;
-	vdev->tvnorms		= V4L2_STD_UNKNOWN;
 	vdev->ctrl_handler	= &icd->ctrl_handler;
 	vdev->lock		= &ici->host_lock;
 
@@ -1537,6 +1965,7 @@ static int soc_camera_video_start(struct
 	if (!icd->parent)
 		return -ENODEV;
 
+	video_set_drvdata(icd->vdev, icd);
 	ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
 		dev_err(icd->pdev, "video_register_device failed: %d\n", ret);
@@ -1563,6 +1992,12 @@ static int soc_camera_pdrv_probe(struct
 	if (!icd)
 		return -ENOMEM;
 
+	/*
+	 * In the asynchronous case ssdd->num_regulators == 0 yet, so, the below
+	 * regulator allocation is a dummy. They will be really requested later
+	 * in soc_camera_async_bind(). Also note, that in that case regulators
+	 * are attached to the I2C device and not to the camera platform device.
+	 */
 	ret = devm_regulator_bulk_get(&pdev->dev, ssdd->num_regulators,
 				      ssdd->regulators);
 	if (ret < 0)
@@ -1587,11 +2022,25 @@ static int soc_camera_pdrv_probe(struct
 static int soc_camera_pdrv_remove(struct platform_device *pdev)
 {
 	struct soc_camera_device *icd = platform_get_drvdata(pdev);
+	int i;
 
 	if (!icd)
 		return -EINVAL;
 
-	list_del(&icd->list);
+	i = pdev->id;
+	if (i < 0)
+		i = 0;
+
+	/*
+	 * In synchronous mode with static platform devices this is called in a
+	 * loop from drivers/base/dd.c::driver_detach(), no parallel execution,
+	 * no need to lock. In asynchronous case the caller -
+	 * soc_camera_host_unregister() - already holds the lock
+	 */
+	if (test_bit(i, device_map)) {
+		clear_bit(i, device_map);
+		list_del(&icd->list);
+	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/soc_camera_platform.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/soc_camera_platform.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/soc_camera_platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/soc_camera_platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ static int soc_camera_platform_s_power(s
 {
 	struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
 
-	return soc_camera_set_power(p->icd->control, &p->icd->sdesc->subdev_desc, on);
+	return soc_camera_set_power(p->icd->control, &p->icd->sdesc->subdev_desc, NULL, on);
 }
 
 static struct v4l2_subdev_core_ops platform_subdev_core_ops = {
@@ -137,7 +137,6 @@ static int soc_camera_platform_probe(str
 	struct soc_camera_platform_priv *priv;
 	struct soc_camera_platform_info *p = pdev->dev.platform_data;
 	struct soc_camera_device *icd;
-	int ret;
 
 	if (!p)
 		return -EINVAL;
@@ -165,15 +164,7 @@ static int soc_camera_platform_probe(str
 	v4l2_set_subdevdata(&priv->subdev, p);
 	strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
 
-	ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
-	if (ret)
-		goto evdrs;
-
-	return ret;
-
-evdrs:
-	platform_set_drvdata(pdev, NULL);
-	return ret;
+	return v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
 }
 
 static int soc_camera_platform_remove(struct platform_device *pdev)
@@ -183,7 +174,6 @@ static int soc_camera_platform_remove(st
 
 	p->icd->control = NULL;
 	v4l2_device_unregister_subdev(&priv->subdev);
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/soc_scale_crop.c linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/soc_scale_crop.c
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/soc_scale_crop.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/soc_scale_crop.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,402 @@
+/*
+ * soc-camera generic scaling-cropping manipulation functions
+ *
+ * Copyright (C) 2013 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include <media/soc_camera.h>
+#include <media/v4l2-common.h>
+
+#include "soc_scale_crop.h"
+
+#ifdef DEBUG_GEOMETRY
+#define dev_geo	dev_info
+#else
+#define dev_geo	dev_dbg
+#endif
+
+/* Check if any dimension of r1 is smaller than respective one of r2 */
+static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
+{
+	return r1->width < r2->width || r1->height < r2->height;
+}
+
+/* Check if r1 fails to cover r2 */
+static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
+{
+	return r1->left > r2->left || r1->top > r2->top ||
+		r1->left + r1->width < r2->left + r2->width ||
+		r1->top + r1->height < r2->top + r2->height;
+}
+
+/* Get and store current client crop */
+int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
+{
+	struct v4l2_crop crop;
+	struct v4l2_cropcap cap;
+	int ret;
+
+	crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, g_crop, &crop);
+	if (!ret) {
+		*rect = crop.c;
+		return ret;
+	}
+
+	/* Camera driver doesn't support .g_crop(), assume default rectangle */
+	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+	if (!ret)
+		*rect = cap.defrect;
+
+	return ret;
+}
+EXPORT_SYMBOL(soc_camera_client_g_rect);
+
+/* Client crop has changed, update our sub-rectangle to remain within the area */
+static void update_subrect(struct v4l2_rect *rect, struct v4l2_rect *subrect)
+{
+	if (rect->width < subrect->width)
+		subrect->width = rect->width;
+
+	if (rect->height < subrect->height)
+		subrect->height = rect->height;
+
+	if (rect->left > subrect->left)
+		subrect->left = rect->left;
+	else if (rect->left + rect->width >
+		 subrect->left + subrect->width)
+		subrect->left = rect->left + rect->width -
+			subrect->width;
+
+	if (rect->top > subrect->top)
+		subrect->top = rect->top;
+	else if (rect->top + rect->height >
+		 subrect->top + subrect->height)
+		subrect->top = rect->top + rect->height -
+			subrect->height;
+}
+
+/*
+ * The common for both scaling and cropping iterative approach is:
+ * 1. try if the client can produce exactly what requested by the user
+ * 2. if (1) failed, try to double the client image until we get one big enough
+ * 3. if (2) failed, try to request the maximum image
+ */
+int soc_camera_client_s_crop(struct v4l2_subdev *sd,
+			struct v4l2_crop *crop, struct v4l2_crop *cam_crop,
+			struct v4l2_rect *target_rect, struct v4l2_rect *subrect)
+{
+	struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
+	struct device *dev = sd->v4l2_dev->dev;
+	struct v4l2_cropcap cap;
+	int ret;
+	unsigned int width, height;
+
+	v4l2_subdev_call(sd, video, s_crop, crop);
+	ret = soc_camera_client_g_rect(sd, cam_rect);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Now cam_crop contains the current camera input rectangle, and it must
+	 * be within camera cropcap bounds
+	 */
+	if (!memcmp(rect, cam_rect, sizeof(*rect))) {
+		/* Even if camera S_CROP failed, but camera rectangle matches */
+		dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
+			rect->width, rect->height, rect->left, rect->top);
+		*target_rect = *cam_rect;
+		return 0;
+	}
+
+	/* Try to fix cropping, that camera hasn't managed to set */
+	dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
+		cam_rect->width, cam_rect->height,
+		cam_rect->left, cam_rect->top,
+		rect->width, rect->height, rect->left, rect->top);
+
+	/* We need sensor maximum rectangle */
+	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+	if (ret < 0)
+		return ret;
+
+	/* Put user requested rectangle within sensor bounds */
+	soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
+			      cap.bounds.width);
+	soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
+			      cap.bounds.height);
+
+	/*
+	 * Popular special case - some cameras can only handle fixed sizes like
+	 * QVGA, VGA,... Take care to avoid infinite loop.
+	 */
+	width = max(cam_rect->width, 2);
+	height = max(cam_rect->height, 2);
+
+	/*
+	 * Loop as long as sensor is not covering the requested rectangle and
+	 * is still within its bounds
+	 */
+	while (!ret && (is_smaller(cam_rect, rect) ||
+			is_inside(cam_rect, rect)) &&
+	       (cap.bounds.width > width || cap.bounds.height > height)) {
+
+		width *= 2;
+		height *= 2;
+
+		cam_rect->width = width;
+		cam_rect->height = height;
+
+		/*
+		 * We do not know what capabilities the camera has to set up
+		 * left and top borders. We could try to be smarter in iterating
+		 * them, e.g., if camera current left is to the right of the
+		 * target left, set it to the middle point between the current
+		 * left and minimum left. But that would add too much
+		 * complexity: we would have to iterate each border separately.
+		 * Instead we just drop to the left and top bounds.
+		 */
+		if (cam_rect->left > rect->left)
+			cam_rect->left = cap.bounds.left;
+
+		if (cam_rect->left + cam_rect->width < rect->left + rect->width)
+			cam_rect->width = rect->left + rect->width -
+				cam_rect->left;
+
+		if (cam_rect->top > rect->top)
+			cam_rect->top = cap.bounds.top;
+
+		if (cam_rect->top + cam_rect->height < rect->top + rect->height)
+			cam_rect->height = rect->top + rect->height -
+				cam_rect->top;
+
+		v4l2_subdev_call(sd, video, s_crop, cam_crop);
+		ret = soc_camera_client_g_rect(sd, cam_rect);
+		dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
+			cam_rect->width, cam_rect->height,
+			cam_rect->left, cam_rect->top);
+	}
+
+	/* S_CROP must not modify the rectangle */
+	if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
+		/*
+		 * The camera failed to configure a suitable cropping,
+		 * we cannot use the current rectangle, set to max
+		 */
+		*cam_rect = cap.bounds;
+		v4l2_subdev_call(sd, video, s_crop, cam_crop);
+		ret = soc_camera_client_g_rect(sd, cam_rect);
+		dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
+			cam_rect->width, cam_rect->height,
+			cam_rect->left, cam_rect->top);
+	}
+
+	if (!ret) {
+		*target_rect = *cam_rect;
+		update_subrect(target_rect, subrect);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(soc_camera_client_s_crop);
+
+/* Iterative s_mbus_fmt, also updates cached client crop on success */
+static int client_s_fmt(struct soc_camera_device *icd,
+			struct v4l2_rect *rect, struct v4l2_rect *subrect,
+			unsigned int max_width, unsigned int max_height,
+			struct v4l2_mbus_framefmt *mf, bool host_can_scale)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct device *dev = icd->parent;
+	unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
+	struct v4l2_cropcap cap;
+	bool host_1to1;
+	int ret;
+
+	ret = v4l2_device_call_until_err(sd->v4l2_dev,
+					 soc_camera_grp_id(icd), video,
+					 s_mbus_fmt, mf);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
+
+	if (width == mf->width && height == mf->height) {
+		/* Perfect! The client has done it all. */
+		host_1to1 = true;
+		goto update_cache;
+	}
+
+	host_1to1 = false;
+	if (!host_can_scale)
+		goto update_cache;
+
+	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+	if (ret < 0)
+		return ret;
+
+	if (max_width > cap.bounds.width)
+		max_width = cap.bounds.width;
+	if (max_height > cap.bounds.height)
+		max_height = cap.bounds.height;
+
+	/* Camera set a format, but geometry is not precise, try to improve */
+	tmp_w = mf->width;
+	tmp_h = mf->height;
+
+	/* width <= max_width && height <= max_height - guaranteed by try_fmt */
+	while ((width > tmp_w || height > tmp_h) &&
+	       tmp_w < max_width && tmp_h < max_height) {
+		tmp_w = min(2 * tmp_w, max_width);
+		tmp_h = min(2 * tmp_h, max_height);
+		mf->width = tmp_w;
+		mf->height = tmp_h;
+		ret = v4l2_device_call_until_err(sd->v4l2_dev,
+					soc_camera_grp_id(icd), video,
+					s_mbus_fmt, mf);
+		dev_geo(dev, "Camera scaled to %ux%u\n",
+			mf->width, mf->height);
+		if (ret < 0) {
+			/* This shouldn't happen */
+			dev_err(dev, "Client failed to set format: %d\n", ret);
+			return ret;
+		}
+	}
+
+update_cache:
+	/* Update cache */
+	ret = soc_camera_client_g_rect(sd, rect);
+	if (ret < 0)
+		return ret;
+
+	if (host_1to1)
+		*subrect = *rect;
+	else
+		update_subrect(rect, subrect);
+
+	return 0;
+}
+
+/**
+ * @icd		- soc-camera device
+ * @rect	- camera cropping window
+ * @subrect	- part of rect, sent to the user
+ * @mf		- in- / output camera output window
+ * @width	- on input: max host input width
+ *		  on output: user width, mapped back to input
+ * @height	- on input: max host input height
+ *		  on output: user height, mapped back to input
+ * @host_can_scale - host can scale this pixel format
+ * @shift	- shift, used for scaling
+ */
+int soc_camera_client_scale(struct soc_camera_device *icd,
+			struct v4l2_rect *rect, struct v4l2_rect *subrect,
+			struct v4l2_mbus_framefmt *mf,
+			unsigned int *width, unsigned int *height,
+			bool host_can_scale, unsigned int shift)
+{
+	struct device *dev = icd->parent;
+	struct v4l2_mbus_framefmt mf_tmp = *mf;
+	unsigned int scale_h, scale_v;
+	int ret;
+
+	/*
+	 * 5. Apply iterative camera S_FMT for camera user window (also updates
+	 *    client crop cache and the imaginary sub-rectangle).
+	 */
+	ret = client_s_fmt(icd, rect, subrect, *width, *height,
+			   &mf_tmp, host_can_scale);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "5: camera scaled to %ux%u\n",
+		mf_tmp.width, mf_tmp.height);
+
+	/* 6. Retrieve camera output window (g_fmt) */
+
+	/* unneeded - it is already in "mf_tmp" */
+
+	/* 7. Calculate new client scales. */
+	scale_h = soc_camera_calc_scale(rect->width, shift, mf_tmp.width);
+	scale_v = soc_camera_calc_scale(rect->height, shift, mf_tmp.height);
+
+	mf->width	= mf_tmp.width;
+	mf->height	= mf_tmp.height;
+	mf->colorspace	= mf_tmp.colorspace;
+
+	/*
+	 * 8. Calculate new host crop - apply camera scales to previously
+	 *    updated "effective" crop.
+	 */
+	*width = soc_camera_shift_scale(subrect->width, shift, scale_h);
+	*height = soc_camera_shift_scale(subrect->height, shift, scale_v);
+
+	dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
+
+	return 0;
+}
+EXPORT_SYMBOL(soc_camera_client_scale);
+
+/*
+ * Calculate real client output window by applying new scales to the current
+ * client crop. New scales are calculated from the requested output format and
+ * host crop, mapped backed onto the client input (subrect).
+ */
+void soc_camera_calc_client_output(struct soc_camera_device *icd,
+		struct v4l2_rect *rect, struct v4l2_rect *subrect,
+		const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf,
+		unsigned int shift)
+{
+	struct device *dev = icd->parent;
+	unsigned int scale_v, scale_h;
+
+	if (subrect->width == rect->width &&
+	    subrect->height == rect->height) {
+		/* No sub-cropping */
+		mf->width	= pix->width;
+		mf->height	= pix->height;
+		return;
+	}
+
+	/* 1.-2. Current camera scales and subwin - cached. */
+
+	dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
+		subrect->width, subrect->height,
+		subrect->left, subrect->top);
+
+	/*
+	 * 3. Calculate new combined scales from input sub-window to requested
+	 *    user window.
+	 */
+
+	/*
+	 * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
+	 * (128x96) or larger than VGA. This and similar limitations have to be
+	 * taken into account here.
+	 */
+	scale_h = soc_camera_calc_scale(subrect->width, shift, pix->width);
+	scale_v = soc_camera_calc_scale(subrect->height, shift, pix->height);
+
+	dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
+
+	/*
+	 * 4. Calculate desired client output window by applying combined scales
+	 *    to client (real) input window.
+	 */
+	mf->width = soc_camera_shift_scale(rect->width, shift, scale_h);
+	mf->height = soc_camera_shift_scale(rect->height, shift, scale_v);
+}
+EXPORT_SYMBOL(soc_camera_calc_client_output);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/soc_camera/soc_scale_crop.h linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/soc_scale_crop.h
--- linux-libre-3.10-gnu/drivers/media/platform/soc_camera/soc_scale_crop.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/soc_camera/soc_scale_crop.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,47 @@
+/*
+ * soc-camera generic scaling-cropping manipulation functions
+ *
+ * Copyright (C) 2013 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef SOC_SCALE_CROP_H
+#define SOC_SCALE_CROP_H
+
+#include <linux/kernel.h>
+
+struct soc_camera_device;
+
+struct v4l2_crop;
+struct v4l2_mbus_framefmt;
+struct v4l2_pix_format;
+struct v4l2_rect;
+struct v4l2_subdev;
+
+static inline unsigned int soc_camera_shift_scale(unsigned int size,
+				unsigned int shift, unsigned int scale)
+{
+	return DIV_ROUND_CLOSEST(size << shift, scale);
+}
+
+#define soc_camera_calc_scale(in, shift, out) soc_camera_shift_scale(in, shift, out)
+
+int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
+int soc_camera_client_s_crop(struct v4l2_subdev *sd,
+			struct v4l2_crop *crop, struct v4l2_crop *cam_crop,
+			struct v4l2_rect *target_rect, struct v4l2_rect *subrect);
+int soc_camera_client_scale(struct soc_camera_device *icd,
+			struct v4l2_rect *rect, struct v4l2_rect *subrect,
+			struct v4l2_mbus_framefmt *mf,
+			unsigned int *width, unsigned int *height,
+			bool host_can_scale, unsigned int shift);
+void soc_camera_calc_client_output(struct soc_camera_device *icd,
+		struct v4l2_rect *rect, struct v4l2_rect *subrect,
+		const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf,
+		unsigned int shift);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/timblogiw.c linux-libre-3.11-rc7-gnu/drivers/media/platform/timblogiw.c
--- linux-libre-3.10-gnu/drivers/media/platform/timblogiw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/timblogiw.c	2013-08-25 20:43:22.000000000 -0400
@@ -239,13 +239,12 @@ static int timblogiw_querycap(struct fil
 	struct video_device *vdev = video_devdata(file);
 
 	dev_dbg(&vdev->dev, "%s: Entry\n",  __func__);
-	memset(cap, 0, sizeof(*cap));
 	strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1);
 	strncpy(cap->driver, DRIVER_NAME, sizeof(cap->driver) - 1);
-	strlcpy(cap->bus_info, vdev->name, sizeof(cap->bus_info));
-	cap->version = TIMBLOGIW_VERSION_CODE;
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", vdev->name);
+	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
 		V4L2_CAP_READWRITE;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 
 	return 0;
 }
@@ -834,11 +833,9 @@ static int timblogiw_probe(struct platfo
 		goto err_request;
 	}
 
-
 	return 0;
 
 err_request:
-	platform_set_drvdata(pdev, NULL);
 	v4l2_device_unregister(&lw->v4l2_dev);
 err_register:
 	kfree(lw);
@@ -858,8 +855,6 @@ static int timblogiw_remove(struct platf
 
 	kfree(lw);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/via-camera.c linux-libre-3.11-rc7-gnu/drivers/media/platform/via-camera.c
--- linux-libre-3.10-gnu/drivers/media/platform/via-camera.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/via-camera.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/ov7670.h>
 #include <media/videobuf-dma-sg.h>
@@ -805,20 +804,6 @@ static const struct v4l2_file_operations
  * The long list of v4l2 ioctl ops
  */
 
-static int viacam_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *ident)
-{
-	struct via_camera *cam = priv;
-
-	ident->ident = V4L2_IDENT_NONE;
-	ident->revision = 0;
-	if (v4l2_chip_match_host(&ident->match)) {
-		ident->ident = V4L2_IDENT_VIA_VX855;
-		return 0;
-	}
-	return sensor_call(cam, core, g_chip_ident, ident);
-}
-
 /*
  * Only one input.
  */
@@ -852,6 +837,12 @@ static int viacam_s_std(struct file *fil
 	return 0;
 }
 
+static int viacam_g_std(struct file *filp, void *priv, v4l2_std_id *std)
+{
+	*std = V4L2_STD_NTSC_M;
+	return 0;
+}
+
 /*
  * Video format stuff.	Here is our default format until
  * user space messes with things.
@@ -1174,11 +1165,11 @@ static int viacam_enum_frameintervals(st
 
 
 static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
-	.vidioc_g_chip_ident	= viacam_g_chip_ident,
 	.vidioc_enum_input	= viacam_enum_input,
 	.vidioc_g_input		= viacam_g_input,
 	.vidioc_s_input		= viacam_s_input,
 	.vidioc_s_std		= viacam_s_std,
+	.vidioc_g_std		= viacam_g_std,
 	.vidioc_enum_fmt_vid_cap = viacam_enum_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap = viacam_try_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap	= viacam_g_fmt_vid_cap,
@@ -1266,7 +1257,6 @@ static struct video_device viacam_v4l_te
 	.name		= "via-camera",
 	.minor		= -1,
 	.tvnorms	= V4L2_STD_NTSC_M,
-	.current_norm	= V4L2_STD_NTSC_M,
 	.fops		= &viacam_fops,
 	.ioctl_ops	= &viacam_ioctl_ops,
 	.release	= video_device_release_empty, /* Check this */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/platform/vivi.c linux-libre-3.11-rc7-gnu/drivers/media/platform/vivi.c
--- linux-libre-3.10-gnu/drivers/media/platform/vivi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/platform/vivi.c	2013-08-25 20:43:22.000000000 -0400
@@ -768,7 +768,8 @@ static int vivi_start_generating(struct
 
 	dma_q->frame = 0;
 	dma_q->ini_jiffies = jiffies;
-	dma_q->kthread = kthread_run(vivi_thread, dev, dev->v4l2_dev.name);
+	dma_q->kthread = kthread_run(vivi_thread, dev, "%s",
+				     dev->v4l2_dev.name);
 
 	if (IS_ERR(dma_q->kthread)) {
 		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/radio-keene.c linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-keene.c
--- linux-libre-3.10-gnu/drivers/media/radio/radio-keene.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-keene.c	2013-08-25 20:43:22.000000000 -0400
@@ -93,7 +93,7 @@ static int keene_cmd_main(struct keene_d
 	/* If bit 4 is set, then tune to the frequency.
 	   If bit 3 is set, then unmute; if bit 2 is set, then mute.
 	   If bit 1 is set, then enter idle mode; if bit 0 is set,
-	   then enter transit mode.
+	   then enter transmit mode.
 	 */
 	radio->buffer[5] = (radio->muted ? 4 : 8) | (play ? 1 : 2) |
 							(freq ? 0x10 : 0);
@@ -350,7 +350,6 @@ static int usb_keene_probe(struct usb_in
 	radio->pa = 118;
 	radio->tx = 0x32;
 	radio->stereo = true;
-	radio->curfreq = 95.16 * FREQ_MUL;
 	if (hdl->error) {
 		retval = hdl->error;
 
@@ -383,6 +382,10 @@ static int usb_keene_probe(struct usb_in
 	video_set_drvdata(&radio->vdev, radio);
 	set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
 
+	/* at least 11ms is needed in order to settle hardware */
+	msleep(20);
+	keene_cmd_main(radio, 95.16 * FREQ_MUL, false);
+
 	retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1);
 	if (retval < 0) {
 		dev_err(&intf->dev, "could not register video device\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/radio-sf16fmi.c linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-sf16fmi.c
--- linux-libre-3.10-gnu/drivers/media/radio/radio-sf16fmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-sf16fmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,8 @@
 #include <linux/io.h>		/* outb, outb_p			*/
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
 #include "lm7000.h"
 
 MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
@@ -44,10 +46,11 @@ module_param(radio_nr, int, 0);
 struct fmi
 {
 	struct v4l2_device v4l2_dev;
+	struct v4l2_ctrl_handler hdl;
 	struct video_device vdev;
 	int io;
 	bool mute;
-	unsigned long curfreq; /* freq in kHz */
+	u32 curfreq; /* freq in kHz */
 	struct mutex lock;
 };
 
@@ -55,8 +58,8 @@ static struct fmi fmi_card;
 static struct pnp_dev *dev;
 bool pnp_attached;
 
-#define RSF16_MINFREQ (87 * 16000)
-#define RSF16_MAXFREQ (108 * 16000)
+#define RSF16_MINFREQ (87U * 16000)
+#define RSF16_MAXFREQ (108U * 16000)
 
 #define FMI_BIT_TUN_CE		(1 << 0)
 #define FMI_BIT_TUN_CLK		(1 << 1)
@@ -115,13 +118,22 @@ static inline int fmi_getsigstr(struct f
 	return (res & 2) ? 0 : 0xFFFF;
 }
 
+static void fmi_set_freq(struct fmi *fmi)
+{
+	fmi->curfreq = clamp(fmi->curfreq, RSF16_MINFREQ, RSF16_MAXFREQ);
+	/* rounding in steps of 800 to match the freq
+	   that will be used */
+	lm7000_set_freq((fmi->curfreq / 800) * 800, fmi, fmi_set_pins);
+}
+
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *v)
 {
 	strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
 	strlcpy(v->card, "SF16-FMI/FMP/FMD radio", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	strlcpy(v->bus_info, "ISA:radio-sf16fmi", sizeof(v->bus_info));
+	v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -157,12 +169,10 @@ static int vidioc_s_frequency(struct fil
 
 	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
 		return -EINVAL;
-	if (f->frequency < RSF16_MINFREQ ||
-			f->frequency > RSF16_MAXFREQ)
-		return -EINVAL;
-	/* rounding in steps of 800 to match the freq
-	   that will be used */
-	lm7000_set_freq((f->frequency / 800) * 800, fmi, fmi_set_pins);
+
+	fmi->curfreq = f->frequency;
+	fmi_set_freq(fmi);
+
 	return 0;
 }
 
@@ -178,74 +188,31 @@ static int vidioc_g_frequency(struct fil
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-					struct v4l2_queryctrl *qc)
-{
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct fmi *fmi = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = fmi->mute;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
+static int fmi_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	struct fmi *fmi = video_drvdata(file);
+	struct fmi *fmi = container_of(ctrl->handler, struct fmi, hdl);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
+		if (ctrl->val)
 			fmi_mute(fmi);
 		else
 			fmi_unmute(fmi);
-		fmi->mute = ctrl->value;
+		fmi->mute = ctrl->val;
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-					const struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
+static const struct v4l2_ctrl_ops fmi_ctrl_ops = {
+	.s_ctrl = fmi_s_ctrl,
+};
 
 static const struct v4l2_file_operations fmi_fops = {
 	.owner		= THIS_MODULE,
+	.open		= v4l2_fh_open,
+	.release	= v4l2_fh_release,
+	.poll		= v4l2_ctrl_poll,
 	.unlocked_ioctl	= video_ioctl2,
 };
 
@@ -253,15 +220,11 @@ static const struct v4l2_ioctl_ops fmi_i
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
 	.vidioc_g_frequency = vidioc_g_frequency,
 	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
+	.vidioc_log_status  = v4l2_ctrl_log_status,
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 /* ladis: this is my card. does any other types exist? */
@@ -311,6 +274,7 @@ static int __init fmi_init(void)
 {
 	struct fmi *fmi = &fmi_card;
 	struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
+	struct v4l2_ctrl_handler *hdl = &fmi->hdl;
 	int res, i;
 	int probe_ports[] = { 0, 0x284, 0x384 };
 
@@ -363,19 +327,35 @@ static int __init fmi_init(void)
 		return res;
 	}
 
+	v4l2_ctrl_handler_init(hdl, 1);
+	v4l2_ctrl_new_std(hdl, &fmi_ctrl_ops,
+			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+	v4l2_dev->ctrl_handler = hdl;
+	if (hdl->error) {
+		res = hdl->error;
+		v4l2_err(v4l2_dev, "Could not register controls\n");
+		v4l2_ctrl_handler_free(hdl);
+		v4l2_device_unregister(v4l2_dev);
+		return res;
+	}
+
 	strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
 	fmi->vdev.v4l2_dev = v4l2_dev;
 	fmi->vdev.fops = &fmi_fops;
 	fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
 	fmi->vdev.release = video_device_release_empty;
+	set_bit(V4L2_FL_USE_FH_PRIO, &fmi->vdev.flags);
 	video_set_drvdata(&fmi->vdev, fmi);
 
 	mutex_init(&fmi->lock);
 
-	/* mute card - prevents noisy bootups */
-	fmi_mute(fmi);
+	/* mute card and set default frequency */
+	fmi->mute = 1;
+	fmi->curfreq = RSF16_MINFREQ;
+	fmi_set_freq(fmi);
 
 	if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_ctrl_handler_free(hdl);
 		v4l2_device_unregister(v4l2_dev);
 		release_region(fmi->io, 2);
 		if (pnp_attached)
@@ -391,6 +371,7 @@ static void __exit fmi_exit(void)
 {
 	struct fmi *fmi = &fmi_card;
 
+	v4l2_ctrl_handler_free(&fmi->hdl);
 	video_unregister_device(&fmi->vdev);
 	v4l2_device_unregister(&fmi->v4l2_dev);
 	release_region(fmi->io, 2);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/radio-si476x.c linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-si476x.c
--- linux-libre-3.10-gnu/drivers/media/radio/radio-si476x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-si476x.c	2013-08-25 20:43:22.000000000 -0400
@@ -1018,16 +1018,6 @@ static int si476x_radio_s_ctrl(struct v4
 	return retval;
 }
 
-static int si476x_radio_g_chip_ident(struct file *file, void *fh,
-				     struct v4l2_dbg_chip_ident *chip)
-{
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
-	    v4l2_chip_match_host(&chip->match))
-		return 0;
-	return -EINVAL;
-}
-
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int si476x_radio_g_register(struct file *file, void *fh,
 				   struct v4l2_dbg_register *reg)
@@ -1203,7 +1193,6 @@ static const struct v4l2_ioctl_ops si476
 	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
 
-	.vidioc_g_chip_ident		= si476x_radio_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register		= si476x_radio_g_register,
 	.vidioc_s_register		= si476x_radio_s_register,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/radio-tea5764.c linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-tea5764.c
--- linux-libre-3.10-gnu/drivers/media/radio/radio-tea5764.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-tea5764.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,9 @@
 #include <linux/i2c.h>			/* I2C				*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
 
 #define DRIVER_VERSION	"0.0.2"
 
@@ -57,8 +60,8 @@
 
 /* Frequency limits in MHz -- these are European values.  For Japanese
 devices, that would be 76000 and 91000.  */
-#define FREQ_MIN  87500
-#define FREQ_MAX 108000
+#define FREQ_MIN  87500U
+#define FREQ_MAX 108000U
 #define FREQ_MUL 16
 
 /* TEA5764 registers */
@@ -138,8 +141,10 @@ static int radio_nr = -1;
 static int use_xtal = RADIO_TEA5764_XTAL;
 
 struct tea5764_device {
+	struct v4l2_device		v4l2_dev;
+	struct v4l2_ctrl_handler	ctrl_handler;
 	struct i2c_client		*i2c_client;
-	struct video_device		*videodev;
+	struct video_device		vdev;
 	struct tea5764_regs		regs;
 	struct mutex			mutex;
 };
@@ -187,18 +192,6 @@ static int tea5764_i2c_write(struct tea5
 	return 0;
 }
 
-/* V4L2 code related */
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	}
-};
-
 static void tea5764_power_up(struct tea5764_device *radio)
 {
 	struct tea5764_regs *r = &radio->regs;
@@ -291,23 +284,19 @@ static void tea5764_mute(struct tea5764_
 		tea5764_i2c_write(radio);
 }
 
-static int tea5764_is_muted(struct tea5764_device *radio)
-{
-	return radio->regs.tnctrl & TEA5764_TNCTRL_MU;
-}
-
 /* V4L2 vidioc */
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *v)
 {
 	struct tea5764_device *radio = video_drvdata(file);
-	struct video_device *dev = radio->videodev;
+	struct video_device *dev = &radio->vdev;
 
 	strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
 	strlcpy(v->card, dev->name, sizeof(v->card));
 	snprintf(v->bus_info, sizeof(v->bus_info),
 		 "I2C:%s", dev_name(&dev->dev));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -320,8 +309,7 @@ static int vidioc_g_tuner(struct file *f
 	if (v->index > 0)
 		return -EINVAL;
 
-	memset(v, 0, sizeof(*v));
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
 	tea5764_i2c_read(radio);
 	v->rangelow   = FREQ_MIN * FREQ_MUL;
@@ -354,19 +342,23 @@ static int vidioc_s_frequency(struct fil
 				const struct v4l2_frequency *f)
 {
 	struct tea5764_device *radio = video_drvdata(file);
+	unsigned freq = f->frequency;
 
 	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
 		return -EINVAL;
-	if (f->frequency == 0) {
+	if (freq == 0) {
 		/* We special case this as a power down control. */
 		tea5764_power_down(radio);
-	}
-	if (f->frequency < (FREQ_MIN * FREQ_MUL))
-		return -EINVAL;
-	if (f->frequency > (FREQ_MAX * FREQ_MUL))
+		/* Yes, that's what is returned in this case. This
+		   whole special case is non-compliant and should really
+		   be replaced with something better, but changing this
+		   might well break code that depends on this behavior.
+		   So we keep it as-is. */
 		return -EINVAL;
+	}
+	clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
 	tea5764_power_up(radio);
-	tea5764_tune(radio, (f->frequency * 125) / 2);
+	tea5764_tune(radio, (freq * 125) / 2);
 	return 0;
 }
 
@@ -379,7 +371,6 @@ static int vidioc_g_frequency(struct fil
 	if (f->tuner != 0)
 		return -EINVAL;
 	tea5764_i2c_read(radio);
-	memset(f, 0, sizeof(*f));
 	f->type = V4L2_TUNER_RADIO;
 	if (r->tnctrl & TEA5764_TNCTRL_PUPD0)
 		f->frequency = (tea5764_get_freq(radio) * 2) / 125;
@@ -389,83 +380,29 @@ static int vidioc_g_frequency(struct fil
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-			    struct v4l2_queryctrl *qc)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
-			return 0;
-		}
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-			    struct v4l2_control *ctrl)
-{
-	struct tea5764_device *radio = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		tea5764_i2c_read(radio);
-		ctrl->value = tea5764_is_muted(radio) ? 1 : 0;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-			    struct v4l2_control *ctrl)
+static int tea5764_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	struct tea5764_device *radio = video_drvdata(file);
+	struct tea5764_device *radio =
+		container_of(ctrl->handler, struct tea5764_device, ctrl_handler);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		tea5764_mute(radio, ctrl->value);
+		tea5764_mute(radio, ctrl->val);
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	if (i != 0)
-		return -EINVAL;
-	return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-			   struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-			   const struct v4l2_audio *a)
-{
-	if (a->index != 0)
-		return -EINVAL;
-
-	return 0;
-}
+static const struct v4l2_ctrl_ops tea5764_ctrl_ops = {
+	.s_ctrl = tea5764_s_ctrl,
+};
 
 /* File system interface */
 static const struct v4l2_file_operations tea5764_fops = {
 	.owner		= THIS_MODULE,
+	.open		= v4l2_fh_open,
+	.release	= v4l2_fh_release,
+	.poll		= v4l2_ctrl_poll,
 	.unlocked_ioctl	= video_ioctl2,
 };
 
@@ -473,15 +410,11 @@ static const struct v4l2_ioctl_ops tea57
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
 	.vidioc_g_frequency = vidioc_g_frequency,
 	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
+	.vidioc_log_status  = v4l2_ctrl_log_status,
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 /* V4L2 interface */
@@ -489,7 +422,7 @@ static struct video_device tea5764_radio
 	.name		= "TEA5764 FM-Radio",
 	.fops           = &tea5764_fops,
 	.ioctl_ops 	= &tea5764_ioctl_ops,
-	.release	= video_device_release,
+	.release	= video_device_release_empty,
 };
 
 /* I2C probe: check if the device exists and register with v4l if it is */
@@ -497,6 +430,8 @@ static int tea5764_i2c_probe(struct i2c_
 			     const struct i2c_device_id *id)
 {
 	struct tea5764_device *radio;
+	struct v4l2_device *v4l2_dev;
+	struct v4l2_ctrl_handler *hdl;
 	struct tea5764_regs *r;
 	int ret;
 
@@ -505,31 +440,45 @@ static int tea5764_i2c_probe(struct i2c_
 	if (!radio)
 		return -ENOMEM;
 
+	v4l2_dev = &radio->v4l2_dev;
+	ret = v4l2_device_register(&client->dev, v4l2_dev);
+	if (ret < 0) {
+		v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+		goto errfr;
+	}
+
+	hdl = &radio->ctrl_handler;
+	v4l2_ctrl_handler_init(hdl, 1);
+	v4l2_ctrl_new_std(hdl, &tea5764_ctrl_ops,
+			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+	v4l2_dev->ctrl_handler = hdl;
+	if (hdl->error) {
+		ret = hdl->error;
+		v4l2_err(v4l2_dev, "Could not register controls\n");
+		goto errunreg;
+	}
+
 	mutex_init(&radio->mutex);
 	radio->i2c_client = client;
 	ret = tea5764_i2c_read(radio);
 	if (ret)
-		goto errfr;
+		goto errunreg;
 	r = &radio->regs;
 	PDEBUG("chipid = %04X, manid = %04X", r->chipid, r->manid);
 	if (r->chipid != TEA5764_CHIPID ||
 		(r->manid & 0x0fff) != TEA5764_MANID) {
 		PWARN("This chip is not a TEA5764!");
 		ret = -EINVAL;
-		goto errfr;
+		goto errunreg;
 	}
 
-	radio->videodev = video_device_alloc();
-	if (!(radio->videodev)) {
-		ret = -ENOMEM;
-		goto errfr;
-	}
-	memcpy(radio->videodev, &tea5764_radio_template,
-		sizeof(tea5764_radio_template));
+	radio->vdev = tea5764_radio_template;
 
 	i2c_set_clientdata(client, radio);
-	video_set_drvdata(radio->videodev, radio);
-	radio->videodev->lock = &radio->mutex;
+	video_set_drvdata(&radio->vdev, radio);
+	radio->vdev.lock = &radio->mutex;
+	radio->vdev.v4l2_dev = v4l2_dev;
+	set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
 
 	/* initialize and power off the chip */
 	tea5764_i2c_read(radio);
@@ -537,16 +486,17 @@ static int tea5764_i2c_probe(struct i2c_
 	tea5764_mute(radio, 1);
 	tea5764_power_down(radio);
 
-	ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+	ret = video_register_device(&radio->vdev, VFL_TYPE_RADIO, radio_nr);
 	if (ret < 0) {
 		PWARN("Could not register video device!");
-		goto errrel;
+		goto errunreg;
 	}
 
 	PINFO("registered.");
 	return 0;
-errrel:
-	video_device_release(radio->videodev);
+errunreg:
+	v4l2_ctrl_handler_free(hdl);
+	v4l2_device_unregister(v4l2_dev);
 errfr:
 	kfree(radio);
 	return ret;
@@ -559,7 +509,9 @@ static int tea5764_i2c_remove(struct i2c
 	PDEBUG("remove");
 	if (radio) {
 		tea5764_power_down(radio);
-		video_unregister_device(radio->videodev);
+		video_unregister_device(&radio->vdev);
+		v4l2_ctrl_handler_free(&radio->ctrl_handler);
+		v4l2_device_unregister(&radio->v4l2_dev);
 		kfree(radio);
 	}
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/radio-timb.c linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-timb.c
--- linux-libre-3.10-gnu/drivers/media/radio/radio-timb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/radio-timb.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,8 @@
 #include <linux/io.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
@@ -44,7 +46,8 @@ static int timbradio_vidioc_querycap(str
 	strlcpy(v->driver, DRIVER_NAME, sizeof(v->driver));
 	strlcpy(v->card, "Timberdale Radio", sizeof(v->card));
 	snprintf(v->bus_info, sizeof(v->bus_info), "platform:"DRIVER_NAME);
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -62,34 +65,6 @@ static int timbradio_vidioc_s_tuner(stru
 	return v4l2_subdev_call(tr->sd_tuner, tuner, s_tuner, v);
 }
 
-static int timbradio_vidioc_g_input(struct file *filp, void *priv,
-	unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int timbradio_vidioc_s_input(struct file *filp, void *priv,
-	unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int timbradio_vidioc_g_audio(struct file *file, void *priv,
-	struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int timbradio_vidioc_s_audio(struct file *file, void *priv,
-	const struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
-
 static int timbradio_vidioc_s_frequency(struct file *file, void *priv,
 	const struct v4l2_frequency *f)
 {
@@ -104,44 +79,22 @@ static int timbradio_vidioc_g_frequency(
 	return v4l2_subdev_call(tr->sd_tuner, tuner, g_frequency, f);
 }
 
-static int timbradio_vidioc_queryctrl(struct file *file, void *priv,
-	struct v4l2_queryctrl *qc)
-{
-	struct timbradio *tr = video_drvdata(file);
-	return v4l2_subdev_call(tr->sd_dsp, core, queryctrl, qc);
-}
-
-static int timbradio_vidioc_g_ctrl(struct file *file, void *priv,
-	struct v4l2_control *ctrl)
-{
-	struct timbradio *tr = video_drvdata(file);
-	return v4l2_subdev_call(tr->sd_dsp, core, g_ctrl, ctrl);
-}
-
-static int timbradio_vidioc_s_ctrl(struct file *file, void *priv,
-	struct v4l2_control *ctrl)
-{
-	struct timbradio *tr = video_drvdata(file);
-	return v4l2_subdev_call(tr->sd_dsp, core, s_ctrl, ctrl);
-}
-
 static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
 	.vidioc_querycap	= timbradio_vidioc_querycap,
 	.vidioc_g_tuner		= timbradio_vidioc_g_tuner,
 	.vidioc_s_tuner		= timbradio_vidioc_s_tuner,
 	.vidioc_g_frequency	= timbradio_vidioc_g_frequency,
 	.vidioc_s_frequency	= timbradio_vidioc_s_frequency,
-	.vidioc_g_input		= timbradio_vidioc_g_input,
-	.vidioc_s_input		= timbradio_vidioc_s_input,
-	.vidioc_g_audio		= timbradio_vidioc_g_audio,
-	.vidioc_s_audio		= timbradio_vidioc_s_audio,
-	.vidioc_queryctrl	= timbradio_vidioc_queryctrl,
-	.vidioc_g_ctrl		= timbradio_vidioc_g_ctrl,
-	.vidioc_s_ctrl		= timbradio_vidioc_s_ctrl
+	.vidioc_log_status      = v4l2_ctrl_log_status,
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 static const struct v4l2_file_operations timbradio_fops = {
 	.owner		= THIS_MODULE,
+	.open		= v4l2_fh_open,
+	.release	= v4l2_fh_release,
+	.poll		= v4l2_ctrl_poll,
 	.unlocked_ioctl	= video_ioctl2,
 };
 
@@ -173,6 +126,7 @@ static int timbradio_probe(struct platfo
 	tr->video_dev.release = video_device_release_empty;
 	tr->video_dev.minor = -1;
 	tr->video_dev.lock = &tr->lock;
+	set_bit(V4L2_FL_USE_FH_PRIO, &tr->video_dev.flags);
 
 	strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
 	err = v4l2_device_register(NULL, &tr->v4l2_dev);
@@ -181,6 +135,15 @@ static int timbradio_probe(struct platfo
 
 	tr->video_dev.v4l2_dev = &tr->v4l2_dev;
 
+	tr->sd_tuner = v4l2_i2c_new_subdev_board(&tr->v4l2_dev,
+		i2c_get_adapter(pdata->i2c_adapter), pdata->tuner, NULL);
+	tr->sd_dsp = v4l2_i2c_new_subdev_board(&tr->v4l2_dev,
+		i2c_get_adapter(pdata->i2c_adapter), pdata->dsp, NULL);
+	if (tr->sd_tuner == NULL || tr->sd_dsp == NULL)
+		goto err_video_req;
+
+	tr->v4l2_dev.ctrl_handler = tr->sd_dsp->ctrl_handler;
+
 	err = video_register_device(&tr->video_dev, VFL_TYPE_RADIO, -1);
 	if (err) {
 		dev_err(&pdev->dev, "Error reg video\n");
@@ -193,7 +156,6 @@ static int timbradio_probe(struct platfo
 	return 0;
 
 err_video_req:
-	video_device_release_empty(&tr->video_dev);
 	v4l2_device_unregister(&tr->v4l2_dev);
 err:
 	dev_err(&pdev->dev, "Failed to register: %d\n", err);
@@ -206,10 +168,7 @@ static int timbradio_remove(struct platf
 	struct timbradio *tr = platform_get_drvdata(pdev);
 
 	video_unregister_device(&tr->video_dev);
-	video_device_release_empty(&tr->video_dev);
-
 	v4l2_device_unregister(&tr->v4l2_dev);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/saa7706h.c linux-libre-3.11-rc7-gnu/drivers/media/radio/saa7706h.c
--- linux-libre-3.10-gnu/drivers/media/radio/saa7706h.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/saa7706h.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ctrls.h>
 
 #define DRIVER_NAME "saa7706h"
 
@@ -127,6 +127,7 @@
 
 struct saa7706h_state {
 	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler hdl;
 	unsigned muted;
 };
 
@@ -317,51 +318,32 @@ static int saa7706h_mute(struct v4l2_sub
 	return err;
 }
 
-static int saa7706h_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	}
-	return -EINVAL;
-}
-
-static int saa7706h_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int saa7706h_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	struct saa7706h_state *state = to_state(sd);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = state->muted;
-		return 0;
-	}
-	return -EINVAL;
-}
+	struct saa7706h_state *state =
+		container_of(ctrl->handler, struct saa7706h_state, hdl);
 
-static int saa7706h_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			return saa7706h_mute(sd);
-		return saa7706h_unmute(sd);
+		if (ctrl->val)
+			return saa7706h_mute(&state->sd);
+		return saa7706h_unmute(&state->sd);
 	}
 	return -EINVAL;
 }
 
-static int saa7706h_g_chip_ident(struct v4l2_subdev *sd,
-	struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7706H, 0);
-}
+static const struct v4l2_ctrl_ops saa7706h_ctrl_ops = {
+	.s_ctrl = saa7706h_s_ctrl,
+};
 
 static const struct v4l2_subdev_core_ops saa7706h_core_ops = {
-	.g_chip_ident = saa7706h_g_chip_ident,
-	.queryctrl = saa7706h_queryctrl,
-	.g_ctrl = saa7706h_g_ctrl,
-	.s_ctrl = saa7706h_s_ctrl,
+	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+	.g_ctrl = v4l2_subdev_g_ctrl,
+	.s_ctrl = v4l2_subdev_s_ctrl,
+	.queryctrl = v4l2_subdev_queryctrl,
+	.querymenu = v4l2_subdev_querymenu,
 };
 
 static const struct v4l2_subdev_ops saa7706h_ops = {
@@ -393,13 +375,20 @@ static int saa7706h_probe(struct i2c_cli
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &saa7706h_ops);
 
+	v4l2_ctrl_handler_init(&state->hdl, 4);
+	v4l2_ctrl_new_std(&state->hdl, &saa7706h_ctrl_ops,
+			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+	sd->ctrl_handler = &state->hdl;
+	err = state->hdl.error;
+	if (err)
+		goto err;
+
 	/* check the rom versions */
 	err = saa7706h_get_reg16(sd, SAA7706H_DSP1_ROM_VER);
 	if (err < 0)
 		goto err;
 	if (err != SUPPORTED_DSP1_ROM_VER)
 		v4l2_warn(sd, "Unknown DSP1 ROM code version: 0x%x\n", err);
-
 	state->muted = 1;
 
 	/* startup in a muted state */
@@ -411,6 +400,7 @@ static int saa7706h_probe(struct i2c_cli
 
 err:
 	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&state->hdl);
 	kfree(to_state(sd));
 
 	printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", err);
@@ -421,9 +411,11 @@ err:
 static int saa7706h_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct saa7706h_state *state = to_state(sd);
 
 	saa7706h_mute(sd);
 	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&state->hdl);
 	kfree(to_state(sd));
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/tef6862.c linux-libre-3.11-rc7-gnu/drivers/media/radio/tef6862.c
--- linux-libre-3.10-gnu/drivers/media/radio/tef6862.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/tef6862.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,14 +25,13 @@
 #include <linux/slab.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 #define DRIVER_NAME "tef6862"
 
 #define FREQ_MUL 16000
 
-#define TEF6862_LO_FREQ (875 * FREQ_MUL / 10)
-#define TEF6862_HI_FREQ (108 * FREQ_MUL)
+#define TEF6862_LO_FREQ (875U * FREQ_MUL / 10)
+#define TEF6862_HI_FREQ (108U * FREQ_MUL)
 
 /* Write mode sub addresses */
 #define WM_SUB_BANDWIDTH	0x0
@@ -105,6 +104,7 @@ static int tef6862_s_frequency(struct v4
 {
 	struct tef6862_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	unsigned freq = f->frequency;
 	u16 pll;
 	u8 i2cmsg[3];
 	int err;
@@ -112,7 +112,8 @@ static int tef6862_s_frequency(struct v4
 	if (f->tuner != 0)
 		return -EINVAL;
 
-	pll = 1964 + ((f->frequency - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
+	clamp(freq, TEF6862_LO_FREQ, TEF6862_HI_FREQ);
+	pll = 1964 + ((freq - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
 	i2cmsg[0] = (MODE_PRESET << MODE_SHIFT) | WM_SUB_PLLM;
 	i2cmsg[1] = (pll >> 8) & 0xff;
 	i2cmsg[2] = pll & 0xff;
@@ -121,7 +122,7 @@ static int tef6862_s_frequency(struct v4
 	if (err != sizeof(i2cmsg))
 		return err < 0 ? err : -EIO;
 
-	state->freq = f->frequency;
+	state->freq = freq;
 	return 0;
 }
 
@@ -136,14 +137,6 @@ static int tef6862_g_frequency(struct v4
 	return 0;
 }
 
-static int tef6862_g_chip_ident(struct v4l2_subdev *sd,
-	struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEF6862, 0);
-}
-
 static const struct v4l2_subdev_tuner_ops tef6862_tuner_ops = {
 	.g_tuner = tef6862_g_tuner,
 	.s_tuner = tef6862_s_tuner,
@@ -151,12 +144,7 @@ static const struct v4l2_subdev_tuner_op
 	.g_frequency = tef6862_g_frequency,
 };
 
-static const struct v4l2_subdev_core_ops tef6862_core_ops = {
-	.g_chip_ident = tef6862_g_chip_ident,
-};
-
 static const struct v4l2_subdev_ops tef6862_ops = {
-	.core = &tef6862_core_ops,
 	.tuner = &tef6862_tuner_ops,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/wl128x/fmdrv_common.c linux-libre-3.11-rc7-gnu/drivers/media/radio/wl128x/fmdrv_common.c
--- linux-libre-3.10-gnu/drivers/media/radio/wl128x/fmdrv_common.c	2013-07-01 10:35:56.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/wl128x/fmdrv_common.c	2013-08-31 17:55:27.000000000 -0400
@@ -715,7 +715,7 @@ static void fm_irq_handle_rdsdata_getcmd
 	struct fm_rdsdata_format rds_fmt;
 	struct fm_rds *rds = &fmdev->rx.rds;
 	unsigned long group_idx, flags;
-	u8 *rds_data, meta_data, tmpbuf[3];
+	u8 *rds_data, meta_data, tmpbuf[FM_RDS_BLK_SIZE];
 	u8 type, blk_idx;
 	u16 cur_picode;
 	u32 rds_len;
@@ -1073,6 +1073,7 @@ int fmc_transfer_rds_from_internal_buff(
 		u8 __user *buf, size_t count)
 {
 	u32 block_count;
+	u8 tmpbuf[FM_RDS_BLK_SIZE];
 	unsigned long flags;
 	int ret;
 
@@ -1087,29 +1088,32 @@ int fmc_transfer_rds_from_internal_buff(
 	}
 
 	/* Calculate block count from byte count */
-	count /= 3;
+	count /= FM_RDS_BLK_SIZE;
 	block_count = 0;
 	ret = 0;
 
-	spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
-
 	while (block_count < count) {
-		if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx)
-			break;
+		spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
 
-		if (copy_to_user(buf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
-					FM_RDS_BLK_SIZE))
+		if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) {
+			spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
 			break;
-
+		}
+		memcpy(tmpbuf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
+					FM_RDS_BLK_SIZE);
 		fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE;
 		if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size)
 			fmdev->rx.rds.rd_idx = 0;
 
+		spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
+
+		if (copy_to_user(buf, tmpbuf, FM_RDS_BLK_SIZE))
+			break;
+
 		block_count++;
 		buf += FM_RDS_BLK_SIZE;
 		ret += FM_RDS_BLK_SIZE;
 	}
-	spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/wl128x/fmdrv.h linux-libre-3.11-rc7-gnu/drivers/media/radio/wl128x/fmdrv.h
--- linux-libre-3.10-gnu/drivers/media/radio/wl128x/fmdrv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/wl128x/fmdrv.h	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/timer.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
 
 #define FM_DRV_VERSION            "0.1.1"
@@ -202,6 +203,7 @@ struct fmtx_data {
 /* FM driver operation structure */
 struct fmdev {
 	struct video_device *radio_dev;	/* V4L2 video device pointer */
+	struct v4l2_device v4l2_dev;	/* V4L2 top level struct */
 	struct snd_card *card;	/* Card which holds FM mixer controls */
 	u16 asci_id;
 	spinlock_t rds_buff_lock; /* To protect access to RDS buffer */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/radio/wl128x/fmdrv_v4l2.c linux-libre-3.11-rc7-gnu/drivers/media/radio/wl128x/fmdrv_v4l2.c
--- linux-libre-3.10-gnu/drivers/media/radio/wl128x/fmdrv_v4l2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/radio/wl128x/fmdrv_v4l2.c	2013-08-25 20:43:22.000000000 -0400
@@ -533,6 +533,11 @@ int fm_v4l2_init_video_device(struct fmd
 	struct v4l2_ctrl *ctrl;
 	int ret;
 
+	strlcpy(fmdev->v4l2_dev.name, FM_DRV_NAME, sizeof(fmdev->v4l2_dev.name));
+	ret = v4l2_device_register(NULL, &fmdev->v4l2_dev);
+	if (ret < 0)
+		return ret;
+
 	/* Init mutex for core locking */
 	mutex_init(&fmdev->mutex);
 
@@ -549,6 +554,7 @@ int fm_v4l2_init_video_device(struct fmd
 	video_set_drvdata(gradio_dev, fmdev);
 
 	gradio_dev->lock = &fmdev->mutex;
+	gradio_dev->v4l2_dev = &fmdev->v4l2_dev;
 
 	/* Register with V4L2 subsystem as RADIO device */
 	if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
@@ -611,5 +617,7 @@ void *fm_v4l2_deinit_video_device(void)
 	/* Unregister RADIO device from V4L2 subsystem */
 	video_unregister_device(gradio_dev);
 
+	v4l2_device_unregister(&fmdev->v4l2_dev);
+
 	return fmdev;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/rc/gpio-ir-recv.c linux-libre-3.11-rc7-gnu/drivers/media/rc/gpio-ir-recv.c
--- linux-libre-3.10-gnu/drivers/media/rc/gpio-ir-recv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/rc/gpio-ir-recv.c	2013-08-25 20:43:22.000000000 -0400
@@ -178,7 +178,6 @@ static int gpio_ir_recv_probe(struct pla
 	return 0;
 
 err_request_irq:
-	platform_set_drvdata(pdev, NULL);
 	rc_unregister_device(rcdev);
 	rcdev = NULL;
 err_register_rc_device:
@@ -196,7 +195,6 @@ static int gpio_ir_recv_remove(struct pl
 	struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
 
 	free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev);
-	platform_set_drvdata(pdev, NULL);
 	rc_unregister_device(gpio_dev->rcdev);
 	gpio_free(gpio_dev->gpio_nr);
 	kfree(gpio_dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/rc/keymaps/Makefile linux-libre-3.11-rc7-gnu/drivers/media/rc/keymaps/Makefile
--- linux-libre-3.10-gnu/drivers/media/rc/keymaps/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/rc/keymaps/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t
 			rc-budget-ci-old.o \
 			rc-cinergy-1400.o \
 			rc-cinergy.o \
+			rc-delock-61959.o \
 			rc-dib0700-nec.o \
 			rc-dib0700-rc5.o \
 			rc-digitalnow-tinytwin.o \
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/rc/keymaps/rc-delock-61959.c linux-libre-3.11-rc7-gnu/drivers/media/rc/keymaps/rc-delock-61959.c
--- linux-libre-3.10-gnu/drivers/media/rc/keymaps/rc-delock-61959.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/rc/keymaps/rc-delock-61959.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,83 @@
+/* rc-delock-61959.c - Keytable for Delock
+ *
+ * Copyright (c) 2013 by Jakob Haufe <sur5r@sur5r.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+/*
+ * Keytable for remote provided with Delock 61959
+ */
+static struct rc_map_table delock_61959[] = {
+	{ 0x866b16, KEY_POWER2 },	/* Power */
+	{ 0x866b0c, KEY_POWER },	/* Shut Down */
+
+	{ 0x866b00, KEY_1},
+	{ 0x866b01, KEY_2},
+	{ 0x866b02, KEY_3},
+	{ 0x866b03, KEY_4},
+	{ 0x866b04, KEY_5},
+	{ 0x866b05, KEY_6},
+	{ 0x866b06, KEY_7},
+	{ 0x866b07, KEY_8},
+	{ 0x866b08, KEY_9},
+	{ 0x866b14, KEY_0},
+
+	{ 0x866b0a, KEY_ZOOM},		/* Full Screen */
+	{ 0x866b10, KEY_CAMERA},	/* Photo */
+	{ 0x866b0e, KEY_CHANNEL},	/* circular arrow / Recall */
+	{ 0x866b13, KEY_ESC},           /* Back */
+
+	{ 0x866b20, KEY_UP},
+	{ 0x866b21, KEY_DOWN},
+	{ 0x866b42, KEY_LEFT},
+	{ 0x866b43, KEY_RIGHT},
+	{ 0x866b0b, KEY_OK},
+
+	{ 0x866b11, KEY_CHANNELUP},
+	{ 0x866b1b, KEY_CHANNELDOWN},
+
+	{ 0x866b12, KEY_VOLUMEUP},
+	{ 0x866b48, KEY_VOLUMEDOWN},
+	{ 0x866b44, KEY_MUTE},
+
+	{ 0x866b1a, KEY_RECORD},
+	{ 0x866b41, KEY_PLAY},
+	{ 0x866b40, KEY_STOP},
+	{ 0x866b19, KEY_PAUSE},
+	{ 0x866b1c, KEY_FASTFORWARD},	/* >> / FWD */
+	{ 0x866b1e, KEY_REWIND},	/* << / REW */
+
+};
+
+static struct rc_map_list delock_61959_map = {
+	.map = {
+		.scan    = delock_61959,
+		.size    = ARRAY_SIZE(delock_61959),
+		.rc_type = RC_TYPE_NEC,
+		.name    = RC_MAP_DELOCK_61959,
+	}
+};
+
+static int __init init_rc_map_delock_61959(void)
+{
+	return rc_map_register(&delock_61959_map);
+}
+
+static void __exit exit_rc_map_delock_61959(void)
+{
+	rc_map_unregister(&delock_61959_map);
+}
+
+module_init(init_rc_map_delock_61959)
+module_exit(exit_rc_map_delock_61959)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jakob Haufe <sur5r@sur5r.net>");
+MODULE_DESCRIPTION("Delock 61959 remote keytable");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/tuners/r820t.c linux-libre-3.11-rc7-gnu/drivers/media/tuners/r820t.c
--- linux-libre-3.10-gnu/drivers/media/tuners/r820t.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/tuners/r820t.c	2013-08-25 20:43:22.000000000 -0400
@@ -364,8 +364,8 @@ static void shadow_store(struct r820t_pr
 	}
 	if (len <= 0)
 		return;
-	if (len > NUM_REGS)
-		len = NUM_REGS;
+	if (len > NUM_REGS - r)
+		len = NUM_REGS - r;
 
 	tuner_dbg("%s: prev  reg=%02x len=%d: %*ph\n",
 		  __func__, r + REG_SHADOW_START, len, len, val);
@@ -1857,9 +1857,9 @@ static int r820t_imr(struct r820t_priv *
 	int reg18, reg19, reg1f;
 
 	if (priv->cfg->xtal > 24000000)
-		ring_ref = priv->cfg->xtal / 2;
+		ring_ref = priv->cfg->xtal / 2000;
 	else
-		ring_ref = priv->cfg->xtal;
+		ring_ref = priv->cfg->xtal / 1000;
 
 	n_ring = 15;
 	for (n = 0; n < 16; n++) {
@@ -2256,7 +2256,6 @@ static int r820t_release(struct dvb_fron
 
 	mutex_unlock(&r820t_list_mutex);
 
-	kfree(fe->tuner_priv);
 	fe->tuner_priv = NULL;
 
 	return 0;
@@ -2311,8 +2310,6 @@ struct dvb_frontend *r820t_attach(struct
 		break;
 	}
 
-	memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops, sizeof(r820t_tuner_ops));
-
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 
@@ -2327,15 +2324,14 @@ struct dvb_frontend *r820t_attach(struct
 
 	tuner_info("Rafael Micro r820t successfully identified\n");
 
-	fe->tuner_priv = priv;
-	memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops,
-			sizeof(struct dvb_tuner_ops));
-
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 
 	mutex_unlock(&r820t_list_mutex);
 
+	memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops,
+			sizeof(struct dvb_tuner_ops));
+
 	return fe;
 err:
 	if (fe->ops.i2c_gate_ctrl)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/au0828/au0828-video.c linux-libre-3.11-rc7-gnu/drivers/media/usb/au0828/au0828-video.c
--- linux-libre-3.10-gnu/drivers/media/usb/au0828/au0828-video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/au0828/au0828-video.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/tuner.h>
 #include "au0828.h"
 #include "au0828-reg.h"
@@ -1638,26 +1637,6 @@ static int vidioc_g_fmt_vbi_cap(struct f
 	return 0;
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-	       struct v4l2_dbg_chip_ident *chip)
-{
-	struct au0828_fh *fh = priv;
-	struct au0828_dev *dev = fh->dev;
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-
-	if (v4l2_chip_match_host(&chip->match)) {
-		chip->ident = V4L2_IDENT_AU0828;
-		return 0;
-	}
-
-	v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
-	if (chip->ident == V4L2_IDENT_NONE)
-		return -EINVAL;
-
-	return 0;
-}
-
 static int vidioc_cropcap(struct file *file, void *priv,
 			  struct v4l2_cropcap *cc)
 {
@@ -1779,16 +1758,8 @@ static int vidioc_g_register(struct file
 	struct au0828_fh *fh = priv;
 	struct au0828_dev *dev = fh->dev;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
-	}
-
 	reg->val = au0828_read(dev, reg->reg);
+	reg->size = 1;
 	return 0;
 }
 
@@ -1798,14 +1769,6 @@ static int vidioc_s_register(struct file
 	struct au0828_fh *fh = priv;
 	struct au0828_dev *dev = fh->dev;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
-	}
 	return au0828_writereg(dev, reg->reg, reg->val);
 }
 #endif
@@ -1943,7 +1906,6 @@ static const struct v4l2_ioctl_ops video
 	.vidioc_g_register          = vidioc_g_register,
 	.vidioc_s_register          = vidioc_s_register,
 #endif
-	.vidioc_g_chip_ident        = vidioc_g_chip_ident,
 	.vidioc_log_status	    = vidioc_log_status,
 	.vidioc_subscribe_event     = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-417.c linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-417.c
--- linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-417.c	2013-07-01 10:35:05.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-417.c	2013-08-31 17:54:36.000000000 -0400
@@ -1840,7 +1840,6 @@ static const struct v4l2_ioctl_ops mpeg_
 	.vidioc_streamon	 = vidioc_streamon,
 	.vidioc_streamoff	 = vidioc_streamoff,
 	.vidioc_log_status	 = vidioc_log_status,
-	.vidioc_g_chip_ident	 = cx231xx_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register	 = cx231xx_g_register,
 	.vidioc_s_register	 = cx231xx_s_register,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-avcore.c linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-avcore.c
--- linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-avcore.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-avcore.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,7 +35,6 @@
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 
 #include "cx231xx.h"
 #include "cx231xx-dif.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-cards.c linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-cards.c
--- linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-cards.c	2013-07-01 10:32:45.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-cards.c	2013-08-31 17:52:15.000000000 -0400
@@ -29,7 +29,6 @@
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 
 #include <media/cx25840.h>
 #include "dvb-usb-ids.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx.h linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx.h
--- linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -945,7 +945,7 @@ int cx231xx_enum_input(struct file *file
 			     struct v4l2_input *i);
 int cx231xx_g_input(struct file *file, void *priv, unsigned int *i);
 int cx231xx_s_input(struct file *file, void *priv, unsigned int i);
-int cx231xx_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip);
+int cx231xx_g_chip_info(struct file *file, void *fh, struct v4l2_dbg_chip_info *chip);
 int cx231xx_g_register(struct file *file, void *priv,
 			     struct v4l2_dbg_register *reg);
 int cx231xx_s_register(struct file *file, void *priv,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-vbi.c linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-vbi.c
--- linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-vbi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-vbi.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/msp3400.h>
 #include <media/tuner.h>
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-video.c linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-video.c
--- linux-libre-3.10-gnu/drivers/media/usb/cx231xx/cx231xx-video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/cx231xx/cx231xx-video.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/msp3400.h>
 #include <media/tuner.h>
 
@@ -1228,179 +1227,93 @@ int cx231xx_s_frequency(struct file *fil
 	return rc;
 }
 
-int cx231xx_g_chip_ident(struct file *file, void *fh,
-			struct v4l2_dbg_chip_ident *chip)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+int cx231xx_g_chip_info(struct file *file, void *fh,
+			struct v4l2_dbg_chip_info *chip)
 {
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
-		if (v4l2_chip_match_host(&chip->match))
-			chip->ident = V4L2_IDENT_CX23100;
+	switch (chip->match.addr) {
+	case 0:	/* Cx231xx - internal registers */
+		return 0;
+	case 1:	/* AFE - read byte */
+		strlcpy(chip->name, "AFE (byte)", sizeof(chip->name));
+		return 0;
+	case 2:	/* Video Block - read byte */
+		strlcpy(chip->name, "Video (byte)", sizeof(chip->name));
+		return 0;
+	case 3:	/* I2S block - read byte */
+		strlcpy(chip->name, "I2S (byte)", sizeof(chip->name));
+		return 0;
+	case 4: /* AFE - read dword */
+		strlcpy(chip->name, "AFE (dword)", sizeof(chip->name));
+		return 0;
+	case 5: /* Video Block - read dword */
+		strlcpy(chip->name, "Video (dword)", sizeof(chip->name));
+		return 0;
+	case 6: /* I2S Block - read dword */
+		strlcpy(chip->name, "I2S (dword)", sizeof(chip->name));
 		return 0;
 	}
 	return -EINVAL;
 }
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-
-/*
-  -R, --list-registers=type=<host/i2cdrv/i2caddr>,
-				chip=<chip>[,min=<addr>,max=<addr>]
-		     dump registers from <min> to <max> [VIDIOC_DBG_G_REGISTER]
-  -r, --set-register=type=<host/i2cdrv/i2caddr>,
-				chip=<chip>,reg=<addr>,val=<val>
-		     set the register [VIDIOC_DBG_S_REGISTER]
-
-  if type == host, then <chip> is the hosts chip ID (default 0)
-  if type == i2cdrv (default), then <chip> is the I2C driver name or ID
-  if type == i2caddr, then <chip> is the 7-bit I2C address
-*/
-
 int cx231xx_g_register(struct file *file, void *priv,
 			     struct v4l2_dbg_register *reg)
 {
 	struct cx231xx_fh *fh = priv;
 	struct cx231xx *dev = fh->dev;
-	int ret = 0;
+	int ret;
 	u8 value[4] = { 0, 0, 0, 0 };
 	u32 data = 0;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		switch (reg->match.addr) {
-		case 0:	/* Cx231xx - internal registers */
-			ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
-						  (u16)reg->reg, value, 4);
-			reg->val = value[0] | value[1] << 8 |
-				   value[2] << 16 | value[3] << 24;
-			break;
-		case 1:	/* AFE - read byte */
-			ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
-						  (u16)reg->reg, 2, &data, 1);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 14: /* AFE - read dword */
-			ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
-						  (u16)reg->reg, 2, &data, 4);
-			reg->val = le32_to_cpu(data);
-			break;
-		case 2:	/* Video Block - read byte */
-			ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
-						  (u16)reg->reg, 2, &data, 1);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 24: /* Video Block - read dword */
-			ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
-						  (u16)reg->reg, 2, &data, 4);
-			reg->val = le32_to_cpu(data);
-			break;
-		case 3:	/* I2S block - read byte */
-			ret = cx231xx_read_i2c_data(dev,
-						    I2S_BLK_DEVICE_ADDRESS,
-						    (u16)reg->reg, 1,
-						    &data, 1);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 34: /* I2S Block - read dword */
-			ret =
-			    cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
-						  (u16)reg->reg, 1, &data, 4);
-			reg->val = le32_to_cpu(data);
-			break;
-		}
-		return ret < 0 ? ret : 0;
-
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		call_all(dev, core, g_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:/*for register debug*/
-		switch (reg->match.addr) {
-		case 0:	/* Cx231xx - internal registers */
-			ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
-						  (u16)reg->reg, value, 4);
-			reg->val = value[0] | value[1] << 8 |
-				   value[2] << 16 | value[3] << 24;
-
-			break;
-		case 0x600:/* AFE - read byte */
-			ret = cx231xx_read_i2c_master(dev, AFE_DEVICE_ADDRESS,
-						 (u16)reg->reg, 2,
-						 &data, 1 , 0);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-
-		case 0x880:/* Video Block - read byte */
-			if (reg->reg < 0x0b) {
-				ret = cx231xx_read_i2c_master(dev,
-						VID_BLK_I2C_ADDRESS,
-						 (u16)reg->reg, 2,
-						 &data, 1 , 0);
-				reg->val = le32_to_cpu(data & 0xff);
-			} else {
-				ret = cx231xx_read_i2c_master(dev,
-						VID_BLK_I2C_ADDRESS,
-						 (u16)reg->reg, 2,
-						 &data, 4 , 0);
-				reg->val = le32_to_cpu(data);
-			}
-			break;
-		case 0x980:
-			ret = cx231xx_read_i2c_master(dev,
-						I2S_BLK_DEVICE_ADDRESS,
-						(u16)reg->reg, 1,
-						&data, 1 , 0);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 0x400:
-			ret =
-			    cx231xx_read_i2c_master(dev, 0x40,
-						  (u16)reg->reg, 1,
-						 &data, 1 , 0);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 0xc01:
-			ret =
-				cx231xx_read_i2c_master(dev, 0xc0,
-						(u16)reg->reg, 2,
-						 &data, 38, 1);
-			reg->val = le32_to_cpu(data);
-			break;
-		case 0x022:
-			ret =
-				cx231xx_read_i2c_master(dev, 0x02,
-						(u16)reg->reg, 1,
-						 &data, 1, 2);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 0x322:
-			ret = cx231xx_read_i2c_master(dev,
-						0x32,
-						 (u16)reg->reg, 1,
-						 &data, 4 , 2);
-				reg->val = le32_to_cpu(data);
-			break;
-		case 0x342:
-			ret = cx231xx_read_i2c_master(dev,
-						0x34,
-						 (u16)reg->reg, 1,
-						 &data, 4 , 2);
-				reg->val = le32_to_cpu(data);
-			break;
-
-		default:
-			cx231xx_info("no match device address!!\n");
-			break;
-			}
-		return ret < 0 ? ret : 0;
-		/*return -EINVAL;*/
+	switch (reg->match.addr) {
+	case 0:	/* Cx231xx - internal registers */
+		ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
+				(u16)reg->reg, value, 4);
+		reg->val = value[0] | value[1] << 8 |
+			value[2] << 16 | value[3] << 24;
+		reg->size = 4;
+		break;
+	case 1:	/* AFE - read byte */
+		ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+				(u16)reg->reg, 2, &data, 1);
+		reg->val = data;
+		reg->size = 1;
+		break;
+	case 2:	/* Video Block - read byte */
+		ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+				(u16)reg->reg, 2, &data, 1);
+		reg->val = data;
+		reg->size = 1;
+		break;
+	case 3:	/* I2S block - read byte */
+		ret = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+				(u16)reg->reg, 1, &data, 1);
+		reg->val = data;
+		reg->size = 1;
+		break;
+	case 4: /* AFE - read dword */
+		ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+				(u16)reg->reg, 2, &data, 4);
+		reg->val = data;
+		reg->size = 4;
+		break;
+	case 5: /* Video Block - read dword */
+		ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+				(u16)reg->reg, 2, &data, 4);
+		reg->val = data;
+		reg->size = 4;
+		break;
+	case 6: /* I2S Block - read dword */
+		ret = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+				(u16)reg->reg, 1, &data, 4);
+		reg->val = data;
+		reg->size = 4;
+		break;
 	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
+		return -EINVAL;
 	}
-
-	call_all(dev, core, g_register, reg);
-
-	return ret;
+	return ret < 0 ? ret : 0;
 }
 
 int cx231xx_s_register(struct file *file, void *priv,
@@ -1408,165 +1321,46 @@ int cx231xx_s_register(struct file *file
 {
 	struct cx231xx_fh *fh = priv;
 	struct cx231xx *dev = fh->dev;
-	int ret = 0;
-	__le64 buf;
-	u32 value;
+	int ret;
 	u8 data[4] = { 0, 0, 0, 0 };
 
-	buf = cpu_to_le64(reg->val);
-
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		{
-			value = (u32) buf & 0xffffffff;
-
-			switch (reg->match.addr) {
-			case 0:	/* cx231xx internal registers */
-				data[0] = (u8) value;
-				data[1] = (u8) (value >> 8);
-				data[2] = (u8) (value >> 16);
-				data[3] = (u8) (value >> 24);
-				ret = cx231xx_write_ctrl_reg(dev,
-							   VRT_SET_REGISTER,
-							   (u16)reg->reg, data,
-							   4);
-				break;
-			case 1:	/* AFE - read byte */
-				ret = cx231xx_write_i2c_data(dev,
-							AFE_DEVICE_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 1);
-				break;
-			case 14: /* AFE - read dword */
-				ret = cx231xx_write_i2c_data(dev,
-							AFE_DEVICE_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 4);
-				break;
-			case 2:	/* Video Block - read byte */
-				ret =
-				    cx231xx_write_i2c_data(dev,
-							VID_BLK_I2C_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 1);
-				break;
-			case 24: /* Video Block - read dword */
-				ret =
-				    cx231xx_write_i2c_data(dev,
-							VID_BLK_I2C_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 4);
-				break;
-			case 3:	/* I2S block - read byte */
-				ret =
-				    cx231xx_write_i2c_data(dev,
-							I2S_BLK_DEVICE_ADDRESS,
-							(u16)reg->reg, 1,
-							value, 1);
-				break;
-			case 34: /* I2S block - read dword */
-				ret =
-				    cx231xx_write_i2c_data(dev,
-							I2S_BLK_DEVICE_ADDRESS,
-							(u16)reg->reg, 1,
-							value, 4);
-				break;
-			}
-		}
-		return ret < 0 ? ret : 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		{
-			value = (u32) buf & 0xffffffff;
-
-			switch (reg->match.addr) {
-			case 0:/*cx231xx internal registers*/
-					data[0] = (u8) value;
-					data[1] = (u8) (value >> 8);
-					data[2] = (u8) (value >> 16);
-					data[3] = (u8) (value >> 24);
-					ret = cx231xx_write_ctrl_reg(dev,
-							   VRT_SET_REGISTER,
-							   (u16)reg->reg, data,
-							   4);
-					break;
-			case 0x600:/* AFE - read byte */
-					ret = cx231xx_write_i2c_master(dev,
-							AFE_DEVICE_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 1 , 0);
-					break;
-
-			case 0x880:/* Video Block - read byte */
-					if (reg->reg < 0x0b)
-						cx231xx_write_i2c_master(dev,
-							VID_BLK_I2C_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 1, 0);
-					else
-						cx231xx_write_i2c_master(dev,
-							VID_BLK_I2C_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 4, 0);
-					break;
-			case 0x980:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							I2S_BLK_DEVICE_ADDRESS,
-							(u16)reg->reg, 1,
-							value, 1, 0);
-					break;
-			case 0x400:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							0x40,
-							(u16)reg->reg, 1,
-							value, 1, 0);
-					break;
-			case 0xc01:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							 0xc0,
-							 (u16)reg->reg, 1,
-							 value, 1, 1);
-					break;
-
-			case 0x022:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							0x02,
-							(u16)reg->reg, 1,
-							value, 1, 2);
-					break;
-			case 0x322:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							0x32,
-							(u16)reg->reg, 1,
-							value, 4, 2);
-					break;
-
-			case 0x342:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							0x34,
-							(u16)reg->reg, 1,
-							value, 4, 2);
-					break;
-			default:
-				cx231xx_info("no match device address, "
-					"the value is %x\n", reg->match.addr);
-					break;
-
-					}
-
-		}
-	default:
+	switch (reg->match.addr) {
+	case 0:	/* cx231xx internal registers */
+		data[0] = (u8) reg->val;
+		data[1] = (u8) (reg->val >> 8);
+		data[2] = (u8) (reg->val >> 16);
+		data[3] = (u8) (reg->val >> 24);
+		ret = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+				(u16)reg->reg, data, 4);
 		break;
+	case 1:	/* AFE - write byte */
+		ret = cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
+				(u16)reg->reg, 2, reg->val, 1);
+		break;
+	case 2:	/* Video Block - write byte */
+		ret = cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+				(u16)reg->reg, 2, reg->val, 1);
+		break;
+	case 3:	/* I2S block - write byte */
+		ret = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+				(u16)reg->reg, 1, reg->val, 1);
+		break;
+	case 4: /* AFE - write dword */
+		ret = cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
+				(u16)reg->reg, 2, reg->val, 4);
+		break;
+	case 5: /* Video Block - write dword */
+		ret = cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+				(u16)reg->reg, 2, reg->val, 4);
+		break;
+	case 6: /* I2S block - write dword */
+		ret = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+				(u16)reg->reg, 1, reg->val, 4);
+		break;
+	default:
+		return -EINVAL;
 	}
-
-	call_all(dev, core, s_register, reg);
-
-	return ret;
+	return ret < 0 ? ret : 0;
 }
 #endif
 
@@ -2208,8 +2002,8 @@ static const struct v4l2_ioctl_ops video
 	.vidioc_s_tuner                = cx231xx_s_tuner,
 	.vidioc_g_frequency            = cx231xx_g_frequency,
 	.vidioc_s_frequency            = cx231xx_s_frequency,
-	.vidioc_g_chip_ident           = cx231xx_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info            = cx231xx_g_chip_info,
 	.vidioc_g_register             = cx231xx_g_register,
 	.vidioc_s_register             = cx231xx_s_register,
 #endif
@@ -2240,8 +2034,8 @@ static const struct v4l2_ioctl_ops radio
 	.vidioc_s_tuner     = radio_s_tuner,
 	.vidioc_g_frequency = cx231xx_g_frequency,
 	.vidioc_s_frequency = cx231xx_s_frequency,
-	.vidioc_g_chip_ident = cx231xx_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info = cx231xx_g_chip_info,
 	.vidioc_g_register  = cx231xx_g_register,
 	.vidioc_s_register  = cx231xx_s_register,
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb/az6027.c linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb/az6027.c
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb/az6027.c	2013-07-01 10:33:07.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb/az6027.c	2013-08-31 17:52:37.000000000 -0400
@@ -264,7 +264,7 @@ struct stb0899_config az6027_stb0899_con
 	.demod_address 		= 0xd0, /* 0x68, 0xd0 >> 1 */
 
 	.xtal_freq		= 27000000,
-	.inversion		= IQ_SWAP_ON, /* 1 */
+	.inversion		= IQ_SWAP_ON,
 
 	.lo_clk			= 76500000,
 	.hi_clk			= 99000000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb/pctv452e.c linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb/pctv452e.c
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb/pctv452e.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb/pctv452e.c	2013-08-25 20:43:22.000000000 -0400
@@ -828,7 +828,7 @@ static struct stb0899_config stb0899_con
 	.block_sync_mode = STB0899_SYNC_FORCED, /* ? */
 
 	.xtal_freq       = 27000000,	 /* Assume Hz ? */
-	.inversion       = IQ_SWAP_ON,       /* ? */
+	.inversion       = IQ_SWAP_ON,
 
 	.lo_clk	  = 76500000,
 	.hi_clk	  = 99000000,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/af9035.c linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/af9035.c
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/af9035.c	2013-07-01 10:33:03.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/af9035.c	2013-08-31 17:52:33.000000000 -0400
@@ -55,7 +55,7 @@ static int af9035_ctrl_msg(struct dvb_us
 	if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
 			req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
 		dev_err(&d->udev->dev, "%s: too much data wlen=%d rlen=%d\n",
-				__func__, req->wlen, req->rlen);
+				KBUILD_MODNAME, req->wlen, req->rlen);
 		ret = -EINVAL;
 		goto exit;
 	}
@@ -91,9 +91,10 @@ static int af9035_ctrl_msg(struct dvb_us
 	checksum = af9035_checksum(state->buf, rlen - 2);
 	tmp_checksum = (state->buf[rlen - 2] << 8) | state->buf[rlen - 1];
 	if (tmp_checksum != checksum) {
-		dev_err(&d->udev->dev, "%s: command=%02x checksum mismatch " \
-				"(%04x != %04x)\n", KBUILD_MODNAME, req->cmd,
-				tmp_checksum, checksum);
+		dev_err(&d->udev->dev,
+				"%s: command=%02x checksum mismatch (%04x != %04x)\n",
+				KBUILD_MODNAME, req->cmd, tmp_checksum,
+				checksum);
 		ret = -EIO;
 		goto exit;
 	}
@@ -268,11 +269,29 @@ static int af9035_i2c_master_xfer(struct
 			memcpy(&buf[5], msg[0].buf, msg[0].len);
 			ret = af9035_ctrl_msg(d, &req);
 		}
+	} else if (num == 1 && (msg[0].flags & I2C_M_RD)) {
+		if (msg[0].len > 40) {
+			/* TODO: correct limits > 40 */
+			ret = -EOPNOTSUPP;
+		} else {
+			/* I2C */
+			u8 buf[5];
+			struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
+					buf, msg[0].len, msg[0].buf };
+			req.mbox |= ((msg[0].addr & 0x80)  >>  3);
+			buf[0] = msg[0].len;
+			buf[1] = msg[0].addr << 1;
+			buf[2] = 0x00; /* reg addr len */
+			buf[3] = 0x00; /* reg addr MSB */
+			buf[4] = 0x00; /* reg addr LSB */
+			ret = af9035_ctrl_msg(d, &req);
+		}
 	} else {
 		/*
-		 * We support only two kind of I2C transactions:
-		 * 1) 1 x read + 1 x write
+		 * We support only three kind of I2C transactions:
+		 * 1) 1 x read + 1 x write (repeated start)
 		 * 2) 1 x write
+		 * 3) 1 x read
 		 */
 		ret = -EOPNOTSUPP;
 	}
@@ -317,8 +336,8 @@ static int af9035_identify_state(struct
 
 	dev_info(&d->udev->dev,
 			"%s: prechip_version=%02x chip_version=%02x chip_type=%04x\n",
-			__func__, state->prechip_version, state->chip_version,
-			state->chip_type);
+			KBUILD_MODNAME, state->prechip_version,
+			state->chip_version, state->chip_type);
 
 	if (state->chip_type == 0x9135) {
 		if (state->chip_version == 0x02)
@@ -382,9 +401,10 @@ static int af9035_download_firmware_old(
 		hdr_checksum = fw->data[fw->size - i + 5] << 8;
 		hdr_checksum |= fw->data[fw->size - i + 6] << 0;
 
-		dev_dbg(&d->udev->dev, "%s: core=%d addr=%04x data_len=%d " \
-				"checksum=%04x\n", __func__, hdr_core, hdr_addr,
-				hdr_data_len, hdr_checksum);
+		dev_dbg(&d->udev->dev,
+				"%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
+				__func__, hdr_core, hdr_addr, hdr_data_len,
+				hdr_checksum);
 
 		if (((hdr_core != 1) && (hdr_core != 2)) ||
 				(hdr_data_len > i)) {
@@ -489,7 +509,7 @@ static int af9035_download_firmware(stru
 	u8 rbuf[4];
 	u8 tmp;
 	struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
-	struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
+	struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf };
 	dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
 	/*
@@ -498,11 +518,11 @@ static int af9035_download_firmware(stru
 	 * which is done by master demod.
 	 * Master feeds also clock and controls power via GPIO.
 	 */
-	ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_DUAL_MODE, &tmp);
+	ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
 	if (ret < 0)
 		goto err;
 
-	if (tmp) {
+	if (tmp == 1 || tmp == 3) {
 		/* configure gpioh1, reset & power slave demod */
 		ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01);
 		if (ret < 0)
@@ -620,13 +640,15 @@ static int af9035_read_config(struct dvb
 	}
 
 	/* check if there is dual tuners */
-	ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_DUAL_MODE, &tmp);
+	ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
 	if (ret < 0)
 		goto err;
 
-	state->dual_mode = tmp;
-	dev_dbg(&d->udev->dev, "%s: dual mode=%d\n", __func__,
-			state->dual_mode);
+	if (tmp == 1 || tmp == 3)
+		state->dual_mode = true;
+
+	dev_dbg(&d->udev->dev, "%s: ts mode=%d dual mode=%d\n", __func__,
+			tmp, state->dual_mode);
 
 	if (state->dual_mode) {
 		/* read 2nd demodulator I2C address */
@@ -1200,9 +1222,9 @@ static int af9035_init(struct dvb_usb_de
 		{ 0x80f9a4, 0x00, 0x01 },
 	};
 
-	dev_dbg(&d->udev->dev, "%s: USB speed=%d frame_size=%04x " \
-			"packet_size=%02x\n", __func__,
-			d->udev->speed, frame_size, packet_size);
+	dev_dbg(&d->udev->dev,
+			"%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
+			__func__, d->udev->speed, frame_size, packet_size);
 
 	/* init endpoints */
 	for (i = 0; i < ARRAY_SIZE(tab); i++) {
@@ -1477,7 +1499,7 @@ static const struct usb_device_id af9035
 		&af9035_props, "AVerMedia Twinstar (A825)", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100MINI_PLUS,
 		&af9035_props, "Asus U3100Mini Plus", NULL) },
-        { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa,
+	{ DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa,
 		&af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) },
 	/* IT9135 devices */
 #if 0
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/af9035.h linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/af9035.h
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/af9035.h	2013-07-01 10:33:00.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/af9035.h	2013-08-31 17:52:30.000000000 -0400
@@ -100,8 +100,13 @@ static const u32 clock_lut_it9135[] = {
  * eeprom is memory mapped as read only. Writing that memory mapped address
  * will not corrupt eeprom.
  *
- * eeprom has value 0x00 single mode and 0x03 for dual mode as far as I have
- * seen to this day.
+ * TS mode:
+ * 0  TS
+ * 1  DCA + PIP
+ * 3  PIP
+ * n  DCA
+ *
+ * Values 0 and 3 are seen to this day. 0 for single TS and 3 for dual TS.
  */
 
 #define EEPROM_BASE_AF9035        0x42fd
@@ -109,7 +114,7 @@ static const u32 clock_lut_it9135[] = {
 #define EEPROM_SHIFT                0x10
 
 #define EEPROM_IR_MODE              0x10
-#define EEPROM_DUAL_MODE            0x29
+#define EEPROM_TS_MODE              0x29
 #define EEPROM_2ND_DEMOD_ADDR       0x2a
 #define EEPROM_IR_TYPE              0x2c
 #define EEPROM_1_IF_L               0x30
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/dvb_usb.h linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/dvb_usb.h
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/dvb_usb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/dvb_usb.h	2013-08-25 20:43:22.000000000 -0400
@@ -140,7 +140,7 @@ struct dvb_usb_rc {
 	int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
 	int (*query) (struct dvb_usb_device *d);
 	unsigned int interval;
-	const enum rc_driver_type driver_type;
+	enum rc_driver_type driver_type;
 	bool bulk_mode;
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/it913x.c linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/it913x.c
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/it913x.c	2013-07-01 10:33:33.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/it913x.c	2013-08-31 17:53:03.000000000 -0400
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(debug, "set debugging l
 
 static int dvb_usb_it913x_firmware;
 module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
-MODULE_PARM_DESC(firmware, "set firmware 0=auto"\
+MODULE_PARM_DESC(firmware, "set firmware 0=auto "\
 	"1=IT9137 2=IT9135 V1 3=IT9135 V2");
 #define FW_IT9137 "/*(DEBLOBBED)*/"
 #define FW_IT9135_V1 "/*(DEBLOBBED)*/"
@@ -796,6 +796,9 @@ static const struct usb_device_id it913x
 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_4835,
 		&it913x_properties, "Avermedia A835B(4835)",
 			RC_MAP_IT913X_V2) },
+	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2,
+		&it913x_properties, "Digital Dual TV Receiver CTVDIGDUAL_V2",
+			RC_MAP_IT913X_V1) },
 	{}		/* Terminating entry */
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.c linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.c
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf.c	2013-08-25 20:43:22.000000000 -0400
@@ -52,12 +52,6 @@ MODULE_PARM_DESC(rfswitch, "force rf swi
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
-#define deb_info pr_debug
-#define deb_reg pr_debug
-#define deb_adv pr_debug
-#define err pr_err
-#define info pr_info
-
 int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
 		      u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
@@ -65,7 +59,7 @@ int mxl111sf_ctrl_msg(struct dvb_usb_dev
 	int ret;
 	u8 sndbuf[1+wlen];
 
-	deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
+	pr_debug("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
 
 	memset(sndbuf, 0, 1+wlen);
 
@@ -98,12 +92,12 @@ int mxl111sf_read_reg(struct mxl111sf_st
 	if (buf[0] == addr)
 		*data = buf[1];
 	else {
-		err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
+		pr_err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
 		    addr, buf[0], buf[1]);
 		ret = -EINVAL;
 	}
 
-	deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
+	pr_debug("R: (0x%02x, 0x%02x)\n", addr, *data);
 fail:
 	return ret;
 }
@@ -113,11 +107,11 @@ int mxl111sf_write_reg(struct mxl111sf_s
 	u8 buf[] = { addr, data };
 	int ret;
 
-	deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
+	pr_debug("W: (0x%02x, 0x%02x)\n", addr, data);
 
 	ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
 	if (mxl_fail(ret))
-		err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
+		pr_err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
 	return ret;
 }
 
@@ -134,7 +128,7 @@ int mxl111sf_write_reg_mask(struct mxl11
 #if 1
 		/* dont know why this usually errors out on the first try */
 		if (mxl_fail(ret))
-			err("error writing addr: 0x%02x, mask: 0x%02x, "
+			pr_err("error writing addr: 0x%02x, mask: 0x%02x, "
 			    "data: 0x%02x, retrying...", addr, mask, data);
 
 		ret = mxl111sf_read_reg(state, addr, &val);
@@ -167,7 +161,7 @@ int mxl111sf_ctrl_program_regs(struct mx
 					      ctrl_reg_info[i].mask,
 					      ctrl_reg_info[i].data);
 		if (mxl_fail(ret)) {
-			err("failed on reg #%d (0x%02x)", i,
+			pr_err("failed on reg #%d (0x%02x)", i,
 			    ctrl_reg_info[i].addr);
 			break;
 		}
@@ -225,7 +219,7 @@ static int mxl1x1sf_get_chip_info(struct
 		mxl_rev = "UNKNOWN REVISION";
 		break;
 	}
-	info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
+	pr_info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
 fail:
 	return ret;
 }
@@ -239,7 +233,7 @@ fail:
 			  " on first probe attempt");			\
 		___ret = mxl1x1sf_get_chip_info(state);			\
 		if (mxl_fail(___ret))					\
-			err("failed to get chip info during probe");	\
+			pr_err("failed to get chip info during probe");	\
 		else							\
 			mxl_debug("probe needed a retry "		\
 				  "in order to succeed.");		\
@@ -270,14 +264,14 @@ static int mxl111sf_adap_fe_init(struct
 		goto fail;
 	}
 
-	deb_info("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	mutex_lock(&state->fe_lock);
 
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	err = mxl1x1sf_soft_reset(state);
 	mxl_fail(err);
@@ -326,7 +320,7 @@ static int mxl111sf_adap_fe_sleep(struct
 		goto fail;
 	}
 
-	deb_info("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
 
@@ -344,7 +338,7 @@ static int mxl111sf_ep6_streaming_ctrl(s
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
 	int ret = 0;
 
-	deb_info("%s(%d)\n", __func__, onoff);
+	pr_debug("%s(%d)\n", __func__, onoff);
 
 	if (onoff) {
 		ret = mxl111sf_enable_usb_output(state);
@@ -368,7 +362,7 @@ static int mxl111sf_ep5_streaming_ctrl(s
 	struct mxl111sf_state *state = fe_to_priv(fe);
 	int ret = 0;
 
-	deb_info("%s(%d)\n", __func__, onoff);
+	pr_debug("%s(%d)\n", __func__, onoff);
 
 	if (onoff) {
 		ret = mxl111sf_enable_usb_output(state);
@@ -394,7 +388,7 @@ static int mxl111sf_ep4_streaming_ctrl(s
 	struct mxl111sf_state *state = fe_to_priv(fe);
 	int ret = 0;
 
-	deb_info("%s(%d)\n", __func__, onoff);
+	pr_debug("%s(%d)\n", __func__, onoff);
 
 	if (onoff) {
 		ret = mxl111sf_enable_usb_output(state);
@@ -424,7 +418,7 @@ static int mxl111sf_lgdt3305_frontend_at
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -432,7 +426,7 @@ static int mxl111sf_lgdt3305_frontend_at
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -495,7 +489,7 @@ static int mxl111sf_lg2160_frontend_atta
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -503,7 +497,7 @@ static int mxl111sf_lg2160_frontend_atta
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_MH;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -580,7 +574,7 @@ static int mxl111sf_lg2161_frontend_atta
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -588,7 +582,7 @@ static int mxl111sf_lg2161_frontend_atta
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_MH;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -667,7 +661,7 @@ static int mxl111sf_lg2161_ep6_frontend_
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -675,7 +669,7 @@ static int mxl111sf_lg2161_ep6_frontend_
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_MH;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -742,7 +736,7 @@ static int mxl111sf_attach_demod(struct
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -750,7 +744,7 @@ static int mxl111sf_attach_demod(struct
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -802,7 +796,7 @@ static inline int mxl111sf_set_ant_path(
 }
 
 #define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
-	err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
+	pr_err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
 	    __func__, __LINE__, \
 	    (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
 	    pwr0, pwr1, pwr2, pwr3)
@@ -868,7 +862,7 @@ static int mxl111sf_attach_tuner(struct
 	struct mxl111sf_state *state = adap_to_priv(adap);
 	int i;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	for (i = 0; i < state->num_frontends; i++) {
 		if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,
@@ -902,7 +896,7 @@ static int mxl111sf_init(struct dvb_usb_
 
 	ret = get_chip_info(state);
 	if (mxl_fail(ret))
-		err("failed to get chip info during probe");
+		pr_err("failed to get chip info during probe");
 
 	mutex_init(&state->fe_lock);
 
@@ -950,7 +944,7 @@ static int mxl111sf_frontend_attach_mh(s
 static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
 {
 	int ret;
-	deb_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
 	ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
 	if (ret < 0)
@@ -970,7 +964,7 @@ static int mxl111sf_frontend_attach_atsc
 static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
 {
 	int ret;
-	deb_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
 	ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
 	if (ret < 0)
@@ -990,7 +984,7 @@ static int mxl111sf_frontend_attach_merc
 static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
 {
 	int ret;
-	deb_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
 	ret = mxl111sf_attach_demod(adap, 0);
 	if (ret < 0)
@@ -1006,7 +1000,7 @@ static int mxl111sf_frontend_attach_merc
 
 static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)
 {
-	deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint);
+	pr_debug("%s: endpoint=%d size=8192\n", __func__, endpoint);
 	stream->type = USB_BULK;
 	stream->count = 5;
 	stream->endpoint = endpoint;
@@ -1016,7 +1010,7 @@ static void mxl111sf_stream_config_bulk(
 static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,
 		u8 endpoint, int framesperurb, int framesize)
 {
-	deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint,
+	pr_debug("%s: endpoint=%d size=%d\n", __func__, endpoint,
 			framesperurb * framesize);
 	stream->type = USB_ISOC;
 	stream->count = 5;
@@ -1035,7 +1029,7 @@ static void mxl111sf_stream_config_isoc(
 static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	*ts_type = DVB_USB_FE_TS_TYPE_188;
 	if (dvb_usb_mxl111sf_isoc)
@@ -1076,7 +1070,7 @@ static struct dvb_usb_device_properties
 static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	*ts_type = DVB_USB_FE_TS_TYPE_188;
 	if (dvb_usb_mxl111sf_isoc)
@@ -1117,7 +1111,7 @@ static struct dvb_usb_device_properties
 static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	*ts_type = DVB_USB_FE_TS_TYPE_RAW;
 	if (dvb_usb_mxl111sf_isoc)
@@ -1158,7 +1152,7 @@ static struct dvb_usb_device_properties
 static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	if (fe->id == 0) {
 		*ts_type = DVB_USB_FE_TS_TYPE_188;
@@ -1184,7 +1178,7 @@ static int mxl111sf_get_stream_config_at
 
 static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)
 {
-	deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+	pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
 
 	if (fe->id == 0)
 		return mxl111sf_ep6_streaming_ctrl(fe, onoff);
@@ -1228,7 +1222,7 @@ static struct dvb_usb_device_properties
 static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	if (fe->id == 0) {
 		*ts_type = DVB_USB_FE_TS_TYPE_188;
@@ -1260,7 +1254,7 @@ static int mxl111sf_get_stream_config_me
 
 static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)
 {
-	deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+	pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
 
 	if (fe->id == 0)
 		return mxl111sf_ep6_streaming_ctrl(fe, onoff);
@@ -1306,7 +1300,7 @@ static struct dvb_usb_device_properties
 static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	if (fe->id == 0) {
 		*ts_type = DVB_USB_FE_TS_TYPE_188;
@@ -1332,7 +1326,7 @@ static int mxl111sf_get_stream_config_me
 
 static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)
 {
-	deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+	pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
 
 	if (fe->id == 0)
 		return mxl111sf_ep4_streaming_ctrl(fe, onoff);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,8 +31,6 @@ MODULE_PARM_DESC(debug, "set debugging l
 	if (mxl111sf_tuner_debug) \
 		mxl_printk(KERN_DEBUG, fmt, ##arg)
 
-#define err pr_err
-
 /* ------------------------------------------------------------------------ */
 
 struct mxl111sf_tuner_state {
@@ -113,7 +111,7 @@ static struct mxl111sf_reg_ctrl_info *mx
 		filt_bw = 63;
 		break;
 	default:
-		err("%s: invalid bandwidth setting!", __func__);
+		pr_err("%s: invalid bandwidth setting!", __func__);
 		return NULL;
 	}
 
@@ -304,12 +302,12 @@ static int mxl111sf_tuner_set_params(str
 			bw = 8;
 			break;
 		default:
-			err("%s: bandwidth not set!", __func__);
+			pr_err("%s: bandwidth not set!", __func__);
 			return -EINVAL;
 		}
 		break;
 	default:
-		err("%s: modulation type not supported!", __func__);
+		pr_err("%s: modulation type not supported!", __func__);
 		return -EINVAL;
 	}
 	ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/rtl28xxu.c linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/rtl28xxu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/rtl28xxu.c	2013-08-25 20:43:22.000000000 -0400
@@ -1041,67 +1041,34 @@ err:
 static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
 	int ret;
-	u8 val;
 
 	dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
 
 	if (onoff) {
-		/* set output values */
-		ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
-		if (ret)
-			goto err;
-
-		val |= 0x08;
-		val &= 0xef;
-
-		ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
-		if (ret)
-			goto err;
-
-		/* demod_ctl_1 */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
-		if (ret)
-			goto err;
-
-		val &= 0xef;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
-		if (ret)
-			goto err;
-
-		/* demod control */
-		/* PLL enable */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
+		/* GPIO3=1, GPIO4=0 */
+		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x08, 0x18);
 		if (ret)
 			goto err;
 
-		/* bit 7 to 1 */
-		val |= 0x80;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+		/* suspend? */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL1, 0x00, 0x10);
 		if (ret)
 			goto err;
 
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
+		/* enable PLL */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x80, 0x80);
 		if (ret)
 			goto err;
 
-		val |= 0x20;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+		/* disable reset */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x20, 0x20);
 		if (ret)
 			goto err;
 
 		mdelay(5);
 
-		/*enable ADC_Q and ADC_I */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-		if (ret)
-			goto err;
-
-		val |= 0x48;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+		/* enable ADC */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x48, 0x48);
 		if (ret)
 			goto err;
 
@@ -1114,36 +1081,18 @@ static int rtl2832u_power_ctrl(struct dv
 		if (ret)
 			goto err;
 	} else {
-		/* demod_ctl_1 */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
-		if (ret)
-			goto err;
-
-		val |= 0x0c;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
-		if (ret)
-			goto err;
-
-		/* set output values */
-		ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
-		if (ret)
-				goto err;
-
-		val |= 0x10;
-
-		ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
+		/* GPIO4=1 */
+		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x10, 0x10);
 		if (ret)
 			goto err;
 
-		/* demod control */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
+		/* disable ADC */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x48);
 		if (ret)
 			goto err;
 
-		val &= 0x37;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+		/* disable PLL */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x80);
 		if (ret)
 			goto err;
 
@@ -1242,42 +1191,47 @@ static int rtl2831u_get_rc_config(struct
 
 	return 0;
 }
-#else
-	#define rtl2831u_get_rc_config NULL
-#endif
 
-#if IS_ENABLED(CONFIG_RC_CORE)
 static int rtl2832u_rc_query(struct dvb_usb_device *d)
 {
-	int ret, i;
+	int ret, i, len;
 	struct rtl28xxu_priv *priv = d->priv;
+	struct ir_raw_event ev;
 	u8 buf[128];
-	int len;
-	struct rtl28xxu_reg_val rc_nec_tab[] = {
-		{ IR_RX_CTRL,             0x20 },
-		{ IR_RX_BUF_CTRL,         0x80 },
-		{ IR_RX_IF,               0xff },
-		{ IR_RX_IE,               0xff },
-		{ IR_MAX_DURATION0,       0xd0 },
-		{ IR_MAX_DURATION1,       0x07 },
-		{ IR_IDLE_LEN0,           0xc0 },
-		{ IR_IDLE_LEN1,           0x00 },
-		{ IR_GLITCH_LEN,          0x03 },
-		{ IR_RX_CLK,              0x09 },
-		{ IR_RX_CFG,              0x1c },
-		{ IR_MAX_H_TOL_LEN,       0x1e },
-		{ IR_MAX_L_TOL_LEN,       0x1e },
-		{ IR_RX_CTRL,             0x80 },
+	static const struct rtl28xxu_reg_val_mask refresh_tab[] = {
+		{IR_RX_IF,               0x03, 0xff},
+		{IR_RX_BUF_CTRL,         0x80, 0xff},
+		{IR_RX_CTRL,             0x80, 0xff},
 	};
 
 	/* init remote controller */
 	if (!priv->rc_active) {
-		for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
-			ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
-					rc_nec_tab[i].val);
+		static const struct rtl28xxu_reg_val_mask init_tab[] = {
+			{SYS_DEMOD_CTL1,         0x00, 0x04},
+			{SYS_DEMOD_CTL1,         0x00, 0x08},
+			{USB_CTRL,               0x20, 0x20},
+			{SYS_GPIO_DIR,           0x00, 0x08},
+			{SYS_GPIO_OUT_EN,        0x08, 0x08},
+			{SYS_GPIO_OUT_VAL,       0x08, 0x08},
+			{IR_MAX_DURATION0,       0xd0, 0xff},
+			{IR_MAX_DURATION1,       0x07, 0xff},
+			{IR_IDLE_LEN0,           0xc0, 0xff},
+			{IR_IDLE_LEN1,           0x00, 0xff},
+			{IR_GLITCH_LEN,          0x03, 0xff},
+			{IR_RX_CLK,              0x09, 0xff},
+			{IR_RX_CFG,              0x1c, 0xff},
+			{IR_MAX_H_TOL_LEN,       0x1e, 0xff},
+			{IR_MAX_L_TOL_LEN,       0x1e, 0xff},
+			{IR_RX_CTRL,             0x80, 0xff},
+		};
+
+		for (i = 0; i < ARRAY_SIZE(init_tab); i++) {
+			ret = rtl28xx_wr_reg_mask(d, init_tab[i].reg,
+					init_tab[i].val, init_tab[i].mask);
 			if (ret)
 				goto err;
 		}
+
 		priv->rc_active = true;
 	}
 
@@ -1293,14 +1247,32 @@ static int rtl2832u_rc_query(struct dvb_
 		goto err;
 
 	len = buf[0];
+
+	/* read raw code from hw */
 	ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
+	if (ret)
+		goto err;
 
-	/* TODO: pass raw IR to Kernel IR decoder */
+	/* let hw receive new code */
+	for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) {
+		ret = rtl28xx_wr_reg_mask(d, refresh_tab[i].reg,
+				refresh_tab[i].val, refresh_tab[i].mask);
+		if (ret)
+			goto err;
+	}
 
-	ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03);
-	ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
-	ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80);
+	/* pass data to Kernel IR decoder */
+	init_ir_raw_event(&ev);
 
+	for (i = 0; i < len; i++) {
+		ev.pulse = buf[i] >> 7;
+		ev.duration = 50800 * (buf[i] & 0x7f);
+		ir_raw_event_store_with_filter(d->rc_dev, &ev);
+	}
+
+	/* 'flush' ir_raw_event_store_with_filter() */
+	ir_raw_event_set_idle(d->rc_dev, true);
+	ir_raw_event_handle(d->rc_dev);
 exit:
 	return ret;
 err:
@@ -1311,15 +1283,19 @@ err:
 static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
 		struct dvb_usb_rc *rc)
 {
-	rc->map_name = RC_MAP_EMPTY;
-	rc->allowed_protos = RC_BIT_NEC;
+	/* load empty to enable rc */
+	if (!rc->map_name)
+		rc->map_name = RC_MAP_EMPTY;
+	rc->allowed_protos = RC_BIT_ALL;
+	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->query = rtl2832u_rc_query;
 	rc->interval = 400;
 
 	return 0;
 }
 #else
-	#define rtl2832u_get_rc_config NULL
+#define rtl2831u_get_rc_config NULL
+#define rtl2832u_get_rc_config NULL
 #endif
 
 static const struct dvb_usb_device_properties rtl2831u_props = {
@@ -1379,7 +1355,7 @@ static const struct usb_device_id rtl28x
 	{ DVB_USB_DEVICE(USB_VID_REALTEK, 0x2838,
 		&rtl2832u_props, "Realtek RTL2832U reference design", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1,
-		&rtl2832u_props, "TerraTec Cinergy T Stick Black", NULL) },
+		&rtl2832u_props, "TerraTec Cinergy T Stick Black", RC_MAP_TERRATEC_SLIM) },
 	{ DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT,
 		&rtl2832u_props, "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK,
@@ -1403,11 +1379,15 @@ static const struct usb_device_id rtl28x
 	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd393,
 		&rtl2832u_props, "GIGABYTE U7300", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1104,
-		&rtl2832u_props, "Digivox Micro Hd", NULL) },
+		&rtl2832u_props, "MSI DIGIVOX Micro HD", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_COMPRO, 0x0620,
 		&rtl2832u_props, "Compro VideoMate U620F", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394,
 		&rtl2832u_props, "MaxMedia HU394-T", NULL) },
+	{ DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a03,
+		&rtl2832u_props, "Leadtek WinFast DTV Dongle mini", NULL) },
+	{ DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A,
+		&rtl2832u_props, "Crypto ReDi PC 50 A", NULL) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/rtl28xxu.h linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
--- linux-libre-3.10-gnu/drivers/media/usb/dvb-usb-v2/rtl28xxu.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/dvb-usb-v2/rtl28xxu.h	2013-08-25 20:43:22.000000000 -0400
@@ -97,6 +97,12 @@ struct rtl28xxu_reg_val {
 	u8 val;
 };
 
+struct rtl28xxu_reg_val_mask {
+	u16 reg;
+	u8 val;
+	u8 mask;
+};
+
 /*
  * memory map
  *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-cards.c linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-cards.c
--- linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-cards.c	2013-07-01 10:32:41.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-cards.c	2013-08-31 17:52:11.000000000 -0400
@@ -37,7 +37,6 @@
 #include <media/i2c-addr.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 
 #include "em28xx.h"
 
@@ -83,26 +82,26 @@ static void em28xx_pre_card_setup(struct
 
 /* Reset for the most [analog] boards */
 static struct em28xx_reg_seq default_analog[] = {
-	{EM28XX_R08_GPIO,	0x6d,   ~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6d,   ~EM_GPIO_4,	10},
 	{	-1,		-1,	-1,		-1},
 };
 
 /* Reset for the most [digital] boards */
 static struct em28xx_reg_seq default_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{	-1,		-1,	-1,		-1},
 };
 
 /* Board Hauppauge WinTV HVR 900 analog */
 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
-	{EM28XX_R08_GPIO,	0x2d,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x2d,	~EM_GPIO_4,	10},
 	{0x05,			0xff,	0x10,		10},
 	{  -1,			-1,	-1,		-1},
 };
 
 /* Board Hauppauge WinTV HVR 900 digital */
 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
-	{EM28XX_R08_GPIO,	0x2e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x2e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x04,	0x0f,		10},
 	{EM2880_R04_GPO,	0x0c,	0x0f,		10},
 	{ -1,			-1,	-1,		-1},
@@ -110,14 +109,14 @@ static struct em28xx_reg_seq hauppauge_w
 
 /* Board Hauppauge WinTV HVR 900 (R2) digital */
 static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = {
-	{EM28XX_R08_GPIO,	0x2e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x2e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x0c,	0x0f,		10},
 	{ -1,			-1,	-1,		-1},
 };
 
 /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
 static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
-	{EM28XX_R08_GPIO,       0x69,   ~EM_GPIO_4,	 10},
+	{EM2820_R08_GPIO_CTRL,       0x69,   ~EM_GPIO_4,	 10},
 	{	-1,		-1,	-1,		 -1},
 };
 
@@ -128,11 +127,11 @@ static struct em28xx_reg_seq em2880_msi_
 
 /* Board - EM2882 Kworld 315U digital */
 static struct em28xx_reg_seq em2882_kworld_315u_digital[] = {
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xfe,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
 	{EM2880_R04_GPO,	0x04,	0xff,		10},
 	{EM2880_R04_GPO,	0x0c,	0xff,		10},
-	{EM28XX_R08_GPIO,	0x7e,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0x7e,	0xff,		10},
 	{  -1,			-1,	-1,		-1},
 };
 
@@ -145,13 +144,13 @@ static struct em28xx_reg_seq em2882_kwor
 };
 
 static struct em28xx_reg_seq kworld_330u_analog[] = {
-	{EM28XX_R08_GPIO,	0x6d,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x00,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq kworld_330u_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x08,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
@@ -163,12 +162,12 @@ static struct em28xx_reg_seq kworld_330u
    GOP3  - s5h1409 reset
  */
 static struct em28xx_reg_seq evga_indtube_analog[] = {
-	{EM28XX_R08_GPIO,	0x79,   0xff,		60},
+	{EM2820_R08_GPIO_CTRL,	0x79,   0xff,		60},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq evga_indtube_digital[] = {
-	{EM28XX_R08_GPIO,	0x7a,	0xff,		 1},
+	{EM2820_R08_GPIO_CTRL,	0x7a,	0xff,		 1},
 	{EM2880_R04_GPO,	0x04,	0xff,		10},
 	{EM2880_R04_GPO,	0x0c,	0xff,		 1},
 	{ -1,			-1,	-1,		-1},
@@ -186,31 +185,31 @@ static struct em28xx_reg_seq evga_indtub
  * EM_GPIO_7 - currently unknown
  */
 static struct em28xx_reg_seq kworld_a340_digital[] = {
-	{EM28XX_R08_GPIO,	0x6d,		~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6d,		~EM_GPIO_4,	10},
 	{ -1,			-1,		-1,		-1},
 };
 
 /* Pinnacle Hybrid Pro eb1a:2881 */
 static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
-	{EM28XX_R08_GPIO,	0xfd,   ~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0xfd,   ~EM_GPIO_4,	10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x04,	0xff,	       100},/* zl10353 reset */
 	{EM2880_R04_GPO,	0x0c,	0xff,		 1},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = {
-	{EM28XX_R08_GPIO,	0x6d,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x00,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x08,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
@@ -219,66 +218,66 @@ static struct em28xx_reg_seq terratec_ci
    GPIO4 - CU1216L NIM
    Other GPIOs seems to be don't care. */
 static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = {
-	{EM28XX_R08_GPIO,	0xfe,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xde,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xfe,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
-	{EM28XX_R08_GPIO,	0x7f,	0xff,		10},
-	{EM28XX_R08_GPIO,	0x6f,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xde,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0x7f,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0x6f,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
 	{-1,			-1,	-1,		-1},
 };
 
 /* Callback for the most boards */
 static struct em28xx_reg_seq default_tuner_gpio[] = {
-	{EM28XX_R08_GPIO,	EM_GPIO_4,	EM_GPIO_4,	10},
-	{EM28XX_R08_GPIO,	0,		EM_GPIO_4,	10},
-	{EM28XX_R08_GPIO,	EM_GPIO_4,	EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	EM_GPIO_4,	EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0,		EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	EM_GPIO_4,	EM_GPIO_4,	10},
 	{  -1,			-1,		-1,		-1},
 };
 
 /* Mute/unmute */
 static struct em28xx_reg_seq compro_unmute_tv_gpio[] = {
-	{EM28XX_R08_GPIO,	5,		7,		10},
+	{EM2820_R08_GPIO_CTRL,	5,		7,		10},
 	{  -1,			-1,		-1,		-1},
 };
 
 static struct em28xx_reg_seq compro_unmute_svid_gpio[] = {
-	{EM28XX_R08_GPIO,	4,		7,		10},
+	{EM2820_R08_GPIO_CTRL,	4,		7,		10},
 	{  -1,			-1,		-1,		-1},
 };
 
 static struct em28xx_reg_seq compro_mute_gpio[] = {
-	{EM28XX_R08_GPIO,	6,		7,		10},
+	{EM2820_R08_GPIO_CTRL,	6,		7,		10},
 	{  -1,			-1,		-1,		-1},
 };
 
 /* Terratec AV350 */
 static struct em28xx_reg_seq terratec_av350_mute_gpio[] = {
-	{EM28XX_R08_GPIO,	0xff,	0x7f,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0x7f,		10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = {
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq silvercrest_reg_seq[] = {
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
-	{EM28XX_R08_GPIO,	0x01,	0xf7,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0x01,	0xf7,		10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq vc211a_enable[] = {
-	{EM28XX_R08_GPIO,	0xff,	0x07,		10},
-	{EM28XX_R08_GPIO,	0xff,	0x0f,		10},
-	{EM28XX_R08_GPIO,	0xff,	0x0b,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0x07,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0x0f,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0x0b,		10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq dikom_dk300_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x08,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
@@ -286,14 +285,14 @@ static struct em28xx_reg_seq dikom_dk300
 
 /* Reset for the most [digital] boards */
 static struct em28xx_reg_seq leadership_digital[] = {
-	{EM2874_R80_GPIO,	0x70,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0x70,	0xff,	10},
 	{	-1,		-1,	-1,	-1},
 };
 
 static struct em28xx_reg_seq leadership_reset[] = {
-	{EM2874_R80_GPIO,	0xf0,	0xff,	10},
-	{EM2874_R80_GPIO,	0xb0,	0xff,	10},
-	{EM2874_R80_GPIO,	0xf0,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf0,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xb0,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf0,	0xff,	10},
 	{	-1,		-1,	-1,	-1},
 };
 
@@ -302,25 +301,25 @@ static struct em28xx_reg_seq leadership_
  * GPIO_7 - LED
  */
 static struct em28xx_reg_seq pctv_290e[] = {
-	{EM2874_R80_GPIO,	0x00,	0xff,		80},
-	{EM2874_R80_GPIO,	0x40,	0xff,		80}, /* GPIO_6 = 1 */
-	{EM2874_R80_GPIO,	0xc0,	0xff,		80}, /* GPIO_7 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL,	0x00,	0xff,	80},
+	{EM2874_R80_GPIO_P0_CTRL,	0x40,	0xff,	80}, /* GPIO_6 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL,	0xc0,	0xff,	80}, /* GPIO_7 = 1 */
 	{-1,			-1,	-1,		-1},
 };
 
 #if 0
 static struct em28xx_reg_seq terratec_h5_gpio[] = {
-	{EM28XX_R08_GPIO,	0xff,	0xff,	10},
-	{EM2874_R80_GPIO,	0xf6,	0xff,	100},
-	{EM2874_R80_GPIO,	0xf2,	0xff,	50},
-	{EM2874_R80_GPIO,	0xf6,	0xff,	50},
+	{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf2,	0xff,	50},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	50},
 	{ -1,			-1,	-1,	-1},
 };
 
 static struct em28xx_reg_seq terratec_h5_digital[] = {
-	{EM2874_R80_GPIO,	0xf6,	0xff,	10},
-	{EM2874_R80_GPIO,	0xe6,	0xff,	100},
-	{EM2874_R80_GPIO,	0xa6,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
+	{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	10},
 	{ -1,			-1,	-1,	-1},
 };
 #endif
@@ -336,51 +335,52 @@ static struct em28xx_reg_seq terratec_h5
  * GPIO_7 - LED (green LED)
  */
 static struct em28xx_reg_seq pctv_460e[] = {
-	{EM2874_R80_GPIO, 0x01, 0xff,  50},
+	{EM2874_R80_GPIO_P0_CTRL, 0x01, 0xff,  50},
 	{0x0d,            0xff, 0xff,  50},
-	{EM2874_R80_GPIO, 0x41, 0xff,  50}, /* GPIO_6=1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x41, 0xff,  50}, /* GPIO_6=1 */
 	{0x0d,            0x42, 0xff,  50},
-	{EM2874_R80_GPIO, 0x61, 0xff,  50}, /* GPIO_5=1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x61, 0xff,  50}, /* GPIO_5=1 */
 	{             -1,   -1,   -1,  -1},
 };
 
 static struct em28xx_reg_seq c3tech_digital_duo_digital[] = {
-	{EM2874_R80_GPIO,	0xff,	0xff,	10},
-	{EM2874_R80_GPIO,	0xfd,	0xff,	10}, /* xc5000 reset */
-	{EM2874_R80_GPIO,	0xf9,	0xff,	35},
-	{EM2874_R80_GPIO,	0xfd,	0xff,	10},
-	{EM2874_R80_GPIO,	0xff,	0xff,	10},
-	{EM2874_R80_GPIO,	0xfe,	0xff,	10},
-	{EM2874_R80_GPIO,	0xbe,	0xff,	10},
-	{EM2874_R80_GPIO,	0xfe,	0xff,	20},
+	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10}, /* xc5000 reset */
+	{EM2874_R80_GPIO_P0_CTRL,	0xf9,	0xff,	35},
+	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xbe,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	20},
 	{ -1,			-1,	-1,	-1},
 };
 
 #if 0
 static struct em28xx_reg_seq hauppauge_930c_gpio[] = {
-	{EM2874_R80_GPIO,	0x6f,	0xff,	10},
-	{EM2874_R80_GPIO,	0x4f,	0xff,	10}, /* xc5000 reset */
-	{EM2874_R80_GPIO,	0x6f,	0xff,	10},
-	{EM2874_R80_GPIO,	0x4f,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0x6f,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0x4f,	0xff,	10}, /* xc5000 reset */
+	{EM2874_R80_GPIO_P0_CTRL,	0x6f,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0x4f,	0xff,	10},
 	{ -1,			-1,	-1,	-1},
 };
 
 static struct em28xx_reg_seq hauppauge_930c_digital[] = {
-	{EM2874_R80_GPIO,	0xf6,	0xff,	10},
-	{EM2874_R80_GPIO,	0xe6,	0xff,	100},
-	{EM2874_R80_GPIO,	0xa6,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
+	{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	10},
 	{ -1,			-1,	-1,	-1},
 };
 #endif
 
 /* 1b80:e425 MaxMedia UB425-TC
+ * 1b80:e1cc Delock 61959
  * GPIO_6 - demod reset, 0=active
  * GPIO_7 - LED, 0=active
  */
 static struct em28xx_reg_seq maxmedia_ub425_tc[] = {
-	{EM2874_R80_GPIO,  0x83,  0xff,  100},
-	{EM2874_R80_GPIO,  0xc3,  0xff,  100}, /* GPIO_6 = 1 */
-	{EM2874_R80_GPIO,  0x43,  0xff,  000}, /* GPIO_7 = 0 */
+	{EM2874_R80_GPIO_P0_CTRL,  0x83,  0xff,  100},
+	{EM2874_R80_GPIO_P0_CTRL,  0xc3,  0xff,  100}, /* GPIO_6 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL,  0x43,  0xff,  000}, /* GPIO_7 = 0 */
 	{-1,                 -1,    -1,   -1},
 };
 
@@ -391,9 +391,9 @@ static struct em28xx_reg_seq maxmedia_ub
  * GPIO_7: LED, 1=active
  */
 static struct em28xx_reg_seq pctv_510e[] = {
-	{EM2874_R80_GPIO, 0x10, 0xff, 100},
-	{EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
-	{EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100},
+	{EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
 	{             -1,   -1,   -1,  -1},
 };
 
@@ -404,10 +404,10 @@ static struct em28xx_reg_seq pctv_510e[]
  * GPIO_7: LED, 1=active
  */
 static struct em28xx_reg_seq pctv_520e[] = {
-	{EM2874_R80_GPIO, 0x10, 0xff, 100},
-	{EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
-	{EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
-	{EM2874_R80_GPIO, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100},
+	{EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */
 	{             -1,   -1,   -1,  -1},
 };
 
@@ -2017,6 +2017,19 @@ struct em28xx_board em28xx_boards[] = {
 		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
 				EM28XX_I2C_FREQ_400_KHZ,
 	},
+	/* 1b80:e1cc Delock 61959
+	 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2
+         * mostly the same as MaxMedia UB-425-TC but different remote */
+	[EM2874_BOARD_DELOCK_61959] = {
+		.name          = "Delock 61959",
+		.tuner_type    = TUNER_ABSENT,
+		.tuner_gpio    = maxmedia_ub425_tc,
+		.has_dvb       = 1,
+		.ir_codes      = RC_MAP_DELOCK_61959,
+		.def_i2c_bus   = 1,
+		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
+				EM28XX_I2C_FREQ_400_KHZ,
+	},
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
@@ -2178,6 +2191,8 @@ struct usb_device_id em28xx_id_table[] =
 			.driver_info = EM2884_BOARD_PCTV_510E },
 	{ USB_DEVICE(0x2013, 0x0251),
 			.driver_info = EM2884_BOARD_PCTV_520E },
+	{ USB_DEVICE(0x1b80, 0xe1cc),
+			.driver_info = EM2874_BOARD_DELOCK_61959 },
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -2284,9 +2299,9 @@ static void em28xx_pre_card_setup(struct
 		break;
 	case EM2861_BOARD_KWORLD_PVRTV_300U:
 	case EM2880_BOARD_KWORLD_DVB_305U:
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x6d);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x6d);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x7d);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x7d);
 		msleep(10);
 		break;
 	case EM2870_BOARD_COMPRO_VIDEOMATE:
@@ -2296,45 +2311,45 @@ static void em28xx_pre_card_setup(struct
 		msleep(10);
 		em28xx_write_reg(dev, EM2880_R04_GPO, 0x01);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xdc);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xdc);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
 		mdelay(70);
 		break;
 	case EM2870_BOARD_TERRATEC_XS_MT2060:
 		/* this device needs some gpio writes to get the DVB-T
 		   demod work */
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		mdelay(70);
 		break;
 	case EM2870_BOARD_PINNACLE_PCTV_DVB:
 		/* this device needs some gpio writes to get the
 		   DVB-T demod work */
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		mdelay(70);
 		break;
 	case EM2820_BOARD_GADMEI_UTV310:
 	case EM2820_BOARD_MSI_VOX_USB_2:
 		/* enables audio for that devices */
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
 		break;
 
 	case EM2882_BOARD_KWORLD_ATSC_315U:
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		msleep(10);
 		em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
 		msleep(10);
@@ -2360,13 +2375,13 @@ static void em28xx_pre_card_setup(struct
 		break;
 
 	case EM2820_BOARD_IODATA_GVMVP_SZ:
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
 		msleep(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		msleep(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
 		msleep(70);
 		break;
 	}
@@ -2653,7 +2668,7 @@ static void em28xx_card_setup(struct em2
 
 		dev->tuner_type = tv.tuner_type;
 
-		if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
+		if (tv.audio_processor == TVEEPROM_AUDPROC_MSP) {
 			dev->i2s_speed = 2048000;
 			dev->board.has_msp34xx = 1;
 		}
@@ -2662,12 +2677,12 @@ static void em28xx_card_setup(struct em2
 	case EM2882_BOARD_KWORLD_ATSC_315U:
 		em28xx_write_reg(dev, 0x0d, 0x42);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
 		msleep(10);
 		break;
 	case EM2820_BOARD_KWORLD_PVRTV2800RF:
 		/* GPIO enables sound on KWORLD PVR TV 2800RF */
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf9);
 		break;
 	case EM2820_BOARD_UNKNOWN:
 	case EM2800_BOARD_UNKNOWN:
@@ -2881,10 +2896,6 @@ static int em28xx_init_dev(struct em28xx
 
 	em28xx_set_model(dev);
 
-	/* Set the default GPO/GPIO for legacy devices */
-	dev->reg_gpo_num = EM2880_R04_GPO;
-	dev->reg_gpio_num = EM28XX_R08_GPIO;
-
 	dev->wait_after_write = 5;
 
 	/* Based on the Chip ID, set the device configuration */
@@ -2932,13 +2943,11 @@ static int em28xx_init_dev(struct em28xx
 			break;
 		case CHIP_ID_EM2874:
 			chip_name = "em2874";
-			dev->reg_gpio_num = EM2874_R80_GPIO;
 			dev->wait_after_write = 0;
 			dev->eeprom_addrwidth_16bit = 1;
 			break;
 		case CHIP_ID_EM28174:
 			chip_name = "em28174";
-			dev->reg_gpio_num = EM2874_R80_GPIO;
 			dev->wait_after_write = 0;
 			dev->eeprom_addrwidth_16bit = 1;
 			break;
@@ -2948,7 +2957,6 @@ static int em28xx_init_dev(struct em28xx
 			break;
 		case CHIP_ID_EM2884:
 			chip_name = "em2884";
-			dev->reg_gpio_num = EM2874_R80_GPIO;
 			dev->wait_after_write = 0;
 			dev->eeprom_addrwidth_16bit = 1;
 			break;
@@ -2977,11 +2985,6 @@ static int em28xx_init_dev(struct em28xx
 		return 0;
 	}
 
-	/* Prepopulate cached GPO register content */
-	retval = em28xx_read_reg(dev, dev->reg_gpo_num);
-	if (retval >= 0)
-		dev->reg_gpo = retval;
-
 	em28xx_pre_card_setup(dev);
 
 	if (!dev->board.is_em2800) {
@@ -3071,7 +3074,7 @@ static int em28xx_init_dev(struct em28xx
 
 	if (dev->board.has_msp34xx) {
 		/* Send a reset to other chips via gpio */
-		retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+		retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
 		if (retval < 0) {
 			em28xx_errdev("%s: em28xx_write_reg - "
 				      "msp34xx(1) failed! error [%d]\n",
@@ -3080,7 +3083,7 @@ static int em28xx_init_dev(struct em28xx
 		}
 		msleep(3);
 
-		retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+		retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
 		if (retval < 0) {
 			em28xx_errdev("%s: em28xx_write_reg - "
 				      "msp34xx(2) failed! error [%d]\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-core.c linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-core.c
--- linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -193,23 +193,7 @@ int em28xx_write_regs_req(struct em28xx
 
 int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
 {
-	int rc;
-
-	rc = em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
-
-	/* Stores GPO/GPIO values at the cache, if changed
-	   Only write values should be stored, since input on a GPIO
-	   register will return the input bits.
-	   Not sure what happens on reading GPO register.
-	 */
-	if (rc >= 0) {
-		if (reg == dev->reg_gpo_num)
-			dev->reg_gpo = buf[0];
-		else if (reg == dev->reg_gpio_num)
-			dev->reg_gpio = buf[0];
-	}
-
-	return rc;
+	return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
 }
 EXPORT_SYMBOL_GPL(em28xx_write_regs);
 
@@ -231,14 +215,7 @@ int em28xx_write_reg_bits(struct em28xx
 	int oldval;
 	u8 newval;
 
-	/* Uses cache for gpo/gpio registers */
-	if (reg == dev->reg_gpo_num)
-		oldval = dev->reg_gpo;
-	else if (reg == dev->reg_gpio_num)
-		oldval = dev->reg_gpio;
-	else
-		oldval = em28xx_read_reg(dev, reg);
-
+	oldval = em28xx_read_reg(dev, reg);
 	if (oldval < 0)
 		return oldval;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-dvb.c linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-dvb.c
--- linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-dvb.c	2013-07-01 10:35:17.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-dvb.c	2013-08-31 17:54:48.000000000 -0400
@@ -421,23 +421,23 @@ static void hauppauge_hvr930c_init(struc
 	int i;
 
 	struct em28xx_reg_seq hauppauge_hvr930c_init[] = {
-		{EM2874_R80_GPIO,	0xff,	0xff,	0x65},
-		{EM2874_R80_GPIO,	0xfb,	0xff,	0x32},
-		{EM2874_R80_GPIO,	0xff,	0xff,	0xb8},
+		{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xfb,	0xff,	0x32},
+		{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	0xb8},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct em28xx_reg_seq hauppauge_hvr930c_end[] = {
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x01},
-		{EM2874_R80_GPIO,	0xaf,	0xff,	0x65},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x76},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x01},
-		{EM2874_R80_GPIO,	0xcf,	0xff,	0x0b},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x40},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x01},
+		{EM2874_R80_GPIO_P0_CTRL,	0xaf,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x76},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x01},
+		{EM2874_R80_GPIO_P0_CTRL,	0xcf,	0xff,	0x0b},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x40},
 
-		{EM2874_R80_GPIO,	0xcf,	0xff,	0x65},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x65},
-		{EM2874_R80_GPIO,	0xcf,	0xff,	0x0b},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xcf,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xcf,	0xff,	0x0b},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x65},
 
 		{ -1,                   -1,     -1,     -1},
 	};
@@ -487,16 +487,16 @@ static void terratec_h5_init(struct em28
 {
 	int i;
 	struct em28xx_reg_seq terratec_h5_init[] = {
-		{EM28XX_R08_GPIO,	0xff,	0xff,	10},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xf2,	0xff,	50},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	100},
+		{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf2,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct em28xx_reg_seq terratec_h5_end[] = {
-		{EM2874_R80_GPIO,	0xe6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xa6,	0xff,	50},
-		{EM2874_R80_GPIO,	0xe6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct {
@@ -543,15 +543,15 @@ static void terratec_htc_stick_init(stru
 	 * 0xb6: unknown (does not affect DVB-T).
 	 */
 	struct em28xx_reg_seq terratec_htc_stick_init[] = {
-		{EM28XX_R08_GPIO,	0xff,	0xff,	10},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xe6,	0xff,	50},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	100},
+		{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct em28xx_reg_seq terratec_htc_stick_end[] = {
-		{EM2874_R80_GPIO,	0xb6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xb6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	50},
 		{ -1,                   -1,     -1,     -1},
 	};
 
@@ -590,16 +590,16 @@ static void terratec_htc_usb_xs_init(str
 	int i;
 
 	struct em28xx_reg_seq terratec_htc_usb_xs_init[] = {
-		{EM28XX_R08_GPIO,	0xff,	0xff,	10},
-		{EM2874_R80_GPIO,	0xb2,	0xff,	100},
-		{EM2874_R80_GPIO,	0xb2,	0xff,	50},
-		{EM2874_R80_GPIO,	0xb6,	0xff,	100},
+		{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
+		{EM2874_R80_GPIO_P0_CTRL,	0xb2,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xb2,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xb6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct em28xx_reg_seq terratec_htc_usb_xs_end[] = {
-		{EM2874_R80_GPIO,	0xa6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xa6,	0xff,	50},
-		{EM2874_R80_GPIO,	0xe6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 
@@ -1216,6 +1216,7 @@ static int em28xx_dvb_init(struct em28xx
 			dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus],
 				&em28xx_a8293_config);
 		break;
+	case EM2874_BOARD_DELOCK_61959:
 	case EM2874_BOARD_MAXMEDIA_UB425_TC:
 		/* attach demodulator */
 		dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk,
@@ -1235,8 +1236,8 @@ static int em28xx_dvb_init(struct em28xx
 		}
 
 		/* TODO: we need drx-3913k firmware in order to support DVB-T */
-		em28xx_info("MaxMedia UB425-TC: only DVB-C supported by that " \
-				"driver version\n");
+		em28xx_info("MaxMedia UB425-TC/Delock 61959: only DVB-C " \
+				"supported by that driver version\n");
 
 		break;
 	case EM2884_BOARD_PCTV_510E:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx.h linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx.h
--- linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx.h	2013-08-25 20:43:22.000000000 -0400
@@ -130,6 +130,7 @@
 #define EM2884_BOARD_PCTV_520E			  86
 #define EM2884_BOARD_TERRATEC_HTC_USB_XS	  87
 #define EM2884_BOARD_C3TECH_DIGITAL_DUO		  88
+#define EM2874_BOARD_DELOCK_61959		  89
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
@@ -636,12 +637,6 @@ struct em28xx {
 
 	enum em28xx_mode mode;
 
-	/* register numbers for GPO/GPIO registers */
-	u16 reg_gpo_num, reg_gpio_num;
-
-	/* Caches GPO and GPIO registers */
-	unsigned char	reg_gpo, reg_gpio;
-
 	/* Snapshot button */
 	char snapshot_button_path[30];	/* path of the input dev */
 	struct input_dev *sbutton_input_dev;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-i2c.c linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-i2c.c
--- linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-i2c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -726,7 +726,7 @@ static int em28xx_i2c_eeprom(struct em28
 
 	*eedata = data;
 	*eedata_len = len;
-	dev_config = (void *)eedata;
+	dev_config = (void *)*eedata;
 
 	switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) {
 	case 0:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-input.c linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-input.c
--- linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-input.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-input.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@
 
 #define EM28XX_SNAPSHOT_KEY KEY_CAMERA
 #define EM28XX_SBUTTON_QUERY_INTERVAL 500
-#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20
 
 static unsigned int ir_debug;
 module_param(ir_debug, int, 0644);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-reg.h linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-reg.h
--- linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -49,8 +49,9 @@
 
 
 /* GPIO/GPO registers */
-#define EM2880_R04_GPO	0x04    /* em2880-em2883 only */
-#define EM28XX_R08_GPIO	0x08	/* em2820 or upper */
+#define EM2880_R04_GPO		0x04    /* em2880-em2883 only */
+#define EM2820_R08_GPIO_CTRL	0x08	/* em2820-em2873/83 only */
+#define EM2820_R09_GPIO_STATE	0x09	/* em2820-em2873/83 only */
 
 #define EM28XX_R06_I2C_CLK	0x06
 
@@ -67,7 +68,8 @@
 
 
 #define EM28XX_R0A_CHIPID	0x0a
-#define EM28XX_R0C_USBSUSP	0x0c	/* */
+#define EM28XX_R0C_USBSUSP	0x0c
+#define   EM28XX_R0C_USBSUSP_SNAPSHOT	0x20 /* 1=button pressed, needs reset */
 
 #define EM28XX_R0E_AUDIOSRC	0x0e
 #define EM28XX_R0F_XCLK	0x0f
@@ -193,7 +195,20 @@
 #define EM2874_R50_IR_CONFIG    0x50
 #define EM2874_R51_IR           0x51
 #define EM2874_R5F_TS_ENABLE    0x5f
-#define EM2874_R80_GPIO         0x80
+
+/* em2874/174/84, em25xx, em276x/7x/8x GPIO registers */
+/*
+ * NOTE: not all ports are bonded out;
+ * Some ports are multiplexed with special function I/O
+ */
+#define EM2874_R80_GPIO_P0_CTRL    0x80
+#define EM2874_R81_GPIO_P1_CTRL    0x81
+#define EM2874_R82_GPIO_P2_CTRL    0x82
+#define EM2874_R83_GPIO_P3_CTRL    0x83
+#define EM2874_R84_GPIO_P0_STATE   0x84
+#define EM2874_R85_GPIO_P1_STATE   0x85
+#define EM2874_R86_GPIO_P2_STATE   0x86
+#define EM2874_R87_GPIO_P3_STATE   0x87
 
 /* em2874 IR config register (0x50) */
 #define EM2874_IR_NEC           0x00
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-video.c linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-video.c
--- linux-libre-3.10-gnu/drivers/media/usb/em28xx/em28xx-video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/em28xx/em28xx-video.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,7 +41,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/msp3400.h>
 #include <media/tuner.h>
 
@@ -1309,28 +1308,6 @@ static int vidioc_s_frequency(struct fil
 	return 0;
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-	       struct v4l2_dbg_chip_ident *chip)
-{
-	struct em28xx_fh      *fh  = priv;
-	struct em28xx         *dev = fh->dev;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_BRIDGE) {
-		if (chip->match.addr > 1)
-			return -EINVAL;
-		return 0;
-	}
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int vidioc_g_chip_info(struct file *file, void *priv,
 	       struct v4l2_dbg_chip_info *chip)
@@ -1366,14 +1343,9 @@ static int vidioc_g_register(struct file
 	struct em28xx         *dev = fh->dev;
 	int ret;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_BRIDGE:
-		if (reg->match.addr > 1)
-			return -EINVAL;
-		if (!reg->match.addr)
-			break;
-		/* fall-through */
-	case V4L2_CHIP_MATCH_AC97:
+	if (reg->match.addr > 1)
+		return -EINVAL;
+	if (reg->match.addr) {
 		ret = em28xx_read_ac97(dev, reg->reg);
 		if (ret < 0)
 			return ret;
@@ -1381,15 +1353,6 @@ static int vidioc_g_register(struct file
 		reg->val = ret;
 		reg->size = 1;
 		return 0;
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* TODO: is this correct? */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	default:
-		return -EINVAL;
 	}
 
 	/* Match host */
@@ -1421,25 +1384,10 @@ static int vidioc_s_register(struct file
 	struct em28xx         *dev = fh->dev;
 	__le16 buf;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_BRIDGE:
-		if (reg->match.addr > 1)
-			return -EINVAL;
-		if (!reg->match.addr)
-			break;
-		/* fall-through */
-	case V4L2_CHIP_MATCH_AC97:
-		return em28xx_write_ac97(dev, reg->reg, reg->val);
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* TODO: is this correct? */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	default:
+	if (reg->match.addr > 1)
 		return -EINVAL;
-	}
+	if (reg->match.addr)
+		return em28xx_write_ac97(dev, reg->reg, reg->val);
 
 	/* Match host */
 	buf = cpu_to_le16(reg->val);
@@ -1795,7 +1743,6 @@ static const struct v4l2_ioctl_ops video
 	.vidioc_s_frequency         = vidioc_s_frequency,
 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident        = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_chip_info         = vidioc_g_chip_info,
 	.vidioc_g_register          = vidioc_g_register,
@@ -1826,7 +1773,6 @@ static const struct v4l2_ioctl_ops radio
 	.vidioc_s_frequency   = vidioc_s_frequency,
 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident  = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_chip_info   = vidioc_g_chip_info,
 	.vidioc_g_register    = vidioc_g_register,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/gspca/gspca.c linux-libre-3.11-rc7-gnu/drivers/media/usb/gspca/gspca.c
--- linux-libre-3.10-gnu/drivers/media/usb/gspca/gspca.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/gspca/gspca.c	2013-08-25 20:43:22.000000000 -0400
@@ -1029,33 +1029,35 @@ static int gspca_get_mode(struct gspca_d
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vidioc_g_register(struct file *file, void *priv,
-			struct v4l2_dbg_register *reg)
+static int vidioc_g_chip_info(struct file *file, void *priv,
+				struct v4l2_dbg_chip_info *chip)
 {
 	struct gspca_dev *gspca_dev = video_drvdata(file);
 
 	gspca_dev->usb_err = 0;
-	return gspca_dev->sd_desc->get_register(gspca_dev, reg);
+	if (gspca_dev->sd_desc->get_chip_info)
+		return gspca_dev->sd_desc->get_chip_info(gspca_dev, chip);
+	return chip->match.addr ? -EINVAL : 0;
 }
 
-static int vidioc_s_register(struct file *file, void *priv,
-			const struct v4l2_dbg_register *reg)
+static int vidioc_g_register(struct file *file, void *priv,
+		struct v4l2_dbg_register *reg)
 {
 	struct gspca_dev *gspca_dev = video_drvdata(file);
 
 	gspca_dev->usb_err = 0;
-	return gspca_dev->sd_desc->set_register(gspca_dev, reg);
+	return gspca_dev->sd_desc->get_register(gspca_dev, reg);
 }
-#endif
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-			struct v4l2_dbg_chip_ident *chip)
+static int vidioc_s_register(struct file *file, void *priv,
+		const struct v4l2_dbg_register *reg)
 {
 	struct gspca_dev *gspca_dev = video_drvdata(file);
 
 	gspca_dev->usb_err = 0;
-	return gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
+	return gspca_dev->sd_desc->set_register(gspca_dev, reg);
 }
+#endif
 
 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 				struct v4l2_fmtdesc *fmtdesc)
@@ -1974,10 +1976,10 @@ static const struct v4l2_ioctl_ops dev_i
 	.vidioc_enum_framesizes = vidioc_enum_framesizes,
 	.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info	= vidioc_g_chip_info,
 	.vidioc_g_register	= vidioc_g_register,
 	.vidioc_s_register	= vidioc_s_register,
 #endif
-	.vidioc_g_chip_ident	= vidioc_g_chip_ident,
 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
@@ -2086,14 +2088,10 @@ int gspca_dev_probe2(struct usb_interfac
 	v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_DQBUF);
 	v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QBUF);
 	v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QUERYBUF);
-	if (!gspca_dev->sd_desc->get_chip_ident)
-		v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_CHIP_IDENT);
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	if (!gspca_dev->sd_desc->get_chip_ident ||
-	    !gspca_dev->sd_desc->get_register)
+	if (!gspca_dev->sd_desc->get_register)
 		v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_REGISTER);
-	if (!gspca_dev->sd_desc->get_chip_ident ||
-	    !gspca_dev->sd_desc->set_register)
+	if (!gspca_dev->sd_desc->set_register)
 		v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_S_REGISTER);
 #endif
 	if (!gspca_dev->sd_desc->get_jcomp)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/gspca/gspca.h linux-libre-3.11-rc7-gnu/drivers/media/usb/gspca/gspca.h
--- linux-libre-3.10-gnu/drivers/media/usb/gspca/gspca.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/gspca/gspca.h	2013-08-25 20:43:22.000000000 -0400
@@ -78,8 +78,8 @@ typedef int (*cam_get_reg_op) (struct gs
 				struct v4l2_dbg_register *);
 typedef int (*cam_set_reg_op) (struct gspca_dev *,
 				const struct v4l2_dbg_register *);
-typedef int (*cam_ident_op) (struct gspca_dev *,
-				struct v4l2_dbg_chip_ident *);
+typedef int (*cam_chip_info_op) (struct gspca_dev *,
+				struct v4l2_dbg_chip_info *);
 typedef void (*cam_streamparm_op) (struct gspca_dev *,
 				  struct v4l2_streamparm *);
 typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
@@ -112,8 +112,8 @@ struct sd_desc {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	cam_set_reg_op set_register;
 	cam_get_reg_op get_register;
+	cam_chip_info_op get_chip_info;
 #endif
-	cam_ident_op get_chip_ident;
 #if IS_ENABLED(CONFIG_INPUT)
 	cam_int_pkt_op int_pkt_scan;
 	/* other_input makes the gspca core create gspca_dev->input even when
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/gspca/pac7302.c linux-libre-3.11-rc7-gnu/drivers/media/usb/gspca/pac7302.c
--- linux-libre-3.10-gnu/drivers/media/usb/gspca/pac7302.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/gspca/pac7302.c	2013-08-25 20:43:22.000000000 -0400
@@ -93,7 +93,6 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/input.h>
-#include <media/v4l2-chip-ident.h>
 #include "gspca.h"
 /* Include pac common sof detection functions */
 #include "pac_common.h"
@@ -849,8 +848,7 @@ static int sd_dbg_s_register(struct gspc
 	 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
 	 *		       long on the USB bus)
 	 */
-	if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
-	    reg->match.addr == 0 &&
+	if (reg->match.addr == 0 &&
 	    (reg->reg < 0x000000ff) &&
 	    (reg->val <= 0x000000ff)
 	) {
@@ -871,20 +869,6 @@ static int sd_dbg_s_register(struct gspc
 	}
 	return gspca_dev->usb_err;
 }
-
-static int sd_chip_ident(struct gspca_dev *gspca_dev,
-			struct v4l2_dbg_chip_ident *chip)
-{
-	int ret = -EINVAL;
-
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
-	    chip->match.addr == 0) {
-		chip->revision = 0;
-		chip->ident = V4L2_IDENT_UNKNOWN;
-		ret = 0;
-	}
-	return ret;
-}
 #endif
 
 #if IS_ENABLED(CONFIG_INPUT)
@@ -931,7 +915,6 @@ static const struct sd_desc sd_desc = {
 	.dq_callback = do_autogain,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.set_register = sd_dbg_s_register,
-	.get_chip_ident = sd_chip_ident,
 #endif
 #if IS_ENABLED(CONFIG_INPUT)
 	.int_pkt_scan = sd_int_pkt_scan,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/gspca/sn9c20x.c linux-libre-3.11-rc7-gnu/drivers/media/usb/gspca/sn9c20x.c
--- linux-libre-3.10-gnu/drivers/media/usb/gspca/sn9c20x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/gspca/sn9c20x.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,6 @@
 #include "gspca.h"
 #include "jpeg.h"
 
-#include <media/v4l2-chip-ident.h>
 #include <linux/dmi.h>
 
 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
@@ -582,22 +581,6 @@ static const s16 hsv_blue_y[] = {
 	4,   2,   0,  -1,  -3,  -5,  -7,  -9, -11
 };
 
-static const u16 i2c_ident[] = {
-	V4L2_IDENT_OV9650,
-	V4L2_IDENT_OV9655,
-	V4L2_IDENT_SOI968,
-	V4L2_IDENT_OV7660,
-	V4L2_IDENT_OV7670,
-	V4L2_IDENT_MT9V011,
-	V4L2_IDENT_MT9V111,
-	V4L2_IDENT_MT9V112,
-	V4L2_IDENT_MT9M001C12ST,
-	V4L2_IDENT_MT9M111,
-	V4L2_IDENT_MT9M112,
-	V4L2_IDENT_HV7131R,
-[SENSOR_MT9VPRB] = V4L2_IDENT_UNKNOWN,
-};
-
 static const u16 bridge_init[][2] = {
 	{0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
 	{0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
@@ -1574,21 +1557,19 @@ static int sd_dbg_g_register(struct gspc
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		if (reg->match.addr != 0)
-			return -EINVAL;
+	reg->size = 1;
+	switch (reg->match.addr) {
+	case 0:
 		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
 			return -EINVAL;
 		reg_r(gspca_dev, reg->reg, 1);
 		reg->val = gspca_dev->usb_buf[0];
 		return gspca_dev->usb_err;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		if (reg->match.addr != sd->i2c_addr)
-			return -EINVAL;
+	case 1:
 		if (sd->sensor >= SENSOR_MT9V011 &&
 		    sd->sensor <= SENSOR_MT9M112) {
 			i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
+			reg->size = 2;
 		} else {
 			i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
 		}
@@ -1602,17 +1583,13 @@ static int sd_dbg_s_register(struct gspc
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		if (reg->match.addr != 0)
-			return -EINVAL;
+	switch (reg->match.addr) {
+	case 0:
 		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
 			return -EINVAL;
 		reg_w1(gspca_dev, reg->reg, reg->val);
 		return gspca_dev->usb_err;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		if (reg->match.addr != sd->i2c_addr)
-			return -EINVAL;
+	case 1:
 		if (sd->sensor >= SENSOR_MT9V011 &&
 		    sd->sensor <= SENSOR_MT9M112) {
 			i2c_w2(gspca_dev, reg->reg, reg->val);
@@ -1623,29 +1600,17 @@ static int sd_dbg_s_register(struct gspc
 	}
 	return -EINVAL;
 }
-#endif
 
-static int sd_chip_ident(struct gspca_dev *gspca_dev,
-			struct v4l2_dbg_chip_ident *chip)
+static int sd_chip_info(struct gspca_dev *gspca_dev,
+			struct v4l2_dbg_chip_info *chip)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	switch (chip->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		if (chip->match.addr != 0)
-			return -EINVAL;
-		chip->revision = 0;
-		chip->ident = V4L2_IDENT_SN9C20X;
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		if (chip->match.addr != sd->i2c_addr)
-			return -EINVAL;
-		chip->revision = 0;
-		chip->ident = i2c_ident[sd->sensor];
-		return 0;
-	}
-	return -EINVAL;
+	if (chip->match.addr > 1)
+		return -EINVAL;
+	if (chip->match.addr == 1)
+		strlcpy(chip->name, "sensor", sizeof(chip->name));
+	return 0;
 }
+#endif
 
 static int sd_config(struct gspca_dev *gspca_dev,
 			const struct usb_device_id *id)
@@ -2356,8 +2321,8 @@ static const struct sd_desc sd_desc = {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.set_register = sd_dbg_s_register,
 	.get_register = sd_dbg_g_register,
+	.get_chip_info = sd_chip_info,
 #endif
-	.get_chip_ident = sd_chip_ident,
 };
 
 #define SN9C20X(sensor, i2c_addr, flags) \
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/hdpvr/hdpvr-control.c linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/hdpvr-control.c
--- linux-libre-3.10-gnu/drivers/media/usb/hdpvr/hdpvr-control.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/hdpvr-control.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,20 +45,11 @@ int hdpvr_config_call(struct hdpvr_devic
 	return ret < 0 ? ret : 0;
 }
 
-struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
+int get_video_info(struct hdpvr_device *dev, struct hdpvr_video_info *vidinf)
 {
-	struct hdpvr_video_info *vidinf = NULL;
-#ifdef HDPVR_DEBUG
-	char print_buf[15];
-#endif
 	int ret;
 
-	vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
-	if (!vidinf) {
-		v4l2_err(&dev->v4l2_dev, "out of memory\n");
-		goto err;
-	}
-
+	vidinf->valid = false;
 	mutex_lock(&dev->usbc_mutex);
 	ret = usb_control_msg(dev->udev,
 			      usb_rcvctrlpipe(dev->udev, 0),
@@ -66,14 +57,10 @@ struct hdpvr_video_info *get_video_info(
 			      0x1400, 0x0003,
 			      dev->usbc_buf, 5,
 			      1000);
-	if (ret == 5) {
-		vidinf->width	= dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
-		vidinf->height	= dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
-		vidinf->fps	= dev->usbc_buf[4];
-	}
 
 #ifdef HDPVR_DEBUG
 	if (hdpvr_debug & MSG_INFO) {
+		char print_buf[15];
 		hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,
 				   sizeof(print_buf), 0);
 		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
@@ -82,12 +69,15 @@ struct hdpvr_video_info *get_video_info(
 #endif
 	mutex_unlock(&dev->usbc_mutex);
 
-	if (!vidinf->width || !vidinf->height || !vidinf->fps) {
-		kfree(vidinf);
-		vidinf = NULL;
-	}
-err:
-	return vidinf;
+	if (ret < 0)
+		return ret;
+
+	vidinf->width	= dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
+	vidinf->height	= dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
+	vidinf->fps	= dev->usbc_buf[4];
+	vidinf->valid   = vidinf->width && vidinf->height && vidinf->fps;
+
+	return 0;
 }
 
 int get_input_lines_info(struct hdpvr_device *dev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/hdpvr/hdpvr-core.c linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/hdpvr-core.c
--- linux-libre-3.10-gnu/drivers/media/usb/hdpvr/hdpvr-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/hdpvr-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -220,7 +220,6 @@ static int hdpvr_device_init(struct hdpv
 {
 	int ret;
 	u8 *buf;
-	struct hdpvr_video_info *vidinf;
 
 	if (device_authorization(dev))
 		return -EACCES;
@@ -242,13 +241,6 @@ static int hdpvr_device_init(struct hdpv
 		 "control request returned %d\n", ret);
 	mutex_unlock(&dev->usbc_mutex);
 
-	vidinf = get_video_info(dev);
-	if (!vidinf)
-		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
-			"no valid video signal or device init failed\n");
-	else
-		kfree(vidinf);
-
 	/* enable fan and bling leds */
 	mutex_lock(&dev->usbc_mutex);
 	buf[0] = 0x1;
@@ -311,6 +303,11 @@ static int hdpvr_probe(struct usb_interf
 
 	dev->workqueue = 0;
 
+	/* init video transfer queues first of all */
+	/* to prevent oops in hdpvr_delete() on error paths */
+	INIT_LIST_HEAD(&dev->free_buff_list);
+	INIT_LIST_HEAD(&dev->rec_buff_list);
+
 	/* register v4l2_device early so it can be used for printks */
 	if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
 		dev_err(&interface->dev, "v4l2_device_register failed\n");
@@ -333,10 +330,6 @@ static int hdpvr_probe(struct usb_interf
 	if (!dev->workqueue)
 		goto error;
 
-	/* init video transfer queues */
-	INIT_LIST_HEAD(&dev->free_buff_list);
-	INIT_LIST_HEAD(&dev->rec_buff_list);
-
 	dev->options = hdpvr_default_options;
 
 	if (default_video_input < HDPVR_VIDEO_INPUTS)
@@ -413,7 +406,7 @@ static int hdpvr_probe(struct usb_interf
 				    video_nr[atomic_inc_return(&dev_nr)]);
 	if (retval < 0) {
 		v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
-		goto error;
+		goto reg_fail;
 	}
 
 	/* let the user know what node this device is now attached to */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/hdpvr/hdpvr.h linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/hdpvr.h
--- linux-libre-3.10-gnu/drivers/media/usb/hdpvr/hdpvr.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/hdpvr.h	2013-08-25 20:43:22.000000000 -0400
@@ -154,6 +154,7 @@ struct hdpvr_video_info {
 	u16	width;
 	u16	height;
 	u8	fps;
+	bool	valid;
 };
 
 enum {
@@ -303,7 +304,7 @@ int hdpvr_set_audio(struct hdpvr_device
 int hdpvr_config_call(struct hdpvr_device *dev, uint value,
 		      unsigned char valbuf);
 
-struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev);
+int get_video_info(struct hdpvr_device *dev, struct hdpvr_video_info *vid_info);
 
 /* :0 s b8 81 1800 0003 0003 3 < */
 /* :0 0 3 = 0301ff */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/hdpvr/hdpvr-video.c linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/hdpvr-video.c
--- linux-libre-3.10-gnu/drivers/media/usb/hdpvr/hdpvr-video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/hdpvr-video.c	2013-08-25 20:43:22.000000000 -0400
@@ -277,44 +277,50 @@ error:
 static int hdpvr_start_streaming(struct hdpvr_device *dev)
 {
 	int ret;
-	struct hdpvr_video_info *vidinf;
+	struct hdpvr_video_info vidinf;
 
 	if (dev->status == STATUS_STREAMING)
 		return 0;
-	else if (dev->status != STATUS_IDLE)
+	if (dev->status != STATUS_IDLE)
 		return -EAGAIN;
 
-	vidinf = get_video_info(dev);
+	ret = get_video_info(dev, &vidinf);
+	if (ret < 0)
+		return ret;
 
-	if (vidinf) {
-		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
-			 "video signal: %dx%d@%dhz\n", vidinf->width,
-			 vidinf->height, vidinf->fps);
-		kfree(vidinf);
+	if (!vidinf.valid) {
+		msleep(250);
+		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+				"no video signal at input %d\n", dev->options.video_input);
+		return -EAGAIN;
+	}
 
-		/* start streaming 2 request */
-		ret = usb_control_msg(dev->udev,
-				      usb_sndctrlpipe(dev->udev, 0),
-				      0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
-		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
-			 "encoder start control request returned %d\n", ret);
+	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			"video signal: %dx%d@%dhz\n", vidinf.width,
+			vidinf.height, vidinf.fps);
 
-		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
+	/* start streaming 2 request */
+	ret = usb_control_msg(dev->udev,
+			usb_sndctrlpipe(dev->udev, 0),
+			0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
+	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			"encoder start control request returned %d\n", ret);
+	if (ret < 0)
+		return ret;
 
-		dev->status = STATUS_STREAMING;
+	ret = hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
+	if (ret)
+		return ret;
 
-		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
-		queue_work(dev->workqueue, &dev->worker);
+	dev->status = STATUS_STREAMING;
 
-		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
-			 "streaming started\n");
+	INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
+	queue_work(dev->workqueue, &dev->worker);
 
-		return 0;
-	}
-	msleep(250);
-	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
-		 "no video signal at input %d\n", dev->options.video_input);
-	return -EAGAIN;
+	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			"streaming started\n");
+
+	return 0;
 }
 
 
@@ -606,22 +612,20 @@ static int vidioc_g_std(struct file *fil
 static int vidioc_querystd(struct file *file, void *_fh, v4l2_std_id *a)
 {
 	struct hdpvr_device *dev = video_drvdata(file);
-	struct hdpvr_video_info *vid_info;
+	struct hdpvr_video_info vid_info;
 	struct hdpvr_fh *fh = _fh;
+	int ret;
 
-	*a = V4L2_STD_ALL;
+	*a = V4L2_STD_UNKNOWN;
 	if (dev->options.video_input == HDPVR_COMPONENT)
 		return fh->legacy_mode ? 0 : -ENODATA;
-	vid_info = get_video_info(dev);
-	if (vid_info == NULL)
-		return 0;
-	if (vid_info->width == 720 &&
-	    (vid_info->height == 480 || vid_info->height == 576)) {
-		*a = (vid_info->height == 480) ?
+	ret = get_video_info(dev, &vid_info);
+	if (vid_info.valid && vid_info.width == 720 &&
+	    (vid_info.height == 480 || vid_info.height == 576)) {
+		*a = (vid_info.height == 480) ?
 			V4L2_STD_525_60 : V4L2_STD_625_50;
 	}
-	kfree(vid_info);
-	return 0;
+	return ret;
 }
 
 static int vidioc_s_dv_timings(struct file *file, void *_fh,
@@ -665,7 +669,7 @@ static int vidioc_query_dv_timings(struc
 {
 	struct hdpvr_device *dev = video_drvdata(file);
 	struct hdpvr_fh *fh = _fh;
-	struct hdpvr_video_info *vid_info;
+	struct hdpvr_video_info vid_info;
 	bool interlaced;
 	int ret = 0;
 	int i;
@@ -673,10 +677,12 @@ static int vidioc_query_dv_timings(struc
 	fh->legacy_mode = false;
 	if (dev->options.video_input)
 		return -ENODATA;
-	vid_info = get_video_info(dev);
-	if (vid_info == NULL)
+	ret = get_video_info(dev, &vid_info);
+	if (ret)
+		return ret;
+	if (!vid_info.valid)
 		return -ENOLCK;
-	interlaced = vid_info->fps <= 30;
+	interlaced = vid_info.fps <= 30;
 	for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++) {
 		const struct v4l2_bt_timings *bt = &hdpvr_dv_timings[i].bt;
 		unsigned hsize;
@@ -688,17 +694,17 @@ static int vidioc_query_dv_timings(struc
 			bt->il_vfrontporch + bt->il_vsync + bt->il_vbackporch +
 			bt->height;
 		fps = (unsigned)bt->pixelclock / (hsize * vsize);
-		if (bt->width != vid_info->width ||
-		    bt->height != vid_info->height ||
+		if (bt->width != vid_info.width ||
+		    bt->height != vid_info.height ||
 		    bt->interlaced != interlaced ||
-		    (fps != vid_info->fps && fps + 1 != vid_info->fps))
+		    (fps != vid_info.fps && fps + 1 != vid_info.fps))
 			continue;
 		*timings = hdpvr_dv_timings[i];
 		break;
 	}
 	if (i == ARRAY_SIZE(hdpvr_dv_timings))
 		ret = -ERANGE;
-	kfree(vid_info);
+
 	return ret;
 }
 
@@ -988,6 +994,7 @@ static int vidioc_g_fmt_vid_cap(struct f
 {
 	struct hdpvr_device *dev = video_drvdata(file);
 	struct hdpvr_fh *fh = _fh;
+	int ret;
 
 	/*
 	 * The original driver would always returns the current detected
@@ -1000,14 +1007,15 @@ static int vidioc_g_fmt_vid_cap(struct f
 	 * last set format.
 	 */
 	if (fh->legacy_mode) {
-		struct hdpvr_video_info *vid_info;
+		struct hdpvr_video_info vid_info;
 
-		vid_info = get_video_info(dev);
-		if (!vid_info)
+		ret = get_video_info(dev, &vid_info);
+		if (ret < 0)
+			return ret;
+		if (!vid_info.valid)
 			return -EFAULT;
-		f->fmt.pix.width = vid_info->width;
-		f->fmt.pix.height = vid_info->height;
-		kfree(vid_info);
+		f->fmt.pix.width = vid_info.width;
+		f->fmt.pix.height = vid_info.height;
 	} else {
 		f->fmt.pix.width = dev->width;
 		f->fmt.pix.height = dev->height;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/hdpvr/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/Kconfig
--- linux-libre-3.10-gnu/drivers/media/usb/hdpvr/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/hdpvr/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 
 config VIDEO_HDPVR
 	tristate "Hauppauge HD PVR support"
-	depends on VIDEO_DEV
+	depends on VIDEO_DEV && VIDEO_V4L2
 	---help---
 	  This is a video4linux driver for Hauppauge's HD PVR USB device.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/usb/Kconfig
--- linux-libre-3.10-gnu/drivers/media/usb/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,7 @@
+if USB && MEDIA_SUPPORT
+
 menuconfig MEDIA_USB_SUPPORT
 	bool "Media USB Adapters"
-	depends on USB && MEDIA_SUPPORT
 	help
 	  Enable media drivers for USB bus.
 	  If you have such devices, say Y.
@@ -17,6 +18,7 @@ source "drivers/media/usb/zr364xx/Kconfi
 source "drivers/media/usb/stkwebcam/Kconfig"
 source "drivers/media/usb/s2255/Kconfig"
 source "drivers/media/usb/sn9c102/Kconfig"
+source "drivers/media/usb/usbtv/Kconfig"
 endif
 
 if MEDIA_ANALOG_TV_SUPPORT
@@ -52,3 +54,4 @@ source "drivers/media/usb/em28xx/Kconfig
 endif
 
 endif #MEDIA_USB_SUPPORT
+endif #USB
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/Makefile linux-libre-3.11-rc7-gnu/drivers/media/usb/Makefile
--- linux-libre-3.10-gnu/drivers/media/usb/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -20,3 +20,4 @@ obj-$(CONFIG_VIDEO_STK1160) += stk1160/
 obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
 obj-$(CONFIG_VIDEO_TM6000) += tm6000/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
+obj-$(CONFIG_VIDEO_USBTV) += usbtv/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/pvrusb2/pvrusb2-hdw.c linux-libre-3.11-rc7-gnu/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
--- linux-libre-3.10-gnu/drivers/media/usb/pvrusb2/pvrusb2-hdw.c	2013-07-01 10:35:21.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/pvrusb2/pvrusb2-hdw.c	2013-08-31 17:54:52.000000000 -0400
@@ -2704,6 +2704,10 @@ static void pvr2_hdw_remove_usb_stuff(st
 	pvr2_hdw_render_useless(hdw);
 }
 
+void pvr2_hdw_set_v4l2_dev(struct pvr2_hdw *hdw, struct video_device *vdev)
+{
+	vdev->v4l2_dev = &hdw->v4l2_dev;
+}
 
 /* Destroy hardware interaction structure */
 void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
@@ -5162,41 +5166,3 @@ static int pvr2_hdw_get_eeprom_addr(stru
 	} while(0); LOCK_GIVE(hdw->ctl_lock);
 	return result;
 }
-
-
-int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
-			     const struct v4l2_dbg_match *match, u64 reg_id,
-			     int setFl, u64 *val_ptr)
-{
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	struct v4l2_dbg_register req;
-	int stat = 0;
-	int okFl = 0;
-
-	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
-
-	req.match = *match;
-	req.reg = reg_id;
-	if (setFl) req.val = *val_ptr;
-	/* It would be nice to know if a sub-device answered the request */
-	v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req);
-	if (!setFl) *val_ptr = req.val;
-	if (okFl) {
-		return stat;
-	}
-	return -EINVAL;
-#else
-	return -ENOSYS;
-#endif
-}
-
-
-/*
-  Stuff for Emacs to see, in order to encourage consistent editing style:
-  *** Local Variables: ***
-  *** mode: c ***
-  *** fill-column: 75 ***
-  *** tab-width: 8 ***
-  *** c-basic-offset: 8 ***
-  *** End: ***
-  */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/pvrusb2/pvrusb2-hdw.h linux-libre-3.11-rc7-gnu/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
--- linux-libre-3.10-gnu/drivers/media/usb/pvrusb2/pvrusb2-hdw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/pvrusb2/pvrusb2-hdw.h	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@
 
 #include <linux/usb.h>
 #include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
 #include "pvrusb2-io.h"
 #include "pvrusb2-ctrl.h"
 
@@ -138,6 +139,9 @@ const char *pvr2_hdw_get_device_identifi
 /* Called when hardware has been unplugged */
 void pvr2_hdw_disconnect(struct pvr2_hdw *);
 
+/* Sets v4l2_dev of a video_device struct */
+void pvr2_hdw_set_v4l2_dev(struct pvr2_hdw *, struct video_device *);
+
 /* Get the number of defined controls */
 unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *);
 
@@ -234,15 +238,6 @@ int pvr2_hdw_v4l_get_minor_number(struct
 void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
 				     enum pvr2_v4l_type index,int);
 
-/* Direct read/write access to chip's registers:
-   match - specify criteria to identify target chip (this is a v4l dbg struct)
-   reg_id  - register number to access
-   setFl   - true to set the register, false to read it
-   val_ptr - storage location for source / result. */
-int pvr2_hdw_register_access(struct pvr2_hdw *,
-			     const struct v4l2_dbg_match *match, u64 reg_id,
-			     int setFl, u64 *val_ptr);
-
 /* The following entry points are all lower level things you normally don't
    want to worry about. */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/pvrusb2/pvrusb2-io.c linux-libre-3.11-rc7-gnu/drivers/media/usb/pvrusb2/pvrusb2-io.c
--- linux-libre-3.10-gnu/drivers/media/usb/pvrusb2/pvrusb2-io.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/pvrusb2/pvrusb2-io.c	2013-08-25 20:43:22.000000000 -0400
@@ -354,9 +354,9 @@ static int pvr2_stream_buffer_count(stru
 		if (scnt < sp->buffer_slot_count) {
 			struct pvr2_buffer **nb = NULL;
 			if (scnt) {
-				nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
+				nb = kmemdup(sp->buffers, scnt * sizeof(*nb),
+					     GFP_KERNEL);
 				if (!nb) return -ENOMEM;
-				memcpy(nb,sp->buffers,scnt * sizeof(*nb));
 			}
 			kfree(sp->buffers);
 			sp->buffers = nb;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c linux-libre-3.11-rc7-gnu/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
--- linux-libre-3.10-gnu/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/videodev2.h>
 #include <linux/module.h>
 #include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 
@@ -800,36 +801,6 @@ static int pvr2_log_status(struct file *
 	return 0;
 }
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int pvr2_g_register(struct file *file, void *priv, struct v4l2_dbg_register *req)
-{
-	struct pvr2_v4l2_fh *fh = file->private_data;
-	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-	u64 val;
-	int ret;
-
-	ret = pvr2_hdw_register_access(
-			hdw, &req->match, req->reg,
-			0, &val);
-	req->val = val;
-	return ret;
-}
-
-static int pvr2_s_register(struct file *file, void *priv, const struct v4l2_dbg_register *req)
-{
-	struct pvr2_v4l2_fh *fh = file->private_data;
-	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-	u64 val;
-	int ret;
-
-	val = req->val;
-	ret = pvr2_hdw_register_access(
-			hdw, &req->match, req->reg,
-			1, &val);
-	return ret;
-}
-#endif
-
 static const struct v4l2_ioctl_ops pvr2_ioctl_ops = {
 	.vidioc_querycap		    = pvr2_querycap,
 	.vidioc_g_priority		    = pvr2_g_priority,
@@ -864,10 +835,6 @@ static const struct v4l2_ioctl_ops pvr2_
 	.vidioc_g_ext_ctrls		    = pvr2_g_ext_ctrls,
 	.vidioc_s_ext_ctrls		    = pvr2_s_ext_ctrls,
 	.vidioc_try_ext_ctrls		    = pvr2_try_ext_ctrls,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register		    = pvr2_g_register,
-	.vidioc_s_register		    = pvr2_s_register,
-#endif
 };
 
 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
@@ -904,8 +871,8 @@ static void pvr2_v4l2_dev_destroy(struct
 static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
 {
 	if (!dip) return;
-	if (!dip->devbase.parent) return;
-	dip->devbase.parent = NULL;
+	if (!dip->devbase.v4l2_dev->dev) return;
+	dip->devbase.v4l2_dev->dev = NULL;
 	device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
 }
 
@@ -1298,7 +1265,6 @@ static void pvr2_v4l2_dev_init(struct pv
 			       struct pvr2_v4l2 *vp,
 			       int v4l_type)
 {
-	struct usb_device *usbdev;
 	int mindevnum;
 	int unit_number;
 	struct pvr2_hdw *hdw;
@@ -1306,7 +1272,6 @@ static void pvr2_v4l2_dev_init(struct pv
 	dip->v4lp = vp;
 
 	hdw = vp->channel.mc_head->hdw;
-	usbdev = pvr2_hdw_get_dev(hdw);
 	dip->v4l_type = v4l_type;
 	switch (v4l_type) {
 	case VFL_TYPE_GRABBER:
@@ -1355,7 +1320,7 @@ static void pvr2_v4l2_dev_init(struct pv
 	if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
 		mindevnum = nr_ptr[unit_number];
 	}
-	dip->devbase.parent = &usbdev->dev;
+	pvr2_hdw_set_v4l2_dev(hdw, &dip->devbase);
 	if ((video_register_device(&dip->devbase,
 				   dip->v4l_type, mindevnum) < 0) &&
 	    (video_register_device(&dip->devbase,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/sn9c102/sn9c102_core.c linux-libre-3.11-rc7-gnu/drivers/media/usb/sn9c102/sn9c102_core.c
--- linux-libre-3.10-gnu/drivers/media/usb/sn9c102/sn9c102_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/sn9c102/sn9c102_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -1737,6 +1737,7 @@ static void sn9c102_release_resources(st
 	    video_device_node_name(cam->v4ldev));
 	video_set_drvdata(cam->v4ldev, NULL);
 	video_unregister_device(cam->v4ldev);
+	v4l2_device_unregister(&cam->v4l2_dev);
 	usb_put_dev(cam->usbdev);
 	kfree(cam->control_buffer);
 	kfree(cam);
@@ -3254,6 +3255,13 @@ sn9c102_usb_probe(struct usb_interface*
 
 	cam->usbdev = udev;
 
+	/* register v4l2_device early so it can be used for printks */
+	if (v4l2_device_register(&intf->dev, &cam->v4l2_dev)) {
+		dev_err(&intf->dev, "v4l2_device_register failed\n");
+		err = -ENOMEM;
+		goto fail;
+	}
+
 	if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
 		DBG(1, "kzalloc() failed");
 		err = -ENOMEM;
@@ -3325,7 +3333,7 @@ sn9c102_usb_probe(struct usb_interface*
 	strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
 	cam->v4ldev->fops = &sn9c102_fops;
 	cam->v4ldev->release = video_device_release;
-	cam->v4ldev->parent = &udev->dev;
+	cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
 
 	init_completion(&cam->probe);
 
@@ -3377,6 +3385,7 @@ fail:
 		kfree(cam->control_buffer);
 		if (cam->v4ldev)
 			video_device_release(cam->v4ldev);
+		v4l2_device_unregister(&cam->v4l2_dev);
 		kfree(cam);
 	}
 	return err;
@@ -3407,6 +3416,8 @@ static void sn9c102_usb_disconnect(struc
 
 	wake_up_interruptible_all(&cam->wait_open);
 
+	v4l2_device_disconnect(&cam->v4l2_dev);
+
 	kref_put(&cam->kref, sn9c102_release_resources);
 
 	up_write(&sn9c102_dev_lock);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/sn9c102/sn9c102.h linux-libre-3.11-rc7-gnu/drivers/media/usb/sn9c102/sn9c102.h
--- linux-libre-3.10-gnu/drivers/media/usb/sn9c102/sn9c102.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/sn9c102/sn9c102.h	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
@@ -100,6 +101,8 @@ static DECLARE_RWSEM(sn9c102_dev_lock);
 struct sn9c102_device {
 	struct video_device* v4ldev;
 
+	struct v4l2_device v4l2_dev;
+
 	enum sn9c102_bridge bridge;
 	struct sn9c102_sensor sensor;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/stk1160/stk1160-v4l.c linux-libre-3.11-rc7-gnu/drivers/media/usb/stk1160/stk1160-v4l.c
--- linux-libre-3.10-gnu/drivers/media/usb/stk1160/stk1160-v4l.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/stk1160/stk1160-v4l.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,7 +31,6 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-fh.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/videobuf2-vmalloc.h>
 
 #include <media/saa7115.h>
@@ -454,19 +453,6 @@ static int vidioc_s_input(struct file *f
 	return 0;
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-	       struct v4l2_dbg_chip_ident *chip)
-{
-	switch (chip->match.type) {
-	case V4L2_CHIP_MATCH_BRIDGE:
-		chip->ident = V4L2_IDENT_NONE;
-		chip->revision = 0;
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int vidioc_g_register(struct file *file, void *priv,
 			     struct v4l2_dbg_register *reg)
@@ -475,19 +461,6 @@ static int vidioc_g_register(struct file
 	int rc;
 	u8 val;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* TODO: is this correct? */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
-	}
-
 	/* Match host */
 	rc = stk1160_read_reg(dev, reg->reg, &val);
 	reg->val = val;
@@ -501,19 +474,6 @@ static int vidioc_s_register(struct file
 {
 	struct stk1160 *dev = video_drvdata(file);
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* TODO: is this correct? */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
-	}
-
 	/* Match host */
 	return stk1160_write_reg(dev, reg->reg, cpu_to_le16(reg->val));
 }
@@ -543,7 +503,6 @@ static const struct v4l2_ioctl_ops stk11
 	.vidioc_log_status  = v4l2_ctrl_log_status,
 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident = vidioc_g_chip_ident,
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register = vidioc_g_register,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/tm6000/tm6000-cards.c linux-libre-3.11-rc7-gnu/drivers/media/usb/tm6000/tm6000-cards.c
--- linux-libre-3.10-gnu/drivers/media/usb/tm6000/tm6000-cards.c	2013-07-01 10:32:45.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/tm6000/tm6000-cards.c	2013-08-31 17:52:15.000000000 -0400
@@ -1114,7 +1114,7 @@ static int tm6000_init_dev(struct tm6000
 	/* Default values for STD and resolutions */
 	dev->width = 720;
 	dev->height = 480;
-	dev->norm = V4L2_STD_PAL_M;
+	dev->norm = V4L2_STD_NTSC_M;
 
 	/* Configure tuner */
 	tm6000_config_tuner(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/tm6000/tm6000-video.c linux-libre-3.11-rc7-gnu/drivers/media/usb/tm6000/tm6000-video.c
--- linux-libre-3.10-gnu/drivers/media/usb/tm6000/tm6000-video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/tm6000/tm6000-video.c	2013-08-25 20:43:22.000000000 -0400
@@ -1076,6 +1076,15 @@ static int vidioc_s_std(struct file *fil
 	return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+	struct tm6000_fh *fh = priv;
+	struct tm6000_core *dev = fh->dev;
+
+	*norm = dev->norm;
+	return 0;
+}
+
 static const char *iname[] = {
 	[TM6000_INPUT_TV] = "Television",
 	[TM6000_INPUT_COMPOSITE1] = "Composite 1",
@@ -1134,7 +1143,7 @@ static int vidioc_s_input(struct file *f
 
 	dev->input = i;
 
-	rc = vidioc_s_std(file, priv, dev->vfd->current_norm);
+	rc = vidioc_s_std(file, priv, dev->norm);
 
 	return rc;
 }
@@ -1547,6 +1556,7 @@ static const struct v4l2_ioctl_ops video
 	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
 	.vidioc_s_std             = vidioc_s_std,
+	.vidioc_g_std             = vidioc_g_std,
 	.vidioc_enum_input        = vidioc_enum_input,
 	.vidioc_g_input           = vidioc_g_input,
 	.vidioc_s_input           = vidioc_s_input,
@@ -1570,7 +1580,6 @@ static struct video_device tm6000_templa
 	.ioctl_ops      = &video_ioctl_ops,
 	.release	= video_device_release,
 	.tvnorms        = TM6000_STD,
-	.current_norm   = V4L2_STD_NTSC_M,
 };
 
 static const struct v4l2_file_operations radio_fops = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c linux-libre-3.11-rc7-gnu/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
--- linux-libre-3.10-gnu/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c	2013-07-01 10:34:37.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c	2013-08-31 17:54:07.000000000 -0400
@@ -1768,6 +1768,8 @@ err_i2c_del_adapter:
 	i2c_del_adapter(&ttusb->i2c_adap);
 err_unregister_adapter:
 	dvb_unregister_adapter (&ttusb->adapter);
+	ttusb_free_iso_urbs(ttusb);
+	kfree(ttusb);
 	return result;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/usbtv/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/usb/usbtv/Kconfig
--- linux-libre-3.10-gnu/drivers/media/usb/usbtv/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/usbtv/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+config VIDEO_USBTV
+        tristate "USBTV007 video capture support"
+        depends on VIDEO_V4L2
+        select VIDEOBUF2_VMALLOC
+
+        ---help---
+          This is a video4linux2 driver for USBTV007 based video capture devices.
+
+          To compile this driver as a module, choose M here: the
+          module will be called usbtv
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/usbtv/Makefile linux-libre-3.11-rc7-gnu/drivers/media/usb/usbtv/Makefile
--- linux-libre-3.10-gnu/drivers/media/usb/usbtv/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/usbtv/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_USBTV) += usbtv.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/usbtv/usbtv.c linux-libre-3.11-rc7-gnu/drivers/media/usb/usbtv/usbtv.c
--- linux-libre-3.10-gnu/drivers/media/usb/usbtv/usbtv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/usbtv/usbtv.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,721 @@
+/*
+ * Fushicai USBTV007 Video Grabber Driver
+ *
+ * Product web site:
+ * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
+ *
+ * Following LWN articles were very useful in construction of this driver:
+ * Video4Linux2 API series: http://lwn.net/Articles/203924/
+ * videobuf2 API explanation: http://lwn.net/Articles/447435/
+ * Thanks go to Jonathan Corbet for providing this quality documentation.
+ * He is awesome.
+ *
+ * Copyright (c) 2013 Lubomir Rintel
+ * All rights reserved.
+ * No physical hardware was harmed running Windows during the
+ * reverse-engineering activity
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h>
+
+/* Hardware. */
+#define USBTV_VIDEO_ENDP	0x81
+#define USBTV_BASE		0xc000
+#define USBTV_REQUEST_REG	12
+
+/* Number of concurrent isochronous urbs submitted.
+ * Higher numbers was seen to overly saturate the USB bus. */
+#define USBTV_ISOC_TRANSFERS	16
+#define USBTV_ISOC_PACKETS	8
+
+#define USBTV_WIDTH		720
+#define USBTV_HEIGHT		480
+
+#define USBTV_CHUNK_SIZE	256
+#define USBTV_CHUNK		240
+#define USBTV_CHUNKS		(USBTV_WIDTH * USBTV_HEIGHT \
+					/ 4 / USBTV_CHUNK)
+
+/* Chunk header. */
+#define USBTV_MAGIC_OK(chunk)	((be32_to_cpu(chunk[0]) & 0xff000000) \
+							== 0x88000000)
+#define USBTV_FRAME_ID(chunk)	((be32_to_cpu(chunk[0]) & 0x00ff0000) >> 16)
+#define USBTV_ODD(chunk)	((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15)
+#define USBTV_CHUNK_NO(chunk)	(be32_to_cpu(chunk[0]) & 0x00000fff)
+
+/* A single videobuf2 frame buffer. */
+struct usbtv_buf {
+	struct vb2_buffer vb;
+	struct list_head list;
+};
+
+/* Per-device structure. */
+struct usbtv {
+	struct device *dev;
+	struct usb_device *udev;
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	struct vb2_queue vb2q;
+	struct mutex v4l2_lock;
+	struct mutex vb2q_lock;
+
+	/* List of videobuf2 buffers protected by a lock. */
+	spinlock_t buflock;
+	struct list_head bufs;
+
+	/* Number of currently processed frame, useful find
+	 * out when a new one begins. */
+	u32 frame_id;
+	int chunks_done;
+
+	int iso_size;
+	unsigned int sequence;
+	struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
+};
+
+static int usbtv_setup_capture(struct usbtv *usbtv)
+{
+	int ret;
+	int pipe = usb_rcvctrlpipe(usbtv->udev, 0);
+	int i;
+	static const u16 protoregs[][2] = {
+		/* These seem to enable the device. */
+		{ USBTV_BASE + 0x0008, 0x0001 },
+		{ USBTV_BASE + 0x01d0, 0x00ff },
+		{ USBTV_BASE + 0x01d9, 0x0002 },
+
+		/* These seem to influence color parameters, such as
+		 * brightness, etc. */
+		{ USBTV_BASE + 0x0239, 0x0040 },
+		{ USBTV_BASE + 0x0240, 0x0000 },
+		{ USBTV_BASE + 0x0241, 0x0000 },
+		{ USBTV_BASE + 0x0242, 0x0002 },
+		{ USBTV_BASE + 0x0243, 0x0080 },
+		{ USBTV_BASE + 0x0244, 0x0012 },
+		{ USBTV_BASE + 0x0245, 0x0090 },
+		{ USBTV_BASE + 0x0246, 0x0000 },
+
+		{ USBTV_BASE + 0x0278, 0x002d },
+		{ USBTV_BASE + 0x0279, 0x000a },
+		{ USBTV_BASE + 0x027a, 0x0032 },
+		{ 0xf890, 0x000c },
+		{ 0xf894, 0x0086 },
+
+		{ USBTV_BASE + 0x00ac, 0x00c0 },
+		{ USBTV_BASE + 0x00ad, 0x0000 },
+		{ USBTV_BASE + 0x00a2, 0x0012 },
+		{ USBTV_BASE + 0x00a3, 0x00e0 },
+		{ USBTV_BASE + 0x00a4, 0x0028 },
+		{ USBTV_BASE + 0x00a5, 0x0082 },
+		{ USBTV_BASE + 0x00a7, 0x0080 },
+		{ USBTV_BASE + 0x0000, 0x0014 },
+		{ USBTV_BASE + 0x0006, 0x0003 },
+		{ USBTV_BASE + 0x0090, 0x0099 },
+		{ USBTV_BASE + 0x0091, 0x0090 },
+		{ USBTV_BASE + 0x0094, 0x0068 },
+		{ USBTV_BASE + 0x0095, 0x0070 },
+		{ USBTV_BASE + 0x009c, 0x0030 },
+		{ USBTV_BASE + 0x009d, 0x00c0 },
+		{ USBTV_BASE + 0x009e, 0x00e0 },
+		{ USBTV_BASE + 0x0019, 0x0006 },
+		{ USBTV_BASE + 0x008c, 0x00ba },
+		{ USBTV_BASE + 0x0101, 0x00ff },
+		{ USBTV_BASE + 0x010c, 0x00b3 },
+		{ USBTV_BASE + 0x01b2, 0x0080 },
+		{ USBTV_BASE + 0x01b4, 0x00a0 },
+		{ USBTV_BASE + 0x014c, 0x00ff },
+		{ USBTV_BASE + 0x014d, 0x00ca },
+		{ USBTV_BASE + 0x0113, 0x0053 },
+		{ USBTV_BASE + 0x0119, 0x008a },
+		{ USBTV_BASE + 0x013c, 0x0003 },
+		{ USBTV_BASE + 0x0150, 0x009c },
+		{ USBTV_BASE + 0x0151, 0x0071 },
+		{ USBTV_BASE + 0x0152, 0x00c6 },
+		{ USBTV_BASE + 0x0153, 0x0084 },
+		{ USBTV_BASE + 0x0154, 0x00bc },
+		{ USBTV_BASE + 0x0155, 0x00a0 },
+		{ USBTV_BASE + 0x0156, 0x00a0 },
+		{ USBTV_BASE + 0x0157, 0x009c },
+		{ USBTV_BASE + 0x0158, 0x001f },
+		{ USBTV_BASE + 0x0159, 0x0006 },
+		{ USBTV_BASE + 0x015d, 0x0000 },
+
+		{ USBTV_BASE + 0x0284, 0x0088 },
+		{ USBTV_BASE + 0x0003, 0x0004 },
+		{ USBTV_BASE + 0x001a, 0x0079 },
+		{ USBTV_BASE + 0x0100, 0x00d3 },
+		{ USBTV_BASE + 0x010e, 0x0068 },
+		{ USBTV_BASE + 0x010f, 0x009c },
+		{ USBTV_BASE + 0x0112, 0x00f0 },
+		{ USBTV_BASE + 0x0115, 0x0015 },
+		{ USBTV_BASE + 0x0117, 0x0000 },
+		{ USBTV_BASE + 0x0118, 0x00fc },
+		{ USBTV_BASE + 0x012d, 0x0004 },
+		{ USBTV_BASE + 0x012f, 0x0008 },
+		{ USBTV_BASE + 0x0220, 0x002e },
+		{ USBTV_BASE + 0x0225, 0x0008 },
+		{ USBTV_BASE + 0x024e, 0x0002 },
+		{ USBTV_BASE + 0x024f, 0x0001 },
+		{ USBTV_BASE + 0x0254, 0x005f },
+		{ USBTV_BASE + 0x025a, 0x0012 },
+		{ USBTV_BASE + 0x025b, 0x0001 },
+		{ USBTV_BASE + 0x0263, 0x001c },
+		{ USBTV_BASE + 0x0266, 0x0011 },
+		{ USBTV_BASE + 0x0267, 0x0005 },
+		{ USBTV_BASE + 0x024e, 0x0002 },
+		{ USBTV_BASE + 0x024f, 0x0002 },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(protoregs); i++) {
+		u16 index = protoregs[i][0];
+		u16 value = protoregs[i][1];
+
+		ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			value, index, NULL, 0, 0);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+/* Copy data from chunk into a frame buffer, deinterlacing the data
+ * into every second line. Unfortunately, they don't align nicely into
+ * 720 pixel lines, as the chunk is 240 words long, which is 480 pixels.
+ * Therefore, we break down the chunk into two halves before copyting,
+ * so that we can interleave a line if needed. */
+static void usbtv_chunk_to_vbuf(u32 *frame, u32 *src, int chunk_no, int odd)
+{
+	int half;
+
+	for (half = 0; half < 2; half++) {
+		int part_no = chunk_no * 2 + half;
+		int line = part_no / 3;
+		int part_index = (line * 2 + !odd) * 3 + (part_no % 3);
+
+		u32 *dst = &frame[part_index * USBTV_CHUNK/2];
+		memcpy(dst, src, USBTV_CHUNK/2 * sizeof(*src));
+		src += USBTV_CHUNK/2;
+	}
+}
+
+/* Called for each 256-byte image chunk.
+ * First word identifies the chunk, followed by 240 words of image
+ * data and padding. */
+static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
+{
+	int frame_id, odd, chunk_no;
+	u32 *frame;
+	struct usbtv_buf *buf;
+	unsigned long flags;
+
+	/* Ignore corrupted lines. */
+	if (!USBTV_MAGIC_OK(chunk))
+		return;
+	frame_id = USBTV_FRAME_ID(chunk);
+	odd = USBTV_ODD(chunk);
+	chunk_no = USBTV_CHUNK_NO(chunk);
+	if (chunk_no >= USBTV_CHUNKS)
+		return;
+
+	/* Beginning of a frame. */
+	if (chunk_no == 0) {
+		usbtv->frame_id = frame_id;
+		usbtv->chunks_done = 0;
+	}
+
+	if (usbtv->frame_id != frame_id)
+		return;
+
+	spin_lock_irqsave(&usbtv->buflock, flags);
+	if (list_empty(&usbtv->bufs)) {
+		/* No free buffers. Userspace likely too slow. */
+		spin_unlock_irqrestore(&usbtv->buflock, flags);
+		return;
+	}
+
+	/* First available buffer. */
+	buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list);
+	frame = vb2_plane_vaddr(&buf->vb, 0);
+
+	/* Copy the chunk data. */
+	usbtv_chunk_to_vbuf(frame, &chunk[1], chunk_no, odd);
+	usbtv->chunks_done++;
+
+	/* Last chunk in a frame, signalling an end */
+	if (odd && chunk_no == USBTV_CHUNKS-1) {
+		int size = vb2_plane_size(&buf->vb, 0);
+		enum vb2_buffer_state state = usbtv->chunks_done ==
+						USBTV_CHUNKS ?
+						VB2_BUF_STATE_DONE :
+						VB2_BUF_STATE_ERROR;
+
+		buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
+		buf->vb.v4l2_buf.sequence = usbtv->sequence++;
+		v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+		vb2_set_plane_payload(&buf->vb, 0, size);
+		vb2_buffer_done(&buf->vb, state);
+		list_del(&buf->list);
+	}
+
+	spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+/* Got image data. Each packet contains a number of 256-word chunks we
+ * compose the image from. */
+static void usbtv_iso_cb(struct urb *ip)
+{
+	int ret;
+	int i;
+	struct usbtv *usbtv = (struct usbtv *)ip->context;
+
+	switch (ip->status) {
+	/* All fine. */
+	case 0:
+		break;
+	/* Device disconnected or capture stopped? */
+	case -ENODEV:
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		return;
+	/* Unknown error. Retry. */
+	default:
+		dev_warn(usbtv->dev, "Bad response for ISO request.\n");
+		goto resubmit;
+	}
+
+	for (i = 0; i < ip->number_of_packets; i++) {
+		int size = ip->iso_frame_desc[i].actual_length;
+		unsigned char *data = ip->transfer_buffer +
+				ip->iso_frame_desc[i].offset;
+		int offset;
+
+		for (offset = 0; USBTV_CHUNK_SIZE * offset < size; offset++)
+			usbtv_image_chunk(usbtv,
+				(u32 *)&data[USBTV_CHUNK_SIZE * offset]);
+	}
+
+resubmit:
+	ret = usb_submit_urb(ip, GFP_ATOMIC);
+	if (ret < 0)
+		dev_warn(usbtv->dev, "Could not resubmit ISO URB\n");
+}
+
+static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv)
+{
+	struct urb *ip;
+	int size = usbtv->iso_size;
+	int i;
+
+	ip = usb_alloc_urb(USBTV_ISOC_PACKETS, GFP_KERNEL);
+	if (ip == NULL)
+		return NULL;
+
+	ip->dev = usbtv->udev;
+	ip->context = usbtv;
+	ip->pipe = usb_rcvisocpipe(usbtv->udev, USBTV_VIDEO_ENDP);
+	ip->interval = 1;
+	ip->transfer_flags = URB_ISO_ASAP;
+	ip->transfer_buffer = kzalloc(size * USBTV_ISOC_PACKETS,
+						GFP_KERNEL);
+	ip->complete = usbtv_iso_cb;
+	ip->number_of_packets = USBTV_ISOC_PACKETS;
+	ip->transfer_buffer_length = size * USBTV_ISOC_PACKETS;
+	for (i = 0; i < USBTV_ISOC_PACKETS; i++) {
+		ip->iso_frame_desc[i].offset = size * i;
+		ip->iso_frame_desc[i].length = size;
+	}
+
+	return ip;
+}
+
+static void usbtv_stop(struct usbtv *usbtv)
+{
+	int i;
+	unsigned long flags;
+
+	/* Cancel running transfers. */
+	for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
+		struct urb *ip = usbtv->isoc_urbs[i];
+		if (ip == NULL)
+			continue;
+		usb_kill_urb(ip);
+		kfree(ip->transfer_buffer);
+		usb_free_urb(ip);
+		usbtv->isoc_urbs[i] = NULL;
+	}
+
+	/* Return buffers to userspace. */
+	spin_lock_irqsave(&usbtv->buflock, flags);
+	while (!list_empty(&usbtv->bufs)) {
+		struct usbtv_buf *buf = list_first_entry(&usbtv->bufs,
+						struct usbtv_buf, list);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+		list_del(&buf->list);
+	}
+	spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+static int usbtv_start(struct usbtv *usbtv)
+{
+	int i;
+	int ret;
+
+	ret = usb_set_interface(usbtv->udev, 0, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = usbtv_setup_capture(usbtv);
+	if (ret < 0)
+		return ret;
+
+	ret = usb_set_interface(usbtv->udev, 0, 1);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
+		struct urb *ip;
+
+		ip = usbtv_setup_iso_transfer(usbtv);
+		if (ip == NULL) {
+			ret = -ENOMEM;
+			goto start_fail;
+		}
+		usbtv->isoc_urbs[i] = ip;
+
+		ret = usb_submit_urb(ip, GFP_KERNEL);
+		if (ret < 0)
+			goto start_fail;
+	}
+
+	return 0;
+
+start_fail:
+	usbtv_stop(usbtv);
+	return ret;
+}
+
+struct usb_device_id usbtv_id_table[] = {
+	{ USB_DEVICE(0x1b71, 0x3002) },
+	{}
+};
+MODULE_DEVICE_TABLE(usb, usbtv_id_table);
+
+static int usbtv_querycap(struct file *file, void *priv,
+				struct v4l2_capability *cap)
+{
+	struct usbtv *dev = video_drvdata(file);
+
+	strlcpy(cap->driver, "usbtv", sizeof(cap->driver));
+	strlcpy(cap->card, "usbtv", sizeof(cap->card));
+	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE;
+	cap->device_caps |= V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+	return 0;
+}
+
+static int usbtv_enum_input(struct file *file, void *priv,
+					struct v4l2_input *i)
+{
+	if (i->index > 0)
+		return -EINVAL;
+
+	strlcpy(i->name, "Composite", sizeof(i->name));
+	i->type = V4L2_INPUT_TYPE_CAMERA;
+	i->std = V4L2_STD_525_60;
+	return 0;
+}
+
+static int usbtv_enum_fmt_vid_cap(struct file *file, void  *priv,
+					struct v4l2_fmtdesc *f)
+{
+	if (f->index > 0)
+		return -EINVAL;
+
+	strlcpy(f->description, "16 bpp YUY2, 4:2:2, packed",
+					sizeof(f->description));
+	f->pixelformat = V4L2_PIX_FMT_YUYV;
+	return 0;
+}
+
+static int usbtv_fmt_vid_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	f->fmt.pix.width = USBTV_WIDTH;
+	f->fmt.pix.height = USBTV_HEIGHT;
+	f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+	f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+	f->fmt.pix.bytesperline = USBTV_WIDTH * 2;
+	f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height);
+	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+	f->fmt.pix.priv = 0;
+	return 0;
+}
+
+static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+	*norm = V4L2_STD_525_60;
+	return 0;
+}
+
+static int usbtv_g_input(struct file *file, void *priv, unsigned int *i)
+{
+	*i = 0;
+	return 0;
+}
+
+static int usbtv_s_input(struct file *file, void *priv, unsigned int i)
+{
+	if (i > 0)
+		return -EINVAL;
+	return 0;
+}
+
+static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)
+{
+	if (norm & V4L2_STD_525_60)
+		return 0;
+	return -EINVAL;
+}
+
+struct v4l2_ioctl_ops usbtv_ioctl_ops = {
+	.vidioc_querycap = usbtv_querycap,
+	.vidioc_enum_input = usbtv_enum_input,
+	.vidioc_enum_fmt_vid_cap = usbtv_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = usbtv_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = usbtv_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = usbtv_fmt_vid_cap,
+	.vidioc_g_std = usbtv_g_std,
+	.vidioc_s_std = usbtv_s_std,
+	.vidioc_g_input = usbtv_g_input,
+	.vidioc_s_input = usbtv_s_input,
+
+	.vidioc_reqbufs = vb2_ioctl_reqbufs,
+	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf = vb2_ioctl_querybuf,
+	.vidioc_create_bufs = vb2_ioctl_create_bufs,
+	.vidioc_qbuf = vb2_ioctl_qbuf,
+	.vidioc_dqbuf = vb2_ioctl_dqbuf,
+	.vidioc_streamon = vb2_ioctl_streamon,
+	.vidioc_streamoff = vb2_ioctl_streamoff,
+};
+
+struct v4l2_file_operations usbtv_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = video_ioctl2,
+	.mmap = vb2_fop_mmap,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.read = vb2_fop_read,
+	.poll = vb2_fop_poll,
+};
+
+static int usbtv_queue_setup(struct vb2_queue *vq,
+	const struct v4l2_format *v4l_fmt, unsigned int *nbuffers,
+	unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
+{
+	if (*nbuffers < 2)
+		*nbuffers = 2;
+	*nplanes = 1;
+	sizes[0] = USBTV_WIDTH * USBTV_HEIGHT / 2 * sizeof(u32);
+
+	return 0;
+}
+
+static void usbtv_buf_queue(struct vb2_buffer *vb)
+{
+	struct usbtv *usbtv = vb2_get_drv_priv(vb->vb2_queue);
+	struct usbtv_buf *buf = container_of(vb, struct usbtv_buf, vb);
+	unsigned long flags;
+
+	if (usbtv->udev == NULL) {
+		vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+		return;
+	}
+
+	spin_lock_irqsave(&usbtv->buflock, flags);
+	list_add_tail(&buf->list, &usbtv->bufs);
+	spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
+	if (usbtv->udev == NULL)
+		return -ENODEV;
+
+	return usbtv_start(usbtv);
+}
+
+static int usbtv_stop_streaming(struct vb2_queue *vq)
+{
+	struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
+	if (usbtv->udev == NULL)
+		return -ENODEV;
+
+	usbtv_stop(usbtv);
+	return 0;
+}
+
+struct vb2_ops usbtv_vb2_ops = {
+	.queue_setup = usbtv_queue_setup,
+	.buf_queue = usbtv_buf_queue,
+	.start_streaming = usbtv_start_streaming,
+	.stop_streaming = usbtv_stop_streaming,
+};
+
+static void usbtv_release(struct v4l2_device *v4l2_dev)
+{
+	struct usbtv *usbtv = container_of(v4l2_dev, struct usbtv, v4l2_dev);
+
+	v4l2_device_unregister(&usbtv->v4l2_dev);
+	vb2_queue_release(&usbtv->vb2q);
+	kfree(usbtv);
+}
+
+static int usbtv_probe(struct usb_interface *intf,
+	const struct usb_device_id *id)
+{
+	int ret;
+	int size;
+	struct device *dev = &intf->dev;
+	struct usbtv *usbtv;
+
+	/* Checks that the device is what we think it is. */
+	if (intf->num_altsetting != 2)
+		return -ENODEV;
+	if (intf->altsetting[1].desc.bNumEndpoints != 4)
+		return -ENODEV;
+
+	/* Packet size is split into 11 bits of base size and count of
+	 * extra multiplies of it.*/
+	size = usb_endpoint_maxp(&intf->altsetting[1].endpoint[0].desc);
+	size = (size & 0x07ff) * (((size & 0x1800) >> 11) + 1);
+
+	/* Device structure */
+	usbtv = kzalloc(sizeof(struct usbtv), GFP_KERNEL);
+	if (usbtv == NULL)
+		return -ENOMEM;
+	usbtv->dev = dev;
+	usbtv->udev = usb_get_dev(interface_to_usbdev(intf));
+	usbtv->iso_size = size;
+	spin_lock_init(&usbtv->buflock);
+	mutex_init(&usbtv->v4l2_lock);
+	mutex_init(&usbtv->vb2q_lock);
+	INIT_LIST_HEAD(&usbtv->bufs);
+
+	/* videobuf2 structure */
+	usbtv->vb2q.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	usbtv->vb2q.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+	usbtv->vb2q.drv_priv = usbtv;
+	usbtv->vb2q.buf_struct_size = sizeof(struct usbtv_buf);
+	usbtv->vb2q.ops = &usbtv_vb2_ops;
+	usbtv->vb2q.mem_ops = &vb2_vmalloc_memops;
+	usbtv->vb2q.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	usbtv->vb2q.lock = &usbtv->vb2q_lock;
+	ret = vb2_queue_init(&usbtv->vb2q);
+	if (ret < 0) {
+		dev_warn(dev, "Could not initialize videobuf2 queue\n");
+		goto usbtv_fail;
+	}
+
+	/* v4l2 structure */
+	usbtv->v4l2_dev.release = usbtv_release;
+	ret = v4l2_device_register(dev, &usbtv->v4l2_dev);
+	if (ret < 0) {
+		dev_warn(dev, "Could not register v4l2 device\n");
+		goto v4l2_fail;
+	}
+
+	usb_set_intfdata(intf, usbtv);
+
+	/* Video structure */
+	strlcpy(usbtv->vdev.name, "usbtv", sizeof(usbtv->vdev.name));
+	usbtv->vdev.v4l2_dev = &usbtv->v4l2_dev;
+	usbtv->vdev.release = video_device_release_empty;
+	usbtv->vdev.fops = &usbtv_fops;
+	usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops;
+	usbtv->vdev.tvnorms = V4L2_STD_525_60;
+	usbtv->vdev.queue = &usbtv->vb2q;
+	usbtv->vdev.lock = &usbtv->v4l2_lock;
+	set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags);
+	video_set_drvdata(&usbtv->vdev, usbtv);
+	ret = video_register_device(&usbtv->vdev, VFL_TYPE_GRABBER, -1);
+	if (ret < 0) {
+		dev_warn(dev, "Could not register video device\n");
+		goto vdev_fail;
+	}
+
+	dev_info(dev, "Fushicai USBTV007 Video Grabber\n");
+	return 0;
+
+vdev_fail:
+	v4l2_device_unregister(&usbtv->v4l2_dev);
+v4l2_fail:
+	vb2_queue_release(&usbtv->vb2q);
+usbtv_fail:
+	kfree(usbtv);
+
+	return ret;
+}
+
+static void usbtv_disconnect(struct usb_interface *intf)
+{
+	struct usbtv *usbtv = usb_get_intfdata(intf);
+
+	mutex_lock(&usbtv->vb2q_lock);
+	mutex_lock(&usbtv->v4l2_lock);
+
+	usbtv_stop(usbtv);
+	usb_set_intfdata(intf, NULL);
+	video_unregister_device(&usbtv->vdev);
+	v4l2_device_disconnect(&usbtv->v4l2_dev);
+	usb_put_dev(usbtv->udev);
+	usbtv->udev = NULL;
+
+	mutex_unlock(&usbtv->v4l2_lock);
+	mutex_unlock(&usbtv->vb2q_lock);
+
+	v4l2_device_put(&usbtv->v4l2_dev);
+}
+
+MODULE_AUTHOR("Lubomir Rintel");
+MODULE_DESCRIPTION("Fushicai USBTV007 Video Grabber Driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+struct usb_driver usbtv_usb_driver = {
+	.name = "usbtv",
+	.id_table = usbtv_id_table,
+	.probe = usbtv_probe,
+	.disconnect = usbtv_disconnect,
+};
+
+module_usb_driver(usbtv_usb_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/usbvision/usbvision-video.c linux-libre-3.11-rc7-gnu/drivers/media/usb/usbvision/usbvision-video.c
--- linux-libre-3.10-gnu/drivers/media/usb/usbvision/usbvision-video.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/usbvision/usbvision-video.c	2013-08-25 20:43:22.000000000 -0400
@@ -467,8 +467,6 @@ static int vidioc_g_register(struct file
 	struct usb_usbvision *usbvision = video_drvdata(file);
 	int err_code;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
 	/* NT100x has a 8-bit register space */
 	err_code = usbvision_read_reg(usbvision, reg->reg&0xff);
 	if (err_code < 0) {
@@ -488,8 +486,6 @@ static int vidioc_s_register(struct file
 	struct usb_usbvision *usbvision = video_drvdata(file);
 	int err_code;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
 	/* NT100x has a 8-bit register space */
 	err_code = usbvision_write_reg(usbvision, reg->reg & 0xff, reg->val);
 	if (err_code < 0) {
@@ -608,6 +604,14 @@ static int vidioc_s_std(struct file *fil
 	return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+	struct usb_usbvision *usbvision = video_drvdata(file);
+
+	*id = usbvision->tvnorm_id;
+	return 0;
+}
+
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *vt)
 {
@@ -1248,6 +1252,7 @@ static const struct v4l2_ioctl_ops usbvi
 	.vidioc_qbuf          = vidioc_qbuf,
 	.vidioc_dqbuf         = vidioc_dqbuf,
 	.vidioc_s_std         = vidioc_s_std,
+	.vidioc_g_std         = vidioc_g_std,
 	.vidioc_enum_input    = vidioc_enum_input,
 	.vidioc_g_input       = vidioc_g_input,
 	.vidioc_s_input       = vidioc_s_input,
@@ -1274,7 +1279,6 @@ static struct video_device usbvision_vid
 	.name           = "usbvision-video",
 	.release	= video_device_release,
 	.tvnorms        = USBVISION_NORMS,
-	.current_norm   = V4L2_STD_PAL
 };
 
 
@@ -1307,9 +1311,6 @@ static struct video_device usbvision_rad
 	.name		= "usbvision-radio",
 	.release	= video_device_release,
 	.ioctl_ops	= &usbvision_radio_ioctl_ops,
-
-	.tvnorms              = USBVISION_NORMS,
-	.current_norm         = V4L2_STD_PAL
 };
 
 
@@ -1459,6 +1460,7 @@ static void usbvision_release(struct usb
 
 	usbvision_remove_sysfs(usbvision->vdev);
 	usbvision_unregister_video(usbvision);
+	kfree(usbvision->alt_max_pkt_size);
 
 	usb_free_urb(usbvision->ctrl_urb);
 
@@ -1574,6 +1576,7 @@ static int usbvision_probe(struct usb_in
 	usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL);
 	if (usbvision->alt_max_pkt_size == NULL) {
 		dev_err(&intf->dev, "usbvision: out of memory!\n");
+		usbvision_release(usbvision);
 		return -ENOMEM;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/uvc/Kconfig linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/Kconfig
--- linux-libre-3.10-gnu/drivers/media/usb/uvc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,6 @@
 config USB_VIDEO_CLASS
 	tristate "USB Video Class (UVC)"
+	depends on VIDEO_V4L2
 	select VIDEOBUF2_VMALLOC
 	---help---
 	  Support for the USB Video Class (UVC).  Currently only video
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/uvc/uvc_driver.c linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/uvc_driver.c
--- linux-libre-3.10-gnu/drivers/media/usb/uvc/uvc_driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/uvc_driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -1836,8 +1836,8 @@ static int uvc_probe(struct usb_interfac
 	INIT_LIST_HEAD(&dev->chains);
 	INIT_LIST_HEAD(&dev->streams);
 	atomic_set(&dev->nstreams, 0);
-	atomic_set(&dev->users, 0);
 	atomic_set(&dev->nmappings, 0);
+	mutex_init(&dev->lock);
 
 	dev->udev = usb_get_dev(udev);
 	dev->intf = usb_get_intf(intf);
@@ -1950,8 +1950,13 @@ static int uvc_suspend(struct usb_interf
 
 	/* Controls are cached on the fly so they don't need to be saved. */
 	if (intf->cur_altsetting->desc.bInterfaceSubClass ==
-	    UVC_SC_VIDEOCONTROL)
-		return uvc_status_suspend(dev);
+	    UVC_SC_VIDEOCONTROL) {
+		mutex_lock(&dev->lock);
+		if (dev->users)
+			uvc_status_stop(dev);
+		mutex_unlock(&dev->lock);
+		return 0;
+	}
 
 	list_for_each_entry(stream, &dev->streams, list) {
 		if (stream->intf == intf)
@@ -1973,14 +1978,20 @@ static int __uvc_resume(struct usb_inter
 
 	if (intf->cur_altsetting->desc.bInterfaceSubClass ==
 	    UVC_SC_VIDEOCONTROL) {
-		if (reset) {
-			int ret = uvc_ctrl_resume_device(dev);
+		int ret = 0;
 
+		if (reset) {
+			ret = uvc_ctrl_resume_device(dev);
 			if (ret < 0)
 				return ret;
 		}
 
-		return uvc_status_resume(dev);
+		mutex_lock(&dev->lock);
+		if (dev->users)
+			ret = uvc_status_start(dev, GFP_NOIO);
+		mutex_unlock(&dev->lock);
+
+		return ret;
 	}
 
 	list_for_each_entry(stream, &dev->streams, list) {
@@ -2163,6 +2174,24 @@ static struct usb_device_id uvc_ids[] =
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info 		= UVC_QUIRK_PROBE_DEF },
+	/* Dell Alienware X51 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x05a9,
+	  .idProduct		= 0x2643,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info	= UVC_QUIRK_PROBE_DEF },
+	/* Dell Studio Hybrid 140g (OmniVision webcam) */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x05a9,
+	  .idProduct		= 0x264a,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_DEF },
 	/* Apple Built-In iSight */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/uvc/uvc_status.c linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/uvc_status.c
--- linux-libre-3.10-gnu/drivers/media/usb/uvc/uvc_status.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/uvc_status.c	2013-08-25 20:43:22.000000000 -0400
@@ -206,32 +206,15 @@ void uvc_status_cleanup(struct uvc_devic
 	uvc_input_cleanup(dev);
 }
 
-int uvc_status_start(struct uvc_device *dev)
+int uvc_status_start(struct uvc_device *dev, gfp_t flags)
 {
 	if (dev->int_urb == NULL)
 		return 0;
 
-	return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+	return usb_submit_urb(dev->int_urb, flags);
 }
 
 void uvc_status_stop(struct uvc_device *dev)
 {
 	usb_kill_urb(dev->int_urb);
 }
-
-int uvc_status_suspend(struct uvc_device *dev)
-{
-	if (atomic_read(&dev->users))
-		usb_kill_urb(dev->int_urb);
-
-	return 0;
-}
-
-int uvc_status_resume(struct uvc_device *dev)
-{
-	if (dev->int_urb == NULL || atomic_read(&dev->users) == 0)
-		return 0;
-
-	return usb_submit_urb(dev->int_urb, GFP_NOIO);
-}
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/uvc/uvc_v4l2.c linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/uvc_v4l2.c
--- linux-libre-3.10-gnu/drivers/media/usb/uvc/uvc_v4l2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/uvc_v4l2.c	2013-08-25 20:43:22.000000000 -0400
@@ -498,16 +498,20 @@ static int uvc_v4l2_open(struct file *fi
 		return -ENOMEM;
 	}
 
-	if (atomic_inc_return(&stream->dev->users) == 1) {
-		ret = uvc_status_start(stream->dev);
+	mutex_lock(&stream->dev->lock);
+	if (stream->dev->users == 0) {
+		ret = uvc_status_start(stream->dev, GFP_KERNEL);
 		if (ret < 0) {
-			atomic_dec(&stream->dev->users);
+			mutex_unlock(&stream->dev->lock);
 			usb_autopm_put_interface(stream->dev->intf);
 			kfree(handle);
 			return ret;
 		}
 	}
 
+	stream->dev->users++;
+	mutex_unlock(&stream->dev->lock);
+
 	v4l2_fh_init(&handle->vfh, stream->vdev);
 	v4l2_fh_add(&handle->vfh);
 	handle->chain = stream->chain;
@@ -538,8 +542,10 @@ static int uvc_v4l2_release(struct file
 	kfree(handle);
 	file->private_data = NULL;
 
-	if (atomic_dec_return(&stream->dev->users) == 0)
+	mutex_lock(&stream->dev->lock);
+	if (--stream->dev->users == 0)
 		uvc_status_stop(stream->dev);
+	mutex_unlock(&stream->dev->lock);
 
 	usb_autopm_put_interface(stream->dev->intf);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/usb/uvc/uvcvideo.h linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/uvcvideo.h
--- linux-libre-3.10-gnu/drivers/media/usb/uvc/uvcvideo.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/usb/uvc/uvcvideo.h	2013-08-25 20:43:22.000000000 -0400
@@ -514,7 +514,8 @@ struct uvc_device {
 	char name[32];
 
 	enum uvc_device_state state;
-	atomic_t users;
+	struct mutex lock;		/* Protects users */
+	unsigned int users;
 	atomic_t nmappings;
 
 	/* Video control interface */
@@ -660,10 +661,8 @@ void uvc_video_clock_update(struct uvc_s
 /* Status */
 extern int uvc_status_init(struct uvc_device *dev);
 extern void uvc_status_cleanup(struct uvc_device *dev);
-extern int uvc_status_start(struct uvc_device *dev);
+extern int uvc_status_start(struct uvc_device *dev, gfp_t flags);
 extern void uvc_status_stop(struct uvc_device *dev);
-extern int uvc_status_suspend(struct uvc_device *dev);
-extern int uvc_status_resume(struct uvc_device *dev);
 
 /* Controls */
 extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/Makefile linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/Makefile
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,8 @@
 tuner-objs	:=	tuner-core.o
 
 videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
-			v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
+			v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o \
+			v4l2-async.o
 ifeq ($(CONFIG_COMPAT),y)
   videodev-objs += v4l2-compat-ioctl32.o
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-async.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-async.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-async.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-async.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,284 @@
+/*
+ * V4L2 asynchronous subdevice registration API
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <media/v4l2-async.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
+{
+#if IS_ENABLED(CONFIG_I2C)
+	struct i2c_client *client = i2c_verify_client(dev);
+	return client &&
+		asd->bus_type == V4L2_ASYNC_BUS_I2C &&
+		asd->match.i2c.adapter_id == client->adapter->nr &&
+		asd->match.i2c.address == client->addr;
+#else
+	return false;
+#endif
+}
+
+static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd)
+{
+	return asd->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
+		!strcmp(asd->match.platform.name, dev_name(dev));
+}
+
+static LIST_HEAD(subdev_list);
+static LIST_HEAD(notifier_list);
+static DEFINE_MUTEX(list_lock);
+
+static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier,
+						    struct v4l2_async_subdev_list *asdl)
+{
+	struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+	struct v4l2_async_subdev *asd;
+	bool (*match)(struct device *,
+		      struct v4l2_async_subdev *);
+
+	list_for_each_entry(asd, &notifier->waiting, list) {
+		/* bus_type has been verified valid before */
+		switch (asd->bus_type) {
+		case V4L2_ASYNC_BUS_CUSTOM:
+			match = asd->match.custom.match;
+			if (!match)
+				/* Match always */
+				return asd;
+			break;
+		case V4L2_ASYNC_BUS_PLATFORM:
+			match = match_platform;
+			break;
+		case V4L2_ASYNC_BUS_I2C:
+			match = match_i2c;
+			break;
+		default:
+			/* Cannot happen, unless someone breaks us */
+			WARN_ON(true);
+			return NULL;
+		}
+
+		/* match cannot be NULL here */
+		if (match(sd->dev, asd))
+			return asd;
+	}
+
+	return NULL;
+}
+
+static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
+				  struct v4l2_async_subdev_list *asdl,
+				  struct v4l2_async_subdev *asd)
+{
+	struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+	int ret;
+
+	/* Remove from the waiting list */
+	list_del(&asd->list);
+	asdl->asd = asd;
+	asdl->notifier = notifier;
+
+	if (notifier->bound) {
+		ret = notifier->bound(notifier, sd, asd);
+		if (ret < 0)
+			return ret;
+	}
+	/* Move from the global subdevice list to notifier's done */
+	list_move(&asdl->list, &notifier->done);
+
+	ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
+	if (ret < 0) {
+		if (notifier->unbind)
+			notifier->unbind(notifier, sd, asd);
+		return ret;
+	}
+
+	if (list_empty(&notifier->waiting) && notifier->complete)
+		return notifier->complete(notifier);
+
+	return 0;
+}
+
+static void v4l2_async_cleanup(struct v4l2_async_subdev_list *asdl)
+{
+	struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+
+	v4l2_device_unregister_subdev(sd);
+	/* Subdevice driver will reprobe and put asdl back onto the list */
+	list_del_init(&asdl->list);
+	asdl->asd = NULL;
+	sd->dev = NULL;
+}
+
+int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+				 struct v4l2_async_notifier *notifier)
+{
+	struct v4l2_async_subdev_list *asdl, *tmp;
+	struct v4l2_async_subdev *asd;
+	int i;
+
+	if (!notifier->num_subdevs || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
+		return -EINVAL;
+
+	notifier->v4l2_dev = v4l2_dev;
+	INIT_LIST_HEAD(&notifier->waiting);
+	INIT_LIST_HEAD(&notifier->done);
+
+	for (i = 0; i < notifier->num_subdevs; i++) {
+		asd = notifier->subdev[i];
+
+		switch (asd->bus_type) {
+		case V4L2_ASYNC_BUS_CUSTOM:
+		case V4L2_ASYNC_BUS_PLATFORM:
+		case V4L2_ASYNC_BUS_I2C:
+			break;
+		default:
+			dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
+				"Invalid bus-type %u on %p\n",
+				asd->bus_type, asd);
+			return -EINVAL;
+		}
+		list_add_tail(&asd->list, &notifier->waiting);
+	}
+
+	mutex_lock(&list_lock);
+
+	/* Keep also completed notifiers on the list */
+	list_add(&notifier->list, &notifier_list);
+
+	list_for_each_entry_safe(asdl, tmp, &subdev_list, list) {
+		int ret;
+
+		asd = v4l2_async_belongs(notifier, asdl);
+		if (!asd)
+			continue;
+
+		ret = v4l2_async_test_notify(notifier, asdl, asd);
+		if (ret < 0) {
+			mutex_unlock(&list_lock);
+			return ret;
+		}
+	}
+
+	mutex_unlock(&list_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_async_notifier_register);
+
+void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+{
+	struct v4l2_async_subdev_list *asdl, *tmp;
+	unsigned int notif_n_subdev = notifier->num_subdevs;
+	unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
+	struct device *dev[n_subdev];
+	int i = 0;
+
+	mutex_lock(&list_lock);
+
+	list_del(&notifier->list);
+
+	list_for_each_entry_safe(asdl, tmp, &notifier->done, list) {
+		struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+
+		dev[i] = get_device(sd->dev);
+
+		v4l2_async_cleanup(asdl);
+
+		/* If we handled USB devices, we'd have to lock the parent too */
+		device_release_driver(dev[i++]);
+
+		if (notifier->unbind)
+			notifier->unbind(notifier, sd, sd->asdl.asd);
+	}
+
+	mutex_unlock(&list_lock);
+
+	while (i--) {
+		struct device *d = dev[i];
+
+		if (d && device_attach(d) < 0) {
+			const char *name = "(none)";
+			int lock = device_trylock(d);
+
+			if (lock && d->driver)
+				name = d->driver->name;
+			dev_err(d, "Failed to re-probe to %s\n", name);
+			if (lock)
+				device_unlock(d);
+		}
+		put_device(d);
+	}
+	/*
+	 * Don't care about the waiting list, it is initialised and populated
+	 * upon notifier registration.
+	 */
+}
+EXPORT_SYMBOL(v4l2_async_notifier_unregister);
+
+int v4l2_async_register_subdev(struct v4l2_subdev *sd)
+{
+	struct v4l2_async_subdev_list *asdl = &sd->asdl;
+	struct v4l2_async_notifier *notifier;
+
+	mutex_lock(&list_lock);
+
+	INIT_LIST_HEAD(&asdl->list);
+
+	list_for_each_entry(notifier, &notifier_list, list) {
+		struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, asdl);
+		if (asd) {
+			int ret = v4l2_async_test_notify(notifier, asdl, asd);
+			mutex_unlock(&list_lock);
+			return ret;
+		}
+	}
+
+	/* None matched, wait for hot-plugging */
+	list_add(&asdl->list, &subdev_list);
+
+	mutex_unlock(&list_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_async_register_subdev);
+
+void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
+{
+	struct v4l2_async_subdev_list *asdl = &sd->asdl;
+	struct v4l2_async_notifier *notifier = asdl->notifier;
+
+	if (!asdl->asd) {
+		if (!list_empty(&asdl->list))
+			v4l2_async_cleanup(asdl);
+		return;
+	}
+
+	mutex_lock(&list_lock);
+
+	list_add(&asdl->asd->list, &notifier->waiting);
+
+	v4l2_async_cleanup(asdl);
+
+	if (notifier->unbind)
+		notifier->unbind(notifier, sd, sd->asdl.asd);
+
+	mutex_unlock(&list_lock);
+}
+EXPORT_SYMBOL(v4l2_async_unregister_subdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-clk.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-clk.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-clk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-clk.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,242 @@
+/*
+ * V4L2 clock service
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/atomic.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <media/v4l2-clk.h>
+#include <media/v4l2-subdev.h>
+
+static DEFINE_MUTEX(clk_lock);
+static LIST_HEAD(clk_list);
+
+static struct v4l2_clk *v4l2_clk_find(const char *dev_id, const char *id)
+{
+	struct v4l2_clk *clk;
+
+	list_for_each_entry(clk, &clk_list, list) {
+		if (strcmp(dev_id, clk->dev_id))
+			continue;
+
+		if (!id || !clk->id || !strcmp(clk->id, id))
+			return clk;
+	}
+
+	return ERR_PTR(-ENODEV);
+}
+
+struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id)
+{
+	struct v4l2_clk *clk;
+
+	mutex_lock(&clk_lock);
+	clk = v4l2_clk_find(dev_name(dev), id);
+
+	if (!IS_ERR(clk))
+		atomic_inc(&clk->use_count);
+	mutex_unlock(&clk_lock);
+
+	return clk;
+}
+EXPORT_SYMBOL(v4l2_clk_get);
+
+void v4l2_clk_put(struct v4l2_clk *clk)
+{
+	struct v4l2_clk *tmp;
+
+	if (IS_ERR(clk))
+		return;
+
+	mutex_lock(&clk_lock);
+
+	list_for_each_entry(tmp, &clk_list, list)
+		if (tmp == clk)
+			atomic_dec(&clk->use_count);
+
+	mutex_unlock(&clk_lock);
+}
+EXPORT_SYMBOL(v4l2_clk_put);
+
+static int v4l2_clk_lock_driver(struct v4l2_clk *clk)
+{
+	struct v4l2_clk *tmp;
+	int ret = -ENODEV;
+
+	mutex_lock(&clk_lock);
+
+	list_for_each_entry(tmp, &clk_list, list)
+		if (tmp == clk) {
+			ret = !try_module_get(clk->ops->owner);
+			if (ret)
+				ret = -EFAULT;
+			break;
+		}
+
+	mutex_unlock(&clk_lock);
+
+	return ret;
+}
+
+static void v4l2_clk_unlock_driver(struct v4l2_clk *clk)
+{
+	module_put(clk->ops->owner);
+}
+
+int v4l2_clk_enable(struct v4l2_clk *clk)
+{
+	int ret = v4l2_clk_lock_driver(clk);
+
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&clk->lock);
+
+	if (++clk->enable == 1 && clk->ops->enable) {
+		ret = clk->ops->enable(clk);
+		if (ret < 0)
+			clk->enable--;
+	}
+
+	mutex_unlock(&clk->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(v4l2_clk_enable);
+
+/*
+ * You might Oops if you try to disabled a disabled clock, because then the
+ * driver isn't locked and could have been unloaded by now, so, don't do that
+ */
+void v4l2_clk_disable(struct v4l2_clk *clk)
+{
+	int enable;
+
+	mutex_lock(&clk->lock);
+
+	enable = --clk->enable;
+	if (WARN(enable < 0, "Unbalanced %s() on %s:%s!\n", __func__,
+		 clk->dev_id, clk->id))
+		clk->enable++;
+	else if (!enable && clk->ops->disable)
+		clk->ops->disable(clk);
+
+	mutex_unlock(&clk->lock);
+
+	v4l2_clk_unlock_driver(clk);
+}
+EXPORT_SYMBOL(v4l2_clk_disable);
+
+unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk)
+{
+	int ret = v4l2_clk_lock_driver(clk);
+
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&clk->lock);
+	if (!clk->ops->get_rate)
+		ret = -ENOSYS;
+	else
+		ret = clk->ops->get_rate(clk);
+	mutex_unlock(&clk->lock);
+
+	v4l2_clk_unlock_driver(clk);
+
+	return ret;
+}
+EXPORT_SYMBOL(v4l2_clk_get_rate);
+
+int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate)
+{
+	int ret = v4l2_clk_lock_driver(clk);
+
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&clk->lock);
+	if (!clk->ops->set_rate)
+		ret = -ENOSYS;
+	else
+		ret = clk->ops->set_rate(clk, rate);
+	mutex_unlock(&clk->lock);
+
+	v4l2_clk_unlock_driver(clk);
+
+	return ret;
+}
+EXPORT_SYMBOL(v4l2_clk_set_rate);
+
+struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops,
+				   const char *dev_id,
+				   const char *id, void *priv)
+{
+	struct v4l2_clk *clk;
+	int ret;
+
+	if (!ops || !dev_id)
+		return ERR_PTR(-EINVAL);
+
+	clk = kzalloc(sizeof(struct v4l2_clk), GFP_KERNEL);
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	clk->id = kstrdup(id, GFP_KERNEL);
+	clk->dev_id = kstrdup(dev_id, GFP_KERNEL);
+	if ((id && !clk->id) || !clk->dev_id) {
+		ret = -ENOMEM;
+		goto ealloc;
+	}
+	clk->ops = ops;
+	clk->priv = priv;
+	atomic_set(&clk->use_count, 0);
+	mutex_init(&clk->lock);
+
+	mutex_lock(&clk_lock);
+	if (!IS_ERR(v4l2_clk_find(dev_id, id))) {
+		mutex_unlock(&clk_lock);
+		ret = -EEXIST;
+		goto eexist;
+	}
+	list_add_tail(&clk->list, &clk_list);
+	mutex_unlock(&clk_lock);
+
+	return clk;
+
+eexist:
+ealloc:
+	kfree(clk->id);
+	kfree(clk->dev_id);
+	kfree(clk);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(v4l2_clk_register);
+
+void v4l2_clk_unregister(struct v4l2_clk *clk)
+{
+	if (WARN(atomic_read(&clk->use_count),
+		 "%s(): Refusing to unregister ref-counted %s:%s clock!\n",
+		 __func__, clk->dev_id, clk->id))
+		return;
+
+	mutex_lock(&clk_lock);
+	list_del(&clk->list);
+	mutex_unlock(&clk_lock);
+
+	kfree(clk->id);
+	kfree(clk->dev_id);
+	kfree(clk);
+}
+EXPORT_SYMBOL(v4l2_clk_unregister);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-common.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-common.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-common.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,7 +61,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 
 #include <linux/videodev2.h>
 
@@ -227,62 +226,9 @@ u32 v4l2_ctrl_next(const u32 * const * c
 }
 EXPORT_SYMBOL(v4l2_ctrl_next);
 
-int v4l2_chip_match_host(const struct v4l2_dbg_match *match)
-{
-	switch (match->type) {
-	case V4L2_CHIP_MATCH_BRIDGE:
-		return match->addr == 0;
-	default:
-		return 0;
-	}
-}
-EXPORT_SYMBOL(v4l2_chip_match_host);
-
-#if IS_ENABLED(CONFIG_I2C)
-int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match)
-{
-	int len;
-
-	if (c == NULL || match == NULL)
-		return 0;
-
-	switch (match->type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		if (c->driver == NULL || c->driver->driver.name == NULL)
-			return 0;
-		len = strlen(c->driver->driver.name);
-		return len && !strncmp(c->driver->driver.name, match->name, len);
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		return c->addr == match->addr;
-	case V4L2_CHIP_MATCH_SUBDEV:
-		return 1;
-	default:
-		return 0;
-	}
-}
-EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
-
-int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip,
-		u32 ident, u32 revision)
-{
-	if (!v4l2_chip_match_i2c_client(c, &chip->match))
-		return 0;
-	if (chip->ident == V4L2_IDENT_NONE) {
-		chip->ident = ident;
-		chip->revision = revision;
-	}
-	else {
-		chip->ident = V4L2_IDENT_AMBIGUOUS;
-		chip->revision = 0;
-	}
-	return 0;
-}
-EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
-
-/* ----------------------------------------------------------------- */
-
 /* I2C Helper functions */
 
+#if IS_ENABLED(CONFIG_I2C)
 
 void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
 		const struct v4l2_subdev_ops *ops)
@@ -291,6 +237,7 @@ void v4l2_i2c_subdev_init(struct v4l2_su
 	sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
 	/* the owner is the same as the i2c_client's driver owner */
 	sd->owner = client->driver->driver.owner;
+	sd->dev = &client->dev;
 	/* i2c_client and v4l2_subdev point to one another */
 	v4l2_set_subdevdata(sd, client);
 	i2c_set_clientdata(client, sd);
@@ -301,8 +248,6 @@ void v4l2_i2c_subdev_init(struct v4l2_su
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
 
-
-
 /* Load an i2c sub-device. */
 struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
 		struct i2c_adapter *adapter, struct i2c_board_info *info,
@@ -426,6 +371,7 @@ void v4l2_spi_subdev_init(struct v4l2_su
 	sd->flags |= V4L2_SUBDEV_FL_IS_SPI;
 	/* the owner is the same as the spi_device's driver owner */
 	sd->owner = spi->dev.driver->owner;
+	sd->dev = &spi->dev;
 	/* spi_device and v4l2_subdev point to one another */
 	v4l2_set_subdevdata(sd, spi);
 	spi_set_drvdata(spi, sd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-compat-ioctl32.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-compat-ioctl32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-compat-ioctl32.c	2013-08-25 20:43:22.000000000 -0400
@@ -1074,7 +1074,6 @@ long v4l2_compat_ioctl32(struct file *fi
 	case VIDIOC_TRY_DECODER_CMD:
 	case VIDIOC_DBG_S_REGISTER:
 	case VIDIOC_DBG_G_REGISTER:
-	case VIDIOC_DBG_G_CHIP_IDENT:
 	case VIDIOC_S_HW_FREQ_SEEK:
 	case VIDIOC_S_DV_TIMINGS:
 	case VIDIOC_G_DV_TIMINGS:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-dev.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-dev.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-dev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-dev.c	2013-08-25 20:43:22.000000000 -0400
@@ -495,8 +495,8 @@ static const struct file_operations v4l2
 };
 
 /**
- * get_index - assign stream index number based on parent device
- * @vdev: video_device to assign index number to, vdev->parent should be assigned
+ * get_index - assign stream index number based on v4l2_dev
+ * @vdev: video_device to assign index number to, vdev->v4l2_dev should be assigned
  *
  * Note that when this is called the new device has not yet been registered
  * in the video_device array, but it was able to obtain a minor number.
@@ -514,15 +514,11 @@ static int get_index(struct video_device
 	static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
 	int i;
 
-	/* Some drivers do not set the parent. In that case always return 0. */
-	if (vdev->parent == NULL)
-		return 0;
-
 	bitmap_zero(used, VIDEO_NUM_DEVICES);
 
 	for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
 		if (video_device[i] != NULL &&
-		    video_device[i]->parent == vdev->parent) {
+		    video_device[i]->v4l2_dev == vdev->v4l2_dev) {
 			set_bit(video_device[i]->index, used);
 		}
 	}
@@ -596,7 +592,6 @@ static void determine_valid_ioctls(struc
 	set_bit(_IOC_NR(VIDIOC_DBG_G_REGISTER), valid_ioctls);
 	set_bit(_IOC_NR(VIDIOC_DBG_S_REGISTER), valid_ioctls);
 #endif
-	SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident);
 	/* yes, really vidioc_subscribe_event */
 	SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event);
 	SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event);
@@ -675,9 +670,8 @@ static void determine_valid_ioctls(struc
 		SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
 		if (ops->vidioc_s_std)
 			set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
-		if (ops->vidioc_g_std || vdev->current_norm)
-			set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls);
 		SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
+		SET_VALID_IOCTL(ops, VIDIOC_G_STD, vidioc_g_std);
 		if (is_rx) {
 			SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
 			SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
@@ -705,7 +699,7 @@ static void determine_valid_ioctls(struc
 		if (ops->vidioc_cropcap || ops->vidioc_g_selection)
 			set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls);
 		if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER &&
-					(ops->vidioc_g_std || vdev->current_norm)))
+					ops->vidioc_g_std))
 			set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);
 		SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
 		SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings);
@@ -777,6 +771,9 @@ int __video_register_device(struct video
 	/* the release callback MUST be present */
 	if (WARN_ON(!vdev->release))
 		return -EINVAL;
+	/* the v4l2_dev pointer MUST be present */
+	if (WARN_ON(!vdev->v4l2_dev))
+		return -EINVAL;
 
 	/* v4l2_fh support */
 	spin_lock_init(&vdev->fh_lock);
@@ -804,16 +801,14 @@ int __video_register_device(struct video
 
 	vdev->vfl_type = type;
 	vdev->cdev = NULL;
-	if (vdev->v4l2_dev) {
-		if (vdev->v4l2_dev->dev)
-			vdev->parent = vdev->v4l2_dev->dev;
-		if (vdev->ctrl_handler == NULL)
-			vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
-		/* If the prio state pointer is NULL, then use the v4l2_device
-		   prio state. */
-		if (vdev->prio == NULL)
-			vdev->prio = &vdev->v4l2_dev->prio;
-	}
+	if (vdev->dev_parent == NULL)
+		vdev->dev_parent = vdev->v4l2_dev->dev;
+	if (vdev->ctrl_handler == NULL)
+		vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
+	/* If the prio state pointer is NULL, then use the v4l2_device
+	   prio state. */
+	if (vdev->prio == NULL)
+		vdev->prio = &vdev->v4l2_dev->prio;
 
 	/* Part 2: find a free minor, device node number and device index. */
 #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
@@ -898,8 +893,7 @@ int __video_register_device(struct video
 	/* Part 4: register the device with sysfs */
 	vdev->dev.class = &video_class;
 	vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
-	if (vdev->parent)
-		vdev->dev.parent = vdev->parent;
+	vdev->dev.parent = vdev->dev_parent;
 	dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
 	ret = device_register(&vdev->dev);
 	if (ret < 0) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-device.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-device.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-device.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-device.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,7 +44,8 @@ int v4l2_device_register(struct device *
 	v4l2_dev->dev = dev;
 	if (dev == NULL) {
 		/* If dev == NULL, then name must be filled in by the caller */
-		WARN_ON(!v4l2_dev->name[0]);
+		if (WARN_ON(!v4l2_dev->name[0]))
+			return -EINVAL;
 		return 0;
 	}
 
@@ -105,7 +106,9 @@ void v4l2_device_unregister(struct v4l2_
 {
 	struct v4l2_subdev *sd, *next;
 
-	if (v4l2_dev == NULL)
+	/* Just return if v4l2_dev is NULL or if it was already
+	 * unregistered before. */
+	if (v4l2_dev == NULL || !v4l2_dev->name[0])
 		return;
 	v4l2_device_disconnect(v4l2_dev);
 
@@ -135,6 +138,8 @@ void v4l2_device_unregister(struct v4l2_
 		}
 #endif
 	}
+	/* Mark as unregistered, thus preventing duplicate unregistrations */
+	v4l2_dev->name[0] = '\0';
 }
 EXPORT_SYMBOL_GPL(v4l2_device_unregister);
 
@@ -269,8 +274,10 @@ void v4l2_device_unregister_subdev(struc
 	sd->v4l2_dev = NULL;
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-	if (v4l2_dev->mdev)
+	if (v4l2_dev->mdev) {
+		media_entity_remove_links(&sd->entity);
 		media_device_unregister_entity(&sd->entity);
+	}
 #endif
 	video_unregister_device(sd->devnode);
 	module_put(sd->owner);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-ioctl.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-ioctl.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/v4l2-ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/v4l2-ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,6 @@
 #include <media/v4l2-fh.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/videobuf2-core.h>
 
 /* Zero out the end of the struct pointed to by p.  Everything after, but
@@ -619,20 +618,6 @@ static void v4l_print_decoder_cmd(const
 		pr_info("pts=%llu\n", p->stop.pts);
 }
 
-static void v4l_print_dbg_chip_ident(const void *arg, bool write_only)
-{
-	const struct v4l2_dbg_chip_ident *p = arg;
-
-	pr_cont("type=%u, ", p->match.type);
-	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
-		pr_cont("name=%.*s, ",
-				(int)sizeof(p->match.name), p->match.name);
-	else
-		pr_cont("addr=%u, ", p->match.addr);
-	pr_cont("chip_ident=%u, revision=0x%x\n",
-			p->ident, p->revision);
-}
-
 static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
 {
 	const struct v4l2_dbg_chip_info *p = arg;
@@ -1359,40 +1344,18 @@ static int v4l_enumstd(const struct v4l2
 	return 0;
 }
 
-static int v4l_g_std(const struct v4l2_ioctl_ops *ops,
-				struct file *file, void *fh, void *arg)
-{
-	struct video_device *vfd = video_devdata(file);
-	v4l2_std_id *id = arg;
-
-	/* Calls the specific handler */
-	if (ops->vidioc_g_std)
-		return ops->vidioc_g_std(file, fh, arg);
-	if (vfd->current_norm) {
-		*id = vfd->current_norm;
-		return 0;
-	}
-	return -ENOTTY;
-}
-
 static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
 	struct video_device *vfd = video_devdata(file);
 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
-	int ret;
 
 	norm = id & vfd->tvnorms;
 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
 		return -EINVAL;
 
 	/* Calls the specific handler */
-	ret = ops->vidioc_s_std(file, fh, norm);
-
-	/* Updates standard information */
-	if (ret >= 0)
-		vfd->current_norm = norm;
-	return ret;
+	return ops->vidioc_s_std(file, fh, norm);
 }
 
 static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
@@ -1402,10 +1365,10 @@ static int v4l_querystd(const struct v4l
 	v4l2_std_id *p = arg;
 
 	/*
-	 * If nothing detected, it should return all supported
-	 * standard.
-	 * Drivers just need to mask the std argument, in order
-	 * to remove the standards that don't apply from the mask.
+	 * If no signal is detected, then the driver should return
+	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
+	 * any standards that do not apply removed.
+	 *
 	 * This means that tuners, audio and video decoders can join
 	 * their efforts to improve the standards detection.
 	 */
@@ -1495,7 +1458,6 @@ static int v4l_prepare_buf(const struct
 static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
-	struct video_device *vfd = video_devdata(file);
 	struct v4l2_streamparm *p = arg;
 	v4l2_std_id std;
 	int ret = check_fmt(file, p->type);
@@ -1504,16 +1466,13 @@ static int v4l_g_parm(const struct v4l2_
 		return ret;
 	if (ops->vidioc_g_parm)
 		return ops->vidioc_g_parm(file, fh, p);
-	std = vfd->current_norm;
 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 		return -EINVAL;
 	p->parm.capture.readbuffers = 2;
-	if (is_valid_ioctl(vfd, VIDIOC_G_STD) && ops->vidioc_g_std)
-		ret = ops->vidioc_g_std(file, fh, &std);
+	ret = ops->vidioc_g_std(file, fh, &std);
 	if (ret == 0)
-		v4l2_video_std_frame_period(std,
-			    &p->parm.capture.timeperframe);
+		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
 	return ret;
 }
 
@@ -1802,7 +1761,8 @@ static int v4l_dbg_g_register(const stru
 				return v4l2_subdev_call(sd, core, g_register, p);
 		return -EINVAL;
 	}
-	if (ops->vidioc_g_register)
+	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
+	    (ops->vidioc_g_chip_info || p->match.addr == 0))
 		return ops->vidioc_g_register(file, fh, p);
 	return -EINVAL;
 #else
@@ -1829,7 +1789,8 @@ static int v4l_dbg_s_register(const stru
 				return v4l2_subdev_call(sd, core, s_register, p);
 		return -EINVAL;
 	}
-	if (ops->vidioc_s_register)
+	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
+	    (ops->vidioc_g_chip_info || p->match.addr == 0))
 		return ops->vidioc_s_register(file, fh, p);
 	return -EINVAL;
 #else
@@ -1837,18 +1798,6 @@ static int v4l_dbg_s_register(const stru
 #endif
 }
 
-static int v4l_dbg_g_chip_ident(const struct v4l2_ioctl_ops *ops,
-				struct file *file, void *fh, void *arg)
-{
-	struct v4l2_dbg_chip_ident *p = arg;
-
-	p->ident = V4L2_IDENT_NONE;
-	p->revision = 0;
-	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV)
-		return -EINVAL;
-	return ops->vidioc_g_chip_ident(file, fh, p);
-}
-
 static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
@@ -1864,12 +1813,7 @@ static int v4l_dbg_g_chip_info(const str
 			p->flags |= V4L2_CHIP_FL_WRITABLE;
 		if (ops->vidioc_g_register)
 			p->flags |= V4L2_CHIP_FL_READABLE;
-		if (vfd->v4l2_dev)
-			strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
-		else if (vfd->parent)
-			strlcpy(p->name, vfd->parent->driver->name, sizeof(p->name));
-		else
-			strlcpy(p->name, "bridge", sizeof(p->name));
+		strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
 		if (ops->vidioc_g_chip_info)
 			return ops->vidioc_g_chip_info(file, fh, arg);
 		if (p->match.addr)
@@ -2048,7 +1992,7 @@ static struct v4l2_ioctl_info v4l2_ioctl
 	IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
 	IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
 	IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
-	IOCTL_INFO_FNC(VIDIOC_G_STD, v4l_g_std, v4l_print_std, 0),
+	IOCTL_INFO_STD(VIDIOC_G_STD, vidioc_g_std, v4l_print_std, 0),
 	IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
 	IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
 	IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
@@ -2098,7 +2042,6 @@ static struct v4l2_ioctl_info v4l2_ioctl
 	IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0),
 	IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
 	IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
-	IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_IDENT, v4l_dbg_g_chip_ident, v4l_print_dbg_chip_ident, 0),
 	IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
 	IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO),
 	IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/videobuf2-core.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/videobuf2-core.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/videobuf2-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/videobuf2-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -2194,8 +2194,10 @@ static int __vb2_init_fileio(struct vb2_
 	 */
 	for (i = 0; i < q->num_buffers; i++) {
 		fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
-		if (fileio->bufs[i].vaddr == NULL)
+		if (fileio->bufs[i].vaddr == NULL) {
+			ret = -EINVAL;
 			goto err_reqbufs;
+		}
 		fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/videobuf-dma-contig.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/videobuf-dma-contig.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/videobuf-dma-contig.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/videobuf-dma-contig.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,11 +66,14 @@ static void __videobuf_dc_free(struct de
 static void videobuf_vm_open(struct vm_area_struct *vma)
 {
 	struct videobuf_mapping *map = vma->vm_private_data;
+	struct videobuf_queue *q = map->q;
 
-	dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
+	dev_dbg(q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
 		map, map->count, vma->vm_start, vma->vm_end);
 
+	videobuf_queue_lock(q);
 	map->count++;
+	videobuf_queue_unlock(q);
 }
 
 static void videobuf_vm_close(struct vm_area_struct *vma)
@@ -82,12 +85,11 @@ static void videobuf_vm_close(struct vm_
 	dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
 		map, map->count, vma->vm_start, vma->vm_end);
 
-	map->count--;
-	if (0 == map->count) {
+	videobuf_queue_lock(q);
+	if (!--map->count) {
 		struct videobuf_dma_contig_memory *mem;
 
 		dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
-		videobuf_queue_lock(q);
 
 		/* We need first to cancel streams, before unmapping */
 		if (q->streaming)
@@ -126,8 +128,8 @@ static void videobuf_vm_close(struct vm_
 
 		kfree(map);
 
-		videobuf_queue_unlock(q);
 	}
+	videobuf_queue_unlock(q);
 }
 
 static const struct vm_operations_struct videobuf_vm_ops = {
@@ -303,14 +305,9 @@ static int __videobuf_mmap_mapper(struct
 		goto error;
 
 	/* Try to remap memory */
-
 	size = vma->vm_end - vma->vm_start;
-	size = (size < mem->size) ? size : mem->size;
-
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-	retval = remap_pfn_range(vma, vma->vm_start,
-				 mem->dma_handle >> PAGE_SHIFT,
-				 size, vma->vm_page_prot);
+	retval = vm_iomap_memory(vma, vma->vm_start, size);
 	if (retval) {
 		dev_err(q->dev, "mmap: remap failed with error %d. ",
 			retval);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/videobuf-dma-sg.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/videobuf-dma-sg.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/videobuf-dma-sg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/videobuf-dma-sg.c	2013-08-25 20:43:22.000000000 -0400
@@ -338,11 +338,14 @@ EXPORT_SYMBOL_GPL(videobuf_dma_free);
 static void videobuf_vm_open(struct vm_area_struct *vma)
 {
 	struct videobuf_mapping *map = vma->vm_private_data;
+	struct videobuf_queue *q = map->q;
 
 	dprintk(2, "vm_open %p [count=%d,vma=%08lx-%08lx]\n", map,
 		map->count, vma->vm_start, vma->vm_end);
 
+	videobuf_queue_lock(q);
 	map->count++;
+	videobuf_queue_unlock(q);
 }
 
 static void videobuf_vm_close(struct vm_area_struct *vma)
@@ -355,10 +358,9 @@ static void videobuf_vm_close(struct vm_
 	dprintk(2, "vm_close %p [count=%d,vma=%08lx-%08lx]\n", map,
 		map->count, vma->vm_start, vma->vm_end);
 
-	map->count--;
-	if (0 == map->count) {
+	videobuf_queue_lock(q);
+	if (!--map->count) {
 		dprintk(1, "munmap %p q=%p\n", map, q);
-		videobuf_queue_lock(q);
 		for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 			if (NULL == q->bufs[i])
 				continue;
@@ -374,9 +376,9 @@ static void videobuf_vm_close(struct vm_
 			q->bufs[i]->baddr = 0;
 			q->ops->buf_release(q, q->bufs[i]);
 		}
-		videobuf_queue_unlock(q);
 		kfree(map);
 	}
+	videobuf_queue_unlock(q);
 	return;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/media/v4l2-core/videobuf-vmalloc.c linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/videobuf-vmalloc.c
--- linux-libre-3.10-gnu/drivers/media/v4l2-core/videobuf-vmalloc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/media/v4l2-core/videobuf-vmalloc.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,11 +54,14 @@ MODULE_LICENSE("GPL");
 static void videobuf_vm_open(struct vm_area_struct *vma)
 {
 	struct videobuf_mapping *map = vma->vm_private_data;
+	struct videobuf_queue *q = map->q;
 
 	dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map,
 		map->count, vma->vm_start, vma->vm_end);
 
+	videobuf_queue_lock(q);
 	map->count++;
+	videobuf_queue_unlock(q);
 }
 
 static void videobuf_vm_close(struct vm_area_struct *vma)
@@ -70,12 +73,11 @@ static void videobuf_vm_close(struct vm_
 	dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map,
 		map->count, vma->vm_start, vma->vm_end);
 
-	map->count--;
-	if (0 == map->count) {
+	videobuf_queue_lock(q);
+	if (!--map->count) {
 		struct videobuf_vmalloc_memory *mem;
 
 		dprintk(1, "munmap %p q=%p\n", map, q);
-		videobuf_queue_lock(q);
 
 		/* We need first to cancel streams, before unmapping */
 		if (q->streaming)
@@ -114,8 +116,8 @@ static void videobuf_vm_close(struct vm_
 
 		kfree(map);
 
-		videobuf_queue_unlock(q);
 	}
+	videobuf_queue_unlock(q);
 
 	return;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/memory/Kconfig linux-libre-3.11-rc7-gnu/drivers/memory/Kconfig
--- linux-libre-3.10-gnu/drivers/memory/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/memory/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,16 @@ config TI_EMIF
 	  parameters and other settings during frequency, voltage and
 	  temperature changes
 
+config MVEBU_DEVBUS
+	bool "Marvell EBU Device Bus Controller"
+	default y
+	depends on PLAT_ORION && OF
+	help
+	  This driver is for the Device Bus controller available in some
+	  Marvell EBU SoCs such as Discovery (mv78xx0), Orion (88f5xxx) and
+	  Armada 370 and Armada XP. This controller allows to handle flash
+	  devices such as NOR, NAND, SRAM, and FPGA.
+
 config TEGRA20_MC
 	bool "Tegra20 Memory Controller(MC) driver"
 	default y
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/memory/Makefile linux-libre-3.11-rc7-gnu/drivers/memory/Makefile
--- linux-libre-3.10-gnu/drivers/memory/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/memory/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -6,5 +6,6 @@ ifeq ($(CONFIG_DDR),y)
 obj-$(CONFIG_OF)		+= of_memory.o
 endif
 obj-$(CONFIG_TI_EMIF)		+= emif.o
+obj-$(CONFIG_MVEBU_DEVBUS)	+= mvebu-devbus.o
 obj-$(CONFIG_TEGRA20_MC)	+= tegra20-mc.o
 obj-$(CONFIG_TEGRA30_MC)	+= tegra30-mc.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/memory/mvebu-devbus.c linux-libre-3.11-rc7-gnu/drivers/memory/mvebu-devbus.c
--- linux-libre-3.10-gnu/drivers/memory/mvebu-devbus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/memory/mvebu-devbus.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,340 @@
+/*
+ * Marvell EBU SoC Device Bus Controller
+ * (memory controller for NOR/NAND/SRAM/FPGA devices)
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/mbus.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+/* Register definitions */
+#define DEV_WIDTH_BIT		30
+#define BADR_SKEW_BIT		28
+#define RD_HOLD_BIT		23
+#define ACC_NEXT_BIT		17
+#define RD_SETUP_BIT		12
+#define ACC_FIRST_BIT		6
+
+#define SYNC_ENABLE_BIT		24
+#define WR_HIGH_BIT		16
+#define WR_LOW_BIT		8
+
+#define READ_PARAM_OFFSET	0x0
+#define WRITE_PARAM_OFFSET	0x4
+
+static const char * const devbus_wins[] = {
+	"devbus-boot",
+	"devbus-cs0",
+	"devbus-cs1",
+	"devbus-cs2",
+	"devbus-cs3",
+};
+
+struct devbus_read_params {
+	u32 bus_width;
+	u32 badr_skew;
+	u32 turn_off;
+	u32 acc_first;
+	u32 acc_next;
+	u32 rd_setup;
+	u32 rd_hold;
+};
+
+struct devbus_write_params {
+	u32 sync_enable;
+	u32 wr_high;
+	u32 wr_low;
+	u32 ale_wr;
+};
+
+struct devbus {
+	struct device *dev;
+	void __iomem *base;
+	unsigned long tick_ps;
+};
+
+static int get_timing_param_ps(struct devbus *devbus,
+			       struct device_node *node,
+			       const char *name,
+			       u32 *ticks)
+{
+	u32 time_ps;
+	int err;
+
+	err = of_property_read_u32(node, name, &time_ps);
+	if (err < 0) {
+		dev_err(devbus->dev, "%s has no '%s' property\n",
+			name, node->full_name);
+		return err;
+	}
+
+	*ticks = (time_ps + devbus->tick_ps - 1) / devbus->tick_ps;
+
+	dev_dbg(devbus->dev, "%s: %u ps -> 0x%x\n",
+		name, time_ps, *ticks);
+	return 0;
+}
+
+static int devbus_set_timing_params(struct devbus *devbus,
+				    struct device_node *node)
+{
+	struct devbus_read_params r;
+	struct devbus_write_params w;
+	u32 value;
+	int err;
+
+	dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n",
+		devbus->tick_ps);
+
+	/* Get read timings */
+	err = of_property_read_u32(node, "devbus,bus-width", &r.bus_width);
+	if (err < 0) {
+		dev_err(devbus->dev,
+			"%s has no 'devbus,bus-width' property\n",
+			node->full_name);
+		return err;
+	}
+	/* Convert bit width to byte width */
+	r.bus_width /= 8;
+
+	err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps",
+				 &r.badr_skew);
+	if (err < 0)
+		return err;
+
+	err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps",
+				 &r.turn_off);
+	if (err < 0)
+		return err;
+
+	err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps",
+				 &r.acc_first);
+	if (err < 0)
+		return err;
+
+	err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps",
+				 &r.acc_next);
+	if (err < 0)
+		return err;
+
+	err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps",
+				 &r.rd_setup);
+	if (err < 0)
+		return err;
+
+	err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps",
+				 &r.rd_hold);
+	if (err < 0)
+		return err;
+
+	/* Get write timings */
+	err = of_property_read_u32(node, "devbus,sync-enable",
+				  &w.sync_enable);
+	if (err < 0) {
+		dev_err(devbus->dev,
+			"%s has no 'devbus,sync-enable' property\n",
+			node->full_name);
+		return err;
+	}
+
+	err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps",
+				 &w.ale_wr);
+	if (err < 0)
+		return err;
+
+	err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps",
+				 &w.wr_low);
+	if (err < 0)
+		return err;
+
+	err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps",
+				 &w.wr_high);
+	if (err < 0)
+		return err;
+
+	/* Set read timings */
+	value = r.bus_width << DEV_WIDTH_BIT |
+		r.badr_skew << BADR_SKEW_BIT |
+		r.rd_hold   << RD_HOLD_BIT   |
+		r.acc_next  << ACC_NEXT_BIT  |
+		r.rd_setup  << RD_SETUP_BIT  |
+		r.acc_first << ACC_FIRST_BIT |
+		r.turn_off;
+
+	dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n",
+		devbus->base + READ_PARAM_OFFSET,
+		value);
+
+	writel(value, devbus->base + READ_PARAM_OFFSET);
+
+	/* Set write timings */
+	value = w.sync_enable  << SYNC_ENABLE_BIT |
+		w.wr_low       << WR_LOW_BIT      |
+		w.wr_high      << WR_HIGH_BIT     |
+		w.ale_wr;
+
+	dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n",
+		devbus->base + WRITE_PARAM_OFFSET,
+		value);
+
+	writel(value, devbus->base + WRITE_PARAM_OFFSET);
+
+	return 0;
+}
+
+static int mvebu_devbus_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *parent;
+	struct devbus *devbus;
+	struct resource *res;
+	struct clk *clk;
+	unsigned long rate;
+	const __be32 *ranges;
+	int err, cs;
+	int addr_cells, p_addr_cells, size_cells;
+	int ranges_len, tuple_len;
+	u32 base, size;
+
+	devbus = devm_kzalloc(&pdev->dev, sizeof(struct devbus), GFP_KERNEL);
+	if (!devbus)
+		return -ENOMEM;
+
+	devbus->dev = dev;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	devbus->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(devbus->base))
+		return PTR_ERR(devbus->base);
+
+	clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+	clk_prepare_enable(clk);
+
+	/*
+	 * Obtain clock period in picoseconds,
+	 * we need this in order to convert timing
+	 * parameters from cycles to picoseconds.
+	 */
+	rate = clk_get_rate(clk) / 1000;
+	devbus->tick_ps = 1000000000 / rate;
+
+	/* Read the device tree node and set the new timing parameters */
+	err = devbus_set_timing_params(devbus, node);
+	if (err < 0)
+		return err;
+
+	/*
+	 * Allocate an address window for this device.
+	 * If the device probing fails, then we won't be able to
+	 * remove the allocated address decoding window.
+	 *
+	 * FIXME: This is only a temporary hack! We need to do this here
+	 * because we still don't have device tree bindings for mbus.
+	 * Once that support is added, we will declare these address windows
+	 * statically in the device tree, and remove the window configuration
+	 * from here.
+	 */
+
+	/*
+	 * Get the CS to choose the window string.
+	 * This is a bit hacky, but it will be removed once the
+	 * address windows are declared in the device tree.
+	 */
+	cs = (((unsigned long)devbus->base) % 0x400) / 8;
+
+	/*
+	 * Parse 'ranges' property to obtain a (base,size) window tuple.
+	 * This will be removed once the address windows
+	 * are declared in the device tree.
+	 */
+	parent = of_get_parent(node);
+	if (!parent)
+		return -EINVAL;
+
+	p_addr_cells = of_n_addr_cells(parent);
+	of_node_put(parent);
+
+	addr_cells = of_n_addr_cells(node);
+	size_cells = of_n_size_cells(node);
+	tuple_len = (p_addr_cells + addr_cells + size_cells) * sizeof(__be32);
+
+	ranges = of_get_property(node, "ranges", &ranges_len);
+	if (ranges == NULL || ranges_len != tuple_len)
+		return -EINVAL;
+
+	base = of_translate_address(node, ranges + addr_cells);
+	if (base == OF_BAD_ADDR)
+		return -EINVAL;
+	size = of_read_number(ranges + addr_cells + p_addr_cells, size_cells);
+
+	/*
+	 * Create an mbus address windows.
+	 * FIXME: Remove this, together with the above code, once the
+	 * address windows are declared in the device tree.
+	 */
+	err = mvebu_mbus_add_window(devbus_wins[cs], base, size);
+	if (err < 0)
+		return err;
+
+	/*
+	 * We need to create a child device explicitly from here to
+	 * guarantee that the child will be probed after the timing
+	 * parameters for the bus are written.
+	 */
+	err = of_platform_populate(node, NULL, NULL, dev);
+	if (err < 0) {
+		mvebu_mbus_del_window(base, size);
+		return err;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id mvebu_devbus_of_match[] = {
+	{ .compatible = "marvell,mvebu-devbus" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match);
+
+static struct platform_driver mvebu_devbus_driver = {
+	.probe		= mvebu_devbus_probe,
+	.driver		= {
+		.name	= "mvebu-devbus",
+		.owner	= THIS_MODULE,
+		.of_match_table = mvebu_devbus_of_match,
+	},
+};
+
+static int __init mvebu_devbus_init(void)
+{
+	return platform_driver_register(&mvebu_devbus_driver);
+}
+module_init(mvebu_devbus_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell EBU SoC Device Bus controller");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/memory/tegra20-mc.c linux-libre-3.11-rc7-gnu/drivers/memory/tegra20-mc.c
--- linux-libre-3.10-gnu/drivers/memory/tegra20-mc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/memory/tegra20-mc.c	2013-08-25 20:43:22.000000000 -0400
@@ -193,8 +193,11 @@ static irqreturn_t tegra20_mc_isr(int ir
 	mask &= stat;
 	if (!mask)
 		return IRQ_NONE;
-	while ((bit = ffs(mask)) != 0)
+	while ((bit = ffs(mask)) != 0) {
 		tegra20_mc_decode(mc, bit - 1);
+		mask &= ~BIT(bit - 1);
+	}
+
 	mc_writel(mc, stat, MC_INTSTATUS);
 	return IRQ_HANDLED;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/memory/tegra30-mc.c linux-libre-3.11-rc7-gnu/drivers/memory/tegra30-mc.c
--- linux-libre-3.10-gnu/drivers/memory/tegra30-mc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/memory/tegra30-mc.c	2013-08-25 20:43:22.000000000 -0400
@@ -218,7 +218,7 @@ static void tegra30_mc_decode(struct teg
 		return;
 	}
 
-	err = readl(mc + MC_ERR_STATUS);
+	err = mc_readl(mc, MC_ERR_STATUS);
 
 	type = (err & MC_ERR_TYPE_MASK) >> MC_ERR_TYPE_SHIFT;
 	perm = (err & MC_ERR_INVALID_SMMU_PAGE_MASK) >>
@@ -235,7 +235,7 @@ static void tegra30_mc_decode(struct teg
 	if (cid < ARRAY_SIZE(tegra30_mc_client))
 		client = tegra30_mc_client[cid];
 
-	addr = readl(mc + MC_ERR_ADR);
+	addr = mc_readl(mc, MC_ERR_ADR);
 
 	dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s %s %s)\n",
 			   mc_int_err[idx], err, addr, client,
@@ -313,8 +313,11 @@ static irqreturn_t tegra30_mc_isr(int ir
 	mask &= stat;
 	if (!mask)
 		return IRQ_NONE;
-	while ((bit = ffs(mask)) != 0)
+	while ((bit = ffs(mask)) != 0) {
 		tegra30_mc_decode(mc, bit - 1);
+		mask &= ~BIT(bit - 1);
+	}
+
 	mc_writel(mc, stat, MC_INTSTATUS);
 	return IRQ_HANDLED;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/memstick/host/jmb38x_ms.c linux-libre-3.11-rc7-gnu/drivers/memstick/host/jmb38x_ms.c
--- linux-libre-3.10-gnu/drivers/memstick/host/jmb38x_ms.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/memstick/host/jmb38x_ms.c	2013-08-25 20:43:22.000000000 -0400
@@ -1046,20 +1046,9 @@ static struct pci_driver jmb38x_ms_drive
 	.resume = jmb38x_ms_resume
 };
 
-static int __init jmb38x_ms_init(void)
-{
-	return pci_register_driver(&jmb38x_ms_driver);
-}
-
-static void __exit jmb38x_ms_exit(void)
-{
-	pci_unregister_driver(&jmb38x_ms_driver);
-}
+module_pci_driver(jmb38x_ms_driver);
 
 MODULE_AUTHOR("Alex Dubov");
 MODULE_DESCRIPTION("JMicron jmb38x MemoryStick driver");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, jmb38x_ms_id_tbl);
-
-module_init(jmb38x_ms_init);
-module_exit(jmb38x_ms_exit);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/memstick/host/r592.c linux-libre-3.11-rc7-gnu/drivers/memstick/host/r592.c
--- linux-libre-3.10-gnu/drivers/memstick/host/r592.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/memstick/host/r592.c	2013-08-25 20:43:22.000000000 -0400
@@ -884,18 +884,7 @@ static struct pci_driver r852_pci_driver
 	.driver.pm	= &r592_pm_ops,
 };
 
-static __init int r592_module_init(void)
-{
-	return pci_register_driver(&r852_pci_driver);
-}
-
-static void __exit r592_module_exit(void)
-{
-	pci_unregister_driver(&r852_pci_driver);
-}
-
-module_init(r592_module_init);
-module_exit(r592_module_exit);
+module_pci_driver(r852_pci_driver);
 
 module_param_named(enable_dma, r592_enable_dma, bool, S_IRUGO);
 MODULE_PARM_DESC(enable_dma, "Enable usage of the DMA (default)");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/message/i2o/driver.c linux-libre-3.11-rc7-gnu/drivers/message/i2o/driver.c
--- linux-libre-3.10-gnu/drivers/message/i2o/driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/message/i2o/driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,8 +84,8 @@ int i2o_driver_register(struct i2o_drive
 	osm_debug("Register driver %s\n", drv->name);
 
 	if (drv->event) {
-		drv->event_queue = alloc_workqueue(drv->name,
-						   WQ_MEM_RECLAIM, 1);
+		drv->event_queue = alloc_workqueue("%s", WQ_MEM_RECLAIM, 1,
+						   drv->name);
 		if (!drv->event_queue) {
 			osm_err("Could not initialize event queue for driver "
 				"%s\n", drv->name);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/88pm800.c linux-libre-3.11-rc7-gnu/drivers/mfd/88pm800.c
--- linux-libre-3.10-gnu/drivers/mfd/88pm800.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/88pm800.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,13 +22,12 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/88pm80x.h>
 #include <linux/slab.h>
 
-#define PM800_CHIP_ID			(0x00)
-
 /* Interrupt Registers */
 #define PM800_INT_STATUS1		(0x05)
 #define PM800_ONKEY_INT_STS1		(1 << 0)
@@ -113,20 +112,11 @@ enum {
 	PM800_MAX_IRQ,
 };
 
-enum {
-	/* Procida */
-	PM800_CHIP_A0  = 0x60,
-	PM800_CHIP_A1  = 0x61,
-	PM800_CHIP_B0  = 0x62,
-	PM800_CHIP_C0  = 0x63,
-	PM800_CHIP_END = PM800_CHIP_C0,
-
-	/* Make sure to update this to the last stepping */
-	PM8XXX_CHIP_END = PM800_CHIP_END
-};
+/* PM800: generation identification number */
+#define PM800_CHIP_GEN_ID_NUM	0x3
 
 static const struct i2c_device_id pm80x_id_table[] = {
-	{"88PM800", CHIP_PM800},
+	{"88PM800", 0},
 	{} /* NULL terminated */
 };
 MODULE_DEVICE_TABLE(i2c, pm80x_id_table);
@@ -167,6 +157,13 @@ static struct mfd_cell onkey_devs[] = {
 	 },
 };
 
+static struct mfd_cell regulator_devs[] = {
+	{
+	 .name = "88pm80x-regulator",
+	 .id = -1,
+	},
+};
+
 static const struct regmap_irq pm800_irqs[] = {
 	/* INT0 */
 	[PM800_IRQ_ONKEY] = {
@@ -315,10 +312,59 @@ out:
 	return ret;
 }
 
+static int device_onkey_init(struct pm80x_chip *chip,
+				struct pm80x_platform_data *pdata)
+{
+	int ret;
+
+	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
+			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
+			      NULL);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add onkey subdev\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int device_rtc_init(struct pm80x_chip *chip,
+				struct pm80x_platform_data *pdata)
+{
+	int ret;
+
+	rtc_devs[0].platform_data = pdata->rtc;
+	rtc_devs[0].pdata_size =
+			pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
+	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
+			      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add rtc subdev\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int device_regulator_init(struct pm80x_chip *chip,
+					   struct pm80x_platform_data *pdata)
+{
+	int ret;
+
+	ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
+			      ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add regulator subdev\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int device_irq_init_800(struct pm80x_chip *chip)
 {
 	struct regmap *map = chip->regmap;
-	unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+	unsigned long flags = IRQF_ONESHOT;
 	int data, mask, ret = -EINVAL;
 
 	if (!map || !chip->irq) {
@@ -362,6 +408,7 @@ static struct regmap_irq_chip pm800_irq_
 	.status_base = PM800_INT_STATUS1,
 	.mask_base = PM800_INT_ENA_1,
 	.ack_base = PM800_INT_STATUS1,
+	.mask_invert = 1,
 };
 
 static int pm800_pages_init(struct pm80x_chip *chip)
@@ -369,77 +416,72 @@ static int pm800_pages_init(struct pm80x
 	struct pm80x_subchip *subchip;
 	struct i2c_client *client = chip->client;
 
+	int ret = 0;
+
 	subchip = chip->subchip;
-	/* PM800 block power: i2c addr 0x31 */
-	if (subchip->power_page_addr) {
-		subchip->power_page =
-		    i2c_new_dummy(client->adapter, subchip->power_page_addr);
-		subchip->regmap_power =
-		    devm_regmap_init_i2c(subchip->power_page,
-					 &pm80x_regmap_config);
-		i2c_set_clientdata(subchip->power_page, chip);
-	} else
-		dev_info(chip->dev,
-			 "PM800 block power 0x31: No power_page_addr\n");
+	if (!subchip || !subchip->power_page_addr || !subchip->gpadc_page_addr)
+		return -ENODEV;
 
-	/* PM800 block GPADC: i2c addr 0x32 */
-	if (subchip->gpadc_page_addr) {
-		subchip->gpadc_page = i2c_new_dummy(client->adapter,
-						    subchip->gpadc_page_addr);
-		subchip->regmap_gpadc =
-		    devm_regmap_init_i2c(subchip->gpadc_page,
-					 &pm80x_regmap_config);
-		i2c_set_clientdata(subchip->gpadc_page, chip);
-	} else
-		dev_info(chip->dev,
-			 "PM800 block GPADC 0x32: No gpadc_page_addr\n");
+	/* PM800 block power page */
+	subchip->power_page = i2c_new_dummy(client->adapter,
+					    subchip->power_page_addr);
+	if (subchip->power_page == NULL) {
+		ret = -ENODEV;
+		goto out;
+	}
 
-	return 0;
+	subchip->regmap_power = devm_regmap_init_i2c(subchip->power_page,
+						     &pm80x_regmap_config);
+	if (IS_ERR(subchip->regmap_power)) {
+		ret = PTR_ERR(subchip->regmap_power);
+		dev_err(chip->dev,
+			"Failed to allocate regmap_power: %d\n", ret);
+		goto out;
+	}
+
+	i2c_set_clientdata(subchip->power_page, chip);
+
+	/* PM800 block GPADC */
+	subchip->gpadc_page = i2c_new_dummy(client->adapter,
+					    subchip->gpadc_page_addr);
+	if (subchip->gpadc_page == NULL) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	subchip->regmap_gpadc = devm_regmap_init_i2c(subchip->gpadc_page,
+						     &pm80x_regmap_config);
+	if (IS_ERR(subchip->regmap_gpadc)) {
+		ret = PTR_ERR(subchip->regmap_gpadc);
+		dev_err(chip->dev,
+			"Failed to allocate regmap_gpadc: %d\n", ret);
+		goto out;
+	}
+	i2c_set_clientdata(subchip->gpadc_page, chip);
+
+out:
+	return ret;
 }
 
 static void pm800_pages_exit(struct pm80x_chip *chip)
 {
 	struct pm80x_subchip *subchip;
 
-	regmap_exit(chip->regmap);
-	i2c_unregister_device(chip->client);
-
 	subchip = chip->subchip;
-	if (subchip->power_page) {
-		regmap_exit(subchip->regmap_power);
+
+	if (subchip && subchip->power_page)
 		i2c_unregister_device(subchip->power_page);
-	}
-	if (subchip->gpadc_page) {
-		regmap_exit(subchip->regmap_gpadc);
+
+	if (subchip && subchip->gpadc_page)
 		i2c_unregister_device(subchip->gpadc_page);
-	}
 }
 
 static int device_800_init(struct pm80x_chip *chip,
 				     struct pm80x_platform_data *pdata)
 {
-	int ret, pmic_id;
+	int ret;
 	unsigned int val;
 
-	ret = regmap_read(chip->regmap, PM800_CHIP_ID, &val);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
-		goto out;
-	}
-
-	pmic_id = val & PM80X_VERSION_MASK;
-
-	if ((pmic_id >= PM800_CHIP_A0) && (pmic_id <= PM800_CHIP_END)) {
-		chip->version = val;
-		dev_info(chip->dev,
-			 "88PM80x:Marvell 88PM800 (ID:0x%x) detected\n", val);
-	} else {
-		dev_err(chip->dev,
-			"Failed to detect Marvell 88PM800:ChipID[0x%x]\n", val);
-		ret = -EINVAL;
-		goto out;
-	}
-
 	/*
 	 * alarm wake up bit will be clear in device_irq_init(),
 	 * read before that
@@ -468,27 +510,22 @@ static int device_800_init(struct pm80x_
 		goto out;
 	}
 
-	ret =
-	    mfd_add_devices(chip->dev, 0, &onkey_devs[0],
-			    ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
-			    NULL);
-	if (ret < 0) {
+	ret = device_onkey_init(chip, pdata);
+	if (ret) {
 		dev_err(chip->dev, "Failed to add onkey subdev\n");
 		goto out_dev;
-	} else
-		dev_info(chip->dev, "[%s]:Added mfd onkey_devs\n", __func__);
+	}
 
-	if (pdata && pdata->rtc) {
-		rtc_devs[0].platform_data = pdata->rtc;
-		rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata);
-		ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
-				      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
-		if (ret < 0) {
-			dev_err(chip->dev, "Failed to add rtc subdev\n");
-			goto out_dev;
-		} else
-			dev_info(chip->dev,
-				 "[%s]:Added mfd rtc_devs\n", __func__);
+	ret = device_rtc_init(chip, pdata);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add rtc subdev\n");
+		goto out;
+	}
+
+	ret = device_regulator_init(chip, pdata);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add regulators subdev\n");
+		goto out;
 	}
 
 	return 0;
@@ -507,7 +544,7 @@ static int pm800_probe(struct i2c_client
 	struct pm80x_platform_data *pdata = client->dev.platform_data;
 	struct pm80x_subchip *subchip;
 
-	ret = pm80x_init(client, id);
+	ret = pm80x_init(client);
 	if (ret) {
 		dev_err(&client->dev, "pm800_init fail\n");
 		goto out_init;
@@ -524,28 +561,31 @@ static int pm800_probe(struct i2c_client
 		goto err_subchip_alloc;
 	}
 
-	subchip->power_page_addr = pdata->power_page_addr;
-	subchip->gpadc_page_addr = pdata->gpadc_page_addr;
+	/* pm800 has 2 addtional pages to support power and gpadc. */
+	subchip->power_page_addr = client->addr + 1;
+	subchip->gpadc_page_addr = client->addr + 2;
 	chip->subchip = subchip;
 
-	ret = device_800_init(chip, pdata);
-	if (ret) {
-		dev_err(chip->dev, "%s id 0x%x failed!\n", __func__, chip->id);
-		goto err_subchip_alloc;
-	}
-
 	ret = pm800_pages_init(chip);
 	if (ret) {
 		dev_err(&client->dev, "pm800_pages_init failed!\n");
 		goto err_page_init;
 	}
 
+	ret = device_800_init(chip, pdata);
+	if (ret) {
+		dev_err(chip->dev, "Failed to initialize 88pm800 devices\n");
+		goto err_device_init;
+	}
+
 	if (pdata->plat_config)
 		pdata->plat_config(chip, pdata);
 
+	return 0;
+
+err_device_init:
+	pm800_pages_exit(chip);
 err_page_init:
-	mfd_remove_devices(chip->dev);
-	device_irq_exit_800(chip);
 err_subchip_alloc:
 	pm80x_deinit();
 out_init:
@@ -567,7 +607,7 @@ static int pm800_remove(struct i2c_clien
 
 static struct i2c_driver pm800_driver = {
 	.driver = {
-		.name = "88PM80X",
+		.name = "88PM800",
 		.owner = THIS_MODULE,
 		.pm = &pm80x_pm_ops,
 		},
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/88pm805.c linux-libre-3.11-rc7-gnu/drivers/mfd/88pm805.c
--- linux-libre-3.10-gnu/drivers/mfd/88pm805.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/88pm805.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,10 +29,8 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
-#define PM805_CHIP_ID			(0x00)
-
 static const struct i2c_device_id pm80x_id_table[] = {
-	{"88PM805", CHIP_PM805},
+	{"88PM805", 0},
 	{} /* NULL terminated */
 };
 MODULE_DEVICE_TABLE(i2c, pm80x_id_table);
@@ -138,7 +136,7 @@ static struct regmap_irq pm805_irqs[] =
 static int device_irq_init_805(struct pm80x_chip *chip)
 {
 	struct regmap *map = chip->regmap;
-	unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+	unsigned long flags = IRQF_ONESHOT;
 	int data, mask, ret = -EINVAL;
 
 	if (!map || !chip->irq) {
@@ -192,7 +190,6 @@ static struct regmap_irq_chip pm805_irq_
 static int device_805_init(struct pm80x_chip *chip)
 {
 	int ret = 0;
-	unsigned int val;
 	struct regmap *map = chip->regmap;
 
 	if (!map) {
@@ -200,13 +197,6 @@ static int device_805_init(struct pm80x_
 		return -EINVAL;
 	}
 
-	ret = regmap_read(map, PM805_CHIP_ID, &val);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
-		goto out_irq_init;
-	}
-	chip->version = val;
-
 	chip->regmap_irq_chip = &pm805_irq_chip;
 
 	ret = device_irq_init_805(chip);
@@ -239,7 +229,7 @@ static int pm805_probe(struct i2c_client
 	struct pm80x_chip *chip;
 	struct pm80x_platform_data *pdata = client->dev.platform_data;
 
-	ret = pm80x_init(client, id);
+	ret = pm80x_init(client);
 	if (ret) {
 		dev_err(&client->dev, "pm805_init fail!\n");
 		goto out_init;
@@ -249,7 +239,7 @@ static int pm805_probe(struct i2c_client
 
 	ret = device_805_init(chip);
 	if (ret) {
-		dev_err(chip->dev, "%s id 0x%x failed!\n", __func__, chip->id);
+		dev_err(chip->dev, "Failed to initialize 88pm805 devices\n");
 		goto err_805_init;
 	}
 
@@ -276,7 +266,7 @@ static int pm805_remove(struct i2c_clien
 
 static struct i2c_driver pm805_driver = {
 	.driver = {
-		.name = "88PM80X",
+		.name = "88PM805",
 		.owner = THIS_MODULE,
 		.pm = &pm80x_pm_ops,
 		},
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/88pm80x.c linux-libre-3.11-rc7-gnu/drivers/mfd/88pm80x.c
--- linux-libre-3.10-gnu/drivers/mfd/88pm80x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/88pm80x.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,23 @@
 #include <linux/uaccess.h>
 #include <linux/err.h>
 
+/* 88pm80x chips have same definition for chip id register. */
+#define PM80X_CHIP_ID			(0x00)
+#define PM80X_CHIP_ID_NUM(x)		(((x) >> 5) & 0x7)
+#define PM80X_CHIP_ID_REVISION(x)	((x) & 0x1F)
+
+struct pm80x_chip_mapping {
+	unsigned int	id;
+	int		type;
+};
+
+static struct pm80x_chip_mapping chip_mapping[] = {
+	/* 88PM800 chip id number */
+	{0x3,	CHIP_PM800},
+	/* 88PM805 chip id number */
+	{0x0,	CHIP_PM805},
+};
+
 /*
  * workaround: some registers needed by pm805 are defined in pm800, so
  * need to use this global variable to maintain the relation between
@@ -31,12 +48,13 @@ const struct regmap_config pm80x_regmap_
 };
 EXPORT_SYMBOL_GPL(pm80x_regmap_config);
 
-int pm80x_init(struct i2c_client *client,
-				 const struct i2c_device_id *id)
+
+int pm80x_init(struct i2c_client *client)
 {
 	struct pm80x_chip *chip;
 	struct regmap *map;
-	int ret = 0;
+	unsigned int val;
+	int i, ret = 0;
 
 	chip =
 	    devm_kzalloc(&client->dev, sizeof(struct pm80x_chip), GFP_KERNEL);
@@ -51,10 +69,6 @@ int pm80x_init(struct i2c_client *client
 		return ret;
 	}
 
-	chip->id = id->driver_data;
-	if (chip->id < CHIP_PM800 || chip->id > CHIP_PM805)
-		return -EINVAL;
-
 	chip->client = client;
 	chip->regmap = map;
 
@@ -64,6 +78,25 @@ int pm80x_init(struct i2c_client *client
 	dev_set_drvdata(chip->dev, chip);
 	i2c_set_clientdata(chip->client, chip);
 
+	ret = regmap_read(chip->regmap, PM80X_CHIP_ID, &val);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(chip_mapping); i++) {
+		if (chip_mapping[i].id == PM80X_CHIP_ID_NUM(val)) {
+			chip->type = chip_mapping[i].type;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(chip_mapping)) {
+		dev_err(chip->dev,
+			"Failed to detect Marvell 88PM800:ChipID[0x%x]\n", val);
+		return -EINVAL;
+	}
+
 	device_init_wakeup(&client->dev, 1);
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/88pm860x-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/88pm860x-core.c
--- linux-libre-3.10-gnu/drivers/mfd/88pm860x-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/88pm860x-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -1150,17 +1150,17 @@ static int pm860x_probe(struct i2c_clien
 		return -EINVAL;
 	}
 
-	chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
+	chip = devm_kzalloc(&client->dev,
+			    sizeof(struct pm860x_chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 
 	chip->id = verify_addr(client);
-	chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
+	chip->regmap = devm_regmap_init_i2c(client, &pm860x_regmap_config);
 	if (IS_ERR(chip->regmap)) {
 		ret = PTR_ERR(chip->regmap);
 		dev_err(&client->dev, "Failed to allocate register map: %d\n",
 				ret);
-		kfree(chip);
 		return ret;
 	}
 	chip->client = client;
@@ -1203,8 +1203,6 @@ static int pm860x_remove(struct i2c_clie
 		regmap_exit(chip->regmap_companion);
 		i2c_unregister_device(chip->companion);
 	}
-	regmap_exit(chip->regmap);
-	kfree(chip);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/aat2870-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/aat2870-core.c
--- linux-libre-3.10-gnu/drivers/mfd/aat2870-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/aat2870-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -312,8 +312,9 @@ static ssize_t aat2870_reg_write_file(st
 	while (*start == ' ')
 		start++;
 
-	if (strict_strtoul(start, 16, &val))
-		return -EINVAL;
+	ret = kstrtoul(start, 16, &val);
+	if (ret)
+		return ret;
 
 	ret = aat2870->write(aat2870, (u8)addr, (u8)val);
 	if (ret)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/ab3100-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/ab3100-core.c
--- linux-libre-3.10-gnu/drivers/mfd/ab3100-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/ab3100-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -491,7 +491,7 @@ static ssize_t ab3100_get_set_reg(struct
 	char buf[32];
 	ssize_t buf_size;
 	int regp;
-	unsigned long user_reg;
+	u8 user_reg;
 	int err;
 	int i = 0;
 
@@ -514,34 +514,29 @@ static ssize_t ab3100_get_set_reg(struct
 	/*
 	 * Advance pointer to end of string then terminate
 	 * the register string. This is needed to satisfy
-	 * the strict_strtoul() function.
+	 * the kstrtou8() function.
 	 */
 	while ((i < buf_size) && (buf[i] != ' '))
 		i++;
 	buf[i] = '\0';
 
-	err = strict_strtoul(&buf[regp], 16, &user_reg);
+	err = kstrtou8(&buf[regp], 16, &user_reg);
 	if (err)
 		return err;
-	if (user_reg > 0xff)
-		return -EINVAL;
 
 	/* Either we read or we write a register here */
 	if (!priv->mode) {
 		/* Reading */
-		u8 reg = (u8) user_reg;
 		u8 regvalue;
 
-		ab3100_get_register_interruptible(ab3100, reg, &regvalue);
+		ab3100_get_register_interruptible(ab3100, user_reg, &regvalue);
 
 		dev_info(ab3100->dev,
 			 "debug read AB3100 reg[0x%02x]: 0x%02x\n",
-			 reg, regvalue);
+			 user_reg, regvalue);
 	} else {
 		int valp;
-		unsigned long user_value;
-		u8 reg = (u8) user_reg;
-		u8 value;
+		u8 user_value;
 		u8 regvalue;
 
 		/*
@@ -557,20 +552,17 @@ static ssize_t ab3100_get_set_reg(struct
 			i++;
 		buf[i] = '\0';
 
-		err = strict_strtoul(&buf[valp], 16, &user_value);
+		err = kstrtou8(&buf[valp], 16, &user_value);
 		if (err)
 			return err;
-		if (user_reg > 0xff)
-			return -EINVAL;
 
-		value = (u8) user_value;
-		ab3100_set_register_interruptible(ab3100, reg, value);
-		ab3100_get_register_interruptible(ab3100, reg, &regvalue);
+		ab3100_set_register_interruptible(ab3100, user_reg, user_value);
+		ab3100_get_register_interruptible(ab3100, user_reg, &regvalue);
 
 		dev_info(ab3100->dev,
 			 "debug write reg[0x%02x] with 0x%02x, "
 			 "after readback: 0x%02x\n",
-			 reg, value, regvalue);
+			 user_reg, user_value, regvalue);
 	}
 	return buf_size;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/ab3100-otp.c linux-libre-3.11-rc7-gnu/drivers/mfd/ab3100-otp.c
--- linux-libre-3.10-gnu/drivers/mfd/ab3100-otp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/ab3100-otp.c	2013-08-25 20:43:22.000000000 -0400
@@ -187,7 +187,7 @@ static int __init ab3100_otp_probe(struc
 	int err = 0;
 	int i;
 
-	otp = kzalloc(sizeof(struct ab3100_otp), GFP_KERNEL);
+	otp = devm_kzalloc(&pdev->dev, sizeof(struct ab3100_otp), GFP_KERNEL);
 	if (!otp) {
 		dev_err(&pdev->dev, "could not allocate AB3100 OTP device\n");
 		return -ENOMEM;
@@ -199,7 +199,7 @@ static int __init ab3100_otp_probe(struc
 
 	err = ab3100_otp_read(otp);
 	if (err)
-		goto err_otp_read;
+		return err;
 
 	dev_info(&pdev->dev, "AB3100 OTP readout registered\n");
 
@@ -208,22 +208,19 @@ static int __init ab3100_otp_probe(struc
 		err = device_create_file(&pdev->dev,
 					 &ab3100_otp_attrs[i]);
 		if (err)
-			goto err_create_file;
+			goto err;
 	}
 
 	/* debugfs entries */
 	err = ab3100_otp_init_debugfs(&pdev->dev, otp);
 	if (err)
-		goto err_init_debugfs;
+		goto err;
 
 	return 0;
 
-err_init_debugfs:
-err_create_file:
+err:
 	while (--i >= 0)
 		device_remove_file(&pdev->dev, &ab3100_otp_attrs[i]);
-err_otp_read:
-	kfree(otp);
 	return err;
 }
 
@@ -236,7 +233,6 @@ static int __exit ab3100_otp_remove(stru
 		device_remove_file(&pdev->dev,
 				   &ab3100_otp_attrs[i]);
 	ab3100_otp_exit_debugfs(otp);
-	kfree(otp);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/ab8500-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/ab8500-core.c
--- linux-libre-3.10-gnu/drivers/mfd/ab8500-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/ab8500-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -650,6 +650,21 @@ static struct resource ab8500_rtc_resour
 	},
 };
 
+static struct resource ab8540_rtc_resources[] = {
+	{
+		.name	= "1S",
+		.start	= AB8540_INT_RTC_1S,
+		.end	= AB8540_INT_RTC_1S,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "ALARM",
+		.start	= AB8500_INT_RTC_ALARM,
+		.end	= AB8500_INT_RTC_ALARM,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
 static struct resource ab8500_poweronkey_db_resources[] = {
 	{
 		.name	= "ONKEY_DBF",
@@ -1051,6 +1066,10 @@ static struct mfd_cell ab8500_devs[] = {
 		.of_compatible = "stericsson,ab8500-sysctrl",
 	},
 	{
+		.name = "ab8500-ext-regulator",
+		.of_compatible = "stericsson,ab8500-ext-regulator",
+	},
+	{
 		.name = "ab8500-regulator",
 		.of_compatible = "stericsson,ab8500-regulator",
 	},
@@ -1099,10 +1118,6 @@ static struct mfd_cell ab8500_devs[] = {
 		.id = 3,
 	},
 	{
-		.name = "ab8500-leds",
-		.of_compatible = "stericsson,ab8500-leds",
-	},
-	{
 		.name = "ab8500-denc",
 		.of_compatible = "stericsson,ab8500-denc",
 	},
@@ -1124,6 +1139,7 @@ static struct mfd_cell ab8500_devs[] = {
 	},
 	{
 		.name = "ab8500-codec",
+		.of_compatible = "stericsson,ab8500-codec",
 	},
 };
 
@@ -1139,6 +1155,9 @@ static struct mfd_cell ab9540_devs[] = {
 		.name = "ab8500-sysctrl",
 	},
 	{
+		.name = "ab8500-ext-regulator",
+	},
+	{
 		.name = "ab8500-regulator",
 	},
 	{
@@ -1171,9 +1190,6 @@ static struct mfd_cell ab9540_devs[] = {
 		.id = 1,
 	},
 	{
-		.name = "ab8500-leds",
-	},
-	{
 		.name = "abx500-temp",
 		.num_resources = ARRAY_SIZE(ab8500_temp_resources),
 		.resources = ab8500_temp_resources,
@@ -1242,9 +1258,6 @@ static struct mfd_cell ab8505_devs[] = {
 		.id = 1,
 	},
 	{
-		.name = "ab8500-leds",
-	},
-	{
 		.name = "pinctrl-ab8505",
 	},
 	{
@@ -1274,6 +1287,9 @@ static struct mfd_cell ab8540_devs[] = {
 		.name = "ab8500-sysctrl",
 	},
 	{
+		.name = "ab8500-ext-regulator",
+	},
+	{
 		.name = "ab8500-regulator",
 	},
 	{
@@ -1287,11 +1303,6 @@ static struct mfd_cell ab8540_devs[] = {
 		.resources = ab8505_gpadc_resources,
 	},
 	{
-		.name = "ab8500-rtc",
-		.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
-		.resources = ab8500_rtc_resources,
-	},
-	{
 		.name = "ab8500-acc-det",
 		.num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources),
 		.resources = ab8500_av_acc_detect_resources,
@@ -1306,9 +1317,6 @@ static struct mfd_cell ab8540_devs[] = {
 		.id = 1,
 	},
 	{
-		.name = "ab8500-leds",
-	},
-	{
 		.name = "abx500-temp",
 		.num_resources = ARRAY_SIZE(ab8500_temp_resources),
 		.resources = ab8500_temp_resources,
@@ -1331,6 +1339,24 @@ static struct mfd_cell ab8540_devs[] = {
 	},
 };
 
+static struct mfd_cell ab8540_cut1_devs[] = {
+	{
+		.name = "ab8500-rtc",
+		.of_compatible = "stericsson,ab8500-rtc",
+		.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
+		.resources = ab8500_rtc_resources,
+	},
+};
+
+static struct mfd_cell ab8540_cut2_devs[] = {
+	{
+		.name = "ab8540-rtc",
+		.of_compatible = "stericsson,ab8540-rtc",
+		.num_resources = ARRAY_SIZE(ab8540_rtc_resources),
+		.resources = ab8540_rtc_resources,
+	},
+};
+
 static ssize_t show_chip_id(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -1734,11 +1760,22 @@ static int ab8500_probe(struct platform_
 		ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
 				ARRAY_SIZE(ab9540_devs), NULL,
 				ab8500->irq_base, ab8500->domain);
-	else if (is_ab8540(ab8500))
+	else if (is_ab8540(ab8500)) {
 		ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs,
 			      ARRAY_SIZE(ab8540_devs), NULL,
-			      ab8500->irq_base, ab8500->domain);
-	else if (is_ab8505(ab8500))
+			      ab8500->irq_base, NULL);
+		if (ret)
+			return ret;
+
+		if (is_ab8540_1p2_or_earlier(ab8500))
+			ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut1_devs,
+			      ARRAY_SIZE(ab8540_cut1_devs), NULL,
+			      ab8500->irq_base, NULL);
+		else /* ab8540 >= cut2 */
+			ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut2_devs,
+			      ARRAY_SIZE(ab8540_cut2_devs), NULL,
+			      ab8500->irq_base, NULL);
+	} else if (is_ab8505(ab8500))
 		ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs,
 			      ARRAY_SIZE(ab8505_devs), NULL,
 			      ab8500->irq_base, ab8500->domain);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/ab8500-debugfs.c linux-libre-3.11-rc7-gnu/drivers/mfd/ab8500-debugfs.c
--- linux-libre-3.10-gnu/drivers/mfd/ab8500-debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/ab8500-debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -2757,7 +2757,7 @@ static ssize_t show_irq(struct device *d
 	unsigned int irq_index;
 	int err;
 
-	err = strict_strtoul(attr->attr.name, 0, &name);
+	err = kstrtoul(attr->attr.name, 0, &name);
 	if (err)
 		return err;
 
@@ -2937,7 +2937,6 @@ static struct dentry *ab8500_gpadc_dir;
 static int ab8500_debug_probe(struct platform_device *plf)
 {
 	struct dentry *file;
-	int ret = -ENOMEM;
 	struct ab8500 *ab8500;
 	struct resource *res;
 	debug_bank = AB8500_MISC;
@@ -2946,24 +2945,26 @@ static int ab8500_debug_probe(struct pla
 	ab8500 = dev_get_drvdata(plf->dev.parent);
 	num_irqs = ab8500->mask_size;
 
-	irq_count = kzalloc(sizeof(*irq_count)*num_irqs, GFP_KERNEL);
+	irq_count = devm_kzalloc(&plf->dev,
+				 sizeof(*irq_count)*num_irqs, GFP_KERNEL);
 	if (!irq_count)
 		return -ENOMEM;
 
-	dev_attr = kzalloc(sizeof(*dev_attr)*num_irqs,GFP_KERNEL);
+	dev_attr = devm_kzalloc(&plf->dev,
+				sizeof(*dev_attr)*num_irqs,GFP_KERNEL);
 	if (!dev_attr)
-		goto out_freeirq_count;
+		return -ENOMEM;
 
-	event_name = kzalloc(sizeof(*event_name)*num_irqs, GFP_KERNEL);
+	event_name = devm_kzalloc(&plf->dev,
+				  sizeof(*event_name)*num_irqs, GFP_KERNEL);
 	if (!event_name)
-		goto out_freedev_attr;
+		return -ENOMEM;
 
 	res = platform_get_resource_byname(plf, 0, "IRQ_AB8500");
 	if (!res) {
 		dev_err(&plf->dev, "AB8500 irq not found, err %d\n",
 			irq_first);
-		ret = -ENXIO;
-		goto out_freeevent_name;
+		return ENXIO;
 	}
 	irq_ab8500 = res->start;
 
@@ -2971,16 +2972,14 @@ static int ab8500_debug_probe(struct pla
 	if (irq_first < 0) {
 		dev_err(&plf->dev, "First irq not found, err %d\n",
 			irq_first);
-		ret = irq_first;
-		goto out_freeevent_name;
+		return irq_first;
 	}
 
 	irq_last = platform_get_irq_byname(plf, "IRQ_LAST");
 	if (irq_last < 0) {
 		dev_err(&plf->dev, "Last irq not found, err %d\n",
 			irq_last);
-		ret = irq_last;
-		goto out_freeevent_name;
+		return irq_last;
 	}
 
 	ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
@@ -3189,22 +3188,13 @@ err:
 	if (ab8500_dir)
 		debugfs_remove_recursive(ab8500_dir);
 	dev_err(&plf->dev, "failed to create debugfs entries.\n");
-out_freeevent_name:
-	kfree(event_name);
-out_freedev_attr:
-	kfree(dev_attr);
-out_freeirq_count:
-	kfree(irq_count);
 
-	return ret;
+	return -ENOMEM;
 }
 
 static int ab8500_debug_remove(struct platform_device *plf)
 {
 	debugfs_remove_recursive(ab8500_dir);
-	kfree(event_name);
-	kfree(dev_attr);
-	kfree(irq_count);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/ab8500-gpadc.c linux-libre-3.11-rc7-gnu/drivers/mfd/ab8500-gpadc.c
--- linux-libre-3.10-gnu/drivers/mfd/ab8500-gpadc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/ab8500-gpadc.c	2013-08-25 20:43:22.000000000 -0400
@@ -886,12 +886,6 @@ static int ab8500_gpadc_runtime_resume(s
 	return ret;
 }
 
-static int ab8500_gpadc_runtime_idle(struct device *dev)
-{
-	pm_runtime_suspend(dev);
-	return 0;
-}
-
 static int ab8500_gpadc_suspend(struct device *dev)
 {
 	struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
@@ -925,7 +919,7 @@ static int ab8500_gpadc_probe(struct pla
 	int ret = 0;
 	struct ab8500_gpadc *gpadc;
 
-	gpadc = kzalloc(sizeof(struct ab8500_gpadc), GFP_KERNEL);
+	gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
 	if (!gpadc) {
 		dev_err(&pdev->dev, "Error: No memory\n");
 		return -ENOMEM;
@@ -1005,8 +999,6 @@ fail_irq:
 	free_irq(gpadc->irq_sw, gpadc);
 	free_irq(gpadc->irq_hw, gpadc);
 fail:
-	kfree(gpadc);
-	gpadc = NULL;
 	return ret;
 }
 
@@ -1031,15 +1023,13 @@ static int ab8500_gpadc_remove(struct pl
 
 	pm_runtime_put_noidle(gpadc->dev);
 
-	kfree(gpadc);
-	gpadc = NULL;
 	return 0;
 }
 
 static const struct dev_pm_ops ab8500_gpadc_pm_ops = {
 	SET_RUNTIME_PM_OPS(ab8500_gpadc_runtime_suspend,
 			   ab8500_gpadc_runtime_resume,
-			   ab8500_gpadc_runtime_idle)
+			   NULL)
 	SET_SYSTEM_SLEEP_PM_OPS(ab8500_gpadc_suspend,
 				ab8500_gpadc_resume)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/abx500-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/abx500-core.c
--- linux-libre-3.10-gnu/drivers/mfd/abx500-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/abx500-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,9 @@ int abx500_register_ops(struct device *d
 {
 	struct abx500_device_entry *dev_entry;
 
-	dev_entry = kzalloc(sizeof(struct abx500_device_entry), GFP_KERNEL);
+	dev_entry = devm_kzalloc(dev,
+				 sizeof(struct abx500_device_entry),
+				 GFP_KERNEL);
 	if (!dev_entry) {
 		dev_err(dev, "register_ops kzalloc failed");
 		return -ENOMEM;
@@ -54,12 +56,8 @@ void abx500_remove_ops(struct device *de
 	struct abx500_device_entry *dev_entry, *tmp;
 
 	list_for_each_entry_safe(dev_entry, tmp, &abx500_list, list)
-	{
-		if (dev_entry->dev == dev) {
+		if (dev_entry->dev == dev)
 			list_del(&dev_entry->list);
-			kfree(dev_entry);
-		}
-	}
 }
 EXPORT_SYMBOL(abx500_remove_ops);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/adp5520.c linux-libre-3.11-rc7-gnu/drivers/mfd/adp5520.c
--- linux-libre-3.10-gnu/drivers/mfd/adp5520.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/adp5520.c	2013-08-25 20:43:22.000000000 -0400
@@ -223,7 +223,7 @@ static int adp5520_probe(struct i2c_clie
 		return -ENODEV;
 	}
 
-	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
 
@@ -244,7 +244,7 @@ static int adp5520_probe(struct i2c_clie
 		if (ret) {
 			dev_err(&client->dev, "failed to request irq %d\n",
 					chip->irq);
-			goto out_free_chip;
+			return ret;
 		}
 	}
 
@@ -302,9 +302,6 @@ out_free_irq:
 	if (chip->irq)
 		free_irq(chip->irq, chip);
 
-out_free_chip:
-	kfree(chip);
-
 	return ret;
 }
 
@@ -317,7 +314,6 @@ static int adp5520_remove(struct i2c_cli
 
 	adp5520_remove_subdevs(chip);
 	adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0);
-	kfree(chip);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/arizona-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/arizona-core.c
--- linux-libre-3.10-gnu/drivers/mfd/arizona-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/arizona-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,9 +16,13 @@
 #include <linux/interrupt.h>
 #include <linux/mfd/core.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
 #include <linux/slab.h>
 
 #include <linux/mfd/arizona/core.h>
@@ -344,6 +348,17 @@ static int arizona_runtime_resume(struct
 
 	switch (arizona->type) {
 	case WM5102:
+		if (arizona->external_dcvdd) {
+			ret = regmap_update_bits(arizona->regmap,
+						 ARIZONA_ISOLATION_CONTROL,
+						 ARIZONA_ISOLATE_DCVDD1, 0);
+			if (ret != 0) {
+				dev_err(arizona->dev,
+					"Failed to connect DCVDD: %d\n", ret);
+				goto err;
+			}
+		}
+
 		ret = wm5102_patch(arizona);
 		if (ret != 0) {
 			dev_err(arizona->dev, "Failed to apply patch: %d\n",
@@ -365,6 +380,28 @@ static int arizona_runtime_resume(struct
 			goto err;
 		}
 
+		if (arizona->external_dcvdd) {
+			ret = regmap_update_bits(arizona->regmap,
+						 ARIZONA_ISOLATION_CONTROL,
+						 ARIZONA_ISOLATE_DCVDD1, 0);
+			if (ret != 0) {
+				dev_err(arizona->dev,
+					"Failed to connect DCVDD: %d\n", ret);
+				goto err;
+			}
+		}
+		break;
+	}
+
+	switch (arizona->type) {
+	case WM5102:
+		ret = wm5102_patch(arizona);
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to apply patch: %d\n",
+				ret);
+			goto err;
+		}
+	default:
 		break;
 	}
 
@@ -385,9 +422,22 @@ err:
 static int arizona_runtime_suspend(struct device *dev)
 {
 	struct arizona *arizona = dev_get_drvdata(dev);
+	int ret;
 
 	dev_dbg(arizona->dev, "Entering AoD mode\n");
 
+	if (arizona->external_dcvdd) {
+		ret = regmap_update_bits(arizona->regmap,
+					 ARIZONA_ISOLATION_CONTROL,
+					 ARIZONA_ISOLATE_DCVDD1,
+					 ARIZONA_ISOLATE_DCVDD1);
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	regulator_disable(arizona->dcvdd);
 	regcache_cache_only(arizona->regmap, true);
 	regcache_mark_dirty(arizona->regmap);
@@ -397,6 +447,26 @@ static int arizona_runtime_suspend(struc
 #endif
 
 #ifdef CONFIG_PM_SLEEP
+static int arizona_suspend(struct device *dev)
+{
+	struct arizona *arizona = dev_get_drvdata(dev);
+
+	dev_dbg(arizona->dev, "Suspend, disabling IRQ\n");
+	disable_irq(arizona->irq);
+
+	return 0;
+}
+
+static int arizona_suspend_late(struct device *dev)
+{
+	struct arizona *arizona = dev_get_drvdata(dev);
+
+	dev_dbg(arizona->dev, "Late suspend, reenabling IRQ\n");
+	enable_irq(arizona->irq);
+
+	return 0;
+}
+
 static int arizona_resume_noirq(struct device *dev)
 {
 	struct arizona *arizona = dev_get_drvdata(dev);
@@ -422,13 +492,79 @@ const struct dev_pm_ops arizona_pm_ops =
 	SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
 			   arizona_runtime_resume,
 			   NULL)
-	SET_SYSTEM_SLEEP_PM_OPS(NULL, arizona_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
 #ifdef CONFIG_PM_SLEEP
+	.suspend_late = arizona_suspend_late,
 	.resume_noirq = arizona_resume_noirq,
 #endif
 };
 EXPORT_SYMBOL_GPL(arizona_pm_ops);
 
+#ifdef CONFIG_OF
+int arizona_of_get_type(struct device *dev)
+{
+	const struct of_device_id *id = of_match_device(arizona_of_match, dev);
+
+	if (id)
+		return (int)id->data;
+	else
+		return 0;
+}
+EXPORT_SYMBOL_GPL(arizona_of_get_type);
+
+static int arizona_of_get_core_pdata(struct arizona *arizona)
+{
+	int ret, i;
+
+	arizona->pdata.reset = of_get_named_gpio(arizona->dev->of_node,
+						 "wlf,reset", 0);
+	if (arizona->pdata.reset < 0)
+		arizona->pdata.reset = 0;
+
+	arizona->pdata.ldoena = of_get_named_gpio(arizona->dev->of_node,
+						  "wlf,ldoena", 0);
+	if (arizona->pdata.ldoena < 0)
+		arizona->pdata.ldoena = 0;
+
+	ret = of_property_read_u32_array(arizona->dev->of_node,
+					 "wlf,gpio-defaults",
+					 arizona->pdata.gpio_defaults,
+					 ARRAY_SIZE(arizona->pdata.gpio_defaults));
+	if (ret >= 0) {
+		/*
+		 * All values are literal except out of range values
+		 * which are chip default, translate into platform
+		 * data which uses 0 as chip default and out of range
+		 * as zero.
+		 */
+		for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
+			if (arizona->pdata.gpio_defaults[i] > 0xffff)
+				arizona->pdata.gpio_defaults[i] = 0;
+			if (arizona->pdata.gpio_defaults[i] == 0)
+				arizona->pdata.gpio_defaults[i] = 0x10000;
+		}
+	} else {
+		dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
+			ret);
+	}
+
+	return 0;
+}
+
+const struct of_device_id arizona_of_match[] = {
+	{ .compatible = "wlf,wm5102", .data = (void *)WM5102 },
+	{ .compatible = "wlf,wm5110", .data = (void *)WM5110 },
+	{ .compatible = "wlf,wm8997", .data = (void *)WM8997 },
+	{},
+};
+EXPORT_SYMBOL_GPL(arizona_of_match);
+#else
+static inline int arizona_of_get_core_pdata(struct arizona *arizona)
+{
+	return 0;
+}
+#endif
+
 static struct mfd_cell early_devs[] = {
 	{ .name = "arizona-ldo1" },
 };
@@ -451,6 +587,15 @@ static struct mfd_cell wm5110_devs[] = {
 	{ .name = "wm5110-codec" },
 };
 
+static struct mfd_cell wm8997_devs[] = {
+	{ .name = "arizona-micsupp" },
+	{ .name = "arizona-extcon" },
+	{ .name = "arizona-gpio" },
+	{ .name = "arizona-haptics" },
+	{ .name = "arizona-pwm" },
+	{ .name = "wm8997-codec" },
+};
+
 int arizona_dev_init(struct arizona *arizona)
 {
 	struct device *dev = arizona->dev;
@@ -462,6 +607,8 @@ int arizona_dev_init(struct arizona *ari
 	dev_set_drvdata(arizona->dev, arizona);
 	mutex_init(&arizona->clk_lock);
 
+	arizona_of_get_core_pdata(arizona);
+
 	if (dev_get_platdata(arizona->dev))
 		memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
 		       sizeof(arizona->pdata));
@@ -471,6 +618,7 @@ int arizona_dev_init(struct arizona *ari
 	switch (arizona->type) {
 	case WM5102:
 	case WM5110:
+	case WM8997:
 		for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
 			arizona->core_supplies[i].supply
 				= wm5102_core_supplies[i];
@@ -536,51 +684,23 @@ int arizona_dev_init(struct arizona *ari
 
 	regcache_cache_only(arizona->regmap, false);
 
+	/* Verify that this is a chip we know about */
 	ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
 	if (ret != 0) {
 		dev_err(dev, "Failed to read ID register: %d\n", ret);
 		goto err_reset;
 	}
 
-	ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
-			  &arizona->rev);
-	if (ret != 0) {
-		dev_err(dev, "Failed to read revision register: %d\n", ret);
-		goto err_reset;
-	}
-	arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
-
 	switch (reg) {
-#ifdef CONFIG_MFD_WM5102
 	case 0x5102:
-		type_name = "WM5102";
-		if (arizona->type != WM5102) {
-			dev_err(arizona->dev, "WM5102 registered as %d\n",
-				arizona->type);
-			arizona->type = WM5102;
-		}
-		apply_patch = wm5102_patch;
-		arizona->rev &= 0x7;
-		break;
-#endif
-#ifdef CONFIG_MFD_WM5110
 	case 0x5110:
-		type_name = "WM5110";
-		if (arizona->type != WM5110) {
-			dev_err(arizona->dev, "WM5110 registered as %d\n",
-				arizona->type);
-			arizona->type = WM5110;
-		}
-		apply_patch = wm5110_patch;
+	case 0x8997:
 		break;
-#endif
 	default:
-		dev_err(arizona->dev, "Unknown device ID %x\n", reg);
+		dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
 		goto err_reset;
 	}
 
-	dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
-
 	/* If we have a /RESET GPIO we'll already be reset */
 	if (!arizona->pdata.reset) {
 		regcache_mark_dirty(arizona->regmap);
@@ -600,6 +720,7 @@ int arizona_dev_init(struct arizona *ari
 		}
 	}
 
+	/* Ensure device startup is complete */
 	switch (arizona->type) {
 	case WM5102:
 		ret = regmap_read(arizona->regmap, 0x19, &val);
@@ -620,6 +741,63 @@ int arizona_dev_init(struct arizona *ari
 		break;
 	}
 
+	/* Read the device ID information & do device specific stuff */
+	ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
+	if (ret != 0) {
+		dev_err(dev, "Failed to read ID register: %d\n", ret);
+		goto err_reset;
+	}
+
+	ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
+			  &arizona->rev);
+	if (ret != 0) {
+		dev_err(dev, "Failed to read revision register: %d\n", ret);
+		goto err_reset;
+	}
+	arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
+
+	switch (reg) {
+#ifdef CONFIG_MFD_WM5102
+	case 0x5102:
+		type_name = "WM5102";
+		if (arizona->type != WM5102) {
+			dev_err(arizona->dev, "WM5102 registered as %d\n",
+				arizona->type);
+			arizona->type = WM5102;
+		}
+		apply_patch = wm5102_patch;
+		arizona->rev &= 0x7;
+		break;
+#endif
+#ifdef CONFIG_MFD_WM5110
+	case 0x5110:
+		type_name = "WM5110";
+		if (arizona->type != WM5110) {
+			dev_err(arizona->dev, "WM5110 registered as %d\n",
+				arizona->type);
+			arizona->type = WM5110;
+		}
+		apply_patch = wm5110_patch;
+		break;
+#endif
+#ifdef CONFIG_MFD_WM8997
+	case 0x8997:
+		type_name = "WM8997";
+		if (arizona->type != WM8997) {
+			dev_err(arizona->dev, "WM8997 registered as %d\n",
+				arizona->type);
+			arizona->type = WM8997;
+		}
+		apply_patch = wm8997_patch;
+		break;
+#endif
+	default:
+		dev_err(arizona->dev, "Unknown device ID %x\n", reg);
+		goto err_reset;
+	}
+
+	dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
+
 	if (apply_patch) {
 		ret = apply_patch(arizona);
 		if (ret != 0) {
@@ -651,6 +829,14 @@ int arizona_dev_init(struct arizona *ari
 			     arizona->pdata.gpio_defaults[i]);
 	}
 
+	/*
+	 * LDO1 can only be used to supply DCVDD so if it has no
+	 * consumers then DCVDD is supplied externally.
+	 */
+	if (arizona->pdata.ldo1 &&
+	    arizona->pdata.ldo1->num_consumer_supplies == 0)
+		arizona->external_dcvdd = true;
+
 	pm_runtime_set_autosuspend_delay(arizona->dev, 100);
 	pm_runtime_use_autosuspend(arizona->dev);
 	pm_runtime_enable(arizona->dev);
@@ -697,7 +883,7 @@ int arizona_dev_init(struct arizona *ari
 		if (arizona->pdata.micbias[i].discharge)
 			val |= ARIZONA_MICB1_DISCH;
 
-		if (arizona->pdata.micbias[i].fast_start)
+		if (arizona->pdata.micbias[i].soft_start)
 			val |= ARIZONA_MICB1_RATE;
 
 		if (arizona->pdata.micbias[i].bypass)
@@ -771,6 +957,10 @@ int arizona_dev_init(struct arizona *ari
 		ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
 				      ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
 		break;
+	case WM8997:
+		ret = mfd_add_devices(arizona->dev, -1, wm8997_devs,
+				      ARRAY_SIZE(wm8997_devs), NULL, 0, NULL);
+		break;
 	}
 
 	if (ret != 0) {
@@ -809,6 +999,11 @@ int arizona_dev_exit(struct arizona *ari
 	arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
 	pm_runtime_disable(arizona->dev);
 	arizona_irq_exit(arizona);
+	if (arizona->pdata.reset)
+		gpio_set_value_cansleep(arizona->pdata.reset, 0);
+	regulator_disable(arizona->dcvdd);
+	regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies),
+			       arizona->core_supplies);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(arizona_dev_exit);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/arizona.h linux-libre-3.11-rc7-gnu/drivers/mfd/arizona.h
--- linux-libre-3.10-gnu/drivers/mfd/arizona.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/arizona.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
 #ifndef _WM5102_H
 #define _WM5102_H
 
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/pm.h>
 
@@ -24,17 +25,33 @@ extern const struct regmap_config wm5102
 extern const struct regmap_config wm5110_i2c_regmap;
 extern const struct regmap_config wm5110_spi_regmap;
 
+extern const struct regmap_config wm8997_i2c_regmap;
+
 extern const struct dev_pm_ops arizona_pm_ops;
 
+extern const struct of_device_id arizona_of_match[];
+
 extern const struct regmap_irq_chip wm5102_aod;
 extern const struct regmap_irq_chip wm5102_irq;
 
 extern const struct regmap_irq_chip wm5110_aod;
 extern const struct regmap_irq_chip wm5110_irq;
 
+extern const struct regmap_irq_chip wm8997_aod;
+extern const struct regmap_irq_chip wm8997_irq;
+
 int arizona_dev_init(struct arizona *arizona);
 int arizona_dev_exit(struct arizona *arizona);
 int arizona_irq_init(struct arizona *arizona);
 int arizona_irq_exit(struct arizona *arizona);
 
+#ifdef CONFIG_OF
+int arizona_of_get_type(struct device *dev);
+#else
+static inline int arizona_of_get_type(struct device *dev)
+{
+	return 0;
+}
+#endif
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/arizona-i2c.c linux-libre-3.11-rc7-gnu/drivers/mfd/arizona-i2c.c
--- linux-libre-3.10-gnu/drivers/mfd/arizona-i2c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/arizona-i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,9 +27,14 @@ static int arizona_i2c_probe(struct i2c_
 {
 	struct arizona *arizona;
 	const struct regmap_config *regmap_config;
-	int ret;
+	int ret, type;
 
-	switch (id->driver_data) {
+	if (i2c->dev.of_node)
+		type = arizona_of_get_type(&i2c->dev);
+	else
+		type = id->driver_data;
+
+	switch (type) {
 #ifdef CONFIG_MFD_WM5102
 	case WM5102:
 		regmap_config = &wm5102_i2c_regmap;
@@ -40,6 +45,11 @@ static int arizona_i2c_probe(struct i2c_
 		regmap_config = &wm5110_i2c_regmap;
 		break;
 #endif
+#ifdef CONFIG_MFD_WM8997
+	case WM8997:
+		regmap_config = &wm8997_i2c_regmap;
+		break;
+#endif
 	default:
 		dev_err(&i2c->dev, "Unknown device type %ld\n",
 			id->driver_data);
@@ -75,6 +85,7 @@ static int arizona_i2c_remove(struct i2c
 static const struct i2c_device_id arizona_i2c_id[] = {
 	{ "wm5102", WM5102 },
 	{ "wm5110", WM5110 },
+	{ "wm8997", WM8997 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, arizona_i2c_id);
@@ -84,6 +95,7 @@ static struct i2c_driver arizona_i2c_dri
 		.name	= "arizona",
 		.owner	= THIS_MODULE,
 		.pm	= &arizona_pm_ops,
+		.of_match_table	= of_match_ptr(arizona_of_match),
 	},
 	.probe		= arizona_i2c_probe,
 	.remove		= arizona_i2c_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/arizona-irq.c linux-libre-3.11-rc7-gnu/drivers/mfd/arizona-irq.c
--- linux-libre-3.10-gnu/drivers/mfd/arizona-irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/arizona-irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -208,6 +208,14 @@ int arizona_irq_init(struct arizona *ari
 		ctrlif_error = false;
 		break;
 #endif
+#ifdef CONFIG_MFD_WM8997
+	case WM8997:
+		aod = &wm8997_aod;
+		irq = &wm8997_irq;
+
+		ctrlif_error = false;
+		break;
+#endif
 	default:
 		BUG_ON("Unknown Arizona class device" == NULL);
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/arizona-spi.c linux-libre-3.11-rc7-gnu/drivers/mfd/arizona-spi.c
--- linux-libre-3.10-gnu/drivers/mfd/arizona-spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/arizona-spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,9 +27,14 @@ static int arizona_spi_probe(struct spi_
 	const struct spi_device_id *id = spi_get_device_id(spi);
 	struct arizona *arizona;
 	const struct regmap_config *regmap_config;
-	int ret;
+	int ret, type;
 
-	switch (id->driver_data) {
+	if (spi->dev.of_node)
+		type = arizona_of_get_type(&spi->dev);
+	else
+		type = id->driver_data;
+
+	switch (type) {
 #ifdef CONFIG_MFD_WM5102
 	case WM5102:
 		regmap_config = &wm5102_spi_regmap;
@@ -84,6 +89,7 @@ static struct spi_driver arizona_spi_dri
 		.name	= "arizona",
 		.owner	= THIS_MODULE,
 		.pm	= &arizona_pm_ops,
+		.of_match_table	= of_match_ptr(arizona_of_match),
 	},
 	.probe		= arizona_spi_probe,
 	.remove		= arizona_spi_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/asic3.c linux-libre-3.11-rc7-gnu/drivers/mfd/asic3.c
--- linux-libre-3.10-gnu/drivers/mfd/asic3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/asic3.c	2013-08-25 20:43:22.000000000 -0400
@@ -958,7 +958,8 @@ static int __init asic3_probe(struct pla
 	unsigned long clksel;
 	int ret = 0;
 
-	asic = kzalloc(sizeof(struct asic3), GFP_KERNEL);
+	asic = devm_kzalloc(&pdev->dev,
+			    sizeof(struct asic3), GFP_KERNEL);
 	if (asic == NULL) {
 		printk(KERN_ERR "kzalloc failed\n");
 		return -ENOMEM;
@@ -970,16 +971,14 @@ static int __init asic3_probe(struct pla
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mem) {
-		ret = -ENOMEM;
 		dev_err(asic->dev, "no MEM resource\n");
-		goto out_free;
+		return -ENOMEM;
 	}
 
 	asic->mapping = ioremap(mem->start, resource_size(mem));
 	if (!asic->mapping) {
-		ret = -ENOMEM;
 		dev_err(asic->dev, "Couldn't ioremap\n");
-		goto out_free;
+		return -ENOMEM;
 	}
 
 	asic->irq_base = pdata->irq_base;
@@ -1033,9 +1032,6 @@ static int __init asic3_probe(struct pla
  out_unmap:
 	iounmap(asic->mapping);
 
- out_free:
-	kfree(asic);
-
 	return ret;
 }
 
@@ -1058,8 +1054,6 @@ static int asic3_remove(struct platform_
 
 	iounmap(asic->mapping);
 
-	kfree(asic);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/cros_ec.c linux-libre-3.11-rc7-gnu/drivers/mfd/cros_ec.c
--- linux-libre-3.10-gnu/drivers/mfd/cros_ec.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/cros_ec.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,23 +104,19 @@ int cros_ec_register(struct cros_ec_devi
 	ec_dev->command_sendrecv = cros_ec_command_sendrecv;
 
 	if (ec_dev->din_size) {
-		ec_dev->din = kmalloc(ec_dev->din_size, GFP_KERNEL);
-		if (!ec_dev->din) {
-			err = -ENOMEM;
-			goto fail_din;
-		}
+		ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
+		if (!ec_dev->din)
+			return -ENOMEM;
 	}
 	if (ec_dev->dout_size) {
-		ec_dev->dout = kmalloc(ec_dev->dout_size, GFP_KERNEL);
-		if (!ec_dev->dout) {
-			err = -ENOMEM;
-			goto fail_dout;
-		}
+		ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
+		if (!ec_dev->dout)
+			return -ENOMEM;
 	}
 
 	if (!ec_dev->irq) {
 		dev_dbg(dev, "no valid IRQ: %d\n", ec_dev->irq);
-		goto fail_irq;
+		return err;
 	}
 
 	err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread,
@@ -128,7 +124,7 @@ int cros_ec_register(struct cros_ec_devi
 				   "chromeos-ec", ec_dev);
 	if (err) {
 		dev_err(dev, "request irq %d: error %d\n", ec_dev->irq, err);
-		goto fail_irq;
+		return err;
 	}
 
 	err = mfd_add_devices(dev, 0, cros_devs,
@@ -145,11 +141,7 @@ int cros_ec_register(struct cros_ec_devi
 
 fail_mfd:
 	free_irq(ec_dev->irq, ec_dev);
-fail_irq:
-	kfree(ec_dev->dout);
-fail_dout:
-	kfree(ec_dev->din);
-fail_din:
+
 	return err;
 }
 EXPORT_SYMBOL(cros_ec_register);
@@ -158,8 +150,6 @@ int cros_ec_remove(struct cros_ec_device
 {
 	mfd_remove_devices(ec_dev->dev);
 	free_irq(ec_dev->irq, ec_dev);
-	kfree(ec_dev->dout);
-	kfree(ec_dev->din);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/davinci_voicecodec.c linux-libre-3.11-rc7-gnu/drivers/mfd/davinci_voicecodec.c
--- linux-libre-3.10-gnu/drivers/mfd/davinci_voicecodec.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/davinci_voicecodec.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,56 +46,39 @@ void davinci_vc_write(struct davinci_vc
 static int __init davinci_vc_probe(struct platform_device *pdev)
 {
 	struct davinci_vc *davinci_vc;
-	struct resource *res, *mem;
+	struct resource *res;
 	struct mfd_cell *cell = NULL;
 	int ret;
 
-	davinci_vc = kzalloc(sizeof(struct davinci_vc), GFP_KERNEL);
+	davinci_vc = devm_kzalloc(&pdev->dev,
+				  sizeof(struct davinci_vc), GFP_KERNEL);
 	if (!davinci_vc) {
 		dev_dbg(&pdev->dev,
 			    "could not allocate memory for private data\n");
 		return -ENOMEM;
 	}
 
-	davinci_vc->clk = clk_get(&pdev->dev, NULL);
+	davinci_vc->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(davinci_vc->clk)) {
 		dev_dbg(&pdev->dev,
 			    "could not get the clock for voice codec\n");
-		ret = -ENODEV;
-		goto fail1;
+		return -ENODEV;
 	}
 	clk_enable(davinci_vc->clk);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "no mem resource\n");
-		ret = -ENODEV;
-		goto fail2;
-	}
 
-	davinci_vc->pbase = res->start;
-	davinci_vc->base_size = resource_size(res);
-
-	mem = request_mem_region(davinci_vc->pbase, davinci_vc->base_size,
-				 pdev->name);
-	if (!mem) {
-		dev_err(&pdev->dev, "VCIF region already claimed\n");
-		ret = -EBUSY;
-		goto fail2;
-	}
-
-	davinci_vc->base = ioremap(davinci_vc->pbase, davinci_vc->base_size);
-	if (!davinci_vc->base) {
-		dev_err(&pdev->dev, "can't ioremap mem resource.\n");
-		ret = -ENOMEM;
-		goto fail3;
+	davinci_vc->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(davinci_vc->base)) {
+		ret = PTR_ERR(davinci_vc->base);
+		goto fail;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "no DMA resource\n");
 		ret = -ENXIO;
-		goto fail4;
+		goto fail;
 	}
 
 	davinci_vc->davinci_vcif.dma_tx_channel = res->start;
@@ -106,7 +89,7 @@ static int __init davinci_vc_probe(struc
 	if (!res) {
 		dev_err(&pdev->dev, "no DMA resource\n");
 		ret = -ENXIO;
-		goto fail4;
+		goto fail;
 	}
 
 	davinci_vc->davinci_vcif.dma_rx_channel = res->start;
@@ -132,21 +115,13 @@ static int __init davinci_vc_probe(struc
 			      DAVINCI_VC_CELLS, NULL, 0, NULL);
 	if (ret != 0) {
 		dev_err(&pdev->dev, "fail to register client devices\n");
-		goto fail4;
+		goto fail;
 	}
 
 	return 0;
 
-fail4:
-	iounmap(davinci_vc->base);
-fail3:
-	release_mem_region(davinci_vc->pbase, davinci_vc->base_size);
-fail2:
+fail:
 	clk_disable(davinci_vc->clk);
-	clk_put(davinci_vc->clk);
-	davinci_vc->clk = NULL;
-fail1:
-	kfree(davinci_vc);
 
 	return ret;
 }
@@ -157,14 +132,7 @@ static int davinci_vc_remove(struct plat
 
 	mfd_remove_devices(&pdev->dev);
 
-	iounmap(davinci_vc->base);
-	release_mem_region(davinci_vc->pbase, davinci_vc->base_size);
-
 	clk_disable(davinci_vc->clk);
-	clk_put(davinci_vc->clk);
-	davinci_vc->clk = NULL;
-
-	kfree(davinci_vc);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/db8500-prcmu.c linux-libre-3.11-rc7-gnu/drivers/mfd/db8500-prcmu.c
--- linux-libre-3.10-gnu/drivers/mfd/db8500-prcmu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/db8500-prcmu.c	2013-08-25 20:43:22.000000000 -0400
@@ -480,6 +480,7 @@ struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLO
 	CLK_MGT_ENTRY(PER6CLK, PLL_DIV, true),
 	CLK_MGT_ENTRY(PER7CLK, PLL_DIV, true),
 	CLK_MGT_ENTRY(LCDCLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(BML8580CLK, PLL_DIV, true),
 	CLK_MGT_ENTRY(BMLCLK, PLL_DIV, true),
 	CLK_MGT_ENTRY(HSITXCLK, PLL_DIV, true),
 	CLK_MGT_ENTRY(HSIRXCLK, PLL_DIV, true),
@@ -1724,9 +1725,9 @@ static long round_clock_rate(u8 clock, u
 
 /* CPU FREQ table, may be changed due to if MAX_OPP is supported. */
 static struct cpufreq_frequency_table db8500_cpufreq_table[] = {
-	{ .frequency = 200000, .index = ARM_EXTCLK,},
-	{ .frequency = 400000, .index = ARM_50_OPP,},
-	{ .frequency = 800000, .index = ARM_100_OPP,},
+	{ .frequency = 200000, .driver_data = ARM_EXTCLK,},
+	{ .frequency = 400000, .driver_data = ARM_50_OPP,},
+	{ .frequency = 800000, .driver_data = ARM_100_OPP,},
 	{ .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */
 	{ .frequency = CPUFREQ_TABLE_END,},
 };
@@ -1901,7 +1902,7 @@ static int set_armss_rate(unsigned long
 		return -EINVAL;
 
 	/* Set the new arm opp. */
-	return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].index);
+	return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].driver_data);
 }
 
 static int set_plldsi_rate(unsigned long rate)
@@ -3105,7 +3106,7 @@ static void db8500_prcmu_update_cpufreq(
 {
 	if (prcmu_has_arm_maxopp()) {
 		db8500_cpufreq_table[3].frequency = 1000000;
-		db8500_cpufreq_table[3].index = ARM_MAX_OPP;
+		db8500_cpufreq_table[3].driver_data = ARM_MAX_OPP;
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/dbx500-prcmu-regs.h linux-libre-3.11-rc7-gnu/drivers/mfd/dbx500-prcmu-regs.h
--- linux-libre-3.10-gnu/drivers/mfd/dbx500-prcmu-regs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/dbx500-prcmu-regs.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,8 +16,8 @@
 #define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))
 
 #define PRCM_ACLK_MGT		(0x004)
-#define PRCM_SVACLK_MGT		(0x008)
-#define PRCM_SIACLK_MGT		(0x00C)
+#define PRCM_SVAMMCSPCLK_MGT	(0x008)
+#define PRCM_SIAMMDSPCLK_MGT	(0x00C)
 #define PRCM_SGACLK_MGT		(0x014)
 #define PRCM_UARTCLK_MGT	(0x018)
 #define PRCM_MSP02CLK_MGT	(0x01C)
@@ -32,6 +32,7 @@
 #define PRCM_PER7CLK_MGT	(0x040)
 #define PRCM_LCDCLK_MGT		(0x044)
 #define PRCM_BMLCLK_MGT		(0x04C)
+#define PRCM_BML8580CLK_MGT	(0x108)
 #define PRCM_HSITXCLK_MGT	(0x050)
 #define PRCM_HSIRXCLK_MGT	(0x054)
 #define PRCM_HDMICLK_MGT	(0x058)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/htc-egpio.c linux-libre-3.11-rc7-gnu/drivers/mfd/htc-egpio.c
--- linux-libre-3.10-gnu/drivers/mfd/htc-egpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/htc-egpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -270,7 +270,7 @@ static int __init egpio_probe(struct pla
 	int               ret;
 
 	/* Initialize ei data structure. */
-	ei = kzalloc(sizeof(*ei), GFP_KERNEL);
+	ei = devm_kzalloc(&pdev->dev, sizeof(*ei), GFP_KERNEL);
 	if (!ei)
 		return -ENOMEM;
 
@@ -286,7 +286,8 @@ static int __init egpio_probe(struct pla
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		goto fail;
-	ei->base_addr = ioremap_nocache(res->start, resource_size(res));
+	ei->base_addr = devm_ioremap_nocache(&pdev->dev, res->start,
+					     resource_size(res));
 	if (!ei->base_addr)
 		goto fail;
 	pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr);
@@ -306,7 +307,9 @@ static int __init egpio_probe(struct pla
 	platform_set_drvdata(pdev, ei);
 
 	ei->nchips = pdata->num_chips;
-	ei->chip = kzalloc(sizeof(struct egpio_chip) * ei->nchips, GFP_KERNEL);
+	ei->chip = devm_kzalloc(&pdev->dev,
+				sizeof(struct egpio_chip) * ei->nchips,
+				GFP_KERNEL);
 	if (!ei->chip) {
 		ret = -ENOMEM;
 		goto fail;
@@ -361,7 +364,6 @@ static int __init egpio_probe(struct pla
 
 fail:
 	printk(KERN_ERR "EGPIO failed to setup\n");
-	kfree(ei);
 	return ret;
 }
 
@@ -379,9 +381,6 @@ static int __exit egpio_remove(struct pl
 		irq_set_chained_handler(ei->chained_irq, NULL);
 		device_init_wakeup(&pdev->dev, 0);
 	}
-	iounmap(ei->base_addr);
-	kfree(ei->chip);
-	kfree(ei);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/htc-i2cpld.c linux-libre-3.11-rc7-gnu/drivers/mfd/htc-i2cpld.c
--- linux-libre-3.10-gnu/drivers/mfd/htc-i2cpld.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/htc-i2cpld.c	2013-08-25 20:43:22.000000000 -0400
@@ -514,8 +514,8 @@ static int htcpld_setup_chips(struct pla
 
 	/* Setup each chip's output GPIOs */
 	htcpld->nchips = pdata->num_chip;
-	htcpld->chip = kzalloc(sizeof(struct htcpld_chip) * htcpld->nchips,
-			       GFP_KERNEL);
+	htcpld->chip = devm_kzalloc(dev, sizeof(struct htcpld_chip) * htcpld->nchips,
+				    GFP_KERNEL);
 	if (!htcpld->chip) {
 		dev_warn(dev, "Unable to allocate memory for chips\n");
 		return -ENOMEM;
@@ -580,12 +580,11 @@ static int htcpld_core_probe(struct plat
 		return -ENXIO;
 	}
 
-	htcpld = kzalloc(sizeof(struct htcpld_data), GFP_KERNEL);
+	htcpld = devm_kzalloc(dev, sizeof(struct htcpld_data), GFP_KERNEL);
 	if (!htcpld)
 		return -ENOMEM;
 
 	/* Find chained irq */
-	ret = -EINVAL;
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (res) {
 		int flags;
@@ -598,7 +597,7 @@ static int htcpld_core_probe(struct plat
 					   flags, pdev->name, htcpld);
 		if (ret) {
 			dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret);
-			goto fail;
+			return ret;
 		} else
 			device_init_wakeup(dev, 0);
 	}
@@ -609,7 +608,7 @@ static int htcpld_core_probe(struct plat
 	/* Setup the htcpld chips */
 	ret = htcpld_setup_chips(pdev);
 	if (ret)
-		goto fail;
+		return ret;
 
 	/* Request the GPIO(s) for the int reset and set them up */
 	if (pdata->int_reset_gpio_hi) {
@@ -644,10 +643,6 @@ static int htcpld_core_probe(struct plat
 
 	dev_info(dev, "Initialized successfully\n");
 	return 0;
-
-fail:
-	kfree(htcpld);
-	return ret;
 }
 
 /* The I2C Driver -- used internally */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/htc-pasic3.c linux-libre-3.11-rc7-gnu/drivers/mfd/htc-pasic3.c
--- linux-libre-3.10-gnu/drivers/mfd/htc-pasic3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/htc-pasic3.c	2013-08-25 20:43:22.000000000 -0400
@@ -147,7 +147,7 @@ static int __init pasic3_probe(struct pl
 	if (!request_mem_region(r->start, resource_size(r), "pasic3"))
 		return -EBUSY;
 
-	asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL);
+	asic = devm_kzalloc(dev, sizeof(struct pasic3_data), GFP_KERNEL);
 	if (!asic)
 		return -ENOMEM;
 
@@ -156,7 +156,6 @@ static int __init pasic3_probe(struct pl
 	asic->mapping = ioremap(r->start, resource_size(r));
 	if (!asic->mapping) {
 		dev_err(dev, "couldn't ioremap PASIC3\n");
-		kfree(asic);
 		return -ENOMEM;
 	}
 
@@ -195,7 +194,6 @@ static int pasic3_remove(struct platform
 	iounmap(asic->mapping);
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(r->start, resource_size(r));
-	kfree(asic);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/intel_msic.c linux-libre-3.11-rc7-gnu/drivers/mfd/intel_msic.c
--- linux-libre-3.10-gnu/drivers/mfd/intel_msic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/intel_msic.c	2013-08-25 20:43:22.000000000 -0400
@@ -438,7 +438,6 @@ static int intel_msic_remove(struct plat
 	struct intel_msic *msic = platform_get_drvdata(pdev);
 
 	intel_msic_remove_devices(msic);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/janz-cmodio.c linux-libre-3.11-rc7-gnu/drivers/mfd/janz-cmodio.c
--- linux-libre-3.10-gnu/drivers/mfd/janz-cmodio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/janz-cmodio.c	2013-08-25 20:43:22.000000000 -0400
@@ -183,11 +183,10 @@ static int cmodio_pci_probe(struct pci_d
 	struct cmodio_device *priv;
 	int ret;
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv) {
 		dev_err(&dev->dev, "unable to allocate private data\n");
-		ret = -ENOMEM;
-		goto out_return;
+		return -ENOMEM;
 	}
 
 	pci_set_drvdata(dev, priv);
@@ -197,7 +196,7 @@ static int cmodio_pci_probe(struct pci_d
 	ret = pci_enable_device(dev);
 	if (ret) {
 		dev_err(&dev->dev, "unable to enable device\n");
-		goto out_free_priv;
+		return ret;
 	}
 
 	pci_set_master(dev);
@@ -248,9 +247,7 @@ out_pci_release_regions:
 	pci_release_regions(dev);
 out_pci_disable_device:
 	pci_disable_device(dev);
-out_free_priv:
-	kfree(priv);
-out_return:
+
 	return ret;
 }
 
@@ -263,7 +260,6 @@ static void cmodio_pci_remove(struct pci
 	iounmap(priv->ctrl);
 	pci_release_regions(dev);
 	pci_disable_device(dev);
-	kfree(priv);
 }
 
 #define PCI_VENDOR_ID_JANZ		0x13c3
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/jz4740-adc.c linux-libre-3.11-rc7-gnu/drivers/mfd/jz4740-adc.c
--- linux-libre-3.10-gnu/drivers/mfd/jz4740-adc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/jz4740-adc.c	2013-08-25 20:43:22.000000000 -0400
@@ -86,13 +86,13 @@ static void jz4740_adc_irq_demux(unsigne
 static inline void jz4740_adc_clk_enable(struct jz4740_adc *adc)
 {
 	if (atomic_inc_return(&adc->clk_ref) == 1)
-		clk_enable(adc->clk);
+		clk_prepare_enable(adc->clk);
 }
 
 static inline void jz4740_adc_clk_disable(struct jz4740_adc *adc)
 {
 	if (atomic_dec_return(&adc->clk_ref) == 0)
-		clk_disable(adc->clk);
+		clk_disable_unprepare(adc->clk);
 }
 
 static inline void jz4740_adc_set_enabled(struct jz4740_adc *adc, int engine,
@@ -294,7 +294,6 @@ static int jz4740_adc_probe(struct platf
 err_clk_put:
 	clk_put(adc->clk);
 err_iounmap:
-	platform_set_drvdata(pdev, NULL);
 	iounmap(adc->base);
 err_release_mem_region:
 	release_mem_region(adc->mem->start, resource_size(adc->mem));
@@ -317,8 +316,6 @@ static int jz4740_adc_remove(struct plat
 
 	clk_put(adc->clk);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/Kconfig linux-libre-3.11-rc7-gnu/drivers/mfd/Kconfig
--- linux-libre-3.10-gnu/drivers/mfd/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -53,7 +53,7 @@ config MFD_CROS_EC
 	help
 	  If you say Y here you get support for the ChromeOS Embedded
 	  Controller (EC) providing keyboard, battery and power services.
-	  You also ned to enable the driver for the bus you are using. The
+	  You also need to enable the driver for the bus you are using. The
 	  protocol for talking to the EC is defined by the bus driver.
 
 config MFD_CROS_EC_I2C
@@ -242,6 +242,27 @@ config MFD_JZ4740_ADC
 	  Say yes here if you want support for the ADC unit in the JZ4740 SoC.
 	  This driver is necessary for jz4740-battery and jz4740-hwmon driver.
 
+config MFD_KEMPLD
+	tristate "Kontron module PLD device"
+	select MFD_CORE
+	help
+	  This is the core driver for the PLD (Programmable Logic Device) found
+	  on some Kontron ETX and COMexpress (ETXexpress) modules. The PLD
+	  device may provide functions like watchdog, GPIO, UART and I2C bus.
+
+	  The following modules are supported:
+		* COMe-bIP#
+		* COMe-bPC2 (ETXexpress-PC)
+		* COMe-bSC# (ETXexpress-SC T#)
+		* COMe-cCT6
+		* COMe-cDC2 (microETXexpress-DC)
+		* COMe-cPC2 (microETXexpress-PC)
+		* COMe-mCT10
+		* ETX-OH
+
+	  This driver can also be built as a module. If so, the module
+	  will be called kempld-core.
+
 config MFD_88PM800
 	tristate "Marvell 88PM800"
 	depends on I2C=y && GENERIC_HARDIRQS
@@ -342,6 +363,7 @@ config MFD_MAX8998
 	bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support"
 	depends on I2C=y && GENERIC_HARDIRQS
 	select MFD_CORE
+	select IRQ_DOMAIN
 	help
 	  Say yes here to support for Maxim Semiconductor MAX8998 and
 	  National Semiconductor LP3974. This is a Power Management IC.
@@ -419,7 +441,8 @@ config MFD_PM8XXX
 
 config MFD_PM8921_CORE
 	tristate "Qualcomm PM8921 PMIC chip"
-	depends on SSBI && BROKEN
+	depends on (ARCH_MSM || HEXAGON)
+	depends on BROKEN
 	select MFD_CORE
 	select MFD_PM8XXX
 	help
@@ -1046,6 +1069,12 @@ config MFD_WM5110
 	help
 	  Support for Wolfson Microelectronics WM5110 low power audio SoC
 
+config MFD_WM8997
+	bool "Support Wolfson Microelectronics WM8997"
+	depends on MFD_ARIZONA
+	help
+	  Support for Wolfson Microelectronics WM8997 low power audio SoC
+
 config MFD_WM8400
 	bool "Wolfson Microelectronics WM8400"
 	select MFD_CORE
@@ -1144,7 +1173,8 @@ config MCP_UCB1200_TS
 endmenu
 
 config VEXPRESS_CONFIG
-	bool
+	bool "ARM Versatile Express platform infrastructure"
+	depends on ARM || ARM64
 	help
 	  Platform configuration infrastructure for the ARM Ltd.
 	  Versatile Express.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/kempld-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/kempld-core.c
--- linux-libre-3.10-gnu/drivers/mfd/kempld-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/kempld-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,641 @@
+/*
+ * Kontron PLD MFD core driver
+ *
+ * Copyright (c) 2010-2013 Kontron Europe GmbH
+ * Author: Michael Brunner <michael.brunner@kontron.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/kempld.h>
+#include <linux/module.h>
+#include <linux/dmi.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#define MAX_ID_LEN 4
+static char force_device_id[MAX_ID_LEN + 1] = "";
+module_param_string(force_device_id, force_device_id, sizeof(force_device_id), 0);
+MODULE_PARM_DESC(force_device_id, "Override detected product");
+
+/*
+ * Get hardware mutex to block firmware from accessing the pld.
+ * It is possible for the firmware may hold the mutex for an extended length of
+ * time. This function will block until access has been granted.
+ */
+static void kempld_get_hardware_mutex(struct kempld_device_data *pld)
+{
+	/* The mutex bit will read 1 until access has been granted */
+	while (ioread8(pld->io_index) & KEMPLD_MUTEX_KEY)
+		msleep(1);
+}
+
+static void kempld_release_hardware_mutex(struct kempld_device_data *pld)
+{
+	/* The harware mutex is released when 1 is written to the mutex bit. */
+	iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
+}
+
+static int kempld_get_info_generic(struct kempld_device_data *pld)
+{
+	u16 version;
+	u8 spec;
+
+	kempld_get_mutex(pld);
+
+	version = kempld_read16(pld, KEMPLD_VERSION);
+	spec = kempld_read8(pld, KEMPLD_SPEC);
+	pld->info.buildnr = kempld_read16(pld, KEMPLD_BUILDNR);
+
+	pld->info.minor = KEMPLD_VERSION_GET_MINOR(version);
+	pld->info.major = KEMPLD_VERSION_GET_MAJOR(version);
+	pld->info.number = KEMPLD_VERSION_GET_NUMBER(version);
+	pld->info.type = KEMPLD_VERSION_GET_TYPE(version);
+
+	if (spec == 0xff) {
+		pld->info.spec_minor = 0;
+		pld->info.spec_major = 1;
+	} else {
+		pld->info.spec_minor = KEMPLD_SPEC_GET_MINOR(spec);
+		pld->info.spec_major = KEMPLD_SPEC_GET_MAJOR(spec);
+	}
+
+	if (pld->info.spec_major > 0)
+		pld->feature_mask = kempld_read16(pld, KEMPLD_FEATURE);
+	else
+		pld->feature_mask = 0;
+
+	kempld_release_mutex(pld);
+
+	return 0;
+}
+
+enum kempld_cells {
+	KEMPLD_I2C = 0,
+	KEMPLD_WDT,
+	KEMPLD_GPIO,
+	KEMPLD_UART,
+};
+
+static struct mfd_cell kempld_devs[] = {
+	[KEMPLD_I2C] = {
+		.name = "kempld-i2c",
+	},
+	[KEMPLD_WDT] = {
+		.name = "kempld-wdt",
+	},
+	[KEMPLD_GPIO] = {
+		.name = "kempld-gpio",
+	},
+	[KEMPLD_UART] = {
+		.name = "kempld-uart",
+	},
+};
+
+#define KEMPLD_MAX_DEVS	ARRAY_SIZE(kempld_devs)
+
+static int kempld_register_cells_generic(struct kempld_device_data *pld)
+{
+	struct mfd_cell devs[KEMPLD_MAX_DEVS];
+	int i = 0;
+
+	if (pld->feature_mask & KEMPLD_FEATURE_BIT_I2C)
+		devs[i++] = kempld_devs[KEMPLD_I2C];
+
+	if (pld->feature_mask & KEMPLD_FEATURE_BIT_WATCHDOG)
+		devs[i++] = kempld_devs[KEMPLD_WDT];
+
+	if (pld->feature_mask & KEMPLD_FEATURE_BIT_GPIO)
+		devs[i++] = kempld_devs[KEMPLD_GPIO];
+
+	if (pld->feature_mask & KEMPLD_FEATURE_MASK_UART)
+		devs[i++] = kempld_devs[KEMPLD_UART];
+
+	return mfd_add_devices(pld->dev, -1, devs, i, NULL, 0, NULL);
+}
+
+static struct resource kempld_ioresource = {
+	.start	= KEMPLD_IOINDEX,
+	.end	= KEMPLD_IODATA,
+	.flags	= IORESOURCE_IO,
+};
+
+static const struct kempld_platform_data kempld_platform_data_generic = {
+	.pld_clock		= KEMPLD_CLK,
+	.ioresource		= &kempld_ioresource,
+	.get_hardware_mutex	= kempld_get_hardware_mutex,
+	.release_hardware_mutex	= kempld_release_hardware_mutex,
+	.get_info		= kempld_get_info_generic,
+	.register_cells		= kempld_register_cells_generic,
+};
+
+static struct platform_device *kempld_pdev;
+
+static int kempld_create_platform_device(const struct dmi_system_id *id)
+{
+	struct kempld_platform_data *pdata = id->driver_data;
+	int ret;
+
+	kempld_pdev = platform_device_alloc("kempld", -1);
+	if (!kempld_pdev)
+		return -ENOMEM;
+
+	ret = platform_device_add_data(kempld_pdev, pdata, sizeof(*pdata));
+	if (ret)
+		goto err;
+
+	ret = platform_device_add_resources(kempld_pdev, pdata->ioresource, 1);
+	if (ret)
+		goto err;
+
+	ret = platform_device_add(kempld_pdev);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	platform_device_put(kempld_pdev);
+	return ret;
+}
+
+/**
+ * kempld_read8 - read 8 bit register
+ * @pld: kempld_device_data structure describing the PLD
+ * @index: register index on the chip
+ *
+ * kempld_get_mutex must be called prior to calling this function.
+ */
+u8 kempld_read8(struct kempld_device_data *pld, u8 index)
+{
+	iowrite8(index, pld->io_index);
+	return ioread8(pld->io_data);
+}
+EXPORT_SYMBOL_GPL(kempld_read8);
+
+/**
+ * kempld_write8 - write 8 bit register
+ * @pld: kempld_device_data structure describing the PLD
+ * @index: register index on the chip
+ * @data: new register value
+ *
+ * kempld_get_mutex must be called prior to calling this function.
+ */
+void kempld_write8(struct kempld_device_data *pld, u8 index, u8 data)
+{
+	iowrite8(index, pld->io_index);
+	iowrite8(data, pld->io_data);
+}
+EXPORT_SYMBOL_GPL(kempld_write8);
+
+/**
+ * kempld_read16 - read 16 bit register
+ * @pld: kempld_device_data structure describing the PLD
+ * @index: register index on the chip
+ *
+ * kempld_get_mutex must be called prior to calling this function.
+ */
+u16 kempld_read16(struct kempld_device_data *pld, u8 index)
+{
+	return kempld_read8(pld, index) | kempld_read8(pld, index + 1) << 8;
+}
+EXPORT_SYMBOL_GPL(kempld_read16);
+
+/**
+ * kempld_write16 - write 16 bit register
+ * @pld: kempld_device_data structure describing the PLD
+ * @index: register index on the chip
+ * @data: new register value
+ *
+ * kempld_get_mutex must be called prior to calling this function.
+ */
+void kempld_write16(struct kempld_device_data *pld, u8 index, u16 data)
+{
+	kempld_write8(pld, index, (u8)data);
+	kempld_write8(pld, index + 1, (u8)(data >> 8));
+}
+EXPORT_SYMBOL_GPL(kempld_write16);
+
+/**
+ * kempld_read32 - read 32 bit register
+ * @pld: kempld_device_data structure describing the PLD
+ * @index: register index on the chip
+ *
+ * kempld_get_mutex must be called prior to calling this function.
+ */
+u32 kempld_read32(struct kempld_device_data *pld, u8 index)
+{
+	return kempld_read16(pld, index) | kempld_read16(pld, index + 2) << 16;
+}
+EXPORT_SYMBOL_GPL(kempld_read32);
+
+/**
+ * kempld_write32 - write 32 bit register
+ * @pld: kempld_device_data structure describing the PLD
+ * @index: register index on the chip
+ * @data: new register value
+ *
+ * kempld_get_mutex must be called prior to calling this function.
+ */
+void kempld_write32(struct kempld_device_data *pld, u8 index, u32 data)
+{
+	kempld_write16(pld, index, (u16)data);
+	kempld_write16(pld, index + 2, (u16)(data >> 16));
+}
+EXPORT_SYMBOL_GPL(kempld_write32);
+
+/**
+ * kempld_get_mutex - acquire PLD mutex
+ * @pld: kempld_device_data structure describing the PLD
+ */
+void kempld_get_mutex(struct kempld_device_data *pld)
+{
+	struct kempld_platform_data *pdata = pld->dev->platform_data;
+
+	mutex_lock(&pld->lock);
+	pdata->get_hardware_mutex(pld);
+}
+EXPORT_SYMBOL_GPL(kempld_get_mutex);
+
+/**
+ * kempld_release_mutex - release PLD mutex
+ * @pld: kempld_device_data structure describing the PLD
+ */
+void kempld_release_mutex(struct kempld_device_data *pld)
+{
+	struct kempld_platform_data *pdata = pld->dev->platform_data;
+
+	pdata->release_hardware_mutex(pld);
+	mutex_unlock(&pld->lock);
+}
+EXPORT_SYMBOL_GPL(kempld_release_mutex);
+
+/**
+ * kempld_get_info - update device specific information
+ * @pld: kempld_device_data structure describing the PLD
+ *
+ * This function calls the configured board specific kempld_get_info_XXXX
+ * function which is responsible for gathering information about the specific
+ * hardware. The information is then stored within the pld structure.
+ */
+static int kempld_get_info(struct kempld_device_data *pld)
+{
+	struct kempld_platform_data *pdata = pld->dev->platform_data;
+
+	return pdata->get_info(pld);
+}
+
+/*
+ * kempld_register_cells - register cell drivers
+ *
+ * This function registers cell drivers for the detected hardware by calling
+ * the configured kempld_register_cells_XXXX function which is responsible
+ * to detect and register the needed cell drivers.
+ */
+static int kempld_register_cells(struct kempld_device_data *pld)
+{
+	struct kempld_platform_data *pdata = pld->dev->platform_data;
+
+	return pdata->register_cells(pld);
+}
+
+static int kempld_detect_device(struct kempld_device_data *pld)
+{
+	char *version_type;
+	u8 index_reg;
+	int ret;
+
+	mutex_lock(&pld->lock);
+
+	/* Check for empty IO space */
+	index_reg = ioread8(pld->io_index);
+	if (index_reg == 0xff && ioread8(pld->io_data) == 0xff) {
+		mutex_unlock(&pld->lock);
+		return -ENODEV;
+	}
+
+	/* Release hardware mutex if aquired */
+	if (!(index_reg & KEMPLD_MUTEX_KEY))
+		iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
+
+	mutex_unlock(&pld->lock);
+
+	ret = kempld_get_info(pld);
+	if (ret)
+		return ret;
+
+	switch (pld->info.type) {
+	case 0:
+		version_type = "release";
+		break;
+	case 1:
+		version_type = "debug";
+		break;
+	case 2:
+		version_type = "custom";
+		break;
+	default:
+		version_type = "unspecified";
+	}
+
+	dev_info(pld->dev, "Found Kontron PLD %d\n", pld->info.number);
+	dev_info(pld->dev, "%s version %d.%d build %d, specification %d.%d\n",
+		 version_type, pld->info.major, pld->info.minor,
+		 pld->info.buildnr, pld->info.spec_major,
+		 pld->info.spec_minor);
+
+	return kempld_register_cells(pld);
+}
+
+static int kempld_probe(struct platform_device *pdev)
+{
+	struct kempld_platform_data *pdata = pdev->dev.platform_data;
+	struct device *dev = &pdev->dev;
+	struct kempld_device_data *pld;
+	struct resource *ioport;
+	int ret;
+
+	pld = devm_kzalloc(dev, sizeof(*pld), GFP_KERNEL);
+	if (!pld)
+		return -ENOMEM;
+
+	ioport = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (!ioport)
+		return -EINVAL;
+
+	pld->io_base = devm_ioport_map(dev, ioport->start,
+					ioport->end - ioport->start);
+	if (!pld->io_base)
+		return -ENOMEM;
+
+	pld->io_index = pld->io_base;
+	pld->io_data = pld->io_base + 1;
+	pld->pld_clock = pdata->pld_clock;
+	pld->dev = dev;
+
+	mutex_init(&pld->lock);
+	platform_set_drvdata(pdev, pld);
+
+	ret = kempld_detect_device(pld);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int kempld_remove(struct platform_device *pdev)
+{
+	struct kempld_device_data *pld = platform_get_drvdata(pdev);
+	struct kempld_platform_data *pdata = pld->dev->platform_data;
+
+	mfd_remove_devices(&pdev->dev);
+	pdata->release_hardware_mutex(pld);
+
+	return 0;
+}
+
+static struct platform_driver kempld_driver = {
+	.driver		= {
+		.name	= "kempld",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= kempld_probe,
+	.remove		= kempld_remove,
+};
+
+static struct dmi_system_id __initdata kempld_dmi_table[] = {
+	{
+		.ident = "CCR2",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-bIP2"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CCR6",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-bIP6"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CHR2",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "ETXexpress-SC T2"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CHR2",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "ETXe-SC T2"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CHR2",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-bSC2"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CHR6",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "ETXexpress-SC T6"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CHR6",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "ETXe-SC T6"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CHR6",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-bSC6"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CNTG",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "ETXexpress-PC"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CNTG",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-bPC2"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "CNTX",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "PXT"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "FRI2",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BIOS_VERSION, "FRI2"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "FRI2",
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_NAME, "Fish River Island II"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "MBR1",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "ETX-OH"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "NTC1",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "nanoETXexpress-TT"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "NTC1",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "nETXe-TT"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "NTC1",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-mTT"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "NUP1",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-mCT"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "UNP1",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "microETXexpress-DC"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "UNP1",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-cDC2"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "UNTG",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "microETXexpress-PC"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "UNTG",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-cPC2"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	}, {
+		.ident = "UUP6",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+			DMI_MATCH(DMI_BOARD_NAME, "COMe-cCT6"),
+		},
+		.driver_data = (void *)&kempld_platform_data_generic,
+		.callback = kempld_create_platform_device,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(dmi, kempld_dmi_table);
+
+static int __init kempld_init(void)
+{
+	const struct dmi_system_id *id;
+	int ret;
+
+	if (force_device_id[0]) {
+		for (id = kempld_dmi_table; id->matches[0].slot != DMI_NONE; id++)
+			if (strstr(id->ident, force_device_id))
+				if (id->callback && id->callback(id))
+					break;
+		if (id->matches[0].slot == DMI_NONE)
+			return -ENODEV;
+	} else {
+		if (!dmi_check_system(kempld_dmi_table))
+			return -ENODEV;
+	}
+
+	ret = platform_driver_register(&kempld_driver);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void __exit kempld_exit(void)
+{
+	if (kempld_pdev)
+		platform_device_unregister(kempld_pdev);
+
+	platform_driver_unregister(&kempld_driver);
+}
+
+module_init(kempld_init);
+module_exit(kempld_exit);
+
+MODULE_DESCRIPTION("KEM PLD Core Driver");
+MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:kempld-core");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/lpc_ich.c linux-libre-3.11-rc7-gnu/drivers/mfd/lpc_ich.c
--- linux-libre-3.10-gnu/drivers/mfd/lpc_ich.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/lpc_ich.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,6 +51,8 @@
  *	document number TBD : Lynx Point
  *	document number TBD : Lynx Point-LP
  *	document number TBD : Wellsburg
+ *	document number TBD : Avoton SoC
+ *	document number TBD : Coleto Creek
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -207,6 +209,8 @@ enum lpc_chipsets {
 	LPC_LPT,	/* Lynx Point */
 	LPC_LPT_LP,	/* Lynx Point-LP */
 	LPC_WBG,	/* Wellsburg */
+	LPC_AVN,	/* Avoton SoC */
+	LPC_COLETO,	/* Coleto Creek */
 };
 
 struct lpc_ich_info lpc_chipset_info[] = {
@@ -491,6 +495,14 @@ struct lpc_ich_info lpc_chipset_info[] =
 		.name = "Wellsburg",
 		.iTCO_version = 2,
 	},
+	[LPC_AVN] = {
+		.name = "Avoton SoC",
+		.iTCO_version = 1,
+	},
+	[LPC_COLETO] = {
+		.name = "Coleto Creek",
+		.iTCO_version = 2,
+	},
 };
 
 /*
@@ -704,6 +716,11 @@ static DEFINE_PCI_DEVICE_TABLE(lpc_ich_i
 	{ PCI_VDEVICE(INTEL, 0x8d5d), LPC_WBG},
 	{ PCI_VDEVICE(INTEL, 0x8d5e), LPC_WBG},
 	{ PCI_VDEVICE(INTEL, 0x8d5f), LPC_WBG},
+	{ PCI_VDEVICE(INTEL, 0x1f38), LPC_AVN},
+	{ PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN},
+	{ PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
+	{ PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
+	{ PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO},
 	{ 0, },			/* End of list */
 };
 MODULE_DEVICE_TABLE(pci, lpc_ich_ids);
@@ -973,18 +990,7 @@ static struct pci_driver lpc_ich_driver
 	.remove		= lpc_ich_remove,
 };
 
-static int __init lpc_ich_init(void)
-{
-	return pci_register_driver(&lpc_ich_driver);
-}
-
-static void __exit lpc_ich_exit(void)
-{
-	pci_unregister_driver(&lpc_ich_driver);
-}
-
-module_init(lpc_ich_init);
-module_exit(lpc_ich_exit);
+module_pci_driver(lpc_ich_driver);
 
 MODULE_AUTHOR("Aaron Sierra <asierra@xes-inc.com>");
 MODULE_DESCRIPTION("LPC interface for Intel ICH");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/Makefile linux-libre-3.11-rc7-gnu/drivers/mfd/Makefile
--- linux-libre-3.10-gnu/drivers/mfd/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -43,6 +43,9 @@ endif
 ifneq ($(CONFIG_MFD_WM5110),n)
 obj-$(CONFIG_MFD_ARIZONA)	+= wm5110-tables.o
 endif
+ifneq ($(CONFIG_MFD_WM8997),n)
+obj-$(CONFIG_MFD_ARIZONA)	+= wm8997-tables.o
+endif
 obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
 wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
 wm831x-objs			+= wm831x-auxadc.o
@@ -126,6 +129,7 @@ obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500
 obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
 obj-$(CONFIG_MFD_TIMBERDALE)    += timberdale.o
 obj-$(CONFIG_PMIC_ADP5520)	+= adp5520.o
+obj-$(CONFIG_MFD_KEMPLD)	+= kempld-core.o
 obj-$(CONFIG_LPC_SCH)		+= lpc_sch.o
 obj-$(CONFIG_LPC_ICH)		+= lpc_ich.o
 obj-$(CONFIG_MFD_RDC321X)	+= rdc321x-southbridge.o
@@ -140,7 +144,7 @@ obj-$(CONFIG_MFD_SI476X_CORE)	+= si476x-
 
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
-obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o
+obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o ssbi.o
 obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)	+= tps65090.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/max77686.c linux-libre-3.11-rc7-gnu/drivers/mfd/max77686.c
--- linux-libre-3.10-gnu/drivers/mfd/max77686.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/max77686.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,6 +37,7 @@
 static struct mfd_cell max77686_devs[] = {
 	{ .name = "max77686-pmic", },
 	{ .name = "max77686-rtc", },
+	{ .name = "max77686-clk", },
 };
 
 static struct regmap_config max77686_regmap_config = {
@@ -84,12 +85,12 @@ static int max77686_i2c_probe(struct i2c
 		pdata = max77686_i2c_parse_dt_pdata(&i2c->dev);
 
 	if (!pdata) {
-		ret = -EIO;
 		dev_err(&i2c->dev, "No platform data found.\n");
-		goto err;
+		return -EIO;
 	}
 
-	max77686 = kzalloc(sizeof(struct max77686_dev), GFP_KERNEL);
+	max77686 = devm_kzalloc(&i2c->dev,
+				sizeof(struct max77686_dev), GFP_KERNEL);
 	if (max77686 == NULL)
 		return -ENOMEM;
 
@@ -107,7 +108,6 @@ static int max77686_i2c_probe(struct i2c
 		ret = PTR_ERR(max77686->regmap);
 		dev_err(max77686->dev, "Failed to allocate register map: %d\n",
 				ret);
-		kfree(max77686);
 		return ret;
 	}
 
@@ -115,8 +115,7 @@ static int max77686_i2c_probe(struct i2c
 			 MAX77686_REG_DEVICE_ID, &data) < 0) {
 		dev_err(max77686->dev,
 			"device not found on this channel (this is not an error)\n");
-		ret = -ENODEV;
-		goto err;
+		return -ENODEV;
 	} else
 		dev_info(max77686->dev, "device found\n");
 
@@ -127,18 +126,12 @@ static int max77686_i2c_probe(struct i2c
 
 	ret = mfd_add_devices(max77686->dev, -1, max77686_devs,
 			      ARRAY_SIZE(max77686_devs), NULL, 0, NULL);
-
-	if (ret < 0)
-		goto err_mfd;
+	if (ret < 0) {
+		mfd_remove_devices(max77686->dev);
+		i2c_unregister_device(max77686->rtc);
+	}
 
 	return ret;
-
-err_mfd:
-	mfd_remove_devices(max77686->dev);
-	i2c_unregister_device(max77686->rtc);
-err:
-	kfree(max77686);
-	return ret;
 }
 
 static int max77686_i2c_remove(struct i2c_client *i2c)
@@ -147,7 +140,6 @@ static int max77686_i2c_remove(struct i2
 
 	mfd_remove_devices(max77686->dev);
 	i2c_unregister_device(max77686->rtc);
-	kfree(max77686);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/max8925-i2c.c linux-libre-3.11-rc7-gnu/drivers/mfd/max8925-i2c.c
--- linux-libre-3.10-gnu/drivers/mfd/max8925-i2c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/max8925-i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -170,7 +170,8 @@ static int max8925_probe(struct i2c_clie
 		return -EINVAL;
 	}
 
-	chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL);
+	chip = devm_kzalloc(&client->dev,
+			    sizeof(struct max8925_chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	chip->i2c = client;
@@ -199,7 +200,6 @@ static int max8925_remove(struct i2c_cli
 	max8925_device_exit(chip);
 	i2c_unregister_device(chip->adc);
 	i2c_unregister_device(chip->rtc);
-	kfree(chip);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/max8998.c linux-libre-3.11-rc7-gnu/drivers/mfd/max8998.c
--- linux-libre-3.10-gnu/drivers/mfd/max8998.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/max8998.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,12 +20,15 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/err.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/pm_runtime.h>
 #include <linux/mutex.h>
 #include <linux/mfd/core.h>
@@ -128,6 +131,56 @@ int max8998_update_reg(struct i2c_client
 }
 EXPORT_SYMBOL(max8998_update_reg);
 
+#ifdef CONFIG_OF
+static struct of_device_id max8998_dt_match[] = {
+	{ .compatible = "maxim,max8998", .data = (void *)TYPE_MAX8998 },
+	{ .compatible = "national,lp3974", .data = (void *)TYPE_LP3974 },
+	{ .compatible = "ti,lp3974", .data = (void *)TYPE_LP3974 },
+	{},
+};
+MODULE_DEVICE_TABLE(of, max8998_dt_match);
+#endif
+
+/*
+ * Only the common platform data elements for max8998 are parsed here from the
+ * device tree. Other sub-modules of max8998 such as pmic, rtc and others have
+ * to parse their own platform data elements from device tree.
+ *
+ * The max8998 platform data structure is instantiated here and the drivers for
+ * the sub-modules need not instantiate another instance while parsing their
+ * platform data.
+ */
+static struct max8998_platform_data *max8998_i2c_parse_dt_pdata(
+							struct device *dev)
+{
+	struct max8998_platform_data *pd;
+
+	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return ERR_PTR(-ENOMEM);
+
+	pd->ono = irq_of_parse_and_map(dev->of_node, 1);
+
+	/*
+	 * ToDo: the 'wakeup' member in the platform data is more of a linux
+	 * specfic information. Hence, there is no binding for that yet and
+	 * not parsed here.
+	 */
+	return pd;
+}
+
+static inline int max8998_i2c_get_driver_data(struct i2c_client *i2c,
+						const struct i2c_device_id *id)
+{
+	if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(max8998_dt_match, i2c->dev.of_node);
+		return (int)match->data;
+	}
+
+	return (int)id->driver_data;
+}
+
 static int max8998_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
@@ -139,11 +192,20 @@ static int max8998_i2c_probe(struct i2c_
 	if (max8998 == NULL)
 		return -ENOMEM;
 
+	if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) {
+		pdata = max8998_i2c_parse_dt_pdata(&i2c->dev);
+		if (IS_ERR(pdata)) {
+			ret = PTR_ERR(pdata);
+			goto err;
+		}
+	}
+
 	i2c_set_clientdata(i2c, max8998);
 	max8998->dev = &i2c->dev;
 	max8998->i2c = i2c;
 	max8998->irq = i2c->irq;
-	max8998->type = id->driver_data;
+	max8998->type = max8998_i2c_get_driver_data(i2c, id);
+	max8998->pdata = pdata;
 	if (pdata) {
 		max8998->ono = pdata->ono;
 		max8998->irq_base = pdata->irq_base;
@@ -158,7 +220,7 @@ static int max8998_i2c_probe(struct i2c_
 
 	pm_runtime_set_active(max8998->dev);
 
-	switch (id->driver_data) {
+	switch (max8998->type) {
 	case TYPE_LP3974:
 		ret = mfd_add_devices(max8998->dev, -1,
 				      lp3974_devs, ARRAY_SIZE(lp3974_devs),
@@ -314,6 +376,7 @@ static struct i2c_driver max8998_i2c_dri
 		   .name = "max8998",
 		   .owner = THIS_MODULE,
 		   .pm = &max8998_pm,
+		   .of_match_table = of_match_ptr(max8998_dt_match),
 	},
 	.probe = max8998_i2c_probe,
 	.remove = max8998_i2c_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/max8998-irq.c linux-libre-3.11-rc7-gnu/drivers/mfd/max8998-irq.c
--- linux-libre-3.10-gnu/drivers/mfd/max8998-irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/max8998-irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/device.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/mfd/max8998-private.h>
 
 struct max8998_irq_data {
@@ -99,7 +100,8 @@ static struct max8998_irq_data max8998_i
 static inline struct max8998_irq_data *
 irq_to_max8998_irq(struct max8998_dev *max8998, int irq)
 {
-	return &max8998_irqs[irq - max8998->irq_base];
+	struct irq_data *data = irq_get_irq_data(irq);
+	return &max8998_irqs[data->hwirq];
 }
 
 static void max8998_irq_lock(struct irq_data *data)
@@ -176,8 +178,14 @@ static irqreturn_t max8998_irq_thread(in
 
 	/* Report */
 	for (i = 0; i < MAX8998_IRQ_NR; i++) {
-		if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask)
-			handle_nested_irq(max8998->irq_base + i);
+		if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask) {
+			irq = irq_find_mapping(max8998->irq_domain, i);
+			if (WARN_ON(!irq)) {
+				disable_irq_nosync(max8998->irq);
+				return IRQ_NONE;
+			}
+			handle_nested_irq(irq);
+		}
 	}
 
 	return IRQ_HANDLED;
@@ -185,27 +193,40 @@ static irqreturn_t max8998_irq_thread(in
 
 int max8998_irq_resume(struct max8998_dev *max8998)
 {
-	if (max8998->irq && max8998->irq_base)
-		max8998_irq_thread(max8998->irq_base, max8998);
+	if (max8998->irq && max8998->irq_domain)
+		max8998_irq_thread(max8998->irq, max8998);
 	return 0;
 }
 
+static int max8998_irq_domain_map(struct irq_domain *d, unsigned int irq,
+					irq_hw_number_t hw)
+{
+	struct max8997_dev *max8998 = d->host_data;
+
+	irq_set_chip_data(irq, max8998);
+	irq_set_chip_and_handler(irq, &max8998_irq_chip, handle_edge_irq);
+	irq_set_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+	set_irq_flags(irq, IRQF_VALID);
+#else
+	irq_set_noprobe(irq);
+#endif
+	return 0;
+}
+
+static struct irq_domain_ops max8998_irq_domain_ops = {
+	.map = max8998_irq_domain_map,
+};
+
 int max8998_irq_init(struct max8998_dev *max8998)
 {
 	int i;
-	int cur_irq;
 	int ret;
+	struct irq_domain *domain;
 
 	if (!max8998->irq) {
 		dev_warn(max8998->dev,
 			 "No interrupt specified, no interrupts\n");
-		max8998->irq_base = 0;
-		return 0;
-	}
-
-	if (!max8998->irq_base) {
-		dev_err(max8998->dev,
-			"No interrupt base specified, no interrupts\n");
 		return 0;
 	}
 
@@ -221,19 +242,13 @@ int max8998_irq_init(struct max8998_dev
 	max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM1, 0xff);
 	max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM2, 0xff);
 
-	/* register with genirq */
-	for (i = 0; i < MAX8998_IRQ_NR; i++) {
-		cur_irq = i + max8998->irq_base;
-		irq_set_chip_data(cur_irq, max8998);
-		irq_set_chip_and_handler(cur_irq, &max8998_irq_chip,
-					 handle_edge_irq);
-		irq_set_nested_thread(cur_irq, 1);
-#ifdef CONFIG_ARM
-		set_irq_flags(cur_irq, IRQF_VALID);
-#else
-		irq_set_noprobe(cur_irq);
-#endif
+	domain = irq_domain_add_simple(NULL, MAX8998_IRQ_NR,
+			max8998->irq_base, &max8998_irq_domain_ops, max8998);
+	if (!domain) {
+		dev_err(max8998->dev, "could not create irq domain\n");
+		return -ENODEV;
 	}
+	max8998->irq_domain = domain;
 
 	ret = request_threaded_irq(max8998->irq, NULL, max8998_irq_thread,
 				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/mcp-sa11x0.c linux-libre-3.11-rc7-gnu/drivers/mfd/mcp-sa11x0.c
--- linux-libre-3.10-gnu/drivers/mfd/mcp-sa11x0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/mcp-sa11x0.c	2013-08-25 20:43:22.000000000 -0400
@@ -225,8 +225,6 @@ static int mcp_sa11x0_probe(struct platf
 	if (ret == 0)
 		return 0;
 
-	platform_set_drvdata(dev, NULL);
-
  err_ioremap:
 	iounmap(m->base1);
 	iounmap(m->base0);
@@ -252,7 +250,6 @@ static int mcp_sa11x0_remove(struct plat
 	mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
 
-	platform_set_drvdata(dev, NULL);
 	mcp_host_del(mcp);
 	iounmap(m->base1);
 	iounmap(m->base0);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/palmas.c linux-libre-3.11-rc7-gnu/drivers/mfd/palmas.c
--- linux-libre-3.10-gnu/drivers/mfd/palmas.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/palmas.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,78 +23,7 @@
 #include <linux/err.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/palmas.h>
-#include <linux/of_platform.h>
-
-enum palmas_ids {
-	PALMAS_PMIC_ID,
-	PALMAS_GPIO_ID,
-	PALMAS_LEDS_ID,
-	PALMAS_WDT_ID,
-	PALMAS_RTC_ID,
-	PALMAS_PWRBUTTON_ID,
-	PALMAS_GPADC_ID,
-	PALMAS_RESOURCE_ID,
-	PALMAS_CLK_ID,
-	PALMAS_PWM_ID,
-	PALMAS_USB_ID,
-};
-
-static struct resource palmas_rtc_resources[] = {
-	{
-		.start  = PALMAS_RTC_ALARM_IRQ,
-		.end    = PALMAS_RTC_ALARM_IRQ,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static const struct mfd_cell palmas_children[] = {
-	{
-		.name = "palmas-pmic",
-		.id = PALMAS_PMIC_ID,
-	},
-	{
-		.name = "palmas-gpio",
-		.id = PALMAS_GPIO_ID,
-	},
-	{
-		.name = "palmas-leds",
-		.id = PALMAS_LEDS_ID,
-	},
-	{
-		.name = "palmas-wdt",
-		.id = PALMAS_WDT_ID,
-	},
-	{
-		.name = "palmas-rtc",
-		.id = PALMAS_RTC_ID,
-		.resources = &palmas_rtc_resources[0],
-		.num_resources = ARRAY_SIZE(palmas_rtc_resources),
-	},
-	{
-		.name = "palmas-pwrbutton",
-		.id = PALMAS_PWRBUTTON_ID,
-	},
-	{
-		.name = "palmas-gpadc",
-		.id = PALMAS_GPADC_ID,
-	},
-	{
-		.name = "palmas-resource",
-		.id = PALMAS_RESOURCE_ID,
-	},
-	{
-		.name = "palmas-clk",
-		.id = PALMAS_CLK_ID,
-	},
-	{
-		.name = "palmas-pwm",
-		.id = PALMAS_PWM_ID,
-	},
-	{
-		.name = "palmas-usb",
-		.id = PALMAS_USB_ID,
-	}
-};
+#include <linux/of_device.h>
 
 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
 	{
@@ -302,6 +231,21 @@ static void palmas_dt_to_pdata(struct i2
 		palmas_set_pdata_irq_flag(i2c, pdata);
 }
 
+static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST;
+static unsigned int tps659038_features;
+
+static const struct of_device_id of_palmas_match_tbl[] = {
+	{
+		.compatible = "ti,palmas",
+		.data = &palmas_features,
+	},
+	{
+		.compatible = "ti,tps659038",
+		.data = &tps659038_features,
+	},
+	{ },
+};
+
 static int palmas_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
@@ -309,9 +253,9 @@ static int palmas_i2c_probe(struct i2c_c
 	struct palmas_platform_data *pdata;
 	struct device_node *node = i2c->dev.of_node;
 	int ret = 0, i;
-	unsigned int reg, addr;
+	unsigned int reg, addr, *features;
 	int slave;
-	struct mfd_cell *children;
+	const struct of_device_id *match;
 
 	pdata = dev_get_platdata(&i2c->dev);
 
@@ -333,9 +277,16 @@ static int palmas_i2c_probe(struct i2c_c
 
 	i2c_set_clientdata(i2c, palmas);
 	palmas->dev = &i2c->dev;
-	palmas->id = id->driver_data;
 	palmas->irq = i2c->irq;
 
+	match = of_match_device(of_match_ptr(of_palmas_match_tbl), &i2c->dev);
+
+	if (!match)
+		return -ENODATA;
+
+	features = (unsigned int *)match->data;
+	palmas->features = *features;
+
 	for (i = 0; i < PALMAS_NUM_CLIENTS; i++) {
 		if (i == 0)
 			palmas->i2c_clients[i] = i2c;
@@ -362,6 +313,11 @@ static int palmas_i2c_probe(struct i2c_c
 		}
 	}
 
+	if (!palmas->irq) {
+		dev_warn(palmas->dev, "IRQ missing: skipping irq request\n");
+		goto no_irq;
+	}
+
 	/* Change interrupt line output polarity */
 	if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH)
 		reg = PALMAS_POLARITY_CTRL_INT_POLARITY;
@@ -388,6 +344,7 @@ static int palmas_i2c_probe(struct i2c_c
 	if (ret < 0)
 		goto err;
 
+no_irq:
 	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
 	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
 			PALMAS_PRIMARY_SECONDARY_PAD1);
@@ -472,42 +429,8 @@ static int palmas_i2c_probe(struct i2c_c
 			return ret;
 	}
 
-	children = kmemdup(palmas_children, sizeof(palmas_children),
-			   GFP_KERNEL);
-	if (!children) {
-		ret = -ENOMEM;
-		goto err_irq;
-	}
-
-	children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata;
-	children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata);
-
-	children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata;
-	children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata);
-
-	children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata;
-	children[PALMAS_RESOURCE_ID].pdata_size =
-			sizeof(*pdata->resource_pdata);
-
-	children[PALMAS_USB_ID].platform_data = pdata->usb_pdata;
-	children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata);
-
-	children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata;
-	children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata);
-
-	ret = mfd_add_devices(palmas->dev, -1,
-			      children, ARRAY_SIZE(palmas_children),
-			      NULL, 0,
-			      regmap_irq_get_domain(palmas->irq_data));
-	kfree(children);
-
-	if (ret < 0)
-		goto err_devices;
-
 	return ret;
 
-err_devices:
-	mfd_remove_devices(palmas->dev);
 err_irq:
 	regmap_del_irq_chip(palmas->irq, palmas->irq_data);
 err:
@@ -533,11 +456,6 @@ static const struct i2c_device_id palmas
 };
 MODULE_DEVICE_TABLE(i2c, palmas_i2c_id);
 
-static struct of_device_id of_palmas_match_tbl[] = {
-	{ .compatible = "ti,palmas", },
-	{ /* end */ }
-};
-
 static struct i2c_driver palmas_i2c_driver = {
 	.driver = {
 		   .name = "palmas",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/rtl8411.c linux-libre-3.11-rc7-gnu/drivers/mfd/rtl8411.c
--- linux-libre-3.10-gnu/drivers/mfd/rtl8411.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/rtl8411.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,12 +35,33 @@ static u8 rtl8411_get_ic_version(struct
 	return val & 0x0F;
 }
 
+static int rtl8411b_is_qfn48(struct rtsx_pcr *pcr)
+{
+	u8 val = 0;
+
+	rtsx_pci_read_register(pcr, RTL8411B_PACKAGE_MODE, &val);
+
+	if (val & 0x2)
+		return 1;
+	else
+		return 0;
+}
+
 static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
 {
 	return rtsx_pci_write_register(pcr, CD_PAD_CTL,
 			CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
 }
 
+static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr)
+{
+	if (rtl8411b_is_qfn48(pcr))
+		rtsx_pci_write_register(pcr, CARD_PULL_CTL3, 0xFF, 0xF5);
+
+	return rtsx_pci_write_register(pcr, CD_PAD_CTL,
+			CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
+}
+
 static int rtl8411_turn_on_led(struct rtsx_pcr *pcr)
 {
 	return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00);
@@ -214,6 +235,20 @@ static const struct pcr_ops rtl8411_pcr_
 	.conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
 };
 
+static const struct pcr_ops rtl8411b_pcr_ops = {
+	.extra_init_hw = rtl8411b_extra_init_hw,
+	.optimize_phy = NULL,
+	.turn_on_led = rtl8411_turn_on_led,
+	.turn_off_led = rtl8411_turn_off_led,
+	.enable_auto_blink = rtl8411_enable_auto_blink,
+	.disable_auto_blink = rtl8411_disable_auto_blink,
+	.card_power_on = rtl8411_card_power_on,
+	.card_power_off = rtl8411_card_power_off,
+	.switch_output_voltage = rtl8411_switch_output_voltage,
+	.cd_deglitch = rtl8411_cd_deglitch,
+	.conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
+};
+
 /* SD Pull Control Enable:
  *     SD_DAT[3:0] ==> pull up
  *     SD_CD       ==> pull up
@@ -276,6 +311,74 @@ static const u32 rtl8411_ms_pull_ctl_dis
 	0,
 };
 
+static const u32 rtl8411b_qfn64_sd_pull_ctl_enable_tbl[] = {
+	RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
+	RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+	RTSX_REG_PAIR(CARD_PULL_CTL3, 0x09 | 0xD0),
+	RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
+	RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
+	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+	0,
+};
+
+static const u32 rtl8411b_qfn48_sd_pull_ctl_enable_tbl[] = {
+	RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+	RTSX_REG_PAIR(CARD_PULL_CTL3, 0x69 | 0x90),
+	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x08 | 0x11),
+	0,
+};
+
+static const u32 rtl8411b_qfn64_sd_pull_ctl_disable_tbl[] = {
+	RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+	RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+	RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
+	RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
+	RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
+	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+	0,
+};
+
+static const u32 rtl8411b_qfn48_sd_pull_ctl_disable_tbl[] = {
+	RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+	RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
+	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+	0,
+};
+
+static const u32 rtl8411b_qfn64_ms_pull_ctl_enable_tbl[] = {
+	RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+	RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+	RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
+	RTSX_REG_PAIR(CARD_PULL_CTL4, 0x05 | 0x50),
+	RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
+	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+	0,
+};
+
+static const u32 rtl8411b_qfn48_ms_pull_ctl_enable_tbl[] = {
+	RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+	RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
+	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+	0,
+};
+
+static const u32 rtl8411b_qfn64_ms_pull_ctl_disable_tbl[] = {
+	RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+	RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+	RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
+	RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
+	RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
+	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+	0,
+};
+
+static const u32 rtl8411b_qfn48_ms_pull_ctl_disable_tbl[] = {
+	RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+	RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
+	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+	0,
+};
+
 void rtl8411_init_params(struct rtsx_pcr *pcr)
 {
 	pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
@@ -288,3 +391,32 @@ void rtl8411_init_params(struct rtsx_pcr
 	pcr->ms_pull_ctl_enable_tbl = rtl8411_ms_pull_ctl_enable_tbl;
 	pcr->ms_pull_ctl_disable_tbl = rtl8411_ms_pull_ctl_disable_tbl;
 }
+
+void rtl8411b_init_params(struct rtsx_pcr *pcr)
+{
+	pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
+	pcr->num_slots = 2;
+	pcr->ops = &rtl8411b_pcr_ops;
+
+	pcr->ic_version = rtl8411_get_ic_version(pcr);
+
+	if (rtl8411b_is_qfn48(pcr)) {
+		pcr->sd_pull_ctl_enable_tbl =
+			rtl8411b_qfn48_sd_pull_ctl_enable_tbl;
+		pcr->sd_pull_ctl_disable_tbl =
+			rtl8411b_qfn48_sd_pull_ctl_disable_tbl;
+		pcr->ms_pull_ctl_enable_tbl =
+			rtl8411b_qfn48_ms_pull_ctl_enable_tbl;
+		pcr->ms_pull_ctl_disable_tbl =
+			rtl8411b_qfn48_ms_pull_ctl_disable_tbl;
+	} else {
+		pcr->sd_pull_ctl_enable_tbl =
+			rtl8411b_qfn64_sd_pull_ctl_enable_tbl;
+		pcr->sd_pull_ctl_disable_tbl =
+			rtl8411b_qfn64_sd_pull_ctl_disable_tbl;
+		pcr->ms_pull_ctl_enable_tbl =
+			rtl8411b_qfn64_ms_pull_ctl_enable_tbl;
+		pcr->ms_pull_ctl_disable_tbl =
+			rtl8411b_qfn64_ms_pull_ctl_disable_tbl;
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/rtsx_pcr.c linux-libre-3.11-rc7-gnu/drivers/mfd/rtsx_pcr.c
--- linux-libre-3.10-gnu/drivers/mfd/rtsx_pcr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/rtsx_pcr.c	2013-08-25 20:43:22.000000000 -0400
@@ -57,6 +57,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtsx_pci_
 	{ PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 },
 	{ PCI_DEVICE(0x10EC, 0x5227), PCI_CLASS_OTHERS << 16, 0xFF0000 },
 	{ PCI_DEVICE(0x10EC, 0x5249), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+	{ PCI_DEVICE(0x10EC, 0x5287), PCI_CLASS_OTHERS << 16, 0xFF0000 },
 	{ 0, }
 };
 
@@ -1038,6 +1039,10 @@ static int rtsx_pci_init_chip(struct rts
 	case 0x5249:
 		rts5249_init_params(pcr);
 		break;
+
+	case 0x5287:
+		rtl8411b_init_params(pcr);
+		break;
 	}
 
 	dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/rtsx_pcr.h linux-libre-3.11-rc7-gnu/drivers/mfd/rtsx_pcr.h
--- linux-libre-3.10-gnu/drivers/mfd/rtsx_pcr.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/rtsx_pcr.h	2013-08-25 20:43:22.000000000 -0400
@@ -33,5 +33,6 @@ void rts5229_init_params(struct rtsx_pcr
 void rtl8411_init_params(struct rtsx_pcr *pcr);
 void rts5227_init_params(struct rtsx_pcr *pcr);
 void rts5249_init_params(struct rtsx_pcr *pcr);
+void rtl8411b_init_params(struct rtsx_pcr *pcr);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/sec-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/sec-core.c
--- linux-libre-3.10-gnu/drivers/mfd/sec-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/sec-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,9 @@
 #include <linux/mfd/samsung/core.h>
 #include <linux/mfd/samsung/irq.h>
 #include <linux/mfd/samsung/rtc.h>
+#include <linux/mfd/samsung/s2mps11.h>
+#include <linux/mfd/samsung/s5m8763.h>
+#include <linux/mfd/samsung/s5m8767.h>
 #include <linux/regmap.h>
 
 static struct mfd_cell s5m8751_devs[] = {
@@ -105,6 +108,26 @@ static struct regmap_config sec_regmap_c
 	.val_bits = 8,
 };
 
+static struct regmap_config s2mps11_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = S2MPS11_REG_L38CTRL,
+};
+
+static struct regmap_config s5m8763_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = S5M8763_REG_LBCNFG2,
+};
+
+static struct regmap_config s5m8767_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = S5M8767_REG_LDO28CTRL,
+};
 
 #ifdef CONFIG_OF
 /*
@@ -160,6 +183,7 @@ static int sec_pmic_probe(struct i2c_cli
 			    const struct i2c_device_id *id)
 {
 	struct sec_platform_data *pdata = i2c->dev.platform_data;
+	const struct regmap_config *regmap;
 	struct sec_pmic_dev *sec_pmic;
 	int ret;
 
@@ -190,7 +214,22 @@ static int sec_pmic_probe(struct i2c_cli
 		sec_pmic->pdata = pdata;
 	}
 
-	sec_pmic->regmap = devm_regmap_init_i2c(i2c, &sec_regmap_config);
+	switch (sec_pmic->device_type) {
+	case S2MPS11X:
+		regmap = &s2mps11_regmap_config;
+		break;
+	case S5M8763X:
+		regmap = &s5m8763_regmap_config;
+		break;
+	case S5M8767X:
+		regmap = &s5m8767_regmap_config;
+		break;
+	default:
+		regmap = &sec_regmap_config;
+		break;
+	}
+
+	sec_pmic->regmap = devm_regmap_init_i2c(i2c, regmap);
 	if (IS_ERR(sec_pmic->regmap)) {
 		ret = PTR_ERR(sec_pmic->regmap);
 		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -230,13 +269,12 @@ static int sec_pmic_probe(struct i2c_cli
 		BUG();
 	}
 
-	if (ret < 0)
+	if (ret)
 		goto err;
 
 	return ret;
 
 err:
-	mfd_remove_devices(sec_pmic->dev);
 	sec_irq_exit(sec_pmic);
 	i2c_unregister_device(sec_pmic->rtc);
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/ssbi.c linux-libre-3.11-rc7-gnu/drivers/mfd/ssbi.c
--- linux-libre-3.10-gnu/drivers/mfd/ssbi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/ssbi.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,333 @@
+/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010, Google Inc.
+ *
+ * Original authors: Code Aurora Forum
+ *
+ * Author: Dima Zavin <dima@android.com>
+ *  - Largely rewritten from original to not be an i2c driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/ssbi.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+/* SSBI 2.0 controller registers */
+#define SSBI2_CMD			0x0008
+#define SSBI2_RD			0x0010
+#define SSBI2_STATUS			0x0014
+#define SSBI2_MODE2			0x001C
+
+/* SSBI_CMD fields */
+#define SSBI_CMD_RDWRN			(1 << 24)
+
+/* SSBI_STATUS fields */
+#define SSBI_STATUS_RD_READY		(1 << 2)
+#define SSBI_STATUS_READY		(1 << 1)
+#define SSBI_STATUS_MCHN_BUSY		(1 << 0)
+
+/* SSBI_MODE2 fields */
+#define SSBI_MODE2_REG_ADDR_15_8_SHFT	0x04
+#define SSBI_MODE2_REG_ADDR_15_8_MASK	(0x7f << SSBI_MODE2_REG_ADDR_15_8_SHFT)
+
+#define SET_SSBI_MODE2_REG_ADDR_15_8(MD, AD) \
+	(((MD) & 0x0F) | ((((AD) >> 8) << SSBI_MODE2_REG_ADDR_15_8_SHFT) & \
+	SSBI_MODE2_REG_ADDR_15_8_MASK))
+
+/* SSBI PMIC Arbiter command registers */
+#define SSBI_PA_CMD			0x0000
+#define SSBI_PA_RD_STATUS		0x0004
+
+/* SSBI_PA_CMD fields */
+#define SSBI_PA_CMD_RDWRN		(1 << 24)
+#define SSBI_PA_CMD_ADDR_MASK		0x7fff /* REG_ADDR_7_0, REG_ADDR_8_14*/
+
+/* SSBI_PA_RD_STATUS fields */
+#define SSBI_PA_RD_STATUS_TRANS_DONE	(1 << 27)
+#define SSBI_PA_RD_STATUS_TRANS_DENIED	(1 << 26)
+
+#define SSBI_TIMEOUT_US			100
+
+struct ssbi {
+	struct device		*slave;
+	void __iomem		*base;
+	spinlock_t		lock;
+	enum ssbi_controller_type controller_type;
+	int (*read)(struct ssbi *, u16 addr, u8 *buf, int len);
+	int (*write)(struct ssbi *, u16 addr, u8 *buf, int len);
+};
+
+#define to_ssbi(dev)	platform_get_drvdata(to_platform_device(dev))
+
+static inline u32 ssbi_readl(struct ssbi *ssbi, u32 reg)
+{
+	return readl(ssbi->base + reg);
+}
+
+static inline void ssbi_writel(struct ssbi *ssbi, u32 val, u32 reg)
+{
+	writel(val, ssbi->base + reg);
+}
+
+/*
+ * Via private exchange with one of the original authors, the hardware
+ * should generally finish a transaction in about 5us.  The worst
+ * case, is when using the arbiter and both other CPUs have just
+ * started trying to use the SSBI bus will result in a time of about
+ * 20us.  It should never take longer than this.
+ *
+ * As such, this wait merely spins, with a udelay.
+ */
+static int ssbi_wait_mask(struct ssbi *ssbi, u32 set_mask, u32 clr_mask)
+{
+	u32 timeout = SSBI_TIMEOUT_US;
+	u32 val;
+
+	while (timeout--) {
+		val = ssbi_readl(ssbi, SSBI2_STATUS);
+		if (((val & set_mask) == set_mask) && ((val & clr_mask) == 0))
+			return 0;
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int
+ssbi_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
+{
+	u32 cmd = SSBI_CMD_RDWRN | ((addr & 0xff) << 16);
+	int ret = 0;
+
+	if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
+		u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
+		mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
+		ssbi_writel(ssbi, mode2, SSBI2_MODE2);
+	}
+
+	while (len) {
+		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
+		if (ret)
+			goto err;
+
+		ssbi_writel(ssbi, cmd, SSBI2_CMD);
+		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_RD_READY, 0);
+		if (ret)
+			goto err;
+		*buf++ = ssbi_readl(ssbi, SSBI2_RD) & 0xff;
+		len--;
+	}
+
+err:
+	return ret;
+}
+
+static int
+ssbi_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
+{
+	int ret = 0;
+
+	if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
+		u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
+		mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
+		ssbi_writel(ssbi, mode2, SSBI2_MODE2);
+	}
+
+	while (len) {
+		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
+		if (ret)
+			goto err;
+
+		ssbi_writel(ssbi, ((addr & 0xff) << 16) | *buf, SSBI2_CMD);
+		ret = ssbi_wait_mask(ssbi, 0, SSBI_STATUS_MCHN_BUSY);
+		if (ret)
+			goto err;
+		buf++;
+		len--;
+	}
+
+err:
+	return ret;
+}
+
+/*
+ * See ssbi_wait_mask for an explanation of the time and the
+ * busywait.
+ */
+static inline int
+ssbi_pa_transfer(struct ssbi *ssbi, u32 cmd, u8 *data)
+{
+	u32 timeout = SSBI_TIMEOUT_US;
+	u32 rd_status = 0;
+
+	ssbi_writel(ssbi, cmd, SSBI_PA_CMD);
+
+	while (timeout--) {
+		rd_status = ssbi_readl(ssbi, SSBI_PA_RD_STATUS);
+
+		if (rd_status & SSBI_PA_RD_STATUS_TRANS_DENIED)
+			return -EPERM;
+
+		if (rd_status & SSBI_PA_RD_STATUS_TRANS_DONE) {
+			if (data)
+				*data = rd_status & 0xff;
+			return 0;
+		}
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int
+ssbi_pa_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
+{
+	u32 cmd;
+	int ret = 0;
+
+	cmd = SSBI_PA_CMD_RDWRN | (addr & SSBI_PA_CMD_ADDR_MASK) << 8;
+
+	while (len) {
+		ret = ssbi_pa_transfer(ssbi, cmd, buf);
+		if (ret)
+			goto err;
+		buf++;
+		len--;
+	}
+
+err:
+	return ret;
+}
+
+static int
+ssbi_pa_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
+{
+	u32 cmd;
+	int ret = 0;
+
+	while (len) {
+		cmd = (addr & SSBI_PA_CMD_ADDR_MASK) << 8 | *buf;
+		ret = ssbi_pa_transfer(ssbi, cmd, NULL);
+		if (ret)
+			goto err;
+		buf++;
+		len--;
+	}
+
+err:
+	return ret;
+}
+
+int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
+{
+	struct ssbi *ssbi = to_ssbi(dev);
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&ssbi->lock, flags);
+	ret = ssbi->read(ssbi, addr, buf, len);
+	spin_unlock_irqrestore(&ssbi->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ssbi_read);
+
+int ssbi_write(struct device *dev, u16 addr, u8 *buf, int len)
+{
+	struct ssbi *ssbi = to_ssbi(dev);
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&ssbi->lock, flags);
+	ret = ssbi->write(ssbi, addr, buf, len);
+	spin_unlock_irqrestore(&ssbi->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ssbi_write);
+
+static int ssbi_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *mem_res;
+	struct ssbi *ssbi;
+	const char *type;
+
+	ssbi = devm_kzalloc(&pdev->dev, sizeof(*ssbi), GFP_KERNEL);
+	if (!ssbi)
+		return -ENOMEM;
+
+	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ssbi->base = devm_ioremap_resource(&pdev->dev, mem_res);
+	if (IS_ERR(ssbi->base))
+		return PTR_ERR(ssbi->base);
+
+	platform_set_drvdata(pdev, ssbi);
+
+	type = of_get_property(np, "qcom,controller-type", NULL);
+	if (type == NULL) {
+		dev_err(&pdev->dev, "Missing qcom,controller-type property\n");
+		return -EINVAL;
+	}
+	dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type);
+	if (strcmp(type, "ssbi") == 0)
+		ssbi->controller_type = MSM_SBI_CTRL_SSBI;
+	else if (strcmp(type, "ssbi2") == 0)
+		ssbi->controller_type = MSM_SBI_CTRL_SSBI2;
+	else if (strcmp(type, "pmic-arbiter") == 0)
+		ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER;
+	else {
+		dev_err(&pdev->dev, "Unknown qcom,controller-type\n");
+		return -EINVAL;
+	}
+
+	if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
+		ssbi->read = ssbi_pa_read_bytes;
+		ssbi->write = ssbi_pa_write_bytes;
+	} else {
+		ssbi->read = ssbi_read_bytes;
+		ssbi->write = ssbi_write_bytes;
+	}
+
+	spin_lock_init(&ssbi->lock);
+
+	return of_platform_populate(np, NULL, NULL, &pdev->dev);
+}
+
+static struct of_device_id ssbi_match_table[] = {
+	{ .compatible = "qcom,ssbi" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, ssbi_match_table);
+
+static struct platform_driver ssbi_driver = {
+	.probe		= ssbi_probe,
+	.driver		= {
+		.name	= "ssbi",
+		.owner	= THIS_MODULE,
+		.of_match_table = ssbi_match_table,
+	},
+};
+module_platform_driver(ssbi_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:ssbi");
+MODULE_AUTHOR("Dima Zavin <dima@android.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/stmpe.c linux-libre-3.11-rc7-gnu/drivers/mfd/stmpe.c
--- linux-libre-3.10-gnu/drivers/mfd/stmpe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/stmpe.c	2013-08-25 20:43:22.000000000 -0400
@@ -1208,8 +1208,7 @@ int stmpe_probe(struct stmpe_client_info
 		}
 		stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
 	} else if (pdata->irq_trigger == IRQF_TRIGGER_NONE) {
-		pdata->irq_trigger =
-			irqd_get_trigger_type(irq_get_irq_data(stmpe->irq));
+		pdata->irq_trigger = irq_get_trigger_type(stmpe->irq);
 	}
 
 	ret = stmpe_chip_init(stmpe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/syscon.c linux-libre-3.11-rc7-gnu/drivers/mfd/syscon.c
--- linux-libre-3.10-gnu/drivers/mfd/syscon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/syscon.c	2013-08-25 20:43:22.000000000 -0400
@@ -159,6 +159,9 @@ static int syscon_probe(struct platform_
 
 static const struct platform_device_id syscon_ids[] = {
 	{ "syscon", },
+#ifdef CONFIG_ARCH_CLPS711X
+	{ "clps711x-syscon", },
+#endif
 	{ }
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/t7l66xb.c linux-libre-3.11-rc7-gnu/drivers/mfd/t7l66xb.c
--- linux-libre-3.10-gnu/drivers/mfd/t7l66xb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/t7l66xb.c	2013-08-25 20:43:22.000000000 -0400
@@ -422,7 +422,6 @@ static int t7l66xb_remove(struct platfor
 	iounmap(t7l66xb->scr);
 	release_resource(&t7l66xb->rscr);
 	mfd_remove_devices(&dev->dev);
-	platform_set_drvdata(dev, NULL);
 	kfree(t7l66xb);
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/tc6387xb.c linux-libre-3.11-rc7-gnu/drivers/mfd/tc6387xb.c
--- linux-libre-3.10-gnu/drivers/mfd/tc6387xb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/tc6387xb.c	2013-08-25 20:43:22.000000000 -0400
@@ -217,7 +217,6 @@ static int tc6387xb_remove(struct platfo
 	release_resource(&tc6387xb->rscr);
 	clk_disable(tc6387xb->clk32k);
 	clk_put(tc6387xb->clk32k);
-	platform_set_drvdata(dev, NULL);
 	kfree(tc6387xb);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/tc6393xb.c linux-libre-3.11-rc7-gnu/drivers/mfd/tc6393xb.c
--- linux-libre-3.10-gnu/drivers/mfd/tc6393xb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/tc6393xb.c	2013-08-25 20:43:22.000000000 -0400
@@ -756,7 +756,6 @@ static int tc6393xb_remove(struct platfo
 	clk_disable(tc6393xb->clk);
 	iounmap(tc6393xb->scr);
 	release_resource(&tc6393xb->rscr);
-	platform_set_drvdata(dev, NULL);
 	clk_put(tc6393xb->clk);
 	kfree(tc6393xb);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/ti_am335x_tscadc.c linux-libre-3.11-rc7-gnu/drivers/mfd/ti_am335x_tscadc.c
--- linux-libre-3.10-gnu/drivers/mfd/ti_am335x_tscadc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/ti_am335x_tscadc.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,10 +22,10 @@
 #include <linux/regmap.h>
 #include <linux/mfd/core.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <linux/mfd/ti_am335x_tscadc.h>
-#include <linux/input/ti_am335x_tsc.h>
-#include <linux/platform_data/ti_am335x_adc.h>
 
 static unsigned int tscadc_readl(struct ti_tscadc_dev *tsadc, unsigned int reg)
 {
@@ -48,6 +48,32 @@ static const struct regmap_config tscadc
 	.val_bits = 32,
 };
 
+void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc)
+{
+	tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
+}
+EXPORT_SYMBOL_GPL(am335x_tsc_se_update);
+
+void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val)
+{
+	spin_lock(&tsadc->reg_lock);
+	tsadc->reg_se_cache |= val;
+	spin_unlock(&tsadc->reg_lock);
+
+	am335x_tsc_se_update(tsadc);
+}
+EXPORT_SYMBOL_GPL(am335x_tsc_se_set);
+
+void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
+{
+	spin_lock(&tsadc->reg_lock);
+	tsadc->reg_se_cache &= ~val;
+	spin_unlock(&tsadc->reg_lock);
+
+	am335x_tsc_se_update(tsadc);
+}
+EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
+
 static void tscadc_idle_config(struct ti_tscadc_dev *config)
 {
 	unsigned int idleconfig;
@@ -63,27 +89,48 @@ static	int ti_tscadc_probe(struct platfo
 	struct ti_tscadc_dev	*tscadc;
 	struct resource		*res;
 	struct clk		*clk;
-	struct mfd_tscadc_board	*pdata = pdev->dev.platform_data;
+	struct device_node	*node = pdev->dev.of_node;
 	struct mfd_cell		*cell;
+	struct property         *prop;
+	const __be32            *cur;
+	u32			val;
 	int			err, ctrl;
 	int			clk_value, clock_rate;
-	int			tsc_wires, adc_channels = 0, total_channels;
+	int			tsc_wires = 0, adc_channels = 0, total_channels;
+	int			readouts = 0;
 
-	if (!pdata) {
-		dev_err(&pdev->dev, "Could not find platform data\n");
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "Could not find valid DT data.\n");
 		return -EINVAL;
 	}
 
-	if (pdata->adc_init)
-		adc_channels = pdata->adc_init->adc_channels;
+	node = of_get_child_by_name(pdev->dev.of_node, "tsc");
+	of_property_read_u32(node, "ti,wires", &tsc_wires);
+	of_property_read_u32(node, "ti,coordiante-readouts", &readouts);
 
-	tsc_wires = pdata->tsc_init->wires;
+	node = of_get_child_by_name(pdev->dev.of_node, "adc");
+	of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
+		adc_channels++;
+		if (val > 7) {
+			dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n",
+					val);
+			return -EINVAL;
+		}
+	}
 	total_channels = tsc_wires + adc_channels;
-
 	if (total_channels > 8) {
 		dev_err(&pdev->dev, "Number of i/p channels more than 8\n");
 		return -EINVAL;
 	}
+	if (total_channels == 0) {
+		dev_err(&pdev->dev, "Need atleast one channel.\n");
+		return -EINVAL;
+	}
+
+	if (readouts * 2 + 2 + adc_channels > 16) {
+		dev_err(&pdev->dev, "Too many step configurations requested\n");
+		return -EINVAL;
+	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
@@ -129,6 +176,7 @@ static	int ti_tscadc_probe(struct platfo
 		goto ret;
 	}
 
+	spin_lock_init(&tscadc->reg_lock);
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 
@@ -173,26 +221,37 @@ static	int ti_tscadc_probe(struct platfo
 	ctrl |= CNTRLREG_TSCSSENB;
 	tscadc_writel(tscadc, REG_CTRL, ctrl);
 
+	tscadc->used_cells = 0;
+	tscadc->tsc_cell = -1;
+	tscadc->adc_cell = -1;
+
 	/* TSC Cell */
-	cell = &tscadc->cells[TSC_CELL];
-	cell->name = "tsc";
-	cell->platform_data = tscadc;
-	cell->pdata_size = sizeof(*tscadc);
+	if (tsc_wires > 0) {
+		tscadc->tsc_cell = tscadc->used_cells;
+		cell = &tscadc->cells[tscadc->used_cells++];
+		cell->name = "TI-am335x-tsc";
+		cell->of_compatible = "ti,am3359-tsc";
+		cell->platform_data = &tscadc;
+		cell->pdata_size = sizeof(tscadc);
+	}
 
 	/* ADC Cell */
-	cell = &tscadc->cells[ADC_CELL];
-	cell->name = "tiadc";
-	cell->platform_data = tscadc;
-	cell->pdata_size = sizeof(*tscadc);
+	if (adc_channels > 0) {
+		tscadc->adc_cell = tscadc->used_cells;
+		cell = &tscadc->cells[tscadc->used_cells++];
+		cell->name = "TI-am335x-adc";
+		cell->of_compatible = "ti,am3359-adc";
+		cell->platform_data = &tscadc;
+		cell->pdata_size = sizeof(tscadc);
+	}
 
 	err = mfd_add_devices(&pdev->dev, pdev->id, tscadc->cells,
-			TSCADC_CELLS, NULL, 0, NULL);
+			tscadc->used_cells, NULL, 0, NULL);
 	if (err < 0)
 		goto err_disable_clk;
 
 	device_init_wakeup(&pdev->dev, true);
 	platform_set_drvdata(pdev, tscadc);
-
 	return 0;
 
 err_disable_clk:
@@ -239,7 +298,7 @@ static int tscadc_resume(struct device *
 			CNTRLREG_STEPID | CNTRLREG_4WIRE;
 	tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
 	tscadc_idle_config(tscadc_dev);
-	tscadc_writel(tscadc_dev, REG_SE, STPENB_STEPENB);
+	am335x_tsc_se_update(tscadc_dev);
 	restore = tscadc_readl(tscadc_dev, REG_CTRL);
 	tscadc_writel(tscadc_dev, REG_CTRL,
 			(restore | CNTRLREG_TSCSSENB));
@@ -256,11 +315,18 @@ static const struct dev_pm_ops tscadc_pm
 #define TSCADC_PM_OPS NULL
 #endif
 
+static const struct of_device_id ti_tscadc_dt_ids[] = {
+	{ .compatible = "ti,am3359-tscadc", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids);
+
 static struct platform_driver ti_tscadc_driver = {
 	.driver = {
-		.name   = "ti_tscadc",
+		.name   = "ti_am3359-tscadc",
 		.owner	= THIS_MODULE,
 		.pm	= TSCADC_PM_OPS,
+		.of_match_table = of_match_ptr(ti_tscadc_dt_ids),
 	},
 	.probe	= ti_tscadc_probe,
 	.remove	= ti_tscadc_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/timberdale.c linux-libre-3.11-rc7-gnu/drivers/mfd/timberdale.c
--- linux-libre-3.10-gnu/drivers/mfd/timberdale.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/timberdale.c	2013-08-25 20:43:22.000000000 -0400
@@ -145,7 +145,6 @@ static struct spi_board_info timberdale_
 
 static struct xspi_platform_data timberdale_xspi_platform_data = {
 	.num_chipselect = 3,
-	.little_endian = true,
 	/* bits per word and devices will be filled in runtime depending
 	 * on the HW config
 	 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/tps65912-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/tps65912-core.c
--- linux-libre-3.10-gnu/drivers/mfd/tps65912-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/tps65912-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -162,7 +162,6 @@ int tps65912_device_init(struct tps65912
 err:
 	kfree(init_data);
 	mfd_remove_devices(tps65912->dev);
-	kfree(tps65912);
 	return ret;
 }
 
@@ -170,7 +169,6 @@ void tps65912_device_exit(struct tps6591
 {
 	mfd_remove_devices(tps65912->dev);
 	tps65912_irq_exit(tps65912);
-	kfree(tps65912);
 }
 
 MODULE_AUTHOR("Margarita Olaya	<magi@slimlogic.co.uk>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/tps65912-i2c.c linux-libre-3.11-rc7-gnu/drivers/mfd/tps65912-i2c.c
--- linux-libre-3.10-gnu/drivers/mfd/tps65912-i2c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/tps65912-i2c.c	2013-08-25 20:43:22.000000000 -0400
@@ -77,7 +77,8 @@ static int tps65912_i2c_probe(struct i2c
 {
 	struct tps65912 *tps65912;
 
-	tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL);
+	tps65912 = devm_kzalloc(&i2c->dev,
+				sizeof(struct tps65912), GFP_KERNEL);
 	if (tps65912 == NULL)
 		return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/tps65912-spi.c linux-libre-3.11-rc7-gnu/drivers/mfd/tps65912-spi.c
--- linux-libre-3.10-gnu/drivers/mfd/tps65912-spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/tps65912-spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -85,7 +85,8 @@ static int tps65912_spi_probe(struct spi
 {
 	struct tps65912 *tps65912;
 
-	tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL);
+	tps65912 = devm_kzalloc(&spi->dev,
+				sizeof(struct tps65912), GFP_KERNEL);
 	if (tps65912 == NULL)
 		return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/twl4030-audio.c linux-libre-3.11-rc7-gnu/drivers/mfd/twl4030-audio.c
--- linux-libre-3.10-gnu/drivers/mfd/twl4030-audio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/twl4030-audio.c	2013-08-25 20:43:22.000000000 -0400
@@ -261,10 +261,8 @@ static int twl4030_audio_probe(struct pl
 		ret = -ENODEV;
 	}
 
-	if (ret) {
-		platform_set_drvdata(pdev, NULL);
+	if (ret)
 		twl4030_audio_dev = NULL;
-	}
 
 	return ret;
 }
@@ -272,7 +270,6 @@ static int twl4030_audio_probe(struct pl
 static int twl4030_audio_remove(struct platform_device *pdev)
 {
 	mfd_remove_devices(&pdev->dev);
-	platform_set_drvdata(pdev, NULL);
 	twl4030_audio_dev = NULL;
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/twl4030-irq.c linux-libre-3.11-rc7-gnu/drivers/mfd/twl4030-irq.c
--- linux-libre-3.10-gnu/drivers/mfd/twl4030-irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/twl4030-irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -537,16 +537,13 @@ static void twl4030_sih_bus_sync_unlock(
 		/* Modify only the bits we know must change */
 		while (edge_change) {
 			int		i = fls(edge_change) - 1;
-			struct irq_data	*idata;
 			int		byte = i >> 2;
 			int		off = (i & 0x3) * 2;
 			unsigned int	type;
 
-			idata = irq_get_irq_data(i + agent->irq_base);
-
 			bytes[byte] &= ~(0x03 << off);
 
-			type = irqd_get_trigger_type(idata);
+			type = irq_get_trigger_type(i + agent->irq_base);
 			if (type & IRQ_TYPE_EDGE_RISING)
 				bytes[byte] |= BIT(off + 1);
 			if (type & IRQ_TYPE_EDGE_FALLING)
@@ -573,6 +570,7 @@ static struct irq_chip twl4030_sih_irq_c
 	.irq_set_type	= twl4030_sih_set_type,
 	.irq_bus_lock	= twl4030_sih_bus_lock,
 	.irq_bus_sync_unlock = twl4030_sih_bus_sync_unlock,
+	.flags		= IRQCHIP_SKIP_SET_WAKE,
 };
 
 /*----------------------------------------------------------------------*/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/twl4030-madc.c linux-libre-3.11-rc7-gnu/drivers/mfd/twl4030-madc.c
--- linux-libre-3.10-gnu/drivers/mfd/twl4030-madc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/twl4030-madc.c	2013-08-25 20:43:22.000000000 -0400
@@ -775,12 +775,10 @@ static int twl4030_madc_probe(struct pla
 				   IRQF_TRIGGER_RISING, "twl4030_madc", madc);
 	if (ret) {
 		dev_dbg(&pdev->dev, "could not request irq\n");
-		goto err_irq;
+		goto err_i2c;
 	}
 	twl4030_madc = madc;
 	return 0;
-err_irq:
-	platform_set_drvdata(pdev, NULL);
 err_i2c:
 	twl4030_madc_set_current_generator(madc, 0, 0);
 err_current_generator:
@@ -796,7 +794,6 @@ static int twl4030_madc_remove(struct pl
 	struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
 
 	free_irq(platform_get_irq(pdev, 0), madc);
-	platform_set_drvdata(pdev, NULL);
 	twl4030_madc_set_current_generator(madc, 0, 0);
 	twl4030_madc_set_power(madc, 0);
 	kfree(madc);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/twl4030-power.c linux-libre-3.11-rc7-gnu/drivers/mfd/twl4030-power.c
--- linux-libre-3.10-gnu/drivers/mfd/twl4030-power.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/twl4030-power.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/pm.h>
 #include <linux/i2c/twl.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 #include <asm/mach-types.h>
 
@@ -492,6 +493,39 @@ int twl4030_remove_script(u8 flags)
 	return err;
 }
 
+int twl4030_power_configure_scripts(struct twl4030_power_data *pdata)
+{
+	int err;
+	int i;
+	u8 address = twl4030_start_script_address;
+
+	for (i = 0; i < pdata->num; i++) {
+		err = load_twl4030_script(pdata->scripts[i], address);
+		if (err)
+			return err;
+		address += pdata->scripts[i]->size;
+	}
+
+	return 0;
+}
+
+int twl4030_power_configure_resources(struct twl4030_power_data *pdata)
+{
+	struct twl4030_resconfig *resconfig = pdata->resource_config;
+	int err;
+
+	if (resconfig) {
+		while (resconfig->resource) {
+			err = twl4030_configure_resource(resconfig);
+			if (err)
+				return err;
+			resconfig++;
+		}
+	}
+
+	return 0;
+}
+
 /*
  * In master mode, start the power off sequence.
  * After a successful execution, TWL shuts down the power to the SoC
@@ -507,43 +541,58 @@ void twl4030_power_off(void)
 		pr_err("TWL4030 Unable to power off\n");
 }
 
-void twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
+static bool twl4030_power_use_poweroff(struct twl4030_power_data *pdata,
+					struct device_node *node)
 {
+	if (pdata && pdata->use_poweroff)
+		return true;
+
+	if (of_property_read_bool(node, "ti,use_poweroff"))
+		return true;
+
+	return false;
+}
+
+int twl4030_power_probe(struct platform_device *pdev)
+{
+	struct twl4030_power_data *pdata = pdev->dev.platform_data;
+	struct device_node *node = pdev->dev.of_node;
 	int err = 0;
-	int i;
-	struct twl4030_resconfig *resconfig;
-	u8 val, address = twl4030_start_script_address;
+	int err2 = 0;
+	u8 val;
+
+	if (!pdata && !node) {
+		dev_err(&pdev->dev, "Platform data is missing\n");
+		return -EINVAL;
+	}
 
 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
 			       TWL4030_PM_MASTER_PROTECT_KEY);
-	if (err)
-		goto unlock;
-
-	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
+	err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
+			       TWL4030_PM_MASTER_KEY_CFG2,
 			       TWL4030_PM_MASTER_PROTECT_KEY);
-	if (err)
-		goto unlock;
 
-	for (i = 0; i < twl4030_scripts->num; i++) {
-		err = load_twl4030_script(twl4030_scripts->scripts[i], address);
-		if (err)
-			goto load;
-		address += twl4030_scripts->scripts[i]->size;
+	if (err) {
+		pr_err("TWL4030 Unable to unlock registers\n");
+		return err;
 	}
 
-	resconfig = twl4030_scripts->resource_config;
-	if (resconfig) {
-		while (resconfig->resource) {
-			err = twl4030_configure_resource(resconfig);
-			if (err)
-				goto resource;
-			resconfig++;
-
+	if (pdata) {
+		/* TODO: convert to device tree */
+		err = twl4030_power_configure_scripts(pdata);
+		if (err) {
+			pr_err("TWL4030 failed to load scripts\n");
+			goto relock;
+		}
+		err = twl4030_power_configure_resources(pdata);
+		if (err) {
+			pr_err("TWL4030 failed to configure resource\n");
+			goto relock;
 		}
 	}
 
 	/* Board has to be wired properly to use this feature */
-	if (twl4030_scripts->use_poweroff && !pm_power_off) {
+	if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
 		/* Default for SEQ_OFFSYNC is set, lets ensure this */
 		err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
 				      TWL4030_PM_MASTER_CFG_P123_TRANSITION);
@@ -564,22 +613,43 @@ void twl4030_power_init(struct twl4030_p
 	}
 
 relock:
-	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
+	err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
 			       TWL4030_PM_MASTER_PROTECT_KEY);
-	if (err)
+	if (err2) {
 		pr_err("TWL4030 Unable to relock registers\n");
-	return;
+		return err2;
+	}
 
-unlock:
-	if (err)
-		pr_err("TWL4030 Unable to unlock registers\n");
-	return;
-load:
-	if (err)
-		pr_err("TWL4030 failed to load scripts\n");
-	return;
-resource:
-	if (err)
-		pr_err("TWL4030 failed to configure resource\n");
-	return;
+	return err;
 }
+
+static int twl4030_power_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id twl4030_power_of_match[] = {
+	{.compatible = "ti,twl4030-power", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, twl4030_power_of_match);
+#endif
+
+static struct platform_driver twl4030_power_driver = {
+	.driver = {
+		.name	= "twl4030_power",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(twl4030_power_of_match),
+	},
+	.probe		= twl4030_power_probe,
+	.remove		= twl4030_power_remove,
+};
+
+module_platform_driver(twl4030_power_driver);
+
+MODULE_AUTHOR("Nokia Corporation");
+MODULE_AUTHOR("Texas Instruments, Inc.");
+MODULE_DESCRIPTION("Power management for TWL4030");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:twl4030_power");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/twl-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/twl-core.c
--- linux-libre-3.10-gnu/drivers/mfd/twl-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/twl-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -118,7 +118,7 @@
 #define TWL6030_BASEADD_GASGAUGE	0x00C0
 #define TWL6030_BASEADD_PIH		0x00D0
 #define TWL6030_BASEADD_CHARGER		0x00E0
-#define TWL6025_BASEADD_CHARGER		0x00DA
+#define TWL6032_BASEADD_CHARGER		0x00DA
 #define TWL6030_BASEADD_LED		0x00F4
 
 /* subchip/slave 2 0x4A - DFT */
@@ -718,9 +718,9 @@ add_children(struct twl4030_platform_dat
 					| REGULATOR_CHANGE_STATUS,
 			};
 
-			if (features & TWL6025_SUBCLASS) {
+			if (features & TWL6032_SUBCLASS) {
 				usb3v3.supply =	"ldousb";
-				regulator = TWL6025_REG_LDOUSB;
+				regulator = TWL6032_REG_LDOUSB;
 			} else {
 				usb3v3.supply = "vusb";
 				regulator = TWL6030_REG_VUSB;
@@ -747,8 +747,8 @@ add_children(struct twl4030_platform_dat
 			usb3v3.dev_name = dev_name(child);
 	} else if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) &&
 		   twl_class_is_6030()) {
-		if (features & TWL6025_SUBCLASS)
-			child = add_regulator(TWL6025_REG_LDOUSB,
+		if (features & TWL6032_SUBCLASS)
+			child = add_regulator(TWL6032_REG_LDOUSB,
 						pdata->ldousb, features);
 		else
 			child = add_regulator(TWL6030_REG_VUSB,
@@ -872,7 +872,7 @@ add_children(struct twl4030_platform_dat
 
 	/* twl6030 regulators */
 	if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
-			!(features & TWL6025_SUBCLASS)) {
+			!(features & TWL6032_SUBCLASS)) {
 		child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1,
 					features);
 		if (IS_ERR(child))
@@ -952,60 +952,60 @@ add_children(struct twl4030_platform_dat
 			return PTR_ERR(child);
 	}
 
-	/* twl6025 regulators */
+	/* twl6032 regulators */
 	if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
-			(features & TWL6025_SUBCLASS)) {
-		child = add_regulator(TWL6025_REG_LDO5, pdata->ldo5,
+			(features & TWL6032_SUBCLASS)) {
+		child = add_regulator(TWL6032_REG_LDO5, pdata->ldo5,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_LDO1, pdata->ldo1,
+		child = add_regulator(TWL6032_REG_LDO1, pdata->ldo1,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_LDO7, pdata->ldo7,
+		child = add_regulator(TWL6032_REG_LDO7, pdata->ldo7,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_LDO6, pdata->ldo6,
+		child = add_regulator(TWL6032_REG_LDO6, pdata->ldo6,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_LDOLN, pdata->ldoln,
+		child = add_regulator(TWL6032_REG_LDOLN, pdata->ldoln,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_LDO2, pdata->ldo2,
+		child = add_regulator(TWL6032_REG_LDO2, pdata->ldo2,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_LDO4, pdata->ldo4,
+		child = add_regulator(TWL6032_REG_LDO4, pdata->ldo4,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_LDO3, pdata->ldo3,
+		child = add_regulator(TWL6032_REG_LDO3, pdata->ldo3,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_SMPS3, pdata->smps3,
+		child = add_regulator(TWL6032_REG_SMPS3, pdata->smps3,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_SMPS4, pdata->smps4,
+		child = add_regulator(TWL6032_REG_SMPS4, pdata->smps4,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6025_REG_VIO, pdata->vio6025,
+		child = add_regulator(TWL6032_REG_VIO, pdata->vio6025,
 					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
@@ -1023,6 +1023,14 @@ add_children(struct twl4030_platform_dat
 			return PTR_ERR(child);
 	}
 
+	if (IS_ENABLED(CONFIG_TWL4030_POWER) && pdata->power) {
+		child = add_child(TWL_MODULE_PM_MASTER, "twl4030_power",
+				  pdata->power, sizeof(*pdata->power), false,
+				  0, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
 	return 0;
 }
 
@@ -1176,10 +1184,10 @@ twl_probe(struct i2c_client *client, con
 	if ((id->driver_data) & TWL6030_CLASS) {
 		twl_priv->twl_id = TWL6030_CLASS_ID;
 		twl_priv->twl_map = &twl6030_map[0];
-		/* The charger base address is different in twl6025 */
-		if ((id->driver_data) & TWL6025_SUBCLASS)
+		/* The charger base address is different in twl6032 */
+		if ((id->driver_data) & TWL6032_SUBCLASS)
 			twl_priv->twl_map[TWL_MODULE_MAIN_CHARGE].base =
-							TWL6025_BASEADD_CHARGER;
+							TWL6032_BASEADD_CHARGER;
 		twl_regmap_config = twl6030_regmap_config;
 	} else {
 		twl_priv->twl_id = TWL4030_CLASS_ID;
@@ -1234,10 +1242,6 @@ twl_probe(struct i2c_client *client, con
 		WARN(status < 0, "Error: reading twl_idcode register value\n");
 	}
 
-	/* load power event scripts */
-	if (IS_ENABLED(CONFIG_TWL4030_POWER) && pdata && pdata->power)
-		twl4030_power_init(pdata->power);
-
 	/* Maybe init the T2 Interrupt subsystem */
 	if (client->irq) {
 		if (twl_class_is_4030()) {
@@ -1292,7 +1296,7 @@ static const struct i2c_device_id twl_id
 	{ "tps65921", TPS_SUBSET },	/* fewer LDOs; no codec, no LED
 					   and vibrator. Charger in USB module*/
 	{ "twl6030", TWL6030_CLASS },	/* "Phoenix power chip" */
-	{ "twl6025", TWL6030_CLASS | TWL6025_SUBCLASS }, /* "Phoenix lite" */
+	{ "twl6032", TWL6030_CLASS | TWL6032_SUBCLASS }, /* "Phoenix lite" */
 	{ /* end of list */ },
 };
 MODULE_DEVICE_TABLE(i2c, twl_ids);
@@ -1305,17 +1309,7 @@ static struct i2c_driver twl_driver = {
 	.remove		= twl_remove,
 };
 
-static int __init twl_init(void)
-{
-	return i2c_add_driver(&twl_driver);
-}
-subsys_initcall(twl_init);
-
-static void __exit twl_exit(void)
-{
-	i2c_del_driver(&twl_driver);
-}
-module_exit(twl_exit);
+module_i2c_driver(twl_driver);
 
 MODULE_AUTHOR("Texas Instruments, Inc.");
 MODULE_DESCRIPTION("I2C Core interface for TWL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/vexpress-sysreg.c linux-libre-3.11-rc7-gnu/drivers/mfd/vexpress-sysreg.c
--- linux-libre-3.10-gnu/drivers/mfd/vexpress-sysreg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/vexpress-sysreg.c	2013-08-25 20:43:22.000000000 -0400
@@ -351,6 +351,8 @@ void __init vexpress_sysreg_of_early_ini
 }
 
 
+#ifdef CONFIG_GPIOLIB
+
 #define VEXPRESS_SYSREG_GPIO(_name, _reg, _value) \
 	[VEXPRESS_GPIO_##_name] = { \
 		.reg = _reg, \
@@ -445,6 +447,8 @@ struct gpio_led_platform_data vexpress_s
 	.leds = vexpress_sysreg_leds,
 };
 
+#endif
+
 
 static ssize_t vexpress_sysreg_sys_id_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
@@ -480,6 +484,9 @@ static int vexpress_sysreg_probe(struct
 	setup_timer(&vexpress_sysreg_config_timer,
 			vexpress_sysreg_config_complete, 0);
 
+	vexpress_sysreg_dev = &pdev->dev;
+
+#ifdef CONFIG_GPIOLIB
 	vexpress_sysreg_gpio_chip.dev = &pdev->dev;
 	err = gpiochip_add(&vexpress_sysreg_gpio_chip);
 	if (err) {
@@ -490,11 +497,10 @@ static int vexpress_sysreg_probe(struct
 		return err;
 	}
 
-	vexpress_sysreg_dev = &pdev->dev;
-
 	platform_device_register_data(vexpress_sysreg_dev, "leds-gpio",
 			PLATFORM_DEVID_AUTO, &vexpress_sysreg_leds_pdata,
 			sizeof(vexpress_sysreg_leds_pdata));
+#endif
 
 	device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/wm5102-tables.c linux-libre-3.11-rc7-gnu/drivers/mfd/wm5102-tables.c
--- linux-libre-3.10-gnu/drivers/mfd/wm5102-tables.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/wm5102-tables.c	2013-08-25 20:43:22.000000000 -0400
@@ -65,7 +65,8 @@ static const struct reg_default wm5102_r
 	{ 0x418, 0xa080 },
 	{ 0x420, 0xa080 },
 	{ 0x428, 0xe000 },
-	{ 0x443, 0xDC1A },
+	{ 0x442, 0x3F0A },
+	{ 0x443, 0xDC1F },
 	{ 0x4B0, 0x0066 },
 	{ 0x458, 0x000b },
 	{ 0x212, 0x0000 },
@@ -424,6 +425,9 @@ static const struct reg_default wm5102_r
 	{ 0x00000435, 0x0180 },   /* R1077  - DAC Digital Volume 5R */ 
 	{ 0x00000436, 0x0081 },   /* R1078  - DAC Volume Limit 5R */
 	{ 0x00000437, 0x0200 },   /* R1079  - Noise Gate Select 5R */
+	{ 0x00000440, 0x8FFF },   /* R1088  - DRE Enable */
+	{ 0x00000442, 0x3F0A },   /* R1090  - DRE Control 2 */
+	{ 0x00000443, 0xDC1F },   /* R1090  - DRE Control 3 */
 	{ 0x00000450, 0x0000 },   /* R1104  - DAC AEC Control 1 */ 
 	{ 0x00000458, 0x000B },   /* R1112  - Noise Gate Control */
 	{ 0x00000490, 0x0069 },   /* R1168  - PDM SPK1 CTRL 1 */ 
@@ -1197,6 +1201,9 @@ static bool wm5102_readable_register(str
 	case ARIZONA_DAC_DIGITAL_VOLUME_5R:
 	case ARIZONA_DAC_VOLUME_LIMIT_5R:
 	case ARIZONA_NOISE_GATE_SELECT_5R:
+	case ARIZONA_DRE_ENABLE:
+	case ARIZONA_DRE_CONTROL_2:
+	case ARIZONA_DRE_CONTROL_3:
 	case ARIZONA_DAC_AEC_CONTROL_1:
 	case ARIZONA_NOISE_GATE_CONTROL:
 	case ARIZONA_PDM_SPK1_CTRL_1:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/wm5110-tables.c linux-libre-3.11-rc7-gnu/drivers/mfd/wm5110-tables.c
--- linux-libre-3.10-gnu/drivers/mfd/wm5110-tables.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/wm5110-tables.c	2013-08-25 20:43:22.000000000 -0400
@@ -2273,18 +2273,22 @@ static bool wm5110_readable_register(str
 	case ARIZONA_DSP1_CLOCKING_1:
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_2:
+	case ARIZONA_DSP1_STATUS_3:
 	case ARIZONA_DSP2_CONTROL_1:
 	case ARIZONA_DSP2_CLOCKING_1:
 	case ARIZONA_DSP2_STATUS_1:
 	case ARIZONA_DSP2_STATUS_2:
+	case ARIZONA_DSP2_STATUS_3:
 	case ARIZONA_DSP3_CONTROL_1:
 	case ARIZONA_DSP3_CLOCKING_1:
 	case ARIZONA_DSP3_STATUS_1:
 	case ARIZONA_DSP3_STATUS_2:
+	case ARIZONA_DSP3_STATUS_3:
 	case ARIZONA_DSP4_CONTROL_1:
 	case ARIZONA_DSP4_CLOCKING_1:
 	case ARIZONA_DSP4_STATUS_1:
 	case ARIZONA_DSP4_STATUS_2:
+	case ARIZONA_DSP4_STATUS_3:
 		return true;
 	default:
 		return false;
@@ -2334,12 +2338,16 @@ static bool wm5110_volatile_register(str
 	case ARIZONA_DSP1_CLOCKING_1:
 	case ARIZONA_DSP1_STATUS_1:
 	case ARIZONA_DSP1_STATUS_2:
+	case ARIZONA_DSP1_STATUS_3:
 	case ARIZONA_DSP2_STATUS_1:
 	case ARIZONA_DSP2_STATUS_2:
+	case ARIZONA_DSP2_STATUS_3:
 	case ARIZONA_DSP3_STATUS_1:
 	case ARIZONA_DSP3_STATUS_2:
+	case ARIZONA_DSP3_STATUS_3:
 	case ARIZONA_DSP4_STATUS_1:
 	case ARIZONA_DSP4_STATUS_2:
+	case ARIZONA_DSP4_STATUS_3:
 		return true;
 	default:
 		return false;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/wm8994-core.c linux-libre-3.11-rc7-gnu/drivers/mfd/wm8994-core.c
--- linux-libre-3.10-gnu/drivers/mfd/wm8994-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/wm8994-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -259,20 +259,6 @@ static int wm8994_suspend(struct device
 		break;
 	}
 
-	switch (wm8994->type) {
-	case WM1811:
-		ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
-		if (ret < 0) {
-			dev_err(dev, "Failed to read jackdet: %d\n", ret);
-		} else if (ret & WM1811_JACKDET_MODE_MASK) {
-			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
-			return 0;
-		}
-		break;
-	default:
-		break;
-	}
-
 	/* Disable LDO pulldowns while the device is suspended if we
 	 * don't know that something will be driving them. */
 	if (!wm8994->ldo_ena_always_driven)
@@ -652,6 +638,17 @@ static int wm8994_device_init(struct wm8
 		return ret;
 	}
 
+	/* Explicitly put the device into reset in case regulators
+	 * don't get disabled in order to ensure we know the device
+	 * state.
+	 */
+	ret = wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,
+			       wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));
+	if (ret != 0) {
+		dev_err(wm8994->dev, "Failed to reset device: %d\n", ret);
+		return ret;
+	}
+
 	if (regmap_patch) {
 		ret = regmap_register_patch(wm8994->regmap, regmap_patch,
 					    patch_regs);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/wm8994-irq.c linux-libre-3.11-rc7-gnu/drivers/mfd/wm8994-irq.c
--- linux-libre-3.10-gnu/drivers/mfd/wm8994-irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/wm8994-irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,12 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/mfd/core.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/regmap.h>
 
 #include <linux/mfd/wm8994/core.h>
@@ -138,6 +140,55 @@ static struct regmap_irq_chip wm8994_irq
 	.runtime_pm = true,
 };
 
+static void wm8994_edge_irq_enable(struct irq_data *data)
+{
+}
+
+static void wm8994_edge_irq_disable(struct irq_data *data)
+{
+}
+
+static struct irq_chip wm8994_edge_irq_chip = {
+	.name			= "wm8994_edge",
+	.irq_disable		= wm8994_edge_irq_disable,
+	.irq_enable		= wm8994_edge_irq_enable,
+};
+
+static irqreturn_t wm8994_edge_irq(int irq, void *data)
+{
+	struct wm8994 *wm8994 = data;
+
+	while (gpio_get_value_cansleep(wm8994->pdata.irq_gpio))
+		handle_nested_irq(irq_create_mapping(wm8994->edge_irq, 0));
+
+	return IRQ_HANDLED;
+}
+
+static int wm8994_edge_irq_map(struct irq_domain *h, unsigned int virq,
+			       irq_hw_number_t hw)
+{
+	struct wm8994 *wm8994 = h->host_data;
+
+	irq_set_chip_data(virq, wm8994);
+	irq_set_chip_and_handler(virq, &wm8994_edge_irq_chip, handle_edge_irq);
+	irq_set_nested_thread(virq, 1);
+
+	/* ARM needs us to explicitly flag the IRQ as valid
+	 * and will set them noprobe when we do so. */
+#ifdef CONFIG_ARM
+	set_irq_flags(virq, IRQF_VALID);
+#else
+	irq_set_noprobe(virq);
+#endif
+
+	return 0;
+}
+
+static struct irq_domain_ops wm8994_edge_irq_ops = {
+	.map	= wm8994_edge_irq_map,
+	.xlate	= irq_domain_xlate_twocell,
+};
+
 int wm8994_irq_init(struct wm8994 *wm8994)
 {
 	int ret;
@@ -156,10 +207,51 @@ int wm8994_irq_init(struct wm8994 *wm899
 	if (pdata->irq_flags)
 		irqflags = pdata->irq_flags;
 
-	ret = regmap_add_irq_chip(wm8994->regmap, wm8994->irq,
-				  irqflags,
-				  wm8994->irq_base, &wm8994_irq_chip,
-				  &wm8994->irq_data);
+	/* use a GPIO for edge triggered controllers */
+	if (irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+		if (gpio_to_irq(pdata->irq_gpio) != wm8994->irq) {
+			dev_warn(wm8994->dev, "IRQ %d is not GPIO %d (%d)\n",
+				 wm8994->irq, pdata->irq_gpio,
+				 gpio_to_irq(pdata->irq_gpio));
+			wm8994->irq = gpio_to_irq(pdata->irq_gpio);
+		}
+
+		ret = devm_gpio_request_one(wm8994->dev, pdata->irq_gpio,
+					    GPIOF_IN, "WM8994 IRQ");
+
+		if (ret != 0) {
+			dev_err(wm8994->dev, "Failed to get IRQ GPIO: %d\n",
+				ret);
+			return ret;
+		}
+
+		wm8994->edge_irq = irq_domain_add_linear(NULL, 1,
+							 &wm8994_edge_irq_ops,
+							 wm8994);
+
+		ret = regmap_add_irq_chip(wm8994->regmap,
+					  irq_create_mapping(wm8994->edge_irq,
+							     0),
+					  IRQF_ONESHOT,
+					  wm8994->irq_base, &wm8994_irq_chip,
+					  &wm8994->irq_data);
+		if (ret != 0) {
+			dev_err(wm8994->dev, "Failed to get IRQ: %d\n",
+				ret);
+			return ret;
+		}
+
+		ret = request_threaded_irq(wm8994->irq,
+					   NULL, wm8994_edge_irq,
+					   irqflags,
+					   "WM8994 edge", wm8994);
+	} else {
+		ret = regmap_add_irq_chip(wm8994->regmap, wm8994->irq,
+					  irqflags,
+					  wm8994->irq_base, &wm8994_irq_chip,
+					  &wm8994->irq_data);
+	}
+
 	if (ret != 0) {
 		dev_err(wm8994->dev, "Failed to register IRQ chip: %d\n", ret);
 		return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mfd/wm8997-tables.c linux-libre-3.11-rc7-gnu/drivers/mfd/wm8997-tables.c
--- linux-libre-3.10-gnu/drivers/mfd/wm8997-tables.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/mfd/wm8997-tables.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1525 @@
+/*
+ * wm8997-tables.c  --  WM8997 data tables
+ *
+ * Copyright 2012 Wolfson Microelectronics plc
+ *
+ * Author: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+
+#include <linux/mfd/arizona/core.h>
+#include <linux/mfd/arizona/registers.h>
+
+#include "arizona.h"
+
+static const struct reg_default wm8997_reva_patch[] = {
+	{ 0x80, 0x0003 },
+	{ 0x214, 0x0008 },
+	{ 0x458, 0x0000 },
+	{ 0x0081, 0xE022 },
+	{ 0x294, 0x0000 },
+	{ 0x80, 0x0000 },
+	{ 0x171, 0x0000 },
+};
+
+/* We use a function so we can use ARRAY_SIZE() */
+int wm8997_patch(struct arizona *arizona)
+{
+	switch (arizona->rev) {
+	case 0:
+		return regmap_register_patch(arizona->regmap,
+					     wm8997_reva_patch,
+					     ARRAY_SIZE(wm8997_reva_patch));
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(wm8997_patch);
+
+static const struct regmap_irq wm8997_aod_irqs[ARIZONA_NUM_IRQ] = {
+	[ARIZONA_IRQ_GP5_FALL] = { .mask = ARIZONA_GP5_FALL_EINT1 },
+	[ARIZONA_IRQ_GP5_RISE] = { .mask = ARIZONA_GP5_RISE_EINT1 },
+	[ARIZONA_IRQ_JD_FALL] = { .mask = ARIZONA_JD1_FALL_EINT1 },
+	[ARIZONA_IRQ_JD_RISE] = { .mask = ARIZONA_JD1_RISE_EINT1 },
+};
+
+const struct regmap_irq_chip wm8997_aod = {
+	.name = "wm8997 AOD",
+	.status_base = ARIZONA_AOD_IRQ1,
+	.mask_base = ARIZONA_AOD_IRQ_MASK_IRQ1,
+	.ack_base = ARIZONA_AOD_IRQ1,
+	.num_regs = 1,
+	.irqs = wm8997_aod_irqs,
+	.num_irqs = ARRAY_SIZE(wm8997_aod_irqs),
+};
+EXPORT_SYMBOL_GPL(wm8997_aod);
+
+static const struct regmap_irq wm8997_irqs[ARIZONA_NUM_IRQ] = {
+	[ARIZONA_IRQ_GP4] = { .reg_offset = 0, .mask = ARIZONA_GP4_EINT1 },
+	[ARIZONA_IRQ_GP3] = { .reg_offset = 0, .mask = ARIZONA_GP3_EINT1 },
+	[ARIZONA_IRQ_GP2] = { .reg_offset = 0, .mask = ARIZONA_GP2_EINT1 },
+	[ARIZONA_IRQ_GP1] = { .reg_offset = 0, .mask = ARIZONA_GP1_EINT1 },
+
+	[ARIZONA_IRQ_SPK_SHUTDOWN_WARN] = {
+		.reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_WARN_EINT1
+	},
+	[ARIZONA_IRQ_SPK_SHUTDOWN] = {
+		.reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_EINT1
+	},
+	[ARIZONA_IRQ_HPDET] = {
+		.reg_offset = 2, .mask = ARIZONA_HPDET_EINT1
+	},
+	[ARIZONA_IRQ_MICDET] = {
+		.reg_offset = 2, .mask = ARIZONA_MICDET_EINT1
+	},
+	[ARIZONA_IRQ_WSEQ_DONE] = {
+		.reg_offset = 2, .mask = ARIZONA_WSEQ_DONE_EINT1
+	},
+	[ARIZONA_IRQ_DRC1_SIG_DET] = {
+		.reg_offset = 2, .mask = ARIZONA_DRC1_SIG_DET_EINT1
+	},
+	[ARIZONA_IRQ_UNDERCLOCKED] = {
+		.reg_offset = 2, .mask = ARIZONA_UNDERCLOCKED_EINT1
+	},
+	[ARIZONA_IRQ_OVERCLOCKED] = {
+		.reg_offset = 2, .mask = ARIZONA_OVERCLOCKED_EINT1
+	},
+	[ARIZONA_IRQ_FLL2_LOCK] = {
+		.reg_offset = 2, .mask = ARIZONA_FLL2_LOCK_EINT1
+	},
+	[ARIZONA_IRQ_FLL1_LOCK] = {
+		.reg_offset = 2, .mask = ARIZONA_FLL1_LOCK_EINT1
+	},
+	[ARIZONA_IRQ_CLKGEN_ERR] = {
+		.reg_offset = 2, .mask = ARIZONA_CLKGEN_ERR_EINT1
+	},
+	[ARIZONA_IRQ_CLKGEN_ERR_ASYNC] = {
+		.reg_offset = 2, .mask = ARIZONA_CLKGEN_ERR_ASYNC_EINT1
+	},
+
+	[ARIZONA_IRQ_AIF2_ERR] = {
+		.reg_offset = 3, .mask = ARIZONA_AIF2_ERR_EINT1
+	},
+	[ARIZONA_IRQ_AIF1_ERR] = {
+		.reg_offset = 3, .mask = ARIZONA_AIF1_ERR_EINT1
+	},
+	[ARIZONA_IRQ_CTRLIF_ERR] = {
+		.reg_offset = 3, .mask = ARIZONA_CTRLIF_ERR_EINT1
+	},
+	[ARIZONA_IRQ_MIXER_DROPPED_SAMPLES] = {
+		.reg_offset = 3, .mask = ARIZONA_MIXER_DROPPED_SAMPLE_EINT1
+	},
+	[ARIZONA_IRQ_ASYNC_CLK_ENA_LOW] = {
+		.reg_offset = 3, .mask = ARIZONA_ASYNC_CLK_ENA_LOW_EINT1
+	},
+	[ARIZONA_IRQ_SYSCLK_ENA_LOW] = {
+		.reg_offset = 3, .mask = ARIZONA_SYSCLK_ENA_LOW_EINT1
+	},
+	[ARIZONA_IRQ_ISRC1_CFG_ERR] = {
+		.reg_offset = 3, .mask = ARIZONA_ISRC1_CFG_ERR_EINT1
+	},
+	[ARIZONA_IRQ_ISRC2_CFG_ERR] = {
+		.reg_offset = 3, .mask = ARIZONA_ISRC2_CFG_ERR_EINT1
+	},
+
+	[ARIZONA_IRQ_BOOT_DONE] = {
+		.reg_offset = 4, .mask = ARIZONA_BOOT_DONE_EINT1
+	},
+	[ARIZONA_IRQ_DCS_DAC_DONE] = {
+		.reg_offset = 4, .mask = ARIZONA_DCS_DAC_DONE_EINT1
+	},
+	[ARIZONA_IRQ_DCS_HP_DONE] = {
+		.reg_offset = 4, .mask = ARIZONA_DCS_HP_DONE_EINT1
+	},
+	[ARIZONA_IRQ_FLL2_CLOCK_OK] = {
+		.reg_offset = 4, .mask = ARIZONA_FLL2_CLOCK_OK_EINT1
+	},
+	[ARIZONA_IRQ_FLL1_CLOCK_OK] = {
+		.reg_offset = 4, .mask = ARIZONA_FLL1_CLOCK_OK_EINT1
+	},
+};
+
+const struct regmap_irq_chip wm8997_irq = {
+	.name = "wm8997 IRQ",
+	.status_base = ARIZONA_INTERRUPT_STATUS_1,
+	.mask_base = ARIZONA_INTERRUPT_STATUS_1_MASK,
+	.ack_base = ARIZONA_INTERRUPT_STATUS_1,
+	.num_regs = 5,
+	.irqs = wm8997_irqs,
+	.num_irqs = ARRAY_SIZE(wm8997_irqs),
+};
+EXPORT_SYMBOL_GPL(wm8997_irq);
+
+static const struct reg_default wm8997_reg_default[] = {
+	{ 0x00000009, 0x0001 },    /* R9     - Ctrl IF I2C1 CFG 1 */
+	{ 0x00000016, 0x0000 },    /* R22    - Write Sequencer Ctrl 0 */
+	{ 0x00000017, 0x0000 },    /* R23    - Write Sequencer Ctrl 1 */
+	{ 0x00000018, 0x0000 },    /* R24    - Write Sequencer Ctrl 2 */
+	{ 0x00000020, 0x0000 },    /* R32    - Tone Generator 1 */
+	{ 0x00000021, 0x1000 },    /* R33    - Tone Generator 2 */
+	{ 0x00000022, 0x0000 },    /* R34    - Tone Generator 3 */
+	{ 0x00000023, 0x1000 },    /* R35    - Tone Generator 4 */
+	{ 0x00000024, 0x0000 },    /* R36    - Tone Generator 5 */
+	{ 0x00000030, 0x0000 },    /* R48    - PWM Drive 1 */
+	{ 0x00000031, 0x0100 },    /* R49    - PWM Drive 2 */
+	{ 0x00000032, 0x0100 },    /* R50    - PWM Drive 3 */
+	{ 0x00000040, 0x0000 },    /* R64    - Wake control */
+	{ 0x00000041, 0x0000 },    /* R65    - Sequence control */
+	{ 0x00000061, 0x01FF },    /* R97    - Sample Rate Sequence Select 1 */
+	{ 0x00000062, 0x01FF },    /* R98    - Sample Rate Sequence Select 2 */
+	{ 0x00000063, 0x01FF },    /* R99    - Sample Rate Sequence Select 3 */
+	{ 0x00000064, 0x01FF },    /* R100   - Sample Rate Sequence Select 4 */
+	{ 0x00000068, 0x01FF },    /* R104   - Always On Triggers Sequence Select 1 */
+	{ 0x00000069, 0x01FF },    /* R105   - Always On Triggers Sequence Select 2 */
+	{ 0x0000006A, 0x01FF },    /* R106   - Always On Triggers Sequence Select 3 */
+	{ 0x0000006B, 0x01FF },    /* R107   - Always On Triggers Sequence Select 4 */
+	{ 0x00000070, 0x0000 },    /* R112   - Comfort Noise Generator */
+	{ 0x00000090, 0x0000 },    /* R144   - Haptics Control 1 */
+	{ 0x00000091, 0x7FFF },    /* R145   - Haptics Control 2 */
+	{ 0x00000092, 0x0000 },    /* R146   - Haptics phase 1 intensity */
+	{ 0x00000093, 0x0000 },    /* R147   - Haptics phase 1 duration */
+	{ 0x00000094, 0x0000 },    /* R148   - Haptics phase 2 intensity */
+	{ 0x00000095, 0x0000 },    /* R149   - Haptics phase 2 duration */
+	{ 0x00000096, 0x0000 },    /* R150   - Haptics phase 3 intensity */
+	{ 0x00000097, 0x0000 },    /* R151   - Haptics phase 3 duration */
+	{ 0x00000100, 0x0002 },    /* R256   - Clock 32k 1 */
+	{ 0x00000101, 0x0304 },    /* R257   - System Clock 1 */
+	{ 0x00000102, 0x0011 },    /* R258   - Sample rate 1 */
+	{ 0x00000103, 0x0011 },    /* R259   - Sample rate 2 */
+	{ 0x00000104, 0x0011 },    /* R260   - Sample rate 3 */
+	{ 0x00000112, 0x0305 },    /* R274   - Async clock 1 */
+	{ 0x00000113, 0x0011 },    /* R275   - Async sample rate 1 */
+	{ 0x00000149, 0x0000 },    /* R329   - Output system clock */
+	{ 0x0000014A, 0x0000 },    /* R330   - Output async clock */
+	{ 0x00000152, 0x0000 },    /* R338   - Rate Estimator 1 */
+	{ 0x00000153, 0x0000 },    /* R339   - Rate Estimator 2 */
+	{ 0x00000154, 0x0000 },    /* R340   - Rate Estimator 3 */
+	{ 0x00000155, 0x0000 },    /* R341   - Rate Estimator 4 */
+	{ 0x00000156, 0x0000 },    /* R342   - Rate Estimator 5 */
+	{ 0x00000161, 0x0000 },    /* R353   - Dynamic Frequency Scaling 1 */
+	{ 0x00000171, 0x0000 },    /* R369   - FLL1 Control 1 */
+	{ 0x00000172, 0x0008 },    /* R370   - FLL1 Control 2 */
+	{ 0x00000173, 0x0018 },    /* R371   - FLL1 Control 3 */
+	{ 0x00000174, 0x007D },    /* R372   - FLL1 Control 4 */
+	{ 0x00000175, 0x0004 },    /* R373   - FLL1 Control 5 */
+	{ 0x00000176, 0x0000 },    /* R374   - FLL1 Control 6 */
+	{ 0x00000177, 0x0181 },    /* R375   - FLL1 Loop Filter Test 1 */
+	{ 0x00000181, 0x0000 },    /* R385   - FLL1 Synchroniser 1 */
+	{ 0x00000182, 0x0000 },    /* R386   - FLL1 Synchroniser 2 */
+	{ 0x00000183, 0x0000 },    /* R387   - FLL1 Synchroniser 3 */
+	{ 0x00000184, 0x0000 },    /* R388   - FLL1 Synchroniser 4 */
+	{ 0x00000185, 0x0000 },    /* R389   - FLL1 Synchroniser 5 */
+	{ 0x00000186, 0x0000 },    /* R390   - FLL1 Synchroniser 6 */
+	{ 0x00000189, 0x0000 },    /* R393   - FLL1 Spread Spectrum */
+	{ 0x0000018A, 0x0004 },    /* R394   - FLL1 GPIO Clock */
+	{ 0x00000191, 0x0000 },    /* R401   - FLL2 Control 1 */
+	{ 0x00000192, 0x0008 },    /* R402   - FLL2 Control 2 */
+	{ 0x00000193, 0x0018 },    /* R403   - FLL2 Control 3 */
+	{ 0x00000194, 0x007D },    /* R404   - FLL2 Control 4 */
+	{ 0x00000195, 0x0004 },    /* R405   - FLL2 Control 5 */
+	{ 0x00000196, 0x0000 },    /* R406   - FLL2 Control 6 */
+	{ 0x00000197, 0x0000 },    /* R407   - FLL2 Loop Filter Test 1 */
+	{ 0x000001A1, 0x0000 },    /* R417   - FLL2 Synchroniser 1 */
+	{ 0x000001A2, 0x0000 },    /* R418   - FLL2 Synchroniser 2 */
+	{ 0x000001A3, 0x0000 },    /* R419   - FLL2 Synchroniser 3 */
+	{ 0x000001A4, 0x0000 },    /* R420   - FLL2 Synchroniser 4 */
+	{ 0x000001A5, 0x0000 },    /* R421   - FLL2 Synchroniser 5 */
+	{ 0x000001A6, 0x0000 },    /* R422   - FLL2 Synchroniser 6 */
+	{ 0x000001A9, 0x0000 },    /* R425   - FLL2 Spread Spectrum */
+	{ 0x000001AA, 0x0004 },    /* R426   - FLL2 GPIO Clock */
+	{ 0x00000200, 0x0006 },    /* R512   - Mic Charge Pump 1 */
+	{ 0x00000210, 0x00D4 },    /* R528   - LDO1 Control 1 */
+	{ 0x00000212, 0x0000 },    /* R530   - LDO1 Control 2 */
+	{ 0x00000213, 0x0344 },    /* R531   - LDO2 Control 1 */
+	{ 0x00000218, 0x01A6 },    /* R536   - Mic Bias Ctrl 1 */
+	{ 0x00000219, 0x01A6 },    /* R537   - Mic Bias Ctrl 2 */
+	{ 0x0000021A, 0x01A6 },    /* R538   - Mic Bias Ctrl 3 */
+	{ 0x00000293, 0x0000 },    /* R659   - Accessory Detect Mode 1 */
+	{ 0x0000029B, 0x0020 },    /* R667   - Headphone Detect 1 */
+	{ 0x000002A3, 0x1102 },    /* R675   - Mic Detect 1 */
+	{ 0x000002A4, 0x009F },    /* R676   - Mic Detect 2 */
+	{ 0x000002A5, 0x0000 },    /* R677   - Mic Detect 3 */
+	{ 0x000002C3, 0x0000 },    /* R707   - Mic noise mix control 1 */
+	{ 0x000002CB, 0x0000 },    /* R715   - Isolation control */
+	{ 0x000002D3, 0x0000 },    /* R723   - Jack detect analogue */
+	{ 0x00000300, 0x0000 },    /* R768   - Input Enables */
+	{ 0x00000308, 0x0000 },    /* R776   - Input Rate */
+	{ 0x00000309, 0x0022 },    /* R777   - Input Volume Ramp */
+	{ 0x00000310, 0x2080 },    /* R784   - IN1L Control */
+	{ 0x00000311, 0x0180 },    /* R785   - ADC Digital Volume 1L */
+	{ 0x00000312, 0x0000 },    /* R786   - DMIC1L Control */
+	{ 0x00000314, 0x0080 },    /* R788   - IN1R Control */
+	{ 0x00000315, 0x0180 },    /* R789   - ADC Digital Volume 1R */
+	{ 0x00000316, 0x0000 },    /* R790   - DMIC1R Control */
+	{ 0x00000318, 0x2080 },    /* R792   - IN2L Control */
+	{ 0x00000319, 0x0180 },    /* R793   - ADC Digital Volume 2L */
+	{ 0x0000031A, 0x0000 },    /* R794   - DMIC2L Control */
+	{ 0x0000031C, 0x0080 },    /* R796   - IN2R Control */
+	{ 0x0000031D, 0x0180 },    /* R797   - ADC Digital Volume 2R */
+	{ 0x0000031E, 0x0000 },    /* R798   - DMIC2R Control */
+	{ 0x00000400, 0x0000 },    /* R1024  - Output Enables 1 */
+	{ 0x00000408, 0x0000 },    /* R1032  - Output Rate 1 */
+	{ 0x00000409, 0x0022 },    /* R1033  - Output Volume Ramp */
+	{ 0x00000410, 0x0080 },    /* R1040  - Output Path Config 1L */
+	{ 0x00000411, 0x0180 },    /* R1041  - DAC Digital Volume 1L */
+	{ 0x00000412, 0x0080 },    /* R1042  - DAC Volume Limit 1L */
+	{ 0x00000413, 0x0001 },    /* R1043  - Noise Gate Select 1L */
+	{ 0x00000414, 0x0080 },    /* R1044  - Output Path Config 1R */
+	{ 0x00000415, 0x0180 },    /* R1045  - DAC Digital Volume 1R */
+	{ 0x00000416, 0x0080 },    /* R1046  - DAC Volume Limit 1R */
+	{ 0x00000417, 0x0002 },    /* R1047  - Noise Gate Select 1R */
+	{ 0x00000420, 0x0080 },    /* R1056  - Output Path Config 3L */
+	{ 0x00000421, 0x0180 },    /* R1057  - DAC Digital Volume 3L */
+	{ 0x00000422, 0x0080 },    /* R1058  - DAC Volume Limit 3L */
+	{ 0x00000423, 0x0010 },    /* R1059  - Noise Gate Select 3L */
+	{ 0x00000428, 0x0000 },    /* R1064  - Output Path Config 4L */
+	{ 0x00000429, 0x0180 },    /* R1065  - DAC Digital Volume 4L */
+	{ 0x0000042A, 0x0080 },    /* R1066  - Out Volume 4L */
+	{ 0x0000042B, 0x0040 },    /* R1067  - Noise Gate Select 4L */
+	{ 0x00000430, 0x0000 },    /* R1072  - Output Path Config 5L */
+	{ 0x00000431, 0x0180 },    /* R1073  - DAC Digital Volume 5L */
+	{ 0x00000432, 0x0080 },    /* R1074  - DAC Volume Limit 5L */
+	{ 0x00000433, 0x0100 },    /* R1075  - Noise Gate Select 5L */
+	{ 0x00000435, 0x0180 },    /* R1077  - DAC Digital Volume 5R */
+	{ 0x00000436, 0x0080 },    /* R1078  - DAC Volume Limit 5R */
+	{ 0x00000437, 0x0200 },    /* R1079  - Noise Gate Select 5R */
+	{ 0x00000450, 0x0000 },    /* R1104  - DAC AEC Control 1 */
+	{ 0x00000458, 0x0000 },    /* R1112  - Noise Gate Control */
+	{ 0x00000490, 0x0069 },    /* R1168  - PDM SPK1 CTRL 1 */
+	{ 0x00000491, 0x0000 },    /* R1169  - PDM SPK1 CTRL 2 */
+	{ 0x00000500, 0x000C },    /* R1280  - AIF1 BCLK Ctrl */
+	{ 0x00000501, 0x0008 },    /* R1281  - AIF1 Tx Pin Ctrl */
+	{ 0x00000502, 0x0000 },    /* R1282  - AIF1 Rx Pin Ctrl */
+	{ 0x00000503, 0x0000 },    /* R1283  - AIF1 Rate Ctrl */
+	{ 0x00000504, 0x0000 },    /* R1284  - AIF1 Format */
+	{ 0x00000505, 0x0040 },    /* R1285  - AIF1 Tx BCLK Rate */
+	{ 0x00000506, 0x0040 },    /* R1286  - AIF1 Rx BCLK Rate */
+	{ 0x00000507, 0x1818 },    /* R1287  - AIF1 Frame Ctrl 1 */
+	{ 0x00000508, 0x1818 },    /* R1288  - AIF1 Frame Ctrl 2 */
+	{ 0x00000509, 0x0000 },    /* R1289  - AIF1 Frame Ctrl 3 */
+	{ 0x0000050A, 0x0001 },    /* R1290  - AIF1 Frame Ctrl 4 */
+	{ 0x0000050B, 0x0002 },    /* R1291  - AIF1 Frame Ctrl 5 */
+	{ 0x0000050C, 0x0003 },    /* R1292  - AIF1 Frame Ctrl 6 */
+	{ 0x0000050D, 0x0004 },    /* R1293  - AIF1 Frame Ctrl 7 */
+	{ 0x0000050E, 0x0005 },    /* R1294  - AIF1 Frame Ctrl 8 */
+	{ 0x0000050F, 0x0006 },    /* R1295  - AIF1 Frame Ctrl 9 */
+	{ 0x00000510, 0x0007 },    /* R1296  - AIF1 Frame Ctrl 10 */
+	{ 0x00000511, 0x0000 },    /* R1297  - AIF1 Frame Ctrl 11 */
+	{ 0x00000512, 0x0001 },    /* R1298  - AIF1 Frame Ctrl 12 */
+	{ 0x00000513, 0x0002 },    /* R1299  - AIF1 Frame Ctrl 13 */
+	{ 0x00000514, 0x0003 },    /* R1300  - AIF1 Frame Ctrl 14 */
+	{ 0x00000515, 0x0004 },    /* R1301  - AIF1 Frame Ctrl 15 */
+	{ 0x00000516, 0x0005 },    /* R1302  - AIF1 Frame Ctrl 16 */
+	{ 0x00000517, 0x0006 },    /* R1303  - AIF1 Frame Ctrl 17 */
+	{ 0x00000518, 0x0007 },    /* R1304  - AIF1 Frame Ctrl 18 */
+	{ 0x00000519, 0x0000 },    /* R1305  - AIF1 Tx Enables */
+	{ 0x0000051A, 0x0000 },    /* R1306  - AIF1 Rx Enables */
+	{ 0x00000540, 0x000C },    /* R1344  - AIF2 BCLK Ctrl */
+	{ 0x00000541, 0x0008 },    /* R1345  - AIF2 Tx Pin Ctrl */
+	{ 0x00000542, 0x0000 },    /* R1346  - AIF2 Rx Pin Ctrl */
+	{ 0x00000543, 0x0000 },    /* R1347  - AIF2 Rate Ctrl */
+	{ 0x00000544, 0x0000 },    /* R1348  - AIF2 Format */
+	{ 0x00000545, 0x0040 },    /* R1349  - AIF2 Tx BCLK Rate */
+	{ 0x00000546, 0x0040 },    /* R1350  - AIF2 Rx BCLK Rate */
+	{ 0x00000547, 0x1818 },    /* R1351  - AIF2 Frame Ctrl 1 */
+	{ 0x00000548, 0x1818 },    /* R1352  - AIF2 Frame Ctrl 2 */
+	{ 0x00000549, 0x0000 },    /* R1353  - AIF2 Frame Ctrl 3 */
+	{ 0x0000054A, 0x0001 },    /* R1354  - AIF2 Frame Ctrl 4 */
+	{ 0x00000551, 0x0000 },    /* R1361  - AIF2 Frame Ctrl 11 */
+	{ 0x00000552, 0x0001 },    /* R1362  - AIF2 Frame Ctrl 12 */
+	{ 0x00000559, 0x0000 },    /* R1369  - AIF2 Tx Enables */
+	{ 0x0000055A, 0x0000 },    /* R1370  - AIF2 Rx Enables */
+	{ 0x000005E3, 0x0004 },    /* R1507  - SLIMbus Framer Ref Gear */
+	{ 0x000005E5, 0x0000 },    /* R1509  - SLIMbus Rates 1 */
+	{ 0x000005E6, 0x0000 },    /* R1510  - SLIMbus Rates 2 */
+	{ 0x000005E7, 0x0000 },    /* R1511  - SLIMbus Rates 3 */
+	{ 0x000005E8, 0x0000 },    /* R1512  - SLIMbus Rates 4 */
+	{ 0x000005E9, 0x0000 },    /* R1513  - SLIMbus Rates 5 */
+	{ 0x000005EA, 0x0000 },    /* R1514  - SLIMbus Rates 6 */
+	{ 0x000005EB, 0x0000 },    /* R1515  - SLIMbus Rates 7 */
+	{ 0x000005EC, 0x0000 },    /* R1516  - SLIMbus Rates 8 */
+	{ 0x000005F5, 0x0000 },    /* R1525  - SLIMbus RX Channel Enable */
+	{ 0x000005F6, 0x0000 },    /* R1526  - SLIMbus TX Channel Enable */
+	{ 0x00000640, 0x0000 },    /* R1600  - PWM1MIX Input 1 Source */
+	{ 0x00000641, 0x0080 },    /* R1601  - PWM1MIX Input 1 Volume */
+	{ 0x00000642, 0x0000 },    /* R1602  - PWM1MIX Input 2 Source */
+	{ 0x00000643, 0x0080 },    /* R1603  - PWM1MIX Input 2 Volume */
+	{ 0x00000644, 0x0000 },    /* R1604  - PWM1MIX Input 3 Source */
+	{ 0x00000645, 0x0080 },    /* R1605  - PWM1MIX Input 3 Volume */
+	{ 0x00000646, 0x0000 },    /* R1606  - PWM1MIX Input 4 Source */
+	{ 0x00000647, 0x0080 },    /* R1607  - PWM1MIX Input 4 Volume */
+	{ 0x00000648, 0x0000 },    /* R1608  - PWM2MIX Input 1 Source */
+	{ 0x00000649, 0x0080 },    /* R1609  - PWM2MIX Input 1 Volume */
+	{ 0x0000064A, 0x0000 },    /* R1610  - PWM2MIX Input 2 Source */
+	{ 0x0000064B, 0x0080 },    /* R1611  - PWM2MIX Input 2 Volume */
+	{ 0x0000064C, 0x0000 },    /* R1612  - PWM2MIX Input 3 Source */
+	{ 0x0000064D, 0x0080 },    /* R1613  - PWM2MIX Input 3 Volume */
+	{ 0x0000064E, 0x0000 },    /* R1614  - PWM2MIX Input 4 Source */
+	{ 0x0000064F, 0x0080 },    /* R1615  - PWM2MIX Input 4 Volume */
+	{ 0x00000660, 0x0000 },    /* R1632  - MICMIX Input 1 Source */
+	{ 0x00000661, 0x0080 },    /* R1633  - MICMIX Input 1 Volume */
+	{ 0x00000662, 0x0000 },    /* R1634  - MICMIX Input 2 Source */
+	{ 0x00000663, 0x0080 },    /* R1635  - MICMIX Input 2 Volume */
+	{ 0x00000664, 0x0000 },    /* R1636  - MICMIX Input 3 Source */
+	{ 0x00000665, 0x0080 },    /* R1637  - MICMIX Input 3 Volume */
+	{ 0x00000666, 0x0000 },    /* R1638  - MICMIX Input 4 Source */
+	{ 0x00000667, 0x0080 },    /* R1639  - MICMIX Input 4 Volume */
+	{ 0x00000668, 0x0000 },    /* R1640  - NOISEMIX Input 1 Source */
+	{ 0x00000669, 0x0080 },    /* R1641  - NOISEMIX Input 1 Volume */
+	{ 0x0000066A, 0x0000 },    /* R1642  - NOISEMIX Input 2 Source */
+	{ 0x0000066B, 0x0080 },    /* R1643  - NOISEMIX Input 2 Volume */
+	{ 0x0000066C, 0x0000 },    /* R1644  - NOISEMIX Input 3 Source */
+	{ 0x0000066D, 0x0080 },    /* R1645  - NOISEMIX Input 3 Volume */
+	{ 0x0000066E, 0x0000 },    /* R1646  - NOISEMIX Input 4 Source */
+	{ 0x0000066F, 0x0080 },    /* R1647  - NOISEMIX Input 4 Volume */
+	{ 0x00000680, 0x0000 },    /* R1664  - OUT1LMIX Input 1 Source */
+	{ 0x00000681, 0x0080 },    /* R1665  - OUT1LMIX Input 1 Volume */
+	{ 0x00000682, 0x0000 },    /* R1666  - OUT1LMIX Input 2 Source */
+	{ 0x00000683, 0x0080 },    /* R1667  - OUT1LMIX Input 2 Volume */
+	{ 0x00000684, 0x0000 },    /* R1668  - OUT1LMIX Input 3 Source */
+	{ 0x00000685, 0x0080 },    /* R1669  - OUT1LMIX Input 3 Volume */
+	{ 0x00000686, 0x0000 },    /* R1670  - OUT1LMIX Input 4 Source */
+	{ 0x00000687, 0x0080 },    /* R1671  - OUT1LMIX Input 4 Volume */
+	{ 0x00000688, 0x0000 },    /* R1672  - OUT1RMIX Input 1 Source */
+	{ 0x00000689, 0x0080 },    /* R1673  - OUT1RMIX Input 1 Volume */
+	{ 0x0000068A, 0x0000 },    /* R1674  - OUT1RMIX Input 2 Source */
+	{ 0x0000068B, 0x0080 },    /* R1675  - OUT1RMIX Input 2 Volume */
+	{ 0x0000068C, 0x0000 },    /* R1676  - OUT1RMIX Input 3 Source */
+	{ 0x0000068D, 0x0080 },    /* R1677  - OUT1RMIX Input 3 Volume */
+	{ 0x0000068E, 0x0000 },    /* R1678  - OUT1RMIX Input 4 Source */
+	{ 0x0000068F, 0x0080 },    /* R1679  - OUT1RMIX Input 4 Volume */
+	{ 0x000006A0, 0x0000 },    /* R1696  - OUT3LMIX Input 1 Source */
+	{ 0x000006A1, 0x0080 },    /* R1697  - OUT3LMIX Input 1 Volume */
+	{ 0x000006A2, 0x0000 },    /* R1698  - OUT3LMIX Input 2 Source */
+	{ 0x000006A3, 0x0080 },    /* R1699  - OUT3LMIX Input 2 Volume */
+	{ 0x000006A4, 0x0000 },    /* R1700  - OUT3LMIX Input 3 Source */
+	{ 0x000006A5, 0x0080 },    /* R1701  - OUT3LMIX Input 3 Volume */
+	{ 0x000006A6, 0x0000 },    /* R1702  - OUT3LMIX Input 4 Source */
+	{ 0x000006A7, 0x0080 },    /* R1703  - OUT3LMIX Input 4 Volume */
+	{ 0x000006B0, 0x0000 },    /* R1712  - OUT4LMIX Input 1 Source */
+	{ 0x000006B1, 0x0080 },    /* R1713  - OUT4LMIX Input 1 Volume */
+	{ 0x000006B2, 0x0000 },    /* R1714  - OUT4LMIX Input 2 Source */
+	{ 0x000006B3, 0x0080 },    /* R1715  - OUT4LMIX Input 2 Volume */
+	{ 0x000006B4, 0x0000 },    /* R1716  - OUT4LMIX Input 3 Source */
+	{ 0x000006B5, 0x0080 },    /* R1717  - OUT4LMIX Input 3 Volume */
+	{ 0x000006B6, 0x0000 },    /* R1718  - OUT4LMIX Input 4 Source */
+	{ 0x000006B7, 0x0080 },    /* R1719  - OUT4LMIX Input 4 Volume */
+	{ 0x000006C0, 0x0000 },    /* R1728  - OUT5LMIX Input 1 Source */
+	{ 0x000006C1, 0x0080 },    /* R1729  - OUT5LMIX Input 1 Volume */
+	{ 0x000006C2, 0x0000 },    /* R1730  - OUT5LMIX Input 2 Source */
+	{ 0x000006C3, 0x0080 },    /* R1731  - OUT5LMIX Input 2 Volume */
+	{ 0x000006C4, 0x0000 },    /* R1732  - OUT5LMIX Input 3 Source */
+	{ 0x000006C5, 0x0080 },    /* R1733  - OUT5LMIX Input 3 Volume */
+	{ 0x000006C6, 0x0000 },    /* R1734  - OUT5LMIX Input 4 Source */
+	{ 0x000006C7, 0x0080 },    /* R1735  - OUT5LMIX Input 4 Volume */
+	{ 0x000006C8, 0x0000 },    /* R1736  - OUT5RMIX Input 1 Source */
+	{ 0x000006C9, 0x0080 },    /* R1737  - OUT5RMIX Input 1 Volume */
+	{ 0x000006CA, 0x0000 },    /* R1738  - OUT5RMIX Input 2 Source */
+	{ 0x000006CB, 0x0080 },    /* R1739  - OUT5RMIX Input 2 Volume */
+	{ 0x000006CC, 0x0000 },    /* R1740  - OUT5RMIX Input 3 Source */
+	{ 0x000006CD, 0x0080 },    /* R1741  - OUT5RMIX Input 3 Volume */
+	{ 0x000006CE, 0x0000 },    /* R1742  - OUT5RMIX Input 4 Source */
+	{ 0x000006CF, 0x0080 },    /* R1743  - OUT5RMIX Input 4 Volume */
+	{ 0x00000700, 0x0000 },    /* R1792  - AIF1TX1MIX Input 1 Source */
+	{ 0x00000701, 0x0080 },    /* R1793  - AIF1TX1MIX Input 1 Volume */
+	{ 0x00000702, 0x0000 },    /* R1794  - AIF1TX1MIX Input 2 Source */
+	{ 0x00000703, 0x0080 },    /* R1795  - AIF1TX1MIX Input 2 Volume */
+	{ 0x00000704, 0x0000 },    /* R1796  - AIF1TX1MIX Input 3 Source */
+	{ 0x00000705, 0x0080 },    /* R1797  - AIF1TX1MIX Input 3 Volume */
+	{ 0x00000706, 0x0000 },    /* R1798  - AIF1TX1MIX Input 4 Source */
+	{ 0x00000707, 0x0080 },    /* R1799  - AIF1TX1MIX Input 4 Volume */
+	{ 0x00000708, 0x0000 },    /* R1800  - AIF1TX2MIX Input 1 Source */
+	{ 0x00000709, 0x0080 },    /* R1801  - AIF1TX2MIX Input 1 Volume */
+	{ 0x0000070A, 0x0000 },    /* R1802  - AIF1TX2MIX Input 2 Source */
+	{ 0x0000070B, 0x0080 },    /* R1803  - AIF1TX2MIX Input 2 Volume */
+	{ 0x0000070C, 0x0000 },    /* R1804  - AIF1TX2MIX Input 3 Source */
+	{ 0x0000070D, 0x0080 },    /* R1805  - AIF1TX2MIX Input 3 Volume */
+	{ 0x0000070E, 0x0000 },    /* R1806  - AIF1TX2MIX Input 4 Source */
+	{ 0x0000070F, 0x0080 },    /* R1807  - AIF1TX2MIX Input 4 Volume */
+	{ 0x00000710, 0x0000 },    /* R1808  - AIF1TX3MIX Input 1 Source */
+	{ 0x00000711, 0x0080 },    /* R1809  - AIF1TX3MIX Input 1 Volume */
+	{ 0x00000712, 0x0000 },    /* R1810  - AIF1TX3MIX Input 2 Source */
+	{ 0x00000713, 0x0080 },    /* R1811  - AIF1TX3MIX Input 2 Volume */
+	{ 0x00000714, 0x0000 },    /* R1812  - AIF1TX3MIX Input 3 Source */
+	{ 0x00000715, 0x0080 },    /* R1813  - AIF1TX3MIX Input 3 Volume */
+	{ 0x00000716, 0x0000 },    /* R1814  - AIF1TX3MIX Input 4 Source */
+	{ 0x00000717, 0x0080 },    /* R1815  - AIF1TX3MIX Input 4 Volume */
+	{ 0x00000718, 0x0000 },    /* R1816  - AIF1TX4MIX Input 1 Source */
+	{ 0x00000719, 0x0080 },    /* R1817  - AIF1TX4MIX Input 1 Volume */
+	{ 0x0000071A, 0x0000 },    /* R1818  - AIF1TX4MIX Input 2 Source */
+	{ 0x0000071B, 0x0080 },    /* R1819  - AIF1TX4MIX Input 2 Volume */
+	{ 0x0000071C, 0x0000 },    /* R1820  - AIF1TX4MIX Input 3 Source */
+	{ 0x0000071D, 0x0080 },    /* R1821  - AIF1TX4MIX Input 3 Volume */
+	{ 0x0000071E, 0x0000 },    /* R1822  - AIF1TX4MIX Input 4 Source */
+	{ 0x0000071F, 0x0080 },    /* R1823  - AIF1TX4MIX Input 4 Volume */
+	{ 0x00000720, 0x0000 },    /* R1824  - AIF1TX5MIX Input 1 Source */
+	{ 0x00000721, 0x0080 },    /* R1825  - AIF1TX5MIX Input 1 Volume */
+	{ 0x00000722, 0x0000 },    /* R1826  - AIF1TX5MIX Input 2 Source */
+	{ 0x00000723, 0x0080 },    /* R1827  - AIF1TX5MIX Input 2 Volume */
+	{ 0x00000724, 0x0000 },    /* R1828  - AIF1TX5MIX Input 3 Source */
+	{ 0x00000725, 0x0080 },    /* R1829  - AIF1TX5MIX Input 3 Volume */
+	{ 0x00000726, 0x0000 },    /* R1830  - AIF1TX5MIX Input 4 Source */
+	{ 0x00000727, 0x0080 },    /* R1831  - AIF1TX5MIX Input 4 Volume */
+	{ 0x00000728, 0x0000 },    /* R1832  - AIF1TX6MIX Input 1 Source */
+	{ 0x00000729, 0x0080 },    /* R1833  - AIF1TX6MIX Input 1 Volume */
+	{ 0x0000072A, 0x0000 },    /* R1834  - AIF1TX6MIX Input 2 Source */
+	{ 0x0000072B, 0x0080 },    /* R1835  - AIF1TX6MIX Input 2 Volume */
+	{ 0x0000072C, 0x0000 },    /* R1836  - AIF1TX6MIX Input 3 Source */
+	{ 0x0000072D, 0x0080 },    /* R1837  - AIF1TX6MIX Input 3 Volume */
+	{ 0x0000072E, 0x0000 },    /* R1838  - AIF1TX6MIX Input 4 Source */
+	{ 0x0000072F, 0x0080 },    /* R1839  - AIF1TX6MIX Input 4 Volume */
+	{ 0x00000730, 0x0000 },    /* R1840  - AIF1TX7MIX Input 1 Source */
+	{ 0x00000731, 0x0080 },    /* R1841  - AIF1TX7MIX Input 1 Volume */
+	{ 0x00000732, 0x0000 },    /* R1842  - AIF1TX7MIX Input 2 Source */
+	{ 0x00000733, 0x0080 },    /* R1843  - AIF1TX7MIX Input 2 Volume */
+	{ 0x00000734, 0x0000 },    /* R1844  - AIF1TX7MIX Input 3 Source */
+	{ 0x00000735, 0x0080 },    /* R1845  - AIF1TX7MIX Input 3 Volume */
+	{ 0x00000736, 0x0000 },    /* R1846  - AIF1TX7MIX Input 4 Source */
+	{ 0x00000737, 0x0080 },    /* R1847  - AIF1TX7MIX Input 4 Volume */
+	{ 0x00000738, 0x0000 },    /* R1848  - AIF1TX8MIX Input 1 Source */
+	{ 0x00000739, 0x0080 },    /* R1849  - AIF1TX8MIX Input 1 Volume */
+	{ 0x0000073A, 0x0000 },    /* R1850  - AIF1TX8MIX Input 2 Source */
+	{ 0x0000073B, 0x0080 },    /* R1851  - AIF1TX8MIX Input 2 Volume */
+	{ 0x0000073C, 0x0000 },    /* R1852  - AIF1TX8MIX Input 3 Source */
+	{ 0x0000073D, 0x0080 },    /* R1853  - AIF1TX8MIX Input 3 Volume */
+	{ 0x0000073E, 0x0000 },    /* R1854  - AIF1TX8MIX Input 4 Source */
+	{ 0x0000073F, 0x0080 },    /* R1855  - AIF1TX8MIX Input 4 Volume */
+	{ 0x00000740, 0x0000 },    /* R1856  - AIF2TX1MIX Input 1 Source */
+	{ 0x00000741, 0x0080 },    /* R1857  - AIF2TX1MIX Input 1 Volume */
+	{ 0x00000742, 0x0000 },    /* R1858  - AIF2TX1MIX Input 2 Source */
+	{ 0x00000743, 0x0080 },    /* R1859  - AIF2TX1MIX Input 2 Volume */
+	{ 0x00000744, 0x0000 },    /* R1860  - AIF2TX1MIX Input 3 Source */
+	{ 0x00000745, 0x0080 },    /* R1861  - AIF2TX1MIX Input 3 Volume */
+	{ 0x00000746, 0x0000 },    /* R1862  - AIF2TX1MIX Input 4 Source */
+	{ 0x00000747, 0x0080 },    /* R1863  - AIF2TX1MIX Input 4 Volume */
+	{ 0x00000748, 0x0000 },    /* R1864  - AIF2TX2MIX Input 1 Source */
+	{ 0x00000749, 0x0080 },    /* R1865  - AIF2TX2MIX Input 1 Volume */
+	{ 0x0000074A, 0x0000 },    /* R1866  - AIF2TX2MIX Input 2 Source */
+	{ 0x0000074B, 0x0080 },    /* R1867  - AIF2TX2MIX Input 2 Volume */
+	{ 0x0000074C, 0x0000 },    /* R1868  - AIF2TX2MIX Input 3 Source */
+	{ 0x0000074D, 0x0080 },    /* R1869  - AIF2TX2MIX Input 3 Volume */
+	{ 0x0000074E, 0x0000 },    /* R1870  - AIF2TX2MIX Input 4 Source */
+	{ 0x0000074F, 0x0080 },    /* R1871  - AIF2TX2MIX Input 4 Volume */
+	{ 0x000007C0, 0x0000 },    /* R1984  - SLIMTX1MIX Input 1 Source */
+	{ 0x000007C1, 0x0080 },    /* R1985  - SLIMTX1MIX Input 1 Volume */
+	{ 0x000007C2, 0x0000 },    /* R1986  - SLIMTX1MIX Input 2 Source */
+	{ 0x000007C3, 0x0080 },    /* R1987  - SLIMTX1MIX Input 2 Volume */
+	{ 0x000007C4, 0x0000 },    /* R1988  - SLIMTX1MIX Input 3 Source */
+	{ 0x000007C5, 0x0080 },    /* R1989  - SLIMTX1MIX Input 3 Volume */
+	{ 0x000007C6, 0x0000 },    /* R1990  - SLIMTX1MIX Input 4 Source */
+	{ 0x000007C7, 0x0080 },    /* R1991  - SLIMTX1MIX Input 4 Volume */
+	{ 0x000007C8, 0x0000 },    /* R1992  - SLIMTX2MIX Input 1 Source */
+	{ 0x000007C9, 0x0080 },    /* R1993  - SLIMTX2MIX Input 1 Volume */
+	{ 0x000007CA, 0x0000 },    /* R1994  - SLIMTX2MIX Input 2 Source */
+	{ 0x000007CB, 0x0080 },    /* R1995  - SLIMTX2MIX Input 2 Volume */
+	{ 0x000007CC, 0x0000 },    /* R1996  - SLIMTX2MIX Input 3 Source */
+	{ 0x000007CD, 0x0080 },    /* R1997  - SLIMTX2MIX Input 3 Volume */
+	{ 0x000007CE, 0x0000 },    /* R1998  - SLIMTX2MIX Input 4 Source */
+	{ 0x000007CF, 0x0080 },    /* R1999  - SLIMTX2MIX Input 4 Volume */
+	{ 0x000007D0, 0x0000 },    /* R2000  - SLIMTX3MIX Input 1 Source */
+	{ 0x000007D1, 0x0080 },    /* R2001  - SLIMTX3MIX Input 1 Volume */
+	{ 0x000007D2, 0x0000 },    /* R2002  - SLIMTX3MIX Input 2 Source */
+	{ 0x000007D3, 0x0080 },    /* R2003  - SLIMTX3MIX Input 2 Volume */
+	{ 0x000007D4, 0x0000 },    /* R2004  - SLIMTX3MIX Input 3 Source */
+	{ 0x000007D5, 0x0080 },    /* R2005  - SLIMTX3MIX Input 3 Volume */
+	{ 0x000007D6, 0x0000 },    /* R2006  - SLIMTX3MIX Input 4 Source */
+	{ 0x000007D7, 0x0080 },    /* R2007  - SLIMTX3MIX Input 4 Volume */
+	{ 0x000007D8, 0x0000 },    /* R2008  - SLIMTX4MIX Input 1 Source */
+	{ 0x000007D9, 0x0080 },    /* R2009  - SLIMTX4MIX Input 1 Volume */
+	{ 0x000007DA, 0x0000 },    /* R2010  - SLIMTX4MIX Input 2 Source */
+	{ 0x000007DB, 0x0080 },    /* R2011  - SLIMTX4MIX Input 2 Volume */
+	{ 0x000007DC, 0x0000 },    /* R2012  - SLIMTX4MIX Input 3 Source */
+	{ 0x000007DD, 0x0080 },    /* R2013  - SLIMTX4MIX Input 3 Volume */
+	{ 0x000007DE, 0x0000 },    /* R2014  - SLIMTX4MIX Input 4 Source */
+	{ 0x000007DF, 0x0080 },    /* R2015  - SLIMTX4MIX Input 4 Volume */
+	{ 0x000007E0, 0x0000 },    /* R2016  - SLIMTX5MIX Input 1 Source */
+	{ 0x000007E1, 0x0080 },    /* R2017  - SLIMTX5MIX Input 1 Volume */
+	{ 0x000007E2, 0x0000 },    /* R2018  - SLIMTX5MIX Input 2 Source */
+	{ 0x000007E3, 0x0080 },    /* R2019  - SLIMTX5MIX Input 2 Volume */
+	{ 0x000007E4, 0x0000 },    /* R2020  - SLIMTX5MIX Input 3 Source */
+	{ 0x000007E5, 0x0080 },    /* R2021  - SLIMTX5MIX Input 3 Volume */
+	{ 0x000007E6, 0x0000 },    /* R2022  - SLIMTX5MIX Input 4 Source */
+	{ 0x000007E7, 0x0080 },    /* R2023  - SLIMTX5MIX Input 4 Volume */
+	{ 0x000007E8, 0x0000 },    /* R2024  - SLIMTX6MIX Input 1 Source */
+	{ 0x000007E9, 0x0080 },    /* R2025  - SLIMTX6MIX Input 1 Volume */
+	{ 0x000007EA, 0x0000 },    /* R2026  - SLIMTX6MIX Input 2 Source */
+	{ 0x000007EB, 0x0080 },    /* R2027  - SLIMTX6MIX Input 2 Volume */
+	{ 0x000007EC, 0x0000 },    /* R2028  - SLIMTX6MIX Input 3 Source */
+	{ 0x000007ED, 0x0080 },    /* R2029  - SLIMTX6MIX Input 3 Volume */
+	{ 0x000007EE, 0x0000 },    /* R2030  - SLIMTX6MIX Input 4 Source */
+	{ 0x000007EF, 0x0080 },    /* R2031  - SLIMTX6MIX Input 4 Volume */
+	{ 0x000007F0, 0x0000 },    /* R2032  - SLIMTX7MIX Input 1 Source */
+	{ 0x000007F1, 0x0080 },    /* R2033  - SLIMTX7MIX Input 1 Volume */
+	{ 0x000007F2, 0x0000 },    /* R2034  - SLIMTX7MIX Input 2 Source */
+	{ 0x000007F3, 0x0080 },    /* R2035  - SLIMTX7MIX Input 2 Volume */
+	{ 0x000007F4, 0x0000 },    /* R2036  - SLIMTX7MIX Input 3 Source */
+	{ 0x000007F5, 0x0080 },    /* R2037  - SLIMTX7MIX Input 3 Volume */
+	{ 0x000007F6, 0x0000 },    /* R2038  - SLIMTX7MIX Input 4 Source */
+	{ 0x000007F7, 0x0080 },    /* R2039  - SLIMTX7MIX Input 4 Volume */
+	{ 0x000007F8, 0x0000 },    /* R2040  - SLIMTX8MIX Input 1 Source */
+	{ 0x000007F9, 0x0080 },    /* R2041  - SLIMTX8MIX Input 1 Volume */
+	{ 0x000007FA, 0x0000 },    /* R2042  - SLIMTX8MIX Input 2 Source */
+	{ 0x000007FB, 0x0080 },    /* R2043  - SLIMTX8MIX Input 2 Volume */
+	{ 0x000007FC, 0x0000 },    /* R2044  - SLIMTX8MIX Input 3 Source */
+	{ 0x000007FD, 0x0080 },    /* R2045  - SLIMTX8MIX Input 3 Volume */
+	{ 0x000007FE, 0x0000 },    /* R2046  - SLIMTX8MIX Input 4 Source */
+	{ 0x000007FF, 0x0080 },    /* R2047  - SLIMTX8MIX Input 4 Volume */
+	{ 0x00000880, 0x0000 },    /* R2176  - EQ1MIX Input 1 Source */
+	{ 0x00000881, 0x0080 },    /* R2177  - EQ1MIX Input 1 Volume */
+	{ 0x00000882, 0x0000 },    /* R2178  - EQ1MIX Input 2 Source */
+	{ 0x00000883, 0x0080 },    /* R2179  - EQ1MIX Input 2 Volume */
+	{ 0x00000884, 0x0000 },    /* R2180  - EQ1MIX Input 3 Source */
+	{ 0x00000885, 0x0080 },    /* R2181  - EQ1MIX Input 3 Volume */
+	{ 0x00000886, 0x0000 },    /* R2182  - EQ1MIX Input 4 Source */
+	{ 0x00000887, 0x0080 },    /* R2183  - EQ1MIX Input 4 Volume */
+	{ 0x00000888, 0x0000 },    /* R2184  - EQ2MIX Input 1 Source */
+	{ 0x00000889, 0x0080 },    /* R2185  - EQ2MIX Input 1 Volume */
+	{ 0x0000088A, 0x0000 },    /* R2186  - EQ2MIX Input 2 Source */
+	{ 0x0000088B, 0x0080 },    /* R2187  - EQ2MIX Input 2 Volume */
+	{ 0x0000088C, 0x0000 },    /* R2188  - EQ2MIX Input 3 Source */
+	{ 0x0000088D, 0x0080 },    /* R2189  - EQ2MIX Input 3 Volume */
+	{ 0x0000088E, 0x0000 },    /* R2190  - EQ2MIX Input 4 Source */
+	{ 0x0000088F, 0x0080 },    /* R2191  - EQ2MIX Input 4 Volume */
+	{ 0x00000890, 0x0000 },    /* R2192  - EQ3MIX Input 1 Source */
+	{ 0x00000891, 0x0080 },    /* R2193  - EQ3MIX Input 1 Volume */
+	{ 0x00000892, 0x0000 },    /* R2194  - EQ3MIX Input 2 Source */
+	{ 0x00000893, 0x0080 },    /* R2195  - EQ3MIX Input 2 Volume */
+	{ 0x00000894, 0x0000 },    /* R2196  - EQ3MIX Input 3 Source */
+	{ 0x00000895, 0x0080 },    /* R2197  - EQ3MIX Input 3 Volume */
+	{ 0x00000896, 0x0000 },    /* R2198  - EQ3MIX Input 4 Source */
+	{ 0x00000897, 0x0080 },    /* R2199  - EQ3MIX Input 4 Volume */
+	{ 0x00000898, 0x0000 },    /* R2200  - EQ4MIX Input 1 Source */
+	{ 0x00000899, 0x0080 },    /* R2201  - EQ4MIX Input 1 Volume */
+	{ 0x0000089A, 0x0000 },    /* R2202  - EQ4MIX Input 2 Source */
+	{ 0x0000089B, 0x0080 },    /* R2203  - EQ4MIX Input 2 Volume */
+	{ 0x0000089C, 0x0000 },    /* R2204  - EQ4MIX Input 3 Source */
+	{ 0x0000089D, 0x0080 },    /* R2205  - EQ4MIX Input 3 Volume */
+	{ 0x0000089E, 0x0000 },    /* R2206  - EQ4MIX Input 4 Source */
+	{ 0x0000089F, 0x0080 },    /* R2207  - EQ4MIX Input 4 Volume */
+	{ 0x000008C0, 0x0000 },    /* R2240  - DRC1LMIX Input 1 Source */
+	{ 0x000008C1, 0x0080 },    /* R2241  - DRC1LMIX Input 1 Volume */
+	{ 0x000008C2, 0x0000 },    /* R2242  - DRC1LMIX Input 2 Source */
+	{ 0x000008C3, 0x0080 },    /* R2243  - DRC1LMIX Input 2 Volume */
+	{ 0x000008C4, 0x0000 },    /* R2244  - DRC1LMIX Input 3 Source */
+	{ 0x000008C5, 0x0080 },    /* R2245  - DRC1LMIX Input 3 Volume */
+	{ 0x000008C6, 0x0000 },    /* R2246  - DRC1LMIX Input 4 Source */
+	{ 0x000008C7, 0x0080 },    /* R2247  - DRC1LMIX Input 4 Volume */
+	{ 0x000008C8, 0x0000 },    /* R2248  - DRC1RMIX Input 1 Source */
+	{ 0x000008C9, 0x0080 },    /* R2249  - DRC1RMIX Input 1 Volume */
+	{ 0x000008CA, 0x0000 },    /* R2250  - DRC1RMIX Input 2 Source */
+	{ 0x000008CB, 0x0080 },    /* R2251  - DRC1RMIX Input 2 Volume */
+	{ 0x000008CC, 0x0000 },    /* R2252  - DRC1RMIX Input 3 Source */
+	{ 0x000008CD, 0x0080 },    /* R2253  - DRC1RMIX Input 3 Volume */
+	{ 0x000008CE, 0x0000 },    /* R2254  - DRC1RMIX Input 4 Source */
+	{ 0x000008CF, 0x0080 },    /* R2255  - DRC1RMIX Input 4 Volume */
+	{ 0x00000900, 0x0000 },    /* R2304  - HPLP1MIX Input 1 Source */
+	{ 0x00000901, 0x0080 },    /* R2305  - HPLP1MIX Input 1 Volume */
+	{ 0x00000902, 0x0000 },    /* R2306  - HPLP1MIX Input 2 Source */
+	{ 0x00000903, 0x0080 },    /* R2307  - HPLP1MIX Input 2 Volume */
+	{ 0x00000904, 0x0000 },    /* R2308  - HPLP1MIX Input 3 Source */
+	{ 0x00000905, 0x0080 },    /* R2309  - HPLP1MIX Input 3 Volume */
+	{ 0x00000906, 0x0000 },    /* R2310  - HPLP1MIX Input 4 Source */
+	{ 0x00000907, 0x0080 },    /* R2311  - HPLP1MIX Input 4 Volume */
+	{ 0x00000908, 0x0000 },    /* R2312  - HPLP2MIX Input 1 Source */
+	{ 0x00000909, 0x0080 },    /* R2313  - HPLP2MIX Input 1 Volume */
+	{ 0x0000090A, 0x0000 },    /* R2314  - HPLP2MIX Input 2 Source */
+	{ 0x0000090B, 0x0080 },    /* R2315  - HPLP2MIX Input 2 Volume */
+	{ 0x0000090C, 0x0000 },    /* R2316  - HPLP2MIX Input 3 Source */
+	{ 0x0000090D, 0x0080 },    /* R2317  - HPLP2MIX Input 3 Volume */
+	{ 0x0000090E, 0x0000 },    /* R2318  - HPLP2MIX Input 4 Source */
+	{ 0x0000090F, 0x0080 },    /* R2319  - HPLP2MIX Input 4 Volume */
+	{ 0x00000910, 0x0000 },    /* R2320  - HPLP3MIX Input 1 Source */
+	{ 0x00000911, 0x0080 },    /* R2321  - HPLP3MIX Input 1 Volume */
+	{ 0x00000912, 0x0000 },    /* R2322  - HPLP3MIX Input 2 Source */
+	{ 0x00000913, 0x0080 },    /* R2323  - HPLP3MIX Input 2 Volume */
+	{ 0x00000914, 0x0000 },    /* R2324  - HPLP3MIX Input 3 Source */
+	{ 0x00000915, 0x0080 },    /* R2325  - HPLP3MIX Input 3 Volume */
+	{ 0x00000916, 0x0000 },    /* R2326  - HPLP3MIX Input 4 Source */
+	{ 0x00000917, 0x0080 },    /* R2327  - HPLP3MIX Input 4 Volume */
+	{ 0x00000918, 0x0000 },    /* R2328  - HPLP4MIX Input 1 Source */
+	{ 0x00000919, 0x0080 },    /* R2329  - HPLP4MIX Input 1 Volume */
+	{ 0x0000091A, 0x0000 },    /* R2330  - HPLP4MIX Input 2 Source */
+	{ 0x0000091B, 0x0080 },    /* R2331  - HPLP4MIX Input 2 Volume */
+	{ 0x0000091C, 0x0000 },    /* R2332  - HPLP4MIX Input 3 Source */
+	{ 0x0000091D, 0x0080 },    /* R2333  - HPLP4MIX Input 3 Volume */
+	{ 0x0000091E, 0x0000 },    /* R2334  - HPLP4MIX Input 4 Source */
+	{ 0x0000091F, 0x0080 },    /* R2335  - HPLP4MIX Input 4 Volume */
+	{ 0x00000B00, 0x0000 },    /* R2816  - ISRC1DEC1MIX Input 1 Source */
+	{ 0x00000B08, 0x0000 },    /* R2824  - ISRC1DEC2MIX Input 1 Source */
+	{ 0x00000B20, 0x0000 },    /* R2848  - ISRC1INT1MIX Input 1 Source */
+	{ 0x00000B28, 0x0000 },    /* R2856  - ISRC1INT2MIX Input 1 Source */
+	{ 0x00000B40, 0x0000 },    /* R2880  - ISRC2DEC1MIX Input 1 Source */
+	{ 0x00000B48, 0x0000 },    /* R2888  - ISRC2DEC2MIX Input 1 Source */
+	{ 0x00000B60, 0x0000 },    /* R2912  - ISRC2INT1MIX Input 1 Source */
+	{ 0x00000B68, 0x0000 },    /* R2920  - ISRC2INT2MIX Input 1 Source */
+	{ 0x00000C00, 0xA101 },    /* R3072  - GPIO1 CTRL */
+	{ 0x00000C01, 0xA101 },    /* R3073  - GPIO2 CTRL */
+	{ 0x00000C02, 0xA101 },    /* R3074  - GPIO3 CTRL */
+	{ 0x00000C03, 0xA101 },    /* R3075  - GPIO4 CTRL */
+	{ 0x00000C04, 0xA101 },    /* R3076  - GPIO5 CTRL */
+	{ 0x00000C0F, 0x0400 },    /* R3087  - IRQ CTRL 1 */
+	{ 0x00000C10, 0x1000 },    /* R3088  - GPIO Debounce Config */
+	{ 0x00000C20, 0x8002 },    /* R3104  - Misc Pad Ctrl 1 */
+	{ 0x00000C21, 0x0001 },    /* R3105  - Misc Pad Ctrl 2 */
+	{ 0x00000C22, 0x0000 },    /* R3106  - Misc Pad Ctrl 3 */
+	{ 0x00000C23, 0x0000 },    /* R3107  - Misc Pad Ctrl 4 */
+	{ 0x00000C24, 0x0000 },    /* R3108  - Misc Pad Ctrl 5 */
+	{ 0x00000D08, 0xFFFF },    /* R3336  - Interrupt Status 1 Mask */
+	{ 0x00000D0A, 0xFFFF },    /* R3338  - Interrupt Status 3 Mask */
+	{ 0x00000D0B, 0xFFFF },    /* R3339  - Interrupt Status 4 Mask */
+	{ 0x00000D0C, 0xFEFF },    /* R3340  - Interrupt Status 5 Mask */
+	{ 0x00000D0F, 0x0000 },    /* R3343  - Interrupt Control */
+	{ 0x00000D18, 0xFFFF },    /* R3352  - IRQ2 Status 1 Mask */
+	{ 0x00000D1A, 0xFFFF },    /* R3354  - IRQ2 Status 3 Mask */
+	{ 0x00000D1B, 0xFFFF },    /* R3355  - IRQ2 Status 4 Mask */
+	{ 0x00000D1C, 0xFFFF },    /* R3356  - IRQ2 Status 5 Mask */
+	{ 0x00000D1F, 0x0000 },    /* R3359  - IRQ2 Control */
+	{ 0x00000D53, 0xFFFF },    /* R3411  - AOD IRQ Mask IRQ1 */
+	{ 0x00000D54, 0xFFFF },    /* R3412  - AOD IRQ Mask IRQ2 */
+	{ 0x00000D56, 0x0000 },    /* R3414  - Jack detect debounce */
+	{ 0x00000E00, 0x0000 },    /* R3584  - FX_Ctrl1 */
+	{ 0x00000E01, 0x0000 },    /* R3585  - FX_Ctrl2 */
+	{ 0x00000E10, 0x6318 },    /* R3600  - EQ1_1 */
+	{ 0x00000E11, 0x6300 },    /* R3601  - EQ1_2 */
+	{ 0x00000E12, 0x0FC8 },    /* R3602  - EQ1_3 */
+	{ 0x00000E13, 0x03FE },    /* R3603  - EQ1_4 */
+	{ 0x00000E14, 0x00E0 },    /* R3604  - EQ1_5 */
+	{ 0x00000E15, 0x1EC4 },    /* R3605  - EQ1_6 */
+	{ 0x00000E16, 0xF136 },    /* R3606  - EQ1_7 */
+	{ 0x00000E17, 0x0409 },    /* R3607  - EQ1_8 */
+	{ 0x00000E18, 0x04CC },    /* R3608  - EQ1_9 */
+	{ 0x00000E19, 0x1C9B },    /* R3609  - EQ1_10 */
+	{ 0x00000E1A, 0xF337 },    /* R3610  - EQ1_11 */
+	{ 0x00000E1B, 0x040B },    /* R3611  - EQ1_12 */
+	{ 0x00000E1C, 0x0CBB },    /* R3612  - EQ1_13 */
+	{ 0x00000E1D, 0x16F8 },    /* R3613  - EQ1_14 */
+	{ 0x00000E1E, 0xF7D9 },    /* R3614  - EQ1_15 */
+	{ 0x00000E1F, 0x040A },    /* R3615  - EQ1_16 */
+	{ 0x00000E20, 0x1F14 },    /* R3616  - EQ1_17 */
+	{ 0x00000E21, 0x058C },    /* R3617  - EQ1_18 */
+	{ 0x00000E22, 0x0563 },    /* R3618  - EQ1_19 */
+	{ 0x00000E23, 0x4000 },    /* R3619  - EQ1_20 */
+	{ 0x00000E24, 0x0B75 },    /* R3620  - EQ1_21 */
+	{ 0x00000E26, 0x6318 },    /* R3622  - EQ2_1 */
+	{ 0x00000E27, 0x6300 },    /* R3623  - EQ2_2 */
+	{ 0x00000E28, 0x0FC8 },    /* R3624  - EQ2_3 */
+	{ 0x00000E29, 0x03FE },    /* R3625  - EQ2_4 */
+	{ 0x00000E2A, 0x00E0 },    /* R3626  - EQ2_5 */
+	{ 0x00000E2B, 0x1EC4 },    /* R3627  - EQ2_6 */
+	{ 0x00000E2C, 0xF136 },    /* R3628  - EQ2_7 */
+	{ 0x00000E2D, 0x0409 },    /* R3629  - EQ2_8 */
+	{ 0x00000E2E, 0x04CC },    /* R3630  - EQ2_9 */
+	{ 0x00000E2F, 0x1C9B },    /* R3631  - EQ2_10 */
+	{ 0x00000E30, 0xF337 },    /* R3632  - EQ2_11 */
+	{ 0x00000E31, 0x040B },    /* R3633  - EQ2_12 */
+	{ 0x00000E32, 0x0CBB },    /* R3634  - EQ2_13 */
+	{ 0x00000E33, 0x16F8 },    /* R3635  - EQ2_14 */
+	{ 0x00000E34, 0xF7D9 },    /* R3636  - EQ2_15 */
+	{ 0x00000E35, 0x040A },    /* R3637  - EQ2_16 */
+	{ 0x00000E36, 0x1F14 },    /* R3638  - EQ2_17 */
+	{ 0x00000E37, 0x058C },    /* R3639  - EQ2_18 */
+	{ 0x00000E38, 0x0563 },    /* R3640  - EQ2_19 */
+	{ 0x00000E39, 0x4000 },    /* R3641  - EQ2_20 */
+	{ 0x00000E3A, 0x0B75 },    /* R3642  - EQ2_21 */
+	{ 0x00000E3C, 0x6318 },    /* R3644  - EQ3_1 */
+	{ 0x00000E3D, 0x6300 },    /* R3645  - EQ3_2 */
+	{ 0x00000E3E, 0x0FC8 },    /* R3646  - EQ3_3 */
+	{ 0x00000E3F, 0x03FE },    /* R3647  - EQ3_4 */
+	{ 0x00000E40, 0x00E0 },    /* R3648  - EQ3_5 */
+	{ 0x00000E41, 0x1EC4 },    /* R3649  - EQ3_6 */
+	{ 0x00000E42, 0xF136 },    /* R3650  - EQ3_7 */
+	{ 0x00000E43, 0x0409 },    /* R3651  - EQ3_8 */
+	{ 0x00000E44, 0x04CC },    /* R3652  - EQ3_9 */
+	{ 0x00000E45, 0x1C9B },    /* R3653  - EQ3_10 */
+	{ 0x00000E46, 0xF337 },    /* R3654  - EQ3_11 */
+	{ 0x00000E47, 0x040B },    /* R3655  - EQ3_12 */
+	{ 0x00000E48, 0x0CBB },    /* R3656  - EQ3_13 */
+	{ 0x00000E49, 0x16F8 },    /* R3657  - EQ3_14 */
+	{ 0x00000E4A, 0xF7D9 },    /* R3658  - EQ3_15 */
+	{ 0x00000E4B, 0x040A },    /* R3659  - EQ3_16 */
+	{ 0x00000E4C, 0x1F14 },    /* R3660  - EQ3_17 */
+	{ 0x00000E4D, 0x058C },    /* R3661  - EQ3_18 */
+	{ 0x00000E4E, 0x0563 },    /* R3662  - EQ3_19 */
+	{ 0x00000E4F, 0x4000 },    /* R3663  - EQ3_20 */
+	{ 0x00000E50, 0x0B75 },    /* R3664  - EQ3_21 */
+	{ 0x00000E52, 0x6318 },    /* R3666  - EQ4_1 */
+	{ 0x00000E53, 0x6300 },    /* R3667  - EQ4_2 */
+	{ 0x00000E54, 0x0FC8 },    /* R3668  - EQ4_3 */
+	{ 0x00000E55, 0x03FE },    /* R3669  - EQ4_4 */
+	{ 0x00000E56, 0x00E0 },    /* R3670  - EQ4_5 */
+	{ 0x00000E57, 0x1EC4 },    /* R3671  - EQ4_6 */
+	{ 0x00000E58, 0xF136 },    /* R3672  - EQ4_7 */
+	{ 0x00000E59, 0x0409 },    /* R3673  - EQ4_8 */
+	{ 0x00000E5A, 0x04CC },    /* R3674  - EQ4_9 */
+	{ 0x00000E5B, 0x1C9B },    /* R3675  - EQ4_10 */
+	{ 0x00000E5C, 0xF337 },    /* R3676  - EQ4_11 */
+	{ 0x00000E5D, 0x040B },    /* R3677  - EQ4_12 */
+	{ 0x00000E5E, 0x0CBB },    /* R3678  - EQ4_13 */
+	{ 0x00000E5F, 0x16F8 },    /* R3679  - EQ4_14 */
+	{ 0x00000E60, 0xF7D9 },    /* R3680  - EQ4_15 */
+	{ 0x00000E61, 0x040A },    /* R3681  - EQ4_16 */
+	{ 0x00000E62, 0x1F14 },    /* R3682  - EQ4_17 */
+	{ 0x00000E63, 0x058C },    /* R3683  - EQ4_18 */
+	{ 0x00000E64, 0x0563 },    /* R3684  - EQ4_19 */
+	{ 0x00000E65, 0x4000 },    /* R3685  - EQ4_20 */
+	{ 0x00000E66, 0x0B75 },    /* R3686  - EQ4_21 */
+	{ 0x00000E80, 0x0018 },    /* R3712  - DRC1 ctrl1 */
+	{ 0x00000E81, 0x0933 },    /* R3713  - DRC1 ctrl2 */
+	{ 0x00000E82, 0x0018 },    /* R3714  - DRC1 ctrl3 */
+	{ 0x00000E83, 0x0000 },    /* R3715  - DRC1 ctrl4 */
+	{ 0x00000E84, 0x0000 },    /* R3716  - DRC1 ctrl5 */
+	{ 0x00000EC0, 0x0000 },    /* R3776  - HPLPF1_1 */
+	{ 0x00000EC1, 0x0000 },    /* R3777  - HPLPF1_2 */
+	{ 0x00000EC4, 0x0000 },    /* R3780  - HPLPF2_1 */
+	{ 0x00000EC5, 0x0000 },    /* R3781  - HPLPF2_2 */
+	{ 0x00000EC8, 0x0000 },    /* R3784  - HPLPF3_1 */
+	{ 0x00000EC9, 0x0000 },    /* R3785  - HPLPF3_2 */
+	{ 0x00000ECC, 0x0000 },    /* R3788  - HPLPF4_1 */
+	{ 0x00000ECD, 0x0000 },    /* R3789  - HPLPF4_2 */
+	{ 0x00000EF0, 0x0000 },    /* R3824  - ISRC 1 CTRL 1 */
+	{ 0x00000EF1, 0x0000 },    /* R3825  - ISRC 1 CTRL 2 */
+	{ 0x00000EF2, 0x0000 },    /* R3826  - ISRC 1 CTRL 3 */
+	{ 0x00000EF3, 0x0000 },    /* R3827  - ISRC 2 CTRL 1 */
+	{ 0x00000EF4, 0x0000 },    /* R3828  - ISRC 2 CTRL 2 */
+	{ 0x00000EF5, 0x0000 },    /* R3829  - ISRC 2 CTRL 3 */
+	{ 0x00001100, 0x0010 },    /* R4352  - DSP1 Control 1 */
+	{ 0x00001101, 0x0000 },    /* R4353  - DSP1 Clocking 1 */
+};
+
+static bool wm8997_readable_register(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case ARIZONA_SOFTWARE_RESET:
+	case ARIZONA_DEVICE_REVISION:
+	case ARIZONA_CTRL_IF_I2C1_CFG_1:
+	case ARIZONA_WRITE_SEQUENCER_CTRL_0:
+	case ARIZONA_WRITE_SEQUENCER_CTRL_1:
+	case ARIZONA_WRITE_SEQUENCER_CTRL_2:
+	case ARIZONA_TONE_GENERATOR_1:
+	case ARIZONA_TONE_GENERATOR_2:
+	case ARIZONA_TONE_GENERATOR_3:
+	case ARIZONA_TONE_GENERATOR_4:
+	case ARIZONA_TONE_GENERATOR_5:
+	case ARIZONA_PWM_DRIVE_1:
+	case ARIZONA_PWM_DRIVE_2:
+	case ARIZONA_PWM_DRIVE_3:
+	case ARIZONA_WAKE_CONTROL:
+	case ARIZONA_SEQUENCE_CONTROL:
+	case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_1:
+	case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_2:
+	case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_3:
+	case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_4:
+	case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_1:
+	case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_2:
+	case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_3:
+	case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_4:
+	case ARIZONA_COMFORT_NOISE_GENERATOR:
+	case ARIZONA_HAPTICS_CONTROL_1:
+	case ARIZONA_HAPTICS_CONTROL_2:
+	case ARIZONA_HAPTICS_PHASE_1_INTENSITY:
+	case ARIZONA_HAPTICS_PHASE_1_DURATION:
+	case ARIZONA_HAPTICS_PHASE_2_INTENSITY:
+	case ARIZONA_HAPTICS_PHASE_2_DURATION:
+	case ARIZONA_HAPTICS_PHASE_3_INTENSITY:
+	case ARIZONA_HAPTICS_PHASE_3_DURATION:
+	case ARIZONA_HAPTICS_STATUS:
+	case ARIZONA_CLOCK_32K_1:
+	case ARIZONA_SYSTEM_CLOCK_1:
+	case ARIZONA_SAMPLE_RATE_1:
+	case ARIZONA_SAMPLE_RATE_2:
+	case ARIZONA_SAMPLE_RATE_3:
+	case ARIZONA_SAMPLE_RATE_1_STATUS:
+	case ARIZONA_SAMPLE_RATE_2_STATUS:
+	case ARIZONA_SAMPLE_RATE_3_STATUS:
+	case ARIZONA_ASYNC_CLOCK_1:
+	case ARIZONA_ASYNC_SAMPLE_RATE_1:
+	case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS:
+	case ARIZONA_OUTPUT_SYSTEM_CLOCK:
+	case ARIZONA_OUTPUT_ASYNC_CLOCK:
+	case ARIZONA_RATE_ESTIMATOR_1:
+	case ARIZONA_RATE_ESTIMATOR_2:
+	case ARIZONA_RATE_ESTIMATOR_3:
+	case ARIZONA_RATE_ESTIMATOR_4:
+	case ARIZONA_RATE_ESTIMATOR_5:
+	case ARIZONA_FLL1_CONTROL_1:
+	case ARIZONA_FLL1_CONTROL_2:
+	case ARIZONA_FLL1_CONTROL_3:
+	case ARIZONA_FLL1_CONTROL_4:
+	case ARIZONA_FLL1_CONTROL_5:
+	case ARIZONA_FLL1_CONTROL_6:
+	case ARIZONA_FLL1_LOOP_FILTER_TEST_1:
+	case ARIZONA_FLL1_NCO_TEST_0:
+	case ARIZONA_FLL1_SYNCHRONISER_1:
+	case ARIZONA_FLL1_SYNCHRONISER_2:
+	case ARIZONA_FLL1_SYNCHRONISER_3:
+	case ARIZONA_FLL1_SYNCHRONISER_4:
+	case ARIZONA_FLL1_SYNCHRONISER_5:
+	case ARIZONA_FLL1_SYNCHRONISER_6:
+	case ARIZONA_FLL1_SPREAD_SPECTRUM:
+	case ARIZONA_FLL1_GPIO_CLOCK:
+	case ARIZONA_FLL2_CONTROL_1:
+	case ARIZONA_FLL2_CONTROL_2:
+	case ARIZONA_FLL2_CONTROL_3:
+	case ARIZONA_FLL2_CONTROL_4:
+	case ARIZONA_FLL2_CONTROL_5:
+	case ARIZONA_FLL2_CONTROL_6:
+	case ARIZONA_FLL2_LOOP_FILTER_TEST_1:
+	case ARIZONA_FLL2_NCO_TEST_0:
+	case ARIZONA_FLL2_SYNCHRONISER_1:
+	case ARIZONA_FLL2_SYNCHRONISER_2:
+	case ARIZONA_FLL2_SYNCHRONISER_3:
+	case ARIZONA_FLL2_SYNCHRONISER_4:
+	case ARIZONA_FLL2_SYNCHRONISER_5:
+	case ARIZONA_FLL2_SYNCHRONISER_6:
+	case ARIZONA_FLL2_SPREAD_SPECTRUM:
+	case ARIZONA_FLL2_GPIO_CLOCK:
+	case ARIZONA_MIC_CHARGE_PUMP_1:
+	case ARIZONA_LDO1_CONTROL_1:
+	case ARIZONA_LDO2_CONTROL_1:
+	case ARIZONA_MIC_BIAS_CTRL_1:
+	case ARIZONA_MIC_BIAS_CTRL_2:
+	case ARIZONA_MIC_BIAS_CTRL_3:
+	case ARIZONA_ACCESSORY_DETECT_MODE_1:
+	case ARIZONA_HEADPHONE_DETECT_1:
+	case ARIZONA_HEADPHONE_DETECT_2:
+	case ARIZONA_MIC_DETECT_1:
+	case ARIZONA_MIC_DETECT_2:
+	case ARIZONA_MIC_DETECT_3:
+	case ARIZONA_MIC_NOISE_MIX_CONTROL_1:
+	case ARIZONA_ISOLATION_CONTROL:
+	case ARIZONA_JACK_DETECT_ANALOGUE:
+	case ARIZONA_INPUT_ENABLES:
+	case ARIZONA_INPUT_ENABLES_STATUS:
+	case ARIZONA_INPUT_RATE:
+	case ARIZONA_INPUT_VOLUME_RAMP:
+	case ARIZONA_IN1L_CONTROL:
+	case ARIZONA_ADC_DIGITAL_VOLUME_1L:
+	case ARIZONA_DMIC1L_CONTROL:
+	case ARIZONA_IN1R_CONTROL:
+	case ARIZONA_ADC_DIGITAL_VOLUME_1R:
+	case ARIZONA_DMIC1R_CONTROL:
+	case ARIZONA_IN2L_CONTROL:
+	case ARIZONA_ADC_DIGITAL_VOLUME_2L:
+	case ARIZONA_DMIC2L_CONTROL:
+	case ARIZONA_IN2R_CONTROL:
+	case ARIZONA_ADC_DIGITAL_VOLUME_2R:
+	case ARIZONA_DMIC2R_CONTROL:
+	case ARIZONA_OUTPUT_ENABLES_1:
+	case ARIZONA_OUTPUT_STATUS_1:
+	case ARIZONA_RAW_OUTPUT_STATUS_1:
+	case ARIZONA_OUTPUT_RATE_1:
+	case ARIZONA_OUTPUT_VOLUME_RAMP:
+	case ARIZONA_OUTPUT_PATH_CONFIG_1L:
+	case ARIZONA_DAC_DIGITAL_VOLUME_1L:
+	case ARIZONA_DAC_VOLUME_LIMIT_1L:
+	case ARIZONA_NOISE_GATE_SELECT_1L:
+	case ARIZONA_OUTPUT_PATH_CONFIG_1R:
+	case ARIZONA_DAC_DIGITAL_VOLUME_1R:
+	case ARIZONA_DAC_VOLUME_LIMIT_1R:
+	case ARIZONA_NOISE_GATE_SELECT_1R:
+	case ARIZONA_OUTPUT_PATH_CONFIG_3L:
+	case ARIZONA_DAC_DIGITAL_VOLUME_3L:
+	case ARIZONA_DAC_VOLUME_LIMIT_3L:
+	case ARIZONA_NOISE_GATE_SELECT_3L:
+	case ARIZONA_OUTPUT_PATH_CONFIG_4L:
+	case ARIZONA_DAC_DIGITAL_VOLUME_4L:
+	case ARIZONA_OUT_VOLUME_4L:
+	case ARIZONA_NOISE_GATE_SELECT_4L:
+	case ARIZONA_OUTPUT_PATH_CONFIG_5L:
+	case ARIZONA_DAC_DIGITAL_VOLUME_5L:
+	case ARIZONA_DAC_VOLUME_LIMIT_5L:
+	case ARIZONA_NOISE_GATE_SELECT_5L:
+	case ARIZONA_DAC_DIGITAL_VOLUME_5R:
+	case ARIZONA_DAC_VOLUME_LIMIT_5R:
+	case ARIZONA_NOISE_GATE_SELECT_5R:
+	case ARIZONA_DAC_AEC_CONTROL_1:
+	case ARIZONA_NOISE_GATE_CONTROL:
+	case ARIZONA_PDM_SPK1_CTRL_1:
+	case ARIZONA_PDM_SPK1_CTRL_2:
+	case ARIZONA_AIF1_BCLK_CTRL:
+	case ARIZONA_AIF1_TX_PIN_CTRL:
+	case ARIZONA_AIF1_RX_PIN_CTRL:
+	case ARIZONA_AIF1_RATE_CTRL:
+	case ARIZONA_AIF1_FORMAT:
+	case ARIZONA_AIF1_TX_BCLK_RATE:
+	case ARIZONA_AIF1_RX_BCLK_RATE:
+	case ARIZONA_AIF1_FRAME_CTRL_1:
+	case ARIZONA_AIF1_FRAME_CTRL_2:
+	case ARIZONA_AIF1_FRAME_CTRL_3:
+	case ARIZONA_AIF1_FRAME_CTRL_4:
+	case ARIZONA_AIF1_FRAME_CTRL_5:
+	case ARIZONA_AIF1_FRAME_CTRL_6:
+	case ARIZONA_AIF1_FRAME_CTRL_7:
+	case ARIZONA_AIF1_FRAME_CTRL_8:
+	case ARIZONA_AIF1_FRAME_CTRL_9:
+	case ARIZONA_AIF1_FRAME_CTRL_10:
+	case ARIZONA_AIF1_FRAME_CTRL_11:
+	case ARIZONA_AIF1_FRAME_CTRL_12:
+	case ARIZONA_AIF1_FRAME_CTRL_13:
+	case ARIZONA_AIF1_FRAME_CTRL_14:
+	case ARIZONA_AIF1_FRAME_CTRL_15:
+	case ARIZONA_AIF1_FRAME_CTRL_16:
+	case ARIZONA_AIF1_FRAME_CTRL_17:
+	case ARIZONA_AIF1_FRAME_CTRL_18:
+	case ARIZONA_AIF1_TX_ENABLES:
+	case ARIZONA_AIF1_RX_ENABLES:
+	case ARIZONA_AIF2_BCLK_CTRL:
+	case ARIZONA_AIF2_TX_PIN_CTRL:
+	case ARIZONA_AIF2_RX_PIN_CTRL:
+	case ARIZONA_AIF2_RATE_CTRL:
+	case ARIZONA_AIF2_FORMAT:
+	case ARIZONA_AIF2_TX_BCLK_RATE:
+	case ARIZONA_AIF2_RX_BCLK_RATE:
+	case ARIZONA_AIF2_FRAME_CTRL_1:
+	case ARIZONA_AIF2_FRAME_CTRL_2:
+	case ARIZONA_AIF2_FRAME_CTRL_3:
+	case ARIZONA_AIF2_FRAME_CTRL_4:
+	case ARIZONA_AIF2_FRAME_CTRL_11:
+	case ARIZONA_AIF2_FRAME_CTRL_12:
+	case ARIZONA_AIF2_TX_ENABLES:
+	case ARIZONA_AIF2_RX_ENABLES:
+	case ARIZONA_SLIMBUS_FRAMER_REF_GEAR:
+	case ARIZONA_SLIMBUS_RATES_1:
+	case ARIZONA_SLIMBUS_RATES_2:
+	case ARIZONA_SLIMBUS_RATES_3:
+	case ARIZONA_SLIMBUS_RATES_4:
+	case ARIZONA_SLIMBUS_RATES_5:
+	case ARIZONA_SLIMBUS_RATES_6:
+	case ARIZONA_SLIMBUS_RATES_7:
+	case ARIZONA_SLIMBUS_RATES_8:
+	case ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE:
+	case ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE:
+	case ARIZONA_SLIMBUS_RX_PORT_STATUS:
+	case ARIZONA_SLIMBUS_TX_PORT_STATUS:
+	case ARIZONA_PWM1MIX_INPUT_1_SOURCE:
+	case ARIZONA_PWM1MIX_INPUT_1_VOLUME:
+	case ARIZONA_PWM1MIX_INPUT_2_SOURCE:
+	case ARIZONA_PWM1MIX_INPUT_2_VOLUME:
+	case ARIZONA_PWM1MIX_INPUT_3_SOURCE:
+	case ARIZONA_PWM1MIX_INPUT_3_VOLUME:
+	case ARIZONA_PWM1MIX_INPUT_4_SOURCE:
+	case ARIZONA_PWM1MIX_INPUT_4_VOLUME:
+	case ARIZONA_PWM2MIX_INPUT_1_SOURCE:
+	case ARIZONA_PWM2MIX_INPUT_1_VOLUME:
+	case ARIZONA_PWM2MIX_INPUT_2_SOURCE:
+	case ARIZONA_PWM2MIX_INPUT_2_VOLUME:
+	case ARIZONA_PWM2MIX_INPUT_3_SOURCE:
+	case ARIZONA_PWM2MIX_INPUT_3_VOLUME:
+	case ARIZONA_PWM2MIX_INPUT_4_SOURCE:
+	case ARIZONA_PWM2MIX_INPUT_4_VOLUME:
+	case ARIZONA_MICMIX_INPUT_1_SOURCE:
+	case ARIZONA_MICMIX_INPUT_1_VOLUME:
+	case ARIZONA_MICMIX_INPUT_2_SOURCE:
+	case ARIZONA_MICMIX_INPUT_2_VOLUME:
+	case ARIZONA_MICMIX_INPUT_3_SOURCE:
+	case ARIZONA_MICMIX_INPUT_3_VOLUME:
+	case ARIZONA_MICMIX_INPUT_4_SOURCE:
+	case ARIZONA_MICMIX_INPUT_4_VOLUME:
+	case ARIZONA_NOISEMIX_INPUT_1_SOURCE:
+	case ARIZONA_NOISEMIX_INPUT_1_VOLUME:
+	case ARIZONA_NOISEMIX_INPUT_2_SOURCE:
+	case ARIZONA_NOISEMIX_INPUT_2_VOLUME:
+	case ARIZONA_NOISEMIX_INPUT_3_SOURCE:
+	case ARIZONA_NOISEMIX_INPUT_3_VOLUME:
+	case ARIZONA_NOISEMIX_INPUT_4_SOURCE:
+	case ARIZONA_NOISEMIX_INPUT_4_VOLUME:
+	case ARIZONA_OUT1LMIX_INPUT_1_SOURCE:
+	case ARIZONA_OUT1LMIX_INPUT_1_VOLUME:
+	case ARIZONA_OUT1LMIX_INPUT_2_SOURCE:
+	case ARIZONA_OUT1LMIX_INPUT_2_VOLUME:
+	case ARIZONA_OUT1LMIX_INPUT_3_SOURCE:
+	case ARIZONA_OUT1LMIX_INPUT_3_VOLUME:
+	case ARIZONA_OUT1LMIX_INPUT_4_SOURCE:
+	case ARIZONA_OUT1LMIX_INPUT_4_VOLUME:
+	case ARIZONA_OUT1RMIX_INPUT_1_SOURCE:
+	case ARIZONA_OUT1RMIX_INPUT_1_VOLUME:
+	case ARIZONA_OUT1RMIX_INPUT_2_SOURCE:
+	case ARIZONA_OUT1RMIX_INPUT_2_VOLUME:
+	case ARIZONA_OUT1RMIX_INPUT_3_SOURCE:
+	case ARIZONA_OUT1RMIX_INPUT_3_VOLUME:
+	case ARIZONA_OUT1RMIX_INPUT_4_SOURCE:
+	case ARIZONA_OUT1RMIX_INPUT_4_VOLUME:
+	case ARIZONA_OUT3LMIX_INPUT_1_SOURCE:
+	case ARIZONA_OUT3LMIX_INPUT_1_VOLUME:
+	case ARIZONA_OUT3LMIX_INPUT_2_SOURCE:
+	case ARIZONA_OUT3LMIX_INPUT_2_VOLUME:
+	case ARIZONA_OUT3LMIX_INPUT_3_SOURCE:
+	case ARIZONA_OUT3LMIX_INPUT_3_VOLUME:
+	case ARIZONA_OUT3LMIX_INPUT_4_SOURCE:
+	case ARIZONA_OUT3LMIX_INPUT_4_VOLUME:
+	case ARIZONA_OUT4LMIX_INPUT_1_SOURCE:
+	case ARIZONA_OUT4LMIX_INPUT_1_VOLUME:
+	case ARIZONA_OUT4LMIX_INPUT_2_SOURCE:
+	case ARIZONA_OUT4LMIX_INPUT_2_VOLUME:
+	case ARIZONA_OUT4LMIX_INPUT_3_SOURCE:
+	case ARIZONA_OUT4LMIX_INPUT_3_VOLUME:
+	case ARIZONA_OUT4LMIX_INPUT_4_SOURCE:
+	case ARIZONA_OUT4LMIX_INPUT_4_VOLUME:
+	case ARIZONA_OUT5LMIX_INPUT_1_SOURCE:
+	case ARIZONA_OUT5LMIX_INPUT_1_VOLUME:
+	case ARIZONA_OUT5LMIX_INPUT_2_SOURCE:
+	case ARIZONA_OUT5LMIX_INPUT_2_VOLUME:
+	case ARIZONA_OUT5LMIX_INPUT_3_SOURCE:
+	case ARIZONA_OUT5LMIX_INPUT_3_VOLUME:
+	case ARIZONA_OUT5LMIX_INPUT_4_SOURCE:
+	case ARIZONA_OUT5LMIX_INPUT_4_VOLUME:
+	case ARIZONA_OUT5RMIX_INPUT_1_SOURCE:
+	case ARIZONA_OUT5RMIX_INPUT_1_VOLUME:
+	case ARIZONA_OUT5RMIX_INPUT_2_SOURCE:
+	case ARIZONA_OUT5RMIX_INPUT_2_VOLUME:
+	case ARIZONA_OUT5RMIX_INPUT_3_SOURCE:
+	case ARIZONA_OUT5RMIX_INPUT_3_VOLUME:
+	case ARIZONA_OUT5RMIX_INPUT_4_SOURCE:
+	case ARIZONA_OUT5RMIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF1TX1MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF1TX1MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF1TX1MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF1TX1MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF1TX1MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF1TX1MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF1TX1MIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF1TX2MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF1TX2MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF1TX2MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF1TX2MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF1TX2MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF1TX2MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF1TX2MIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF1TX3MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF1TX3MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF1TX3MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF1TX3MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF1TX3MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF1TX3MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF1TX3MIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF1TX4MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF1TX4MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF1TX4MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF1TX4MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF1TX4MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF1TX4MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF1TX4MIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF1TX5MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF1TX5MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF1TX5MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF1TX5MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF1TX5MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF1TX5MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF1TX5MIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF1TX6MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF1TX6MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF1TX6MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF1TX6MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF1TX6MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF1TX6MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF1TX6MIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF1TX7MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF1TX7MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF1TX7MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF1TX7MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF1TX7MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF1TX7MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF1TX7MIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF1TX8MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF1TX8MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF1TX8MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF1TX8MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF1TX8MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF1TX8MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF1TX8MIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF2TX1MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF2TX1MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF2TX1MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF2TX1MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF2TX1MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF2TX1MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF2TX1MIX_INPUT_4_VOLUME:
+	case ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE:
+	case ARIZONA_AIF2TX2MIX_INPUT_1_VOLUME:
+	case ARIZONA_AIF2TX2MIX_INPUT_2_SOURCE:
+	case ARIZONA_AIF2TX2MIX_INPUT_2_VOLUME:
+	case ARIZONA_AIF2TX2MIX_INPUT_3_SOURCE:
+	case ARIZONA_AIF2TX2MIX_INPUT_3_VOLUME:
+	case ARIZONA_AIF2TX2MIX_INPUT_4_SOURCE:
+	case ARIZONA_AIF2TX2MIX_INPUT_4_VOLUME:
+	case ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE:
+	case ARIZONA_SLIMTX1MIX_INPUT_1_VOLUME:
+	case ARIZONA_SLIMTX1MIX_INPUT_2_SOURCE:
+	case ARIZONA_SLIMTX1MIX_INPUT_2_VOLUME:
+	case ARIZONA_SLIMTX1MIX_INPUT_3_SOURCE:
+	case ARIZONA_SLIMTX1MIX_INPUT_3_VOLUME:
+	case ARIZONA_SLIMTX1MIX_INPUT_4_SOURCE:
+	case ARIZONA_SLIMTX1MIX_INPUT_4_VOLUME:
+	case ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE:
+	case ARIZONA_SLIMTX2MIX_INPUT_1_VOLUME:
+	case ARIZONA_SLIMTX2MIX_INPUT_2_SOURCE:
+	case ARIZONA_SLIMTX2MIX_INPUT_2_VOLUME:
+	case ARIZONA_SLIMTX2MIX_INPUT_3_SOURCE:
+	case ARIZONA_SLIMTX2MIX_INPUT_3_VOLUME:
+	case ARIZONA_SLIMTX2MIX_INPUT_4_SOURCE:
+	case ARIZONA_SLIMTX2MIX_INPUT_4_VOLUME:
+	case ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE:
+	case ARIZONA_SLIMTX3MIX_INPUT_1_VOLUME:
+	case ARIZONA_SLIMTX3MIX_INPUT_2_SOURCE:
+	case ARIZONA_SLIMTX3MIX_INPUT_2_VOLUME:
+	case ARIZONA_SLIMTX3MIX_INPUT_3_SOURCE:
+	case ARIZONA_SLIMTX3MIX_INPUT_3_VOLUME:
+	case ARIZONA_SLIMTX3MIX_INPUT_4_SOURCE:
+	case ARIZONA_SLIMTX3MIX_INPUT_4_VOLUME:
+	case ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE:
+	case ARIZONA_SLIMTX4MIX_INPUT_1_VOLUME:
+	case ARIZONA_SLIMTX4MIX_INPUT_2_SOURCE:
+	case ARIZONA_SLIMTX4MIX_INPUT_2_VOLUME:
+	case ARIZONA_SLIMTX4MIX_INPUT_3_SOURCE:
+	case ARIZONA_SLIMTX4MIX_INPUT_3_VOLUME:
+	case ARIZONA_SLIMTX4MIX_INPUT_4_SOURCE:
+	case ARIZONA_SLIMTX4MIX_INPUT_4_VOLUME:
+	case ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE:
+	case ARIZONA_SLIMTX5MIX_INPUT_1_VOLUME:
+	case ARIZONA_SLIMTX5MIX_INPUT_2_SOURCE:
+	case ARIZONA_SLIMTX5MIX_INPUT_2_VOLUME:
+	case ARIZONA_SLIMTX5MIX_INPUT_3_SOURCE:
+	case ARIZONA_SLIMTX5MIX_INPUT_3_VOLUME:
+	case ARIZONA_SLIMTX5MIX_INPUT_4_SOURCE:
+	case ARIZONA_SLIMTX5MIX_INPUT_4_VOLUME:
+	case ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE:
+	case ARIZONA_SLIMTX6MIX_INPUT_1_VOLUME:
+	case ARIZONA_SLIMTX6MIX_INPUT_2_SOURCE:
+	case ARIZONA_SLIMTX6MIX_INPUT_2_VOLUME:
+	case ARIZONA_SLIMTX6MIX_INPUT_3_SOURCE:
+	case ARIZONA_SLIMTX6MIX_INPUT_3_VOLUME:
+	case ARIZONA_SLIMTX6MIX_INPUT_4_SOURCE:
+	case ARIZONA_SLIMTX6MIX_INPUT_4_VOLUME:
+	case ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE:
+	case ARIZONA_SLIMTX7MIX_INPUT_1_VOLUME:
+	case ARIZONA_SLIMTX7MIX_INPUT_2_SOURCE:
+	case ARIZONA_SLIMTX7MIX_INPUT_2_VOLUME:
+	case ARIZONA_SLIMTX7MIX_INPUT_3_SOURCE:
+	case ARIZONA_SLIMTX7MIX_INPUT_3_VOLUME:
+	case ARIZONA_SLIMTX7MIX_INPUT_4_SOURCE:
+	case ARIZONA_SLIMTX7MIX_INPUT_4_VOLUME:
+	case ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE:
+	case ARIZONA_SLIMTX8MIX_INPUT_1_VOLUME:
+	case ARIZONA_SLIMTX8MIX_INPUT_2_SOURCE:
+	case ARIZONA_SLIMTX8MIX_INPUT_2_VOLUME:
+	case ARIZONA_SLIMTX8MIX_INPUT_3_SOURCE:
+	case ARIZONA_SLIMTX8MIX_INPUT_3_VOLUME:
+	case ARIZONA_SLIMTX8MIX_INPUT_4_SOURCE:
+	case ARIZONA_SLIMTX8MIX_INPUT_4_VOLUME:
+	case ARIZONA_EQ1MIX_INPUT_1_SOURCE:
+	case ARIZONA_EQ1MIX_INPUT_1_VOLUME:
+	case ARIZONA_EQ1MIX_INPUT_2_SOURCE:
+	case ARIZONA_EQ1MIX_INPUT_2_VOLUME:
+	case ARIZONA_EQ1MIX_INPUT_3_SOURCE:
+	case ARIZONA_EQ1MIX_INPUT_3_VOLUME:
+	case ARIZONA_EQ1MIX_INPUT_4_SOURCE:
+	case ARIZONA_EQ1MIX_INPUT_4_VOLUME:
+	case ARIZONA_EQ2MIX_INPUT_1_SOURCE:
+	case ARIZONA_EQ2MIX_INPUT_1_VOLUME:
+	case ARIZONA_EQ2MIX_INPUT_2_SOURCE:
+	case ARIZONA_EQ2MIX_INPUT_2_VOLUME:
+	case ARIZONA_EQ2MIX_INPUT_3_SOURCE:
+	case ARIZONA_EQ2MIX_INPUT_3_VOLUME:
+	case ARIZONA_EQ2MIX_INPUT_4_SOURCE:
+	case ARIZONA_EQ2MIX_INPUT_4_VOLUME:
+	case ARIZONA_EQ3MIX_INPUT_1_SOURCE:
+	case ARIZONA_EQ3MIX_INPUT_1_VOLUME:
+	case ARIZONA_EQ3MIX_INPUT_2_SOURCE:
+	case ARIZONA_EQ3MIX_INPUT_2_VOLUME:
+	case ARIZONA_EQ3MIX_INPUT_3_SOURCE:
+	case ARIZONA_EQ3MIX_INPUT_3_VOLUME:
+	case ARIZONA_EQ3MIX_INPUT_4_SOURCE:
+	case ARIZONA_EQ3MIX_INPUT_4_VOLUME:
+	case ARIZONA_EQ4MIX_INPUT_1_SOURCE:
+	case ARIZONA_EQ4MIX_INPUT_1_VOLUME:
+	case ARIZONA_EQ4MIX_INPUT_2_SOURCE:
+	case ARIZONA_EQ4MIX_INPUT_2_VOLUME:
+	case ARIZONA_EQ4MIX_INPUT_3_SOURCE:
+	case ARIZONA_EQ4MIX_INPUT_3_VOLUME:
+	case ARIZONA_EQ4MIX_INPUT_4_SOURCE:
+	case ARIZONA_EQ4MIX_INPUT_4_VOLUME:
+	case ARIZONA_DRC1LMIX_INPUT_1_SOURCE:
+	case ARIZONA_DRC1LMIX_INPUT_1_VOLUME:
+	case ARIZONA_DRC1LMIX_INPUT_2_SOURCE:
+	case ARIZONA_DRC1LMIX_INPUT_2_VOLUME:
+	case ARIZONA_DRC1LMIX_INPUT_3_SOURCE:
+	case ARIZONA_DRC1LMIX_INPUT_3_VOLUME:
+	case ARIZONA_DRC1LMIX_INPUT_4_SOURCE:
+	case ARIZONA_DRC1LMIX_INPUT_4_VOLUME:
+	case ARIZONA_DRC1RMIX_INPUT_1_SOURCE:
+	case ARIZONA_DRC1RMIX_INPUT_1_VOLUME:
+	case ARIZONA_DRC1RMIX_INPUT_2_SOURCE:
+	case ARIZONA_DRC1RMIX_INPUT_2_VOLUME:
+	case ARIZONA_DRC1RMIX_INPUT_3_SOURCE:
+	case ARIZONA_DRC1RMIX_INPUT_3_VOLUME:
+	case ARIZONA_DRC1RMIX_INPUT_4_SOURCE:
+	case ARIZONA_DRC1RMIX_INPUT_4_VOLUME:
+	case ARIZONA_HPLP1MIX_INPUT_1_SOURCE:
+	case ARIZONA_HPLP1MIX_INPUT_1_VOLUME:
+	case ARIZONA_HPLP1MIX_INPUT_2_SOURCE:
+	case ARIZONA_HPLP1MIX_INPUT_2_VOLUME:
+	case ARIZONA_HPLP1MIX_INPUT_3_SOURCE:
+	case ARIZONA_HPLP1MIX_INPUT_3_VOLUME:
+	case ARIZONA_HPLP1MIX_INPUT_4_SOURCE:
+	case ARIZONA_HPLP1MIX_INPUT_4_VOLUME:
+	case ARIZONA_HPLP2MIX_INPUT_1_SOURCE:
+	case ARIZONA_HPLP2MIX_INPUT_1_VOLUME:
+	case ARIZONA_HPLP2MIX_INPUT_2_SOURCE:
+	case ARIZONA_HPLP2MIX_INPUT_2_VOLUME:
+	case ARIZONA_HPLP2MIX_INPUT_3_SOURCE:
+	case ARIZONA_HPLP2MIX_INPUT_3_VOLUME:
+	case ARIZONA_HPLP2MIX_INPUT_4_SOURCE:
+	case ARIZONA_HPLP2MIX_INPUT_4_VOLUME:
+	case ARIZONA_HPLP3MIX_INPUT_1_SOURCE:
+	case ARIZONA_HPLP3MIX_INPUT_1_VOLUME:
+	case ARIZONA_HPLP3MIX_INPUT_2_SOURCE:
+	case ARIZONA_HPLP3MIX_INPUT_2_VOLUME:
+	case ARIZONA_HPLP3MIX_INPUT_3_SOURCE:
+	case ARIZONA_HPLP3MIX_INPUT_3_VOLUME:
+	case ARIZONA_HPLP3MIX_INPUT_4_SOURCE:
+	case ARIZONA_HPLP3MIX_INPUT_4_VOLUME:
+	case ARIZONA_HPLP4MIX_INPUT_1_SOURCE:
+	case ARIZONA_HPLP4MIX_INPUT_1_VOLUME:
+	case ARIZONA_HPLP4MIX_INPUT_2_SOURCE:
+	case ARIZONA_HPLP4MIX_INPUT_2_VOLUME:
+	case ARIZONA_HPLP4MIX_INPUT_3_SOURCE:
+	case ARIZONA_HPLP4MIX_INPUT_3_VOLUME:
+	case ARIZONA_HPLP4MIX_INPUT_4_SOURCE:
+	case ARIZONA_HPLP4MIX_INPUT_4_VOLUME:
+	case ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE:
+	case ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE:
+	case ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE:
+	case ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE:
+	case ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE:
+	case ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE:
+	case ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE:
+	case ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE:
+	case ARIZONA_GPIO1_CTRL:
+	case ARIZONA_GPIO2_CTRL:
+	case ARIZONA_GPIO3_CTRL:
+	case ARIZONA_GPIO4_CTRL:
+	case ARIZONA_GPIO5_CTRL:
+	case ARIZONA_IRQ_CTRL_1:
+	case ARIZONA_GPIO_DEBOUNCE_CONFIG:
+	case ARIZONA_MISC_PAD_CTRL_1:
+	case ARIZONA_MISC_PAD_CTRL_2:
+	case ARIZONA_MISC_PAD_CTRL_3:
+	case ARIZONA_MISC_PAD_CTRL_4:
+	case ARIZONA_MISC_PAD_CTRL_5:
+	case ARIZONA_INTERRUPT_STATUS_1:
+	case ARIZONA_INTERRUPT_STATUS_2:
+	case ARIZONA_INTERRUPT_STATUS_3:
+	case ARIZONA_INTERRUPT_STATUS_4:
+	case ARIZONA_INTERRUPT_STATUS_5:
+	case ARIZONA_INTERRUPT_STATUS_1_MASK:
+	case ARIZONA_INTERRUPT_STATUS_3_MASK:
+	case ARIZONA_INTERRUPT_STATUS_4_MASK:
+	case ARIZONA_INTERRUPT_STATUS_5_MASK:
+	case ARIZONA_INTERRUPT_CONTROL:
+	case ARIZONA_IRQ2_STATUS_1:
+	case ARIZONA_IRQ2_STATUS_3:
+	case ARIZONA_IRQ2_STATUS_4:
+	case ARIZONA_IRQ2_STATUS_5:
+	case ARIZONA_IRQ2_STATUS_1_MASK:
+	case ARIZONA_IRQ2_STATUS_3_MASK:
+	case ARIZONA_IRQ2_STATUS_4_MASK:
+	case ARIZONA_IRQ2_STATUS_5_MASK:
+	case ARIZONA_IRQ2_CONTROL:
+	case ARIZONA_INTERRUPT_RAW_STATUS_3:
+	case ARIZONA_INTERRUPT_RAW_STATUS_4:
+	case ARIZONA_INTERRUPT_RAW_STATUS_5:
+	case ARIZONA_INTERRUPT_RAW_STATUS_6:
+	case ARIZONA_INTERRUPT_RAW_STATUS_7:
+	case ARIZONA_INTERRUPT_RAW_STATUS_8:
+	case ARIZONA_IRQ_PIN_STATUS:
+	case ARIZONA_AOD_WKUP_AND_TRIG:
+	case ARIZONA_AOD_IRQ1:
+	case ARIZONA_AOD_IRQ2:
+	case ARIZONA_AOD_IRQ_MASK_IRQ1:
+	case ARIZONA_AOD_IRQ_MASK_IRQ2:
+	case ARIZONA_AOD_IRQ_RAW_STATUS:
+	case ARIZONA_JACK_DETECT_DEBOUNCE:
+	case ARIZONA_FX_CTRL1:
+	case ARIZONA_FX_CTRL2:
+	case ARIZONA_EQ1_1:
+	case ARIZONA_EQ1_2:
+	case ARIZONA_EQ1_3:
+	case ARIZONA_EQ1_4:
+	case ARIZONA_EQ1_5:
+	case ARIZONA_EQ1_6:
+	case ARIZONA_EQ1_7:
+	case ARIZONA_EQ1_8:
+	case ARIZONA_EQ1_9:
+	case ARIZONA_EQ1_10:
+	case ARIZONA_EQ1_11:
+	case ARIZONA_EQ1_12:
+	case ARIZONA_EQ1_13:
+	case ARIZONA_EQ1_14:
+	case ARIZONA_EQ1_15:
+	case ARIZONA_EQ1_16:
+	case ARIZONA_EQ1_17:
+	case ARIZONA_EQ1_18:
+	case ARIZONA_EQ1_19:
+	case ARIZONA_EQ1_20:
+	case ARIZONA_EQ1_21:
+	case ARIZONA_EQ2_1:
+	case ARIZONA_EQ2_2:
+	case ARIZONA_EQ2_3:
+	case ARIZONA_EQ2_4:
+	case ARIZONA_EQ2_5:
+	case ARIZONA_EQ2_6:
+	case ARIZONA_EQ2_7:
+	case ARIZONA_EQ2_8:
+	case ARIZONA_EQ2_9:
+	case ARIZONA_EQ2_10:
+	case ARIZONA_EQ2_11:
+	case ARIZONA_EQ2_12:
+	case ARIZONA_EQ2_13:
+	case ARIZONA_EQ2_14:
+	case ARIZONA_EQ2_15:
+	case ARIZONA_EQ2_16:
+	case ARIZONA_EQ2_17:
+	case ARIZONA_EQ2_18:
+	case ARIZONA_EQ2_19:
+	case ARIZONA_EQ2_20:
+	case ARIZONA_EQ2_21:
+	case ARIZONA_EQ3_1:
+	case ARIZONA_EQ3_2:
+	case ARIZONA_EQ3_3:
+	case ARIZONA_EQ3_4:
+	case ARIZONA_EQ3_5:
+	case ARIZONA_EQ3_6:
+	case ARIZONA_EQ3_7:
+	case ARIZONA_EQ3_8:
+	case ARIZONA_EQ3_9:
+	case ARIZONA_EQ3_10:
+	case ARIZONA_EQ3_11:
+	case ARIZONA_EQ3_12:
+	case ARIZONA_EQ3_13:
+	case ARIZONA_EQ3_14:
+	case ARIZONA_EQ3_15:
+	case ARIZONA_EQ3_16:
+	case ARIZONA_EQ3_17:
+	case ARIZONA_EQ3_18:
+	case ARIZONA_EQ3_19:
+	case ARIZONA_EQ3_20:
+	case ARIZONA_EQ3_21:
+	case ARIZONA_EQ4_1:
+	case ARIZONA_EQ4_2:
+	case ARIZONA_EQ4_3:
+	case ARIZONA_EQ4_4:
+	case ARIZONA_EQ4_5:
+	case ARIZONA_EQ4_6:
+	case ARIZONA_EQ4_7:
+	case ARIZONA_EQ4_8:
+	case ARIZONA_EQ4_9:
+	case ARIZONA_EQ4_10:
+	case ARIZONA_EQ4_11:
+	case ARIZONA_EQ4_12:
+	case ARIZONA_EQ4_13:
+	case ARIZONA_EQ4_14:
+	case ARIZONA_EQ4_15:
+	case ARIZONA_EQ4_16:
+	case ARIZONA_EQ4_17:
+	case ARIZONA_EQ4_18:
+	case ARIZONA_EQ4_19:
+	case ARIZONA_EQ4_20:
+	case ARIZONA_EQ4_21:
+	case ARIZONA_DRC1_CTRL1:
+	case ARIZONA_DRC1_CTRL2:
+	case ARIZONA_DRC1_CTRL3:
+	case ARIZONA_DRC1_CTRL4:
+	case ARIZONA_DRC1_CTRL5:
+	case ARIZONA_HPLPF1_1:
+	case ARIZONA_HPLPF1_2:
+	case ARIZONA_HPLPF2_1:
+	case ARIZONA_HPLPF2_2:
+	case ARIZONA_HPLPF3_1:
+	case ARIZONA_HPLPF3_2:
+	case ARIZONA_HPLPF4_1:
+	case ARIZONA_HPLPF4_2:
+	case ARIZONA_ISRC_1_CTRL_1:
+	case ARIZONA_ISRC_1_CTRL_2:
+	case ARIZONA_ISRC_1_CTRL_3:
+	case ARIZONA_ISRC_2_CTRL_1:
+	case ARIZONA_ISRC_2_CTRL_2:
+	case ARIZONA_ISRC_2_CTRL_3:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool wm8997_volatile_register(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case ARIZONA_SOFTWARE_RESET:
+	case ARIZONA_DEVICE_REVISION:
+	case ARIZONA_HAPTICS_STATUS:
+	case ARIZONA_SAMPLE_RATE_1_STATUS:
+	case ARIZONA_SAMPLE_RATE_2_STATUS:
+	case ARIZONA_SAMPLE_RATE_3_STATUS:
+	case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS:
+	case ARIZONA_MIC_DETECT_3:
+	case ARIZONA_HEADPHONE_DETECT_2:
+	case ARIZONA_INPUT_ENABLES_STATUS:
+	case ARIZONA_OUTPUT_STATUS_1:
+	case ARIZONA_RAW_OUTPUT_STATUS_1:
+	case ARIZONA_SLIMBUS_RX_PORT_STATUS:
+	case ARIZONA_SLIMBUS_TX_PORT_STATUS:
+	case ARIZONA_INTERRUPT_STATUS_1:
+	case ARIZONA_INTERRUPT_STATUS_2:
+	case ARIZONA_INTERRUPT_STATUS_3:
+	case ARIZONA_INTERRUPT_STATUS_4:
+	case ARIZONA_INTERRUPT_STATUS_5:
+	case ARIZONA_IRQ2_STATUS_1:
+	case ARIZONA_IRQ2_STATUS_3:
+	case ARIZONA_IRQ2_STATUS_4:
+	case ARIZONA_IRQ2_STATUS_5:
+	case ARIZONA_INTERRUPT_RAW_STATUS_3:
+	case ARIZONA_INTERRUPT_RAW_STATUS_4:
+	case ARIZONA_INTERRUPT_RAW_STATUS_5:
+	case ARIZONA_INTERRUPT_RAW_STATUS_6:
+	case ARIZONA_INTERRUPT_RAW_STATUS_7:
+	case ARIZONA_INTERRUPT_RAW_STATUS_8:
+	case ARIZONA_IRQ_PIN_STATUS:
+	case ARIZONA_AOD_WKUP_AND_TRIG:
+	case ARIZONA_AOD_IRQ1:
+	case ARIZONA_AOD_IRQ2:
+	case ARIZONA_AOD_IRQ_RAW_STATUS:
+	case ARIZONA_FX_CTRL2:
+		return true;
+	default:
+		return false;
+	}
+}
+
+#define WM8997_MAX_REGISTER 0x31ff
+
+const struct regmap_config wm8997_i2c_regmap = {
+	.reg_bits = 32,
+	.val_bits = 16,
+
+	.max_register = WM8997_MAX_REGISTER,
+	.readable_reg = wm8997_readable_register,
+	.volatile_reg = wm8997_volatile_register,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8997_reg_default,
+	.num_reg_defaults = ARRAY_SIZE(wm8997_reg_default),
+};
+EXPORT_SYMBOL_GPL(wm8997_i2c_regmap);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/ad525x_dpot.c linux-libre-3.11-rc7-gnu/drivers/misc/ad525x_dpot.c
--- linux-libre-3.10-gnu/drivers/misc/ad525x_dpot.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/ad525x_dpot.c	2013-08-25 20:43:22.000000000 -0400
@@ -470,7 +470,7 @@ static ssize_t sysfs_set_reg(struct devi
 		!test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask))
 		return -EPERM;
 
-	err = strict_strtoul(buf, 10, &value);
+	err = kstrtoul(buf, 10, &value);
 	if (err)
 		return err;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/apds9802als.c linux-libre-3.11-rc7-gnu/drivers/misc/apds9802als.c
--- linux-libre-3.10-gnu/drivers/misc/apds9802als.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/apds9802als.c	2013-08-25 20:43:22.000000000 -0400
@@ -126,8 +126,9 @@ static ssize_t als_sensing_range_store(s
 	int ret_val;
 	unsigned long val;
 
-	if (strict_strtoul(buf, 10, &val))
-		return -EINVAL;
+	ret_val = kstrtoul(buf, 10, &val);
+	if (ret_val)
+		return ret_val;
 
 	if (val < 4096)
 		val = 1;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/apds990x.c linux-libre-3.11-rc7-gnu/drivers/misc/apds990x.c
--- linux-libre-3.10-gnu/drivers/misc/apds990x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/apds990x.c	2013-08-25 20:43:22.000000000 -0400
@@ -696,9 +696,11 @@ static ssize_t apds990x_lux_calib_store(
 {
 	struct apds990x_chip *chip = dev_get_drvdata(dev);
 	unsigned long value;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	chip->lux_calib = value;
 
@@ -759,8 +761,9 @@ static ssize_t apds990x_rate_store(struc
 	unsigned long value;
 	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	mutex_lock(&chip->mutex);
 	ret = apds990x_set_arate(chip, value);
@@ -813,9 +816,11 @@ static ssize_t apds990x_prox_enable_stor
 {
 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
 	unsigned long value;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	mutex_lock(&chip->mutex);
 
@@ -892,11 +897,12 @@ static ssize_t apds990x_lux_thresh_below
 static ssize_t apds990x_set_lux_thresh(struct apds990x_chip *chip, u32 *target,
 				const char *buf)
 {
-	int ret = 0;
 	unsigned long thresh;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &thresh))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &thresh);
+	if (ret)
+		return ret;
 
 	if (thresh > APDS_RANGE)
 		return -EINVAL;
@@ -957,9 +963,11 @@ static ssize_t apds990x_prox_threshold_s
 {
 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
 	unsigned long value;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	if ((value > APDS_RANGE) || (value == 0) ||
 		(value < APDS_PROX_HYSTERESIS))
@@ -990,9 +998,12 @@ static ssize_t apds990x_power_state_stor
 {
 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
 	unsigned long value;
+	int ret;
+
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
 	if (value) {
 		pm_runtime_get_sync(dev);
 		mutex_lock(&chip->mutex);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/arm-charlcd.c linux-libre-3.11-rc7-gnu/drivers/misc/arm-charlcd.c
--- linux-libre-3.10-gnu/drivers/misc/arm-charlcd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/arm-charlcd.c	2013-08-25 20:43:22.000000000 -0400
@@ -291,7 +291,7 @@ static int __init charlcd_probe(struct p
 	lcd->virtbase = ioremap(lcd->phybase, lcd->physize);
 	if (!lcd->virtbase) {
 		ret = -ENOMEM;
-		goto out_no_remap;
+		goto out_no_memregion;
 	}
 
 	lcd->irq = platform_get_irq(pdev, 0);
@@ -320,8 +320,6 @@ static int __init charlcd_probe(struct p
 
 out_no_irq:
 	iounmap(lcd->virtbase);
-out_no_remap:
-	platform_set_drvdata(pdev, NULL);
 out_no_memregion:
 	release_mem_region(lcd->phybase, SZ_4K);
 out_no_resource:
@@ -337,7 +335,6 @@ static int __exit charlcd_remove(struct
 		free_irq(lcd->irq, lcd);
 		iounmap(lcd->virtbase);
 		release_mem_region(lcd->phybase, lcd->physize);
-		platform_set_drvdata(pdev, NULL);
 		kfree(lcd);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/atmel-ssc.c linux-libre-3.11-rc7-gnu/drivers/misc/atmel-ssc.c
--- linux-libre-3.10-gnu/drivers/misc/atmel-ssc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/atmel-ssc.c	2013-08-25 20:43:22.000000000 -0400
@@ -58,7 +58,7 @@ struct ssc_device *ssc_request(unsigned
 	ssc->user++;
 	spin_unlock(&user_lock);
 
-	clk_enable(ssc->clk);
+	clk_prepare_enable(ssc->clk);
 
 	return ssc;
 }
@@ -66,14 +66,19 @@ EXPORT_SYMBOL(ssc_request);
 
 void ssc_free(struct ssc_device *ssc)
 {
+	bool disable_clk = true;
+
 	spin_lock(&user_lock);
-	if (ssc->user) {
+	if (ssc->user)
 		ssc->user--;
-		clk_disable(ssc->clk);
-	} else {
+	else {
+		disable_clk = false;
 		dev_dbg(&ssc->pdev->dev, "device already free\n");
 	}
 	spin_unlock(&user_lock);
+
+	if (disable_clk)
+		clk_disable_unprepare(ssc->clk);
 }
 EXPORT_SYMBOL(ssc_free);
 
@@ -167,10 +172,10 @@ static int ssc_probe(struct platform_dev
 	}
 
 	/* disable all interrupts */
-	clk_enable(ssc->clk);
+	clk_prepare_enable(ssc->clk);
 	ssc_writel(ssc->regs, IDR, -1);
 	ssc_readl(ssc->regs, SR);
-	clk_disable(ssc->clk);
+	clk_disable_unprepare(ssc->clk);
 
 	ssc->irq = platform_get_irq(pdev, 0);
 	if (!ssc->irq) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/bh1770glc.c linux-libre-3.11-rc7-gnu/drivers/misc/bh1770glc.c
--- linux-libre-3.10-gnu/drivers/misc/bh1770glc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/bh1770glc.c	2013-08-25 20:43:22.000000000 -0400
@@ -651,8 +651,9 @@ static ssize_t bh1770_power_state_store(
 	unsigned long value;
 	ssize_t ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	mutex_lock(&chip->mutex);
 	if (value) {
@@ -726,9 +727,11 @@ static ssize_t bh1770_prox_enable_store(
 {
 	struct bh1770_chip *chip =  dev_get_drvdata(dev);
 	unsigned long value;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	mutex_lock(&chip->mutex);
 	/* Assume no proximity. Sensor will tell real state soon */
@@ -824,9 +827,11 @@ static ssize_t bh1770_set_prox_rate_abov
 {
 	struct bh1770_chip *chip =  dev_get_drvdata(dev);
 	unsigned long value;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	mutex_lock(&chip->mutex);
 	chip->prox_rate_threshold = bh1770_prox_rate_validate(value);
@@ -840,9 +845,11 @@ static ssize_t bh1770_set_prox_rate_belo
 {
 	struct bh1770_chip *chip =  dev_get_drvdata(dev);
 	unsigned long value;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	mutex_lock(&chip->mutex);
 	chip->prox_rate = bh1770_prox_rate_validate(value);
@@ -865,8 +872,10 @@ static ssize_t bh1770_set_prox_thres(str
 	unsigned long value;
 	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
+
 	if (value > BH1770_PROX_RANGE)
 		return -EINVAL;
 
@@ -893,9 +902,11 @@ static ssize_t bh1770_prox_persistence_s
 {
 	struct bh1770_chip *chip = dev_get_drvdata(dev);
 	unsigned long value;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	if (value > BH1770_PROX_MAX_PERSISTENCE)
 		return -EINVAL;
@@ -918,9 +929,11 @@ static ssize_t bh1770_prox_abs_thres_sto
 {
 	struct bh1770_chip *chip = dev_get_drvdata(dev);
 	unsigned long value;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	if (value > BH1770_PROX_RANGE)
 		return -EINVAL;
@@ -963,9 +976,11 @@ static ssize_t bh1770_lux_calib_store(st
 	unsigned long value;
 	u32 old_calib;
 	u32 new_corr;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &value))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
 
 	mutex_lock(&chip->mutex);
 	old_calib = chip->lux_calib;
@@ -1012,8 +1027,9 @@ static ssize_t bh1770_set_lux_rate(struc
 	unsigned long rate_hz;
 	int ret, i;
 
-	if (strict_strtoul(buf, 0, &rate_hz))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &rate_hz);
+	if (ret)
+		return ret;
 
 	for (i = 0; i < ARRAY_SIZE(lux_rates_hz) - 1; i++)
 		if (rate_hz >= lux_rates_hz[i])
@@ -1047,11 +1063,12 @@ static ssize_t bh1770_get_lux_thresh_bel
 static ssize_t bh1770_set_lux_thresh(struct bh1770_chip *chip, u16 *target,
 				const char *buf)
 {
-	int ret = 0;
 	unsigned long thresh;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &thresh))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &thresh);
+	if (ret)
+		return ret;
 
 	if (thresh > BH1770_LUX_RANGE)
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/bh1780gli.c linux-libre-3.11-rc7-gnu/drivers/misc/bh1780gli.c
--- linux-libre-3.10-gnu/drivers/misc/bh1780gli.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/bh1780gli.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,7 +107,7 @@ static ssize_t bh1780_store_power_state(
 	unsigned long val;
 	int error;
 
-	error = strict_strtoul(buf, 0, &val);
+	error = kstrtoul(buf, 0, &val);
 	if (error)
 		return error;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/carma/carma-fpga.c linux-libre-3.11-rc7-gnu/drivers/misc/carma/carma-fpga.c
--- linux-libre-3.10-gnu/drivers/misc/carma/carma-fpga.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/carma/carma-fpga.c	2013-08-25 20:43:22.000000000 -0400
@@ -1002,10 +1002,10 @@ static ssize_t data_en_set(struct device
 	unsigned long enable;
 	int ret;
 
-	ret = strict_strtoul(buf, 0, &enable);
+	ret = kstrtoul(buf, 0, &enable);
 	if (ret) {
 		dev_err(priv->dev, "unable to parse enable input\n");
-		return -EINVAL;
+		return ret;
 	}
 
 	/* protect against concurrent enable/disable */
@@ -1296,7 +1296,7 @@ static int data_of_probe(struct platform
 		goto out_return;
 	}
 
-	dev_set_drvdata(&op->dev, priv);
+	platform_set_drvdata(op, priv);
 	priv->dev = &op->dev;
 	kref_init(&priv->ref);
 	mutex_init(&priv->mutex);
@@ -1400,7 +1400,7 @@ out_return:
 
 static int data_of_remove(struct platform_device *op)
 {
-	struct fpga_device *priv = dev_get_drvdata(&op->dev);
+	struct fpga_device *priv = platform_get_drvdata(op);
 	struct device *this_device = priv->miscdev.this_device;
 
 	/* remove all sysfs files, now the device cannot be re-enabled */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/carma/carma-fpga-program.c linux-libre-3.11-rc7-gnu/drivers/misc/carma/carma-fpga-program.c
--- linux-libre-3.10-gnu/drivers/misc/carma/carma-fpga-program.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/carma/carma-fpga-program.c	2013-08-25 20:43:22.000000000 -0400
@@ -830,8 +830,9 @@ static ssize_t penable_store(struct devi
 	unsigned long val;
 	int ret;
 
-	if (strict_strtoul(buf, 0, &val))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &val);
+	if (ret)
+		return ret;
 
 	if (val) {
 		ret = fpga_enable_power_supplies(priv);
@@ -859,8 +860,9 @@ static ssize_t program_store(struct devi
 	unsigned long val;
 	int ret;
 
-	if (strict_strtoul(buf, 0, &val))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &val);
+	if (ret)
+		return ret;
 
 	/* We can't have an image writer and be programming simultaneously */
 	if (mutex_lock_interruptible(&priv->lock))
@@ -919,7 +921,7 @@ static bool dma_filter(struct dma_chan *
 
 static int fpga_of_remove(struct platform_device *op)
 {
-	struct fpga_dev *priv = dev_get_drvdata(&op->dev);
+	struct fpga_dev *priv = platform_get_drvdata(op);
 	struct device *this_device = priv->miscdev.this_device;
 
 	sysfs_remove_group(&this_device->kobj, &fpga_attr_group);
@@ -969,7 +971,7 @@ static int fpga_of_probe(struct platform
 
 	kref_init(&priv->ref);
 
-	dev_set_drvdata(&op->dev, priv);
+	platform_set_drvdata(op, priv);
 	priv->dev = &op->dev;
 	mutex_init(&priv->lock);
 	init_completion(&priv->completion);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/dummy-irq.c linux-libre-3.11-rc7-gnu/drivers/misc/dummy-irq.c
--- linux-libre-3.10-gnu/drivers/misc/dummy-irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/dummy-irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,7 +26,7 @@ static irqreturn_t dummy_interrupt(int i
 	static int count = 0;
 
 	if (count == 0) {
-		printk(KERN_INFO "dummy-irq: interrupt occured on IRQ %d\n",
+		printk(KERN_INFO "dummy-irq: interrupt occurred on IRQ %d\n",
 				irq);
 		count++;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/eeprom/at24.c linux-libre-3.11-rc7-gnu/drivers/misc/eeprom/at24.c
--- linux-libre-3.10-gnu/drivers/misc/eeprom/at24.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/eeprom/at24.c	2013-08-25 20:43:22.000000000 -0400
@@ -492,10 +492,9 @@ static int at24_probe(struct i2c_client
 	if (client->dev.platform_data) {
 		chip = *(struct at24_platform_data *)client->dev.platform_data;
 	} else {
-		if (!id->driver_data) {
-			err = -ENODEV;
-			goto err_out;
-		}
+		if (!id->driver_data)
+			return -ENODEV;
+
 		magic = id->driver_data;
 		chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN));
 		magic >>= AT24_SIZE_BYTELEN;
@@ -519,8 +518,7 @@ static int at24_probe(struct i2c_client
 			"byte_len looks suspicious (no power of 2)!\n");
 	if (!chip.page_size) {
 		dev_err(&client->dev, "page_size must not be 0!\n");
-		err = -EINVAL;
-		goto err_out;
+		return -EINVAL;
 	}
 	if (!is_power_of_2(chip.page_size))
 		dev_warn(&client->dev,
@@ -528,10 +526,9 @@ static int at24_probe(struct i2c_client
 
 	/* Use I2C operations unless we're stuck with SMBus extensions. */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		if (chip.flags & AT24_FLAG_ADDR16) {
-			err = -EPFNOSUPPORT;
-			goto err_out;
-		}
+		if (chip.flags & AT24_FLAG_ADDR16)
+			return -EPFNOSUPPORT;
+
 		if (i2c_check_functionality(client->adapter,
 				I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
 			use_smbus = I2C_SMBUS_I2C_BLOCK_DATA;
@@ -542,8 +539,7 @@ static int at24_probe(struct i2c_client
 				I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
 			use_smbus = I2C_SMBUS_BYTE_DATA;
 		} else {
-			err = -EPFNOSUPPORT;
-			goto err_out;
+			return -EPFNOSUPPORT;
 		}
 	}
 
@@ -553,12 +549,10 @@ static int at24_probe(struct i2c_client
 		num_addresses =	DIV_ROUND_UP(chip.byte_len,
 			(chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256);
 
-	at24 = kzalloc(sizeof(struct at24_data) +
+	at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) +
 		num_addresses * sizeof(struct i2c_client *), GFP_KERNEL);
-	if (!at24) {
-		err = -ENOMEM;
-		goto err_out;
-	}
+	if (!at24)
+		return -ENOMEM;
 
 	mutex_init(&at24->lock);
 	at24->use_smbus = use_smbus;
@@ -596,11 +590,10 @@ static int at24_probe(struct i2c_client
 			at24->write_max = write_max;
 
 			/* buffer (data + address at the beginning) */
-			at24->writebuf = kmalloc(write_max + 2, GFP_KERNEL);
-			if (!at24->writebuf) {
-				err = -ENOMEM;
-				goto err_struct;
-			}
+			at24->writebuf = devm_kzalloc(&client->dev,
+				write_max + 2, GFP_KERNEL);
+			if (!at24->writebuf)
+				return -ENOMEM;
 		} else {
 			dev_warn(&client->dev,
 				"cannot write due to controller restrictions.");
@@ -648,11 +641,6 @@ err_clients:
 		if (at24->client[i])
 			i2c_unregister_device(at24->client[i]);
 
-	kfree(at24->writebuf);
-err_struct:
-	kfree(at24);
-err_out:
-	dev_dbg(&client->dev, "probe error %d\n", err);
 	return err;
 }
 
@@ -667,8 +655,6 @@ static int at24_remove(struct i2c_client
 	for (i = 1; i < at24->num_addresses; i++)
 		i2c_unregister_device(at24->client[i]);
 
-	kfree(at24->writebuf);
-	kfree(at24);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/eeprom/at25.c linux-libre-3.11-rc7-gnu/drivers/misc/eeprom/at25.c
--- linux-libre-3.10-gnu/drivers/misc/eeprom/at25.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/eeprom/at25.c	2013-08-25 20:43:22.000000000 -0400
@@ -371,11 +371,10 @@ static int at25_probe(struct spi_device
 		if (np) {
 			err = at25_np_to_chip(&spi->dev, np, &chip);
 			if (err)
-				goto fail;
+				return err;
 		} else {
 			dev_err(&spi->dev, "Error: no chip description\n");
-			err = -ENODEV;
-			goto fail;
+			return -ENODEV;
 		}
 	} else
 		chip = *(struct spi_eeprom *)spi->dev.platform_data;
@@ -389,8 +388,7 @@ static int at25_probe(struct spi_device
 		addrlen = 3;
 	else {
 		dev_dbg(&spi->dev, "unsupported address type\n");
-		err = -EINVAL;
-		goto fail;
+		return -EINVAL;
 	}
 
 	/* Ping the chip ... the status register is pretty portable,
@@ -400,14 +398,12 @@ static int at25_probe(struct spi_device
 	sr = spi_w8r8(spi, AT25_RDSR);
 	if (sr < 0 || sr & AT25_SR_nRDY) {
 		dev_dbg(&spi->dev, "rdsr --> %d (%02x)\n", sr, sr);
-		err = -ENXIO;
-		goto fail;
+		return -ENXIO;
 	}
 
-	if (!(at25 = kzalloc(sizeof *at25, GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto fail;
-	}
+	at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL);
+	if (!at25)
+		return -ENOMEM;
 
 	mutex_init(&at25->lock);
 	at25->chip = chip;
@@ -439,7 +435,7 @@ static int at25_probe(struct spi_device
 
 	err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin);
 	if (err)
-		goto fail;
+		return err;
 
 	if (chip.setup)
 		chip.setup(&at25->mem, chip.context);
@@ -453,10 +449,6 @@ static int at25_probe(struct spi_device
 		(chip.flags & EE_READONLY) ? " (readonly)" : "",
 		at25->chip.page_size);
 	return 0;
-fail:
-	dev_dbg(&spi->dev, "probe err %d\n", err);
-	kfree(at25);
-	return err;
 }
 
 static int at25_remove(struct spi_device *spi)
@@ -465,7 +457,6 @@ static int at25_remove(struct spi_device
 
 	at25 = spi_get_drvdata(spi);
 	sysfs_remove_bin_file(&spi->dev.kobj, &at25->bin);
-	kfree(at25);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/ep93xx_pwm.c linux-libre-3.11-rc7-gnu/drivers/misc/ep93xx_pwm.c
--- linux-libre-3.10-gnu/drivers/misc/ep93xx_pwm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/ep93xx_pwm.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,63 +39,6 @@ struct ep93xx_pwm {
 	u32		duty_percent;
 };
 
-static inline void ep93xx_pwm_writel(struct ep93xx_pwm *pwm,
-		unsigned int val, unsigned int off)
-{
-	__raw_writel(val, pwm->mmio_base + off);
-}
-
-static inline unsigned int ep93xx_pwm_readl(struct ep93xx_pwm *pwm,
-		unsigned int off)
-{
-	return __raw_readl(pwm->mmio_base + off);
-}
-
-static inline void ep93xx_pwm_write_tc(struct ep93xx_pwm *pwm, u16 value)
-{
-	ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_TERM_COUNT);
-}
-
-static inline u16 ep93xx_pwm_read_tc(struct ep93xx_pwm *pwm)
-{
-	return ep93xx_pwm_readl(pwm, EP93XX_PWMx_TERM_COUNT);
-}
-
-static inline void ep93xx_pwm_write_dc(struct ep93xx_pwm *pwm, u16 value)
-{
-	ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_DUTY_CYCLE);
-}
-
-static inline void ep93xx_pwm_enable(struct ep93xx_pwm *pwm)
-{
-	ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_ENABLE);
-}
-
-static inline void ep93xx_pwm_disable(struct ep93xx_pwm *pwm)
-{
-	ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_ENABLE);
-}
-
-static inline int ep93xx_pwm_is_enabled(struct ep93xx_pwm *pwm)
-{
-	return ep93xx_pwm_readl(pwm, EP93XX_PWMx_ENABLE) & 0x1;
-}
-
-static inline void ep93xx_pwm_invert(struct ep93xx_pwm *pwm)
-{
-	ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_INVERT);
-}
-
-static inline void ep93xx_pwm_normal(struct ep93xx_pwm *pwm)
-{
-	ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_INVERT);
-}
-
-static inline int ep93xx_pwm_is_inverted(struct ep93xx_pwm *pwm)
-{
-	return ep93xx_pwm_readl(pwm, EP93XX_PWMx_INVERT) & 0x1;
-}
-
 /*
  * /sys/devices/platform/ep93xx-pwm.N
  *   /min_freq      read-only   minimum pwm output frequency
@@ -131,9 +74,9 @@ static ssize_t ep93xx_pwm_get_freq(struc
 	struct platform_device *pdev = to_platform_device(dev);
 	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
 
-	if (ep93xx_pwm_is_enabled(pwm)) {
+	if (readl(pwm->mmio_base + EP93XX_PWMx_ENABLE) & 0x1) {
 		unsigned long rate = clk_get_rate(pwm->clk);
-		u16 term = ep93xx_pwm_read_tc(pwm);
+		u16 term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
 
 		return sprintf(buf, "%ld\n", rate / (term + 1));
 	} else {
@@ -149,12 +92,12 @@ static ssize_t ep93xx_pwm_set_freq(struc
 	long val;
 	int err;
 
-	err = strict_strtol(buf, 10, &val);
+	err = kstrtol(buf, 10, &val);
 	if (err)
 		return -EINVAL;
 
 	if (val == 0) {
-		ep93xx_pwm_disable(pwm);
+		writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE);
 	} else if (val <= (clk_get_rate(pwm->clk) / 2)) {
 		u32 term, duty;
 
@@ -164,20 +107,20 @@ static ssize_t ep93xx_pwm_set_freq(struc
 		if (val < 1)
 			val = 1;
 
-		term = ep93xx_pwm_read_tc(pwm);
+		term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
 		duty = ((val + 1) * pwm->duty_percent / 100) - 1;
 
 		/* If pwm is running, order is important */
 		if (val > term) {
-			ep93xx_pwm_write_tc(pwm, val);
-			ep93xx_pwm_write_dc(pwm, duty);
+			writel(val, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
+			writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE);
 		} else {
-			ep93xx_pwm_write_dc(pwm, duty);
-			ep93xx_pwm_write_tc(pwm, val);
+			writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE);
+			writel(val, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
 		}
 
-		if (!ep93xx_pwm_is_enabled(pwm))
-			ep93xx_pwm_enable(pwm);
+		if (!readl(pwm->mmio_base + EP93XX_PWMx_ENABLE) & 0x1)
+			writel(0x1, pwm->mmio_base + EP93XX_PWMx_ENABLE);
 	} else {
 		return -EINVAL;
 	}
@@ -202,13 +145,15 @@ static ssize_t ep93xx_pwm_set_duty_perce
 	long val;
 	int err;
 
-	err = strict_strtol(buf, 10, &val);
+	err = kstrtol(buf, 10, &val);
 	if (err)
 		return -EINVAL;
 
 	if (val > 0 && val < 100) {
-		u32 term = ep93xx_pwm_read_tc(pwm);
-		ep93xx_pwm_write_dc(pwm, ((term + 1) * val / 100) - 1);
+		u32 term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
+		u32 duty = ((term + 1) * val / 100) - 1;
+
+		writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE);
 		pwm->duty_percent = val;
 		return count;
 	}
@@ -221,8 +166,9 @@ static ssize_t ep93xx_pwm_get_invert(str
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+	int inverted = readl(pwm->mmio_base + EP93XX_PWMx_INVERT) & 0x1;
 
-	return sprintf(buf, "%d\n", ep93xx_pwm_is_inverted(pwm));
+	return sprintf(buf, "%d\n", inverted);
 }
 
 static ssize_t ep93xx_pwm_set_invert(struct device *dev,
@@ -233,14 +179,14 @@ static ssize_t ep93xx_pwm_set_invert(str
 	long val;
 	int err;
 
-	err = strict_strtol(buf, 10, &val);
+	err = kstrtol(buf, 10, &val);
 	if (err)
 		return -EINVAL;
 
 	if (val == 0)
-		ep93xx_pwm_normal(pwm);
+		writel(0x0, pwm->mmio_base + EP93XX_PWMx_INVERT);
 	else if (val == 1)
-		ep93xx_pwm_invert(pwm);
+		writel(0x1, pwm->mmio_base + EP93XX_PWMx_INVERT);
 	else
 		return -EINVAL;
 
@@ -269,89 +215,55 @@ static const struct attribute_group ep93
 	.attrs	= ep93xx_pwm_attrs,
 };
 
-static int __init ep93xx_pwm_probe(struct platform_device *pdev)
+static int ep93xx_pwm_probe(struct platform_device *pdev)
 {
 	struct ep93xx_pwm *pwm;
 	struct resource *res;
-	int err;
+	int ret;
 
-	err = ep93xx_pwm_acquire_gpio(pdev);
-	if (err)
-		return err;
+	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
+	if (!pwm)
+		return -ENOMEM;
 
-	pwm = kzalloc(sizeof(struct ep93xx_pwm), GFP_KERNEL);
-	if (!pwm) {
-		err = -ENOMEM;
-		goto fail_no_mem;
-	}
+	pwm->clk = devm_clk_get(&pdev->dev, "pwm_clk");
+	if (IS_ERR(pwm->clk))
+		return PTR_ERR(pwm->clk);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		err = -ENXIO;
-		goto fail_no_mem_resource;
-	}
-
-	res = request_mem_region(res->start, resource_size(res), pdev->name);
-	if (res == NULL) {
-		err = -EBUSY;
-		goto fail_no_mem_resource;
-	}
-
-	pwm->mmio_base = ioremap(res->start, resource_size(res));
-	if (pwm->mmio_base == NULL) {
-		err = -ENXIO;
-		goto fail_no_ioremap;
-	}
+	pwm->mmio_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pwm->mmio_base))
+		return PTR_ERR(pwm->mmio_base);
 
-	err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
-	if (err)
-		goto fail_no_sysfs;
+	ret = ep93xx_pwm_acquire_gpio(pdev);
+	if (ret)
+		return ret;
 
-	pwm->clk = clk_get(&pdev->dev, "pwm_clk");
-	if (IS_ERR(pwm->clk)) {
-		err = PTR_ERR(pwm->clk);
-		goto fail_no_clk;
+	ret = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
+	if (ret) {
+		ep93xx_pwm_release_gpio(pdev);
+		return ret;
 	}
 
 	pwm->duty_percent = 50;
 
-	platform_set_drvdata(pdev, pwm);
-
 	/* disable pwm at startup. Avoids zero value. */
-	ep93xx_pwm_disable(pwm);
-	ep93xx_pwm_write_tc(pwm, EP93XX_PWM_MAX_COUNT);
-	ep93xx_pwm_write_dc(pwm, EP93XX_PWM_MAX_COUNT / 2);
+	writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE);
+	writel(EP93XX_PWM_MAX_COUNT, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT);
+	writel(EP93XX_PWM_MAX_COUNT/2, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE);
 
 	clk_enable(pwm->clk);
 
+	platform_set_drvdata(pdev, pwm);
 	return 0;
-
-fail_no_clk:
-	sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
-fail_no_sysfs:
-	iounmap(pwm->mmio_base);
-fail_no_ioremap:
-	release_mem_region(res->start, resource_size(res));
-fail_no_mem_resource:
-	kfree(pwm);
-fail_no_mem:
-	ep93xx_pwm_release_gpio(pdev);
-	return err;
 }
 
-static int __exit ep93xx_pwm_remove(struct platform_device *pdev)
+static int ep93xx_pwm_remove(struct platform_device *pdev)
 {
 	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
-	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-	ep93xx_pwm_disable(pwm);
+	writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE);
 	clk_disable(pwm->clk);
-	clk_put(pwm->clk);
-	platform_set_drvdata(pdev, NULL);
 	sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
-	iounmap(pwm->mmio_base);
-	release_mem_region(res->start, resource_size(res));
-	kfree(pwm);
 	ep93xx_pwm_release_gpio(pdev);
 
 	return 0;
@@ -362,10 +274,10 @@ static struct platform_driver ep93xx_pwm
 		.name	= "ep93xx-pwm",
 		.owner	= THIS_MODULE,
 	},
-	.remove		= __exit_p(ep93xx_pwm_remove),
+	.probe		= ep93xx_pwm_probe,
+	.remove		= ep93xx_pwm_remove,
 };
-
-module_platform_driver_probe(ep93xx_pwm_driver, ep93xx_pwm_probe);
+module_platform_driver(ep93xx_pwm_driver);
 
 MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, "
 	      "H Hartley Sweeten <hsweeten@visionengravers.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/hmc6352.c linux-libre-3.11-rc7-gnu/drivers/misc/hmc6352.c
--- linux-libre-3.10-gnu/drivers/misc/hmc6352.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/hmc6352.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,8 +46,9 @@ static int compass_store(struct device *
 	int ret;
 	unsigned long val;
 
-	if (strict_strtoul(buf, 10, &val))
-		return -EINVAL;
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
 	if (val >= strlen(map))
 		return -EINVAL;
 	mutex_lock(&compass_mutex);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/isl29003.c linux-libre-3.11-rc7-gnu/drivers/misc/isl29003.c
--- linux-libre-3.10-gnu/drivers/misc/isl29003.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/isl29003.c	2013-08-25 20:43:22.000000000 -0400
@@ -208,7 +208,11 @@ static ssize_t isl29003_store_range(stru
 	unsigned long val;
 	int ret;
 
-	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (val > 3)
 		return -EINVAL;
 
 	ret = isl29003_set_range(client, val);
@@ -239,7 +243,11 @@ static ssize_t isl29003_store_resolution
 	unsigned long val;
 	int ret;
 
-	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (val > 3)
 		return -EINVAL;
 
 	ret = isl29003_set_resolution(client, val);
@@ -267,7 +275,11 @@ static ssize_t isl29003_store_mode(struc
 	unsigned long val;
 	int ret;
 
-	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 2))
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (val > 2)
 		return -EINVAL;
 
 	ret = isl29003_set_mode(client, val);
@@ -298,7 +310,11 @@ static ssize_t isl29003_store_power_stat
 	unsigned long val;
 	int ret;
 
-	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1))
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (val > 1)
 		return -EINVAL;
 
 	ret = isl29003_set_power_state(client, val);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/isl29020.c linux-libre-3.11-rc7-gnu/drivers/misc/isl29020.c
--- linux-libre-3.10-gnu/drivers/misc/isl29020.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/isl29020.c	2013-08-25 20:43:22.000000000 -0400
@@ -90,8 +90,10 @@ static ssize_t als_sensing_range_store(s
 	int ret_val;
 	unsigned long val;
 
-	if (strict_strtoul(buf, 10, &val))
-		return -EINVAL;
+	ret_val = kstrtoul(buf, 10, &val);
+	if (ret_val)
+		return ret_val;
+
 	if (val < 1 || val > 64000)
 		return -EINVAL;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/Kconfig linux-libre-3.11-rc7-gnu/drivers/misc/Kconfig
--- linux-libre-3.10-gnu/drivers/misc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -135,7 +135,7 @@ config PHANTOM
 
 config INTEL_MID_PTI
 	tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
-	depends on PCI && TTY
+	depends on PCI && TTY && (X86_INTEL_MID || COMPILE_TEST)
 	default n
 	help
 	  The PTI (Parallel Trace Interface) driver directs
@@ -480,6 +480,7 @@ config BMP085_SPI
 
 config PCH_PHUB
 	tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"
+	select GENERIC_NET_UTILS
 	depends on PCI
 	help
 	  This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/lattice-ecp3-config.c linux-libre-3.11-rc7-gnu/drivers/misc/lattice-ecp3-config.c
--- linux-libre-3.10-gnu/drivers/misc/lattice-ecp3-config.c	2013-07-01 10:43:39.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/lattice-ecp3-config.c	2013-08-31 18:03:27.000000000 -0400
@@ -170,7 +170,7 @@ static void firmware_load(const struct f
 
 	/* Check result */
 	if (status & FPGA_STATUS_DONE)
-		dev_info(&spi->dev, "FPGA succesfully configured!\n");
+		dev_info(&spi->dev, "FPGA successfully configured!\n");
 	else
 		dev_info(&spi->dev, "FPGA not configured (DONE not set)\n");
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/lis3lv02d/lis3lv02d.c linux-libre-3.11-rc7-gnu/drivers/misc/lis3lv02d/lis3lv02d.c
--- linux-libre-3.10-gnu/drivers/misc/lis3lv02d/lis3lv02d.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/lis3lv02d/lis3lv02d.c	2013-08-25 20:43:22.000000000 -0400
@@ -831,9 +831,11 @@ static ssize_t lis3lv02d_rate_set(struct
 {
 	struct lis3lv02d *lis3 = dev_get_drvdata(dev);
 	unsigned long rate;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &rate))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &rate);
+	if (ret)
+		return ret;
 
 	lis3lv02d_sysfs_poweron(lis3);
 	if (lis3lv02d_set_odr(lis3, rate))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/amthif.c linux-libre-3.11-rc7-gnu/drivers/misc/mei/amthif.c
--- linux-libre-3.10-gnu/drivers/misc/mei/amthif.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/amthif.c	2013-08-25 20:43:22.000000000 -0400
@@ -443,11 +443,11 @@ unsigned int mei_amthif_poll(struct mei_
  *
  * returns 0, OK; otherwise, error.
  */
-int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
-			struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
+int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
+				  s32 *slots, struct mei_cl_cb *cmpl_list)
 {
+	struct mei_device *dev = cl->dev;
 	struct mei_msg_hdr mei_hdr;
-	struct mei_cl *cl = cb->cl;
 	size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
 	u32 msg_slots = mei_data2slots(len);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/client.c linux-libre-3.11-rc7-gnu/drivers/misc/mei/client.c
--- linux-libre-3.10-gnu/drivers/misc/mei/client.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/client.c	2013-08-25 20:43:22.000000000 -0400
@@ -485,7 +485,6 @@ int mei_cl_connect(struct mei_cl *cl, st
 {
 	struct mei_device *dev;
 	struct mei_cl_cb *cb;
-	long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT);
 	int rets;
 
 	if (WARN_ON(!cl || !cl->dev))
@@ -518,7 +517,7 @@ int mei_cl_connect(struct mei_cl *cl, st
 	rets = wait_event_timeout(dev->wait_recvd_msg,
 				 (cl->state == MEI_FILE_CONNECTED ||
 				  cl->state == MEI_FILE_DISCONNECTED),
-				 timeout * HZ);
+				 mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
 	mutex_lock(&dev->device_lock);
 
 	if (cl->state != MEI_FILE_CONNECTED) {
@@ -682,6 +681,68 @@ err:
 }
 
 /**
+ * mei_cl_irq_write_complete - write a message to device
+ *	from the interrupt thread context
+ *
+ * @cl: client
+ * @cb: callback block.
+ * @slots: free slots.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise error.
+ */
+int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
+				     s32 *slots, struct mei_cl_cb *cmpl_list)
+{
+	struct mei_device *dev = cl->dev;
+	struct mei_msg_hdr mei_hdr;
+	size_t len = cb->request_buffer.size - cb->buf_idx;
+	u32 msg_slots = mei_data2slots(len);
+
+	mei_hdr.host_addr = cl->host_client_id;
+	mei_hdr.me_addr = cl->me_client_id;
+	mei_hdr.reserved = 0;
+
+	if (*slots >= msg_slots) {
+		mei_hdr.length = len;
+		mei_hdr.msg_complete = 1;
+	/* Split the message only if we can write the whole host buffer */
+	} else if (*slots == dev->hbuf_depth) {
+		msg_slots = *slots;
+		len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
+		mei_hdr.length = len;
+		mei_hdr.msg_complete = 0;
+	} else {
+		/* wait for next time the host buffer is empty */
+		return 0;
+	}
+
+	dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
+			cb->request_buffer.size, cb->buf_idx);
+	dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
+
+	*slots -=  msg_slots;
+	if (mei_write_message(dev, &mei_hdr,
+			cb->request_buffer.data + cb->buf_idx)) {
+		cl->status = -ENODEV;
+		list_move_tail(&cb->list, &cmpl_list->list);
+		return -ENODEV;
+	}
+
+	cl->status = 0;
+	cl->writing_state = MEI_WRITING;
+	cb->buf_idx += mei_hdr.length;
+
+	if (mei_hdr.msg_complete) {
+		if (mei_cl_flow_ctrl_reduce(cl))
+			return -ENODEV;
+		list_move_tail(&cb->list, &dev->write_waiting_list.list);
+	}
+
+	return 0;
+}
+
+/**
  * mei_cl_write - submit a write cb to mei device
 	assumes device_lock is locked
  *
@@ -723,7 +784,6 @@ int mei_cl_write(struct mei_cl *cl, stru
 		cb->buf_idx = 0;
 		/* unseting complete will enqueue the cb for write */
 		mei_hdr.msg_complete = 0;
-		cl->writing_state = MEI_WRITING;
 		rets = buf->size;
 		goto out;
 	}
@@ -785,6 +845,32 @@ err:
 }
 
 
+/**
+ * mei_cl_complete - processes completed operation for a client
+ *
+ * @cl: private data of the file object.
+ * @cb: callback block.
+ */
+void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
+{
+	if (cb->fop_type == MEI_FOP_WRITE) {
+		mei_io_cb_free(cb);
+		cb = NULL;
+		cl->writing_state = MEI_WRITE_COMPLETE;
+		if (waitqueue_active(&cl->tx_wait))
+			wake_up_interruptible(&cl->tx_wait);
+
+	} else if (cb->fop_type == MEI_FOP_READ &&
+			MEI_READING == cl->reading_state) {
+		cl->reading_state = MEI_READ_COMPLETE;
+		if (waitqueue_active(&cl->rx_wait))
+			wake_up_interruptible(&cl->rx_wait);
+		else
+			mei_cl_bus_rx_event(cl);
+
+	}
+}
+
 
 /**
  * mei_cl_all_disconnect - disconnect forcefully all connected clients
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/client.h linux-libre-3.11-rc7-gnu/drivers/misc/mei/client.h
--- linux-libre-3.10-gnu/drivers/misc/mei/client.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/client.h	2013-08-25 20:43:22.000000000 -0400
@@ -89,6 +89,10 @@ int mei_cl_disconnect(struct mei_cl *cl)
 int mei_cl_connect(struct mei_cl *cl, struct file *file);
 int mei_cl_read_start(struct mei_cl *cl, size_t length);
 int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
+int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
+				s32 *slots, struct mei_cl_cb *cmpl_list);
+
+void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb);
 
 void mei_host_client_init(struct work_struct *work);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/hbm.c linux-libre-3.11-rc7-gnu/drivers/misc/mei/hbm.c
--- linux-libre-3.10-gnu/drivers/misc/mei/hbm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/hbm.c	2013-08-25 20:43:22.000000000 -0400
@@ -139,7 +139,7 @@ int mei_hbm_start_wait(struct mei_device
 
 	if (ret <= 0 && (dev->hbm_state <= MEI_HBM_START)) {
 		dev->hbm_state = MEI_HBM_IDLE;
-		dev_err(&dev->pdev->dev, "wating for mei start failed\n");
+		dev_err(&dev->pdev->dev, "waiting for mei start failed\n");
 		return -ETIMEDOUT;
 	}
 	return 0;
@@ -167,7 +167,7 @@ int mei_hbm_start_req(struct mei_device
 
 	dev->hbm_state = MEI_HBM_IDLE;
 	if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
-		dev_err(&dev->pdev->dev, "version message writet failed\n");
+		dev_err(&dev->pdev->dev, "version message write failed\n");
 		dev->dev_state = MEI_DEV_RESETTING;
 		mei_reset(dev, 1);
 		return -ENODEV;
@@ -536,6 +536,20 @@ static void mei_hbm_fw_disconnect_req(st
 
 
 /**
+ * mei_hbm_version_is_supported - checks whether the driver can
+ *     support the hbm version of the device
+ *
+ * @dev: the device structure
+ * returns true if driver can support hbm version of the device
+ */
+bool mei_hbm_version_is_supported(struct mei_device *dev)
+{
+	return	(dev->version.major_version < HBM_MAJOR_VERSION) ||
+		(dev->version.major_version == HBM_MAJOR_VERSION &&
+		 dev->version.minor_version <= HBM_MINOR_VERSION);
+}
+
+/**
  * mei_hbm_dispatch - bottom half read routine after ISR to
  * handle the read bus message cmd processing.
  *
@@ -562,9 +576,24 @@ void mei_hbm_dispatch(struct mei_device
 	switch (mei_msg->hbm_cmd) {
 	case HOST_START_RES_CMD:
 		version_res = (struct hbm_host_version_response *)mei_msg;
-		if (!version_res->host_version_supported) {
-			dev->version = version_res->me_max_version;
-			dev_dbg(&dev->pdev->dev, "version mismatch.\n");
+
+		dev_dbg(&dev->pdev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n",
+				HBM_MAJOR_VERSION, HBM_MINOR_VERSION,
+				version_res->me_max_version.major_version,
+				version_res->me_max_version.minor_version);
+
+		if (version_res->host_version_supported) {
+			dev->version.major_version = HBM_MAJOR_VERSION;
+			dev->version.minor_version = HBM_MINOR_VERSION;
+		} else {
+			dev->version.major_version =
+				version_res->me_max_version.major_version;
+			dev->version.minor_version =
+				version_res->me_max_version.minor_version;
+		}
+
+		if (!mei_hbm_version_is_supported(dev)) {
+			dev_warn(&dev->pdev->dev, "hbm version mismatch: stopping the driver.\n");
 
 			dev->hbm_state = MEI_HBM_STOP;
 			mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr,
@@ -575,8 +604,6 @@ void mei_hbm_dispatch(struct mei_device
 			return;
 		}
 
-		dev->version.major_version = HBM_MAJOR_VERSION;
-		dev->version.minor_version = HBM_MINOR_VERSION;
 		if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
 		    dev->hbm_state == MEI_HBM_START) {
 			dev->init_clients_timer = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/hbm.h linux-libre-3.11-rc7-gnu/drivers/misc/mei/hbm.h
--- linux-libre-3.10-gnu/drivers/misc/mei/hbm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/hbm.h	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ int mei_hbm_start_wait(struct mei_device
 int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
 int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
 int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl);
-
+bool mei_hbm_version_is_supported(struct mei_device *dev);
 
 #endif /* _MEI_HBM_H_ */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/hw-me.c linux-libre-3.11-rc7-gnu/drivers/misc/mei/hw-me.c
--- linux-libre-3.10-gnu/drivers/misc/mei/hw-me.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/hw-me.c	2013-08-25 20:43:22.000000000 -0400
@@ -171,7 +171,7 @@ static void mei_me_hw_reset_release(stru
  * @dev: the device structure
  * @intr_enable: if interrupt should be enabled after reset.
  */
-static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
+static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
 {
 	struct mei_me_hw *hw = to_me_hw(dev);
 	u32 hcsr = mei_hcsr_read(hw);
@@ -191,6 +191,7 @@ static void mei_me_hw_reset(struct mei_d
 		mei_me_hw_reset_release(dev);
 
 	dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", mei_hcsr_read(hw));
+	return 0;
 }
 
 /**
@@ -238,14 +239,18 @@ static int mei_me_hw_ready_wait(struct m
 	if (mei_me_hw_is_ready(dev))
 		return 0;
 
+	dev->recvd_hw_ready = false;
 	mutex_unlock(&dev->device_lock);
 	err = wait_event_interruptible_timeout(dev->wait_hw_ready,
-			dev->recvd_hw_ready, MEI_INTEROP_TIMEOUT);
+			dev->recvd_hw_ready,
+			mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
 	mutex_lock(&dev->device_lock);
 	if (!err && !dev->recvd_hw_ready) {
+		if (!err)
+			err = -ETIMEDOUT;
 		dev_err(&dev->pdev->dev,
-			"wait hw ready failed. status = 0x%x\n", err);
-		return -ETIMEDOUT;
+			"wait hw ready failed. status = %d\n", err);
+		return err;
 	}
 
 	dev->recvd_hw_ready = false;
@@ -482,7 +487,9 @@ irqreturn_t mei_me_irq_thread_handler(in
 	/* check if ME wants a reset */
 	if (!mei_hw_is_ready(dev) &&
 	    dev->dev_state != MEI_DEV_RESETTING &&
-	    dev->dev_state != MEI_DEV_INITIALIZING) {
+	    dev->dev_state != MEI_DEV_INITIALIZING &&
+	    dev->dev_state != MEI_DEV_POWER_DOWN &&
+	    dev->dev_state != MEI_DEV_POWER_UP) {
 		dev_dbg(&dev->pdev->dev, "FW not ready.\n");
 		mei_reset(dev, 1);
 		mutex_unlock(&dev->device_lock);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/init.c linux-libre-3.11-rc7-gnu/drivers/misc/mei/init.c
--- linux-libre-3.10-gnu/drivers/misc/mei/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,7 @@ const char *mei_dev_state_str(int state)
 	MEI_DEV_STATE(POWER_DOWN);
 	MEI_DEV_STATE(POWER_UP);
 	default:
-		return "unkown";
+		return "unknown";
 	}
 #undef MEI_DEV_STATE
 }
@@ -106,8 +106,7 @@ int mei_start(struct mei_device *dev)
 		goto err;
 	}
 
-	if (dev->version.major_version != HBM_MAJOR_VERSION ||
-	    dev->version.minor_version != HBM_MINOR_VERSION) {
+	if (!mei_hbm_version_is_supported(dev)) {
 		dev_dbg(&dev->pdev->dev, "MEI start failed.\n");
 		goto err;
 	}
@@ -133,17 +132,24 @@ EXPORT_SYMBOL_GPL(mei_start);
 void mei_reset(struct mei_device *dev, int interrupts_enabled)
 {
 	bool unexpected;
+	int ret;
 
 	unexpected = (dev->dev_state != MEI_DEV_INITIALIZING &&
 			dev->dev_state != MEI_DEV_DISABLED &&
 			dev->dev_state != MEI_DEV_POWER_DOWN &&
 			dev->dev_state != MEI_DEV_POWER_UP);
 
-	mei_hw_reset(dev, interrupts_enabled);
+	ret = mei_hw_reset(dev, interrupts_enabled);
+	if (ret) {
+		dev_err(&dev->pdev->dev, "hw reset failed disabling the device\n");
+		interrupts_enabled = false;
+		dev->dev_state = MEI_DEV_DISABLED;
+	}
 
 	dev->hbm_state = MEI_HBM_IDLE;
 
-	if (dev->dev_state != MEI_DEV_INITIALIZING) {
+	if (dev->dev_state != MEI_DEV_INITIALIZING &&
+	    dev->dev_state != MEI_DEV_POWER_UP) {
 		if (dev->dev_state != MEI_DEV_DISABLED &&
 		    dev->dev_state != MEI_DEV_POWER_DOWN)
 			dev->dev_state = MEI_DEV_RESETTING;
@@ -176,7 +182,12 @@ void mei_reset(struct mei_device *dev, i
 		return;
 	}
 
-	mei_hw_start(dev);
+	ret = mei_hw_start(dev);
+	if (ret) {
+		dev_err(&dev->pdev->dev, "hw_start failed disabling the device\n");
+		dev->dev_state = MEI_DEV_DISABLED;
+		return;
+	}
 
 	dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
 	/* link is established * start sending messages.  */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/interrupt.c linux-libre-3.11-rc7-gnu/drivers/misc/mei/interrupt.c
--- linux-libre-3.10-gnu/drivers/misc/mei/interrupt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/interrupt.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,32 +31,6 @@
 
 
 /**
- * mei_cl_complete_handler - processes completed operation for a client
- *
- * @cl: private data of the file object.
- * @cb: callback block.
- */
-static void mei_cl_complete_handler(struct mei_cl *cl, struct mei_cl_cb *cb)
-{
-	if (cb->fop_type == MEI_FOP_WRITE) {
-		mei_io_cb_free(cb);
-		cb = NULL;
-		cl->writing_state = MEI_WRITE_COMPLETE;
-		if (waitqueue_active(&cl->tx_wait))
-			wake_up_interruptible(&cl->tx_wait);
-
-	} else if (cb->fop_type == MEI_FOP_READ &&
-			MEI_READING == cl->reading_state) {
-		cl->reading_state = MEI_READ_COMPLETE;
-		if (waitqueue_active(&cl->rx_wait))
-			wake_up_interruptible(&cl->rx_wait);
-		else
-			mei_cl_bus_rx_event(cl);
-
-	}
-}
-
-/**
  * mei_irq_compl_handler - dispatch complete handelers
  *	for the completed callbacks
  *
@@ -78,7 +52,7 @@ void mei_irq_compl_handler(struct mei_de
 		if (cl == &dev->iamthif_cl)
 			mei_amthif_complete(dev, cb);
 		else
-			mei_cl_complete_handler(cl, cb);
+			mei_cl_complete(cl, cb);
 	}
 }
 EXPORT_SYMBOL_GPL(mei_irq_compl_handler);
@@ -189,21 +163,21 @@ static int mei_cl_irq_read_msg(struct me
 }
 
 /**
- * _mei_irq_thread_close - processes close related operation.
+ * mei_cl_irq_close - processes close related operation from
+ *	interrupt thread context - send disconnect request
  *
- * @dev: the device structure.
+ * @cl: client
+ * @cb: callback block.
  * @slots: free slots.
- * @cb_pos: callback block.
- * @cl: private data of the file object.
  * @cmpl_list: complete list.
  *
  * returns 0, OK; otherwise, error.
  */
-static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
-				struct mei_cl_cb *cb_pos,
-				struct mei_cl *cl,
-				struct mei_cl_cb *cmpl_list)
+static int mei_cl_irq_close(struct mei_cl *cl, struct mei_cl_cb *cb,
+			s32 *slots, struct mei_cl_cb *cmpl_list)
 {
+	struct mei_device *dev = cl->dev;
+
 	u32 msg_slots =
 		mei_data2slots(sizeof(struct hbm_client_connect_request));
 
@@ -214,15 +188,15 @@ static int _mei_irq_thread_close(struct
 
 	if (mei_hbm_cl_disconnect_req(dev, cl)) {
 		cl->status = 0;
-		cb_pos->buf_idx = 0;
-		list_move_tail(&cb_pos->list, &cmpl_list->list);
+		cb->buf_idx = 0;
+		list_move_tail(&cb->list, &cmpl_list->list);
 		return -EIO;
 	}
 
 	cl->state = MEI_FILE_DISCONNECTING;
 	cl->status = 0;
-	cb_pos->buf_idx = 0;
-	list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
+	cb->buf_idx = 0;
+	list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
 	cl->timer_count = MEI_CONNECT_TIMEOUT;
 
 	return 0;
@@ -230,26 +204,26 @@ static int _mei_irq_thread_close(struct
 
 
 /**
- * _mei_irq_thread_read - processes read related operation.
+ * mei_cl_irq_close - processes client read related operation from the
+ *	interrupt thread context - request for flow control credits
  *
- * @dev: the device structure.
+ * @cl: client
+ * @cb: callback block.
  * @slots: free slots.
- * @cb_pos: callback block.
- * @cl: private data of the file object.
  * @cmpl_list: complete list.
  *
  * returns 0, OK; otherwise, error.
  */
-static int _mei_irq_thread_read(struct mei_device *dev,	s32 *slots,
-			struct mei_cl_cb *cb_pos,
-			struct mei_cl *cl,
-			struct mei_cl_cb *cmpl_list)
+static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
+			   s32 *slots, struct mei_cl_cb *cmpl_list)
 {
+	struct mei_device *dev = cl->dev;
+
 	u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
 
 	if (*slots < msg_slots) {
 		/* return the cancel routine */
-		list_del(&cb_pos->list);
+		list_del(&cb->list);
 		return -EMSGSIZE;
 	}
 
@@ -257,38 +231,38 @@ static int _mei_irq_thread_read(struct m
 
 	if (mei_hbm_cl_flow_control_req(dev, cl)) {
 		cl->status = -ENODEV;
-		cb_pos->buf_idx = 0;
-		list_move_tail(&cb_pos->list, &cmpl_list->list);
+		cb->buf_idx = 0;
+		list_move_tail(&cb->list, &cmpl_list->list);
 		return -ENODEV;
 	}
-	list_move_tail(&cb_pos->list, &dev->read_list.list);
+	list_move_tail(&cb->list, &dev->read_list.list);
 
 	return 0;
 }
 
 
 /**
- * _mei_irq_thread_ioctl - processes ioctl related operation.
+ * mei_cl_irq_ioctl - processes client ioctl related operation from the
+ *	interrupt thread context -   send connection request
  *
- * @dev: the device structure.
+ * @cl: client
+ * @cb: callback block.
  * @slots: free slots.
- * @cb_pos: callback block.
- * @cl: private data of the file object.
  * @cmpl_list: complete list.
  *
  * returns 0, OK; otherwise, error.
  */
-static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
-			struct mei_cl_cb *cb_pos,
-			struct mei_cl *cl,
-			struct mei_cl_cb *cmpl_list)
+static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
+			   s32 *slots, struct mei_cl_cb *cmpl_list)
 {
+	struct mei_device *dev = cl->dev;
+
 	u32 msg_slots =
 		mei_data2slots(sizeof(struct hbm_client_connect_request));
 
 	if (*slots < msg_slots) {
 		/* return the cancel routine */
-		list_del(&cb_pos->list);
+		list_del(&cb->list);
 		return -EMSGSIZE;
 	}
 
@@ -298,76 +272,17 @@ static int _mei_irq_thread_ioctl(struct
 
 	if (mei_hbm_cl_connect_req(dev, cl)) {
 		cl->status = -ENODEV;
-		cb_pos->buf_idx = 0;
-		list_del(&cb_pos->list);
-		return -ENODEV;
-	} else {
-		list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
-		cl->timer_count = MEI_CONNECT_TIMEOUT;
-	}
-	return 0;
-}
-
-/**
- * mei_irq_thread_write_complete - write messages to device.
- *
- * @dev: the device structure.
- * @slots: free slots.
- * @cb: callback block.
- * @cmpl_list: complete list.
- *
- * returns 0, OK; otherwise, error.
- */
-static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
-			struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
-{
-	struct mei_msg_hdr mei_hdr;
-	struct mei_cl *cl = cb->cl;
-	size_t len = cb->request_buffer.size - cb->buf_idx;
-	u32 msg_slots = mei_data2slots(len);
-
-	mei_hdr.host_addr = cl->host_client_id;
-	mei_hdr.me_addr = cl->me_client_id;
-	mei_hdr.reserved = 0;
-
-	if (*slots >= msg_slots) {
-		mei_hdr.length = len;
-		mei_hdr.msg_complete = 1;
-	/* Split the message only if we can write the whole host buffer */
-	} else if (*slots == dev->hbuf_depth) {
-		msg_slots = *slots;
-		len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
-		mei_hdr.length = len;
-		mei_hdr.msg_complete = 0;
-	} else {
-		/* wait for next time the host buffer is empty */
-		return 0;
-	}
-
-	dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n",
-			cb->request_buffer.size, cb->buf_idx);
-	dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
-
-	*slots -=  msg_slots;
-	if (mei_write_message(dev, &mei_hdr,
-			cb->request_buffer.data + cb->buf_idx)) {
-		cl->status = -ENODEV;
-		list_move_tail(&cb->list, &cmpl_list->list);
+		cb->buf_idx = 0;
+		list_del(&cb->list);
 		return -ENODEV;
 	}
 
-
-	cl->status = 0;
-	cb->buf_idx += mei_hdr.length;
-	if (mei_hdr.msg_complete) {
-		if (mei_cl_flow_ctrl_reduce(cl))
-			return -ENODEV;
-		list_move_tail(&cb->list, &dev->write_waiting_list.list);
-	}
-
+	list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
+	cl->timer_count = MEI_CONNECT_TIMEOUT;
 	return 0;
 }
 
+
 /**
  * mei_irq_read_handler - bottom half read routine after ISR to
  * handle the read processing.
@@ -481,7 +396,7 @@ int mei_irq_write_handler(struct mei_dev
 {
 
 	struct mei_cl *cl;
-	struct mei_cl_cb *pos = NULL, *next = NULL;
+	struct mei_cl_cb *cb, *next;
 	struct mei_cl_cb *list;
 	s32 slots;
 	int ret;
@@ -498,19 +413,19 @@ int mei_irq_write_handler(struct mei_dev
 	dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
 
 	list = &dev->write_waiting_list;
-	list_for_each_entry_safe(pos, next, &list->list, list) {
-		cl = pos->cl;
+	list_for_each_entry_safe(cb, next, &list->list, list) {
+		cl = cb->cl;
 		if (cl == NULL)
 			continue;
 
 		cl->status = 0;
-		list_del(&pos->list);
+		list_del(&cb->list);
 		if (MEI_WRITING == cl->writing_state &&
-		    pos->fop_type == MEI_FOP_WRITE &&
+		    cb->fop_type == MEI_FOP_WRITE &&
 		    cl != &dev->iamthif_cl) {
 			dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
 			cl->writing_state = MEI_WRITE_COMPLETE;
-			list_add_tail(&pos->list, &cmpl_list->list);
+			list_add_tail(&cb->list, &cmpl_list->list);
 		}
 		if (cl == &dev->iamthif_cl) {
 			dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
@@ -552,25 +467,23 @@ int mei_irq_write_handler(struct mei_dev
 
 	/* complete control write list CB */
 	dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
-	list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) {
-		cl = pos->cl;
+	list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list.list, list) {
+		cl = cb->cl;
 		if (!cl) {
-			list_del(&pos->list);
+			list_del(&cb->list);
 			return -ENODEV;
 		}
-		switch (pos->fop_type) {
+		switch (cb->fop_type) {
 		case MEI_FOP_CLOSE:
 			/* send disconnect message */
-			ret = _mei_irq_thread_close(dev, &slots, pos,
-						cl, cmpl_list);
+			ret = mei_cl_irq_close(cl, cb, &slots, cmpl_list);
 			if (ret)
 				return ret;
 
 			break;
 		case MEI_FOP_READ:
 			/* send flow control message */
-			ret = _mei_irq_thread_read(dev, &slots, pos,
-						cl, cmpl_list);
+			ret = mei_cl_irq_read(cl, cb, &slots, cmpl_list);
 			if (ret)
 				return ret;
 
@@ -579,8 +492,7 @@ int mei_irq_write_handler(struct mei_dev
 			/* connect message */
 			if (mei_cl_is_other_connecting(cl))
 				continue;
-			ret = _mei_irq_thread_ioctl(dev, &slots, pos,
-						cl, cmpl_list);
+			ret = mei_cl_irq_ioctl(cl, cb, &slots, cmpl_list);
 			if (ret)
 				return ret;
 
@@ -593,8 +505,8 @@ int mei_irq_write_handler(struct mei_dev
 	}
 	/* complete  write list CB */
 	dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
-	list_for_each_entry_safe(pos, next, &dev->write_list.list, list) {
-		cl = pos->cl;
+	list_for_each_entry_safe(cb, next, &dev->write_list.list, list) {
+		cl = cb->cl;
 		if (cl == NULL)
 			continue;
 		if (mei_cl_flow_ctrl_creds(cl) <= 0) {
@@ -605,14 +517,13 @@ int mei_irq_write_handler(struct mei_dev
 		}
 
 		if (cl == &dev->iamthif_cl)
-			ret = mei_amthif_irq_write_complete(dev, &slots,
-							pos, cmpl_list);
+			ret = mei_amthif_irq_write_complete(cl, cb,
+						&slots, cmpl_list);
 		else
-			ret = mei_irq_thread_write_complete(dev, &slots, pos,
-						cmpl_list);
+			ret = mei_cl_irq_write_complete(cl, cb,
+						&slots, cmpl_list);
 		if (ret)
 			return ret;
-
 	}
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/main.c linux-libre-3.11-rc7-gnu/drivers/misc/mei/main.c
--- linux-libre-3.10-gnu/drivers/misc/mei/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -194,7 +194,6 @@ static ssize_t mei_read(struct file *fil
 	struct mei_cl_cb *cb_pos = NULL;
 	struct mei_cl_cb *cb = NULL;
 	struct mei_device *dev;
-	int i;
 	int rets;
 	int err;
 
@@ -210,38 +209,26 @@ static ssize_t mei_read(struct file *fil
 		goto out;
 	}
 
-	if ((cl->sm_state & MEI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) {
-		/* Do not allow to read watchdog client */
-		i = mei_me_cl_by_uuid(dev, &mei_wd_guid);
-		if (i >= 0) {
-			struct mei_me_client *me_client = &dev->me_clients[i];
-			if (cl->me_client_id == me_client->client_id) {
-				rets = -EBADF;
-				goto out;
-			}
-		}
-	} else {
-		cl->sm_state &= ~MEI_WD_STATE_INDEPENDENCE_MSG_SENT;
-	}
-
 	if (cl == &dev->iamthif_cl) {
 		rets = mei_amthif_read(dev, file, ubuf, length, offset);
 		goto out;
 	}
 
-	if (cl->read_cb && cl->read_cb->buf_idx > *offset) {
-		cb = cl->read_cb;
-		goto copy_buffer;
-	} else if (cl->read_cb && cl->read_cb->buf_idx > 0 &&
-		   cl->read_cb->buf_idx <= *offset) {
+	if (cl->read_cb) {
 		cb = cl->read_cb;
-		rets = 0;
-		goto free;
-	} else if ((!cl->read_cb || !cl->read_cb->buf_idx) && *offset > 0) {
-		/*Offset needs to be cleaned for contiguous reads*/
+		/* read what left */
+		if (cb->buf_idx > *offset)
+			goto copy_buffer;
+		/* offset is beyond buf_idx we have no more data return 0 */
+		if (cb->buf_idx > 0 && cb->buf_idx <= *offset) {
+			rets = 0;
+			goto free;
+		}
+		/* Offset needs to be cleaned for contiguous reads*/
+		if (cb->buf_idx == 0 && *offset > 0)
+			*offset = 0;
+	} else if (*offset > 0) {
 		*offset = 0;
-		rets = 0;
-		goto out;
 	}
 
 	err = mei_cl_read_start(cl, length);
@@ -420,16 +407,6 @@ static ssize_t mei_write(struct file *fi
 	if (rets)
 		goto out;
 
-	cl->sm_state = 0;
-	if (length == 4 &&
-	    ((memcmp(mei_wd_state_independence_msg[0],
-				 write_cb->request_buffer.data, 4) == 0) ||
-	     (memcmp(mei_wd_state_independence_msg[1],
-				 write_cb->request_buffer.data, 4) == 0) ||
-	     (memcmp(mei_wd_state_independence_msg[2],
-				 write_cb->request_buffer.data, 4) == 0)))
-		cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT;
-
 	if (cl == &dev->iamthif_cl) {
 		rets = mei_amthif_write(dev, write_cb);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/mei_dev.h linux-libre-3.11-rc7-gnu/drivers/misc/mei/mei_dev.h
--- linux-libre-3.10-gnu/drivers/misc/mei/mei_dev.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/mei_dev.h	2013-08-25 20:43:22.000000000 -0400
@@ -56,11 +56,6 @@ extern const uuid_le mei_amthif_guid;
 extern const uuid_le mei_wd_guid;
 
 /*
- * Watchdog independence state message
- */
-extern const u8 mei_wd_state_independence_msg[3][4];
-
-/*
  * Number of Maximum MEI Clients
  */
 #define MEI_CLIENTS_MAX 256
@@ -201,7 +196,6 @@ struct mei_cl {
 	u8 timer_count;
 	enum mei_file_transaction_states reading_state;
 	enum mei_file_transaction_states writing_state;
-	int sm_state;
 	struct mei_cl_cb *read_cb;
 
 	/* MEI CL bus data */
@@ -239,7 +233,7 @@ struct mei_hw_ops {
 	bool (*host_is_ready) (struct mei_device *dev);
 
 	bool (*hw_is_ready) (struct mei_device *dev);
-	void (*hw_reset) (struct mei_device *dev, bool enable);
+	int (*hw_reset) (struct mei_device *dev, bool enable);
 	int  (*hw_start) (struct mei_device *dev);
 	void (*hw_config) (struct mei_device *dev);
 
@@ -502,8 +496,8 @@ struct mei_cl_cb *mei_amthif_find_read_l
 
 void mei_amthif_run_next_cmd(struct mei_device *dev);
 
-int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
-			struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list);
+int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
+				  s32 *slots, struct mei_cl_cb *cmpl_list);
 
 void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
 int mei_amthif_irq_read_msg(struct mei_device *dev,
@@ -522,15 +516,6 @@ void mei_nfc_host_exit(void);
  */
 extern const uuid_le mei_nfc_guid;
 
-int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
-			struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list);
-
-void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
-int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
-		struct mei_device *dev, struct mei_msg_hdr *mei_hdr);
-int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
-
-
 int mei_wd_send(struct mei_device *dev);
 int mei_wd_stop(struct mei_device *dev);
 int mei_wd_host_init(struct mei_device *dev);
@@ -554,14 +539,14 @@ static inline void mei_hw_config(struct
 {
 	dev->ops->hw_config(dev);
 }
-static inline void mei_hw_reset(struct mei_device *dev, bool enable)
+static inline int mei_hw_reset(struct mei_device *dev, bool enable)
 {
-	dev->ops->hw_reset(dev, enable);
+	return dev->ops->hw_reset(dev, enable);
 }
 
-static inline void mei_hw_start(struct mei_device *dev)
+static inline int mei_hw_start(struct mei_device *dev)
 {
-	dev->ops->hw_start(dev);
+	return dev->ops->hw_start(dev);
 }
 
 static inline void mei_clear_interrupts(struct mei_device *dev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/pci-me.c linux-libre-3.11-rc7-gnu/drivers/misc/mei/pci-me.c
--- linux-libre-3.10-gnu/drivers/misc/mei/pci-me.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/pci-me.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,9 +43,6 @@
 #include "hw-me.h"
 #include "client.h"
 
-/* AMT device is a singleton on the platform */
-static struct pci_dev *mei_pdev;
-
 /* mei_pci_tbl - PCI Device ID Table */
 static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)},
@@ -88,8 +85,6 @@ static DEFINE_PCI_DEVICE_TABLE(mei_me_pc
 
 MODULE_DEVICE_TABLE(pci, mei_me_pci_tbl);
 
-static DEFINE_MUTEX(mei_mutex);
-
 /**
  * mei_quirk_probe - probe for devices that doesn't valid ME interface
  *
@@ -126,17 +121,12 @@ static int mei_me_probe(struct pci_dev *
 	struct mei_me_hw *hw;
 	int err;
 
-	mutex_lock(&mei_mutex);
 
 	if (!mei_me_quirk_probe(pdev, ent)) {
 		err = -ENODEV;
 		goto end;
 	}
 
-	if (mei_pdev) {
-		err = -EEXIST;
-		goto end;
-	}
 	/* enable pci dev */
 	err = pci_enable_device(pdev);
 	if (err) {
@@ -195,13 +185,10 @@ static int mei_me_probe(struct pci_dev *
 	if (err)
 		goto release_irq;
 
-	mei_pdev = pdev;
 	pci_set_drvdata(pdev, dev);
 
 	schedule_delayed_work(&dev->timer_work, HZ);
 
-	mutex_unlock(&mei_mutex);
-
 	pr_debug("initialization successful.\n");
 
 	return 0;
@@ -220,7 +207,6 @@ release_regions:
 disable_device:
 	pci_disable_device(pdev);
 end:
-	mutex_unlock(&mei_mutex);
 	dev_err(&pdev->dev, "initialization failed.\n");
 	return err;
 }
@@ -238,9 +224,6 @@ static void mei_me_remove(struct pci_dev
 	struct mei_device *dev;
 	struct mei_me_hw *hw;
 
-	if (mei_pdev != pdev)
-		return;
-
 	dev = pci_get_drvdata(pdev);
 	if (!dev)
 		return;
@@ -251,8 +234,6 @@ static void mei_me_remove(struct pci_dev
 	dev_err(&pdev->dev, "stop\n");
 	mei_stop(dev);
 
-	mei_pdev = NULL;
-
 	/* disable interrupts */
 	mei_disable_interrupts(dev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/mei/wd.c linux-libre-3.11-rc7-gnu/drivers/misc/mei/wd.c
--- linux-libre-3.10-gnu/drivers/misc/mei/wd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/mei/wd.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,12 +31,6 @@
 static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
 static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 };
 
-const u8 mei_wd_state_independence_msg[3][4] = {
-	{0x05, 0x02, 0x51, 0x10},
-	{0x05, 0x02, 0x52, 0x10},
-	{0x07, 0x02, 0x01, 0x10}
-};
-
 /*
  * AMT Watchdog Device
  */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/pch_phub.c linux-libre-3.11-rc7-gnu/drivers/misc/pch_phub.c
--- linux-libre-3.10-gnu/drivers/misc/pch_phub.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/pch_phub.c	2013-08-25 20:43:22.000000000 -0400
@@ -633,17 +633,13 @@ static ssize_t show_pch_mac(struct devic
 static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
 			     const char *buf, size_t count)
 {
-	u8 mac[6];
+	u8 mac[ETH_ALEN];
 	ssize_t rom_size;
 	struct pch_phub_reg *chip = dev_get_drvdata(dev);
 
-	if (count != 18)
+	if (!mac_pton(buf, mac))
 		return -EINVAL;
 
-	sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
-		(u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
-		(u32 *)&mac[4], (u32 *)&mac[5]);
-
 	chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
 	if (!chip->pch_phub_extrom_base_address)
 		return -ENOMEM;
@@ -669,8 +665,6 @@ static struct bin_attribute pch_bin_attr
 static int pch_phub_probe(struct pci_dev *pdev,
 				    const struct pci_device_id *id)
 {
-	int retval;
-
 	int ret;
 	struct pch_phub_reg *chip;
 
@@ -713,13 +707,13 @@ static int pch_phub_probe(struct pci_dev
 	if (id->driver_data == 1) { /* EG20T PCH */
 		const char *board_name;
 
-		retval = sysfs_create_file(&pdev->dev.kobj,
-					   &dev_attr_pch_mac.attr);
-		if (retval)
+		ret = sysfs_create_file(&pdev->dev.kobj,
+					&dev_attr_pch_mac.attr);
+		if (ret)
 			goto err_sysfs_create;
 
-		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
-		if (retval)
+		ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+		if (ret)
 			goto exit_bin_attr;
 
 		pch_phub_read_modify_write_reg(chip,
@@ -743,8 +737,8 @@ static int pch_phub_probe(struct pci_dev
 		chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
 		chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
 	} else if (id->driver_data == 2) { /* ML7213 IOH */
-		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
-		if (retval)
+		ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+		if (ret)
 			goto err_sysfs_create;
 		/* set the prefech value
 		 * Device2(USB OHCI #1/ USB EHCI #1/ USB Device):a
@@ -766,12 +760,12 @@ static int pch_phub_probe(struct pci_dev
 						 PCH_PHUB_ROM_START_ADDR_ML7223;
 		chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
 	} else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/
-		retval = sysfs_create_file(&pdev->dev.kobj,
-					   &dev_attr_pch_mac.attr);
-		if (retval)
+		ret = sysfs_create_file(&pdev->dev.kobj,
+					&dev_attr_pch_mac.attr);
+		if (ret)
 			goto err_sysfs_create;
-		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
-		if (retval)
+		ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+		if (ret)
 			goto exit_bin_attr;
 		/* set the prefech value
 		 * Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a
@@ -783,13 +777,13 @@ static int pch_phub_probe(struct pci_dev
 						 PCH_PHUB_ROM_START_ADDR_ML7223;
 		chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
 	} else if (id->driver_data == 5) { /* ML7831 */
-		retval = sysfs_create_file(&pdev->dev.kobj,
-					   &dev_attr_pch_mac.attr);
-		if (retval)
+		ret = sysfs_create_file(&pdev->dev.kobj,
+					&dev_attr_pch_mac.attr);
+		if (ret)
 			goto err_sysfs_create;
 
-		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
-		if (retval)
+		ret = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+		if (ret)
 			goto exit_bin_attr;
 
 		/* set the prefech value */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/sgi-gru/grufault.c linux-libre-3.11-rc7-gnu/drivers/misc/sgi-gru/grufault.c
--- linux-libre-3.10-gnu/drivers/misc/sgi-gru/grufault.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/sgi-gru/grufault.c	2013-08-25 20:43:22.000000000 -0400
@@ -876,8 +876,9 @@ int gru_set_context_option(unsigned long
 	switch (req.op) {
 	case sco_blade_chiplet:
 		/* Select blade/chiplet for GRU context */
-		if (req.val1 < -1 || req.val1 >= GRU_MAX_BLADES || !gru_base[req.val1] ||
-		    req.val0 < -1 || req.val0 >= GRU_CHIPLETS_PER_HUB) {
+		if (req.val0 < -1 || req.val0 >= GRU_CHIPLETS_PER_HUB ||
+		    req.val1 < -1 || req.val1 >= GRU_MAX_BLADES ||
+		    (req.val1 >= 0 && !gru_base[req.val1])) {
 			ret = -EINVAL;
 		} else {
 			gts->ts_user_blade_id = req.val1;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/sgi-gru/gruprocfs.c linux-libre-3.11-rc7-gnu/drivers/misc/sgi-gru/gruprocfs.c
--- linux-libre-3.10-gnu/drivers/misc/sgi-gru/gruprocfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/sgi-gru/gruprocfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -160,15 +160,11 @@ static int options_show(struct seq_file
 static ssize_t options_write(struct file *file, const char __user *userbuf,
 			     size_t count, loff_t *data)
 {
-	char buf[20];
+	int ret;
 
-	if (count >= sizeof(buf))
-		return -EINVAL;
-	if (copy_from_user(buf, userbuf, count))
-		return -EFAULT;
-	buf[count] = '\0';
-	if (strict_strtoul(buf, 0, &gru_options))
-		return -EINVAL;
+	ret = kstrtoul_from_user(userbuf, count, 0, &gru_options);
+	if (ret)
+		return ret;
 
 	return count;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/sgi-xp/xpc_main.c linux-libre-3.11-rc7-gnu/drivers/misc/sgi-xp/xpc_main.c
--- linux-libre-3.10-gnu/drivers/misc/sgi-xp/xpc_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/sgi-xp/xpc_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -92,7 +92,7 @@ int xpc_disengage_timelimit = XPC_DISENG
 static int xpc_disengage_min_timelimit;	/* = 0 */
 static int xpc_disengage_max_timelimit = 120;
 
-static ctl_table xpc_sys_xpc_hb_dir[] = {
+static struct ctl_table xpc_sys_xpc_hb_dir[] = {
 	{
 	 .procname = "hb_interval",
 	 .data = &xpc_hb_interval,
@@ -111,7 +111,7 @@ static ctl_table xpc_sys_xpc_hb_dir[] =
 	 .extra2 = &xpc_hb_check_max_interval},
 	{}
 };
-static ctl_table xpc_sys_xpc_dir[] = {
+static struct ctl_table xpc_sys_xpc_dir[] = {
 	{
 	 .procname = "hb",
 	 .mode = 0555,
@@ -126,7 +126,7 @@ static ctl_table xpc_sys_xpc_dir[] = {
 	 .extra2 = &xpc_disengage_max_timelimit},
 	{}
 };
-static ctl_table xpc_sys_dir[] = {
+static struct ctl_table xpc_sys_dir[] = {
 	{
 	 .procname = "xpc",
 	 .mode = 0555,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/spear13xx_pcie_gadget.c linux-libre-3.11-rc7-gnu/drivers/misc/spear13xx_pcie_gadget.c
--- linux-libre-3.10-gnu/drivers/misc/spear13xx_pcie_gadget.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/spear13xx_pcie_gadget.c	2013-08-25 20:43:22.000000000 -0400
@@ -316,8 +316,12 @@ static ssize_t pcie_gadget_store_no_of_m
 		struct spear_pcie_gadget_config *config,
 		const char *buf, size_t count)
 {
-	if (strict_strtoul(buf, 0, &config->requested_msi))
-		return -EINVAL;
+	int ret;
+
+	ret = kstrtoul(buf, 0, &config->requested_msi);
+	if (ret)
+		return ret;
+
 	if (config->requested_msi > 32)
 		config->requested_msi = 32;
 
@@ -330,9 +334,11 @@ static ssize_t pcie_gadget_store_inta(
 {
 	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
 	ulong en;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &en))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &en);
+	if (ret)
+		return ret;
 
 	if (en)
 		writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID),
@@ -351,9 +357,11 @@ static ssize_t pcie_gadget_store_send_ms
 	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
 	ulong vector;
 	u32 ven_msi;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &vector))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &vector);
+	if (ret)
+		return ret;
 
 	if (!config->configured_msi)
 		return -EINVAL;
@@ -395,9 +403,11 @@ static ssize_t pcie_gadget_store_vendor_
 		const char *buf, size_t count)
 {
 	ulong id;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &id))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &id);
+	if (ret)
+		return ret;
 
 	spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id);
 
@@ -420,9 +430,11 @@ static ssize_t pcie_gadget_store_device_
 		const char *buf, size_t count)
 {
 	ulong id;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &id))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &id);
+	if (ret)
+		return ret;
 
 	spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id);
 
@@ -443,9 +455,12 @@ static ssize_t pcie_gadget_store_bar0_si
 	ulong size;
 	u32 pos, pos1;
 	u32 no_of_bit = 0;
+	int ret;
+
+	ret = kstrtoul(buf, 0, &size);
+	if (ret)
+		return ret;
 
-	if (strict_strtoul(buf, 0, &size))
-		return -EINVAL;
 	/* min bar size is 256 */
 	if (size <= 0x100)
 		size = 0x100;
@@ -490,9 +505,11 @@ static ssize_t pcie_gadget_store_bar0_ad
 {
 	struct pcie_app_reg __iomem *app_reg = config->va_app_base;
 	ulong address;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &address))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &address);
+	if (ret)
+		return ret;
 
 	address &= ~(config->bar0_size - 1);
 	if (config->va_bar0_address)
@@ -518,9 +535,11 @@ static ssize_t pcie_gadget_store_bar0_rw
 		const char *buf, size_t count)
 {
 	ulong offset;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &offset))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &offset);
+	if (ret)
+		return ret;
 
 	if (offset % 4)
 		return -EINVAL;
@@ -549,9 +568,11 @@ static ssize_t pcie_gadget_store_bar0_da
 		const char *buf, size_t count)
 {
 	ulong data;
+	int ret;
 
-	if (strict_strtoul(buf, 0, &data))
-		return -EINVAL;
+	ret = kstrtoul(buf, 0, &data);
+	if (ret)
+		return ret;
 
 	if (!config->va_bar0_address)
 		return -ENOMEM;
@@ -776,7 +797,7 @@ static int spear_pcie_gadget_probe(struc
 		goto err_iounmap_app;
 	}
 
-	dev_set_drvdata(&pdev->dev, target);
+	platform_set_drvdata(pdev, target);
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -814,9 +835,11 @@ static int spear_pcie_gadget_probe(struc
 		clk = clk_get_sys("pcie1", NULL);
 		if (IS_ERR(clk)) {
 			pr_err("%s:couldn't get clk for pcie1\n", __func__);
+			status = PTR_ERR(clk);
 			goto err_irq;
 		}
-		if (clk_enable(clk)) {
+		status = clk_enable(clk);
+		if (status) {
 			pr_err("%s:couldn't enable clk for pcie1\n", __func__);
 			goto err_irq;
 		}
@@ -828,9 +851,11 @@ static int spear_pcie_gadget_probe(struc
 		clk = clk_get_sys("pcie2", NULL);
 		if (IS_ERR(clk)) {
 			pr_err("%s:couldn't get clk for pcie2\n", __func__);
+			status = PTR_ERR(clk);
 			goto err_irq;
 		}
-		if (clk_enable(clk)) {
+		status = clk_enable(clk);
+		if (status) {
 			pr_err("%s:couldn't enable clk for pcie2\n", __func__);
 			goto err_irq;
 		}
@@ -863,7 +888,7 @@ static int spear_pcie_gadget_remove(stru
 	res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	irq = platform_get_irq(pdev, 0);
-	target = dev_get_drvdata(&pdev->dev);
+	target = platform_get_drvdata(pdev);
 	config = &target->config;
 
 	free_irq(irq, NULL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/sram.c linux-libre-3.11-rc7-gnu/drivers/misc/sram.c
--- linux-libre-3.10-gnu/drivers/misc/sram.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/sram.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,15 +45,12 @@ static int sram_probe(struct platform_de
 	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -EINVAL;
+	virt_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(virt_base))
+		return PTR_ERR(virt_base);
 
 	size = resource_size(res);
 
-	virt_base = devm_request_and_ioremap(&pdev->dev, res);
-	if (!virt_base)
-		return -EADDRNOTAVAIL;
-
 	sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
 	if (!sram)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/ti_dac7512.c linux-libre-3.11-rc7-gnu/drivers/misc/ti_dac7512.c
--- linux-libre-3.10-gnu/drivers/misc/ti_dac7512.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/ti_dac7512.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,9 +33,11 @@ static ssize_t dac7512_store_val(struct
 	struct spi_device *spi = to_spi_device(dev);
 	unsigned char tmp[2];
 	unsigned long val;
+	int ret;
 
-	if (strict_strtoul(buf, 10, &val) < 0)
-		return -EINVAL;
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
 
 	tmp[0] = val >> 8;
 	tmp[1] = val & 0xff;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/ti-st/st_kim.c linux-libre-3.11-rc7-gnu/drivers/misc/ti-st/st_kim.c
--- linux-libre-3.10-gnu/drivers/misc/ti-st/st_kim.c	2013-07-01 10:41:24.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/ti-st/st_kim.c	2013-08-31 18:01:09.000000000 -0400
@@ -680,7 +680,7 @@ void st_kim_ref(struct st_data_s **core_
 		*core_data = NULL;
 		return;
 	}
-	kim_gdata = dev_get_drvdata(&pdev->dev);
+	kim_gdata = platform_get_drvdata(pdev);
 	*core_data = kim_gdata->core_data;
 }
 
@@ -735,7 +735,7 @@ static int kim_probe(struct platform_dev
 		pr_err("no mem to allocate");
 		return -ENOMEM;
 	}
-	dev_set_drvdata(&pdev->dev, kim_gdata);
+	platform_set_drvdata(pdev, kim_gdata);
 
 	err = st_core_init(&kim_gdata->core_data);
 	if (err != 0) {
@@ -810,7 +810,7 @@ static int kim_remove(struct platform_de
 	struct ti_st_plat_data	*pdata = pdev->dev.platform_data;
 	struct kim_data_s	*kim_gdata;
 
-	kim_gdata = dev_get_drvdata(&pdev->dev);
+	kim_gdata = platform_get_drvdata(pdev);
 
 	/* Free the Bluetooth/FM/GPIO
 	 * nShutdown gpio from the system
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/misc/tsl2550.c linux-libre-3.11-rc7-gnu/drivers/misc/tsl2550.c
--- linux-libre-3.10-gnu/drivers/misc/tsl2550.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/misc/tsl2550.c	2013-08-25 20:43:22.000000000 -0400
@@ -204,7 +204,7 @@ static ssize_t tsl2550_store_power_state
 	unsigned long val = simple_strtoul(buf, NULL, 10);
 	int ret;
 
-	if (val < 0 || val > 1)
+	if (val > 1)
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
@@ -236,7 +236,7 @@ static ssize_t tsl2550_store_operating_m
 	unsigned long val = simple_strtoul(buf, NULL, 10);
 	int ret;
 
-	if (val < 0 || val > 1)
+	if (val > 1)
 		return -EINVAL;
 
 	if (data->power_state == 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/card/block.c linux-libre-3.11-rc7-gnu/drivers/mmc/card/block.c
--- linux-libre-3.10-gnu/drivers/mmc/card/block.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/card/block.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <linux/capability.h>
 #include <linux/compat.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/mmc/ioctl.h>
 #include <linux/mmc/card.h>
@@ -58,6 +59,8 @@ MODULE_ALIAS("mmc:block");
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88
 #define MMC_BLK_TIMEOUT_MS  (10 * 60 * 1000)        /* 10 minute timeout */
+#define MMC_SANITIZE_REQ_TIMEOUT 240000
+#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)
 
 #define mmc_req_rel_wr(req)	(((req->cmd_flags & REQ_FUA) || \
 				  (req->cmd_flags & REQ_META)) && \
@@ -222,7 +225,7 @@ static ssize_t power_ro_lock_store(struc
 	md = mmc_blk_get(dev_to_disk(dev));
 	card = md->queue.card;
 
-	mmc_claim_host(card->host);
+	mmc_get_card(card);
 
 	ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP,
 				card->ext_csd.boot_ro_lock |
@@ -233,7 +236,7 @@ static ssize_t power_ro_lock_store(struc
 	else
 		card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN;
 
-	mmc_release_host(card->host);
+	mmc_put_card(card);
 
 	if (!ret) {
 		pr_info("%s: Locking boot partition ro until next power on\n",
@@ -408,6 +411,35 @@ static int ioctl_rpmb_card_status_poll(s
 	return err;
 }
 
+static int ioctl_do_sanitize(struct mmc_card *card)
+{
+	int err;
+
+	if (!(mmc_can_sanitize(card) &&
+	      (card->host->caps2 & MMC_CAP2_SANITIZE))) {
+			pr_warn("%s: %s - SANITIZE is not supported\n",
+				mmc_hostname(card->host), __func__);
+			err = -EOPNOTSUPP;
+			goto out;
+	}
+
+	pr_debug("%s: %s - SANITIZE IN PROGRESS...\n",
+		mmc_hostname(card->host), __func__);
+
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+					EXT_CSD_SANITIZE_START, 1,
+					MMC_SANITIZE_REQ_TIMEOUT);
+
+	if (err)
+		pr_err("%s: %s - EXT_CSD_SANITIZE_START failed. err=%d\n",
+		       mmc_hostname(card->host), __func__, err);
+
+	pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host),
+					     __func__);
+out:
+	return err;
+}
+
 static int mmc_blk_ioctl_cmd(struct block_device *bdev,
 	struct mmc_ioc_cmd __user *ic_ptr)
 {
@@ -491,7 +523,7 @@ static int mmc_blk_ioctl_cmd(struct bloc
 
 	mrq.cmd = &cmd;
 
-	mmc_claim_host(card->host);
+	mmc_get_card(card);
 
 	err = mmc_blk_part_switch(card, md);
 	if (err)
@@ -510,6 +542,17 @@ static int mmc_blk_ioctl_cmd(struct bloc
 			goto cmd_rel_host;
 	}
 
+	if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) &&
+	    (cmd.opcode == MMC_SWITCH)) {
+		err = ioctl_do_sanitize(card);
+
+		if (err)
+			pr_err("%s: ioctl_do_sanitize() failed. err = %d",
+			       __func__, err);
+
+		goto cmd_rel_host;
+	}
+
 	mmc_wait_for_req(card->host, &mrq);
 
 	if (cmd.error) {
@@ -558,7 +601,7 @@ static int mmc_blk_ioctl_cmd(struct bloc
 	}
 
 cmd_rel_host:
-	mmc_release_host(card->host);
+	mmc_put_card(card);
 
 cmd_done:
 	mmc_blk_put(md);
@@ -939,10 +982,10 @@ static int mmc_blk_issue_secdiscard_rq(s
 {
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
-	unsigned int from, nr, arg, trim_arg, erase_arg;
+	unsigned int from, nr, arg;
 	int err = 0, type = MMC_BLK_SECDISCARD;
 
-	if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
+	if (!(mmc_can_secure_erase_trim(card))) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -950,23 +993,11 @@ static int mmc_blk_issue_secdiscard_rq(s
 	from = blk_rq_pos(req);
 	nr = blk_rq_sectors(req);
 
-	/* The sanitize operation is supported at v4.5 only */
-	if (mmc_can_sanitize(card)) {
-		erase_arg = MMC_ERASE_ARG;
-		trim_arg = MMC_TRIM_ARG;
-	} else {
-		erase_arg = MMC_SECURE_ERASE_ARG;
-		trim_arg = MMC_SECURE_TRIM1_ARG;
-	}
+	if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
+		arg = MMC_SECURE_TRIM1_ARG;
+	else
+		arg = MMC_SECURE_ERASE_ARG;
 
-	if (mmc_erase_group_aligned(card, from, nr))
-		arg = erase_arg;
-	else if (mmc_can_trim(card))
-		arg = trim_arg;
-	else {
-		err = -EINVAL;
-		goto out;
-	}
 retry:
 	if (card->quirks & MMC_QUIRK_INAND_CMD38) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
@@ -1002,9 +1033,6 @@ retry:
 			goto out;
 	}
 
-	if (mmc_can_sanitize(card))
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-				 EXT_CSD_SANITIZE_START, 1, 0);
 out_retry:
 	if (err && !mmc_blk_reset(md, card->host, type))
 		goto retry;
@@ -1895,7 +1923,7 @@ static int mmc_blk_issue_rq(struct mmc_q
 
 	if (req && !mq->mqrq_prev->req)
 		/* claim host only for the first request */
-		mmc_claim_host(card->host);
+		mmc_get_card(card);
 
 	ret = mmc_blk_part_switch(card, md);
 	if (ret) {
@@ -1939,7 +1967,7 @@ out:
 		 * In case sepecial request, there is no reentry to
 		 * the 'mmc_blk_issue_rq' with 'mqrq_prev->req'.
 		 */
-		mmc_release_host(card->host);
+		mmc_put_card(card);
 	return ret;
 }
 
@@ -2158,6 +2186,14 @@ static void mmc_blk_remove_req(struct mm
 	struct mmc_card *card;
 
 	if (md) {
+		/*
+		 * Flush remaining requests and free queues. It
+		 * is freeing the queue that stops new requests
+		 * from being accepted.
+		 */
+		mmc_cleanup_queue(&md->queue);
+		if (md->flags & MMC_BLK_PACKED_CMD)
+			mmc_packed_clean(&md->queue);
 		card = md->queue.card;
 		if (md->disk->flags & GENHD_FL_UP) {
 			device_remove_file(disk_to_dev(md->disk), &md->force_ro);
@@ -2166,14 +2202,8 @@ static void mmc_blk_remove_req(struct mm
 				device_remove_file(disk_to_dev(md->disk),
 					&md->power_ro_lock);
 
-			/* Stop new requests from getting into the queue */
 			del_gendisk(md->disk);
 		}
-
-		/* Then flush out any already in there */
-		mmc_cleanup_queue(&md->queue);
-		if (md->flags & MMC_BLK_PACKED_CMD)
-			mmc_packed_clean(&md->queue);
 		mmc_blk_put(md);
 	}
 }
@@ -2336,6 +2366,19 @@ static int mmc_blk_probe(struct mmc_card
 		if (mmc_add_disk(part_md))
 			goto out;
 	}
+
+	pm_runtime_set_autosuspend_delay(&card->dev, 3000);
+	pm_runtime_use_autosuspend(&card->dev);
+
+	/*
+	 * Don't enable runtime PM for SD-combo cards here. Leave that
+	 * decision to be taken during the SDIO init sequence instead.
+	 */
+	if (card->type != MMC_TYPE_SD_COMBO) {
+		pm_runtime_set_active(&card->dev);
+		pm_runtime_enable(&card->dev);
+	}
+
 	return 0;
 
  out:
@@ -2349,20 +2392,24 @@ static void mmc_blk_remove(struct mmc_ca
 	struct mmc_blk_data *md = mmc_get_drvdata(card);
 
 	mmc_blk_remove_parts(card, md);
+	pm_runtime_get_sync(&card->dev);
 	mmc_claim_host(card->host);
 	mmc_blk_part_switch(card, md);
 	mmc_release_host(card->host);
+	if (card->type != MMC_TYPE_SD_COMBO)
+		pm_runtime_disable(&card->dev);
+	pm_runtime_put_noidle(&card->dev);
 	mmc_blk_remove_req(md);
 	mmc_set_drvdata(card, NULL);
 }
 
-#ifdef CONFIG_PM
-static int mmc_blk_suspend(struct mmc_card *card)
+static int _mmc_blk_suspend(struct mmc_card *card)
 {
 	struct mmc_blk_data *part_md;
 	struct mmc_blk_data *md = mmc_get_drvdata(card);
 
 	if (md) {
+		pm_runtime_get_sync(&card->dev);
 		mmc_queue_suspend(&md->queue);
 		list_for_each_entry(part_md, &md->part, part) {
 			mmc_queue_suspend(&part_md->queue);
@@ -2371,6 +2418,17 @@ static int mmc_blk_suspend(struct mmc_ca
 	return 0;
 }
 
+static void mmc_blk_shutdown(struct mmc_card *card)
+{
+	_mmc_blk_suspend(card);
+}
+
+#ifdef CONFIG_PM
+static int mmc_blk_suspend(struct mmc_card *card)
+{
+	return _mmc_blk_suspend(card);
+}
+
 static int mmc_blk_resume(struct mmc_card *card)
 {
 	struct mmc_blk_data *part_md;
@@ -2386,6 +2444,7 @@ static int mmc_blk_resume(struct mmc_car
 		list_for_each_entry(part_md, &md->part, part) {
 			mmc_queue_resume(&part_md->queue);
 		}
+		pm_runtime_put(&card->dev);
 	}
 	return 0;
 }
@@ -2402,6 +2461,7 @@ static struct mmc_driver mmc_driver = {
 	.remove		= mmc_blk_remove,
 	.suspend	= mmc_blk_suspend,
 	.resume		= mmc_blk_resume,
+	.shutdown	= mmc_blk_shutdown,
 };
 
 static int __init mmc_blk_init(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/card/mmc_test.c linux-libre-3.11-rc7-gnu/drivers/mmc/card/mmc_test.c
--- linux-libre-3.10-gnu/drivers/mmc/card/mmc_test.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/card/mmc_test.c	2013-08-25 20:43:22.000000000 -0400
@@ -3025,12 +3025,17 @@ static void mmc_test_remove(struct mmc_c
 	mmc_test_free_dbgfs_file(card);
 }
 
+static void mmc_test_shutdown(struct mmc_card *card)
+{
+}
+
 static struct mmc_driver mmc_driver = {
 	.drv		= {
 		.name	= "mmc_test",
 	},
 	.probe		= mmc_test_probe,
 	.remove		= mmc_test_remove,
+	.shutdown	= mmc_test_shutdown,
 };
 
 static int __init mmc_test_init(void)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/card/queue.c linux-libre-3.11-rc7-gnu/drivers/mmc/card/queue.c
--- linux-libre-3.10-gnu/drivers/mmc/card/queue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/card/queue.c	2013-08-25 20:43:22.000000000 -0400
@@ -173,7 +173,7 @@ static void mmc_queue_setup_discard(stru
 	/* granularity must not be greater than max. discard */
 	if (card->pref_erase > max_discard)
 		q->limits.discard_granularity = 0;
-	if (mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))
+	if (mmc_can_secure_erase_trim(card))
 		queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/bus.c linux-libre-3.11-rc7-gnu/drivers/mmc/core/bus.c
--- linux-libre-3.10-gnu/drivers/mmc/core/bus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -122,15 +122,39 @@ static int mmc_bus_remove(struct device
 	return 0;
 }
 
+static void mmc_bus_shutdown(struct device *dev)
+{
+	struct mmc_driver *drv = to_mmc_driver(dev->driver);
+	struct mmc_card *card = mmc_dev_to_card(dev);
+	struct mmc_host *host = card->host;
+	int ret;
+
+	if (dev->driver && drv->shutdown)
+		drv->shutdown(card);
+
+	if (host->bus_ops->shutdown) {
+		ret = host->bus_ops->shutdown(host);
+		if (ret)
+			pr_warn("%s: error %d during shutdown\n",
+				mmc_hostname(host), ret);
+	}
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int mmc_bus_suspend(struct device *dev)
 {
 	struct mmc_driver *drv = to_mmc_driver(dev->driver);
 	struct mmc_card *card = mmc_dev_to_card(dev);
-	int ret = 0;
+	struct mmc_host *host = card->host;
+	int ret;
 
-	if (dev->driver && drv->suspend)
+	if (dev->driver && drv->suspend) {
 		ret = drv->suspend(card);
+		if (ret)
+			return ret;
+	}
+
+	ret = host->bus_ops->suspend(host);
 	return ret;
 }
 
@@ -138,10 +162,17 @@ static int mmc_bus_resume(struct device
 {
 	struct mmc_driver *drv = to_mmc_driver(dev->driver);
 	struct mmc_card *card = mmc_dev_to_card(dev);
-	int ret = 0;
+	struct mmc_host *host = card->host;
+	int ret;
+
+	ret = host->bus_ops->resume(host);
+	if (ret)
+		pr_warn("%s: error %d during resume (card was removed?)\n",
+			mmc_hostname(host), ret);
 
 	if (dev->driver && drv->resume)
 		ret = drv->resume(card);
+
 	return ret;
 }
 #endif
@@ -151,20 +182,30 @@ static int mmc_bus_resume(struct device
 static int mmc_runtime_suspend(struct device *dev)
 {
 	struct mmc_card *card = mmc_dev_to_card(dev);
+	struct mmc_host *host = card->host;
+	int ret = 0;
 
-	return mmc_power_save_host(card->host);
+	if (host->bus_ops->runtime_suspend)
+		ret = host->bus_ops->runtime_suspend(host);
+
+	return ret;
 }
 
 static int mmc_runtime_resume(struct device *dev)
 {
 	struct mmc_card *card = mmc_dev_to_card(dev);
+	struct mmc_host *host = card->host;
+	int ret = 0;
 
-	return mmc_power_restore_host(card->host);
+	if (host->bus_ops->runtime_resume)
+		ret = host->bus_ops->runtime_resume(host);
+
+	return ret;
 }
 
 static int mmc_runtime_idle(struct device *dev)
 {
-	return pm_runtime_suspend(dev);
+	return 0;
 }
 
 #endif /* !CONFIG_PM_RUNTIME */
@@ -182,6 +223,7 @@ static struct bus_type mmc_bus_type = {
 	.uevent		= mmc_bus_uevent,
 	.probe		= mmc_bus_probe,
 	.remove		= mmc_bus_remove,
+	.shutdown	= mmc_bus_shutdown,
 	.pm		= &mmc_bus_pm_ops,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/core.c linux-libre-3.11-rc7-gnu/drivers/mmc/core/core.c
--- linux-libre-3.10-gnu/drivers/mmc/core/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -402,6 +402,7 @@ static int mmc_wait_for_data_req_done(st
 			context_info->is_done_rcv = false;
 			context_info->is_new_req = false;
 			cmd = mrq->cmd;
+
 			if (!cmd->error || !cmd->retries ||
 			    mmc_card_removed(host->card)) {
 				err = host->areq->err_check(host->card,
@@ -436,6 +437,24 @@ static void mmc_wait_for_req_done(struct
 		wait_for_completion(&mrq->completion);
 
 		cmd = mrq->cmd;
+
+		/*
+		 * If host has timed out waiting for the sanitize
+		 * to complete, card might be still in programming state
+		 * so let's try to bring the card out of programming
+		 * state.
+		 */
+		if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT) {
+			if (!mmc_interrupt_hpi(host->card)) {
+				pr_warning("%s: %s: Interrupted sanitize\n",
+					   mmc_hostname(host), __func__);
+				cmd->error = 0;
+				break;
+			} else {
+				pr_err("%s: %s: Failed to interrupt sanitize\n",
+				       mmc_hostname(host), __func__);
+			}
+		}
 		if (!cmd->error || !cmd->retries ||
 		    mmc_card_removed(host->card))
 			break;
@@ -952,6 +971,29 @@ void mmc_release_host(struct mmc_host *h
 EXPORT_SYMBOL(mmc_release_host);
 
 /*
+ * This is a helper function, which fetches a runtime pm reference for the
+ * card device and also claims the host.
+ */
+void mmc_get_card(struct mmc_card *card)
+{
+	pm_runtime_get_sync(&card->dev);
+	mmc_claim_host(card->host);
+}
+EXPORT_SYMBOL(mmc_get_card);
+
+/*
+ * This is a helper function, which releases the host and drops the runtime
+ * pm reference for the card device.
+ */
+void mmc_put_card(struct mmc_card *card)
+{
+	mmc_release_host(card->host);
+	pm_runtime_mark_last_busy(&card->dev);
+	pm_runtime_put_autosuspend(&card->dev);
+}
+EXPORT_SYMBOL(mmc_put_card);
+
+/*
  * Internal function that does the actual ios call to the host driver,
  * optionally printing some debug output.
  */
@@ -1459,7 +1501,7 @@ void mmc_set_driver_type(struct mmc_host
  * If a host does all the power sequencing itself, ignore the
  * initial MMC_POWER_UP stage.
  */
-static void mmc_power_up(struct mmc_host *host)
+void mmc_power_up(struct mmc_host *host)
 {
 	int bit;
 
@@ -2325,14 +2367,13 @@ int mmc_detect_card_removed(struct mmc_h
 	 * The card will be considered unchanged unless we have been asked to
 	 * detect a change or host requires polling to provide card detection.
 	 */
-	if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) &&
-	    !(host->caps2 & MMC_CAP2_DETECT_ON_ERR))
+	if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL))
 		return ret;
 
 	host->detect_change = 0;
 	if (!ret) {
 		ret = _mmc_detect_card_removed(host);
-		if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) {
+		if (ret && (host->caps & MMC_CAP_NEEDS_POLL)) {
 			/*
 			 * Schedule a detect work as soon as possible to let a
 			 * rescan handle the card removal.
@@ -2442,9 +2483,7 @@ void mmc_stop_host(struct mmc_host *host
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
 		/* Calling bus_ops->remove() with a claimed host can deadlock */
-		if (host->bus_ops->remove)
-			host->bus_ops->remove(host);
-
+		host->bus_ops->remove(host);
 		mmc_claim_host(host);
 		mmc_detach_bus(host);
 		mmc_power_off(host);
@@ -2509,52 +2548,6 @@ int mmc_power_restore_host(struct mmc_ho
 }
 EXPORT_SYMBOL(mmc_power_restore_host);
 
-int mmc_card_awake(struct mmc_host *host)
-{
-	int err = -ENOSYS;
-
-	if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
-		return 0;
-
-	mmc_bus_get(host);
-
-	if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
-		err = host->bus_ops->awake(host);
-
-	mmc_bus_put(host);
-
-	return err;
-}
-EXPORT_SYMBOL(mmc_card_awake);
-
-int mmc_card_sleep(struct mmc_host *host)
-{
-	int err = -ENOSYS;
-
-	if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
-		return 0;
-
-	mmc_bus_get(host);
-
-	if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
-		err = host->bus_ops->sleep(host);
-
-	mmc_bus_put(host);
-
-	return err;
-}
-EXPORT_SYMBOL(mmc_card_sleep);
-
-int mmc_card_can_sleep(struct mmc_host *host)
-{
-	struct mmc_card *card = host->card;
-
-	if (card && mmc_card_mmc(card) && card->ext_csd.rev >= 3)
-		return 1;
-	return 0;
-}
-EXPORT_SYMBOL(mmc_card_can_sleep);
-
 /*
  * Flush the cache to the non-volatile storage.
  */
@@ -2626,48 +2619,9 @@ EXPORT_SYMBOL(mmc_cache_ctrl);
  */
 int mmc_suspend_host(struct mmc_host *host)
 {
-	int err = 0;
-
-	cancel_delayed_work(&host->detect);
-	mmc_flush_scheduled_work();
-
-	mmc_bus_get(host);
-	if (host->bus_ops && !host->bus_dead) {
-		if (host->bus_ops->suspend) {
-			if (mmc_card_doing_bkops(host->card)) {
-				err = mmc_stop_bkops(host->card);
-				if (err)
-					goto out;
-			}
-			err = host->bus_ops->suspend(host);
-		}
-
-		if (err == -ENOSYS || !host->bus_ops->resume) {
-			/*
-			 * We simply "remove" the card in this case.
-			 * It will be redetected on resume.  (Calling
-			 * bus_ops->remove() with a claimed host can
-			 * deadlock.)
-			 */
-			if (host->bus_ops->remove)
-				host->bus_ops->remove(host);
-			mmc_claim_host(host);
-			mmc_detach_bus(host);
-			mmc_power_off(host);
-			mmc_release_host(host);
-			host->pm_flags = 0;
-			err = 0;
-		}
-	}
-	mmc_bus_put(host);
-
-	if (!err && !mmc_card_keep_power(host))
-		mmc_power_off(host);
-
-out:
-	return err;
+	/* This function is deprecated */
+	return 0;
 }
-
 EXPORT_SYMBOL(mmc_suspend_host);
 
 /**
@@ -2676,39 +2630,8 @@ EXPORT_SYMBOL(mmc_suspend_host);
  */
 int mmc_resume_host(struct mmc_host *host)
 {
-	int err = 0;
-
-	mmc_bus_get(host);
-	if (host->bus_ops && !host->bus_dead) {
-		if (!mmc_card_keep_power(host)) {
-			mmc_power_up(host);
-			mmc_select_voltage(host, host->ocr);
-			/*
-			 * Tell runtime PM core we just powered up the card,
-			 * since it still believes the card is powered off.
-			 * Note that currently runtime PM is only enabled
-			 * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
-			 */
-			if (mmc_card_sdio(host->card) &&
-			    (host->caps & MMC_CAP_POWER_OFF_CARD)) {
-				pm_runtime_disable(&host->card->dev);
-				pm_runtime_set_active(&host->card->dev);
-				pm_runtime_enable(&host->card->dev);
-			}
-		}
-		BUG_ON(!host->bus_ops->resume);
-		err = host->bus_ops->resume(host);
-		if (err) {
-			pr_warning("%s: error %d during resume "
-					    "(card was removed?)\n",
-					    mmc_hostname(host), err);
-			err = 0;
-		}
-	}
-	host->pm_flags &= ~MMC_PM_KEEP_POWER;
-	mmc_bus_put(host);
-
-	return err;
+	/* This function is deprecated */
+	return 0;
 }
 EXPORT_SYMBOL(mmc_resume_host);
 
@@ -2727,29 +2650,22 @@ int mmc_pm_notify(struct notifier_block
 	switch (mode) {
 	case PM_HIBERNATION_PREPARE:
 	case PM_SUSPEND_PREPARE:
-		if (host->card && mmc_card_mmc(host->card) &&
-		    mmc_card_doing_bkops(host->card)) {
-			err = mmc_stop_bkops(host->card);
-			if (err) {
-				pr_err("%s: didn't stop bkops\n",
-					mmc_hostname(host));
-				return err;
-			}
-			mmc_card_clr_doing_bkops(host->card);
-		}
-
 		spin_lock_irqsave(&host->lock, flags);
 		host->rescan_disable = 1;
 		spin_unlock_irqrestore(&host->lock, flags);
 		cancel_delayed_work_sync(&host->detect);
 
-		if (!host->bus_ops || host->bus_ops->suspend)
+		if (!host->bus_ops)
 			break;
 
-		/* Calling bus_ops->remove() with a claimed host can deadlock */
-		if (host->bus_ops->remove)
-			host->bus_ops->remove(host);
+		/* Validate prerequisites for suspend */
+		if (host->bus_ops->pre_suspend)
+			err = host->bus_ops->pre_suspend(host);
+		if (!err && host->bus_ops->suspend)
+			break;
 
+		/* Calling bus_ops->remove() with a claimed host can deadlock */
+		host->bus_ops->remove(host);
 		mmc_claim_host(host);
 		mmc_detach_bus(host);
 		mmc_power_off(host);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/core.h linux-libre-3.11-rc7-gnu/drivers/mmc/core/core.h
--- linux-libre-3.10-gnu/drivers/mmc/core/core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/core.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,15 +16,17 @@
 #define MMC_CMD_RETRIES        3
 
 struct mmc_bus_ops {
-	int (*awake)(struct mmc_host *);
-	int (*sleep)(struct mmc_host *);
 	void (*remove)(struct mmc_host *);
 	void (*detect)(struct mmc_host *);
+	int (*pre_suspend)(struct mmc_host *);
 	int (*suspend)(struct mmc_host *);
 	int (*resume)(struct mmc_host *);
+	int (*runtime_suspend)(struct mmc_host *);
+	int (*runtime_resume)(struct mmc_host *);
 	int (*power_save)(struct mmc_host *);
 	int (*power_restore)(struct mmc_host *);
 	int (*alive)(struct mmc_host *);
+	int (*shutdown)(struct mmc_host *);
 };
 
 void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
@@ -44,6 +46,7 @@ int mmc_set_signal_voltage(struct mmc_ho
 int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
 void mmc_set_timing(struct mmc_host *host, unsigned int timing);
 void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
+void mmc_power_up(struct mmc_host *host);
 void mmc_power_off(struct mmc_host *host);
 void mmc_power_cycle(struct mmc_host *host);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/debugfs.c linux-libre-3.11-rc7-gnu/drivers/mmc/core/debugfs.c
--- linux-libre-3.10-gnu/drivers/mmc/core/debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -258,13 +258,13 @@ static int mmc_dbg_card_status_get(void
 	u32		status;
 	int		ret;
 
-	mmc_claim_host(card->host);
+	mmc_get_card(card);
 
 	ret = mmc_send_status(data, &status);
 	if (!ret)
 		*val = status;
 
-	mmc_release_host(card->host);
+	mmc_put_card(card);
 
 	return ret;
 }
@@ -291,9 +291,9 @@ static int mmc_ext_csd_open(struct inode
 		goto out_free;
 	}
 
-	mmc_claim_host(card->host);
+	mmc_get_card(card);
 	err = mmc_send_ext_csd(card, ext_csd);
-	mmc_release_host(card->host);
+	mmc_put_card(card);
 	if (err)
 		goto out_free;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/host.c linux-libre-3.11-rc7-gnu/drivers/mmc/core/host.c
--- linux-libre-3.10-gnu/drivers/mmc/core/host.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/host.c	2013-08-25 20:43:22.000000000 -0400
@@ -306,7 +306,7 @@ static inline void mmc_host_clk_sysfs_in
  * parse the properties and set respective generic mmc-host flags and
  * parameters.
  */
-void mmc_of_parse(struct mmc_host *host)
+int mmc_of_parse(struct mmc_host *host)
 {
 	struct device_node *np;
 	u32 bus_width;
@@ -315,7 +315,7 @@ void mmc_of_parse(struct mmc_host *host)
 	int len, ret, gpio;
 
 	if (!host->parent || !host->parent->of_node)
-		return;
+		return 0;
 
 	np = host->parent->of_node;
 
@@ -338,6 +338,7 @@ void mmc_of_parse(struct mmc_host *host)
 	default:
 		dev_err(host->parent,
 			"Invalid \"bus-width\" value %ud!\n", bus_width);
+		return -EINVAL;
 	}
 
 	/* f_max is obtained from the optional "max-frequency" property */
@@ -367,18 +368,22 @@ void mmc_of_parse(struct mmc_host *host)
 			host->caps |= MMC_CAP_NEEDS_POLL;
 
 		gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags);
+		if (gpio == -EPROBE_DEFER)
+			return gpio;
 		if (gpio_is_valid(gpio)) {
 			if (!(flags & OF_GPIO_ACTIVE_LOW))
 				gpio_inv_cd = true;
 
 			ret = mmc_gpio_request_cd(host, gpio);
-			if (ret < 0)
+			if (ret < 0) {
 				dev_err(host->parent,
 					"Failed to request CD GPIO #%d: %d!\n",
 					gpio, ret);
-			else
+				return ret;
+			} else {
 				dev_info(host->parent, "Got CD GPIO #%d.\n",
 					 gpio);
+			}
 		}
 
 		if (explicit_inv_cd ^ gpio_inv_cd)
@@ -389,14 +394,23 @@ void mmc_of_parse(struct mmc_host *host)
 	explicit_inv_wp = of_property_read_bool(np, "wp-inverted");
 
 	gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags);
+	if (gpio == -EPROBE_DEFER) {
+		ret = -EPROBE_DEFER;
+		goto out;
+	}
 	if (gpio_is_valid(gpio)) {
 		if (!(flags & OF_GPIO_ACTIVE_LOW))
 			gpio_inv_wp = true;
 
 		ret = mmc_gpio_request_ro(host, gpio);
-		if (ret < 0)
+		if (ret < 0) {
 			dev_err(host->parent,
 				"Failed to request WP GPIO: %d!\n", ret);
+			goto out;
+		} else {
+				dev_info(host->parent, "Got WP GPIO #%d.\n",
+					 gpio);
+		}
 	}
 	if (explicit_inv_wp ^ gpio_inv_wp)
 		host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
@@ -409,10 +423,18 @@ void mmc_of_parse(struct mmc_host *host)
 		host->caps |= MMC_CAP_POWER_OFF_CARD;
 	if (of_find_property(np, "cap-sdio-irq", &len))
 		host->caps |= MMC_CAP_SDIO_IRQ;
+	if (of_find_property(np, "full-pwr-cycle", &len))
+		host->caps2 |= MMC_CAP2_FULL_PWR_CYCLE;
 	if (of_find_property(np, "keep-power-in-suspend", &len))
 		host->pm_caps |= MMC_PM_KEEP_POWER;
 	if (of_find_property(np, "enable-sdio-wakeup", &len))
 		host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
+
+	return 0;
+
+out:
+	mmc_gpio_free_cd(host);
+	return ret;
 }
 
 EXPORT_SYMBOL(mmc_of_parse);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/mmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/core/mmc.c
--- linux-libre-3.10-gnu/drivers/mmc/core/mmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/mmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -293,7 +293,7 @@ static int mmc_read_ext_csd(struct mmc_c
 	}
 
 	card->ext_csd.rev = ext_csd[EXT_CSD_REV];
-	if (card->ext_csd.rev > 6) {
+	if (card->ext_csd.rev > 7) {
 		pr_err("%s: unrecognised EXT_CSD revision %d\n",
 			mmc_hostname(card->host), card->ext_csd.rev);
 		err = -EINVAL;
@@ -461,9 +461,31 @@ static int mmc_read_ext_csd(struct mmc_c
 		 */
 		card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP];
 		card->ext_csd.boot_ro_lockable = true;
+
+		/* Save power class values */
+		card->ext_csd.raw_pwr_cl_52_195 =
+			ext_csd[EXT_CSD_PWR_CL_52_195];
+		card->ext_csd.raw_pwr_cl_26_195 =
+			ext_csd[EXT_CSD_PWR_CL_26_195];
+		card->ext_csd.raw_pwr_cl_52_360 =
+			ext_csd[EXT_CSD_PWR_CL_52_360];
+		card->ext_csd.raw_pwr_cl_26_360 =
+			ext_csd[EXT_CSD_PWR_CL_26_360];
+		card->ext_csd.raw_pwr_cl_200_195 =
+			ext_csd[EXT_CSD_PWR_CL_200_195];
+		card->ext_csd.raw_pwr_cl_200_360 =
+			ext_csd[EXT_CSD_PWR_CL_200_360];
+		card->ext_csd.raw_pwr_cl_ddr_52_195 =
+			ext_csd[EXT_CSD_PWR_CL_DDR_52_195];
+		card->ext_csd.raw_pwr_cl_ddr_52_360 =
+			ext_csd[EXT_CSD_PWR_CL_DDR_52_360];
 	}
 
 	if (card->ext_csd.rev >= 5) {
+		/* Adjust production date as per JEDEC JESD84-B451 */
+		if (card->cid.year < 2010)
+			card->cid.year += 16;
+
 		/* check whether the eMMC card supports BKOPS */
 		if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
 			card->ext_csd.bkops = 1;
@@ -607,7 +629,23 @@ static int mmc_compare_ext_csds(struct m
 		(card->ext_csd.raw_sectors[2] ==
 			bw_ext_csd[EXT_CSD_SEC_CNT + 2]) &&
 		(card->ext_csd.raw_sectors[3] ==
-			bw_ext_csd[EXT_CSD_SEC_CNT + 3]));
+			bw_ext_csd[EXT_CSD_SEC_CNT + 3]) &&
+		(card->ext_csd.raw_pwr_cl_52_195 ==
+			bw_ext_csd[EXT_CSD_PWR_CL_52_195]) &&
+		(card->ext_csd.raw_pwr_cl_26_195 ==
+			bw_ext_csd[EXT_CSD_PWR_CL_26_195]) &&
+		(card->ext_csd.raw_pwr_cl_52_360 ==
+			bw_ext_csd[EXT_CSD_PWR_CL_52_360]) &&
+		(card->ext_csd.raw_pwr_cl_26_360 ==
+			bw_ext_csd[EXT_CSD_PWR_CL_26_360]) &&
+		(card->ext_csd.raw_pwr_cl_200_195 ==
+			bw_ext_csd[EXT_CSD_PWR_CL_200_195]) &&
+		(card->ext_csd.raw_pwr_cl_200_360 ==
+			bw_ext_csd[EXT_CSD_PWR_CL_200_360]) &&
+		(card->ext_csd.raw_pwr_cl_ddr_52_195 ==
+			bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) &&
+		(card->ext_csd.raw_pwr_cl_ddr_52_360 ==
+			bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]));
 	if (err)
 		err = -EINVAL;
 
@@ -676,11 +714,10 @@ static struct device_type mmc_type = {
  * mmc_switch command.
  */
 static int mmc_select_powerclass(struct mmc_card *card,
-		unsigned int bus_width, u8 *ext_csd)
+		unsigned int bus_width)
 {
 	int err = 0;
-	unsigned int pwrclass_val;
-	unsigned int index = 0;
+	unsigned int pwrclass_val = 0;
 	struct mmc_host *host;
 
 	BUG_ON(!card);
@@ -688,9 +725,6 @@ static int mmc_select_powerclass(struct
 	host = card->host;
 	BUG_ON(!host);
 
-	if (ext_csd == NULL)
-		return 0;
-
 	/* Power class selection is supported for versions >= 4.0 */
 	if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
 		return 0;
@@ -702,13 +736,13 @@ static int mmc_select_powerclass(struct
 	switch (1 << host->ios.vdd) {
 	case MMC_VDD_165_195:
 		if (host->ios.clock <= 26000000)
-			index = EXT_CSD_PWR_CL_26_195;
+			pwrclass_val = card->ext_csd.raw_pwr_cl_26_195;
 		else if	(host->ios.clock <= 52000000)
-			index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
-				EXT_CSD_PWR_CL_52_195 :
-				EXT_CSD_PWR_CL_DDR_52_195;
+			pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
+				card->ext_csd.raw_pwr_cl_52_195 :
+				card->ext_csd.raw_pwr_cl_ddr_52_195;
 		else if (host->ios.clock <= 200000000)
-			index = EXT_CSD_PWR_CL_200_195;
+			pwrclass_val = card->ext_csd.raw_pwr_cl_200_195;
 		break;
 	case MMC_VDD_27_28:
 	case MMC_VDD_28_29:
@@ -720,13 +754,13 @@ static int mmc_select_powerclass(struct
 	case MMC_VDD_34_35:
 	case MMC_VDD_35_36:
 		if (host->ios.clock <= 26000000)
-			index = EXT_CSD_PWR_CL_26_360;
+			pwrclass_val = card->ext_csd.raw_pwr_cl_26_360;
 		else if	(host->ios.clock <= 52000000)
-			index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
-				EXT_CSD_PWR_CL_52_360 :
-				EXT_CSD_PWR_CL_DDR_52_360;
+			pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
+				card->ext_csd.raw_pwr_cl_52_360 :
+				card->ext_csd.raw_pwr_cl_ddr_52_360;
 		else if (host->ios.clock <= 200000000)
-			index = EXT_CSD_PWR_CL_200_360;
+			pwrclass_val = card->ext_csd.raw_pwr_cl_200_360;
 		break;
 	default:
 		pr_warning("%s: Voltage range not supported "
@@ -734,8 +768,6 @@ static int mmc_select_powerclass(struct
 		return -EINVAL;
 	}
 
-	pwrclass_val = ext_csd[index];
-
 	if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8))
 		pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >>
 				EXT_CSD_PWR_CL_8BIT_SHIFT;
@@ -1013,11 +1045,9 @@ static int mmc_init_card(struct mmc_host
 	}
 
 	/*
-	 * If the host supports the power_off_notify capability then
-	 * set the notification byte in the ext_csd register of device
+	 * Enable power_off_notification byte in the ext_csd register
 	 */
-	if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) &&
-	    (card->ext_csd.rev >= 6)) {
+	if (card->ext_csd.rev >= 6) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 				 EXT_CSD_POWER_OFF_NOTIFICATION,
 				 EXT_CSD_POWER_ON,
@@ -1131,7 +1161,7 @@ static int mmc_init_card(struct mmc_host
 
 		ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
 				EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
-		err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
+		err = mmc_select_powerclass(card, ext_csd_bits);
 		if (err)
 			pr_warning("%s: power class selection to bus width %d"
 				   " failed\n", mmc_hostname(card->host),
@@ -1164,8 +1194,7 @@ static int mmc_init_card(struct mmc_host
 			bus_width = bus_widths[idx];
 			if (bus_width == MMC_BUS_WIDTH_1)
 				ddr = 0; /* no DDR for 1-bit width */
-			err = mmc_select_powerclass(card, ext_csd_bits[idx][0],
-						    ext_csd);
+			err = mmc_select_powerclass(card, ext_csd_bits[idx][0]);
 			if (err)
 				pr_warning("%s: power class selection to "
 					   "bus width %d failed\n",
@@ -1195,8 +1224,7 @@ static int mmc_init_card(struct mmc_host
 		}
 
 		if (!err && ddr) {
-			err = mmc_select_powerclass(card, ext_csd_bits[idx][1],
-						    ext_csd);
+			err = mmc_select_powerclass(card, ext_csd_bits[idx][1]);
 			if (err)
 				pr_warning("%s: power class selection to "
 					   "bus width %d ddr %d failed\n",
@@ -1321,6 +1349,45 @@ err:
 	return err;
 }
 
+static int mmc_can_sleep(struct mmc_card *card)
+{
+	return (card && card->ext_csd.rev >= 3);
+}
+
+static int mmc_sleep(struct mmc_host *host)
+{
+	struct mmc_command cmd = {0};
+	struct mmc_card *card = host->card;
+	int err;
+
+	if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
+		return 0;
+
+	err = mmc_deselect_cards(host);
+	if (err)
+		return err;
+
+	cmd.opcode = MMC_SLEEP_AWAKE;
+	cmd.arg = card->rca << 16;
+	cmd.arg |= 1 << 15;
+
+	cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
+	err = mmc_wait_for_cmd(host, &cmd, 0);
+	if (err)
+		return err;
+
+	/*
+	 * If the host does not wait while the card signals busy, then we will
+	 * will have to wait the sleep/awake timeout.  Note, we cannot use the
+	 * SEND_STATUS command to poll the status because that command (and most
+	 * others) is invalid while the card sleeps.
+	 */
+	if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
+		mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000));
+
+	return err;
+}
+
 static int mmc_can_poweroff_notify(const struct mmc_card *card)
 {
 	return card &&
@@ -1380,14 +1447,14 @@ static void mmc_detect(struct mmc_host *
 	BUG_ON(!host);
 	BUG_ON(!host->card);
 
-	mmc_claim_host(host);
+	mmc_get_card(host->card);
 
 	/*
 	 * Just check if our card has been removed.
 	 */
 	err = _mmc_detect_card_removed(host);
 
-	mmc_release_host(host);
+	mmc_put_card(host->card);
 
 	if (err) {
 		mmc_remove(host);
@@ -1399,36 +1466,60 @@ static void mmc_detect(struct mmc_host *
 	}
 }
 
-/*
- * Suspend callback from host.
- */
-static int mmc_suspend(struct mmc_host *host)
+static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
 {
 	int err = 0;
+	unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT :
+					EXT_CSD_POWER_OFF_LONG;
 
 	BUG_ON(!host);
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
 
+	if (mmc_card_doing_bkops(host->card)) {
+		err = mmc_stop_bkops(host->card);
+		if (err)
+			goto out;
+	}
+
 	err = mmc_cache_ctrl(host, 0);
 	if (err)
 		goto out;
 
-	if (mmc_can_poweroff_notify(host->card))
-		err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
-	else if (mmc_card_can_sleep(host))
-		err = mmc_card_sleep(host);
+	if (mmc_can_poweroff_notify(host->card) &&
+		((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend))
+		err = mmc_poweroff_notify(host->card, notify_type);
+	else if (mmc_can_sleep(host->card))
+		err = mmc_sleep(host);
 	else if (!mmc_host_is_spi(host))
 		err = mmc_deselect_cards(host);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 
+	if (!err)
+		mmc_power_off(host);
 out:
 	mmc_release_host(host);
 	return err;
 }
 
 /*
+ * Suspend callback from host.
+ */
+static int mmc_suspend(struct mmc_host *host)
+{
+	return _mmc_suspend(host, true);
+}
+
+/*
+ * Shutdown callback
+ */
+static int mmc_shutdown(struct mmc_host *host)
+{
+	return _mmc_suspend(host, false);
+}
+
+/*
  * Resume callback from host.
  *
  * This function tries to determine if the same card is still present
@@ -1442,74 +1533,94 @@ static int mmc_resume(struct mmc_host *h
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
+	mmc_power_up(host);
+	mmc_select_voltage(host, host->ocr);
 	err = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
 	return err;
 }
 
-static int mmc_power_restore(struct mmc_host *host)
+
+/*
+ * Callback for runtime_suspend.
+ */
+static int mmc_runtime_suspend(struct mmc_host *host)
 {
-	int ret;
+	int err;
+
+	if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
+		return 0;
 
-	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 	mmc_claim_host(host);
-	ret = mmc_init_card(host, host->ocr, host->card);
-	mmc_release_host(host);
 
-	return ret;
+	err = mmc_suspend(host);
+	if (err) {
+		pr_err("%s: error %d doing aggessive suspend\n",
+			mmc_hostname(host), err);
+		goto out;
+	}
+	mmc_power_off(host);
+
+out:
+	mmc_release_host(host);
+	return err;
 }
 
-static int mmc_sleep(struct mmc_host *host)
+/*
+ * Callback for runtime_resume.
+ */
+static int mmc_runtime_resume(struct mmc_host *host)
 {
-	struct mmc_card *card = host->card;
-	int err = -ENOSYS;
+	int err;
 
-	if (card && card->ext_csd.rev >= 3) {
-		err = mmc_card_sleepawake(host, 1);
-		if (err < 0)
-			pr_debug("%s: Error %d while putting card into sleep",
-				 mmc_hostname(host), err);
-	}
+	if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
+		return 0;
 
-	return err;
+	mmc_claim_host(host);
+
+	mmc_power_up(host);
+	err = mmc_resume(host);
+	if (err)
+		pr_err("%s: error %d doing aggessive resume\n",
+			mmc_hostname(host), err);
+
+	mmc_release_host(host);
+	return 0;
 }
 
-static int mmc_awake(struct mmc_host *host)
+static int mmc_power_restore(struct mmc_host *host)
 {
-	struct mmc_card *card = host->card;
-	int err = -ENOSYS;
+	int ret;
 
-	if (card && card->ext_csd.rev >= 3) {
-		err = mmc_card_sleepawake(host, 0);
-		if (err < 0)
-			pr_debug("%s: Error %d while awaking sleeping card",
-				 mmc_hostname(host), err);
-	}
+	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
+	mmc_claim_host(host);
+	ret = mmc_init_card(host, host->ocr, host->card);
+	mmc_release_host(host);
 
-	return err;
+	return ret;
 }
 
 static const struct mmc_bus_ops mmc_ops = {
-	.awake = mmc_awake,
-	.sleep = mmc_sleep,
 	.remove = mmc_remove,
 	.detect = mmc_detect,
 	.suspend = NULL,
 	.resume = NULL,
 	.power_restore = mmc_power_restore,
 	.alive = mmc_alive,
+	.shutdown = mmc_shutdown,
 };
 
 static const struct mmc_bus_ops mmc_ops_unsafe = {
-	.awake = mmc_awake,
-	.sleep = mmc_sleep,
 	.remove = mmc_remove,
 	.detect = mmc_detect,
 	.suspend = mmc_suspend,
 	.resume = mmc_resume,
+	.runtime_suspend = mmc_runtime_suspend,
+	.runtime_resume = mmc_runtime_resume,
 	.power_restore = mmc_power_restore,
 	.alive = mmc_alive,
+	.shutdown = mmc_shutdown,
 };
 
 static void mmc_attach_bus_ops(struct mmc_host *host)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/mmc_ops.c linux-libre-3.11-rc7-gnu/drivers/mmc/core/mmc_ops.c
--- linux-libre-3.10-gnu/drivers/mmc/core/mmc_ops.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/mmc_ops.c	2013-08-25 20:43:22.000000000 -0400
@@ -59,40 +59,6 @@ int mmc_deselect_cards(struct mmc_host *
 	return _mmc_select_card(host, NULL);
 }
 
-int mmc_card_sleepawake(struct mmc_host *host, int sleep)
-{
-	struct mmc_command cmd = {0};
-	struct mmc_card *card = host->card;
-	int err;
-
-	if (sleep)
-		mmc_deselect_cards(host);
-
-	cmd.opcode = MMC_SLEEP_AWAKE;
-	cmd.arg = card->rca << 16;
-	if (sleep)
-		cmd.arg |= 1 << 15;
-
-	cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
-	err = mmc_wait_for_cmd(host, &cmd, 0);
-	if (err)
-		return err;
-
-	/*
-	 * If the host does not wait while the card signals busy, then we will
-	 * will have to wait the sleep/awake timeout.  Note, we cannot use the
-	 * SEND_STATUS command to poll the status because that command (and most
-	 * others) is invalid while the card sleeps.
-	 */
-	if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
-		mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000));
-
-	if (!sleep)
-		err = mmc_select_card(card);
-
-	return err;
-}
-
 int mmc_go_idle(struct mmc_host *host)
 {
 	int err;
@@ -431,6 +397,8 @@ int __mmc_switch(struct mmc_card *card,
 
 
 	cmd.cmd_timeout_ms = timeout_ms;
+	if (index == EXT_CSD_SANITIZE_START)
+		cmd.sanitize_busy = true;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
 	if (err)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/mmc_ops.h linux-libre-3.11-rc7-gnu/drivers/mmc/core/mmc_ops.h
--- linux-libre-3.10-gnu/drivers/mmc/core/mmc_ops.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/mmc_ops.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,6 @@ int mmc_send_status(struct mmc_card *car
 int mmc_send_cid(struct mmc_host *host, u32 *cid);
 int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);
 int mmc_spi_set_crc(struct mmc_host *host, int use_crc);
-int mmc_card_sleepawake(struct mmc_host *host, int sleep);
 int mmc_bus_test(struct mmc_card *card, u8 bus_width);
 int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/sd.c linux-libre-3.11-rc7-gnu/drivers/mmc/core/sd.c
--- linux-libre-3.10-gnu/drivers/mmc/core/sd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/sd.c	2013-08-25 20:43:22.000000000 -0400
@@ -646,8 +646,13 @@ static int mmc_sd_init_uhs_card(struct m
 	if (err)
 		goto out;
 
-	/* SPI mode doesn't define CMD19 */
-	if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) {
+	/*
+	 * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and
+	 * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
+	 */
+	if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning &&
+			(card->sd_bus_speed == UHS_SDR50_BUS_SPEED ||
+			 card->sd_bus_speed == UHS_SDR104_BUS_SPEED)) {
 		mmc_host_clk_hold(card->host);
 		err = card->host->ops->execute_tuning(card->host,
 						      MMC_SEND_TUNING_BLOCK);
@@ -1037,14 +1042,14 @@ static void mmc_sd_detect(struct mmc_hos
 	BUG_ON(!host);
 	BUG_ON(!host->card);
 
-	mmc_claim_host(host);
+	mmc_get_card(host->card);
 
 	/*
 	 * Just check if our card has been removed.
 	 */
 	err = _mmc_detect_card_removed(host);
 
-	mmc_release_host(host);
+	mmc_put_card(host->card);
 
 	if (err) {
 		mmc_sd_remove(host);
@@ -1070,6 +1075,8 @@ static int mmc_sd_suspend(struct mmc_hos
 	if (!mmc_host_is_spi(host))
 		err = mmc_deselect_cards(host);
 	host->card->state &= ~MMC_STATE_HIGHSPEED;
+	if (!err)
+		mmc_power_off(host);
 	mmc_release_host(host);
 
 	return err;
@@ -1089,12 +1096,61 @@ static int mmc_sd_resume(struct mmc_host
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
+	mmc_power_up(host);
+	mmc_select_voltage(host, host->ocr);
 	err = mmc_sd_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
 	return err;
 }
 
+/*
+ * Callback for runtime_suspend.
+ */
+static int mmc_sd_runtime_suspend(struct mmc_host *host)
+{
+	int err;
+
+	if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
+		return 0;
+
+	mmc_claim_host(host);
+
+	err = mmc_sd_suspend(host);
+	if (err) {
+		pr_err("%s: error %d doing aggessive suspend\n",
+			mmc_hostname(host), err);
+		goto out;
+	}
+	mmc_power_off(host);
+
+out:
+	mmc_release_host(host);
+	return err;
+}
+
+/*
+ * Callback for runtime_resume.
+ */
+static int mmc_sd_runtime_resume(struct mmc_host *host)
+{
+	int err;
+
+	if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
+		return 0;
+
+	mmc_claim_host(host);
+
+	mmc_power_up(host);
+	err = mmc_sd_resume(host);
+	if (err)
+		pr_err("%s: error %d doing aggessive resume\n",
+			mmc_hostname(host), err);
+
+	mmc_release_host(host);
+	return 0;
+}
+
 static int mmc_sd_power_restore(struct mmc_host *host)
 {
 	int ret;
@@ -1114,15 +1170,19 @@ static const struct mmc_bus_ops mmc_sd_o
 	.resume = NULL,
 	.power_restore = mmc_sd_power_restore,
 	.alive = mmc_sd_alive,
+	.shutdown = mmc_sd_suspend,
 };
 
 static const struct mmc_bus_ops mmc_sd_ops_unsafe = {
 	.remove = mmc_sd_remove,
 	.detect = mmc_sd_detect,
+	.runtime_suspend = mmc_sd_runtime_suspend,
+	.runtime_resume = mmc_sd_runtime_resume,
 	.suspend = mmc_sd_suspend,
 	.resume = mmc_sd_resume,
 	.power_restore = mmc_sd_power_restore,
 	.alive = mmc_sd_alive,
+	.shutdown = mmc_sd_suspend,
 };
 
 static void mmc_sd_attach_bus_ops(struct mmc_host *host)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/sdio_bus.c linux-libre-3.11-rc7-gnu/drivers/mmc/core/sdio_bus.c
--- linux-libre-3.10-gnu/drivers/mmc/core/sdio_bus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/sdio_bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -211,7 +211,7 @@ static const struct dev_pm_ops sdio_bus_
 	SET_RUNTIME_PM_OPS(
 		pm_generic_runtime_suspend,
 		pm_generic_runtime_resume,
-		pm_generic_runtime_idle
+		NULL
 	)
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/core/sdio.c linux-libre-3.11-rc7-gnu/drivers/mmc/core/sdio.c
--- linux-libre-3.10-gnu/drivers/mmc/core/sdio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/core/sdio.c	2013-08-25 20:43:22.000000000 -0400
@@ -563,10 +563,18 @@ static int mmc_sdio_init_uhs_card(struct
 	if (err)
 		goto out;
 
-	/* Initialize and start re-tuning timer */
-	if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
+	/*
+	 * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and
+	 * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
+	 */
+	if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning &&
+			((card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50) ||
+			 (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104))) {
+		mmc_host_clk_hold(card->host);
 		err = card->host->ops->execute_tuning(card->host,
 						      MMC_SEND_TUNING_BLOCK);
+		mmc_host_clk_release(card->host);
+	}
 
 out:
 
@@ -902,11 +910,11 @@ out:
 }
 
 /*
- * SDIO suspend.  We need to suspend all functions separately.
+ * SDIO pre_suspend.  We need to suspend all functions separately.
  * Therefore all registered functions must have drivers with suspend
  * and resume methods.  Failing that we simply remove the whole card.
  */
-static int mmc_sdio_suspend(struct mmc_host *host)
+static int mmc_sdio_pre_suspend(struct mmc_host *host)
 {
 	int i, err = 0;
 
@@ -917,8 +925,26 @@ static int mmc_sdio_suspend(struct mmc_h
 			if (!pmops || !pmops->suspend || !pmops->resume) {
 				/* force removal of entire card in that case */
 				err = -ENOSYS;
-			} else
-				err = pmops->suspend(&func->dev);
+				break;
+			}
+		}
+	}
+
+	return err;
+}
+
+/*
+ * SDIO suspend.  Suspend all functions separately.
+ */
+static int mmc_sdio_suspend(struct mmc_host *host)
+{
+	int i, err = 0;
+
+	for (i = 0; i < host->card->sdio_funcs; i++) {
+		struct sdio_func *func = host->card->sdio_func[i];
+		if (func && sdio_func_present(func) && func->dev.driver) {
+			const struct dev_pm_ops *pmops = func->dev.driver->pm;
+			err = pmops->suspend(&func->dev);
 			if (err)
 				break;
 		}
@@ -937,6 +963,9 @@ static int mmc_sdio_suspend(struct mmc_h
 		mmc_release_host(host);
 	}
 
+	if (!err && !mmc_card_keep_power(host))
+		mmc_power_off(host);
+
 	return err;
 }
 
@@ -950,6 +979,23 @@ static int mmc_sdio_resume(struct mmc_ho
 	/* Basic card reinitialization. */
 	mmc_claim_host(host);
 
+	/* Restore power if needed */
+	if (!mmc_card_keep_power(host)) {
+		mmc_power_up(host);
+		mmc_select_voltage(host, host->ocr);
+		/*
+		 * Tell runtime PM core we just powered up the card,
+		 * since it still believes the card is powered off.
+		 * Note that currently runtime PM is only enabled
+		 * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
+		 */
+		if (host->caps & MMC_CAP_POWER_OFF_CARD) {
+			pm_runtime_disable(&host->card->dev);
+			pm_runtime_set_active(&host->card->dev);
+			pm_runtime_enable(&host->card->dev);
+		}
+	}
+
 	/* No need to reinitialize powered-resumed nonremovable cards */
 	if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
 		sdio_reset(host);
@@ -987,6 +1033,7 @@ static int mmc_sdio_resume(struct mmc_ho
 		}
 	}
 
+	host->pm_flags &= ~MMC_PM_KEEP_POWER;
 	return err;
 }
 
@@ -1051,11 +1098,28 @@ out:
 	return ret;
 }
 
+static int mmc_sdio_runtime_suspend(struct mmc_host *host)
+{
+	/* No references to the card, cut the power to it. */
+	mmc_power_off(host);
+	return 0;
+}
+
+static int mmc_sdio_runtime_resume(struct mmc_host *host)
+{
+	/* Restore power and re-initialize. */
+	mmc_power_up(host);
+	return mmc_sdio_power_restore(host);
+}
+
 static const struct mmc_bus_ops mmc_sdio_ops = {
 	.remove = mmc_sdio_remove,
 	.detect = mmc_sdio_detect,
+	.pre_suspend = mmc_sdio_pre_suspend,
 	.suspend = mmc_sdio_suspend,
 	.resume = mmc_sdio_resume,
+	.runtime_suspend = mmc_sdio_runtime_suspend,
+	.runtime_resume = mmc_sdio_runtime_resume,
 	.power_restore = mmc_sdio_power_restore,
 	.alive = mmc_sdio_alive,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/android-goldfish.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/android-goldfish.c
--- linux-libre-3.10-gnu/drivers/mmc/host/android-goldfish.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/android-goldfish.c	2013-08-25 20:43:22.000000000 -0400
@@ -546,8 +546,6 @@ static int goldfish_mmc_remove(struct pl
 {
 	struct goldfish_mmc_host *host = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	BUG_ON(host == NULL);
 
 	mmc_remove_host(host->mmc);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/atmel-mci.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/atmel-mci.c
--- linux-libre-3.10-gnu/drivers/mmc/host/atmel-mci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/atmel-mci.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,8 +40,6 @@
 #include <asm/io.h>
 #include <asm/unaligned.h>
 
-#include <mach/cpu.h>
-
 #include "atmel-mci-regs.h"
 
 #define ATMCI_DATA_ERROR_FLAGS	(ATMCI_DCRCE | ATMCI_DTOE | ATMCI_OVRE | ATMCI_UNRE)
@@ -2475,8 +2473,6 @@ static int __exit atmci_remove(struct pl
 	struct atmel_mci	*host = platform_get_drvdata(pdev);
 	unsigned int		i;
 
-	platform_set_drvdata(pdev, NULL);
-
 	if (host->buffer)
 		dma_free_coherent(&pdev->dev, host->buf_size,
 		                  host->buffer, host->buf_phys_addr);
@@ -2504,7 +2500,7 @@ static int __exit atmci_remove(struct pl
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int atmci_suspend(struct device *dev)
 {
 	struct atmel_mci *host = dev_get_drvdata(dev);
@@ -2559,17 +2555,15 @@ static int atmci_resume(struct device *d
 
 	return ret;
 }
-static SIMPLE_DEV_PM_OPS(atmci_pm, atmci_suspend, atmci_resume);
-#define ATMCI_PM_OPS	(&atmci_pm)
-#else
-#define ATMCI_PM_OPS	NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(atmci_pm, atmci_suspend, atmci_resume);
+
 static struct platform_driver atmci_driver = {
 	.remove		= __exit_p(atmci_remove),
 	.driver		= {
 		.name		= "atmel_mci",
-		.pm		= ATMCI_PM_OPS,
+		.pm		= &atmci_pm,
 		.of_match_table	= of_match_ptr(atmci_dt_ids),
 	},
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/au1xmmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/au1xmmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/au1xmmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/au1xmmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -1149,7 +1149,6 @@ static int au1xmmc_remove(struct platfor
 		kfree(host->ioarea);
 
 		mmc_free_host(host->mmc);
-		platform_set_drvdata(pdev, NULL);
 	}
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/bfin_sdh.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/bfin_sdh.c
--- linux-libre-3.10-gnu/drivers/mmc/host/bfin_sdh.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/bfin_sdh.c	2013-08-25 20:43:22.000000000 -0400
@@ -621,8 +621,6 @@ static int sdh_remove(struct platform_de
 {
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	if (mmc) {
 		struct sdh_host *host = mmc_priv(mmc);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/cb710-mmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/cb710-mmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/cb710-mmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/cb710-mmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -703,7 +703,7 @@ static int cb710_mmc_init(struct platfor
 	if (!mmc)
 		return -ENOMEM;
 
-	dev_set_drvdata(&pdev->dev, mmc);
+	platform_set_drvdata(pdev, mmc);
 
 	/* harmless (maybe) magic */
 	pci_read_config_dword(chip->pdev, 0x48, &val);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/cb710-mmc.h linux-libre-3.11-rc7-gnu/drivers/mmc/host/cb710-mmc.h
--- linux-libre-3.10-gnu/drivers/mmc/host/cb710-mmc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/cb710-mmc.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,7 @@ struct cb710_mmc_reader {
 
 static inline struct mmc_host *cb710_slot_to_mmc(struct cb710_slot *slot)
 {
-	return dev_get_drvdata(&slot->pdev.dev);
+	return platform_get_drvdata(&slot->pdev);
 }
 
 static inline struct cb710_slot *cb710_mmc_to_slot(struct mmc_host *mmc)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/davinci_mmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/davinci_mmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/davinci_mmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/davinci_mmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
+#include <linux/platform_data/edma.h>
 #include <linux/platform_data/mmc-davinci.h>
 
 /*
@@ -1406,7 +1407,6 @@ static int __exit davinci_mmcsd_remove(s
 {
 	struct mmc_davinci_host *host = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	if (host) {
 		mmc_davinci_cpufreq_deregister(host);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,7 @@
 #include "dw_mmc.h"
 
 /* Common flag combinations */
-#define DW_MCI_DATA_ERROR_FLAGS	(SDMMC_INT_DTO | SDMMC_INT_DCRC | \
+#define DW_MCI_DATA_ERROR_FLAGS	(SDMMC_INT_DRTO | SDMMC_INT_DCRC | \
 				 SDMMC_INT_HTO | SDMMC_INT_SBE  | \
 				 SDMMC_INT_EBE)
 #define DW_MCI_CMD_ERROR_FLAGS	(SDMMC_INT_RTO | SDMMC_INT_RCRC | \
@@ -51,6 +51,11 @@
 #define DW_MCI_DMA_THRESHOLD	16
 
 #ifdef CONFIG_MMC_DW_IDMAC
+#define IDMAC_INT_CLR		(SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
+				 SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
+				 SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
+				 SDMMC_IDMAC_INT_TI)
+
 struct idmac_desc {
 	u32		des0;	/* Control Descriptor */
 #define IDMAC_DES0_DIC	BIT(1)
@@ -433,6 +438,7 @@ static int dw_mci_idmac_init(struct dw_m
 	mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET);
 
 	/* Mask out interrupts - get Tx & Rx complete only */
+	mci_writel(host, IDSTS, IDMAC_INT_CLR);
 	mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI |
 		   SDMMC_IDMAC_INT_TI);
 
@@ -1087,7 +1093,7 @@ static void dw_mci_tasklet_func(unsigned
 			status = host->data_status;
 
 			if (status & DW_MCI_DATA_ERROR_FLAGS) {
-				if (status & SDMMC_INT_DTO) {
+				if (status & SDMMC_INT_DRTO) {
 					data->error = -ETIMEDOUT;
 				} else if (status & SDMMC_INT_DCRC) {
 					data->error = -EILSEQ;
@@ -1985,19 +1991,6 @@ static int dw_mci_init_slot(struct dw_mc
 #endif /* CONFIG_MMC_DW_IDMAC */
 	}
 
-	host->vmmc = devm_regulator_get(mmc_dev(mmc), "vmmc");
-	if (IS_ERR(host->vmmc)) {
-		pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
-		host->vmmc = NULL;
-	} else {
-		ret = regulator_enable(host->vmmc);
-		if (ret) {
-			dev_err(host->dev,
-				"failed to enable regulator: %d\n", ret);
-			goto err_setup_bus;
-		}
-	}
-
 	if (dw_mci_get_cd(mmc))
 		set_bit(DW_MMC_CARD_PRESENT, &slot->flags);
 	else
@@ -2124,6 +2117,7 @@ static struct dw_mci_board *dw_mci_parse
 	struct device_node *np = dev->of_node;
 	const struct dw_mci_drv_data *drv_data = host->drv_data;
 	int idx, ret;
+	u32 clock_frequency;
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
@@ -2150,6 +2144,9 @@ static struct dw_mci_board *dw_mci_parse
 
 	of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms);
 
+	if (!of_property_read_u32(np, "clock-frequency", &clock_frequency))
+		pdata->bus_hz = clock_frequency;
+
 	if (drv_data && drv_data->parse_dt) {
 		ret = drv_data->parse_dt(host);
 		if (ret)
@@ -2207,18 +2204,23 @@ int dw_mci_probe(struct dw_mci *host)
 	host->ciu_clk = devm_clk_get(host->dev, "ciu");
 	if (IS_ERR(host->ciu_clk)) {
 		dev_dbg(host->dev, "ciu clock not available\n");
+		host->bus_hz = host->pdata->bus_hz;
 	} else {
 		ret = clk_prepare_enable(host->ciu_clk);
 		if (ret) {
 			dev_err(host->dev, "failed to enable ciu clock\n");
 			goto err_clk_biu;
 		}
-	}
 
-	if (IS_ERR(host->ciu_clk))
-		host->bus_hz = host->pdata->bus_hz;
-	else
+		if (host->pdata->bus_hz) {
+			ret = clk_set_rate(host->ciu_clk, host->pdata->bus_hz);
+			if (ret)
+				dev_warn(host->dev,
+					 "Unable to set bus rate to %ul\n",
+					 host->pdata->bus_hz);
+		}
 		host->bus_hz = clk_get_rate(host->ciu_clk);
+	}
 
 	if (drv_data && drv_data->setup_clock) {
 		ret = drv_data->setup_clock(host);
@@ -2229,11 +2231,29 @@ int dw_mci_probe(struct dw_mci *host)
 		}
 	}
 
+	host->vmmc = devm_regulator_get(host->dev, "vmmc");
+	if (IS_ERR(host->vmmc)) {
+		ret = PTR_ERR(host->vmmc);
+		if (ret == -EPROBE_DEFER)
+			goto err_clk_ciu;
+
+		dev_info(host->dev, "no vmmc regulator found: %d\n", ret);
+		host->vmmc = NULL;
+	} else {
+		ret = regulator_enable(host->vmmc);
+		if (ret) {
+			if (ret != -EPROBE_DEFER)
+				dev_err(host->dev,
+					"regulator_enable fail: %d\n", ret);
+			goto err_clk_ciu;
+		}
+	}
+
 	if (!host->bus_hz) {
 		dev_err(host->dev,
 			"Platform data must supply bus speed\n");
 		ret = -ENODEV;
-		goto err_clk_ciu;
+		goto err_regulator;
 	}
 
 	host->quirks = host->pdata->quirks;
@@ -2321,8 +2341,10 @@ int dw_mci_probe(struct dw_mci *host)
 	tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host);
 	host->card_workqueue = alloc_workqueue("dw-mci-card",
 			WQ_MEM_RECLAIM | WQ_NON_REENTRANT, 1);
-	if (!host->card_workqueue)
+	if (!host->card_workqueue) {
+		ret = -ENOMEM;
 		goto err_dmaunmap;
+	}
 	INIT_WORK(&host->card_work, dw_mci_work_routine_card);
 	ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt,
 			       host->irq_flags, "dw-mci", host);
@@ -2378,6 +2400,7 @@ err_dmaunmap:
 	if (host->use_dma && host->dma_ops->exit)
 		host->dma_ops->exit(host);
 
+err_regulator:
 	if (host->vmmc)
 		regulator_disable(host->vmmc);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc-exynos.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc-exynos.c
--- linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc-exynos.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc-exynos.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,8 +31,6 @@
 					SDMMC_CLKSEL_CCLK_DRIVE(y) |	\
 					SDMMC_CLKSEL_CCLK_DIVIDER(z))
 
-#define SDMMC_CMD_USE_HOLD_REG		BIT(29)
-
 #define EXYNOS4210_FIXED_CIU_CLK_DIV	2
 #define EXYNOS4412_FIXED_CIU_CLK_DIV	4
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc.h linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc.h
--- linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc.h	2013-08-25 20:43:22.000000000 -0400
@@ -98,7 +98,7 @@
 #define SDMMC_INT_HLE			BIT(12)
 #define SDMMC_INT_FRUN			BIT(11)
 #define SDMMC_INT_HTO			BIT(10)
-#define SDMMC_INT_DTO			BIT(9)
+#define SDMMC_INT_DRTO			BIT(9)
 #define SDMMC_INT_RTO			BIT(8)
 #define SDMMC_INT_DCRC			BIT(7)
 #define SDMMC_INT_RCRC			BIT(6)
@@ -111,6 +111,7 @@
 #define SDMMC_INT_ERROR			0xbfc2
 /* Command register defines */
 #define SDMMC_CMD_START			BIT(31)
+#define SDMMC_CMD_USE_HOLD_REG	BIT(29)
 #define SDMMC_CMD_CCS_EXP		BIT(23)
 #define SDMMC_CMD_CEATA_RD		BIT(22)
 #define SDMMC_CMD_UPD_CLK		BIT(21)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc-pci.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc-pci.c
--- linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc-pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc-pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,7 +21,6 @@
 #include "dw_mmc.h"
 
 #define PCI_BAR_NO 2
-#define COMPLETE_BAR 0
 #define SYNOPSYS_DW_MCI_VENDOR_ID 0x700
 #define SYNOPSYS_DW_MCI_DEVICE_ID 0x1107
 /* Defining the Capabilities */
@@ -38,51 +37,37 @@ static struct dw_mci_board pci_board_dat
 };
 
 static int dw_mci_pci_probe(struct pci_dev *pdev,
-				  const struct pci_device_id *entries)
+			    const struct pci_device_id *entries)
 {
 	struct dw_mci *host;
 	int ret;
 
-	ret = pci_enable_device(pdev);
+	ret = pcim_enable_device(pdev);
 	if (ret)
 		return ret;
-	if (pci_request_regions(pdev, "dw_mmc_pci")) {
-		ret = -ENODEV;
-		goto err_disable_dev;
-	}
 
-	host = kzalloc(sizeof(struct dw_mci), GFP_KERNEL);
-	if (!host) {
-		ret = -ENOMEM;
-		goto err_release;
-	}
+	host = devm_kzalloc(&pdev->dev, sizeof(struct dw_mci), GFP_KERNEL);
+	if (!host)
+		return -ENOMEM;
 
 	host->irq = pdev->irq;
 	host->irq_flags = IRQF_SHARED;
 	host->dev = &pdev->dev;
 	host->pdata = &pci_board_data;
 
-	host->regs = pci_iomap(pdev, PCI_BAR_NO, COMPLETE_BAR);
-	if (!host->regs) {
-		ret = -EIO;
-		goto err_unmap;
-	}
+	ret = pcim_iomap_regions(pdev, 1 << PCI_BAR_NO, pci_name(pdev));
+	if (ret)
+		return ret;
+
+	host->regs = pcim_iomap_table(pdev)[0];
 
-	pci_set_drvdata(pdev, host);
 	ret = dw_mci_probe(host);
 	if (ret)
-		goto err_probe_failed;
-	return ret;
+		return ret;
 
-err_probe_failed:
-	pci_iounmap(pdev, host->regs);
-err_unmap:
-	kfree(host);
-err_release:
-	pci_release_regions(pdev);
-err_disable_dev:
-	pci_disable_device(pdev);
-	return ret;
+	pci_set_drvdata(pdev, host);
+
+	return 0;
 }
 
 static void dw_mci_pci_remove(struct pci_dev *pdev)
@@ -90,32 +75,23 @@ static void dw_mci_pci_remove(struct pci
 	struct dw_mci *host = pci_get_drvdata(pdev);
 
 	dw_mci_remove(host);
-	pci_set_drvdata(pdev, NULL);
-	pci_release_regions(pdev);
-	pci_iounmap(pdev, host->regs);
-	kfree(host);
-	pci_disable_device(pdev);
 }
 
 #ifdef CONFIG_PM_SLEEP
 static int dw_mci_pci_suspend(struct device *dev)
 {
-	int ret;
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct dw_mci *host = pci_get_drvdata(pdev);
 
-	ret = dw_mci_suspend(host);
-	return ret;
+	return dw_mci_suspend(host);
 }
 
 static int dw_mci_pci_resume(struct device *dev)
 {
-	int ret;
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct dw_mci *host = pci_get_drvdata(pdev);
 
-	ret = dw_mci_resume(host);
-	return ret;
+	return dw_mci_resume(host);
 }
 #else
 #define dw_mci_pci_suspend	NULL
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc-pltfm.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc-pltfm.c
--- linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc-pltfm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc-pltfm.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,8 +24,17 @@
 
 #include "dw_mmc.h"
 
+static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr)
+{
+	*cmdr |= SDMMC_CMD_USE_HOLD_REG;
+}
+
+static const struct dw_mci_drv_data rockchip_drv_data = {
+	.prepare_command	= dw_mci_rockchip_prepare_command,
+};
+
 int dw_mci_pltfm_register(struct platform_device *pdev,
-				const struct dw_mci_drv_data *drv_data)
+			  const struct dw_mci_drv_data *drv_data)
 {
 	struct dw_mci *host;
 	struct resource	*regs;
@@ -35,10 +44,6 @@ int dw_mci_pltfm_register(struct platfor
 	if (!host)
 		return -ENOMEM;
 
-	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!regs)
-		return -ENXIO;
-
 	host->irq = platform_get_irq(pdev, 0);
 	if (host->irq < 0)
 		return host->irq;
@@ -47,6 +52,8 @@ int dw_mci_pltfm_register(struct platfor
 	host->dev = &pdev->dev;
 	host->irq_flags = 0;
 	host->pdata = pdev->dev.platform_data;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	host->regs = devm_ioremap_resource(&pdev->dev, regs);
 	if (IS_ERR(host->regs))
 		return PTR_ERR(host->regs);
@@ -58,52 +65,26 @@ int dw_mci_pltfm_register(struct platfor
 	}
 
 	platform_set_drvdata(pdev, host);
-	ret = dw_mci_probe(host);
-	return ret;
+	return dw_mci_probe(host);
 }
 EXPORT_SYMBOL_GPL(dw_mci_pltfm_register);
 
-static int dw_mci_pltfm_probe(struct platform_device *pdev)
-{
-	return dw_mci_pltfm_register(pdev, NULL);
-}
-
-static int dw_mci_pltfm_remove(struct platform_device *pdev)
-{
-	struct dw_mci *host = platform_get_drvdata(pdev);
-
-	platform_set_drvdata(pdev, NULL);
-	dw_mci_remove(host);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(dw_mci_pltfm_remove);
-
 #ifdef CONFIG_PM_SLEEP
 /*
  * TODO: we should probably disable the clock to the card in the suspend path.
  */
 static int dw_mci_pltfm_suspend(struct device *dev)
 {
-	int ret;
 	struct dw_mci *host = dev_get_drvdata(dev);
 
-	ret = dw_mci_suspend(host);
-	if (ret)
-		return ret;
-
-	return 0;
+	return dw_mci_suspend(host);
 }
 
 static int dw_mci_pltfm_resume(struct device *dev)
 {
-	int ret;
 	struct dw_mci *host = dev_get_drvdata(dev);
 
-	ret = dw_mci_resume(host);
-	if (ret)
-		return ret;
-
-	return 0;
+	return dw_mci_resume(host);
 }
 #else
 #define dw_mci_pltfm_suspend	NULL
@@ -115,10 +96,34 @@ EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
 
 static const struct of_device_id dw_mci_pltfm_match[] = {
 	{ .compatible = "snps,dw-mshc", },
+	{ .compatible = "rockchip,rk2928-dw-mshc",
+		.data = &rockchip_drv_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
 
+static int dw_mci_pltfm_probe(struct platform_device *pdev)
+{
+	const struct dw_mci_drv_data *drv_data = NULL;
+	const struct of_device_id *match;
+
+	if (pdev->dev.of_node) {
+		match = of_match_node(dw_mci_pltfm_match, pdev->dev.of_node);
+		drv_data = match->data;
+	}
+
+	return dw_mci_pltfm_register(pdev, drv_data);
+}
+
+int dw_mci_pltfm_remove(struct platform_device *pdev)
+{
+	struct dw_mci *host = platform_get_drvdata(pdev);
+
+	dw_mci_remove(host);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_remove);
+
 static struct platform_driver dw_mci_pltfm_driver = {
 	.probe		= dw_mci_pltfm_probe,
 	.remove		= dw_mci_pltfm_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc-socfpga.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc-socfpga.c
--- linux-libre-3.10-gnu/drivers/mmc/host/dw_mmc-socfpga.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/dw_mmc-socfpga.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,140 @@
+/*
+ * Altera SoCFPGA Specific Extensions for Synopsys DW Multimedia Card Interface
+ * driver
+ *
+ *  Copyright (C) 2012, Samsung Electronics Co., Ltd.
+ *  Copyright (C) 2013 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Taken from dw_mmc-exynos.c
+ */
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "dw_mmc.h"
+#include "dw_mmc-pltfm.h"
+
+#define SYSMGR_SDMMCGRP_CTRL_OFFSET		0x108
+#define DRV_CLK_PHASE_SHIFT_SEL_MASK	0x7
+#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel)          \
+	((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
+
+/* SOCFPGA implementation specific driver private data */
+struct dw_mci_socfpga_priv_data {
+	u8	ciu_div; /* card interface unit divisor */
+	u32	hs_timing; /* bitmask for CIU clock phase shift */
+	struct regmap   *sysreg; /* regmap for system manager register */
+};
+
+static int dw_mci_socfpga_priv_init(struct dw_mci *host)
+{
+	struct dw_mci_socfpga_priv_data *priv;
+
+	priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(host->dev, "mem alloc failed for private data\n");
+		return -ENOMEM;
+	}
+
+	priv->sysreg = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
+	if (IS_ERR(priv->sysreg)) {
+		dev_err(host->dev, "regmap for altr,sys-mgr lookup failed.\n");
+		return PTR_ERR(priv->sysreg);
+	}
+	host->priv = priv;
+
+	return 0;
+}
+
+static int dw_mci_socfpga_setup_clock(struct dw_mci *host)
+{
+	struct dw_mci_socfpga_priv_data *priv = host->priv;
+
+	clk_disable_unprepare(host->ciu_clk);
+	regmap_write(priv->sysreg, SYSMGR_SDMMCGRP_CTRL_OFFSET,
+		priv->hs_timing);
+	clk_prepare_enable(host->ciu_clk);
+
+	host->bus_hz /= (priv->ciu_div + 1);
+	return 0;
+}
+
+static void dw_mci_socfpga_prepare_command(struct dw_mci *host, u32 *cmdr)
+{
+	struct dw_mci_socfpga_priv_data *priv = host->priv;
+
+	if (priv->hs_timing & DRV_CLK_PHASE_SHIFT_SEL_MASK)
+		*cmdr |= SDMMC_CMD_USE_HOLD_REG;
+}
+
+static int dw_mci_socfpga_parse_dt(struct dw_mci *host)
+{
+	struct dw_mci_socfpga_priv_data *priv = host->priv;
+	struct device_node *np = host->dev->of_node;
+	u32 timing[2];
+	u32 div = 0;
+	int ret;
+
+	ret = of_property_read_u32(np, "altr,dw-mshc-ciu-div", &div);
+	if (ret)
+		dev_info(host->dev, "No dw-mshc-ciu-div specified, assuming 1");
+	priv->ciu_div = div;
+
+	ret = of_property_read_u32_array(np,
+			"altr,dw-mshc-sdr-timing", timing, 2);
+	if (ret)
+		return ret;
+
+	priv->hs_timing = SYSMGR_SDMMC_CTRL_SET(timing[0], timing[1]);
+	return 0;
+}
+
+static const struct dw_mci_drv_data socfpga_drv_data = {
+	.init			= dw_mci_socfpga_priv_init,
+	.setup_clock		= dw_mci_socfpga_setup_clock,
+	.prepare_command	= dw_mci_socfpga_prepare_command,
+	.parse_dt		= dw_mci_socfpga_parse_dt,
+};
+
+static const struct of_device_id dw_mci_socfpga_match[] = {
+	{ .compatible = "altr,socfpga-dw-mshc",
+			.data = &socfpga_drv_data, },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_socfpga_match);
+
+int dw_mci_socfpga_probe(struct platform_device *pdev)
+{
+	const struct dw_mci_drv_data *drv_data;
+	const struct of_device_id *match;
+
+	match = of_match_node(dw_mci_socfpga_match, pdev->dev.of_node);
+	drv_data = match->data;
+	return dw_mci_pltfm_register(pdev, drv_data);
+}
+
+static struct platform_driver dw_mci_socfpga_pltfm_driver = {
+	.probe		= dw_mci_socfpga_probe,
+	.remove		= __exit_p(dw_mci_pltfm_remove),
+	.driver		= {
+		.name		= "dwmmc_socfpga",
+		.of_match_table	= of_match_ptr(dw_mci_socfpga_match),
+		.pm		= &dw_mci_pltfm_pmops,
+	},
+};
+
+module_platform_driver(dw_mci_socfpga_pltfm_driver);
+
+MODULE_DESCRIPTION("Altera SOCFPGA Specific DW-MSHC Driver Extension");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:dwmmc-socfpga");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/jz4740_mmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/jz4740_mmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/jz4740_mmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/jz4740_mmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@
  */
 
 #include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/irq.h>
@@ -120,7 +121,6 @@ struct jz4740_mmc_host {
 	int irq;
 	int card_detect_irq;
 
-	struct resource *mem;
 	void __iomem *base;
 	struct mmc_request *req;
 	struct mmc_command *cmd;
@@ -231,6 +231,14 @@ static void jz4740_mmc_transfer_check_st
 			host->req->cmd->error = -EIO;
 			data->error = -EIO;
 		}
+	} else if (status & JZ_MMC_STATUS_READ_ERROR_MASK) {
+		if (status & (JZ_MMC_STATUS_TIMEOUT_READ)) {
+			host->req->cmd->error = -ETIMEDOUT;
+			data->error = -ETIMEDOUT;
+		} else {
+			host->req->cmd->error = -EIO;
+			data->error = -EIO;
+		}
 	}
 }
 
@@ -560,11 +568,6 @@ static irqreturn_t jz_mmc_irq(int irq, v
 					if (cmd->data)
 							cmd->data->error = -EIO;
 					cmd->error = -EIO;
-			} else if (status & (JZ_MMC_STATUS_CRC_READ_ERROR |
-					JZ_MMC_STATUS_CRC_WRITE_ERROR)) {
-					if (cmd->data)
-							cmd->data->error = -EIO;
-					cmd->error = -EIO;
 			}
 
 			jz4740_mmc_set_irq_enabled(host, irq_reg, false);
@@ -626,7 +629,7 @@ static void jz4740_mmc_set_ios(struct mm
 			gpio_set_value(host->pdata->gpio_power,
 					!host->pdata->power_active_low);
 		host->cmdat |= JZ_MMC_CMDAT_INIT;
-		clk_enable(host->clk);
+		clk_prepare_enable(host->clk);
 		break;
 	case MMC_POWER_ON:
 		break;
@@ -634,7 +637,7 @@ static void jz4740_mmc_set_ios(struct mm
 		if (gpio_is_valid(host->pdata->gpio_power))
 			gpio_set_value(host->pdata->gpio_power,
 					host->pdata->power_active_low);
-		clk_disable(host->clk);
+		clk_disable_unprepare(host->clk);
 		break;
 	}
 
@@ -650,35 +653,6 @@ static void jz4740_mmc_set_ios(struct mm
 	}
 }
 
-static int jz4740_mmc_get_ro(struct mmc_host *mmc)
-{
-	struct jz4740_mmc_host *host = mmc_priv(mmc);
-	if (!gpio_is_valid(host->pdata->gpio_read_only))
-		return -ENOSYS;
-
-	return gpio_get_value(host->pdata->gpio_read_only) ^
-		host->pdata->read_only_active_low;
-}
-
-static int jz4740_mmc_get_cd(struct mmc_host *mmc)
-{
-	struct jz4740_mmc_host *host = mmc_priv(mmc);
-	if (!gpio_is_valid(host->pdata->gpio_card_detect))
-		return -ENOSYS;
-
-	return gpio_get_value(host->pdata->gpio_card_detect) ^
-			host->pdata->card_detect_active_low;
-}
-
-static irqreturn_t jz4740_mmc_card_detect_irq(int irq, void *devid)
-{
-	struct jz4740_mmc_host *host = devid;
-
-	mmc_detect_change(host->mmc, HZ / 2);
-
-	return IRQ_HANDLED;
-}
-
 static void jz4740_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
 	struct jz4740_mmc_host *host = mmc_priv(mmc);
@@ -688,8 +662,8 @@ static void jz4740_mmc_enable_sdio_irq(s
 static const struct mmc_host_ops jz4740_mmc_ops = {
 	.request	= jz4740_mmc_request,
 	.set_ios	= jz4740_mmc_set_ios,
-	.get_ro		= jz4740_mmc_get_ro,
-	.get_cd		= jz4740_mmc_get_cd,
+	.get_ro		= mmc_gpio_get_ro,
+	.get_cd		= mmc_gpio_get_cd,
 	.enable_sdio_irq = jz4740_mmc_enable_sdio_irq,
 };
 
@@ -724,58 +698,34 @@ static int jz4740_mmc_request_gpio(struc
 	return 0;
 }
 
-static int jz4740_mmc_request_gpios(struct platform_device *pdev)
+static int jz4740_mmc_request_gpios(struct mmc_host *mmc,
+	struct platform_device *pdev)
 {
-	int ret;
 	struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
+	int ret = 0;
 
 	if (!pdata)
 		return 0;
 
-	ret = jz4740_mmc_request_gpio(&pdev->dev, pdata->gpio_card_detect,
-			"MMC detect change", false, 0);
-	if (ret)
-		goto err;
-
-	ret = jz4740_mmc_request_gpio(&pdev->dev, pdata->gpio_read_only,
-			"MMC read only", false, 0);
-	if (ret)
-		goto err_free_gpio_card_detect;
-
-	ret = jz4740_mmc_request_gpio(&pdev->dev, pdata->gpio_power,
-			"MMC read only", true, pdata->power_active_low);
-	if (ret)
-		goto err_free_gpio_read_only;
-
-	return 0;
-
-err_free_gpio_read_only:
-	if (gpio_is_valid(pdata->gpio_read_only))
-		gpio_free(pdata->gpio_read_only);
-err_free_gpio_card_detect:
-	if (gpio_is_valid(pdata->gpio_card_detect))
-		gpio_free(pdata->gpio_card_detect);
-err:
-	return ret;
-}
-
-static int jz4740_mmc_request_cd_irq(struct platform_device *pdev,
-	struct jz4740_mmc_host *host)
-{
-	struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data;
+	if (!pdata->card_detect_active_low)
+		mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+	if (!pdata->read_only_active_low)
+		mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
 
-	if (!gpio_is_valid(pdata->gpio_card_detect))
-		return 0;
+	if (gpio_is_valid(pdata->gpio_card_detect)) {
+		ret = mmc_gpio_request_cd(mmc, pdata->gpio_card_detect);
+		if (ret)
+			return ret;
+	}
 
-	host->card_detect_irq = gpio_to_irq(pdata->gpio_card_detect);
-	if (host->card_detect_irq < 0) {
-		dev_warn(&pdev->dev, "Failed to get card detect irq\n");
-		return 0;
+	if (gpio_is_valid(pdata->gpio_read_only)) {
+		ret = mmc_gpio_request_ro(mmc, pdata->gpio_read_only);
+		if (ret)
+			return ret;
 	}
 
-	return request_irq(host->card_detect_irq, jz4740_mmc_card_detect_irq,
-			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-			"MMC card detect", host);
+	return jz4740_mmc_request_gpio(&pdev->dev, pdata->gpio_power,
+			"MMC read only", true, pdata->power_active_low);
 }
 
 static void jz4740_mmc_free_gpios(struct platform_device *pdev)
@@ -787,10 +737,6 @@ static void jz4740_mmc_free_gpios(struct
 
 	if (gpio_is_valid(pdata->gpio_power))
 		gpio_free(pdata->gpio_power);
-	if (gpio_is_valid(pdata->gpio_read_only))
-		gpio_free(pdata->gpio_read_only);
-	if (gpio_is_valid(pdata->gpio_card_detect))
-		gpio_free(pdata->gpio_card_detect);
 }
 
 static inline size_t jz4740_mmc_num_pins(struct jz4740_mmc_host *host)
@@ -808,6 +754,7 @@ static int jz4740_mmc_probe(struct platf
 	struct mmc_host *mmc;
 	struct jz4740_mmc_host *host;
 	struct jz4740_mmc_platform_data *pdata;
+	struct resource *res;
 
 	pdata = pdev->dev.platform_data;
 
@@ -827,42 +774,28 @@ static int jz4740_mmc_probe(struct platf
 		goto err_free_host;
 	}
 
-	host->clk = clk_get(&pdev->dev, "mmc");
+	host->clk = devm_clk_get(&pdev->dev, "mmc");
 	if (IS_ERR(host->clk)) {
 		ret = PTR_ERR(host->clk);
 		dev_err(&pdev->dev, "Failed to get mmc clock\n");
 		goto err_free_host;
 	}
 
-	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!host->mem) {
-		ret = -ENOENT;
-		dev_err(&pdev->dev, "Failed to get base platform memory\n");
-		goto err_clk_put;
-	}
-
-	host->mem = request_mem_region(host->mem->start,
-					resource_size(host->mem), pdev->name);
-	if (!host->mem) {
-		ret = -EBUSY;
-		dev_err(&pdev->dev, "Failed to request base memory region\n");
-		goto err_clk_put;
-	}
-
-	host->base = ioremap_nocache(host->mem->start, resource_size(host->mem));
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	host->base = devm_ioremap_resource(&pdev->dev, res);
 	if (!host->base) {
 		ret = -EBUSY;
 		dev_err(&pdev->dev, "Failed to ioremap base memory\n");
-		goto err_release_mem_region;
+		goto err_free_host;
 	}
 
 	ret = jz_gpio_bulk_request(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to request mmc pins: %d\n", ret);
-		goto err_iounmap;
+		goto err_free_host;
 	}
 
-	ret = jz4740_mmc_request_gpios(pdev);
+	ret = jz4740_mmc_request_gpios(mmc, pdev);
 	if (ret)
 		goto err_gpio_bulk_free;
 
@@ -885,17 +818,11 @@ static int jz4740_mmc_probe(struct platf
 	spin_lock_init(&host->lock);
 	host->irq_mask = 0xffff;
 
-	ret = jz4740_mmc_request_cd_irq(pdev, host);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to request card detect irq\n");
-		goto err_free_gpios;
-	}
-
 	ret = request_threaded_irq(host->irq, jz_mmc_irq, jz_mmc_irq_worker, 0,
 			dev_name(&pdev->dev), host);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
-		goto err_free_card_detect_irq;
+		goto err_free_gpios;
 	}
 
 	jz4740_mmc_reset(host);
@@ -918,21 +845,11 @@ static int jz4740_mmc_probe(struct platf
 
 err_free_irq:
 	free_irq(host->irq, host);
-err_free_card_detect_irq:
-	if (host->card_detect_irq >= 0)
-		free_irq(host->card_detect_irq, host);
 err_free_gpios:
 	jz4740_mmc_free_gpios(pdev);
 err_gpio_bulk_free:
 	jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
-err_iounmap:
-	iounmap(host->base);
-err_release_mem_region:
-	release_mem_region(host->mem->start, resource_size(host->mem));
-err_clk_put:
-	clk_put(host->clk);
 err_free_host:
-	platform_set_drvdata(pdev, NULL);
 	mmc_free_host(mmc);
 
 	return ret;
@@ -949,24 +866,16 @@ static int jz4740_mmc_remove(struct plat
 	mmc_remove_host(host->mmc);
 
 	free_irq(host->irq, host);
-	if (host->card_detect_irq >= 0)
-		free_irq(host->card_detect_irq, host);
 
 	jz4740_mmc_free_gpios(pdev);
 	jz_gpio_bulk_free(jz4740_mmc_pins, jz4740_mmc_num_pins(host));
 
-	iounmap(host->base);
-	release_mem_region(host->mem->start, resource_size(host->mem));
-
-	clk_put(host->clk);
-
-	platform_set_drvdata(pdev, NULL);
 	mmc_free_host(host->mmc);
 
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 
 static int jz4740_mmc_suspend(struct device *dev)
 {
@@ -990,13 +899,8 @@ static int jz4740_mmc_resume(struct devi
 	return 0;
 }
 
-const struct dev_pm_ops jz4740_mmc_pm_ops = {
-	.suspend	= jz4740_mmc_suspend,
-	.resume		= jz4740_mmc_resume,
-	.poweroff	= jz4740_mmc_suspend,
-	.restore	= jz4740_mmc_resume,
-};
-
+static SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend,
+	jz4740_mmc_resume);
 #define JZ4740_MMC_PM_OPS (&jz4740_mmc_pm_ops)
 #else
 #define JZ4740_MMC_PM_OPS NULL
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/Kconfig linux-libre-3.11-rc7-gnu/drivers/mmc/host/Kconfig
--- linux-libre-3.10-gnu/drivers/mmc/host/Kconfig	2013-07-01 10:42:17.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/Kconfig	2013-08-31 18:02:04.000000000 -0400
@@ -249,6 +249,17 @@ config MMC_SDHCI_S3C_DMA
 
 	  YMMV.
 
+config MMC_SDHCI_BCM_KONA
+	tristate "SDHCI support on Broadcom KONA platform"
+	depends on ARCH_BCM
+	select MMC_SDHCI_PLTFM
+	help
+	  This selects the Broadcom Kona Secure Digital Host Controller
+	  Interface(SDHCI) support.
+	  This is used in Broadcom mobile SoCs.
+
+	  If you have a controller with this interface, say Y or M here.
+
 config MMC_SDHCI_BCM2835
 	tristate "SDHCI platform support for the BCM2835 SD/MMC Controller"
 	depends on ARCH_BCM2835
@@ -556,6 +567,14 @@ config MMC_DW_EXYNOS
 	  Synopsys DesignWare Memory Card Interface driver. Select this option
 	  for platforms based on Exynos4 and Exynos5 SoC's.
 
+config MMC_DW_SOCFPGA
+	tristate "SOCFPGA specific extensions for Synopsys DW Memory Card Interface"
+	depends on MMC_DW
+	select MMC_DW_PLTFM
+	help
+	  This selects support for Altera SoCFPGA specific extensions to the
+	  Synopsys DesignWare Memory Card Interface driver.
+
 config MMC_DW_PCI
 	tristate "Synopsys Designware MCI support on PCI bus"
 	depends on MMC_DW && PCI
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/Makefile linux-libre-3.11-rc7-gnu/drivers/mmc/host/Makefile
--- linux-libre-3.10-gnu/drivers/mmc/host/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -42,6 +42,7 @@ obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
 obj-$(CONFIG_MMC_DW)		+= dw_mmc.o
 obj-$(CONFIG_MMC_DW_PLTFM)	+= dw_mmc-pltfm.o
 obj-$(CONFIG_MMC_DW_EXYNOS)	+= dw_mmc-exynos.o
+obj-$(CONFIG_MMC_DW_SOCFPGA)	+= dw_mmc-socfpga.o
 obj-$(CONFIG_MMC_DW_PCI)	+= dw_mmc-pci.o
 obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
 obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
@@ -60,6 +61,7 @@ obj-$(CONFIG_MMC_SDHCI_DOVE)		+= sdhci-d
 obj-$(CONFIG_MMC_SDHCI_TEGRA)		+= sdhci-tegra.o
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
+obj-$(CONFIG_MMC_SDHCI_BCM_KONA)	+= sdhci-bcm-kona.o
 obj-$(CONFIG_MMC_SDHCI_BCM2835)		+= sdhci-bcm2835.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/mmci.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/mmci.c
--- linux-libre-3.10-gnu/drivers/mmc/host/mmci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/mmci.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,6 +61,7 @@ static unsigned int fmax = 515633;
  * @pwrreg_powerup: power up value for MMCIPOWER register
  * @signal_direction: input/out direction of bus signals can be indicated
  * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
+ * @busy_detect: true if busy detection on dat0 is supported
  */
 struct variant_data {
 	unsigned int		clkreg;
@@ -74,6 +75,7 @@ struct variant_data {
 	u32			pwrreg_powerup;
 	bool			signal_direction;
 	bool			pwrreg_clkgate;
+	bool			busy_detect;
 };
 
 static struct variant_data variant_arm = {
@@ -132,6 +134,7 @@ static struct variant_data variant_ux500
 	.pwrreg_powerup		= MCI_PWR_ON,
 	.signal_direction	= true,
 	.pwrreg_clkgate		= true,
+	.busy_detect		= true,
 };
 
 static struct variant_data variant_ux500v2 = {
@@ -146,8 +149,28 @@ static struct variant_data variant_ux500
 	.pwrreg_powerup		= MCI_PWR_ON,
 	.signal_direction	= true,
 	.pwrreg_clkgate		= true,
+	.busy_detect		= true,
 };
 
+static int mmci_card_busy(struct mmc_host *mmc)
+{
+	struct mmci_host *host = mmc_priv(mmc);
+	unsigned long flags;
+	int busy = 0;
+
+	pm_runtime_get_sync(mmc_dev(mmc));
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (readl(host->base + MMCISTATUS) & MCI_ST_CARDBUSY)
+		busy = 1;
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	pm_runtime_mark_last_busy(mmc_dev(mmc));
+	pm_runtime_put_autosuspend(mmc_dev(mmc));
+
+	return busy;
+}
+
 /*
  * Validate mmc prerequisites
  */
@@ -191,11 +214,28 @@ static void mmci_write_pwrreg(struct mmc
 /*
  * This must be called with host->lock held
  */
+static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl)
+{
+	/* Keep ST Micro busy mode if enabled */
+	datactrl |= host->datactrl_reg & MCI_ST_DPSM_BUSYMODE;
+
+	if (host->datactrl_reg != datactrl) {
+		host->datactrl_reg = datactrl;
+		writel(datactrl, host->base + MMCIDATACTRL);
+	}
+}
+
+/*
+ * This must be called with host->lock held
+ */
 static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
 {
 	struct variant_data *variant = host->variant;
 	u32 clk = variant->clkreg;
 
+	/* Make sure cclk reflects the current calculated clock */
+	host->cclk = 0;
+
 	if (desired) {
 		if (desired >= host->mclk) {
 			clk = MCI_CLK_BYPASS;
@@ -230,6 +270,9 @@ static void mmci_set_clkreg(struct mmci_
 		/* clk |= MCI_CLK_PWRSAVE; */
 	}
 
+	/* Set actual clock for debug */
+	host->mmc->actual_clock = host->cclk;
+
 	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
 		clk |= MCI_4BIT_BUS;
 	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
@@ -275,7 +318,7 @@ static void mmci_set_mask1(struct mmci_h
 
 static void mmci_stop_data(struct mmci_host *host)
 {
-	writel(0, host->base + MMCIDATACTRL);
+	mmci_write_datactrlreg(host, 0);
 	mmci_set_mask1(host, 0);
 	host->data = NULL;
 }
@@ -304,10 +347,8 @@ static void mmci_dma_setup(struct mmci_h
 	const char *rxname, *txname;
 	dma_cap_mask_t mask;
 
-	if (!plat || !plat->dma_filter) {
-		dev_info(mmc_dev(host->mmc), "no DMA platform data\n");
-		return;
-	}
+	host->dma_rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "rx");
+	host->dma_tx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "tx");
 
 	/* initialize pre request cookie */
 	host->next_data.cookie = 1;
@@ -316,30 +357,33 @@ static void mmci_dma_setup(struct mmci_h
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
-	/*
-	 * If only an RX channel is specified, the driver will
-	 * attempt to use it bidirectionally, however if it is
-	 * is specified but cannot be located, DMA will be disabled.
-	 */
-	if (plat->dma_rx_param) {
-		host->dma_rx_channel = dma_request_channel(mask,
+	if (plat && plat->dma_filter) {
+		if (!host->dma_rx_channel && plat->dma_rx_param) {
+			host->dma_rx_channel = dma_request_channel(mask,
 							   plat->dma_filter,
 							   plat->dma_rx_param);
-		/* E.g if no DMA hardware is present */
-		if (!host->dma_rx_channel)
-			dev_err(mmc_dev(host->mmc), "no RX DMA channel\n");
-	}
+			/* E.g if no DMA hardware is present */
+			if (!host->dma_rx_channel)
+				dev_err(mmc_dev(host->mmc), "no RX DMA channel\n");
+		}
 
-	if (plat->dma_tx_param) {
-		host->dma_tx_channel = dma_request_channel(mask,
+		if (!host->dma_tx_channel && plat->dma_tx_param) {
+			host->dma_tx_channel = dma_request_channel(mask,
 							   plat->dma_filter,
 							   plat->dma_tx_param);
-		if (!host->dma_tx_channel)
-			dev_warn(mmc_dev(host->mmc), "no TX DMA channel\n");
-	} else {
-		host->dma_tx_channel = host->dma_rx_channel;
+			if (!host->dma_tx_channel)
+				dev_warn(mmc_dev(host->mmc), "no TX DMA channel\n");
+		}
 	}
 
+	/*
+	 * If only an RX channel is specified, the driver will
+	 * attempt to use it bidirectionally, however if it is
+	 * is specified but cannot be located, DMA will be disabled.
+	 */
+	if (host->dma_rx_channel && !host->dma_tx_channel)
+		host->dma_tx_channel = host->dma_rx_channel;
+
 	if (host->dma_rx_channel)
 		rxname = dma_chan_name(host->dma_rx_channel);
 	else
@@ -552,7 +596,7 @@ static int mmci_dma_start_data(struct mm
 	datactrl |= MCI_DPSM_DMAENABLE;
 
 	/* Trigger the DMA transfer */
-	writel(datactrl, host->base + MMCIDATACTRL);
+	mmci_write_datactrlreg(host, datactrl);
 
 	/*
 	 * Let the MMCI say when the data is ended and it's time
@@ -750,7 +794,7 @@ static void mmci_start_data(struct mmci_
 		irqmask = MCI_TXFIFOHALFEMPTYMASK;
 	}
 
-	writel(datactrl, base + MMCIDATACTRL);
+	mmci_write_datactrlreg(host, datactrl);
 	writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
 	mmci_set_mask1(host, irqmask);
 }
@@ -842,7 +886,7 @@ mmci_data_irq(struct mmci_host *host, st
 			/* The error clause is handled above, success! */
 			data->bytes_xfered = data->blksz * data->blocks;
 
-		if (!data->stop) {
+		if (!data->stop || host->mrq->sbc) {
 			mmci_request_end(host, data->mrq);
 		} else {
 			mmci_start_command(host, data->stop, 0);
@@ -855,6 +899,7 @@ mmci_cmd_irq(struct mmci_host *host, str
 	     unsigned int status)
 {
 	void __iomem *base = host->base;
+	bool sbc = (cmd == host->mrq->sbc);
 
 	host->cmd = NULL;
 
@@ -869,7 +914,7 @@ mmci_cmd_irq(struct mmci_host *host, str
 		cmd->resp[3] = readl(base + MMCIRESPONSE3);
 	}
 
-	if (!cmd->data || cmd->error) {
+	if ((!sbc && !cmd->data) || cmd->error) {
 		if (host->data) {
 			/* Terminate the DMA transfer */
 			if (dma_inprogress(host)) {
@@ -878,7 +923,9 @@ mmci_cmd_irq(struct mmci_host *host, str
 			}
 			mmci_stop_data(host);
 		}
-		mmci_request_end(host, cmd->mrq);
+		mmci_request_end(host, host->mrq);
+	} else if (sbc) {
+		mmci_start_command(host, host->mrq->cmd, 0);
 	} else if (!(cmd->data->flags & MMC_DATA_READ)) {
 		mmci_start_data(host, cmd->data);
 	}
@@ -1119,7 +1166,10 @@ static void mmci_request(struct mmc_host
 	if (mrq->data && mrq->data->flags & MMC_DATA_READ)
 		mmci_start_data(host, mrq->data);
 
-	mmci_start_command(host, mrq->cmd, 0);
+	if (mrq->sbc)
+		mmci_start_command(host, mrq->sbc, 0);
+	else
+		mmci_start_command(host, mrq->cmd, 0);
 
 	spin_unlock_irqrestore(&host->lock, flags);
 }
@@ -1143,9 +1193,10 @@ static void mmci_set_ios(struct mmc_host
 		if (!IS_ERR(mmc->supply.vmmc))
 			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
 
-		if (!IS_ERR(mmc->supply.vqmmc) &&
-		    regulator_is_enabled(mmc->supply.vqmmc))
+		if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) {
 			regulator_disable(mmc->supply.vqmmc);
+			host->vqmmc_enabled = false;
+		}
 
 		break;
 	case MMC_POWER_UP:
@@ -1161,12 +1212,13 @@ static void mmci_set_ios(struct mmc_host
 
 		break;
 	case MMC_POWER_ON:
-		if (!IS_ERR(mmc->supply.vqmmc) &&
-		    !regulator_is_enabled(mmc->supply.vqmmc)) {
+		if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) {
 			ret = regulator_enable(mmc->supply.vqmmc);
 			if (ret < 0)
 				dev_err(mmc_dev(mmc),
 					"failed to enable vqmmc regulator\n");
+			else
+				host->vqmmc_enabled = true;
 		}
 
 		pwr |= MCI_PWR_ON;
@@ -1251,6 +1303,39 @@ static int mmci_get_cd(struct mmc_host *
 	return status;
 }
 
+static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	int ret = 0;
+
+	if (!IS_ERR(mmc->supply.vqmmc)) {
+
+		pm_runtime_get_sync(mmc_dev(mmc));
+
+		switch (ios->signal_voltage) {
+		case MMC_SIGNAL_VOLTAGE_330:
+			ret = regulator_set_voltage(mmc->supply.vqmmc,
+						2700000, 3600000);
+			break;
+		case MMC_SIGNAL_VOLTAGE_180:
+			ret = regulator_set_voltage(mmc->supply.vqmmc,
+						1700000, 1950000);
+			break;
+		case MMC_SIGNAL_VOLTAGE_120:
+			ret = regulator_set_voltage(mmc->supply.vqmmc,
+						1100000, 1300000);
+			break;
+		}
+
+		if (ret)
+			dev_warn(mmc_dev(mmc), "Voltage switch failed\n");
+
+		pm_runtime_mark_last_busy(mmc_dev(mmc));
+		pm_runtime_put_autosuspend(mmc_dev(mmc));
+	}
+
+	return ret;
+}
+
 static irqreturn_t mmci_cd_irq(int irq, void *dev_id)
 {
 	struct mmci_host *host = dev_id;
@@ -1260,13 +1345,14 @@ static irqreturn_t mmci_cd_irq(int irq,
 	return IRQ_HANDLED;
 }
 
-static const struct mmc_host_ops mmci_ops = {
+static struct mmc_host_ops mmci_ops = {
 	.request	= mmci_request,
 	.pre_req	= mmci_pre_request,
 	.post_req	= mmci_post_request,
 	.set_ios	= mmci_set_ios,
 	.get_ro		= mmci_get_ro,
 	.get_cd		= mmci_get_cd,
+	.start_signal_voltage_switch = mmci_sig_volt_switch,
 };
 
 #ifdef CONFIG_OF
@@ -1362,16 +1448,15 @@ static int mmci_probe(struct amba_device
 	dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
 	dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision);
 
-	host->clk = clk_get(&dev->dev, NULL);
+	host->clk = devm_clk_get(&dev->dev, NULL);
 	if (IS_ERR(host->clk)) {
 		ret = PTR_ERR(host->clk);
-		host->clk = NULL;
 		goto host_free;
 	}
 
 	ret = clk_prepare_enable(host->clk);
 	if (ret)
-		goto clk_free;
+		goto host_free;
 
 	host->plat = plat;
 	host->variant = variant;
@@ -1396,6 +1481,11 @@ static int mmci_probe(struct amba_device
 		goto clk_disable;
 	}
 
+	if (variant->busy_detect) {
+		mmci_ops.card_busy = mmci_card_busy;
+		mmci_write_datactrlreg(host, MCI_ST_DPSM_BUSYMODE);
+	}
+
 	mmc->ops = &mmci_ops;
 	/*
 	 * The ARM and ST versions of the block have slightly different
@@ -1576,8 +1666,6 @@ static int mmci_probe(struct amba_device
 	iounmap(host->base);
  clk_disable:
 	clk_disable_unprepare(host->clk);
- clk_free:
-	clk_put(host->clk);
  host_free:
 	mmc_free_host(mmc);
  rel_regions:
@@ -1623,7 +1711,6 @@ static int mmci_remove(struct amba_devic
 
 		iounmap(host->base);
 		clk_disable_unprepare(host->clk);
-		clk_put(host->clk);
 
 		mmc_free_host(mmc);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/mmci.h linux-libre-3.11-rc7-gnu/drivers/mmc/host/mmci.h
--- linux-libre-3.10-gnu/drivers/mmc/host/mmci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/mmci.h	2013-08-25 20:43:22.000000000 -0400
@@ -94,6 +94,7 @@
 /* Extended status bits for the ST Micro variants */
 #define MCI_ST_SDIOIT		(1 << 22)
 #define MCI_ST_CEATAEND		(1 << 23)
+#define MCI_ST_CARDBUSY		(1 << 24)
 
 #define MMCICLEAR		0x038
 #define MCI_CMDCRCFAILCLR	(1 << 0)
@@ -110,6 +111,7 @@
 /* Extended status bits for the ST Micro variants */
 #define MCI_ST_SDIOITC		(1 << 22)
 #define MCI_ST_CEATAENDC	(1 << 23)
+#define MCI_ST_BUSYENDC		(1 << 24)
 
 #define MMCIMASK0		0x03c
 #define MCI_CMDCRCFAILMASK	(1 << 0)
@@ -183,6 +185,8 @@ struct mmci_host {
 	unsigned int		cclk;
 	u32			pwr_reg;
 	u32			clk_reg;
+	u32			datactrl_reg;
+	bool			vqmmc_enabled;
 	struct mmci_platform_data *plat;
 	struct variant_data	*variant;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/msm_sdcc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/msm_sdcc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/msm_sdcc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/msm_sdcc.c	2013-08-25 20:43:22.000000000 -0400
@@ -1268,10 +1268,18 @@ msmsdcc_probe(struct platform_device *pd
 		goto clk_put;
 	}
 
+	ret = clk_prepare(host->pclk);
+	if (ret)
+		goto clk_put;
+
+	ret = clk_prepare(host->clk);
+	if (ret)
+		goto clk_unprepare_p;
+
 	/* Enable clocks */
 	ret = msmsdcc_enable_clocks(host);
 	if (ret)
-		goto clk_put;
+		goto clk_unprepare;
 
 	host->pclk_rate = clk_get_rate(host->pclk);
 	host->clk_rate = clk_get_rate(host->clk);
@@ -1386,6 +1394,10 @@ msmsdcc_probe(struct platform_device *pd
 		free_irq(host->stat_irq, host);
  clk_disable:
 	msmsdcc_disable_clocks(host, 0);
+ clk_unprepare:
+	clk_unprepare(host->clk);
+ clk_unprepare_p:
+	clk_unprepare(host->pclk);
  clk_put:
 	clk_put(host->clk);
  pclk_put:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/mvsdio.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/mvsdio.c
--- linux-libre-3.10-gnu/drivers/mmc/host/mvsdio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/mvsdio.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,7 +35,7 @@
 
 #define DRIVER_NAME	"mvsdio"
 
-static int maxfreq = MVSD_CLOCKRATE_MAX;
+static int maxfreq;
 static int nodma;
 
 struct mvsd_host {
@@ -685,7 +685,6 @@ static int __init mvsd_probe(struct plat
 	const struct mbus_dram_target_info *dram;
 	struct resource *r;
 	int ret, irq;
-	int gpio_card_detect, gpio_write_protect;
 	struct pinctrl *pinctrl;
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -718,6 +717,20 @@ static int __init mvsd_probe(struct plat
 	if (!IS_ERR(host->clk))
 		clk_prepare_enable(host->clk);
 
+	mmc->ops = &mvsd_ops;
+
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	mmc->f_min = DIV_ROUND_UP(host->base_clock, MVSD_BASE_DIV_MAX);
+	mmc->f_max = MVSD_CLOCKRATE_MAX;
+
+	mmc->max_blk_size = 2048;
+	mmc->max_blk_count = 65535;
+
+	mmc->max_segs = 1;
+	mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
+	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+
 	if (np) {
 		if (IS_ERR(host->clk)) {
 			dev_err(&pdev->dev, "DT platforms must have a clock associated\n");
@@ -726,35 +739,38 @@ static int __init mvsd_probe(struct plat
 		}
 
 		host->base_clock = clk_get_rate(host->clk) / 2;
-		gpio_card_detect = of_get_named_gpio(np, "cd-gpios", 0);
-		gpio_write_protect = of_get_named_gpio(np, "wp-gpios", 0);
+		ret = mmc_of_parse(mmc);
+		if (ret < 0)
+			goto out;
 	} else {
 		const struct mvsdio_platform_data *mvsd_data;
+
 		mvsd_data = pdev->dev.platform_data;
 		if (!mvsd_data) {
 			ret = -ENXIO;
 			goto out;
 		}
+		mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
+			    MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 		host->base_clock = mvsd_data->clock / 2;
-		gpio_card_detect = mvsd_data->gpio_card_detect ? : -EINVAL;
-		gpio_write_protect = mvsd_data->gpio_write_protect ? : -EINVAL;
-	}
-
-	mmc->ops = &mvsd_ops;
-
-	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
-		    MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
-
-	mmc->f_min = DIV_ROUND_UP(host->base_clock, MVSD_BASE_DIV_MAX);
-	mmc->f_max = maxfreq;
+		/* GPIO 0 regarded as invalid for backward compatibility */
+		if (mvsd_data->gpio_card_detect &&
+		    gpio_is_valid(mvsd_data->gpio_card_detect)) {
+			ret = mmc_gpio_request_cd(mmc,
+						  mvsd_data->gpio_card_detect);
+			if (ret)
+				goto out;
+		} else {
+			mmc->caps |= MMC_CAP_NEEDS_POLL;
+		}
 
-	mmc->max_blk_size = 2048;
-	mmc->max_blk_count = 65535;
+		if (mvsd_data->gpio_write_protect &&
+		    gpio_is_valid(mvsd_data->gpio_write_protect))
+			mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect);
+	}
 
-	mmc->max_segs = 1;
-	mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
-	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+	if (maxfreq)
+		mmc->f_max = maxfreq;
 
 	spin_lock_init(&host->lock);
 
@@ -777,15 +793,6 @@ static int __init mvsd_probe(struct plat
 		goto out;
 	}
 
-	if (gpio_is_valid(gpio_card_detect)) {
-		ret = mmc_gpio_request_cd(mmc, gpio_card_detect);
-		if (ret)
-			goto out;
-	} else
-		mmc->caps |= MMC_CAP_NEEDS_POLL;
-
-	mmc_gpio_request_ro(mmc, gpio_write_protect);
-
 	setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host);
 	platform_set_drvdata(pdev, mmc);
 	ret = mmc_add_host(mmc);
@@ -793,10 +800,10 @@ static int __init mvsd_probe(struct plat
 		goto out;
 
 	if (!(mmc->caps & MMC_CAP_NEEDS_POLL))
-		dev_notice(&pdev->dev, "using GPIO %d for card detection\n",
-			   gpio_card_detect);
+		dev_notice(&pdev->dev, "using GPIO for card detection\n");
 	else
-		dev_notice(&pdev->dev, "lacking card detect (fall back to polling)\n");
+		dev_notice(&pdev->dev,
+			   "lacking card detect (fall back to polling)\n");
 	return 0;
 
 out:
@@ -827,7 +834,6 @@ static int __exit mvsd_remove(struct pla
 		clk_disable_unprepare(host->clk);
 	mmc_free_host(mmc);
 
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/mxcmmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/mxcmmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/mxcmmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/mxcmmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -1067,7 +1067,9 @@ static int mxcmci_probe(struct platform_
 		goto out_release_mem;
 	}
 
-	mmc_of_parse(mmc);
+	ret = mmc_of_parse(mmc);
+	if (ret)
+		goto out_free;
 	mmc->ops = &mxcmci_ops;
 
 	/* For devicetree parsing, the bus width is read from devicetree */
@@ -1219,8 +1221,6 @@ static int mxcmci_remove(struct platform
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 	struct mxcmci_host *host = mmc_priv(mmc);
 
-	platform_set_drvdata(pdev, NULL);
-
 	mmc_remove_host(mmc);
 
 	if (host->vcc)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/mxs-mmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/mxs-mmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/mxs-mmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/mxs-mmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,7 +41,6 @@
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/module.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/stmp_device.h>
 #include <linux/spi/mxs-spi.h>
 
@@ -580,7 +579,6 @@ static int mxs_mmc_probe(struct platform
 	struct mxs_mmc_host *host;
 	struct mmc_host *mmc;
 	struct resource *iores;
-	struct pinctrl *pinctrl;
 	int ret = 0, irq_err;
 	struct regulator *reg_vmmc;
 	enum of_gpio_flags flags;
@@ -620,12 +618,6 @@ static int mxs_mmc_probe(struct platform
 		}
 	}
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl)) {
-		ret = PTR_ERR(pinctrl);
-		goto out_mmc_free;
-	}
-
 	ssp->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(ssp->clk)) {
 		ret = PTR_ERR(ssp->clk);
@@ -639,6 +631,7 @@ static int mxs_mmc_probe(struct platform
 	if (!ssp->dmach) {
 		dev_err(mmc_dev(host->mmc),
 			"%s: failed to request dma\n", __func__);
+		ret = -ENODEV;
 		goto out_clk_put;
 	}
 
@@ -708,8 +701,6 @@ static int mxs_mmc_remove(struct platfor
 
 	mmc_remove_host(mmc);
 
-	platform_set_drvdata(pdev, NULL);
-
 	if (ssp->dmach)
 		dma_release_channel(ssp->dmach);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/omap.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/omap.c
--- linux-libre-3.10-gnu/drivers/mmc/host/omap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/omap.c	2013-08-25 20:43:22.000000000 -0400
@@ -1413,33 +1413,17 @@ static int mmc_omap_probe(struct platfor
 	else
 		sig = host->id == 0 ? OMAP_DMA_MMC_TX : OMAP_DMA_MMC2_TX;
 	host->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
-#if 0
-	if (!host->dma_tx) {
-		dev_err(host->dev, "unable to obtain TX DMA engine channel %u\n",
-			sig);
-		goto err_dma;
-	}
-#else
 	if (!host->dma_tx)
 		dev_warn(host->dev, "unable to obtain TX DMA engine channel %u\n",
 			sig);
-#endif
 	if (mmc_omap2())
 		sig = host->id == 0 ? OMAP24XX_DMA_MMC1_RX : OMAP24XX_DMA_MMC2_RX;
 	else
 		sig = host->id == 0 ? OMAP_DMA_MMC_RX : OMAP_DMA_MMC2_RX;
 	host->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
-#if 0
-	if (!host->dma_rx) {
-		dev_err(host->dev, "unable to obtain RX DMA engine channel %u\n",
-			sig);
-		goto err_dma;
-	}
-#else
 	if (!host->dma_rx)
 		dev_warn(host->dev, "unable to obtain RX DMA engine channel %u\n",
 			sig);
-#endif
 
 	ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host);
 	if (ret)
@@ -1500,8 +1484,6 @@ static int mmc_omap_remove(struct platfo
 	struct mmc_omap_host *host = platform_get_drvdata(pdev);
 	int i;
 
-	platform_set_drvdata(pdev, NULL);
-
 	BUG_ON(host == NULL);
 
 	for (i = 0; i < host->nr_slots; i++)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/omap_hsmmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/omap_hsmmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/omap_hsmmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/omap_hsmmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -2047,7 +2047,6 @@ err_irq:
 	}
 err1:
 	iounmap(host->base);
-	platform_set_drvdata(pdev, NULL);
 	mmc_free_host(mmc);
 err_alloc:
 	omap_hsmmc_gpio_free(pdata);
@@ -2093,7 +2092,6 @@ static int omap_hsmmc_remove(struct plat
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res)
 		release_mem_region(res->start, resource_size(res));
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/pxamci.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/pxamci.c
--- linux-libre-3.10-gnu/drivers/mmc/host/pxamci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/pxamci.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,7 +128,7 @@ static inline int pxamci_set_power(struc
 			       !!on ^ host->pdata->gpio_power_invert);
 	}
 	if (!host->vcc && host->pdata && host->pdata->setpower)
-		host->pdata->setpower(mmc_dev(host->mmc), vdd);
+		return host->pdata->setpower(mmc_dev(host->mmc), vdd);
 
 	return 0;
 }
@@ -834,8 +834,6 @@ static int pxamci_remove(struct platform
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 	int gpio_cd = -1, gpio_ro = -1, gpio_power = -1;
 
-	platform_set_drvdata(pdev, NULL);
-
 	if (mmc) {
 		struct pxamci_host *host = mmc_priv(mmc);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/rtsx_pci_sdmmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/rtsx_pci_sdmmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/rtsx_pci_sdmmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/rtsx_pci_sdmmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -1316,8 +1316,6 @@ static int rtsx_pci_sdmmc_drv_remove(str
 	mmc_remove_host(mmc);
 	mmc_free_host(mmc);
 
-	platform_set_drvdata(pdev, NULL);
-
 	dev_dbg(&(pdev->dev),
 		": Realtek PCI-E SDMMC controller has been removed\n");
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-acpi.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-acpi.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-acpi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-acpi.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,10 +31,13 @@
 #include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/err.h>
+#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/acpi.h>
+#include <linux/acpi_gpio.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
+#include <linux/delay.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/pm.h>
@@ -83,12 +86,37 @@ static int sdhci_acpi_enable_dma(struct
 	return 0;
 }
 
+static void sdhci_acpi_int_hw_reset(struct sdhci_host *host)
+{
+	u8 reg;
+
+	reg = sdhci_readb(host, SDHCI_POWER_CONTROL);
+	reg |= 0x10;
+	sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
+	/* For eMMC, minimum is 1us but give it 9us for good measure */
+	udelay(9);
+	reg &= ~0x10;
+	sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
+	/* For eMMC, minimum is 200us but give it 300us for good measure */
+	usleep_range(300, 1000);
+}
+
 static const struct sdhci_ops sdhci_acpi_ops_dflt = {
 	.enable_dma = sdhci_acpi_enable_dma,
 };
 
+static const struct sdhci_ops sdhci_acpi_ops_int = {
+	.enable_dma = sdhci_acpi_enable_dma,
+	.hw_reset   = sdhci_acpi_int_hw_reset,
+};
+
+static const struct sdhci_acpi_chip sdhci_acpi_chip_int = {
+	.ops = &sdhci_acpi_ops_int,
+};
+
 static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
-	.caps    = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+	.chip    = &sdhci_acpi_chip_int,
+	.caps    = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE | MMC_CAP_HW_RESET,
 	.caps2   = MMC_CAP2_HC_ERASE_SZ,
 	.flags   = SDHCI_ACPI_RUNTIME_PM,
 };
@@ -101,6 +129,8 @@ static const struct sdhci_acpi_slot sdhc
 };
 
 static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = {
+	.flags   = SDHCI_ACPI_SD_CD | SDHCI_ACPI_RUNTIME_PM,
+	.quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON,
 };
 
 struct sdhci_acpi_uid_slot {
@@ -161,6 +191,59 @@ static const struct sdhci_acpi_slot *sdh
 	return slot;
 }
 
+#ifdef CONFIG_PM_RUNTIME
+
+static irqreturn_t sdhci_acpi_sd_cd(int irq, void *dev_id)
+{
+	mmc_detect_change(dev_id, msecs_to_jiffies(200));
+	return IRQ_HANDLED;
+}
+
+static int sdhci_acpi_add_own_cd(struct device *dev, int gpio,
+				 struct mmc_host *mmc)
+{
+	unsigned long flags;
+	int err, irq;
+
+	if (gpio < 0) {
+		err = gpio;
+		goto out;
+	}
+
+	err = devm_gpio_request_one(dev, gpio, GPIOF_DIR_IN, "sd_cd");
+	if (err)
+		goto out;
+
+	irq = gpio_to_irq(gpio);
+	if (irq < 0) {
+		err = irq;
+		goto out_free;
+	}
+
+	flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
+	err = devm_request_irq(dev, irq, sdhci_acpi_sd_cd, flags, "sd_cd", mmc);
+	if (err)
+		goto out_free;
+
+	return 0;
+
+out_free:
+	devm_gpio_free(dev, gpio);
+out:
+	dev_warn(dev, "failed to setup card detect wake up\n");
+	return err;
+}
+
+#else
+
+static int sdhci_acpi_add_own_cd(struct device *dev, int gpio,
+				 struct mmc_host *mmc)
+{
+	return 0;
+}
+
+#endif
+
 static int sdhci_acpi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -171,7 +254,7 @@ static int sdhci_acpi_probe(struct platf
 	struct resource *iomem;
 	resource_size_t len;
 	const char *hid;
-	int err;
+	int err, gpio;
 
 	if (acpi_bus_get_device(handle, &device))
 		return -ENODEV;
@@ -196,6 +279,8 @@ static int sdhci_acpi_probe(struct platf
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
+	gpio = acpi_get_gpio_by_index(dev, 0, NULL);
+
 	c = sdhci_priv(host);
 	c->host = host;
 	c->slot = sdhci_acpi_get_slot(handle, hid);
@@ -251,6 +336,11 @@ static int sdhci_acpi_probe(struct platf
 	if (err)
 		goto err_free;
 
+	if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) {
+		if (sdhci_acpi_add_own_cd(dev, gpio, host->mmc))
+			c->use_runtime_pm = false;
+	}
+
 	if (c->use_runtime_pm) {
 		pm_runtime_set_active(dev);
 		pm_suspend_ignore_children(dev, 1);
@@ -262,7 +352,6 @@ static int sdhci_acpi_probe(struct platf
 	return 0;
 
 err_free:
-	platform_set_drvdata(pdev, NULL);
 	sdhci_free_host(c->host);
 	return err;
 }
@@ -281,7 +370,6 @@ static int sdhci_acpi_remove(struct plat
 
 	dead = (sdhci_readl(c->host, SDHCI_INT_STATUS) == ~0);
 	sdhci_remove_host(c->host, dead);
-	platform_set_drvdata(pdev, NULL);
 	sdhci_free_host(c->host);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-bcm2835.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-bcm2835.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-bcm2835.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-bcm2835.c	2013-08-25 20:43:22.000000000 -0400
@@ -148,7 +148,7 @@ static int bcm2835_sdhci_probe(struct pl
 	struct sdhci_pltfm_host *pltfm_host;
 	int ret;
 
-	host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata);
+	host = sdhci_pltfm_init(pdev, &bcm2835_sdhci_pdata, 0);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-bcm-kona.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-bcm-kona.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-bcm-kona.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-bcm-kona.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/highmem.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/version.h>
+#include <linux/mmc/slot-gpio.h>
+
+#include "sdhci-pltfm.h"
+#include "sdhci.h"
+
+#define SDHCI_SOFT_RESET			0x01000000
+#define KONA_SDHOST_CORECTRL			0x8000
+#define KONA_SDHOST_CD_PINCTRL			0x00000008
+#define KONA_SDHOST_STOP_HCLK			0x00000004
+#define KONA_SDHOST_RESET			0x00000002
+#define KONA_SDHOST_EN				0x00000001
+
+#define KONA_SDHOST_CORESTAT			0x8004
+#define KONA_SDHOST_WP				0x00000002
+#define KONA_SDHOST_CD_SW			0x00000001
+
+#define KONA_SDHOST_COREIMR			0x8008
+#define KONA_SDHOST_IP				0x00000001
+
+#define KONA_SDHOST_COREISR			0x800C
+#define KONA_SDHOST_COREIMSR			0x8010
+#define KONA_SDHOST_COREDBG1			0x8014
+#define KONA_SDHOST_COREGPO_MASK		0x8018
+
+#define SD_DETECT_GPIO_DEBOUNCE_128MS		128
+
+#define KONA_MMC_AUTOSUSPEND_DELAY		(50)
+
+struct sdhci_bcm_kona_dev {
+	struct mutex	write_lock; /* protect back to back writes */
+};
+
+
+static int sdhci_bcm_kona_sd_reset(struct sdhci_host *host)
+{
+	unsigned int val;
+	unsigned long timeout;
+
+	/* This timeout should be sufficent for core to reset */
+	timeout = jiffies + msecs_to_jiffies(100);
+
+	/* reset the host using the top level reset */
+	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
+	val |= KONA_SDHOST_RESET;
+	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
+
+	while (!(sdhci_readl(host, KONA_SDHOST_CORECTRL) & KONA_SDHOST_RESET)) {
+		if (time_is_before_jiffies(timeout)) {
+			pr_err("Error: sd host is stuck in reset!!!\n");
+			return -EFAULT;
+		}
+	}
+
+	/* bring the host out of reset */
+	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
+	val &= ~KONA_SDHOST_RESET;
+
+	/*
+	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
+	 * Back-to-Back writes to same register needs delay when SD bus clock
+	 * is very low w.r.t AHB clock, mainly during boot-time and during card
+	 * insert-removal.
+	 */
+	usleep_range(1000, 5000);
+	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
+
+	return 0;
+}
+
+static void sdhci_bcm_kona_sd_init(struct sdhci_host *host)
+{
+	unsigned int val;
+
+	/* enable the interrupt from the IP core */
+	val = sdhci_readl(host, KONA_SDHOST_COREIMR);
+	val |= KONA_SDHOST_IP;
+	sdhci_writel(host, val, KONA_SDHOST_COREIMR);
+
+	/* Enable the AHB clock gating module to the host */
+	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
+	val |= KONA_SDHOST_EN;
+
+	/*
+	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
+	 * Back-to-Back writes to same register needs delay when SD bus clock
+	 * is very low w.r.t AHB clock, mainly during boot-time and during card
+	 * insert-removal.
+	 */
+	usleep_range(1000, 5000);
+	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
+}
+
+/*
+ * Software emulation of the SD card insertion/removal. Set insert=1 for insert
+ * and insert=0 for removal. The card detection is done by GPIO. For Broadcom
+ * IP to function properly the bit 0 of CORESTAT register needs to be set/reset
+ * to generate the CD IRQ handled in sdhci.c which schedules card_tasklet.
+ */
+static int sdhci_bcm_kona_sd_card_emulate(struct sdhci_host *host, int insert)
+{
+	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
+	struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv);
+	u32 val;
+
+	/*
+	 * Back-to-Back register write needs a delay of min 10uS.
+	 * Back-to-Back writes to same register needs delay when SD bus clock
+	 * is very low w.r.t AHB clock, mainly during boot-time and during card
+	 * insert-removal.
+	 * We keep 20uS
+	 */
+	mutex_lock(&kona_dev->write_lock);
+	udelay(20);
+	val = sdhci_readl(host, KONA_SDHOST_CORESTAT);
+
+	if (insert) {
+		int ret;
+
+		ret = mmc_gpio_get_ro(host->mmc);
+		if (ret >= 0)
+			val = (val & ~KONA_SDHOST_WP) |
+				((ret) ? KONA_SDHOST_WP : 0);
+
+		val |= KONA_SDHOST_CD_SW;
+		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
+	} else {
+		val &= ~KONA_SDHOST_CD_SW;
+		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
+	}
+	mutex_unlock(&kona_dev->write_lock);
+
+	return 0;
+}
+
+/*
+ * SD card interrupt event callback
+ */
+void sdhci_bcm_kona_card_event(struct sdhci_host *host)
+{
+	if (mmc_gpio_get_cd(host->mmc) > 0) {
+		dev_dbg(mmc_dev(host->mmc),
+			"card inserted\n");
+		sdhci_bcm_kona_sd_card_emulate(host, 1);
+	} else {
+		dev_dbg(mmc_dev(host->mmc),
+			"card removed\n");
+		sdhci_bcm_kona_sd_card_emulate(host, 0);
+	}
+}
+
+/*
+ * Get the base clock. Use central clock source for now. Not sure if different
+ * clock speed to each dev is allowed
+ */
+static unsigned int sdhci_bcm_kona_get_max_clk(struct sdhci_host *host)
+{
+	struct sdhci_bcm_kona_dev *kona_dev;
+	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
+	kona_dev = sdhci_pltfm_priv(pltfm_priv);
+
+	return host->mmc->f_max;
+}
+
+static unsigned int sdhci_bcm_kona_get_timeout_clock(struct sdhci_host *host)
+{
+	return sdhci_bcm_kona_get_max_clk(host);
+}
+
+static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
+				u8 power_mode)
+{
+	/*
+	 *  JEDEC and SD spec specify supplying 74 continuous clocks to
+	 * device after power up. With minimum bus (100KHz) that
+	 * that translates to 740us
+	 */
+	if (power_mode != MMC_POWER_OFF)
+		udelay(740);
+}
+
+static struct sdhci_ops sdhci_bcm_kona_ops = {
+	.get_max_clock = sdhci_bcm_kona_get_max_clk,
+	.get_timeout_clock = sdhci_bcm_kona_get_timeout_clock,
+	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
+	.card_event = sdhci_bcm_kona_card_event,
+};
+
+static struct sdhci_pltfm_data sdhci_pltfm_data_kona = {
+	.ops    = &sdhci_bcm_kona_ops,
+	.quirks = SDHCI_QUIRK_NO_CARD_NO_RESET |
+		SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_32BIT_DMA_ADDR |
+		SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE |
+		SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
+		SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
+};
+
+static const struct of_device_id sdhci_bcm_kona_of_match[] __initdata = {
+	{ .compatible = "bcm,kona-sdhci"},
+	{}
+};
+MODULE_DEVICE_TABLE(of, sdhci_bcm_kona_of_match);
+
+static int __init sdhci_bcm_kona_probe(struct platform_device *pdev)
+{
+	struct sdhci_bcm_kona_dev *kona_dev = NULL;
+	struct sdhci_pltfm_host *pltfm_priv;
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host;
+	int ret;
+
+	ret = 0;
+
+	host = sdhci_pltfm_init(pdev, &sdhci_pltfm_data_kona,
+			sizeof(*kona_dev));
+	if (IS_ERR(host))
+		return PTR_ERR(host);
+
+	dev_dbg(dev, "%s: inited. IOADDR=%p\n", __func__, host->ioaddr);
+
+	pltfm_priv = sdhci_priv(host);
+
+	kona_dev = sdhci_pltfm_priv(pltfm_priv);
+	mutex_init(&kona_dev->write_lock);
+
+	mmc_of_parse(host->mmc);
+
+	if (!host->mmc->f_max) {
+		dev_err(&pdev->dev, "Missing max-freq for SDHCI cfg\n");
+		ret = -ENXIO;
+		goto err_pltfm_free;
+	}
+
+	dev_dbg(dev, "non-removable=%c\n",
+		(host->mmc->caps & MMC_CAP_NONREMOVABLE) ? 'Y' : 'N');
+	dev_dbg(dev, "cd_gpio %c, wp_gpio %c\n",
+		(mmc_gpio_get_cd(host->mmc) != -ENOSYS) ? 'Y' : 'N',
+		(mmc_gpio_get_ro(host->mmc) != -ENOSYS) ? 'Y' : 'N');
+
+	if (host->mmc->caps | MMC_CAP_NONREMOVABLE)
+		host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+
+	dev_dbg(dev, "is_8bit=%c\n",
+		(host->mmc->caps | MMC_CAP_8_BIT_DATA) ? 'Y' : 'N');
+
+	ret = sdhci_bcm_kona_sd_reset(host);
+	if (ret)
+		goto err_pltfm_free;
+
+	sdhci_bcm_kona_sd_init(host);
+
+	ret = sdhci_add_host(host);
+	if (ret) {
+		dev_err(dev, "Failed sdhci_add_host\n");
+		goto err_reset;
+	}
+
+	/* if device is eMMC, emulate card insert right here */
+	if (host->mmc->caps | MMC_CAP_NONREMOVABLE) {
+		ret = sdhci_bcm_kona_sd_card_emulate(host, 1);
+		if (ret) {
+			dev_err(dev,
+				"unable to emulate card insertion\n");
+			goto err_remove_host;
+		}
+	}
+	/*
+	 * Since the card detection GPIO interrupt is configured to be
+	 * edge sensitive, check the initial GPIO value here, emulate
+	 * only if the card is present
+	 */
+	if (mmc_gpio_get_cd(host->mmc) > 0)
+		sdhci_bcm_kona_sd_card_emulate(host, 1);
+
+	dev_dbg(dev, "initialized properly\n");
+	return 0;
+
+err_remove_host:
+	sdhci_remove_host(host, 0);
+
+err_reset:
+	sdhci_bcm_kona_sd_reset(host);
+
+err_pltfm_free:
+	sdhci_pltfm_free(pdev);
+
+	dev_err(dev, "Probing of sdhci-pltfm failed: %d\n", ret);
+	return ret;
+}
+
+static int __exit sdhci_bcm_kona_remove(struct platform_device *pdev)
+{
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+	int dead;
+	u32 scratch;
+
+	dead = 0;
+	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
+	if (scratch == (u32)-1)
+		dead = 1;
+	sdhci_remove_host(host, dead);
+
+	sdhci_free_host(host);
+
+	return 0;
+}
+
+static struct platform_driver sdhci_bcm_kona_driver = {
+	.driver		= {
+		.name	= "sdhci-kona",
+		.owner	= THIS_MODULE,
+		.pm	= SDHCI_PLTFM_PMOPS,
+		.of_match_table = of_match_ptr(sdhci_bcm_kona_of_match),
+	},
+	.probe		= sdhci_bcm_kona_probe,
+	.remove		= __exit_p(sdhci_bcm_kona_remove),
+};
+module_platform_driver(sdhci_bcm_kona_driver);
+
+MODULE_DESCRIPTION("SDHCI driver for Broadcom Kona platform");
+MODULE_AUTHOR("Broadcom");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci.c	2013-08-25 20:43:22.000000000 -0400
@@ -58,6 +58,8 @@ static void sdhci_enable_preset_value(st
 #ifdef CONFIG_PM_RUNTIME
 static int sdhci_runtime_pm_get(struct sdhci_host *host);
 static int sdhci_runtime_pm_put(struct sdhci_host *host);
+static void sdhci_runtime_pm_bus_on(struct sdhci_host *host);
+static void sdhci_runtime_pm_bus_off(struct sdhci_host *host);
 #else
 static inline int sdhci_runtime_pm_get(struct sdhci_host *host)
 {
@@ -67,6 +69,12 @@ static inline int sdhci_runtime_pm_put(s
 {
 	return 0;
 }
+static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
+{
+}
+static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
+{
+}
 #endif
 
 static void sdhci_dumpregs(struct sdhci_host *host)
@@ -192,8 +200,12 @@ static void sdhci_reset(struct sdhci_hos
 
 	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
 
-	if (mask & SDHCI_RESET_ALL)
+	if (mask & SDHCI_RESET_ALL) {
 		host->clock = 0;
+		/* Reset-all turns off SD Bus Power */
+		if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
+			sdhci_runtime_pm_bus_off(host);
+	}
 
 	/* Wait max 100 ms */
 	timeout = 100;
@@ -1268,6 +1280,8 @@ static int sdhci_set_power(struct sdhci_
 
 	if (pwr == 0) {
 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+		if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
+			sdhci_runtime_pm_bus_off(host);
 		return 0;
 	}
 
@@ -1289,6 +1303,9 @@ static int sdhci_set_power(struct sdhci_
 
 	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
 
+	if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
+		sdhci_runtime_pm_bus_on(host);
+
 	/*
 	 * Some controllers need an extra 10ms delay of 10ms before they
 	 * can apply clock after applying power
@@ -1526,16 +1543,15 @@ static void sdhci_do_set_ios(struct sdhc
 			ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 			/* Select Bus Speed Mode for host */
 			ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
-			if (ios->timing == MMC_TIMING_MMC_HS200)
-				ctrl_2 |= SDHCI_CTRL_HS_SDR200;
+			if ((ios->timing == MMC_TIMING_MMC_HS200) ||
+			    (ios->timing == MMC_TIMING_UHS_SDR104))
+				ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
 			else if (ios->timing == MMC_TIMING_UHS_SDR12)
 				ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
 			else if (ios->timing == MMC_TIMING_UHS_SDR25)
 				ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
 			else if (ios->timing == MMC_TIMING_UHS_SDR50)
 				ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
-			else if (ios->timing == MMC_TIMING_UHS_SDR104)
-				ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
 			else if (ios->timing == MMC_TIMING_UHS_DDR50)
 				ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
 			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
@@ -1846,7 +1862,7 @@ static int sdhci_execute_tuning(struct m
 	 */
 	if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
 	    (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
-	     host->flags & SDHCI_HS200_NEEDS_TUNING))
+	     host->flags & SDHCI_SDR104_NEEDS_TUNING))
 		requires_tuning_nonuhs = true;
 
 	if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
@@ -2046,11 +2062,14 @@ static void sdhci_card_event(struct mmc_
 	struct sdhci_host *host = mmc_priv(mmc);
 	unsigned long flags;
 
+	/* First check if client has provided their own card event */
+	if (host->ops->card_event)
+		host->ops->card_event(host);
+
 	spin_lock_irqsave(&host->lock, flags);
 
 	/* Check host->mrq first in case we are runtime suspended */
-	if (host->mrq &&
-	    !(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
+	if (host->mrq && !sdhci_do_get_cd(host)) {
 		pr_err("%s: Card removed during transfer!\n",
 			mmc_hostname(host->mmc));
 		pr_err("%s: Resetting controller.\n",
@@ -2625,6 +2644,22 @@ static int sdhci_runtime_pm_put(struct s
 	return pm_runtime_put_autosuspend(host->mmc->parent);
 }
 
+static void sdhci_runtime_pm_bus_on(struct sdhci_host *host)
+{
+	if (host->runtime_suspended || host->bus_on)
+		return;
+	host->bus_on = true;
+	pm_runtime_get_noresume(host->mmc->parent);
+}
+
+static void sdhci_runtime_pm_bus_off(struct sdhci_host *host)
+{
+	if (host->runtime_suspended || !host->bus_on)
+		return;
+	host->bus_on = false;
+	pm_runtime_put_noidle(host->mmc->parent);
+}
+
 int sdhci_runtime_suspend_host(struct sdhci_host *host)
 {
 	unsigned long flags;
@@ -2962,9 +2997,13 @@ int sdhci_add_host(struct sdhci_host *ho
 		mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
 
 	/* SDR104 supports also implies SDR50 support */
-	if (caps[1] & SDHCI_SUPPORT_SDR104)
+	if (caps[1] & SDHCI_SUPPORT_SDR104) {
 		mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50;
-	else if (caps[1] & SDHCI_SUPPORT_SDR50)
+		/* SD3.0: SDR104 is supported so (for eMMC) the caps2
+		 * field can be promoted to support HS200.
+		 */
+		mmc->caps2 |= MMC_CAP2_HS200;
+	} else if (caps[1] & SDHCI_SUPPORT_SDR50)
 		mmc->caps |= MMC_CAP_UHS_SDR50;
 
 	if (caps[1] & SDHCI_SUPPORT_DDR50)
@@ -2974,9 +3013,9 @@ int sdhci_add_host(struct sdhci_host *ho
 	if (caps[1] & SDHCI_USE_SDR50_TUNING)
 		host->flags |= SDHCI_SDR50_NEEDS_TUNING;
 
-	/* Does the host need tuning for HS200? */
+	/* Does the host need tuning for SDR104 / HS200? */
 	if (mmc->caps2 & MMC_CAP2_HS200)
-		host->flags |= SDHCI_HS200_NEEDS_TUNING;
+		host->flags |= SDHCI_SDR104_NEEDS_TUNING;
 
 	/* Driver Type(s) (A, C, D) supported by the host */
 	if (caps[1] & SDHCI_DRIVER_TYPE_A)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-cns3xxx.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-cns3xxx.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-cns3xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-cns3xxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -96,7 +96,7 @@ static const struct sdhci_pltfm_data sdh
 
 static int sdhci_cns3xxx_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata);
+	return sdhci_pltfm_register(pdev, &sdhci_cns3xxx_pdata, 0);
 }
 
 static int sdhci_cns3xxx_remove(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-dove.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-dove.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-dove.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-dove.c	2013-08-25 20:43:22.000000000 -0400
@@ -130,7 +130,7 @@ static int sdhci_dove_probe(struct platf
 		gpio_direction_input(priv->gpio_cd);
 	}
 
-	host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata);
+	host = sdhci_pltfm_init(pdev, &sdhci_dove_pdata, 0);
 	if (IS_ERR(host)) {
 		ret = PTR_ERR(host);
 		goto err_sdhci_pltfm_init;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-esdhc.h linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-esdhc.h
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-esdhc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-esdhc.h	2013-08-25 20:43:22.000000000 -0400
@@ -36,13 +36,21 @@
 /* pltfm-specific */
 #define ESDHC_HOST_CONTROL_LE	0x20
 
+/*
+ * P2020 interpretation of the SDHCI_HOST_CONTROL register
+ */
+#define ESDHC_CTRL_4BITBUS          (0x1 << 1)
+#define ESDHC_CTRL_8BITBUS          (0x2 << 1)
+#define ESDHC_CTRL_BUSWIDTH_MASK    (0x3 << 1)
+
 /* OF-specific */
 #define ESDHC_DMA_SYSCTL	0x40c
 #define ESDHC_DMA_SNOOP		0x00000040
 
 #define ESDHC_HOST_CONTROL_RES	0x05
 
-static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
+static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock,
+				   unsigned int host_clock)
 {
 	int pre_div = 2;
 	int div = 1;
@@ -56,14 +64,14 @@ static inline void esdhc_set_clock(struc
 		| ESDHC_CLOCK_MASK);
 	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
 
-	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
+	while (host_clock / pre_div / 16 > clock && pre_div < 256)
 		pre_div *= 2;
 
-	while (host->max_clk / pre_div / div > clock && div < 16)
+	while (host_clock / pre_div / div > clock && div < 16)
 		div++;
 
 	dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
-		clock, host->max_clk / pre_div / div);
+		clock, host_clock / pre_div / div);
 
 	pre_div >>= 1;
 	div--;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-esdhc-imx.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-esdhc-imx.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-esdhc-imx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-esdhc-imx.c	2013-08-25 20:43:22.000000000 -0400
@@ -384,6 +384,20 @@ static void esdhc_writeb_le(struct sdhci
 	}
 }
 
+static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct pltfm_imx_data *imx_data = pltfm_host->priv;
+	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
+
+	u32 f_host = clk_get_rate(pltfm_host->clk);
+
+	if (boarddata->f_max && (boarddata->f_max < f_host))
+		return boarddata->f_max;
+	else
+		return f_host;
+}
+
 static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -391,6 +405,14 @@ static unsigned int esdhc_pltfm_get_min_
 	return clk_get_rate(pltfm_host->clk) / 256 / 16;
 }
 
+static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
+					 unsigned int clock)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	esdhc_set_clock(host, clock, clk_get_rate(pltfm_host->clk));
+}
+
 static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -438,8 +460,8 @@ static const struct sdhci_ops sdhci_esdh
 	.write_l = esdhc_writel_le,
 	.write_w = esdhc_writew_le,
 	.write_b = esdhc_writeb_le,
-	.set_clock = esdhc_set_clock,
-	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
+	.set_clock = esdhc_pltfm_set_clock,
+	.get_max_clock = esdhc_pltfm_get_max_clock,
 	.get_min_clock = esdhc_pltfm_get_min_clock,
 	.get_ro = esdhc_pltfm_get_ro,
 	.platform_bus_width = esdhc_pltfm_bus_width,
@@ -482,6 +504,8 @@ sdhci_esdhc_imx_probe_dt(struct platform
 
 	of_property_read_u32(np, "bus-width", &boarddata->max_bus_width);
 
+	of_property_read_u32(np, "max-frequency", &boarddata->f_max);
+
 	return 0;
 }
 #else
@@ -503,7 +527,7 @@ static int sdhci_esdhc_imx_probe(struct
 	int err;
 	struct pltfm_imx_data *imx_data;
 
-	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata);
+	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci.h linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci.h
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci.h	2013-08-25 20:43:22.000000000 -0400
@@ -294,6 +294,7 @@ struct sdhci_ops {
 	void	(*platform_resume)(struct sdhci_host *host);
 	void    (*adma_workaround)(struct sdhci_host *host, u32 intmask);
 	void	(*platform_init)(struct sdhci_host *host);
+	void    (*card_event)(struct sdhci_host *host);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-of-esdhc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-of-esdhc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-of-esdhc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-of-esdhc.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
  * your option) any later version.
  */
 
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/delay.h>
@@ -120,6 +121,13 @@ static void esdhc_writeb(struct sdhci_ho
 	if (reg == SDHCI_HOST_CONTROL) {
 		u32 dma_bits;
 
+		/*
+		 * If host control register is not standard, exit
+		 * this function
+		 */
+		if (host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL)
+			return;
+
 		/* DMA select is 22,23 bits in Protocol Control Register */
 		dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5;
 		clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5,
@@ -200,7 +208,7 @@ static void esdhc_of_set_clock(struct sd
 	}
 
 	/* Set the clock */
-	esdhc_set_clock(host, clock);
+	esdhc_set_clock(host, clock, host->max_clk);
 }
 
 #ifdef CONFIG_PM
@@ -230,6 +238,30 @@ static void esdhc_of_platform_init(struc
 		host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
 }
 
+static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
+{
+	u32 ctrl;
+
+	switch (width) {
+	case MMC_BUS_WIDTH_8:
+		ctrl = ESDHC_CTRL_8BITBUS;
+		break;
+
+	case MMC_BUS_WIDTH_4:
+		ctrl = ESDHC_CTRL_4BITBUS;
+		break;
+
+	default:
+		ctrl = 0;
+		break;
+	}
+
+	clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL,
+			ESDHC_CTRL_BUSWIDTH_MASK, ctrl);
+
+	return 0;
+}
+
 static const struct sdhci_ops sdhci_esdhc_ops = {
 	.read_l = esdhc_readl,
 	.read_w = esdhc_readw,
@@ -247,6 +279,7 @@ static const struct sdhci_ops sdhci_esdh
 	.platform_resume = esdhc_of_resume,
 #endif
 	.adma_workaround = esdhci_of_adma_workaround,
+	.platform_bus_width = esdhc_pltfm_bus_width,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
@@ -262,7 +295,33 @@ static const struct sdhci_pltfm_data sdh
 
 static int sdhci_esdhc_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_esdhc_pdata);
+	struct sdhci_host *host;
+	struct device_node *np;
+	int ret;
+
+	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0);
+	if (IS_ERR(host))
+		return PTR_ERR(host);
+
+	sdhci_get_of_property(pdev);
+
+	np = pdev->dev.of_node;
+	if (of_device_is_compatible(np, "fsl,p2020-esdhc")) {
+		/*
+		 * Freescale messed up with P2020 as it has a non-standard
+		 * host control register
+		 */
+		host->quirks2 |= SDHCI_QUIRK2_BROKEN_HOST_CONTROL;
+	}
+
+	/* call to generic mmc_of_parse to support additional capabilities */
+	mmc_of_parse(host->mmc);
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		sdhci_pltfm_free(pdev);
+
+	return ret;
 }
 
 static int sdhci_esdhc_remove(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-of-hlwd.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-of-hlwd.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-of-hlwd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-of-hlwd.c	2013-08-25 20:43:22.000000000 -0400
@@ -68,7 +68,7 @@ static const struct sdhci_pltfm_data sdh
 
 static int sdhci_hlwd_probe(struct platform_device *pdev)
 {
-	return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata);
+	return sdhci_pltfm_register(pdev, &sdhci_hlwd_pdata, 0);
 }
 
 static int sdhci_hlwd_remove(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pci.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pci.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,7 @@
 #define PCI_DEVICE_ID_INTEL_BYT_EMMC	0x0f14
 #define PCI_DEVICE_ID_INTEL_BYT_SDIO	0x0f15
 #define PCI_DEVICE_ID_INTEL_BYT_SD	0x0f16
+#define PCI_DEVICE_ID_INTEL_BYT_EMMC2	0x0f50
 
 /*
  * PCI registers
@@ -77,6 +78,8 @@ struct sdhci_pci_slot {
 	int			rst_n_gpio;
 	int			cd_gpio;
 	int			cd_irq;
+
+	void (*hw_reset)(struct sdhci_host *host);
 };
 
 struct sdhci_pci_chip {
@@ -307,10 +310,27 @@ static const struct sdhci_pci_fixes sdhc
 	.probe_slot	= pch_hc_probe_slot,
 };
 
+static void sdhci_pci_int_hw_reset(struct sdhci_host *host)
+{
+	u8 reg;
+
+	reg = sdhci_readb(host, SDHCI_POWER_CONTROL);
+	reg |= 0x10;
+	sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
+	/* For eMMC, minimum is 1us but give it 9us for good measure */
+	udelay(9);
+	reg &= ~0x10;
+	sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
+	/* For eMMC, minimum is 200us but give it 300us for good measure */
+	usleep_range(300, 1000);
+}
+
 static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
 {
-	slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
+	slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
+				 MMC_CAP_HW_RESET;
 	slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
+	slot->hw_reset = sdhci_pci_int_hw_reset;
 	return 0;
 }
 
@@ -332,6 +352,8 @@ static const struct sdhci_pci_fixes sdhc
 };
 
 static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
+	.quirks2	= SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON,
+	.allow_runtime_pm = true,
 };
 
 /* O2Micro extra registers */
@@ -910,6 +932,14 @@ static const struct pci_device_id pci_id
 	},
 
 	{
+		.vendor		= PCI_VENDOR_ID_INTEL,
+		.device		= PCI_DEVICE_ID_INTEL_BYT_EMMC2,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (kernel_ulong_t)&sdhci_intel_byt_emmc,
+	},
+
+	{
 		.vendor		= PCI_VENDOR_ID_O2,
 		.device		= PCI_DEVICE_ID_O2_8120,
 		.subvendor	= PCI_ANY_ID,
@@ -1014,7 +1044,7 @@ static int sdhci_pci_bus_width(struct sd
 	return 0;
 }
 
-static void sdhci_pci_hw_reset(struct sdhci_host *host)
+static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host)
 {
 	struct sdhci_pci_slot *slot = sdhci_priv(host);
 	int rst_n_gpio = slot->rst_n_gpio;
@@ -1029,6 +1059,14 @@ static void sdhci_pci_hw_reset(struct sd
 	usleep_range(300, 1000);
 }
 
+static void sdhci_pci_hw_reset(struct sdhci_host *host)
+{
+	struct sdhci_pci_slot *slot = sdhci_priv(host);
+
+	if (slot->hw_reset)
+		slot->hw_reset(host);
+}
+
 static const struct sdhci_ops sdhci_pci_ops = {
 	.enable_dma	= sdhci_pci_enable_dma,
 	.platform_bus_width	= sdhci_pci_bus_width,
@@ -1326,6 +1364,7 @@ static struct sdhci_pci_slot *sdhci_pci_
 		if (!gpio_request(slot->rst_n_gpio, "eMMC_reset")) {
 			gpio_direction_output(slot->rst_n_gpio, 1);
 			slot->host->mmc->caps |= MMC_CAP_HW_RESET;
+			slot->hw_reset = sdhci_pci_gpio_hw_reset;
 		} else {
 			dev_warn(&pdev->dev, "failed to request rst_n_gpio\n");
 			slot->rst_n_gpio = -EINVAL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pltfm.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pltfm.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pltfm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pltfm.c	2013-08-25 20:43:22.000000000 -0400
@@ -115,10 +115,10 @@ void sdhci_get_of_property(struct platfo
 EXPORT_SYMBOL_GPL(sdhci_get_of_property);
 
 struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
-				    const struct sdhci_pltfm_data *pdata)
+				    const struct sdhci_pltfm_data *pdata,
+				    size_t priv_size)
 {
 	struct sdhci_host *host;
-	struct sdhci_pltfm_host *pltfm_host;
 	struct device_node *np = pdev->dev.of_node;
 	struct resource *iomem;
 	int ret;
@@ -134,24 +134,27 @@ struct sdhci_host *sdhci_pltfm_init(stru
 
 	/* Some PCI-based MFD need the parent here */
 	if (pdev->dev.parent != &platform_bus && !np)
-		host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host));
+		host = sdhci_alloc_host(pdev->dev.parent,
+			sizeof(struct sdhci_pltfm_host) + priv_size);
 	else
-		host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host));
+		host = sdhci_alloc_host(&pdev->dev,
+			sizeof(struct sdhci_pltfm_host) + priv_size);
 
 	if (IS_ERR(host)) {
 		ret = PTR_ERR(host);
 		goto err;
 	}
 
-	pltfm_host = sdhci_priv(host);
-
 	host->hw_name = dev_name(&pdev->dev);
 	if (pdata && pdata->ops)
 		host->ops = pdata->ops;
 	else
 		host->ops = &sdhci_pltfm_ops;
-	if (pdata)
+	if (pdata) {
 		host->quirks = pdata->quirks;
+		host->quirks2 = pdata->quirks2;
+	}
+
 	host->irq = platform_get_irq(pdev, 0);
 
 	if (!request_mem_region(iomem->start, resource_size(iomem),
@@ -197,17 +200,17 @@ void sdhci_pltfm_free(struct platform_de
 	iounmap(host->ioaddr);
 	release_mem_region(iomem->start, resource_size(iomem));
 	sdhci_free_host(host);
-	platform_set_drvdata(pdev, NULL);
 }
 EXPORT_SYMBOL_GPL(sdhci_pltfm_free);
 
 int sdhci_pltfm_register(struct platform_device *pdev,
-			 const struct sdhci_pltfm_data *pdata)
+			const struct sdhci_pltfm_data *pdata,
+			size_t priv_size)
 {
 	struct sdhci_host *host;
 	int ret = 0;
 
-	host = sdhci_pltfm_init(pdev, pdata);
+	host = sdhci_pltfm_init(pdev, pdata, priv_size);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pltfm.h linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pltfm.h
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pltfm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pltfm.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
 struct sdhci_pltfm_data {
 	const struct sdhci_ops *ops;
 	unsigned int quirks;
+	unsigned int quirks2;
 };
 
 struct sdhci_pltfm_host {
@@ -27,6 +28,8 @@ struct sdhci_pltfm_host {
 	/* migrate from sdhci_of_host */
 	unsigned int clock;
 	u16 xfer_mode_shadow;
+
+	unsigned long private[0] ____cacheline_aligned;
 };
 
 #ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
@@ -91,15 +94,22 @@ static inline void sdhci_be32bs_writeb(s
 extern void sdhci_get_of_property(struct platform_device *pdev);
 
 extern struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
-					  const struct sdhci_pltfm_data *pdata);
+					  const struct sdhci_pltfm_data *pdata,
+					  size_t priv_size);
 extern void sdhci_pltfm_free(struct platform_device *pdev);
 
 extern int sdhci_pltfm_register(struct platform_device *pdev,
-				const struct sdhci_pltfm_data *pdata);
+				const struct sdhci_pltfm_data *pdata,
+				size_t priv_size);
 extern int sdhci_pltfm_unregister(struct platform_device *pdev);
 
 extern unsigned int sdhci_pltfm_clk_get_max_clock(struct sdhci_host *host);
 
+static inline void *sdhci_pltfm_priv(struct sdhci_pltfm_host *host)
+{
+	return (void *)host->private;
+}
+
 #ifdef CONFIG_PM
 extern const struct dev_pm_ops sdhci_pltfm_pmops;
 #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pxav2.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pxav2.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pxav2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pxav2.c	2013-08-25 20:43:22.000000000 -0400
@@ -175,7 +175,7 @@ static int sdhci_pxav2_probe(struct plat
 	if (!pxa)
 		return -ENOMEM;
 
-	host = sdhci_pltfm_init(pdev, NULL);
+	host = sdhci_pltfm_init(pdev, NULL, 0);
 	if (IS_ERR(host)) {
 		kfree(pxa);
 		return PTR_ERR(host);
@@ -253,8 +253,6 @@ static int sdhci_pxav2_remove(struct pla
 	sdhci_pltfm_free(pdev);
 	kfree(pxa);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pxav3.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pxav3.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-pxav3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-pxav3.c	2013-08-25 20:43:22.000000000 -0400
@@ -230,7 +230,7 @@ static int sdhci_pxav3_probe(struct plat
 	if (!pxa)
 		return -ENOMEM;
 
-	host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata);
+	host = sdhci_pltfm_init(pdev, &sdhci_pxav3_pdata, 0);
 	if (IS_ERR(host)) {
 		kfree(pxa);
 		return PTR_ERR(host);
@@ -252,7 +252,9 @@ static int sdhci_pxav3_probe(struct plat
 
 	match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev);
 	if (match) {
-		mmc_of_parse(host->mmc);
+		ret = mmc_of_parse(host->mmc);
+		if (ret)
+			goto err_of_parse;
 		sdhci_get_of_property(pdev);
 		pdata = pxav3_get_mmc_pdata(dev);
 	} else if (pdata) {
@@ -285,18 +287,15 @@ static int sdhci_pxav3_probe(struct plat
 		}
 	}
 
-	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS);
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_suspend_ignore_children(&pdev->dev, 1);
-	pm_runtime_get_noresume(&pdev->dev);
 
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to add host\n");
-		pm_runtime_forbid(&pdev->dev);
-		pm_runtime_disable(&pdev->dev);
 		goto err_add_host;
 	}
 
@@ -313,10 +312,13 @@ static int sdhci_pxav3_probe(struct plat
 
 	return 0;
 
+err_of_parse:
+err_cd_req:
 err_add_host:
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	clk_disable_unprepare(clk);
 	clk_put(clk);
-err_cd_req:
 err_clk_get:
 	sdhci_pltfm_free(pdev);
 	kfree(pxa);
@@ -339,8 +341,6 @@ static int sdhci_pxav3_remove(struct pla
 	sdhci_pltfm_free(pdev);
 	kfree(pxa);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-s3c.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-s3c.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-s3c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-s3c.c	2013-08-25 20:43:22.000000000 -0400
@@ -745,7 +745,6 @@ static int sdhci_s3c_remove(struct platf
 	clk_disable_unprepare(sc->clk_io);
 
 	sdhci_free_host(host);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-sirf.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-sirf.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-sirf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-sirf.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/mmc/slot-gpio.h>
-#include <linux/pinctrl/consumer.h>
 #include "sdhci-pltfm.h"
 
 struct sdhci_sirf_priv {
@@ -24,7 +23,7 @@ struct sdhci_sirf_priv {
 static unsigned int sdhci_sirf_get_max_clk(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-	struct sdhci_sirf_priv *priv = pltfm_host->priv;
+	struct sdhci_sirf_priv *priv = sdhci_pltfm_priv(pltfm_host);
 	return clk_get_rate(priv->clk);
 }
 
@@ -46,47 +45,35 @@ static int sdhci_sirf_probe(struct platf
 	struct sdhci_host *host;
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_sirf_priv *priv;
-	struct pinctrl *pinctrl;
+	struct clk *clk;
+	int gpio_cd;
 	int ret;
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl)) {
-		dev_err(&pdev->dev, "unable to get pinmux");
-		return PTR_ERR(pinctrl);
-	}
-
-	priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_sirf_priv),
-		GFP_KERNEL);
-	if (!priv) {
-		dev_err(&pdev->dev, "unable to allocate private data");
-		return -ENOMEM;
-	}
-
-	priv->clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(priv->clk)) {
+	clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(clk)) {
 		dev_err(&pdev->dev, "unable to get clock");
-		return PTR_ERR(priv->clk);
+		return PTR_ERR(clk);
 	}
 
-	if (pdev->dev.of_node) {
-		priv->gpio_cd = of_get_named_gpio(pdev->dev.of_node,
-			"cd-gpios", 0);
-	} else {
-		priv->gpio_cd = -EINVAL;
-	}
+	if (pdev->dev.of_node)
+		gpio_cd = of_get_named_gpio(pdev->dev.of_node, "cd-gpios", 0);
+	else
+		gpio_cd = -EINVAL;
 
-	host = sdhci_pltfm_init(pdev, &sdhci_sirf_pdata);
-	if (IS_ERR(host)) {
-		ret = PTR_ERR(host);
-		goto err_sdhci_pltfm_init;
-	}
+	host = sdhci_pltfm_init(pdev, &sdhci_sirf_pdata, sizeof(struct sdhci_sirf_priv));
+	if (IS_ERR(host))
+		return PTR_ERR(host);
 
 	pltfm_host = sdhci_priv(host);
-	pltfm_host->priv = priv;
+	priv = sdhci_pltfm_priv(pltfm_host);
+	priv->clk = clk;
+	priv->gpio_cd = gpio_cd;
 
 	sdhci_get_of_property(pdev);
 
-	clk_prepare_enable(priv->clk);
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		goto err_clk_prepare;
 
 	ret = sdhci_add_host(host);
 	if (ret)
@@ -111,8 +98,8 @@ err_request_cd:
 	sdhci_remove_host(host, 0);
 err_sdhci_add:
 	clk_disable_unprepare(priv->clk);
+err_clk_prepare:
 	sdhci_pltfm_free(pdev);
-err_sdhci_pltfm_init:
 	return ret;
 }
 
@@ -120,7 +107,7 @@ static int sdhci_sirf_remove(struct plat
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-	struct sdhci_sirf_priv *priv = pltfm_host->priv;
+	struct sdhci_sirf_priv *priv = sdhci_pltfm_priv(pltfm_host);
 
 	sdhci_pltfm_unregister(pdev);
 
@@ -136,7 +123,7 @@ static int sdhci_sirf_suspend(struct dev
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-	struct sdhci_sirf_priv *priv = pltfm_host->priv;
+	struct sdhci_sirf_priv *priv = sdhci_pltfm_priv(pltfm_host);
 	int ret;
 
 	ret = sdhci_suspend_host(host);
@@ -152,7 +139,7 @@ static int sdhci_sirf_resume(struct devi
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-	struct sdhci_sirf_priv *priv = pltfm_host->priv;
+	struct sdhci_sirf_priv *priv = sdhci_pltfm_priv(pltfm_host);
 	int ret;
 
 	ret = clk_enable(priv->clk);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-spear.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-spear.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-spear.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-spear.c	2013-08-25 20:43:22.000000000 -0400
@@ -258,7 +258,6 @@ static int sdhci_probe(struct platform_d
 	return 0;
 
 set_drvdata:
-	platform_set_drvdata(pdev, NULL);
 	sdhci_remove_host(host, 1);
 free_host:
 	sdhci_free_host(host);
@@ -278,7 +277,6 @@ static int sdhci_remove(struct platform_
 	int dead = 0;
 	u32 scratch;
 
-	platform_set_drvdata(pdev, NULL);
 	scratch = readl(host->ioaddr + SDHCI_INT_STATUS);
 	if (scratch == (u32)-1)
 		dead = 1;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sdhci-tegra.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-tegra.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sdhci-tegra.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sdhci-tegra.c	2013-08-25 20:43:22.000000000 -0400
@@ -205,7 +205,7 @@ static const struct of_device_id sdhci_t
 };
 MODULE_DEVICE_TABLE(of, sdhci_tegra_dt_match);
 
-static void sdhci_tegra_parse_dt(struct device *dev)
+static int sdhci_tegra_parse_dt(struct device *dev)
 {
 	struct device_node *np = dev->of_node;
 	struct sdhci_host *host = dev_get_drvdata(dev);
@@ -213,7 +213,7 @@ static void sdhci_tegra_parse_dt(struct
 	struct sdhci_tegra *tegra_host = pltfm_host->priv;
 
 	tegra_host->power_gpio = of_get_named_gpio(np, "power-gpios", 0);
-	mmc_of_parse(host->mmc);
+	return mmc_of_parse(host->mmc);
 }
 
 static int sdhci_tegra_probe(struct platform_device *pdev)
@@ -231,7 +231,7 @@ static int sdhci_tegra_probe(struct plat
 		return -EINVAL;
 	soc_data = match->data;
 
-	host = sdhci_pltfm_init(pdev, soc_data->pdata);
+	host = sdhci_pltfm_init(pdev, soc_data->pdata, 0);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 	pltfm_host = sdhci_priv(host);
@@ -245,7 +245,9 @@ static int sdhci_tegra_probe(struct plat
 	tegra_host->soc_data = soc_data;
 	pltfm_host->priv = tegra_host;
 
-	sdhci_tegra_parse_dt(&pdev->dev);
+	rc = sdhci_tegra_parse_dt(&pdev->dev);
+	if (rc)
+		goto err_parse_dt;
 
 	if (gpio_is_valid(tegra_host->power_gpio)) {
 		rc = gpio_request(tegra_host->power_gpio, "sdhci_power");
@@ -279,6 +281,7 @@ err_clk_get:
 	if (gpio_is_valid(tegra_host->power_gpio))
 		gpio_free(tegra_host->power_gpio);
 err_power_req:
+err_parse_dt:
 err_alloc_tegra_host:
 	sdhci_pltfm_free(pdev);
 	return rc;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sh_mmcif.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sh_mmcif.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sh_mmcif.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sh_mmcif.c	2013-08-25 20:43:22.000000000 -0400
@@ -1244,7 +1244,8 @@ static irqreturn_t sh_mmcif_intr(int irq
 	u32 state;
 
 	state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
-	sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
+	sh_mmcif_writel(host->addr, MMCIF_CE_INT,
+			~(state & sh_mmcif_readl(host->addr, MMCIF_CE_INT_MASK)));
 	sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state & MASK_CLEAN);
 
 	if (state & ~MASK_CLEAN)
@@ -1369,7 +1370,11 @@ static int sh_mmcif_probe(struct platfor
 		ret = -ENOMEM;
 		goto ealloch;
 	}
-	mmc_of_parse(mmc);
+
+	ret = mmc_of_parse(mmc);
+	if (ret < 0)
+		goto eofparse;
+
 	host		= mmc_priv(mmc);
 	host->mmc	= mmc;
 	host->addr	= reg;
@@ -1464,6 +1469,7 @@ eclkupdate:
 	clk_put(host->hclk);
 eclkget:
 	pm_runtime_disable(&pdev->dev);
+eofparse:
 	mmc_free_host(mmc);
 ealloch:
 	iounmap(reg);
@@ -1501,8 +1507,6 @@ static int sh_mmcif_remove(struct platfo
 	if (irq[1] >= 0)
 		free_irq(irq[1], host);
 
-	platform_set_drvdata(pdev, NULL);
-
 	clk_disable(host->hclk);
 	mmc_free_host(host->mmc);
 	pm_runtime_put_sync(&pdev->dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/sh_mobile_sdhi.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/sh_mobile_sdhi.c
--- linux-libre-3.10-gnu/drivers/mmc/host/sh_mobile_sdhi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/sh_mobile_sdhi.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,14 +46,12 @@ static const struct sh_mobile_sdhi_of_da
 struct sh_mobile_sdhi {
 	struct clk *clk;
 	struct tmio_mmc_data mmc_data;
-	struct sh_dmae_slave param_tx;
-	struct sh_dmae_slave param_rx;
 	struct tmio_mmc_dma dma_priv;
 };
 
 static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int *f)
 {
-	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
 	int ret = clk_enable(priv->clk);
@@ -66,7 +64,7 @@ static int sh_mobile_sdhi_clk_enable(str
 
 static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev)
 {
-	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
 	clk_disable(priv->clk);
@@ -121,7 +119,7 @@ static int sh_mobile_sdhi_write16_hook(s
 
 static void sh_mobile_sdhi_cd_wakeup(const struct platform_device *pdev)
 {
-	mmc_detect_change(dev_get_drvdata(&pdev->dev), msecs_to_jiffies(100));
+	mmc_detect_change(platform_get_drvdata(pdev), msecs_to_jiffies(100));
 }
 
 static const struct sh_mobile_sdhi_ops sdhi_ops = {
@@ -146,6 +144,7 @@ static int sh_mobile_sdhi_probe(struct p
 	struct tmio_mmc_host *host;
 	int irq, ret, i = 0;
 	bool multiplexed_isr = true;
+	struct tmio_mmc_dma *dma_priv;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
 	if (priv == NULL) {
@@ -154,6 +153,7 @@ static int sh_mobile_sdhi_probe(struct p
 	}
 
 	mmc_data = &priv->mmc_data;
+	dma_priv = &priv->dma_priv;
 
 	if (p) {
 		if (p->init) {
@@ -186,15 +186,23 @@ static int sh_mobile_sdhi_probe(struct p
 			mmc_data->get_cd = sh_mobile_sdhi_get_cd;
 
 		if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
-			priv->param_tx.shdma_slave.slave_id = p->dma_slave_tx;
-			priv->param_rx.shdma_slave.slave_id = p->dma_slave_rx;
-			priv->dma_priv.chan_priv_tx = &priv->param_tx.shdma_slave;
-			priv->dma_priv.chan_priv_rx = &priv->param_rx.shdma_slave;
-			priv->dma_priv.alignment_shift = 1; /* 2-byte alignment */
-			mmc_data->dma = &priv->dma_priv;
+			/*
+			 * Yes, we have to provide slave IDs twice to TMIO:
+			 * once as a filter parameter and once for channel
+			 * configuration as an explicit slave ID
+			 */
+			dma_priv->chan_priv_tx = (void *)p->dma_slave_tx;
+			dma_priv->chan_priv_rx = (void *)p->dma_slave_rx;
+			dma_priv->slave_id_tx = p->dma_slave_tx;
+			dma_priv->slave_id_rx = p->dma_slave_rx;
 		}
 	}
 
+	dma_priv->alignment_shift = 1; /* 2-byte alignment */
+	dma_priv->filter = shdma_chan_filter;
+
+	mmc_data->dma = dma_priv;
+
 	/*
 	 * All SDHI blocks support 2-byte and larger block sizes in 4-bit
 	 * bus width mode.
@@ -265,8 +273,10 @@ static int sh_mobile_sdhi_probe(struct p
 		}
 
 		/* There must be at least one IRQ source */
-		if (!i)
+		if (!i) {
+			ret = irq;
 			goto eirq;
+		}
 	}
 
 	dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/tmio_mmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/tmio_mmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/tmio_mmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/tmio_mmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -112,8 +112,6 @@ static int tmio_mmc_remove(struct platfo
 	const struct mfd_cell *cell = mfd_get_cell(pdev);
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	if (mmc) {
 		struct tmio_mmc_host *host = mmc_priv(mmc);
 		free_irq(platform_get_irq(pdev, 0), host);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/tmio_mmc_dma.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/tmio_mmc_dma.c
--- linux-libre-3.10-gnu/drivers/mmc/host/tmio_mmc_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/tmio_mmc_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -261,42 +261,62 @@ out:
 	spin_unlock_irq(&host->lock);
 }
 
-/* It might be necessary to make filter MFD specific */
-static bool tmio_mmc_filter(struct dma_chan *chan, void *arg)
-{
-	dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg);
-	chan->private = arg;
-	return true;
-}
-
 void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata)
 {
 	/* We can only either use DMA for both Tx and Rx or not use it at all */
-	if (!pdata->dma)
+	if (!pdata->dma || (!host->pdev->dev.of_node &&
+		(!pdata->dma->chan_priv_tx || !pdata->dma->chan_priv_rx)))
 		return;
 
 	if (!host->chan_tx && !host->chan_rx) {
+		struct resource *res = platform_get_resource(host->pdev,
+							     IORESOURCE_MEM, 0);
+		struct dma_slave_config cfg = {};
 		dma_cap_mask_t mask;
+		int ret;
+
+		if (!res)
+			return;
 
 		dma_cap_zero(mask);
 		dma_cap_set(DMA_SLAVE, mask);
 
-		host->chan_tx = dma_request_channel(mask, tmio_mmc_filter,
-						    pdata->dma->chan_priv_tx);
+		host->chan_tx = dma_request_slave_channel_compat(mask,
+					pdata->dma->filter, pdata->dma->chan_priv_tx,
+					&host->pdev->dev, "tx");
 		dev_dbg(&host->pdev->dev, "%s: TX: got channel %p\n", __func__,
 			host->chan_tx);
 
 		if (!host->chan_tx)
 			return;
 
-		host->chan_rx = dma_request_channel(mask, tmio_mmc_filter,
-						    pdata->dma->chan_priv_rx);
+		if (pdata->dma->chan_priv_tx)
+			cfg.slave_id = pdata->dma->slave_id_tx;
+		cfg.direction = DMA_MEM_TO_DEV;
+		cfg.dst_addr = res->start + (CTL_SD_DATA_PORT << host->bus_shift);
+		cfg.src_addr = 0;
+		ret = dmaengine_slave_config(host->chan_tx, &cfg);
+		if (ret < 0)
+			goto ecfgtx;
+
+		host->chan_rx = dma_request_slave_channel_compat(mask,
+					pdata->dma->filter, pdata->dma->chan_priv_rx,
+					&host->pdev->dev, "rx");
 		dev_dbg(&host->pdev->dev, "%s: RX: got channel %p\n", __func__,
 			host->chan_rx);
 
 		if (!host->chan_rx)
 			goto ereqrx;
 
+		if (pdata->dma->chan_priv_rx)
+			cfg.slave_id = pdata->dma->slave_id_rx;
+		cfg.direction = DMA_DEV_TO_MEM;
+		cfg.src_addr = cfg.dst_addr;
+		cfg.dst_addr = 0;
+		ret = dmaengine_slave_config(host->chan_rx, &cfg);
+		if (ret < 0)
+			goto ecfgrx;
+
 		host->bounce_buf = (u8 *)__get_free_page(GFP_KERNEL | GFP_DMA);
 		if (!host->bounce_buf)
 			goto ebouncebuf;
@@ -310,9 +330,11 @@ void tmio_mmc_request_dma(struct tmio_mm
 	return;
 
 ebouncebuf:
+ecfgrx:
 	dma_release_channel(host->chan_rx);
 	host->chan_rx = NULL;
 ereqrx:
+ecfgtx:
 	dma_release_channel(host->chan_tx);
 	host->chan_tx = NULL;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/tmio_mmc.h linux-libre-3.11-rc7-gnu/drivers/mmc/host/tmio_mmc.h
--- linux-libre-3.10-gnu/drivers/mmc/host/tmio_mmc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/tmio_mmc.h	2013-08-25 20:43:22.000000000 -0400
@@ -40,6 +40,22 @@
 
 struct tmio_mmc_data;
 
+/*
+ * We differentiate between the following 3 power states:
+ * 1. card slot powered off, controller stopped. This is used, when either there
+ *    is no card in the slot, or the card really has to be powered down.
+ * 2. card slot powered on, controller stopped. This is used, when a card is in
+ *    the slot, but no activity is currently taking place. This is a power-
+ *    saving mode with card-state preserved. This state can be entered, e.g.
+ *    when MMC clock-gating is used.
+ * 3. card slot powered on, controller running. This is the actual active state.
+ */
+enum tmio_mmc_power {
+	TMIO_MMC_OFF_STOP,	/* card power off, controller stopped */
+	TMIO_MMC_ON_STOP,	/* card power on, controller stopped */
+	TMIO_MMC_ON_RUN,	/* card power on, controller running */
+};
+
 struct tmio_mmc_host {
 	void __iomem *ctl;
 	unsigned long bus_shift;
@@ -48,8 +64,8 @@ struct tmio_mmc_host {
 	struct mmc_data         *data;
 	struct mmc_host         *mmc;
 
-	/* Controller power state */
-	bool			power;
+	/* Controller and card power state */
+	enum tmio_mmc_power	power;
 
 	/* Callbacks for clock / power control */
 	void (*set_pwr)(struct platform_device *host, int state);
@@ -85,6 +101,7 @@ struct tmio_mmc_host {
 	unsigned long		last_req_ts;
 	struct mutex		ios_lock;	/* protect set_ios() context */
 	bool			native_hotplug;
+	bool			resuming;
 };
 
 int tmio_mmc_host_probe(struct tmio_mmc_host **host,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/tmio_mmc_pio.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/tmio_mmc_pio.c
--- linux-libre-3.10-gnu/drivers/mmc/host/tmio_mmc_pio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/tmio_mmc_pio.c	2013-08-25 20:43:22.000000000 -0400
@@ -859,32 +859,45 @@ static void tmio_mmc_set_ios(struct mmc_
 	 * is kept positive, so no suspending actually takes place.
 	 */
 	if (ios->power_mode == MMC_POWER_ON && ios->clock) {
-		if (!host->power) {
+		if (host->power != TMIO_MMC_ON_RUN) {
 			tmio_mmc_clk_update(mmc);
 			pm_runtime_get_sync(dev);
+			if (host->resuming) {
+				tmio_mmc_reset(host);
+				host->resuming = false;
+			}
 		}
+		if (host->power == TMIO_MMC_OFF_STOP)
+			tmio_mmc_reset(host);
 		tmio_mmc_set_clock(host, ios->clock);
-		if (!host->power) {
+		if (host->power == TMIO_MMC_OFF_STOP)
 			/* power up SD card and the bus */
 			tmio_mmc_power_on(host, ios->vdd);
-			host->power = true;
-		}
+		host->power = TMIO_MMC_ON_RUN;
 		/* start bus clock */
 		tmio_mmc_clk_start(host);
 	} else if (ios->power_mode != MMC_POWER_UP) {
-		if (host->power) {
-			struct tmio_mmc_data *pdata = host->pdata;
-			if (ios->power_mode == MMC_POWER_OFF)
+		struct tmio_mmc_data *pdata = host->pdata;
+		unsigned int old_power = host->power;
+
+		if (old_power != TMIO_MMC_OFF_STOP) {
+			if (ios->power_mode == MMC_POWER_OFF) {
 				tmio_mmc_power_off(host);
+				host->power = TMIO_MMC_OFF_STOP;
+			} else {
+				host->power = TMIO_MMC_ON_STOP;
+			}
+		}
+
+		if (old_power == TMIO_MMC_ON_RUN) {
 			tmio_mmc_clk_stop(host);
-			host->power = false;
 			pm_runtime_put(dev);
 			if (pdata->clk_disable)
 				pdata->clk_disable(host->pdev);
 		}
 	}
 
-	if (host->power) {
+	if (host->power != TMIO_MMC_OFF_STOP) {
 		switch (ios->bus_width) {
 		case MMC_BUS_WIDTH_1:
 			sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
@@ -988,7 +1001,9 @@ int tmio_mmc_host_probe(struct tmio_mmc_
 	if (!mmc)
 		return -ENOMEM;
 
-	mmc_of_parse(mmc);
+	ret = mmc_of_parse(mmc);
+	if (ret < 0)
+		goto host_free;
 
 	pdata->dev = &pdev->dev;
 	_host = mmc_priv(mmc);
@@ -1025,7 +1040,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_
 				  mmc->caps & MMC_CAP_NONREMOVABLE ||
 				  mmc->slot.cd_irq >= 0);
 
-	_host->power = false;
+	_host->power = TMIO_MMC_OFF_STOP;
 	pm_runtime_enable(&pdev->dev);
 	ret = pm_runtime_resume(&pdev->dev);
 	if (ret < 0)
@@ -1154,10 +1169,10 @@ int tmio_mmc_host_resume(struct device *
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 
-	tmio_mmc_reset(host);
 	tmio_mmc_enable_dma(host, true);
 
 	/* The MMC core will perform the complete set up */
+	host->resuming = true;
 	return mmc_resume_host(mmc);
 }
 EXPORT_SYMBOL(tmio_mmc_host_resume);
@@ -1175,7 +1190,6 @@ int tmio_mmc_host_runtime_resume(struct
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 
-	tmio_mmc_reset(host);
 	tmio_mmc_enable_dma(host, true);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mmc/host/wmt-sdmmc.c linux-libre-3.11-rc7-gnu/drivers/mmc/host/wmt-sdmmc.c
--- linux-libre-3.10-gnu/drivers/mmc/host/wmt-sdmmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mmc/host/wmt-sdmmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -927,8 +927,6 @@ static int wmt_mci_remove(struct platfor
 
 	mmc_free_host(mmc);
 
-	platform_set_drvdata(pdev, NULL);
-
 	dev_info(&pdev->dev, "WMT MCI device removed\n");
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mtd/maps/autcpu12-nvram.c linux-libre-3.11-rc7-gnu/drivers/mtd/maps/autcpu12-nvram.c
--- linux-libre-3.10-gnu/drivers/mtd/maps/autcpu12-nvram.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mtd/maps/autcpu12-nvram.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,129 +0,0 @@
-/*
- * NV-RAM memory access on autcpu12
- * (C) 2002 Thomas Gleixner (gleixner@autronix.de)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/err.h>
-#include <linux/sizes.h>
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-
-struct autcpu12_nvram_priv {
-	struct mtd_info *mtd;
-	struct map_info map;
-};
-
-static int autcpu12_nvram_probe(struct platform_device *pdev)
-{
-	map_word tmp, save0, save1;
-	struct resource *res;
-	struct autcpu12_nvram_priv *priv;
-
-	priv = devm_kzalloc(&pdev->dev,
-			    sizeof(struct autcpu12_nvram_priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	platform_set_drvdata(pdev, priv);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "failed to get memory resource\n");
-		return -ENOENT;
-	}
-
-	priv->map.bankwidth	= 4;
-	priv->map.phys		= res->start;
-	priv->map.size		= resource_size(res);
-	priv->map.virt = devm_ioremap_resource(&pdev->dev, res);
-	strcpy((char *)priv->map.name, res->name);
-	if (IS_ERR(priv->map.virt))
-		return PTR_ERR(priv->map.virt);
-
-	simple_map_init(&priv->map);
-
-	/*
-	 * Check for 32K/128K
-	 * read ofs 0
-	 * read ofs 0x10000
-	 * Write complement to ofs 0x100000
-	 * Read	and check result on ofs 0x0
-	 * Restore contents
-	 */
-	save0 = map_read(&priv->map, 0);
-	save1 = map_read(&priv->map, 0x10000);
-	tmp.x[0] = ~save0.x[0];
-	map_write(&priv->map, tmp, 0x10000);
-	tmp = map_read(&priv->map, 0);
-	/* if we find this pattern on 0x0, we have 32K size */
-	if (!map_word_equal(&priv->map, tmp, save0)) {
-		map_write(&priv->map, save0, 0x0);
-		priv->map.size = SZ_32K;
-	} else
-		map_write(&priv->map, save1, 0x10000);
-
-	priv->mtd = do_map_probe("map_ram", &priv->map);
-	if (!priv->mtd) {
-		dev_err(&pdev->dev, "probing failed\n");
-		return -ENXIO;
-	}
-
-	priv->mtd->owner	= THIS_MODULE;
-	priv->mtd->erasesize	= 16;
-	priv->mtd->dev.parent	= &pdev->dev;
-	if (!mtd_device_register(priv->mtd, NULL, 0)) {
-		dev_info(&pdev->dev,
-			 "NV-RAM device size %ldKiB registered on AUTCPU12\n",
-			 priv->map.size / SZ_1K);
-		return 0;
-	}
-
-	map_destroy(priv->mtd);
-	dev_err(&pdev->dev, "NV-RAM device addition failed\n");
-	return -ENOMEM;
-}
-
-static int autcpu12_nvram_remove(struct platform_device *pdev)
-{
-	struct autcpu12_nvram_priv *priv = platform_get_drvdata(pdev);
-
-	mtd_device_unregister(priv->mtd);
-	map_destroy(priv->mtd);
-
-	return 0;
-}
-
-static struct platform_driver autcpu12_nvram_driver = {
-	.driver		= {
-		.name	= "autcpu12_nvram",
-		.owner	= THIS_MODULE,
-	},
-	.probe		= autcpu12_nvram_probe,
-	.remove		= autcpu12_nvram_remove,
-};
-module_platform_driver(autcpu12_nvram_driver);
-
-MODULE_AUTHOR("Thomas Gleixner");
-MODULE_DESCRIPTION("autcpu12 NVRAM map driver");
-MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mtd/maps/Kconfig linux-libre-3.11-rc7-gnu/drivers/mtd/maps/Kconfig
--- linux-libre-3.10-gnu/drivers/mtd/maps/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mtd/maps/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -297,13 +297,6 @@ config MTD_IXP4XX
 	  IXDP425 and Coyote. If you have an IXP4xx based board and
 	  would like to use the flash chips on it, say 'Y'.
 
-config MTD_AUTCPU12
-	bool "NV-RAM mapping AUTCPU12 board"
-	depends on ARCH_AUTCPU12
-	help
-	  This enables access to the NV-RAM on autronix autcpu12 board.
-	  If you have such a board, say 'Y'.
-
 config MTD_IMPA7
 	tristate "JEDEC Flash device mapped on impA7"
 	depends on ARM && MTD_JEDECPROBE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mtd/maps/Makefile linux-libre-3.11-rc7-gnu/drivers/mtd/maps/Makefile
--- linux-libre-3.10-gnu/drivers/mtd/maps/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mtd/maps/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@ obj-$(CONFIG_MTD_VMAX)		+= vmax301.o
 obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)		+= pci.o
-obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o
 obj-$(CONFIG_MTD_IMPA7)		+= impa7.o
 obj-$(CONFIG_MTD_UCLINUX)	+= uclinux.o
 obj-$(CONFIG_MTD_NETtel)	+= nettel.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mtd/mtdchar.c linux-libre-3.11-rc7-gnu/drivers/mtd/mtdchar.c
--- linux-libre-3.10-gnu/drivers/mtd/mtdchar.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mtd/mtdchar.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,25 +55,7 @@ struct mtd_file_info {
 static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig)
 {
 	struct mtd_file_info *mfi = file->private_data;
-	struct mtd_info *mtd = mfi->mtd;
-
-	switch (orig) {
-	case SEEK_SET:
-		break;
-	case SEEK_CUR:
-		offset += file->f_pos;
-		break;
-	case SEEK_END:
-		offset += mtd->size;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (offset >= 0 && offset <= mtd->size)
-		return file->f_pos = offset;
-
-	return -EINVAL;
+	return fixed_size_llseek(file, offset, orig, mfi->mtd->size);
 }
 
 static int count;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mtd/mtdcore.c linux-libre-3.11-rc7-gnu/drivers/mtd/mtdcore.c
--- linux-libre-3.10-gnu/drivers/mtd/mtdcore.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mtd/mtdcore.c	2013-08-25 20:43:22.000000000 -0400
@@ -1151,7 +1151,7 @@ static int __init mtd_bdi_init(struct ba
 
 	ret = bdi_init(bdi);
 	if (!ret)
-		ret = bdi_register(bdi, NULL, name);
+		ret = bdi_register(bdi, NULL, "%s", name);
 
 	if (ret)
 		bdi_destroy(bdi);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mtd/nand/Kconfig linux-libre-3.11-rc7-gnu/drivers/mtd/nand/Kconfig
--- linux-libre-3.10-gnu/drivers/mtd/nand/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mtd/nand/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -95,7 +95,7 @@ config MTD_NAND_OMAP2
 
 config MTD_NAND_OMAP_BCH
 	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
-	bool "Enable support for hardware BCH error correction"
+	tristate "Enable support for hardware BCH error correction"
 	default n
 	select BCH
 	select BCH_CONST_PARAMS
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mtd/ubi/build.c linux-libre-3.11-rc7-gnu/drivers/mtd/ubi/build.c
--- linux-libre-3.10-gnu/drivers/mtd/ubi/build.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mtd/ubi/build.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,7 +47,7 @@
 #define MTD_PARAM_LEN_MAX 64
 
 /* Maximum number of comma-separated items in the 'mtd=' parameter */
-#define MTD_PARAM_MAX_COUNT 3
+#define MTD_PARAM_MAX_COUNT 4
 
 /* Maximum value for the number of bad PEBs per 1024 PEBs */
 #define MAX_MTD_UBI_BEB_LIMIT 768
@@ -67,6 +67,7 @@
  */
 struct mtd_dev_param {
 	char name[MTD_PARAM_LEN_MAX];
+	int ubi_num;
 	int vid_hdr_offs;
 	int max_beb_per1024;
 };
@@ -1005,7 +1006,7 @@ int ubi_attach_mtd_dev(struct mtd_info *
 	if (err)
 		goto out_uif;
 
-	ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
+	ubi->bgt_thread = kthread_create(ubi_thread, ubi, "%s", ubi->bgt_name);
 	if (IS_ERR(ubi->bgt_thread)) {
 		err = PTR_ERR(ubi->bgt_thread);
 		ubi_err("cannot spawn \"%s\", error %d", ubi->bgt_name,
@@ -1261,11 +1262,15 @@ static int __init ubi_init(void)
 		mtd = open_mtd_device(p->name);
 		if (IS_ERR(mtd)) {
 			err = PTR_ERR(mtd);
-			goto out_detach;
+			ubi_err("cannot open mtd %s, error %d", p->name, err);
+			/* See comment below re-ubi_is_module(). */
+			if (ubi_is_module())
+				goto out_detach;
+			continue;
 		}
 
 		mutex_lock(&ubi_devices_mutex);
-		err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO,
+		err = ubi_attach_mtd_dev(mtd, p->ubi_num,
 					 p->vid_hdr_offs, p->max_beb_per1024);
 		mutex_unlock(&ubi_devices_mutex);
 		if (err < 0) {
@@ -1309,7 +1314,7 @@ out_version:
 out_class:
 	class_destroy(ubi_class);
 out:
-	ubi_err("UBI error: cannot initialize UBI, error %d", err);
+	ubi_err("cannot initialize UBI, error %d", err);
 	return err;
 }
 late_initcall(ubi_init);
@@ -1346,7 +1351,7 @@ static int __init bytes_str_to_int(const
 
 	result = simple_strtoul(str, &endp, 0);
 	if (str == endp || result >= INT_MAX) {
-		ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str);
+		ubi_err("incorrect bytes count: \"%s\"\n", str);
 		return -EINVAL;
 	}
 
@@ -1362,7 +1367,7 @@ static int __init bytes_str_to_int(const
 	case '\0':
 		break;
 	default:
-		ubi_err("UBI error: incorrect bytes count: \"%s\"\n", str);
+		ubi_err("incorrect bytes count: \"%s\"\n", str);
 		return -EINVAL;
 	}
 
@@ -1383,20 +1388,20 @@ static int __init ubi_mtd_param_parse(co
 	struct mtd_dev_param *p;
 	char buf[MTD_PARAM_LEN_MAX];
 	char *pbuf = &buf[0];
-	char *tokens[MTD_PARAM_MAX_COUNT];
+	char *tokens[MTD_PARAM_MAX_COUNT], *token;
 
 	if (!val)
 		return -EINVAL;
 
 	if (mtd_devs == UBI_MAX_DEVICES) {
-		ubi_err("UBI error: too many parameters, max. is %d\n",
+		ubi_err("too many parameters, max. is %d\n",
 			UBI_MAX_DEVICES);
 		return -EINVAL;
 	}
 
 	len = strnlen(val, MTD_PARAM_LEN_MAX);
 	if (len == MTD_PARAM_LEN_MAX) {
-		ubi_err("UBI error: parameter \"%s\" is too long, max. is %d\n",
+		ubi_err("parameter \"%s\" is too long, max. is %d\n",
 			val, MTD_PARAM_LEN_MAX);
 		return -EINVAL;
 	}
@@ -1416,44 +1421,60 @@ static int __init ubi_mtd_param_parse(co
 		tokens[i] = strsep(&pbuf, ",");
 
 	if (pbuf) {
-		ubi_err("UBI error: too many arguments at \"%s\"\n", val);
+		ubi_err("too many arguments at \"%s\"\n", val);
 		return -EINVAL;
 	}
 
 	p = &mtd_dev_param[mtd_devs];
 	strcpy(&p->name[0], tokens[0]);
 
-	if (tokens[1])
-		p->vid_hdr_offs = bytes_str_to_int(tokens[1]);
+	token = tokens[1];
+	if (token) {
+		p->vid_hdr_offs = bytes_str_to_int(token);
 
-	if (p->vid_hdr_offs < 0)
-		return p->vid_hdr_offs;
+		if (p->vid_hdr_offs < 0)
+			return p->vid_hdr_offs;
+	}
 
-	if (tokens[2]) {
-		int err = kstrtoint(tokens[2], 10, &p->max_beb_per1024);
+	token = tokens[2];
+	if (token) {
+		int err = kstrtoint(token, 10, &p->max_beb_per1024);
 
 		if (err) {
-			ubi_err("UBI error: bad value for max_beb_per1024 parameter: %s",
-				tokens[2]);
+			ubi_err("bad value for max_beb_per1024 parameter: %s",
+				token);
 			return -EINVAL;
 		}
 	}
 
+	token = tokens[3];
+	if (token) {
+		int err = kstrtoint(token, 10, &p->ubi_num);
+
+		if (err) {
+			ubi_err("bad value for ubi_num parameter: %s", token);
+			return -EINVAL;
+		}
+	} else
+		p->ubi_num = UBI_DEV_NUM_AUTO;
+
 	mtd_devs += 1;
 	return 0;
 }
 
 module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000);
-MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024]].\n"
+MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num]]].\n"
 		      "Multiple \"mtd\" parameters may be specified.\n"
 		      "MTD devices may be specified by their number, name, or path to the MTD character device node.\n"
 		      "Optional \"vid_hdr_offs\" parameter specifies UBI VID header position to be used by UBI. (default value if 0)\n"
 		      "Optional \"max_beb_per1024\" parameter specifies the maximum expected bad eraseblock per 1024 eraseblocks. (default value ("
 		      __stringify(CONFIG_MTD_UBI_BEB_LIMIT) ") if 0)\n"
+		      "Optional \"ubi_num\" parameter specifies UBI device number which have to be assigned to the newly created UBI device (assigned automatically by default)\n"
 		      "\n"
 		      "Example 1: mtd=/dev/mtd0 - attach MTD device /dev/mtd0.\n"
 		      "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n"
 		      "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n"
+		      "Example 4: mtd=/dev/mtd1,0,0,5 - attach MTD device /dev/mtd1 to UBI 5 and using default values for the other fields.\n"
 		      "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).");
 #ifdef CONFIG_MTD_UBI_FASTMAP
 module_param(fm_autoconvert, bool, 0644);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mtd/ubi/cdev.c linux-libre-3.11-rc7-gnu/drivers/mtd/ubi/cdev.c
--- linux-libre-3.10-gnu/drivers/mtd/ubi/cdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mtd/ubi/cdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -155,7 +155,6 @@ static loff_t vol_cdev_llseek(struct fil
 {
 	struct ubi_volume_desc *desc = file->private_data;
 	struct ubi_volume *vol = desc->vol;
-	loff_t new_offset;
 
 	if (vol->updating) {
 		/* Update is in progress, seeking is prohibited */
@@ -163,30 +162,7 @@ static loff_t vol_cdev_llseek(struct fil
 		return -EBUSY;
 	}
 
-	switch (origin) {
-	case 0: /* SEEK_SET */
-		new_offset = offset;
-		break;
-	case 1: /* SEEK_CUR */
-		new_offset = file->f_pos + offset;
-		break;
-	case 2: /* SEEK_END */
-		new_offset = vol->used_bytes + offset;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (new_offset < 0 || new_offset > vol->used_bytes) {
-		ubi_err("bad seek %lld", new_offset);
-		return -EINVAL;
-	}
-
-	dbg_gen("seek volume %d, offset %lld, origin %d, new offset %lld",
-		vol->vol_id, offset, origin, new_offset);
-
-	file->f_pos = new_offset;
-	return new_offset;
+	return fixed_size_llseek(file, offset, origin, vol->used_bytes);
 }
 
 static int vol_cdev_fsync(struct file *file, loff_t start, loff_t end,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/mtd/ubi/fastmap.c linux-libre-3.11-rc7-gnu/drivers/mtd/ubi/fastmap.c
--- linux-libre-3.10-gnu/drivers/mtd/ubi/fastmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/mtd/ubi/fastmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -727,8 +727,10 @@ static int ubi_attach_fastmap(struct ubi
 
 			aeb = NULL;
 			list_for_each_entry(tmp_aeb, &used, u.list) {
-				if (tmp_aeb->pnum == pnum)
+				if (tmp_aeb->pnum == pnum) {
 					aeb = tmp_aeb;
+					break;
+				}
 			}
 
 			/* This can happen if a PEB is already in an EBA known
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/arcnet/arcnet.c linux-libre-3.11-rc7-gnu/drivers/net/arcnet/arcnet.c
--- linux-libre-3.10-gnu/drivers/net/arcnet/arcnet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/arcnet/arcnet.c	2013-08-25 20:43:22.000000000 -0400
@@ -1007,7 +1007,7 @@ static void arcnet_rx(struct net_device
 
 	soft = &pkt.soft.rfc1201;
 
-	lp->hw.copy_from_card(dev, bufnum, 0, &pkt, sizeof(ARC_HDR_SIZE));
+	lp->hw.copy_from_card(dev, bufnum, 0, &pkt, ARC_HDR_SIZE);
 	if (pkt.hard.offset[0]) {
 		ofs = pkt.hard.offset[0];
 		length = 256 - ofs;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/bonding/bond_alb.c linux-libre-3.11-rc7-gnu/drivers/net/bonding/bond_alb.c
--- linux-libre-3.10-gnu/drivers/net/bonding/bond_alb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/bonding/bond_alb.c	2013-08-25 20:43:22.000000000 -0400
@@ -1056,7 +1056,7 @@ static int alb_set_slave_mac_addr(struct
  *
  */
 
-static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct slave *slave2)
+static void alb_swap_mac_addr(struct slave *slave1, struct slave *slave2)
 {
 	u8 tmp_mac_addr[ETH_ALEN];
 
@@ -1129,6 +1129,7 @@ static void alb_change_hw_addr_on_detach
 {
 	int perm_curr_diff;
 	int perm_bond_diff;
+	struct slave *found_slave;
 
 	perm_curr_diff = !ether_addr_equal_64bits(slave->perm_hwaddr,
 						  slave->dev->dev_addr);
@@ -1136,21 +1137,12 @@ static void alb_change_hw_addr_on_detach
 						  bond->dev->dev_addr);
 
 	if (perm_curr_diff && perm_bond_diff) {
-		struct slave *tmp_slave;
-		int i, found = 0;
-
-		bond_for_each_slave(bond, tmp_slave, i) {
-			if (ether_addr_equal_64bits(slave->perm_hwaddr,
-						    tmp_slave->dev->dev_addr)) {
-				found = 1;
-				break;
-			}
-		}
+		found_slave = bond_slave_has_mac(bond, slave->perm_hwaddr);
 
-		if (found) {
+		if (found_slave) {
 			/* locking: needs RTNL and nothing else */
-			alb_swap_mac_addr(bond, slave, tmp_slave);
-			alb_fasten_mac_swap(bond, slave, tmp_slave);
+			alb_swap_mac_addr(slave, found_slave);
+			alb_fasten_mac_swap(bond, slave, found_slave);
 		}
 	}
 }
@@ -1175,16 +1167,13 @@ static void alb_change_hw_addr_on_detach
  * @slave.
  *
  * assumption: this function is called before @slave is attached to the
- * 	       bond slave list.
- *
- * caller must hold the bond lock for write since the mac addresses are compared
- * and may be swapped.
+ *	       bond slave list.
  */
 static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
 {
-	struct slave *tmp_slave1, *tmp_slave2, *free_mac_slave;
+	struct slave *tmp_slave1, *free_mac_slave = NULL;
 	struct slave *has_bond_addr = bond->curr_active_slave;
-	int i, j, found = 0;
+	int i;
 
 	if (bond->slave_cnt == 0) {
 		/* this is the first slave */
@@ -1196,15 +1185,7 @@ static int alb_handle_addr_collision_on_
 	 * slaves in the bond.
 	 */
 	if (!ether_addr_equal_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) {
-		bond_for_each_slave(bond, tmp_slave1, i) {
-			if (ether_addr_equal_64bits(tmp_slave1->dev->dev_addr,
-						    slave->dev->dev_addr)) {
-				found = 1;
-				break;
-			}
-		}
-
-		if (!found)
+		if (!bond_slave_has_mac(bond, slave->dev->dev_addr))
 			return 0;
 
 		/* Try setting slave mac to bond address and fall-through
@@ -1215,19 +1196,8 @@ static int alb_handle_addr_collision_on_
 	/* The slave's address is equal to the address of the bond.
 	 * Search for a spare address in the bond for this slave.
 	 */
-	free_mac_slave = NULL;
-
 	bond_for_each_slave(bond, tmp_slave1, i) {
-		found = 0;
-		bond_for_each_slave(bond, tmp_slave2, j) {
-			if (ether_addr_equal_64bits(tmp_slave1->perm_hwaddr,
-						    tmp_slave2->dev->dev_addr)) {
-				found = 1;
-				break;
-			}
-		}
-
-		if (!found) {
+		if (!bond_slave_has_mac(bond, tmp_slave1->perm_hwaddr)) {
 			/* no slave has tmp_slave1's perm addr
 			 * as its curr addr
 			 */
@@ -1607,15 +1577,7 @@ int bond_alb_init_slave(struct bonding *
 		return res;
 	}
 
-	/* caller must hold the bond lock for write since the mac addresses
-	 * are compared and may be swapped.
-	 */
-	read_lock(&bond->lock);
-
 	res = alb_handle_addr_collision_on_attach(bond, slave);
-
-	read_unlock(&bond->lock);
-
 	if (res) {
 		return res;
 	}
@@ -1698,7 +1660,6 @@ void bond_alb_handle_active_change(struc
 	__acquires(&bond->curr_slave_lock)
 {
 	struct slave *swap_slave;
-	int i;
 
 	if (bond->curr_active_slave == new_slave) {
 		return;
@@ -1720,17 +1681,8 @@ void bond_alb_handle_active_change(struc
 	/* set the new curr_active_slave to the bonds mac address
 	 * i.e. swap mac addresses of old curr_active_slave and new curr_active_slave
 	 */
-	if (!swap_slave) {
-		struct slave *tmp_slave;
-		/* find slave that is holding the bond's mac address */
-		bond_for_each_slave(bond, tmp_slave, i) {
-			if (ether_addr_equal_64bits(tmp_slave->dev->dev_addr,
-						    bond->dev->dev_addr)) {
-				swap_slave = tmp_slave;
-				break;
-			}
-		}
-	}
+	if (!swap_slave)
+		swap_slave = bond_slave_has_mac(bond, bond->dev->dev_addr);
 
 	/*
 	 * Arrange for swap_slave and new_slave to temporarily be
@@ -1750,16 +1702,12 @@ void bond_alb_handle_active_change(struc
 	/* curr_active_slave must be set before calling alb_swap_mac_addr */
 	if (swap_slave) {
 		/* swap mac address */
-		alb_swap_mac_addr(bond, swap_slave, new_slave);
-	} else {
-		/* set the new_slave to the bond mac address */
-		alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr);
-	}
-
-	if (swap_slave) {
+		alb_swap_mac_addr(swap_slave, new_slave);
 		alb_fasten_mac_swap(bond, swap_slave, new_slave);
 		read_lock(&bond->lock);
 	} else {
+		/* set the new_slave to the bond mac address */
+		alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr);
 		read_lock(&bond->lock);
 		alb_send_learning_packets(new_slave, bond->dev->dev_addr);
 	}
@@ -1776,9 +1724,8 @@ int bond_alb_set_mac_address(struct net_
 {
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct sockaddr *sa = addr;
-	struct slave *slave, *swap_slave;
+	struct slave *swap_slave;
 	int res;
-	int i;
 
 	if (!is_valid_ether_addr(sa->sa_data)) {
 		return -EADDRNOTAVAIL;
@@ -1799,18 +1746,10 @@ int bond_alb_set_mac_address(struct net_
 		return 0;
 	}
 
-	swap_slave = NULL;
-
-	bond_for_each_slave(bond, slave, i) {
-		if (ether_addr_equal_64bits(slave->dev->dev_addr,
-					    bond_dev->dev_addr)) {
-			swap_slave = slave;
-			break;
-		}
-	}
+	swap_slave = bond_slave_has_mac(bond, bond_dev->dev_addr);
 
 	if (swap_slave) {
-		alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave);
+		alb_swap_mac_addr(swap_slave, bond->curr_active_slave);
 		alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave);
 	} else {
 		alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/bonding/bonding.h linux-libre-3.11-rc7-gnu/drivers/net/bonding/bonding.h
--- linux-libre-3.10-gnu/drivers/net/bonding/bonding.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/bonding/bonding.h	2013-08-25 20:43:22.000000000 -0400
@@ -144,6 +144,7 @@ struct bond_params {
 	u8 num_peer_notif;
 	int arp_interval;
 	int arp_validate;
+	int arp_all_targets;
 	int use_carrier;
 	int fail_over_mac;
 	int updelay;
@@ -179,6 +180,7 @@ struct slave {
 	int    delay;
 	unsigned long jiffies;
 	unsigned long last_arp_rx;
+	unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
 	s8     link;    /* one of BOND_LINK_XXXX */
 	s8     new_link;
 	u8     backup:1,   /* indicates backup slave. Value corresponds with
@@ -224,14 +226,12 @@ struct bonding {
 	rwlock_t lock;
 	rwlock_t curr_slave_lock;
 	u8	 send_peer_notif;
-	s8	 setup_by_slave;
 	u8       igmp_retrans;
 #ifdef CONFIG_PROC_FS
 	struct   proc_dir_entry *proc_entry;
 	char     proc_file_name[IFNAMSIZ];
 #endif /* CONFIG_PROC_FS */
 	struct   list_head bond_list;
-	struct   netdev_hw_addr_list mc_list;
 	int      (*xmit_hash_policy)(struct sk_buff *, int);
 	u16      rr_tx_counter;
 	struct   ad_bond_info ad_info;
@@ -248,7 +248,6 @@ struct bonding {
 	/* debugging support via debugfs */
 	struct	 dentry *debug_dir;
 #endif /* CONFIG_DEBUG_FS */
-	bool	dev_addr_from_first;
 };
 
 static inline bool bond_vlan_used(struct bonding *bond)
@@ -323,6 +322,9 @@ static inline bool bond_is_active_slave(
 #define BOND_FOM_ACTIVE			1
 #define BOND_FOM_FOLLOW			2
 
+#define BOND_ARP_TARGETS_ANY		0
+#define BOND_ARP_TARGETS_ALL		1
+
 #define BOND_ARP_VALIDATE_NONE		0
 #define BOND_ARP_VALIDATE_ACTIVE	(1 << BOND_STATE_ACTIVE)
 #define BOND_ARP_VALIDATE_BACKUP	(1 << BOND_STATE_BACKUP)
@@ -335,11 +337,31 @@ static inline int slave_do_arp_validate(
 	return bond->params.arp_validate & (1 << bond_slave_state(slave));
 }
 
+/* Get the oldest arp which we've received on this slave for bond's
+ * arp_targets.
+ */
+static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond,
+						       struct slave *slave)
+{
+	int i = 1;
+	unsigned long ret = slave->target_last_arp_rx[0];
+
+	for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++)
+		if (time_before(slave->target_last_arp_rx[i], ret))
+			ret = slave->target_last_arp_rx[i];
+
+	return ret;
+}
+
 static inline unsigned long slave_last_rx(struct bonding *bond,
 					struct slave *slave)
 {
-	if (slave_do_arp_validate(bond, slave))
-		return slave->last_arp_rx;
+	if (slave_do_arp_validate(bond, slave)) {
+		if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL)
+			return slave_oldest_target_arp_rx(bond, slave);
+		else
+			return slave->last_arp_rx;
+	}
 
 	return slave->dev->last_rx;
 }
@@ -465,12 +487,29 @@ static inline struct slave *bond_slave_h
 	return NULL;
 }
 
+/* Check if the ip is present in arp ip list, or first free slot if ip == 0
+ * Returns -1 if not found, index if found
+ */
+static inline int bond_get_targets_ip(__be32 *targets, __be32 ip)
+{
+	int i;
+
+	for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
+		if (targets[i] == ip)
+			return i;
+		else if (targets[i] == 0)
+			break;
+
+	return -1;
+}
+
 /* exported from bond_main.c */
 extern int bond_net_id;
 extern const struct bond_parm_tbl bond_lacp_tbl[];
 extern const struct bond_parm_tbl bond_mode_tbl[];
 extern const struct bond_parm_tbl xmit_hashtype_tbl[];
 extern const struct bond_parm_tbl arp_validate_tbl[];
+extern const struct bond_parm_tbl arp_all_targets_tbl[];
 extern const struct bond_parm_tbl fail_over_mac_tbl[];
 extern const struct bond_parm_tbl pri_reselect_tbl[];
 extern struct bond_parm_tbl ad_select_tbl[];
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/bonding/bond_main.c linux-libre-3.11-rc7-gnu/drivers/net/bonding/bond_main.c
--- linux-libre-3.10-gnu/drivers/net/bonding/bond_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/bonding/bond_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,6 +104,7 @@ static char *xmit_hash_policy;
 static int arp_interval = BOND_LINK_ARP_INTERV;
 static char *arp_ip_target[BOND_MAX_ARP_TARGETS];
 static char *arp_validate;
+static char *arp_all_targets;
 static char *fail_over_mac;
 static int all_slaves_active = 0;
 static struct bond_params bonding_defaults;
@@ -166,6 +167,8 @@ module_param(arp_validate, charp, 0);
 MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes; "
 			       "0 for none (default), 1 for active, "
 			       "2 for backup, 3 for all");
+module_param(arp_all_targets, charp, 0);
+MODULE_PARM_DESC(arp_all_targets, "fail on any/all arp targets timeout; 0 for any (default), 1 for all");
 module_param(fail_over_mac, charp, 0);
 MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to "
 				"the same MAC; 0 for none (default), "
@@ -216,6 +219,12 @@ const struct bond_parm_tbl xmit_hashtype
 {	NULL,			-1},
 };
 
+const struct bond_parm_tbl arp_all_targets_tbl[] = {
+{	"any",			BOND_ARP_TARGETS_ANY},
+{	"all",			BOND_ARP_TARGETS_ALL},
+{	NULL,			-1},
+};
+
 const struct bond_parm_tbl arp_validate_tbl[] = {
 {	"none",			BOND_ARP_VALIDATE_NONE},
 {	"active",		BOND_ARP_VALIDATE_ACTIVE},
@@ -706,45 +715,6 @@ static int bond_set_allmulti(struct bond
 	return err;
 }
 
-/*
- * Add a Multicast address to slaves
- * according to mode
- */
-static void bond_mc_add(struct bonding *bond, void *addr)
-{
-	if (USES_PRIMARY(bond->params.mode)) {
-		/* write lock already acquired */
-		if (bond->curr_active_slave)
-			dev_mc_add(bond->curr_active_slave->dev, addr);
-	} else {
-		struct slave *slave;
-		int i;
-
-		bond_for_each_slave(bond, slave, i)
-			dev_mc_add(slave->dev, addr);
-	}
-}
-
-/*
- * Remove a multicast address from slave
- * according to mode
- */
-static void bond_mc_del(struct bonding *bond, void *addr)
-{
-	if (USES_PRIMARY(bond->params.mode)) {
-		/* write lock already acquired */
-		if (bond->curr_active_slave)
-			dev_mc_del(bond->curr_active_slave->dev, addr);
-	} else {
-		struct slave *slave;
-		int i;
-		bond_for_each_slave(bond, slave, i) {
-			dev_mc_del(slave->dev, addr);
-		}
-	}
-}
-
-
 static void __bond_resend_igmp_join_requests(struct net_device *dev)
 {
 	struct in_device *in_dev;
@@ -810,17 +780,15 @@ static void bond_resend_igmp_join_reques
 	bond_resend_igmp_join_requests(bond);
 }
 
-/*
- * flush all members of flush->mc_list from device dev->mc_list
+/* Flush bond's hardware addresses from slave
  */
-static void bond_mc_list_flush(struct net_device *bond_dev,
+static void bond_hw_addr_flush(struct net_device *bond_dev,
 			       struct net_device *slave_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
-	struct netdev_hw_addr *ha;
 
-	netdev_for_each_mc_addr(ha, bond_dev)
-		dev_mc_del(slave_dev, ha->addr);
+	dev_uc_unsync(slave_dev, bond_dev);
+	dev_mc_unsync(slave_dev, bond_dev);
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		/* del lacpdu mc addr from mc list */
@@ -832,22 +800,14 @@ static void bond_mc_list_flush(struct ne
 
 /*--------------------------- Active slave change ---------------------------*/
 
-/*
- * Update the mc list and multicast-related flags for the new and
- * old active slaves (if any) according to the multicast mode, and
- * promiscuous flags unconditionally.
+/* Update the hardware address list and promisc/allmulti for the new and
+ * old active slaves (if any).  Modes that are !USES_PRIMARY keep all
+ * slaves up date at all times; only the USES_PRIMARY modes need to call
+ * this function to swap these settings during a failover.
  */
-static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
-			 struct slave *old_active)
+static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
+			      struct slave *old_active)
 {
-	struct netdev_hw_addr *ha;
-
-	if (!USES_PRIMARY(bond->params.mode))
-		/* nothing to do -  mc list is already up-to-date on
-		 * all slaves
-		 */
-		return;
-
 	if (old_active) {
 		if (bond->dev->flags & IFF_PROMISC)
 			dev_set_promiscuity(old_active->dev, -1);
@@ -855,10 +815,7 @@ static void bond_mc_swap(struct bonding
 		if (bond->dev->flags & IFF_ALLMULTI)
 			dev_set_allmulti(old_active->dev, -1);
 
-		netif_addr_lock_bh(bond->dev);
-		netdev_for_each_mc_addr(ha, bond->dev)
-			dev_mc_del(old_active->dev, ha->addr);
-		netif_addr_unlock_bh(bond->dev);
+		bond_hw_addr_flush(bond->dev, old_active->dev);
 	}
 
 	if (new_active) {
@@ -870,12 +827,29 @@ static void bond_mc_swap(struct bonding
 			dev_set_allmulti(new_active->dev, 1);
 
 		netif_addr_lock_bh(bond->dev);
-		netdev_for_each_mc_addr(ha, bond->dev)
-			dev_mc_add(new_active->dev, ha->addr);
+		dev_uc_sync(new_active->dev, bond->dev);
+		dev_mc_sync(new_active->dev, bond->dev);
 		netif_addr_unlock_bh(bond->dev);
 	}
 }
 
+/**
+ * bond_set_dev_addr - clone slave's address to bond
+ * @bond_dev: bond net device
+ * @slave_dev: slave net device
+ *
+ * Should be called with RTNL held.
+ */
+static void bond_set_dev_addr(struct net_device *bond_dev,
+			      struct net_device *slave_dev)
+{
+	pr_debug("bond_dev=%p slave_dev=%p slave_dev->addr_len=%d\n",
+		 bond_dev, slave_dev, slave_dev->addr_len);
+	memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len);
+	bond_dev->addr_assign_type = NET_ADDR_STOLEN;
+	call_netdevice_notifiers(NETDEV_CHANGEADDR, bond_dev);
+}
+
 /*
  * bond_do_fail_over_mac
  *
@@ -898,11 +872,9 @@ static void bond_do_fail_over_mac(struct
 	switch (bond->params.fail_over_mac) {
 	case BOND_FOM_ACTIVE:
 		if (new_active) {
-			memcpy(bond->dev->dev_addr,  new_active->dev->dev_addr,
-			       new_active->dev->addr_len);
 			write_unlock_bh(&bond->curr_slave_lock);
 			read_unlock(&bond->lock);
-			call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
+			bond_set_dev_addr(bond->dev, new_active->dev);
 			read_lock(&bond->lock);
 			write_lock_bh(&bond->curr_slave_lock);
 		}
@@ -1090,7 +1062,7 @@ void bond_change_active_slave(struct bon
 	}
 
 	if (USES_PRIMARY(bond->params.mode))
-		bond_mc_swap(bond, new_active, old_active);
+		bond_hw_addr_swap(bond, new_active, old_active);
 
 	if (bond_is_lb(bond)) {
 		bond_alb_handle_active_change(bond, new_active);
@@ -1333,17 +1305,6 @@ static void bond_netpoll_cleanup(struct
 
 /*---------------------------------- IOCTL ----------------------------------*/
 
-static void bond_set_dev_addr(struct net_device *bond_dev,
-			      struct net_device *slave_dev)
-{
-	pr_debug("bond_dev=%p\n", bond_dev);
-	pr_debug("slave_dev=%p\n", slave_dev);
-	pr_debug("slave_dev->addr_len=%d\n", slave_dev->addr_len);
-	memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len);
-	bond_dev->addr_assign_type = NET_ADDR_SET;
-	call_netdevice_notifiers(NETDEV_CHANGEADDR, bond_dev);
-}
-
 static netdev_features_t bond_fix_features(struct net_device *dev,
 	netdev_features_t features)
 {
@@ -1425,8 +1386,6 @@ done:
 static void bond_setup_by_slave(struct net_device *bond_dev,
 				struct net_device *slave_dev)
 {
-	struct bonding *bond = netdev_priv(bond_dev);
-
 	bond_dev->header_ops	    = slave_dev->header_ops;
 
 	bond_dev->type		    = slave_dev->type;
@@ -1435,7 +1394,6 @@ static void bond_setup_by_slave(struct n
 
 	memcpy(bond_dev->broadcast, slave_dev->broadcast,
 		slave_dev->addr_len);
-	bond->setup_by_slave = 1;
 }
 
 /* On bonding slaves other than the currently active slave, suppress
@@ -1533,10 +1491,9 @@ int bond_enslave(struct net_device *bond
 	struct bonding *bond = netdev_priv(bond_dev);
 	const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
 	struct slave *new_slave = NULL;
-	struct netdev_hw_addr *ha;
 	struct sockaddr addr;
 	int link_reporting;
-	int res = 0;
+	int res = 0, i;
 
 	if (!bond->params.use_carrier &&
 	    slave_dev->ethtool_ops->get_link == NULL &&
@@ -1643,7 +1600,7 @@ int bond_enslave(struct net_device *bond
 
 	/* If this is the first slave, then we need to set the master's hardware
 	 * address to be the same as the slave's. */
-	if (bond->slave_cnt == 0 && bond->dev_addr_from_first)
+	if (!bond->slave_cnt && bond->dev->addr_assign_type == NET_ADDR_RANDOM)
 		bond_set_dev_addr(bond->dev, slave_dev);
 
 	new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
@@ -1713,10 +1670,8 @@ int bond_enslave(struct net_device *bond
 			goto err_close;
 	}
 
-	/* If the mode USES_PRIMARY, then the new slave gets the
-	 * master's promisc (and mc) settings only if it becomes the
-	 * curr_active_slave, and that is taken care of later when calling
-	 * bond_change_active()
+	/* If the mode USES_PRIMARY, then the following is handled by
+	 * bond_change_active_slave().
 	 */
 	if (!USES_PRIMARY(bond->params.mode)) {
 		/* set promiscuity level to new slave */
@@ -1734,9 +1689,10 @@ int bond_enslave(struct net_device *bond
 		}
 
 		netif_addr_lock_bh(bond_dev);
-		/* upload master's mc_list to new slave */
-		netdev_for_each_mc_addr(ha, bond_dev)
-			dev_mc_add(slave_dev, ha->addr);
+
+		dev_mc_sync_multiple(slave_dev, bond_dev);
+		dev_uc_sync_multiple(slave_dev, bond_dev);
+
 		netif_addr_unlock_bh(bond_dev);
 	}
 
@@ -1766,6 +1722,8 @@ int bond_enslave(struct net_device *bond
 
 	new_slave->last_arp_rx = jiffies -
 		(msecs_to_jiffies(bond->params.arp_interval) + 1);
+	for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
+		new_slave->target_last_arp_rx[i] = new_slave->last_arp_rx;
 
 	if (bond->params.miimon && !bond->params.use_carrier) {
 		link_reporting = bond_check_dev_link(bond, slave_dev, 1);
@@ -1915,11 +1873,9 @@ err_dest_symlinks:
 	bond_destroy_slave_symlinks(bond_dev, slave_dev);
 
 err_detach:
-	if (!USES_PRIMARY(bond->params.mode)) {
-		netif_addr_lock_bh(bond_dev);
-		bond_mc_list_flush(bond_dev, slave_dev);
-		netif_addr_unlock_bh(bond_dev);
-	}
+	if (!USES_PRIMARY(bond->params.mode))
+		bond_hw_addr_flush(bond_dev, slave_dev);
+
 	bond_del_vlans_from_slave(bond, slave_dev);
 	write_lock_bh(&bond->lock);
 	bond_detach_slave(bond, new_slave);
@@ -2089,7 +2045,6 @@ static int __bond_release_one(struct net
 	if (bond->slave_cnt == 0) {
 		bond_set_carrier(bond);
 		eth_hw_addr_random(bond_dev);
-		bond->dev_addr_from_first = true;
 
 		if (bond_vlan_used(bond)) {
 			pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
@@ -2118,9 +2073,8 @@ static int __bond_release_one(struct net
 
 	bond_del_vlans_from_slave(bond, slave_dev);
 
-	/* If the mode USES_PRIMARY, then we should only remove its
-	 * promisc and mc settings if it was the curr_active_slave, but that was
-	 * already taken care of above when we detached the slave
+	/* If the mode USES_PRIMARY, then this cases was handled above by
+	 * bond_change_active_slave(..., NULL)
 	 */
 	if (!USES_PRIMARY(bond->params.mode)) {
 		/* unset promiscuity level from slave */
@@ -2131,10 +2085,7 @@ static int __bond_release_one(struct net
 		if (bond_dev->flags & IFF_ALLMULTI)
 			dev_set_allmulti(slave_dev, -1);
 
-		/* flush master's mc_list from slave */
-		netif_addr_lock_bh(bond_dev);
-		bond_mc_list_flush(bond_dev, slave_dev);
-		netif_addr_unlock_bh(bond_dev);
+		bond_hw_addr_flush(bond_dev, slave_dev);
 	}
 
 	bond_upper_dev_unlink(bond_dev, slave_dev);
@@ -2672,18 +2623,19 @@ static void bond_arp_send_all(struct bon
 static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip)
 {
 	int i;
-	__be32 *targets = bond->params.arp_targets;
 
-	for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
-		pr_debug("bva: sip %pI4 tip %pI4 t[%d] %pI4 bhti(tip) %d\n",
-			 &sip, &tip, i, &targets[i],
-			 bond_has_this_ip(bond, tip));
-		if (sip == targets[i]) {
-			if (bond_has_this_ip(bond, tip))
-				slave->last_arp_rx = jiffies;
-			return;
-		}
+	if (!sip || !bond_has_this_ip(bond, tip)) {
+		pr_debug("bva: sip %pI4 tip %pI4 not found\n", &sip, &tip);
+		return;
 	}
+
+	i = bond_get_targets_ip(bond->params.arp_targets, sip);
+	if (i == -1) {
+		pr_debug("bva: sip %pI4 not found in targets\n", &sip);
+		return;
+	}
+	slave->last_arp_rx = jiffies;
+	slave->target_last_arp_rx[i] = jiffies;
 }
 
 static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
@@ -2698,6 +2650,10 @@ static int bond_arp_rcv(const struct sk_
 		return RX_HANDLER_ANOTHER;
 
 	read_lock(&bond->lock);
+
+	if (!slave_do_arp_validate(bond, slave))
+		goto out_unlock;
+
 	alen = arp_hdr_len(bond->dev);
 
 	pr_debug("bond_arp_rcv: bond %s skb->dev %s\n",
@@ -2737,10 +2693,17 @@ static int bond_arp_rcv(const struct sk_
 	 * configuration, the ARP probe will (hopefully) travel from
 	 * the active, through one switch, the router, then the other
 	 * switch before reaching the backup.
+	 *
+	 * We 'trust' the arp requests if there is an active slave and
+	 * it received valid arp reply(s) after it became active. This
+	 * is done to avoid endless looping when we can't reach the
+	 * arp_ip_target and fool ourselves with our own arp requests.
 	 */
 	if (bond_is_active_slave(slave))
 		bond_validate_arp(bond, slave, sip, tip);
-	else
+	else if (bond->curr_active_slave &&
+		 time_after(slave_last_rx(bond, bond->curr_active_slave),
+			    bond->curr_active_slave->jiffies))
 		bond_validate_arp(bond, slave, tip, sip);
 
 out_unlock:
@@ -3225,7 +3188,7 @@ static int bond_slave_netdev_event(unsig
 
 	switch (event) {
 	case NETDEV_UNREGISTER:
-		if (bond->setup_by_slave)
+		if (bond_dev->type != ARPHRD_ETHER)
 			bond_release_and_destroy(bond_dev, slave_dev);
 		else
 			bond_release(bond_dev, slave_dev);
@@ -3289,7 +3252,7 @@ static int bond_slave_netdev_event(unsig
 static int bond_netdev_event(struct notifier_block *this,
 			     unsigned long event, void *ptr)
 {
-	struct net_device *event_dev = (struct net_device *)ptr;
+	struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
 
 	pr_debug("event_dev: %s, event: %lx\n",
 		 event_dev ? event_dev->name : "None",
@@ -3672,19 +3635,6 @@ static int bond_do_ioctl(struct net_devi
 	return res;
 }
 
-static bool bond_addr_in_mc_list(unsigned char *addr,
-				 struct netdev_hw_addr_list *list,
-				 int addrlen)
-{
-	struct netdev_hw_addr *ha;
-
-	netdev_hw_addr_list_for_each(ha, list)
-		if (!memcmp(ha->addr, addr, addrlen))
-			return true;
-
-	return false;
-}
-
 static void bond_change_rx_flags(struct net_device *bond_dev, int change)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
@@ -3698,35 +3648,29 @@ static void bond_change_rx_flags(struct
 				  bond_dev->flags & IFF_ALLMULTI ? 1 : -1);
 }
 
-static void bond_set_multicast_list(struct net_device *bond_dev)
+static void bond_set_rx_mode(struct net_device *bond_dev)
 {
 	struct bonding *bond = netdev_priv(bond_dev);
-	struct netdev_hw_addr *ha;
-	bool found;
+	struct slave *slave;
+	int i;
 
 	read_lock(&bond->lock);
 
-	/* looking for addresses to add to slaves' mc list */
-	netdev_for_each_mc_addr(ha, bond_dev) {
-		found = bond_addr_in_mc_list(ha->addr, &bond->mc_list,
-					     bond_dev->addr_len);
-		if (!found)
-			bond_mc_add(bond, ha->addr);
-	}
-
-	/* looking for addresses to delete from slaves' list */
-	netdev_hw_addr_list_for_each(ha, &bond->mc_list) {
-		found = bond_addr_in_mc_list(ha->addr, &bond_dev->mc,
-					     bond_dev->addr_len);
-		if (!found)
-			bond_mc_del(bond, ha->addr);
+	if (USES_PRIMARY(bond->params.mode)) {
+		read_lock(&bond->curr_slave_lock);
+		slave = bond->curr_active_slave;
+		if (slave) {
+			dev_uc_sync(slave->dev, bond_dev);
+			dev_mc_sync(slave->dev, bond_dev);
+		}
+		read_unlock(&bond->curr_slave_lock);
+	} else {
+		bond_for_each_slave(bond, slave, i) {
+			dev_uc_sync_multiple(slave->dev, bond_dev);
+			dev_mc_sync_multiple(slave->dev, bond_dev);
+		}
 	}
 
-	/* save master's multicast list */
-	__hw_addr_flush(&bond->mc_list);
-	__hw_addr_add_multiple(&bond->mc_list, &bond_dev->mc,
-			       bond_dev->addr_len, NETDEV_HW_ADDR_T_MULTICAST);
-
 	read_unlock(&bond->lock);
 }
 
@@ -3770,11 +3714,17 @@ static int bond_neigh_init(struct neighb
  * The bonding ndo_neigh_setup is called at init time beofre any
  * slave exists. So we must declare proxy setup function which will
  * be used at run time to resolve the actual slave neigh param setup.
+ *
+ * It's also called by master devices (such as vlans) to setup their
+ * underlying devices. In that case - do nothing, we're already set up from
+ * our init.
  */
 static int bond_neigh_setup(struct net_device *dev,
 			    struct neigh_parms *parms)
 {
-	parms->neigh_setup   = bond_neigh_init;
+	/* modify only our neigh_parms */
+	if (parms->dev == dev)
+		parms->neigh_setup = bond_neigh_init;
 
 	return 0;
 }
@@ -3871,11 +3821,10 @@ static int bond_set_mac_address(struct n
 	pr_debug("bond=%p, name=%s\n",
 		 bond, bond_dev ? bond_dev->name : "None");
 
-	/*
-	 * If fail_over_mac is set to active, do nothing and return
-	 * success.  Returning an error causes ifenslave to fail.
+	/* If fail_over_mac is enabled, do nothing and return success.
+	 * Returning an error causes ifenslave to fail.
 	 */
-	if (bond->params.fail_over_mac == BOND_FOM_ACTIVE)
+	if (bond->params.fail_over_mac)
 		return 0;
 
 	if (!is_valid_ether_addr(sa->sa_data))
@@ -4333,7 +4282,7 @@ static const struct net_device_ops bond_
 	.ndo_get_stats64	= bond_get_stats,
 	.ndo_do_ioctl		= bond_do_ioctl,
 	.ndo_change_rx_flags	= bond_change_rx_flags,
-	.ndo_set_rx_mode	= bond_set_multicast_list,
+	.ndo_set_rx_mode	= bond_set_rx_mode,
 	.ndo_change_mtu		= bond_change_mtu,
 	.ndo_set_mac_address	= bond_set_mac_address,
 	.ndo_neigh_setup	= bond_neigh_setup,
@@ -4438,8 +4387,6 @@ static void bond_uninit(struct net_devic
 
 	bond_debug_unregister(bond);
 
-	__hw_addr_flush(&bond->mc_list);
-
 	list_for_each_entry_safe(vlan, tmp, &bond->vlan_list, vlan_list) {
 		list_del(&vlan->vlan_list);
 		kfree(vlan);
@@ -4484,6 +4431,7 @@ int bond_parse_parm(const char *buf, con
 static int bond_check_params(struct bond_params *params)
 {
 	int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
+	int arp_all_targets_value;
 
 	/*
 	 * Convert string parameters.
@@ -4674,7 +4622,11 @@ static int bond_check_params(struct bond
 				   arp_ip_target[i]);
 			arp_interval = 0;
 		} else {
-			arp_target[arp_ip_count++] = ip;
+			if (bond_get_targets_ip(arp_target, ip) == -1)
+				arp_target[arp_ip_count++] = ip;
+			else
+				pr_warning("Warning: duplicate address %pI4 in arp_ip_target, skipping\n",
+					   &ip);
 		}
 	}
 
@@ -4705,6 +4657,18 @@ static int bond_check_params(struct bond
 	} else
 		arp_validate_value = 0;
 
+	arp_all_targets_value = 0;
+	if (arp_all_targets) {
+		arp_all_targets_value = bond_parse_parm(arp_all_targets,
+							arp_all_targets_tbl);
+
+		if (arp_all_targets_value == -1) {
+			pr_err("Error: invalid arp_all_targets_value \"%s\"\n",
+			       arp_all_targets);
+			arp_all_targets_value = 0;
+		}
+	}
+
 	if (miimon) {
 		pr_info("MII link monitoring set to %d ms\n", miimon);
 	} else if (arp_interval) {
@@ -4769,6 +4733,7 @@ static int bond_check_params(struct bond
 	params->num_peer_notif = num_peer_notif;
 	params->arp_interval = arp_interval;
 	params->arp_validate = arp_validate_value;
+	params->arp_all_targets = arp_all_targets_value;
 	params->updelay = updelay;
 	params->downdelay = downdelay;
 	params->use_carrier = use_carrier;
@@ -4845,12 +4810,9 @@ static int bond_init(struct net_device *
 
 	/* Ensure valid dev_addr */
 	if (is_zero_ether_addr(bond_dev->dev_addr) &&
-	    bond_dev->addr_assign_type == NET_ADDR_PERM) {
+	    bond_dev->addr_assign_type == NET_ADDR_PERM)
 		eth_hw_addr_random(bond_dev);
-		bond->dev_addr_from_first = true;
-	}
 
-	__hw_addr_init(&bond->mc_list);
 	return 0;
 }
 
@@ -4923,7 +4885,7 @@ static int __net_init bond_net_init(stru
 
 	bond_create_proc_dir(bn);
 	bond_create_sysfs(bn);
-	
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/bonding/bond_sysfs.c linux-libre-3.11-rc7-gnu/drivers/net/bonding/bond_sysfs.c
--- linux-libre-3.10-gnu/drivers/net/bonding/bond_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/bonding/bond_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -231,8 +231,7 @@ static ssize_t bonding_show_slaves(struc
 }
 
 /*
- * Set the slaves in the current bond.  The bond interface must be
- * up for this to succeed.
+ * Set the slaves in the current bond.
  * This is supposed to be only thin wrapper for bond_enslave and bond_release.
  * All hard work should be done there.
  */
@@ -363,7 +362,6 @@ static DEVICE_ATTR(mode, S_IRUGO | S_IWU
 
 /*
  * Show and set the bonding transmit hash method.
- * The bond interface must be down to change the xmit hash policy.
  */
 static ssize_t bonding_show_xmit_hash(struct device *d,
 				      struct device_attribute *attr,
@@ -383,20 +381,12 @@ static ssize_t bonding_store_xmit_hash(s
 	int new_value, ret = count;
 	struct bonding *bond = to_bond(d);
 
-	if (bond->dev->flags & IFF_UP) {
-		pr_err("%s: Interface is up. Unable to update xmit policy.\n",
-		       bond->dev->name);
-		ret = -EPERM;
-		goto out;
-	}
-
 	new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
 	if (new_value < 0)  {
 		pr_err("%s: Ignoring invalid xmit hash policy value %.*s.\n",
 		       bond->dev->name,
 		       (int)strlen(buf) - 1, buf);
 		ret = -EINVAL;
-		goto out;
 	} else {
 		bond->params.xmit_policy = new_value;
 		bond_set_mode_ops(bond, bond->params.mode);
@@ -404,7 +394,7 @@ static ssize_t bonding_store_xmit_hash(s
 			bond->dev->name,
 			xmit_hashtype_tbl[new_value].modename, new_value);
 	}
-out:
+
 	return ret;
 }
 static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR,
@@ -453,6 +443,44 @@ static ssize_t bonding_store_arp_validat
 
 static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,
 		   bonding_store_arp_validate);
+/*
+ * Show and set arp_all_targets.
+ */
+static ssize_t bonding_show_arp_all_targets(struct device *d,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct bonding *bond = to_bond(d);
+	int value = bond->params.arp_all_targets;
+
+	return sprintf(buf, "%s %d\n", arp_all_targets_tbl[value].modename,
+		       value);
+}
+
+static ssize_t bonding_store_arp_all_targets(struct device *d,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
+{
+	struct bonding *bond = to_bond(d);
+	int new_value;
+
+	new_value = bond_parse_parm(buf, arp_all_targets_tbl);
+	if (new_value < 0) {
+		pr_err("%s: Ignoring invalid arp_all_targets value %s\n",
+		       bond->dev->name, buf);
+		return -EINVAL;
+	}
+	pr_info("%s: setting arp_all_targets to %s (%d).\n",
+		bond->dev->name, arp_all_targets_tbl[new_value].modename,
+		new_value);
+
+	bond->params.arp_all_targets = new_value;
+
+	return count;
+}
+
+static DEVICE_ATTR(arp_all_targets, S_IRUGO | S_IWUSR,
+		   bonding_show_arp_all_targets, bonding_store_arp_all_targets);
 
 /*
  * Show and store fail_over_mac.  User only allowed to change the
@@ -600,10 +628,11 @@ static ssize_t bonding_store_arp_targets
 					 struct device_attribute *attr,
 					 const char *buf, size_t count)
 {
-	__be32 newtarget;
-	int i = 0, done = 0, ret = count;
 	struct bonding *bond = to_bond(d);
-	__be32 *targets;
+	struct slave *slave;
+	__be32 newtarget, *targets;
+	unsigned long *targets_rx;
+	int ind, i, j, ret = -EINVAL;
 
 	targets = bond->params.arp_targets;
 	newtarget = in_aton(buf + 1);
@@ -612,57 +641,63 @@ static ssize_t bonding_store_arp_targets
 		if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
 			pr_err("%s: invalid ARP target %pI4 specified for addition\n",
 			       bond->dev->name, &newtarget);
-			ret = -EINVAL;
 			goto out;
 		}
-		/* look for an empty slot to put the target in, and check for dupes */
-		for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
-			if (targets[i] == newtarget) { /* duplicate */
-				pr_err("%s: ARP target %pI4 is already present\n",
-				       bond->dev->name, &newtarget);
-				ret = -EINVAL;
-				goto out;
-			}
-			if (targets[i] == 0) {
-				pr_info("%s: adding ARP target %pI4.\n",
-					bond->dev->name, &newtarget);
-				done = 1;
-				targets[i] = newtarget;
-			}
+
+		if (bond_get_targets_ip(targets, newtarget) != -1) { /* dup */
+			pr_err("%s: ARP target %pI4 is already present\n",
+			       bond->dev->name, &newtarget);
+			goto out;
 		}
-		if (!done) {
+
+		ind = bond_get_targets_ip(targets, 0); /* first free slot */
+		if (ind == -1) {
 			pr_err("%s: ARP target table is full!\n",
 			       bond->dev->name);
-			ret = -EINVAL;
 			goto out;
 		}
 
+		pr_info("%s: adding ARP target %pI4.\n", bond->dev->name,
+			 &newtarget);
+		/* not to race with bond_arp_rcv */
+		write_lock_bh(&bond->lock);
+		bond_for_each_slave(bond, slave, i)
+			slave->target_last_arp_rx[ind] = jiffies;
+		targets[ind] = newtarget;
+		write_unlock_bh(&bond->lock);
 	} else if (buf[0] == '-')	{
 		if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
 			pr_err("%s: invalid ARP target %pI4 specified for removal\n",
 			       bond->dev->name, &newtarget);
-			ret = -EINVAL;
 			goto out;
 		}
 
-		for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
-			if (targets[i] == newtarget) {
-				int j;
-				pr_info("%s: removing ARP target %pI4.\n",
-					bond->dev->name, &newtarget);
-				for (j = i; (j < (BOND_MAX_ARP_TARGETS-1)) && targets[j+1]; j++)
-					targets[j] = targets[j+1];
-
-				targets[j] = 0;
-				done = 1;
-			}
-		}
-		if (!done) {
-			pr_info("%s: unable to remove nonexistent ARP target %pI4.\n",
+		ind = bond_get_targets_ip(targets, newtarget);
+		if (ind == -1) {
+			pr_err("%s: unable to remove nonexistent ARP target %pI4.\n",
 				bond->dev->name, &newtarget);
-			ret = -EINVAL;
 			goto out;
 		}
+
+		if (ind == 0 && !targets[1] && bond->params.arp_interval)
+			pr_warn("%s: removing last arp target with arp_interval on\n",
+				bond->dev->name);
+
+		pr_info("%s: removing ARP target %pI4.\n", bond->dev->name,
+			&newtarget);
+
+		write_lock_bh(&bond->lock);
+		bond_for_each_slave(bond, slave, i) {
+			targets_rx = slave->target_last_arp_rx;
+			j = ind;
+			for (; (j < BOND_MAX_ARP_TARGETS-1) && targets[j+1]; j++)
+				targets_rx[j] = targets_rx[j+1];
+			targets_rx[j] = 0;
+		}
+		for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
+			targets[i] = targets[i+1];
+		targets[i] = 0;
+		write_unlock_bh(&bond->lock);
 	} else {
 		pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
 		       bond->dev->name);
@@ -670,6 +705,7 @@ static ssize_t bonding_store_arp_targets
 		goto out;
 	}
 
+	ret = count;
 out:
 	return ret;
 }
@@ -1645,6 +1681,7 @@ static struct attribute *per_bond_attrs[
 	&dev_attr_mode.attr,
 	&dev_attr_fail_over_mac.attr,
 	&dev_attr_arp_validate.attr,
+	&dev_attr_arp_all_targets.attr,
 	&dev_attr_arp_interval.attr,
 	&dev_attr_arp_ip_target.attr,
 	&dev_attr_downdelay.attr,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/caif/caif_serial.c linux-libre-3.11-rc7-gnu/drivers/net/caif/caif_serial.c
--- linux-libre-3.10-gnu/drivers/net/caif/caif_serial.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/caif/caif_serial.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,8 +35,9 @@ MODULE_ALIAS_LDISC(N_CAIF);
 #define OFF 0
 #define CAIF_MAX_MTU 4096
 
-/*This list is protected by the rtnl lock. */
+static DEFINE_SPINLOCK(ser_lock);
 static LIST_HEAD(ser_list);
+static LIST_HEAD(ser_release_list);
 
 static bool ser_loop;
 module_param(ser_loop, bool, S_IRUGO);
@@ -308,6 +309,28 @@ static void ldisc_tx_wakeup(struct tty_s
 }
 
 
+static void ser_release(struct work_struct *work)
+{
+	struct list_head list;
+	struct ser_device *ser, *tmp;
+
+	spin_lock(&ser_lock);
+	list_replace_init(&ser_release_list, &list);
+	spin_unlock(&ser_lock);
+
+	if (!list_empty(&list)) {
+		rtnl_lock();
+		list_for_each_entry_safe(ser, tmp, &list, node) {
+			dev_close(ser->dev);
+			unregister_netdevice(ser->dev);
+			debugfs_deinit(ser);
+		}
+		rtnl_unlock();
+	}
+}
+
+static DECLARE_WORK(ser_release_work, ser_release);
+
 static int ldisc_open(struct tty_struct *tty)
 {
 	struct ser_device *ser;
@@ -321,6 +344,9 @@ static int ldisc_open(struct tty_struct
 	if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_TTY_CONFIG))
 		return -EPERM;
 
+	/* release devices to avoid name collision */
+	ser_release(NULL);
+
 	sprintf(name, "cf%s", tty->name);
 	dev = alloc_netdev(sizeof(*ser), name, caifdev_setup);
 	if (!dev)
@@ -341,7 +367,9 @@ static int ldisc_open(struct tty_struct
 		return -ENODEV;
 	}
 
+	spin_lock(&ser_lock);
 	list_add(&ser->node, &ser_list);
+	spin_unlock(&ser_lock);
 	rtnl_unlock();
 	netif_stop_queue(dev);
 	update_tty_status(ser);
@@ -351,19 +379,13 @@ static int ldisc_open(struct tty_struct
 static void ldisc_close(struct tty_struct *tty)
 {
 	struct ser_device *ser = tty->disc_data;
-	/* Remove may be called inside or outside of rtnl_lock */
-	int islocked = rtnl_is_locked();
 
-	if (!islocked)
-		rtnl_lock();
-	/* device is freed automagically by net-sysfs */
-	dev_close(ser->dev);
-	unregister_netdevice(ser->dev);
-	list_del(&ser->node);
-	debugfs_deinit(ser);
 	tty_kref_put(ser->tty);
-	if (!islocked)
-		rtnl_unlock();
+
+	spin_lock(&ser_lock);
+	list_move(&ser->node, &ser_release_list);
+	spin_unlock(&ser_lock);
+	schedule_work(&ser_release_work);
 }
 
 /* The line discipline structure. */
@@ -438,16 +460,11 @@ static int __init caif_ser_init(void)
 
 static void __exit caif_ser_exit(void)
 {
-	struct ser_device *ser = NULL;
-	struct list_head *node;
-	struct list_head *_tmp;
-
-	list_for_each_safe(node, _tmp, &ser_list) {
-		ser = list_entry(node, struct ser_device, node);
-		dev_close(ser->dev);
-		unregister_netdevice(ser->dev);
-		list_del(node);
-	}
+	spin_lock(&ser_lock);
+	list_splice(&ser_list, &ser_release_list);
+	spin_unlock(&ser_lock);
+	ser_release(NULL);
+	cancel_work_sync(&ser_release_work);
 	tty_unregister_ldisc(N_CAIF);
 	debugfs_remove_recursive(debugfsdir);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/at91_can.c linux-libre-3.11-rc7-gnu/drivers/net/can/at91_can.c
--- linux-libre-3.10-gnu/drivers/net/can/at91_can.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/at91_can.c	2013-08-25 20:43:22.000000000 -0400
@@ -1220,7 +1220,7 @@ static ssize_t at91_sysfs_set_mb0_id(str
 		goto out;
 	}
 
-	err = strict_strtoul(buf, 0, &can_id);
+	err = kstrtoul(buf, 0, &can_id);
 	if (err) {
 		ret = err;
 		goto out;
@@ -1264,8 +1264,6 @@ static const struct of_device_id at91_ca
 	}
 };
 MODULE_DEVICE_TABLE(of, at91_can_dt_ids);
-#else
-#define at91_can_dt_ids NULL
 #endif
 
 static const struct at91_devtype_data *at91_can_get_driver_data(struct platform_device *pdev)
@@ -1393,8 +1391,6 @@ static int at91_can_remove(struct platfo
 
 	unregister_netdev(dev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	iounmap(priv->reg_base);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1426,7 +1422,7 @@ static struct platform_driver at91_can_d
 	.driver = {
 		.name = KBUILD_MODNAME,
 		.owner = THIS_MODULE,
-		.of_match_table = at91_can_dt_ids,
+		.of_match_table = of_match_ptr(at91_can_dt_ids),
 	},
 	.id_table = at91_can_id_table,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/bfin_can.c linux-libre-3.11-rc7-gnu/drivers/net/can/bfin_can.c
--- linux-libre-3.10-gnu/drivers/net/can/bfin_can.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/bfin_can.c	2013-08-25 20:43:22.000000000 -0400
@@ -580,7 +580,7 @@ static int bfin_can_probe(struct platfor
 	priv->pin_list = pdata;
 	priv->can.clock.freq = get_sclk();
 
-	dev_set_drvdata(&pdev->dev, dev);
+	platform_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	dev->flags |= IFF_ECHO;	/* we support local echo */
@@ -613,7 +613,7 @@ exit:
 
 static int bfin_can_remove(struct platform_device *pdev)
 {
-	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct net_device *dev = platform_get_drvdata(pdev);
 	struct bfin_can_priv *priv = netdev_priv(dev);
 	struct resource *res;
 
@@ -621,8 +621,6 @@ static int bfin_can_remove(struct platfo
 
 	unregister_candev(dev);
 
-	dev_set_drvdata(&pdev->dev, NULL);
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, resource_size(res));
 
@@ -635,7 +633,7 @@ static int bfin_can_remove(struct platfo
 #ifdef CONFIG_PM
 static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg)
 {
-	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct net_device *dev = platform_get_drvdata(pdev);
 	struct bfin_can_priv *priv = netdev_priv(dev);
 	struct bfin_can_regs __iomem *reg = priv->membase;
 	int timeout = BFIN_CAN_TIMEOUT;
@@ -658,7 +656,7 @@ static int bfin_can_suspend(struct platf
 
 static int bfin_can_resume(struct platform_device *pdev)
 {
-	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct net_device *dev = platform_get_drvdata(pdev);
 	struct bfin_can_priv *priv = netdev_priv(dev);
 	struct bfin_can_regs __iomem *reg = priv->membase;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/cc770/cc770_isa.c linux-libre-3.11-rc7-gnu/drivers/net/can/cc770/cc770_isa.c
--- linux-libre-3.10-gnu/drivers/net/can/cc770/cc770_isa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/cc770/cc770_isa.c	2013-08-25 20:43:22.000000000 -0400
@@ -265,7 +265,7 @@ static int cc770_isa_probe(struct platfo
 	else
 		priv->clkout = COR_DEFAULT;
 
-	dev_set_drvdata(&pdev->dev, dev);
+	platform_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	err = register_cc770dev(dev);
@@ -293,12 +293,11 @@ static int cc770_isa_probe(struct platfo
 
 static int cc770_isa_remove(struct platform_device *pdev)
 {
-	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct net_device *dev = platform_get_drvdata(pdev);
 	struct cc770_priv *priv = netdev_priv(dev);
 	int idx = pdev->id;
 
 	unregister_cc770dev(dev);
-	dev_set_drvdata(&pdev->dev, NULL);
 
 	if (mem[idx]) {
 		iounmap(priv->reg_base);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/cc770/cc770_platform.c linux-libre-3.11-rc7-gnu/drivers/net/can/cc770/cc770_platform.c
--- linux-libre-3.10-gnu/drivers/net/can/cc770/cc770_platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/cc770/cc770_platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -216,7 +216,7 @@ static int cc770_platform_probe(struct p
 		 priv->reg_base, dev->irq, priv->can.clock.freq,
 		 priv->cpu_interface, priv->bus_config, priv->clkout);
 
-	dev_set_drvdata(&pdev->dev, dev);
+	platform_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	err = register_cc770dev(dev);
@@ -240,7 +240,7 @@ exit_release_mem:
 
 static int cc770_platform_remove(struct platform_device *pdev)
 {
-	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct net_device *dev = platform_get_drvdata(pdev);
 	struct cc770_priv *priv = netdev_priv(dev);
 	struct resource *mem;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/c_can/c_can_platform.c linux-libre-3.11-rc7-gnu/drivers/net/can/c_can/c_can_platform.c
--- linux-libre-3.10-gnu/drivers/net/can/c_can/c_can_platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/c_can/c_can_platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/pinctrl/consumer.h>
 
 #include <linux/can/dev.h>
 
@@ -114,7 +113,6 @@ static int c_can_plat_probe(struct platf
 	struct c_can_priv *priv;
 	const struct of_device_id *match;
 	const struct platform_device_id *id;
-	struct pinctrl *pinctrl;
 	struct resource *mem, *res;
 	int irq;
 	struct clk *clk;
@@ -131,11 +129,6 @@ static int c_can_plat_probe(struct platf
 		id = platform_get_device_id(pdev);
 	}
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl))
-		dev_warn(&pdev->dev,
-			"failed to configure pins from driver\n");
-
 	/* get the appropriate clk */
 	clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(clk)) {
@@ -201,8 +194,8 @@ static int c_can_plat_probe(struct platf
 			priv->instance = pdev->id;
 
 		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-		priv->raminit_ctrlreg =	devm_request_and_ioremap(&pdev->dev, res);
-		if (!priv->raminit_ctrlreg || priv->instance < 0)
+		priv->raminit_ctrlreg = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0)
 			dev_info(&pdev->dev, "control memory is not used for raminit\n");
 		else
 			priv->raminit = c_can_hw_raminit;
@@ -234,7 +227,6 @@ static int c_can_plat_probe(struct platf
 	return 0;
 
 exit_free_device:
-	platform_set_drvdata(pdev, NULL);
 	free_c_can_dev(dev);
 exit_iounmap:
 	iounmap(addr);
@@ -255,7 +247,6 @@ static int c_can_plat_remove(struct plat
 	struct resource *mem;
 
 	unregister_c_can_dev(dev);
-	platform_set_drvdata(pdev, NULL);
 
 	free_c_can_dev(dev);
 	iounmap(priv->base);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/flexcan.c linux-libre-3.11-rc7-gnu/drivers/net/can/flexcan.c
--- linux-libre-3.10-gnu/drivers/net/can/flexcan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/flexcan.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
 #include <linux/can/led.h>
-#include <linux/can/platform/flexcan.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/if_arp.h>
@@ -37,7 +36,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
-#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
 
 #define DRV_NAME			"flexcan"
 
@@ -212,6 +211,7 @@ struct flexcan_priv {
 	struct clk *clk_per;
 	struct flexcan_platform_data *pdata;
 	const struct flexcan_devtype_data *devtype_data;
+	struct regulator *reg_xceiver;
 };
 
 static struct flexcan_devtype_data fsl_p1010_devtype_data = {
@@ -259,15 +259,6 @@ static inline void flexcan_write(u32 val
 }
 #endif
 
-/*
- * Swtich transceiver on or off
- */
-static void flexcan_transceiver_switch(const struct flexcan_priv *priv, int on)
-{
-	if (priv->pdata && priv->pdata->transceiver_switch)
-		priv->pdata->transceiver_switch(on);
-}
-
 static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv,
 					      u32 reg_esr)
 {
@@ -800,7 +791,11 @@ static int flexcan_chip_start(struct net
 	if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
 		flexcan_write(0x0, &regs->rxfgmask);
 
-	flexcan_transceiver_switch(priv, 1);
+	if (priv->reg_xceiver)	{
+		err = regulator_enable(priv->reg_xceiver);
+		if (err)
+			goto out;
+	}
 
 	/* synchronize with the can bus */
 	reg_mcr = flexcan_read(&regs->mcr);
@@ -843,7 +838,8 @@ static void flexcan_chip_stop(struct net
 	reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
 	flexcan_write(reg, &regs->mcr);
 
-	flexcan_transceiver_switch(priv, 0);
+	if (priv->reg_xceiver)
+		regulator_disable(priv->reg_xceiver);
 	priv->can.state = CAN_STATE_STOPPED;
 
 	return;
@@ -1004,16 +1000,11 @@ static int flexcan_probe(struct platform
 	struct flexcan_priv *priv;
 	struct resource *mem;
 	struct clk *clk_ipg = NULL, *clk_per = NULL;
-	struct pinctrl *pinctrl;
 	void __iomem *base;
 	resource_size_t mem_size;
 	int err, irq;
 	u32 clock_freq = 0;
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl))
-		return PTR_ERR(pinctrl);
-
 	if (pdev->dev.of_node)
 		of_property_read_u32(pdev->dev.of_node,
 						"clock-frequency", &clock_freq);
@@ -1090,6 +1081,10 @@ static int flexcan_probe(struct platform
 	priv->pdata = pdev->dev.platform_data;
 	priv->devtype_data = devtype_data;
 
+	priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver");
+	if (IS_ERR(priv->reg_xceiver))
+		priv->reg_xceiver = NULL;
+
 	netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
 
 	dev_set_drvdata(&pdev->dev, dev);
@@ -1127,7 +1122,6 @@ static int flexcan_remove(struct platfor
 	struct resource *mem;
 
 	unregister_flexcandev(dev);
-	platform_set_drvdata(pdev, NULL);
 	iounmap(priv->base);
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1138,10 +1132,10 @@ static int flexcan_remove(struct platfor
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int flexcan_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int flexcan_suspend(struct device *device)
 {
-	struct net_device *dev = platform_get_drvdata(pdev);
+	struct net_device *dev = dev_get_drvdata(device);
 	struct flexcan_priv *priv = netdev_priv(dev);
 
 	flexcan_chip_disable(priv);
@@ -1155,9 +1149,9 @@ static int flexcan_suspend(struct platfo
 	return 0;
 }
 
-static int flexcan_resume(struct platform_device *pdev)
+static int flexcan_resume(struct device *device)
 {
-	struct net_device *dev = platform_get_drvdata(pdev);
+	struct net_device *dev = dev_get_drvdata(device);
 	struct flexcan_priv *priv = netdev_priv(dev);
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
@@ -1169,21 +1163,19 @@ static int flexcan_resume(struct platfor
 
 	return 0;
 }
-#else
-#define flexcan_suspend NULL
-#define flexcan_resume NULL
-#endif
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume);
 
 static struct platform_driver flexcan_driver = {
 	.driver = {
 		.name = DRV_NAME,
 		.owner = THIS_MODULE,
+		.pm = &flexcan_pm_ops,
 		.of_match_table = flexcan_of_match,
 	},
 	.probe = flexcan_probe,
 	.remove = flexcan_remove,
-	.suspend = flexcan_suspend,
-	.resume = flexcan_resume,
 	.id_table = flexcan_id_table,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/grcan.c linux-libre-3.11-rc7-gnu/drivers/net/can/grcan.c
--- linux-libre-3.10-gnu/drivers/net/can/grcan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/grcan.c	2013-08-25 20:43:22.000000000 -0400
@@ -1646,7 +1646,7 @@ static int grcan_setup_netdev(struct pla
 	if (err)
 		goto exit_free_candev;
 
-	dev_set_drvdata(&ofdev->dev, dev);
+	platform_set_drvdata(ofdev, dev);
 
 	/* Reset device to allow bit-timing to be set. No need to call
 	 * grcan_reset at this stage. That is done in grcan_open.
@@ -1683,10 +1683,9 @@ static int grcan_probe(struct platform_d
 	}
 
 	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
-	base = devm_request_and_ioremap(&ofdev->dev, res);
-	if (!base) {
-		dev_err(&ofdev->dev, "couldn't map IO resource\n");
-		err = -EADDRNOTAVAIL;
+	base = devm_ioremap_resource(&ofdev->dev, res);
+	if (IS_ERR(base)) {
+		err = PTR_ERR(base);
 		goto exit_error;
 	}
 
@@ -1716,13 +1715,12 @@ exit_error:
 
 static int grcan_remove(struct platform_device *ofdev)
 {
-	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct net_device *dev = platform_get_drvdata(ofdev);
 	struct grcan_priv *priv = netdev_priv(dev);
 
 	unregister_candev(dev); /* Will in turn call grcan_close */
 
 	irq_dispose_mapping(dev->irq);
-	dev_set_drvdata(&ofdev->dev, NULL);
 	netif_napi_del(&priv->napi);
 	free_candev(dev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/janz-ican3.c linux-libre-3.11-rc7-gnu/drivers/net/can/janz-ican3.c
--- linux-libre-3.10-gnu/drivers/net/can/janz-ican3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/janz-ican3.c	2013-08-25 20:43:22.000000000 -0400
@@ -1734,7 +1734,7 @@ static ssize_t ican3_sysfs_set_term(stru
 	unsigned long enable;
 	int ret;
 
-	if (strict_strtoul(buf, 0, &enable))
+	if (kstrtoul(buf, 0, &enable))
 		return -EINVAL;
 
 	ret = ican3_set_termination(mod, enable);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/can/Kconfig
--- linux-libre-3.10-gnu/drivers/net/can/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -102,12 +102,9 @@ config CAN_JANZ_ICAN3
 	  This driver can also be built as a module. If so, the module will be
 	  called janz-ican3.ko.
 
-config HAVE_CAN_FLEXCAN
-	bool
-
 config CAN_FLEXCAN
 	tristate "Support for Freescale FLEXCAN based chips"
-	depends on HAVE_CAN_FLEXCAN
+	depends on ARM || PPC
 	---help---
 	  Say Y here if you want to support for Freescale FlexCAN.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/led.c linux-libre-3.11-rc7-gnu/drivers/net/can/led.c
--- linux-libre-3.10-gnu/drivers/net/can/led.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/led.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,9 +88,9 @@ EXPORT_SYMBOL_GPL(devm_can_led_init);
 
 /* NETDEV rename notifier to rename the associated led triggers too */
 static int can_led_notifier(struct notifier_block *nb, unsigned long msg,
-			void *data)
+			    void *ptr)
 {
-	struct net_device *netdev = data;
+	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
 	struct can_priv *priv = safe_candev_priv(netdev);
 	char name[CAN_LED_NAME_SZ];
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/mscan/mpc5xxx_can.c linux-libre-3.11-rc7-gnu/drivers/net/can/mscan/mpc5xxx_can.c
--- linux-libre-3.10-gnu/drivers/net/can/mscan/mpc5xxx_can.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/mscan/mpc5xxx_can.c	2013-08-25 20:43:22.000000000 -0400
@@ -302,7 +302,7 @@ static int mpc5xxx_can_probe(struct plat
 		goto exit_free_mscan;
 	}
 
-	dev_set_drvdata(&ofdev->dev, dev);
+	platform_set_drvdata(ofdev, dev);
 
 	dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n",
 		 priv->reg_base, dev->irq, priv->can.clock.freq);
@@ -321,11 +321,9 @@ exit_unmap_mem:
 
 static int mpc5xxx_can_remove(struct platform_device *ofdev)
 {
-	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct net_device *dev = platform_get_drvdata(ofdev);
 	struct mscan_priv *priv = netdev_priv(dev);
 
-	dev_set_drvdata(&ofdev->dev, NULL);
-
 	unregister_mscandev(dev);
 	iounmap(priv->reg_base);
 	irq_dispose_mapping(dev->irq);
@@ -338,7 +336,7 @@ static int mpc5xxx_can_remove(struct pla
 static struct mscan_regs saved_regs;
 static int mpc5xxx_can_suspend(struct platform_device *ofdev, pm_message_t state)
 {
-	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct net_device *dev = platform_get_drvdata(ofdev);
 	struct mscan_priv *priv = netdev_priv(dev);
 	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
 
@@ -349,7 +347,7 @@ static int mpc5xxx_can_suspend(struct pl
 
 static int mpc5xxx_can_resume(struct platform_device *ofdev)
 {
-	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct net_device *dev = platform_get_drvdata(ofdev);
 	struct mscan_priv *priv = netdev_priv(dev);
 	struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/sja1000/sja1000_isa.c linux-libre-3.11-rc7-gnu/drivers/net/can/sja1000/sja1000_isa.c
--- linux-libre-3.10-gnu/drivers/net/can/sja1000/sja1000_isa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/sja1000/sja1000_isa.c	2013-08-25 20:43:22.000000000 -0400
@@ -197,7 +197,7 @@ static int sja1000_isa_probe(struct plat
 	else
 		priv->cdr = CDR_DEFAULT;
 
-	dev_set_drvdata(&pdev->dev, dev);
+	platform_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	err = register_sja1000dev(dev);
@@ -225,12 +225,11 @@ static int sja1000_isa_probe(struct plat
 
 static int sja1000_isa_remove(struct platform_device *pdev)
 {
-	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct net_device *dev = platform_get_drvdata(pdev);
 	struct sja1000_priv *priv = netdev_priv(dev);
 	int idx = pdev->id;
 
 	unregister_sja1000dev(dev);
-	dev_set_drvdata(&pdev->dev, NULL);
 
 	if (mem[idx]) {
 		iounmap(priv->reg_base);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/sja1000/sja1000_of_platform.c linux-libre-3.11-rc7-gnu/drivers/net/can/sja1000/sja1000_of_platform.c
--- linux-libre-3.10-gnu/drivers/net/can/sja1000/sja1000_of_platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/sja1000/sja1000_of_platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -72,13 +72,11 @@ static void sja1000_ofp_write_reg(const
 
 static int sja1000_ofp_remove(struct platform_device *ofdev)
 {
-	struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+	struct net_device *dev = platform_get_drvdata(ofdev);
 	struct sja1000_priv *priv = netdev_priv(dev);
 	struct device_node *np = ofdev->dev.of_node;
 	struct resource res;
 
-	dev_set_drvdata(&ofdev->dev, NULL);
-
 	unregister_sja1000dev(dev);
 	free_sja1000dev(dev);
 	iounmap(priv->reg_base);
@@ -181,7 +179,7 @@ static int sja1000_ofp_probe(struct plat
 		 priv->reg_base, dev->irq, priv->can.clock.freq,
 		 priv->ocr, priv->cdr);
 
-	dev_set_drvdata(&ofdev->dev, dev);
+	platform_set_drvdata(ofdev, dev);
 	SET_NETDEV_DEV(dev, &ofdev->dev);
 
 	err = register_sja1000dev(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/sja1000/sja1000_platform.c linux-libre-3.11-rc7-gnu/drivers/net/can/sja1000/sja1000_platform.c
--- linux-libre-3.10-gnu/drivers/net/can/sja1000/sja1000_platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/sja1000/sja1000_platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -135,7 +135,7 @@ static int sp_probe(struct platform_devi
 		break;
 	}
 
-	dev_set_drvdata(&pdev->dev, dev);
+	platform_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	err = register_sja1000dev(dev);
@@ -161,12 +161,11 @@ static int sp_probe(struct platform_devi
 
 static int sp_remove(struct platform_device *pdev)
 {
-	struct net_device *dev = dev_get_drvdata(&pdev->dev);
+	struct net_device *dev = platform_get_drvdata(pdev);
 	struct sja1000_priv *priv = netdev_priv(dev);
 	struct resource *res;
 
 	unregister_sja1000dev(dev);
-	dev_set_drvdata(&pdev->dev, NULL);
 
 	if (priv->reg_base)
 		iounmap(priv->reg_base);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/slcan.c linux-libre-3.11-rc7-gnu/drivers/net/can/slcan.c
--- linux-libre-3.10-gnu/drivers/net/can/slcan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/slcan.c	2013-08-25 20:43:22.000000000 -0400
@@ -161,7 +161,7 @@ static void slc_bump(struct slcan *sl)
 
 	sl->rbuff[dlc_pos] = 0; /* terminate can_id string */
 
-	if (strict_strtoul(sl->rbuff+1, 16, &ultmp))
+	if (kstrtoul(sl->rbuff+1, 16, &ultmp))
 		return;
 
 	cf.can_id = ultmp;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/softing/softing_main.c linux-libre-3.11-rc7-gnu/drivers/net/can/softing/softing_main.c
--- linux-libre-3.10-gnu/drivers/net/can/softing/softing_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/softing/softing_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -594,7 +594,7 @@ static ssize_t store_output(struct devic
 	unsigned long val;
 	int ret;
 
-	ret = strict_strtoul(buf, 0, &val);
+	ret = kstrtoul(buf, 0, &val);
 	if (ret < 0)
 		return ret;
 	val &= 0xFF;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/ti_hecc.c linux-libre-3.11-rc7-gnu/drivers/net/can/ti_hecc.c
--- linux-libre-3.10-gnu/drivers/net/can/ti_hecc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/ti_hecc.c	2013-08-25 20:43:22.000000000 -0400
@@ -1001,7 +1001,6 @@ static int ti_hecc_remove(struct platfor
 	iounmap(priv->base);
 	release_mem_region(res->start, resource_size(res));
 	free_candev(ndev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/usb/esd_usb2.c linux-libre-3.11-rc7-gnu/drivers/net/can/usb/esd_usb2.c
--- linux-libre-3.10-gnu/drivers/net/can/usb/esd_usb2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/usb/esd_usb2.c	2013-08-25 20:43:22.000000000 -0400
@@ -412,10 +412,20 @@ static void esd_usb2_read_bulk_callback(
 
 		switch (msg->msg.hdr.cmd) {
 		case CMD_CAN_RX:
+			if (msg->msg.rx.net >= dev->net_count) {
+				dev_err(dev->udev->dev.parent, "format error\n");
+				break;
+			}
+
 			esd_usb2_rx_can_msg(dev->nets[msg->msg.rx.net], msg);
 			break;
 
 		case CMD_CAN_TX:
+			if (msg->msg.txdone.net >= dev->net_count) {
+				dev_err(dev->udev->dev.parent, "format error\n");
+				break;
+			}
+
 			esd_usb2_tx_done_msg(dev->nets[msg->msg.txdone.net],
 					     msg);
 			break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/usb/peak_usb/pcan_usb.c linux-libre-3.11-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_usb.c
--- linux-libre-3.10-gnu/drivers/net/can/usb/peak_usb/pcan_usb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/usb/peak_usb/pcan_usb.c	2013-08-25 20:43:22.000000000 -0400
@@ -649,7 +649,7 @@ static int pcan_usb_decode_data(struct p
 		if ((mc->ptr + rec_len) > mc->end)
 			goto decode_failed;
 
-		memcpy(cf->data, mc->ptr, rec_len);
+		memcpy(cf->data, mc->ptr, cf->can_dlc);
 		mc->ptr += rec_len;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/can/usb/usb_8dev.c linux-libre-3.11-rc7-gnu/drivers/net/can/usb/usb_8dev.c
--- linux-libre-3.10-gnu/drivers/net/can/usb/usb_8dev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/can/usb/usb_8dev.c	2013-08-25 20:43:22.000000000 -0400
@@ -779,6 +779,7 @@ static int usb_8dev_start(struct usb_8de
 			usb_unanchor_urb(urb);
 			usb_free_coherent(priv->udev, RX_BUFFER_SIZE, buf,
 					  urb->transfer_dma);
+			usb_free_urb(urb);
 			break;
 		}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/dummy.c linux-libre-3.11-rc7-gnu/drivers/net/dummy.c
--- linux-libre-3.10-gnu/drivers/net/dummy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/dummy.c	2013-08-25 20:43:22.000000000 -0400
@@ -185,6 +185,8 @@ static int __init dummy_init_module(void
 
 	rtnl_lock();
 	err = __rtnl_link_register(&dummy_link_ops);
+	if (err < 0)
+		goto out;
 
 	for (i = 0; i < numdummies && !err; i++) {
 		err = dummy_init_one();
@@ -192,6 +194,8 @@ static int __init dummy_init_module(void
 	}
 	if (err < 0)
 		__rtnl_link_unregister(&dummy_link_ops);
+
+out:
 	rtnl_unlock();
 
 	return err;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/3com/3c509.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/3com/3c509.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/3com/3c509.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/3com/3c509.c	2013-08-25 20:43:22.000000000 -0400
@@ -723,25 +723,6 @@ el3_start_xmit(struct sk_buff *skb, stru
 		pr_debug("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
 			   dev->name, skb->len, inw(ioaddr + EL3_STATUS));
 	}
-#if 0
-#ifndef final_version
-	{	/* Error-checking code, delete someday. */
-		ushort status = inw(ioaddr + EL3_STATUS);
-		if (status & 0x0001 && 		/* IRQ line active, missed one. */
-		    inw(ioaddr + EL3_STATUS) & 1) { 			/* Make sure. */
-			pr_debug("%s: Missed interrupt, status then %04x now %04x"
-				   "  Tx %2.2x Rx %4.4x.\n", dev->name, status,
-				   inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
-				   inw(ioaddr + RX_STATUS));
-			/* Fake interrupt trigger by masking, acknowledge interrupts. */
-			outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
-			outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
-				 ioaddr + EL3_CMD);
-			outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
-		}
-	}
-#endif
-#endif
 	/*
 	 *	We lock the driver against other processors. Note
 	 *	we don't need to lock versus the IRQ as we suspended
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/3com/3c59x.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/3com/3c59x.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/3com/3c59x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/3com/3c59x.c	2013-08-25 20:43:22.000000000 -0400
@@ -1012,10 +1012,8 @@ static int vortex_init_one(struct pci_de
 		goto out;
 
 	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc < 0) {
-		pci_disable_device(pdev);
-		goto out;
-	}
+	if (rc < 0)
+		goto out_disable;
 
 	unit = vortex_cards_found;
 
@@ -1032,23 +1030,24 @@ static int vortex_init_one(struct pci_de
 	if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
 		ioaddr = pci_iomap(pdev, 0, 0);
 	if (!ioaddr) {
-		pci_release_regions(pdev);
-		pci_disable_device(pdev);
 		rc = -ENOMEM;
-		goto out;
+		goto out_release;
 	}
 
 	rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
 			   ent->driver_data, unit);
-	if (rc < 0) {
-		pci_iounmap(pdev, ioaddr);
-		pci_release_regions(pdev);
-		pci_disable_device(pdev);
-		goto out;
-	}
+	if (rc < 0)
+		goto out_iounmap;
 
 	vortex_cards_found++;
+	goto out;
 
+out_iounmap:
+	pci_iounmap(pdev, ioaddr);
+out_release:
+	pci_release_regions(pdev);
+out_disable:
+	pci_disable_device(pdev);
 out:
 	return rc;
 }
@@ -1473,7 +1472,7 @@ static int vortex_probe1(struct device *
 
 	if (pdev) {
 		vp->pm_state_valid = 1;
- 		pci_save_state(VORTEX_PCI(vp));
+		pci_save_state(pdev);
  		acpi_set_WOL(dev);
 	}
 	retval = register_netdev(dev);
@@ -3233,21 +3232,20 @@ static void vortex_remove_one(struct pci
 	vp = netdev_priv(dev);
 
 	if (vp->cb_fn_base)
-		pci_iounmap(VORTEX_PCI(vp), vp->cb_fn_base);
+		pci_iounmap(pdev, vp->cb_fn_base);
 
 	unregister_netdev(dev);
 
-	if (VORTEX_PCI(vp)) {
-		pci_set_power_state(VORTEX_PCI(vp), PCI_D0);	/* Go active */
-		if (vp->pm_state_valid)
-			pci_restore_state(VORTEX_PCI(vp));
-		pci_disable_device(VORTEX_PCI(vp));
-	}
+	pci_set_power_state(pdev, PCI_D0);	/* Go active */
+	if (vp->pm_state_valid)
+		pci_restore_state(pdev);
+	pci_disable_device(pdev);
+
 	/* Should really use issue_and_wait() here */
 	iowrite16(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
 	     vp->ioaddr + EL3_CMD);
 
-	pci_iounmap(VORTEX_PCI(vp), vp->ioaddr);
+	pci_iounmap(pdev, vp->ioaddr);
 
 	pci_free_consistent(pdev,
 						sizeof(struct boom_rx_desc) * RX_RING_SIZE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/3com/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/3com/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/3com/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/3com/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -67,7 +67,6 @@ config PCMCIA_3C589
 config VORTEX
 	tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support"
 	depends on (PCI || EISA) && HAS_IOPORT
-	select NET_CORE
 	select MII
 	---help---
 	  This option enables driver support for a large number of 10Mbps and
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/8390/ne2k-pci.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/8390/ne2k-pci.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/8390/ne2k-pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/8390/ne2k-pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -676,7 +676,7 @@ static int ne2k_pci_resume (struct pci_d
 	struct net_device *dev = pci_get_drvdata (pdev);
 	int rc;
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
 	rc = pci_enable_device(pdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/8390/ne.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/8390/ne.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/8390/ne.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/8390/ne.c	2013-08-25 20:43:22.000000000 -0400
@@ -849,7 +849,6 @@ static int ne_drv_remove(struct platform
 		free_irq(dev->irq, dev);
 		release_region(dev->base_addr, NE_IO_EXTENT);
 		free_netdev(dev);
-		platform_set_drvdata(pdev, NULL);
 	}
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/adaptec/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/adaptec/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/adaptec/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/adaptec/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@ config ADAPTEC_STARFIRE
 	tristate "Adaptec Starfire/DuraLAN support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/adi/bfin_mac.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/adi/bfin_mac.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/adi/bfin_mac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/adi/bfin_mac.c	2013-08-25 20:43:22.000000000 -0400
@@ -1719,7 +1719,6 @@ out_err_mii_probe:
 	mdiobus_unregister(lp->mii_bus);
 	mdiobus_free(lp->mii_bus);
 out_err_probe_mac:
-	platform_set_drvdata(pdev, NULL);
 	free_netdev(ndev);
 
 	return rc;
@@ -1732,8 +1731,6 @@ static int bfin_mac_remove(struct platfo
 
 	bfin_phc_release(lp);
 
-	platform_set_drvdata(pdev, NULL);
-
 	lp->mii_bus->priv = NULL;
 
 	unregister_netdev(ndev);
@@ -1868,7 +1865,6 @@ static int bfin_mii_bus_remove(struct pl
 	struct bfin_mii_bus_platform_data *mii_bus_pd =
 		dev_get_platdata(&pdev->dev);
 
-	platform_set_drvdata(pdev, NULL);
 	mdiobus_unregister(miibus);
 	kfree(miibus->irq);
 	mdiobus_free(miibus);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/adi/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/adi/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/adi/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/adi/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,6 @@ config BFIN_MAC
 	tristate "Blackfin on-chip MAC support"
 	depends on (BF516 || BF518 || BF526 || BF527 || BF536 || BF537)
 	select CRC32
-	select NET_CORE
 	select MII
 	select PHYLIB
 	select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/aeroflex/greth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/aeroflex/greth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/aeroflex/greth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/aeroflex/greth.c	2013-08-25 20:43:22.000000000 -0400
@@ -1565,7 +1565,7 @@ error1:
 
 static int greth_of_remove(struct platform_device *of_dev)
 {
-	struct net_device *ndev = dev_get_drvdata(&of_dev->dev);
+	struct net_device *ndev = platform_get_drvdata(of_dev);
 	struct greth_private *greth = netdev_priv(ndev);
 
 	/* Free descriptor areas */
@@ -1573,8 +1573,6 @@ static int greth_of_remove(struct platfo
 
 	dma_free_coherent(&of_dev->dev, 1024, greth->tx_bd_base, greth->tx_bd_base_phys);
 
-	dev_set_drvdata(&of_dev->dev, NULL);
-
 	if (greth->phy)
 		phy_stop(greth->phy);
 	mdiobus_unregister(greth->mdio);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/allwinner/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/allwinner/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/allwinner/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/allwinner/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,37 @@
+#
+# Allwinner device configuration
+#
+
+config NET_VENDOR_ALLWINNER
+	bool "Allwinner devices"
+	default y
+
+	depends on ARCH_SUNXI
+	---help---
+	  If you have a network (Ethernet) card belonging to this
+	  class, say Y and read the Ethernet-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+	  Note that the answer to this question doesn't directly
+	  affect the kernel: saying N will just cause the configurator
+	  to skip all the questions about Allwinner cards. If you say Y,
+	  you will be asked for your specific card in the following
+	  questions.
+
+if NET_VENDOR_ALLWINNER
+
+config SUN4I_EMAC
+        tristate "Allwinner A10 EMAC support"
+	depends on ARCH_SUNXI
+	depends on OF
+	select CRC32
+	select MII
+	select PHYLIB
+	select MDIO_SUN4I
+        ---help---
+          Support for Allwinner A10 EMAC ethernet driver.
+
+          To compile this driver as a module, choose M here.  The module
+          will be called sun4i-emac.
+
+endif # NET_VENDOR_ALLWINNER
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/allwinner/Makefile linux-libre-3.11-rc7-gnu/drivers/net/ethernet/allwinner/Makefile
--- linux-libre-3.10-gnu/drivers/net/ethernet/allwinner/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/allwinner/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,5 @@
+#
+# Makefile for the Allwinner device drivers.
+#
+
+obj-$(CONFIG_SUN4I_EMAC) += sun4i-emac.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/allwinner/sun4i-emac.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/allwinner/sun4i-emac.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/allwinner/sun4i-emac.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/allwinner/sun4i-emac.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,954 @@
+/*
+ * Allwinner EMAC Fast Ethernet driver for Linux.
+ *
+ * Copyright 2012-2013 Stefan Roese <sr@denx.de>
+ * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on the Linux driver provided by Allwinner:
+ * Copyright (C) 1997  Sten Wang
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/phy.h>
+
+#include "sun4i-emac.h"
+
+#define DRV_NAME		"sun4i-emac"
+#define DRV_VERSION		"1.02"
+
+#define EMAC_MAX_FRAME_LEN	0x0600
+
+/* Transmit timeout, default 5 seconds. */
+static int watchdog = 5000;
+module_param(watchdog, int, 0400);
+MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
+
+/* EMAC register address locking.
+ *
+ * The EMAC uses an address register to control where data written
+ * to the data register goes. This means that the address register
+ * must be preserved over interrupts or similar calls.
+ *
+ * During interrupt and other critical calls, a spinlock is used to
+ * protect the system, but the calls themselves save the address
+ * in the address register in case they are interrupting another
+ * access to the device.
+ *
+ * For general accesses a lock is provided so that calls which are
+ * allowed to sleep are serialised so that the address register does
+ * not need to be saved. This lock also serves to serialise access
+ * to the EEPROM and PHY access registers which are shared between
+ * these two devices.
+ */
+
+/* The driver supports the original EMACE, and now the two newer
+ * devices, EMACA and EMACB.
+ */
+
+struct emac_board_info {
+	struct clk		*clk;
+	struct device		*dev;
+	struct platform_device	*pdev;
+	spinlock_t		lock;
+	void __iomem		*membase;
+	u32			msg_enable;
+	struct net_device	*ndev;
+	struct sk_buff		*skb_last;
+	u16			tx_fifo_stat;
+
+	int			emacrx_completed_flag;
+
+	struct phy_device	*phy_dev;
+	struct device_node	*phy_node;
+	unsigned int		link;
+	unsigned int		speed;
+	unsigned int		duplex;
+
+	phy_interface_t		phy_interface;
+};
+
+static void emac_update_speed(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	unsigned int reg_val;
+
+	/* set EMAC SPEED, depend on PHY  */
+	reg_val = readl(db->membase + EMAC_MAC_SUPP_REG);
+	reg_val &= ~(0x1 << 8);
+	if (db->speed == SPEED_100)
+		reg_val |= 1 << 8;
+	writel(reg_val, db->membase + EMAC_MAC_SUPP_REG);
+}
+
+static void emac_update_duplex(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	unsigned int reg_val;
+
+	/* set duplex depend on phy */
+	reg_val = readl(db->membase + EMAC_MAC_CTL1_REG);
+	reg_val &= ~EMAC_MAC_CTL1_DUPLEX_EN;
+	if (db->duplex)
+		reg_val |= EMAC_MAC_CTL1_DUPLEX_EN;
+	writel(reg_val, db->membase + EMAC_MAC_CTL1_REG);
+}
+
+static void emac_handle_link_change(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	struct phy_device *phydev = db->phy_dev;
+	unsigned long flags;
+	int status_change = 0;
+
+	if (phydev->link) {
+		if (db->speed != phydev->speed) {
+			spin_lock_irqsave(&db->lock, flags);
+			db->speed = phydev->speed;
+			emac_update_speed(dev);
+			spin_unlock_irqrestore(&db->lock, flags);
+			status_change = 1;
+		}
+
+		if (db->duplex != phydev->duplex) {
+			spin_lock_irqsave(&db->lock, flags);
+			db->duplex = phydev->duplex;
+			emac_update_duplex(dev);
+			spin_unlock_irqrestore(&db->lock, flags);
+			status_change = 1;
+		}
+	}
+
+	if (phydev->link != db->link) {
+		if (!phydev->link) {
+			db->speed = 0;
+			db->duplex = -1;
+		}
+		db->link = phydev->link;
+
+		status_change = 1;
+	}
+
+	if (status_change)
+		phy_print_status(phydev);
+}
+
+static int emac_mdio_probe(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+
+	/* to-do: PHY interrupts are currently not supported */
+
+	/* attach the mac to the phy */
+	db->phy_dev = of_phy_connect(db->ndev, db->phy_node,
+				     &emac_handle_link_change, 0,
+				     db->phy_interface);
+	if (!db->phy_dev) {
+		netdev_err(db->ndev, "could not find the PHY\n");
+		return -ENODEV;
+	}
+
+	/* mask with MAC supported features */
+	db->phy_dev->supported &= PHY_BASIC_FEATURES;
+	db->phy_dev->advertising = db->phy_dev->supported;
+
+	db->link = 0;
+	db->speed = 0;
+	db->duplex = -1;
+
+	return 0;
+}
+
+static void emac_mdio_remove(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+
+	phy_disconnect(db->phy_dev);
+	db->phy_dev = NULL;
+}
+
+static void emac_reset(struct emac_board_info *db)
+{
+	dev_dbg(db->dev, "resetting device\n");
+
+	/* RESET device */
+	writel(0, db->membase + EMAC_CTL_REG);
+	udelay(200);
+	writel(EMAC_CTL_RESET, db->membase + EMAC_CTL_REG);
+	udelay(200);
+}
+
+static void emac_outblk_32bit(void __iomem *reg, void *data, int count)
+{
+	writesl(reg, data, round_up(count, 4) / 4);
+}
+
+static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
+{
+	readsl(reg, data, round_up(count, 4) / 4);
+}
+
+static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct emac_board_info *dm = netdev_priv(dev);
+	struct phy_device *phydev = dm->phy_dev;
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_mii_ioctl(phydev, rq, cmd);
+}
+
+/* ethtool ops */
+static void emac_get_drvinfo(struct net_device *dev,
+			      struct ethtool_drvinfo *info)
+{
+	strlcpy(info->driver, DRV_NAME, sizeof(DRV_NAME));
+	strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION));
+	strlcpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info));
+}
+
+static int emac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct emac_board_info *dm = netdev_priv(dev);
+	struct phy_device *phydev = dm->phy_dev;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_ethtool_gset(phydev, cmd);
+}
+
+static int emac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct emac_board_info *dm = netdev_priv(dev);
+	struct phy_device *phydev = dm->phy_dev;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_ethtool_sset(phydev, cmd);
+}
+
+static const struct ethtool_ops emac_ethtool_ops = {
+	.get_drvinfo	= emac_get_drvinfo,
+	.get_settings	= emac_get_settings,
+	.set_settings	= emac_set_settings,
+	.get_link	= ethtool_op_get_link,
+};
+
+static unsigned int emac_setup(struct net_device *ndev)
+{
+	struct emac_board_info *db = netdev_priv(ndev);
+	unsigned int reg_val;
+
+	/* set up TX */
+	reg_val = readl(db->membase + EMAC_TX_MODE_REG);
+
+	writel(reg_val | EMAC_TX_MODE_ABORTED_FRAME_EN,
+		db->membase + EMAC_TX_MODE_REG);
+
+	/* set up RX */
+	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+
+	writel(reg_val | EMAC_RX_CTL_PASS_LEN_OOR_EN |
+		EMAC_RX_CTL_ACCEPT_UNICAST_EN | EMAC_RX_CTL_DA_FILTER_EN |
+		EMAC_RX_CTL_ACCEPT_MULTICAST_EN |
+		EMAC_RX_CTL_ACCEPT_BROADCAST_EN,
+		db->membase + EMAC_RX_CTL_REG);
+
+	/* set MAC */
+	/* set MAC CTL0 */
+	reg_val = readl(db->membase + EMAC_MAC_CTL0_REG);
+	writel(reg_val | EMAC_MAC_CTL0_RX_FLOW_CTL_EN |
+		EMAC_MAC_CTL0_TX_FLOW_CTL_EN,
+		db->membase + EMAC_MAC_CTL0_REG);
+
+	/* set MAC CTL1 */
+	reg_val = readl(db->membase + EMAC_MAC_CTL1_REG);
+	reg_val |= EMAC_MAC_CTL1_LEN_CHECK_EN;
+	reg_val |= EMAC_MAC_CTL1_CRC_EN;
+	reg_val |= EMAC_MAC_CTL1_PAD_EN;
+	writel(reg_val, db->membase + EMAC_MAC_CTL1_REG);
+
+	/* set up IPGT */
+	writel(EMAC_MAC_IPGT_FULL_DUPLEX, db->membase + EMAC_MAC_IPGT_REG);
+
+	/* set up IPGR */
+	writel((EMAC_MAC_IPGR_IPG1 << 8) | EMAC_MAC_IPGR_IPG2,
+		db->membase + EMAC_MAC_IPGR_REG);
+
+	/* set up Collison window */
+	writel((EMAC_MAC_CLRT_COLLISION_WINDOW << 8) | EMAC_MAC_CLRT_RM,
+		db->membase + EMAC_MAC_CLRT_REG);
+
+	/* set up Max Frame Length */
+	writel(EMAC_MAX_FRAME_LEN,
+		db->membase + EMAC_MAC_MAXF_REG);
+
+	return 0;
+}
+
+static unsigned int emac_powerup(struct net_device *ndev)
+{
+	struct emac_board_info *db = netdev_priv(ndev);
+	unsigned int reg_val;
+
+	/* initial EMAC */
+	/* flush RX FIFO */
+	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+	reg_val |= 0x8;
+	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+	udelay(1);
+
+	/* initial MAC */
+	/* soft reset MAC */
+	reg_val = readl(db->membase + EMAC_MAC_CTL0_REG);
+	reg_val &= ~EMAC_MAC_CTL0_SOFT_RESET;
+	writel(reg_val, db->membase + EMAC_MAC_CTL0_REG);
+
+	/* set MII clock */
+	reg_val = readl(db->membase + EMAC_MAC_MCFG_REG);
+	reg_val &= (~(0xf << 2));
+	reg_val |= (0xD << 2);
+	writel(reg_val, db->membase + EMAC_MAC_MCFG_REG);
+
+	/* clear RX counter */
+	writel(0x0, db->membase + EMAC_RX_FBC_REG);
+
+	/* disable all interrupt and clear interrupt status */
+	writel(0, db->membase + EMAC_INT_CTL_REG);
+	reg_val = readl(db->membase + EMAC_INT_STA_REG);
+	writel(reg_val, db->membase + EMAC_INT_STA_REG);
+
+	udelay(1);
+
+	/* set up EMAC */
+	emac_setup(ndev);
+
+	/* set mac_address to chip */
+	writel(ndev->dev_addr[0] << 16 | ndev->dev_addr[1] << 8 | ndev->
+	       dev_addr[2], db->membase + EMAC_MAC_A1_REG);
+	writel(ndev->dev_addr[3] << 16 | ndev->dev_addr[4] << 8 | ndev->
+	       dev_addr[5], db->membase + EMAC_MAC_A0_REG);
+
+	mdelay(1);
+
+	return 0;
+}
+
+static int emac_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+	struct emac_board_info *db = netdev_priv(dev);
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+	writel(dev->dev_addr[0] << 16 | dev->dev_addr[1] << 8 | dev->
+	       dev_addr[2], db->membase + EMAC_MAC_A1_REG);
+	writel(dev->dev_addr[3] << 16 | dev->dev_addr[4] << 8 | dev->
+	       dev_addr[5], db->membase + EMAC_MAC_A0_REG);
+
+	return 0;
+}
+
+/* Initialize emac board */
+static void emac_init_device(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	unsigned long flags;
+	unsigned int reg_val;
+
+	spin_lock_irqsave(&db->lock, flags);
+
+	emac_update_speed(dev);
+	emac_update_duplex(dev);
+
+	/* enable RX/TX */
+	reg_val = readl(db->membase + EMAC_CTL_REG);
+	writel(reg_val | EMAC_CTL_RESET | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN,
+		db->membase + EMAC_CTL_REG);
+
+	/* enable RX/TX0/RX Hlevel interrup */
+	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+	reg_val |= (0xf << 0) | (0x01 << 8);
+	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+	spin_unlock_irqrestore(&db->lock, flags);
+}
+
+/* Our watchdog timed out. Called by the networking layer */
+static void emac_timeout(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	unsigned long flags;
+
+	if (netif_msg_timer(db))
+		dev_err(db->dev, "tx time out.\n");
+
+	/* Save previous register address */
+	spin_lock_irqsave(&db->lock, flags);
+
+	netif_stop_queue(dev);
+	emac_reset(db);
+	emac_init_device(dev);
+	/* We can accept TX packets again */
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+
+	/* Restore previous register address */
+	spin_unlock_irqrestore(&db->lock, flags);
+}
+
+/* Hardware start transmission.
+ * Send a packet to media from the upper layer.
+ */
+static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	unsigned long channel;
+	unsigned long flags;
+
+	channel = db->tx_fifo_stat & 3;
+	if (channel == 3)
+		return 1;
+
+	channel = (channel == 1 ? 1 : 0);
+
+	spin_lock_irqsave(&db->lock, flags);
+
+	writel(channel, db->membase + EMAC_TX_INS_REG);
+
+	emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG,
+			skb->data, skb->len);
+	dev->stats.tx_bytes += skb->len;
+
+	db->tx_fifo_stat |= 1 << channel;
+	/* TX control: First packet immediately send, second packet queue */
+	if (channel == 0) {
+		/* set TX len */
+		writel(skb->len, db->membase + EMAC_TX_PL0_REG);
+		/* start translate from fifo to phy */
+		writel(readl(db->membase + EMAC_TX_CTL0_REG) | 1,
+		       db->membase + EMAC_TX_CTL0_REG);
+
+		/* save the time stamp */
+		dev->trans_start = jiffies;
+	} else if (channel == 1) {
+		/* set TX len */
+		writel(skb->len, db->membase + EMAC_TX_PL1_REG);
+		/* start translate from fifo to phy */
+		writel(readl(db->membase + EMAC_TX_CTL1_REG) | 1,
+		       db->membase + EMAC_TX_CTL1_REG);
+
+		/* save the time stamp */
+		dev->trans_start = jiffies;
+	}
+
+	if ((db->tx_fifo_stat & 3) == 3) {
+		/* Second packet */
+		netif_stop_queue(dev);
+	}
+
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	/* free this SKB */
+	dev_kfree_skb(skb);
+
+	return NETDEV_TX_OK;
+}
+
+/* EMAC interrupt handler
+ * receive the packet to upper layer, free the transmitted packet
+ */
+static void emac_tx_done(struct net_device *dev, struct emac_board_info *db,
+			  unsigned int tx_status)
+{
+	/* One packet sent complete */
+	db->tx_fifo_stat &= ~(tx_status & 3);
+	if (3 == (tx_status & 3))
+		dev->stats.tx_packets += 2;
+	else
+		dev->stats.tx_packets++;
+
+	if (netif_msg_tx_done(db))
+		dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
+
+	netif_wake_queue(dev);
+}
+
+/* Received a packet and pass to upper layer
+ */
+static void emac_rx(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	struct sk_buff *skb;
+	u8 *rdptr;
+	bool good_packet;
+	static int rxlen_last;
+	unsigned int reg_val;
+	u32 rxhdr, rxstatus, rxcount, rxlen;
+
+	/* Check packet ready or not */
+	while (1) {
+		/* race warning: the first packet might arrive with
+		 * the interrupts disabled, but the second will fix
+		 * it
+		 */
+		rxcount = readl(db->membase + EMAC_RX_FBC_REG);
+
+		if (netif_msg_rx_status(db))
+			dev_dbg(db->dev, "RXCount: %x\n", rxcount);
+
+		if ((db->skb_last != NULL) && (rxlen_last > 0)) {
+			dev->stats.rx_bytes += rxlen_last;
+
+			/* Pass to upper layer */
+			db->skb_last->protocol = eth_type_trans(db->skb_last,
+								dev);
+			netif_rx(db->skb_last);
+			dev->stats.rx_packets++;
+			db->skb_last = NULL;
+			rxlen_last = 0;
+
+			reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+			reg_val &= ~EMAC_RX_CTL_DMA_EN;
+			writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+		}
+
+		if (!rxcount) {
+			db->emacrx_completed_flag = 1;
+			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+			reg_val |= (0xf << 0) | (0x01 << 8);
+			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+			/* had one stuck? */
+			rxcount = readl(db->membase + EMAC_RX_FBC_REG);
+			if (!rxcount)
+				return;
+		}
+
+		reg_val = readl(db->membase + EMAC_RX_IO_DATA_REG);
+		if (netif_msg_rx_status(db))
+			dev_dbg(db->dev, "receive header: %x\n", reg_val);
+		if (reg_val != EMAC_UNDOCUMENTED_MAGIC) {
+			/* disable RX */
+			reg_val = readl(db->membase + EMAC_CTL_REG);
+			writel(reg_val & ~EMAC_CTL_RX_EN,
+			       db->membase + EMAC_CTL_REG);
+
+			/* Flush RX FIFO */
+			reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+			writel(reg_val | (1 << 3),
+			       db->membase + EMAC_RX_CTL_REG);
+
+			do {
+				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+			} while (reg_val & (1 << 3));
+
+			/* enable RX */
+			reg_val = readl(db->membase + EMAC_CTL_REG);
+			writel(reg_val | EMAC_CTL_RX_EN,
+			       db->membase + EMAC_CTL_REG);
+			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+			reg_val |= (0xf << 0) | (0x01 << 8);
+			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+			db->emacrx_completed_flag = 1;
+
+			return;
+		}
+
+		/* A packet ready now  & Get status/length */
+		good_packet = true;
+
+		emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
+				&rxhdr, sizeof(rxhdr));
+
+		if (netif_msg_rx_status(db))
+			dev_dbg(db->dev, "rxhdr: %x\n", *((int *)(&rxhdr)));
+
+		rxlen = EMAC_RX_IO_DATA_LEN(rxhdr);
+		rxstatus = EMAC_RX_IO_DATA_STATUS(rxhdr);
+
+		if (netif_msg_rx_status(db))
+			dev_dbg(db->dev, "RX: status %02x, length %04x\n",
+				rxstatus, rxlen);
+
+		/* Packet Status check */
+		if (rxlen < 0x40) {
+			good_packet = false;
+			if (netif_msg_rx_err(db))
+				dev_dbg(db->dev, "RX: Bad Packet (runt)\n");
+		}
+
+		if (unlikely(!(rxstatus & EMAC_RX_IO_DATA_STATUS_OK))) {
+			good_packet = false;
+
+			if (rxstatus & EMAC_RX_IO_DATA_STATUS_CRC_ERR) {
+				if (netif_msg_rx_err(db))
+					dev_dbg(db->dev, "crc error\n");
+				dev->stats.rx_crc_errors++;
+			}
+
+			if (rxstatus & EMAC_RX_IO_DATA_STATUS_LEN_ERR) {
+				if (netif_msg_rx_err(db))
+					dev_dbg(db->dev, "length error\n");
+				dev->stats.rx_length_errors++;
+			}
+		}
+
+		/* Move data from EMAC */
+		skb = dev_alloc_skb(rxlen + 4);
+		if (good_packet && skb) {
+			skb_reserve(skb, 2);
+			rdptr = (u8 *) skb_put(skb, rxlen - 4);
+
+			/* Read received packet from RX SRAM */
+			if (netif_msg_rx_status(db))
+				dev_dbg(db->dev, "RxLen %x\n", rxlen);
+
+			emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
+					rdptr, rxlen);
+			dev->stats.rx_bytes += rxlen;
+
+			/* Pass to upper layer */
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
+			dev->stats.rx_packets++;
+		}
+	}
+}
+
+static irqreturn_t emac_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct emac_board_info *db = netdev_priv(dev);
+	int int_status;
+	unsigned long flags;
+	unsigned int reg_val;
+
+	/* A real interrupt coming */
+
+	/* holders of db->lock must always block IRQs */
+	spin_lock_irqsave(&db->lock, flags);
+
+	/* Disable all interrupts */
+	writel(0, db->membase + EMAC_INT_CTL_REG);
+
+	/* Got EMAC interrupt status */
+	/* Got ISR */
+	int_status = readl(db->membase + EMAC_INT_STA_REG);
+	/* Clear ISR status */
+	writel(int_status, db->membase + EMAC_INT_STA_REG);
+
+	if (netif_msg_intr(db))
+		dev_dbg(db->dev, "emac interrupt %02x\n", int_status);
+
+	/* Received the coming packet */
+	if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) {
+		/* carrier lost */
+		db->emacrx_completed_flag = 0;
+		emac_rx(dev);
+	}
+
+	/* Transmit Interrupt check */
+	if (int_status & (0x01 | 0x02))
+		emac_tx_done(dev, db, int_status);
+
+	if (int_status & (0x04 | 0x08))
+		netdev_info(dev, " ab : %x\n", int_status);
+
+	/* Re-enable interrupt mask */
+	if (db->emacrx_completed_flag == 1) {
+		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+		reg_val |= (0xf << 0) | (0x01 << 8);
+		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+	}
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Used by netconsole
+ */
+static void emac_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	emac_interrupt(dev->irq, dev);
+	enable_irq(dev->irq);
+}
+#endif
+
+/*  Open the interface.
+ *  The interface is opened whenever "ifconfig" actives it.
+ */
+static int emac_open(struct net_device *dev)
+{
+	struct emac_board_info *db = netdev_priv(dev);
+	int ret;
+
+	if (netif_msg_ifup(db))
+		dev_dbg(db->dev, "enabling %s\n", dev->name);
+
+	if (devm_request_irq(db->dev, dev->irq, &emac_interrupt,
+			     0, dev->name, dev))
+		return -EAGAIN;
+
+	/* Initialize EMAC board */
+	emac_reset(db);
+	emac_init_device(dev);
+
+	ret = emac_mdio_probe(dev);
+	if (ret < 0) {
+		netdev_err(dev, "cannot probe MDIO bus\n");
+		return ret;
+	}
+
+	phy_start(db->phy_dev);
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static void emac_shutdown(struct net_device *dev)
+{
+	unsigned int reg_val;
+	struct emac_board_info *db = netdev_priv(dev);
+
+	/* Disable all interrupt */
+	writel(0, db->membase + EMAC_INT_CTL_REG);
+
+	/* clear interupt status */
+	reg_val = readl(db->membase + EMAC_INT_STA_REG);
+	writel(reg_val, db->membase + EMAC_INT_STA_REG);
+
+	/* Disable RX/TX */
+	reg_val = readl(db->membase + EMAC_CTL_REG);
+	reg_val &= ~(EMAC_CTL_TX_EN | EMAC_CTL_RX_EN | EMAC_CTL_RESET);
+	writel(reg_val, db->membase + EMAC_CTL_REG);
+}
+
+/* Stop the interface.
+ * The interface is stopped when it is brought.
+ */
+static int emac_stop(struct net_device *ndev)
+{
+	struct emac_board_info *db = netdev_priv(ndev);
+
+	if (netif_msg_ifdown(db))
+		dev_dbg(db->dev, "shutting down %s\n", ndev->name);
+
+	netif_stop_queue(ndev);
+	netif_carrier_off(ndev);
+
+	phy_stop(db->phy_dev);
+
+	emac_mdio_remove(ndev);
+
+	emac_shutdown(ndev);
+
+	return 0;
+}
+
+static const struct net_device_ops emac_netdev_ops = {
+	.ndo_open		= emac_open,
+	.ndo_stop		= emac_stop,
+	.ndo_start_xmit		= emac_start_xmit,
+	.ndo_tx_timeout		= emac_timeout,
+	.ndo_do_ioctl		= emac_ioctl,
+	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= emac_set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= emac_poll_controller,
+#endif
+};
+
+/* Search EMAC board, allocate space and register it
+ */
+static int emac_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct emac_board_info *db;
+	struct net_device *ndev;
+	int ret = 0;
+	const char *mac_addr;
+
+	ndev = alloc_etherdev(sizeof(struct emac_board_info));
+	if (!ndev) {
+		dev_err(&pdev->dev, "could not allocate device.\n");
+		return -ENOMEM;
+	}
+
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	db = netdev_priv(ndev);
+	memset(db, 0, sizeof(*db));
+
+	db->dev = &pdev->dev;
+	db->ndev = ndev;
+	db->pdev = pdev;
+
+	spin_lock_init(&db->lock);
+
+	db->membase = of_iomap(np, 0);
+	if (!db->membase) {
+		dev_err(&pdev->dev, "failed to remap registers\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* fill in parameters for net-dev structure */
+	ndev->base_addr = (unsigned long)db->membase;
+	ndev->irq = irq_of_parse_and_map(np, 0);
+	if (ndev->irq == -ENXIO) {
+		netdev_err(ndev, "No irq resource\n");
+		ret = ndev->irq;
+		goto out;
+	}
+
+	db->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(db->clk))
+		goto out;
+
+	clk_prepare_enable(db->clk);
+
+	db->phy_node = of_parse_phandle(np, "phy", 0);
+	if (!db->phy_node) {
+		dev_err(&pdev->dev, "no associated PHY\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	/* Read MAC-address from DT */
+	mac_addr = of_get_mac_address(np);
+	if (mac_addr)
+		memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+
+	/* Check if the MAC address is valid, if not get a random one */
+	if (!is_valid_ether_addr(ndev->dev_addr)) {
+		eth_hw_addr_random(ndev);
+		dev_warn(&pdev->dev, "using random MAC address %pM\n",
+			 ndev->dev_addr);
+	}
+
+	db->emacrx_completed_flag = 1;
+	emac_powerup(ndev);
+	emac_reset(db);
+
+	ether_setup(ndev);
+
+	ndev->netdev_ops = &emac_netdev_ops;
+	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
+	ndev->ethtool_ops = &emac_ethtool_ops;
+
+	platform_set_drvdata(pdev, ndev);
+
+	/* Carrier starts down, phylib will bring it up */
+	netif_carrier_off(ndev);
+
+	ret = register_netdev(ndev);
+	if (ret) {
+		dev_err(&pdev->dev, "Registering netdev failed!\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n",
+		 ndev->name, db->membase, ndev->irq, ndev->dev_addr);
+
+	return 0;
+
+out:
+	dev_err(db->dev, "not found (%d).\n", ret);
+
+	free_netdev(ndev);
+
+	return ret;
+}
+
+static int emac_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+
+	unregister_netdev(ndev);
+	free_netdev(ndev);
+
+	dev_dbg(&pdev->dev, "released and freed device\n");
+	return 0;
+}
+
+static int emac_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+
+	netif_carrier_off(ndev);
+	netif_device_detach(ndev);
+	emac_shutdown(ndev);
+
+	return 0;
+}
+
+static int emac_resume(struct platform_device *dev)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+	struct emac_board_info *db = netdev_priv(ndev);
+
+	emac_reset(db);
+	emac_init_device(ndev);
+	netif_device_attach(ndev);
+
+	return 0;
+}
+
+static const struct of_device_id emac_of_match[] = {
+	{.compatible = "allwinner,sun4i-emac",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, emac_of_match);
+
+static struct platform_driver emac_driver = {
+	.driver = {
+		.name = "sun4i-emac",
+		.of_match_table = emac_of_match,
+	},
+	.probe = emac_probe,
+	.remove = emac_remove,
+	.suspend = emac_suspend,
+	.resume = emac_resume,
+};
+
+module_platform_driver(emac_driver);
+
+MODULE_AUTHOR("Stefan Roese <sr@denx.de>");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_DESCRIPTION("Allwinner A10 emac network driver");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/allwinner/sun4i-emac.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/allwinner/sun4i-emac.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/allwinner/sun4i-emac.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/allwinner/sun4i-emac.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,108 @@
+/*
+ * Allwinner EMAC Fast Ethernet driver for Linux.
+ *
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on the Linux driver provided by Allwinner:
+ * Copyright (C) 1997  Sten Wang
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef _SUN4I_EMAC_H_
+#define _SUN4I_EMAC_H_
+
+#define EMAC_CTL_REG		(0x00)
+#define EMAC_CTL_RESET			(1 << 0)
+#define EMAC_CTL_TX_EN			(1 << 1)
+#define EMAC_CTL_RX_EN			(1 << 2)
+#define EMAC_TX_MODE_REG	(0x04)
+#define EMAC_TX_MODE_ABORTED_FRAME_EN	(1 << 0)
+#define EMAC_TX_MODE_DMA_EN		(1 << 1)
+#define EMAC_TX_FLOW_REG	(0x08)
+#define EMAC_TX_CTL0_REG	(0x0c)
+#define EMAC_TX_CTL1_REG	(0x10)
+#define EMAC_TX_INS_REG		(0x14)
+#define EMAC_TX_PL0_REG		(0x18)
+#define EMAC_TX_PL1_REG		(0x1c)
+#define EMAC_TX_STA_REG		(0x20)
+#define EMAC_TX_IO_DATA_REG	(0x24)
+#define EMAC_TX_IO_DATA1_REG	(0x28)
+#define EMAC_TX_TSVL0_REG	(0x2c)
+#define EMAC_TX_TSVH0_REG	(0x30)
+#define EMAC_TX_TSVL1_REG	(0x34)
+#define EMAC_TX_TSVH1_REG	(0x38)
+#define EMAC_RX_CTL_REG		(0x3c)
+#define EMAC_RX_CTL_AUTO_DRQ_EN		(1 << 1)
+#define EMAC_RX_CTL_DMA_EN		(1 << 2)
+#define EMAC_RX_CTL_PASS_ALL_EN		(1 << 4)
+#define EMAC_RX_CTL_PASS_CTL_EN		(1 << 5)
+#define EMAC_RX_CTL_PASS_CRC_ERR_EN	(1 << 6)
+#define EMAC_RX_CTL_PASS_LEN_ERR_EN	(1 << 7)
+#define EMAC_RX_CTL_PASS_LEN_OOR_EN	(1 << 8)
+#define EMAC_RX_CTL_ACCEPT_UNICAST_EN	(1 << 16)
+#define EMAC_RX_CTL_DA_FILTER_EN	(1 << 17)
+#define EMAC_RX_CTL_ACCEPT_MULTICAST_EN	(1 << 20)
+#define EMAC_RX_CTL_HASH_FILTER_EN	(1 << 21)
+#define EMAC_RX_CTL_ACCEPT_BROADCAST_EN	(1 << 22)
+#define EMAC_RX_CTL_SA_FILTER_EN	(1 << 24)
+#define EMAC_RX_CTL_SA_FILTER_INVERT_EN	(1 << 25)
+#define EMAC_RX_HASH0_REG	(0x40)
+#define EMAC_RX_HASH1_REG	(0x44)
+#define EMAC_RX_STA_REG		(0x48)
+#define EMAC_RX_IO_DATA_REG	(0x4c)
+#define EMAC_RX_IO_DATA_LEN(x)		(x & 0xffff)
+#define EMAC_RX_IO_DATA_STATUS(x)	((x >> 16) & 0xffff)
+#define EMAC_RX_IO_DATA_STATUS_CRC_ERR	(1 << 4)
+#define EMAC_RX_IO_DATA_STATUS_LEN_ERR	(3 << 5)
+#define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
+#define EMAC_RX_FBC_REG		(0x50)
+#define EMAC_INT_CTL_REG	(0x54)
+#define EMAC_INT_STA_REG	(0x58)
+#define EMAC_MAC_CTL0_REG	(0x5c)
+#define EMAC_MAC_CTL0_RX_FLOW_CTL_EN	(1 << 2)
+#define EMAC_MAC_CTL0_TX_FLOW_CTL_EN	(1 << 3)
+#define EMAC_MAC_CTL0_SOFT_RESET	(1 << 15)
+#define EMAC_MAC_CTL1_REG	(0x60)
+#define EMAC_MAC_CTL1_DUPLEX_EN		(1 << 0)
+#define EMAC_MAC_CTL1_LEN_CHECK_EN	(1 << 1)
+#define EMAC_MAC_CTL1_HUGE_FRAME_EN	(1 << 2)
+#define EMAC_MAC_CTL1_DELAYED_CRC_EN	(1 << 3)
+#define EMAC_MAC_CTL1_CRC_EN		(1 << 4)
+#define EMAC_MAC_CTL1_PAD_EN		(1 << 5)
+#define EMAC_MAC_CTL1_PAD_CRC_EN	(1 << 6)
+#define EMAC_MAC_CTL1_AD_SHORT_FRAME_EN	(1 << 7)
+#define EMAC_MAC_CTL1_BACKOFF_DIS	(1 << 12)
+#define EMAC_MAC_IPGT_REG	(0x64)
+#define EMAC_MAC_IPGT_HALF_DUPLEX	(0x12)
+#define EMAC_MAC_IPGT_FULL_DUPLEX	(0x15)
+#define EMAC_MAC_IPGR_REG	(0x68)
+#define EMAC_MAC_IPGR_IPG1		(0x0c)
+#define EMAC_MAC_IPGR_IPG2		(0x12)
+#define EMAC_MAC_CLRT_REG	(0x6c)
+#define EMAC_MAC_CLRT_COLLISION_WINDOW	(0x37)
+#define EMAC_MAC_CLRT_RM		(0x0f)
+#define EMAC_MAC_MAXF_REG	(0x70)
+#define EMAC_MAC_SUPP_REG	(0x74)
+#define EMAC_MAC_TEST_REG	(0x78)
+#define EMAC_MAC_MCFG_REG	(0x7c)
+#define EMAC_MAC_A0_REG		(0x98)
+#define EMAC_MAC_A1_REG		(0x9c)
+#define EMAC_MAC_A2_REG		(0xa0)
+#define EMAC_SAFX_L_REG0	(0xa4)
+#define EMAC_SAFX_H_REG0	(0xa8)
+#define EMAC_SAFX_L_REG1	(0xac)
+#define EMAC_SAFX_H_REG1	(0xb0)
+#define EMAC_SAFX_L_REG2	(0xb4)
+#define EMAC_SAFX_H_REG2	(0xb8)
+#define EMAC_SAFX_L_REG3	(0xbc)
+#define EMAC_SAFX_H_REG3	(0xc0)
+
+#define EMAC_PHY_DUPLEX		(1 << 8)
+
+#define EMAC_EEPROM_MAGIC	(0x444d394b)
+#define EMAC_UNDOCUMENTED_MAGIC	(0x0143414d)
+#endif /* _SUN4I_EMAC_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/alteon/acenic.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/alteon/acenic.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/alteon/acenic.c	2013-07-01 10:35:59.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/alteon/acenic.c	2013-08-31 17:55:30.000000000 -0400
@@ -702,19 +702,6 @@ static struct pci_driver acenic_pci_driv
 	.remove		= acenic_remove_one,
 };
 
-static int __init acenic_init(void)
-{
-	return pci_register_driver(&acenic_pci_driver);
-}
-
-static void __exit acenic_exit(void)
-{
-	pci_unregister_driver(&acenic_pci_driver);
-}
-
-module_init(acenic_init);
-module_exit(acenic_exit);
-
 static void ace_free_descriptors(struct net_device *dev)
 {
 	struct ace_private *ap = netdev_priv(dev);
@@ -3199,3 +3186,5 @@ static int read_eeprom_byte(struct net_d
 	       ap->name, offset);
 	goto out;
 }
+
+module_pci_driver(acenic_pci_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/amd/amd8111e.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/amd/amd8111e.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/amd/amd8111e.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/amd/amd8111e.c	2013-08-25 20:43:22.000000000 -0400
@@ -1813,7 +1813,7 @@ static const struct net_device_ops amd81
 static int amd8111e_probe_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
-	int err,i,pm_cap;
+	int err, i;
 	unsigned long reg_addr,reg_len;
 	struct amd8111e_priv* lp;
 	struct net_device* dev;
@@ -1842,7 +1842,7 @@ static int amd8111e_probe_one(struct pci
 	pci_set_master(pdev);
 
 	/* Find power-management capability. */
-	if((pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM))==0){
+	if (!pdev->pm_cap) {
 		printk(KERN_ERR "amd8111e: No Power Management capability, "
 		       "exiting.\n");
 		err = -ENODEV;
@@ -1875,7 +1875,7 @@ static int amd8111e_probe_one(struct pci
 	lp = netdev_priv(dev);
 	lp->pci_dev = pdev;
 	lp->amd8111e_net_dev = dev;
-	lp->pm_cap = pm_cap;
+	lp->pm_cap = pdev->pm_cap;
 
 	spin_lock_init(&lp->lock);
 
@@ -1981,15 +1981,4 @@ static struct pci_driver amd8111e_driver
 	.resume		= amd8111e_resume
 };
 
-static int __init amd8111e_init(void)
-{
-	return pci_register_driver(&amd8111e_driver);
-}
-
-static void __exit amd8111e_cleanup(void)
-{
-	pci_unregister_driver(&amd8111e_driver);
-}
-
-module_init(amd8111e_init);
-module_exit(amd8111e_cleanup);
+module_pci_driver(amd8111e_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/amd/au1000_eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/amd/au1000_eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/amd/au1000_eth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/amd/au1000_eth.c	2013-08-25 20:43:22.000000000 -0400
@@ -1301,8 +1301,6 @@ static int au1000_remove(struct platform
 	int i;
 	struct resource *base, *macen;
 
-	platform_set_drvdata(pdev, NULL);
-
 	unregister_netdev(dev);
 	mdiobus_unregister(aup->mii_bus);
 	mdiobus_free(aup->mii_bus);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/amd/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/amd/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/amd/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/amd/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -34,7 +34,6 @@ config AMD8111_ETH
 	tristate "AMD 8111 (new PCI LANCE) support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  If you have an AMD 8111-based PCI LANCE ethernet card,
@@ -60,7 +59,6 @@ config PCNET32
 	tristate "AMD PCnet32 PCI support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/amd/sunlance.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/amd/sunlance.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/amd/sunlance.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/amd/sunlance.c	2013-08-25 20:43:22.000000000 -0400
@@ -1470,7 +1470,7 @@ no_link_test:
 		goto fail;
 	}
 
-	dev_set_drvdata(&op->dev, lp);
+	platform_set_drvdata(op, lp);
 
 	printk(KERN_INFO "%s: LANCE %pM\n",
 	       dev->name, dev->dev_addr);
@@ -1501,7 +1501,7 @@ static int sunlance_sbus_probe(struct pl
 
 static int sunlance_sbus_remove(struct platform_device *op)
 {
-	struct lance_private *lp = dev_get_drvdata(&op->dev);
+	struct lance_private *lp = platform_get_drvdata(op);
 	struct net_device *net_dev = lp->dev;
 
 	unregister_netdev(net_dev);
@@ -1510,8 +1510,6 @@ static int sunlance_sbus_remove(struct p
 
 	free_netdev(net_dev);
 
-	dev_set_drvdata(&op->dev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/apple/bmac.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/apple/bmac.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/apple/bmac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/apple/bmac.c	2013-08-25 20:43:22.000000000 -0400
@@ -1016,7 +1016,6 @@ static void bmac_set_multicast(struct ne
 static void bmac_set_multicast(struct net_device *dev)
 {
 	struct netdev_hw_addr *ha;
-	int i;
 	unsigned short rx_cfg;
 	u32 crc;
 
@@ -1030,14 +1029,12 @@ static void bmac_set_multicast(struct ne
 		rx_cfg |= RxPromiscEnable;
 		bmwrite(dev, RXCFG, rx_cfg);
 	} else {
-		u16 hash_table[4];
+		u16 hash_table[4] = { 0 };
 
 		rx_cfg = bmread(dev, RXCFG);
 		rx_cfg &= ~RxPromiscEnable;
 		bmwrite(dev, RXCFG, rx_cfg);
 
-		for(i = 0; i < 4; i++) hash_table[i] = 0;
-
 		netdev_for_each_mc_addr(ha, dev) {
 			crc = ether_crc_le(6, ha->addr);
 			crc >>= 26;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/arc/emac.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/emac.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/arc/emac.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/emac.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)
+ *
+ * Registers and bits definitions of ARC EMAC
+ */
+
+#ifndef ARC_EMAC_H
+#define ARC_EMAC_H
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+
+/* STATUS and ENABLE Register bit masks */
+#define TXINT_MASK	(1<<0)	/* Transmit interrupt */
+#define RXINT_MASK	(1<<1)	/* Receive interrupt */
+#define ERR_MASK	(1<<2)	/* Error interrupt */
+#define TXCH_MASK	(1<<3)	/* Transmit chaining error interrupt */
+#define MSER_MASK	(1<<4)	/* Missed packet counter error */
+#define RXCR_MASK	(1<<8)	/* RXCRCERR counter rolled over  */
+#define RXFR_MASK	(1<<9)	/* RXFRAMEERR counter rolled over */
+#define RXFL_MASK	(1<<10)	/* RXOFLOWERR counter rolled over */
+#define MDIO_MASK	(1<<12)	/* MDIO complete interrupt */
+#define TXPL_MASK	(1<<31)	/* Force polling of BD by EMAC */
+
+/* CONTROL Register bit masks */
+#define EN_MASK		(1<<0)	/* VMAC enable */
+#define TXRN_MASK	(1<<3)	/* TX enable */
+#define RXRN_MASK	(1<<4)	/* RX enable */
+#define DSBC_MASK	(1<<8)	/* Disable receive broadcast */
+#define ENFL_MASK	(1<<10)	/* Enable Full-duplex */
+#define PROM_MASK	(1<<11)	/* Promiscuous mode */
+
+/* Buffer descriptor INFO bit masks */
+#define OWN_MASK	(1<<31)	/* 0-CPU owns buffer, 1-EMAC owns buffer */
+#define FIRST_MASK	(1<<16)	/* First buffer in chain */
+#define LAST_MASK	(1<<17)	/* Last buffer in chain */
+#define LEN_MASK	0x000007FF	/* last 11 bits */
+#define CRLS		(1<<21)
+#define DEFR		(1<<22)
+#define DROP		(1<<23)
+#define RTRY		(1<<24)
+#define LTCL		(1<<28)
+#define UFLO		(1<<29)
+
+#define FOR_EMAC	OWN_MASK
+#define FOR_CPU		0
+
+/* ARC EMAC register set combines entries for MAC and MDIO */
+enum {
+	R_ID = 0,
+	R_STATUS,
+	R_ENABLE,
+	R_CTRL,
+	R_POLLRATE,
+	R_RXERR,
+	R_MISS,
+	R_TX_RING,
+	R_RX_RING,
+	R_ADDRL,
+	R_ADDRH,
+	R_LAFL,
+	R_LAFH,
+	R_MDIO,
+};
+
+#define TX_TIMEOUT		(400*HZ/1000)	/* Transmission timeout */
+
+#define ARC_EMAC_NAPI_WEIGHT	40		/* Workload for NAPI */
+
+#define EMAC_BUFFER_SIZE	1536		/* EMAC buffer size */
+
+/**
+ * struct arc_emac_bd - EMAC buffer descriptor (BD).
+ *
+ * @info:	Contains status information on the buffer itself.
+ * @data:	32-bit byte addressable pointer to the packet data.
+ */
+struct arc_emac_bd {
+	__le32 info;
+	dma_addr_t data;
+};
+
+/* Number of Rx/Tx BD's */
+#define RX_BD_NUM	128
+#define TX_BD_NUM	128
+
+#define RX_RING_SZ	(RX_BD_NUM * sizeof(struct arc_emac_bd))
+#define TX_RING_SZ	(TX_BD_NUM * sizeof(struct arc_emac_bd))
+
+/**
+ * struct buffer_state - Stores Rx/Tx buffer state.
+ * @sk_buff:	Pointer to socket buffer.
+ * @addr:	Start address of DMA-mapped memory region.
+ * @len:	Length of DMA-mapped memory region.
+ */
+struct buffer_state {
+	struct sk_buff *skb;
+	DEFINE_DMA_UNMAP_ADDR(addr);
+	DEFINE_DMA_UNMAP_LEN(len);
+};
+
+/**
+ * struct arc_emac_priv - Storage of EMAC's private information.
+ * @dev:	Pointer to the current device.
+ * @ndev:	Pointer to the current network device.
+ * @phy_dev:	Pointer to attached PHY device.
+ * @bus:	Pointer to the current MII bus.
+ * @regs:	Base address of EMAC memory-mapped control registers.
+ * @napi:	Structure for NAPI.
+ * @stats:	Network device statistics.
+ * @rxbd:	Pointer to Rx BD ring.
+ * @txbd:	Pointer to Tx BD ring.
+ * @rxbd_dma:	DMA handle for Rx BD ring.
+ * @txbd_dma:	DMA handle for Tx BD ring.
+ * @rx_buff:	Storage for Rx buffers states.
+ * @tx_buff:	Storage for Tx buffers states.
+ * @txbd_curr:	Index of Tx BD to use on the next "ndo_start_xmit".
+ * @txbd_dirty:	Index of Tx BD to free on the next Tx interrupt.
+ * @last_rx_bd:	Index of the last Rx BD we've got from EMAC.
+ * @link:	PHY's last seen link state.
+ * @duplex:	PHY's last set duplex mode.
+ * @speed:	PHY's last set speed.
+ * @max_speed:	Maximum supported by current system network data-rate.
+ */
+struct arc_emac_priv {
+	/* Devices */
+	struct device *dev;
+	struct net_device *ndev;
+	struct phy_device *phy_dev;
+	struct mii_bus *bus;
+
+	void __iomem *regs;
+
+	struct napi_struct napi;
+	struct net_device_stats stats;
+
+	struct arc_emac_bd *rxbd;
+	struct arc_emac_bd *txbd;
+
+	dma_addr_t rxbd_dma;
+	dma_addr_t txbd_dma;
+
+	struct buffer_state rx_buff[RX_BD_NUM];
+	struct buffer_state tx_buff[TX_BD_NUM];
+	unsigned int txbd_curr;
+	unsigned int txbd_dirty;
+
+	unsigned int last_rx_bd;
+
+	unsigned int link;
+	unsigned int duplex;
+	unsigned int speed;
+	unsigned int max_speed;
+};
+
+/**
+ * arc_reg_set - Sets EMAC register with provided value.
+ * @priv:	Pointer to ARC EMAC private data structure.
+ * @reg:	Register offset from base address.
+ * @value:	Value to set in register.
+ */
+static inline void arc_reg_set(struct arc_emac_priv *priv, int reg, int value)
+{
+	iowrite32(value, priv->regs + reg * sizeof(int));
+}
+
+/**
+ * arc_reg_get - Gets value of specified EMAC register.
+ * @priv:	Pointer to ARC EMAC private data structure.
+ * @reg:	Register offset from base address.
+ *
+ * returns:	Value of requested register.
+ */
+static inline unsigned int arc_reg_get(struct arc_emac_priv *priv, int reg)
+{
+	return ioread32(priv->regs + reg * sizeof(int));
+}
+
+/**
+ * arc_reg_or - Applies mask to specified EMAC register - ("reg" | "mask").
+ * @priv:	Pointer to ARC EMAC private data structure.
+ * @reg:	Register offset from base address.
+ * @mask:	Mask to apply to specified register.
+ *
+ * This function reads initial register value, then applies provided mask
+ * to it and then writes register back.
+ */
+static inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask)
+{
+	unsigned int value = arc_reg_get(priv, reg);
+	arc_reg_set(priv, reg, value | mask);
+}
+
+/**
+ * arc_reg_clr - Applies mask to specified EMAC register - ("reg" & ~"mask").
+ * @priv:	Pointer to ARC EMAC private data structure.
+ * @reg:	Register offset from base address.
+ * @mask:	Mask to apply to specified register.
+ *
+ * This function reads initial register value, then applies provided mask
+ * to it and then writes register back.
+ */
+static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask)
+{
+	unsigned int value = arc_reg_get(priv, reg);
+	arc_reg_set(priv, reg, value & ~mask);
+}
+
+int arc_mdio_probe(struct platform_device *pdev, struct arc_emac_priv *priv);
+int arc_mdio_remove(struct arc_emac_priv *priv);
+
+#endif /* ARC_EMAC_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/arc/emac_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/emac_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/arc/emac_main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/emac_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,819 @@
+/*
+ * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver for the ARC EMAC 10100 (hardware revision 5)
+ *
+ * Contributors:
+ *		Amit Bhor
+ *		Sameer Dhavale
+ *		Vineet Gupta
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+
+#include "emac.h"
+
+#define DRV_NAME	"arc_emac"
+#define DRV_VERSION	"1.0"
+
+/**
+ * arc_emac_adjust_link - Adjust the PHY link duplex.
+ * @ndev:	Pointer to the net_device structure.
+ *
+ * This function is called to change the duplex setting after auto negotiation
+ * is done by the PHY.
+ */
+static void arc_emac_adjust_link(struct net_device *ndev)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	struct phy_device *phy_dev = priv->phy_dev;
+	unsigned int reg, state_changed = 0;
+
+	if (priv->link != phy_dev->link) {
+		priv->link = phy_dev->link;
+		state_changed = 1;
+	}
+
+	if (priv->speed != phy_dev->speed) {
+		priv->speed = phy_dev->speed;
+		state_changed = 1;
+	}
+
+	if (priv->duplex != phy_dev->duplex) {
+		reg = arc_reg_get(priv, R_CTRL);
+
+		if (DUPLEX_FULL == phy_dev->duplex)
+			reg |= ENFL_MASK;
+		else
+			reg &= ~ENFL_MASK;
+
+		arc_reg_set(priv, R_CTRL, reg);
+		priv->duplex = phy_dev->duplex;
+		state_changed = 1;
+	}
+
+	if (state_changed)
+		phy_print_status(phy_dev);
+}
+
+/**
+ * arc_emac_get_settings - Get PHY settings.
+ * @ndev:	Pointer to net_device structure.
+ * @cmd:	Pointer to ethtool_cmd structure.
+ *
+ * This implements ethtool command for getting PHY settings. If PHY could
+ * not be found, the function returns -ENODEV. This function calls the
+ * relevant PHY ethtool API to get the PHY settings.
+ * Issue "ethtool ethX" under linux prompt to execute this function.
+ */
+static int arc_emac_get_settings(struct net_device *ndev,
+				 struct ethtool_cmd *cmd)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+
+	return phy_ethtool_gset(priv->phy_dev, cmd);
+}
+
+/**
+ * arc_emac_set_settings - Set PHY settings as passed in the argument.
+ * @ndev:	Pointer to net_device structure.
+ * @cmd:	Pointer to ethtool_cmd structure.
+ *
+ * This implements ethtool command for setting various PHY settings. If PHY
+ * could not be found, the function returns -ENODEV. This function calls the
+ * relevant PHY ethtool API to set the PHY.
+ * Issue e.g. "ethtool -s ethX speed 1000" under linux prompt to execute this
+ * function.
+ */
+static int arc_emac_set_settings(struct net_device *ndev,
+				 struct ethtool_cmd *cmd)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	return phy_ethtool_sset(priv->phy_dev, cmd);
+}
+
+/**
+ * arc_emac_get_drvinfo - Get EMAC driver information.
+ * @ndev:	Pointer to net_device structure.
+ * @info:	Pointer to ethtool_drvinfo structure.
+ *
+ * This implements ethtool command for getting the driver information.
+ * Issue "ethtool -i ethX" under linux prompt to execute this function.
+ */
+static void arc_emac_get_drvinfo(struct net_device *ndev,
+				 struct ethtool_drvinfo *info)
+{
+	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+}
+
+static const struct ethtool_ops arc_emac_ethtool_ops = {
+	.get_settings	= arc_emac_get_settings,
+	.set_settings	= arc_emac_set_settings,
+	.get_drvinfo	= arc_emac_get_drvinfo,
+	.get_link	= ethtool_op_get_link,
+};
+
+#define FIRST_OR_LAST_MASK	(FIRST_MASK | LAST_MASK)
+
+/**
+ * arc_emac_tx_clean - clears processed by EMAC Tx BDs.
+ * @ndev:	Pointer to the network device.
+ */
+static void arc_emac_tx_clean(struct net_device *ndev)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &priv->stats;
+	unsigned int i;
+
+	for (i = 0; i < TX_BD_NUM; i++) {
+		unsigned int *txbd_dirty = &priv->txbd_dirty;
+		struct arc_emac_bd *txbd = &priv->txbd[*txbd_dirty];
+		struct buffer_state *tx_buff = &priv->tx_buff[*txbd_dirty];
+		struct sk_buff *skb = tx_buff->skb;
+		unsigned int info = le32_to_cpu(txbd->info);
+
+		*txbd_dirty = (*txbd_dirty + 1) % TX_BD_NUM;
+
+		if ((info & FOR_EMAC) || !txbd->data)
+			break;
+
+		if (unlikely(info & (DROP | DEFR | LTCL | UFLO))) {
+			stats->tx_errors++;
+			stats->tx_dropped++;
+
+			if (info & DEFR)
+				stats->tx_carrier_errors++;
+
+			if (info & LTCL)
+				stats->collisions++;
+
+			if (info & UFLO)
+				stats->tx_fifo_errors++;
+		} else if (likely(info & FIRST_OR_LAST_MASK)) {
+			stats->tx_packets++;
+			stats->tx_bytes += skb->len;
+		}
+
+		dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr),
+				 dma_unmap_len(tx_buff, len), DMA_TO_DEVICE);
+
+		/* return the sk_buff to system */
+		dev_kfree_skb_irq(skb);
+
+		txbd->data = 0;
+		txbd->info = 0;
+
+		if (netif_queue_stopped(ndev))
+			netif_wake_queue(ndev);
+	}
+}
+
+/**
+ * arc_emac_rx - processing of Rx packets.
+ * @ndev:	Pointer to the network device.
+ * @budget:	How many BDs to process on 1 call.
+ *
+ * returns:	Number of processed BDs
+ *
+ * Iterate through Rx BDs and deliver received packages to upper layer.
+ */
+static int arc_emac_rx(struct net_device *ndev, int budget)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	unsigned int work_done;
+
+	for (work_done = 0; work_done < budget; work_done++) {
+		unsigned int *last_rx_bd = &priv->last_rx_bd;
+		struct net_device_stats *stats = &priv->stats;
+		struct buffer_state *rx_buff = &priv->rx_buff[*last_rx_bd];
+		struct arc_emac_bd *rxbd = &priv->rxbd[*last_rx_bd];
+		unsigned int pktlen, info = le32_to_cpu(rxbd->info);
+		struct sk_buff *skb;
+		dma_addr_t addr;
+
+		if (unlikely((info & OWN_MASK) == FOR_EMAC))
+			break;
+
+		/* Make a note that we saw a packet at this BD.
+		 * So next time, driver starts from this + 1
+		 */
+		*last_rx_bd = (*last_rx_bd + 1) % RX_BD_NUM;
+
+		if (unlikely((info & FIRST_OR_LAST_MASK) !=
+			     FIRST_OR_LAST_MASK)) {
+			/* We pre-allocate buffers of MTU size so incoming
+			 * packets won't be split/chained.
+			 */
+			if (net_ratelimit())
+				netdev_err(ndev, "incomplete packet received\n");
+
+			/* Return ownership to EMAC */
+			rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
+			stats->rx_errors++;
+			stats->rx_length_errors++;
+			continue;
+		}
+
+		pktlen = info & LEN_MASK;
+		stats->rx_packets++;
+		stats->rx_bytes += pktlen;
+		skb = rx_buff->skb;
+		skb_put(skb, pktlen);
+		skb->dev = ndev;
+		skb->protocol = eth_type_trans(skb, ndev);
+
+		dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
+				 dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
+
+		/* Prepare the BD for next cycle */
+		rx_buff->skb = netdev_alloc_skb_ip_align(ndev,
+							 EMAC_BUFFER_SIZE);
+		if (unlikely(!rx_buff->skb)) {
+			stats->rx_errors++;
+			/* Because receive_skb is below, increment rx_dropped */
+			stats->rx_dropped++;
+			continue;
+		}
+
+		/* receive_skb only if new skb was allocated to avoid holes */
+		netif_receive_skb(skb);
+
+		addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
+				      EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
+		if (dma_mapping_error(&ndev->dev, addr)) {
+			if (net_ratelimit())
+				netdev_err(ndev, "cannot dma map\n");
+			dev_kfree_skb(rx_buff->skb);
+			stats->rx_errors++;
+			continue;
+		}
+		dma_unmap_addr_set(rx_buff, addr, addr);
+		dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE);
+
+		rxbd->data = cpu_to_le32(addr);
+
+		/* Make sure pointer to data buffer is set */
+		wmb();
+
+		/* Return ownership to EMAC */
+		rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
+	}
+
+	return work_done;
+}
+
+/**
+ * arc_emac_poll - NAPI poll handler.
+ * @napi:	Pointer to napi_struct structure.
+ * @budget:	How many BDs to process on 1 call.
+ *
+ * returns:	Number of processed BDs
+ */
+static int arc_emac_poll(struct napi_struct *napi, int budget)
+{
+	struct net_device *ndev = napi->dev;
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	unsigned int work_done;
+
+	arc_emac_tx_clean(ndev);
+
+	work_done = arc_emac_rx(ndev, budget);
+	if (work_done < budget) {
+		napi_complete(napi);
+		arc_reg_or(priv, R_ENABLE, RXINT_MASK);
+	}
+
+	return work_done;
+}
+
+/**
+ * arc_emac_intr - Global interrupt handler for EMAC.
+ * @irq:		irq number.
+ * @dev_instance:	device instance.
+ *
+ * returns: IRQ_HANDLED for all cases.
+ *
+ * ARC EMAC has only 1 interrupt line, and depending on bits raised in
+ * STATUS register we may tell what is a reason for interrupt to fire.
+ */
+static irqreturn_t arc_emac_intr(int irq, void *dev_instance)
+{
+	struct net_device *ndev = dev_instance;
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &priv->stats;
+	unsigned int status;
+
+	status = arc_reg_get(priv, R_STATUS);
+	status &= ~MDIO_MASK;
+
+	/* Reset all flags except "MDIO complete" */
+	arc_reg_set(priv, R_STATUS, status);
+
+	if (status & RXINT_MASK) {
+		if (likely(napi_schedule_prep(&priv->napi))) {
+			arc_reg_clr(priv, R_ENABLE, RXINT_MASK);
+			__napi_schedule(&priv->napi);
+		}
+	}
+
+	if (status & ERR_MASK) {
+		/* MSER/RXCR/RXFR/RXFL interrupt fires on corresponding
+		 * 8-bit error counter overrun.
+		 */
+
+		if (status & MSER_MASK) {
+			stats->rx_missed_errors += 0x100;
+			stats->rx_errors += 0x100;
+		}
+
+		if (status & RXCR_MASK) {
+			stats->rx_crc_errors += 0x100;
+			stats->rx_errors += 0x100;
+		}
+
+		if (status & RXFR_MASK) {
+			stats->rx_frame_errors += 0x100;
+			stats->rx_errors += 0x100;
+		}
+
+		if (status & RXFL_MASK) {
+			stats->rx_over_errors += 0x100;
+			stats->rx_errors += 0x100;
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * arc_emac_open - Open the network device.
+ * @ndev:	Pointer to the network device.
+ *
+ * returns: 0, on success or non-zero error value on failure.
+ *
+ * This function sets the MAC address, requests and enables an IRQ
+ * for the EMAC device and starts the Tx queue.
+ * It also connects to the phy device.
+ */
+static int arc_emac_open(struct net_device *ndev)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	struct phy_device *phy_dev = priv->phy_dev;
+	int i;
+
+	phy_dev->autoneg = AUTONEG_ENABLE;
+	phy_dev->speed = 0;
+	phy_dev->duplex = 0;
+	phy_dev->advertising = phy_dev->supported;
+
+	if (priv->max_speed > 100) {
+		phy_dev->advertising &= PHY_GBIT_FEATURES;
+	} else if (priv->max_speed <= 100) {
+		phy_dev->advertising &= PHY_BASIC_FEATURES;
+		if (priv->max_speed <= 10) {
+			phy_dev->advertising &= ~SUPPORTED_100baseT_Half;
+			phy_dev->advertising &= ~SUPPORTED_100baseT_Full;
+		}
+	}
+
+	priv->last_rx_bd = 0;
+
+	/* Allocate and set buffers for Rx BD's */
+	for (i = 0; i < RX_BD_NUM; i++) {
+		dma_addr_t addr;
+		unsigned int *last_rx_bd = &priv->last_rx_bd;
+		struct arc_emac_bd *rxbd = &priv->rxbd[*last_rx_bd];
+		struct buffer_state *rx_buff = &priv->rx_buff[*last_rx_bd];
+
+		rx_buff->skb = netdev_alloc_skb_ip_align(ndev,
+							 EMAC_BUFFER_SIZE);
+		if (unlikely(!rx_buff->skb))
+			return -ENOMEM;
+
+		addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
+				      EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
+		if (dma_mapping_error(&ndev->dev, addr)) {
+			netdev_err(ndev, "cannot dma map\n");
+			dev_kfree_skb(rx_buff->skb);
+			return -ENOMEM;
+		}
+		dma_unmap_addr_set(rx_buff, addr, addr);
+		dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE);
+
+		rxbd->data = cpu_to_le32(addr);
+
+		/* Make sure pointer to data buffer is set */
+		wmb();
+
+		/* Return ownership to EMAC */
+		rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
+
+		*last_rx_bd = (*last_rx_bd + 1) % RX_BD_NUM;
+	}
+
+	/* Clean Tx BD's */
+	memset(priv->txbd, 0, TX_RING_SZ);
+
+	/* Initialize logical address filter */
+	arc_reg_set(priv, R_LAFL, 0);
+	arc_reg_set(priv, R_LAFH, 0);
+
+	/* Set BD ring pointers for device side */
+	arc_reg_set(priv, R_RX_RING, (unsigned int)priv->rxbd_dma);
+	arc_reg_set(priv, R_TX_RING, (unsigned int)priv->txbd_dma);
+
+	/* Enable interrupts */
+	arc_reg_set(priv, R_ENABLE, RXINT_MASK | ERR_MASK);
+
+	/* Set CONTROL */
+	arc_reg_set(priv, R_CTRL,
+		     (RX_BD_NUM << 24) |	/* RX BD table length */
+		     (TX_BD_NUM << 16) |	/* TX BD table length */
+		     TXRN_MASK | RXRN_MASK);
+
+	napi_enable(&priv->napi);
+
+	/* Enable EMAC */
+	arc_reg_or(priv, R_CTRL, EN_MASK);
+
+	phy_start_aneg(priv->phy_dev);
+
+	netif_start_queue(ndev);
+
+	return 0;
+}
+
+/**
+ * arc_emac_stop - Close the network device.
+ * @ndev:	Pointer to the network device.
+ *
+ * This function stops the Tx queue, disables interrupts and frees the IRQ for
+ * the EMAC device.
+ * It also disconnects the PHY device associated with the EMAC device.
+ */
+static int arc_emac_stop(struct net_device *ndev)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+
+	napi_disable(&priv->napi);
+	netif_stop_queue(ndev);
+
+	/* Disable interrupts */
+	arc_reg_clr(priv, R_ENABLE, RXINT_MASK | ERR_MASK);
+
+	/* Disable EMAC */
+	arc_reg_clr(priv, R_CTRL, EN_MASK);
+
+	return 0;
+}
+
+/**
+ * arc_emac_stats - Get system network statistics.
+ * @ndev:	Pointer to net_device structure.
+ *
+ * Returns the address of the device statistics structure.
+ * Statistics are updated in interrupt handler.
+ */
+static struct net_device_stats *arc_emac_stats(struct net_device *ndev)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &priv->stats;
+	unsigned long miss, rxerr;
+	u8 rxcrc, rxfram, rxoflow;
+
+	rxerr = arc_reg_get(priv, R_RXERR);
+	miss = arc_reg_get(priv, R_MISS);
+
+	rxcrc = rxerr;
+	rxfram = rxerr >> 8;
+	rxoflow = rxerr >> 16;
+
+	stats->rx_errors += miss;
+	stats->rx_errors += rxcrc + rxfram + rxoflow;
+
+	stats->rx_over_errors += rxoflow;
+	stats->rx_frame_errors += rxfram;
+	stats->rx_crc_errors += rxcrc;
+	stats->rx_missed_errors += miss;
+
+	return stats;
+}
+
+/**
+ * arc_emac_tx - Starts the data transmission.
+ * @skb:	sk_buff pointer that contains data to be Transmitted.
+ * @ndev:	Pointer to net_device structure.
+ *
+ * returns: NETDEV_TX_OK, on success
+ *		NETDEV_TX_BUSY, if any of the descriptors are not free.
+ *
+ * This function is invoked from upper layers to initiate transmission.
+ */
+static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	unsigned int len, *txbd_curr = &priv->txbd_curr;
+	struct net_device_stats *stats = &priv->stats;
+	__le32 *info = &priv->txbd[*txbd_curr].info;
+	dma_addr_t addr;
+
+	if (skb_padto(skb, ETH_ZLEN))
+		return NETDEV_TX_OK;
+
+	len = max_t(unsigned int, ETH_ZLEN, skb->len);
+
+	/* EMAC still holds this buffer in its possession.
+	 * CPU must not modify this buffer descriptor
+	 */
+	if (unlikely((le32_to_cpu(*info) & OWN_MASK) == FOR_EMAC)) {
+		netif_stop_queue(ndev);
+		return NETDEV_TX_BUSY;
+	}
+
+	addr = dma_map_single(&ndev->dev, (void *)skb->data, len,
+			      DMA_TO_DEVICE);
+
+	if (unlikely(dma_mapping_error(&ndev->dev, addr))) {
+		stats->tx_dropped++;
+		stats->tx_errors++;
+		dev_kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+	dma_unmap_addr_set(&priv->tx_buff[*txbd_curr], addr, addr);
+	dma_unmap_len_set(&priv->tx_buff[*txbd_curr], len, len);
+
+	priv->tx_buff[*txbd_curr].skb = skb;
+	priv->txbd[*txbd_curr].data = cpu_to_le32(addr);
+
+	/* Make sure pointer to data buffer is set */
+	wmb();
+
+	*info = cpu_to_le32(FOR_EMAC | FIRST_OR_LAST_MASK | len);
+
+	/* Increment index to point to the next BD */
+	*txbd_curr = (*txbd_curr + 1) % TX_BD_NUM;
+
+	/* Get "info" of the next BD */
+	info = &priv->txbd[*txbd_curr].info;
+
+	/* Check if if Tx BD ring is full - next BD is still owned by EMAC */
+	if (unlikely((le32_to_cpu(*info) & OWN_MASK) == FOR_EMAC))
+		netif_stop_queue(ndev);
+
+	arc_reg_set(priv, R_STATUS, TXPL_MASK);
+
+	skb_tx_timestamp(skb);
+
+	return NETDEV_TX_OK;
+}
+
+/**
+ * arc_emac_set_address - Set the MAC address for this device.
+ * @ndev:	Pointer to net_device structure.
+ * @p:		6 byte Address to be written as MAC address.
+ *
+ * This function copies the HW address from the sockaddr structure to the
+ * net_device structure and updates the address in HW.
+ *
+ * returns:	-EBUSY if the net device is busy or 0 if the address is set
+ *		successfully.
+ */
+static int arc_emac_set_address(struct net_device *ndev, void *p)
+{
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+	struct sockaddr *addr = p;
+	unsigned int addr_low, addr_hi;
+
+	if (netif_running(ndev))
+		return -EBUSY;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
+
+	addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]);
+	addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]);
+
+	arc_reg_set(priv, R_ADDRL, addr_low);
+	arc_reg_set(priv, R_ADDRH, addr_hi);
+
+	return 0;
+}
+
+static const struct net_device_ops arc_emac_netdev_ops = {
+	.ndo_open		= arc_emac_open,
+	.ndo_stop		= arc_emac_stop,
+	.ndo_start_xmit		= arc_emac_tx,
+	.ndo_set_mac_address	= arc_emac_set_address,
+	.ndo_get_stats		= arc_emac_stats,
+};
+
+static int arc_emac_probe(struct platform_device *pdev)
+{
+	struct resource res_regs, res_irq;
+	struct device_node *phy_node;
+	struct arc_emac_priv *priv;
+	struct net_device *ndev;
+	const char *mac_addr;
+	unsigned int id, clock_frequency;
+	int err;
+
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	/* Get PHY from device tree */
+	phy_node = of_parse_phandle(pdev->dev.of_node, "phy", 0);
+	if (!phy_node) {
+		dev_err(&pdev->dev, "failed to retrieve phy description from device tree\n");
+		return -ENODEV;
+	}
+
+	/* Get EMAC registers base address from device tree */
+	err = of_address_to_resource(pdev->dev.of_node, 0, &res_regs);
+	if (err) {
+		dev_err(&pdev->dev, "failed to retrieve registers base from device tree\n");
+		return -ENODEV;
+	}
+
+	/* Get CPU clock frequency from device tree */
+	if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
+				 &clock_frequency)) {
+		dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n");
+		return -EINVAL;
+	}
+
+	/* Get IRQ from device tree */
+	err = of_irq_to_resource(pdev->dev.of_node, 0, &res_irq);
+	if (!err) {
+		dev_err(&pdev->dev, "failed to retrieve <irq> value from device tree\n");
+		return -ENODEV;
+	}
+
+	ndev = alloc_etherdev(sizeof(struct arc_emac_priv));
+	if (!ndev)
+		return -ENOMEM;
+
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	ndev->netdev_ops = &arc_emac_netdev_ops;
+	ndev->ethtool_ops = &arc_emac_ethtool_ops;
+	ndev->watchdog_timeo = TX_TIMEOUT;
+	/* FIXME :: no multicast support yet */
+	ndev->flags &= ~IFF_MULTICAST;
+
+	priv = netdev_priv(ndev);
+	priv->dev = &pdev->dev;
+	priv->ndev = ndev;
+
+	priv->regs = devm_ioremap_resource(&pdev->dev, &res_regs);
+	if (IS_ERR(priv->regs)) {
+		err = PTR_ERR(priv->regs);
+		goto out;
+	}
+	dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs);
+
+	id = arc_reg_get(priv, R_ID);
+
+	/* Check for EMAC revision 5 or 7, magic number */
+	if (!(id == 0x0005fd02 || id == 0x0007fd02)) {
+		dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id);
+		err = -ENODEV;
+		goto out;
+	}
+	dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id);
+
+	/* Set poll rate so that it polls every 1 ms */
+	arc_reg_set(priv, R_POLLRATE, clock_frequency / 1000000);
+
+	/* Get max speed of operation from device tree */
+	if (of_property_read_u32(pdev->dev.of_node, "max-speed",
+				 &priv->max_speed)) {
+		dev_err(&pdev->dev, "failed to retrieve <max-speed> from device tree\n");
+		err = -EINVAL;
+		goto out;
+	}
+
+	ndev->irq = res_irq.start;
+	dev_info(&pdev->dev, "IRQ is %d\n", ndev->irq);
+
+	/* Register interrupt handler for device */
+	err = devm_request_irq(&pdev->dev, ndev->irq, arc_emac_intr, 0,
+			       ndev->name, ndev);
+	if (err) {
+		dev_err(&pdev->dev, "could not allocate IRQ\n");
+		goto out;
+	}
+
+	/* Get MAC address from device tree */
+	mac_addr = of_get_mac_address(pdev->dev.of_node);
+
+	if (!mac_addr || !is_valid_ether_addr(mac_addr))
+		eth_hw_addr_random(ndev);
+	else
+		memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+
+	dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr);
+
+	/* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */
+	priv->rxbd = dmam_alloc_coherent(&pdev->dev, RX_RING_SZ + TX_RING_SZ,
+					 &priv->rxbd_dma, GFP_KERNEL);
+
+	if (!priv->rxbd) {
+		dev_err(&pdev->dev, "failed to allocate data buffers\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	priv->txbd = priv->rxbd + RX_BD_NUM;
+
+	priv->txbd_dma = priv->rxbd_dma + RX_RING_SZ;
+	dev_dbg(&pdev->dev, "EMAC Device addr: Rx Ring [0x%x], Tx Ring[%x]\n",
+		(unsigned int)priv->rxbd_dma, (unsigned int)priv->txbd_dma);
+
+	err = arc_mdio_probe(pdev, priv);
+	if (err) {
+		dev_err(&pdev->dev, "failed to probe MII bus\n");
+		goto out;
+	}
+
+	priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0,
+				       PHY_INTERFACE_MODE_MII);
+	if (!priv->phy_dev) {
+		dev_err(&pdev->dev, "of_phy_connect() failed\n");
+		err = -ENODEV;
+		goto out;
+	}
+
+	dev_info(&pdev->dev, "connected to %s phy with id 0x%x\n",
+		 priv->phy_dev->drv->name, priv->phy_dev->phy_id);
+
+	netif_napi_add(ndev, &priv->napi, arc_emac_poll, ARC_EMAC_NAPI_WEIGHT);
+
+	err = register_netdev(ndev);
+	if (err) {
+		netif_napi_del(&priv->napi);
+		dev_err(&pdev->dev, "failed to register network device\n");
+		goto out;
+	}
+
+	return 0;
+
+out:
+	free_netdev(ndev);
+	return err;
+}
+
+static int arc_emac_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+
+	phy_disconnect(priv->phy_dev);
+	priv->phy_dev = NULL;
+	arc_mdio_remove(priv);
+	unregister_netdev(ndev);
+	netif_napi_del(&priv->napi);
+	free_netdev(ndev);
+
+	return 0;
+}
+
+static const struct of_device_id arc_emac_dt_ids[] = {
+	{ .compatible = "snps,arc-emac" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, arc_emac_dt_ids);
+
+static struct platform_driver arc_emac_driver = {
+	.probe = arc_emac_probe,
+	.remove = arc_emac_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table  = arc_emac_dt_ids,
+		},
+};
+
+module_platform_driver(arc_emac_driver);
+
+MODULE_AUTHOR("Alexey Brodkin <abrodkin@synopsys.com>");
+MODULE_DESCRIPTION("ARC EMAC driver");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/arc/emac_mdio.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/emac_mdio.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/arc/emac_mdio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/emac_mdio.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)
+ *
+ * MDIO implementation for ARC EMAC
+ */
+
+#include <linux/delay.h>
+#include <linux/of_mdio.h>
+#include <linux/platform_device.h>
+
+#include "emac.h"
+
+/* Number of seconds we wait for "MDIO complete" flag to appear */
+#define ARC_MDIO_COMPLETE_POLL_COUNT	1
+
+/**
+ * arc_mdio_complete_wait - Waits until MDIO transaction is completed.
+ * @priv:	Pointer to ARC EMAC private data structure.
+ *
+ * returns:	0 on success, -ETIMEDOUT on a timeout.
+ */
+static int arc_mdio_complete_wait(struct arc_emac_priv *priv)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARC_MDIO_COMPLETE_POLL_COUNT * 40; i++) {
+		unsigned int status = arc_reg_get(priv, R_STATUS);
+
+		status &= MDIO_MASK;
+
+		if (status) {
+			/* Reset "MDIO complete" flag */
+			arc_reg_set(priv, R_STATUS, status);
+			return 0;
+		}
+
+		msleep(25);
+	}
+
+	return -ETIMEDOUT;
+}
+
+/**
+ * arc_mdio_read - MDIO interface read function.
+ * @bus:	Pointer to MII bus structure.
+ * @phy_addr:	Address of the PHY device.
+ * @reg_num:	PHY register to read.
+ *
+ * returns:	The register contents on success, -ETIMEDOUT on a timeout.
+ *
+ * Reads the contents of the requested register from the requested PHY
+ * address.
+ */
+static int arc_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
+{
+	struct arc_emac_priv *priv = bus->priv;
+	unsigned int value;
+	int error;
+
+	arc_reg_set(priv, R_MDIO,
+		    0x60020000 | (phy_addr << 23) | (reg_num << 18));
+
+	error = arc_mdio_complete_wait(priv);
+	if (error < 0)
+		return error;
+
+	value = arc_reg_get(priv, R_MDIO) & 0xffff;
+
+	dev_dbg(priv->dev, "arc_mdio_read(phy_addr=%i, reg_num=%x) = %x\n",
+		phy_addr, reg_num, value);
+
+	return value;
+}
+
+/**
+ * arc_mdio_write - MDIO interface write function.
+ * @bus:	Pointer to MII bus structure.
+ * @phy_addr:	Address of the PHY device.
+ * @reg_num:	PHY register to write to.
+ * @value:	Value to be written into the register.
+ *
+ * returns:	0 on success, -ETIMEDOUT on a timeout.
+ *
+ * Writes the value to the requested register.
+ */
+static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
+			  int reg_num, u16 value)
+{
+	struct arc_emac_priv *priv = bus->priv;
+
+	dev_dbg(priv->dev,
+		"arc_mdio_write(phy_addr=%i, reg_num=%x, value=%x)\n",
+		phy_addr, reg_num, value);
+
+	arc_reg_set(priv, R_MDIO,
+		     0x50020000 | (phy_addr << 23) | (reg_num << 18) | value);
+
+	return arc_mdio_complete_wait(priv);
+}
+
+/**
+ * arc_mdio_probe - MDIO probe function.
+ * @pdev:	Pointer to platform device.
+ * @priv:	Pointer to ARC EMAC private data structure.
+ *
+ * returns:	0 on success, -ENOMEM when mdiobus_alloc
+ * (to allocate memory for MII bus structure) fails.
+ *
+ * Sets up and registers the MDIO interface.
+ */
+int arc_mdio_probe(struct platform_device *pdev, struct arc_emac_priv *priv)
+{
+	struct mii_bus *bus;
+	int error;
+
+	bus = mdiobus_alloc();
+	if (!bus)
+		return -ENOMEM;
+
+	priv->bus = bus;
+	bus->priv = priv;
+	bus->parent = priv->dev;
+	bus->name = "Synopsys MII Bus",
+	bus->read = &arc_mdio_read;
+	bus->write = &arc_mdio_write;
+
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
+
+	error = of_mdiobus_register(bus, pdev->dev.of_node);
+	if (error) {
+		dev_err(priv->dev, "cannot register MDIO bus %s\n", bus->name);
+		mdiobus_free(bus);
+		return error;
+	}
+
+	return 0;
+}
+
+/**
+ * arc_mdio_remove - MDIO remove function.
+ * @priv:	Pointer to ARC EMAC private data structure.
+ *
+ * Unregisters the MDIO and frees any associate memory for MII bus.
+ */
+int arc_mdio_remove(struct arc_emac_priv *priv)
+{
+	mdiobus_unregister(priv->bus);
+	mdiobus_free(priv->bus);
+	priv->bus = NULL;
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/arc/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/arc/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,31 @@
+#
+# ARC EMAC network device configuration
+#
+
+config NET_VENDOR_ARC
+	bool "ARC devices"
+	default y
+	---help---
+	  If you have a network (Ethernet) card belonging to this class, say Y
+	  and read the Ethernet-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+	  Note that the answer to this question doesn't directly affect the
+	  kernel: saying N will just cause the configurator to skip all
+	  the questions about ARC cards. If you say Y, you will be asked for
+	  your specific card in the following questions.
+
+if NET_VENDOR_ARC
+
+config ARC_EMAC
+	tristate "ARC EMAC support"
+	select MII
+	select PHYLIB
+	depends on OF_IRQ
+	depends on OF_NET
+	---help---
+	  On some legacy ARC (Synopsys) FPGA boards such as ARCAngel4/ML50x
+	  non-standard on-chip ethernet device ARC EMAC 10/100 is used.
+	  Say Y here if you have such a board.  If unsure, say N.
+
+endif # NET_VENDOR_ARC
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/arc/Makefile linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/Makefile
--- linux-libre-3.10-gnu/drivers/net/ethernet/arc/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/arc/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,6 @@
+#
+# Makefile for the ARC network device drivers.
+#
+
+arc_emac-objs := emac_main.o emac_mdio.o
+obj-$(CONFIG_ARC_EMAC) += arc_emac.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/alx.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/alx.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/alx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/alx.h	2013-08-25 20:43:22.000000000 -0400
@@ -85,16 +85,16 @@ struct alx_priv {
 	struct {
 		dma_addr_t dma;
 		void *virt;
-		int size;
+		unsigned int size;
 	} descmem;
 
 	/* protect int_mask updates */
 	spinlock_t irq_lock;
 	u32 int_mask;
 
-	int tx_ringsz;
-	int rx_ringsz;
-	int rxbuf_size;
+	unsigned int tx_ringsz;
+	unsigned int rx_ringsz;
+	unsigned int rxbuf_size;
 
 	struct napi_struct napi;
 	struct alx_tx_queue txq;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,21 +46,37 @@
 #include "reg.h"
 #include "hw.h"
 
+static u32 alx_get_supported_speeds(struct alx_hw *hw)
+{
+	u32 supported = SUPPORTED_10baseT_Half |
+			SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half |
+			SUPPORTED_100baseT_Full;
+
+	if (alx_hw_giga(hw))
+		supported |= SUPPORTED_1000baseT_Full;
+
+	BUILD_BUG_ON(SUPPORTED_10baseT_Half != ADVERTISED_10baseT_Half);
+	BUILD_BUG_ON(SUPPORTED_10baseT_Full != ADVERTISED_10baseT_Full);
+	BUILD_BUG_ON(SUPPORTED_100baseT_Half != ADVERTISED_100baseT_Half);
+	BUILD_BUG_ON(SUPPORTED_100baseT_Full != ADVERTISED_100baseT_Full);
+	BUILD_BUG_ON(SUPPORTED_1000baseT_Full != ADVERTISED_1000baseT_Full);
+
+	return supported;
+}
 
 static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct alx_priv *alx = netdev_priv(netdev);
 	struct alx_hw *hw = &alx->hw;
 
-	ecmd->supported = SUPPORTED_10baseT_Half |
-			  SUPPORTED_10baseT_Full |
-			  SUPPORTED_100baseT_Half |
-			  SUPPORTED_100baseT_Full |
-			  SUPPORTED_Autoneg |
+	ecmd->supported = SUPPORTED_Autoneg |
 			  SUPPORTED_TP |
-			  SUPPORTED_Pause;
+			  SUPPORTED_Pause |
+			  SUPPORTED_Asym_Pause;
 	if (alx_hw_giga(hw))
 		ecmd->supported |= SUPPORTED_1000baseT_Full;
+	ecmd->supported |= alx_get_supported_speeds(hw);
 
 	ecmd->advertising = ADVERTISED_TP;
 	if (hw->adv_cfg & ADVERTISED_Autoneg)
@@ -68,6 +84,7 @@ static int alx_get_settings(struct net_d
 
 	ecmd->port = PORT_TP;
 	ecmd->phy_address = 0;
+
 	if (hw->adv_cfg & ADVERTISED_Autoneg)
 		ecmd->autoneg = AUTONEG_ENABLE;
 	else
@@ -85,14 +102,8 @@ static int alx_get_settings(struct net_d
 		}
 	}
 
-	if (hw->link_speed != SPEED_UNKNOWN) {
-		ethtool_cmd_speed_set(ecmd,
-				      hw->link_speed - hw->link_speed % 10);
-		ecmd->duplex = hw->link_speed % 10;
-	} else {
-		ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
-		ecmd->duplex = DUPLEX_UNKNOWN;
-	}
+	ethtool_cmd_speed_set(ecmd, hw->link_speed);
+	ecmd->duplex = hw->duplex;
 
 	return 0;
 }
@@ -106,28 +117,15 @@ static int alx_set_settings(struct net_d
 	ASSERT_RTNL();
 
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
-		if (ecmd->advertising & ADVERTISED_1000baseT_Half)
+		if (ecmd->advertising & ~alx_get_supported_speeds(hw))
 			return -EINVAL;
 		adv_cfg = ecmd->advertising | ADVERTISED_Autoneg;
 	} else {
-		int speed = ethtool_cmd_speed(ecmd);
+		adv_cfg = alx_speed_to_ethadv(ethtool_cmd_speed(ecmd),
+					      ecmd->duplex);
 
-		switch (speed + ecmd->duplex) {
-		case SPEED_10 + DUPLEX_HALF:
-			adv_cfg = ADVERTISED_10baseT_Half;
-			break;
-		case SPEED_10 + DUPLEX_FULL:
-			adv_cfg = ADVERTISED_10baseT_Full;
-			break;
-		case SPEED_100 + DUPLEX_HALF:
-			adv_cfg = ADVERTISED_100baseT_Half;
-			break;
-		case SPEED_100 + DUPLEX_FULL:
-			adv_cfg = ADVERTISED_100baseT_Full;
-			break;
-		default:
+		if (!adv_cfg || adv_cfg == ADVERTISED_1000baseT_Full)
 			return -EINVAL;
-		}
 	}
 
 	hw->adv_cfg = adv_cfg;
@@ -140,21 +138,10 @@ static void alx_get_pauseparam(struct ne
 	struct alx_priv *alx = netdev_priv(netdev);
 	struct alx_hw *hw = &alx->hw;
 
-	if (hw->flowctrl & ALX_FC_ANEG &&
-	    hw->adv_cfg & ADVERTISED_Autoneg)
-		pause->autoneg = AUTONEG_ENABLE;
-	else
-		pause->autoneg = AUTONEG_DISABLE;
-
-	if (hw->flowctrl & ALX_FC_TX)
-		pause->tx_pause = 1;
-	else
-		pause->tx_pause = 0;
-
-	if (hw->flowctrl & ALX_FC_RX)
-		pause->rx_pause = 1;
-	else
-		pause->rx_pause = 0;
+	pause->autoneg = !!(hw->flowctrl & ALX_FC_ANEG &&
+			    hw->adv_cfg & ADVERTISED_Autoneg);
+	pause->tx_pause = !!(hw->flowctrl & ALX_FC_TX);
+	pause->rx_pause = !!(hw->flowctrl & ALX_FC_RX);
 }
 
 
@@ -187,7 +174,8 @@ static int alx_set_pauseparam(struct net
 
 	if (reconfig_phy) {
 		err = alx_setup_speed_duplex(hw, hw->adv_cfg, fc);
-		return err;
+		if (err)
+			return err;
 	}
 
 	/* flow control on mac */
@@ -213,60 +201,12 @@ static void alx_set_msglevel(struct net_
 	alx->msg_enable = data;
 }
 
-static void alx_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-{
-	struct alx_priv *alx = netdev_priv(netdev);
-	struct alx_hw *hw = &alx->hw;
-
-	wol->supported = WAKE_MAGIC | WAKE_PHY;
-	wol->wolopts = 0;
-
-	if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC)
-		wol->wolopts |= WAKE_MAGIC;
-	if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY)
-		wol->wolopts |= WAKE_PHY;
-}
-
-static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-{
-	struct alx_priv *alx = netdev_priv(netdev);
-	struct alx_hw *hw = &alx->hw;
-
-	if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
-			    WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
-		return -EOPNOTSUPP;
-
-	hw->sleep_ctrl = 0;
-
-	if (wol->wolopts & WAKE_MAGIC)
-		hw->sleep_ctrl |= ALX_SLEEP_WOL_MAGIC;
-	if (wol->wolopts & WAKE_PHY)
-		hw->sleep_ctrl |= ALX_SLEEP_WOL_PHY;
-
-	device_set_wakeup_enable(&alx->hw.pdev->dev, hw->sleep_ctrl);
-
-	return 0;
-}
-
-static void alx_get_drvinfo(struct net_device *netdev,
-			    struct ethtool_drvinfo *drvinfo)
-{
-	struct alx_priv *alx = netdev_priv(netdev);
-
-	strlcpy(drvinfo->driver, alx_drv_name, sizeof(drvinfo->driver));
-	strlcpy(drvinfo->bus_info, pci_name(alx->hw.pdev),
-		sizeof(drvinfo->bus_info));
-}
-
 const struct ethtool_ops alx_ethtool_ops = {
 	.get_settings	= alx_get_settings,
 	.set_settings	= alx_set_settings,
 	.get_pauseparam	= alx_get_pauseparam,
 	.set_pauseparam	= alx_set_pauseparam,
-	.get_drvinfo	= alx_get_drvinfo,
 	.get_msglevel	= alx_get_msglevel,
 	.set_msglevel	= alx_set_msglevel,
-	.get_wol	= alx_get_wol,
-	.set_wol	= alx_set_wol,
 	.get_link	= ethtool_op_get_link,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/hw.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/hw.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -282,8 +282,8 @@ static bool alx_read_macaddr(struct alx_
 	mac1 = alx_read_mem32(hw, ALX_STAD1);
 
 	/* addr should be big-endian */
-	*(__be32 *)(addr + 2) = cpu_to_be32(mac0);
-	*(__be16 *)addr = cpu_to_be16(mac1);
+	put_unaligned(cpu_to_be32(mac0), (__be32 *)(addr + 2));
+	put_unaligned(cpu_to_be16(mac1), (__be16 *)addr);
 
 	return is_valid_ether_addr(addr);
 }
@@ -326,22 +326,12 @@ void alx_set_macaddr(struct alx_hw *hw,
 	u32 val;
 
 	/* for example: 00-0B-6A-F6-00-DC * STAD0=6AF600DC, STAD1=000B */
-	val = be32_to_cpu(*(__be32 *)(addr + 2));
+	val = be32_to_cpu(get_unaligned((__be32 *)(addr + 2)));
 	alx_write_mem32(hw, ALX_STAD0, val);
-	val = be16_to_cpu(*(__be16 *)addr);
+	val = be16_to_cpu(get_unaligned((__be16 *)addr));
 	alx_write_mem32(hw, ALX_STAD1, val);
 }
 
-static void alx_enable_osc(struct alx_hw *hw)
-{
-	u32 val;
-
-	/* rising edge */
-	val = alx_read_mem32(hw, ALX_MISC);
-	alx_write_mem32(hw, ALX_MISC, val & ~ALX_MISC_INTNLOSC_OPEN);
-	alx_write_mem32(hw, ALX_MISC, val | ALX_MISC_INTNLOSC_OPEN);
-}
-
 static void alx_reset_osc(struct alx_hw *hw, u8 rev)
 {
 	u32 val, val2;
@@ -624,12 +614,12 @@ void alx_start_mac(struct alx_hw *hw)
 	alx_write_mem32(hw, ALX_TXQ0, txq | ALX_TXQ0_EN);
 
 	mac = hw->rx_ctrl;
-	if (hw->link_speed % 10 == DUPLEX_FULL)
+	if (hw->duplex == DUPLEX_FULL)
 		mac |= ALX_MAC_CTRL_FULLD;
 	else
 		mac &= ~ALX_MAC_CTRL_FULLD;
 	ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED,
-		      hw->link_speed >= SPEED_1000 ? ALX_MAC_CTRL_SPEED_1000 :
+		      hw->link_speed == SPEED_1000 ? ALX_MAC_CTRL_SPEED_1000 :
 						     ALX_MAC_CTRL_SPEED_10_100);
 	mac |= ALX_MAC_CTRL_TX_EN | ALX_MAC_CTRL_RX_EN;
 	hw->rx_ctrl = mac;
@@ -790,28 +780,22 @@ void alx_post_phy_link(struct alx_hw *hw
 	u16 phy_val, len, agc;
 	u8 revid = alx_hw_revision(hw);
 	bool adj_th = revid == ALX_REV_B0;
-	int speed;
-
-	if (hw->link_speed == SPEED_UNKNOWN)
-		speed = SPEED_UNKNOWN;
-	else
-		speed = hw->link_speed - hw->link_speed % 10;
 
 	if (revid != ALX_REV_B0 && !alx_is_rev_a(revid))
 		return;
 
 	/* 1000BT/AZ, wrong cable length */
-	if (speed != SPEED_UNKNOWN) {
+	if (hw->link_speed != SPEED_UNKNOWN) {
 		alx_read_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL6,
 				 &phy_val);
 		len = ALX_GET_FIELD(phy_val, ALX_CLDCTRL6_CAB_LEN);
 		alx_read_phy_dbg(hw, ALX_MIIDBG_AGC, &phy_val);
 		agc = ALX_GET_FIELD(phy_val, ALX_AGC_2_VGA);
 
-		if ((speed == SPEED_1000 &&
+		if ((hw->link_speed == SPEED_1000 &&
 		     (len > ALX_CLDCTRL6_CAB_LEN_SHORT1G ||
 		      (len == 0 && agc > ALX_AGC_LONG1G_LIMT))) ||
-		    (speed == SPEED_100 &&
+		    (hw->link_speed == SPEED_100 &&
 		     (len > ALX_CLDCTRL6_CAB_LEN_SHORT100M ||
 		      (len == 0 && agc > ALX_AGC_LONG100M_LIMT)))) {
 			alx_write_phy_dbg(hw, ALX_MIIDBG_AZ_ANADECT,
@@ -831,10 +815,10 @@ void alx_post_phy_link(struct alx_hw *hw
 
 		/* threshold adjust */
 		if (adj_th && hw->lnk_patch) {
-			if (speed == SPEED_100) {
+			if (hw->link_speed == SPEED_100) {
 				alx_write_phy_dbg(hw, ALX_MIIDBG_MSE16DB,
 						  ALX_MSE16DB_UP);
-			} else if (speed == SPEED_1000) {
+			} else if (hw->link_speed == SPEED_1000) {
 				/*
 				 * Giga link threshold, raise the tolerance of
 				 * noise 50%
@@ -864,66 +848,6 @@ void alx_post_phy_link(struct alx_hw *hw
 	}
 }
 
-
-/* NOTE:
- *    1. phy link must be established before calling this function
- *    2. wol option (pattern,magic,link,etc.) is configed before call it.
- */
-int alx_pre_suspend(struct alx_hw *hw, int speed)
-{
-	u32 master, mac, phy, val;
-	int err = 0;
-
-	master = alx_read_mem32(hw, ALX_MASTER);
-	master &= ~ALX_MASTER_PCLKSEL_SRDS;
-	mac = hw->rx_ctrl;
-	/* 10/100 half */
-	ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED,  ALX_MAC_CTRL_SPEED_10_100);
-	mac &= ~(ALX_MAC_CTRL_FULLD | ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_TX_EN);
-
-	phy = alx_read_mem32(hw, ALX_PHY_CTRL);
-	phy &= ~(ALX_PHY_CTRL_DSPRST_OUT | ALX_PHY_CTRL_CLS);
-	phy |= ALX_PHY_CTRL_RST_ANALOG | ALX_PHY_CTRL_HIB_PULSE |
-	       ALX_PHY_CTRL_HIB_EN;
-
-	/* without any activity  */
-	if (!(hw->sleep_ctrl & ALX_SLEEP_ACTIVE)) {
-		err = alx_write_phy_reg(hw, ALX_MII_IER, 0);
-		if (err)
-			return err;
-		phy |= ALX_PHY_CTRL_IDDQ | ALX_PHY_CTRL_POWER_DOWN;
-	} else {
-		if (hw->sleep_ctrl & (ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_CIFS))
-			mac |= ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_BRD_EN;
-		if (hw->sleep_ctrl & ALX_SLEEP_CIFS)
-			mac |= ALX_MAC_CTRL_TX_EN;
-		if (speed % 10 == DUPLEX_FULL)
-			mac |= ALX_MAC_CTRL_FULLD;
-		if (speed >= SPEED_1000)
-			ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED,
-				      ALX_MAC_CTRL_SPEED_1000);
-		phy |= ALX_PHY_CTRL_DSPRST_OUT;
-		err = alx_write_phy_ext(hw, ALX_MIIEXT_ANEG,
-					ALX_MIIEXT_S3DIG10,
-					ALX_MIIEXT_S3DIG10_SL);
-		if (err)
-			return err;
-	}
-
-	alx_enable_osc(hw);
-	hw->rx_ctrl = mac;
-	alx_write_mem32(hw, ALX_MASTER, master);
-	alx_write_mem32(hw, ALX_MAC_CTRL, mac);
-	alx_write_mem32(hw, ALX_PHY_CTRL, phy);
-
-	/* set val of PDLL D3PLLOFF */
-	val = alx_read_mem32(hw, ALX_PDLL_TRNS1);
-	val |= ALX_PDLL_TRNS1_D3PLLOFF_EN;
-	alx_write_mem32(hw, ALX_PDLL_TRNS1, val);
-
-	return 0;
-}
-
 bool alx_phy_configured(struct alx_hw *hw)
 {
 	u32 cfg, hw_cfg;
@@ -938,7 +862,7 @@ bool alx_phy_configured(struct alx_hw *h
 	return cfg == hw_cfg;
 }
 
-int alx_get_phy_link(struct alx_hw *hw, int *speed)
+int alx_read_phy_link(struct alx_hw *hw)
 {
 	struct pci_dev *pdev = hw->pdev;
 	u16 bmsr, giga;
@@ -953,7 +877,8 @@ int alx_get_phy_link(struct alx_hw *hw,
 		return err;
 
 	if (!(bmsr & BMSR_LSTATUS)) {
-		*speed = SPEED_UNKNOWN;
+		hw->link_speed = SPEED_UNKNOWN;
+		hw->duplex = DUPLEX_UNKNOWN;
 		return 0;
 	}
 
@@ -967,20 +892,20 @@ int alx_get_phy_link(struct alx_hw *hw,
 
 	switch (giga & ALX_GIGA_PSSR_SPEED) {
 	case ALX_GIGA_PSSR_1000MBS:
-		*speed = SPEED_1000;
+		hw->link_speed = SPEED_1000;
 		break;
 	case ALX_GIGA_PSSR_100MBS:
-		*speed = SPEED_100;
+		hw->link_speed = SPEED_100;
 		break;
 	case ALX_GIGA_PSSR_10MBS:
-		*speed = SPEED_10;
+		hw->link_speed = SPEED_10;
 		break;
 	default:
 		goto wrong_speed;
 	}
 
-	*speed += (giga & ALX_GIGA_PSSR_DPLX) ? DUPLEX_FULL : DUPLEX_HALF;
-	return 1;
+	hw->duplex = (giga & ALX_GIGA_PSSR_DPLX) ? DUPLEX_FULL : DUPLEX_HALF;
+	return 0;
 
 wrong_speed:
 	dev_err(&pdev->dev, "invalid PHY speed/duplex: 0x%x\n", giga);
@@ -995,26 +920,6 @@ int alx_clear_phy_intr(struct alx_hw *hw
 	return alx_read_phy_reg(hw, ALX_MII_ISR, &isr);
 }
 
-int alx_config_wol(struct alx_hw *hw)
-{
-	u32 wol = 0;
-	int err = 0;
-
-	/* turn on magic packet event */
-	if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC)
-		wol |= ALX_WOL0_MAGIC_EN | ALX_WOL0_PME_MAGIC_EN;
-
-	/* turn on link up event */
-	if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY) {
-		wol |=  ALX_WOL0_LINK_EN | ALX_WOL0_PME_LINK;
-		/* only link up can wake up */
-		err = alx_write_phy_reg(hw, ALX_MII_IER, ALX_IER_LINK_UP);
-	}
-	alx_write_mem32(hw, ALX_WOL0, wol);
-
-	return err;
-}
-
 void alx_disable_rss(struct alx_hw *hw)
 {
 	u32 ctrl = alx_read_mem32(hw, ALX_RXQ0);
@@ -1126,85 +1031,6 @@ void alx_configure_basic(struct alx_hw *
 	alx_write_mem32(hw, ALX_WRR, val);
 }
 
-static inline u32 alx_speed_to_ethadv(int speed)
-{
-	switch (speed) {
-	case SPEED_1000 + DUPLEX_FULL:
-		return ADVERTISED_1000baseT_Full;
-	case SPEED_100 + DUPLEX_FULL:
-		return ADVERTISED_100baseT_Full;
-	case SPEED_100 + DUPLEX_HALF:
-		return ADVERTISED_10baseT_Half;
-	case SPEED_10 + DUPLEX_FULL:
-		return ADVERTISED_10baseT_Full;
-	case SPEED_10 + DUPLEX_HALF:
-		return ADVERTISED_10baseT_Half;
-	default:
-		return 0;
-	}
-}
-
-int alx_select_powersaving_speed(struct alx_hw *hw, int *speed)
-{
-	int i, err, spd;
-	u16 lpa;
-
-	err = alx_get_phy_link(hw, &spd);
-	if (err < 0)
-		return err;
-
-	if (spd == SPEED_UNKNOWN)
-		return 0;
-
-	err = alx_read_phy_reg(hw, MII_LPA, &lpa);
-	if (err)
-		return err;
-
-	if (!(lpa & LPA_LPACK)) {
-		*speed = spd;
-		return 0;
-	}
-
-	if (lpa & LPA_10FULL)
-		*speed = SPEED_10 + DUPLEX_FULL;
-	else if (lpa & LPA_10HALF)
-		*speed = SPEED_10 + DUPLEX_HALF;
-	else if (lpa & LPA_100FULL)
-		*speed = SPEED_100 + DUPLEX_FULL;
-	else
-		*speed = SPEED_100 + DUPLEX_HALF;
-
-	if (*speed != spd) {
-		err = alx_write_phy_reg(hw, ALX_MII_IER, 0);
-		if (err)
-			return err;
-		err = alx_setup_speed_duplex(hw,
-					     alx_speed_to_ethadv(*speed) |
-					     ADVERTISED_Autoneg,
-					     ALX_FC_ANEG | ALX_FC_RX |
-					     ALX_FC_TX);
-		if (err)
-			return err;
-
-		/* wait for linkup */
-		for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) {
-			int speed2;
-
-			msleep(100);
-
-			err = alx_get_phy_link(hw, &speed2);
-			if (err < 0)
-				return err;
-			if (speed2 != SPEED_UNKNOWN)
-				break;
-		}
-		if (i == ALX_MAX_SETUP_LNK_CYCLE)
-			return -ETIMEDOUT;
-	}
-
-	return 0;
-}
-
 bool alx_get_phy_info(struct alx_hw *hw)
 {
 	u16  devs1, devs2;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/hw.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/hw.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -412,12 +412,11 @@ struct alx_hw {
 	u32 smb_timer;
 	/* SPEED_* + DUPLEX_*, SPEED_UNKNOWN if link is down */
 	int link_speed;
+	u8 duplex;
 
 	/* auto-neg advertisement or force mode config */
-	u32 adv_cfg;
 	u8 flowctrl;
-
-	u32 sleep_ctrl;
+	u32 adv_cfg;
 
 	spinlock_t mdio_lock;
 	struct mdio_if_info mdio;
@@ -478,14 +477,12 @@ void alx_reset_pcie(struct alx_hw *hw);
 void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en);
 int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl);
 void alx_post_phy_link(struct alx_hw *hw);
-int alx_pre_suspend(struct alx_hw *hw, int speed);
 int alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data);
 int alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data);
 int alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata);
 int alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data);
-int alx_get_phy_link(struct alx_hw *hw, int *speed);
+int alx_read_phy_link(struct alx_hw *hw);
 int alx_clear_phy_intr(struct alx_hw *hw);
-int alx_config_wol(struct alx_hw *hw);
 void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc);
 void alx_start_mac(struct alx_hw *hw);
 int alx_reset_mac(struct alx_hw *hw);
@@ -493,7 +490,21 @@ void alx_set_macaddr(struct alx_hw *hw,
 bool alx_phy_configured(struct alx_hw *hw);
 void alx_configure_basic(struct alx_hw *hw);
 void alx_disable_rss(struct alx_hw *hw);
-int alx_select_powersaving_speed(struct alx_hw *hw, int *speed);
 bool alx_get_phy_info(struct alx_hw *hw);
 
+static inline u32 alx_speed_to_ethadv(int speed, u8 duplex)
+{
+	if (speed == SPEED_1000 && duplex == DUPLEX_FULL)
+		return ADVERTISED_1000baseT_Full;
+	if (speed == SPEED_100 && duplex == DUPLEX_FULL)
+		return ADVERTISED_100baseT_Full;
+	if (speed == SPEED_100 && duplex== DUPLEX_HALF)
+		return ADVERTISED_100baseT_Half;
+	if (speed == SPEED_10 && duplex == DUPLEX_FULL)
+		return ADVERTISED_10baseT_Full;
+	if (speed == SPEED_10 && duplex == DUPLEX_HALF)
+		return ADVERTISED_10baseT_Half;
+	return 0;
+}
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/alx/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/alx/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -706,12 +706,12 @@ static int alx_init_sw(struct alx_priv *
 	alx->rxbuf_size = ALIGN(ALX_RAW_MTU(hw->mtu), 8);
 	alx->tx_ringsz = 256;
 	alx->rx_ringsz = 512;
-	hw->sleep_ctrl = ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_WOL_PHY;
 	hw->imt = 200;
 	alx->int_mask = ALX_ISR_MISC;
 	hw->dma_chnl = hw->max_dma_chnl;
 	hw->ith_tpd = alx->tx_ringsz / 3;
 	hw->link_speed = SPEED_UNKNOWN;
+	hw->duplex = DUPLEX_UNKNOWN;
 	hw->adv_cfg = ADVERTISED_Autoneg |
 		      ADVERTISED_10baseT_Half |
 		      ADVERTISED_10baseT_Full |
@@ -758,6 +758,7 @@ static void alx_halt(struct alx_priv *al
 
 	alx_netif_stop(alx);
 	hw->link_speed = SPEED_UNKNOWN;
+	hw->duplex = DUPLEX_UNKNOWN;
 
 	alx_reset_mac(hw);
 
@@ -869,18 +870,18 @@ static void __alx_stop(struct alx_priv *
 	alx_free_rings(alx);
 }
 
-static const char *alx_speed_desc(u16 speed)
+static const char *alx_speed_desc(struct alx_hw *hw)
 {
-	switch (speed) {
-	case SPEED_1000 + DUPLEX_FULL:
+	switch (alx_speed_to_ethadv(hw->link_speed, hw->duplex)) {
+	case ADVERTISED_1000baseT_Full:
 		return "1 Gbps Full";
-	case SPEED_100 + DUPLEX_FULL:
+	case ADVERTISED_100baseT_Full:
 		return "100 Mbps Full";
-	case SPEED_100 + DUPLEX_HALF:
+	case ADVERTISED_100baseT_Half:
 		return "100 Mbps Half";
-	case SPEED_10 + DUPLEX_FULL:
+	case ADVERTISED_10baseT_Full:
 		return "10 Mbps Full";
-	case SPEED_10 + DUPLEX_HALF:
+	case ADVERTISED_10baseT_Half:
 		return "10 Mbps Half";
 	default:
 		return "Unknown speed";
@@ -891,7 +892,8 @@ static void alx_check_link(struct alx_pr
 {
 	struct alx_hw *hw = &alx->hw;
 	unsigned long flags;
-	int speed, old_speed;
+	int old_speed;
+	u8 old_duplex;
 	int err;
 
 	/* clear PHY internal interrupt status, otherwise the main
@@ -899,7 +901,9 @@ static void alx_check_link(struct alx_pr
 	 */
 	alx_clear_phy_intr(hw);
 
-	err = alx_get_phy_link(hw, &speed);
+	old_speed = hw->link_speed;
+	old_duplex = hw->duplex;
+	err = alx_read_phy_link(hw);
 	if (err < 0)
 		goto reset;
 
@@ -908,15 +912,12 @@ static void alx_check_link(struct alx_pr
 	alx_write_mem32(hw, ALX_IMR, alx->int_mask);
 	spin_unlock_irqrestore(&alx->irq_lock, flags);
 
-	old_speed = hw->link_speed;
-
-	if (old_speed == speed)
+	if (old_speed == hw->link_speed)
 		return;
-	hw->link_speed = speed;
 
-	if (speed != SPEED_UNKNOWN) {
+	if (hw->link_speed != SPEED_UNKNOWN) {
 		netif_info(alx, link, alx->dev,
-			   "NIC Up: %s\n", alx_speed_desc(speed));
+			   "NIC Up: %s\n", alx_speed_desc(hw));
 		alx_post_phy_link(hw);
 		alx_enable_aspm(hw, true, true);
 		alx_start_mac(hw);
@@ -959,65 +960,6 @@ static int alx_stop(struct net_device *n
 	return 0;
 }
 
-static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en)
-{
-	struct alx_priv *alx = pci_get_drvdata(pdev);
-	struct net_device *netdev = alx->dev;
-	struct alx_hw *hw = &alx->hw;
-	int err, speed;
-
-	netif_device_detach(netdev);
-
-	if (netif_running(netdev))
-		__alx_stop(alx);
-
-#ifdef CONFIG_PM_SLEEP
-	err = pci_save_state(pdev);
-	if (err)
-		return err;
-#endif
-
-	err = alx_select_powersaving_speed(hw, &speed);
-	if (err)
-		return err;
-	err = alx_clear_phy_intr(hw);
-	if (err)
-		return err;
-	err = alx_pre_suspend(hw, speed);
-	if (err)
-		return err;
-	err = alx_config_wol(hw);
-	if (err)
-		return err;
-
-	*wol_en = false;
-	if (hw->sleep_ctrl & ALX_SLEEP_ACTIVE) {
-		netif_info(alx, wol, netdev,
-			   "wol: ctrl=%X, speed=%X\n",
-			   hw->sleep_ctrl, speed);
-		device_set_wakeup_enable(&pdev->dev, true);
-		*wol_en = true;
-	}
-
-	pci_disable_device(pdev);
-
-	return 0;
-}
-
-static void alx_shutdown(struct pci_dev *pdev)
-{
-	int err;
-	bool wol_en;
-
-	err = __alx_shutdown(pdev, &wol_en);
-	if (!err) {
-		pci_wake_from_d3(pdev, wol_en);
-		pci_set_power_state(pdev, PCI_D3hot);
-	} else {
-		dev_err(&pdev->dev, "shutdown fail %d\n", err);
-	}
-}
-
 static void alx_link_check(struct work_struct *work)
 {
 	struct alx_priv *alx;
@@ -1303,6 +1245,8 @@ static int alx_probe(struct pci_dev *pde
 
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 	alx = netdev_priv(netdev);
+	spin_lock_init(&alx->hw.mdio_lock);
+	spin_lock_init(&alx->irq_lock);
 	alx->dev = netdev;
 	alx->hw.pdev = pdev;
 	alx->msg_enable = NETIF_MSG_LINK | NETIF_MSG_HW | NETIF_MSG_IFUP |
@@ -1385,9 +1329,6 @@ static int alx_probe(struct pci_dev *pde
 
 	INIT_WORK(&alx->link_check_wk, alx_link_check);
 	INIT_WORK(&alx->reset_wk, alx_reset);
-	spin_lock_init(&alx->hw.mdio_lock);
-	spin_lock_init(&alx->irq_lock);
-
 	netif_carrier_off(netdev);
 
 	err = register_netdev(netdev);
@@ -1396,8 +1337,6 @@ static int alx_probe(struct pci_dev *pde
 		goto out_unmap;
 	}
 
-	device_set_wakeup_enable(&pdev->dev, hw->sleep_ctrl);
-
 	netdev_info(netdev,
 		    "Qualcomm Atheros AR816x/AR817x Ethernet [%pM]\n",
 		    netdev->dev_addr);
@@ -1442,22 +1381,12 @@ static void alx_remove(struct pci_dev *p
 static int alx_suspend(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
-	int err;
-	bool wol_en;
-
-	err = __alx_shutdown(pdev, &wol_en);
-	if (err) {
-		dev_err(&pdev->dev, "shutdown fail in suspend %d\n", err);
-		return err;
-	}
-
-	if (wol_en) {
-		pci_prepare_to_sleep(pdev);
-	} else {
-		pci_wake_from_d3(pdev, false);
-		pci_set_power_state(pdev, PCI_D3hot);
-	}
+	struct alx_priv *alx = pci_get_drvdata(pdev);
 
+	if (!netif_running(alx->dev))
+		return 0;
+	netif_device_detach(alx->dev);
+	__alx_stop(alx);
 	return 0;
 }
 
@@ -1465,49 +1394,20 @@ static int alx_resume(struct device *dev
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct alx_priv *alx = pci_get_drvdata(pdev);
-	struct net_device *netdev = alx->dev;
-	struct alx_hw *hw = &alx->hw;
-	int err;
-
-	pci_set_power_state(pdev, PCI_D0);
-	pci_restore_state(pdev);
-	pci_save_state(pdev);
-
-	pci_enable_wake(pdev, PCI_D3hot, 0);
-	pci_enable_wake(pdev, PCI_D3cold, 0);
 
-	hw->link_speed = SPEED_UNKNOWN;
-	alx->int_mask = ALX_ISR_MISC;
-
-	alx_reset_pcie(hw);
-	alx_reset_phy(hw);
-
-	err = alx_reset_mac(hw);
-	if (err) {
-		netif_err(alx, hw, alx->dev,
-			  "resume:reset_mac fail %d\n", err);
-		return -EIO;
-	}
-
-	err = alx_setup_speed_duplex(hw, hw->adv_cfg, hw->flowctrl);
-	if (err) {
-		netif_err(alx, hw, alx->dev,
-			  "resume:setup_speed_duplex fail %d\n", err);
-		return -EIO;
-	}
-
-	if (netif_running(netdev)) {
-		err = __alx_open(alx, true);
-		if (err)
-			return err;
-	}
-
-	netif_device_attach(netdev);
-
-	return err;
+	if (!netif_running(alx->dev))
+		return 0;
+	netif_device_attach(alx->dev);
+	return __alx_open(alx, true);
 }
+
+static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
+#define ALX_PM_OPS      (&alx_pm_ops)
+#else
+#define ALX_PM_OPS      NULL
 #endif
 
+
 static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev,
 					       pci_channel_state_t state)
 {
@@ -1550,8 +1450,6 @@ static pci_ers_result_t alx_pci_error_sl
 	}
 
 	pci_set_master(pdev);
-	pci_enable_wake(pdev, PCI_D3hot, 0);
-	pci_enable_wake(pdev, PCI_D3cold, 0);
 
 	alx_reset_pcie(hw);
 	if (!alx_reset_mac(hw))
@@ -1587,13 +1485,6 @@ static const struct pci_error_handlers a
 	.resume         = alx_pci_error_resume,
 };
 
-#ifdef CONFIG_PM_SLEEP
-static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
-#define ALX_PM_OPS      (&alx_pm_ops)
-#else
-#define ALX_PM_OPS      NULL
-#endif
-
 static DEFINE_PCI_DEVICE_TABLE(alx_pci_tbl) = {
 	{ PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8161),
 	  .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG },
@@ -1611,7 +1502,6 @@ static struct pci_driver alx_driver = {
 	.id_table    = alx_pci_tbl,
 	.probe       = alx_probe,
 	.remove      = alx_remove,
-	.shutdown    = alx_shutdown,
 	.err_handler = &alx_err_handlers,
 	.driver.pm   = ALX_PM_OPS,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/atl1c/atl1c.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/atl1c/atl1c.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/atl1c/atl1c.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/atl1c/atl1c.h	2013-08-25 20:43:22.000000000 -0400
@@ -520,6 +520,9 @@ struct atl1c_adapter {
 	struct net_device   *netdev;
 	struct pci_dev      *pdev;
 	struct napi_struct  napi;
+	struct page         *rx_page;
+	unsigned int	    rx_page_offset;
+	unsigned int	    rx_frag_size;
 	struct atl1c_hw        hw;
 	struct atl1c_hw_stats  hw_stats;
 	struct mii_if_info  mii;    /* MII interface info */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/atl1c/atl1c_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/atl1c/atl1c_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/atl1c/atl1c_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -481,10 +481,15 @@ static int atl1c_set_mac_addr(struct net
 static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
 				struct net_device *dev)
 {
+	unsigned int head_size;
 	int mtu = dev->mtu;
 
 	adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
 		roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;
+
+	head_size = SKB_DATA_ALIGN(adapter->rx_buffer_len + NET_SKB_PAD) +
+		    SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+	adapter->rx_frag_size = roundup_pow_of_two(head_size);
 }
 
 static netdev_features_t atl1c_fix_features(struct net_device *netdev,
@@ -952,6 +957,10 @@ static void atl1c_free_ring_resources(st
 		kfree(adapter->tpd_ring[0].buffer_info);
 		adapter->tpd_ring[0].buffer_info = NULL;
 	}
+	if (adapter->rx_page) {
+		put_page(adapter->rx_page);
+		adapter->rx_page = NULL;
+	}
 }
 
 /**
@@ -1639,6 +1648,35 @@ static inline void atl1c_rx_checksum(str
 	skb_checksum_none_assert(skb);
 }
 
+static struct sk_buff *atl1c_alloc_skb(struct atl1c_adapter *adapter)
+{
+	struct sk_buff *skb;
+	struct page *page;
+
+	if (adapter->rx_frag_size > PAGE_SIZE)
+		return netdev_alloc_skb(adapter->netdev,
+					adapter->rx_buffer_len);
+
+	page = adapter->rx_page;
+	if (!page) {
+		adapter->rx_page = page = alloc_page(GFP_ATOMIC);
+		if (unlikely(!page))
+			return NULL;
+		adapter->rx_page_offset = 0;
+	}
+
+	skb = build_skb(page_address(page) + adapter->rx_page_offset,
+			adapter->rx_frag_size);
+	if (likely(skb)) {
+		adapter->rx_page_offset += adapter->rx_frag_size;
+		if (adapter->rx_page_offset >= PAGE_SIZE)
+			adapter->rx_page = NULL;
+		else
+			get_page(page);
+	}
+	return skb;
+}
+
 static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter)
 {
 	struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring;
@@ -1660,7 +1698,7 @@ static int atl1c_alloc_rx_buffer(struct
 	while (next_info->flags & ATL1C_BUFFER_FREE) {
 		rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
 
-		skb = netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len);
+		skb = atl1c_alloc_skb(adapter);
 		if (unlikely(!skb)) {
 			if (netif_msg_rx_err(adapter))
 				dev_warn(&pdev->dev, "alloc rx buffer failed\n");
@@ -2755,27 +2793,4 @@ static struct pci_driver atl1c_driver =
 	.driver.pm = &atl1c_pm_ops,
 };
 
-/**
- * atl1c_init_module - Driver Registration Routine
- *
- * atl1c_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- */
-static int __init atl1c_init_module(void)
-{
-	return pci_register_driver(&atl1c_driver);
-}
-
-/**
- * atl1c_exit_module - Driver Exit Cleanup Routine
- *
- * atl1c_exit_module is called just before the driver is removed
- * from memory.
- */
-static void __exit atl1c_exit_module(void)
-{
-	pci_unregister_driver(&atl1c_driver);
-}
-
-module_init(atl1c_init_module);
-module_exit(atl1c_exit_module);
+module_pci_driver(atl1c_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/atl1e/atl1e_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/atl1e/atl1e_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/atl1e/atl1e_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1665,8 +1665,8 @@ check_sum:
 	return 0;
 }
 
-static void atl1e_tx_map(struct atl1e_adapter *adapter,
-		      struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
+static int atl1e_tx_map(struct atl1e_adapter *adapter,
+			struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
 {
 	struct atl1e_tpd_desc *use_tpd = NULL;
 	struct atl1e_tx_buffer *tx_buffer = NULL;
@@ -1677,6 +1677,8 @@ static void atl1e_tx_map(struct atl1e_ad
 	u16 nr_frags;
 	u16 f;
 	int segment;
+	int ring_start = adapter->tx_ring.next_to_use;
+	int ring_end;
 
 	nr_frags = skb_shinfo(skb)->nr_frags;
 	segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
@@ -1689,6 +1691,9 @@ static void atl1e_tx_map(struct atl1e_ad
 		tx_buffer->length = map_len;
 		tx_buffer->dma = pci_map_single(adapter->pdev,
 					skb->data, hdr_len, PCI_DMA_TODEVICE);
+		if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma))
+			return -ENOSPC;
+
 		ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
 		mapped_len += map_len;
 		use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
@@ -1715,6 +1720,22 @@ static void atl1e_tx_map(struct atl1e_ad
 		tx_buffer->dma =
 			pci_map_single(adapter->pdev, skb->data + mapped_len,
 					map_len, PCI_DMA_TODEVICE);
+
+		if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) {
+			/* We need to unwind the mappings we've done */
+			ring_end = adapter->tx_ring.next_to_use;
+			adapter->tx_ring.next_to_use = ring_start;
+			while (adapter->tx_ring.next_to_use != ring_end) {
+				tpd = atl1e_get_tpd(adapter);
+				tx_buffer = atl1e_get_tx_buffer(adapter, tpd);
+				pci_unmap_single(adapter->pdev, tx_buffer->dma,
+						 tx_buffer->length, PCI_DMA_TODEVICE);
+			}
+			/* Reset the tx rings next pointer */
+			adapter->tx_ring.next_to_use = ring_start;
+			return -ENOSPC;
+		}
+
 		ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
 		mapped_len  += map_len;
 		use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
@@ -1750,6 +1771,23 @@ static void atl1e_tx_map(struct atl1e_ad
 							  (i * MAX_TX_BUF_LEN),
 							  tx_buffer->length,
 							  DMA_TO_DEVICE);
+
+			if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) {
+				/* We need to unwind the mappings we've done */
+				ring_end = adapter->tx_ring.next_to_use;
+				adapter->tx_ring.next_to_use = ring_start;
+				while (adapter->tx_ring.next_to_use != ring_end) {
+					tpd = atl1e_get_tpd(adapter);
+					tx_buffer = atl1e_get_tx_buffer(adapter, tpd);
+					dma_unmap_page(&adapter->pdev->dev, tx_buffer->dma,
+						       tx_buffer->length, DMA_TO_DEVICE);
+				}
+
+				/* Reset the ring next to use pointer */
+				adapter->tx_ring.next_to_use = ring_start;
+				return -ENOSPC;
+			}
+
 			ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE);
 			use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 			use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1767,6 +1805,7 @@ static void atl1e_tx_map(struct atl1e_ad
 	/* The last buffer info contain the skb address,
 	   so it will be free after unmap */
 	tx_buffer->skb = skb;
+	return 0;
 }
 
 static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count,
@@ -1834,10 +1873,15 @@ static netdev_tx_t atl1e_xmit_frame(stru
 		return NETDEV_TX_OK;
 	}
 
-	atl1e_tx_map(adapter, skb, tpd);
+	if (atl1e_tx_map(adapter, skb, tpd)) {
+		dev_kfree_skb_any(skb);
+		goto out;
+	}
+
 	atl1e_tx_queue(adapter, tpd_req, tpd);
 
 	netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+out:
 	spin_unlock_irqrestore(&adapter->tx_lock, flags);
 	return NETDEV_TX_OK;
 }
@@ -2489,27 +2533,4 @@ static struct pci_driver atl1e_driver =
 	.err_handler = &atl1e_err_handler
 };
 
-/**
- * atl1e_init_module - Driver Registration Routine
- *
- * atl1e_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- */
-static int __init atl1e_init_module(void)
-{
-	return pci_register_driver(&atl1e_driver);
-}
-
-/**
- * atl1e_exit_module - Driver Exit Cleanup Routine
- *
- * atl1e_exit_module is called just before the driver is removed
- * from memory.
- */
-static void __exit atl1e_exit_module(void)
-{
-	pci_unregister_driver(&atl1e_driver);
-}
-
-module_init(atl1e_init_module);
-module_exit(atl1e_exit_module);
+module_pci_driver(atl1e_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/atlx/atl1.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/atlx/atl1.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/atlx/atl1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/atlx/atl1.c	2013-08-25 20:43:22.000000000 -0400
@@ -3145,31 +3145,6 @@ static struct pci_driver atl1_driver = {
 	.driver.pm = &atl1_pm_ops,
 };
 
-/**
- * atl1_exit_module - Driver Exit Cleanup Routine
- *
- * atl1_exit_module is called just before the driver is removed
- * from memory.
- */
-static void __exit atl1_exit_module(void)
-{
-	pci_unregister_driver(&atl1_driver);
-}
-
-/**
- * atl1_init_module - Driver Registration Routine
- *
- * atl1_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- */
-static int __init atl1_init_module(void)
-{
-	return pci_register_driver(&atl1_driver);
-}
-
-module_init(atl1_init_module);
-module_exit(atl1_exit_module);
-
 struct atl1_stats {
 	char stat_string[ETH_GSTRING_LEN];
 	int sizeof_stat;
@@ -3705,3 +3680,5 @@ static const struct ethtool_ops atl1_eth
 	.get_ethtool_stats	= atl1_get_ethtool_stats,
 	.get_sset_count		= atl1_get_sset_count,
 };
+
+module_pci_driver(atl1_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/atheros/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/atheros/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/atheros/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@ config ATL2
 	tristate "Atheros L2 Fast Ethernet support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This driver supports the Atheros L2 fast ethernet adapter.
@@ -34,7 +33,6 @@ config ATL1
 	tristate "Atheros/Attansic L1 Gigabit Ethernet support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This driver supports the Atheros/Attansic L1 gigabit ethernet
@@ -47,7 +45,6 @@ config ATL1E
 	tristate "Atheros L1E Gigabit Ethernet support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This driver supports the Atheros L1E gigabit ethernet adapter.
@@ -59,7 +56,6 @@ config ATL1C
 	tristate "Atheros L1C Gigabit Ethernet support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This driver supports the Atheros L1C gigabit ethernet adapter.
@@ -71,7 +67,6 @@ config ALX
 	tristate "Qualcomm Atheros AR816x/AR817x support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MDIO
 	help
 	  This driver supports the Qualcomm Atheros L1F ethernet adapter,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bcm63xx_enet.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bcm63xx_enet.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bcm63xx_enet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bcm63xx_enet.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,8 +41,8 @@ static int copybreak __read_mostly = 128
 module_param(copybreak, int, 0);
 MODULE_PARM_DESC(copybreak, "Receive copy threshold");
 
-/* io memory shared between all devices */
-static void __iomem *bcm_enet_shared_base;
+/* io registers memory shared between all devices */
+static void __iomem *bcm_enet_shared_base[3];
 
 /*
  * io helpers to access mac registers
@@ -59,17 +59,76 @@ static inline void enet_writel(struct bc
 }
 
 /*
- * io helpers to access shared registers
+ * io helpers to access switch registers
  */
+static inline u32 enetsw_readl(struct bcm_enet_priv *priv, u32 off)
+{
+	return bcm_readl(priv->base + off);
+}
+
+static inline void enetsw_writel(struct bcm_enet_priv *priv,
+				 u32 val, u32 off)
+{
+	bcm_writel(val, priv->base + off);
+}
+
+static inline u16 enetsw_readw(struct bcm_enet_priv *priv, u32 off)
+{
+	return bcm_readw(priv->base + off);
+}
+
+static inline void enetsw_writew(struct bcm_enet_priv *priv,
+				 u16 val, u32 off)
+{
+	bcm_writew(val, priv->base + off);
+}
+
+static inline u8 enetsw_readb(struct bcm_enet_priv *priv, u32 off)
+{
+	return bcm_readb(priv->base + off);
+}
+
+static inline void enetsw_writeb(struct bcm_enet_priv *priv,
+				 u8 val, u32 off)
+{
+	bcm_writeb(val, priv->base + off);
+}
+
+
+/* io helpers to access shared registers */
 static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off)
 {
-	return bcm_readl(bcm_enet_shared_base + off);
+	return bcm_readl(bcm_enet_shared_base[0] + off);
 }
 
 static inline void enet_dma_writel(struct bcm_enet_priv *priv,
 				       u32 val, u32 off)
 {
-	bcm_writel(val, bcm_enet_shared_base + off);
+	bcm_writel(val, bcm_enet_shared_base[0] + off);
+}
+
+static inline u32 enet_dmac_readl(struct bcm_enet_priv *priv, u32 off, int chan)
+{
+	return bcm_readl(bcm_enet_shared_base[1] +
+		bcm63xx_enetdmacreg(off) + chan * priv->dma_chan_width);
+}
+
+static inline void enet_dmac_writel(struct bcm_enet_priv *priv,
+				       u32 val, u32 off, int chan)
+{
+	bcm_writel(val, bcm_enet_shared_base[1] +
+		bcm63xx_enetdmacreg(off) + chan * priv->dma_chan_width);
+}
+
+static inline u32 enet_dmas_readl(struct bcm_enet_priv *priv, u32 off, int chan)
+{
+	return bcm_readl(bcm_enet_shared_base[2] + off + chan * priv->dma_chan_width);
+}
+
+static inline void enet_dmas_writel(struct bcm_enet_priv *priv,
+				       u32 val, u32 off, int chan)
+{
+	bcm_writel(val, bcm_enet_shared_base[2] + off + chan * priv->dma_chan_width);
 }
 
 /*
@@ -196,7 +255,6 @@ static int bcm_enet_refill_rx(struct net
 			if (!skb)
 				break;
 			priv->rx_skb[desc_idx] = skb;
-
 			p = dma_map_single(&priv->pdev->dev, skb->data,
 					   priv->rx_skb_size,
 					   DMA_FROM_DEVICE);
@@ -206,7 +264,7 @@ static int bcm_enet_refill_rx(struct net
 		len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT;
 		len_stat |= DMADESC_OWNER_MASK;
 		if (priv->rx_dirty_desc == priv->rx_ring_size - 1) {
-			len_stat |= DMADESC_WRAP_MASK;
+			len_stat |= (DMADESC_WRAP_MASK >> priv->dma_desc_shift);
 			priv->rx_dirty_desc = 0;
 		} else {
 			priv->rx_dirty_desc++;
@@ -217,7 +275,10 @@ static int bcm_enet_refill_rx(struct net
 		priv->rx_desc_count++;
 
 		/* tell dma engine we allocated one buffer */
-		enet_dma_writel(priv, 1, ENETDMA_BUFALLOC_REG(priv->rx_chan));
+		if (priv->dma_has_sram)
+			enet_dma_writel(priv, 1, ENETDMA_BUFALLOC_REG(priv->rx_chan));
+		else
+			enet_dmac_writel(priv, 1, ENETDMAC_BUFALLOC, priv->rx_chan);
 	}
 
 	/* If rx ring is still empty, set a timer to try allocating
@@ -293,13 +354,15 @@ static int bcm_enet_receive_queue(struct
 
 		/* if the packet does not have start of packet _and_
 		 * end of packet flag set, then just recycle it */
-		if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) {
+		if ((len_stat & (DMADESC_ESOP_MASK >> priv->dma_desc_shift)) !=
+			(DMADESC_ESOP_MASK >> priv->dma_desc_shift)) {
 			dev->stats.rx_dropped++;
 			continue;
 		}
 
 		/* recycle packet if it's marked as bad */
-		if (unlikely(len_stat & DMADESC_ERR_MASK)) {
+		if (!priv->enet_is_sw &&
+		    unlikely(len_stat & DMADESC_ERR_MASK)) {
 			dev->stats.rx_errors++;
 
 			if (len_stat & DMADESC_OVSIZE_MASK)
@@ -353,8 +416,8 @@ static int bcm_enet_receive_queue(struct
 		bcm_enet_refill_rx(dev);
 
 		/* kick rx dma */
-		enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
-				ENETDMA_CHANCFG_REG(priv->rx_chan));
+		enet_dmac_writel(priv, priv->dma_chan_en_mask,
+					 ENETDMAC_CHANCFG, priv->rx_chan);
 	}
 
 	return processed;
@@ -429,10 +492,10 @@ static int bcm_enet_poll(struct napi_str
 	dev = priv->net_dev;
 
 	/* ack interrupts */
-	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
-			ENETDMA_IR_REG(priv->rx_chan));
-	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
-			ENETDMA_IR_REG(priv->tx_chan));
+	enet_dmac_writel(priv, priv->dma_chan_int_mask,
+			 ENETDMAC_IR, priv->rx_chan);
+	enet_dmac_writel(priv, priv->dma_chan_int_mask,
+			 ENETDMAC_IR, priv->tx_chan);
 
 	/* reclaim sent skb */
 	tx_work_done = bcm_enet_tx_reclaim(dev, 0);
@@ -451,10 +514,10 @@ static int bcm_enet_poll(struct napi_str
 	napi_complete(napi);
 
 	/* restore rx/tx interrupt */
-	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
-			ENETDMA_IRMASK_REG(priv->rx_chan));
-	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
-			ENETDMA_IRMASK_REG(priv->tx_chan));
+	enet_dmac_writel(priv, priv->dma_chan_int_mask,
+			 ENETDMAC_IRMASK, priv->rx_chan);
+	enet_dmac_writel(priv, priv->dma_chan_int_mask,
+			 ENETDMAC_IRMASK, priv->tx_chan);
 
 	return rx_work_done;
 }
@@ -497,8 +560,8 @@ static irqreturn_t bcm_enet_isr_dma(int
 	priv = netdev_priv(dev);
 
 	/* mask rx/tx interrupts */
-	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
-	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
 
 	napi_schedule(&priv->napi);
 
@@ -530,6 +593,26 @@ static int bcm_enet_start_xmit(struct sk
 		goto out_unlock;
 	}
 
+	/* pad small packets sent on a switch device */
+	if (priv->enet_is_sw && skb->len < 64) {
+		int needed = 64 - skb->len;
+		char *data;
+
+		if (unlikely(skb_tailroom(skb) < needed)) {
+			struct sk_buff *nskb;
+
+			nskb = skb_copy_expand(skb, 0, needed, GFP_ATOMIC);
+			if (!nskb) {
+				ret = NETDEV_TX_BUSY;
+				goto out_unlock;
+			}
+			dev_kfree_skb(skb);
+			skb = nskb;
+		}
+		data = skb_put(skb, needed);
+		memset(data, 0, needed);
+	}
+
 	/* point to the next available desc */
 	desc = &priv->tx_desc_cpu[priv->tx_curr_desc];
 	priv->tx_skb[priv->tx_curr_desc] = skb;
@@ -539,14 +622,14 @@ static int bcm_enet_start_xmit(struct sk
 				       DMA_TO_DEVICE);
 
 	len_stat = (skb->len << DMADESC_LENGTH_SHIFT) & DMADESC_LENGTH_MASK;
-	len_stat |= DMADESC_ESOP_MASK |
+	len_stat |= (DMADESC_ESOP_MASK >> priv->dma_desc_shift) |
 		DMADESC_APPEND_CRC |
 		DMADESC_OWNER_MASK;
 
 	priv->tx_curr_desc++;
 	if (priv->tx_curr_desc == priv->tx_ring_size) {
 		priv->tx_curr_desc = 0;
-		len_stat |= DMADESC_WRAP_MASK;
+		len_stat |= (DMADESC_WRAP_MASK >> priv->dma_desc_shift);
 	}
 	priv->tx_desc_count--;
 
@@ -557,8 +640,8 @@ static int bcm_enet_start_xmit(struct sk
 	wmb();
 
 	/* kick tx dma */
-	enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
-			ENETDMA_CHANCFG_REG(priv->tx_chan));
+	enet_dmac_writel(priv, priv->dma_chan_en_mask,
+				 ENETDMAC_CHANCFG, priv->tx_chan);
 
 	/* stop queue if no more desc available */
 	if (!priv->tx_desc_count)
@@ -686,6 +769,9 @@ static void bcm_enet_set_flow(struct bcm
 		val &= ~ENET_RXCFG_ENFLOW_MASK;
 	enet_writel(priv, val, ENET_RXCFG_REG);
 
+	if (!priv->dma_has_sram)
+		return;
+
 	/* tx flow control (pause frame generation) */
 	val = enet_dma_readl(priv, ENETDMA_CFG_REG);
 	if (tx_en)
@@ -833,8 +919,8 @@ static int bcm_enet_open(struct net_devi
 
 	/* mask all interrupts and request them */
 	enet_writel(priv, 0, ENET_IRMASK_REG);
-	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
-	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
 
 	ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
 	if (ret)
@@ -909,8 +995,12 @@ static int bcm_enet_open(struct net_devi
 	priv->rx_curr_desc = 0;
 
 	/* initialize flow control buffer allocation */
-	enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
-			ENETDMA_BUFALLOC_REG(priv->rx_chan));
+	if (priv->dma_has_sram)
+		enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+				ENETDMA_BUFALLOC_REG(priv->rx_chan));
+	else
+		enet_dmac_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+				ENETDMAC_BUFALLOC, priv->rx_chan);
 
 	if (bcm_enet_refill_rx(dev)) {
 		dev_err(kdev, "cannot allocate rx skb queue\n");
@@ -919,37 +1009,55 @@ static int bcm_enet_open(struct net_devi
 	}
 
 	/* write rx & tx ring addresses */
-	enet_dma_writel(priv, priv->rx_desc_dma,
-			ENETDMA_RSTART_REG(priv->rx_chan));
-	enet_dma_writel(priv, priv->tx_desc_dma,
-			ENETDMA_RSTART_REG(priv->tx_chan));
+	if (priv->dma_has_sram) {
+		enet_dmas_writel(priv, priv->rx_desc_dma,
+				 ENETDMAS_RSTART_REG, priv->rx_chan);
+		enet_dmas_writel(priv, priv->tx_desc_dma,
+			 ENETDMAS_RSTART_REG, priv->tx_chan);
+	} else {
+		enet_dmac_writel(priv, priv->rx_desc_dma,
+				ENETDMAC_RSTART, priv->rx_chan);
+		enet_dmac_writel(priv, priv->tx_desc_dma,
+				ENETDMAC_RSTART, priv->tx_chan);
+	}
 
 	/* clear remaining state ram for rx & tx channel */
-	enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->rx_chan));
-	enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->tx_chan));
-	enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->rx_chan));
-	enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->tx_chan));
-	enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->rx_chan));
-	enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->tx_chan));
+	if (priv->dma_has_sram) {
+		enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG, priv->rx_chan);
+		enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG, priv->tx_chan);
+		enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG, priv->rx_chan);
+		enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG, priv->tx_chan);
+		enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG, priv->rx_chan);
+		enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG, priv->tx_chan);
+	} else {
+		enet_dmac_writel(priv, 0, ENETDMAC_FC, priv->rx_chan);
+		enet_dmac_writel(priv, 0, ENETDMAC_FC, priv->tx_chan);
+	}
 
 	/* set max rx/tx length */
 	enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG);
 	enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG);
 
 	/* set dma maximum burst len */
-	enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
-			ENETDMA_MAXBURST_REG(priv->rx_chan));
-	enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
-			ENETDMA_MAXBURST_REG(priv->tx_chan));
+	enet_dmac_writel(priv, priv->dma_maxburst,
+			 ENETDMAC_MAXBURST, priv->rx_chan);
+	enet_dmac_writel(priv, priv->dma_maxburst,
+			 ENETDMAC_MAXBURST, priv->tx_chan);
 
 	/* set correct transmit fifo watermark */
 	enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG);
 
 	/* set flow control low/high threshold to 1/3 / 2/3 */
-	val = priv->rx_ring_size / 3;
-	enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan));
-	val = (priv->rx_ring_size * 2) / 3;
-	enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan));
+	if (priv->dma_has_sram) {
+		val = priv->rx_ring_size / 3;
+		enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan));
+		val = (priv->rx_ring_size * 2) / 3;
+		enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan));
+	} else {
+		enet_dmac_writel(priv, 5, ENETDMAC_FC, priv->rx_chan);
+		enet_dmac_writel(priv, priv->rx_ring_size, ENETDMAC_LEN, priv->rx_chan);
+		enet_dmac_writel(priv, priv->tx_ring_size, ENETDMAC_LEN, priv->tx_chan);
+	}
 
 	/* all set, enable mac and interrupts, start dma engine and
 	 * kick rx dma channel */
@@ -958,26 +1066,26 @@ static int bcm_enet_open(struct net_devi
 	val |= ENET_CTL_ENABLE_MASK;
 	enet_writel(priv, val, ENET_CTL_REG);
 	enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
-	enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
-			ENETDMA_CHANCFG_REG(priv->rx_chan));
+	enet_dmac_writel(priv, priv->dma_chan_en_mask,
+			 ENETDMAC_CHANCFG, priv->rx_chan);
 
 	/* watch "mib counters about to overflow" interrupt */
 	enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
 	enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
 
 	/* watch "packet transferred" interrupt in rx and tx */
-	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
-			ENETDMA_IR_REG(priv->rx_chan));
-	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
-			ENETDMA_IR_REG(priv->tx_chan));
+	enet_dmac_writel(priv, priv->dma_chan_int_mask,
+			 ENETDMAC_IR, priv->rx_chan);
+	enet_dmac_writel(priv, priv->dma_chan_int_mask,
+			 ENETDMAC_IR, priv->tx_chan);
 
 	/* make sure we enable napi before rx interrupt  */
 	napi_enable(&priv->napi);
 
-	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
-			ENETDMA_IRMASK_REG(priv->rx_chan));
-	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
-			ENETDMA_IRMASK_REG(priv->tx_chan));
+	enet_dmac_writel(priv, priv->dma_chan_int_mask,
+			 ENETDMAC_IRMASK, priv->rx_chan);
+	enet_dmac_writel(priv, priv->dma_chan_int_mask,
+			 ENETDMAC_IRMASK, priv->tx_chan);
 
 	if (priv->has_phy)
 		phy_start(priv->phydev);
@@ -1057,14 +1165,14 @@ static void bcm_enet_disable_dma(struct
 {
 	int limit;
 
-	enet_dma_writel(priv, 0, ENETDMA_CHANCFG_REG(chan));
+	enet_dmac_writel(priv, 0, ENETDMAC_CHANCFG, chan);
 
 	limit = 1000;
 	do {
 		u32 val;
 
-		val = enet_dma_readl(priv, ENETDMA_CHANCFG_REG(chan));
-		if (!(val & ENETDMA_CHANCFG_EN_MASK))
+		val = enet_dmac_readl(priv, ENETDMAC_CHANCFG, chan);
+		if (!(val & ENETDMAC_CHANCFG_EN_MASK))
 			break;
 		udelay(1);
 	} while (limit--);
@@ -1090,8 +1198,8 @@ static int bcm_enet_stop(struct net_devi
 
 	/* mask all interrupts */
 	enet_writel(priv, 0, ENET_IRMASK_REG);
-	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
-	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
 
 	/* make sure no mib update is scheduled */
 	cancel_work_sync(&priv->mib_update_task);
@@ -1328,6 +1436,20 @@ static void bcm_enet_get_ethtool_stats(s
 	mutex_unlock(&priv->mib_update_lock);
 }
 
+static int bcm_enet_nway_reset(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+	if (priv->has_phy) {
+		if (!priv->phydev)
+			return -ENODEV;
+		return genphy_restart_aneg(priv->phydev);
+	}
+
+	return -EOPNOTSUPP;
+}
+
 static int bcm_enet_get_settings(struct net_device *dev,
 				 struct ethtool_cmd *cmd)
 {
@@ -1470,6 +1592,7 @@ static const struct ethtool_ops bcm_enet
 	.get_strings		= bcm_enet_get_strings,
 	.get_sset_count		= bcm_enet_get_sset_count,
 	.get_ethtool_stats      = bcm_enet_get_ethtool_stats,
+	.nway_reset		= bcm_enet_nway_reset,
 	.get_settings		= bcm_enet_get_settings,
 	.set_settings		= bcm_enet_set_settings,
 	.get_drvinfo		= bcm_enet_get_drvinfo,
@@ -1530,7 +1653,7 @@ static int compute_hw_mtu(struct bcm_ene
 	 * it's appended
 	 */
 	priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN,
-				  BCMENET_DMA_MAXBURST * 4);
+				  priv->dma_maxburst * 4);
 	return 0;
 }
 
@@ -1621,7 +1744,7 @@ static int bcm_enet_probe(struct platfor
 
 	/* stop if shared driver failed, assume driver->probe will be
 	 * called in the same order we register devices (correct ?) */
-	if (!bcm_enet_shared_base)
+	if (!bcm_enet_shared_base[0])
 		return -ENODEV;
 
 	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1637,6 +1760,9 @@ static int bcm_enet_probe(struct platfor
 		return -ENOMEM;
 	priv = netdev_priv(dev);
 
+	priv->enet_is_sw = false;
+	priv->dma_maxburst = BCMENET_DMA_MAXBURST;
+
 	ret = compute_hw_mtu(priv, dev->mtu);
 	if (ret)
 		goto out;
@@ -1687,6 +1813,11 @@ static int bcm_enet_probe(struct platfor
 		priv->pause_tx = pd->pause_tx;
 		priv->force_duplex_full = pd->force_duplex_full;
 		priv->force_speed_100 = pd->force_speed_100;
+		priv->dma_chan_en_mask = pd->dma_chan_en_mask;
+		priv->dma_chan_int_mask = pd->dma_chan_int_mask;
+		priv->dma_chan_width = pd->dma_chan_width;
+		priv->dma_has_sram = pd->dma_has_sram;
+		priv->dma_desc_shift = pd->dma_desc_shift;
 	}
 
 	if (priv->mac_id == 0 && priv->has_phy && !priv->use_external_mii) {
@@ -1847,7 +1978,6 @@ static int bcm_enet_remove(struct platfo
 	clk_disable_unprepare(priv->mac_clk);
 	clk_put(priv->mac_clk);
 
-	platform_set_drvdata(pdev, NULL);
 	free_netdev(dev);
 	return 0;
 }
@@ -1862,19 +1992,881 @@ struct platform_driver bcm63xx_enet_driv
 };
 
 /*
- * reserve & remap memory space shared between all macs
+ * switch mii access callbacks
  */
-static int bcm_enet_shared_probe(struct platform_device *pdev)
+static int bcmenet_sw_mdio_read(struct bcm_enet_priv *priv,
+				int ext, int phy_id, int location)
 {
-	struct resource *res;
+	u32 reg;
+	int ret;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
+	spin_lock_bh(&priv->enetsw_mdio_lock);
+	enetsw_writel(priv, 0, ENETSW_MDIOC_REG);
+
+	reg = ENETSW_MDIOC_RD_MASK |
+		(phy_id << ENETSW_MDIOC_PHYID_SHIFT) |
+		(location << ENETSW_MDIOC_REG_SHIFT);
+
+	if (ext)
+		reg |= ENETSW_MDIOC_EXT_MASK;
+
+	enetsw_writel(priv, reg, ENETSW_MDIOC_REG);
+	udelay(50);
+	ret = enetsw_readw(priv, ENETSW_MDIOD_REG);
+	spin_unlock_bh(&priv->enetsw_mdio_lock);
+	return ret;
+}
+
+static void bcmenet_sw_mdio_write(struct bcm_enet_priv *priv,
+				 int ext, int phy_id, int location,
+				 uint16_t data)
+{
+	u32 reg;
+
+	spin_lock_bh(&priv->enetsw_mdio_lock);
+	enetsw_writel(priv, 0, ENETSW_MDIOC_REG);
+
+	reg = ENETSW_MDIOC_WR_MASK |
+		(phy_id << ENETSW_MDIOC_PHYID_SHIFT) |
+		(location << ENETSW_MDIOC_REG_SHIFT);
+
+	if (ext)
+		reg |= ENETSW_MDIOC_EXT_MASK;
+
+	reg |= data;
+
+	enetsw_writel(priv, reg, ENETSW_MDIOC_REG);
+	udelay(50);
+	spin_unlock_bh(&priv->enetsw_mdio_lock);
+}
+
+static inline int bcm_enet_port_is_rgmii(int portid)
+{
+	return portid >= ENETSW_RGMII_PORT0;
+}
+
+/*
+ * enet sw PHY polling
+ */
+static void swphy_poll_timer(unsigned long data)
+{
+	struct bcm_enet_priv *priv = (struct bcm_enet_priv *)data;
+	unsigned int i;
+
+	for (i = 0; i < priv->num_ports; i++) {
+		struct bcm63xx_enetsw_port *port;
+		int val, j, up, advertise, lpa, lpa2, speed, duplex, media;
+		int external_phy = bcm_enet_port_is_rgmii(i);
+		u8 override;
+
+		port = &priv->used_ports[i];
+		if (!port->used)
+			continue;
+
+		if (port->bypass_link)
+			continue;
+
+		/* dummy read to clear */
+		for (j = 0; j < 2; j++)
+			val = bcmenet_sw_mdio_read(priv, external_phy,
+						   port->phy_id, MII_BMSR);
+
+		if (val == 0xffff)
+			continue;
+
+		up = (val & BMSR_LSTATUS) ? 1 : 0;
+		if (!(up ^ priv->sw_port_link[i]))
+			continue;
+
+		priv->sw_port_link[i] = up;
+
+		/* link changed */
+		if (!up) {
+			dev_info(&priv->pdev->dev, "link DOWN on %s\n",
+				 port->name);
+			enetsw_writeb(priv, ENETSW_PORTOV_ENABLE_MASK,
+				      ENETSW_PORTOV_REG(i));
+			enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK |
+				      ENETSW_PTCTRL_TXDIS_MASK,
+				      ENETSW_PTCTRL_REG(i));
+			continue;
+		}
+
+		advertise = bcmenet_sw_mdio_read(priv, external_phy,
+						 port->phy_id, MII_ADVERTISE);
+
+		lpa = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id,
+					   MII_LPA);
+
+		lpa2 = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id,
+					    MII_STAT1000);
+
+		/* figure out media and duplex from advertise and LPA values */
+		media = mii_nway_result(lpa & advertise);
+		duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+		if (lpa2 & LPA_1000FULL)
+			duplex = 1;
+
+		if (lpa2 & (LPA_1000FULL | LPA_1000HALF))
+			speed = 1000;
+		else {
+			if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
+				speed = 100;
+			else
+				speed = 10;
+		}
+
+		dev_info(&priv->pdev->dev,
+			 "link UP on %s, %dMbps, %s-duplex\n",
+			 port->name, speed, duplex ? "full" : "half");
+
+		override = ENETSW_PORTOV_ENABLE_MASK |
+			ENETSW_PORTOV_LINKUP_MASK;
+
+		if (speed == 1000)
+			override |= ENETSW_IMPOV_1000_MASK;
+		else if (speed == 100)
+			override |= ENETSW_IMPOV_100_MASK;
+		if (duplex)
+			override |= ENETSW_IMPOV_FDX_MASK;
+
+		enetsw_writeb(priv, override, ENETSW_PORTOV_REG(i));
+		enetsw_writeb(priv, 0, ENETSW_PTCTRL_REG(i));
+	}
+
+	priv->swphy_poll.expires = jiffies + HZ;
+	add_timer(&priv->swphy_poll);
+}
+
+/*
+ * open callback, allocate dma rings & buffers and start rx operation
+ */
+static int bcm_enetsw_open(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+	struct device *kdev;
+	int i, ret;
+	unsigned int size;
+	void *p;
+	u32 val;
+
+	priv = netdev_priv(dev);
+	kdev = &priv->pdev->dev;
+
+	/* mask all interrupts and request them */
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
+
+	ret = request_irq(priv->irq_rx, bcm_enet_isr_dma,
+			  IRQF_DISABLED, dev->name, dev);
+	if (ret)
+		goto out_freeirq;
+
+	if (priv->irq_tx != -1) {
+		ret = request_irq(priv->irq_tx, bcm_enet_isr_dma,
+				  IRQF_DISABLED, dev->name, dev);
+		if (ret)
+			goto out_freeirq_rx;
+	}
+
+	/* allocate rx dma ring */
+	size = priv->rx_ring_size * sizeof(struct bcm_enet_desc);
+	p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL);
+	if (!p) {
+		dev_err(kdev, "cannot allocate rx ring %u\n", size);
+		ret = -ENOMEM;
+		goto out_freeirq_tx;
+	}
+
+	memset(p, 0, size);
+	priv->rx_desc_alloc_size = size;
+	priv->rx_desc_cpu = p;
+
+	/* allocate tx dma ring */
+	size = priv->tx_ring_size * sizeof(struct bcm_enet_desc);
+	p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL);
+	if (!p) {
+		dev_err(kdev, "cannot allocate tx ring\n");
+		ret = -ENOMEM;
+		goto out_free_rx_ring;
+	}
+
+	memset(p, 0, size);
+	priv->tx_desc_alloc_size = size;
+	priv->tx_desc_cpu = p;
+
+	priv->tx_skb = kzalloc(sizeof(struct sk_buff *) * priv->tx_ring_size,
+			       GFP_KERNEL);
+	if (!priv->tx_skb) {
+		dev_err(kdev, "cannot allocate rx skb queue\n");
+		ret = -ENOMEM;
+		goto out_free_tx_ring;
+	}
+
+	priv->tx_desc_count = priv->tx_ring_size;
+	priv->tx_dirty_desc = 0;
+	priv->tx_curr_desc = 0;
+	spin_lock_init(&priv->tx_lock);
+
+	/* init & fill rx ring with skbs */
+	priv->rx_skb = kzalloc(sizeof(struct sk_buff *) * priv->rx_ring_size,
+			       GFP_KERNEL);
+	if (!priv->rx_skb) {
+		dev_err(kdev, "cannot allocate rx skb queue\n");
+		ret = -ENOMEM;
+		goto out_free_tx_skb;
+	}
+
+	priv->rx_desc_count = 0;
+	priv->rx_dirty_desc = 0;
+	priv->rx_curr_desc = 0;
+
+	/* disable all ports */
+	for (i = 0; i < priv->num_ports; i++) {
+		enetsw_writeb(priv, ENETSW_PORTOV_ENABLE_MASK,
+			      ENETSW_PORTOV_REG(i));
+		enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK |
+			      ENETSW_PTCTRL_TXDIS_MASK,
+			      ENETSW_PTCTRL_REG(i));
+
+		priv->sw_port_link[i] = 0;
+	}
+
+	/* reset mib */
+	val = enetsw_readb(priv, ENETSW_GMCR_REG);
+	val |= ENETSW_GMCR_RST_MIB_MASK;
+	enetsw_writeb(priv, val, ENETSW_GMCR_REG);
+	mdelay(1);
+	val &= ~ENETSW_GMCR_RST_MIB_MASK;
+	enetsw_writeb(priv, val, ENETSW_GMCR_REG);
+	mdelay(1);
+
+	/* force CPU port state */
+	val = enetsw_readb(priv, ENETSW_IMPOV_REG);
+	val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK;
+	enetsw_writeb(priv, val, ENETSW_IMPOV_REG);
+
+	/* enable switch forward engine */
+	val = enetsw_readb(priv, ENETSW_SWMODE_REG);
+	val |= ENETSW_SWMODE_FWD_EN_MASK;
+	enetsw_writeb(priv, val, ENETSW_SWMODE_REG);
+
+	/* enable jumbo on all ports */
+	enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG);
+	enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG);
+
+	/* initialize flow control buffer allocation */
+	enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+			ENETDMA_BUFALLOC_REG(priv->rx_chan));
+
+	if (bcm_enet_refill_rx(dev)) {
+		dev_err(kdev, "cannot allocate rx skb queue\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* write rx & tx ring addresses */
+	enet_dmas_writel(priv, priv->rx_desc_dma,
+			 ENETDMAS_RSTART_REG, priv->rx_chan);
+	enet_dmas_writel(priv, priv->tx_desc_dma,
+			 ENETDMAS_RSTART_REG, priv->tx_chan);
+
+	/* clear remaining state ram for rx & tx channel */
+	enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG, priv->rx_chan);
+	enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG, priv->tx_chan);
+	enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG, priv->rx_chan);
+	enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG, priv->tx_chan);
+	enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG, priv->rx_chan);
+	enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG, priv->tx_chan);
+
+	/* set dma maximum burst len */
+	enet_dmac_writel(priv, priv->dma_maxburst,
+			 ENETDMAC_MAXBURST, priv->rx_chan);
+	enet_dmac_writel(priv, priv->dma_maxburst,
+			 ENETDMAC_MAXBURST, priv->tx_chan);
+
+	/* set flow control low/high threshold to 1/3 / 2/3 */
+	val = priv->rx_ring_size / 3;
+	enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan));
+	val = (priv->rx_ring_size * 2) / 3;
+	enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan));
+
+	/* all set, enable mac and interrupts, start dma engine and
+	 * kick rx dma channel
+	 */
+	wmb();
+	enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
+	enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK,
+			 ENETDMAC_CHANCFG, priv->rx_chan);
+
+	/* watch "packet transferred" interrupt in rx and tx */
+	enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+			 ENETDMAC_IR, priv->rx_chan);
+	enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+			 ENETDMAC_IR, priv->tx_chan);
+
+	/* make sure we enable napi before rx interrupt  */
+	napi_enable(&priv->napi);
+
+	enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+			 ENETDMAC_IRMASK, priv->rx_chan);
+	enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+			 ENETDMAC_IRMASK, priv->tx_chan);
+
+	netif_carrier_on(dev);
+	netif_start_queue(dev);
+
+	/* apply override config for bypass_link ports here. */
+	for (i = 0; i < priv->num_ports; i++) {
+		struct bcm63xx_enetsw_port *port;
+		u8 override;
+		port = &priv->used_ports[i];
+		if (!port->used)
+			continue;
+
+		if (!port->bypass_link)
+			continue;
+
+		override = ENETSW_PORTOV_ENABLE_MASK |
+			ENETSW_PORTOV_LINKUP_MASK;
+
+		switch (port->force_speed) {
+		case 1000:
+			override |= ENETSW_IMPOV_1000_MASK;
+			break;
+		case 100:
+			override |= ENETSW_IMPOV_100_MASK;
+			break;
+		case 10:
+			break;
+		default:
+			pr_warn("invalid forced speed on port %s: assume 10\n",
+			       port->name);
+			break;
+		}
+
+		if (port->force_duplex_full)
+			override |= ENETSW_IMPOV_FDX_MASK;
+
+
+		enetsw_writeb(priv, override, ENETSW_PORTOV_REG(i));
+		enetsw_writeb(priv, 0, ENETSW_PTCTRL_REG(i));
+	}
+
+	/* start phy polling timer */
+	init_timer(&priv->swphy_poll);
+	priv->swphy_poll.function = swphy_poll_timer;
+	priv->swphy_poll.data = (unsigned long)priv;
+	priv->swphy_poll.expires = jiffies;
+	add_timer(&priv->swphy_poll);
+	return 0;
+
+out:
+	for (i = 0; i < priv->rx_ring_size; i++) {
+		struct bcm_enet_desc *desc;
+
+		if (!priv->rx_skb[i])
+			continue;
+
+		desc = &priv->rx_desc_cpu[i];
+		dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+				 DMA_FROM_DEVICE);
+		kfree_skb(priv->rx_skb[i]);
+	}
+	kfree(priv->rx_skb);
+
+out_free_tx_skb:
+	kfree(priv->tx_skb);
+
+out_free_tx_ring:
+	dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+			  priv->tx_desc_cpu, priv->tx_desc_dma);
+
+out_free_rx_ring:
+	dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+			  priv->rx_desc_cpu, priv->rx_desc_dma);
+
+out_freeirq_tx:
+	if (priv->irq_tx != -1)
+		free_irq(priv->irq_tx, dev);
+
+out_freeirq_rx:
+	free_irq(priv->irq_rx, dev);
+
+out_freeirq:
+	return ret;
+}
+
+/* stop callback */
+static int bcm_enetsw_stop(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+	struct device *kdev;
+	int i;
+
+	priv = netdev_priv(dev);
+	kdev = &priv->pdev->dev;
+
+	del_timer_sync(&priv->swphy_poll);
+	netif_stop_queue(dev);
+	napi_disable(&priv->napi);
+	del_timer_sync(&priv->rx_timeout);
+
+	/* mask all interrupts */
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+	enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
+
+	/* disable dma & mac */
+	bcm_enet_disable_dma(priv, priv->tx_chan);
+	bcm_enet_disable_dma(priv, priv->rx_chan);
+
+	/* force reclaim of all tx buffers */
+	bcm_enet_tx_reclaim(dev, 1);
+
+	/* free the rx skb ring */
+	for (i = 0; i < priv->rx_ring_size; i++) {
+		struct bcm_enet_desc *desc;
+
+		if (!priv->rx_skb[i])
+			continue;
+
+		desc = &priv->rx_desc_cpu[i];
+		dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+				 DMA_FROM_DEVICE);
+		kfree_skb(priv->rx_skb[i]);
+	}
+
+	/* free remaining allocated memory */
+	kfree(priv->rx_skb);
+	kfree(priv->tx_skb);
+	dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+			  priv->rx_desc_cpu, priv->rx_desc_dma);
+	dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+			  priv->tx_desc_cpu, priv->tx_desc_dma);
+	if (priv->irq_tx != -1)
+		free_irq(priv->irq_tx, dev);
+	free_irq(priv->irq_rx, dev);
+
+	return 0;
+}
+
+/* try to sort out phy external status by walking the used_port field
+ * in the bcm_enet_priv structure. in case the phy address is not
+ * assigned to any physical port on the switch, assume it is external
+ * (and yell at the user).
+ */
+static int bcm_enetsw_phy_is_external(struct bcm_enet_priv *priv, int phy_id)
+{
+	int i;
+
+	for (i = 0; i < priv->num_ports; ++i) {
+		if (!priv->used_ports[i].used)
+			continue;
+		if (priv->used_ports[i].phy_id == phy_id)
+			return bcm_enet_port_is_rgmii(i);
+	}
+
+	printk_once(KERN_WARNING  "bcm63xx_enet: could not find a used port with phy_id %i, assuming phy is external\n",
+		    phy_id);
+	return 1;
+}
+
+/* can't use bcmenet_sw_mdio_read directly as we need to sort out
+ * external/internal status of the given phy_id first.
+ */
+static int bcm_enetsw_mii_mdio_read(struct net_device *dev, int phy_id,
+				    int location)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+	return bcmenet_sw_mdio_read(priv,
+				    bcm_enetsw_phy_is_external(priv, phy_id),
+				    phy_id, location);
+}
+
+/* can't use bcmenet_sw_mdio_write directly as we need to sort out
+ * external/internal status of the given phy_id first.
+ */
+static void bcm_enetsw_mii_mdio_write(struct net_device *dev, int phy_id,
+				      int location,
+				      int val)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+	bcmenet_sw_mdio_write(priv, bcm_enetsw_phy_is_external(priv, phy_id),
+			      phy_id, location, val);
+}
+
+static int bcm_enetsw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct mii_if_info mii;
+
+	mii.dev = dev;
+	mii.mdio_read = bcm_enetsw_mii_mdio_read;
+	mii.mdio_write = bcm_enetsw_mii_mdio_write;
+	mii.phy_id = 0;
+	mii.phy_id_mask = 0x3f;
+	mii.reg_num_mask = 0x1f;
+	return generic_mii_ioctl(&mii, if_mii(rq), cmd, NULL);
+
+}
+
+static const struct net_device_ops bcm_enetsw_ops = {
+	.ndo_open		= bcm_enetsw_open,
+	.ndo_stop		= bcm_enetsw_stop,
+	.ndo_start_xmit		= bcm_enet_start_xmit,
+	.ndo_change_mtu		= bcm_enet_change_mtu,
+	.ndo_do_ioctl		= bcm_enetsw_ioctl,
+};
+
+
+static const struct bcm_enet_stats bcm_enetsw_gstrings_stats[] = {
+	{ "rx_packets", DEV_STAT(rx_packets), -1 },
+	{ "tx_packets",	DEV_STAT(tx_packets), -1 },
+	{ "rx_bytes", DEV_STAT(rx_bytes), -1 },
+	{ "tx_bytes", DEV_STAT(tx_bytes), -1 },
+	{ "rx_errors", DEV_STAT(rx_errors), -1 },
+	{ "tx_errors", DEV_STAT(tx_errors), -1 },
+	{ "rx_dropped",	DEV_STAT(rx_dropped), -1 },
+	{ "tx_dropped",	DEV_STAT(tx_dropped), -1 },
+
+	{ "tx_good_octets", GEN_STAT(mib.tx_gd_octets), ETHSW_MIB_RX_GD_OCT },
+	{ "tx_unicast", GEN_STAT(mib.tx_unicast), ETHSW_MIB_RX_BRDCAST },
+	{ "tx_broadcast", GEN_STAT(mib.tx_brdcast), ETHSW_MIB_RX_BRDCAST },
+	{ "tx_multicast", GEN_STAT(mib.tx_mult), ETHSW_MIB_RX_MULT },
+	{ "tx_64_octets", GEN_STAT(mib.tx_64), ETHSW_MIB_RX_64 },
+	{ "tx_65_127_oct", GEN_STAT(mib.tx_65_127), ETHSW_MIB_RX_65_127 },
+	{ "tx_128_255_oct", GEN_STAT(mib.tx_128_255), ETHSW_MIB_RX_128_255 },
+	{ "tx_256_511_oct", GEN_STAT(mib.tx_256_511), ETHSW_MIB_RX_256_511 },
+	{ "tx_512_1023_oct", GEN_STAT(mib.tx_512_1023), ETHSW_MIB_RX_512_1023},
+	{ "tx_1024_1522_oct", GEN_STAT(mib.tx_1024_max),
+	  ETHSW_MIB_RX_1024_1522 },
+	{ "tx_1523_2047_oct", GEN_STAT(mib.tx_1523_2047),
+	  ETHSW_MIB_RX_1523_2047 },
+	{ "tx_2048_4095_oct", GEN_STAT(mib.tx_2048_4095),
+	  ETHSW_MIB_RX_2048_4095 },
+	{ "tx_4096_8191_oct", GEN_STAT(mib.tx_4096_8191),
+	  ETHSW_MIB_RX_4096_8191 },
+	{ "tx_8192_9728_oct", GEN_STAT(mib.tx_8192_9728),
+	  ETHSW_MIB_RX_8192_9728 },
+	{ "tx_oversize", GEN_STAT(mib.tx_ovr), ETHSW_MIB_RX_OVR },
+	{ "tx_oversize_drop", GEN_STAT(mib.tx_ovr), ETHSW_MIB_RX_OVR_DISC },
+	{ "tx_dropped",	GEN_STAT(mib.tx_drop), ETHSW_MIB_RX_DROP },
+	{ "tx_undersize", GEN_STAT(mib.tx_underrun), ETHSW_MIB_RX_UND },
+	{ "tx_pause", GEN_STAT(mib.tx_pause), ETHSW_MIB_RX_PAUSE },
+
+	{ "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETHSW_MIB_TX_ALL_OCT },
+	{ "rx_broadcast", GEN_STAT(mib.rx_brdcast), ETHSW_MIB_TX_BRDCAST },
+	{ "rx_multicast", GEN_STAT(mib.rx_mult), ETHSW_MIB_TX_MULT },
+	{ "rx_unicast", GEN_STAT(mib.rx_unicast), ETHSW_MIB_TX_MULT },
+	{ "rx_pause", GEN_STAT(mib.rx_pause), ETHSW_MIB_TX_PAUSE },
+	{ "rx_dropped", GEN_STAT(mib.rx_drop), ETHSW_MIB_TX_DROP_PKTS },
+
+};
+
+#define BCM_ENETSW_STATS_LEN	\
+	(sizeof(bcm_enetsw_gstrings_stats) / sizeof(struct bcm_enet_stats))
+
+static void bcm_enetsw_get_strings(struct net_device *netdev,
+				   u32 stringset, u8 *data)
+{
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < BCM_ENETSW_STATS_LEN; i++) {
+			memcpy(data + i * ETH_GSTRING_LEN,
+			       bcm_enetsw_gstrings_stats[i].stat_string,
+			       ETH_GSTRING_LEN);
+		}
+		break;
+	}
+}
+
+static int bcm_enetsw_get_sset_count(struct net_device *netdev,
+				     int string_set)
+{
+	switch (string_set) {
+	case ETH_SS_STATS:
+		return BCM_ENETSW_STATS_LEN;
+	default:
+		return -EINVAL;
+	}
+}
+
+static void bcm_enetsw_get_drvinfo(struct net_device *netdev,
+				   struct ethtool_drvinfo *drvinfo)
+{
+	strncpy(drvinfo->driver, bcm_enet_driver_name, 32);
+	strncpy(drvinfo->version, bcm_enet_driver_version, 32);
+	strncpy(drvinfo->fw_version, "N/A", 32);
+	strncpy(drvinfo->bus_info, "bcm63xx", 32);
+	drvinfo->n_stats = BCM_ENETSW_STATS_LEN;
+}
+
+static void bcm_enetsw_get_ethtool_stats(struct net_device *netdev,
+					 struct ethtool_stats *stats,
+					 u64 *data)
+{
+	struct bcm_enet_priv *priv;
+	int i;
+
+	priv = netdev_priv(netdev);
+
+	for (i = 0; i < BCM_ENETSW_STATS_LEN; i++) {
+		const struct bcm_enet_stats *s;
+		u32 lo, hi;
+		char *p;
+		int reg;
+
+		s = &bcm_enetsw_gstrings_stats[i];
+
+		reg = s->mib_reg;
+		if (reg == -1)
+			continue;
+
+		lo = enetsw_readl(priv, ENETSW_MIB_REG(reg));
+		p = (char *)priv + s->stat_offset;
+
+		if (s->sizeof_stat == sizeof(u64)) {
+			hi = enetsw_readl(priv, ENETSW_MIB_REG(reg + 1));
+			*(u64 *)p = ((u64)hi << 32 | lo);
+		} else {
+			*(u32 *)p = lo;
+		}
+	}
+
+	for (i = 0; i < BCM_ENETSW_STATS_LEN; i++) {
+		const struct bcm_enet_stats *s;
+		char *p;
+
+		s = &bcm_enetsw_gstrings_stats[i];
+
+		if (s->mib_reg == -1)
+			p = (char *)&netdev->stats + s->stat_offset;
+		else
+			p = (char *)priv + s->stat_offset;
+
+		data[i] = (s->sizeof_stat == sizeof(u64)) ?
+			*(u64 *)p : *(u32 *)p;
+	}
+}
+
+static void bcm_enetsw_get_ringparam(struct net_device *dev,
+				     struct ethtool_ringparam *ering)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+
+	/* rx/tx ring is actually only limited by memory */
+	ering->rx_max_pending = 8192;
+	ering->tx_max_pending = 8192;
+	ering->rx_mini_max_pending = 0;
+	ering->rx_jumbo_max_pending = 0;
+	ering->rx_pending = priv->rx_ring_size;
+	ering->tx_pending = priv->tx_ring_size;
+}
+
+static int bcm_enetsw_set_ringparam(struct net_device *dev,
+				    struct ethtool_ringparam *ering)
+{
+	struct bcm_enet_priv *priv;
+	int was_running;
+
+	priv = netdev_priv(dev);
+
+	was_running = 0;
+	if (netif_running(dev)) {
+		bcm_enetsw_stop(dev);
+		was_running = 1;
+	}
+
+	priv->rx_ring_size = ering->rx_pending;
+	priv->tx_ring_size = ering->tx_pending;
+
+	if (was_running) {
+		int err;
+
+		err = bcm_enetsw_open(dev);
+		if (err)
+			dev_close(dev);
+	}
+	return 0;
+}
+
+static struct ethtool_ops bcm_enetsw_ethtool_ops = {
+	.get_strings		= bcm_enetsw_get_strings,
+	.get_sset_count		= bcm_enetsw_get_sset_count,
+	.get_ethtool_stats      = bcm_enetsw_get_ethtool_stats,
+	.get_drvinfo		= bcm_enetsw_get_drvinfo,
+	.get_ringparam		= bcm_enetsw_get_ringparam,
+	.set_ringparam		= bcm_enetsw_set_ringparam,
+};
+
+/* allocate netdevice, request register memory and register device. */
+static int bcm_enetsw_probe(struct platform_device *pdev)
+{
+	struct bcm_enet_priv *priv;
+	struct net_device *dev;
+	struct bcm63xx_enetsw_platform_data *pd;
+	struct resource *res_mem;
+	int ret, irq_rx, irq_tx;
+
+	/* stop if shared driver failed, assume driver->probe will be
+	 * called in the same order we register devices (correct ?)
+	 */
+	if (!bcm_enet_shared_base[0])
 		return -ENODEV;
 
-	bcm_enet_shared_base = devm_request_and_ioremap(&pdev->dev, res);
-	if (!bcm_enet_shared_base)
+	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq_rx = platform_get_irq(pdev, 0);
+	irq_tx = platform_get_irq(pdev, 1);
+	if (!res_mem || irq_rx < 0)
+		return -ENODEV;
+
+	ret = 0;
+	dev = alloc_etherdev(sizeof(*priv));
+	if (!dev)
 		return -ENOMEM;
+	priv = netdev_priv(dev);
+	memset(priv, 0, sizeof(*priv));
+
+	/* initialize default and fetch platform data */
+	priv->enet_is_sw = true;
+	priv->irq_rx = irq_rx;
+	priv->irq_tx = irq_tx;
+	priv->rx_ring_size = BCMENET_DEF_RX_DESC;
+	priv->tx_ring_size = BCMENET_DEF_TX_DESC;
+	priv->dma_maxburst = BCMENETSW_DMA_MAXBURST;
+
+	pd = pdev->dev.platform_data;
+	if (pd) {
+		memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN);
+		memcpy(priv->used_ports, pd->used_ports,
+		       sizeof(pd->used_ports));
+		priv->num_ports = pd->num_ports;
+		priv->dma_has_sram = pd->dma_has_sram;
+		priv->dma_chan_en_mask = pd->dma_chan_en_mask;
+		priv->dma_chan_int_mask = pd->dma_chan_int_mask;
+		priv->dma_chan_width = pd->dma_chan_width;
+	}
+
+	ret = compute_hw_mtu(priv, dev->mtu);
+	if (ret)
+		goto out;
+
+	if (!request_mem_region(res_mem->start, resource_size(res_mem),
+				"bcm63xx_enetsw")) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	priv->base = ioremap(res_mem->start, resource_size(res_mem));
+	if (priv->base == NULL) {
+		ret = -ENOMEM;
+		goto out_release_mem;
+	}
+
+	priv->mac_clk = clk_get(&pdev->dev, "enetsw");
+	if (IS_ERR(priv->mac_clk)) {
+		ret = PTR_ERR(priv->mac_clk);
+		goto out_unmap;
+	}
+	clk_enable(priv->mac_clk);
+
+	priv->rx_chan = 0;
+	priv->tx_chan = 1;
+	spin_lock_init(&priv->rx_lock);
+
+	/* init rx timeout (used for oom) */
+	init_timer(&priv->rx_timeout);
+	priv->rx_timeout.function = bcm_enet_refill_rx_timer;
+	priv->rx_timeout.data = (unsigned long)dev;
+
+	/* register netdevice */
+	dev->netdev_ops = &bcm_enetsw_ops;
+	netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
+	SET_ETHTOOL_OPS(dev, &bcm_enetsw_ethtool_ops);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	spin_lock_init(&priv->enetsw_mdio_lock);
+
+	ret = register_netdev(dev);
+	if (ret)
+		goto out_put_clk;
+
+	netif_carrier_off(dev);
+	platform_set_drvdata(pdev, dev);
+	priv->pdev = pdev;
+	priv->net_dev = dev;
+
+	return 0;
+
+out_put_clk:
+	clk_put(priv->mac_clk);
+
+out_unmap:
+	iounmap(priv->base);
+
+out_release_mem:
+	release_mem_region(res_mem->start, resource_size(res_mem));
+out:
+	free_netdev(dev);
+	return ret;
+}
+
+
+/* exit func, stops hardware and unregisters netdevice */
+static int bcm_enetsw_remove(struct platform_device *pdev)
+{
+	struct bcm_enet_priv *priv;
+	struct net_device *dev;
+	struct resource *res;
+
+	/* stop netdevice */
+	dev = platform_get_drvdata(pdev);
+	priv = netdev_priv(dev);
+	unregister_netdev(dev);
+
+	/* release device resources */
+	iounmap(priv->base);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	platform_set_drvdata(pdev, NULL);
+	free_netdev(dev);
+	return 0;
+}
+
+struct platform_driver bcm63xx_enetsw_driver = {
+	.probe	= bcm_enetsw_probe,
+	.remove	= bcm_enetsw_remove,
+	.driver	= {
+		.name	= "bcm63xx_enetsw",
+		.owner  = THIS_MODULE,
+	},
+};
+
+/* reserve & remap memory space shared between all macs */
+static int bcm_enet_shared_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	void __iomem *p[3];
+	unsigned int i;
+
+	memset(bcm_enet_shared_base, 0, sizeof(bcm_enet_shared_base));
+
+	for (i = 0; i < 3; i++) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		p[i] = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(p[i]))
+			return PTR_ERR(p[i]);
+	}
+
+	memcpy(bcm_enet_shared_base, p, sizeof(bcm_enet_shared_base));
 
 	return 0;
 }
@@ -1884,8 +2876,7 @@ static int bcm_enet_shared_remove(struct
 	return 0;
 }
 
-/*
- * this "shared" driver is needed because both macs share a single
+/* this "shared" driver is needed because both macs share a single
  * address space
  */
 struct platform_driver bcm63xx_enet_shared_driver = {
@@ -1897,9 +2888,7 @@ struct platform_driver bcm63xx_enet_shar
 	},
 };
 
-/*
- * entry point
- */
+/* entry point */
 static int __init bcm_enet_init(void)
 {
 	int ret;
@@ -1912,12 +2901,19 @@ static int __init bcm_enet_init(void)
 	if (ret)
 		platform_driver_unregister(&bcm63xx_enet_shared_driver);
 
+	ret = platform_driver_register(&bcm63xx_enetsw_driver);
+	if (ret) {
+		platform_driver_unregister(&bcm63xx_enet_driver);
+		platform_driver_unregister(&bcm63xx_enet_shared_driver);
+	}
+
 	return ret;
 }
 
 static void __exit bcm_enet_exit(void)
 {
 	platform_driver_unregister(&bcm63xx_enet_driver);
+	platform_driver_unregister(&bcm63xx_enetsw_driver);
 	platform_driver_unregister(&bcm63xx_enet_shared_driver);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bcm63xx_enet.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bcm63xx_enet.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bcm63xx_enet.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bcm63xx_enet.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,7 @@
 
 /* maximum burst len for dma (4 bytes unit) */
 #define BCMENET_DMA_MAXBURST	16
+#define BCMENETSW_DMA_MAXBURST	8
 
 /* tx transmit threshold (4 bytes unit), fifo is 256 bytes, the value
  * must be low enough so that a DMA transfer of above burst length can
@@ -84,11 +85,60 @@
 #define ETH_MIB_RX_CNTRL			54
 
 
+/*
+ * SW MIB Counters register definitions
+*/
+#define ETHSW_MIB_TX_ALL_OCT			0
+#define ETHSW_MIB_TX_DROP_PKTS			2
+#define ETHSW_MIB_TX_QOS_PKTS			3
+#define ETHSW_MIB_TX_BRDCAST			4
+#define ETHSW_MIB_TX_MULT			5
+#define ETHSW_MIB_TX_UNI			6
+#define ETHSW_MIB_TX_COL			7
+#define ETHSW_MIB_TX_1_COL			8
+#define ETHSW_MIB_TX_M_COL			9
+#define ETHSW_MIB_TX_DEF			10
+#define ETHSW_MIB_TX_LATE			11
+#define ETHSW_MIB_TX_EX_COL			12
+#define ETHSW_MIB_TX_PAUSE			14
+#define ETHSW_MIB_TX_QOS_OCT			15
+
+#define ETHSW_MIB_RX_ALL_OCT			17
+#define ETHSW_MIB_RX_UND			19
+#define ETHSW_MIB_RX_PAUSE			20
+#define ETHSW_MIB_RX_64				21
+#define ETHSW_MIB_RX_65_127			22
+#define ETHSW_MIB_RX_128_255			23
+#define ETHSW_MIB_RX_256_511			24
+#define ETHSW_MIB_RX_512_1023			25
+#define ETHSW_MIB_RX_1024_1522			26
+#define ETHSW_MIB_RX_OVR			27
+#define ETHSW_MIB_RX_JAB			28
+#define ETHSW_MIB_RX_ALIGN			29
+#define ETHSW_MIB_RX_CRC			30
+#define ETHSW_MIB_RX_GD_OCT			31
+#define ETHSW_MIB_RX_DROP			33
+#define ETHSW_MIB_RX_UNI			34
+#define ETHSW_MIB_RX_MULT			35
+#define ETHSW_MIB_RX_BRDCAST			36
+#define ETHSW_MIB_RX_SA_CHANGE			37
+#define ETHSW_MIB_RX_FRAG			38
+#define ETHSW_MIB_RX_OVR_DISC			39
+#define ETHSW_MIB_RX_SYM			40
+#define ETHSW_MIB_RX_QOS_PKTS			41
+#define ETHSW_MIB_RX_QOS_OCT			42
+#define ETHSW_MIB_RX_1523_2047			44
+#define ETHSW_MIB_RX_2048_4095			45
+#define ETHSW_MIB_RX_4096_8191			46
+#define ETHSW_MIB_RX_8192_9728			47
+
+
 struct bcm_enet_mib_counters {
 	u64 tx_gd_octets;
 	u32 tx_gd_pkts;
 	u32 tx_all_octets;
 	u32 tx_all_pkts;
+	u32 tx_unicast;
 	u32 tx_brdcast;
 	u32 tx_mult;
 	u32 tx_64;
@@ -97,7 +147,12 @@ struct bcm_enet_mib_counters {
 	u32 tx_256_511;
 	u32 tx_512_1023;
 	u32 tx_1024_max;
+	u32 tx_1523_2047;
+	u32 tx_2048_4095;
+	u32 tx_4096_8191;
+	u32 tx_8192_9728;
 	u32 tx_jab;
+	u32 tx_drop;
 	u32 tx_ovr;
 	u32 tx_frag;
 	u32 tx_underrun;
@@ -114,6 +169,7 @@ struct bcm_enet_mib_counters {
 	u32 rx_all_octets;
 	u32 rx_all_pkts;
 	u32 rx_brdcast;
+	u32 rx_unicast;
 	u32 rx_mult;
 	u32 rx_64;
 	u32 rx_65_127;
@@ -197,6 +253,9 @@ struct bcm_enet_priv {
 	/* number of dma desc in tx ring */
 	int tx_ring_size;
 
+	/* maximum dma burst size */
+	int dma_maxburst;
+
 	/* cpu view of rx dma ring */
 	struct bcm_enet_desc *tx_desc_cpu;
 
@@ -269,6 +328,33 @@ struct bcm_enet_priv {
 
 	/* maximum hardware transmit/receive size */
 	unsigned int hw_mtu;
+
+	bool enet_is_sw;
+
+	/* port mapping for switch devices */
+	int num_ports;
+	struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT];
+	int sw_port_link[ENETSW_MAX_PORT];
+
+	/* used to poll switch port state */
+	struct timer_list swphy_poll;
+	spinlock_t enetsw_mdio_lock;
+
+	/* dma channel enable mask */
+	u32 dma_chan_en_mask;
+
+	/* dma channel interrupt mask */
+	u32 dma_chan_int_mask;
+
+	/* DMA engine has internal SRAM */
+	bool dma_has_sram;
+
+	/* dma channel width */
+	unsigned int dma_chan_width;
+
+	/* dma descriptor shift value */
+	unsigned int dma_desc_shift;
 };
 
+
 #endif /* ! BCM63XX_ENET_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2.c	2013-07-01 10:36:15.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2.c	2013-08-31 17:55:47.000000000 -0400
@@ -8100,7 +8100,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 
 	pci_set_master(pdev);
 
-	bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	bp->pm_cap = pdev->pm_cap;
 	if (bp->pm_cap == 0) {
 		dev_err(&pdev->dev,
 			"Cannot find power management capability, aborting\n");
@@ -8760,18 +8760,4 @@ static struct pci_driver bnx2_pci_driver
 	.err_handler	= &bnx2_err_handler,
 };
 
-static int __init bnx2_init(void)
-{
-	return pci_register_driver(&bnx2_pci_driver);
-}
-
-static void __exit bnx2_cleanup(void)
-{
-	pci_unregister_driver(&bnx2_pci_driver);
-}
-
-module_init(bnx2_init);
-module_exit(bnx2_cleanup);
-
-
-
+module_pci_driver(bnx2_pci_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2013-07-01 10:36:22.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c	2013-08-31 17:55:54.000000000 -0400
@@ -24,6 +24,7 @@
 #include <net/tcp.h>
 #include <net/ipv6.h>
 #include <net/ip6_checksum.h>
+#include <net/busy_poll.h>
 #include <linux/prefetch.h>
 #include "bnx2x_cmn.h"
 #include "bnx2x_init.h"
@@ -124,7 +125,7 @@ static void bnx2x_shrink_eth_fp(struct b
 	int i, cos, old_eth_num = BNX2X_NUM_ETH_QUEUES(bp);
 
 	/* Queue pointer cannot be re-set on an fp-basis, as moving pointer
-	 * backward along the array could cause memory to be overriden
+	 * backward along the array could cause memory to be overridden
 	 */
 	for (cos = 1; cos < bp->max_cos; cos++) {
 		for (i = 0; i < old_eth_num - delta; i++) {
@@ -165,7 +166,6 @@ static u16 bnx2x_free_tx_pkt(struct bnx2
 	dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd),
 			 BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE);
 
-
 	nbd = le16_to_cpu(tx_start_bd->nbd) - 1;
 #ifdef BNX2X_STOP_ON_ERROR
 	if ((nbd - 1) > (MAX_SKB_FRAGS + 2)) {
@@ -259,7 +259,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struc
 	smp_mb();
 
 	if (unlikely(netif_tx_queue_stopped(txq))) {
-		/* Taking tx_lock() is needed to prevent reenabling the queue
+		/* Taking tx_lock() is needed to prevent re-enabling the queue
 		 * while it's empty. This could have happen if rx_action() gets
 		 * suspended in bnx2x_tx_int() after the condition before
 		 * netif_tx_wake_queue(), while tx_action (bnx2x_start_xmit()):
@@ -572,7 +572,7 @@ static int bnx2x_fill_frag_skb(struct bn
 			return err;
 		}
 
-		/* Unmap the page as we r going to pass it to the stack */
+		/* Unmap the page as we're going to pass it to the stack */
 		dma_unmap_page(&bp->pdev->dev,
 			       dma_unmap_addr(&old_rx_pg, mapping),
 			       SGE_PAGES, DMA_FROM_DEVICE);
@@ -733,7 +733,6 @@ static void bnx2x_tpa_stop(struct bnx2x
 			dev_kfree_skb_any(skb);
 		}
 
-
 		/* put new data in bin */
 		rx_buf->data = new_data;
 
@@ -805,40 +804,32 @@ int bnx2x_rx_int(struct bnx2x_fastpath *
 {
 	struct bnx2x *bp = fp->bp;
 	u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons;
-	u16 hw_comp_cons, sw_comp_cons, sw_comp_prod;
+	u16 sw_comp_cons, sw_comp_prod;
 	int rx_pkt = 0;
+	union eth_rx_cqe *cqe;
+	struct eth_fast_path_rx_cqe *cqe_fp;
 
 #ifdef BNX2X_STOP_ON_ERROR
 	if (unlikely(bp->panic))
 		return 0;
 #endif
 
-	/* CQ "next element" is of the size of the regular element,
-	   that's why it's ok here */
-	hw_comp_cons = le16_to_cpu(*fp->rx_cons_sb);
-	if ((hw_comp_cons & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
-		hw_comp_cons++;
-
 	bd_cons = fp->rx_bd_cons;
 	bd_prod = fp->rx_bd_prod;
 	bd_prod_fw = bd_prod;
 	sw_comp_cons = fp->rx_comp_cons;
 	sw_comp_prod = fp->rx_comp_prod;
 
-	/* Memory barrier necessary as speculative reads of the rx
-	 * buffer can be ahead of the index in the status block
-	 */
-	rmb();
+	comp_ring_cons = RCQ_BD(sw_comp_cons);
+	cqe = &fp->rx_comp_ring[comp_ring_cons];
+	cqe_fp = &cqe->fast_path_cqe;
 
 	DP(NETIF_MSG_RX_STATUS,
-	   "queue[%d]:  hw_comp_cons %u  sw_comp_cons %u\n",
-	   fp->index, hw_comp_cons, sw_comp_cons);
+	   "queue[%d]: sw_comp_cons %u\n", fp->index, sw_comp_cons);
 
-	while (sw_comp_cons != hw_comp_cons) {
+	while (BNX2X_IS_CQE_COMPLETED(cqe_fp)) {
 		struct sw_rx_bd *rx_buf = NULL;
 		struct sk_buff *skb;
-		union eth_rx_cqe *cqe;
-		struct eth_fast_path_rx_cqe *cqe_fp;
 		u8 cqe_fp_flags;
 		enum eth_rx_cqe_type cqe_fp_type;
 		u16 len, pad, queue;
@@ -850,12 +841,9 @@ int bnx2x_rx_int(struct bnx2x_fastpath *
 			return 0;
 #endif
 
-		comp_ring_cons = RCQ_BD(sw_comp_cons);
 		bd_prod = RX_BD(bd_prod);
 		bd_cons = RX_BD(bd_cons);
 
-		cqe = &fp->rx_comp_ring[comp_ring_cons];
-		cqe_fp = &cqe->fast_path_cqe;
 		cqe_fp_flags = cqe_fp->type_error_flags;
 		cqe_fp_type = cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE;
 
@@ -899,7 +887,6 @@ int bnx2x_rx_int(struct bnx2x_fastpath *
 						cqe_fp);
 
 				goto next_rx;
-
 			}
 			queue = cqe->end_agg_cqe.queue_index;
 			tpa_info = &fp->tpa_info[queue];
@@ -1002,9 +989,13 @@ reuse_rx:
 		    PARSING_FLAGS_VLAN)
 			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
 					       le16_to_cpu(cqe_fp->vlan_tag));
-		napi_gro_receive(&fp->napi, skb);
 
+		skb_mark_napi_id(skb, &fp->napi);
 
+		if (bnx2x_fp_ll_polling(fp))
+			netif_receive_skb(skb);
+		else
+			napi_gro_receive(&fp->napi, skb);
 next_rx:
 		rx_buf->data = NULL;
 
@@ -1016,8 +1007,15 @@ next_cqe:
 		sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod);
 		sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons);
 
+		/* mark CQE as free */
+		BNX2X_SEED_CQE(cqe_fp);
+
 		if (rx_pkt == budget)
 			break;
+
+		comp_ring_cons = RCQ_BD(sw_comp_cons);
+		cqe = &fp->rx_comp_ring[comp_ring_cons];
+		cqe_fp = &cqe->fast_path_cqe;
 	} /* while */
 
 	fp->rx_bd_cons = bd_cons;
@@ -1053,8 +1051,6 @@ static irqreturn_t bnx2x_msix_fp_int(int
 #endif
 
 	/* Handle Rx and Tx according to MSI-X vector */
-	prefetch(fp->rx_cons_sb);
-
 	for_each_cos_in_tx_queue(fp, cos)
 		prefetch(fp->txdata_ptr[cos]->tx_cons_sb);
 
@@ -1118,7 +1114,7 @@ static void bnx2x_fill_report_data(struc
 
 	memset(data, 0, sizeof(*data));
 
-	/* Fill the report data: efective line speed */
+	/* Fill the report data: effective line speed */
 	data->line_speed = line_speed;
 
 	/* Link is down */
@@ -1161,7 +1157,7 @@ void bnx2x_link_report(struct bnx2x *bp)
  *
  * @bp:		driver handle
  *
- * None atomic inmlementation.
+ * None atomic implementation.
  * Should be called under the phy_lock.
  */
 void __bnx2x_link_report(struct bnx2x *bp)
@@ -1304,7 +1300,7 @@ void bnx2x_init_rx_rings(struct bnx2x *b
 		   "mtu %d  rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size);
 
 		if (!fp->disable_tpa) {
-			/* Fill the per-aggregtion pool */
+			/* Fill the per-aggregation pool */
 			for (i = 0; i < MAX_AGG_QS(bp); i++) {
 				struct bnx2x_agg_info *tpa_info =
 					&fp->tpa_info[i];
@@ -1726,7 +1722,7 @@ static int bnx2x_req_irq(struct bnx2x *b
 	return request_irq(irq, bnx2x_interrupt, flags, bp->dev->name, bp->dev);
 }
 
-int bnx2x_setup_irqs(struct bnx2x *bp)
+static int bnx2x_setup_irqs(struct bnx2x *bp)
 {
 	int rc = 0;
 	if (bp->flags & USING_MSIX_FLAG &&
@@ -1759,32 +1755,46 @@ static void bnx2x_napi_enable_cnic(struc
 {
 	int i;
 
-	for_each_rx_queue_cnic(bp, i)
+	for_each_rx_queue_cnic(bp, i) {
+		bnx2x_fp_init_lock(&bp->fp[i]);
 		napi_enable(&bnx2x_fp(bp, i, napi));
+	}
 }
 
 static void bnx2x_napi_enable(struct bnx2x *bp)
 {
 	int i;
 
-	for_each_eth_queue(bp, i)
+	for_each_eth_queue(bp, i) {
+		bnx2x_fp_init_lock(&bp->fp[i]);
 		napi_enable(&bnx2x_fp(bp, i, napi));
+	}
 }
 
 static void bnx2x_napi_disable_cnic(struct bnx2x *bp)
 {
 	int i;
 
-	for_each_rx_queue_cnic(bp, i)
+	local_bh_disable();
+	for_each_rx_queue_cnic(bp, i) {
 		napi_disable(&bnx2x_fp(bp, i, napi));
+		while (!bnx2x_fp_lock_napi(&bp->fp[i]))
+			mdelay(1);
+	}
+	local_bh_enable();
 }
 
 static void bnx2x_napi_disable(struct bnx2x *bp)
 {
 	int i;
 
-	for_each_eth_queue(bp, i)
+	local_bh_disable();
+	for_each_eth_queue(bp, i) {
 		napi_disable(&bnx2x_fp(bp, i, napi));
+		while (!bnx2x_fp_lock_napi(&bp->fp[i]))
+			mdelay(1);
+	}
+	local_bh_enable();
 }
 
 void bnx2x_netif_start(struct bnx2x *bp)
@@ -1829,7 +1839,7 @@ u16 bnx2x_select_queue(struct net_device
 	}
 
 	/* select a non-FCoE queue */
-	return __skb_tx_hash(dev, skb, BNX2X_NUM_ETH_QUEUES(bp));
+	return __netdev_pick_tx(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp);
 }
 
 void bnx2x_set_num_queues(struct bnx2x *bp)
@@ -1862,7 +1872,7 @@ void bnx2x_set_num_queues(struct bnx2x *
  *
  * If the actual number of Tx queues (for each CoS) is less than 16 then there
  * will be the holes at the end of each group of 16 ETh L2 indices (0..15,
- * 16..31,...) with indicies that are not coupled with any real Tx queue.
+ * 16..31,...) with indices that are not coupled with any real Tx queue.
  *
  * The proper configuration of skb->queue_mapping is handled by
  * bnx2x_select_queue() and __skb_tx_hash().
@@ -1924,7 +1934,7 @@ static void bnx2x_set_rx_buf_size(struct
 				  ETH_OVREHEAD +
 				  mtu +
 				  BNX2X_FW_RX_ALIGN_END;
-		/* Note : rx_buf_size doesnt take into account NET_SKB_PAD */
+		/* Note : rx_buf_size doesn't take into account NET_SKB_PAD */
 		if (fp->rx_buf_size + NET_SKB_PAD <= PAGE_SIZE)
 			fp->rx_frag_size = fp->rx_buf_size + NET_SKB_PAD;
 		else
@@ -1937,7 +1947,7 @@ static int bnx2x_init_rss_pf(struct bnx2
 	int i;
 	u8 num_eth_queues = BNX2X_NUM_ETH_QUEUES(bp);
 
-	/* Prepare the initial contents fo the indirection table if RSS is
+	/* Prepare the initial contents for the indirection table if RSS is
 	 * enabled
 	 */
 	for (i = 0; i < sizeof(bp->rss_conf_obj.ind_table); i++)
@@ -2015,7 +2025,7 @@ static int bnx2x_init_hw(struct bnx2x *b
 
 /*
  * Cleans the object that have internal lists without sending
- * ramrods. Should be run when interrutps are disabled.
+ * ramrods. Should be run when interrupts are disabled.
  */
 void bnx2x_squeeze_objects(struct bnx2x *bp)
 {
@@ -2166,10 +2176,10 @@ static int bnx2x_alloc_fw_stats_mem(stru
 	bp->fw_stats_data_mapping = bp->fw_stats_mapping +
 		bp->fw_stats_req_sz;
 
-	DP(BNX2X_MSG_SP, "statistics request base address set to %x %x",
+	DP(BNX2X_MSG_SP, "statistics request base address set to %x %x\n",
 	   U64_HI(bp->fw_stats_req_mapping),
 	   U64_LO(bp->fw_stats_req_mapping));
-	DP(BNX2X_MSG_SP, "statistics data base address set to %x %x",
+	DP(BNX2X_MSG_SP, "statistics data base address set to %x %x\n",
 	   U64_HI(bp->fw_stats_data_mapping),
 	   U64_LO(bp->fw_stats_data_mapping));
 	return 0;
@@ -2183,6 +2193,8 @@ alloc_mem_err:
 /* send load request to mcp and analyze response */
 static int bnx2x_nic_load_request(struct bnx2x *bp, u32 *load_code)
 {
+	u32 param;
+
 	/* init fw_seq */
 	bp->fw_seq =
 		(SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
@@ -2195,9 +2207,13 @@ static int bnx2x_nic_load_request(struct
 		 DRV_PULSE_SEQ_MASK);
 	BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq);
 
+	param = DRV_MSG_CODE_LOAD_REQ_WITH_LFA;
+
+	if (IS_MF_SD(bp) && bnx2x_port_after_undi(bp))
+		param |= DRV_MSG_CODE_LOAD_REQ_FORCE_LFA;
+
 	/* load request */
-	(*load_code) = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ,
-					DRV_MSG_CODE_LOAD_REQ_WITH_LFA);
+	(*load_code) = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, param);
 
 	/* if mcp fails to respond we must abort */
 	if (!(*load_code)) {
@@ -2237,7 +2253,7 @@ int bnx2x_nic_load_analyze_req(struct bn
 
 		/* abort nic load if version mismatch */
 		if (my_fw != loaded_fw) {
-			BNX2X_ERR("bnx2x with FW %x was already loaded which mismatches my %x FW. aborting\n",
+			BNX2X_ERR("bnx2x with FW %x was already loaded which mismatches my %x FW. Aborting\n",
 				  loaded_fw, my_fw);
 			return -EBUSY;
 		}
@@ -2315,10 +2331,10 @@ static void bnx2x_nic_load_afex_dcc(stru
 static void bnx2x_bz_fp(struct bnx2x *bp, int index)
 {
 	struct bnx2x_fastpath *fp = &bp->fp[index];
-
 	int cos;
 	struct napi_struct orig_napi = fp->napi;
 	struct bnx2x_agg_info *orig_tpa_info = fp->tpa_info;
+
 	/* bzero bnx2x_fastpath contents */
 	if (fp->tpa_info)
 		memset(fp->tpa_info, 0, ETH_MAX_AGGREGATION_QUEUES_E1H_E2 *
@@ -2344,8 +2360,7 @@ static void bnx2x_bz_fp(struct bnx2x *bp
 			fp->txdata_ptr[cos] = &bp->bnx2x_txq[cos *
 				BNX2X_NUM_ETH_QUEUES(bp) + index];
 
-	/*
-	 * set the tpa flag for each queue. The tpa flag determines the queue
+	/* set the tpa flag for each queue. The tpa flag determines the queue
 	 * minimal size so it must be set prior to queue memory allocation
 	 */
 	fp->disable_tpa = !(bp->flags & TPA_ENABLE_FLAG ||
@@ -2428,7 +2443,6 @@ int bnx2x_load_cnic(struct bnx2x *bp)
 	if (bp->state == BNX2X_STATE_OPEN)
 		bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD);
 
-
 	DP(NETIF_MSG_IFUP, "Ending successfully CNIC-related load\n");
 
 	return 0;
@@ -2471,6 +2485,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int
 
 	bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
 
+	/* zero the structure w/o any lock, before SP handler is initialized */
 	memset(&bp->last_reported_link, 0, sizeof(bp->last_reported_link));
 	__set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
 		&bp->last_reported_link.link_report_flags);
@@ -2535,8 +2550,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int
 	}
 
 	/* configure multi cos mappings in kernel.
-	 * this configuration may be overriden by a multi class queue discipline
-	 * or by a dcbx negotiation result.
+	 * this configuration may be overridden by a multi class queue
+	 * discipline or by a dcbx negotiation result.
 	 */
 	bnx2x_setup_tc(bp->dev, bp->max_cos);
 
@@ -2695,7 +2710,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int
 	/* Start the Tx */
 	switch (load_mode) {
 	case LOAD_NORMAL:
-		/* Tx queue should be only reenabled */
+		/* Tx queue should be only re-enabled */
 		netif_tx_wake_all_queues(bp->dev);
 		break;
 
@@ -2840,7 +2855,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, i
 	}
 
 	/* Nothing to do during unload if previous bnx2x_nic_load()
-	 * have not completed succesfully - all resourses are released.
+	 * have not completed successfully - all resources are released.
 	 *
 	 * we can get here only after unsuccessful ndo_* callback, during which
 	 * dev->IFF_UP flag is still on.
@@ -2855,6 +2870,9 @@ int bnx2x_nic_unload(struct bnx2x *bp, i
 	bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
 	smp_mb();
 
+	/* indicate to VFs that the PF is going down */
+	bnx2x_iov_channel_down(bp);
+
 	if (CNIC_LOADED(bp))
 		bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD);
 
@@ -2889,10 +2907,9 @@ int bnx2x_nic_unload(struct bnx2x *bp, i
 		/* Send the UNLOAD_REQUEST to the MCP */
 		bnx2x_send_unload_req(bp, unload_mode);
 
-		/*
-		 * Prevent transactions to host from the functions on the
+		/* Prevent transactions to host from the functions on the
 		 * engine that doesn't reset global blocks in case of global
-		 * attention once gloabl blocks are reset and gates are opened
+		 * attention once global blocks are reset and gates are opened
 		 * (the engine which leader will perform the recovery
 		 * last).
 		 */
@@ -2913,7 +2930,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, i
 	}
 
 	/*
-	 * At this stage no more interrupts will arrive so we may safly clean
+	 * At this stage no more interrupts will arrive so we may safely clean
 	 * the queueable objects here in case they failed to get cleaned so far.
 	 */
 	if (IS_PF(bp))
@@ -2954,7 +2971,6 @@ int bnx2x_nic_unload(struct bnx2x *bp, i
 			bnx2x_set_reset_global(bp);
 	}
 
-
 	/* The last driver must disable a "close the gate" if there is no
 	 * parity attention or "process kill" pending.
 	 */
@@ -3039,6 +3055,8 @@ int bnx2x_poll(struct napi_struct *napi,
 			return 0;
 		}
 #endif
+		if (!bnx2x_fp_lock_napi(fp))
+			return work_done;
 
 		for_each_cos_in_tx_queue(fp, cos)
 			if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos]))
@@ -3048,12 +3066,15 @@ int bnx2x_poll(struct napi_struct *napi,
 			work_done += bnx2x_rx_int(fp, budget - work_done);
 
 			/* must not complete if we consumed full budget */
-			if (work_done >= budget)
+			if (work_done >= budget) {
+				bnx2x_fp_unlock_napi(fp);
 				break;
+			}
 		}
 
 		/* Fall out from the NAPI loop if needed */
-		if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
+		if (!bnx2x_fp_unlock_napi(fp) &&
+		    !(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
 
 			/* No need to update SB for FCoE L2 ring as long as
 			 * it's connected to the default SB and the SB
@@ -3095,6 +3116,32 @@ int bnx2x_poll(struct napi_struct *napi,
 	return work_done;
 }
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+/* must be called with local_bh_disable()d */
+int bnx2x_low_latency_recv(struct napi_struct *napi)
+{
+	struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath,
+						 napi);
+	struct bnx2x *bp = fp->bp;
+	int found = 0;
+
+	if ((bp->state == BNX2X_STATE_CLOSED) ||
+	    (bp->state == BNX2X_STATE_ERROR) ||
+	    (bp->flags & (TPA_ENABLE_FLAG | GRO_ENABLE_FLAG)))
+		return LL_FLUSH_FAILED;
+
+	if (!bnx2x_fp_lock_poll(fp))
+		return LL_FLUSH_BUSY;
+
+	if (bnx2x_has_rx_work(fp))
+		found = bnx2x_rx_int(fp, 4);
+
+	bnx2x_fp_unlock_poll(fp);
+
+	return found;
+}
+#endif
+
 /* we split the first BD into headers and data BDs
  * to ease the pain of our fellow microcode engineers
  * we use one mapping for both BDs
@@ -3495,9 +3542,12 @@ static void bnx2x_update_pbds_gso_enc(st
 	/* outer IP header info */
 	if (xmit_type & XMIT_CSUM_V4) {
 		struct iphdr *iph = ip_hdr(skb);
+		u32 csum = (__force u32)(~iph->check) -
+			   (__force u32)iph->tot_len -
+			   (__force u32)iph->frag_off;
+
 		pbd2->fw_ip_csum_wo_len_flags_frag =
-			bswab16(csum_fold((~iph->check) -
-					  iph->tot_len - iph->frag_off));
+			bswab16(csum_fold((__force __wsum)csum));
 	} else {
 		pbd2->fw_ip_hdr_to_payload_w =
 			hlen_w - ((sizeof(struct ipv6hdr)) >> 1);
@@ -3585,7 +3635,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_b
 	DP(NETIF_MSG_TX_QUEUED, "indices: txq %d, fp %d, txdata %d\n",
 	   txq_index, fp_index, txdata_index); */
 
-	/* enable this debug print to view the tranmission details
+	/* enable this debug print to view the transmission details
 	DP(NETIF_MSG_TX_QUEUED,
 	   "transmitting packet cid %d fp index %d txdata_index %d tx_data ptr %p fp pointer %p\n",
 	   txdata->cid, fp_index, txdata_index, txdata, fp); */
@@ -3967,7 +4017,7 @@ int bnx2x_setup_tc(struct net_device *de
 	/* setup tc must be called under rtnl lock */
 	ASSERT_RTNL();
 
-	/* no traffic classes requested. aborting */
+	/* no traffic classes requested. Aborting */
 	if (!num_tc) {
 		netdev_reset_tc(dev);
 		return 0;
@@ -3975,7 +4025,7 @@ int bnx2x_setup_tc(struct net_device *de
 
 	/* requested to support too many traffic classes */
 	if (num_tc > bp->max_cos) {
-		BNX2X_ERR("support for too many traffic classes requested: %d. max supported is %d\n",
+		BNX2X_ERR("support for too many traffic classes requested: %d. Max supported is %d\n",
 			  num_tc, bp->max_cos);
 		return -EINVAL;
 	}
@@ -3994,8 +4044,7 @@ int bnx2x_setup_tc(struct net_device *de
 		   prio, bp->prio_to_cos[prio]);
 	}
 
-
-	/* Use this configuration to diffrentiate tc0 from other COSes
+	/* Use this configuration to differentiate tc0 from other COSes
 	   This can be used for ets or pfc, and save the effort of setting
 	   up a multio class queue disc or negotiating DCBX with a switch
 	netdev_set_prio_tc_map(dev, 0, 0);
@@ -4287,10 +4336,11 @@ static int bnx2x_alloc_fp_mem_at(struct
 				&bnx2x_fp(bp, index, rx_desc_mapping),
 				sizeof(struct eth_rx_bd) * NUM_RX_BD);
 
-		BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_comp_ring),
-				&bnx2x_fp(bp, index, rx_comp_mapping),
-				sizeof(struct eth_fast_path_rx_cqe) *
-				NUM_RCQ_BD);
+		/* Seed all CQEs by 1s */
+		BNX2X_PCI_FALLOC(bnx2x_fp(bp, index, rx_comp_ring),
+				 &bnx2x_fp(bp, index, rx_comp_mapping),
+				 sizeof(struct eth_fast_path_rx_cqe) *
+				 NUM_RCQ_BD);
 
 		/* SGE ring */
 		BNX2X_ALLOC(bnx2x_fp(bp, index, rx_page_ring),
@@ -4471,7 +4521,6 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp)
 alloc_err:
 	bnx2x_free_mem_bp(bp);
 	return -ENOMEM;
-
 }
 
 int bnx2x_reload_if_running(struct net_device *dev)
@@ -4513,7 +4562,6 @@ int bnx2x_get_cur_phy_idx(struct bnx2x *
 	}
 
 	return sel_phy_idx;
-
 }
 int bnx2x_get_link_cfg_idx(struct bnx2x *bp)
 {
@@ -4601,6 +4649,7 @@ int bnx2x_set_features(struct net_device
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	u32 flags = bp->flags;
+	u32 changes;
 	bool bnx2x_reload = false;
 
 	if (features & NETIF_F_LRO)
@@ -4625,10 +4674,16 @@ int bnx2x_set_features(struct net_device
 		}
 	}
 
-	if (flags ^ bp->flags) {
-		bp->flags = flags;
+	changes = flags ^ bp->flags;
+
+	/* if GRO is changed while LRO is enabled, don't force a reload */
+	if ((changes & GRO_ENABLE_FLAG) && (flags & TPA_ENABLE_FLAG))
+		changes &= ~GRO_ENABLE_FLAG;
+
+	if (changes)
 		bnx2x_reload = true;
-	}
+
+	bp->flags = flags;
 
 	if (bnx2x_reload) {
 		if (bp->recovery_state == BNX2X_RECOVERY_DONE)
@@ -4723,7 +4778,6 @@ int bnx2x_resume(struct pci_dev *pdev)
 	return rc;
 }
 
-
 void bnx2x_set_ctx_validation(struct bnx2x *bp, struct eth_context *cxt,
 			      u32 cid)
 {
@@ -4741,7 +4795,6 @@ static void storm_memset_hc_timeout(stru
 				    u8 fw_sb_id, u8 sb_index,
 				    u8 ticks)
 {
-
 	u32 addr = BAR_CSTRORM_INTMEM +
 		   CSTORM_STATUS_BLOCK_DATA_TIMEOUT_OFFSET(fw_sb_id, sb_index);
 	REG_WR8(bp, addr, ticks);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 
-
 #include "bnx2x.h"
 #include "bnx2x_sriov.h"
 
@@ -50,13 +49,25 @@ extern int int_mode;
 		} \
 	} while (0)
 
-#define BNX2X_PCI_ALLOC(x, y, size)				\
-do {								\
-	x = dma_alloc_coherent(&bp->pdev->dev, size, y,		\
-			       GFP_KERNEL | __GFP_ZERO);	\
-	if (x == NULL)						\
-		goto alloc_mem_err;				\
-} while (0)
+#define BNX2X_PCI_ALLOC(x, y, size) \
+	do { \
+		x = dma_alloc_coherent(&bp->pdev->dev, size, y, \
+				       GFP_KERNEL | __GFP_ZERO); \
+		if (x == NULL) \
+			goto alloc_mem_err; \
+		DP(NETIF_MSG_HW, "BNX2X_PCI_ALLOC: Physical %Lx Virtual %p\n", \
+		   (unsigned long long)(*y), x); \
+	} while (0)
+
+#define BNX2X_PCI_FALLOC(x, y, size) \
+	do { \
+		x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
+		if (x == NULL) \
+			goto alloc_mem_err; \
+		memset((void *)x, 0xFFFFFFFF, size); \
+		DP(NETIF_MSG_HW, "BNX2X_PCI_FALLOC: Physical %Lx Virtual %p\n",\
+		   (unsigned long long)(*y), x); \
+	} while (0)
 
 #define BNX2X_ALLOC(x, size) \
 	do { \
@@ -494,9 +505,6 @@ void bnx2x_update_max_mf_config(struct b
 /* Error handling */
 void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl);
 
-/* validate currect fw is loaded */
-bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err);
-
 /* dev_close main block */
 int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link);
 
@@ -607,6 +615,13 @@ int bnx2x_enable_msi(struct bnx2x *bp);
 int bnx2x_poll(struct napi_struct *napi, int budget);
 
 /**
+ * bnx2x_low_latency_recv - LL callback
+ *
+ * @napi:	napi structure
+ */
+int bnx2x_low_latency_recv(struct napi_struct *napi);
+
+/**
  * bnx2x_alloc_mem_bp - allocate memories outsize main driver structure
  *
  * @bp:		driver handle
@@ -800,16 +815,18 @@ static inline bool bnx2x_has_tx_work(str
 	return false;
 }
 
+#define BNX2X_IS_CQE_COMPLETED(cqe_fp) (cqe_fp->marker == 0x0)
+#define BNX2X_SEED_CQE(cqe_fp) (cqe_fp->marker = 0xFFFFFFFF)
 static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
 {
-	u16 rx_cons_sb;
+	u16 cons;
+	union eth_rx_cqe *cqe;
+	struct eth_fast_path_rx_cqe *cqe_fp;
 
-	/* Tell compiler that status block fields can change */
-	barrier();
-	rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
-	if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
-		rx_cons_sb++;
-	return (fp->rx_comp_cons != rx_cons_sb);
+	cons = RCQ_BD(fp->rx_comp_cons);
+	cqe = &fp->rx_comp_ring[cons];
+	cqe_fp = &cqe->fast_path_cqe;
+	return BNX2X_IS_CQE_COMPLETED(cqe_fp);
 }
 
 /**
@@ -848,9 +865,11 @@ static inline void bnx2x_add_all_napi_cn
 	int i;
 
 	/* Add NAPI objects */
-	for_each_rx_queue_cnic(bp, i)
+	for_each_rx_queue_cnic(bp, i) {
 		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
 			       bnx2x_poll, NAPI_POLL_WEIGHT);
+		napi_hash_add(&bnx2x_fp(bp, i, napi));
+	}
 }
 
 static inline void bnx2x_add_all_napi(struct bnx2x *bp)
@@ -858,25 +877,31 @@ static inline void bnx2x_add_all_napi(st
 	int i;
 
 	/* Add NAPI objects */
-	for_each_eth_queue(bp, i)
+	for_each_eth_queue(bp, i) {
 		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
 			       bnx2x_poll, NAPI_POLL_WEIGHT);
+		napi_hash_add(&bnx2x_fp(bp, i, napi));
+	}
 }
 
 static inline void bnx2x_del_all_napi_cnic(struct bnx2x *bp)
 {
 	int i;
 
-	for_each_rx_queue_cnic(bp, i)
+	for_each_rx_queue_cnic(bp, i) {
+		napi_hash_del(&bnx2x_fp(bp, i, napi));
 		netif_napi_del(&bnx2x_fp(bp, i, napi));
+	}
 }
 
 static inline void bnx2x_del_all_napi(struct bnx2x *bp)
 {
 	int i;
 
-	for_each_eth_queue(bp, i)
+	for_each_eth_queue(bp, i) {
+		napi_hash_del(&bnx2x_fp(bp, i, napi));
 		netif_napi_del(&bnx2x_fp(bp, i, napi));
+	}
 }
 
 int bnx2x_set_int_mode(struct bnx2x *bp);
@@ -1171,7 +1196,6 @@ static inline u8 bnx2x_cnic_eth_cl_id(st
 
 static inline u8 bnx2x_cnic_fw_sb_id(struct bnx2x *bp)
 {
-
 	/* the 'first' id is allocated for the cnic */
 	return bp->base_fw_ndsb;
 }
@@ -1181,7 +1205,6 @@ static inline u8 bnx2x_cnic_igu_sb_id(st
 	return bp->igu_base_sb;
 }
 
-
 static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp)
 {
 	struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp);
@@ -1334,8 +1357,8 @@ static inline bool bnx2x_mtu_allows_gro(
 	int fpp = SGE_PAGE_SIZE / (mtu - ETH_MAX_TPA_HEADER_SIZE);
 
 	/*
-	 * 1. number of frags should not grow above MAX_SKB_FRAGS
-	 * 2. frag must fit the page
+	 * 1. Number of frags should not grow above MAX_SKB_FRAGS
+	 * 2. Frag must fit the page
 	 */
 	return mtu <= SGE_PAGE_SIZE && (U_ETH_SGL_SIZE * fpp) <= MAX_SKB_FRAGS;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,10 +30,8 @@
 #include "bnx2x_dcb.h"
 
 /* forward declarations of dcbx related functions */
-static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp);
 static void bnx2x_pfc_set_pfc(struct bnx2x *bp);
 static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp);
-static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp);
 static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
 					  u32 *set_configuration_ets_pg,
 					  u32 *pri_pg_tbl);
@@ -253,7 +251,6 @@ static void bnx2x_dcbx_get_ets_feature(s
 
 	memset(&pg_help_data, 0, sizeof(struct pg_help_data));
 
-
 	if (GET_FLAGS(error, DCBX_LOCAL_ETS_ERROR))
 		DP(BNX2X_MSG_DCB, "DCBX_LOCAL_ETS_ERROR\n");
 
@@ -298,7 +295,6 @@ static void bnx2x_dcbx_get_ets_feature(s
 static void  bnx2x_dcbx_get_pfc_feature(struct bnx2x *bp,
 					struct dcbx_pfc_feature *pfc, u32 error)
 {
-
 	if (GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR))
 		DP(BNX2X_MSG_DCB, "DCBX_LOCAL_PFC_ERROR\n");
 
@@ -367,7 +363,6 @@ static int bnx2x_dcbx_read_mib(struct bn
 	struct lldp_remote_mib *remote_mib ;
 	struct lldp_local_mib  *local_mib;
 
-
 	switch (read_mib_type) {
 	case DCBX_READ_LOCAL_MIB:
 		mib_size = sizeof(struct lldp_local_mib);
@@ -428,30 +423,52 @@ static void bnx2x_pfc_set_pfc(struct bnx
 		bnx2x_pfc_clear(bp);
 }
 
-static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp)
+int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp)
 {
 	struct bnx2x_func_state_params func_params = {NULL};
+	int rc;
 
 	func_params.f_obj = &bp->func_obj;
 	func_params.cmd = BNX2X_F_CMD_TX_STOP;
 
+	__set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
+	__set_bit(RAMROD_RETRY, &func_params.ramrod_flags);
+
 	DP(BNX2X_MSG_DCB, "STOP TRAFFIC\n");
-	return bnx2x_func_state_change(bp, &func_params);
+
+	rc = bnx2x_func_state_change(bp, &func_params);
+	if (rc) {
+		BNX2X_ERR("Unable to hold traffic for HW configuration\n");
+		bnx2x_panic();
+	}
+
+	return rc;
 }
 
-static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp)
+int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp)
 {
 	struct bnx2x_func_state_params func_params = {NULL};
 	struct bnx2x_func_tx_start_params *tx_params =
 		&func_params.params.tx_start;
+	int rc;
 
 	func_params.f_obj = &bp->func_obj;
 	func_params.cmd = BNX2X_F_CMD_TX_START;
 
+	__set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
+	__set_bit(RAMROD_RETRY, &func_params.ramrod_flags);
+
 	bnx2x_dcbx_fw_struct(bp, tx_params);
 
 	DP(BNX2X_MSG_DCB, "START TRAFFIC\n");
-	return bnx2x_func_state_change(bp, &func_params);
+
+	rc = bnx2x_func_state_change(bp, &func_params);
+	if (rc) {
+		BNX2X_ERR("Unable to resume traffic after HW configuration\n");
+		bnx2x_panic();
+	}
+
+	return rc;
 }
 
 static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp)
@@ -629,7 +646,6 @@ static int bnx2x_dcbx_read_shmem_neg_res
 	return 0;
 }
 
-
 #ifdef BCM_DCBNL
 static inline
 u8 bnx2x_dcbx_dcbnl_app_up(struct dcbx_app_priority_entry *ent)
@@ -691,7 +707,7 @@ static inline void bnx2x_dcbx_update_tc_
 	}
 
 	/* setup tc must be called under rtnl lock, but we can't take it here
-	 * as we are handling an attetntion on a work queue which must be
+	 * as we are handling an attention on a work queue which must be
 	 * flushed at some rtnl-locked contexts (e.g. if down)
 	 */
 	if (!test_and_set_bit(BNX2X_SP_RTNL_SETUP_TC, &bp->sp_rtnl_state))
@@ -711,7 +727,7 @@ void bnx2x_dcbx_set_params(struct bnx2x
 			 */
 			bnx2x_dcbnl_update_applist(bp, true);
 
-			/* Read rmeote mib if dcbx is in the FW */
+			/* Read remote mib if dcbx is in the FW */
 			if (bnx2x_dcbx_read_shmem_remote_mib(bp))
 				return;
 #endif
@@ -742,13 +758,15 @@ void bnx2x_dcbx_set_params(struct bnx2x
 			bnx2x_dcbx_update_tc_mapping(bp);
 
 			/*
-			 * allow other funtions to update their netdevices
+			 * allow other functions to update their netdevices
 			 * accordingly
 			 */
 			if (IS_MF(bp))
 				bnx2x_link_sync_notify(bp);
 
-			bnx2x_dcbx_stop_hw_tx(bp);
+			set_bit(BNX2X_SP_RTNL_TX_STOP, &bp->sp_rtnl_state);
+
+			schedule_delayed_work(&bp->sp_rtnl_task, 0);
 
 			return;
 		}
@@ -757,7 +775,13 @@ void bnx2x_dcbx_set_params(struct bnx2x
 		bnx2x_pfc_set_pfc(bp);
 
 		bnx2x_dcbx_update_ets_params(bp);
-		bnx2x_dcbx_resume_hw_tx(bp);
+
+		/* ets may affect cmng configuration: reinit it in hw */
+		bnx2x_set_local_cmng(bp);
+
+		set_bit(BNX2X_SP_RTNL_TX_RESUME, &bp->sp_rtnl_state);
+
+		schedule_delayed_work(&bp->sp_rtnl_task, 0);
 
 		return;
 	case BNX2X_DCBX_STATE_TX_RELEASED:
@@ -864,7 +888,7 @@ static void bnx2x_dcbx_admin_mib_updated
 			   i, DCBX_PRI_PG_GET(af->ets.pri_pg_tbl, i));
 		}
 
-		/*For IEEE admin_recommendation_bw_precentage
+		/*For IEEE admin_recommendation_bw_percentage
 		 *For IEEE admin_recommendation_ets_pg */
 		af->pfc.pri_en_bitmap = (u8)dp->admin_pfc_bitmap;
 		for (i = 0; i < DCBX_CONFIG_MAX_APP_PROTOCOL; i++) {
@@ -896,13 +920,11 @@ static void bnx2x_dcbx_admin_mib_updated
 		}
 
 		af->app.default_pri = (u8)dp->admin_default_priority;
-
 	}
 
 	/* Write the data. */
 	bnx2x_write_data(bp, (u32 *)&admin_mib, offset,
 			 sizeof(struct lldp_admin_mib));
-
 }
 
 void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled)
@@ -1076,7 +1098,7 @@ static void bnx2x_dcbx_get_num_pg_traf_t
 	bool pg_found  = false;
 	u32 i, traf_type, add_traf_type, add_pg;
 	u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
-	struct pg_entry_help_data *data = help_data->data; /*shotcut*/
+	struct pg_entry_help_data *data = help_data->data; /*shortcut*/
 
 	/* Set to invalid */
 	for (i = 0; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++)
@@ -1172,7 +1194,8 @@ static void bnx2x_dcbx_separate_pauseabl
 				DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_entry));
 		else
 			/* If we join a group and one is strict
-			 * than the bw rulls */
+			 * than the bw rules
+			 */
 			cos_data->data[entry].strict =
 						BNX2X_DCBX_STRICT_COS_HIGHEST;
 	}
@@ -1181,7 +1204,6 @@ static void bnx2x_dcbx_separate_pauseabl
 		BNX2X_ERR("dcbx error: Both groups must have priorities\n");
 }
 
-
 #ifndef POWER_OF_2
 #define POWER_OF_2(x)	((0 != x) && (0 == (x & (x-1))))
 #endif
@@ -1284,7 +1306,7 @@ static void bnx2x_dcbx_2cos_limit_cee_si
 		} else {
 			/* If there are only pauseable priorities or
 			 * only non-pauseable,* the lower priorities go
-			 * to the first queue and the higherpriorities go
+			 * to the first queue and the higher priorities go
 			 * to the second queue.
 			 */
 			cos_data->data[0].pausable =
@@ -1484,7 +1506,7 @@ static void bnx2x_dcbx_2cos_limit_cee_th
 		 * queue and one priority goes to the second queue.
 		 *
 		 * We will join this two cases:
-		 * if one is BW limited it will go to the secoend queue
+		 * if one is BW limited it will go to the second queue
 		 * otherwise the last priority will get it
 		 */
 
@@ -1504,7 +1526,8 @@ static void bnx2x_dcbx_2cos_limit_cee_th
 				    false == b_found_strict)
 					/* last entry will be handled separately
 					 * If no priority is strict than last
-					 * enty goes to last queue.*/
+					 * entry goes to last queue.
+					 */
 					entry = 1;
 				cos_data->data[entry].pri_join_mask |=
 								pri_tested;
@@ -1516,7 +1539,8 @@ static void bnx2x_dcbx_2cos_limit_cee_th
 				b_found_strict = true;
 				cos_data->data[1].pri_join_mask |= pri_tested;
 				/* If we join a group and one is strict
-				 * than the bw rulls */
+				 * than the bw rules
+				 */
 				cos_data->data[1].strict =
 					BNX2X_DCBX_STRICT_COS_HIGHEST;
 			}
@@ -1524,7 +1548,6 @@ static void bnx2x_dcbx_2cos_limit_cee_th
 	}
 }
 
-
 static void bnx2x_dcbx_2cos_limit_cee_fill_cos_params(struct bnx2x *bp,
 				       struct pg_help_data *help_data,
 				       struct dcbx_ets_feature *ets,
@@ -1533,7 +1556,6 @@ static void bnx2x_dcbx_2cos_limit_cee_fi
 				       u32 pri_join_mask,
 				       u8 num_of_dif_pri)
 {
-
 	/* default E2 settings */
 	cos_data->num_of_cos = DCBX_COS_MAX_NUM_E2;
 
@@ -1629,7 +1651,6 @@ static u8 bnx2x_dcbx_cee_fill_strict_pri
 					 u8 num_spread_of_entries,
 					 u8 strict_app_pris)
 {
-
 	if (bnx2x_dcbx_spread_strict_pri(bp, cos_data, entry,
 					 num_spread_of_entries,
 					 strict_app_pris)) {
@@ -1848,7 +1869,7 @@ static void bnx2x_dcbx_fw_struct(struct
 
 void bnx2x_dcbx_pmf_update(struct bnx2x *bp)
 {
-	/* if we need to syncronize DCBX result from prev PMF
+	/* if we need to synchronize DCBX result from prev PMF
 	 * read it from shmem and update bp and netdev accordingly
 	 */
 	if (SHMEM2_HAS(bp, drv_flags) &&
@@ -1876,7 +1897,6 @@ void bnx2x_dcbx_pmf_update(struct bnx2x
 		 * dcbx negotiation.
 		 */
 		bnx2x_dcbx_update_tc_mapping(bp);
-
 	}
 }
 
@@ -1943,14 +1963,14 @@ static void bnx2x_dcbnl_set_pg_tccfg_tx(
 		return;
 
 	/**
-	 * bw_pct ingnored -	band-width percentage devision between user
+	 * bw_pct ignored -	band-width percentage devision between user
 	 *			priorities within the same group is not
 	 *			standard and hence not supported
 	 *
-	 * prio_type igonred -	priority levels within the same group are not
+	 * prio_type ignored -	priority levels within the same group are not
 	 *			standard and hence are not supported. According
 	 *			to the standard pgid 15 is dedicated to strict
-	 *			prioirty traffic (on the port level).
+	 *			priority traffic (on the port level).
 	 *
 	 * up_map ignored
 	 */
@@ -1995,14 +2015,14 @@ static void bnx2x_dcbnl_get_pg_tccfg_tx(
 	DP(BNX2X_MSG_DCB, "prio = %d\n", prio);
 
 	/**
-	 * bw_pct ingnored -	band-width percentage devision between user
+	 * bw_pct ignored -	band-width percentage devision between user
 	 *			priorities within the same group is not
 	 *			standard and hence not supported
 	 *
-	 * prio_type igonred -	priority levels within the same group are not
+	 * prio_type ignored -	priority levels within the same group are not
 	 *			standard and hence are not supported. According
 	 *			to the standard pgid 15 is dedicated to strict
-	 *			prioirty traffic (on the port level).
+	 *			priority traffic (on the port level).
 	 *
 	 * up_map ignored
 	 */
@@ -2371,25 +2391,28 @@ static u8 bnx2x_dcbnl_get_featcfg(struct
 		case DCB_FEATCFG_ATTR_PG:
 			if (bp->dcbx_local_feat.ets.enabled)
 				*flags |= DCB_FEATCFG_ENABLE;
-			if (bp->dcbx_error & DCBX_LOCAL_ETS_ERROR)
+			if (bp->dcbx_error & (DCBX_LOCAL_ETS_ERROR |
+					      DCBX_REMOTE_MIB_ERROR))
 				*flags |= DCB_FEATCFG_ERROR;
 			break;
 		case DCB_FEATCFG_ATTR_PFC:
 			if (bp->dcbx_local_feat.pfc.enabled)
 				*flags |= DCB_FEATCFG_ENABLE;
 			if (bp->dcbx_error & (DCBX_LOCAL_PFC_ERROR |
-			    DCBX_LOCAL_PFC_MISMATCH))
+					      DCBX_LOCAL_PFC_MISMATCH |
+					      DCBX_REMOTE_MIB_ERROR))
 				*flags |= DCB_FEATCFG_ERROR;
 			break;
 		case DCB_FEATCFG_ATTR_APP:
 			if (bp->dcbx_local_feat.app.enabled)
 				*flags |= DCB_FEATCFG_ENABLE;
 			if (bp->dcbx_error & (DCBX_LOCAL_APP_ERROR |
-			    DCBX_LOCAL_APP_MISMATCH))
+					      DCBX_LOCAL_APP_MISMATCH |
+					      DCBX_REMOTE_MIB_ERROR))
 				*flags |= DCB_FEATCFG_ERROR;
 			break;
 		default:
-			BNX2X_ERR("Non valid featrue-ID\n");
+			BNX2X_ERR("Non valid feature-ID\n");
 			rval = 1;
 			break;
 		}
@@ -2430,7 +2453,7 @@ static u8 bnx2x_dcbnl_set_featcfg(struct
 				flags & DCB_FEATCFG_WILLING ? 1 : 0;
 			break;
 		default:
-			BNX2X_ERR("Non valid featrue-ID\n");
+			BNX2X_ERR("Non valid feature-ID\n");
 			rval = 1;
 			break;
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h	2013-08-25 20:43:22.000000000 -0400
@@ -134,8 +134,6 @@ enum {
 #define PFC_BRB1_REG_HIGH_LLFC_LOW_THRESHOLD			130
 #define PFC_BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD			170
 
-
-
 struct cos_entry_help_data {
 	u32			pri_join_mask;
 	u32			cos_bw;
@@ -170,7 +168,6 @@ struct cos_help_data {
 			(!(IS_DCBX_PFC_PRI_ONLY_NON_PAUSE((bp), (pg_pri)) || \
 			 IS_DCBX_PFC_PRI_ONLY_PAUSE((bp), (pg_pri))))
 
-
 struct pg_entry_help_data {
 	u8	num_of_dif_pri;
 	u8	pg;
@@ -202,4 +199,7 @@ extern const struct dcbnl_rtnl_ops bnx2x
 int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall);
 #endif /* BCM_DCBNL */
 
+int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp);
+int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp);
+
 #endif /* BNX2X_DCB_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,12 +13,6 @@
  * consent.
  */
 
-
-/* This struct holds a signature to ensure the dump returned from the driver
- * match the meta data file inserted to grc_dump.tcl
- * The signature is time stamp, diag version and grc_dump version
- */
-
 #ifndef BNX2X_DUMP_H
 #define BNX2X_DUMP_H
 
@@ -28,7 +22,6 @@
 #define DRV_DUMP_USTORM_WAITP_ADDRESS    0x338a80
 #define DRV_DUMP_CSTORM_WAITP_ADDRESS    0x238a80
 
-
 /* Possible Chips */
 #define DUMP_CHIP_E1 1
 #define DUMP_CHIP_E1H 2
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -320,7 +320,7 @@ static int bnx2x_set_settings(struct net
 
 	speed = ethtool_cmd_speed(cmd);
 
-	/* If recieved a request for an unknown duplex, assume full*/
+	/* If received a request for an unknown duplex, assume full*/
 	if (cmd->duplex == DUPLEX_UNKNOWN)
 		cmd->duplex = DUPLEX_FULL;
 
@@ -733,7 +733,6 @@ static bool bnx2x_is_reg_in_chip(struct
 		return false;
 }
 
-
 static bool bnx2x_is_wreg_in_chip(struct bnx2x *bp,
 	const struct wreg_addr *wreg_info)
 {
@@ -850,7 +849,7 @@ static int __bnx2x_get_preset_regs(struc
 
 	/* Paged registers are supported in E2 & E3 only */
 	if (CHIP_IS_E2(bp) || CHIP_IS_E3(bp)) {
-		/* Read "paged" registes */
+		/* Read "paged" registers */
 		bnx2x_read_pages_regs(bp, p, preset);
 	}
 
@@ -960,6 +959,9 @@ static int bnx2x_set_dump(struct net_dev
 	struct bnx2x *bp = netdev_priv(dev);
 
 	/* Use the ethtool_dump "flag" field as the dump preset index */
+	if (val->flag < 1 || val->flag > DUMP_MAX_PRESETS)
+		return -EINVAL;
+
 	bp->dump_preset_idx = val->flag;
 	return 0;
 }
@@ -969,12 +971,12 @@ static int bnx2x_get_dump_flag(struct ne
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
+	dump->version = BNX2X_DUMP_VERSION;
+	dump->flag = bp->dump_preset_idx;
 	/* Calculate the requested preset idx length */
 	dump->len = bnx2x_get_preset_regs_len(dev, bp->dump_preset_idx);
 	DP(BNX2X_MSG_ETHTOOL, "Get dump preset %d length=%d\n",
 	   bp->dump_preset_idx, dump->len);
-
-	dump->flag = ETHTOOL_GET_DUMP_DATA;
 	return 0;
 }
 
@@ -986,8 +988,6 @@ static int bnx2x_get_dump_data(struct ne
 	struct bnx2x *bp = netdev_priv(dev);
 	struct dump_header dump_hdr = {0};
 
-	memset(p, 0, dump->len);
-
 	/* Disable parity attentions as long as following dump may
 	 * cause false alarms by reading never written registers. We
 	 * will re-enable parity attentions right after the dump.
@@ -1155,8 +1155,8 @@ static int bnx2x_get_eeprom_len(struct n
 	return bp->common.flash_size;
 }
 
-/* Per pf misc lock must be aquired before the per port mcp lock. Otherwise, had
- * we done things the other way around, if two pfs from the same port would
+/* Per pf misc lock must be acquired before the per port mcp lock. Otherwise,
+ * had we done things the other way around, if two pfs from the same port would
  * attempt to access nvram at the same time, we could run into a scenario such
  * as:
  * pf A takes the port lock.
@@ -1381,12 +1381,29 @@ static int bnx2x_nvram_read32(struct bnx
 	return rc;
 }
 
+static bool bnx2x_is_nvm_accessible(struct bnx2x *bp)
+{
+	int rc = 1;
+	u16 pm = 0;
+	struct net_device *dev = pci_get_drvdata(bp->pdev);
+
+	if (bp->pm_cap)
+		rc = pci_read_config_word(bp->pdev,
+					  bp->pm_cap + PCI_PM_CTRL, &pm);
+
+	if ((rc && !netif_running(dev)) ||
+	    (!rc && ((pm & PCI_PM_CTRL_STATE_MASK) != (__force u16)PCI_D0)))
+		return false;
+
+	return true;
+}
+
 static int bnx2x_get_eeprom(struct net_device *dev,
 			    struct ethtool_eeprom *eeprom, u8 *eebuf)
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
-	if (!netif_running(dev)) {
+	if (!bnx2x_is_nvm_accessible(bp)) {
 		DP(BNX2X_MSG_ETHTOOL  | BNX2X_MSG_NVM,
 		   "cannot access eeprom when the interface is down\n");
 		return -EAGAIN;
@@ -1411,7 +1428,7 @@ static int bnx2x_get_module_eeprom(struc
 	u8 *user_data = data;
 	unsigned int start_addr = ee->offset, xfer_size = 0;
 
-	if (!netif_running(dev)) {
+	if (!bnx2x_is_nvm_accessible(bp)) {
 		DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
 		   "cannot access eeprom when the interface is down\n");
 		return -EAGAIN;
@@ -1474,7 +1491,7 @@ static int bnx2x_get_module_info(struct
 	int phy_idx, rc;
 	u8 sff8472_comp, diag_type;
 
-	if (!netif_running(dev)) {
+	if (!bnx2x_is_nvm_accessible(bp)) {
 		DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
 		   "cannot access eeprom when the interface is down\n");
 		return -EAGAIN;
@@ -1594,8 +1611,10 @@ static int bnx2x_nvram_write1(struct bnx
 		 */
 		val = be32_to_cpu(val_be);
 
-		val &= ~le32_to_cpu(0xff << BYTE_OFFSET(offset));
-		val |= le32_to_cpu(*data_buf << BYTE_OFFSET(offset));
+		val &= ~le32_to_cpu((__force __le32)
+				    (0xff << BYTE_OFFSET(offset)));
+		val |= le32_to_cpu((__force __le32)
+				   (*data_buf << BYTE_OFFSET(offset)));
 
 		rc = bnx2x_nvram_write_dword(bp, align_offset, val,
 					     cmd_flags);
@@ -1676,7 +1695,8 @@ static int bnx2x_set_eeprom(struct net_d
 	int port = BP_PORT(bp);
 	int rc = 0;
 	u32 ext_phy_config;
-	if (!netif_running(dev)) {
+
+	if (!bnx2x_is_nvm_accessible(bp)) {
 		DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
 		   "cannot access eeprom when the interface is down\n");
 		return -EAGAIN;
@@ -1921,6 +1941,19 @@ static const char bnx2x_tests_str_arr[BN
 	"link_test (online)         "
 };
 
+enum {
+	BNX2X_PRI_FLAG_ISCSI,
+	BNX2X_PRI_FLAG_FCOE,
+	BNX2X_PRI_FLAG_STORAGE,
+	BNX2X_PRI_FLAG_LEN,
+};
+
+static const char bnx2x_private_arr[BNX2X_PRI_FLAG_LEN][ETH_GSTRING_LEN] = {
+	"iSCSI offload support",
+	"FCoE offload support",
+	"Storage only interface"
+};
+
 static u32 bnx2x_eee_to_adv(u32 eee_adv)
 {
 	u32 modes = 0;
@@ -2041,7 +2074,7 @@ static int bnx2x_set_eee(struct net_devi
 				    EEE_MODE_OVERRIDE_NVRAM |
 				    EEE_MODE_OUTPUT_TIME;
 
-	/* Restart link to propogate changes */
+	/* Restart link to propagate changes */
 	if (netif_running(dev)) {
 		bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 		bnx2x_force_link_reset(bp);
@@ -2160,7 +2193,7 @@ static int bnx2x_test_registers(struct b
 		{ BNX2X_CHIP_MASK_ALL, 0xffffffff, 0, 0x00000000 }
 	};
 
-	if (!netif_running(bp->dev)) {
+	if (!bnx2x_is_nvm_accessible(bp)) {
 		DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
 		   "cannot access eeprom when the interface is down\n");
 		return rc;
@@ -2264,7 +2297,7 @@ static int bnx2x_test_memory(struct bnx2
 		{ NULL, 0xffffffff, {0, 0, 0, 0} }
 	};
 
-	if (!netif_running(bp->dev)) {
+	if (!bnx2x_is_nvm_accessible(bp)) {
 		DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
 		   "cannot access eeprom when the interface is down\n");
 		return rc;
@@ -2978,32 +3011,47 @@ static int bnx2x_num_stat_queues(struct
 static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	int i, num_stats;
+	int i, num_strings = 0;
 
 	switch (stringset) {
 	case ETH_SS_STATS:
 		if (is_multi(bp)) {
-			num_stats = bnx2x_num_stat_queues(bp) *
-						BNX2X_NUM_Q_STATS;
+			num_strings = bnx2x_num_stat_queues(bp) *
+				      BNX2X_NUM_Q_STATS;
 		} else
-			num_stats = 0;
+			num_strings = 0;
 		if (IS_MF_MODE_STAT(bp)) {
 			for (i = 0; i < BNX2X_NUM_STATS; i++)
 				if (IS_FUNC_STAT(i))
-					num_stats++;
+					num_strings++;
 		} else
-			num_stats += BNX2X_NUM_STATS;
+			num_strings += BNX2X_NUM_STATS;
 
-		return num_stats;
+		return num_strings;
 
 	case ETH_SS_TEST:
 		return BNX2X_NUM_TESTS(bp);
 
+	case ETH_SS_PRIV_FLAGS:
+		return BNX2X_PRI_FLAG_LEN;
+
 	default:
 		return -EINVAL;
 	}
 }
 
+static u32 bnx2x_get_private_flags(struct net_device *dev)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	u32 flags = 0;
+
+	flags |= (!(bp->flags & NO_ISCSI_FLAG) ? 1 : 0) << BNX2X_PRI_FLAG_ISCSI;
+	flags |= (!(bp->flags & NO_FCOE_FLAG)  ? 1 : 0) << BNX2X_PRI_FLAG_FCOE;
+	flags |= (!!IS_MF_STORAGE_ONLY(bp)) << BNX2X_PRI_FLAG_STORAGE;
+
+	return flags;
+}
+
 static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 {
 	struct bnx2x *bp = netdev_priv(dev);
@@ -3026,7 +3074,6 @@ static void bnx2x_get_strings(struct net
 			}
 		}
 
-
 		for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
 			if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i))
 				continue;
@@ -3045,6 +3092,12 @@ static void bnx2x_get_strings(struct net
 			start = 4;
 		memcpy(buf, bnx2x_tests_str_arr + start,
 		       ETH_GSTRING_LEN * BNX2X_NUM_TESTS(bp));
+		break;
+
+	case ETH_SS_PRIV_FLAGS:
+		memcpy(buf, bnx2x_private_arr,
+		       ETH_GSTRING_LEN * BNX2X_PRI_FLAG_LEN);
+		break;
 	}
 }
 
@@ -3106,17 +3159,12 @@ static int bnx2x_set_phys_id(struct net_
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
-	if (!netif_running(dev)) {
+	if (!bnx2x_is_nvm_accessible(bp)) {
 		DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
 		   "cannot access eeprom when the interface is down\n");
 		return -EAGAIN;
 	}
 
-	if (!bp->port.pmf) {
-		DP(BNX2X_MSG_ETHTOOL, "Interface is not pmf\n");
-		return -EOPNOTSUPP;
-	}
-
 	switch (state) {
 	case ETHTOOL_ID_ACTIVE:
 		return 1;	/* cycle on/off once per second */
@@ -3148,7 +3196,6 @@ static int bnx2x_set_phys_id(struct net_
 
 static int bnx2x_get_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info)
 {
-
 	switch (info->flow_type) {
 	case TCP_V4_FLOW:
 	case TCP_V6_FLOW:
@@ -3384,7 +3431,6 @@ static int bnx2x_set_channels(struct net
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
-
 	DP(BNX2X_MSG_ETHTOOL,
 	   "set-channels command parameters: rx = %d, tx = %d, other = %d, combined = %d\n",
 	   channels->rx_count, channels->tx_count, channels->other_count,
@@ -3445,6 +3491,7 @@ static const struct ethtool_ops bnx2x_et
 	.set_pauseparam		= bnx2x_set_pauseparam,
 	.self_test		= bnx2x_self_test,
 	.get_sset_count		= bnx2x_get_sset_count,
+	.get_priv_flags		= bnx2x_get_private_flags,
 	.get_strings		= bnx2x_get_strings,
 	.set_phys_id		= bnx2x_set_phys_id,
 	.get_ethtool_stats	= bnx2x_get_ethtool_stats,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h	2013-08-25 20:43:22.000000000 -0400
@@ -34,12 +34,10 @@
 #define BCM_DCBNL
 #endif
 
-
 #include "bnx2x_hsi.h"
 
 #include "../cnic_if.h"
 
-
 #define BNX2X_MIN_MSIX_VEC_CNT(bp)		((bp)->min_msix_vec_cnt)
 
 #include <linux/mdio.h>
@@ -114,7 +112,6 @@ do {								\
 #define BNX2X_ERROR(fmt, ...)					\
 	pr_err("[%s:%d]" fmt, __func__, __LINE__, ##__VA_ARGS__)
 
-
 /* before we have a dev->name use dev_info() */
 #define BNX2X_DEV_INFO(fmt, ...)				 \
 do {								 \
@@ -147,7 +144,6 @@ do {						\
 #define U64_HI(x)			((u32)(((u64)(x)) >> 32))
 #define HILO_U64(hi, lo)		((((u64)(hi)) << 32) + (lo))
 
-
 #define REG_ADDR(bp, offset)		((bp->regview) + (offset))
 
 #define REG_RD(bp, offset)		readl(REG_ADDR(bp, offset))
@@ -366,7 +362,7 @@ union db_prod {
 /*
  * Number of required  SGEs is the sum of two:
  * 1. Number of possible opened aggregations (next packet for
- *    these aggregations will probably consume SGE immidiatelly)
+ *    these aggregations will probably consume SGE immediately)
  * 2. Rest of BRB blocks divided by 2 (block will consume new SGE only
  *    after placement on BD for new TPA aggregation)
  *
@@ -387,7 +383,6 @@ union db_prod {
 #define BIT_VEC64_ELEM_SHIFT		6
 #define BIT_VEC64_ELEM_MASK		((u64)BIT_VEC64_ELEM_SZ - 1)
 
-
 #define __BIT_VEC64_SET_BIT(el, bit) \
 	do { \
 		el = ((el) | ((u64)0x1 << (bit))); \
@@ -398,7 +393,6 @@ union db_prod {
 		el = ((el) & (~((u64)0x1 << (bit)))); \
 	} while (0)
 
-
 #define BIT_VEC64_SET_BIT(vec64, idx) \
 	__BIT_VEC64_SET_BIT((vec64)[(idx) >> BIT_VEC64_ELEM_SHIFT], \
 			   (idx) & BIT_VEC64_ELEM_MASK)
@@ -419,8 +413,6 @@ union db_prod {
 
 /*******************************************************/
 
-
-
 /* Number of u64 elements in SGE mask array */
 #define RX_SGE_MASK_LEN			(NUM_RX_SGE / BIT_VEC64_ELEM_SZ)
 #define RX_SGE_MASK_LEN_MASK		(RX_SGE_MASK_LEN - 1)
@@ -493,11 +485,26 @@ struct bnx2x_fastpath {
 	struct bnx2x		*bp; /* parent */
 
 	struct napi_struct	napi;
+
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	unsigned int state;
+#define BNX2X_FP_STATE_IDLE		      0
+#define BNX2X_FP_STATE_NAPI		(1 << 0)    /* NAPI owns this FP */
+#define BNX2X_FP_STATE_POLL		(1 << 1)    /* poll owns this FP */
+#define BNX2X_FP_STATE_NAPI_YIELD	(1 << 2)    /* NAPI yielded this FP */
+#define BNX2X_FP_STATE_POLL_YIELD	(1 << 3)    /* poll yielded this FP */
+#define BNX2X_FP_YIELD	(BNX2X_FP_STATE_NAPI_YIELD | BNX2X_FP_STATE_POLL_YIELD)
+#define BNX2X_FP_LOCKED	(BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
+#define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)
+	/* protect state */
+	spinlock_t lock;
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
 	union host_hc_status_block	status_blk;
-	/* chip independed shortcuts into sb structure */
+	/* chip independent shortcuts into sb structure */
 	__le16			*sb_index_values;
 	__le16			*sb_running_index;
-	/* chip independed shortcut into rx_prods_offset memory */
+	/* chip independent shortcut into rx_prods_offset memory */
 	u32			ustorm_rx_prods_offset;
 
 	u32			rx_buf_size;
@@ -565,6 +572,116 @@ struct bnx2x_fastpath {
 #define bnx2x_fp_stats(bp, fp)	(&((bp)->fp_stats[(fp)->index]))
 #define bnx2x_fp_qstats(bp, fp)	(&((bp)->fp_stats[(fp)->index].eth_q_stats))
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
+{
+	spin_lock_init(&fp->lock);
+	fp->state = BNX2X_FP_STATE_IDLE;
+}
+
+/* called from the device poll routine to get ownership of a FP */
+static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
+{
+	bool rc = true;
+
+	spin_lock(&fp->lock);
+	if (fp->state & BNX2X_FP_LOCKED) {
+		WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
+		fp->state |= BNX2X_FP_STATE_NAPI_YIELD;
+		rc = false;
+	} else {
+		/* we don't care if someone yielded */
+		fp->state = BNX2X_FP_STATE_NAPI;
+	}
+	spin_unlock(&fp->lock);
+	return rc;
+}
+
+/* returns true is someone tried to get the FP while napi had it */
+static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
+{
+	bool rc = false;
+
+	spin_lock(&fp->lock);
+	WARN_ON(fp->state &
+		(BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD));
+
+	if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
+		rc = true;
+	fp->state = BNX2X_FP_STATE_IDLE;
+	spin_unlock(&fp->lock);
+	return rc;
+}
+
+/* called from bnx2x_low_latency_poll() */
+static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
+{
+	bool rc = true;
+
+	spin_lock_bh(&fp->lock);
+	if ((fp->state & BNX2X_FP_LOCKED)) {
+		fp->state |= BNX2X_FP_STATE_POLL_YIELD;
+		rc = false;
+	} else {
+		/* preserve yield marks */
+		fp->state |= BNX2X_FP_STATE_POLL;
+	}
+	spin_unlock_bh(&fp->lock);
+	return rc;
+}
+
+/* returns true if someone tried to get the FP while it was locked */
+static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
+{
+	bool rc = false;
+
+	spin_lock_bh(&fp->lock);
+	WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
+
+	if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
+		rc = true;
+	fp->state = BNX2X_FP_STATE_IDLE;
+	spin_unlock_bh(&fp->lock);
+	return rc;
+}
+
+/* true if a socket is polling, even if it did not get the lock */
+static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
+{
+	WARN_ON(!(fp->state & BNX2X_FP_LOCKED));
+	return fp->state & BNX2X_FP_USER_PEND;
+}
+#else
+static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
+{
+}
+
+static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
+{
+	return true;
+}
+
+static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
+{
+	return false;
+}
+
+static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
+{
+	return false;
+}
+
+static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
+{
+	return false;
+}
+
+static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
+{
+	return false;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
 /* Use 2500 as a mini-jumbo MTU for FCoE */
 #define BNX2X_FCOE_MINI_JUMBO_MTU	2500
 
@@ -580,12 +697,10 @@ struct bnx2x_fastpath {
 						txdata_ptr[FIRST_TX_COS_INDEX] \
 						->var)
 
-
 #define IS_ETH_FP(fp)		((fp)->index < BNX2X_NUM_ETH_QUEUES((fp)->bp))
 #define IS_FCOE_FP(fp)		((fp)->index == FCOE_IDX((fp)->bp))
 #define IS_FCOE_IDX(idx)	((idx) == FCOE_IDX(bp))
 
-
 /* MC hsi */
 #define MAX_FETCH_BD		13	/* HW max BDs per packet */
 #define RX_COPY_THRESH		92
@@ -613,7 +728,7 @@ struct bnx2x_fastpath {
  * START_BD(splitted)	- includes unpaged data segment for GSO
  * PARSING_BD		- for TSO and CSUM data
  * PARSING_BD2		- for encapsulation data
- * Frag BDs		- decribes pages for frags
+ * Frag BDs		- describes pages for frags
  */
 #define BDS_PER_TX_PKT		4
 #define MAX_BDS_PER_TX_PKT	(MAX_SKB_FRAGS + BDS_PER_TX_PKT)
@@ -693,12 +808,10 @@ struct bnx2x_fastpath {
 				 FW_DROP_LEVEL(bp))
 #define RCQ_TH_HI(bp)		(RCQ_TH_LO(bp) + DROPLESS_FC_HEADROOM)
 
-
 /* This is needed for determining of last_max */
 #define SUB_S16(a, b)		(s16)((s16)(a) - (s16)(b))
 #define SUB_S32(a, b)		(s32)((s32)(a) - (s32)(b))
 
-
 #define BNX2X_SWCID_SHIFT	17
 #define BNX2X_SWCID_MASK	((0x1 << BNX2X_SWCID_SHIFT) - 1)
 
@@ -723,7 +836,6 @@ struct bnx2x_fastpath {
 		       DPM_TRIGER_TYPE); \
 	} while (0)
 
-
 /* TX CSUM helpers */
 #define SKB_CS_OFF(skb)		(offsetof(struct tcphdr, check) - \
 				 skb->csum_offset)
@@ -766,7 +878,6 @@ struct bnx2x_fastpath {
 #define BNX2X_RX_SUM_FIX(cqe) \
 	BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags)
 
-
 #define FP_USB_FUNC_OFF	\
 			offsetof(struct cstorm_status_block_u, func)
 #define FP_CSB_FUNC_OFF	\
@@ -900,14 +1011,14 @@ struct bnx2x_common {
 #define CHIP_IS_E3A0(bp)		(CHIP_IS_E3(bp) && \
 					 (CHIP_REV(bp) == CHIP_REV_Ax))
 /* This define is used in two main places:
- * 1. In the early stages of nic_load, to know if to configrue Parser / Searcher
+ * 1. In the early stages of nic_load, to know if to configure Parser / Searcher
  * to nic-only mode or to offload mode. Offload mode is configured if either the
  * chip is E1x (where MIC_MODE register is not applicable), or if cnic already
  * registered for this port (which means that the user wants storage services).
  * 2. During cnic-related load, to know if offload mode is already configured in
- * the HW or needs to be configrued.
+ * the HW or needs to be configured.
  * Since the transition from nic-mode to offload-mode in HW causes traffic
- * coruption, nic-mode is configured only in ports on which storage services
+ * corruption, nic-mode is configured only in ports on which storage services
  * where never requested.
  */
 #define CONFIGURE_NIC_MODE(bp)		(!CHIP_IS_E1x(bp) && !CNIC_ENABLED(bp))
@@ -1008,14 +1119,14 @@ extern struct workqueue_struct *bnx2x_wq
  * If the maximum number of FP-SB available is X then:
  * a. If CNIC is supported it consumes 1 FP-SB thus the max number of
  *    regular L2 queues is Y=X-1
- * b. in MF mode the actual number of L2 queues is Y= (X-1/MF_factor)
+ * b. In MF mode the actual number of L2 queues is Y= (X-1/MF_factor)
  * c. If the FCoE L2 queue is supported the actual number of L2 queues
  *    is Y+1
  * d. The number of irqs (MSIX vectors) is either Y+1 (one extra for
  *    slow-path interrupts) or Y+2 if CNIC is supported (one additional
  *    FP interrupt context for the CNIC).
  * e. The number of HW context (CID count) is always X or X+1 if FCoE
- *    L2 queue is supported. the cid for the FCoE L2 queue is always X.
+ *    L2 queue is supported. The cid for the FCoE L2 queue is always X.
  */
 
 /* fast-path interrupt contexts E1x */
@@ -1068,7 +1179,6 @@ struct bnx2x_slowpath {
 		struct eth_classify_rules_ramrod_data	e2;
 	} mac_rdata;
 
-
 	union {
 		struct tstorm_eth_mac_filter_config	e1x;
 		struct eth_filter_rules_ramrod_data	e2;
@@ -1119,7 +1229,6 @@ struct bnx2x_slowpath {
 #define bnx2x_sp_mapping(bp, var) \
 		(bp->slowpath_mapping + offsetof(struct bnx2x_slowpath, var))
 
-
 /* attn group wiring */
 #define MAX_DYNAMIC_ATTN_GRPS		8
 
@@ -1221,11 +1330,13 @@ enum {
 	BNX2X_SP_RTNL_AFEX_F_UPDATE,
 	BNX2X_SP_RTNL_ENABLE_SRIOV,
 	BNX2X_SP_RTNL_VFPF_MCAST,
+	BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
 	BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
 	BNX2X_SP_RTNL_HYPERVISOR_VLAN,
+	BNX2X_SP_RTNL_TX_STOP,
+	BNX2X_SP_RTNL_TX_RESUME,
 };
 
-
 struct bnx2x_prev_path_list {
 	struct list_head list;
 	u8 bus;
@@ -1392,6 +1503,8 @@ struct bnx2x {
 #define USING_SINGLE_MSIX_FLAG		(1 << 20)
 #define BC_SUPPORTS_DCBX_MSG_NON_PMF	(1 << 21)
 #define IS_VF_FLAG			(1 << 22)
+#define INTERRUPTS_ENABLED_FLAG		(1 << 23)
+#define BC_SUPPORTS_RMMOD_CMD		(1 << 24)
 
 #define BP_NOMCP(bp)			((bp)->flags & NO_MCP_FLAG)
 
@@ -1585,7 +1698,7 @@ struct bnx2x {
 	struct mutex		cnic_mutex;
 	struct bnx2x_vlan_mac_obj iscsi_l2_mac_obj;
 
-	/* Start index of the "special" (CNIC related) L2 cleints */
+	/* Start index of the "special" (CNIC related) L2 clients */
 	u8				cnic_base_cl_id;
 
 	int			dmae_ready;
@@ -1699,7 +1812,7 @@ struct bnx2x {
 	/* operation indication for the sp_rtnl task */
 	unsigned long				sp_rtnl_state;
 
-	/* DCBX Negotation results */
+	/* DCBX Negotiation results */
 	struct dcbx_features			dcbx_local_feat;
 	u32					dcbx_error;
 
@@ -1720,6 +1833,8 @@ struct bnx2x {
 
 	int fp_array_size;
 	u32 dump_preset_idx;
+	bool					stats_started;
+	struct semaphore			stats_sema;
 };
 
 /* Tx queues may be less or equal to Rx queues */
@@ -1755,7 +1870,6 @@ extern int num_queues;
 #define FUNC_FLG_SPQ		0x0010
 #define FUNC_FLG_LEADING	0x0020	/* PF only */
 
-
 struct bnx2x_func_init_params {
 	/* dma */
 	dma_addr_t	fw_stat_map;	/* valid iff FUNC_FLG_STATS */
@@ -1853,9 +1967,6 @@ struct bnx2x_func_init_params {
 
 #define skip_queue(bp, idx)	(NO_FCOE(bp) && IS_FCOE_IDX(idx))
 
-
-
-
 /**
  * bnx2x_set_mac_one - configure a single MAC address
  *
@@ -1921,7 +2032,6 @@ u32 bnx2x_dmae_opcode(struct bnx2x *bp,
 void bnx2x_prep_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
 			       u8 src_type, u8 dst_type);
 int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae);
-void bnx2x_dp_dmae(struct bnx2x *bp, struct dmae_command *dmae, int msglvl);
 
 /* FLR related routines */
 u32 bnx2x_flr_clnup_poll_count(struct bnx2x *bp);
@@ -1937,6 +2047,8 @@ int bnx2x_sp_post(struct bnx2x *bp, int
 void bnx2x_update_coalesce(struct bnx2x *bp);
 int bnx2x_get_cur_phy_idx(struct bnx2x *bp);
 
+bool bnx2x_port_after_undi(struct bnx2x *bp);
+
 static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 			   int wait)
 {
@@ -1998,7 +2110,6 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x
 #define UNLOAD_CLOSE			1
 #define UNLOAD_RECOVERY			2
 
-
 /* DMAE command defines */
 #define DMAE_TIMEOUT			-1
 #define DMAE_PCI_ERROR			-2	/* E2 and onward */
@@ -2062,7 +2173,8 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x
 #define DMAE_LEN32_WR_MAX(bp)		(CHIP_IS_E1(bp) ? 0x400 : 0x2000)
 
 #define DMAE_COMP_VAL			0x60d0d0ae /* E2 and on - upper bit
-							indicates eror */
+						    * indicates error
+						    */
 
 #define MAX_DMAE_C_PER_PORT		8
 #define INIT_DMAE_C(bp)			(BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
@@ -2100,7 +2212,6 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x
 #define SP_DESC_CNT		(BCM_PAGE_SIZE / sizeof(struct eth_spe))
 #define MAX_SP_DESC_CNT			(SP_DESC_CNT - 1)
 
-
 #define BNX2X_BTR			4
 #define MAX_SPQ_PENDING			8
 
@@ -2137,6 +2248,8 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x
 #define ATTN_HARD_WIRED_MASK		0xff00
 #define ATTENTION_ID			4
 
+#define IS_MF_STORAGE_ONLY(bp) (IS_MF_STORAGE_SD(bp) || \
+				 IS_MF_FCOE_AFEX(bp))
 
 /* stuff added to make the code fit 80Col */
 
@@ -2338,4 +2451,11 @@ enum {
 
 #define NUM_MACS	8
 
+enum bnx2x_pci_bus_speed {
+	BNX2X_PCI_LINK_SPEED_2500 = 2500,
+	BNX2X_PCI_LINK_SPEED_5000 = 5000,
+	BNX2X_PCI_LINK_SPEED_8000 = 8000
+};
+
+void bnx2x_set_local_cmng(struct bnx2x *bp);
 #endif /* bnx2x.h */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h	2013-07-01 10:36:26.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h	2013-08-31 17:55:59.000000000 -0400
@@ -1300,6 +1300,9 @@ struct drv_func_mb {
 
 	#define DRV_MSG_CODE_EEE_RESULTS_ACK            0xda000000
 
+	#define DRV_MSG_CODE_RMMOD                      0xdb000000
+	#define REQ_BC_VER_4_RMMOD_CMD                  0x0007080f
+
 	#define DRV_MSG_CODE_SET_MF_BW                  0xe0000000
 	#define REQ_BC_VER_4_SET_MF_BW                  0x00060202
 	#define DRV_MSG_CODE_SET_MF_BW_ACK              0xe1000000
@@ -1323,6 +1326,8 @@ struct drv_func_mb {
 	#define DRV_MSG_CODE_UNLOAD_SKIP_LINK_RESET     0x00000002
 
 	#define DRV_MSG_CODE_LOAD_REQ_WITH_LFA          0x0000100a
+	#define DRV_MSG_CODE_LOAD_REQ_FORCE_LFA         0x00002000
+
 	u32 fw_mb_header;
 	#define FW_MSG_CODE_MASK                        0xffff0000
 	#define FW_MSG_CODE_DRV_LOAD_COMMON             0x10100000
@@ -1370,6 +1375,8 @@ struct drv_func_mb {
 
 	#define FW_MSG_CODE_EEE_RESULS_ACK              0xda100000
 
+	#define FW_MSG_CODE_RMMOD_ACK                   0xdb100000
+
 	#define FW_MSG_CODE_SET_MF_BW_SENT              0xe0000000
 	#define FW_MSG_CODE_SET_MF_BW_DONE              0xe1000000
 
@@ -3812,7 +3819,8 @@ struct eth_fast_path_rx_cqe {
 	__le16 len_on_bd;
 	struct parsing_flags pars_flags;
 	union eth_sgl_or_raw_data sgl_or_raw_data;
-	__le32 reserved1[8];
+	__le32 reserved1[7];
+	u32 marker;
 };
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c	2013-07-01 10:36:22.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c	2013-08-31 17:55:54.000000000 -0400
@@ -90,7 +90,6 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 /*(DEBLOBBED)*/
 
-
 int num_queues;
 module_param(num_queues, int, 0);
 MODULE_PARM_DESC(num_queues,
@@ -100,8 +99,6 @@ static int disable_tpa;
 module_param(disable_tpa, int, 0);
 MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature");
 
-#define INT_MODE_INTx			1
-#define INT_MODE_MSI			2
 int int_mode;
 module_param(int_mode, int, 0);
 MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X "
@@ -119,8 +116,6 @@ static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, " Default debug msglevel");
 
-
-
 struct workqueue_struct *bnx2x_wq;
 
 struct bnx2x_mac_vals {
@@ -373,9 +368,11 @@ static u32 bnx2x_reg_rd_ind(struct bnx2x
 #define DMAE_DP_DST_PCI		"pci dst_addr [%x:%08x]"
 #define DMAE_DP_DST_NONE	"dst_addr [none]"
 
-void bnx2x_dp_dmae(struct bnx2x *bp, struct dmae_command *dmae, int msglvl)
+static void bnx2x_dp_dmae(struct bnx2x *bp,
+			  struct dmae_command *dmae, int msglvl)
 {
 	u32 src_type = dmae->opcode & DMAE_COMMAND_SRC;
+	int i;
 
 	switch (dmae->opcode & DMAE_COMMAND_DST) {
 	case DMAE_CMD_DST_PCI:
@@ -431,6 +428,10 @@ void bnx2x_dp_dmae(struct bnx2x *bp, str
 			   dmae->comp_val);
 		break;
 	}
+
+	for (i = 0; i < (sizeof(struct dmae_command)/4); i++)
+		DP(msglvl, "DMAE RAW [%02d]: 0x%08x\n",
+		   i, *(((u32 *)dmae) + i));
 }
 
 /* copy command into DMAE command memory and set DMAE command go */
@@ -505,8 +506,9 @@ int bnx2x_issue_dmae_with_comp(struct bn
 	int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 4000;
 	int rc = 0;
 
-	/*
-	 * Lock the dmae channel. Disable BHs to prevent a dead-lock
+	bnx2x_dp_dmae(bp, dmae, BNX2X_MSG_DMAE);
+
+	/* Lock the dmae channel. Disable BHs to prevent a dead-lock
 	 * as long as this code is called both from syscall context and
 	 * from ndo_set_rx_mode() flow that may be called from BH.
 	 */
@@ -545,6 +547,7 @@ unlock:
 void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
 		      u32 len32)
 {
+	int rc;
 	struct dmae_command dmae;
 
 	if (!bp->dmae_ready) {
@@ -568,11 +571,16 @@ void bnx2x_write_dmae(struct bnx2x *bp,
 	dmae.len = len32;
 
 	/* issue the command and wait for completion */
-	bnx2x_issue_dmae_with_comp(bp, &dmae);
+	rc = bnx2x_issue_dmae_with_comp(bp, &dmae);
+	if (rc) {
+		BNX2X_ERR("DMAE returned failure %d\n", rc);
+		bnx2x_panic();
+	}
 }
 
 void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
 {
+	int rc;
 	struct dmae_command dmae;
 
 	if (!bp->dmae_ready) {
@@ -600,7 +608,11 @@ void bnx2x_read_dmae(struct bnx2x *bp, u
 	dmae.len = len32;
 
 	/* issue the command and wait for completion */
-	bnx2x_issue_dmae_with_comp(bp, &dmae);
+	rc = bnx2x_issue_dmae_with_comp(bp, &dmae);
+	if (rc) {
+		BNX2X_ERR("DMAE returned failure %d\n", rc);
+		bnx2x_panic();
+	}
 }
 
 static void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
@@ -808,8 +820,8 @@ static void bnx2x_hc_int_disable(struct
 	u32 val = REG_RD(bp, addr);
 
 	/* in E1 we must use only PCI configuration space to disable
-	 * MSI/MSIX capablility
-	 * It's forbitten to disable IGU_PF_CONF_MSI_MSIX_EN in HC block
+	 * MSI/MSIX capability
+	 * It's forbidden to disable IGU_PF_CONF_MSI_MSIX_EN in HC block
 	 */
 	if (CHIP_IS_E1(bp)) {
 		/* Since IGU_PF_CONF_MSI_MSIX_EN still always on
@@ -836,7 +848,7 @@ static void bnx2x_hc_int_disable(struct
 
 	REG_WR(bp, addr, val);
 	if (REG_RD(bp, addr) != val)
-		BNX2X_ERR("BUG! proper val not read from IGU!\n");
+		BNX2X_ERR("BUG! Proper val not read from IGU!\n");
 }
 
 static void bnx2x_igu_int_disable(struct bnx2x *bp)
@@ -854,7 +866,7 @@ static void bnx2x_igu_int_disable(struct
 
 	REG_WR(bp, IGU_REG_PF_CONFIGURATION, val);
 	if (REG_RD(bp, IGU_REG_PF_CONFIGURATION) != val)
-		BNX2X_ERR("BUG! proper val not read from IGU!\n");
+		BNX2X_ERR("BUG! Proper val not read from IGU!\n");
 }
 
 static void bnx2x_int_disable(struct bnx2x *bp)
@@ -914,7 +926,6 @@ void bnx2x_panic_dump(struct bnx2x *bp,
 	       sp_sb_data.p_func.vf_valid,
 	       sp_sb_data.state);
 
-
 	for_each_eth_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 		int loop;
@@ -1013,7 +1024,7 @@ void bnx2x_panic_dump(struct bnx2x *bp,
 				hc_sm_p[j].timer_value);
 		}
 
-		/* Indecies data */
+		/* Indices data */
 		for (j = 0; j < loop; j++) {
 			pr_cont("INDEX[%d] flags (0x%x) timeout (0x%x)\n", j,
 			       hc_index_p[j].flags,
@@ -1024,6 +1035,7 @@ void bnx2x_panic_dump(struct bnx2x *bp,
 #ifdef BNX2X_STOP_ON_ERROR
 
 	/* event queue */
+	BNX2X_ERR("eq cons %x prod %x\n", bp->eq_cons, bp->eq_prod);
 	for (i = 0; i < NUM_EQ_DESC; i++) {
 		u32 *data = (u32 *)&bp->eq_ring[i].message.data;
 
@@ -1108,7 +1120,7 @@ void bnx2x_panic_dump(struct bnx2x *bp,
  * bnx2x_pf_flr_clnup() is called during nic_load in the per function HW
  * initialization.
  */
-#define FLR_WAIT_USEC		10000	/* 10 miliseconds */
+#define FLR_WAIT_USEC		10000	/* 10 milliseconds */
 #define FLR_WAIT_INTERVAL	50	/* usec */
 #define	FLR_POLL_CNT		(FLR_WAIT_USEC/FLR_WAIT_INTERVAL) /* 200 */
 
@@ -1287,7 +1299,6 @@ void bnx2x_tx_hw_flushed(struct bnx2x *b
 	for (i = 0; i < ARRAY_SIZE(cmd_regs); i++)
 		bnx2x_pbf_pN_cmd_flushed(bp, &cmd_regs[i], poll_count);
 
-
 	/* Verify the transmission buffers are flushed P0, P1, P4 */
 	for (i = 0; i < ARRAY_SIZE(buf_regs); i++)
 		bnx2x_pbf_pN_buf_flushed(bp, &buf_regs[i], poll_count);
@@ -1302,11 +1313,9 @@ void bnx2x_tx_hw_flushed(struct bnx2x *b
 #define OP_GEN_AGG_VECT(index) \
 	(((index) << SDM_OP_GEN_AGG_VECT_IDX_SHIFT) & SDM_OP_GEN_AGG_VECT_IDX)
 
-
 int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func, u32 poll_cnt)
 {
 	u32 op_gen_command = 0;
-
 	u32 comp_addr = BAR_CSTRORM_INTMEM +
 			CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(clnup_func);
 	int ret = 0;
@@ -1331,7 +1340,7 @@ int bnx2x_send_final_clnup(struct bnx2x
 		bnx2x_panic();
 		return 1;
 	}
-	/* Zero completion for nxt FLR */
+	/* Zero completion for next FLR */
 	REG_WR(bp, comp_addr, 0);
 
 	return ret;
@@ -1349,7 +1358,6 @@ u8 bnx2x_is_pcie_pending(struct pci_dev
 */
 static int bnx2x_poll_hw_usage_counters(struct bnx2x *bp, u32 poll_cnt)
 {
-
 	/* wait for CFC PF usage-counter to zero (includes all the VFs) */
 	if (bnx2x_flr_clnup_poll_hw_counter(bp,
 			CFC_REG_NUM_LCIDS_INSIDE_PF,
@@ -1357,7 +1365,6 @@ static int bnx2x_poll_hw_usage_counters(
 			poll_cnt))
 		return 1;
 
-
 	/* Wait for DQ PF usage-counter to zero (until DQ cleanup) */
 	if (bnx2x_flr_clnup_poll_hw_counter(bp,
 			DORQ_REG_PF_USAGE_CNT,
@@ -1387,7 +1394,7 @@ static int bnx2x_poll_hw_usage_counters(
 	/* Wait DMAE PF usage counter to zero */
 	if (bnx2x_flr_clnup_poll_hw_counter(bp,
 			dmae_reg_go_c[INIT_DMAE_C(bp)],
-			"DMAE dommand register timed out",
+			"DMAE command register timed out",
 			poll_cnt))
 		return 1;
 
@@ -1767,7 +1774,7 @@ void bnx2x_sp_event(struct bnx2x_fastpat
 		break;
 
 	case (RAMROD_CMD_ID_ETH_TERMINATE):
-		DP(BNX2X_MSG_SP, "got MULTI[%d] teminate ramrod\n", cid);
+		DP(BNX2X_MSG_SP, "got MULTI[%d] terminate ramrod\n", cid);
 		drv_cmd = BNX2X_Q_CMD_TERMINATE;
 		break;
 
@@ -1856,7 +1863,6 @@ irqreturn_t bnx2x_interrupt(int irq, voi
 		mask = 0x2 << (fp->index + CNIC_SUPPORT(bp));
 		if (status & mask) {
 			/* Handle Rx or Tx according to SB id */
-			prefetch(fp->rx_cons_sb);
 			for_each_cos_in_tx_queue(fp, cos)
 				prefetch(fp->txdata_ptr[cos]->tx_cons_sb);
 			prefetch(&fp->sb_running_index[SM_RX_ID]);
@@ -1944,7 +1950,7 @@ int bnx2x_acquire_hw_lock(struct bnx2x *
 		if (lock_status & resource_bit)
 			return 0;
 
-		msleep(5);
+		usleep_range(5000, 10000);
 	}
 	BNX2X_ERR("Timeout\n");
 	return -EAGAIN;
@@ -1979,8 +1985,8 @@ int bnx2x_release_hw_lock(struct bnx2x *
 	/* Validating that the resource is currently taken */
 	lock_status = REG_RD(bp, hw_lock_control_reg);
 	if (!(lock_status & resource_bit)) {
-		BNX2X_ERR("lock_status 0x%x resource_bit 0x%x. unlock was called but lock wasn't taken!\n",
-		   lock_status, resource_bit);
+		BNX2X_ERR("lock_status 0x%x resource_bit 0x%x. Unlock was called but lock wasn't taken!\n",
+			  lock_status, resource_bit);
 		return -EFAULT;
 	}
 
@@ -1988,7 +1994,6 @@ int bnx2x_release_hw_lock(struct bnx2x *
 	return 0;
 }
 
-
 int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port)
 {
 	/* The GPIO should be swapped if swap register is set and active */
@@ -2253,6 +2258,23 @@ static void bnx2x_set_requested_fc(struc
 		bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
 }
 
+static void bnx2x_init_dropless_fc(struct bnx2x *bp)
+{
+	u32 pause_enabled = 0;
+
+	if (!CHIP_IS_E1(bp) && bp->dropless_fc && bp->link_vars.link_up) {
+		if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+			pause_enabled = 1;
+
+		REG_WR(bp, BAR_USTRORM_INTMEM +
+			   USTORM_ETH_PAUSE_ENABLED_OFFSET(BP_PORT(bp)),
+		       pause_enabled);
+	}
+
+	DP(NETIF_MSG_IFUP | NETIF_MSG_LINK, "dropless_fc is %s\n",
+	   pause_enabled ? "enabled" : "disabled");
+}
+
 int bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
 {
 	int rc, cfx_idx = bnx2x_get_link_cfg_idx(bp);
@@ -2286,6 +2308,8 @@ int bnx2x_initial_phy_init(struct bnx2x
 
 		bnx2x_release_phy_lock(bp);
 
+		bnx2x_init_dropless_fc(bp);
+
 		bnx2x_calc_fc_adv(bp);
 
 		if (bp->link_vars.link_up) {
@@ -2307,6 +2331,8 @@ void bnx2x_link_set(struct bnx2x *bp)
 		bnx2x_phy_init(&bp->link_params, &bp->link_vars);
 		bnx2x_release_phy_lock(bp);
 
+		bnx2x_init_dropless_fc(bp);
+
 		bnx2x_calc_fc_adv(bp);
 	} else
 		BNX2X_ERR("Bootcode is missing - can not set link\n");
@@ -2344,14 +2370,13 @@ u8 bnx2x_link_test(struct bnx2x *bp, u8
 	return rc;
 }
 
-
 /* Calculates the sum of vn_min_rates.
    It's needed for further normalizing of the min_rates.
    Returns:
      sum of vn_min_rates.
        or
      0 - if all the min_rates are 0.
-     In the later case fainess algorithm should be deactivated.
+     In the later case fairness algorithm should be deactivated.
      If not all min_rates are zero then those that are zeroes will be set to 1.
  */
 static void bnx2x_calc_vn_min(struct bnx2x *bp,
@@ -2416,7 +2441,6 @@ static void bnx2x_calc_vn_max(struct bnx
 	input->vnic_max_rate[vn] = vn_max_rate;
 }
 
-
 static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp)
 {
 	if (CHIP_REV_IS_SLOW(bp))
@@ -2432,7 +2456,7 @@ void bnx2x_read_mf_cfg(struct bnx2x *bp)
 	int vn, n = (CHIP_MODE_IS_4_PORT(bp) ? 2 : 1);
 
 	if (BP_NOMCP(bp))
-		return; /* what should be the default bvalue in this case */
+		return; /* what should be the default value in this case */
 
 	/* For 2 port configuration the absolute function number formula
 	 * is:
@@ -2470,7 +2494,7 @@ static void bnx2x_cmng_fns_init(struct b
 
 	input.port_rate = bp->link_vars.line_speed;
 
-	if (cmng_type == CMNG_FNS_MINMAX) {
+	if (cmng_type == CMNG_FNS_MINMAX && input.port_rate) {
 		int vn;
 
 		/* read mf conf from shmem */
@@ -2527,6 +2551,21 @@ static void storm_memset_cmng(struct bnx
 	}
 }
 
+/* init cmng mode in HW according to local configuration */
+void bnx2x_set_local_cmng(struct bnx2x *bp)
+{
+	int cmng_fns = bnx2x_get_cmng_fns_mode(bp);
+
+	if (cmng_fns != CMNG_FNS_NONE) {
+		bnx2x_cmng_fns_init(bp, false, cmng_fns);
+		storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp));
+	} else {
+		/* rate shaping and fairness are disabled */
+		DP(NETIF_MSG_IFUP,
+		   "single function mode without fairness\n");
+	}
+}
+
 /* This function is called upon link interrupt */
 static void bnx2x_link_attn(struct bnx2x *bp)
 {
@@ -2535,20 +2574,9 @@ static void bnx2x_link_attn(struct bnx2x
 
 	bnx2x_link_update(&bp->link_params, &bp->link_vars);
 
-	if (bp->link_vars.link_up) {
-
-		/* dropless flow control */
-		if (!CHIP_IS_E1(bp) && bp->dropless_fc) {
-			int port = BP_PORT(bp);
-			u32 pause_enabled = 0;
-
-			if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
-				pause_enabled = 1;
+	bnx2x_init_dropless_fc(bp);
 
-			REG_WR(bp, BAR_USTRORM_INTMEM +
-			       USTORM_ETH_PAUSE_ENABLED_OFFSET(port),
-			       pause_enabled);
-		}
+	if (bp->link_vars.link_up) {
 
 		if (bp->link_vars.mac_type != MAC_TYPE_EMAC) {
 			struct host_port_stats *pstats;
@@ -2562,17 +2590,8 @@ static void bnx2x_link_attn(struct bnx2x
 			bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
 	}
 
-	if (bp->link_vars.link_up && bp->link_vars.line_speed) {
-		int cmng_fns = bnx2x_get_cmng_fns_mode(bp);
-
-		if (cmng_fns != CMNG_FNS_NONE) {
-			bnx2x_cmng_fns_init(bp, false, cmng_fns);
-			storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp));
-		} else
-			/* rate shaping and fairness are disabled */
-			DP(NETIF_MSG_IFUP,
-			   "single function mode without fairness\n");
-	}
+	if (bp->link_vars.link_up && bp->link_vars.line_speed)
+		bnx2x_set_local_cmng(bp);
 
 	__bnx2x_link_report(bp);
 
@@ -2898,7 +2917,6 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u
 	return rc;
 }
 
-
 static void storm_memset_func_cfg(struct bnx2x *bp,
 				 struct tstorm_eth_function_common_config *tcfg,
 				 u16 abs_fid)
@@ -2932,7 +2950,7 @@ void bnx2x_func_init(struct bnx2x *bp, s
 }
 
 /**
- * bnx2x_get_tx_only_flags - Return common flags
+ * bnx2x_get_common_flags - Return common flags
  *
  * @bp		device handle
  * @fp		queue handle
@@ -3003,7 +3021,6 @@ static unsigned long bnx2x_get_q_flags(s
 	if (IS_MF_AFEX(bp))
 		__set_bit(BNX2X_Q_FLG_SILENT_VLAN_REM, &flags);
 
-
 	return flags | bnx2x_get_common_flags(bp, fp, true);
 }
 
@@ -3079,7 +3096,7 @@ static void bnx2x_pf_rx_q_prep(struct bn
 	 * placed on the BD (not including paddings).
 	 */
 	rxq_init->buf_sz = fp->rx_buf_size - BNX2X_FW_RX_ALIGN_START -
-		BNX2X_FW_RX_ALIGN_END -	IP_HEADER_ALIGNMENT_PADDING;
+			   BNX2X_FW_RX_ALIGN_END - IP_HEADER_ALIGNMENT_PADDING;
 
 	rxq_init->cl_qzone_id = fp->cl_qzone_id;
 	rxq_init->tpa_agg_sz = tpa_agg_size;
@@ -3121,7 +3138,7 @@ static void bnx2x_pf_tx_q_prep(struct bn
 	txq_init->fw_sb_id = fp->fw_sb_id;
 
 	/*
-	 * set the tss leading client id for TX classfication ==
+	 * set the tss leading client id for TX classification ==
 	 * leading RSS client id
 	 */
 	txq_init->tss_leading_cl_id = bnx2x_fp(bp, 0, cl_id);
@@ -3193,7 +3210,6 @@ static void bnx2x_pf_init(struct bnx2x *
 	storm_memset_eq_data(bp, &eq_data, BP_FUNC(bp));
 }
 
-
 static void bnx2x_e1h_disable(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
@@ -3209,7 +3225,7 @@ static void bnx2x_e1h_enable(struct bnx2
 
 	REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
 
-	/* Tx queue should be only reenabled */
+	/* Tx queue should be only re-enabled */
 	netif_tx_wake_all_queues(bp->dev);
 
 	/*
@@ -3537,10 +3553,8 @@ static bool bnx2x_is_contextless_ramrod(
 		return true;
 	else
 		return false;
-
 }
 
-
 /**
  * bnx2x_sp_post - place a single command on an SP ring
  *
@@ -3605,14 +3619,13 @@ int bnx2x_sp_post(struct bnx2x *bp, int
 	/*
 	 * It's ok if the actual decrement is issued towards the memory
 	 * somewhere between the spin_lock and spin_unlock. Thus no
-	 * more explict memory barrier is needed.
+	 * more explicit memory barrier is needed.
 	 */
 	if (common)
 		atomic_dec(&bp->eq_spq_left);
 	else
 		atomic_dec(&bp->cq_spq_left);
 
-
 	DP(BNX2X_MSG_SP,
 	   "SPQE[%x] (%x:%x)  (cmd, common?) (%d,%d)  hw_cid %x  data (%x:%x) type(0x%x) left (CQ, EQ) (%x,%x)\n",
 	   bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping),
@@ -3634,15 +3647,14 @@ static int bnx2x_acquire_alr(struct bnx2
 
 	might_sleep();
 	for (j = 0; j < 1000; j++) {
-		val = (1UL << 31);
-		REG_WR(bp, GRCBASE_MCP + 0x9c, val);
-		val = REG_RD(bp, GRCBASE_MCP + 0x9c);
-		if (val & (1L << 31))
+		REG_WR(bp, MCP_REG_MCPR_ACCESS_LOCK, MCPR_ACCESS_LOCK_LOCK);
+		val = REG_RD(bp, MCP_REG_MCPR_ACCESS_LOCK);
+		if (val & MCPR_ACCESS_LOCK_LOCK)
 			break;
 
-		msleep(5);
+		usleep_range(5000, 10000);
 	}
-	if (!(val & (1L << 31))) {
+	if (!(val & MCPR_ACCESS_LOCK_LOCK)) {
 		BNX2X_ERR("Cannot acquire MCP access lock register\n");
 		rc = -EBUSY;
 	}
@@ -3653,7 +3665,7 @@ static int bnx2x_acquire_alr(struct bnx2
 /* release split MCP access lock register */
 static void bnx2x_release_alr(struct bnx2x *bp)
 {
-	REG_WR(bp, GRCBASE_MCP + 0x9c, 0);
+	REG_WR(bp, MCP_REG_MCPR_ACCESS_LOCK, 0);
 }
 
 #define BNX2X_DEF_SB_ATT_IDX	0x0001
@@ -3675,7 +3687,7 @@ static u16 bnx2x_update_dsb_idx(struct b
 		rc |= BNX2X_DEF_SB_IDX;
 	}
 
-	/* Do not reorder: indecies reading should complete before handling */
+	/* Do not reorder: indices reading should complete before handling */
 	barrier();
 	return rc;
 }
@@ -3824,8 +3836,7 @@ static void bnx2x_fan_failure(struct bnx
 	netdev_err(bp->dev, "Fan Failure on Network Controller has caused the driver to shutdown the card to prevent permanent damage.\n"
 			    "Please contact OEM Support for assistance\n");
 
-	/*
-	 * Schedule device reset (unload)
+	/* Schedule device reset (unload)
 	 * This is due to some boards consuming sufficient power when driver is
 	 * up to overheat if fan fails.
 	 */
@@ -3833,7 +3844,6 @@ static void bnx2x_fan_failure(struct bnx
 	set_bit(BNX2X_SP_RTNL_FAN_FAILURE, &bp->sp_rtnl_state);
 	smp_mb__after_clear_bit();
 	schedule_delayed_work(&bp->sp_rtnl_task, 0);
-
 }
 
 static void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
@@ -4103,7 +4113,7 @@ static void bnx2x_clear_reset_global(str
  */
 static bool bnx2x_reset_is_global(struct bnx2x *bp)
 {
-	u32 val	= REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
+	u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
 
 	DP(NETIF_MSG_HW, "GEN_REG_VAL=0x%08x\n", val);
 	return (val & BNX2X_GLOBAL_RESET_BIT) ? true : false;
@@ -4154,7 +4164,7 @@ void bnx2x_set_reset_in_progress(struct
  */
 bool bnx2x_reset_is_done(struct bnx2x *bp, int engine)
 {
-	u32 val	= REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
+	u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
 	u32 bit = engine ?
 		BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT;
 
@@ -4257,13 +4267,18 @@ static bool bnx2x_get_load_status(struct
 	return val != 0;
 }
 
+static void _print_parity(struct bnx2x *bp, u32 reg)
+{
+	pr_cont(" [0x%08x] ", REG_RD(bp, reg));
+}
+
 static void _print_next_block(int idx, const char *blk)
 {
 	pr_cont("%s%s", idx ? ", " : "", blk);
 }
 
-static int bnx2x_check_blocks_with_parity0(u32 sig, int par_num,
-					   bool print)
+static int bnx2x_check_blocks_with_parity0(struct bnx2x *bp, u32 sig,
+					    int par_num, bool print)
 {
 	int i = 0;
 	u32 cur_bit = 0;
@@ -4272,33 +4287,54 @@ static int bnx2x_check_blocks_with_parit
 		if (sig & cur_bit) {
 			switch (cur_bit) {
 			case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "BRB");
+					_print_parity(bp,
+						      BRB1_REG_BRB1_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "PARSER");
+					_print_parity(bp, PRS_REG_PRS_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "TSDM");
+					_print_parity(bp,
+						      TSDM_REG_TSDM_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++,
 							  "SEARCHER");
+					_print_parity(bp, SRC_REG_SRC_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "TCM");
+					_print_parity(bp,
+						      TCM_REG_TCM_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "TSEMI");
+					_print_parity(bp,
+						      TSEM_REG_TSEM_PRTY_STS_0);
+					_print_parity(bp,
+						      TSEM_REG_TSEM_PRTY_STS_1);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "XPB");
+					_print_parity(bp, GRCBASE_XPB +
+							  PB_REG_PB_PRTY_STS);
+				}
 				break;
 			}
 
@@ -4310,8 +4346,9 @@ static int bnx2x_check_blocks_with_parit
 	return par_num;
 }
 
-static int bnx2x_check_blocks_with_parity1(u32 sig, int par_num,
-					   bool *global, bool print)
+static int bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
+					    int par_num, bool *global,
+					    bool print)
 {
 	int i = 0;
 	u32 cur_bit = 0;
@@ -4320,37 +4357,66 @@ static int bnx2x_check_blocks_with_parit
 		if (sig & cur_bit) {
 			switch (cur_bit) {
 			case AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "PBF");
+					_print_parity(bp, PBF_REG_PBF_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "QM");
+					_print_parity(bp, QM_REG_QM_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "TM");
+					_print_parity(bp, TM_REG_TM_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "XSDM");
+					_print_parity(bp,
+						      XSDM_REG_XSDM_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "XCM");
+					_print_parity(bp, XCM_REG_XCM_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "XSEMI");
+					_print_parity(bp,
+						      XSEM_REG_XSEM_PRTY_STS_0);
+					_print_parity(bp,
+						      XSEM_REG_XSEM_PRTY_STS_1);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++,
 							  "DOORBELLQ");
+					_print_parity(bp,
+						      DORQ_REG_DORQ_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "NIG");
+					if (CHIP_IS_E1x(bp)) {
+						_print_parity(bp,
+							NIG_REG_NIG_PRTY_STS);
+					} else {
+						_print_parity(bp,
+							NIG_REG_NIG_PRTY_STS_0);
+						_print_parity(bp,
+							NIG_REG_NIG_PRTY_STS_1);
+					}
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR:
 				if (print)
@@ -4359,32 +4425,52 @@ static int bnx2x_check_blocks_with_parit
 				*global = true;
 				break;
 			case AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "DEBUG");
+					_print_parity(bp, DBG_REG_DBG_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "USDM");
+					_print_parity(bp,
+						      USDM_REG_USDM_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "UCM");
+					_print_parity(bp, UCM_REG_UCM_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "USEMI");
+					_print_parity(bp,
+						      USEM_REG_USEM_PRTY_STS_0);
+					_print_parity(bp,
+						      USEM_REG_USEM_PRTY_STS_1);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "UPB");
+					_print_parity(bp, GRCBASE_UPB +
+							  PB_REG_PB_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "CSDM");
+					_print_parity(bp,
+						      CSDM_REG_CSDM_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "CCM");
+					_print_parity(bp, CCM_REG_CCM_PRTY_STS);
+				}
 				break;
 			}
 
@@ -4396,8 +4482,8 @@ static int bnx2x_check_blocks_with_parit
 	return par_num;
 }
 
-static int bnx2x_check_blocks_with_parity2(u32 sig, int par_num,
-					   bool print)
+static int bnx2x_check_blocks_with_parity2(struct bnx2x *bp, u32 sig,
+					    int par_num, bool print)
 {
 	int i = 0;
 	u32 cur_bit = 0;
@@ -4406,12 +4492,23 @@ static int bnx2x_check_blocks_with_parit
 		if (sig & cur_bit) {
 			switch (cur_bit) {
 			case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "CSEMI");
+					_print_parity(bp,
+						      CSEM_REG_CSEM_PRTY_STS_0);
+					_print_parity(bp,
+						      CSEM_REG_CSEM_PRTY_STS_1);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "PXP");
+					_print_parity(bp, PXP_REG_PXP_PRTY_STS);
+					_print_parity(bp,
+						      PXP2_REG_PXP2_PRTY_STS_0);
+					_print_parity(bp,
+						      PXP2_REG_PXP2_PRTY_STS_1);
+				}
 				break;
 			case AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR:
 				if (print)
@@ -4419,24 +4516,42 @@ static int bnx2x_check_blocks_with_parit
 					"PXPPCICLOCKCLIENT");
 				break;
 			case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "CFC");
+					_print_parity(bp,
+						      CFC_REG_CFC_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "CDU");
+					_print_parity(bp, CDU_REG_CDU_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "DMAE");
+					_print_parity(bp,
+						      DMAE_REG_DMAE_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "IGU");
+					if (CHIP_IS_E1x(bp))
+						_print_parity(bp,
+							HC_REG_HC_PRTY_STS);
+					else
+						_print_parity(bp,
+							IGU_REG_IGU_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "MISC");
+					_print_parity(bp,
+						      MISC_REG_MISC_PRTY_STS);
+				}
 				break;
 			}
 
@@ -4490,8 +4605,8 @@ static int bnx2x_check_blocks_with_parit
 	return par_num;
 }
 
-static int bnx2x_check_blocks_with_parity4(u32 sig, int par_num,
-					   bool print)
+static int bnx2x_check_blocks_with_parity4(struct bnx2x *bp, u32 sig,
+					    int par_num, bool print)
 {
 	int i = 0;
 	u32 cur_bit = 0;
@@ -4500,12 +4615,18 @@ static int bnx2x_check_blocks_with_parit
 		if (sig & cur_bit) {
 			switch (cur_bit) {
 			case AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "PGLUE_B");
+					_print_parity(bp,
+						PGLUE_B_REG_PGLUE_B_PRTY_STS);
+				}
 				break;
 			case AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR:
-				if (print)
+				if (print) {
 					_print_next_block(par_num++, "ATC");
+					_print_parity(bp,
+						      ATC_REG_ATC_PRTY_STS);
+				}
 				break;
 			}
 
@@ -4536,15 +4657,15 @@ static bool bnx2x_parity_attn(struct bnx
 		if (print)
 			netdev_err(bp->dev,
 				   "Parity errors detected in blocks: ");
-		par_num = bnx2x_check_blocks_with_parity0(
+		par_num = bnx2x_check_blocks_with_parity0(bp,
 			sig[0] & HW_PRTY_ASSERT_SET_0, par_num, print);
-		par_num = bnx2x_check_blocks_with_parity1(
+		par_num = bnx2x_check_blocks_with_parity1(bp,
 			sig[1] & HW_PRTY_ASSERT_SET_1, par_num, global, print);
-		par_num = bnx2x_check_blocks_with_parity2(
+		par_num = bnx2x_check_blocks_with_parity2(bp,
 			sig[2] & HW_PRTY_ASSERT_SET_2, par_num, print);
 		par_num = bnx2x_check_blocks_with_parity3(
 			sig[3] & HW_PRTY_ASSERT_SET_3, par_num, global, print);
-		par_num = bnx2x_check_blocks_with_parity4(
+		par_num = bnx2x_check_blocks_with_parity4(bp,
 			sig[4] & HW_PRTY_ASSERT_SET_4, par_num, print);
 
 		if (print)
@@ -4588,7 +4709,6 @@ bool bnx2x_chk_parity_attn(struct bnx2x
 	return bnx2x_parity_attn(bp, global, print, attn.sig);
 }
 
-
 static void bnx2x_attn_int_deasserted4(struct bnx2x *bp, u32 attn)
 {
 	u32 val;
@@ -4640,7 +4760,6 @@ static void bnx2x_attn_int_deasserted4(s
 		(u32)(attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR |
 		    AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR)));
 	}
-
 }
 
 static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
@@ -4875,7 +4994,6 @@ static void bnx2x_handle_classification_
 		BNX2X_ERR("Failed to schedule new commands: %d\n", rc);
 	else if (rc > 0)
 		DP(BNX2X_MSG_SP, "Scheduled next pending commands...\n");
-
 }
 
 static void bnx2x_set_iscsi_eth_rx_mode(struct bnx2x *bp, bool start);
@@ -5006,7 +5124,7 @@ static void bnx2x_eq_int(struct bnx2x *b
 	hw_cons = le16_to_cpu(*bp->eq_cons_sb);
 
 	/* The hw_cos range is 1-255, 257 - the sw_cons range is 0-254, 256.
-	 * when we get the the next-page we nned to adjust so the loop
+	 * when we get the next-page we need to adjust so the loop
 	 * condition below will be met. The next element is the size of a
 	 * regular element and hence incrementing by 1
 	 */
@@ -5072,8 +5190,6 @@ static void bnx2x_eq_int(struct bnx2x *b
 			if (q_obj->complete_cmd(bp, q_obj, BNX2X_Q_CMD_CFC_DEL))
 				break;
 
-
-
 			goto next_spqe;
 
 		case EVENT_RING_OPCODE_STOP_TRAFFIC:
@@ -5215,7 +5331,7 @@ static void bnx2x_sp_task(struct work_st
 
 	DP(BNX2X_MSG_SP, "sp task invoked\n");
 
-	/* make sure the atomic interupt_occurred has been written */
+	/* make sure the atomic interrupt_occurred has been written */
 	smp_rmb();
 	if (atomic_read(&bp->interrupt_occurred)) {
 
@@ -5262,7 +5378,6 @@ static void bnx2x_sp_task(struct work_st
 		/* ack status block only if something was actually handled */
 		bnx2x_ack_sb(bp, bp->igu_dsb_id, ATTENTION_ID,
 			     le16_to_cpu(bp->def_att_idx), IGU_INT_ENABLE, 1);
-
 	}
 
 	/* must be called after the EQ processing (since eq leads to sriov
@@ -5313,7 +5428,6 @@ irqreturn_t bnx2x_msix_sp_int(int irq, v
 
 /* end of slow path */
 
-
 void bnx2x_drv_pulse(struct bnx2x *bp)
 {
 	SHMEM_WR(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb,
@@ -5357,7 +5471,7 @@ static void bnx2x_timer(unsigned long da
 
 	/* sample pf vf bulletin board for new posts from pf */
 	if (IS_VF(bp))
-		bnx2x_sample_bulletin(bp);
+		bnx2x_timer_sriov(bp);
 
 	mod_timer(&bp->timer, jiffies + bp->current_interval);
 }
@@ -5379,7 +5493,6 @@ static void bnx2x_fill(struct bnx2x *bp,
 	else
 		for (i = 0; i < len; i++)
 			REG_WR8(bp, addr + i, fill);
-
 }
 
 /* helper: writes FP SP data to FW - data_size in dwords */
@@ -5458,10 +5571,8 @@ static void bnx2x_zero_sp_sb(struct bnx2
 	bnx2x_fill(bp, BAR_CSTRORM_INTMEM +
 			CSTORM_SP_SYNC_BLOCK_OFFSET(func), 0,
 			CSTORM_SP_SYNC_BLOCK_SIZE);
-
 }
 
-
 static void bnx2x_setup_ndsb_state_machine(struct hc_status_block_sm *hc_sm,
 					   int igu_sb_id, int igu_seg_id)
 {
@@ -5471,7 +5582,6 @@ static void bnx2x_setup_ndsb_state_machi
 	hc_sm->time_to_expire = 0xFFFFFFFF;
 }
 
-
 /* allocates state machine ids. */
 static void bnx2x_map_sb_state_machines(struct hc_index_data *index_data)
 {
@@ -5697,7 +5807,7 @@ static void bnx2x_init_eq_ring(struct bn
 	bp->eq_cons = 0;
 	bp->eq_prod = NUM_EQ_DESC;
 	bp->eq_cons_sb = BNX2X_EQ_INDEX;
-	/* we want a warning message before it gets rought... */
+	/* we want a warning message before it gets wrought... */
 	atomic_set(&bp->eq_spq_left,
 		min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1);
 }
@@ -5781,7 +5891,7 @@ static int bnx2x_fill_accept_flags(struc
 
 		break;
 	case BNX2X_RX_MODE_PROMISC:
-		/* According to deffinition of SI mode, iface in promisc mode
+		/* According to definition of SI mode, iface in promisc mode
 		 * should receive matched and unmatched (in resolution of port)
 		 * unicast packets.
 		 */
@@ -5924,7 +6034,7 @@ static void bnx2x_init_eth_fp(struct bnx
 	/* init shortcut */
 	fp->ustorm_rx_prods_offset = bnx2x_rx_ustorm_prods_offset(fp);
 
-	/* Setup SB indicies */
+	/* Setup SB indices */
 	fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
 
 	/* Configure Queue State object */
@@ -5980,6 +6090,8 @@ static void bnx2x_init_tx_ring_one(struc
 				    BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
 	}
 
+	*txdata->tx_cons_sb = cpu_to_le16(0);
+
 	SET_FLAG(txdata->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1);
 	txdata->tx_db.data.zero_fill1 = 0;
 	txdata->tx_db.data.prod = 0;
@@ -5998,6 +6110,7 @@ static void bnx2x_init_tx_rings_cnic(str
 	for_each_tx_queue_cnic(bp, i)
 		bnx2x_init_tx_ring_one(bp->fp[i].txdata_ptr[0]);
 }
+
 static void bnx2x_init_tx_rings(struct bnx2x *bp)
 {
 	int i;
@@ -6040,11 +6153,6 @@ void bnx2x_pre_irq_nic_init(struct bnx2x
 	bnx2x_init_rx_rings(bp);
 	bnx2x_init_tx_rings(bp);
 
-	if (IS_VF(bp)) {
-		bnx2x_memset_stats(bp);
-		return;
-	}
-
 	if (IS_PF(bp)) {
 		/* Initialize MOD_ABS interrupts */
 		bnx2x_init_mod_abs_int(bp, &bp->link_vars, bp->common.chip_id,
@@ -6055,6 +6163,8 @@ void bnx2x_pre_irq_nic_init(struct bnx2x
 		bnx2x_init_def_sb(bp);
 		bnx2x_update_dsb_idx(bp);
 		bnx2x_init_sp_ring(bp);
+	} else {
+		bnx2x_memset_stats(bp);
 	}
 }
 
@@ -6233,7 +6343,7 @@ static int bnx2x_int_mem_test(struct bnx
 		if (val == 0x10)
 			break;
 
-		msleep(10);
+		usleep_range(10000, 20000);
 		count--;
 	}
 	if (val != 0x10) {
@@ -6248,7 +6358,7 @@ static int bnx2x_int_mem_test(struct bnx
 		if (val == 1)
 			break;
 
-		msleep(10);
+		usleep_range(10000, 20000);
 		count--;
 	}
 	if (val != 0x1) {
@@ -6289,7 +6399,7 @@ static int bnx2x_int_mem_test(struct bnx
 		if (val == 0xb0)
 			break;
 
-		msleep(10);
+		usleep_range(10000, 20000);
 		count--;
 	}
 	if (val != 0xb0) {
@@ -6678,7 +6788,7 @@ static int bnx2x_init_hw_common(struct b
  *		    stay set)
  *		f.  If this is VNIC 3 of a port then also init
  *		    first_timers_ilt_entry to zero and last_timers_ilt_entry
- *		    to the last enrty in the ILT.
+ *		    to the last entry in the ILT.
  *
  *	Notes:
  *	Currently the PF error in the PGLC is non recoverable.
@@ -6769,7 +6879,6 @@ static int bnx2x_init_hw_common(struct b
 
 	bnx2x_init_block(bp, BLOCK_QM, PHASE_COMMON);
 
-
 	/* QM queues pointers table */
 	bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET);
 
@@ -7010,7 +7119,6 @@ static int bnx2x_init_hw_port(struct bnx
 	u32 low, high;
 	u32 val;
 
-
 	DP(NETIF_MSG_HW, "starting port init  port %d\n", port);
 
 	REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
@@ -7075,7 +7183,6 @@ static int bnx2x_init_hw_port(struct bnx
 			    BRB1_REG_MAC_GUARANTIED_1 :
 			    BRB1_REG_MAC_GUARANTIED_0), 40);
 
-
 	bnx2x_init_block(bp, BLOCK_PRS, init_phase);
 	if (CHIP_IS_E3B0(bp)) {
 		if (IS_MF_AFEX(bp)) {
@@ -7147,8 +7254,8 @@ static int bnx2x_init_hw_port(struct bnx
 
 	bnx2x_init_block(bp, BLOCK_MISC_AEU, init_phase);
 	/* init aeu_mask_attn_func_0/1:
-	 *  - SF mode: bits 3-7 are masked. only bits 0-2 are in use
-	 *  - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
+	 *  - SF mode: bits 3-7 are masked. Only bits 0-2 are in use
+	 *  - MF mode: bit 3 is masked. Bits 0-2 are in use as in SF
 	 *             bits 4-7 are used for "per vn group attention" */
 	val = IS_MF(bp) ? 0xF7 : 0x7;
 	/* Enable DCBX attention for all but E1 */
@@ -7272,7 +7379,6 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x
 	while (!(REG_RD(bp, igu_addr_ack) & sb_bit) && --cnt)
 		msleep(20);
 
-
 	if (!(REG_RD(bp, igu_addr_ack) & sb_bit)) {
 		DP(NETIF_MSG_HW,
 		   "Unable to finish IGU cleanup: idu_sb_id %d offset %d bit %d (cnt %d)\n",
@@ -7292,7 +7398,6 @@ static void bnx2x_clear_func_ilt(struct
 		bnx2x_ilt_wr(bp, i, 0);
 }
 
-
 static void bnx2x_init_searcher(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
@@ -7328,7 +7433,6 @@ static int bnx2x_reset_nic_mode(struct b
 	int rc, i, port = BP_PORT(bp);
 	int vlan_en = 0, mac_en[NUM_MACS];
 
-
 	/* Close input from network */
 	if (bp->mf_mode == SINGLE_FUNCTION) {
 		bnx2x_set_rx_filter(&bp->link_params, 0);
@@ -7403,7 +7507,7 @@ int bnx2x_init_hw_func_cnic(struct bnx2x
 	bnx2x_ilt_init_op_cnic(bp, INITOP_SET);
 
 	if (CONFIGURE_NIC_MODE(bp)) {
-		/* Configrue searcher as part of function hw init */
+		/* Configure searcher as part of function hw init */
 		bnx2x_init_searcher(bp);
 
 		/* Reset NIC mode */
@@ -7476,8 +7580,7 @@ static int bnx2x_init_hw_func(struct bnx
 	} else {
 		/* Set NIC mode */
 		REG_WR(bp, PRS_REG_NIC_MODE, 1);
-		DP(NETIF_MSG_IFUP, "NIC MODE configrued\n");
-
+		DP(NETIF_MSG_IFUP, "NIC MODE configured\n");
 	}
 
 	if (!CHIP_IS_E1x(bp)) {
@@ -7674,7 +7777,7 @@ static int bnx2x_init_hw_func(struct bnx
 			}
 			bnx2x_igu_clear_sb(bp, bp->igu_dsb_id);
 
-			/* !!! these should become driver const once
+			/* !!! These should become driver const once
 			   rf-tool supports split-68 const */
 			REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_LSB, 0);
 			REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_MSB, 0);
@@ -7731,7 +7834,6 @@ static int bnx2x_init_hw_func(struct bnx
 	return 0;
 }
 
-
 void bnx2x_free_mem_cnic(struct bnx2x *bp)
 {
 	bnx2x_ilt_mem_op_cnic(bp, ILT_MEMOP_FREE);
@@ -7776,7 +7878,6 @@ void bnx2x_free_mem(struct bnx2x *bp)
 	bnx2x_iov_free_mem(bp);
 }
 
-
 int bnx2x_alloc_mem_cnic(struct bnx2x *bp)
 {
 	if (!CHIP_IS_E1x(bp))
@@ -7790,7 +7891,7 @@ int bnx2x_alloc_mem_cnic(struct bnx2x *b
 				       host_hc_status_block_e1x));
 
 	if (CONFIGURE_NIC_MODE(bp) && !bp->t2)
-		/* allocate searcher T2 table, as it wan't allocated before */
+		/* allocate searcher T2 table, as it wasn't allocated before */
 		BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ);
 
 	/* write address to which L5 should insert its values */
@@ -8065,7 +8166,6 @@ void bnx2x_ilt_set_info(struct bnx2x *bp
 		   ilt_client->page_size,
 		   ilt_client->flags,
 		   ilog2(ilt_client->page_size >> 12));
-
 	}
 
 	if (CNIC_SUPPORT(bp)) {
@@ -8121,7 +8221,6 @@ void bnx2x_ilt_set_info(struct bnx2x *bp
 static void bnx2x_pf_q_prep_init(struct bnx2x *bp,
 	struct bnx2x_fastpath *fp, struct bnx2x_queue_init_params *init_params)
 {
-
 	u8 cos;
 	int cxt_index, cxt_offset;
 
@@ -8130,7 +8229,7 @@ static void bnx2x_pf_q_prep_init(struct
 		__set_bit(BNX2X_Q_FLG_HC, &init_params->rx.flags);
 		__set_bit(BNX2X_Q_FLG_HC, &init_params->tx.flags);
 
-		/* If HC is supporterd, enable host coalescing in the transition
+		/* If HC is supported, enable host coalescing in the transition
 		 * to INIT state.
 		 */
 		__set_bit(BNX2X_Q_FLG_HC_EN, &init_params->rx.flags);
@@ -8202,7 +8301,6 @@ static int bnx2x_setup_tx_only(struct bn
 	return bnx2x_queue_state_change(bp, q_params);
 }
 
-
 /**
  * bnx2x_setup_queue - setup queue
  *
@@ -8251,7 +8349,6 @@ int bnx2x_setup_queue(struct bnx2x *bp,
 
 	DP(NETIF_MSG_IFUP, "init complete\n");
 
-
 	/* Now move the Queue to the SETUP state... */
 	memset(setup_params, 0, sizeof(*setup_params));
 
@@ -8312,7 +8409,6 @@ static int bnx2x_stop_queue(struct bnx2x
 	/* We want to wait for completion in this context */
 	__set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags);
 
-
 	/* close tx-only connections */
 	for (tx_index = FIRST_TX_ONLY_COS_INDEX;
 	     tx_index < fp->max_cos;
@@ -8366,7 +8462,6 @@ static int bnx2x_stop_queue(struct bnx2x
 	return bnx2x_queue_state_change(bp, &q_params);
 }
 
-
 static void bnx2x_reset_func(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
@@ -8419,7 +8514,7 @@ static void bnx2x_reset_func(struct bnx2
 		 * scan to complete
 		 */
 		for (i = 0; i < 200; i++) {
-			msleep(10);
+			usleep_range(10000, 20000);
 			if (!REG_RD(bp, TM_REG_LIN0_SCAN_ON + port*4))
 				break;
 		}
@@ -8620,14 +8715,14 @@ static int bnx2x_func_wait_started(struc
 
 	/*
 	 * (assumption: No Attention from MCP at this stage)
-	 * PMF probably in the middle of TXdisable/enable transaction
+	 * PMF probably in the middle of TX disable/enable transaction
 	 * 1. Sync IRS for default SB
-	 * 2. Sync SP queue - this guarantes us that attention handling started
-	 * 3. Wait, that TXdisable/enable transaction completes
+	 * 2. Sync SP queue - this guarantees us that attention handling started
+	 * 3. Wait, that TX disable/enable transaction completes
 	 *
-	 * 1+2 guranty that if DCBx attention was scheduled it already changed
-	 * pending bit of transaction from STARTED-->TX_STOPPED, if we alredy
-	 * received complettion for the transaction the state is TX_STOPPED.
+	 * 1+2 guarantee that if DCBx attention was scheduled it already changed
+	 * pending bit of transaction from STARTED-->TX_STOPPED, if we already
+	 * received completion for the transaction the state is TX_STOPPED.
 	 * State will return to STARTED after completion of TX_STOPPED-->STARTED
 	 * transaction.
 	 */
@@ -8657,7 +8752,7 @@ static int bnx2x_func_wait_started(struc
 		struct bnx2x_func_state_params func_params = {NULL};
 
 		DP(NETIF_MSG_IFDOWN,
-		   "Hmmm... unexpected function state! Forcing STARTED-->TX_ST0PPED-->STARTED\n");
+		   "Hmmm... Unexpected function state! Forcing STARTED-->TX_ST0PPED-->STARTED\n");
 
 		func_params.f_obj = &bp->func_obj;
 		__set_bit(RAMROD_DRV_CLR_ONLY,
@@ -8737,7 +8832,6 @@ void bnx2x_chip_cleanup(struct bnx2x *bp
 
 	bnx2x_iov_chip_cleanup(bp);
 
-
 	/*
 	 * Send the UNLOAD_REQUEST to the MCP. This will return if
 	 * this function should perform FUNC, PORT or COMMON HW
@@ -8747,7 +8841,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp
 
 	/*
 	 * (assumption: No Attention from MCP at this stage)
-	 * PMF probably in the middle of TXdisable/enable transaction
+	 * PMF probably in the middle of TX disable/enable transaction
 	 */
 	rc = bnx2x_func_wait_started(bp);
 	if (rc) {
@@ -8810,7 +8904,6 @@ unload_error:
 	if (rc)
 		BNX2X_ERR("HW_RESET failed\n");
 
-
 	/* Report UNLOAD_DONE to MCP */
 	bnx2x_send_unload_done(bp, keep_link);
 }
@@ -9176,7 +9269,6 @@ static int bnx2x_process_kill(struct bnx
 	if (!CHIP_IS_E1x(bp) && bnx2x_er_poll_igu_vq(bp))
 		return -EAGAIN;
 
-
 	/* TBD: Indicate that "process kill" is in progress to MCP */
 
 	/* Clear "unprepared" bit */
@@ -9364,7 +9456,7 @@ static void bnx2x_parity_recover(struct
 				 * the first leader that performs a
 				 * leader_reset() reset the global blocks in
 				 * order to clear global attentions. Otherwise
-				 * the the gates will remain closed for that
+				 * the gates will remain closed for that
 				 * engine.
 				 */
 				if (load_status ||
@@ -9477,14 +9569,12 @@ static void bnx2x_sp_rtnl_task(struct wo
 		return;
 	}
 
-	/* if stop on error is defined no recovery flows should be executed */
+	if (unlikely(bp->recovery_state != BNX2X_RECOVERY_DONE)) {
 #ifdef BNX2X_STOP_ON_ERROR
-	BNX2X_ERR("recovery flow called but STOP_ON_ERROR defined so reset not done to allow debug dump,\n"
-		  "you will need to reboot when done\n");
-	goto sp_rtnl_not_reset;
+		BNX2X_ERR("recovery flow called but STOP_ON_ERROR defined so reset not done to allow debug dump,\n"
+			  "you will need to reboot when done\n");
+		goto sp_rtnl_not_reset;
 #endif
-
-	if (unlikely(bp->recovery_state != BNX2X_RECOVERY_DONE)) {
 		/*
 		 * Clear all pending SP commands as we are going to reset the
 		 * function anyway.
@@ -9499,6 +9589,12 @@ static void bnx2x_sp_rtnl_task(struct wo
 	}
 
 	if (test_and_clear_bit(BNX2X_SP_RTNL_TX_TIMEOUT, &bp->sp_rtnl_state)) {
+#ifdef BNX2X_STOP_ON_ERROR
+		BNX2X_ERR("recovery flow called but STOP_ON_ERROR defined so reset not done to allow debug dump,\n"
+			  "you will need to reboot when done\n");
+		goto sp_rtnl_not_reset;
+#endif
+
 		/*
 		 * Clear all pending SP commands as we are going to reset the
 		 * function anyway.
@@ -9537,6 +9633,13 @@ sp_rtnl_not_reset:
 		   "sending set mcast vf pf channel message from rtnl sp-task\n");
 		bnx2x_vfpf_set_mcast(bp->dev);
 	}
+	if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
+			       &bp->sp_rtnl_state)){
+		if (!test_bit(__LINK_STATE_NOCARRIER, &bp->dev->state)) {
+			bnx2x_tx_disable(bp);
+			BNX2X_ERR("PF indicated channel is not servicable anymore. This means this VF device is no longer operational\n");
+		}
+	}
 
 	if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
 			       &bp->sp_rtnl_state)) {
@@ -9549,6 +9652,12 @@ sp_rtnl_not_reset:
 			       &bp->sp_rtnl_state))
 		bnx2x_pf_set_vfs_vlan(bp);
 
+	if (test_and_clear_bit(BNX2X_SP_RTNL_TX_STOP, &bp->sp_rtnl_state))
+		bnx2x_dcbx_stop_hw_tx(bp);
+
+	if (test_and_clear_bit(BNX2X_SP_RTNL_TX_RESUME, &bp->sp_rtnl_state))
+		bnx2x_dcbx_resume_hw_tx(bp);
+
 	/* work which needs rtnl lock not-taken (as it takes the lock itself and
 	 * can be called from other contexts as well)
 	 */
@@ -9644,7 +9753,6 @@ static void bnx2x_prev_unload_close_mac(
 			wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
 			REG_WR(bp, vals->bmac_addr, wb_data[0]);
 			REG_WR(bp, vals->bmac_addr + 0x4, wb_data[1]);
-
 		}
 		BNX2X_DEV_INFO("Disable emac Rx\n");
 		vals->emac_addr = NIG_REG_NIG_EMAC0_EN + BP_PORT(bp)*4;
@@ -9678,7 +9786,6 @@ static void bnx2x_prev_unload_close_mac(
 
 	if (mac_stopped)
 		msleep(20);
-
 }
 
 #define BNX2X_PREV_UNDI_PROD_ADDR(p) (BAR_TSTRORM_INTMEM + 0x1508 + ((p) << 4))
@@ -9777,6 +9884,21 @@ static bool bnx2x_prev_is_path_marked(st
 	return rc;
 }
 
+bool bnx2x_port_after_undi(struct bnx2x *bp)
+{
+	struct bnx2x_prev_path_list *entry;
+	bool val;
+
+	down(&bnx2x_prev_sem);
+
+	entry = bnx2x_prev_path_get_entry(bp);
+	val = !!(entry && (entry->undi & (1 << BP_PORT(bp))));
+
+	up(&bnx2x_prev_sem);
+
+	return val;
+}
+
 static int bnx2x_prev_mark_path(struct bnx2x *bp, bool after_undi)
 {
 	struct bnx2x_prev_path_list *tmp_list;
@@ -9836,7 +9958,6 @@ static int bnx2x_do_flr(struct bnx2x *bp
 	u16 status;
 	struct pci_dev *dev = bp->pdev;
 
-
 	if (CHIP_IS_E1x(bp)) {
 		BNX2X_DEV_INFO("FLR not supported in E1/E1H\n");
 		return -EINVAL;
@@ -9983,7 +10104,6 @@ static int bnx2x_prev_unload_common(stru
 
 		if (!timer_count)
 			BNX2X_ERR("Failed to empty BRB, hope for the best\n");
-
 	}
 
 	/* No packets are in the pipeline, path is ready for reset */
@@ -10033,7 +10153,6 @@ static int bnx2x_prev_unload(struct bnx2
 {
 	int time_counter = 10;
 	u32 rc, fw, hw_lock_reg, hw_lock_val;
-	struct bnx2x_prev_path_list *prev_list;
 	BNX2X_DEV_INFO("Entering Previous Unload Flow\n");
 
 	/* clear hw from errors which may have resulted from an interrupted
@@ -10046,7 +10165,7 @@ static int bnx2x_prev_unload(struct bnx2
 		      (MISC_REG_DRIVER_CONTROL_1 + BP_FUNC(bp) * 8) :
 		      (MISC_REG_DRIVER_CONTROL_7 + (BP_FUNC(bp) - 6) * 8);
 
-	hw_lock_val = (REG_RD(bp, hw_lock_reg));
+	hw_lock_val = REG_RD(bp, hw_lock_reg);
 	if (hw_lock_val) {
 		if (hw_lock_val & HW_LOCK_RESOURCE_NVRAM) {
 			BNX2X_DEV_INFO("Release Previously held NVRAM lock\n");
@@ -10061,7 +10180,7 @@ static int bnx2x_prev_unload(struct bnx2
 
 	if (MCPR_ACCESS_LOCK_LOCK & REG_RD(bp, MCP_REG_MCPR_ACCESS_LOCK)) {
 		BNX2X_DEV_INFO("Release previously held alr\n");
-		REG_WR(bp, MCP_REG_MCPR_ACCESS_LOCK, 0);
+		bnx2x_release_alr(bp);
 	}
 
 	do {
@@ -10090,7 +10209,7 @@ static int bnx2x_prev_unload(struct bnx2
 			break;
 		}
 
-		/* non-common reply from MCP night require looping */
+		/* non-common reply from MCP might require looping */
 		rc = bnx2x_prev_unload_uncommon(bp);
 		if (rc != BNX2X_PREV_WAIT_NEEDED)
 			break;
@@ -10104,8 +10223,7 @@ static int bnx2x_prev_unload(struct bnx2
 	}
 
 	/* Mark function if its port was used to boot from SAN */
-	prev_list = bnx2x_prev_path_get_entry(bp);
-	if (prev_list && (prev_list->undi & (1 << BP_PORT(bp))))
+	if (bnx2x_port_after_undi(bp))
 		bp->link_params.feature_config_flags |=
 			FEATURE_CONFIG_BOOT_FROM_SAN;
 
@@ -10189,8 +10307,6 @@ static void bnx2x_get_common_hwinfo(stru
 
 	bnx2x_init_shmem(bp);
 
-
-
 	bp->common.shmem2_base = REG_RD(bp, (BP_PATH(bp) ?
 					MISC_REG_GENERIC_CR_1 :
 					MISC_REG_GENERIC_CR_0));
@@ -10265,6 +10381,10 @@ static void bnx2x_get_common_hwinfo(stru
 
 	bp->flags |= (val >= REQ_BC_VER_4_DCBX_ADMIN_MSG_NON_PMF) ?
 			BC_SUPPORTS_DCBX_MSG_NON_PMF : 0;
+
+	bp->flags |= (val >= REQ_BC_VER_4_RMMOD_CMD) ?
+			BC_SUPPORTS_RMMOD_CMD : 0;
+
 	boot_mode = SHMEM_RD(bp,
 			dev_info.port_feature_config[BP_PORT(bp)].mba_config) &
 			PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK;
@@ -10452,6 +10572,9 @@ static void bnx2x_link_settings_supporte
 					PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
 			bp->port.supported[idx] &= ~SUPPORTED_10000baseT_Full;
 
+		if (!(bp->link_params.speed_cap_mask[idx] &
+					PORT_HW_CFG_SPEED_CAPABILITY_D0_20G))
+			bp->port.supported[idx] &= ~SUPPORTED_20000baseKR2_Full;
 	}
 
 	BNX2X_DEV_INFO("supported 0x%x 0x%x\n", bp->port.supported[0],
@@ -10762,7 +10885,6 @@ void bnx2x_get_iscsi_info(struct bnx2x *
 	 */
 	if (!bp->cnic_eth_dev.max_iscsi_conn)
 		bp->flags |= no_flags;
-
 }
 
 static void bnx2x_get_ext_wwn_info(struct bnx2x *bp, int func)
@@ -10779,12 +10901,56 @@ static void bnx2x_get_ext_wwn_info(struc
 	bp->cnic_eth_dev.fcoe_wwn_node_name_lo =
 		MF_CFG_RD(bp, func_ext_config[func].fcoe_wwn_node_name_lower);
 }
+
+static int bnx2x_shared_fcoe_funcs(struct bnx2x *bp)
+{
+	u8 count = 0;
+
+	if (IS_MF(bp)) {
+		u8 fid;
+
+		/* iterate over absolute function ids for this path: */
+		for (fid = BP_PATH(bp); fid < E2_FUNC_MAX * 2; fid += 2) {
+			if (IS_MF_SD(bp)) {
+				u32 cfg = MF_CFG_RD(bp,
+						    func_mf_config[fid].config);
+
+				if (!(cfg & FUNC_MF_CFG_FUNC_HIDE) &&
+				    ((cfg & FUNC_MF_CFG_PROTOCOL_MASK) ==
+					    FUNC_MF_CFG_PROTOCOL_FCOE))
+					count++;
+			} else {
+				u32 cfg = MF_CFG_RD(bp,
+						    func_ext_config[fid].
+								      func_cfg);
+
+				if ((cfg & MACP_FUNC_CFG_FLAGS_ENABLED) &&
+				    (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD))
+					count++;
+			}
+		}
+	} else { /* SF */
+		int port, port_cnt = CHIP_MODE_IS_4_PORT(bp) ? 2 : 1;
+
+		for (port = 0; port < port_cnt; port++) {
+			u32 lic = SHMEM_RD(bp,
+					   drv_lic_key[port].max_fcoe_conn) ^
+				  FW_ENCODE_32BIT_PATTERN;
+			if (lic)
+				count++;
+		}
+	}
+
+	return count;
+}
+
 static void bnx2x_get_fcoe_info(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
 	int func = BP_ABS_FUNC(bp);
 	u32 max_fcoe_conn = FW_ENCODE_32BIT_PATTERN ^ SHMEM_RD(bp,
 				drv_lic_key[port].max_fcoe_conn);
+	u8 num_fcoe_func = bnx2x_shared_fcoe_funcs(bp);
 
 	if (!CNIC_SUPPORT(bp)) {
 		bp->flags |= NO_FCOE_FLAG;
@@ -10798,9 +10964,10 @@ static void bnx2x_get_fcoe_info(struct b
 
 	/* Calculate the number of maximum allowed FCoE tasks */
 	bp->cnic_eth_dev.max_fcoe_exchanges = MAX_NUM_FCOE_TASKS_PER_ENGINE;
-	if (IS_MF(bp) || CHIP_MODE_IS_4_PORT(bp))
-		bp->cnic_eth_dev.max_fcoe_exchanges /=
-						MAX_FCOE_FUNCS_PER_ENGINE;
+
+	/* check if FCoE resources must be shared between different functions */
+	if (num_fcoe_func)
+		bp->cnic_eth_dev.max_fcoe_exchanges /= num_fcoe_func;
 
 	/* Read the WWN: */
 	if (!IS_MF(bp)) {
@@ -10993,6 +11160,9 @@ static bool bnx2x_get_dropless_info(stru
 	int tmp;
 	u32 cfg;
 
+	if (IS_VF(bp))
+		return 0;
+
 	if (IS_MF(bp) && !CHIP_IS_E1x(bp)) {
 		/* Take function: tmp = func */
 		tmp = BP_ABS_FUNC(bp);
@@ -11028,7 +11198,7 @@ static int bnx2x_get_hwinfo(struct bnx2x
 	} else {
 		bp->common.int_block = INT_BLOCK_IGU;
 
-		/* do not allow device reset during IGU info preocessing */
+		/* do not allow device reset during IGU info processing */
 		bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
 
 		val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION);
@@ -11107,7 +11277,7 @@ static int bnx2x_get_hwinfo(struct bnx2x
 				E1H_FUNC_MAX * sizeof(struct drv_func_mb);
 		/*
 		 * get mf configuration:
-		 * 1. existence of MF configuration
+		 * 1. Existence of MF configuration
 		 * 2. MAC address must be legal (check only upper bytes)
 		 *    for  Switch-Independent mode;
 		 *    OVLAN must be legal for Switch-Dependent mode
@@ -11380,7 +11550,7 @@ static int bnx2x_init_bp(struct bnx2x *b
 	mutex_init(&bp->port.phy_mutex);
 	mutex_init(&bp->fw_mb_mutex);
 	spin_lock_init(&bp->stats_lock);
-
+	sema_init(&bp->stats_sema, 1);
 
 	INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task);
 	INIT_DELAYED_WORK(&bp->sp_rtnl_task, bnx2x_sp_rtnl_task);
@@ -11390,7 +11560,7 @@ static int bnx2x_init_bp(struct bnx2x *b
 		if (rc)
 			return rc;
 	} else {
-		random_ether_addr(bp->dev->dev_addr);
+		eth_zero_addr(bp->dev->dev_addr);
 	}
 
 	bnx2x_set_modes_bitmap(bp);
@@ -11414,7 +11584,6 @@ static int bnx2x_init_bp(struct bnx2x *b
 		bnx2x_prev_unload(bp);
 	}
 
-
 	if (CHIP_REV_IS_FPGA(bp))
 		dev_err(&bp->pdev->dev, "FPGA detected\n");
 
@@ -11486,7 +11655,7 @@ static int bnx2x_init_bp(struct bnx2x *b
 
 	/* We need at least one default status block for slow-path events,
 	 * second status block for the L2 queue, and a third status block for
-	 * CNIC if supproted.
+	 * CNIC if supported.
 	 */
 	if (CNIC_SUPPORT(bp))
 		bp->min_msix_vec_cnt = 3;
@@ -11494,10 +11663,11 @@ static int bnx2x_init_bp(struct bnx2x *b
 		bp->min_msix_vec_cnt = 2;
 	BNX2X_DEV_INFO("bp->min_msix_vec_cnt %d", bp->min_msix_vec_cnt);
 
+	bp->dump_preset_idx = 1;
+
 	return rc;
 }
 
-
 /****************************************************************************
 * General service functions
 ****************************************************************************/
@@ -11582,9 +11752,6 @@ static int bnx2x_close(struct net_device
 	/* Unload the driver, release IRQs */
 	bnx2x_nic_unload(bp, UNLOAD_CLOSE, false);
 
-	/* Power off */
-	bnx2x_set_power_state(bp, PCI_D3hot);
-
 	return 0;
 }
 
@@ -11849,6 +12016,10 @@ static int bnx2x_validate_addr(struct ne
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
+	/* query the bulletin board for mac address configured by the PF */
+	if (IS_VF(bp))
+		bnx2x_sample_bulletin(bp);
+
 	if (!bnx2x_is_valid_ether_addr(bp, dev->dev_addr)) {
 		BNX2X_ERR("Non-valid Ethernet address\n");
 		return -EADDRNOTAVAIL;
@@ -11875,12 +12046,16 @@ static const struct net_device_ops bnx2x
 	.ndo_setup_tc		= bnx2x_setup_tc,
 #ifdef CONFIG_BNX2X_SRIOV
 	.ndo_set_vf_mac		= bnx2x_set_vf_mac,
-	.ndo_set_vf_vlan        = bnx2x_set_vf_vlan,
+	.ndo_set_vf_vlan	= bnx2x_set_vf_vlan,
 	.ndo_get_vf_config	= bnx2x_get_vf_config,
 #endif
 #ifdef NETDEV_FCOE_WWNN
 	.ndo_fcoe_get_wwn	= bnx2x_fcoe_get_wwn,
 #endif
+
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	.ndo_busy_poll		= bnx2x_low_latency_recv,
+#endif
 };
 
 static int bnx2x_set_coherency_mask(struct bnx2x *bp)
@@ -11956,7 +12131,7 @@ static int bnx2x_init_dev(struct bnx2x *
 	}
 
 	if (IS_PF(bp)) {
-		bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+		bp->pm_cap = pdev->pm_cap;
 		if (bp->pm_cap == 0) {
 			dev_err(&bp->pdev->dev,
 				"Cannot find power management capability, aborting\n");
@@ -12005,8 +12180,6 @@ static int bnx2x_init_dev(struct bnx2x *
 	}
 	BNX2X_DEV_INFO("me reg PF num: %d\n", bp->pf_num);
 
-	bnx2x_set_power_state(bp, PCI_D0);
-
 	/* clean indirect addresses */
 	pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
 			       PCICFG_VENDOR_ID_OFFSET);
@@ -12091,15 +12264,26 @@ err_out:
 	return rc;
 }
 
-static void bnx2x_get_pcie_width_speed(struct bnx2x *bp, int *width, int *speed)
+static void bnx2x_get_pcie_width_speed(struct bnx2x *bp, int *width,
+				       enum bnx2x_pci_bus_speed *speed)
 {
-	u32 val = 0;
+	u32 link_speed, val = 0;
 
 	pci_read_config_dword(bp->pdev, PCICFG_LINK_CONTROL, &val);
 	*width = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
 
-	/* return value of 1=2.5GHz 2=5GHz */
-	*speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
+	link_speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
+
+	switch (link_speed) {
+	case 3:
+		*speed = BNX2X_PCI_LINK_SPEED_8000;
+		break;
+	case 2:
+		*speed = BNX2X_PCI_LINK_SPEED_5000;
+		break;
+	default:
+		*speed = BNX2X_PCI_LINK_SPEED_2500;
+	}
 }
 
 /*(DEBLOBBED)*/
@@ -12266,7 +12450,6 @@ static void bnx2x_release_firmware(struc
 	bp->firmware = NULL;
 }
 
-
 static struct bnx2x_func_sp_drv_ops bnx2x_func_sp_drv = {
 	.init_hw_cmn_chip = bnx2x_init_hw_common_chip,
 	.init_hw_cmn      = bnx2x_init_hw_common,
@@ -12404,7 +12587,8 @@ static int bnx2x_init_one(struct pci_dev
 {
 	struct net_device *dev = NULL;
 	struct bnx2x *bp;
-	int pcie_width, pcie_speed;
+	int pcie_width;
+	enum bnx2x_pci_bus_speed pcie_speed;
 	int rc, max_non_def_sbs;
 	int rx_count, tx_count, rss_count, doorbell_size;
 	int max_cos_est;
@@ -12544,7 +12728,6 @@ static int bnx2x_init_one(struct pci_dev
 	}
 	BNX2X_DEV_INFO("device name after netdev register %s\n", dev->name);
 
-
 	if (!NO_FCOE(bp)) {
 		/* Add storage MAC address */
 		rtnl_lock();
@@ -12556,15 +12739,15 @@ static int bnx2x_init_one(struct pci_dev
 	BNX2X_DEV_INFO("got pcie width %d and speed %d\n",
 		       pcie_width, pcie_speed);
 
-	BNX2X_DEV_INFO(
-		"%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n",
-		    board_info[ent->driver_data].name,
-		    (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
-		    pcie_width,
-		    ((!CHIP_IS_E2(bp) && pcie_speed == 2) ||
-		     (CHIP_IS_E2(bp) && pcie_speed == 1)) ?
-		    "5GHz (Gen2)" : "2.5GHz",
-		    dev->base_addr, bp->pdev->irq, dev->dev_addr);
+	BNX2X_DEV_INFO("%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n",
+		       board_info[ent->driver_data].name,
+		       (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
+		       pcie_width,
+		       pcie_speed == BNX2X_PCI_LINK_SPEED_2500 ? "2.5GHz" :
+		       pcie_speed == BNX2X_PCI_LINK_SPEED_5000 ? "5.0GHz" :
+		       pcie_speed == BNX2X_PCI_LINK_SPEED_8000 ? "8.0GHz" :
+		       "Unknown",
+		       dev->base_addr, bp->pdev->irq, dev->dev_addr);
 
 	return 0;
 
@@ -12586,17 +12769,11 @@ init_one_exit:
 	return rc;
 }
 
-static void bnx2x_remove_one(struct pci_dev *pdev)
+static void __bnx2x_remove(struct pci_dev *pdev,
+			   struct net_device *dev,
+			   struct bnx2x *bp,
+			   bool remove_netdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct bnx2x *bp;
-
-	if (!dev) {
-		dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n");
-		return;
-	}
-	bp = netdev_priv(dev);
-
 	/* Delete storage MAC address */
 	if (!NO_FCOE(bp)) {
 		rtnl_lock();
@@ -12609,7 +12786,21 @@ static void bnx2x_remove_one(struct pci_
 	bnx2x_dcbnl_update_applist(bp, true);
 #endif
 
-	unregister_netdev(dev);
+	if (IS_PF(bp) &&
+	    !BP_NOMCP(bp) &&
+	    (bp->flags & BC_SUPPORTS_RMMOD_CMD))
+		bnx2x_fw_command(bp, DRV_MSG_CODE_RMMOD, 0);
+
+	/* Close the interface - either directly or implicitly */
+	if (remove_netdev) {
+		unregister_netdev(dev);
+	} else {
+		rtnl_lock();
+		dev_close(dev);
+		rtnl_unlock();
+	}
+
+	bnx2x_iov_remove_one(bp);
 
 	/* Power on: we can't let PCI layer write to us while we are in D3 */
 	if (IS_PF(bp))
@@ -12625,12 +12816,16 @@ static void bnx2x_remove_one(struct pci_
 	/* Make sure RESET task is not scheduled before continuing */
 	cancel_delayed_work_sync(&bp->sp_rtnl_task);
 
-	bnx2x_iov_remove_one(bp);
-
 	/* send message via vfpf channel to release the resources of this vf */
 	if (IS_VF(bp))
 		bnx2x_vfpf_release(bp);
 
+	/* Assumes no further PCIe PM changes will occur */
+	if (system_state == SYSTEM_POWER_OFF) {
+		pci_wake_from_d3(pdev, bp->wol);
+		pci_set_power_state(pdev, PCI_D3hot);
+	}
+
 	if (bp->regview)
 		iounmap(bp->regview);
 
@@ -12645,7 +12840,8 @@ static void bnx2x_remove_one(struct pci_
 	}
 	bnx2x_free_mem_bp(bp);
 
-	free_netdev(dev);
+	if (remove_netdev)
+		free_netdev(dev);
 
 	if (atomic_read(&pdev->enable_cnt) == 1)
 		pci_release_regions(pdev);
@@ -12654,6 +12850,20 @@ static void bnx2x_remove_one(struct pci_
 	pci_set_drvdata(pdev, NULL);
 }
 
+static void bnx2x_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct bnx2x *bp;
+
+	if (!dev) {
+		dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n");
+		return;
+	}
+	bp = netdev_priv(dev);
+
+	__bnx2x_remove(pdev, dev, bp, true);
+}
+
 static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
 {
 	bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
@@ -12686,19 +12896,6 @@ static int bnx2x_eeh_nic_unload(struct b
 	return 0;
 }
 
-static void bnx2x_eeh_recover(struct bnx2x *bp)
-{
-	u32 val;
-
-	mutex_init(&bp->port.phy_mutex);
-
-
-	val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
-	if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
-		!= (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
-		BNX2X_ERR("BAD MCP validity signature\n");
-}
-
 /**
  * bnx2x_io_error_detected - called when PCI error is detected
  * @pdev: Pointer to PCI device
@@ -12767,6 +12964,10 @@ static pci_ers_result_t bnx2x_io_slot_re
 
 	if (netif_running(dev)) {
 		BNX2X_ERR("IO slot reset --> driver unload\n");
+
+		/* MCP should have been reset; Need to wait for validity */
+		bnx2x_init_shmem(bp);
+
 		if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) {
 			u32 v;
 
@@ -12788,7 +12989,7 @@ static pci_ers_result_t bnx2x_io_slot_re
 
 		bnx2x_prev_unload(bp);
 
-		/* We should have resetted the engine, so It's fair to
+		/* We should have reseted the engine, so It's fair to
 		 * assume the FW will no longer write to the bnx2x driver.
 		 */
 		bnx2x_squeeze_objects(bp);
@@ -12825,8 +13026,6 @@ static void bnx2x_io_resume(struct pci_d
 
 	rtnl_lock();
 
-	bnx2x_eeh_recover(bp);
-
 	bp->fw_seq = SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
 							DRV_MSG_SEQ_NUMBER_MASK;
 
@@ -12844,6 +13043,29 @@ static const struct pci_error_handlers b
 	.resume         = bnx2x_io_resume,
 };
 
+static void bnx2x_shutdown(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct bnx2x *bp;
+
+	if (!dev)
+		return;
+
+	bp = netdev_priv(dev);
+	if (!bp)
+		return;
+
+	rtnl_lock();
+	netif_device_detach(dev);
+	rtnl_unlock();
+
+	/* Don't remove the netdevice, as there are scenarios which will cause
+	 * the kernel to hang, e.g., when trying to remove bnx2i while the
+	 * rootfs is mounted from SAN.
+	 */
+	__bnx2x_remove(pdev, dev, bp, false);
+}
+
 static struct pci_driver bnx2x_pci_driver = {
 	.name        = DRV_MODULE_NAME,
 	.id_table    = bnx2x_pci_tbl,
@@ -12855,6 +13077,7 @@ static struct pci_driver bnx2x_pci_drive
 #ifdef CONFIG_BNX2X_SRIOV
 	.sriov_configure = bnx2x_sriov_configure,
 #endif
+	.shutdown    = bnx2x_shutdown,
 };
 
 static int __init bnx2x_init(void)
@@ -12880,11 +13103,12 @@ static int __init bnx2x_init(void)
 static void __exit bnx2x_cleanup(void)
 {
 	struct list_head *pos, *q;
+
 	pci_unregister_driver(&bnx2x_pci_driver);
 
 	destroy_workqueue(bnx2x_wq);
 
-	/* Free globablly allocated resources */
+	/* Free globally allocated resources */
 	list_for_each_safe(pos, q, &bnx2x_prev_list) {
 		struct bnx2x_prev_path_list *tmp =
 			list_entry(pos, struct bnx2x_prev_path_list, list);
@@ -12907,7 +13131,7 @@ module_exit(bnx2x_cleanup);
  * @bp:		driver handle
  * @set:	set or clear the CAM entry
  *
- * This function will wait until the ramdord completion returns.
+ * This function will wait until the ramrod completion returns.
  * Return 0 if success, -ENODEV if ramrod doesn't return.
  */
 static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp)
@@ -12935,7 +13159,6 @@ static void bnx2x_cnic_sp_post(struct bn
 	BUG_ON(bp->cnic_spq_pending < count);
 	bp->cnic_spq_pending -= count;
 
-
 	for (; bp->cnic_kwq_pending; bp->cnic_kwq_pending--) {
 		u16 type =  (le16_to_cpu(bp->cnic_kwq_cons->hdr.type)
 				& SPE_HDR_CONN_TYPE) >>
@@ -13108,7 +13331,6 @@ static void bnx2x_cnic_cfc_comp(struct b
 	bnx2x_cnic_sp_post(bp, 0);
 }
 
-
 /* Called with netif_addr_lock_bh() taken.
  * Sets an rx_mode config for an iSCSI ETH client.
  * Doesn't block.
@@ -13149,7 +13371,6 @@ static void bnx2x_set_iscsi_eth_rx_mode(
 	}
 }
 
-
 static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
 {
 	struct bnx2x *bp = netdev_priv(dev);
@@ -13337,7 +13558,6 @@ void bnx2x_setup_cnic_info(struct bnx2x
 {
 	struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
 
-
 	cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) +
 			     bnx2x_cid_ilt_lines(bp);
 	cp->starting_cid = bnx2x_cid_ilt_lines(bp) * ILT_PAGE_CIDS;
@@ -13373,7 +13593,6 @@ static int bnx2x_register_cnic(struct ne
 			BNX2X_ERR("CNIC-related load failed\n");
 			return rc;
 		}
-
 	}
 
 	bp->cnic_enabled = true;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,8 @@
 #define ATC_REG_ATC_INT_STS_CLR					 0x1101c0
 /* [RW 5] Parity mask register #0 read/write */
 #define ATC_REG_ATC_PRTY_MASK					 0x1101d8
+/* [R 5] Parity register #0 read */
+#define ATC_REG_ATC_PRTY_STS					 0x1101cc
 /* [RC 5] Parity register #0 read clear */
 #define ATC_REG_ATC_PRTY_STS_CLR				 0x1101d0
 /* [RW 19] Interrupt mask register #0 read/write */
@@ -2750,6 +2752,8 @@
 #define PBF_REG_PBF_INT_STS					 0x1401c8
 /* [RW 20] Parity mask register #0 read/write */
 #define PBF_REG_PBF_PRTY_MASK					 0x1401e4
+/* [R 28] Parity register #0 read */
+#define PBF_REG_PBF_PRTY_STS					 0x1401d8
 /* [RC 20] Parity register #0 read clear */
 #define PBF_REG_PBF_PRTY_STS_CLR				 0x1401dc
 /* [RW 16] The Ethernet type value for L2 tag 0 */
@@ -4517,6 +4521,8 @@
 #define TM_REG_TM_INT_STS					 0x1640f0
 /* [RW 7] Parity mask register #0 read/write */
 #define TM_REG_TM_PRTY_MASK					 0x16410c
+/* [R 7] Parity register #0 read */
+#define TM_REG_TM_PRTY_STS					 0x164100
 /* [RC 7] Parity register #0 read clear */
 #define TM_REG_TM_PRTY_STS_CLR					 0x164104
 /* [RW 8] The event id for aggregated interrupt 0 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,9 +35,9 @@
 /**
  * bnx2x_exe_queue_init - init the Exe Queue object
  *
- * @o:		poiter to the object
+ * @o:		pointer to the object
  * @exe_len:	length
- * @owner:	poiter to the owner
+ * @owner:	pointer to the owner
  * @validate:	validate function pointer
  * @optimize:	optimize function pointer
  * @exec:	execute function pointer
@@ -142,7 +142,6 @@ free_and_exit:
 	spin_unlock_bh(&o->lock);
 
 	return rc;
-
 }
 
 static inline void __bnx2x_exe_queue_reset_pending(
@@ -163,13 +162,11 @@ static inline void __bnx2x_exe_queue_res
 static inline void bnx2x_exe_queue_reset_pending(struct bnx2x *bp,
 						 struct bnx2x_exe_queue_obj *o)
 {
-
 	spin_lock_bh(&o->lock);
 
 	__bnx2x_exe_queue_reset_pending(bp, o);
 
 	spin_unlock_bh(&o->lock);
-
 }
 
 /**
@@ -179,7 +176,7 @@ static inline void bnx2x_exe_queue_reset
  * @o:			queue
  * @ramrod_flags:	flags
  *
- * (Atomicy is ensured using the exe_queue->lock).
+ * (Atomicity is ensured using the exe_queue->lock).
  */
 static inline int bnx2x_exe_queue_step(struct bnx2x *bp,
 				       struct bnx2x_exe_queue_obj *o,
@@ -192,8 +189,7 @@ static inline int bnx2x_exe_queue_step(s
 
 	spin_lock_bh(&o->lock);
 
-	/*
-	 * Next step should not be performed until the current is finished,
+	/* Next step should not be performed until the current is finished,
 	 * unless a DRV_CLEAR_ONLY bit is set. In this case we just want to
 	 * properly clear object internals without sending any command to the FW
 	 * which also implies there won't be any completion to clear the
@@ -209,8 +205,7 @@ static inline int bnx2x_exe_queue_step(s
 		}
 	}
 
-	/*
-	 * Run through the pending commands list and create a next
+	/* Run through the pending commands list and create a next
 	 * execution chunk.
 	 */
 	while (!list_empty(&o->exe_queue)) {
@@ -220,8 +215,7 @@ static inline int bnx2x_exe_queue_step(s
 
 		if (cur_len + elem->cmd_len <= o->exe_chunk_len) {
 			cur_len += elem->cmd_len;
-			/*
-			 * Prevent from both lists being empty when moving an
+			/* Prevent from both lists being empty when moving an
 			 * element. This will allow the call of
 			 * bnx2x_exe_queue_empty() without locking.
 			 */
@@ -241,14 +235,12 @@ static inline int bnx2x_exe_queue_step(s
 
 	rc = o->execute(bp, o->owner, &o->pending_comp, ramrod_flags);
 	if (rc < 0)
-		/*
-		 *  In case of an error return the commands back to the queue
-		 *  and reset the pending_comp.
+		/* In case of an error return the commands back to the queue
+		 * and reset the pending_comp.
 		 */
 		list_splice_init(&o->pending_comp, &o->exe_queue);
 	else if (!rc)
-		/*
-		 * If zero is returned, means there are no outstanding pending
+		/* If zero is returned, means there are no outstanding pending
 		 * completions and we may dismiss the pending list.
 		 */
 		__bnx2x_exe_queue_reset_pending(bp, o);
@@ -308,7 +300,6 @@ static inline int bnx2x_state_wait(struc
 	/* can take a while if any port is running */
 	int cnt = 5000;
 
-
 	if (CHIP_REV_IS_EMUL(bp))
 		cnt *= 20;
 
@@ -456,7 +447,6 @@ static int bnx2x_get_n_elements(struct b
 			DP(BNX2X_MSG_SP, "copied element number %d to address %p element was:\n",
 			   counter, next);
 			next += stride + size;
-
 		}
 	}
 	return counter * ETH_ALEN;
@@ -518,7 +508,6 @@ static int bnx2x_check_vlan_mac_add(stru
 	return 0;
 }
 
-
 /* check_del() callbacks */
 static struct bnx2x_vlan_mac_registry_elem *
 	bnx2x_check_mac_del(struct bnx2x *bp,
@@ -609,7 +598,6 @@ static bool bnx2x_check_move_always_err(
 	return false;
 }
 
-
 static inline u8 bnx2x_vlan_mac_get_rx_tx_flag(struct bnx2x_vlan_mac_obj *o)
 {
 	struct bnx2x_raw_obj *raw = &o->raw;
@@ -626,7 +614,6 @@ static inline u8 bnx2x_vlan_mac_get_rx_t
 	return rx_tx_flag;
 }
 
-
 void bnx2x_set_mac_in_nig(struct bnx2x *bp,
 			  bool add, unsigned char *dev_addr, int index)
 {
@@ -693,7 +680,7 @@ static inline void bnx2x_vlan_mac_set_cm
  *
  * @cid:	connection id
  * @type:	BNX2X_FILTER_XXX_PENDING
- * @hdr:	poiter to header to setup
+ * @hdr:	pointer to header to setup
  * @rule_cnt:
  *
  * currently we always configure one rule and echo field to contain a CID and an
@@ -707,7 +694,6 @@ static inline void bnx2x_vlan_mac_set_rd
 	hdr->rule_cnt = (u8)rule_cnt;
 }
 
-
 /* hw_config() callbacks */
 static void bnx2x_set_one_mac_e2(struct bnx2x *bp,
 				 struct bnx2x_vlan_mac_obj *o,
@@ -723,8 +709,7 @@ static void bnx2x_set_one_mac_e2(struct
 	unsigned long *vlan_mac_flags = &elem->cmd_data.vlan_mac.vlan_mac_flags;
 	u8 *mac = elem->cmd_data.vlan_mac.u.mac.mac;
 
-	/*
-	 * Set LLH CAM entry: currently only iSCSI and ETH macs are
+	/* Set LLH CAM entry: currently only iSCSI and ETH macs are
 	 * relevant. In addition, current implementation is tuned for a
 	 * single ETH MAC.
 	 *
@@ -879,8 +864,7 @@ static void bnx2x_set_one_mac_e1x(struct
 	struct bnx2x_raw_obj *raw = &o->raw;
 	struct mac_configuration_cmd *config =
 		(struct mac_configuration_cmd *)(raw->rdata);
-	/*
-	 * 57710 and 57711 do not support MOVE command,
+	/* 57710 and 57711 do not support MOVE command,
 	 * so it's either ADD or DEL
 	 */
 	bool add = (elem->cmd_data.vlan_mac.cmd == BNX2X_VLAN_MAC_ADD) ?
@@ -960,7 +944,6 @@ static void bnx2x_set_one_vlan_mac_e2(st
 	u16 vlan = elem->cmd_data.vlan_mac.u.vlan_mac.vlan;
 	u8 *mac = elem->cmd_data.vlan_mac.u.vlan_mac.mac;
 
-
 	/* Reset the ramrod data buffer for the first rule */
 	if (rule_idx == 0)
 		memset(data, 0, sizeof(*data));
@@ -969,7 +952,7 @@ static void bnx2x_set_one_vlan_mac_e2(st
 	bnx2x_vlan_mac_set_cmd_hdr_e2(bp, o, add, CLASSIFY_RULE_OPCODE_PAIR,
 				      &rule_entry->pair.header);
 
-	/* Set VLAN and MAC themselvs */
+	/* Set VLAN and MAC themselves */
 	rule_entry->pair.vlan = cpu_to_le16(vlan);
 	bnx2x_set_fw_mac_addr(&rule_entry->pair.mac_msb,
 			      &rule_entry->pair.mac_mid,
@@ -1021,8 +1004,7 @@ static void bnx2x_set_one_vlan_mac_e1h(s
 	struct bnx2x_raw_obj *raw = &o->raw;
 	struct mac_configuration_cmd *config =
 		(struct mac_configuration_cmd *)(raw->rdata);
-	/*
-	 * 57710 and 57711 do not support MOVE command,
+	/* 57710 and 57711 do not support MOVE command,
 	 * so it's either ADD or DEL
 	 */
 	bool add = (elem->cmd_data.vlan_mac.cmd == BNX2X_VLAN_MAC_ADD) ?
@@ -1046,7 +1028,7 @@ static void bnx2x_set_one_vlan_mac_e1h(s
  *
  * @bp:		device handle
  * @p:		command parameters
- * @ppos:	pointer to the cooky
+ * @ppos:	pointer to the cookie
  *
  * reconfigure next MAC/VLAN/VLAN-MAC element from the
  * previously configured elements list.
@@ -1054,7 +1036,7 @@ static void bnx2x_set_one_vlan_mac_e1h(s
  * from command parameters only RAMROD_COMP_WAIT bit in ramrod_flags is	taken
  * into an account
  *
- * pointer to the cooky  - that should be given back in the next call to make
+ * pointer to the cookie  - that should be given back in the next call to make
  * function handle the next element. If *ppos is set to NULL it will restart the
  * iterator. If returned *ppos == NULL this means that the last element has been
  * handled.
@@ -1102,8 +1084,7 @@ static int bnx2x_vlan_mac_restore(struct
 	return bnx2x_config_vlan_mac(bp, p);
 }
 
-/*
- * bnx2x_exeq_get_mac/bnx2x_exeq_get_vlan/bnx2x_exeq_get_vlan_mac return a
+/* bnx2x_exeq_get_mac/bnx2x_exeq_get_vlan/bnx2x_exeq_get_vlan_mac return a
  * pointer to an element with a specific criteria and NULL if such an element
  * hasn't been found.
  */
@@ -1187,8 +1168,7 @@ static inline int bnx2x_validate_vlan_ma
 		return rc;
 	}
 
-	/*
-	 * Check if there is a pending ADD command for this
+	/* Check if there is a pending ADD command for this
 	 * MAC/VLAN/VLAN-MAC. Return an error if there is.
 	 */
 	if (exeq->get(exeq, elem)) {
@@ -1196,8 +1176,7 @@ static inline int bnx2x_validate_vlan_ma
 		return -EEXIST;
 	}
 
-	/*
-	 * TODO: Check the pending MOVE from other objects where this
+	/* TODO: Check the pending MOVE from other objects where this
 	 * object is a destination object.
 	 */
 
@@ -1240,8 +1219,7 @@ static inline int bnx2x_validate_vlan_ma
 		return -EEXIST;
 	}
 
-	/*
-	 * Check if there are pending DEL or MOVE commands for this
+	/* Check if there are pending DEL or MOVE commands for this
 	 * MAC/VLAN/VLAN-MAC. Return an error if so.
 	 */
 	memcpy(&query_elem, elem, sizeof(query_elem));
@@ -1292,8 +1270,7 @@ static inline int bnx2x_validate_vlan_ma
 	struct bnx2x_exe_queue_obj *src_exeq = &src_o->exe_queue;
 	struct bnx2x_exe_queue_obj *dest_exeq = &dest_o->exe_queue;
 
-	/*
-	 * Check if we can perform this operation based on the current registry
+	/* Check if we can perform this operation based on the current registry
 	 * state.
 	 */
 	if (!src_o->check_move(bp, src_o, dest_o,
@@ -1302,8 +1279,7 @@ static inline int bnx2x_validate_vlan_ma
 		return -EINVAL;
 	}
 
-	/*
-	 * Check if there is an already pending DEL or MOVE command for the
+	/* Check if there is an already pending DEL or MOVE command for the
 	 * source object or ADD command for a destination object. Return an
 	 * error if so.
 	 */
@@ -1392,7 +1368,7 @@ static int bnx2x_remove_vlan_mac(struct
 }
 
 /**
- * bnx2x_wait_vlan_mac - passivly wait for 5 seconds until all work completes.
+ * bnx2x_wait_vlan_mac - passively wait for 5 seconds until all work completes.
  *
  * @bp:		device handle
  * @o:		bnx2x_vlan_mac_obj
@@ -1550,9 +1526,8 @@ static inline int bnx2x_vlan_mac_get_reg
 
 		/* Get a new CAM offset */
 		if (!o->get_cam_offset(o, &reg_elem->cam_offset)) {
-			/*
-			 * This shell never happen, because we have checked the
-			 * CAM availiability in the 'validate'.
+			/* This shall never happen, because we have checked the
+			 * CAM availability in the 'validate'.
 			 */
 			WARN_ON(1);
 			kfree(reg_elem);
@@ -1599,8 +1574,7 @@ static int bnx2x_execute_vlan_mac(struct
 	struct bnx2x_vlan_mac_registry_elem *reg_elem;
 	enum bnx2x_vlan_mac_cmd cmd;
 
-	/*
-	 * If DRIVER_ONLY execution is requested, cleanup a registry
+	/* If DRIVER_ONLY execution is requested, cleanup a registry
 	 * and exit. Otherwise send a ramrod to FW.
 	 */
 	if (!drv_only) {
@@ -1609,11 +1583,10 @@ static int bnx2x_execute_vlan_mac(struct
 		/* Set pending */
 		r->set_pending(r);
 
-		/* Fill tha ramrod data */
+		/* Fill the ramrod data */
 		list_for_each_entry(elem, exe_chunk, link) {
 			cmd = elem->cmd_data.vlan_mac.cmd;
-			/*
-			 * We will add to the target object in MOVE command, so
+			/* We will add to the target object in MOVE command, so
 			 * change the object for a CAM search.
 			 */
 			if (cmd == BNX2X_VLAN_MAC_MOVE)
@@ -1646,12 +1619,11 @@ static int bnx2x_execute_vlan_mac(struct
 				idx++;
 		}
 
-		/*
-		 *  No need for an explicit memory barrier here as long we would
-		 *  need to ensure the ordering of writing to the SPQ element
-		 *  and updating of the SPQ producer which involves a memory
-		 *  read and we will have to put a full memory barrier there
-		 *  (inside bnx2x_sp_post()).
+		/* No need for an explicit memory barrier here as long we would
+		 * need to ensure the ordering of writing to the SPQ element
+		 * and updating of the SPQ producer which involves a memory
+		 * read and we will have to put a full memory barrier there
+		 * (inside bnx2x_sp_post()).
 		 */
 
 		rc = bnx2x_sp_post(bp, o->ramrod_cmd, r->cid,
@@ -1766,8 +1738,7 @@ int bnx2x_config_vlan_mac(
 			return rc;
 	}
 
-	/*
-	 * If nothing will be executed further in this iteration we want to
+	/* If nothing will be executed further in this iteration we want to
 	 * return PENDING if there are pending commands
 	 */
 	if (!bnx2x_exe_queue_empty(&o->exe_queue))
@@ -1786,13 +1757,11 @@ int bnx2x_config_vlan_mac(
 			return rc;
 	}
 
-	/*
-	 * RAMROD_COMP_WAIT is a superset of RAMROD_EXEC. If it was set
+	/* RAMROD_COMP_WAIT is a superset of RAMROD_EXEC. If it was set
 	 * then user want to wait until the last command is done.
 	 */
 	if (test_bit(RAMROD_COMP_WAIT, &p->ramrod_flags)) {
-		/*
-		 * Wait maximum for the current exe_queue length iterations plus
+		/* Wait maximum for the current exe_queue length iterations plus
 		 * one (for the current pending command).
 		 */
 		int max_iterations = bnx2x_exe_queue_length(&o->exe_queue) + 1;
@@ -1818,8 +1787,6 @@ int bnx2x_config_vlan_mac(
 	return rc;
 }
 
-
-
 /**
  * bnx2x_vlan_mac_del_all - delete elements with given vlan_mac_flags spec
  *
@@ -1829,7 +1796,7 @@ int bnx2x_config_vlan_mac(
  * @ramrod_flags:	execution flags to be used for this deletion
  *
  * if the last operation has completed successfully and there are no
- * moreelements left, positive value if the last operation has completed
+ * more elements left, positive value if the last operation has completed
  * successfully and there are more previously configured elements, negative
  * value is current operation has failed.
  */
@@ -1870,8 +1837,7 @@ static int bnx2x_vlan_mac_del_all(struct
 	p.ramrod_flags = *ramrod_flags;
 	p.user_req.cmd = BNX2X_VLAN_MAC_DEL;
 
-	/*
-	 * Add all but the last VLAN-MAC to the execution queue without actually
+	/* Add all but the last VLAN-MAC to the execution queue without actually
 	 * execution anything.
 	 */
 	__clear_bit(RAMROD_COMP_WAIT, &p.ramrod_flags);
@@ -1934,7 +1900,6 @@ static inline void bnx2x_init_vlan_mac_c
 			   state, pstate, type);
 }
 
-
 void bnx2x_init_mac_obj(struct bnx2x *bp,
 			struct bnx2x_vlan_mac_obj *mac_obj,
 			u8 cl_id, u32 cid, u8 func_id, void *rdata,
@@ -2048,8 +2013,7 @@ void bnx2x_init_vlan_mac_obj(struct bnx2
 	/* CAM pool handling */
 	vlan_mac_obj->get_credit = bnx2x_get_credit_vlan_mac;
 	vlan_mac_obj->put_credit = bnx2x_put_credit_vlan_mac;
-	/*
-	 * CAM offset is relevant for 57710 and 57711 chips only which have a
+	/* CAM offset is relevant for 57710 and 57711 chips only which have a
 	 * single CAM for both MACs and VLAN-MAC pairs. So the offset
 	 * will be taken from MACs' pool object only.
 	 */
@@ -2092,7 +2056,6 @@ void bnx2x_init_vlan_mac_obj(struct bnx2
 				     bnx2x_execute_vlan_mac,
 				     bnx2x_exeq_get_vlan_mac);
 	}
-
 }
 
 /* RX_MODE verbs: DROP_ALL/ACCEPT_ALL/ACCEPT_ALL_MULTI/ACCEPT_ALL_VLAN/NORMAL */
@@ -2117,12 +2080,12 @@ static int bnx2x_set_rx_mode_e1x(struct
 	struct tstorm_eth_mac_filter_config *mac_filters =
 		(struct tstorm_eth_mac_filter_config *)p->rdata;
 
-	/* initial seeting is drop-all */
+	/* initial setting is drop-all */
 	u8 drop_all_ucast = 1, drop_all_mcast = 1;
 	u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0;
 	u8 unmatched_unicast = 0;
 
-    /* In e1x there we only take into account rx acceot flag since tx switching
+    /* In e1x there we only take into account rx accept flag since tx switching
      * isn't enabled. */
 	if (test_bit(BNX2X_ACCEPT_UNICAST, &p->rx_accept_flags))
 		/* accept matched ucast */
@@ -2245,7 +2208,6 @@ static inline void bnx2x_rx_mode_set_cmd
 	}
 
 	cmd->state = cpu_to_le16(state);
-
 }
 
 static int bnx2x_set_rx_mode_e2(struct bnx2x *bp,
@@ -2286,9 +2248,7 @@ static int bnx2x_set_rx_mode_e2(struct b
 					       false);
 	}
 
-
-	/*
-	 * If FCoE Queue configuration has been requested configure the Rx and
+	/* If FCoE Queue configuration has been requested configure the Rx and
 	 * internal switching modes for this queue in separate rules.
 	 *
 	 * FCoE queue shell never be set to ACCEPT_ALL packets of any sort:
@@ -2324,8 +2284,7 @@ static int bnx2x_set_rx_mode_e2(struct b
 		}
 	}
 
-	/*
-	 * Set the ramrod header (most importantly - number of rules to
+	/* Set the ramrod header (most importantly - number of rules to
 	 * configure).
 	 */
 	bnx2x_rx_mode_set_rdata_hdr_e2(p->cid, &data->header, rule_idx);
@@ -2334,12 +2293,11 @@ static int bnx2x_set_rx_mode_e2(struct b
 			 data->header.rule_cnt, p->rx_accept_flags,
 			 p->tx_accept_flags);
 
-	/*
-	 *  No need for an explicit memory barrier here as long we would
-	 *  need to ensure the ordering of writing to the SPQ element
-	 *  and updating of the SPQ producer which involves a memory
-	 *  read and we will have to put a full memory barrier there
-	 *  (inside bnx2x_sp_post()).
+	/* No need for an explicit memory barrier here as long we would
+	 * need to ensure the ordering of writing to the SPQ element
+	 * and updating of the SPQ producer which involves a memory
+	 * read and we will have to put a full memory barrier there
+	 * (inside bnx2x_sp_post()).
 	 */
 
 	/* Send a ramrod */
@@ -2476,7 +2434,7 @@ static int bnx2x_mcast_enqueue_cmd(struc
 		cur_mac = (struct bnx2x_mcast_mac_elem *)
 			  ((u8 *)new_cmd + sizeof(*new_cmd));
 
-		/* Push the MACs of the current command into the pendig command
+		/* Push the MACs of the current command into the pending command
 		 * MACs list: FIFO
 		 */
 		list_for_each_entry(pos, &p->mcast_list, link) {
@@ -2909,7 +2867,6 @@ static int bnx2x_mcast_validate_e2(struc
 	default:
 		BNX2X_ERR("Unknown command: %d\n", cmd);
 		return -EINVAL;
-
 	}
 
 	/* Increase the total number of MACs pending to be configured */
@@ -3034,20 +2991,18 @@ static int bnx2x_mcast_setup_e2(struct b
 	if (!o->total_pending_num)
 		bnx2x_mcast_refresh_registry_e2(bp, o);
 
-	/*
-	 * If CLEAR_ONLY was requested - don't send a ramrod and clear
+	/* If CLEAR_ONLY was requested - don't send a ramrod and clear
 	 * RAMROD_PENDING status immediately.
 	 */
 	if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) {
 		raw->clear_pending(raw);
 		return 0;
 	} else {
-		/*
-		 *  No need for an explicit memory barrier here as long we would
-		 *  need to ensure the ordering of writing to the SPQ element
-		 *  and updating of the SPQ producer which involves a memory
-		 *  read and we will have to put a full memory barrier there
-		 *  (inside bnx2x_sp_post()).
+		/* No need for an explicit memory barrier here as long we would
+		 * need to ensure the ordering of writing to the SPQ element
+		 * and updating of the SPQ producer which involves a memory
+		 * read and we will have to put a full memory barrier there
+		 * (inside bnx2x_sp_post()).
 		 */
 
 		/* Send a ramrod */
@@ -3121,7 +3076,7 @@ static inline void bnx2x_mcast_hdl_resto
 	}
 }
 
-/* On 57711 we write the multicast MACs' aproximate match
+/* On 57711 we write the multicast MACs' approximate match
  * table by directly into the TSTORM's internal RAM. So we don't
  * really need to handle any tricks to make it work.
  */
@@ -3223,7 +3178,6 @@ static int bnx2x_mcast_validate_e1(struc
 	default:
 		BNX2X_ERR("Unknown command: %d\n", cmd);
 		return -EINVAL;
-
 	}
 
 	/* We want to ensure that commands are executed one by one for 57710.
@@ -3245,7 +3199,7 @@ static void bnx2x_mcast_revert_e1(struct
 
 	/* If current command hasn't been handled yet and we are
 	 * here means that it's meant to be dropped and we have to
-	 * update the number of outstandling MACs accordingly.
+	 * update the number of outstanding MACs accordingly.
 	 */
 	if (p->mcast_list_len)
 		o->total_pending_num -= o->max_cmd_len;
@@ -3342,7 +3296,6 @@ static inline int bnx2x_mcast_handle_res
 	return -1;
 }
 
-
 static inline int bnx2x_mcast_handle_pending_cmds_e1(
 	struct bnx2x *bp, struct bnx2x_mcast_ramrod_params *p)
 {
@@ -3352,7 +3305,6 @@ static inline int bnx2x_mcast_handle_pen
 	union bnx2x_mcast_config_data cfg_data = {NULL};
 	int cnt = 0;
 
-
 	/* If nothing to be done - return */
 	if (list_empty(&o->pending_cmds_head))
 		return 0;
@@ -3523,20 +3475,18 @@ static int bnx2x_mcast_setup_e1(struct b
 	if (rc)
 		return rc;
 
-	/*
-	 * If CLEAR_ONLY was requested - don't send a ramrod and clear
+	/* If CLEAR_ONLY was requested - don't send a ramrod and clear
 	 * RAMROD_PENDING status immediately.
 	 */
 	if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) {
 		raw->clear_pending(raw);
 		return 0;
 	} else {
-		/*
-		 *  No need for an explicit memory barrier here as long we would
-		 *  need to ensure the ordering of writing to the SPQ element
-		 *  and updating of the SPQ producer which involves a memory
-		 *  read and we will have to put a full memory barrier there
-		 *  (inside bnx2x_sp_post()).
+		/* No need for an explicit memory barrier here as long we would
+		 * need to ensure the ordering of writing to the SPQ element
+		 * and updating of the SPQ producer which involves a memory
+		 * read and we will have to put a full memory barrier there
+		 * (inside bnx2x_sp_post()).
 		 */
 
 		/* Send a ramrod */
@@ -3550,7 +3500,6 @@ static int bnx2x_mcast_setup_e1(struct b
 		/* Ramrod completion is pending */
 		return 1;
 	}
-
 }
 
 static int bnx2x_mcast_get_registry_size_exact(struct bnx2x_mcast_obj *o)
@@ -3848,7 +3797,6 @@ static bool bnx2x_credit_pool_always_tru
 	return true;
 }
 
-
 static bool bnx2x_credit_pool_get_entry(
 	struct bnx2x_credit_pool_obj *o,
 	int *offset)
@@ -3999,8 +3947,7 @@ void bnx2x_init_mac_credit_pool(struct b
 
 	} else {
 
-		/*
-		 * CAM credit is equaly divided between all active functions
+		/* CAM credit is equaly divided between all active functions
 		 * on the PATH.
 		 */
 		if ((func_num > 0)) {
@@ -4009,8 +3956,7 @@ void bnx2x_init_mac_credit_pool(struct b
 			else
 				cam_sz = BNX2X_CAM_SIZE_EMUL;
 
-			/*
-			 * No need for CAM entries handling for 57712 and
+			/* No need for CAM entries handling for 57712 and
 			 * newer.
 			 */
 			bnx2x_init_credit_pool(p, -1, cam_sz);
@@ -4018,7 +3964,6 @@ void bnx2x_init_mac_credit_pool(struct b
 			/* this should never happen! Block MAC operations. */
 			bnx2x_init_credit_pool(p, 0, 0);
 		}
-
 	}
 }
 
@@ -4028,14 +3973,12 @@ void bnx2x_init_vlan_credit_pool(struct
 				 u8 func_num)
 {
 	if (CHIP_IS_E1x(bp)) {
-		/*
-		 * There is no VLAN credit in HW on 57710 and 57711 only
+		/* There is no VLAN credit in HW on 57710 and 57711 only
 		 * MAC / MAC-VLAN can be set
 		 */
 		bnx2x_init_credit_pool(p, 0, -1);
 	} else {
-		/*
-		 * CAM credit is equaly divided between all active functions
+		/* CAM credit is equally divided between all active functions
 		 * on the PATH.
 		 */
 		if (func_num > 0) {
@@ -4051,7 +3994,7 @@ void bnx2x_init_vlan_credit_pool(struct
 /**
  * bnx2x_debug_print_ind_table - prints the indirection table configuration.
  *
- * @bp:		driver hanlde
+ * @bp:		driver handle
  * @p:		pointer to rss configuration
  *
  * Prints it when NETIF_MSG_IFUP debug level is configured.
@@ -4164,12 +4107,11 @@ static int bnx2x_setup_rss(struct bnx2x
 		data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY;
 	}
 
-	/*
-	 *  No need for an explicit memory barrier here as long we would
-	 *  need to ensure the ordering of writing to the SPQ element
-	 *  and updating of the SPQ producer which involves a memory
-	 *  read and we will have to put a full memory barrier there
-	 *  (inside bnx2x_sp_post()).
+	/* No need for an explicit memory barrier here as long we would
+	 * need to ensure the ordering of writing to the SPQ element
+	 * and updating of the SPQ producer which involves a memory
+	 * read and we will have to put a full memory barrier there
+	 * (inside bnx2x_sp_post()).
 	 */
 
 	/* Send a ramrod */
@@ -4215,7 +4157,6 @@ int bnx2x_config_rss(struct bnx2x *bp,
 	return rc;
 }
 
-
 void bnx2x_init_rss_config_obj(struct bnx2x *bp,
 			       struct bnx2x_rss_config_obj *rss_obj,
 			       u8 cl_id, u32 cid, u8 func_id, u8 engine_id,
@@ -4288,7 +4229,6 @@ int bnx2x_queue_state_change(struct bnx2
 	return !!test_bit(pending_bit, pending);
 }
 
-
 static int bnx2x_queue_set_pending(struct bnx2x_queue_sp_obj *obj,
 				   struct bnx2x_queue_state_params *params)
 {
@@ -4337,7 +4277,7 @@ static int bnx2x_queue_comp_cmd(struct b
 	}
 
 	if (o->next_tx_only >= o->max_cos)
-		/* >= becuase tx only must always be smaller than cos since the
+		/* >= because tx only must always be smaller than cos since the
 		 * primary connection supports COS 0
 		 */
 		BNX2X_ERR("illegal value for next tx_only: %d. max cos was %d",
@@ -4403,7 +4343,6 @@ static void bnx2x_q_fill_init_general_da
 	gen_data->mtu = cpu_to_le16(params->mtu);
 	gen_data->func_id = o->func_id;
 
-
 	gen_data->cos = params->cos;
 
 	gen_data->traffic_type =
@@ -4530,7 +4469,6 @@ static void bnx2x_q_fill_init_rx_data(st
 		cpu_to_le16(params->silent_removal_value);
 	rx_data->silent_vlan_mask =
 		cpu_to_le16(params->silent_removal_mask);
-
 }
 
 /* initialize the general, tx and rx parts of a queue object */
@@ -4652,12 +4590,11 @@ static inline int bnx2x_q_send_setup_e1x
 	/* Fill the ramrod data */
 	bnx2x_q_fill_setup_data_cmn(bp, params, rdata);
 
-	/*
-	 *  No need for an explicit memory barrier here as long we would
-	 *  need to ensure the ordering of writing to the SPQ element
-	 *  and updating of the SPQ producer which involves a memory
-	 *  read and we will have to put a full memory barrier there
-	 *  (inside bnx2x_sp_post()).
+	/* No need for an explicit memory barrier here as long we would
+	 * need to ensure the ordering of writing to the SPQ element
+	 * and updating of the SPQ producer which involves a memory
+	 * read and we will have to put a full memory barrier there
+	 * (inside bnx2x_sp_post()).
 	 */
 
 	return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX],
@@ -4681,12 +4618,11 @@ static inline int bnx2x_q_send_setup_e2(
 	bnx2x_q_fill_setup_data_cmn(bp, params, rdata);
 	bnx2x_q_fill_setup_data_e2(bp, params, rdata);
 
-	/*
-	 *  No need for an explicit memory barrier here as long we would
-	 *  need to ensure the ordering of writing to the SPQ element
-	 *  and updating of the SPQ producer which involves a memory
-	 *  read and we will have to put a full memory barrier there
-	 *  (inside bnx2x_sp_post()).
+	/* No need for an explicit memory barrier here as long we would
+	 * need to ensure the ordering of writing to the SPQ element
+	 * and updating of the SPQ producer which involves a memory
+	 * read and we will have to put a full memory barrier there
+	 * (inside bnx2x_sp_post()).
 	 */
 
 	return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX],
@@ -4706,7 +4642,6 @@ static inline int bnx2x_q_send_setup_tx_
 		&params->params.tx_only;
 	u8 cid_index = tx_only_params->cid_index;
 
-
 	if (cid_index >= o->max_cos) {
 		BNX2X_ERR("queue[%d]: cid_index (%d) is out of range\n",
 			  o->cl_id, cid_index);
@@ -4727,12 +4662,11 @@ static inline int bnx2x_q_send_setup_tx_
 			 o->cids[cid_index], rdata->general.client_id,
 			 rdata->general.sp_client_id, rdata->general.cos);
 
-	/*
-	 *  No need for an explicit memory barrier here as long we would
-	 *  need to ensure the ordering of writing to the SPQ element
-	 *  and updating of the SPQ producer which involves a memory
-	 *  read and we will have to put a full memory barrier there
-	 *  (inside bnx2x_sp_post()).
+	/* No need for an explicit memory barrier here as long we would
+	 * need to ensure the ordering of writing to the SPQ element
+	 * and updating of the SPQ producer which involves a memory
+	 * read and we will have to put a full memory barrier there
+	 * (inside bnx2x_sp_post()).
 	 */
 
 	return bnx2x_sp_post(bp, ramrod, o->cids[cid_index],
@@ -4761,7 +4695,7 @@ static void bnx2x_q_fill_update_data(str
 		test_bit(BNX2X_Q_UPDATE_IN_VLAN_REM_CHNG,
 			 &params->update_flags);
 
-	/* Outer VLAN sripping */
+	/* Outer VLAN stripping */
 	data->outer_vlan_removal_enable_flg =
 		test_bit(BNX2X_Q_UPDATE_OUT_VLAN_REM, &params->update_flags);
 	data->outer_vlan_removal_change_flg =
@@ -4816,19 +4750,17 @@ static inline int bnx2x_q_send_update(st
 		return -EINVAL;
 	}
 
-
 	/* Clear the ramrod data */
 	memset(rdata, 0, sizeof(*rdata));
 
 	/* Fill the ramrod data */
 	bnx2x_q_fill_update_data(bp, o, update_params, rdata);
 
-	/*
-	 *  No need for an explicit memory barrier here as long we would
-	 *  need to ensure the ordering of writing to the SPQ element
-	 *  and updating of the SPQ producer which involves a memory
-	 *  read and we will have to put a full memory barrier there
-	 *  (inside bnx2x_sp_post()).
+	/* No need for an explicit memory barrier here as long we would
+	 * need to ensure the ordering of writing to the SPQ element
+	 * and updating of the SPQ producer which involves a memory
+	 * read and we will have to put a full memory barrier there
+	 * (inside bnx2x_sp_post()).
 	 */
 
 	return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE,
@@ -5038,8 +4970,7 @@ static int bnx2x_queue_chk_transition(st
 		 &params->params.update;
 	u8 next_tx_only = o->num_tx_only;
 
-	/*
-	 * Forget all pending for completion commands if a driver only state
+	/* Forget all pending for completion commands if a driver only state
 	 * transition has been requested.
 	 */
 	if (test_bit(RAMROD_DRV_CLR_ONLY, &params->ramrod_flags)) {
@@ -5047,8 +4978,7 @@ static int bnx2x_queue_chk_transition(st
 		o->next_state = BNX2X_Q_STATE_MAX;
 	}
 
-	/*
-	 * Don't allow a next state transition if we are in the middle of
+	/* Don't allow a next state transition if we are in the middle of
 	 * the previous one.
 	 */
 	if (o->pending) {
@@ -5257,8 +5187,7 @@ enum bnx2x_func_state bnx2x_func_get_sta
 	if (o->pending)
 		return BNX2X_F_STATE_MAX;
 
-	/*
-	 * unsure the order of reading of o->pending and o->state
+	/* unsure the order of reading of o->pending and o->state
 	 * o->pending should be read first
 	 */
 	rmb();
@@ -5356,8 +5285,7 @@ static int bnx2x_func_chk_transition(str
 	enum bnx2x_func_state state = o->state, next_state = BNX2X_F_STATE_MAX;
 	enum bnx2x_func_cmd cmd = params->cmd;
 
-	/*
-	 * Forget all pending for completion commands if a driver only state
+	/* Forget all pending for completion commands if a driver only state
 	 * transition has been requested.
 	 */
 	if (test_bit(RAMROD_DRV_CLR_ONLY, &params->ramrod_flags)) {
@@ -5365,8 +5293,7 @@ static int bnx2x_func_chk_transition(str
 		o->next_state = BNX2X_F_STATE_MAX;
 	}
 
-	/*
-	 * Don't allow a next state transition if we are in the middle of
+	/* Don't allow a next state transition if we are in the middle of
 	 * the previous one.
 	 */
 	if (o->pending)
@@ -5539,7 +5466,7 @@ static int bnx2x_func_hw_init(struct bnx
 		goto init_err;
 	}
 
-	/* Handle the beginning of COMMON_XXX pases separatelly... */
+	/* Handle the beginning of COMMON_XXX pases separately... */
 	switch (load_code) {
 	case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP:
 		rc = bnx2x_func_init_cmn_chip(bp, drv);
@@ -5573,7 +5500,7 @@ static int bnx2x_func_hw_init(struct bnx
 init_err:
 	drv->gunzip_end(bp);
 
-	/* In case of success, complete the comand immediatelly: no ramrods
+	/* In case of success, complete the command immediately: no ramrods
 	 * have been sent.
 	 */
 	if (!rc)
@@ -5598,7 +5525,7 @@ static inline void bnx2x_func_reset_func
 }
 
 /**
- * bnx2x_func_reset_port - reser HW at port stage
+ * bnx2x_func_reset_port - reset HW at port stage
  *
  * @bp:		device handle
  * @drv:
@@ -5620,7 +5547,7 @@ static inline void bnx2x_func_reset_port
 }
 
 /**
- * bnx2x_func_reset_cmn - reser HW at common stage
+ * bnx2x_func_reset_cmn - reset HW at common stage
  *
  * @bp:		device handle
  * @drv:
@@ -5636,7 +5563,6 @@ static inline void bnx2x_func_reset_cmn(
 	drv->reset_hw_cmn(bp);
 }
 
-
 static inline int bnx2x_func_hw_reset(struct bnx2x *bp,
 				      struct bnx2x_func_state_params *params)
 {
@@ -5663,7 +5589,7 @@ static inline int bnx2x_func_hw_reset(st
 		break;
 	}
 
-	/* Complete the comand immediatelly: no ramrods have been sent. */
+	/* Complete the command immediately: no ramrods have been sent. */
 	o->complete_cmd(bp, o, BNX2X_F_CMD_HW_RESET);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h	2013-08-25 20:43:22.000000000 -0400
@@ -34,8 +34,7 @@ enum {
 	RAMROD_RESTORE,
 	 /* Execute the next command now */
 	RAMROD_EXEC,
-	/*
-	 * Don't add a new command and continue execution of posponed
+	/* Don't add a new command and continue execution of postponed
 	 * commands. If not set a new command will be added to the
 	 * pending commands list.
 	 */
@@ -129,8 +128,7 @@ enum bnx2x_vlan_mac_cmd {
 struct bnx2x_vlan_mac_data {
 	/* Requested command: BNX2X_VLAN_MAC_XX */
 	enum bnx2x_vlan_mac_cmd cmd;
-	/*
-	 * used to contain the data related vlan_mac_flags bits from
+	/* used to contain the data related vlan_mac_flags bits from
 	 * ramrod parameters.
 	 */
 	unsigned long vlan_mac_flags;
@@ -190,14 +188,10 @@ typedef struct bnx2x_exeq_elem *
 				     struct bnx2x_exeq_elem *elem);
 
 struct bnx2x_exe_queue_obj {
-	/*
-	 * Commands pending for an execution.
-	 */
+	/* Commands pending for an execution. */
 	struct list_head	exe_queue;
 
-	/*
-	 * Commands pending for an completion.
-	 */
+	/* Commands pending for an completion. */
 	struct list_head	pending_comp;
 
 	spinlock_t		lock;
@@ -245,14 +239,13 @@ struct bnx2x_exe_queue_obj {
 };
 /***************** Classification verbs: Set/Del MAC/VLAN/VLAN-MAC ************/
 /*
- * Element in the VLAN_MAC registry list having all currenty configured
+ * Element in the VLAN_MAC registry list having all currently configured
  * rules.
  */
 struct bnx2x_vlan_mac_registry_elem {
 	struct list_head	link;
 
-	/*
-	 * Used to store the cam offset used for the mac/vlan/vlan-mac.
+	/* Used to store the cam offset used for the mac/vlan/vlan-mac.
 	 * Relevant for 57710 and 57711 only. VLANs and MACs share the
 	 * same CAM for these chips.
 	 */
@@ -310,7 +303,7 @@ struct bnx2x_vlan_mac_obj {
 	 * @param n number of elements to get
 	 * @param buf buffer preallocated by caller into which elements
 	 *            will be copied. Note elements are 4-byte aligned
-	 *            so buffer size must be able to accomodate the
+	 *            so buffer size must be able to accommodate the
 	 *            aligned elements.
 	 *
 	 * @return number of copied bytes
@@ -395,7 +388,7 @@ struct bnx2x_vlan_mac_obj {
 	 * @param bp
 	 * @param p Command parameters (RAMROD_COMP_WAIT bit in
 	 *          ramrod_flags is only taken into an account)
-	 * @param ppos a pointer to the cooky that should be given back in the
+	 * @param ppos a pointer to the cookie that should be given back in the
 	 *        next call to make function handle the next element. If
 	 *        *ppos is set to NULL it will restart the iterator.
 	 *        If returned *ppos == NULL this means that the last
@@ -408,7 +401,7 @@ struct bnx2x_vlan_mac_obj {
 		       struct bnx2x_vlan_mac_registry_elem **ppos);
 
 	/**
-	 * Should be called on a completion arival.
+	 * Should be called on a completion arrival.
 	 *
 	 * @param bp
 	 * @param o
@@ -447,7 +440,7 @@ void bnx2x_set_mac_in_nig(struct bnx2x *
 
 /** RX_MODE verbs:DROP_ALL/ACCEPT_ALL/ACCEPT_ALL_MULTI/ACCEPT_ALL_VLAN/NORMAL */
 
-/* RX_MODE ramrod spesial flags: set in rx_mode_flags field in
+/* RX_MODE ramrod special flags: set in rx_mode_flags field in
  * a bnx2x_rx_mode_ramrod_params.
  */
 enum {
@@ -475,8 +468,7 @@ struct bnx2x_rx_mode_ramrod_params {
 	unsigned long ramrod_flags;
 	unsigned long rx_mode_flags;
 
-	/*
-	 * rdata is either a pointer to eth_filter_rules_ramrod_data(e2) or to
+	/* rdata is either a pointer to eth_filter_rules_ramrod_data(e2) or to
 	 * a tstorm_eth_mac_filter_config (e1x).
 	 */
 	void *rdata;
@@ -646,12 +638,11 @@ struct bnx2x_credit_pool_obj {
 	/* Maximum allowed credit. put() will check against it. */
 	int		pool_sz;
 
-	/*
-	 *  Allocate a pool table statically.
+	/* Allocate a pool table statically.
 	 *
-	 *  Currently the mamimum allowed size is MAX_MAC_CREDIT_E2(272)
+	 * Currently the maximum allowed size is MAX_MAC_CREDIT_E2(272)
 	 *
-	 *  The set bit in the table will mean that the entry is available.
+	 * The set bit in the table will mean that the entry is available.
 	 */
 #define BNX2X_POOL_VEC_SIZE	(MAX_MAC_CREDIT_E2 / 64)
 	u64		pool_mirror[BNX2X_POOL_VEC_SIZE];
@@ -832,7 +823,7 @@ enum {
 	BNX2X_Q_FLG_TUN_INC_INNER_IP_ID
 };
 
-/* Queue type options: queue type may be a compination of below. */
+/* Queue type options: queue type may be a combination of below. */
 enum bnx2x_q_type {
 	/** TODO: Consider moving both these flags into the init()
 	 *        ramrod params.
@@ -1002,10 +993,9 @@ struct bnx2x_queue_sp_obj {
 	u8		cl_id;
 	u8		func_id;
 
-	/*
-	 * number of traffic classes supported by queue.
-	 * The primary connection of the queue suppotrs the first traffic
-	 * class. Any further traffic class is suppoted by a tx-only
+	/* number of traffic classes supported by queue.
+	 * The primary connection of the queue supports the first traffic
+	 * class. Any further traffic class is supported by a tx-only
 	 * connection.
 	 *
 	 * Therefore max_cos is also a number of valid entries in the cids
@@ -1021,7 +1011,7 @@ struct bnx2x_queue_sp_obj {
 
 	/* BNX2X_Q_CMD_XX bits. This object implements "one
 	 * pending" paradigm but for debug and tracing purposes it's
-	 * more convinient to have different bits for different
+	 * more convenient to have different bits for different
 	 * commands.
 	 */
 	unsigned long	pending;
@@ -1210,7 +1200,7 @@ struct bnx2x_func_sp_obj {
 
 	/* BNX2X_FUNC_CMD_XX bits. This object implements "one
 	 * pending" paradigm but for debug and tracing purposes it's
-	 * more convinient to have different bits for different
+	 * more convenient to have different bits for different
 	 * commands.
 	 */
 	unsigned long		pending;
@@ -1329,7 +1319,7 @@ void bnx2x_init_rx_mode_obj(struct bnx2x
  *
  * @p: Command parameters
  *
- * Return: 0 - if operation was successfull and there is no pending completions,
+ * Return: 0 - if operation was successful and there is no pending completions,
  *         positive number - if there are pending completions,
  *         negative - if there were errors
  */
@@ -1361,7 +1351,7 @@ void bnx2x_init_mcast_obj(struct bnx2x *
  * the current command will be enqueued to the tail of the
  * pending commands list.
  *
- * Return: 0 is operation was successfull and there are no pending completions,
+ * Return: 0 is operation was successful and there are no pending completions,
  *         negative if there were errors, positive if there are pending
  *         completions.
  */
@@ -1377,7 +1367,6 @@ void bnx2x_init_vlan_credit_pool(struct
 				 struct bnx2x_credit_pool_obj *p, u8 func_id,
 				 u8 func_num);
 
-
 /****************** RSS CONFIGURATION ****************/
 void bnx2x_init_rss_config_obj(struct bnx2x *bp,
 			       struct bnx2x_rss_config_obj *rss_obj,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c	2013-08-25 20:43:22.000000000 -0400
@@ -1341,7 +1341,7 @@ int bnx2x_vfop_qdown_cmd(struct bnx2x *b
  */
 
 /* internal vf enable - until vf is enabled internally all transactions
- * are blocked. this routine should always be called last with pretend.
+ * are blocked. This routine should always be called last with pretend.
  */
 static void bnx2x_vf_enable_internal(struct bnx2x *bp, u8 enable)
 {
@@ -1459,21 +1459,16 @@ static u8 bnx2x_vf_is_pcie_pending(struc
 	struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
 
 	if (!vf)
-		goto unknown_dev;
+		return false;
 
 	dev = pci_get_bus_and_slot(vf->bus, vf->devfn);
 	if (dev)
 		return bnx2x_is_pcie_pending(dev);
-
-unknown_dev:
 	return false;
 }
 
 int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid)
 {
-	/* Wait 100ms */
-	msleep(100);
-
 	/* Verify no pending pci transactions */
 	if (bnx2x_vf_is_pcie_pending(bp, abs_vfid))
 		BNX2X_ERR("PCIE Transactions still pending\n");
@@ -1620,7 +1615,7 @@ next_vf_to_clean:
 	     i++)
 		;
 
-	DP(BNX2X_MSG_IOV, "next vf to cleanup: %d. num of vfs: %d\n", i,
+	DP(BNX2X_MSG_IOV, "next vf to cleanup: %d. Num of vfs: %d\n", i,
 	   BNX2X_NR_VIRTFN(bp));
 
 	if (i < BNX2X_NR_VIRTFN(bp)) {
@@ -1743,7 +1738,7 @@ void bnx2x_iov_init_dq(struct bnx2x *bp)
 	REG_WR(bp, DORQ_REG_VF_TYPE_MIN_MCID_0, 0);
 	REG_WR(bp, DORQ_REG_VF_TYPE_MAX_MCID_0, 0x1ffff);
 
-	/* set the number of VF alllowed doorbells to the full DQ range */
+	/* set the number of VF allowed doorbells to the full DQ range */
 	REG_WR(bp, DORQ_REG_VF_NORM_MAX_CID_COUNT, 0x20000);
 
 	/* set the VF doorbell threshold */
@@ -1752,11 +1747,8 @@ void bnx2x_iov_init_dq(struct bnx2x *bp)
 
 void bnx2x_iov_init_dmae(struct bnx2x *bp)
 {
-	DP(BNX2X_MSG_IOV, "SRIOV is %s\n", IS_SRIOV(bp) ? "ON" : "OFF");
-	if (!IS_SRIOV(bp))
-		return;
-
-	REG_WR(bp, DMAE_REG_BACKWARD_COMP_EN, 0);
+	if (pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV))
+		REG_WR(bp, DMAE_REG_BACKWARD_COMP_EN, 0);
 }
 
 static int bnx2x_vf_bus(struct bnx2x *bp, int vfid)
@@ -2176,6 +2168,9 @@ int bnx2x_iov_nic_init(struct bnx2x *bp)
 
 	DP(BNX2X_MSG_IOV, "num of vfs: %d\n", (bp)->vfdb->sriov.nr_virtfn);
 
+	/* let FLR complete ... */
+	msleep(100);
+
 	/* initialize vf database */
 	for_each_vf(bp, vfid) {
 		struct bnx2x_virtf *vf = BP_VF(bp, vfid);
@@ -2403,7 +2398,7 @@ int bnx2x_iov_eq_sp_event(struct bnx2x *
 
 	/* extract vf and rxq index from vf_cid - relies on the following:
 	 * 1. vfid on cid reflects the true abs_vfid
-	 * 2. the max number of VFs (per path) is 64
+	 * 2. The max number of VFs (per path) is 64
 	 */
 	qidx = cid & ((1 << BNX2X_VF_CID_WND)-1);
 	abs_vfid = (cid >> BNX2X_VF_CID_WND) & (BNX2X_MAX_NUM_OF_VFS-1);
@@ -2461,7 +2456,7 @@ static struct bnx2x_virtf *bnx2x_vf_by_c
 {
 	/* extract the vf from vf_cid - relies on the following:
 	 * 1. vfid on cid reflects the true abs_vfid
-	 * 2. the max number of VFs (per path) is 64
+	 * 2. The max number of VFs (per path) is 64
 	 */
 	int abs_vfid = (vf_cid >> BNX2X_VF_CID_WND) & (BNX2X_MAX_NUM_OF_VFS-1);
 	return bnx2x_vf_by_abs_fid(bp, abs_vfid);
@@ -2480,7 +2475,7 @@ void bnx2x_iov_set_queue_sp_obj(struct b
 	if (vf) {
 		/* extract queue index from vf_cid - relies on the following:
 		 * 1. vfid on cid reflects the true abs_vfid
-		 * 2. the max number of VFs (per path) is 64
+		 * 2. The max number of VFs (per path) is 64
 		 */
 		int q_index = vf_cid & ((1 << BNX2X_VF_CID_WND)-1);
 		*q_obj = &bnx2x_vfq(vf, q_index, sp_obj);
@@ -2705,7 +2700,7 @@ int bnx2x_vf_acquire(struct bnx2x *bp, s
 	}
 
 	/* static allocation:
-	 * the global maximum number are fixed per VF. fail the request if
+	 * the global maximum number are fixed per VF. Fail the request if
 	 * requested number exceed these globals
 	 */
 	if (!bnx2x_vf_chk_avail_resc(bp, vf, resc)) {
@@ -2777,6 +2772,10 @@ int bnx2x_vf_init(struct bnx2x *bp, stru
 		   vf->abs_vfid, vf->state);
 		return -EINVAL;
 	}
+
+	/* let FLR complete ... */
+	msleep(100);
+
 	/* FLR cleanup epilogue */
 	if (bnx2x_vf_flr_clnup_epilog(bp, vf->abs_vfid))
 		return -EBUSY;
@@ -2890,7 +2889,7 @@ int bnx2x_vfop_close_cmd(struct bnx2x *b
 	return -ENOMEM;
 }
 
-/* VF release can be called either: 1. the VF was acquired but
+/* VF release can be called either: 1. The VF was acquired but
  * not enabled 2. the vf was enabled or in the process of being
  * enabled
  */
@@ -3024,7 +3023,6 @@ void bnx2x_unlock_vf_pf_channel(struct b
 
 int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs_param)
 {
-
 	struct bnx2x *bp = netdev_priv(pci_get_drvdata(dev));
 
 	DP(BNX2X_MSG_IOV, "bnx2x_sriov_configure called with %d, BNX2X_NR_VIRTFN(bp) was %d\n",
@@ -3032,7 +3030,7 @@ int bnx2x_sriov_configure(struct pci_dev
 
 	/* HW channel is only operational when PF is up */
 	if (bp->state != BNX2X_STATE_OPEN) {
-		BNX2X_ERR("VF num configurtion via sysfs not supported while PF is down");
+		BNX2X_ERR("VF num configuration via sysfs not supported while PF is down\n");
 		return -EINVAL;
 	}
 
@@ -3083,9 +3081,15 @@ void bnx2x_disable_sriov(struct bnx2x *b
 	pci_disable_sriov(bp->pdev);
 }
 
-static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx,
-			       struct bnx2x_virtf *vf)
+static int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx,
+			     struct bnx2x_virtf **vf,
+			     struct pf_vf_bulletin_content **bulletin)
 {
+	if (bp->state != BNX2X_STATE_OPEN) {
+		BNX2X_ERR("vf ndo called though PF is down\n");
+		return -EINVAL;
+	}
+
 	if (!IS_SRIOV(bp)) {
 		BNX2X_ERR("vf ndo called though sriov is disabled\n");
 		return -EINVAL;
@@ -3097,12 +3101,22 @@ static int bnx2x_vf_ndo_sanity(struct bn
 		return -EINVAL;
 	}
 
-	if (!vf) {
+	/* init members */
+	*vf = BP_VF(bp, vfidx);
+	*bulletin = BP_VF_BULLETIN(bp, vfidx);
+
+	if (!*vf) {
 		BNX2X_ERR("vf ndo called but vf was null. vfidx was %d\n",
 			  vfidx);
 		return -EINVAL;
 	}
 
+	if (!*bulletin) {
+		BNX2X_ERR("vf ndo called but Bulletin Board struct is null. vfidx was %d\n",
+			  vfidx);
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
@@ -3110,17 +3124,19 @@ int bnx2x_get_vf_config(struct net_devic
 			struct ifla_vf_info *ivi)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
-	struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj);
-	struct bnx2x_vlan_mac_obj *vlan_obj = &bnx2x_vfq(vf, 0, vlan_obj);
-	struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
+	struct bnx2x_virtf *vf = NULL;
+	struct pf_vf_bulletin_content *bulletin = NULL;
+	struct bnx2x_vlan_mac_obj *mac_obj;
+	struct bnx2x_vlan_mac_obj *vlan_obj;
 	int rc;
 
-	/* sanity */
-	rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
+	/* sanity and init */
+	rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin);
 	if (rc)
 		return rc;
-	if (!mac_obj || !vlan_obj || !bulletin) {
+	mac_obj = &bnx2x_vfq(vf, 0, mac_obj);
+	vlan_obj = &bnx2x_vfq(vf, 0, vlan_obj);
+	if (!mac_obj || !vlan_obj) {
 		BNX2X_ERR("VF partially initialized\n");
 		return -EINVAL;
 	}
@@ -3141,7 +3157,7 @@ int bnx2x_get_vf_config(struct net_devic
 			/* mac configured by ndo so its in bulletin board */
 			memcpy(&ivi->mac, bulletin->mac, ETH_ALEN);
 		else
-			/* funtion has not been loaded yet. Show mac as 0s */
+			/* function has not been loaded yet. Show mac as 0s */
 			memset(&ivi->mac, 0, ETH_ALEN);
 
 		/* vlan */
@@ -3149,7 +3165,7 @@ int bnx2x_get_vf_config(struct net_devic
 			/* vlan configured by ndo so its in bulletin board */
 			memcpy(&ivi->vlan, &bulletin->vlan, VLAN_HLEN);
 		else
-			/* funtion has not been loaded yet. Show vlans as 0s */
+			/* function has not been loaded yet. Show vlans as 0s */
 			memset(&ivi->vlan, 0, VLAN_HLEN);
 	}
 
@@ -3177,11 +3193,11 @@ int bnx2x_set_vf_mac(struct net_device *
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	int rc, q_logical_state;
-	struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
-	struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
+	struct bnx2x_virtf *vf = NULL;
+	struct pf_vf_bulletin_content *bulletin = NULL;
 
-	/* sanity */
-	rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
+	/* sanity and init */
+	rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin);
 	if (rc)
 		return rc;
 	if (!is_valid_ether_addr(mac)) {
@@ -3189,7 +3205,7 @@ int bnx2x_set_vf_mac(struct net_device *
 		return -EINVAL;
 	}
 
-	/* update PF's copy of the VF's bulletin. will no longer accept mac
+	/* update PF's copy of the VF's bulletin. Will no longer accept mac
 	 * configuration requests from vf unless match this mac
 	 */
 	bulletin->valid_bitmap |= 1 << MAC_ADDR_VALID;
@@ -3243,11 +3259,11 @@ int bnx2x_set_vf_vlan(struct net_device
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	int rc, q_logical_state;
-	struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
-	struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
+	struct bnx2x_virtf *vf = NULL;
+	struct pf_vf_bulletin_content *bulletin = NULL;
 
-	/* sanity */
-	rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
+	/* sanity and init */
+	rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin);
 	if (rc)
 		return rc;
 
@@ -3358,8 +3374,11 @@ int bnx2x_set_vf_vlan(struct net_device
 	return 0;
 }
 
-/* crc is the first field in the bulletin board. compute the crc over the
- * entire bulletin board excluding the crc field itself
+/* crc is the first field in the bulletin board. Compute the crc over the
+ * entire bulletin board excluding the crc field itself. Use the length field
+ * as the Bulletin Board was posted by a PF with possibly a different version
+ * from the vf which will sample it. Therefore, the length is computed by the
+ * PF and the used blindly by the VF.
  */
 u32 bnx2x_crc_vf_bulletin(struct bnx2x *bp,
 			  struct pf_vf_bulletin_content *bulletin)
@@ -3389,7 +3408,7 @@ enum sample_bulletin_result bnx2x_sample
 			if (bulletin.crc == bnx2x_crc_vf_bulletin(bp,
 								  &bulletin))
 				break;
-			BNX2X_ERR("bad crc on bulletin board. contained %x computed %x\n",
+			BNX2X_ERR("bad crc on bulletin board. Contained %x computed %x\n",
 				  bulletin.crc,
 				  bnx2x_crc_vf_bulletin(bp, &bulletin));
 		}
@@ -3417,6 +3436,20 @@ enum sample_bulletin_result bnx2x_sample
 	return PFVF_BULLETIN_UPDATED;
 }
 
+void bnx2x_timer_sriov(struct bnx2x *bp)
+{
+	bnx2x_sample_bulletin(bp);
+
+	/* if channel is down we need to self destruct */
+	if (bp->old_bulletin.valid_bitmap & 1 << CHANNEL_DOWN) {
+		smp_mb__before_clear_bit();
+		set_bit(BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
+			&bp->sp_rtnl_state);
+		smp_mb__after_clear_bit();
+		schedule_delayed_work(&bp->sp_rtnl_task, 0);
+	}
+}
+
 void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp)
 {
 	/* vf doorbells are embedded within the regview */
@@ -3440,7 +3473,7 @@ int bnx2x_vf_pci_alloc(struct bnx2x *bp)
 alloc_mem_err:
 	BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping,
 		       sizeof(struct bnx2x_vf_mbx_msg));
-	BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping,
+	BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->pf2vf_bulletin_mapping,
 		       sizeof(union pf_vf_bulletin));
 	return -ENOMEM;
 }
@@ -3452,7 +3485,7 @@ int bnx2x_open_epilog(struct bnx2x *bp)
 	 * register_netdevice which must have rtnl lock taken. As we are holding
 	 * the lock right now, that could only work if the probe would not take
 	 * the lock. However, as the probe of the vf may be called from other
-	 * contexts as well (such as passthrough to vm failes) it can't assume
+	 * contexts as well (such as passthrough to vm fails) it can't assume
 	 * the lock is being held for it. Using delayed work here allows the
 	 * probe code to simply take the lock (i.e. wait for it to be released
 	 * if it is being held). We only want to do this if the number of VFs
@@ -3467,3 +3500,23 @@ int bnx2x_open_epilog(struct bnx2x *bp)
 
 	return 0;
 }
+
+void bnx2x_iov_channel_down(struct bnx2x *bp)
+{
+	int vf_idx;
+	struct pf_vf_bulletin_content *bulletin;
+
+	if (!IS_SRIOV(bp))
+		return;
+
+	for_each_vf(bp, vf_idx) {
+		/* locate this VFs bulletin board and update the channel down
+		 * bit
+		 */
+		bulletin = BP_VF_BULLETIN(bp, vf_idx);
+		bulletin->valid_bitmap |= 1 << CHANNEL_DOWN;
+
+		/* update vf bulletin board */
+		bnx2x_post_vf_bulletin(bp, vf_idx);
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h	2013-08-25 20:43:22.000000000 -0400
@@ -197,7 +197,7 @@ struct bnx2x_virtf {
 
 	u8 state;
 #define VF_FREE		0	/* VF ready to be acquired holds no resc */
-#define VF_ACQUIRED	1	/* VF aquired, but not initalized */
+#define VF_ACQUIRED	1	/* VF acquired, but not initialized */
 #define VF_ENABLED	2	/* VF Enabled */
 #define VF_RESET	3	/* VF FLR'd, pending cleanup */
 
@@ -496,7 +496,7 @@ enum {
 		else if ((next) == VFOP_VERIFY_PEND)			\
 			BNX2X_ERR("expected pending\n");		\
 		else {							\
-			DP(BNX2X_MSG_IOV, "no ramrod. scheduling\n");	\
+			DP(BNX2X_MSG_IOV, "no ramrod. Scheduling\n");	\
 			atomic_set(&vf->op_in_progress, 1);		\
 			queue_delayed_work(bnx2x_wq, &bp->sp_task, 0);  \
 			return;						\
@@ -722,7 +722,6 @@ u32 bnx2x_crc_vf_bulletin(struct bnx2x *
 			  struct pf_vf_bulletin_content *bulletin);
 int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf);
 
-
 enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp);
 
 /* VF side vfpf channel functions */
@@ -752,6 +751,7 @@ static inline int bnx2x_vf_ustorm_prods_
 }
 
 enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp);
+void bnx2x_timer_sriov(struct bnx2x *bp);
 void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp);
 int bnx2x_vf_pci_alloc(struct bnx2x *bp);
 int bnx2x_enable_sriov(struct bnx2x *bp);
@@ -762,6 +762,7 @@ static inline int bnx2x_vf_headroom(stru
 }
 void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp);
 int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs);
+void bnx2x_iov_channel_down(struct bnx2x *bp);
 int bnx2x_open_epilog(struct bnx2x *bp);
 
 #else /* CONFIG_BNX2X_SRIOV */
@@ -809,6 +810,7 @@ static inline enum sample_bulletin_resul
 {
 	return PFVF_BULLETIN_UNCHANGED;
 }
+static inline void bnx2x_timer_sriov(struct bnx2x *bp) {}
 
 static inline void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp)
 {
@@ -818,6 +820,7 @@ static inline void __iomem *bnx2x_vf_doo
 static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; }
 static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {}
 static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; }
+static inline void bnx2x_iov_channel_down(struct bnx2x *bp) {}
 static inline int bnx2x_open_epilog(struct bnx2x *bp) {return 0; }
 
 #endif /* CONFIG_BNX2X_SRIOV */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c	2013-08-25 20:43:22.000000000 -0400
@@ -221,7 +221,8 @@ static int bnx2x_stats_comp(struct bnx2x
  * Statistics service functions
  */
 
-static void bnx2x_stats_pmf_update(struct bnx2x *bp)
+/* should be called under stats_sema */
+static void __bnx2x_stats_pmf_update(struct bnx2x *bp)
 {
 	struct dmae_command *dmae;
 	u32 opcode;
@@ -518,7 +519,8 @@ static void bnx2x_func_stats_init(struct
 	*stats_comp = 0;
 }
 
-static void bnx2x_stats_start(struct bnx2x *bp)
+/* should be called under stats_sema */
+static void __bnx2x_stats_start(struct bnx2x *bp)
 {
 	/* vfs travel through here as part of the statistics FSM, but no action
 	 * is required
@@ -534,13 +536,34 @@ static void bnx2x_stats_start(struct bnx
 
 	bnx2x_hw_stats_post(bp);
 	bnx2x_storm_stats_post(bp);
+
+	bp->stats_started = true;
+}
+
+static void bnx2x_stats_start(struct bnx2x *bp)
+{
+	if (down_timeout(&bp->stats_sema, HZ/10))
+		BNX2X_ERR("Unable to acquire stats lock\n");
+	__bnx2x_stats_start(bp);
+	up(&bp->stats_sema);
 }
 
 static void bnx2x_stats_pmf_start(struct bnx2x *bp)
 {
+	if (down_timeout(&bp->stats_sema, HZ/10))
+		BNX2X_ERR("Unable to acquire stats lock\n");
 	bnx2x_stats_comp(bp);
-	bnx2x_stats_pmf_update(bp);
-	bnx2x_stats_start(bp);
+	__bnx2x_stats_pmf_update(bp);
+	__bnx2x_stats_start(bp);
+	up(&bp->stats_sema);
+}
+
+static void bnx2x_stats_pmf_update(struct bnx2x *bp)
+{
+	if (down_timeout(&bp->stats_sema, HZ/10))
+		BNX2X_ERR("Unable to acquire stats lock\n");
+	__bnx2x_stats_pmf_update(bp);
+	up(&bp->stats_sema);
 }
 
 static void bnx2x_stats_restart(struct bnx2x *bp)
@@ -550,8 +573,11 @@ static void bnx2x_stats_restart(struct b
 	 */
 	if (IS_VF(bp))
 		return;
+	if (down_timeout(&bp->stats_sema, HZ/10))
+		BNX2X_ERR("Unable to acquire stats lock\n");
 	bnx2x_stats_comp(bp);
-	bnx2x_stats_start(bp);
+	__bnx2x_stats_start(bp);
+	up(&bp->stats_sema);
 }
 
 static void bnx2x_bmac_stats_update(struct bnx2x *bp)
@@ -888,9 +914,7 @@ static int bnx2x_storm_stats_validate_co
 	/* Make sure we use the value of the counter
 	 * used for sending the last stats ramrod.
 	 */
-	spin_lock_bh(&bp->stats_lock);
 	cur_stats_counter = bp->stats_counter - 1;
-	spin_unlock_bh(&bp->stats_lock);
 
 	/* are storm stats valid? */
 	if (le16_to_cpu(counters->xstats_counter) != cur_stats_counter) {
@@ -1002,7 +1026,6 @@ static int bnx2x_storm_stats_update(stru
 		qstats->valid_bytes_received_lo =
 					qstats->total_bytes_received_lo;
 
-
 		UPDATE_EXTEND_TSTAT(rcv_ucast_pkts,
 					total_unicast_packets_received);
 		UPDATE_EXTEND_TSTAT(rcv_mcast_pkts,
@@ -1228,12 +1251,18 @@ static void bnx2x_stats_update(struct bn
 {
 	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
 
-	if (bnx2x_edebug_stats_stopped(bp))
+	/* we run update from timer context, so give up
+	 * if somebody is in the middle of transition
+	 */
+	if (down_trylock(&bp->stats_sema))
 		return;
 
+	if (bnx2x_edebug_stats_stopped(bp) || !bp->stats_started)
+		goto out;
+
 	if (IS_PF(bp)) {
 		if (*stats_comp != DMAE_COMP_VAL)
-			return;
+			goto out;
 
 		if (bp->port.pmf)
 			bnx2x_hw_stats_update(bp);
@@ -1243,7 +1272,7 @@ static void bnx2x_stats_update(struct bn
 				BNX2X_ERR("storm stats were not updated for 3 times\n");
 				bnx2x_panic();
 			}
-			return;
+			goto out;
 		}
 	} else {
 		/* vf doesn't collect HW statistics, and doesn't get completions
@@ -1257,7 +1286,7 @@ static void bnx2x_stats_update(struct bn
 
 	/* vf is done */
 	if (IS_VF(bp))
-		return;
+		goto out;
 
 	if (netif_msg_timer(bp)) {
 		struct bnx2x_eth_stats *estats = &bp->eth_stats;
@@ -1268,6 +1297,9 @@ static void bnx2x_stats_update(struct bn
 
 	bnx2x_hw_stats_post(bp);
 	bnx2x_storm_stats_post(bp);
+
+out:
+	up(&bp->stats_sema);
 }
 
 static void bnx2x_port_stats_stop(struct bnx2x *bp)
@@ -1333,6 +1365,11 @@ static void bnx2x_stats_stop(struct bnx2
 {
 	int update = 0;
 
+	if (down_timeout(&bp->stats_sema, HZ/10))
+		BNX2X_ERR("Unable to acquire stats lock\n");
+
+	bp->stats_started = false;
+
 	bnx2x_stats_comp(bp);
 
 	if (bp->port.pmf)
@@ -1349,6 +1386,8 @@ static void bnx2x_stats_stop(struct bnx2
 		bnx2x_hw_stats_post(bp);
 		bnx2x_stats_comp(bp);
 	}
+
+	up(&bp->stats_sema);
 }
 
 static void bnx2x_stats_do_nothing(struct bnx2x *bp)
@@ -1377,15 +1416,17 @@ static const struct {
 void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
 {
 	enum bnx2x_stats_state state;
+	void (*action)(struct bnx2x *bp);
 	if (unlikely(bp->panic))
 		return;
 
 	spin_lock_bh(&bp->stats_lock);
 	state = bp->stats_state;
 	bp->stats_state = bnx2x_stats_stm[state][event].next_state;
+	action = bnx2x_stats_stm[state][event].action;
 	spin_unlock_bh(&bp->stats_lock);
 
-	bnx2x_stats_stm[state][event].action(bp);
+	action(bp);
 
 	if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp))
 		DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h	2013-08-25 20:43:22.000000000 -0400
@@ -40,7 +40,6 @@ struct nig_stats {
 	u32 egress_mac_pkt1_hi;
 };
 
-
 enum bnx2x_stats_event {
 	STATS_EVENT_PMF = 0,
 	STATS_EVENT_LINK_UP,
@@ -208,7 +207,6 @@ struct bnx2x_eth_stats {
 	u32 eee_tx_lpi;
 };
 
-
 struct bnx2x_eth_q_stats {
 	u32 total_unicast_bytes_received_hi;
 	u32 total_unicast_bytes_received_lo;
@@ -331,7 +329,6 @@ struct bnx2x_fw_port_stats_old {
 	 u32 mac_discard;
 };
 
-
 /****************************************************************************
 * Macros
 ****************************************************************************/
@@ -536,7 +533,6 @@ struct bnx2x_fw_port_stats_old {
 		SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
 	} while (0)
 
-
 /* forward */
 struct bnx2x;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c	2013-08-25 20:43:22.000000000 -0400
@@ -113,7 +113,7 @@ static int bnx2x_send_msg2pf(struct bnx2
 {
 	struct cstorm_vf_zone_data __iomem *zone_data =
 		REG_ADDR(bp, PXP_VF_ADDR_CSDM_GLOBAL_START);
-	int tout = 600, interval = 100; /* wait for 60 seconds */
+	int tout = 100, interval = 100; /* wait for 10 seconds */
 
 	if (*done) {
 		BNX2X_ERR("done was non zero before message to pf was sent\n");
@@ -121,6 +121,16 @@ static int bnx2x_send_msg2pf(struct bnx2
 		return -EINVAL;
 	}
 
+	/* if PF indicated channel is down avoid sending message. Return success
+	 * so calling flow can continue
+	 */
+	bnx2x_sample_bulletin(bp);
+	if (bp->old_bulletin.valid_bitmap & 1 << CHANNEL_DOWN) {
+		DP(BNX2X_MSG_IOV, "detecting channel down. Aborting message\n");
+		*done = PFVF_STATUS_SUCCESS;
+		return 0;
+	}
+
 	/* Write message address */
 	writel(U64_LO(msg_mapping),
 	       &zone_data->non_trigger.vf_pf_channel.msg_addr_lo);
@@ -233,7 +243,7 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp,
 
 		attempts++;
 
-		/* test whether the PF accepted our request. If not, humble the
+		/* test whether the PF accepted our request. If not, humble
 		 * the request and try again.
 		 */
 		if (bp->acquire_resp.hdr.status == PFVF_STATUS_SUCCESS) {
@@ -333,7 +343,7 @@ int bnx2x_vfpf_release(struct bnx2x *bp)
 		DP(BNX2X_MSG_SP, "vf released\n");
 	} else {
 		/* PF reports error */
-		BNX2X_ERR("PF failed our release request - are we out of sync? response status: %d\n",
+		BNX2X_ERR("PF failed our release request - are we out of sync? Response status: %d\n",
 			  resp->hdr.status);
 		rc = -EAGAIN;
 		goto out;
@@ -787,7 +797,7 @@ static inline void bnx2x_set_vf_mbxs_val
 		storm_memset_vf_mbx_valid(bp, bnx2x_vf(bp, i, abs_vfid));
 }
 
-/* enable vf_pf mailbox (aka vf-pf-chanell) */
+/* enable vf_pf mailbox (aka vf-pf-channel) */
 void bnx2x_vf_enable_mbx(struct bnx2x *bp, u8 abs_vfid)
 {
 	bnx2x_vf_flr_clnup_epilog(bp, abs_vfid);
@@ -844,7 +854,6 @@ static int bnx2x_copy32_vf_dmae(struct b
 		dmae.dst_addr_hi = vf_addr_hi;
 	}
 	dmae.len = len32;
-	bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_DMAE);
 
 	/* issue the command and wait for completion */
 	return bnx2x_issue_dmae_with_comp(bp, &dmae);
@@ -1072,7 +1081,7 @@ static void bnx2x_vf_mbx_set_q_flags(str
 	if (mbx_q_flags & VFPF_QUEUE_FLG_DHC)
 		__set_bit(BNX2X_Q_FLG_DHC, sp_q_flags);
 
-	/* outer vlan removal is set according to the PF's multi fuction mode */
+	/* outer vlan removal is set according to PF's multi function mode */
 	if (IS_MF_SD(bp))
 		__set_bit(BNX2X_Q_FLG_OV, sp_q_flags);
 }
@@ -1104,7 +1113,7 @@ static void bnx2x_vf_mbx_setup_q(struct
 		struct bnx2x_queue_init_params *init_p;
 		struct bnx2x_queue_setup_params *setup_p;
 
-		/* reinit the VF operation context */
+		/* re-init the VF operation context */
 		memset(&vf->op_params.qctor, 0 , sizeof(vf->op_params.qctor));
 		setup_p = &vf->op_params.qctor.prep_qsetup;
 		init_p =  &vf->op_params.qctor.qstate.params.init;
@@ -1588,8 +1597,9 @@ static void bnx2x_vf_mbx_request(struct
 		 * support them. Or this may be because someone wrote a crappy
 		 * VF driver and is sending garbage over the channel.
 		 */
-		BNX2X_ERR("unknown TLV. type %d length %d. first 20 bytes of mailbox buffer:\n",
-			  mbx->first_tlv.tl.type, mbx->first_tlv.tl.length);
+		BNX2X_ERR("unknown TLV. type %d length %d vf->state was %d. first 20 bytes of mailbox buffer:\n",
+			  mbx->first_tlv.tl.type, mbx->first_tlv.tl.length,
+			  vf->state);
 		for (i = 0; i < 20; i++)
 			DP_CONT(BNX2X_MSG_IOV, "%x ",
 				mbx->msg->req.tlv_buf_size.tlv_buffer[i]);
@@ -1605,8 +1615,11 @@ static void bnx2x_vf_mbx_request(struct
 			bnx2x_vf_mbx_resp(bp, vf);
 		} else {
 			/* can't send a response since this VF is unknown to us
-			 * just unlock the channel and be done with.
+			 * just ack the FW to release the mailbox and unlock
+			 * the channel.
 			 */
+			storm_memset_vf_mbx_ack(bp, vf->abs_vfid);
+			mmiowb();
 			bnx2x_unlock_vf_pf_channel(bp, vf,
 						   mbx->first_tlv.tl.type);
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h	2013-08-25 20:43:22.000000000 -0400
@@ -331,7 +331,10 @@ struct pf_vf_bulletin_content {
 #define VLAN_VALID		1	/* when set, the vf should not access
 					 * the vfpf channel
 					 */
-
+#define CHANNEL_DOWN		2	/* vfpf channel is disabled. VFs are not
+					 * to attempt to send messages on the
+					 * channel after this bit is set
+					 */
 	u8 mac[ETH_ALEN];
 	u8 mac_padding[2];
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/cnic.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/cnic.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/cnic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/cnic.c	2013-08-25 20:43:22.000000000 -0400
@@ -5622,7 +5622,7 @@ static void cnic_rcv_netevent(struct cni
 static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
 							 void *ptr)
 {
-	struct net_device *netdev = ptr;
+	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
 	struct cnic_dev *dev;
 	int new_dev = 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@ config B44
 	tristate "Broadcom 440x/47xx ethernet support"
 	depends on SSB_POSSIBLE && HAS_DMA
 	select SSB
-	select NET_CORE
 	select MII
 	---help---
 	  If you have a network (Ethernet) controller of this type, say Y
@@ -54,7 +53,6 @@ config B44_PCI
 config BCM63XX_ENET
 	tristate "Broadcom 63xx internal mac support"
 	depends on BCM63XX
-	select NET_CORE
 	select MII
 	select PHYLIB
 	help
@@ -133,6 +131,7 @@ config BNX2X_SRIOV
 config BGMAC
 	tristate "BCMA bus GBit core support"
 	depends on BCMA_HOST_SOC && HAS_DMA
+	select PHYLIB
 	---help---
 	  This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus.
 	  They can be found on BCM47xx SoCs and provide gigabit ethernet.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/sb1250-mac.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/sb1250-mac.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/sb1250-mac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/sb1250-mac.c	2013-08-25 20:43:22.000000000 -0400
@@ -2197,7 +2197,7 @@ static const struct net_device_ops sbmac
 
 static int sbmac_init(struct platform_device *pldev, long long base)
 {
-	struct net_device *dev = dev_get_drvdata(&pldev->dev);
+	struct net_device *dev = platform_get_drvdata(pldev);
 	int idx = pldev->id;
 	struct sbmac_softc *sc = netdev_priv(dev);
 	unsigned char *eaddr;
@@ -2275,7 +2275,7 @@ static int sbmac_init(struct platform_de
 		       dev->name);
 		goto free_mdio;
 	}
-	dev_set_drvdata(&pldev->dev, sc->mii_bus);
+	platform_set_drvdata(pldev, sc->mii_bus);
 
 	err = register_netdev(dev);
 	if (err) {
@@ -2300,7 +2300,6 @@ static int sbmac_init(struct platform_de
 	return 0;
 unreg_mdio:
 	mdiobus_unregister(sc->mii_bus);
-	dev_set_drvdata(&pldev->dev, NULL);
 free_mdio:
 	mdiobus_free(sc->mii_bus);
 uninit_ctx:
@@ -2624,7 +2623,7 @@ static int sbmac_probe(struct platform_d
 		goto out_unmap;
 	}
 
-	dev_set_drvdata(&pldev->dev, dev);
+	platform_set_drvdata(pldev, dev);
 	SET_NETDEV_DEV(dev, &pldev->dev);
 
 	sc = netdev_priv(dev);
@@ -2649,7 +2648,7 @@ out_out:
 
 static int __exit sbmac_remove(struct platform_device *pldev)
 {
-	struct net_device *dev = dev_get_drvdata(&pldev->dev);
+	struct net_device *dev = platform_get_drvdata(pldev);
 	struct sbmac_softc *sc = netdev_priv(dev);
 
 	unregister_netdev(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/tg3.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/tg3.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/tg3.c	2013-07-01 10:37:30.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/tg3.c	2013-08-31 17:57:03.000000000 -0400
@@ -959,9 +959,6 @@ static void tg3_ape_driver_state_change(
 
 		event = APE_EVENT_STATUS_STATE_UNLOAD;
 		break;
-	case RESET_KIND_SUSPEND:
-		event = APE_EVENT_STATUS_STATE_SUSPEND;
-		break;
 	default:
 		return;
 	}
@@ -1308,8 +1305,8 @@ static int tg3_phy_toggle_auxctl_smdsp(s
 
 	if (err)
 		return err;
-	if (enable)
 
+	if (enable)
 		val |= MII_TG3_AUXCTL_ACTL_SMDSP_ENA;
 	else
 		val &= ~MII_TG3_AUXCTL_ACTL_SMDSP_ENA;
@@ -1736,10 +1733,6 @@ static void tg3_write_sig_pre_reset(stru
 			break;
 		}
 	}
-
-	if (kind == RESET_KIND_INIT ||
-	    kind == RESET_KIND_SUSPEND)
-		tg3_ape_driver_state_change(tp, kind);
 }
 
 /* tp->lock is held. */
@@ -1761,9 +1754,6 @@ static void tg3_write_sig_post_reset(str
 			break;
 		}
 	}
-
-	if (kind == RESET_KIND_SHUTDOWN)
-		tg3_ape_driver_state_change(tp, kind);
 }
 
 /* tp->lock is held. */
@@ -2332,6 +2322,46 @@ static void tg3_phy_apply_otp(struct tg3
 	tg3_phy_toggle_auxctl_smdsp(tp, false);
 }
 
+static void tg3_eee_pull_config(struct tg3 *tp, struct ethtool_eee *eee)
+{
+	u32 val;
+	struct ethtool_eee *dest = &tp->eee;
+
+	if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP))
+		return;
+
+	if (eee)
+		dest = eee;
+
+	if (tg3_phy_cl45_read(tp, MDIO_MMD_AN, TG3_CL45_D7_EEERES_STAT, &val))
+		return;
+
+	/* Pull eee_active */
+	if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T ||
+	    val == TG3_CL45_D7_EEERES_STAT_LP_100TX) {
+		dest->eee_active = 1;
+	} else
+		dest->eee_active = 0;
+
+	/* Pull lp advertised settings */
+	if (tg3_phy_cl45_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE, &val))
+		return;
+	dest->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
+
+	/* Pull advertised and eee_enabled settings */
+	if (tg3_phy_cl45_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, &val))
+		return;
+	dest->eee_enabled = !!val;
+	dest->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
+
+	/* Pull tx_lpi_enabled */
+	val = tr32(TG3_CPMU_EEE_MODE);
+	dest->tx_lpi_enabled = !!(val & TG3_CPMU_EEEMD_LPI_IN_TX);
+
+	/* Pull lpi timer value */
+	dest->tx_lpi_timer = tr32(TG3_CPMU_EEE_DBTMR1) & 0xffff;
+}
+
 static void tg3_phy_eee_adjust(struct tg3 *tp, bool current_link_up)
 {
 	u32 val;
@@ -2355,11 +2385,8 @@ static void tg3_phy_eee_adjust(struct tg
 
 		tw32(TG3_CPMU_EEE_CTRL, eeectl);
 
-		tg3_phy_cl45_read(tp, MDIO_MMD_AN,
-				  TG3_CL45_D7_EEERES_STAT, &val);
-
-		if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T ||
-		    val == TG3_CL45_D7_EEERES_STAT_LP_100TX)
+		tg3_eee_pull_config(tp, NULL);
+		if (tp->eee.eee_active)
 			tp->setlpicnt = 2;
 	}
 
@@ -4183,6 +4210,8 @@ static int tg3_power_down_prepare(struct
 
 	tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
 
+	tg3_ape_driver_state_change(tp, RESET_KIND_SHUTDOWN);
+
 	return 0;
 }
 
@@ -4283,6 +4312,16 @@ static int tg3_phy_autoneg_cfg(struct tg
 		/* Advertise 1000-BaseT EEE ability */
 		if (advertise & ADVERTISED_1000baseT_Full)
 			val |= MDIO_AN_EEE_ADV_1000T;
+
+		if (!tp->eee.eee_enabled) {
+			val = 0;
+			tp->eee.advertised = 0;
+		} else {
+			tp->eee.advertised = advertise &
+					     (ADVERTISED_100baseT_Full |
+					      ADVERTISED_1000baseT_Full);
+		}
+
 		err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
 		if (err)
 			val = 0;
@@ -4527,26 +4566,23 @@ static int tg3_init_5401phy_dsp(struct t
 
 static bool tg3_phy_eee_config_ok(struct tg3 *tp)
 {
-	u32 val;
-	u32 tgtadv = 0;
-	u32 advertising = tp->link_config.advertising;
+	struct ethtool_eee eee;
 
 	if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP))
 		return true;
 
-	if (tg3_phy_cl45_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, &val))
-		return false;
-
-	val &= (MDIO_AN_EEE_ADV_100TX | MDIO_AN_EEE_ADV_1000T);
-
-
-	if (advertising & ADVERTISED_100baseT_Full)
-		tgtadv |= MDIO_AN_EEE_ADV_100TX;
-	if (advertising & ADVERTISED_1000baseT_Full)
-		tgtadv |= MDIO_AN_EEE_ADV_1000T;
+	tg3_eee_pull_config(tp, &eee);
 
-	if (val != tgtadv)
-		return false;
+	if (tp->eee.eee_enabled) {
+		if (tp->eee.advertised != eee.advertised ||
+		    tp->eee.tx_lpi_timer != eee.tx_lpi_timer ||
+		    tp->eee.tx_lpi_enabled != eee.tx_lpi_enabled)
+			return false;
+	} else {
+		/* EEE is disabled but we're advertising */
+		if (eee.advertised)
+			return false;
+	}
 
 	return true;
 }
@@ -4647,6 +4683,42 @@ static void tg3_clear_mac_status(struct
 	udelay(40);
 }
 
+static void tg3_setup_eee(struct tg3 *tp)
+{
+	u32 val;
+
+	val = TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
+	      TG3_CPMU_EEE_LNKIDL_UART_IDL;
+	if (tg3_chip_rev_id(tp) == CHIPREV_ID_57765_A0)
+		val |= TG3_CPMU_EEE_LNKIDL_APE_TX_MT;
+
+	tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, val);
+
+	tw32_f(TG3_CPMU_EEE_CTRL,
+	       TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
+
+	val = TG3_CPMU_EEEMD_ERLY_L1_XIT_DET |
+	      (tp->eee.tx_lpi_enabled ? TG3_CPMU_EEEMD_LPI_IN_TX : 0) |
+	      TG3_CPMU_EEEMD_LPI_IN_RX |
+	      TG3_CPMU_EEEMD_EEE_ENABLE;
+
+	if (tg3_asic_rev(tp) != ASIC_REV_5717)
+		val |= TG3_CPMU_EEEMD_SND_IDX_DET_EN;
+
+	if (tg3_flag(tp, ENABLE_APE))
+		val |= TG3_CPMU_EEEMD_APE_TX_DET_EN;
+
+	tw32_f(TG3_CPMU_EEE_MODE, tp->eee.eee_enabled ? val : 0);
+
+	tw32_f(TG3_CPMU_EEE_DBTMR1,
+	       TG3_CPMU_DBTMR1_PCIEXIT_2047US |
+	       (tp->eee.tx_lpi_timer & 0xffff));
+
+	tw32_f(TG3_CPMU_EEE_DBTMR2,
+	       TG3_CPMU_DBTMR2_APE_TX_2047US |
+	       TG3_CPMU_DBTMR2_TXIDXEQ_2047US);
+}
+
 static int tg3_setup_copper_phy(struct tg3 *tp, bool force_reset)
 {
 	bool current_link_up;
@@ -4813,8 +4885,10 @@ static int tg3_setup_copper_phy(struct t
 			 */
 			if (!eee_config_ok &&
 			    (tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN) &&
-			    !force_reset)
+			    !force_reset) {
+				tg3_setup_eee(tp);
 				tg3_phy_reset(tp);
+			}
 		} else {
 			if (!(bmcr & BMCR_ANENABLE) &&
 			    tp->link_config.speed == current_speed &&
@@ -6326,9 +6400,7 @@ static void tg3_tx_recover(struct tg3 *t
 		    "Please report the problem to the driver maintainer "
 		    "and include system chipset information.\n");
 
-	spin_lock(&tp->lock);
 	tg3_flag_set(tp, TX_RECOVERY_PENDING);
-	spin_unlock(&tp->lock);
 }
 
 static inline u32 tg3_tx_avail(struct tg3_napi *tnapi)
@@ -9196,11 +9268,9 @@ static void __tg3_set_coalesce(struct tg
 }
 
 /* tp->lock is held. */
-static void tg3_rings_reset(struct tg3 *tp)
+static void tg3_tx_rcbs_disable(struct tg3 *tp)
 {
-	int i;
-	u32 stblk, txrcb, rxrcb, limit;
-	struct tg3_napi *tnapi = &tp->napi[0];
+	u32 txrcb, limit;
 
 	/* Disable all transmit rings but the first. */
 	if (!tg3_flag(tp, 5705_PLUS))
@@ -9217,7 +9287,33 @@ static void tg3_rings_reset(struct tg3 *
 	     txrcb < limit; txrcb += TG3_BDINFO_SIZE)
 		tg3_write_mem(tp, txrcb + TG3_BDINFO_MAXLEN_FLAGS,
 			      BDINFO_FLAGS_DISABLED);
+}
 
+/* tp->lock is held. */
+static void tg3_tx_rcbs_init(struct tg3 *tp)
+{
+	int i = 0;
+	u32 txrcb = NIC_SRAM_SEND_RCB;
+
+	if (tg3_flag(tp, ENABLE_TSS))
+		i++;
+
+	for (; i < tp->irq_max; i++, txrcb += TG3_BDINFO_SIZE) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+
+		if (!tnapi->tx_ring)
+			continue;
+
+		tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
+			       (TG3_TX_RING_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT),
+			       NIC_SRAM_TX_BUFFER_DESC);
+	}
+}
+
+/* tp->lock is held. */
+static void tg3_rx_ret_rcbs_disable(struct tg3 *tp)
+{
+	u32 rxrcb, limit;
 
 	/* Disable all receive return rings but the first. */
 	if (tg3_flag(tp, 5717_PLUS))
@@ -9235,6 +9331,39 @@ static void tg3_rings_reset(struct tg3 *
 	     rxrcb < limit; rxrcb += TG3_BDINFO_SIZE)
 		tg3_write_mem(tp, rxrcb + TG3_BDINFO_MAXLEN_FLAGS,
 			      BDINFO_FLAGS_DISABLED);
+}
+
+/* tp->lock is held. */
+static void tg3_rx_ret_rcbs_init(struct tg3 *tp)
+{
+	int i = 0;
+	u32 rxrcb = NIC_SRAM_RCV_RET_RCB;
+
+	if (tg3_flag(tp, ENABLE_RSS))
+		i++;
+
+	for (; i < tp->irq_max; i++, rxrcb += TG3_BDINFO_SIZE) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+
+		if (!tnapi->rx_rcb)
+			continue;
+
+		tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
+			       (tp->rx_ret_ring_mask + 1) <<
+				BDINFO_FLAGS_MAXLEN_SHIFT, 0);
+	}
+}
+
+/* tp->lock is held. */
+static void tg3_rings_reset(struct tg3 *tp)
+{
+	int i;
+	u32 stblk;
+	struct tg3_napi *tnapi = &tp->napi[0];
+
+	tg3_tx_rcbs_disable(tp);
+
+	tg3_rx_ret_rcbs_disable(tp);
 
 	/* Disable interrupts */
 	tw32_mailbox_f(tp->napi[0].int_mbox, 1);
@@ -9271,9 +9400,6 @@ static void tg3_rings_reset(struct tg3 *
 			tw32_tx_mbox(mbox + i * 8, 0);
 	}
 
-	txrcb = NIC_SRAM_SEND_RCB;
-	rxrcb = NIC_SRAM_RCV_RET_RCB;
-
 	/* Clear status block in ram. */
 	memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
 
@@ -9283,46 +9409,20 @@ static void tg3_rings_reset(struct tg3 *
 	tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
 	     ((u64) tnapi->status_mapping & 0xffffffff));
 
-	if (tnapi->tx_ring) {
-		tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
-			       (TG3_TX_RING_SIZE <<
-				BDINFO_FLAGS_MAXLEN_SHIFT),
-			       NIC_SRAM_TX_BUFFER_DESC);
-		txrcb += TG3_BDINFO_SIZE;
-	}
-
-	if (tnapi->rx_rcb) {
-		tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
-			       (tp->rx_ret_ring_mask + 1) <<
-				BDINFO_FLAGS_MAXLEN_SHIFT, 0);
-		rxrcb += TG3_BDINFO_SIZE;
-	}
-
 	stblk = HOSTCC_STATBLCK_RING1;
 
 	for (i = 1, tnapi++; i < tp->irq_cnt; i++, tnapi++) {
 		u64 mapping = (u64)tnapi->status_mapping;
 		tw32(stblk + TG3_64BIT_REG_HIGH, mapping >> 32);
 		tw32(stblk + TG3_64BIT_REG_LOW, mapping & 0xffffffff);
+		stblk += 8;
 
 		/* Clear status block in ram. */
 		memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
-
-		if (tnapi->tx_ring) {
-			tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
-				       (TG3_TX_RING_SIZE <<
-					BDINFO_FLAGS_MAXLEN_SHIFT),
-				       NIC_SRAM_TX_BUFFER_DESC);
-			txrcb += TG3_BDINFO_SIZE;
-		}
-
-		tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
-			       ((tp->rx_ret_ring_mask + 1) <<
-				BDINFO_FLAGS_MAXLEN_SHIFT), 0);
-
-		stblk += 8;
-		rxrcb += TG3_BDINFO_SIZE;
 	}
+
+	tg3_tx_rcbs_init(tp);
+	tg3_rx_ret_rcbs_init(tp);
 }
 
 static void tg3_setup_rxbd_thresholds(struct tg3 *tp)
@@ -9522,46 +9622,17 @@ static int tg3_reset_hw(struct tg3 *tp,
 	if (tg3_flag(tp, INIT_COMPLETE))
 		tg3_abort_hw(tp, 1);
 
-	/* Enable MAC control of LPI */
-	if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
-		val = TG3_CPMU_EEE_LNKIDL_PCIE_NL0 |
-		      TG3_CPMU_EEE_LNKIDL_UART_IDL;
-		if (tg3_chip_rev_id(tp) == CHIPREV_ID_57765_A0)
-			val |= TG3_CPMU_EEE_LNKIDL_APE_TX_MT;
-
-		tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, val);
-
-		tw32_f(TG3_CPMU_EEE_CTRL,
-		       TG3_CPMU_EEE_CTRL_EXIT_20_1_US);
-
-		val = TG3_CPMU_EEEMD_ERLY_L1_XIT_DET |
-		      TG3_CPMU_EEEMD_LPI_IN_TX |
-		      TG3_CPMU_EEEMD_LPI_IN_RX |
-		      TG3_CPMU_EEEMD_EEE_ENABLE;
-
-		if (tg3_asic_rev(tp) != ASIC_REV_5717)
-			val |= TG3_CPMU_EEEMD_SND_IDX_DET_EN;
-
-		if (tg3_flag(tp, ENABLE_APE))
-			val |= TG3_CPMU_EEEMD_APE_TX_DET_EN;
-
-		tw32_f(TG3_CPMU_EEE_MODE, val);
-
-		tw32_f(TG3_CPMU_EEE_DBTMR1,
-		       TG3_CPMU_DBTMR1_PCIEXIT_2047US |
-		       TG3_CPMU_DBTMR1_LNKIDLE_2047US);
-
-		tw32_f(TG3_CPMU_EEE_DBTMR2,
-		       TG3_CPMU_DBTMR2_APE_TX_2047US |
-		       TG3_CPMU_DBTMR2_TXIDXEQ_2047US);
-	}
-
 	if ((tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN) &&
 	    !(tp->phy_flags & TG3_PHYFLG_USER_CONFIGURED)) {
 		tg3_phy_pull_config(tp);
+		tg3_eee_pull_config(tp, NULL);
 		tp->phy_flags |= TG3_PHYFLG_USER_CONFIGURED;
 	}
 
+	/* Enable MAC control of LPI */
+	if (tp->phy_flags & TG3_PHYFLG_EEE_CAP)
+		tg3_setup_eee(tp);
+
 	if (reset_phy)
 		tg3_phy_reset(tp);
 
@@ -11217,7 +11288,7 @@ static int tg3_start(struct tg3 *tp, boo
 	 */
 	err = tg3_alloc_consistent(tp);
 	if (err)
-		goto err_out1;
+		goto out_ints_fini;
 
 	tg3_napi_init(tp);
 
@@ -11231,12 +11302,15 @@ static int tg3_start(struct tg3 *tp, boo
 				tnapi = &tp->napi[i];
 				free_irq(tnapi->irq_vec, tnapi);
 			}
-			goto err_out2;
+			goto out_napi_fini;
 		}
 	}
 
 	tg3_full_lock(tp, 0);
 
+	if (init)
+		tg3_ape_driver_state_change(tp, RESET_KIND_INIT);
+
 	err = tg3_init_hw(tp, reset_phy);
 	if (err) {
 		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -11246,7 +11320,7 @@ static int tg3_start(struct tg3 *tp, boo
 	tg3_full_unlock(tp);
 
 	if (err)
-		goto err_out3;
+		goto out_free_irq;
 
 	if (test_irq && tg3_flag(tp, USING_MSI)) {
 		err = tg3_test_msi(tp);
@@ -11257,7 +11331,7 @@ static int tg3_start(struct tg3 *tp, boo
 			tg3_free_rings(tp);
 			tg3_full_unlock(tp);
 
-			goto err_out2;
+			goto out_napi_fini;
 		}
 
 		if (!tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) {
@@ -11297,18 +11371,18 @@ static int tg3_start(struct tg3 *tp, boo
 
 	return 0;
 
-err_out3:
+out_free_irq:
 	for (i = tp->irq_cnt - 1; i >= 0; i--) {
 		struct tg3_napi *tnapi = &tp->napi[i];
 		free_irq(tnapi->irq_vec, tnapi);
 	}
 
-err_out2:
+out_napi_fini:
 	tg3_napi_disable(tp);
 	tg3_napi_fini(tp);
 	tg3_free_consistent(tp);
 
-err_out1:
+out_ints_fini:
 	tg3_ints_fini(tp);
 
 	return err;
@@ -13353,11 +13427,13 @@ static void tg3_self_test(struct net_dev
 	struct tg3 *tp = netdev_priv(dev);
 	bool doextlpbk = etest->flags & ETH_TEST_FL_EXTERNAL_LB;
 
-	if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) &&
-	    tg3_power_up(tp)) {
-		etest->flags |= ETH_TEST_FL_FAILED;
-		memset(data, 1, sizeof(u64) * TG3_NUM_TEST);
-		return;
+	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
+		if (tg3_power_up(tp)) {
+			etest->flags |= ETH_TEST_FL_FAILED;
+			memset(data, 1, sizeof(u64) * TG3_NUM_TEST);
+			return;
+		}
+		tg3_ape_driver_state_change(tp, RESET_KIND_INIT);
 	}
 
 	memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
@@ -13648,6 +13724,57 @@ static int tg3_set_coalesce(struct net_d
 	return 0;
 }
 
+static int tg3_set_eee(struct net_device *dev, struct ethtool_eee *edata)
+{
+	struct tg3 *tp = netdev_priv(dev);
+
+	if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) {
+		netdev_warn(tp->dev, "Board does not support EEE!\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (edata->advertised != tp->eee.advertised) {
+		netdev_warn(tp->dev,
+			    "Direct manipulation of EEE advertisement is not supported\n");
+		return -EINVAL;
+	}
+
+	if (edata->tx_lpi_timer > TG3_CPMU_DBTMR1_LNKIDLE_MAX) {
+		netdev_warn(tp->dev,
+			    "Maximal Tx Lpi timer supported is %#x(u)\n",
+			    TG3_CPMU_DBTMR1_LNKIDLE_MAX);
+		return -EINVAL;
+	}
+
+	tp->eee = *edata;
+
+	tp->phy_flags |= TG3_PHYFLG_USER_CONFIGURED;
+	tg3_warn_mgmt_link_flap(tp);
+
+	if (netif_running(tp->dev)) {
+		tg3_full_lock(tp, 0);
+		tg3_setup_eee(tp);
+		tg3_phy_reset(tp);
+		tg3_full_unlock(tp);
+	}
+
+	return 0;
+}
+
+static int tg3_get_eee(struct net_device *dev, struct ethtool_eee *edata)
+{
+	struct tg3 *tp = netdev_priv(dev);
+
+	if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) {
+		netdev_warn(tp->dev,
+			    "Board does not support EEE!\n");
+		return -EOPNOTSUPP;
+	}
+
+	*edata = tp->eee;
+	return 0;
+}
+
 static const struct ethtool_ops tg3_ethtool_ops = {
 	.get_settings		= tg3_get_settings,
 	.set_settings		= tg3_set_settings,
@@ -13681,6 +13808,8 @@ static const struct ethtool_ops tg3_etht
 	.get_channels		= tg3_get_channels,
 	.set_channels		= tg3_set_channels,
 	.get_ts_info		= tg3_get_ts_info,
+	.get_eee		= tg3_get_eee,
+	.set_eee		= tg3_set_eee,
 };
 
 static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev,
@@ -15029,9 +15158,18 @@ static int tg3_phy_probe(struct tg3 *tp)
 	     (tg3_asic_rev(tp) == ASIC_REV_5717 &&
 	      tg3_chip_rev_id(tp) != CHIPREV_ID_5717_A0) ||
 	     (tg3_asic_rev(tp) == ASIC_REV_57765 &&
-	      tg3_chip_rev_id(tp) != CHIPREV_ID_57765_A0)))
+	      tg3_chip_rev_id(tp) != CHIPREV_ID_57765_A0))) {
 		tp->phy_flags |= TG3_PHYFLG_EEE_CAP;
 
+		tp->eee.supported = SUPPORTED_100baseT_Full |
+				    SUPPORTED_1000baseT_Full;
+		tp->eee.advertised = ADVERTISED_100baseT_Full |
+				     ADVERTISED_1000baseT_Full;
+		tp->eee.eee_enabled = 1;
+		tp->eee.tx_lpi_enabled = 1;
+		tp->eee.tx_lpi_timer = TG3_CPMU_DBTMR1_LNKIDLE_2047US;
+	}
+
 	tg3_phy_init_link_config(tp);
 
 	if (!(tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN) &&
@@ -17103,7 +17241,7 @@ static int tg3_init_one(struct pci_dev *
 {
 	struct net_device *dev;
 	struct tg3 *tp;
-	int i, err, pm_cap;
+	int i, err;
 	u32 sndmbx, rcvmbx, intmbx;
 	char str[40];
 	u64 dma_mask, persist_dma_mask;
@@ -17125,25 +17263,10 @@ static int tg3_init_one(struct pci_dev *
 
 	pci_set_master(pdev);
 
-	/* Find power-management capability. */
-	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
-	if (pm_cap == 0) {
-		dev_err(&pdev->dev,
-			"Cannot find Power Management capability, aborting\n");
-		err = -EIO;
-		goto err_out_free_res;
-	}
-
-	err = pci_set_power_state(pdev, PCI_D0);
-	if (err) {
-		dev_err(&pdev->dev, "Transition to D0 failed, aborting\n");
-		goto err_out_free_res;
-	}
-
 	dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS);
 	if (!dev) {
 		err = -ENOMEM;
-		goto err_out_power_down;
+		goto err_out_free_res;
 	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -17151,7 +17274,7 @@ static int tg3_init_one(struct pci_dev *
 	tp = netdev_priv(dev);
 	tp->pdev = pdev;
 	tp->dev = dev;
-	tp->pm_cap = pm_cap;
+	tp->pm_cap = pdev->pm_cap;
 	tp->rx_mode = TG3_DEF_RX_MODE;
 	tp->tx_mode = TG3_DEF_TX_MODE;
 	tp->irq_sync = 1;
@@ -17489,14 +17612,12 @@ err_out_iounmap:
 err_out_free_dev:
 	free_netdev(dev);
 
-err_out_power_down:
-	pci_set_power_state(pdev, PCI_D3hot);
-
 err_out_free_res:
 	pci_release_regions(pdev);
 
 err_out_disable_pdev:
-	pci_disable_device(pdev);
+	if (pci_is_enabled(pdev))
+		pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 	return err;
 }
@@ -17601,6 +17722,8 @@ static int tg3_resume(struct device *dev
 
 	tg3_full_lock(tp, 0);
 
+	tg3_ape_driver_state_change(tp, RESET_KIND_INIT);
+
 	tg3_flag_set(tp, INIT_COMPLETE);
 	err = tg3_restart_hw(tp,
 			     !(tp->phy_flags & TG3_PHYFLG_KEEP_LINK_ON_PWRDN));
@@ -17642,7 +17765,8 @@ static pci_ers_result_t tg3_io_error_det
 
 	rtnl_lock();
 
-	if (!netif_running(netdev))
+	/* We probably don't have netdev yet */
+	if (!netdev || !netif_running(netdev))
 		goto done;
 
 	tg3_phy_stop(tp);
@@ -17662,10 +17786,15 @@ static pci_ers_result_t tg3_io_error_det
 	tg3_full_unlock(tp);
 
 done:
-	if (state == pci_channel_io_perm_failure)
+	if (state == pci_channel_io_perm_failure) {
+		if (netdev) {
+			tg3_napi_enable(tp);
+			dev_close(netdev);
+		}
 		err = PCI_ERS_RESULT_DISCONNECT;
-	else
+	} else {
 		pci_disable_device(pdev);
+	}
 
 	rtnl_unlock();
 
@@ -17691,7 +17820,8 @@ static pci_ers_result_t tg3_io_slot_rese
 	rtnl_lock();
 
 	if (pci_enable_device(pdev)) {
-		netdev_err(netdev, "Cannot re-enable PCI device after reset.\n");
+		dev_err(&pdev->dev,
+			"Cannot re-enable PCI device after reset.\n");
 		goto done;
 	}
 
@@ -17699,7 +17829,7 @@ static pci_ers_result_t tg3_io_slot_rese
 	pci_restore_state(pdev);
 	pci_save_state(pdev);
 
-	if (!netif_running(netdev)) {
+	if (!netdev || !netif_running(netdev)) {
 		rc = PCI_ERS_RESULT_RECOVERED;
 		goto done;
 	}
@@ -17711,6 +17841,10 @@ static pci_ers_result_t tg3_io_slot_rese
 	rc = PCI_ERS_RESULT_RECOVERED;
 
 done:
+	if (rc != PCI_ERS_RESULT_RECOVERED && netdev && netif_running(netdev)) {
+		tg3_napi_enable(tp);
+		dev_close(netdev);
+	}
 	rtnl_unlock();
 
 	return rc;
@@ -17735,6 +17869,7 @@ static void tg3_io_resume(struct pci_dev
 		goto done;
 
 	tg3_full_lock(tp, 0);
+	tg3_ape_driver_state_change(tp, RESET_KIND_INIT);
 	tg3_flag_set(tp, INIT_COMPLETE);
 	err = tg3_restart_hw(tp, true);
 	if (err) {
@@ -17772,15 +17907,4 @@ static struct pci_driver tg3_driver = {
 	.driver.pm	= &tg3_pm_ops,
 };
 
-static int __init tg3_init(void)
-{
-	return pci_register_driver(&tg3_driver);
-}
-
-static void __exit tg3_cleanup(void)
-{
-	pci_unregister_driver(&tg3_driver);
-}
-
-module_init(tg3_init);
-module_exit(tg3_cleanup);
+module_pci_driver(tg3_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/tg3.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/tg3.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/broadcom/tg3.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/broadcom/tg3.h	2013-08-25 20:43:22.000000000 -0400
@@ -1175,6 +1175,7 @@
 #define TG3_CPMU_EEE_DBTMR1		0x000036b4
 #define  TG3_CPMU_DBTMR1_PCIEXIT_2047US	 0x07ff0000
 #define  TG3_CPMU_DBTMR1_LNKIDLE_2047US	 0x000007ff
+#define  TG3_CPMU_DBTMR1_LNKIDLE_MAX	 0x0000ffff
 #define TG3_CPMU_EEE_DBTMR2		0x000036b8
 #define  TG3_CPMU_DBTMR2_APE_TX_2047US	 0x07ff0000
 #define  TG3_CPMU_DBTMR2_TXIDXEQ_2047US	 0x000007ff
@@ -3372,6 +3373,7 @@ struct tg3 {
 	unsigned int			irq_cnt;
 
 	struct ethtool_coalesce		coal;
+	struct ethtool_eee		eee;
 
 	/* firmware info */
 	const char			*fw_needed;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bfa_defs.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bfa_defs.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bfa_defs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bfa_defs.h	2013-08-25 20:43:22.000000000 -0400
@@ -164,7 +164,8 @@ struct bfa_ioc_attr {
 	u8				port_mode;	/*!< enum bfa_mode */
 	u8				cap_bm;		/*!< capability */
 	u8				port_mode_cfg;	/*!< enum bfa_mode */
-	u8				rsvd[4];	/*!< 64bit align */
+	u8				def_fn;		/*!< 1 if default fn */
+	u8				rsvd[3];	/*!< 64bit align */
 };
 
 /* Adapter capability mask definition */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.c	2013-08-25 20:43:22.000000000 -0400
@@ -2371,7 +2371,7 @@ bfa_nw_ioc_get_attr(struct bfa_ioc *ioc,
 	memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr));
 
 	ioc_attr->state = bfa_ioc_get_state(ioc);
-	ioc_attr->port_id = ioc->port_id;
+	ioc_attr->port_id = bfa_ioc_portid(ioc);
 	ioc_attr->port_mode = ioc->port_mode;
 
 	ioc_attr->port_mode_cfg = ioc->port_mode_cfg;
@@ -2381,8 +2381,9 @@ bfa_nw_ioc_get_attr(struct bfa_ioc *ioc,
 
 	bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
 
-	ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
-	ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
+	ioc_attr->pci_attr.device_id = bfa_ioc_devid(ioc);
+	ioc_attr->pci_attr.pcifn = bfa_ioc_pcifn(ioc);
+	ioc_attr->def_fn = bfa_ioc_is_default(ioc);
 	bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bfa_ioc.h	2013-08-25 20:43:22.000000000 -0400
@@ -222,6 +222,8 @@ struct bfa_ioc_hwif {
 #define bfa_ioc_bar0(__ioc)		((__ioc)->pcidev.pci_bar_kva)
 #define bfa_ioc_portid(__ioc)		((__ioc)->port_id)
 #define bfa_ioc_asic_gen(__ioc)		((__ioc)->asic_gen)
+#define bfa_ioc_is_default(__ioc)	\
+	(bfa_ioc_pcifn(__ioc) == bfa_ioc_portid(__ioc))
 #define bfa_ioc_fetch_stats(__ioc, __stats) \
 		(((__stats)->drv_stats) = (__ioc)->stats)
 #define bfa_ioc_clr_stats(__ioc)	\
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bnad.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bnad.c	2013-07-01 10:36:08.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad.c	2013-08-31 17:55:40.000000000 -0400
@@ -2624,6 +2624,9 @@ bnad_stop(struct net_device *netdev)
 	bnad_destroy_tx(bnad, 0);
 	bnad_destroy_rx(bnad, 0);
 
+	/* These config flags are cleared in the hardware */
+	bnad->cfg_flags &= ~(BNAD_CF_ALLMULTI | BNAD_CF_PROMISC);
+
 	/* Synchronize mailbox IRQ */
 	bnad_mbox_irq_sync(bnad);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bnad_debugfs.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bnad_debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad_debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -230,32 +230,12 @@ bnad_debugfs_open_drvinfo(struct inode *
 static loff_t
 bnad_debugfs_lseek(struct file *file, loff_t offset, int orig)
 {
-	loff_t pos = file->f_pos;
 	struct bnad_debug_info *debug = file->private_data;
 
 	if (!debug)
 		return -EINVAL;
 
-	switch (orig) {
-	case 0:
-		file->f_pos = offset;
-		break;
-	case 1:
-		file->f_pos += offset;
-		break;
-	case 2:
-		file->f_pos = debug->buffer_len + offset;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (file->f_pos < 0 || file->f_pos > debug->buffer_len) {
-		file->f_pos = pos;
-		return -EINVAL;
-	}
-
-	return file->f_pos;
+	return fixed_size_llseek(file, offset, orig, debug->buffer_len);
 }
 
 static ssize_t
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bnad.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bnad.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bnad.h	2013-08-25 20:43:22.000000000 -0400
@@ -71,7 +71,7 @@ struct bnad_rx_ctrl {
 #define BNAD_NAME			"bna"
 #define BNAD_NAME_LEN			64
 
-#define BNAD_VERSION			"3.1.2.1"
+#define BNAD_VERSION			"3.2.21.1"
 
 #define BNAD_MAILBOX_MSIX_INDEX		0
 #define BNAD_MAILBOX_MSIX_VECTORS	1
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bna_enet.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bna_enet.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bna_enet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bna_enet.c	2013-08-25 20:43:22.000000000 -0400
@@ -298,7 +298,6 @@ bna_msgq_rsp_handler(void *arg, struct b
 	case BFI_ENET_I2H_RSS_ENABLE_RSP:
 	case BFI_ENET_I2H_RX_PROMISCUOUS_RSP:
 	case BFI_ENET_I2H_RX_DEFAULT_RSP:
-	case BFI_ENET_I2H_MAC_UCAST_SET_RSP:
 	case BFI_ENET_I2H_MAC_UCAST_CLR_RSP:
 	case BFI_ENET_I2H_MAC_UCAST_ADD_RSP:
 	case BFI_ENET_I2H_MAC_UCAST_DEL_RSP:
@@ -311,6 +310,12 @@ bna_msgq_rsp_handler(void *arg, struct b
 			bna_bfi_rxf_cfg_rsp(&rx->rxf, msghdr);
 		break;
 
+	case BFI_ENET_I2H_MAC_UCAST_SET_RSP:
+		bna_rx_from_rid(bna, msghdr->enet_id, rx);
+		if (rx)
+			bna_bfi_rxf_ucast_set_rsp(&rx->rxf, msghdr);
+		break;
+
 	case BFI_ENET_I2H_MAC_MCAST_ADD_RSP:
 		bna_rx_from_rid(bna, msghdr->enet_id, rx);
 		if (rx)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bna.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bna.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bna.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bna.h	2013-08-25 20:43:22.000000000 -0400
@@ -455,6 +455,8 @@ void bna_bfi_rx_enet_stop_rsp(struct bna
 void bna_bfi_rxf_cfg_rsp(struct bna_rxf *rxf, struct bfi_msgq_mhdr *msghdr);
 void bna_bfi_rxf_mcast_add_rsp(struct bna_rxf *rxf,
 			       struct bfi_msgq_mhdr *msghdr);
+void bna_bfi_rxf_ucast_set_rsp(struct bna_rxf *rxf,
+			       struct bfi_msgq_mhdr *msghdr);
 
 /* APIs for BNA */
 void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bna_tx_rx.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/brocade/bna/bna_tx_rx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/brocade/bna/bna_tx_rx.c	2013-08-25 20:43:22.000000000 -0400
@@ -711,6 +711,21 @@ bna_bfi_rxf_cfg_rsp(struct bna_rxf *rxf,
 }
 
 void
+bna_bfi_rxf_ucast_set_rsp(struct bna_rxf *rxf,
+			struct bfi_msgq_mhdr *msghdr)
+{
+	struct bfi_enet_rsp *rsp =
+		(struct bfi_enet_rsp *)msghdr;
+
+	if (rsp->error) {
+		/* Clear ucast from cache */
+		rxf->ucast_active_set = 0;
+	}
+
+	bfa_fsm_send_event(rxf, RXF_E_FW_RESP);
+}
+
+void
 bna_bfi_rxf_mcast_add_rsp(struct bna_rxf *rxf,
 			struct bfi_msgq_mhdr *msghdr)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/cadence/at91_ether.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cadence/at91_ether.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/cadence/at91_ether.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cadence/at91_ether.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_net.h>
-#include <linux/pinctrl/consumer.h>
 
 #include "macb.h"
 
@@ -309,7 +308,6 @@ static int __init at91ether_probe(struct
 	struct resource *regs;
 	struct net_device *dev;
 	struct phy_device *phydev;
-	struct pinctrl *pinctrl;
 	struct macb *lp;
 	int res;
 	u32 reg;
@@ -319,15 +317,6 @@ static int __init at91ether_probe(struct
 	if (!regs)
 		return -ENOENT;
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl)) {
-		res = PTR_ERR(pinctrl);
-		if (res == -EPROBE_DEFER)
-			return res;
-
-		dev_warn(&pdev->dev, "No pinctrl provided\n");
-	}
-
 	dev = alloc_etherdev(sizeof(struct macb));
 	if (!dev)
 		return -ENOMEM;
@@ -435,7 +424,6 @@ static int at91ether_remove(struct platf
 	unregister_netdev(dev);
 	clk_disable(lp->pclk);
 	free_netdev(dev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/cadence/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cadence/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/cadence/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cadence/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,6 @@ if NET_CADENCE
 config ARM_AT91_ETHER
 	tristate "AT91RM9200 Ethernet support"
 	depends on GENERIC_HARDIRQS && HAS_DMA
-	select NET_CORE
 	select MACB
 	---help---
 	  If you wish to compile a kernel for the AT91RM9200 and enable
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/cadence/macb.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cadence/macb.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/cadence/macb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cadence/macb.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,8 @@
 
 #include "macb.h"
 
-#define RX_BUFFER_SIZE		128
+#define MACB_RX_BUFFER_SIZE	128
+#define RX_BUFFER_MULTIPLE	64  /* bytes */
 #define RX_RING_SIZE		512 /* must be power of 2 */
 #define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
 
@@ -92,7 +93,7 @@ static struct macb_dma_desc *macb_rx_des
 
 static void *macb_rx_buffer(struct macb *bp, unsigned int index)
 {
-	return bp->rx_buffers + RX_BUFFER_SIZE * macb_rx_ring_wrap(index);
+	return bp->rx_buffers + bp->rx_buffer_size * macb_rx_ring_wrap(index);
 }
 
 void macb_set_hwaddr(struct macb *bp)
@@ -528,6 +529,155 @@ static void macb_tx_interrupt(struct mac
 		netif_wake_queue(bp->dev);
 }
 
+static void gem_rx_refill(struct macb *bp)
+{
+	unsigned int		entry;
+	struct sk_buff		*skb;
+	struct macb_dma_desc	*desc;
+	dma_addr_t		paddr;
+
+	while (CIRC_SPACE(bp->rx_prepared_head, bp->rx_tail, RX_RING_SIZE) > 0) {
+		u32 addr, ctrl;
+
+		entry = macb_rx_ring_wrap(bp->rx_prepared_head);
+		desc = &bp->rx_ring[entry];
+
+		/* Make hw descriptor updates visible to CPU */
+		rmb();
+
+		addr = desc->addr;
+		ctrl = desc->ctrl;
+		bp->rx_prepared_head++;
+
+		if ((addr & MACB_BIT(RX_USED)))
+			continue;
+
+		if (bp->rx_skbuff[entry] == NULL) {
+			/* allocate sk_buff for this free entry in ring */
+			skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size);
+			if (unlikely(skb == NULL)) {
+				netdev_err(bp->dev,
+					   "Unable to allocate sk_buff\n");
+				break;
+			}
+			bp->rx_skbuff[entry] = skb;
+
+			/* now fill corresponding descriptor entry */
+			paddr = dma_map_single(&bp->pdev->dev, skb->data,
+					       bp->rx_buffer_size, DMA_FROM_DEVICE);
+
+			if (entry == RX_RING_SIZE - 1)
+				paddr |= MACB_BIT(RX_WRAP);
+			bp->rx_ring[entry].addr = paddr;
+			bp->rx_ring[entry].ctrl = 0;
+
+			/* properly align Ethernet header */
+			skb_reserve(skb, NET_IP_ALIGN);
+		}
+	}
+
+	/* Make descriptor updates visible to hardware */
+	wmb();
+
+	netdev_vdbg(bp->dev, "rx ring: prepared head %d, tail %d\n",
+		   bp->rx_prepared_head, bp->rx_tail);
+}
+
+/* Mark DMA descriptors from begin up to and not including end as unused */
+static void discard_partial_frame(struct macb *bp, unsigned int begin,
+				  unsigned int end)
+{
+	unsigned int frag;
+
+	for (frag = begin; frag != end; frag++) {
+		struct macb_dma_desc *desc = macb_rx_desc(bp, frag);
+		desc->addr &= ~MACB_BIT(RX_USED);
+	}
+
+	/* Make descriptor updates visible to hardware */
+	wmb();
+
+	/*
+	 * When this happens, the hardware stats registers for
+	 * whatever caused this is updated, so we don't have to record
+	 * anything.
+	 */
+}
+
+static int gem_rx(struct macb *bp, int budget)
+{
+	unsigned int		len;
+	unsigned int		entry;
+	struct sk_buff		*skb;
+	struct macb_dma_desc	*desc;
+	int			count = 0;
+
+	while (count < budget) {
+		u32 addr, ctrl;
+
+		entry = macb_rx_ring_wrap(bp->rx_tail);
+		desc = &bp->rx_ring[entry];
+
+		/* Make hw descriptor updates visible to CPU */
+		rmb();
+
+		addr = desc->addr;
+		ctrl = desc->ctrl;
+
+		if (!(addr & MACB_BIT(RX_USED)))
+			break;
+
+		desc->addr &= ~MACB_BIT(RX_USED);
+		bp->rx_tail++;
+		count++;
+
+		if (!(ctrl & MACB_BIT(RX_SOF) && ctrl & MACB_BIT(RX_EOF))) {
+			netdev_err(bp->dev,
+				   "not whole frame pointed by descriptor\n");
+			bp->stats.rx_dropped++;
+			break;
+		}
+		skb = bp->rx_skbuff[entry];
+		if (unlikely(!skb)) {
+			netdev_err(bp->dev,
+				   "inconsistent Rx descriptor chain\n");
+			bp->stats.rx_dropped++;
+			break;
+		}
+		/* now everything is ready for receiving packet */
+		bp->rx_skbuff[entry] = NULL;
+		len = MACB_BFEXT(RX_FRMLEN, ctrl);
+
+		netdev_vdbg(bp->dev, "gem_rx %u (len %u)\n", entry, len);
+
+		skb_put(skb, len);
+		addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, addr));
+		dma_unmap_single(&bp->pdev->dev, addr,
+				 len, DMA_FROM_DEVICE);
+
+		skb->protocol = eth_type_trans(skb, bp->dev);
+		skb_checksum_none_assert(skb);
+
+		bp->stats.rx_packets++;
+		bp->stats.rx_bytes += skb->len;
+
+#if defined(DEBUG) && defined(VERBOSE_DEBUG)
+		netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
+			    skb->len, skb->csum);
+		print_hex_dump(KERN_DEBUG, " mac: ", DUMP_PREFIX_ADDRESS, 16, 1,
+			       skb->mac_header, 16, true);
+		print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_ADDRESS, 16, 1,
+			       skb->data, 32, true);
+#endif
+
+		netif_receive_skb(skb);
+	}
+
+	gem_rx_refill(bp);
+
+	return count;
+}
+
 static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 			 unsigned int last_frag)
 {
@@ -575,7 +725,7 @@ static int macb_rx_frame(struct macb *bp
 	skb_put(skb, len);
 
 	for (frag = first_frag; ; frag++) {
-		unsigned int frag_len = RX_BUFFER_SIZE;
+		unsigned int frag_len = bp->rx_buffer_size;
 
 		if (offset + frag_len > len) {
 			BUG_ON(frag != last_frag);
@@ -583,7 +733,7 @@ static int macb_rx_frame(struct macb *bp
 		}
 		skb_copy_to_linear_data_offset(skb, offset,
 				macb_rx_buffer(bp, frag), frag_len);
-		offset += RX_BUFFER_SIZE;
+		offset += bp->rx_buffer_size;
 		desc = macb_rx_desc(bp, frag);
 		desc->addr &= ~MACB_BIT(RX_USED);
 
@@ -606,27 +756,6 @@ static int macb_rx_frame(struct macb *bp
 	return 0;
 }
 
-/* Mark DMA descriptors from begin up to and not including end as unused */
-static void discard_partial_frame(struct macb *bp, unsigned int begin,
-				  unsigned int end)
-{
-	unsigned int frag;
-
-	for (frag = begin; frag != end; frag++) {
-		struct macb_dma_desc *desc = macb_rx_desc(bp, frag);
-		desc->addr &= ~MACB_BIT(RX_USED);
-	}
-
-	/* Make descriptor updates visible to hardware */
-	wmb();
-
-	/*
-	 * When this happens, the hardware stats registers for
-	 * whatever caused this is updated, so we don't have to record
-	 * anything.
-	 */
-}
-
 static int macb_rx(struct macb *bp, int budget)
 {
 	int received = 0;
@@ -687,7 +816,7 @@ static int macb_poll(struct napi_struct
 	netdev_vdbg(bp->dev, "poll: status = %08lx, budget = %d\n",
 		   (unsigned long)status, budget);
 
-	work_done = macb_rx(bp, budget);
+	work_done = bp->macbgem_ops.mog_rx(bp, budget);
 	if (work_done < budget) {
 		napi_complete(napi);
 
@@ -870,12 +999,71 @@ static int macb_start_xmit(struct sk_buf
 	return NETDEV_TX_OK;
 }
 
+static void macb_init_rx_buffer_size(struct macb *bp, size_t size)
+{
+	if (!macb_is_gem(bp)) {
+		bp->rx_buffer_size = MACB_RX_BUFFER_SIZE;
+	} else {
+		bp->rx_buffer_size = size;
+
+		if (bp->rx_buffer_size % RX_BUFFER_MULTIPLE) {
+			netdev_dbg(bp->dev,
+				    "RX buffer must be multiple of %d bytes, expanding\n",
+				    RX_BUFFER_MULTIPLE);
+			bp->rx_buffer_size =
+				roundup(bp->rx_buffer_size, RX_BUFFER_MULTIPLE);
+		}
+	}
+
+	netdev_dbg(bp->dev, "mtu [%u] rx_buffer_size [%Zu]\n",
+		   bp->dev->mtu, bp->rx_buffer_size);
+}
+
+static void gem_free_rx_buffers(struct macb *bp)
+{
+	struct sk_buff		*skb;
+	struct macb_dma_desc	*desc;
+	dma_addr_t		addr;
+	int i;
+
+	if (!bp->rx_skbuff)
+		return;
+
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		skb = bp->rx_skbuff[i];
+
+		if (skb == NULL)
+			continue;
+
+		desc = &bp->rx_ring[i];
+		addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr));
+		dma_unmap_single(&bp->pdev->dev, addr, skb->len,
+				 DMA_FROM_DEVICE);
+		dev_kfree_skb_any(skb);
+		skb = NULL;
+	}
+
+	kfree(bp->rx_skbuff);
+	bp->rx_skbuff = NULL;
+}
+
+static void macb_free_rx_buffers(struct macb *bp)
+{
+	if (bp->rx_buffers) {
+		dma_free_coherent(&bp->pdev->dev,
+				  RX_RING_SIZE * bp->rx_buffer_size,
+				  bp->rx_buffers, bp->rx_buffers_dma);
+		bp->rx_buffers = NULL;
+	}
+}
+
 static void macb_free_consistent(struct macb *bp)
 {
 	if (bp->tx_skb) {
 		kfree(bp->tx_skb);
 		bp->tx_skb = NULL;
 	}
+	bp->macbgem_ops.mog_free_rx_buffers(bp);
 	if (bp->rx_ring) {
 		dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES,
 				  bp->rx_ring, bp->rx_ring_dma);
@@ -886,12 +1074,37 @@ static void macb_free_consistent(struct
 				  bp->tx_ring, bp->tx_ring_dma);
 		bp->tx_ring = NULL;
 	}
-	if (bp->rx_buffers) {
-		dma_free_coherent(&bp->pdev->dev,
-				  RX_RING_SIZE * RX_BUFFER_SIZE,
-				  bp->rx_buffers, bp->rx_buffers_dma);
-		bp->rx_buffers = NULL;
-	}
+}
+
+static int gem_alloc_rx_buffers(struct macb *bp)
+{
+	int size;
+
+	size = RX_RING_SIZE * sizeof(struct sk_buff *);
+	bp->rx_skbuff = kzalloc(size, GFP_KERNEL);
+	if (!bp->rx_skbuff)
+		return -ENOMEM;
+	else
+		netdev_dbg(bp->dev,
+			   "Allocated %d RX struct sk_buff entries at %p\n",
+			   RX_RING_SIZE, bp->rx_skbuff);
+	return 0;
+}
+
+static int macb_alloc_rx_buffers(struct macb *bp)
+{
+	int size;
+
+	size = RX_RING_SIZE * bp->rx_buffer_size;
+	bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size,
+					    &bp->rx_buffers_dma, GFP_KERNEL);
+	if (!bp->rx_buffers)
+		return -ENOMEM;
+	else
+		netdev_dbg(bp->dev,
+			   "Allocated RX buffers of %d bytes at %08lx (mapped %p)\n",
+			   size, (unsigned long)bp->rx_buffers_dma, bp->rx_buffers);
+	return 0;
 }
 
 static int macb_alloc_consistent(struct macb *bp)
@@ -921,14 +1134,8 @@ static int macb_alloc_consistent(struct
 		   "Allocated TX ring of %d bytes at %08lx (mapped %p)\n",
 		   size, (unsigned long)bp->tx_ring_dma, bp->tx_ring);
 
-	size = RX_RING_SIZE * RX_BUFFER_SIZE;
-	bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size,
-					    &bp->rx_buffers_dma, GFP_KERNEL);
-	if (!bp->rx_buffers)
+	if (bp->macbgem_ops.mog_alloc_rx_buffers(bp))
 		goto out_err;
-	netdev_dbg(bp->dev,
-		   "Allocated RX buffers of %d bytes at %08lx (mapped %p)\n",
-		   size, (unsigned long)bp->rx_buffers_dma, bp->rx_buffers);
 
 	return 0;
 
@@ -937,6 +1144,21 @@ out_err:
 	return -ENOMEM;
 }
 
+static void gem_init_rings(struct macb *bp)
+{
+	int i;
+
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		bp->tx_ring[i].addr = 0;
+		bp->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+	}
+	bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
+
+	bp->rx_tail = bp->rx_prepared_head = bp->tx_head = bp->tx_tail = 0;
+
+	gem_rx_refill(bp);
+}
+
 static void macb_init_rings(struct macb *bp)
 {
 	int i;
@@ -946,7 +1168,7 @@ static void macb_init_rings(struct macb
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		bp->rx_ring[i].addr = addr;
 		bp->rx_ring[i].ctrl = 0;
-		addr += RX_BUFFER_SIZE;
+		addr += bp->rx_buffer_size;
 	}
 	bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
 
@@ -1056,7 +1278,7 @@ static void macb_configure_dma(struct ma
 
 	if (macb_is_gem(bp)) {
 		dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L);
-		dmacfg |= GEM_BF(RXBS, RX_BUFFER_SIZE / 64);
+		dmacfg |= GEM_BF(RXBS, bp->rx_buffer_size / RX_BUFFER_MULTIPLE);
 		dmacfg |= GEM_BF(FBLDO, 16);
 		dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
 		dmacfg &= ~GEM_BIT(ENDIA);
@@ -1070,7 +1292,7 @@ static void macb_configure_dma(struct ma
 static void macb_configure_caps(struct macb *bp)
 {
 	if (macb_is_gem(bp)) {
-		if (GEM_BF(IRQCOR, gem_readl(bp, DCFG1)) == 0)
+		if (GEM_BFEXT(IRQCOR, gem_readl(bp, DCFG1)) == 0)
 			bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
 	}
 }
@@ -1233,6 +1455,7 @@ EXPORT_SYMBOL_GPL(macb_set_rx_mode);
 static int macb_open(struct net_device *dev)
 {
 	struct macb *bp = netdev_priv(dev);
+	size_t bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN;
 	int err;
 
 	netdev_dbg(bp->dev, "open\n");
@@ -1244,6 +1467,9 @@ static int macb_open(struct net_device *
 	if (!bp->phy_dev)
 		return -EAGAIN;
 
+	/* RX buffers initialization */
+	macb_init_rx_buffer_size(bp, bufsz);
+
 	err = macb_alloc_consistent(bp);
 	if (err) {
 		netdev_err(dev, "Unable to allocate DMA memory (error %d)\n",
@@ -1253,7 +1479,7 @@ static int macb_open(struct net_device *
 
 	napi_enable(&bp->napi);
 
-	macb_init_rings(bp);
+	bp->macbgem_ops.mog_init_rings(bp);
 	macb_init_hw(bp);
 
 	/* schedule a link state check */
@@ -1572,6 +1798,19 @@ static int __init macb_probe(struct plat
 
 	dev->base_addr = regs->start;
 
+	/* setup appropriated routines according to adapter type */
+	if (macb_is_gem(bp)) {
+		bp->macbgem_ops.mog_alloc_rx_buffers = gem_alloc_rx_buffers;
+		bp->macbgem_ops.mog_free_rx_buffers = gem_free_rx_buffers;
+		bp->macbgem_ops.mog_init_rings = gem_init_rings;
+		bp->macbgem_ops.mog_rx = gem_rx;
+	} else {
+		bp->macbgem_ops.mog_alloc_rx_buffers = macb_alloc_rx_buffers;
+		bp->macbgem_ops.mog_free_rx_buffers = macb_free_rx_buffers;
+		bp->macbgem_ops.mog_init_rings = macb_init_rings;
+		bp->macbgem_ops.mog_rx = macb_rx;
+	}
+
 	/* Set MII management clock divider */
 	config = macb_mdc_clk_div(bp);
 	config |= macb_dbw(bp);
@@ -1649,7 +1888,6 @@ err_out_put_pclk:
 err_out_free_dev:
 	free_netdev(dev);
 err_out:
-	platform_set_drvdata(pdev, NULL);
 	return err;
 }
 
@@ -1675,7 +1913,6 @@ static int __exit macb_remove(struct pla
 		clk_disable_unprepare(bp->pclk);
 		clk_put(bp->pclk);
 		free_netdev(dev);
-		platform_set_drvdata(pdev, NULL);
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/cadence/macb.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cadence/macb.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/cadence/macb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cadence/macb.h	2013-08-25 20:43:22.000000000 -0400
@@ -545,12 +545,24 @@ struct gem_stats {
 	u32	rx_udp_checksum_errors;
 };
 
+struct macb;
+
+struct macb_or_gem_ops {
+	int	(*mog_alloc_rx_buffers)(struct macb *bp);
+	void	(*mog_free_rx_buffers)(struct macb *bp);
+	void	(*mog_init_rings)(struct macb *bp);
+	int	(*mog_rx)(struct macb *bp, int budget);
+};
+
 struct macb {
 	void __iomem		*regs;
 
 	unsigned int		rx_tail;
+	unsigned int		rx_prepared_head;
 	struct macb_dma_desc	*rx_ring;
+	struct sk_buff		**rx_skbuff;
 	void			*rx_buffers;
+	size_t			rx_buffer_size;
 
 	unsigned int		tx_head, tx_tail;
 	struct macb_dma_desc	*tx_ring;
@@ -573,6 +585,8 @@ struct macb {
 	dma_addr_t		tx_ring_dma;
 	dma_addr_t		rx_buffers_dma;
 
+	struct macb_or_gem_ops	macbgem_ops;
+
 	struct mii_bus		*mii_bus;
 	struct phy_device	*phy_dev;
 	unsigned int 		link;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/calxeda/xgmac.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/calxeda/xgmac.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/calxeda/xgmac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/calxeda/xgmac.c	2013-08-25 20:43:22.000000000 -0400
@@ -1790,7 +1790,6 @@ err_io:
 	free_netdev(ndev);
 err_alloc:
 	release_mem_region(res->start, resource_size(res));
-	platform_set_drvdata(pdev, NULL);
 	return ret;
 }
 
@@ -1813,7 +1812,6 @@ static int xgmac_remove(struct platform_
 	free_irq(ndev->irq, ndev);
 	free_irq(priv->pmt_irq, ndev);
 
-	platform_set_drvdata(pdev, NULL);
 	unregister_netdev(ndev);
 	netif_napi_del(&priv->napi);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb/cxgb2.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb/cxgb2.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb/cxgb2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb/cxgb2.c	2013-08-25 20:43:22.000000000 -0400
@@ -1351,22 +1351,11 @@ static void remove_one(struct pci_dev *p
 	t1_sw_reset(pdev);
 }
 
-static struct pci_driver driver = {
+static struct pci_driver cxgb_pci_driver = {
 	.name     = DRV_NAME,
 	.id_table = t1_pci_tbl,
 	.probe    = init_one,
 	.remove   = remove_one,
 };
 
-static int __init t1_init_module(void)
-{
-	return pci_register_driver(&driver);
-}
-
-static void __exit t1_cleanup_module(void)
-{
-	pci_unregister_driver(&driver);
-}
-
-module_init(t1_init_module);
-module_exit(t1_cleanup_module);
+module_pci_driver(cxgb_pci_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c	2013-07-01 10:36:36.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c	2013-08-31 17:56:08.000000000 -0400
@@ -3030,7 +3030,9 @@ static void t3_io_resume(struct pci_dev
 	CH_ALERT(adapter, "adapter recovering, PEX ERR 0x%x\n",
 		 t3_read_reg(adapter, A_PCIE_PEX_ERR));
 
+	rtnl_lock();
 	t3_resume_ports(adapter);
+	rtnl_unlock();
 }
 
 static const struct pci_error_handlers t3_err_handler = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c	2013-08-25 20:43:22.000000000 -0400
@@ -1246,6 +1246,7 @@ int cxgb3_offload_activate(struct adapte
 	struct tid_range stid_range, tid_range;
 	struct mtutab mtutab;
 	unsigned int l2t_capacity;
+	struct l2t_data *l2td;
 
 	t = kzalloc(sizeof(*t), GFP_KERNEL);
 	if (!t)
@@ -1261,8 +1262,8 @@ int cxgb3_offload_activate(struct adapte
 		goto out_free;
 
 	err = -ENOMEM;
-	RCU_INIT_POINTER(dev->l2opt, t3_init_l2t(l2t_capacity));
-	if (!L2DATA(dev))
+	l2td = t3_init_l2t(l2t_capacity);
+	if (!l2td)
 		goto out_free;
 
 	natids = min(tid_range.num / 2, MAX_ATIDS);
@@ -1279,6 +1280,7 @@ int cxgb3_offload_activate(struct adapte
 	INIT_LIST_HEAD(&t->list_node);
 	t->dev = dev;
 
+	RCU_INIT_POINTER(dev->l2opt, l2td);
 	T3C_DATA(dev) = t;
 	dev->recv = process_rx;
 	dev->neigh_update = t3_l2t_update;
@@ -1294,8 +1296,7 @@ int cxgb3_offload_activate(struct adapte
 	return 0;
 
 out_free_l2t:
-	t3_free_l2t(L2DATA(dev));
-	RCU_INIT_POINTER(dev->l2opt, NULL);
+	t3_free_l2t(l2td);
 out_free:
 	kfree(t);
 	return err;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb3/sge.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb3/sge.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb3/sge.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb3/sge.c	2013-08-25 20:43:22.000000000 -0400
@@ -1537,10 +1537,9 @@ static void deferred_unmap_destructor(st
 	dui = (struct deferred_unmap_info *)skb->head;
 	p = dui->addr;
 
-	if (skb->tail - skb->transport_header)
-		pci_unmap_single(dui->pdev, *p++,
-				 skb->tail - skb->transport_header,
-				 PCI_DMA_TODEVICE);
+	if (skb_tail_pointer(skb) - skb_transport_header(skb))
+		pci_unmap_single(dui->pdev, *p++, skb_tail_pointer(skb) -
+				 skb_transport_header(skb), PCI_DMA_TODEVICE);
 
 	si = skb_shinfo(skb);
 	for (i = 0; i < si->nr_frags; i++)
@@ -1627,7 +1626,7 @@ static inline unsigned int calc_tx_descs
 
 	flits = skb_transport_offset(skb) / 8;	/* headers */
 	cnt = skb_shinfo(skb)->nr_frags;
-	if (skb->tail != skb->transport_header)
+	if (skb_tail_pointer(skb) != skb_transport_header(skb))
 		cnt++;
 	return flits_to_desc(flits + sgl_len(cnt));
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h	2013-08-25 20:43:22.000000000 -0400
@@ -51,7 +51,7 @@
 #include "t4_hw.h"
 
 #define FW_VERSION_MAJOR 1
-#define FW_VERSION_MINOR 1
+#define FW_VERSION_MINOR 4
 #define FW_VERSION_MICRO 0
 
 #define FW_VERSION_MAJOR_T5 0
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c	2013-07-01 10:36:40.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c	2013-08-31 17:56:12.000000000 -0400
@@ -4841,8 +4841,17 @@ static int adap_init0(struct adapter *ad
 	 * is excessively mismatched relative to the driver.)
 	 */
 	ret = t4_check_fw_version(adap);
+
+	/* The error code -EFAULT is returned by t4_check_fw_version() if
+	 * firmware on adapter < supported firmware. If firmware on adapter
+	 * is too old (not supported by driver) and we're the MASTER_PF set
+	 * adapter state to DEV_STATE_UNINIT to force firmware upgrade
+	 * and reinitialization.
+	 */
+	if ((adap->flags & MASTER_PF) && ret == -EFAULT)
+		state = DEV_STATE_UNINIT;
 	if ((adap->flags & MASTER_PF) && state != DEV_STATE_INIT) {
-		if (ret == -EINVAL || ret > 0) {
+		if (ret == -EINVAL || ret == -EFAULT || ret > 0) {
 			if (upgrade_fw(adap) >= 0) {
 				/*
 				 * Note that the chip was reset as part of the
@@ -4851,7 +4860,21 @@ static int adap_init0(struct adapter *ad
 				 */
 				reset = 0;
 				ret = t4_check_fw_version(adap);
-			}
+			} else
+				if (ret == -EFAULT) {
+					/*
+					 * Firmware is old but still might
+					 * work if we force reinitialization
+					 * of the adapter. Ignoring FW upgrade
+					 * failure.
+					 */
+					dev_warn(adap->pdev_dev,
+						 "Ignoring firmware upgrade "
+						 "failure, and forcing driver "
+						 "to reinitialize the "
+						 "adapter.\n");
+					ret = 0;
+				}
 		}
 		if (ret < 0)
 			return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb4/sge.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/sge.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb4/sge.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/sge.c	2013-08-25 20:43:22.000000000 -0400
@@ -1294,7 +1294,7 @@ static inline unsigned int calc_tx_flits
 
 	flits = skb_transport_offset(skb) / 8U;   /* headers */
 	cnt = skb_shinfo(skb)->nr_frags;
-	if (skb->tail != skb->transport_header)
+	if (skb_tail_pointer(skb) != skb_transport_header(skb))
 		cnt++;
 	return flits + sgl_len(cnt);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -938,6 +938,15 @@ int t4_check_fw_version(struct adapter *
 	memcpy(adapter->params.api_vers, api_vers,
 	       sizeof(adapter->params.api_vers));
 
+	if (major < exp_major || (major == exp_major && minor < exp_minor) ||
+	    (major == exp_major && minor == exp_minor && micro < exp_micro)) {
+		dev_err(adapter->pdev_dev,
+			"Card has firmware version %u.%u.%u, minimum "
+			"supported firmware is %u.%u.%u.\n", major, minor,
+			micro, exp_major, exp_minor, exp_micro);
+		return -EFAULT;
+	}
+
 	if (major != exp_major) {            /* major mismatch - fail */
 		dev_err(adapter->pdev_dev,
 			"card FW has major version %u, driver wants %u\n",
@@ -3773,7 +3782,6 @@ int t4_port_init(struct adapter *adap, i
 		p->lport = j;
 		p->rss_size = rss_size;
 		memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
-		adap->port[i]->dev_id = j;
 
 		ret = ntohl(c.u.info.lstatus_to_modtype);
 		p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP) ?
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c	2013-08-25 20:43:22.000000000 -0400
@@ -783,7 +783,6 @@ static int ep93xx_eth_remove(struct plat
 	dev = platform_get_drvdata(pdev);
 	if (dev == NULL)
 		return 0;
-	platform_set_drvdata(pdev, NULL);
 
 	ep = netdev_priv(dev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/cirrus/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cirrus/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/cirrus/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cirrus/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -44,7 +44,6 @@ config CS89x0_PLATFORM
 config EP93XX_ETH
 	tristate "EP93xx Ethernet support"
 	depends on ARM && ARCH_EP93XX
-	select NET_CORE
 	select MII
 	help
 	  This is a driver for the ethernet hardware included in EP93xx CPUs.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/cisco/enic/enic_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cisco/enic/enic_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/cisco/enic/enic_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/cisco/enic/enic_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1761,6 +1761,7 @@ static void enic_change_mtu_work(struct
 	enic_synchronize_irqs(enic);
 	err = vnic_rq_disable(&enic->rq[0]);
 	if (err) {
+		rtnl_unlock();
 		netdev_err(netdev, "Unable to disable RQ.\n");
 		return;
 	}
@@ -1773,6 +1774,7 @@ static void enic_change_mtu_work(struct
 	vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
 	/* Need at least one buffer on ring to get going */
 	if (vnic_rq_desc_used(&enic->rq[0]) == 0) {
+		rtnl_unlock();
 		netdev_err(netdev, "Unable to alloc receive buffers.\n");
 		return;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/davicom/dm9000.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/davicom/dm9000.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/davicom/dm9000.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/davicom/dm9000.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,8 @@
 #include <linux/spinlock.h>
 #include <linux/crc32.h>
 #include <linux/mii.h>
+#include <linux/of.h>
+#include <linux/of_net.h>
 #include <linux/ethtool.h>
 #include <linux/dm9000.h>
 #include <linux/delay.h>
@@ -827,7 +829,7 @@ dm9000_hash_table_unlocked(struct net_de
 	struct netdev_hw_addr *ha;
 	int i, oft;
 	u32 hash_val;
-	u16 hash_table[4];
+	u16 hash_table[4] = { 0, 0, 0, 0x8000 }; /* broadcast address */
 	u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;
 
 	dm9000_dbg(db, 1, "entering %s\n", __func__);
@@ -835,13 +837,6 @@ dm9000_hash_table_unlocked(struct net_de
 	for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
 		iow(db, oft, dev->dev_addr[i]);
 
-	/* Clear Hash Table */
-	for (i = 0; i < 4; i++)
-		hash_table[i] = 0x0;
-
-	/* broadcast address */
-	hash_table[3] = 0x8000;
-
 	if (dev->flags & IFF_PROMISC)
 		rcr |= RCR_PRMSC;
 
@@ -1358,6 +1353,31 @@ static const struct net_device_ops dm900
 #endif
 };
 
+static struct dm9000_plat_data *dm9000_parse_dt(struct device *dev)
+{
+	struct dm9000_plat_data *pdata;
+	struct device_node *np = dev->of_node;
+	const void *mac_addr;
+
+	if (!IS_ENABLED(CONFIG_OF) || !np)
+		return NULL;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	if (of_find_property(np, "davicom,ext-phy", NULL))
+		pdata->flags |= DM9000_PLATF_EXT_PHY;
+	if (of_find_property(np, "davicom,no-eeprom", NULL))
+		pdata->flags |= DM9000_PLATF_NO_EEPROM;
+
+	mac_addr = of_get_mac_address(np);
+	if (mac_addr)
+		memcpy(pdata->dev_addr, mac_addr, sizeof(pdata->dev_addr));
+
+	return pdata;
+}
+
 /*
  * Search DM9000 board, allocate space and register it
  */
@@ -1373,6 +1393,12 @@ dm9000_probe(struct platform_device *pde
 	int i;
 	u32 id_val;
 
+	if (!pdata) {
+		pdata = dm9000_parse_dt(&pdev->dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+	}
+
 	/* Init network device */
 	ndev = alloc_etherdev(sizeof(struct board_info));
 	if (!ndev)
@@ -1673,8 +1699,6 @@ dm9000_drv_remove(struct platform_device
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	unregister_netdev(ndev);
 	dm9000_release_board(pdev, netdev_priv(ndev));
 	free_netdev(ndev);		/* free device structure */
@@ -1683,11 +1707,20 @@ dm9000_drv_remove(struct platform_device
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id dm9000_of_matches[] = {
+	{ .compatible = "davicom,dm9000", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dm9000_of_matches);
+#endif
+
 static struct platform_driver dm9000_driver = {
 	.driver	= {
 		.name    = "dm9000",
 		.owner	 = THIS_MODULE,
 		.pm	 = &dm9000_drv_pm_ops,
+		.of_match_table = of_match_ptr(dm9000_of_matches),
 	},
 	.probe   = dm9000_probe,
 	.remove  = dm9000_drv_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/davicom/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/davicom/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/davicom/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/davicom/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,6 @@ config DM9000
 	tristate "DM9000 support"
 	depends on ARM || BLACKFIN || MIPS || COLDFIRE
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  Support for DM9000 chipset.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/dec/tulip/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/dec/tulip/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/dec/tulip/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/dec/tulip/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -126,7 +126,6 @@ config WINBOND_840
 	tristate "Winbond W89c840 Ethernet support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This driver is for the Winbond W89c840 chip.  It also works with 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/dec/tulip/tulip_core.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/dec/tulip/tulip_core.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/dec/tulip/tulip_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/dec/tulip/tulip_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -1410,12 +1410,6 @@ static int tulip_init_one(struct pci_dev
 		return i;
 	}
 
-	/* The chip will fail to enter a low-power state later unless
-	 * first explicitly commanded into D0 */
-	if (pci_set_power_state(pdev, PCI_D0)) {
-		pr_notice("Failed to set power state to D0\n");
-	}
-
 	irq = pdev->irq;
 
 	/* alloc_etherdev ensures aligned and zeroed private structures */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/dec/tulip/xircom_cb.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/dec/tulip/xircom_cb.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/dec/tulip/xircom_cb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/dec/tulip/xircom_cb.c	2013-08-25 20:43:22.000000000 -0400
@@ -1171,16 +1171,4 @@ investigate_write_descriptor(struct net_
 	}
 }
 
-static int __init xircom_init(void)
-{
-	return pci_register_driver(&xircom_ops);
-}
-
-static void __exit xircom_exit(void)
-{
-	pci_unregister_driver(&xircom_ops);
-}
-
-module_init(xircom_init)
-module_exit(xircom_exit)
-
+module_pci_driver(xircom_ops);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/dlink/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/dlink/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/dlink/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/dlink/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,6 @@ config SUNDANCE
 	tristate "Sundance Alta support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This driver is for the Sundance "Alta" chip.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_cmds.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_cmds.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_cmds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_cmds.c	2013-08-25 20:43:22.000000000 -0400
@@ -3048,6 +3048,9 @@ int be_cmd_get_func_config(struct be_ada
 
 		adapter->max_event_queues = le16_to_cpu(desc->eq_count);
 		adapter->if_cap_flags = le32_to_cpu(desc->cap_flags);
+
+		/* Clear flags that driver is not interested in */
+		adapter->if_cap_flags &=  BE_IF_CAP_FLAGS_WANT;
 	}
 err:
 	mutex_unlock(&adapter->mbox_lock);
@@ -3255,6 +3258,72 @@ err:
 	return status;
 }
 
+static int lancer_wait_idle(struct be_adapter *adapter)
+{
+#define SLIPORT_IDLE_TIMEOUT 30
+	u32 reg_val;
+	int status = 0, i;
+
+	for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
+		reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
+		if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
+			break;
+
+		ssleep(1);
+	}
+
+	if (i == SLIPORT_IDLE_TIMEOUT)
+		status = -1;
+
+	return status;
+}
+
+int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask)
+{
+	int status = 0;
+
+	status = lancer_wait_idle(adapter);
+	if (status)
+		return status;
+
+	iowrite32(mask, adapter->db + PHYSDEV_CONTROL_OFFSET);
+
+	return status;
+}
+
+/* Routine to check whether dump image is present or not */
+bool dump_present(struct be_adapter *adapter)
+{
+	u32 sliport_status = 0;
+
+	sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
+	return !!(sliport_status & SLIPORT_STATUS_DIP_MASK);
+}
+
+int lancer_initiate_dump(struct be_adapter *adapter)
+{
+	int status;
+
+	/* give firmware reset and diagnostic dump */
+	status = lancer_physdev_ctrl(adapter, PHYSDEV_CONTROL_FW_RESET_MASK |
+				     PHYSDEV_CONTROL_DD_MASK);
+	if (status < 0) {
+		dev_err(&adapter->pdev->dev, "Firmware reset failed\n");
+		return status;
+	}
+
+	status = lancer_wait_idle(adapter);
+	if (status)
+		return status;
+
+	if (!dump_present(adapter)) {
+		dev_err(&adapter->pdev->dev, "Dump image not present\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 /* Uses sync mcc */
 int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_cmds.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_cmds.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_cmds.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_cmds.h	2013-08-25 20:43:22.000000000 -0400
@@ -563,6 +563,12 @@ enum be_if_flags {
 	BE_IF_FLAGS_MULTICAST = 0x1000
 };
 
+#define BE_IF_CAP_FLAGS_WANT (BE_IF_FLAGS_RSS | BE_IF_FLAGS_PROMISCUOUS |\
+			 BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_VLAN_PROMISCUOUS |\
+			 BE_IF_FLAGS_VLAN | BE_IF_FLAGS_MCAST_PROMISCUOUS |\
+			 BE_IF_FLAGS_PASS_L3L4_ERRORS | BE_IF_FLAGS_MULTICAST |\
+			 BE_IF_FLAGS_UNTAGGED)
+
 /* An RX interface is an object with one or more MAC addresses and
  * filtering capabilities. */
 struct be_cmd_req_if_create {
@@ -1937,6 +1943,9 @@ extern int be_cmd_set_ext_fat_capabilite
 					  struct be_dma_mem *cmd,
 					  struct be_fat_conf_params *cfgs);
 extern int lancer_wait_ready(struct be_adapter *adapter);
+extern int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask);
+extern int lancer_initiate_dump(struct be_adapter *adapter);
+extern bool dump_present(struct be_adapter *adapter);
 extern int lancer_test_and_set_rdy_state(struct be_adapter *adapter);
 extern int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name);
 extern int be_cmd_get_func_config(struct be_adapter *adapter);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -177,19 +177,15 @@ static void be_get_drvinfo(struct net_de
 				struct ethtool_drvinfo *drvinfo)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	char fw_on_flash[FW_VER_LEN];
-
-	memset(fw_on_flash, 0 , sizeof(fw_on_flash));
-	be_cmd_get_fw_ver(adapter, adapter->fw_ver, fw_on_flash);
 
 	strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
 	strlcpy(drvinfo->version, DRV_VER, sizeof(drvinfo->version));
-	if (!memcmp(adapter->fw_ver, fw_on_flash, FW_VER_LEN))
+	if (!memcmp(adapter->fw_ver, adapter->fw_on_flash, FW_VER_LEN))
 		strlcpy(drvinfo->fw_version, adapter->fw_ver,
 			sizeof(drvinfo->fw_version));
 	else
 		snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
-			 "%s [%s]", adapter->fw_ver, fw_on_flash);
+			 "%s [%s]", adapter->fw_ver, adapter->fw_on_flash);
 
 	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
 		sizeof(drvinfo->bus_info));
@@ -673,6 +669,34 @@ be_set_phys_id(struct net_device *netdev
 	return 0;
 }
 
+static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+	struct device *dev = &adapter->pdev->dev;
+	int status;
+
+	if (!lancer_chip(adapter)) {
+		dev_err(dev, "FW dump not supported\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (dump_present(adapter)) {
+		dev_err(dev, "Previous dump not cleared, not forcing dump\n");
+		return 0;
+	}
+
+	switch (dump->flag) {
+	case LANCER_INITIATE_FW_DUMP:
+		status = lancer_initiate_dump(adapter);
+		if (!status)
+			dev_info(dev, "F/w dump initiated successfully\n");
+		break;
+	default:
+		dev_err(dev, "Invalid dump level: 0x%x\n", dump->flag);
+		return -EINVAL;
+	}
+	return status;
+}
 
 static void
 be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
@@ -1110,6 +1134,7 @@ const struct ethtool_ops be_ethtool_ops
 	.set_pauseparam = be_set_pauseparam,
 	.get_strings = be_get_stat_strings,
 	.set_phys_id = be_set_phys_id,
+	.set_dump = be_set_dump,
 	.get_msglevel = be_get_msg_level,
 	.set_msglevel = be_set_msg_level,
 	.get_sset_count = be_get_sset_count,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be.h	2013-08-25 20:43:22.000000000 -0400
@@ -333,6 +333,9 @@ enum vf_state {
 #define BE_VF_UC_PMAC_COUNT		2
 #define BE_FLAGS_QNQ_ASYNC_EVT_RCVD		(1 << 11)
 
+/* Ethtool set_dump flags */
+#define LANCER_INITIATE_FW_DUMP			0x1
+
 struct phy_info {
 	u8 transceiver;
 	u8 autoneg;
@@ -398,6 +401,7 @@ struct be_adapter {
 	u32 cmd_privileges;
 	/* Ethtool knobs and info */
 	char fw_ver[FW_VER_LEN];
+	char fw_on_flash[FW_VER_LEN];
 	int if_handle;		/* Used to configure filtering */
 	u32 *pmac_id;		/* MAC addr handle used by BE card */
 	u32 beacon_state;	/* for set_phys_id */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_hw.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_hw.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -53,10 +53,12 @@
 #define PHYSDEV_CONTROL_OFFSET		0x414
 
 #define SLIPORT_STATUS_ERR_MASK		0x80000000
+#define SLIPORT_STATUS_DIP_MASK		0x02000000
 #define SLIPORT_STATUS_RN_MASK		0x01000000
 #define SLIPORT_STATUS_RDY_MASK		0x00800000
 #define SLI_PORT_CONTROL_IP_MASK	0x08000000
 #define PHYSDEV_CONTROL_FW_RESET_MASK	0x00000002
+#define PHYSDEV_CONTROL_DD_MASK		0x00000004
 #define PHYSDEV_CONTROL_INP_MASK	0x40000000
 
 #define SLIPORT_ERROR_NO_RESOURCE1	0x2
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/emulex/benet/be_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/emulex/benet/be_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -782,16 +782,22 @@ static struct sk_buff *be_insert_vlan_in
 
 	if (vlan_tx_tag_present(skb))
 		vlan_tag = be_get_tx_vlan_tag(adapter, skb);
-	else if (qnq_async_evt_rcvd(adapter) && adapter->pvid)
-		vlan_tag = adapter->pvid;
+
+	if (qnq_async_evt_rcvd(adapter) && adapter->pvid) {
+		if (!vlan_tag)
+			vlan_tag = adapter->pvid;
+		/* f/w workaround to set skip_hw_vlan = 1, informs the F/W to
+		 * skip VLAN insertion
+		 */
+		if (skip_hw_vlan)
+			*skip_hw_vlan = true;
+	}
 
 	if (vlan_tag) {
 		skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
 		if (unlikely(!skb))
 			return skb;
 		skb->vlan_tci = 0;
-		if (skip_hw_vlan)
-			*skip_hw_vlan = true;
 	}
 
 	/* Insert the outer VLAN, if any */
@@ -834,32 +840,39 @@ static int be_vlan_tag_tx_chk(struct be_
 	return vlan_tx_tag_present(skb) || adapter->pvid || adapter->qnq_vid;
 }
 
-static int be_ipv6_tx_stall_chk(struct be_adapter *adapter, struct sk_buff *skb)
+static int be_ipv6_tx_stall_chk(struct be_adapter *adapter,
+				struct sk_buff *skb)
 {
-	return BE3_chip(adapter) &&
-		be_ipv6_exthdr_check(skb);
+	return BE3_chip(adapter) && be_ipv6_exthdr_check(skb);
 }
 
-static netdev_tx_t be_xmit(struct sk_buff *skb,
-			struct net_device *netdev)
+static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
+					   struct sk_buff *skb,
+					   bool *skip_hw_vlan)
 {
-	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_tx_obj *txo = &adapter->tx_obj[skb_get_queue_mapping(skb)];
-	struct be_queue_info *txq = &txo->q;
-	struct iphdr *ip = NULL;
-	u32 wrb_cnt = 0, copied = 0;
-	u32 start = txq->head, eth_hdr_len;
-	bool dummy_wrb, stopped = false;
-	bool skip_hw_vlan = false;
 	struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
+	unsigned int eth_hdr_len;
+	struct iphdr *ip;
 
-	eth_hdr_len = ntohs(skb->protocol) == ETH_P_8021Q ?
-		VLAN_ETH_HLEN : ETH_HLEN;
+	/* Lancer ASIC has a bug wherein packets that are 32 bytes or less
+	 * may cause a transmit stall on that port. So the work-around is to
+	 * pad such packets to a 36-byte length.
+	 */
+	if (unlikely(lancer_chip(adapter) && skb->len <= 32)) {
+		if (skb_padto(skb, 36))
+			goto tx_drop;
+		skb->len = 36;
+	}
 
 	/* For padded packets, BE HW modifies tot_len field in IP header
 	 * incorrecly when VLAN tag is inserted by HW.
+	 * For padded packets, Lancer computes incorrect checksum.
 	 */
-	if (skb->len <= 60 && vlan_tx_tag_present(skb) && is_ipv4_pkt(skb)) {
+	eth_hdr_len = ntohs(skb->protocol) == ETH_P_8021Q ?
+						VLAN_ETH_HLEN : ETH_HLEN;
+	if (skb->len <= 60 &&
+	    (lancer_chip(adapter) || vlan_tx_tag_present(skb)) &&
+	    is_ipv4_pkt(skb)) {
 		ip = (struct iphdr *)ip_hdr(skb);
 		pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len));
 	}
@@ -869,15 +882,15 @@ static netdev_tx_t be_xmit(struct sk_buf
 	 */
 	if ((adapter->function_mode & UMC_ENABLED) &&
 	    veh->h_vlan_proto == htons(ETH_P_8021Q))
-			skip_hw_vlan = true;
+			*skip_hw_vlan = true;
 
 	/* HW has a bug wherein it will calculate CSUM for VLAN
 	 * pkts even though it is disabled.
 	 * Manually insert VLAN in pkt.
 	 */
 	if (skb->ip_summed != CHECKSUM_PARTIAL &&
-			vlan_tx_tag_present(skb)) {
-		skb = be_insert_vlan_in_pkt(adapter, skb, &skip_hw_vlan);
+	    vlan_tx_tag_present(skb)) {
+		skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan);
 		if (unlikely(!skb))
 			goto tx_drop;
 	}
@@ -887,8 +900,8 @@ static netdev_tx_t be_xmit(struct sk_buf
 	 * skip HW tagging is not enabled by FW.
 	 */
 	if (unlikely(be_ipv6_tx_stall_chk(adapter, skb) &&
-		     (adapter->pvid || adapter->qnq_vid) &&
-		     !qnq_async_evt_rcvd(adapter)))
+	    (adapter->pvid || adapter->qnq_vid) &&
+	    !qnq_async_evt_rcvd(adapter)))
 		goto tx_drop;
 
 	/* Manual VLAN tag insertion to prevent:
@@ -899,11 +912,31 @@ static netdev_tx_t be_xmit(struct sk_buf
 	 */
 	if (be_ipv6_tx_stall_chk(adapter, skb) &&
 	    be_vlan_tag_tx_chk(adapter, skb)) {
-		skb = be_insert_vlan_in_pkt(adapter, skb, &skip_hw_vlan);
+		skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan);
 		if (unlikely(!skb))
 			goto tx_drop;
 	}
 
+	return skb;
+tx_drop:
+	dev_kfree_skb_any(skb);
+	return NULL;
+}
+
+static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+	struct be_tx_obj *txo = &adapter->tx_obj[skb_get_queue_mapping(skb)];
+	struct be_queue_info *txq = &txo->q;
+	bool dummy_wrb, stopped = false;
+	u32 wrb_cnt = 0, copied = 0;
+	bool skip_hw_vlan = false;
+	u32 start = txq->head;
+
+	skb = be_xmit_workarounds(adapter, skb, &skip_hw_vlan);
+	if (!skb)
+		return NETDEV_TX_OK;
+
 	wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb);
 
 	copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb,
@@ -933,7 +966,6 @@ static netdev_tx_t be_xmit(struct sk_buf
 		txq->head = start;
 		dev_kfree_skb_any(skb);
 	}
-tx_drop:
 	return NETDEV_TX_OK;
 }
 
@@ -1236,30 +1268,6 @@ static int be_set_vf_tx_rate(struct net_
 	return status;
 }
 
-static int be_find_vfs(struct be_adapter *adapter, int vf_state)
-{
-	struct pci_dev *dev, *pdev = adapter->pdev;
-	int vfs = 0, assigned_vfs = 0, pos;
-	u16 offset, stride;
-
-	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
-	if (!pos)
-		return 0;
-	pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset);
-	pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride);
-
-	dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL);
-	while (dev) {
-		if (dev->is_virtfn && pci_physfn(dev) == pdev) {
-			vfs++;
-			if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
-				assigned_vfs++;
-		}
-		dev = pci_get_device(pdev->vendor, PCI_ANY_ID, dev);
-	}
-	return (vf_state == ASSIGNED) ? assigned_vfs : vfs;
-}
-
 static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo)
 {
 	struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]);
@@ -2555,8 +2563,8 @@ static int be_close(struct net_device *n
 	/* Wait for all pending tx completions to arrive so that
 	 * all tx skbs are freed.
 	 */
-	be_tx_compl_clean(adapter);
 	netif_tx_disable(netdev);
+	be_tx_compl_clean(adapter);
 
 	be_rx_qs_destroy(adapter);
 
@@ -2771,7 +2779,7 @@ static void be_vf_clear(struct be_adapte
 	struct be_vf_cfg *vf_cfg;
 	u32 vf;
 
-	if (be_find_vfs(adapter, ASSIGNED)) {
+	if (pci_vfs_assigned(adapter->pdev)) {
 		dev_warn(&adapter->pdev->dev,
 			 "VFs are assigned to VMs: not disabling VFs\n");
 		goto done;
@@ -2873,7 +2881,7 @@ static int be_vf_setup(struct be_adapter
 	int status, old_vfs, vf;
 	struct device *dev = &adapter->pdev->dev;
 
-	old_vfs = be_find_vfs(adapter, ENABLED);
+	old_vfs = pci_num_vf(adapter->pdev);
 	if (old_vfs) {
 		dev_info(dev, "%d VFs are already enabled\n", old_vfs);
 		if (old_vfs != num_vfs)
@@ -3184,7 +3192,7 @@ static int be_setup(struct be_adapter *a
 	if (status)
 		goto err;
 
-	be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
+	be_cmd_get_fw_ver(adapter, adapter->fw_ver, adapter->fw_on_flash);
 
 	if (adapter->vlans_added)
 		be_vid_config(adapter);
@@ -3530,40 +3538,6 @@ static int be_flash_skyhawk(struct be_ad
 	return 0;
 }
 
-static int lancer_wait_idle(struct be_adapter *adapter)
-{
-#define SLIPORT_IDLE_TIMEOUT 30
-	u32 reg_val;
-	int status = 0, i;
-
-	for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
-		reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
-		if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
-			break;
-
-		ssleep(1);
-	}
-
-	if (i == SLIPORT_IDLE_TIMEOUT)
-		status = -1;
-
-	return status;
-}
-
-static int lancer_fw_reset(struct be_adapter *adapter)
-{
-	int status = 0;
-
-	status = lancer_wait_idle(adapter);
-	if (status)
-		return status;
-
-	iowrite32(PHYSDEV_CONTROL_FW_RESET_MASK, adapter->db +
-		  PHYSDEV_CONTROL_OFFSET);
-
-	return status;
-}
-
 static int lancer_fw_download(struct be_adapter *adapter,
 				const struct firmware *fw)
 {
@@ -3641,7 +3615,8 @@ static int lancer_fw_download(struct be_
 	}
 
 	if (change_status == LANCER_FW_RESET_NEEDED) {
-		status = lancer_fw_reset(adapter);
+		status = lancer_physdev_ctrl(adapter,
+					     PHYSDEV_CONTROL_FW_RESET_MASK);
 		if (status) {
 			dev_err(&adapter->pdev->dev,
 				"Adapter busy for FW reset.\n"
@@ -3776,6 +3751,10 @@ int be_load_fw(struct be_adapter *adapte
 	else
 		status = be_fw_download(adapter, fw);
 
+	if (!status)
+		be_cmd_get_fw_ver(adapter, adapter->fw_ver,
+				  adapter->fw_on_flash);
+
 fw_exit:
 	release_firmware(fw);
 	return status;
@@ -4203,9 +4182,10 @@ reschedule:
 	schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
 }
 
+/* If any VFs are already enabled don't FLR the PF */
 static bool be_reset_required(struct be_adapter *adapter)
 {
-	return be_find_vfs(adapter, ENABLED) > 0 ? false : true;
+	return pci_num_vf(adapter->pdev) ? false : true;
 }
 
 static char *mc_name(struct be_adapter *adapter)
@@ -4390,7 +4370,7 @@ static int be_resume(struct pci_dev *pde
 	if (status)
 		return status;
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
 	/* tell fw we're ready to fire cmds */
@@ -4486,7 +4466,7 @@ static pci_ers_result_t be_eeh_reset(str
 		return PCI_ERS_RESULT_DISCONNECT;
 
 	pci_set_master(pdev);
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
 	/* Check if card is ok and fw is ready */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ethoc.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ethoc.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ethoc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ethoc.c	2013-08-25 20:43:22.000000000 -0400
@@ -1147,8 +1147,6 @@ static int ethoc_remove(struct platform_
 	struct net_device *netdev = platform_get_drvdata(pdev);
 	struct ethoc *priv = netdev_priv(netdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	if (netdev) {
 		netif_napi_del(&priv->napi);
 		phy_disconnect(priv->phy);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/faraday/ftgmac100.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/faraday/ftgmac100.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/faraday/ftgmac100.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/faraday/ftgmac100.c	2013-08-25 20:43:22.000000000 -0400
@@ -1311,7 +1311,6 @@ err_ioremap:
 	release_resource(priv->res);
 err_req_mem:
 	netif_napi_del(&priv->napi);
-	platform_set_drvdata(pdev, NULL);
 	free_netdev(netdev);
 err_alloc_etherdev:
 	return err;
@@ -1335,7 +1334,6 @@ static int __exit ftgmac100_remove(struc
 	release_resource(priv->res);
 
 	netif_napi_del(&priv->napi);
-	platform_set_drvdata(pdev, NULL);
 	free_netdev(netdev);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/faraday/ftmac100.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/faraday/ftmac100.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/faraday/ftmac100.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/faraday/ftmac100.c	2013-08-25 20:43:22.000000000 -0400
@@ -1149,7 +1149,6 @@ err_ioremap:
 	release_resource(priv->res);
 err_req_mem:
 	netif_napi_del(&priv->napi);
-	platform_set_drvdata(pdev, NULL);
 	free_netdev(netdev);
 err_alloc_etherdev:
 	return err;
@@ -1169,7 +1168,6 @@ static int __exit ftmac100_remove(struct
 	release_resource(priv->res);
 
 	netif_napi_del(&priv->napi);
-	platform_set_drvdata(pdev, NULL);
 	free_netdev(netdev);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/faraday/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/faraday/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/faraday/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/faraday/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -21,7 +21,6 @@ if NET_VENDOR_FARADAY
 config FTMAC100
 	tristate "Faraday FTMAC100 10/100 Ethernet support"
 	depends on ARM
-	select NET_CORE
 	select MII
 	---help---
 	  This driver supports the FTMAC100 10/100 Ethernet controller
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fec.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fec.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fec.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fec.h	2013-08-25 20:43:22.000000000 -0400
@@ -60,6 +60,61 @@
 #define BM_MIIGSK_CFGR_RMII		0x01
 #define BM_MIIGSK_CFGR_FRCONT_10M	0x40
 
+#define RMON_T_DROP		0x200 /* Count of frames not cntd correctly */
+#define RMON_T_PACKETS		0x204 /* RMON TX packet count */
+#define RMON_T_BC_PKT		0x208 /* RMON TX broadcast pkts */
+#define RMON_T_MC_PKT		0x20C /* RMON TX multicast pkts */
+#define RMON_T_CRC_ALIGN	0x210 /* RMON TX pkts with CRC align err */
+#define RMON_T_UNDERSIZE	0x214 /* RMON TX pkts < 64 bytes, good CRC */
+#define RMON_T_OVERSIZE		0x218 /* RMON TX pkts > MAX_FL bytes good CRC */
+#define RMON_T_FRAG		0x21C /* RMON TX pkts < 64 bytes, bad CRC */
+#define RMON_T_JAB		0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */
+#define RMON_T_COL		0x224 /* RMON TX collision count */
+#define RMON_T_P64		0x228 /* RMON TX 64 byte pkts */
+#define RMON_T_P65TO127		0x22C /* RMON TX 65 to 127 byte pkts */
+#define RMON_T_P128TO255	0x230 /* RMON TX 128 to 255 byte pkts */
+#define RMON_T_P256TO511	0x234 /* RMON TX 256 to 511 byte pkts */
+#define RMON_T_P512TO1023	0x238 /* RMON TX 512 to 1023 byte pkts */
+#define RMON_T_P1024TO2047	0x23C /* RMON TX 1024 to 2047 byte pkts */
+#define RMON_T_P_GTE2048	0x240 /* RMON TX pkts > 2048 bytes */
+#define RMON_T_OCTETS		0x244 /* RMON TX octets */
+#define IEEE_T_DROP		0x248 /* Count of frames not counted crtly */
+#define IEEE_T_FRAME_OK		0x24C /* Frames tx'd OK */
+#define IEEE_T_1COL		0x250 /* Frames tx'd with single collision */
+#define IEEE_T_MCOL		0x254 /* Frames tx'd with multiple collision */
+#define IEEE_T_DEF		0x258 /* Frames tx'd after deferral delay */
+#define IEEE_T_LCOL		0x25C /* Frames tx'd with late collision */
+#define IEEE_T_EXCOL		0x260 /* Frames tx'd with excesv collisions */
+#define IEEE_T_MACERR		0x264 /* Frames tx'd with TX FIFO underrun */
+#define IEEE_T_CSERR		0x268 /* Frames tx'd with carrier sense err */
+#define IEEE_T_SQE		0x26C /* Frames tx'd with SQE err */
+#define IEEE_T_FDXFC		0x270 /* Flow control pause frames tx'd */
+#define IEEE_T_OCTETS_OK	0x274 /* Octet count for frames tx'd w/o err */
+#define RMON_R_PACKETS		0x284 /* RMON RX packet count */
+#define RMON_R_BC_PKT		0x288 /* RMON RX broadcast pkts */
+#define RMON_R_MC_PKT		0x28C /* RMON RX multicast pkts */
+#define RMON_R_CRC_ALIGN	0x290 /* RMON RX pkts with CRC alignment err */
+#define RMON_R_UNDERSIZE	0x294 /* RMON RX pkts < 64 bytes, good CRC */
+#define RMON_R_OVERSIZE		0x298 /* RMON RX pkts > MAX_FL bytes good CRC */
+#define RMON_R_FRAG		0x29C /* RMON RX pkts < 64 bytes, bad CRC */
+#define RMON_R_JAB		0x2A0 /* RMON RX pkts > MAX_FL bytes, bad CRC */
+#define RMON_R_RESVD_O		0x2A4 /* Reserved */
+#define RMON_R_P64		0x2A8 /* RMON RX 64 byte pkts */
+#define RMON_R_P65TO127		0x2AC /* RMON RX 65 to 127 byte pkts */
+#define RMON_R_P128TO255	0x2B0 /* RMON RX 128 to 255 byte pkts */
+#define RMON_R_P256TO511	0x2B4 /* RMON RX 256 to 511 byte pkts */
+#define RMON_R_P512TO1023	0x2B8 /* RMON RX 512 to 1023 byte pkts */
+#define RMON_R_P1024TO2047	0x2BC /* RMON RX 1024 to 2047 byte pkts */
+#define RMON_R_P_GTE2048	0x2C0 /* RMON RX pkts > 2048 bytes */
+#define RMON_R_OCTETS		0x2C4 /* RMON RX octets */
+#define IEEE_R_DROP		0x2C8 /* Count frames not counted correctly */
+#define IEEE_R_FRAME_OK		0x2CC /* Frames rx'd OK */
+#define IEEE_R_CRC		0x2D0 /* Frames rx'd with CRC err */
+#define IEEE_R_ALIGN		0x2D4 /* Frames rx'd with alignment err */
+#define IEEE_R_MACERR		0x2D8 /* Receive FIFO overflow count */
+#define IEEE_R_FDXFC		0x2DC /* Flow control pause frames rx'd */
+#define IEEE_R_OCTETS_OK	0x2E0 /* Octet cnt for frames rx'd w/o err */
+
 #else
 
 #define FEC_ECNTRL		0x000 /* Ethernet control reg */
@@ -148,6 +203,9 @@ struct bufdesc_ex {
 #define BD_ENET_RX_CL           ((ushort)0x0001)
 #define BD_ENET_RX_STATS        ((ushort)0x013f)        /* All status bits */
 
+/* Enhanced buffer descriptor control/status used by Ethernet receive */
+#define BD_ENET_RX_VLAN         0x00000004
+
 /* Buffer descriptor control/status used by Ethernet transmit.
 */
 #define BD_ENET_TX_READY        ((ushort)0x8000)
@@ -201,6 +259,7 @@ struct bufdesc_ex {
 struct fec_enet_delayed_work {
 	struct delayed_work delay_work;
 	bool timeout;
+	bool trig_tx;
 };
 
 /* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
@@ -272,9 +331,10 @@ struct fec_enet_private {
 	int hwts_tx_en;
 	struct timer_list time_keep;
 	struct fec_enet_delayed_work delay_work;
+	struct regulator *reg_phy;
 };
 
-void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev);
+void fec_ptp_init(struct platform_device *pdev);
 void fec_ptp_start_cyclecounter(struct net_device *ndev);
 int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fec_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fec_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fec_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fec_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -53,13 +53,15 @@
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
 #include <linux/of_net.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/regulator/consumer.h>
+#include <linux/if_vlan.h>
 
 #include <asm/cacheflush.h>
 
 #include "fec.h"
 
+static void set_multicast_list(struct net_device *ndev);
+
 #if defined(CONFIG_ARM)
 #define FEC_ALIGNMENT	0xf
 #else
@@ -89,6 +91,22 @@
 #define FEC_QUIRK_HAS_BUFDESC_EX	(1 << 4)
 /* Controller has hardware checksum support */
 #define FEC_QUIRK_HAS_CSUM		(1 << 5)
+/* Controller has hardware vlan support */
+#define FEC_QUIRK_HAS_VLAN		(1 << 6)
+/* ENET IP errata ERR006358
+ *
+ * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously
+ * detected as not set during a prior frame transmission, then the
+ * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs
+ * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in
+ * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously
+ * detected as not set during a prior frame transmission, then the
+ * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs
+ * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in
+ * frames not being transmitted until there is a 0-to-1 transition on
+ * ENET_TDAR[TDAR].
+ */
+#define FEC_QUIRK_ERR006358            (1 << 7)
 
 static struct platform_device_id fec_devtype[] = {
 	{
@@ -107,7 +125,8 @@ static struct platform_device_id fec_dev
 	}, {
 		.name = "imx6q-fec",
 		.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
-				FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM,
+				FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+				FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358,
 	}, {
 		.name = "mvf600-fec",
 		.driver_data = FEC_QUIRK_ENET_MAC,
@@ -178,11 +197,11 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet
 #define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII)
 #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
 
-/* The FEC stores dest/src/type, data, and checksum for receive packets.
+/* The FEC stores dest/src/type/vlan, data, and checksum for receive packets.
  */
-#define PKT_MAXBUF_SIZE		1518
+#define PKT_MAXBUF_SIZE		1522
 #define PKT_MINBUF_SIZE		64
-#define PKT_MAXBLR_SIZE		1520
+#define PKT_MAXBLR_SIZE		1536
 
 /* FEC receive acceleration */
 #define FEC_RACC_IPDIS		(1 << 1)
@@ -243,7 +262,7 @@ static void *swap_buffer(void *bufaddr,
 	int i;
 	unsigned int *buf = bufaddr;
 
-	for (i = 0; i < (len + 3) / 4; i++, buf++)
+	for (i = 0; i < DIV_ROUND_UP(len, 4); i++, buf++)
 		*buf = cpu_to_be32(*buf);
 
 	return bufaddr;
@@ -270,16 +289,11 @@ fec_enet_start_xmit(struct sk_buff *skb,
 	struct fec_enet_private *fep = netdev_priv(ndev);
 	const struct platform_device_id *id_entry =
 				platform_get_device_id(fep->pdev);
-	struct bufdesc *bdp;
+	struct bufdesc *bdp, *bdp_pre;
 	void *bufaddr;
 	unsigned short	status;
 	unsigned int index;
 
-	if (!fep->link) {
-		/* Link is down or auto-negotiation is in progress. */
-		return NETDEV_TX_BUSY;
-	}
-
 	/* Fill in a Tx ring entry */
 	bdp = fep->cur_tx;
 
@@ -365,6 +379,15 @@ fec_enet_start_xmit(struct sk_buff *skb,
 				ebdp->cbd_esc |= BD_ENET_TX_PINS;
 		}
 	}
+
+	bdp_pre = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+	if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
+	    !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {
+		fep->delay_work.trig_tx = true;
+		schedule_delayed_work(&(fep->delay_work.delay_work),
+					msecs_to_jiffies(1));
+	}
+
 	/* If this was the last BD in the ring, start at the beginning again. */
 	if (status & BD_ENET_TX_WRAP)
 		bdp = fep->tx_bd_base;
@@ -471,9 +494,8 @@ fec_restart(struct net_device *ndev, int
 	/* Clear any outstanding interrupt. */
 	writel(0xffc00000, fep->hwp + FEC_IEVENT);
 
-	/* Reset all multicast.	*/
-	writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
-	writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+	/* Setup multicast filter. */
+	set_multicast_list(ndev);
 #ifndef CONFIG_M5272
 	writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
 	writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
@@ -609,6 +631,11 @@ fec_restart(struct net_device *ndev, int
 	if (fep->bufdesc_ex)
 		ecntl |= (1 << 4);
 
+#ifndef CONFIG_M5272
+	/* Enable the MIB statistic event counters */
+	writel(0 << 31, fep->hwp + FEC_MIB_CTRLSTAT);
+#endif
+
 	/* And last, enable the transmit and receive processing */
 	writel(ecntl, fep->hwp + FEC_ECNTRL);
 	writel(0, fep->hwp + FEC_R_DES_ACTIVE);
@@ -680,6 +707,11 @@ static void fec_enet_work(struct work_st
 		fec_restart(fep->netdev, fep->full_duplex);
 		netif_wake_queue(fep->netdev);
 	}
+
+	if (fep->delay_work.trig_tx) {
+		fep->delay_work.trig_tx = false;
+		writel(0, fep->hwp + FEC_X_DES_ACTIVE);
+	}
 }
 
 static void
@@ -735,6 +767,7 @@ fec_enet_tx(struct net_device *ndev)
 				ndev->stats.tx_carrier_errors++;
 		} else {
 			ndev->stats.tx_packets++;
+			ndev->stats.tx_bytes += bdp->cbd_datlen;
 		}
 
 		if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) &&
@@ -800,6 +833,9 @@ fec_enet_rx(struct net_device *ndev, int
 	ushort	pkt_len;
 	__u8 *data;
 	int	pkt_received = 0;
+	struct	bufdesc_ex *ebdp = NULL;
+	bool	vlan_packet_rcvd = false;
+	u16	vlan_tag;
 
 #ifdef CONFIG_M532x
 	flush_cache_all();
@@ -863,6 +899,24 @@ fec_enet_rx(struct net_device *ndev, int
 		if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
 			swap_buffer(data, pkt_len);
 
+		/* Extract the enhanced buffer descriptor */
+		ebdp = NULL;
+		if (fep->bufdesc_ex)
+			ebdp = (struct bufdesc_ex *)bdp;
+
+		/* If this is a VLAN packet remove the VLAN Tag */
+		vlan_packet_rcvd = false;
+		if ((ndev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
+		    fep->bufdesc_ex && (ebdp->cbd_esc & BD_ENET_RX_VLAN)) {
+			/* Push and remove the vlan tag */
+			struct vlan_hdr *vlan_header =
+					(struct vlan_hdr *) (data + ETH_HLEN);
+			vlan_tag = ntohs(vlan_header->h_vlan_TCI);
+			pkt_len -= VLAN_HLEN;
+
+			vlan_packet_rcvd = true;
+		}
+
 		/* This does 16 byte alignment, exactly what we need.
 		 * The packet length includes FCS, but we don't want to
 		 * include that when passing upstream as it messes up
@@ -873,9 +927,18 @@ fec_enet_rx(struct net_device *ndev, int
 		if (unlikely(!skb)) {
 			ndev->stats.rx_dropped++;
 		} else {
+			int payload_offset = (2 * ETH_ALEN);
 			skb_reserve(skb, NET_IP_ALIGN);
 			skb_put(skb, pkt_len - 4);	/* Make room */
-			skb_copy_to_linear_data(skb, data, pkt_len - 4);
+
+			/* Extract the frame data without the VLAN header. */
+			skb_copy_to_linear_data(skb, data, (2 * ETH_ALEN));
+			if (vlan_packet_rcvd)
+				payload_offset = (2 * ETH_ALEN) + VLAN_HLEN;
+			skb_copy_to_linear_data_offset(skb, (2 * ETH_ALEN),
+						       data + payload_offset,
+						       pkt_len - 4 - (2 * ETH_ALEN));
+
 			skb->protocol = eth_type_trans(skb, ndev);
 
 			/* Get receive timestamp from the skb */
@@ -883,8 +946,6 @@ fec_enet_rx(struct net_device *ndev, int
 				struct skb_shared_hwtstamps *shhwtstamps =
 							    skb_hwtstamps(skb);
 				unsigned long flags;
-				struct bufdesc_ex *ebdp =
-					(struct bufdesc_ex *)bdp;
 
 				memset(shhwtstamps, 0, sizeof(*shhwtstamps));
 
@@ -895,9 +956,7 @@ fec_enet_rx(struct net_device *ndev, int
 			}
 
 			if (fep->bufdesc_ex &&
-				(fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
-				struct bufdesc_ex *ebdp =
-					(struct bufdesc_ex *)bdp;
+			    (fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
 				if (!(ebdp->cbd_esc & FLAG_RX_CSUM_ERROR)) {
 					/* don't check it */
 					skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -906,6 +965,12 @@ fec_enet_rx(struct net_device *ndev, int
 				}
 			}
 
+			/* Handle received VLAN packets */
+			if (vlan_packet_rcvd)
+				__vlan_hwaccel_put_tag(skb,
+						       htons(ETH_P_8021Q),
+						       vlan_tag);
+
 			if (!skb_defer_rx_timestamp(skb))
 				napi_gro_receive(&fep->napi, skb);
 		}
@@ -1444,8 +1509,117 @@ static int fec_enet_set_pauseparam(struc
 	return 0;
 }
 
+static const struct fec_stat {
+	char name[ETH_GSTRING_LEN];
+	u16 offset;
+} fec_stats[] = {
+	/* RMON TX */
+	{ "tx_dropped", RMON_T_DROP },
+	{ "tx_packets", RMON_T_PACKETS },
+	{ "tx_broadcast", RMON_T_BC_PKT },
+	{ "tx_multicast", RMON_T_MC_PKT },
+	{ "tx_crc_errors", RMON_T_CRC_ALIGN },
+	{ "tx_undersize", RMON_T_UNDERSIZE },
+	{ "tx_oversize", RMON_T_OVERSIZE },
+	{ "tx_fragment", RMON_T_FRAG },
+	{ "tx_jabber", RMON_T_JAB },
+	{ "tx_collision", RMON_T_COL },
+	{ "tx_64byte", RMON_T_P64 },
+	{ "tx_65to127byte", RMON_T_P65TO127 },
+	{ "tx_128to255byte", RMON_T_P128TO255 },
+	{ "tx_256to511byte", RMON_T_P256TO511 },
+	{ "tx_512to1023byte", RMON_T_P512TO1023 },
+	{ "tx_1024to2047byte", RMON_T_P1024TO2047 },
+	{ "tx_GTE2048byte", RMON_T_P_GTE2048 },
+	{ "tx_octets", RMON_T_OCTETS },
+
+	/* IEEE TX */
+	{ "IEEE_tx_drop", IEEE_T_DROP },
+	{ "IEEE_tx_frame_ok", IEEE_T_FRAME_OK },
+	{ "IEEE_tx_1col", IEEE_T_1COL },
+	{ "IEEE_tx_mcol", IEEE_T_MCOL },
+	{ "IEEE_tx_def", IEEE_T_DEF },
+	{ "IEEE_tx_lcol", IEEE_T_LCOL },
+	{ "IEEE_tx_excol", IEEE_T_EXCOL },
+	{ "IEEE_tx_macerr", IEEE_T_MACERR },
+	{ "IEEE_tx_cserr", IEEE_T_CSERR },
+	{ "IEEE_tx_sqe", IEEE_T_SQE },
+	{ "IEEE_tx_fdxfc", IEEE_T_FDXFC },
+	{ "IEEE_tx_octets_ok", IEEE_T_OCTETS_OK },
+
+	/* RMON RX */
+	{ "rx_packets", RMON_R_PACKETS },
+	{ "rx_broadcast", RMON_R_BC_PKT },
+	{ "rx_multicast", RMON_R_MC_PKT },
+	{ "rx_crc_errors", RMON_R_CRC_ALIGN },
+	{ "rx_undersize", RMON_R_UNDERSIZE },
+	{ "rx_oversize", RMON_R_OVERSIZE },
+	{ "rx_fragment", RMON_R_FRAG },
+	{ "rx_jabber", RMON_R_JAB },
+	{ "rx_64byte", RMON_R_P64 },
+	{ "rx_65to127byte", RMON_R_P65TO127 },
+	{ "rx_128to255byte", RMON_R_P128TO255 },
+	{ "rx_256to511byte", RMON_R_P256TO511 },
+	{ "rx_512to1023byte", RMON_R_P512TO1023 },
+	{ "rx_1024to2047byte", RMON_R_P1024TO2047 },
+	{ "rx_GTE2048byte", RMON_R_P_GTE2048 },
+	{ "rx_octets", RMON_R_OCTETS },
+
+	/* IEEE RX */
+	{ "IEEE_rx_drop", IEEE_R_DROP },
+	{ "IEEE_rx_frame_ok", IEEE_R_FRAME_OK },
+	{ "IEEE_rx_crc", IEEE_R_CRC },
+	{ "IEEE_rx_align", IEEE_R_ALIGN },
+	{ "IEEE_rx_macerr", IEEE_R_MACERR },
+	{ "IEEE_rx_fdxfc", IEEE_R_FDXFC },
+	{ "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
+};
+
+static void fec_enet_get_ethtool_stats(struct net_device *dev,
+	struct ethtool_stats *stats, u64 *data)
+{
+	struct fec_enet_private *fep = netdev_priv(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
+		data[i] = readl(fep->hwp + fec_stats[i].offset);
+}
+
+static void fec_enet_get_strings(struct net_device *netdev,
+	u32 stringset, u8 *data)
+{
+	int i;
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
+			memcpy(data + i * ETH_GSTRING_LEN,
+				fec_stats[i].name, ETH_GSTRING_LEN);
+		break;
+	}
+}
+
+static int fec_enet_get_sset_count(struct net_device *dev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ARRAY_SIZE(fec_stats);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
 #endif /* !defined(CONFIG_M5272) */
 
+static int fec_enet_nway_reset(struct net_device *dev)
+{
+	struct fec_enet_private *fep = netdev_priv(dev);
+	struct phy_device *phydev = fep->phy_dev;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return genphy_restart_aneg(phydev);
+}
+
 static const struct ethtool_ops fec_enet_ethtool_ops = {
 #if !defined(CONFIG_M5272)
 	.get_pauseparam		= fec_enet_get_pauseparam,
@@ -1456,6 +1630,12 @@ static const struct ethtool_ops fec_enet
 	.get_drvinfo		= fec_enet_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
 	.get_ts_info		= fec_enet_get_ts_info,
+	.nway_reset		= fec_enet_nway_reset,
+#ifndef CONFIG_M5272
+	.get_ethtool_stats	= fec_enet_get_ethtool_stats,
+	.get_strings		= fec_enet_get_strings,
+	.get_sset_count		= fec_enet_get_sset_count,
+#endif
 };
 
 static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
@@ -1803,6 +1983,12 @@ static int fec_enet_init(struct net_devi
 	writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
 	netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT);
 
+	if (id_entry->driver_data & FEC_QUIRK_HAS_VLAN) {
+		/* enable hw VLAN support */
+		ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+		ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
+	}
+
 	if (id_entry->driver_data & FEC_QUIRK_HAS_CSUM) {
 		/* enable hw accelerator */
 		ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
@@ -1865,8 +2051,6 @@ fec_probe(struct platform_device *pdev)
 	struct resource *r;
 	const struct of_device_id *of_id;
 	static int dev_id;
-	struct pinctrl *pinctrl;
-	struct regulator *reg_phy;
 
 	of_id = of_match_device(fec_dt_ids, &pdev->dev);
 	if (of_id)
@@ -1893,17 +2077,17 @@ fec_probe(struct platform_device *pdev)
 		fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG;
 #endif
 
-	fep->hwp = devm_request_and_ioremap(&pdev->dev, r);
+	fep->hwp = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(fep->hwp)) {
+		ret = PTR_ERR(fep->hwp);
+		goto failed_ioremap;
+	}
+
 	fep->pdev = pdev;
 	fep->dev_id = dev_id++;
 
 	fep->bufdesc_ex = 0;
 
-	if (!fep->hwp) {
-		ret = -ENOMEM;
-		goto failed_ioremap;
-	}
-
 	platform_set_drvdata(pdev, ndev);
 
 	ret = of_get_phy_mode(pdev->dev.of_node);
@@ -1917,12 +2101,6 @@ fec_probe(struct platform_device *pdev)
 		fep->phy_interface = ret;
 	}
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl)) {
-		ret = PTR_ERR(pinctrl);
-		goto failed_pin;
-	}
-
 	fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
 	if (IS_ERR(fep->clk_ipg)) {
 		ret = PTR_ERR(fep->clk_ipg);
@@ -1953,20 +2131,22 @@ fec_probe(struct platform_device *pdev)
 	clk_prepare_enable(fep->clk_enet_out);
 	clk_prepare_enable(fep->clk_ptp);
 
-	reg_phy = devm_regulator_get(&pdev->dev, "phy");
-	if (!IS_ERR(reg_phy)) {
-		ret = regulator_enable(reg_phy);
+	fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
+	if (!IS_ERR(fep->reg_phy)) {
+		ret = regulator_enable(fep->reg_phy);
 		if (ret) {
 			dev_err(&pdev->dev,
 				"Failed to enable phy regulator: %d\n", ret);
 			goto failed_regulator;
 		}
+	} else {
+		fep->reg_phy = NULL;
 	}
 
 	fec_reset_phy(pdev);
 
 	if (fep->bufdesc_ex)
-		fec_ptp_init(ndev, pdev);
+		fec_ptp_init(pdev);
 
 	ret = fec_enet_init(ndev);
 	if (ret)
@@ -2010,19 +2190,20 @@ fec_probe(struct platform_device *pdev)
 failed_register:
 	fec_enet_mii_remove(fep);
 failed_mii_init:
-failed_init:
+failed_irq:
 	for (i = 0; i < FEC_IRQ_NUM; i++) {
 		irq = platform_get_irq(pdev, i);
 		if (irq > 0)
 			free_irq(irq, ndev);
 	}
-failed_irq:
+failed_init:
+	if (fep->reg_phy)
+		regulator_disable(fep->reg_phy);
 failed_regulator:
 	clk_disable_unprepare(fep->clk_ahb);
 	clk_disable_unprepare(fep->clk_ipg);
 	clk_disable_unprepare(fep->clk_enet_out);
 	clk_disable_unprepare(fep->clk_ptp);
-failed_pin:
 failed_clk:
 failed_ioremap:
 	free_netdev(ndev);
@@ -2041,21 +2222,21 @@ fec_drv_remove(struct platform_device *p
 	unregister_netdev(ndev);
 	fec_enet_mii_remove(fep);
 	del_timer_sync(&fep->time_keep);
+	for (i = 0; i < FEC_IRQ_NUM; i++) {
+		int irq = platform_get_irq(pdev, i);
+		if (irq > 0)
+			free_irq(irq, ndev);
+	}
+	if (fep->reg_phy)
+		regulator_disable(fep->reg_phy);
 	clk_disable_unprepare(fep->clk_ptp);
 	if (fep->ptp_clock)
 		ptp_clock_unregister(fep->ptp_clock);
 	clk_disable_unprepare(fep->clk_enet_out);
 	clk_disable_unprepare(fep->clk_ahb);
 	clk_disable_unprepare(fep->clk_ipg);
-	for (i = 0; i < FEC_IRQ_NUM; i++) {
-		int irq = platform_get_irq(pdev, i);
-		if (irq > 0)
-			free_irq(irq, ndev);
-	}
 	free_netdev(ndev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
@@ -2074,6 +2255,9 @@ fec_suspend(struct device *dev)
 	clk_disable_unprepare(fep->clk_ahb);
 	clk_disable_unprepare(fep->clk_ipg);
 
+	if (fep->reg_phy)
+		regulator_disable(fep->reg_phy);
+
 	return 0;
 }
 
@@ -2082,6 +2266,13 @@ fec_resume(struct device *dev)
 {
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	int ret;
+
+	if (fep->reg_phy) {
+		ret = regulator_enable(fep->reg_phy);
+		if (ret)
+			return ret;
+	}
 
 	clk_prepare_enable(fep->clk_enet_out);
 	clk_prepare_enable(fep->clk_ahb);
@@ -2111,4 +2302,5 @@ static struct platform_driver fec_driver
 
 module_platform_driver(fec_driver);
 
+MODULE_ALIAS("platform:"DRIVER_NAME);
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fec_mpc52xx.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fec_mpc52xx.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fec_mpc52xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fec_mpc52xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -981,7 +981,7 @@ static int mpc52xx_fec_probe(struct plat
 		goto err_node;
 
 	/* We're done ! */
-	dev_set_drvdata(&op->dev, ndev);
+	platform_set_drvdata(op, ndev);
 	netdev_info(ndev, "%s MAC %pM\n",
 		    op->dev.of_node->full_name, ndev->dev_addr);
 
@@ -1010,7 +1010,7 @@ mpc52xx_fec_remove(struct platform_devic
 	struct net_device *ndev;
 	struct mpc52xx_fec_priv *priv;
 
-	ndev = dev_get_drvdata(&op->dev);
+	ndev = platform_get_drvdata(op);
 	priv = netdev_priv(ndev);
 
 	unregister_netdev(ndev);
@@ -1030,14 +1030,13 @@ mpc52xx_fec_remove(struct platform_devic
 
 	free_netdev(ndev);
 
-	dev_set_drvdata(&op->dev, NULL);
 	return 0;
 }
 
 #ifdef CONFIG_PM
 static int mpc52xx_fec_of_suspend(struct platform_device *op, pm_message_t state)
 {
-	struct net_device *dev = dev_get_drvdata(&op->dev);
+	struct net_device *dev = platform_get_drvdata(op);
 
 	if (netif_running(dev))
 		mpc52xx_fec_close(dev);
@@ -1047,7 +1046,7 @@ static int mpc52xx_fec_of_suspend(struct
 
 static int mpc52xx_fec_of_resume(struct platform_device *op)
 {
-	struct net_device *dev = dev_get_drvdata(&op->dev);
+	struct net_device *dev = platform_get_drvdata(op);
 
 	mpc52xx_fec_hw_init(dev);
 	mpc52xx_fec_reset_stats(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fec_ptp.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fec_ptp.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fec_ptp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fec_ptp.c	2013-08-25 20:43:22.000000000 -0400
@@ -347,8 +347,9 @@ static void fec_time_keep(unsigned long
  * cyclecounter init routine and exits.
  */
 
-void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev)
+void fec_ptp_init(struct platform_device *pdev)
 {
+	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
 
 	fep->ptp_caps.owner = THIS_MODULE;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1048,7 +1048,7 @@ static int fs_enet_probe(struct platform
 	}
 
 	SET_NETDEV_DEV(ndev, &ofdev->dev);
-	dev_set_drvdata(&ofdev->dev, ndev);
+	platform_set_drvdata(ofdev, ndev);
 
 	fep = netdev_priv(ndev);
 	fep->dev = &ofdev->dev;
@@ -1106,7 +1106,6 @@ out_cleanup_data:
 	fep->ops->cleanup_data(ndev);
 out_free_dev:
 	free_netdev(ndev);
-	dev_set_drvdata(&ofdev->dev, NULL);
 out_put:
 	of_node_put(fpi->phy_node);
 out_free_fpi:
@@ -1116,7 +1115,7 @@ out_free_fpi:
 
 static int fs_enet_remove(struct platform_device *ofdev)
 {
-	struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+	struct net_device *ndev = platform_get_drvdata(ofdev);
 	struct fs_enet_private *fep = netdev_priv(ndev);
 
 	unregister_netdev(ndev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fs_enet/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fs_enet/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,6 @@
 config FS_ENET
        tristate "Freescale Ethernet Driver"
        depends on NET_VENDOR_FREESCALE && (CPM1 || CPM2 || PPC_MPC512x)
-       select NET_CORE
        select MII
        select PHYLIB
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c	2013-08-25 20:43:22.000000000 -0400
@@ -179,7 +179,7 @@ static int fs_enet_mdio_probe(struct pla
 	}
 
 	new_bus->parent = &ofdev->dev;
-	dev_set_drvdata(&ofdev->dev, new_bus);
+	platform_set_drvdata(ofdev, new_bus);
 
 	ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);
 	if (ret)
@@ -188,7 +188,6 @@ static int fs_enet_mdio_probe(struct pla
 	return 0;
 
 out_free_irqs:
-	dev_set_drvdata(&ofdev->dev, NULL);
 	kfree(new_bus->irq);
 out_unmap_regs:
 	iounmap(bitbang->dir);
@@ -202,11 +201,10 @@ out:
 
 static int fs_enet_mdio_remove(struct platform_device *ofdev)
 {
-	struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
+	struct mii_bus *bus = platform_get_drvdata(ofdev);
 	struct bb_info *bitbang = bus->priv;
 
 	mdiobus_unregister(bus);
-	dev_set_drvdata(&ofdev->dev, NULL);
 	kfree(bus->irq);
 	free_mdio_bitbang(bus);
 	iounmap(bitbang->dir);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fs_enet/mii-fec.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/fs_enet/mii-fec.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/fs_enet/mii-fec.c	2013-08-25 20:43:22.000000000 -0400
@@ -180,7 +180,7 @@ static int fs_enet_mdio_probe(struct pla
 	}
 
 	new_bus->parent = &ofdev->dev;
-	dev_set_drvdata(&ofdev->dev, new_bus);
+	platform_set_drvdata(ofdev, new_bus);
 
 	ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);
 	if (ret)
@@ -189,7 +189,6 @@ static int fs_enet_mdio_probe(struct pla
 	return 0;
 
 out_free_irqs:
-	dev_set_drvdata(&ofdev->dev, NULL);
 	kfree(new_bus->irq);
 out_unmap_regs:
 	iounmap(fec->fecp);
@@ -204,11 +203,10 @@ out:
 
 static int fs_enet_mdio_remove(struct platform_device *ofdev)
 {
-	struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
+	struct mii_bus *bus = platform_get_drvdata(ofdev);
 	struct fec_info *fec = bus->priv;
 
 	mdiobus_unregister(bus);
-	dev_set_drvdata(&ofdev->dev, NULL);
 	kfree(bus->irq);
 	iounmap(fec->fecp);
 	kfree(fec);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/gianfar.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/gianfar.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/gianfar.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/gianfar.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,6 +128,7 @@ static void gfar_set_multi(struct net_de
 static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
 static void gfar_configure_serdes(struct net_device *dev);
 static int gfar_poll(struct napi_struct *napi, int budget);
+static int gfar_poll_sq(struct napi_struct *napi, int budget);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void gfar_netpoll(struct net_device *dev);
 #endif
@@ -1000,7 +1001,7 @@ static int gfar_probe(struct platform_de
 	spin_lock_init(&priv->bflock);
 	INIT_WORK(&priv->reset_task, gfar_reset_task);
 
-	dev_set_drvdata(&ofdev->dev, priv);
+	platform_set_drvdata(ofdev, priv);
 	regs = priv->gfargrp[0].regs;
 
 	gfar_detect_errata(priv);
@@ -1038,9 +1039,13 @@ static int gfar_probe(struct platform_de
 	dev->ethtool_ops = &gfar_ethtool_ops;
 
 	/* Register for napi ...We are registering NAPI for each grp */
-	for (i = 0; i < priv->num_grps; i++)
-		netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll,
+	if (priv->mode == SQ_SG_MODE)
+		netif_napi_add(dev, &priv->gfargrp[0].napi, gfar_poll_sq,
 			       GFAR_DEV_WEIGHT);
+	else
+		for (i = 0; i < priv->num_grps; i++)
+			netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll,
+				       GFAR_DEV_WEIGHT);
 
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
 		dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
@@ -1240,15 +1245,13 @@ register_fail:
 
 static int gfar_remove(struct platform_device *ofdev)
 {
-	struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
+	struct gfar_private *priv = platform_get_drvdata(ofdev);
 
 	if (priv->phy_node)
 		of_node_put(priv->phy_node);
 	if (priv->tbi_node)
 		of_node_put(priv->tbi_node);
 
-	dev_set_drvdata(&ofdev->dev, NULL);
-
 	unregister_netdev(priv->ndev);
 	unmap_group_regs(priv);
 	free_gfar_dev(priv);
@@ -2825,6 +2828,48 @@ int gfar_clean_rx_ring(struct gfar_priv_
 	return howmany;
 }
 
+static int gfar_poll_sq(struct napi_struct *napi, int budget)
+{
+	struct gfar_priv_grp *gfargrp =
+		container_of(napi, struct gfar_priv_grp, napi);
+	struct gfar __iomem *regs = gfargrp->regs;
+	struct gfar_priv_tx_q *tx_queue = gfargrp->priv->tx_queue[0];
+	struct gfar_priv_rx_q *rx_queue = gfargrp->priv->rx_queue[0];
+	int work_done = 0;
+
+	/* Clear IEVENT, so interrupts aren't called again
+	 * because of the packets that have already arrived
+	 */
+	gfar_write(&regs->ievent, IEVENT_RTX_MASK);
+
+	/* run Tx cleanup to completion */
+	if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx])
+		gfar_clean_tx_ring(tx_queue);
+
+	work_done = gfar_clean_rx_ring(rx_queue, budget);
+
+	if (work_done < budget) {
+		napi_complete(napi);
+		/* Clear the halt bit in RSTAT */
+		gfar_write(&regs->rstat, gfargrp->rstat);
+
+		gfar_write(&regs->imask, IMASK_DEFAULT);
+
+		/* If we are coalescing interrupts, update the timer
+		 * Otherwise, clear it
+		 */
+		gfar_write(&regs->txic, 0);
+		if (likely(tx_queue->txcoalescing))
+			gfar_write(&regs->txic, tx_queue->txic);
+
+		gfar_write(&regs->rxic, 0);
+		if (unlikely(rx_queue->rxcoalescing))
+			gfar_write(&regs->rxic, rx_queue->rxic);
+	}
+
+	return work_done;
+}
+
 static int gfar_poll(struct napi_struct *napi, int budget)
 {
 	struct gfar_priv_grp *gfargrp =
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/gianfar_ptp.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/gianfar_ptp.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/gianfar_ptp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/gianfar_ptp.c	2013-08-25 20:43:22.000000000 -0400
@@ -519,7 +519,7 @@ static int gianfar_ptp_probe(struct plat
 	}
 	gfar_phc_index = ptp_clock_index(etsects->clock);
 
-	dev_set_drvdata(&dev->dev, etsects);
+	platform_set_drvdata(dev, etsects);
 
 	return 0;
 
@@ -537,7 +537,7 @@ no_memory:
 
 static int gianfar_ptp_remove(struct platform_device *dev)
 {
-	struct etsects *etsects = dev_get_drvdata(&dev->dev);
+	struct etsects *etsects = platform_get_drvdata(dev);
 
 	gfar_write(&etsects->regs->tmr_temask, 0);
 	gfar_write(&etsects->regs->tmr_ctrl,   0);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/ucc_geth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/ucc_geth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/ucc_geth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/ucc_geth.c	2013-08-25 20:43:22.000000000 -0400
@@ -3564,7 +3564,7 @@ static void ucc_geth_timeout(struct net_
 
 static int ucc_geth_suspend(struct platform_device *ofdev, pm_message_t state)
 {
-	struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+	struct net_device *ndev = platform_get_drvdata(ofdev);
 	struct ucc_geth_private *ugeth = netdev_priv(ndev);
 
 	if (!netif_running(ndev))
@@ -3592,7 +3592,7 @@ static int ucc_geth_suspend(struct platf
 
 static int ucc_geth_resume(struct platform_device *ofdev)
 {
-	struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+	struct net_device *ndev = platform_get_drvdata(ofdev);
 	struct ucc_geth_private *ugeth = netdev_priv(ndev);
 	int err;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/freescale/xgmac_mdio.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/xgmac_mdio.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/freescale/xgmac_mdio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/freescale/xgmac_mdio.c	2013-08-25 20:43:22.000000000 -0400
@@ -227,7 +227,7 @@ static int xgmac_mdio_probe(struct platf
 		goto err_registration;
 	}
 
-	dev_set_drvdata(&pdev->dev, bus);
+	platform_set_drvdata(pdev, bus);
 
 	return 0;
 
@@ -242,7 +242,7 @@ err_ioremap:
 
 static int xgmac_mdio_remove(struct platform_device *pdev)
 {
-	struct mii_bus *bus = dev_get_drvdata(&pdev->dev);
+	struct mii_bus *bus = platform_get_drvdata(pdev);
 
 	mdiobus_unregister(bus);
 	iounmap(bus->priv);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ibm/ehea/ehea_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/ehea/ehea_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ibm/ehea/ehea_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/ehea/ehea_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -98,8 +98,7 @@ static struct ehea_fw_handle_array ehea_
 static struct ehea_bcmc_reg_array ehea_bcmc_regs;
 
 
-static int ehea_probe_adapter(struct platform_device *dev,
-			      const struct of_device_id *id);
+static int ehea_probe_adapter(struct platform_device *dev);
 
 static int ehea_remove(struct platform_device *dev);
 
@@ -112,7 +111,7 @@ static struct of_device_id ehea_device_t
 };
 MODULE_DEVICE_TABLE(of, ehea_device_table);
 
-static struct of_platform_driver ehea_driver = {
+static struct platform_driver ehea_driver = {
 	.driver = {
 		.name = "ehea",
 		.owner = THIS_MODULE,
@@ -3251,8 +3250,7 @@ static void ehea_remove_device_sysfs(str
 	device_remove_file(&dev->dev, &dev_attr_remove_port);
 }
 
-static int ehea_probe_adapter(struct platform_device *dev,
-			      const struct of_device_id *id)
+static int ehea_probe_adapter(struct platform_device *dev)
 {
 	struct ehea_adapter *adapter;
 	const u64 *adapter_handle;
@@ -3289,7 +3287,7 @@ static int ehea_probe_adapter(struct pla
 
 	adapter->pd = EHEA_PD_ID;
 
-	dev_set_drvdata(&dev->dev, adapter);
+	platform_set_drvdata(dev, adapter);
 
 
 	/* initialize adapter and ports */
@@ -3360,7 +3358,7 @@ out:
 
 static int ehea_remove(struct platform_device *dev)
 {
-	struct ehea_adapter *adapter = dev_get_drvdata(&dev->dev);
+	struct ehea_adapter *adapter = platform_get_drvdata(dev);
 	int i;
 
 	for (i = 0; i < EHEA_MAX_PORTS; i++)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ibm/emac/mal.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/emac/mal.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ibm/emac/mal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/emac/mal.c	2013-08-25 20:43:22.000000000 -0400
@@ -696,7 +696,7 @@ static int mal_probe(struct platform_dev
 
 	/* Advertise this instance to the rest of the world */
 	wmb();
-	dev_set_drvdata(&ofdev->dev, mal);
+	platform_set_drvdata(ofdev, mal);
 
 	mal_dbg_register(mal);
 
@@ -722,7 +722,7 @@ static int mal_probe(struct platform_dev
 
 static int mal_remove(struct platform_device *ofdev)
 {
-	struct mal_instance *mal = dev_get_drvdata(&ofdev->dev);
+	struct mal_instance *mal = platform_get_drvdata(ofdev);
 
 	MAL_DBG(mal, "remove" NL);
 
@@ -735,8 +735,6 @@ static int mal_remove(struct platform_de
 		       "mal%d: commac list is not empty on remove!\n",
 		       mal->index);
 
-	dev_set_drvdata(&ofdev->dev, NULL);
-
 	free_irq(mal->serr_irq, mal);
 	free_irq(mal->txde_irq, mal);
 	free_irq(mal->txeob_irq, mal);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ibm/emac/rgmii.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/emac/rgmii.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ibm/emac/rgmii.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/emac/rgmii.c	2013-08-25 20:43:22.000000000 -0400
@@ -95,7 +95,7 @@ static inline u32 rgmii_mode_mask(int mo
 
 int rgmii_attach(struct platform_device *ofdev, int input, int mode)
 {
-	struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
 	struct rgmii_regs __iomem *p = dev->base;
 
 	RGMII_DBG(dev, "attach(%d)" NL, input);
@@ -124,7 +124,7 @@ int rgmii_attach(struct platform_device
 
 void rgmii_set_speed(struct platform_device *ofdev, int input, int speed)
 {
-	struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
 	struct rgmii_regs __iomem *p = dev->base;
 	u32 ssr;
 
@@ -146,7 +146,7 @@ void rgmii_set_speed(struct platform_dev
 
 void rgmii_get_mdio(struct platform_device *ofdev, int input)
 {
-	struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
 	struct rgmii_regs __iomem *p = dev->base;
 	u32 fer;
 
@@ -167,7 +167,7 @@ void rgmii_get_mdio(struct platform_devi
 
 void rgmii_put_mdio(struct platform_device *ofdev, int input)
 {
-	struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
 	struct rgmii_regs __iomem *p = dev->base;
 	u32 fer;
 
@@ -188,7 +188,7 @@ void rgmii_put_mdio(struct platform_devi
 
 void rgmii_detach(struct platform_device *ofdev, int input)
 {
-	struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
 	struct rgmii_regs __iomem *p;
 
 	BUG_ON(!dev || dev->users == 0);
@@ -214,7 +214,7 @@ int rgmii_get_regs_len(struct platform_d
 
 void *rgmii_dump_regs(struct platform_device *ofdev, void *buf)
 {
-	struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
 	struct emac_ethtool_regs_subhdr *hdr = buf;
 	struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1);
 
@@ -279,7 +279,7 @@ static int rgmii_probe(struct platform_d
 	       (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out");
 
 	wmb();
-	dev_set_drvdata(&ofdev->dev, dev);
+	platform_set_drvdata(ofdev, dev);
 
 	return 0;
 
@@ -291,9 +291,7 @@ static int rgmii_probe(struct platform_d
 
 static int rgmii_remove(struct platform_device *ofdev)
 {
-	struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev);
-
-	dev_set_drvdata(&ofdev->dev, NULL);
+	struct rgmii_instance *dev = platform_get_drvdata(ofdev);
 
 	WARN_ON(dev->users != 0);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ibm/emac/tah.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/emac/tah.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ibm/emac/tah.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/emac/tah.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@
 
 int tah_attach(struct platform_device *ofdev, int channel)
 {
-	struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct tah_instance *dev = platform_get_drvdata(ofdev);
 
 	mutex_lock(&dev->lock);
 	/* Reset has been done at probe() time... nothing else to do for now */
@@ -37,7 +37,7 @@ int tah_attach(struct platform_device *o
 
 void tah_detach(struct platform_device *ofdev, int channel)
 {
-	struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct tah_instance *dev = platform_get_drvdata(ofdev);
 
 	mutex_lock(&dev->lock);
 	--dev->users;
@@ -46,7 +46,7 @@ void tah_detach(struct platform_device *
 
 void tah_reset(struct platform_device *ofdev)
 {
-	struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct tah_instance *dev = platform_get_drvdata(ofdev);
 	struct tah_regs __iomem *p = dev->base;
 	int n;
 
@@ -74,7 +74,7 @@ int tah_get_regs_len(struct platform_dev
 
 void *tah_dump_regs(struct platform_device *ofdev, void *buf)
 {
-	struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct tah_instance *dev = platform_get_drvdata(ofdev);
 	struct emac_ethtool_regs_subhdr *hdr = buf;
 	struct tah_regs *regs = (struct tah_regs *)(hdr + 1);
 
@@ -118,7 +118,7 @@ static int tah_probe(struct platform_dev
 		goto err_free;
 	}
 
-	dev_set_drvdata(&ofdev->dev, dev);
+	platform_set_drvdata(ofdev, dev);
 
 	/* Initialize TAH and enable IPv4 checksum verification, no TSO yet */
 	tah_reset(ofdev);
@@ -137,9 +137,7 @@ static int tah_probe(struct platform_dev
 
 static int tah_remove(struct platform_device *ofdev)
 {
-	struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
-
-	dev_set_drvdata(&ofdev->dev, NULL);
+	struct tah_instance *dev = platform_get_drvdata(ofdev);
 
 	WARN_ON(dev->users != 0);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ibm/emac/zmii.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/emac/zmii.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ibm/emac/zmii.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/emac/zmii.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,7 +84,7 @@ static inline u32 zmii_mode_mask(int mod
 
 int zmii_attach(struct platform_device *ofdev, int input, int *mode)
 {
-	struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct zmii_instance *dev = platform_get_drvdata(ofdev);
 	struct zmii_regs __iomem *p = dev->base;
 
 	ZMII_DBG(dev, "init(%d, %d)" NL, input, *mode);
@@ -150,7 +150,7 @@ int zmii_attach(struct platform_device *
 
 void zmii_get_mdio(struct platform_device *ofdev, int input)
 {
-	struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct zmii_instance *dev = platform_get_drvdata(ofdev);
 	u32 fer;
 
 	ZMII_DBG2(dev, "get_mdio(%d)" NL, input);
@@ -163,7 +163,7 @@ void zmii_get_mdio(struct platform_devic
 
 void zmii_put_mdio(struct platform_device *ofdev, int input)
 {
-	struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct zmii_instance *dev = platform_get_drvdata(ofdev);
 
 	ZMII_DBG2(dev, "put_mdio(%d)" NL, input);
 	mutex_unlock(&dev->lock);
@@ -172,7 +172,7 @@ void zmii_put_mdio(struct platform_devic
 
 void zmii_set_speed(struct platform_device *ofdev, int input, int speed)
 {
-	struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct zmii_instance *dev = platform_get_drvdata(ofdev);
 	u32 ssr;
 
 	mutex_lock(&dev->lock);
@@ -193,7 +193,7 @@ void zmii_set_speed(struct platform_devi
 
 void zmii_detach(struct platform_device *ofdev, int input)
 {
-	struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct zmii_instance *dev = platform_get_drvdata(ofdev);
 
 	BUG_ON(!dev || dev->users == 0);
 
@@ -218,7 +218,7 @@ int zmii_get_regs_len(struct platform_de
 
 void *zmii_dump_regs(struct platform_device *ofdev, void *buf)
 {
-	struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
+	struct zmii_instance *dev = platform_get_drvdata(ofdev);
 	struct emac_ethtool_regs_subhdr *hdr = buf;
 	struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1);
 
@@ -272,7 +272,7 @@ static int zmii_probe(struct platform_de
 	printk(KERN_INFO
 	       "ZMII %s initialized\n", ofdev->dev.of_node->full_name);
 	wmb();
-	dev_set_drvdata(&ofdev->dev, dev);
+	platform_set_drvdata(ofdev, dev);
 
 	return 0;
 
@@ -284,9 +284,7 @@ static int zmii_probe(struct platform_de
 
 static int zmii_remove(struct platform_device *ofdev)
 {
-	struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
-
-	dev_set_drvdata(&ofdev->dev, NULL);
+	struct zmii_instance *dev = platform_get_drvdata(ofdev);
 
 	WARN_ON(dev->users != 0);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ibm/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/ibm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ibm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -5,8 +5,7 @@
 config NET_VENDOR_IBM
 	bool "IBM devices"
 	default y
-	depends on MCA || PPC_PSERIES || PPC_PSERIES || PPC_DCR || \
-		   (IBMEBUS && SPARSEMEM)
+	depends on PPC_PSERIES || PPC_DCR || (IBMEBUS && SPARSEMEM)
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y
 	  and read the Ethernet-HOWTO, available from
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/icplus/ipg.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/icplus/ipg.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/icplus/ipg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/icplus/ipg.c	2013-08-25 20:43:22.000000000 -0400
@@ -2298,15 +2298,4 @@ static struct pci_driver ipg_pci_driver
 	.remove		= ipg_remove,
 };
 
-static int __init ipg_init_module(void)
-{
-	return pci_register_driver(&ipg_pci_driver);
-}
-
-static void __exit ipg_exit_module(void)
-{
-	pci_unregister_driver(&ipg_pci_driver);
-}
-
-module_init(ipg_init_module);
-module_exit(ipg_exit_module);
+module_pci_driver(ipg_pci_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/icplus/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/icplus/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/icplus/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/icplus/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,6 @@
 config IP1000
 	tristate "IP1000 Gigabit Ethernet support"
 	depends on PCI
-	select NET_CORE
 	select MII
 	---help---
 	  This driver supports IP1000 gigabit Ethernet cards.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/80003es2lan.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/80003es2lan.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/80003es2lan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/80003es2lan.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,17 +66,17 @@ static s32 e1000_init_phy_params_80003es
 	s32 ret_val;
 
 	if (hw->phy.media_type != e1000_media_type_copper) {
-		phy->type	= e1000_phy_none;
+		phy->type = e1000_phy_none;
 		return 0;
 	} else {
 		phy->ops.power_up = e1000_power_up_phy_copper;
 		phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan;
 	}
 
-	phy->addr		= 1;
-	phy->autoneg_mask	= AUTONEG_ADVERTISE_SPEED_DEFAULT;
-	phy->reset_delay_us      = 100;
-	phy->type		= e1000_phy_gg82563;
+	phy->addr = 1;
+	phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+	phy->reset_delay_us = 100;
+	phy->type = e1000_phy_gg82563;
 
 	/* This can only be done after all function pointers are setup. */
 	ret_val = e1000e_get_phy_id(hw);
@@ -98,19 +98,19 @@ static s32 e1000_init_nvm_params_80003es
 	u32 eecd = er32(EECD);
 	u16 size;
 
-	nvm->opcode_bits	= 8;
-	nvm->delay_usec	 = 1;
+	nvm->opcode_bits = 8;
+	nvm->delay_usec = 1;
 	switch (nvm->override) {
 	case e1000_nvm_override_spi_large:
-		nvm->page_size    = 32;
+		nvm->page_size = 32;
 		nvm->address_bits = 16;
 		break;
 	case e1000_nvm_override_spi_small:
-		nvm->page_size    = 8;
+		nvm->page_size = 8;
 		nvm->address_bits = 8;
 		break;
 	default:
-		nvm->page_size    = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
+		nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
 		nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8;
 		break;
 	}
@@ -128,7 +128,7 @@ static s32 e1000_init_nvm_params_80003es
 	/* EEPROM access above 16k is unsupported */
 	if (size > 14)
 		size = 14;
-	nvm->word_size	= 1 << size;
+	nvm->word_size = 1 << size;
 
 	return 0;
 }
@@ -859,7 +859,7 @@ static void e1000_initialize_hw_bits_800
 
 	/* Transmit Arbitration Control 0 */
 	reg = er32(TARC(0));
-	reg &= ~(0xF << 27); /* 30:27 */
+	reg &= ~(0xF << 27);	/* 30:27 */
 	if (hw->phy.media_type != e1000_media_type_copper)
 		reg &= ~(1 << 20);
 	ew32(TARC(0), reg);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/82571.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/82571.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/82571.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/82571.c	2013-08-25 20:43:22.000000000 -0400
@@ -77,24 +77,24 @@ static s32 e1000_init_phy_params_82571(s
 		return 0;
 	}
 
-	phy->addr			 = 1;
-	phy->autoneg_mask		 = AUTONEG_ADVERTISE_SPEED_DEFAULT;
-	phy->reset_delay_us		 = 100;
+	phy->addr = 1;
+	phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+	phy->reset_delay_us = 100;
 
-	phy->ops.power_up		 = e1000_power_up_phy_copper;
-	phy->ops.power_down		 = e1000_power_down_phy_copper_82571;
+	phy->ops.power_up = e1000_power_up_phy_copper;
+	phy->ops.power_down = e1000_power_down_phy_copper_82571;
 
 	switch (hw->mac.type) {
 	case e1000_82571:
 	case e1000_82572:
-		phy->type		 = e1000_phy_igp_2;
+		phy->type = e1000_phy_igp_2;
 		break;
 	case e1000_82573:
-		phy->type		 = e1000_phy_m88;
+		phy->type = e1000_phy_m88;
 		break;
 	case e1000_82574:
 	case e1000_82583:
-		phy->type		 = e1000_phy_bm;
+		phy->type = e1000_phy_bm;
 		phy->ops.acquire = e1000_get_hw_semaphore_82574;
 		phy->ops.release = e1000_put_hw_semaphore_82574;
 		phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82574;
@@ -193,7 +193,7 @@ static s32 e1000_init_nvm_params_82571(s
 		/* EEPROM access above 16k is unsupported */
 		if (size > 14)
 			size = 14;
-		nvm->word_size	= 1 << size;
+		nvm->word_size = 1 << size;
 		break;
 	}
 
@@ -339,7 +339,7 @@ static s32 e1000_init_mac_params_82571(s
 static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	static int global_quad_port_a; /* global port a indication */
+	static int global_quad_port_a;	/* global port a indication */
 	struct pci_dev *pdev = adapter->pdev;
 	int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1;
 	s32 rc;
@@ -1003,8 +1003,6 @@ static s32 e1000_reset_hw_82571(struct e
 	default:
 		break;
 	}
-	if (ret_val)
-		e_dbg("Cannot acquire MDIO ownership\n");
 
 	ctrl = er32(CTRL);
 
@@ -1015,7 +1013,9 @@ static s32 e1000_reset_hw_82571(struct e
 	switch (hw->mac.type) {
 	case e1000_82574:
 	case e1000_82583:
-		e1000_put_hw_semaphore_82574(hw);
+		/* Release mutex only if the hw semaphore is acquired */
+		if (!ret_val)
+			e1000_put_hw_semaphore_82574(hw);
 		break;
 	default:
 		break;
@@ -1178,7 +1178,7 @@ static void e1000_initialize_hw_bits_825
 
 	/* Transmit Arbitration Control 0 */
 	reg = er32(TARC(0));
-	reg &= ~(0xF << 27); /* 30:27 */
+	reg &= ~(0xF << 27);	/* 30:27 */
 	switch (hw->mac.type) {
 	case e1000_82571:
 	case e1000_82572:
@@ -1390,7 +1390,7 @@ bool e1000_check_phy_82574(struct e1000_
 	ret_val = e1e_rphy(hw, E1000_RECEIVE_ERROR_COUNTER, &receive_errors);
 	if (ret_val)
 		return false;
-	if (receive_errors == E1000_RECEIVE_ERROR_MAX)  {
+	if (receive_errors == E1000_RECEIVE_ERROR_MAX) {
 		ret_val = e1e_rphy(hw, E1000_BASE1000T_STATUS, &status_1kbt);
 		if (ret_val)
 			return false;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -244,7 +244,7 @@ static int e1000_set_spd_dplx(struct e10
 		mac->autoneg = 1;
 		adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL;
 		break;
-	case SPEED_1000 + DUPLEX_HALF: /* not supported */
+	case SPEED_1000 + DUPLEX_HALF:	/* not supported */
 	default:
 		goto err_inval;
 	}
@@ -416,7 +416,7 @@ static void e1000_set_msglevel(struct ne
 
 static int e1000_get_regs_len(struct net_device __always_unused *netdev)
 {
-#define E1000_REGS_LEN 32 /* overestimate */
+#define E1000_REGS_LEN 32	/* overestimate */
 	return E1000_REGS_LEN * sizeof(u32);
 }
 
@@ -433,22 +433,22 @@ static void e1000_get_regs(struct net_de
 	regs->version = (1 << 24) | (adapter->pdev->revision << 16) |
 	    adapter->pdev->device;
 
-	regs_buff[0]  = er32(CTRL);
-	regs_buff[1]  = er32(STATUS);
+	regs_buff[0] = er32(CTRL);
+	regs_buff[1] = er32(STATUS);
 
-	regs_buff[2]  = er32(RCTL);
-	regs_buff[3]  = er32(RDLEN(0));
-	regs_buff[4]  = er32(RDH(0));
-	regs_buff[5]  = er32(RDT(0));
-	regs_buff[6]  = er32(RDTR);
+	regs_buff[2] = er32(RCTL);
+	regs_buff[3] = er32(RDLEN(0));
+	regs_buff[4] = er32(RDH(0));
+	regs_buff[5] = er32(RDT(0));
+	regs_buff[6] = er32(RDTR);
 
-	regs_buff[7]  = er32(TCTL);
-	regs_buff[8]  = er32(TDLEN(0));
-	regs_buff[9]  = er32(TDH(0));
+	regs_buff[7] = er32(TCTL);
+	regs_buff[8] = er32(TDLEN(0));
+	regs_buff[9] = er32(TDH(0));
 	regs_buff[10] = er32(TDT(0));
 	regs_buff[11] = er32(TIDV);
 
-	regs_buff[12] = adapter->hw.phy.type;  /* PHY type (IGP=1, M88=0) */
+	regs_buff[12] = adapter->hw.phy.type;	/* PHY type (IGP=1, M88=0) */
 
 	/* ethtool doesn't use anything past this point, so all this
 	 * code is likely legacy junk for apps that may or may not exist
@@ -1379,7 +1379,7 @@ static int e1000_integrated_phy_loopback
 
 	if (hw->phy.media_type == e1000_media_type_copper &&
 	    hw->phy.type == e1000_phy_m88) {
-		ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
+		ctrl_reg |= E1000_CTRL_ILOS;	/* Invert Loss of Signal */
 	} else {
 		/* Set the ILOS bit on the fiber Nic if half duplex link is
 		 * detected.
@@ -1613,7 +1613,7 @@ static int e1000_run_loopback_test(struc
 		ew32(TDT(0), k);
 		e1e_flush();
 		msleep(200);
-		time = jiffies; /* set the start time for the receive */
+		time = jiffies;	/* set the start time for the receive */
 		good_cnt = 0;
 		/* receive the sent packets */
 		do {
@@ -1636,11 +1636,11 @@ static int e1000_run_loopback_test(struc
 			 */
 		} while ((good_cnt < 64) && !time_after(jiffies, time + 20));
 		if (good_cnt != 64) {
-			ret_val = 13; /* ret_val is the same as mis-compare */
+			ret_val = 13;	/* ret_val is the same as mis-compare */
 			break;
 		}
 		if (jiffies >= (time + 20)) {
-			ret_val = 14; /* error code for time out error */
+			ret_val = 14;	/* error code for time out error */
 			break;
 		}
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/hw.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/hw.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -402,13 +402,13 @@ struct e1000_phy_stats {
 
 struct e1000_host_mng_dhcp_cookie {
 	u32 signature;
-	u8  status;
-	u8  reserved0;
+	u8 status;
+	u8 reserved0;
 	u16 vlan_id;
 	u32 reserved1;
 	u16 reserved2;
-	u8  reserved3;
-	u8  checksum;
+	u8 reserved3;
+	u8 checksum;
 };
 
 /* Host Interface "Rev 1" */
@@ -427,8 +427,8 @@ struct e1000_host_command_info {
 
 /* Host Interface "Rev 2" */
 struct e1000_host_mng_command_header {
-	u8  command_id;
-	u8  checksum;
+	u8 command_id;
+	u8 checksum;
 	u16 reserved1;
 	u16 reserved2;
 	u16 command_length;
@@ -549,7 +549,7 @@ struct e1000_mac_info {
 	u32 mta_shadow[MAX_MTA_REG];
 	u16 rar_entry_count;
 
-	u8  forced_speed_duplex;
+	u8 forced_speed_duplex;
 
 	bool adaptive_ifs;
 	bool has_fwsm;
@@ -577,7 +577,7 @@ struct e1000_phy_info {
 
 	u32 addr;
 	u32 id;
-	u32 reset_delay_us; /* in usec */
+	u32 reset_delay_us;	/* in usec */
 	u32 revision;
 
 	enum e1000_media_type media_type;
@@ -636,11 +636,11 @@ struct e1000_dev_spec_82571 {
 };
 
 struct e1000_dev_spec_80003es2lan {
-	bool  mdic_wa_enable;
+	bool mdic_wa_enable;
 };
 
 struct e1000_shadow_ram {
-	u16  value;
+	u16 value;
 	bool modified;
 };
 
@@ -660,17 +660,17 @@ struct e1000_hw {
 	void __iomem *hw_addr;
 	void __iomem *flash_address;
 
-	struct e1000_mac_info  mac;
-	struct e1000_fc_info   fc;
-	struct e1000_phy_info  phy;
-	struct e1000_nvm_info  nvm;
-	struct e1000_bus_info  bus;
+	struct e1000_mac_info mac;
+	struct e1000_fc_info fc;
+	struct e1000_phy_info phy;
+	struct e1000_nvm_info nvm;
+	struct e1000_bus_info bus;
 	struct e1000_host_mng_dhcp_cookie mng_cookie;
 
 	union {
-		struct e1000_dev_spec_82571	e82571;
+		struct e1000_dev_spec_82571 e82571;
 		struct e1000_dev_spec_80003es2lan e80003es2lan;
-		struct e1000_dev_spec_ich8lan	ich8lan;
+		struct e1000_dev_spec_ich8lan ich8lan;
 	} dev_spec;
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/ich8lan.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/ich8lan.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/ich8lan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/ich8lan.c	2013-08-25 20:43:22.000000000 -0400
@@ -101,12 +101,12 @@ union ich8_hws_flash_regacc {
 /* ICH Flash Protected Region */
 union ich8_flash_protected_range {
 	struct ich8_pr {
-		u32 base:13;     /* 0:12 Protected Range Base */
-		u32 reserved1:2; /* 13:14 Reserved */
-		u32 rpe:1;       /* 15 Read Protection Enable */
-		u32 limit:13;    /* 16:28 Protected Range Limit */
-		u32 reserved2:2; /* 29:30 Reserved */
-		u32 wpe:1;       /* 31 Write Protection Enable */
+		u32 base:13;	/* 0:12 Protected Range Base */
+		u32 reserved1:2;	/* 13:14 Reserved */
+		u32 rpe:1;	/* 15 Read Protection Enable */
+		u32 limit:13;	/* 16:28 Protected Range Limit */
+		u32 reserved2:2;	/* 29:30 Reserved */
+		u32 wpe:1;	/* 31 Write Protection Enable */
 	} range;
 	u32 regval;
 };
@@ -362,21 +362,21 @@ static s32 e1000_init_phy_params_pchlan(
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
 
-	phy->addr                     = 1;
-	phy->reset_delay_us           = 100;
+	phy->addr = 1;
+	phy->reset_delay_us = 100;
 
-	phy->ops.set_page             = e1000_set_page_igp;
-	phy->ops.read_reg             = e1000_read_phy_reg_hv;
-	phy->ops.read_reg_locked      = e1000_read_phy_reg_hv_locked;
-	phy->ops.read_reg_page        = e1000_read_phy_reg_page_hv;
-	phy->ops.set_d0_lplu_state    = e1000_set_lplu_state_pchlan;
-	phy->ops.set_d3_lplu_state    = e1000_set_lplu_state_pchlan;
-	phy->ops.write_reg            = e1000_write_phy_reg_hv;
-	phy->ops.write_reg_locked     = e1000_write_phy_reg_hv_locked;
-	phy->ops.write_reg_page       = e1000_write_phy_reg_page_hv;
-	phy->ops.power_up             = e1000_power_up_phy_copper;
-	phy->ops.power_down           = e1000_power_down_phy_copper_ich8lan;
-	phy->autoneg_mask             = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+	phy->ops.set_page = e1000_set_page_igp;
+	phy->ops.read_reg = e1000_read_phy_reg_hv;
+	phy->ops.read_reg_locked = e1000_read_phy_reg_hv_locked;
+	phy->ops.read_reg_page = e1000_read_phy_reg_page_hv;
+	phy->ops.set_d0_lplu_state = e1000_set_lplu_state_pchlan;
+	phy->ops.set_d3_lplu_state = e1000_set_lplu_state_pchlan;
+	phy->ops.write_reg = e1000_write_phy_reg_hv;
+	phy->ops.write_reg_locked = e1000_write_phy_reg_hv_locked;
+	phy->ops.write_reg_page = e1000_write_phy_reg_page_hv;
+	phy->ops.power_up = e1000_power_up_phy_copper;
+	phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
+	phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
 
 	phy->id = e1000_phy_unknown;
 
@@ -445,11 +445,11 @@ static s32 e1000_init_phy_params_ich8lan
 	s32 ret_val;
 	u16 i = 0;
 
-	phy->addr			= 1;
-	phy->reset_delay_us		= 100;
+	phy->addr = 1;
+	phy->reset_delay_us = 100;
 
-	phy->ops.power_up               = e1000_power_up_phy_copper;
-	phy->ops.power_down             = e1000_power_down_phy_copper_ich8lan;
+	phy->ops.power_up = e1000_power_up_phy_copper;
+	phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
 
 	/* We may need to do this twice - once for IGP and if that fails,
 	 * we'll set BM func pointers and try again
@@ -457,7 +457,7 @@ static s32 e1000_init_phy_params_ich8lan
 	ret_val = e1000e_determine_phy_address(hw);
 	if (ret_val) {
 		phy->ops.write_reg = e1000e_write_phy_reg_bm;
-		phy->ops.read_reg  = e1000e_read_phy_reg_bm;
+		phy->ops.read_reg = e1000e_read_phy_reg_bm;
 		ret_val = e1000e_determine_phy_address(hw);
 		if (ret_val) {
 			e_dbg("Cannot determine PHY addr. Erroring out\n");
@@ -560,7 +560,7 @@ static s32 e1000_init_nvm_params_ich8lan
 	/* Clear shadow ram */
 	for (i = 0; i < nvm->word_size; i++) {
 		dev_spec->shadow_ram[i].modified = false;
-		dev_spec->shadow_ram[i].value    = 0xFFFF;
+		dev_spec->shadow_ram[i].value = 0xFFFF;
 	}
 
 	return 0;
@@ -1012,7 +1012,7 @@ static s32 e1000_check_for_copper_link_i
 	hw->dev_spec.ich8lan.eee_lp_ability = 0;
 
 	if (!link)
-		return 0; /* No link detected */
+		return 0;	/* No link detected */
 
 	mac->get_link_status = false;
 
@@ -2816,7 +2816,7 @@ static s32 e1000_read_flash_data_ich8lan
 	s32 ret_val = -E1000_ERR_NVM;
 	u8 count = 0;
 
-	if (size < 1  || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
+	if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
 		return -E1000_ERR_NVM;
 
 	flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
@@ -2939,7 +2939,7 @@ static s32 e1000_update_nvm_checksum_ich
 	 * write to bank 0 etc.  We also need to erase the segment that
 	 * is going to be written
 	 */
-	ret_val =  e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
+	ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
 	if (ret_val) {
 		e_dbg("Could not detect valid bank, assuming bank 0\n");
 		bank = 0;
@@ -4073,7 +4073,7 @@ void e1000e_igp3_phy_powerdown_workaroun
 {
 	u32 reg;
 	u16 data;
-	u8  retry = 0;
+	u8 retry = 0;
 
 	if (hw->phy.type != e1000_phy_igp_3)
 		return;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/netdev.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/netdev.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/netdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/netdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -1196,7 +1196,7 @@ static bool e1000_clean_tx_irq(struct e1
 	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
 		bool cleaned = false;
-		rmb(); /* read buffer_info after eop_desc */
+		rmb();		/* read buffer_info after eop_desc */
 		for (; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -1385,7 +1385,7 @@ static bool e1000_clean_rx_irq_ps(struct
 
 				skb_put(skb, l1);
 				goto copydone;
-			} /* if */
+			}	/* if */
 		}
 
 		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
@@ -1800,7 +1800,7 @@ static irqreturn_t e1000_intr(int __alwa
 	u32 rctl, icr = er32(ICR);
 
 	if (!icr || test_bit(__E1000_DOWN, &adapter->state))
-		return IRQ_NONE;  /* Not our interrupt */
+		return IRQ_NONE;	/* Not our interrupt */
 
 	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
 	 * not set, then the adapter didn't send an interrupt
@@ -2487,7 +2487,7 @@ static unsigned int e1000_update_itr(u16
 		else if ((packets < 5) && (bytes > 512))
 			retval = low_latency;
 		break;
-	case low_latency:  /* 50 usec aka 20000 ints/s */
+	case low_latency:	/* 50 usec aka 20000 ints/s */
 		if (bytes > 10000) {
 			/* this if handles the TSO accounting */
 			if (bytes / packets > 8000)
@@ -2502,7 +2502,7 @@ static unsigned int e1000_update_itr(u16
 			retval = lowest_latency;
 		}
 		break;
-	case bulk_latency: /* 250 usec aka 4000 ints/s */
+	case bulk_latency:	/* 250 usec aka 4000 ints/s */
 		if (bytes > 25000) {
 			if (packets > 35)
 				retval = low_latency;
@@ -2554,7 +2554,7 @@ static void e1000_set_itr(struct e1000_a
 		new_itr = 70000;
 		break;
 	case low_latency:
-		new_itr = 20000; /* aka hwitr = ~200 */
+		new_itr = 20000;	/* aka hwitr = ~200 */
 		break;
 	case bulk_latency:
 		new_itr = 4000;
@@ -2673,7 +2673,7 @@ static int e1000e_poll(struct napi_struc
 }
 
 static int e1000_vlan_rx_add_vid(struct net_device *netdev,
-				 __be16 proto, u16 vid)
+				 __always_unused __be16 proto, u16 vid)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
@@ -2699,7 +2699,7 @@ static int e1000_vlan_rx_add_vid(struct
 }
 
 static int e1000_vlan_rx_kill_vid(struct net_device *netdev,
-				  __be16 proto, u16 vid)
+				  __always_unused __be16 proto, u16 vid)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
@@ -3104,13 +3104,13 @@ static void e1000_setup_rctl(struct e100
 		/* UPE and MPE will be handled by normal PROMISC logic
 		 * in e1000e_set_rx_mode
 		 */
-		rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
-			 E1000_RCTL_BAM | /* RX All Bcast Pkts */
-			 E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
+		rctl |= (E1000_RCTL_SBP |	/* Receive bad packets */
+			 E1000_RCTL_BAM |	/* RX All Bcast Pkts */
+			 E1000_RCTL_PMCF);	/* RX All MAC Ctrl Pkts */
 
-		rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
-			  E1000_RCTL_DPF | /* Allow filtered pause */
-			  E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
+		rctl &= ~(E1000_RCTL_VFE |	/* Disable VLAN filter */
+			  E1000_RCTL_DPF |	/* Allow filtered pause */
+			  E1000_RCTL_CFIEN);	/* Dis VLAN CFIEN Filter */
 		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
 		 * and that breaks VLANs.
 		 */
@@ -3799,7 +3799,7 @@ void e1000e_reset(struct e1000_adapter *
 		hwm = min(((pba << 10) * 9 / 10),
 			  ((pba << 10) - adapter->max_frame_size));
 
-		fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
+		fc->high_water = hwm & E1000_FCRTH_RTH;	/* 8-byte granularity */
 		fc->low_water = fc->high_water - 8;
 		break;
 	case e1000_pchlan:
@@ -3808,10 +3808,10 @@ void e1000e_reset(struct e1000_adapter *
 		 */
 		if (adapter->netdev->mtu > ETH_DATA_LEN) {
 			fc->high_water = 0x3500;
-			fc->low_water  = 0x1500;
+			fc->low_water = 0x1500;
 		} else {
 			fc->high_water = 0x5000;
-			fc->low_water  = 0x3000;
+			fc->low_water = 0x3000;
 		}
 		fc->refresh_time = 0x1000;
 		break;
@@ -4581,7 +4581,7 @@ static void e1000e_update_stats(struct e
 	adapter->stats.crcerrs += er32(CRCERRS);
 	adapter->stats.gprc += er32(GPRC);
 	adapter->stats.gorc += er32(GORCL);
-	er32(GORCH); /* Clear gorc */
+	er32(GORCH);		/* Clear gorc */
 	adapter->stats.bprc += er32(BPRC);
 	adapter->stats.mprc += er32(MPRC);
 	adapter->stats.roc += er32(ROC);
@@ -4614,7 +4614,7 @@ static void e1000e_update_stats(struct e
 	adapter->stats.xofftxc += er32(XOFFTXC);
 	adapter->stats.gptc += er32(GPTC);
 	adapter->stats.gotc += er32(GOTCL);
-	er32(GOTCH); /* Clear gotc */
+	er32(GOTCH);		/* Clear gotc */
 	adapter->stats.rnbc += er32(RNBC);
 	adapter->stats.ruc += er32(RUC);
 
@@ -5106,13 +5106,13 @@ static int e1000_tso(struct e1000_ring *
 	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
 	buffer_info = &tx_ring->buffer_info[i];
 
-	context_desc->lower_setup.ip_fields.ipcss  = ipcss;
-	context_desc->lower_setup.ip_fields.ipcso  = ipcso;
-	context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
+	context_desc->lower_setup.ip_fields.ipcss = ipcss;
+	context_desc->lower_setup.ip_fields.ipcso = ipcso;
+	context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse);
 	context_desc->upper_setup.tcp_fields.tucss = tucss;
 	context_desc->upper_setup.tcp_fields.tucso = tucso;
 	context_desc->upper_setup.tcp_fields.tucse = 0;
-	context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
+	context_desc->tcp_seg_setup.fields.mss = cpu_to_le16(mss);
 	context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
 	context_desc->cmd_and_length = cpu_to_le32(cmd_length);
 
@@ -5363,7 +5363,7 @@ static void e1000_tx_queue(struct e1000_
 static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
 				    struct sk_buff *skb)
 {
-	struct e1000_hw *hw =  &adapter->hw;
+	struct e1000_hw *hw = &adapter->hw;
 	u16 length, offset;
 
 	if (vlan_tx_tag_present(skb) &&
@@ -6259,7 +6259,7 @@ static void e1000_netpoll(struct net_dev
 		e1000_intr_msi(adapter->pdev->irq, netdev);
 		enable_irq(adapter->pdev->irq);
 		break;
-	default: /* E1000E_INT_MODE_LEGACY */
+	default:		/* E1000E_INT_MODE_LEGACY */
 		disable_irq(adapter->pdev->irq);
 		e1000_intr(adapter->pdev->irq, netdev);
 		enable_irq(adapter->pdev->irq);
@@ -6589,9 +6589,9 @@ static int e1000_probe(struct pci_dev *p
 		adapter->eee_advert = MDIO_EEE_100TX | MDIO_EEE_1000T;
 
 	/* construct the net_device struct */
-	netdev->netdev_ops		= &e1000e_netdev_ops;
+	netdev->netdev_ops = &e1000e_netdev_ops;
 	e1000e_set_ethtool_ops(netdev);
-	netdev->watchdog_timeo		= 5 * HZ;
+	netdev->watchdog_timeo = 5 * HZ;
 	netif_napi_add(netdev, &adapter->napi, e1000e_poll, 64);
 	strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
 
@@ -7034,7 +7034,6 @@ static void __exit e1000_exit_module(voi
 }
 module_exit(e1000_exit_module);
 
-
 MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
 MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/nvm.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/nvm.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/nvm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/nvm.c	2013-08-25 20:43:22.000000000 -0400
@@ -117,7 +117,6 @@ static u16 e1000_shift_in_eec_bits(struc
 	u16 data;
 
 	eecd = er32(EECD);
-
 	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
 	data = 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/phy.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/phy.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/e1000e/phy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e1000e/phy.c	2013-08-25 20:43:22.000000000 -0400
@@ -1583,13 +1583,13 @@ s32 e1000e_check_downshift(struct e1000_
 	case e1000_phy_gg82563:
 	case e1000_phy_bm:
 	case e1000_phy_82578:
-		offset	= M88E1000_PHY_SPEC_STATUS;
-		mask	= M88E1000_PSSR_DOWNSHIFT;
+		offset = M88E1000_PHY_SPEC_STATUS;
+		mask = M88E1000_PSSR_DOWNSHIFT;
 		break;
 	case e1000_phy_igp_2:
 	case e1000_phy_igp_3:
-		offset	= IGP01E1000_PHY_LINK_HEALTH;
-		mask	= IGP01E1000_PLHR_SS_DOWNGRADE;
+		offset = IGP01E1000_PHY_LINK_HEALTH;
+		mask = IGP01E1000_PLHR_SS_DOWNGRADE;
 		break;
 	default:
 		/* speed downshift not supported */
@@ -1653,14 +1653,14 @@ s32 e1000_check_polarity_igp(struct e100
 
 	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
 	    IGP01E1000_PSSR_SPEED_1000MBPS) {
-		offset	= IGP01E1000_PHY_PCS_INIT_REG;
-		mask	= IGP01E1000_PHY_POLARITY_MASK;
+		offset = IGP01E1000_PHY_PCS_INIT_REG;
+		mask = IGP01E1000_PHY_POLARITY_MASK;
 	} else {
 		/* This really only applies to 10Mbps since
 		 * there is no polarity for 100Mbps (always 0).
 		 */
-		offset	= IGP01E1000_PHY_PORT_STATUS;
-		mask	= IGP01E1000_PSSR_POLARITY_REVERSED;
+		offset = IGP01E1000_PHY_PORT_STATUS;
+		mask = IGP01E1000_PSSR_POLARITY_REVERSED;
 	}
 
 	ret_val = e1e_rphy(hw, offset, &data);
@@ -1900,7 +1900,7 @@ s32 e1000e_get_cable_length_igp_2(struct
 s32 e1000e_get_phy_info_m88(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32  ret_val;
+	s32 ret_val;
 	u16 phy_data;
 	bool link;
 
@@ -2253,7 +2253,7 @@ enum e1000_phy_type e1000e_get_phy_type_
 	case M88E1011_I_PHY_ID:
 		phy_type = e1000_phy_m88;
 		break;
-	case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
+	case IGP01E1000_I_PHY_ID:	/* IGP 1 & 2 share this */
 		phy_type = e1000_phy_igp_2;
 		break;
 	case GG82563_E_PHY_ID:
@@ -2317,7 +2317,7 @@ s32 e1000e_determine_phy_address(struct
 			/* If phy_type is valid, break - we found our
 			 * PHY address
 			 */
-			if (phy_type  != e1000_phy_unknown)
+			if (phy_type != e1000_phy_unknown)
 				return 0;
 
 			usleep_range(1000, 2000);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/e100.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e100.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/e100.c	2013-07-01 10:36:43.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/e100.c	2013-08-31 17:56:15.000000000 -0400
@@ -3068,7 +3068,7 @@ static int e100_resume(struct pci_dev *p
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	/* ack any pending wake events, disable PME */
-	pci_enable_wake(pdev, 0, 0);
+	pci_enable_wake(pdev, PCI_D0, 0);
 
 	/* disable reverse auto-negotiation */
 	if (nic->phy == phy_82552_v) {
@@ -3159,7 +3159,7 @@ static void e100_io_resume(struct pci_de
 	struct nic *nic = netdev_priv(netdev);
 
 	/* ack any pending wake events, disable PME */
-	pci_enable_wake(pdev, 0, 0);
+	pci_enable_wake(pdev, PCI_D0, 0);
 
 	netif_device_attach(netdev);
 	if (netif_running(netdev)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_82575.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_82575.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_82575.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_82575.c	2013-08-25 20:43:22.000000000 -0400
@@ -401,12 +401,82 @@ static s32 igb_init_mac_params_82575(str
 	return 0;
 }
 
+/**
+ *  igb_set_sfp_media_type_82575 - derives SFP module media type.
+ *  @hw: pointer to the HW structure
+ *
+ *  The media type is chosen based on SFP module.
+ *  compatibility flags retrieved from SFP ID EEPROM.
+ **/
+static s32 igb_set_sfp_media_type_82575(struct e1000_hw *hw)
+{
+	s32 ret_val = E1000_ERR_CONFIG;
+	u32 ctrl_ext = 0;
+	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
+	struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags;
+	u8 tranceiver_type = 0;
+	s32 timeout = 3;
+
+	/* Turn I2C interface ON and power on sfp cage */
+	ctrl_ext = rd32(E1000_CTRL_EXT);
+	ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
+	wr32(E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA);
+
+	wrfl();
+
+	/* Read SFP module data */
+	while (timeout) {
+		ret_val = igb_read_sfp_data_byte(hw,
+			E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET),
+			&tranceiver_type);
+		if (ret_val == 0)
+			break;
+		msleep(100);
+		timeout--;
+	}
+	if (ret_val != 0)
+		goto out;
+
+	ret_val = igb_read_sfp_data_byte(hw,
+			E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET),
+			(u8 *)eth_flags);
+	if (ret_val != 0)
+		goto out;
+
+	/* Check if there is some SFP module plugged and powered */
+	if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) ||
+	    (tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) {
+		dev_spec->module_plugged = true;
+		if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) {
+			hw->phy.media_type = e1000_media_type_internal_serdes;
+		} else if (eth_flags->e100_base_fx) {
+			dev_spec->sgmii_active = true;
+			hw->phy.media_type = e1000_media_type_internal_serdes;
+		} else if (eth_flags->e1000_base_t) {
+			dev_spec->sgmii_active = true;
+			hw->phy.media_type = e1000_media_type_copper;
+		} else {
+			hw->phy.media_type = e1000_media_type_unknown;
+			hw_dbg("PHY module has not been recognized\n");
+			goto out;
+		}
+	} else {
+		hw->phy.media_type = e1000_media_type_unknown;
+	}
+	ret_val = 0;
+out:
+	/* Restore I2C interface setting */
+	wr32(E1000_CTRL_EXT, ctrl_ext);
+	return ret_val;
+}
+
 static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575;
 	s32 ret_val;
 	u32 ctrl_ext = 0;
+	u32 link_mode = 0;
 
 	switch (hw->device_id) {
 	case E1000_DEV_ID_82575EB_COPPER:
@@ -470,16 +540,56 @@ static s32 igb_get_invariants_82575(stru
 	 */
 	hw->phy.media_type = e1000_media_type_copper;
 	dev_spec->sgmii_active = false;
+	dev_spec->module_plugged = false;
 
 	ctrl_ext = rd32(E1000_CTRL_EXT);
-	switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
-	case E1000_CTRL_EXT_LINK_MODE_SGMII:
-		dev_spec->sgmii_active = true;
-		break;
+
+	link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
+	switch (link_mode) {
 	case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
-	case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
 		hw->phy.media_type = e1000_media_type_internal_serdes;
 		break;
+	case E1000_CTRL_EXT_LINK_MODE_SGMII:
+		/* Get phy control interface type set (MDIO vs. I2C)*/
+		if (igb_sgmii_uses_mdio_82575(hw)) {
+			hw->phy.media_type = e1000_media_type_copper;
+			dev_spec->sgmii_active = true;
+			break;
+		}
+		/* fall through for I2C based SGMII */
+	case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
+		/* read media type from SFP EEPROM */
+		ret_val = igb_set_sfp_media_type_82575(hw);
+		if ((ret_val != 0) ||
+		    (hw->phy.media_type == e1000_media_type_unknown)) {
+			/* If media type was not identified then return media
+			 * type defined by the CTRL_EXT settings.
+			 */
+			hw->phy.media_type = e1000_media_type_internal_serdes;
+
+			if (link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII) {
+				hw->phy.media_type = e1000_media_type_copper;
+				dev_spec->sgmii_active = true;
+			}
+
+			break;
+		}
+
+		/* do not change link mode for 100BaseFX */
+		if (dev_spec->eth_flags.e100_base_fx)
+			break;
+
+		/* change current link mode setting */
+		ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
+
+		if (hw->phy.media_type == e1000_media_type_copper)
+			ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII;
+		else
+			ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
+
+		wr32(E1000_CTRL_EXT, ctrl_ext);
+
+		break;
 	default:
 		break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_defines.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_defines.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_defines.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_defines.h	2013-08-25 20:43:22.000000000 -0400
@@ -61,20 +61,22 @@
 /* Clear Interrupt timers after IMS clear */
 /* packet buffer parity error detection enabled */
 /* descriptor FIFO parity error detection enable */
-#define E1000_CTRL_EXT_PBA_CLR        0x80000000 /* PBA Clear */
-#define E1000_I2CCMD_REG_ADDR_SHIFT   16
-#define E1000_I2CCMD_PHY_ADDR_SHIFT   24
-#define E1000_I2CCMD_OPCODE_READ      0x08000000
-#define E1000_I2CCMD_OPCODE_WRITE     0x00000000
-#define E1000_I2CCMD_READY            0x20000000
-#define E1000_I2CCMD_ERROR            0x80000000
-#define E1000_MAX_SGMII_PHY_REG_ADDR  255
-#define E1000_I2CCMD_PHY_TIMEOUT      200
-#define E1000_IVAR_VALID              0x80
-#define E1000_GPIE_NSICR              0x00000001
-#define E1000_GPIE_MSIX_MODE          0x00000010
-#define E1000_GPIE_EIAME              0x40000000
-#define E1000_GPIE_PBA                0x80000000
+#define E1000_CTRL_EXT_PBA_CLR		0x80000000 /* PBA Clear */
+#define E1000_I2CCMD_REG_ADDR_SHIFT	16
+#define E1000_I2CCMD_PHY_ADDR_SHIFT	24
+#define E1000_I2CCMD_OPCODE_READ	0x08000000
+#define E1000_I2CCMD_OPCODE_WRITE	0x00000000
+#define E1000_I2CCMD_READY		0x20000000
+#define E1000_I2CCMD_ERROR		0x80000000
+#define E1000_I2CCMD_SFP_DATA_ADDR(a)	(0x0000 + (a))
+#define E1000_I2CCMD_SFP_DIAG_ADDR(a)	(0x0100 + (a))
+#define E1000_MAX_SGMII_PHY_REG_ADDR	255
+#define E1000_I2CCMD_PHY_TIMEOUT	200
+#define E1000_IVAR_VALID		0x80
+#define E1000_GPIE_NSICR		0x00000001
+#define E1000_GPIE_MSIX_MODE		0x00000010
+#define E1000_GPIE_EIAME		0x40000000
+#define E1000_GPIE_PBA			0x80000000
 
 /* Receive Descriptor bit definitions */
 #define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
@@ -270,8 +272,10 @@
 #define AUTONEG_ADVERTISE_SPEED_DEFAULT   E1000_ALL_SPEED_DUPLEX
 
 /* LED Control */
-#define E1000_LEDCTL_LED0_MODE_SHIFT      0
-#define E1000_LEDCTL_LED0_BLINK           0x00000080
+#define E1000_LEDCTL_LED0_MODE_SHIFT	0
+#define E1000_LEDCTL_LED0_BLINK		0x00000080
+#define E1000_LEDCTL_LED0_MODE_MASK	0x0000000F
+#define E1000_LEDCTL_LED0_IVRT		0x00000040
 
 #define E1000_LEDCTL_MODE_LED_ON        0xE
 #define E1000_LEDCTL_MODE_LED_OFF       0xF
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_hw.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_hw.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -528,6 +528,8 @@ struct e1000_dev_spec_82575 {
 	bool global_device_reset;
 	bool eee_disable;
 	bool clear_semaphore_once;
+	struct e1000_sfp_flags eth_flags;
+	bool module_plugged;
 };
 
 struct e1000_hw {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_i210.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_i210.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_i210.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_i210.h	2013-08-25 20:43:22.000000000 -0400
@@ -82,11 +82,11 @@ enum E1000_INVM_STRUCTURE_TYPE {
 #define E1000_INVM_MAJOR_SHIFT		4
 
 #define ID_LED_DEFAULT_I210		((ID_LED_OFF1_ON2  << 8) | \
-					 (ID_LED_OFF1_OFF2 <<  4) | \
-					 (ID_LED_DEF1_DEF2))
+					 (ID_LED_DEF1_DEF2 <<  4) | \
+					 (ID_LED_OFF1_OFF2))
 #define ID_LED_DEFAULT_I210_SERDES	((ID_LED_DEF1_DEF2 << 8) | \
 					 (ID_LED_DEF1_DEF2 <<  4) | \
-					 (ID_LED_DEF1_DEF2))
+					 (ID_LED_OFF1_ON2))
 
 /* NVM offset defaults for i211 device */
 #define NVM_INIT_CTRL_2_DEFAULT_I211	0X7243
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_mac.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_mac.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_mac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_mac.c	2013-08-25 20:43:22.000000000 -0400
@@ -1332,7 +1332,13 @@ s32 igb_id_led_init(struct e1000_hw *hw)
 	u16 data, i, temp;
 	const u16 led_mask = 0x0F;
 
-	ret_val = igb_valid_led_default(hw, &data);
+	/* i210 and i211 devices have different LED mechanism */
+	if ((hw->mac.type == e1000_i210) ||
+	    (hw->mac.type == e1000_i211))
+		ret_val = igb_valid_led_default_i210(hw, &data);
+	else
+		ret_val = igb_valid_led_default(hw, &data);
+
 	if (ret_val)
 		goto out;
 
@@ -1406,15 +1412,34 @@ s32 igb_blink_led(struct e1000_hw *hw)
 	u32 ledctl_blink = 0;
 	u32 i;
 
-	/* set the blink bit for each LED that's "on" (0x0E)
-	 * in ledctl_mode2
-	 */
-	ledctl_blink = hw->mac.ledctl_mode2;
-	for (i = 0; i < 4; i++)
-		if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
-		    E1000_LEDCTL_MODE_LED_ON)
-			ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
-					 (i * 8));
+	if (hw->phy.media_type == e1000_media_type_fiber) {
+		/* always blink LED0 for PCI-E fiber */
+		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
+		     (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
+	} else {
+		/* Set the blink bit for each LED that's "on" (0x0E)
+		 * (or "off" if inverted) in ledctl_mode2.  The blink
+		 * logic in hardware only works when mode is set to "on"
+		 * so it must be changed accordingly when the mode is
+		 * "off" and inverted.
+		 */
+		ledctl_blink = hw->mac.ledctl_mode2;
+		for (i = 0; i < 32; i += 8) {
+			u32 mode = (hw->mac.ledctl_mode2 >> i) &
+			    E1000_LEDCTL_LED0_MODE_MASK;
+			u32 led_default = hw->mac.ledctl_default >> i;
+
+			if ((!(led_default & E1000_LEDCTL_LED0_IVRT) &&
+			     (mode == E1000_LEDCTL_MODE_LED_ON)) ||
+			    ((led_default & E1000_LEDCTL_LED0_IVRT) &&
+			     (mode == E1000_LEDCTL_MODE_LED_OFF))) {
+				ledctl_blink &=
+				    ~(E1000_LEDCTL_LED0_MODE_MASK << i);
+				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK |
+						 E1000_LEDCTL_MODE_LED_ON) << i;
+			}
+		}
+	}
 
 	wr32(E1000_LEDCTL, ledctl_blink);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_phy.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_phy.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_phy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_phy.c	2013-08-25 20:43:22.000000000 -0400
@@ -341,6 +341,130 @@ s32 igb_write_phy_reg_i2c(struct e1000_h
 }
 
 /**
+ *  igb_read_sfp_data_byte - Reads SFP module data.
+ *  @hw: pointer to the HW structure
+ *  @offset: byte location offset to be read
+ *  @data: read data buffer pointer
+ *
+ *  Reads one byte from SFP module data stored
+ *  in SFP resided EEPROM memory or SFP diagnostic area.
+ *  Function should be called with
+ *  E1000_I2CCMD_SFP_DATA_ADDR(<byte offset>) for SFP module database access
+ *  E1000_I2CCMD_SFP_DIAG_ADDR(<byte offset>) for SFP diagnostics parameters
+ *  access
+ **/
+s32 igb_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data)
+{
+	u32 i = 0;
+	u32 i2ccmd = 0;
+	u32 data_local = 0;
+
+	if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) {
+		hw_dbg("I2CCMD command address exceeds upper limit\n");
+		return -E1000_ERR_PHY;
+	}
+
+	/* Set up Op-code, EEPROM Address,in the I2CCMD
+	 * register. The MAC will take care of interfacing with the
+	 * EEPROM to retrieve the desired data.
+	 */
+	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
+		  E1000_I2CCMD_OPCODE_READ);
+
+	wr32(E1000_I2CCMD, i2ccmd);
+
+	/* Poll the ready bit to see if the I2C read completed */
+	for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
+		udelay(50);
+		data_local = rd32(E1000_I2CCMD);
+		if (data_local & E1000_I2CCMD_READY)
+			break;
+	}
+	if (!(data_local & E1000_I2CCMD_READY)) {
+		hw_dbg("I2CCMD Read did not complete\n");
+		return -E1000_ERR_PHY;
+	}
+	if (data_local & E1000_I2CCMD_ERROR) {
+		hw_dbg("I2CCMD Error bit set\n");
+		return -E1000_ERR_PHY;
+	}
+	*data = (u8) data_local & 0xFF;
+
+	return 0;
+}
+
+/**
+ *  e1000_write_sfp_data_byte - Writes SFP module data.
+ *  @hw: pointer to the HW structure
+ *  @offset: byte location offset to write to
+ *  @data: data to write
+ *
+ *  Writes one byte to SFP module data stored
+ *  in SFP resided EEPROM memory or SFP diagnostic area.
+ *  Function should be called with
+ *  E1000_I2CCMD_SFP_DATA_ADDR(<byte offset>) for SFP module database access
+ *  E1000_I2CCMD_SFP_DIAG_ADDR(<byte offset>) for SFP diagnostics parameters
+ *  access
+ **/
+s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data)
+{
+	u32 i = 0;
+	u32 i2ccmd = 0;
+	u32 data_local = 0;
+
+	if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) {
+		hw_dbg("I2CCMD command address exceeds upper limit\n");
+		return -E1000_ERR_PHY;
+	}
+	/* The programming interface is 16 bits wide
+	 * so we need to read the whole word first
+	 * then update appropriate byte lane and write
+	 * the updated word back.
+	 */
+	/* Set up Op-code, EEPROM Address,in the I2CCMD
+	 * register. The MAC will take care of interfacing
+	 * with an EEPROM to write the data given.
+	 */
+	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
+		  E1000_I2CCMD_OPCODE_READ);
+	/* Set a command to read single word */
+	wr32(E1000_I2CCMD, i2ccmd);
+	for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
+		udelay(50);
+		/* Poll the ready bit to see if lastly
+		 * launched I2C operation completed
+		 */
+		i2ccmd = rd32(E1000_I2CCMD);
+		if (i2ccmd & E1000_I2CCMD_READY) {
+			/* Check if this is READ or WRITE phase */
+			if ((i2ccmd & E1000_I2CCMD_OPCODE_READ) ==
+			    E1000_I2CCMD_OPCODE_READ) {
+				/* Write the selected byte
+				 * lane and update whole word
+				 */
+				data_local = i2ccmd & 0xFF00;
+				data_local |= data;
+				i2ccmd = ((offset <<
+					E1000_I2CCMD_REG_ADDR_SHIFT) |
+					E1000_I2CCMD_OPCODE_WRITE | data_local);
+				wr32(E1000_I2CCMD, i2ccmd);
+			} else {
+				break;
+			}
+		}
+	}
+	if (!(i2ccmd & E1000_I2CCMD_READY)) {
+		hw_dbg("I2CCMD Write did not complete\n");
+		return -E1000_ERR_PHY;
+	}
+	if (i2ccmd & E1000_I2CCMD_ERROR) {
+		hw_dbg("I2CCMD Error bit set\n");
+		return -E1000_ERR_PHY;
+	}
+	return 0;
+}
+
+/**
  *  igb_read_phy_reg_igp - Read igp PHY register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to be read
@@ -2014,7 +2138,7 @@ out:
  *  Verify the reset block is not blocking us from resetting.  Acquire
  *  semaphore (if necessary) and read/set/write the device control reset
  *  bit in the PHY.  Wait the appropriate delay time for the device to
- *  reset and relase the semaphore (if necessary).
+ *  reset and release the semaphore (if necessary).
  **/
 s32 igb_phy_hw_reset(struct e1000_hw *hw)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_phy.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_phy.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/e1000_phy.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/e1000_phy.h	2013-08-25 20:43:22.000000000 -0400
@@ -69,6 +69,8 @@ s32  igb_read_phy_reg_mdic(struct e1000_
 s32  igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
 s32  igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
 s32  igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
+s32  igb_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data);
+s32  e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data);
 s32  igb_copper_link_setup_82580(struct e1000_hw *hw);
 s32  igb_get_phy_info_82580(struct e1000_hw *hw);
 s32  igb_phy_force_speed_duplex_82580(struct e1000_hw *hw);
@@ -157,4 +159,22 @@ s32  igb_check_polarity_m88(struct e1000
 #define GS40G_CS_POWER_DOWN		0x0002
 #define GS40G_LINE_LB			0x4000
 
+/* SFP modules ID memory locations */
+#define E1000_SFF_IDENTIFIER_OFFSET	0x00
+#define E1000_SFF_IDENTIFIER_SFF	0x02
+#define E1000_SFF_IDENTIFIER_SFP	0x03
+
+#define E1000_SFF_ETH_FLAGS_OFFSET	0x06
+/* Flags for SFP modules compatible with ETH up to 1Gb */
+struct e1000_sfp_flags {
+	u8 e1000_base_sx:1;
+	u8 e1000_base_lx:1;
+	u8 e1000_base_cx:1;
+	u8 e1000_base_t:1;
+	u8 e100_base_lx:1;
+	u8 e100_base_fx:1;
+	u8 e10_base_bx10:1;
+	u8 e10_base_px:1;
+};
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/igb_ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/igb_ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/igb_ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/igb_ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -142,6 +142,8 @@ static int igb_get_settings(struct net_d
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
+	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
+	struct e1000_sfp_flags *eth_flags = &dev_spec->eth_flags;
 	u32 status;
 
 	if (hw->phy.media_type == e1000_media_type_copper) {
@@ -162,49 +164,26 @@ static int igb_get_settings(struct net_d
 			ecmd->advertising |= hw->phy.autoneg_advertised;
 		}
 
-		if (hw->mac.autoneg != 1)
-			ecmd->advertising &= ~(ADVERTISED_Pause |
-					       ADVERTISED_Asym_Pause);
-
-		if (hw->fc.requested_mode == e1000_fc_full)
-			ecmd->advertising |= ADVERTISED_Pause;
-		else if (hw->fc.requested_mode == e1000_fc_rx_pause)
-			ecmd->advertising |= (ADVERTISED_Pause |
-					      ADVERTISED_Asym_Pause);
-		else if (hw->fc.requested_mode == e1000_fc_tx_pause)
-			ecmd->advertising |=  ADVERTISED_Asym_Pause;
-		else
-			ecmd->advertising &= ~(ADVERTISED_Pause |
-					       ADVERTISED_Asym_Pause);
-
 		ecmd->port = PORT_TP;
 		ecmd->phy_address = hw->phy.addr;
 		ecmd->transceiver = XCVR_INTERNAL;
 	} else {
-		ecmd->supported = (SUPPORTED_1000baseT_Full |
-				   SUPPORTED_100baseT_Full |
-				   SUPPORTED_FIBRE |
+		ecmd->supported = (SUPPORTED_FIBRE |
 				   SUPPORTED_Autoneg |
 				   SUPPORTED_Pause);
-		if (hw->mac.type == e1000_i354)
-				ecmd->supported |= SUPPORTED_2500baseX_Full;
-
 		ecmd->advertising = ADVERTISED_FIBRE;
-
-		switch (adapter->link_speed) {
-		case SPEED_2500:
-			ecmd->advertising = ADVERTISED_2500baseX_Full;
-			break;
-		case SPEED_1000:
-			ecmd->advertising = ADVERTISED_1000baseT_Full;
-			break;
-		case SPEED_100:
-			ecmd->advertising = ADVERTISED_100baseT_Full;
-			break;
-		default:
-			break;
+		if (hw->mac.type == e1000_i354) {
+			ecmd->supported |= SUPPORTED_2500baseX_Full;
+			ecmd->advertising |= ADVERTISED_2500baseX_Full;
+		}
+		if ((eth_flags->e1000_base_lx) || (eth_flags->e1000_base_sx)) {
+			ecmd->supported |= SUPPORTED_1000baseT_Full;
+			ecmd->advertising |= ADVERTISED_1000baseT_Full;
+		}
+		if (eth_flags->e100_base_fx) {
+			ecmd->supported |= SUPPORTED_100baseT_Full;
+			ecmd->advertising |= ADVERTISED_100baseT_Full;
 		}
-
 		if (hw->mac.autoneg == 1)
 			ecmd->advertising |= ADVERTISED_Autoneg;
 
@@ -212,6 +191,21 @@ static int igb_get_settings(struct net_d
 		ecmd->transceiver = XCVR_EXTERNAL;
 	}
 
+	if (hw->mac.autoneg != 1)
+		ecmd->advertising &= ~(ADVERTISED_Pause |
+				       ADVERTISED_Asym_Pause);
+
+	if (hw->fc.requested_mode == e1000_fc_full)
+		ecmd->advertising |= ADVERTISED_Pause;
+	else if (hw->fc.requested_mode == e1000_fc_rx_pause)
+		ecmd->advertising |= (ADVERTISED_Pause |
+				      ADVERTISED_Asym_Pause);
+	else if (hw->fc.requested_mode == e1000_fc_tx_pause)
+		ecmd->advertising |=  ADVERTISED_Asym_Pause;
+	else
+		ecmd->advertising &= ~(ADVERTISED_Pause |
+				       ADVERTISED_Asym_Pause);
+
 	status = rd32(E1000_STATUS);
 
 	if (status & E1000_STATUS_LU) {
@@ -392,6 +386,10 @@ static int igb_set_pauseparam(struct net
 	struct e1000_hw *hw = &adapter->hw;
 	int retval = 0;
 
+	/* 100basefx does not support setting link flow control */
+	if (hw->dev_spec._82575.eth_flags.e100_base_fx)
+		return -EINVAL;
+
 	adapter->fc_autoneg = pause->autoneg;
 
 	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
@@ -813,10 +811,8 @@ static int igb_set_eeprom(struct net_dev
 	ret_val = hw->nvm.ops.write(hw, first_word,
 				    last_word - first_word + 1, eeprom_buff);
 
-	/* Update the checksum over the first part of the EEPROM if needed
-	 * and flush shadow RAM for 82573 controllers
-	 */
-	if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG)))
+	/* Update the checksum if nvm write succeeded */
+	if (ret_val == 0)
 		hw->nvm.ops.update(hw);
 
 	igb_set_fw_version(adapter);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/igb.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/igb.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/igb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/igb.h	2013-08-25 20:43:22.000000000 -0400
@@ -322,11 +322,6 @@ static inline int igb_desc_unused(struct
 	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
 }
 
-struct igb_i2c_client_list {
-	struct i2c_client *client;
-	struct igb_i2c_client_list *next;
-};
-
 #ifdef CONFIG_IGB_HWMON
 
 #define IGB_HWMON_TYPE_LOC	0
@@ -514,13 +509,18 @@ extern void igb_ptp_rx_rgtstamp(struct i
 extern void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector,
 				unsigned char *va,
 				struct sk_buff *skb);
-static inline void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector,
+static inline void igb_ptp_rx_hwtstamp(struct igb_ring *rx_ring,
 				       union e1000_adv_rx_desc *rx_desc,
 				       struct sk_buff *skb)
 {
 	if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TS) &&
 	    !igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP))
-		igb_ptp_rx_rgtstamp(q_vector, skb);
+		igb_ptp_rx_rgtstamp(rx_ring->q_vector, skb);
+
+	/* Update the last_rx_timestamp timer in order to enable watchdog check
+	 * for error case of latched timestamp on a dropped packet.
+	 */
+	rx_ring->last_rx_timestamp = jiffies;
 }
 
 extern int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/igb_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/igb_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/igb/igb_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/igb/igb_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1667,10 +1667,13 @@ void igb_down(struct igb_adapter *adapte
 	wrfl();
 	msleep(10);
 
-	for (i = 0; i < adapter->num_q_vectors; i++)
+	igb_irq_disable(adapter);
+
+	for (i = 0; i < adapter->num_q_vectors; i++) {
+		napi_synchronize(&(adapter->q_vector[i]->napi));
 		napi_disable(&(adapter->q_vector[i]->napi));
+	}
 
-	igb_irq_disable(adapter);
 
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
@@ -3736,9 +3739,8 @@ static void igb_set_rx_mode(struct net_d
 	rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_VFE);
 
 	if (netdev->flags & IFF_PROMISC) {
-		u32 mrqc = rd32(E1000_MRQC);
 		/* retain VLAN HW filtering if in VT mode */
-		if (mrqc & E1000_MRQC_ENABLE_VMDQ)
+		if (adapter->vfs_allocated_count)
 			rctl |= E1000_RCTL_VFE;
 		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
 		vmolr |= (E1000_VMOLR_ROPE | E1000_VMOLR_MPME);
@@ -6622,7 +6624,7 @@ static void igb_process_skb_fields(struc
 
 	igb_rx_checksum(rx_ring, rx_desc, skb);
 
-	igb_ptp_rx_hwtstamp(rx_ring->q_vector, rx_desc, skb);
+	igb_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
 
 	if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
 	    igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c	2013-08-25 20:43:22.000000000 -0400
@@ -108,9 +108,8 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_825
 
 	/* Enable arbiter */
 	reg &= ~IXGBE_DPMCS_ARBDIS;
-	/* Enable DFP and Recycle mode */
-	reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM);
 	reg |= IXGBE_DPMCS_TSOEF;
+
 	/* Configure Max TSO packet size 34KB including payload and headers */
 	reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h	2013-08-25 20:43:22.000000000 -0400
@@ -45,6 +45,7 @@
 
 /* Receive UP2TC mapping */
 #define IXGBE_RTRUP2TC_UP_SHIFT 3
+#define IXGBE_RTRUP2TC_UP_MASK	7
 /* Transmit UP2TC mapping */
 #define IXGBE_RTTUP2TC_UP_SHIFT 3
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c	2013-08-25 20:43:22.000000000 -0400
@@ -380,3 +380,26 @@ s32 ixgbe_dcb_hw_ets_config(struct ixgbe
 	}
 	return 0;
 }
+
+static void ixgbe_dcb_read_rtrup2tc_82599(struct ixgbe_hw *hw, u8 *map)
+{
+	u32 reg, i;
+
+	reg = IXGBE_READ_REG(hw, IXGBE_RTRUP2TC);
+	for (i = 0; i < MAX_USER_PRIORITY; i++)
+		map[i] = IXGBE_RTRUP2TC_UP_MASK &
+			(reg >> (i * IXGBE_RTRUP2TC_UP_SHIFT));
+	return;
+}
+
+void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map)
+{
+	switch (hw->mac.type) {
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
+		ixgbe_dcb_read_rtrup2tc_82599(hw, map);
+		break;
+	default:
+		break;
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h	2013-08-25 20:43:22.000000000 -0400
@@ -159,6 +159,8 @@ s32 ixgbe_dcb_hw_ets_config(struct ixgbe
 s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *tc_prio);
 s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *);
 
+void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map);
+
 /* DCB definitions for credit calculation */
 #define DCB_CREDIT_QUANTUM	64   /* DCB Quantum */
 #define MAX_CREDIT_REFILL       511  /* 0x1FF * 64B = 32704B */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c	2013-08-25 20:43:22.000000000 -0400
@@ -554,6 +554,9 @@ static int ixgbe_dcbnl_ieee_setets(struc
 		for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
 			adapter->ixgbe_ieee_ets->prio_tc[i] =
 				IEEE_8021QAZ_MAX_TCS;
+		/* if possible update UP2TC mappings from HW */
+		ixgbe_dcb_read_rtrup2tc(&adapter->hw,
+					adapter->ixgbe_ieee_ets->prio_tc);
 	}
 
 	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -1054,6 +1054,12 @@ static void ixgbe_get_ethtool_stats(stru
 			data[i] = 0;
 			data[i+1] = 0;
 			i += 2;
+#ifdef LL_EXTENDED_STATS
+			data[i] = 0;
+			data[i+1] = 0;
+			data[i+2] = 0;
+			i += 3;
+#endif
 			continue;
 		}
 
@@ -1063,6 +1069,12 @@ static void ixgbe_get_ethtool_stats(stru
 			data[i+1] = ring->stats.bytes;
 		} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
 		i += 2;
+#ifdef LL_EXTENDED_STATS
+		data[i] = ring->stats.yields;
+		data[i+1] = ring->stats.misses;
+		data[i+2] = ring->stats.cleaned;
+		i += 3;
+#endif
 	}
 	for (j = 0; j < IXGBE_NUM_RX_QUEUES; j++) {
 		ring = adapter->rx_ring[j];
@@ -1070,6 +1082,12 @@ static void ixgbe_get_ethtool_stats(stru
 			data[i] = 0;
 			data[i+1] = 0;
 			i += 2;
+#ifdef LL_EXTENDED_STATS
+			data[i] = 0;
+			data[i+1] = 0;
+			data[i+2] = 0;
+			i += 3;
+#endif
 			continue;
 		}
 
@@ -1079,6 +1097,12 @@ static void ixgbe_get_ethtool_stats(stru
 			data[i+1] = ring->stats.bytes;
 		} while (u64_stats_fetch_retry_bh(&ring->syncp, start));
 		i += 2;
+#ifdef LL_EXTENDED_STATS
+		data[i] = ring->stats.yields;
+		data[i+1] = ring->stats.misses;
+		data[i+2] = ring->stats.cleaned;
+		i += 3;
+#endif
 	}
 
 	for (j = 0; j < IXGBE_MAX_PACKET_BUFFERS; j++) {
@@ -1115,12 +1139,28 @@ static void ixgbe_get_strings(struct net
 			p += ETH_GSTRING_LEN;
 			sprintf(p, "tx_queue_%u_bytes", i);
 			p += ETH_GSTRING_LEN;
+#ifdef LL_EXTENDED_STATS
+			sprintf(p, "tx_q_%u_napi_yield", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "tx_q_%u_misses", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "tx_q_%u_cleaned", i);
+			p += ETH_GSTRING_LEN;
+#endif /* LL_EXTENDED_STATS */
 		}
 		for (i = 0; i < IXGBE_NUM_RX_QUEUES; i++) {
 			sprintf(p, "rx_queue_%u_packets", i);
 			p += ETH_GSTRING_LEN;
 			sprintf(p, "rx_queue_%u_bytes", i);
 			p += ETH_GSTRING_LEN;
+#ifdef LL_EXTENDED_STATS
+			sprintf(p, "rx_q_%u_ll_poll_yield", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "rx_q_%u_misses", i);
+			p += ETH_GSTRING_LEN;
+			sprintf(p, "rx_q_%u_cleaned", i);
+			p += ETH_GSTRING_LEN;
+#endif /* LL_EXTENDED_STATS */
 		}
 		for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
 			sprintf(p, "tx_pb_%u_pxon", i);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe.h	2013-08-25 20:43:22.000000000 -0400
@@ -52,6 +52,11 @@
 #include <linux/dca.h>
 #endif
 
+#include <net/busy_poll.h>
+
+#ifdef CONFIG_NET_RX_BUSY_POLL
+#define LL_EXTENDED_STATS
+#endif
 /* common prefix used by pr_<> macros */
 #undef pr_fmt
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -182,6 +187,11 @@ struct ixgbe_rx_buffer {
 struct ixgbe_queue_stats {
 	u64 packets;
 	u64 bytes;
+#ifdef LL_EXTENDED_STATS
+	u64 yields;
+	u64 misses;
+	u64 cleaned;
+#endif  /* LL_EXTENDED_STATS */
 };
 
 struct ixgbe_tx_queue_stats {
@@ -356,9 +366,133 @@ struct ixgbe_q_vector {
 	struct rcu_head rcu;	/* to avoid race with update stats on free */
 	char name[IFNAMSIZ + 9];
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	unsigned int state;
+#define IXGBE_QV_STATE_IDLE        0
+#define IXGBE_QV_STATE_NAPI	   1    /* NAPI owns this QV */
+#define IXGBE_QV_STATE_POLL	   2    /* poll owns this QV */
+#define IXGBE_QV_LOCKED (IXGBE_QV_STATE_NAPI | IXGBE_QV_STATE_POLL)
+#define IXGBE_QV_STATE_NAPI_YIELD  4    /* NAPI yielded this QV */
+#define IXGBE_QV_STATE_POLL_YIELD  8    /* poll yielded this QV */
+#define IXGBE_QV_YIELD (IXGBE_QV_STATE_NAPI_YIELD | IXGBE_QV_STATE_POLL_YIELD)
+#define IXGBE_QV_USER_PEND (IXGBE_QV_STATE_POLL | IXGBE_QV_STATE_POLL_YIELD)
+	spinlock_t lock;
+#endif  /* CONFIG_NET_RX_BUSY_POLL */
+
 	/* for dynamic allocation of rings associated with this q_vector */
 	struct ixgbe_ring ring[0] ____cacheline_internodealigned_in_smp;
 };
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static inline void ixgbe_qv_init_lock(struct ixgbe_q_vector *q_vector)
+{
+
+	spin_lock_init(&q_vector->lock);
+	q_vector->state = IXGBE_QV_STATE_IDLE;
+}
+
+/* called from the device poll routine to get ownership of a q_vector */
+static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector)
+{
+	int rc = true;
+	spin_lock(&q_vector->lock);
+	if (q_vector->state & IXGBE_QV_LOCKED) {
+		WARN_ON(q_vector->state & IXGBE_QV_STATE_NAPI);
+		q_vector->state |= IXGBE_QV_STATE_NAPI_YIELD;
+		rc = false;
+#ifdef LL_EXTENDED_STATS
+		q_vector->tx.ring->stats.yields++;
+#endif
+	} else
+		/* we don't care if someone yielded */
+		q_vector->state = IXGBE_QV_STATE_NAPI;
+	spin_unlock(&q_vector->lock);
+	return rc;
+}
+
+/* returns true is someone tried to get the qv while napi had it */
+static inline bool ixgbe_qv_unlock_napi(struct ixgbe_q_vector *q_vector)
+{
+	int rc = false;
+	spin_lock(&q_vector->lock);
+	WARN_ON(q_vector->state & (IXGBE_QV_STATE_POLL |
+			       IXGBE_QV_STATE_NAPI_YIELD));
+
+	if (q_vector->state & IXGBE_QV_STATE_POLL_YIELD)
+		rc = true;
+	q_vector->state = IXGBE_QV_STATE_IDLE;
+	spin_unlock(&q_vector->lock);
+	return rc;
+}
+
+/* called from ixgbe_low_latency_poll() */
+static inline bool ixgbe_qv_lock_poll(struct ixgbe_q_vector *q_vector)
+{
+	int rc = true;
+	spin_lock_bh(&q_vector->lock);
+	if ((q_vector->state & IXGBE_QV_LOCKED)) {
+		q_vector->state |= IXGBE_QV_STATE_POLL_YIELD;
+		rc = false;
+#ifdef LL_EXTENDED_STATS
+		q_vector->rx.ring->stats.yields++;
+#endif
+	} else
+		/* preserve yield marks */
+		q_vector->state |= IXGBE_QV_STATE_POLL;
+	spin_unlock_bh(&q_vector->lock);
+	return rc;
+}
+
+/* returns true if someone tried to get the qv while it was locked */
+static inline bool ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector)
+{
+	int rc = false;
+	spin_lock_bh(&q_vector->lock);
+	WARN_ON(q_vector->state & (IXGBE_QV_STATE_NAPI));
+
+	if (q_vector->state & IXGBE_QV_STATE_POLL_YIELD)
+		rc = true;
+	q_vector->state = IXGBE_QV_STATE_IDLE;
+	spin_unlock_bh(&q_vector->lock);
+	return rc;
+}
+
+/* true if a socket is polling, even if it did not get the lock */
+static inline bool ixgbe_qv_ll_polling(struct ixgbe_q_vector *q_vector)
+{
+	WARN_ON(!(q_vector->state & IXGBE_QV_LOCKED));
+	return q_vector->state & IXGBE_QV_USER_PEND;
+}
+#else /* CONFIG_NET_RX_BUSY_POLL */
+static inline void ixgbe_qv_init_lock(struct ixgbe_q_vector *q_vector)
+{
+}
+
+static inline bool ixgbe_qv_lock_napi(struct ixgbe_q_vector *q_vector)
+{
+	return true;
+}
+
+static inline bool ixgbe_qv_unlock_napi(struct ixgbe_q_vector *q_vector)
+{
+	return false;
+}
+
+static inline bool ixgbe_qv_lock_poll(struct ixgbe_q_vector *q_vector)
+{
+	return false;
+}
+
+static inline bool ixgbe_qv_unlock_poll(struct ixgbe_q_vector *q_vector)
+{
+	return false;
+}
+
+static inline bool ixgbe_qv_ll_polling(struct ixgbe_q_vector *q_vector)
+{
+	return false;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
 #ifdef CONFIG_IXGBE_HWMON
 
 #define IXGBE_HWMON_TYPE_LOC		0
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c	2013-08-25 20:43:22.000000000 -0400
@@ -811,6 +811,7 @@ static int ixgbe_alloc_q_vector(struct i
 	/* initialize NAPI */
 	netif_napi_add(adapter->netdev, &q_vector->napi,
 		       ixgbe_poll, 64);
+	napi_hash_add(&q_vector->napi);
 
 	/* tie q_vector and adapter together */
 	adapter->q_vector[v_idx] = q_vector;
@@ -931,6 +932,7 @@ static void ixgbe_free_q_vector(struct i
 		adapter->rx_ring[ring->queue_index] = NULL;
 
 	adapter->q_vector[v_idx] = NULL;
+	napi_hash_del(&q_vector->napi);
 	netif_napi_del(&q_vector->napi);
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1504,7 +1504,9 @@ static void ixgbe_rx_skb(struct ixgbe_q_
 {
 	struct ixgbe_adapter *adapter = q_vector->adapter;
 
-	if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
+	if (ixgbe_qv_ll_polling(q_vector))
+		netif_receive_skb(skb);
+	else if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
 		napi_gro_receive(&q_vector->napi, skb);
 	else
 		netif_rx(skb);
@@ -1892,9 +1894,9 @@ dma_sync:
  * expensive overhead for IOMMU access this provides a means of avoiding
  * it by maintaining the mapping of the page to the syste.
  *
- * Returns true if all work is completed without reaching budget
+ * Returns amount of work completed
  **/
-static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
+static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 			       struct ixgbe_ring *rx_ring,
 			       const int budget)
 {
@@ -1976,6 +1978,7 @@ static bool ixgbe_clean_rx_irq(struct ix
 		}
 
 #endif /* IXGBE_FCOE */
+		skb_mark_napi_id(skb, &q_vector->napi);
 		ixgbe_rx_skb(q_vector, skb);
 
 		/* update budget accounting */
@@ -1992,9 +1995,43 @@ static bool ixgbe_clean_rx_irq(struct ix
 	if (cleaned_count)
 		ixgbe_alloc_rx_buffers(rx_ring, cleaned_count);
 
-	return (total_rx_packets < budget);
+	return total_rx_packets;
 }
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+/* must be called with local_bh_disable()d */
+static int ixgbe_low_latency_recv(struct napi_struct *napi)
+{
+	struct ixgbe_q_vector *q_vector =
+			container_of(napi, struct ixgbe_q_vector, napi);
+	struct ixgbe_adapter *adapter = q_vector->adapter;
+	struct ixgbe_ring  *ring;
+	int found = 0;
+
+	if (test_bit(__IXGBE_DOWN, &adapter->state))
+		return LL_FLUSH_FAILED;
+
+	if (!ixgbe_qv_lock_poll(q_vector))
+		return LL_FLUSH_BUSY;
+
+	ixgbe_for_each_ring(ring, q_vector->rx) {
+		found = ixgbe_clean_rx_irq(q_vector, ring, 4);
+#ifdef LL_EXTENDED_STATS
+		if (found)
+			ring->stats.cleaned += found;
+		else
+			ring->stats.misses++;
+#endif
+		if (found)
+			break;
+	}
+
+	ixgbe_qv_unlock_poll(q_vector);
+
+	return found;
+}
+#endif	/* CONFIG_NET_RX_BUSY_POLL */
+
 /**
  * ixgbe_configure_msix - Configure MSI-X hardware
  * @adapter: board private structure
@@ -2550,6 +2587,9 @@ int ixgbe_poll(struct napi_struct *napi,
 	ixgbe_for_each_ring(ring, q_vector->tx)
 		clean_complete &= !!ixgbe_clean_tx_irq(q_vector, ring);
 
+	if (!ixgbe_qv_lock_napi(q_vector))
+		return budget;
+
 	/* attempt to distribute budget to each queue fairly, but don't allow
 	 * the budget to go below 1 because we'll exit polling */
 	if (q_vector->rx.count > 1)
@@ -2558,9 +2598,10 @@ int ixgbe_poll(struct napi_struct *napi,
 		per_ring_budget = budget;
 
 	ixgbe_for_each_ring(ring, q_vector->rx)
-		clean_complete &= ixgbe_clean_rx_irq(q_vector, ring,
-						     per_ring_budget);
+		clean_complete &= (ixgbe_clean_rx_irq(q_vector, ring,
+				   per_ring_budget) < per_ring_budget);
 
+	ixgbe_qv_unlock_napi(q_vector);
 	/* If all work not completed, return budget and keep polling */
 	if (!clean_complete)
 		return budget;
@@ -3747,16 +3788,25 @@ static void ixgbe_napi_enable_all(struct
 {
 	int q_idx;
 
-	for (q_idx = 0; q_idx < adapter->num_q_vectors; q_idx++)
+	for (q_idx = 0; q_idx < adapter->num_q_vectors; q_idx++) {
+		ixgbe_qv_init_lock(adapter->q_vector[q_idx]);
 		napi_enable(&adapter->q_vector[q_idx]->napi);
+	}
 }
 
 static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
 {
 	int q_idx;
 
-	for (q_idx = 0; q_idx < adapter->num_q_vectors; q_idx++)
+	local_bh_disable(); /* for ixgbe_qv_lock_napi() */
+	for (q_idx = 0; q_idx < adapter->num_q_vectors; q_idx++) {
 		napi_disable(&adapter->q_vector[q_idx]->napi);
+		while (!ixgbe_qv_lock_napi(adapter->q_vector[q_idx])) {
+			pr_info("QV %d locked\n", q_idx);
+			mdelay(1);
+		}
+	}
+	local_bh_enable();
 }
 
 #ifdef CONFIG_IXGBE_DCB
@@ -7177,6 +7227,9 @@ static const struct net_device_ops ixgbe
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= ixgbe_netpoll,
 #endif
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	.ndo_busy_poll		= ixgbe_low_latency_recv,
+#endif
 #ifdef IXGBE_FCOE
 	.ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
 	.ndo_fcoe_ddp_target = ixgbe_fcoe_ddp_target,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/intel/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/intel/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/intel/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -20,7 +20,6 @@ if NET_VENDOR_INTEL
 config E100
 	tristate "Intel(R) PRO/100+ support"
 	depends on PCI
-	select NET_CORE
 	select MII
 	---help---
 	  This driver supports Intel(R) PRO/100 family of adapters.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/jme.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/jme.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/jme.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/jme.c	2013-08-25 20:43:22.000000000 -0400
@@ -3148,7 +3148,6 @@ jme_init_one(struct pci_dev *pdev,
 	jme->mii_if.mdio_write = jme_mdio_write;
 
 	jme_clear_pm(jme);
-	pci_set_power_state(jme->pdev, PCI_D0);
 	device_set_wakeup_enable(&pdev->dev, true);
 
 	jme_set_phyfifo_5level(jme);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -20,9 +20,11 @@ config SUNGEM_PHY
 source "drivers/net/ethernet/3com/Kconfig"
 source "drivers/net/ethernet/adaptec/Kconfig"
 source "drivers/net/ethernet/aeroflex/Kconfig"
+source "drivers/net/ethernet/allwinner/Kconfig"
 source "drivers/net/ethernet/alteon/Kconfig"
 source "drivers/net/ethernet/amd/Kconfig"
 source "drivers/net/ethernet/apple/Kconfig"
+source "drivers/net/ethernet/arc/Kconfig"
 source "drivers/net/ethernet/atheros/Kconfig"
 source "drivers/net/ethernet/cadence/Kconfig"
 source "drivers/net/ethernet/adi/Kconfig"
@@ -63,7 +65,6 @@ config JME
 	tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This driver supports the PCI-Express gigabit ethernet adapters
@@ -95,7 +96,6 @@ config FEALNX
 	tristate "Myson MTD-8xx PCI Ethernet support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  Say Y here to support the Myson MTD-800 family of PCI-based Ethernet
@@ -106,7 +106,6 @@ source "drivers/net/ethernet/8390/Kconfi
 
 config NET_NETX
 	tristate "NetX Ethernet support"
-	select NET_CORE
 	select MII
 	depends on ARCH_NETX
 	---help---
@@ -124,7 +123,6 @@ source "drivers/net/ethernet/oki-semi/Kc
 config ETHOC
 	tristate "OpenCores 10/100 Mbps Ethernet MAC support"
 	depends on HAS_IOMEM && HAS_DMA
-	select NET_CORE
 	select MII
 	select PHYLIB
 	select CRC32
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/korina.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/korina.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/korina.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/korina.c	2013-08-25 20:43:22.000000000 -0400
@@ -483,7 +483,6 @@ static void korina_multicast_list(struct
 	unsigned long flags;
 	struct netdev_hw_addr *ha;
 	u32 recognise = ETH_ARC_AB;	/* always accept broadcasts */
-	int i;
 
 	/* Set promiscuous mode */
 	if (dev->flags & IFF_PROMISC)
@@ -495,12 +494,9 @@ static void korina_multicast_list(struct
 
 	/* Build the hash table */
 	if (netdev_mc_count(dev) > 4) {
-		u16 hash_table[4];
+		u16 hash_table[4] = { 0 };
 		u32 crc;
 
-		for (i = 0; i < 4; i++)
-			hash_table[i] = 0;
-
 		netdev_for_each_mc_addr(ha, dev) {
 			crc = ether_crc_le(6, ha->addr);
 			crc >>= 26;
@@ -1214,7 +1210,6 @@ static int korina_remove(struct platform
 	iounmap(lp->rx_dma_regs);
 	iounmap(lp->tx_dma_regs);
 
-	platform_set_drvdata(pdev, NULL);
 	unregister_netdev(bif->dev);
 	free_netdev(bif->dev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/Makefile linux-libre-3.11-rc7-gnu/drivers/net/ethernet/Makefile
--- linux-libre-3.10-gnu/drivers/net/ethernet/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -6,9 +6,11 @@ obj-$(CONFIG_NET_VENDOR_3COM) += 3com/
 obj-$(CONFIG_NET_VENDOR_8390) += 8390/
 obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/
 obj-$(CONFIG_GRETH) += aeroflex/
+obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/
 obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
 obj-$(CONFIG_NET_VENDOR_AMD) += amd/
 obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
+obj-$(CONFIG_NET_VENDOR_ARC) += arc/
 obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
 obj-$(CONFIG_NET_CADENCE) += cadence/
 obj-$(CONFIG_NET_BFIN) += adi/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/marvell/mv643xx_eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/mv643xx_eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/marvell/mv643xx_eth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/mv643xx_eth.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,6 +60,10 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
 
 static char mv643xx_eth_driver_name[] = "mv643xx_eth";
 static char mv643xx_eth_driver_version[] = "1.4";
@@ -115,6 +119,8 @@ static char mv643xx_eth_driver_version[]
 #define  LINK_UP			0x00000002
 #define TXQ_COMMAND			0x0048
 #define TXQ_FIX_PRIO_CONF		0x004c
+#define PORT_SERIAL_CONTROL1		0x004c
+#define  CLK125_BYPASS_EN		0x00000010
 #define TX_BW_RATE			0x0050
 #define TX_BW_MTU			0x0058
 #define TX_BW_BURST			0x005c
@@ -615,7 +621,7 @@ static int rxq_refill(struct rx_queue *r
 
 		rx_desc = rxq->rx_desc_area + rx;
 
-		size = skb->end - skb->data;
+		size = skb_end_pointer(skb) - skb->data;
 		rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent,
 						  skb->data, size,
 						  DMA_FROM_DEVICE);
@@ -2450,13 +2456,159 @@ static void infer_hw_params(struct mv643
 	}
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id mv643xx_eth_shared_ids[] = {
+	{ .compatible = "marvell,orion-eth", },
+	{ .compatible = "marvell,kirkwood-eth", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_ids);
+#endif
+
+#if defined(CONFIG_OF) && !defined(CONFIG_MV64X60)
+#define mv643xx_eth_property(_np, _name, _v)				\
+	do {								\
+		u32 tmp;						\
+		if (!of_property_read_u32(_np, "marvell," _name, &tmp))	\
+			_v = tmp;					\
+	} while (0)
+
+static struct platform_device *port_platdev[3];
+
+static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
+					  struct device_node *pnp)
+{
+	struct platform_device *ppdev;
+	struct mv643xx_eth_platform_data ppd;
+	struct resource res;
+	const char *mac_addr;
+	int ret;
+	int dev_num = 0;
+
+	memset(&ppd, 0, sizeof(ppd));
+	ppd.shared = pdev;
+
+	memset(&res, 0, sizeof(res));
+	if (!of_irq_to_resource(pnp, 0, &res)) {
+		dev_err(&pdev->dev, "missing interrupt on %s\n", pnp->name);
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(pnp, "reg", &ppd.port_number)) {
+		dev_err(&pdev->dev, "missing reg property on %s\n", pnp->name);
+		return -EINVAL;
+	}
+
+	if (ppd.port_number >= 3) {
+		dev_err(&pdev->dev, "invalid reg property on %s\n", pnp->name);
+		return -EINVAL;
+	}
+
+	while (dev_num < 3 && port_platdev[dev_num])
+		dev_num++;
+
+	if (dev_num == 3) {
+		dev_err(&pdev->dev, "too many ports registered\n");
+		return -EINVAL;
+	}
+
+	mac_addr = of_get_mac_address(pnp);
+	if (mac_addr)
+		memcpy(ppd.mac_addr, mac_addr, 6);
+
+	mv643xx_eth_property(pnp, "tx-queue-size", ppd.tx_queue_size);
+	mv643xx_eth_property(pnp, "tx-sram-addr", ppd.tx_sram_addr);
+	mv643xx_eth_property(pnp, "tx-sram-size", ppd.tx_sram_size);
+	mv643xx_eth_property(pnp, "rx-queue-size", ppd.rx_queue_size);
+	mv643xx_eth_property(pnp, "rx-sram-addr", ppd.rx_sram_addr);
+	mv643xx_eth_property(pnp, "rx-sram-size", ppd.rx_sram_size);
+
+	ppd.phy_node = of_parse_phandle(pnp, "phy-handle", 0);
+	if (!ppd.phy_node) {
+		ppd.phy_addr = MV643XX_ETH_PHY_NONE;
+		of_property_read_u32(pnp, "speed", &ppd.speed);
+		of_property_read_u32(pnp, "duplex", &ppd.duplex);
+	}
+
+	ppdev = platform_device_alloc(MV643XX_ETH_NAME, dev_num);
+	if (!ppdev)
+		return -ENOMEM;
+	ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+	ret = platform_device_add_resources(ppdev, &res, 1);
+	if (ret)
+		goto port_err;
+
+	ret = platform_device_add_data(ppdev, &ppd, sizeof(ppd));
+	if (ret)
+		goto port_err;
+
+	ret = platform_device_add(ppdev);
+	if (ret)
+		goto port_err;
+
+	port_platdev[dev_num] = ppdev;
+
+	return 0;
+
+port_err:
+	platform_device_put(ppdev);
+	return ret;
+}
+
+static int mv643xx_eth_shared_of_probe(struct platform_device *pdev)
+{
+	struct mv643xx_eth_shared_platform_data *pd;
+	struct device_node *pnp, *np = pdev->dev.of_node;
+	int ret;
+
+	/* bail out if not registered from DT */
+	if (!np)
+		return 0;
+
+	pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return -ENOMEM;
+	pdev->dev.platform_data = pd;
+
+	mv643xx_eth_property(np, "tx-checksum-limit", pd->tx_csum_limit);
+
+	for_each_available_child_of_node(np, pnp) {
+		ret = mv643xx_eth_shared_of_add_port(pdev, pnp);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+static void mv643xx_eth_shared_of_remove(void)
+{
+	int n;
+
+	for (n = 0; n < 3; n++) {
+		platform_device_del(port_platdev[n]);
+		port_platdev[n] = NULL;
+	}
+}
+#else
+static inline int mv643xx_eth_shared_of_probe(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static inline void mv643xx_eth_shared_of_remove(void)
+{
+}
+#endif
+
 static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 {
 	static int mv643xx_eth_version_printed;
-	struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
+	struct mv643xx_eth_shared_platform_data *pd;
 	struct mv643xx_eth_shared_private *msp;
 	const struct mbus_dram_target_info *dram;
 	struct resource *res;
+	int ret;
 
 	if (!mv643xx_eth_version_printed++)
 		pr_notice("MV-643xx 10/100/1000 ethernet driver version %s\n",
@@ -2469,8 +2621,9 @@ static int mv643xx_eth_shared_probe(stru
 	msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL);
 	if (msp == NULL)
 		return -ENOMEM;
+	platform_set_drvdata(pdev, msp);
 
-	msp->base = ioremap(res->start, resource_size(res));
+	msp->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
 	if (msp->base == NULL)
 		return -ENOMEM;
 
@@ -2485,12 +2638,15 @@ static int mv643xx_eth_shared_probe(stru
 	if (dram)
 		mv643xx_eth_conf_mbus_windows(msp, dram);
 
+	ret = mv643xx_eth_shared_of_probe(pdev);
+	if (ret)
+		return ret;
+	pd = pdev->dev.platform_data;
+
 	msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ?
 					pd->tx_csum_limit : 9 * 1024;
 	infer_hw_params(msp);
 
-	platform_set_drvdata(pdev, msp);
-
 	return 0;
 }
 
@@ -2498,10 +2654,9 @@ static int mv643xx_eth_shared_remove(str
 {
 	struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);
 
-	iounmap(msp->base);
+	mv643xx_eth_shared_of_remove();
 	if (!IS_ERR(msp->clk))
 		clk_disable_unprepare(msp->clk);
-
 	return 0;
 }
 
@@ -2511,6 +2666,7 @@ static struct platform_driver mv643xx_et
 	.driver = {
 		.name	= MV643XX_ETH_SHARED_NAME,
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(mv643xx_eth_shared_ids),
 	},
 };
 
@@ -2701,6 +2857,15 @@ static int mv643xx_eth_probe(struct plat
 
 	mp->dev = dev;
 
+	/* Kirkwood resets some registers on gated clocks. Especially
+	 * CLK125_BYPASS_EN must be cleared but is not available on
+	 * all other SoCs/System Controllers using this driver.
+	 */
+	if (of_device_is_compatible(pdev->dev.of_node,
+				    "marvell,kirkwood-eth-port"))
+		wrlp(mp, PORT_SERIAL_CONTROL1,
+		     rdlp(mp, PORT_SERIAL_CONTROL1) & ~CLK125_BYPASS_EN);
+
 	/*
 	 * Start with a default rate, and if there is a clock, allow
 	 * it to override the default.
@@ -2710,23 +2875,35 @@ static int mv643xx_eth_probe(struct plat
 	if (!IS_ERR(mp->clk)) {
 		clk_prepare_enable(mp->clk);
 		mp->t_clk = clk_get_rate(mp->clk);
+	} else if (!IS_ERR(mp->shared->clk)) {
+		mp->t_clk = clk_get_rate(mp->shared->clk);
 	}
 
 	set_params(mp, pd);
 	netif_set_real_num_tx_queues(dev, mp->txq_count);
 	netif_set_real_num_rx_queues(dev, mp->rxq_count);
 
-	if (pd->phy_addr != MV643XX_ETH_PHY_NONE) {
+	err = 0;
+	if (pd->phy_node) {
+		mp->phy = of_phy_connect(mp->dev, pd->phy_node,
+					 mv643xx_eth_adjust_link, 0,
+					 PHY_INTERFACE_MODE_GMII);
+		if (!mp->phy)
+			err = -ENODEV;
+	} else if (pd->phy_addr != MV643XX_ETH_PHY_NONE) {
 		mp->phy = phy_scan(mp, pd->phy_addr);
 
-		if (IS_ERR(mp->phy)) {
+		if (IS_ERR(mp->phy))
 			err = PTR_ERR(mp->phy);
-			if (err == -ENODEV)
-				err = -EPROBE_DEFER;
-			goto out;
-		}
-		phy_init(mp, pd->speed, pd->duplex);
+		else
+			phy_init(mp, pd->speed, pd->duplex);
+	}
+	if (err == -ENODEV) {
+		err = -EPROBE_DEFER;
+		goto out;
 	}
+	if (err)
+		goto out;
 
 	SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
 
@@ -2805,7 +2982,7 @@ static int mv643xx_eth_remove(struct pla
 
 	unregister_netdev(mp->dev);
 	if (mp->phy != NULL)
-		phy_detach(mp->phy);
+		phy_disconnect(mp->phy);
 	cancel_work_sync(&mp->tx_timeout_task);
 
 	if (!IS_ERR(mp->clk))
@@ -2813,8 +2990,6 @@ static int mv643xx_eth_remove(struct pla
 
 	free_netdev(mp->dev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/marvell/mvneta.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/mvneta.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/marvell/mvneta.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/mvneta.c	2013-08-25 20:43:22.000000000 -0400
@@ -88,6 +88,8 @@
 #define      MVNETA_TX_IN_PRGRS                  BIT(1)
 #define      MVNETA_TX_FIFO_EMPTY                BIT(8)
 #define MVNETA_RX_MIN_FRAME_SIZE                 0x247c
+#define MVNETA_SGMII_SERDES_CFG			 0x24A0
+#define      MVNETA_SGMII_SERDES_PROTO		 0x0cc7
 #define MVNETA_TYPE_PRIO                         0x24bc
 #define      MVNETA_FORCE_UNI                    BIT(21)
 #define MVNETA_TXQ_CMD_1                         0x24e4
@@ -655,6 +657,8 @@ static void mvneta_port_sgmii_config(str
 	val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
 	val |= MVNETA_GMAC2_PSC_ENABLE;
 	mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
+
+	mvreg_write(pp, MVNETA_SGMII_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
 }
 
 /* Start the Ethernet port RX and TX activity */
@@ -2251,6 +2255,21 @@ static int mvneta_change_mtu(struct net_
 	return 0;
 }
 
+/* Get mac address */
+static void mvneta_get_mac_addr(struct mvneta_port *pp, unsigned char *addr)
+{
+	u32 mac_addr_l, mac_addr_h;
+
+	mac_addr_l = mvreg_read(pp, MVNETA_MAC_ADDR_LOW);
+	mac_addr_h = mvreg_read(pp, MVNETA_MAC_ADDR_HIGH);
+	addr[0] = (mac_addr_h >> 24) & 0xFF;
+	addr[1] = (mac_addr_h >> 16) & 0xFF;
+	addr[2] = (mac_addr_h >> 8) & 0xFF;
+	addr[3] = mac_addr_h & 0xFF;
+	addr[4] = (mac_addr_l >> 8) & 0xFF;
+	addr[5] = mac_addr_l & 0xFF;
+}
+
 /* Handle setting mac address */
 static int mvneta_set_mac_addr(struct net_device *dev, void *addr)
 {
@@ -2667,7 +2686,9 @@ static int mvneta_probe(struct platform_
 	u32 phy_addr;
 	struct mvneta_port *pp;
 	struct net_device *dev;
-	const char *mac_addr;
+	const char *dt_mac_addr;
+	char hw_mac_addr[ETH_ALEN];
+	const char *mac_from;
 	int phy_mode;
 	int err;
 
@@ -2703,13 +2724,6 @@ static int mvneta_probe(struct platform_
 		goto err_free_irq;
 	}
 
-	mac_addr = of_get_mac_address(dn);
-
-	if (!mac_addr || !is_valid_ether_addr(mac_addr))
-		eth_hw_addr_random(dev);
-	else
-		memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
-
 	dev->tx_queue_len = MVNETA_MAX_TXD;
 	dev->watchdog_timeo = 5 * HZ;
 	dev->netdev_ops = &mvneta_netdev_ops;
@@ -2718,29 +2732,43 @@ static int mvneta_probe(struct platform_
 
 	pp = netdev_priv(dev);
 
-	pp->tx_done_timer.function = mvneta_tx_done_timer_callback;
-	init_timer(&pp->tx_done_timer);
-	clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
-
 	pp->weight = MVNETA_RX_POLL_WEIGHT;
 	pp->phy_node = phy_node;
 	pp->phy_interface = phy_mode;
 
-	pp->base = of_iomap(dn, 0);
-	if (pp->base == NULL) {
-		err = -ENOMEM;
-		goto err_free_irq;
-	}
-
 	pp->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(pp->clk)) {
 		err = PTR_ERR(pp->clk);
-		goto err_unmap;
+		goto err_free_irq;
 	}
 
 	clk_prepare_enable(pp->clk);
 
+	pp->base = of_iomap(dn, 0);
+	if (pp->base == NULL) {
+		err = -ENOMEM;
+		goto err_clk;
+	}
+
+	dt_mac_addr = of_get_mac_address(dn);
+	if (dt_mac_addr && is_valid_ether_addr(dt_mac_addr)) {
+		mac_from = "device tree";
+		memcpy(dev->dev_addr, dt_mac_addr, ETH_ALEN);
+	} else {
+		mvneta_get_mac_addr(pp, hw_mac_addr);
+		if (is_valid_ether_addr(hw_mac_addr)) {
+			mac_from = "hardware";
+			memcpy(dev->dev_addr, hw_mac_addr, ETH_ALEN);
+		} else {
+			mac_from = "random";
+			eth_hw_addr_random(dev);
+		}
+	}
+
 	pp->tx_done_timer.data = (unsigned long)dev;
+	pp->tx_done_timer.function = mvneta_tx_done_timer_callback;
+	init_timer(&pp->tx_done_timer);
+	clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
 
 	pp->tx_ring_size = MVNETA_MAX_TXD;
 	pp->rx_ring_size = MVNETA_MAX_RXD;
@@ -2751,7 +2779,7 @@ static int mvneta_probe(struct platform_
 	err = mvneta_init(pp, phy_addr);
 	if (err < 0) {
 		dev_err(&pdev->dev, "can't init eth hal\n");
-		goto err_clk;
+		goto err_unmap;
 	}
 	mvneta_port_power_up(pp, phy_mode);
 
@@ -2772,7 +2800,8 @@ static int mvneta_probe(struct platform_
 		goto err_deinit;
 	}
 
-	netdev_info(dev, "mac: %pM\n", dev->dev_addr);
+	netdev_info(dev, "Using %s mac address %pM\n", mac_from,
+		    dev->dev_addr);
 
 	platform_set_drvdata(pdev, pp->dev);
 
@@ -2780,10 +2809,10 @@ static int mvneta_probe(struct platform_
 
 err_deinit:
 	mvneta_deinit(pp);
-err_clk:
-	clk_disable_unprepare(pp->clk);
 err_unmap:
 	iounmap(pp->base);
+err_clk:
+	clk_disable_unprepare(pp->clk);
 err_free_irq:
 	irq_dispose_mapping(dev->irq);
 err_free_netdev:
@@ -2804,8 +2833,6 @@ static int mvneta_remove(struct platform
 	irq_dispose_mapping(dev->irq);
 	free_netdev(dev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/marvell/pxa168_eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/pxa168_eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/marvell/pxa168_eth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/pxa168_eth.c	2013-08-25 20:43:22.000000000 -0400
@@ -357,7 +357,7 @@ static void rxq_refill(struct net_device
 		/* Get 'used' Rx descriptor */
 		used_rx_desc = pep->rx_used_desc_q;
 		p_used_rx_desc = &pep->p_rx_desc_area[used_rx_desc];
-		size = skb->end - skb->data;
+		size = skb_end_pointer(skb) - skb->data;
 		p_used_rx_desc->buf_ptr = dma_map_single(NULL,
 							 skb->data,
 							 size,
@@ -1602,7 +1602,6 @@ static int pxa168_eth_remove(struct plat
 	unregister_netdev(dev);
 	cancel_work_sync(&pep->tx_timeout_task);
 	free_netdev(dev);
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/marvell/skge.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/skge.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/marvell/skge.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/skge.c	2013-08-25 20:43:22.000000000 -0400
@@ -931,17 +931,20 @@ static int skge_ring_alloc(struct skge_r
 }
 
 /* Allocate and setup a new buffer for receiving */
-static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
-			  struct sk_buff *skb, unsigned int bufsize)
+static int skge_rx_setup(struct skge_port *skge, struct skge_element *e,
+			 struct sk_buff *skb, unsigned int bufsize)
 {
 	struct skge_rx_desc *rd = e->desc;
-	u64 map;
+	dma_addr_t map;
 
 	map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
 			     PCI_DMA_FROMDEVICE);
 
-	rd->dma_lo = map;
-	rd->dma_hi = map >> 32;
+	if (pci_dma_mapping_error(skge->hw->pdev, map))
+		return -1;
+
+	rd->dma_lo = lower_32_bits(map);
+	rd->dma_hi = upper_32_bits(map);
 	e->skb = skb;
 	rd->csum1_start = ETH_HLEN;
 	rd->csum2_start = ETH_HLEN;
@@ -953,6 +956,7 @@ static void skge_rx_setup(struct skge_po
 	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
 	dma_unmap_addr_set(e, mapaddr, map);
 	dma_unmap_len_set(e, maplen, bufsize);
+	return 0;
 }
 
 /* Resume receiving using existing skb,
@@ -1014,7 +1018,10 @@ static int skge_rx_fill(struct net_devic
 			return -ENOMEM;
 
 		skb_reserve(skb, NET_IP_ALIGN);
-		skge_rx_setup(skge, e, skb, skge->rx_buf_size);
+		if (skge_rx_setup(skge, e, skb, skge->rx_buf_size) < 0) {
+			dev_kfree_skb(skb);
+			return -EIO;
+		}
 	} while ((e = e->next) != ring->start);
 
 	ring->to_clean = ring->start;
@@ -2544,7 +2551,7 @@ static int skge_up(struct net_device *de
 
 	BUG_ON(skge->dma & 7);
 
-	if ((u64)skge->dma >> 32 != ((u64) skge->dma + skge->mem_size) >> 32) {
+	if (upper_32_bits(skge->dma) != upper_32_bits(skge->dma + skge->mem_size)) {
 		dev_err(&hw->pdev->dev, "pci_alloc_consistent region crosses 4G boundary\n");
 		err = -EINVAL;
 		goto free_pci_mem;
@@ -2729,7 +2736,7 @@ static netdev_tx_t skge_xmit_frame(struc
 	struct skge_tx_desc *td;
 	int i;
 	u32 control, len;
-	u64 map;
+	dma_addr_t map;
 
 	if (skb_padto(skb, ETH_ZLEN))
 		return NETDEV_TX_OK;
@@ -2743,11 +2750,14 @@ static netdev_tx_t skge_xmit_frame(struc
 	e->skb = skb;
 	len = skb_headlen(skb);
 	map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(hw->pdev, map))
+		goto mapping_error;
+
 	dma_unmap_addr_set(e, mapaddr, map);
 	dma_unmap_len_set(e, maplen, len);
 
-	td->dma_lo = map;
-	td->dma_hi = map >> 32;
+	td->dma_lo = lower_32_bits(map);
+	td->dma_hi = upper_32_bits(map);
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		const int offset = skb_checksum_start_offset(skb);
@@ -2778,14 +2788,16 @@ static netdev_tx_t skge_xmit_frame(struc
 
 			map = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
 					       skb_frag_size(frag), DMA_TO_DEVICE);
+			if (dma_mapping_error(&hw->pdev->dev, map))
+				goto mapping_unwind;
 
 			e = e->next;
 			e->skb = skb;
 			tf = e->desc;
 			BUG_ON(tf->control & BMU_OWN);
 
-			tf->dma_lo = map;
-			tf->dma_hi = (u64) map >> 32;
+			tf->dma_lo = lower_32_bits(map);
+			tf->dma_hi = upper_32_bits(map);
 			dma_unmap_addr_set(e, mapaddr, map);
 			dma_unmap_len_set(e, maplen, skb_frag_size(frag));
 
@@ -2815,6 +2827,26 @@ static netdev_tx_t skge_xmit_frame(struc
 	}
 
 	return NETDEV_TX_OK;
+
+mapping_unwind:
+	e = skge->tx_ring.to_use;
+	pci_unmap_single(hw->pdev,
+			 dma_unmap_addr(e, mapaddr),
+			 dma_unmap_len(e, maplen),
+			 PCI_DMA_TODEVICE);
+	while (i-- > 0) {
+		e = e->next;
+		pci_unmap_page(hw->pdev,
+			       dma_unmap_addr(e, mapaddr),
+			       dma_unmap_len(e, maplen),
+			       PCI_DMA_TODEVICE);
+	}
+
+mapping_error:
+	if (net_ratelimit())
+		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
 }
 
 
@@ -3045,11 +3077,13 @@ static struct sk_buff *skge_rx_get(struc
 
 		pci_dma_sync_single_for_cpu(skge->hw->pdev,
 					    dma_unmap_addr(e, mapaddr),
-					    len, PCI_DMA_FROMDEVICE);
+					    dma_unmap_len(e, maplen),
+					    PCI_DMA_FROMDEVICE);
 		skb_copy_from_linear_data(e->skb, skb->data, len);
 		pci_dma_sync_single_for_device(skge->hw->pdev,
 					       dma_unmap_addr(e, mapaddr),
-					       len, PCI_DMA_FROMDEVICE);
+					       dma_unmap_len(e, maplen),
+					       PCI_DMA_FROMDEVICE);
 		skge_rx_reuse(e, skge->rx_buf_size);
 	} else {
 		struct sk_buff *nskb;
@@ -3058,13 +3092,17 @@ static struct sk_buff *skge_rx_get(struc
 		if (!nskb)
 			goto resubmit;
 
+		if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) {
+			dev_kfree_skb(nskb);
+			goto resubmit;
+		}
+
 		pci_unmap_single(skge->hw->pdev,
 				 dma_unmap_addr(e, mapaddr),
 				 dma_unmap_len(e, maplen),
 				 PCI_DMA_FROMDEVICE);
 		skb = e->skb;
 		prefetch(skb->data);
-		skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
 	}
 
 	skb_put(skb, len);
@@ -3706,7 +3744,7 @@ static const struct file_operations skge
 static int skge_device_event(struct notifier_block *unused,
 			     unsigned long event, void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct skge_port *skge;
 	struct dentry *d;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/marvell/sky2.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/sky2.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/marvell/sky2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/marvell/sky2.c	2013-08-25 20:43:22.000000000 -0400
@@ -4642,7 +4642,7 @@ static const struct file_operations sky2
 static int sky2_device_event(struct notifier_block *unused,
 			     unsigned long event, void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct sky2_port *sky2 = netdev_priv(dev);
 
 	if (dev->netdev_ops->ndo_open != sky2_open || !sky2_debug)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -19,5 +19,6 @@ config NET_VENDOR_MELLANOX
 if NET_VENDOR_MELLANOX
 
 source "drivers/net/ethernet/mellanox/mlx4/Kconfig"
+source "drivers/net/ethernet/mellanox/mlx5/core/Kconfig"
 
 endif # NET_VENDOR_MELLANOX
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/Makefile linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/Makefile
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_MLX4_CORE) += mlx4/
+obj-$(CONFIG_MLX5_CORE) += mlx5/core/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/cmd.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/cmd.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/cmd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/cmd.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/errno.h>
 
 #include <linux/mlx4/cmd.h>
+#include <linux/mlx4/device.h>
 #include <linux/semaphore.h>
 #include <rdma/ib_smi.h>
 
@@ -111,6 +112,14 @@ enum {
 	GO_BIT_TIMEOUT_MSECS	= 10000
 };
 
+enum mlx4_vlan_transition {
+	MLX4_VLAN_TRANSITION_VST_VST = 0,
+	MLX4_VLAN_TRANSITION_VST_VGT = 1,
+	MLX4_VLAN_TRANSITION_VGT_VST = 2,
+	MLX4_VLAN_TRANSITION_VGT_VGT = 3,
+};
+
+
 struct mlx4_cmd_context {
 	struct completion	done;
 	int			result;
@@ -256,6 +265,8 @@ static int mlx4_comm_cmd_wait(struct mlx
 
 	if (!wait_for_completion_timeout(&context->done,
 					 msecs_to_jiffies(timeout))) {
+		mlx4_warn(dev, "communication channel command 0x%x timed out\n",
+			  op);
 		err = -EBUSY;
 		goto out;
 	}
@@ -485,6 +496,8 @@ static int mlx4_cmd_poll(struct mlx4_dev
 	}
 
 	if (cmd_pending(dev)) {
+		mlx4_warn(dev, "command 0x%x timed out (go bit not cleared)\n",
+			  op);
 		err = -ETIMEDOUT;
 		goto out;
 	}
@@ -548,6 +561,8 @@ static int mlx4_cmd_wait(struct mlx4_dev
 
 	if (!wait_for_completion_timeout(&context->done,
 					 msecs_to_jiffies(timeout))) {
+		mlx4_warn(dev, "command 0x%x timed out (go bit not cleared)\n",
+			  op);
 		err = -EBUSY;
 		goto out;
 	}
@@ -785,6 +800,15 @@ static int mlx4_MAD_IFC_wrapper(struct m
 				    vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
 }
 
+int MLX4_CMD_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave,
+		     struct mlx4_vhcr *vhcr,
+		     struct mlx4_cmd_mailbox *inbox,
+		     struct mlx4_cmd_mailbox *outbox,
+		     struct mlx4_cmd_info *cmd)
+{
+	return -EPERM;
+}
+
 int mlx4_DMA_wrapper(struct mlx4_dev *dev, int slave,
 		     struct mlx4_vhcr *vhcr,
 		     struct mlx4_cmd_mailbox *inbox,
@@ -1219,6 +1243,15 @@ static struct mlx4_cmd_info cmd_info[] =
 		.wrapper = mlx4_GEN_QP_wrapper
 	},
 	{
+		.opcode = MLX4_CMD_UPDATE_QP,
+		.has_inbox = false,
+		.has_outbox = false,
+		.out_is_imm = false,
+		.encode_slave_id = false,
+		.verify = NULL,
+		.wrapper = MLX4_CMD_UPDATE_QP_wrapper
+	},
+	{
 		.opcode = MLX4_CMD_CONF_SPECIAL_QP,
 		.has_inbox = false,
 		.has_outbox = false,
@@ -1488,6 +1521,102 @@ out:
 	return ret;
 }
 
+static int calculate_transition(u16 oper_vlan, u16 admin_vlan)
+{
+	return (2 * (oper_vlan == MLX4_VGT) + (admin_vlan == MLX4_VGT));
+}
+
+int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv,
+					    int slave, int port)
+{
+	struct mlx4_vport_oper_state *vp_oper;
+	struct mlx4_vport_state *vp_admin;
+	struct mlx4_vf_immed_vlan_work *work;
+	struct mlx4_dev *dev = &(priv->dev);
+	int err;
+	int admin_vlan_ix = NO_INDX;
+	enum mlx4_vlan_transition vlan_trans;
+
+	vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
+	vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
+
+	if (vp_oper->state.default_vlan == vp_admin->default_vlan &&
+	    vp_oper->state.default_qos == vp_admin->default_qos &&
+	    vp_oper->state.link_state == vp_admin->link_state)
+		return 0;
+
+	vlan_trans = calculate_transition(vp_oper->state.default_vlan,
+					  vp_admin->default_vlan);
+
+	if (!(priv->mfunc.master.slave_state[slave].active &&
+	      dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP &&
+	      vlan_trans == MLX4_VLAN_TRANSITION_VST_VST)) {
+		/* even if the UPDATE_QP command isn't supported, we still want
+		 * to set this VF link according to the admin directive
+		 */
+		vp_oper->state.link_state = vp_admin->link_state;
+		return -1;
+	}
+
+	mlx4_dbg(dev, "updating immediately admin params slave %d port %d\n",
+		 slave, port);
+	mlx4_dbg(dev, "vlan %d QoS %d link down %d\n", vp_admin->default_vlan,
+		 vp_admin->default_qos, vp_admin->link_state);
+
+	work = kzalloc(sizeof(*work), GFP_KERNEL);
+	if (!work)
+		return -ENOMEM;
+
+	if (vp_oper->state.default_vlan != vp_admin->default_vlan) {
+		err = __mlx4_register_vlan(&priv->dev, port,
+					   vp_admin->default_vlan,
+					   &admin_vlan_ix);
+		if (err) {
+			kfree(work);
+			mlx4_warn((&priv->dev),
+				  "No vlan resources slave %d, port %d\n",
+				  slave, port);
+			return err;
+		}
+		work->flags |= MLX4_VF_IMMED_VLAN_FLAG_VLAN;
+		mlx4_dbg((&(priv->dev)),
+			 "alloc vlan %d idx  %d slave %d port %d\n",
+			 (int)(vp_admin->default_vlan),
+			 admin_vlan_ix, slave, port);
+	}
+
+	/* save original vlan ix and vlan id */
+	work->orig_vlan_id = vp_oper->state.default_vlan;
+	work->orig_vlan_ix = vp_oper->vlan_idx;
+
+	/* handle new qos */
+	if (vp_oper->state.default_qos != vp_admin->default_qos)
+		work->flags |= MLX4_VF_IMMED_VLAN_FLAG_QOS;
+
+	if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN)
+		vp_oper->vlan_idx = admin_vlan_ix;
+
+	vp_oper->state.default_vlan = vp_admin->default_vlan;
+	vp_oper->state.default_qos = vp_admin->default_qos;
+	vp_oper->state.link_state = vp_admin->link_state;
+
+	if (vp_admin->link_state == IFLA_VF_LINK_STATE_DISABLE)
+		work->flags |= MLX4_VF_IMMED_VLAN_FLAG_LINK_DISABLE;
+
+	/* iterate over QPs owned by this slave, using UPDATE_QP */
+	work->port = port;
+	work->slave = slave;
+	work->qos = vp_oper->state.default_qos;
+	work->vlan_id = vp_oper->state.default_vlan;
+	work->vlan_ix = vp_oper->vlan_idx;
+	work->priv = priv;
+	INIT_WORK(&work->work, mlx4_vf_immed_vlan_work_handler);
+	queue_work(priv->mfunc.master.comm_wq, &work->work);
+
+	return 0;
+}
+
+
 static int mlx4_master_activate_admin_state(struct mlx4_priv *priv, int slave)
 {
 	int port, err;
@@ -2102,10 +2231,12 @@ int mlx4_set_vf_mac(struct mlx4_dev *dev
 }
 EXPORT_SYMBOL_GPL(mlx4_set_vf_mac);
 
+
 int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
-	struct mlx4_vport_state *s_info;
+	struct mlx4_vport_oper_state *vf_oper;
+	struct mlx4_vport_state *vf_admin;
 	int slave;
 
 	if ((!mlx4_is_master(dev)) ||
@@ -2119,12 +2250,19 @@ int mlx4_set_vf_vlan(struct mlx4_dev *de
 	if (slave < 0)
 		return -EINVAL;
 
-	s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
+	vf_admin = &priv->mfunc.master.vf_admin[slave].vport[port];
+	vf_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
+
 	if ((0 == vlan) && (0 == qos))
-		s_info->default_vlan = MLX4_VGT;
+		vf_admin->default_vlan = MLX4_VGT;
 	else
-		s_info->default_vlan = vlan;
-	s_info->default_qos = qos;
+		vf_admin->default_vlan = vlan;
+	vf_admin->default_qos = qos;
+
+	if (mlx4_master_immediate_activate_vlan_qos(priv, slave, port))
+		mlx4_info(dev,
+			  "updating vf %d port %d config will take effect on next VF restart\n",
+			  vf, port);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mlx4_set_vf_vlan);
@@ -2178,7 +2316,55 @@ int mlx4_get_vf_config(struct mlx4_dev *
 	ivf->qos	= s_info->default_qos;
 	ivf->tx_rate	= s_info->tx_rate;
 	ivf->spoofchk	= s_info->spoofchk;
+	ivf->linkstate	= s_info->link_state;
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mlx4_get_vf_config);
+
+int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_state)
+{
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	struct mlx4_vport_state *s_info;
+	int slave;
+	u8 link_stat_event;
+
+	slave = mlx4_get_slave_indx(dev, vf);
+	if (slave < 0)
+		return -EINVAL;
+
+	switch (link_state) {
+	case IFLA_VF_LINK_STATE_AUTO:
+		/* get current link state */
+		if (!priv->sense.do_sense_port[port])
+			link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_ACTIVE;
+		else
+			link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_DOWN;
+	    break;
+
+	case IFLA_VF_LINK_STATE_ENABLE:
+		link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_ACTIVE;
+	    break;
+
+	case IFLA_VF_LINK_STATE_DISABLE:
+		link_stat_event = MLX4_PORT_CHANGE_SUBTYPE_DOWN;
+	    break;
+
+	default:
+		mlx4_warn(dev, "unknown value for link_state %02x on slave %d port %d\n",
+			  link_state, slave, port);
+		return -EINVAL;
+	};
+	s_info = &priv->mfunc.master.vf_admin[slave].vport[port];
+	s_info->link_state = link_state;
+
+	/* send event */
+	mlx4_gen_port_state_change_eqe(dev, slave, port, link_stat_event);
+
+	if (mlx4_master_immediate_activate_vlan_qos(priv, slave, port))
+		mlx4_dbg(dev,
+			 "updating vf %d port %d no link state HW enforcment\n",
+			 vf, port);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_cq.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_cq.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_cq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_cq.c	2013-08-25 20:43:22.000000000 -0400
@@ -139,6 +139,7 @@ int mlx4_en_activate_cq(struct mlx4_en_p
 
 	if (!cq->is_tx) {
 		netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64);
+		napi_hash_add(&cq->napi);
 		napi_enable(&cq->napi);
 	}
 
@@ -162,6 +163,8 @@ void mlx4_en_deactivate_cq(struct mlx4_e
 {
 	if (!cq->is_tx) {
 		napi_disable(&cq->napi);
+		napi_hash_del(&cq->napi);
+		synchronize_rcu();
 		netif_napi_del(&cq->napi);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c	2013-08-25 20:43:22.000000000 -0400
@@ -207,9 +207,6 @@ static int mlx4_en_dcbnl_ieee_getmaxrate
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	int i;
 
-	if (!priv->maxrate)
-		return -EINVAL;
-
 	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
 		maxrate->tc_maxrate[i] =
 			priv->maxrate[i] * MLX4_RATELIMIT_UNITS_IN_KB;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -222,7 +222,12 @@ static int mlx4_en_get_sset_count(struct
 	switch (sset) {
 	case ETH_SS_STATS:
 		return (priv->stats_bitmap ? bit_count : NUM_ALL_STATS) +
-			(priv->tx_ring_num + priv->rx_ring_num) * 2;
+			(priv->tx_ring_num * 2) +
+#ifdef CONFIG_NET_RX_BUSY_POLL
+			(priv->rx_ring_num * 5);
+#else
+			(priv->rx_ring_num * 2);
+#endif
 	case ETH_SS_TEST:
 		return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.flags
 					& MLX4_DEV_CAP_FLAG_UC_LOOPBACK) * 2;
@@ -271,6 +276,11 @@ static void mlx4_en_get_ethtool_stats(st
 	for (i = 0; i < priv->rx_ring_num; i++) {
 		data[index++] = priv->rx_ring[i].packets;
 		data[index++] = priv->rx_ring[i].bytes;
+#ifdef CONFIG_NET_RX_BUSY_POLL
+		data[index++] = priv->rx_ring[i].yields;
+		data[index++] = priv->rx_ring[i].misses;
+		data[index++] = priv->rx_ring[i].cleaned;
+#endif
 	}
 	spin_unlock_bh(&priv->stats_lock);
 
@@ -334,6 +344,14 @@ static void mlx4_en_get_strings(struct n
 				"rx%d_packets", i);
 			sprintf(data + (index++) * ETH_GSTRING_LEN,
 				"rx%d_bytes", i);
+#ifdef CONFIG_NET_RX_BUSY_POLL
+			sprintf(data + (index++) * ETH_GSTRING_LEN,
+				"rx%d_napi_yield", i);
+			sprintf(data + (index++) * ETH_GSTRING_LEN,
+				"rx%d_misses", i);
+			sprintf(data + (index++) * ETH_GSTRING_LEN,
+				"rx%d_cleaned", i);
+#endif
 		}
 		break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -310,7 +310,7 @@ static void *mlx4_en_add(struct mlx4_dev
 err_mr:
 	(void) mlx4_mr_free(dev, &mdev->mr);
 err_map:
-	if (!mdev->uar_map)
+	if (mdev->uar_map)
 		iounmap(mdev->uar_map);
 err_uar:
 	mlx4_uar_free(dev, &mdev->priv_uar);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/slab.h>
 #include <linux/hash.h>
 #include <net/ip.h>
+#include <net/busy_poll.h>
 
 #include <linux/mlx4/driver.h>
 #include <linux/mlx4/device.h>
@@ -67,6 +68,34 @@ int mlx4_en_setup_tc(struct net_device *
 	return 0;
 }
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+/* must be called with local_bh_disable()d */
+static int mlx4_en_low_latency_recv(struct napi_struct *napi)
+{
+	struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi);
+	struct net_device *dev = cq->dev;
+	struct mlx4_en_priv *priv = netdev_priv(dev);
+	struct mlx4_en_rx_ring *rx_ring = &priv->rx_ring[cq->ring];
+	int done;
+
+	if (!priv->port_up)
+		return LL_FLUSH_FAILED;
+
+	if (!mlx4_en_cq_lock_poll(cq))
+		return LL_FLUSH_BUSY;
+
+	done = mlx4_en_process_rx_cq(dev, cq, 4);
+	if (likely(done))
+		rx_ring->cleaned += done;
+	else
+		rx_ring->misses++;
+
+	mlx4_en_cq_unlock_poll(cq);
+
+	return done;
+}
+#endif	/* CONFIG_NET_RX_BUSY_POLL */
+
 #ifdef CONFIG_RFS_ACCEL
 
 struct mlx4_en_filter {
@@ -376,7 +405,7 @@ static int mlx4_en_vlan_rx_add_vid(struc
 			en_err(priv, "Failed configuring VLAN filter\n");
 	}
 	if (mlx4_register_vlan(mdev->dev, priv->port, vid, &idx))
-		en_err(priv, "failed adding vlan %d\n", vid);
+		en_dbg(HW, priv, "failed adding vlan %d\n", vid);
 	mutex_unlock(&mdev->state_lock);
 
 	return 0;
@@ -399,7 +428,7 @@ static int mlx4_en_vlan_rx_kill_vid(stru
 	if (!mlx4_find_cached_vlan(mdev->dev, priv->port, vid, &idx))
 		mlx4_unregister_vlan(mdev->dev, priv->port, idx);
 	else
-		en_err(priv, "could not find vid %d in cache\n", vid);
+		en_dbg(HW, priv, "could not find vid %d in cache\n", vid);
 
 	if (mdev->device_up && priv->port_up) {
 		err = mlx4_SET_VLAN_FLTR(mdev->dev, priv);
@@ -1207,10 +1236,19 @@ static void mlx4_en_tx_timeout(struct ne
 {
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	struct mlx4_en_dev *mdev = priv->mdev;
+	int i;
 
 	if (netif_msg_timer(priv))
 		en_warn(priv, "Tx timeout called on port:%d\n", priv->port);
 
+	for (i = 0; i < priv->tx_ring_num; i++) {
+		if (!netif_tx_queue_stopped(netdev_get_tx_queue(dev, i)))
+			continue;
+		en_warn(priv, "TX timeout on queue: %d, QP: 0x%x, CQ: 0x%x, Cons: 0x%x, Prod: 0x%x\n",
+			i, priv->tx_ring[i].qpn, priv->tx_ring[i].cqn,
+			priv->tx_ring[i].cons, priv->tx_ring[i].prod);
+	}
+
 	priv->port_stats.tx_timeout++;
 	en_dbg(DRV, priv, "Scheduling watchdog\n");
 	queue_work(mdev->workqueue, &priv->watchdog_task);
@@ -1346,12 +1384,13 @@ static void mlx4_en_do_get_stats(struct
 
 	mutex_lock(&mdev->state_lock);
 	if (mdev->device_up) {
-		err = mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 0);
-		if (err)
-			en_dbg(HW, priv, "Could not update stats\n");
+		if (priv->port_up) {
+			err = mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 0);
+			if (err)
+				en_dbg(HW, priv, "Could not update stats\n");
 
-		if (priv->port_up)
 			mlx4_en_auto_moderation(priv);
+		}
 
 		queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
 	}
@@ -1445,6 +1484,8 @@ int mlx4_en_start_port(struct net_device
 	for (i = 0; i < priv->rx_ring_num; i++) {
 		cq = &priv->rx_cq[i];
 
+		mlx4_en_cq_init_lock(cq);
+
 		err = mlx4_en_activate_cq(priv, cq, i);
 		if (err) {
 			en_err(priv, "Failed activating Rx CQ\n");
@@ -1603,6 +1644,9 @@ void mlx4_en_stop_port(struct net_device
 		return;
 	}
 
+	/* close port*/
+	mlx4_CLOSE_PORT(mdev->dev, priv->port);
+
 	/* Synchronize with tx routine */
 	netif_tx_lock_bh(dev);
 	if (detach)
@@ -1694,14 +1738,20 @@ void mlx4_en_stop_port(struct net_device
 
 	/* Free RX Rings */
 	for (i = 0; i < priv->rx_ring_num; i++) {
-		mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
-		while (test_bit(NAPI_STATE_SCHED, &priv->rx_cq[i].napi.state))
+		struct mlx4_en_cq *cq = &priv->rx_cq[i];
+
+		local_bh_disable();
+		while (!mlx4_en_cq_lock_napi(cq)) {
+			pr_info("CQ %d locked\n", i);
+			mdelay(1);
+		}
+		local_bh_enable();
+
+		while (test_bit(NAPI_STATE_SCHED, &cq->napi.state))
 			msleep(1);
-		mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]);
+		mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
+		mlx4_en_deactivate_cq(priv, cq);
 	}
-
-	/* close port*/
-	mlx4_CLOSE_PORT(mdev->dev, priv->port);
 }
 
 static void mlx4_en_restart(struct work_struct *work)
@@ -2061,6 +2111,13 @@ static int mlx4_en_get_vf_config(struct
 	return mlx4_get_vf_config(mdev->dev, en_priv->port, vf, ivf);
 }
 
+static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_state)
+{
+	struct mlx4_en_priv *en_priv = netdev_priv(dev);
+	struct mlx4_en_dev *mdev = en_priv->mdev;
+
+	return mlx4_set_vf_link_state(mdev->dev, en_priv->port, vf, link_state);
+}
 static const struct net_device_ops mlx4_netdev_ops = {
 	.ndo_open		= mlx4_en_open,
 	.ndo_stop		= mlx4_en_close,
@@ -2083,6 +2140,9 @@ static const struct net_device_ops mlx4_
 #ifdef CONFIG_RFS_ACCEL
 	.ndo_rx_flow_steer	= mlx4_en_filter_rfs,
 #endif
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	.ndo_busy_poll		= mlx4_en_low_latency_recv,
+#endif
 };
 
 static const struct net_device_ops mlx4_netdev_ops_master = {
@@ -2101,6 +2161,7 @@ static const struct net_device_ops mlx4_
 	.ndo_set_vf_mac		= mlx4_en_set_vf_mac,
 	.ndo_set_vf_vlan	= mlx4_en_set_vf_vlan,
 	.ndo_set_vf_spoofchk	= mlx4_en_set_vf_spoofchk,
+	.ndo_set_vf_link_state	= mlx4_en_set_vf_link_state,
 	.ndo_get_vf_config	= mlx4_en_get_vf_config,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= mlx4_en_netpoll,
@@ -2271,6 +2332,8 @@ int mlx4_en_init_netdev(struct mlx4_en_d
 	mdev->pndev[port] = dev;
 
 	netif_carrier_off(dev);
+	mlx4_en_set_default_moderation(priv);
+
 	err = register_netdev(dev);
 	if (err) {
 		en_err(priv, "Netdev registration failed for port %d\n", port);
@@ -2302,7 +2365,6 @@ int mlx4_en_init_netdev(struct mlx4_en_d
 		en_err(priv, "Failed Initializing port\n");
 		goto out;
 	}
-	mlx4_en_set_default_moderation(priv);
 	queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
 
 	if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_rx.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_rx.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_rx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_rx.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,6 +31,7 @@
  *
  */
 
+#include <net/busy_poll.h>
 #include <linux/mlx4/cq.h>
 #include <linux/slab.h>
 #include <linux/mlx4/qp.h>
@@ -42,40 +43,64 @@
 
 #include "mlx4_en.h"
 
+static int mlx4_alloc_pages(struct mlx4_en_priv *priv,
+			    struct mlx4_en_rx_alloc *page_alloc,
+			    const struct mlx4_en_frag_info *frag_info,
+			    gfp_t _gfp)
+{
+	int order;
+	struct page *page;
+	dma_addr_t dma;
+
+	for (order = MLX4_EN_ALLOC_PREFER_ORDER; ;) {
+		gfp_t gfp = _gfp;
+
+		if (order)
+			gfp |= __GFP_COMP | __GFP_NOWARN;
+		page = alloc_pages(gfp, order);
+		if (likely(page))
+			break;
+		if (--order < 0 ||
+		    ((PAGE_SIZE << order) < frag_info->frag_size))
+			return -ENOMEM;
+	}
+	dma = dma_map_page(priv->ddev, page, 0, PAGE_SIZE << order,
+			   PCI_DMA_FROMDEVICE);
+	if (dma_mapping_error(priv->ddev, dma)) {
+		put_page(page);
+		return -ENOMEM;
+	}
+	page_alloc->size = PAGE_SIZE << order;
+	page_alloc->page = page;
+	page_alloc->dma = dma;
+	page_alloc->offset = frag_info->frag_align;
+	/* Not doing get_page() for each frag is a big win
+	 * on asymetric workloads.
+	 */
+	atomic_set(&page->_count, page_alloc->size / frag_info->frag_stride);
+	return 0;
+}
+
 static int mlx4_en_alloc_frags(struct mlx4_en_priv *priv,
 			       struct mlx4_en_rx_desc *rx_desc,
 			       struct mlx4_en_rx_alloc *frags,
-			       struct mlx4_en_rx_alloc *ring_alloc)
+			       struct mlx4_en_rx_alloc *ring_alloc,
+			       gfp_t gfp)
 {
 	struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS];
-	struct mlx4_en_frag_info *frag_info;
+	const struct mlx4_en_frag_info *frag_info;
 	struct page *page;
 	dma_addr_t dma;
 	int i;
 
 	for (i = 0; i < priv->num_frags; i++) {
 		frag_info = &priv->frag_info[i];
-		if (ring_alloc[i].offset == frag_info->last_offset) {
-			page = alloc_pages(GFP_ATOMIC | __GFP_COMP,
-					MLX4_EN_ALLOC_ORDER);
-			if (!page)
-				goto out;
-			dma = dma_map_page(priv->ddev, page, 0,
-				MLX4_EN_ALLOC_SIZE, PCI_DMA_FROMDEVICE);
-			if (dma_mapping_error(priv->ddev, dma)) {
-				put_page(page);
-				goto out;
-			}
-			page_alloc[i].page = page;
-			page_alloc[i].dma = dma;
-			page_alloc[i].offset = frag_info->frag_align;
-		} else {
-			page_alloc[i].page = ring_alloc[i].page;
-			get_page(ring_alloc[i].page);
-			page_alloc[i].dma = ring_alloc[i].dma;
-			page_alloc[i].offset = ring_alloc[i].offset +
-						frag_info->frag_stride;
-		}
+		page_alloc[i] = ring_alloc[i];
+		page_alloc[i].offset += frag_info->frag_stride;
+		if (page_alloc[i].offset + frag_info->frag_stride <= ring_alloc[i].size)
+			continue;
+		if (mlx4_alloc_pages(priv, &page_alloc[i], frag_info, gfp))
+			goto out;
 	}
 
 	for (i = 0; i < priv->num_frags; i++) {
@@ -87,14 +112,16 @@ static int mlx4_en_alloc_frags(struct ml
 
 	return 0;
 
-
 out:
 	while (i--) {
 		frag_info = &priv->frag_info[i];
-		if (ring_alloc[i].offset == frag_info->last_offset)
+		if (page_alloc[i].page != ring_alloc[i].page) {
 			dma_unmap_page(priv->ddev, page_alloc[i].dma,
-				MLX4_EN_ALLOC_SIZE, PCI_DMA_FROMDEVICE);
-		put_page(page_alloc[i].page);
+				page_alloc[i].size, PCI_DMA_FROMDEVICE);
+			page = page_alloc[i].page;
+			atomic_set(&page->_count, 1);
+			put_page(page);
+		}
 	}
 	return -ENOMEM;
 }
@@ -103,12 +130,12 @@ static void mlx4_en_free_frag(struct mlx
 			      struct mlx4_en_rx_alloc *frags,
 			      int i)
 {
-	struct mlx4_en_frag_info *frag_info = &priv->frag_info[i];
+	const struct mlx4_en_frag_info *frag_info = &priv->frag_info[i];
 
-	if (frags[i].offset == frag_info->last_offset) {
-		dma_unmap_page(priv->ddev, frags[i].dma, MLX4_EN_ALLOC_SIZE,
+	if (frags[i].offset + frag_info->frag_stride > frags[i].size)
+		dma_unmap_page(priv->ddev, frags[i].dma, frags[i].size,
 					 PCI_DMA_FROMDEVICE);
-	}
+
 	if (frags[i].page)
 		put_page(frags[i].page);
 }
@@ -116,35 +143,28 @@ static void mlx4_en_free_frag(struct mlx
 static int mlx4_en_init_allocator(struct mlx4_en_priv *priv,
 				  struct mlx4_en_rx_ring *ring)
 {
-	struct mlx4_en_rx_alloc *page_alloc;
 	int i;
+	struct mlx4_en_rx_alloc *page_alloc;
 
 	for (i = 0; i < priv->num_frags; i++) {
-		page_alloc = &ring->page_alloc[i];
-		page_alloc->page = alloc_pages(GFP_ATOMIC | __GFP_COMP,
-					       MLX4_EN_ALLOC_ORDER);
-		if (!page_alloc->page)
-			goto out;
+		const struct mlx4_en_frag_info *frag_info = &priv->frag_info[i];
 
-		page_alloc->dma = dma_map_page(priv->ddev, page_alloc->page, 0,
-					MLX4_EN_ALLOC_SIZE, PCI_DMA_FROMDEVICE);
-		if (dma_mapping_error(priv->ddev, page_alloc->dma)) {
-			put_page(page_alloc->page);
-			page_alloc->page = NULL;
+		if (mlx4_alloc_pages(priv, &ring->page_alloc[i],
+				     frag_info, GFP_KERNEL))
 			goto out;
-		}
-		page_alloc->offset = priv->frag_info[i].frag_align;
-		en_dbg(DRV, priv, "Initialized allocator:%d with page:%p\n",
-		       i, page_alloc->page);
 	}
 	return 0;
 
 out:
 	while (i--) {
+		struct page *page;
+
 		page_alloc = &ring->page_alloc[i];
 		dma_unmap_page(priv->ddev, page_alloc->dma,
-				MLX4_EN_ALLOC_SIZE, PCI_DMA_FROMDEVICE);
-		put_page(page_alloc->page);
+			       page_alloc->size, PCI_DMA_FROMDEVICE);
+		page = page_alloc->page;
+		atomic_set(&page->_count, 1);
+		put_page(page);
 		page_alloc->page = NULL;
 	}
 	return -ENOMEM;
@@ -157,13 +177,18 @@ static void mlx4_en_destroy_allocator(st
 	int i;
 
 	for (i = 0; i < priv->num_frags; i++) {
+		const struct mlx4_en_frag_info *frag_info = &priv->frag_info[i];
+
 		page_alloc = &ring->page_alloc[i];
 		en_dbg(DRV, priv, "Freeing allocator:%d count:%d\n",
 		       i, page_count(page_alloc->page));
 
 		dma_unmap_page(priv->ddev, page_alloc->dma,
-				MLX4_EN_ALLOC_SIZE, PCI_DMA_FROMDEVICE);
-		put_page(page_alloc->page);
+				page_alloc->size, PCI_DMA_FROMDEVICE);
+		while (page_alloc->offset + frag_info->frag_stride < page_alloc->size) {
+			put_page(page_alloc->page);
+			page_alloc->offset += frag_info->frag_stride;
+		}
 		page_alloc->page = NULL;
 	}
 }
@@ -194,13 +219,14 @@ static void mlx4_en_init_rx_desc(struct
 }
 
 static int mlx4_en_prepare_rx_desc(struct mlx4_en_priv *priv,
-				   struct mlx4_en_rx_ring *ring, int index)
+				   struct mlx4_en_rx_ring *ring, int index,
+				   gfp_t gfp)
 {
 	struct mlx4_en_rx_desc *rx_desc = ring->buf + (index * ring->stride);
 	struct mlx4_en_rx_alloc *frags = ring->rx_info +
 					(index << priv->log_rx_info);
 
-	return mlx4_en_alloc_frags(priv, rx_desc, frags, ring->page_alloc);
+	return mlx4_en_alloc_frags(priv, rx_desc, frags, ring->page_alloc, gfp);
 }
 
 static inline void mlx4_en_update_rx_prod_db(struct mlx4_en_rx_ring *ring)
@@ -234,7 +260,8 @@ static int mlx4_en_fill_rx_buffers(struc
 			ring = &priv->rx_ring[ring_ind];
 
 			if (mlx4_en_prepare_rx_desc(priv, ring,
-						    ring->actual_size)) {
+						    ring->actual_size,
+						    GFP_KERNEL)) {
 				if (ring->actual_size < MLX4_EN_MIN_RX_SIZE) {
 					en_err(priv, "Failed to allocate "
 						     "enough rx buffers\n");
@@ -449,11 +476,11 @@ static int mlx4_en_complete_rx_desc(stru
 					DMA_FROM_DEVICE);
 
 		/* Save page reference in skb */
-		get_page(frags[nr].page);
 		__skb_frag_set_page(&skb_frags_rx[nr], frags[nr].page);
 		skb_frag_size_set(&skb_frags_rx[nr], frag_info->frag_size);
 		skb_frags_rx[nr].page_offset = frags[nr].offset;
 		skb->truesize += frag_info->frag_stride;
+		frags[nr].page = NULL;
 	}
 	/* Adjust size of last fragment to match actual length */
 	if (nr > 0)
@@ -546,7 +573,7 @@ static void mlx4_en_refill_rx_buffers(st
 	int index = ring->prod & ring->size_mask;
 
 	while ((u32) (ring->prod - ring->cons) < ring->actual_size) {
-		if (mlx4_en_prepare_rx_desc(priv, ring, index))
+		if (mlx4_en_prepare_rx_desc(priv, ring, index, GFP_ATOMIC))
 			break;
 		ring->prod++;
 		index = ring->prod & ring->size_mask;
@@ -656,8 +683,11 @@ int mlx4_en_process_rx_cq(struct net_dev
 				 * - DIX Ethernet (type interpretation)
 				 * - TCP/IP (v4)
 				 * - without IP options
-				 * - not an IP fragment */
-				if (dev->features & NETIF_F_GRO) {
+				 * - not an IP fragment
+				 * - no LLS polling in progress
+				 */
+				if (!mlx4_en_cq_ll_polling(cq) &&
+				    (dev->features & NETIF_F_GRO)) {
 					struct sk_buff *gro_skb = napi_get_frags(&cq->napi);
 					if (!gro_skb)
 						goto next;
@@ -737,6 +767,8 @@ int mlx4_en_process_rx_cq(struct net_dev
 					       timestamp);
 		}
 
+		skb_mark_napi_id(skb, &cq->napi);
+
 		/* Push it up the stack */
 		netif_receive_skb(skb);
 
@@ -781,8 +813,13 @@ int mlx4_en_poll_rx_cq(struct napi_struc
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	int done;
 
+	if (!mlx4_en_cq_lock_napi(cq))
+		return budget;
+
 	done = mlx4_en_process_rx_cq(dev, cq, budget);
 
+	mlx4_en_cq_unlock_napi(cq);
+
 	/* If we used up all the quota - we're probably not done yet... */
 	if (done == budget)
 		INC_PERF_COUNTER(priv->pstats.napi_quota);
@@ -794,21 +831,7 @@ int mlx4_en_poll_rx_cq(struct napi_struc
 	return done;
 }
 
-
-/* Calculate the last offset position that accommodates a full fragment
- * (assuming fagment size = stride-align) */
-static int mlx4_en_last_alloc_offset(struct mlx4_en_priv *priv, u16 stride, u16 align)
-{
-	u16 res = MLX4_EN_ALLOC_SIZE % stride;
-	u16 offset = MLX4_EN_ALLOC_SIZE - stride - res + align;
-
-	en_dbg(DRV, priv, "Calculated last offset for stride:%d align:%d "
-			    "res:%d offset:%d\n", stride, align, res, offset);
-	return offset;
-}
-
-
-static int frag_sizes[] = {
+static const int frag_sizes[] = {
 	FRAG_SZ0,
 	FRAG_SZ1,
 	FRAG_SZ2,
@@ -836,9 +859,6 @@ void mlx4_en_calc_rx_buf(struct net_devi
 			priv->frag_info[i].frag_stride =
 				ALIGN(frag_sizes[i], SMP_CACHE_BYTES);
 		}
-		priv->frag_info[i].last_offset = mlx4_en_last_alloc_offset(
-						priv, priv->frag_info[i].frag_stride,
-						priv->frag_info[i].frag_align);
 		buf_size += priv->frag_info[i].frag_size;
 		i++;
 	}
@@ -850,13 +870,13 @@ void mlx4_en_calc_rx_buf(struct net_devi
 	en_dbg(DRV, priv, "Rx buffer scatter-list (effective-mtu:%d "
 		  "num_frags:%d):\n", eff_mtu, priv->num_frags);
 	for (i = 0; i < priv->num_frags; i++) {
-		en_dbg(DRV, priv, "  frag:%d - size:%d prefix:%d align:%d "
-				"stride:%d last_offset:%d\n", i,
-				priv->frag_info[i].frag_size,
-				priv->frag_info[i].frag_prefix_size,
-				priv->frag_info[i].frag_align,
-				priv->frag_info[i].frag_stride,
-				priv->frag_info[i].last_offset);
+		en_err(priv,
+		       "  frag:%d - size:%d prefix:%d align:%d stride:%d\n",
+		       i,
+		       priv->frag_info[i].frag_size,
+		       priv->frag_info[i].frag_prefix_size,
+		       priv->frag_info[i].frag_align,
+		       priv->frag_info[i].frag_stride);
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_tx.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_tx.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/en_tx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_tx.c	2013-08-25 20:43:22.000000000 -0400
@@ -544,7 +544,7 @@ u16 mlx4_en_select_queue(struct net_devi
 	if (vlan_tx_tag_present(skb))
 		up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT;
 
-	return __skb_tx_hash(dev, skb, rings_p_up) + up * rings_p_up;
+	return __netdev_pick_tx(dev, skb) % rings_p_up + up * rings_p_up;
 }
 
 static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/eq.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/eq.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/eq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/eq.c	2013-08-25 20:43:22.000000000 -0400
@@ -448,6 +448,7 @@ static int mlx4_eq_int(struct mlx4_dev *
 	int i;
 	enum slave_port_gen_event gen_event;
 	unsigned long flags;
+	struct mlx4_vport_state *s_info;
 
 	while ((eqe = next_eqe_sw(eq, dev->caps.eqe_factor))) {
 		/*
@@ -556,7 +557,9 @@ static int mlx4_eq_int(struct mlx4_dev *
 						mlx4_dbg(dev, "%s: Sending MLX4_PORT_CHANGE_SUBTYPE_DOWN"
 							 " to slave: %d, port:%d\n",
 							 __func__, i, port);
-						mlx4_slave_event(dev, i, eqe);
+						s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state;
+						if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state)
+							mlx4_slave_event(dev, i, eqe);
 					} else {  /* IB port */
 						set_and_calc_slave_port_state(dev, i, port,
 									      MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN,
@@ -580,7 +583,9 @@ static int mlx4_eq_int(struct mlx4_dev *
 					for (i = 0; i < dev->num_slaves; i++) {
 						if (i == mlx4_master_func_num(dev))
 							continue;
-						mlx4_slave_event(dev, i, eqe);
+						s_info = &priv->mfunc.master.vf_oper[slave].vport[port].state;
+						if (IFLA_VF_LINK_STATE_AUTO == s_info->link_state)
+							mlx4_slave_event(dev, i, eqe);
 					}
 				else /* IB port */
 					/* port-up event will be sent to a slave when the
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/fw.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/fw.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/fw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/fw.c	2013-08-25 20:43:22.000000000 -0400
@@ -133,7 +133,8 @@ static void dump_dev_cap_flags2(struct m
 		[4] = "Automatic MAC reassignment support",
 		[5] = "Time stamping support",
 		[6] = "VST (control vlan insertion/stripping) support",
-		[7] = "FSM (MAC anti-spoofing) support"
+		[7] = "FSM (MAC anti-spoofing) support",
+		[8] = "Dynamic QP updates support"
 	};
 	int i;
 
@@ -659,6 +660,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *
 			 QUERY_DEV_CAP_MAX_COUNTERS_OFFSET);
 
 	MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
+	if (field32 & (1 << 16))
+		dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP;
 	if (field32 & (1 << 26))
 		dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL;
 	if (field32 & (1 << 20))
@@ -830,8 +833,10 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_
 	u8 port_type;
 	u16 short_field;
 	int err;
+	int admin_link_state;
 
 #define MLX4_VF_PORT_NO_LINK_SENSE_MASK	0xE0
+#define MLX4_PORT_LINK_UP_MASK		0x80
 #define QUERY_PORT_CUR_MAX_PKEY_OFFSET	0x0c
 #define QUERY_PORT_CUR_MAX_GID_OFFSET	0x0e
 
@@ -840,16 +845,7 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_
 			   MLX4_CMD_NATIVE);
 
 	if (!err && dev->caps.function != slave) {
-		/* if config MAC in DB use it */
-		if (priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac)
-			def_mac = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac;
-		else {
-			/* set slave default_mac address */
-			MLX4_GET(def_mac, outbox->buf, QUERY_PORT_MAC_OFFSET);
-			def_mac += slave << 8;
-			priv->mfunc.master.vf_admin[slave].vport[vhcr->in_modifier].mac = def_mac;
-		}
-
+		def_mac = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac;
 		MLX4_PUT(outbox->buf, def_mac, QUERY_PORT_MAC_OFFSET);
 
 		/* get port type - currently only eth is enabled */
@@ -861,6 +857,12 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_
 		/* set port type to currently operating port type */
 		port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3);
 
+		admin_link_state = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.link_state;
+		if (IFLA_VF_LINK_STATE_ENABLE == admin_link_state)
+			port_type |= MLX4_PORT_LINK_UP_MASK;
+		else if (IFLA_VF_LINK_STATE_DISABLE == admin_link_state)
+			port_type &= ~MLX4_PORT_LINK_UP_MASK;
+
 		MLX4_PUT(outbox->buf, port_type,
 			 QUERY_PORT_SUPPORTED_TYPE_OFFSET);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -98,7 +98,7 @@ MODULE_PARM_DESC(log_num_mgm_entry_size,
 static bool enable_64b_cqe_eqe;
 module_param(enable_64b_cqe_eqe, bool, 0444);
 MODULE_PARM_DESC(enable_64b_cqe_eqe,
-		 "Enable 64 byte CQEs/EQEs when the the FW supports this");
+		 "Enable 64 byte CQEs/EQEs when the FW supports this");
 
 #define HCA_GLOBAL_CAP_MASK            0
 
@@ -371,7 +371,7 @@ static int mlx4_dev_cap(struct mlx4_dev
 
 	dev->caps.sqp_demux = (mlx4_is_master(dev)) ? MLX4_MAX_NUM_SLAVES : 0;
 
-	if (!enable_64b_cqe_eqe) {
+	if (!enable_64b_cqe_eqe && !mlx4_is_slave(dev)) {
 		if (dev_cap->flags &
 		    (MLX4_DEV_CAP_FLAG_64B_CQE | MLX4_DEV_CAP_FLAG_64B_EQE)) {
 			mlx4_warn(dev, "64B EQEs/CQEs supported by the device but not enabled\n");
@@ -842,11 +842,11 @@ static ssize_t set_port_ib_mtu(struct de
 		return -EINVAL;
 	}
 
-	err = sscanf(buf, "%d", &mtu);
-	if (err > 0)
+	err = kstrtoint(buf, 0, &mtu);
+	if (!err)
 		ibta_mtu = int_to_ibta_mtu(mtu);
 
-	if (err <= 0 || ibta_mtu < 0) {
+	if (err || ibta_mtu < 0) {
 		mlx4_err(mdev, "%s is invalid IBTA mtu\n", buf);
 		return -EINVAL;
 	}
@@ -2080,6 +2080,11 @@ static int __mlx4_init_one(struct pci_de
 		       num_vfs, MLX4_MAX_NUM_VF);
 		return -EINVAL;
 	}
+
+	if (num_vfs < 0) {
+		pr_err("num_vfs module parameter cannot be negative\n");
+		return -EINVAL;
+	}
 	/*
 	 * Check for BARs.
 	 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h	2013-08-25 20:43:22.000000000 -0400
@@ -96,13 +96,14 @@
 
 /* Use the maximum between 16384 and a single page */
 #define MLX4_EN_ALLOC_SIZE	PAGE_ALIGN(16384)
-#define MLX4_EN_ALLOC_ORDER	get_order(MLX4_EN_ALLOC_SIZE)
 
-/* Receive fragment sizes; we use at most 4 fragments (for 9600 byte MTU
+#define MLX4_EN_ALLOC_PREFER_ORDER	PAGE_ALLOC_COSTLY_ORDER
+
+/* Receive fragment sizes; we use at most 3 fragments (for 9600 byte MTU
  * and 4K allocations) */
 enum {
-	FRAG_SZ0 = 512 - NET_IP_ALIGN,
-	FRAG_SZ1 = 1024,
+	FRAG_SZ0 = 1536 - NET_IP_ALIGN,
+	FRAG_SZ1 = 4096,
 	FRAG_SZ2 = 4096,
 	FRAG_SZ3 = MLX4_EN_ALLOC_SIZE
 };
@@ -234,9 +235,10 @@ struct mlx4_en_tx_desc {
 #define MLX4_EN_CX3_HIGH_ID	0x1005
 
 struct mlx4_en_rx_alloc {
-	struct page *page;
-	dma_addr_t dma;
-	u16 offset;
+	struct page	*page;
+	dma_addr_t	dma;
+	u32		offset;
+	u32		size;
 };
 
 struct mlx4_en_tx_ring {
@@ -290,6 +292,11 @@ struct mlx4_en_rx_ring {
 	void *rx_info;
 	unsigned long bytes;
 	unsigned long packets;
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	unsigned long yields;
+	unsigned long misses;
+	unsigned long cleaned;
+#endif
 	unsigned long csum_ok;
 	unsigned long csum_none;
 	int hwtstamp_rx_filter;
@@ -310,6 +317,19 @@ struct mlx4_en_cq {
 	u16 moder_cnt;
 	struct mlx4_cqe *buf;
 #define MLX4_EN_OPCODE_ERROR	0x1e
+
+#ifdef CONFIG_NET_RX_BUSY_POLL
+	unsigned int state;
+#define MLX4_EN_CQ_STATE_IDLE        0
+#define MLX4_EN_CQ_STATE_NAPI     1    /* NAPI owns this CQ */
+#define MLX4_EN_CQ_STATE_POLL     2    /* poll owns this CQ */
+#define MLX4_CQ_LOCKED (MLX4_EN_CQ_STATE_NAPI | MLX4_EN_CQ_STATE_POLL)
+#define MLX4_EN_CQ_STATE_NAPI_YIELD  4    /* NAPI yielded this CQ */
+#define MLX4_EN_CQ_STATE_POLL_YIELD  8    /* poll yielded this CQ */
+#define CQ_YIELD (MLX4_EN_CQ_STATE_NAPI_YIELD | MLX4_EN_CQ_STATE_POLL_YIELD)
+#define CQ_USER_PEND (MLX4_EN_CQ_STATE_POLL | MLX4_EN_CQ_STATE_POLL_YIELD)
+	spinlock_t poll_lock; /* protects from LLS/napi conflicts */
+#endif  /* CONFIG_NET_RX_BUSY_POLL */
 };
 
 struct mlx4_en_port_profile {
@@ -421,8 +441,6 @@ struct mlx4_en_frag_info {
 	u16 frag_prefix_size;
 	u16 frag_stride;
 	u16 frag_align;
-	u16 last_offset;
-
 };
 
 #ifdef CONFIG_MLX4_EN_DCB
@@ -562,6 +580,115 @@ struct mlx4_mac_entry {
 	struct rcu_head rcu;
 };
 
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static inline void mlx4_en_cq_init_lock(struct mlx4_en_cq *cq)
+{
+	spin_lock_init(&cq->poll_lock);
+	cq->state = MLX4_EN_CQ_STATE_IDLE;
+}
+
+/* called from the device poll rutine to get ownership of a cq */
+static inline bool mlx4_en_cq_lock_napi(struct mlx4_en_cq *cq)
+{
+	int rc = true;
+	spin_lock(&cq->poll_lock);
+	if (cq->state & MLX4_CQ_LOCKED) {
+		WARN_ON(cq->state & MLX4_EN_CQ_STATE_NAPI);
+		cq->state |= MLX4_EN_CQ_STATE_NAPI_YIELD;
+		rc = false;
+	} else
+		/* we don't care if someone yielded */
+		cq->state = MLX4_EN_CQ_STATE_NAPI;
+	spin_unlock(&cq->poll_lock);
+	return rc;
+}
+
+/* returns true is someone tried to get the cq while napi had it */
+static inline bool mlx4_en_cq_unlock_napi(struct mlx4_en_cq *cq)
+{
+	int rc = false;
+	spin_lock(&cq->poll_lock);
+	WARN_ON(cq->state & (MLX4_EN_CQ_STATE_POLL |
+			       MLX4_EN_CQ_STATE_NAPI_YIELD));
+
+	if (cq->state & MLX4_EN_CQ_STATE_POLL_YIELD)
+		rc = true;
+	cq->state = MLX4_EN_CQ_STATE_IDLE;
+	spin_unlock(&cq->poll_lock);
+	return rc;
+}
+
+/* called from mlx4_en_low_latency_poll() */
+static inline bool mlx4_en_cq_lock_poll(struct mlx4_en_cq *cq)
+{
+	int rc = true;
+	spin_lock_bh(&cq->poll_lock);
+	if ((cq->state & MLX4_CQ_LOCKED)) {
+		struct net_device *dev = cq->dev;
+		struct mlx4_en_priv *priv = netdev_priv(dev);
+		struct mlx4_en_rx_ring *rx_ring = &priv->rx_ring[cq->ring];
+
+		cq->state |= MLX4_EN_CQ_STATE_POLL_YIELD;
+		rc = false;
+		rx_ring->yields++;
+	} else
+		/* preserve yield marks */
+		cq->state |= MLX4_EN_CQ_STATE_POLL;
+	spin_unlock_bh(&cq->poll_lock);
+	return rc;
+}
+
+/* returns true if someone tried to get the cq while it was locked */
+static inline bool mlx4_en_cq_unlock_poll(struct mlx4_en_cq *cq)
+{
+	int rc = false;
+	spin_lock_bh(&cq->poll_lock);
+	WARN_ON(cq->state & (MLX4_EN_CQ_STATE_NAPI));
+
+	if (cq->state & MLX4_EN_CQ_STATE_POLL_YIELD)
+		rc = true;
+	cq->state = MLX4_EN_CQ_STATE_IDLE;
+	spin_unlock_bh(&cq->poll_lock);
+	return rc;
+}
+
+/* true if a socket is polling, even if it did not get the lock */
+static inline bool mlx4_en_cq_ll_polling(struct mlx4_en_cq *cq)
+{
+	WARN_ON(!(cq->state & MLX4_CQ_LOCKED));
+	return cq->state & CQ_USER_PEND;
+}
+#else
+static inline void mlx4_en_cq_init_lock(struct mlx4_en_cq *cq)
+{
+}
+
+static inline bool mlx4_en_cq_lock_napi(struct mlx4_en_cq *cq)
+{
+	return true;
+}
+
+static inline bool mlx4_en_cq_unlock_napi(struct mlx4_en_cq *cq)
+{
+	return false;
+}
+
+static inline bool mlx4_en_cq_lock_poll(struct mlx4_en_cq *cq)
+{
+	return false;
+}
+
+static inline bool mlx4_en_cq_unlock_poll(struct mlx4_en_cq *cq)
+{
+	return false;
+}
+
+static inline bool mlx4_en_cq_ll_polling(struct mlx4_en_cq *cq)
+{
+	return false;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
 #define MLX4_EN_WOL_DO_MODIFY (1ULL << 63)
 
 void mlx4_en_update_loopback_state(struct net_device *dev,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4.h	2013-08-25 20:43:22.000000000 -0400
@@ -482,6 +482,7 @@ struct mlx4_vport_state {
 	u8  default_qos;
 	u32 tx_rate;
 	bool spoofchk;
+	u32 link_state;
 };
 
 struct mlx4_vf_admin_state {
@@ -570,6 +571,25 @@ struct mlx4_cmd {
 	u8			comm_toggle;
 };
 
+enum {
+	MLX4_VF_IMMED_VLAN_FLAG_VLAN = 1 << 0,
+	MLX4_VF_IMMED_VLAN_FLAG_QOS = 1 << 1,
+	MLX4_VF_IMMED_VLAN_FLAG_LINK_DISABLE = 1 << 2,
+};
+struct mlx4_vf_immed_vlan_work {
+	struct work_struct	work;
+	struct mlx4_priv	*priv;
+	int			flags;
+	int			slave;
+	int			vlan_ix;
+	int			orig_vlan_ix;
+	u8			port;
+	u8			qos;
+	u16			vlan_id;
+	u16			orig_vlan_id;
+};
+
+
 struct mlx4_uar_table {
 	struct mlx4_bitmap	bitmap;
 };
@@ -1217,4 +1237,6 @@ static inline spinlock_t *mlx4_tlock(str
 
 #define NOT_MASKED_PD_BITS 17
 
+void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work);
+
 #endif /* MLX4_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c	2013-08-25 20:43:22.000000000 -0400
@@ -101,6 +101,8 @@ struct res_qp {
 	spinlock_t		mcg_spl;
 	int			local_qpn;
 	atomic_t		ref_count;
+	u32			qpc_flags;
+	u8			sched_queue;
 };
 
 enum res_mtt_states {
@@ -355,7 +357,7 @@ static void update_gid(struct mlx4_dev *
 
 static int update_vport_qp_param(struct mlx4_dev *dev,
 				 struct mlx4_cmd_mailbox *inbox,
-				 u8 slave)
+				 u8 slave, u32 qpn)
 {
 	struct mlx4_qp_context	*qpc = inbox->buf + 8;
 	struct mlx4_vport_oper_state *vp_oper;
@@ -369,12 +371,30 @@ static int update_vport_qp_param(struct
 
 	if (MLX4_VGT != vp_oper->state.default_vlan) {
 		qp_type	= (be32_to_cpu(qpc->flags) >> 16) & 0xff;
-		if (MLX4_QP_ST_RC == qp_type)
+		if (MLX4_QP_ST_RC == qp_type ||
+		    (MLX4_QP_ST_UD == qp_type &&
+		     !mlx4_is_qp_reserved(dev, qpn)))
 			return -EINVAL;
 
+		/* the reserved QPs (special, proxy, tunnel)
+		 * do not operate over vlans
+		 */
+		if (mlx4_is_qp_reserved(dev, qpn))
+			return 0;
+
 		/* force strip vlan by clear vsd */
 		qpc->param3 &= ~cpu_to_be32(MLX4_STRIP_VLAN);
-		if (0 != vp_oper->state.default_vlan) {
+
+		if (vp_oper->state.link_state == IFLA_VF_LINK_STATE_DISABLE &&
+		    dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP) {
+			qpc->pri_path.vlan_control =
+				MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
+				MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
+				MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED |
+				MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
+				MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED |
+				MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
+		} else if (0 != vp_oper->state.default_vlan) {
 			qpc->pri_path.vlan_control =
 				MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
 				MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
@@ -2114,6 +2134,8 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4
 	if (err)
 		return err;
 	qp->local_qpn = local_qpn;
+	qp->sched_queue = 0;
+	qp->qpc_flags = be32_to_cpu(qpc->flags);
 
 	err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
 	if (err)
@@ -2836,6 +2858,9 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4
 {
 	int err;
 	struct mlx4_qp_context *qpc = inbox->buf + 8;
+	int qpn = vhcr->in_modifier & 0x7fffff;
+	struct res_qp *qp;
+	u8 orig_sched_queue;
 
 	err = verify_qp_parameters(dev, inbox, QP_TRANS_INIT2RTR, slave);
 	if (err)
@@ -2844,11 +2869,30 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4
 	update_pkey_index(dev, slave, inbox);
 	update_gid(dev, inbox, (u8)slave);
 	adjust_proxy_tun_qkey(dev, vhcr, qpc);
-	err = update_vport_qp_param(dev, inbox, slave);
+	orig_sched_queue = qpc->pri_path.sched_queue;
+	err = update_vport_qp_param(dev, inbox, slave, qpn);
 	if (err)
 		return err;
 
-	return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
+	err = get_res(dev, slave, qpn, RES_QP, &qp);
+	if (err)
+		return err;
+	if (qp->com.from_state != RES_QP_HW) {
+		err = -EBUSY;
+		goto out;
+	}
+
+	err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
+out:
+	/* if no error, save sched queue value passed in by VF. This is
+	 * essentially the QOS value provided by the VF. This will be useful
+	 * if we allow dynamic changes from VST back to VGT
+	 */
+	if (!err)
+		qp->sched_queue = orig_sched_queue;
+
+	put_res(dev, slave, qpn, RES_QP);
+	return err;
 }
 
 int mlx4_RTR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
@@ -3932,3 +3976,112 @@ void mlx4_delete_all_resources_for_slave
 	rem_slave_xrcdns(dev, slave);
 	mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
 }
+
+void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work)
+{
+	struct mlx4_vf_immed_vlan_work *work =
+		container_of(_work, struct mlx4_vf_immed_vlan_work, work);
+	struct mlx4_cmd_mailbox *mailbox;
+	struct mlx4_update_qp_context *upd_context;
+	struct mlx4_dev *dev = &work->priv->dev;
+	struct mlx4_resource_tracker *tracker =
+		&work->priv->mfunc.master.res_tracker;
+	struct list_head *qp_list =
+		&tracker->slave_list[work->slave].res_list[RES_QP];
+	struct res_qp *qp;
+	struct res_qp *tmp;
+	u64 qp_mask = ((1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_UNTAGGED) |
+		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_1P) |
+		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_TAGGED) |
+		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_UNTAGGED) |
+		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_1P) |
+		       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_TAGGED) |
+		       (1ULL << MLX4_UPD_QP_PATH_MASK_VLAN_INDEX) |
+		       (1ULL << MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE));
+
+	int err;
+	int port, errors = 0;
+	u8 vlan_control;
+
+	if (mlx4_is_slave(dev)) {
+		mlx4_warn(dev, "Trying to update-qp in slave %d\n",
+			  work->slave);
+		goto out;
+	}
+
+	mailbox = mlx4_alloc_cmd_mailbox(dev);
+	if (IS_ERR(mailbox))
+		goto out;
+	if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_LINK_DISABLE) /* block all */
+		vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
+			MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
+			MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED |
+			MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
+			MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED |
+			MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
+	else if (!work->vlan_id)
+		vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
+			MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
+	else
+		vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
+			MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
+			MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
+
+	upd_context = mailbox->buf;
+	upd_context->primary_addr_path_mask = cpu_to_be64(qp_mask);
+	upd_context->qp_context.pri_path.vlan_control = vlan_control;
+	upd_context->qp_context.pri_path.vlan_index = work->vlan_ix;
+
+	spin_lock_irq(mlx4_tlock(dev));
+	list_for_each_entry_safe(qp, tmp, qp_list, com.list) {
+		spin_unlock_irq(mlx4_tlock(dev));
+		if (qp->com.owner == work->slave) {
+			if (qp->com.from_state != RES_QP_HW ||
+			    !qp->sched_queue ||  /* no INIT2RTR trans yet */
+			    mlx4_is_qp_reserved(dev, qp->local_qpn) ||
+			    qp->qpc_flags & (1 << MLX4_RSS_QPC_FLAG_OFFSET)) {
+				spin_lock_irq(mlx4_tlock(dev));
+				continue;
+			}
+			port = (qp->sched_queue >> 6 & 1) + 1;
+			if (port != work->port) {
+				spin_lock_irq(mlx4_tlock(dev));
+				continue;
+			}
+			upd_context->qp_context.pri_path.sched_queue =
+				qp->sched_queue & 0xC7;
+			upd_context->qp_context.pri_path.sched_queue |=
+				((work->qos & 0x7) << 3);
+
+			err = mlx4_cmd(dev, mailbox->dma,
+				       qp->local_qpn & 0xffffff,
+				       0, MLX4_CMD_UPDATE_QP,
+				       MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
+			if (err) {
+				mlx4_info(dev, "UPDATE_QP failed for slave %d, "
+					  "port %d, qpn %d (%d)\n",
+					  work->slave, port, qp->local_qpn,
+					  err);
+				errors++;
+			}
+		}
+		spin_lock_irq(mlx4_tlock(dev));
+	}
+	spin_unlock_irq(mlx4_tlock(dev));
+	mlx4_free_cmd_mailbox(dev, mailbox);
+
+	if (errors)
+		mlx4_err(dev, "%d UPDATE_QP failures for slave %d, port %d\n",
+			 errors, work->slave, work->port);
+
+	/* unregister previous vlan_id if needed and we had no errors
+	 * while updating the QPs
+	 */
+	if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN && !errors &&
+	    NO_INDX != work->orig_vlan_ix)
+		__mlx4_unregister_vlan(&work->priv->dev, work->port,
+				       work->orig_vlan_ix);
+out:
+	kfree(work);
+	return;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/alloc.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/alloc.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/alloc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/alloc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/export.h>
+#include <linux/bitmap.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/mlx5/driver.h>
+
+#include "mlx5_core.h"
+
+/* Handling for queue buffers -- we allocate a bunch of memory and
+ * register it in a memory region at HCA virtual address 0.  If the
+ * requested size is > max_direct, we split the allocation into
+ * multiple pages, so we don't require too much contiguous memory.
+ */
+
+int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, int max_direct,
+		   struct mlx5_buf *buf)
+{
+	dma_addr_t t;
+
+	buf->size = size;
+	if (size <= max_direct) {
+		buf->nbufs        = 1;
+		buf->npages       = 1;
+		buf->page_shift   = get_order(size) + PAGE_SHIFT;
+		buf->direct.buf   = dma_zalloc_coherent(&dev->pdev->dev,
+							size, &t, GFP_KERNEL);
+		if (!buf->direct.buf)
+			return -ENOMEM;
+
+		buf->direct.map = t;
+
+		while (t & ((1 << buf->page_shift) - 1)) {
+			--buf->page_shift;
+			buf->npages *= 2;
+		}
+	} else {
+		int i;
+
+		buf->direct.buf  = NULL;
+		buf->nbufs       = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+		buf->npages      = buf->nbufs;
+		buf->page_shift  = PAGE_SHIFT;
+		buf->page_list   = kcalloc(buf->nbufs, sizeof(*buf->page_list),
+					   GFP_KERNEL);
+		if (!buf->page_list)
+			return -ENOMEM;
+
+		for (i = 0; i < buf->nbufs; i++) {
+			buf->page_list[i].buf =
+				dma_zalloc_coherent(&dev->pdev->dev, PAGE_SIZE,
+						    &t, GFP_KERNEL);
+			if (!buf->page_list[i].buf)
+				goto err_free;
+
+			buf->page_list[i].map = t;
+		}
+
+		if (BITS_PER_LONG == 64) {
+			struct page **pages;
+			pages = kmalloc(sizeof(*pages) * buf->nbufs, GFP_KERNEL);
+			if (!pages)
+				goto err_free;
+			for (i = 0; i < buf->nbufs; i++)
+				pages[i] = virt_to_page(buf->page_list[i].buf);
+			buf->direct.buf = vmap(pages, buf->nbufs, VM_MAP, PAGE_KERNEL);
+			kfree(pages);
+			if (!buf->direct.buf)
+				goto err_free;
+		}
+	}
+
+	return 0;
+
+err_free:
+	mlx5_buf_free(dev, buf);
+
+	return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(mlx5_buf_alloc);
+
+void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_buf *buf)
+{
+	int i;
+
+	if (buf->nbufs == 1)
+		dma_free_coherent(&dev->pdev->dev, buf->size, buf->direct.buf,
+				  buf->direct.map);
+	else {
+		if (BITS_PER_LONG == 64 && buf->direct.buf)
+			vunmap(buf->direct.buf);
+
+		for (i = 0; i < buf->nbufs; i++)
+			if (buf->page_list[i].buf)
+				dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+						  buf->page_list[i].buf,
+						  buf->page_list[i].map);
+		kfree(buf->page_list);
+	}
+}
+EXPORT_SYMBOL_GPL(mlx5_buf_free);
+
+static struct mlx5_db_pgdir *mlx5_alloc_db_pgdir(struct device *dma_device)
+{
+	struct mlx5_db_pgdir *pgdir;
+
+	pgdir = kzalloc(sizeof(*pgdir), GFP_KERNEL);
+	if (!pgdir)
+		return NULL;
+
+	bitmap_fill(pgdir->bitmap, MLX5_DB_PER_PAGE);
+	pgdir->db_page = dma_alloc_coherent(dma_device, PAGE_SIZE,
+					    &pgdir->db_dma, GFP_KERNEL);
+	if (!pgdir->db_page) {
+		kfree(pgdir);
+		return NULL;
+	}
+
+	return pgdir;
+}
+
+static int mlx5_alloc_db_from_pgdir(struct mlx5_db_pgdir *pgdir,
+				    struct mlx5_db *db)
+{
+	int offset;
+	int i;
+
+	i = find_first_bit(pgdir->bitmap, MLX5_DB_PER_PAGE);
+	if (i >= MLX5_DB_PER_PAGE)
+		return -ENOMEM;
+
+	__clear_bit(i, pgdir->bitmap);
+
+	db->u.pgdir = pgdir;
+	db->index   = i;
+	offset = db->index * L1_CACHE_BYTES;
+	db->db      = pgdir->db_page + offset / sizeof(*pgdir->db_page);
+	db->dma     = pgdir->db_dma  + offset;
+
+	return 0;
+}
+
+int mlx5_db_alloc(struct mlx5_core_dev *dev, struct mlx5_db *db)
+{
+	struct mlx5_db_pgdir *pgdir;
+	int ret = 0;
+
+	mutex_lock(&dev->priv.pgdir_mutex);
+
+	list_for_each_entry(pgdir, &dev->priv.pgdir_list, list)
+		if (!mlx5_alloc_db_from_pgdir(pgdir, db))
+			goto out;
+
+	pgdir = mlx5_alloc_db_pgdir(&(dev->pdev->dev));
+	if (!pgdir) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	list_add(&pgdir->list, &dev->priv.pgdir_list);
+
+	/* This should never fail -- we just allocated an empty page: */
+	WARN_ON(mlx5_alloc_db_from_pgdir(pgdir, db));
+
+out:
+	mutex_unlock(&dev->priv.pgdir_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mlx5_db_alloc);
+
+void mlx5_db_free(struct mlx5_core_dev *dev, struct mlx5_db *db)
+{
+	mutex_lock(&dev->priv.pgdir_mutex);
+
+	__set_bit(db->index, db->u.pgdir->bitmap);
+
+	if (bitmap_full(db->u.pgdir->bitmap, MLX5_DB_PER_PAGE)) {
+		dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
+				  db->u.pgdir->db_page, db->u.pgdir->db_dma);
+		list_del(&db->u.pgdir->list);
+		kfree(db->u.pgdir);
+	}
+
+	mutex_unlock(&dev->priv.pgdir_mutex);
+}
+EXPORT_SYMBOL_GPL(mlx5_db_free);
+
+
+void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas)
+{
+	u64 addr;
+	int i;
+
+	for (i = 0; i < buf->npages; i++) {
+		if (buf->nbufs == 1)
+			addr = buf->direct.map + (i << buf->page_shift);
+		else
+			addr = buf->page_list[i].map;
+
+		pas[i] = cpu_to_be64(addr);
+	}
+}
+EXPORT_SYMBOL_GPL(mlx5_fill_page_array);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1524 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <asm-generic/kmap_types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/io-mapping.h>
+#include <linux/mlx5/driver.h>
+#include <linux/debugfs.h>
+
+#include "mlx5_core.h"
+
+enum {
+	CMD_IF_REV = 5,
+};
+
+enum {
+	CMD_MODE_POLLING,
+	CMD_MODE_EVENTS
+};
+
+enum {
+	NUM_LONG_LISTS	  = 2,
+	NUM_MED_LISTS	  = 64,
+	LONG_LIST_SIZE	  = (2ULL * 1024 * 1024 * 1024 / PAGE_SIZE) * 8 + 16 +
+				MLX5_CMD_DATA_BLOCK_SIZE,
+	MED_LIST_SIZE	  = 16 + MLX5_CMD_DATA_BLOCK_SIZE,
+};
+
+enum {
+	MLX5_CMD_DELIVERY_STAT_OK			= 0x0,
+	MLX5_CMD_DELIVERY_STAT_SIGNAT_ERR		= 0x1,
+	MLX5_CMD_DELIVERY_STAT_TOK_ERR			= 0x2,
+	MLX5_CMD_DELIVERY_STAT_BAD_BLK_NUM_ERR		= 0x3,
+	MLX5_CMD_DELIVERY_STAT_OUT_PTR_ALIGN_ERR	= 0x4,
+	MLX5_CMD_DELIVERY_STAT_IN_PTR_ALIGN_ERR		= 0x5,
+	MLX5_CMD_DELIVERY_STAT_FW_ERR			= 0x6,
+	MLX5_CMD_DELIVERY_STAT_IN_LENGTH_ERR		= 0x7,
+	MLX5_CMD_DELIVERY_STAT_OUT_LENGTH_ERR		= 0x8,
+	MLX5_CMD_DELIVERY_STAT_RES_FLD_NOT_CLR_ERR	= 0x9,
+	MLX5_CMD_DELIVERY_STAT_CMD_DESCR_ERR		= 0x10,
+};
+
+enum {
+	MLX5_CMD_STAT_OK			= 0x0,
+	MLX5_CMD_STAT_INT_ERR			= 0x1,
+	MLX5_CMD_STAT_BAD_OP_ERR		= 0x2,
+	MLX5_CMD_STAT_BAD_PARAM_ERR		= 0x3,
+	MLX5_CMD_STAT_BAD_SYS_STATE_ERR		= 0x4,
+	MLX5_CMD_STAT_BAD_RES_ERR		= 0x5,
+	MLX5_CMD_STAT_RES_BUSY			= 0x6,
+	MLX5_CMD_STAT_LIM_ERR			= 0x8,
+	MLX5_CMD_STAT_BAD_RES_STATE_ERR		= 0x9,
+	MLX5_CMD_STAT_IX_ERR			= 0xa,
+	MLX5_CMD_STAT_NO_RES_ERR		= 0xf,
+	MLX5_CMD_STAT_BAD_INP_LEN_ERR		= 0x50,
+	MLX5_CMD_STAT_BAD_OUTP_LEN_ERR		= 0x51,
+	MLX5_CMD_STAT_BAD_QP_STATE_ERR		= 0x10,
+	MLX5_CMD_STAT_BAD_PKT_ERR		= 0x30,
+	MLX5_CMD_STAT_BAD_SIZE_OUTS_CQES_ERR	= 0x40,
+};
+
+static struct mlx5_cmd_work_ent *alloc_cmd(struct mlx5_cmd *cmd,
+					   struct mlx5_cmd_msg *in,
+					   struct mlx5_cmd_msg *out,
+					   mlx5_cmd_cbk_t cbk,
+					   void *context, int page_queue)
+{
+	gfp_t alloc_flags = cbk ? GFP_ATOMIC : GFP_KERNEL;
+	struct mlx5_cmd_work_ent *ent;
+
+	ent = kzalloc(sizeof(*ent), alloc_flags);
+	if (!ent)
+		return ERR_PTR(-ENOMEM);
+
+	ent->in		= in;
+	ent->out	= out;
+	ent->callback	= cbk;
+	ent->context	= context;
+	ent->cmd	= cmd;
+	ent->page_queue = page_queue;
+
+	return ent;
+}
+
+static u8 alloc_token(struct mlx5_cmd *cmd)
+{
+	u8 token;
+
+	spin_lock(&cmd->token_lock);
+	token = cmd->token++ % 255 + 1;
+	spin_unlock(&cmd->token_lock);
+
+	return token;
+}
+
+static int alloc_ent(struct mlx5_cmd *cmd)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&cmd->alloc_lock, flags);
+	ret = find_first_bit(&cmd->bitmask, cmd->max_reg_cmds);
+	if (ret < cmd->max_reg_cmds)
+		clear_bit(ret, &cmd->bitmask);
+	spin_unlock_irqrestore(&cmd->alloc_lock, flags);
+
+	return ret < cmd->max_reg_cmds ? ret : -ENOMEM;
+}
+
+static void free_ent(struct mlx5_cmd *cmd, int idx)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&cmd->alloc_lock, flags);
+	set_bit(idx, &cmd->bitmask);
+	spin_unlock_irqrestore(&cmd->alloc_lock, flags);
+}
+
+static struct mlx5_cmd_layout *get_inst(struct mlx5_cmd *cmd, int idx)
+{
+	return cmd->cmd_buf + (idx << cmd->log_stride);
+}
+
+static u8 xor8_buf(void *buf, int len)
+{
+	u8 *ptr = buf;
+	u8 sum = 0;
+	int i;
+
+	for (i = 0; i < len; i++)
+		sum ^= ptr[i];
+
+	return sum;
+}
+
+static int verify_block_sig(struct mlx5_cmd_prot_block *block)
+{
+	if (xor8_buf(block->rsvd0, sizeof(*block) - sizeof(block->data) - 1) != 0xff)
+		return -EINVAL;
+
+	if (xor8_buf(block, sizeof(*block)) != 0xff)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void calc_block_sig(struct mlx5_cmd_prot_block *block, u8 token)
+{
+	block->token = token;
+	block->ctrl_sig = ~xor8_buf(block->rsvd0, sizeof(*block) - sizeof(block->data) - 2);
+	block->sig = ~xor8_buf(block, sizeof(*block) - 1);
+}
+
+static void calc_chain_sig(struct mlx5_cmd_msg *msg, u8 token)
+{
+	struct mlx5_cmd_mailbox *next = msg->next;
+
+	while (next) {
+		calc_block_sig(next->buf, token);
+		next = next->next;
+	}
+}
+
+static void set_signature(struct mlx5_cmd_work_ent *ent)
+{
+	ent->lay->sig = ~xor8_buf(ent->lay, sizeof(*ent->lay));
+	calc_chain_sig(ent->in, ent->token);
+	calc_chain_sig(ent->out, ent->token);
+}
+
+static void poll_timeout(struct mlx5_cmd_work_ent *ent)
+{
+	unsigned long poll_end = jiffies + msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC + 1000);
+	u8 own;
+
+	do {
+		own = ent->lay->status_own;
+		if (!(own & CMD_OWNER_HW)) {
+			ent->ret = 0;
+			return;
+		}
+		usleep_range(5000, 10000);
+	} while (time_before(jiffies, poll_end));
+
+	ent->ret = -ETIMEDOUT;
+}
+
+static void free_cmd(struct mlx5_cmd_work_ent *ent)
+{
+	kfree(ent);
+}
+
+
+static int verify_signature(struct mlx5_cmd_work_ent *ent)
+{
+	struct mlx5_cmd_mailbox *next = ent->out->next;
+	int err;
+	u8 sig;
+
+	sig = xor8_buf(ent->lay, sizeof(*ent->lay));
+	if (sig != 0xff)
+		return -EINVAL;
+
+	while (next) {
+		err = verify_block_sig(next->buf);
+		if (err)
+			return err;
+
+		next = next->next;
+	}
+
+	return 0;
+}
+
+static void dump_buf(void *buf, int size, int data_only, int offset)
+{
+	__be32 *p = buf;
+	int i;
+
+	for (i = 0; i < size; i += 16) {
+		pr_debug("%03x: %08x %08x %08x %08x\n", offset, be32_to_cpu(p[0]),
+			 be32_to_cpu(p[1]), be32_to_cpu(p[2]),
+			 be32_to_cpu(p[3]));
+		p += 4;
+		offset += 16;
+	}
+	if (!data_only)
+		pr_debug("\n");
+}
+
+const char *mlx5_command_str(int command)
+{
+	switch (command) {
+	case MLX5_CMD_OP_QUERY_HCA_CAP:
+		return "QUERY_HCA_CAP";
+
+	case MLX5_CMD_OP_SET_HCA_CAP:
+		return "SET_HCA_CAP";
+
+	case MLX5_CMD_OP_QUERY_ADAPTER:
+		return "QUERY_ADAPTER";
+
+	case MLX5_CMD_OP_INIT_HCA:
+		return "INIT_HCA";
+
+	case MLX5_CMD_OP_TEARDOWN_HCA:
+		return "TEARDOWN_HCA";
+
+	case MLX5_CMD_OP_ENABLE_HCA:
+		return "MLX5_CMD_OP_ENABLE_HCA";
+
+	case MLX5_CMD_OP_DISABLE_HCA:
+		return "MLX5_CMD_OP_DISABLE_HCA";
+
+	case MLX5_CMD_OP_QUERY_PAGES:
+		return "QUERY_PAGES";
+
+	case MLX5_CMD_OP_MANAGE_PAGES:
+		return "MANAGE_PAGES";
+
+	case MLX5_CMD_OP_CREATE_MKEY:
+		return "CREATE_MKEY";
+
+	case MLX5_CMD_OP_QUERY_MKEY:
+		return "QUERY_MKEY";
+
+	case MLX5_CMD_OP_DESTROY_MKEY:
+		return "DESTROY_MKEY";
+
+	case MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS:
+		return "QUERY_SPECIAL_CONTEXTS";
+
+	case MLX5_CMD_OP_CREATE_EQ:
+		return "CREATE_EQ";
+
+	case MLX5_CMD_OP_DESTROY_EQ:
+		return "DESTROY_EQ";
+
+	case MLX5_CMD_OP_QUERY_EQ:
+		return "QUERY_EQ";
+
+	case MLX5_CMD_OP_CREATE_CQ:
+		return "CREATE_CQ";
+
+	case MLX5_CMD_OP_DESTROY_CQ:
+		return "DESTROY_CQ";
+
+	case MLX5_CMD_OP_QUERY_CQ:
+		return "QUERY_CQ";
+
+	case MLX5_CMD_OP_MODIFY_CQ:
+		return "MODIFY_CQ";
+
+	case MLX5_CMD_OP_CREATE_QP:
+		return "CREATE_QP";
+
+	case MLX5_CMD_OP_DESTROY_QP:
+		return "DESTROY_QP";
+
+	case MLX5_CMD_OP_RST2INIT_QP:
+		return "RST2INIT_QP";
+
+	case MLX5_CMD_OP_INIT2RTR_QP:
+		return "INIT2RTR_QP";
+
+	case MLX5_CMD_OP_RTR2RTS_QP:
+		return "RTR2RTS_QP";
+
+	case MLX5_CMD_OP_RTS2RTS_QP:
+		return "RTS2RTS_QP";
+
+	case MLX5_CMD_OP_SQERR2RTS_QP:
+		return "SQERR2RTS_QP";
+
+	case MLX5_CMD_OP_2ERR_QP:
+		return "2ERR_QP";
+
+	case MLX5_CMD_OP_RTS2SQD_QP:
+		return "RTS2SQD_QP";
+
+	case MLX5_CMD_OP_SQD2RTS_QP:
+		return "SQD2RTS_QP";
+
+	case MLX5_CMD_OP_2RST_QP:
+		return "2RST_QP";
+
+	case MLX5_CMD_OP_QUERY_QP:
+		return "QUERY_QP";
+
+	case MLX5_CMD_OP_CONF_SQP:
+		return "CONF_SQP";
+
+	case MLX5_CMD_OP_MAD_IFC:
+		return "MAD_IFC";
+
+	case MLX5_CMD_OP_INIT2INIT_QP:
+		return "INIT2INIT_QP";
+
+	case MLX5_CMD_OP_SUSPEND_QP:
+		return "SUSPEND_QP";
+
+	case MLX5_CMD_OP_UNSUSPEND_QP:
+		return "UNSUSPEND_QP";
+
+	case MLX5_CMD_OP_SQD2SQD_QP:
+		return "SQD2SQD_QP";
+
+	case MLX5_CMD_OP_ALLOC_QP_COUNTER_SET:
+		return "ALLOC_QP_COUNTER_SET";
+
+	case MLX5_CMD_OP_DEALLOC_QP_COUNTER_SET:
+		return "DEALLOC_QP_COUNTER_SET";
+
+	case MLX5_CMD_OP_QUERY_QP_COUNTER_SET:
+		return "QUERY_QP_COUNTER_SET";
+
+	case MLX5_CMD_OP_CREATE_PSV:
+		return "CREATE_PSV";
+
+	case MLX5_CMD_OP_DESTROY_PSV:
+		return "DESTROY_PSV";
+
+	case MLX5_CMD_OP_QUERY_PSV:
+		return "QUERY_PSV";
+
+	case MLX5_CMD_OP_QUERY_SIG_RULE_TABLE:
+		return "QUERY_SIG_RULE_TABLE";
+
+	case MLX5_CMD_OP_QUERY_BLOCK_SIZE_TABLE:
+		return "QUERY_BLOCK_SIZE_TABLE";
+
+	case MLX5_CMD_OP_CREATE_SRQ:
+		return "CREATE_SRQ";
+
+	case MLX5_CMD_OP_DESTROY_SRQ:
+		return "DESTROY_SRQ";
+
+	case MLX5_CMD_OP_QUERY_SRQ:
+		return "QUERY_SRQ";
+
+	case MLX5_CMD_OP_ARM_RQ:
+		return "ARM_RQ";
+
+	case MLX5_CMD_OP_RESIZE_SRQ:
+		return "RESIZE_SRQ";
+
+	case MLX5_CMD_OP_ALLOC_PD:
+		return "ALLOC_PD";
+
+	case MLX5_CMD_OP_DEALLOC_PD:
+		return "DEALLOC_PD";
+
+	case MLX5_CMD_OP_ALLOC_UAR:
+		return "ALLOC_UAR";
+
+	case MLX5_CMD_OP_DEALLOC_UAR:
+		return "DEALLOC_UAR";
+
+	case MLX5_CMD_OP_ATTACH_TO_MCG:
+		return "ATTACH_TO_MCG";
+
+	case MLX5_CMD_OP_DETACH_FROM_MCG:
+		return "DETACH_FROM_MCG";
+
+	case MLX5_CMD_OP_ALLOC_XRCD:
+		return "ALLOC_XRCD";
+
+	case MLX5_CMD_OP_DEALLOC_XRCD:
+		return "DEALLOC_XRCD";
+
+	case MLX5_CMD_OP_ACCESS_REG:
+		return "MLX5_CMD_OP_ACCESS_REG";
+
+	default: return "unknown command opcode";
+	}
+}
+
+static void dump_command(struct mlx5_core_dev *dev,
+			 struct mlx5_cmd_work_ent *ent, int input)
+{
+	u16 op = be16_to_cpu(((struct mlx5_inbox_hdr *)(ent->lay->in))->opcode);
+	struct mlx5_cmd_msg *msg = input ? ent->in : ent->out;
+	struct mlx5_cmd_mailbox *next = msg->next;
+	int data_only;
+	int offset = 0;
+	int dump_len;
+
+	data_only = !!(mlx5_core_debug_mask & (1 << MLX5_CMD_DATA));
+
+	if (data_only)
+		mlx5_core_dbg_mask(dev, 1 << MLX5_CMD_DATA,
+				   "dump command data %s(0x%x) %s\n",
+				   mlx5_command_str(op), op,
+				   input ? "INPUT" : "OUTPUT");
+	else
+		mlx5_core_dbg(dev, "dump command %s(0x%x) %s\n",
+			      mlx5_command_str(op), op,
+			      input ? "INPUT" : "OUTPUT");
+
+	if (data_only) {
+		if (input) {
+			dump_buf(ent->lay->in, sizeof(ent->lay->in), 1, offset);
+			offset += sizeof(ent->lay->in);
+		} else {
+			dump_buf(ent->lay->out, sizeof(ent->lay->out), 1, offset);
+			offset += sizeof(ent->lay->out);
+		}
+	} else {
+		dump_buf(ent->lay, sizeof(*ent->lay), 0, offset);
+		offset += sizeof(*ent->lay);
+	}
+
+	while (next && offset < msg->len) {
+		if (data_only) {
+			dump_len = min_t(int, MLX5_CMD_DATA_BLOCK_SIZE, msg->len - offset);
+			dump_buf(next->buf, dump_len, 1, offset);
+			offset += MLX5_CMD_DATA_BLOCK_SIZE;
+		} else {
+			mlx5_core_dbg(dev, "command block:\n");
+			dump_buf(next->buf, sizeof(struct mlx5_cmd_prot_block), 0, offset);
+			offset += sizeof(struct mlx5_cmd_prot_block);
+		}
+		next = next->next;
+	}
+
+	if (data_only)
+		pr_debug("\n");
+}
+
+static void cmd_work_handler(struct work_struct *work)
+{
+	struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
+	struct mlx5_cmd *cmd = ent->cmd;
+	struct mlx5_core_dev *dev = container_of(cmd, struct mlx5_core_dev, cmd);
+	struct mlx5_cmd_layout *lay;
+	struct semaphore *sem;
+
+	sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
+	down(sem);
+	if (!ent->page_queue) {
+		ent->idx = alloc_ent(cmd);
+		if (ent->idx < 0) {
+			mlx5_core_err(dev, "failed to allocate command entry\n");
+			up(sem);
+			return;
+		}
+	} else {
+		ent->idx = cmd->max_reg_cmds;
+	}
+
+	ent->token = alloc_token(cmd);
+	cmd->ent_arr[ent->idx] = ent;
+	lay = get_inst(cmd, ent->idx);
+	ent->lay = lay;
+	memset(lay, 0, sizeof(*lay));
+	memcpy(lay->in, ent->in->first.data, sizeof(lay->in));
+	if (ent->in->next)
+		lay->in_ptr = cpu_to_be64(ent->in->next->dma);
+	lay->inlen = cpu_to_be32(ent->in->len);
+	if (ent->out->next)
+		lay->out_ptr = cpu_to_be64(ent->out->next->dma);
+	lay->outlen = cpu_to_be32(ent->out->len);
+	lay->type = MLX5_PCI_CMD_XPORT;
+	lay->token = ent->token;
+	lay->status_own = CMD_OWNER_HW;
+	if (!cmd->checksum_disabled)
+		set_signature(ent);
+	dump_command(dev, ent, 1);
+	ktime_get_ts(&ent->ts1);
+
+	/* ring doorbell after the descriptor is valid */
+	wmb();
+	iowrite32be(1 << ent->idx, &dev->iseg->cmd_dbell);
+	mlx5_core_dbg(dev, "write 0x%x to command doorbell\n", 1 << ent->idx);
+	mmiowb();
+	if (cmd->mode == CMD_MODE_POLLING) {
+		poll_timeout(ent);
+		/* make sure we read the descriptor after ownership is SW */
+		rmb();
+		mlx5_cmd_comp_handler(dev, 1UL << ent->idx);
+	}
+}
+
+static const char *deliv_status_to_str(u8 status)
+{
+	switch (status) {
+	case MLX5_CMD_DELIVERY_STAT_OK:
+		return "no errors";
+	case MLX5_CMD_DELIVERY_STAT_SIGNAT_ERR:
+		return "signature error";
+	case MLX5_CMD_DELIVERY_STAT_TOK_ERR:
+		return "token error";
+	case MLX5_CMD_DELIVERY_STAT_BAD_BLK_NUM_ERR:
+		return "bad block number";
+	case MLX5_CMD_DELIVERY_STAT_OUT_PTR_ALIGN_ERR:
+		return "output pointer not aligned to block size";
+	case MLX5_CMD_DELIVERY_STAT_IN_PTR_ALIGN_ERR:
+		return "input pointer not aligned to block size";
+	case MLX5_CMD_DELIVERY_STAT_FW_ERR:
+		return "firmware internal error";
+	case MLX5_CMD_DELIVERY_STAT_IN_LENGTH_ERR:
+		return "command input length error";
+	case MLX5_CMD_DELIVERY_STAT_OUT_LENGTH_ERR:
+		return "command ouput length error";
+	case MLX5_CMD_DELIVERY_STAT_RES_FLD_NOT_CLR_ERR:
+		return "reserved fields not cleared";
+	case MLX5_CMD_DELIVERY_STAT_CMD_DESCR_ERR:
+		return "bad command descriptor type";
+	default:
+		return "unknown status code";
+	}
+}
+
+static u16 msg_to_opcode(struct mlx5_cmd_msg *in)
+{
+	struct mlx5_inbox_hdr *hdr = (struct mlx5_inbox_hdr *)(in->first.data);
+
+	return be16_to_cpu(hdr->opcode);
+}
+
+static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
+{
+	unsigned long timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC);
+	struct mlx5_cmd *cmd = &dev->cmd;
+	int err;
+
+	if (cmd->mode == CMD_MODE_POLLING) {
+		wait_for_completion(&ent->done);
+		err = ent->ret;
+	} else {
+		if (!wait_for_completion_timeout(&ent->done, timeout))
+			err = -ETIMEDOUT;
+		else
+			err = 0;
+	}
+	if (err == -ETIMEDOUT) {
+		mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n",
+			       mlx5_command_str(msg_to_opcode(ent->in)),
+			       msg_to_opcode(ent->in));
+	}
+	mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n", err,
+		      deliv_status_to_str(ent->status), ent->status);
+
+	return err;
+}
+
+/*  Notes:
+ *    1. Callback functions may not sleep
+ *    2. page queue commands do not support asynchrous completion
+ */
+static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
+			   struct mlx5_cmd_msg *out, mlx5_cmd_cbk_t callback,
+			   void *context, int page_queue, u8 *status)
+{
+	struct mlx5_cmd *cmd = &dev->cmd;
+	struct mlx5_cmd_work_ent *ent;
+	ktime_t t1, t2, delta;
+	struct mlx5_cmd_stats *stats;
+	int err = 0;
+	s64 ds;
+	u16 op;
+
+	if (callback && page_queue)
+		return -EINVAL;
+
+	ent = alloc_cmd(cmd, in, out, callback, context, page_queue);
+	if (IS_ERR(ent))
+		return PTR_ERR(ent);
+
+	if (!callback)
+		init_completion(&ent->done);
+
+	INIT_WORK(&ent->work, cmd_work_handler);
+	if (page_queue) {
+		cmd_work_handler(&ent->work);
+	} else if (!queue_work(cmd->wq, &ent->work)) {
+		mlx5_core_warn(dev, "failed to queue work\n");
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	if (!callback) {
+		err = wait_func(dev, ent);
+		if (err == -ETIMEDOUT)
+			goto out;
+
+		t1 = timespec_to_ktime(ent->ts1);
+		t2 = timespec_to_ktime(ent->ts2);
+		delta = ktime_sub(t2, t1);
+		ds = ktime_to_ns(delta);
+		op = be16_to_cpu(((struct mlx5_inbox_hdr *)in->first.data)->opcode);
+		if (op < ARRAY_SIZE(cmd->stats)) {
+			stats = &cmd->stats[op];
+			spin_lock(&stats->lock);
+			stats->sum += ds;
+			++stats->n;
+			spin_unlock(&stats->lock);
+		}
+		mlx5_core_dbg_mask(dev, 1 << MLX5_CMD_TIME,
+				   "fw exec time for %s is %lld nsec\n",
+				   mlx5_command_str(op), ds);
+		*status = ent->status;
+		free_cmd(ent);
+	}
+
+	return err;
+
+out_free:
+	free_cmd(ent);
+out:
+	return err;
+}
+
+static ssize_t dbg_write(struct file *filp, const char __user *buf,
+			 size_t count, loff_t *pos)
+{
+	struct mlx5_core_dev *dev = filp->private_data;
+	struct mlx5_cmd_debug *dbg = &dev->cmd.dbg;
+	char lbuf[3];
+	int err;
+
+	if (!dbg->in_msg || !dbg->out_msg)
+		return -ENOMEM;
+
+	if (copy_from_user(lbuf, buf, sizeof(lbuf)))
+		return -EFAULT;
+
+	lbuf[sizeof(lbuf) - 1] = 0;
+
+	if (strcmp(lbuf, "go"))
+		return -EINVAL;
+
+	err = mlx5_cmd_exec(dev, dbg->in_msg, dbg->inlen, dbg->out_msg, dbg->outlen);
+
+	return err ? err : count;
+}
+
+
+static const struct file_operations fops = {
+	.owner	= THIS_MODULE,
+	.open	= simple_open,
+	.write	= dbg_write,
+};
+
+static int mlx5_copy_to_msg(struct mlx5_cmd_msg *to, void *from, int size)
+{
+	struct mlx5_cmd_prot_block *block;
+	struct mlx5_cmd_mailbox *next;
+	int copy;
+
+	if (!to || !from)
+		return -ENOMEM;
+
+	copy = min_t(int, size, sizeof(to->first.data));
+	memcpy(to->first.data, from, copy);
+	size -= copy;
+	from += copy;
+
+	next = to->next;
+	while (size) {
+		if (!next) {
+			/* this is a BUG */
+			return -ENOMEM;
+		}
+
+		copy = min_t(int, size, MLX5_CMD_DATA_BLOCK_SIZE);
+		block = next->buf;
+		memcpy(block->data, from, copy);
+		from += copy;
+		size -= copy;
+		next = next->next;
+	}
+
+	return 0;
+}
+
+static int mlx5_copy_from_msg(void *to, struct mlx5_cmd_msg *from, int size)
+{
+	struct mlx5_cmd_prot_block *block;
+	struct mlx5_cmd_mailbox *next;
+	int copy;
+
+	if (!to || !from)
+		return -ENOMEM;
+
+	copy = min_t(int, size, sizeof(from->first.data));
+	memcpy(to, from->first.data, copy);
+	size -= copy;
+	to += copy;
+
+	next = from->next;
+	while (size) {
+		if (!next) {
+			/* this is a BUG */
+			return -ENOMEM;
+		}
+
+		copy = min_t(int, size, MLX5_CMD_DATA_BLOCK_SIZE);
+		block = next->buf;
+		if (xor8_buf(block, sizeof(*block)) != 0xff)
+			return -EINVAL;
+
+		memcpy(to, block->data, copy);
+		to += copy;
+		size -= copy;
+		next = next->next;
+	}
+
+	return 0;
+}
+
+static struct mlx5_cmd_mailbox *alloc_cmd_box(struct mlx5_core_dev *dev,
+					      gfp_t flags)
+{
+	struct mlx5_cmd_mailbox *mailbox;
+
+	mailbox = kmalloc(sizeof(*mailbox), flags);
+	if (!mailbox)
+		return ERR_PTR(-ENOMEM);
+
+	mailbox->buf = pci_pool_alloc(dev->cmd.pool, flags,
+				      &mailbox->dma);
+	if (!mailbox->buf) {
+		mlx5_core_dbg(dev, "failed allocation\n");
+		kfree(mailbox);
+		return ERR_PTR(-ENOMEM);
+	}
+	memset(mailbox->buf, 0, sizeof(struct mlx5_cmd_prot_block));
+	mailbox->next = NULL;
+
+	return mailbox;
+}
+
+static void free_cmd_box(struct mlx5_core_dev *dev,
+			 struct mlx5_cmd_mailbox *mailbox)
+{
+	pci_pool_free(dev->cmd.pool, mailbox->buf, mailbox->dma);
+	kfree(mailbox);
+}
+
+static struct mlx5_cmd_msg *mlx5_alloc_cmd_msg(struct mlx5_core_dev *dev,
+					       gfp_t flags, int size)
+{
+	struct mlx5_cmd_mailbox *tmp, *head = NULL;
+	struct mlx5_cmd_prot_block *block;
+	struct mlx5_cmd_msg *msg;
+	int blen;
+	int err;
+	int n;
+	int i;
+
+	msg = kzalloc(sizeof(*msg), GFP_KERNEL);
+	if (!msg)
+		return ERR_PTR(-ENOMEM);
+
+	blen = size - min_t(int, sizeof(msg->first.data), size);
+	n = (blen + MLX5_CMD_DATA_BLOCK_SIZE - 1) / MLX5_CMD_DATA_BLOCK_SIZE;
+
+	for (i = 0; i < n; i++) {
+		tmp = alloc_cmd_box(dev, flags);
+		if (IS_ERR(tmp)) {
+			mlx5_core_warn(dev, "failed allocating block\n");
+			err = PTR_ERR(tmp);
+			goto err_alloc;
+		}
+
+		block = tmp->buf;
+		tmp->next = head;
+		block->next = cpu_to_be64(tmp->next ? tmp->next->dma : 0);
+		block->block_num = cpu_to_be32(n - i - 1);
+		head = tmp;
+	}
+	msg->next = head;
+	msg->len = size;
+	return msg;
+
+err_alloc:
+	while (head) {
+		tmp = head->next;
+		free_cmd_box(dev, head);
+		head = tmp;
+	}
+	kfree(msg);
+
+	return ERR_PTR(err);
+}
+
+static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,
+				  struct mlx5_cmd_msg *msg)
+{
+	struct mlx5_cmd_mailbox *head = msg->next;
+	struct mlx5_cmd_mailbox *next;
+
+	while (head) {
+		next = head->next;
+		free_cmd_box(dev, head);
+		head = next;
+	}
+	kfree(msg);
+}
+
+static ssize_t data_write(struct file *filp, const char __user *buf,
+			  size_t count, loff_t *pos)
+{
+	struct mlx5_core_dev *dev = filp->private_data;
+	struct mlx5_cmd_debug *dbg = &dev->cmd.dbg;
+	void *ptr;
+	int err;
+
+	if (*pos != 0)
+		return -EINVAL;
+
+	kfree(dbg->in_msg);
+	dbg->in_msg = NULL;
+	dbg->inlen = 0;
+
+	ptr = kzalloc(count, GFP_KERNEL);
+	if (!ptr)
+		return -ENOMEM;
+
+	if (copy_from_user(ptr, buf, count)) {
+		err = -EFAULT;
+		goto out;
+	}
+	dbg->in_msg = ptr;
+	dbg->inlen = count;
+
+	*pos = count;
+
+	return count;
+
+out:
+	kfree(ptr);
+	return err;
+}
+
+static ssize_t data_read(struct file *filp, char __user *buf, size_t count,
+			 loff_t *pos)
+{
+	struct mlx5_core_dev *dev = filp->private_data;
+	struct mlx5_cmd_debug *dbg = &dev->cmd.dbg;
+	int copy;
+
+	if (*pos)
+		return 0;
+
+	if (!dbg->out_msg)
+		return -ENOMEM;
+
+	copy = min_t(int, count, dbg->outlen);
+	if (copy_to_user(buf, dbg->out_msg, copy))
+		return -EFAULT;
+
+	*pos += copy;
+
+	return copy;
+}
+
+static const struct file_operations dfops = {
+	.owner	= THIS_MODULE,
+	.open	= simple_open,
+	.write	= data_write,
+	.read	= data_read,
+};
+
+static ssize_t outlen_read(struct file *filp, char __user *buf, size_t count,
+			   loff_t *pos)
+{
+	struct mlx5_core_dev *dev = filp->private_data;
+	struct mlx5_cmd_debug *dbg = &dev->cmd.dbg;
+	char outlen[8];
+	int err;
+
+	if (*pos)
+		return 0;
+
+	err = snprintf(outlen, sizeof(outlen), "%d", dbg->outlen);
+	if (err < 0)
+		return err;
+
+	if (copy_to_user(buf, &outlen, err))
+		return -EFAULT;
+
+	*pos += err;
+
+	return err;
+}
+
+static ssize_t outlen_write(struct file *filp, const char __user *buf,
+			    size_t count, loff_t *pos)
+{
+	struct mlx5_core_dev *dev = filp->private_data;
+	struct mlx5_cmd_debug *dbg = &dev->cmd.dbg;
+	char outlen_str[8];
+	int outlen;
+	void *ptr;
+	int err;
+
+	if (*pos != 0 || count > 6)
+		return -EINVAL;
+
+	kfree(dbg->out_msg);
+	dbg->out_msg = NULL;
+	dbg->outlen = 0;
+
+	if (copy_from_user(outlen_str, buf, count))
+		return -EFAULT;
+
+	outlen_str[7] = 0;
+
+	err = sscanf(outlen_str, "%d", &outlen);
+	if (err < 0)
+		return err;
+
+	ptr = kzalloc(outlen, GFP_KERNEL);
+	if (!ptr)
+		return -ENOMEM;
+
+	dbg->out_msg = ptr;
+	dbg->outlen = outlen;
+
+	*pos = count;
+
+	return count;
+}
+
+static const struct file_operations olfops = {
+	.owner	= THIS_MODULE,
+	.open	= simple_open,
+	.write	= outlen_write,
+	.read	= outlen_read,
+};
+
+static void set_wqname(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd *cmd = &dev->cmd;
+
+	snprintf(cmd->wq_name, sizeof(cmd->wq_name), "mlx5_cmd_%s",
+		 dev_name(&dev->pdev->dev));
+}
+
+static void clean_debug_files(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd_debug *dbg = &dev->cmd.dbg;
+
+	if (!mlx5_debugfs_root)
+		return;
+
+	mlx5_cmdif_debugfs_cleanup(dev);
+	debugfs_remove_recursive(dbg->dbg_root);
+}
+
+static int create_debugfs_files(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd_debug *dbg = &dev->cmd.dbg;
+	int err = -ENOMEM;
+
+	if (!mlx5_debugfs_root)
+		return 0;
+
+	dbg->dbg_root = debugfs_create_dir("cmd", dev->priv.dbg_root);
+	if (!dbg->dbg_root)
+		return err;
+
+	dbg->dbg_in = debugfs_create_file("in", 0400, dbg->dbg_root,
+					  dev, &dfops);
+	if (!dbg->dbg_in)
+		goto err_dbg;
+
+	dbg->dbg_out = debugfs_create_file("out", 0200, dbg->dbg_root,
+					   dev, &dfops);
+	if (!dbg->dbg_out)
+		goto err_dbg;
+
+	dbg->dbg_outlen = debugfs_create_file("out_len", 0600, dbg->dbg_root,
+					      dev, &olfops);
+	if (!dbg->dbg_outlen)
+		goto err_dbg;
+
+	dbg->dbg_status = debugfs_create_u8("status", 0600, dbg->dbg_root,
+					    &dbg->status);
+	if (!dbg->dbg_status)
+		goto err_dbg;
+
+	dbg->dbg_run = debugfs_create_file("run", 0200, dbg->dbg_root, dev, &fops);
+	if (!dbg->dbg_run)
+		goto err_dbg;
+
+	mlx5_cmdif_debugfs_init(dev);
+
+	return 0;
+
+err_dbg:
+	clean_debug_files(dev);
+	return err;
+}
+
+void mlx5_cmd_use_events(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd *cmd = &dev->cmd;
+	int i;
+
+	for (i = 0; i < cmd->max_reg_cmds; i++)
+		down(&cmd->sem);
+
+	down(&cmd->pages_sem);
+
+	flush_workqueue(cmd->wq);
+
+	cmd->mode = CMD_MODE_EVENTS;
+
+	up(&cmd->pages_sem);
+	for (i = 0; i < cmd->max_reg_cmds; i++)
+		up(&cmd->sem);
+}
+
+void mlx5_cmd_use_polling(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd *cmd = &dev->cmd;
+	int i;
+
+	for (i = 0; i < cmd->max_reg_cmds; i++)
+		down(&cmd->sem);
+
+	down(&cmd->pages_sem);
+
+	flush_workqueue(cmd->wq);
+	cmd->mode = CMD_MODE_POLLING;
+
+	up(&cmd->pages_sem);
+	for (i = 0; i < cmd->max_reg_cmds; i++)
+		up(&cmd->sem);
+}
+
+void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector)
+{
+	struct mlx5_cmd *cmd = &dev->cmd;
+	struct mlx5_cmd_work_ent *ent;
+	mlx5_cmd_cbk_t callback;
+	void *context;
+	int err;
+	int i;
+
+	for (i = 0; i < (1 << cmd->log_sz); i++) {
+		if (test_bit(i, &vector)) {
+			struct semaphore *sem;
+
+			ent = cmd->ent_arr[i];
+			if (ent->page_queue)
+				sem = &cmd->pages_sem;
+			else
+				sem = &cmd->sem;
+			ktime_get_ts(&ent->ts2);
+			memcpy(ent->out->first.data, ent->lay->out, sizeof(ent->lay->out));
+			dump_command(dev, ent, 0);
+			if (!ent->ret) {
+				if (!cmd->checksum_disabled)
+					ent->ret = verify_signature(ent);
+				else
+					ent->ret = 0;
+				ent->status = ent->lay->status_own >> 1;
+				mlx5_core_dbg(dev, "command completed. ret 0x%x, delivery status %s(0x%x)\n",
+					      ent->ret, deliv_status_to_str(ent->status), ent->status);
+			}
+			free_ent(cmd, ent->idx);
+			if (ent->callback) {
+				callback = ent->callback;
+				context = ent->context;
+				err = ent->ret;
+				free_cmd(ent);
+				callback(err, context);
+			} else {
+				complete(&ent->done);
+			}
+			up(sem);
+		}
+	}
+}
+EXPORT_SYMBOL(mlx5_cmd_comp_handler);
+
+static int status_to_err(u8 status)
+{
+	return status ? -1 : 0; /* TBD more meaningful codes */
+}
+
+static struct mlx5_cmd_msg *alloc_msg(struct mlx5_core_dev *dev, int in_size)
+{
+	struct mlx5_cmd_msg *msg = ERR_PTR(-ENOMEM);
+	struct mlx5_cmd *cmd = &dev->cmd;
+	struct cache_ent *ent = NULL;
+
+	if (in_size > MED_LIST_SIZE && in_size <= LONG_LIST_SIZE)
+		ent = &cmd->cache.large;
+	else if (in_size > 16 && in_size <= MED_LIST_SIZE)
+		ent = &cmd->cache.med;
+
+	if (ent) {
+		spin_lock(&ent->lock);
+		if (!list_empty(&ent->head)) {
+			msg = list_entry(ent->head.next, typeof(*msg), list);
+			/* For cached lists, we must explicitly state what is
+			 * the real size
+			 */
+			msg->len = in_size;
+			list_del(&msg->list);
+		}
+		spin_unlock(&ent->lock);
+	}
+
+	if (IS_ERR(msg))
+		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, in_size);
+
+	return msg;
+}
+
+static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg)
+{
+	if (msg->cache) {
+		spin_lock(&msg->cache->lock);
+		list_add_tail(&msg->list, &msg->cache->head);
+		spin_unlock(&msg->cache->lock);
+	} else {
+		mlx5_free_cmd_msg(dev, msg);
+	}
+}
+
+static int is_manage_pages(struct mlx5_inbox_hdr *in)
+{
+	return be16_to_cpu(in->opcode) == MLX5_CMD_OP_MANAGE_PAGES;
+}
+
+int mlx5_cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,
+		  int out_size)
+{
+	struct mlx5_cmd_msg *inb;
+	struct mlx5_cmd_msg *outb;
+	int pages_queue;
+	int err;
+	u8 status = 0;
+
+	pages_queue = is_manage_pages(in);
+
+	inb = alloc_msg(dev, in_size);
+	if (IS_ERR(inb)) {
+		err = PTR_ERR(inb);
+		return err;
+	}
+
+	err = mlx5_copy_to_msg(inb, in, in_size);
+	if (err) {
+		mlx5_core_warn(dev, "err %d\n", err);
+		goto out_in;
+	}
+
+	outb = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, out_size);
+	if (IS_ERR(outb)) {
+		err = PTR_ERR(outb);
+		goto out_in;
+	}
+
+	err = mlx5_cmd_invoke(dev, inb, outb, NULL, NULL, pages_queue, &status);
+	if (err)
+		goto out_out;
+
+	mlx5_core_dbg(dev, "err %d, status %d\n", err, status);
+	if (status) {
+		err = status_to_err(status);
+		goto out_out;
+	}
+
+	err = mlx5_copy_from_msg(out, outb, out_size);
+
+out_out:
+	mlx5_free_cmd_msg(dev, outb);
+
+out_in:
+	free_msg(dev, inb);
+	return err;
+}
+EXPORT_SYMBOL(mlx5_cmd_exec);
+
+static void destroy_msg_cache(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd *cmd = &dev->cmd;
+	struct mlx5_cmd_msg *msg;
+	struct mlx5_cmd_msg *n;
+
+	list_for_each_entry_safe(msg, n, &cmd->cache.large.head, list) {
+		list_del(&msg->list);
+		mlx5_free_cmd_msg(dev, msg);
+	}
+
+	list_for_each_entry_safe(msg, n, &cmd->cache.med.head, list) {
+		list_del(&msg->list);
+		mlx5_free_cmd_msg(dev, msg);
+	}
+}
+
+static int create_msg_cache(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd *cmd = &dev->cmd;
+	struct mlx5_cmd_msg *msg;
+	int err;
+	int i;
+
+	spin_lock_init(&cmd->cache.large.lock);
+	INIT_LIST_HEAD(&cmd->cache.large.head);
+	spin_lock_init(&cmd->cache.med.lock);
+	INIT_LIST_HEAD(&cmd->cache.med.head);
+
+	for (i = 0; i < NUM_LONG_LISTS; i++) {
+		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, LONG_LIST_SIZE);
+		if (IS_ERR(msg)) {
+			err = PTR_ERR(msg);
+			goto ex_err;
+		}
+		msg->cache = &cmd->cache.large;
+		list_add_tail(&msg->list, &cmd->cache.large.head);
+	}
+
+	for (i = 0; i < NUM_MED_LISTS; i++) {
+		msg = mlx5_alloc_cmd_msg(dev, GFP_KERNEL, MED_LIST_SIZE);
+		if (IS_ERR(msg)) {
+			err = PTR_ERR(msg);
+			goto ex_err;
+		}
+		msg->cache = &cmd->cache.med;
+		list_add_tail(&msg->list, &cmd->cache.med.head);
+	}
+
+	return 0;
+
+ex_err:
+	destroy_msg_cache(dev);
+	return err;
+}
+
+int mlx5_cmd_init(struct mlx5_core_dev *dev)
+{
+	int size = sizeof(struct mlx5_cmd_prot_block);
+	int align = roundup_pow_of_two(size);
+	struct mlx5_cmd *cmd = &dev->cmd;
+	u32 cmd_h, cmd_l;
+	u16 cmd_if_rev;
+	int err;
+	int i;
+
+	cmd_if_rev = cmdif_rev(dev);
+	if (cmd_if_rev != CMD_IF_REV) {
+		dev_err(&dev->pdev->dev,
+			"Driver cmdif rev(%d) differs from firmware's(%d)\n",
+			CMD_IF_REV, cmd_if_rev);
+		return -EINVAL;
+	}
+
+	cmd->pool = pci_pool_create("mlx5_cmd", dev->pdev, size, align, 0);
+	if (!cmd->pool)
+		return -ENOMEM;
+
+	cmd->cmd_buf = (void *)__get_free_pages(GFP_ATOMIC, 0);
+	if (!cmd->cmd_buf) {
+		err = -ENOMEM;
+		goto err_free_pool;
+	}
+	cmd->dma = dma_map_single(&dev->pdev->dev, cmd->cmd_buf, PAGE_SIZE,
+				  DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(&dev->pdev->dev, cmd->dma)) {
+		err = -ENOMEM;
+		goto err_free;
+	}
+
+	cmd_l = ioread32be(&dev->iseg->cmdq_addr_l_sz) & 0xff;
+	cmd->log_sz = cmd_l >> 4 & 0xf;
+	cmd->log_stride = cmd_l & 0xf;
+	if (1 << cmd->log_sz > MLX5_MAX_COMMANDS) {
+		dev_err(&dev->pdev->dev, "firmware reports too many outstanding commands %d\n",
+			1 << cmd->log_sz);
+		err = -EINVAL;
+		goto err_map;
+	}
+
+	if (cmd->log_sz + cmd->log_stride > PAGE_SHIFT) {
+		dev_err(&dev->pdev->dev, "command queue size overflow\n");
+		err = -EINVAL;
+		goto err_map;
+	}
+
+	cmd->max_reg_cmds = (1 << cmd->log_sz) - 1;
+	cmd->bitmask = (1 << cmd->max_reg_cmds) - 1;
+
+	cmd->cmdif_rev = ioread32be(&dev->iseg->cmdif_rev_fw_sub) >> 16;
+	if (cmd->cmdif_rev > CMD_IF_REV) {
+		dev_err(&dev->pdev->dev, "driver does not support command interface version. driver %d, firmware %d\n",
+			CMD_IF_REV, cmd->cmdif_rev);
+		err = -ENOTSUPP;
+		goto err_map;
+	}
+
+	spin_lock_init(&cmd->alloc_lock);
+	spin_lock_init(&cmd->token_lock);
+	for (i = 0; i < ARRAY_SIZE(cmd->stats); i++)
+		spin_lock_init(&cmd->stats[i].lock);
+
+	sema_init(&cmd->sem, cmd->max_reg_cmds);
+	sema_init(&cmd->pages_sem, 1);
+
+	cmd_h = (u32)((u64)(cmd->dma) >> 32);
+	cmd_l = (u32)(cmd->dma);
+	if (cmd_l & 0xfff) {
+		dev_err(&dev->pdev->dev, "invalid command queue address\n");
+		err = -ENOMEM;
+		goto err_map;
+	}
+
+	iowrite32be(cmd_h, &dev->iseg->cmdq_addr_h);
+	iowrite32be(cmd_l, &dev->iseg->cmdq_addr_l_sz);
+
+	/* Make sure firmware sees the complete address before we proceed */
+	wmb();
+
+	mlx5_core_dbg(dev, "descriptor at dma 0x%llx\n", (unsigned long long)(cmd->dma));
+
+	cmd->mode = CMD_MODE_POLLING;
+
+	err = create_msg_cache(dev);
+	if (err) {
+		dev_err(&dev->pdev->dev, "failed to create command cache\n");
+		goto err_map;
+	}
+
+	set_wqname(dev);
+	cmd->wq = create_singlethread_workqueue(cmd->wq_name);
+	if (!cmd->wq) {
+		dev_err(&dev->pdev->dev, "failed to create command workqueue\n");
+		err = -ENOMEM;
+		goto err_cache;
+	}
+
+	err = create_debugfs_files(dev);
+	if (err) {
+		err = -ENOMEM;
+		goto err_wq;
+	}
+
+	return 0;
+
+err_wq:
+	destroy_workqueue(cmd->wq);
+
+err_cache:
+	destroy_msg_cache(dev);
+
+err_map:
+	dma_unmap_single(&dev->pdev->dev, cmd->dma, PAGE_SIZE,
+			 DMA_BIDIRECTIONAL);
+err_free:
+	free_pages((unsigned long)cmd->cmd_buf, 0);
+
+err_free_pool:
+	pci_pool_destroy(cmd->pool);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_cmd_init);
+
+void mlx5_cmd_cleanup(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd *cmd = &dev->cmd;
+
+	clean_debug_files(dev);
+	destroy_workqueue(cmd->wq);
+	destroy_msg_cache(dev);
+	dma_unmap_single(&dev->pdev->dev, cmd->dma, PAGE_SIZE,
+			 DMA_BIDIRECTIONAL);
+	free_pages((unsigned long)cmd->cmd_buf, 0);
+	pci_pool_destroy(cmd->pool);
+}
+EXPORT_SYMBOL(mlx5_cmd_cleanup);
+
+static const char *cmd_status_str(u8 status)
+{
+	switch (status) {
+	case MLX5_CMD_STAT_OK:
+		return "OK";
+	case MLX5_CMD_STAT_INT_ERR:
+		return "internal error";
+	case MLX5_CMD_STAT_BAD_OP_ERR:
+		return "bad operation";
+	case MLX5_CMD_STAT_BAD_PARAM_ERR:
+		return "bad parameter";
+	case MLX5_CMD_STAT_BAD_SYS_STATE_ERR:
+		return "bad system state";
+	case MLX5_CMD_STAT_BAD_RES_ERR:
+		return "bad resource";
+	case MLX5_CMD_STAT_RES_BUSY:
+		return "resource busy";
+	case MLX5_CMD_STAT_LIM_ERR:
+		return "limits exceeded";
+	case MLX5_CMD_STAT_BAD_RES_STATE_ERR:
+		return "bad resource state";
+	case MLX5_CMD_STAT_IX_ERR:
+		return "bad index";
+	case MLX5_CMD_STAT_NO_RES_ERR:
+		return "no resources";
+	case MLX5_CMD_STAT_BAD_INP_LEN_ERR:
+		return "bad input length";
+	case MLX5_CMD_STAT_BAD_OUTP_LEN_ERR:
+		return "bad output length";
+	case MLX5_CMD_STAT_BAD_QP_STATE_ERR:
+		return "bad QP state";
+	case MLX5_CMD_STAT_BAD_PKT_ERR:
+		return "bad packet (discarded)";
+	case MLX5_CMD_STAT_BAD_SIZE_OUTS_CQES_ERR:
+		return "bad size too many outstanding CQEs";
+	default:
+		return "unknown status";
+	}
+}
+
+int mlx5_cmd_status_to_err(struct mlx5_outbox_hdr *hdr)
+{
+	if (!hdr->status)
+		return 0;
+
+	pr_warn("command failed, status %s(0x%x), syndrome 0x%x\n",
+		cmd_status_str(hdr->status), hdr->status,
+		be32_to_cpu(hdr->syndrome));
+
+	switch (hdr->status) {
+	case MLX5_CMD_STAT_OK:				return 0;
+	case MLX5_CMD_STAT_INT_ERR:			return -EIO;
+	case MLX5_CMD_STAT_BAD_OP_ERR:			return -EINVAL;
+	case MLX5_CMD_STAT_BAD_PARAM_ERR:		return -EINVAL;
+	case MLX5_CMD_STAT_BAD_SYS_STATE_ERR:		return -EIO;
+	case MLX5_CMD_STAT_BAD_RES_ERR:			return -EINVAL;
+	case MLX5_CMD_STAT_RES_BUSY:			return -EBUSY;
+	case MLX5_CMD_STAT_LIM_ERR:			return -EINVAL;
+	case MLX5_CMD_STAT_BAD_RES_STATE_ERR:		return -EINVAL;
+	case MLX5_CMD_STAT_IX_ERR:			return -EINVAL;
+	case MLX5_CMD_STAT_NO_RES_ERR:			return -EAGAIN;
+	case MLX5_CMD_STAT_BAD_INP_LEN_ERR:		return -EIO;
+	case MLX5_CMD_STAT_BAD_OUTP_LEN_ERR:		return -EIO;
+	case MLX5_CMD_STAT_BAD_QP_STATE_ERR:		return -EINVAL;
+	case MLX5_CMD_STAT_BAD_PKT_ERR:			return -EINVAL;
+	case MLX5_CMD_STAT_BAD_SIZE_OUTS_CQES_ERR:	return -EINVAL;
+	default:					return -EIO;
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/cq.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/cq.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/cq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/cq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/hardirq.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include <rdma/ib_verbs.h>
+#include <linux/mlx5/cq.h>
+#include "mlx5_core.h"
+
+void mlx5_cq_completion(struct mlx5_core_dev *dev, u32 cqn)
+{
+	struct mlx5_core_cq *cq;
+	struct mlx5_cq_table *table = &dev->priv.cq_table;
+
+	spin_lock(&table->lock);
+	cq = radix_tree_lookup(&table->tree, cqn);
+	if (likely(cq))
+		atomic_inc(&cq->refcount);
+	spin_unlock(&table->lock);
+
+	if (!cq) {
+		mlx5_core_warn(dev, "Completion event for bogus CQ 0x%x\n", cqn);
+		return;
+	}
+
+	++cq->arm_sn;
+
+	cq->comp(cq);
+
+	if (atomic_dec_and_test(&cq->refcount))
+		complete(&cq->free);
+}
+
+void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type)
+{
+	struct mlx5_cq_table *table = &dev->priv.cq_table;
+	struct mlx5_core_cq *cq;
+
+	spin_lock(&table->lock);
+
+	cq = radix_tree_lookup(&table->tree, cqn);
+	if (cq)
+		atomic_inc(&cq->refcount);
+
+	spin_unlock(&table->lock);
+
+	if (!cq) {
+		mlx5_core_warn(dev, "Async event for bogus CQ 0x%x\n", cqn);
+		return;
+	}
+
+	cq->event(cq, event_type);
+
+	if (atomic_dec_and_test(&cq->refcount))
+		complete(&cq->free);
+}
+
+
+int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+			struct mlx5_create_cq_mbox_in *in, int inlen)
+{
+	int err;
+	struct mlx5_cq_table *table = &dev->priv.cq_table;
+	struct mlx5_create_cq_mbox_out out;
+	struct mlx5_destroy_cq_mbox_in din;
+	struct mlx5_destroy_cq_mbox_out dout;
+
+	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_CQ);
+	memset(&out, 0, sizeof(out));
+	err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	cq->cqn = be32_to_cpu(out.cqn) & 0xffffff;
+	cq->cons_index = 0;
+	cq->arm_sn     = 0;
+	atomic_set(&cq->refcount, 1);
+	init_completion(&cq->free);
+
+	spin_lock_irq(&table->lock);
+	err = radix_tree_insert(&table->tree, cq->cqn, cq);
+	spin_unlock_irq(&table->lock);
+	if (err)
+		goto err_cmd;
+
+	cq->pid = current->pid;
+	err = mlx5_debug_cq_add(dev, cq);
+	if (err)
+		mlx5_core_dbg(dev, "failed adding CP 0x%x to debug file system\n",
+			      cq->cqn);
+
+	return 0;
+
+err_cmd:
+	memset(&din, 0, sizeof(din));
+	memset(&dout, 0, sizeof(dout));
+	din.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_CQ);
+	mlx5_cmd_exec(dev, &din, sizeof(din), &dout, sizeof(dout));
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_create_cq);
+
+int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
+{
+	struct mlx5_cq_table *table = &dev->priv.cq_table;
+	struct mlx5_destroy_cq_mbox_in in;
+	struct mlx5_destroy_cq_mbox_out out;
+	struct mlx5_core_cq *tmp;
+	int err;
+
+	spin_lock_irq(&table->lock);
+	tmp = radix_tree_delete(&table->tree, cq->cqn);
+	spin_unlock_irq(&table->lock);
+	if (!tmp) {
+		mlx5_core_warn(dev, "cq 0x%x not found in tree\n", cq->cqn);
+		return -EINVAL;
+	}
+	if (tmp != cq) {
+		mlx5_core_warn(dev, "corruption on srqn 0x%x\n", cq->cqn);
+		return -EINVAL;
+	}
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_CQ);
+	in.cqn = cpu_to_be32(cq->cqn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	synchronize_irq(cq->irqn);
+
+	mlx5_debug_cq_remove(dev, cq);
+	if (atomic_dec_and_test(&cq->refcount))
+		complete(&cq->free);
+	wait_for_completion(&cq->free);
+
+	return 0;
+}
+EXPORT_SYMBOL(mlx5_core_destroy_cq);
+
+int mlx5_core_query_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+		       struct mlx5_query_cq_mbox_out *out)
+{
+	struct mlx5_query_cq_mbox_in in;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(out, 0, sizeof(*out));
+
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_CQ);
+	in.cqn = cpu_to_be32(cq->cqn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out));
+	if (err)
+		return err;
+
+	if (out->hdr.status)
+		return mlx5_cmd_status_to_err(&out->hdr);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_query_cq);
+
+
+int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+			int type, struct mlx5_cq_modify_params *params)
+{
+	return -ENOSYS;
+}
+
+int mlx5_init_cq_table(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cq_table *table = &dev->priv.cq_table;
+	int err;
+
+	spin_lock_init(&table->lock);
+	INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
+	err = mlx5_cq_debugfs_init(dev);
+
+	return err;
+}
+
+void mlx5_cleanup_cq_table(struct mlx5_core_dev *dev)
+{
+	mlx5_cq_debugfs_cleanup(dev);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/mlx5/qp.h>
+#include <linux/mlx5/cq.h>
+#include <linux/mlx5/driver.h>
+#include "mlx5_core.h"
+
+enum {
+	QP_PID,
+	QP_STATE,
+	QP_XPORT,
+	QP_MTU,
+	QP_N_RECV,
+	QP_RECV_SZ,
+	QP_N_SEND,
+	QP_LOG_PG_SZ,
+	QP_RQPN,
+};
+
+static char *qp_fields[] = {
+	[QP_PID]	= "pid",
+	[QP_STATE]	= "state",
+	[QP_XPORT]	= "transport",
+	[QP_MTU]	= "mtu",
+	[QP_N_RECV]	= "num_recv",
+	[QP_RECV_SZ]	= "rcv_wqe_sz",
+	[QP_N_SEND]	= "num_send",
+	[QP_LOG_PG_SZ]	= "log2_page_sz",
+	[QP_RQPN]	= "remote_qpn",
+};
+
+enum {
+	EQ_NUM_EQES,
+	EQ_INTR,
+	EQ_LOG_PG_SZ,
+};
+
+static char *eq_fields[] = {
+	[EQ_NUM_EQES]	= "num_eqes",
+	[EQ_INTR]	= "intr",
+	[EQ_LOG_PG_SZ]	= "log_page_size",
+};
+
+enum {
+	CQ_PID,
+	CQ_NUM_CQES,
+	CQ_LOG_PG_SZ,
+};
+
+static char *cq_fields[] = {
+	[CQ_PID]	= "pid",
+	[CQ_NUM_CQES]	= "num_cqes",
+	[CQ_LOG_PG_SZ]	= "log_page_size",
+};
+
+struct dentry *mlx5_debugfs_root;
+EXPORT_SYMBOL(mlx5_debugfs_root);
+
+void mlx5_register_debugfs(void)
+{
+	mlx5_debugfs_root = debugfs_create_dir("mlx5", NULL);
+	if (IS_ERR_OR_NULL(mlx5_debugfs_root))
+		mlx5_debugfs_root = NULL;
+}
+
+void mlx5_unregister_debugfs(void)
+{
+	debugfs_remove(mlx5_debugfs_root);
+}
+
+int mlx5_qp_debugfs_init(struct mlx5_core_dev *dev)
+{
+	if (!mlx5_debugfs_root)
+		return 0;
+
+	atomic_set(&dev->num_qps, 0);
+
+	dev->priv.qp_debugfs = debugfs_create_dir("QPs",  dev->priv.dbg_root);
+	if (!dev->priv.qp_debugfs)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void mlx5_qp_debugfs_cleanup(struct mlx5_core_dev *dev)
+{
+	if (!mlx5_debugfs_root)
+		return;
+
+	debugfs_remove_recursive(dev->priv.qp_debugfs);
+}
+
+int mlx5_eq_debugfs_init(struct mlx5_core_dev *dev)
+{
+	if (!mlx5_debugfs_root)
+		return 0;
+
+	dev->priv.eq_debugfs = debugfs_create_dir("EQs",  dev->priv.dbg_root);
+	if (!dev->priv.eq_debugfs)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void mlx5_eq_debugfs_cleanup(struct mlx5_core_dev *dev)
+{
+	if (!mlx5_debugfs_root)
+		return;
+
+	debugfs_remove_recursive(dev->priv.eq_debugfs);
+}
+
+static ssize_t average_read(struct file *filp, char __user *buf, size_t count,
+			    loff_t *pos)
+{
+	struct mlx5_cmd_stats *stats;
+	u64 field = 0;
+	int ret;
+	char tbuf[22];
+
+	if (*pos)
+		return 0;
+
+	stats = filp->private_data;
+	spin_lock(&stats->lock);
+	if (stats->n)
+		field = div64_u64(stats->sum, stats->n);
+	spin_unlock(&stats->lock);
+	ret = snprintf(tbuf, sizeof(tbuf), "%llu\n", field);
+	if (ret > 0) {
+		if (copy_to_user(buf, tbuf, ret))
+			return -EFAULT;
+	}
+
+	*pos += ret;
+	return ret;
+}
+
+
+static ssize_t average_write(struct file *filp, const char __user *buf,
+			     size_t count, loff_t *pos)
+{
+	struct mlx5_cmd_stats *stats;
+
+	stats = filp->private_data;
+	spin_lock(&stats->lock);
+	stats->sum = 0;
+	stats->n = 0;
+	spin_unlock(&stats->lock);
+
+	*pos += count;
+
+	return count;
+}
+
+static const struct file_operations stats_fops = {
+	.owner	= THIS_MODULE,
+	.open	= simple_open,
+	.read	= average_read,
+	.write	= average_write,
+};
+
+int mlx5_cmdif_debugfs_init(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd_stats *stats;
+	struct dentry **cmd;
+	const char *namep;
+	int err;
+	int i;
+
+	if (!mlx5_debugfs_root)
+		return 0;
+
+	cmd = &dev->priv.cmdif_debugfs;
+	*cmd = debugfs_create_dir("commands", dev->priv.dbg_root);
+	if (!*cmd)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(dev->cmd.stats); i++) {
+		stats = &dev->cmd.stats[i];
+		namep = mlx5_command_str(i);
+		if (strcmp(namep, "unknown command opcode")) {
+			stats->root = debugfs_create_dir(namep, *cmd);
+			if (!stats->root) {
+				mlx5_core_warn(dev, "failed adding command %d\n",
+					       i);
+				err = -ENOMEM;
+				goto out;
+			}
+
+			stats->avg = debugfs_create_file("average", 0400,
+							 stats->root, stats,
+							 &stats_fops);
+			if (!stats->avg) {
+				mlx5_core_warn(dev, "failed creating debugfs file\n");
+				err = -ENOMEM;
+				goto out;
+			}
+
+			stats->count = debugfs_create_u64("n", 0400,
+							  stats->root,
+							  &stats->n);
+			if (!stats->count) {
+				mlx5_core_warn(dev, "failed creating debugfs file\n");
+				err = -ENOMEM;
+				goto out;
+			}
+		}
+	}
+
+	return 0;
+out:
+	debugfs_remove_recursive(dev->priv.cmdif_debugfs);
+	return err;
+}
+
+void mlx5_cmdif_debugfs_cleanup(struct mlx5_core_dev *dev)
+{
+	if (!mlx5_debugfs_root)
+		return;
+
+	debugfs_remove_recursive(dev->priv.cmdif_debugfs);
+}
+
+int mlx5_cq_debugfs_init(struct mlx5_core_dev *dev)
+{
+	if (!mlx5_debugfs_root)
+		return 0;
+
+	dev->priv.cq_debugfs = debugfs_create_dir("CQs",  dev->priv.dbg_root);
+	if (!dev->priv.cq_debugfs)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev)
+{
+	if (!mlx5_debugfs_root)
+		return;
+
+	debugfs_remove_recursive(dev->priv.cq_debugfs);
+}
+
+static u64 qp_read_field(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
+			 int index)
+{
+	struct mlx5_query_qp_mbox_out *out;
+	struct mlx5_qp_context *ctx;
+	u64 param = 0;
+	int err;
+	int no_sq;
+
+	out = kzalloc(sizeof(*out), GFP_KERNEL);
+	if (!out)
+		return param;
+
+	err = mlx5_core_qp_query(dev, qp, out, sizeof(*out));
+	if (err) {
+		mlx5_core_warn(dev, "failed to query qp\n");
+		goto out;
+	}
+
+	ctx = &out->ctx;
+	switch (index) {
+	case QP_PID:
+		param = qp->pid;
+		break;
+	case QP_STATE:
+		param = be32_to_cpu(ctx->flags) >> 28;
+		break;
+	case QP_XPORT:
+		param = (be32_to_cpu(ctx->flags) >> 16) & 0xff;
+		break;
+	case QP_MTU:
+		param = ctx->mtu_msgmax >> 5;
+		break;
+	case QP_N_RECV:
+		param = 1 << ((ctx->rq_size_stride >> 3) & 0xf);
+		break;
+	case QP_RECV_SZ:
+		param = 1 << ((ctx->rq_size_stride & 7) + 4);
+		break;
+	case QP_N_SEND:
+		no_sq = be16_to_cpu(ctx->sq_crq_size) >> 15;
+		if (!no_sq)
+			param = 1 << (be16_to_cpu(ctx->sq_crq_size) >> 11);
+		else
+			param = 0;
+		break;
+	case QP_LOG_PG_SZ:
+		param = (be32_to_cpu(ctx->log_pg_sz_remote_qpn) >> 24) & 0x1f;
+		param += 12;
+		break;
+	case QP_RQPN:
+		param = be32_to_cpu(ctx->log_pg_sz_remote_qpn) & 0xffffff;
+		break;
+	}
+
+out:
+	kfree(out);
+	return param;
+}
+
+static u64 eq_read_field(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
+			 int index)
+{
+	struct mlx5_query_eq_mbox_out *out;
+	struct mlx5_eq_context *ctx;
+	u64 param = 0;
+	int err;
+
+	out = kzalloc(sizeof(*out), GFP_KERNEL);
+	if (!out)
+		return param;
+
+	ctx = &out->ctx;
+
+	err = mlx5_core_eq_query(dev, eq, out, sizeof(*out));
+	if (err) {
+		mlx5_core_warn(dev, "failed to query eq\n");
+		goto out;
+	}
+
+	switch (index) {
+	case EQ_NUM_EQES:
+		param = 1 << ((be32_to_cpu(ctx->log_sz_usr_page) >> 24) & 0x1f);
+		break;
+	case EQ_INTR:
+		param = ctx->intr;
+		break;
+	case EQ_LOG_PG_SZ:
+		param = (ctx->log_page_size & 0x1f) + 12;
+		break;
+	}
+
+out:
+	kfree(out);
+	return param;
+}
+
+static u64 cq_read_field(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
+			 int index)
+{
+	struct mlx5_query_cq_mbox_out *out;
+	struct mlx5_cq_context *ctx;
+	u64 param = 0;
+	int err;
+
+	out = kzalloc(sizeof(*out), GFP_KERNEL);
+	if (!out)
+		return param;
+
+	ctx = &out->ctx;
+
+	err = mlx5_core_query_cq(dev, cq, out);
+	if (err) {
+		mlx5_core_warn(dev, "failed to query cq\n");
+		goto out;
+	}
+
+	switch (index) {
+	case CQ_PID:
+		param = cq->pid;
+		break;
+	case CQ_NUM_CQES:
+		param = 1 << ((be32_to_cpu(ctx->log_sz_usr_page) >> 24) & 0x1f);
+		break;
+	case CQ_LOG_PG_SZ:
+		param = (ctx->log_pg_sz & 0x1f) + 12;
+		break;
+	}
+
+out:
+	kfree(out);
+	return param;
+}
+
+static ssize_t dbg_read(struct file *filp, char __user *buf, size_t count,
+			loff_t *pos)
+{
+	struct mlx5_field_desc *desc;
+	struct mlx5_rsc_debug *d;
+	char tbuf[18];
+	u64 field;
+	int ret;
+
+	if (*pos)
+		return 0;
+
+	desc = filp->private_data;
+	d = (void *)(desc - desc->i) - sizeof(*d);
+	switch (d->type) {
+	case MLX5_DBG_RSC_QP:
+		field = qp_read_field(d->dev, d->object, desc->i);
+		break;
+
+	case MLX5_DBG_RSC_EQ:
+		field = eq_read_field(d->dev, d->object, desc->i);
+		break;
+
+	case MLX5_DBG_RSC_CQ:
+		field = cq_read_field(d->dev, d->object, desc->i);
+		break;
+
+	default:
+		mlx5_core_warn(d->dev, "invalid resource type %d\n", d->type);
+		return -EINVAL;
+	}
+
+	ret = snprintf(tbuf, sizeof(tbuf), "0x%llx\n", field);
+	if (ret > 0) {
+		if (copy_to_user(buf, tbuf, ret))
+			return -EFAULT;
+	}
+
+	*pos += ret;
+	return ret;
+}
+
+static const struct file_operations fops = {
+	.owner	= THIS_MODULE,
+	.open	= simple_open,
+	.read	= dbg_read,
+};
+
+static int add_res_tree(struct mlx5_core_dev *dev, enum dbg_rsc_type type,
+			struct dentry *root, struct mlx5_rsc_debug **dbg,
+			int rsn, char **field, int nfile, void *data)
+{
+	struct mlx5_rsc_debug *d;
+	char resn[32];
+	int err;
+	int i;
+
+	d = kzalloc(sizeof(*d) + nfile * sizeof(d->fields[0]), GFP_KERNEL);
+	if (!d)
+		return -ENOMEM;
+
+	d->dev = dev;
+	d->object = data;
+	d->type = type;
+	sprintf(resn, "0x%x", rsn);
+	d->root = debugfs_create_dir(resn,  root);
+	if (!d->root) {
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	for (i = 0; i < nfile; i++) {
+		d->fields[i].i = i;
+		d->fields[i].dent = debugfs_create_file(field[i], 0400,
+							d->root, &d->fields[i],
+							&fops);
+		if (!d->fields[i].dent) {
+			err = -ENOMEM;
+			goto out_rem;
+		}
+	}
+	*dbg = d;
+
+	return 0;
+out_rem:
+	debugfs_remove_recursive(d->root);
+
+out_free:
+	kfree(d);
+	return err;
+}
+
+static void rem_res_tree(struct mlx5_rsc_debug *d)
+{
+	debugfs_remove_recursive(d->root);
+	kfree(d);
+}
+
+int mlx5_debug_qp_add(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp)
+{
+	int err;
+
+	if (!mlx5_debugfs_root)
+		return 0;
+
+	err = add_res_tree(dev, MLX5_DBG_RSC_QP, dev->priv.qp_debugfs,
+			   &qp->dbg, qp->qpn, qp_fields,
+			   ARRAY_SIZE(qp_fields), qp);
+	if (err)
+		qp->dbg = NULL;
+
+	return err;
+}
+
+void mlx5_debug_qp_remove(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp)
+{
+	if (!mlx5_debugfs_root)
+		return;
+
+	if (qp->dbg)
+		rem_res_tree(qp->dbg);
+}
+
+
+int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
+{
+	int err;
+
+	if (!mlx5_debugfs_root)
+		return 0;
+
+	err = add_res_tree(dev, MLX5_DBG_RSC_EQ, dev->priv.eq_debugfs,
+			   &eq->dbg, eq->eqn, eq_fields,
+			   ARRAY_SIZE(eq_fields), eq);
+	if (err)
+		eq->dbg = NULL;
+
+	return err;
+}
+
+void mlx5_debug_eq_remove(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
+{
+	if (!mlx5_debugfs_root)
+		return;
+
+	if (eq->dbg)
+		rem_res_tree(eq->dbg);
+}
+
+int mlx5_debug_cq_add(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
+{
+	int err;
+
+	if (!mlx5_debugfs_root)
+		return 0;
+
+	err = add_res_tree(dev, MLX5_DBG_RSC_CQ, dev->priv.cq_debugfs,
+			   &cq->dbg, cq->cqn, cq_fields,
+			   ARRAY_SIZE(cq_fields), cq);
+	if (err)
+		cq->dbg = NULL;
+
+	return err;
+}
+
+void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
+{
+	if (!mlx5_debugfs_root)
+		return;
+
+	if (cq->dbg)
+		rem_res_tree(cq->dbg);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/eq.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/eq.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/eq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/eq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include "mlx5_core.h"
+
+enum {
+	MLX5_EQE_SIZE		= sizeof(struct mlx5_eqe),
+	MLX5_EQE_OWNER_INIT_VAL	= 0x1,
+};
+
+enum {
+	MLX5_EQ_STATE_ARMED		= 0x9,
+	MLX5_EQ_STATE_FIRED		= 0xa,
+	MLX5_EQ_STATE_ALWAYS_ARMED	= 0xb,
+};
+
+enum {
+	MLX5_NUM_SPARE_EQE	= 0x80,
+	MLX5_NUM_ASYNC_EQE	= 0x100,
+	MLX5_NUM_CMD_EQE	= 32,
+};
+
+enum {
+	MLX5_EQ_DOORBEL_OFFSET	= 0x40,
+};
+
+#define MLX5_ASYNC_EVENT_MASK ((1ull << MLX5_EVENT_TYPE_PATH_MIG)	    | \
+			       (1ull << MLX5_EVENT_TYPE_COMM_EST)	    | \
+			       (1ull << MLX5_EVENT_TYPE_SQ_DRAINED)	    | \
+			       (1ull << MLX5_EVENT_TYPE_CQ_ERROR)	    | \
+			       (1ull << MLX5_EVENT_TYPE_WQ_CATAS_ERROR)	    | \
+			       (1ull << MLX5_EVENT_TYPE_PATH_MIG_FAILED)    | \
+			       (1ull << MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR) | \
+			       (1ull << MLX5_EVENT_TYPE_WQ_ACCESS_ERROR)    | \
+			       (1ull << MLX5_EVENT_TYPE_PORT_CHANGE)	    | \
+			       (1ull << MLX5_EVENT_TYPE_SRQ_CATAS_ERROR)    | \
+			       (1ull << MLX5_EVENT_TYPE_SRQ_LAST_WQE)	    | \
+			       (1ull << MLX5_EVENT_TYPE_SRQ_RQ_LIMIT))
+
+struct map_eq_in {
+	u64	mask;
+	u32	reserved;
+	u32	unmap_eqn;
+};
+
+struct cre_des_eq {
+	u8	reserved[15];
+	u8	eqn;
+};
+
+static int mlx5_cmd_destroy_eq(struct mlx5_core_dev *dev, u8 eqn)
+{
+	struct mlx5_destroy_eq_mbox_in in;
+	struct mlx5_destroy_eq_mbox_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_EQ);
+	in.eqn = eqn;
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (!err)
+		goto ex;
+
+	if (out.hdr.status)
+		err = mlx5_cmd_status_to_err(&out.hdr);
+
+ex:
+	return err;
+}
+
+static struct mlx5_eqe *get_eqe(struct mlx5_eq *eq, u32 entry)
+{
+	return mlx5_buf_offset(&eq->buf, entry * MLX5_EQE_SIZE);
+}
+
+static struct mlx5_eqe *next_eqe_sw(struct mlx5_eq *eq)
+{
+	struct mlx5_eqe *eqe = get_eqe(eq, eq->cons_index & (eq->nent - 1));
+
+	return ((eqe->owner & 1) ^ !!(eq->cons_index & eq->nent)) ? NULL : eqe;
+}
+
+static const char *eqe_type_str(u8 type)
+{
+	switch (type) {
+	case MLX5_EVENT_TYPE_COMP:
+		return "MLX5_EVENT_TYPE_COMP";
+	case MLX5_EVENT_TYPE_PATH_MIG:
+		return "MLX5_EVENT_TYPE_PATH_MIG";
+	case MLX5_EVENT_TYPE_COMM_EST:
+		return "MLX5_EVENT_TYPE_COMM_EST";
+	case MLX5_EVENT_TYPE_SQ_DRAINED:
+		return "MLX5_EVENT_TYPE_SQ_DRAINED";
+	case MLX5_EVENT_TYPE_SRQ_LAST_WQE:
+		return "MLX5_EVENT_TYPE_SRQ_LAST_WQE";
+	case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT:
+		return "MLX5_EVENT_TYPE_SRQ_RQ_LIMIT";
+	case MLX5_EVENT_TYPE_CQ_ERROR:
+		return "MLX5_EVENT_TYPE_CQ_ERROR";
+	case MLX5_EVENT_TYPE_WQ_CATAS_ERROR:
+		return "MLX5_EVENT_TYPE_WQ_CATAS_ERROR";
+	case MLX5_EVENT_TYPE_PATH_MIG_FAILED:
+		return "MLX5_EVENT_TYPE_PATH_MIG_FAILED";
+	case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
+		return "MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR";
+	case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
+		return "MLX5_EVENT_TYPE_WQ_ACCESS_ERROR";
+	case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
+		return "MLX5_EVENT_TYPE_SRQ_CATAS_ERROR";
+	case MLX5_EVENT_TYPE_INTERNAL_ERROR:
+		return "MLX5_EVENT_TYPE_INTERNAL_ERROR";
+	case MLX5_EVENT_TYPE_PORT_CHANGE:
+		return "MLX5_EVENT_TYPE_PORT_CHANGE";
+	case MLX5_EVENT_TYPE_GPIO_EVENT:
+		return "MLX5_EVENT_TYPE_GPIO_EVENT";
+	case MLX5_EVENT_TYPE_REMOTE_CONFIG:
+		return "MLX5_EVENT_TYPE_REMOTE_CONFIG";
+	case MLX5_EVENT_TYPE_DB_BF_CONGESTION:
+		return "MLX5_EVENT_TYPE_DB_BF_CONGESTION";
+	case MLX5_EVENT_TYPE_STALL_EVENT:
+		return "MLX5_EVENT_TYPE_STALL_EVENT";
+	case MLX5_EVENT_TYPE_CMD:
+		return "MLX5_EVENT_TYPE_CMD";
+	case MLX5_EVENT_TYPE_PAGE_REQUEST:
+		return "MLX5_EVENT_TYPE_PAGE_REQUEST";
+	default:
+		return "Unrecognized event";
+	}
+}
+
+static enum mlx5_dev_event port_subtype_event(u8 subtype)
+{
+	switch (subtype) {
+	case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
+		return MLX5_DEV_EVENT_PORT_DOWN;
+	case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
+		return MLX5_DEV_EVENT_PORT_UP;
+	case MLX5_PORT_CHANGE_SUBTYPE_INITIALIZED:
+		return MLX5_DEV_EVENT_PORT_INITIALIZED;
+	case MLX5_PORT_CHANGE_SUBTYPE_LID:
+		return MLX5_DEV_EVENT_LID_CHANGE;
+	case MLX5_PORT_CHANGE_SUBTYPE_PKEY:
+		return MLX5_DEV_EVENT_PKEY_CHANGE;
+	case MLX5_PORT_CHANGE_SUBTYPE_GUID:
+		return MLX5_DEV_EVENT_GUID_CHANGE;
+	case MLX5_PORT_CHANGE_SUBTYPE_CLIENT_REREG:
+		return MLX5_DEV_EVENT_CLIENT_REREG;
+	}
+	return -1;
+}
+
+static void eq_update_ci(struct mlx5_eq *eq, int arm)
+{
+	__be32 __iomem *addr = eq->doorbell + (arm ? 0 : 2);
+	u32 val = (eq->cons_index & 0xffffff) | (eq->eqn << 24);
+	__raw_writel((__force u32) cpu_to_be32(val), addr);
+	/* We still want ordering, just not swabbing, so add a barrier */
+	mb();
+}
+
+static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
+{
+	struct mlx5_eqe *eqe;
+	int eqes_found = 0;
+	int set_ci = 0;
+	u32 cqn;
+	u32 srqn;
+	u8 port;
+
+	while ((eqe = next_eqe_sw(eq))) {
+		/*
+		 * Make sure we read EQ entry contents after we've
+		 * checked the ownership bit.
+		 */
+		rmb();
+
+		mlx5_core_dbg(eq->dev, "eqn %d, eqe type %s\n", eq->eqn, eqe_type_str(eqe->type));
+		switch (eqe->type) {
+		case MLX5_EVENT_TYPE_COMP:
+			cqn = be32_to_cpu(eqe->data.comp.cqn) & 0xffffff;
+			mlx5_cq_completion(dev, cqn);
+			break;
+
+		case MLX5_EVENT_TYPE_PATH_MIG:
+		case MLX5_EVENT_TYPE_COMM_EST:
+		case MLX5_EVENT_TYPE_SQ_DRAINED:
+		case MLX5_EVENT_TYPE_SRQ_LAST_WQE:
+		case MLX5_EVENT_TYPE_WQ_CATAS_ERROR:
+		case MLX5_EVENT_TYPE_PATH_MIG_FAILED:
+		case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
+		case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
+			mlx5_core_dbg(dev, "event %s(%d) arrived\n",
+				      eqe_type_str(eqe->type), eqe->type);
+			mlx5_qp_event(dev, be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff,
+				      eqe->type);
+			break;
+
+		case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT:
+		case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
+			srqn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
+			mlx5_core_dbg(dev, "SRQ event %s(%d): srqn 0x%x\n",
+				      eqe_type_str(eqe->type), eqe->type, srqn);
+			mlx5_srq_event(dev, srqn, eqe->type);
+			break;
+
+		case MLX5_EVENT_TYPE_CMD:
+			mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector));
+			break;
+
+		case MLX5_EVENT_TYPE_PORT_CHANGE:
+			port = (eqe->data.port.port >> 4) & 0xf;
+			switch (eqe->sub_type) {
+			case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
+			case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
+			case MLX5_PORT_CHANGE_SUBTYPE_LID:
+			case MLX5_PORT_CHANGE_SUBTYPE_PKEY:
+			case MLX5_PORT_CHANGE_SUBTYPE_GUID:
+			case MLX5_PORT_CHANGE_SUBTYPE_CLIENT_REREG:
+			case MLX5_PORT_CHANGE_SUBTYPE_INITIALIZED:
+				dev->event(dev, port_subtype_event(eqe->sub_type), &port);
+				break;
+			default:
+				mlx5_core_warn(dev, "Port event with unrecognized subtype: port %d, sub_type %d\n",
+					       port, eqe->sub_type);
+			}
+			break;
+		case MLX5_EVENT_TYPE_CQ_ERROR:
+			cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff;
+			mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrom 0x%x\n",
+				       cqn, eqe->data.cq_err.syndrome);
+			mlx5_cq_event(dev, cqn, eqe->type);
+			break;
+
+		case MLX5_EVENT_TYPE_PAGE_REQUEST:
+			{
+				u16 func_id = be16_to_cpu(eqe->data.req_pages.func_id);
+				s32 npages = be32_to_cpu(eqe->data.req_pages.num_pages);
+
+				mlx5_core_dbg(dev, "page request for func 0x%x, napges %d\n", func_id, npages);
+				mlx5_core_req_pages_handler(dev, func_id, npages);
+			}
+			break;
+
+
+		default:
+			mlx5_core_warn(dev, "Unhandled event 0x%x on EQ 0x%x\n", eqe->type, eq->eqn);
+			break;
+		}
+
+		++eq->cons_index;
+		eqes_found = 1;
+		++set_ci;
+
+		/* The HCA will think the queue has overflowed if we
+		 * don't tell it we've been processing events.  We
+		 * create our EQs with MLX5_NUM_SPARE_EQE extra
+		 * entries, so we must update our consumer index at
+		 * least that often.
+		 */
+		if (unlikely(set_ci >= MLX5_NUM_SPARE_EQE)) {
+			eq_update_ci(eq, 0);
+			set_ci = 0;
+		}
+	}
+
+	eq_update_ci(eq, 1);
+
+	return eqes_found;
+}
+
+static irqreturn_t mlx5_msix_handler(int irq, void *eq_ptr)
+{
+	struct mlx5_eq *eq = eq_ptr;
+	struct mlx5_core_dev *dev = eq->dev;
+
+	mlx5_eq_int(dev, eq);
+
+	/* MSI-X vectors always belong to us */
+	return IRQ_HANDLED;
+}
+
+static void init_eq_buf(struct mlx5_eq *eq)
+{
+	struct mlx5_eqe *eqe;
+	int i;
+
+	for (i = 0; i < eq->nent; i++) {
+		eqe = get_eqe(eq, i);
+		eqe->owner = MLX5_EQE_OWNER_INIT_VAL;
+	}
+}
+
+int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
+		       int nent, u64 mask, const char *name, struct mlx5_uar *uar)
+{
+	struct mlx5_eq_table *table = &dev->priv.eq_table;
+	struct mlx5_create_eq_mbox_in *in;
+	struct mlx5_create_eq_mbox_out out;
+	int err;
+	int inlen;
+
+	eq->nent = roundup_pow_of_two(nent + MLX5_NUM_SPARE_EQE);
+	err = mlx5_buf_alloc(dev, eq->nent * MLX5_EQE_SIZE, 2 * PAGE_SIZE,
+			     &eq->buf);
+	if (err)
+		return err;
+
+	init_eq_buf(eq);
+
+	inlen = sizeof(*in) + sizeof(in->pas[0]) * eq->buf.npages;
+	in = mlx5_vzalloc(inlen);
+	if (!in) {
+		err = -ENOMEM;
+		goto err_buf;
+	}
+	memset(&out, 0, sizeof(out));
+
+	mlx5_fill_page_array(&eq->buf, in->pas);
+
+	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_EQ);
+	in->ctx.log_sz_usr_page = cpu_to_be32(ilog2(eq->nent) << 24 | uar->index);
+	in->ctx.intr = vecidx;
+	in->ctx.log_page_size = PAGE_SHIFT - 12;
+	in->events_mask = cpu_to_be64(mask);
+
+	err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
+	if (err)
+		goto err_in;
+
+	if (out.hdr.status) {
+		err = mlx5_cmd_status_to_err(&out.hdr);
+		goto err_in;
+	}
+
+	eq->eqn = out.eq_number;
+	err = request_irq(table->msix_arr[vecidx].vector, mlx5_msix_handler, 0,
+			  name, eq);
+	if (err)
+		goto err_eq;
+
+	eq->irqn = vecidx;
+	eq->dev = dev;
+	eq->doorbell = uar->map + MLX5_EQ_DOORBEL_OFFSET;
+
+	err = mlx5_debug_eq_add(dev, eq);
+	if (err)
+		goto err_irq;
+
+	/* EQs are created in ARMED state
+	 */
+	eq_update_ci(eq, 1);
+
+	mlx5_vfree(in);
+	return 0;
+
+err_irq:
+	free_irq(table->msix_arr[vecidx].vector, eq);
+
+err_eq:
+	mlx5_cmd_destroy_eq(dev, eq->eqn);
+
+err_in:
+	mlx5_vfree(in);
+
+err_buf:
+	mlx5_buf_free(dev, &eq->buf);
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_create_map_eq);
+
+int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
+{
+	struct mlx5_eq_table *table = &dev->priv.eq_table;
+	int err;
+
+	mlx5_debug_eq_remove(dev, eq);
+	free_irq(table->msix_arr[eq->irqn].vector, eq);
+	err = mlx5_cmd_destroy_eq(dev, eq->eqn);
+	if (err)
+		mlx5_core_warn(dev, "failed to destroy a previously created eq: eqn %d\n",
+			       eq->eqn);
+	mlx5_buf_free(dev, &eq->buf);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_destroy_unmap_eq);
+
+int mlx5_eq_init(struct mlx5_core_dev *dev)
+{
+	int err;
+
+	spin_lock_init(&dev->priv.eq_table.lock);
+
+	err = mlx5_eq_debugfs_init(dev);
+
+	return err;
+}
+
+
+void mlx5_eq_cleanup(struct mlx5_core_dev *dev)
+{
+	mlx5_eq_debugfs_cleanup(dev);
+}
+
+int mlx5_start_eqs(struct mlx5_core_dev *dev)
+{
+	struct mlx5_eq_table *table = &dev->priv.eq_table;
+	int err;
+
+	err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD,
+				 MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD,
+				 "mlx5_cmd_eq", &dev->priv.uuari.uars[0]);
+	if (err) {
+		mlx5_core_warn(dev, "failed to create cmd EQ %d\n", err);
+		return err;
+	}
+
+	mlx5_cmd_use_events(dev);
+
+	err = mlx5_create_map_eq(dev, &table->async_eq, MLX5_EQ_VEC_ASYNC,
+				 MLX5_NUM_ASYNC_EQE, MLX5_ASYNC_EVENT_MASK,
+				 "mlx5_async_eq", &dev->priv.uuari.uars[0]);
+	if (err) {
+		mlx5_core_warn(dev, "failed to create async EQ %d\n", err);
+		goto err1;
+	}
+
+	err = mlx5_create_map_eq(dev, &table->pages_eq,
+				 MLX5_EQ_VEC_PAGES,
+				 dev->caps.max_vf + 1,
+				 1 << MLX5_EVENT_TYPE_PAGE_REQUEST, "mlx5_pages_eq",
+				 &dev->priv.uuari.uars[0]);
+	if (err) {
+		mlx5_core_warn(dev, "failed to create pages EQ %d\n", err);
+		goto err2;
+	}
+
+	return err;
+
+err2:
+	mlx5_destroy_unmap_eq(dev, &table->async_eq);
+
+err1:
+	mlx5_cmd_use_polling(dev);
+	mlx5_destroy_unmap_eq(dev, &table->cmd_eq);
+	return err;
+}
+
+int mlx5_stop_eqs(struct mlx5_core_dev *dev)
+{
+	struct mlx5_eq_table *table = &dev->priv.eq_table;
+	int err;
+
+	err = mlx5_destroy_unmap_eq(dev, &table->pages_eq);
+	if (err)
+		return err;
+
+	mlx5_destroy_unmap_eq(dev, &table->async_eq);
+	mlx5_cmd_use_polling(dev);
+
+	err = mlx5_destroy_unmap_eq(dev, &table->cmd_eq);
+	if (err)
+		mlx5_cmd_use_events(dev);
+
+	return err;
+}
+
+int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
+		       struct mlx5_query_eq_mbox_out *out, int outlen)
+{
+	struct mlx5_query_eq_mbox_in in;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(out, 0, outlen);
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_EQ);
+	in.eqn = eq->eqn;
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, outlen);
+	if (err)
+		return err;
+
+	if (out->hdr.status)
+		err = mlx5_cmd_status_to_err(&out->hdr);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_core_eq_query);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/fw.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/fw.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/fw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/fw.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include <linux/module.h>
+#include "mlx5_core.h"
+
+int mlx5_cmd_query_adapter(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd_query_adapter_mbox_out *out;
+	struct mlx5_cmd_query_adapter_mbox_in in;
+	int err;
+
+	out = kzalloc(sizeof(*out), GFP_KERNEL);
+	if (!out)
+		return -ENOMEM;
+
+	memset(&in, 0, sizeof(in));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_ADAPTER);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out));
+	if (err)
+		goto out_out;
+
+	if (out->hdr.status) {
+		err = mlx5_cmd_status_to_err(&out->hdr);
+		goto out_out;
+	}
+
+	memcpy(dev->board_id, out->vsd_psid, sizeof(out->vsd_psid));
+
+out_out:
+	kfree(out);
+
+	return err;
+}
+
+int mlx5_cmd_query_hca_cap(struct mlx5_core_dev *dev,
+			   struct mlx5_caps *caps)
+{
+	struct mlx5_cmd_query_hca_cap_mbox_out *out;
+	struct mlx5_cmd_query_hca_cap_mbox_in in;
+	struct mlx5_query_special_ctxs_mbox_out ctx_out;
+	struct mlx5_query_special_ctxs_mbox_in ctx_in;
+	int err;
+	u16 t16;
+
+	out = kzalloc(sizeof(*out), GFP_KERNEL);
+	if (!out)
+		return -ENOMEM;
+
+	memset(&in, 0, sizeof(in));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP);
+	in.hdr.opmod  = cpu_to_be16(0x1);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out));
+	if (err)
+		goto out_out;
+
+	if (out->hdr.status) {
+		err = mlx5_cmd_status_to_err(&out->hdr);
+		goto out_out;
+	}
+
+
+	caps->log_max_eq = out->hca_cap.log_max_eq & 0xf;
+	caps->max_cqes = 1 << out->hca_cap.log_max_cq_sz;
+	caps->max_wqes = 1 << out->hca_cap.log_max_qp_sz;
+	caps->max_sq_desc_sz = be16_to_cpu(out->hca_cap.max_desc_sz_sq);
+	caps->max_rq_desc_sz = be16_to_cpu(out->hca_cap.max_desc_sz_rq);
+	caps->flags = be64_to_cpu(out->hca_cap.flags);
+	caps->stat_rate_support = be16_to_cpu(out->hca_cap.stat_rate_support);
+	caps->log_max_msg = out->hca_cap.log_max_msg & 0x1f;
+	caps->num_ports = out->hca_cap.num_ports & 0xf;
+	caps->log_max_cq = out->hca_cap.log_max_cq & 0x1f;
+	if (caps->num_ports > MLX5_MAX_PORTS) {
+		mlx5_core_err(dev, "device has %d ports while the driver supports max %d ports\n",
+			      caps->num_ports, MLX5_MAX_PORTS);
+		err = -EINVAL;
+		goto out_out;
+	}
+	caps->log_max_qp = out->hca_cap.log_max_qp & 0x1f;
+	caps->log_max_mkey = out->hca_cap.log_max_mkey & 0x3f;
+	caps->log_max_pd = out->hca_cap.log_max_pd & 0x1f;
+	caps->log_max_srq = out->hca_cap.log_max_srqs & 0x1f;
+	caps->local_ca_ack_delay = out->hca_cap.local_ca_ack_delay & 0x1f;
+	caps->log_max_mcg = out->hca_cap.log_max_mcg;
+	caps->max_qp_mcg = be32_to_cpu(out->hca_cap.max_qp_mcg) & 0xffffff;
+	caps->max_ra_res_qp = 1 << (out->hca_cap.log_max_ra_res_qp & 0x3f);
+	caps->max_ra_req_qp = 1 << (out->hca_cap.log_max_ra_req_qp & 0x3f);
+	caps->max_srq_wqes = 1 << out->hca_cap.log_max_srq_sz;
+	t16 = be16_to_cpu(out->hca_cap.bf_log_bf_reg_size);
+	if (t16 & 0x8000) {
+		caps->bf_reg_size = 1 << (t16 & 0x1f);
+		caps->bf_regs_per_page = MLX5_BF_REGS_PER_PAGE;
+	} else {
+		caps->bf_reg_size = 0;
+		caps->bf_regs_per_page = 0;
+	}
+	caps->min_page_sz = ~(u32)((1 << out->hca_cap.log_pg_sz) - 1);
+
+	memset(&ctx_in, 0, sizeof(ctx_in));
+	memset(&ctx_out, 0, sizeof(ctx_out));
+	ctx_in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS);
+	err = mlx5_cmd_exec(dev, &ctx_in, sizeof(ctx_in),
+				 &ctx_out, sizeof(ctx_out));
+	if (err)
+		goto out_out;
+
+	if (ctx_out.hdr.status)
+		err = mlx5_cmd_status_to_err(&ctx_out.hdr);
+
+	caps->reserved_lkey = be32_to_cpu(ctx_out.reserved_lkey);
+
+out_out:
+	kfree(out);
+
+	return err;
+}
+
+int mlx5_cmd_init_hca(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd_init_hca_mbox_in in;
+	struct mlx5_cmd_init_hca_mbox_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_INIT_HCA);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		err = mlx5_cmd_status_to_err(&out.hdr);
+
+	return err;
+}
+
+int mlx5_cmd_teardown_hca(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd_teardown_hca_mbox_in in;
+	struct mlx5_cmd_teardown_hca_mbox_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_TEARDOWN_HCA);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		err = mlx5_cmd_status_to_err(&out.hdr);
+
+	return err;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/health.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/health.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/health.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/health.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/vmalloc.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include "mlx5_core.h"
+
+enum {
+	MLX5_HEALTH_POLL_INTERVAL	= 2 * HZ,
+	MAX_MISSES			= 3,
+};
+
+enum {
+	MLX5_HEALTH_SYNDR_FW_ERR		= 0x1,
+	MLX5_HEALTH_SYNDR_IRISC_ERR		= 0x7,
+	MLX5_HEALTH_SYNDR_CRC_ERR		= 0x9,
+	MLX5_HEALTH_SYNDR_FETCH_PCI_ERR		= 0xa,
+	MLX5_HEALTH_SYNDR_HW_FTL_ERR		= 0xb,
+	MLX5_HEALTH_SYNDR_ASYNC_EQ_OVERRUN_ERR	= 0xc,
+	MLX5_HEALTH_SYNDR_EQ_ERR		= 0xd,
+	MLX5_HEALTH_SYNDR_FFSER_ERR		= 0xf,
+};
+
+static DEFINE_SPINLOCK(health_lock);
+static LIST_HEAD(health_list);
+static struct work_struct health_work;
+
+static void health_care(struct work_struct *work)
+{
+	struct mlx5_core_health *health, *n;
+	struct mlx5_core_dev *dev;
+	struct mlx5_priv *priv;
+	LIST_HEAD(tlist);
+
+	spin_lock_irq(&health_lock);
+	list_splice_init(&health_list, &tlist);
+
+	spin_unlock_irq(&health_lock);
+
+	list_for_each_entry_safe(health, n, &tlist, list) {
+		priv = container_of(health, struct mlx5_priv, health);
+		dev = container_of(priv, struct mlx5_core_dev, priv);
+		mlx5_core_warn(dev, "handling bad device here\n");
+		/* nothing yet */
+		spin_lock_irq(&health_lock);
+		list_del_init(&health->list);
+		spin_unlock_irq(&health_lock);
+	}
+}
+
+static const char *hsynd_str(u8 synd)
+{
+	switch (synd) {
+	case MLX5_HEALTH_SYNDR_FW_ERR:
+		return "firmware internal error";
+	case MLX5_HEALTH_SYNDR_IRISC_ERR:
+		return "irisc not responding";
+	case MLX5_HEALTH_SYNDR_CRC_ERR:
+		return "firmware CRC error";
+	case MLX5_HEALTH_SYNDR_FETCH_PCI_ERR:
+		return "ICM fetch PCI error";
+	case MLX5_HEALTH_SYNDR_HW_FTL_ERR:
+		return "HW fatal error\n";
+	case MLX5_HEALTH_SYNDR_ASYNC_EQ_OVERRUN_ERR:
+		return "async EQ buffer overrun";
+	case MLX5_HEALTH_SYNDR_EQ_ERR:
+		return "EQ error";
+	case MLX5_HEALTH_SYNDR_FFSER_ERR:
+		return "FFSER error";
+	default:
+		return "unrecognized error";
+	}
+}
+
+static u16 read_be16(__be16 __iomem *p)
+{
+	return swab16(readl((__force u16 __iomem *) p));
+}
+
+static u32 read_be32(__be32 __iomem *p)
+{
+	return swab32(readl((__force u32 __iomem *) p));
+}
+
+static void print_health_info(struct mlx5_core_dev *dev)
+{
+	struct mlx5_core_health *health = &dev->priv.health;
+	struct health_buffer __iomem *h = health->health;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(h->assert_var); i++)
+		pr_info("assert_var[%d] 0x%08x\n", i, read_be32(h->assert_var + i));
+
+	pr_info("assert_exit_ptr 0x%08x\n", read_be32(&h->assert_exit_ptr));
+	pr_info("assert_callra 0x%08x\n", read_be32(&h->assert_callra));
+	pr_info("fw_ver 0x%08x\n", read_be32(&h->fw_ver));
+	pr_info("hw_id 0x%08x\n", read_be32(&h->hw_id));
+	pr_info("irisc_index %d\n", readb(&h->irisc_index));
+	pr_info("synd 0x%x: %s\n", readb(&h->synd), hsynd_str(readb(&h->synd)));
+	pr_info("ext_sync 0x%04x\n", read_be16(&h->ext_sync));
+}
+
+static void poll_health(unsigned long data)
+{
+	struct mlx5_core_dev *dev = (struct mlx5_core_dev *)data;
+	struct mlx5_core_health *health = &dev->priv.health;
+	unsigned long next;
+	u32 count;
+
+	count = ioread32be(health->health_counter);
+	if (count == health->prev)
+		++health->miss_counter;
+	else
+		health->miss_counter = 0;
+
+	health->prev = count;
+	if (health->miss_counter == MAX_MISSES) {
+		mlx5_core_err(dev, "device's health compromised\n");
+		print_health_info(dev);
+		spin_lock_irq(&health_lock);
+		list_add_tail(&health->list, &health_list);
+		spin_unlock_irq(&health_lock);
+
+		queue_work(mlx5_core_wq, &health_work);
+	} else {
+		get_random_bytes(&next, sizeof(next));
+		next %= HZ;
+		next += jiffies + MLX5_HEALTH_POLL_INTERVAL;
+		mod_timer(&health->timer, next);
+	}
+}
+
+void mlx5_start_health_poll(struct mlx5_core_dev *dev)
+{
+	struct mlx5_core_health *health = &dev->priv.health;
+
+	INIT_LIST_HEAD(&health->list);
+	init_timer(&health->timer);
+	health->health = &dev->iseg->health;
+	health->health_counter = &dev->iseg->health_counter;
+
+	health->timer.data = (unsigned long)dev;
+	health->timer.function = poll_health;
+	health->timer.expires = round_jiffies(jiffies + MLX5_HEALTH_POLL_INTERVAL);
+	add_timer(&health->timer);
+}
+
+void mlx5_stop_health_poll(struct mlx5_core_dev *dev)
+{
+	struct mlx5_core_health *health = &dev->priv.health;
+
+	del_timer_sync(&health->timer);
+
+	spin_lock_irq(&health_lock);
+	if (!list_empty(&health->list))
+		list_del_init(&health->list);
+	spin_unlock_irq(&health_lock);
+}
+
+void mlx5_health_cleanup(void)
+{
+}
+
+void  __init mlx5_health_init(void)
+{
+	INIT_WORK(&health_work, health_care);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,18 @@
+#
+# Mellanox driver configuration
+#
+
+config MLX5_CORE
+	tristate
+	depends on PCI && X86
+	default n
+
+config MLX5_DEBUG
+	bool "Verbose debugging output" if (MLX5_CORE && EXPERT)
+	depends on MLX5_CORE
+	default y
+	---help---
+	  This option causes debugging code to be compiled into the
+	  mlx5_core driver.  The output can be turned on via the
+	  debug_mask module parameter (which can also be set after
+	  the driver is loaded through sysfs).
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/mad.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/mad.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/mad.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/mad.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include "mlx5_core.h"
+
+int mlx5_core_mad_ifc(struct mlx5_core_dev *dev, void *inb, void *outb,
+		      u16 opmod, int port)
+{
+	struct mlx5_mad_ifc_mbox_in *in = NULL;
+	struct mlx5_mad_ifc_mbox_out *out = NULL;
+	int err;
+
+	in = kzalloc(sizeof(*in), GFP_KERNEL);
+	if (!in)
+		return -ENOMEM;
+
+	out = kzalloc(sizeof(*out), GFP_KERNEL);
+	if (!out) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_MAD_IFC);
+	in->hdr.opmod = cpu_to_be16(opmod);
+	in->port = port;
+
+	memcpy(in->data, inb, sizeof(in->data));
+
+	err = mlx5_cmd_exec(dev, in, sizeof(*in), out, sizeof(*out));
+	if (err)
+		goto out;
+
+	if (out->hdr.status) {
+		err = mlx5_cmd_status_to_err(&out->hdr);
+		goto out;
+	}
+
+	memcpy(outb, out->data, sizeof(out->data));
+
+out:
+	kfree(out);
+	kfree(in);
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_core_mad_ifc);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <asm-generic/kmap_types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/io-mapping.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cq.h>
+#include <linux/mlx5/qp.h>
+#include <linux/mlx5/srq.h>
+#include <linux/debugfs.h>
+#include "mlx5_core.h"
+
+#define DRIVER_NAME "mlx5_core"
+#define DRIVER_VERSION "1.0"
+#define DRIVER_RELDATE	"June 2013"
+
+MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox ConnectX-IB HCA core library");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+int mlx5_core_debug_mask;
+module_param_named(debug_mask, mlx5_core_debug_mask, int, 0644);
+MODULE_PARM_DESC(debug_mask, "debug mask: 1 = dump cmd data, 2 = dump cmd exec time, 3 = both. Default=0");
+
+struct workqueue_struct *mlx5_core_wq;
+
+static int set_dma_caps(struct pci_dev *pdev)
+{
+	int err;
+
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+	if (err) {
+		dev_warn(&pdev->dev, "Warning: couldn't set 64-bit PCI DMA mask.\n");
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (err) {
+			dev_err(&pdev->dev, "Can't set PCI DMA mask, aborting.\n");
+			return err;
+		}
+	}
+
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+	if (err) {
+		dev_warn(&pdev->dev,
+			 "Warning: couldn't set 64-bit consistent PCI DMA mask.\n");
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (err) {
+			dev_err(&pdev->dev,
+				"Can't set consistent PCI DMA mask, aborting.\n");
+			return err;
+		}
+	}
+
+	dma_set_max_seg_size(&pdev->dev, 2u * 1024 * 1024 * 1024);
+	return err;
+}
+
+static int request_bar(struct pci_dev *pdev)
+{
+	int err = 0;
+
+	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+		dev_err(&pdev->dev, "Missing registers BAR, aborting.\n");
+		return -ENODEV;
+	}
+
+	err = pci_request_regions(pdev, DRIVER_NAME);
+	if (err)
+		dev_err(&pdev->dev, "Couldn't get PCI resources, aborting\n");
+
+	return err;
+}
+
+static void release_bar(struct pci_dev *pdev)
+{
+	pci_release_regions(pdev);
+}
+
+static int mlx5_enable_msix(struct mlx5_core_dev *dev)
+{
+	struct mlx5_eq_table *table = &dev->priv.eq_table;
+	int num_eqs = 1 << dev->caps.log_max_eq;
+	int nvec;
+	int err;
+	int i;
+
+	nvec = dev->caps.num_ports * num_online_cpus() + MLX5_EQ_VEC_COMP_BASE;
+	nvec = min_t(int, nvec, num_eqs);
+	if (nvec <= MLX5_EQ_VEC_COMP_BASE)
+		return -ENOMEM;
+
+	table->msix_arr = kzalloc(nvec * sizeof(*table->msix_arr), GFP_KERNEL);
+	if (!table->msix_arr)
+		return -ENOMEM;
+
+	for (i = 0; i < nvec; i++)
+		table->msix_arr[i].entry = i;
+
+retry:
+	table->num_comp_vectors = nvec - MLX5_EQ_VEC_COMP_BASE;
+	err = pci_enable_msix(dev->pdev, table->msix_arr, nvec);
+	if (err <= 0) {
+		return err;
+	} else if (err > 2) {
+		nvec = err;
+		goto retry;
+	}
+
+	mlx5_core_dbg(dev, "received %d MSI vectors out of %d requested\n", err, nvec);
+
+	return 0;
+}
+
+static void mlx5_disable_msix(struct mlx5_core_dev *dev)
+{
+	struct mlx5_eq_table *table = &dev->priv.eq_table;
+
+	pci_disable_msix(dev->pdev);
+	kfree(table->msix_arr);
+}
+
+struct mlx5_reg_host_endianess {
+	u8	he;
+	u8      rsvd[15];
+};
+
+static int handle_hca_cap(struct mlx5_core_dev *dev)
+{
+	struct mlx5_cmd_query_hca_cap_mbox_out *query_out = NULL;
+	struct mlx5_cmd_set_hca_cap_mbox_in *set_ctx = NULL;
+	struct mlx5_cmd_query_hca_cap_mbox_in query_ctx;
+	struct mlx5_cmd_set_hca_cap_mbox_out set_out;
+	struct mlx5_profile *prof = dev->profile;
+	u64 flags;
+	int csum = 1;
+	int err;
+
+	memset(&query_ctx, 0, sizeof(query_ctx));
+	query_out = kzalloc(sizeof(*query_out), GFP_KERNEL);
+	if (!query_out)
+		return -ENOMEM;
+
+	set_ctx = kzalloc(sizeof(*set_ctx), GFP_KERNEL);
+	if (!set_ctx) {
+		err = -ENOMEM;
+		goto query_ex;
+	}
+
+	query_ctx.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_HCA_CAP);
+	query_ctx.hdr.opmod  = cpu_to_be16(0x1);
+	err = mlx5_cmd_exec(dev, &query_ctx, sizeof(query_ctx),
+				 query_out, sizeof(*query_out));
+	if (err)
+		goto query_ex;
+
+	err = mlx5_cmd_status_to_err(&query_out->hdr);
+	if (err) {
+		mlx5_core_warn(dev, "query hca cap failed, %d\n", err);
+		goto query_ex;
+	}
+
+	memcpy(&set_ctx->hca_cap, &query_out->hca_cap,
+	       sizeof(set_ctx->hca_cap));
+
+	if (prof->mask & MLX5_PROF_MASK_CMDIF_CSUM) {
+		csum = !!prof->cmdif_csum;
+		flags = be64_to_cpu(set_ctx->hca_cap.flags);
+		if (csum)
+			flags |= MLX5_DEV_CAP_FLAG_CMDIF_CSUM;
+		else
+			flags &= ~MLX5_DEV_CAP_FLAG_CMDIF_CSUM;
+
+		set_ctx->hca_cap.flags = cpu_to_be64(flags);
+	}
+
+	if (dev->profile->mask & MLX5_PROF_MASK_QP_SIZE)
+		set_ctx->hca_cap.log_max_qp = dev->profile->log_max_qp;
+
+	memset(&set_out, 0, sizeof(set_out));
+	set_ctx->hca_cap.log_uar_page_sz = cpu_to_be16(PAGE_SHIFT - 12);
+	set_ctx->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_SET_HCA_CAP);
+	err = mlx5_cmd_exec(dev, set_ctx, sizeof(*set_ctx),
+				 &set_out, sizeof(set_out));
+	if (err) {
+		mlx5_core_warn(dev, "set hca cap failed, %d\n", err);
+		goto query_ex;
+	}
+
+	err = mlx5_cmd_status_to_err(&set_out.hdr);
+	if (err)
+		goto query_ex;
+
+	if (!csum)
+		dev->cmd.checksum_disabled = 1;
+
+query_ex:
+	kfree(query_out);
+	kfree(set_ctx);
+
+	return err;
+}
+
+static int set_hca_ctrl(struct mlx5_core_dev *dev)
+{
+	struct mlx5_reg_host_endianess he_in;
+	struct mlx5_reg_host_endianess he_out;
+	int err;
+
+	memset(&he_in, 0, sizeof(he_in));
+	he_in.he = MLX5_SET_HOST_ENDIANNESS;
+	err = mlx5_core_access_reg(dev, &he_in,  sizeof(he_in),
+					&he_out, sizeof(he_out),
+					MLX5_REG_HOST_ENDIANNESS, 0, 1);
+	return err;
+}
+
+static int mlx5_core_enable_hca(struct mlx5_core_dev *dev)
+{
+	int err;
+	struct mlx5_enable_hca_mbox_in in;
+	struct mlx5_enable_hca_mbox_out out;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ENABLE_HCA);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	return 0;
+}
+
+static int mlx5_core_disable_hca(struct mlx5_core_dev *dev)
+{
+	int err;
+	struct mlx5_disable_hca_mbox_in in;
+	struct mlx5_disable_hca_mbox_out out;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DISABLE_HCA);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	return 0;
+}
+
+int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev)
+{
+	struct mlx5_priv *priv = &dev->priv;
+	int err;
+
+	dev->pdev = pdev;
+	pci_set_drvdata(dev->pdev, dev);
+	strncpy(priv->name, dev_name(&pdev->dev), MLX5_MAX_NAME_LEN);
+	priv->name[MLX5_MAX_NAME_LEN - 1] = 0;
+
+	mutex_init(&priv->pgdir_mutex);
+	INIT_LIST_HEAD(&priv->pgdir_list);
+	spin_lock_init(&priv->mkey_lock);
+
+	priv->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), mlx5_debugfs_root);
+	if (!priv->dbg_root)
+		return -ENOMEM;
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n");
+		goto err_dbg;
+	}
+
+	err = request_bar(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "error requesting BARs, aborting.\n");
+		goto err_disable;
+	}
+
+	pci_set_master(pdev);
+
+	err = set_dma_caps(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "Failed setting DMA capabilities mask, aborting\n");
+		goto err_clr_master;
+	}
+
+	dev->iseg_base = pci_resource_start(dev->pdev, 0);
+	dev->iseg = ioremap(dev->iseg_base, sizeof(*dev->iseg));
+	if (!dev->iseg) {
+		err = -ENOMEM;
+		dev_err(&pdev->dev, "Failed mapping initialization segment, aborting\n");
+		goto err_clr_master;
+	}
+	dev_info(&pdev->dev, "firmware version: %d.%d.%d\n", fw_rev_maj(dev),
+		 fw_rev_min(dev), fw_rev_sub(dev));
+
+	err = mlx5_cmd_init(dev);
+	if (err) {
+		dev_err(&pdev->dev, "Failed initializing command interface, aborting\n");
+		goto err_unmap;
+	}
+
+	mlx5_pagealloc_init(dev);
+
+	err = mlx5_core_enable_hca(dev);
+	if (err) {
+		dev_err(&pdev->dev, "enable hca failed\n");
+		goto err_pagealloc_cleanup;
+	}
+
+	err = mlx5_satisfy_startup_pages(dev, 1);
+	if (err) {
+		dev_err(&pdev->dev, "failed to allocate boot pages\n");
+		goto err_disable_hca;
+	}
+
+	err = set_hca_ctrl(dev);
+	if (err) {
+		dev_err(&pdev->dev, "set_hca_ctrl failed\n");
+		goto reclaim_boot_pages;
+	}
+
+	err = handle_hca_cap(dev);
+	if (err) {
+		dev_err(&pdev->dev, "handle_hca_cap failed\n");
+		goto reclaim_boot_pages;
+	}
+
+	err = mlx5_satisfy_startup_pages(dev, 0);
+	if (err) {
+		dev_err(&pdev->dev, "failed to allocate init pages\n");
+		goto reclaim_boot_pages;
+	}
+
+	err = mlx5_pagealloc_start(dev);
+	if (err) {
+		dev_err(&pdev->dev, "mlx5_pagealloc_start failed\n");
+		goto reclaim_boot_pages;
+	}
+
+	err = mlx5_cmd_init_hca(dev);
+	if (err) {
+		dev_err(&pdev->dev, "init hca failed\n");
+		goto err_pagealloc_stop;
+	}
+
+	mlx5_start_health_poll(dev);
+
+	err = mlx5_cmd_query_hca_cap(dev, &dev->caps);
+	if (err) {
+		dev_err(&pdev->dev, "query hca failed\n");
+		goto err_stop_poll;
+	}
+
+	err = mlx5_cmd_query_adapter(dev);
+	if (err) {
+		dev_err(&pdev->dev, "query adapter failed\n");
+		goto err_stop_poll;
+	}
+
+	err = mlx5_enable_msix(dev);
+	if (err) {
+		dev_err(&pdev->dev, "enable msix failed\n");
+		goto err_stop_poll;
+	}
+
+	err = mlx5_eq_init(dev);
+	if (err) {
+		dev_err(&pdev->dev, "failed to initialize eq\n");
+		goto disable_msix;
+	}
+
+	err = mlx5_alloc_uuars(dev, &priv->uuari);
+	if (err) {
+		dev_err(&pdev->dev, "Failed allocating uar, aborting\n");
+		goto err_eq_cleanup;
+	}
+
+	err = mlx5_start_eqs(dev);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to start pages and async EQs\n");
+		goto err_free_uar;
+	}
+
+	MLX5_INIT_DOORBELL_LOCK(&priv->cq_uar_lock);
+
+	mlx5_init_cq_table(dev);
+	mlx5_init_qp_table(dev);
+	mlx5_init_srq_table(dev);
+
+	return 0;
+
+err_free_uar:
+	mlx5_free_uuars(dev, &priv->uuari);
+
+err_eq_cleanup:
+	mlx5_eq_cleanup(dev);
+
+disable_msix:
+	mlx5_disable_msix(dev);
+
+err_stop_poll:
+	mlx5_stop_health_poll(dev);
+	mlx5_cmd_teardown_hca(dev);
+
+err_pagealloc_stop:
+	mlx5_pagealloc_stop(dev);
+
+reclaim_boot_pages:
+	mlx5_reclaim_startup_pages(dev);
+
+err_disable_hca:
+	mlx5_core_disable_hca(dev);
+
+err_pagealloc_cleanup:
+	mlx5_pagealloc_cleanup(dev);
+	mlx5_cmd_cleanup(dev);
+
+err_unmap:
+	iounmap(dev->iseg);
+
+err_clr_master:
+	pci_clear_master(dev->pdev);
+	release_bar(dev->pdev);
+
+err_disable:
+	pci_disable_device(dev->pdev);
+
+err_dbg:
+	debugfs_remove(priv->dbg_root);
+	return err;
+}
+EXPORT_SYMBOL(mlx5_dev_init);
+
+void mlx5_dev_cleanup(struct mlx5_core_dev *dev)
+{
+	struct mlx5_priv *priv = &dev->priv;
+
+	mlx5_cleanup_srq_table(dev);
+	mlx5_cleanup_qp_table(dev);
+	mlx5_cleanup_cq_table(dev);
+	mlx5_stop_eqs(dev);
+	mlx5_free_uuars(dev, &priv->uuari);
+	mlx5_eq_cleanup(dev);
+	mlx5_disable_msix(dev);
+	mlx5_stop_health_poll(dev);
+	mlx5_cmd_teardown_hca(dev);
+	mlx5_pagealloc_stop(dev);
+	mlx5_reclaim_startup_pages(dev);
+	mlx5_core_disable_hca(dev);
+	mlx5_pagealloc_cleanup(dev);
+	mlx5_cmd_cleanup(dev);
+	iounmap(dev->iseg);
+	pci_clear_master(dev->pdev);
+	release_bar(dev->pdev);
+	pci_disable_device(dev->pdev);
+	debugfs_remove(priv->dbg_root);
+}
+EXPORT_SYMBOL(mlx5_dev_cleanup);
+
+static int __init init(void)
+{
+	int err;
+
+	mlx5_register_debugfs();
+	mlx5_core_wq = create_singlethread_workqueue("mlx5_core_wq");
+	if (!mlx5_core_wq) {
+		err = -ENOMEM;
+		goto err_debug;
+	}
+	mlx5_health_init();
+
+	return 0;
+
+	mlx5_health_cleanup();
+err_debug:
+	mlx5_unregister_debugfs();
+	return err;
+}
+
+static void __exit cleanup(void)
+{
+	mlx5_health_cleanup();
+	destroy_workqueue(mlx5_core_wq);
+	mlx5_unregister_debugfs();
+}
+
+module_init(init);
+module_exit(cleanup);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/Makefile linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/Makefile
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,5 @@
+obj-$(CONFIG_MLX5_CORE)		+= mlx5_core.o
+
+mlx5_core-y :=	main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
+		health.o mcg.o cq.o srq.o alloc.o qp.o port.o mr.o pd.o   \
+		mad.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/mcg.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/mcg.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/mcg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/mcg.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include <rdma/ib_verbs.h>
+#include "mlx5_core.h"
+
+struct mlx5_attach_mcg_mbox_in {
+	struct mlx5_inbox_hdr	hdr;
+	__be32			qpn;
+	__be32			rsvd;
+	u8			gid[16];
+};
+
+struct mlx5_attach_mcg_mbox_out {
+	struct mlx5_outbox_hdr	hdr;
+	u8			rsvf[8];
+};
+
+struct mlx5_detach_mcg_mbox_in {
+	struct mlx5_inbox_hdr	hdr;
+	__be32			qpn;
+	__be32			rsvd;
+	u8			gid[16];
+};
+
+struct mlx5_detach_mcg_mbox_out {
+	struct mlx5_outbox_hdr	hdr;
+	u8			rsvf[8];
+};
+
+int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn)
+{
+	struct mlx5_attach_mcg_mbox_in in;
+	struct mlx5_attach_mcg_mbox_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ATTACH_TO_MCG);
+	memcpy(in.gid, mgid, sizeof(*mgid));
+	in.qpn = cpu_to_be32(qpn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		err = mlx5_cmd_status_to_err(&out.hdr);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_attach_mcg);
+
+int mlx5_core_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn)
+{
+	struct mlx5_detach_mcg_mbox_in in;
+	struct mlx5_detach_mcg_mbox_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DETACH_FROM_MCG);
+	memcpy(in.gid, mgid, sizeof(*mgid));
+	in.qpn = cpu_to_be32(qpn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		err = mlx5_cmd_status_to_err(&out.hdr);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_detach_mcg);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 __MLX5_CORE_H__
+#define __MLX5_CORE_H__
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+extern int mlx5_core_debug_mask;
+
+#define mlx5_core_dbg(dev, format, arg...)				       \
+pr_debug("%s:%s:%d:(pid %d): " format, (dev)->priv.name, __func__, __LINE__,   \
+	 current->pid, ##arg)
+
+#define mlx5_core_dbg_mask(dev, mask, format, arg...)			       \
+do {									       \
+	if ((mask) & mlx5_core_debug_mask)				       \
+		pr_debug("%s:%s:%d:(pid %d): " format, (dev)->priv.name,       \
+			 __func__, __LINE__, current->pid, ##arg);	       \
+} while (0)
+
+#define mlx5_core_err(dev, format, arg...) \
+pr_err("%s:%s:%d:(pid %d): " format, (dev)->priv.name, __func__, __LINE__,     \
+	current->pid, ##arg)
+
+#define mlx5_core_warn(dev, format, arg...) \
+pr_warn("%s:%s:%d:(pid %d): " format, (dev)->priv.name, __func__, __LINE__,    \
+	current->pid, ##arg)
+
+enum {
+	MLX5_CMD_DATA, /* print command payload only */
+	MLX5_CMD_TIME, /* print command execution time */
+};
+
+
+int mlx5_cmd_query_hca_cap(struct mlx5_core_dev *dev,
+			   struct mlx5_caps *caps);
+int mlx5_cmd_query_adapter(struct mlx5_core_dev *dev);
+int mlx5_cmd_init_hca(struct mlx5_core_dev *dev);
+int mlx5_cmd_teardown_hca(struct mlx5_core_dev *dev);
+
+#endif /* __MLX5_CORE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/mr.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/mr.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/mr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/mr.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include "mlx5_core.h"
+
+int mlx5_core_create_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr,
+			  struct mlx5_create_mkey_mbox_in *in, int inlen)
+{
+	struct mlx5_create_mkey_mbox_out out;
+	int err;
+	u8 key;
+
+	memset(&out, 0, sizeof(out));
+	spin_lock(&dev->priv.mkey_lock);
+	key = dev->priv.mkey_key++;
+	spin_unlock(&dev->priv.mkey_lock);
+	in->seg.qpn_mkey7_0 |= cpu_to_be32(key);
+	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_MKEY);
+	err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
+	if (err) {
+		mlx5_core_dbg(dev, "cmd exec faile %d\n", err);
+		return err;
+	}
+
+	if (out.hdr.status) {
+		mlx5_core_dbg(dev, "status %d\n", out.hdr.status);
+		return mlx5_cmd_status_to_err(&out.hdr);
+	}
+
+	mr->key = mlx5_idx_to_mkey(be32_to_cpu(out.mkey) & 0xffffff) | key;
+	mlx5_core_dbg(dev, "out 0x%x, key 0x%x, mkey 0x%x\n", be32_to_cpu(out.mkey), key, mr->key);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_create_mkey);
+
+int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr)
+{
+	struct mlx5_destroy_mkey_mbox_in in;
+	struct mlx5_destroy_mkey_mbox_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_MKEY);
+	in.mkey = cpu_to_be32(mlx5_mkey_to_idx(mr->key));
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_destroy_mkey);
+
+int mlx5_core_query_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr,
+			 struct mlx5_query_mkey_mbox_out *out, int outlen)
+{
+	struct mlx5_destroy_mkey_mbox_in in;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(out, 0, outlen);
+
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_MKEY);
+	in.mkey = cpu_to_be32(mlx5_mkey_to_idx(mr->key));
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, outlen);
+	if (err)
+		return err;
+
+	if (out->hdr.status)
+		return mlx5_cmd_status_to_err(&out->hdr);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_query_mkey);
+
+int mlx5_core_dump_fill_mkey(struct mlx5_core_dev *dev, struct mlx5_core_mr *mr,
+			     u32 *mkey)
+{
+	struct mlx5_query_special_ctxs_mbox_in in;
+	struct mlx5_query_special_ctxs_mbox_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_SPECIAL_CONTEXTS);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	*mkey = be32_to_cpu(out.dump_fill_mkey);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_dump_fill_mkey);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <asm-generic/kmap_types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include "mlx5_core.h"
+
+enum {
+	MLX5_PAGES_CANT_GIVE	= 0,
+	MLX5_PAGES_GIVE		= 1,
+	MLX5_PAGES_TAKE		= 2
+};
+
+enum {
+	MLX5_BOOT_PAGES		= 1,
+	MLX5_INIT_PAGES		= 2,
+	MLX5_POST_INIT_PAGES	= 3
+};
+
+struct mlx5_pages_req {
+	struct mlx5_core_dev *dev;
+	u32	func_id;
+	s32	npages;
+	struct work_struct work;
+};
+
+struct fw_page {
+	struct rb_node	rb_node;
+	u64		addr;
+	struct page	*page;
+	u16		func_id;
+};
+
+struct mlx5_query_pages_inbox {
+	struct mlx5_inbox_hdr	hdr;
+	u8			rsvd[8];
+};
+
+struct mlx5_query_pages_outbox {
+	struct mlx5_outbox_hdr	hdr;
+	__be16			rsvd;
+	__be16			func_id;
+	__be32			num_pages;
+};
+
+struct mlx5_manage_pages_inbox {
+	struct mlx5_inbox_hdr	hdr;
+	__be16			rsvd;
+	__be16			func_id;
+	__be32			num_entries;
+	__be64			pas[0];
+};
+
+struct mlx5_manage_pages_outbox {
+	struct mlx5_outbox_hdr	hdr;
+	__be32			num_entries;
+	u8			rsvd[4];
+	__be64			pas[0];
+};
+
+static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u16 func_id)
+{
+	struct rb_root *root = &dev->priv.page_root;
+	struct rb_node **new = &root->rb_node;
+	struct rb_node *parent = NULL;
+	struct fw_page *nfp;
+	struct fw_page *tfp;
+
+	while (*new) {
+		parent = *new;
+		tfp = rb_entry(parent, struct fw_page, rb_node);
+		if (tfp->addr < addr)
+			new = &parent->rb_left;
+		else if (tfp->addr > addr)
+			new = &parent->rb_right;
+		else
+			return -EEXIST;
+	}
+
+	nfp = kmalloc(sizeof(*nfp), GFP_KERNEL);
+	if (!nfp)
+		return -ENOMEM;
+
+	nfp->addr = addr;
+	nfp->page = page;
+	nfp->func_id = func_id;
+
+	rb_link_node(&nfp->rb_node, parent, new);
+	rb_insert_color(&nfp->rb_node, root);
+
+	return 0;
+}
+
+static struct page *remove_page(struct mlx5_core_dev *dev, u64 addr)
+{
+	struct rb_root *root = &dev->priv.page_root;
+	struct rb_node *tmp = root->rb_node;
+	struct page *result = NULL;
+	struct fw_page *tfp;
+
+	while (tmp) {
+		tfp = rb_entry(tmp, struct fw_page, rb_node);
+		if (tfp->addr < addr) {
+			tmp = tmp->rb_left;
+		} else if (tfp->addr > addr) {
+			tmp = tmp->rb_right;
+		} else {
+			rb_erase(&tfp->rb_node, root);
+			result = tfp->page;
+			kfree(tfp);
+			break;
+		}
+	}
+
+	return result;
+}
+
+static int mlx5_cmd_query_pages(struct mlx5_core_dev *dev, u16 *func_id,
+				s32 *npages, int boot)
+{
+	struct mlx5_query_pages_inbox	in;
+	struct mlx5_query_pages_outbox	out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_PAGES);
+	in.hdr.opmod = boot ? cpu_to_be16(MLX5_BOOT_PAGES) : cpu_to_be16(MLX5_INIT_PAGES);
+
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	*npages = be32_to_cpu(out.num_pages);
+	*func_id = be16_to_cpu(out.func_id);
+
+	return err;
+}
+
+static int give_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
+		      int notify_fail)
+{
+	struct mlx5_manage_pages_inbox *in;
+	struct mlx5_manage_pages_outbox out;
+	struct page *page;
+	int inlen;
+	u64 addr;
+	int err;
+	int i;
+
+	inlen = sizeof(*in) + npages * sizeof(in->pas[0]);
+	in = mlx5_vzalloc(inlen);
+	if (!in) {
+		mlx5_core_warn(dev, "vzalloc failed %d\n", inlen);
+		return -ENOMEM;
+	}
+	memset(&out, 0, sizeof(out));
+
+	for (i = 0; i < npages; i++) {
+		page = alloc_page(GFP_HIGHUSER);
+		if (!page) {
+			err = -ENOMEM;
+			mlx5_core_warn(dev, "failed to allocate page\n");
+			goto out_alloc;
+		}
+		addr = dma_map_page(&dev->pdev->dev, page, 0,
+				    PAGE_SIZE, DMA_BIDIRECTIONAL);
+		if (dma_mapping_error(&dev->pdev->dev, addr)) {
+			mlx5_core_warn(dev, "failed dma mapping page\n");
+			__free_page(page);
+			err = -ENOMEM;
+			goto out_alloc;
+		}
+		err = insert_page(dev, addr, page, func_id);
+		if (err) {
+			mlx5_core_err(dev, "failed to track allocated page\n");
+			dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
+			__free_page(page);
+			err = -ENOMEM;
+			goto out_alloc;
+		}
+		in->pas[i] = cpu_to_be64(addr);
+	}
+
+	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_MANAGE_PAGES);
+	in->hdr.opmod = cpu_to_be16(MLX5_PAGES_GIVE);
+	in->func_id = cpu_to_be16(func_id);
+	in->num_entries = cpu_to_be32(npages);
+	err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
+	mlx5_core_dbg(dev, "err %d\n", err);
+	if (err) {
+		mlx5_core_warn(dev, "func_id 0x%x, npages %d, err %d\n", func_id, npages, err);
+		goto out_alloc;
+	}
+	dev->priv.fw_pages += npages;
+
+	if (out.hdr.status) {
+		err = mlx5_cmd_status_to_err(&out.hdr);
+		if (err) {
+			mlx5_core_warn(dev, "func_id 0x%x, npages %d, status %d\n", func_id, npages, out.hdr.status);
+			goto out_alloc;
+		}
+	}
+
+	mlx5_core_dbg(dev, "err %d\n", err);
+
+	goto out_free;
+
+out_alloc:
+	if (notify_fail) {
+		memset(in, 0, inlen);
+		memset(&out, 0, sizeof(out));
+		in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_MANAGE_PAGES);
+		in->hdr.opmod = cpu_to_be16(MLX5_PAGES_CANT_GIVE);
+		if (mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out)))
+			mlx5_core_warn(dev, "\n");
+	}
+	for (i--; i >= 0; i--) {
+		addr = be64_to_cpu(in->pas[i]);
+		page = remove_page(dev, addr);
+		if (!page) {
+			mlx5_core_err(dev, "BUG: can't remove page at addr 0x%llx\n",
+				      addr);
+			continue;
+		}
+		dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
+		__free_page(page);
+	}
+
+out_free:
+	mlx5_vfree(in);
+	return err;
+}
+
+static int reclaim_pages(struct mlx5_core_dev *dev, u32 func_id, int npages,
+			 int *nclaimed)
+{
+	struct mlx5_manage_pages_inbox   in;
+	struct mlx5_manage_pages_outbox *out;
+	struct page *page;
+	int num_claimed;
+	int outlen;
+	u64 addr;
+	int err;
+	int i;
+
+	memset(&in, 0, sizeof(in));
+	outlen = sizeof(*out) + npages * sizeof(out->pas[0]);
+	out = mlx5_vzalloc(outlen);
+	if (!out)
+		return -ENOMEM;
+
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_MANAGE_PAGES);
+	in.hdr.opmod = cpu_to_be16(MLX5_PAGES_TAKE);
+	in.func_id = cpu_to_be16(func_id);
+	in.num_entries = cpu_to_be32(npages);
+	mlx5_core_dbg(dev, "npages %d, outlen %d\n", npages, outlen);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, outlen);
+	if (err) {
+		mlx5_core_err(dev, "failed recliaming pages\n");
+		goto out_free;
+	}
+	dev->priv.fw_pages -= npages;
+
+	if (out->hdr.status) {
+		err = mlx5_cmd_status_to_err(&out->hdr);
+		goto out_free;
+	}
+
+	num_claimed = be32_to_cpu(out->num_entries);
+	if (nclaimed)
+		*nclaimed = num_claimed;
+
+	for (i = 0; i < num_claimed; i++) {
+		addr = be64_to_cpu(out->pas[i]);
+		page = remove_page(dev, addr);
+		if (!page) {
+			mlx5_core_warn(dev, "FW reported unknown DMA address 0x%llx\n", addr);
+		} else {
+			dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
+			__free_page(page);
+		}
+	}
+
+out_free:
+	mlx5_vfree(out);
+	return err;
+}
+
+static void pages_work_handler(struct work_struct *work)
+{
+	struct mlx5_pages_req *req = container_of(work, struct mlx5_pages_req, work);
+	struct mlx5_core_dev *dev = req->dev;
+	int err = 0;
+
+	if (req->npages < 0)
+		err = reclaim_pages(dev, req->func_id, -1 * req->npages, NULL);
+	else if (req->npages > 0)
+		err = give_pages(dev, req->func_id, req->npages, 1);
+
+	if (err)
+		mlx5_core_warn(dev, "%s fail %d\n", req->npages < 0 ?
+			       "reclaim" : "give", err);
+
+	kfree(req);
+}
+
+void mlx5_core_req_pages_handler(struct mlx5_core_dev *dev, u16 func_id,
+				 s32 npages)
+{
+	struct mlx5_pages_req *req;
+
+	req = kzalloc(sizeof(*req), GFP_ATOMIC);
+	if (!req) {
+		mlx5_core_warn(dev, "failed to allocate pages request\n");
+		return;
+	}
+
+	req->dev = dev;
+	req->func_id = func_id;
+	req->npages = npages;
+	INIT_WORK(&req->work, pages_work_handler);
+	queue_work(dev->priv.pg_wq, &req->work);
+}
+
+int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot)
+{
+	u16 uninitialized_var(func_id);
+	s32 uninitialized_var(npages);
+	int err;
+
+	err = mlx5_cmd_query_pages(dev, &func_id, &npages, boot);
+	if (err)
+		return err;
+
+	mlx5_core_dbg(dev, "requested %d %s pages for func_id 0x%x\n",
+		      npages, boot ? "boot" : "init", func_id);
+
+	return give_pages(dev, func_id, npages, 0);
+}
+
+static int optimal_reclaimed_pages(void)
+{
+	struct mlx5_cmd_prot_block *block;
+	struct mlx5_cmd_layout *lay;
+	int ret;
+
+	ret = (sizeof(lay->in) + sizeof(block->data) -
+	       sizeof(struct mlx5_manage_pages_outbox)) / 8;
+
+	return ret;
+}
+
+int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev)
+{
+	unsigned long end = jiffies + msecs_to_jiffies(5000);
+	struct fw_page *fwp;
+	struct rb_node *p;
+	int err;
+
+	do {
+		p = rb_first(&dev->priv.page_root);
+		if (p) {
+			fwp = rb_entry(p, struct fw_page, rb_node);
+			err = reclaim_pages(dev, fwp->func_id, optimal_reclaimed_pages(), NULL);
+			if (err) {
+				mlx5_core_warn(dev, "failed reclaiming pages (%d)\n", err);
+				return err;
+			}
+		}
+		if (time_after(jiffies, end)) {
+			mlx5_core_warn(dev, "FW did not return all pages. giving up...\n");
+			break;
+		}
+	} while (p);
+
+	return 0;
+}
+
+void mlx5_pagealloc_init(struct mlx5_core_dev *dev)
+{
+	dev->priv.page_root = RB_ROOT;
+}
+
+void mlx5_pagealloc_cleanup(struct mlx5_core_dev *dev)
+{
+	/* nothing */
+}
+
+int mlx5_pagealloc_start(struct mlx5_core_dev *dev)
+{
+	dev->priv.pg_wq = create_singlethread_workqueue("mlx5_page_allocator");
+	if (!dev->priv.pg_wq)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void mlx5_pagealloc_stop(struct mlx5_core_dev *dev)
+{
+	destroy_workqueue(dev->priv.pg_wq);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/pd.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/pd.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/pd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/pd.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include "mlx5_core.h"
+
+struct mlx5_alloc_pd_mbox_in {
+	struct mlx5_inbox_hdr	hdr;
+	u8			rsvd[8];
+};
+
+struct mlx5_alloc_pd_mbox_out {
+	struct mlx5_outbox_hdr	hdr;
+	__be32			pdn;
+	u8			rsvd[4];
+};
+
+struct mlx5_dealloc_pd_mbox_in {
+	struct mlx5_inbox_hdr	hdr;
+	__be32			pdn;
+	u8			rsvd[4];
+};
+
+struct mlx5_dealloc_pd_mbox_out {
+	struct mlx5_outbox_hdr	hdr;
+	u8			rsvd[8];
+};
+
+int mlx5_core_alloc_pd(struct mlx5_core_dev *dev, u32 *pdn)
+{
+	struct mlx5_alloc_pd_mbox_in	in;
+	struct mlx5_alloc_pd_mbox_out	out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ALLOC_PD);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	*pdn = be32_to_cpu(out.pdn) & 0xffffff;
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_alloc_pd);
+
+int mlx5_core_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn)
+{
+	struct mlx5_dealloc_pd_mbox_in	in;
+	struct mlx5_dealloc_pd_mbox_out	out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DEALLOC_PD);
+	in.pdn = cpu_to_be32(pdn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_dealloc_pd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/port.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/port.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/port.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/port.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include "mlx5_core.h"
+
+int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in,
+			 int size_in, void *data_out, int size_out,
+			 u16 reg_num, int arg, int write)
+{
+	struct mlx5_access_reg_mbox_in *in = NULL;
+	struct mlx5_access_reg_mbox_out *out = NULL;
+	int err = -ENOMEM;
+
+	in = mlx5_vzalloc(sizeof(*in) + size_in);
+	if (!in)
+		return -ENOMEM;
+
+	out = mlx5_vzalloc(sizeof(*out) + size_out);
+	if (!out)
+		goto ex1;
+
+	memcpy(in->data, data_in, size_in);
+	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ACCESS_REG);
+	in->hdr.opmod = cpu_to_be16(!write);
+	in->arg = cpu_to_be32(arg);
+	in->register_id = cpu_to_be16(reg_num);
+	err = mlx5_cmd_exec(dev, in, sizeof(*in) + size_in, out,
+			    sizeof(out) + size_out);
+	if (err)
+		goto ex2;
+
+	if (out->hdr.status)
+		err = mlx5_cmd_status_to_err(&out->hdr);
+
+	if (!err)
+		memcpy(data_out, out->data, size_out);
+
+ex2:
+	mlx5_vfree(out);
+ex1:
+	mlx5_vfree(in);
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_core_access_reg);
+
+
+struct mlx5_reg_pcap {
+	u8			rsvd0;
+	u8			port_num;
+	u8			rsvd1[2];
+	__be32			caps_127_96;
+	__be32			caps_95_64;
+	__be32			caps_63_32;
+	__be32			caps_31_0;
+};
+
+int mlx5_set_port_caps(struct mlx5_core_dev *dev, int port_num, u32 caps)
+{
+	struct mlx5_reg_pcap in;
+	struct mlx5_reg_pcap out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	in.caps_127_96 = cpu_to_be32(caps);
+	in.port_num = port_num;
+
+	err = mlx5_core_access_reg(dev, &in, sizeof(in), &out,
+				   sizeof(out), MLX5_REG_PCAP, 0, 1);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_set_port_caps);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/qp.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/qp.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/qp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/qp.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+
+#include <linux/gfp.h>
+#include <linux/export.h>
+#include <linux/mlx5/cmd.h>
+#include <linux/mlx5/qp.h>
+#include <linux/mlx5/driver.h>
+
+#include "mlx5_core.h"
+
+void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type)
+{
+	struct mlx5_qp_table *table = &dev->priv.qp_table;
+	struct mlx5_core_qp *qp;
+
+	spin_lock(&table->lock);
+
+	qp = radix_tree_lookup(&table->tree, qpn);
+	if (qp)
+		atomic_inc(&qp->refcount);
+
+	spin_unlock(&table->lock);
+
+	if (!qp) {
+		mlx5_core_warn(dev, "Async event for bogus QP 0x%x\n", qpn);
+		return;
+	}
+
+	qp->event(qp, event_type);
+
+	if (atomic_dec_and_test(&qp->refcount))
+		complete(&qp->free);
+}
+
+int mlx5_core_create_qp(struct mlx5_core_dev *dev,
+			struct mlx5_core_qp *qp,
+			struct mlx5_create_qp_mbox_in *in,
+			int inlen)
+{
+	struct mlx5_qp_table *table = &dev->priv.qp_table;
+	struct mlx5_create_qp_mbox_out out;
+	struct mlx5_destroy_qp_mbox_in din;
+	struct mlx5_destroy_qp_mbox_out dout;
+	int err;
+
+	memset(&dout, 0, sizeof(dout));
+	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_QP);
+
+	err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
+	if (err) {
+		mlx5_core_warn(dev, "ret %d", err);
+		return err;
+	}
+
+	if (out.hdr.status) {
+		pr_warn("current num of QPs 0x%x\n", atomic_read(&dev->num_qps));
+		return mlx5_cmd_status_to_err(&out.hdr);
+	}
+
+	qp->qpn = be32_to_cpu(out.qpn) & 0xffffff;
+	mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
+
+	spin_lock_irq(&table->lock);
+	err = radix_tree_insert(&table->tree, qp->qpn, qp);
+	spin_unlock_irq(&table->lock);
+	if (err) {
+		mlx5_core_warn(dev, "err %d", err);
+		goto err_cmd;
+	}
+
+	err = mlx5_debug_qp_add(dev, qp);
+	if (err)
+		mlx5_core_dbg(dev, "failed adding QP 0x%x to debug file system\n",
+			      qp->qpn);
+
+	qp->pid = current->pid;
+	atomic_set(&qp->refcount, 1);
+	atomic_inc(&dev->num_qps);
+	init_completion(&qp->free);
+
+	return 0;
+
+err_cmd:
+	memset(&din, 0, sizeof(din));
+	memset(&dout, 0, sizeof(dout));
+	din.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_QP);
+	din.qpn = cpu_to_be32(qp->qpn);
+	mlx5_cmd_exec(dev, &din, sizeof(din), &out, sizeof(dout));
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_core_create_qp);
+
+int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
+			 struct mlx5_core_qp *qp)
+{
+	struct mlx5_destroy_qp_mbox_in in;
+	struct mlx5_destroy_qp_mbox_out out;
+	struct mlx5_qp_table *table = &dev->priv.qp_table;
+	unsigned long flags;
+	int err;
+
+	mlx5_debug_qp_remove(dev, qp);
+
+	spin_lock_irqsave(&table->lock, flags);
+	radix_tree_delete(&table->tree, qp->qpn);
+	spin_unlock_irqrestore(&table->lock, flags);
+
+	if (atomic_dec_and_test(&qp->refcount))
+		complete(&qp->free);
+	wait_for_completion(&qp->free);
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_QP);
+	in.qpn = cpu_to_be32(qp->qpn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	atomic_dec(&dev->num_qps);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mlx5_core_destroy_qp);
+
+int mlx5_core_qp_modify(struct mlx5_core_dev *dev, enum mlx5_qp_state cur_state,
+			enum mlx5_qp_state new_state,
+			struct mlx5_modify_qp_mbox_in *in, int sqd_event,
+			struct mlx5_core_qp *qp)
+{
+	static const u16 optab[MLX5_QP_NUM_STATE][MLX5_QP_NUM_STATE] = {
+		[MLX5_QP_STATE_RST] = {
+			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,
+			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,
+			[MLX5_QP_STATE_INIT]	= MLX5_CMD_OP_RST2INIT_QP,
+		},
+		[MLX5_QP_STATE_INIT]  = {
+			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,
+			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,
+			[MLX5_QP_STATE_INIT]	= MLX5_CMD_OP_INIT2INIT_QP,
+			[MLX5_QP_STATE_RTR]	= MLX5_CMD_OP_INIT2RTR_QP,
+		},
+		[MLX5_QP_STATE_RTR]   = {
+			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,
+			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,
+			[MLX5_QP_STATE_RTS]	= MLX5_CMD_OP_RTR2RTS_QP,
+		},
+		[MLX5_QP_STATE_RTS]   = {
+			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,
+			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,
+			[MLX5_QP_STATE_RTS]	= MLX5_CMD_OP_RTS2RTS_QP,
+			[MLX5_QP_STATE_SQD]	= MLX5_CMD_OP_RTS2SQD_QP,
+		},
+		[MLX5_QP_STATE_SQD] = {
+			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,
+			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,
+			[MLX5_QP_STATE_RTS]	= MLX5_CMD_OP_SQD2RTS_QP,
+			[MLX5_QP_STATE_SQD]	= MLX5_CMD_OP_SQD2SQD_QP,
+		},
+		[MLX5_QP_STATE_SQER] = {
+			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,
+			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,
+			[MLX5_QP_STATE_RTS]	= MLX5_CMD_OP_SQERR2RTS_QP,
+		},
+		[MLX5_QP_STATE_ERR] = {
+			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,
+			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,
+		}
+	};
+
+	struct mlx5_modify_qp_mbox_out out;
+	int err = 0;
+	u16 op;
+
+	if (cur_state >= MLX5_QP_NUM_STATE || new_state >= MLX5_QP_NUM_STATE ||
+	    !optab[cur_state][new_state])
+		return -EINVAL;
+
+	memset(&out, 0, sizeof(out));
+	op = optab[cur_state][new_state];
+	in->hdr.opcode = cpu_to_be16(op);
+	in->qpn = cpu_to_be32(qp->qpn);
+	err = mlx5_cmd_exec(dev, in, sizeof(*in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	return mlx5_cmd_status_to_err(&out.hdr);
+}
+EXPORT_SYMBOL_GPL(mlx5_core_qp_modify);
+
+void mlx5_init_qp_table(struct mlx5_core_dev *dev)
+{
+	struct mlx5_qp_table *table = &dev->priv.qp_table;
+
+	spin_lock_init(&table->lock);
+	INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
+	mlx5_qp_debugfs_init(dev);
+}
+
+void mlx5_cleanup_qp_table(struct mlx5_core_dev *dev)
+{
+	mlx5_qp_debugfs_cleanup(dev);
+}
+
+int mlx5_core_qp_query(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
+		       struct mlx5_query_qp_mbox_out *out, int outlen)
+{
+	struct mlx5_query_qp_mbox_in in;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(out, 0, outlen);
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_QP);
+	in.qpn = cpu_to_be32(qp->qpn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, outlen);
+	if (err)
+		return err;
+
+	if (out->hdr.status)
+		return mlx5_cmd_status_to_err(&out->hdr);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_core_qp_query);
+
+int mlx5_core_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn)
+{
+	struct mlx5_alloc_xrcd_mbox_in in;
+	struct mlx5_alloc_xrcd_mbox_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ALLOC_XRCD);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		err = mlx5_cmd_status_to_err(&out.hdr);
+	else
+		*xrcdn = be32_to_cpu(out.xrcdn);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_core_xrcd_alloc);
+
+int mlx5_core_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn)
+{
+	struct mlx5_dealloc_xrcd_mbox_in in;
+	struct mlx5_dealloc_xrcd_mbox_out out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DEALLOC_XRCD);
+	in.xrcdn = cpu_to_be32(xrcdn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		err = mlx5_cmd_status_to_err(&out.hdr);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_core_xrcd_dealloc);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/srq.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/srq.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/srq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/srq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include <linux/mlx5/srq.h>
+#include <rdma/ib_verbs.h>
+#include "mlx5_core.h"
+
+void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type)
+{
+	struct mlx5_srq_table *table = &dev->priv.srq_table;
+	struct mlx5_core_srq *srq;
+
+	spin_lock(&table->lock);
+
+	srq = radix_tree_lookup(&table->tree, srqn);
+	if (srq)
+		atomic_inc(&srq->refcount);
+
+	spin_unlock(&table->lock);
+
+	if (!srq) {
+		mlx5_core_warn(dev, "Async event for bogus SRQ 0x%08x\n", srqn);
+		return;
+	}
+
+	srq->event(srq, event_type);
+
+	if (atomic_dec_and_test(&srq->refcount))
+		complete(&srq->free);
+}
+
+struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn)
+{
+	struct mlx5_srq_table *table = &dev->priv.srq_table;
+	struct mlx5_core_srq *srq;
+
+	spin_lock(&table->lock);
+
+	srq = radix_tree_lookup(&table->tree, srqn);
+	if (srq)
+		atomic_inc(&srq->refcount);
+
+	spin_unlock(&table->lock);
+
+	return srq;
+}
+EXPORT_SYMBOL(mlx5_core_get_srq);
+
+int mlx5_core_create_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
+			 struct mlx5_create_srq_mbox_in *in, int inlen)
+{
+	struct mlx5_create_srq_mbox_out out;
+	struct mlx5_srq_table *table = &dev->priv.srq_table;
+	struct mlx5_destroy_srq_mbox_in din;
+	struct mlx5_destroy_srq_mbox_out dout;
+	int err;
+
+	memset(&out, 0, sizeof(out));
+	in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_SRQ);
+	err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	srq->srqn = be32_to_cpu(out.srqn) & 0xffffff;
+
+	atomic_set(&srq->refcount, 1);
+	init_completion(&srq->free);
+
+	spin_lock_irq(&table->lock);
+	err = radix_tree_insert(&table->tree, srq->srqn, srq);
+	spin_unlock_irq(&table->lock);
+	if (err) {
+		mlx5_core_warn(dev, "err %d, srqn 0x%x\n", err, srq->srqn);
+		goto err_cmd;
+	}
+
+	return 0;
+
+err_cmd:
+	memset(&din, 0, sizeof(din));
+	memset(&dout, 0, sizeof(dout));
+	din.srqn = cpu_to_be32(srq->srqn);
+	din.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_SRQ);
+	mlx5_cmd_exec(dev, &din, sizeof(din), &dout, sizeof(dout));
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_create_srq);
+
+int mlx5_core_destroy_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq)
+{
+	struct mlx5_destroy_srq_mbox_in in;
+	struct mlx5_destroy_srq_mbox_out out;
+	struct mlx5_srq_table *table = &dev->priv.srq_table;
+	struct mlx5_core_srq *tmp;
+	int err;
+
+	spin_lock_irq(&table->lock);
+	tmp = radix_tree_delete(&table->tree, srq->srqn);
+	spin_unlock_irq(&table->lock);
+	if (!tmp) {
+		mlx5_core_warn(dev, "srq 0x%x not found in tree\n", srq->srqn);
+		return -EINVAL;
+	}
+	if (tmp != srq) {
+		mlx5_core_warn(dev, "corruption on srqn 0x%x\n", srq->srqn);
+		return -EINVAL;
+	}
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DESTROY_SRQ);
+	in.srqn = cpu_to_be32(srq->srqn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	if (atomic_dec_and_test(&srq->refcount))
+		complete(&srq->free);
+	wait_for_completion(&srq->free);
+
+	return 0;
+}
+EXPORT_SYMBOL(mlx5_core_destroy_srq);
+
+int mlx5_core_query_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
+			struct mlx5_query_srq_mbox_out *out)
+{
+	struct mlx5_query_srq_mbox_in in;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(out, 0, sizeof(*out));
+
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_SRQ);
+	in.srqn = cpu_to_be32(srq->srqn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out));
+	if (err)
+		return err;
+
+	if (out->hdr.status)
+		return mlx5_cmd_status_to_err(&out->hdr);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_query_srq);
+
+int mlx5_core_arm_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
+		      u16 lwm, int is_srq)
+{
+	struct mlx5_arm_srq_mbox_in	in;
+	struct mlx5_arm_srq_mbox_out	out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ARM_RQ);
+	in.hdr.opmod = cpu_to_be16(!!is_srq);
+	in.srqn = cpu_to_be32(srq->srqn);
+	in.lwm = cpu_to_be16(lwm);
+
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		return err;
+
+	if (out.hdr.status)
+		return mlx5_cmd_status_to_err(&out.hdr);
+
+	return err;
+}
+EXPORT_SYMBOL(mlx5_core_arm_srq);
+
+void mlx5_init_srq_table(struct mlx5_core_dev *dev)
+{
+	struct mlx5_srq_table *table = &dev->priv.srq_table;
+
+	spin_lock_init(&table->lock);
+	INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
+}
+
+void mlx5_cleanup_srq_table(struct mlx5_core_dev *dev)
+{
+	/* nothing */
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/uar.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/uar.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/mellanox/mlx5/core/uar.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/uar.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2013, Mellanox Technologies inc.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include <linux/mlx5/cmd.h>
+#include "mlx5_core.h"
+
+enum {
+	NUM_DRIVER_UARS		= 4,
+	NUM_LOW_LAT_UUARS	= 4,
+};
+
+
+struct mlx5_alloc_uar_mbox_in {
+	struct mlx5_inbox_hdr	hdr;
+	u8			rsvd[8];
+};
+
+struct mlx5_alloc_uar_mbox_out {
+	struct mlx5_outbox_hdr	hdr;
+	__be32			uarn;
+	u8			rsvd[4];
+};
+
+struct mlx5_free_uar_mbox_in {
+	struct mlx5_inbox_hdr	hdr;
+	__be32			uarn;
+	u8			rsvd[4];
+};
+
+struct mlx5_free_uar_mbox_out {
+	struct mlx5_outbox_hdr	hdr;
+	u8			rsvd[8];
+};
+
+int mlx5_cmd_alloc_uar(struct mlx5_core_dev *dev, u32 *uarn)
+{
+	struct mlx5_alloc_uar_mbox_in	in;
+	struct mlx5_alloc_uar_mbox_out	out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	memset(&out, 0, sizeof(out));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ALLOC_UAR);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		goto ex;
+
+	if (out.hdr.status) {
+		err = mlx5_cmd_status_to_err(&out.hdr);
+		goto ex;
+	}
+
+	*uarn = be32_to_cpu(out.uarn) & 0xffffff;
+
+ex:
+	return err;
+}
+EXPORT_SYMBOL(mlx5_cmd_alloc_uar);
+
+int mlx5_cmd_free_uar(struct mlx5_core_dev *dev, u32 uarn)
+{
+	struct mlx5_free_uar_mbox_in	in;
+	struct mlx5_free_uar_mbox_out	out;
+	int err;
+
+	memset(&in, 0, sizeof(in));
+	in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DEALLOC_UAR);
+	in.uarn = cpu_to_be32(uarn);
+	err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+	if (err)
+		goto ex;
+
+	if (out.hdr.status)
+		err = mlx5_cmd_status_to_err(&out.hdr);
+
+ex:
+	return err;
+}
+EXPORT_SYMBOL(mlx5_cmd_free_uar);
+
+static int need_uuar_lock(int uuarn)
+{
+	int tot_uuars = NUM_DRIVER_UARS * MLX5_BF_REGS_PER_PAGE;
+
+	if (uuarn == 0 || tot_uuars - NUM_LOW_LAT_UUARS)
+		return 0;
+
+	return 1;
+}
+
+int mlx5_alloc_uuars(struct mlx5_core_dev *dev, struct mlx5_uuar_info *uuari)
+{
+	int tot_uuars = NUM_DRIVER_UARS * MLX5_BF_REGS_PER_PAGE;
+	struct mlx5_bf *bf;
+	phys_addr_t addr;
+	int err;
+	int i;
+
+	uuari->num_uars = NUM_DRIVER_UARS;
+	uuari->num_low_latency_uuars = NUM_LOW_LAT_UUARS;
+
+	mutex_init(&uuari->lock);
+	uuari->uars = kcalloc(uuari->num_uars, sizeof(*uuari->uars), GFP_KERNEL);
+	if (!uuari->uars)
+		return -ENOMEM;
+
+	uuari->bfs = kcalloc(tot_uuars, sizeof(*uuari->bfs), GFP_KERNEL);
+	if (!uuari->bfs) {
+		err = -ENOMEM;
+		goto out_uars;
+	}
+
+	uuari->bitmap = kcalloc(BITS_TO_LONGS(tot_uuars), sizeof(*uuari->bitmap),
+				GFP_KERNEL);
+	if (!uuari->bitmap) {
+		err = -ENOMEM;
+		goto out_bfs;
+	}
+
+	uuari->count = kcalloc(tot_uuars, sizeof(*uuari->count), GFP_KERNEL);
+	if (!uuari->count) {
+		err = -ENOMEM;
+		goto out_bitmap;
+	}
+
+	for (i = 0; i < uuari->num_uars; i++) {
+		err = mlx5_cmd_alloc_uar(dev, &uuari->uars[i].index);
+		if (err)
+			goto out_count;
+
+		addr = dev->iseg_base + ((phys_addr_t)(uuari->uars[i].index) << PAGE_SHIFT);
+		uuari->uars[i].map = ioremap(addr, PAGE_SIZE);
+		if (!uuari->uars[i].map) {
+			mlx5_cmd_free_uar(dev, uuari->uars[i].index);
+			err = -ENOMEM;
+			goto out_count;
+		}
+		mlx5_core_dbg(dev, "allocated uar index 0x%x, mmaped at %p\n",
+			      uuari->uars[i].index, uuari->uars[i].map);
+	}
+
+	for (i = 0; i < tot_uuars; i++) {
+		bf = &uuari->bfs[i];
+
+		bf->buf_size = dev->caps.bf_reg_size / 2;
+		bf->uar = &uuari->uars[i / MLX5_BF_REGS_PER_PAGE];
+		bf->regreg = uuari->uars[i / MLX5_BF_REGS_PER_PAGE].map;
+		bf->reg = NULL; /* Add WC support */
+		bf->offset = (i % MLX5_BF_REGS_PER_PAGE) * dev->caps.bf_reg_size +
+			MLX5_BF_OFFSET;
+		bf->need_lock = need_uuar_lock(i);
+		spin_lock_init(&bf->lock);
+		spin_lock_init(&bf->lock32);
+		bf->uuarn = i;
+	}
+
+	return 0;
+
+out_count:
+	for (i--; i >= 0; i--) {
+		iounmap(uuari->uars[i].map);
+		mlx5_cmd_free_uar(dev, uuari->uars[i].index);
+	}
+	kfree(uuari->count);
+
+out_bitmap:
+	kfree(uuari->bitmap);
+
+out_bfs:
+	kfree(uuari->bfs);
+
+out_uars:
+	kfree(uuari->uars);
+	return err;
+}
+
+int mlx5_free_uuars(struct mlx5_core_dev *dev, struct mlx5_uuar_info *uuari)
+{
+	int i = uuari->num_uars;
+
+	for (i--; i >= 0; i--) {
+		iounmap(uuari->uars[i].map);
+		mlx5_cmd_free_uar(dev, uuari->uars[i].index);
+	}
+
+	kfree(uuari->count);
+	kfree(uuari->bitmap);
+	kfree(uuari->bfs);
+	kfree(uuari->uars);
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/micrel/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/micrel/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/micrel/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/micrel/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@ if NET_VENDOR_MICREL
 config ARM_KS8695_ETHER
 	tristate "KS8695 Ethernet support"
 	depends on ARM && ARCH_KS8695
-	select NET_CORE
 	select MII
 	---help---
 	  If you wish to compile a kernel for the KS8695 and want to
@@ -39,7 +38,6 @@ config KS8842
 config KS8851
 	tristate "Micrel KS8851 SPI"
 	depends on SPI
-	select NET_CORE
 	select MII
 	select CRC32
 	select EEPROM_93CX6
@@ -49,7 +47,6 @@ config KS8851
 config KS8851_MLL
 	tristate "Micrel KS8851 MLL"
 	depends on HAS_IOMEM
-	select NET_CORE
 	select MII
 	---help---
 	  This platform driver is for Micrel KS8851 Address/data bus
@@ -58,7 +55,6 @@ config KS8851_MLL
 config KSZ884X_PCI
 	tristate "Micrel KSZ8841/2 PCI"
 	depends on PCI
-	select NET_CORE
 	select MII
 	select CRC32
 	---help---
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/micrel/ks8695net.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/micrel/ks8695net.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/micrel/ks8695net.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/micrel/ks8695net.c	2013-08-25 20:43:22.000000000 -0400
@@ -1600,7 +1600,6 @@ ks8695_drv_remove(struct platform_device
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct ks8695_priv *ksp = netdev_priv(ndev);
 
-	platform_set_drvdata(pdev, NULL);
 	netif_napi_del(&ksp->napi);
 
 	unregister_netdev(ndev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/micrel/ks8842.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/micrel/ks8842.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/micrel/ks8842.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/micrel/ks8842.c	2013-08-25 20:43:22.000000000 -0400
@@ -1250,7 +1250,6 @@ static int ks8842_remove(struct platform
 	iounmap(adapter->hw_addr);
 	free_netdev(netdev);
 	release_mem_region(iomem->start, resource_size(iomem));
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/micrel/ks8851_mll.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/micrel/ks8851_mll.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/micrel/ks8851_mll.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/micrel/ks8851_mll.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,9 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/ks8851_mll.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_net.h>
 
 #define	DRV_NAME	"ks8851_mll"
 
@@ -1524,6 +1527,13 @@ static int ks_hw_init(struct ks_net *ks)
 	return true;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id ks8851_ml_dt_ids[] = {
+	{ .compatible = "micrel,ks8851-mll" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ks8851_ml_dt_ids);
+#endif
 
 static int ks8851_probe(struct platform_device *pdev)
 {
@@ -1532,7 +1542,7 @@ static int ks8851_probe(struct platform_
 	struct net_device *netdev;
 	struct ks_net *ks;
 	u16 id, data;
-	struct ks8851_mll_platform_data *pdata;
+	const char *mac;
 
 	io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -1619,13 +1629,21 @@ static int ks8851_probe(struct platform_
 	ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA);
 
 	/* overwriting the default MAC address */
-	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		netdev_err(netdev, "No platform data\n");
-		err = -ENODEV;
-		goto err_pdata;
+	if (pdev->dev.of_node) {
+		mac = of_get_mac_address(pdev->dev.of_node);
+		if (mac)
+			memcpy(ks->mac_addr, mac, ETH_ALEN);
+	} else {
+		struct ks8851_mll_platform_data *pdata;
+
+		pdata = pdev->dev.platform_data;
+		if (!pdata) {
+			netdev_err(netdev, "No platform data\n");
+			err = -ENODEV;
+			goto err_pdata;
+		}
+		memcpy(ks->mac_addr, pdata->mac_addr, ETH_ALEN);
 	}
-	memcpy(ks->mac_addr, pdata->mac_addr, 6);
 	if (!is_valid_ether_addr(ks->mac_addr)) {
 		/* Use random MAC address if none passed */
 		eth_random_addr(ks->mac_addr);
@@ -1671,7 +1689,6 @@ static int ks8851_remove(struct platform
 	iounmap(ks->hw_addr);
 	free_netdev(netdev);
 	release_mem_region(iomem->start, resource_size(iomem));
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 
 }
@@ -1680,6 +1697,7 @@ static struct platform_driver ks8851_pla
 	.driver = {
 		.name = DRV_NAME,
 		.owner = THIS_MODULE,
+		.of_match_table	= of_match_ptr(ks8851_ml_dt_ids),
 	},
 	.probe = ks8851_probe,
 	.remove = ks8851_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/myricom/myri10ge/myri10ge.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/myricom/myri10ge/myri10ge.c	2013-07-01 10:36:53.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/myricom/myri10ge/myri10ge.c	2013-08-31 17:56:25.000000000 -0400
@@ -3289,7 +3289,7 @@ static int myri10ge_resume(struct pci_de
 	if (mgp == NULL)
 		return -EINVAL;
 	netdev = mgp->dev;
-	pci_set_power_state(pdev, 0);	/* zeros conf space as a side effect */
+	pci_set_power_state(pdev, PCI_D0);	/* zeros conf space as a side effect */
 	msleep(5);		/* give card time to respond */
 	pci_read_config_word(mgp->pdev, PCI_VENDOR_ID, &vendor);
 	if (vendor == 0xffff) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/neterion/vxge/vxge-main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/neterion/vxge/vxge-main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/neterion/vxge/vxge-main.c	2013-07-01 10:37:36.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/neterion/vxge/vxge-main.c	2013-08-31 17:57:10.000000000 -0400
@@ -3444,7 +3444,7 @@ static int vxge_device_register(struct _
 	}
 
 	vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
-		"%s : checksuming enabled", __func__);
+		"%s : checksumming enabled", __func__);
 
 	if (high_dma) {
 		ndev->features |= NETIF_F_HIGHDMA;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/netx-eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/netx-eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/netx-eth.c	2013-07-01 10:31:31.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/netx-eth.c	2013-08-31 17:50:50.000000000 -0400
@@ -422,7 +422,6 @@ exit_free_pfifo:
 exit_free_xc:
 	free_xc(priv->xc);
 exit_free_netdev:
-	platform_set_drvdata(pdev, NULL);
 	free_netdev(ndev);
 exit:
 	return ret;
@@ -430,11 +429,9 @@ exit:
 
 static int netx_eth_drv_remove(struct platform_device *pdev)
 {
-	struct net_device *ndev = dev_get_drvdata(&pdev->dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct netx_eth_priv *priv = netdev_priv(ndev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	unregister_netdev(ndev);
 	xc_stop(priv->xc);
 	free_xc(priv->xc);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/nuvoton/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/nuvoton/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/nuvoton/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/nuvoton/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@ config W90P910_ETH
 	tristate "Nuvoton w90p910 Ethernet support"
 	depends on ARM && ARCH_W90X900
 	select PHYLIB
-	select NET_CORE
 	select MII
 	---help---
 	  Say Y here if you want to use built-in Ethernet ports
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/nuvoton/w90p910_ether.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/nuvoton/w90p910_ether.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/nuvoton/w90p910_ether.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/nuvoton/w90p910_ether.c	2013-08-25 20:43:22.000000000 -0400
@@ -1051,7 +1051,6 @@ failed_put_clk:
 	clk_put(ether->clk);
 failed_free_rxirq:
 	free_irq(ether->rxirq, pdev);
-	platform_set_drvdata(pdev, NULL);
 failed_free_txirq:
 	free_irq(ether->txirq, pdev);
 failed_free_io:
@@ -1080,7 +1079,6 @@ static int w90p910_ether_remove(struct p
 	free_irq(ether->rxirq, dev);
 
 	del_timer_sync(&ether->check_timer);
-	platform_set_drvdata(pdev, NULL);
 
 	free_netdev(dev);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/nvidia/forcedeth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/nvidia/forcedeth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/nvidia/forcedeth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/nvidia/forcedeth.c	2013-08-25 20:43:22.000000000 -0400
@@ -6340,7 +6340,7 @@ static DEFINE_PCI_DEVICE_TABLE(pci_tbl)
 	{0,},
 };
 
-static struct pci_driver driver = {
+static struct pci_driver forcedeth_pci_driver = {
 	.name		= DRV_NAME,
 	.id_table	= pci_tbl,
 	.probe		= nv_probe,
@@ -6349,16 +6349,6 @@ static struct pci_driver driver = {
 	.driver.pm	= NV_PM_OPS,
 };
 
-static int __init init_nic(void)
-{
-	return pci_register_driver(&driver);
-}
-
-static void __exit exit_nic(void)
-{
-	pci_unregister_driver(&driver);
-}
-
 module_param(max_interrupt_work, int, 0);
 MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
 module_param(optimization_mode, int, 0);
@@ -6379,11 +6369,8 @@ module_param(debug_tx_timeout, bool, 0);
 MODULE_PARM_DESC(debug_tx_timeout,
 		 "Dump tx related registers and ring when tx_timeout happens");
 
+module_pci_driver(forcedeth_pci_driver);
 MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
 MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
 MODULE_LICENSE("GPL");
-
 MODULE_DEVICE_TABLE(pci, pci_tbl);
-
-module_init(init_nic);
-module_exit(exit_nic);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/nxp/lpc_eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/nxp/lpc_eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/nxp/lpc_eth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/nxp/lpc_eth.c	2013-08-25 20:43:22.000000000 -0400
@@ -1483,7 +1483,6 @@ static int lpc_eth_drv_probe(struct plat
 	return 0;
 
 err_out_unregister_netdev:
-	platform_set_drvdata(pdev, NULL);
 	unregister_netdev(ndev);
 err_out_dma_unmap:
 	if (!use_iram_for_net(&pldat->pdev->dev) ||
@@ -1511,7 +1510,6 @@ static int lpc_eth_drv_remove(struct pla
 	struct netdata_local *pldat = netdev_priv(ndev);
 
 	unregister_netdev(ndev);
-	platform_set_drvdata(pdev, NULL);
 
 	if (!use_iram_for_net(&pldat->pdev->dev) ||
 	    pldat->dma_buff_size > lpc32xx_return_iram_size())
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/octeon/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/octeon/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/octeon/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/octeon/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,7 @@
 
 config OCTEON_MGMT_ETHERNET
 	tristate "Octeon Management port ethernet driver (CN5XXX, CN6XXX)"
-	depends on  CPU_CAVIUM_OCTEON
+	depends on CAVIUM_OCTEON_SOC
 	select PHYLIB
 	select MDIO_OCTEON
 	default y
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/octeon/octeon_mgmt.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/octeon/octeon_mgmt.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/octeon/octeon_mgmt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/octeon/octeon_mgmt.c	2013-08-25 20:43:22.000000000 -0400
@@ -1448,7 +1448,7 @@ static int octeon_mgmt_probe(struct plat
 
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 
-	dev_set_drvdata(&pdev->dev, netdev);
+	platform_set_drvdata(pdev, netdev);
 	p = netdev_priv(netdev);
 	netif_napi_add(netdev, &p->napi, octeon_mgmt_napi_poll,
 		       OCTEON_MGMT_NAPI_WEIGHT);
@@ -1570,7 +1570,7 @@ err:
 
 static int octeon_mgmt_remove(struct platform_device *pdev)
 {
-	struct net_device *netdev = dev_get_drvdata(&pdev->dev);
+	struct net_device *netdev = platform_get_drvdata(pdev);
 
 	unregister_netdev(netdev);
 	free_netdev(netdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -4,8 +4,7 @@
 
 config PCH_GBE
 	tristate "OKI SEMICONDUCTOR IOH(ML7223/ML7831) GbE"
-	depends on PCI
-	select NET_CORE
+	depends on PCI && (X86 || COMPILE_TEST)
 	select MII
 	select PTP_1588_CLOCK_PCH
 	---help---
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,7 @@
  */
 #include "pch_gbe.h"
 #include "pch_gbe_phy.h"
+#include "pch_gbe_api.h"
 
 /* bus type values */
 #define pch_gbe_bus_type_unknown	0
@@ -70,7 +71,9 @@ static s32 pch_gbe_plat_init_hw(struct p
 
 	ret_val = pch_gbe_phy_get_id(hw);
 	if (ret_val) {
-		pr_err("pch_gbe_phy_get_id error\n");
+		struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
+
+		netdev_err(adapter->netdev, "pch_gbe_phy_get_id error\n");
 		return ret_val;
 	}
 	pch_gbe_phy_init_setting(hw);
@@ -112,10 +115,12 @@ static void pch_gbe_plat_init_function_p
  *	0:	Successfully
  *	ENOSYS:	Function is not registered
  */
-inline s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw)
+s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw)
 {
 	if (!hw->reg) {
-		pr_err("ERROR: Registers not mapped\n");
+		struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
+
+		netdev_err(adapter->netdev, "ERROR: Registers not mapped\n");
 		return -ENOSYS;
 	}
 	pch_gbe_plat_init_function_pointers(hw);
@@ -126,12 +131,15 @@ inline s32 pch_gbe_hal_setup_init_funcs(
  * pch_gbe_hal_get_bus_info - Obtain bus information for adapter
  * @hw:	Pointer to the HW structure
  */
-inline void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw)
+void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw)
 {
-	if (!hw->func->get_bus_info)
-		pr_err("ERROR: configuration\n");
-	else
-		hw->func->get_bus_info(hw);
+	if (!hw->func->get_bus_info) {
+		struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
+
+		netdev_err(adapter->netdev, "ERROR: configuration\n");
+		return;
+	}
+	hw->func->get_bus_info(hw);
 }
 
 /**
@@ -141,10 +149,12 @@ inline void pch_gbe_hal_get_bus_info(str
  *	0:	Successfully
  *	ENOSYS:	Function is not registered
  */
-inline s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw)
+s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw)
 {
 	if (!hw->func->init_hw) {
-		pr_err("ERROR: configuration\n");
+		struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
+
+		netdev_err(adapter->netdev, "ERROR: configuration\n");
 		return -ENOSYS;
 	}
 	return hw->func->init_hw(hw);
@@ -159,7 +169,7 @@ inline s32 pch_gbe_hal_init_hw(struct pc
  *	0:	Successfully
  *	Negative value:	Failed
  */
-inline s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset,
+s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset,
 					u16 *data)
 {
 	if (!hw->func->read_phy_reg)
@@ -176,7 +186,7 @@ inline s32 pch_gbe_hal_read_phy_reg(stru
  *	0:	Successfully
  *	Negative value:	Failed
  */
-inline s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset,
+s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset,
 					u16 data)
 {
 	if (!hw->func->write_phy_reg)
@@ -188,24 +198,30 @@ inline s32 pch_gbe_hal_write_phy_reg(str
  * pch_gbe_hal_phy_hw_reset - Hard PHY reset
  * @hw:	    Pointer to the HW structure
  */
-inline void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw)
+void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw)
 {
-	if (!hw->func->reset_phy)
-		pr_err("ERROR: configuration\n");
-	else
-		hw->func->reset_phy(hw);
+	if (!hw->func->reset_phy) {
+		struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
+
+		netdev_err(adapter->netdev, "ERROR: configuration\n");
+		return;
+	}
+	hw->func->reset_phy(hw);
 }
 
 /**
  * pch_gbe_hal_phy_sw_reset - Soft PHY reset
  * @hw:	    Pointer to the HW structure
  */
-inline void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw)
+void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw)
 {
-	if (!hw->func->sw_reset_phy)
-		pr_err("ERROR: configuration\n");
-	else
-		hw->func->sw_reset_phy(hw);
+	if (!hw->func->sw_reset_phy) {
+		struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
+
+		netdev_err(adapter->netdev, "ERROR: configuration\n");
+		return;
+	}
+	hw->func->sw_reset_phy(hw);
 }
 
 /**
@@ -215,10 +231,12 @@ inline void pch_gbe_hal_phy_sw_reset(str
  *	0:	Successfully
  *	ENOSYS:	Function is not registered
  */
-inline s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw)
+s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw)
 {
 	if (!hw->func->read_mac_addr) {
-		pr_err("ERROR: configuration\n");
+		struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
+
+		netdev_err(adapter->netdev, "ERROR: configuration\n");
 		return -ENOSYS;
 	}
 	return hw->func->read_mac_addr(hw);
@@ -228,7 +246,7 @@ inline s32 pch_gbe_hal_read_mac_addr(str
  * pch_gbe_hal_power_up_phy - Power up PHY
  * @hw:	Pointer to the HW structure
  */
-inline void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw)
+void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw)
 {
 	if (hw->func->power_up_phy)
 		hw->func->power_up_phy(hw);
@@ -238,7 +256,7 @@ inline void pch_gbe_hal_power_up_phy(str
  * pch_gbe_hal_power_down_phy - Power down PHY
  * @hw:	Pointer to the HW structure
  */
-inline void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw)
+void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw)
 {
 	if (hw->func->power_down_phy)
 		hw->func->power_down_phy(hw);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -122,7 +122,7 @@ static int pch_gbe_set_settings(struct n
 	}
 	ret = mii_ethtool_sset(&adapter->mii, ecmd);
 	if (ret) {
-		pr_err("Error: mii_ethtool_sset\n");
+		netdev_err(netdev, "Error: mii_ethtool_sset\n");
 		return ret;
 	}
 	hw->mac.link_speed = speed;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h	2013-08-25 20:43:22.000000000 -0400
@@ -633,6 +633,8 @@ struct pch_gbe_adapter {
 	struct pci_dev *ptp_pdev;
 };
 
+#define pch_gbe_hw_to_adapter(hw)	container_of(hw, struct pch_gbe_adapter, hw)
+
 extern const char pch_driver_version[];
 
 /* pch_gbe_main.c */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -287,7 +287,7 @@ static int hwtstamp_ioctl(struct net_dev
 	return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
 }
 
-inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw)
+static inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw)
 {
 	iowrite32(0x01, &hw->reg->MAC_ADDR_LOAD);
 }
@@ -300,6 +300,7 @@ inline void pch_gbe_mac_load_mac_addr(st
  */
 s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw)
 {
+	struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 	u32  adr1a, adr1b;
 
 	adr1a = ioread32(&hw->reg->mac_adr[0].high);
@@ -312,7 +313,7 @@ s32 pch_gbe_mac_read_mac_addr(struct pch
 	hw->mac.addr[4] = (u8)(adr1b & 0xFF);
 	hw->mac.addr[5] = (u8)((adr1b >> 8) & 0xFF);
 
-	pr_debug("hw->mac.addr : %pM\n", hw->mac.addr);
+	netdev_dbg(adapter->netdev, "hw->mac.addr : %pM\n", hw->mac.addr);
 	return 0;
 }
 
@@ -324,6 +325,7 @@ s32 pch_gbe_mac_read_mac_addr(struct pch
 static void pch_gbe_wait_clr_bit(void *reg, u32 bit)
 {
 	u32 tmp;
+
 	/* wait busy */
 	tmp = 1000;
 	while ((ioread32(reg) & bit) && --tmp)
@@ -340,9 +342,10 @@ static void pch_gbe_wait_clr_bit(void *r
  */
 static void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index)
 {
+	struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 	u32 mar_low, mar_high, adrmask;
 
-	pr_debug("index : 0x%x\n", index);
+	netdev_dbg(adapter->netdev, "index : 0x%x\n", index);
 
 	/*
 	 * HW expects these in little endian so we reverse the byte order
@@ -468,10 +471,11 @@ static void pch_gbe_mac_mc_addr_list_upd
  */
 s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw)
 {
+	struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 	struct pch_gbe_mac_info *mac = &hw->mac;
 	u32 rx_fctrl;
 
-	pr_debug("mac->fc = %u\n", mac->fc);
+	netdev_dbg(adapter->netdev, "mac->fc = %u\n", mac->fc);
 
 	rx_fctrl = ioread32(&hw->reg->RX_FCTRL);
 
@@ -493,14 +497,16 @@ s32 pch_gbe_mac_force_mac_fc(struct pch_
 		mac->tx_fc_enable = true;
 		break;
 	default:
-		pr_err("Flow control param set incorrectly\n");
+		netdev_err(adapter->netdev,
+			   "Flow control param set incorrectly\n");
 		return -EINVAL;
 	}
 	if (mac->link_duplex == DUPLEX_HALF)
 		rx_fctrl &= ~PCH_GBE_FL_CTRL_EN;
 	iowrite32(rx_fctrl, &hw->reg->RX_FCTRL);
-	pr_debug("RX_FCTRL reg : 0x%08x  mac->tx_fc_enable : %d\n",
-		 ioread32(&hw->reg->RX_FCTRL), mac->tx_fc_enable);
+	netdev_dbg(adapter->netdev,
+		   "RX_FCTRL reg : 0x%08x  mac->tx_fc_enable : %d\n",
+		   ioread32(&hw->reg->RX_FCTRL), mac->tx_fc_enable);
 	return 0;
 }
 
@@ -511,10 +517,11 @@ s32 pch_gbe_mac_force_mac_fc(struct pch_
  */
 static void pch_gbe_mac_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt)
 {
+	struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 	u32 addr_mask;
 
-	pr_debug("wu_evt : 0x%08x  ADDR_MASK reg : 0x%08x\n",
-		 wu_evt, ioread32(&hw->reg->ADDR_MASK));
+	netdev_dbg(adapter->netdev, "wu_evt : 0x%08x  ADDR_MASK reg : 0x%08x\n",
+		   wu_evt, ioread32(&hw->reg->ADDR_MASK));
 
 	if (wu_evt) {
 		/* Set Wake-On-Lan address mask */
@@ -546,6 +553,7 @@ static void pch_gbe_mac_set_wol_event(st
 u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg,
 			u16 data)
 {
+	struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 	u32 data_out = 0;
 	unsigned int i;
 	unsigned long flags;
@@ -558,7 +566,7 @@ u16 pch_gbe_mac_ctrl_miim(struct pch_gbe
 		udelay(20);
 	}
 	if (i == 0) {
-		pr_err("pch-gbe.miim won't go Ready\n");
+		netdev_err(adapter->netdev, "pch-gbe.miim won't go Ready\n");
 		spin_unlock_irqrestore(&hw->miim_lock, flags);
 		return 0;	/* No way to indicate timeout error */
 	}
@@ -573,9 +581,9 @@ u16 pch_gbe_mac_ctrl_miim(struct pch_gbe
 	}
 	spin_unlock_irqrestore(&hw->miim_lock, flags);
 
-	pr_debug("PHY %s: reg=%d, data=0x%04X\n",
-		 dir == PCH_GBE_MIIM_OPER_READ ? "READ" : "WRITE", reg,
-		 dir == PCH_GBE_MIIM_OPER_READ ? data_out : data);
+	netdev_dbg(adapter->netdev, "PHY %s: reg=%d, data=0x%04X\n",
+		   dir == PCH_GBE_MIIM_OPER_READ ? "READ" : "WRITE", reg,
+		   dir == PCH_GBE_MIIM_OPER_READ ? data_out : data);
 	return (u16) data_out;
 }
 
@@ -585,6 +593,7 @@ u16 pch_gbe_mac_ctrl_miim(struct pch_gbe
  */
 static void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw)
 {
+	struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 	unsigned long tmp2, tmp3;
 
 	/* Set Pause packet */
@@ -606,10 +615,13 @@ static void pch_gbe_mac_set_pause_packet
 	/* Transmit Pause Packet */
 	iowrite32(PCH_GBE_PS_PKT_RQ, &hw->reg->PAUSE_REQ);
 
-	pr_debug("PAUSE_PKT1-5 reg : 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
-		 ioread32(&hw->reg->PAUSE_PKT1), ioread32(&hw->reg->PAUSE_PKT2),
-		 ioread32(&hw->reg->PAUSE_PKT3), ioread32(&hw->reg->PAUSE_PKT4),
-		 ioread32(&hw->reg->PAUSE_PKT5));
+	netdev_dbg(adapter->netdev,
+		   "PAUSE_PKT1-5 reg : 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
+		   ioread32(&hw->reg->PAUSE_PKT1),
+		   ioread32(&hw->reg->PAUSE_PKT2),
+		   ioread32(&hw->reg->PAUSE_PKT3),
+		   ioread32(&hw->reg->PAUSE_PKT4),
+		   ioread32(&hw->reg->PAUSE_PKT5));
 
 	return;
 }
@@ -624,15 +636,15 @@ static void pch_gbe_mac_set_pause_packet
  */
 static int pch_gbe_alloc_queues(struct pch_gbe_adapter *adapter)
 {
-	adapter->tx_ring = kzalloc(sizeof(*adapter->tx_ring), GFP_KERNEL);
+	adapter->tx_ring = devm_kzalloc(&adapter->pdev->dev,
+					sizeof(*adapter->tx_ring), GFP_KERNEL);
 	if (!adapter->tx_ring)
 		return -ENOMEM;
 
-	adapter->rx_ring = kzalloc(sizeof(*adapter->rx_ring), GFP_KERNEL);
-	if (!adapter->rx_ring) {
-		kfree(adapter->tx_ring);
+	adapter->rx_ring = devm_kzalloc(&adapter->pdev->dev,
+					sizeof(*adapter->rx_ring), GFP_KERNEL);
+	if (!adapter->rx_ring)
 		return -ENOMEM;
-	}
 	return 0;
 }
 
@@ -669,7 +681,7 @@ static int pch_gbe_init_phy(struct pch_g
 			break;
 	}
 	adapter->hw.phy.addr = adapter->mii.phy_id;
-	pr_debug("phy_addr = %d\n", adapter->mii.phy_id);
+	netdev_dbg(netdev, "phy_addr = %d\n", adapter->mii.phy_id);
 	if (addr == 32)
 		return -EAGAIN;
 	/* Selected the phy and isolate the rest */
@@ -758,13 +770,15 @@ void pch_gbe_reinit_locked(struct pch_gb
  */
 void pch_gbe_reset(struct pch_gbe_adapter *adapter)
 {
+	struct net_device *netdev = adapter->netdev;
+
 	pch_gbe_mac_reset_hw(&adapter->hw);
 	/* reprogram multicast address register after reset */
-	pch_gbe_set_multi(adapter->netdev);
+	pch_gbe_set_multi(netdev);
 	/* Setup the receive address. */
 	pch_gbe_mac_init_rx_addrs(&adapter->hw, PCH_GBE_MAR_ENTRIES);
 	if (pch_gbe_hal_init_hw(&adapter->hw))
-		pr_err("Hardware Error\n");
+		netdev_err(netdev, "Hardware Error\n");
 }
 
 /**
@@ -778,7 +792,7 @@ static void pch_gbe_free_irq(struct pch_
 	free_irq(adapter->pdev->irq, netdev);
 	if (adapter->have_msi) {
 		pci_disable_msi(adapter->pdev);
-		pr_debug("call pci_disable_msi\n");
+		netdev_dbg(netdev, "call pci_disable_msi\n");
 	}
 }
 
@@ -795,7 +809,8 @@ static void pch_gbe_irq_disable(struct p
 	ioread32(&hw->reg->INT_ST);
 	synchronize_irq(adapter->pdev->irq);
 
-	pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN));
+	netdev_dbg(adapter->netdev, "INT_EN reg : 0x%08x\n",
+		   ioread32(&hw->reg->INT_EN));
 }
 
 /**
@@ -809,7 +824,8 @@ static void pch_gbe_irq_enable(struct pc
 	if (likely(atomic_dec_and_test(&adapter->irq_sem)))
 		iowrite32(PCH_GBE_INT_ENABLE_MASK, &hw->reg->INT_EN);
 	ioread32(&hw->reg->INT_ST);
-	pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN));
+	netdev_dbg(adapter->netdev, "INT_EN reg : 0x%08x\n",
+		   ioread32(&hw->reg->INT_EN));
 }
 
 
@@ -846,9 +862,9 @@ static void pch_gbe_configure_tx(struct
 	struct pch_gbe_hw *hw = &adapter->hw;
 	u32 tdba, tdlen, dctrl;
 
-	pr_debug("dma addr = 0x%08llx  size = 0x%08x\n",
-		 (unsigned long long)adapter->tx_ring->dma,
-		 adapter->tx_ring->size);
+	netdev_dbg(adapter->netdev, "dma addr = 0x%08llx  size = 0x%08x\n",
+		   (unsigned long long)adapter->tx_ring->dma,
+		   adapter->tx_ring->size);
 
 	/* Setup the HW Tx Head and Tail descriptor pointers */
 	tdba = adapter->tx_ring->dma;
@@ -894,9 +910,9 @@ static void pch_gbe_configure_rx(struct
 	struct pch_gbe_hw *hw = &adapter->hw;
 	u32 rdba, rdlen, rxdma;
 
-	pr_debug("dma adr = 0x%08llx  size = 0x%08x\n",
-		 (unsigned long long)adapter->rx_ring->dma,
-		 adapter->rx_ring->size);
+	netdev_dbg(adapter->netdev, "dma adr = 0x%08llx  size = 0x%08x\n",
+		   (unsigned long long)adapter->rx_ring->dma,
+		   adapter->rx_ring->size);
 
 	pch_gbe_mac_force_mac_fc(hw);
 
@@ -907,9 +923,10 @@ static void pch_gbe_configure_rx(struct
 	rxdma &= ~PCH_GBE_RX_DMA_EN;
 	iowrite32(rxdma, &hw->reg->DMA_CTRL);
 
-	pr_debug("MAC_RX_EN reg = 0x%08x  DMA_CTRL reg = 0x%08x\n",
-		 ioread32(&hw->reg->MAC_RX_EN),
-		 ioread32(&hw->reg->DMA_CTRL));
+	netdev_dbg(adapter->netdev,
+		   "MAC_RX_EN reg = 0x%08x  DMA_CTRL reg = 0x%08x\n",
+		   ioread32(&hw->reg->MAC_RX_EN),
+		   ioread32(&hw->reg->DMA_CTRL));
 
 	/* Setup the HW Rx Head and Tail Descriptor Pointers and
 	 * the Base and Length of the Rx Descriptor Ring */
@@ -977,7 +994,8 @@ static void pch_gbe_clean_tx_ring(struct
 		buffer_info = &tx_ring->buffer_info[i];
 		pch_gbe_unmap_and_free_tx_resource(adapter, buffer_info);
 	}
-	pr_debug("call pch_gbe_unmap_and_free_tx_resource() %d count\n", i);
+	netdev_dbg(adapter->netdev,
+		   "call pch_gbe_unmap_and_free_tx_resource() %d count\n", i);
 
 	size = (unsigned long)sizeof(struct pch_gbe_buffer) * tx_ring->count;
 	memset(tx_ring->buffer_info, 0, size);
@@ -1009,7 +1027,8 @@ pch_gbe_clean_rx_ring(struct pch_gbe_ada
 		buffer_info = &rx_ring->buffer_info[i];
 		pch_gbe_unmap_and_free_rx_resource(adapter, buffer_info);
 	}
-	pr_debug("call pch_gbe_unmap_and_free_rx_resource() %d count\n", i);
+	netdev_dbg(adapter->netdev,
+		   "call pch_gbe_unmap_and_free_rx_resource() %d count\n", i);
 	size = (unsigned long)sizeof(struct pch_gbe_buffer) * rx_ring->count;
 	memset(rx_ring->buffer_info, 0, size);
 
@@ -1087,7 +1106,7 @@ static void pch_gbe_watchdog(unsigned lo
 	struct net_device *netdev = adapter->netdev;
 	struct pch_gbe_hw *hw = &adapter->hw;
 
-	pr_debug("right now = %ld\n", jiffies);
+	netdev_dbg(netdev, "right now = %ld\n", jiffies);
 
 	pch_gbe_update_stats(adapter);
 	if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) {
@@ -1095,7 +1114,7 @@ static void pch_gbe_watchdog(unsigned lo
 		netdev->tx_queue_len = adapter->tx_queue_len;
 		/* mii library handles link maintenance tasks */
 		if (mii_ethtool_gset(&adapter->mii, &cmd)) {
-			pr_err("ethtool get setting Error\n");
+			netdev_err(netdev, "ethtool get setting Error\n");
 			mod_timer(&adapter->watchdog_timer,
 				  round_jiffies(jiffies +
 						PCH_GBE_WATCHDOG_PERIOD));
@@ -1213,7 +1232,7 @@ static void pch_gbe_tx_queue(struct pch_
 					  buffer_info->length,
 					  DMA_TO_DEVICE);
 	if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) {
-		pr_err("TX DMA map failed\n");
+		netdev_err(adapter->netdev, "TX DMA map failed\n");
 		buffer_info->dma = 0;
 		buffer_info->time_stamp = 0;
 		tx_ring->next_to_use = ring_num;
@@ -1333,13 +1352,13 @@ static irqreturn_t pch_gbe_intr(int irq,
 	/* When request status is no interruption factor */
 	if (unlikely(!int_st))
 		return IRQ_NONE;	/* Not our interrupt. End processing. */
-	pr_debug("%s occur int_st = 0x%08x\n", __func__, int_st);
+	netdev_dbg(netdev, "%s occur int_st = 0x%08x\n", __func__, int_st);
 	if (int_st & PCH_GBE_INT_RX_FRAME_ERR)
 		adapter->stats.intr_rx_frame_err_count++;
 	if (int_st & PCH_GBE_INT_RX_FIFO_ERR)
 		if (!adapter->rx_stop_flag) {
 			adapter->stats.intr_rx_fifo_err_count++;
-			pr_debug("Rx fifo over run\n");
+			netdev_dbg(netdev, "Rx fifo over run\n");
 			adapter->rx_stop_flag = true;
 			int_en = ioread32(&hw->reg->INT_EN);
 			iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR),
@@ -1359,7 +1378,7 @@ static irqreturn_t pch_gbe_intr(int irq,
 	/* When Rx descriptor is empty  */
 	if ((int_st & PCH_GBE_INT_RX_DSC_EMP)) {
 		adapter->stats.intr_rx_dsc_empty_count++;
-		pr_debug("Rx descriptor is empty\n");
+		netdev_dbg(netdev, "Rx descriptor is empty\n");
 		int_en = ioread32(&hw->reg->INT_EN);
 		iowrite32((int_en & ~PCH_GBE_INT_RX_DSC_EMP), &hw->reg->INT_EN);
 		if (hw->mac.tx_fc_enable) {
@@ -1382,8 +1401,8 @@ static irqreturn_t pch_gbe_intr(int irq,
 			__napi_schedule(&adapter->napi);
 		}
 	}
-	pr_debug("return = 0x%08x  INT_EN reg = 0x%08x\n",
-		 IRQ_HANDLED, ioread32(&hw->reg->INT_EN));
+	netdev_dbg(netdev, "return = 0x%08x  INT_EN reg = 0x%08x\n",
+		   IRQ_HANDLED, ioread32(&hw->reg->INT_EN));
 	return IRQ_HANDLED;
 }
 
@@ -1437,9 +1456,10 @@ pch_gbe_alloc_rx_buffers(struct pch_gbe_
 		rx_desc->buffer_addr = (buffer_info->dma);
 		rx_desc->gbec_status = DSC_INIT16;
 
-		pr_debug("i = %d  buffer_info->dma = 0x08%llx  buffer_info->length = 0x%x\n",
-			 i, (unsigned long long)buffer_info->dma,
-			 buffer_info->length);
+		netdev_dbg(netdev,
+			   "i = %d  buffer_info->dma = 0x08%llx  buffer_info->length = 0x%x\n",
+			   i, (unsigned long long)buffer_info->dma,
+			   buffer_info->length);
 
 		if (unlikely(++i == rx_ring->count))
 			i = 0;
@@ -1531,12 +1551,13 @@ pch_gbe_clean_tx(struct pch_gbe_adapter
 	bool cleaned = false;
 	int unused, thresh;
 
-	pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
+	netdev_dbg(adapter->netdev, "next_to_clean : %d\n",
+		   tx_ring->next_to_clean);
 
 	i = tx_ring->next_to_clean;
 	tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);
-	pr_debug("gbec_status:0x%04x  dma_status:0x%04x\n",
-		 tx_desc->gbec_status, tx_desc->dma_status);
+	netdev_dbg(adapter->netdev, "gbec_status:0x%04x  dma_status:0x%04x\n",
+		   tx_desc->gbec_status, tx_desc->dma_status);
 
 	unused = PCH_GBE_DESC_UNUSED(tx_ring);
 	thresh = tx_ring->count - PCH_GBE_TX_WEIGHT;
@@ -1544,8 +1565,10 @@ pch_gbe_clean_tx(struct pch_gbe_adapter
 	{  /* current marked clean, tx queue filling up, do extra clean */
 		int j, k;
 		if (unused < 8) {  /* tx queue nearly full */
-			pr_debug("clean_tx: transmit queue warning (%x,%x) unused=%d\n",
-				tx_ring->next_to_clean,tx_ring->next_to_use,unused);
+			netdev_dbg(adapter->netdev,
+				   "clean_tx: transmit queue warning (%x,%x) unused=%d\n",
+				   tx_ring->next_to_clean, tx_ring->next_to_use,
+				   unused);
 		}
 
 		/* current marked clean, scan for more that need cleaning. */
@@ -1557,49 +1580,56 @@ pch_gbe_clean_tx(struct pch_gbe_adapter
 			if (++k >= tx_ring->count) k = 0;  /*increment, wrap*/
 		}
 		if (j < PCH_GBE_TX_WEIGHT) {
-			pr_debug("clean_tx: unused=%d loops=%d found tx_desc[%x,%x:%x].gbec_status=%04x\n",
-				unused,j, i,k, tx_ring->next_to_use, tx_desc->gbec_status);
+			netdev_dbg(adapter->netdev,
+				   "clean_tx: unused=%d loops=%d found tx_desc[%x,%x:%x].gbec_status=%04x\n",
+				   unused, j, i, k, tx_ring->next_to_use,
+				   tx_desc->gbec_status);
 			i = k;  /*found one to clean, usu gbec_status==2000.*/
 		}
 	}
 
 	while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) {
-		pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status);
+		netdev_dbg(adapter->netdev, "gbec_status:0x%04x\n",
+			   tx_desc->gbec_status);
 		buffer_info = &tx_ring->buffer_info[i];
 		skb = buffer_info->skb;
 		cleaned = true;
 
 		if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_ABT)) {
 			adapter->stats.tx_aborted_errors++;
-			pr_err("Transfer Abort Error\n");
+			netdev_err(adapter->netdev, "Transfer Abort Error\n");
 		} else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CRSER)
 			  ) {
 			adapter->stats.tx_carrier_errors++;
-			pr_err("Transfer Carrier Sense Error\n");
+			netdev_err(adapter->netdev,
+				   "Transfer Carrier Sense Error\n");
 		} else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_EXCOL)
 			  ) {
 			adapter->stats.tx_aborted_errors++;
-			pr_err("Transfer Collision Abort Error\n");
+			netdev_err(adapter->netdev,
+				   "Transfer Collision Abort Error\n");
 		} else if ((tx_desc->gbec_status &
 			    (PCH_GBE_TXD_GMAC_STAT_SNGCOL |
 			     PCH_GBE_TXD_GMAC_STAT_MLTCOL))) {
 			adapter->stats.collisions++;
 			adapter->stats.tx_packets++;
 			adapter->stats.tx_bytes += skb->len;
-			pr_debug("Transfer Collision\n");
+			netdev_dbg(adapter->netdev, "Transfer Collision\n");
 		} else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CMPLT)
 			  ) {
 			adapter->stats.tx_packets++;
 			adapter->stats.tx_bytes += skb->len;
 		}
 		if (buffer_info->mapped) {
-			pr_debug("unmap buffer_info->dma : %d\n", i);
+			netdev_dbg(adapter->netdev,
+				   "unmap buffer_info->dma : %d\n", i);
 			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
 					 buffer_info->length, DMA_TO_DEVICE);
 			buffer_info->mapped = false;
 		}
 		if (buffer_info->skb) {
-			pr_debug("trim buffer_info->skb : %d\n", i);
+			netdev_dbg(adapter->netdev,
+				   "trim buffer_info->skb : %d\n", i);
 			skb_trim(buffer_info->skb, 0);
 		}
 		tx_desc->gbec_status = DSC_INIT16;
@@ -1613,8 +1643,9 @@ pch_gbe_clean_tx(struct pch_gbe_adapter
 			break;
 		}
 	}
-	pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n",
-		 cleaned_count);
+	netdev_dbg(adapter->netdev,
+		   "called pch_gbe_unmap_and_free_tx_resource() %d count\n",
+		   cleaned_count);
 	if (cleaned_count > 0)  { /*skip this if nothing cleaned*/
 		/* Recover from running out of Tx resources in xmit_frame */
 		spin_lock(&tx_ring->tx_lock);
@@ -1622,12 +1653,13 @@ pch_gbe_clean_tx(struct pch_gbe_adapter
 		{
 			netif_wake_queue(adapter->netdev);
 			adapter->stats.tx_restart_count++;
-			pr_debug("Tx wake queue\n");
+			netdev_dbg(adapter->netdev, "Tx wake queue\n");
 		}
 
 		tx_ring->next_to_clean = i;
 
-		pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
+		netdev_dbg(adapter->netdev, "next_to_clean : %d\n",
+			   tx_ring->next_to_clean);
 		spin_unlock(&tx_ring->tx_lock);
 	}
 	return cleaned;
@@ -1684,22 +1716,22 @@ pch_gbe_clean_rx(struct pch_gbe_adapter
 				   buffer_info->length, DMA_FROM_DEVICE);
 		buffer_info->mapped = false;
 
-		pr_debug("RxDecNo = 0x%04x  Status[DMA:0x%02x GBE:0x%04x "
-			 "TCP:0x%08x]  BufInf = 0x%p\n",
-			 i, dma_status, gbec_status, tcp_ip_status,
-			 buffer_info);
+		netdev_dbg(netdev,
+			   "RxDecNo = 0x%04x  Status[DMA:0x%02x GBE:0x%04x TCP:0x%08x]  BufInf = 0x%p\n",
+			   i, dma_status, gbec_status, tcp_ip_status,
+			   buffer_info);
 		/* Error check */
 		if (unlikely(gbec_status & PCH_GBE_RXD_GMAC_STAT_NOTOCTAL)) {
 			adapter->stats.rx_frame_errors++;
-			pr_err("Receive Not Octal Error\n");
+			netdev_err(netdev, "Receive Not Octal Error\n");
 		} else if (unlikely(gbec_status &
 				PCH_GBE_RXD_GMAC_STAT_NBLERR)) {
 			adapter->stats.rx_frame_errors++;
-			pr_err("Receive Nibble Error\n");
+			netdev_err(netdev, "Receive Nibble Error\n");
 		} else if (unlikely(gbec_status &
 				PCH_GBE_RXD_GMAC_STAT_CRCERR)) {
 			adapter->stats.rx_crc_errors++;
-			pr_err("Receive CRC Error\n");
+			netdev_err(netdev, "Receive CRC Error\n");
 		} else {
 			/* get receive length */
 			/* length convert[-3], length includes FCS length */
@@ -1730,8 +1762,9 @@ pch_gbe_clean_rx(struct pch_gbe_adapter
 
 			napi_gro_receive(&adapter->napi, skb);
 			(*work_done)++;
-			pr_debug("Receive skb->ip_summed: %d length: %d\n",
-				 skb->ip_summed, length);
+			netdev_dbg(netdev,
+				   "Receive skb->ip_summed: %d length: %d\n",
+				   skb->ip_summed, length);
 		}
 		/* return some buffers to hardware, one at a time is too slow */
 		if (unlikely(cleaned_count >= PCH_GBE_RX_BUFFER_WRITE)) {
@@ -1787,10 +1820,10 @@ int pch_gbe_setup_tx_resources(struct pc
 		tx_desc = PCH_GBE_TX_DESC(*tx_ring, desNo);
 		tx_desc->gbec_status = DSC_INIT16;
 	}
-	pr_debug("tx_ring->desc = 0x%p  tx_ring->dma = 0x%08llx\n"
-		 "next_to_clean = 0x%08x  next_to_use = 0x%08x\n",
-		 tx_ring->desc, (unsigned long long)tx_ring->dma,
-		 tx_ring->next_to_clean, tx_ring->next_to_use);
+	netdev_dbg(adapter->netdev,
+		   "tx_ring->desc = 0x%p  tx_ring->dma = 0x%08llx next_to_clean = 0x%08x  next_to_use = 0x%08x\n",
+		   tx_ring->desc, (unsigned long long)tx_ring->dma,
+		   tx_ring->next_to_clean, tx_ring->next_to_use);
 	return 0;
 }
 
@@ -1829,10 +1862,10 @@ int pch_gbe_setup_rx_resources(struct pc
 		rx_desc = PCH_GBE_RX_DESC(*rx_ring, desNo);
 		rx_desc->gbec_status = DSC_INIT16;
 	}
-	pr_debug("rx_ring->desc = 0x%p  rx_ring->dma = 0x%08llx "
-		 "next_to_clean = 0x%08x  next_to_use = 0x%08x\n",
-		 rx_ring->desc, (unsigned long long)rx_ring->dma,
-		 rx_ring->next_to_clean, rx_ring->next_to_use);
+	netdev_dbg(adapter->netdev,
+		   "rx_ring->desc = 0x%p  rx_ring->dma = 0x%08llx next_to_clean = 0x%08x  next_to_use = 0x%08x\n",
+		   rx_ring->desc, (unsigned long long)rx_ring->dma,
+		   rx_ring->next_to_clean, rx_ring->next_to_use);
 	return 0;
 }
 
@@ -1886,9 +1919,9 @@ static int pch_gbe_request_irq(struct pc
 	flags = IRQF_SHARED;
 	adapter->have_msi = false;
 	err = pci_enable_msi(adapter->pdev);
-	pr_debug("call pci_enable_msi\n");
+	netdev_dbg(netdev, "call pci_enable_msi\n");
 	if (err) {
-		pr_debug("call pci_enable_msi - Error: %d\n", err);
+		netdev_dbg(netdev, "call pci_enable_msi - Error: %d\n", err);
 	} else {
 		flags = 0;
 		adapter->have_msi = true;
@@ -1896,9 +1929,11 @@ static int pch_gbe_request_irq(struct pc
 	err = request_irq(adapter->pdev->irq, &pch_gbe_intr,
 			  flags, netdev->name, netdev);
 	if (err)
-		pr_err("Unable to allocate interrupt Error: %d\n", err);
-	pr_debug("adapter->have_msi : %d  flags : 0x%04x  return : 0x%04x\n",
-		 adapter->have_msi, flags, err);
+		netdev_err(netdev, "Unable to allocate interrupt Error: %d\n",
+			   err);
+	netdev_dbg(netdev,
+		   "adapter->have_msi : %d  flags : 0x%04x  return : 0x%04x\n",
+		   adapter->have_msi, flags, err);
 	return err;
 }
 
@@ -1919,7 +1954,7 @@ int pch_gbe_up(struct pch_gbe_adapter *a
 
 	/* Ensure we have a valid MAC */
 	if (!is_valid_ether_addr(adapter->hw.mac.addr)) {
-		pr_err("Error: Invalid MAC address\n");
+		netdev_err(netdev, "Error: Invalid MAC address\n");
 		goto out;
 	}
 
@@ -1933,12 +1968,14 @@ int pch_gbe_up(struct pch_gbe_adapter *a
 
 	err = pch_gbe_request_irq(adapter);
 	if (err) {
-		pr_err("Error: can't bring device up - irq request failed\n");
+		netdev_err(netdev,
+			   "Error: can't bring device up - irq request failed\n");
 		goto out;
 	}
 	err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count);
 	if (err) {
-		pr_err("Error: can't bring device up - alloc rx buffers pool failed\n");
+		netdev_err(netdev,
+			   "Error: can't bring device up - alloc rx buffers pool failed\n");
 		goto freeirq;
 	}
 	pch_gbe_alloc_tx_buffers(adapter, tx_ring);
@@ -2015,11 +2052,11 @@ static int pch_gbe_sw_init(struct pch_gb
 
 	/* Initialize the hardware-specific values */
 	if (pch_gbe_hal_setup_init_funcs(hw)) {
-		pr_err("Hardware Initialization Failure\n");
+		netdev_err(netdev, "Hardware Initialization Failure\n");
 		return -EIO;
 	}
 	if (pch_gbe_alloc_queues(adapter)) {
-		pr_err("Unable to allocate memory for queues\n");
+		netdev_err(netdev, "Unable to allocate memory for queues\n");
 		return -ENOMEM;
 	}
 	spin_lock_init(&adapter->hw.miim_lock);
@@ -2030,9 +2067,10 @@ static int pch_gbe_sw_init(struct pch_gb
 
 	pch_gbe_init_stats(adapter);
 
-	pr_debug("rx_buffer_len : %d  mac.min_frame_size : %d  mac.max_frame_size : %d\n",
-		 (u32) adapter->rx_buffer_len,
-		 hw->mac.min_frame_size, hw->mac.max_frame_size);
+	netdev_dbg(netdev,
+		   "rx_buffer_len : %d  mac.min_frame_size : %d  mac.max_frame_size : %d\n",
+		   (u32) adapter->rx_buffer_len,
+		   hw->mac.min_frame_size, hw->mac.max_frame_size);
 	return 0;
 }
 
@@ -2061,7 +2099,7 @@ static int pch_gbe_open(struct net_devic
 	err = pch_gbe_up(adapter);
 	if (err)
 		goto err_up;
-	pr_debug("Success End\n");
+	netdev_dbg(netdev, "Success End\n");
 	return 0;
 
 err_up:
@@ -2072,7 +2110,7 @@ err_setup_rx:
 	pch_gbe_free_tx_resources(adapter, adapter->tx_ring);
 err_setup_tx:
 	pch_gbe_reset(adapter);
-	pr_err("Error End\n");
+	netdev_err(netdev, "Error End\n");
 	return err;
 }
 
@@ -2116,8 +2154,9 @@ static int pch_gbe_xmit_frame(struct sk_
 	if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) {
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
-		pr_debug("Return : BUSY  next_to use : 0x%08x  next_to clean : 0x%08x\n",
-			 tx_ring->next_to_use, tx_ring->next_to_clean);
+		netdev_dbg(netdev,
+			   "Return : BUSY  next_to use : 0x%08x  next_to clean : 0x%08x\n",
+			   tx_ring->next_to_use, tx_ring->next_to_clean);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -2152,7 +2191,7 @@ static void pch_gbe_set_multi(struct net
 	int i;
 	int mc_count;
 
-	pr_debug("netdev->flags : 0x%08x\n", netdev->flags);
+	netdev_dbg(netdev, "netdev->flags : 0x%08x\n", netdev->flags);
 
 	/* Check for Promiscuous and All Multicast modes */
 	rctl = ioread32(&hw->reg->RX_MODE);
@@ -2192,7 +2231,8 @@ static void pch_gbe_set_multi(struct net
 					PCH_GBE_MAR_ENTRIES);
 	kfree(mta_list);
 
-	pr_debug("RX_MODE reg(check bit31,30 ADD,MLT) : 0x%08x  netdev->mc_count : 0x%08x\n",
+	netdev_dbg(netdev,
+		 "RX_MODE reg(check bit31,30 ADD,MLT) : 0x%08x  netdev->mc_count : 0x%08x\n",
 		 ioread32(&hw->reg->RX_MODE), mc_count);
 }
 
@@ -2218,12 +2258,12 @@ static int pch_gbe_set_mac(struct net_de
 		pch_gbe_mac_mar_set(&adapter->hw, adapter->hw.mac.addr, 0);
 		ret_val = 0;
 	}
-	pr_debug("ret_val : 0x%08x\n", ret_val);
-	pr_debug("dev_addr : %pM\n", netdev->dev_addr);
-	pr_debug("mac_addr : %pM\n", adapter->hw.mac.addr);
-	pr_debug("MAC_ADR1AB reg : 0x%08x 0x%08x\n",
-		 ioread32(&adapter->hw.reg->mac_adr[0].high),
-		 ioread32(&adapter->hw.reg->mac_adr[0].low));
+	netdev_dbg(netdev, "ret_val : 0x%08x\n", ret_val);
+	netdev_dbg(netdev, "dev_addr : %pM\n", netdev->dev_addr);
+	netdev_dbg(netdev, "mac_addr : %pM\n", adapter->hw.mac.addr);
+	netdev_dbg(netdev, "MAC_ADR1AB reg : 0x%08x 0x%08x\n",
+		   ioread32(&adapter->hw.reg->mac_adr[0].high),
+		   ioread32(&adapter->hw.reg->mac_adr[0].low));
 	return ret_val;
 }
 
@@ -2245,7 +2285,7 @@ static int pch_gbe_change_mtu(struct net
 	max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 	if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
 		(max_frame > PCH_GBE_MAX_JUMBO_FRAME_SIZE)) {
-		pr_err("Invalid MTU setting\n");
+		netdev_err(netdev, "Invalid MTU setting\n");
 		return -EINVAL;
 	}
 	if (max_frame <= PCH_GBE_FRAME_SIZE_2048)
@@ -2274,9 +2314,10 @@ static int pch_gbe_change_mtu(struct net
 		adapter->hw.mac.max_frame_size = max_frame;
 	}
 
-	pr_debug("max_frame : %d  rx_buffer_len : %d  mtu : %d  max_frame_size : %d\n",
-		 max_frame, (u32) adapter->rx_buffer_len, netdev->mtu,
-		 adapter->hw.mac.max_frame_size);
+	netdev_dbg(netdev,
+		   "max_frame : %d  rx_buffer_len : %d  mtu : %d  max_frame_size : %d\n",
+		   max_frame, (u32) adapter->rx_buffer_len, netdev->mtu,
+		   adapter->hw.mac.max_frame_size);
 	return 0;
 }
 
@@ -2317,7 +2358,7 @@ static int pch_gbe_ioctl(struct net_devi
 {
 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 
-	pr_debug("cmd : 0x%04x\n", cmd);
+	netdev_dbg(netdev, "cmd : 0x%04x\n", cmd);
 
 	if (cmd == SIOCSHWTSTAMP)
 		return hwtstamp_ioctl(netdev, ifr, cmd);
@@ -2354,7 +2395,7 @@ static int pch_gbe_napi_poll(struct napi
 	bool poll_end_flag = false;
 	bool cleaned = false;
 
-	pr_debug("budget : %d\n", budget);
+	netdev_dbg(adapter->netdev, "budget : %d\n", budget);
 
 	pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);
 	cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
@@ -2377,8 +2418,9 @@ static int pch_gbe_napi_poll(struct napi
 		pch_gbe_enable_dma_rx(&adapter->hw);
 	}
 
-	pr_debug("poll_end_flag : %d  work_done : %d  budget : %d\n",
-		 poll_end_flag, work_done, budget);
+	netdev_dbg(adapter->netdev,
+		   "poll_end_flag : %d  work_done : %d  budget : %d\n",
+		   poll_end_flag, work_done, budget);
 
 	return work_done;
 }
@@ -2435,7 +2477,7 @@ static pci_ers_result_t pch_gbe_io_slot_
 	struct pch_gbe_hw *hw = &adapter->hw;
 
 	if (pci_enable_device(pdev)) {
-		pr_err("Cannot re-enable PCI device after reset\n");
+		netdev_err(netdev, "Cannot re-enable PCI device after reset\n");
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 	pci_set_master(pdev);
@@ -2455,7 +2497,8 @@ static void pch_gbe_io_resume(struct pci
 
 	if (netif_running(netdev)) {
 		if (pch_gbe_up(adapter)) {
-			pr_debug("can't bring device back up after reset\n");
+			netdev_dbg(netdev,
+				   "can't bring device back up after reset\n");
 			return;
 		}
 	}
@@ -2509,7 +2552,7 @@ static int pch_gbe_resume(struct device
 
 	err = pci_enable_device(pdev);
 	if (err) {
-		pr_err("Cannot enable PCI device from suspend\n");
+		netdev_err(netdev, "Cannot enable PCI device from suspend\n");
 		return err;
 	}
 	pci_set_master(pdev);
@@ -2545,13 +2588,7 @@ static void pch_gbe_remove(struct pci_de
 
 	pch_gbe_hal_phy_hw_reset(&adapter->hw);
 
-	kfree(adapter->tx_ring);
-	kfree(adapter->rx_ring);
-
-	iounmap(adapter->hw.reg);
-	pci_release_regions(pdev);
 	free_netdev(netdev);
-	pci_disable_device(pdev);
 }
 
 static int pch_gbe_probe(struct pci_dev *pdev,
@@ -2561,7 +2598,7 @@ static int pch_gbe_probe(struct pci_dev
 	struct pch_gbe_adapter *adapter;
 	int ret;
 
-	ret = pci_enable_device(pdev);
+	ret = pcim_enable_device(pdev);
 	if (ret)
 		return ret;
 
@@ -2574,24 +2611,22 @@ static int pch_gbe_probe(struct pci_dev
 			if (ret) {
 				dev_err(&pdev->dev, "ERR: No usable DMA "
 					"configuration, aborting\n");
-				goto err_disable_device;
+				return ret;
 			}
 		}
 	}
 
-	ret = pci_request_regions(pdev, KBUILD_MODNAME);
+	ret = pcim_iomap_regions(pdev, 1 << PCH_GBE_PCI_BAR, pci_name(pdev));
 	if (ret) {
 		dev_err(&pdev->dev,
 			"ERR: Can't reserve PCI I/O and memory resources\n");
-		goto err_disable_device;
+		return ret;
 	}
 	pci_set_master(pdev);
 
 	netdev = alloc_etherdev((int)sizeof(struct pch_gbe_adapter));
-	if (!netdev) {
-		ret = -ENOMEM;
-		goto err_release_pci;
-	}
+	if (!netdev)
+		return -ENOMEM;
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 
 	pci_set_drvdata(pdev, netdev);
@@ -2599,18 +2634,14 @@ static int pch_gbe_probe(struct pci_dev
 	adapter->netdev = netdev;
 	adapter->pdev = pdev;
 	adapter->hw.back = adapter;
-	adapter->hw.reg = pci_iomap(pdev, PCH_GBE_PCI_BAR, 0);
-	if (!adapter->hw.reg) {
-		ret = -EIO;
-		dev_err(&pdev->dev, "Can't ioremap\n");
-		goto err_free_netdev;
-	}
+	adapter->hw.reg = pcim_iomap_table(pdev)[PCH_GBE_PCI_BAR];
 
 	adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number,
 					       PCI_DEVFN(12, 4));
 	if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) {
-		pr_err("Bad ptp filter\n");
-		return -EINVAL;
+		dev_err(&pdev->dev, "Bad ptp filter\n");
+		ret = -EINVAL;
+		goto err_free_netdev;
 	}
 
 	netdev->netdev_ops = &pch_gbe_netdev_ops;
@@ -2628,7 +2659,7 @@ static int pch_gbe_probe(struct pci_dev
 	/* setup the private structure */
 	ret = pch_gbe_sw_init(adapter);
 	if (ret)
-		goto err_iounmap;
+		goto err_free_netdev;
 
 	/* Initialize PHY */
 	ret = pch_gbe_init_phy(adapter);
@@ -2684,16 +2715,8 @@ static int pch_gbe_probe(struct pci_dev
 
 err_free_adapter:
 	pch_gbe_hal_phy_hw_reset(&adapter->hw);
-	kfree(adapter->tx_ring);
-	kfree(adapter->rx_ring);
-err_iounmap:
-	iounmap(adapter->hw.reg);
 err_free_netdev:
 	free_netdev(netdev);
-err_release_pci:
-	pci_release_regions(pdev);
-err_disable_device:
-	pci_disable_device(pdev);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c	2013-08-25 20:43:22.000000000 -0400
@@ -237,16 +237,17 @@ static int pch_gbe_validate_option(int *
 	case enable_option:
 		switch (*value) {
 		case OPTION_ENABLED:
-			pr_debug("%s Enabled\n", opt->name);
+			netdev_dbg(adapter->netdev, "%s Enabled\n", opt->name);
 			return 0;
 		case OPTION_DISABLED:
-			pr_debug("%s Disabled\n", opt->name);
+			netdev_dbg(adapter->netdev, "%s Disabled\n", opt->name);
 			return 0;
 		}
 		break;
 	case range_option:
 		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
-			pr_debug("%s set to %i\n", opt->name, *value);
+			netdev_dbg(adapter->netdev, "%s set to %i\n",
+				   opt->name, *value);
 			return 0;
 		}
 		break;
@@ -258,7 +259,8 @@ static int pch_gbe_validate_option(int *
 			ent = &opt->arg.l.p[i];
 			if (*value == ent->i) {
 				if (ent->str[0] != '\0')
-					pr_debug("%s\n", ent->str);
+					netdev_dbg(adapter->netdev, "%s\n",
+						   ent->str);
 				return 0;
 			}
 		}
@@ -268,8 +270,8 @@ static int pch_gbe_validate_option(int *
 		BUG();
 	}
 
-	pr_debug("Invalid %s value specified (%i) %s\n",
-		 opt->name, *value, opt->err);
+	netdev_dbg(adapter->netdev, "Invalid %s value specified (%i) %s\n",
+		   opt->name, *value, opt->err);
 	*value = opt->def;
 	return -1;
 }
@@ -318,7 +320,8 @@ static void pch_gbe_check_copper_options
 					 .p = an_list} }
 		};
 		if (speed || dplx) {
-			pr_debug("AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n");
+			netdev_dbg(adapter->netdev,
+				   "AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n");
 			hw->phy.autoneg_advertised = opt.def;
 		} else {
 			int tmp = AutoNeg;
@@ -332,13 +335,16 @@ static void pch_gbe_check_copper_options
 	case 0:
 		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
 		if ((speed || dplx))
-			pr_debug("Speed and duplex autonegotiation enabled\n");
+			netdev_dbg(adapter->netdev,
+				   "Speed and duplex autonegotiation enabled\n");
 		hw->mac.link_speed = SPEED_10;
 		hw->mac.link_duplex = DUPLEX_HALF;
 		break;
 	case HALF_DUPLEX:
-		pr_debug("Half Duplex specified without Speed\n");
-		pr_debug("Using Autonegotiation at Half Duplex only\n");
+		netdev_dbg(adapter->netdev,
+			   "Half Duplex specified without Speed\n");
+		netdev_dbg(adapter->netdev,
+			   "Using Autonegotiation at Half Duplex only\n");
 		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
 		hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
 						PHY_ADVERTISE_100_HALF;
@@ -346,8 +352,10 @@ static void pch_gbe_check_copper_options
 		hw->mac.link_duplex = DUPLEX_HALF;
 		break;
 	case FULL_DUPLEX:
-		pr_debug("Full Duplex specified without Speed\n");
-		pr_debug("Using Autonegotiation at Full Duplex only\n");
+		netdev_dbg(adapter->netdev,
+			   "Full Duplex specified without Speed\n");
+		netdev_dbg(adapter->netdev,
+			   "Using Autonegotiation at Full Duplex only\n");
 		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
 		hw->phy.autoneg_advertised = PHY_ADVERTISE_10_FULL |
 						PHY_ADVERTISE_100_FULL |
@@ -356,8 +364,10 @@ static void pch_gbe_check_copper_options
 		hw->mac.link_duplex = DUPLEX_FULL;
 		break;
 	case SPEED_10:
-		pr_debug("10 Mbps Speed specified without Duplex\n");
-		pr_debug("Using Autonegotiation at 10 Mbps only\n");
+		netdev_dbg(adapter->netdev,
+			   "10 Mbps Speed specified without Duplex\n");
+		netdev_dbg(adapter->netdev,
+			   "Using Autonegotiation at 10 Mbps only\n");
 		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
 		hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF |
 						PHY_ADVERTISE_10_FULL;
@@ -365,22 +375,24 @@ static void pch_gbe_check_copper_options
 		hw->mac.link_duplex = DUPLEX_HALF;
 		break;
 	case SPEED_10 + HALF_DUPLEX:
-		pr_debug("Forcing to 10 Mbps Half Duplex\n");
+		netdev_dbg(adapter->netdev, "Forcing to 10 Mbps Half Duplex\n");
 		hw->mac.autoneg = hw->mac.fc_autoneg = 0;
 		hw->phy.autoneg_advertised = 0;
 		hw->mac.link_speed = SPEED_10;
 		hw->mac.link_duplex = DUPLEX_HALF;
 		break;
 	case SPEED_10 + FULL_DUPLEX:
-		pr_debug("Forcing to 10 Mbps Full Duplex\n");
+		netdev_dbg(adapter->netdev, "Forcing to 10 Mbps Full Duplex\n");
 		hw->mac.autoneg = hw->mac.fc_autoneg = 0;
 		hw->phy.autoneg_advertised = 0;
 		hw->mac.link_speed = SPEED_10;
 		hw->mac.link_duplex = DUPLEX_FULL;
 		break;
 	case SPEED_100:
-		pr_debug("100 Mbps Speed specified without Duplex\n");
-		pr_debug("Using Autonegotiation at 100 Mbps only\n");
+		netdev_dbg(adapter->netdev,
+			   "100 Mbps Speed specified without Duplex\n");
+		netdev_dbg(adapter->netdev,
+			   "Using Autonegotiation at 100 Mbps only\n");
 		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
 		hw->phy.autoneg_advertised = PHY_ADVERTISE_100_HALF |
 						PHY_ADVERTISE_100_FULL;
@@ -388,28 +400,33 @@ static void pch_gbe_check_copper_options
 		hw->mac.link_duplex = DUPLEX_HALF;
 		break;
 	case SPEED_100 + HALF_DUPLEX:
-		pr_debug("Forcing to 100 Mbps Half Duplex\n");
+		netdev_dbg(adapter->netdev,
+			   "Forcing to 100 Mbps Half Duplex\n");
 		hw->mac.autoneg = hw->mac.fc_autoneg = 0;
 		hw->phy.autoneg_advertised = 0;
 		hw->mac.link_speed = SPEED_100;
 		hw->mac.link_duplex = DUPLEX_HALF;
 		break;
 	case SPEED_100 + FULL_DUPLEX:
-		pr_debug("Forcing to 100 Mbps Full Duplex\n");
+		netdev_dbg(adapter->netdev,
+			   "Forcing to 100 Mbps Full Duplex\n");
 		hw->mac.autoneg = hw->mac.fc_autoneg = 0;
 		hw->phy.autoneg_advertised = 0;
 		hw->mac.link_speed = SPEED_100;
 		hw->mac.link_duplex = DUPLEX_FULL;
 		break;
 	case SPEED_1000:
-		pr_debug("1000 Mbps Speed specified without Duplex\n");
+		netdev_dbg(adapter->netdev,
+			   "1000 Mbps Speed specified without Duplex\n");
 		goto full_duplex_only;
 	case SPEED_1000 + HALF_DUPLEX:
-		pr_debug("Half Duplex is not supported at 1000 Mbps\n");
+		netdev_dbg(adapter->netdev,
+			   "Half Duplex is not supported at 1000 Mbps\n");
 		/* fall through */
 	case SPEED_1000 + FULL_DUPLEX:
 full_duplex_only:
-		pr_debug("Using Autonegotiation at 1000 Mbps Full Duplex only\n");
+		netdev_dbg(adapter->netdev,
+			   "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
 		hw->mac.autoneg = hw->mac.fc_autoneg = 1;
 		hw->phy.autoneg_advertised = PHY_ADVERTISE_1000_FULL;
 		hw->mac.link_speed = SPEED_1000;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c	2013-08-25 20:43:22.000000000 -0400
@@ -97,6 +97,7 @@
  */
 s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw)
 {
+	struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 	struct pch_gbe_phy_info *phy = &hw->phy;
 	s32 ret;
 	u16 phy_id1;
@@ -115,8 +116,9 @@ s32 pch_gbe_phy_get_id(struct pch_gbe_hw
 	phy->id = (u32)phy_id1;
 	phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10));
 	phy->revision = (u32) (phy_id2 & 0x000F);
-	pr_debug("phy->id : 0x%08x  phy->revision : 0x%08x\n",
-		 phy->id, phy->revision);
+	netdev_dbg(adapter->netdev,
+		   "phy->id : 0x%08x  phy->revision : 0x%08x\n",
+		   phy->id, phy->revision);
 	return 0;
 }
 
@@ -134,7 +136,10 @@ s32 pch_gbe_phy_read_reg_miic(struct pch
 	struct pch_gbe_phy_info *phy = &hw->phy;
 
 	if (offset > PHY_MAX_REG_ADDRESS) {
-		pr_err("PHY Address %d is out of range\n", offset);
+		struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
+
+		netdev_err(adapter->netdev, "PHY Address %d is out of range\n",
+			   offset);
 		return -EINVAL;
 	}
 	*data = pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ,
@@ -156,7 +161,10 @@ s32 pch_gbe_phy_write_reg_miic(struct pc
 	struct pch_gbe_phy_info *phy = &hw->phy;
 
 	if (offset > PHY_MAX_REG_ADDRESS) {
-		pr_err("PHY Address %d is out of range\n", offset);
+		struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
+
+		netdev_err(adapter->netdev, "PHY Address %d is out of range\n",
+			   offset);
 		return -EINVAL;
 	}
 	pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE,
@@ -235,7 +243,7 @@ void pch_gbe_phy_power_down(struct pch_g
  * pch_gbe_phy_set_rgmii - RGMII interface setting
  * @hw:	            Pointer to the HW structure
  */
-inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)
+void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw)
 {
 	pch_gbe_phy_sw_reset(hw);
 }
@@ -246,15 +254,14 @@ inline void pch_gbe_phy_set_rgmii(struct
  */
 void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
 {
-	struct pch_gbe_adapter *adapter;
+	struct pch_gbe_adapter *adapter = pch_gbe_hw_to_adapter(hw);
 	struct ethtool_cmd     cmd = { .cmd = ETHTOOL_GSET };
 	int ret;
 	u16 mii_reg;
 
-	adapter = container_of(hw, struct pch_gbe_adapter, hw);
 	ret = mii_ethtool_gset(&adapter->mii, &cmd);
 	if (ret)
-		pr_err("Error: mii_ethtool_gset\n");
+		netdev_err(adapter->netdev, "Error: mii_ethtool_gset\n");
 
 	ethtool_cmd_speed_set(&cmd, hw->mac.link_speed);
 	cmd.duplex = hw->mac.link_duplex;
@@ -263,12 +270,11 @@ void pch_gbe_phy_init_setting(struct pch
 	pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET);
 	ret = mii_ethtool_sset(&adapter->mii, &cmd);
 	if (ret)
-		pr_err("Error: mii_ethtool_sset\n");
+		netdev_err(adapter->netdev, "Error: mii_ethtool_sset\n");
 
 	pch_gbe_phy_sw_reset(hw);
 
 	pch_gbe_phy_read_reg_miic(hw, PHY_PHYSP_CONTROL, &mii_reg);
 	mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX;
 	pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, mii_reg);
-
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/packetengines/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/packetengines/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/packetengines/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/packetengines/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -21,7 +21,6 @@ if NET_PACKET_ENGINE
 config HAMACHI
 	tristate "Packet Engines Hamachi GNIC-II support"
 	depends on PCI
-	select NET_CORE
 	select MII
 	---help---
 	  If you have a Gigabit Ethernet card of this type, say Y and read
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic.h	2013-07-01 10:36:55.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic.h	2013-08-31 17:56:28.000000000 -0400
@@ -53,8 +53,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 80
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.80"
+#define _NETXEN_NIC_LINUX_SUBVERSION 81
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.81"
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
 #define _major(v)	(((v) >> 24) & 0xff)
@@ -1855,7 +1855,7 @@ static const struct netxen_brdinfo netxe
 
 #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(netxen_boards)
 
-static inline void get_brd_name_by_type(u32 type, char *name)
+static inline int netxen_nic_get_brd_name_by_type(u32 type, char *name)
 {
 	int i, found = 0;
 	for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) {
@@ -1864,10 +1864,14 @@ static inline void get_brd_name_by_type(
 			found = 1;
 			break;
 		}
+	}
 
+	if (!found) {
+		strcpy(name, "Unknown");
+		return -EINVAL;
 	}
-	if (!found)
-		name = "Unknown";
+
+	return 0;
 }
 
 static inline u32 netxen_tx_avail(struct nx_host_tx_ring *tx_ring)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h	2013-08-25 20:43:22.000000000 -0400
@@ -734,6 +734,9 @@ enum {
 #define NIC_CRB_BASE_2		(NETXEN_CAM_RAM(0x700))
 #define NETXEN_NIC_REG(X)	(NIC_CRB_BASE+(X))
 #define NETXEN_NIC_REG_2(X)	(NIC_CRB_BASE_2+(X))
+#define NETXEN_INTR_MODE_REG	NETXEN_NIC_REG(0x44)
+#define NETXEN_MSI_MODE		0x1
+#define NETXEN_INTX_MODE	0x2
 
 #define NX_CDRP_CRB_OFFSET		(NETXEN_NIC_REG(0x18))
 #define NX_ARG1_CRB_OFFSET		(NETXEN_NIC_REG(0x1c))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c	2013-07-01 10:36:58.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c	2013-08-31 17:56:31.000000000 -0400
@@ -592,48 +592,60 @@ static const struct net_device_ops netxe
 #endif
 };
 
-static void
-netxen_setup_intr(struct netxen_adapter *adapter)
+static inline bool netxen_function_zero(struct pci_dev *pdev)
 {
-	struct netxen_legacy_intr_set *legacy_intrp;
-	struct pci_dev *pdev = adapter->pdev;
-	int err, num_msix;
+	return (PCI_FUNC(pdev->devfn) == 0) ? true : false;
+}
 
-	if (adapter->rss_supported) {
-		num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ?
-			MSIX_ENTRIES_PER_ADAPTER : 2;
-	} else
-		num_msix = 1;
+static inline void netxen_set_interrupt_mode(struct netxen_adapter *adapter,
+					     u32 mode)
+{
+	NXWR32(adapter, NETXEN_INTR_MODE_REG, mode);
+}
 
-	adapter->max_sds_rings = 1;
+static inline u32 netxen_get_interrupt_mode(struct netxen_adapter *adapter)
+{
+	return NXRD32(adapter, NETXEN_INTR_MODE_REG);
+}
 
-	adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
+static void
+netxen_initialize_interrupt_registers(struct netxen_adapter *adapter)
+{
+	struct netxen_legacy_intr_set *legacy_intrp;
+	u32 tgt_status_reg, int_state_reg;
 
 	if (adapter->ahw.revision_id >= NX_P3_B0)
 		legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
 	else
 		legacy_intrp = &legacy_intr[0];
 
+	tgt_status_reg = legacy_intrp->tgt_status_reg;
+	int_state_reg = ISR_INT_STATE_REG;
+
 	adapter->int_vec_bit = legacy_intrp->int_vec_bit;
-	adapter->tgt_status_reg = netxen_get_ioaddr(adapter,
-			legacy_intrp->tgt_status_reg);
+	adapter->tgt_status_reg = netxen_get_ioaddr(adapter, tgt_status_reg);
 	adapter->tgt_mask_reg = netxen_get_ioaddr(adapter,
-			legacy_intrp->tgt_mask_reg);
+						  legacy_intrp->tgt_mask_reg);
 	adapter->pci_int_reg = netxen_get_ioaddr(adapter,
-			legacy_intrp->pci_int_reg);
+						 legacy_intrp->pci_int_reg);
 	adapter->isr_int_vec = netxen_get_ioaddr(adapter, ISR_INT_VECTOR);
 
 	if (adapter->ahw.revision_id >= NX_P3_B1)
 		adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
-			ISR_INT_STATE_REG);
+							       int_state_reg);
 	else
 		adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
-			CRB_INT_VECTOR);
+							       CRB_INT_VECTOR);
+}
 
-	netxen_set_msix_bit(pdev, 0);
+static int netxen_setup_msi_interrupts(struct netxen_adapter *adapter,
+				       int num_msix)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	u32 value;
+	int err;
 
 	if (adapter->msix_supported) {
-
 		netxen_init_msix_entries(adapter, num_msix);
 		err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
 		if (err == 0) {
@@ -644,26 +656,59 @@ netxen_setup_intr(struct netxen_adapter
 				adapter->max_sds_rings = num_msix;
 
 			dev_info(&pdev->dev, "using msi-x interrupts\n");
-			return;
+			return 0;
 		}
-
-		if (err > 0)
-			pci_disable_msix(pdev);
-
 		/* fall through for msi */
 	}
 
 	if (use_msi && !pci_enable_msi(pdev)) {
+		value = msi_tgt_status[adapter->ahw.pci_func];
 		adapter->flags |= NETXEN_NIC_MSI_ENABLED;
-		adapter->tgt_status_reg = netxen_get_ioaddr(adapter,
-				msi_tgt_status[adapter->ahw.pci_func]);
-		dev_info(&pdev->dev, "using msi interrupts\n");
+		adapter->tgt_status_reg = netxen_get_ioaddr(adapter, value);
 		adapter->msix_entries[0].vector = pdev->irq;
-		return;
+		dev_info(&pdev->dev, "using msi interrupts\n");
+		return 0;
 	}
 
-	dev_info(&pdev->dev, "using legacy interrupts\n");
-	adapter->msix_entries[0].vector = pdev->irq;
+	dev_err(&pdev->dev, "Failed to acquire MSI-X/MSI interrupt vector\n");
+	return -EIO;
+}
+
+static int netxen_setup_intr(struct netxen_adapter *adapter)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int num_msix;
+
+	if (adapter->rss_supported)
+		num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ?
+			    MSIX_ENTRIES_PER_ADAPTER : 2;
+	else
+		num_msix = 1;
+
+	adapter->max_sds_rings = 1;
+	adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
+
+	netxen_initialize_interrupt_registers(adapter);
+	netxen_set_msix_bit(pdev, 0);
+
+	if (netxen_function_zero(pdev)) {
+		if (!netxen_setup_msi_interrupts(adapter, num_msix))
+			netxen_set_interrupt_mode(adapter, NETXEN_MSI_MODE);
+		else
+			netxen_set_interrupt_mode(adapter, NETXEN_INTX_MODE);
+	} else {
+		if (netxen_get_interrupt_mode(adapter) == NETXEN_MSI_MODE &&
+		    netxen_setup_msi_interrupts(adapter, num_msix)) {
+			dev_err(&pdev->dev, "Co-existence of MSI-X/MSI and INTx interrupts is not supported\n");
+			return -EIO;
+		}
+	}
+
+	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
+		adapter->msix_entries[0].vector = pdev->irq;
+		dev_info(&pdev->dev, "using legacy interrupts\n");
+	}
+	return 0;
 }
 
 static void
@@ -841,7 +886,9 @@ netxen_check_options(struct netxen_adapt
 	}
 
 	if (adapter->portnum == 0) {
-		get_brd_name_by_type(adapter->ahw.board_type, brd_name);
+		if (netxen_nic_get_brd_name_by_type(adapter->ahw.board_type,
+						    brd_name))
+			strcpy(serial_num, "Unknown");
 
 		pr_info("%s: %s Board S/N %s  Chip rev 0x%x\n",
 				module_name(THIS_MODULE),
@@ -860,9 +907,9 @@ netxen_check_options(struct netxen_adapt
 		adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
 	}
 
-	dev_info(&pdev->dev, "firmware v%d.%d.%d [%s]\n",
-			fw_major, fw_minor, fw_build,
-			adapter->ahw.cut_through ? "cut-through" : "legacy");
+	dev_info(&pdev->dev, "Driver v%s, firmware v%d.%d.%d [%s]\n",
+		 NETXEN_NIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build,
+		 adapter->ahw.cut_through ? "cut-through" : "legacy");
 
 	if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222))
 		adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
@@ -1508,7 +1555,13 @@ netxen_nic_probe(struct pci_dev *pdev, c
 
 	netxen_nic_clear_stats(adapter);
 
-	netxen_setup_intr(adapter);
+	err = netxen_setup_intr(adapter);
+
+	if (err) {
+		dev_err(&adapter->pdev->dev,
+			"Failed to setup interrupts, error = %d\n", err);
+		goto err_out_disable_msi;
+	}
 
 	err = netxen_setup_netdev(adapter, netdev);
 	if (err)
@@ -1596,7 +1649,7 @@ static void netxen_nic_remove(struct pci
 	clear_bit(__NX_RESETTING, &adapter->state);
 
 	netxen_teardown_intr(adapter);
-
+	netxen_set_interrupt_mode(adapter, 0);
 	netxen_remove_diag_entries(adapter);
 
 	netxen_cleanup_pci_map(adapter);
@@ -2721,7 +2774,7 @@ netxen_store_bridged_mode(struct device
 	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
 		goto err_out;
 
-	if (strict_strtoul(buf, 2, &new))
+	if (kstrtoul(buf, 2, &new))
 		goto err_out;
 
 	if (!netxen_config_bridged_mode(adapter, !!new))
@@ -2760,7 +2813,7 @@ netxen_store_diag_mode(struct device *de
 	struct netxen_adapter *adapter = dev_get_drvdata(dev);
 	unsigned long new;
 
-	if (strict_strtoul(buf, 2, &new))
+	if (kstrtoul(buf, 2, &new))
 		return -EINVAL;
 
 	if (!!new != !!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
@@ -3311,7 +3364,7 @@ static int netxen_netdev_event(struct no
 				 unsigned long event, void *ptr)
 {
 	struct netxen_adapter *adapter;
-	struct net_device *dev = (struct net_device *)ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct net_device *orig_dev = dev;
 	struct net_device *slave;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,6 +63,7 @@ static const struct qlcnic_mailbox_metad
 	{QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
 	{QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
 	{QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
+	{QLCNIC_CMD_83XX_SET_DRV_VER, 4, 1},
 	{QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
 	{QLCNIC_CMD_CONFIG_VPORT, 4, 4},
 	{QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
@@ -172,6 +173,7 @@ static struct qlcnic_hardware_ops qlcnic
 	.config_promisc_mode		= qlcnic_83xx_nic_set_promisc,
 	.change_l2_filter		= qlcnic_83xx_change_l2_filter,
 	.get_board_info			= qlcnic_83xx_get_port_info,
+	.set_mac_filter_count		= qlcnic_83xx_set_mac_filter_count,
 	.free_mac_list			= qlcnic_82xx_free_mac_list,
 };
 
@@ -184,6 +186,8 @@ static struct qlcnic_nic_template qlcnic
 	.napi_del		= qlcnic_83xx_napi_del,
 	.config_ipaddr		= qlcnic_83xx_config_ipaddr,
 	.clear_legacy_intr	= qlcnic_83xx_clear_legacy_intr,
+	.shutdown		= qlcnic_83xx_shutdown,
+	.resume			= qlcnic_83xx_resume,
 };
 
 void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
@@ -224,17 +228,17 @@ static int __qlcnic_set_win_base(struct
 	return 0;
 }
 
-int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr)
+int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
+				int *err)
 {
-	int ret;
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
-	ret = __qlcnic_set_win_base(adapter, (u32) addr);
-	if (!ret) {
+	*err = __qlcnic_set_win_base(adapter, (u32) addr);
+	if (!*err) {
 		return QLCRDX(ahw, QLCNIC_WILDCARD);
 	} else {
 		dev_err(&adapter->pdev->dev,
-			"%s failed, addr = 0x%x\n", __func__, (int)addr);
+			"%s failed, addr = 0x%lx\n", __func__, addr);
 		return -EIO;
 	}
 }
@@ -312,6 +316,11 @@ inline void qlcnic_83xx_clear_legacy_int
 	writel(0, adapter->tgt_mask_reg);
 }
 
+inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
+{
+	writel(1, adapter->tgt_mask_reg);
+}
+
 /* Enable MSI-x and INT-x interrupts */
 void qlcnic_83xx_enable_intr(struct qlcnic_adapter *adapter,
 			     struct qlcnic_host_sds_ring *sds_ring)
@@ -458,6 +467,9 @@ void qlcnic_83xx_free_mbx_intr(struct ql
 {
 	u32 num_msix;
 
+	if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
+		qlcnic_83xx_set_legacy_intr_mask(adapter);
+
 	qlcnic_83xx_disable_mbx_intr(adapter);
 
 	if (adapter->flags & QLCNIC_MSIX_ENABLED)
@@ -474,7 +486,6 @@ int qlcnic_83xx_setup_mbx_intr(struct ql
 {
 	irq_handler_t handler;
 	u32 val;
-	char name[32];
 	int err = 0;
 	unsigned long flags = 0;
 
@@ -485,9 +496,7 @@ int qlcnic_83xx_setup_mbx_intr(struct ql
 	if (adapter->flags & QLCNIC_MSIX_ENABLED) {
 		handler = qlcnic_83xx_handle_aen;
 		val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
-		snprintf(name, (IFNAMSIZ + 4),
-			 "%s[%s]", "qlcnic", "aen");
-		err = request_irq(val, handler, flags, name, adapter);
+		err = request_irq(val, handler, flags, "qlcnic-MB", adapter);
 		if (err) {
 			dev_err(&adapter->pdev->dev,
 				"failed to register MBX interrupt\n");
@@ -552,7 +561,7 @@ void qlcnic_83xx_cam_unlock(struct qlcni
 void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
 			  loff_t offset, size_t size)
 {
-	int ret;
+	int ret = 0;
 	u32 data;
 
 	if (qlcnic_api_lock(adapter)) {
@@ -562,7 +571,7 @@ void qlcnic_83xx_read_crb(struct qlcnic_
 		return;
 	}
 
-	ret = qlcnic_83xx_rd_reg_indirect(adapter, (u32) offset);
+	data = QLCRD32(adapter, (u32) offset, &ret);
 	qlcnic_api_unlock(adapter);
 
 	if (ret == -EIO) {
@@ -571,7 +580,6 @@ void qlcnic_83xx_read_crb(struct qlcnic_
 			__func__, (u32)offset);
 		return;
 	}
-	data = ret;
 	memcpy(buf, &data, size);
 }
 
@@ -604,6 +612,22 @@ int qlcnic_83xx_get_port_info(struct qlc
 	return status;
 }
 
+void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	u16 act_pci_fn = ahw->act_pci_func;
+	u16 count;
+
+	ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT;
+	if (act_pci_fn <= 2)
+		count = (QLC_83XX_MAX_UC_COUNT - QLC_83XX_MAX_MC_COUNT) /
+			 act_pci_fn;
+	else
+		count = (QLC_83XX_LB_MAX_FILTERS - QLC_83XX_MAX_MC_COUNT) /
+			 act_pci_fn;
+	ahw->max_uc_count = count;
+}
+
 void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter)
 {
 	u32 val;
@@ -839,7 +863,9 @@ void qlcnic_83xx_idc_aen_work(struct wor
 	int i, err = 0;
 
 	adapter = container_of(work, struct qlcnic_adapter, idc_aen_work.work);
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
+	if (err)
+		return;
 
 	for (i = 1; i < QLC_83XX_MBX_AEN_CNT; i++)
 		cmd.req.arg[i] = adapter->ahw->mbox_aen[i];
@@ -1080,8 +1106,10 @@ int qlcnic_83xx_create_rx_ctx(struct qlc
 		cap |= QLC_83XX_FW_CAP_LRO_MSS;
 
 	/* set mailbox hdr and capabilities */
-	qlcnic_alloc_mbx_args(&cmd, adapter,
-			      QLCNIC_CMD_CREATE_RX_CTX);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter,
+				    QLCNIC_CMD_CREATE_RX_CTX);
+	if (err)
+		return err;
 
 	if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
 		cmd.req.arg[0] |= (0x3 << 29);
@@ -1239,7 +1267,9 @@ int qlcnic_83xx_create_tx_ctx(struct qlc
 		mbx.intr_id = 0xffff;
 	mbx.src = 0;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
+	if (err)
+		return err;
 
 	if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
 		cmd.req.arg[0] |= (0x3 << 29);
@@ -1385,8 +1415,11 @@ int qlcnic_83xx_config_led(struct qlcnic
 
 	if (state) {
 		/* Get LED configuration */
-		qlcnic_alloc_mbx_args(&cmd, adapter,
-				      QLCNIC_CMD_GET_LED_CONFIG);
+		status = qlcnic_alloc_mbx_args(&cmd, adapter,
+					       QLCNIC_CMD_GET_LED_CONFIG);
+		if (status)
+			return status;
+
 		status = qlcnic_issue_cmd(adapter, &cmd);
 		if (status) {
 			dev_err(&adapter->pdev->dev,
@@ -1400,8 +1433,11 @@ int qlcnic_83xx_config_led(struct qlcnic
 		/* Set LED Configuration */
 		mbx_in = (LSW(QLC_83XX_LED_CONFIG) << 16) |
 			  LSW(QLC_83XX_LED_CONFIG);
-		qlcnic_alloc_mbx_args(&cmd, adapter,
-				      QLCNIC_CMD_SET_LED_CONFIG);
+		status = qlcnic_alloc_mbx_args(&cmd, adapter,
+					       QLCNIC_CMD_SET_LED_CONFIG);
+		if (status)
+			return status;
+
 		cmd.req.arg[1] = mbx_in;
 		cmd.req.arg[2] = mbx_in;
 		cmd.req.arg[3] = mbx_in;
@@ -1418,8 +1454,11 @@ mbx_err:
 
 	} else {
 		/* Restoring default LED configuration */
-		qlcnic_alloc_mbx_args(&cmd, adapter,
-				      QLCNIC_CMD_SET_LED_CONFIG);
+		status = qlcnic_alloc_mbx_args(&cmd, adapter,
+					       QLCNIC_CMD_SET_LED_CONFIG);
+		if (status)
+			return status;
+
 		cmd.req.arg[1] = adapter->ahw->mbox_reg[0];
 		cmd.req.arg[2] = adapter->ahw->mbox_reg[1];
 		cmd.req.arg[3] = adapter->ahw->mbox_reg[2];
@@ -1489,10 +1528,18 @@ void qlcnic_83xx_register_nic_idc_func(s
 		return;
 
 	if (enable) {
-		qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INIT_NIC_FUNC);
+		status = qlcnic_alloc_mbx_args(&cmd, adapter,
+					       QLCNIC_CMD_INIT_NIC_FUNC);
+		if (status)
+			return;
+
 		cmd.req.arg[1] = BIT_0 | BIT_31;
 	} else {
-		qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_STOP_NIC_FUNC);
+		status = qlcnic_alloc_mbx_args(&cmd, adapter,
+					       QLCNIC_CMD_STOP_NIC_FUNC);
+		if (status)
+			return;
+
 		cmd.req.arg[1] = BIT_0 | BIT_31;
 	}
 	status = qlcnic_issue_cmd(adapter, &cmd);
@@ -1509,7 +1556,10 @@ int qlcnic_83xx_set_port_config(struct q
 	struct qlcnic_cmd_args cmd;
 	int err;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = adapter->ahw->port_config;
 	err = qlcnic_issue_cmd(adapter, &cmd);
 	if (err)
@@ -1523,7 +1573,10 @@ int qlcnic_83xx_get_port_config(struct q
 	struct qlcnic_cmd_args cmd;
 	int err;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
+	if (err)
+		return err;
+
 	err = qlcnic_issue_cmd(adapter, &cmd);
 	if (err)
 		dev_info(&adapter->pdev->dev, "Get Port config failed\n");
@@ -1539,7 +1592,10 @@ int qlcnic_83xx_setup_link_event(struct
 	u32 temp;
 	struct qlcnic_cmd_args cmd;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
+	if (err)
+		return err;
+
 	temp = adapter->recv_ctx->context_id << 16;
 	cmd.req.arg[1] = (enable ? 1 : 0) | BIT_8 | temp;
 	err = qlcnic_issue_cmd(adapter, &cmd);
@@ -1570,7 +1626,11 @@ int qlcnic_83xx_nic_set_promisc(struct q
 	if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
 		return -EIO;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter,
+				    QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
+	if (err)
+		return err;
+
 	qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
 	cmd.req.arg[1] = (mode ? 1 : 0) | temp;
 	err = qlcnic_issue_cmd(adapter, &cmd);
@@ -1588,16 +1648,24 @@ int qlcnic_83xx_loopback_test(struct net
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	int ret = 0, loop = 0, max_sds_rings = adapter->max_sds_rings;
 
-	QLCDB(adapter, DRV, "%s loopback test in progress\n",
-	      mode == QLCNIC_ILB_MODE ? "internal" : "external");
 	if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
-		dev_warn(&adapter->pdev->dev,
-			 "Loopback test not supported for non privilege function\n");
+		netdev_warn(netdev,
+			    "Loopback test not supported in non privileged mode\n");
 		return ret;
 	}
 
-	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+	if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
+		netdev_info(netdev, "Device is resetting\n");
 		return -EBUSY;
+	}
+
+	if (qlcnic_get_diag_lock(adapter)) {
+		netdev_info(netdev, "Device is in diagnostics mode\n");
+		return -EBUSY;
+	}
+
+	netdev_info(netdev, "%s loopback test in progress\n",
+		    mode == QLCNIC_ILB_MODE ? "internal" : "external");
 
 	ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
 					 max_sds_rings);
@@ -1610,13 +1678,19 @@ int qlcnic_83xx_loopback_test(struct net
 
 	/* Poll for link up event before running traffic */
 	do {
-		msleep(500);
+		msleep(QLC_83XX_LB_MSLEEP_COUNT);
 		if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
 			qlcnic_83xx_process_aen(adapter);
 
-		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
-			dev_info(&adapter->pdev->dev,
-				 "Firmware didn't sent link up event to loopback request\n");
+		if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
+			netdev_info(netdev,
+				    "Device is resetting, free LB test resources\n");
+			ret = -EIO;
+			goto free_diag_res;
+		}
+		if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
+			netdev_info(netdev,
+				    "Firmware didn't sent link up event to loopback request\n");
 			ret = -QLCNIC_FW_NOT_RESPOND;
 			qlcnic_83xx_clear_lb_mode(adapter, mode);
 			goto free_diag_res;
@@ -1638,13 +1712,14 @@ free_diag_res:
 
 fail_diag_alloc:
 	adapter->max_sds_rings = max_sds_rings;
-	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	qlcnic_release_diag_lock(adapter);
 	return ret;
 }
 
 int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
 {
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct net_device *netdev = adapter->netdev;
 	int status = 0, loop = 0;
 	u32 config;
 
@@ -1662,9 +1737,9 @@ int qlcnic_83xx_set_lb_mode(struct qlcni
 
 	status = qlcnic_83xx_set_port_config(adapter);
 	if (status) {
-		dev_err(&adapter->pdev->dev,
-			"Failed to Set Loopback Mode = 0x%x.\n",
-			ahw->port_config);
+		netdev_err(netdev,
+			   "Failed to Set Loopback Mode = 0x%x.\n",
+			   ahw->port_config);
 		ahw->port_config = config;
 		clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
 		return status;
@@ -1672,13 +1747,19 @@ int qlcnic_83xx_set_lb_mode(struct qlcni
 
 	/* Wait for Link and IDC Completion AEN */
 	do {
-		msleep(300);
+		msleep(QLC_83XX_LB_MSLEEP_COUNT);
 		if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
 			qlcnic_83xx_process_aen(adapter);
 
-		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
-			dev_err(&adapter->pdev->dev,
-				"FW did not generate IDC completion AEN\n");
+		if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
+			netdev_info(netdev,
+				    "Device is resetting, free LB test resources\n");
+			clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
+			return -EIO;
+		}
+		if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
+			netdev_err(netdev,
+				   "Did not receive IDC completion AEN\n");
 			clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
 			qlcnic_83xx_clear_lb_mode(adapter, mode);
 			return -EIO;
@@ -1693,6 +1774,7 @@ int qlcnic_83xx_set_lb_mode(struct qlcni
 int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
 {
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct net_device *netdev = adapter->netdev;
 	int status = 0, loop = 0;
 	u32 config = ahw->port_config;
 
@@ -1704,9 +1786,9 @@ int qlcnic_83xx_clear_lb_mode(struct qlc
 
 	status = qlcnic_83xx_set_port_config(adapter);
 	if (status) {
-		dev_err(&adapter->pdev->dev,
-			"Failed to Clear Loopback Mode = 0x%x.\n",
-			ahw->port_config);
+		netdev_err(netdev,
+			   "Failed to Clear Loopback Mode = 0x%x.\n",
+			   ahw->port_config);
 		ahw->port_config = config;
 		clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
 		return status;
@@ -1714,13 +1796,20 @@ int qlcnic_83xx_clear_lb_mode(struct qlc
 
 	/* Wait for Link and IDC Completion AEN */
 	do {
-		msleep(300);
+		msleep(QLC_83XX_LB_MSLEEP_COUNT);
 		if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
 			qlcnic_83xx_process_aen(adapter);
 
-		if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
-			dev_err(&adapter->pdev->dev,
-				"Firmware didn't sent IDC completion AEN\n");
+		if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
+			netdev_info(netdev,
+				    "Device is resetting, free LB test resources\n");
+			clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
+			return -EIO;
+		}
+
+		if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
+			netdev_err(netdev,
+				   "Did not receive IDC completion AEN\n");
 			clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
 			return -EIO;
 		}
@@ -1749,7 +1838,11 @@ void qlcnic_83xx_config_ipaddr(struct ql
 	u32 temp = 0, temp_ip;
 	struct qlcnic_cmd_args cmd;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_IP_ADDR);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter,
+				    QLCNIC_CMD_CONFIGURE_IP_ADDR);
+	if (err)
+		return;
+
 	qlcnic_83xx_set_interface_id_ipaddr(adapter, &temp);
 
 	if (mode == QLCNIC_IP_UP)
@@ -1788,7 +1881,10 @@ int qlcnic_83xx_config_hw_lro(struct qlc
 	if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
 		return 0;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
+	if (err)
+		return err;
+
 	temp = adapter->recv_ctx->context_id << 16;
 	arg1 = lro_bit_mask | temp;
 	cmd.req.arg[1] = arg1;
@@ -1810,8 +1906,9 @@ int qlcnic_83xx_config_rss(struct qlcnic
 			    0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
 			    0x255b0ec26d5a56daULL };
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
-
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
+	if (err)
+		return err;
 	/*
 	 * RSS request:
 	 * bits 3-0: Rsvd
@@ -1917,7 +2014,10 @@ int qlcnic_83xx_get_mac_address(struct q
 	struct qlcnic_cmd_args cmd;
 	u32 mac_low, mac_high;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
+	if (err)
+		return err;
+
 	qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
 	err = qlcnic_issue_cmd(adapter, &cmd);
 
@@ -1948,7 +2048,10 @@ void qlcnic_83xx_config_intr_coal(struct
 	if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
 		return;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
+	if (err)
+		return;
+
 	if (coal->type == QLCNIC_INTR_COAL_TYPE_RX) {
 		temp = adapter->recv_ctx->context_id;
 		cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16;
@@ -1971,18 +2074,25 @@ void qlcnic_83xx_config_intr_coal(struct
 static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
 					u32 data[])
 {
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	u8 link_status, duplex;
 	/* link speed */
 	link_status = LSB(data[3]) & 1;
-	adapter->ahw->link_speed = MSW(data[2]);
-	adapter->ahw->link_autoneg = MSB(MSW(data[3]));
-	adapter->ahw->module_type = MSB(LSW(data[3]));
-	duplex = LSB(MSW(data[3]));
-	if (duplex)
-		adapter->ahw->link_duplex = DUPLEX_FULL;
-	else
-		adapter->ahw->link_duplex = DUPLEX_HALF;
-	adapter->ahw->has_link_events = 1;
+	if (link_status) {
+		ahw->link_speed = MSW(data[2]);
+		duplex = LSB(MSW(data[3]));
+		if (duplex)
+			ahw->link_duplex = DUPLEX_FULL;
+		else
+			ahw->link_duplex = DUPLEX_HALF;
+	} else {
+		ahw->link_speed = SPEED_UNKNOWN;
+		ahw->link_duplex = DUPLEX_UNKNOWN;
+	}
+
+	ahw->link_autoneg = MSB(MSW(data[3]));
+	ahw->module_type = MSB(LSW(data[3]));
+	ahw->has_link_events = 1;
 	qlcnic_advert_link_change(adapter, link_status);
 }
 
@@ -2020,7 +2130,10 @@ int qlcnic_enable_eswitch(struct qlcnic_
 		return err;
 	}
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = (port & 0xf) | BIT_4;
 	err = qlcnic_issue_cmd(adapter, &cmd);
 
@@ -2048,7 +2161,10 @@ int qlcnic_83xx_set_nic_info(struct qlcn
 		return err;
 	}
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = (nic->pci_func << 16);
 	cmd.req.arg[2] = 0x1 << 16;
 	cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
@@ -2079,13 +2195,17 @@ int qlcnic_83xx_get_nic_info(struct qlcn
 	u32 temp;
 	u8 op = 0;
 	struct qlcnic_cmd_args cmd;
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
-	if (func_id != adapter->ahw->pci_func) {
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
+	if (err)
+		return err;
+
+	if (func_id != ahw->pci_func) {
 		temp = func_id << 16;
 		cmd.req.arg[1] = op | BIT_31 | temp;
 	} else {
-		cmd.req.arg[1] = adapter->ahw->pci_func << 16;
+		cmd.req.arg[1] = ahw->pci_func << 16;
 	}
 	err = qlcnic_issue_cmd(adapter, &cmd);
 	if (err) {
@@ -2112,6 +2232,9 @@ int qlcnic_83xx_get_nic_info(struct qlcn
 		temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
 		npar_info->max_linkspeed_reg_offset = temp;
 	}
+	if (npar_info->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS)
+		memcpy(ahw->extra_capability, &cmd.rsp.arg[16],
+		       sizeof(ahw->extra_capability));
 
 out:
 	qlcnic_free_mbx_args(&cmd);
@@ -2121,26 +2244,28 @@ out:
 int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
 			     struct qlcnic_pci_info *pci_info)
 {
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct device *dev = &adapter->pdev->dev;
+	struct qlcnic_cmd_args cmd;
 	int i, err = 0, j = 0;
 	u32 temp;
-	struct qlcnic_cmd_args cmd;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
+	if (err)
+		return err;
+
 	err = qlcnic_issue_cmd(adapter, &cmd);
 
-	adapter->ahw->act_pci_func = 0;
+	ahw->act_pci_func = 0;
 	if (err == QLCNIC_RCODE_SUCCESS) {
-		pci_info->func_count = cmd.rsp.arg[1] & 0xFF;
-		dev_info(&adapter->pdev->dev,
-			 "%s: total functions = %d\n",
-			 __func__, pci_info->func_count);
+		ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
 		for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) {
 			pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
 			pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
 			i++;
 			pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
 			if (pci_info->type == QLCNIC_TYPE_NIC)
-				adapter->ahw->act_pci_func++;
+				ahw->act_pci_func++;
 			temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
 			pci_info->default_port = temp;
 			i++;
@@ -2152,18 +2277,21 @@ int qlcnic_83xx_get_pci_info(struct qlcn
 			i++;
 			memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
 			i = i + 3;
-
-			dev_info(&adapter->pdev->dev, "%s:\n"
-				 "\tid = %d active = %d type = %d\n"
-				 "\tport = %d min bw = %d max bw = %d\n"
-				 "\tmac_addr =  %pM\n", __func__,
-				 pci_info->id, pci_info->active, pci_info->type,
-				 pci_info->default_port, pci_info->tx_min_bw,
-				 pci_info->tx_max_bw, pci_info->mac);
+			if (ahw->op_mode == QLCNIC_MGMT_FUNC)
+				dev_info(dev, "id = %d active = %d type = %d\n"
+					 "\tport = %d min bw = %d max bw = %d\n"
+					 "\tmac_addr =  %pM\n", pci_info->id,
+					 pci_info->active, pci_info->type,
+					 pci_info->default_port,
+					 pci_info->tx_min_bw,
+					 pci_info->tx_max_bw, pci_info->mac);
 		}
+		if (ahw->op_mode == QLCNIC_MGMT_FUNC)
+			dev_info(dev, "Max vNIC functions = %d, active vNIC functions = %d\n",
+				 ahw->max_pci_func, ahw->act_pci_func);
+
 	} else {
-		dev_err(&adapter->pdev->dev, "Failed to get PCI Info%d\n",
-			err);
+		dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
 		err = -EIO;
 	}
 
@@ -2180,7 +2308,10 @@ int qlcnic_83xx_config_intrpt(struct qlc
 	struct qlcnic_cmd_args cmd;
 
 	max_ints = adapter->ahw->num_msix - 1;
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = max_ints;
 
 	if (qlcnic_sriov_vf_check(adapter))
@@ -2259,9 +2390,9 @@ int qlcnic_83xx_lockless_flash_read32(st
 				      u32 flash_addr, u8 *p_data,
 				      int count)
 {
-	int i, ret;
-	u32 word, range, flash_offset, addr = flash_addr;
+	u32 word, range, flash_offset, addr = flash_addr, ret;
 	ulong indirect_add, direct_window;
+	int i, err = 0;
 
 	flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1);
 	if (addr & 0x3) {
@@ -2279,10 +2410,9 @@ int qlcnic_83xx_lockless_flash_read32(st
 		/* Multi sector read */
 		for (i = 0; i < count; i++) {
 			indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
-			ret = qlcnic_83xx_rd_reg_indirect(adapter,
-							  indirect_add);
-			if (ret == -EIO)
-				return -EIO;
+			ret = QLCRD32(adapter, indirect_add, &err);
+			if (err == -EIO)
+				return err;
 
 			word = ret;
 			*(u32 *)p_data  = word;
@@ -2303,10 +2433,9 @@ int qlcnic_83xx_lockless_flash_read32(st
 		/* Single sector read */
 		for (i = 0; i < count; i++) {
 			indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
-			ret = qlcnic_83xx_rd_reg_indirect(adapter,
-							  indirect_add);
-			if (ret == -EIO)
-				return -EIO;
+			ret = QLCRD32(adapter, indirect_add, &err);
+			if (err == -EIO)
+				return err;
 
 			word = ret;
 			*(u32 *)p_data  = word;
@@ -2322,10 +2451,13 @@ static int qlcnic_83xx_poll_flash_status
 {
 	u32 status;
 	int retries = QLC_83XX_FLASH_READ_RETRY_COUNT;
+	int err = 0;
 
 	do {
-		status = qlcnic_83xx_rd_reg_indirect(adapter,
-						     QLC_83XX_FLASH_STATUS);
+		status = QLCRD32(adapter, QLC_83XX_FLASH_STATUS, &err);
+		if (err == -EIO)
+			return err;
+
 		if ((status & QLC_83XX_FLASH_STATUS_READY) ==
 		    QLC_83XX_FLASH_STATUS_READY)
 			break;
@@ -2377,7 +2509,8 @@ int qlcnic_83xx_disable_flash_write(stru
 
 int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter)
 {
-	int ret, mfg_id;
+	int ret, err = 0;
+	u32 mfg_id;
 
 	if (qlcnic_83xx_lock_flash(adapter))
 		return -EIO;
@@ -2392,9 +2525,11 @@ int qlcnic_83xx_read_flash_mfg_id(struct
 		return -EIO;
 	}
 
-	mfg_id = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA);
-	if (mfg_id == -EIO)
-		return -EIO;
+	mfg_id = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err);
+	if (err == -EIO) {
+		qlcnic_83xx_unlock_flash(adapter);
+		return err;
+	}
 
 	adapter->flash_mfg_id = (mfg_id & 0xFF);
 	qlcnic_83xx_unlock_flash(adapter);
@@ -2511,7 +2646,7 @@ int qlcnic_83xx_flash_bulk_write(struct
 				 u32 *p_data, int count)
 {
 	u32 temp;
-	int ret = -EIO;
+	int ret = -EIO, err = 0;
 
 	if ((count < QLC_83XX_FLASH_WRITE_MIN) ||
 	    (count > QLC_83XX_FLASH_WRITE_MAX)) {
@@ -2520,8 +2655,10 @@ int qlcnic_83xx_flash_bulk_write(struct
 		return -EIO;
 	}
 
-	temp = qlcnic_83xx_rd_reg_indirect(adapter,
-					   QLC_83XX_FLASH_SPI_CONTROL);
+	temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
+	if (err == -EIO)
+		return err;
+
 	qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL,
 				     (temp | QLC_83XX_FLASH_SPI_CTRL));
 	qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
@@ -2570,13 +2707,18 @@ int qlcnic_83xx_flash_bulk_write(struct
 		return -EIO;
 	}
 
-	ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_SPI_STATUS);
+	ret = QLCRD32(adapter, QLC_83XX_FLASH_SPI_STATUS, &err);
+	if (err == -EIO)
+		return err;
+
 	if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) {
 		dev_err(&adapter->pdev->dev, "%s: failed at %d\n",
 			__func__, __LINE__);
 		/* Operation failed, clear error bit */
-		temp = qlcnic_83xx_rd_reg_indirect(adapter,
-						   QLC_83XX_FLASH_SPI_CONTROL);
+		temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
+		if (err == -EIO)
+			return err;
+
 		qlcnic_83xx_wrt_reg_indirect(adapter,
 					     QLC_83XX_FLASH_SPI_CONTROL,
 					     (temp | QLC_83XX_FLASH_SPI_CTRL));
@@ -2698,6 +2840,7 @@ int qlcnic_83xx_ms_mem_write128(struct q
 {
 	int i, j, ret = 0;
 	u32 temp;
+	int err = 0;
 
 	/* Check alignment */
 	if (addr & 0xF)
@@ -2730,8 +2873,12 @@ int qlcnic_83xx_ms_mem_write128(struct q
 					     QLCNIC_TA_WRITE_START);
 
 		for (j = 0; j < MAX_CTL_CHECK; j++) {
-			temp = qlcnic_83xx_rd_reg_indirect(adapter,
-							   QLCNIC_MS_CTRL);
+			temp = QLCRD32(adapter, QLCNIC_MS_CTRL, &err);
+			if (err == -EIO) {
+				mutex_unlock(&adapter->ahw->mem_lock);
+				return err;
+			}
+
 			if ((temp & TA_CTL_BUSY) == 0)
 				break;
 		}
@@ -2753,9 +2900,9 @@ int qlcnic_83xx_ms_mem_write128(struct q
 int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
 			     u8 *p_data, int count)
 {
-	int i, ret;
-	u32 word, addr = flash_addr;
+	u32 word, addr = flash_addr, ret;
 	ulong  indirect_addr;
+	int i, err = 0;
 
 	if (qlcnic_83xx_lock_flash(adapter) != 0)
 		return -EIO;
@@ -2775,10 +2922,10 @@ int qlcnic_83xx_flash_read32(struct qlcn
 		}
 
 		indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr);
-		ret = qlcnic_83xx_rd_reg_indirect(adapter,
-						  indirect_addr);
-		if (ret == -EIO)
-			return -EIO;
+		ret = QLCRD32(adapter, indirect_addr, &err);
+		if (err == -EIO)
+			return err;
+
 		word = ret;
 		*(u32 *)p_data  = word;
 		p_data = p_data + 4;
@@ -2808,7 +2955,11 @@ int qlcnic_83xx_test_link(struct qlcnic_
 		dev_info(&adapter->pdev->dev, "link state down\n");
 		return config;
 	}
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
+
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
+	if (err)
+		return err;
+
 	err = qlcnic_issue_cmd(adapter, &cmd);
 	if (err) {
 		dev_info(&adapter->pdev->dev,
@@ -2885,8 +3036,8 @@ int qlcnic_83xx_get_settings(struct qlcn
 	}
 
 	if (ahw->port_type == QLCNIC_XGBE) {
-		ecmd->supported = SUPPORTED_1000baseT_Full;
-		ecmd->advertising = ADVERTISED_1000baseT_Full;
+		ecmd->supported = SUPPORTED_10000baseT_Full;
+		ecmd->advertising = ADVERTISED_10000baseT_Full;
 	} else {
 		ecmd->supported = (SUPPORTED_10baseT_Half |
 				   SUPPORTED_10baseT_Full |
@@ -3034,7 +3185,9 @@ void qlcnic_83xx_get_stats(struct qlcnic
 	struct net_device *netdev = adapter->netdev;
 	int ret = 0;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
+	ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
+	if (ret)
+		return;
 	/* Get Tx stats */
 	cmd.req.arg[1] = BIT_1 | (adapter->tx_ring->ctx_id << 16);
 	cmd.rsp.num = QLC_83XX_TX_STAT_REGS;
@@ -3113,8 +3266,15 @@ int qlcnic_83xx_interrupt_test(struct ne
 	u8 val;
 	int ret, max_sds_rings = adapter->max_sds_rings;
 
-	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
-		return -EIO;
+	if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
+		netdev_info(netdev, "Device is resetting\n");
+		return -EBUSY;
+	}
+
+	if (qlcnic_get_diag_lock(adapter)) {
+		netdev_info(netdev, "Device in diagnostics mode\n");
+		return -EBUSY;
+	}
 
 	ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
 					 max_sds_rings);
@@ -3122,7 +3282,9 @@ int qlcnic_83xx_interrupt_test(struct ne
 		goto fail_diag_irq;
 
 	ahw->diag_cnt = 0;
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
+	ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
+	if (ret)
+		goto fail_diag_irq;
 
 	if (adapter->flags & QLCNIC_MSIX_ENABLED)
 		intrpt_id = ahw->intr_tbl[0].id;
@@ -3156,7 +3318,7 @@ done:
 
 fail_diag_irq:
 	adapter->max_sds_rings = max_sds_rings;
-	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	qlcnic_release_diag_lock(adapter);
 	return ret;
 }
 
@@ -3234,7 +3396,8 @@ int qlcnic_83xx_set_pauseparam(struct ql
 
 static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter)
 {
-	int ret;
+	int ret, err = 0;
+	u32 temp;
 
 	qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
 				     QLC_83XX_FLASH_OEM_READ_SIG);
@@ -3244,8 +3407,11 @@ static int qlcnic_83xx_read_flash_status
 	if (ret)
 		return -EIO;
 
-	ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA);
-	return ret & 0xFF;
+	temp = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err);
+	if (err == -EIO)
+		return err;
+
+	return temp & 0xFF;
 }
 
 int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter)
@@ -3260,3 +3426,54 @@ int qlcnic_83xx_flash_test(struct qlcnic
 	}
 	return 0;
 }
+
+int qlcnic_83xx_shutdown(struct pci_dev *pdev)
+{
+	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev = adapter->netdev;
+	int retval;
+
+	netif_device_detach(netdev);
+	qlcnic_cancel_idc_work(adapter);
+
+	if (netif_running(netdev))
+		qlcnic_down(adapter, netdev);
+
+	qlcnic_83xx_disable_mbx_intr(adapter);
+	cancel_delayed_work_sync(&adapter->idc_aen_work);
+
+	retval = pci_save_state(pdev);
+	if (retval)
+		return retval;
+
+	return 0;
+}
+
+int qlcnic_83xx_resume(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct qlc_83xx_idc *idc = &ahw->idc;
+	int err = 0;
+
+	err = qlcnic_83xx_idc_init(adapter);
+	if (err)
+		return err;
+
+	if (ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE) {
+		if (ahw->op_mode == QLCNIC_MGMT_FUNC) {
+			qlcnic_83xx_set_vnic_opmode(adapter);
+		} else {
+			err = qlcnic_83xx_check_vnic_state(adapter);
+			if (err)
+				return err;
+		}
+	}
+
+	err = qlcnic_83xx_idc_reattach_driver(adapter);
+	if (err)
+		return err;
+
+	qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
+			     idc->delay);
+	return err;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h	2013-07-01 10:37:03.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h	2013-08-31 17:56:36.000000000 -0400
@@ -36,7 +36,8 @@
 #define QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT		3
 #define QLC_83XX_DRV_LOCK_RECOVERY_DELAY		200
 #define QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK		0x3
-
+#define QLC_83XX_LB_WAIT_COUNT				250
+#define QLC_83XX_LB_MSLEEP_COUNT			20
 #define QLC_83XX_NO_NIC_RESOURCE	0x5
 #define QLC_83XX_MAC_PRESENT		0xC
 #define QLC_83XX_MAC_ABSENT		0xD
@@ -314,6 +315,7 @@ struct qlc_83xx_idc {
 	u8		vnic_state;
 	u8		vnic_wait_limit;
 	u8		quiesce_req;
+	u8		delay_reset;
 	char		**name;
 };
 
@@ -392,6 +394,8 @@ enum qlcnic_83xx_states {
 #define QLC_83XX_LB_MAX_FILTERS			2048
 #define QLC_83XX_LB_BUCKET_SIZE			256
 #define QLC_83XX_MINIMUM_VECTOR			3
+#define QLC_83XX_MAX_MC_COUNT			38
+#define QLC_83XX_MAX_UC_COUNT			4096
 
 #define QLC_83XX_GET_FUNC_MODE_FROM_NPAR_INFO(val)	(val & 0x80000000)
 #define QLC_83XX_GET_LRO_CAPABILITY(val)		(val & 0x20)
@@ -504,7 +508,7 @@ void qlcnic_83xx_add_sysfs(struct qlcnic
 void qlcnic_83xx_remove_sysfs(struct qlcnic_adapter *);
 void qlcnic_83xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
 void qlcnic_83xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
-int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *, ulong);
+int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *, ulong, int *);
 int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *, ulong, u32);
 void qlcnic_83xx_process_rcv_diag(struct qlcnic_adapter *, int, u64 []);
 int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *, u32);
@@ -623,4 +627,11 @@ u32 qlcnic_83xx_mac_rcode(struct qlcnic_
 u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *, u32 *);
 void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *);
 void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *);
+void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *);
+int qlcnic_83xx_shutdown(struct pci_dev *);
+int qlcnic_83xx_resume(struct qlcnic_adapter *);
+int qlcnic_83xx_idc_init(struct qlcnic_adapter *);
+int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *);
+int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *);
+int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *);
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c	2013-07-01 10:36:58.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c	2013-08-31 17:56:31.000000000 -0400
@@ -606,7 +606,7 @@ static int qlcnic_83xx_idc_check_fan_fai
 	return 0;
 }
 
-static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
+int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
 {
 	int err;
 
@@ -629,6 +629,8 @@ static int qlcnic_83xx_idc_reattach_driv
 		return -EIO;
 	}
 
+	if (adapter->portnum == 0)
+		qlcnic_set_drv_version(adapter);
 	qlcnic_83xx_idc_attach_driver(adapter);
 
 	return 0;
@@ -649,6 +651,7 @@ static void qlcnic_83xx_idc_update_idc_p
 	ahw->idc.collect_dump = 0;
 	ahw->reset_context = 0;
 	adapter->tx_timeo_cnt = 0;
+	ahw->idc.delay_reset = 0;
 
 	clear_bit(__QLCNIC_RESETTING, &adapter->state);
 }
@@ -883,21 +886,41 @@ static int qlcnic_83xx_idc_need_reset_st
 	int ret = 0;
 
 	if (adapter->ahw->idc.prev_state != QLC_83XX_IDC_DEV_NEED_RESET) {
-		qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
 		qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
 		set_bit(__QLCNIC_RESETTING, &adapter->state);
 		clear_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
 		if (adapter->ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE)
 			qlcnic_83xx_disable_vnic_mode(adapter, 1);
-		qlcnic_83xx_idc_detach_driver(adapter);
+
+		if (qlcnic_check_diag_status(adapter)) {
+			dev_info(&adapter->pdev->dev,
+				 "%s: Wait for diag completion\n", __func__);
+			adapter->ahw->idc.delay_reset = 1;
+			return 0;
+		} else {
+			qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
+			qlcnic_83xx_idc_detach_driver(adapter);
+		}
 	}
 
-	/* Check ACK from other functions */
-	ret = qlcnic_83xx_idc_check_reset_ack_reg(adapter);
-	if (ret) {
+	if (qlcnic_check_diag_status(adapter)) {
 		dev_info(&adapter->pdev->dev,
-			 "%s: Waiting for reset ACK\n", __func__);
-		return 0;
+			 "%s: Wait for diag completion\n", __func__);
+		return  -1;
+	} else {
+		if (adapter->ahw->idc.delay_reset) {
+			qlcnic_83xx_idc_update_drv_ack_reg(adapter, 1, 1);
+			qlcnic_83xx_idc_detach_driver(adapter);
+			adapter->ahw->idc.delay_reset = 0;
+		}
+
+		/* Check for ACK from other functions */
+		ret = qlcnic_83xx_idc_check_reset_ack_reg(adapter);
+		if (ret) {
+			dev_info(&adapter->pdev->dev,
+				 "%s: Waiting for reset ACK\n", __func__);
+			return -1;
+		}
 	}
 
 	/* Transit to INIT state and restart the HW */
@@ -1113,7 +1136,7 @@ qlcnic_83xx_idc_first_to_load_function_h
 	return 0;
 }
 
-static int qlcnic_83xx_idc_init(struct qlcnic_adapter *adapter)
+int qlcnic_83xx_idc_init(struct qlcnic_adapter *adapter)
 {
 	int ret = -EIO;
 
@@ -1281,8 +1304,11 @@ static void qlcnic_83xx_dump_pause_contr
 {
 	int i, j;
 	u32 val = 0, val1 = 0, reg = 0;
+	int err = 0;
 
-	val = QLCRD32(adapter, QLC_83XX_SRE_SHIM_REG);
+	val = QLCRD32(adapter, QLC_83XX_SRE_SHIM_REG, &err);
+	if (err == -EIO)
+		return;
 	dev_info(&adapter->pdev->dev, "SRE-Shim Ctrl:0x%x\n", val);
 
 	for (j = 0; j < 2; j++) {
@@ -1296,7 +1322,9 @@ static void qlcnic_83xx_dump_pause_contr
 			reg = QLC_83XX_PORT1_THRESHOLD;
 		}
 		for (i = 0; i < 8; i++) {
-			val = QLCRD32(adapter, reg + (i * 0x4));
+			val = QLCRD32(adapter, reg + (i * 0x4), &err);
+			if (err == -EIO)
+				return;
 			dev_info(&adapter->pdev->dev, "0x%x  ", val);
 		}
 		dev_info(&adapter->pdev->dev, "\n");
@@ -1313,8 +1341,10 @@ static void qlcnic_83xx_dump_pause_contr
 			reg = QLC_83XX_PORT1_TC_MC_REG;
 		}
 		for (i = 0; i < 4; i++) {
-			val = QLCRD32(adapter, reg + (i * 0x4));
-			 dev_info(&adapter->pdev->dev, "0x%x  ", val);
+			val = QLCRD32(adapter, reg + (i * 0x4), &err);
+			if (err == -EIO)
+				return;
+			dev_info(&adapter->pdev->dev, "0x%x  ", val);
 		}
 		dev_info(&adapter->pdev->dev, "\n");
 	}
@@ -1330,17 +1360,25 @@ static void qlcnic_83xx_dump_pause_contr
 			reg = QLC_83XX_PORT1_TC_STATS;
 		}
 		for (i = 7; i >= 0; i--) {
-			val = QLCRD32(adapter, reg);
+			val = QLCRD32(adapter, reg, &err);
+			if (err == -EIO)
+				return;
 			val &= ~(0x7 << 29);    /* Reset bits 29 to 31 */
 			QLCWR32(adapter, reg, (val | (i << 29)));
-			val = QLCRD32(adapter, reg);
+			val = QLCRD32(adapter, reg, &err);
+			if (err == -EIO)
+				return;
 			dev_info(&adapter->pdev->dev, "0x%x  ", val);
 		}
 		dev_info(&adapter->pdev->dev, "\n");
 	}
 
-	val = QLCRD32(adapter, QLC_83XX_PORT2_IFB_THRESHOLD);
-	val1 = QLCRD32(adapter, QLC_83XX_PORT3_IFB_THRESHOLD);
+	val = QLCRD32(adapter, QLC_83XX_PORT2_IFB_THRESHOLD, &err);
+	if (err == -EIO)
+		return;
+	val1 = QLCRD32(adapter, QLC_83XX_PORT3_IFB_THRESHOLD, &err);
+	if (err == -EIO)
+		return;
 	dev_info(&adapter->pdev->dev,
 		 "IFB-Pause Thresholds: Port 2:0x%x, Port 3:0x%x\n",
 		 val, val1);
@@ -1403,7 +1441,7 @@ static void qlcnic_83xx_take_eport_out_o
 static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev)
 {
 	u32 heartbeat, peg_status;
-	int retries, ret = -EIO;
+	int retries, ret = -EIO, err = 0;
 
 	retries = QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT;
 	p_dev->heartbeat = QLC_SHARED_REG_RD32(p_dev,
@@ -1431,11 +1469,11 @@ static int qlcnic_83xx_check_heartbeat(s
 			 "PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n"
 			 "PEG_NET_4_PC: 0x%x\n", peg_status,
 			 QLC_SHARED_REG_RD32(p_dev, QLCNIC_PEG_HALT_STATUS2),
-			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_0),
-			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_1),
-			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_2),
-			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_3),
-			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_4));
+			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_0, &err),
+			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_1, &err),
+			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_2, &err),
+			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_3, &err),
+			 QLCRD32(p_dev, QLC_83XX_CRB_PEG_NET_4, &err));
 
 		if (QLCNIC_FWERROR_CODE(peg_status) == 0x67)
 			dev_err(&p_dev->pdev->dev,
@@ -1479,18 +1517,22 @@ int qlcnic_83xx_check_hw_status(struct q
 static int qlcnic_83xx_poll_reg(struct qlcnic_adapter *p_dev, u32 addr,
 				int duration, u32 mask, u32 status)
 {
+	int timeout_error, err = 0;
 	u32 value;
-	int timeout_error;
 	u8 retries;
 
-	value = qlcnic_83xx_rd_reg_indirect(p_dev, addr);
+	value = QLCRD32(p_dev, addr, &err);
+	if (err == -EIO)
+		return err;
 	retries = duration / 10;
 
 	do {
 		if ((value & mask) != status) {
 			timeout_error = 1;
 			msleep(duration / 10);
-			value = qlcnic_83xx_rd_reg_indirect(p_dev, addr);
+			value = QLCRD32(p_dev, addr, &err);
+			if (err == -EIO)
+				return err;
 		} else {
 			timeout_error = 0;
 			break;
@@ -1532,9 +1574,18 @@ static int qlcnic_83xx_reset_template_ch
 
 int qlcnic_83xx_get_reset_instruction_template(struct qlcnic_adapter *p_dev)
 {
-	u8 *p_buff;
-	u32 addr, count;
 	struct qlcnic_hardware_context *ahw = p_dev->ahw;
+	u32 addr, count, prev_ver, curr_ver;
+	u8 *p_buff;
+
+	if (ahw->reset.buff != NULL) {
+		prev_ver = p_dev->fw_version;
+		curr_ver = qlcnic_83xx_get_fw_version(p_dev);
+		if (curr_ver > prev_ver)
+			kfree(ahw->reset.buff);
+		else
+			return 0;
+	}
 
 	ahw->reset.seq_error = 0;
 	ahw->reset.buff = kzalloc(QLC_83XX_RESTART_TEMPLATE_SIZE, GFP_KERNEL);
@@ -1575,9 +1626,12 @@ int qlcnic_83xx_get_reset_instruction_te
 static void qlcnic_83xx_read_write_crb_reg(struct qlcnic_adapter *p_dev,
 					   u32 raddr, u32 waddr)
 {
-	int value;
+	int err = 0;
+	u32 value;
 
-	value = qlcnic_83xx_rd_reg_indirect(p_dev, raddr);
+	value = QLCRD32(p_dev, raddr, &err);
+	if (err == -EIO)
+		return;
 	qlcnic_83xx_wrt_reg_indirect(p_dev, waddr, value);
 }
 
@@ -1586,12 +1640,16 @@ static void qlcnic_83xx_rmw_crb_reg(stru
 				    u32 raddr, u32 waddr,
 				    struct qlc_83xx_rmw *p_rmw_hdr)
 {
-	int value;
+	int err = 0;
+	u32 value;
 
-	if (p_rmw_hdr->index_a)
+	if (p_rmw_hdr->index_a) {
 		value = p_dev->ahw->reset.array[p_rmw_hdr->index_a];
-	else
-		value = qlcnic_83xx_rd_reg_indirect(p_dev, raddr);
+	} else {
+		value = QLCRD32(p_dev, raddr, &err);
+		if (err == -EIO)
+			return;
+	}
 
 	value &= p_rmw_hdr->mask;
 	value <<= p_rmw_hdr->shl;
@@ -1644,7 +1702,7 @@ static void qlcnic_83xx_poll_list(struct
 	long delay;
 	struct qlc_83xx_entry *entry;
 	struct qlc_83xx_poll *poll;
-	int i;
+	int i, err = 0;
 	unsigned long arg1, arg2;
 
 	poll = (struct qlc_83xx_poll *)((char *)p_hdr +
@@ -1668,10 +1726,12 @@ static void qlcnic_83xx_poll_list(struct
 							 arg1, delay,
 							 poll->mask,
 							 poll->status)){
-					qlcnic_83xx_rd_reg_indirect(p_dev,
-								    arg1);
-					qlcnic_83xx_rd_reg_indirect(p_dev,
-								    arg2);
+					QLCRD32(p_dev, arg1, &err);
+					if (err == -EIO)
+						return;
+					QLCRD32(p_dev, arg2, &err);
+					if (err == -EIO)
+						return;
 				}
 			}
 		}
@@ -1737,7 +1797,7 @@ static void qlcnic_83xx_poll_read_list(s
 				       struct qlc_83xx_entry_hdr *p_hdr)
 {
 	long delay;
-	int index, i, j;
+	int index, i, j, err;
 	struct qlc_83xx_quad_entry *entry;
 	struct qlc_83xx_poll *poll;
 	unsigned long addr;
@@ -1757,7 +1817,10 @@ static void qlcnic_83xx_poll_read_list(s
 						  poll->mask, poll->status)){
 				index = p_dev->ahw->reset.array_index;
 				addr = entry->dr_addr;
-				j = qlcnic_83xx_rd_reg_indirect(p_dev, addr);
+				j = QLCRD32(p_dev, addr, &err);
+				if (err == -EIO)
+					return;
+
 				p_dev->ahw->reset.array[index++] = j;
 
 				if (index == QLC_83XX_MAX_RESET_SEQ_ENTRIES)
@@ -2062,7 +2125,11 @@ static void qlcnic_83xx_clear_function_r
 	audit_mask = QLCRDX(adapter->ahw, QLC_83XX_IDC_DRV_AUDIT);
 
 	if (IS_QLC_83XX_USED(adapter, presence_mask, audit_mask)) {
-		qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_STOP_NIC_FUNC);
+		status = qlcnic_alloc_mbx_args(&cmd, adapter,
+					       QLCNIC_CMD_STOP_NIC_FUNC);
+		if (status)
+			return;
+
 		cmd.req.arg[1] = BIT_31;
 		status = qlcnic_issue_cmd(adapter, &cmd);
 		if (status)
@@ -2088,6 +2155,8 @@ int qlcnic_83xx_init(struct qlcnic_adapt
 	set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
 	qlcnic_83xx_clear_function_resources(adapter);
 
+	INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);
+
 	/* register for NIC IDC AEN Events */
 	qlcnic_83xx_register_nic_idc_func(adapter, 1);
 
@@ -2105,8 +2174,6 @@ int qlcnic_83xx_init(struct qlcnic_adapt
 	if (adapter->nic_ops->init_driver(adapter))
 		return -EIO;
 
-	INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);
-
 	/* Periodically monitor device status */
 	qlcnic_83xx_idc_poll_dev_state(&adapter->fw_work.work);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,30 +39,21 @@ int qlcnic_83xx_disable_vnic_mode(struct
 	return 0;
 }
 
-static int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter)
+int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter)
 {
 	u8 id;
-	int i, ret = -EBUSY;
+	int ret = -EBUSY;
 	u32 data = QLCNIC_MGMT_FUNC;
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
 	if (qlcnic_83xx_lock_driver(adapter))
 		return ret;
 
-	if (qlcnic_config_npars) {
-		for (i = 0; i < ahw->act_pci_func; i++) {
-			id = adapter->npars[i].pci_func;
-			if (id == ahw->pci_func)
-				continue;
-			data |= qlcnic_config_npars &
-				QLC_83XX_SET_FUNC_OPMODE(0x3, id);
-		}
-	} else {
-		data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
-		data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, ahw->pci_func)) |
-		       QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC,
-						ahw->pci_func);
-	}
+	id = ahw->pci_func;
+	data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
+	data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, id)) |
+	       QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC, id);
+
 	QLCWRX(adapter->ahw, QLC_83XX_DRV_OP_MODE, data);
 
 	qlcnic_83xx_unlock_driver(adapter);
@@ -196,20 +187,24 @@ int qlcnic_83xx_config_vnic_opmode(struc
 	else
 		priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
 							 ahw->pci_func);
-
-	if (priv_level == QLCNIC_NON_PRIV_FUNC) {
+	switch (priv_level) {
+	case QLCNIC_NON_PRIV_FUNC:
 		ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
 		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
 		nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic;
-	} else if (priv_level == QLCNIC_PRIV_FUNC) {
+		break;
+	case QLCNIC_PRIV_FUNC:
 		ahw->op_mode = QLCNIC_PRIV_FUNC;
 		ahw->idc.state_entry = qlcnic_83xx_idc_vnic_pf_entry;
 		nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic;
-	} else if (priv_level == QLCNIC_MGMT_FUNC) {
+		break;
+	case QLCNIC_MGMT_FUNC:
 		ahw->op_mode = QLCNIC_MGMT_FUNC;
 		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
 		nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic;
-	} else {
+		break;
+	default:
+		dev_err(&adapter->pdev->dev, "Invalid Virtual NIC opmode\n");
 		return -EIO;
 	}
 
@@ -218,8 +213,29 @@ int qlcnic_83xx_config_vnic_opmode(struc
 	else
 		adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
 
-	adapter->ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
-	adapter->ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO;
+	ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
+	ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO;
+
+	return 0;
+}
+
+int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	struct qlc_83xx_idc *idc = &ahw->idc;
+	u32 state;
+
+	state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
+	while (state != QLCNIC_DEV_NPAR_OPER && idc->vnic_wait_limit--) {
+		msleep(1000);
+		state = QLCRDX(ahw, QLC_83XX_VNIC_STATE);
+	}
+
+	if (!idc->vnic_wait_limit) {
+		dev_err(&adapter->pdev->dev,
+			"vNIC mode not operational, state check timed out.\n");
+		return -EIO;
+	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,8 @@ static const struct qlcnic_mailbox_metad
 	{QLCNIC_CMD_CONFIG_PORT, 4, 1},
 	{QLCNIC_CMD_TEMP_SIZE, 4, 4},
 	{QLCNIC_CMD_GET_TEMP_HDR, 4, 1},
-	{QLCNIC_CMD_SET_DRV_VER, 4, 1},
+	{QLCNIC_CMD_82XX_SET_DRV_VER, 4, 1},
+	{QLCNIC_CMD_GET_LED_STATUS, 4, 2},
 };
 
 static inline u32 qlcnic_get_cmd_signature(struct qlcnic_hardware_context *ahw)
@@ -103,7 +104,7 @@ static u32
 qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
 {
 	u32 rsp;
-	int timeout = 0;
+	int timeout = 0, err = 0;
 
 	do {
 		/* give atleast 1ms for firmware to respond */
@@ -112,7 +113,7 @@ qlcnic_poll_rsp(struct qlcnic_adapter *a
 		if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT)
 			return QLCNIC_CDRP_RSP_TIMEOUT;
 
-		rsp = QLCRD32(adapter, QLCNIC_CDRP_CRB_OFFSET);
+		rsp = QLCRD32(adapter, QLCNIC_CDRP_CRB_OFFSET, &err);
 	} while (!QLCNIC_CDRP_IS_RSP(rsp));
 
 	return rsp;
@@ -121,7 +122,7 @@ qlcnic_poll_rsp(struct qlcnic_adapter *a
 int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter,
 			  struct qlcnic_cmd_args *cmd)
 {
-	int i;
+	int i, err = 0;
 	u32 rsp;
 	u32 signature;
 	struct pci_dev *pdev = adapter->pdev;
@@ -147,7 +148,7 @@ int qlcnic_82xx_issue_cmd(struct qlcnic_
 		dev_err(&pdev->dev, "card response timeout.\n");
 		cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
 	} else if (rsp == QLCNIC_CDRP_RSP_FAIL) {
-		cmd->rsp.arg[0] = QLCRD32(adapter, QLCNIC_CDRP_ARG(1));
+		cmd->rsp.arg[0] = QLCRD32(adapter, QLCNIC_CDRP_ARG(1), &err);
 		switch (cmd->rsp.arg[0]) {
 		case QLCNIC_RCODE_INVALID_ARGS:
 			fmt = "CDRP invalid args: [%d]\n";
@@ -174,14 +175,14 @@ int qlcnic_82xx_issue_cmd(struct qlcnic_
 		cmd->rsp.arg[0] = QLCNIC_RCODE_SUCCESS;
 
 	for (i = 1; i < cmd->rsp.num; i++)
-		cmd->rsp.arg[i] = QLCRD32(adapter, QLCNIC_CDRP_ARG(i));
+		cmd->rsp.arg[i] = QLCRD32(adapter, QLCNIC_CDRP_ARG(i), &err);
 
 	/* Release semaphore */
 	qlcnic_api_unlock(adapter);
 	return cmd->rsp.arg[0];
 }
 
-int qlcnic_fw_cmd_set_drv_version(struct qlcnic_adapter *adapter)
+int qlcnic_fw_cmd_set_drv_version(struct qlcnic_adapter *adapter, u32 fw_cmd)
 {
 	struct qlcnic_cmd_args cmd;
 	u32 arg1, arg2, arg3;
@@ -193,7 +194,10 @@ int qlcnic_fw_cmd_set_drv_version(struct
 		 _QLCNIC_LINUX_MAJOR, _QLCNIC_LINUX_MINOR,
 		 _QLCNIC_LINUX_SUBVERSION);
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_DRV_VER);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, fw_cmd);
+	if (err)
+		return err;
+
 	memcpy(&arg1, drv_string, sizeof(u32));
 	memcpy(&arg2, drv_string + 4, sizeof(u32));
 	memcpy(&arg3, drv_string + 8, sizeof(u32));
@@ -206,10 +210,10 @@ int qlcnic_fw_cmd_set_drv_version(struct
 	if (err) {
 		dev_info(&adapter->pdev->dev,
 			 "Failed to set driver version in firmware\n");
-		return -EIO;
+		err = -EIO;
 	}
-
-	return 0;
+	qlcnic_free_mbx_args(&cmd);
+	return err;
 }
 
 int
@@ -221,7 +225,10 @@ qlcnic_fw_cmd_set_mtu(struct qlcnic_adap
 
 	if (recv_ctx->state != QLCNIC_HOST_CTX_STATE_ACTIVE)
 		return err;
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_MTU);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_MTU);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = recv_ctx->context_id;
 	cmd.req.arg[2] = mtu;
 
@@ -335,7 +342,10 @@ int qlcnic_82xx_fw_cmd_create_rx_ctx(str
 	}
 
 	phys_addr = hostrq_phys_addr;
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_RX_CTX);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_RX_CTX);
+	if (err)
+		goto out_free_rsp;
+
 	cmd.req.arg[1] = MSD(phys_addr);
 	cmd.req.arg[2] = LSD(phys_addr);
 	cmd.req.arg[3] = rq_size;
@@ -373,10 +383,10 @@ int qlcnic_82xx_fw_cmd_create_rx_ctx(str
 	recv_ctx->context_id = le16_to_cpu(prsp->context_id);
 	recv_ctx->virt_port = prsp->virt_port;
 
+	qlcnic_free_mbx_args(&cmd);
 out_free_rsp:
 	dma_free_coherent(&adapter->pdev->dev, rsp_size, prsp,
-		cardrsp_phys_addr);
-	qlcnic_free_mbx_args(&cmd);
+			  cardrsp_phys_addr);
 out_free_rq:
 	dma_free_coherent(&adapter->pdev->dev, rq_size, prq, hostrq_phys_addr);
 	return err;
@@ -388,7 +398,10 @@ void qlcnic_82xx_fw_cmd_del_rx_ctx(struc
 	struct qlcnic_cmd_args cmd;
 	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX);
+	if (err)
+		return;
+
 	cmd.req.arg[1] = recv_ctx->context_id;
 	err = qlcnic_issue_cmd(adapter, &cmd);
 	if (err)
@@ -457,7 +470,10 @@ int qlcnic_82xx_fw_cmd_create_tx_ctx(str
 
 	phys_addr = rq_phys_addr;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
+	if (err)
+		goto out_free_rsp;
+
 	cmd.req.arg[1] = MSD(phys_addr);
 	cmd.req.arg[2] = LSD(phys_addr);
 	cmd.req.arg[3] = rq_size;
@@ -473,12 +489,13 @@ int qlcnic_82xx_fw_cmd_create_tx_ctx(str
 		err = -EIO;
 	}
 
+	qlcnic_free_mbx_args(&cmd);
+
+out_free_rsp:
 	dma_free_coherent(&adapter->pdev->dev, rsp_size, rsp_addr,
 			  rsp_phys_addr);
-
 out_free_rq:
 	dma_free_coherent(&adapter->pdev->dev, rq_size, rq_addr, rq_phys_addr);
-	qlcnic_free_mbx_args(&cmd);
 
 	return err;
 }
@@ -487,8 +504,11 @@ void qlcnic_82xx_fw_cmd_del_tx_ctx(struc
 				   struct qlcnic_host_tx_ring *tx_ring)
 {
 	struct qlcnic_cmd_args cmd;
+	int ret;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX);
+	ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX);
+	if (ret)
+		return;
 
 	cmd.req.arg[1] = tx_ring->ctx_id;
 	if (qlcnic_issue_cmd(adapter, &cmd))
@@ -503,7 +523,10 @@ qlcnic_fw_cmd_set_port(struct qlcnic_ada
 	int err;
 	struct qlcnic_cmd_args cmd;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_PORT);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_PORT);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = config;
 	err = qlcnic_issue_cmd(adapter, &cmd);
 	qlcnic_free_mbx_args(&cmd);
@@ -707,7 +730,10 @@ int qlcnic_82xx_get_mac_address(struct q
 	struct qlcnic_cmd_args cmd;
 	u32 mac_low, mac_high;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = adapter->ahw->pci_func | BIT_8;
 	err = qlcnic_issue_cmd(adapter, &cmd);
 
@@ -746,7 +772,10 @@ int qlcnic_82xx_get_nic_info(struct qlcn
 
 	nic_info = nic_info_addr;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
+	if (err)
+		goto out_free_dma;
+
 	cmd.req.arg[1] = MSD(nic_dma_t);
 	cmd.req.arg[2] = LSD(nic_dma_t);
 	cmd.req.arg[3] = (func_id << 16 | nic_size);
@@ -768,9 +797,10 @@ int qlcnic_82xx_get_nic_info(struct qlcn
 		npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu);
 	}
 
+	qlcnic_free_mbx_args(&cmd);
+out_free_dma:
 	dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr,
 			  nic_dma_t);
-	qlcnic_free_mbx_args(&cmd);
 
 	return err;
 }
@@ -807,7 +837,10 @@ int qlcnic_82xx_set_nic_info(struct qlcn
 	nic_info->min_tx_bw = cpu_to_le16(nic->min_tx_bw);
 	nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw);
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
+	if (err)
+		goto out_free_dma;
+
 	cmd.req.arg[1] = MSD(nic_dma_t);
 	cmd.req.arg[2] = LSD(nic_dma_t);
 	cmd.req.arg[3] = ((nic->pci_func << 16) | nic_size);
@@ -819,9 +852,10 @@ int qlcnic_82xx_set_nic_info(struct qlcn
 		err = -EIO;
 	}
 
-	dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr,
-		nic_dma_t);
 	qlcnic_free_mbx_args(&cmd);
+out_free_dma:
+	dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr,
+			  nic_dma_t);
 
 	return err;
 }
@@ -845,7 +879,10 @@ int qlcnic_82xx_get_pci_info(struct qlcn
 		return -ENOMEM;
 
 	npar = pci_info_addr;
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
+	if (err)
+		goto out_free_dma;
+
 	cmd.req.arg[1] = MSD(pci_info_dma_t);
 	cmd.req.arg[2] = LSD(pci_info_dma_t);
 	cmd.req.arg[3] = pci_size;
@@ -873,20 +910,22 @@ int qlcnic_82xx_get_pci_info(struct qlcn
 		err = -EIO;
 	}
 
+	qlcnic_free_mbx_args(&cmd);
+out_free_dma:
 	dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr,
 		pci_info_dma_t);
-	qlcnic_free_mbx_args(&cmd);
 
 	return err;
 }
 
 /* Configure eSwitch for port mirroring */
 int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
-				u8 enable_mirroring, u8 pci_func)
+				 u8 enable_mirroring, u8 pci_func)
 {
+	struct device *dev = &adapter->pdev->dev;
+	struct qlcnic_cmd_args cmd;
 	int err = -EIO;
 	u32 arg1;
-	struct qlcnic_cmd_args cmd;
 
 	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC ||
 	    !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE))
@@ -895,18 +934,20 @@ int qlcnic_config_port_mirroring(struct
 	arg1 = id | (enable_mirroring ? BIT_4 : 0);
 	arg1 |= pci_func << 8;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORTMIRRORING);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter,
+				    QLCNIC_CMD_SET_PORTMIRRORING);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = arg1;
 	err = qlcnic_issue_cmd(adapter, &cmd);
 
 	if (err != QLCNIC_RCODE_SUCCESS)
-		dev_err(&adapter->pdev->dev,
-			"Failed to configure port mirroring%d on eswitch:%d\n",
+		dev_err(dev, "Failed to configure port mirroring for vNIC function %d on eSwitch %d\n",
 			pci_func, id);
 	else
-		dev_info(&adapter->pdev->dev,
-			"Configured eSwitch %d for port mirroring:%d\n",
-			id, pci_func);
+		dev_info(dev, "Configured port mirroring for vNIC function %d on eSwitch %d\n",
+			 pci_func, id);
 	qlcnic_free_mbx_args(&cmd);
 
 	return err;
@@ -941,7 +982,11 @@ int qlcnic_get_port_stats(struct qlcnic_
 	arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12;
 	arg1 |= rx_tx << 15 | stats_size << 16;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_ESWITCH_STATS);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter,
+				    QLCNIC_CMD_GET_ESWITCH_STATS);
+	if (err)
+		goto out_free_dma;
+
 	cmd.req.arg[1] = arg1;
 	cmd.req.arg[2] = MSD(stats_dma_t);
 	cmd.req.arg[3] = LSD(stats_dma_t);
@@ -963,9 +1008,10 @@ int qlcnic_get_port_stats(struct qlcnic_
 		esw_stats->numbytes = le64_to_cpu(stats->numbytes);
 	}
 
-	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,
-		stats_dma_t);
 	qlcnic_free_mbx_args(&cmd);
+out_free_dma:
+	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,
+			  stats_dma_t);
 
 	return err;
 }
@@ -989,7 +1035,10 @@ int qlcnic_get_mac_stats(struct qlcnic_a
 	if (!stats_addr)
 		return -ENOMEM;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_MAC_STATS);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_MAC_STATS);
+	if (err)
+		goto out_free_dma;
+
 	cmd.req.arg[1] = stats_size << 16;
 	cmd.req.arg[2] = MSD(stats_dma_t);
 	cmd.req.arg[3] = LSD(stats_dma_t);
@@ -1020,11 +1069,12 @@ int qlcnic_get_mac_stats(struct qlcnic_a
 			"%s: Get mac stats failed, err=%d.\n", __func__, err);
 	}
 
-	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,
-		stats_dma_t);
-
 	qlcnic_free_mbx_args(&cmd);
 
+out_free_dma:
+	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,
+			  stats_dma_t);
+
 	return err;
 }
 
@@ -1108,7 +1158,11 @@ int qlcnic_clear_esw_stats(struct qlcnic
 	arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12;
 	arg1 |= BIT_14 | rx_tx << 15;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_ESWITCH_STATS);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter,
+				    QLCNIC_CMD_GET_ESWITCH_STATS);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = arg1;
 	err = qlcnic_issue_cmd(adapter, &cmd);
 	qlcnic_free_mbx_args(&cmd);
@@ -1121,17 +1175,19 @@ err_ret:
 	return -EIO;
 }
 
-static int
-__qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
-					u32 *arg1, u32 *arg2)
+static int __qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter,
+					    u32 *arg1, u32 *arg2)
 {
-	int err = -EIO;
+	struct device *dev = &adapter->pdev->dev;
 	struct qlcnic_cmd_args cmd;
-	u8 pci_func;
-	pci_func = (*arg1 >> 8);
+	u8 pci_func = *arg1 >> 8;
+	int err;
+
+	err = qlcnic_alloc_mbx_args(&cmd, adapter,
+				    QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG);
+	if (err)
+		return err;
 
-	qlcnic_alloc_mbx_args(&cmd, adapter,
-			      QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG);
 	cmd.req.arg[1] = *arg1;
 	err = qlcnic_issue_cmd(adapter, &cmd);
 	*arg1 = cmd.rsp.arg[1];
@@ -1139,12 +1195,11 @@ __qlcnic_get_eswitch_port_config(struct
 	qlcnic_free_mbx_args(&cmd);
 
 	if (err == QLCNIC_RCODE_SUCCESS)
-		dev_info(&adapter->pdev->dev,
-			 "eSwitch port config for pci func %d\n", pci_func);
+		dev_info(dev, "Get eSwitch port config for vNIC function %d\n",
+			 pci_func);
 	else
-		dev_err(&adapter->pdev->dev,
-			"Failed to get eswitch port config for pci func %d\n",
-								pci_func);
+		dev_err(dev, "Failed to get eswitch port config for vNIC function %d\n",
+			pci_func);
 	return err;
 }
 /* Configure eSwitch port
@@ -1157,9 +1212,10 @@ op_type = 1 for port vlan_id
 int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
 		struct qlcnic_esw_func_cfg *esw_cfg)
 {
+	struct device *dev = &adapter->pdev->dev;
+	struct qlcnic_cmd_args cmd;
 	int err = -EIO, index;
 	u32 arg1, arg2 = 0;
-	struct qlcnic_cmd_args cmd;
 	u8 pci_func;
 
 	if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
@@ -1209,18 +1265,22 @@ int qlcnic_config_switch_port(struct qlc
 		return err;
 	}
 
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_ESWITCH);
+	err = qlcnic_alloc_mbx_args(&cmd, adapter,
+				    QLCNIC_CMD_CONFIGURE_ESWITCH);
+	if (err)
+		return err;
+
 	cmd.req.arg[1] = arg1;
 	cmd.req.arg[2] = arg2;
 	err = qlcnic_issue_cmd(adapter, &cmd);
 	qlcnic_free_mbx_args(&cmd);
 
 	if (err != QLCNIC_RCODE_SUCCESS)
-		dev_err(&adapter->pdev->dev,
-			"Failed to configure eswitch pci func %d\n", pci_func);
+		dev_err(dev, "Failed to configure eswitch for vNIC function %d\n",
+			pci_func);
 	else
-		dev_info(&adapter->pdev->dev,
-			 "Configured eSwitch for pci func %d\n", pci_func);
+		dev_info(dev, "Configured eSwitch for vNIC function %d\n",
+			 pci_func);
 
 	return err;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,6 +150,7 @@ static const char qlcnic_gstrings_test[]
 	"Link_Test_on_offline",
 	"Interrupt_Test_offline",
 	"Internal_Loopback_offline",
+	"External_Loopback_offline",
 	"EEPROM_Test_offline"
 };
 
@@ -266,7 +267,7 @@ int qlcnic_82xx_get_settings(struct qlcn
 {
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	u32 speed, reg;
-	int check_sfp_module = 0;
+	int check_sfp_module = 0, err = 0;
 	u16 pcifn = ahw->pci_func;
 
 	/* read which mode */
@@ -289,7 +290,7 @@ int qlcnic_82xx_get_settings(struct qlcn
 
 	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 		u32 val = 0;
-		val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
+		val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR, &err);
 
 		if (val == QLCNIC_PORT_MODE_802_3_AP) {
 			ecmd->supported = SUPPORTED_1000baseT_Full;
@@ -300,9 +301,13 @@ int qlcnic_82xx_get_settings(struct qlcn
 		}
 
 		if (netif_running(adapter->netdev) && ahw->has_link_events) {
-			reg = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
-			speed = P3P_LINK_SPEED_VAL(pcifn, reg);
-			ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
+			if (ahw->linkup) {
+				reg = QLCRD32(adapter,
+					      P3P_LINK_SPEED_REG(pcifn), &err);
+				speed = P3P_LINK_SPEED_VAL(pcifn, reg);
+				ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
+			}
+
 			ethtool_cmd_speed_set(ecmd, ahw->link_speed);
 			ecmd->autoneg = ahw->link_autoneg;
 			ecmd->duplex = ahw->link_duplex;
@@ -463,13 +468,14 @@ static int qlcnic_set_settings(struct ne
 static int qlcnic_82xx_get_registers(struct qlcnic_adapter *adapter,
 				     u32 *regs_buff)
 {
-	int i, j = 0;
+	int i, j = 0, err = 0;
 
 	for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++)
 		regs_buff[i] = QLC_SHARED_REG_RD32(adapter, diag_registers[j]);
 	j = 0;
 	while (ext_diag_registers[j] != -1)
-		regs_buff[i++] = QLCRD32(adapter, ext_diag_registers[j++]);
+		regs_buff[i++] = QLCRD32(adapter, ext_diag_registers[j++],
+					 &err);
 	return i;
 }
 
@@ -519,13 +525,16 @@ qlcnic_get_regs(struct net_device *dev,
 static u32 qlcnic_test_link(struct net_device *dev)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	int err = 0;
 	u32 val;
 
 	if (qlcnic_83xx_check(adapter)) {
 		val = qlcnic_83xx_test_link(adapter);
 		return (val & 1) ? 0 : 1;
 	}
-	val = QLCRD32(adapter, CRB_XG_STATE_P3P);
+	val = QLCRD32(adapter, CRB_XG_STATE_P3P, &err);
+	if (err == -EIO)
+		return err;
 	val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
 	return (val == XG_LINK_UP_P3P) ? 0 : 1;
 }
@@ -658,6 +667,7 @@ qlcnic_get_pauseparam(struct net_device
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	int port = adapter->ahw->physical_port;
+	int err = 0;
 	__u32 val;
 
 	if (qlcnic_83xx_check(adapter)) {
@@ -668,9 +678,13 @@ qlcnic_get_pauseparam(struct net_device
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 			return;
 		/* get flow control settings */
-		val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
+		val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
+		if (err == -EIO)
+			return;
 		pause->rx_pause = qlcnic_gb_get_rx_flowctl(val);
-		val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
+		val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
+		if (err == -EIO)
+			return;
 		switch (port) {
 		case 0:
 			pause->tx_pause = !(qlcnic_gb_get_gb0_mask(val));
@@ -690,7 +704,9 @@ qlcnic_get_pauseparam(struct net_device
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 			return;
 		pause->rx_pause = 1;
-		val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
+		val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
+		if (err == -EIO)
+			return;
 		if (port == 0)
 			pause->tx_pause = !(qlcnic_xg_get_xg0_mask(val));
 		else
@@ -707,6 +723,7 @@ qlcnic_set_pauseparam(struct net_device
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	int port = adapter->ahw->physical_port;
+	int err = 0;
 	__u32 val;
 
 	if (qlcnic_83xx_check(adapter))
@@ -717,7 +734,9 @@ qlcnic_set_pauseparam(struct net_device
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 			return -EIO;
 		/* set flow control */
-		val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port));
+		val = QLCRD32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), &err);
+		if (err == -EIO)
+			return err;
 
 		if (pause->rx_pause)
 			qlcnic_gb_rx_flowctl(val);
@@ -728,7 +747,9 @@ qlcnic_set_pauseparam(struct net_device
 				val);
 		QLCWR32(adapter, QLCNIC_NIU_GB_MAC_CONFIG_0(port), val);
 		/* set autoneg */
-		val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL);
+		val = QLCRD32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, &err);
+		if (err == -EIO)
+			return err;
 		switch (port) {
 		case 0:
 			if (pause->tx_pause)
@@ -764,7 +785,9 @@ qlcnic_set_pauseparam(struct net_device
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 			return -EIO;
 
-		val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL);
+		val = QLCRD32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, &err);
+		if (err == -EIO)
+			return err;
 		if (port == 0) {
 			if (pause->tx_pause)
 				qlcnic_xg_unset_xg0_mask(val);
@@ -788,11 +811,14 @@ static int qlcnic_reg_test(struct net_de
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 	u32 data_read;
+	int err = 0;
 
 	if (qlcnic_83xx_check(adapter))
 		return qlcnic_83xx_reg_test(adapter);
 
-	data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0));
+	data_read = QLCRD32(adapter, QLCNIC_PCIX_PH_REG(0), &err);
+	if (err == -EIO)
+		return err;
 	if ((data_read & 0xffff) != adapter->pdev->vendor)
 		return 1;
 
@@ -846,7 +872,9 @@ static int qlcnic_irq_test(struct net_de
 		goto clear_diag_irq;
 
 	ahw->diag_cnt = 0;
-	qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
+	ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
+	if (ret)
+		goto free_diag_res;
 
 	cmd.req.arg[1] = ahw->pci_func;
 	ret = qlcnic_issue_cmd(adapter, &cmd);
@@ -858,6 +886,8 @@ static int qlcnic_irq_test(struct net_de
 
 done:
 	qlcnic_free_mbx_args(&cmd);
+
+free_diag_res:
 	qlcnic_diag_free_res(netdev, max_sds_rings);
 
 clear_diag_irq:
@@ -1022,8 +1052,15 @@ qlcnic_diag_test(struct net_device *dev,
 		if (data[3])
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
-		data[4] = qlcnic_eeprom_test(dev);
-		if (data[4])
+		if (eth_test->flags & ETH_TEST_FL_EXTERNAL_LB) {
+			data[4] = qlcnic_loopback_test(dev, QLCNIC_ELB_MODE);
+			if (data[4])
+				eth_test->flags |= ETH_TEST_FL_FAILED;
+			eth_test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
+		}
+
+		data[5] = qlcnic_eeprom_test(dev);
+		if (data[5])
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 	}
 }
@@ -1253,17 +1290,20 @@ qlcnic_get_wol(struct net_device *dev, s
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 	u32 wol_cfg;
+	int err = 0;
 
 	if (qlcnic_83xx_check(adapter))
 		return;
 	wol->supported = 0;
 	wol->wolopts = 0;
 
-	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
+	if (err == -EIO)
+		return;
 	if (wol_cfg & (1UL << adapter->portnum))
 		wol->supported |= WAKE_MAGIC;
 
-	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
 	if (wol_cfg & (1UL << adapter->portnum))
 		wol->wolopts |= WAKE_MAGIC;
 }
@@ -1273,17 +1313,22 @@ qlcnic_set_wol(struct net_device *dev, s
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 	u32 wol_cfg;
+	int err = 0;
 
 	if (qlcnic_83xx_check(adapter))
 		return -EOPNOTSUPP;
 	if (wol->wolopts & ~WAKE_MAGIC)
 		return -EINVAL;
 
-	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
+	if (err == -EIO)
+		return err;
 	if (!(wol_cfg & (1 << adapter->portnum)))
 		return -EOPNOTSUPP;
 
-	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
+	if (err == -EIO)
+		return err;
 	if (wol->wolopts & WAKE_MAGIC)
 		wol_cfg |= 1UL << adapter->portnum;
 	else
@@ -1536,7 +1581,7 @@ qlcnic_set_dump(struct net_device *netde
 		return 0;
 	case QLCNIC_SET_QUIESCENT:
 	case QLCNIC_RESET_QUIESCENT:
-		state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE);
+		state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE);
 		if (state == QLCNIC_DEV_FAILED || (state == QLCNIC_DEV_BADBAD))
 			netdev_info(netdev, "Device in FAILED state\n");
 		return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h	2013-07-01 10:37:01.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h	2013-08-31 17:56:34.000000000 -0400
@@ -38,8 +38,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 2
-#define _QLCNIC_LINUX_SUBVERSION 42
-#define QLCNIC_LINUX_VERSIONID  "5.2.42"
+#define _QLCNIC_LINUX_SUBVERSION 44
+#define QLCNIC_LINUX_VERSIONID  "5.2.44"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -303,7 +303,6 @@ extern int qlcnic_use_msi;
 extern int qlcnic_use_msi_x;
 extern int qlcnic_auto_fw_reset;
 extern int qlcnic_load_fw_file;
-extern int qlcnic_config_npars;
 
 /* Number of status descriptors to handle per interrupt */
 #define MAX_STATUS_HANDLE	(64)
@@ -394,6 +393,9 @@ struct qlcnic_fw_dump {
 	u32	size;	/* total size of the dump */
 	void	*data;	/* dump data area */
 	struct	qlcnic_dump_template_hdr *tmpl_hdr;
+	dma_addr_t phys_addr;
+	void	*dma_buffer;
+	bool	use_pex_dma;
 };
 
 /*
@@ -427,6 +429,7 @@ struct qlcnic_hardware_context {
 	u8 nic_mode;
 	char diag_cnt;
 
+	u16 max_uc_count;
 	u16 port_type;
 	u16 board_type;
 	u16 supported_type;
@@ -443,9 +446,10 @@ struct qlcnic_hardware_context {
 	u16 max_mtu;
 	u32 msg_enable;
 	u16 act_pci_func;
+	u16 max_pci_func;
 
 	u32 capabilities;
-	u32 capabilities2;
+	u32 extra_capability[3];
 	u32 temp;
 	u32 int_vec_bit;
 	u32 fw_hal_version;
@@ -815,7 +819,8 @@ struct qlcnic_mac_list_s {
 
 #define QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG	BIT_2
 #define QLCNIC_FW_CAP2_HW_LRO_IPV6		BIT_3
-#define QLCNIC_FW_CAPABILITY_2_OCBB		BIT_5
+#define QLCNIC_FW_CAPABILITY_SET_DRV_VER	BIT_5
+#define QLCNIC_FW_CAPABILITY_2_BEACON		BIT_7
 
 /* module types */
 #define LINKEVENT_MODULE_NOT_PRESENT			1
@@ -913,6 +918,9 @@ struct qlcnic_ipaddr {
 #define QLCNIC_IS_TSO_CAPABLE(adapter)  \
 	((adapter)->ahw->capabilities & QLCNIC_FW_CAPABILITY_TSO)
 
+#define QLCNIC_BEACON_EANBLE		0xC
+#define QLCNIC_BEACON_DISABLE		0xD
+
 #define QLCNIC_DEF_NUM_STS_DESC_RINGS	4
 #define QLCNIC_MSIX_TBL_SPACE		8192
 #define QLCNIC_PCI_REG_MSIX_TBL 	0x44
@@ -932,6 +940,7 @@ struct qlcnic_ipaddr {
 #define __QLCNIC_SRIOV_ENABLE		10
 #define __QLCNIC_SRIOV_CAPABLE		11
 #define __QLCNIC_MBX_POLL_ENABLE	12
+#define __QLCNIC_DIAG_MODE		13
 
 #define QLCNIC_INTERRUPT_TEST		1
 #define QLCNIC_LOOPBACK_TEST		2
@@ -1391,8 +1400,8 @@ void qlcnic_pci_camqm_write_2M(struct ql
 #define ADDR_IN_RANGE(addr, low, high)	\
 	(((addr) < (high)) && ((addr) >= (low)))
 
-#define QLCRD32(adapter, off) \
-	(adapter->ahw->hw_ops->read_reg)(adapter, off)
+#define QLCRD32(adapter, off, err) \
+	(adapter->ahw->hw_ops->read_reg)(adapter, off, err)
 
 #define QLCWR32(adapter, off, val) \
 	adapter->ahw->hw_ops->write_reg(adapter, off, val)
@@ -1467,7 +1476,7 @@ int qlcnic_nic_del_mac(struct qlcnic_ada
 void qlcnic_82xx_free_mac_list(struct qlcnic_adapter *adapter);
 
 int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu);
-int qlcnic_fw_cmd_set_drv_version(struct qlcnic_adapter *);
+int qlcnic_fw_cmd_set_drv_version(struct qlcnic_adapter *, u32);
 int qlcnic_change_mtu(struct net_device *netdev, int new_mtu);
 netdev_features_t qlcnic_fix_features(struct net_device *netdev,
 	netdev_features_t features);
@@ -1489,7 +1498,9 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_
 int qlcnic_set_max_rss(struct qlcnic_adapter *, u8, size_t);
 int qlcnic_validate_max_rss(struct qlcnic_adapter *, __u32);
 void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
+void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *);
 int qlcnic_enable_msix(struct qlcnic_adapter *, u32);
+void qlcnic_set_drv_version(struct qlcnic_adapter *);
 
 /*  eSwitch management functions */
 int qlcnic_config_switch_port(struct qlcnic_adapter *,
@@ -1543,6 +1554,7 @@ int qlcnic_set_default_offload_settings(
 int qlcnic_reset_npar_config(struct qlcnic_adapter *);
 int qlcnic_set_eswitch_port_config(struct qlcnic_adapter *);
 void qlcnic_add_lb_filter(struct qlcnic_adapter *, struct sk_buff *, int, u16);
+int qlcnic_get_beacon_state(struct qlcnic_adapter *, u8 *);
 int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter);
 int qlcnic_read_mac_addr(struct qlcnic_adapter *);
 int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
@@ -1584,13 +1596,15 @@ struct qlcnic_nic_template {
 	void (*napi_del)(struct qlcnic_adapter *);
 	void (*config_ipaddr)(struct qlcnic_adapter *, __be32, int);
 	irqreturn_t (*clear_legacy_intr)(struct qlcnic_adapter *);
+	int (*shutdown)(struct pci_dev *);
+	int (*resume)(struct qlcnic_adapter *);
 };
 
 /* Adapter hardware abstraction */
 struct qlcnic_hardware_ops {
 	void (*read_crb) (struct qlcnic_adapter *, char *, loff_t, size_t);
 	void (*write_crb) (struct qlcnic_adapter *, char *, loff_t, size_t);
-	int (*read_reg) (struct qlcnic_adapter *, ulong);
+	int (*read_reg) (struct qlcnic_adapter *, ulong, int *);
 	int (*write_reg) (struct qlcnic_adapter *, ulong, u32);
 	void (*get_ocm_win) (struct qlcnic_hardware_context *);
 	int (*get_mac_address) (struct qlcnic_adapter *, u8 *);
@@ -1625,6 +1639,7 @@ struct qlcnic_hardware_ops {
 	int (*config_promisc_mode) (struct qlcnic_adapter *, u32);
 	void (*change_l2_filter) (struct qlcnic_adapter *, u64 *, u16);
 	int (*get_board_info) (struct qlcnic_adapter *);
+	void (*set_mac_filter_count) (struct qlcnic_adapter *);
 	void (*free_mac_list) (struct qlcnic_adapter *);
 };
 
@@ -1647,12 +1662,6 @@ static inline void qlcnic_write_crb(stru
 	adapter->ahw->hw_ops->write_crb(adapter, buf, offset, size);
 }
 
-static inline int qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter,
-				       ulong off)
-{
-	return adapter->ahw->hw_ops->read_reg(adapter, off);
-}
-
 static inline int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter,
 					ulong off, u32 data)
 {
@@ -1787,6 +1796,18 @@ static inline void qlcnic_napi_enable(st
 	adapter->ahw->hw_ops->napi_enable(adapter);
 }
 
+static inline int __qlcnic_shutdown(struct pci_dev *pdev)
+{
+	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+
+	return adapter->nic_ops->shutdown(pdev);
+}
+
+static inline int __qlcnic_resume(struct qlcnic_adapter *adapter)
+{
+	return adapter->nic_ops->resume(adapter);
+}
+
 static inline void qlcnic_napi_disable(struct qlcnic_adapter *adapter)
 {
 	adapter->ahw->hw_ops->napi_disable(adapter);
@@ -1840,6 +1861,12 @@ static inline void qlcnic_free_mac_list(
 	return adapter->ahw->hw_ops->free_mac_list(adapter);
 }
 
+static inline void qlcnic_set_mac_filter_count(struct qlcnic_adapter *adapter)
+{
+	if (adapter->ahw->hw_ops->set_mac_filter_count)
+		adapter->ahw->hw_ops->set_mac_filter_count(adapter);
+}
+
 static inline void qlcnic_dev_request_reset(struct qlcnic_adapter *adapter,
 					    u32 key)
 {
@@ -1886,6 +1913,21 @@ static inline void qlcnic_enable_int(str
 		writel(0xfbff, adapter->tgt_mask_reg);
 }
 
+static inline int qlcnic_get_diag_lock(struct qlcnic_adapter *adapter)
+{
+	return test_and_set_bit(__QLCNIC_DIAG_MODE, &adapter->state);
+}
+
+static inline void qlcnic_release_diag_lock(struct qlcnic_adapter *adapter)
+{
+	clear_bit(__QLCNIC_DIAG_MODE, &adapter->state);
+}
+
+static inline int qlcnic_check_diag_status(struct qlcnic_adapter *adapter)
+{
+	return test_bit(__QLCNIC_DIAG_MODE, &adapter->state);
+}
+
 extern const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops;
 extern const struct ethtool_ops qlcnic_ethtool_ops;
 extern const struct ethtool_ops qlcnic_ethtool_failed_ops;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h	2013-08-25 20:43:22.000000000 -0400
@@ -672,6 +672,7 @@ enum {
 #define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT	10
 
 #define QLCNIC_MAX_MC_COUNT		38
+#define QLCNIC_MAX_UC_COUNT		512
 #define QLCNIC_WATCHDOG_TIMEOUTVALUE	5
 
 #define	ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -317,16 +317,20 @@ static void qlcnic_write_window_reg(u32
 int
 qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
 {
-	int done = 0, timeout = 0;
+	int timeout = 0;
+	int err = 0;
+	u32 done = 0;
 
 	while (!done) {
-		done = QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_LOCK(sem)));
+		done = QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_LOCK(sem)),
+			       &err);
 		if (done == 1)
 			break;
 		if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) {
 			dev_err(&adapter->pdev->dev,
 				"Failed to acquire sem=%d lock; holdby=%d\n",
-				sem, id_reg ? QLCRD32(adapter, id_reg) : -1);
+				sem,
+				id_reg ? QLCRD32(adapter, id_reg, &err) : -1);
 			return -EIO;
 		}
 		msleep(1);
@@ -341,19 +345,22 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapt
 void
 qlcnic_pcie_sem_unlock(struct qlcnic_adapter *adapter, int sem)
 {
-	QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
+	int err = 0;
+
+	QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_UNLOCK(sem)), &err);
 }
 
 int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr)
 {
+	int err = 0;
 	u32 data;
 
 	if (qlcnic_82xx_check(adapter))
 		qlcnic_read_window_reg(addr, adapter->ahw->pci_base0, &data);
 	else {
-		data = qlcnic_83xx_rd_reg_indirect(adapter, addr);
-		if (data == -EIO)
-			return -EIO;
+		data = QLCRD32(adapter, addr, &err);
+		if (err == -EIO)
+			return err;
 	}
 	return data;
 }
@@ -499,6 +506,7 @@ int qlcnic_nic_add_mac(struct qlcnic_ada
 void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
 	struct netdev_hw_addr *ha;
 	static const u8 bcast_addr[ETH_ALEN] = {
 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
@@ -515,25 +523,28 @@ void __qlcnic_set_multi(struct net_devic
 	if (netdev->flags & IFF_PROMISC) {
 		if (!(adapter->flags & QLCNIC_PROMISC_DISABLED))
 			mode = VPORT_MISS_MODE_ACCEPT_ALL;
-		goto send_fw_cmd;
-	}
-
-	if ((netdev->flags & IFF_ALLMULTI) ||
-	    (netdev_mc_count(netdev) > adapter->ahw->max_mc_count)) {
+	} else if ((netdev->flags & IFF_ALLMULTI) ||
+		   (netdev_mc_count(netdev) > ahw->max_mc_count)) {
 		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
-		goto send_fw_cmd;
-	}
-
-	if (!netdev_mc_empty(netdev) && !qlcnic_sriov_vf_check(adapter)) {
-		netdev_for_each_mc_addr(ha, netdev) {
+	} else if (!netdev_mc_empty(netdev) &&
+		   !qlcnic_sriov_vf_check(adapter)) {
+		netdev_for_each_mc_addr(ha, netdev)
 			qlcnic_nic_add_mac(adapter, ha->addr, vlan);
-		}
 	}
 
 	if (qlcnic_sriov_vf_check(adapter))
 		qlcnic_vf_add_mc_list(netdev, vlan);
 
-send_fw_cmd:
+	/* configure unicast MAC address, if there is not sufficient space
+	 * to store all the unicast addresses then enable promiscuous mode
+	 */
+	if (netdev_uc_count(netdev) > ahw->max_uc_count) {
+		mode = VPORT_MISS_MODE_ACCEPT_ALL;
+	} else if (!netdev_uc_empty(netdev)) {
+		netdev_for_each_uc_addr(ha, netdev)
+			qlcnic_nic_add_mac(adapter, ha->addr, vlan);
+	}
+
 	if (!qlcnic_sriov_vf_check(adapter)) {
 		if (mode == VPORT_MISS_MODE_ACCEPT_ALL &&
 		    !adapter->fdb_mac_learn) {
@@ -780,7 +791,8 @@ int qlcnic_82xx_config_hw_lro(struct qlc
 	word = 0;
 	if (enable) {
 		word = QLCNIC_ENABLE_IPV4_LRO | QLCNIC_NO_DEST_IPV4_CHECK;
-		if (adapter->ahw->capabilities2 & QLCNIC_FW_CAP2_HW_LRO_IPV6)
+		if (adapter->ahw->extra_capability[0] &
+		    QLCNIC_FW_CAP2_HW_LRO_IPV6)
 			word |= QLCNIC_ENABLE_IPV6_LRO |
 				QLCNIC_NO_DEST_IPV6_CHECK;
 	}
@@ -1154,7 +1166,8 @@ int qlcnic_82xx_hw_write_wx_2M(struct ql
 	return -EIO;
 }
 
-int qlcnic_82xx_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off)
+int qlcnic_82xx_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off,
+			      int *err)
 {
 	unsigned long flags;
 	int rv;
@@ -1410,7 +1423,7 @@ int qlcnic_pci_mem_read_2M(struct qlcnic
 
 int qlcnic_82xx_get_board_info(struct qlcnic_adapter *adapter)
 {
-	int offset, board_type, magic;
+	int offset, board_type, magic, err = 0;
 	struct pci_dev *pdev = adapter->pdev;
 
 	offset = QLCNIC_FW_MAGIC_OFFSET;
@@ -1430,7 +1443,9 @@ int qlcnic_82xx_get_board_info(struct ql
 	adapter->ahw->board_type = board_type;
 
 	if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) {
-		u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I);
+		u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I, &err);
+		if (err == -EIO)
+			return err;
 		if ((gpio & 0x8000) == 0)
 			board_type = QLCNIC_BRDTYPE_P3P_10G_TP;
 	}
@@ -1470,10 +1485,13 @@ int
 qlcnic_wol_supported(struct qlcnic_adapter *adapter)
 {
 	u32 wol_cfg;
+	int err = 0;
 
-	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV);
+	wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG_NV, &err);
 	if (wol_cfg & (1UL << adapter->portnum)) {
-		wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG);
+		wol_cfg = QLCRD32(adapter, QLCNIC_WOL_CONFIG, &err);
+		if (err == -EIO)
+			return err;
 		if (wol_cfg & (1 << adapter->portnum))
 			return 1;
 	}
@@ -1503,6 +1521,21 @@ int qlcnic_82xx_config_led(struct qlcnic
 	return rv;
 }
 
+int qlcnic_get_beacon_state(struct qlcnic_adapter *adapter, u8 *h_state)
+{
+	struct qlcnic_cmd_args cmd;
+	int err;
+
+	err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_STATUS);
+	if (!err) {
+		err = qlcnic_issue_cmd(adapter, &cmd);
+		if (!err)
+			*h_state = cmd.rsp.arg[1];
+	}
+	qlcnic_free_mbx_args(&cmd);
+	return err;
+}
+
 void qlcnic_82xx_get_func_no(struct qlcnic_adapter *adapter)
 {
 	void __iomem *msix_base_addr;
@@ -1519,6 +1552,7 @@ void qlcnic_82xx_get_func_no(struct qlcn
 void qlcnic_82xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
 			  loff_t offset, size_t size)
 {
+	int err = 0;
 	u32 data;
 	u64 qmdata;
 
@@ -1526,7 +1560,7 @@ void qlcnic_82xx_read_crb(struct qlcnic_
 		qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata);
 		memcpy(buf, &qmdata, size);
 	} else {
-		data = QLCRD32(adapter, offset);
+		data = QLCRD32(adapter, offset, &err);
 		memcpy(buf, &data, size);
 	}
 }
@@ -1555,3 +1589,54 @@ void qlcnic_82xx_api_unlock(struct qlcni
 {
 	qlcnic_pcie_sem_unlock(adapter, 5);
 }
+
+int qlcnic_82xx_shutdown(struct pci_dev *pdev)
+{
+	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev = adapter->netdev;
+	int retval;
+
+	netif_device_detach(netdev);
+
+	qlcnic_cancel_idc_work(adapter);
+
+	if (netif_running(netdev))
+		qlcnic_down(adapter, netdev);
+
+	qlcnic_clr_all_drv_state(adapter, 0);
+
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+
+	retval = pci_save_state(pdev);
+	if (retval)
+		return retval;
+
+	if (qlcnic_wol_supported(adapter)) {
+		pci_enable_wake(pdev, PCI_D3cold, 1);
+		pci_enable_wake(pdev, PCI_D3hot, 1);
+	}
+
+	return 0;
+}
+
+int qlcnic_82xx_resume(struct qlcnic_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	int err;
+
+	err = qlcnic_start_firmware(adapter);
+	if (err) {
+		dev_err(&adapter->pdev->dev, "failed to start firmware\n");
+		return err;
+	}
+
+	if (netif_running(netdev)) {
+		err = qlcnic_up(adapter, netdev);
+		if (!err)
+			qlcnic_restore_indev_addr(netdev, NETDEV_UP);
+	}
+
+	netif_device_attach(netdev);
+	qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
+	return err;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -86,7 +86,8 @@ enum qlcnic_regs {
 #define QLCNIC_CMD_BC_EVENT_SETUP		0x31
 #define	QLCNIC_CMD_CONFIG_VPORT			0x32
 #define QLCNIC_CMD_GET_MAC_STATS		0x37
-#define QLCNIC_CMD_SET_DRV_VER			0x38
+#define QLCNIC_CMD_82XX_SET_DRV_VER		0x38
+#define QLCNIC_CMD_GET_LED_STATUS		0x3C
 #define QLCNIC_CMD_CONFIGURE_RSS		0x41
 #define QLCNIC_CMD_CONFIG_INTR_COAL		0x43
 #define QLCNIC_CMD_CONFIGURE_LED		0x44
@@ -102,6 +103,7 @@ enum qlcnic_regs {
 #define QLCNIC_CMD_GET_LINK_STATUS		0x68
 #define QLCNIC_CMD_SET_LED_CONFIG		0x69
 #define QLCNIC_CMD_GET_LED_CONFIG		0x6A
+#define QLCNIC_CMD_83XX_SET_DRV_VER		0x6F
 #define QLCNIC_CMD_ADD_RCV_RINGS		0x0B
 
 #define QLCNIC_INTRPT_INTX			1
@@ -152,7 +154,7 @@ struct qlcnic_hardware_context;
 struct qlcnic_adapter;
 
 int qlcnic_82xx_start_firmware(struct qlcnic_adapter *);
-int qlcnic_82xx_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong);
+int qlcnic_82xx_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong, int *);
 int qlcnic_82xx_hw_write_wx_2M(struct qlcnic_adapter *, ulong, u32);
 int qlcnic_82xx_config_hw_lro(struct qlcnic_adapter *adapter, int);
 int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32);
@@ -197,4 +199,8 @@ void qlcnic_82xx_api_unlock(struct qlcni
 void qlcnic_82xx_napi_enable(struct qlcnic_adapter *);
 void qlcnic_82xx_napi_disable(struct qlcnic_adapter *);
 void qlcnic_82xx_napi_del(struct qlcnic_adapter *);
+int qlcnic_82xx_shutdown(struct pci_dev *);
+int qlcnic_82xx_resume(struct qlcnic_adapter *);
+void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed);
+void qlcnic_fw_poll_work(struct work_struct *work);
 #endif				/* __QLCNIC_HW_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c	2013-07-01 10:36:58.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c	2013-08-31 17:56:31.000000000 -0400
@@ -142,7 +142,7 @@ void qlcnic_release_tx_buffers(struct ql
 					 buffrag->length, PCI_DMA_TODEVICE);
 			buffrag->dma = 0ULL;
 		}
-		for (j = 0; j < cmd_buf->frag_count; j++) {
+		for (j = 1; j < cmd_buf->frag_count; j++) {
 			buffrag++;
 			if (buffrag->dma) {
 				pci_unmap_page(adapter->pdev, buffrag->dma,
@@ -286,10 +286,11 @@ static int qlcnic_wait_rom_done(struct q
 {
 	long timeout = 0;
 	long done = 0;
+	int err = 0;
 
 	cond_resched();
 	while (done == 0) {
-		done = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_STATUS);
+		done = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_STATUS, &err);
 		done &= 2;
 		if (++timeout >= QLCNIC_MAX_ROM_WAIT_USEC) {
 			dev_err(&adapter->pdev->dev,
@@ -304,6 +305,8 @@ static int qlcnic_wait_rom_done(struct q
 static int do_rom_fast_read(struct qlcnic_adapter *adapter,
 			    u32 addr, u32 *valp)
 {
+	int err = 0;
+
 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ADDRESS, addr);
 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ABYTE_CNT, 3);
@@ -317,7 +320,9 @@ static int do_rom_fast_read(struct qlcni
 	udelay(10);
 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
 
-	*valp = QLCRD32(adapter, QLCNIC_ROMUSB_ROM_RDATA);
+	*valp = QLCRD32(adapter, QLCNIC_ROMUSB_ROM_RDATA, &err);
+	if (err == -EIO)
+		return err;
 	return 0;
 }
 
@@ -369,11 +374,11 @@ int qlcnic_rom_fast_read(struct qlcnic_a
 
 int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter)
 {
-	int addr, val;
+	int addr, err = 0;
 	int i, n, init_delay;
 	struct crb_addr_pair *buf;
 	unsigned offset;
-	u32 off;
+	u32 off, val;
 	struct pci_dev *pdev = adapter->pdev;
 
 	QLC_SHARED_REG_WR32(adapter, QLCNIC_CMDPEG_STATE, 0);
@@ -402,7 +407,9 @@ int qlcnic_pinit_from_rom(struct qlcnic_
 	QLCWR32(adapter, QLCNIC_CRB_NIU + 0xb0000, 0x00);
 
 	/* halt sre */
-	val = QLCRD32(adapter, QLCNIC_CRB_SRE + 0x1000);
+	val = QLCRD32(adapter, QLCNIC_CRB_SRE + 0x1000, &err);
+	if (err == -EIO)
+		return err;
 	QLCWR32(adapter, QLCNIC_CRB_SRE + 0x1000, val & (~(0x1)));
 
 	/* halt epg */
@@ -719,10 +726,12 @@ qlcnic_check_flash_fw_ver(struct qlcnic_
 static int
 qlcnic_has_mn(struct qlcnic_adapter *adapter)
 {
-	u32 capability;
-	capability = 0;
+	u32 capability = 0;
+	int err = 0;
 
-	capability = QLCRD32(adapter, QLCNIC_PEG_TUNE_CAPABILITY);
+	capability = QLCRD32(adapter, QLCNIC_PEG_TUNE_CAPABILITY, &err);
+	if (err == -EIO)
+		return err;
 	if (capability & QLCNIC_PEG_TUNE_MN_PRESENT)
 		return 1;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c	2013-08-25 20:43:22.000000000 -0400
@@ -161,36 +161,68 @@ static inline int qlcnic_82xx_is_lb_pkt(
 	return (qlcnic_get_sts_status(sts_data) == STATUS_CKSUM_LOOP) ? 1 : 0;
 }
 
+static void qlcnic_delete_rx_list_mac(struct qlcnic_adapter *adapter,
+				      struct qlcnic_filter *fil,
+				      void *addr, u16 vlan_id)
+{
+	int ret;
+	u8 op;
+
+	op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD;
+	ret = qlcnic_sre_macaddr_change(adapter, addr, vlan_id, op);
+	if (ret)
+		return;
+
+	op = vlan_id ? QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL;
+	ret = qlcnic_sre_macaddr_change(adapter, addr, vlan_id, op);
+	if (!ret) {
+		hlist_del(&fil->fnode);
+		adapter->rx_fhash.fnum--;
+	}
+}
+
+static struct qlcnic_filter *qlcnic_find_mac_filter(struct hlist_head *head,
+						    void *addr, u16 vlan_id)
+{
+	struct qlcnic_filter *tmp_fil = NULL;
+	struct hlist_node *n;
+
+	hlist_for_each_entry_safe(tmp_fil, n, head, fnode) {
+		if (!memcmp(tmp_fil->faddr, addr, ETH_ALEN) &&
+		    tmp_fil->vlan_id == vlan_id)
+			return tmp_fil;
+	}
+
+	return NULL;
+}
+
 void qlcnic_add_lb_filter(struct qlcnic_adapter *adapter, struct sk_buff *skb,
 			  int loopback_pkt, u16 vlan_id)
 {
 	struct ethhdr *phdr = (struct ethhdr *)(skb->data);
 	struct qlcnic_filter *fil, *tmp_fil;
-	struct hlist_node *n;
 	struct hlist_head *head;
 	unsigned long time;
 	u64 src_addr = 0;
-	u8 hindex, found = 0, op;
+	u8 hindex, op;
 	int ret;
 
 	memcpy(&src_addr, phdr->h_source, ETH_ALEN);
+	hindex = qlcnic_mac_hash(src_addr) &
+		 (adapter->fhash.fbucket_size - 1);
 
 	if (loopback_pkt) {
 		if (adapter->rx_fhash.fnum >= adapter->rx_fhash.fmax)
 			return;
 
-		hindex = qlcnic_mac_hash(src_addr) &
-			 (adapter->fhash.fbucket_size - 1);
 		head = &(adapter->rx_fhash.fhead[hindex]);
 
-		hlist_for_each_entry_safe(tmp_fil, n, head, fnode) {
-			if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) &&
-			    tmp_fil->vlan_id == vlan_id) {
-				time = tmp_fil->ftime;
-				if (jiffies > (QLCNIC_READD_AGE * HZ + time))
-					tmp_fil->ftime = jiffies;
-				return;
-			}
+		tmp_fil = qlcnic_find_mac_filter(head, &src_addr, vlan_id);
+		if (tmp_fil) {
+			time = tmp_fil->ftime;
+			if (time_after(jiffies, QLCNIC_READD_AGE * HZ + time))
+				tmp_fil->ftime = jiffies;
+			return;
 		}
 
 		fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC);
@@ -205,36 +237,37 @@ void qlcnic_add_lb_filter(struct qlcnic_
 		adapter->rx_fhash.fnum++;
 		spin_unlock(&adapter->rx_mac_learn_lock);
 	} else {
-		hindex = qlcnic_mac_hash(src_addr) &
-			 (adapter->fhash.fbucket_size - 1);
-		head = &(adapter->rx_fhash.fhead[hindex]);
-		spin_lock(&adapter->rx_mac_learn_lock);
-		hlist_for_each_entry_safe(tmp_fil, n, head, fnode) {
-			if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) &&
-			    tmp_fil->vlan_id == vlan_id) {
-				found = 1;
-				break;
-			}
-		}
+		head = &adapter->fhash.fhead[hindex];
 
-		if (!found) {
-			spin_unlock(&adapter->rx_mac_learn_lock);
-			return;
-		}
+		spin_lock(&adapter->mac_learn_lock);
 
-		op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD;
-		ret = qlcnic_sre_macaddr_change(adapter, (u8 *)&src_addr,
-						vlan_id, op);
-		if (!ret) {
+		tmp_fil = qlcnic_find_mac_filter(head, &src_addr, vlan_id);
+		if (tmp_fil) {
 			op = vlan_id ? QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL;
 			ret = qlcnic_sre_macaddr_change(adapter,
 							(u8 *)&src_addr,
 							vlan_id, op);
 			if (!ret) {
-				hlist_del(&(tmp_fil->fnode));
-				adapter->rx_fhash.fnum--;
+				hlist_del(&tmp_fil->fnode);
+				adapter->fhash.fnum--;
 			}
+
+			spin_unlock(&adapter->mac_learn_lock);
+
+			return;
 		}
+
+		spin_unlock(&adapter->mac_learn_lock);
+
+		head = &adapter->rx_fhash.fhead[hindex];
+
+		spin_lock(&adapter->rx_mac_learn_lock);
+
+		tmp_fil = qlcnic_find_mac_filter(head, &src_addr, vlan_id);
+		if (tmp_fil)
+			qlcnic_delete_rx_list_mac(adapter, tmp_fil, &src_addr,
+						  vlan_id);
+
 		spin_unlock(&adapter->rx_mac_learn_lock);
 	}
 }
@@ -262,7 +295,7 @@ void qlcnic_82xx_change_filter(struct ql
 
 	mac_req = (struct qlcnic_mac_req *)&(req->words[0]);
 	mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD;
-	memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN);
+	memcpy(mac_req->mac_addr, uaddr, ETH_ALEN);
 
 	vlan_req = (struct qlcnic_vlan_req *)&req->words[1];
 	vlan_req->vlan_id = cpu_to_le16(vlan_id);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c	2013-07-01 10:37:06.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c	2013-08-31 17:56:39.000000000 -0400
@@ -52,10 +52,6 @@ int qlcnic_load_fw_file;
 MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file)");
 module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444);
 
-int qlcnic_config_npars;
-module_param(qlcnic_config_npars, int, 0444);
-MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled)");
-
 static int qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void qlcnic_remove(struct pci_dev *pdev);
 static int qlcnic_open(struct net_device *netdev);
@@ -63,13 +59,11 @@ static int qlcnic_close(struct net_devic
 static void qlcnic_tx_timeout(struct net_device *netdev);
 static void qlcnic_attach_work(struct work_struct *work);
 static void qlcnic_fwinit_work(struct work_struct *work);
-static void qlcnic_fw_poll_work(struct work_struct *work);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void qlcnic_poll_controller(struct net_device *netdev);
 #endif
 
 static void qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding);
-static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8);
 static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter);
 
 static irqreturn_t qlcnic_tmp_intr(int irq, void *data);
@@ -364,12 +358,15 @@ static int qlcnic_fdb_del(struct ndmsg *
 		return ndo_dflt_fdb_del(ndm, tb, netdev, addr);
 
 	if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
-		if (is_unicast_ether_addr(addr))
-			err = qlcnic_nic_del_mac(adapter, addr);
-		else if (is_multicast_ether_addr(addr))
+		if (is_unicast_ether_addr(addr)) {
+			err = dev_uc_del(netdev, addr);
+			if (!err)
+				err = qlcnic_nic_del_mac(adapter, addr);
+		} else if (is_multicast_ether_addr(addr)) {
 			err = dev_mc_del(netdev, addr);
-		else
+		} else {
 			err =  -EINVAL;
+		}
 	}
 	return err;
 }
@@ -392,12 +389,16 @@ static int qlcnic_fdb_add(struct ndmsg *
 	if (ether_addr_equal(addr, adapter->mac_addr))
 		return err;
 
-	if (is_unicast_ether_addr(addr))
-		err = qlcnic_nic_add_mac(adapter, addr, 0);
-	else if (is_multicast_ether_addr(addr))
+	if (is_unicast_ether_addr(addr)) {
+		if (netdev_uc_count(netdev) < adapter->ahw->max_uc_count)
+			err = dev_uc_add_excl(netdev, addr);
+		else
+			err = -ENOMEM;
+	} else if (is_multicast_ether_addr(addr)) {
 		err = dev_mc_add_excl(netdev, addr);
-	else
+	} else {
 		err = -EINVAL;
+	}
 
 	return err;
 }
@@ -449,6 +450,7 @@ static const struct net_device_ops qlcni
 	.ndo_set_vf_tx_rate	= qlcnic_sriov_set_vf_tx_rate,
 	.ndo_get_vf_config	= qlcnic_sriov_get_vf_config,
 	.ndo_set_vf_vlan	= qlcnic_sriov_set_vf_vlan,
+	.ndo_set_vf_spoofchk	= qlcnic_sriov_set_vf_spoofchk,
 #endif
 };
 
@@ -465,6 +467,8 @@ static struct qlcnic_nic_template qlcnic
 	.napi_add		= qlcnic_82xx_napi_add,
 	.napi_del		= qlcnic_82xx_napi_del,
 	.config_ipaddr		= qlcnic_82xx_config_ipaddr,
+	.shutdown		= qlcnic_82xx_shutdown,
+	.resume			= qlcnic_82xx_resume,
 	.clear_legacy_intr	= qlcnic_82xx_clear_legacy_intr,
 };
 
@@ -508,6 +512,7 @@ static struct qlcnic_hardware_ops qlcnic
 	.config_promisc_mode		= qlcnic_82xx_nic_set_promisc,
 	.change_l2_filter		= qlcnic_82xx_change_filter,
 	.get_board_info			= qlcnic_82xx_get_board_info,
+	.set_mac_filter_count		= qlcnic_82xx_set_mac_filter_count,
 	.free_mac_list			= qlcnic_82xx_free_mac_list,
 };
 
@@ -768,7 +773,7 @@ static int
 qlcnic_set_function_modes(struct qlcnic_adapter *adapter)
 {
 	u8 id;
-	int i, ret = 1;
+	int ret;
 	u32 data = QLCNIC_MGMT_FUNC;
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
 
@@ -776,20 +781,10 @@ qlcnic_set_function_modes(struct qlcnic_
 	if (ret)
 		goto err_lock;
 
-	if (qlcnic_config_npars) {
-		for (i = 0; i < ahw->act_pci_func; i++) {
-			id = adapter->npars[i].pci_func;
-			if (id == ahw->pci_func)
-				continue;
-			data |= (qlcnic_config_npars &
-					QLC_DEV_SET_DRV(0xf, id));
-		}
-	} else {
-		data = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE);
-		data = (data & ~QLC_DEV_SET_DRV(0xf, ahw->pci_func)) |
-			(QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC,
-					 ahw->pci_func));
-	}
+	id = ahw->pci_func;
+	data = QLC_SHARED_REG_RD32(adapter, QLCNIC_DRV_OP_MODE);
+	data = (data & ~QLC_DEV_SET_DRV(0xf, id)) |
+	       QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, id);
 	QLC_SHARED_REG_WR32(adapter, QLCNIC_DRV_OP_MODE, data);
 	qlcnic_api_unlock(adapter);
 err_lock:
@@ -875,6 +870,27 @@ static int qlcnic_setup_pci_map(struct p
 	return 0;
 }
 
+static inline bool qlcnic_validate_subsystem_id(struct qlcnic_adapter *adapter,
+						int index)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	unsigned short subsystem_vendor;
+	bool ret = true;
+
+	subsystem_vendor = pdev->subsystem_vendor;
+
+	if (pdev->device == PCI_DEVICE_ID_QLOGIC_QLE824X ||
+	    pdev->device == PCI_DEVICE_ID_QLOGIC_QLE834X) {
+		if (qlcnic_boards[index].sub_vendor == subsystem_vendor &&
+		    qlcnic_boards[index].sub_device == pdev->subsystem_device)
+			ret = true;
+		else
+			ret = false;
+	}
+
+	return ret;
+}
+
 static void qlcnic_get_board_name(struct qlcnic_adapter *adapter, char *name)
 {
 	struct pci_dev *pdev = adapter->pdev;
@@ -882,20 +898,18 @@ static void qlcnic_get_board_name(struct
 
 	for (i = 0; i < NUM_SUPPORTED_BOARDS; ++i) {
 		if (qlcnic_boards[i].vendor == pdev->vendor &&
-			qlcnic_boards[i].device == pdev->device &&
-			qlcnic_boards[i].sub_vendor == pdev->subsystem_vendor &&
-			qlcnic_boards[i].sub_device == pdev->subsystem_device) {
-				sprintf(name, "%pM: %s" ,
-					adapter->mac_addr,
-					qlcnic_boards[i].short_name);
-				found = 1;
-				break;
+		    qlcnic_boards[i].device == pdev->device &&
+		    qlcnic_validate_subsystem_id(adapter, i)) {
+			found = 1;
+			break;
 		}
-
 	}
 
 	if (!found)
 		sprintf(name, "%pM Gigabit Ethernet", adapter->mac_addr);
+	else
+		sprintf(name, "%pM: %s" , adapter->mac_addr,
+			qlcnic_boards[i].short_name);
 }
 
 static void
@@ -963,8 +977,8 @@ qlcnic_check_options(struct qlcnic_adapt
 static int
 qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
 {
-	int err;
 	struct qlcnic_info nic_info;
+	int err = 0;
 
 	memset(&nic_info, 0, sizeof(struct qlcnic_info));
 	err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func);
@@ -979,8 +993,10 @@ qlcnic_initialize_nic(struct qlcnic_adap
 
 	if (adapter->ahw->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) {
 		u32 temp;
-		temp = QLCRD32(adapter, CRB_FW_CAPABILITIES_2);
-		adapter->ahw->capabilities2 = temp;
+		temp = QLCRD32(adapter, CRB_FW_CAPABILITIES_2, &err);
+		if (err == -EIO)
+			return err;
+		adapter->ahw->extra_capability[0] = temp;
 	}
 	adapter->ahw->max_mac_filters = nic_info.max_mac_filters;
 	adapter->ahw->max_mtu = nic_info.max_mtu;
@@ -1369,6 +1385,8 @@ qlcnic_request_irq(struct qlcnic_adapter
 	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
 		if (qlcnic_82xx_check(adapter))
 			handler = qlcnic_tmp_intr;
+		else
+			handler = qlcnic_83xx_tmp_intr;
 		if (!QLCNIC_IS_MSI_FAMILY(adapter))
 			flags |= IRQF_SHARED;
 
@@ -1395,16 +1413,23 @@ qlcnic_request_irq(struct qlcnic_adapter
 			for (ring = 0; ring < num_sds_rings; ring++) {
 				sds_ring = &recv_ctx->sds_rings[ring];
 				if (qlcnic_82xx_check(adapter) &&
-				    (ring == (num_sds_rings - 1)))
-					snprintf(sds_ring->name,
-						 sizeof(sds_ring->name),
-						 "qlcnic-%s[Tx0+Rx%d]",
-						 netdev->name, ring);
-				else
+				    (ring == (num_sds_rings - 1))) {
+					if (!(adapter->flags &
+					      QLCNIC_MSIX_ENABLED))
+						snprintf(sds_ring->name,
+							 sizeof(sds_ring->name),
+							 "qlcnic");
+					else
+						snprintf(sds_ring->name,
+							 sizeof(sds_ring->name),
+							 "%s-tx-0-rx-%d",
+							 netdev->name, ring);
+				} else {
 					snprintf(sds_ring->name,
 						 sizeof(sds_ring->name),
-						 "qlcnic-%s[Rx%d]",
+						 "%s-rx-%d",
 						 netdev->name, ring);
+				}
 				err = request_irq(sds_ring->irq, handler, flags,
 						  sds_ring->name, sds_ring);
 				if (err)
@@ -1419,7 +1444,7 @@ qlcnic_request_irq(struct qlcnic_adapter
 			     ring++) {
 				tx_ring = &adapter->tx_ring[ring];
 				snprintf(tx_ring->name, sizeof(tx_ring->name),
-					 "qlcnic-%s[Tx%d]", netdev->name, ring);
+					 "%s-tx-%d", netdev->name, ring);
 				err = request_irq(tx_ring->irq, handler, flags,
 						  tx_ring->name, tx_ring);
 				if (err)
@@ -1465,7 +1490,7 @@ static void qlcnic_get_lro_mss_capabilit
 	u32 capab = 0;
 
 	if (qlcnic_82xx_check(adapter)) {
-		if (adapter->ahw->capabilities2 &
+		if (adapter->ahw->extra_capability[0] &
 		    QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG)
 			adapter->flags |= QLCNIC_FW_LRO_MSS_CAP;
 	} else {
@@ -1510,12 +1535,12 @@ int __qlcnic_up(struct qlcnic_adapter *a
 	if (netdev->features & NETIF_F_LRO)
 		qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED);
 
+	set_bit(__QLCNIC_DEV_UP, &adapter->state);
 	qlcnic_napi_enable(adapter);
 
 	qlcnic_linkevent_request(adapter, 1);
 
 	adapter->ahw->reset_context = 0;
-	set_bit(__QLCNIC_DEV_UP, &adapter->state);
 	return 0;
 }
 
@@ -1816,6 +1841,22 @@ qlcnic_reset_context(struct qlcnic_adapt
 	return err;
 }
 
+void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	u16 act_pci_fn = ahw->act_pci_func;
+	u16 count;
+
+	ahw->max_mc_count = QLCNIC_MAX_MC_COUNT;
+	if (act_pci_fn <= 2)
+		count = (QLCNIC_MAX_UC_COUNT - QLCNIC_MAX_MC_COUNT) /
+			 act_pci_fn;
+	else
+		count = (QLCNIC_LB_MAX_FILTERS - QLCNIC_MAX_MC_COUNT) /
+			 act_pci_fn;
+	ahw->max_uc_count = count;
+}
+
 int
 qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
 		    int pci_using_dac)
@@ -1825,7 +1866,7 @@ qlcnic_setup_netdev(struct qlcnic_adapte
 
 	adapter->rx_csum = 1;
 	adapter->ahw->mc_enabled = 0;
-	adapter->ahw->max_mc_count = QLCNIC_MAX_MC_COUNT;
+	qlcnic_set_mac_filter_count(adapter);
 
 	netdev->netdev_ops	   = &qlcnic_netdev_ops;
 	netdev->watchdog_timeo     = QLCNIC_WATCHDOG_TIMEOUTVALUE * HZ;
@@ -1863,6 +1904,7 @@ qlcnic_setup_netdev(struct qlcnic_adapte
 		netdev->features |= NETIF_F_LRO;
 
 	netdev->hw_features = netdev->features;
+	netdev->priv_flags |= IFF_UNICAST_FLT;
 	netdev->irq = adapter->msix_entries[0].vector;
 
 	err = register_netdev(netdev);
@@ -1947,6 +1989,21 @@ int qlcnic_alloc_tx_rings(struct qlcnic_
 	return 0;
 }
 
+void qlcnic_set_drv_version(struct qlcnic_adapter *adapter)
+{
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	u32 fw_cmd = 0;
+
+	if (qlcnic_82xx_check(adapter))
+		fw_cmd = QLCNIC_CMD_82XX_SET_DRV_VER;
+	else if (qlcnic_83xx_check(adapter))
+		fw_cmd = QLCNIC_CMD_83XX_SET_DRV_VER;
+
+	if ((ahw->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) &&
+	    (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_SET_DRV_VER))
+		qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd);
+}
+
 static int
 qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -1954,7 +2011,6 @@ qlcnic_probe(struct pci_dev *pdev, const
 	struct qlcnic_adapter *adapter = NULL;
 	struct qlcnic_hardware_context *ahw;
 	int err, pci_using_dac = -1;
-	u32 capab2;
 	char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */
 
 	if (pdev->is_virtfn)
@@ -2087,7 +2143,7 @@ qlcnic_probe(struct pci_dev *pdev, const
 	if (qlcnic_83xx_check(adapter) && !qlcnic_use_msi_x &&
 	    !!qlcnic_use_msi)
 		dev_warn(&pdev->dev,
-			 "83xx adapter do not support MSI interrupts\n");
+			 "Device does not support MSI interrupts\n");
 
 	err = qlcnic_setup_intr(adapter, 0);
 	if (err) {
@@ -2109,13 +2165,8 @@ qlcnic_probe(struct pci_dev *pdev, const
 	if (err)
 		goto err_out_disable_mbx_intr;
 
-	if (qlcnic_82xx_check(adapter)) {
-		if (ahw->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) {
-			capab2 = QLCRD32(adapter, CRB_FW_CAPABILITIES_2);
-			if (capab2 & QLCNIC_FW_CAPABILITY_2_OCBB)
-				qlcnic_fw_cmd_set_drv_version(adapter);
-		}
-	}
+	if (adapter->portnum == 0)
+		qlcnic_set_drv_version(adapter);
 
 	pci_set_drvdata(pdev, adapter);
 
@@ -2231,37 +2282,6 @@ static void qlcnic_remove(struct pci_dev
 	kfree(ahw);
 	free_netdev(netdev);
 }
-static int __qlcnic_shutdown(struct pci_dev *pdev)
-{
-	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
-	struct net_device *netdev = adapter->netdev;
-	int retval;
-
-	netif_device_detach(netdev);
-
-	qlcnic_cancel_idc_work(adapter);
-
-	if (netif_running(netdev))
-		qlcnic_down(adapter, netdev);
-
-	qlcnic_sriov_cleanup(adapter);
-	if (qlcnic_82xx_check(adapter))
-		qlcnic_clr_all_drv_state(adapter, 0);
-
-	clear_bit(__QLCNIC_RESETTING, &adapter->state);
-
-	retval = pci_save_state(pdev);
-	if (retval)
-		return retval;
-	if (qlcnic_82xx_check(adapter)) {
-		if (qlcnic_wol_supported(adapter)) {
-			pci_enable_wake(pdev, PCI_D3cold, 1);
-			pci_enable_wake(pdev, PCI_D3hot, 1);
-		}
-	}
-
-	return 0;
-}
 
 static void qlcnic_shutdown(struct pci_dev *pdev)
 {
@@ -2272,8 +2292,7 @@ static void qlcnic_shutdown(struct pci_d
 }
 
 #ifdef CONFIG_PM
-static int
-qlcnic_suspend(struct pci_dev *pdev, pm_message_t state)
+static int qlcnic_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	int retval;
 
@@ -2285,11 +2304,9 @@ qlcnic_suspend(struct pci_dev *pdev, pm_
 	return 0;
 }
 
-static int
-qlcnic_resume(struct pci_dev *pdev)
+static int qlcnic_resume(struct pci_dev *pdev)
 {
 	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
-	struct net_device *netdev = adapter->netdev;
 	int err;
 
 	err = pci_enable_device(pdev);
@@ -2300,23 +2317,7 @@ qlcnic_resume(struct pci_dev *pdev)
 	pci_set_master(pdev);
 	pci_restore_state(pdev);
 
-	err = qlcnic_start_firmware(adapter);
-	if (err) {
-		dev_err(&pdev->dev, "failed to start firmware\n");
-		return err;
-	}
-
-	if (netif_running(netdev)) {
-		err = qlcnic_up(adapter, netdev);
-		if (err)
-			goto done;
-
-		qlcnic_restore_indev_addr(netdev, NETDEV_UP);
-	}
-done:
-	netif_device_attach(netdev);
-	qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
-	return 0;
+	return  __qlcnic_resume(adapter);
 }
 #endif
 
@@ -2655,8 +2656,7 @@ qlcnic_clr_drv_state(struct qlcnic_adapt
 	return 0;
 }
 
-static void
-qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed)
+void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed)
 {
 	u32  val;
 
@@ -3086,6 +3086,8 @@ done:
 	adapter->fw_fail_cnt = 0;
 	adapter->flags &= ~QLCNIC_FW_HANG;
 	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	if (adapter->portnum == 0)
+		qlcnic_set_drv_version(adapter);
 
 	if (!qlcnic_clr_drv_state(adapter))
 		qlcnic_schedule_work(adapter, qlcnic_fw_poll_work,
@@ -3097,6 +3099,7 @@ qlcnic_check_health(struct qlcnic_adapte
 {
 	u32 state = 0, heartbeat;
 	u32 peg_status;
+	int err = 0;
 
 	if (qlcnic_check_temp(adapter))
 		goto detach;
@@ -3143,11 +3146,11 @@ qlcnic_check_health(struct qlcnic_adapte
 			"PEG_NET_4_PC: 0x%x\n",
 			peg_status,
 			QLC_SHARED_REG_RD32(adapter, QLCNIC_PEG_HALT_STATUS2),
-			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c),
-			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c),
-			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c),
-			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c),
-			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c));
+			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x3c, &err),
+			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x3c, &err),
+			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_2 + 0x3c, &err),
+			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c, &err),
+			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c, &err));
 	if (QLCNIC_FWERROR_CODE(peg_status) == 0x67)
 		dev_err(&adapter->pdev->dev,
 			"Firmware aborted with error code 0x00006700. "
@@ -3166,8 +3169,7 @@ detach:
 	return 1;
 }
 
-static void
-qlcnic_fw_poll_work(struct work_struct *work)
+void qlcnic_fw_poll_work(struct work_struct *work)
 {
 	struct qlcnic_adapter *adapter = container_of(work,
 				struct qlcnic_adapter, fw_work.work);
@@ -3219,7 +3221,6 @@ static int qlcnic_attach_func(struct pci
 	if (err)
 		return err;
 
-	pci_set_power_state(pdev, PCI_D0);
 	pci_set_master(pdev);
 	pci_restore_state(pdev);
 
@@ -3517,7 +3518,7 @@ static int qlcnic_netdev_event(struct no
 				 unsigned long event, void *ptr)
 {
 	struct qlcnic_adapter *adapter;
-	struct net_device *dev = (struct net_device *)ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 
 recheck:
 	if (dev == NULL)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@
 #define QLC_83XX_MINIDUMP_FLASH		0x520000
 #define QLC_83XX_OCM_INDEX			3
 #define QLC_83XX_PCI_INDEX			0
+#define QLC_83XX_DMA_ENGINE_INDEX		8
 
 static const u32 qlcnic_ms_read_data[] = {
 	0x410000A8, 0x410000AC, 0x410000B8, 0x410000BC
@@ -32,6 +33,16 @@ static const u32 qlcnic_ms_read_data[] =
 
 #define QLCNIC_DUMP_MASK_MAX	0xff
 
+struct qlcnic_pex_dma_descriptor {
+	u32	read_data_size;
+	u32	dma_desc_cmd;
+	u32	src_addr_low;
+	u32	src_addr_high;
+	u32	dma_bus_addr_low;
+	u32	dma_bus_addr_high;
+	u32	rsvd[6];
+} __packed;
+
 struct qlcnic_common_entry_hdr {
 	u32     type;
 	u32     offset;
@@ -90,7 +101,10 @@ struct __ocm {
 } __packed;
 
 struct __mem {
-	u8	rsvd[24];
+	u32	desc_card_addr;
+	u32	dma_desc_cmd;
+	u32	start_dma_cmd;
+	u32	rsvd[3];
 	u32	addr;
 	u32	size;
 } __packed;
@@ -466,12 +480,12 @@ skip_poll:
 	return l2->no_ops * l2->read_addr_num * sizeof(u32);
 }
 
-static u32 qlcnic_read_memory(struct qlcnic_adapter *adapter,
-			      struct qlcnic_dump_entry *entry, __le32 *buffer)
+static u32 qlcnic_read_memory_test_agent(struct qlcnic_adapter *adapter,
+					 struct __mem *mem, __le32 *buffer,
+					 int *ret)
 {
-	u32 addr, data, test, ret = 0;
+	u32 addr, data, test;
 	int i, reg_read;
-	struct __mem *mem = &entry->region.mem;
 
 	reg_read = mem->size;
 	addr = mem->addr;
@@ -480,7 +494,8 @@ static u32 qlcnic_read_memory(struct qlc
 		dev_info(&adapter->pdev->dev,
 			 "Unaligned memory addr:0x%x size:0x%x\n",
 			 addr, reg_read);
-		return -EINVAL;
+		*ret = -EINVAL;
+		return 0;
 	}
 
 	mutex_lock(&adapter->ahw->mem_lock);
@@ -499,7 +514,7 @@ static u32 qlcnic_read_memory(struct qlc
 			if (printk_ratelimit()) {
 				dev_err(&adapter->pdev->dev,
 					"failed to read through agent\n");
-				ret = -EINVAL;
+				*ret = -EIO;
 				goto out;
 			}
 		}
@@ -516,6 +531,181 @@ out:
 	return mem->size;
 }
 
+/* DMA register base address */
+#define QLC_DMA_REG_BASE_ADDR(dma_no)	(0x77320000 + (dma_no * 0x10000))
+
+/* DMA register offsets w.r.t base address */
+#define QLC_DMA_CMD_BUFF_ADDR_LOW	0
+#define QLC_DMA_CMD_BUFF_ADDR_HI	4
+#define QLC_DMA_CMD_STATUS_CTRL		8
+
+#define QLC_PEX_DMA_READ_SIZE		(PAGE_SIZE * 16)
+
+static int qlcnic_start_pex_dma(struct qlcnic_adapter *adapter,
+				struct __mem *mem)
+{
+	struct qlcnic_dump_template_hdr *tmpl_hdr;
+	struct device *dev = &adapter->pdev->dev;
+	u32 dma_no, dma_base_addr, temp_addr;
+	int i, ret, dma_sts;
+
+	tmpl_hdr = adapter->ahw->fw_dump.tmpl_hdr;
+	dma_no = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX];
+	dma_base_addr = QLC_DMA_REG_BASE_ADDR(dma_no);
+
+	temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_LOW;
+	ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr,
+					   mem->desc_card_addr);
+	if (ret)
+		return ret;
+
+	temp_addr = dma_base_addr + QLC_DMA_CMD_BUFF_ADDR_HI;
+	ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr, 0);
+	if (ret)
+		return ret;
+
+	temp_addr = dma_base_addr + QLC_DMA_CMD_STATUS_CTRL;
+	ret = qlcnic_83xx_wrt_reg_indirect(adapter, temp_addr,
+					   mem->start_dma_cmd);
+	if (ret)
+		return ret;
+
+	/* Wait for DMA to complete */
+	temp_addr = dma_base_addr + QLC_DMA_CMD_STATUS_CTRL;
+	for (i = 0; i < 400; i++) {
+		dma_sts = qlcnic_ind_rd(adapter, temp_addr);
+
+		if (dma_sts & BIT_1)
+			usleep_range(250, 500);
+		else
+			break;
+	}
+
+	if (i >= 400) {
+		dev_info(dev, "PEX DMA operation timed out");
+		ret = -EIO;
+	}
+
+	return ret;
+}
+
+static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter,
+				     struct __mem *mem,
+				     __le32 *buffer, int *ret)
+{
+	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
+	u32 temp, dma_base_addr, size = 0, read_size = 0;
+	struct qlcnic_pex_dma_descriptor *dma_descr;
+	struct qlcnic_dump_template_hdr *tmpl_hdr;
+	struct device *dev = &adapter->pdev->dev;
+	dma_addr_t dma_phys_addr;
+	void *dma_buffer;
+
+	tmpl_hdr = fw_dump->tmpl_hdr;
+
+	/* Check if DMA engine is available */
+	temp = tmpl_hdr->saved_state[QLC_83XX_DMA_ENGINE_INDEX];
+	dma_base_addr = QLC_DMA_REG_BASE_ADDR(temp);
+	temp = qlcnic_ind_rd(adapter,
+			     dma_base_addr + QLC_DMA_CMD_STATUS_CTRL);
+
+	if (!(temp & BIT_31)) {
+		dev_info(dev, "%s: DMA engine is not available\n", __func__);
+		*ret = -EIO;
+		return 0;
+	}
+
+	/* Create DMA descriptor */
+	dma_descr = kzalloc(sizeof(struct qlcnic_pex_dma_descriptor),
+			    GFP_KERNEL);
+	if (!dma_descr) {
+		*ret = -ENOMEM;
+		return 0;
+	}
+
+	/* dma_desc_cmd  0:15  = 0
+	 * dma_desc_cmd 16:19  = mem->dma_desc_cmd 0:3
+	 * dma_desc_cmd 20:23  = pci function number
+	 * dma_desc_cmd 24:31  = mem->dma_desc_cmd 8:15
+	 */
+	dma_phys_addr = fw_dump->phys_addr;
+	dma_buffer = fw_dump->dma_buffer;
+	temp = 0;
+	temp = mem->dma_desc_cmd & 0xff0f;
+	temp |= (adapter->ahw->pci_func & 0xf) << 4;
+	dma_descr->dma_desc_cmd = (temp << 16) & 0xffff0000;
+	dma_descr->dma_bus_addr_low = LSD(dma_phys_addr);
+	dma_descr->dma_bus_addr_high = MSD(dma_phys_addr);
+	dma_descr->src_addr_high = 0;
+
+	/* Collect memory dump using multiple DMA operations if required */
+	while (read_size < mem->size) {
+		if (mem->size - read_size >= QLC_PEX_DMA_READ_SIZE)
+			size = QLC_PEX_DMA_READ_SIZE;
+		else
+			size = mem->size - read_size;
+
+		dma_descr->src_addr_low = mem->addr + read_size;
+		dma_descr->read_data_size = size;
+
+		/* Write DMA descriptor to MS memory*/
+		temp = sizeof(struct qlcnic_pex_dma_descriptor) / 16;
+		*ret = qlcnic_83xx_ms_mem_write128(adapter, mem->desc_card_addr,
+						   (u32 *)dma_descr, temp);
+		if (*ret) {
+			dev_info(dev, "Failed to write DMA descriptor to MS memory at address 0x%x\n",
+				 mem->desc_card_addr);
+			goto free_dma_descr;
+		}
+
+		*ret = qlcnic_start_pex_dma(adapter, mem);
+		if (*ret) {
+			dev_info(dev, "Failed to start PEX DMA operation\n");
+			goto free_dma_descr;
+		}
+
+		memcpy(buffer, dma_buffer, size);
+		buffer += size / 4;
+		read_size += size;
+	}
+
+free_dma_descr:
+	kfree(dma_descr);
+
+	return read_size;
+}
+
+static u32 qlcnic_read_memory(struct qlcnic_adapter *adapter,
+			      struct qlcnic_dump_entry *entry, __le32 *buffer)
+{
+	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
+	struct device *dev = &adapter->pdev->dev;
+	struct __mem *mem = &entry->region.mem;
+	u32 data_size;
+	int ret = 0;
+
+	if (fw_dump->use_pex_dma) {
+		data_size = qlcnic_read_memory_pexdma(adapter, mem, buffer,
+						      &ret);
+		if (ret)
+			dev_info(dev,
+				 "Failed to read memory dump using PEX DMA: mask[0x%x]\n",
+				 entry->hdr.mask);
+		else
+			return data_size;
+	}
+
+	data_size = qlcnic_read_memory_test_agent(adapter, mem, buffer, &ret);
+	if (ret) {
+		dev_info(dev,
+			 "Failed to read memory dump using test agent method: mask[0x%x]\n",
+			 entry->hdr.mask);
+		return 0;
+	} else {
+		return data_size;
+	}
+}
+
 static u32 qlcnic_dump_nop(struct qlcnic_adapter *adapter,
 			   struct qlcnic_dump_entry *entry, __le32 *buffer)
 {
@@ -893,6 +1083,12 @@ flash_temp:
 
 	tmpl_hdr = ahw->fw_dump.tmpl_hdr;
 	tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF;
+
+	if ((tmpl_hdr->version & 0xfffff) >= 0x20001)
+		ahw->fw_dump.use_pex_dma = true;
+	else
+		ahw->fw_dump.use_pex_dma = false;
+
 	ahw->fw_dump.enable = 1;
 
 	return 0;
@@ -910,7 +1106,9 @@ int qlcnic_dump_fw(struct qlcnic_adapter
 	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
 	struct qlcnic_dump_template_hdr *tmpl_hdr = fw_dump->tmpl_hdr;
 	static const struct qlcnic_dump_operations *fw_dump_ops;
+	struct device *dev = &adapter->pdev->dev;
 	struct qlcnic_hardware_context *ahw;
+	void *temp_buffer;
 
 	ahw = adapter->ahw;
 
@@ -944,6 +1142,16 @@ int qlcnic_dump_fw(struct qlcnic_adapter
 	tmpl_hdr->sys_info[0] = QLCNIC_DRIVER_VERSION;
 	tmpl_hdr->sys_info[1] = adapter->fw_version;
 
+	if (fw_dump->use_pex_dma) {
+		temp_buffer = dma_alloc_coherent(dev, QLC_PEX_DMA_READ_SIZE,
+						 &fw_dump->phys_addr,
+						 GFP_KERNEL);
+		if (!temp_buffer)
+			fw_dump->use_pex_dma = false;
+		else
+			fw_dump->dma_buffer = temp_buffer;
+	}
+
 	if (qlcnic_82xx_check(adapter)) {
 		ops_cnt = ARRAY_SIZE(qlcnic_fw_dump_ops);
 		fw_dump_ops = qlcnic_fw_dump_ops;
@@ -1002,6 +1210,9 @@ int qlcnic_dump_fw(struct qlcnic_adapter
 		return 0;
 	}
 error:
+	if (fw_dump->use_pex_dma)
+		dma_free_coherent(dev, QLC_PEX_DMA_READ_SIZE,
+				  fw_dump->dma_buffer, fw_dump->phys_addr);
 	vfree(fw_dump->data);
 	return -EINVAL;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,7 @@ static void qlcnic_sriov_vf_cancel_fw_wo
 static void qlcnic_sriov_cleanup_transaction(struct qlcnic_bc_trans *);
 static int qlcnic_sriov_vf_mbx_op(struct qlcnic_adapter *,
 				  struct qlcnic_cmd_args *);
+static void qlcnic_sriov_process_bc_cmd(struct work_struct *);
 
 static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = {
 	.read_crb			= qlcnic_83xx_read_crb,
@@ -75,6 +76,8 @@ static struct qlcnic_nic_template qlcnic
 	.cancel_idc_work        = qlcnic_sriov_vf_cancel_fw_work,
 	.napi_add		= qlcnic_83xx_napi_add,
 	.napi_del		= qlcnic_83xx_napi_del,
+	.shutdown		= qlcnic_sriov_vf_shutdown,
+	.resume			= qlcnic_sriov_vf_resume,
 	.config_ipaddr		= qlcnic_83xx_config_ipaddr,
 	.clear_legacy_intr	= qlcnic_83xx_clear_legacy_intr,
 };
@@ -179,6 +182,8 @@ int qlcnic_sriov_init(struct qlcnic_adap
 		spin_lock_init(&vf->rcv_pend.lock);
 		init_completion(&vf->ch_free_cmpl);
 
+		INIT_WORK(&vf->trans_work, qlcnic_sriov_process_bc_cmd);
+
 		if (qlcnic_sriov_pf_check(adapter)) {
 			vp = kzalloc(sizeof(struct qlcnic_vport), GFP_KERNEL);
 			if (!vp) {
@@ -187,6 +192,7 @@ int qlcnic_sriov_init(struct qlcnic_adap
 			}
 			sriov->vf_info[i].vp = vp;
 			vp->max_tx_bw = MAX_BW;
+			vp->spoofchk = true;
 			random_ether_addr(vp->mac);
 			dev_info(&adapter->pdev->dev,
 				 "MAC Address %pM is configured for VF %d\n",
@@ -556,7 +562,7 @@ static int qlcnic_sriov_setup_vf(struct
 	INIT_LIST_HEAD(&adapter->vf_mc_list);
 	if (!qlcnic_use_msi_x && !!qlcnic_use_msi)
 		dev_warn(&adapter->pdev->dev,
-			 "83xx adapter do not support MSI interrupts\n");
+			 "Device does not support MSI interrupts\n");
 
 	err = qlcnic_setup_intr(adapter, 1);
 	if (err) {
@@ -652,6 +658,8 @@ int qlcnic_sriov_vf_init(struct qlcnic_a
 	if (qlcnic_read_mac_addr(adapter))
 		dev_warn(&adapter->pdev->dev, "failed to read mac addr\n");
 
+	INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work);
+
 	clear_bit(__QLCNIC_RESETTING, &adapter->state);
 	return 0;
 }
@@ -754,6 +762,7 @@ static int qlcnic_sriov_alloc_bc_mbx_arg
 			memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num);
 			mbx->req.arg[0] = (type | (mbx->req.num << 16) |
 					   (3 << 29));
+			mbx->rsp.arg[0] = (type & 0xffff) | mbx->rsp.num << 16;
 			return 0;
 		}
 	}
@@ -805,6 +814,7 @@ static int qlcnic_sriov_prepare_bc_hdr(s
 		cmd->req.num = trans->req_pay_size / 4;
 		cmd->rsp.num = trans->rsp_pay_size / 4;
 		hdr = trans->rsp_hdr;
+		cmd->op_type = trans->req_hdr->op_type;
 	}
 
 	trans->trans_id = seq;
@@ -864,7 +874,6 @@ static void qlcnic_sriov_schedule_bc_cmd
 	    vf->adapter->need_fw_reset)
 		return;
 
-	INIT_WORK(&vf->trans_work, func);
 	queue_work(sriov->bc.bc_trans_wq, &vf->trans_work);
 }
 
@@ -1675,7 +1684,7 @@ static int qlcnic_sriov_vf_handle_dev_re
 			qlcnic_sriov_vf_attach(adapter);
 			adapter->fw_fail_cnt = 0;
 			dev_info(dev,
-				 "%s: Reinitalization of VF 0x%x done after FW reset\n",
+				 "%s: Reinitialization of VF 0x%x done after FW reset\n",
 				 __func__, func);
 		} else {
 			dev_err(dev,
@@ -1949,3 +1958,54 @@ static void qlcnic_sriov_vf_free_mac_lis
 		kfree(cur);
 	}
 }
+
+int qlcnic_sriov_vf_shutdown(struct pci_dev *pdev)
+{
+	struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
+	struct net_device *netdev = adapter->netdev;
+	int retval;
+
+	netif_device_detach(netdev);
+	qlcnic_cancel_idc_work(adapter);
+
+	if (netif_running(netdev))
+		qlcnic_down(adapter, netdev);
+
+	qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_TERM);
+	qlcnic_sriov_cfg_bc_intr(adapter, 0);
+	qlcnic_83xx_disable_mbx_intr(adapter);
+	cancel_delayed_work_sync(&adapter->idc_aen_work);
+
+	retval = pci_save_state(pdev);
+	if (retval)
+		return retval;
+
+	return 0;
+}
+
+int qlcnic_sriov_vf_resume(struct qlcnic_adapter *adapter)
+{
+	struct qlc_83xx_idc *idc = &adapter->ahw->idc;
+	struct net_device *netdev = adapter->netdev;
+	int err;
+
+	set_bit(QLC_83XX_MODULE_LOADED, &idc->status);
+	qlcnic_83xx_enable_mbx_intrpt(adapter);
+	err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
+	if (err)
+		return err;
+
+	err = qlcnic_sriov_channel_cfg_cmd(adapter, QLCNIC_BC_CMD_CHANNEL_INIT);
+	if (!err) {
+		if (netif_running(netdev)) {
+			err = qlcnic_up(adapter, netdev);
+			if (!err)
+				qlcnic_restore_indev_addr(netdev, NETDEV_UP);
+		}
+	}
+
+	netif_device_attach(netdev);
+	qlcnic_schedule_work(adapter, qlcnic_sriov_vf_poll_dev_state,
+			     idc->delay);
+	return err;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h	2013-08-25 20:43:22.000000000 -0400
@@ -129,6 +129,7 @@ struct qlcnic_vport {
 	u8			vlan_mode;
 	u16			vlan;
 	u8			qos;
+	bool			spoofchk;
 	u8			mac[6];
 };
 
@@ -194,6 +195,8 @@ int __qlcnic_sriov_add_act_list(struct q
 int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *,
 				   struct qlcnic_info *, u16);
 int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8);
+int qlcnic_sriov_vf_shutdown(struct pci_dev *);
+int qlcnic_sriov_vf_resume(struct qlcnic_adapter *);
 
 static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
 {
@@ -225,6 +228,7 @@ int qlcnic_sriov_set_vf_tx_rate(struct n
 int qlcnic_sriov_get_vf_config(struct net_device *, int ,
 			       struct ifla_vf_info *);
 int qlcnic_sriov_set_vf_vlan(struct net_device *, int, u16, u8);
+int qlcnic_sriov_set_vf_spoofchk(struct net_device *, int, bool);
 #else
 static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
 static inline void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter) {}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c	2013-08-25 20:43:22.000000000 -0400
@@ -580,6 +580,7 @@ static int qlcnic_sriov_set_vf_acl(struc
 	struct qlcnic_cmd_args cmd;
 	struct qlcnic_vport *vp;
 	int err, id;
+	u8 *mac;
 
 	id = qlcnic_sriov_func_to_index(adapter, func);
 	if (id < 0)
@@ -591,6 +592,14 @@ static int qlcnic_sriov_set_vf_acl(struc
 		return err;
 
 	cmd.req.arg[1] = 0x3 | func << 16;
+	if (vp->spoofchk == true) {
+		mac = vp->mac;
+		cmd.req.arg[2] |= BIT_1 | BIT_3 | BIT_8;
+		cmd.req.arg[4] = mac[5] | mac[4] << 8 | mac[3] << 16 |
+				 mac[2] << 24;
+		cmd.req.arg[5] = mac[1] | mac[0] << 8;
+	}
+
 	if (vp->vlan_mode == QLC_PVID_MODE) {
 		cmd.req.arg[2] |= BIT_6;
 		cmd.req.arg[3] |= vp->vlan << 8;
@@ -626,12 +635,12 @@ static int qlcnic_sriov_pf_channel_cfg_c
 					   struct qlcnic_cmd_args *cmd)
 {
 	struct qlcnic_vf_info *vf = trans->vf;
-	struct qlcnic_adapter *adapter = vf->adapter;
-	int err;
+	struct qlcnic_vport *vp = vf->vp;
+	struct qlcnic_adapter *adapter;
 	u16 func = vf->pci_func;
+	int err;
 
-	cmd->rsp.arg[0] = trans->req_hdr->cmd_op;
-	cmd->rsp.arg[0] |= (1 << 16);
+	adapter = vf->adapter;
 
 	if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) {
 		err = qlcnic_sriov_pf_config_vport(adapter, 1, func);
@@ -641,6 +650,8 @@ static int qlcnic_sriov_pf_channel_cfg_c
 				qlcnic_sriov_pf_config_vport(adapter, 0, func);
 		}
 	} else {
+		if (vp->vlan_mode == QLC_GUEST_VLAN_MODE)
+			vp->vlan = 0;
 		err = qlcnic_sriov_pf_config_vport(adapter, 0, func);
 	}
 
@@ -1174,7 +1185,7 @@ static int qlcnic_sriov_pf_get_acl_cmd(s
 	u8 cmd_op, mode = vp->vlan_mode;
 
 	cmd_op = trans->req_hdr->cmd_op;
-	cmd->rsp.arg[0] = (cmd_op & 0xffff) | 14 << 16 | 1 << 25;
+	cmd->rsp.arg[0] |= 1 << 25;
 
 	switch (mode) {
 	case QLC_GUEST_VLAN_MODE:
@@ -1552,6 +1563,7 @@ void qlcnic_sriov_pf_handle_flr(struct q
 				struct qlcnic_vf_info *vf)
 {
 	struct net_device *dev = vf->adapter->netdev;
+	struct qlcnic_vport *vp = vf->vp;
 
 	if (!test_and_clear_bit(QLC_BC_VF_STATE, &vf->state)) {
 		clear_bit(QLC_BC_VF_FLR, &vf->state);
@@ -1564,6 +1576,9 @@ void qlcnic_sriov_pf_handle_flr(struct q
 		return;
 	}
 
+	if (vp->vlan_mode == QLC_GUEST_VLAN_MODE)
+		vp->vlan = 0;
+
 	qlcnic_sriov_schedule_flr(sriov, vf, qlcnic_sriov_pf_process_flr);
 	netdev_info(dev, "FLR received for PCI func %d\n", vf->pci_func);
 }
@@ -1612,13 +1627,15 @@ int qlcnic_sriov_set_vf_mac(struct net_d
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
-	int i, num_vfs = sriov->num_vfs;
+	int i, num_vfs;
 	struct qlcnic_vf_info *vf_info;
 	u8 *curr_mac;
 
 	if (!qlcnic_sriov_pf_check(adapter))
 		return -EOPNOTSUPP;
 
+	num_vfs = sriov->num_vfs;
+
 	if (!is_valid_ether_addr(mac) || vf >= num_vfs)
 		return -EINVAL;
 
@@ -1732,6 +1749,7 @@ int qlcnic_sriov_set_vf_vlan(struct net_
 
 	switch (vlan) {
 	case 4095:
+		vp->vlan = 0;
 		vp->vlan_mode = QLC_GUEST_VLAN_MODE;
 		break;
 	case 0:
@@ -1750,6 +1768,29 @@ int qlcnic_sriov_set_vf_vlan(struct net_
 	return 0;
 }
 
+static inline __u32 qlcnic_sriov_get_vf_vlan(struct qlcnic_adapter *adapter,
+					     struct qlcnic_vport *vp, int vf)
+{
+	__u32 vlan = 0;
+
+	switch (vp->vlan_mode) {
+	case QLC_PVID_MODE:
+		vlan = vp->vlan;
+		break;
+	case QLC_GUEST_VLAN_MODE:
+		vlan = MAX_VLAN_ID;
+		break;
+	case QLC_NO_VLAN_MODE:
+		vlan = 0;
+		break;
+	default:
+		netdev_info(adapter->netdev, "Invalid VLAN mode = %d for VF %d\n",
+			    vp->vlan_mode, vf);
+	}
+
+	return vlan;
+}
+
 int qlcnic_sriov_get_vf_config(struct net_device *netdev,
 			       int vf, struct ifla_vf_info *ivi)
 {
@@ -1765,8 +1806,9 @@ int qlcnic_sriov_get_vf_config(struct ne
 
 	vp = sriov->vf_info[vf].vp;
 	memcpy(&ivi->mac, vp->mac, ETH_ALEN);
-	ivi->vlan = vp->vlan;
+	ivi->vlan = qlcnic_sriov_get_vf_vlan(adapter, vp, vf);
 	ivi->qos = vp->qos;
+	ivi->spoofchk = vp->spoofchk;
 	if (vp->max_tx_bw == MAX_BW)
 		ivi->tx_rate = 0;
 	else
@@ -1775,3 +1817,29 @@ int qlcnic_sriov_get_vf_config(struct ne
 	ivi->vf = vf;
 	return 0;
 }
+
+int qlcnic_sriov_set_vf_spoofchk(struct net_device *netdev, int vf, bool chk)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_sriov *sriov = adapter->ahw->sriov;
+	struct qlcnic_vf_info *vf_info;
+	struct qlcnic_vport *vp;
+
+	if (!qlcnic_sriov_pf_check(adapter))
+		return -EOPNOTSUPP;
+
+	if (vf >= sriov->num_vfs)
+		return -EINVAL;
+
+	vf_info = &sriov->vf_info[vf];
+	vp = vf_info->vp;
+	if (test_bit(QLC_BC_VF_STATE, &vf_info->state)) {
+		netdev_err(netdev,
+			   "Spoof check change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation\n",
+			   vf);
+		return -EOPNOTSUPP;
+	}
+
+	vp->spoofchk = chk;
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,7 +47,7 @@ static ssize_t qlcnic_store_bridged_mode
 	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
 		goto err_out;
 
-	if (strict_strtoul(buf, 2, &new))
+	if (kstrtoul(buf, 2, &new))
 		goto err_out;
 
 	if (!qlcnic_config_bridged_mode(adapter, !!new))
@@ -77,7 +77,7 @@ static ssize_t qlcnic_store_diag_mode(st
 	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
 	unsigned long new;
 
-	if (strict_strtoul(buf, 2, &new))
+	if (kstrtoul(buf, 2, &new))
 		return -EINVAL;
 
 	if (!!new != !!(adapter->flags & QLCNIC_DIAG_ENABLED))
@@ -114,57 +114,51 @@ static int qlcnic_validate_beacon(struct
 	return 0;
 }
 
-static ssize_t qlcnic_store_beacon(struct device *dev,
-				   struct device_attribute *attr,
-				   const char *buf, size_t len)
+static int qlcnic_83xx_store_beacon(struct qlcnic_adapter *adapter,
+				    const char *buf, size_t len)
 {
-	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
 	struct qlcnic_hardware_context *ahw = adapter->ahw;
-	int err, max_sds_rings = adapter->max_sds_rings;
-	u16 beacon;
-	u8 b_state, b_rate;
 	unsigned long h_beacon;
+	int err;
 
-	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
-		dev_warn(dev,
-			 "LED test not supported in non privileged mode\n");
-		return -EOPNOTSUPP;
-	}
+	if (test_bit(__QLCNIC_RESETTING, &adapter->state))
+		return -EIO;
 
-	if (qlcnic_83xx_check(adapter) &&
-	    !test_bit(__QLCNIC_RESETTING, &adapter->state)) {
-		if (kstrtoul(buf, 2, &h_beacon))
-			return -EINVAL;
+	if (kstrtoul(buf, 2, &h_beacon))
+		return -EINVAL;
 
-		if (ahw->beacon_state == h_beacon)
-			return len;
+	if (ahw->beacon_state == h_beacon)
+		return len;
 
-		rtnl_lock();
-		if (!ahw->beacon_state) {
-			if (test_and_set_bit(__QLCNIC_LED_ENABLE,
-					     &adapter->state)) {
-				rtnl_unlock();
-				return -EBUSY;
-			}
-		}
-		if (h_beacon) {
-			err = qlcnic_83xx_config_led(adapter, 1, h_beacon);
-			if (err)
-				goto beacon_err;
-		} else {
-			err = qlcnic_83xx_config_led(adapter, 0, !h_beacon);
-			if (err)
-				goto beacon_err;
+	rtnl_lock();
+	if (!ahw->beacon_state) {
+		if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
+			rtnl_unlock();
+			return -EBUSY;
 		}
-		/* set the current beacon state */
+	}
+
+	if (h_beacon)
+		err = qlcnic_83xx_config_led(adapter, 1, h_beacon);
+	else
+		err = qlcnic_83xx_config_led(adapter, 0, !h_beacon);
+	if (!err)
 		ahw->beacon_state = h_beacon;
-beacon_err:
-		if (!ahw->beacon_state)
-			clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
 
-		rtnl_unlock();
-		return len;
-	}
+	if (!ahw->beacon_state)
+		clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
+
+	rtnl_unlock();
+	return len;
+}
+
+static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter,
+				    const char *buf, size_t len)
+{
+	struct qlcnic_hardware_context *ahw = adapter->ahw;
+	int err, max_sds_rings = adapter->max_sds_rings;
+	u16 beacon;
+	u8 h_beacon_state, b_state, b_rate;
 
 	if (len != sizeof(u16))
 		return QL_STATUS_INVALID_PARAM;
@@ -174,16 +168,29 @@ beacon_err:
 	if (err)
 		return err;
 
-	if (adapter->ahw->beacon_state == b_state)
+	if (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_2_BEACON) {
+		err = qlcnic_get_beacon_state(adapter, &h_beacon_state);
+		if (err) {
+			netdev_err(adapter->netdev,
+				   "Failed to get current beacon state\n");
+		} else {
+			if (h_beacon_state == QLCNIC_BEACON_DISABLE)
+				ahw->beacon_state = 0;
+			else if (h_beacon_state == QLCNIC_BEACON_EANBLE)
+				ahw->beacon_state = 2;
+		}
+	}
+
+	if (ahw->beacon_state == b_state)
 		return len;
 
 	rtnl_lock();
-
-	if (!adapter->ahw->beacon_state)
+	if (!ahw->beacon_state) {
 		if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state)) {
 			rtnl_unlock();
 			return -EBUSY;
 		}
+	}
 
 	if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
 		err = -EIO;
@@ -206,13 +213,36 @@ beacon_err:
 	if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
 		qlcnic_diag_free_res(adapter->netdev, max_sds_rings);
 
- out:
-	if (!adapter->ahw->beacon_state)
+out:
+	if (!ahw->beacon_state)
 		clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
 	rtnl_unlock();
 
 	return err;
 }
+
+static ssize_t qlcnic_store_beacon(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t len)
+{
+	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+	int err = 0;
+
+	if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
+		dev_warn(dev,
+			 "LED test not supported in non privileged mode\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (qlcnic_82xx_check(adapter))
+		err = qlcnic_82xx_store_beacon(adapter, buf, len);
+	else if (qlcnic_83xx_check(adapter))
+		err = qlcnic_83xx_store_beacon(adapter, buf, len);
+	else
+		return -EIO;
+
+	return err;
+}
 
 static ssize_t qlcnic_show_beacon(struct device *dev,
 				  struct device_attribute *attr, char *buf)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlge/qlge_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlge/qlge_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/qlogic/qlge/qlge_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/qlogic/qlge/qlge_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -4946,15 +4946,4 @@ static struct pci_driver qlge_driver = {
 	.err_handler = &qlge_err_handler
 };
 
-static int __init qlge_init_module(void)
-{
-	return pci_register_driver(&qlge_driver);
-}
-
-static void __exit qlge_exit(void)
-{
-	pci_unregister_driver(&qlge_driver);
-}
-
-module_init(qlge_init_module);
-module_exit(qlge_exit);
+module_pci_driver(qlge_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/rdc/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/rdc/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/rdc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/rdc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@ config R6040
 	tristate "RDC R6040 Fast Ethernet Adapter support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	select PHYLIB
 	---help---
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/realtek/8139cp.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/realtek/8139cp.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/realtek/8139cp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/realtek/8139cp.c	2013-08-25 20:43:22.000000000 -0400
@@ -478,7 +478,7 @@ rx_status_loop:
 
 	while (1) {
 		u32 status, len;
-		dma_addr_t mapping;
+		dma_addr_t mapping, new_mapping;
 		struct sk_buff *skb, *new_skb;
 		struct cp_desc *desc;
 		const unsigned buflen = cp->rx_buf_sz;
@@ -520,6 +520,14 @@ rx_status_loop:
 			goto rx_next;
 		}
 
+		new_mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen,
+					 PCI_DMA_FROMDEVICE);
+		if (dma_mapping_error(&cp->pdev->dev, new_mapping)) {
+			dev->stats.rx_dropped++;
+			kfree_skb(new_skb);
+			goto rx_next;
+		}
+
 		dma_unmap_single(&cp->pdev->dev, mapping,
 				 buflen, PCI_DMA_FROMDEVICE);
 
@@ -531,12 +539,11 @@ rx_status_loop:
 
 		skb_put(skb, len);
 
-		mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen,
-					 PCI_DMA_FROMDEVICE);
 		cp->rx_skb[rx_tail] = new_skb;
 
 		cp_rx_skb(cp, skb, desc);
 		rx++;
+		mapping = new_mapping;
 
 rx_next:
 		cp->rx_ring[rx_tail].opts2 = 0;
@@ -716,6 +723,22 @@ static inline u32 cp_tx_vlan_tag(struct
 		TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
 }
 
+static void unwind_tx_frag_mapping(struct cp_private *cp, struct sk_buff *skb,
+				   int first, int entry_last)
+{
+	int frag, index;
+	struct cp_desc *txd;
+	skb_frag_t *this_frag;
+	for (frag = 0; frag+first < entry_last; frag++) {
+		index = first+frag;
+		cp->tx_skb[index] = NULL;
+		txd = &cp->tx_ring[index];
+		this_frag = &skb_shinfo(skb)->frags[frag];
+		dma_unmap_single(&cp->pdev->dev, le64_to_cpu(txd->addr),
+				 skb_frag_size(this_frag), PCI_DMA_TODEVICE);
+	}
+}
+
 static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
 					struct net_device *dev)
 {
@@ -749,6 +772,9 @@ static netdev_tx_t cp_start_xmit (struct
 
 		len = skb->len;
 		mapping = dma_map_single(&cp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE);
+		if (dma_mapping_error(&cp->pdev->dev, mapping))
+			goto out_dma_error;
+
 		txd->opts2 = opts2;
 		txd->addr = cpu_to_le64(mapping);
 		wmb();
@@ -786,6 +812,9 @@ static netdev_tx_t cp_start_xmit (struct
 		first_len = skb_headlen(skb);
 		first_mapping = dma_map_single(&cp->pdev->dev, skb->data,
 					       first_len, PCI_DMA_TODEVICE);
+		if (dma_mapping_error(&cp->pdev->dev, first_mapping))
+			goto out_dma_error;
+
 		cp->tx_skb[entry] = skb;
 		entry = NEXT_TX(entry);
 
@@ -799,6 +828,11 @@ static netdev_tx_t cp_start_xmit (struct
 			mapping = dma_map_single(&cp->pdev->dev,
 						 skb_frag_address(this_frag),
 						 len, PCI_DMA_TODEVICE);
+			if (dma_mapping_error(&cp->pdev->dev, mapping)) {
+				unwind_tx_frag_mapping(cp, skb, first_entry, entry);
+				goto out_dma_error;
+			}
+
 			eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
 
 			ctrl = eor | len | DescOwn;
@@ -859,11 +893,16 @@ static netdev_tx_t cp_start_xmit (struct
 	if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
 		netif_stop_queue(dev);
 
+out_unlock:
 	spin_unlock_irqrestore(&cp->lock, intr_flags);
 
 	cpw8(TxPoll, NormalTxPoll);
 
 	return NETDEV_TX_OK;
+out_dma_error:
+	kfree_skb(skb);
+	cp->dev->stats.tx_dropped++;
+	goto out_unlock;
 }
 
 /* Set or clear the multicast filter for this adaptor.
@@ -1054,6 +1093,10 @@ static int cp_refill_rx(struct cp_privat
 
 		mapping = dma_map_single(&cp->pdev->dev, skb->data,
 					 cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+		if (dma_mapping_error(&cp->pdev->dev, mapping)) {
+			kfree_skb(skb);
+			goto err_out;
+		}
 		cp->rx_skb[i] = skb;
 
 		cp->rx_ring[i].opts2 = 0;
@@ -1817,7 +1860,7 @@ static int cp_set_eeprom(struct net_devi
 /* Put the board into D3cold state and wait for WakeUp signal */
 static void cp_set_d3_state (struct cp_private *cp)
 {
-	pci_enable_wake (cp->pdev, 0, 1); /* Enable PME# generation */
+	pci_enable_wake(cp->pdev, PCI_D0, 1); /* Enable PME# generation */
 	pci_set_power_state (cp->pdev, PCI_D3hot);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/realtek/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/realtek/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/realtek/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/realtek/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,6 @@ config 8139CP
 	tristate "RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This is a driver for the Fast Ethernet PCI network cards based on
@@ -52,7 +51,6 @@ config 8139TOO
 	tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This is a driver for the Fast Ethernet PCI network cards based on
@@ -107,7 +105,6 @@ config R8169
 	depends on PCI
 	select FW_LOADER
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/realtek/r8169.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/realtek/r8169.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/realtek/r8169.c	2013-07-01 10:37:10.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/realtek/r8169.c	2013-08-31 17:56:43.000000000 -0400
@@ -46,6 +46,7 @@
 #define FIRMWARE_8105E_1	"/*(DEBLOBBED)*/"
 #define FIRMWARE_8402_1		"/*(DEBLOBBED)*/"
 #define FIRMWARE_8411_1		"/*(DEBLOBBED)*/"
+#define FIRMWARE_8411_2		"/*(DEBLOBBED)*/"
 #define FIRMWARE_8106E_1	"/*(DEBLOBBED)*/"
 #define FIRMWARE_8106E_2	"/*(DEBLOBBED)*/"
 #define FIRMWARE_8168G_2	"/*(DEBLOBBED)*/"
@@ -144,6 +145,7 @@ enum mac_version {
 	RTL_GIGA_MAC_VER_41,
 	RTL_GIGA_MAC_VER_42,
 	RTL_GIGA_MAC_VER_43,
+	RTL_GIGA_MAC_VER_44,
 	RTL_GIGA_MAC_NONE   = 0xff,
 };
 
@@ -276,6 +278,9 @@ static const struct {
 	[RTL_GIGA_MAC_VER_43] =
 		_R("RTL8106e",		RTL_TD_1, FIRMWARE_8106E_2,
 							JUMBO_1K, true),
+	[RTL_GIGA_MAC_VER_44] =
+		_R("RTL8411",		RTL_TD_1, FIRMWARE_8411_2,
+							JUMBO_9K, false),
 };
 #undef _R
 
@@ -394,6 +399,7 @@ enum rtl8168_8101_registers {
 #define CSIAR_FUNC_CARD			0x00000000
 #define CSIAR_FUNC_SDIO			0x00010000
 #define CSIAR_FUNC_NIC			0x00020000
+#define CSIAR_FUNC_NIC2			0x00010000
 	PMCH			= 0x6f,
 	EPHYAR			= 0x80,
 #define	EPHYAR_FLAG			0x80000000
@@ -2038,6 +2044,7 @@ static void rtl8169_get_mac_version(stru
 		int mac_version;
 	} mac_info[] = {
 		/* 8168G family. */
+		{ 0x7cf00000, 0x5c800000,	RTL_GIGA_MAC_VER_44 },
 		{ 0x7cf00000, 0x50900000,	RTL_GIGA_MAC_VER_42 },
 		{ 0x7cf00000, 0x4c100000,	RTL_GIGA_MAC_VER_41 },
 		{ 0x7cf00000, 0x4c000000,	RTL_GIGA_MAC_VER_40 },
@@ -3638,6 +3645,7 @@ static void rtl_hw_phy_config(struct net
 		break;
 	case RTL_GIGA_MAC_VER_42:
 	case RTL_GIGA_MAC_VER_43:
+	case RTL_GIGA_MAC_VER_44:
 		rtl8168g_2_hw_phy_config(tp);
 		break;
 
@@ -3667,7 +3675,7 @@ static void rtl_phy_work(struct rtl8169_
 	if (tp->link_ok(ioaddr))
 		return;
 
-	netif_warn(tp, link, tp->dev, "PHY reset until link up\n");
+	netif_dbg(tp, link, tp->dev, "PHY reset until link up\n");
 
 	tp->phy_reset_enable(tp);
 
@@ -3850,6 +3858,7 @@ static void rtl_init_mdio_ops(struct rtl
 	case RTL_GIGA_MAC_VER_41:
 	case RTL_GIGA_MAC_VER_42:
 	case RTL_GIGA_MAC_VER_43:
+	case RTL_GIGA_MAC_VER_44:
 		ops->write	= r8168g_mdio_write;
 		ops->read	= r8168g_mdio_read;
 		break;
@@ -3903,6 +3912,7 @@ static void rtl_wol_suspend_quirk(struct
 	case RTL_GIGA_MAC_VER_41:
 	case RTL_GIGA_MAC_VER_42:
 	case RTL_GIGA_MAC_VER_43:
+	case RTL_GIGA_MAC_VER_44:
 		RTL_W32(RxConfig, RTL_R32(RxConfig) |
 			AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
 		break;
@@ -4165,6 +4175,7 @@ static void rtl_init_pll_power_ops(struc
 	case RTL_GIGA_MAC_VER_40:
 	case RTL_GIGA_MAC_VER_41:
 	case RTL_GIGA_MAC_VER_42:
+	case RTL_GIGA_MAC_VER_44:
 		ops->down	= r8168_pll_power_down;
 		ops->up		= r8168_pll_power_up;
 		break;
@@ -4211,6 +4222,7 @@ static void rtl_init_rxcfg(struct rtl816
 	case RTL_GIGA_MAC_VER_41:
 	case RTL_GIGA_MAC_VER_42:
 	case RTL_GIGA_MAC_VER_43:
+	case RTL_GIGA_MAC_VER_44:
 		RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF);
 		break;
 	default:
@@ -4371,6 +4383,7 @@ static void rtl_init_jumbo_ops(struct rt
 	case RTL_GIGA_MAC_VER_41:
 	case RTL_GIGA_MAC_VER_42:
 	case RTL_GIGA_MAC_VER_43:
+	case RTL_GIGA_MAC_VER_44:
 	default:
 		ops->disable	= NULL;
 		ops->enable	= NULL;
@@ -4480,6 +4493,7 @@ static void rtl8169_hw_reset(struct rtl8
 	           tp->mac_version == RTL_GIGA_MAC_VER_41 ||
 	           tp->mac_version == RTL_GIGA_MAC_VER_42 ||
 	           tp->mac_version == RTL_GIGA_MAC_VER_43 ||
+	           tp->mac_version == RTL_GIGA_MAC_VER_44 ||
 	           tp->mac_version == RTL_GIGA_MAC_VER_38) {
 		RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
 		rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
@@ -4769,6 +4783,29 @@ static u32 r8402_csi_read(struct rtl8169
 		RTL_R32(CSIDR) : ~0;
 }
 
+static void r8411_csi_write(struct rtl8169_private *tp, int addr, int value)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	RTL_W32(CSIDR, value);
+	RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
+		CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT |
+		CSIAR_FUNC_NIC2);
+
+	rtl_udelay_loop_wait_low(tp, &rtl_csiar_cond, 10, 100);
+}
+
+static u32 r8411_csi_read(struct rtl8169_private *tp, int addr)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_FUNC_NIC2 |
+		CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
+
+	return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ?
+		RTL_R32(CSIDR) : ~0;
+}
+
 static void rtl_init_csi_ops(struct rtl8169_private *tp)
 {
 	struct csi_ops *ops = &tp->csi_ops;
@@ -4798,6 +4835,11 @@ static void rtl_init_csi_ops(struct rtl8
 		ops->read	= r8402_csi_read;
 		break;
 
+	case RTL_GIGA_MAC_VER_44:
+		ops->write	= r8411_csi_write;
+		ops->read	= r8411_csi_read;
+		break;
+
 	default:
 		ops->write	= r8169_csi_write;
 		ops->read	= r8169_csi_read;
@@ -5242,6 +5284,25 @@ static void rtl_hw_start_8168g_2(struct
 	rtl_ephy_init(tp, e_info_8168g_2, ARRAY_SIZE(e_info_8168g_2));
 }
 
+static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	static const struct ephy_info e_info_8411_2[] = {
+		{ 0x00, 0x0000,	0x0008 },
+		{ 0x0c, 0x3df0,	0x0200 },
+		{ 0x0f, 0xffff,	0x5200 },
+		{ 0x19, 0x0020,	0x0000 },
+		{ 0x1e, 0x0000,	0x2000 }
+	};
+
+	rtl_hw_start_8168g_1(tp);
+
+	/* disable aspm and clock request before access ephy */
+	RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
+	RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
+	rtl_ephy_init(tp, e_info_8411_2, ARRAY_SIZE(e_info_8411_2));
+}
+
 static void rtl_hw_start_8168(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -5348,6 +5409,10 @@ static void rtl_hw_start_8168(struct net
 		rtl_hw_start_8168g_2(tp);
 		break;
 
+	case RTL_GIGA_MAC_VER_44:
+		rtl_hw_start_8411_2(tp);
+		break;
+
 	default:
 		printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n",
 			dev->name, tp->mac_version);
@@ -6389,6 +6454,8 @@ static int rtl8169_close(struct net_devi
 	rtl8169_down(dev);
 	rtl_unlock_work(tp);
 
+	cancel_work_sync(&tp->wk.work);
+
 	free_irq(pdev->irq, dev);
 
 	dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
@@ -6714,8 +6781,6 @@ static void rtl_remove_one(struct pci_de
 		rtl8168_driver_stop(tp);
 	}
 
-	cancel_work_sync(&tp->wk.work);
-
 	netif_napi_del(&tp->napi);
 
 	unregister_netdev(dev);
@@ -6864,6 +6929,7 @@ static void rtl_hw_initialize(struct rtl
 	case RTL_GIGA_MAC_VER_41:
 	case RTL_GIGA_MAC_VER_42:
 	case RTL_GIGA_MAC_VER_43:
+	case RTL_GIGA_MAC_VER_44:
 		rtl_hw_init_8168g(tp);
 		break;
 
@@ -7008,7 +7074,7 @@ rtl_init_one(struct pci_dev *pdev, const
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
 	RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
-	RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
+	RTL_W8(Config5, RTL_R8(Config5) & (BWF | MWF | UWF | LanWake | PMEStatus));
 	if ((RTL_R8(Config3) & (LinkUp | MagicPacket)) != 0)
 		tp->features |= RTL_FEATURE_WOL;
 	if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/renesas/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/renesas/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/renesas/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/renesas/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -4,14 +4,8 @@
 
 config SH_ETH
 	tristate "Renesas SuperH Ethernet support"
-	depends on (SUPERH || ARCH_SHMOBILE) && \
-		(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
-		 CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
-		 CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \
-		 CPU_SUBTYPE_SH7757 || ARCH_R8A7740 || \
-		 ARCH_R8A7778 || ARCH_R8A7779)
+	depends on HAS_DMA
 	select CRC32
-	select NET_CORE
 	select MII
 	select MDIO_BITBANG
 	select PHYLIB
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/renesas/sh_eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/renesas/sh_eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/renesas/sh_eth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/renesas/sh_eth.c	2013-08-25 20:43:22.000000000 -0400
@@ -313,9 +313,14 @@ static const u16 sh_eth_offset_fast_sh3_
 	[TSU_ADRL31]	= 0x01fc,
 };
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7734) || \
-	defined(CONFIG_CPU_SUBTYPE_SH7763) || \
-	defined(CONFIG_ARCH_R8A7740)
+static int sh_eth_is_gether(struct sh_eth_private *mdp)
+{
+	if (mdp->reg_offset == sh_eth_offset_gigabit)
+		return 1;
+	else
+		return 0;
+}
+
 static void sh_eth_select_mii(struct net_device *ndev)
 {
 	u32 value = 0x0;
@@ -339,11 +344,7 @@ static void sh_eth_select_mii(struct net
 
 	sh_eth_write(ndev, value, RMII_MII);
 }
-#endif
 
-/* There is CPU dependent code */
-#if defined(CONFIG_ARCH_R8A7778) || defined(CONFIG_ARCH_R8A7779)
-#define SH_ETH_RESET_DEFAULT	1
 static void sh_eth_set_duplex(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -354,7 +355,8 @@ static void sh_eth_set_duplex(struct net
 		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
 }
 
-static void sh_eth_set_rate(struct net_device *ndev)
+/* There is CPU dependent code */
+static void sh_eth_set_rate_r8a777x(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -371,9 +373,9 @@ static void sh_eth_set_rate(struct net_d
 }
 
 /* R8A7778/9 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+static struct sh_eth_cpu_data r8a777x_data = {
 	.set_duplex	= sh_eth_set_duplex,
-	.set_rate	= sh_eth_set_rate,
+	.set_rate	= sh_eth_set_rate_r8a777x,
 
 	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
 	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
@@ -383,26 +385,14 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
 			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
 			  EESR_ECI,
-	.tx_error_check	= EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
 
 	.apr		= 1,
 	.mpr		= 1,
 	.tpauser	= 1,
 	.hw_swap	= 1,
 };
-#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
-#define SH_ETH_RESET_DEFAULT	1
-static void sh_eth_set_duplex(struct net_device *ndev)
-{
-	struct sh_eth_private *mdp = netdev_priv(ndev);
-
-	if (mdp->duplex) /* Full */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
-	else		/* Half */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
-}
 
-static void sh_eth_set_rate(struct net_device *ndev)
+static void sh_eth_set_rate_sh7724(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -419,19 +409,18 @@ static void sh_eth_set_rate(struct net_d
 }
 
 /* SH7724 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+static struct sh_eth_cpu_data sh7724_data = {
 	.set_duplex	= sh_eth_set_duplex,
-	.set_rate	= sh_eth_set_rate,
+	.set_rate	= sh_eth_set_rate_sh7724,
 
 	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
 	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
-	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x01ff009f,
+	.eesipr_value	= 0x01ff009f,
 
 	.tx_check	= EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
 	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
 			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
 			  EESR_ECI,
-	.tx_error_check	= EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
 
 	.apr		= 1,
 	.mpr		= 1,
@@ -440,22 +429,8 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.rpadir		= 1,
 	.rpadir_value	= 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
 };
-#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
-#define SH_ETH_HAS_BOTH_MODULES	1
-#define SH_ETH_HAS_TSU	1
-static int sh_eth_check_reset(struct net_device *ndev);
 
-static void sh_eth_set_duplex(struct net_device *ndev)
-{
-	struct sh_eth_private *mdp = netdev_priv(ndev);
-
-	if (mdp->duplex) /* Full */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
-	else		/* Half */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
-}
-
-static void sh_eth_set_rate(struct net_device *ndev)
+static void sh_eth_set_rate_sh7757(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -472,9 +447,9 @@ static void sh_eth_set_rate(struct net_d
 }
 
 /* SH7757 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
-	.set_duplex		= sh_eth_set_duplex,
-	.set_rate		= sh_eth_set_rate,
+static struct sh_eth_cpu_data sh7757_data = {
+	.set_duplex	= sh_eth_set_duplex,
+	.set_rate	= sh_eth_set_rate_sh7757,
 
 	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
 	.rmcr_value	= 0x00000001,
@@ -483,8 +458,8 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
 			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
 			  EESR_ECI,
-	.tx_error_check	= EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
 
+	.irq_flags	= IRQF_SHARED,
 	.apr		= 1,
 	.mpr		= 1,
 	.tpauser	= 1,
@@ -494,7 +469,7 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.rpadir_value   = 2 << 16,
 };
 
-#define SH_GIGA_ETH_BASE	0xfee00000
+#define SH_GIGA_ETH_BASE	0xfee00000UL
 #define GIGA_MALR(port)		(SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8)
 #define GIGA_MAHR(port)		(SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0)
 static void sh_eth_chip_reset_giga(struct net_device *ndev)
@@ -519,52 +494,6 @@ static void sh_eth_chip_reset_giga(struc
 	}
 }
 
-static int sh_eth_is_gether(struct sh_eth_private *mdp);
-static int sh_eth_reset(struct net_device *ndev)
-{
-	struct sh_eth_private *mdp = netdev_priv(ndev);
-	int ret = 0;
-
-	if (sh_eth_is_gether(mdp)) {
-		sh_eth_write(ndev, 0x03, EDSR);
-		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
-				EDMR);
-
-		ret = sh_eth_check_reset(ndev);
-		if (ret)
-			goto out;
-
-		/* Table Init */
-		sh_eth_write(ndev, 0x0, TDLAR);
-		sh_eth_write(ndev, 0x0, TDFAR);
-		sh_eth_write(ndev, 0x0, TDFXR);
-		sh_eth_write(ndev, 0x0, TDFFR);
-		sh_eth_write(ndev, 0x0, RDLAR);
-		sh_eth_write(ndev, 0x0, RDFAR);
-		sh_eth_write(ndev, 0x0, RDFXR);
-		sh_eth_write(ndev, 0x0, RDFFR);
-	} else {
-		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
-				EDMR);
-		mdelay(3);
-		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
-				EDMR);
-	}
-
-out:
-	return ret;
-}
-
-static void sh_eth_set_duplex_giga(struct net_device *ndev)
-{
-	struct sh_eth_private *mdp = netdev_priv(ndev);
-
-	if (mdp->duplex) /* Full */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
-	else		/* Half */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
-}
-
 static void sh_eth_set_rate_giga(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -585,9 +514,9 @@ static void sh_eth_set_rate_giga(struct
 }
 
 /* SH7757(GETHERC) */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
+static struct sh_eth_cpu_data sh7757_data_giga = {
 	.chip_reset	= sh_eth_chip_reset_giga,
-	.set_duplex	= sh_eth_set_duplex_giga,
+	.set_duplex	= sh_eth_set_duplex,
 	.set_rate	= sh_eth_set_rate_giga,
 
 	.ecsr_value	= ECSR_ICD | ECSR_MPD,
@@ -598,11 +527,10 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
 			  EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
 			  EESR_TDE | EESR_ECI,
-	.tx_error_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
-			  EESR_TFE,
 	.fdr_value	= 0x0000072f,
 	.rmcr_value	= 0x00000001,
 
+	.irq_flags	= IRQF_SHARED,
 	.apr		= 1,
 	.mpr		= 1,
 	.tpauser	= 1,
@@ -615,19 +543,6 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.tsu		= 1,
 };
 
-static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
-{
-	if (sh_eth_is_gether(mdp))
-		return &sh_eth_my_cpu_data_giga;
-	else
-		return &sh_eth_my_cpu_data;
-}
-
-#elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
-#define SH_ETH_HAS_TSU	1
-static int sh_eth_check_reset(struct net_device *ndev);
-static void sh_eth_reset_hw_crc(struct net_device *ndev);
-
 static void sh_eth_chip_reset(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -637,17 +552,7 @@ static void sh_eth_chip_reset(struct net
 	mdelay(1);
 }
 
-static void sh_eth_set_duplex(struct net_device *ndev)
-{
-	struct sh_eth_private *mdp = netdev_priv(ndev);
-
-	if (mdp->duplex) /* Full */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
-	else		/* Half */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
-}
-
-static void sh_eth_set_rate(struct net_device *ndev)
+static void sh_eth_set_rate_gether(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -666,11 +571,11 @@ static void sh_eth_set_rate(struct net_d
 	}
 }
 
-/* sh7763 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+/* SH7734 */
+static struct sh_eth_cpu_data sh7734_data = {
 	.chip_reset	= sh_eth_chip_reset,
 	.set_duplex	= sh_eth_set_duplex,
-	.set_rate	= sh_eth_set_rate,
+	.set_rate	= sh_eth_set_rate_gether,
 
 	.ecsr_value	= ECSR_ICD | ECSR_MPD,
 	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
@@ -680,8 +585,6 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
 			  EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
 			  EESR_TDE | EESR_ECI,
-	.tx_error_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
-			  EESR_TFE,
 
 	.apr		= 1,
 	.mpr		= 1,
@@ -691,54 +594,37 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.no_trimd	= 1,
 	.no_ade		= 1,
 	.tsu		= 1,
-#if defined(CONFIG_CPU_SUBTYPE_SH7734)
-	.hw_crc     = 1,
-	.select_mii = 1,
-#endif
+	.hw_crc		= 1,
+	.select_mii	= 1,
 };
 
-static int sh_eth_reset(struct net_device *ndev)
-{
-	int ret = 0;
-
-	sh_eth_write(ndev, EDSR_ENALL, EDSR);
-	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
-
-	ret = sh_eth_check_reset(ndev);
-	if (ret)
-		goto out;
-
-	/* Table Init */
-	sh_eth_write(ndev, 0x0, TDLAR);
-	sh_eth_write(ndev, 0x0, TDFAR);
-	sh_eth_write(ndev, 0x0, TDFXR);
-	sh_eth_write(ndev, 0x0, TDFFR);
-	sh_eth_write(ndev, 0x0, RDLAR);
-	sh_eth_write(ndev, 0x0, RDFAR);
-	sh_eth_write(ndev, 0x0, RDFXR);
-	sh_eth_write(ndev, 0x0, RDFFR);
-
-	/* Reset HW CRC register */
-	sh_eth_reset_hw_crc(ndev);
+/* SH7763 */
+static struct sh_eth_cpu_data sh7763_data = {
+	.chip_reset	= sh_eth_chip_reset,
+	.set_duplex	= sh_eth_set_duplex,
+	.set_rate	= sh_eth_set_rate_gether,
 
-	/* Select MII mode */
-	if (sh_eth_my_cpu_data.select_mii)
-		sh_eth_select_mii(ndev);
-out:
-	return ret;
-}
+	.ecsr_value	= ECSR_ICD | ECSR_MPD,
+	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
+	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
 
-static void sh_eth_reset_hw_crc(struct net_device *ndev)
-{
-	if (sh_eth_my_cpu_data.hw_crc)
-		sh_eth_write(ndev, 0x0, CSMR);
-}
+	.tx_check	= EESR_TC1 | EESR_FTC,
+	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
+			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
+			  EESR_ECI,
 
-#elif defined(CONFIG_ARCH_R8A7740)
-#define SH_ETH_HAS_TSU	1
-static int sh_eth_check_reset(struct net_device *ndev);
+	.apr		= 1,
+	.mpr		= 1,
+	.tpauser	= 1,
+	.bculr		= 1,
+	.hw_swap	= 1,
+	.no_trimd	= 1,
+	.no_ade		= 1,
+	.tsu		= 1,
+	.irq_flags	= IRQF_SHARED,
+};
 
-static void sh_eth_chip_reset(struct net_device *ndev)
+static void sh_eth_chip_reset_r8a7740(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
@@ -749,65 +635,11 @@ static void sh_eth_chip_reset(struct net
 	sh_eth_select_mii(ndev);
 }
 
-static int sh_eth_reset(struct net_device *ndev)
-{
-	int ret = 0;
-
-	sh_eth_write(ndev, EDSR_ENALL, EDSR);
-	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
-
-	ret = sh_eth_check_reset(ndev);
-	if (ret)
-		goto out;
-
-	/* Table Init */
-	sh_eth_write(ndev, 0x0, TDLAR);
-	sh_eth_write(ndev, 0x0, TDFAR);
-	sh_eth_write(ndev, 0x0, TDFXR);
-	sh_eth_write(ndev, 0x0, TDFFR);
-	sh_eth_write(ndev, 0x0, RDLAR);
-	sh_eth_write(ndev, 0x0, RDFAR);
-	sh_eth_write(ndev, 0x0, RDFXR);
-	sh_eth_write(ndev, 0x0, RDFFR);
-
-out:
-	return ret;
-}
-
-static void sh_eth_set_duplex(struct net_device *ndev)
-{
-	struct sh_eth_private *mdp = netdev_priv(ndev);
-
-	if (mdp->duplex) /* Full */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
-	else		/* Half */
-		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
-}
-
-static void sh_eth_set_rate(struct net_device *ndev)
-{
-	struct sh_eth_private *mdp = netdev_priv(ndev);
-
-	switch (mdp->speed) {
-	case 10: /* 10BASE */
-		sh_eth_write(ndev, GECMR_10, GECMR);
-		break;
-	case 100:/* 100BASE */
-		sh_eth_write(ndev, GECMR_100, GECMR);
-		break;
-	case 1000: /* 1000BASE */
-		sh_eth_write(ndev, GECMR_1000, GECMR);
-		break;
-	default:
-		break;
-	}
-}
-
 /* R8A7740 */
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
-	.chip_reset	= sh_eth_chip_reset,
+static struct sh_eth_cpu_data r8a7740_data = {
+	.chip_reset	= sh_eth_chip_reset_r8a7740,
 	.set_duplex	= sh_eth_set_duplex,
-	.set_rate	= sh_eth_set_rate,
+	.set_rate	= sh_eth_set_rate_gether,
 
 	.ecsr_value	= ECSR_ICD | ECSR_MPD,
 	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
@@ -817,8 +649,6 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
 			  EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
 			  EESR_TDE | EESR_ECI,
-	.tx_error_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
-			  EESR_TFE,
 
 	.apr		= 1,
 	.mpr		= 1,
@@ -829,11 +659,10 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.no_ade		= 1,
 	.tsu		= 1,
 	.select_mii	= 1,
+	.shift_rd0	= 1,
 };
 
-#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
-#define SH_ETH_RESET_DEFAULT	1
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+static struct sh_eth_cpu_data sh7619_data = {
 	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
 
 	.apr		= 1,
@@ -841,14 +670,11 @@ static struct sh_eth_cpu_data sh_eth_my_
 	.tpauser	= 1,
 	.hw_swap	= 1,
 };
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
-#define SH_ETH_RESET_DEFAULT	1
-#define SH_ETH_HAS_TSU	1
-static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+
+static struct sh_eth_cpu_data sh771x_data = {
 	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
 	.tsu		= 1,
 };
-#endif
 
 static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
 {
@@ -873,22 +699,8 @@ static void sh_eth_set_default_cpu_data(
 
 	if (!cd->eesr_err_check)
 		cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK;
-
-	if (!cd->tx_error_check)
-		cd->tx_error_check = DEFAULT_TX_ERROR_CHECK;
 }
 
-#if defined(SH_ETH_RESET_DEFAULT)
-/* Chip Reset */
-static int  sh_eth_reset(struct net_device *ndev)
-{
-	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, EDMR);
-	mdelay(3);
-	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, EDMR);
-
-	return 0;
-}
-#else
 static int sh_eth_check_reset(struct net_device *ndev)
 {
 	int ret = 0;
@@ -906,7 +718,49 @@ static int sh_eth_check_reset(struct net
 	}
 	return ret;
 }
-#endif
+
+static int sh_eth_reset(struct net_device *ndev)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	int ret = 0;
+
+	if (sh_eth_is_gether(mdp)) {
+		sh_eth_write(ndev, EDSR_ENALL, EDSR);
+		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
+			     EDMR);
+
+		ret = sh_eth_check_reset(ndev);
+		if (ret)
+			goto out;
+
+		/* Table Init */
+		sh_eth_write(ndev, 0x0, TDLAR);
+		sh_eth_write(ndev, 0x0, TDFAR);
+		sh_eth_write(ndev, 0x0, TDFXR);
+		sh_eth_write(ndev, 0x0, TDFFR);
+		sh_eth_write(ndev, 0x0, RDLAR);
+		sh_eth_write(ndev, 0x0, RDFAR);
+		sh_eth_write(ndev, 0x0, RDFXR);
+		sh_eth_write(ndev, 0x0, RDFFR);
+
+		/* Reset HW CRC register */
+		if (mdp->cd->hw_crc)
+			sh_eth_write(ndev, 0x0, CSMR);
+
+		/* Select MII mode */
+		if (mdp->cd->select_mii)
+			sh_eth_select_mii(ndev);
+	} else {
+		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
+			     EDMR);
+		mdelay(3);
+		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
+			     EDMR);
+	}
+
+out:
+	return ret;
+}
 
 #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
 static void sh_eth_set_receive_align(struct sk_buff *skb)
@@ -982,14 +836,6 @@ static void read_mac_address(struct net_
 	}
 }
 
-static int sh_eth_is_gether(struct sh_eth_private *mdp)
-{
-	if (mdp->reg_offset == sh_eth_offset_gigabit)
-		return 1;
-	else
-		return 0;
-}
-
 static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
 {
 	if (sh_eth_is_gether(mdp))
@@ -1388,7 +1234,7 @@ static int sh_eth_txfree(struct net_devi
 }
 
 /* Packet receive function */
-static int sh_eth_rx(struct net_device *ndev, u32 intr_status)
+static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	struct sh_eth_rxdesc *rxdesc;
@@ -1396,6 +1242,7 @@ static int sh_eth_rx(struct net_device *
 	int entry = mdp->cur_rx % mdp->num_rx_ring;
 	int boguscnt = (mdp->dirty_rx + mdp->num_rx_ring) - mdp->cur_rx;
 	struct sk_buff *skb;
+	int exceeded = 0;
 	u16 pkt_len = 0;
 	u32 desc_status;
 
@@ -1407,10 +1254,15 @@ static int sh_eth_rx(struct net_device *
 		if (--boguscnt < 0)
 			break;
 
+		if (*quota <= 0) {
+			exceeded = 1;
+			break;
+		}
+		(*quota)--;
+
 		if (!(desc_status & RDFEND))
 			ndev->stats.rx_length_errors++;
 
-#if defined(CONFIG_ARCH_R8A7740)
 		/*
 		 * In case of almost all GETHER/ETHERs, the Receive Frame State
 		 * (RFS) bits in the Receive Descriptor 0 are from bit 9 to
@@ -1418,8 +1270,8 @@ static int sh_eth_rx(struct net_device *
 		 * bits are from bit 25 to bit 16. So, the driver needs right
 		 * shifting by 16.
 		 */
-		desc_status >>= 16;
-#endif
+		if (mdp->cd->shift_rd0)
+			desc_status >>= 16;
 
 		if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
 				   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
@@ -1494,7 +1346,7 @@ static int sh_eth_rx(struct net_device *
 		sh_eth_write(ndev, EDRRR_R, EDRRR);
 	}
 
-	return 0;
+	return exceeded;
 }
 
 static void sh_eth_rcv_snd_disable(struct net_device *ndev)
@@ -1636,7 +1488,7 @@ static irqreturn_t sh_eth_interrupt(int
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	struct sh_eth_cpu_data *cd = mdp->cd;
 	irqreturn_t ret = IRQ_NONE;
-	unsigned long intr_status;
+	unsigned long intr_status, intr_enable;
 
 	spin_lock(&mdp->lock);
 
@@ -1647,34 +1499,41 @@ static irqreturn_t sh_eth_interrupt(int
 	 * and we need to fully handle it in sh_eth_error() in order to quench
 	 * it as it doesn't get cleared by just writing 1 to the ECI bit...
 	 */
-	intr_status &= sh_eth_read(ndev, EESIPR) | DMAC_M_ECI;
-	/* Clear interrupt */
-	if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
-			EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
-			cd->tx_check | cd->eesr_err_check)) {
-		sh_eth_write(ndev, intr_status, EESR);
+	intr_enable = sh_eth_read(ndev, EESIPR);
+	intr_status &= intr_enable | DMAC_M_ECI;
+	if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check))
 		ret = IRQ_HANDLED;
-	} else
+	else
 		goto other_irq;
 
-	if (intr_status & (EESR_FRC | /* Frame recv*/
-			EESR_RMAF | /* Multi cast address recv*/
-			EESR_RRF  | /* Bit frame recv */
-			EESR_RTLF | /* Long frame recv*/
-			EESR_RTSF | /* short frame recv */
-			EESR_PRE  | /* PHY-LSI recv error */
-			EESR_CERF)){ /* recv frame CRC error */
-		sh_eth_rx(ndev, intr_status);
+	if (intr_status & EESR_RX_CHECK) {
+		if (napi_schedule_prep(&mdp->napi)) {
+			/* Mask Rx interrupts */
+			sh_eth_write(ndev, intr_enable & ~EESR_RX_CHECK,
+				     EESIPR);
+			__napi_schedule(&mdp->napi);
+		} else {
+			dev_warn(&ndev->dev,
+				 "ignoring interrupt, status 0x%08lx, mask 0x%08lx.\n",
+				 intr_status, intr_enable);
+		}
 	}
 
 	/* Tx Check */
 	if (intr_status & cd->tx_check) {
+		/* Clear Tx interrupts */
+		sh_eth_write(ndev, intr_status & cd->tx_check, EESR);
+
 		sh_eth_txfree(ndev);
 		netif_wake_queue(ndev);
 	}
 
-	if (intr_status & cd->eesr_err_check)
+	if (intr_status & cd->eesr_err_check) {
+		/* Clear error interrupts */
+		sh_eth_write(ndev, intr_status & cd->eesr_err_check, EESR);
+
 		sh_eth_error(ndev, intr_status);
+	}
 
 other_irq:
 	spin_unlock(&mdp->lock);
@@ -1682,6 +1541,33 @@ other_irq:
 	return ret;
 }
 
+static int sh_eth_poll(struct napi_struct *napi, int budget)
+{
+	struct sh_eth_private *mdp = container_of(napi, struct sh_eth_private,
+						  napi);
+	struct net_device *ndev = napi->dev;
+	int quota = budget;
+	unsigned long intr_status;
+
+	for (;;) {
+		intr_status = sh_eth_read(ndev, EESR);
+		if (!(intr_status & EESR_RX_CHECK))
+			break;
+		/* Clear Rx interrupts */
+		sh_eth_write(ndev, intr_status & EESR_RX_CHECK, EESR);
+
+		if (sh_eth_rx(ndev, intr_status, &quota))
+			goto out;
+	}
+
+	napi_complete(napi);
+
+	/* Reenable Rx interrupts */
+	sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
+out:
+	return budget - quota;
+}
+
 /* PHY state control function */
 static void sh_eth_adjust_link(struct net_device *ndev)
 {
@@ -1972,14 +1858,7 @@ static int sh_eth_open(struct net_device
 	pm_runtime_get_sync(&mdp->pdev->dev);
 
 	ret = request_irq(ndev->irq, sh_eth_interrupt,
-#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
-	defined(CONFIG_CPU_SUBTYPE_SH7764) || \
-	defined(CONFIG_CPU_SUBTYPE_SH7757)
-				IRQF_SHARED,
-#else
-				0,
-#endif
-				ndev->name, ndev);
+			  mdp->cd->irq_flags, ndev->name, ndev);
 	if (ret) {
 		dev_err(&ndev->dev, "Can not assign IRQ number\n");
 		return ret;
@@ -2000,6 +1879,8 @@ static int sh_eth_open(struct net_device
 	if (ret)
 		goto out_free_irq;
 
+	napi_enable(&mdp->napi);
+
 	return ret;
 
 out_free_irq:
@@ -2095,6 +1976,8 @@ static int sh_eth_close(struct net_devic
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
+	napi_disable(&mdp->napi);
+
 	netif_stop_queue(ndev);
 
 	/* Disable interrupts by clearing the interrupt mask. */
@@ -2165,7 +2048,6 @@ static int sh_eth_do_ioctl(struct net_de
 	return phy_mii_ioctl(phydev, rq, cmd);
 }
 
-#if defined(SH_ETH_HAS_TSU)
 /* For TSU_POSTn. Please refer to the manual about this (strange) bitfields */
 static void *sh_eth_tsu_get_post_reg_offset(struct sh_eth_private *mdp,
 					    int entry)
@@ -2508,7 +2390,6 @@ static int sh_eth_vlan_rx_kill_vid(struc
 
 	return 0;
 }
-#endif /* SH_ETH_HAS_TSU */
 
 /* SuperH's TSU register init function */
 static void sh_eth_tsu_init(struct sh_eth_private *mdp)
@@ -2652,11 +2533,21 @@ static const struct net_device_ops sh_et
 	.ndo_stop		= sh_eth_close,
 	.ndo_start_xmit		= sh_eth_start_xmit,
 	.ndo_get_stats		= sh_eth_get_stats,
-#if defined(SH_ETH_HAS_TSU)
+	.ndo_tx_timeout		= sh_eth_tx_timeout,
+	.ndo_do_ioctl		= sh_eth_do_ioctl,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+};
+
+static const struct net_device_ops sh_eth_netdev_ops_tsu = {
+	.ndo_open		= sh_eth_open,
+	.ndo_stop		= sh_eth_close,
+	.ndo_start_xmit		= sh_eth_start_xmit,
+	.ndo_get_stats		= sh_eth_get_stats,
 	.ndo_set_rx_mode	= sh_eth_set_multicast_list,
 	.ndo_vlan_rx_add_vid	= sh_eth_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= sh_eth_vlan_rx_kill_vid,
-#endif
 	.ndo_tx_timeout		= sh_eth_tx_timeout,
 	.ndo_do_ioctl		= sh_eth_do_ioctl,
 	.ndo_validate_addr	= eth_validate_addr,
@@ -2671,6 +2562,7 @@ static int sh_eth_drv_probe(struct platf
 	struct net_device *ndev = NULL;
 	struct sh_eth_private *mdp = NULL;
 	struct sh_eth_plat_data *pd = pdev->dev.platform_data;
+	const struct platform_device_id *id = platform_get_device_id(pdev);
 
 	/* get base addr */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2729,15 +2621,14 @@ static int sh_eth_drv_probe(struct platf
 	mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);
 
 	/* set cpu data */
-#if defined(SH_ETH_HAS_BOTH_MODULES)
-	mdp->cd = sh_eth_get_cpu_data(mdp);
-#else
-	mdp->cd = &sh_eth_my_cpu_data;
-#endif
+	mdp->cd = (struct sh_eth_cpu_data *)id->driver_data;
 	sh_eth_set_default_cpu_data(mdp->cd);
 
 	/* set function */
-	ndev->netdev_ops = &sh_eth_netdev_ops;
+	if (mdp->cd->tsu)
+		ndev->netdev_ops = &sh_eth_netdev_ops_tsu;
+	else
+		ndev->netdev_ops = &sh_eth_netdev_ops;
 	SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
 	ndev->watchdog_timeo = TX_TIMEOUT;
 
@@ -2776,10 +2667,12 @@ static int sh_eth_drv_probe(struct platf
 		}
 	}
 
+	netif_napi_add(ndev, &mdp->napi, sh_eth_poll, 64);
+
 	/* network device register */
 	ret = register_netdev(ndev);
 	if (ret)
-		goto out_release;
+		goto out_napi_del;
 
 	/* mdio bus init */
 	ret = sh_mdio_init(ndev, pdev->id, pd);
@@ -2797,6 +2690,9 @@ static int sh_eth_drv_probe(struct platf
 out_unregister:
 	unregister_netdev(ndev);
 
+out_napi_del:
+	netif_napi_del(&mdp->napi);
+
 out_release:
 	/* net_dev free */
 	if (ndev)
@@ -2809,16 +2705,18 @@ out:
 static int sh_eth_drv_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct sh_eth_private *mdp = netdev_priv(ndev);
 
 	sh_mdio_release(ndev);
 	unregister_netdev(ndev);
+	netif_napi_del(&mdp->napi);
 	pm_runtime_disable(&pdev->dev);
 	free_netdev(ndev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
 
+#ifdef CONFIG_PM
 static int sh_eth_runtime_nop(struct device *dev)
 {
 	/*
@@ -2832,17 +2730,36 @@ static int sh_eth_runtime_nop(struct dev
 	return 0;
 }
 
-static struct dev_pm_ops sh_eth_dev_pm_ops = {
+static const struct dev_pm_ops sh_eth_dev_pm_ops = {
 	.runtime_suspend = sh_eth_runtime_nop,
 	.runtime_resume = sh_eth_runtime_nop,
 };
+#define SH_ETH_PM_OPS (&sh_eth_dev_pm_ops)
+#else
+#define SH_ETH_PM_OPS NULL
+#endif
+
+static struct platform_device_id sh_eth_id_table[] = {
+	{ "sh7619-ether", (kernel_ulong_t)&sh7619_data },
+	{ "sh771x-ether", (kernel_ulong_t)&sh771x_data },
+	{ "sh7724-ether", (kernel_ulong_t)&sh7724_data },
+	{ "sh7734-gether", (kernel_ulong_t)&sh7734_data },
+	{ "sh7757-ether", (kernel_ulong_t)&sh7757_data },
+	{ "sh7757-gether", (kernel_ulong_t)&sh7757_data_giga },
+	{ "sh7763-gether", (kernel_ulong_t)&sh7763_data },
+	{ "r8a7740-gether", (kernel_ulong_t)&r8a7740_data },
+	{ "r8a777x-ether", (kernel_ulong_t)&r8a777x_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, sh_eth_id_table);
 
 static struct platform_driver sh_eth_driver = {
 	.probe = sh_eth_drv_probe,
 	.remove = sh_eth_drv_remove,
+	.id_table = sh_eth_id_table,
 	.driver = {
 		   .name = CARDNAME,
-		   .pm = &sh_eth_dev_pm_ops,
+		   .pm = SH_ETH_PM_OPS,
 	},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/renesas/sh_eth.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/renesas/sh_eth.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/renesas/sh_eth.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/renesas/sh_eth.h	2013-08-25 20:43:22.000000000 -0400
@@ -166,19 +166,16 @@ enum {
 /*
  * Register's bits
  */
-#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763) ||\
-    defined(CONFIG_ARCH_R8A7740)
-/* EDSR */
+/* EDSR : sh7734, sh7757, sh7763, and r8a7740 only */
 enum EDSR_BIT {
 	EDSR_ENT = 0x01, EDSR_ENR = 0x02,
 };
 #define EDSR_ENALL (EDSR_ENT|EDSR_ENR)
 
-/* GECMR */
+/* GECMR : sh7734, sh7763 and r8a7740 only */
 enum GECMR_BIT {
 	GECMR_10 = 0x0, GECMR_100 = 0x04, GECMR_1000 = 0x01,
 };
-#endif
 
 /* EDMR */
 enum DMAC_M_BIT {
@@ -251,13 +248,19 @@ enum EESR_BIT {
 	EESR_CERF	= 0x00000001,
 };
 
+#define EESR_RX_CHECK		(EESR_FRC  | /* Frame recv */		\
+				 EESR_RMAF | /* Multicast address recv */ \
+				 EESR_RRF  | /* Bit frame recv */	\
+				 EESR_RTLF | /* Long frame recv */	\
+				 EESR_RTSF | /* Short frame recv */	\
+				 EESR_PRE  | /* PHY-LSI recv error */	\
+				 EESR_CERF)  /* Recv frame CRC error */
+
 #define DEFAULT_TX_CHECK	(EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \
 				 EESR_RTO)
 #define DEFAULT_EESR_ERR_CHECK	(EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | \
 				 EESR_RDE | EESR_RFRMER | EESR_ADE | \
 				 EESR_TFE | EESR_TDE | EESR_ECI)
-#define DEFAULT_TX_ERROR_CHECK	(EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \
-				 EESR_TFE)
 
 /* EESIPR */
 enum DMAC_IM_BIT {
@@ -299,11 +302,11 @@ enum FCFTR_BIT {
 #define DEFAULT_FIFO_F_D_RFF	(FCFTR_RFF2 | FCFTR_RFF1 | FCFTR_RFF0)
 #define DEFAULT_FIFO_F_D_RFD	(FCFTR_RFD2 | FCFTR_RFD1 | FCFTR_RFD0)
 
-/* Transfer descriptor bit */
+/* Transmit descriptor bit */
 enum TD_STS_BIT {
-	TD_TACT = 0x80000000,
-	TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000,
-	TD_TFP0 = 0x10000000,
+	TD_TACT = 0x80000000, TD_TDLE = 0x40000000,
+	TD_TFP1 = 0x20000000, TD_TFP0 = 0x10000000,
+	TD_TFE  = 0x08000000, TD_TWBI = 0x04000000,
 };
 #define TDF1ST	TD_TFP1
 #define TDFEND	TD_TFP0
@@ -463,9 +466,9 @@ struct sh_eth_cpu_data {
 	/* interrupt checking mask */
 	unsigned long tx_check;
 	unsigned long eesr_err_check;
-	unsigned long tx_error_check;
 
 	/* hardware features */
+	unsigned long irq_flags;	/* IRQ configuration flags */
 	unsigned no_psr:1;		/* EtherC DO NOT have PSR */
 	unsigned apr:1;			/* EtherC have APR */
 	unsigned mpr:1;			/* EtherC have MPR */
@@ -478,6 +481,7 @@ struct sh_eth_cpu_data {
 	unsigned no_ade:1;	/* E-DMAC DO NOT have ADE bit in EESR */
 	unsigned hw_crc:1;	/* E-DMAC have CSMR */
 	unsigned select_mii:1;	/* EtherC have RMII_MII (MII select register) */
+	unsigned shift_rd0:1;	/* shift Rx descriptor word 0 right by 16 */
 };
 
 struct sh_eth_private {
@@ -499,6 +503,7 @@ struct sh_eth_private {
 	u32 cur_tx, dirty_tx;
 	u32 rx_buf_sz;		/* Based on MTU+slack. */
 	int edmac_endian;
+	struct napi_struct napi;
 	/* MII transceiver section. */
 	u32 phy_id;					/* PHY ID */
 	struct mii_bus *mii_bus;	/* MDIO bus control */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/s6gmac.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/s6gmac.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/s6gmac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/s6gmac.c	2013-08-25 20:43:22.000000000 -0400
@@ -1040,7 +1040,6 @@ static int s6gmac_remove(struct platform
 		unregister_netdev(dev);
 		free_irq(dev->irq, dev);
 		free_netdev(dev);
-		platform_set_drvdata(pdev, NULL);
 	}
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/seeq/sgiseeq.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/seeq/sgiseeq.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/seeq/sgiseeq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/seeq/sgiseeq.c	2013-08-25 20:43:22.000000000 -0400
@@ -818,7 +818,6 @@ static int __exit sgiseeq_remove(struct
 	dma_free_noncoherent(&pdev->dev, sizeof(*sp->srings), sp->srings,
 			     sp->srings_dma);
 	free_netdev(dev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/efx.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/efx.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/efx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/efx.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,8 +21,8 @@
 #include <linux/ethtool.h>
 #include <linux/topology.h>
 #include <linux/gfp.h>
-#include <linux/cpu_rmap.h>
 #include <linux/aer.h>
+#include <linux/interrupt.h>
 #include "net_driver.h"
 #include "efx.h"
 #include "nic.h"
@@ -1283,29 +1283,6 @@ static unsigned int efx_wanted_paralleli
 	return count;
 }
 
-static int
-efx_init_rx_cpu_rmap(struct efx_nic *efx, struct msix_entry *xentries)
-{
-#ifdef CONFIG_RFS_ACCEL
-	unsigned int i;
-	int rc;
-
-	efx->net_dev->rx_cpu_rmap = alloc_irq_cpu_rmap(efx->n_rx_channels);
-	if (!efx->net_dev->rx_cpu_rmap)
-		return -ENOMEM;
-	for (i = 0; i < efx->n_rx_channels; i++) {
-		rc = irq_cpu_rmap_add(efx->net_dev->rx_cpu_rmap,
-				      xentries[i].vector);
-		if (rc) {
-			free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap);
-			efx->net_dev->rx_cpu_rmap = NULL;
-			return rc;
-		}
-	}
-#endif
-	return 0;
-}
-
 /* Probe the number and type of interrupts we are able to obtain, and
  * the resulting numbers of channels and RX queues.
  */
@@ -1359,11 +1336,6 @@ static int efx_probe_interrupts(struct e
 				efx->n_tx_channels = n_channels;
 				efx->n_rx_channels = n_channels;
 			}
-			rc = efx_init_rx_cpu_rmap(efx, xentries);
-			if (rc) {
-				pci_disable_msix(efx->pci_dev);
-				return rc;
-			}
 			for (i = 0; i < efx->n_channels; i++)
 				efx_get_channel(efx, i)->irq =
 					xentries[i].vector;
@@ -1427,6 +1399,10 @@ static void efx_start_interrupts(struct
 
 	BUG_ON(efx->state == STATE_DISABLED);
 
+	if (efx->eeh_disabled_legacy_irq) {
+		enable_irq(efx->legacy_irq);
+		efx->eeh_disabled_legacy_irq = false;
+	}
 	if (efx->legacy_irq)
 		efx->legacy_irq_enabled = true;
 	efx_nic_enable_interrupts(efx);
@@ -2120,7 +2096,7 @@ static void efx_update_name(struct efx_n
 static int efx_netdev_event(struct notifier_block *this,
 			    unsigned long event, void *ptr)
 {
-	struct net_device *net_dev = ptr;
+	struct net_device *net_dev = netdev_notifier_info_to_dev(ptr);
 
 	if (net_dev->netdev_ops == &efx_netdev_ops &&
 	    event == NETDEV_CHANGENAME)
@@ -2365,7 +2341,7 @@ out:
  * Returns 0 if the recovery mechanisms are unsuccessful.
  * Returns a non-zero value otherwise.
  */
-static int efx_try_recovery(struct efx_nic *efx)
+int efx_try_recovery(struct efx_nic *efx)
 {
 #ifdef CONFIG_EEH
 	/* A PCI error can occur and not be seen by EEH because nothing
@@ -2603,10 +2579,6 @@ static void efx_pci_remove_main(struct e
 	BUG_ON(efx->state == STATE_READY);
 	cancel_work_sync(&efx->reset_work);
 
-#ifdef CONFIG_RFS_ACCEL
-	free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap);
-	efx->net_dev->rx_cpu_rmap = NULL;
-#endif
 	efx_stop_interrupts(efx, false);
 	efx_nic_fini_interrupt(efx);
 	efx_fini_port(efx);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/efx.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/efx.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/efx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/efx.h	2013-08-25 20:43:22.000000000 -0400
@@ -124,6 +124,7 @@ extern const struct ethtool_ops efx_etht
 extern int efx_reset(struct efx_nic *efx, enum reset_type method);
 extern void efx_reset_down(struct efx_nic *efx, enum reset_type method);
 extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok);
+extern int efx_try_recovery(struct efx_nic *efx);
 
 /* Global */
 extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/ethtool.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/ethtool.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/ethtool.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/ethtool.c	2013-08-25 20:43:22.000000000 -0400
@@ -1114,6 +1114,20 @@ static int efx_ethtool_set_rxfh_indir(st
 	return 0;
 }
 
+int efx_ethtool_get_ts_info(struct net_device *net_dev,
+			    struct ethtool_ts_info *ts_info)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+
+	/* Software capabilities */
+	ts_info->so_timestamping = (SOF_TIMESTAMPING_RX_SOFTWARE |
+				    SOF_TIMESTAMPING_SOFTWARE);
+	ts_info->phc_index = -1;
+
+	efx_ptp_get_ts_info(efx, ts_info);
+	return 0;
+}
+
 static int efx_ethtool_get_module_eeprom(struct net_device *net_dev,
 					 struct ethtool_eeprom *ee,
 					 u8 *data)
@@ -1176,7 +1190,7 @@ const struct ethtool_ops efx_ethtool_ops
 	.get_rxfh_indir_size	= efx_ethtool_get_rxfh_indir_size,
 	.get_rxfh_indir		= efx_ethtool_get_rxfh_indir,
 	.set_rxfh_indir		= efx_ethtool_set_rxfh_indir,
-	.get_ts_info		= efx_ptp_get_ts_info,
+	.get_ts_info		= efx_ethtool_get_ts_info,
 	.get_module_info	= efx_ethtool_get_module_info,
 	.get_module_eeprom	= efx_ethtool_get_module_eeprom,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/filter.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/filter.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/filter.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/filter.c	2013-08-25 20:43:22.000000000 -0400
@@ -675,7 +675,7 @@ s32 efx_filter_insert_filter(struct efx_
 		BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0);
 		BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF !=
 			     EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF);
-		rep_index = spec->type - EFX_FILTER_INDEX_UC_DEF;
+		rep_index = spec->type - EFX_FILTER_UC_DEF;
 		ins_index = rep_index;
 
 		spin_lock_bh(&state->lock);
@@ -1185,8 +1185,21 @@ int efx_filter_rfs(struct net_device *ne
 
 	nhoff = skb_network_offset(skb);
 
-	if (skb->protocol != htons(ETH_P_IP))
+	if (skb->protocol == htons(ETH_P_8021Q)) {
+		EFX_BUG_ON_PARANOID(skb_headlen(skb) <
+				    nhoff + sizeof(struct vlan_hdr));
+		if (((const struct vlan_hdr *)skb->data + nhoff)->
+		    h_vlan_encapsulated_proto != htons(ETH_P_IP))
+			return -EPROTONOSUPPORT;
+
+		/* This is IP over 802.1q VLAN.  We can't filter on the
+		 * IP 5-tuple and the vlan together, so just strip the
+		 * vlan header and filter on the IP part.
+		 */
+		nhoff += sizeof(struct vlan_hdr);
+	} else if (skb->protocol != htons(ETH_P_IP)) {
 		return -EPROTONOSUPPORT;
+	}
 
 	/* RFS must validate the IP header length before calling us */
 	EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + sizeof(*ip));
@@ -1196,7 +1209,9 @@ int efx_filter_rfs(struct net_device *ne
 	EFX_BUG_ON_PARANOID(skb_headlen(skb) < nhoff + 4 * ip->ihl + 4);
 	ports = (const __be16 *)(skb->data + nhoff + 4 * ip->ihl);
 
-	efx_filter_init_rx(&spec, EFX_FILTER_PRI_HINT, 0, rxq_index);
+	efx_filter_init_rx(&spec, EFX_FILTER_PRI_HINT,
+			   efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0,
+			   rxq_index);
 	rc = efx_filter_set_ipv4_full(&spec, ip->protocol,
 				      ip->daddr, ports[1], ip->saddr, ports[0]);
 	if (rc)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/net_driver.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/net_driver.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/net_driver.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/net_driver.h	2013-08-25 20:43:22.000000000 -0400
@@ -243,6 +243,7 @@ struct efx_rx_buffer {
 #define EFX_RX_BUF_LAST_IN_PAGE	0x0001
 #define EFX_RX_PKT_CSUMMED	0x0002
 #define EFX_RX_PKT_DISCARD	0x0004
+#define EFX_RX_PKT_TCP		0x0040
 
 /**
  * struct efx_rx_page_state - Page-based rx buffer state
@@ -784,9 +785,11 @@ struct efx_nic {
 
 	char name[IFNAMSIZ];
 	struct pci_dev *pci_dev;
+	unsigned int port_num;
 	const struct efx_nic_type *type;
 	int legacy_irq;
 	bool legacy_irq_enabled;
+	bool eeh_disabled_legacy_irq;
 	struct workqueue_struct *workqueue;
 	char workqueue_name[16];
 	struct work_struct reset_work;
@@ -916,7 +919,7 @@ static inline int efx_dev_registered(str
 
 static inline unsigned int efx_port_num(struct efx_nic *efx)
 {
-	return efx->net_dev->dev_id;
+	return efx->port_num;
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/nic.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/nic.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/nic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/nic.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/seq_file.h>
+#include <linux/cpu_rmap.h>
 #include "net_driver.h"
 #include "bitfield.h"
 #include "efx.h"
@@ -1080,12 +1081,21 @@ efx_handle_rx_event(struct efx_channel *
 	rx_ev_hdr_type = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE);
 
 	if (likely(rx_ev_pkt_ok)) {
-		/* If packet is marked as OK and packet type is TCP/IP or
-		 * UDP/IP, then we can rely on the hardware checksum.
+		/* If packet is marked as OK then we can rely on the
+		 * hardware checksum and classification.
 		 */
-		flags = (rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
-			 rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP) ?
-			EFX_RX_PKT_CSUMMED : 0;
+		flags = 0;
+		switch (rx_ev_hdr_type) {
+		case FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP:
+			flags |= EFX_RX_PKT_TCP;
+			/* fall through */
+		case FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP:
+			flags |= EFX_RX_PKT_CSUMMED;
+			/* fall through */
+		case FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_OTHER:
+		case FSE_AZ_RX_EV_HDR_TYPE_OTHER:
+			break;
+		}
 	} else {
 		flags = efx_handle_rx_not_ok(rx_queue, event);
 	}
@@ -1579,6 +1589,16 @@ static irqreturn_t efx_legacy_interrupt(
 	efx_readd(efx, &reg, FR_BZ_INT_ISR0);
 	queues = EFX_EXTRACT_DWORD(reg, 0, 31);
 
+	/* Legacy interrupts are disabled too late by the EEH kernel
+	 * code. Disable them earlier.
+	 * If an EEH error occurred, the read will have returned all ones.
+	 */
+	if (EFX_DWORD_IS_ALL_ONES(reg) && efx_try_recovery(efx) &&
+	    !efx->eeh_disabled_legacy_irq) {
+		disable_irq_nosync(efx->legacy_irq);
+		efx->eeh_disabled_legacy_irq = true;
+	}
+
 	/* Handle non-event-queue sources */
 	if (queues & (1U << efx->irq_level)) {
 		syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
@@ -1687,6 +1707,7 @@ void efx_nic_push_rx_indir_table(struct
 int efx_nic_init_interrupt(struct efx_nic *efx)
 {
 	struct efx_channel *channel;
+	unsigned int n_irqs;
 	int rc;
 
 	if (!EFX_INT_MODE_USE_MSI(efx)) {
@@ -1707,7 +1728,19 @@ int efx_nic_init_interrupt(struct efx_ni
 		return 0;
 	}
 
+#ifdef CONFIG_RFS_ACCEL
+	if (efx->interrupt_mode == EFX_INT_MODE_MSIX) {
+		efx->net_dev->rx_cpu_rmap =
+			alloc_irq_cpu_rmap(efx->n_rx_channels);
+		if (!efx->net_dev->rx_cpu_rmap) {
+			rc = -ENOMEM;
+			goto fail1;
+		}
+	}
+#endif
+
 	/* Hook MSI or MSI-X interrupt */
+	n_irqs = 0;
 	efx_for_each_channel(channel, efx) {
 		rc = request_irq(channel->irq, efx_msi_interrupt,
 				 IRQF_PROBE_SHARED, /* Not shared */
@@ -1718,13 +1751,31 @@ int efx_nic_init_interrupt(struct efx_ni
 				  "failed to hook IRQ %d\n", channel->irq);
 			goto fail2;
 		}
+		++n_irqs;
+
+#ifdef CONFIG_RFS_ACCEL
+		if (efx->interrupt_mode == EFX_INT_MODE_MSIX &&
+		    channel->channel < efx->n_rx_channels) {
+			rc = irq_cpu_rmap_add(efx->net_dev->rx_cpu_rmap,
+					      channel->irq);
+			if (rc)
+				goto fail2;
+		}
+#endif
 	}
 
 	return 0;
 
  fail2:
-	efx_for_each_channel(channel, efx)
+#ifdef CONFIG_RFS_ACCEL
+	free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap);
+	efx->net_dev->rx_cpu_rmap = NULL;
+#endif
+	efx_for_each_channel(channel, efx) {
+		if (n_irqs-- == 0)
+			break;
 		free_irq(channel->irq, &efx->channel[channel->channel]);
+	}
  fail1:
 	return rc;
 }
@@ -1734,11 +1785,14 @@ void efx_nic_fini_interrupt(struct efx_n
 	struct efx_channel *channel;
 	efx_oword_t reg;
 
+#ifdef CONFIG_RFS_ACCEL
+	free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap);
+	efx->net_dev->rx_cpu_rmap = NULL;
+#endif
+
 	/* Disable MSI/MSI-X interrupts */
-	efx_for_each_channel(channel, efx) {
-		if (channel->irq)
-			free_irq(channel->irq, &efx->channel[channel->channel]);
-	}
+	efx_for_each_channel(channel, efx)
+		free_irq(channel->irq, &efx->channel[channel->channel]);
 
 	/* ACK legacy interrupt */
 	if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/nic.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/nic.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/nic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/nic.h	2013-08-25 20:43:22.000000000 -0400
@@ -254,8 +254,8 @@ extern int efx_sriov_set_vf_spoofchk(str
 struct ethtool_ts_info;
 extern void efx_ptp_probe(struct efx_nic *efx);
 extern int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd);
-extern int efx_ptp_get_ts_info(struct net_device *net_dev,
-			       struct ethtool_ts_info *ts_info);
+extern void efx_ptp_get_ts_info(struct efx_nic *efx,
+				struct ethtool_ts_info *ts_info);
 extern bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
 extern int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb);
 extern void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/ptp.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/ptp.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/ptp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/ptp.c	2013-08-25 20:43:22.000000000 -0400
@@ -1203,18 +1203,16 @@ static int efx_ptp_ts_init(struct efx_ni
 	return 0;
 }
 
-int
-efx_ptp_get_ts_info(struct net_device *net_dev, struct ethtool_ts_info *ts_info)
+void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info)
 {
-	struct efx_nic *efx = netdev_priv(net_dev);
 	struct efx_ptp_data *ptp = efx->ptp_data;
 
 	if (!ptp)
-		return -EOPNOTSUPP;
+		return;
 
-	ts_info->so_timestamping = (SOF_TIMESTAMPING_TX_HARDWARE |
-				    SOF_TIMESTAMPING_RX_HARDWARE |
-				    SOF_TIMESTAMPING_RAW_HARDWARE);
+	ts_info->so_timestamping |= (SOF_TIMESTAMPING_TX_HARDWARE |
+				     SOF_TIMESTAMPING_RX_HARDWARE |
+				     SOF_TIMESTAMPING_RAW_HARDWARE);
 	ts_info->phc_index = ptp_clock_index(ptp->phc_clock);
 	ts_info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON;
 	ts_info->rx_filters = (1 << HWTSTAMP_FILTER_NONE |
@@ -1224,7 +1222,6 @@ efx_ptp_get_ts_info(struct net_device *n
 			       1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT |
 			       1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC |
 			       1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
-	return 0;
 }
 
 int efx_ptp_ioctl(struct efx_nic *efx, struct ifreq *ifr, int cmd)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/rx.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/rx.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/rx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/rx.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,7 @@
 #define EFX_RECYCLE_RING_SIZE_NOIOMMU (2 * EFX_RX_PREFERRED_BATCH)
 
 /* Size of buffer allocated for skb header area. */
-#define EFX_SKB_HEADERS  64u
+#define EFX_SKB_HEADERS  128u
 
 /* This is the percentage fill level below which new RX descriptors
  * will be added to the RX descriptor ring.
@@ -282,9 +282,9 @@ static void efx_fini_rx_buffer(struct ef
 }
 
 /* Recycle the pages that are used by buffers that have just been received. */
-static void efx_recycle_rx_buffers(struct efx_channel *channel,
-				   struct efx_rx_buffer *rx_buf,
-				   unsigned int n_frags)
+static void efx_recycle_rx_pages(struct efx_channel *channel,
+				 struct efx_rx_buffer *rx_buf,
+				 unsigned int n_frags)
 {
 	struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
 
@@ -294,6 +294,20 @@ static void efx_recycle_rx_buffers(struc
 	} while (--n_frags);
 }
 
+static void efx_discard_rx_packet(struct efx_channel *channel,
+				  struct efx_rx_buffer *rx_buf,
+				  unsigned int n_frags)
+{
+	struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
+
+	efx_recycle_rx_pages(channel, rx_buf, n_frags);
+
+	do {
+		efx_free_rx_buffer(rx_buf);
+		rx_buf = efx_rx_buf_next(rx_queue, rx_buf);
+	} while (--n_frags);
+}
+
 /**
  * efx_fast_push_rx_descriptors - push new RX descriptors quickly
  * @rx_queue:		RX descriptor queue
@@ -533,8 +547,7 @@ void efx_rx_packet(struct efx_rx_queue *
 	 */
 	if (unlikely(rx_buf->flags & EFX_RX_PKT_DISCARD)) {
 		efx_rx_flush_packet(channel);
-		put_page(rx_buf->page);
-		efx_recycle_rx_buffers(channel, rx_buf, n_frags);
+		efx_discard_rx_packet(channel, rx_buf, n_frags);
 		return;
 	}
 
@@ -570,9 +583,9 @@ void efx_rx_packet(struct efx_rx_queue *
 		efx_sync_rx_buffer(efx, rx_buf, rx_buf->len);
 	}
 
-	/* All fragments have been DMA-synced, so recycle buffers and pages. */
+	/* All fragments have been DMA-synced, so recycle pages. */
 	rx_buf = efx_rx_buffer(rx_queue, index);
-	efx_recycle_rx_buffers(channel, rx_buf, n_frags);
+	efx_recycle_rx_pages(channel, rx_buf, n_frags);
 
 	/* Pipeline receives so that we give time for packet headers to be
 	 * prefetched into cache.
@@ -598,6 +611,8 @@ static void efx_rx_deliver(struct efx_ch
 
 	/* Set the SKB flags */
 	skb_checksum_none_assert(skb);
+	if (likely(rx_buf->flags & EFX_RX_PKT_CSUMMED))
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 	if (channel->type->receive_skb)
 		if (channel->type->receive_skb(channel, skb))
@@ -627,7 +642,7 @@ void __efx_rx_packet(struct efx_channel
 	if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
 		rx_buf->flags &= ~EFX_RX_PKT_CSUMMED;
 
-	if (!channel->type->receive_skb)
+	if ((rx_buf->flags & EFX_RX_PKT_TCP) && !channel->type->receive_skb)
 		efx_rx_packet_gro(channel, rx_buf, channel->rx_pkt_n_frags, eh);
 	else
 		efx_rx_deliver(channel, eh, rx_buf, channel->rx_pkt_n_frags);
@@ -675,7 +690,7 @@ static void efx_init_rx_recycle_ring(str
 #ifdef CONFIG_PPC64
 	bufs_in_recycle_ring = EFX_RECYCLE_RING_SIZE_IOMMU;
 #else
-	if (efx->pci_dev->dev.iommu_group)
+	if (iommu_present(&pci_bus_type))
 		bufs_in_recycle_ring = EFX_RECYCLE_RING_SIZE_IOMMU;
 	else
 		bufs_in_recycle_ring = EFX_RECYCLE_RING_SIZE_NOIOMMU;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sfc/siena.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/siena.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sfc/siena.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sfc/siena.c	2013-08-25 20:43:22.000000000 -0400
@@ -304,7 +304,7 @@ static int siena_probe_nic(struct efx_ni
 	}
 
 	efx_reado(efx, &reg, FR_AZ_CS_DEBUG);
-	efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
+	efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
 
 	efx_mcdi_init(efx);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sgi/ioc3-eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sgi/ioc3-eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sgi/ioc3-eth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sgi/ioc3-eth.c	2013-08-25 20:43:22.000000000 -0400
@@ -1398,16 +1398,6 @@ static struct pci_driver ioc3_driver = {
 	.remove		= ioc3_remove_one,
 };
 
-static int __init ioc3_init_module(void)
-{
-	return pci_register_driver(&ioc3_driver);
-}
-
-static void __exit ioc3_cleanup_module(void)
-{
-	pci_unregister_driver(&ioc3_driver);
-}
-
 static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	unsigned long data;
@@ -1677,9 +1667,7 @@ static void ioc3_set_multicast_list(stru
 	netif_wake_queue(dev);			/* Let us get going again. */
 }
 
+module_pci_driver(ioc3_driver);
 MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
 MODULE_DESCRIPTION("SGI IOC3 Ethernet driver");
 MODULE_LICENSE("GPL");
-
-module_init(ioc3_init_module);
-module_exit(ioc3_cleanup_module);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sgi/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sgi/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/sgi/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sgi/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@ config SGI_IOC3_ETH
 	bool "SGI IOC3 Ethernet"
 	depends on PCI && SGI_IP27
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  If you have a network (Ethernet) card of this type, say Y and read
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sgi/meth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sgi/meth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sgi/meth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sgi/meth.c	2013-08-25 20:43:22.000000000 -0400
@@ -863,7 +863,6 @@ static int __exit meth_remove(struct pla
 
 	unregister_netdev(dev);
 	free_netdev(dev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/silan/sc92031.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/silan/sc92031.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/silan/sc92031.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/silan/sc92031.c	2013-08-25 20:43:22.000000000 -0400
@@ -1578,19 +1578,7 @@ static struct pci_driver sc92031_pci_dri
 	.resume		= sc92031_resume,
 };
 
-static int __init sc92031_init(void)
-{
-	return pci_register_driver(&sc92031_pci_driver);
-}
-
-static void __exit sc92031_exit(void)
-{
-	pci_unregister_driver(&sc92031_pci_driver);
-}
-
-module_init(sc92031_init);
-module_exit(sc92031_exit);
-
+module_pci_driver(sc92031_pci_driver);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Cesar Eduardo Barros <cesarb@cesarb.net>");
 MODULE_DESCRIPTION("Silan SC92031 PCI Fast Ethernet Adapter driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sis/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sis/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/sis/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sis/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@ config SIS900
 	tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This is a driver for the Fast Ethernet PCI network cards based on
@@ -39,7 +38,6 @@ config SIS190
 	tristate "SiS190/SiS191 gigabit ethernet support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sis/sis190.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sis/sis190.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sis/sis190.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sis/sis190.c	2013-08-25 20:43:22.000000000 -0400
@@ -1934,15 +1934,4 @@ static struct pci_driver sis190_pci_driv
 	.remove		= sis190_remove_one,
 };
 
-static int __init sis190_init_module(void)
-{
-	return pci_register_driver(&sis190_pci_driver);
-}
-
-static void __exit sis190_cleanup_module(void)
-{
-	pci_unregister_driver(&sis190_pci_driver);
-}
-
-module_init(sis190_init_module);
-module_exit(sis190_cleanup_module);
+module_pci_driver(sis190_pci_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sis/sis900.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sis/sis900.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sis/sis900.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sis/sis900.c	2013-08-25 20:43:22.000000000 -0400
@@ -1318,7 +1318,7 @@ static void sis900_timer(unsigned long d
 		if (duplex){
 			sis900_set_mode(sis_priv, speed, duplex);
 			sis630_set_eq(net_dev, sis_priv->chipset_rev);
-			netif_start_queue(net_dev);
+			netif_carrier_on(net_dev);
 		}
 
 		sis_priv->timer.expires = jiffies + HZ;
@@ -1336,10 +1336,8 @@ static void sis900_timer(unsigned long d
 		status = sis900_default_phy(net_dev);
 		mii_phy = sis_priv->mii;
 
-		if (status & MII_STAT_LINK){
+		if (status & MII_STAT_LINK)
 			sis900_check_mode(net_dev, mii_phy);
-			netif_carrier_on(net_dev);
-		}
 	} else {
 	/* Link ON -> OFF */
                 if (!(status & MII_STAT_LINK)){
@@ -1612,12 +1610,6 @@ sis900_start_xmit(struct sk_buff *skb, s
 	unsigned int  index_cur_tx, index_dirty_tx;
 	unsigned int  count_dirty_tx;
 
-	/* Don't transmit data before the complete of auto-negotiation */
-	if(!sis_priv->autong_complete){
-		netif_stop_queue(net_dev);
-		return NETDEV_TX_BUSY;
-	}
-
 	spin_lock_irqsave(&sis_priv->lock, flags);
 
 	/* Calculate the next Tx descriptor entry. */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/smsc/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/smsc/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/smsc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/smsc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,6 @@ config SMC9194
 config SMC91X
 	tristate "SMC 91C9x/91C1xxx support"
 	select CRC32
-	select NET_CORE
 	select MII
 	depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \
 		    MN10300 || COLDFIRE || ARM64)
@@ -57,7 +56,6 @@ config PCMCIA_SMC91C92
 	tristate "SMC 91Cxx PCMCIA support"
 	depends on PCMCIA
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  Say Y here if you intend to attach an SMC 91Cxx compatible PCMCIA
@@ -70,7 +68,6 @@ config EPIC100
 	tristate "SMC EtherPower II"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC,
@@ -81,7 +78,6 @@ config EPIC100
 config SMC911X
 	tristate "SMSC LAN911[5678] support"
 	select CRC32
-	select NET_CORE
 	select MII
 	depends on (ARM || SUPERH || MN10300)
 	---help---
@@ -97,9 +93,8 @@ config SMC911X
 
 config SMSC911X
 	tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
-	depends on (ARM || SUPERH || BLACKFIN || MIPS || MN10300)
+	depends on HAS_IOMEM
 	select CRC32
-	select NET_CORE
 	select MII
 	select PHYLIB
 	---help---
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/smsc/smc911x.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/smsc/smc911x.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/smsc/smc911x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/smsc/smc911x.c	2013-08-25 20:43:22.000000000 -0400
@@ -2087,7 +2087,6 @@ static int smc911x_drv_probe(struct plat
 	ndev->base_addr = res->start;
 	ret = smc911x_probe(ndev);
 	if (ret != 0) {
-		platform_set_drvdata(pdev, NULL);
 		iounmap(addr);
 release_both:
 		free_netdev(ndev);
@@ -2113,7 +2112,6 @@ static int smc911x_drv_remove(struct pla
 	struct resource *res;
 
 	DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
-	platform_set_drvdata(pdev, NULL);
 
 	unregister_netdev(ndev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/smsc/smc91x.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/smsc/smc91x.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/smsc/smc91x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/smsc/smc91x.c	2013-08-25 20:43:22.000000000 -0400
@@ -2299,7 +2299,6 @@ static int smc_drv_probe(struct platform
 	return 0;
 
  out_iounmap:
-	platform_set_drvdata(pdev, NULL);
 	iounmap(addr);
  out_release_attrib:
 	smc_release_attrib(pdev, ndev);
@@ -2319,8 +2318,6 @@ static int smc_drv_remove(struct platfor
 	struct smc_local *lp = netdev_priv(ndev);
 	struct resource *res;
 
-	platform_set_drvdata(pdev, NULL);
-
 	unregister_netdev(ndev);
 
 	free_irq(ndev->irq, ndev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/smsc/smsc911x.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/smsc/smsc911x.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/smsc/smsc911x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/smsc/smsc911x.c	2013-08-25 20:43:22.000000000 -0400
@@ -2284,7 +2284,6 @@ static int smsc911x_drv_remove(struct pl
 	mdiobus_unregister(pdata->mii_bus);
 	mdiobus_free(pdata->mii_bus);
 
-	platform_set_drvdata(pdev, NULL);
 	unregister_netdev(dev);
 	free_irq(dev->irq, dev);
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
@@ -2539,7 +2538,6 @@ out_disable_resources:
 out_enable_resources_fail:
 	smsc911x_free_resources(pdev);
 out_request_resources_fail:
-	platform_set_drvdata(pdev, NULL);
 	iounmap(pdata->ioaddr);
 	free_netdev(dev);
 out_release_io_1:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/common.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/common.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,16 +38,6 @@
 #include "descs.h"
 #include "mmc.h"
 
-#undef CHIP_DEBUG_PRINT
-/* Turn-on extra printk debug for MAC core, dma and descriptors */
-/* #define CHIP_DEBUG_PRINT */
-
-#ifdef CHIP_DEBUG_PRINT
-#define CHIP_DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define CHIP_DBG(fmt, args...)  do { } while (0)
-#endif
-
 /* Synopsys Core versions */
 #define	DWMAC_CORE_3_40	0x34
 #define	DWMAC_CORE_3_50	0x35
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -91,8 +91,8 @@ static void dwmac1000_set_filter(struct
 	unsigned int value = 0;
 	unsigned int perfect_addr_number;
 
-	CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
-		 __func__, netdev_mc_count(dev), netdev_uc_count(dev));
+	pr_debug("%s: # mcasts %d, # unicast %d\n", __func__,
+		 netdev_mc_count(dev), netdev_uc_count(dev));
 
 	if (dev->flags & IFF_PROMISC)
 		value = GMAC_FRAME_FILTER_PR;
@@ -152,7 +152,7 @@ static void dwmac1000_set_filter(struct
 #endif
 	writel(value, ioaddr + GMAC_FRAME_FILTER);
 
-	CHIP_DBG(KERN_INFO "\tFilter: 0x%08x\n\tHash: HI 0x%08x, LO 0x%08x\n",
+	pr_debug("\tFilter: 0x%08x\n\tHash: HI 0x%08x, LO 0x%08x\n",
 		 readl(ioaddr + GMAC_FRAME_FILTER),
 		 readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
 }
@@ -162,18 +162,18 @@ static void dwmac1000_flow_ctrl(void __i
 {
 	unsigned int flow = 0;
 
-	CHIP_DBG(KERN_DEBUG "GMAC Flow-Control:\n");
+	pr_debug("GMAC Flow-Control:\n");
 	if (fc & FLOW_RX) {
-		CHIP_DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
+		pr_debug("\tReceive Flow-Control ON\n");
 		flow |= GMAC_FLOW_CTRL_RFE;
 	}
 	if (fc & FLOW_TX) {
-		CHIP_DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
+		pr_debug("\tTransmit Flow-Control ON\n");
 		flow |= GMAC_FLOW_CTRL_TFE;
 	}
 
 	if (duplex) {
-		CHIP_DBG(KERN_DEBUG "\tduplex mode: PAUSE %d\n", pause_time);
+		pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
 		flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
 	}
 
@@ -185,11 +185,11 @@ static void dwmac1000_pmt(void __iomem *
 	unsigned int pmt = 0;
 
 	if (mode & WAKE_MAGIC) {
-		CHIP_DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
+		pr_debug("GMAC: WOL Magic frame\n");
 		pmt |= power_down | magic_pkt_en;
 	}
 	if (mode & WAKE_UCAST) {
-		CHIP_DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
+		pr_debug("GMAC: WOL on global unicast\n");
 		pmt |= global_unicast;
 	}
 
@@ -203,23 +203,13 @@ static int dwmac1000_irq_status(void __i
 	int ret = 0;
 
 	/* Not used events (e.g. MMC interrupts) are not handled. */
-	if ((intr_status & mmc_tx_irq)) {
-		CHIP_DBG(KERN_INFO "GMAC: MMC tx interrupt: 0x%08x\n",
-			 readl(ioaddr + GMAC_MMC_TX_INTR));
+	if ((intr_status & mmc_tx_irq))
 		x->mmc_tx_irq_n++;
-	}
-	if (unlikely(intr_status & mmc_rx_irq)) {
-		CHIP_DBG(KERN_INFO "GMAC: MMC rx interrupt: 0x%08x\n",
-			 readl(ioaddr + GMAC_MMC_RX_INTR));
+	if (unlikely(intr_status & mmc_rx_irq))
 		x->mmc_rx_irq_n++;
-	}
-	if (unlikely(intr_status & mmc_rx_csum_offload_irq)) {
-		CHIP_DBG(KERN_INFO "GMAC: MMC rx csum offload: 0x%08x\n",
-			 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
+	if (unlikely(intr_status & mmc_rx_csum_offload_irq))
 		x->mmc_rx_csum_offload_irq_n++;
-	}
 	if (unlikely(intr_status & pmt_irq)) {
-		CHIP_DBG(KERN_INFO "GMAC: received Magic frame\n");
 		/* clear the PMT bits 5 and 6 by reading the PMT status reg */
 		readl(ioaddr + GMAC_PMT);
 		x->irq_receive_pmt_irq_n++;
@@ -229,32 +219,22 @@ static int dwmac1000_irq_status(void __i
 		/* Clean LPI interrupt by reading the Reg 12 */
 		ret = readl(ioaddr + LPI_CTRL_STATUS);
 
-		if (ret & LPI_CTRL_STATUS_TLPIEN) {
-			CHIP_DBG(KERN_INFO "GMAC TX entered in LPI\n");
+		if (ret & LPI_CTRL_STATUS_TLPIEN)
 			x->irq_tx_path_in_lpi_mode_n++;
-		}
-		if (ret & LPI_CTRL_STATUS_TLPIEX) {
-			CHIP_DBG(KERN_INFO "GMAC TX exit from LPI\n");
+		if (ret & LPI_CTRL_STATUS_TLPIEX)
 			x->irq_tx_path_exit_lpi_mode_n++;
-		}
-		if (ret & LPI_CTRL_STATUS_RLPIEN) {
-			CHIP_DBG(KERN_INFO "GMAC RX entered in LPI\n");
+		if (ret & LPI_CTRL_STATUS_RLPIEN)
 			x->irq_rx_path_in_lpi_mode_n++;
-		}
-		if (ret & LPI_CTRL_STATUS_RLPIEX) {
-			CHIP_DBG(KERN_INFO "GMAC RX exit from LPI\n");
+		if (ret & LPI_CTRL_STATUS_RLPIEX)
 			x->irq_rx_path_exit_lpi_mode_n++;
-		}
 	}
 
 	if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
-		CHIP_DBG(KERN_INFO "GMAC PCS ANE IRQ\n");
 		readl(ioaddr + GMAC_AN_STATUS);
 		x->irq_pcs_ane_n++;
 	}
 	if (intr_status & rgmii_irq) {
 		u32 status = readl(ioaddr + GMAC_S_R_GMII);
-		CHIP_DBG(KERN_INFO "GMAC RGMII/SGMII interrupt\n");
 		x->irq_rgmii_n++;
 
 		/* Save and dump the link status. */
@@ -271,11 +251,12 @@ static int dwmac1000_irq_status(void __i
 				x->pcs_speed = SPEED_10;
 
 			x->pcs_link = 1;
-			pr_debug("Link is Up - %d/%s\n", (int)x->pcs_speed,
+			pr_debug("%s: Link is Up - %d/%s\n", __func__,
+				 (int)x->pcs_speed,
 				 x->pcs_duplex ? "Full" : "Half");
 		} else {
 			x->pcs_link = 0;
-			pr_debug("Link is Down\n");
+			pr_debug("%s: Link is Down\n", __func__);
 		}
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,7 +116,7 @@ static void dwmac1000_dma_operation_mode
 	u32 csr6 = readl(ioaddr + DMA_CONTROL);
 
 	if (txmode == SF_DMA_MODE) {
-		CHIP_DBG(KERN_DEBUG "GMAC: enable TX store and forward mode\n");
+		pr_debug("GMAC: enable TX store and forward mode\n");
 		/* Transmit COE type 2 cannot be done in cut-through mode. */
 		csr6 |= DMA_CONTROL_TSF;
 		/* Operating on second frame increase the performance
@@ -124,8 +124,7 @@ static void dwmac1000_dma_operation_mode
 		 */
 		csr6 |= DMA_CONTROL_OSF;
 	} else {
-		CHIP_DBG(KERN_DEBUG "GMAC: disabling TX SF (threshold %d)\n",
-			 txmode);
+		pr_debug("GMAC: disabling TX SF (threshold %d)\n", txmode);
 		csr6 &= ~DMA_CONTROL_TSF;
 		csr6 &= DMA_CONTROL_TC_TX_MASK;
 		/* Set the transmit threshold */
@@ -142,11 +141,10 @@ static void dwmac1000_dma_operation_mode
 	}
 
 	if (rxmode == SF_DMA_MODE) {
-		CHIP_DBG(KERN_DEBUG "GMAC: enable RX store and forward mode\n");
+		pr_debug("GMAC: enable RX store and forward mode\n");
 		csr6 |= DMA_CONTROL_RSF;
 	} else {
-		CHIP_DBG(KERN_DEBUG "GMAC: disable RX SF mode (threshold %d)\n",
-			 rxmode);
+		pr_debug("GMAC: disable RX SF mode (threshold %d)\n", rxmode);
 		csr6 &= ~DMA_CONTROL_RSF;
 		csr6 &= DMA_CONTROL_TC_RX_MASK;
 		if (rxmode <= 32)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -135,10 +135,6 @@ static void dwmac100_set_filter(struct n
 	}
 
 	writel(value, ioaddr + MAC_CONTROL);
-
-	CHIP_DBG(KERN_INFO "%s: Filter: 0x%08x Hash: HI 0x%08x, LO 0x%08x\n",
-		 __func__, readl(ioaddr + MAC_CONTROL),
-		 readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
 }
 
 static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -90,14 +90,14 @@ static void dwmac100_dump_dma_regs(void
 {
 	int i;
 
-	CHIP_DBG(KERN_DEBUG "DWMAC 100 DMA CSR\n");
+	pr_debug("DWMAC 100 DMA CSR\n");
 	for (i = 0; i < 9; i++)
 		pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
 			 (DMA_BUS_MODE + i * 4),
 			 readl(ioaddr + DMA_BUS_MODE + i * 4));
-	CHIP_DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
-		 DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
-	CHIP_DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
+
+	pr_debug("\tCSR20 (0x%x): 0x%08x, CSR21 (0x%x): 0x%08x\n",
+		 DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR),
 		 DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,13 +24,6 @@
 #include "common.h"
 #include "dwmac_dma.h"
 
-#undef DWMAC_DMA_DEBUG
-#ifdef DWMAC_DMA_DEBUG
-#define DWMAC_LIB_DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define DWMAC_LIB_DBG(fmt, args...)  do { } while (0)
-#endif
-
 #define GMAC_HI_REG_AE		0x80000000
 
 /* CSR1 enables the transmit DMA to check for new descriptor */
@@ -85,24 +78,24 @@ static void show_tx_process_state(unsign
 
 	switch (state) {
 	case 0:
-		pr_info("- TX (Stopped): Reset or Stop command\n");
+		pr_debug("- TX (Stopped): Reset or Stop command\n");
 		break;
 	case 1:
-		pr_info("- TX (Running):Fetching the Tx desc\n");
+		pr_debug("- TX (Running):Fetching the Tx desc\n");
 		break;
 	case 2:
-		pr_info("- TX (Running): Waiting for end of tx\n");
+		pr_debug("- TX (Running): Waiting for end of tx\n");
 		break;
 	case 3:
-		pr_info("- TX (Running): Reading the data "
+		pr_debug("- TX (Running): Reading the data "
 		       "and queuing the data into the Tx buf\n");
 		break;
 	case 6:
-		pr_info("- TX (Suspended): Tx Buff Underflow "
+		pr_debug("- TX (Suspended): Tx Buff Underflow "
 		       "or an unavailable Transmit descriptor\n");
 		break;
 	case 7:
-		pr_info("- TX (Running): Closing Tx descriptor\n");
+		pr_debug("- TX (Running): Closing Tx descriptor\n");
 		break;
 	default:
 		break;
@@ -116,29 +109,29 @@ static void show_rx_process_state(unsign
 
 	switch (state) {
 	case 0:
-		pr_info("- RX (Stopped): Reset or Stop command\n");
+		pr_debug("- RX (Stopped): Reset or Stop command\n");
 		break;
 	case 1:
-		pr_info("- RX (Running): Fetching the Rx desc\n");
+		pr_debug("- RX (Running): Fetching the Rx desc\n");
 		break;
 	case 2:
-		pr_info("- RX (Running):Checking for end of pkt\n");
+		pr_debug("- RX (Running):Checking for end of pkt\n");
 		break;
 	case 3:
-		pr_info("- RX (Running): Waiting for Rx pkt\n");
+		pr_debug("- RX (Running): Waiting for Rx pkt\n");
 		break;
 	case 4:
-		pr_info("- RX (Suspended): Unavailable Rx buf\n");
+		pr_debug("- RX (Suspended): Unavailable Rx buf\n");
 		break;
 	case 5:
-		pr_info("- RX (Running): Closing Rx descriptor\n");
+		pr_debug("- RX (Running): Closing Rx descriptor\n");
 		break;
 	case 6:
-		pr_info("- RX(Running): Flushing the current frame"
+		pr_debug("- RX(Running): Flushing the current frame"
 		       " from the Rx buf\n");
 		break;
 	case 7:
-		pr_info("- RX (Running): Queuing the Rx frame"
+		pr_debug("- RX (Running): Queuing the Rx frame"
 		       " from the Rx buf into memory\n");
 		break;
 	default:
@@ -154,51 +147,37 @@ int dwmac_dma_interrupt(void __iomem *io
 	/* read the status register (CSR5) */
 	u32 intr_status = readl(ioaddr + DMA_STATUS);
 
-	DWMAC_LIB_DBG(KERN_INFO "%s: [CSR5: 0x%08x]\n", __func__, intr_status);
 #ifdef DWMAC_DMA_DEBUG
-	/* It displays the DMA process states (CSR5 register) */
+	/* Enable it to monitor DMA rx/tx status in case of critical problems */
+	pr_debug("%s: [CSR5: 0x%08x]\n", __func__, intr_status);
 	show_tx_process_state(intr_status);
 	show_rx_process_state(intr_status);
 #endif
 	/* ABNORMAL interrupts */
 	if (unlikely(intr_status & DMA_STATUS_AIS)) {
-		DWMAC_LIB_DBG(KERN_INFO "CSR5[15] DMA ABNORMAL IRQ: ");
 		if (unlikely(intr_status & DMA_STATUS_UNF)) {
-			DWMAC_LIB_DBG(KERN_INFO "transmit underflow\n");
 			ret = tx_hard_error_bump_tc;
 			x->tx_undeflow_irq++;
 		}
-		if (unlikely(intr_status & DMA_STATUS_TJT)) {
-			DWMAC_LIB_DBG(KERN_INFO "transmit jabber\n");
+		if (unlikely(intr_status & DMA_STATUS_TJT))
 			x->tx_jabber_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_OVF)) {
-			DWMAC_LIB_DBG(KERN_INFO "recv overflow\n");
+
+		if (unlikely(intr_status & DMA_STATUS_OVF))
 			x->rx_overflow_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_RU)) {
-			DWMAC_LIB_DBG(KERN_INFO "receive buffer unavailable\n");
+
+		if (unlikely(intr_status & DMA_STATUS_RU))
 			x->rx_buf_unav_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_RPS)) {
-			DWMAC_LIB_DBG(KERN_INFO "receive process stopped\n");
+		if (unlikely(intr_status & DMA_STATUS_RPS))
 			x->rx_process_stopped_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_RWT)) {
-			DWMAC_LIB_DBG(KERN_INFO "receive watchdog\n");
+		if (unlikely(intr_status & DMA_STATUS_RWT))
 			x->rx_watchdog_irq++;
-		}
-		if (unlikely(intr_status & DMA_STATUS_ETI)) {
-			DWMAC_LIB_DBG(KERN_INFO "transmit early interrupt\n");
+		if (unlikely(intr_status & DMA_STATUS_ETI))
 			x->tx_early_irq++;
-		}
 		if (unlikely(intr_status & DMA_STATUS_TPS)) {
-			DWMAC_LIB_DBG(KERN_INFO "transmit process stopped\n");
 			x->tx_process_stopped_irq++;
 			ret = tx_hard_error;
 		}
 		if (unlikely(intr_status & DMA_STATUS_FBI)) {
-			DWMAC_LIB_DBG(KERN_INFO "fatal bus error\n");
 			x->fatal_bus_error_irq++;
 			ret = tx_hard_error;
 		}
@@ -224,12 +203,11 @@ int dwmac_dma_interrupt(void __iomem *io
 	/* Optional hardware blocks, interrupts should be disabled */
 	if (unlikely(intr_status &
 		     (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
-		pr_info("%s: unexpected status %08x\n", __func__, intr_status);
+		pr_warn("%s: unexpected status %08x\n", __func__, intr_status);
 
 	/* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
 	writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
 
-	DWMAC_LIB_DBG(KERN_INFO "\n\n");
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/enh_desc.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/enh_desc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/enh_desc.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,54 +33,40 @@ static int enh_desc_get_tx_status(void *
 	struct net_device_stats *stats = (struct net_device_stats *)data;
 
 	if (unlikely(p->des01.etx.error_summary)) {
-		CHIP_DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
-		if (unlikely(p->des01.etx.jabber_timeout)) {
-			CHIP_DBG(KERN_ERR "\tjabber_timeout error\n");
+		if (unlikely(p->des01.etx.jabber_timeout))
 			x->tx_jabber++;
-		}
 
 		if (unlikely(p->des01.etx.frame_flushed)) {
-			CHIP_DBG(KERN_ERR "\tframe_flushed error\n");
 			x->tx_frame_flushed++;
 			dwmac_dma_flush_tx_fifo(ioaddr);
 		}
 
 		if (unlikely(p->des01.etx.loss_carrier)) {
-			CHIP_DBG(KERN_ERR "\tloss_carrier error\n");
 			x->tx_losscarrier++;
 			stats->tx_carrier_errors++;
 		}
 		if (unlikely(p->des01.etx.no_carrier)) {
-			CHIP_DBG(KERN_ERR "\tno_carrier error\n");
 			x->tx_carrier++;
 			stats->tx_carrier_errors++;
 		}
-		if (unlikely(p->des01.etx.late_collision)) {
-			CHIP_DBG(KERN_ERR "\tlate_collision error\n");
+		if (unlikely(p->des01.etx.late_collision))
 			stats->collisions += p->des01.etx.collision_count;
-		}
-		if (unlikely(p->des01.etx.excessive_collisions)) {
-			CHIP_DBG(KERN_ERR "\texcessive_collisions\n");
+
+		if (unlikely(p->des01.etx.excessive_collisions))
 			stats->collisions += p->des01.etx.collision_count;
-		}
-		if (unlikely(p->des01.etx.excessive_deferral)) {
-			CHIP_DBG(KERN_INFO "\texcessive tx_deferral\n");
+
+		if (unlikely(p->des01.etx.excessive_deferral))
 			x->tx_deferred++;
-		}
 
 		if (unlikely(p->des01.etx.underflow_error)) {
-			CHIP_DBG(KERN_ERR "\tunderflow error\n");
 			dwmac_dma_flush_tx_fifo(ioaddr);
 			x->tx_underflow++;
 		}
 
-		if (unlikely(p->des01.etx.ip_header_error)) {
-			CHIP_DBG(KERN_ERR "\tTX IP header csum error\n");
+		if (unlikely(p->des01.etx.ip_header_error))
 			x->tx_ip_header_error++;
-		}
 
 		if (unlikely(p->des01.etx.payload_error)) {
-			CHIP_DBG(KERN_ERR "\tAddr/Payload csum error\n");
 			x->tx_payload_error++;
 			dwmac_dma_flush_tx_fifo(ioaddr);
 		}
@@ -88,15 +74,12 @@ static int enh_desc_get_tx_status(void *
 		ret = -1;
 	}
 
-	if (unlikely(p->des01.etx.deferred)) {
-		CHIP_DBG(KERN_INFO "GMAC TX status: tx deferred\n");
+	if (unlikely(p->des01.etx.deferred))
 		x->tx_deferred++;
-	}
+
 #ifdef STMMAC_VLAN_TAG_USED
-	if (p->des01.etx.vlan_frame) {
-		CHIP_DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
+	if (p->des01.etx.vlan_frame)
 		x->tx_vlan++;
-	}
 #endif
 
 	return ret;
@@ -123,30 +106,20 @@ static int enh_desc_coe_rdes0(int ipc_er
 	 *      0 1 1 | COE bypassed.. no IPv4/6 frame
 	 *      0 1 0 | Reserved.
 	 */
-	if (status == 0x0) {
-		CHIP_DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
+	if (status == 0x0)
 		ret = llc_snap;
-	} else if (status == 0x4) {
-		CHIP_DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
+	else if (status == 0x4)
 		ret = good_frame;
-	} else if (status == 0x5) {
-		CHIP_DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
+	else if (status == 0x5)
 		ret = csum_none;
-	} else if (status == 0x6) {
-		CHIP_DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
+	else if (status == 0x6)
 		ret = csum_none;
-	} else if (status == 0x7) {
-		CHIP_DBG(KERN_ERR
-		    "RX Des0 status: IPv4/6 Header and Payload Error.\n");
+	else if (status == 0x7)
 		ret = csum_none;
-	} else if (status == 0x1) {
-		CHIP_DBG(KERN_ERR
-		    "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
+	else if (status == 0x1)
 		ret = discard_frame;
-	} else if (status == 0x3) {
-		CHIP_DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
+	else if (status == 0x3)
 		ret = discard_frame;
-	}
 	return ret;
 }
 
@@ -208,36 +181,26 @@ static int enh_desc_get_rx_status(void *
 	struct net_device_stats *stats = (struct net_device_stats *)data;
 
 	if (unlikely(p->des01.erx.error_summary)) {
-		CHIP_DBG(KERN_ERR "GMAC RX Error Summary 0x%08x\n",
-				  p->des01.erx);
 		if (unlikely(p->des01.erx.descriptor_error)) {
-			CHIP_DBG(KERN_ERR "\tdescriptor error\n");
 			x->rx_desc++;
 			stats->rx_length_errors++;
 		}
-		if (unlikely(p->des01.erx.overflow_error)) {
-			CHIP_DBG(KERN_ERR "\toverflow error\n");
+		if (unlikely(p->des01.erx.overflow_error))
 			x->rx_gmac_overflow++;
-		}
 
 		if (unlikely(p->des01.erx.ipc_csum_error))
-			CHIP_DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
+			pr_err("\tIPC Csum Error/Giant frame\n");
 
 		if (unlikely(p->des01.erx.late_collision)) {
-			CHIP_DBG(KERN_ERR "\tlate_collision error\n");
-			stats->collisions++;
 			stats->collisions++;
 		}
-		if (unlikely(p->des01.erx.receive_watchdog)) {
-			CHIP_DBG(KERN_ERR "\treceive_watchdog error\n");
+		if (unlikely(p->des01.erx.receive_watchdog))
 			x->rx_watchdog++;
-		}
-		if (unlikely(p->des01.erx.error_gmii)) {
-			CHIP_DBG(KERN_ERR "\tReceive Error\n");
+
+		if (unlikely(p->des01.erx.error_gmii))
 			x->rx_mii++;
-		}
+
 		if (unlikely(p->des01.erx.crc_error)) {
-			CHIP_DBG(KERN_ERR "\tCRC error\n");
 			x->rx_crc++;
 			stats->rx_crc_errors++;
 		}
@@ -251,30 +214,24 @@ static int enh_desc_get_rx_status(void *
 	ret = enh_desc_coe_rdes0(p->des01.erx.ipc_csum_error,
 		p->des01.erx.frame_type, p->des01.erx.rx_mac_addr);
 
-	if (unlikely(p->des01.erx.dribbling)) {
-		CHIP_DBG(KERN_ERR "GMAC RX: dribbling error\n");
+	if (unlikely(p->des01.erx.dribbling))
 		x->dribbling_bit++;
-	}
+
 	if (unlikely(p->des01.erx.sa_filter_fail)) {
-		CHIP_DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
 		x->sa_rx_filter_fail++;
 		ret = discard_frame;
 	}
 	if (unlikely(p->des01.erx.da_filter_fail)) {
-		CHIP_DBG(KERN_ERR "GMAC RX : Dest Address filter fail\n");
 		x->da_rx_filter_fail++;
 		ret = discard_frame;
 	}
 	if (unlikely(p->des01.erx.length_error)) {
-		CHIP_DBG(KERN_ERR "GMAC RX: length_error error\n");
 		x->rx_length++;
 		ret = discard_frame;
 	}
 #ifdef STMMAC_VLAN_TAG_USED
-	if (p->des01.erx.vlan_tag) {
-		CHIP_DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
+	if (p->des01.erx.vlan_tag)
 		x->rx_vlan++;
-	}
 #endif
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,6 @@
 config STMMAC_ETH
 	tristate "STMicroelectronics 10/100/1000 Ethernet driver"
 	depends on HAS_IOMEM && HAS_DMA
-	select NET_CORE
 	select MII
 	select PHYLIB
 	select CRC32
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/norm_desc.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/norm_desc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/norm_desc.c	2013-08-25 20:43:22.000000000 -0400
@@ -52,10 +52,8 @@ static int ndesc_get_tx_status(void *dat
 		ret = -1;
 	}
 
-	if (p->des01.etx.vlan_frame) {
-		CHIP_DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
+	if (p->des01.etx.vlan_frame)
 		x->tx_vlan++;
-	}
 
 	if (unlikely(p->des01.tx.deferred))
 		x->tx_deferred++;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/ring_mode.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/ring_mode.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/ring_mode.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,10 +33,15 @@ static unsigned int stmmac_jumbo_frm(voi
 	struct stmmac_priv *priv = (struct stmmac_priv *)p;
 	unsigned int txsize = priv->dma_tx_size;
 	unsigned int entry = priv->cur_tx % txsize;
-	struct dma_desc *desc = priv->dma_tx + entry;
+	struct dma_desc *desc;
 	unsigned int nopaged_len = skb_headlen(skb);
 	unsigned int bmax, len;
 
+	if (priv->extend_desc)
+		desc = (struct dma_desc *)(priv->dma_etx + entry);
+	else
+		desc = priv->dma_tx + entry;
+
 	if (priv->plat->enh_desc)
 		bmax = BUF_SIZE_8KiB;
 	else
@@ -54,7 +59,11 @@ static unsigned int stmmac_jumbo_frm(voi
 						STMMAC_RING_MODE);
 		wmb();
 		entry = (++priv->cur_tx) % txsize;
-		desc = priv->dma_tx + entry;
+
+		if (priv->extend_desc)
+			desc = (struct dma_desc *)(priv->dma_etx + entry);
+		else
+			desc = priv->dma_tx + entry;
 
 		desc->des2 = dma_map_single(priv->device, skb->data + bmax,
 					    len, DMA_TO_DEVICE);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,32 +51,6 @@
 #include "stmmac_ptp.h"
 #include "stmmac.h"
 
-#undef STMMAC_DEBUG
-/*#define STMMAC_DEBUG*/
-#ifdef STMMAC_DEBUG
-#define DBG(nlevel, klevel, fmt, args...) \
-		((void)(netif_msg_##nlevel(priv) && \
-		printk(KERN_##klevel fmt, ## args)))
-#else
-#define DBG(nlevel, klevel, fmt, args...) do { } while (0)
-#endif
-
-#undef STMMAC_RX_DEBUG
-/*#define STMMAC_RX_DEBUG*/
-#ifdef STMMAC_RX_DEBUG
-#define RX_DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define RX_DBG(fmt, args...)  do { } while (0)
-#endif
-
-#undef STMMAC_XMIT_DEBUG
-/*#define STMMAC_XMIT_DEBUG*/
-#ifdef STMMAC_XMIT_DEBUG
-#define TX_DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define TX_DBG(fmt, args...)  do { } while (0)
-#endif
-
 #define STMMAC_ALIGN(x)	L1_CACHE_ALIGN(x)
 #define JUMBO_LEN	9000
 
@@ -214,19 +188,17 @@ static void stmmac_clk_csr_set(struct st
 	}
 }
 
-#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
 static void print_pkt(unsigned char *buf, int len)
 {
 	int j;
-	pr_info("len = %d byte, buf addr: 0x%p", len, buf);
+	pr_debug("len = %d byte, buf addr: 0x%p", len, buf);
 	for (j = 0; j < len; j++) {
 		if ((j % 16) == 0)
-			pr_info("\n %03x:", j);
-		pr_info(" %02x", buf[j]);
+			pr_debug("\n %03x:", j);
+		pr_debug(" %02x", buf[j]);
 	}
-	pr_info("\n");
+	pr_debug("\n");
 }
-#endif
 
 /* minimum number of free TX descriptors required to wake up TX process */
 #define STMMAC_TX_THRESH(x)	(x->dma_tx_size/4)
@@ -696,9 +668,6 @@ static void stmmac_adjust_link(struct ne
 	if (phydev == NULL)
 		return;
 
-	DBG(probe, DEBUG, "stmmac_adjust_link: called.  address %d link %d\n",
-	    phydev->addr, phydev->link);
-
 	spin_lock_irqsave(&priv->lock, flags);
 
 	if (phydev->link) {
@@ -773,8 +742,6 @@ static void stmmac_adjust_link(struct ne
 	priv->eee_enabled = stmmac_eee_init(priv);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
-
-	DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
 }
 
 /**
@@ -789,13 +756,13 @@ static void stmmac_check_pcs_mode(struct
 	int interface = priv->plat->interface;
 
 	if (priv->dma_cap.pcs) {
-		if ((interface & PHY_INTERFACE_MODE_RGMII) ||
-		    (interface & PHY_INTERFACE_MODE_RGMII_ID) ||
-		    (interface & PHY_INTERFACE_MODE_RGMII_RXID) ||
-		    (interface & PHY_INTERFACE_MODE_RGMII_TXID)) {
+		if ((interface == PHY_INTERFACE_MODE_RGMII) ||
+		    (interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+		    (interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
+		    (interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
 			pr_debug("STMMAC: PCS RGMII support enable\n");
 			priv->pcs = STMMAC_PCS_RGMII;
-		} else if (interface & PHY_INTERFACE_MODE_SGMII) {
+		} else if (interface == PHY_INTERFACE_MODE_SGMII) {
 			pr_debug("STMMAC: PCS SGMII support enable\n");
 			priv->pcs = STMMAC_PCS_SGMII;
 		}
@@ -972,15 +939,20 @@ static int stmmac_init_rx_buffers(struct
 
 	skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN,
 				 GFP_KERNEL);
-	if (unlikely(skb == NULL)) {
+	if (!skb) {
 		pr_err("%s: Rx init fails; skb is NULL\n", __func__);
-		return 1;
+		return -ENOMEM;
 	}
 	skb_reserve(skb, NET_IP_ALIGN);
 	priv->rx_skbuff[i] = skb;
 	priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
 						priv->dma_buf_sz,
 						DMA_FROM_DEVICE);
+	if (dma_mapping_error(priv->device, priv->rx_skbuff_dma[i])) {
+		pr_err("%s: DMA mapping error\n", __func__);
+		dev_kfree_skb_any(skb);
+		return -EINVAL;
+	}
 
 	p->des2 = priv->rx_skbuff_dma[i];
 
@@ -991,6 +963,16 @@ static int stmmac_init_rx_buffers(struct
 	return 0;
 }
 
+static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i)
+{
+	if (priv->rx_skbuff[i]) {
+		dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
+				 priv->dma_buf_sz, DMA_FROM_DEVICE);
+		dev_kfree_skb_any(priv->rx_skbuff[i]);
+	}
+	priv->rx_skbuff[i] = NULL;
+}
+
 /**
  * init_dma_desc_rings - init the RX/TX descriptor rings
  * @dev: net device structure
@@ -998,13 +980,14 @@ static int stmmac_init_rx_buffers(struct
  * and allocates the socket buffers. It suppors the chained and ring
  * modes.
  */
-static void init_dma_desc_rings(struct net_device *dev)
+static int init_dma_desc_rings(struct net_device *dev)
 {
 	int i;
 	struct stmmac_priv *priv = netdev_priv(dev);
 	unsigned int txsize = priv->dma_tx_size;
 	unsigned int rxsize = priv->dma_rx_size;
 	unsigned int bfsize = 0;
+	int ret = -ENOMEM;
 
 	/* Set the max buffer size according to the DESC mode
 	 * and the MTU. Note that RING mode allows 16KiB bsize.
@@ -1015,8 +998,9 @@ static void init_dma_desc_rings(struct n
 	if (bfsize < BUF_SIZE_16KiB)
 		bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
 
-	DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
-	    txsize, rxsize, bfsize);
+	if (netif_msg_probe(priv))
+		pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__,
+			 txsize, rxsize, bfsize);
 
 	if (priv->extend_desc) {
 		priv->dma_erx = dma_alloc_coherent(priv->device, rxsize *
@@ -1024,40 +1008,67 @@ static void init_dma_desc_rings(struct n
 							  dma_extended_desc),
 						   &priv->dma_rx_phy,
 						   GFP_KERNEL);
+		if (!priv->dma_erx)
+			goto err_dma;
+
 		priv->dma_etx = dma_alloc_coherent(priv->device, txsize *
 						   sizeof(struct
 							  dma_extended_desc),
 						   &priv->dma_tx_phy,
 						   GFP_KERNEL);
-		if ((!priv->dma_erx) || (!priv->dma_etx))
-			return;
+		if (!priv->dma_etx) {
+			dma_free_coherent(priv->device, priv->dma_rx_size *
+					sizeof(struct dma_extended_desc),
+					priv->dma_erx, priv->dma_rx_phy);
+			goto err_dma;
+		}
 	} else {
 		priv->dma_rx = dma_alloc_coherent(priv->device, rxsize *
 						  sizeof(struct dma_desc),
 						  &priv->dma_rx_phy,
 						  GFP_KERNEL);
+		if (!priv->dma_rx)
+			goto err_dma;
+
 		priv->dma_tx = dma_alloc_coherent(priv->device, txsize *
 						  sizeof(struct dma_desc),
 						  &priv->dma_tx_phy,
 						  GFP_KERNEL);
-		if ((!priv->dma_rx) || (!priv->dma_tx))
-			return;
+		if (!priv->dma_tx) {
+			dma_free_coherent(priv->device, priv->dma_rx_size *
+					sizeof(struct dma_desc),
+					priv->dma_rx, priv->dma_rx_phy);
+			goto err_dma;
+		}
 	}
 
 	priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t),
 					    GFP_KERNEL);
+	if (!priv->rx_skbuff_dma)
+		goto err_rx_skbuff_dma;
+
 	priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
 					GFP_KERNEL);
+	if (!priv->rx_skbuff)
+		goto err_rx_skbuff;
+
 	priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
 					    GFP_KERNEL);
+	if (!priv->tx_skbuff_dma)
+		goto err_tx_skbuff_dma;
+
 	priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
 					GFP_KERNEL);
-	if (netif_msg_drv(priv))
+	if (!priv->tx_skbuff)
+		goto err_tx_skbuff;
+
+	if (netif_msg_probe(priv)) {
 		pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__,
 			 (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy);
 
-	/* RX INITIALIZATION */
-	DBG(probe, INFO, "stmmac: SKB addresses:\nskb\t\tskb data\tdma data\n");
+		/* RX INITIALIZATION */
+		pr_debug("\tSKB addresses:\nskb\t\tskb data\tdma data\n");
+	}
 	for (i = 0; i < rxsize; i++) {
 		struct dma_desc *p;
 		if (priv->extend_desc)
@@ -1065,11 +1076,14 @@ static void init_dma_desc_rings(struct n
 		else
 			p = priv->dma_rx + i;
 
-		if (stmmac_init_rx_buffers(priv, p, i))
-			break;
+		ret = stmmac_init_rx_buffers(priv, p, i);
+		if (ret)
+			goto err_init_rx_buffers;
 
-		DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
-		    priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
+		if (netif_msg_probe(priv))
+			pr_debug("[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
+				 priv->rx_skbuff[i]->data,
+				 (unsigned int)priv->rx_skbuff_dma[i]);
 	}
 	priv->cur_rx = 0;
 	priv->dirty_rx = (unsigned int)(i - rxsize);
@@ -1110,20 +1124,44 @@ static void init_dma_desc_rings(struct n
 
 	if (netif_msg_hw(priv))
 		stmmac_display_rings(priv);
+
+	return 0;
+err_init_rx_buffers:
+	while (--i >= 0)
+		stmmac_free_rx_buffers(priv, i);
+	kfree(priv->tx_skbuff);
+err_tx_skbuff:
+	kfree(priv->tx_skbuff_dma);
+err_tx_skbuff_dma:
+	kfree(priv->rx_skbuff);
+err_rx_skbuff:
+	kfree(priv->rx_skbuff_dma);
+err_rx_skbuff_dma:
+	if (priv->extend_desc) {
+		dma_free_coherent(priv->device, priv->dma_tx_size *
+				  sizeof(struct dma_extended_desc),
+				  priv->dma_etx, priv->dma_tx_phy);
+		dma_free_coherent(priv->device, priv->dma_rx_size *
+				  sizeof(struct dma_extended_desc),
+				  priv->dma_erx, priv->dma_rx_phy);
+	} else {
+		dma_free_coherent(priv->device,
+				priv->dma_tx_size * sizeof(struct dma_desc),
+				priv->dma_tx, priv->dma_tx_phy);
+		dma_free_coherent(priv->device,
+				priv->dma_rx_size * sizeof(struct dma_desc),
+				priv->dma_rx, priv->dma_rx_phy);
+	}
+err_dma:
+	return ret;
 }
 
 static void dma_free_rx_skbufs(struct stmmac_priv *priv)
 {
 	int i;
 
-	for (i = 0; i < priv->dma_rx_size; i++) {
-		if (priv->rx_skbuff[i]) {
-			dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
-					 priv->dma_buf_sz, DMA_FROM_DEVICE);
-			dev_kfree_skb_any(priv->rx_skbuff[i]);
-		}
-		priv->rx_skbuff[i] = NULL;
-	}
+	for (i = 0; i < priv->dma_rx_size; i++)
+		stmmac_free_rx_buffers(priv, i);
 }
 
 static void dma_free_tx_skbufs(struct stmmac_priv *priv)
@@ -1244,8 +1282,9 @@ static void stmmac_tx_clean(struct stmma
 
 			stmmac_get_tx_hwtstamp(priv, entry, skb);
 		}
-		TX_DBG("%s: curr %d, dirty %d\n", __func__,
-		       priv->cur_tx, priv->dirty_tx);
+		if (netif_msg_tx_done(priv))
+			pr_debug("%s: curr %d, dirty %d\n", __func__,
+				 priv->cur_tx, priv->dirty_tx);
 
 		if (likely(priv->tx_skbuff_dma[entry])) {
 			dma_unmap_single(priv->device,
@@ -1270,7 +1309,8 @@ static void stmmac_tx_clean(struct stmma
 		netif_tx_lock(priv->dev);
 		if (netif_queue_stopped(priv->dev) &&
 		    stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
-			TX_DBG("%s: restart transmit\n", __func__);
+			if (netif_msg_tx_done(priv))
+				pr_debug("%s: restart transmit\n", __func__);
 			netif_wake_queue(priv->dev);
 		}
 		netif_tx_unlock(priv->dev);
@@ -1579,7 +1619,7 @@ static int stmmac_open(struct net_device
 		if (ret) {
 			pr_err("%s: Cannot attach to PHY (error: %d)\n",
 			       __func__, ret);
-			goto open_error;
+			goto phy_error;
 		}
 	}
 
@@ -1587,13 +1627,18 @@ static int stmmac_open(struct net_device
 	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
 	priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
-	init_dma_desc_rings(dev);
+
+	ret = init_dma_desc_rings(dev);
+	if (ret < 0) {
+		pr_err("%s: DMA descriptors initialization failed\n", __func__);
+		goto dma_desc_error;
+	}
 
 	/* DMA initialization and SW reset */
 	ret = stmmac_init_dma_engine(priv);
 	if (ret < 0) {
-		pr_err("%s: DMA initialization failed\n", __func__);
-		goto open_error;
+		pr_err("%s: DMA engine initialization failed\n", __func__);
+		goto init_error;
 	}
 
 	/* Copy the MAC addr into the HW  */
@@ -1612,7 +1657,7 @@ static int stmmac_open(struct net_device
 	if (unlikely(ret < 0)) {
 		pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
 		       __func__, dev->irq, ret);
-		goto open_error;
+		goto init_error;
 	}
 
 	/* Request the Wake IRQ in case of another line is used for WoL */
@@ -1622,7 +1667,7 @@ static int stmmac_open(struct net_device
 		if (unlikely(ret < 0)) {
 			pr_err("%s: ERROR: allocating the WoL IRQ %d (%d)\n",
 			       __func__, priv->wol_irq, ret);
-			goto open_error_wolirq;
+			goto wolirq_error;
 		}
 	}
 
@@ -1633,7 +1678,7 @@ static int stmmac_open(struct net_device
 		if (unlikely(ret < 0)) {
 			pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n",
 			       __func__, priv->lpi_irq, ret);
-			goto open_error_lpiirq;
+			goto lpiirq_error;
 		}
 	}
 
@@ -1659,7 +1704,7 @@ static int stmmac_open(struct net_device
 		pr_warn("%s: failed debugFS registration\n", __func__);
 #endif
 	/* Start the ball rolling... */
-	DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
+	pr_debug("%s: DMA RX/TX processes started...\n", dev->name);
 	priv->hw->dma->start_tx(priv->ioaddr);
 	priv->hw->dma->start_rx(priv->ioaddr);
 
@@ -1691,17 +1736,18 @@ static int stmmac_open(struct net_device
 
 	return 0;
 
-open_error_lpiirq:
+lpiirq_error:
 	if (priv->wol_irq != dev->irq)
 		free_irq(priv->wol_irq, dev);
-
-open_error_wolirq:
+wolirq_error:
 	free_irq(dev->irq, dev);
 
-open_error:
+init_error:
+	free_dma_desc_resources(priv);
+dma_desc_error:
 	if (priv->phydev)
 		phy_disconnect(priv->phydev);
-
+phy_error:
 	clk_disable_unprepare(priv->stmmac_clk);
 
 	return ret;
@@ -1796,16 +1842,6 @@ static netdev_tx_t stmmac_xmit(struct sk
 
 	entry = priv->cur_tx % txsize;
 
-#ifdef STMMAC_XMIT_DEBUG
-	if ((skb->len > ETH_FRAME_LEN) || nfrags)
-		pr_debug("%s: [entry %d]: skb addr %p len: %d nopagedlen: %d\n"
-			 "\tn_frags: %d - ip_summed: %d - %s gso\n"
-			 "\ttx_count_frames %d\n", __func__, entry,
-			 skb, skb->len, nopaged_len, nfrags, skb->ip_summed,
-			 !skb_is_gso(skb) ? "isn't" : "is",
-			 priv->tx_count_frames);
-#endif
-
 	csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
 
 	if (priv->extend_desc)
@@ -1815,12 +1851,6 @@ static netdev_tx_t stmmac_xmit(struct sk
 
 	first = desc;
 
-#ifdef STMMAC_XMIT_DEBUG
-	if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
-		pr_debug("\tskb len: %d, nopaged_len: %d,\n"
-			 "\t\tn_frags: %d, ip_summed: %d\n",
-			 skb->len, nopaged_len, nfrags, skb->ip_summed);
-#endif
 	priv->tx_skbuff[entry] = skb;
 
 	/* To program the descriptors according to the size of the frame */
@@ -1856,7 +1886,6 @@ static netdev_tx_t stmmac_xmit(struct sk
 		else
 			desc = priv->dma_tx + entry;
 
-		TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
 		desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len,
 					      DMA_TO_DEVICE);
 		priv->tx_skbuff_dma[entry] = desc->des2;
@@ -1880,8 +1909,6 @@ static netdev_tx_t stmmac_xmit(struct sk
 	if (priv->tx_coal_frames > priv->tx_count_frames) {
 		priv->hw->desc->clear_tx_ic(desc);
 		priv->xstats.tx_reset_ic_bit++;
-		TX_DBG("\t[entry %d]: tx_count_frames %d\n", entry,
-		       priv->tx_count_frames);
 		mod_timer(&priv->txtimer,
 			  STMMAC_COAL_TIMER(priv->tx_coal_timer));
 	} else
@@ -1893,22 +1920,22 @@ static netdev_tx_t stmmac_xmit(struct sk
 
 	priv->cur_tx++;
 
-#ifdef STMMAC_XMIT_DEBUG
 	if (netif_msg_pktdata(priv)) {
-		pr_info("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d",
+		pr_debug("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d",
 			__func__, (priv->cur_tx % txsize),
 			(priv->dirty_tx % txsize), entry, first, nfrags);
+
 		if (priv->extend_desc)
 			stmmac_display_ring((void *)priv->dma_etx, txsize, 1);
 		else
 			stmmac_display_ring((void *)priv->dma_tx, txsize, 0);
 
-		pr_info(">>> frame to be transmitted: ");
+		pr_debug(">>> frame to be transmitted: ");
 		print_pkt(skb->data, skb->len);
 	}
-#endif
 	if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
-		TX_DBG("%s: stop transmitted packets\n", __func__);
+		if (netif_msg_hw(priv))
+			pr_debug("%s: stop transmitted packets\n", __func__);
 		netif_stop_queue(dev);
 	}
 
@@ -1968,7 +1995,8 @@ static inline void stmmac_rx_refill(stru
 
 			priv->hw->ring->refill_desc3(priv, p);
 
-			RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
+			if (netif_msg_rx_status(priv))
+				pr_debug("\trefill entry #%d\n", entry);
 		}
 		wmb();
 		priv->hw->desc->set_rx_owner(p);
@@ -1991,15 +2019,13 @@ static int stmmac_rx(struct stmmac_priv
 	unsigned int count = 0;
 	int coe = priv->plat->rx_coe;
 
-#ifdef STMMAC_RX_DEBUG
-	if (netif_msg_hw(priv)) {
-		pr_debug(">>> stmmac_rx: descriptor ring:\n");
+	if (netif_msg_rx_status(priv)) {
+		pr_debug("%s: descriptor ring:\n", __func__);
 		if (priv->extend_desc)
 			stmmac_display_ring((void *)priv->dma_erx, rxsize, 1);
 		else
 			stmmac_display_ring((void *)priv->dma_rx, rxsize, 0);
 	}
-#endif
 	while (count < limit) {
 		int status;
 		struct dma_desc *p;
@@ -2053,15 +2079,14 @@ static int stmmac_rx(struct stmmac_priv
 			 */
 			if (unlikely(status != llc_snap))
 				frame_len -= ETH_FCS_LEN;
-#ifdef STMMAC_RX_DEBUG
-			if (frame_len > ETH_FRAME_LEN)
-				pr_debug("\tRX frame size %d, COE status: %d\n",
-					 frame_len, status);
 
-			if (netif_msg_hw(priv))
+			if (netif_msg_rx_status(priv)) {
 				pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
 					 p, entry, p->des2);
-#endif
+				if (frame_len > ETH_FRAME_LEN)
+					pr_debug("\tframe size %d, COE: %d\n",
+						 frame_len, status);
+			}
 			skb = priv->rx_skbuff[entry];
 			if (unlikely(!skb)) {
 				pr_err("%s: Inconsistent Rx descriptor chain\n",
@@ -2078,12 +2103,12 @@ static int stmmac_rx(struct stmmac_priv
 			dma_unmap_single(priv->device,
 					 priv->rx_skbuff_dma[entry],
 					 priv->dma_buf_sz, DMA_FROM_DEVICE);
-#ifdef STMMAC_RX_DEBUG
+
 			if (netif_msg_pktdata(priv)) {
-				pr_info(" frame received (%dbytes)", frame_len);
+				pr_debug("frame received (%dbytes)", frame_len);
 				print_pkt(skb->data, frame_len);
 			}
-#endif
+
 			skb->protocol = eth_type_trans(skb, priv->dev);
 
 			if (unlikely(!coe))
@@ -2562,9 +2587,6 @@ static int stmmac_hw_init(struct stmmac_
 	/* Get and dump the chip ID */
 	priv->synopsys_id = stmmac_get_synopsys_id(priv);
 
-	/* To use alternate (extended) or normal descriptor structures */
-	stmmac_selec_desc_mode(priv);
-
 	/* To use the chained or ring mode */
 	if (chain_mode) {
 		priv->hw->chain = &chain_mode_ops;
@@ -2599,6 +2621,9 @@ static int stmmac_hw_init(struct stmmac_
 	} else
 		pr_info(" No HW DMA feature register supported");
 
+	/* To use alternate (extended) or normal descriptor structures */
+	stmmac_selec_desc_mode(priv);
+
 	ret = priv->hw->mac->rx_ipc(priv->ioaddr);
 	if (!ret) {
 		pr_warn(" RX IPC Checksum Offload not configured.\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,9 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+
 #include <asm/io.h>
 
 #include "stmmac.h"
@@ -131,10 +134,46 @@ static int stmmac_mdio_reset(struct mii_
 	struct net_device *ndev = bus->priv;
 	struct stmmac_priv *priv = netdev_priv(ndev);
 	unsigned int mii_address = priv->hw->mii.addr;
+	struct stmmac_mdio_bus_data *data = priv->plat->mdio_bus_data;
 
-	if (priv->plat->mdio_bus_data->phy_reset) {
+#ifdef CONFIG_OF
+	if (priv->device->of_node) {
+		int reset_gpio, active_low;
+
+		if (data->reset_gpio < 0) {
+			struct device_node *np = priv->device->of_node;
+			if (!np)
+				return 0;
+
+			data->reset_gpio = of_get_named_gpio(np,
+						"snps,reset-gpio", 0);
+			if (data->reset_gpio < 0)
+				return 0;
+
+			data->active_low = of_property_read_bool(np,
+						"snps,reset-active-low");
+			of_property_read_u32_array(np,
+				"snps,reset-delays-us", data->delays, 3);
+		}
+
+		reset_gpio = data->reset_gpio;
+		active_low = data->active_low;
+
+		if (!gpio_request(reset_gpio, "mdio-reset")) {
+			gpio_direction_output(reset_gpio, active_low ? 1 : 0);
+			udelay(data->delays[0]);
+			gpio_set_value(reset_gpio, active_low ? 0 : 1);
+			udelay(data->delays[1]);
+			gpio_set_value(reset_gpio, active_low ? 1 : 0);
+			udelay(data->delays[2]);
+			gpio_free(reset_gpio);
+		}
+	}
+#endif
+
+	if (data->phy_reset) {
 		pr_debug("stmmac_mdio_reset: calling phy_reset\n");
-		priv->plat->mdio_bus_data->phy_reset(priv->plat->bsp_priv);
+		data->phy_reset(priv->plat->bsp_priv);
 	}
 
 	/* This is a workaround for problems with the STE101P PHY.
@@ -172,6 +211,11 @@ int stmmac_mdio_register(struct net_devi
 	else
 		irqlist = priv->mii_irq;
 
+#ifdef CONFIG_OF
+	if (priv->device->of_node)
+		mdio_bus_data->reset_gpio = -1;
+#endif
+
 	new_bus->name = "stmmac";
 	new_bus->read = &stmmac_mdio_read;
 	new_bus->write = &stmmac_mdio_write;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,12 +34,20 @@ static int stmmac_probe_config_dt(struct
 				  const char **mac)
 {
 	struct device_node *np = pdev->dev.of_node;
+	struct stmmac_dma_cfg *dma_cfg;
 
 	if (!np)
 		return -ENODEV;
 
 	*mac = of_get_mac_address(np);
 	plat->interface = of_get_phy_mode(np);
+
+	plat->bus_id = of_alias_get_id(np, "ethernet");
+	if (plat->bus_id < 0)
+		plat->bus_id = 0;
+
+	of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr);
+
 	plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
 					   sizeof(struct stmmac_mdio_bus_data),
 					   GFP_KERNEL);
@@ -56,6 +64,22 @@ static int stmmac_probe_config_dt(struct
 		plat->pmt = 1;
 	}
 
+	if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
+		of_device_is_compatible(np, "snps,dwmac-3.710")) {
+		plat->enh_desc = 1;
+		plat->bugged_jumbo = 1;
+		plat->force_sf_dma_mode = 1;
+	}
+
+	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL);
+	if (!dma_cfg)
+		return -ENOMEM;
+
+	plat->dma_cfg = dma_cfg;
+	of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
+	dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
+	dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
+
 	return 0;
 }
 #else
@@ -92,8 +116,10 @@ static int stmmac_pltfr_probe(struct pla
 	if (IS_ERR(addr))
 		return PTR_ERR(addr);
 
+	plat_dat = pdev->dev.platform_data;
 	if (pdev->dev.of_node) {
-		plat_dat = devm_kzalloc(&pdev->dev,
+		if (!plat_dat)
+			plat_dat = devm_kzalloc(&pdev->dev,
 					sizeof(struct plat_stmmacenet_data),
 					GFP_KERNEL);
 		if (!plat_dat) {
@@ -106,8 +132,6 @@ static int stmmac_pltfr_probe(struct pla
 			pr_err("%s: main dt probe failed", __func__);
 			return ret;
 		}
-	} else {
-		plat_dat = pdev->dev.platform_data;
 	}
 
 	/* Custom initialisation (if needed)*/
@@ -171,8 +195,6 @@ static int stmmac_pltfr_remove(struct pl
 	if (priv->plat->exit)
 		priv->plat->exit(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return ret;
 }
 
@@ -230,7 +252,9 @@ static const struct dev_pm_ops stmmac_pl
 
 static const struct of_device_id stmmac_dt_ids[] = {
 	{ .compatible = "st,spear600-gmac"},
+	{ .compatible = "snps,dwmac-3.610"},
 	{ .compatible = "snps,dwmac-3.70a"},
+	{ .compatible = "snps,dwmac-3.710"},
 	{ .compatible = "snps,dwmac"},
 	{ /* sentinel */ }
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sun/cassini.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/cassini.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sun/cassini.c	2013-07-01 10:36:33.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/cassini.c	2013-08-31 17:56:05.000000000 -0400
@@ -808,44 +808,43 @@ static int cas_reset_mii_phy(struct cas
 	return limit <= 0;
 }
 
-static int cas_saturn_firmware_init(struct cas *cp)
+static void cas_saturn_firmware_init(struct cas *cp)
 {
 	const struct firmware *fw;
 	const char fw_name[] = "/*(DEBLOBBED)*/";
 	int err;
 
 	if (PHY_NS_DP83065 != cp->phy_id)
-		return 0;
+		return;
 
 	err = reject_firmware(&fw, fw_name, &cp->pdev->dev);
 	if (err) {
 		pr_err("Failed to load firmware \"%s\"\n",
 		       fw_name);
-		return err;
+		return;
 	}
 	if (fw->size < 2) {
 		pr_err("bogus length %zu in \"%s\"\n",
 		       fw->size, fw_name);
-		err = -EINVAL;
 		goto out;
 	}
 	cp->fw_load_addr= fw->data[1] << 8 | fw->data[0];
 	cp->fw_size = fw->size - 2;
 	cp->fw_data = vmalloc(cp->fw_size);
-	if (!cp->fw_data) {
-		err = -ENOMEM;
+	if (!cp->fw_data)
 		goto out;
-	}
 	memcpy(cp->fw_data, &fw->data[2], cp->fw_size);
 out:
 	release_firmware(fw);
-	return err;
 }
 
 static void cas_saturn_firmware_load(struct cas *cp)
 {
 	int i;
 
+	if (!cp->fw_data)
+		return;
+
 	cas_phy_powerdown(cp);
 
 	/* expanded memory access mode */
@@ -5083,8 +5082,7 @@ static int cas_init_one(struct pci_dev *
 	if (cas_check_invariants(cp))
 		goto err_out_iounmap;
 	if (cp->cas_flags & CAS_FLAG_SATURN)
-		if (cas_saturn_firmware_init(cp))
-			goto err_out_iounmap;
+		cas_saturn_firmware_init(cp);
 
 	cp->init_block = (struct cas_init_block *)
 		pci_alloc_consistent(pdev, sizeof(struct cas_init_block),
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sun/niu.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/niu.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sun/niu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/niu.c	2013-08-25 20:43:22.000000000 -0400
@@ -10108,7 +10108,7 @@ static int niu_of_probe(struct platform_
 		goto err_out_iounmap;
 	}
 
-	dev_set_drvdata(&op->dev, dev);
+	platform_set_drvdata(op, dev);
 
 	niu_device_announce(np);
 
@@ -10145,7 +10145,7 @@ err_out:
 
 static int niu_of_remove(struct platform_device *op)
 {
-	struct net_device *dev = dev_get_drvdata(&op->dev);
+	struct net_device *dev = platform_get_drvdata(op);
 
 	if (dev) {
 		struct niu *np = netdev_priv(dev);
@@ -10175,7 +10175,6 @@ static int niu_of_remove(struct platform
 		niu_put_parent(np);
 
 		free_netdev(dev);
-		dev_set_drvdata(&op->dev, NULL);
 	}
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sun/sunbmac.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sunbmac.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sun/sunbmac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sunbmac.c	2013-08-25 20:43:22.000000000 -0400
@@ -995,7 +995,6 @@ static void bigmac_set_multicast(struct
 	struct bigmac *bp = netdev_priv(dev);
 	void __iomem *bregs = bp->bregs;
 	struct netdev_hw_addr *ha;
-	int i;
 	u32 tmp, crc;
 
 	/* Disable the receiver.  The bit self-clears when
@@ -1017,10 +1016,7 @@ static void bigmac_set_multicast(struct
 		tmp |= BIGMAC_RXCFG_PMISC;
 		sbus_writel(tmp, bregs + BMAC_RXCFG);
 	} else {
-		u16 hash_table[4];
-
-		for (i = 0; i < 4; i++)
-			hash_table[i] = 0;
+		u16 hash_table[4] = { 0 };
 
 		netdev_for_each_mc_addr(ha, dev) {
 			crc = ether_crc_le(6, ha->addr);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sun/sungem.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sungem.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sun/sungem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sungem.c	2013-08-25 20:43:22.000000000 -0400
@@ -3028,15 +3028,4 @@ static struct pci_driver gem_driver = {
 #endif /* CONFIG_PM */
 };
 
-static int __init gem_init(void)
-{
-	return pci_register_driver(&gem_driver);
-}
-
-static void __exit gem_cleanup(void)
-{
-	pci_unregister_driver(&gem_driver);
-}
-
-module_init(gem_init);
-module_exit(gem_cleanup);
+module_pci_driver(gem_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sun/sunhme.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sunhme.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sun/sunhme.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sunhme.c	2013-08-25 20:43:22.000000000 -0400
@@ -2506,7 +2506,7 @@ static struct quattro *quattro_sbus_find
 	struct quattro *qp;
 
 	op = to_platform_device(parent);
-	qp = dev_get_drvdata(&op->dev);
+	qp = platform_get_drvdata(op);
 	if (qp)
 		return qp;
 
@@ -2521,7 +2521,7 @@ static struct quattro *quattro_sbus_find
 		qp->next = qfe_sbus_list;
 		qfe_sbus_list = qp;
 
-		dev_set_drvdata(&op->dev, qp);
+		platform_set_drvdata(op, qp);
 	}
 	return qp;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sun/sunqe.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sunqe.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sun/sunqe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sunqe.c	2013-08-25 20:43:22.000000000 -0400
@@ -767,7 +767,7 @@ static struct sunqec *get_qec(struct pla
 	struct platform_device *op = to_platform_device(child->dev.parent);
 	struct sunqec *qecp;
 
-	qecp = dev_get_drvdata(&op->dev);
+	qecp = platform_get_drvdata(op);
 	if (!qecp) {
 		qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL);
 		if (qecp) {
@@ -801,7 +801,7 @@ static struct sunqec *get_qec(struct pla
 				goto fail;
 			}
 
-			dev_set_drvdata(&op->dev, qecp);
+			platform_set_drvdata(op, qecp);
 
 			qecp->next_module = root_qec_dev;
 			root_qec_dev = qecp;
@@ -902,7 +902,7 @@ static int qec_ether_init(struct platfor
 	if (res)
 		goto fail;
 
-	dev_set_drvdata(&op->dev, qe);
+	platform_set_drvdata(op, qe);
 
 	printk(KERN_INFO "%s: qe channel[%d] %pM\n", dev->name, qe->channel,
 	       dev->dev_addr);
@@ -934,7 +934,7 @@ static int qec_sbus_probe(struct platfor
 
 static int qec_sbus_remove(struct platform_device *op)
 {
-	struct sunqe *qp = dev_get_drvdata(&op->dev);
+	struct sunqe *qp = platform_get_drvdata(op);
 	struct net_device *net_dev = qp->dev;
 
 	unregister_netdev(net_dev);
@@ -948,8 +948,6 @@ static int qec_sbus_remove(struct platfo
 
 	free_netdev(net_dev);
 
-	dev_set_drvdata(&op->dev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/sun/sunvnet.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sunvnet.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/sun/sunvnet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/sun/sunvnet.c	2013-08-25 20:43:22.000000000 -0400
@@ -1239,6 +1239,8 @@ static int vnet_port_remove(struct vio_d
 		dev_set_drvdata(&vdev->dev, NULL);
 
 		kfree(port);
+
+		unregister_netdev(vp->dev);
 	}
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ti/cpsw.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/cpsw.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ti/cpsw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/cpsw.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/if_vlan.h>
 
 #include <linux/platform_data/cpsw.h>
+#include <linux/pinctrl/consumer.h>
 
 #include "cpsw_ale.h"
 #include "cpts.h"
@@ -1554,6 +1555,8 @@ static int cpsw_probe_dt(struct cpsw_pla
 		if (mac_addr)
 			memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN);
 
+		slave_data->phy_if = of_get_phy_mode(slave_node);
+
 		if (data->dual_emac) {
 			if (of_property_read_u32(slave_node, "dual_emac_res_vlan",
 						 &prop)) {
@@ -1689,6 +1692,9 @@ static int cpsw_probe(struct platform_de
 	 */
 	pm_runtime_enable(&pdev->dev);
 
+	/* Select default pin state */
+	pinctrl_pm_select_default_state(&pdev->dev);
+
 	if (cpsw_probe_dt(&priv->data, pdev)) {
 		pr_err("cpsw: platform data missing\n");
 		ret = -ENODEV;
@@ -1698,10 +1704,10 @@ static int cpsw_probe(struct platform_de
 
 	if (is_valid_ether_addr(data->slave_data[0].mac_addr)) {
 		memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN);
-		pr_info("Detected MACID = %pM", priv->mac_addr);
+		pr_info("Detected MACID = %pM\n", priv->mac_addr);
 	} else {
 		eth_random_addr(priv->mac_addr);
-		pr_info("Random MACID = %pM", priv->mac_addr);
+		pr_info("Random MACID = %pM\n", priv->mac_addr);
 	}
 
 	memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN);
@@ -1861,7 +1867,7 @@ static int cpsw_probe(struct platform_de
 
 	while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) {
 		for (i = res->start; i <= res->end; i++) {
-			if (request_irq(i, cpsw_interrupt, IRQF_DISABLED,
+			if (request_irq(i, cpsw_interrupt, 0,
 					dev_name(&pdev->dev), priv)) {
 				dev_err(priv->dev, "error attaching irq\n");
 				goto clean_ale_ret;
@@ -1940,7 +1946,6 @@ static int cpsw_remove(struct platform_d
 	struct cpsw_priv *priv = netdev_priv(ndev);
 	int i;
 
-	platform_set_drvdata(pdev, NULL);
 	if (priv->data.dual_emac)
 		unregister_netdev(cpsw_get_slave_ndev(priv, 1));
 	unregister_netdev(ndev);
@@ -1981,6 +1986,9 @@ static int cpsw_suspend(struct device *d
 	soft_reset("sliver 1", &priv->slaves[1].sliver->soft_reset);
 	pm_runtime_put_sync(&pdev->dev);
 
+	/* Select sleep pin state */
+	pinctrl_pm_select_sleep_state(&pdev->dev);
+
 	return 0;
 }
 
@@ -1990,6 +1998,10 @@ static int cpsw_resume(struct device *de
 	struct net_device	*ndev = platform_get_drvdata(pdev);
 
 	pm_runtime_get_sync(&pdev->dev);
+
+	/* Select default pin state */
+	pinctrl_pm_select_default_state(&pdev->dev);
+
 	if (netif_running(ndev))
 		cpsw_ndo_open(ndev);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ti/davinci_cpdma.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/davinci_cpdma.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ti/davinci_cpdma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/davinci_cpdma.c	2013-08-25 20:43:22.000000000 -0400
@@ -64,6 +64,7 @@
 #define CPDMA_DESC_TO_PORT_EN	BIT(20)
 #define CPDMA_TO_PORT_SHIFT	16
 #define CPDMA_DESC_PORT_MASK	(BIT(18) | BIT(17) | BIT(16))
+#define CPDMA_DESC_CRC_LEN	4
 
 #define CPDMA_TEARDOWN_VALUE	0xfffffffc
 
@@ -805,6 +806,10 @@ static int __cpdma_chan_process(struct c
 		status = -EBUSY;
 		goto unlock_ret;
 	}
+
+	if (status & CPDMA_DESC_PASS_CRC)
+		outlen -= CPDMA_DESC_CRC_LEN;
+
 	status	= status & (CPDMA_DESC_EOQ | CPDMA_DESC_TD_COMPLETE |
 			    CPDMA_DESC_PORT_MASK);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ti/davinci_emac.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/davinci_emac.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ti/davinci_emac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/davinci_emac.c	2013-08-25 20:43:22.000000000 -0400
@@ -1532,7 +1532,7 @@ static int emac_dev_open(struct net_devi
 	struct device *emac_dev = &ndev->dev;
 	u32 cnt;
 	struct resource *res;
-	int q, m, ret;
+	int ret;
 	int i = 0;
 	int k = 0;
 	struct emac_priv *priv = netdev_priv(ndev);
@@ -1567,8 +1567,8 @@ static int emac_dev_open(struct net_devi
 
 	while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) {
 		for (i = res->start; i <= res->end; i++) {
-			if (request_irq(i, emac_irq, IRQF_DISABLED,
-					ndev->name, ndev))
+			if (devm_request_irq(&priv->pdev->dev, i, emac_irq,
+					     0, ndev->name, ndev))
 				goto rollback;
 		}
 		k++;
@@ -1641,15 +1641,7 @@ static int emac_dev_open(struct net_devi
 
 rollback:
 
-	dev_err(emac_dev, "DaVinci EMAC: request_irq() failed");
-
-	for (q = k; k >= 0; k--) {
-		for (m = i; m >= res->start; m--)
-			free_irq(m, ndev);
-		res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k-1);
-		m = res->end;
-	}
-
+	dev_err(emac_dev, "DaVinci EMAC: devm_request_irq() failed");
 	ret = -EBUSY;
 err:
 	pm_runtime_put(&priv->pdev->dev);
@@ -1667,9 +1659,6 @@ err:
  */
 static int emac_dev_stop(struct net_device *ndev)
 {
-	struct resource *res;
-	int i = 0;
-	int irq_num;
 	struct emac_priv *priv = netdev_priv(ndev);
 	struct device *emac_dev = &ndev->dev;
 
@@ -1685,13 +1674,6 @@ static int emac_dev_stop(struct net_devi
 	if (priv->phydev)
 		phy_disconnect(priv->phydev);
 
-	/* Free IRQ */
-	while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, i))) {
-		for (irq_num = res->start; irq_num <= res->end; irq_num++)
-			free_irq(irq_num, priv->ndev);
-		i++;
-	}
-
 	if (netif_msg_drv(priv))
 		dev_notice(emac_dev, "DaVinci EMAC: %s stopped\n", ndev->name);
 
@@ -1771,29 +1753,22 @@ static const struct net_device_ops emac_
 #endif
 };
 
-#ifdef CONFIG_OF
-static struct emac_platform_data
-	*davinci_emac_of_get_pdata(struct platform_device *pdev,
-	struct emac_priv *priv)
+static struct emac_platform_data *
+davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
 {
 	struct device_node *np;
 	struct emac_platform_data *pdata = NULL;
 	const u8 *mac_addr;
-	u32 data;
-	int ret;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-		if (!pdata)
-			goto nodata;
-	}
+	if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
+		return pdev->dev.platform_data;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
 
 	np = pdev->dev.of_node;
-	if (!np)
-		goto nodata;
-	else
-		pdata->version = EMAC_VERSION_2;
+	pdata->version = EMAC_VERSION_2;
 
 	if (!is_valid_ether_addr(pdata->mac_addr)) {
 		mac_addr = of_get_mac_address(np);
@@ -1801,47 +1776,31 @@ static struct emac_platform_data
 			memcpy(pdata->mac_addr, mac_addr, ETH_ALEN);
 	}
 
-	ret = of_property_read_u32(np, "ti,davinci-ctrl-reg-offset", &data);
-	if (!ret)
-		pdata->ctrl_reg_offset = data;
+	of_property_read_u32(np, "ti,davinci-ctrl-reg-offset",
+			     &pdata->ctrl_reg_offset);
 
-	ret = of_property_read_u32(np, "ti,davinci-ctrl-mod-reg-offset",
-		&data);
-	if (!ret)
-		pdata->ctrl_mod_reg_offset = data;
+	of_property_read_u32(np, "ti,davinci-ctrl-mod-reg-offset",
+			     &pdata->ctrl_mod_reg_offset);
 
-	ret = of_property_read_u32(np, "ti,davinci-ctrl-ram-offset", &data);
-	if (!ret)
-		pdata->ctrl_ram_offset = data;
+	of_property_read_u32(np, "ti,davinci-ctrl-ram-offset",
+			     &pdata->ctrl_ram_offset);
 
-	ret = of_property_read_u32(np, "ti,davinci-ctrl-ram-size", &data);
-	if (!ret)
-		pdata->ctrl_ram_size = data;
+	of_property_read_u32(np, "ti,davinci-ctrl-ram-size",
+			     &pdata->ctrl_ram_size);
 
-	ret = of_property_read_u32(np, "ti,davinci-rmii-en", &data);
-	if (!ret)
-		pdata->rmii_en = data;
+	of_property_read_u8(np, "ti,davinci-rmii-en", &pdata->rmii_en);
 
-	ret = of_property_read_u32(np, "ti,davinci-no-bd-ram", &data);
-	if (!ret)
-		pdata->no_bd_ram = data;
+	pdata->no_bd_ram = of_property_read_bool(np, "ti,davinci-no-bd-ram");
 
 	priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
 	if (!priv->phy_node)
 		pdata->phy_id = "";
 
 	pdev->dev.platform_data = pdata;
-nodata:
+
 	return  pdata;
 }
-#else
-static struct emac_platform_data
-	*davinci_emac_of_get_pdata(struct platform_device *pdev,
-	struct emac_priv *priv)
-{
-	return  pdev->dev.platform_data;
-}
-#endif
+
 /**
  * davinci_emac_probe - EMAC device probe
  * @pdev: The DaVinci EMAC device that we are removing
@@ -1856,7 +1815,7 @@ static int davinci_emac_probe(struct pla
 	struct resource *res;
 	struct net_device *ndev;
 	struct emac_priv *priv;
-	unsigned long size, hw_ram_addr;
+	unsigned long hw_ram_addr;
 	struct emac_platform_data *pdata;
 	struct device *emac_dev;
 	struct cpdma_params dma_params;
@@ -1907,25 +1866,10 @@ static int davinci_emac_probe(struct pla
 	emac_dev = &ndev->dev;
 	/* Get EMAC platform data */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev,"error getting res\n");
-		rc = -ENOENT;
-		goto no_pdata;
-	}
-
 	priv->emac_base_phys = res->start + pdata->ctrl_reg_offset;
-	size = resource_size(res);
-	if (!devm_request_mem_region(&pdev->dev, res->start,
-				     size, ndev->name)) {
-		dev_err(&pdev->dev, "failed request_mem_region() for regs\n");
-		rc = -ENXIO;
-		goto no_pdata;
-	}
-
-	priv->remap_addr = devm_ioremap(&pdev->dev, res->start, size);
-	if (!priv->remap_addr) {
-		dev_err(&pdev->dev, "unable to map IO\n");
-		rc = -ENOMEM;
+	priv->remap_addr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->remap_addr)) {
+		rc = PTR_ERR(priv->remap_addr);
 		goto no_pdata;
 	}
 	priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset;
@@ -2037,8 +1981,6 @@ static int davinci_emac_remove(struct pl
 
 	dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n");
 
-	platform_set_drvdata(pdev, NULL);
-
 	if (priv->txchan)
 		cpdma_chan_destroy(priv->txchan);
 	if (priv->rxchan)
@@ -2078,11 +2020,13 @@ static const struct dev_pm_ops davinci_e
 	.resume		= davinci_emac_resume,
 };
 
+#if IS_ENABLED(CONFIG_OF)
 static const struct of_device_id davinci_emac_of_match[] = {
 	{.compatible = "ti,davinci-dm6467-emac", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, davinci_emac_of_match);
+#endif
 
 /* davinci_emac_driver: EMAC platform driver structure */
 static struct platform_driver davinci_emac_driver = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ti/davinci_mdio.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/davinci_mdio.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ti/davinci_mdio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/davinci_mdio.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/davinci_emac.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
 
 /*
  * This timeout definition is a worst-case ultra defensive measure against
@@ -291,6 +292,7 @@ static int davinci_mdio_write(struct mii
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_OF)
 static int davinci_mdio_probe_dt(struct mdio_platform_data *data,
 			 struct platform_device *pdev)
 {
@@ -308,7 +310,7 @@ static int davinci_mdio_probe_dt(struct
 
 	return 0;
 }
-
+#endif
 
 static int davinci_mdio_probe(struct platform_device *pdev)
 {
@@ -347,6 +349,9 @@ static int davinci_mdio_probe(struct pla
 	data->bus->parent	= dev;
 	data->bus->priv		= data;
 
+	/* Select default pin state */
+	pinctrl_pm_select_default_state(&pdev->dev);
+
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 	data->clk = clk_get(&pdev->dev, "fck");
@@ -453,6 +458,9 @@ static int davinci_mdio_suspend(struct d
 	spin_unlock(&data->lock);
 	pm_runtime_put_sync(data->dev);
 
+	/* Select sleep pin state */
+	pinctrl_pm_select_sleep_state(dev);
+
 	return 0;
 }
 
@@ -460,6 +468,9 @@ static int davinci_mdio_resume(struct de
 {
 	struct davinci_mdio_data *data = dev_get_drvdata(dev);
 
+	/* Select default pin state */
+	pinctrl_pm_select_default_state(dev);
+
 	pm_runtime_get_sync(data->dev);
 
 	spin_lock(&data->lock);
@@ -477,11 +488,13 @@ static const struct dev_pm_ops davinci_m
 	.resume_early	= davinci_mdio_resume,
 };
 
+#if IS_ENABLED(CONFIG_OF)
 static const struct of_device_id davinci_mdio_of_mtable[] = {
 	{ .compatible = "ti,davinci_mdio", },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable);
+#endif
 
 static struct platform_driver davinci_mdio_driver = {
 	.driver = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ti/tlan.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/tlan.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/ti/tlan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/tlan.c	2013-08-25 20:43:22.000000000 -0400
@@ -372,7 +372,7 @@ static int tlan_resume(struct pci_dev *p
 
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
-	pci_enable_wake(pdev, 0, 0);
+	pci_enable_wake(pdev, PCI_D0, 0);
 	netif_device_attach(dev);
 
 	if (netif_running(dev))
@@ -533,7 +533,6 @@ static int tlan_probe1(struct pci_dev *p
 		/* This is a hack. We need to know which board structure
 		 * is suited for this adapter */
 		device_id = inw(ioaddr + EISA_ID2);
-		priv->is_eisa = 1;
 		if (device_id == 0x20F1) {
 			priv->adapter = &board_info[13]; /* NetFlex-3/E */
 			priv->adapter_rev = 23;		/* TLAN 2.3 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/ti/tlan.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/tlan.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/ti/tlan.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/ti/tlan.h	2013-08-25 20:43:22.000000000 -0400
@@ -207,7 +207,6 @@ struct tlan_priv {
 	u8			tlan_full_duplex;
 	spinlock_t		lock;
 	u8			link;
-	u8			is_eisa;
 	struct work_struct			tlan_tqueue;
 	u8			neg_be_verbose;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/toshiba/tc35815.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/toshiba/tc35815.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/toshiba/tc35815.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/toshiba/tc35815.c	2013-08-25 20:43:22.000000000 -0400
@@ -2209,18 +2209,6 @@ MODULE_PARM_DESC(speed, "0:auto, 10:10Mb
 module_param_named(duplex, options.duplex, int, 0);
 MODULE_PARM_DESC(duplex, "0:auto, 1:half, 2:full");
 
-static int __init tc35815_init_module(void)
-{
-	return pci_register_driver(&tc35815_pci_driver);
-}
-
-static void __exit tc35815_cleanup_module(void)
-{
-	pci_unregister_driver(&tc35815_pci_driver);
-}
-
-module_init(tc35815_init_module);
-module_exit(tc35815_cleanup_module);
-
+module_pci_driver(tc35815_pci_driver);
 MODULE_DESCRIPTION("TOSHIBA TC35815 PCI 10M/100M Ethernet driver");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/tundra/tsi108_eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/tundra/tsi108_eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/tundra/tsi108_eth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/tundra/tsi108_eth.c	2013-08-25 20:43:22.000000000 -0400
@@ -1682,7 +1682,6 @@ static int tsi108_ether_remove(struct pl
 
 	unregister_netdev(dev);
 	tsi108_stop_ethernet(dev);
-	platform_set_drvdata(pdev, NULL);
 	iounmap(priv->regs);
 	iounmap(priv->phyregs);
 	free_netdev(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/via/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/via/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/via/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/via/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,6 @@
 config NET_VENDOR_VIA
 	bool "VIA devices"
 	default y
-	depends on PCI
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y
 	  and read the Ethernet-HOWTO, available from
@@ -22,7 +21,6 @@ config VIA_RHINE
 	tristate "VIA Rhine support"
 	depends on PCI
 	select CRC32
-	select NET_CORE
 	select MII
 	---help---
 	  If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A),
@@ -45,10 +43,9 @@ config VIA_RHINE_MMIO
 
 config VIA_VELOCITY
 	tristate "VIA Velocity support"
-	depends on PCI
+	depends on (PCI || USE_OF)
 	select CRC32
 	select CRC_CCITT
-	select NET_CORE
 	select MII
 	---help---
 	  If you have a VIA "Velocity" based network card say Y here.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/via/via-rhine.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/via/via-rhine.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/via/via-rhine.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/via/via-rhine.c	2013-08-25 20:43:22.000000000 -0400
@@ -1171,7 +1171,11 @@ static void alloc_rbufs(struct net_devic
 		rp->rx_skbuff_dma[i] =
 			pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz,
 				       PCI_DMA_FROMDEVICE);
-
+		if (dma_mapping_error(&rp->pdev->dev, rp->rx_skbuff_dma[i])) {
+			rp->rx_skbuff_dma[i] = 0;
+			dev_kfree_skb(skb);
+			break;
+		}
 		rp->rx_ring[i].addr = cpu_to_le32(rp->rx_skbuff_dma[i]);
 		rp->rx_ring[i].rx_status = cpu_to_le32(DescOwn);
 	}
@@ -1687,6 +1691,12 @@ static netdev_tx_t rhine_start_tx(struct
 		rp->tx_skbuff_dma[entry] =
 			pci_map_single(rp->pdev, skb->data, skb->len,
 				       PCI_DMA_TODEVICE);
+		if (dma_mapping_error(&rp->pdev->dev, rp->tx_skbuff_dma[entry])) {
+			dev_kfree_skb(skb);
+			rp->tx_skbuff_dma[entry] = 0;
+			dev->stats.tx_dropped++;
+			return NETDEV_TX_OK;
+		}
 		rp->tx_ring[entry].addr = cpu_to_le32(rp->tx_skbuff_dma[entry]);
 	}
 
@@ -1961,6 +1971,11 @@ static int rhine_rx(struct net_device *d
 				pci_map_single(rp->pdev, skb->data,
 					       rp->rx_buf_sz,
 					       PCI_DMA_FROMDEVICE);
+			if (dma_mapping_error(&rp->pdev->dev, rp->rx_skbuff_dma[entry])) {
+				dev_kfree_skb(skb);
+				rp->rx_skbuff_dma[entry] = 0;
+				break;
+			}
 			rp->rx_ring[entry].addr = cpu_to_le32(rp->rx_skbuff_dma[entry]);
 		}
 		rp->rx_ring[entry].rx_status = cpu_to_le32(DescOwn);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/via/via-velocity.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/via/via-velocity.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/via/via-velocity.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/via/via-velocity.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,6 +46,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
+#include <linux/dma-mapping.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
@@ -64,7 +65,11 @@
 #include <linux/if.h>
 #include <linux/uaccess.h>
 #include <linux/proc_fs.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/inetdevice.h>
+#include <linux/platform_device.h>
 #include <linux/reboot.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
@@ -79,10 +84,24 @@
 
 #include "via-velocity.h"
 
+enum velocity_bus_type {
+	BUS_PCI,
+	BUS_PLATFORM,
+};
 
 static int velocity_nics;
 static int msglevel = MSG_LEVEL_INFO;
 
+static void velocity_set_power_state(struct velocity_info *vptr, char state)
+{
+	void *addr = vptr->mac_regs;
+
+	if (vptr->pdev)
+		pci_set_power_state(vptr->pdev, state);
+	else
+		writeb(state, addr + 0x154);
+}
+
 /**
  *	mac_get_cam_mask	-	Read a CAM mask
  *	@regs: register block for this velocity
@@ -361,12 +380,23 @@ static struct velocity_info_tbl chip_inf
  *	Describe the PCI device identifiers that we support in this
  *	device driver. Used for hotplug autoloading.
  */
-static DEFINE_PCI_DEVICE_TABLE(velocity_id_table) = {
+
+static DEFINE_PCI_DEVICE_TABLE(velocity_pci_id_table) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X) },
 	{ }
 };
 
-MODULE_DEVICE_TABLE(pci, velocity_id_table);
+MODULE_DEVICE_TABLE(pci, velocity_pci_id_table);
+
+/**
+ *	Describe the OF device identifiers that we support in this
+ *	device driver. Used for devicetree nodes.
+ */
+static struct of_device_id velocity_of_ids[] = {
+	{ .compatible = "via,velocity-vt6110", .data = &chip_info_table[0] },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, velocity_of_ids);
 
 /**
  *	get_chip_name	- 	identifier to name
@@ -385,29 +415,6 @@ static const char *get_chip_name(enum ch
 }
 
 /**
- *	velocity_remove1	-	device unplug
- *	@pdev: PCI device being removed
- *
- *	Device unload callback. Called on an unplug or on module
- *	unload for each active device that is present. Disconnects
- *	the device from the network layer and frees all the resources
- */
-static void velocity_remove1(struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct velocity_info *vptr = netdev_priv(dev);
-
-	unregister_netdev(dev);
-	iounmap(vptr->mac_regs);
-	pci_release_regions(pdev);
-	pci_disable_device(pdev);
-	pci_set_drvdata(pdev, NULL);
-	free_netdev(dev);
-
-	velocity_nics--;
-}
-
-/**
  *	velocity_set_int_opt	-	parser for integer options
  *	@opt: pointer to option value
  *	@val: value the user requested (or -1 for default)
@@ -998,9 +1005,9 @@ static void velocity_print_link_status(s
 {
 
 	if (vptr->mii_status & VELOCITY_LINK_FAIL) {
-		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->netdev->name);
 	} else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
-		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name);
+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->netdev->name);
 
 		if (vptr->mii_status & VELOCITY_SPEED_1000)
 			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
@@ -1014,7 +1021,7 @@ static void velocity_print_link_status(s
 		else
 			VELOCITY_PRT(MSG_LEVEL_INFO, " half duplex\n");
 	} else {
-		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name);
+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->netdev->name);
 		switch (vptr->options.spd_dpx) {
 		case SPD_DPX_1000_FULL:
 			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps full duplex\n");
@@ -1180,6 +1187,17 @@ static void mii_init(struct velocity_inf
 	u16 BMCR;
 
 	switch (PHYID_GET_PHY_ID(vptr->phy_id)) {
+	case PHYID_ICPLUS_IP101A:
+		MII_REG_BITS_ON((ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP),
+						MII_ADVERTISE, vptr->mac_regs);
+		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+			MII_REG_BITS_ON(TCSR_ECHODIS, MII_SREVISION,
+								vptr->mac_regs);
+		else
+			MII_REG_BITS_OFF(TCSR_ECHODIS, MII_SREVISION,
+								vptr->mac_regs);
+		MII_REG_BITS_ON(PLED_LALBE, MII_TPISTATUS, vptr->mac_regs);
+		break;
 	case PHYID_CICADA_CS8201:
 		/*
 		 *	Reset to hardware default
@@ -1311,6 +1329,7 @@ static void velocity_init_registers(stru
 				    enum velocity_init_type type)
 {
 	struct mac_regs __iomem *regs = vptr->mac_regs;
+	struct net_device *netdev = vptr->netdev;
 	int i, mii_status;
 
 	mac_wol_reset(regs);
@@ -1319,7 +1338,7 @@ static void velocity_init_registers(stru
 	case VELOCITY_INIT_RESET:
 	case VELOCITY_INIT_WOL:
 
-		netif_stop_queue(vptr->dev);
+		netif_stop_queue(netdev);
 
 		/*
 		 *	Reset RX to prevent RX pointer not on the 4X location
@@ -1332,7 +1351,7 @@ static void velocity_init_registers(stru
 		if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) {
 			velocity_print_link_status(vptr);
 			if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
-				netif_wake_queue(vptr->dev);
+				netif_wake_queue(netdev);
 		}
 
 		enable_flow_control_ability(vptr);
@@ -1352,9 +1371,11 @@ static void velocity_init_registers(stru
 		velocity_soft_reset(vptr);
 		mdelay(5);
 
-		mac_eeprom_reload(regs);
-		for (i = 0; i < 6; i++)
-			writeb(vptr->dev->dev_addr[i], &(regs->PAR[i]));
+		if (!vptr->no_eeprom) {
+			mac_eeprom_reload(regs);
+			for (i = 0; i < 6; i++)
+				writeb(netdev->dev_addr[i], regs->PAR + i);
+		}
 
 		/*
 		 *	clear Pre_ACPI bit.
@@ -1377,7 +1398,7 @@ static void velocity_init_registers(stru
 		/*
 		 *	Set packet filter: Receive directed and broadcast address
 		 */
-		velocity_set_multi(vptr->dev);
+		velocity_set_multi(netdev);
 
 		/*
 		 *	Enable MII auto-polling
@@ -1404,14 +1425,14 @@ static void velocity_init_registers(stru
 		writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), &regs->CR0Set);
 
 		mii_status = velocity_get_opt_media_mode(vptr);
-		netif_stop_queue(vptr->dev);
+		netif_stop_queue(netdev);
 
 		mii_init(vptr, mii_status);
 
 		if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) {
 			velocity_print_link_status(vptr);
 			if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
-				netif_wake_queue(vptr->dev);
+				netif_wake_queue(netdev);
 		}
 
 		enable_flow_control_ability(vptr);
@@ -1459,7 +1480,6 @@ static int velocity_init_dma_rings(struc
 	struct velocity_opt *opt = &vptr->options;
 	const unsigned int rx_ring_size = opt->numrx * sizeof(struct rx_desc);
 	const unsigned int tx_ring_size = opt->numtx * sizeof(struct tx_desc);
-	struct pci_dev *pdev = vptr->pdev;
 	dma_addr_t pool_dma;
 	void *pool;
 	unsigned int i;
@@ -1467,14 +1487,14 @@ static int velocity_init_dma_rings(struc
 	/*
 	 * Allocate all RD/TD rings a single pool.
 	 *
-	 * pci_alloc_consistent() fulfills the requirement for 64 bytes
+	 * dma_alloc_coherent() fulfills the requirement for 64 bytes
 	 * alignment
 	 */
-	pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->tx.numq +
-				    rx_ring_size, &pool_dma);
+	pool = dma_alloc_coherent(vptr->dev, tx_ring_size * vptr->tx.numq +
+				    rx_ring_size, &pool_dma, GFP_ATOMIC);
 	if (!pool) {
-		dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n",
-			vptr->dev->name);
+		dev_err(vptr->dev, "%s : DMA memory allocation failed.\n",
+			vptr->netdev->name);
 		return -ENOMEM;
 	}
 
@@ -1514,7 +1534,7 @@ static int velocity_alloc_rx_buf(struct
 	struct rx_desc *rd = &(vptr->rx.ring[idx]);
 	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
 
-	rd_info->skb = netdev_alloc_skb(vptr->dev, vptr->rx.buf_sz + 64);
+	rd_info->skb = netdev_alloc_skb(vptr->netdev, vptr->rx.buf_sz + 64);
 	if (rd_info->skb == NULL)
 		return -ENOMEM;
 
@@ -1524,8 +1544,8 @@ static int velocity_alloc_rx_buf(struct
 	 */
 	skb_reserve(rd_info->skb,
 			64 - ((unsigned long) rd_info->skb->data & 63));
-	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data,
-					vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
+	rd_info->skb_dma = dma_map_single(vptr->dev, rd_info->skb->data,
+					vptr->rx.buf_sz, DMA_FROM_DEVICE);
 
 	/*
 	 *	Fill in the descriptor to match
@@ -1588,8 +1608,8 @@ static void velocity_free_rd_ring(struct
 
 		if (!rd_info->skb)
 			continue;
-		pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
-				 PCI_DMA_FROMDEVICE);
+		dma_unmap_single(vptr->dev, rd_info->skb_dma, vptr->rx.buf_sz,
+				 DMA_FROM_DEVICE);
 		rd_info->skb_dma = 0;
 
 		dev_kfree_skb(rd_info->skb);
@@ -1620,7 +1640,7 @@ static int velocity_init_rd_ring(struct
 
 	if (velocity_rx_refill(vptr) != vptr->options.numrx) {
 		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
-			"%s: failed to allocate RX buffer.\n", vptr->dev->name);
+			"%s: failed to allocate RX buffer.\n", vptr->netdev->name);
 		velocity_free_rd_ring(vptr);
 		goto out;
 	}
@@ -1670,7 +1690,7 @@ static void velocity_free_dma_rings(stru
 	const int size = vptr->options.numrx * sizeof(struct rx_desc) +
 		vptr->options.numtx * sizeof(struct tx_desc) * vptr->tx.numq;
 
-	pci_free_consistent(vptr->pdev, size, vptr->rx.ring, vptr->rx.pool_dma);
+	dma_free_coherent(vptr->dev, size, vptr->rx.ring, vptr->rx.pool_dma);
 }
 
 static int velocity_init_rings(struct velocity_info *vptr, int mtu)
@@ -1727,8 +1747,8 @@ static void velocity_free_tx_buf(struct
 				pktlen = max_t(size_t, pktlen,
 						td->td_buf[i].size & ~TD_QUEUE);
 
-			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i],
-					le16_to_cpu(pktlen), PCI_DMA_TODEVICE);
+			dma_unmap_single(vptr->dev, tdinfo->skb_dma[i],
+					le16_to_cpu(pktlen), DMA_TO_DEVICE);
 		}
 	}
 	dev_kfree_skb_irq(skb);
@@ -1750,8 +1770,8 @@ static void velocity_free_td_ring_entry(
 	if (td_info->skb) {
 		for (i = 0; i < td_info->nskb_dma; i++) {
 			if (td_info->skb_dma[i]) {
-				pci_unmap_single(vptr->pdev, td_info->skb_dma[i],
-					td_info->skb->len, PCI_DMA_TODEVICE);
+				dma_unmap_single(vptr->dev, td_info->skb_dma[i],
+					td_info->skb->len, DMA_TO_DEVICE);
 				td_info->skb_dma[i] = 0;
 			}
 		}
@@ -1809,7 +1829,7 @@ static void velocity_error(struct veloci
 		printk(KERN_ERR "TD structure error TDindex=%hx\n", readw(&regs->TDIdx[0]));
 		BYTE_REG_BITS_ON(TXESR_TDSTR, &regs->TXESR);
 		writew(TRDCSR_RUN, &regs->TDCSRClr);
-		netif_stop_queue(vptr->dev);
+		netif_stop_queue(vptr->netdev);
 
 		/* FIXME: port over the pci_device_failed code and use it
 		   here */
@@ -1850,10 +1870,10 @@ static void velocity_error(struct veloci
 
 		if (linked) {
 			vptr->mii_status &= ~VELOCITY_LINK_FAIL;
-			netif_carrier_on(vptr->dev);
+			netif_carrier_on(vptr->netdev);
 		} else {
 			vptr->mii_status |= VELOCITY_LINK_FAIL;
-			netif_carrier_off(vptr->dev);
+			netif_carrier_off(vptr->netdev);
 		}
 
 		velocity_print_link_status(vptr);
@@ -1867,9 +1887,9 @@ static void velocity_error(struct veloci
 		enable_mii_autopoll(regs);
 
 		if (vptr->mii_status & VELOCITY_LINK_FAIL)
-			netif_stop_queue(vptr->dev);
+			netif_stop_queue(vptr->netdev);
 		else
-			netif_wake_queue(vptr->dev);
+			netif_wake_queue(vptr->netdev);
 
 	}
 	if (status & ISR_MIBFI)
@@ -1894,7 +1914,7 @@ static int velocity_tx_srv(struct veloci
 	int idx;
 	int works = 0;
 	struct velocity_td_info *tdinfo;
-	struct net_device_stats *stats = &vptr->dev->stats;
+	struct net_device_stats *stats = &vptr->netdev->stats;
 
 	for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
 		for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
@@ -1939,9 +1959,9 @@ static int velocity_tx_srv(struct veloci
 	 *	Look to see if we should kick the transmit network
 	 *	layer for more work.
 	 */
-	if (netif_queue_stopped(vptr->dev) && (full == 0) &&
+	if (netif_queue_stopped(vptr->netdev) && (full == 0) &&
 	    (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
-		netif_wake_queue(vptr->dev);
+		netif_wake_queue(vptr->netdev);
 	}
 	return works;
 }
@@ -1989,7 +2009,7 @@ static int velocity_rx_copy(struct sk_bu
 	if (pkt_size < rx_copybreak) {
 		struct sk_buff *new_skb;
 
-		new_skb = netdev_alloc_skb_ip_align(vptr->dev, pkt_size);
+		new_skb = netdev_alloc_skb_ip_align(vptr->netdev, pkt_size);
 		if (new_skb) {
 			new_skb->ip_summed = rx_skb[0]->ip_summed;
 			skb_copy_from_linear_data(*rx_skb, new_skb->data, pkt_size);
@@ -2029,15 +2049,14 @@ static inline void velocity_iph_realign(
  */
 static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 {
-	void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
-	struct net_device_stats *stats = &vptr->dev->stats;
+	struct net_device_stats *stats = &vptr->netdev->stats;
 	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
 	struct rx_desc *rd = &(vptr->rx.ring[idx]);
 	int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff;
 	struct sk_buff *skb;
 
 	if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
-		VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name);
+		VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->netdev->name);
 		stats->rx_length_errors++;
 		return -EINVAL;
 	}
@@ -2047,8 +2066,8 @@ static int velocity_receive_frame(struct
 
 	skb = rd_info->skb;
 
-	pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma,
-				    vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
+	dma_sync_single_for_cpu(vptr->dev, rd_info->skb_dma,
+				    vptr->rx.buf_sz, DMA_FROM_DEVICE);
 
 	/*
 	 *	Drop frame not meeting IEEE 802.3
@@ -2061,28 +2080,27 @@ static int velocity_receive_frame(struct
 		}
 	}
 
-	pci_action = pci_dma_sync_single_for_device;
-
 	velocity_rx_csum(rd, skb);
 
 	if (velocity_rx_copy(&skb, pkt_len, vptr) < 0) {
 		velocity_iph_realign(vptr, skb, pkt_len);
-		pci_action = pci_unmap_single;
 		rd_info->skb = NULL;
+		dma_unmap_single(vptr->dev, rd_info->skb_dma, vptr->rx.buf_sz,
+				 DMA_FROM_DEVICE);
+	} else {
+		dma_sync_single_for_device(vptr->dev, rd_info->skb_dma,
+					   vptr->rx.buf_sz, DMA_FROM_DEVICE);
 	}
 
-	pci_action(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
-		   PCI_DMA_FROMDEVICE);
-
 	skb_put(skb, pkt_len - 4);
-	skb->protocol = eth_type_trans(skb, vptr->dev);
+	skb->protocol = eth_type_trans(skb, vptr->netdev);
 
 	if (rd->rdesc0.RSR & RSR_DETAG) {
 		u16 vid = swab16(le16_to_cpu(rd->rdesc1.PQTAG));
 
 		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
 	}
-	netif_rx(skb);
+	netif_receive_skb(skb);
 
 	stats->rx_bytes += pkt_len;
 	stats->rx_packets++;
@@ -2100,7 +2118,7 @@ static int velocity_receive_frame(struct
  */
 static int velocity_rx_srv(struct velocity_info *vptr, int budget_left)
 {
-	struct net_device_stats *stats = &vptr->dev->stats;
+	struct net_device_stats *stats = &vptr->netdev->stats;
 	int rd_curr = vptr->rx.curr;
 	int works = 0;
 
@@ -2235,15 +2253,15 @@ static int velocity_open(struct net_devi
 		goto out;
 
 	/* Ensure chip is running */
-	pci_set_power_state(vptr->pdev, PCI_D0);
+	velocity_set_power_state(vptr, PCI_D0);
 
 	velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
-	ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED,
+	ret = request_irq(dev->irq, velocity_intr, IRQF_SHARED,
 			  dev->name, dev);
 	if (ret < 0) {
 		/* Power down the chip */
-		pci_set_power_state(vptr->pdev, PCI_D3hot);
+		velocity_set_power_state(vptr, PCI_D3hot);
 		velocity_free_rings(vptr);
 		goto out;
 	}
@@ -2292,7 +2310,7 @@ static int velocity_change_mtu(struct ne
 
 	if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) {
 		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
-				vptr->dev->name);
+				vptr->netdev->name);
 		ret = -EINVAL;
 		goto out_0;
 	}
@@ -2314,8 +2332,9 @@ static int velocity_change_mtu(struct ne
 			goto out_0;
 		}
 
-		tmp_vptr->dev = dev;
+		tmp_vptr->netdev = dev;
 		tmp_vptr->pdev = vptr->pdev;
+		tmp_vptr->dev = vptr->dev;
 		tmp_vptr->options = vptr->options;
 		tmp_vptr->tx.numq = vptr->tx.numq;
 
@@ -2415,7 +2434,7 @@ static int velocity_ioctl(struct net_dev
 	   saving then we need to bring the device back up to talk to it */
 
 	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D0);
+		velocity_set_power_state(vptr, PCI_D0);
 
 	switch (cmd) {
 	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
@@ -2428,7 +2447,7 @@ static int velocity_ioctl(struct net_dev
 		ret = -EOPNOTSUPP;
 	}
 	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D3hot);
+		velocity_set_power_state(vptr, PCI_D3hot);
 
 
 	return ret;
@@ -2494,7 +2513,7 @@ static int velocity_close(struct net_dev
 	if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED)
 		velocity_get_ip(vptr);
 
-	free_irq(vptr->pdev->irq, dev);
+	free_irq(dev->irq, dev);
 
 	velocity_free_rings(vptr);
 
@@ -2550,7 +2569,8 @@ static netdev_tx_t velocity_xmit(struct
 	 *	add it to the transmit ring.
 	 */
 	tdinfo->skb = skb;
-	tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
+	tdinfo->skb_dma[0] = dma_map_single(vptr->dev, skb->data, pktlen,
+								DMA_TO_DEVICE);
 	td_ptr->tdesc0.len = cpu_to_le16(pktlen);
 	td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
 	td_ptr->td_buf[0].pa_high = 0;
@@ -2560,7 +2580,7 @@ static netdev_tx_t velocity_xmit(struct
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
-		tdinfo->skb_dma[i + 1] = skb_frag_dma_map(&vptr->pdev->dev,
+		tdinfo->skb_dma[i + 1] = skb_frag_dma_map(vptr->dev,
 							  frag, 0,
 							  skb_frag_size(frag),
 							  DMA_TO_DEVICE);
@@ -2632,12 +2652,9 @@ static const struct net_device_ops veloc
  *	Set up the initial velocity_info struct for the device that has been
  *	discovered.
  */
-static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr,
-			       const struct velocity_info_tbl *info)
+static void velocity_init_info(struct velocity_info *vptr,
+				const struct velocity_info_tbl *info)
 {
-	memset(vptr, 0, sizeof(struct velocity_info));
-
-	vptr->pdev = pdev;
 	vptr->chip_id = info->chip_id;
 	vptr->tx.numq = info->txqueue;
 	vptr->multicast_limit = MCAM_SIZE;
@@ -2652,10 +2669,9 @@ static void velocity_init_info(struct pc
  *	Retrieve the PCI configuration space data that interests us from
  *	the kernel PCI layer
  */
-static int velocity_get_pci_info(struct velocity_info *vptr,
-				 struct pci_dev *pdev)
+static int velocity_get_pci_info(struct velocity_info *vptr)
 {
-	vptr->rev_id = pdev->revision;
+	struct pci_dev *pdev = vptr->pdev;
 
 	pci_set_master(pdev);
 
@@ -2678,7 +2694,37 @@ static int velocity_get_pci_info(struct
 		dev_err(&pdev->dev, "region #1 is too small.\n");
 		return -EINVAL;
 	}
-	vptr->pdev = pdev;
+
+	return 0;
+}
+
+/**
+ *	velocity_get_platform_info - retrieve platform info for device
+ *	@vptr: velocity device
+ *	@pdev: platform device it matches
+ *
+ *	Retrieve the Platform configuration data that interests us
+ */
+static int velocity_get_platform_info(struct velocity_info *vptr)
+{
+	struct resource res;
+	int ret;
+
+	if (of_get_property(vptr->dev->of_node, "no-eeprom", NULL))
+		vptr->no_eeprom = 1;
+
+	ret = of_address_to_resource(vptr->dev->of_node, 0, &res);
+	if (ret) {
+		dev_err(vptr->dev, "unable to find memory address\n");
+		return ret;
+	}
+
+	vptr->memaddr = res.start;
+
+	if (resource_size(&res) < VELOCITY_IO_SIZE) {
+		dev_err(vptr->dev, "memory region is too small.\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -2692,7 +2738,7 @@ static int velocity_get_pci_info(struct
  */
 static void velocity_print_info(struct velocity_info *vptr)
 {
-	struct net_device *dev = vptr->dev;
+	struct net_device *dev = vptr->netdev;
 
 	printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
 	printk(KERN_INFO "%s: Ethernet Address: %pM\n",
@@ -2707,21 +2753,22 @@ static u32 velocity_get_link(struct net_
 }
 
 /**
- *	velocity_found1		-	set up discovered velocity card
+ *	velocity_probe - set up discovered velocity device
  *	@pdev: PCI device
  *	@ent: PCI device table entry that matched
+ *	@bustype: bus that device is connected to
  *
  *	Configure a discovered adapter from scratch. Return a negative
  *	errno error code on failure paths.
  */
-static int velocity_found1(struct pci_dev *pdev,
-			   const struct pci_device_id *ent)
+static int velocity_probe(struct device *dev, int irq,
+			   const struct velocity_info_tbl *info,
+			   enum velocity_bus_type bustype)
 {
 	static int first = 1;
-	struct net_device *dev;
+	struct net_device *netdev;
 	int i;
 	const char *drv_string;
-	const struct velocity_info_tbl *info = &chip_info_table[ent->driver_data];
 	struct velocity_info *vptr;
 	struct mac_regs __iomem *regs;
 	int ret = -ENOMEM;
@@ -2730,20 +2777,18 @@ static int velocity_found1(struct pci_de
 	 * can support more than MAX_UNITS.
 	 */
 	if (velocity_nics >= MAX_UNITS) {
-		dev_notice(&pdev->dev, "already found %d NICs.\n",
-			   velocity_nics);
+		dev_notice(dev, "already found %d NICs.\n", velocity_nics);
 		return -ENODEV;
 	}
 
-	dev = alloc_etherdev(sizeof(struct velocity_info));
-	if (!dev)
+	netdev = alloc_etherdev(sizeof(struct velocity_info));
+	if (!netdev)
 		goto out;
 
 	/* Chain it all together */
 
-	SET_NETDEV_DEV(dev, &pdev->dev);
-	vptr = netdev_priv(dev);
-
+	SET_NETDEV_DEV(netdev, dev);
+	vptr = netdev_priv(netdev);
 
 	if (first) {
 		printk(KERN_INFO "%s Ver. %s\n",
@@ -2753,41 +2798,41 @@ static int velocity_found1(struct pci_de
 		first = 0;
 	}
 
-	velocity_init_info(pdev, vptr, info);
-
+	netdev->irq = irq;
+	vptr->netdev = netdev;
 	vptr->dev = dev;
 
-	ret = pci_enable_device(pdev);
-	if (ret < 0)
-		goto err_free_dev;
+	velocity_init_info(vptr, info);
 
-	ret = velocity_get_pci_info(vptr, pdev);
-	if (ret < 0) {
-		/* error message already printed */
-		goto err_disable;
-	}
+	if (bustype == BUS_PCI) {
+		vptr->pdev = to_pci_dev(dev);
 
-	ret = pci_request_regions(pdev, VELOCITY_NAME);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "No PCI resources.\n");
-		goto err_disable;
+		ret = velocity_get_pci_info(vptr);
+		if (ret < 0)
+			goto err_free_dev;
+	} else {
+		vptr->pdev = NULL;
+		ret = velocity_get_platform_info(vptr);
+		if (ret < 0)
+			goto err_free_dev;
 	}
 
 	regs = ioremap(vptr->memaddr, VELOCITY_IO_SIZE);
 	if (regs == NULL) {
 		ret = -EIO;
-		goto err_release_res;
+		goto err_free_dev;
 	}
 
 	vptr->mac_regs = regs;
+	vptr->rev_id = readb(&regs->rev_id);
 
 	mac_wol_reset(regs);
 
 	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = readb(&regs->PAR[i]);
+		netdev->dev_addr[i] = readb(&regs->PAR[i]);
 
 
-	drv_string = dev_driver_string(&pdev->dev);
+	drv_string = dev_driver_string(dev);
 
 	velocity_get_options(&vptr->options, velocity_nics, drv_string);
 
@@ -2808,46 +2853,127 @@ static int velocity_found1(struct pci_de
 
 	vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
 
-	dev->netdev_ops = &velocity_netdev_ops;
-	dev->ethtool_ops = &velocity_ethtool_ops;
-	netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
+	netdev->netdev_ops = &velocity_netdev_ops;
+	netdev->ethtool_ops = &velocity_ethtool_ops;
+	netif_napi_add(netdev, &vptr->napi, velocity_poll,
+							VELOCITY_NAPI_WEIGHT);
 
-	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+	netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
 			   NETIF_F_HW_VLAN_CTAG_TX;
-	dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_FILTER |
-			 NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_IP_CSUM;
+	netdev->features |= NETIF_F_HW_VLAN_CTAG_TX |
+			NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX |
+			NETIF_F_IP_CSUM;
 
-	ret = register_netdev(dev);
+	ret = register_netdev(netdev);
 	if (ret < 0)
 		goto err_iounmap;
 
-	if (!velocity_get_link(dev)) {
-		netif_carrier_off(dev);
+	if (!velocity_get_link(netdev)) {
+		netif_carrier_off(netdev);
 		vptr->mii_status |= VELOCITY_LINK_FAIL;
 	}
 
 	velocity_print_info(vptr);
-	pci_set_drvdata(pdev, dev);
+	dev_set_drvdata(vptr->dev, netdev);
 
 	/* and leave the chip powered down */
 
-	pci_set_power_state(pdev, PCI_D3hot);
+	velocity_set_power_state(vptr, PCI_D3hot);
 	velocity_nics++;
 out:
 	return ret;
 
 err_iounmap:
+	netif_napi_del(&vptr->napi);
 	iounmap(regs);
-err_release_res:
-	pci_release_regions(pdev);
-err_disable:
-	pci_disable_device(pdev);
 err_free_dev:
-	free_netdev(dev);
+	free_netdev(netdev);
 	goto out;
 }
 
-#ifdef CONFIG_PM
+/**
+ *	velocity_remove	- device unplug
+ *	@dev: device being removed
+ *
+ *	Device unload callback. Called on an unplug or on module
+ *	unload for each active device that is present. Disconnects
+ *	the device from the network layer and frees all the resources
+ */
+static int velocity_remove(struct device *dev)
+{
+	struct net_device *netdev = dev_get_drvdata(dev);
+	struct velocity_info *vptr = netdev_priv(netdev);
+
+	unregister_netdev(netdev);
+	netif_napi_del(&vptr->napi);
+	iounmap(vptr->mac_regs);
+	free_netdev(netdev);
+	velocity_nics--;
+
+	return 0;
+}
+
+static int velocity_pci_probe(struct pci_dev *pdev,
+			       const struct pci_device_id *ent)
+{
+	const struct velocity_info_tbl *info =
+					&chip_info_table[ent->driver_data];
+	int ret;
+
+	ret = pci_enable_device(pdev);
+	if (ret < 0)
+		return ret;
+
+	ret = pci_request_regions(pdev, VELOCITY_NAME);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "No PCI resources.\n");
+		goto fail1;
+	}
+
+	ret = velocity_probe(&pdev->dev, pdev->irq, info, BUS_PCI);
+	if (ret == 0)
+		return 0;
+
+	pci_release_regions(pdev);
+fail1:
+	pci_disable_device(pdev);
+	return ret;
+}
+
+static void velocity_pci_remove(struct pci_dev *pdev)
+{
+	velocity_remove(&pdev->dev);
+
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+static int velocity_platform_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *of_id;
+	const struct velocity_info_tbl *info;
+	int irq;
+
+	of_id = of_match_device(velocity_of_ids, &pdev->dev);
+	if (!of_id)
+		return -EINVAL;
+	info = of_id->data;
+
+	irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	if (!irq)
+		return -EINVAL;
+
+	return velocity_probe(&pdev->dev, irq, info, BUS_PLATFORM);
+}
+
+static int velocity_platform_remove(struct platform_device *pdev)
+{
+	velocity_remove(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
 /**
  *	wol_calc_crc		-	WOL CRC
  *	@pattern: data pattern
@@ -3004,32 +3130,35 @@ static void velocity_save_context(struct
 
 }
 
-static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
+static int velocity_suspend(struct device *dev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct velocity_info *vptr = netdev_priv(dev);
+	struct net_device *netdev = dev_get_drvdata(dev);
+	struct velocity_info *vptr = netdev_priv(netdev);
 	unsigned long flags;
 
-	if (!netif_running(vptr->dev))
+	if (!netif_running(vptr->netdev))
 		return 0;
 
-	netif_device_detach(vptr->dev);
+	netif_device_detach(vptr->netdev);
 
 	spin_lock_irqsave(&vptr->lock, flags);
-	pci_save_state(pdev);
+	if (vptr->pdev)
+		pci_save_state(vptr->pdev);
 
 	if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) {
 		velocity_get_ip(vptr);
 		velocity_save_context(vptr, &vptr->context);
 		velocity_shutdown(vptr);
 		velocity_set_wol(vptr);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_set_power_state(pdev, PCI_D3hot);
+		if (vptr->pdev)
+			pci_enable_wake(vptr->pdev, PCI_D3hot, 1);
+		velocity_set_power_state(vptr, PCI_D3hot);
 	} else {
 		velocity_save_context(vptr, &vptr->context);
 		velocity_shutdown(vptr);
-		pci_disable_device(pdev);
-		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+		if (vptr->pdev)
+			pci_disable_device(vptr->pdev);
+		velocity_set_power_state(vptr, PCI_D3hot);
 	}
 
 	spin_unlock_irqrestore(&vptr->lock, flags);
@@ -3071,19 +3200,22 @@ static void velocity_restore_context(str
 		writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
 }
 
-static int velocity_resume(struct pci_dev *pdev)
+static int velocity_resume(struct device *dev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct velocity_info *vptr = netdev_priv(dev);
+	struct net_device *netdev = dev_get_drvdata(dev);
+	struct velocity_info *vptr = netdev_priv(netdev);
 	unsigned long flags;
 	int i;
 
-	if (!netif_running(vptr->dev))
+	if (!netif_running(vptr->netdev))
 		return 0;
 
-	pci_set_power_state(pdev, PCI_D0);
-	pci_enable_wake(pdev, 0, 0);
-	pci_restore_state(pdev);
+	velocity_set_power_state(vptr, PCI_D0);
+
+	if (vptr->pdev) {
+		pci_enable_wake(vptr->pdev, PCI_D0, 0);
+		pci_restore_state(vptr->pdev);
+	}
 
 	mac_wol_reset(vptr->mac_regs);
 
@@ -3101,27 +3233,38 @@ static int velocity_resume(struct pci_de
 
 	mac_enable_int(vptr->mac_regs);
 	spin_unlock_irqrestore(&vptr->lock, flags);
-	netif_device_attach(vptr->dev);
+	netif_device_attach(vptr->netdev);
 
 	return 0;
 }
-#endif
+#endif	/* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(velocity_pm_ops, velocity_suspend, velocity_resume);
 
 /*
  *	Definition for our device driver. The PCI layer interface
  *	uses this to handle all our card discover and plugging
  */
-static struct pci_driver velocity_driver = {
+static struct pci_driver velocity_pci_driver = {
 	.name		= VELOCITY_NAME,
-	.id_table	= velocity_id_table,
-	.probe		= velocity_found1,
-	.remove		= velocity_remove1,
-#ifdef CONFIG_PM
-	.suspend	= velocity_suspend,
-	.resume		= velocity_resume,
-#endif
+	.id_table	= velocity_pci_id_table,
+	.probe		= velocity_pci_probe,
+	.remove		= velocity_pci_remove,
+	.driver = {
+		.pm = &velocity_pm_ops,
+	},
 };
 
+static struct platform_driver velocity_platform_driver = {
+	.probe		= velocity_platform_probe,
+	.remove		= velocity_platform_remove,
+	.driver = {
+		.name = "via-velocity",
+		.owner = THIS_MODULE,
+		.of_match_table = velocity_of_ids,
+		.pm = &velocity_pm_ops,
+	},
+};
 
 /**
  *	velocity_ethtool_up	-	pre hook for ethtool
@@ -3134,7 +3277,7 @@ static int velocity_ethtool_up(struct ne
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D0);
+		velocity_set_power_state(vptr, PCI_D0);
 	return 0;
 }
 
@@ -3149,7 +3292,7 @@ static void velocity_ethtool_down(struct
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D3hot);
+		velocity_set_power_state(vptr, PCI_D3hot);
 }
 
 static int velocity_get_settings(struct net_device *dev,
@@ -3269,9 +3412,14 @@ static int velocity_set_settings(struct
 static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
+
 	strlcpy(info->driver, VELOCITY_NAME, sizeof(info->driver));
 	strlcpy(info->version, VELOCITY_VERSION, sizeof(info->version));
-	strlcpy(info->bus_info, pci_name(vptr->pdev), sizeof(info->bus_info));
+	if (vptr->pdev)
+		strlcpy(info->bus_info, pci_name(vptr->pdev),
+						sizeof(info->bus_info));
+	else
+		strlcpy(info->bus_info, "platform", sizeof(info->bus_info));
 }
 
 static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
@@ -3561,13 +3709,20 @@ static void velocity_unregister_notifier
  */
 static int __init velocity_init_module(void)
 {
-	int ret;
+	int ret_pci, ret_platform;
 
 	velocity_register_notifier();
-	ret = pci_register_driver(&velocity_driver);
-	if (ret < 0)
+
+	ret_pci = pci_register_driver(&velocity_pci_driver);
+	ret_platform = platform_driver_register(&velocity_platform_driver);
+
+	/* if both_registers failed, remove the notifier */
+	if ((ret_pci < 0) && (ret_platform < 0)) {
 		velocity_unregister_notifier();
-	return ret;
+		return ret_pci;
+	}
+
+	return 0;
 }
 
 /**
@@ -3581,7 +3736,9 @@ static int __init velocity_init_module(v
 static void __exit velocity_cleanup_module(void)
 {
 	velocity_unregister_notifier();
-	pci_unregister_driver(&velocity_driver);
+
+	pci_unregister_driver(&velocity_pci_driver);
+	platform_driver_unregister(&velocity_platform_driver);
 }
 
 module_init(velocity_init_module);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/via/via-velocity.h linux-libre-3.11-rc7-gnu/drivers/net/ethernet/via/via-velocity.h
--- linux-libre-3.10-gnu/drivers/net/ethernet/via/via-velocity.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/via/via-velocity.h	2013-08-25 20:43:22.000000000 -0400
@@ -1265,7 +1265,7 @@ struct velocity_context {
 #define PHYID_VT3216_64BIT  0x000FC600UL
 #define PHYID_MARVELL_1000  0x01410C50UL
 #define PHYID_MARVELL_1000S 0x01410C40UL
-
+#define PHYID_ICPLUS_IP101A 0x02430C54UL
 #define PHYID_REV_ID_MASK   0x0000000FUL
 
 #define PHYID_GET_PHY_ID(i)         ((i) & ~PHYID_REV_ID_MASK)
@@ -1434,8 +1434,10 @@ struct velocity_opt {
 #define GET_RD_BY_IDX(vptr, idx)   (vptr->rd_ring[idx])
 
 struct velocity_info {
+	struct device *dev;
 	struct pci_dev *pdev;
-	struct net_device *dev;
+	struct net_device *netdev;
+	int no_eeprom;
 
 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
 	u8 ip_addr[4];
@@ -1514,7 +1516,7 @@ static inline int velocity_get_ip(struct
 	int res = -ENOENT;
 
 	rcu_read_lock();
-	in_dev = __in_dev_get_rcu(vptr->dev);
+	in_dev = __in_dev_get_rcu(vptr->netdev);
 	if (in_dev != NULL) {
 		ifa = (struct in_ifaddr *) in_dev->ifa_list;
 		if (ifa != NULL) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/wiznet/w5100.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/wiznet/w5100.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/wiznet/w5100.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/wiznet/w5100.c	2013-08-25 20:43:22.000000000 -0400
@@ -734,7 +734,6 @@ err_hw_probe:
 	unregister_netdev(ndev);
 err_register:
 	free_netdev(ndev);
-	platform_set_drvdata(pdev, NULL);
 	return err;
 }
 
@@ -750,7 +749,6 @@ static int w5100_remove(struct platform_
 
 	unregister_netdev(ndev);
 	free_netdev(ndev);
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/wiznet/w5300.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/wiznet/w5300.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/wiznet/w5300.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/wiznet/w5300.c	2013-08-25 20:43:22.000000000 -0400
@@ -646,7 +646,6 @@ err_hw_probe:
 	unregister_netdev(ndev);
 err_register:
 	free_netdev(ndev);
-	platform_set_drvdata(pdev, NULL);
 	return err;
 }
 
@@ -662,7 +661,6 @@ static int w5300_remove(struct platform_
 
 	unregister_netdev(ndev);
 	free_netdev(ndev);
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/xilinx/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xilinx/Kconfig
--- linux-libre-3.10-gnu/drivers/net/ethernet/xilinx/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xilinx/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,7 @@
 config NET_VENDOR_XILINX
 	bool "Xilinx devices"
 	default y
-	depends on PPC || PPC32 || MICROBLAZE
+	depends on PPC || PPC32 || MICROBLAZE || ARCH_ZYNQ
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y
 	  and read the Ethernet-HOWTO, available from
@@ -20,7 +20,7 @@ if NET_VENDOR_XILINX
 
 config XILINX_EMACLITE
 	tristate "Xilinx 10/100 Ethernet Lite support"
-	depends on (PPC32 || MICROBLAZE)
+	depends on (PPC32 || MICROBLAZE || ARCH_ZYNQ)
 	select PHYLIB
 	---help---
 	  This driver supports the 10/100 Ethernet Lite from Xilinx.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/xilinx/ll_temac_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xilinx/ll_temac_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/xilinx/ll_temac_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xilinx/ll_temac_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1007,7 +1007,7 @@ static int temac_of_probe(struct platfor
 		return -ENOMEM;
 
 	ether_setup(ndev);
-	dev_set_drvdata(&op->dev, ndev);
+	platform_set_drvdata(op, ndev);
 	SET_NETDEV_DEV(ndev, &op->dev);
 	ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
 	ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
@@ -1136,7 +1136,7 @@ static int temac_of_probe(struct platfor
 
 static int temac_of_remove(struct platform_device *op)
 {
-	struct net_device *ndev = dev_get_drvdata(&op->dev);
+	struct net_device *ndev = platform_get_drvdata(op);
 	struct temac_local *lp = netdev_priv(ndev);
 
 	temac_mdio_teardown(lp);
@@ -1145,7 +1145,6 @@ static int temac_of_remove(struct platfo
 	if (lp->phy_node)
 		of_node_put(lp->phy_node);
 	lp->phy_node = NULL;
-	dev_set_drvdata(&op->dev, NULL);
 	iounmap(lp->regs);
 	if (lp->sdma_regs)
 		iounmap(lp->sdma_regs);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/xilinx/xilinx_axienet_main.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/xilinx/xilinx_axienet_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xilinx/xilinx_axienet_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1484,7 +1484,7 @@ static int axienet_of_probe(struct platf
 		return -ENOMEM;
 
 	ether_setup(ndev);
-	dev_set_drvdata(&op->dev, ndev);
+	platform_set_drvdata(op, ndev);
 
 	SET_NETDEV_DEV(ndev, &op->dev);
 	ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
@@ -1622,7 +1622,7 @@ nodev:
 
 static int axienet_of_remove(struct platform_device *op)
 {
-	struct net_device *ndev = dev_get_drvdata(&op->dev);
+	struct net_device *ndev = platform_get_drvdata(op);
 	struct axienet_local *lp = netdev_priv(ndev);
 
 	axienet_mdio_teardown(lp);
@@ -1632,8 +1632,6 @@ static int axienet_of_remove(struct plat
 		of_node_put(lp->phy_node);
 	lp->phy_node = NULL;
 
-	dev_set_drvdata(&op->dev, NULL);
-
 	iounmap(lp->regs);
 	if (lp->dma_regs)
 		iounmap(lp->dma_regs);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/xilinx/xilinx_emaclite.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xilinx/xilinx_emaclite.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/xilinx/xilinx_emaclite.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xilinx/xilinx_emaclite.c	2013-08-25 20:43:22.000000000 -0400
@@ -2,9 +2,9 @@
  * Xilinx EmacLite Linux driver for the Xilinx Ethernet MAC Lite device.
  *
  * This is a new flat driver which is based on the original emac_lite
- * driver from John Williams <john.williams@petalogix.com>.
+ * driver from John Williams <john.williams@xilinx.com>.
  *
- * 2007-2009 (c) Xilinx, Inc.
+ * 2007 - 2013 (c) Xilinx, Inc.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -159,34 +159,32 @@ static void xemaclite_enable_interrupts(
 	u32 reg_data;
 
 	/* Enable the Tx interrupts for the first Buffer */
-	reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET);
-	out_be32(drvdata->base_addr + XEL_TSR_OFFSET,
-		 reg_data | XEL_TSR_XMIT_IE_MASK);
+	reg_data = __raw_readl(drvdata->base_addr + XEL_TSR_OFFSET);
+	__raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK,
+		     drvdata->base_addr + XEL_TSR_OFFSET);
 
 	/* Enable the Tx interrupts for the second Buffer if
 	 * configured in HW */
 	if (drvdata->tx_ping_pong != 0) {
-		reg_data = in_be32(drvdata->base_addr +
+		reg_data = __raw_readl(drvdata->base_addr +
 				   XEL_BUFFER_OFFSET + XEL_TSR_OFFSET);
-		out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
-			 XEL_TSR_OFFSET,
-			 reg_data | XEL_TSR_XMIT_IE_MASK);
+		__raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK,
+			     drvdata->base_addr + XEL_BUFFER_OFFSET +
+			     XEL_TSR_OFFSET);
 	}
 
 	/* Enable the Rx interrupts for the first buffer */
-	out_be32(drvdata->base_addr + XEL_RSR_OFFSET,
-		 XEL_RSR_RECV_IE_MASK);
+	__raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET);
 
 	/* Enable the Rx interrupts for the second Buffer if
 	 * configured in HW */
 	if (drvdata->rx_ping_pong != 0) {
-		out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
-			 XEL_RSR_OFFSET,
-			 XEL_RSR_RECV_IE_MASK);
+		__raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr +
+			     XEL_BUFFER_OFFSET + XEL_RSR_OFFSET);
 	}
 
 	/* Enable the Global Interrupt Enable */
-	out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK);
+	__raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET);
 }
 
 /**
@@ -201,37 +199,37 @@ static void xemaclite_disable_interrupts
 	u32 reg_data;
 
 	/* Disable the Global Interrupt Enable */
-	out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK);
+	__raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET);
 
 	/* Disable the Tx interrupts for the first buffer */
-	reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET);
-	out_be32(drvdata->base_addr + XEL_TSR_OFFSET,
-		 reg_data & (~XEL_TSR_XMIT_IE_MASK));
+	reg_data = __raw_readl(drvdata->base_addr + XEL_TSR_OFFSET);
+	__raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK),
+		     drvdata->base_addr + XEL_TSR_OFFSET);
 
 	/* Disable the Tx interrupts for the second Buffer
 	 * if configured in HW */
 	if (drvdata->tx_ping_pong != 0) {
-		reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
+		reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET +
 				   XEL_TSR_OFFSET);
-		out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
-			 XEL_TSR_OFFSET,
-			 reg_data & (~XEL_TSR_XMIT_IE_MASK));
+		__raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK),
+			     drvdata->base_addr + XEL_BUFFER_OFFSET +
+			     XEL_TSR_OFFSET);
 	}
 
 	/* Disable the Rx interrupts for the first buffer */
-	reg_data = in_be32(drvdata->base_addr + XEL_RSR_OFFSET);
-	out_be32(drvdata->base_addr + XEL_RSR_OFFSET,
-		 reg_data & (~XEL_RSR_RECV_IE_MASK));
+	reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET);
+	__raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK),
+		     drvdata->base_addr + XEL_RSR_OFFSET);
 
 	/* Disable the Rx interrupts for the second buffer
 	 * if configured in HW */
 	if (drvdata->rx_ping_pong != 0) {
 
-		reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
+		reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET +
 				   XEL_RSR_OFFSET);
-		out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
-			 XEL_RSR_OFFSET,
-			 reg_data & (~XEL_RSR_RECV_IE_MASK));
+		__raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK),
+			     drvdata->base_addr + XEL_BUFFER_OFFSET +
+			     XEL_RSR_OFFSET);
 	}
 }
 
@@ -351,7 +349,7 @@ static int xemaclite_send_data(struct ne
 		byte_count = ETH_FRAME_LEN;
 
 	/* Check if the expected buffer is available */
-	reg_data = in_be32(addr + XEL_TSR_OFFSET);
+	reg_data = __raw_readl(addr + XEL_TSR_OFFSET);
 	if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK |
 	     XEL_TSR_XMIT_ACTIVE_MASK)) == 0) {
 
@@ -364,7 +362,7 @@ static int xemaclite_send_data(struct ne
 
 		addr = (void __iomem __force *)((u32 __force)addr ^
 						 XEL_BUFFER_OFFSET);
-		reg_data = in_be32(addr + XEL_TSR_OFFSET);
+		reg_data = __raw_readl(addr + XEL_TSR_OFFSET);
 
 		if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK |
 		     XEL_TSR_XMIT_ACTIVE_MASK)) != 0)
@@ -375,15 +373,16 @@ static int xemaclite_send_data(struct ne
 	/* Write the frame to the buffer */
 	xemaclite_aligned_write(data, (u32 __force *) addr, byte_count);
 
-	out_be32(addr + XEL_TPLR_OFFSET, (byte_count & XEL_TPLR_LENGTH_MASK));
+	__raw_writel((byte_count & XEL_TPLR_LENGTH_MASK),
+		     addr + XEL_TPLR_OFFSET);
 
 	/* Update the Tx Status Register to indicate that there is a
 	 * frame to send. Set the XEL_TSR_XMIT_ACTIVE_MASK flag which
 	 * is used by the interrupt handler to check whether a frame
 	 * has been transmitted */
-	reg_data = in_be32(addr + XEL_TSR_OFFSET);
+	reg_data = __raw_readl(addr + XEL_TSR_OFFSET);
 	reg_data |= (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK);
-	out_be32(addr + XEL_TSR_OFFSET, reg_data);
+	__raw_writel(reg_data, addr + XEL_TSR_OFFSET);
 
 	return 0;
 }
@@ -408,7 +407,7 @@ static u16 xemaclite_recv_data(struct ne
 	addr = (drvdata->base_addr + drvdata->next_rx_buf_to_use);
 
 	/* Verify which buffer has valid data */
-	reg_data = in_be32(addr + XEL_RSR_OFFSET);
+	reg_data = __raw_readl(addr + XEL_RSR_OFFSET);
 
 	if ((reg_data & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
 		if (drvdata->rx_ping_pong != 0)
@@ -425,14 +424,14 @@ static u16 xemaclite_recv_data(struct ne
 			return 0;	/* No data was available */
 
 		/* Verify that buffer has valid data */
-		reg_data = in_be32(addr + XEL_RSR_OFFSET);
+		reg_data = __raw_readl(addr + XEL_RSR_OFFSET);
 		if ((reg_data & XEL_RSR_RECV_DONE_MASK) !=
 		     XEL_RSR_RECV_DONE_MASK)
 			return 0;	/* No data was available */
 	}
 
 	/* Get the protocol type of the ethernet frame that arrived */
-	proto_type = ((ntohl(in_be32(addr + XEL_HEADER_OFFSET +
+	proto_type = ((ntohl(__raw_readl(addr + XEL_HEADER_OFFSET +
 			XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) &
 			XEL_RPLR_LENGTH_MASK);
 
@@ -441,7 +440,7 @@ static u16 xemaclite_recv_data(struct ne
 	if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
 
 		if (proto_type == ETH_P_IP) {
-			length = ((ntohl(in_be32(addr +
+			length = ((ntohl(__raw_readl(addr +
 					XEL_HEADER_IP_LENGTH_OFFSET +
 					XEL_RXBUFF_OFFSET)) >>
 					XEL_HEADER_SHIFT) &
@@ -463,9 +462,9 @@ static u16 xemaclite_recv_data(struct ne
 				data, length);
 
 	/* Acknowledge the frame */
-	reg_data = in_be32(addr + XEL_RSR_OFFSET);
+	reg_data = __raw_readl(addr + XEL_RSR_OFFSET);
 	reg_data &= ~XEL_RSR_RECV_DONE_MASK;
-	out_be32(addr + XEL_RSR_OFFSET, reg_data);
+	__raw_writel(reg_data, addr + XEL_RSR_OFFSET);
 
 	return length;
 }
@@ -492,14 +491,14 @@ static void xemaclite_update_address(str
 
 	xemaclite_aligned_write(address_ptr, (u32 __force *) addr, ETH_ALEN);
 
-	out_be32(addr + XEL_TPLR_OFFSET, ETH_ALEN);
+	__raw_writel(ETH_ALEN, addr + XEL_TPLR_OFFSET);
 
 	/* Update the MAC address in the EmacLite */
-	reg_data = in_be32(addr + XEL_TSR_OFFSET);
-	out_be32(addr + XEL_TSR_OFFSET, reg_data | XEL_TSR_PROG_MAC_ADDR);
+	reg_data = __raw_readl(addr + XEL_TSR_OFFSET);
+	__raw_writel(reg_data | XEL_TSR_PROG_MAC_ADDR, addr + XEL_TSR_OFFSET);
 
 	/* Wait for EmacLite to finish with the MAC address update */
-	while ((in_be32(addr + XEL_TSR_OFFSET) &
+	while ((__raw_readl(addr + XEL_TSR_OFFSET) &
 		XEL_TSR_PROG_MAC_ADDR) != 0)
 		;
 }
@@ -669,31 +668,32 @@ static irqreturn_t xemaclite_interrupt(i
 	u32 tx_status;
 
 	/* Check if there is Rx Data available */
-	if ((in_be32(base_addr + XEL_RSR_OFFSET) & XEL_RSR_RECV_DONE_MASK) ||
-			(in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET)
+	if ((__raw_readl(base_addr + XEL_RSR_OFFSET) &
+			 XEL_RSR_RECV_DONE_MASK) ||
+	    (__raw_readl(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET)
 			 & XEL_RSR_RECV_DONE_MASK))
 
 		xemaclite_rx_handler(dev);
 
 	/* Check if the Transmission for the first buffer is completed */
-	tx_status = in_be32(base_addr + XEL_TSR_OFFSET);
+	tx_status = __raw_readl(base_addr + XEL_TSR_OFFSET);
 	if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) &&
 		(tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) {
 
 		tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK;
-		out_be32(base_addr + XEL_TSR_OFFSET, tx_status);
+		__raw_writel(tx_status, base_addr + XEL_TSR_OFFSET);
 
 		tx_complete = true;
 	}
 
 	/* Check if the Transmission for the second buffer is completed */
-	tx_status = in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET);
+	tx_status = __raw_readl(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET);
 	if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) &&
 		(tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) {
 
 		tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK;
-		out_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET,
-			 tx_status);
+		__raw_writel(tx_status, base_addr + XEL_BUFFER_OFFSET +
+			     XEL_TSR_OFFSET);
 
 		tx_complete = true;
 	}
@@ -726,7 +726,7 @@ static int xemaclite_mdio_wait(struct ne
 	/* wait for the MDIO interface to not be busy or timeout
 	   after some time.
 	*/
-	while (in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET) &
+	while (__raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) &
 			XEL_MDIOCTRL_MDIOSTS_MASK) {
 		if (end - jiffies <= 0) {
 			WARN_ON(1);
@@ -762,17 +762,17 @@ static int xemaclite_mdio_read(struct mi
 	 * MDIO Address register. Set the Status bit in the MDIO Control
 	 * register to start a MDIO read transaction.
 	 */
-	ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET);
-	out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET,
-		 XEL_MDIOADDR_OP_MASK |
-		 ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg));
-	out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET,
-		 ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
+	ctrl_reg = __raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET);
+	__raw_writel(XEL_MDIOADDR_OP_MASK |
+		     ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg),
+		     lp->base_addr + XEL_MDIOADDR_OFFSET);
+	__raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK,
+		     lp->base_addr + XEL_MDIOCTRL_OFFSET);
 
 	if (xemaclite_mdio_wait(lp))
 		return -ETIMEDOUT;
 
-	rc = in_be32(lp->base_addr + XEL_MDIORD_OFFSET);
+	rc = __raw_readl(lp->base_addr + XEL_MDIORD_OFFSET);
 
 	dev_dbg(&lp->ndev->dev,
 		"xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n",
@@ -809,13 +809,13 @@ static int xemaclite_mdio_write(struct m
 	 * Data register. Finally, set the Status bit in the MDIO Control
 	 * register to start a MDIO write transaction.
 	 */
-	ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET);
-	out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET,
-		 ~XEL_MDIOADDR_OP_MASK &
-		 ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg));
-	out_be32(lp->base_addr + XEL_MDIOWR_OFFSET, val);
-	out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET,
-		 ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
+	ctrl_reg = __raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET);
+	__raw_writel(~XEL_MDIOADDR_OP_MASK &
+		     ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg),
+		     lp->base_addr + XEL_MDIOADDR_OFFSET);
+	__raw_writel(val, lp->base_addr + XEL_MDIOWR_OFFSET);
+	__raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK,
+		     lp->base_addr + XEL_MDIOCTRL_OFFSET);
 
 	return 0;
 }
@@ -848,24 +848,39 @@ static int xemaclite_mdio_setup(struct n
 	int rc;
 	struct resource res;
 	struct device_node *np = of_get_parent(lp->phy_node);
+	struct device_node *npp;
 
 	/* Don't register the MDIO bus if the phy_node or its parent node
 	 * can't be found.
 	 */
-	if (!np)
+	if (!np) {
+		dev_err(dev, "Failed to register mdio bus.\n");
 		return -ENODEV;
+	}
+	npp = of_get_parent(np);
+
+	of_address_to_resource(npp, 0, &res);
+	if (lp->ndev->mem_start != res.start) {
+		struct phy_device *phydev;
+		phydev = of_phy_find_device(lp->phy_node);
+		if (!phydev)
+			dev_info(dev,
+				 "MDIO of the phy is not registered yet\n");
+		return 0;
+	}
 
 	/* Enable the MDIO bus by asserting the enable bit in MDIO Control
 	 * register.
 	 */
-	out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET,
-		 XEL_MDIOCTRL_MDIOEN_MASK);
+	__raw_writel(XEL_MDIOCTRL_MDIOEN_MASK,
+		     lp->base_addr + XEL_MDIOCTRL_OFFSET);
 
 	bus = mdiobus_alloc();
-	if (!bus)
+	if (!bus) {
+		dev_err(dev, "Failed to allocate mdiobus\n");
 		return -ENOMEM;
+	}
 
-	of_address_to_resource(np, 0, &res);
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
 		 (unsigned long long)res.start);
 	bus->priv = lp;
@@ -879,8 +894,10 @@ static int xemaclite_mdio_setup(struct n
 	lp->mii_bus = bus;
 
 	rc = of_mdiobus_register(bus, np);
-	if (rc)
+	if (rc) {
+		dev_err(dev, "Failed to register mdio bus.\n");
 		goto err_register;
+	}
 
 	return 0;
 
@@ -896,7 +913,7 @@ err_register:
  * There's nothing in the Emaclite device to be configured when the link
  * state changes. We just print the status.
  */
-void xemaclite_adjust_link(struct net_device *ndev)
+static void xemaclite_adjust_link(struct net_device *ndev)
 {
 	struct net_local *lp = netdev_priv(ndev);
 	struct phy_device *phy = lp->phy_dev;
@@ -1058,13 +1075,14 @@ static int xemaclite_send(struct sk_buff
  * This function un maps the IO region of the Emaclite device and frees the net
  * device.
  */
-static void xemaclite_remove_ndev(struct net_device *ndev)
+static void xemaclite_remove_ndev(struct net_device *ndev,
+				  struct platform_device *pdev)
 {
 	if (ndev) {
 		struct net_local *lp = netdev_priv(ndev);
 
 		if (lp->base_addr)
-			iounmap((void __iomem __force *) (lp->base_addr));
+			devm_iounmap(&pdev->dev, lp->base_addr);
 		free_netdev(ndev);
 	}
 }
@@ -1110,8 +1128,7 @@ static struct net_device_ops xemaclite_n
  */
 static int xemaclite_of_probe(struct platform_device *ofdev)
 {
-	struct resource r_irq; /* Interrupt resources */
-	struct resource r_mem; /* IO mem resources */
+	struct resource *res;
 	struct net_device *ndev = NULL;
 	struct net_local *lp = NULL;
 	struct device *dev = &ofdev->dev;
@@ -1121,20 +1138,6 @@ static int xemaclite_of_probe(struct pla
 
 	dev_info(dev, "Device Tree Probing\n");
 
-	/* Get iospace for the device */
-	rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
-	if (rc) {
-		dev_err(dev, "invalid address\n");
-		return rc;
-	}
-
-	/* Get IRQ for the device */
-	rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq);
-	if (!rc) {
-		dev_err(dev, "no IRQ found\n");
-		return rc;
-	}
-
 	/* Create an ethernet device instance */
 	ndev = alloc_etherdev(sizeof(struct net_local));
 	if (!ndev)
@@ -1143,30 +1146,28 @@ static int xemaclite_of_probe(struct pla
 	dev_set_drvdata(dev, ndev);
 	SET_NETDEV_DEV(ndev, &ofdev->dev);
 
-	ndev->irq = r_irq.start;
-	ndev->mem_start = r_mem.start;
-	ndev->mem_end = r_mem.end;
-
 	lp = netdev_priv(ndev);
 	lp->ndev = ndev;
 
-	if (!request_mem_region(ndev->mem_start,
-				ndev->mem_end - ndev->mem_start + 1,
-				DRIVER_NAME)) {
-		dev_err(dev, "Couldn't lock memory region at %p\n",
-			(void *)ndev->mem_start);
-		rc = -EBUSY;
-		goto error2;
+	/* Get IRQ for the device */
+	res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_err(dev, "no IRQ found\n");
+		goto error;
 	}
 
-	/* Get the virtual base address for the device */
-	lp->base_addr = ioremap(r_mem.start, resource_size(&r_mem));
-	if (NULL == lp->base_addr) {
-		dev_err(dev, "EmacLite: Could not allocate iomem\n");
-		rc = -EIO;
-		goto error1;
+	ndev->irq = res->start;
+
+	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+	lp->base_addr = devm_ioremap_resource(&ofdev->dev, res);
+	if (IS_ERR(lp->base_addr)) {
+		rc = PTR_ERR(lp->base_addr);
+		goto error;
 	}
 
+	ndev->mem_start = res->start;
+	ndev->mem_end = res->end;
+
 	spin_lock_init(&lp->reset_lock);
 	lp->next_tx_buf_to_use = 0x0;
 	lp->next_rx_buf_to_use = 0x0;
@@ -1181,8 +1182,8 @@ static int xemaclite_of_probe(struct pla
 		dev_warn(dev, "No MAC address found\n");
 
 	/* Clear the Tx CSR's in case this is a restart */
-	out_be32(lp->base_addr + XEL_TSR_OFFSET, 0);
-	out_be32(lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0);
+	__raw_writel(0, lp->base_addr + XEL_TSR_OFFSET);
+	__raw_writel(0, lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET);
 
 	/* Set the MAC address in the EmacLite device */
 	xemaclite_update_address(lp, ndev->dev_addr);
@@ -1203,7 +1204,7 @@ static int xemaclite_of_probe(struct pla
 	if (rc) {
 		dev_err(dev,
 			"Cannot register network device, aborting\n");
-		goto error1;
+		goto error;
 	}
 
 	dev_info(dev,
@@ -1212,11 +1213,8 @@ static int xemaclite_of_probe(struct pla
 		 (unsigned int __force)lp->base_addr, ndev->irq);
 	return 0;
 
-error1:
-	release_mem_region(ndev->mem_start, resource_size(&r_mem));
-
-error2:
-	xemaclite_remove_ndev(ndev);
+error:
+	xemaclite_remove_ndev(ndev, ofdev);
 	return rc;
 }
 
@@ -1251,9 +1249,7 @@ static int xemaclite_of_remove(struct pl
 		of_node_put(lp->phy_node);
 	lp->phy_node = NULL;
 
-	release_mem_region(ndev->mem_start, ndev->mem_end-ndev->mem_start + 1);
-
-	xemaclite_remove_ndev(ndev);
+	xemaclite_remove_ndev(ndev, of_dev);
 	dev_set_drvdata(dev, NULL);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ethernet/xscale/ixp4xx_eth.c linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xscale/ixp4xx_eth.c
--- linux-libre-3.10-gnu/drivers/net/ethernet/xscale/ixp4xx_eth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ethernet/xscale/ixp4xx_eth.c	2013-08-25 20:43:22.000000000 -0400
@@ -1472,7 +1472,6 @@ err_phy_dis:
 	phy_disconnect(port->phydev);
 err_free_mem:
 	npe_port_tab[NPE_ID(port->id)] = NULL;
-	platform_set_drvdata(pdev, NULL);
 	release_resource(port->mem_res);
 err_npe_rel:
 	npe_release(port->npe);
@@ -1489,7 +1488,6 @@ static int eth_remove_one(struct platfor
 	unregister_netdev(dev);
 	phy_disconnect(port->phydev);
 	npe_port_tab[NPE_ID(port->id)] = NULL;
-	platform_set_drvdata(pdev, NULL);
 	npe_release(port->npe);
 	release_resource(port->mem_res);
 	free_netdev(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/fddi/skfp/skfddi.c linux-libre-3.11-rc7-gnu/drivers/net/fddi/skfp/skfddi.c
--- linux-libre-3.10-gnu/drivers/net/fddi/skfp/skfddi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/fddi/skfp/skfddi.c	2013-08-25 20:43:22.000000000 -0400
@@ -2246,15 +2246,4 @@ static struct pci_driver skfddi_pci_driv
 	.remove		= skfp_remove_one,
 };
 
-static int __init skfd_init(void)
-{
-	return pci_register_driver(&skfddi_pci_driver);
-}
-
-static void __exit skfd_exit(void)
-{
-	pci_unregister_driver(&skfddi_pci_driver);
-}
-
-module_init(skfd_init);
-module_exit(skfd_exit);
+module_pci_driver(skfddi_pci_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/hamradio/bpqether.c linux-libre-3.11-rc7-gnu/drivers/net/hamradio/bpqether.c
--- linux-libre-3.10-gnu/drivers/net/hamradio/bpqether.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/hamradio/bpqether.c	2013-08-25 20:43:22.000000000 -0400
@@ -103,7 +103,7 @@ static struct packet_type bpq_packet_typ
 };
 
 static struct notifier_block bpq_dev_notifier = {
-	.notifier_call =bpq_device_event,
+	.notifier_call = bpq_device_event,
 };
 
 
@@ -544,9 +544,10 @@ static void bpq_free_device(struct net_d
 /*
  *	Handle device status changes.
  */
-static int bpq_device_event(struct notifier_block *this,unsigned long event, void *ptr)
+static int bpq_device_event(struct notifier_block *this,
+			    unsigned long event, void *ptr)
 {
-	struct net_device *dev = (struct net_device *)ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 
 	if (!net_eq(dev_net(dev), &init_net))
 		return NOTIFY_DONE;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/hippi/rrunner.c linux-libre-3.11-rc7-gnu/drivers/net/hippi/rrunner.c
--- linux-libre-3.10-gnu/drivers/net/hippi/rrunner.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/hippi/rrunner.c	2013-08-25 20:43:22.000000000 -0400
@@ -1686,15 +1686,4 @@ static struct pci_driver rr_driver = {
 	.remove		= rr_remove_one,
 };
 
-static int __init rr_init_module(void)
-{
-	return pci_register_driver(&rr_driver);
-}
-
-static void __exit rr_cleanup_module(void)
-{
-	pci_unregister_driver(&rr_driver);
-}
-
-module_init(rr_init_module);
-module_exit(rr_cleanup_module);
+module_pci_driver(rr_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/hyperv/netvsc_drv.c linux-libre-3.11-rc7-gnu/drivers/net/hyperv/netvsc_drv.c
--- linux-libre-3.10-gnu/drivers/net/hyperv/netvsc_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/hyperv/netvsc_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -431,8 +431,8 @@ static int netvsc_probe(struct hv_device
 	net->netdev_ops = &device_ops;
 
 	/* TODO: Add GSO and Checksum offload */
-	net->hw_features = NETIF_F_SG;
-	net->features = NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_TX;
+	net->hw_features = 0;
+	net->features = NETIF_F_HW_VLAN_CTAG_TX;
 
 	SET_ETHTOOL_OPS(net, &ethtool_ops);
 	SET_NETDEV_DEV(net, &dev->device);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ieee802154/mrf24j40.c linux-libre-3.11-rc7-gnu/drivers/net/ieee802154/mrf24j40.c
--- linux-libre-3.10-gnu/drivers/net/ieee802154/mrf24j40.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ieee802154/mrf24j40.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/spi/spi.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/pinctrl/consumer.h>
 #include <net/wpan-phy.h>
 #include <net/mac802154.h>
 #include <net/ieee802154.h>
@@ -627,7 +626,6 @@ static int mrf24j40_probe(struct spi_dev
 	int ret = -ENOMEM;
 	u8 val;
 	struct mrf24j40 *devrec;
-	struct pinctrl *pinctrl;
 
 	printk(KERN_INFO "mrf24j40: probe(). IRQ: %d\n", spi->irq);
 
@@ -638,11 +636,6 @@ static int mrf24j40_probe(struct spi_dev
 	if (!devrec->buf)
 		goto err_buf;
 
-	pinctrl = devm_pinctrl_get_select_default(&spi->dev);
-	if (IS_ERR(pinctrl))
-		dev_warn(&spi->dev,
-			"pinctrl pins are not configured from the driver");
-
 	spi->mode = SPI_MODE_0; /* TODO: Is this appropriate for right here? */
 	if (spi->max_speed_hz > MAX_SPI_SPEED_HZ)
 		spi->max_speed_hz = MAX_SPI_SPEED_HZ;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ifb.c linux-libre-3.11-rc7-gnu/drivers/net/ifb.c
--- linux-libre-3.10-gnu/drivers/net/ifb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ifb.c	2013-08-25 20:43:22.000000000 -0400
@@ -291,11 +291,17 @@ static int __init ifb_init_module(void)
 
 	rtnl_lock();
 	err = __rtnl_link_register(&ifb_link_ops);
+	if (err < 0)
+		goto out;
 
-	for (i = 0; i < numifbs && !err; i++)
+	for (i = 0; i < numifbs && !err; i++) {
 		err = ifb_init_one(i);
+		cond_resched();
+	}
 	if (err)
 		__rtnl_link_unregister(&ifb_link_ops);
+
+out:
 	rtnl_unlock();
 
 	return err;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/irda/bfin_sir.c linux-libre-3.11-rc7-gnu/drivers/net/irda/bfin_sir.c
--- linux-libre-3.10-gnu/drivers/net/irda/bfin_sir.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/irda/bfin_sir.c	2013-08-25 20:43:22.000000000 -0400
@@ -794,7 +794,6 @@ static int bfin_sir_remove(struct platfo
 	kfree(self->rx_buff.head);
 	free_netdev(dev);
 	kfree(sir_port);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/irda/sh_irda.c linux-libre-3.11-rc7-gnu/drivers/net/irda/sh_irda.c
--- linux-libre-3.10-gnu/drivers/net/irda/sh_irda.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/irda/sh_irda.c	2013-08-25 20:43:22.000000000 -0400
@@ -838,7 +838,6 @@ static int sh_irda_remove(struct platfor
 	sh_irda_remove_iobuf(self);
 	iounmap(self->membase);
 	free_netdev(ndev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/irda/sh_sir.c linux-libre-3.11-rc7-gnu/drivers/net/irda/sh_sir.c
--- linux-libre-3.10-gnu/drivers/net/irda/sh_sir.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/irda/sh_sir.c	2013-08-25 20:43:22.000000000 -0400
@@ -796,7 +796,6 @@ static int sh_sir_remove(struct platform
 	sh_sir_remove_iobuf(self);
 	iounmap(self->membase);
 	free_netdev(ndev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/irda/via-ircc.c linux-libre-3.11-rc7-gnu/drivers/net/irda/via-ircc.c
--- linux-libre-3.10-gnu/drivers/net/irda/via-ircc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/irda/via-ircc.c	2013-08-25 20:43:22.000000000 -0400
@@ -210,8 +210,7 @@ static int via_init_one(struct pci_dev *
 			pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0));
 			pci_write_config_byte(pcidev,0x5a,0xc0);
 			WriteLPCReg(0x28, 0x70 );
-			if (via_ircc_open(pcidev, &info, 0x3076) == 0)
-				rc=0;
+			rc = via_ircc_open(pcidev, &info, 0x3076);
 		} else
 			rc = -ENODEV; //IR not turn on	 
 	} else { //Not VT1211
@@ -249,8 +248,7 @@ static int via_init_one(struct pci_dev *
 			info.irq=FirIRQ;
 			info.dma=FirDRQ1;
 			info.dma2=FirDRQ0;
-			if (via_ircc_open(pcidev, &info, 0x3096) == 0)
-				rc=0;
+			rc = via_ircc_open(pcidev, &info, 0x3096);
 		} else
 			rc = -ENODEV; //IR not turn on !!!!!
 	}//Not VT1211
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/Kconfig
--- linux-libre-3.10-gnu/drivers/net/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -25,6 +25,9 @@ menuconfig NETDEVICES
 # that for each of the symbols.
 if NETDEVICES
 
+config MII
+	tristate
+
 config NET_CORE
 	default y
 	bool "Network core driver support"
@@ -100,13 +103,6 @@ config NET_FC
 	  adaptor below. You also should have said Y to "SCSI support" and
 	  "SCSI generic support".
 
-config MII
-	tristate "Generic Media Independent Interface device support"
-	help
-	  Most ethernet controllers have MII transceiver either as an external
-	  or internal device.  It is safe to say Y or M here even if your
-	  ethernet card lacks MII.
-
 config IFB
 	tristate "Intermediate Functional Block support"
 	depends on NET_CLS_ACT
@@ -244,6 +240,16 @@ config VIRTIO_NET
 	  This is the virtual network driver for virtio.  It can be used with
 	  lguest or QEMU based VMMs (like KVM or Xen).  Say Y or M.
 
+config NLMON
+	tristate "Virtual netlink monitoring device"
+	---help---
+	  This option enables a monitoring net device for netlink skbs. The
+	  purpose of this is to analyze netlink messages with packet sockets.
+	  Thus applications like tcpdump will be able to see local netlink
+	  messages if they tap into the netlink device, record pcaps for further
+	  diagnostics, etc. This is mostly intended for developers or support
+	  to debug netlink issues. If unsure, say N.
+
 endif # NET_CORE
 
 config SUNGEM_PHY
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/macvlan.c linux-libre-3.11-rc7-gnu/drivers/net/macvlan.c
--- linux-libre-3.10-gnu/drivers/net/macvlan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/macvlan.c	2013-08-25 20:43:22.000000000 -0400
@@ -337,8 +337,11 @@ static int macvlan_open(struct net_devic
 	int err;
 
 	if (vlan->port->passthru) {
-		if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC))
-			dev_set_promiscuity(lowerdev, 1);
+		if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC)) {
+			err = dev_set_promiscuity(lowerdev, 1);
+			if (err < 0)
+				goto out;
+		}
 		goto hash_add;
 	}
 
@@ -638,6 +641,14 @@ static int macvlan_ethtool_get_settings(
 	return __ethtool_get_settings(vlan->lowerdev, cmd);
 }
 
+static netdev_features_t macvlan_fix_features(struct net_device *dev,
+					      netdev_features_t features)
+{
+	struct macvlan_dev *vlan = netdev_priv(dev);
+
+	return features & (vlan->set_features | ~MACVLAN_FEATURES);
+}
+
 static const struct ethtool_ops macvlan_ethtool_ops = {
 	.get_link		= ethtool_op_get_link,
 	.get_settings		= macvlan_ethtool_get_settings,
@@ -651,6 +662,7 @@ static const struct net_device_ops macvl
 	.ndo_stop		= macvlan_stop,
 	.ndo_start_xmit		= macvlan_start_xmit,
 	.ndo_change_mtu		= macvlan_change_mtu,
+	.ndo_fix_features	= macvlan_fix_features,
 	.ndo_change_rx_flags	= macvlan_change_rx_flags,
 	.ndo_set_mac_address	= macvlan_set_mac_address,
 	.ndo_set_rx_mode	= macvlan_set_mac_lists,
@@ -727,6 +739,10 @@ static int macvlan_validate(struct nlatt
 			return -EADDRNOTAVAIL;
 	}
 
+	if (data && data[IFLA_MACVLAN_FLAGS] &&
+	    nla_get_u16(data[IFLA_MACVLAN_FLAGS]) & ~MACVLAN_FLAG_NOPROMISC)
+		return -EINVAL;
+
 	if (data && data[IFLA_MACVLAN_MODE]) {
 		switch (nla_get_u32(data[IFLA_MACVLAN_MODE])) {
 		case MACVLAN_MODE_PRIVATE:
@@ -791,6 +807,7 @@ int macvlan_common_newlink(struct net *s
 	vlan->port     = port;
 	vlan->receive  = receive;
 	vlan->forward  = forward;
+	vlan->set_features = MACVLAN_FEATURES;
 
 	vlan->mode     = MACVLAN_MODE_VEPA;
 	if (data && data[IFLA_MACVLAN_MODE])
@@ -853,6 +870,18 @@ static int macvlan_changelink(struct net
 		struct nlattr *tb[], struct nlattr *data[])
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
+	enum macvlan_mode mode;
+	bool set_mode = false;
+
+	/* Validate mode, but don't set yet: setting flags may fail. */
+	if (data && data[IFLA_MACVLAN_MODE]) {
+		set_mode = true;
+		mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+		/* Passthrough mode can't be set or cleared dynamically */
+		if ((mode == MACVLAN_MODE_PASSTHRU) !=
+		    (vlan->mode == MACVLAN_MODE_PASSTHRU))
+			return -EINVAL;
+	}
 
 	if (data && data[IFLA_MACVLAN_FLAGS]) {
 		__u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
@@ -869,8 +898,8 @@ static int macvlan_changelink(struct net
 		}
 		vlan->flags = flags;
 	}
-	if (data && data[IFLA_MACVLAN_MODE])
-		vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+	if (set_mode)
+		vlan->mode = mode;
 	return 0;
 }
 
@@ -927,7 +956,7 @@ static struct rtnl_link_ops macvlan_link
 static int macvlan_device_event(struct notifier_block *unused,
 				unsigned long event, void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct macvlan_dev *vlan, *next;
 	struct macvlan_port *port;
 	LIST_HEAD(list_kill);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/macvtap.c linux-libre-3.11-rc7-gnu/drivers/net/macvtap.c
--- linux-libre-3.10-gnu/drivers/net/macvtap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/macvtap.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,10 +31,6 @@
  * macvtap_proto is used to allocate queues through the sock allocation
  * mechanism.
  *
- * TODO: multiqueue support is currently not implemented, even though
- * macvtap is basically prepared for that. We will need to add this
- * here as well as in virtio-net and qemu to get line rate on 10gbit
- * adapters from a guest.
  */
 struct macvtap_queue {
 	struct sock sk;
@@ -44,6 +40,9 @@ struct macvtap_queue {
 	struct macvlan_dev __rcu *vlan;
 	struct file *file;
 	unsigned int flags;
+	u16 queue_index;
+	bool enabled;
+	struct list_head next;
 };
 
 static struct proto macvtap_proto = {
@@ -66,11 +65,16 @@ static struct cdev macvtap_cdev;
 
 static const struct proto_ops macvtap_socket_ops;
 
+#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
+		      NETIF_F_TSO6 | NETIF_F_UFO)
+#define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
+#define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG)
+
 /*
  * RCU usage:
  * The macvtap_queue and the macvlan_dev are loosely coupled, the
  * pointers from one to the other can only be read while rcu_read_lock
- * or macvtap_lock is held.
+ * or rtnl is held.
  *
  * Both the file and the macvlan_dev hold a reference on the macvtap_queue
  * through sock_hold(&q->sk). When the macvlan_dev goes away first,
@@ -82,54 +86,84 @@ static const struct proto_ops macvtap_so
  * file or the dev. The data structure is freed through __sk_free
  * when both our references and any pending SKBs are gone.
  */
-static DEFINE_SPINLOCK(macvtap_lock);
 
-/*
- * get_slot: return a [unused/occupied] slot in vlan->taps[]:
- *	- if 'q' is NULL, return the first empty slot;
- *	- otherwise, return the slot this pointer occupies.
- */
-static int get_slot(struct macvlan_dev *vlan, struct macvtap_queue *q)
+static int macvtap_enable_queue(struct net_device *dev, struct file *file,
+				struct macvtap_queue *q)
 {
-	int i;
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	int err = -EINVAL;
 
-	for (i = 0; i < MAX_MACVTAP_QUEUES; i++) {
-		if (rcu_dereference_protected(vlan->taps[i],
-					      lockdep_is_held(&macvtap_lock)) == q)
-			return i;
-	}
+	ASSERT_RTNL();
 
-	/* Should never happen */
-	BUG_ON(1);
+	if (q->enabled)
+		goto out;
+
+	err = 0;
+	rcu_assign_pointer(vlan->taps[vlan->numvtaps], q);
+	q->queue_index = vlan->numvtaps;
+	q->enabled = true;
+
+	vlan->numvtaps++;
+out:
+	return err;
 }
 
 static int macvtap_set_queue(struct net_device *dev, struct file *file,
-				struct macvtap_queue *q)
+			     struct macvtap_queue *q)
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
-	int index;
 	int err = -EBUSY;
 
-	spin_lock(&macvtap_lock);
-	if (vlan->numvtaps == MAX_MACVTAP_QUEUES)
+	rtnl_lock();
+	if (vlan->numqueues == MAX_MACVTAP_QUEUES)
 		goto out;
 
 	err = 0;
-	index = get_slot(vlan, NULL);
 	rcu_assign_pointer(q->vlan, vlan);
-	rcu_assign_pointer(vlan->taps[index], q);
+	rcu_assign_pointer(vlan->taps[vlan->numvtaps], q);
 	sock_hold(&q->sk);
 
 	q->file = file;
+	q->queue_index = vlan->numvtaps;
+	q->enabled = true;
 	file->private_data = q;
+	list_add_tail(&q->next, &vlan->queue_list);
 
 	vlan->numvtaps++;
+	vlan->numqueues++;
 
 out:
-	spin_unlock(&macvtap_lock);
+	rtnl_unlock();
 	return err;
 }
 
+static int macvtap_disable_queue(struct macvtap_queue *q)
+{
+	struct macvlan_dev *vlan;
+	struct macvtap_queue *nq;
+
+	ASSERT_RTNL();
+	if (!q->enabled)
+		return -EINVAL;
+
+	vlan = rtnl_dereference(q->vlan);
+
+	if (vlan) {
+		int index = q->queue_index;
+		BUG_ON(index >= vlan->numvtaps);
+		nq = rtnl_dereference(vlan->taps[vlan->numvtaps - 1]);
+		nq->queue_index = index;
+
+		rcu_assign_pointer(vlan->taps[index], nq);
+		RCU_INIT_POINTER(vlan->taps[vlan->numvtaps - 1], NULL);
+		q->enabled = false;
+
+		vlan->numvtaps--;
+	}
+
+	return 0;
+}
+
 /*
  * The file owning the queue got closed, give up both
  * the reference that the files holds as well as the
@@ -142,19 +176,20 @@ static void macvtap_put_queue(struct mac
 {
 	struct macvlan_dev *vlan;
 
-	spin_lock(&macvtap_lock);
-	vlan = rcu_dereference_protected(q->vlan,
-					 lockdep_is_held(&macvtap_lock));
+	rtnl_lock();
+	vlan = rtnl_dereference(q->vlan);
+
 	if (vlan) {
-		int index = get_slot(vlan, q);
+		if (q->enabled)
+			BUG_ON(macvtap_disable_queue(q));
 
-		RCU_INIT_POINTER(vlan->taps[index], NULL);
+		vlan->numqueues--;
 		RCU_INIT_POINTER(q->vlan, NULL);
 		sock_put(&q->sk);
-		--vlan->numvtaps;
+		list_del_init(&q->next);
 	}
 
-	spin_unlock(&macvtap_lock);
+	rtnl_unlock();
 
 	synchronize_rcu();
 	sock_put(&q->sk);
@@ -172,7 +207,12 @@ static struct macvtap_queue *macvtap_get
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct macvtap_queue *tap = NULL;
-	int numvtaps = vlan->numvtaps;
+	/* Access to taps array is protected by rcu, but access to numvtaps
+	 * isn't. Below we use it to lookup a queue, but treat it as a hint
+	 * and validate that the result isn't NULL - in case we are
+	 * racing against queue removal.
+	 */
+	int numvtaps = ACCESS_ONCE(vlan->numvtaps);
 	__u32 rxq;
 
 	if (!numvtaps)
@@ -182,8 +222,7 @@ static struct macvtap_queue *macvtap_get
 	rxq = skb_get_rxhash(skb);
 	if (rxq) {
 		tap = rcu_dereference(vlan->taps[rxq % numvtaps]);
-		if (tap)
-			goto out;
+		goto out;
 	}
 
 	if (likely(skb_rx_queue_recorded(skb))) {
@@ -193,17 +232,10 @@ static struct macvtap_queue *macvtap_get
 			rxq -= numvtaps;
 
 		tap = rcu_dereference(vlan->taps[rxq]);
-		if (tap)
-			goto out;
-	}
-
-	/* Everything failed - find first available queue */
-	for (rxq = 0; rxq < MAX_MACVTAP_QUEUES; rxq++) {
-		tap = rcu_dereference(vlan->taps[rxq]);
-		if (tap)
-			break;
+		goto out;
 	}
 
+	tap = rcu_dereference(vlan->taps[0]);
 out:
 	return tap;
 }
@@ -216,27 +248,24 @@ out:
 static void macvtap_del_queues(struct net_device *dev)
 {
 	struct macvlan_dev *vlan = netdev_priv(dev);
-	struct macvtap_queue *q, *qlist[MAX_MACVTAP_QUEUES];
+	struct macvtap_queue *q, *tmp, *qlist[MAX_MACVTAP_QUEUES];
 	int i, j = 0;
 
-	/* macvtap_put_queue can free some slots, so go through all slots */
-	spin_lock(&macvtap_lock);
-	for (i = 0; i < MAX_MACVTAP_QUEUES && vlan->numvtaps; i++) {
-		q = rcu_dereference_protected(vlan->taps[i],
-					      lockdep_is_held(&macvtap_lock));
-		if (q) {
-			qlist[j++] = q;
-			RCU_INIT_POINTER(vlan->taps[i], NULL);
-			RCU_INIT_POINTER(q->vlan, NULL);
+	ASSERT_RTNL();
+	list_for_each_entry_safe(q, tmp, &vlan->queue_list, next) {
+		list_del_init(&q->next);
+		qlist[j++] = q;
+		RCU_INIT_POINTER(q->vlan, NULL);
+		if (q->enabled)
 			vlan->numvtaps--;
-		}
+		vlan->numqueues--;
 	}
-	BUG_ON(vlan->numvtaps != 0);
+	for (i = 0; i < vlan->numvtaps; i++)
+		RCU_INIT_POINTER(vlan->taps[i], NULL);
+	BUG_ON(vlan->numvtaps);
+	BUG_ON(vlan->numqueues);
 	/* guarantee that any future macvtap_set_queue will fail */
 	vlan->numvtaps = MAX_MACVTAP_QUEUES;
-	spin_unlock(&macvtap_lock);
-
-	synchronize_rcu();
 
 	for (--j; j >= 0; j--)
 		sock_put(&qlist[j]->sk);
@@ -249,14 +278,47 @@ static void macvtap_del_queues(struct ne
  */
 static int macvtap_forward(struct net_device *dev, struct sk_buff *skb)
 {
+	struct macvlan_dev *vlan = netdev_priv(dev);
 	struct macvtap_queue *q = macvtap_get_queue(dev, skb);
+	netdev_features_t features = TAP_FEATURES;
+
 	if (!q)
 		goto drop;
 
 	if (skb_queue_len(&q->sk.sk_receive_queue) >= dev->tx_queue_len)
 		goto drop;
 
-	skb_queue_tail(&q->sk.sk_receive_queue, skb);
+	skb->dev = dev;
+	/* Apply the forward feature mask so that we perform segmentation
+	 * according to users wishes.  This only works if VNET_HDR is
+	 * enabled.
+	 */
+	if (q->flags & IFF_VNET_HDR)
+		features |= vlan->tap_features;
+	if (netif_needs_gso(skb, features)) {
+		struct sk_buff *segs = __skb_gso_segment(skb, features, false);
+
+		if (IS_ERR(segs))
+			goto drop;
+
+		if (!segs) {
+			skb_queue_tail(&q->sk.sk_receive_queue, skb);
+			goto wake_up;
+		}
+
+		kfree_skb(skb);
+		while (segs) {
+			struct sk_buff *nskb = segs->next;
+
+			segs->next = NULL;
+			skb_queue_tail(&q->sk.sk_receive_queue, segs);
+			segs = nskb;
+		}
+	} else {
+		skb_queue_tail(&q->sk.sk_receive_queue, skb);
+	}
+
+wake_up:
 	wake_up_interruptible_poll(sk_sleep(&q->sk), POLLIN | POLLRDNORM | POLLRDBAND);
 	return NET_RX_SUCCESS;
 
@@ -322,6 +384,14 @@ static int macvtap_newlink(struct net *s
 			   struct nlattr *tb[],
 			   struct nlattr *data[])
 {
+	struct macvlan_dev *vlan = netdev_priv(dev);
+	INIT_LIST_HEAD(&vlan->queue_list);
+
+	/* Since macvlan supports all offloads by default, make
+	 * tap support all offloads also.
+	 */
+	vlan->tap_features = TUN_OFFLOADS;
+
 	/* Don't put anything that may fail after macvlan_common_newlink
 	 * because we can't undo what it does.
 	 */
@@ -385,7 +455,7 @@ static int macvtap_open(struct inode *in
 	if (!q)
 		goto out;
 
-	q->sock.wq = &q->wq;
+	RCU_INIT_POINTER(q->sock.wq, &q->wq);
 	init_waitqueue_head(&q->wq.wait);
 	q->sock.type = SOCK_RAW;
 	q->sock.state = SS_CONNECTED;
@@ -633,6 +703,28 @@ static int macvtap_skb_to_vnet_hdr(const
 	return 0;
 }
 
+static unsigned long iov_pages(const struct iovec *iv, int offset,
+			       unsigned long nr_segs)
+{
+	unsigned long seg, base;
+	int pages = 0, len, size;
+
+	while (nr_segs && (offset >= iv->iov_len)) {
+		offset -= iv->iov_len;
+		++iv;
+		--nr_segs;
+	}
+
+	for (seg = 0; seg < nr_segs; seg++) {
+		base = (unsigned long)iv[seg].iov_base + offset;
+		len = iv[seg].iov_len - offset;
+		size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
+		pages += size;
+		offset = 0;
+	}
+
+	return pages;
+}
 
 /* Get packet from user space buffer */
 static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
@@ -647,6 +739,7 @@ static ssize_t macvtap_get_user(struct m
 	int vnet_hdr_len = 0;
 	int copylen = 0;
 	bool zerocopy = false;
+	size_t linear;
 
 	if (q->flags & IFF_VNET_HDR) {
 		vnet_hdr_len = q->vnet_hdr_sz;
@@ -678,42 +771,35 @@ static ssize_t macvtap_get_user(struct m
 	if (unlikely(count > UIO_MAXIOV))
 		goto err;
 
-	if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY))
-		zerocopy = true;
+	if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) {
+		copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN;
+		linear = copylen;
+		if (iov_pages(iv, vnet_hdr_len + copylen, count)
+		    <= MAX_SKB_FRAGS)
+			zerocopy = true;
+	}
 
-	if (zerocopy) {
-		/* Userspace may produce vectors with count greater than
-		 * MAX_SKB_FRAGS, so we need to linearize parts of the skb
-		 * to let the rest of data to be fit in the frags.
-		 */
-		if (count > MAX_SKB_FRAGS) {
-			copylen = iov_length(iv, count - MAX_SKB_FRAGS);
-			if (copylen < vnet_hdr_len)
-				copylen = 0;
-			else
-				copylen -= vnet_hdr_len;
-		}
-		/* There are 256 bytes to be copied in skb, so there is enough
-		 * room for skb expand head in case it is used.
-		 * The rest buffer is mapped from userspace.
-		 */
-		if (copylen < vnet_hdr.hdr_len)
-			copylen = vnet_hdr.hdr_len;
-		if (!copylen)
-			copylen = GOODCOPY_LEN;
-	} else
+	if (!zerocopy) {
 		copylen = len;
+		linear = vnet_hdr.hdr_len;
+	}
 
 	skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, copylen,
-				vnet_hdr.hdr_len, noblock, &err);
+				linear, noblock, &err);
 	if (!skb)
 		goto err;
 
 	if (zerocopy)
 		err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count);
-	else
+	else {
 		err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len,
 						   len);
+		if (!err && m && m->msg_control) {
+			struct ubuf_info *uarg = m->msg_control;
+			uarg->callback(uarg, false);
+		}
+	}
+
 	if (err)
 		goto err_kfree;
 
@@ -729,19 +815,22 @@ static ssize_t macvtap_get_user(struct m
 
 	skb_probe_transport_header(skb, ETH_HLEN);
 
-	rcu_read_lock_bh();
-	vlan = rcu_dereference_bh(q->vlan);
+	rcu_read_lock();
+	vlan = rcu_dereference(q->vlan);
 	/* copy skb_ubuf_info for callback when skb has no error */
 	if (zerocopy) {
 		skb_shinfo(skb)->destructor_arg = m->msg_control;
 		skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
 		skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
 	}
-	if (vlan)
+	if (vlan) {
+		local_bh_disable();
 		macvlan_start_xmit(skb, vlan->dev);
-	else
+		local_bh_enable();
+	} else {
 		kfree_skb(skb);
-	rcu_read_unlock_bh();
+	}
+	rcu_read_unlock();
 
 	return total_len;
 
@@ -749,11 +838,11 @@ err_kfree:
 	kfree_skb(skb);
 
 err:
-	rcu_read_lock_bh();
-	vlan = rcu_dereference_bh(q->vlan);
+	rcu_read_lock();
+	vlan = rcu_dereference(q->vlan);
 	if (vlan)
 		vlan->dev->stats.tx_dropped++;
-	rcu_read_unlock_bh();
+	rcu_read_unlock();
 
 	return err;
 }
@@ -804,7 +893,7 @@ static ssize_t macvtap_put_user(struct m
 			__be16 h_vlan_proto;
 			__be16 h_vlan_TCI;
 		} veth;
-		veth.h_vlan_proto = htons(ETH_P_8021Q);
+		veth.h_vlan_proto = skb->vlan_proto;
 		veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb));
 
 		vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
@@ -829,11 +918,14 @@ static ssize_t macvtap_put_user(struct m
 	copied += len;
 
 done:
-	rcu_read_lock_bh();
-	vlan = rcu_dereference_bh(q->vlan);
-	if (vlan)
+	rcu_read_lock();
+	vlan = rcu_dereference(q->vlan);
+	if (vlan) {
+		preempt_disable();
 		macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0);
-	rcu_read_unlock_bh();
+		preempt_enable();
+	}
+	rcu_read_unlock();
 
 	return ret ? ret : copied;
 }
@@ -847,7 +939,9 @@ static ssize_t macvtap_do_read(struct ma
 	ssize_t ret = 0;
 
 	while (len) {
-		prepare_to_wait(sk_sleep(&q->sk), &wait, TASK_INTERRUPTIBLE);
+		if (!noblock)
+			prepare_to_wait(sk_sleep(&q->sk), &wait,
+					TASK_INTERRUPTIBLE);
 
 		/* Read frames from the queue */
 		skb = skb_dequeue(&q->sk.sk_receive_queue);
@@ -869,7 +963,8 @@ static ssize_t macvtap_do_read(struct ma
 		break;
 	}
 
-	finish_wait(sk_sleep(&q->sk), &wait);
+	if (!noblock)
+		finish_wait(sk_sleep(&q->sk), &wait);
 	return ret;
 }
 
@@ -892,6 +987,95 @@ out:
 	return ret;
 }
 
+static struct macvlan_dev *macvtap_get_vlan(struct macvtap_queue *q)
+{
+	struct macvlan_dev *vlan;
+
+	ASSERT_RTNL();
+	vlan = rtnl_dereference(q->vlan);
+	if (vlan)
+		dev_hold(vlan->dev);
+
+	return vlan;
+}
+
+static void macvtap_put_vlan(struct macvlan_dev *vlan)
+{
+	dev_put(vlan->dev);
+}
+
+static int macvtap_ioctl_set_queue(struct file *file, unsigned int flags)
+{
+	struct macvtap_queue *q = file->private_data;
+	struct macvlan_dev *vlan;
+	int ret;
+
+	vlan = macvtap_get_vlan(q);
+	if (!vlan)
+		return -EINVAL;
+
+	if (flags & IFF_ATTACH_QUEUE)
+		ret = macvtap_enable_queue(vlan->dev, file, q);
+	else if (flags & IFF_DETACH_QUEUE)
+		ret = macvtap_disable_queue(q);
+	else
+		ret = -EINVAL;
+
+	macvtap_put_vlan(vlan);
+	return ret;
+}
+
+static int set_offload(struct macvtap_queue *q, unsigned long arg)
+{
+	struct macvlan_dev *vlan;
+	netdev_features_t features;
+	netdev_features_t feature_mask = 0;
+
+	vlan = rtnl_dereference(q->vlan);
+	if (!vlan)
+		return -ENOLINK;
+
+	features = vlan->dev->features;
+
+	if (arg & TUN_F_CSUM) {
+		feature_mask = NETIF_F_HW_CSUM;
+
+		if (arg & (TUN_F_TSO4 | TUN_F_TSO6)) {
+			if (arg & TUN_F_TSO_ECN)
+				feature_mask |= NETIF_F_TSO_ECN;
+			if (arg & TUN_F_TSO4)
+				feature_mask |= NETIF_F_TSO;
+			if (arg & TUN_F_TSO6)
+				feature_mask |= NETIF_F_TSO6;
+		}
+
+		if (arg & TUN_F_UFO)
+			feature_mask |= NETIF_F_UFO;
+	}
+
+	/* tun/tap driver inverts the usage for TSO offloads, where
+	 * setting the TSO bit means that the userspace wants to
+	 * accept TSO frames and turning it off means that user space
+	 * does not support TSO.
+	 * For macvtap, we have to invert it to mean the same thing.
+	 * When user space turns off TSO, we turn off GSO/LRO so that
+	 * user-space will not receive TSO frames.
+	 */
+	if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO))
+		features |= RX_OFFLOADS;
+	else
+		features &= ~RX_OFFLOADS;
+
+	/* tap_features are the same as features on tun/tap and
+	 * reflect user expectations.
+	 */
+	vlan->tap_features = feature_mask;
+	vlan->set_features = features;
+	netdev_update_features(vlan->dev);
+
+	return 0;
+}
+
 /*
  * provide compatibility with generic tun/tap interface
  */
@@ -915,7 +1099,8 @@ static long macvtap_ioctl(struct file *f
 			return -EFAULT;
 
 		ret = 0;
-		if ((u & ~IFF_VNET_HDR) != (IFF_NO_PI | IFF_TAP))
+		if ((u & ~(IFF_VNET_HDR | IFF_MULTI_QUEUE)) !=
+		    (IFF_NO_PI | IFF_TAP))
 			ret = -EINVAL;
 		else
 			q->flags = u;
@@ -923,24 +1108,32 @@ static long macvtap_ioctl(struct file *f
 		return ret;
 
 	case TUNGETIFF:
-		rcu_read_lock_bh();
-		vlan = rcu_dereference_bh(q->vlan);
-		if (vlan)
-			dev_hold(vlan->dev);
-		rcu_read_unlock_bh();
-
-		if (!vlan)
+		rtnl_lock();
+		vlan = macvtap_get_vlan(q);
+		if (!vlan) {
+			rtnl_unlock();
 			return -ENOLINK;
+		}
 
 		ret = 0;
 		if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) ||
 		    put_user(q->flags, &ifr->ifr_flags))
 			ret = -EFAULT;
-		dev_put(vlan->dev);
+		macvtap_put_vlan(vlan);
+		rtnl_unlock();
+		return ret;
+
+	case TUNSETQUEUE:
+		if (get_user(u, &ifr->ifr_flags))
+			return -EFAULT;
+		rtnl_lock();
+		ret = macvtap_ioctl_set_queue(file, u);
+		rtnl_unlock();
 		return ret;
 
 	case TUNGETFEATURES:
-		if (put_user(IFF_TAP | IFF_NO_PI | IFF_VNET_HDR, up))
+		if (put_user(IFF_TAP | IFF_NO_PI | IFF_VNET_HDR |
+			     IFF_MULTI_QUEUE, up))
 			return -EFAULT;
 		return 0;
 
@@ -972,11 +1165,10 @@ static long macvtap_ioctl(struct file *f
 			    TUN_F_TSO_ECN | TUN_F_UFO))
 			return -EINVAL;
 
-		/* TODO: only accept frames with the features that
-			 got enabled for forwarded frames */
-		if (!(q->flags & IFF_VNET_HDR))
-			return  -EINVAL;
-		return 0;
+		rtnl_lock();
+		ret = set_offload(q, arg);
+		rtnl_unlock();
+		return ret;
 
 	default:
 		return -EINVAL;
@@ -1055,7 +1247,7 @@ EXPORT_SYMBOL_GPL(macvtap_get_socket);
 static int macvtap_device_event(struct notifier_block *unused,
 				unsigned long event, void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct macvlan_dev *vlan;
 	struct device *classdev;
 	dev_t devt;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/Makefile linux-libre-3.11-rc7-gnu/drivers/net/Makefile
--- linux-libre-3.10-gnu/drivers/net/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@ obj-$(CONFIG_TUN) += tun.o
 obj-$(CONFIG_VETH) += veth.o
 obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
 obj-$(CONFIG_VXLAN) += vxlan.o
+obj-$(CONFIG_NLMON) += nlmon.o
 
 #
 # Networking Drivers
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/netconsole.c linux-libre-3.11-rc7-gnu/drivers/net/netconsole.c
--- linux-libre-3.10-gnu/drivers/net/netconsole.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/netconsole.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/slab.h>
 #include <linux/console.h>
 #include <linux/moduleparam.h>
+#include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/netpoll.h>
 #include <linux/inet.h>
@@ -653,12 +654,11 @@ static struct configfs_subsystem netcons
 
 /* Handle network interface device notifications */
 static int netconsole_netdev_event(struct notifier_block *this,
-				   unsigned long event,
-				   void *ptr)
+				   unsigned long event, void *ptr)
 {
 	unsigned long flags;
 	struct netconsole_target *nt;
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	bool stopped = false;
 
 	if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER ||
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/nlmon.c linux-libre-3.11-rc7-gnu/drivers/net/nlmon.c
--- linux-libre-3.10-gnu/drivers/net/nlmon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/nlmon.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,181 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/netlink.h>
+#include <net/net_namespace.h>
+#include <linux/if_arp.h>
+#include <net/rtnetlink.h>
+
+struct pcpu_lstats {
+	u64 packets;
+	u64 bytes;
+	struct u64_stats_sync syncp;
+};
+
+static netdev_tx_t nlmon_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	int len = skb->len;
+	struct pcpu_lstats *stats = this_cpu_ptr(dev->lstats);
+
+	u64_stats_update_begin(&stats->syncp);
+	stats->bytes += len;
+	stats->packets++;
+	u64_stats_update_end(&stats->syncp);
+
+	dev_kfree_skb(skb);
+
+	return NETDEV_TX_OK;
+}
+
+static int nlmon_is_valid_mtu(int new_mtu)
+{
+	/* Note that in netlink we do not really have an upper limit. On
+	 * default, we use NLMSG_GOODSIZE. Here at least we should make
+	 * sure that it's at least the header size.
+	 */
+	return new_mtu >= (int) sizeof(struct nlmsghdr);
+}
+
+static int nlmon_change_mtu(struct net_device *dev, int new_mtu)
+{
+	if (!nlmon_is_valid_mtu(new_mtu))
+		return -EINVAL;
+
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+static int nlmon_dev_init(struct net_device *dev)
+{
+	dev->lstats = alloc_percpu(struct pcpu_lstats);
+
+	return dev->lstats == NULL ? -ENOMEM : 0;
+}
+
+static void nlmon_dev_uninit(struct net_device *dev)
+{
+	free_percpu(dev->lstats);
+}
+
+struct nlmon {
+	struct netlink_tap nt;
+};
+
+static int nlmon_open(struct net_device *dev)
+{
+	struct nlmon *nlmon = netdev_priv(dev);
+
+	nlmon->nt.dev = dev;
+	nlmon->nt.module = THIS_MODULE;
+	return netlink_add_tap(&nlmon->nt);
+}
+
+static int nlmon_close(struct net_device *dev)
+{
+	struct nlmon *nlmon = netdev_priv(dev);
+
+	return netlink_remove_tap(&nlmon->nt);
+}
+
+static struct rtnl_link_stats64 *
+nlmon_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
+{
+	int i;
+	u64 bytes = 0, packets = 0;
+
+	for_each_possible_cpu(i) {
+		const struct pcpu_lstats *nl_stats;
+		u64 tbytes, tpackets;
+		unsigned int start;
+
+		nl_stats = per_cpu_ptr(dev->lstats, i);
+
+		do {
+			start = u64_stats_fetch_begin_bh(&nl_stats->syncp);
+			tbytes = nl_stats->bytes;
+			tpackets = nl_stats->packets;
+		} while (u64_stats_fetch_retry_bh(&nl_stats->syncp, start));
+
+		packets += tpackets;
+		bytes += tbytes;
+	}
+
+	stats->rx_packets = packets;
+	stats->tx_packets = 0;
+
+	stats->rx_bytes = bytes;
+	stats->tx_bytes = 0;
+
+	return stats;
+}
+
+static u32 always_on(struct net_device *dev)
+{
+	return 1;
+}
+
+static const struct ethtool_ops nlmon_ethtool_ops = {
+	.get_link = always_on,
+};
+
+static const struct net_device_ops nlmon_ops = {
+	.ndo_init = nlmon_dev_init,
+	.ndo_uninit = nlmon_dev_uninit,
+	.ndo_open = nlmon_open,
+	.ndo_stop = nlmon_close,
+	.ndo_start_xmit = nlmon_xmit,
+	.ndo_get_stats64 = nlmon_get_stats64,
+	.ndo_change_mtu = nlmon_change_mtu,
+};
+
+static void nlmon_setup(struct net_device *dev)
+{
+	dev->type = ARPHRD_NETLINK;
+	dev->tx_queue_len = 0;
+
+	dev->netdev_ops	= &nlmon_ops;
+	dev->ethtool_ops = &nlmon_ethtool_ops;
+	dev->destructor	= free_netdev;
+
+	dev->features = NETIF_F_FRAGLIST | NETIF_F_HIGHDMA;
+	dev->flags = IFF_NOARP;
+
+	/* That's rather a softlimit here, which, of course,
+	 * can be altered. Not a real MTU, but what is to be
+	 * expected in most cases.
+	 */
+	dev->mtu = NLMSG_GOODSIZE;
+}
+
+static int nlmon_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+	if (tb[IFLA_ADDRESS])
+		return -EINVAL;
+	return 0;
+}
+
+static struct rtnl_link_ops nlmon_link_ops __read_mostly = {
+	.kind			= "nlmon",
+	.priv_size		= sizeof(struct nlmon),
+	.setup			= nlmon_setup,
+	.validate		= nlmon_validate,
+};
+
+static __init int nlmon_register(void)
+{
+	return rtnl_link_register(&nlmon_link_ops);
+}
+
+static __exit void nlmon_unregister(void)
+{
+	rtnl_link_unregister(&nlmon_link_ops);
+}
+
+module_init(nlmon_register);
+module_exit(nlmon_unregister);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Daniel Borkmann <dborkman@redhat.com>");
+MODULE_AUTHOR("Mathieu Geli <geli@enseirb.fr>");
+MODULE_DESCRIPTION("Netlink monitoring device");
+MODULE_ALIAS_RTNL_LINK("nlmon");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/at803x.c linux-libre-3.11-rc7-gnu/drivers/net/phy/at803x.c
--- linux-libre-3.10-gnu/drivers/net/phy/at803x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/at803x.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,15 +27,22 @@
 #define AT803X_MMD_ACCESS_CONTROL		0x0D
 #define AT803X_MMD_ACCESS_CONTROL_DATA		0x0E
 #define AT803X_FUNC_DATA			0x4003
+#define AT803X_DEBUG_ADDR			0x1D
+#define AT803X_DEBUG_DATA			0x1E
+#define AT803X_DEBUG_SYSTEM_MODE_CTRL		0x05
+#define AT803X_DEBUG_RGMII_TX_CLK_DLY		BIT(8)
 
 MODULE_DESCRIPTION("Atheros 803x PHY driver");
 MODULE_AUTHOR("Matus Ujhelyi");
 MODULE_LICENSE("GPL");
 
-static void at803x_set_wol_mac_addr(struct phy_device *phydev)
+static int at803x_set_wol(struct phy_device *phydev,
+			  struct ethtool_wolinfo *wol)
 {
 	struct net_device *ndev = phydev->attached_dev;
 	const u8 *mac;
+	int ret;
+	u32 value;
 	unsigned int i, offsets[] = {
 		AT803X_LOC_MAC_ADDR_32_47_OFFSET,
 		AT803X_LOC_MAC_ADDR_16_31_OFFSET,
@@ -43,30 +50,61 @@ static void at803x_set_wol_mac_addr(stru
 	};
 
 	if (!ndev)
-		return;
+		return -ENODEV;
 
-	mac = (const u8 *) ndev->dev_addr;
+	if (wol->wolopts & WAKE_MAGIC) {
+		mac = (const u8 *) ndev->dev_addr;
 
-	if (!is_valid_ether_addr(mac))
-		return;
+		if (!is_valid_ether_addr(mac))
+			return -EFAULT;
 
-	for (i = 0; i < 3; i++) {
-		phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
+		for (i = 0; i < 3; i++) {
+			phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
 				  AT803X_DEVICE_ADDR);
-		phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
+			phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
 				  offsets[i]);
-		phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
+			phy_write(phydev, AT803X_MMD_ACCESS_CONTROL,
 				  AT803X_FUNC_DATA);
-		phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
+			phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA,
 				  mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
+		}
+
+		value = phy_read(phydev, AT803X_INTR_ENABLE);
+		value |= AT803X_WOL_ENABLE;
+		ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
+		if (ret)
+			return ret;
+		value = phy_read(phydev, AT803X_INTR_STATUS);
+	} else {
+		value = phy_read(phydev, AT803X_INTR_ENABLE);
+		value &= (~AT803X_WOL_ENABLE);
+		ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
+		if (ret)
+			return ret;
+		value = phy_read(phydev, AT803X_INTR_STATUS);
 	}
+
+	return ret;
+}
+
+static void at803x_get_wol(struct phy_device *phydev,
+			   struct ethtool_wolinfo *wol)
+{
+	u32 value;
+
+	wol->supported = WAKE_MAGIC;
+	wol->wolopts = 0;
+
+	value = phy_read(phydev, AT803X_INTR_ENABLE);
+	if (value & AT803X_WOL_ENABLE)
+		wol->wolopts |= WAKE_MAGIC;
 }
 
 static int at803x_config_init(struct phy_device *phydev)
 {
 	int val;
+	int ret;
 	u32 features;
-	int status;
 
 	features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI |
 		   SUPPORTED_FIBRE | SUPPORTED_BNC;
@@ -100,20 +138,29 @@ static int at803x_config_init(struct phy
 	phydev->supported = features;
 	phydev->advertising = features;
 
-	/* enable WOL */
-	at803x_set_wol_mac_addr(phydev);
-	status = phy_write(phydev, AT803X_INTR_ENABLE, AT803X_WOL_ENABLE);
-	status = phy_read(phydev, AT803X_INTR_STATUS);
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
+		ret = phy_write(phydev, AT803X_DEBUG_ADDR,
+				AT803X_DEBUG_SYSTEM_MODE_CTRL);
+		if (ret)
+			return ret;
+		ret = phy_write(phydev, AT803X_DEBUG_DATA,
+				AT803X_DEBUG_RGMII_TX_CLK_DLY);
+		if (ret)
+			return ret;
+	}
 
 	return 0;
 }
 
-/* ATHEROS 8035 */
-static struct phy_driver at8035_driver = {
+static struct phy_driver at803x_driver[] = {
+{
+	/* ATHEROS 8035 */
 	.phy_id		= 0x004dd072,
 	.name		= "Atheros 8035 ethernet",
 	.phy_id_mask	= 0xffffffef,
 	.config_init	= at803x_config_init,
+	.set_wol	= at803x_set_wol,
+	.get_wol	= at803x_get_wol,
 	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.config_aneg	= &genphy_config_aneg,
@@ -121,14 +168,14 @@ static struct phy_driver at8035_driver =
 	.driver		= {
 		.owner = THIS_MODULE,
 	},
-};
-
-/* ATHEROS 8030 */
-static struct phy_driver at8030_driver = {
+}, {
+	/* ATHEROS 8030 */
 	.phy_id		= 0x004dd076,
 	.name		= "Atheros 8030 ethernet",
 	.phy_id_mask	= 0xffffffef,
 	.config_init	= at803x_config_init,
+	.set_wol	= at803x_set_wol,
+	.get_wol	= at803x_get_wol,
 	.features	= PHY_GBIT_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.config_aneg	= &genphy_config_aneg,
@@ -136,32 +183,33 @@ static struct phy_driver at8030_driver =
 	.driver		= {
 		.owner = THIS_MODULE,
 	},
-};
+}, {
+	/* ATHEROS 8031 */
+	.phy_id		= 0x004dd074,
+	.name		= "Atheros 8031 ethernet",
+	.phy_id_mask	= 0xffffffef,
+	.config_init	= at803x_config_init,
+	.set_wol	= at803x_set_wol,
+	.get_wol	= at803x_get_wol,
+	.features	= PHY_GBIT_FEATURES,
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_aneg	= &genphy_config_aneg,
+	.read_status	= &genphy_read_status,
+	.driver		= {
+		.owner = THIS_MODULE,
+	},
+} };
 
 static int __init atheros_init(void)
 {
-	int ret;
-
-	ret = phy_driver_register(&at8035_driver);
-	if (ret)
-		goto err1;
-
-	ret = phy_driver_register(&at8030_driver);
-	if (ret)
-		goto err2;
-
-	return 0;
-
-err2:
-	phy_driver_unregister(&at8035_driver);
-err1:
-	return ret;
+	return phy_drivers_register(at803x_driver,
+				    ARRAY_SIZE(at803x_driver));
 }
 
 static void __exit atheros_exit(void)
 {
-	phy_driver_unregister(&at8035_driver);
-	phy_driver_unregister(&at8030_driver);
+	return phy_drivers_unregister(at803x_driver,
+				      ARRAY_SIZE(at803x_driver));
 }
 
 module_init(atheros_init);
@@ -169,6 +217,7 @@ module_exit(atheros_exit);
 
 static struct mdio_device_id __maybe_unused atheros_tbl[] = {
 	{ 0x004dd076, 0xffffffef },
+	{ 0x004dd074, 0xffffffef },
 	{ 0x004dd072, 0xffffffef },
 	{ }
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/bcm63xx.c linux-libre-3.11-rc7-gnu/drivers/net/phy/bcm63xx.c
--- linux-libre-3.10-gnu/drivers/net/phy/bcm63xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/bcm63xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -78,7 +78,7 @@ static struct phy_driver bcm63xx_driver[
 	.name		= "Broadcom BCM63XX (1)",
 	/* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */
 	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
-	.flags		= PHY_HAS_INTERRUPT,
+	.flags		= PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
 	.config_init	= bcm63xx_config_init,
 	.config_aneg	= genphy_config_aneg,
 	.read_status	= genphy_read_status,
@@ -91,7 +91,7 @@ static struct phy_driver bcm63xx_driver[
 	.phy_id_mask	= 0xfffffc00,
 	.name		= "Broadcom BCM63XX (2)",
 	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
-	.flags		= PHY_HAS_INTERRUPT,
+	.flags		= PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
 	.config_init	= bcm63xx_config_init,
 	.config_aneg	= genphy_config_aneg,
 	.read_status	= genphy_read_status,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/phy/Kconfig
--- linux-libre-3.10-gnu/drivers/net/phy/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -135,7 +135,7 @@ config MDIO_GPIO
 
 config MDIO_OCTEON
 	tristate "Support for MDIO buses on Octeon SOCs"
-	depends on  CPU_CAVIUM_OCTEON
+	depends on CAVIUM_OCTEON_SOC
 	default y
 	help
 
@@ -144,6 +144,16 @@ config MDIO_OCTEON
 
 	  If in doubt, say Y.
 
+config MDIO_SUN4I
+	tristate "Allwinner sun4i MDIO interface support"
+	depends on ARCH_SUNXI
+	select REGULATOR
+	select REGULATOR_FIXED_VOLTAGE
+	help
+	  This driver supports the MDIO interface found in the network
+	  interface units of the Allwinner SoC that have an EMAC (A10,
+	  A12, A10s, etc.)
+
 config MDIO_BUS_MUX
 	tristate
 	depends on OF_MDIO
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/Makefile linux-libre-3.11-rc7-gnu/drivers/net/phy/Makefile
--- linux-libre-3.10-gnu/drivers/net/phy/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -30,3 +30,4 @@ obj-$(CONFIG_AMD_PHY)		+= amd.o
 obj-$(CONFIG_MDIO_BUS_MUX)	+= mdio-mux.o
 obj-$(CONFIG_MDIO_BUS_MUX_GPIO)	+= mdio-mux-gpio.o
 obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o
+obj-$(CONFIG_MDIO_SUN4I)	+= mdio-sun4i.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/marvell.c linux-libre-3.11-rc7-gnu/drivers/net/phy/marvell.c
--- linux-libre-3.10-gnu/drivers/net/phy/marvell.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/marvell.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,6 +116,8 @@
 #define MII_M1011_PHY_STATUS_RESOLVED	0x0800
 #define MII_M1011_PHY_STATUS_LINK	0x0400
 
+#define MII_M1116R_CONTROL_REG_MAC	21
+
 
 MODULE_DESCRIPTION("Marvell PHY driver");
 MODULE_AUTHOR("Andy Fleming");
@@ -372,6 +374,66 @@ static int m88e1318_config_aneg(struct p
 	return m88e1121_config_aneg(phydev);
 }
 
+static int m88e1510_config_aneg(struct phy_device *phydev)
+{
+	int err;
+
+	err = m88e1318_config_aneg(phydev);
+	if (err < 0)
+		return err;
+
+	return marvell_of_reg_init(phydev);
+}
+
+static int m88e1116r_config_init(struct phy_device *phydev)
+{
+	int temp;
+	int err;
+
+	temp = phy_read(phydev, MII_BMCR);
+	temp |= BMCR_RESET;
+	err = phy_write(phydev, MII_BMCR, temp);
+	if (err < 0)
+		return err;
+
+	mdelay(500);
+
+	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0);
+	if (err < 0)
+		return err;
+
+	temp = phy_read(phydev, MII_M1011_PHY_SCR);
+	temp |= (7 << 12);	/* max number of gigabit attempts */
+	temp |= (1 << 11);	/* enable downshift */
+	temp |= MII_M1011_PHY_SCR_AUTO_CROSS;
+	err = phy_write(phydev, MII_M1011_PHY_SCR, temp);
+	if (err < 0)
+		return err;
+
+	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 2);
+	if (err < 0)
+		return err;
+	temp = phy_read(phydev, MII_M1116R_CONTROL_REG_MAC);
+	temp |= (1 << 5);
+	temp |= (1 << 4);
+	err = phy_write(phydev, MII_M1116R_CONTROL_REG_MAC, temp);
+	if (err < 0)
+		return err;
+	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0);
+	if (err < 0)
+		return err;
+
+	temp = phy_read(phydev, MII_BMCR);
+	temp |= BMCR_RESET;
+	err = phy_write(phydev, MII_BMCR, temp);
+	if (err < 0)
+		return err;
+
+	mdelay(500);
+
+	return 0;
+}
+
 static int m88e1111_config_init(struct phy_device *phydev)
 {
 	int err;
@@ -940,6 +1002,32 @@ static struct phy_driver marvell_drivers
 		.config_intr = &marvell_config_intr,
 		.driver = { .owner = THIS_MODULE },
 	},
+	{
+		.phy_id = MARVELL_PHY_ID_88E1116R,
+		.phy_id_mask = MARVELL_PHY_ID_MASK,
+		.name = "Marvell 88E1116R",
+		.features = PHY_GBIT_FEATURES,
+		.flags = PHY_HAS_INTERRUPT,
+		.config_init = &m88e1116r_config_init,
+		.config_aneg = &genphy_config_aneg,
+		.read_status = &genphy_read_status,
+		.ack_interrupt = &marvell_ack_interrupt,
+		.config_intr = &marvell_config_intr,
+		.driver = { .owner = THIS_MODULE },
+	},
+	{
+		.phy_id = MARVELL_PHY_ID_88E1510,
+		.phy_id_mask = MARVELL_PHY_ID_MASK,
+		.name = "Marvell 88E1510",
+		.features = PHY_GBIT_FEATURES,
+		.flags = PHY_HAS_INTERRUPT,
+		.config_aneg = &m88e1510_config_aneg,
+		.read_status = &marvell_read_status,
+		.ack_interrupt = &marvell_ack_interrupt,
+		.config_intr = &marvell_config_intr,
+		.did_interrupt = &m88e1121_did_interrupt,
+		.driver = { .owner = THIS_MODULE },
+	},
 };
 
 static int __init marvell_init(void)
@@ -958,15 +1046,17 @@ module_init(marvell_init);
 module_exit(marvell_exit);
 
 static struct mdio_device_id __maybe_unused marvell_tbl[] = {
-	{ 0x01410c60, 0xfffffff0 },
-	{ 0x01410c90, 0xfffffff0 },
-	{ 0x01410cc0, 0xfffffff0 },
-	{ 0x01410e10, 0xfffffff0 },
-	{ 0x01410cb0, 0xfffffff0 },
-	{ 0x01410cd0, 0xfffffff0 },
-	{ 0x01410e50, 0xfffffff0 },
-	{ 0x01410e30, 0xfffffff0 },
-	{ 0x01410e90, 0xfffffff0 },
+	{ MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },
+	{ MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },
 	{ }
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/mdio-sun4i.c linux-libre-3.11-rc7-gnu/drivers/net/phy/mdio-sun4i.c
--- linux-libre-3.10-gnu/drivers/net/phy/mdio-sun4i.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/mdio-sun4i.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,192 @@
+/*
+ * Allwinner EMAC MDIO interface driver
+ *
+ * Copyright 2012-2013 Stefan Roese <sr@denx.de>
+ * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on the Linux driver provided by Allwinner:
+ * Copyright (C) 1997  Sten Wang
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_address.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#define EMAC_MAC_MCMD_REG	(0x00)
+#define EMAC_MAC_MADR_REG	(0x04)
+#define EMAC_MAC_MWTD_REG	(0x08)
+#define EMAC_MAC_MRDD_REG	(0x0c)
+#define EMAC_MAC_MIND_REG	(0x10)
+#define EMAC_MAC_SSRR_REG	(0x14)
+
+#define MDIO_TIMEOUT		(msecs_to_jiffies(100))
+
+struct sun4i_mdio_data {
+	void __iomem		*membase;
+	struct regulator	*regulator;
+};
+
+static int sun4i_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+	struct sun4i_mdio_data *data = bus->priv;
+	unsigned long timeout_jiffies;
+	int value;
+
+	/* issue the phy address and reg */
+	writel((mii_id << 8) | regnum, data->membase + EMAC_MAC_MADR_REG);
+	/* pull up the phy io line */
+	writel(0x1, data->membase + EMAC_MAC_MCMD_REG);
+
+	/* Wait read complete */
+	timeout_jiffies = jiffies + MDIO_TIMEOUT;
+	while (readl(data->membase + EMAC_MAC_MIND_REG) & 0x1) {
+		if (time_is_before_jiffies(timeout_jiffies))
+			return -ETIMEDOUT;
+		msleep(1);
+	}
+
+	/* push down the phy io line */
+	writel(0x0, data->membase + EMAC_MAC_MCMD_REG);
+	/* and read data */
+	value = readl(data->membase + EMAC_MAC_MRDD_REG);
+
+	return value;
+}
+
+static int sun4i_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+			    u16 value)
+{
+	struct sun4i_mdio_data *data = bus->priv;
+	unsigned long timeout_jiffies;
+
+	/* issue the phy address and reg */
+	writel((mii_id << 8) | regnum, data->membase + EMAC_MAC_MADR_REG);
+	/* pull up the phy io line */
+	writel(0x1, data->membase + EMAC_MAC_MCMD_REG);
+
+	/* Wait read complete */
+	timeout_jiffies = jiffies + MDIO_TIMEOUT;
+	while (readl(data->membase + EMAC_MAC_MIND_REG) & 0x1) {
+		if (time_is_before_jiffies(timeout_jiffies))
+			return -ETIMEDOUT;
+		msleep(1);
+	}
+
+	/* push down the phy io line */
+	writel(0x0, data->membase + EMAC_MAC_MCMD_REG);
+	/* and write data */
+	writel(value, data->membase + EMAC_MAC_MWTD_REG);
+
+	return 0;
+}
+
+static int sun4i_mdio_reset(struct mii_bus *bus)
+{
+	return 0;
+}
+
+static int sun4i_mdio_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct mii_bus *bus;
+	struct sun4i_mdio_data *data;
+	int ret, i;
+
+	bus = mdiobus_alloc_size(sizeof(*data));
+	if (!bus)
+		return -ENOMEM;
+
+	bus->name = "sun4i_mii_bus";
+	bus->read = &sun4i_mdio_read;
+	bus->write = &sun4i_mdio_write;
+	bus->reset = &sun4i_mdio_reset;
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev));
+	bus->parent = &pdev->dev;
+
+	bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+	if (!bus->irq) {
+		ret = -ENOMEM;
+		goto err_out_free_mdiobus;
+	}
+
+	for (i = 0; i < PHY_MAX_ADDR; i++)
+		bus->irq[i] = PHY_POLL;
+
+	data = bus->priv;
+	data->membase = of_iomap(np, 0);
+	if (!data->membase) {
+		ret = -ENOMEM;
+		goto err_out_free_mdio_irq;
+	}
+
+	data->regulator = devm_regulator_get(&pdev->dev, "phy");
+	if (IS_ERR(data->regulator)) {
+		if (PTR_ERR(data->regulator) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+
+		dev_info(&pdev->dev, "no regulator found\n");
+	} else {
+		ret = regulator_enable(data->regulator);
+		if (ret)
+			goto err_out_free_mdio_irq;
+	}
+
+	ret = of_mdiobus_register(bus, np);
+	if (ret < 0)
+		goto err_out_disable_regulator;
+
+	platform_set_drvdata(pdev, bus);
+
+	return 0;
+
+err_out_disable_regulator:
+	regulator_disable(data->regulator);
+err_out_free_mdio_irq:
+	kfree(bus->irq);
+err_out_free_mdiobus:
+	mdiobus_free(bus);
+	return ret;
+}
+
+static int sun4i_mdio_remove(struct platform_device *pdev)
+{
+	struct mii_bus *bus = platform_get_drvdata(pdev);
+
+	mdiobus_unregister(bus);
+	kfree(bus->irq);
+	mdiobus_free(bus);
+
+	return 0;
+}
+
+static const struct of_device_id sun4i_mdio_dt_ids[] = {
+	{ .compatible = "allwinner,sun4i-mdio" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sun4i_mdio_dt_ids);
+
+static struct platform_driver sun4i_mdio_driver = {
+	.probe = sun4i_mdio_probe,
+	.remove = sun4i_mdio_remove,
+	.driver = {
+		.name = "sun4i-mdio",
+		.of_match_table = sun4i_mdio_dt_ids,
+	},
+};
+
+module_platform_driver(sun4i_mdio_driver);
+
+MODULE_DESCRIPTION("Allwinner EMAC MDIO interface driver");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/phy.c linux-libre-3.11-rc7-gnu/drivers/net/phy/phy.c
--- linux-libre-3.10-gnu/drivers/net/phy/phy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/phy.c	2013-08-25 20:43:22.000000000 -0400
@@ -294,7 +294,8 @@ int phy_ethtool_gset(struct phy_device *
 	cmd->duplex = phydev->duplex;
 	cmd->port = PORT_MII;
 	cmd->phy_address = phydev->addr;
-	cmd->transceiver = XCVR_EXTERNAL;
+	cmd->transceiver = phy_is_internal(phydev) ?
+		XCVR_INTERNAL : XCVR_EXTERNAL;
 	cmd->autoneg = phydev->autoneg;
 
 	return 0;
@@ -419,8 +420,6 @@ out_unlock:
 EXPORT_SYMBOL(phy_start_aneg);
 
 
-static void phy_change(struct work_struct *work);
-
 /**
  * phy_start_machine - start PHY state machine tracking
  * @phydev: the phy_device struct
@@ -439,7 +438,7 @@ void phy_start_machine(struct phy_device
 {
 	phydev->adjust_state = handler;
 
-	schedule_delayed_work(&phydev->state_queue, HZ);
+	queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, HZ);
 }
 
 /**
@@ -500,7 +499,7 @@ static irqreturn_t phy_interrupt(int irq
 	disable_irq_nosync(irq);
 	atomic_inc(&phydev->irq_disable);
 
-	schedule_work(&phydev->phy_queue);
+	queue_work(system_power_efficient_wq, &phydev->phy_queue);
 
 	return IRQ_HANDLED;
 }
@@ -565,8 +564,6 @@ int phy_start_interrupts(struct phy_devi
 {
 	int err = 0;
 
-	INIT_WORK(&phydev->phy_queue, phy_change);
-
 	atomic_set(&phydev->irq_disable, 0);
 	if (request_irq(phydev->irq, phy_interrupt,
 				IRQF_SHARED,
@@ -623,7 +620,7 @@ EXPORT_SYMBOL(phy_stop_interrupts);
  * phy_change - Scheduled by the phy_interrupt/timer to handle PHY changes
  * @work: work_struct that describes the work to be done
  */
-static void phy_change(struct work_struct *work)
+void phy_change(struct work_struct *work)
 {
 	int err;
 	struct phy_device *phydev =
@@ -655,7 +652,7 @@ static void phy_change(struct work_struc
 
 	/* reschedule state queue work to run as soon as possible */
 	cancel_delayed_work_sync(&phydev->state_queue);
-	schedule_delayed_work(&phydev->state_queue, 0);
+	queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
 
 	return;
 
@@ -682,7 +679,7 @@ void phy_stop(struct phy_device *phydev)
 	if (PHY_HALTED == phydev->state)
 		goto out_unlock;
 
-	if (phydev->irq != PHY_POLL) {
+	if (phy_interrupt_is_valid(phydev)) {
 		/* Disable PHY Interrupts */
 		phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
 
@@ -828,8 +825,9 @@ void phy_state_machine(struct work_struc
 			break;
 		case PHY_RUNNING:
 			/* Only register a CHANGE if we are
-			 * polling */
-			if (PHY_POLL == phydev->irq)
+			 * polling or ignoring interrupts
+			 */
+			if (!phy_interrupt_is_valid(phydev))
 				phydev->state = PHY_CHANGELINK;
 			break;
 		case PHY_CHANGELINK:
@@ -848,7 +846,7 @@ void phy_state_machine(struct work_struc
 
 			phydev->adjust_link(phydev->attached_dev);
 
-			if (PHY_POLL != phydev->irq)
+			if (phy_interrupt_is_valid(phydev))
 				err = phy_config_interrupt(phydev,
 						PHY_INTERRUPT_ENABLED);
 			break;
@@ -918,9 +916,18 @@ void phy_state_machine(struct work_struc
 	if (err < 0)
 		phy_error(phydev);
 
-	schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ);
+	queue_delayed_work(system_power_efficient_wq, &phydev->state_queue,
+			PHY_STATE_TIME * HZ);
 }
 
+void phy_mac_interrupt(struct phy_device *phydev, int new_link)
+{
+	cancel_work_sync(&phydev->phy_queue);
+	phydev->link = new_link;
+	schedule_work(&phydev->phy_queue);
+}
+EXPORT_SYMBOL(phy_mac_interrupt);
+
 static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
 				    int addr)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/phy_device.c linux-libre-3.11-rc7-gnu/drivers/net/phy/phy_device.c
--- linux-libre-3.10-gnu/drivers/net/phy/phy_device.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/phy_device.c	2013-08-25 20:43:22.000000000 -0400
@@ -189,6 +189,7 @@ struct phy_device *phy_device_create(str
 
 	mutex_init(&dev->lock);
 	INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
+	INIT_WORK(&dev->phy_queue, phy_change);
 
 	/* Request the appropriate module unconditionally; don't
 	   bother trying to do so only if it isn't already loaded,
@@ -1009,10 +1010,16 @@ static int phy_probe(struct device *dev)
 	phydrv = to_phy_driver(drv);
 	phydev->drv = phydrv;
 
-	/* Disable the interrupt if the PHY doesn't support it */
-	if (!(phydrv->flags & PHY_HAS_INTERRUPT))
+	/* Disable the interrupt if the PHY doesn't support it
+	 * but the interrupt is still a valid one
+	 */
+	if (!(phydrv->flags & PHY_HAS_INTERRUPT) &&
+			phy_interrupt_is_valid(phydev))
 		phydev->irq = PHY_POLL;
 
+	if (phydrv->flags & PHY_IS_INTERNAL)
+		phydev->is_internal = true;
+
 	mutex_lock(&phydev->lock);
 
 	/* Start out supporting everything. Eventually,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/realtek.c linux-libre-3.11-rc7-gnu/drivers/net/phy/realtek.c
--- linux-libre-3.10-gnu/drivers/net/phy/realtek.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/realtek.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,7 @@
 #define RTL821x_INER_INIT	0x6400
 #define RTL821x_INSR		0x13
 
-#define	RTL8211E_INER_LINK_STAT	0x10
+#define	RTL8211E_INER_LINK_STATUS	0x400
 
 MODULE_DESCRIPTION("Realtek PHY driver");
 MODULE_AUTHOR("Johnson Leung");
@@ -57,7 +57,7 @@ static int rtl8211e_config_intr(struct p
 
 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 		err = phy_write(phydev, RTL821x_INER,
-				RTL8211E_INER_LINK_STAT);
+				RTL8211E_INER_LINK_STATUS);
 	else
 		err = phy_write(phydev, RTL821x_INER, 0);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/spi_ks8995.c linux-libre-3.11-rc7-gnu/drivers/net/phy/spi_ks8995.c
--- linux-libre-3.10-gnu/drivers/net/phy/spi_ks8995.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/spi_ks8995.c	2013-08-25 20:43:22.000000000 -0400
@@ -354,19 +354,7 @@ static struct spi_driver ks8995_driver =
 	.remove	  = ks8995_remove,
 };
 
-static int __init ks8995_init(void)
-{
-	pr_info(DRV_DESC " version " DRV_VERSION "\n");
-
-	return spi_register_driver(&ks8995_driver);
-}
-module_init(ks8995_init);
-
-static void __exit ks8995_exit(void)
-{
-	spi_unregister_driver(&ks8995_driver);
-}
-module_exit(ks8995_exit);
+module_spi_driver(ks8995_driver);
 
 MODULE_DESCRIPTION(DRV_DESC);
 MODULE_VERSION(DRV_VERSION);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/phy/vitesse.c linux-libre-3.11-rc7-gnu/drivers/net/phy/vitesse.c
--- linux-libre-3.10-gnu/drivers/net/phy/vitesse.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/phy/vitesse.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,18 +44,19 @@
 #define MII_VSC8244_ISTAT_DUPLEX	0x1000
 
 /* Vitesse Auxiliary Control/Status Register */
-#define MII_VSC8244_AUX_CONSTAT        	0x1c
-#define MII_VSC8244_AUXCONSTAT_INIT    	0x0000
-#define MII_VSC8244_AUXCONSTAT_DUPLEX  	0x0020
-#define MII_VSC8244_AUXCONSTAT_SPEED   	0x0018
-#define MII_VSC8244_AUXCONSTAT_GBIT    	0x0010
-#define MII_VSC8244_AUXCONSTAT_100     	0x0008
+#define MII_VSC8244_AUX_CONSTAT		0x1c
+#define MII_VSC8244_AUXCONSTAT_INIT	0x0000
+#define MII_VSC8244_AUXCONSTAT_DUPLEX	0x0020
+#define MII_VSC8244_AUXCONSTAT_SPEED	0x0018
+#define MII_VSC8244_AUXCONSTAT_GBIT	0x0010
+#define MII_VSC8244_AUXCONSTAT_100	0x0008
 
 #define MII_VSC8221_AUXCONSTAT_INIT	0x0004 /* need to set this bit? */
 #define MII_VSC8221_AUXCONSTAT_RESERVED	0x0004
 
 #define PHY_ID_VSC8244			0x000fc6c0
 #define PHY_ID_VSC8221			0x000fc550
+#define PHY_ID_VSC8211			0x000fc4b0
 
 MODULE_DESCRIPTION("Vitesse PHY driver");
 MODULE_AUTHOR("Kriston Carson");
@@ -100,9 +101,8 @@ static int vsc824x_config_init(struct ph
 static int vsc824x_ack_interrupt(struct phy_device *phydev)
 {
 	int err = 0;
-	
-	/*
-	 * Don't bother to ACK the interrupts if interrupts
+
+	/* Don't bother to ACK the interrupts if interrupts
 	 * are disabled.  The 824x cannot clear the interrupts
 	 * if they are disabled.
 	 */
@@ -122,8 +122,7 @@ static int vsc82xx_config_intr(struct ph
 				MII_VSC8244_IMASK_MASK :
 				MII_VSC8221_IMASK_MASK);
 	else {
-		/*
-		 * The Vitesse PHY cannot clear the interrupt
+		/* The Vitesse PHY cannot clear the interrupt
 		 * once it has disabled them, so we clear them first
 		 */
 		err = phy_read(phydev, MII_VSC8244_ISTAT);
@@ -146,7 +145,8 @@ static int vsc8221_config_init(struct ph
 	return err;
 
 	/* Perhaps we should set EXT_CON1 based on the interface?
-	   Options are 802.3Z SerDes or SGMII */
+	 * Options are 802.3Z SerDes or SGMII
+	 */
 }
 
 /* Vitesse 824x */
@@ -176,6 +176,19 @@ static struct phy_driver vsc82xx_driver[
 	.ack_interrupt	= &vsc824x_ack_interrupt,
 	.config_intr	= &vsc82xx_config_intr,
 	.driver		= { .owner = THIS_MODULE,},
+}, {
+	/* Vitesse 8211 */
+	.phy_id		= PHY_ID_VSC8211,
+	.phy_id_mask	= 0x000ffff0,
+	.name		= "Vitesse VSC8211",
+	.features	= PHY_GBIT_FEATURES,
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_init	= &vsc8221_config_init,
+	.config_aneg	= &genphy_config_aneg,
+	.read_status	= &genphy_read_status,
+	.ack_interrupt	= &vsc824x_ack_interrupt,
+	.config_intr	= &vsc82xx_config_intr,
+	.driver		= { .owner = THIS_MODULE,},
 } };
 
 static int __init vsc82xx_init(void)
@@ -196,6 +209,7 @@ module_exit(vsc82xx_exit);
 static struct mdio_device_id __maybe_unused vitesse_tbl[] = {
 	{ PHY_ID_VSC8244, 0x000fffc0 },
 	{ PHY_ID_VSC8221, 0x000ffff0 },
+	{ PHY_ID_VSC8211, 0x000ffff0 },
 	{ }
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/ppp/pppoe.c linux-libre-3.11-rc7-gnu/drivers/net/ppp/pppoe.c
--- linux-libre-3.10-gnu/drivers/net/ppp/pppoe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/ppp/pppoe.c	2013-08-25 20:43:22.000000000 -0400
@@ -338,7 +338,7 @@ static void pppoe_flush_dev(struct net_d
 static int pppoe_device_event(struct notifier_block *this,
 			      unsigned long event, void *ptr)
 {
-	struct net_device *dev = (struct net_device *)ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 
 	/* Only look at sockets that are using this specific device. */
 	switch (event) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/rionet.c linux-libre-3.11-rc7-gnu/drivers/net/rionet.c
--- linux-libre-3.10-gnu/drivers/net/rionet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/rionet.c	2013-08-25 20:43:22.000000000 -0400
@@ -208,6 +208,17 @@ static int rionet_start_xmit(struct sk_b
 		if (nets[rnet->mport->id].active[destid])
 			rionet_queue_tx_msg(skb, ndev,
 					nets[rnet->mport->id].active[destid]);
+		else {
+			/*
+			 * If the target device was removed from the list of
+			 * active peers but we still have TX packets targeting
+			 * it just report sending a packet to the target
+			 * (without actual packet transfer).
+			 */
+			dev_kfree_skb_any(skb);
+			ndev->stats.tx_packets++;
+			ndev->stats.tx_bytes += skb->len;
+		}
 	}
 
 	spin_unlock_irqrestore(&rnet->tx_lock, flags);
@@ -385,24 +396,28 @@ static int rionet_close(struct net_devic
 	return 0;
 }
 
-static void rionet_remove(struct rio_dev *rdev)
+static int rionet_remove_dev(struct device *dev, struct subsys_interface *sif)
 {
-	struct net_device *ndev = rio_get_drvdata(rdev);
+	struct rio_dev *rdev = to_rio_dev(dev);
 	unsigned char netid = rdev->net->hport->id;
 	struct rionet_peer *peer, *tmp;
 
-	unregister_netdev(ndev);
-
-	free_pages((unsigned long)nets[netid].active, get_order(sizeof(void *) *
-			RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size)));
-	nets[netid].active = NULL;
+	if (dev_rionet_capable(rdev)) {
+		list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
+			if (peer->rdev == rdev) {
+				if (nets[netid].active[rdev->destid]) {
+					nets[netid].active[rdev->destid] = NULL;
+					nets[netid].nact--;
+				}
 
-	list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
-		list_del(&peer->node);
-		kfree(peer);
+				list_del(&peer->node);
+				kfree(peer);
+				break;
+			}
+		}
 	}
 
-	free_netdev(ndev);
+	return 0;
 }
 
 static void rionet_get_drvinfo(struct net_device *ndev,
@@ -503,12 +518,13 @@ static int rionet_setup_netdev(struct ri
 
 static unsigned long net_table[RIONET_MAX_NETS/sizeof(unsigned long) + 1];
 
-static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
+static int rionet_add_dev(struct device *dev, struct subsys_interface *sif)
 {
 	int rc = -ENODEV;
 	u32 lsrc_ops, ldst_ops;
 	struct rionet_peer *peer;
 	struct net_device *ndev = NULL;
+	struct rio_dev *rdev = to_rio_dev(dev);
 	unsigned char netid = rdev->net->hport->id;
 	int oldnet;
 
@@ -518,8 +534,9 @@ static int rionet_probe(struct rio_dev *
 	oldnet = test_and_set_bit(netid, net_table);
 
 	/*
-	 * First time through, make sure local device is rionet
-	 * capable, setup netdev (will be skipped on later probes)
+	 * If first time through this net, make sure local device is rionet
+	 * capable and setup netdev (this step will be skipped in later probes
+	 * on the same net).
 	 */
 	if (!oldnet) {
 		rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
@@ -541,6 +558,12 @@ static int rionet_probe(struct rio_dev *
 		}
 		nets[netid].ndev = ndev;
 		rc = rionet_setup_netdev(rdev->net->hport, ndev);
+		if (rc) {
+			printk(KERN_ERR "%s: failed to setup netdev (rc=%d)\n",
+			       DRV_NAME, rc);
+			goto out;
+		}
+
 		INIT_LIST_HEAD(&nets[netid].peers);
 		nets[netid].nact = 0;
 	} else if (nets[netid].ndev == NULL)
@@ -559,31 +582,61 @@ static int rionet_probe(struct rio_dev *
 		list_add_tail(&peer->node, &nets[netid].peers);
 	}
 
-	rio_set_drvdata(rdev, nets[netid].ndev);
-
-      out:
+	return 0;
+out:
 	return rc;
 }
 
+#ifdef MODULE
 static struct rio_device_id rionet_id_table[] = {
-	{RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}
+	{RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)},
+	{ 0, }	/* terminate list */
 };
 
-static struct rio_driver rionet_driver = {
-	.name = "rionet",
-	.id_table = rionet_id_table,
-	.probe = rionet_probe,
-	.remove = rionet_remove,
+MODULE_DEVICE_TABLE(rapidio, rionet_id_table);
+#endif
+
+static struct subsys_interface rionet_interface = {
+	.name		= "rionet",
+	.subsys		= &rio_bus_type,
+	.add_dev	= rionet_add_dev,
+	.remove_dev	= rionet_remove_dev,
 };
 
 static int __init rionet_init(void)
 {
-	return rio_register_driver(&rionet_driver);
+	return subsys_interface_register(&rionet_interface);
 }
 
 static void __exit rionet_exit(void)
 {
-	rio_unregister_driver(&rionet_driver);
+	struct rionet_private *rnet;
+	struct net_device *ndev;
+	struct rionet_peer *peer, *tmp;
+	int i;
+
+	for (i = 0; i < RIONET_MAX_NETS; i++) {
+		if (nets[i].ndev != NULL) {
+			ndev = nets[i].ndev;
+			rnet = netdev_priv(ndev);
+			unregister_netdev(ndev);
+
+			list_for_each_entry_safe(peer,
+						 tmp, &nets[i].peers, node) {
+				list_del(&peer->node);
+				kfree(peer);
+			}
+
+			free_pages((unsigned long)nets[i].active,
+				 get_order(sizeof(void *) *
+				 RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size)));
+			nets[i].active = NULL;
+
+			free_netdev(ndev);
+		}
+	}
+
+	subsys_interface_unregister(&rionet_interface);
 }
 
 late_initcall(rionet_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/team/team.c linux-libre-3.11-rc7-gnu/drivers/net/team/team.c
--- linux-libre-3.10-gnu/drivers/net/team/team.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/team/team.c	2013-08-25 20:43:22.000000000 -0400
@@ -525,31 +525,26 @@ static void team_set_no_mode(struct team
 	team->mode = &__team_no_mode;
 }
 
-static void __team_adjust_ops(struct team *team, int en_port_count)
+static void team_adjust_ops(struct team *team)
 {
 	/*
 	 * To avoid checks in rx/tx skb paths, ensure here that non-null and
 	 * correct ops are always set.
 	 */
 
-	if (!en_port_count || !team_is_mode_set(team) ||
+	if (!team->en_port_count || !team_is_mode_set(team) ||
 	    !team->mode->ops->transmit)
 		team->ops.transmit = team_dummy_transmit;
 	else
 		team->ops.transmit = team->mode->ops->transmit;
 
-	if (!en_port_count || !team_is_mode_set(team) ||
+	if (!team->en_port_count || !team_is_mode_set(team) ||
 	    !team->mode->ops->receive)
 		team->ops.receive = team_dummy_receive;
 	else
 		team->ops.receive = team->mode->ops->receive;
 }
 
-static void team_adjust_ops(struct team *team)
-{
-	__team_adjust_ops(team, team->en_port_count);
-}
-
 /*
  * We can benefit from the fact that it's ensured no port is present
  * at the time of mode change. Therefore no packets are in fly so there's no
@@ -725,9 +720,9 @@ static bool team_queue_override_transmit
 static void __team_queue_override_port_del(struct team *team,
 					   struct team_port *port)
 {
+	if (!port->queue_id)
+		return;
 	list_del_rcu(&port->qom_list);
-	synchronize_rcu();
-	INIT_LIST_HEAD(&port->qom_list);
 }
 
 static bool team_queue_override_port_has_gt_prio_than(struct team_port *port,
@@ -749,9 +744,8 @@ static void __team_queue_override_port_a
 	struct list_head *qom_list;
 	struct list_head *node;
 
-	if (!port->queue_id || !team_port_enabled(port))
+	if (!port->queue_id)
 		return;
-
 	qom_list = __team_get_qom_list(team, port->queue_id);
 	node = qom_list;
 	list_for_each_entry(cur, qom_list, qom_list) {
@@ -768,7 +762,7 @@ static void __team_queue_override_enable
 	bool enabled = false;
 
 	list_for_each_entry(port, &team->port_list, list) {
-		if (!list_empty(&port->qom_list)) {
+		if (port->queue_id) {
 			enabled = true;
 			break;
 		}
@@ -780,14 +774,44 @@ static void __team_queue_override_enable
 	team->queue_override_enabled = enabled;
 }
 
-static void team_queue_override_port_refresh(struct team *team,
-					     struct team_port *port)
+static void team_queue_override_port_prio_changed(struct team *team,
+						  struct team_port *port)
 {
+	if (!port->queue_id || team_port_enabled(port))
+		return;
 	__team_queue_override_port_del(team, port);
 	__team_queue_override_port_add(team, port);
 	__team_queue_override_enabled_check(team);
 }
 
+static void team_queue_override_port_change_queue_id(struct team *team,
+						     struct team_port *port,
+						     u16 new_queue_id)
+{
+	if (team_port_enabled(port)) {
+		__team_queue_override_port_del(team, port);
+		port->queue_id = new_queue_id;
+		__team_queue_override_port_add(team, port);
+		__team_queue_override_enabled_check(team);
+	} else {
+		port->queue_id = new_queue_id;
+	}
+}
+
+static void team_queue_override_port_add(struct team *team,
+					 struct team_port *port)
+{
+	__team_queue_override_port_add(team, port);
+	__team_queue_override_enabled_check(team);
+}
+
+static void team_queue_override_port_del(struct team *team,
+					 struct team_port *port)
+{
+	__team_queue_override_port_del(team, port);
+	__team_queue_override_enabled_check(team);
+}
+
 
 /****************
  * Port handling
@@ -819,7 +843,7 @@ static void team_port_enable(struct team
 	hlist_add_head_rcu(&port->hlist,
 			   team_port_index_hash(team, port->index));
 	team_adjust_ops(team);
-	team_queue_override_port_refresh(team, port);
+	team_queue_override_port_add(team, port);
 	if (team->ops.port_enabled)
 		team->ops.port_enabled(team, port);
 }
@@ -848,14 +872,9 @@ static void team_port_disable(struct tea
 	hlist_del_rcu(&port->hlist);
 	__reconstruct_port_hlist(team, port->index);
 	port->index = -1;
-	team_queue_override_port_refresh(team, port);
-	__team_adjust_ops(team, team->en_port_count - 1);
-	/*
-	 * Wait until readers see adjusted ops. This ensures that
-	 * readers never see team->en_port_count == 0
-	 */
-	synchronize_rcu();
 	team->en_port_count--;
+	team_queue_override_port_del(team, port);
+	team_adjust_ops(team);
 }
 
 #define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \
@@ -1163,8 +1182,7 @@ static int team_port_del(struct team *te
 
 	team_port_set_orig_dev_addr(port);
 	dev_set_mtu(port_dev, port->orig.mtu);
-	synchronize_rcu();
-	kfree(port);
+	kfree_rcu(port, rcu);
 	netdev_info(dev, "Port device %s removed\n", portname);
 	__team_compute_features(team);
 
@@ -1259,9 +1277,12 @@ static int team_priority_option_set(stru
 				    struct team_gsetter_ctx *ctx)
 {
 	struct team_port *port = ctx->info->port;
+	s32 priority = ctx->data.s32_val;
 
-	port->priority = ctx->data.s32_val;
-	team_queue_override_port_refresh(team, port);
+	if (port->priority == priority)
+		return 0;
+	port->priority = priority;
+	team_queue_override_port_prio_changed(team, port);
 	return 0;
 }
 
@@ -1278,17 +1299,16 @@ static int team_queue_id_option_set(stru
 				    struct team_gsetter_ctx *ctx)
 {
 	struct team_port *port = ctx->info->port;
+	u16 new_queue_id = ctx->data.u32_val;
 
-	if (port->queue_id == ctx->data.u32_val)
+	if (port->queue_id == new_queue_id)
 		return 0;
-	if (ctx->data.u32_val >= team->dev->real_num_tx_queues)
+	if (new_queue_id >= team->dev->real_num_tx_queues)
 		return -EINVAL;
-	port->queue_id = ctx->data.u32_val;
-	team_queue_override_port_refresh(team, port);
+	team_queue_override_port_change_queue_id(team, port, new_queue_id);
 	return 0;
 }
 
-
 static const struct team_option team_options[] = {
 	{
 		.name = "mode",
@@ -2648,7 +2668,7 @@ static void team_port_change_check(struc
 static int team_device_event(struct notifier_block *unused,
 			     unsigned long event, void *ptr)
 {
-	struct net_device *dev = (struct net_device *) ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct team_port *port;
 
 	port = team_port_get_rtnl(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/team/team_mode_loadbalance.c linux-libre-3.11-rc7-gnu/drivers/net/team/team_mode_loadbalance.c
--- linux-libre-3.10-gnu/drivers/net/team/team_mode_loadbalance.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/team/team_mode_loadbalance.c	2013-08-25 20:43:22.000000000 -0400
@@ -112,9 +112,8 @@ static struct team_port *lb_hash_select_
 						struct sk_buff *skb,
 						unsigned char hash)
 {
-	int port_index;
+	int port_index = team_num_to_port_index(team, hash);
 
-	port_index = hash % team->en_port_count;
 	return team_get_port_by_index_rcu(team, port_index);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/team/team_mode_roundrobin.c linux-libre-3.11-rc7-gnu/drivers/net/team/team_mode_roundrobin.c
--- linux-libre-3.10-gnu/drivers/net/team/team_mode_roundrobin.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/team/team_mode_roundrobin.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,8 @@ static bool rr_transmit(struct team *tea
 	struct team_port *port;
 	int port_index;
 
-	port_index = rr_priv(team)->sent_packets++ % team->en_port_count;
+	port_index = team_num_to_port_index(team,
+					    rr_priv(team)->sent_packets++);
 	port = team_get_port_by_index_rcu(team, port_index);
 	if (unlikely(!port))
 		goto drop;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/tun.c linux-libre-3.11-rc7-gnu/drivers/net/tun.c
--- linux-libre-3.10-gnu/drivers/net/tun.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/tun.c	2013-08-25 20:43:22.000000000 -0400
@@ -841,7 +841,7 @@ static const struct net_device_ops tap_n
 #endif
 };
 
-static int tun_flow_init(struct tun_struct *tun)
+static void tun_flow_init(struct tun_struct *tun)
 {
 	int i;
 
@@ -852,8 +852,6 @@ static int tun_flow_init(struct tun_stru
 	setup_timer(&tun->flow_gc_timer, tun_flow_cleanup, (unsigned long)tun);
 	mod_timer(&tun->flow_gc_timer,
 		  round_jiffies_up(jiffies + tun->ageing_time));
-
-	return 0;
 }
 
 static void tun_flow_uninit(struct tun_struct *tun)
@@ -1037,6 +1035,29 @@ static int zerocopy_sg_from_iovec(struct
 	return 0;
 }
 
+static unsigned long iov_pages(const struct iovec *iv, int offset,
+			       unsigned long nr_segs)
+{
+	unsigned long seg, base;
+	int pages = 0, len, size;
+
+	while (nr_segs && (offset >= iv->iov_len)) {
+		offset -= iv->iov_len;
+		++iv;
+		--nr_segs;
+	}
+
+	for (seg = 0; seg < nr_segs; seg++) {
+		base = (unsigned long)iv[seg].iov_base + offset;
+		len = iv[seg].iov_len - offset;
+		size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
+		pages += size;
+		offset = 0;
+	}
+
+	return pages;
+}
+
 /* Get packet from user space buffer */
 static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 			    void *msg_control, const struct iovec *iv,
@@ -1044,7 +1065,7 @@ static ssize_t tun_get_user(struct tun_s
 {
 	struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
 	struct sk_buff *skb;
-	size_t len = total_len, align = NET_SKB_PAD;
+	size_t len = total_len, align = NET_SKB_PAD, linear;
 	struct virtio_net_hdr gso = { 0 };
 	int offset = 0;
 	int copylen;
@@ -1053,8 +1074,9 @@ static ssize_t tun_get_user(struct tun_s
 	u32 rxhash;
 
 	if (!(tun->flags & TUN_NO_PI)) {
-		if ((len -= sizeof(pi)) > total_len)
+		if (len < sizeof(pi))
 			return -EINVAL;
+		len -= sizeof(pi);
 
 		if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
 			return -EFAULT;
@@ -1062,8 +1084,9 @@ static ssize_t tun_get_user(struct tun_s
 	}
 
 	if (tun->flags & TUN_VNET_HDR) {
-		if ((len -= tun->vnet_hdr_sz) > total_len)
+		if (len < tun->vnet_hdr_sz)
 			return -EINVAL;
+		len -= tun->vnet_hdr_sz;
 
 		if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
 			return -EFAULT;
@@ -1084,34 +1107,23 @@ static ssize_t tun_get_user(struct tun_s
 			return -EINVAL;
 	}
 
-	if (msg_control)
-		zerocopy = true;
-
-	if (zerocopy) {
-		/* Userspace may produce vectors with count greater than
-		 * MAX_SKB_FRAGS, so we need to linearize parts of the skb
-		 * to let the rest of data to be fit in the frags.
-		 */
-		if (count > MAX_SKB_FRAGS) {
-			copylen = iov_length(iv, count - MAX_SKB_FRAGS);
-			if (copylen < offset)
-				copylen = 0;
-			else
-				copylen -= offset;
-		} else
-				copylen = 0;
-		/* There are 256 bytes to be copied in skb, so there is enough
-		 * room for skb expand head in case it is used.
+	if (msg_control) {
+		/* There are 256 bytes to be copied in skb, so there is
+		 * enough room for skb expand head in case it is used.
 		 * The rest of the buffer is mapped from userspace.
 		 */
-		if (copylen < gso.hdr_len)
-			copylen = gso.hdr_len;
-		if (!copylen)
-			copylen = GOODCOPY_LEN;
-	} else
+		copylen = gso.hdr_len ? gso.hdr_len : GOODCOPY_LEN;
+		linear = copylen;
+		if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS)
+			zerocopy = true;
+	}
+
+	if (!zerocopy) {
 		copylen = len;
+		linear = gso.hdr_len;
+	}
 
-	skb = tun_alloc_skb(tfile, align, copylen, gso.hdr_len, noblock);
+	skb = tun_alloc_skb(tfile, align, copylen, linear, noblock);
 	if (IS_ERR(skb)) {
 		if (PTR_ERR(skb) != -EAGAIN)
 			tun->dev->stats.rx_dropped++;
@@ -1120,8 +1132,13 @@ static ssize_t tun_get_user(struct tun_s
 
 	if (zerocopy)
 		err = zerocopy_sg_from_iovec(skb, iv, offset, count);
-	else
+	else {
 		err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len);
+		if (!err && msg_control) {
+			struct ubuf_info *uarg = msg_control;
+			uarg->callback(uarg, false);
+		}
+	}
 
 	if (err) {
 		tun->dev->stats.rx_dropped++;
@@ -1532,6 +1549,9 @@ static int tun_flags(struct tun_struct *
 	if (tun->flags & TUN_TAP_MQ)
 		flags |= IFF_MULTI_QUEUE;
 
+	if (tun->flags & TUN_PERSIST)
+		flags |= IFF_PERSIST;
+
 	return flags;
 }
 
@@ -1661,10 +1681,7 @@ static int tun_set_iff(struct net *net,
 			goto err_free_dev;
 
 		tun_net_init(dev);
-
-		err = tun_flow_init(tun);
-		if (err < 0)
-			goto err_free_dev;
+		tun_flow_init(tun);
 
 		dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST |
 			TUN_USER_FEATURES;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/ax88179_178a.c linux-libre-3.11-rc7-gnu/drivers/net/usb/ax88179_178a.c
--- linux-libre-3.10-gnu/drivers/net/usb/ax88179_178a.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/ax88179_178a.c	2013-08-25 20:43:22.000000000 -0400
@@ -1029,10 +1029,10 @@ static int ax88179_bind(struct usbnet *d
 	dev->mii.supports_gmii = 1;
 
 	dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-			      NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+			      NETIF_F_RXCSUM;
 
 	dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-				 NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+				 NETIF_F_RXCSUM;
 
 	/* Enable checksum offload */
 	*tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
@@ -1173,7 +1173,6 @@ ax88179_tx_fixup(struct usbnet *dev, str
 	if (((skb->len + 8) % frame_size) == 0)
 		tx_hdr2 |= 0x80008000;	/* Enable padding */
 
-	skb_linearize(skb);
 	headroom = skb_headroom(skb);
 	tailroom = skb_tailroom(skb);
 
@@ -1317,10 +1316,10 @@ static int ax88179_reset(struct usbnet *
 			  1, 1, tmp);
 
 	dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-			      NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+			      NETIF_F_RXCSUM;
 
 	dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-				 NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+				 NETIF_F_RXCSUM;
 
 	/* Enable checksum offload */
 	*tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
@@ -1371,7 +1370,7 @@ static int ax88179_stop(struct usbnet *d
 }
 
 static const struct driver_info ax88179_info = {
-	.description = "ASIX AX88179 USB 3.0 Gigibit Ethernet",
+	.description = "ASIX AX88179 USB 3.0 Gigabit Ethernet",
 	.bind = ax88179_bind,
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
@@ -1384,7 +1383,7 @@ static const struct driver_info ax88179_
 };
 
 static const struct driver_info ax88178a_info = {
-	.description = "ASIX AX88178A USB 2.0 Gigibit Ethernet",
+	.description = "ASIX AX88178A USB 2.0 Gigabit Ethernet",
 	.bind = ax88179_bind,
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
@@ -1433,6 +1432,7 @@ static struct usb_driver ax88179_178a_dr
 	.probe =	usbnet_probe,
 	.suspend =	ax88179_suspend,
 	.resume =	ax88179_resume,
+	.reset_resume =	ax88179_resume,
 	.disconnect =	usbnet_disconnect,
 	.supports_autosuspend = 1,
 	.disable_hub_initiated_lpm = 1,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/cdc_ether.c linux-libre-3.11-rc7-gnu/drivers/net/usb/cdc_ether.c
--- linux-libre-3.10-gnu/drivers/net/usb/cdc_ether.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/cdc_ether.c	2013-08-25 20:43:22.000000000 -0400
@@ -215,6 +215,10 @@ int usbnet_generic_cdc_bind(struct usbne
 					goto bad_desc;
 			}
 
+			/* some devices merge these - skip class check */
+			if (info->control == info->data)
+				goto next_desc;
+
 			/* a data interface altsetting does the real i/o */
 			d = &info->data->cur_altsetting->desc;
 			if (d->bInterfaceClass != USB_CLASS_CDC_DATA) {
@@ -304,19 +308,23 @@ next_desc:
 	/* claim data interface and set it up ... with side effects.
 	 * network traffic can't flow until an altsetting is enabled.
 	 */
-	status = usb_driver_claim_interface(driver, info->data, dev);
-	if (status < 0)
-		return status;
+	if (info->data != info->control) {
+		status = usb_driver_claim_interface(driver, info->data, dev);
+		if (status < 0)
+			return status;
+	}
 	status = usbnet_get_endpoints(dev, info->data);
 	if (status < 0) {
 		/* ensure immediate exit from usbnet_disconnect */
 		usb_set_intfdata(info->data, NULL);
-		usb_driver_release_interface(driver, info->data);
+		if (info->data != info->control)
+			usb_driver_release_interface(driver, info->data);
 		return status;
 	}
 
 	/* status endpoint: optional for CDC Ethernet, not RNDIS (or ACM) */
-	dev->status = NULL;
+	if (info->data != info->control)
+		dev->status = NULL;
 	if (info->control->cur_altsetting->desc.bNumEndpoints == 1) {
 		struct usb_endpoint_descriptor	*desc;
 
@@ -349,6 +357,10 @@ void usbnet_cdc_unbind(struct usbnet *de
 	struct cdc_state		*info = (void *) &dev->data;
 	struct usb_driver		*driver = driver_of(intf);
 
+	/* combined interface - nothing  to do */
+	if (info->data == info->control)
+		return;
+
 	/* disconnect master --> disconnect slave */
 	if (intf == info->control && info->data) {
 		/* ensure immediate exit from usbnet_disconnect */
@@ -634,13 +646,18 @@ static const struct usb_device_id	produc
 },
 
 /* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */
-#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE)
 {
 	USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
 	.driver_info = 0,
 },
-#endif
+
+/* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */
+{
+	USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+	.driver_info = 0,
+},
 
 /*
  * WHITELIST!!!
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/hso.c linux-libre-3.11-rc7-gnu/drivers/net/usb/hso.c
--- linux-libre-3.10-gnu/drivers/net/usb/hso.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/hso.c	2013-08-25 20:43:22.000000000 -0400
@@ -2816,13 +2816,16 @@ exit:
 static int hso_get_config_data(struct usb_interface *interface)
 {
 	struct usb_device *usbdev = interface_to_usbdev(interface);
-	u8 config_data[17];
+	u8 *config_data = kmalloc(17, GFP_KERNEL);
 	u32 if_num = interface->altsetting->desc.bInterfaceNumber;
 	s32 result;
 
+	if (!config_data)
+		return -ENOMEM;
 	if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
 			    0x86, 0xC0, 0, 0, config_data, 17,
 			    USB_CTRL_SET_TIMEOUT) != 0x11) {
+		kfree(config_data);
 		return -EIO;
 	}
 
@@ -2873,6 +2876,7 @@ static int hso_get_config_data(struct us
 	if (config_data[16] & 0x1)
 		result |= HSO_INFO_CRC_BUG;
 
+	kfree(config_data);
 	return result;
 }
 
@@ -2886,6 +2890,11 @@ static int hso_probe(struct usb_interfac
 	struct hso_shared_int *shared_int;
 	struct hso_device *tmp_dev = NULL;
 
+	if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {
+		dev_err(&interface->dev, "Not our interface\n");
+		return -ENODEV;
+	}
+
 	if_num = interface->altsetting->desc.bInterfaceNumber;
 
 	/* Get the interface/port specification from either driver_info or from
@@ -2895,10 +2904,6 @@ static int hso_probe(struct usb_interfac
 	else
 		port_spec = hso_get_config_data(interface);
 
-	if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {
-		dev_err(&interface->dev, "Not our interface\n");
-		return -ENODEV;
-	}
 	/* Check if we need to switch to alt interfaces prior to port
 	 * configuration */
 	if (interface->num_altsetting > 1)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/ipheth.c linux-libre-3.11-rc7-gnu/drivers/net/usb/ipheth.c
--- linux-libre-3.10-gnu/drivers/net/usb/ipheth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/ipheth.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,6 +60,7 @@
 #define USB_PRODUCT_IPHONE_3GS  0x1294
 #define USB_PRODUCT_IPHONE_4	0x1297
 #define USB_PRODUCT_IPAD 0x129a
+#define USB_PRODUCT_IPAD_MINI    0x12ab
 #define USB_PRODUCT_IPHONE_4_VZW 0x129c
 #define USB_PRODUCT_IPHONE_4S	0x12a0
 #define USB_PRODUCT_IPHONE_5	0x12a8
@@ -107,6 +108,10 @@ static struct usb_device_id ipheth_table
 		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
 		IPHETH_USBINTF_PROTO) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(
+		USB_VENDOR_APPLE, USB_PRODUCT_IPAD_MINI,
+		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+		IPHETH_USBINTF_PROTO) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(
 		USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW,
 		IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
 		IPHETH_USBINTF_PROTO) },
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/kalmia.c linux-libre-3.11-rc7-gnu/drivers/net/usb/kalmia.c
--- linux-libre-3.10-gnu/drivers/net/usb/kalmia.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/kalmia.c	2013-08-25 20:43:22.000000000 -0400
@@ -221,12 +221,9 @@ done:
 		memset(skb_put(skb, padlen), 0, padlen);
 	}
 
-	netdev_dbg(
-		dev->net,
-		"Sending package with length %i and padding %i. Header: %02x:%02x:%02x:%02x:%02x:%02x.",
-		content_len, padlen, header_start[0], header_start[1],
-		header_start[2], header_start[3], header_start[4],
-		header_start[5]);
+	netdev_dbg(dev->net,
+		"Sending package with length %i and padding %i. Header: %6phC.",
+		content_len, padlen, header_start);
 
 	return skb;
 }
@@ -263,32 +260,23 @@ kalmia_rx_fixup(struct usbnet *dev, stru
 				sizeof(EXPECTED_UNKNOWN_HEADER_1)) || !memcmp(
 				header_start, EXPECTED_UNKNOWN_HEADER_2,
 				sizeof(EXPECTED_UNKNOWN_HEADER_2))) {
-				netdev_dbg(
-					dev->net,
-					"Received expected unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
-					header_start[0], header_start[1],
-					header_start[2], header_start[3],
-					header_start[4], header_start[5],
+				netdev_dbg(dev->net,
+					"Received expected unknown frame header: %6phC. Package length: %i\n",
+					header_start,
 					skb->len - KALMIA_HEADER_LENGTH);
 			}
 			else {
-				netdev_err(
-					dev->net,
-					"Received unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
-					header_start[0], header_start[1],
-					header_start[2], header_start[3],
-					header_start[4], header_start[5],
+				netdev_err(dev->net,
+					"Received unknown frame header: %6phC. Package length: %i\n",
+					header_start,
 					skb->len - KALMIA_HEADER_LENGTH);
 				return 0;
 			}
 		}
 		else
-			netdev_dbg(
-				dev->net,
-				"Received header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
-				header_start[0], header_start[1], header_start[2],
-				header_start[3], header_start[4], header_start[5],
-				skb->len - KALMIA_HEADER_LENGTH);
+			netdev_dbg(dev->net,
+				"Received header: %6phC. Package length: %i\n",
+				header_start, skb->len - KALMIA_HEADER_LENGTH);
 
 		/* subtract start header and end header */
 		usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
@@ -310,12 +298,9 @@ kalmia_rx_fixup(struct usbnet *dev, stru
 				sizeof(HEADER_END_OF_USB_PACKET)) == 0);
 			if (!is_last) {
 				header_start = skb->data + ether_packet_length;
-				netdev_dbg(
-					dev->net,
-					"End header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
-					header_start[0], header_start[1],
-					header_start[2], header_start[3],
-					header_start[4], header_start[5],
+				netdev_dbg(dev->net,
+					"End header: %6phC. Package length: %i\n",
+					header_start,
 					skb->len - KALMIA_HEADER_LENGTH);
 			}
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/usb/Kconfig
--- linux-libre-3.10-gnu/drivers/net/usb/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -67,7 +67,6 @@ config USB_KAWETH
 
 config USB_PEGASUS
 	tristate "USB Pegasus/Pegasus-II based ethernet device support"
-	select NET_CORE
 	select MII
 	---help---
 	  Say Y here if you know you have Pegasus or Pegasus-II based adapter.
@@ -83,7 +82,6 @@ config USB_PEGASUS
 
 config USB_RTL8150
 	tristate "USB RTL8150 based ethernet device support"
-	select NET_CORE
 	select MII
 	help
 	  Say Y here if you have RTL8150 based usb-ethernet adapter.
@@ -95,7 +93,6 @@ config USB_RTL8150
 
 config USB_RTL8152
 	tristate "Realtek RTL8152 Based USB 2.0 Ethernet Adapters"
-	select NET_CORE
 	select MII
 	help
 	  This option adds support for Realtek RTL8152 based USB 2.0
@@ -106,7 +103,6 @@ config USB_RTL8152
 
 config USB_USBNET
 	tristate "Multi-purpose USB Networking Framework"
-	select NET_CORE
 	select MII
 	---help---
 	  This driver supports several kinds of network links over USB,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/Makefile linux-libre-3.11-rc7-gnu/drivers/net/usb/Makefile
--- linux-libre-3.10-gnu/drivers/net/usb/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,7 @@ obj-$(CONFIG_USB_HSO)		+= hso.o
 obj-$(CONFIG_USB_NET_AX8817X)	+= asix.o
 asix-y := asix_devices.o asix_common.o ax88172a.o
 obj-$(CONFIG_USB_NET_AX88179_178A)      += ax88179_178a.o
-obj-$(CONFIG_USB_NET_CDCETHER)	+= cdc_ether.o
+obj-$(CONFIG_USB_NET_CDCETHER)	+= cdc_ether.o r815x.o
 obj-$(CONFIG_USB_NET_CDC_EEM)	+= cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)	+= dm9601.o
 obj-$(CONFIG_USB_NET_SMSC75XX)	+= smsc75xx.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/qmi_wwan.c linux-libre-3.11-rc7-gnu/drivers/net/usb/qmi_wwan.c
--- linux-libre-3.10-gnu/drivers/net/usb/qmi_wwan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/qmi_wwan.c	2013-08-25 20:43:22.000000000 -0400
@@ -523,6 +523,7 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x19d2, 0x0002, 1)},
 	{QMI_FIXED_INTF(0x19d2, 0x0012, 1)},
 	{QMI_FIXED_INTF(0x19d2, 0x0017, 3)},
+	{QMI_FIXED_INTF(0x19d2, 0x0019, 3)},	/* ONDA MT689DC */
 	{QMI_FIXED_INTF(0x19d2, 0x0021, 4)},
 	{QMI_FIXED_INTF(0x19d2, 0x0025, 1)},
 	{QMI_FIXED_INTF(0x19d2, 0x0031, 4)},
@@ -582,6 +583,7 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x1199, 0x901c, 8)},    /* Sierra Wireless EM7700 */
 	{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},	/* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
 	{QMI_FIXED_INTF(0x2357, 0x0201, 4)},	/* TP-LINK HSUPA Modem MA180 */
+	{QMI_FIXED_INTF(0x2357, 0x9000, 4)},	/* TP-LINK MA260 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},	/* Telit LE920 */
 	{QMI_FIXED_INTF(0x1e2d, 0x12d1, 4)},	/* Cinterion PLxx */
 
@@ -618,6 +620,7 @@ static const struct usb_device_id produc
 	{QMI_GOBI_DEVICE(0x05c6, 0x9265)},	/* Asus Gobi 2000 Modem device (VR305) */
 	{QMI_GOBI_DEVICE(0x05c6, 0x9235)},	/* Top Global Gobi 2000 Modem device (VR306) */
 	{QMI_GOBI_DEVICE(0x05c6, 0x9275)},	/* iRex Technologies Gobi 2000 Modem device (VR307) */
+	{QMI_GOBI_DEVICE(0x0af0, 0x8120)},	/* Option GTM681W */
 	{QMI_GOBI_DEVICE(0x1199, 0x68a5)},	/* Sierra Wireless Modem */
 	{QMI_GOBI_DEVICE(0x1199, 0x68a9)},	/* Sierra Wireless Modem */
 	{QMI_GOBI_DEVICE(0x1199, 0x9001)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
@@ -631,7 +634,6 @@ static const struct usb_device_id produc
 	{QMI_GOBI_DEVICE(0x1199, 0x9009)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
 	{QMI_GOBI_DEVICE(0x1199, 0x900a)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */
 	{QMI_GOBI_DEVICE(0x1199, 0x9011)},	/* Sierra Wireless Gobi 2000 Modem device (MC8305) */
-	{QMI_FIXED_INTF(0x1199, 0x9011, 5)},	/* alternate interface number!? */
 	{QMI_GOBI_DEVICE(0x16d8, 0x8002)},	/* CMDTech Gobi 2000 Modem device (VU922) */
 	{QMI_GOBI_DEVICE(0x05c6, 0x9205)},	/* Gobi 2000 Modem device */
 	{QMI_GOBI_DEVICE(0x1199, 0x9013)},	/* Sierra Wireless Gobi 3000 Modem device (MC8355) */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/r8152.c linux-libre-3.11-rc7-gnu/drivers/net/usb/r8152.c
--- linux-libre-3.10-gnu/drivers/net/usb/r8152.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/r8152.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,7 +11,6 @@
 #include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/mii.h>
@@ -345,17 +344,41 @@ static const int multicast_filter_limit
 static
 int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
 {
-	return usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0),
+	int ret;
+	void *tmp;
+
+	tmp = kmalloc(size, GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0),
 			       RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
-			       value, index, data, size, 500);
+			       value, index, tmp, size, 500);
+
+	memcpy(data, tmp, size);
+	kfree(tmp);
+
+	return ret;
 }
 
 static
 int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
 {
-	return usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0),
+	int ret;
+	void *tmp;
+
+	tmp = kmalloc(size, GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	memcpy(tmp, data, size);
+
+	ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0),
 			       RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE,
-			       value, index, data, size, 500);
+			       value, index, tmp, size, 500);
+
+	kfree(tmp);
+	return ret;
 }
 
 static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size,
@@ -491,37 +514,31 @@ int usb_ocp_write(struct r8152 *tp, u16
 
 static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index)
 {
-	u32 data;
+	__le32 data;
 
-	if (type == MCU_TYPE_PLA)
-		pla_ocp_read(tp, index, sizeof(data), &data);
-	else
-		usb_ocp_read(tp, index, sizeof(data), &data);
+	generic_ocp_read(tp, index, sizeof(data), &data, type);
 
 	return __le32_to_cpu(data);
 }
 
 static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data)
 {
-	if (type == MCU_TYPE_PLA)
-		pla_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data);
-	else
-		usb_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data);
+	__le32 tmp = __cpu_to_le32(data);
+
+	generic_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(tmp), &tmp, type);
 }
 
 static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index)
 {
 	u32 data;
+	__le32 tmp;
 	u8 shift = index & 2;
 
 	index &= ~3;
 
-	if (type == MCU_TYPE_PLA)
-		pla_ocp_read(tp, index, sizeof(data), &data);
-	else
-		usb_ocp_read(tp, index, sizeof(data), &data);
+	generic_ocp_read(tp, index, sizeof(tmp), &tmp, type);
 
-	data = __le32_to_cpu(data);
+	data = __le32_to_cpu(tmp);
 	data >>= (shift * 8);
 	data &= 0xffff;
 
@@ -530,7 +547,8 @@ static u16 ocp_read_word(struct r8152 *t
 
 static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data)
 {
-	u32 tmp, mask = 0xffff;
+	u32 mask = 0xffff;
+	__le32 tmp;
 	u16 byen = BYTE_EN_WORD;
 	u8 shift = index & 2;
 
@@ -543,34 +561,25 @@ static void ocp_write_word(struct r8152
 		index &= ~3;
 	}
 
-	if (type == MCU_TYPE_PLA)
-		pla_ocp_read(tp, index, sizeof(tmp), &tmp);
-	else
-		usb_ocp_read(tp, index, sizeof(tmp), &tmp);
+	generic_ocp_read(tp, index, sizeof(tmp), &tmp, type);
 
-	tmp = __le32_to_cpu(tmp) & ~mask;
-	tmp |= data;
-	tmp = __cpu_to_le32(tmp);
+	data |= __le32_to_cpu(tmp) & ~mask;
+	tmp = __cpu_to_le32(data);
 
-	if (type == MCU_TYPE_PLA)
-		pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp);
-	else
-		usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp);
+	generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type);
 }
 
 static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index)
 {
 	u32 data;
+	__le32 tmp;
 	u8 shift = index & 3;
 
 	index &= ~3;
 
-	if (type == MCU_TYPE_PLA)
-		pla_ocp_read(tp, index, sizeof(data), &data);
-	else
-		usb_ocp_read(tp, index, sizeof(data), &data);
+	generic_ocp_read(tp, index, sizeof(tmp), &tmp, type);
 
-	data = __le32_to_cpu(data);
+	data = __le32_to_cpu(tmp);
 	data >>= (shift * 8);
 	data &= 0xff;
 
@@ -579,7 +588,8 @@ static u8 ocp_read_byte(struct r8152 *tp
 
 static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data)
 {
-	u32 tmp, mask = 0xff;
+	u32 mask = 0xff;
+	__le32 tmp;
 	u16 byen = BYTE_EN_BYTE;
 	u8 shift = index & 3;
 
@@ -592,19 +602,12 @@ static void ocp_write_byte(struct r8152
 		index &= ~3;
 	}
 
-	if (type == MCU_TYPE_PLA)
-		pla_ocp_read(tp, index, sizeof(tmp), &tmp);
-	else
-		usb_ocp_read(tp, index, sizeof(tmp), &tmp);
+	generic_ocp_read(tp, index, sizeof(tmp), &tmp, type);
 
-	tmp = __le32_to_cpu(tmp) & ~mask;
-	tmp |= data;
-	tmp = __cpu_to_le32(tmp);
+	data |= __le32_to_cpu(tmp) & ~mask;
+	tmp = __cpu_to_le32(data);
 
-	if (type == MCU_TYPE_PLA)
-		pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp);
-	else
-		usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp);
+	generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type);
 }
 
 static void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value)
@@ -686,21 +689,14 @@ static void ocp_reg_write(struct r8152 *
 static inline void set_ethernet_addr(struct r8152 *tp)
 {
 	struct net_device *dev = tp->netdev;
-	u8 *node_id;
-
-	node_id = kmalloc(sizeof(u8) * 8, GFP_KERNEL);
-	if (!node_id) {
-		netif_err(tp, probe, dev, "out of memory");
-		return;
-	}
+	u8 node_id[8] = {0};
 
-	if (pla_ocp_read(tp, PLA_IDR, sizeof(u8) * 8, node_id) < 0)
+	if (pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id) < 0)
 		netif_notice(tp, probe, dev, "inet addr fail\n");
 	else {
 		memcpy(dev->dev_addr, node_id, dev->addr_len);
 		memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	}
-	kfree(node_id);
 }
 
 static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
@@ -883,15 +879,10 @@ static void rtl8152_set_rx_mode(struct n
 static void _rtl8152_set_rx_mode(struct net_device *netdev)
 {
 	struct r8152 *tp = netdev_priv(netdev);
-	u32 tmp, *mc_filter;	/* Multicast hash filter */
+	u32 mc_filter[2];	/* Multicast hash filter */
+	__le32 tmp[2];
 	u32 ocp_data;
 
-	mc_filter = kmalloc(sizeof(u32) * 2, GFP_KERNEL);
-	if (!mc_filter) {
-		netif_err(tp, link, netdev, "out of memory");
-		return;
-	}
-
 	clear_bit(RTL8152_SET_RX_MODE, &tp->flags);
 	netif_stop_queue(netdev);
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
@@ -919,14 +910,12 @@ static void _rtl8152_set_rx_mode(struct
 		}
 	}
 
-	tmp = mc_filter[0];
-	mc_filter[0] = __cpu_to_le32(swab32(mc_filter[1]));
-	mc_filter[1] = __cpu_to_le32(swab32(tmp));
+	tmp[0] = __cpu_to_le32(swab32(mc_filter[1]));
+	tmp[1] = __cpu_to_le32(swab32(mc_filter[0]));
 
-	pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(u32) * 2, mc_filter);
+	pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(tmp), tmp);
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 	netif_wake_queue(netdev);
-	kfree(mc_filter);
 }
 
 static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
@@ -935,7 +924,8 @@ static netdev_tx_t rtl8152_start_xmit(st
 	struct r8152 *tp = netdev_priv(netdev);
 	struct net_device_stats *stats = rtl8152_get_stats(netdev);
 	struct tx_desc *tx_desc;
-	int len, res;
+	unsigned int len;
+	int res;
 
 	netif_stop_queue(netdev);
 	len = skb->len;
@@ -1749,18 +1739,7 @@ static struct usb_driver rtl8152_driver
 	.resume =	rtl8152_resume
 };
 
-static int __init usb_rtl8152_init(void)
-{
-	return usb_register(&rtl8152_driver);
-}
-
-static void __exit usb_rtl8152_exit(void)
-{
-	usb_deregister(&rtl8152_driver);
-}
-
-module_init(usb_rtl8152_init);
-module_exit(usb_rtl8152_exit);
+module_usb_driver(rtl8152_driver);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/r815x.c linux-libre-3.11-rc7-gnu/drivers/net/usb/r815x.c
--- linux-libre-3.10-gnu/drivers/net/usb/r815x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/r815x.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,256 @@
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+
+#define RTL815x_REQT_READ	0xc0
+#define RTL815x_REQT_WRITE	0x40
+#define RTL815x_REQ_GET_REGS	0x05
+#define RTL815x_REQ_SET_REGS	0x05
+
+#define MCU_TYPE_PLA		0x0100
+#define OCP_BASE		0xe86c
+#define BASE_MII		0xa400
+
+#define BYTE_EN_DWORD		0xff
+#define BYTE_EN_WORD		0x33
+#define BYTE_EN_BYTE		0x11
+
+#define R815x_PHY_ID		32
+#define REALTEK_VENDOR_ID	0x0bda
+
+
+static int pla_read_word(struct usb_device *udev, u16 index)
+{
+	int ret;
+	u8 shift = index & 2;
+	__le32 *tmp;
+
+	tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	index &= ~3;
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			      RTL815x_REQ_GET_REGS, RTL815x_REQT_READ,
+			      index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500);
+	if (ret < 0)
+		goto out2;
+
+	ret = __le32_to_cpu(*tmp);
+	ret >>= (shift * 8);
+	ret &= 0xffff;
+
+out2:
+	kfree(tmp);
+	return ret;
+}
+
+static int pla_write_word(struct usb_device *udev, u16 index, u32 data)
+{
+	__le32 *tmp;
+	u32 mask = 0xffff;
+	u16 byen = BYTE_EN_WORD;
+	u8 shift = index & 2;
+	int ret;
+
+	tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	data &= mask;
+
+	if (shift) {
+		byen <<= shift;
+		mask <<= (shift * 8);
+		data <<= (shift * 8);
+		index &= ~3;
+	}
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			      RTL815x_REQ_GET_REGS, RTL815x_REQT_READ,
+			      index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500);
+	if (ret < 0)
+		goto out3;
+
+	data |= __le32_to_cpu(*tmp) & ~mask;
+	*tmp = __cpu_to_le32(data);
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+			      RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE,
+			      index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp),
+			      500);
+
+out3:
+	kfree(tmp);
+	return ret;
+}
+
+static int ocp_reg_read(struct usbnet *dev, u16 addr)
+{
+	u16 ocp_base, ocp_index;
+	int ret;
+
+	ocp_base = addr & 0xf000;
+	ret = pla_write_word(dev->udev, OCP_BASE, ocp_base);
+	if (ret < 0)
+		goto out;
+
+	ocp_index = (addr & 0x0fff) | 0xb000;
+	ret = pla_read_word(dev->udev, ocp_index);
+
+out:
+	return ret;
+}
+
+static int ocp_reg_write(struct usbnet *dev, u16 addr, u16 data)
+{
+	u16 ocp_base, ocp_index;
+	int ret;
+
+	ocp_base = addr & 0xf000;
+	ret = pla_write_word(dev->udev, OCP_BASE, ocp_base);
+	if (ret < 0)
+		goto out1;
+
+	ocp_index = (addr & 0x0fff) | 0xb000;
+	ret = pla_write_word(dev->udev, ocp_index, data);
+
+out1:
+	return ret;
+}
+
+static int r815x_mdio_read(struct net_device *netdev, int phy_id, int reg)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	int ret;
+
+	if (phy_id != R815x_PHY_ID)
+		return -EINVAL;
+
+	if (usb_autopm_get_interface(dev->intf) < 0)
+		return -ENODEV;
+
+	ret = ocp_reg_read(dev, BASE_MII + reg * 2);
+
+	usb_autopm_put_interface(dev->intf);
+	return ret;
+}
+
+static
+void r815x_mdio_write(struct net_device *netdev, int phy_id, int reg, int val)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+
+	if (phy_id != R815x_PHY_ID)
+		return;
+
+	if (usb_autopm_get_interface(dev->intf) < 0)
+		return;
+
+	ocp_reg_write(dev, BASE_MII + reg * 2, val);
+
+	usb_autopm_put_interface(dev->intf);
+}
+
+static int r8153_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	int status;
+
+	status = usbnet_cdc_bind(dev, intf);
+	if (status < 0)
+		return status;
+
+	dev->mii.dev = dev->net;
+	dev->mii.mdio_read = r815x_mdio_read;
+	dev->mii.mdio_write = r815x_mdio_write;
+	dev->mii.phy_id_mask = 0x3f;
+	dev->mii.reg_num_mask = 0x1f;
+	dev->mii.phy_id = R815x_PHY_ID;
+	dev->mii.supports_gmii = 1;
+
+	return status;
+}
+
+static int r8152_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	int status;
+
+	status = usbnet_cdc_bind(dev, intf);
+	if (status < 0)
+		return status;
+
+	dev->mii.dev = dev->net;
+	dev->mii.mdio_read = r815x_mdio_read;
+	dev->mii.mdio_write = r815x_mdio_write;
+	dev->mii.phy_id_mask = 0x3f;
+	dev->mii.reg_num_mask = 0x1f;
+	dev->mii.phy_id = R815x_PHY_ID;
+	dev->mii.supports_gmii = 0;
+
+	return status;
+}
+
+static const struct driver_info r8152_info = {
+	.description =	"RTL8152 ECM Device",
+	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT,
+	.bind =		r8152_bind,
+	.unbind =	usbnet_cdc_unbind,
+	.status =	usbnet_cdc_status,
+	.manage_power =	usbnet_manage_power,
+};
+
+static const struct driver_info r8153_info = {
+	.description =	"RTL8153 ECM Device",
+	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT,
+	.bind =		r8153_bind,
+	.unbind =	usbnet_cdc_unbind,
+	.status =	usbnet_cdc_status,
+	.manage_power =	usbnet_manage_power,
+};
+
+static const struct usb_device_id products[] = {
+{
+	USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE)
+	.driver_info = 0,
+#else
+	.driver_info = (unsigned long) &r8152_info,
+#endif
+},
+
+{
+	USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+#if defined(CONFIG_USB_RTL8153) || defined(CONFIG_USB_RTL8153_MODULE)
+	.driver_info = 0,
+#else
+	.driver_info = (unsigned long) &r8153_info,
+#endif
+},
+
+	{ },		/* END */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver r815x_driver = {
+	.name =		"r815x",
+	.id_table =	products,
+	.probe =	usbnet_probe,
+	.disconnect =	usbnet_disconnect,
+	.suspend =	usbnet_suspend,
+	.resume =	usbnet_resume,
+	.reset_resume =	usbnet_resume,
+	.supports_autosuspend = 1,
+	.disable_hub_initiated_lpm = 1,
+};
+
+module_usb_driver(r815x_driver);
+
+MODULE_AUTHOR("Hayes Wang");
+MODULE_DESCRIPTION("Realtek USB ECM device");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/usb/smsc75xx.c linux-libre-3.11-rc7-gnu/drivers/net/usb/smsc75xx.c
--- linux-libre-3.10-gnu/drivers/net/usb/smsc75xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/usb/smsc75xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,7 +45,6 @@
 #define EEPROM_MAC_OFFSET		(0x01)
 #define DEFAULT_TX_CSUM_ENABLE		(true)
 #define DEFAULT_RX_CSUM_ENABLE		(true)
-#define DEFAULT_TSO_ENABLE		(true)
 #define SMSC75XX_INTERNAL_PHY_ID	(1)
 #define SMSC75XX_TX_OVERHEAD		(8)
 #define MAX_RX_FIFO_SIZE		(20 * 1024)
@@ -1410,17 +1409,14 @@ static int smsc75xx_bind(struct usbnet *
 
 	INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write);
 
-	if (DEFAULT_TX_CSUM_ENABLE) {
+	if (DEFAULT_TX_CSUM_ENABLE)
 		dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-		if (DEFAULT_TSO_ENABLE)
-			dev->net->features |= NETIF_F_SG |
-				NETIF_F_TSO | NETIF_F_TSO6;
-	}
+
 	if (DEFAULT_RX_CSUM_ENABLE)
 		dev->net->features |= NETIF_F_RXCSUM;
 
 	dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-		NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_RXCSUM;
+				NETIF_F_RXCSUM;
 
 	ret = smsc75xx_wait_ready(dev, 0);
 	if (ret < 0) {
@@ -2200,8 +2196,6 @@ static struct sk_buff *smsc75xx_tx_fixup
 {
 	u32 tx_cmd_a, tx_cmd_b;
 
-	skb_linearize(skb);
-
 	if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) {
 		struct sk_buff *skb2 =
 			skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/veth.c linux-libre-3.11-rc7-gnu/drivers/net/veth.c
--- linux-libre-3.10-gnu/drivers/net/veth.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/veth.c	2013-08-25 20:43:22.000000000 -0400
@@ -269,6 +269,7 @@ static void veth_setup(struct net_device
 	dev->ethtool_ops = &veth_ethtool_ops;
 	dev->features |= NETIF_F_LLTX;
 	dev->features |= VETH_FEATURES;
+	dev->vlan_features = dev->features;
 	dev->destructor = veth_dev_free;
 
 	dev->hw_features = VETH_FEATURES;
@@ -379,12 +380,6 @@ static int veth_newlink(struct net *src_
 	else
 		snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d");
 
-	if (strchr(dev->name, '%')) {
-		err = dev_alloc_name(dev, dev->name);
-		if (err < 0)
-			goto err_alloc_name;
-	}
-
 	err = register_netdevice(dev);
 	if (err < 0)
 		goto err_register_dev;
@@ -404,7 +399,6 @@ static int veth_newlink(struct net *src_
 
 err_register_dev:
 	/* nothing to do */
-err_alloc_name:
 err_configure_peer:
 	unregister_netdevice(peer);
 	return err;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/virtio_net.c linux-libre-3.11-rc7-gnu/drivers/net/virtio_net.c
--- linux-libre-3.10-gnu/drivers/net/virtio_net.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/virtio_net.c	2013-08-25 20:43:22.000000000 -0400
@@ -602,7 +602,7 @@ static int virtnet_poll(struct napi_stru
 		container_of(napi, struct receive_queue, napi);
 	struct virtnet_info *vi = rq->vq->vdev->priv;
 	void *buf;
-	unsigned int len, received = 0;
+	unsigned int r, len, received = 0;
 
 again:
 	while (received < budget &&
@@ -619,8 +619,9 @@ again:
 
 	/* Out of packets? */
 	if (received < budget) {
+		r = virtqueue_enable_cb_prepare(rq->vq);
 		napi_complete(napi);
-		if (unlikely(!virtqueue_enable_cb(rq->vq)) &&
+		if (unlikely(virtqueue_poll(rq->vq, r)) &&
 		    napi_schedule_prep(napi)) {
 			virtqueue_disable_cb(rq->vq);
 			__napi_schedule(napi);
@@ -901,7 +902,6 @@ static int virtnet_set_queues(struct vir
 	struct scatterlist sg;
 	struct virtio_net_ctrl_mq s;
 	struct net_device *dev = vi->dev;
-	int i;
 
 	if (!vi->has_cvq || !virtio_has_feature(vi->vdev, VIRTIO_NET_F_MQ))
 		return 0;
@@ -915,10 +915,8 @@ static int virtnet_set_queues(struct vir
 			 queue_pairs);
 		return -EINVAL;
 	} else {
-		for (i = vi->curr_queue_pairs; i < queue_pairs; i++)
-			if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
-				schedule_delayed_work(&vi->refill, 0);
 		vi->curr_queue_pairs = queue_pairs;
+		schedule_delayed_work(&vi->refill, 0);
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/vxlan.c linux-libre-3.11-rc7-gnu/drivers/net/vxlan.c
--- linux-libre-3.10-gnu/drivers/net/vxlan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/vxlan.c	2013-08-25 20:43:22.000000000 -0400
@@ -44,6 +44,8 @@
 
 #define VXLAN_VERSION	"0.1"
 
+#define PORT_HASH_BITS	8
+#define PORT_HASH_SIZE  (1<<PORT_HASH_BITS)
 #define VNI_HASH_BITS	10
 #define VNI_HASH_SIZE	(1<<VNI_HASH_BITS)
 #define FDB_HASH_BITS	8
@@ -66,30 +68,44 @@ struct vxlanhdr {
 
 /* UDP port for VXLAN traffic.
  * The IANA assigned port is 4789, but the Linux default is 8472
- * for compatability with early adopters.
+ * for compatibility with early adopters.
  */
-static unsigned int vxlan_port __read_mostly = 8472;
-module_param_named(udp_port, vxlan_port, uint, 0444);
+static unsigned short vxlan_port __read_mostly = 8472;
+module_param_named(udp_port, vxlan_port, ushort, 0444);
 MODULE_PARM_DESC(udp_port, "Destination UDP port");
 
 static bool log_ecn_error = true;
 module_param(log_ecn_error, bool, 0644);
 MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
 
-/* per-net private data for this module */
-static unsigned int vxlan_net_id;
-struct vxlan_net {
-	struct socket	  *sock;	/* UDP encap socket */
+static int vxlan_net_id;
+
+static const u8 all_zeros_mac[ETH_ALEN];
+
+/* per UDP socket information */
+struct vxlan_sock {
+	struct hlist_node hlist;
+	struct rcu_head	  rcu;
+	struct work_struct del_work;
+	atomic_t	  refcnt;
+	struct socket	  *sock;
 	struct hlist_head vni_list[VNI_HASH_SIZE];
 };
 
+/* per-network namespace private data for this module */
+struct vxlan_net {
+	struct list_head  vxlan_list;
+	struct hlist_head sock_list[PORT_HASH_SIZE];
+	spinlock_t	  sock_lock;
+};
+
 struct vxlan_rdst {
-	struct rcu_head		 rcu;
 	__be32			 remote_ip;
 	__be16			 remote_port;
 	u32			 remote_vni;
 	u32			 remote_ifindex;
-	struct vxlan_rdst	*remote_next;
+	struct list_head	 list;
+	struct rcu_head		 rcu;
 };
 
 /* Forwarding table entry */
@@ -98,7 +114,7 @@ struct vxlan_fdb {
 	struct rcu_head	  rcu;
 	unsigned long	  updated;	/* jiffies */
 	unsigned long	  used;
-	struct vxlan_rdst remote;
+	struct list_head  remotes;
 	u16		  state;	/* see ndm_state */
 	u8		  flags;	/* see ndm_flags */
 	u8		  eth_addr[ETH_ALEN];
@@ -106,7 +122,9 @@ struct vxlan_fdb {
 
 /* Pseudo network device */
 struct vxlan_dev {
-	struct hlist_node hlist;
+	struct hlist_node hlist;	/* vni hash table */
+	struct list_head  next;		/* vxlan's per namespace list */
+	struct vxlan_sock *vn_sock;	/* listening socket */
 	struct net_device *dev;
 	struct vxlan_rdst default_dst;	/* default destination */
 	__be32		  saddr;	/* source address */
@@ -117,6 +135,10 @@ struct vxlan_dev {
 	__u8		  ttl;
 	u32		  flags;	/* VXLAN_F_* below */
 
+	struct work_struct sock_work;
+	struct work_struct igmp_join;
+	struct work_struct igmp_leave;
+
 	unsigned long	  age_interval;
 	struct timer_list age_timer;
 	spinlock_t	  hash_lock;
@@ -134,20 +156,55 @@ struct vxlan_dev {
 
 /* salt for hash table */
 static u32 vxlan_salt __read_mostly;
+static struct workqueue_struct *vxlan_wq;
 
-static inline struct hlist_head *vni_head(struct net *net, u32 id)
+static void vxlan_sock_work(struct work_struct *work);
+
+/* Virtual Network hash table head */
+static inline struct hlist_head *vni_head(struct vxlan_sock *vs, u32 id)
+{
+	return &vs->vni_list[hash_32(id, VNI_HASH_BITS)];
+}
+
+/* Socket hash table head */
+static inline struct hlist_head *vs_head(struct net *net, __be16 port)
 {
 	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
 
-	return &vn->vni_list[hash_32(id, VNI_HASH_BITS)];
+	return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];
+}
+
+/* First remote destination for a forwarding entry.
+ * Guaranteed to be non-NULL because remotes are never deleted.
+ */
+static inline struct vxlan_rdst *first_remote(struct vxlan_fdb *fdb)
+{
+	return list_first_or_null_rcu(&fdb->remotes, struct vxlan_rdst, list);
+}
+
+/* Find VXLAN socket based on network namespace and UDP port */
+static struct vxlan_sock *vxlan_find_port(struct net *net, __be16 port)
+{
+	struct vxlan_sock *vs;
+
+	hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
+		if (inet_sk(vs->sock->sk)->inet_sport == port)
+			return vs;
+	}
+	return NULL;
 }
 
 /* Look up VNI in a per net namespace table */
-static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id)
+static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port)
 {
+	struct vxlan_sock *vs;
 	struct vxlan_dev *vxlan;
 
-	hlist_for_each_entry_rcu(vxlan, vni_head(net, id), hlist) {
+	vs = vxlan_find_port(net, port);
+	if (!vs)
+		return NULL;
+
+	hlist_for_each_entry_rcu(vxlan, vni_head(vs, id), hlist) {
 		if (vxlan->default_dst.remote_vni == id)
 			return vxlan;
 	}
@@ -157,9 +214,9 @@ static struct vxlan_dev *vxlan_find_vni(
 
 /* Fill in neighbour message in skbuff. */
 static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
-			   const struct vxlan_fdb *fdb,
-			   u32 portid, u32 seq, int type, unsigned int flags,
-			   const struct vxlan_rdst *rdst)
+			  const struct vxlan_fdb *fdb,
+			  u32 portid, u32 seq, int type, unsigned int flags,
+			  const struct vxlan_rdst *rdst)
 {
 	unsigned long now = jiffies;
 	struct nda_cacheinfo ci;
@@ -197,7 +254,7 @@ static int vxlan_fdb_info(struct sk_buff
 	    nla_put_be16(skb, NDA_PORT, rdst->remote_port))
 		goto nla_put_failure;
 	if (rdst->remote_vni != vxlan->default_dst.remote_vni &&
-	    nla_put_be32(skb, NDA_VNI, rdst->remote_vni))
+	    nla_put_u32(skb, NDA_VNI, rdst->remote_vni))
 		goto nla_put_failure;
 	if (rdst->remote_ifindex &&
 	    nla_put_u32(skb, NDA_IFINDEX, rdst->remote_ifindex))
@@ -230,7 +287,7 @@ static inline size_t vxlan_nlmsg_size(vo
 }
 
 static void vxlan_fdb_notify(struct vxlan_dev *vxlan,
-			     const struct vxlan_fdb *fdb, int type)
+			     struct vxlan_fdb *fdb, int type)
 {
 	struct net *net = dev_net(vxlan->dev);
 	struct sk_buff *skb;
@@ -240,7 +297,7 @@ static void vxlan_fdb_notify(struct vxla
 	if (skb == NULL)
 		goto errout;
 
-	err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, &fdb->remote);
+	err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, first_remote(fdb));
 	if (err < 0) {
 		/* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */
 		WARN_ON(err == -EMSGSIZE);
@@ -258,22 +315,27 @@ errout:
 static void vxlan_ip_miss(struct net_device *dev, __be32 ipa)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
-	struct vxlan_fdb f;
+	struct vxlan_fdb f = {
+		.state = NUD_STALE,
+	};
+	struct vxlan_rdst remote = {
+		.remote_ip = ipa, /* goes to NDA_DST */
+		.remote_vni = VXLAN_N_VID,
+	};
 
-	memset(&f, 0, sizeof f);
-	f.state = NUD_STALE;
-	f.remote.remote_ip = ipa; /* goes to NDA_DST */
-	f.remote.remote_vni = VXLAN_N_VID;
+	INIT_LIST_HEAD(&f.remotes);
+	list_add_rcu(&remote.list, &f.remotes);
 
 	vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH);
 }
 
 static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN])
 {
-	struct vxlan_fdb	f;
+	struct vxlan_fdb f = {
+		.state = NUD_STALE,
+	};
 
-	memset(&f, 0, sizeof f);
-	f.state = NUD_STALE;
+	INIT_LIST_HEAD(&f.remotes);
 	memcpy(f.eth_addr, eth_addr, ETH_ALEN);
 
 	vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH);
@@ -328,21 +390,34 @@ static struct vxlan_fdb *vxlan_find_mac(
 	return f;
 }
 
-/* Add/update destinations for multicast */
-static int vxlan_fdb_append(struct vxlan_fdb *f,
-			    __be32 ip, __be16 port, __u32 vni, __u32 ifindex)
+/* caller should hold vxlan->hash_lock */
+static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f,
+					      __be32 ip, __be16 port,
+					      __u32 vni, __u32 ifindex)
 {
-	struct vxlan_rdst *rd_prev, *rd;
+	struct vxlan_rdst *rd;
 
-	rd_prev = NULL;
-	for (rd = &f->remote; rd; rd = rd->remote_next) {
+	list_for_each_entry(rd, &f->remotes, list) {
 		if (rd->remote_ip == ip &&
 		    rd->remote_port == port &&
 		    rd->remote_vni == vni &&
 		    rd->remote_ifindex == ifindex)
-			return 0;
-		rd_prev = rd;
+			return rd;
 	}
+
+	return NULL;
+}
+
+/* Add/update destinations for multicast */
+static int vxlan_fdb_append(struct vxlan_fdb *f,
+			    __be32 ip, __be16 port, __u32 vni, __u32 ifindex)
+{
+	struct vxlan_rdst *rd;
+
+	rd = vxlan_fdb_find_rdst(f, ip, port, vni, ifindex);
+	if (rd)
+		return 0;
+
 	rd = kmalloc(sizeof(*rd), GFP_ATOMIC);
 	if (rd == NULL)
 		return -ENOBUFS;
@@ -350,8 +425,9 @@ static int vxlan_fdb_append(struct vxlan
 	rd->remote_port = port;
 	rd->remote_vni = vni;
 	rd->remote_ifindex = ifindex;
-	rd->remote_next = NULL;
-	rd_prev->remote_next = rd;
+
+	list_add_tail_rcu(&rd->list, &f->remotes);
+
 	return 1;
 }
 
@@ -383,7 +459,8 @@ static int vxlan_fdb_create(struct vxlan
 			notify = 1;
 		}
 		if ((flags & NLM_F_APPEND) &&
-		    is_multicast_ether_addr(f->eth_addr)) {
+		    (is_multicast_ether_addr(f->eth_addr) ||
+		     is_zero_ether_addr(f->eth_addr))) {
 			int rc = vxlan_fdb_append(f, ip, port, vni, ifindex);
 
 			if (rc < 0)
@@ -403,16 +480,14 @@ static int vxlan_fdb_create(struct vxlan
 			return -ENOMEM;
 
 		notify = 1;
-		f->remote.remote_ip = ip;
-		f->remote.remote_port = port;
-		f->remote.remote_vni = vni;
-		f->remote.remote_ifindex = ifindex;
-		f->remote.remote_next = NULL;
 		f->state = state;
 		f->flags = ndm_flags;
 		f->updated = f->used = jiffies;
+		INIT_LIST_HEAD(&f->remotes);
 		memcpy(f->eth_addr, mac, ETH_ALEN);
 
+		vxlan_fdb_append(f, ip, port, vni, ifindex);
+
 		++vxlan->addrcnt;
 		hlist_add_head_rcu(&f->hlist,
 				   vxlan_fdb_head(vxlan, mac));
@@ -424,16 +499,19 @@ static int vxlan_fdb_create(struct vxlan
 	return 0;
 }
 
+static void vxlan_fdb_free_rdst(struct rcu_head *head)
+{
+	struct vxlan_rdst *rd = container_of(head, struct vxlan_rdst, rcu);
+	kfree(rd);
+}
+
 static void vxlan_fdb_free(struct rcu_head *head)
 {
 	struct vxlan_fdb *f = container_of(head, struct vxlan_fdb, rcu);
+	struct vxlan_rdst *rd, *nd;
 
-	while (f->remote.remote_next) {
-		struct vxlan_rdst *rd = f->remote.remote_next;
-
-		f->remote.remote_next = rd->remote_next;
+	list_for_each_entry_safe(rd, nd, &f->remotes, list)
 		kfree(rd);
-	}
 	kfree(f);
 }
 
@@ -449,58 +527,77 @@ static void vxlan_fdb_destroy(struct vxl
 	call_rcu(&f->rcu, vxlan_fdb_free);
 }
 
-/* Add static entry (via netlink) */
-static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
-			 struct net_device *dev,
-			 const unsigned char *addr, u16 flags)
+static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
+			   __be32 *ip, __be16 *port, u32 *vni, u32 *ifindex)
 {
-	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct net *net = dev_net(vxlan->dev);
-	__be32 ip;
-	__be16 port;
-	u32 vni, ifindex;
-	int err;
 
-	if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
-		pr_info("RTM_NEWNEIGH with invalid state %#x\n",
-			ndm->ndm_state);
-		return -EINVAL;
-	}
-
-	if (tb[NDA_DST] == NULL)
-		return -EINVAL;
-
-	if (nla_len(tb[NDA_DST]) != sizeof(__be32))
-		return -EAFNOSUPPORT;
+	if (tb[NDA_DST]) {
+		if (nla_len(tb[NDA_DST]) != sizeof(__be32))
+			return -EAFNOSUPPORT;
 
-	ip = nla_get_be32(tb[NDA_DST]);
+		*ip = nla_get_be32(tb[NDA_DST]);
+	} else {
+		*ip = htonl(INADDR_ANY);
+	}
 
 	if (tb[NDA_PORT]) {
 		if (nla_len(tb[NDA_PORT]) != sizeof(__be16))
 			return -EINVAL;
-		port = nla_get_be16(tb[NDA_PORT]);
-	} else
-		port = vxlan->dst_port;
+		*port = nla_get_be16(tb[NDA_PORT]);
+	} else {
+		*port = vxlan->dst_port;
+	}
 
 	if (tb[NDA_VNI]) {
 		if (nla_len(tb[NDA_VNI]) != sizeof(u32))
 			return -EINVAL;
-		vni = nla_get_u32(tb[NDA_VNI]);
-	} else
-		vni = vxlan->default_dst.remote_vni;
+		*vni = nla_get_u32(tb[NDA_VNI]);
+	} else {
+		*vni = vxlan->default_dst.remote_vni;
+	}
 
 	if (tb[NDA_IFINDEX]) {
 		struct net_device *tdev;
 
 		if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
 			return -EINVAL;
-		ifindex = nla_get_u32(tb[NDA_IFINDEX]);
-		tdev = dev_get_by_index(net, ifindex);
+		*ifindex = nla_get_u32(tb[NDA_IFINDEX]);
+		tdev = dev_get_by_index(net, *ifindex);
 		if (!tdev)
 			return -EADDRNOTAVAIL;
 		dev_put(tdev);
-	} else
-		ifindex = 0;
+	} else {
+		*ifindex = 0;
+	}
+
+	return 0;
+}
+
+/* Add static entry (via netlink) */
+static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+			 struct net_device *dev,
+			 const unsigned char *addr, u16 flags)
+{
+	struct vxlan_dev *vxlan = netdev_priv(dev);
+	/* struct net *net = dev_net(vxlan->dev); */
+	__be32 ip;
+	__be16 port;
+	u32 vni, ifindex;
+	int err;
+
+	if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
+		pr_info("RTM_NEWNEIGH with invalid state %#x\n",
+			ndm->ndm_state);
+		return -EINVAL;
+	}
+
+	if (tb[NDA_DST] == NULL)
+		return -EINVAL;
+
+	err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
+	if (err)
+		return err;
 
 	spin_lock_bh(&vxlan->hash_lock);
 	err = vxlan_fdb_create(vxlan, addr, ip, ndm->ndm_state, flags,
@@ -517,14 +614,43 @@ static int vxlan_fdb_delete(struct ndmsg
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct vxlan_fdb *f;
-	int err = -ENOENT;
+	struct vxlan_rdst *rd = NULL;
+	__be32 ip;
+	__be16 port;
+	u32 vni, ifindex;
+	int err;
+
+	err = vxlan_fdb_parse(tb, vxlan, &ip, &port, &vni, &ifindex);
+	if (err)
+		return err;
+
+	err = -ENOENT;
 
 	spin_lock_bh(&vxlan->hash_lock);
 	f = vxlan_find_mac(vxlan, addr);
-	if (f) {
-		vxlan_fdb_destroy(vxlan, f);
-		err = 0;
+	if (!f)
+		goto out;
+
+	if (ip != htonl(INADDR_ANY)) {
+		rd = vxlan_fdb_find_rdst(f, ip, port, vni, ifindex);
+		if (!rd)
+			goto out;
 	}
+
+	err = 0;
+
+	/* remove a destination if it's not the only one on the list,
+	 * otherwise destroy the fdb entry
+	 */
+	if (rd && !list_is_singular(&f->remotes)) {
+		list_del_rcu(&rd->list);
+		call_rcu(&rd->rcu, vxlan_fdb_free_rdst);
+		goto out;
+	}
+
+	vxlan_fdb_destroy(vxlan, f);
+
+out:
 	spin_unlock_bh(&vxlan->hash_lock);
 
 	return err;
@@ -543,23 +669,24 @@ static int vxlan_fdb_dump(struct sk_buff
 
 		hlist_for_each_entry_rcu(f, &vxlan->fdb_head[h], hlist) {
 			struct vxlan_rdst *rd;
-			for (rd = &f->remote; rd; rd = rd->remote_next) {
-				if (idx < cb->args[0])
-					goto skip;
 
+			if (idx < cb->args[0])
+				goto skip;
+
+			list_for_each_entry_rcu(rd, &f->remotes, list) {
 				err = vxlan_fdb_info(skb, vxlan, f,
 						     NETLINK_CB(cb->skb).portid,
 						     cb->nlh->nlmsg_seq,
 						     RTM_NEWNEIGH,
 						     NLM_F_MULTI, rd);
 				if (err < 0)
-					break;
-skip:
-				++idx;
+					goto out;
 			}
+skip:
+			++idx;
 		}
 	}
-
+out:
 	return idx;
 }
 
@@ -575,7 +702,9 @@ static bool vxlan_snoop(struct net_devic
 
 	f = vxlan_find_mac(vxlan, src_mac);
 	if (likely(f)) {
-		if (likely(f->remote.remote_ip == src_ip))
+		struct vxlan_rdst *rdst = first_remote(f);
+
+		if (likely(rdst->remote_ip == src_ip))
 			return false;
 
 		/* Don't migrate static entries, drop packets */
@@ -585,10 +714,11 @@ static bool vxlan_snoop(struct net_devic
 		if (net_ratelimit())
 			netdev_info(dev,
 				    "%pM migrated from %pI4 to %pI4\n",
-				    src_mac, &f->remote.remote_ip, &src_ip);
+				    src_mac, &rdst->remote_ip, &src_ip);
 
-		f->remote.remote_ip = src_ip;
+		rdst->remote_ip = src_ip;
 		f->updated = jiffies;
+		vxlan_fdb_notify(vxlan, f, RTM_NEWNEIGH);
 	} else {
 		/* learned new entry */
 		spin_lock(&vxlan->hash_lock);
@@ -607,80 +737,80 @@ static bool vxlan_snoop(struct net_devic
 	return false;
 }
 
-
 /* See if multicast group is already in use by other ID */
-static bool vxlan_group_used(struct vxlan_net *vn,
-			     const struct vxlan_dev *this)
+static bool vxlan_group_used(struct vxlan_net *vn, __be32 remote_ip)
 {
-	const struct vxlan_dev *vxlan;
-	unsigned h;
-
-	for (h = 0; h < VNI_HASH_SIZE; ++h)
-		hlist_for_each_entry(vxlan, &vn->vni_list[h], hlist) {
-			if (vxlan == this)
-				continue;
+	struct vxlan_dev *vxlan;
 
-			if (!netif_running(vxlan->dev))
-				continue;
+	list_for_each_entry(vxlan, &vn->vxlan_list, next) {
+		if (!netif_running(vxlan->dev))
+			continue;
 
-			if (vxlan->default_dst.remote_ip == this->default_dst.remote_ip)
-				return true;
-		}
+		if (vxlan->default_dst.remote_ip == remote_ip)
+			return true;
+	}
 
 	return false;
 }
 
-/* kernel equivalent to IP_ADD_MEMBERSHIP */
-static int vxlan_join_group(struct net_device *dev)
+static void vxlan_sock_hold(struct vxlan_sock *vs)
 {
-	struct vxlan_dev *vxlan = netdev_priv(dev);
-	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
-	struct sock *sk = vn->sock->sk;
+	atomic_inc(&vs->refcnt);
+}
+
+static void vxlan_sock_release(struct vxlan_net *vn, struct vxlan_sock *vs)
+{
+	if (!atomic_dec_and_test(&vs->refcnt))
+		return;
+
+	spin_lock(&vn->sock_lock);
+	hlist_del_rcu(&vs->hlist);
+	spin_unlock(&vn->sock_lock);
+
+	queue_work(vxlan_wq, &vs->del_work);
+}
+
+/* Callback to update multicast group membership when first VNI on
+ * multicast asddress is brought up
+ * Done as workqueue because ip_mc_join_group acquires RTNL.
+ */
+static void vxlan_igmp_join(struct work_struct *work)
+{
+	struct vxlan_dev *vxlan = container_of(work, struct vxlan_dev, igmp_join);
+	struct vxlan_net *vn = net_generic(dev_net(vxlan->dev), vxlan_net_id);
+	struct vxlan_sock *vs = vxlan->vn_sock;
+	struct sock *sk = vs->sock->sk;
 	struct ip_mreqn mreq = {
 		.imr_multiaddr.s_addr	= vxlan->default_dst.remote_ip,
 		.imr_ifindex		= vxlan->default_dst.remote_ifindex,
 	};
-	int err;
-
-	/* Already a member of group */
-	if (vxlan_group_used(vn, vxlan))
-		return 0;
 
-	/* Need to drop RTNL to call multicast join */
-	rtnl_unlock();
 	lock_sock(sk);
-	err = ip_mc_join_group(sk, &mreq);
+	ip_mc_join_group(sk, &mreq);
 	release_sock(sk);
-	rtnl_lock();
 
-	return err;
+	vxlan_sock_release(vn, vs);
+	dev_put(vxlan->dev);
 }
 
-
-/* kernel equivalent to IP_DROP_MEMBERSHIP */
-static int vxlan_leave_group(struct net_device *dev)
+/* Inverse of vxlan_igmp_join when last VNI is brought down */
+static void vxlan_igmp_leave(struct work_struct *work)
 {
-	struct vxlan_dev *vxlan = netdev_priv(dev);
-	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
-	int err = 0;
-	struct sock *sk = vn->sock->sk;
+	struct vxlan_dev *vxlan = container_of(work, struct vxlan_dev, igmp_leave);
+	struct vxlan_net *vn = net_generic(dev_net(vxlan->dev), vxlan_net_id);
+	struct vxlan_sock *vs = vxlan->vn_sock;
+	struct sock *sk = vs->sock->sk;
 	struct ip_mreqn mreq = {
 		.imr_multiaddr.s_addr	= vxlan->default_dst.remote_ip,
 		.imr_ifindex		= vxlan->default_dst.remote_ifindex,
 	};
 
-	/* Only leave group when last vxlan is done. */
-	if (vxlan_group_used(vn, vxlan))
-		return 0;
-
-	/* Need to drop RTNL to call multicast leave */
-	rtnl_unlock();
 	lock_sock(sk);
-	err = ip_mc_leave_group(sk, &mreq);
+	ip_mc_leave_group(sk, &mreq);
 	release_sock(sk);
-	rtnl_lock();
 
-	return err;
+	vxlan_sock_release(vn, vs);
+	dev_put(vxlan->dev);
 }
 
 /* Callback from net/ipv4/udp.c to receive packets */
@@ -690,6 +820,7 @@ static int vxlan_udp_encap_recv(struct s
 	struct vxlanhdr *vxh;
 	struct vxlan_dev *vxlan;
 	struct pcpu_tstats *stats;
+	__be16 port;
 	__u32 vni;
 	int err;
 
@@ -713,9 +844,11 @@ static int vxlan_udp_encap_recv(struct s
 
 	/* Is this VNI defined? */
 	vni = ntohl(vxh->vx_vni) >> 8;
-	vxlan = vxlan_find_vni(sock_net(sk), vni);
+	port = inet_sk(sk)->inet_sport;
+	vxlan = vxlan_find_vni(sock_net(sk), vni, port);
 	if (!vxlan) {
-		netdev_dbg(skb->dev, "unknown vni %d\n", vni);
+		netdev_dbg(skb->dev, "unknown vni %d port %u\n",
+			   vni, ntohs(port));
 		goto drop;
 	}
 
@@ -834,7 +967,7 @@ static int arp_reduce(struct net_device
 		}
 
 		f = vxlan_find_mac(vxlan, n->ha);
-		if (f && f->remote.remote_ip == htonl(INADDR_ANY)) {
+		if (f && first_remote(f)->remote_ip == htonl(INADDR_ANY)) {
 			/* bridge-local neighbor */
 			neigh_release(n);
 			goto out;
@@ -896,7 +1029,7 @@ static bool route_shortcircuit(struct ne
 	return false;
 }
 
-static void vxlan_sock_free(struct sk_buff *skb)
+static void vxlan_sock_put(struct sk_buff *skb)
 {
 	sock_put(skb->sk);
 }
@@ -904,13 +1037,13 @@ static void vxlan_sock_free(struct sk_bu
 /* On transmit, associate with the tunnel socket */
 static void vxlan_set_owner(struct net_device *dev, struct sk_buff *skb)
 {
-	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
-	struct sock *sk = vn->sock->sk;
+	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct sock *sk = vxlan->vn_sock->sock->sk;
 
 	skb_orphan(skb);
 	sock_hold(sk);
 	skb->sk = sk;
-	skb->destructor = vxlan_sock_free;
+	skb->destructor = vxlan_sock_put;
 }
 
 /* Compute source port for outgoing packet
@@ -976,21 +1109,21 @@ static void vxlan_encap_bypass(struct sk
 	}
 }
 
-static netdev_tx_t vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
-				  struct vxlan_rdst *rdst, bool did_rsc)
+static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
+			   struct vxlan_rdst *rdst, bool did_rsc)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct rtable *rt;
 	const struct iphdr *old_iph;
-	struct iphdr *iph;
 	struct vxlanhdr *vxh;
 	struct udphdr *uh;
 	struct flowi4 fl4;
 	__be32 dst;
 	__be16 src_port, dst_port;
-        u32 vni;
+	u32 vni;
 	__be16 df = 0;
 	__u8 tos, ttl;
+	int err;
 
 	dst_port = rdst->remote_port ? rdst->remote_port : vxlan->dst_port;
 	vni = rdst->remote_vni;
@@ -1000,7 +1133,7 @@ static netdev_tx_t vxlan_xmit_one(struct
 		if (did_rsc) {
 			/* short-circuited back to local bridge */
 			vxlan_encap_bypass(skb, vxlan, vxlan);
-			return NETDEV_TX_OK;
+			return;
 		}
 		goto drop;
 	}
@@ -1052,19 +1185,12 @@ static netdev_tx_t vxlan_xmit_one(struct
 		struct vxlan_dev *dst_vxlan;
 
 		ip_rt_put(rt);
-		dst_vxlan = vxlan_find_vni(dev_net(dev), vni);
+		dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
 		if (!dst_vxlan)
 			goto tx_error;
 		vxlan_encap_bypass(skb, vxlan, dst_vxlan);
-		return NETDEV_TX_OK;
+		return;
 	}
-
-	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
-	IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
-			      IPSKB_REROUTED);
-	skb_dst_drop(skb);
-	skb_dst_set(skb, &rt->dst);
-
 	vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
 	vxh->vx_flags = htonl(VXLAN_FLAGS);
 	vxh->vx_vni = htonl(vni << 8);
@@ -1079,28 +1205,19 @@ static netdev_tx_t vxlan_xmit_one(struct
 	uh->len = htons(skb->len);
 	uh->check = 0;
 
-	__skb_push(skb, sizeof(*iph));
-	skb_reset_network_header(skb);
-	iph		= ip_hdr(skb);
-	iph->version	= 4;
-	iph->ihl	= sizeof(struct iphdr) >> 2;
-	iph->frag_off	= df;
-	iph->protocol	= IPPROTO_UDP;
-	iph->tos	= ip_tunnel_ecn_encap(tos, old_iph, skb);
-	iph->daddr	= dst;
-	iph->saddr	= fl4.saddr;
-	iph->ttl	= ttl ? : ip4_dst_hoplimit(&rt->dst);
-	tunnel_ip_select_ident(skb, old_iph, &rt->dst);
-
-	nf_reset(skb);
-
 	vxlan_set_owner(dev, skb);
 
 	if (handle_offloads(skb))
 		goto drop;
 
-	iptunnel_xmit(skb, dev);
-	return NETDEV_TX_OK;
+	tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
+	ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+
+	err = iptunnel_xmit(dev_net(dev), rt, skb, fl4.saddr, dst,
+			    IPPROTO_UDP, tos, ttl, df);
+	iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
+
+	return;
 
 drop:
 	dev->stats.tx_dropped++;
@@ -1110,7 +1227,6 @@ tx_error:
 	dev->stats.tx_errors++;
 tx_free:
 	dev_kfree_skb(skb);
-	return NETDEV_TX_OK;
 }
 
 /* Transmit local packets over Vxlan
@@ -1124,9 +1240,8 @@ static netdev_tx_t vxlan_xmit(struct sk_
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct ethhdr *eth;
 	bool did_rsc = false;
-	struct vxlan_rdst *rdst0, *rdst;
+	struct vxlan_rdst *rdst;
 	struct vxlan_fdb *f;
-	int rc1, rc;
 
 	skb_reset_mac_header(skb);
 	eth = eth_hdr(skb);
@@ -1145,33 +1260,28 @@ static netdev_tx_t vxlan_xmit(struct sk_
 	}
 
 	if (f == NULL) {
-		rdst0 = &vxlan->default_dst;
-
-		if (rdst0->remote_ip == htonl(INADDR_ANY) &&
-		    (vxlan->flags & VXLAN_F_L2MISS) &&
-		    !is_multicast_ether_addr(eth->h_dest))
-			vxlan_fdb_miss(vxlan, eth->h_dest);
-	} else
-		rdst0 = &f->remote;
+		f = vxlan_find_mac(vxlan, all_zeros_mac);
+		if (f == NULL) {
+			if ((vxlan->flags & VXLAN_F_L2MISS) &&
+			    !is_multicast_ether_addr(eth->h_dest))
+				vxlan_fdb_miss(vxlan, eth->h_dest);
 
-	rc = NETDEV_TX_OK;
+			dev->stats.tx_dropped++;
+			dev_kfree_skb(skb);
+			return NETDEV_TX_OK;
+		}
+	}
 
-	/* if there are multiple destinations, send copies */
-	for (rdst = rdst0->remote_next; rdst; rdst = rdst->remote_next) {
+	list_for_each_entry_rcu(rdst, &f->remotes, list) {
 		struct sk_buff *skb1;
 
 		skb1 = skb_clone(skb, GFP_ATOMIC);
-		if (skb1) {
-			rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc);
-			if (rc == NETDEV_TX_OK)
-				rc = rc1;
-		}
+		if (skb1)
+			vxlan_xmit_one(skb1, dev, rdst, did_rsc);
 	}
 
-	rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc);
-	if (rc == NETDEV_TX_OK)
-		rc = rc1;
-	return rc;
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
 }
 
 /* Walk the forwarding table and purge stale entries */
@@ -1214,23 +1324,72 @@ static void vxlan_cleanup(unsigned long
 /* Setup stats when device is created */
 static int vxlan_init(struct net_device *dev)
 {
+	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+	struct vxlan_sock *vs;
+	__u32 vni = vxlan->default_dst.remote_vni;
+
 	dev->tstats = alloc_percpu(struct pcpu_tstats);
 	if (!dev->tstats)
 		return -ENOMEM;
 
+	spin_lock(&vn->sock_lock);
+	vs = vxlan_find_port(dev_net(dev), vxlan->dst_port);
+	if (vs) {
+		/* If we have a socket with same port already, reuse it */
+		atomic_inc(&vs->refcnt);
+		vxlan->vn_sock = vs;
+		hlist_add_head_rcu(&vxlan->hlist, vni_head(vs, vni));
+	} else {
+		/* otherwise make new socket outside of RTNL */
+		dev_hold(dev);
+		queue_work(vxlan_wq, &vxlan->sock_work);
+	}
+	spin_unlock(&vn->sock_lock);
+
 	return 0;
 }
 
+static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan)
+{
+	struct vxlan_fdb *f;
+
+	spin_lock_bh(&vxlan->hash_lock);
+	f = __vxlan_find_mac(vxlan, all_zeros_mac);
+	if (f)
+		vxlan_fdb_destroy(vxlan, f);
+	spin_unlock_bh(&vxlan->hash_lock);
+}
+
+static void vxlan_uninit(struct net_device *dev)
+{
+	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+	struct vxlan_sock *vs = vxlan->vn_sock;
+
+	vxlan_fdb_delete_default(vxlan);
+
+	if (vs)
+		vxlan_sock_release(vn, vs);
+	free_percpu(dev->tstats);
+}
+
 /* Start ageing timer and join group when device is brought up */
 static int vxlan_open(struct net_device *dev)
 {
+	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
 	struct vxlan_dev *vxlan = netdev_priv(dev);
-	int err;
+	struct vxlan_sock *vs = vxlan->vn_sock;
 
-	if (IN_MULTICAST(ntohl(vxlan->default_dst.remote_ip))) {
-		err = vxlan_join_group(dev);
-		if (err)
-			return err;
+	/* socket hasn't been created */
+	if (!vs)
+		return -ENOTCONN;
+
+	if (IN_MULTICAST(ntohl(vxlan->default_dst.remote_ip)) &&
+	    vxlan_group_used(vn, vxlan->default_dst.remote_ip)) {
+		vxlan_sock_hold(vs);
+		dev_hold(dev);
+		queue_work(vxlan_wq, &vxlan->igmp_join);
 	}
 
 	if (vxlan->age_interval)
@@ -1242,7 +1401,7 @@ static int vxlan_open(struct net_device
 /* Purge the forwarding table */
 static void vxlan_flush(struct vxlan_dev *vxlan)
 {
-	unsigned h;
+	unsigned int h;
 
 	spin_lock_bh(&vxlan->hash_lock);
 	for (h = 0; h < FDB_HASH_SIZE; ++h) {
@@ -1250,7 +1409,9 @@ static void vxlan_flush(struct vxlan_dev
 		hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) {
 			struct vxlan_fdb *f
 				= container_of(p, struct vxlan_fdb, hlist);
-			vxlan_fdb_destroy(vxlan, f);
+			/* the all_zeros_mac entry is deleted at vxlan_uninit */
+			if (!is_zero_ether_addr(f->eth_addr))
+				vxlan_fdb_destroy(vxlan, f);
 		}
 	}
 	spin_unlock_bh(&vxlan->hash_lock);
@@ -1259,10 +1420,16 @@ static void vxlan_flush(struct vxlan_dev
 /* Cleanup timer and forwarding table on shutdown */
 static int vxlan_stop(struct net_device *dev)
 {
+	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
 	struct vxlan_dev *vxlan = netdev_priv(dev);
+	struct vxlan_sock *vs = vxlan->vn_sock;
 
-	if (IN_MULTICAST(ntohl(vxlan->default_dst.remote_ip)))
-		vxlan_leave_group(dev);
+	if (vs && IN_MULTICAST(ntohl(vxlan->default_dst.remote_ip)) &&
+	    ! vxlan_group_used(vn, vxlan->default_dst.remote_ip)) {
+		vxlan_sock_hold(vs);
+		dev_hold(dev);
+		queue_work(vxlan_wq, &vxlan->igmp_leave);
+	}
 
 	del_timer_sync(&vxlan->age_timer);
 
@@ -1278,6 +1445,7 @@ static void vxlan_set_multicast_list(str
 
 static const struct net_device_ops vxlan_netdev_ops = {
 	.ndo_init		= vxlan_init,
+	.ndo_uninit		= vxlan_uninit,
 	.ndo_open		= vxlan_open,
 	.ndo_stop		= vxlan_stop,
 	.ndo_start_xmit		= vxlan_xmit,
@@ -1296,17 +1464,11 @@ static struct device_type vxlan_type = {
 	.name = "vxlan",
 };
 
-static void vxlan_free(struct net_device *dev)
-{
-	free_percpu(dev->tstats);
-	free_netdev(dev);
-}
-
 /* Initialize the device structure. */
 static void vxlan_setup(struct net_device *dev)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
-	unsigned h;
+	unsigned int h;
 	int low, high;
 
 	eth_hw_addr_random(dev);
@@ -1314,7 +1476,7 @@ static void vxlan_setup(struct net_devic
 	dev->hard_header_len = ETH_HLEN + VXLAN_HEADROOM;
 
 	dev->netdev_ops = &vxlan_netdev_ops;
-	dev->destructor = vxlan_free;
+	dev->destructor = free_netdev;
 	SET_NETDEV_DEVTYPE(dev, &vxlan_type);
 
 	dev->tx_queue_len = 0;
@@ -1329,7 +1491,11 @@ static void vxlan_setup(struct net_devic
 	dev->priv_flags	&= ~IFF_XMIT_DST_RELEASE;
 	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 
+	INIT_LIST_HEAD(&vxlan->next);
 	spin_lock_init(&vxlan->hash_lock);
+	INIT_WORK(&vxlan->igmp_join, vxlan_igmp_join);
+	INIT_WORK(&vxlan->igmp_leave, vxlan_igmp_leave);
+	INIT_WORK(&vxlan->sock_work, vxlan_sock_work);
 
 	init_timer_deferrable(&vxlan->age_timer);
 	vxlan->age_timer.function = vxlan_cleanup;
@@ -1413,9 +1579,113 @@ static const struct ethtool_ops vxlan_et
 	.get_link	= ethtool_op_get_link,
 };
 
+static void vxlan_del_work(struct work_struct *work)
+{
+	struct vxlan_sock *vs = container_of(work, struct vxlan_sock, del_work);
+
+	sk_release_kernel(vs->sock->sk);
+	kfree_rcu(vs, rcu);
+}
+
+static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port)
+{
+	struct vxlan_sock *vs;
+	struct sock *sk;
+	struct sockaddr_in vxlan_addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = htonl(INADDR_ANY),
+		.sin_port = port,
+	};
+	int rc;
+	unsigned int h;
+
+	vs = kmalloc(sizeof(*vs), GFP_KERNEL);
+	if (!vs)
+		return ERR_PTR(-ENOMEM);
+
+	for (h = 0; h < VNI_HASH_SIZE; ++h)
+		INIT_HLIST_HEAD(&vs->vni_list[h]);
+
+	INIT_WORK(&vs->del_work, vxlan_del_work);
+
+	/* Create UDP socket for encapsulation receive. */
+	rc = sock_create_kern(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &vs->sock);
+	if (rc < 0) {
+		pr_debug("UDP socket create failed\n");
+		kfree(vs);
+		return ERR_PTR(rc);
+	}
+
+	/* Put in proper namespace */
+	sk = vs->sock->sk;
+	sk_change_net(sk, net);
+
+	rc = kernel_bind(vs->sock, (struct sockaddr *) &vxlan_addr,
+			 sizeof(vxlan_addr));
+	if (rc < 0) {
+		pr_debug("bind for UDP socket %pI4:%u (%d)\n",
+			 &vxlan_addr.sin_addr, ntohs(vxlan_addr.sin_port), rc);
+		sk_release_kernel(sk);
+		kfree(vs);
+		return ERR_PTR(rc);
+	}
+
+	/* Disable multicast loopback */
+	inet_sk(sk)->mc_loop = 0;
+
+	/* Mark socket as an encapsulation socket. */
+	udp_sk(sk)->encap_type = 1;
+	udp_sk(sk)->encap_rcv = vxlan_udp_encap_recv;
+	udp_encap_enable();
+	atomic_set(&vs->refcnt, 1);
+
+	return vs;
+}
+
+/* Scheduled at device creation to bind to a socket */
+static void vxlan_sock_work(struct work_struct *work)
+{
+	struct vxlan_dev *vxlan
+		= container_of(work, struct vxlan_dev, sock_work);
+	struct net_device *dev = vxlan->dev;
+	struct net *net = dev_net(dev);
+	__u32 vni = vxlan->default_dst.remote_vni;
+	__be16 port = vxlan->dst_port;
+	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
+	struct vxlan_sock *nvs, *ovs;
+
+	nvs = vxlan_socket_create(net, port);
+	if (IS_ERR(nvs)) {
+		netdev_err(vxlan->dev, "Can not create UDP socket, %ld\n",
+			   PTR_ERR(nvs));
+		goto out;
+	}
+
+	spin_lock(&vn->sock_lock);
+	/* Look again to see if can reuse socket */
+	ovs = vxlan_find_port(net, port);
+	if (ovs) {
+		atomic_inc(&ovs->refcnt);
+		vxlan->vn_sock = ovs;
+		hlist_add_head_rcu(&vxlan->hlist, vni_head(ovs, vni));
+		spin_unlock(&vn->sock_lock);
+
+		sk_release_kernel(nvs->sock->sk);
+		kfree(nvs);
+	} else {
+		vxlan->vn_sock = nvs;
+		hlist_add_head_rcu(&nvs->hlist, vs_head(net, port));
+		hlist_add_head_rcu(&vxlan->hlist, vni_head(nvs, vni));
+		spin_unlock(&vn->sock_lock);
+	}
+out:
+	dev_put(dev);
+}
+
 static int vxlan_newlink(struct net *net, struct net_device *dev,
 			 struct nlattr *tb[], struct nlattr *data[])
 {
+	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct vxlan_rdst *dst = &vxlan->default_dst;
 	__u32 vni;
@@ -1425,10 +1695,6 @@ static int vxlan_newlink(struct net *net
 		return -EINVAL;
 
 	vni = nla_get_u32(data[IFLA_VXLAN_ID]);
-	if (vxlan_find_vni(net, vni)) {
-		pr_info("duplicate VNI %u\n", vni);
-		return -EEXIST;
-	}
 	dst->remote_vni = vni;
 
 	if (data[IFLA_VXLAN_GROUP])
@@ -1494,21 +1760,44 @@ static int vxlan_newlink(struct net *net
 	if (data[IFLA_VXLAN_PORT])
 		vxlan->dst_port = nla_get_be16(data[IFLA_VXLAN_PORT]);
 
+	if (vxlan_find_vni(net, vni, vxlan->dst_port)) {
+		pr_info("duplicate VNI %u\n", vni);
+		return -EEXIST;
+	}
+
 	SET_ETHTOOL_OPS(dev, &vxlan_ethtool_ops);
 
+	/* create an fdb entry for default destination */
+	err = vxlan_fdb_create(vxlan, all_zeros_mac,
+			       vxlan->default_dst.remote_ip,
+			       NUD_REACHABLE|NUD_PERMANENT,
+			       NLM_F_EXCL|NLM_F_CREATE,
+			       vxlan->dst_port, vxlan->default_dst.remote_vni,
+			       vxlan->default_dst.remote_ifindex, NTF_SELF);
+	if (err)
+		return err;
+
 	err = register_netdevice(dev);
-	if (!err)
-		hlist_add_head_rcu(&vxlan->hlist, vni_head(net, dst->remote_vni));
+	if (err) {
+		vxlan_fdb_delete_default(vxlan);
+		return err;
+	}
 
-	return err;
+	list_add(&vxlan->next, &vn->vxlan_list);
+
+	return 0;
 }
 
 static void vxlan_dellink(struct net_device *dev, struct list_head *head)
 {
+	struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 
+	spin_lock(&vn->sock_lock);
 	hlist_del_rcu(&vxlan->hlist);
+	spin_unlock(&vn->sock_lock);
 
+	list_del(&vxlan->next);
 	unregister_netdevice_queue(dev, head);
 }
 
@@ -1595,46 +1884,13 @@ static struct rtnl_link_ops vxlan_link_o
 static __net_init int vxlan_init_net(struct net *net)
 {
 	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
-	struct sock *sk;
-	struct sockaddr_in vxlan_addr = {
-		.sin_family = AF_INET,
-		.sin_addr.s_addr = htonl(INADDR_ANY),
-	};
-	int rc;
-	unsigned h;
-
-	/* Create UDP socket for encapsulation receive. */
-	rc = sock_create_kern(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &vn->sock);
-	if (rc < 0) {
-		pr_debug("UDP socket create failed\n");
-		return rc;
-	}
-	/* Put in proper namespace */
-	sk = vn->sock->sk;
-	sk_change_net(sk, net);
-
-	vxlan_addr.sin_port = htons(vxlan_port);
-
-	rc = kernel_bind(vn->sock, (struct sockaddr *) &vxlan_addr,
-			 sizeof(vxlan_addr));
-	if (rc < 0) {
-		pr_debug("bind for UDP socket %pI4:%u (%d)\n",
-			 &vxlan_addr.sin_addr, ntohs(vxlan_addr.sin_port), rc);
-		sk_release_kernel(sk);
-		vn->sock = NULL;
-		return rc;
-	}
-
-	/* Disable multicast loopback */
-	inet_sk(sk)->mc_loop = 0;
+	unsigned int h;
 
-	/* Mark socket as an encapsulation socket. */
-	udp_sk(sk)->encap_type = 1;
-	udp_sk(sk)->encap_rcv = vxlan_udp_encap_recv;
-	udp_encap_enable();
+	INIT_LIST_HEAD(&vn->vxlan_list);
+	spin_lock_init(&vn->sock_lock);
 
-	for (h = 0; h < VNI_HASH_SIZE; ++h)
-		INIT_HLIST_HEAD(&vn->vni_list[h]);
+	for (h = 0; h < PORT_HASH_SIZE; ++h)
+		INIT_HLIST_HEAD(&vn->sock_list[h]);
 
 	return 0;
 }
@@ -1643,18 +1899,13 @@ static __net_exit void vxlan_exit_net(st
 {
 	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
 	struct vxlan_dev *vxlan;
-	unsigned h;
+	LIST_HEAD(list);
 
 	rtnl_lock();
-	for (h = 0; h < VNI_HASH_SIZE; ++h)
-		hlist_for_each_entry(vxlan, &vn->vni_list[h], hlist)
-			dev_close(vxlan->dev);
+	list_for_each_entry(vxlan, &vn->vxlan_list, next)
+		unregister_netdevice_queue(vxlan->dev, &list);
+	unregister_netdevice_many(&list);
 	rtnl_unlock();
-
-	if (vn->sock) {
-		sk_release_kernel(vn->sock->sk);
-		vn->sock = NULL;
-	}
 }
 
 static struct pernet_operations vxlan_net_ops = {
@@ -1668,6 +1919,10 @@ static int __init vxlan_init_module(void
 {
 	int rc;
 
+	vxlan_wq = alloc_workqueue("vxlan", 0, 0);
+	if (!vxlan_wq)
+		return -ENOMEM;
+
 	get_random_bytes(&vxlan_salt, sizeof(vxlan_salt));
 
 	rc = register_pernet_device(&vxlan_net_ops);
@@ -1683,13 +1938,15 @@ static int __init vxlan_init_module(void
 out2:
 	unregister_pernet_device(&vxlan_net_ops);
 out1:
+	destroy_workqueue(vxlan_wq);
 	return rc;
 }
-module_init(vxlan_init_module);
+late_initcall(vxlan_init_module);
 
 static void __exit vxlan_cleanup_module(void)
 {
 	rtnl_link_unregister(&vxlan_link_ops);
+	destroy_workqueue(vxlan_wq);
 	unregister_pernet_device(&vxlan_net_ops);
 	rcu_barrier();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wan/dlci.c linux-libre-3.11-rc7-gnu/drivers/net/wan/dlci.c
--- linux-libre-3.10-gnu/drivers/net/wan/dlci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wan/dlci.c	2013-08-25 20:43:22.000000000 -0400
@@ -493,7 +493,7 @@ static void dlci_setup(struct net_device
 static int dlci_dev_event(struct notifier_block *unused,
 			  unsigned long event, void *ptr)
 {
-	struct net_device *dev = (struct net_device *) ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 
 	if (dev_net(dev) != &init_net)
 		return NOTIFY_DONE;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wan/hdlc.c linux-libre-3.11-rc7-gnu/drivers/net/wan/hdlc.c
--- linux-libre-3.10-gnu/drivers/net/wan/hdlc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wan/hdlc.c	2013-08-25 20:43:22.000000000 -0400
@@ -99,7 +99,7 @@ static inline void hdlc_proto_stop(struc
 static int hdlc_device_event(struct notifier_block *this, unsigned long event,
 			     void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	hdlc_device *hdlc;
 	unsigned long flags;
 	int on;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wan/ixp4xx_hss.c linux-libre-3.11-rc7-gnu/drivers/net/wan/ixp4xx_hss.c
--- linux-libre-3.10-gnu/drivers/net/wan/ixp4xx_hss.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wan/ixp4xx_hss.c	2013-08-25 20:43:22.000000000 -0400
@@ -1384,7 +1384,6 @@ static int hss_remove_one(struct platfor
 	unregister_hdlc_device(port->netdev);
 	free_netdev(port->netdev);
 	npe_release(port->npe);
-	platform_set_drvdata(pdev, NULL);
 	kfree(port);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wan/lapbether.c linux-libre-3.11-rc7-gnu/drivers/net/wan/lapbether.c
--- linux-libre-3.10-gnu/drivers/net/wan/lapbether.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wan/lapbether.c	2013-08-25 20:43:22.000000000 -0400
@@ -370,7 +370,7 @@ static int lapbeth_device_event(struct n
 				unsigned long event, void *ptr)
 {
 	struct lapbethdev *lapbeth;
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 
 	if (dev_net(dev) != &init_net)
 		return NOTIFY_DONE;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/airo.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/airo.c
--- linux-libre-3.10-gnu/drivers/net/wireless/airo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/airo.c	2013-08-25 20:43:22.000000000 -0400
@@ -1893,7 +1893,8 @@ static int airo_open(struct net_device *
 
 	if (ai->wifidev != dev) {
 		clear_bit(JOB_DIE, &ai->jobs);
-		ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name);
+		ai->airo_thread_task = kthread_run(airo_thread, dev, "%s",
+						   dev->name);
 		if (IS_ERR(ai->airo_thread_task))
 			return (int)PTR_ERR(ai->airo_thread_task);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/bmi.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/bmi.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/bmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/bmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "bmi.h"
+#include "hif.h"
+#include "debug.h"
+#include "htc.h"
+
+int ath10k_bmi_done(struct ath10k *ar)
+{
+	struct bmi_cmd cmd;
+	u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done);
+	int ret;
+
+	if (ar->bmi.done_sent) {
+		ath10k_dbg(ATH10K_DBG_CORE, "%s skipped\n", __func__);
+		return 0;
+	}
+
+	ar->bmi.done_sent = true;
+	cmd.id = __cpu_to_le32(BMI_DONE);
+
+	ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL);
+	if (ret) {
+		ath10k_warn("unable to write to the device: %d\n", ret);
+		return ret;
+	}
+
+	ath10k_dbg(ATH10K_DBG_CORE, "BMI done\n");
+	return 0;
+}
+
+int ath10k_bmi_get_target_info(struct ath10k *ar,
+			       struct bmi_target_info *target_info)
+{
+	struct bmi_cmd cmd;
+	union bmi_resp resp;
+	u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.get_target_info);
+	u32 resplen = sizeof(resp.get_target_info);
+	int ret;
+
+	if (ar->bmi.done_sent) {
+		ath10k_warn("BMI Get Target Info Command disallowed\n");
+		return -EBUSY;
+	}
+
+	cmd.id = __cpu_to_le32(BMI_GET_TARGET_INFO);
+
+	ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
+	if (ret) {
+		ath10k_warn("unable to get target info from device\n");
+		return ret;
+	}
+
+	if (resplen < sizeof(resp.get_target_info)) {
+		ath10k_warn("invalid get_target_info response length (%d)\n",
+			    resplen);
+		return -EIO;
+	}
+
+	target_info->version = __le32_to_cpu(resp.get_target_info.version);
+	target_info->type    = __le32_to_cpu(resp.get_target_info.type);
+	return 0;
+}
+
+int ath10k_bmi_read_memory(struct ath10k *ar,
+			   u32 address, void *buffer, u32 length)
+{
+	struct bmi_cmd cmd;
+	union bmi_resp resp;
+	u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.read_mem);
+	u32 rxlen;
+	int ret;
+
+	if (ar->bmi.done_sent) {
+		ath10k_warn("command disallowed\n");
+		return -EBUSY;
+	}
+
+	ath10k_dbg(ATH10K_DBG_CORE,
+		   "%s: (device: 0x%p, address: 0x%x, length: %d)\n",
+		   __func__, ar, address, length);
+
+	while (length) {
+		rxlen = min_t(u32, length, BMI_MAX_DATA_SIZE);
+
+		cmd.id            = __cpu_to_le32(BMI_READ_MEMORY);
+		cmd.read_mem.addr = __cpu_to_le32(address);
+		cmd.read_mem.len  = __cpu_to_le32(rxlen);
+
+		ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen,
+						  &resp, &rxlen);
+		if (ret) {
+			ath10k_warn("unable to read from the device\n");
+			return ret;
+		}
+
+		memcpy(buffer, resp.read_mem.payload, rxlen);
+		address += rxlen;
+		buffer  += rxlen;
+		length  -= rxlen;
+	}
+
+	return 0;
+}
+
+int ath10k_bmi_write_memory(struct ath10k *ar,
+			    u32 address, const void *buffer, u32 length)
+{
+	struct bmi_cmd cmd;
+	u32 hdrlen = sizeof(cmd.id) + sizeof(cmd.write_mem);
+	u32 txlen;
+	int ret;
+
+	if (ar->bmi.done_sent) {
+		ath10k_warn("command disallowed\n");
+		return -EBUSY;
+	}
+
+	ath10k_dbg(ATH10K_DBG_CORE,
+		   "%s: (device: 0x%p, address: 0x%x, length: %d)\n",
+		   __func__, ar, address, length);
+
+	while (length) {
+		txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen);
+
+		/* copy before roundup to avoid reading beyond buffer*/
+		memcpy(cmd.write_mem.payload, buffer, txlen);
+		txlen = roundup(txlen, 4);
+
+		cmd.id             = __cpu_to_le32(BMI_WRITE_MEMORY);
+		cmd.write_mem.addr = __cpu_to_le32(address);
+		cmd.write_mem.len  = __cpu_to_le32(txlen);
+
+		ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen,
+						  NULL, NULL);
+		if (ret) {
+			ath10k_warn("unable to write to the device\n");
+			return ret;
+		}
+
+		/* fixup roundup() so `length` zeroes out for last chunk */
+		txlen = min(txlen, length);
+
+		address += txlen;
+		buffer  += txlen;
+		length  -= txlen;
+	}
+
+	return 0;
+}
+
+int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param)
+{
+	struct bmi_cmd cmd;
+	union bmi_resp resp;
+	u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.execute);
+	u32 resplen = sizeof(resp.execute);
+	int ret;
+
+	if (ar->bmi.done_sent) {
+		ath10k_warn("command disallowed\n");
+		return -EBUSY;
+	}
+
+	ath10k_dbg(ATH10K_DBG_CORE,
+		   "%s: (device: 0x%p, address: 0x%x, param: %d)\n",
+		   __func__, ar, address, *param);
+
+	cmd.id            = __cpu_to_le32(BMI_EXECUTE);
+	cmd.execute.addr  = __cpu_to_le32(address);
+	cmd.execute.param = __cpu_to_le32(*param);
+
+	ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
+	if (ret) {
+		ath10k_warn("unable to read from the device\n");
+		return ret;
+	}
+
+	if (resplen < sizeof(resp.execute)) {
+		ath10k_warn("invalid execute response length (%d)\n",
+			    resplen);
+		return ret;
+	}
+
+	*param = __le32_to_cpu(resp.execute.result);
+	return 0;
+}
+
+int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
+{
+	struct bmi_cmd cmd;
+	u32 hdrlen = sizeof(cmd.id) + sizeof(cmd.lz_data);
+	u32 txlen;
+	int ret;
+
+	if (ar->bmi.done_sent) {
+		ath10k_warn("command disallowed\n");
+		return -EBUSY;
+	}
+
+	while (length) {
+		txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen);
+
+		WARN_ON_ONCE(txlen & 3);
+
+		cmd.id          = __cpu_to_le32(BMI_LZ_DATA);
+		cmd.lz_data.len = __cpu_to_le32(txlen);
+		memcpy(cmd.lz_data.payload, buffer, txlen);
+
+		ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen,
+						  NULL, NULL);
+		if (ret) {
+			ath10k_warn("unable to write to the device\n");
+			return ret;
+		}
+
+		buffer += txlen;
+		length -= txlen;
+	}
+
+	return 0;
+}
+
+int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address)
+{
+	struct bmi_cmd cmd;
+	u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start);
+	int ret;
+
+	if (ar->bmi.done_sent) {
+		ath10k_warn("command disallowed\n");
+		return -EBUSY;
+	}
+
+	cmd.id            = __cpu_to_le32(BMI_LZ_STREAM_START);
+	cmd.lz_start.addr = __cpu_to_le32(address);
+
+	ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL);
+	if (ret) {
+		ath10k_warn("unable to Start LZ Stream to the device\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int ath10k_bmi_fast_download(struct ath10k *ar,
+			     u32 address, const void *buffer, u32 length)
+{
+	u8 trailer[4] = {};
+	u32 head_len = rounddown(length, 4);
+	u32 trailer_len = length - head_len;
+	int ret;
+
+	ret = ath10k_bmi_lz_stream_start(ar, address);
+	if (ret)
+		return ret;
+
+	/* copy the last word into a zero padded buffer */
+	if (trailer_len > 0)
+		memcpy(trailer, buffer + head_len, trailer_len);
+
+	ret = ath10k_bmi_lz_data(ar, buffer, head_len);
+	if (ret)
+		return ret;
+
+	if (trailer_len > 0)
+		ret = ath10k_bmi_lz_data(ar, trailer, 4);
+
+	if (ret != 0)
+		return ret;
+
+	/*
+	 * Close compressed stream and open a new (fake) one.
+	 * This serves mainly to flush Target caches.
+	 */
+	ret = ath10k_bmi_lz_stream_start(ar, 0x00);
+
+	return ret;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/bmi.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/bmi.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/bmi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/bmi.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _BMI_H_
+#define _BMI_H_
+
+#include "core.h"
+
+/*
+ * Bootloader Messaging Interface (BMI)
+ *
+ * BMI is a very simple messaging interface used during initialization
+ * to read memory, write memory, execute code, and to define an
+ * application entry PC.
+ *
+ * It is used to download an application to QCA988x, to provide
+ * patches to code that is already resident on QCA988x, and generally
+ * to examine and modify state.  The Host has an opportunity to use
+ * BMI only once during bootup.  Once the Host issues a BMI_DONE
+ * command, this opportunity ends.
+ *
+ * The Host writes BMI requests to mailbox0, and reads BMI responses
+ * from mailbox0.   BMI requests all begin with a command
+ * (see below for specific commands), and are followed by
+ * command-specific data.
+ *
+ * Flow control:
+ * The Host can only issue a command once the Target gives it a
+ * "BMI Command Credit", using AR8K Counter #4.  As soon as the
+ * Target has completed a command, it issues another BMI Command
+ * Credit (so the Host can issue the next command).
+ *
+ * BMI handles all required Target-side cache flushing.
+ */
+
+/* Maximum data size used for BMI transfers */
+#define BMI_MAX_DATA_SIZE	256
+
+/* len = cmd + addr + length */
+#define BMI_MAX_CMDBUF_SIZE (BMI_MAX_DATA_SIZE + \
+			sizeof(u32) + \
+			sizeof(u32) + \
+			sizeof(u32))
+
+/* BMI Commands */
+
+enum bmi_cmd_id {
+	BMI_NO_COMMAND          = 0,
+	BMI_DONE                = 1,
+	BMI_READ_MEMORY         = 2,
+	BMI_WRITE_MEMORY        = 3,
+	BMI_EXECUTE             = 4,
+	BMI_SET_APP_START       = 5,
+	BMI_READ_SOC_REGISTER   = 6,
+	BMI_READ_SOC_WORD       = 6,
+	BMI_WRITE_SOC_REGISTER  = 7,
+	BMI_WRITE_SOC_WORD      = 7,
+	BMI_GET_TARGET_ID       = 8,
+	BMI_GET_TARGET_INFO     = 8,
+	BMI_ROMPATCH_INSTALL    = 9,
+	BMI_ROMPATCH_UNINSTALL  = 10,
+	BMI_ROMPATCH_ACTIVATE   = 11,
+	BMI_ROMPATCH_DEACTIVATE = 12,
+	BMI_LZ_STREAM_START     = 13, /* should be followed by LZ_DATA */
+	BMI_LZ_DATA             = 14,
+	BMI_NVRAM_PROCESS       = 15,
+};
+
+#define BMI_NVRAM_SEG_NAME_SZ 16
+
+struct bmi_cmd {
+	__le32 id; /* enum bmi_cmd_id */
+	union {
+		struct {
+		} done;
+		struct {
+			__le32 addr;
+			__le32 len;
+		} read_mem;
+		struct {
+			__le32 addr;
+			__le32 len;
+			u8 payload[0];
+		} write_mem;
+		struct {
+			__le32 addr;
+			__le32 param;
+		} execute;
+		struct {
+			__le32 addr;
+		} set_app_start;
+		struct {
+			__le32 addr;
+		} read_soc_reg;
+		struct {
+			__le32 addr;
+			__le32 value;
+		} write_soc_reg;
+		struct {
+		} get_target_info;
+		struct {
+			__le32 rom_addr;
+			__le32 ram_addr; /* or value */
+			__le32 size;
+			__le32 activate; /* 0=install, but dont activate */
+		} rompatch_install;
+		struct {
+			__le32 patch_id;
+		} rompatch_uninstall;
+		struct {
+			__le32 count;
+			__le32 patch_ids[0]; /* length of @count */
+		} rompatch_activate;
+		struct {
+			__le32 count;
+			__le32 patch_ids[0]; /* length of @count */
+		} rompatch_deactivate;
+		struct {
+			__le32 addr;
+		} lz_start;
+		struct {
+			__le32 len; /* max BMI_MAX_DATA_SIZE */
+			u8 payload[0]; /* length of @len */
+		} lz_data;
+		struct {
+			u8 name[BMI_NVRAM_SEG_NAME_SZ];
+		} nvram_process;
+		u8 payload[BMI_MAX_CMDBUF_SIZE];
+	};
+} __packed;
+
+union bmi_resp {
+	struct {
+		u8 payload[0];
+	} read_mem;
+	struct {
+		__le32 result;
+	} execute;
+	struct {
+		__le32 value;
+	} read_soc_reg;
+	struct {
+		__le32 len;
+		__le32 version;
+		__le32 type;
+	} get_target_info;
+	struct {
+		__le32 patch_id;
+	} rompatch_install;
+	struct {
+		__le32 patch_id;
+	} rompatch_uninstall;
+	struct {
+		/* 0 = nothing executed
+		 * otherwise = NVRAM segment return value */
+		__le32 result;
+	} nvram_process;
+	u8 payload[BMI_MAX_CMDBUF_SIZE];
+} __packed;
+
+struct bmi_target_info {
+	u32 version;
+	u32 type;
+};
+
+
+/* in msec */
+#define BMI_COMMUNICATION_TIMEOUT_HZ (1*HZ)
+
+#define BMI_CE_NUM_TO_TARG 0
+#define BMI_CE_NUM_TO_HOST 1
+
+int ath10k_bmi_done(struct ath10k *ar);
+int ath10k_bmi_get_target_info(struct ath10k *ar,
+			       struct bmi_target_info *target_info);
+int ath10k_bmi_read_memory(struct ath10k *ar, u32 address,
+			   void *buffer, u32 length);
+int ath10k_bmi_write_memory(struct ath10k *ar, u32 address,
+			    const void *buffer, u32 length);
+
+#define ath10k_bmi_read32(ar, item, val)				\
+	({								\
+		int ret;						\
+		u32 addr;						\
+		__le32 tmp;						\
+									\
+		addr = host_interest_item_address(HI_ITEM(item));	\
+		ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \
+		*val = __le32_to_cpu(tmp);				\
+		ret;							\
+	 })
+
+#define ath10k_bmi_write32(ar, item, val)				\
+	({								\
+		int ret;						\
+		u32 address;						\
+		__le32 v = __cpu_to_le32(val);				\
+									\
+		address = host_interest_item_address(HI_ITEM(item));	\
+		ret = ath10k_bmi_write_memory(ar, address,		\
+					      (u8 *)&v, sizeof(v));	\
+		ret;							\
+	})
+
+int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param);
+int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address);
+int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length);
+int ath10k_bmi_fast_download(struct ath10k *ar, u32 address,
+			     const void *buffer, u32 length);
+#endif /* _BMI_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/ce.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/ce.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/ce.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/ce.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1189 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hif.h"
+#include "pci.h"
+#include "ce.h"
+#include "debug.h"
+
+/*
+ * Support for Copy Engine hardware, which is mainly used for
+ * communication between Host and Target over a PCIe interconnect.
+ */
+
+/*
+ * A single CopyEngine (CE) comprises two "rings":
+ *   a source ring
+ *   a destination ring
+ *
+ * Each ring consists of a number of descriptors which specify
+ * an address, length, and meta-data.
+ *
+ * Typically, one side of the PCIe interconnect (Host or Target)
+ * controls one ring and the other side controls the other ring.
+ * The source side chooses when to initiate a transfer and it
+ * chooses what to send (buffer address, length). The destination
+ * side keeps a supply of "anonymous receive buffers" available and
+ * it handles incoming data as it arrives (when the destination
+ * recieves an interrupt).
+ *
+ * The sender may send a simple buffer (address/length) or it may
+ * send a small list of buffers.  When a small list is sent, hardware
+ * "gathers" these and they end up in a single destination buffer
+ * with a single interrupt.
+ *
+ * There are several "contexts" managed by this layer -- more, it
+ * may seem -- than should be needed. These are provided mainly for
+ * maximum flexibility and especially to facilitate a simpler HIF
+ * implementation. There are per-CopyEngine recv, send, and watermark
+ * contexts. These are supplied by the caller when a recv, send,
+ * or watermark handler is established and they are echoed back to
+ * the caller when the respective callbacks are invoked. There is
+ * also a per-transfer context supplied by the caller when a buffer
+ * (or sendlist) is sent and when a buffer is enqueued for recv.
+ * These per-transfer contexts are echoed back to the caller when
+ * the buffer is sent/received.
+ */
+
+static inline void ath10k_ce_dest_ring_write_index_set(struct ath10k *ar,
+						       u32 ce_ctrl_addr,
+						       unsigned int n)
+{
+	ath10k_pci_write32(ar, ce_ctrl_addr + DST_WR_INDEX_ADDRESS, n);
+}
+
+static inline u32 ath10k_ce_dest_ring_write_index_get(struct ath10k *ar,
+						      u32 ce_ctrl_addr)
+{
+	return ath10k_pci_read32(ar, ce_ctrl_addr + DST_WR_INDEX_ADDRESS);
+}
+
+static inline void ath10k_ce_src_ring_write_index_set(struct ath10k *ar,
+						      u32 ce_ctrl_addr,
+						      unsigned int n)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	void __iomem *indicator_addr;
+
+	if (!test_bit(ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND, ar_pci->features)) {
+		ath10k_pci_write32(ar, ce_ctrl_addr + SR_WR_INDEX_ADDRESS, n);
+		return;
+	}
+
+	/* workaround for QCA988x_1.0 HW CE */
+	indicator_addr = ar_pci->mem + ce_ctrl_addr + DST_WATERMARK_ADDRESS;
+
+	if (ce_ctrl_addr == ath10k_ce_base_address(CDC_WAR_DATA_CE)) {
+		iowrite32((CDC_WAR_MAGIC_STR | n), indicator_addr);
+	} else {
+		unsigned long irq_flags;
+		local_irq_save(irq_flags);
+		iowrite32(1, indicator_addr);
+
+		/*
+		 * PCIE write waits for ACK in IPQ8K, there is no
+		 * need to read back value.
+		 */
+		(void)ioread32(indicator_addr);
+		(void)ioread32(indicator_addr); /* conservative */
+
+		ath10k_pci_write32(ar, ce_ctrl_addr + SR_WR_INDEX_ADDRESS, n);
+
+		iowrite32(0, indicator_addr);
+		local_irq_restore(irq_flags);
+	}
+}
+
+static inline u32 ath10k_ce_src_ring_write_index_get(struct ath10k *ar,
+						     u32 ce_ctrl_addr)
+{
+	return ath10k_pci_read32(ar, ce_ctrl_addr + SR_WR_INDEX_ADDRESS);
+}
+
+static inline u32 ath10k_ce_src_ring_read_index_get(struct ath10k *ar,
+						    u32 ce_ctrl_addr)
+{
+	return ath10k_pci_read32(ar, ce_ctrl_addr + CURRENT_SRRI_ADDRESS);
+}
+
+static inline void ath10k_ce_src_ring_base_addr_set(struct ath10k *ar,
+						    u32 ce_ctrl_addr,
+						    unsigned int addr)
+{
+	ath10k_pci_write32(ar, ce_ctrl_addr + SR_BA_ADDRESS, addr);
+}
+
+static inline void ath10k_ce_src_ring_size_set(struct ath10k *ar,
+					       u32 ce_ctrl_addr,
+					       unsigned int n)
+{
+	ath10k_pci_write32(ar, ce_ctrl_addr + SR_SIZE_ADDRESS, n);
+}
+
+static inline void ath10k_ce_src_ring_dmax_set(struct ath10k *ar,
+					       u32 ce_ctrl_addr,
+					       unsigned int n)
+{
+	u32 ctrl1_addr = ath10k_pci_read32((ar),
+					   (ce_ctrl_addr) + CE_CTRL1_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + CE_CTRL1_ADDRESS,
+			   (ctrl1_addr &  ~CE_CTRL1_DMAX_LENGTH_MASK) |
+			   CE_CTRL1_DMAX_LENGTH_SET(n));
+}
+
+static inline void ath10k_ce_src_ring_byte_swap_set(struct ath10k *ar,
+						    u32 ce_ctrl_addr,
+						    unsigned int n)
+{
+	u32 ctrl1_addr = ath10k_pci_read32(ar, ce_ctrl_addr + CE_CTRL1_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + CE_CTRL1_ADDRESS,
+			   (ctrl1_addr & ~CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK) |
+			   CE_CTRL1_SRC_RING_BYTE_SWAP_EN_SET(n));
+}
+
+static inline void ath10k_ce_dest_ring_byte_swap_set(struct ath10k *ar,
+						     u32 ce_ctrl_addr,
+						     unsigned int n)
+{
+	u32 ctrl1_addr = ath10k_pci_read32(ar, ce_ctrl_addr + CE_CTRL1_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + CE_CTRL1_ADDRESS,
+			   (ctrl1_addr & ~CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK) |
+			   CE_CTRL1_DST_RING_BYTE_SWAP_EN_SET(n));
+}
+
+static inline u32 ath10k_ce_dest_ring_read_index_get(struct ath10k *ar,
+						     u32 ce_ctrl_addr)
+{
+	return ath10k_pci_read32(ar, ce_ctrl_addr + CURRENT_DRRI_ADDRESS);
+}
+
+static inline void ath10k_ce_dest_ring_base_addr_set(struct ath10k *ar,
+						     u32 ce_ctrl_addr,
+						     u32 addr)
+{
+	ath10k_pci_write32(ar, ce_ctrl_addr + DR_BA_ADDRESS, addr);
+}
+
+static inline void ath10k_ce_dest_ring_size_set(struct ath10k *ar,
+						u32 ce_ctrl_addr,
+						unsigned int n)
+{
+	ath10k_pci_write32(ar, ce_ctrl_addr + DR_SIZE_ADDRESS, n);
+}
+
+static inline void ath10k_ce_src_ring_highmark_set(struct ath10k *ar,
+						   u32 ce_ctrl_addr,
+						   unsigned int n)
+{
+	u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + SRC_WATERMARK_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + SRC_WATERMARK_ADDRESS,
+			   (addr & ~SRC_WATERMARK_HIGH_MASK) |
+			   SRC_WATERMARK_HIGH_SET(n));
+}
+
+static inline void ath10k_ce_src_ring_lowmark_set(struct ath10k *ar,
+						  u32 ce_ctrl_addr,
+						  unsigned int n)
+{
+	u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + SRC_WATERMARK_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + SRC_WATERMARK_ADDRESS,
+			   (addr & ~SRC_WATERMARK_LOW_MASK) |
+			   SRC_WATERMARK_LOW_SET(n));
+}
+
+static inline void ath10k_ce_dest_ring_highmark_set(struct ath10k *ar,
+						    u32 ce_ctrl_addr,
+						    unsigned int n)
+{
+	u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + DST_WATERMARK_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + DST_WATERMARK_ADDRESS,
+			   (addr & ~DST_WATERMARK_HIGH_MASK) |
+			   DST_WATERMARK_HIGH_SET(n));
+}
+
+static inline void ath10k_ce_dest_ring_lowmark_set(struct ath10k *ar,
+						   u32 ce_ctrl_addr,
+						   unsigned int n)
+{
+	u32 addr = ath10k_pci_read32(ar, ce_ctrl_addr + DST_WATERMARK_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + DST_WATERMARK_ADDRESS,
+			   (addr & ~DST_WATERMARK_LOW_MASK) |
+			   DST_WATERMARK_LOW_SET(n));
+}
+
+static inline void ath10k_ce_copy_complete_inter_enable(struct ath10k *ar,
+							u32 ce_ctrl_addr)
+{
+	u32 host_ie_addr = ath10k_pci_read32(ar,
+					     ce_ctrl_addr + HOST_IE_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + HOST_IE_ADDRESS,
+			   host_ie_addr | HOST_IE_COPY_COMPLETE_MASK);
+}
+
+static inline void ath10k_ce_copy_complete_intr_disable(struct ath10k *ar,
+							u32 ce_ctrl_addr)
+{
+	u32 host_ie_addr = ath10k_pci_read32(ar,
+					     ce_ctrl_addr + HOST_IE_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + HOST_IE_ADDRESS,
+			   host_ie_addr & ~HOST_IE_COPY_COMPLETE_MASK);
+}
+
+static inline void ath10k_ce_watermark_intr_disable(struct ath10k *ar,
+						    u32 ce_ctrl_addr)
+{
+	u32 host_ie_addr = ath10k_pci_read32(ar,
+					     ce_ctrl_addr + HOST_IE_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + HOST_IE_ADDRESS,
+			   host_ie_addr & ~CE_WATERMARK_MASK);
+}
+
+static inline void ath10k_ce_error_intr_enable(struct ath10k *ar,
+					       u32 ce_ctrl_addr)
+{
+	u32 misc_ie_addr = ath10k_pci_read32(ar,
+					     ce_ctrl_addr + MISC_IE_ADDRESS);
+
+	ath10k_pci_write32(ar, ce_ctrl_addr + MISC_IE_ADDRESS,
+			   misc_ie_addr | CE_ERROR_MASK);
+}
+
+static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar,
+						     u32 ce_ctrl_addr,
+						     unsigned int mask)
+{
+	ath10k_pci_write32(ar, ce_ctrl_addr + HOST_IS_ADDRESS, mask);
+}
+
+
+/*
+ * Guts of ath10k_ce_send, used by both ath10k_ce_send and
+ * ath10k_ce_sendlist_send.
+ * The caller takes responsibility for any needed locking.
+ */
+static int ath10k_ce_send_nolock(struct ce_state *ce_state,
+				 void *per_transfer_context,
+				 u32 buffer,
+				 unsigned int nbytes,
+				 unsigned int transfer_id,
+				 unsigned int flags)
+{
+	struct ath10k *ar = ce_state->ar;
+	struct ce_ring_state *src_ring = ce_state->src_ring;
+	struct ce_desc *desc, *sdesc;
+	unsigned int nentries_mask = src_ring->nentries_mask;
+	unsigned int sw_index = src_ring->sw_index;
+	unsigned int write_index = src_ring->write_index;
+	u32 ctrl_addr = ce_state->ctrl_addr;
+	u32 desc_flags = 0;
+	int ret = 0;
+
+	if (nbytes > ce_state->src_sz_max)
+		ath10k_warn("%s: send more we can (nbytes: %d, max: %d)\n",
+			    __func__, nbytes, ce_state->src_sz_max);
+
+	ath10k_pci_wake(ar);
+
+	if (unlikely(CE_RING_DELTA(nentries_mask,
+				   write_index, sw_index - 1) <= 0)) {
+		ret = -EIO;
+		goto exit;
+	}
+
+	desc = CE_SRC_RING_TO_DESC(src_ring->base_addr_owner_space,
+				   write_index);
+	sdesc = CE_SRC_RING_TO_DESC(src_ring->shadow_base, write_index);
+
+	desc_flags |= SM(transfer_id, CE_DESC_FLAGS_META_DATA);
+
+	if (flags & CE_SEND_FLAG_GATHER)
+		desc_flags |= CE_DESC_FLAGS_GATHER;
+	if (flags & CE_SEND_FLAG_BYTE_SWAP)
+		desc_flags |= CE_DESC_FLAGS_BYTE_SWAP;
+
+	sdesc->addr   = __cpu_to_le32(buffer);
+	sdesc->nbytes = __cpu_to_le16(nbytes);
+	sdesc->flags  = __cpu_to_le16(desc_flags);
+
+	*desc = *sdesc;
+
+	src_ring->per_transfer_context[write_index] = per_transfer_context;
+
+	/* Update Source Ring Write Index */
+	write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
+
+	/* WORKAROUND */
+	if (!(flags & CE_SEND_FLAG_GATHER))
+		ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, write_index);
+
+	src_ring->write_index = write_index;
+exit:
+	ath10k_pci_sleep(ar);
+	return ret;
+}
+
+int ath10k_ce_send(struct ce_state *ce_state,
+		   void *per_transfer_context,
+		   u32 buffer,
+		   unsigned int nbytes,
+		   unsigned int transfer_id,
+		   unsigned int flags)
+{
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ret;
+
+	spin_lock_bh(&ar_pci->ce_lock);
+	ret = ath10k_ce_send_nolock(ce_state, per_transfer_context,
+				    buffer, nbytes, transfer_id, flags);
+	spin_unlock_bh(&ar_pci->ce_lock);
+
+	return ret;
+}
+
+void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, u32 buffer,
+				unsigned int nbytes, u32 flags)
+{
+	unsigned int num_items = sendlist->num_items;
+	struct ce_sendlist_item *item;
+
+	item = &sendlist->item[num_items];
+	item->data = buffer;
+	item->u.nbytes = nbytes;
+	item->flags = flags;
+	sendlist->num_items++;
+}
+
+int ath10k_ce_sendlist_send(struct ce_state *ce_state,
+			    void *per_transfer_context,
+			    struct ce_sendlist *sendlist,
+			    unsigned int transfer_id)
+{
+	struct ce_ring_state *src_ring = ce_state->src_ring;
+	struct ce_sendlist_item *item;
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	unsigned int nentries_mask = src_ring->nentries_mask;
+	unsigned int num_items = sendlist->num_items;
+	unsigned int sw_index;
+	unsigned int write_index;
+	int i, delta, ret = -ENOMEM;
+
+	spin_lock_bh(&ar_pci->ce_lock);
+
+	sw_index = src_ring->sw_index;
+	write_index = src_ring->write_index;
+
+	delta = CE_RING_DELTA(nentries_mask, write_index, sw_index - 1);
+
+	if (delta >= num_items) {
+		/*
+		 * Handle all but the last item uniformly.
+		 */
+		for (i = 0; i < num_items - 1; i++) {
+			item = &sendlist->item[i];
+			ret = ath10k_ce_send_nolock(ce_state,
+						    CE_SENDLIST_ITEM_CTXT,
+						    (u32) item->data,
+						    item->u.nbytes, transfer_id,
+						    item->flags |
+						    CE_SEND_FLAG_GATHER);
+			if (ret)
+				ath10k_warn("CE send failed for item: %d\n", i);
+		}
+		/*
+		 * Provide valid context pointer for final item.
+		 */
+		item = &sendlist->item[i];
+		ret = ath10k_ce_send_nolock(ce_state, per_transfer_context,
+					    (u32) item->data, item->u.nbytes,
+					    transfer_id, item->flags);
+		if (ret)
+			ath10k_warn("CE send failed for last item: %d\n", i);
+	}
+
+	spin_unlock_bh(&ar_pci->ce_lock);
+
+	return ret;
+}
+
+int ath10k_ce_recv_buf_enqueue(struct ce_state *ce_state,
+			       void *per_recv_context,
+			       u32 buffer)
+{
+	struct ce_ring_state *dest_ring = ce_state->dest_ring;
+	u32 ctrl_addr = ce_state->ctrl_addr;
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	unsigned int nentries_mask = dest_ring->nentries_mask;
+	unsigned int write_index;
+	unsigned int sw_index;
+	int ret;
+
+	spin_lock_bh(&ar_pci->ce_lock);
+	write_index = dest_ring->write_index;
+	sw_index = dest_ring->sw_index;
+
+	ath10k_pci_wake(ar);
+
+	if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) {
+		struct ce_desc *base = dest_ring->base_addr_owner_space;
+		struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index);
+
+		/* Update destination descriptor */
+		desc->addr    = __cpu_to_le32(buffer);
+		desc->nbytes = 0;
+
+		dest_ring->per_transfer_context[write_index] =
+							per_recv_context;
+
+		/* Update Destination Ring Write Index */
+		write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
+		ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index);
+		dest_ring->write_index = write_index;
+		ret = 0;
+	} else {
+		ret = -EIO;
+	}
+	ath10k_pci_sleep(ar);
+	spin_unlock_bh(&ar_pci->ce_lock);
+
+	return ret;
+}
+
+/*
+ * Guts of ath10k_ce_completed_recv_next.
+ * The caller takes responsibility for any necessary locking.
+ */
+static int ath10k_ce_completed_recv_next_nolock(struct ce_state *ce_state,
+						void **per_transfer_contextp,
+						u32 *bufferp,
+						unsigned int *nbytesp,
+						unsigned int *transfer_idp,
+						unsigned int *flagsp)
+{
+	struct ce_ring_state *dest_ring = ce_state->dest_ring;
+	unsigned int nentries_mask = dest_ring->nentries_mask;
+	unsigned int sw_index = dest_ring->sw_index;
+
+	struct ce_desc *base = dest_ring->base_addr_owner_space;
+	struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, sw_index);
+	struct ce_desc sdesc;
+	u16 nbytes;
+
+	/* Copy in one go for performance reasons */
+	sdesc = *desc;
+
+	nbytes = __le16_to_cpu(sdesc.nbytes);
+	if (nbytes == 0) {
+		/*
+		 * This closes a relatively unusual race where the Host
+		 * sees the updated DRRI before the update to the
+		 * corresponding descriptor has completed. We treat this
+		 * as a descriptor that is not yet done.
+		 */
+		return -EIO;
+	}
+
+	desc->nbytes = 0;
+
+	/* Return data from completed destination descriptor */
+	*bufferp = __le32_to_cpu(sdesc.addr);
+	*nbytesp = nbytes;
+	*transfer_idp = MS(__le16_to_cpu(sdesc.flags), CE_DESC_FLAGS_META_DATA);
+
+	if (__le16_to_cpu(sdesc.flags) & CE_DESC_FLAGS_BYTE_SWAP)
+		*flagsp = CE_RECV_FLAG_SWAPPED;
+	else
+		*flagsp = 0;
+
+	if (per_transfer_contextp)
+		*per_transfer_contextp =
+			dest_ring->per_transfer_context[sw_index];
+
+	/* sanity */
+	dest_ring->per_transfer_context[sw_index] = NULL;
+
+	/* Update sw_index */
+	sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
+	dest_ring->sw_index = sw_index;
+
+	return 0;
+}
+
+int ath10k_ce_completed_recv_next(struct ce_state *ce_state,
+				  void **per_transfer_contextp,
+				  u32 *bufferp,
+				  unsigned int *nbytesp,
+				  unsigned int *transfer_idp,
+				  unsigned int *flagsp)
+{
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ret;
+
+	spin_lock_bh(&ar_pci->ce_lock);
+	ret = ath10k_ce_completed_recv_next_nolock(ce_state,
+						   per_transfer_contextp,
+						   bufferp, nbytesp,
+						   transfer_idp, flagsp);
+	spin_unlock_bh(&ar_pci->ce_lock);
+
+	return ret;
+}
+
+int ath10k_ce_revoke_recv_next(struct ce_state *ce_state,
+			       void **per_transfer_contextp,
+			       u32 *bufferp)
+{
+	struct ce_ring_state *dest_ring;
+	unsigned int nentries_mask;
+	unsigned int sw_index;
+	unsigned int write_index;
+	int ret;
+	struct ath10k *ar;
+	struct ath10k_pci *ar_pci;
+
+	dest_ring = ce_state->dest_ring;
+
+	if (!dest_ring)
+		return -EIO;
+
+	ar = ce_state->ar;
+	ar_pci = ath10k_pci_priv(ar);
+
+	spin_lock_bh(&ar_pci->ce_lock);
+
+	nentries_mask = dest_ring->nentries_mask;
+	sw_index = dest_ring->sw_index;
+	write_index = dest_ring->write_index;
+	if (write_index != sw_index) {
+		struct ce_desc *base = dest_ring->base_addr_owner_space;
+		struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, sw_index);
+
+		/* Return data from completed destination descriptor */
+		*bufferp = __le32_to_cpu(desc->addr);
+
+		if (per_transfer_contextp)
+			*per_transfer_contextp =
+				dest_ring->per_transfer_context[sw_index];
+
+		/* sanity */
+		dest_ring->per_transfer_context[sw_index] = NULL;
+
+		/* Update sw_index */
+		sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
+		dest_ring->sw_index = sw_index;
+		ret = 0;
+	} else {
+		ret = -EIO;
+	}
+
+	spin_unlock_bh(&ar_pci->ce_lock);
+
+	return ret;
+}
+
+/*
+ * Guts of ath10k_ce_completed_send_next.
+ * The caller takes responsibility for any necessary locking.
+ */
+static int ath10k_ce_completed_send_next_nolock(struct ce_state *ce_state,
+						void **per_transfer_contextp,
+						u32 *bufferp,
+						unsigned int *nbytesp,
+						unsigned int *transfer_idp)
+{
+	struct ce_ring_state *src_ring = ce_state->src_ring;
+	u32 ctrl_addr = ce_state->ctrl_addr;
+	struct ath10k *ar = ce_state->ar;
+	unsigned int nentries_mask = src_ring->nentries_mask;
+	unsigned int sw_index = src_ring->sw_index;
+	unsigned int read_index;
+	int ret = -EIO;
+
+	if (src_ring->hw_index == sw_index) {
+		/*
+		 * The SW completion index has caught up with the cached
+		 * version of the HW completion index.
+		 * Update the cached HW completion index to see whether
+		 * the SW has really caught up to the HW, or if the cached
+		 * value of the HW index has become stale.
+		 */
+		ath10k_pci_wake(ar);
+		src_ring->hw_index =
+			ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
+		ath10k_pci_sleep(ar);
+	}
+	read_index = src_ring->hw_index;
+
+	if ((read_index != sw_index) && (read_index != 0xffffffff)) {
+		struct ce_desc *sbase = src_ring->shadow_base;
+		struct ce_desc *sdesc = CE_SRC_RING_TO_DESC(sbase, sw_index);
+
+		/* Return data from completed source descriptor */
+		*bufferp = __le32_to_cpu(sdesc->addr);
+		*nbytesp = __le16_to_cpu(sdesc->nbytes);
+		*transfer_idp = MS(__le16_to_cpu(sdesc->flags),
+						CE_DESC_FLAGS_META_DATA);
+
+		if (per_transfer_contextp)
+			*per_transfer_contextp =
+				src_ring->per_transfer_context[sw_index];
+
+		/* sanity */
+		src_ring->per_transfer_context[sw_index] = NULL;
+
+		/* Update sw_index */
+		sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
+		src_ring->sw_index = sw_index;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+/* NB: Modeled after ath10k_ce_completed_send_next */
+int ath10k_ce_cancel_send_next(struct ce_state *ce_state,
+			       void **per_transfer_contextp,
+			       u32 *bufferp,
+			       unsigned int *nbytesp,
+			       unsigned int *transfer_idp)
+{
+	struct ce_ring_state *src_ring;
+	unsigned int nentries_mask;
+	unsigned int sw_index;
+	unsigned int write_index;
+	int ret;
+	struct ath10k *ar;
+	struct ath10k_pci *ar_pci;
+
+	src_ring = ce_state->src_ring;
+
+	if (!src_ring)
+		return -EIO;
+
+	ar = ce_state->ar;
+	ar_pci = ath10k_pci_priv(ar);
+
+	spin_lock_bh(&ar_pci->ce_lock);
+
+	nentries_mask = src_ring->nentries_mask;
+	sw_index = src_ring->sw_index;
+	write_index = src_ring->write_index;
+
+	if (write_index != sw_index) {
+		struct ce_desc *base = src_ring->base_addr_owner_space;
+		struct ce_desc *desc = CE_SRC_RING_TO_DESC(base, sw_index);
+
+		/* Return data from completed source descriptor */
+		*bufferp = __le32_to_cpu(desc->addr);
+		*nbytesp = __le16_to_cpu(desc->nbytes);
+		*transfer_idp = MS(__le16_to_cpu(desc->flags),
+						CE_DESC_FLAGS_META_DATA);
+
+		if (per_transfer_contextp)
+			*per_transfer_contextp =
+				src_ring->per_transfer_context[sw_index];
+
+		/* sanity */
+		src_ring->per_transfer_context[sw_index] = NULL;
+
+		/* Update sw_index */
+		sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
+		src_ring->sw_index = sw_index;
+		ret = 0;
+	} else {
+		ret = -EIO;
+	}
+
+	spin_unlock_bh(&ar_pci->ce_lock);
+
+	return ret;
+}
+
+int ath10k_ce_completed_send_next(struct ce_state *ce_state,
+				  void **per_transfer_contextp,
+				  u32 *bufferp,
+				  unsigned int *nbytesp,
+				  unsigned int *transfer_idp)
+{
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ret;
+
+	spin_lock_bh(&ar_pci->ce_lock);
+	ret = ath10k_ce_completed_send_next_nolock(ce_state,
+						   per_transfer_contextp,
+						   bufferp, nbytesp,
+						   transfer_idp);
+	spin_unlock_bh(&ar_pci->ce_lock);
+
+	return ret;
+}
+
+/*
+ * Guts of interrupt handler for per-engine interrupts on a particular CE.
+ *
+ * Invokes registered callbacks for recv_complete,
+ * send_complete, and watermarks.
+ */
+void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct ce_state *ce_state = ar_pci->ce_id_to_state[ce_id];
+	u32 ctrl_addr = ce_state->ctrl_addr;
+	void *transfer_context;
+	u32 buf;
+	unsigned int nbytes;
+	unsigned int id;
+	unsigned int flags;
+
+	ath10k_pci_wake(ar);
+	spin_lock_bh(&ar_pci->ce_lock);
+
+	/* Clear the copy-complete interrupts that will be handled here. */
+	ath10k_ce_engine_int_status_clear(ar, ctrl_addr,
+					  HOST_IS_COPY_COMPLETE_MASK);
+
+	if (ce_state->recv_cb) {
+		/*
+		 * Pop completed recv buffers and call the registered
+		 * recv callback for each
+		 */
+		while (ath10k_ce_completed_recv_next_nolock(ce_state,
+							    &transfer_context,
+							    &buf, &nbytes,
+							    &id, &flags) == 0) {
+			spin_unlock_bh(&ar_pci->ce_lock);
+			ce_state->recv_cb(ce_state, transfer_context, buf,
+					  nbytes, id, flags);
+			spin_lock_bh(&ar_pci->ce_lock);
+		}
+	}
+
+	if (ce_state->send_cb) {
+		/*
+		 * Pop completed send buffers and call the registered
+		 * send callback for each
+		 */
+		while (ath10k_ce_completed_send_next_nolock(ce_state,
+							    &transfer_context,
+							    &buf,
+							    &nbytes,
+							    &id) == 0) {
+			spin_unlock_bh(&ar_pci->ce_lock);
+			ce_state->send_cb(ce_state, transfer_context,
+					  buf, nbytes, id);
+			spin_lock_bh(&ar_pci->ce_lock);
+		}
+	}
+
+	/*
+	 * Misc CE interrupts are not being handled, but still need
+	 * to be cleared.
+	 */
+	ath10k_ce_engine_int_status_clear(ar, ctrl_addr, CE_WATERMARK_MASK);
+
+	spin_unlock_bh(&ar_pci->ce_lock);
+	ath10k_pci_sleep(ar);
+}
+
+/*
+ * Handler for per-engine interrupts on ALL active CEs.
+ * This is used in cases where the system is sharing a
+ * single interrput for all CEs
+ */
+
+void ath10k_ce_per_engine_service_any(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ce_id;
+	u32 intr_summary;
+
+	ath10k_pci_wake(ar);
+	intr_summary = CE_INTERRUPT_SUMMARY(ar);
+
+	for (ce_id = 0; intr_summary && (ce_id < ar_pci->ce_count); ce_id++) {
+		if (intr_summary & (1 << ce_id))
+			intr_summary &= ~(1 << ce_id);
+		else
+			/* no intr pending on this CE */
+			continue;
+
+		ath10k_ce_per_engine_service(ar, ce_id);
+	}
+
+	ath10k_pci_sleep(ar);
+}
+
+/*
+ * Adjust interrupts for the copy complete handler.
+ * If it's needed for either send or recv, then unmask
+ * this interrupt; otherwise, mask it.
+ *
+ * Called with ce_lock held.
+ */
+static void ath10k_ce_per_engine_handler_adjust(struct ce_state *ce_state,
+						int disable_copy_compl_intr)
+{
+	u32 ctrl_addr = ce_state->ctrl_addr;
+	struct ath10k *ar = ce_state->ar;
+
+	ath10k_pci_wake(ar);
+
+	if ((!disable_copy_compl_intr) &&
+	    (ce_state->send_cb || ce_state->recv_cb))
+		ath10k_ce_copy_complete_inter_enable(ar, ctrl_addr);
+	else
+		ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr);
+
+	ath10k_ce_watermark_intr_disable(ar, ctrl_addr);
+
+	ath10k_pci_sleep(ar);
+}
+
+void ath10k_ce_disable_interrupts(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ce_id;
+
+	ath10k_pci_wake(ar);
+	for (ce_id = 0; ce_id < ar_pci->ce_count; ce_id++) {
+		struct ce_state *ce_state = ar_pci->ce_id_to_state[ce_id];
+		u32 ctrl_addr = ce_state->ctrl_addr;
+
+		ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr);
+	}
+	ath10k_pci_sleep(ar);
+}
+
+void ath10k_ce_send_cb_register(struct ce_state *ce_state,
+				void (*send_cb) (struct ce_state *ce_state,
+						 void *transfer_context,
+						 u32 buffer,
+						 unsigned int nbytes,
+						 unsigned int transfer_id),
+				int disable_interrupts)
+{
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	spin_lock_bh(&ar_pci->ce_lock);
+	ce_state->send_cb = send_cb;
+	ath10k_ce_per_engine_handler_adjust(ce_state, disable_interrupts);
+	spin_unlock_bh(&ar_pci->ce_lock);
+}
+
+void ath10k_ce_recv_cb_register(struct ce_state *ce_state,
+				void (*recv_cb) (struct ce_state *ce_state,
+						 void *transfer_context,
+						 u32 buffer,
+						 unsigned int nbytes,
+						 unsigned int transfer_id,
+						 unsigned int flags))
+{
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	spin_lock_bh(&ar_pci->ce_lock);
+	ce_state->recv_cb = recv_cb;
+	ath10k_ce_per_engine_handler_adjust(ce_state, 0);
+	spin_unlock_bh(&ar_pci->ce_lock);
+}
+
+static int ath10k_ce_init_src_ring(struct ath10k *ar,
+				   unsigned int ce_id,
+				   struct ce_state *ce_state,
+				   const struct ce_attr *attr)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct ce_ring_state *src_ring;
+	unsigned int nentries = attr->src_nentries;
+	unsigned int ce_nbytes;
+	u32 ctrl_addr = ath10k_ce_base_address(ce_id);
+	dma_addr_t base_addr;
+	char *ptr;
+
+	nentries = roundup_pow_of_two(nentries);
+
+	if (ce_state->src_ring) {
+		WARN_ON(ce_state->src_ring->nentries != nentries);
+		return 0;
+	}
+
+	ce_nbytes = sizeof(struct ce_ring_state) + (nentries * sizeof(void *));
+	ptr = kzalloc(ce_nbytes, GFP_KERNEL);
+	if (ptr == NULL)
+		return -ENOMEM;
+
+	ce_state->src_ring = (struct ce_ring_state *)ptr;
+	src_ring = ce_state->src_ring;
+
+	ptr += sizeof(struct ce_ring_state);
+	src_ring->nentries = nentries;
+	src_ring->nentries_mask = nentries - 1;
+
+	ath10k_pci_wake(ar);
+	src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
+	src_ring->hw_index = src_ring->sw_index;
+
+	src_ring->write_index =
+		ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
+	ath10k_pci_sleep(ar);
+
+	src_ring->per_transfer_context = (void **)ptr;
+
+	/*
+	 * Legacy platforms that do not support cache
+	 * coherent DMA are unsupported
+	 */
+	src_ring->base_addr_owner_space_unaligned =
+		pci_alloc_consistent(ar_pci->pdev,
+				     (nentries * sizeof(struct ce_desc) +
+				      CE_DESC_RING_ALIGN),
+				     &base_addr);
+	src_ring->base_addr_ce_space_unaligned = base_addr;
+
+	src_ring->base_addr_owner_space = PTR_ALIGN(
+			src_ring->base_addr_owner_space_unaligned,
+			CE_DESC_RING_ALIGN);
+	src_ring->base_addr_ce_space = ALIGN(
+			src_ring->base_addr_ce_space_unaligned,
+			CE_DESC_RING_ALIGN);
+
+	/*
+	 * Also allocate a shadow src ring in regular
+	 * mem to use for faster access.
+	 */
+	src_ring->shadow_base_unaligned =
+		kmalloc((nentries * sizeof(struct ce_desc) +
+			 CE_DESC_RING_ALIGN), GFP_KERNEL);
+
+	src_ring->shadow_base = PTR_ALIGN(
+			src_ring->shadow_base_unaligned,
+			CE_DESC_RING_ALIGN);
+
+	ath10k_pci_wake(ar);
+	ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr,
+					 src_ring->base_addr_ce_space);
+	ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries);
+	ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max);
+	ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0);
+	ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
+	ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
+	ath10k_pci_sleep(ar);
+
+	return 0;
+}
+
+static int ath10k_ce_init_dest_ring(struct ath10k *ar,
+				    unsigned int ce_id,
+				    struct ce_state *ce_state,
+				    const struct ce_attr *attr)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct ce_ring_state *dest_ring;
+	unsigned int nentries = attr->dest_nentries;
+	unsigned int ce_nbytes;
+	u32 ctrl_addr = ath10k_ce_base_address(ce_id);
+	dma_addr_t base_addr;
+	char *ptr;
+
+	nentries = roundup_pow_of_two(nentries);
+
+	if (ce_state->dest_ring) {
+		WARN_ON(ce_state->dest_ring->nentries != nentries);
+		return 0;
+	}
+
+	ce_nbytes = sizeof(struct ce_ring_state) + (nentries * sizeof(void *));
+	ptr = kzalloc(ce_nbytes, GFP_KERNEL);
+	if (ptr == NULL)
+		return -ENOMEM;
+
+	ce_state->dest_ring = (struct ce_ring_state *)ptr;
+	dest_ring = ce_state->dest_ring;
+
+	ptr += sizeof(struct ce_ring_state);
+	dest_ring->nentries = nentries;
+	dest_ring->nentries_mask = nentries - 1;
+
+	ath10k_pci_wake(ar);
+	dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
+	dest_ring->write_index =
+		ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
+	ath10k_pci_sleep(ar);
+
+	dest_ring->per_transfer_context = (void **)ptr;
+
+	/*
+	 * Legacy platforms that do not support cache
+	 * coherent DMA are unsupported
+	 */
+	dest_ring->base_addr_owner_space_unaligned =
+		pci_alloc_consistent(ar_pci->pdev,
+				     (nentries * sizeof(struct ce_desc) +
+				      CE_DESC_RING_ALIGN),
+				     &base_addr);
+	dest_ring->base_addr_ce_space_unaligned = base_addr;
+
+	/*
+	 * Correctly initialize memory to 0 to prevent garbage
+	 * data crashing system when download firmware
+	 */
+	memset(dest_ring->base_addr_owner_space_unaligned, 0,
+	       nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN);
+
+	dest_ring->base_addr_owner_space = PTR_ALIGN(
+			dest_ring->base_addr_owner_space_unaligned,
+			CE_DESC_RING_ALIGN);
+	dest_ring->base_addr_ce_space = ALIGN(
+			dest_ring->base_addr_ce_space_unaligned,
+			CE_DESC_RING_ALIGN);
+
+	ath10k_pci_wake(ar);
+	ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr,
+					  dest_ring->base_addr_ce_space);
+	ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries);
+	ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0);
+	ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0);
+	ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
+	ath10k_pci_sleep(ar);
+
+	return 0;
+}
+
+static struct ce_state *ath10k_ce_init_state(struct ath10k *ar,
+					     unsigned int ce_id,
+					     const struct ce_attr *attr)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct ce_state *ce_state = NULL;
+	u32 ctrl_addr = ath10k_ce_base_address(ce_id);
+
+	spin_lock_bh(&ar_pci->ce_lock);
+
+	if (!ar_pci->ce_id_to_state[ce_id]) {
+		ce_state = kzalloc(sizeof(*ce_state), GFP_ATOMIC);
+		if (ce_state == NULL) {
+			spin_unlock_bh(&ar_pci->ce_lock);
+			return NULL;
+		}
+
+		ar_pci->ce_id_to_state[ce_id] = ce_state;
+		ce_state->ar = ar;
+		ce_state->id = ce_id;
+		ce_state->ctrl_addr = ctrl_addr;
+		ce_state->state = CE_RUNNING;
+		/* Save attribute flags */
+		ce_state->attr_flags = attr->flags;
+		ce_state->src_sz_max = attr->src_sz_max;
+	}
+
+	spin_unlock_bh(&ar_pci->ce_lock);
+
+	return ce_state;
+}
+
+/*
+ * Initialize a Copy Engine based on caller-supplied attributes.
+ * This may be called once to initialize both source and destination
+ * rings or it may be called twice for separate source and destination
+ * initialization. It may be that only one side or the other is
+ * initialized by software/firmware.
+ */
+struct ce_state *ath10k_ce_init(struct ath10k *ar,
+				unsigned int ce_id,
+				const struct ce_attr *attr)
+{
+	struct ce_state *ce_state;
+	u32 ctrl_addr = ath10k_ce_base_address(ce_id);
+
+	ce_state = ath10k_ce_init_state(ar, ce_id, attr);
+	if (!ce_state) {
+		ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id);
+		return NULL;
+	}
+
+	if (attr->src_nentries) {
+		if (ath10k_ce_init_src_ring(ar, ce_id, ce_state, attr)) {
+			ath10k_err("Failed to initialize CE src ring for ID: %d\n",
+				   ce_id);
+			ath10k_ce_deinit(ce_state);
+			return NULL;
+		}
+	}
+
+	if (attr->dest_nentries) {
+		if (ath10k_ce_init_dest_ring(ar, ce_id, ce_state, attr)) {
+			ath10k_err("Failed to initialize CE dest ring for ID: %d\n",
+				   ce_id);
+			ath10k_ce_deinit(ce_state);
+			return NULL;
+		}
+	}
+
+	/* Enable CE error interrupts */
+	ath10k_pci_wake(ar);
+	ath10k_ce_error_intr_enable(ar, ctrl_addr);
+	ath10k_pci_sleep(ar);
+
+	return ce_state;
+}
+
+void ath10k_ce_deinit(struct ce_state *ce_state)
+{
+	unsigned int ce_id = ce_state->id;
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	ce_state->state = CE_UNUSED;
+	ar_pci->ce_id_to_state[ce_id] = NULL;
+
+	if (ce_state->src_ring) {
+		kfree(ce_state->src_ring->shadow_base_unaligned);
+		pci_free_consistent(ar_pci->pdev,
+				    (ce_state->src_ring->nentries *
+				     sizeof(struct ce_desc) +
+				     CE_DESC_RING_ALIGN),
+				    ce_state->src_ring->base_addr_owner_space,
+				    ce_state->src_ring->base_addr_ce_space);
+		kfree(ce_state->src_ring);
+	}
+
+	if (ce_state->dest_ring) {
+		pci_free_consistent(ar_pci->pdev,
+				    (ce_state->dest_ring->nentries *
+				     sizeof(struct ce_desc) +
+				     CE_DESC_RING_ALIGN),
+				    ce_state->dest_ring->base_addr_owner_space,
+				    ce_state->dest_ring->base_addr_ce_space);
+		kfree(ce_state->dest_ring);
+	}
+	kfree(ce_state);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/ce.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/ce.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/ce.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/ce.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,516 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _CE_H_
+#define _CE_H_
+
+#include "hif.h"
+
+
+/* Maximum number of Copy Engine's supported */
+#define CE_COUNT_MAX 8
+#define CE_HTT_H2T_MSG_SRC_NENTRIES 2048
+
+/* Descriptor rings must be aligned to this boundary */
+#define CE_DESC_RING_ALIGN	8
+#define CE_SENDLIST_ITEMS_MAX	12
+#define CE_SEND_FLAG_GATHER	0x00010000
+
+/*
+ * Copy Engine support: low-level Target-side Copy Engine API.
+ * This is a hardware access layer used by code that understands
+ * how to use copy engines.
+ */
+
+struct ce_state;
+
+
+/* Copy Engine operational state */
+enum ce_op_state {
+	CE_UNUSED,
+	CE_PAUSED,
+	CE_RUNNING,
+};
+
+#define CE_DESC_FLAGS_GATHER         (1 << 0)
+#define CE_DESC_FLAGS_BYTE_SWAP      (1 << 1)
+#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC
+#define CE_DESC_FLAGS_META_DATA_LSB  3
+
+struct ce_desc {
+	__le32 addr;
+	__le16 nbytes;
+	__le16 flags; /* %CE_DESC_FLAGS_ */
+};
+
+/* Copy Engine Ring internal state */
+struct ce_ring_state {
+	/* Number of entries in this ring; must be power of 2 */
+	unsigned int nentries;
+	unsigned int nentries_mask;
+
+	/*
+	 * For dest ring, this is the next index to be processed
+	 * by software after it was/is received into.
+	 *
+	 * For src ring, this is the last descriptor that was sent
+	 * and completion processed by software.
+	 *
+	 * Regardless of src or dest ring, this is an invariant
+	 * (modulo ring size):
+	 *     write index >= read index >= sw_index
+	 */
+	unsigned int sw_index;
+	/* cached copy */
+	unsigned int write_index;
+	/*
+	 * For src ring, this is the next index not yet processed by HW.
+	 * This is a cached copy of the real HW index (read index), used
+	 * for avoiding reading the HW index register more often than
+	 * necessary.
+	 * This extends the invariant:
+	 *     write index >= read index >= hw_index >= sw_index
+	 *
+	 * For dest ring, this is currently unused.
+	 */
+	/* cached copy */
+	unsigned int hw_index;
+
+	/* Start of DMA-coherent area reserved for descriptors */
+	/* Host address space */
+	void *base_addr_owner_space_unaligned;
+	/* CE address space */
+	u32 base_addr_ce_space_unaligned;
+
+	/*
+	 * Actual start of descriptors.
+	 * Aligned to descriptor-size boundary.
+	 * Points into reserved DMA-coherent area, above.
+	 */
+	/* Host address space */
+	void *base_addr_owner_space;
+
+	/* CE address space */
+	u32 base_addr_ce_space;
+	/*
+	 * Start of shadow copy of descriptors, within regular memory.
+	 * Aligned to descriptor-size boundary.
+	 */
+	void *shadow_base_unaligned;
+	struct ce_desc *shadow_base;
+
+	void **per_transfer_context;
+};
+
+/* Copy Engine internal state */
+struct ce_state {
+	struct ath10k *ar;
+	unsigned int id;
+
+	unsigned int attr_flags;
+
+	u32 ctrl_addr;
+	enum ce_op_state state;
+
+	void (*send_cb) (struct ce_state *ce_state,
+			 void *per_transfer_send_context,
+			 u32 buffer,
+			 unsigned int nbytes,
+			 unsigned int transfer_id);
+	void (*recv_cb) (struct ce_state *ce_state,
+			 void *per_transfer_recv_context,
+			 u32 buffer,
+			 unsigned int nbytes,
+			 unsigned int transfer_id,
+			 unsigned int flags);
+
+	unsigned int src_sz_max;
+	struct ce_ring_state *src_ring;
+	struct ce_ring_state *dest_ring;
+};
+
+struct ce_sendlist_item {
+	/* e.g. buffer or desc list */
+	dma_addr_t data;
+	union {
+		/* simple buffer */
+		unsigned int nbytes;
+		/* Rx descriptor list */
+		unsigned int ndesc;
+	} u;
+	/* externally-specified flags; OR-ed with internal flags */
+	u32 flags;
+};
+
+struct ce_sendlist {
+	unsigned int num_items;
+	struct ce_sendlist_item item[CE_SENDLIST_ITEMS_MAX];
+};
+
+/* Copy Engine settable attributes */
+struct ce_attr;
+
+/*==================Send====================*/
+
+/* ath10k_ce_send flags */
+#define CE_SEND_FLAG_BYTE_SWAP 1
+
+/*
+ * Queue a source buffer to be sent to an anonymous destination buffer.
+ *   ce         - which copy engine to use
+ *   buffer          - address of buffer
+ *   nbytes          - number of bytes to send
+ *   transfer_id     - arbitrary ID; reflected to destination
+ *   flags           - CE_SEND_FLAG_* values
+ * Returns 0 on success; otherwise an error status.
+ *
+ * Note: If no flags are specified, use CE's default data swap mode.
+ *
+ * Implementation note: pushes 1 buffer to Source ring
+ */
+int ath10k_ce_send(struct ce_state *ce_state,
+		   void *per_transfer_send_context,
+		   u32 buffer,
+		   unsigned int nbytes,
+		   /* 14 bits */
+		   unsigned int transfer_id,
+		   unsigned int flags);
+
+void ath10k_ce_send_cb_register(struct ce_state *ce_state,
+				void (*send_cb) (struct ce_state *ce_state,
+						 void *transfer_context,
+						 u32 buffer,
+						 unsigned int nbytes,
+						 unsigned int transfer_id),
+				int disable_interrupts);
+
+/* Append a simple buffer (address/length) to a sendlist. */
+void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist,
+				u32 buffer,
+				unsigned int nbytes,
+				/* OR-ed with internal flags */
+				u32 flags);
+
+/*
+ * Queue a "sendlist" of buffers to be sent using gather to a single
+ * anonymous destination buffer
+ *   ce         - which copy engine to use
+ *   sendlist        - list of simple buffers to send using gather
+ *   transfer_id     - arbitrary ID; reflected to destination
+ * Returns 0 on success; otherwise an error status.
+ *
+ * Implemenation note: Pushes multiple buffers with Gather to Source ring.
+ */
+int ath10k_ce_sendlist_send(struct ce_state *ce_state,
+			    void *per_transfer_send_context,
+			    struct ce_sendlist *sendlist,
+			    /* 14 bits */
+			    unsigned int transfer_id);
+
+/*==================Recv=======================*/
+
+/*
+ * Make a buffer available to receive. The buffer must be at least of a
+ * minimal size appropriate for this copy engine (src_sz_max attribute).
+ *   ce                    - which copy engine to use
+ *   per_transfer_recv_context  - context passed back to caller's recv_cb
+ *   buffer                     - address of buffer in CE space
+ * Returns 0 on success; otherwise an error status.
+ *
+ * Implemenation note: Pushes a buffer to Dest ring.
+ */
+int ath10k_ce_recv_buf_enqueue(struct ce_state *ce_state,
+			       void *per_transfer_recv_context,
+			       u32 buffer);
+
+void ath10k_ce_recv_cb_register(struct ce_state *ce_state,
+				void (*recv_cb) (struct ce_state *ce_state,
+						 void *transfer_context,
+						 u32 buffer,
+						 unsigned int nbytes,
+						 unsigned int transfer_id,
+						 unsigned int flags));
+
+/* recv flags */
+/* Data is byte-swapped */
+#define CE_RECV_FLAG_SWAPPED	1
+
+/*
+ * Supply data for the next completed unprocessed receive descriptor.
+ * Pops buffer from Dest ring.
+ */
+int ath10k_ce_completed_recv_next(struct ce_state *ce_state,
+				  void **per_transfer_contextp,
+				  u32 *bufferp,
+				  unsigned int *nbytesp,
+				  unsigned int *transfer_idp,
+				  unsigned int *flagsp);
+/*
+ * Supply data for the next completed unprocessed send descriptor.
+ * Pops 1 completed send buffer from Source ring.
+ */
+int ath10k_ce_completed_send_next(struct ce_state *ce_state,
+			   void **per_transfer_contextp,
+			   u32 *bufferp,
+			   unsigned int *nbytesp,
+			   unsigned int *transfer_idp);
+
+/*==================CE Engine Initialization=======================*/
+
+/* Initialize an instance of a CE */
+struct ce_state *ath10k_ce_init(struct ath10k *ar,
+				unsigned int ce_id,
+				const struct ce_attr *attr);
+
+/*==================CE Engine Shutdown=======================*/
+/*
+ * Support clean shutdown by allowing the caller to revoke
+ * receive buffers.  Target DMA must be stopped before using
+ * this API.
+ */
+int ath10k_ce_revoke_recv_next(struct ce_state *ce_state,
+			       void **per_transfer_contextp,
+			       u32 *bufferp);
+
+/*
+ * Support clean shutdown by allowing the caller to cancel
+ * pending sends.  Target DMA must be stopped before using
+ * this API.
+ */
+int ath10k_ce_cancel_send_next(struct ce_state *ce_state,
+			       void **per_transfer_contextp,
+			       u32 *bufferp,
+			       unsigned int *nbytesp,
+			       unsigned int *transfer_idp);
+
+void ath10k_ce_deinit(struct ce_state *ce_state);
+
+/*==================CE Interrupt Handlers====================*/
+void ath10k_ce_per_engine_service_any(struct ath10k *ar);
+void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
+void ath10k_ce_disable_interrupts(struct ath10k *ar);
+
+/* ce_attr.flags values */
+/* Use NonSnooping PCIe accesses? */
+#define CE_ATTR_NO_SNOOP		1
+
+/* Byte swap data words */
+#define CE_ATTR_BYTE_SWAP_DATA		2
+
+/* Swizzle descriptors? */
+#define CE_ATTR_SWIZZLE_DESCRIPTORS	4
+
+/* no interrupt on copy completion */
+#define CE_ATTR_DIS_INTR		8
+
+/* Attributes of an instance of a Copy Engine */
+struct ce_attr {
+	/* CE_ATTR_* values */
+	unsigned int flags;
+
+	/* currently not in use */
+	unsigned int priority;
+
+	/* #entries in source ring - Must be a power of 2 */
+	unsigned int src_nentries;
+
+	/*
+	 * Max source send size for this CE.
+	 * This is also the minimum size of a destination buffer.
+	 */
+	unsigned int src_sz_max;
+
+	/* #entries in destination ring - Must be a power of 2 */
+	unsigned int dest_nentries;
+
+	/* Future use */
+	void *reserved;
+};
+
+/*
+ * When using sendlist_send to transfer multiple buffer fragments, the
+ * transfer context of each fragment, except last one, will be filled
+ * with CE_SENDLIST_ITEM_CTXT. ce_completed_send will return success for
+ * each fragment done with send and the transfer context would be
+ * CE_SENDLIST_ITEM_CTXT. Upper layer could use this to identify the
+ * status of a send completion.
+ */
+#define CE_SENDLIST_ITEM_CTXT	((void *)0xcecebeef)
+
+#define SR_BA_ADDRESS		0x0000
+#define SR_SIZE_ADDRESS		0x0004
+#define DR_BA_ADDRESS		0x0008
+#define DR_SIZE_ADDRESS		0x000c
+#define CE_CMD_ADDRESS		0x0018
+
+#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_MSB	17
+#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB	17
+#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK	0x00020000
+#define CE_CTRL1_DST_RING_BYTE_SWAP_EN_SET(x) \
+	(((0 | (x)) << CE_CTRL1_DST_RING_BYTE_SWAP_EN_LSB) & \
+	CE_CTRL1_DST_RING_BYTE_SWAP_EN_MASK)
+
+#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MSB	16
+#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB	16
+#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK	0x00010000
+#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_GET(x) \
+	(((x) & CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK) >> \
+	 CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB)
+#define CE_CTRL1_SRC_RING_BYTE_SWAP_EN_SET(x) \
+	(((0 | (x)) << CE_CTRL1_SRC_RING_BYTE_SWAP_EN_LSB) & \
+	 CE_CTRL1_SRC_RING_BYTE_SWAP_EN_MASK)
+
+#define CE_CTRL1_DMAX_LENGTH_MSB		15
+#define CE_CTRL1_DMAX_LENGTH_LSB		0
+#define CE_CTRL1_DMAX_LENGTH_MASK		0x0000ffff
+#define CE_CTRL1_DMAX_LENGTH_GET(x) \
+	(((x) & CE_CTRL1_DMAX_LENGTH_MASK) >> CE_CTRL1_DMAX_LENGTH_LSB)
+#define CE_CTRL1_DMAX_LENGTH_SET(x) \
+	(((0 | (x)) << CE_CTRL1_DMAX_LENGTH_LSB) & CE_CTRL1_DMAX_LENGTH_MASK)
+
+#define CE_CTRL1_ADDRESS			0x0010
+#define CE_CTRL1_HW_MASK			0x0007ffff
+#define CE_CTRL1_SW_MASK			0x0007ffff
+#define CE_CTRL1_HW_WRITE_MASK			0x00000000
+#define CE_CTRL1_SW_WRITE_MASK			0x0007ffff
+#define CE_CTRL1_RSTMASK			0xffffffff
+#define CE_CTRL1_RESET				0x00000080
+
+#define CE_CMD_HALT_STATUS_MSB			3
+#define CE_CMD_HALT_STATUS_LSB			3
+#define CE_CMD_HALT_STATUS_MASK			0x00000008
+#define CE_CMD_HALT_STATUS_GET(x) \
+	(((x) & CE_CMD_HALT_STATUS_MASK) >> CE_CMD_HALT_STATUS_LSB)
+#define CE_CMD_HALT_STATUS_SET(x) \
+	(((0 | (x)) << CE_CMD_HALT_STATUS_LSB) & CE_CMD_HALT_STATUS_MASK)
+#define CE_CMD_HALT_STATUS_RESET		0
+#define CE_CMD_HALT_MSB				0
+#define CE_CMD_HALT_MASK			0x00000001
+
+#define HOST_IE_COPY_COMPLETE_MSB		0
+#define HOST_IE_COPY_COMPLETE_LSB		0
+#define HOST_IE_COPY_COMPLETE_MASK		0x00000001
+#define HOST_IE_COPY_COMPLETE_GET(x) \
+	(((x) & HOST_IE_COPY_COMPLETE_MASK) >> HOST_IE_COPY_COMPLETE_LSB)
+#define HOST_IE_COPY_COMPLETE_SET(x) \
+	(((0 | (x)) << HOST_IE_COPY_COMPLETE_LSB) & HOST_IE_COPY_COMPLETE_MASK)
+#define HOST_IE_COPY_COMPLETE_RESET		0
+#define HOST_IE_ADDRESS				0x002c
+
+#define HOST_IS_DST_RING_LOW_WATERMARK_MASK	0x00000010
+#define HOST_IS_DST_RING_HIGH_WATERMARK_MASK	0x00000008
+#define HOST_IS_SRC_RING_LOW_WATERMARK_MASK	0x00000004
+#define HOST_IS_SRC_RING_HIGH_WATERMARK_MASK	0x00000002
+#define HOST_IS_COPY_COMPLETE_MASK		0x00000001
+#define HOST_IS_ADDRESS				0x0030
+
+#define MISC_IE_ADDRESS				0x0034
+
+#define MISC_IS_AXI_ERR_MASK			0x00000400
+
+#define MISC_IS_DST_ADDR_ERR_MASK		0x00000200
+#define MISC_IS_SRC_LEN_ERR_MASK		0x00000100
+#define MISC_IS_DST_MAX_LEN_VIO_MASK		0x00000080
+#define MISC_IS_DST_RING_OVERFLOW_MASK		0x00000040
+#define MISC_IS_SRC_RING_OVERFLOW_MASK		0x00000020
+
+#define MISC_IS_ADDRESS				0x0038
+
+#define SR_WR_INDEX_ADDRESS			0x003c
+
+#define DST_WR_INDEX_ADDRESS			0x0040
+
+#define CURRENT_SRRI_ADDRESS			0x0044
+
+#define CURRENT_DRRI_ADDRESS			0x0048
+
+#define SRC_WATERMARK_LOW_MSB			31
+#define SRC_WATERMARK_LOW_LSB			16
+#define SRC_WATERMARK_LOW_MASK			0xffff0000
+#define SRC_WATERMARK_LOW_GET(x) \
+	(((x) & SRC_WATERMARK_LOW_MASK) >> SRC_WATERMARK_LOW_LSB)
+#define SRC_WATERMARK_LOW_SET(x) \
+	(((0 | (x)) << SRC_WATERMARK_LOW_LSB) & SRC_WATERMARK_LOW_MASK)
+#define SRC_WATERMARK_LOW_RESET			0
+#define SRC_WATERMARK_HIGH_MSB			15
+#define SRC_WATERMARK_HIGH_LSB			0
+#define SRC_WATERMARK_HIGH_MASK			0x0000ffff
+#define SRC_WATERMARK_HIGH_GET(x) \
+	(((x) & SRC_WATERMARK_HIGH_MASK) >> SRC_WATERMARK_HIGH_LSB)
+#define SRC_WATERMARK_HIGH_SET(x) \
+	(((0 | (x)) << SRC_WATERMARK_HIGH_LSB) & SRC_WATERMARK_HIGH_MASK)
+#define SRC_WATERMARK_HIGH_RESET		0
+#define SRC_WATERMARK_ADDRESS			0x004c
+
+#define DST_WATERMARK_LOW_LSB			16
+#define DST_WATERMARK_LOW_MASK			0xffff0000
+#define DST_WATERMARK_LOW_SET(x) \
+	(((0 | (x)) << DST_WATERMARK_LOW_LSB) & DST_WATERMARK_LOW_MASK)
+#define DST_WATERMARK_LOW_RESET			0
+#define DST_WATERMARK_HIGH_MSB			15
+#define DST_WATERMARK_HIGH_LSB			0
+#define DST_WATERMARK_HIGH_MASK			0x0000ffff
+#define DST_WATERMARK_HIGH_GET(x) \
+	(((x) & DST_WATERMARK_HIGH_MASK) >> DST_WATERMARK_HIGH_LSB)
+#define DST_WATERMARK_HIGH_SET(x) \
+	(((0 | (x)) << DST_WATERMARK_HIGH_LSB) & DST_WATERMARK_HIGH_MASK)
+#define DST_WATERMARK_HIGH_RESET		0
+#define DST_WATERMARK_ADDRESS			0x0050
+
+
+static inline u32 ath10k_ce_base_address(unsigned int ce_id)
+{
+	return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id;
+}
+
+#define CE_WATERMARK_MASK (HOST_IS_SRC_RING_LOW_WATERMARK_MASK  | \
+			   HOST_IS_SRC_RING_HIGH_WATERMARK_MASK | \
+			   HOST_IS_DST_RING_LOW_WATERMARK_MASK  | \
+			   HOST_IS_DST_RING_HIGH_WATERMARK_MASK)
+
+#define CE_ERROR_MASK	(MISC_IS_AXI_ERR_MASK           | \
+			 MISC_IS_DST_ADDR_ERR_MASK      | \
+			 MISC_IS_SRC_LEN_ERR_MASK       | \
+			 MISC_IS_DST_MAX_LEN_VIO_MASK   | \
+			 MISC_IS_DST_RING_OVERFLOW_MASK | \
+			 MISC_IS_SRC_RING_OVERFLOW_MASK)
+
+#define CE_SRC_RING_TO_DESC(baddr, idx) \
+	(&(((struct ce_desc *)baddr)[idx]))
+
+#define CE_DEST_RING_TO_DESC(baddr, idx) \
+	(&(((struct ce_desc *)baddr)[idx]))
+
+/* Ring arithmetic (modulus number of entries in ring, which is a pwr of 2). */
+#define CE_RING_DELTA(nentries_mask, fromidx, toidx) \
+	(((int)(toidx)-(int)(fromidx)) & (nentries_mask))
+
+#define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1) & (nentries_mask))
+
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB		8
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK		0x0000ff00
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(x) \
+	(((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> \
+		CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
+#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS			0x0000
+
+#define CE_INTERRUPT_SUMMARY(ar) \
+	CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET( \
+		ath10k_pci_read32((ar), CE_WRAPPER_BASE_ADDRESS + \
+		CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS))
+
+#endif /* _CE_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/core.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/core.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/core.c	2013-08-31 17:59:24.000000000 -0400
@@ -0,0 +1,665 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/firmware.h>
+
+#include "core.h"
+#include "mac.h"
+#include "htc.h"
+#include "hif.h"
+#include "wmi.h"
+#include "bmi.h"
+#include "debug.h"
+#include "htt.h"
+
+unsigned int ath10k_debug_mask;
+static bool uart_print;
+static unsigned int ath10k_p2p;
+module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
+module_param(uart_print, bool, 0644);
+module_param_named(p2p, ath10k_p2p, uint, 0644);
+MODULE_PARM_DESC(debug_mask, "Debugging mask");
+MODULE_PARM_DESC(uart_print, "Uart target debugging");
+MODULE_PARM_DESC(p2p, "Enable ath10k P2P support");
+
+static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+	{
+		.id = QCA988X_HW_1_0_VERSION,
+		.name = "qca988x hw1.0",
+		.patch_load_addr = QCA988X_HW_1_0_PATCH_LOAD_ADDR,
+		.fw = {
+			.dir = QCA988X_HW_1_0_FW_DIR,
+			.fw = QCA988X_HW_1_0_FW_FILE,
+			.otp = QCA988X_HW_1_0_OTP_FILE,
+			.board = QCA988X_HW_1_0_BOARD_DATA_FILE,
+		},
+	},
+	{
+		.id = QCA988X_HW_2_0_VERSION,
+		.name = "qca988x hw2.0",
+		.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
+		.fw = {
+			.dir = QCA988X_HW_2_0_FW_DIR,
+			.fw = QCA988X_HW_2_0_FW_FILE,
+			.otp = QCA988X_HW_2_0_OTP_FILE,
+			.board = QCA988X_HW_2_0_BOARD_DATA_FILE,
+		},
+	},
+};
+
+static void ath10k_send_suspend_complete(struct ath10k *ar)
+{
+	ath10k_dbg(ATH10K_DBG_CORE, "%s\n", __func__);
+
+	ar->is_target_paused = true;
+	wake_up(&ar->event_queue);
+}
+
+static int ath10k_check_fw_version(struct ath10k *ar)
+{
+	char version[32];
+
+	if (ar->fw_version_major >= SUPPORTED_FW_MAJOR &&
+	    ar->fw_version_minor >= SUPPORTED_FW_MINOR &&
+	    ar->fw_version_release >= SUPPORTED_FW_RELEASE &&
+	    ar->fw_version_build >= SUPPORTED_FW_BUILD)
+		return 0;
+
+	snprintf(version, sizeof(version), "%u.%u.%u.%u",
+		 SUPPORTED_FW_MAJOR, SUPPORTED_FW_MINOR,
+		 SUPPORTED_FW_RELEASE, SUPPORTED_FW_BUILD);
+
+	ath10k_warn("WARNING: Firmware version %s is not officially supported.\n",
+		    ar->hw->wiphy->fw_version);
+	ath10k_warn("Please upgrade to version %s (or newer)\n", version);
+
+	return 0;
+}
+
+static int ath10k_init_connect_htc(struct ath10k *ar)
+{
+	int status;
+
+	status = ath10k_wmi_connect_htc_service(ar);
+	if (status)
+		goto conn_fail;
+
+	/* Start HTC */
+	status = ath10k_htc_start(ar->htc);
+	if (status)
+		goto conn_fail;
+
+	/* Wait for WMI event to be ready */
+	status = ath10k_wmi_wait_for_service_ready(ar);
+	if (status <= 0) {
+		ath10k_warn("wmi service ready event not received");
+		status = -ETIMEDOUT;
+		goto timeout;
+	}
+
+	ath10k_dbg(ATH10K_DBG_CORE, "core wmi ready\n");
+	return 0;
+
+timeout:
+	ath10k_htc_stop(ar->htc);
+conn_fail:
+	return status;
+}
+
+static int ath10k_init_configure_target(struct ath10k *ar)
+{
+	u32 param_host;
+	int ret;
+
+	/* tell target which HTC version it is used*/
+	ret = ath10k_bmi_write32(ar, hi_app_host_interest,
+				 HTC_PROTOCOL_VERSION);
+	if (ret) {
+		ath10k_err("settings HTC version failed\n");
+		return ret;
+	}
+
+	/* set the firmware mode to STA/IBSS/AP */
+	ret = ath10k_bmi_read32(ar, hi_option_flag, &param_host);
+	if (ret) {
+		ath10k_err("setting firmware mode (1/2) failed\n");
+		return ret;
+	}
+
+	/* TODO following parameters need to be re-visited. */
+	/* num_device */
+	param_host |= (1 << HI_OPTION_NUM_DEV_SHIFT);
+	/* Firmware mode */
+	/* FIXME: Why FW_MODE_AP ??.*/
+	param_host |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);
+	/* mac_addr_method */
+	param_host |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
+	/* firmware_bridge */
+	param_host |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
+	/* fwsubmode */
+	param_host |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);
+
+	ret = ath10k_bmi_write32(ar, hi_option_flag, param_host);
+	if (ret) {
+		ath10k_err("setting firmware mode (2/2) failed\n");
+		return ret;
+	}
+
+	/* We do all byte-swapping on the host */
+	ret = ath10k_bmi_write32(ar, hi_be, 0);
+	if (ret) {
+		ath10k_err("setting host CPU BE mode failed\n");
+		return ret;
+	}
+
+	/* FW descriptor/Data swap flags */
+	ret = ath10k_bmi_write32(ar, hi_fw_swap, 0);
+
+	if (ret) {
+		ath10k_err("setting FW data/desc swap flags failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
+						   const char *dir,
+						   const char *file)
+{
+	char filename[100];
+	const struct firmware *fw;
+	int ret;
+
+	if (file == NULL)
+		return ERR_PTR(-ENOENT);
+
+	if (dir == NULL)
+		dir = ".";
+
+	snprintf(filename, sizeof(filename), "%s/%s", dir, file);
+	ret = reject_firmware(&fw, filename, ar->dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return fw;
+}
+
+static int ath10k_push_board_ext_data(struct ath10k *ar,
+				      const struct firmware *fw)
+{
+	u32 board_data_size = QCA988X_BOARD_DATA_SZ;
+	u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ;
+	u32 board_ext_data_addr;
+	int ret;
+
+	ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
+	if (ret) {
+		ath10k_err("could not read board ext data addr (%d)\n", ret);
+		return ret;
+	}
+
+	ath10k_dbg(ATH10K_DBG_CORE,
+		   "ath10k: Board extended Data download addr: 0x%x\n",
+		   board_ext_data_addr);
+
+	if (board_ext_data_addr == 0)
+		return 0;
+
+	if (fw->size != (board_data_size + board_ext_data_size)) {
+		ath10k_err("invalid board (ext) data sizes %zu != %d+%d\n",
+			   fw->size, board_data_size, board_ext_data_size);
+		return -EINVAL;
+	}
+
+	ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
+				      fw->data + board_data_size,
+				      board_ext_data_size);
+	if (ret) {
+		ath10k_err("could not write board ext data (%d)\n", ret);
+		return ret;
+	}
+
+	ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
+				 (board_ext_data_size << 16) | 1);
+	if (ret) {
+		ath10k_err("could not write board ext data bit (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ath10k_download_board_data(struct ath10k *ar)
+{
+	u32 board_data_size = QCA988X_BOARD_DATA_SZ;
+	u32 address;
+	const struct firmware *fw;
+	int ret;
+
+	fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
+				  ar->hw_params.fw.board);
+	if (IS_ERR(fw)) {
+		ath10k_err("could not fetch board data fw file (%ld)\n",
+			   PTR_ERR(fw));
+		return PTR_ERR(fw);
+	}
+
+	ret = ath10k_push_board_ext_data(ar, fw);
+	if (ret) {
+		ath10k_err("could not push board ext data (%d)\n", ret);
+		goto exit;
+	}
+
+	ret = ath10k_bmi_read32(ar, hi_board_data, &address);
+	if (ret) {
+		ath10k_err("could not read board data addr (%d)\n", ret);
+		goto exit;
+	}
+
+	ret = ath10k_bmi_write_memory(ar, address, fw->data,
+				      min_t(u32, board_data_size, fw->size));
+	if (ret) {
+		ath10k_err("could not write board data (%d)\n", ret);
+		goto exit;
+	}
+
+	ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
+	if (ret) {
+		ath10k_err("could not write board data bit (%d)\n", ret);
+		goto exit;
+	}
+
+exit:
+	release_firmware(fw);
+	return ret;
+}
+
+static int ath10k_download_and_run_otp(struct ath10k *ar)
+{
+	const struct firmware *fw;
+	u32 address;
+	u32 exec_param;
+	int ret;
+
+	/* OTP is optional */
+
+	if (ar->hw_params.fw.otp == NULL) {
+		ath10k_info("otp file not defined\n");
+		return 0;
+	}
+
+	address = ar->hw_params.patch_load_addr;
+
+	fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
+				  ar->hw_params.fw.otp);
+	if (IS_ERR(fw)) {
+		ath10k_warn("could not fetch otp (%ld)\n", PTR_ERR(fw));
+		return 0;
+	}
+
+	ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size);
+	if (ret) {
+		ath10k_err("could not write otp (%d)\n", ret);
+		goto exit;
+	}
+
+	exec_param = 0;
+	ret = ath10k_bmi_execute(ar, address, &exec_param);
+	if (ret) {
+		ath10k_err("could not execute otp (%d)\n", ret);
+		goto exit;
+	}
+
+exit:
+	release_firmware(fw);
+	return ret;
+}
+
+static int ath10k_download_fw(struct ath10k *ar)
+{
+	const struct firmware *fw;
+	u32 address;
+	int ret;
+
+	if (ar->hw_params.fw.fw == NULL)
+		return -EINVAL;
+
+	address = ar->hw_params.patch_load_addr;
+
+	fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
+				  ar->hw_params.fw.fw);
+	if (IS_ERR(fw)) {
+		ath10k_err("could not fetch fw (%ld)\n", PTR_ERR(fw));
+		return PTR_ERR(fw);
+	}
+
+	ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size);
+	if (ret) {
+		ath10k_err("could not write fw (%d)\n", ret);
+		goto exit;
+	}
+
+exit:
+	release_firmware(fw);
+	return ret;
+}
+
+static int ath10k_init_download_firmware(struct ath10k *ar)
+{
+	int ret;
+
+	ret = ath10k_download_board_data(ar);
+	if (ret)
+		return ret;
+
+	ret = ath10k_download_and_run_otp(ar);
+	if (ret)
+		return ret;
+
+	ret = ath10k_download_fw(ar);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+static int ath10k_init_uart(struct ath10k *ar)
+{
+	int ret;
+
+	/*
+	 * Explicitly setting UART prints to zero as target turns it on
+	 * based on scratch registers.
+	 */
+	ret = ath10k_bmi_write32(ar, hi_serial_enable, 0);
+	if (ret) {
+		ath10k_warn("could not disable UART prints (%d)\n", ret);
+		return ret;
+	}
+
+	if (!uart_print) {
+		ath10k_info("UART prints disabled\n");
+		return 0;
+	}
+
+	ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7);
+	if (ret) {
+		ath10k_warn("could not enable UART prints (%d)\n", ret);
+		return ret;
+	}
+
+	ret = ath10k_bmi_write32(ar, hi_serial_enable, 1);
+	if (ret) {
+		ath10k_warn("could not enable UART prints (%d)\n", ret);
+		return ret;
+	}
+
+	ath10k_info("UART prints enabled\n");
+	return 0;
+}
+
+static int ath10k_init_hw_params(struct ath10k *ar)
+{
+	const struct ath10k_hw_params *uninitialized_var(hw_params);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
+		hw_params = &ath10k_hw_params_list[i];
+
+		if (hw_params->id == ar->target_version)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
+		ath10k_err("Unsupported hardware version: 0x%x\n",
+			   ar->target_version);
+		return -EINVAL;
+	}
+
+	ar->hw_params = *hw_params;
+
+	ath10k_info("Hardware name %s version 0x%x\n",
+		    ar->hw_params.name, ar->target_version);
+
+	return 0;
+}
+
+struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
+				  enum ath10k_bus bus,
+				  const struct ath10k_hif_ops *hif_ops)
+{
+	struct ath10k *ar;
+
+	ar = ath10k_mac_create();
+	if (!ar)
+		return NULL;
+
+	ar->ath_common.priv = ar;
+	ar->ath_common.hw = ar->hw;
+
+	ar->p2p = !!ath10k_p2p;
+	ar->dev = dev;
+
+	ar->hif.priv = hif_priv;
+	ar->hif.ops = hif_ops;
+	ar->hif.bus = bus;
+
+	ar->free_vdev_map = 0xFF; /* 8 vdevs */
+
+	init_completion(&ar->scan.started);
+	init_completion(&ar->scan.completed);
+	init_completion(&ar->scan.on_channel);
+
+	init_completion(&ar->install_key_done);
+	init_completion(&ar->vdev_setup_done);
+
+	setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar);
+
+	ar->workqueue = create_singlethread_workqueue("ath10k_wq");
+	if (!ar->workqueue)
+		goto err_wq;
+
+	mutex_init(&ar->conf_mutex);
+	spin_lock_init(&ar->data_lock);
+
+	INIT_LIST_HEAD(&ar->peers);
+	init_waitqueue_head(&ar->peer_mapping_wq);
+
+	init_completion(&ar->offchan_tx_completed);
+	INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work);
+	skb_queue_head_init(&ar->offchan_tx_queue);
+
+	init_waitqueue_head(&ar->event_queue);
+
+	return ar;
+
+err_wq:
+	ath10k_mac_destroy(ar);
+	return NULL;
+}
+EXPORT_SYMBOL(ath10k_core_create);
+
+void ath10k_core_destroy(struct ath10k *ar)
+{
+	flush_workqueue(ar->workqueue);
+	destroy_workqueue(ar->workqueue);
+
+	ath10k_mac_destroy(ar);
+}
+EXPORT_SYMBOL(ath10k_core_destroy);
+
+
+int ath10k_core_register(struct ath10k *ar)
+{
+	struct ath10k_htc_ops htc_ops;
+	struct bmi_target_info target_info;
+	int status;
+
+	memset(&target_info, 0, sizeof(target_info));
+	status = ath10k_bmi_get_target_info(ar, &target_info);
+	if (status)
+		goto err;
+
+	ar->target_version = target_info.version;
+	ar->hw->wiphy->hw_version = target_info.version;
+
+	status = ath10k_init_hw_params(ar);
+	if (status)
+		goto err;
+
+	if (ath10k_init_configure_target(ar)) {
+		status = -EINVAL;
+		goto err;
+	}
+
+	status = ath10k_init_download_firmware(ar);
+	if (status)
+		goto err;
+
+	status = ath10k_init_uart(ar);
+	if (status)
+		goto err;
+
+	htc_ops.target_send_suspend_complete = ath10k_send_suspend_complete;
+
+	ar->htc = ath10k_htc_create(ar, &htc_ops);
+	if (IS_ERR(ar->htc)) {
+		status = PTR_ERR(ar->htc);
+		ath10k_err("could not create HTC (%d)\n", status);
+		goto err;
+	}
+
+	status = ath10k_bmi_done(ar);
+	if (status)
+		goto err_htc_destroy;
+
+	status = ath10k_wmi_attach(ar);
+	if (status) {
+		ath10k_err("WMI attach failed: %d\n", status);
+		goto err_htc_destroy;
+	}
+
+	status = ath10k_htc_wait_target(ar->htc);
+	if (status)
+		goto err_wmi_detach;
+
+	ar->htt = ath10k_htt_attach(ar);
+	if (!ar->htt) {
+		status = -ENOMEM;
+		goto err_wmi_detach;
+	}
+
+	status = ath10k_init_connect_htc(ar);
+	if (status)
+		goto err_htt_detach;
+
+	ath10k_info("firmware %s booted\n", ar->hw->wiphy->fw_version);
+
+	status = ath10k_check_fw_version(ar);
+	if (status)
+		goto err_disconnect_htc;
+
+	status = ath10k_wmi_cmd_init(ar);
+	if (status) {
+		ath10k_err("could not send WMI init command (%d)\n", status);
+		goto err_disconnect_htc;
+	}
+
+	status = ath10k_wmi_wait_for_unified_ready(ar);
+	if (status <= 0) {
+		ath10k_err("wmi unified ready event not received\n");
+		status = -ETIMEDOUT;
+		goto err_disconnect_htc;
+	}
+
+	status = ath10k_htt_attach_target(ar->htt);
+	if (status)
+		goto err_disconnect_htc;
+
+	status = ath10k_mac_register(ar);
+	if (status)
+		goto err_disconnect_htc;
+
+	status = ath10k_debug_create(ar);
+	if (status) {
+		ath10k_err("unable to initialize debugfs\n");
+		goto err_unregister_mac;
+	}
+
+	return 0;
+
+err_unregister_mac:
+	ath10k_mac_unregister(ar);
+err_disconnect_htc:
+	ath10k_htc_stop(ar->htc);
+err_htt_detach:
+	ath10k_htt_detach(ar->htt);
+err_wmi_detach:
+	ath10k_wmi_detach(ar);
+err_htc_destroy:
+	ath10k_htc_destroy(ar->htc);
+err:
+	return status;
+}
+EXPORT_SYMBOL(ath10k_core_register);
+
+void ath10k_core_unregister(struct ath10k *ar)
+{
+	/* We must unregister from mac80211 before we stop HTC and HIF.
+	 * Otherwise we will fail to submit commands to FW and mac80211 will be
+	 * unhappy about callback failures. */
+	ath10k_mac_unregister(ar);
+	ath10k_htc_stop(ar->htc);
+	ath10k_htt_detach(ar->htt);
+	ath10k_wmi_detach(ar);
+	ath10k_htc_destroy(ar->htc);
+}
+EXPORT_SYMBOL(ath10k_core_unregister);
+
+int ath10k_core_target_suspend(struct ath10k *ar)
+{
+	int ret;
+
+	ath10k_dbg(ATH10K_DBG_CORE, "%s: called", __func__);
+
+	ret = ath10k_wmi_pdev_suspend_target(ar);
+	if (ret)
+		ath10k_warn("could not suspend target (%d)\n", ret);
+
+	return ret;
+}
+EXPORT_SYMBOL(ath10k_core_target_suspend);
+
+int ath10k_core_target_resume(struct ath10k *ar)
+{
+	int ret;
+
+	ath10k_dbg(ATH10K_DBG_CORE, "%s: called", __func__);
+
+	ret = ath10k_wmi_pdev_resume_target(ar);
+	if (ret)
+		ath10k_warn("could not resume target (%d)\n", ret);
+
+	return ret;
+}
+EXPORT_SYMBOL(ath10k_core_target_resume);
+
+MODULE_AUTHOR("Qualcomm Atheros");
+MODULE_DESCRIPTION("Core module for QCA988X PCIe devices.");
+MODULE_LICENSE("Dual BSD/GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/core.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/core.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/core.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _CORE_H_
+#define _CORE_H_
+
+#include <linux/completion.h>
+#include <linux/if_ether.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include "htc.h"
+#include "hw.h"
+#include "targaddrs.h"
+#include "wmi.h"
+#include "../ath.h"
+#include "../regd.h"
+
+#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB)
+#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
+#define WO(_f)      ((_f##_OFFSET) >> 2)
+
+#define ATH10K_SCAN_ID 0
+#define WMI_READY_TIMEOUT (5 * HZ)
+#define ATH10K_FLUSH_TIMEOUT_HZ (5*HZ)
+
+/* Antenna noise floor */
+#define ATH10K_DEFAULT_NOISE_FLOOR -95
+
+struct ath10k;
+
+enum ath10k_bus {
+	ATH10K_BUS_PCI,
+};
+
+struct ath10k_skb_cb {
+	dma_addr_t paddr;
+	bool is_mapped;
+	bool is_aborted;
+
+	struct {
+		u8 vdev_id;
+		u16 msdu_id;
+		u8 tid;
+		bool is_offchan;
+		bool is_conf;
+		bool discard;
+		bool no_ack;
+		u8 refcount;
+		struct sk_buff *txfrag;
+		struct sk_buff *msdu;
+	} __packed htt;
+
+	/* 4 bytes left on 64bit arch */
+} __packed;
+
+static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb)
+{
+	BUILD_BUG_ON(sizeof(struct ath10k_skb_cb) >
+		     IEEE80211_TX_INFO_DRIVER_DATA_SIZE);
+	return (struct ath10k_skb_cb *)&IEEE80211_SKB_CB(skb)->driver_data;
+}
+
+static inline int ath10k_skb_map(struct device *dev, struct sk_buff *skb)
+{
+	if (ATH10K_SKB_CB(skb)->is_mapped)
+		return -EINVAL;
+
+	ATH10K_SKB_CB(skb)->paddr = dma_map_single(dev, skb->data, skb->len,
+						   DMA_TO_DEVICE);
+
+	if (unlikely(dma_mapping_error(dev, ATH10K_SKB_CB(skb)->paddr)))
+		return -EIO;
+
+	ATH10K_SKB_CB(skb)->is_mapped = true;
+	return 0;
+}
+
+static inline int ath10k_skb_unmap(struct device *dev, struct sk_buff *skb)
+{
+	if (!ATH10K_SKB_CB(skb)->is_mapped)
+		return -EINVAL;
+
+	dma_unmap_single(dev, ATH10K_SKB_CB(skb)->paddr, skb->len,
+			 DMA_TO_DEVICE);
+	ATH10K_SKB_CB(skb)->is_mapped = false;
+	return 0;
+}
+
+static inline u32 host_interest_item_address(u32 item_offset)
+{
+	return QCA988X_HOST_INTEREST_ADDRESS + item_offset;
+}
+
+struct ath10k_bmi {
+	bool done_sent;
+};
+
+struct ath10k_wmi {
+	enum ath10k_htc_ep_id eid;
+	struct completion service_ready;
+	struct completion unified_ready;
+	atomic_t pending_tx_count;
+	wait_queue_head_t wq;
+
+	struct sk_buff_head wmi_event_list;
+	struct work_struct wmi_event_work;
+};
+
+struct ath10k_peer_stat {
+	u8 peer_macaddr[ETH_ALEN];
+	u32 peer_rssi;
+	u32 peer_tx_rate;
+};
+
+struct ath10k_target_stats {
+	/* PDEV stats */
+	s32 ch_noise_floor;
+	u32 tx_frame_count;
+	u32 rx_frame_count;
+	u32 rx_clear_count;
+	u32 cycle_count;
+	u32 phy_err_count;
+	u32 chan_tx_power;
+
+	/* PDEV TX stats */
+	s32 comp_queued;
+	s32 comp_delivered;
+	s32 msdu_enqued;
+	s32 mpdu_enqued;
+	s32 wmm_drop;
+	s32 local_enqued;
+	s32 local_freed;
+	s32 hw_queued;
+	s32 hw_reaped;
+	s32 underrun;
+	s32 tx_abort;
+	s32 mpdus_requed;
+	u32 tx_ko;
+	u32 data_rc;
+	u32 self_triggers;
+	u32 sw_retry_failure;
+	u32 illgl_rate_phy_err;
+	u32 pdev_cont_xretry;
+	u32 pdev_tx_timeout;
+	u32 pdev_resets;
+	u32 phy_underrun;
+	u32 txop_ovf;
+
+	/* PDEV RX stats */
+	s32 mid_ppdu_route_change;
+	s32 status_rcvd;
+	s32 r0_frags;
+	s32 r1_frags;
+	s32 r2_frags;
+	s32 r3_frags;
+	s32 htt_msdus;
+	s32 htt_mpdus;
+	s32 loc_msdus;
+	s32 loc_mpdus;
+	s32 oversize_amsdu;
+	s32 phy_errs;
+	s32 phy_err_drop;
+	s32 mpdu_errs;
+
+	/* VDEV STATS */
+
+	/* PEER STATS */
+	u8 peers;
+	struct ath10k_peer_stat peer_stat[TARGET_NUM_PEERS];
+
+	/* TODO: Beacon filter stats */
+
+};
+
+#define ATH10K_MAX_NUM_PEER_IDS (1 << 11) /* htt rx_desc limit */
+
+struct ath10k_peer {
+	struct list_head list;
+	int vdev_id;
+	u8 addr[ETH_ALEN];
+	DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS);
+	struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
+};
+
+#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ)
+
+struct ath10k_vif {
+	u32 vdev_id;
+	enum wmi_vdev_type vdev_type;
+	enum wmi_vdev_subtype vdev_subtype;
+	u32 beacon_interval;
+	u32 dtim_period;
+
+	struct ath10k *ar;
+	struct ieee80211_vif *vif;
+
+	struct ieee80211_key_conf *wep_keys[WMI_MAX_KEY_INDEX + 1];
+	u8 def_wep_key_index;
+
+	u16 tx_seq_no;
+
+	union {
+		struct {
+			u8 bssid[ETH_ALEN];
+			u32 uapsd;
+		} sta;
+		struct {
+			/* 127 stations; wmi limit */
+			u8 tim_bitmap[16];
+			u8 tim_len;
+			u32 ssid_len;
+			u8 ssid[IEEE80211_MAX_SSID_LEN];
+			bool hidden_ssid;
+			/* P2P_IE with NoA attribute for P2P_GO case */
+			u32 noa_len;
+			u8 *noa_data;
+		} ap;
+		struct {
+			u8 bssid[ETH_ALEN];
+		} ibss;
+	} u;
+};
+
+struct ath10k_vif_iter {
+	u32 vdev_id;
+	struct ath10k_vif *arvif;
+};
+
+struct ath10k_debug {
+	struct dentry *debugfs_phy;
+
+	struct ath10k_target_stats target_stats;
+	u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE];
+
+	struct completion event_stats_compl;
+};
+
+struct ath10k {
+	struct ath_common ath_common;
+	struct ieee80211_hw *hw;
+	struct device *dev;
+	u8 mac_addr[ETH_ALEN];
+
+	u32 target_version;
+	u8 fw_version_major;
+	u32 fw_version_minor;
+	u16 fw_version_release;
+	u16 fw_version_build;
+	u32 phy_capability;
+	u32 hw_min_tx_power;
+	u32 hw_max_tx_power;
+	u32 ht_cap_info;
+	u32 vht_cap_info;
+
+	struct targetdef *targetdef;
+	struct hostdef *hostdef;
+
+	bool p2p;
+
+	struct {
+		void *priv;
+		enum ath10k_bus bus;
+		const struct ath10k_hif_ops *ops;
+	} hif;
+
+	struct ath10k_wmi wmi;
+
+	wait_queue_head_t event_queue;
+	bool is_target_paused;
+
+	struct ath10k_bmi bmi;
+
+	struct ath10k_htc *htc;
+	struct ath10k_htt *htt;
+
+	struct ath10k_hw_params {
+		u32 id;
+		const char *name;
+		u32 patch_load_addr;
+
+		struct ath10k_hw_params_fw {
+			const char *dir;
+			const char *fw;
+			const char *otp;
+			const char *board;
+		} fw;
+	} hw_params;
+
+	struct {
+		struct completion started;
+		struct completion completed;
+		struct completion on_channel;
+		struct timer_list timeout;
+		bool is_roc;
+		bool in_progress;
+		bool aborting;
+		int vdev_id;
+		int roc_freq;
+	} scan;
+
+	struct {
+		struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+	} mac;
+
+	/* should never be NULL; needed for regular htt rx */
+	struct ieee80211_channel *rx_channel;
+
+	/* valid during scan; needed for mgmt rx during scan */
+	struct ieee80211_channel *scan_channel;
+
+	int free_vdev_map;
+	int monitor_vdev_id;
+	bool monitor_enabled;
+	bool monitor_present;
+	unsigned int filter_flags;
+
+	struct wmi_pdev_set_wmm_params_arg wmm_params;
+	struct completion install_key_done;
+
+	struct completion vdev_setup_done;
+
+	struct workqueue_struct *workqueue;
+
+	/* prevents concurrent FW reconfiguration */
+	struct mutex conf_mutex;
+
+	/* protects shared structure data */
+	spinlock_t data_lock;
+
+	struct list_head peers;
+	wait_queue_head_t peer_mapping_wq;
+
+	struct work_struct offchan_tx_work;
+	struct sk_buff_head offchan_tx_queue;
+	struct completion offchan_tx_completed;
+	struct sk_buff *offchan_tx_skb;
+
+#ifdef CONFIG_ATH10K_DEBUGFS
+	struct ath10k_debug debug;
+#endif
+};
+
+struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
+				  enum ath10k_bus bus,
+				  const struct ath10k_hif_ops *hif_ops);
+void ath10k_core_destroy(struct ath10k *ar);
+
+int ath10k_core_register(struct ath10k *ar);
+void ath10k_core_unregister(struct ath10k *ar);
+
+int ath10k_core_target_suspend(struct ath10k *ar);
+int ath10k_core_target_resume(struct ath10k *ar);
+
+#endif /* _CORE_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/debug.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/debug.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/debug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+
+#include "core.h"
+#include "debug.h"
+
+static int ath10k_printk(const char *level, const char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+	int rtn;
+
+	va_start(args, fmt);
+
+	vaf.fmt = fmt;
+	vaf.va = &args;
+
+	rtn = printk("%sath10k: %pV", level, &vaf);
+
+	va_end(args);
+
+	return rtn;
+}
+
+int ath10k_info(const char *fmt, ...)
+{
+	struct va_format vaf = {
+		.fmt = fmt,
+	};
+	va_list args;
+	int ret;
+
+	va_start(args, fmt);
+	vaf.va = &args;
+	ret = ath10k_printk(KERN_INFO, "%pV", &vaf);
+	trace_ath10k_log_info(&vaf);
+	va_end(args);
+
+	return ret;
+}
+EXPORT_SYMBOL(ath10k_info);
+
+int ath10k_err(const char *fmt, ...)
+{
+	struct va_format vaf = {
+		.fmt = fmt,
+	};
+	va_list args;
+	int ret;
+
+	va_start(args, fmt);
+	vaf.va = &args;
+	ret = ath10k_printk(KERN_ERR, "%pV", &vaf);
+	trace_ath10k_log_err(&vaf);
+	va_end(args);
+
+	return ret;
+}
+EXPORT_SYMBOL(ath10k_err);
+
+int ath10k_warn(const char *fmt, ...)
+{
+	struct va_format vaf = {
+		.fmt = fmt,
+	};
+	va_list args;
+	int ret = 0;
+
+	va_start(args, fmt);
+	vaf.va = &args;
+
+	if (net_ratelimit())
+		ret = ath10k_printk(KERN_WARNING, "%pV", &vaf);
+
+	trace_ath10k_log_warn(&vaf);
+
+	va_end(args);
+
+	return ret;
+}
+EXPORT_SYMBOL(ath10k_warn);
+
+#ifdef CONFIG_ATH10K_DEBUGFS
+
+void ath10k_debug_read_service_map(struct ath10k *ar,
+				   void *service_map,
+				   size_t map_size)
+{
+	memcpy(ar->debug.wmi_service_bitmap, service_map, map_size);
+}
+
+static ssize_t ath10k_read_wmi_services(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct ath10k *ar = file->private_data;
+	char *buf;
+	unsigned int len = 0, buf_len = 1500;
+	const char *status;
+	ssize_t ret_cnt;
+	int i;
+
+	buf = kzalloc(buf_len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	mutex_lock(&ar->conf_mutex);
+
+	if (len > buf_len)
+		len = buf_len;
+
+	for (i = 0; i < WMI_SERVICE_LAST; i++) {
+		if (WMI_SERVICE_IS_ENABLED(ar->debug.wmi_service_bitmap, i))
+			status = "enabled";
+		else
+			status = "disabled";
+
+		len += scnprintf(buf + len, buf_len - len,
+				 "0x%02x - %20s - %s\n",
+				 i, wmi_service_name(i), status);
+	}
+
+	ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+
+	mutex_unlock(&ar->conf_mutex);
+
+	kfree(buf);
+	return ret_cnt;
+}
+
+static const struct file_operations fops_wmi_services = {
+	.read = ath10k_read_wmi_services,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+void ath10k_debug_read_target_stats(struct ath10k *ar,
+				    struct wmi_stats_event *ev)
+{
+	u8 *tmp = ev->data;
+	struct ath10k_target_stats *stats;
+	int num_pdev_stats, num_vdev_stats, num_peer_stats;
+	struct wmi_pdev_stats *ps;
+	int i;
+
+	mutex_lock(&ar->conf_mutex);
+
+	stats = &ar->debug.target_stats;
+
+	num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); /* 0 or 1 */
+	num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); /* 0 or max vdevs */
+	num_peer_stats = __le32_to_cpu(ev->num_peer_stats); /* 0 or max peers */
+
+	if (num_pdev_stats) {
+		ps = (struct wmi_pdev_stats *)tmp;
+
+		stats->ch_noise_floor = __le32_to_cpu(ps->chan_nf);
+		stats->tx_frame_count = __le32_to_cpu(ps->tx_frame_count);
+		stats->rx_frame_count = __le32_to_cpu(ps->rx_frame_count);
+		stats->rx_clear_count = __le32_to_cpu(ps->rx_clear_count);
+		stats->cycle_count = __le32_to_cpu(ps->cycle_count);
+		stats->phy_err_count = __le32_to_cpu(ps->phy_err_count);
+		stats->chan_tx_power = __le32_to_cpu(ps->chan_tx_pwr);
+
+		stats->comp_queued = __le32_to_cpu(ps->wal.tx.comp_queued);
+		stats->comp_delivered =
+			__le32_to_cpu(ps->wal.tx.comp_delivered);
+		stats->msdu_enqued = __le32_to_cpu(ps->wal.tx.msdu_enqued);
+		stats->mpdu_enqued = __le32_to_cpu(ps->wal.tx.mpdu_enqued);
+		stats->wmm_drop = __le32_to_cpu(ps->wal.tx.wmm_drop);
+		stats->local_enqued = __le32_to_cpu(ps->wal.tx.local_enqued);
+		stats->local_freed = __le32_to_cpu(ps->wal.tx.local_freed);
+		stats->hw_queued = __le32_to_cpu(ps->wal.tx.hw_queued);
+		stats->hw_reaped = __le32_to_cpu(ps->wal.tx.hw_reaped);
+		stats->underrun = __le32_to_cpu(ps->wal.tx.underrun);
+		stats->tx_abort = __le32_to_cpu(ps->wal.tx.tx_abort);
+		stats->mpdus_requed = __le32_to_cpu(ps->wal.tx.mpdus_requed);
+		stats->tx_ko = __le32_to_cpu(ps->wal.tx.tx_ko);
+		stats->data_rc = __le32_to_cpu(ps->wal.tx.data_rc);
+		stats->self_triggers = __le32_to_cpu(ps->wal.tx.self_triggers);
+		stats->sw_retry_failure =
+			__le32_to_cpu(ps->wal.tx.sw_retry_failure);
+		stats->illgl_rate_phy_err =
+			__le32_to_cpu(ps->wal.tx.illgl_rate_phy_err);
+		stats->pdev_cont_xretry =
+			__le32_to_cpu(ps->wal.tx.pdev_cont_xretry);
+		stats->pdev_tx_timeout =
+			__le32_to_cpu(ps->wal.tx.pdev_tx_timeout);
+		stats->pdev_resets = __le32_to_cpu(ps->wal.tx.pdev_resets);
+		stats->phy_underrun = __le32_to_cpu(ps->wal.tx.phy_underrun);
+		stats->txop_ovf = __le32_to_cpu(ps->wal.tx.txop_ovf);
+
+		stats->mid_ppdu_route_change =
+			__le32_to_cpu(ps->wal.rx.mid_ppdu_route_change);
+		stats->status_rcvd = __le32_to_cpu(ps->wal.rx.status_rcvd);
+		stats->r0_frags = __le32_to_cpu(ps->wal.rx.r0_frags);
+		stats->r1_frags = __le32_to_cpu(ps->wal.rx.r1_frags);
+		stats->r2_frags = __le32_to_cpu(ps->wal.rx.r2_frags);
+		stats->r3_frags = __le32_to_cpu(ps->wal.rx.r3_frags);
+		stats->htt_msdus = __le32_to_cpu(ps->wal.rx.htt_msdus);
+		stats->htt_mpdus = __le32_to_cpu(ps->wal.rx.htt_mpdus);
+		stats->loc_msdus = __le32_to_cpu(ps->wal.rx.loc_msdus);
+		stats->loc_mpdus = __le32_to_cpu(ps->wal.rx.loc_mpdus);
+		stats->oversize_amsdu =
+			__le32_to_cpu(ps->wal.rx.oversize_amsdu);
+		stats->phy_errs = __le32_to_cpu(ps->wal.rx.phy_errs);
+		stats->phy_err_drop = __le32_to_cpu(ps->wal.rx.phy_err_drop);
+		stats->mpdu_errs = __le32_to_cpu(ps->wal.rx.mpdu_errs);
+
+		tmp += sizeof(struct wmi_pdev_stats);
+	}
+
+	/* 0 or max vdevs */
+	/* Currently firmware does not support VDEV stats */
+	if (num_vdev_stats) {
+		struct wmi_vdev_stats *vdev_stats;
+
+		for (i = 0; i < num_vdev_stats; i++) {
+			vdev_stats = (struct wmi_vdev_stats *)tmp;
+			tmp += sizeof(struct wmi_vdev_stats);
+		}
+	}
+
+	if (num_peer_stats) {
+		struct wmi_peer_stats *peer_stats;
+		struct ath10k_peer_stat *s;
+
+		stats->peers = num_peer_stats;
+
+		for (i = 0; i < num_peer_stats; i++) {
+			peer_stats = (struct wmi_peer_stats *)tmp;
+			s = &stats->peer_stat[i];
+
+			WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_stats->peer_macaddr,
+						   s->peer_macaddr);
+			s->peer_rssi = __le32_to_cpu(peer_stats->peer_rssi);
+			s->peer_tx_rate =
+				__le32_to_cpu(peer_stats->peer_tx_rate);
+
+			tmp += sizeof(struct wmi_peer_stats);
+		}
+	}
+
+	mutex_unlock(&ar->conf_mutex);
+	complete(&ar->debug.event_stats_compl);
+}
+
+static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
+				    size_t count, loff_t *ppos)
+{
+	struct ath10k *ar = file->private_data;
+	struct ath10k_target_stats *fw_stats;
+	char *buf;
+	unsigned int len = 0, buf_len = 2500;
+	ssize_t ret_cnt;
+	long left;
+	int i;
+	int ret;
+
+	fw_stats = &ar->debug.target_stats;
+
+	buf = kzalloc(buf_len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT);
+	if (ret) {
+		ath10k_warn("could not request stats (%d)\n", ret);
+		kfree(buf);
+		return -EIO;
+	}
+
+	left = wait_for_completion_timeout(&ar->debug.event_stats_compl, 1*HZ);
+
+	if (left <= 0) {
+		kfree(buf);
+		return -ETIMEDOUT;
+	}
+
+	mutex_lock(&ar->conf_mutex);
+
+	len += scnprintf(buf + len, buf_len - len, "\n");
+	len += scnprintf(buf + len, buf_len - len, "%30s\n",
+			 "ath10k PDEV stats");
+	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+				 "=================");
+
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Channel noise floor", fw_stats->ch_noise_floor);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+			 "Channel TX power", fw_stats->chan_tx_power);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+			 "TX frame count", fw_stats->tx_frame_count);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+			 "RX frame count", fw_stats->rx_frame_count);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+			 "RX clear count", fw_stats->rx_clear_count);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+			 "Cycle count", fw_stats->cycle_count);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+			 "PHY error count", fw_stats->phy_err_count);
+
+	len += scnprintf(buf + len, buf_len - len, "\n");
+	len += scnprintf(buf + len, buf_len - len, "%30s\n",
+			 "ath10k PDEV TX stats");
+	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+				 "=================");
+
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "HTT cookies queued", fw_stats->comp_queued);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "HTT cookies disp.", fw_stats->comp_delivered);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MSDU queued", fw_stats->msdu_enqued);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MPDU queued", fw_stats->mpdu_enqued);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MSDUs dropped", fw_stats->wmm_drop);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Local enqued", fw_stats->local_enqued);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Local freed", fw_stats->local_freed);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "HW queued", fw_stats->hw_queued);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "PPDUs reaped", fw_stats->hw_reaped);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Num underruns", fw_stats->underrun);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "PPDUs cleaned", fw_stats->tx_abort);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MPDUs requed", fw_stats->mpdus_requed);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Excessive retries", fw_stats->tx_ko);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "HW rate", fw_stats->data_rc);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Sched self tiggers", fw_stats->self_triggers);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Dropped due to SW retries",
+			 fw_stats->sw_retry_failure);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Illegal rate phy errors",
+			 fw_stats->illgl_rate_phy_err);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Pdev continous xretry", fw_stats->pdev_cont_xretry);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "TX timeout", fw_stats->pdev_tx_timeout);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "PDEV resets", fw_stats->pdev_resets);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "PHY underrun", fw_stats->phy_underrun);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MPDU is more than txop limit", fw_stats->txop_ovf);
+
+	len += scnprintf(buf + len, buf_len - len, "\n");
+	len += scnprintf(buf + len, buf_len - len, "%30s\n",
+			 "ath10k PDEV RX stats");
+	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+				 "=================");
+
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Mid PPDU route change",
+			 fw_stats->mid_ppdu_route_change);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Tot. number of statuses", fw_stats->status_rcvd);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Extra frags on rings 0", fw_stats->r0_frags);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Extra frags on rings 1", fw_stats->r1_frags);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Extra frags on rings 2", fw_stats->r2_frags);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Extra frags on rings 3", fw_stats->r3_frags);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MSDUs delivered to HTT", fw_stats->htt_msdus);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MPDUs delivered to HTT", fw_stats->htt_mpdus);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MSDUs delivered to stack", fw_stats->loc_msdus);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MPDUs delivered to stack", fw_stats->loc_mpdus);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "Oversized AMSUs", fw_stats->oversize_amsdu);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "PHY errors", fw_stats->phy_errs);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "PHY errors drops", fw_stats->phy_err_drop);
+	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
+			 "MPDU errors (FCS, MIC, ENC)", fw_stats->mpdu_errs);
+
+	len += scnprintf(buf + len, buf_len - len, "\n");
+	len += scnprintf(buf + len, buf_len - len, "%30s\n",
+			 "ath10k PEER stats");
+	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+				 "=================");
+
+	for (i = 0; i < fw_stats->peers; i++) {
+		len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
+				 "Peer MAC address",
+				 fw_stats->peer_stat[i].peer_macaddr);
+		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+				 "Peer RSSI", fw_stats->peer_stat[i].peer_rssi);
+		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+				 "Peer TX rate",
+				 fw_stats->peer_stat[i].peer_tx_rate);
+		len += scnprintf(buf + len, buf_len - len, "\n");
+	}
+
+	if (len > buf_len)
+		len = buf_len;
+
+	ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+
+	mutex_unlock(&ar->conf_mutex);
+
+	kfree(buf);
+	return ret_cnt;
+}
+
+static const struct file_operations fops_fw_stats = {
+	.read = ath10k_read_fw_stats,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+int ath10k_debug_create(struct ath10k *ar)
+{
+	ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
+						   ar->hw->wiphy->debugfsdir);
+
+	if (!ar->debug.debugfs_phy)
+		return -ENOMEM;
+
+	init_completion(&ar->debug.event_stats_compl);
+
+	debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar,
+			    &fops_fw_stats);
+
+	debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar,
+			    &fops_wmi_services);
+
+	return 0;
+}
+#endif /* CONFIG_ATH10K_DEBUGFS */
+
+#ifdef CONFIG_ATH10K_DEBUG
+void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+
+	va_start(args, fmt);
+
+	vaf.fmt = fmt;
+	vaf.va = &args;
+
+	if (ath10k_debug_mask & mask)
+		ath10k_printk(KERN_DEBUG, "%pV", &vaf);
+
+	trace_ath10k_log_dbg(mask, &vaf);
+
+	va_end(args);
+}
+EXPORT_SYMBOL(ath10k_dbg);
+
+void ath10k_dbg_dump(enum ath10k_debug_mask mask,
+		     const char *msg, const char *prefix,
+		     const void *buf, size_t len)
+{
+	if (ath10k_debug_mask & mask) {
+		if (msg)
+			ath10k_dbg(mask, "%s\n", msg);
+
+		print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
+	}
+
+	/* tracing code doesn't like null strings :/ */
+	trace_ath10k_log_dbg_dump(msg ? msg : "", prefix ? prefix : "",
+				  buf, len);
+}
+EXPORT_SYMBOL(ath10k_dbg_dump);
+
+#endif /* CONFIG_ATH10K_DEBUG */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/debug.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/debug.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/debug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/debug.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+#include <linux/types.h>
+#include "trace.h"
+
+enum ath10k_debug_mask {
+	ATH10K_DBG_PCI		= 0x00000001,
+	ATH10K_DBG_WMI		= 0x00000002,
+	ATH10K_DBG_HTC		= 0x00000004,
+	ATH10K_DBG_HTT		= 0x00000008,
+	ATH10K_DBG_MAC		= 0x00000010,
+	ATH10K_DBG_CORE		= 0x00000020,
+	ATH10K_DBG_PCI_DUMP	= 0x00000040,
+	ATH10K_DBG_HTT_DUMP	= 0x00000080,
+	ATH10K_DBG_MGMT		= 0x00000100,
+	ATH10K_DBG_DATA		= 0x00000200,
+	ATH10K_DBG_ANY		= 0xffffffff,
+};
+
+extern unsigned int ath10k_debug_mask;
+
+extern __printf(1, 2) int ath10k_info(const char *fmt, ...);
+extern __printf(1, 2) int ath10k_err(const char *fmt, ...);
+extern __printf(1, 2) int ath10k_warn(const char *fmt, ...);
+
+#ifdef CONFIG_ATH10K_DEBUGFS
+int ath10k_debug_create(struct ath10k *ar);
+void ath10k_debug_read_service_map(struct ath10k *ar,
+				   void *service_map,
+				   size_t map_size);
+void ath10k_debug_read_target_stats(struct ath10k *ar,
+				    struct wmi_stats_event *ev);
+
+#else
+static inline int ath10k_debug_create(struct ath10k *ar)
+{
+	return 0;
+}
+
+static inline void ath10k_debug_read_service_map(struct ath10k *ar,
+						 void *service_map,
+						 size_t map_size)
+{
+}
+
+static inline void ath10k_debug_read_target_stats(struct ath10k *ar,
+						  struct wmi_stats_event *ev)
+{
+}
+#endif /* CONFIG_ATH10K_DEBUGFS */
+
+#ifdef CONFIG_ATH10K_DEBUG
+extern __printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask,
+				      const char *fmt, ...);
+void ath10k_dbg_dump(enum ath10k_debug_mask mask,
+		     const char *msg, const char *prefix,
+		     const void *buf, size_t len);
+#else /* CONFIG_ATH10K_DEBUG */
+
+static inline int ath10k_dbg(enum ath10k_debug_mask dbg_mask,
+			     const char *fmt, ...)
+{
+	return 0;
+}
+
+static inline void ath10k_dbg_dump(enum ath10k_debug_mask mask,
+				   const char *msg, const char *prefix,
+				   const void *buf, size_t len)
+{
+}
+#endif /* CONFIG_ATH10K_DEBUG */
+#endif /* _DEBUG_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/hif.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/hif.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/hif.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/hif.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HIF_H_
+#define _HIF_H_
+
+#include <linux/kernel.h>
+#include "core.h"
+
+struct ath10k_hif_cb {
+	int (*tx_completion)(struct ath10k *ar,
+			     struct sk_buff *wbuf,
+			     unsigned transfer_id);
+	int (*rx_completion)(struct ath10k *ar,
+			     struct sk_buff *wbuf,
+			     u8 pipe_id);
+};
+
+struct ath10k_hif_ops {
+	/* Send the head of a buffer to HIF for transmission to the target. */
+	int (*send_head)(struct ath10k *ar, u8 pipe_id,
+			 unsigned int transfer_id,
+			 unsigned int nbytes,
+			 struct sk_buff *buf);
+
+	/*
+	 * API to handle HIF-specific BMI message exchanges, this API is
+	 * synchronous and only allowed to be called from a context that
+	 * can block (sleep)
+	 */
+	int (*exchange_bmi_msg)(struct ath10k *ar,
+				void *request, u32 request_len,
+				void *response, u32 *response_len);
+
+	int (*start)(struct ath10k *ar);
+
+	void (*stop)(struct ath10k *ar);
+
+	int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id,
+				   u8 *ul_pipe, u8 *dl_pipe,
+				   int *ul_is_polled, int *dl_is_polled);
+
+	void (*get_default_pipe)(struct ath10k *ar, u8 *ul_pipe, u8 *dl_pipe);
+
+	/*
+	 * Check if prior sends have completed.
+	 *
+	 * Check whether the pipe in question has any completed
+	 * sends that have not yet been processed.
+	 * This function is only relevant for HIF pipes that are configured
+	 * to be polled rather than interrupt-driven.
+	 */
+	void (*send_complete_check)(struct ath10k *ar, u8 pipe_id, int force);
+
+	void (*init)(struct ath10k *ar,
+		     struct ath10k_hif_cb *callbacks);
+
+	u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id);
+};
+
+
+static inline int ath10k_hif_send_head(struct ath10k *ar, u8 pipe_id,
+				       unsigned int transfer_id,
+				       unsigned int nbytes,
+				       struct sk_buff *buf)
+{
+	return ar->hif.ops->send_head(ar, pipe_id, transfer_id, nbytes, buf);
+}
+
+static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar,
+					      void *request, u32 request_len,
+					      void *response, u32 *response_len)
+{
+	return ar->hif.ops->exchange_bmi_msg(ar, request, request_len,
+					     response, response_len);
+}
+
+static inline int ath10k_hif_start(struct ath10k *ar)
+{
+	return ar->hif.ops->start(ar);
+}
+
+static inline void ath10k_hif_stop(struct ath10k *ar)
+{
+	return ar->hif.ops->stop(ar);
+}
+
+static inline int ath10k_hif_map_service_to_pipe(struct ath10k *ar,
+						 u16 service_id,
+						 u8 *ul_pipe, u8 *dl_pipe,
+						 int *ul_is_polled,
+						 int *dl_is_polled)
+{
+	return ar->hif.ops->map_service_to_pipe(ar, service_id,
+						ul_pipe, dl_pipe,
+						ul_is_polled, dl_is_polled);
+}
+
+static inline void ath10k_hif_get_default_pipe(struct ath10k *ar,
+					       u8 *ul_pipe, u8 *dl_pipe)
+{
+	ar->hif.ops->get_default_pipe(ar, ul_pipe, dl_pipe);
+}
+
+static inline void ath10k_hif_send_complete_check(struct ath10k *ar,
+						  u8 pipe_id, int force)
+{
+	ar->hif.ops->send_complete_check(ar, pipe_id, force);
+}
+
+static inline void ath10k_hif_init(struct ath10k *ar,
+				   struct ath10k_hif_cb *callbacks)
+{
+	ar->hif.ops->init(ar, callbacks);
+}
+
+static inline u16 ath10k_hif_get_free_queue_number(struct ath10k *ar,
+						   u8 pipe_id)
+{
+	return ar->hif.ops->get_free_queue_number(ar, pipe_id);
+}
+
+#endif /* _HIF_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htc.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htc.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1000 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "core.h"
+#include "hif.h"
+#include "debug.h"
+
+/********/
+/* Send */
+/********/
+
+static inline void ath10k_htc_send_complete_check(struct ath10k_htc_ep *ep,
+						  int force)
+{
+	/*
+	 * Check whether HIF has any prior sends that have finished,
+	 * have not had the post-processing done.
+	 */
+	ath10k_hif_send_complete_check(ep->htc->ar, ep->ul_pipe_id, force);
+}
+
+static void ath10k_htc_control_tx_complete(struct ath10k *ar,
+					   struct sk_buff *skb)
+{
+	kfree_skb(skb);
+}
+
+static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
+{
+	struct sk_buff *skb;
+	struct ath10k_skb_cb *skb_cb;
+
+	skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE);
+	if (!skb) {
+		ath10k_warn("Unable to allocate ctrl skb\n");
+		return NULL;
+	}
+
+	skb_reserve(skb, 20); /* FIXME: why 20 bytes? */
+	WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
+
+	skb_cb = ATH10K_SKB_CB(skb);
+	memset(skb_cb, 0, sizeof(*skb_cb));
+
+	ath10k_dbg(ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb);
+	return skb;
+}
+
+static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
+					     struct sk_buff *skb)
+{
+	ath10k_skb_unmap(htc->ar->dev, skb);
+	skb_pull(skb, sizeof(struct ath10k_htc_hdr));
+}
+
+static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
+					    struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__,
+		   ep->eid, skb);
+
+	ath10k_htc_restore_tx_skb(ep->htc, skb);
+
+	if (!ep->ep_ops.ep_tx_complete) {
+		ath10k_warn("no tx handler for eid %d\n", ep->eid);
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
+	ep->ep_ops.ep_tx_complete(ep->htc->ar, skb);
+}
+
+/* assumes tx_lock is held */
+static bool ath10k_htc_ep_need_credit_update(struct ath10k_htc_ep *ep)
+{
+	if (!ep->tx_credit_flow_enabled)
+		return false;
+	if (ep->tx_credits >= ep->tx_credits_per_max_message)
+		return false;
+
+	ath10k_dbg(ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n",
+		   ep->eid);
+	return true;
+}
+
+static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
+				      struct sk_buff *skb)
+{
+	struct ath10k_htc_hdr *hdr;
+
+	hdr = (struct ath10k_htc_hdr *)skb->data;
+	memset(hdr, 0, sizeof(*hdr));
+
+	hdr->eid = ep->eid;
+	hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr));
+
+	spin_lock_bh(&ep->htc->tx_lock);
+	hdr->seq_no = ep->seq_no++;
+
+	if (ath10k_htc_ep_need_credit_update(ep))
+		hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
+
+	spin_unlock_bh(&ep->htc->tx_lock);
+}
+
+static int ath10k_htc_issue_skb(struct ath10k_htc *htc,
+				struct ath10k_htc_ep *ep,
+				struct sk_buff *skb,
+				u8 credits)
+{
+	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
+	int ret;
+
+	ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__,
+		   ep->eid, skb);
+
+	ath10k_htc_prepare_tx_skb(ep, skb);
+
+	ret = ath10k_skb_map(htc->ar->dev, skb);
+	if (ret)
+		goto err;
+
+	ret = ath10k_hif_send_head(htc->ar,
+				   ep->ul_pipe_id,
+				   ep->eid,
+				   skb->len,
+				   skb);
+	if (unlikely(ret))
+		goto err;
+
+	return 0;
+err:
+	ath10k_warn("HTC issue failed: %d\n", ret);
+
+	spin_lock_bh(&htc->tx_lock);
+	ep->tx_credits += credits;
+	spin_unlock_bh(&htc->tx_lock);
+
+	/* this is the simplest way to handle out-of-resources for non-credit
+	 * based endpoints. credit based endpoints can still get -ENOSR, but
+	 * this is highly unlikely as credit reservation should prevent that */
+	if (ret == -ENOSR) {
+		spin_lock_bh(&htc->tx_lock);
+		__skb_queue_head(&ep->tx_queue, skb);
+		spin_unlock_bh(&htc->tx_lock);
+
+		return ret;
+	}
+
+	skb_cb->is_aborted = true;
+	ath10k_htc_notify_tx_completion(ep, skb);
+
+	return ret;
+}
+
+static struct sk_buff *ath10k_htc_get_skb_credit_based(struct ath10k_htc *htc,
+						       struct ath10k_htc_ep *ep,
+						       u8 *credits)
+{
+	struct sk_buff *skb;
+	struct ath10k_skb_cb *skb_cb;
+	int credits_required;
+	int remainder;
+	unsigned int transfer_len;
+
+	lockdep_assert_held(&htc->tx_lock);
+
+	skb = __skb_dequeue(&ep->tx_queue);
+	if (!skb)
+		return NULL;
+
+	skb_cb = ATH10K_SKB_CB(skb);
+	transfer_len = skb->len;
+
+	if (likely(transfer_len <= htc->target_credit_size)) {
+		credits_required = 1;
+	} else {
+		/* figure out how many credits this message requires */
+		credits_required = transfer_len / htc->target_credit_size;
+		remainder = transfer_len % htc->target_credit_size;
+
+		if (remainder)
+			credits_required++;
+	}
+
+	ath10k_dbg(ATH10K_DBG_HTC, "Credits required %d got %d\n",
+		   credits_required, ep->tx_credits);
+
+	if (ep->tx_credits < credits_required) {
+		__skb_queue_head(&ep->tx_queue, skb);
+		return NULL;
+	}
+
+	ep->tx_credits -= credits_required;
+	*credits = credits_required;
+	return skb;
+}
+
+static void ath10k_htc_send_work(struct work_struct *work)
+{
+	struct ath10k_htc_ep *ep = container_of(work,
+					struct ath10k_htc_ep, send_work);
+	struct ath10k_htc *htc = ep->htc;
+	struct sk_buff *skb;
+	u8 credits = 0;
+	int ret;
+
+	while (true) {
+		if (ep->ul_is_polled)
+			ath10k_htc_send_complete_check(ep, 0);
+
+		spin_lock_bh(&htc->tx_lock);
+		if (ep->tx_credit_flow_enabled)
+			skb = ath10k_htc_get_skb_credit_based(htc, ep,
+							      &credits);
+		else
+			skb = __skb_dequeue(&ep->tx_queue);
+		spin_unlock_bh(&htc->tx_lock);
+
+		if (!skb)
+			break;
+
+		ret = ath10k_htc_issue_skb(htc, ep, skb, credits);
+		if (ret == -ENOSR)
+			break;
+	}
+}
+
+int ath10k_htc_send(struct ath10k_htc *htc,
+		    enum ath10k_htc_ep_id eid,
+		    struct sk_buff *skb)
+{
+	struct ath10k_htc_ep *ep = &htc->endpoint[eid];
+
+	if (eid >= ATH10K_HTC_EP_COUNT) {
+		ath10k_warn("Invalid endpoint id: %d\n", eid);
+		return -ENOENT;
+	}
+
+	skb_push(skb, sizeof(struct ath10k_htc_hdr));
+
+	spin_lock_bh(&htc->tx_lock);
+	__skb_queue_tail(&ep->tx_queue, skb);
+	spin_unlock_bh(&htc->tx_lock);
+
+	queue_work(htc->ar->workqueue, &ep->send_work);
+	return 0;
+}
+
+static int ath10k_htc_tx_completion_handler(struct ath10k *ar,
+					    struct sk_buff *skb,
+					    unsigned int eid)
+{
+	struct ath10k_htc *htc = ar->htc;
+	struct ath10k_htc_ep *ep = &htc->endpoint[eid];
+	bool stopping;
+
+	ath10k_htc_notify_tx_completion(ep, skb);
+	/* the skb now belongs to the completion handler */
+
+	spin_lock_bh(&htc->tx_lock);
+	stopping = htc->stopping;
+	spin_unlock_bh(&htc->tx_lock);
+
+	if (!ep->tx_credit_flow_enabled && !stopping)
+		/*
+		 * note: when using TX credit flow, the re-checking of
+		 * queues happens when credits flow back from the target.
+		 * in the non-TX credit case, we recheck after the packet
+		 * completes
+		 */
+		queue_work(ar->workqueue, &ep->send_work);
+
+	return 0;
+}
+
+/* flush endpoint TX queue */
+static void ath10k_htc_flush_endpoint_tx(struct ath10k_htc *htc,
+					 struct ath10k_htc_ep *ep)
+{
+	struct sk_buff *skb;
+	struct ath10k_skb_cb *skb_cb;
+
+	spin_lock_bh(&htc->tx_lock);
+	for (;;) {
+		skb = __skb_dequeue(&ep->tx_queue);
+		if (!skb)
+			break;
+
+		skb_cb = ATH10K_SKB_CB(skb);
+		skb_cb->is_aborted = true;
+		ath10k_htc_notify_tx_completion(ep, skb);
+	}
+	spin_unlock_bh(&htc->tx_lock);
+
+	cancel_work_sync(&ep->send_work);
+}
+
+/***********/
+/* Receive */
+/***********/
+
+static void
+ath10k_htc_process_credit_report(struct ath10k_htc *htc,
+				 const struct ath10k_htc_credit_report *report,
+				 int len,
+				 enum ath10k_htc_ep_id eid)
+{
+	struct ath10k_htc_ep *ep;
+	int i, n_reports;
+
+	if (len % sizeof(*report))
+		ath10k_warn("Uneven credit report len %d", len);
+
+	n_reports = len / sizeof(*report);
+
+	spin_lock_bh(&htc->tx_lock);
+	for (i = 0; i < n_reports; i++, report++) {
+		if (report->eid >= ATH10K_HTC_EP_COUNT)
+			break;
+
+		ath10k_dbg(ATH10K_DBG_HTC, "ep %d got %d credits\n",
+			   report->eid, report->credits);
+
+		ep = &htc->endpoint[report->eid];
+		ep->tx_credits += report->credits;
+
+		if (ep->tx_credits && !skb_queue_empty(&ep->tx_queue))
+			queue_work(htc->ar->workqueue, &ep->send_work);
+	}
+	spin_unlock_bh(&htc->tx_lock);
+}
+
+static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
+				      u8 *buffer,
+				      int length,
+				      enum ath10k_htc_ep_id src_eid)
+{
+	int status = 0;
+	struct ath10k_htc_record *record;
+	u8 *orig_buffer;
+	int orig_length;
+	size_t len;
+
+	orig_buffer = buffer;
+	orig_length = length;
+
+	while (length > 0) {
+		record = (struct ath10k_htc_record *)buffer;
+
+		if (length < sizeof(record->hdr)) {
+			status = -EINVAL;
+			break;
+		}
+
+		if (record->hdr.len > length) {
+			/* no room left in buffer for record */
+			ath10k_warn("Invalid record length: %d\n",
+				    record->hdr.len);
+			status = -EINVAL;
+			break;
+		}
+
+		switch (record->hdr.id) {
+		case ATH10K_HTC_RECORD_CREDITS:
+			len = sizeof(struct ath10k_htc_credit_report);
+			if (record->hdr.len < len) {
+				ath10k_warn("Credit report too long\n");
+				status = -EINVAL;
+				break;
+			}
+			ath10k_htc_process_credit_report(htc,
+							 record->credit_report,
+							 record->hdr.len,
+							 src_eid);
+			break;
+		default:
+			ath10k_warn("Unhandled record: id:%d length:%d\n",
+				    record->hdr.id, record->hdr.len);
+			break;
+		}
+
+		if (status)
+			break;
+
+		/* multiple records may be present in a trailer */
+		buffer += sizeof(record->hdr) + record->hdr.len;
+		length -= sizeof(record->hdr) + record->hdr.len;
+	}
+
+	if (status)
+		ath10k_dbg_dump(ATH10K_DBG_HTC, "htc rx bad trailer", "",
+				orig_buffer, orig_length);
+
+	return status;
+}
+
+static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
+					    struct sk_buff *skb,
+					    u8 pipe_id)
+{
+	int status = 0;
+	struct ath10k_htc *htc = ar->htc;
+	struct ath10k_htc_hdr *hdr;
+	struct ath10k_htc_ep *ep;
+	u16 payload_len;
+	u32 trailer_len = 0;
+	size_t min_len;
+	u8 eid;
+	bool trailer_present;
+
+	hdr = (struct ath10k_htc_hdr *)skb->data;
+	skb_pull(skb, sizeof(*hdr));
+
+	eid = hdr->eid;
+
+	if (eid >= ATH10K_HTC_EP_COUNT) {
+		ath10k_warn("HTC Rx: invalid eid %d\n", eid);
+		ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad header", "",
+				hdr, sizeof(*hdr));
+		status = -EINVAL;
+		goto out;
+	}
+
+	ep = &htc->endpoint[eid];
+
+	/*
+	 * If this endpoint that received a message from the target has
+	 * a to-target HIF pipe whose send completions are polled rather
+	 * than interrupt-driven, this is a good point to ask HIF to check
+	 * whether it has any completed sends to handle.
+	 */
+	if (ep->ul_is_polled)
+		ath10k_htc_send_complete_check(ep, 1);
+
+	payload_len = __le16_to_cpu(hdr->len);
+
+	if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) {
+		ath10k_warn("HTC rx frame too long, len: %zu\n",
+			    payload_len + sizeof(*hdr));
+		ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", "",
+				hdr, sizeof(*hdr));
+		status = -EINVAL;
+		goto out;
+	}
+
+	if (skb->len < payload_len) {
+		ath10k_dbg(ATH10K_DBG_HTC,
+			   "HTC Rx: insufficient length, got %d, expected %d\n",
+			   skb->len, payload_len);
+		ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len",
+				"", hdr, sizeof(*hdr));
+		status = -EINVAL;
+		goto out;
+	}
+
+	/* get flags to check for trailer */
+	trailer_present = hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
+	if (trailer_present) {
+		u8 *trailer;
+
+		trailer_len = hdr->trailer_len;
+		min_len = sizeof(struct ath10k_ath10k_htc_record_hdr);
+
+		if ((trailer_len < min_len) ||
+		    (trailer_len > payload_len)) {
+			ath10k_warn("Invalid trailer length: %d\n",
+				    trailer_len);
+			status = -EPROTO;
+			goto out;
+		}
+
+		trailer = (u8 *)hdr;
+		trailer += sizeof(*hdr);
+		trailer += payload_len;
+		trailer -= trailer_len;
+		status = ath10k_htc_process_trailer(htc, trailer,
+						    trailer_len, hdr->eid);
+		if (status)
+			goto out;
+
+		skb_trim(skb, skb->len - trailer_len);
+	}
+
+	if (((int)payload_len - (int)trailer_len) <= 0)
+		/* zero length packet with trailer data, just drop these */
+		goto out;
+
+	if (eid == ATH10K_HTC_EP_0) {
+		struct ath10k_htc_msg *msg = (struct ath10k_htc_msg *)skb->data;
+
+		switch (__le16_to_cpu(msg->hdr.message_id)) {
+		default:
+			/* handle HTC control message */
+			if (completion_done(&htc->ctl_resp)) {
+				/*
+				 * this is a fatal error, target should not be
+				 * sending unsolicited messages on the ep 0
+				 */
+				ath10k_warn("HTC rx ctrl still processing\n");
+				status = -EINVAL;
+				complete(&htc->ctl_resp);
+				goto out;
+			}
+
+			htc->control_resp_len =
+				min_t(int, skb->len,
+				      ATH10K_HTC_MAX_CTRL_MSG_LEN);
+
+			memcpy(htc->control_resp_buffer, skb->data,
+			       htc->control_resp_len);
+
+			complete(&htc->ctl_resp);
+			break;
+		case ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE:
+			htc->htc_ops.target_send_suspend_complete(ar);
+		}
+		goto out;
+	}
+
+	ath10k_dbg(ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n",
+		   eid, skb);
+	ep->ep_ops.ep_rx_complete(ar, skb);
+
+	/* skb is now owned by the rx completion handler */
+	skb = NULL;
+out:
+	kfree_skb(skb);
+
+	return status;
+}
+
+static void ath10k_htc_control_rx_complete(struct ath10k *ar,
+					   struct sk_buff *skb)
+{
+	/* This is unexpected. FW is not supposed to send regular rx on this
+	 * endpoint. */
+	ath10k_warn("unexpected htc rx\n");
+	kfree_skb(skb);
+}
+
+/***************/
+/* Init/Deinit */
+/***************/
+
+static const char *htc_service_name(enum ath10k_htc_svc_id id)
+{
+	switch (id) {
+	case ATH10K_HTC_SVC_ID_RESERVED:
+		return "Reserved";
+	case ATH10K_HTC_SVC_ID_RSVD_CTRL:
+		return "Control";
+	case ATH10K_HTC_SVC_ID_WMI_CONTROL:
+		return "WMI";
+	case ATH10K_HTC_SVC_ID_WMI_DATA_BE:
+		return "DATA BE";
+	case ATH10K_HTC_SVC_ID_WMI_DATA_BK:
+		return "DATA BK";
+	case ATH10K_HTC_SVC_ID_WMI_DATA_VI:
+		return "DATA VI";
+	case ATH10K_HTC_SVC_ID_WMI_DATA_VO:
+		return "DATA VO";
+	case ATH10K_HTC_SVC_ID_NMI_CONTROL:
+		return "NMI Control";
+	case ATH10K_HTC_SVC_ID_NMI_DATA:
+		return "NMI Data";
+	case ATH10K_HTC_SVC_ID_HTT_DATA_MSG:
+		return "HTT Data";
+	case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS:
+		return "RAW";
+	}
+
+	return "Unknown";
+}
+
+static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc)
+{
+	struct ath10k_htc_ep *ep;
+	int i;
+
+	for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) {
+		ep = &htc->endpoint[i];
+		ep->service_id = ATH10K_HTC_SVC_ID_UNUSED;
+		ep->max_ep_message_len = 0;
+		ep->max_tx_queue_depth = 0;
+		ep->eid = i;
+		skb_queue_head_init(&ep->tx_queue);
+		ep->htc = htc;
+		ep->tx_credit_flow_enabled = true;
+		INIT_WORK(&ep->send_work, ath10k_htc_send_work);
+	}
+}
+
+static void ath10k_htc_setup_target_buffer_assignments(struct ath10k_htc *htc)
+{
+	struct ath10k_htc_svc_tx_credits *entry;
+
+	entry = &htc->service_tx_alloc[0];
+
+	/*
+	 * for PCIE allocate all credists/HTC buffers to WMI.
+	 * no buffers are used/required for data. data always
+	 * remains on host.
+	 */
+	entry++;
+	entry->service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL;
+	entry->credit_allocation = htc->total_transmit_credits;
+}
+
+static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
+					   u16 service_id)
+{
+	u8 allocation = 0;
+	int i;
+
+	for (i = 0; i < ATH10K_HTC_EP_COUNT; i++) {
+		if (htc->service_tx_alloc[i].service_id == service_id)
+			allocation =
+			    htc->service_tx_alloc[i].credit_allocation;
+	}
+
+	return allocation;
+}
+
+int ath10k_htc_wait_target(struct ath10k_htc *htc)
+{
+	int status = 0;
+	struct ath10k_htc_svc_conn_req conn_req;
+	struct ath10k_htc_svc_conn_resp conn_resp;
+	struct ath10k_htc_msg *msg;
+	u16 message_id;
+	u16 credit_count;
+	u16 credit_size;
+
+	INIT_COMPLETION(htc->ctl_resp);
+
+	status = ath10k_hif_start(htc->ar);
+	if (status) {
+		ath10k_err("could not start HIF (%d)\n", status);
+		goto err_start;
+	}
+
+	status = wait_for_completion_timeout(&htc->ctl_resp,
+					     ATH10K_HTC_WAIT_TIMEOUT_HZ);
+	if (status <= 0) {
+		if (status == 0)
+			status = -ETIMEDOUT;
+
+		ath10k_err("ctl_resp never came in (%d)\n", status);
+		goto err_target;
+	}
+
+	if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) {
+		ath10k_err("Invalid HTC ready msg len:%d\n",
+			   htc->control_resp_len);
+
+		status = -ECOMM;
+		goto err_target;
+	}
+
+	msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
+	message_id   = __le16_to_cpu(msg->hdr.message_id);
+	credit_count = __le16_to_cpu(msg->ready.credit_count);
+	credit_size  = __le16_to_cpu(msg->ready.credit_size);
+
+	if (message_id != ATH10K_HTC_MSG_READY_ID) {
+		ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id);
+		status = -ECOMM;
+		goto err_target;
+	}
+
+	htc->total_transmit_credits = credit_count;
+	htc->target_credit_size = credit_size;
+
+	ath10k_dbg(ATH10K_DBG_HTC,
+		   "Target ready! transmit resources: %d size:%d\n",
+		   htc->total_transmit_credits,
+		   htc->target_credit_size);
+
+	if ((htc->total_transmit_credits == 0) ||
+	    (htc->target_credit_size == 0)) {
+		status = -ECOMM;
+		ath10k_err("Invalid credit size received\n");
+		goto err_target;
+	}
+
+	ath10k_htc_setup_target_buffer_assignments(htc);
+
+	/* setup our pseudo HTC control endpoint connection */
+	memset(&conn_req, 0, sizeof(conn_req));
+	memset(&conn_resp, 0, sizeof(conn_resp));
+	conn_req.ep_ops.ep_tx_complete = ath10k_htc_control_tx_complete;
+	conn_req.ep_ops.ep_rx_complete = ath10k_htc_control_rx_complete;
+	conn_req.max_send_queue_depth = ATH10K_NUM_CONTROL_TX_BUFFERS;
+	conn_req.service_id = ATH10K_HTC_SVC_ID_RSVD_CTRL;
+
+	/* connect fake service */
+	status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp);
+	if (status) {
+		ath10k_err("could not connect to htc service (%d)\n", status);
+		goto err_target;
+	}
+
+	return 0;
+err_target:
+	ath10k_hif_stop(htc->ar);
+err_start:
+	return status;
+}
+
+int ath10k_htc_connect_service(struct ath10k_htc *htc,
+			       struct ath10k_htc_svc_conn_req *conn_req,
+			       struct ath10k_htc_svc_conn_resp *conn_resp)
+{
+	struct ath10k_htc_msg *msg;
+	struct ath10k_htc_conn_svc *req_msg;
+	struct ath10k_htc_conn_svc_response resp_msg_dummy;
+	struct ath10k_htc_conn_svc_response *resp_msg = &resp_msg_dummy;
+	enum ath10k_htc_ep_id assigned_eid = ATH10K_HTC_EP_COUNT;
+	struct ath10k_htc_ep *ep;
+	struct sk_buff *skb;
+	unsigned int max_msg_size = 0;
+	int length, status;
+	bool disable_credit_flow_ctrl = false;
+	u16 message_id, service_id, flags = 0;
+	u8 tx_alloc = 0;
+
+	/* special case for HTC pseudo control service */
+	if (conn_req->service_id == ATH10K_HTC_SVC_ID_RSVD_CTRL) {
+		disable_credit_flow_ctrl = true;
+		assigned_eid = ATH10K_HTC_EP_0;
+		max_msg_size = ATH10K_HTC_MAX_CTRL_MSG_LEN;
+		memset(&resp_msg_dummy, 0, sizeof(resp_msg_dummy));
+		goto setup;
+	}
+
+	tx_alloc = ath10k_htc_get_credit_allocation(htc,
+						    conn_req->service_id);
+	if (!tx_alloc)
+		ath10k_warn("HTC Service %s does not allocate target credits\n",
+			    htc_service_name(conn_req->service_id));
+
+	skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
+	if (!skb) {
+		ath10k_err("Failed to allocate HTC packet\n");
+		return -ENOMEM;
+	}
+
+	length = sizeof(msg->hdr) + sizeof(msg->connect_service);
+	skb_put(skb, length);
+	memset(skb->data, 0, length);
+
+	msg = (struct ath10k_htc_msg *)skb->data;
+	msg->hdr.message_id =
+		__cpu_to_le16(ATH10K_HTC_MSG_CONNECT_SERVICE_ID);
+
+	flags |= SM(tx_alloc, ATH10K_HTC_CONN_FLAGS_RECV_ALLOC);
+
+	req_msg = &msg->connect_service;
+	req_msg->flags = __cpu_to_le16(flags);
+	req_msg->service_id = __cpu_to_le16(conn_req->service_id);
+
+	/* Only enable credit flow control for WMI ctrl service */
+	if (conn_req->service_id != ATH10K_HTC_SVC_ID_WMI_CONTROL) {
+		flags |= ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
+		disable_credit_flow_ctrl = true;
+	}
+
+	INIT_COMPLETION(htc->ctl_resp);
+
+	status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
+	if (status) {
+		kfree_skb(skb);
+		return status;
+	}
+
+	/* wait for response */
+	status = wait_for_completion_timeout(&htc->ctl_resp,
+					     ATH10K_HTC_CONN_SVC_TIMEOUT_HZ);
+	if (status <= 0) {
+		if (status == 0)
+			status = -ETIMEDOUT;
+		ath10k_err("Service connect timeout: %d\n", status);
+		return status;
+	}
+
+	/* we controlled the buffer creation, it's aligned */
+	msg = (struct ath10k_htc_msg *)htc->control_resp_buffer;
+	resp_msg = &msg->connect_service_response;
+	message_id = __le16_to_cpu(msg->hdr.message_id);
+	service_id = __le16_to_cpu(resp_msg->service_id);
+
+	if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) ||
+	    (htc->control_resp_len < sizeof(msg->hdr) +
+	     sizeof(msg->connect_service_response))) {
+		ath10k_err("Invalid resp message ID 0x%x", message_id);
+		return -EPROTO;
+	}
+
+	ath10k_dbg(ATH10K_DBG_HTC,
+		   "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n",
+		   htc_service_name(service_id),
+		   resp_msg->status, resp_msg->eid);
+
+	conn_resp->connect_resp_code = resp_msg->status;
+
+	/* check response status */
+	if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) {
+		ath10k_err("HTC Service %s connect request failed: 0x%x)\n",
+			   htc_service_name(service_id),
+			   resp_msg->status);
+		return -EPROTO;
+	}
+
+	assigned_eid = (enum ath10k_htc_ep_id)resp_msg->eid;
+	max_msg_size = __le16_to_cpu(resp_msg->max_msg_size);
+
+setup:
+
+	if (assigned_eid >= ATH10K_HTC_EP_COUNT)
+		return -EPROTO;
+
+	if (max_msg_size == 0)
+		return -EPROTO;
+
+	ep = &htc->endpoint[assigned_eid];
+	ep->eid = assigned_eid;
+
+	if (ep->service_id != ATH10K_HTC_SVC_ID_UNUSED)
+		return -EPROTO;
+
+	/* return assigned endpoint to caller */
+	conn_resp->eid = assigned_eid;
+	conn_resp->max_msg_len = __le16_to_cpu(resp_msg->max_msg_size);
+
+	/* setup the endpoint */
+	ep->service_id = conn_req->service_id;
+	ep->max_tx_queue_depth = conn_req->max_send_queue_depth;
+	ep->max_ep_message_len = __le16_to_cpu(resp_msg->max_msg_size);
+	ep->tx_credits = tx_alloc;
+	ep->tx_credit_size = htc->target_credit_size;
+	ep->tx_credits_per_max_message = ep->max_ep_message_len /
+					 htc->target_credit_size;
+
+	if (ep->max_ep_message_len % htc->target_credit_size)
+		ep->tx_credits_per_max_message++;
+
+	/* copy all the callbacks */
+	ep->ep_ops = conn_req->ep_ops;
+
+	status = ath10k_hif_map_service_to_pipe(htc->ar,
+						ep->service_id,
+						&ep->ul_pipe_id,
+						&ep->dl_pipe_id,
+						&ep->ul_is_polled,
+						&ep->dl_is_polled);
+	if (status)
+		return status;
+
+	ath10k_dbg(ATH10K_DBG_HTC,
+		   "HTC service: %s UL pipe: %d DL pipe: %d eid: %d ready\n",
+		   htc_service_name(ep->service_id), ep->ul_pipe_id,
+		   ep->dl_pipe_id, ep->eid);
+
+	ath10k_dbg(ATH10K_DBG_HTC,
+		   "EP %d UL polled: %d, DL polled: %d\n",
+		   ep->eid, ep->ul_is_polled, ep->dl_is_polled);
+
+	if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) {
+		ep->tx_credit_flow_enabled = false;
+		ath10k_dbg(ATH10K_DBG_HTC,
+			   "HTC service: %s eid: %d TX flow control disabled\n",
+			   htc_service_name(ep->service_id), assigned_eid);
+	}
+
+	return status;
+}
+
+struct sk_buff *ath10k_htc_alloc_skb(int size)
+{
+	struct sk_buff *skb;
+
+	skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr));
+	if (!skb) {
+		ath10k_warn("could not allocate HTC tx skb\n");
+		return NULL;
+	}
+
+	skb_reserve(skb, sizeof(struct ath10k_htc_hdr));
+
+	/* FW/HTC requires 4-byte aligned streams */
+	if (!IS_ALIGNED((unsigned long)skb->data, 4))
+		ath10k_warn("Unaligned HTC tx skb\n");
+
+	return skb;
+}
+
+int ath10k_htc_start(struct ath10k_htc *htc)
+{
+	struct sk_buff *skb;
+	int status = 0;
+	struct ath10k_htc_msg *msg;
+
+	skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
+	if (!skb)
+		return -ENOMEM;
+
+	skb_put(skb, sizeof(msg->hdr) + sizeof(msg->setup_complete_ext));
+	memset(skb->data, 0, skb->len);
+
+	msg = (struct ath10k_htc_msg *)skb->data;
+	msg->hdr.message_id =
+		__cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID);
+
+	ath10k_dbg(ATH10K_DBG_HTC, "HTC is using TX credit flow control\n");
+
+	status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
+	if (status) {
+		kfree_skb(skb);
+		return status;
+	}
+
+	return 0;
+}
+
+/*
+ * stop HTC communications, i.e. stop interrupt reception, and flush all
+ * queued buffers
+ */
+void ath10k_htc_stop(struct ath10k_htc *htc)
+{
+	int i;
+	struct ath10k_htc_ep *ep;
+
+	spin_lock_bh(&htc->tx_lock);
+	htc->stopping = true;
+	spin_unlock_bh(&htc->tx_lock);
+
+	for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) {
+		ep = &htc->endpoint[i];
+		ath10k_htc_flush_endpoint_tx(htc, ep);
+	}
+
+	ath10k_hif_stop(htc->ar);
+	ath10k_htc_reset_endpoint_states(htc);
+}
+
+/* registered target arrival callback from the HIF layer */
+struct ath10k_htc *ath10k_htc_create(struct ath10k *ar,
+				     struct ath10k_htc_ops *htc_ops)
+{
+	struct ath10k_hif_cb htc_callbacks;
+	struct ath10k_htc_ep *ep = NULL;
+	struct ath10k_htc *htc = NULL;
+
+	/* FIXME: use struct ath10k instead */
+	htc = kzalloc(sizeof(struct ath10k_htc), GFP_KERNEL);
+	if (!htc)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_init(&htc->tx_lock);
+
+	memcpy(&htc->htc_ops, htc_ops, sizeof(struct ath10k_htc_ops));
+
+	ath10k_htc_reset_endpoint_states(htc);
+
+	/* setup HIF layer callbacks */
+	htc_callbacks.rx_completion = ath10k_htc_rx_completion_handler;
+	htc_callbacks.tx_completion = ath10k_htc_tx_completion_handler;
+	htc->ar = ar;
+
+	/* Get HIF default pipe for HTC message exchange */
+	ep = &htc->endpoint[ATH10K_HTC_EP_0];
+
+	ath10k_hif_init(ar, &htc_callbacks);
+	ath10k_hif_get_default_pipe(ar, &ep->ul_pipe_id, &ep->dl_pipe_id);
+
+	init_completion(&htc->ctl_resp);
+
+	return htc;
+}
+
+void ath10k_htc_destroy(struct ath10k_htc *htc)
+{
+	kfree(htc);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htc.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htc.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HTC_H_
+#define _HTC_H_
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/bug.h>
+#include <linux/skbuff.h>
+#include <linux/semaphore.h>
+#include <linux/timer.h>
+
+struct ath10k;
+
+/****************/
+/* HTC protocol */
+/****************/
+
+/*
+ * HTC - host-target control protocol
+ *
+ * tx packets are generally <htc_hdr><payload>
+ * rx packets are more complex: <htc_hdr><payload><trailer>
+ *
+ * The payload + trailer length is stored in len.
+ * To get payload-only length one needs to payload - trailer_len.
+ *
+ * Trailer contains (possibly) multiple <htc_record>.
+ * Each record is a id-len-value.
+ *
+ * HTC header flags, control_byte0, control_byte1
+ * have different meaning depending whether its tx
+ * or rx.
+ *
+ * Alignment: htc_hdr, payload and trailer are
+ * 4-byte aligned.
+ */
+
+enum ath10k_htc_tx_flags {
+	ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE = 0x01,
+	ATH10K_HTC_FLAG_SEND_BUNDLE        = 0x02
+};
+
+enum ath10k_htc_rx_flags {
+	ATH10K_HTC_FLAG_TRAILER_PRESENT = 0x02,
+	ATH10K_HTC_FLAG_BUNDLE_MASK     = 0xF0
+};
+
+struct ath10k_htc_hdr {
+	u8 eid; /* @enum ath10k_htc_ep_id */
+	u8 flags; /* @enum ath10k_htc_tx_flags, ath10k_htc_rx_flags */
+	__le16 len;
+	union {
+		u8 trailer_len; /* for rx */
+		u8 control_byte0;
+	} __packed;
+	union {
+		u8 seq_no; /* for tx */
+		u8 control_byte1;
+	} __packed;
+	u8 pad0;
+	u8 pad1;
+} __packed __aligned(4);
+
+enum ath10k_ath10k_htc_msg_id {
+	ATH10K_HTC_MSG_READY_ID                = 1,
+	ATH10K_HTC_MSG_CONNECT_SERVICE_ID      = 2,
+	ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID = 3,
+	ATH10K_HTC_MSG_SETUP_COMPLETE_ID       = 4,
+	ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID    = 5,
+	ATH10K_HTC_MSG_SEND_SUSPEND_COMPLETE   = 6
+};
+
+enum ath10k_htc_version {
+	ATH10K_HTC_VERSION_2P0 = 0x00, /* 2.0 */
+	ATH10K_HTC_VERSION_2P1 = 0x01, /* 2.1 */
+};
+
+enum ath10k_htc_conn_flags {
+	ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH    = 0x0,
+	ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_ONE_HALF      = 0x1,
+	ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS = 0x2,
+	ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_UNITY         = 0x3,
+#define ATH10K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_MASK 0x3
+	ATH10K_HTC_CONN_FLAGS_REDUCE_CREDIT_DRIBBLE    = 1 << 2,
+	ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL = 1 << 3
+#define ATH10K_HTC_CONN_FLAGS_RECV_ALLOC_MASK 0xFF00
+#define ATH10K_HTC_CONN_FLAGS_RECV_ALLOC_LSB  8
+};
+
+enum ath10k_htc_conn_svc_status {
+	ATH10K_HTC_CONN_SVC_STATUS_SUCCESS      = 0,
+	ATH10K_HTC_CONN_SVC_STATUS_NOT_FOUND    = 1,
+	ATH10K_HTC_CONN_SVC_STATUS_FAILED       = 2,
+	ATH10K_HTC_CONN_SVC_STATUS_NO_RESOURCES = 3,
+	ATH10K_HTC_CONN_SVC_STATUS_NO_MORE_EP   = 4
+};
+
+struct ath10k_ath10k_htc_msg_hdr {
+	__le16 message_id; /* @enum htc_message_id */
+} __packed;
+
+struct ath10k_htc_unknown {
+	u8 pad0;
+	u8 pad1;
+} __packed;
+
+struct ath10k_htc_ready {
+	__le16 credit_count;
+	__le16 credit_size;
+	u8 max_endpoints;
+	u8 pad0;
+} __packed;
+
+struct ath10k_htc_ready_extended {
+	struct ath10k_htc_ready base;
+	u8 htc_version; /* @enum ath10k_htc_version */
+	u8 max_msgs_per_htc_bundle;
+	u8 pad0;
+	u8 pad1;
+} __packed;
+
+struct ath10k_htc_conn_svc {
+	__le16 service_id;
+	__le16 flags; /* @enum ath10k_htc_conn_flags */
+	u8 pad0;
+	u8 pad1;
+} __packed;
+
+struct ath10k_htc_conn_svc_response {
+	__le16 service_id;
+	u8 status; /* @enum ath10k_htc_conn_svc_status */
+	u8 eid;
+	__le16 max_msg_size;
+} __packed;
+
+struct ath10k_htc_setup_complete_extended {
+	u8 pad0;
+	u8 pad1;
+	__le32 flags; /* @enum htc_setup_complete_flags */
+	u8 max_msgs_per_bundled_recv;
+	u8 pad2;
+	u8 pad3;
+	u8 pad4;
+} __packed;
+
+struct ath10k_htc_msg {
+	struct ath10k_ath10k_htc_msg_hdr hdr;
+	union {
+		/* host-to-target */
+		struct ath10k_htc_conn_svc connect_service;
+		struct ath10k_htc_ready ready;
+		struct ath10k_htc_ready_extended ready_ext;
+		struct ath10k_htc_unknown unknown;
+		struct ath10k_htc_setup_complete_extended setup_complete_ext;
+
+		/* target-to-host */
+		struct ath10k_htc_conn_svc_response connect_service_response;
+	};
+} __packed __aligned(4);
+
+enum ath10k_ath10k_htc_record_id {
+	ATH10K_HTC_RECORD_NULL    = 0,
+	ATH10K_HTC_RECORD_CREDITS = 1
+};
+
+struct ath10k_ath10k_htc_record_hdr {
+	u8 id; /* @enum ath10k_ath10k_htc_record_id */
+	u8 len;
+	u8 pad0;
+	u8 pad1;
+} __packed;
+
+struct ath10k_htc_credit_report {
+	u8 eid; /* @enum ath10k_htc_ep_id */
+	u8 credits;
+	u8 pad0;
+	u8 pad1;
+} __packed;
+
+struct ath10k_htc_record {
+	struct ath10k_ath10k_htc_record_hdr hdr;
+	union {
+		struct ath10k_htc_credit_report credit_report[0];
+		u8 pauload[0];
+	};
+} __packed __aligned(4);
+
+/*
+ * note: the trailer offset is dynamic depending
+ * on payload length. this is only a struct layout draft
+ */
+struct ath10k_htc_frame {
+	struct ath10k_htc_hdr hdr;
+	union {
+		struct ath10k_htc_msg msg;
+		u8 payload[0];
+	};
+	struct ath10k_htc_record trailer[0];
+} __packed __aligned(4);
+
+
+/*******************/
+/* Host-side stuff */
+/*******************/
+
+enum ath10k_htc_svc_gid {
+	ATH10K_HTC_SVC_GRP_RSVD = 0,
+	ATH10K_HTC_SVC_GRP_WMI = 1,
+	ATH10K_HTC_SVC_GRP_NMI = 2,
+	ATH10K_HTC_SVC_GRP_HTT = 3,
+
+	ATH10K_HTC_SVC_GRP_TEST = 254,
+	ATH10K_HTC_SVC_GRP_LAST = 255,
+};
+
+#define SVC(group, idx) \
+	(int)(((int)(group) << 8) | (int)(idx))
+
+enum ath10k_htc_svc_id {
+	/* NOTE: service ID of 0x0000 is reserved and should never be used */
+	ATH10K_HTC_SVC_ID_RESERVED	= 0x0000,
+	ATH10K_HTC_SVC_ID_UNUSED	= ATH10K_HTC_SVC_ID_RESERVED,
+
+	ATH10K_HTC_SVC_ID_RSVD_CTRL	= SVC(ATH10K_HTC_SVC_GRP_RSVD, 1),
+	ATH10K_HTC_SVC_ID_WMI_CONTROL	= SVC(ATH10K_HTC_SVC_GRP_WMI, 0),
+	ATH10K_HTC_SVC_ID_WMI_DATA_BE	= SVC(ATH10K_HTC_SVC_GRP_WMI, 1),
+	ATH10K_HTC_SVC_ID_WMI_DATA_BK	= SVC(ATH10K_HTC_SVC_GRP_WMI, 2),
+	ATH10K_HTC_SVC_ID_WMI_DATA_VI	= SVC(ATH10K_HTC_SVC_GRP_WMI, 3),
+	ATH10K_HTC_SVC_ID_WMI_DATA_VO	= SVC(ATH10K_HTC_SVC_GRP_WMI, 4),
+
+	ATH10K_HTC_SVC_ID_NMI_CONTROL	= SVC(ATH10K_HTC_SVC_GRP_NMI, 0),
+	ATH10K_HTC_SVC_ID_NMI_DATA	= SVC(ATH10K_HTC_SVC_GRP_NMI, 1),
+
+	ATH10K_HTC_SVC_ID_HTT_DATA_MSG	= SVC(ATH10K_HTC_SVC_GRP_HTT, 0),
+
+	/* raw stream service (i.e. flash, tcmd, calibration apps) */
+	ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS = SVC(ATH10K_HTC_SVC_GRP_TEST, 0),
+};
+
+#undef SVC
+
+enum ath10k_htc_ep_id {
+	ATH10K_HTC_EP_UNUSED = -1,
+	ATH10K_HTC_EP_0 = 0,
+	ATH10K_HTC_EP_1 = 1,
+	ATH10K_HTC_EP_2,
+	ATH10K_HTC_EP_3,
+	ATH10K_HTC_EP_4,
+	ATH10K_HTC_EP_5,
+	ATH10K_HTC_EP_6,
+	ATH10K_HTC_EP_7,
+	ATH10K_HTC_EP_8,
+	ATH10K_HTC_EP_COUNT,
+};
+
+struct ath10k_htc_ops {
+	void (*target_send_suspend_complete)(struct ath10k *ar);
+};
+
+struct ath10k_htc_ep_ops {
+	void (*ep_tx_complete)(struct ath10k *, struct sk_buff *);
+	void (*ep_rx_complete)(struct ath10k *, struct sk_buff *);
+};
+
+/* service connection information */
+struct ath10k_htc_svc_conn_req {
+	u16 service_id;
+	struct ath10k_htc_ep_ops ep_ops;
+	int max_send_queue_depth;
+};
+
+/* service connection response information */
+struct ath10k_htc_svc_conn_resp {
+	u8 buffer_len;
+	u8 actual_len;
+	enum ath10k_htc_ep_id eid;
+	unsigned int max_msg_len;
+	u8 connect_resp_code;
+};
+
+#define ATH10K_NUM_CONTROL_TX_BUFFERS 2
+#define ATH10K_HTC_MAX_LEN 4096
+#define ATH10K_HTC_MAX_CTRL_MSG_LEN 256
+#define ATH10K_HTC_WAIT_TIMEOUT_HZ (1*HZ)
+#define ATH10K_HTC_CONTROL_BUFFER_SIZE (ATH10K_HTC_MAX_CTRL_MSG_LEN + \
+					sizeof(struct ath10k_htc_hdr))
+#define ATH10K_HTC_CONN_SVC_TIMEOUT_HZ (1*HZ)
+
+struct ath10k_htc_ep {
+	struct ath10k_htc *htc;
+	enum ath10k_htc_ep_id eid;
+	enum ath10k_htc_svc_id service_id;
+	struct ath10k_htc_ep_ops ep_ops;
+
+	int max_tx_queue_depth;
+	int max_ep_message_len;
+	u8 ul_pipe_id;
+	u8 dl_pipe_id;
+	int ul_is_polled; /* call HIF to get tx completions */
+	int dl_is_polled; /* call HIF to fetch rx (not implemented) */
+
+	struct sk_buff_head tx_queue;
+
+	u8 seq_no; /* for debugging */
+	int tx_credits;
+	int tx_credit_size;
+	int tx_credits_per_max_message;
+	bool tx_credit_flow_enabled;
+
+	struct work_struct send_work;
+};
+
+struct ath10k_htc_svc_tx_credits {
+	u16 service_id;
+	u8  credit_allocation;
+};
+
+struct ath10k_htc {
+	struct ath10k *ar;
+	struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT];
+
+	/* protects endpoint and stopping fields */
+	spinlock_t tx_lock;
+
+	struct ath10k_htc_ops htc_ops;
+
+	u8 control_resp_buffer[ATH10K_HTC_MAX_CTRL_MSG_LEN];
+	int control_resp_len;
+
+	struct completion ctl_resp;
+
+	int total_transmit_credits;
+	struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT];
+	int target_credit_size;
+
+	bool stopping;
+};
+
+struct ath10k_htc *ath10k_htc_create(struct ath10k *ar,
+				     struct ath10k_htc_ops *htc_ops);
+int ath10k_htc_wait_target(struct ath10k_htc *htc);
+int ath10k_htc_start(struct ath10k_htc *htc);
+int ath10k_htc_connect_service(struct ath10k_htc *htc,
+			       struct ath10k_htc_svc_conn_req  *conn_req,
+			       struct ath10k_htc_svc_conn_resp *conn_resp);
+int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid,
+		    struct sk_buff *packet);
+void ath10k_htc_stop(struct ath10k_htc *htc);
+void ath10k_htc_destroy(struct ath10k_htc *htc);
+struct sk_buff *ath10k_htc_alloc_skb(int size);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htt.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htt.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htt.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/slab.h>
+
+#include "htt.h"
+#include "core.h"
+#include "debug.h"
+
+static int ath10k_htt_htc_attach(struct ath10k_htt *htt)
+{
+	struct ath10k_htc_svc_conn_req conn_req;
+	struct ath10k_htc_svc_conn_resp conn_resp;
+	int status;
+
+	memset(&conn_req, 0, sizeof(conn_req));
+	memset(&conn_resp, 0, sizeof(conn_resp));
+
+	conn_req.ep_ops.ep_tx_complete = ath10k_htt_htc_tx_complete;
+	conn_req.ep_ops.ep_rx_complete = ath10k_htt_t2h_msg_handler;
+
+	/* connect to control service */
+	conn_req.service_id = ATH10K_HTC_SVC_ID_HTT_DATA_MSG;
+
+	status = ath10k_htc_connect_service(htt->ar->htc, &conn_req,
+					    &conn_resp);
+
+	if (status)
+		return status;
+
+	htt->eid = conn_resp.eid;
+
+	return 0;
+}
+
+struct ath10k_htt *ath10k_htt_attach(struct ath10k *ar)
+{
+	struct ath10k_htt *htt;
+	int ret;
+
+	htt = kzalloc(sizeof(*htt), GFP_KERNEL);
+	if (!htt)
+		return NULL;
+
+	htt->ar = ar;
+	htt->max_throughput_mbps = 800;
+
+	/*
+	 * Connect to HTC service.
+	 * This has to be done before calling ath10k_htt_rx_attach,
+	 * since ath10k_htt_rx_attach involves sending a rx ring configure
+	 * message to the target.
+	 */
+	if (ath10k_htt_htc_attach(htt))
+		goto err_htc_attach;
+
+	ret = ath10k_htt_tx_attach(htt);
+	if (ret) {
+		ath10k_err("could not attach htt tx (%d)\n", ret);
+		goto err_htc_attach;
+	}
+
+	if (ath10k_htt_rx_attach(htt))
+		goto err_rx_attach;
+
+	/*
+	 * Prefetch enough data to satisfy target
+	 * classification engine.
+	 * This is for LL chips. HL chips will probably
+	 * transfer all frame in the tx fragment.
+	 */
+	htt->prefetch_len =
+		36 + /* 802.11 + qos + ht */
+		4 + /* 802.1q */
+		8 + /* llc snap */
+		2; /* ip4 dscp or ip6 priority */
+
+	return htt;
+
+err_rx_attach:
+	ath10k_htt_tx_detach(htt);
+err_htc_attach:
+	kfree(htt);
+	return NULL;
+}
+
+#define HTT_TARGET_VERSION_TIMEOUT_HZ (3*HZ)
+
+static int ath10k_htt_verify_version(struct ath10k_htt *htt)
+{
+	ath10k_dbg(ATH10K_DBG_HTT,
+		   "htt target version %d.%d; host version %d.%d\n",
+		    htt->target_version_major,
+		    htt->target_version_minor,
+		    HTT_CURRENT_VERSION_MAJOR,
+		    HTT_CURRENT_VERSION_MINOR);
+
+	if (htt->target_version_major != HTT_CURRENT_VERSION_MAJOR) {
+		ath10k_err("htt major versions are incompatible!\n");
+		return -ENOTSUPP;
+	}
+
+	if (htt->target_version_minor != HTT_CURRENT_VERSION_MINOR)
+		ath10k_warn("htt minor version differ but still compatible\n");
+
+	return 0;
+}
+
+int ath10k_htt_attach_target(struct ath10k_htt *htt)
+{
+	int status;
+
+	init_completion(&htt->target_version_received);
+
+	status = ath10k_htt_h2t_ver_req_msg(htt);
+	if (status)
+		return status;
+
+	status = wait_for_completion_timeout(&htt->target_version_received,
+						HTT_TARGET_VERSION_TIMEOUT_HZ);
+	if (status <= 0) {
+		ath10k_warn("htt version request timed out\n");
+		return -ETIMEDOUT;
+	}
+
+	status = ath10k_htt_verify_version(htt);
+	if (status)
+		return status;
+
+	return ath10k_htt_send_rx_ring_cfg_ll(htt);
+}
+
+void ath10k_htt_detach(struct ath10k_htt *htt)
+{
+	ath10k_htt_rx_detach(htt);
+	ath10k_htt_tx_detach(htt);
+	kfree(htt);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htt.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htt.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htt.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htt.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1338 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HTT_H_
+#define _HTT_H_
+
+#include <linux/bug.h>
+
+#include "core.h"
+#include "htc.h"
+#include "rx_desc.h"
+
+#define HTT_CURRENT_VERSION_MAJOR	2
+#define HTT_CURRENT_VERSION_MINOR	1
+
+enum htt_dbg_stats_type {
+	HTT_DBG_STATS_WAL_PDEV_TXRX = 1 << 0,
+	HTT_DBG_STATS_RX_REORDER    = 1 << 1,
+	HTT_DBG_STATS_RX_RATE_INFO  = 1 << 2,
+	HTT_DBG_STATS_TX_PPDU_LOG   = 1 << 3,
+	HTT_DBG_STATS_TX_RATE_INFO  = 1 << 4,
+	/* bits 5-23 currently reserved */
+
+	HTT_DBG_NUM_STATS /* keep this last */
+};
+
+enum htt_h2t_msg_type { /* host-to-target */
+	HTT_H2T_MSG_TYPE_VERSION_REQ        = 0,
+	HTT_H2T_MSG_TYPE_TX_FRM             = 1,
+	HTT_H2T_MSG_TYPE_RX_RING_CFG        = 2,
+	HTT_H2T_MSG_TYPE_STATS_REQ          = 3,
+	HTT_H2T_MSG_TYPE_SYNC               = 4,
+	HTT_H2T_MSG_TYPE_AGGR_CFG           = 5,
+	HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG = 6,
+	HTT_H2T_MSG_TYPE_MGMT_TX            = 7,
+
+	HTT_H2T_NUM_MSGS /* keep this last */
+};
+
+struct htt_cmd_hdr {
+	u8 msg_type;
+} __packed;
+
+struct htt_ver_req {
+	u8 pad[sizeof(u32) - sizeof(struct htt_cmd_hdr)];
+} __packed;
+
+/*
+ * HTT tx MSDU descriptor
+ *
+ * The HTT tx MSDU descriptor is created by the host HTT SW for each
+ * tx MSDU.  The HTT tx MSDU descriptor contains the information that
+ * the target firmware needs for the FW's tx processing, particularly
+ * for creating the HW msdu descriptor.
+ * The same HTT tx descriptor is used for HL and LL systems, though
+ * a few fields within the tx descriptor are used only by LL or
+ * only by HL.
+ * The HTT tx descriptor is defined in two manners: by a struct with
+ * bitfields, and by a series of [dword offset, bit mask, bit shift]
+ * definitions.
+ * The target should use the struct def, for simplicitly and clarity,
+ * but the host shall use the bit-mast + bit-shift defs, to be endian-
+ * neutral.  Specifically, the host shall use the get/set macros built
+ * around the mask + shift defs.
+ */
+struct htt_data_tx_desc_frag {
+	__le32 paddr;
+	__le32 len;
+} __packed;
+
+enum htt_data_tx_desc_flags0 {
+	HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT = 1 << 0,
+	HTT_DATA_TX_DESC_FLAGS0_NO_AGGR         = 1 << 1,
+	HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT      = 1 << 2,
+	HTT_DATA_TX_DESC_FLAGS0_NO_CLASSIFY     = 1 << 3,
+	HTT_DATA_TX_DESC_FLAGS0_RSVD0           = 1 << 4
+#define HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE_MASK 0xE0
+#define HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE_LSB 5
+};
+
+enum htt_data_tx_desc_flags1 {
+#define HTT_DATA_TX_DESC_FLAGS1_VDEV_ID_BITS 6
+#define HTT_DATA_TX_DESC_FLAGS1_VDEV_ID_MASK 0x003F
+#define HTT_DATA_TX_DESC_FLAGS1_VDEV_ID_LSB  0
+#define HTT_DATA_TX_DESC_FLAGS1_EXT_TID_BITS 5
+#define HTT_DATA_TX_DESC_FLAGS1_EXT_TID_MASK 0x07C0
+#define HTT_DATA_TX_DESC_FLAGS1_EXT_TID_LSB  6
+	HTT_DATA_TX_DESC_FLAGS1_POSTPONED        = 1 << 11,
+	HTT_DATA_TX_DESC_FLAGS1_MORE_IN_BATCH    = 1 << 12,
+	HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD = 1 << 13,
+	HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD = 1 << 14,
+	HTT_DATA_TX_DESC_FLAGS1_RSVD1            = 1 << 15
+};
+
+enum htt_data_tx_ext_tid {
+	HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST = 16,
+	HTT_DATA_TX_EXT_TID_MGMT                = 17,
+	HTT_DATA_TX_EXT_TID_INVALID             = 31
+};
+
+#define HTT_INVALID_PEERID 0xFFFF
+
+/*
+ * htt_data_tx_desc - used for data tx path
+ *
+ * Note: vdev_id irrelevant for pkt_type == raw and no_classify == 1.
+ *       ext_tid: for qos-data frames (0-15), see %HTT_DATA_TX_EXT_TID_
+ *                for special kinds of tids
+ *       postponed: only for HL hosts. indicates if this is a resend
+ *                  (HL hosts manage queues on the host )
+ *       more_in_batch: only for HL hosts. indicates if more packets are
+ *                      pending. this allows target to wait and aggregate
+ */
+struct htt_data_tx_desc {
+	u8 flags0; /* %HTT_DATA_TX_DESC_FLAGS0_ */
+	__le16 flags1; /* %HTT_DATA_TX_DESC_FLAGS1_ */
+	__le16 len;
+	__le16 id;
+	__le32 frags_paddr;
+	__le32 peerid;
+	u8 prefetch[0]; /* start of frame, for FW classification engine */
+} __packed;
+
+enum htt_rx_ring_flags {
+	HTT_RX_RING_FLAGS_MAC80211_HDR = 1 << 0,
+	HTT_RX_RING_FLAGS_MSDU_PAYLOAD = 1 << 1,
+	HTT_RX_RING_FLAGS_PPDU_START   = 1 << 2,
+	HTT_RX_RING_FLAGS_PPDU_END     = 1 << 3,
+	HTT_RX_RING_FLAGS_MPDU_START   = 1 << 4,
+	HTT_RX_RING_FLAGS_MPDU_END     = 1 << 5,
+	HTT_RX_RING_FLAGS_MSDU_START   = 1 << 6,
+	HTT_RX_RING_FLAGS_MSDU_END     = 1 << 7,
+	HTT_RX_RING_FLAGS_RX_ATTENTION = 1 << 8,
+	HTT_RX_RING_FLAGS_FRAG_INFO    = 1 << 9,
+	HTT_RX_RING_FLAGS_UNICAST_RX   = 1 << 10,
+	HTT_RX_RING_FLAGS_MULTICAST_RX = 1 << 11,
+	HTT_RX_RING_FLAGS_CTRL_RX      = 1 << 12,
+	HTT_RX_RING_FLAGS_MGMT_RX      = 1 << 13,
+	HTT_RX_RING_FLAGS_NULL_RX      = 1 << 14,
+	HTT_RX_RING_FLAGS_PHY_DATA_RX  = 1 << 15
+};
+
+struct htt_rx_ring_setup_ring {
+	__le32 fw_idx_shadow_reg_paddr;
+	__le32 rx_ring_base_paddr;
+	__le16 rx_ring_len; /* in 4-byte words */
+	__le16 rx_ring_bufsize; /* rx skb size - in bytes */
+	__le16 flags; /* %HTT_RX_RING_FLAGS_ */
+	__le16 fw_idx_init_val;
+
+	/* the following offsets are in 4-byte units */
+	__le16 mac80211_hdr_offset;
+	__le16 msdu_payload_offset;
+	__le16 ppdu_start_offset;
+	__le16 ppdu_end_offset;
+	__le16 mpdu_start_offset;
+	__le16 mpdu_end_offset;
+	__le16 msdu_start_offset;
+	__le16 msdu_end_offset;
+	__le16 rx_attention_offset;
+	__le16 frag_info_offset;
+} __packed;
+
+struct htt_rx_ring_setup_hdr {
+	u8 num_rings; /* supported values: 1, 2 */
+	__le16 rsvd0;
+} __packed;
+
+struct htt_rx_ring_setup {
+	struct htt_rx_ring_setup_hdr hdr;
+	struct htt_rx_ring_setup_ring rings[0];
+} __packed;
+
+/*
+ * htt_stats_req - request target to send specified statistics
+ *
+ * @msg_type: hardcoded %HTT_H2T_MSG_TYPE_STATS_REQ
+ * @upload_types: see %htt_dbg_stats_type. this is 24bit field actually
+ *	so make sure its little-endian.
+ * @reset_types: see %htt_dbg_stats_type. this is 24bit field actually
+ *	so make sure its little-endian.
+ * @cfg_val: stat_type specific configuration
+ * @stat_type: see %htt_dbg_stats_type
+ * @cookie_lsb: used for confirmation message from target->host
+ * @cookie_msb: ditto as %cookie
+ */
+struct htt_stats_req {
+	u8 upload_types[3];
+	u8 rsvd0;
+	u8 reset_types[3];
+	struct {
+		u8 mpdu_bytes;
+		u8 mpdu_num_msdus;
+		u8 msdu_bytes;
+	} __packed;
+	u8 stat_type;
+	__le32 cookie_lsb;
+	__le32 cookie_msb;
+} __packed;
+
+#define HTT_STATS_REQ_CFG_STAT_TYPE_INVALID 0xff
+
+/*
+ * htt_oob_sync_req - request out-of-band sync
+ *
+ * The HTT SYNC tells the target to suspend processing of subsequent
+ * HTT host-to-target messages until some other target agent locally
+ * informs the target HTT FW that the current sync counter is equal to
+ * or greater than (in a modulo sense) the sync counter specified in
+ * the SYNC message.
+ *
+ * This allows other host-target components to synchronize their operation
+ * with HTT, e.g. to ensure that tx frames don't get transmitted until a
+ * security key has been downloaded to and activated by the target.
+ * In the absence of any explicit synchronization counter value
+ * specification, the target HTT FW will use zero as the default current
+ * sync value.
+ *
+ * The HTT target FW will suspend its host->target message processing as long
+ * as 0 < (in-band sync counter - out-of-band sync counter) & 0xff < 128.
+ */
+struct htt_oob_sync_req {
+	u8 sync_count;
+	__le16 rsvd0;
+} __packed;
+
+#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_MASK 0x1F
+#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_LSB  0
+
+struct htt_aggr_conf {
+	u8 max_num_ampdu_subframes;
+	union {
+		/* dont use bitfields; undefined behaviour */
+		u8 flags; /* see %HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_ */
+		u8 max_num_amsdu_subframes:5;
+	} __packed;
+} __packed;
+
+#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
+
+struct htt_mgmt_tx_desc {
+	u8 pad[sizeof(u32) - sizeof(struct htt_cmd_hdr)];
+	__le32 msdu_paddr;
+	__le32 desc_id;
+	__le32 len;
+	__le32 vdev_id;
+	u8 hdr[HTT_MGMT_FRM_HDR_DOWNLOAD_LEN];
+} __packed;
+
+enum htt_mgmt_tx_status {
+	HTT_MGMT_TX_STATUS_OK    = 0,
+	HTT_MGMT_TX_STATUS_RETRY = 1,
+	HTT_MGMT_TX_STATUS_DROP  = 2
+};
+
+/*=== target -> host messages ===============================================*/
+
+
+enum htt_t2h_msg_type {
+	HTT_T2H_MSG_TYPE_VERSION_CONF		= 0x0,
+	HTT_T2H_MSG_TYPE_RX_IND			= 0x1,
+	HTT_T2H_MSG_TYPE_RX_FLUSH		= 0x2,
+	HTT_T2H_MSG_TYPE_PEER_MAP		= 0x3,
+	HTT_T2H_MSG_TYPE_PEER_UNMAP		= 0x4,
+	HTT_T2H_MSG_TYPE_RX_ADDBA		= 0x5,
+	HTT_T2H_MSG_TYPE_RX_DELBA		= 0x6,
+	HTT_T2H_MSG_TYPE_TX_COMPL_IND		= 0x7,
+	HTT_T2H_MSG_TYPE_PKTLOG			= 0x8,
+	HTT_T2H_MSG_TYPE_STATS_CONF		= 0x9,
+	HTT_T2H_MSG_TYPE_RX_FRAG_IND		= 0xa,
+	HTT_T2H_MSG_TYPE_SEC_IND		= 0xb,
+	HTT_T2H_MSG_TYPE_RC_UPDATE_IND		= 0xc,
+	HTT_T2H_MSG_TYPE_TX_INSPECT_IND		= 0xd,
+	HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION	= 0xe,
+	HTT_T2H_MSG_TYPE_TEST,
+	/* keep this last */
+	HTT_T2H_NUM_MSGS
+};
+
+/*
+ * htt_resp_hdr - header for target-to-host messages
+ *
+ * msg_type: see htt_t2h_msg_type
+ */
+struct htt_resp_hdr {
+	u8 msg_type;
+} __packed;
+
+#define HTT_RESP_HDR_MSG_TYPE_OFFSET 0
+#define HTT_RESP_HDR_MSG_TYPE_MASK   0xff
+#define HTT_RESP_HDR_MSG_TYPE_LSB    0
+
+/* htt_ver_resp - response sent for htt_ver_req */
+struct htt_ver_resp {
+	u8 minor;
+	u8 major;
+	u8 rsvd0;
+} __packed;
+
+struct htt_mgmt_tx_completion {
+	u8 rsvd0;
+	u8 rsvd1;
+	u8 rsvd2;
+	__le32 desc_id;
+	__le32 status;
+} __packed;
+
+#define HTT_RX_INDICATION_INFO0_EXT_TID_MASK  (0x3F)
+#define HTT_RX_INDICATION_INFO0_EXT_TID_LSB   (0)
+#define HTT_RX_INDICATION_INFO0_FLUSH_VALID   (1 << 6)
+#define HTT_RX_INDICATION_INFO0_RELEASE_VALID (1 << 7)
+
+#define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_MASK   0x0000003F
+#define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_LSB    0
+#define HTT_RX_INDICATION_INFO1_FLUSH_END_SEQNO_MASK     0x00000FC0
+#define HTT_RX_INDICATION_INFO1_FLUSH_END_SEQNO_LSB      6
+#define HTT_RX_INDICATION_INFO1_RELEASE_START_SEQNO_MASK 0x0003F000
+#define HTT_RX_INDICATION_INFO1_RELEASE_START_SEQNO_LSB  12
+#define HTT_RX_INDICATION_INFO1_RELEASE_END_SEQNO_MASK   0x00FC0000
+#define HTT_RX_INDICATION_INFO1_RELEASE_END_SEQNO_LSB    18
+#define HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES_MASK     0xFF000000
+#define HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES_LSB      24
+
+struct htt_rx_indication_hdr {
+	u8 info0; /* %HTT_RX_INDICATION_INFO0_ */
+	__le16 peer_id;
+	__le32 info1; /* %HTT_RX_INDICATION_INFO1_ */
+} __packed;
+
+#define HTT_RX_INDICATION_INFO0_PHY_ERR_VALID    (1 << 0)
+#define HTT_RX_INDICATION_INFO0_LEGACY_RATE_MASK (0x1E)
+#define HTT_RX_INDICATION_INFO0_LEGACY_RATE_LSB  (1)
+#define HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK  (1 << 5)
+#define HTT_RX_INDICATION_INFO0_END_VALID        (1 << 6)
+#define HTT_RX_INDICATION_INFO0_START_VALID      (1 << 7)
+
+#define HTT_RX_INDICATION_INFO1_VHT_SIG_A1_MASK    0x00FFFFFF
+#define HTT_RX_INDICATION_INFO1_VHT_SIG_A1_LSB     0
+#define HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE_MASK 0xFF000000
+#define HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE_LSB  24
+
+#define HTT_RX_INDICATION_INFO2_VHT_SIG_A1_MASK 0x00FFFFFF
+#define HTT_RX_INDICATION_INFO2_VHT_SIG_A1_LSB  0
+#define HTT_RX_INDICATION_INFO2_SERVICE_MASK    0xFF000000
+#define HTT_RX_INDICATION_INFO2_SERVICE_LSB     24
+
+enum htt_rx_legacy_rate {
+	HTT_RX_OFDM_48 = 0,
+	HTT_RX_OFDM_24 = 1,
+	HTT_RX_OFDM_12,
+	HTT_RX_OFDM_6,
+	HTT_RX_OFDM_54,
+	HTT_RX_OFDM_36,
+	HTT_RX_OFDM_18,
+	HTT_RX_OFDM_9,
+
+	/* long preamble */
+	HTT_RX_CCK_11_LP = 0,
+	HTT_RX_CCK_5_5_LP = 1,
+	HTT_RX_CCK_2_LP,
+	HTT_RX_CCK_1_LP,
+	/* short preamble */
+	HTT_RX_CCK_11_SP,
+	HTT_RX_CCK_5_5_SP,
+	HTT_RX_CCK_2_SP
+};
+
+enum htt_rx_legacy_rate_type {
+	HTT_RX_LEGACY_RATE_OFDM = 0,
+	HTT_RX_LEGACY_RATE_CCK
+};
+
+enum htt_rx_preamble_type {
+	HTT_RX_LEGACY        = 0x4,
+	HTT_RX_HT            = 0x8,
+	HTT_RX_HT_WITH_TXBF  = 0x9,
+	HTT_RX_VHT           = 0xC,
+	HTT_RX_VHT_WITH_TXBF = 0xD,
+};
+
+/*
+ * Fields: phy_err_valid, phy_err_code, tsf,
+ * usec_timestamp, sub_usec_timestamp
+ * ..are valid only if end_valid == 1.
+ *
+ * Fields: rssi_chains, legacy_rate_type,
+ * legacy_rate_cck, preamble_type, service,
+ * vht_sig_*
+ * ..are valid only if start_valid == 1;
+ */
+struct htt_rx_indication_ppdu {
+	u8 combined_rssi;
+	u8 sub_usec_timestamp;
+	u8 phy_err_code;
+	u8 info0; /* HTT_RX_INDICATION_INFO0_ */
+	struct {
+		u8 pri20_db;
+		u8 ext20_db;
+		u8 ext40_db;
+		u8 ext80_db;
+	} __packed rssi_chains[4];
+	__le32 tsf;
+	__le32 usec_timestamp;
+	__le32 info1; /* HTT_RX_INDICATION_INFO1_ */
+	__le32 info2; /* HTT_RX_INDICATION_INFO2_ */
+} __packed;
+
+enum htt_rx_mpdu_status {
+	HTT_RX_IND_MPDU_STATUS_UNKNOWN = 0x0,
+	HTT_RX_IND_MPDU_STATUS_OK,
+	HTT_RX_IND_MPDU_STATUS_ERR_FCS,
+	HTT_RX_IND_MPDU_STATUS_ERR_DUP,
+	HTT_RX_IND_MPDU_STATUS_ERR_REPLAY,
+	HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER,
+	/* only accept EAPOL frames */
+	HTT_RX_IND_MPDU_STATUS_UNAUTH_PEER,
+	HTT_RX_IND_MPDU_STATUS_OUT_OF_SYNC,
+	/* Non-data in promiscous mode */
+	HTT_RX_IND_MPDU_STATUS_MGMT_CTRL,
+	HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR,
+	HTT_RX_IND_MPDU_STATUS_DECRYPT_ERR,
+	HTT_RX_IND_MPDU_STATUS_MPDU_LENGTH_ERR,
+	HTT_RX_IND_MPDU_STATUS_ENCRYPT_REQUIRED_ERR,
+	HTT_RX_IND_MPDU_STATUS_PRIVACY_ERR,
+
+	/*
+	 * MISC: discard for unspecified reasons.
+	 * Leave this enum value last.
+	 */
+	HTT_RX_IND_MPDU_STATUS_ERR_MISC = 0xFF
+};
+
+struct htt_rx_indication_mpdu_range {
+	u8 mpdu_count;
+	u8 mpdu_range_status; /* %htt_rx_mpdu_status */
+	u8 pad0;
+	u8 pad1;
+} __packed;
+
+struct htt_rx_indication_prefix {
+	__le16 fw_rx_desc_bytes;
+	u8 pad0;
+	u8 pad1;
+};
+
+struct htt_rx_indication {
+	struct htt_rx_indication_hdr hdr;
+	struct htt_rx_indication_ppdu ppdu;
+	struct htt_rx_indication_prefix prefix;
+
+	/*
+	 * the following fields are both dynamically sized, so
+	 * take care addressing them
+	 */
+
+	/* the size of this is %fw_rx_desc_bytes */
+	struct fw_rx_desc_base fw_desc;
+
+	/*
+	 * %mpdu_ranges starts after &%prefix + roundup(%fw_rx_desc_bytes, 4)
+	 * and has %num_mpdu_ranges elements.
+	 */
+	struct htt_rx_indication_mpdu_range mpdu_ranges[0];
+} __packed;
+
+static inline struct htt_rx_indication_mpdu_range *
+		htt_rx_ind_get_mpdu_ranges(struct htt_rx_indication *rx_ind)
+{
+	void *ptr = rx_ind;
+
+	ptr += sizeof(rx_ind->hdr)
+	     + sizeof(rx_ind->ppdu)
+	     + sizeof(rx_ind->prefix)
+	     + roundup(__le16_to_cpu(rx_ind->prefix.fw_rx_desc_bytes), 4);
+	return ptr;
+}
+
+enum htt_rx_flush_mpdu_status {
+	HTT_RX_FLUSH_MPDU_DISCARD = 0,
+	HTT_RX_FLUSH_MPDU_REORDER = 1,
+};
+
+/*
+ * htt_rx_flush - discard or reorder given range of mpdus
+ *
+ * Note: host must check if all sequence numbers between
+ *	[seq_num_start, seq_num_end-1] are valid.
+ */
+struct htt_rx_flush {
+	__le16 peer_id;
+	u8 tid;
+	u8 rsvd0;
+	u8 mpdu_status; /* %htt_rx_flush_mpdu_status */
+	u8 seq_num_start; /* it is 6 LSBs of 802.11 seq no */
+	u8 seq_num_end; /* it is 6 LSBs of 802.11 seq no */
+};
+
+struct htt_rx_peer_map {
+	u8 vdev_id;
+	__le16 peer_id;
+	u8 addr[6];
+	u8 rsvd0;
+	u8 rsvd1;
+} __packed;
+
+struct htt_rx_peer_unmap {
+	u8 rsvd0;
+	__le16 peer_id;
+} __packed;
+
+enum htt_security_types {
+	HTT_SECURITY_NONE,
+	HTT_SECURITY_WEP128,
+	HTT_SECURITY_WEP104,
+	HTT_SECURITY_WEP40,
+	HTT_SECURITY_TKIP,
+	HTT_SECURITY_TKIP_NOMIC,
+	HTT_SECURITY_AES_CCMP,
+	HTT_SECURITY_WAPI,
+
+	HTT_NUM_SECURITY_TYPES /* keep this last! */
+};
+
+enum htt_security_flags {
+#define HTT_SECURITY_TYPE_MASK 0x7F
+#define HTT_SECURITY_TYPE_LSB  0
+	HTT_SECURITY_IS_UNICAST = 1 << 7
+};
+
+struct htt_security_indication {
+	union {
+		/* dont use bitfields; undefined behaviour */
+		u8 flags; /* %htt_security_flags */
+		struct {
+			u8 security_type:7, /* %htt_security_types */
+			   is_unicast:1;
+		} __packed;
+	} __packed;
+	__le16 peer_id;
+	u8 michael_key[8];
+	u8 wapi_rsc[16];
+} __packed;
+
+#define HTT_RX_BA_INFO0_TID_MASK     0x000F
+#define HTT_RX_BA_INFO0_TID_LSB      0
+#define HTT_RX_BA_INFO0_PEER_ID_MASK 0xFFF0
+#define HTT_RX_BA_INFO0_PEER_ID_LSB  4
+
+struct htt_rx_addba {
+	u8 window_size;
+	__le16 info0; /* %HTT_RX_BA_INFO0_ */
+} __packed;
+
+struct htt_rx_delba {
+	u8 rsvd0;
+	__le16 info0; /* %HTT_RX_BA_INFO0_ */
+} __packed;
+
+enum htt_data_tx_status {
+	HTT_DATA_TX_STATUS_OK            = 0,
+	HTT_DATA_TX_STATUS_DISCARD       = 1,
+	HTT_DATA_TX_STATUS_NO_ACK        = 2,
+	HTT_DATA_TX_STATUS_POSTPONE      = 3, /* HL only */
+	HTT_DATA_TX_STATUS_DOWNLOAD_FAIL = 128
+};
+
+enum htt_data_tx_flags {
+#define HTT_DATA_TX_STATUS_MASK 0x07
+#define HTT_DATA_TX_STATUS_LSB  0
+#define HTT_DATA_TX_TID_MASK    0x78
+#define HTT_DATA_TX_TID_LSB     3
+	HTT_DATA_TX_TID_INVALID = 1 << 7
+};
+
+#define HTT_TX_COMPL_INV_MSDU_ID 0xFFFF
+
+struct htt_data_tx_completion {
+	union {
+		u8 flags;
+		struct {
+			u8 status:3,
+			   tid:4,
+			   tid_invalid:1;
+		} __packed;
+	} __packed;
+	u8 num_msdus;
+	u8 rsvd0;
+	__le16 msdus[0]; /* variable length based on %num_msdus */
+} __packed;
+
+struct htt_tx_compl_ind_base {
+	u32 hdr;
+	u16 payload[1/*or more*/];
+} __packed;
+
+struct htt_rc_tx_done_params {
+	u32 rate_code;
+	u32 rate_code_flags;
+	u32 flags;
+	u32 num_enqued; /* 1 for non-AMPDU */
+	u32 num_retries;
+	u32 num_failed; /* for AMPDU */
+	u32 ack_rssi;
+	u32 time_stamp;
+	u32 is_probe;
+};
+
+struct htt_rc_update {
+	u8 vdev_id;
+	__le16 peer_id;
+	u8 addr[6];
+	u8 num_elems;
+	u8 rsvd0;
+	struct htt_rc_tx_done_params params[0]; /* variable length %num_elems */
+} __packed;
+
+/* see htt_rx_indication for similar fields and descriptions */
+struct htt_rx_fragment_indication {
+	union {
+		u8 info0; /* %HTT_RX_FRAG_IND_INFO0_ */
+		struct {
+			u8 ext_tid:5,
+			   flush_valid:1;
+		} __packed;
+	} __packed;
+	__le16 peer_id;
+	__le32 info1; /* %HTT_RX_FRAG_IND_INFO1_ */
+	__le16 fw_rx_desc_bytes;
+	__le16 rsvd0;
+
+	u8 fw_msdu_rx_desc[0];
+} __packed;
+
+#define HTT_RX_FRAG_IND_INFO0_EXT_TID_MASK     0x1F
+#define HTT_RX_FRAG_IND_INFO0_EXT_TID_LSB      0
+#define HTT_RX_FRAG_IND_INFO0_FLUSH_VALID_MASK 0x20
+#define HTT_RX_FRAG_IND_INFO0_FLUSH_VALID_LSB  5
+
+#define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_START_MASK 0x0000003F
+#define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_START_LSB  0
+#define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_END_MASK   0x00000FC0
+#define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_END_LSB    6
+
+/*
+ * target -> host test message definition
+ *
+ * The following field definitions describe the format of the test
+ * message sent from the target to the host.
+ * The message consists of a 4-octet header, followed by a variable
+ * number of 32-bit integer values, followed by a variable number
+ * of 8-bit character values.
+ *
+ * |31                         16|15           8|7            0|
+ * |-----------------------------------------------------------|
+ * |          num chars          |   num ints   |   msg type   |
+ * |-----------------------------------------------------------|
+ * |                           int 0                           |
+ * |-----------------------------------------------------------|
+ * |                           int 1                           |
+ * |-----------------------------------------------------------|
+ * |                            ...                            |
+ * |-----------------------------------------------------------|
+ * |    char 3    |    char 2    |    char 1    |    char 0    |
+ * |-----------------------------------------------------------|
+ * |              |              |      ...     |    char 4    |
+ * |-----------------------------------------------------------|
+ *   - MSG_TYPE
+ *     Bits 7:0
+ *     Purpose: identifies this as a test message
+ *     Value: HTT_MSG_TYPE_TEST
+ *   - NUM_INTS
+ *     Bits 15:8
+ *     Purpose: indicate how many 32-bit integers follow the message header
+ *   - NUM_CHARS
+ *     Bits 31:16
+ *     Purpose: indicate how many 8-bit charaters follow the series of integers
+ */
+struct htt_rx_test {
+	u8 num_ints;
+	__le16 num_chars;
+
+	/* payload consists of 2 lists:
+	 *  a) num_ints * sizeof(__le32)
+	 *  b) num_chars * sizeof(u8) aligned to 4bytes */
+	u8 payload[0];
+} __packed;
+
+static inline __le32 *htt_rx_test_get_ints(struct htt_rx_test *rx_test)
+{
+	return (__le32 *)rx_test->payload;
+}
+
+static inline u8 *htt_rx_test_get_chars(struct htt_rx_test *rx_test)
+{
+	return rx_test->payload + (rx_test->num_ints * sizeof(__le32));
+}
+
+/*
+ * target -> host packet log message
+ *
+ * The following field definitions describe the format of the packet log
+ * message sent from the target to the host.
+ * The message consists of a 4-octet header,followed by a variable number
+ * of 32-bit character values.
+ *
+ * |31          24|23          16|15           8|7            0|
+ * |-----------------------------------------------------------|
+ * |              |              |              |   msg type   |
+ * |-----------------------------------------------------------|
+ * |                        payload                            |
+ * |-----------------------------------------------------------|
+ *   - MSG_TYPE
+ *     Bits 7:0
+ *     Purpose: identifies this as a test message
+ *     Value: HTT_MSG_TYPE_PACKETLOG
+ */
+struct htt_pktlog_msg {
+	u8 pad[3];
+	__le32 payload[1 /* or more */];
+} __packed;
+
+struct htt_dbg_stats_rx_reorder_stats {
+	/* Non QoS MPDUs received */
+	__le32 deliver_non_qos;
+
+	/* MPDUs received in-order */
+	__le32 deliver_in_order;
+
+	/* Flush due to reorder timer expired */
+	__le32 deliver_flush_timeout;
+
+	/* Flush due to move out of window */
+	__le32 deliver_flush_oow;
+
+	/* Flush due to DELBA */
+	__le32 deliver_flush_delba;
+
+	/* MPDUs dropped due to FCS error */
+	__le32 fcs_error;
+
+	/* MPDUs dropped due to monitor mode non-data packet */
+	__le32 mgmt_ctrl;
+
+	/* MPDUs dropped due to invalid peer */
+	__le32 invalid_peer;
+
+	/* MPDUs dropped due to duplication (non aggregation) */
+	__le32 dup_non_aggr;
+
+	/* MPDUs dropped due to processed before */
+	__le32 dup_past;
+
+	/* MPDUs dropped due to duplicate in reorder queue */
+	__le32 dup_in_reorder;
+
+	/* Reorder timeout happened */
+	__le32 reorder_timeout;
+
+	/* invalid bar ssn */
+	__le32 invalid_bar_ssn;
+
+	/* reorder reset due to bar ssn */
+	__le32 ssn_reset;
+};
+
+struct htt_dbg_stats_wal_tx_stats {
+	/* Num HTT cookies queued to dispatch list */
+	__le32 comp_queued;
+
+	/* Num HTT cookies dispatched */
+	__le32 comp_delivered;
+
+	/* Num MSDU queued to WAL */
+	__le32 msdu_enqued;
+
+	/* Num MPDU queue to WAL */
+	__le32 mpdu_enqued;
+
+	/* Num MSDUs dropped by WMM limit */
+	__le32 wmm_drop;
+
+	/* Num Local frames queued */
+	__le32 local_enqued;
+
+	/* Num Local frames done */
+	__le32 local_freed;
+
+	/* Num queued to HW */
+	__le32 hw_queued;
+
+	/* Num PPDU reaped from HW */
+	__le32 hw_reaped;
+
+	/* Num underruns */
+	__le32 underrun;
+
+	/* Num PPDUs cleaned up in TX abort */
+	__le32 tx_abort;
+
+	/* Num MPDUs requed by SW */
+	__le32 mpdus_requed;
+
+	/* excessive retries */
+	__le32 tx_ko;
+
+	/* data hw rate code */
+	__le32 data_rc;
+
+	/* Scheduler self triggers */
+	__le32 self_triggers;
+
+	/* frames dropped due to excessive sw retries */
+	__le32 sw_retry_failure;
+
+	/* illegal rate phy errors  */
+	__le32 illgl_rate_phy_err;
+
+	/* wal pdev continous xretry */
+	__le32 pdev_cont_xretry;
+
+	/* wal pdev continous xretry */
+	__le32 pdev_tx_timeout;
+
+	/* wal pdev resets  */
+	__le32 pdev_resets;
+
+	__le32 phy_underrun;
+
+	/* MPDU is more than txop limit */
+	__le32 txop_ovf;
+} __packed;
+
+struct htt_dbg_stats_wal_rx_stats {
+	/* Cnts any change in ring routing mid-ppdu */
+	__le32 mid_ppdu_route_change;
+
+	/* Total number of statuses processed */
+	__le32 status_rcvd;
+
+	/* Extra frags on rings 0-3 */
+	__le32 r0_frags;
+	__le32 r1_frags;
+	__le32 r2_frags;
+	__le32 r3_frags;
+
+	/* MSDUs / MPDUs delivered to HTT */
+	__le32 htt_msdus;
+	__le32 htt_mpdus;
+
+	/* MSDUs / MPDUs delivered to local stack */
+	__le32 loc_msdus;
+	__le32 loc_mpdus;
+
+	/* AMSDUs that have more MSDUs than the status ring size */
+	__le32 oversize_amsdu;
+
+	/* Number of PHY errors */
+	__le32 phy_errs;
+
+	/* Number of PHY errors drops */
+	__le32 phy_err_drop;
+
+	/* Number of mpdu errors - FCS, MIC, ENC etc. */
+	__le32 mpdu_errs;
+} __packed;
+
+struct htt_dbg_stats_wal_peer_stats {
+	__le32 dummy; /* REMOVE THIS ONCE REAL PEER STAT COUNTERS ARE ADDED */
+} __packed;
+
+struct htt_dbg_stats_wal_pdev_txrx {
+	struct htt_dbg_stats_wal_tx_stats tx_stats;
+	struct htt_dbg_stats_wal_rx_stats rx_stats;
+	struct htt_dbg_stats_wal_peer_stats peer_stats;
+} __packed;
+
+struct htt_dbg_stats_rx_rate_info {
+	__le32 mcs[10];
+	__le32 sgi[10];
+	__le32 nss[4];
+	__le32 stbc[10];
+	__le32 bw[3];
+	__le32 pream[6];
+	__le32 ldpc;
+	__le32 txbf;
+};
+
+/*
+ * htt_dbg_stats_status -
+ * present -     The requested stats have been delivered in full.
+ *               This indicates that either the stats information was contained
+ *               in its entirety within this message, or else this message
+ *               completes the delivery of the requested stats info that was
+ *               partially delivered through earlier STATS_CONF messages.
+ * partial -     The requested stats have been delivered in part.
+ *               One or more subsequent STATS_CONF messages with the same
+ *               cookie value will be sent to deliver the remainder of the
+ *               information.
+ * error -       The requested stats could not be delivered, for example due
+ *               to a shortage of memory to construct a message holding the
+ *               requested stats.
+ * invalid -     The requested stat type is either not recognized, or the
+ *               target is configured to not gather the stats type in question.
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * series_done - This special value indicates that no further stats info
+ *               elements are present within a series of stats info elems
+ *               (within a stats upload confirmation message).
+ */
+enum htt_dbg_stats_status {
+	HTT_DBG_STATS_STATUS_PRESENT     = 0,
+	HTT_DBG_STATS_STATUS_PARTIAL     = 1,
+	HTT_DBG_STATS_STATUS_ERROR       = 2,
+	HTT_DBG_STATS_STATUS_INVALID     = 3,
+	HTT_DBG_STATS_STATUS_SERIES_DONE = 7
+};
+
+/*
+ * target -> host statistics upload
+ *
+ * The following field definitions describe the format of the HTT target
+ * to host stats upload confirmation message.
+ * The message contains a cookie echoed from the HTT host->target stats
+ * upload request, which identifies which request the confirmation is
+ * for, and a series of tag-length-value stats information elements.
+ * The tag-length header for each stats info element also includes a
+ * status field, to indicate whether the request for the stat type in
+ * question was fully met, partially met, unable to be met, or invalid
+ * (if the stat type in question is disabled in the target).
+ * A special value of all 1's in this status field is used to indicate
+ * the end of the series of stats info elements.
+ *
+ *
+ * |31                         16|15           8|7   5|4       0|
+ * |------------------------------------------------------------|
+ * |                  reserved                  |    msg type   |
+ * |------------------------------------------------------------|
+ * |                        cookie LSBs                         |
+ * |------------------------------------------------------------|
+ * |                        cookie MSBs                         |
+ * |------------------------------------------------------------|
+ * |      stats entry length     |   reserved   |  S  |stat type|
+ * |------------------------------------------------------------|
+ * |                                                            |
+ * |                  type-specific stats info                  |
+ * |                                                            |
+ * |------------------------------------------------------------|
+ * |      stats entry length     |   reserved   |  S  |stat type|
+ * |------------------------------------------------------------|
+ * |                                                            |
+ * |                  type-specific stats info                  |
+ * |                                                            |
+ * |------------------------------------------------------------|
+ * |              n/a            |   reserved   | 111 |   n/a   |
+ * |------------------------------------------------------------|
+ * Header fields:
+ *  - MSG_TYPE
+ *    Bits 7:0
+ *    Purpose: identifies this is a statistics upload confirmation message
+ *    Value: 0x9
+ *  - COOKIE_LSBS
+ *    Bits 31:0
+ *    Purpose: Provide a mechanism to match a target->host stats confirmation
+ *        message with its preceding host->target stats request message.
+ *    Value: LSBs of the opaque cookie specified by the host-side requestor
+ *  - COOKIE_MSBS
+ *    Bits 31:0
+ *    Purpose: Provide a mechanism to match a target->host stats confirmation
+ *        message with its preceding host->target stats request message.
+ *    Value: MSBs of the opaque cookie specified by the host-side requestor
+ *
+ * Stats Information Element tag-length header fields:
+ *  - STAT_TYPE
+ *    Bits 4:0
+ *    Purpose: identifies the type of statistics info held in the
+ *        following information element
+ *    Value: htt_dbg_stats_type
+ *  - STATUS
+ *    Bits 7:5
+ *    Purpose: indicate whether the requested stats are present
+ *    Value: htt_dbg_stats_status, including a special value (0x7) to mark
+ *        the completion of the stats entry series
+ *  - LENGTH
+ *    Bits 31:16
+ *    Purpose: indicate the stats information size
+ *    Value: This field specifies the number of bytes of stats information
+ *       that follows the element tag-length header.
+ *       It is expected but not required that this length is a multiple of
+ *       4 bytes.  Even if the length is not an integer multiple of 4, the
+ *       subsequent stats entry header will begin on a 4-byte aligned
+ *       boundary.
+ */
+
+#define HTT_STATS_CONF_ITEM_INFO_STAT_TYPE_MASK 0x1F
+#define HTT_STATS_CONF_ITEM_INFO_STAT_TYPE_LSB  0
+#define HTT_STATS_CONF_ITEM_INFO_STATUS_MASK    0xE0
+#define HTT_STATS_CONF_ITEM_INFO_STATUS_LSB     5
+
+struct htt_stats_conf_item {
+	union {
+		u8 info;
+		struct {
+			u8 stat_type:5; /* %HTT_DBG_STATS_ */
+			u8 status:3; /* %HTT_DBG_STATS_STATUS_ */
+		} __packed;
+	} __packed;
+	u8 pad;
+	__le16 length;
+	u8 payload[0]; /* roundup(length, 4) long */
+} __packed;
+
+struct htt_stats_conf {
+	u8 pad[3];
+	__le32 cookie_lsb;
+	__le32 cookie_msb;
+
+	/* each item has variable length! */
+	struct htt_stats_conf_item items[0];
+} __packed;
+
+static inline struct htt_stats_conf_item *htt_stats_conf_next_item(
+					const struct htt_stats_conf_item *item)
+{
+	return (void *)item + sizeof(*item) + roundup(item->length, 4);
+}
+/*
+ * host -> target FRAG DESCRIPTOR/MSDU_EXT DESC bank
+ *
+ * The following field definitions describe the format of the HTT host
+ * to target frag_desc/msdu_ext bank configuration message.
+ * The message contains the based address and the min and max id of the
+ * MSDU_EXT/FRAG_DESC that will be used by the HTT to map MSDU DESC and
+ * MSDU_EXT/FRAG_DESC.
+ * HTT will use id in HTT descriptor instead sending the frag_desc_ptr.
+ * For QCA988X HW the firmware will use fragment_desc_ptr but in WIFI2.0
+ * the hardware does the mapping/translation.
+ *
+ * Total banks that can be configured is configured to 16.
+ *
+ * This should be called before any TX has be initiated by the HTT
+ *
+ * |31                         16|15           8|7   5|4       0|
+ * |------------------------------------------------------------|
+ * | DESC_SIZE    |  NUM_BANKS   | RES |SWP|pdev|    msg type   |
+ * |------------------------------------------------------------|
+ * |                     BANK0_BASE_ADDRESS                     |
+ * |------------------------------------------------------------|
+ * |                            ...                             |
+ * |------------------------------------------------------------|
+ * |                    BANK15_BASE_ADDRESS                     |
+ * |------------------------------------------------------------|
+ * |       BANK0_MAX_ID          |       BANK0_MIN_ID           |
+ * |------------------------------------------------------------|
+ * |                            ...                             |
+ * |------------------------------------------------------------|
+ * |       BANK15_MAX_ID         |       BANK15_MIN_ID          |
+ * |------------------------------------------------------------|
+ * Header fields:
+ *  - MSG_TYPE
+ *    Bits 7:0
+ *    Value: 0x6
+ *  - BANKx_BASE_ADDRESS
+ *    Bits 31:0
+ *    Purpose: Provide a mechanism to specify the base address of the MSDU_EXT
+ *         bank physical/bus address.
+ *  - BANKx_MIN_ID
+ *    Bits 15:0
+ *    Purpose: Provide a mechanism to specify the min index that needs to
+ *          mapped.
+ *  - BANKx_MAX_ID
+ *    Bits 31:16
+ *    Purpose: Provide a mechanism to specify the max index that needs to
+ *
+ */
+struct htt_frag_desc_bank_id {
+	__le16 bank_min_id;
+	__le16 bank_max_id;
+} __packed;
+
+/* real is 16 but it wouldn't fit in the max htt message size
+ * so we use a conservatively safe value for now */
+#define HTT_FRAG_DESC_BANK_MAX 4
+
+#define HTT_FRAG_DESC_BANK_CFG_INFO_PDEV_ID_MASK 0x03
+#define HTT_FRAG_DESC_BANK_CFG_INFO_PDEV_ID_LSB  0
+#define HTT_FRAG_DESC_BANK_CFG_INFO_SWAP         (1 << 2)
+
+struct htt_frag_desc_bank_cfg {
+	u8 info; /* HTT_FRAG_DESC_BANK_CFG_INFO_ */
+	u8 num_banks;
+	u8 desc_size;
+	__le32 bank_base_addrs[HTT_FRAG_DESC_BANK_MAX];
+	struct htt_frag_desc_bank_id bank_id[HTT_FRAG_DESC_BANK_MAX];
+} __packed;
+
+union htt_rx_pn_t {
+	/* WEP: 24-bit PN */
+	u32 pn24;
+
+	/* TKIP or CCMP: 48-bit PN */
+	u_int64_t pn48;
+
+	/* WAPI: 128-bit PN */
+	u_int64_t pn128[2];
+};
+
+struct htt_cmd {
+	struct htt_cmd_hdr hdr;
+	union {
+		struct htt_ver_req ver_req;
+		struct htt_mgmt_tx_desc mgmt_tx;
+		struct htt_data_tx_desc data_tx;
+		struct htt_rx_ring_setup rx_setup;
+		struct htt_stats_req stats_req;
+		struct htt_oob_sync_req oob_sync_req;
+		struct htt_aggr_conf aggr_conf;
+		struct htt_frag_desc_bank_cfg frag_desc_bank_cfg;
+	};
+} __packed;
+
+struct htt_resp {
+	struct htt_resp_hdr hdr;
+	union {
+		struct htt_ver_resp ver_resp;
+		struct htt_mgmt_tx_completion mgmt_tx_completion;
+		struct htt_data_tx_completion data_tx_completion;
+		struct htt_rx_indication rx_ind;
+		struct htt_rx_fragment_indication rx_frag_ind;
+		struct htt_rx_peer_map peer_map;
+		struct htt_rx_peer_unmap peer_unmap;
+		struct htt_rx_flush rx_flush;
+		struct htt_rx_addba rx_addba;
+		struct htt_rx_delba rx_delba;
+		struct htt_security_indication security_indication;
+		struct htt_rc_update rc_update;
+		struct htt_rx_test rx_test;
+		struct htt_pktlog_msg pktlog_msg;
+		struct htt_stats_conf stats_conf;
+	};
+} __packed;
+
+
+/*** host side structures follow ***/
+
+struct htt_tx_done {
+	u32 msdu_id;
+	bool discard;
+	bool no_ack;
+};
+
+struct htt_peer_map_event {
+	u8 vdev_id;
+	u16 peer_id;
+	u8 addr[ETH_ALEN];
+};
+
+struct htt_peer_unmap_event {
+	u16 peer_id;
+};
+
+struct htt_rx_info {
+	struct sk_buff *skb;
+	enum htt_rx_mpdu_status status;
+	enum htt_rx_mpdu_encrypt_type encrypt_type;
+	s8 signal;
+	struct {
+		u8 info0;
+		u32 info1;
+		u32 info2;
+	} rate;
+	bool fcs_err;
+};
+
+struct ath10k_htt {
+	struct ath10k *ar;
+	enum ath10k_htc_ep_id eid;
+
+	int max_throughput_mbps;
+	u8 target_version_major;
+	u8 target_version_minor;
+	struct completion target_version_received;
+
+	struct {
+		/*
+		 * Ring of network buffer objects - This ring is
+		 * used exclusively by the host SW. This ring
+		 * mirrors the dev_addrs_ring that is shared
+		 * between the host SW and the MAC HW. The host SW
+		 * uses this netbufs ring to locate the network
+		 * buffer objects whose data buffers the HW has
+		 * filled.
+		 */
+		struct sk_buff **netbufs_ring;
+		/*
+		 * Ring of buffer addresses -
+		 * This ring holds the "physical" device address of the
+		 * rx buffers the host SW provides for the MAC HW to
+		 * fill.
+		 */
+		__le32 *paddrs_ring;
+
+		/*
+		 * Base address of ring, as a "physical" device address
+		 * rather than a CPU address.
+		 */
+		dma_addr_t base_paddr;
+
+		/* how many elems in the ring (power of 2) */
+		int size;
+
+		/* size - 1 */
+		unsigned size_mask;
+
+		/* how many rx buffers to keep in the ring */
+		int fill_level;
+
+		/* how many rx buffers (full+empty) are in the ring */
+		int fill_cnt;
+
+		/*
+		 * alloc_idx - where HTT SW has deposited empty buffers
+		 * This is allocated in consistent mem, so that the FW can
+		 * read this variable, and program the HW's FW_IDX reg with
+		 * the value of this shadow register.
+		 */
+		struct {
+			__le32 *vaddr;
+			dma_addr_t paddr;
+		} alloc_idx;
+
+		/* where HTT SW has processed bufs filled by rx MAC DMA */
+		struct {
+			unsigned msdu_payld;
+		} sw_rd_idx;
+
+		/*
+		 * refill_retry_timer - timer triggered when the ring is
+		 * not refilled to the level expected
+		 */
+		struct timer_list refill_retry_timer;
+
+		/* Protects access to all rx ring buffer state variables */
+		spinlock_t lock;
+	} rx_ring;
+
+	unsigned int prefetch_len;
+
+	/* Protects access to %pending_tx, %used_msdu_ids */
+	spinlock_t tx_lock;
+	int max_num_pending_tx;
+	int num_pending_tx;
+	struct sk_buff **pending_tx;
+	unsigned long *used_msdu_ids; /* bitmap */
+	wait_queue_head_t empty_tx_wq;
+
+	/* set if host-fw communication goes haywire
+	 * used to avoid further failures */
+	bool rx_confused;
+};
+
+#define RX_HTT_HDR_STATUS_LEN 64
+
+/* This structure layout is programmed via rx ring setup
+ * so that FW knows how to transfer the rx descriptor to the host.
+ * Buffers like this are placed on the rx ring. */
+struct htt_rx_desc {
+	union {
+		/* This field is filled on the host using the msdu buffer
+		 * from htt_rx_indication */
+		struct fw_rx_desc_base fw_desc;
+		u32 pad;
+	} __packed;
+	struct {
+		struct rx_attention attention;
+		struct rx_frag_info frag_info;
+		struct rx_mpdu_start mpdu_start;
+		struct rx_msdu_start msdu_start;
+		struct rx_msdu_end msdu_end;
+		struct rx_mpdu_end mpdu_end;
+		struct rx_ppdu_start ppdu_start;
+		struct rx_ppdu_end ppdu_end;
+	} __packed;
+	u8 rx_hdr_status[RX_HTT_HDR_STATUS_LEN];
+	u8 msdu_payload[0];
+};
+
+#define HTT_RX_DESC_ALIGN 8
+
+#define HTT_MAC_ADDR_LEN 6
+
+/*
+ * FIX THIS
+ * Should be: sizeof(struct htt_host_rx_desc) + max rx MSDU size,
+ * rounded up to a cache line size.
+ */
+#define HTT_RX_BUF_SIZE 1920
+#define HTT_RX_MSDU_SIZE (HTT_RX_BUF_SIZE - (int)sizeof(struct htt_rx_desc))
+
+/*
+ * DMA_MAP expects the buffer to be an integral number of cache lines.
+ * Rather than checking the actual cache line size, this code makes a
+ * conservative estimate of what the cache line size could be.
+ */
+#define HTT_LOG2_MAX_CACHE_LINE_SIZE 7	/* 2^7 = 128 */
+#define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1)
+
+struct ath10k_htt *ath10k_htt_attach(struct ath10k *ar);
+int ath10k_htt_attach_target(struct ath10k_htt *htt);
+void ath10k_htt_detach(struct ath10k_htt *htt);
+
+int ath10k_htt_tx_attach(struct ath10k_htt *htt);
+void ath10k_htt_tx_detach(struct ath10k_htt *htt);
+int ath10k_htt_rx_attach(struct ath10k_htt *htt);
+void ath10k_htt_rx_detach(struct ath10k_htt *htt);
+void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb);
+void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb);
+int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt);
+int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
+
+void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
+int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt);
+void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id);
+int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *);
+int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *);
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htt_rx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htt_rx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htt_rx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htt_rx.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1167 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "htc.h"
+#include "htt.h"
+#include "txrx.h"
+#include "debug.h"
+
+#include <linux/log2.h>
+
+/* slightly larger than one large A-MPDU */
+#define HTT_RX_RING_SIZE_MIN 128
+
+/* roughly 20 ms @ 1 Gbps of 1500B MSDUs */
+#define HTT_RX_RING_SIZE_MAX 2048
+
+#define HTT_RX_AVG_FRM_BYTES 1000
+
+/* ms, very conservative */
+#define HTT_RX_HOST_LATENCY_MAX_MS 20
+
+/* ms, conservative */
+#define HTT_RX_HOST_LATENCY_WORST_LIKELY_MS 10
+
+/* when under memory pressure rx ring refill may fail and needs a retry */
+#define HTT_RX_RING_REFILL_RETRY_MS 50
+
+static int ath10k_htt_rx_ring_size(struct ath10k_htt *htt)
+{
+	int size;
+
+	/*
+	 * It is expected that the host CPU will typically be able to
+	 * service the rx indication from one A-MPDU before the rx
+	 * indication from the subsequent A-MPDU happens, roughly 1-2 ms
+	 * later. However, the rx ring should be sized very conservatively,
+	 * to accomodate the worst reasonable delay before the host CPU
+	 * services a rx indication interrupt.
+	 *
+	 * The rx ring need not be kept full of empty buffers. In theory,
+	 * the htt host SW can dynamically track the low-water mark in the
+	 * rx ring, and dynamically adjust the level to which the rx ring
+	 * is filled with empty buffers, to dynamically meet the desired
+	 * low-water mark.
+	 *
+	 * In contrast, it's difficult to resize the rx ring itself, once
+	 * it's in use. Thus, the ring itself should be sized very
+	 * conservatively, while the degree to which the ring is filled
+	 * with empty buffers should be sized moderately conservatively.
+	 */
+
+	/* 1e6 bps/mbps / 1e3 ms per sec = 1000 */
+	size =
+	    htt->max_throughput_mbps +
+	    1000  /
+	    (8 * HTT_RX_AVG_FRM_BYTES) * HTT_RX_HOST_LATENCY_MAX_MS;
+
+	if (size < HTT_RX_RING_SIZE_MIN)
+		size = HTT_RX_RING_SIZE_MIN;
+
+	if (size > HTT_RX_RING_SIZE_MAX)
+		size = HTT_RX_RING_SIZE_MAX;
+
+	size = roundup_pow_of_two(size);
+
+	return size;
+}
+
+static int ath10k_htt_rx_ring_fill_level(struct ath10k_htt *htt)
+{
+	int size;
+
+	/* 1e6 bps/mbps / 1e3 ms per sec = 1000 */
+	size =
+	    htt->max_throughput_mbps *
+	    1000  /
+	    (8 * HTT_RX_AVG_FRM_BYTES) * HTT_RX_HOST_LATENCY_WORST_LIKELY_MS;
+
+	/*
+	 * Make sure the fill level is at least 1 less than the ring size.
+	 * Leaving 1 element empty allows the SW to easily distinguish
+	 * between a full ring vs. an empty ring.
+	 */
+	if (size >= htt->rx_ring.size)
+		size = htt->rx_ring.size - 1;
+
+	return size;
+}
+
+static void ath10k_htt_rx_ring_free(struct ath10k_htt *htt)
+{
+	struct sk_buff *skb;
+	struct ath10k_skb_cb *cb;
+	int i;
+
+	for (i = 0; i < htt->rx_ring.fill_cnt; i++) {
+		skb = htt->rx_ring.netbufs_ring[i];
+		cb = ATH10K_SKB_CB(skb);
+		dma_unmap_single(htt->ar->dev, cb->paddr,
+				 skb->len + skb_tailroom(skb),
+				 DMA_FROM_DEVICE);
+		dev_kfree_skb_any(skb);
+	}
+
+	htt->rx_ring.fill_cnt = 0;
+}
+
+static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
+{
+	struct htt_rx_desc *rx_desc;
+	struct sk_buff *skb;
+	dma_addr_t paddr;
+	int ret = 0, idx;
+
+	idx = __le32_to_cpu(*(htt->rx_ring.alloc_idx.vaddr));
+	while (num > 0) {
+		skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN);
+		if (!skb) {
+			ret = -ENOMEM;
+			goto fail;
+		}
+
+		if (!IS_ALIGNED((unsigned long)skb->data, HTT_RX_DESC_ALIGN))
+			skb_pull(skb,
+				 PTR_ALIGN(skb->data, HTT_RX_DESC_ALIGN) -
+				 skb->data);
+
+		/* Clear rx_desc attention word before posting to Rx ring */
+		rx_desc = (struct htt_rx_desc *)skb->data;
+		rx_desc->attention.flags = __cpu_to_le32(0);
+
+		paddr = dma_map_single(htt->ar->dev, skb->data,
+				       skb->len + skb_tailroom(skb),
+				       DMA_FROM_DEVICE);
+
+		if (unlikely(dma_mapping_error(htt->ar->dev, paddr))) {
+			dev_kfree_skb_any(skb);
+			ret = -ENOMEM;
+			goto fail;
+		}
+
+		ATH10K_SKB_CB(skb)->paddr = paddr;
+		htt->rx_ring.netbufs_ring[idx] = skb;
+		htt->rx_ring.paddrs_ring[idx] = __cpu_to_le32(paddr);
+		htt->rx_ring.fill_cnt++;
+
+		num--;
+		idx++;
+		idx &= htt->rx_ring.size_mask;
+	}
+
+fail:
+	*(htt->rx_ring.alloc_idx.vaddr) = __cpu_to_le32(idx);
+	return ret;
+}
+
+static int ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
+{
+	lockdep_assert_held(&htt->rx_ring.lock);
+	return __ath10k_htt_rx_ring_fill_n(htt, num);
+}
+
+static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt)
+{
+	int ret, num_to_fill;
+
+	spin_lock_bh(&htt->rx_ring.lock);
+	num_to_fill = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt;
+	ret = ath10k_htt_rx_ring_fill_n(htt, num_to_fill);
+	if (ret == -ENOMEM) {
+		/*
+		 * Failed to fill it to the desired level -
+		 * we'll start a timer and try again next time.
+		 * As long as enough buffers are left in the ring for
+		 * another A-MPDU rx, no special recovery is needed.
+		 */
+		mod_timer(&htt->rx_ring.refill_retry_timer, jiffies +
+			  msecs_to_jiffies(HTT_RX_RING_REFILL_RETRY_MS));
+	}
+	spin_unlock_bh(&htt->rx_ring.lock);
+}
+
+static void ath10k_htt_rx_ring_refill_retry(unsigned long arg)
+{
+	struct ath10k_htt *htt = (struct ath10k_htt *)arg;
+	ath10k_htt_rx_msdu_buff_replenish(htt);
+}
+
+static unsigned ath10k_htt_rx_ring_elems(struct ath10k_htt *htt)
+{
+	return (__le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr) -
+		htt->rx_ring.sw_rd_idx.msdu_payld) & htt->rx_ring.size_mask;
+}
+
+void ath10k_htt_rx_detach(struct ath10k_htt *htt)
+{
+	int sw_rd_idx = htt->rx_ring.sw_rd_idx.msdu_payld;
+
+	del_timer_sync(&htt->rx_ring.refill_retry_timer);
+
+	while (sw_rd_idx != __le32_to_cpu(*(htt->rx_ring.alloc_idx.vaddr))) {
+		struct sk_buff *skb =
+				htt->rx_ring.netbufs_ring[sw_rd_idx];
+		struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
+
+		dma_unmap_single(htt->ar->dev, cb->paddr,
+				 skb->len + skb_tailroom(skb),
+				 DMA_FROM_DEVICE);
+		dev_kfree_skb_any(htt->rx_ring.netbufs_ring[sw_rd_idx]);
+		sw_rd_idx++;
+		sw_rd_idx &= htt->rx_ring.size_mask;
+	}
+
+	dma_free_coherent(htt->ar->dev,
+			  (htt->rx_ring.size *
+			   sizeof(htt->rx_ring.paddrs_ring)),
+			  htt->rx_ring.paddrs_ring,
+			  htt->rx_ring.base_paddr);
+
+	dma_free_coherent(htt->ar->dev,
+			  sizeof(*htt->rx_ring.alloc_idx.vaddr),
+			  htt->rx_ring.alloc_idx.vaddr,
+			  htt->rx_ring.alloc_idx.paddr);
+
+	kfree(htt->rx_ring.netbufs_ring);
+}
+
+static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt)
+{
+	int idx;
+	struct sk_buff *msdu;
+
+	spin_lock_bh(&htt->rx_ring.lock);
+
+	if (ath10k_htt_rx_ring_elems(htt) == 0)
+		ath10k_warn("htt rx ring is empty!\n");
+
+	idx = htt->rx_ring.sw_rd_idx.msdu_payld;
+	msdu = htt->rx_ring.netbufs_ring[idx];
+
+	idx++;
+	idx &= htt->rx_ring.size_mask;
+	htt->rx_ring.sw_rd_idx.msdu_payld = idx;
+	htt->rx_ring.fill_cnt--;
+
+	spin_unlock_bh(&htt->rx_ring.lock);
+	return msdu;
+}
+
+static void ath10k_htt_rx_free_msdu_chain(struct sk_buff *skb)
+{
+	struct sk_buff *next;
+
+	while (skb) {
+		next = skb->next;
+		dev_kfree_skb_any(skb);
+		skb = next;
+	}
+}
+
+static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
+				   u8 **fw_desc, int *fw_desc_len,
+				   struct sk_buff **head_msdu,
+				   struct sk_buff **tail_msdu)
+{
+	int msdu_len, msdu_chaining = 0;
+	struct sk_buff *msdu;
+	struct htt_rx_desc *rx_desc;
+
+	if (ath10k_htt_rx_ring_elems(htt) == 0)
+		ath10k_warn("htt rx ring is empty!\n");
+
+	if (htt->rx_confused) {
+		ath10k_warn("htt is confused. refusing rx\n");
+		return 0;
+	}
+
+	msdu = *head_msdu = ath10k_htt_rx_netbuf_pop(htt);
+	while (msdu) {
+		int last_msdu, msdu_len_invalid, msdu_chained;
+
+		dma_unmap_single(htt->ar->dev,
+				 ATH10K_SKB_CB(msdu)->paddr,
+				 msdu->len + skb_tailroom(msdu),
+				 DMA_FROM_DEVICE);
+
+		ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx: ",
+				msdu->data, msdu->len + skb_tailroom(msdu));
+
+		rx_desc = (struct htt_rx_desc *)msdu->data;
+
+		/* FIXME: we must report msdu payload since this is what caller
+		 *        expects now */
+		skb_put(msdu, offsetof(struct htt_rx_desc, msdu_payload));
+		skb_pull(msdu, offsetof(struct htt_rx_desc, msdu_payload));
+
+		/*
+		 * Sanity check - confirm the HW is finished filling in the
+		 * rx data.
+		 * If the HW and SW are working correctly, then it's guaranteed
+		 * that the HW's MAC DMA is done before this point in the SW.
+		 * To prevent the case that we handle a stale Rx descriptor,
+		 * just assert for now until we have a way to recover.
+		 */
+		if (!(__le32_to_cpu(rx_desc->attention.flags)
+				& RX_ATTENTION_FLAGS_MSDU_DONE)) {
+			ath10k_htt_rx_free_msdu_chain(*head_msdu);
+			*head_msdu = NULL;
+			msdu = NULL;
+			ath10k_err("htt rx stopped. cannot recover\n");
+			htt->rx_confused = true;
+			break;
+		}
+
+		/*
+		 * Copy the FW rx descriptor for this MSDU from the rx
+		 * indication message into the MSDU's netbuf. HL uses the
+		 * same rx indication message definition as LL, and simply
+		 * appends new info (fields from the HW rx desc, and the
+		 * MSDU payload itself). So, the offset into the rx
+		 * indication message only has to account for the standard
+		 * offset of the per-MSDU FW rx desc info within the
+		 * message, and how many bytes of the per-MSDU FW rx desc
+		 * info have already been consumed. (And the endianness of
+		 * the host, since for a big-endian host, the rx ind
+		 * message contents, including the per-MSDU rx desc bytes,
+		 * were byteswapped during upload.)
+		 */
+		if (*fw_desc_len > 0) {
+			rx_desc->fw_desc.info0 = **fw_desc;
+			/*
+			 * The target is expected to only provide the basic
+			 * per-MSDU rx descriptors. Just to be sure, verify
+			 * that the target has not attached extension data
+			 * (e.g. LRO flow ID).
+			 */
+
+			/* or more, if there's extension data */
+			(*fw_desc)++;
+			(*fw_desc_len)--;
+		} else {
+			/*
+			 * When an oversized AMSDU happened, FW will lost
+			 * some of MSDU status - in this case, the FW
+			 * descriptors provided will be less than the
+			 * actual MSDUs inside this MPDU. Mark the FW
+			 * descriptors so that it will still deliver to
+			 * upper stack, if no CRC error for this MPDU.
+			 *
+			 * FIX THIS - the FW descriptors are actually for
+			 * MSDUs in the end of this A-MSDU instead of the
+			 * beginning.
+			 */
+			rx_desc->fw_desc.info0 = 0;
+		}
+
+		msdu_len_invalid = !!(__le32_to_cpu(rx_desc->attention.flags)
+					& (RX_ATTENTION_FLAGS_MPDU_LENGTH_ERR |
+					   RX_ATTENTION_FLAGS_MSDU_LENGTH_ERR));
+		msdu_len = MS(__le32_to_cpu(rx_desc->msdu_start.info0),
+			      RX_MSDU_START_INFO0_MSDU_LENGTH);
+		msdu_chained = rx_desc->frag_info.ring2_more_count;
+
+		if (msdu_len_invalid)
+			msdu_len = 0;
+
+		skb_trim(msdu, 0);
+		skb_put(msdu, min(msdu_len, HTT_RX_MSDU_SIZE));
+		msdu_len -= msdu->len;
+
+		/* FIXME: Do chained buffers include htt_rx_desc or not? */
+		while (msdu_chained--) {
+			struct sk_buff *next = ath10k_htt_rx_netbuf_pop(htt);
+
+			dma_unmap_single(htt->ar->dev,
+					 ATH10K_SKB_CB(next)->paddr,
+					 next->len + skb_tailroom(next),
+					 DMA_FROM_DEVICE);
+
+			ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx: ",
+					next->data,
+					next->len + skb_tailroom(next));
+
+			skb_trim(next, 0);
+			skb_put(next, min(msdu_len, HTT_RX_BUF_SIZE));
+			msdu_len -= next->len;
+
+			msdu->next = next;
+			msdu = next;
+			msdu_chaining = 1;
+		}
+
+		if (msdu_len > 0) {
+			/* This may suggest FW bug? */
+			ath10k_warn("htt rx msdu len not consumed (%d)\n",
+				    msdu_len);
+		}
+
+		last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) &
+				RX_MSDU_END_INFO0_LAST_MSDU;
+
+		if (last_msdu) {
+			msdu->next = NULL;
+			break;
+		} else {
+			struct sk_buff *next = ath10k_htt_rx_netbuf_pop(htt);
+			msdu->next = next;
+			msdu = next;
+		}
+	}
+	*tail_msdu = msdu;
+
+	/*
+	 * Don't refill the ring yet.
+	 *
+	 * First, the elements popped here are still in use - it is not
+	 * safe to overwrite them until the matching call to
+	 * mpdu_desc_list_next. Second, for efficiency it is preferable to
+	 * refill the rx ring with 1 PPDU's worth of rx buffers (something
+	 * like 32 x 3 buffers), rather than one MPDU's worth of rx buffers
+	 * (something like 3 buffers). Consequently, we'll rely on the txrx
+	 * SW to tell us when it is done pulling all the PPDU's rx buffers
+	 * out of the rx ring, and then refill it just once.
+	 */
+
+	return msdu_chaining;
+}
+
+int ath10k_htt_rx_attach(struct ath10k_htt *htt)
+{
+	dma_addr_t paddr;
+	void *vaddr;
+	struct timer_list *timer = &htt->rx_ring.refill_retry_timer;
+
+	htt->rx_ring.size = ath10k_htt_rx_ring_size(htt);
+	if (!is_power_of_2(htt->rx_ring.size)) {
+		ath10k_warn("htt rx ring size is not power of 2\n");
+		return -EINVAL;
+	}
+
+	htt->rx_ring.size_mask = htt->rx_ring.size - 1;
+
+	/*
+	 * Set the initial value for the level to which the rx ring
+	 * should be filled, based on the max throughput and the
+	 * worst likely latency for the host to fill the rx ring
+	 * with new buffers. In theory, this fill level can be
+	 * dynamically adjusted from the initial value set here, to
+	 * reflect the actual host latency rather than a
+	 * conservative assumption about the host latency.
+	 */
+	htt->rx_ring.fill_level = ath10k_htt_rx_ring_fill_level(htt);
+
+	htt->rx_ring.netbufs_ring =
+		kmalloc(htt->rx_ring.size * sizeof(struct sk_buff *),
+			GFP_KERNEL);
+	if (!htt->rx_ring.netbufs_ring)
+		goto err_netbuf;
+
+	vaddr = dma_alloc_coherent(htt->ar->dev,
+		   (htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring)),
+		   &paddr, GFP_DMA);
+	if (!vaddr)
+		goto err_dma_ring;
+
+	htt->rx_ring.paddrs_ring = vaddr;
+	htt->rx_ring.base_paddr = paddr;
+
+	vaddr = dma_alloc_coherent(htt->ar->dev,
+				   sizeof(*htt->rx_ring.alloc_idx.vaddr),
+				   &paddr, GFP_DMA);
+	if (!vaddr)
+		goto err_dma_idx;
+
+	htt->rx_ring.alloc_idx.vaddr = vaddr;
+	htt->rx_ring.alloc_idx.paddr = paddr;
+	htt->rx_ring.sw_rd_idx.msdu_payld = 0;
+	*htt->rx_ring.alloc_idx.vaddr = 0;
+
+	/* Initialize the Rx refill retry timer */
+	setup_timer(timer, ath10k_htt_rx_ring_refill_retry, (unsigned long)htt);
+
+	spin_lock_init(&htt->rx_ring.lock);
+
+	htt->rx_ring.fill_cnt = 0;
+	if (__ath10k_htt_rx_ring_fill_n(htt, htt->rx_ring.fill_level))
+		goto err_fill_ring;
+
+	ath10k_dbg(ATH10K_DBG_HTT, "HTT RX ring size: %d, fill_level: %d\n",
+		   htt->rx_ring.size, htt->rx_ring.fill_level);
+	return 0;
+
+err_fill_ring:
+	ath10k_htt_rx_ring_free(htt);
+	dma_free_coherent(htt->ar->dev,
+			  sizeof(*htt->rx_ring.alloc_idx.vaddr),
+			  htt->rx_ring.alloc_idx.vaddr,
+			  htt->rx_ring.alloc_idx.paddr);
+err_dma_idx:
+	dma_free_coherent(htt->ar->dev,
+			  (htt->rx_ring.size *
+			   sizeof(htt->rx_ring.paddrs_ring)),
+			  htt->rx_ring.paddrs_ring,
+			  htt->rx_ring.base_paddr);
+err_dma_ring:
+	kfree(htt->rx_ring.netbufs_ring);
+err_netbuf:
+	return -ENOMEM;
+}
+
+static int ath10k_htt_rx_crypto_param_len(enum htt_rx_mpdu_encrypt_type type)
+{
+	switch (type) {
+	case HTT_RX_MPDU_ENCRYPT_WEP40:
+	case HTT_RX_MPDU_ENCRYPT_WEP104:
+		return 4;
+	case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC:
+	case HTT_RX_MPDU_ENCRYPT_WEP128: /* not tested */
+	case HTT_RX_MPDU_ENCRYPT_TKIP_WPA:
+	case HTT_RX_MPDU_ENCRYPT_WAPI: /* not tested */
+	case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
+		return 8;
+	case HTT_RX_MPDU_ENCRYPT_NONE:
+		return 0;
+	}
+
+	ath10k_warn("unknown encryption type %d\n", type);
+	return 0;
+}
+
+static int ath10k_htt_rx_crypto_tail_len(enum htt_rx_mpdu_encrypt_type type)
+{
+	switch (type) {
+	case HTT_RX_MPDU_ENCRYPT_NONE:
+	case HTT_RX_MPDU_ENCRYPT_WEP40:
+	case HTT_RX_MPDU_ENCRYPT_WEP104:
+	case HTT_RX_MPDU_ENCRYPT_WEP128:
+	case HTT_RX_MPDU_ENCRYPT_WAPI:
+		return 0;
+	case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC:
+	case HTT_RX_MPDU_ENCRYPT_TKIP_WPA:
+		return 4;
+	case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
+		return 8;
+	}
+
+	ath10k_warn("unknown encryption type %d\n", type);
+	return 0;
+}
+
+/* Applies for first msdu in chain, before altering it. */
+static struct ieee80211_hdr *ath10k_htt_rx_skb_get_hdr(struct sk_buff *skb)
+{
+	struct htt_rx_desc *rxd;
+	enum rx_msdu_decap_format fmt;
+
+	rxd = (void *)skb->data - sizeof(*rxd);
+	fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
+			RX_MSDU_START_INFO1_DECAP_FORMAT);
+
+	if (fmt == RX_MSDU_DECAP_RAW)
+		return (void *)skb->data;
+	else
+		return (void *)skb->data - RX_HTT_HDR_STATUS_LEN;
+}
+
+/* This function only applies for first msdu in an msdu chain */
+static bool ath10k_htt_rx_hdr_is_amsdu(struct ieee80211_hdr *hdr)
+{
+	if (ieee80211_is_data_qos(hdr->frame_control)) {
+		u8 *qc = ieee80211_get_qos_ctl(hdr);
+		if (qc[0] & 0x80)
+			return true;
+	}
+	return false;
+}
+
+static int ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
+			struct htt_rx_info *info)
+{
+	struct htt_rx_desc *rxd;
+	struct sk_buff *amsdu;
+	struct sk_buff *first;
+	struct ieee80211_hdr *hdr;
+	struct sk_buff *skb = info->skb;
+	enum rx_msdu_decap_format fmt;
+	enum htt_rx_mpdu_encrypt_type enctype;
+	unsigned int hdr_len;
+	int crypto_len;
+
+	rxd = (void *)skb->data - sizeof(*rxd);
+	fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
+			RX_MSDU_START_INFO1_DECAP_FORMAT);
+	enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
+			RX_MPDU_START_INFO0_ENCRYPT_TYPE);
+
+	/* FIXME: No idea what assumptions are safe here. Need logs */
+	if ((fmt == RX_MSDU_DECAP_RAW && skb->next) ||
+	    (fmt == RX_MSDU_DECAP_8023_SNAP_LLC)) {
+		ath10k_htt_rx_free_msdu_chain(skb->next);
+		skb->next = NULL;
+		return -ENOTSUPP;
+	}
+
+	/* A-MSDU max is a little less than 8K */
+	amsdu = dev_alloc_skb(8*1024);
+	if (!amsdu) {
+		ath10k_warn("A-MSDU allocation failed\n");
+		ath10k_htt_rx_free_msdu_chain(skb->next);
+		skb->next = NULL;
+		return -ENOMEM;
+	}
+
+	if (fmt >= RX_MSDU_DECAP_NATIVE_WIFI) {
+		int hdrlen;
+
+		hdr = (void *)rxd->rx_hdr_status;
+		hdrlen = ieee80211_hdrlen(hdr->frame_control);
+		memcpy(skb_put(amsdu, hdrlen), hdr, hdrlen);
+	}
+
+	first = skb;
+	while (skb) {
+		void *decap_hdr;
+		int decap_len = 0;
+
+		rxd = (void *)skb->data - sizeof(*rxd);
+		fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
+				RX_MSDU_START_INFO1_DECAP_FORMAT);
+		decap_hdr = (void *)rxd->rx_hdr_status;
+
+		if (skb == first) {
+			/* We receive linked A-MSDU subframe skbuffs. The
+			 * first one contains the original 802.11 header (and
+			 * possible crypto param) in the RX descriptor. The
+			 * A-MSDU subframe header follows that. Each part is
+			 * aligned to 4 byte boundary. */
+
+			hdr = (void *)amsdu->data;
+			hdr_len = ieee80211_hdrlen(hdr->frame_control);
+			crypto_len = ath10k_htt_rx_crypto_param_len(enctype);
+
+			decap_hdr += roundup(hdr_len, 4);
+			decap_hdr += roundup(crypto_len, 4);
+		}
+
+		if (fmt == RX_MSDU_DECAP_ETHERNET2_DIX) {
+			/* Ethernet2 decap inserts ethernet header in place of
+			 * A-MSDU subframe header. */
+			skb_pull(skb, 6 + 6 + 2);
+
+			/* A-MSDU subframe header length */
+			decap_len += 6 + 6 + 2;
+
+			/* Ethernet2 decap also strips the LLC/SNAP so we need
+			 * to re-insert it. The LLC/SNAP follows A-MSDU
+			 * subframe header. */
+			/* FIXME: Not all LLCs are 8 bytes long */
+			decap_len += 8;
+
+			memcpy(skb_put(amsdu, decap_len), decap_hdr, decap_len);
+		}
+
+		if (fmt == RX_MSDU_DECAP_NATIVE_WIFI) {
+			/* Native Wifi decap inserts regular 802.11 header
+			 * in place of A-MSDU subframe header. */
+			hdr = (struct ieee80211_hdr *)skb->data;
+			skb_pull(skb, ieee80211_hdrlen(hdr->frame_control));
+
+			/* A-MSDU subframe header length */
+			decap_len += 6 + 6 + 2;
+
+			memcpy(skb_put(amsdu, decap_len), decap_hdr, decap_len);
+		}
+
+		if (fmt == RX_MSDU_DECAP_RAW)
+			skb_trim(skb, skb->len - 4); /* remove FCS */
+
+		memcpy(skb_put(amsdu, skb->len), skb->data, skb->len);
+
+		/* A-MSDU subframes are padded to 4bytes
+		 * but relative to first subframe, not the whole MPDU */
+		if (skb->next && ((decap_len + skb->len) & 3)) {
+			int padlen = 4 - ((decap_len + skb->len) & 3);
+			memset(skb_put(amsdu, padlen), 0, padlen);
+		}
+
+		skb = skb->next;
+	}
+
+	info->skb = amsdu;
+	info->encrypt_type = enctype;
+
+	ath10k_htt_rx_free_msdu_chain(first);
+
+	return 0;
+}
+
+static int ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
+{
+	struct sk_buff *skb = info->skb;
+	struct htt_rx_desc *rxd;
+	struct ieee80211_hdr *hdr;
+	enum rx_msdu_decap_format fmt;
+	enum htt_rx_mpdu_encrypt_type enctype;
+
+	/* This shouldn't happen. If it does than it may be a FW bug. */
+	if (skb->next) {
+		ath10k_warn("received chained non A-MSDU frame\n");
+		ath10k_htt_rx_free_msdu_chain(skb->next);
+		skb->next = NULL;
+	}
+
+	rxd = (void *)skb->data - sizeof(*rxd);
+	fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
+			RX_MSDU_START_INFO1_DECAP_FORMAT);
+	enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
+			RX_MPDU_START_INFO0_ENCRYPT_TYPE);
+	hdr = (void *)skb->data - RX_HTT_HDR_STATUS_LEN;
+
+	switch (fmt) {
+	case RX_MSDU_DECAP_RAW:
+		/* remove trailing FCS */
+		skb_trim(skb, skb->len - 4);
+		break;
+	case RX_MSDU_DECAP_NATIVE_WIFI:
+		/* nothing to do here */
+		break;
+	case RX_MSDU_DECAP_ETHERNET2_DIX:
+		/* macaddr[6] + macaddr[6] + ethertype[2] */
+		skb_pull(skb, 6 + 6 + 2);
+		break;
+	case RX_MSDU_DECAP_8023_SNAP_LLC:
+		/* macaddr[6] + macaddr[6] + len[2] */
+		/* we don't need this for non-A-MSDU */
+		skb_pull(skb, 6 + 6 + 2);
+		break;
+	}
+
+	if (fmt == RX_MSDU_DECAP_ETHERNET2_DIX) {
+		void *llc;
+		int llclen;
+
+		llclen = 8;
+		llc  = hdr;
+		llc += roundup(ieee80211_hdrlen(hdr->frame_control), 4);
+		llc += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4);
+
+		skb_push(skb, llclen);
+		memcpy(skb->data, llc, llclen);
+	}
+
+	if (fmt >= RX_MSDU_DECAP_ETHERNET2_DIX) {
+		int len = ieee80211_hdrlen(hdr->frame_control);
+		skb_push(skb, len);
+		memcpy(skb->data, hdr, len);
+	}
+
+	info->skb = skb;
+	info->encrypt_type = enctype;
+	return 0;
+}
+
+static bool ath10k_htt_rx_has_decrypt_err(struct sk_buff *skb)
+{
+	struct htt_rx_desc *rxd;
+	u32 flags;
+
+	rxd = (void *)skb->data - sizeof(*rxd);
+	flags = __le32_to_cpu(rxd->attention.flags);
+
+	if (flags & RX_ATTENTION_FLAGS_DECRYPT_ERR)
+		return true;
+
+	return false;
+}
+
+static bool ath10k_htt_rx_has_fcs_err(struct sk_buff *skb)
+{
+	struct htt_rx_desc *rxd;
+	u32 flags;
+
+	rxd = (void *)skb->data - sizeof(*rxd);
+	flags = __le32_to_cpu(rxd->attention.flags);
+
+	if (flags & RX_ATTENTION_FLAGS_FCS_ERR)
+		return true;
+
+	return false;
+}
+
+static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
+				  struct htt_rx_indication *rx)
+{
+	struct htt_rx_info info;
+	struct htt_rx_indication_mpdu_range *mpdu_ranges;
+	struct ieee80211_hdr *hdr;
+	int num_mpdu_ranges;
+	int fw_desc_len;
+	u8 *fw_desc;
+	int i, j;
+	int ret;
+
+	memset(&info, 0, sizeof(info));
+
+	fw_desc_len = __le16_to_cpu(rx->prefix.fw_rx_desc_bytes);
+	fw_desc = (u8 *)&rx->fw_desc;
+
+	num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
+			     HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
+	mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx);
+
+	ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
+			rx, sizeof(*rx) +
+			(sizeof(struct htt_rx_indication_mpdu_range) *
+				num_mpdu_ranges));
+
+	for (i = 0; i < num_mpdu_ranges; i++) {
+		info.status = mpdu_ranges[i].mpdu_range_status;
+
+		for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
+			struct sk_buff *msdu_head, *msdu_tail;
+			enum htt_rx_mpdu_status status;
+			int msdu_chaining;
+
+			msdu_head = NULL;
+			msdu_tail = NULL;
+			msdu_chaining = ath10k_htt_rx_amsdu_pop(htt,
+							 &fw_desc,
+							 &fw_desc_len,
+							 &msdu_head,
+							 &msdu_tail);
+
+			if (!msdu_head) {
+				ath10k_warn("htt rx no data!\n");
+				continue;
+			}
+
+			if (msdu_head->len == 0) {
+				ath10k_dbg(ATH10K_DBG_HTT,
+					   "htt rx dropping due to zero-len\n");
+				ath10k_htt_rx_free_msdu_chain(msdu_head);
+				continue;
+			}
+
+			if (ath10k_htt_rx_has_decrypt_err(msdu_head)) {
+				ath10k_htt_rx_free_msdu_chain(msdu_head);
+				continue;
+			}
+
+			status = info.status;
+
+			/* Skip mgmt frames while we handle this in WMI */
+			if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL) {
+				ath10k_htt_rx_free_msdu_chain(msdu_head);
+				continue;
+			}
+
+			if (status != HTT_RX_IND_MPDU_STATUS_OK &&
+			    status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR &&
+			    !htt->ar->monitor_enabled) {
+				ath10k_dbg(ATH10K_DBG_HTT,
+					   "htt rx ignoring frame w/ status %d\n",
+					   status);
+				ath10k_htt_rx_free_msdu_chain(msdu_head);
+				continue;
+			}
+
+			/* FIXME: we do not support chaining yet.
+			 * this needs investigation */
+			if (msdu_chaining) {
+				ath10k_warn("msdu_chaining is true\n");
+				ath10k_htt_rx_free_msdu_chain(msdu_head);
+				continue;
+			}
+
+			info.skb     = msdu_head;
+			info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
+			info.signal  = ATH10K_DEFAULT_NOISE_FLOOR;
+			info.signal += rx->ppdu.combined_rssi;
+
+			info.rate.info0 = rx->ppdu.info0;
+			info.rate.info1 = __le32_to_cpu(rx->ppdu.info1);
+			info.rate.info2 = __le32_to_cpu(rx->ppdu.info2);
+
+			hdr = ath10k_htt_rx_skb_get_hdr(msdu_head);
+
+			if (ath10k_htt_rx_hdr_is_amsdu(hdr))
+				ret = ath10k_htt_rx_amsdu(htt, &info);
+			else
+				ret = ath10k_htt_rx_msdu(htt, &info);
+
+			if (ret && !info.fcs_err) {
+				ath10k_warn("error processing msdus %d\n", ret);
+				dev_kfree_skb_any(info.skb);
+				continue;
+			}
+
+			if (ath10k_htt_rx_hdr_is_amsdu((void *)info.skb->data))
+				ath10k_dbg(ATH10K_DBG_HTT, "htt mpdu is amsdu\n");
+
+			ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt mpdu: ",
+					info.skb->data, info.skb->len);
+			ath10k_process_rx(htt->ar, &info);
+		}
+	}
+
+	ath10k_htt_rx_msdu_buff_replenish(htt);
+}
+
+static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
+				struct htt_rx_fragment_indication *frag)
+{
+	struct sk_buff *msdu_head, *msdu_tail;
+	struct htt_rx_desc *rxd;
+	enum rx_msdu_decap_format fmt;
+	struct htt_rx_info info = {};
+	struct ieee80211_hdr *hdr;
+	int msdu_chaining;
+	bool tkip_mic_err;
+	bool decrypt_err;
+	u8 *fw_desc;
+	int fw_desc_len, hdrlen, paramlen;
+	int trim;
+
+	fw_desc_len = __le16_to_cpu(frag->fw_rx_desc_bytes);
+	fw_desc = (u8 *)frag->fw_msdu_rx_desc;
+
+	msdu_head = NULL;
+	msdu_tail = NULL;
+	msdu_chaining = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
+						&msdu_head, &msdu_tail);
+
+	ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");
+
+	if (!msdu_head) {
+		ath10k_warn("htt rx frag no data\n");
+		return;
+	}
+
+	if (msdu_chaining || msdu_head != msdu_tail) {
+		ath10k_warn("aggregation with fragmentation?!\n");
+		ath10k_htt_rx_free_msdu_chain(msdu_head);
+		return;
+	}
+
+	/* FIXME: implement signal strength */
+
+	hdr = (struct ieee80211_hdr *)msdu_head->data;
+	rxd = (void *)msdu_head->data - sizeof(*rxd);
+	tkip_mic_err = !!(__le32_to_cpu(rxd->attention.flags) &
+				RX_ATTENTION_FLAGS_TKIP_MIC_ERR);
+	decrypt_err = !!(__le32_to_cpu(rxd->attention.flags) &
+				RX_ATTENTION_FLAGS_DECRYPT_ERR);
+	fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
+			RX_MSDU_START_INFO1_DECAP_FORMAT);
+
+	if (fmt != RX_MSDU_DECAP_RAW) {
+		ath10k_warn("we dont support non-raw fragmented rx yet\n");
+		dev_kfree_skb_any(msdu_head);
+		goto end;
+	}
+
+	info.skb = msdu_head;
+	info.status = HTT_RX_IND_MPDU_STATUS_OK;
+	info.encrypt_type = MS(__le32_to_cpu(rxd->mpdu_start.info0),
+				RX_MPDU_START_INFO0_ENCRYPT_TYPE);
+
+	if (tkip_mic_err) {
+		ath10k_warn("tkip mic error\n");
+		info.status = HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR;
+	}
+
+	if (decrypt_err) {
+		ath10k_warn("decryption err in fragmented rx\n");
+		dev_kfree_skb_any(info.skb);
+		goto end;
+	}
+
+	if (info.encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
+		hdrlen = ieee80211_hdrlen(hdr->frame_control);
+		paramlen = ath10k_htt_rx_crypto_param_len(info.encrypt_type);
+
+		/* It is more efficient to move the header than the payload */
+		memmove((void *)info.skb->data + paramlen,
+			(void *)info.skb->data,
+			hdrlen);
+		skb_pull(info.skb, paramlen);
+		hdr = (struct ieee80211_hdr *)info.skb->data;
+	}
+
+	/* remove trailing FCS */
+	trim  = 4;
+
+	/* remove crypto trailer */
+	trim += ath10k_htt_rx_crypto_tail_len(info.encrypt_type);
+
+	/* last fragment of TKIP frags has MIC */
+	if (!ieee80211_has_morefrags(hdr->frame_control) &&
+	    info.encrypt_type == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
+		trim += 8;
+
+	if (trim > info.skb->len) {
+		ath10k_warn("htt rx fragment: trailer longer than the frame itself? drop\n");
+		dev_kfree_skb_any(info.skb);
+		goto end;
+	}
+
+	skb_trim(info.skb, info.skb->len - trim);
+
+	ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt frag mpdu: ",
+			info.skb->data, info.skb->len);
+	ath10k_process_rx(htt->ar, &info);
+
+end:
+	if (fw_desc_len > 0) {
+		ath10k_dbg(ATH10K_DBG_HTT,
+			   "expecting more fragmented rx in one indication %d\n",
+			   fw_desc_len);
+	}
+}
+
+void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct ath10k_htt *htt = ar->htt;
+	struct htt_resp *resp = (struct htt_resp *)skb->data;
+
+	/* confirm alignment */
+	if (!IS_ALIGNED((unsigned long)skb->data, 4))
+		ath10k_warn("unaligned htt message, expect trouble\n");
+
+	ath10k_dbg(ATH10K_DBG_HTT, "HTT RX, msg_type: 0x%0X\n",
+		   resp->hdr.msg_type);
+	switch (resp->hdr.msg_type) {
+	case HTT_T2H_MSG_TYPE_VERSION_CONF: {
+		htt->target_version_major = resp->ver_resp.major;
+		htt->target_version_minor = resp->ver_resp.minor;
+		complete(&htt->target_version_received);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_RX_IND: {
+		ath10k_htt_rx_handler(htt, &resp->rx_ind);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_PEER_MAP: {
+		struct htt_peer_map_event ev = {
+			.vdev_id = resp->peer_map.vdev_id,
+			.peer_id = __le16_to_cpu(resp->peer_map.peer_id),
+		};
+		memcpy(ev.addr, resp->peer_map.addr, sizeof(ev.addr));
+		ath10k_peer_map_event(htt, &ev);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_PEER_UNMAP: {
+		struct htt_peer_unmap_event ev = {
+			.peer_id = __le16_to_cpu(resp->peer_unmap.peer_id),
+		};
+		ath10k_peer_unmap_event(htt, &ev);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION: {
+		struct htt_tx_done tx_done = {};
+		int status = __le32_to_cpu(resp->mgmt_tx_completion.status);
+
+		tx_done.msdu_id =
+			__le32_to_cpu(resp->mgmt_tx_completion.desc_id);
+
+		switch (status) {
+		case HTT_MGMT_TX_STATUS_OK:
+			break;
+		case HTT_MGMT_TX_STATUS_RETRY:
+			tx_done.no_ack = true;
+			break;
+		case HTT_MGMT_TX_STATUS_DROP:
+			tx_done.discard = true;
+			break;
+		}
+
+		ath10k_txrx_tx_completed(htt, &tx_done);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_TX_COMPL_IND: {
+		struct htt_tx_done tx_done = {};
+		int status = MS(resp->data_tx_completion.flags,
+				HTT_DATA_TX_STATUS);
+		__le16 msdu_id;
+		int i;
+
+		switch (status) {
+		case HTT_DATA_TX_STATUS_NO_ACK:
+			tx_done.no_ack = true;
+			break;
+		case HTT_DATA_TX_STATUS_OK:
+			break;
+		case HTT_DATA_TX_STATUS_DISCARD:
+		case HTT_DATA_TX_STATUS_POSTPONE:
+		case HTT_DATA_TX_STATUS_DOWNLOAD_FAIL:
+			tx_done.discard = true;
+			break;
+		default:
+			ath10k_warn("unhandled tx completion status %d\n",
+				    status);
+			tx_done.discard = true;
+			break;
+		}
+
+		ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n",
+			   resp->data_tx_completion.num_msdus);
+
+		for (i = 0; i < resp->data_tx_completion.num_msdus; i++) {
+			msdu_id = resp->data_tx_completion.msdus[i];
+			tx_done.msdu_id = __le16_to_cpu(msdu_id);
+			ath10k_txrx_tx_completed(htt, &tx_done);
+		}
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_SEC_IND: {
+		struct ath10k *ar = htt->ar;
+		struct htt_security_indication *ev = &resp->security_indication;
+
+		ath10k_dbg(ATH10K_DBG_HTT,
+			   "sec ind peer_id %d unicast %d type %d\n",
+			  __le16_to_cpu(ev->peer_id),
+			  !!(ev->flags & HTT_SECURITY_IS_UNICAST),
+			  MS(ev->flags, HTT_SECURITY_TYPE));
+		complete(&ar->install_key_done);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_RX_FRAG_IND: {
+		ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
+				skb->data, skb->len);
+		ath10k_htt_rx_frag_handler(htt, &resp->rx_frag_ind);
+		break;
+	}
+	case HTT_T2H_MSG_TYPE_TEST:
+		/* FIX THIS */
+		break;
+	case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
+	case HTT_T2H_MSG_TYPE_STATS_CONF:
+	case HTT_T2H_MSG_TYPE_RX_ADDBA:
+	case HTT_T2H_MSG_TYPE_RX_DELBA:
+	case HTT_T2H_MSG_TYPE_RX_FLUSH:
+	default:
+		ath10k_dbg(ATH10K_DBG_HTT, "htt event (%d) not handled\n",
+			   resp->hdr.msg_type);
+		ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
+				skb->data, skb->len);
+		break;
+	};
+
+	/* Free the indication buffer */
+	dev_kfree_skb_any(skb);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htt_tx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htt_tx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/htt_tx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/htt_tx.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,510 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/etherdevice.h>
+#include "htt.h"
+#include "mac.h"
+#include "hif.h"
+#include "txrx.h"
+#include "debug.h"
+
+void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt)
+{
+	htt->num_pending_tx--;
+	if (htt->num_pending_tx == htt->max_num_pending_tx - 1)
+		ieee80211_wake_queues(htt->ar->hw);
+}
+
+static void ath10k_htt_tx_dec_pending(struct ath10k_htt *htt)
+{
+	spin_lock_bh(&htt->tx_lock);
+	__ath10k_htt_tx_dec_pending(htt);
+	spin_unlock_bh(&htt->tx_lock);
+}
+
+static int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt)
+{
+	int ret = 0;
+
+	spin_lock_bh(&htt->tx_lock);
+
+	if (htt->num_pending_tx >= htt->max_num_pending_tx) {
+		ret = -EBUSY;
+		goto exit;
+	}
+
+	htt->num_pending_tx++;
+	if (htt->num_pending_tx == htt->max_num_pending_tx)
+		ieee80211_stop_queues(htt->ar->hw);
+
+exit:
+	spin_unlock_bh(&htt->tx_lock);
+	return ret;
+}
+
+int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt)
+{
+	int msdu_id;
+
+	lockdep_assert_held(&htt->tx_lock);
+
+	msdu_id = find_first_zero_bit(htt->used_msdu_ids,
+				      htt->max_num_pending_tx);
+	if (msdu_id == htt->max_num_pending_tx)
+		return -ENOBUFS;
+
+	ath10k_dbg(ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", msdu_id);
+	__set_bit(msdu_id, htt->used_msdu_ids);
+	return msdu_id;
+}
+
+void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id)
+{
+	lockdep_assert_held(&htt->tx_lock);
+
+	if (!test_bit(msdu_id, htt->used_msdu_ids))
+		ath10k_warn("trying to free unallocated msdu_id %d\n", msdu_id);
+
+	ath10k_dbg(ATH10K_DBG_HTT, "htt tx free msdu_id %hu\n", msdu_id);
+	__clear_bit(msdu_id, htt->used_msdu_ids);
+}
+
+int ath10k_htt_tx_attach(struct ath10k_htt *htt)
+{
+	u8 pipe;
+
+	spin_lock_init(&htt->tx_lock);
+	init_waitqueue_head(&htt->empty_tx_wq);
+
+	/* At the beginning free queue number should hint us the maximum
+	 * queue length */
+	pipe = htt->ar->htc->endpoint[htt->eid].ul_pipe_id;
+	htt->max_num_pending_tx = ath10k_hif_get_free_queue_number(htt->ar,
+								   pipe);
+
+	ath10k_dbg(ATH10K_DBG_HTT, "htt tx max num pending tx %d\n",
+		   htt->max_num_pending_tx);
+
+	htt->pending_tx = kzalloc(sizeof(*htt->pending_tx) *
+				  htt->max_num_pending_tx, GFP_KERNEL);
+	if (!htt->pending_tx)
+		return -ENOMEM;
+
+	htt->used_msdu_ids = kzalloc(sizeof(unsigned long) *
+				     BITS_TO_LONGS(htt->max_num_pending_tx),
+				     GFP_KERNEL);
+	if (!htt->used_msdu_ids) {
+		kfree(htt->pending_tx);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void ath10k_htt_tx_cleanup_pending(struct ath10k_htt *htt)
+{
+	struct sk_buff *txdesc;
+	int msdu_id;
+
+	/* No locks needed. Called after communication with the device has
+	 * been stopped. */
+
+	for (msdu_id = 0; msdu_id < htt->max_num_pending_tx; msdu_id++) {
+		if (!test_bit(msdu_id, htt->used_msdu_ids))
+			continue;
+
+		txdesc = htt->pending_tx[msdu_id];
+		if (!txdesc)
+			continue;
+
+		ath10k_dbg(ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n",
+			   msdu_id);
+
+		if (ATH10K_SKB_CB(txdesc)->htt.refcount > 0)
+			ATH10K_SKB_CB(txdesc)->htt.refcount = 1;
+
+		ATH10K_SKB_CB(txdesc)->htt.discard = true;
+		ath10k_txrx_tx_unref(htt, txdesc);
+	}
+}
+
+void ath10k_htt_tx_detach(struct ath10k_htt *htt)
+{
+	ath10k_htt_tx_cleanup_pending(htt);
+	kfree(htt->pending_tx);
+	kfree(htt->used_msdu_ids);
+	return;
+}
+
+void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
+	struct ath10k_htt *htt = ar->htt;
+
+	if (skb_cb->htt.is_conf) {
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
+	if (skb_cb->is_aborted) {
+		skb_cb->htt.discard = true;
+
+		/* if the skbuff is aborted we need to make sure we'll free up
+		 * the tx resources, we can't simply run tx_unref() 2 times
+		 * because if htt tx completion came in earlier we'd access
+		 * unallocated memory */
+		if (skb_cb->htt.refcount > 1)
+			skb_cb->htt.refcount = 1;
+	}
+
+	ath10k_txrx_tx_unref(htt, skb);
+}
+
+int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt)
+{
+	struct sk_buff *skb;
+	struct htt_cmd *cmd;
+	int len = 0;
+	int ret;
+
+	len += sizeof(cmd->hdr);
+	len += sizeof(cmd->ver_req);
+
+	skb = ath10k_htc_alloc_skb(len);
+	if (!skb)
+		return -ENOMEM;
+
+	skb_put(skb, len);
+	cmd = (struct htt_cmd *)skb->data;
+	cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_VERSION_REQ;
+
+	ATH10K_SKB_CB(skb)->htt.is_conf = true;
+
+	ret = ath10k_htc_send(htt->ar->htc, htt->eid, skb);
+	if (ret) {
+		dev_kfree_skb_any(skb);
+		return ret;
+	}
+
+	return 0;
+}
+
+int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
+{
+	struct sk_buff *skb;
+	struct htt_cmd *cmd;
+	struct htt_rx_ring_setup_ring *ring;
+	const int num_rx_ring = 1;
+	u16 flags;
+	u32 fw_idx;
+	int len;
+	int ret;
+
+	/*
+	 * the HW expects the buffer to be an integral number of 4-byte
+	 * "words"
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED(HTT_RX_BUF_SIZE, 4));
+	BUILD_BUG_ON((HTT_RX_BUF_SIZE & HTT_MAX_CACHE_LINE_SIZE_MASK) != 0);
+
+	len = sizeof(cmd->hdr) + sizeof(cmd->rx_setup.hdr)
+	    + (sizeof(*ring) * num_rx_ring);
+	skb = ath10k_htc_alloc_skb(len);
+	if (!skb)
+		return -ENOMEM;
+
+	skb_put(skb, len);
+
+	cmd = (struct htt_cmd *)skb->data;
+	ring = &cmd->rx_setup.rings[0];
+
+	cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_RX_RING_CFG;
+	cmd->rx_setup.hdr.num_rings = 1;
+
+	/* FIXME: do we need all of this? */
+	flags = 0;
+	flags |= HTT_RX_RING_FLAGS_MAC80211_HDR;
+	flags |= HTT_RX_RING_FLAGS_MSDU_PAYLOAD;
+	flags |= HTT_RX_RING_FLAGS_PPDU_START;
+	flags |= HTT_RX_RING_FLAGS_PPDU_END;
+	flags |= HTT_RX_RING_FLAGS_MPDU_START;
+	flags |= HTT_RX_RING_FLAGS_MPDU_END;
+	flags |= HTT_RX_RING_FLAGS_MSDU_START;
+	flags |= HTT_RX_RING_FLAGS_MSDU_END;
+	flags |= HTT_RX_RING_FLAGS_RX_ATTENTION;
+	flags |= HTT_RX_RING_FLAGS_FRAG_INFO;
+	flags |= HTT_RX_RING_FLAGS_UNICAST_RX;
+	flags |= HTT_RX_RING_FLAGS_MULTICAST_RX;
+	flags |= HTT_RX_RING_FLAGS_CTRL_RX;
+	flags |= HTT_RX_RING_FLAGS_MGMT_RX;
+	flags |= HTT_RX_RING_FLAGS_NULL_RX;
+	flags |= HTT_RX_RING_FLAGS_PHY_DATA_RX;
+
+	fw_idx = __le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr);
+
+	ring->fw_idx_shadow_reg_paddr =
+		__cpu_to_le32(htt->rx_ring.alloc_idx.paddr);
+	ring->rx_ring_base_paddr = __cpu_to_le32(htt->rx_ring.base_paddr);
+	ring->rx_ring_len = __cpu_to_le16(htt->rx_ring.size);
+	ring->rx_ring_bufsize = __cpu_to_le16(HTT_RX_BUF_SIZE);
+	ring->flags = __cpu_to_le16(flags);
+	ring->fw_idx_init_val = __cpu_to_le16(fw_idx);
+
+#define desc_offset(x) (offsetof(struct htt_rx_desc, x) / 4)
+
+	ring->mac80211_hdr_offset = __cpu_to_le16(desc_offset(rx_hdr_status));
+	ring->msdu_payload_offset = __cpu_to_le16(desc_offset(msdu_payload));
+	ring->ppdu_start_offset = __cpu_to_le16(desc_offset(ppdu_start));
+	ring->ppdu_end_offset = __cpu_to_le16(desc_offset(ppdu_end));
+	ring->mpdu_start_offset = __cpu_to_le16(desc_offset(mpdu_start));
+	ring->mpdu_end_offset = __cpu_to_le16(desc_offset(mpdu_end));
+	ring->msdu_start_offset = __cpu_to_le16(desc_offset(msdu_start));
+	ring->msdu_end_offset = __cpu_to_le16(desc_offset(msdu_end));
+	ring->rx_attention_offset = __cpu_to_le16(desc_offset(attention));
+	ring->frag_info_offset = __cpu_to_le16(desc_offset(frag_info));
+
+#undef desc_offset
+
+	ATH10K_SKB_CB(skb)->htt.is_conf = true;
+
+	ret = ath10k_htc_send(htt->ar->htc, htt->eid, skb);
+	if (ret) {
+		dev_kfree_skb_any(skb);
+		return ret;
+	}
+
+	return 0;
+}
+
+int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
+{
+	struct device *dev = htt->ar->dev;
+	struct ath10k_skb_cb *skb_cb;
+	struct sk_buff *txdesc = NULL;
+	struct htt_cmd *cmd;
+	u8 vdev_id = ATH10K_SKB_CB(msdu)->htt.vdev_id;
+	int len = 0;
+	int msdu_id = -1;
+	int res;
+
+
+	res = ath10k_htt_tx_inc_pending(htt);
+	if (res)
+		return res;
+
+	len += sizeof(cmd->hdr);
+	len += sizeof(cmd->mgmt_tx);
+
+	txdesc = ath10k_htc_alloc_skb(len);
+	if (!txdesc) {
+		res = -ENOMEM;
+		goto err;
+	}
+
+	spin_lock_bh(&htt->tx_lock);
+	msdu_id = ath10k_htt_tx_alloc_msdu_id(htt);
+	if (msdu_id < 0) {
+		spin_unlock_bh(&htt->tx_lock);
+		res = msdu_id;
+		goto err;
+	}
+	htt->pending_tx[msdu_id] = txdesc;
+	spin_unlock_bh(&htt->tx_lock);
+
+	res = ath10k_skb_map(dev, msdu);
+	if (res)
+		goto err;
+
+	skb_put(txdesc, len);
+	cmd = (struct htt_cmd *)txdesc->data;
+	cmd->hdr.msg_type         = HTT_H2T_MSG_TYPE_MGMT_TX;
+	cmd->mgmt_tx.msdu_paddr = __cpu_to_le32(ATH10K_SKB_CB(msdu)->paddr);
+	cmd->mgmt_tx.len        = __cpu_to_le32(msdu->len);
+	cmd->mgmt_tx.desc_id    = __cpu_to_le32(msdu_id);
+	cmd->mgmt_tx.vdev_id    = __cpu_to_le32(vdev_id);
+	memcpy(cmd->mgmt_tx.hdr, msdu->data,
+	       min_t(int, msdu->len, HTT_MGMT_FRM_HDR_DOWNLOAD_LEN));
+
+	/* refcount is decremented by HTC and HTT completions until it reaches
+	 * zero and is freed */
+	skb_cb = ATH10K_SKB_CB(txdesc);
+	skb_cb->htt.msdu_id = msdu_id;
+	skb_cb->htt.refcount = 2;
+	skb_cb->htt.msdu = msdu;
+
+	res = ath10k_htc_send(htt->ar->htc, htt->eid, txdesc);
+	if (res)
+		goto err;
+
+	return 0;
+
+err:
+	ath10k_skb_unmap(dev, msdu);
+
+	if (txdesc)
+		dev_kfree_skb_any(txdesc);
+	if (msdu_id >= 0) {
+		spin_lock_bh(&htt->tx_lock);
+		htt->pending_tx[msdu_id] = NULL;
+		ath10k_htt_tx_free_msdu_id(htt, msdu_id);
+		spin_unlock_bh(&htt->tx_lock);
+	}
+	ath10k_htt_tx_dec_pending(htt);
+	return res;
+}
+
+int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
+{
+	struct device *dev = htt->ar->dev;
+	struct htt_cmd *cmd;
+	struct htt_data_tx_desc_frag *tx_frags;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
+	struct ath10k_skb_cb *skb_cb;
+	struct sk_buff *txdesc = NULL;
+	struct sk_buff *txfrag = NULL;
+	u8 vdev_id = ATH10K_SKB_CB(msdu)->htt.vdev_id;
+	u8 tid;
+	int prefetch_len, desc_len, frag_len;
+	dma_addr_t frags_paddr;
+	int msdu_id = -1;
+	int res;
+	u8 flags0;
+	u16 flags1;
+
+	res = ath10k_htt_tx_inc_pending(htt);
+	if (res)
+		return res;
+
+	prefetch_len = min(htt->prefetch_len, msdu->len);
+	prefetch_len = roundup(prefetch_len, 4);
+
+	desc_len = sizeof(cmd->hdr) + sizeof(cmd->data_tx) + prefetch_len;
+	frag_len = sizeof(*tx_frags) * 2;
+
+	txdesc = ath10k_htc_alloc_skb(desc_len);
+	if (!txdesc) {
+		res = -ENOMEM;
+		goto err;
+	}
+
+	txfrag = dev_alloc_skb(frag_len);
+	if (!txfrag) {
+		res = -ENOMEM;
+		goto err;
+	}
+
+	if (!IS_ALIGNED((unsigned long)txdesc->data, 4)) {
+		ath10k_warn("htt alignment check failed. dropping packet.\n");
+		res = -EIO;
+		goto err;
+	}
+
+	spin_lock_bh(&htt->tx_lock);
+	msdu_id = ath10k_htt_tx_alloc_msdu_id(htt);
+	if (msdu_id < 0) {
+		spin_unlock_bh(&htt->tx_lock);
+		res = msdu_id;
+		goto err;
+	}
+	htt->pending_tx[msdu_id] = txdesc;
+	spin_unlock_bh(&htt->tx_lock);
+
+	res = ath10k_skb_map(dev, msdu);
+	if (res)
+		goto err;
+
+	/* tx fragment list must be terminated with zero-entry */
+	skb_put(txfrag, frag_len);
+	tx_frags = (struct htt_data_tx_desc_frag *)txfrag->data;
+	tx_frags[0].paddr = __cpu_to_le32(ATH10K_SKB_CB(msdu)->paddr);
+	tx_frags[0].len   = __cpu_to_le32(msdu->len);
+	tx_frags[1].paddr = __cpu_to_le32(0);
+	tx_frags[1].len   = __cpu_to_le32(0);
+
+	res = ath10k_skb_map(dev, txfrag);
+	if (res)
+		goto err;
+
+	ath10k_dbg(ATH10K_DBG_HTT, "txfrag 0x%llx msdu 0x%llx\n",
+		   (unsigned long long) ATH10K_SKB_CB(txfrag)->paddr,
+		   (unsigned long long) ATH10K_SKB_CB(msdu)->paddr);
+	ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "txfrag: ",
+			txfrag->data, frag_len);
+	ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "msdu: ",
+			msdu->data, msdu->len);
+
+	skb_put(txdesc, desc_len);
+	cmd = (struct htt_cmd *)txdesc->data;
+	memset(cmd, 0, desc_len);
+
+	tid = ATH10K_SKB_CB(msdu)->htt.tid;
+
+	ath10k_dbg(ATH10K_DBG_HTT, "htt data tx using tid %hhu\n", tid);
+
+	flags0  = 0;
+	if (!ieee80211_has_protected(hdr->frame_control))
+		flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
+	flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
+	flags0 |= SM(ATH10K_HW_TXRX_NATIVE_WIFI,
+		     HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
+
+	flags1  = 0;
+	flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
+	flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
+
+	frags_paddr = ATH10K_SKB_CB(txfrag)->paddr;
+
+	cmd->hdr.msg_type        = HTT_H2T_MSG_TYPE_TX_FRM;
+	cmd->data_tx.flags0      = flags0;
+	cmd->data_tx.flags1      = __cpu_to_le16(flags1);
+	cmd->data_tx.len         = __cpu_to_le16(msdu->len);
+	cmd->data_tx.id          = __cpu_to_le16(msdu_id);
+	cmd->data_tx.frags_paddr = __cpu_to_le32(frags_paddr);
+	cmd->data_tx.peerid      = __cpu_to_le32(HTT_INVALID_PEERID);
+
+	memcpy(cmd->data_tx.prefetch, msdu->data, prefetch_len);
+
+	/* refcount is decremented by HTC and HTT completions until it reaches
+	 * zero and is freed */
+	skb_cb = ATH10K_SKB_CB(txdesc);
+	skb_cb->htt.msdu_id = msdu_id;
+	skb_cb->htt.refcount = 2;
+	skb_cb->htt.txfrag = txfrag;
+	skb_cb->htt.msdu = msdu;
+
+	res = ath10k_htc_send(htt->ar->htc, htt->eid, txdesc);
+	if (res)
+		goto err;
+
+	return 0;
+err:
+	if (txfrag)
+		ath10k_skb_unmap(dev, txfrag);
+	if (txdesc)
+		dev_kfree_skb_any(txdesc);
+	if (txfrag)
+		dev_kfree_skb_any(txfrag);
+	if (msdu_id >= 0) {
+		spin_lock_bh(&htt->tx_lock);
+		htt->pending_tx[msdu_id] = NULL;
+		ath10k_htt_tx_free_msdu_id(htt, msdu_id);
+		spin_unlock_bh(&htt->tx_lock);
+	}
+	ath10k_htt_tx_dec_pending(htt);
+	ath10k_skb_unmap(dev, msdu);
+	return res;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/hw.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/hw.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/hw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/hw.h	2013-08-31 17:59:26.000000000 -0400
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HW_H_
+#define _HW_H_
+
+#include "targaddrs.h"
+
+/* Supported FW version */
+#define SUPPORTED_FW_MAJOR	1
+#define SUPPORTED_FW_MINOR	0
+#define SUPPORTED_FW_RELEASE	0
+#define SUPPORTED_FW_BUILD	629
+
+/* QCA988X 1.0 definitions */
+#define QCA988X_HW_1_0_VERSION		0x4000002c
+#define QCA988X_HW_1_0_FW_DIR		"/*(DEBLOBBED)*/"
+#define QCA988X_HW_1_0_FW_FILE		"/*(DEBLOBBED)*/"
+#define QCA988X_HW_1_0_OTP_FILE		"/*(DEBLOBBED)*/"
+#define QCA988X_HW_1_0_BOARD_DATA_FILE	"/*(DEBLOBBED)*/"
+#define QCA988X_HW_1_0_PATCH_LOAD_ADDR	0x1234
+
+/* QCA988X 2.0 definitions */
+#define QCA988X_HW_2_0_VERSION		0x4100016c
+#define QCA988X_HW_2_0_FW_DIR		"/*(DEBLOBBED)*/"
+#define QCA988X_HW_2_0_FW_FILE		"/*(DEBLOBBED)*/"
+#define QCA988X_HW_2_0_OTP_FILE		"/*(DEBLOBBED)*/"
+#define QCA988X_HW_2_0_BOARD_DATA_FILE	"/*(DEBLOBBED)*/"
+#define QCA988X_HW_2_0_PATCH_LOAD_ADDR	0x1234
+
+/* Known pecularities:
+ *  - current FW doesn't support raw rx mode (last tested v599)
+ *  - current FW dumps upon raw tx mode (last tested v599)
+ *  - raw appears in nwifi decap, raw and nwifi appear in ethernet decap
+ *  - raw have FCS, nwifi doesn't
+ *  - ethernet frames have 802.11 header decapped and parts (base hdr, cipher
+ *    param, llc/snap) are aligned to 4byte boundaries each */
+enum ath10k_hw_txrx_mode {
+	ATH10K_HW_TXRX_RAW = 0,
+	ATH10K_HW_TXRX_NATIVE_WIFI = 1,
+	ATH10K_HW_TXRX_ETHERNET = 2,
+};
+
+enum ath10k_mcast2ucast_mode {
+	ATH10K_MCAST2UCAST_DISABLED = 0,
+	ATH10K_MCAST2UCAST_ENABLED = 1,
+};
+
+#define TARGET_NUM_VDEVS			8
+#define TARGET_NUM_PEER_AST			2
+#define TARGET_NUM_WDS_ENTRIES			32
+#define TARGET_DMA_BURST_SIZE			0
+#define TARGET_MAC_AGGR_DELIM			0
+#define TARGET_AST_SKID_LIMIT			16
+#define TARGET_NUM_PEERS			16
+#define TARGET_NUM_OFFLOAD_PEERS		0
+#define TARGET_NUM_OFFLOAD_REORDER_BUFS         0
+#define TARGET_NUM_PEER_KEYS			2
+#define TARGET_NUM_TIDS		(2 * ((TARGET_NUM_PEERS) + (TARGET_NUM_VDEVS)))
+#define TARGET_TX_CHAIN_MASK			(BIT(0) | BIT(1) | BIT(2))
+#define TARGET_RX_CHAIN_MASK			(BIT(0) | BIT(1) | BIT(2))
+#define TARGET_RX_TIMEOUT_LO_PRI		100
+#define TARGET_RX_TIMEOUT_HI_PRI		40
+#define TARGET_RX_DECAP_MODE			ATH10K_HW_TXRX_ETHERNET
+#define TARGET_SCAN_MAX_PENDING_REQS		4
+#define TARGET_BMISS_OFFLOAD_MAX_VDEV		3
+#define TARGET_ROAM_OFFLOAD_MAX_VDEV		3
+#define TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES	8
+#define TARGET_GTK_OFFLOAD_MAX_VDEV		3
+#define TARGET_NUM_MCAST_GROUPS			0
+#define TARGET_NUM_MCAST_TABLE_ELEMS		0
+#define TARGET_MCAST2UCAST_MODE			ATH10K_MCAST2UCAST_DISABLED
+#define TARGET_TX_DBG_LOG_SIZE			1024
+#define TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 0
+#define TARGET_VOW_CONFIG			0
+#define TARGET_NUM_MSDU_DESC			(1024 + 400)
+#define TARGET_MAX_FRAG_ENTRIES			0
+
+
+/* Number of Copy Engines supported */
+#define CE_COUNT 8
+
+/*
+ * Total number of PCIe MSI interrupts requested for all interrupt sources.
+ * PCIe standard forces this to be a power of 2.
+ * Some Host OS's limit MSI requests that can be granted to 8
+ * so for now we abide by this limit and avoid requesting more
+ * than that.
+ */
+#define MSI_NUM_REQUEST_LOG2	3
+#define MSI_NUM_REQUEST		(1<<MSI_NUM_REQUEST_LOG2)
+
+/*
+ * Granted MSIs are assigned as follows:
+ * Firmware uses the first
+ * Remaining MSIs, if any, are used by Copy Engines
+ * This mapping is known to both Target firmware and Host software.
+ * It may be changed as long as Host and Target are kept in sync.
+ */
+/* MSI for firmware (errors, etc.) */
+#define MSI_ASSIGN_FW		0
+
+/* MSIs for Copy Engines */
+#define MSI_ASSIGN_CE_INITIAL	1
+#define MSI_ASSIGN_CE_MAX	7
+
+/* as of IP3.7.1 */
+#define RTC_STATE_V_ON				3
+
+#define RTC_STATE_COLD_RESET_MASK		0x00000400
+#define RTC_STATE_V_LSB				0
+#define RTC_STATE_V_MASK			0x00000007
+#define RTC_STATE_ADDRESS			0x0000
+#define PCIE_SOC_WAKE_V_MASK			0x00000001
+#define PCIE_SOC_WAKE_ADDRESS			0x0004
+#define PCIE_SOC_WAKE_RESET			0x00000000
+#define SOC_GLOBAL_RESET_ADDRESS		0x0008
+
+#define RTC_SOC_BASE_ADDRESS			0x00004000
+#define RTC_WMAC_BASE_ADDRESS			0x00005000
+#define MAC_COEX_BASE_ADDRESS			0x00006000
+#define BT_COEX_BASE_ADDRESS			0x00007000
+#define SOC_PCIE_BASE_ADDRESS			0x00008000
+#define SOC_CORE_BASE_ADDRESS			0x00009000
+#define WLAN_UART_BASE_ADDRESS			0x0000c000
+#define WLAN_SI_BASE_ADDRESS			0x00010000
+#define WLAN_GPIO_BASE_ADDRESS			0x00014000
+#define WLAN_ANALOG_INTF_BASE_ADDRESS		0x0001c000
+#define WLAN_MAC_BASE_ADDRESS			0x00020000
+#define EFUSE_BASE_ADDRESS			0x00030000
+#define FPGA_REG_BASE_ADDRESS			0x00039000
+#define WLAN_UART2_BASE_ADDRESS			0x00054c00
+#define CE_WRAPPER_BASE_ADDRESS			0x00057000
+#define CE0_BASE_ADDRESS			0x00057400
+#define CE1_BASE_ADDRESS			0x00057800
+#define CE2_BASE_ADDRESS			0x00057c00
+#define CE3_BASE_ADDRESS			0x00058000
+#define CE4_BASE_ADDRESS			0x00058400
+#define CE5_BASE_ADDRESS			0x00058800
+#define CE6_BASE_ADDRESS			0x00058c00
+#define CE7_BASE_ADDRESS			0x00059000
+#define DBI_BASE_ADDRESS			0x00060000
+#define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS	0x0006c000
+#define PCIE_LOCAL_BASE_ADDRESS			0x00080000
+
+#define SOC_RESET_CONTROL_OFFSET		0x00000000
+#define SOC_RESET_CONTROL_SI0_RST_MASK		0x00000001
+#define SOC_CPU_CLOCK_OFFSET			0x00000020
+#define SOC_CPU_CLOCK_STANDARD_LSB		0
+#define SOC_CPU_CLOCK_STANDARD_MASK		0x00000003
+#define SOC_CLOCK_CONTROL_OFFSET		0x00000028
+#define SOC_CLOCK_CONTROL_SI0_CLK_MASK		0x00000001
+#define SOC_SYSTEM_SLEEP_OFFSET			0x000000c4
+#define SOC_LPO_CAL_OFFSET			0x000000e0
+#define SOC_LPO_CAL_ENABLE_LSB			20
+#define SOC_LPO_CAL_ENABLE_MASK			0x00100000
+
+#define WLAN_RESET_CONTROL_COLD_RST_MASK	0x00000008
+#define WLAN_RESET_CONTROL_WARM_RST_MASK	0x00000004
+#define WLAN_SYSTEM_SLEEP_DISABLE_LSB		0
+#define WLAN_SYSTEM_SLEEP_DISABLE_MASK		0x00000001
+
+#define WLAN_GPIO_PIN0_ADDRESS			0x00000028
+#define WLAN_GPIO_PIN0_CONFIG_MASK		0x00007800
+#define WLAN_GPIO_PIN1_ADDRESS			0x0000002c
+#define WLAN_GPIO_PIN1_CONFIG_MASK		0x00007800
+#define WLAN_GPIO_PIN10_ADDRESS			0x00000050
+#define WLAN_GPIO_PIN11_ADDRESS			0x00000054
+#define WLAN_GPIO_PIN12_ADDRESS			0x00000058
+#define WLAN_GPIO_PIN13_ADDRESS			0x0000005c
+
+#define CLOCK_GPIO_OFFSET			0xffffffff
+#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB		0
+#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK		0
+
+#define SI_CONFIG_OFFSET			0x00000000
+#define SI_CONFIG_BIDIR_OD_DATA_LSB		18
+#define SI_CONFIG_BIDIR_OD_DATA_MASK		0x00040000
+#define SI_CONFIG_I2C_LSB			16
+#define SI_CONFIG_I2C_MASK			0x00010000
+#define SI_CONFIG_POS_SAMPLE_LSB		7
+#define SI_CONFIG_POS_SAMPLE_MASK		0x00000080
+#define SI_CONFIG_INACTIVE_DATA_LSB		5
+#define SI_CONFIG_INACTIVE_DATA_MASK		0x00000020
+#define SI_CONFIG_INACTIVE_CLK_LSB		4
+#define SI_CONFIG_INACTIVE_CLK_MASK		0x00000010
+#define SI_CONFIG_DIVIDER_LSB			0
+#define SI_CONFIG_DIVIDER_MASK			0x0000000f
+#define SI_CS_OFFSET				0x00000004
+#define SI_CS_DONE_ERR_MASK			0x00000400
+#define SI_CS_DONE_INT_MASK			0x00000200
+#define SI_CS_START_LSB				8
+#define SI_CS_START_MASK			0x00000100
+#define SI_CS_RX_CNT_LSB			4
+#define SI_CS_RX_CNT_MASK			0x000000f0
+#define SI_CS_TX_CNT_LSB			0
+#define SI_CS_TX_CNT_MASK			0x0000000f
+
+#define SI_TX_DATA0_OFFSET			0x00000008
+#define SI_TX_DATA1_OFFSET			0x0000000c
+#define SI_RX_DATA0_OFFSET			0x00000010
+#define SI_RX_DATA1_OFFSET			0x00000014
+
+#define CORE_CTRL_CPU_INTR_MASK			0x00002000
+#define CORE_CTRL_ADDRESS			0x0000
+#define PCIE_INTR_ENABLE_ADDRESS		0x0008
+#define PCIE_INTR_CLR_ADDRESS			0x0014
+#define SCRATCH_3_ADDRESS			0x0030
+
+/* Firmware indications to the Host via SCRATCH_3 register. */
+#define FW_INDICATOR_ADDRESS	(SOC_CORE_BASE_ADDRESS + SCRATCH_3_ADDRESS)
+#define FW_IND_EVENT_PENDING			1
+#define FW_IND_INITIALIZED			2
+
+/* HOST_REG interrupt from firmware */
+#define PCIE_INTR_FIRMWARE_MASK			0x00000400
+#define PCIE_INTR_CE_MASK_ALL			0x0007f800
+
+#define DRAM_BASE_ADDRESS			0x00400000
+
+#define MISSING 0
+
+#define SYSTEM_SLEEP_OFFSET			SOC_SYSTEM_SLEEP_OFFSET
+#define WLAN_SYSTEM_SLEEP_OFFSET		SOC_SYSTEM_SLEEP_OFFSET
+#define WLAN_RESET_CONTROL_OFFSET		SOC_RESET_CONTROL_OFFSET
+#define CLOCK_CONTROL_OFFSET			SOC_CLOCK_CONTROL_OFFSET
+#define CLOCK_CONTROL_SI0_CLK_MASK		SOC_CLOCK_CONTROL_SI0_CLK_MASK
+#define RESET_CONTROL_MBOX_RST_MASK		MISSING
+#define RESET_CONTROL_SI0_RST_MASK		SOC_RESET_CONTROL_SI0_RST_MASK
+#define GPIO_BASE_ADDRESS			WLAN_GPIO_BASE_ADDRESS
+#define GPIO_PIN0_OFFSET			WLAN_GPIO_PIN0_ADDRESS
+#define GPIO_PIN1_OFFSET			WLAN_GPIO_PIN1_ADDRESS
+#define GPIO_PIN0_CONFIG_MASK			WLAN_GPIO_PIN0_CONFIG_MASK
+#define GPIO_PIN1_CONFIG_MASK			WLAN_GPIO_PIN1_CONFIG_MASK
+#define SI_BASE_ADDRESS				WLAN_SI_BASE_ADDRESS
+#define SCRATCH_BASE_ADDRESS			SOC_CORE_BASE_ADDRESS
+#define LOCAL_SCRATCH_OFFSET			0x18
+#define CPU_CLOCK_OFFSET			SOC_CPU_CLOCK_OFFSET
+#define LPO_CAL_OFFSET				SOC_LPO_CAL_OFFSET
+#define GPIO_PIN10_OFFSET			WLAN_GPIO_PIN10_ADDRESS
+#define GPIO_PIN11_OFFSET			WLAN_GPIO_PIN11_ADDRESS
+#define GPIO_PIN12_OFFSET			WLAN_GPIO_PIN12_ADDRESS
+#define GPIO_PIN13_OFFSET			WLAN_GPIO_PIN13_ADDRESS
+#define CPU_CLOCK_STANDARD_LSB			SOC_CPU_CLOCK_STANDARD_LSB
+#define CPU_CLOCK_STANDARD_MASK			SOC_CPU_CLOCK_STANDARD_MASK
+#define LPO_CAL_ENABLE_LSB			SOC_LPO_CAL_ENABLE_LSB
+#define LPO_CAL_ENABLE_MASK			SOC_LPO_CAL_ENABLE_MASK
+#define ANALOG_INTF_BASE_ADDRESS		WLAN_ANALOG_INTF_BASE_ADDRESS
+#define MBOX_BASE_ADDRESS			MISSING
+#define INT_STATUS_ENABLE_ERROR_LSB		MISSING
+#define INT_STATUS_ENABLE_ERROR_MASK		MISSING
+#define INT_STATUS_ENABLE_CPU_LSB		MISSING
+#define INT_STATUS_ENABLE_CPU_MASK		MISSING
+#define INT_STATUS_ENABLE_COUNTER_LSB		MISSING
+#define INT_STATUS_ENABLE_COUNTER_MASK		MISSING
+#define INT_STATUS_ENABLE_MBOX_DATA_LSB		MISSING
+#define INT_STATUS_ENABLE_MBOX_DATA_MASK	MISSING
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB	MISSING
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK	MISSING
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB	MISSING
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK	MISSING
+#define COUNTER_INT_STATUS_ENABLE_BIT_LSB	MISSING
+#define COUNTER_INT_STATUS_ENABLE_BIT_MASK	MISSING
+#define INT_STATUS_ENABLE_ADDRESS		MISSING
+#define CPU_INT_STATUS_ENABLE_BIT_LSB		MISSING
+#define CPU_INT_STATUS_ENABLE_BIT_MASK		MISSING
+#define HOST_INT_STATUS_ADDRESS			MISSING
+#define CPU_INT_STATUS_ADDRESS			MISSING
+#define ERROR_INT_STATUS_ADDRESS		MISSING
+#define ERROR_INT_STATUS_WAKEUP_MASK		MISSING
+#define ERROR_INT_STATUS_WAKEUP_LSB		MISSING
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK	MISSING
+#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB	MISSING
+#define ERROR_INT_STATUS_TX_OVERFLOW_MASK	MISSING
+#define ERROR_INT_STATUS_TX_OVERFLOW_LSB	MISSING
+#define COUNT_DEC_ADDRESS			MISSING
+#define HOST_INT_STATUS_CPU_MASK		MISSING
+#define HOST_INT_STATUS_CPU_LSB			MISSING
+#define HOST_INT_STATUS_ERROR_MASK		MISSING
+#define HOST_INT_STATUS_ERROR_LSB		MISSING
+#define HOST_INT_STATUS_COUNTER_MASK		MISSING
+#define HOST_INT_STATUS_COUNTER_LSB		MISSING
+#define RX_LOOKAHEAD_VALID_ADDRESS		MISSING
+#define WINDOW_DATA_ADDRESS			MISSING
+#define WINDOW_READ_ADDR_ADDRESS		MISSING
+#define WINDOW_WRITE_ADDR_ADDRESS		MISSING
+
+#define RTC_STATE_V_GET(x) (((x) & RTC_STATE_V_MASK) >> RTC_STATE_V_LSB)
+
+#endif /* _HW_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,39 @@
+config ATH10K
+        tristate "Atheros 802.11ac wireless cards support"
+        depends on MAC80211 && HAS_DMA
+	select ATH_COMMON
+        ---help---
+          This module adds support for wireless adapters based on
+          Atheros IEEE 802.11ac family of chipsets.
+
+          If you choose to build a module, it'll be called ath10k.
+
+config ATH10K_PCI
+	tristate "Atheros ath10k PCI support"
+	depends on ATH10K && PCI
+	---help---
+	  This module adds support for PCIE bus
+
+config ATH10K_DEBUG
+	bool "Atheros ath10k debugging"
+	depends on ATH10K
+	---help---
+	  Enables debug support
+
+	  If unsure, say Y to make it easier to debug problems.
+
+config ATH10K_DEBUGFS
+	bool "Atheros ath10k debugfs support"
+	depends on ATH10K
+	---help---
+	  Enabled debugfs support
+
+	  If unsure, say Y to make it easier to debug problems.
+
+config ATH10K_TRACING
+	bool "Atheros ath10k tracing support"
+	depends on ATH10K
+	depends on EVENT_TRACING
+	---help---
+	  Select this to ath10k use tracing infrastructure.
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/mac.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/mac.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/mac.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/mac.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3069 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mac.h"
+
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+
+#include "core.h"
+#include "debug.h"
+#include "wmi.h"
+#include "htt.h"
+#include "txrx.h"
+
+/**********/
+/* Crypto */
+/**********/
+
+static int ath10k_send_key(struct ath10k_vif *arvif,
+			   struct ieee80211_key_conf *key,
+			   enum set_key_cmd cmd,
+			   const u8 *macaddr)
+{
+	struct wmi_vdev_install_key_arg arg = {
+		.vdev_id = arvif->vdev_id,
+		.key_idx = key->keyidx,
+		.key_len = key->keylen,
+		.key_data = key->key,
+		.macaddr = macaddr,
+	};
+
+	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
+		arg.key_flags = WMI_KEY_PAIRWISE;
+	else
+		arg.key_flags = WMI_KEY_GROUP;
+
+	switch (key->cipher) {
+	case WLAN_CIPHER_SUITE_CCMP:
+		arg.key_cipher = WMI_CIPHER_AES_CCM;
+		key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+		break;
+	case WLAN_CIPHER_SUITE_TKIP:
+		arg.key_cipher = WMI_CIPHER_TKIP;
+		arg.key_txmic_len = 8;
+		arg.key_rxmic_len = 8;
+		break;
+	case WLAN_CIPHER_SUITE_WEP40:
+	case WLAN_CIPHER_SUITE_WEP104:
+		arg.key_cipher = WMI_CIPHER_WEP;
+		/* AP/IBSS mode requires self-key to be groupwise
+		 * Otherwise pairwise key must be set */
+		if (memcmp(macaddr, arvif->vif->addr, ETH_ALEN))
+			arg.key_flags = WMI_KEY_PAIRWISE;
+		break;
+	default:
+		ath10k_warn("cipher %d is not supported\n", key->cipher);
+		return -EOPNOTSUPP;
+	}
+
+	if (cmd == DISABLE_KEY) {
+		arg.key_cipher = WMI_CIPHER_NONE;
+		arg.key_data = NULL;
+	}
+
+	return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
+}
+
+static int ath10k_install_key(struct ath10k_vif *arvif,
+			      struct ieee80211_key_conf *key,
+			      enum set_key_cmd cmd,
+			      const u8 *macaddr)
+{
+	struct ath10k *ar = arvif->ar;
+	int ret;
+
+	INIT_COMPLETION(ar->install_key_done);
+
+	ret = ath10k_send_key(arvif, key, cmd, macaddr);
+	if (ret)
+		return ret;
+
+	ret = wait_for_completion_timeout(&ar->install_key_done, 3*HZ);
+	if (ret == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
+					const u8 *addr)
+{
+	struct ath10k *ar = arvif->ar;
+	struct ath10k_peer *peer;
+	int ret;
+	int i;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	spin_lock_bh(&ar->data_lock);
+	peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
+	spin_unlock_bh(&ar->data_lock);
+
+	if (!peer)
+		return -ENOENT;
+
+	for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
+		if (arvif->wep_keys[i] == NULL)
+			continue;
+
+		ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY,
+					 addr);
+		if (ret)
+			return ret;
+
+		peer->keys[i] = arvif->wep_keys[i];
+	}
+
+	return 0;
+}
+
+static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
+				  const u8 *addr)
+{
+	struct ath10k *ar = arvif->ar;
+	struct ath10k_peer *peer;
+	int first_errno = 0;
+	int ret;
+	int i;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	spin_lock_bh(&ar->data_lock);
+	peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
+	spin_unlock_bh(&ar->data_lock);
+
+	if (!peer)
+		return -ENOENT;
+
+	for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
+		if (peer->keys[i] == NULL)
+			continue;
+
+		ret = ath10k_install_key(arvif, peer->keys[i],
+					 DISABLE_KEY, addr);
+		if (ret && first_errno == 0)
+			first_errno = ret;
+
+		if (ret)
+			ath10k_warn("could not remove peer wep key %d (%d)\n",
+				    i, ret);
+
+		peer->keys[i] = NULL;
+	}
+
+	return first_errno;
+}
+
+static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
+				 struct ieee80211_key_conf *key)
+{
+	struct ath10k *ar = arvif->ar;
+	struct ath10k_peer *peer;
+	u8 addr[ETH_ALEN];
+	int first_errno = 0;
+	int ret;
+	int i;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	for (;;) {
+		/* since ath10k_install_key we can't hold data_lock all the
+		 * time, so we try to remove the keys incrementally */
+		spin_lock_bh(&ar->data_lock);
+		i = 0;
+		list_for_each_entry(peer, &ar->peers, list) {
+			for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
+				if (peer->keys[i] == key) {
+					memcpy(addr, peer->addr, ETH_ALEN);
+					peer->keys[i] = NULL;
+					break;
+				}
+			}
+
+			if (i < ARRAY_SIZE(peer->keys))
+				break;
+		}
+		spin_unlock_bh(&ar->data_lock);
+
+		if (i == ARRAY_SIZE(peer->keys))
+			break;
+
+		ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr);
+		if (ret && first_errno == 0)
+			first_errno = ret;
+
+		if (ret)
+			ath10k_warn("could not remove key for %pM\n", addr);
+	}
+
+	return first_errno;
+}
+
+
+/*********************/
+/* General utilities */
+/*********************/
+
+static inline enum wmi_phy_mode
+chan_to_phymode(const struct cfg80211_chan_def *chandef)
+{
+	enum wmi_phy_mode phymode = MODE_UNKNOWN;
+
+	switch (chandef->chan->band) {
+	case IEEE80211_BAND_2GHZ:
+		switch (chandef->width) {
+		case NL80211_CHAN_WIDTH_20_NOHT:
+			phymode = MODE_11G;
+			break;
+		case NL80211_CHAN_WIDTH_20:
+			phymode = MODE_11NG_HT20;
+			break;
+		case NL80211_CHAN_WIDTH_40:
+			phymode = MODE_11NG_HT40;
+			break;
+		case NL80211_CHAN_WIDTH_5:
+		case NL80211_CHAN_WIDTH_10:
+		case NL80211_CHAN_WIDTH_80:
+		case NL80211_CHAN_WIDTH_80P80:
+		case NL80211_CHAN_WIDTH_160:
+			phymode = MODE_UNKNOWN;
+			break;
+		}
+		break;
+	case IEEE80211_BAND_5GHZ:
+		switch (chandef->width) {
+		case NL80211_CHAN_WIDTH_20_NOHT:
+			phymode = MODE_11A;
+			break;
+		case NL80211_CHAN_WIDTH_20:
+			phymode = MODE_11NA_HT20;
+			break;
+		case NL80211_CHAN_WIDTH_40:
+			phymode = MODE_11NA_HT40;
+			break;
+		case NL80211_CHAN_WIDTH_80:
+			phymode = MODE_11AC_VHT80;
+			break;
+		case NL80211_CHAN_WIDTH_5:
+		case NL80211_CHAN_WIDTH_10:
+		case NL80211_CHAN_WIDTH_80P80:
+		case NL80211_CHAN_WIDTH_160:
+			phymode = MODE_UNKNOWN;
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	WARN_ON(phymode == MODE_UNKNOWN);
+	return phymode;
+}
+
+static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
+{
+/*
+ * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
+ *   0 for no restriction
+ *   1 for 1/4 us
+ *   2 for 1/2 us
+ *   3 for 1 us
+ *   4 for 2 us
+ *   5 for 4 us
+ *   6 for 8 us
+ *   7 for 16 us
+ */
+	switch (mpdudensity) {
+	case 0:
+		return 0;
+	case 1:
+	case 2:
+	case 3:
+	/* Our lower layer calculations limit our precision to
+	   1 microsecond */
+		return 1;
+	case 4:
+		return 2;
+	case 5:
+		return 4;
+	case 6:
+		return 8;
+	case 7:
+		return 16;
+	default:
+		return 0;
+	}
+}
+
+static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
+{
+	int ret;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	ret = ath10k_wmi_peer_create(ar, vdev_id, addr);
+	if (ret)
+		return ret;
+
+	ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
+{
+	int ret;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
+	if (ret)
+		return ret;
+
+	ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
+{
+	struct ath10k_peer *peer, *tmp;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	spin_lock_bh(&ar->data_lock);
+	list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
+		if (peer->vdev_id != vdev_id)
+			continue;
+
+		ath10k_warn("removing stale peer %pM from vdev_id %d\n",
+			    peer->addr, vdev_id);
+
+		list_del(&peer->list);
+		kfree(peer);
+	}
+	spin_unlock_bh(&ar->data_lock);
+}
+
+/************************/
+/* Interface management */
+/************************/
+
+static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
+{
+	int ret;
+
+	ret = wait_for_completion_timeout(&ar->vdev_setup_done,
+					  ATH10K_VDEV_SETUP_TIMEOUT_HZ);
+	if (ret == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static int ath10k_vdev_start(struct ath10k_vif *arvif)
+{
+	struct ath10k *ar = arvif->ar;
+	struct ieee80211_conf *conf = &ar->hw->conf;
+	struct ieee80211_channel *channel = conf->chandef.chan;
+	struct wmi_vdev_start_request_arg arg = {};
+	int ret = 0;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	INIT_COMPLETION(ar->vdev_setup_done);
+
+	arg.vdev_id = arvif->vdev_id;
+	arg.dtim_period = arvif->dtim_period;
+	arg.bcn_intval = arvif->beacon_interval;
+
+	arg.channel.freq = channel->center_freq;
+
+	arg.channel.band_center_freq1 = conf->chandef.center_freq1;
+
+	arg.channel.mode = chan_to_phymode(&conf->chandef);
+
+	arg.channel.min_power = channel->max_power * 3;
+	arg.channel.max_power = channel->max_power * 4;
+	arg.channel.max_reg_power = channel->max_reg_power * 4;
+	arg.channel.max_antenna_gain = channel->max_antenna_gain;
+
+	if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
+		arg.ssid = arvif->u.ap.ssid;
+		arg.ssid_len = arvif->u.ap.ssid_len;
+		arg.hidden_ssid = arvif->u.ap.hidden_ssid;
+	} else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
+		arg.ssid = arvif->vif->bss_conf.ssid;
+		arg.ssid_len = arvif->vif->bss_conf.ssid_len;
+	}
+
+	ret = ath10k_wmi_vdev_start(ar, &arg);
+	if (ret) {
+		ath10k_warn("WMI vdev start failed: ret %d\n", ret);
+		return ret;
+	}
+
+	ret = ath10k_vdev_setup_sync(ar);
+	if (ret) {
+		ath10k_warn("vdev setup failed %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int ath10k_vdev_stop(struct ath10k_vif *arvif)
+{
+	struct ath10k *ar = arvif->ar;
+	int ret;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	INIT_COMPLETION(ar->vdev_setup_done);
+
+	ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
+	if (ret) {
+		ath10k_warn("WMI vdev stop failed: ret %d\n", ret);
+		return ret;
+	}
+
+	ret = ath10k_vdev_setup_sync(ar);
+	if (ret) {
+		ath10k_warn("vdev setup failed %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int ath10k_monitor_start(struct ath10k *ar, int vdev_id)
+{
+	struct ieee80211_channel *channel = ar->hw->conf.chandef.chan;
+	struct wmi_vdev_start_request_arg arg = {};
+	enum nl80211_channel_type type;
+	int ret = 0;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	type = cfg80211_get_chandef_type(&ar->hw->conf.chandef);
+
+	arg.vdev_id = vdev_id;
+	arg.channel.freq = channel->center_freq;
+	arg.channel.band_center_freq1 = ar->hw->conf.chandef.center_freq1;
+
+	/* TODO setup this dynamically, what in case we
+	   don't have any vifs? */
+	arg.channel.mode = chan_to_phymode(&ar->hw->conf.chandef);
+
+	arg.channel.min_power = channel->max_power * 3;
+	arg.channel.max_power = channel->max_power * 4;
+	arg.channel.max_reg_power = channel->max_reg_power * 4;
+	arg.channel.max_antenna_gain = channel->max_antenna_gain;
+
+	ret = ath10k_wmi_vdev_start(ar, &arg);
+	if (ret) {
+		ath10k_warn("Monitor vdev start failed: ret %d\n", ret);
+		return ret;
+	}
+
+	ret = ath10k_vdev_setup_sync(ar);
+	if (ret) {
+		ath10k_warn("Monitor vdev setup failed %d\n", ret);
+		return ret;
+	}
+
+	ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
+	if (ret) {
+		ath10k_warn("Monitor vdev up failed: %d\n", ret);
+		goto vdev_stop;
+	}
+
+	ar->monitor_vdev_id = vdev_id;
+	ar->monitor_enabled = true;
+
+	return 0;
+
+vdev_stop:
+	ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
+	if (ret)
+		ath10k_warn("Monitor vdev stop failed: %d\n", ret);
+
+	return ret;
+}
+
+static int ath10k_monitor_stop(struct ath10k *ar)
+{
+	int ret = 0;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	/* For some reasons, ath10k_wmi_vdev_down() here couse
+	 * often ath10k_wmi_vdev_stop() to fail. Next we could
+	 * not run monitor vdev and driver reload
+	 * required. Don't see such problems we skip
+	 * ath10k_wmi_vdev_down() here.
+	 */
+
+	ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
+	if (ret)
+		ath10k_warn("Monitor vdev stop failed: %d\n", ret);
+
+	ret = ath10k_vdev_setup_sync(ar);
+	if (ret)
+		ath10k_warn("Monitor_down sync failed: %d\n", ret);
+
+	ar->monitor_enabled = false;
+	return ret;
+}
+
+static int ath10k_monitor_create(struct ath10k *ar)
+{
+	int bit, ret = 0;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	if (ar->monitor_present) {
+		ath10k_warn("Monitor mode already enabled\n");
+		return 0;
+	}
+
+	bit = ffs(ar->free_vdev_map);
+	if (bit == 0) {
+		ath10k_warn("No free VDEV slots\n");
+		return -ENOMEM;
+	}
+
+	ar->monitor_vdev_id = bit - 1;
+	ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id);
+
+	ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
+				     WMI_VDEV_TYPE_MONITOR,
+				     0, ar->mac_addr);
+	if (ret) {
+		ath10k_warn("WMI vdev monitor create failed: ret %d\n", ret);
+		goto vdev_fail;
+	}
+
+	ath10k_dbg(ATH10K_DBG_MAC, "Monitor interface created, vdev id: %d\n",
+		   ar->monitor_vdev_id);
+
+	ar->monitor_present = true;
+	return 0;
+
+vdev_fail:
+	/*
+	 * Restore the ID to the global map.
+	 */
+	ar->free_vdev_map |= 1 << (ar->monitor_vdev_id);
+	return ret;
+}
+
+static int ath10k_monitor_destroy(struct ath10k *ar)
+{
+	int ret = 0;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	if (!ar->monitor_present)
+		return 0;
+
+	ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
+	if (ret) {
+		ath10k_warn("WMI vdev monitor delete failed: %d\n", ret);
+		return ret;
+	}
+
+	ar->free_vdev_map |= 1 << (ar->monitor_vdev_id);
+	ar->monitor_present = false;
+
+	ath10k_dbg(ATH10K_DBG_MAC, "Monitor interface destroyed, vdev id: %d\n",
+		   ar->monitor_vdev_id);
+	return ret;
+}
+
+static void ath10k_control_beaconing(struct ath10k_vif *arvif,
+				struct ieee80211_bss_conf *info)
+{
+	int ret = 0;
+
+	if (!info->enable_beacon) {
+		ath10k_vdev_stop(arvif);
+		return;
+	}
+
+	arvif->tx_seq_no = 0x1000;
+
+	ret = ath10k_vdev_start(arvif);
+	if (ret)
+		return;
+
+	ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, 0, info->bssid);
+	if (ret) {
+		ath10k_warn("Failed to bring up VDEV: %d\n",
+			    arvif->vdev_id);
+		return;
+	}
+	ath10k_dbg(ATH10K_DBG_MAC, "VDEV: %d up\n", arvif->vdev_id);
+}
+
+static void ath10k_control_ibss(struct ath10k_vif *arvif,
+				struct ieee80211_bss_conf *info,
+				const u8 self_peer[ETH_ALEN])
+{
+	int ret = 0;
+
+	if (!info->ibss_joined) {
+		ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer);
+		if (ret)
+			ath10k_warn("Failed to delete IBSS self peer:%pM for VDEV:%d ret:%d\n",
+				    self_peer, arvif->vdev_id, ret);
+
+		if (is_zero_ether_addr(arvif->u.ibss.bssid))
+			return;
+
+		ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id,
+					 arvif->u.ibss.bssid);
+		if (ret) {
+			ath10k_warn("Failed to delete IBSS BSSID peer:%pM for VDEV:%d ret:%d\n",
+				    arvif->u.ibss.bssid, arvif->vdev_id, ret);
+			return;
+		}
+
+		memset(arvif->u.ibss.bssid, 0, ETH_ALEN);
+
+		return;
+	}
+
+	ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer);
+	if (ret) {
+		ath10k_warn("Failed to create IBSS self peer:%pM for VDEV:%d ret:%d\n",
+			    self_peer, arvif->vdev_id, ret);
+		return;
+	}
+
+	ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id,
+					WMI_VDEV_PARAM_ATIM_WINDOW,
+					ATH10K_DEFAULT_ATIM);
+	if (ret)
+		ath10k_warn("Failed to set IBSS ATIM for VDEV:%d ret:%d\n",
+			    arvif->vdev_id, ret);
+}
+
+/*
+ * Review this when mac80211 gains per-interface powersave support.
+ */
+static void ath10k_ps_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct ath10k_generic_iter *ar_iter = data;
+	struct ieee80211_conf *conf = &ar_iter->ar->hw->conf;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	enum wmi_sta_powersave_param param;
+	enum wmi_sta_ps_mode psmode;
+	int ret;
+
+	if (vif->type != NL80211_IFTYPE_STATION)
+		return;
+
+	if (conf->flags & IEEE80211_CONF_PS) {
+		psmode = WMI_STA_PS_MODE_ENABLED;
+		param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
+
+		ret = ath10k_wmi_set_sta_ps_param(ar_iter->ar,
+						  arvif->vdev_id,
+						  param,
+						  conf->dynamic_ps_timeout);
+		if (ret) {
+			ath10k_warn("Failed to set inactivity time for VDEV: %d\n",
+				    arvif->vdev_id);
+			return;
+		}
+
+		ar_iter->ret = ret;
+	} else {
+		psmode = WMI_STA_PS_MODE_DISABLED;
+	}
+
+	ar_iter->ret = ath10k_wmi_set_psmode(ar_iter->ar, arvif->vdev_id,
+					     psmode);
+	if (ar_iter->ret)
+		ath10k_warn("Failed to set PS Mode: %d for VDEV: %d\n",
+			    psmode, arvif->vdev_id);
+	else
+		ath10k_dbg(ATH10K_DBG_MAC, "Set PS Mode: %d for VDEV: %d\n",
+			   psmode, arvif->vdev_id);
+}
+
+/**********************/
+/* Station management */
+/**********************/
+
+static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
+				      struct ath10k_vif *arvif,
+				      struct ieee80211_sta *sta,
+				      struct ieee80211_bss_conf *bss_conf,
+				      struct wmi_peer_assoc_complete_arg *arg)
+{
+	memcpy(arg->addr, sta->addr, ETH_ALEN);
+	arg->vdev_id = arvif->vdev_id;
+	arg->peer_aid = sta->aid;
+	arg->peer_flags |= WMI_PEER_AUTH;
+
+	if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
+		/*
+		 * Seems FW have problems with Power Save in STA
+		 * mode when we setup this parameter to high (eg. 5).
+		 * Often we see that FW don't send NULL (with clean P flags)
+		 * frame even there is info about buffered frames in beacons.
+		 * Sometimes we have to wait more than 10 seconds before FW
+		 * will wakeup. Often sending one ping from AP to our device
+		 * just fail (more than 50%).
+		 *
+		 * Seems setting this FW parameter to 1 couse FW
+		 * will check every beacon and will wakup immediately
+		 * after detection buffered data.
+		 */
+		arg->peer_listen_intval = 1;
+	else
+		arg->peer_listen_intval = ar->hw->conf.listen_interval;
+
+	arg->peer_num_spatial_streams = 1;
+
+	/*
+	 * The assoc capabilities are available only in managed mode.
+	 */
+	if (arvif->vdev_type == WMI_VDEV_TYPE_STA && bss_conf)
+		arg->peer_caps = bss_conf->assoc_capability;
+}
+
+static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
+				       struct ath10k_vif *arvif,
+				       struct wmi_peer_assoc_complete_arg *arg)
+{
+	struct ieee80211_vif *vif = arvif->vif;
+	struct ieee80211_bss_conf *info = &vif->bss_conf;
+	struct cfg80211_bss *bss;
+	const u8 *rsnie = NULL;
+	const u8 *wpaie = NULL;
+
+	bss = cfg80211_get_bss(ar->hw->wiphy, ar->hw->conf.chandef.chan,
+			       info->bssid, NULL, 0, 0, 0);
+	if (bss) {
+		const struct cfg80211_bss_ies *ies;
+
+		rcu_read_lock();
+		rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
+
+		ies = rcu_dereference(bss->ies);
+
+		wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+				WLAN_OUI_TYPE_MICROSOFT_WPA,
+				ies->data,
+				ies->len);
+		rcu_read_unlock();
+		cfg80211_put_bss(ar->hw->wiphy, bss);
+	}
+
+	/* FIXME: base on RSN IE/WPA IE is a correct idea? */
+	if (rsnie || wpaie) {
+		ath10k_dbg(ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
+		arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
+	}
+
+	if (wpaie) {
+		ath10k_dbg(ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
+		arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
+	}
+}
+
+static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
+				      struct ieee80211_sta *sta,
+				      struct wmi_peer_assoc_complete_arg *arg)
+{
+	struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
+	const struct ieee80211_supported_band *sband;
+	const struct ieee80211_rate *rates;
+	u32 ratemask;
+	int i;
+
+	sband = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band];
+	ratemask = sta->supp_rates[ar->hw->conf.chandef.chan->band];
+	rates = sband->bitrates;
+
+	rateset->num_rates = 0;
+
+	for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
+		if (!(ratemask & 1))
+			continue;
+
+		rateset->rates[rateset->num_rates] = rates->hw_value;
+		rateset->num_rates++;
+	}
+}
+
+static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
+				   struct ieee80211_sta *sta,
+				   struct wmi_peer_assoc_complete_arg *arg)
+{
+	const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
+	int smps;
+	int i, n;
+
+	if (!ht_cap->ht_supported)
+		return;
+
+	arg->peer_flags |= WMI_PEER_HT;
+	arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
+				    ht_cap->ampdu_factor)) - 1;
+
+	arg->peer_mpdu_density =
+		ath10k_parse_mpdudensity(ht_cap->ampdu_density);
+
+	arg->peer_ht_caps = ht_cap->cap;
+	arg->peer_rate_caps |= WMI_RC_HT_FLAG;
+
+	if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
+		arg->peer_flags |= WMI_PEER_LDPC;
+
+	if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
+		arg->peer_flags |= WMI_PEER_40MHZ;
+		arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
+	}
+
+	if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
+		arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
+
+	if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
+		arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
+
+	if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
+		arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
+		arg->peer_flags |= WMI_PEER_STBC;
+	}
+
+	if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
+		u32 stbc;
+		stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
+		stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
+		stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
+		arg->peer_rate_caps |= stbc;
+		arg->peer_flags |= WMI_PEER_STBC;
+	}
+
+	smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
+	smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
+
+	if (smps == WLAN_HT_CAP_SM_PS_STATIC) {
+		arg->peer_flags |= WMI_PEER_SPATIAL_MUX;
+		arg->peer_flags |= WMI_PEER_STATIC_MIMOPS;
+	} else if (smps == WLAN_HT_CAP_SM_PS_DYNAMIC) {
+		arg->peer_flags |= WMI_PEER_SPATIAL_MUX;
+		arg->peer_flags |= WMI_PEER_DYN_MIMOPS;
+	}
+
+	if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
+		arg->peer_rate_caps |= WMI_RC_TS_FLAG;
+	else if (ht_cap->mcs.rx_mask[1])
+		arg->peer_rate_caps |= WMI_RC_DS_FLAG;
+
+	for (i = 0, n = 0; i < IEEE80211_HT_MCS_MASK_LEN*8; i++)
+		if (ht_cap->mcs.rx_mask[i/8] & (1 << i%8))
+			arg->peer_ht_rates.rates[n++] = i;
+
+	arg->peer_ht_rates.num_rates = n;
+	arg->peer_num_spatial_streams = max((n+7) / 8, 1);
+
+	ath10k_dbg(ATH10K_DBG_MAC, "mcs cnt %d nss %d\n",
+		   arg->peer_ht_rates.num_rates,
+		   arg->peer_num_spatial_streams);
+}
+
+static void ath10k_peer_assoc_h_qos_ap(struct ath10k *ar,
+				       struct ath10k_vif *arvif,
+				       struct ieee80211_sta *sta,
+				       struct ieee80211_bss_conf *bss_conf,
+				       struct wmi_peer_assoc_complete_arg *arg)
+{
+	u32 uapsd = 0;
+	u32 max_sp = 0;
+
+	if (sta->wme)
+		arg->peer_flags |= WMI_PEER_QOS;
+
+	if (sta->wme && sta->uapsd_queues) {
+		ath10k_dbg(ATH10K_DBG_MAC, "uapsd_queues: 0x%X, max_sp: %d\n",
+			   sta->uapsd_queues, sta->max_sp);
+
+		arg->peer_flags |= WMI_PEER_APSD;
+		arg->peer_flags |= WMI_RC_UAPSD_FLAG;
+
+		if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
+			uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
+				 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
+		if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
+			uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
+				 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
+		if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
+			uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
+				 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
+		if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
+			uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
+				 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
+
+
+		if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
+			max_sp = sta->max_sp;
+
+		ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
+					   sta->addr,
+					   WMI_AP_PS_PEER_PARAM_UAPSD,
+					   uapsd);
+
+		ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
+					   sta->addr,
+					   WMI_AP_PS_PEER_PARAM_MAX_SP,
+					   max_sp);
+
+		/* TODO setup this based on STA listen interval and
+		   beacon interval. Currently we don't know
+		   sta->listen_interval - mac80211 patch required.
+		   Currently use 10 seconds */
+		ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
+					   sta->addr,
+					   WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
+					   10);
+	}
+}
+
+static void ath10k_peer_assoc_h_qos_sta(struct ath10k *ar,
+					struct ath10k_vif *arvif,
+					struct ieee80211_sta *sta,
+					struct ieee80211_bss_conf *bss_conf,
+					struct wmi_peer_assoc_complete_arg *arg)
+{
+	if (bss_conf->qos)
+		arg->peer_flags |= WMI_PEER_QOS;
+}
+
+static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
+				    struct ieee80211_sta *sta,
+				    struct wmi_peer_assoc_complete_arg *arg)
+{
+	const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+
+	if (!vht_cap->vht_supported)
+		return;
+
+	arg->peer_flags |= WMI_PEER_VHT;
+
+	arg->peer_vht_caps = vht_cap->cap;
+
+	if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
+		arg->peer_flags |= WMI_PEER_80MHZ;
+
+	arg->peer_vht_rates.rx_max_rate =
+		__le16_to_cpu(vht_cap->vht_mcs.rx_highest);
+	arg->peer_vht_rates.rx_mcs_set =
+		__le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
+	arg->peer_vht_rates.tx_max_rate =
+		__le16_to_cpu(vht_cap->vht_mcs.tx_highest);
+	arg->peer_vht_rates.tx_mcs_set =
+		__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
+
+	ath10k_dbg(ATH10K_DBG_MAC, "mac vht peer\n");
+}
+
+static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
+				    struct ath10k_vif *arvif,
+				    struct ieee80211_sta *sta,
+				    struct ieee80211_bss_conf *bss_conf,
+				    struct wmi_peer_assoc_complete_arg *arg)
+{
+	switch (arvif->vdev_type) {
+	case WMI_VDEV_TYPE_AP:
+		ath10k_peer_assoc_h_qos_ap(ar, arvif, sta, bss_conf, arg);
+		break;
+	case WMI_VDEV_TYPE_STA:
+		ath10k_peer_assoc_h_qos_sta(ar, arvif, sta, bss_conf, arg);
+		break;
+	default:
+		break;
+	}
+}
+
+static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
+					struct ath10k_vif *arvif,
+					struct ieee80211_sta *sta,
+					struct wmi_peer_assoc_complete_arg *arg)
+{
+	enum wmi_phy_mode phymode = MODE_UNKNOWN;
+
+	/* FIXME: add VHT */
+
+	switch (ar->hw->conf.chandef.chan->band) {
+	case IEEE80211_BAND_2GHZ:
+		if (sta->ht_cap.ht_supported) {
+			if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
+				phymode = MODE_11NG_HT40;
+			else
+				phymode = MODE_11NG_HT20;
+		} else {
+			phymode = MODE_11G;
+		}
+
+		break;
+	case IEEE80211_BAND_5GHZ:
+		if (sta->ht_cap.ht_supported) {
+			if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
+				phymode = MODE_11NA_HT40;
+			else
+				phymode = MODE_11NA_HT20;
+		} else {
+			phymode = MODE_11A;
+		}
+
+		break;
+	default:
+		break;
+	}
+
+	arg->peer_phymode = phymode;
+	WARN_ON(phymode == MODE_UNKNOWN);
+}
+
+static int ath10k_peer_assoc(struct ath10k *ar,
+			     struct ath10k_vif *arvif,
+			     struct ieee80211_sta *sta,
+			     struct ieee80211_bss_conf *bss_conf)
+{
+	struct wmi_peer_assoc_complete_arg arg;
+
+	memset(&arg, 0, sizeof(struct wmi_peer_assoc_complete_arg));
+
+	ath10k_peer_assoc_h_basic(ar, arvif, sta, bss_conf, &arg);
+	ath10k_peer_assoc_h_crypto(ar, arvif, &arg);
+	ath10k_peer_assoc_h_rates(ar, sta, &arg);
+	ath10k_peer_assoc_h_ht(ar, sta, &arg);
+	ath10k_peer_assoc_h_vht(ar, sta, &arg);
+	ath10k_peer_assoc_h_qos(ar, arvif, sta, bss_conf, &arg);
+	ath10k_peer_assoc_h_phymode(ar, arvif, sta, &arg);
+
+	return ath10k_wmi_peer_assoc(ar, &arg);
+}
+
+/* can be called only in mac80211 callbacks due to `key_count` usage */
+static void ath10k_bss_assoc(struct ieee80211_hw *hw,
+			     struct ieee80211_vif *vif,
+			     struct ieee80211_bss_conf *bss_conf)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	struct ieee80211_sta *ap_sta;
+	int ret;
+
+	rcu_read_lock();
+
+	ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
+	if (!ap_sta) {
+		ath10k_warn("Failed to find station entry for %pM\n",
+			    bss_conf->bssid);
+		rcu_read_unlock();
+		return;
+	}
+
+	ret = ath10k_peer_assoc(ar, arvif, ap_sta, bss_conf);
+	if (ret) {
+		ath10k_warn("Peer assoc failed for %pM\n", bss_conf->bssid);
+		rcu_read_unlock();
+		return;
+	}
+
+	rcu_read_unlock();
+
+	ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, bss_conf->aid,
+				 bss_conf->bssid);
+	if (ret)
+		ath10k_warn("VDEV: %d up failed: ret %d\n",
+			    arvif->vdev_id, ret);
+	else
+		ath10k_dbg(ATH10K_DBG_MAC,
+			   "VDEV: %d associated, BSSID: %pM, AID: %d\n",
+			   arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
+}
+
+/*
+ * FIXME: flush TIDs
+ */
+static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
+				struct ieee80211_vif *vif)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	int ret;
+
+	/*
+	 * For some reason, calling VDEV-DOWN before VDEV-STOP
+	 * makes the FW to send frames via HTT after disassociation.
+	 * No idea why this happens, even though VDEV-DOWN is supposed
+	 * to be analogous to link down, so just stop the VDEV.
+	 */
+	ret = ath10k_vdev_stop(arvif);
+	if (!ret)
+		ath10k_dbg(ATH10K_DBG_MAC, "VDEV: %d stopped\n",
+			   arvif->vdev_id);
+
+	/*
+	 * If we don't call VDEV-DOWN after VDEV-STOP FW will remain active and
+	 * report beacons from previously associated network through HTT.
+	 * This in turn would spam mac80211 WARN_ON if we bring down all
+	 * interfaces as it expects there is no rx when no interface is
+	 * running.
+	 */
+	ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
+	if (ret)
+		ath10k_dbg(ATH10K_DBG_MAC, "VDEV: %d ath10k_wmi_vdev_down failed (%d)\n",
+			   arvif->vdev_id, ret);
+
+	ath10k_wmi_flush_tx(ar);
+
+	arvif->def_wep_key_index = 0;
+}
+
+static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
+				struct ieee80211_sta *sta)
+{
+	int ret = 0;
+
+	ret = ath10k_peer_assoc(ar, arvif, sta, NULL);
+	if (ret) {
+		ath10k_warn("WMI peer assoc failed for %pM\n", sta->addr);
+		return ret;
+	}
+
+	ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
+	if (ret) {
+		ath10k_warn("could not install peer wep keys (%d)\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif,
+				   struct ieee80211_sta *sta)
+{
+	int ret = 0;
+
+	ret = ath10k_clear_peer_keys(arvif, sta->addr);
+	if (ret) {
+		ath10k_warn("could not clear all peer wep keys (%d)\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+/**************/
+/* Regulatory */
+/**************/
+
+static int ath10k_update_channel_list(struct ath10k *ar)
+{
+	struct ieee80211_hw *hw = ar->hw;
+	struct ieee80211_supported_band **bands;
+	enum ieee80211_band band;
+	struct ieee80211_channel *channel;
+	struct wmi_scan_chan_list_arg arg = {0};
+	struct wmi_channel_arg *ch;
+	bool passive;
+	int len;
+	int ret;
+	int i;
+
+	bands = hw->wiphy->bands;
+	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+		if (!bands[band])
+			continue;
+
+		for (i = 0; i < bands[band]->n_channels; i++) {
+			if (bands[band]->channels[i].flags &
+			    IEEE80211_CHAN_DISABLED)
+				continue;
+
+			arg.n_channels++;
+		}
+	}
+
+	len = sizeof(struct wmi_channel_arg) * arg.n_channels;
+	arg.channels = kzalloc(len, GFP_KERNEL);
+	if (!arg.channels)
+		return -ENOMEM;
+
+	ch = arg.channels;
+	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+		if (!bands[band])
+			continue;
+
+		for (i = 0; i < bands[band]->n_channels; i++) {
+			channel = &bands[band]->channels[i];
+
+			if (channel->flags & IEEE80211_CHAN_DISABLED)
+				continue;
+
+			ch->allow_ht   = true;
+
+			/* FIXME: when should we really allow VHT? */
+			ch->allow_vht = true;
+
+			ch->allow_ibss =
+				!(channel->flags & IEEE80211_CHAN_NO_IBSS);
+
+			ch->ht40plus =
+				!(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
+
+			passive = channel->flags & IEEE80211_CHAN_PASSIVE_SCAN;
+			ch->passive = passive;
+
+			ch->freq = channel->center_freq;
+			ch->min_power = channel->max_power * 3;
+			ch->max_power = channel->max_power * 4;
+			ch->max_reg_power = channel->max_reg_power * 4;
+			ch->max_antenna_gain = channel->max_antenna_gain;
+			ch->reg_class_id = 0; /* FIXME */
+
+			/* FIXME: why use only legacy modes, why not any
+			 * HT/VHT modes? Would that even make any
+			 * difference? */
+			if (channel->band == IEEE80211_BAND_2GHZ)
+				ch->mode = MODE_11G;
+			else
+				ch->mode = MODE_11A;
+
+			if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
+				continue;
+
+			ath10k_dbg(ATH10K_DBG_WMI,
+				   "%s: [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
+				   __func__, ch - arg.channels, arg.n_channels,
+				   ch->freq, ch->max_power, ch->max_reg_power,
+				   ch->max_antenna_gain, ch->mode);
+
+			ch++;
+		}
+	}
+
+	ret = ath10k_wmi_scan_chan_list(ar, &arg);
+	kfree(arg.channels);
+
+	return ret;
+}
+
+static void ath10k_reg_notifier(struct wiphy *wiphy,
+				struct regulatory_request *request)
+{
+	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+	struct reg_dmn_pair_mapping *regpair;
+	struct ath10k *ar = hw->priv;
+	int ret;
+
+	ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
+
+	ret = ath10k_update_channel_list(ar);
+	if (ret)
+		ath10k_warn("could not update channel list (%d)\n", ret);
+
+	regpair = ar->ath_common.regulatory.regpair;
+	/* Target allows setting up per-band regdomain but ath_common provides
+	 * a combined one only */
+	ret = ath10k_wmi_pdev_set_regdomain(ar,
+					    regpair->regDmnEnum,
+					    regpair->regDmnEnum, /* 2ghz */
+					    regpair->regDmnEnum, /* 5ghz */
+					    regpair->reg_2ghz_ctl,
+					    regpair->reg_5ghz_ctl);
+	if (ret)
+		ath10k_warn("could not set pdev regdomain (%d)\n", ret);
+}
+
+/***************/
+/* TX handlers */
+/***************/
+
+/*
+ * Frames sent to the FW have to be in "Native Wifi" format.
+ * Strip the QoS field from the 802.11 header.
+ */
+static void ath10k_tx_h_qos_workaround(struct ieee80211_hw *hw,
+				       struct ieee80211_tx_control *control,
+				       struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (void *)skb->data;
+	u8 *qos_ctl;
+
+	if (!ieee80211_is_data_qos(hdr->frame_control))
+		return;
+
+	qos_ctl = ieee80211_get_qos_ctl(hdr);
+	memmove(qos_ctl, qos_ctl + IEEE80211_QOS_CTL_LEN,
+		skb->len - ieee80211_hdrlen(hdr->frame_control));
+	skb_trim(skb, skb->len - IEEE80211_QOS_CTL_LEN);
+}
+
+static void ath10k_tx_h_update_wep_key(struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_vif *vif = info->control.vif;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	struct ath10k *ar = arvif->ar;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_key_conf *key = info->control.hw_key;
+	int ret;
+
+	/* TODO AP mode should be implemented */
+	if (vif->type != NL80211_IFTYPE_STATION)
+		return;
+
+	if (!ieee80211_has_protected(hdr->frame_control))
+		return;
+
+	if (!key)
+		return;
+
+	if (key->cipher != WLAN_CIPHER_SUITE_WEP40 &&
+	    key->cipher != WLAN_CIPHER_SUITE_WEP104)
+		return;
+
+	if (key->keyidx == arvif->def_wep_key_index)
+		return;
+
+	ath10k_dbg(ATH10K_DBG_MAC, "new wep keyidx will be %d\n", key->keyidx);
+
+	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
+					WMI_VDEV_PARAM_DEF_KEYID,
+					key->keyidx);
+	if (ret) {
+		ath10k_warn("could not update wep keyidx (%d)\n", ret);
+		return;
+	}
+
+	arvif->def_wep_key_index = key->keyidx;
+}
+
+static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_vif *vif = info->control.vif;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+
+	/* This is case only for P2P_GO */
+	if (arvif->vdev_type != WMI_VDEV_TYPE_AP ||
+	    arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
+		return;
+
+	if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
+		spin_lock_bh(&ar->data_lock);
+		if (arvif->u.ap.noa_data)
+			if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
+					      GFP_ATOMIC))
+				memcpy(skb_put(skb, arvif->u.ap.noa_len),
+				       arvif->u.ap.noa_data,
+				       arvif->u.ap.noa_len);
+		spin_unlock_bh(&ar->data_lock);
+	}
+}
+
+static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	int ret;
+
+	if (ieee80211_is_mgmt(hdr->frame_control))
+		ret = ath10k_htt_mgmt_tx(ar->htt, skb);
+	else if (ieee80211_is_nullfunc(hdr->frame_control))
+		/* FW does not report tx status properly for NullFunc frames
+		 * unless they are sent through mgmt tx path. mac80211 sends
+		 * those frames when it detects link/beacon loss and depends on
+		 * the tx status to be correct. */
+		ret = ath10k_htt_mgmt_tx(ar->htt, skb);
+	else
+		ret = ath10k_htt_tx(ar->htt, skb);
+
+	if (ret) {
+		ath10k_warn("tx failed (%d). dropping packet.\n", ret);
+		ieee80211_free_txskb(ar->hw, skb);
+	}
+}
+
+void ath10k_offchan_tx_purge(struct ath10k *ar)
+{
+	struct sk_buff *skb;
+
+	for (;;) {
+		skb = skb_dequeue(&ar->offchan_tx_queue);
+		if (!skb)
+			break;
+
+		ieee80211_free_txskb(ar->hw, skb);
+	}
+}
+
+void ath10k_offchan_tx_work(struct work_struct *work)
+{
+	struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
+	struct ath10k_peer *peer;
+	struct ieee80211_hdr *hdr;
+	struct sk_buff *skb;
+	const u8 *peer_addr;
+	int vdev_id;
+	int ret;
+
+	/* FW requirement: We must create a peer before FW will send out
+	 * an offchannel frame. Otherwise the frame will be stuck and
+	 * never transmitted. We delete the peer upon tx completion.
+	 * It is unlikely that a peer for offchannel tx will already be
+	 * present. However it may be in some rare cases so account for that.
+	 * Otherwise we might remove a legitimate peer and break stuff. */
+
+	for (;;) {
+		skb = skb_dequeue(&ar->offchan_tx_queue);
+		if (!skb)
+			break;
+
+		mutex_lock(&ar->conf_mutex);
+
+		ath10k_dbg(ATH10K_DBG_MAC, "processing offchannel skb %p\n",
+			   skb);
+
+		hdr = (struct ieee80211_hdr *)skb->data;
+		peer_addr = ieee80211_get_DA(hdr);
+		vdev_id = ATH10K_SKB_CB(skb)->htt.vdev_id;
+
+		spin_lock_bh(&ar->data_lock);
+		peer = ath10k_peer_find(ar, vdev_id, peer_addr);
+		spin_unlock_bh(&ar->data_lock);
+
+		if (peer)
+			ath10k_dbg(ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
+				   peer_addr, vdev_id);
+
+		if (!peer) {
+			ret = ath10k_peer_create(ar, vdev_id, peer_addr);
+			if (ret)
+				ath10k_warn("peer %pM on vdev %d not created (%d)\n",
+					    peer_addr, vdev_id, ret);
+		}
+
+		spin_lock_bh(&ar->data_lock);
+		INIT_COMPLETION(ar->offchan_tx_completed);
+		ar->offchan_tx_skb = skb;
+		spin_unlock_bh(&ar->data_lock);
+
+		ath10k_tx_htt(ar, skb);
+
+		ret = wait_for_completion_timeout(&ar->offchan_tx_completed,
+						  3 * HZ);
+		if (ret <= 0)
+			ath10k_warn("timed out waiting for offchannel skb %p\n",
+				    skb);
+
+		if (!peer) {
+			ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
+			if (ret)
+				ath10k_warn("peer %pM on vdev %d not deleted (%d)\n",
+					    peer_addr, vdev_id, ret);
+		}
+
+		mutex_unlock(&ar->conf_mutex);
+	}
+}
+
+/************/
+/* Scanning */
+/************/
+
+/*
+ * This gets called if we dont get a heart-beat during scan.
+ * This may indicate the FW has hung and we need to abort the
+ * scan manually to prevent cancel_hw_scan() from deadlocking
+ */
+void ath10k_reset_scan(unsigned long ptr)
+{
+	struct ath10k *ar = (struct ath10k *)ptr;
+
+	spin_lock_bh(&ar->data_lock);
+	if (!ar->scan.in_progress) {
+		spin_unlock_bh(&ar->data_lock);
+		return;
+	}
+
+	ath10k_warn("scan timeout. resetting. fw issue?\n");
+
+	if (ar->scan.is_roc)
+		ieee80211_remain_on_channel_expired(ar->hw);
+	else
+		ieee80211_scan_completed(ar->hw, 1 /* aborted */);
+
+	ar->scan.in_progress = false;
+	complete_all(&ar->scan.completed);
+	spin_unlock_bh(&ar->data_lock);
+}
+
+static int ath10k_abort_scan(struct ath10k *ar)
+{
+	struct wmi_stop_scan_arg arg = {
+		.req_id = 1, /* FIXME */
+		.req_type = WMI_SCAN_STOP_ONE,
+		.u.scan_id = ATH10K_SCAN_ID,
+	};
+	int ret;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	del_timer_sync(&ar->scan.timeout);
+
+	spin_lock_bh(&ar->data_lock);
+	if (!ar->scan.in_progress) {
+		spin_unlock_bh(&ar->data_lock);
+		return 0;
+	}
+
+	ar->scan.aborting = true;
+	spin_unlock_bh(&ar->data_lock);
+
+	ret = ath10k_wmi_stop_scan(ar, &arg);
+	if (ret) {
+		ath10k_warn("could not submit wmi stop scan (%d)\n", ret);
+		return -EIO;
+	}
+
+	ath10k_wmi_flush_tx(ar);
+
+	ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ);
+	if (ret == 0)
+		ath10k_warn("timed out while waiting for scan to stop\n");
+
+	/* scan completion may be done right after we timeout here, so let's
+	 * check the in_progress and tell mac80211 scan is completed. if we
+	 * don't do that and FW fails to send us scan completion indication
+	 * then userspace won't be able to scan anymore */
+	ret = 0;
+
+	spin_lock_bh(&ar->data_lock);
+	if (ar->scan.in_progress) {
+		ath10k_warn("could not stop scan. its still in progress\n");
+		ar->scan.in_progress = false;
+		ath10k_offchan_tx_purge(ar);
+		ret = -ETIMEDOUT;
+	}
+	spin_unlock_bh(&ar->data_lock);
+
+	return ret;
+}
+
+static int ath10k_start_scan(struct ath10k *ar,
+			     const struct wmi_start_scan_arg *arg)
+{
+	int ret;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	ret = ath10k_wmi_start_scan(ar, arg);
+	if (ret)
+		return ret;
+
+	/* make sure we submit the command so the completion
+	* timeout makes sense */
+	ath10k_wmi_flush_tx(ar);
+
+	ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ);
+	if (ret == 0) {
+		ath10k_abort_scan(ar);
+		return ret;
+	}
+
+	/* the scan can complete earlier, before we even
+	 * start the timer. in that case the timer handler
+	 * checks ar->scan.in_progress and bails out if its
+	 * false. Add a 200ms margin to account event/command
+	 * processing. */
+	mod_timer(&ar->scan.timeout, jiffies +
+		  msecs_to_jiffies(arg->max_scan_time+200));
+	return 0;
+}
+
+/**********************/
+/* mac80211 callbacks */
+/**********************/
+
+static void ath10k_tx(struct ieee80211_hw *hw,
+		      struct ieee80211_tx_control *control,
+		      struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = NULL;
+	u32 vdev_id = 0;
+	u8 tid;
+
+	if (info->control.vif) {
+		arvif = ath10k_vif_to_arvif(info->control.vif);
+		vdev_id = arvif->vdev_id;
+	} else if (ar->monitor_enabled) {
+		vdev_id = ar->monitor_vdev_id;
+	}
+
+	/* We should disable CCK RATE due to P2P */
+	if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
+		ath10k_dbg(ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
+
+	/* we must calculate tid before we apply qos workaround
+	 * as we'd lose the qos control field */
+	tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
+	if (ieee80211_is_data_qos(hdr->frame_control) &&
+	    is_unicast_ether_addr(ieee80211_get_DA(hdr))) {
+		u8 *qc = ieee80211_get_qos_ctl(hdr);
+		tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+	}
+
+	ath10k_tx_h_qos_workaround(hw, control, skb);
+	ath10k_tx_h_update_wep_key(skb);
+	ath10k_tx_h_add_p2p_noa_ie(ar, skb);
+	ath10k_tx_h_seq_no(skb);
+
+	memset(ATH10K_SKB_CB(skb), 0, sizeof(*ATH10K_SKB_CB(skb)));
+	ATH10K_SKB_CB(skb)->htt.vdev_id = vdev_id;
+	ATH10K_SKB_CB(skb)->htt.tid = tid;
+
+	if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
+		spin_lock_bh(&ar->data_lock);
+		ATH10K_SKB_CB(skb)->htt.is_offchan = true;
+		ATH10K_SKB_CB(skb)->htt.vdev_id = ar->scan.vdev_id;
+		spin_unlock_bh(&ar->data_lock);
+
+		ath10k_dbg(ATH10K_DBG_MAC, "queued offchannel skb %p\n", skb);
+
+		skb_queue_tail(&ar->offchan_tx_queue, skb);
+		ieee80211_queue_work(hw, &ar->offchan_tx_work);
+		return;
+	}
+
+	ath10k_tx_htt(ar, skb);
+}
+
+/*
+ * Initialize various parameters with default vaules.
+ */
+static int ath10k_start(struct ieee80211_hw *hw)
+{
+	struct ath10k *ar = hw->priv;
+	int ret;
+
+	ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 1);
+	if (ret)
+		ath10k_warn("could not enable WMI_PDEV_PARAM_PMF_QOS (%d)\n",
+			    ret);
+
+	ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_DYNAMIC_BW, 0);
+	if (ret)
+		ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n",
+			    ret);
+
+	return 0;
+}
+
+static void ath10k_stop(struct ieee80211_hw *hw)
+{
+	struct ath10k *ar = hw->priv;
+
+	/* avoid leaks in case FW never confirms scan for offchannel */
+	cancel_work_sync(&ar->offchan_tx_work);
+	ath10k_offchan_tx_purge(ar);
+}
+
+static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
+{
+	struct ath10k_generic_iter ar_iter;
+	struct ath10k *ar = hw->priv;
+	struct ieee80211_conf *conf = &hw->conf;
+	int ret = 0;
+	u32 flags;
+
+	mutex_lock(&ar->conf_mutex);
+
+	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+		ath10k_dbg(ATH10K_DBG_MAC, "Config channel %d mhz\n",
+			   conf->chandef.chan->center_freq);
+		spin_lock_bh(&ar->data_lock);
+		ar->rx_channel = conf->chandef.chan;
+		spin_unlock_bh(&ar->data_lock);
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter));
+		ar_iter.ar = ar;
+		flags = IEEE80211_IFACE_ITER_RESUME_ALL;
+
+		ieee80211_iterate_active_interfaces_atomic(hw,
+							   flags,
+							   ath10k_ps_iter,
+							   &ar_iter);
+
+		ret = ar_iter.ret;
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+		if (conf->flags & IEEE80211_CONF_MONITOR)
+			ret = ath10k_monitor_create(ar);
+		else
+			ret = ath10k_monitor_destroy(ar);
+	}
+
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+/*
+ * TODO:
+ * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
+ * because we will send mgmt frames without CCK. This requirement
+ * for P2P_FIND/GO_NEG should be handled by checking CCK flag
+ * in the TX packet.
+ */
+static int ath10k_add_interface(struct ieee80211_hw *hw,
+				struct ieee80211_vif *vif)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	enum wmi_sta_powersave_param param;
+	int ret = 0;
+	u32 value;
+	int bit;
+
+	mutex_lock(&ar->conf_mutex);
+
+	arvif->ar = ar;
+	arvif->vif = vif;
+
+	if ((vif->type == NL80211_IFTYPE_MONITOR) && ar->monitor_present) {
+		ath10k_warn("Only one monitor interface allowed\n");
+		ret = -EBUSY;
+		goto exit;
+	}
+
+	bit = ffs(ar->free_vdev_map);
+	if (bit == 0) {
+		ret = -EBUSY;
+		goto exit;
+	}
+
+	arvif->vdev_id = bit - 1;
+	arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
+	ar->free_vdev_map &= ~(1 << arvif->vdev_id);
+
+	if (ar->p2p)
+		arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
+
+	switch (vif->type) {
+	case NL80211_IFTYPE_UNSPECIFIED:
+	case NL80211_IFTYPE_STATION:
+		arvif->vdev_type = WMI_VDEV_TYPE_STA;
+		if (vif->p2p)
+			arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT;
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
+		break;
+	case NL80211_IFTYPE_AP:
+		arvif->vdev_type = WMI_VDEV_TYPE_AP;
+
+		if (vif->p2p)
+			arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO;
+		break;
+	case NL80211_IFTYPE_MONITOR:
+		arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
+		break;
+	default:
+		WARN_ON(1);
+		break;
+	}
+
+	ath10k_dbg(ATH10K_DBG_MAC, "Add interface: id %d type %d subtype %d\n",
+		   arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype);
+
+	ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
+				     arvif->vdev_subtype, vif->addr);
+	if (ret) {
+		ath10k_warn("WMI vdev create failed: ret %d\n", ret);
+		goto exit;
+	}
+
+	ret = ath10k_wmi_vdev_set_param(ar, 0, WMI_VDEV_PARAM_DEF_KEYID,
+					arvif->def_wep_key_index);
+	if (ret)
+		ath10k_warn("Failed to set default keyid: %d\n", ret);
+
+	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
+					WMI_VDEV_PARAM_TX_ENCAP_TYPE,
+					ATH10K_HW_TXRX_NATIVE_WIFI);
+	if (ret)
+		ath10k_warn("Failed to set TX encap: %d\n", ret);
+
+	if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
+		ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr);
+		if (ret) {
+			ath10k_warn("Failed to create peer for AP: %d\n", ret);
+			goto exit;
+		}
+	}
+
+	if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
+		param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
+		value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
+		ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
+						  param, value);
+		if (ret)
+			ath10k_warn("Failed to set RX wake policy: %d\n", ret);
+
+		param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
+		value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
+		ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
+						  param, value);
+		if (ret)
+			ath10k_warn("Failed to set TX wake thresh: %d\n", ret);
+
+		param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
+		value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
+		ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
+						  param, value);
+		if (ret)
+			ath10k_warn("Failed to set PSPOLL count: %d\n", ret);
+	}
+
+	if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
+		ar->monitor_present = true;
+
+exit:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+static void ath10k_remove_interface(struct ieee80211_hw *hw,
+				    struct ieee80211_vif *vif)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	int ret;
+
+	mutex_lock(&ar->conf_mutex);
+
+	ath10k_dbg(ATH10K_DBG_MAC, "Remove interface: id %d\n", arvif->vdev_id);
+
+	ar->free_vdev_map |= 1 << (arvif->vdev_id);
+
+	if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
+		ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr);
+		if (ret)
+			ath10k_warn("Failed to remove peer for AP: %d\n", ret);
+
+		kfree(arvif->u.ap.noa_data);
+	}
+
+	ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
+	if (ret)
+		ath10k_warn("WMI vdev delete failed: %d\n", ret);
+
+	if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
+		ar->monitor_present = false;
+
+	ath10k_peer_cleanup(ar, arvif->vdev_id);
+
+	mutex_unlock(&ar->conf_mutex);
+}
+
+/*
+ * FIXME: Has to be verified.
+ */
+#define SUPPORTED_FILTERS			\
+	(FIF_PROMISC_IN_BSS |			\
+	FIF_ALLMULTI |				\
+	FIF_CONTROL |				\
+	FIF_PSPOLL |				\
+	FIF_OTHER_BSS |				\
+	FIF_BCN_PRBRESP_PROMISC |		\
+	FIF_PROBE_REQ |				\
+	FIF_FCSFAIL)
+
+static void ath10k_configure_filter(struct ieee80211_hw *hw,
+				    unsigned int changed_flags,
+				    unsigned int *total_flags,
+				    u64 multicast)
+{
+	struct ath10k *ar = hw->priv;
+	int ret;
+
+	mutex_lock(&ar->conf_mutex);
+
+	changed_flags &= SUPPORTED_FILTERS;
+	*total_flags &= SUPPORTED_FILTERS;
+	ar->filter_flags = *total_flags;
+
+	if ((ar->filter_flags & FIF_PROMISC_IN_BSS) &&
+	    !ar->monitor_enabled) {
+		ret = ath10k_monitor_start(ar, ar->monitor_vdev_id);
+		if (ret)
+			ath10k_warn("Unable to start monitor mode\n");
+		else
+			ath10k_dbg(ATH10K_DBG_MAC, "Monitor mode started\n");
+	} else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) &&
+		   ar->monitor_enabled) {
+		ret = ath10k_monitor_stop(ar);
+		if (ret)
+			ath10k_warn("Unable to stop monitor mode\n");
+		else
+			ath10k_dbg(ATH10K_DBG_MAC, "Monitor mode stopped\n");
+	}
+
+	mutex_unlock(&ar->conf_mutex);
+}
+
+static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
+				    struct ieee80211_vif *vif,
+				    struct ieee80211_bss_conf *info,
+				    u32 changed)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	int ret = 0;
+
+	mutex_lock(&ar->conf_mutex);
+
+	if (changed & BSS_CHANGED_IBSS)
+		ath10k_control_ibss(arvif, info, vif->addr);
+
+	if (changed & BSS_CHANGED_BEACON_INT) {
+		arvif->beacon_interval = info->beacon_int;
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
+						WMI_VDEV_PARAM_BEACON_INTERVAL,
+						arvif->beacon_interval);
+		if (ret)
+			ath10k_warn("Failed to set beacon interval for VDEV: %d\n",
+				    arvif->vdev_id);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Beacon interval: %d set for VDEV: %d\n",
+				   arvif->beacon_interval, arvif->vdev_id);
+	}
+
+	if (changed & BSS_CHANGED_BEACON) {
+		ret = ath10k_wmi_pdev_set_param(ar,
+						WMI_PDEV_PARAM_BEACON_TX_MODE,
+						WMI_BEACON_STAGGERED_MODE);
+		if (ret)
+			ath10k_warn("Failed to set beacon mode for VDEV: %d\n",
+				    arvif->vdev_id);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Set staggered beacon mode for VDEV: %d\n",
+				   arvif->vdev_id);
+	}
+
+	if (changed & BSS_CHANGED_BEACON_INFO) {
+		arvif->dtim_period = info->dtim_period;
+
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
+						WMI_VDEV_PARAM_DTIM_PERIOD,
+						arvif->dtim_period);
+		if (ret)
+			ath10k_warn("Failed to set dtim period for VDEV: %d\n",
+				    arvif->vdev_id);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Set dtim period: %d for VDEV: %d\n",
+				   arvif->dtim_period, arvif->vdev_id);
+	}
+
+	if (changed & BSS_CHANGED_SSID &&
+	    vif->type == NL80211_IFTYPE_AP) {
+		arvif->u.ap.ssid_len = info->ssid_len;
+		if (info->ssid_len)
+			memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
+		arvif->u.ap.hidden_ssid = info->hidden_ssid;
+	}
+
+	if (changed & BSS_CHANGED_BSSID) {
+		if (!is_zero_ether_addr(info->bssid)) {
+			ret = ath10k_peer_create(ar, arvif->vdev_id,
+						 info->bssid);
+			if (ret)
+				ath10k_warn("Failed to add peer: %pM for VDEV: %d\n",
+					    info->bssid, arvif->vdev_id);
+			else
+				ath10k_dbg(ATH10K_DBG_MAC,
+					   "Added peer: %pM for VDEV: %d\n",
+					   info->bssid, arvif->vdev_id);
+
+
+			if (vif->type == NL80211_IFTYPE_STATION) {
+				/*
+				 * this is never erased as we it for crypto key
+				 * clearing; this is FW requirement
+				 */
+				memcpy(arvif->u.sta.bssid, info->bssid,
+				       ETH_ALEN);
+
+				ret = ath10k_vdev_start(arvif);
+				if (!ret)
+					ath10k_dbg(ATH10K_DBG_MAC,
+						   "VDEV: %d started with BSSID: %pM\n",
+						   arvif->vdev_id, info->bssid);
+			}
+
+			/*
+			 * Mac80211 does not keep IBSS bssid when leaving IBSS,
+			 * so driver need to store it. It is needed when leaving
+			 * IBSS in order to remove BSSID peer.
+			 */
+			if (vif->type == NL80211_IFTYPE_ADHOC)
+				memcpy(arvif->u.ibss.bssid, info->bssid,
+				       ETH_ALEN);
+		}
+	}
+
+	if (changed & BSS_CHANGED_BEACON_ENABLED)
+		ath10k_control_beaconing(arvif, info);
+
+	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+		u32 cts_prot;
+		if (info->use_cts_prot)
+			cts_prot = 1;
+		else
+			cts_prot = 0;
+
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
+						WMI_VDEV_PARAM_ENABLE_RTSCTS,
+						cts_prot);
+		if (ret)
+			ath10k_warn("Failed to set CTS prot for VDEV: %d\n",
+				    arvif->vdev_id);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Set CTS prot: %d for VDEV: %d\n",
+				   cts_prot, arvif->vdev_id);
+	}
+
+	if (changed & BSS_CHANGED_ERP_SLOT) {
+		u32 slottime;
+		if (info->use_short_slot)
+			slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
+
+		else
+			slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
+
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
+						WMI_VDEV_PARAM_SLOT_TIME,
+						slottime);
+		if (ret)
+			ath10k_warn("Failed to set erp slot for VDEV: %d\n",
+				    arvif->vdev_id);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Set slottime: %d for VDEV: %d\n",
+				   slottime, arvif->vdev_id);
+	}
+
+	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+		u32 preamble;
+		if (info->use_short_preamble)
+			preamble = WMI_VDEV_PREAMBLE_SHORT;
+		else
+			preamble = WMI_VDEV_PREAMBLE_LONG;
+
+		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
+						WMI_VDEV_PARAM_PREAMBLE,
+						preamble);
+		if (ret)
+			ath10k_warn("Failed to set preamble for VDEV: %d\n",
+				    arvif->vdev_id);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Set preamble: %d for VDEV: %d\n",
+				   preamble, arvif->vdev_id);
+	}
+
+	if (changed & BSS_CHANGED_ASSOC) {
+		if (info->assoc)
+			ath10k_bss_assoc(hw, vif, info);
+	}
+
+	mutex_unlock(&ar->conf_mutex);
+}
+
+static int ath10k_hw_scan(struct ieee80211_hw *hw,
+			  struct ieee80211_vif *vif,
+			  struct cfg80211_scan_request *req)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	struct wmi_start_scan_arg arg;
+	int ret = 0;
+	int i;
+
+	mutex_lock(&ar->conf_mutex);
+
+	spin_lock_bh(&ar->data_lock);
+	if (ar->scan.in_progress) {
+		spin_unlock_bh(&ar->data_lock);
+		ret = -EBUSY;
+		goto exit;
+	}
+
+	INIT_COMPLETION(ar->scan.started);
+	INIT_COMPLETION(ar->scan.completed);
+	ar->scan.in_progress = true;
+	ar->scan.aborting = false;
+	ar->scan.is_roc = false;
+	ar->scan.vdev_id = arvif->vdev_id;
+	spin_unlock_bh(&ar->data_lock);
+
+	memset(&arg, 0, sizeof(arg));
+	ath10k_wmi_start_scan_init(ar, &arg);
+	arg.vdev_id = arvif->vdev_id;
+	arg.scan_id = ATH10K_SCAN_ID;
+
+	if (!req->no_cck)
+		arg.scan_ctrl_flags |= WMI_SCAN_ADD_CCK_RATES;
+
+	if (req->ie_len) {
+		arg.ie_len = req->ie_len;
+		memcpy(arg.ie, req->ie, arg.ie_len);
+	}
+
+	if (req->n_ssids) {
+		arg.n_ssids = req->n_ssids;
+		for (i = 0; i < arg.n_ssids; i++) {
+			arg.ssids[i].len  = req->ssids[i].ssid_len;
+			arg.ssids[i].ssid = req->ssids[i].ssid;
+		}
+	}
+
+	if (req->n_channels) {
+		arg.n_channels = req->n_channels;
+		for (i = 0; i < arg.n_channels; i++)
+			arg.channels[i] = req->channels[i]->center_freq;
+	}
+
+	ret = ath10k_start_scan(ar, &arg);
+	if (ret) {
+		ath10k_warn("could not start hw scan (%d)\n", ret);
+		spin_lock_bh(&ar->data_lock);
+		ar->scan.in_progress = false;
+		spin_unlock_bh(&ar->data_lock);
+	}
+
+exit:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif)
+{
+	struct ath10k *ar = hw->priv;
+	int ret;
+
+	mutex_lock(&ar->conf_mutex);
+	ret = ath10k_abort_scan(ar);
+	if (ret) {
+		ath10k_warn("couldn't abort scan (%d). forcefully sending scan completion to mac80211\n",
+			    ret);
+		ieee80211_scan_completed(hw, 1 /* aborted */);
+	}
+	mutex_unlock(&ar->conf_mutex);
+}
+
+static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+			  struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+			  struct ieee80211_key_conf *key)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	struct ath10k_peer *peer;
+	const u8 *peer_addr;
+	bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+		      key->cipher == WLAN_CIPHER_SUITE_WEP104;
+	int ret = 0;
+
+	if (key->keyidx > WMI_MAX_KEY_INDEX)
+		return -ENOSPC;
+
+	mutex_lock(&ar->conf_mutex);
+
+	if (sta)
+		peer_addr = sta->addr;
+	else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
+		peer_addr = vif->bss_conf.bssid;
+	else
+		peer_addr = vif->addr;
+
+	key->hw_key_idx = key->keyidx;
+
+	/* the peer should not disappear in mid-way (unless FW goes awry) since
+	 * we already hold conf_mutex. we just make sure its there now. */
+	spin_lock_bh(&ar->data_lock);
+	peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
+	spin_unlock_bh(&ar->data_lock);
+
+	if (!peer) {
+		if (cmd == SET_KEY) {
+			ath10k_warn("cannot install key for non-existent peer %pM\n",
+				    peer_addr);
+			ret = -EOPNOTSUPP;
+			goto exit;
+		} else {
+			/* if the peer doesn't exist there is no key to disable
+			 * anymore */
+			goto exit;
+		}
+	}
+
+	if (is_wep) {
+		if (cmd == SET_KEY)
+			arvif->wep_keys[key->keyidx] = key;
+		else
+			arvif->wep_keys[key->keyidx] = NULL;
+
+		if (cmd == DISABLE_KEY)
+			ath10k_clear_vdev_key(arvif, key);
+	}
+
+	ret = ath10k_install_key(arvif, key, cmd, peer_addr);
+	if (ret) {
+		ath10k_warn("ath10k_install_key failed (%d)\n", ret);
+		goto exit;
+	}
+
+	spin_lock_bh(&ar->data_lock);
+	peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
+	if (peer && cmd == SET_KEY)
+		peer->keys[key->keyidx] = key;
+	else if (peer && cmd == DISABLE_KEY)
+		peer->keys[key->keyidx] = NULL;
+	else if (peer == NULL)
+		/* impossible unless FW goes crazy */
+		ath10k_warn("peer %pM disappeared!\n", peer_addr);
+	spin_unlock_bh(&ar->data_lock);
+
+exit:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+static int ath10k_sta_state(struct ieee80211_hw *hw,
+			    struct ieee80211_vif *vif,
+			    struct ieee80211_sta *sta,
+			    enum ieee80211_sta_state old_state,
+			    enum ieee80211_sta_state new_state)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	int ret = 0;
+
+	mutex_lock(&ar->conf_mutex);
+
+	if (old_state == IEEE80211_STA_NOTEXIST &&
+	    new_state == IEEE80211_STA_NONE &&
+	    vif->type != NL80211_IFTYPE_STATION) {
+		/*
+		 * New station addition.
+		 */
+		ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr);
+		if (ret)
+			ath10k_warn("Failed to add peer: %pM for VDEV: %d\n",
+				    sta->addr, arvif->vdev_id);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Added peer: %pM for VDEV: %d\n",
+				   sta->addr, arvif->vdev_id);
+	} else if ((old_state == IEEE80211_STA_NONE &&
+		    new_state == IEEE80211_STA_NOTEXIST)) {
+		/*
+		 * Existing station deletion.
+		 */
+		ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
+		if (ret)
+			ath10k_warn("Failed to delete peer: %pM for VDEV: %d\n",
+				    sta->addr, arvif->vdev_id);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Removed peer: %pM for VDEV: %d\n",
+				   sta->addr, arvif->vdev_id);
+
+		if (vif->type == NL80211_IFTYPE_STATION)
+			ath10k_bss_disassoc(hw, vif);
+	} else if (old_state == IEEE80211_STA_AUTH &&
+		   new_state == IEEE80211_STA_ASSOC &&
+		   (vif->type == NL80211_IFTYPE_AP ||
+		    vif->type == NL80211_IFTYPE_ADHOC)) {
+		/*
+		 * New association.
+		 */
+		ret = ath10k_station_assoc(ar, arvif, sta);
+		if (ret)
+			ath10k_warn("Failed to associate station: %pM\n",
+				    sta->addr);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Station %pM moved to assoc state\n",
+				   sta->addr);
+	} else if (old_state == IEEE80211_STA_ASSOC &&
+		   new_state == IEEE80211_STA_AUTH &&
+		   (vif->type == NL80211_IFTYPE_AP ||
+		    vif->type == NL80211_IFTYPE_ADHOC)) {
+		/*
+		 * Disassociation.
+		 */
+		ret = ath10k_station_disassoc(ar, arvif, sta);
+		if (ret)
+			ath10k_warn("Failed to disassociate station: %pM\n",
+				    sta->addr);
+		else
+			ath10k_dbg(ATH10K_DBG_MAC,
+				   "Station %pM moved to disassociated state\n",
+				   sta->addr);
+	}
+
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
+				 u16 ac, bool enable)
+{
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	u32 value = 0;
+	int ret = 0;
+
+	if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
+		return 0;
+
+	switch (ac) {
+	case IEEE80211_AC_VO:
+		value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
+			WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
+		break;
+	case IEEE80211_AC_VI:
+		value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
+			WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
+		break;
+	case IEEE80211_AC_BE:
+		value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
+			WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
+		break;
+	case IEEE80211_AC_BK:
+		value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
+			WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
+		break;
+	}
+
+	if (enable)
+		arvif->u.sta.uapsd |= value;
+	else
+		arvif->u.sta.uapsd &= ~value;
+
+	ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
+					  WMI_STA_PS_PARAM_UAPSD,
+					  arvif->u.sta.uapsd);
+	if (ret) {
+		ath10k_warn("could not set uapsd params %d\n", ret);
+		goto exit;
+	}
+
+	if (arvif->u.sta.uapsd)
+		value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
+	else
+		value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
+
+	ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
+					  WMI_STA_PS_PARAM_RX_WAKE_POLICY,
+					  value);
+	if (ret)
+		ath10k_warn("could not set rx wake param %d\n", ret);
+
+exit:
+	return ret;
+}
+
+static int ath10k_conf_tx(struct ieee80211_hw *hw,
+			  struct ieee80211_vif *vif, u16 ac,
+			  const struct ieee80211_tx_queue_params *params)
+{
+	struct ath10k *ar = hw->priv;
+	struct wmi_wmm_params_arg *p = NULL;
+	int ret;
+
+	mutex_lock(&ar->conf_mutex);
+
+	switch (ac) {
+	case IEEE80211_AC_VO:
+		p = &ar->wmm_params.ac_vo;
+		break;
+	case IEEE80211_AC_VI:
+		p = &ar->wmm_params.ac_vi;
+		break;
+	case IEEE80211_AC_BE:
+		p = &ar->wmm_params.ac_be;
+		break;
+	case IEEE80211_AC_BK:
+		p = &ar->wmm_params.ac_bk;
+		break;
+	}
+
+	if (WARN_ON(!p)) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	p->cwmin = params->cw_min;
+	p->cwmax = params->cw_max;
+	p->aifs = params->aifs;
+
+	/*
+	 * The channel time duration programmed in the HW is in absolute
+	 * microseconds, while mac80211 gives the txop in units of
+	 * 32 microseconds.
+	 */
+	p->txop = params->txop * 32;
+
+	/* FIXME: FW accepts wmm params per hw, not per vif */
+	ret = ath10k_wmi_pdev_set_wmm_params(ar, &ar->wmm_params);
+	if (ret) {
+		ath10k_warn("could not set wmm params %d\n", ret);
+		goto exit;
+	}
+
+	ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
+	if (ret)
+		ath10k_warn("could not set sta uapsd %d\n", ret);
+
+exit:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+#define ATH10K_ROC_TIMEOUT_HZ (2*HZ)
+
+static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
+				    struct ieee80211_vif *vif,
+				    struct ieee80211_channel *chan,
+				    int duration,
+				    enum ieee80211_roc_type type)
+{
+	struct ath10k *ar = hw->priv;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	struct wmi_start_scan_arg arg;
+	int ret;
+
+	mutex_lock(&ar->conf_mutex);
+
+	spin_lock_bh(&ar->data_lock);
+	if (ar->scan.in_progress) {
+		spin_unlock_bh(&ar->data_lock);
+		ret = -EBUSY;
+		goto exit;
+	}
+
+	INIT_COMPLETION(ar->scan.started);
+	INIT_COMPLETION(ar->scan.completed);
+	INIT_COMPLETION(ar->scan.on_channel);
+	ar->scan.in_progress = true;
+	ar->scan.aborting = false;
+	ar->scan.is_roc = true;
+	ar->scan.vdev_id = arvif->vdev_id;
+	ar->scan.roc_freq = chan->center_freq;
+	spin_unlock_bh(&ar->data_lock);
+
+	memset(&arg, 0, sizeof(arg));
+	ath10k_wmi_start_scan_init(ar, &arg);
+	arg.vdev_id = arvif->vdev_id;
+	arg.scan_id = ATH10K_SCAN_ID;
+	arg.n_channels = 1;
+	arg.channels[0] = chan->center_freq;
+	arg.dwell_time_active = duration;
+	arg.dwell_time_passive = duration;
+	arg.max_scan_time = 2 * duration;
+	arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
+	arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
+
+	ret = ath10k_start_scan(ar, &arg);
+	if (ret) {
+		ath10k_warn("could not start roc scan (%d)\n", ret);
+		spin_lock_bh(&ar->data_lock);
+		ar->scan.in_progress = false;
+		spin_unlock_bh(&ar->data_lock);
+		goto exit;
+	}
+
+	ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ);
+	if (ret == 0) {
+		ath10k_warn("could not switch to channel for roc scan\n");
+		ath10k_abort_scan(ar);
+		ret = -ETIMEDOUT;
+		goto exit;
+	}
+
+	ret = 0;
+exit:
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
+static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
+{
+	struct ath10k *ar = hw->priv;
+
+	mutex_lock(&ar->conf_mutex);
+	ath10k_abort_scan(ar);
+	mutex_unlock(&ar->conf_mutex);
+
+	return 0;
+}
+
+/*
+ * Both RTS and Fragmentation threshold are interface-specific
+ * in ath10k, but device-specific in mac80211.
+ */
+static void ath10k_set_rts_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct ath10k_generic_iter *ar_iter = data;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	u32 rts = ar_iter->ar->hw->wiphy->rts_threshold;
+
+	rts = min_t(u32, rts, ATH10K_RTS_MAX);
+
+	ar_iter->ret = ath10k_wmi_vdev_set_param(ar_iter->ar, arvif->vdev_id,
+						 WMI_VDEV_PARAM_RTS_THRESHOLD,
+						 rts);
+	if (ar_iter->ret)
+		ath10k_warn("Failed to set RTS threshold for VDEV: %d\n",
+			    arvif->vdev_id);
+	else
+		ath10k_dbg(ATH10K_DBG_MAC,
+			   "Set RTS threshold: %d for VDEV: %d\n",
+			   rts, arvif->vdev_id);
+}
+
+static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+	struct ath10k_generic_iter ar_iter;
+	struct ath10k *ar = hw->priv;
+
+	memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter));
+	ar_iter.ar = ar;
+
+	mutex_lock(&ar->conf_mutex);
+	ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+					    ath10k_set_rts_iter, &ar_iter);
+	mutex_unlock(&ar->conf_mutex);
+
+	return ar_iter.ret;
+}
+
+static void ath10k_set_frag_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct ath10k_generic_iter *ar_iter = data;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+	u32 frag = ar_iter->ar->hw->wiphy->frag_threshold;
+	int ret;
+
+	frag = clamp_t(u32, frag,
+		       ATH10K_FRAGMT_THRESHOLD_MIN,
+		       ATH10K_FRAGMT_THRESHOLD_MAX);
+
+	ret = ath10k_wmi_vdev_set_param(ar_iter->ar, arvif->vdev_id,
+					WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
+					frag);
+
+	ar_iter->ret = ret;
+	if (ar_iter->ret)
+		ath10k_warn("Failed to set frag threshold for VDEV: %d\n",
+			    arvif->vdev_id);
+	else
+		ath10k_dbg(ATH10K_DBG_MAC,
+			   "Set frag threshold: %d for VDEV: %d\n",
+			   frag, arvif->vdev_id);
+}
+
+static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
+{
+	struct ath10k_generic_iter ar_iter;
+	struct ath10k *ar = hw->priv;
+
+	memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter));
+	ar_iter.ar = ar;
+
+	mutex_lock(&ar->conf_mutex);
+	ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+					    ath10k_set_frag_iter, &ar_iter);
+	mutex_unlock(&ar->conf_mutex);
+
+	return ar_iter.ret;
+}
+
+static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
+{
+	struct ath10k *ar = hw->priv;
+	int ret;
+
+	/* mac80211 doesn't care if we really xmit queued frames or not
+	 * we'll collect those frames either way if we stop/delete vdevs */
+	if (drop)
+		return;
+
+	ret = wait_event_timeout(ar->htt->empty_tx_wq, ({
+			bool empty;
+			spin_lock_bh(&ar->htt->tx_lock);
+			empty = bitmap_empty(ar->htt->used_msdu_ids,
+					     ar->htt->max_num_pending_tx);
+			spin_unlock_bh(&ar->htt->tx_lock);
+			(empty);
+		}), ATH10K_FLUSH_TIMEOUT_HZ);
+	if (ret <= 0)
+		ath10k_warn("tx not flushed\n");
+}
+
+/* TODO: Implement this function properly
+ * For now it is needed to reply to Probe Requests in IBSS mode.
+ * Propably we need this information from FW.
+ */
+static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
+{
+	return 1;
+}
+
+static const struct ieee80211_ops ath10k_ops = {
+	.tx				= ath10k_tx,
+	.start				= ath10k_start,
+	.stop				= ath10k_stop,
+	.config				= ath10k_config,
+	.add_interface			= ath10k_add_interface,
+	.remove_interface		= ath10k_remove_interface,
+	.configure_filter		= ath10k_configure_filter,
+	.bss_info_changed		= ath10k_bss_info_changed,
+	.hw_scan			= ath10k_hw_scan,
+	.cancel_hw_scan			= ath10k_cancel_hw_scan,
+	.set_key			= ath10k_set_key,
+	.sta_state			= ath10k_sta_state,
+	.conf_tx			= ath10k_conf_tx,
+	.remain_on_channel		= ath10k_remain_on_channel,
+	.cancel_remain_on_channel	= ath10k_cancel_remain_on_channel,
+	.set_rts_threshold		= ath10k_set_rts_threshold,
+	.set_frag_threshold		= ath10k_set_frag_threshold,
+	.flush				= ath10k_flush,
+	.tx_last_beacon			= ath10k_tx_last_beacon,
+};
+
+#define RATETAB_ENT(_rate, _rateid, _flags) { \
+	.bitrate		= (_rate), \
+	.flags			= (_flags), \
+	.hw_value		= (_rateid), \
+}
+
+#define CHAN2G(_channel, _freq, _flags) { \
+	.band			= IEEE80211_BAND_2GHZ, \
+	.hw_value		= (_channel), \
+	.center_freq		= (_freq), \
+	.flags			= (_flags), \
+	.max_antenna_gain	= 0, \
+	.max_power		= 30, \
+}
+
+#define CHAN5G(_channel, _freq, _flags) { \
+	.band			= IEEE80211_BAND_5GHZ, \
+	.hw_value		= (_channel), \
+	.center_freq		= (_freq), \
+	.flags			= (_flags), \
+	.max_antenna_gain	= 0, \
+	.max_power		= 30, \
+}
+
+static const struct ieee80211_channel ath10k_2ghz_channels[] = {
+	CHAN2G(1, 2412, 0),
+	CHAN2G(2, 2417, 0),
+	CHAN2G(3, 2422, 0),
+	CHAN2G(4, 2427, 0),
+	CHAN2G(5, 2432, 0),
+	CHAN2G(6, 2437, 0),
+	CHAN2G(7, 2442, 0),
+	CHAN2G(8, 2447, 0),
+	CHAN2G(9, 2452, 0),
+	CHAN2G(10, 2457, 0),
+	CHAN2G(11, 2462, 0),
+	CHAN2G(12, 2467, 0),
+	CHAN2G(13, 2472, 0),
+	CHAN2G(14, 2484, 0),
+};
+
+static const struct ieee80211_channel ath10k_5ghz_channels[] = {
+	CHAN5G(36, 5180, 0),
+	CHAN5G(40, 5200, 0),
+	CHAN5G(44, 5220, 0),
+	CHAN5G(48, 5240, 0),
+	CHAN5G(52, 5260, 0),
+	CHAN5G(56, 5280, 0),
+	CHAN5G(60, 5300, 0),
+	CHAN5G(64, 5320, 0),
+	CHAN5G(100, 5500, 0),
+	CHAN5G(104, 5520, 0),
+	CHAN5G(108, 5540, 0),
+	CHAN5G(112, 5560, 0),
+	CHAN5G(116, 5580, 0),
+	CHAN5G(120, 5600, 0),
+	CHAN5G(124, 5620, 0),
+	CHAN5G(128, 5640, 0),
+	CHAN5G(132, 5660, 0),
+	CHAN5G(136, 5680, 0),
+	CHAN5G(140, 5700, 0),
+	CHAN5G(149, 5745, 0),
+	CHAN5G(153, 5765, 0),
+	CHAN5G(157, 5785, 0),
+	CHAN5G(161, 5805, 0),
+	CHAN5G(165, 5825, 0),
+};
+
+static struct ieee80211_rate ath10k_rates[] = {
+	/* CCK */
+	RATETAB_ENT(10,  0x82, 0),
+	RATETAB_ENT(20,  0x84, 0),
+	RATETAB_ENT(55,  0x8b, 0),
+	RATETAB_ENT(110, 0x96, 0),
+	/* OFDM */
+	RATETAB_ENT(60,  0x0c, 0),
+	RATETAB_ENT(90,  0x12, 0),
+	RATETAB_ENT(120, 0x18, 0),
+	RATETAB_ENT(180, 0x24, 0),
+	RATETAB_ENT(240, 0x30, 0),
+	RATETAB_ENT(360, 0x48, 0),
+	RATETAB_ENT(480, 0x60, 0),
+	RATETAB_ENT(540, 0x6c, 0),
+};
+
+#define ath10k_a_rates (ath10k_rates + 4)
+#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - 4)
+#define ath10k_g_rates (ath10k_rates + 0)
+#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
+
+struct ath10k *ath10k_mac_create(void)
+{
+	struct ieee80211_hw *hw;
+	struct ath10k *ar;
+
+	hw = ieee80211_alloc_hw(sizeof(struct ath10k), &ath10k_ops);
+	if (!hw)
+		return NULL;
+
+	ar = hw->priv;
+	ar->hw = hw;
+
+	return ar;
+}
+
+void ath10k_mac_destroy(struct ath10k *ar)
+{
+	ieee80211_free_hw(ar->hw);
+}
+
+static const struct ieee80211_iface_limit ath10k_if_limits[] = {
+	{
+	.max	= 8,
+	.types	= BIT(NL80211_IFTYPE_STATION)
+		| BIT(NL80211_IFTYPE_P2P_CLIENT)
+		| BIT(NL80211_IFTYPE_P2P_GO)
+		| BIT(NL80211_IFTYPE_AP)
+	}
+};
+
+static const struct ieee80211_iface_combination ath10k_if_comb = {
+	.limits = ath10k_if_limits,
+	.n_limits = ARRAY_SIZE(ath10k_if_limits),
+	.max_interfaces = 8,
+	.num_different_channels = 1,
+	.beacon_int_infra_match = true,
+};
+
+static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
+{
+	struct ieee80211_sta_vht_cap vht_cap = {0};
+	u16 mcs_map;
+
+	vht_cap.vht_supported = 1;
+	vht_cap.cap = ar->vht_cap_info;
+
+	/* FIXME: check dynamically how many streams board supports */
+	mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
+		IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
+		IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 |
+		IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
+		IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
+		IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
+		IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
+		IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
+
+	vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
+	vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
+
+	return vht_cap;
+}
+
+static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
+{
+	int i;
+	struct ieee80211_sta_ht_cap ht_cap = {0};
+
+	if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
+		return ht_cap;
+
+	ht_cap.ht_supported = 1;
+	ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+	ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
+	ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+	ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
+	ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;
+
+	if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
+		ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
+
+	if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
+		ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+
+	if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
+		u32 smps;
+
+		smps   = WLAN_HT_CAP_SM_PS_DYNAMIC;
+		smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
+
+		ht_cap.cap |= smps;
+	}
+
+	if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC)
+		ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
+
+	if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
+		u32 stbc;
+
+		stbc   = ar->ht_cap_info;
+		stbc  &= WMI_HT_CAP_RX_STBC;
+		stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
+		stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
+		stbc  &= IEEE80211_HT_CAP_RX_STBC;
+
+		ht_cap.cap |= stbc;
+	}
+
+	if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
+		ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
+
+	if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
+		ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
+
+	/* max AMSDU is implicitly taken from vht_cap_info */
+	if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
+		ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
+
+	for (i = 0; i < WMI_MAX_SPATIAL_STREAM; i++)
+		ht_cap.mcs.rx_mask[i] = 0xFF;
+
+	ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
+
+	return ht_cap;
+}
+
+
+static void ath10k_get_arvif_iter(void *data, u8 *mac,
+				  struct ieee80211_vif *vif)
+{
+	struct ath10k_vif_iter *arvif_iter = data;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+
+	if (arvif->vdev_id == arvif_iter->vdev_id)
+		arvif_iter->arvif = arvif;
+}
+
+struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
+{
+	struct ath10k_vif_iter arvif_iter;
+	u32 flags;
+
+	memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
+	arvif_iter.vdev_id = vdev_id;
+
+	flags = IEEE80211_IFACE_ITER_RESUME_ALL;
+	ieee80211_iterate_active_interfaces_atomic(ar->hw,
+						   flags,
+						   ath10k_get_arvif_iter,
+						   &arvif_iter);
+	if (!arvif_iter.arvif) {
+		ath10k_warn("No VIF found for VDEV: %d\n", vdev_id);
+		return NULL;
+	}
+
+	return arvif_iter.arvif;
+}
+
+int ath10k_mac_register(struct ath10k *ar)
+{
+	struct ieee80211_supported_band *band;
+	struct ieee80211_sta_vht_cap vht_cap;
+	struct ieee80211_sta_ht_cap ht_cap;
+	void *channels;
+	int ret;
+
+	SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
+
+	SET_IEEE80211_DEV(ar->hw, ar->dev);
+
+	ht_cap = ath10k_get_ht_cap(ar);
+	vht_cap = ath10k_create_vht_cap(ar);
+
+	if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
+		channels = kmemdup(ath10k_2ghz_channels,
+				   sizeof(ath10k_2ghz_channels),
+				   GFP_KERNEL);
+		if (!channels)
+			return -ENOMEM;
+
+		band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
+		band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
+		band->channels = channels;
+		band->n_bitrates = ath10k_g_rates_size;
+		band->bitrates = ath10k_g_rates;
+		band->ht_cap = ht_cap;
+
+		/* vht is not supported in 2.4 GHz */
+
+		ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
+	}
+
+	if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
+		channels = kmemdup(ath10k_5ghz_channels,
+				   sizeof(ath10k_5ghz_channels),
+				   GFP_KERNEL);
+		if (!channels) {
+			if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
+				band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
+				kfree(band->channels);
+			}
+			return -ENOMEM;
+		}
+
+		band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
+		band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
+		band->channels = channels;
+		band->n_bitrates = ath10k_a_rates_size;
+		band->bitrates = ath10k_a_rates;
+		band->ht_cap = ht_cap;
+		band->vht_cap = vht_cap;
+		ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
+	}
+
+	ar->hw->wiphy->interface_modes =
+		BIT(NL80211_IFTYPE_STATION) |
+		BIT(NL80211_IFTYPE_ADHOC) |
+		BIT(NL80211_IFTYPE_AP) |
+		BIT(NL80211_IFTYPE_P2P_CLIENT) |
+		BIT(NL80211_IFTYPE_P2P_GO);
+
+	ar->hw->flags = IEEE80211_HW_SIGNAL_DBM |
+			IEEE80211_HW_SUPPORTS_PS |
+			IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
+			IEEE80211_HW_SUPPORTS_UAPSD |
+			IEEE80211_HW_MFP_CAPABLE |
+			IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+			IEEE80211_HW_HAS_RATE_CONTROL |
+			IEEE80211_HW_SUPPORTS_STATIC_SMPS |
+			IEEE80211_HW_WANT_MONITOR_VIF |
+			IEEE80211_HW_AP_LINK_PS;
+
+	if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
+		ar->hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS;
+
+	if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
+		ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+		ar->hw->flags |= IEEE80211_HW_TX_AMPDU_SETUP_IN_HW;
+	}
+
+	ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
+	ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
+
+	ar->hw->vif_data_size = sizeof(struct ath10k_vif);
+
+	ar->hw->channel_change_time = 5000;
+	ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
+
+	ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+	ar->hw->wiphy->max_remain_on_channel_duration = 5000;
+
+	ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
+	/*
+	 * on LL hardware queues are managed entirely by the FW
+	 * so we only advertise to mac we can do the queues thing
+	 */
+	ar->hw->queues = 4;
+
+	ar->hw->wiphy->iface_combinations = &ath10k_if_comb;
+	ar->hw->wiphy->n_iface_combinations = 1;
+
+	ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
+			    ath10k_reg_notifier);
+	if (ret) {
+		ath10k_err("Regulatory initialization failed\n");
+		return ret;
+	}
+
+	ret = ieee80211_register_hw(ar->hw);
+	if (ret) {
+		ath10k_err("ieee80211 registration failed: %d\n", ret);
+		return ret;
+	}
+
+	if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
+		ret = regulatory_hint(ar->hw->wiphy,
+				      ar->ath_common.regulatory.alpha2);
+		if (ret)
+			goto exit;
+	}
+
+	return 0;
+exit:
+	ieee80211_unregister_hw(ar->hw);
+	return ret;
+}
+
+void ath10k_mac_unregister(struct ath10k *ar)
+{
+	ieee80211_unregister_hw(ar->hw);
+
+	kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
+	kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
+
+	SET_IEEE80211_DEV(ar->hw, NULL);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/mac.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/mac.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/mac.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/mac.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MAC_H_
+#define _MAC_H_
+
+#include <net/mac80211.h>
+#include "core.h"
+
+struct ath10k_generic_iter {
+	struct ath10k *ar;
+	int ret;
+};
+
+struct ath10k *ath10k_mac_create(void);
+void ath10k_mac_destroy(struct ath10k *ar);
+int ath10k_mac_register(struct ath10k *ar);
+void ath10k_mac_unregister(struct ath10k *ar);
+struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id);
+void ath10k_reset_scan(unsigned long ptr);
+void ath10k_offchan_tx_purge(struct ath10k *ar);
+void ath10k_offchan_tx_work(struct work_struct *work);
+
+static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
+{
+	return (struct ath10k_vif *)vif->drv_priv;
+}
+
+static inline void ath10k_tx_h_seq_no(struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_vif *vif = info->control.vif;
+	struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
+
+	if (info->flags  & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+		if (arvif->tx_seq_no == 0)
+			arvif->tx_seq_no = 0x1000;
+
+		if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+			arvif->tx_seq_no += 0x10;
+		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+		hdr->seq_ctrl |= cpu_to_le16(arvif->tx_seq_no);
+	}
+}
+
+#endif /* _MAC_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,20 @@
+obj-$(CONFIG_ATH10K) += ath10k_core.o
+ath10k_core-y += mac.o \
+		 debug.o \
+		 core.o \
+		 htc.o \
+		 htt.o \
+		 htt_rx.o \
+		 htt_tx.o \
+		 txrx.o \
+		 wmi.o \
+		 bmi.o
+
+ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
+
+obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
+ath10k_pci-y += pci.o \
+		ce.o
+
+# for tracing framework to find trace.h
+CFLAGS_trace.o := -I$(src)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/pci.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/pci.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/pci.c	2013-08-31 17:59:29.000000000 -0400
@@ -0,0 +1,2502 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include "core.h"
+#include "debug.h"
+
+#include "targaddrs.h"
+#include "bmi.h"
+
+#include "hif.h"
+#include "htc.h"
+
+#include "ce.h"
+#include "pci.h"
+
+unsigned int ath10k_target_ps;
+module_param(ath10k_target_ps, uint, 0644);
+MODULE_PARM_DESC(ath10k_target_ps, "Enable ath10k Target (SoC) PS option");
+
+#define QCA988X_1_0_DEVICE_ID	(0xabcd)
+#define QCA988X_2_0_DEVICE_ID	(0x003c)
+
+static DEFINE_PCI_DEVICE_TABLE(ath10k_pci_id_table) = {
+	{ PCI_VDEVICE(ATHEROS, QCA988X_1_0_DEVICE_ID) }, /* PCI-E QCA988X V1 */
+	{ PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */
+	{0}
+};
+
+static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address,
+				       u32 *data);
+
+static void ath10k_pci_process_ce(struct ath10k *ar);
+static int ath10k_pci_post_rx(struct ath10k *ar);
+static int ath10k_pci_post_rx_pipe(struct hif_ce_pipe_info *pipe_info,
+					     int num);
+static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info);
+static void ath10k_pci_stop_ce(struct ath10k *ar);
+
+static const struct ce_attr host_ce_config_wlan[] = {
+	/* host->target HTC control and raw streams */
+	{ /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL,},
+	/* could be moved to share CE3 */
+	/* target->host HTT + HTC control */
+	{ /* CE1 */ CE_ATTR_FLAGS, 0, 0, 512, 512, NULL,},
+	/* target->host WMI */
+	{ /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 32, NULL,},
+	/* host->target WMI */
+	{ /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,},
+	/* host->target HTT */
+	{ /* CE4 */ CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, 0,
+		    CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,},
+	/* unused */
+	{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,},
+	/* Target autonomous hif_memcpy */
+	{ /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,},
+	/* ce_diag, the Diagnostic Window */
+	{ /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL,},
+};
+
+/* Target firmware's Copy Engine configuration. */
+static const struct ce_pipe_config target_ce_config_wlan[] = {
+	/* host->target HTC control and raw streams */
+	{ /* CE0 */ 0, PIPEDIR_OUT, 32, 256, CE_ATTR_FLAGS, 0,},
+	/* target->host HTT + HTC control */
+	{ /* CE1 */ 1, PIPEDIR_IN, 32, 512, CE_ATTR_FLAGS, 0,},
+	/* target->host WMI */
+	{ /* CE2 */ 2, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,},
+	/* host->target WMI */
+	{ /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,},
+	/* host->target HTT */
+	{ /* CE4 */ 4, PIPEDIR_OUT, 256, 256, CE_ATTR_FLAGS, 0,},
+	/* NB: 50% of src nentries, since tx has 2 frags */
+	/* unused */
+	{ /* CE5 */ 5, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,},
+	/* Reserved for target autonomous hif_memcpy */
+	{ /* CE6 */ 6, PIPEDIR_INOUT, 32, 4096, CE_ATTR_FLAGS, 0,},
+	/* CE7 used only by Host */
+};
+
+/*
+ * Diagnostic read/write access is provided for startup/config/debug usage.
+ * Caller must guarantee proper alignment, when applicable, and single user
+ * at any moment.
+ */
+static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
+				    int nbytes)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ret = 0;
+	u32 buf;
+	unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
+	unsigned int id;
+	unsigned int flags;
+	struct ce_state *ce_diag;
+	/* Host buffer address in CE space */
+	u32 ce_data;
+	dma_addr_t ce_data_base = 0;
+	void *data_buf = NULL;
+	int i;
+
+	/*
+	 * This code cannot handle reads to non-memory space. Redirect to the
+	 * register read fn but preserve the multi word read capability of
+	 * this fn
+	 */
+	if (address < DRAM_BASE_ADDRESS) {
+		if (!IS_ALIGNED(address, 4) ||
+		    !IS_ALIGNED((unsigned long)data, 4))
+			return -EIO;
+
+		while ((nbytes >= 4) &&  ((ret = ath10k_pci_diag_read_access(
+					   ar, address, (u32 *)data)) == 0)) {
+			nbytes -= sizeof(u32);
+			address += sizeof(u32);
+			data += sizeof(u32);
+		}
+		return ret;
+	}
+
+	ce_diag = ar_pci->ce_diag;
+
+	/*
+	 * Allocate a temporary bounce buffer to hold caller's data
+	 * to be DMA'ed from Target. This guarantees
+	 *   1) 4-byte alignment
+	 *   2) Buffer in DMA-able space
+	 */
+	orig_nbytes = nbytes;
+	data_buf = (unsigned char *)pci_alloc_consistent(ar_pci->pdev,
+							 orig_nbytes,
+							 &ce_data_base);
+
+	if (!data_buf) {
+		ret = -ENOMEM;
+		goto done;
+	}
+	memset(data_buf, 0, orig_nbytes);
+
+	remaining_bytes = orig_nbytes;
+	ce_data = ce_data_base;
+	while (remaining_bytes) {
+		nbytes = min_t(unsigned int, remaining_bytes,
+			       DIAG_TRANSFER_LIMIT);
+
+		ret = ath10k_ce_recv_buf_enqueue(ce_diag, NULL, ce_data);
+		if (ret != 0)
+			goto done;
+
+		/* Request CE to send from Target(!) address to Host buffer */
+		/*
+		 * The address supplied by the caller is in the
+		 * Target CPU virtual address space.
+		 *
+		 * In order to use this address with the diagnostic CE,
+		 * convert it from Target CPU virtual address space
+		 * to CE address space
+		 */
+		ath10k_pci_wake(ar);
+		address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem,
+						     address);
+		ath10k_pci_sleep(ar);
+
+		ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0,
+				 0);
+		if (ret)
+			goto done;
+
+		i = 0;
+		while (ath10k_ce_completed_send_next(ce_diag, NULL, &buf,
+						     &completed_nbytes,
+						     &id) != 0) {
+			mdelay(1);
+			if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
+				ret = -EBUSY;
+				goto done;
+			}
+		}
+
+		if (nbytes != completed_nbytes) {
+			ret = -EIO;
+			goto done;
+		}
+
+		if (buf != (u32) address) {
+			ret = -EIO;
+			goto done;
+		}
+
+		i = 0;
+		while (ath10k_ce_completed_recv_next(ce_diag, NULL, &buf,
+						     &completed_nbytes,
+						     &id, &flags) != 0) {
+			mdelay(1);
+
+			if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
+				ret = -EBUSY;
+				goto done;
+			}
+		}
+
+		if (nbytes != completed_nbytes) {
+			ret = -EIO;
+			goto done;
+		}
+
+		if (buf != ce_data) {
+			ret = -EIO;
+			goto done;
+		}
+
+		remaining_bytes -= nbytes;
+		address += nbytes;
+		ce_data += nbytes;
+	}
+
+done:
+	if (ret == 0) {
+		/* Copy data from allocated DMA buf to caller's buf */
+		WARN_ON_ONCE(orig_nbytes & 3);
+		for (i = 0; i < orig_nbytes / sizeof(__le32); i++) {
+			((u32 *)data)[i] =
+				__le32_to_cpu(((__le32 *)data_buf)[i]);
+		}
+	} else
+		ath10k_dbg(ATH10K_DBG_PCI, "%s failure (0x%x)\n",
+			   __func__, address);
+
+	if (data_buf)
+		pci_free_consistent(ar_pci->pdev, orig_nbytes,
+				    data_buf, ce_data_base);
+
+	return ret;
+}
+
+/* Read 4-byte aligned data from Target memory or register */
+static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address,
+				       u32 *data)
+{
+	/* Assume range doesn't cross this boundary */
+	if (address >= DRAM_BASE_ADDRESS)
+		return ath10k_pci_diag_read_mem(ar, address, data, sizeof(u32));
+
+	ath10k_pci_wake(ar);
+	*data = ath10k_pci_read32(ar, address);
+	ath10k_pci_sleep(ar);
+	return 0;
+}
+
+static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
+				     const void *data, int nbytes)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ret = 0;
+	u32 buf;
+	unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
+	unsigned int id;
+	unsigned int flags;
+	struct ce_state *ce_diag;
+	void *data_buf = NULL;
+	u32 ce_data;	/* Host buffer address in CE space */
+	dma_addr_t ce_data_base = 0;
+	int i;
+
+	ce_diag = ar_pci->ce_diag;
+
+	/*
+	 * Allocate a temporary bounce buffer to hold caller's data
+	 * to be DMA'ed to Target. This guarantees
+	 *   1) 4-byte alignment
+	 *   2) Buffer in DMA-able space
+	 */
+	orig_nbytes = nbytes;
+	data_buf = (unsigned char *)pci_alloc_consistent(ar_pci->pdev,
+							 orig_nbytes,
+							 &ce_data_base);
+	if (!data_buf) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	/* Copy caller's data to allocated DMA buf */
+	WARN_ON_ONCE(orig_nbytes & 3);
+	for (i = 0; i < orig_nbytes / sizeof(__le32); i++)
+		((__le32 *)data_buf)[i] = __cpu_to_le32(((u32 *)data)[i]);
+
+	/*
+	 * The address supplied by the caller is in the
+	 * Target CPU virtual address space.
+	 *
+	 * In order to use this address with the diagnostic CE,
+	 * convert it from
+	 *    Target CPU virtual address space
+	 * to
+	 *    CE address space
+	 */
+	ath10k_pci_wake(ar);
+	address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, address);
+	ath10k_pci_sleep(ar);
+
+	remaining_bytes = orig_nbytes;
+	ce_data = ce_data_base;
+	while (remaining_bytes) {
+		/* FIXME: check cast */
+		nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT);
+
+		/* Set up to receive directly into Target(!) address */
+		ret = ath10k_ce_recv_buf_enqueue(ce_diag, NULL, address);
+		if (ret != 0)
+			goto done;
+
+		/*
+		 * Request CE to send caller-supplied data that
+		 * was copied to bounce buffer to Target(!) address.
+		 */
+		ret = ath10k_ce_send(ce_diag, NULL, (u32) ce_data,
+				     nbytes, 0, 0);
+		if (ret != 0)
+			goto done;
+
+		i = 0;
+		while (ath10k_ce_completed_send_next(ce_diag, NULL, &buf,
+						     &completed_nbytes,
+						     &id) != 0) {
+			mdelay(1);
+
+			if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
+				ret = -EBUSY;
+				goto done;
+			}
+		}
+
+		if (nbytes != completed_nbytes) {
+			ret = -EIO;
+			goto done;
+		}
+
+		if (buf != ce_data) {
+			ret = -EIO;
+			goto done;
+		}
+
+		i = 0;
+		while (ath10k_ce_completed_recv_next(ce_diag, NULL, &buf,
+						     &completed_nbytes,
+						     &id, &flags) != 0) {
+			mdelay(1);
+
+			if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) {
+				ret = -EBUSY;
+				goto done;
+			}
+		}
+
+		if (nbytes != completed_nbytes) {
+			ret = -EIO;
+			goto done;
+		}
+
+		if (buf != address) {
+			ret = -EIO;
+			goto done;
+		}
+
+		remaining_bytes -= nbytes;
+		address += nbytes;
+		ce_data += nbytes;
+	}
+
+done:
+	if (data_buf) {
+		pci_free_consistent(ar_pci->pdev, orig_nbytes, data_buf,
+				    ce_data_base);
+	}
+
+	if (ret != 0)
+		ath10k_dbg(ATH10K_DBG_PCI, "%s failure (0x%x)\n", __func__,
+			   address);
+
+	return ret;
+}
+
+/* Write 4B data to Target memory or register */
+static int ath10k_pci_diag_write_access(struct ath10k *ar, u32 address,
+					u32 data)
+{
+	/* Assume range doesn't cross this boundary */
+	if (address >= DRAM_BASE_ADDRESS)
+		return ath10k_pci_diag_write_mem(ar, address, &data,
+						 sizeof(u32));
+
+	ath10k_pci_wake(ar);
+	ath10k_pci_write32(ar, address, data);
+	ath10k_pci_sleep(ar);
+	return 0;
+}
+
+static bool ath10k_pci_target_is_awake(struct ath10k *ar)
+{
+	void __iomem *mem = ath10k_pci_priv(ar)->mem;
+	u32 val;
+	val = ioread32(mem + PCIE_LOCAL_BASE_ADDRESS +
+		       RTC_STATE_ADDRESS);
+	return (RTC_STATE_V_GET(val) == RTC_STATE_V_ON);
+}
+
+static void ath10k_pci_wait(struct ath10k *ar)
+{
+	int n = 100;
+
+	while (n-- && !ath10k_pci_target_is_awake(ar))
+		msleep(10);
+
+	if (n < 0)
+		ath10k_warn("Unable to wakeup target\n");
+}
+
+void ath10k_do_pci_wake(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	void __iomem *pci_addr = ar_pci->mem;
+	int tot_delay = 0;
+	int curr_delay = 5;
+
+	if (atomic_read(&ar_pci->keep_awake_count) == 0) {
+		/* Force AWAKE */
+		iowrite32(PCIE_SOC_WAKE_V_MASK,
+			  pci_addr + PCIE_LOCAL_BASE_ADDRESS +
+			  PCIE_SOC_WAKE_ADDRESS);
+	}
+	atomic_inc(&ar_pci->keep_awake_count);
+
+	if (ar_pci->verified_awake)
+		return;
+
+	for (;;) {
+		if (ath10k_pci_target_is_awake(ar)) {
+			ar_pci->verified_awake = true;
+			break;
+		}
+
+		if (tot_delay > PCIE_WAKE_TIMEOUT) {
+			ath10k_warn("target takes too long to wake up (awake count %d)\n",
+				    atomic_read(&ar_pci->keep_awake_count));
+			break;
+		}
+
+		udelay(curr_delay);
+		tot_delay += curr_delay;
+
+		if (curr_delay < 50)
+			curr_delay += 5;
+	}
+}
+
+void ath10k_do_pci_sleep(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	void __iomem *pci_addr = ar_pci->mem;
+
+	if (atomic_dec_and_test(&ar_pci->keep_awake_count)) {
+		/* Allow sleep */
+		ar_pci->verified_awake = false;
+		iowrite32(PCIE_SOC_WAKE_RESET,
+			  pci_addr + PCIE_LOCAL_BASE_ADDRESS +
+			  PCIE_SOC_WAKE_ADDRESS);
+	}
+}
+
+/*
+ * FIXME: Handle OOM properly.
+ */
+static inline
+struct ath10k_pci_compl *get_free_compl(struct hif_ce_pipe_info *pipe_info)
+{
+	struct ath10k_pci_compl *compl = NULL;
+
+	spin_lock_bh(&pipe_info->pipe_lock);
+	if (list_empty(&pipe_info->compl_free)) {
+		ath10k_warn("Completion buffers are full\n");
+		goto exit;
+	}
+	compl = list_first_entry(&pipe_info->compl_free,
+				 struct ath10k_pci_compl, list);
+	list_del(&compl->list);
+exit:
+	spin_unlock_bh(&pipe_info->pipe_lock);
+	return compl;
+}
+
+/* Called by lower (CE) layer when a send to Target completes. */
+static void ath10k_pci_ce_send_done(struct ce_state *ce_state,
+				    void *transfer_context,
+				    u32 ce_data,
+				    unsigned int nbytes,
+				    unsigned int transfer_id)
+{
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct hif_ce_pipe_info *pipe_info =  &ar_pci->pipe_info[ce_state->id];
+	struct ath10k_pci_compl *compl;
+	bool process = false;
+
+	do {
+		/*
+		 * For the send completion of an item in sendlist, just
+		 * increment num_sends_allowed. The upper layer callback will
+		 * be triggered when last fragment is done with send.
+		 */
+		if (transfer_context == CE_SENDLIST_ITEM_CTXT) {
+			spin_lock_bh(&pipe_info->pipe_lock);
+			pipe_info->num_sends_allowed++;
+			spin_unlock_bh(&pipe_info->pipe_lock);
+			continue;
+		}
+
+		compl = get_free_compl(pipe_info);
+		if (!compl)
+			break;
+
+		compl->send_or_recv = HIF_CE_COMPLETE_SEND;
+		compl->ce_state = ce_state;
+		compl->pipe_info = pipe_info;
+		compl->transfer_context = transfer_context;
+		compl->nbytes = nbytes;
+		compl->transfer_id = transfer_id;
+		compl->flags = 0;
+
+		/*
+		 * Add the completion to the processing queue.
+		 */
+		spin_lock_bh(&ar_pci->compl_lock);
+		list_add_tail(&compl->list, &ar_pci->compl_process);
+		spin_unlock_bh(&ar_pci->compl_lock);
+
+		process = true;
+	} while (ath10k_ce_completed_send_next(ce_state,
+							   &transfer_context,
+							   &ce_data, &nbytes,
+							   &transfer_id) == 0);
+
+	/*
+	 * If only some of the items within a sendlist have completed,
+	 * don't invoke completion processing until the entire sendlist
+	 * has been sent.
+	 */
+	if (!process)
+		return;
+
+	ath10k_pci_process_ce(ar);
+}
+
+/* Called by lower (CE) layer when data is received from the Target. */
+static void ath10k_pci_ce_recv_data(struct ce_state *ce_state,
+				    void *transfer_context, u32 ce_data,
+				    unsigned int nbytes,
+				    unsigned int transfer_id,
+				    unsigned int flags)
+{
+	struct ath10k *ar = ce_state->ar;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct hif_ce_pipe_info *pipe_info =  &ar_pci->pipe_info[ce_state->id];
+	struct ath10k_pci_compl *compl;
+	struct sk_buff *skb;
+
+	do {
+		compl = get_free_compl(pipe_info);
+		if (!compl)
+			break;
+
+		compl->send_or_recv = HIF_CE_COMPLETE_RECV;
+		compl->ce_state = ce_state;
+		compl->pipe_info = pipe_info;
+		compl->transfer_context = transfer_context;
+		compl->nbytes = nbytes;
+		compl->transfer_id = transfer_id;
+		compl->flags = flags;
+
+		skb = transfer_context;
+		dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
+				 skb->len + skb_tailroom(skb),
+				 DMA_FROM_DEVICE);
+		/*
+		 * Add the completion to the processing queue.
+		 */
+		spin_lock_bh(&ar_pci->compl_lock);
+		list_add_tail(&compl->list, &ar_pci->compl_process);
+		spin_unlock_bh(&ar_pci->compl_lock);
+
+	} while (ath10k_ce_completed_recv_next(ce_state,
+							   &transfer_context,
+							   &ce_data, &nbytes,
+							   &transfer_id,
+							   &flags) == 0);
+
+	ath10k_pci_process_ce(ar);
+}
+
+/* Send the first nbytes bytes of the buffer */
+static int ath10k_pci_hif_send_head(struct ath10k *ar, u8 pipe_id,
+				    unsigned int transfer_id,
+				    unsigned int bytes, struct sk_buff *nbuf)
+{
+	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(nbuf);
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct hif_ce_pipe_info *pipe_info = &(ar_pci->pipe_info[pipe_id]);
+	struct ce_state *ce_hdl = pipe_info->ce_hdl;
+	struct ce_sendlist sendlist;
+	unsigned int len;
+	u32 flags = 0;
+	int ret;
+
+	memset(&sendlist, 0, sizeof(struct ce_sendlist));
+
+	len = min(bytes, nbuf->len);
+	bytes -= len;
+
+	if (len & 3)
+		ath10k_warn("skb not aligned to 4-byte boundary (%d)\n", len);
+
+	ath10k_dbg(ATH10K_DBG_PCI,
+		   "pci send data vaddr %p paddr 0x%llx len %d as %d bytes\n",
+		   nbuf->data, (unsigned long long) skb_cb->paddr,
+		   nbuf->len, len);
+	ath10k_dbg_dump(ATH10K_DBG_PCI_DUMP, NULL,
+			"ath10k tx: data: ",
+			nbuf->data, nbuf->len);
+
+	ath10k_ce_sendlist_buf_add(&sendlist, skb_cb->paddr, len, flags);
+
+	/* Make sure we have resources to handle this request */
+	spin_lock_bh(&pipe_info->pipe_lock);
+	if (!pipe_info->num_sends_allowed) {
+		ath10k_warn("Pipe: %d is full\n", pipe_id);
+		spin_unlock_bh(&pipe_info->pipe_lock);
+		return -ENOSR;
+	}
+	pipe_info->num_sends_allowed--;
+	spin_unlock_bh(&pipe_info->pipe_lock);
+
+	ret = ath10k_ce_sendlist_send(ce_hdl, nbuf, &sendlist, transfer_id);
+	if (ret)
+		ath10k_warn("CE send failed: %p\n", nbuf);
+
+	return ret;
+}
+
+static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct hif_ce_pipe_info *pipe_info = &(ar_pci->pipe_info[pipe]);
+	int ret;
+
+	spin_lock_bh(&pipe_info->pipe_lock);
+	ret = pipe_info->num_sends_allowed;
+	spin_unlock_bh(&pipe_info->pipe_lock);
+
+	return ret;
+}
+
+static void ath10k_pci_hif_dump_area(struct ath10k *ar)
+{
+	u32 reg_dump_area = 0;
+	u32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {};
+	u32 host_addr;
+	int ret;
+	u32 i;
+
+	ath10k_err("firmware crashed!\n");
+	ath10k_err("hardware name %s version 0x%x\n",
+		   ar->hw_params.name, ar->target_version);
+	ath10k_err("firmware version: %u.%u.%u.%u\n", ar->fw_version_major,
+		   ar->fw_version_minor, ar->fw_version_release,
+		   ar->fw_version_build);
+
+	host_addr = host_interest_item_address(HI_ITEM(hi_failure_state));
+	if (ath10k_pci_diag_read_mem(ar, host_addr,
+				     &reg_dump_area, sizeof(u32)) != 0) {
+		ath10k_warn("could not read hi_failure_state\n");
+		return;
+	}
+
+	ath10k_err("target register Dump Location: 0x%08X\n", reg_dump_area);
+
+	ret = ath10k_pci_diag_read_mem(ar, reg_dump_area,
+				       &reg_dump_values[0],
+				       REG_DUMP_COUNT_QCA988X * sizeof(u32));
+	if (ret != 0) {
+		ath10k_err("could not dump FW Dump Area\n");
+		return;
+	}
+
+	BUILD_BUG_ON(REG_DUMP_COUNT_QCA988X % 4);
+
+	ath10k_err("target Register Dump\n");
+	for (i = 0; i < REG_DUMP_COUNT_QCA988X; i += 4)
+		ath10k_err("[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X\n",
+			   i,
+			   reg_dump_values[i],
+			   reg_dump_values[i + 1],
+			   reg_dump_values[i + 2],
+			   reg_dump_values[i + 3]);
+}
+
+static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
+					       int force)
+{
+	if (!force) {
+		int resources;
+		/*
+		 * Decide whether to actually poll for completions, or just
+		 * wait for a later chance.
+		 * If there seem to be plenty of resources left, then just wait
+		 * since checking involves reading a CE register, which is a
+		 * relatively expensive operation.
+		 */
+		resources = ath10k_pci_hif_get_free_queue_number(ar, pipe);
+
+		/*
+		 * If at least 50% of the total resources are still available,
+		 * don't bother checking again yet.
+		 */
+		if (resources > (host_ce_config_wlan[pipe].src_nentries >> 1))
+			return;
+	}
+	ath10k_ce_per_engine_service(ar, pipe);
+}
+
+static void ath10k_pci_hif_post_init(struct ath10k *ar,
+				     struct ath10k_hif_cb *callbacks)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
+
+	memcpy(&ar_pci->msg_callbacks_current, callbacks,
+	       sizeof(ar_pci->msg_callbacks_current));
+}
+
+static int ath10k_pci_start_ce(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct ce_state *ce_diag = ar_pci->ce_diag;
+	const struct ce_attr *attr;
+	struct hif_ce_pipe_info *pipe_info;
+	struct ath10k_pci_compl *compl;
+	int i, pipe_num, completions, disable_interrupts;
+
+	spin_lock_init(&ar_pci->compl_lock);
+	INIT_LIST_HEAD(&ar_pci->compl_process);
+
+	for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) {
+		pipe_info = &ar_pci->pipe_info[pipe_num];
+
+		spin_lock_init(&pipe_info->pipe_lock);
+		INIT_LIST_HEAD(&pipe_info->compl_free);
+
+		/* Handle Diagnostic CE specially */
+		if (pipe_info->ce_hdl == ce_diag)
+			continue;
+
+		attr = &host_ce_config_wlan[pipe_num];
+		completions = 0;
+
+		if (attr->src_nentries) {
+			disable_interrupts = attr->flags & CE_ATTR_DIS_INTR;
+			ath10k_ce_send_cb_register(pipe_info->ce_hdl,
+						   ath10k_pci_ce_send_done,
+						   disable_interrupts);
+			completions += attr->src_nentries;
+			pipe_info->num_sends_allowed = attr->src_nentries - 1;
+		}
+
+		if (attr->dest_nentries) {
+			ath10k_ce_recv_cb_register(pipe_info->ce_hdl,
+						   ath10k_pci_ce_recv_data);
+			completions += attr->dest_nentries;
+		}
+
+		if (completions == 0)
+			continue;
+
+		for (i = 0; i < completions; i++) {
+			compl = kmalloc(sizeof(struct ath10k_pci_compl),
+					GFP_KERNEL);
+			if (!compl) {
+				ath10k_warn("No memory for completion state\n");
+				ath10k_pci_stop_ce(ar);
+				return -ENOMEM;
+			}
+
+			compl->send_or_recv = HIF_CE_COMPLETE_FREE;
+			list_add_tail(&compl->list, &pipe_info->compl_free);
+		}
+	}
+
+	return 0;
+}
+
+static void ath10k_pci_stop_ce(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct ath10k_pci_compl *compl;
+	struct sk_buff *skb;
+	int i;
+
+	ath10k_ce_disable_interrupts(ar);
+
+	/* Cancel the pending tasklet */
+	tasklet_kill(&ar_pci->intr_tq);
+
+	for (i = 0; i < CE_COUNT; i++)
+		tasklet_kill(&ar_pci->pipe_info[i].intr);
+
+	/* Mark pending completions as aborted, so that upper layers free up
+	 * their associated resources */
+	spin_lock_bh(&ar_pci->compl_lock);
+	list_for_each_entry(compl, &ar_pci->compl_process, list) {
+		skb = (struct sk_buff *)compl->transfer_context;
+		ATH10K_SKB_CB(skb)->is_aborted = true;
+	}
+	spin_unlock_bh(&ar_pci->compl_lock);
+}
+
+static void ath10k_pci_cleanup_ce(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct ath10k_pci_compl *compl, *tmp;
+	struct hif_ce_pipe_info *pipe_info;
+	struct sk_buff *netbuf;
+	int pipe_num;
+
+	/* Free pending completions. */
+	spin_lock_bh(&ar_pci->compl_lock);
+	if (!list_empty(&ar_pci->compl_process))
+		ath10k_warn("pending completions still present! possible memory leaks.\n");
+
+	list_for_each_entry_safe(compl, tmp, &ar_pci->compl_process, list) {
+		list_del(&compl->list);
+		netbuf = (struct sk_buff *)compl->transfer_context;
+		dev_kfree_skb_any(netbuf);
+		kfree(compl);
+	}
+	spin_unlock_bh(&ar_pci->compl_lock);
+
+	/* Free unused completions for each pipe. */
+	for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) {
+		pipe_info = &ar_pci->pipe_info[pipe_num];
+
+		spin_lock_bh(&pipe_info->pipe_lock);
+		list_for_each_entry_safe(compl, tmp,
+					 &pipe_info->compl_free, list) {
+			list_del(&compl->list);
+			kfree(compl);
+		}
+		spin_unlock_bh(&pipe_info->pipe_lock);
+	}
+}
+
+static void ath10k_pci_process_ce(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ar->hif.priv;
+	struct ath10k_hif_cb *cb = &ar_pci->msg_callbacks_current;
+	struct ath10k_pci_compl *compl;
+	struct sk_buff *skb;
+	unsigned int nbytes;
+	int ret, send_done = 0;
+
+	/* Upper layers aren't ready to handle tx/rx completions in parallel so
+	 * we must serialize all completion processing. */
+
+	spin_lock_bh(&ar_pci->compl_lock);
+	if (ar_pci->compl_processing) {
+		spin_unlock_bh(&ar_pci->compl_lock);
+		return;
+	}
+	ar_pci->compl_processing = true;
+	spin_unlock_bh(&ar_pci->compl_lock);
+
+	for (;;) {
+		spin_lock_bh(&ar_pci->compl_lock);
+		if (list_empty(&ar_pci->compl_process)) {
+			spin_unlock_bh(&ar_pci->compl_lock);
+			break;
+		}
+		compl = list_first_entry(&ar_pci->compl_process,
+					 struct ath10k_pci_compl, list);
+		list_del(&compl->list);
+		spin_unlock_bh(&ar_pci->compl_lock);
+
+		if (compl->send_or_recv == HIF_CE_COMPLETE_SEND) {
+			cb->tx_completion(ar,
+					  compl->transfer_context,
+					  compl->transfer_id);
+			send_done = 1;
+		} else {
+			ret = ath10k_pci_post_rx_pipe(compl->pipe_info, 1);
+			if (ret) {
+				ath10k_warn("Unable to post recv buffer for pipe: %d\n",
+					    compl->pipe_info->pipe_num);
+				break;
+			}
+
+			skb = (struct sk_buff *)compl->transfer_context;
+			nbytes = compl->nbytes;
+
+			ath10k_dbg(ATH10K_DBG_PCI,
+				   "ath10k_pci_ce_recv_data netbuf=%p  nbytes=%d\n",
+				   skb, nbytes);
+			ath10k_dbg_dump(ATH10K_DBG_PCI_DUMP, NULL,
+					"ath10k rx: ", skb->data, nbytes);
+
+			if (skb->len + skb_tailroom(skb) >= nbytes) {
+				skb_trim(skb, 0);
+				skb_put(skb, nbytes);
+				cb->rx_completion(ar, skb,
+						  compl->pipe_info->pipe_num);
+			} else {
+				ath10k_warn("rxed more than expected (nbytes %d, max %d)",
+					    nbytes,
+					    skb->len + skb_tailroom(skb));
+			}
+		}
+
+		compl->send_or_recv = HIF_CE_COMPLETE_FREE;
+
+		/*
+		 * Add completion back to the pipe's free list.
+		 */
+		spin_lock_bh(&compl->pipe_info->pipe_lock);
+		list_add_tail(&compl->list, &compl->pipe_info->compl_free);
+		compl->pipe_info->num_sends_allowed += send_done;
+		spin_unlock_bh(&compl->pipe_info->pipe_lock);
+	}
+
+	spin_lock_bh(&ar_pci->compl_lock);
+	ar_pci->compl_processing = false;
+	spin_unlock_bh(&ar_pci->compl_lock);
+}
+
+/* TODO - temporary mapping while we have too few CE's */
+static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar,
+					      u16 service_id, u8 *ul_pipe,
+					      u8 *dl_pipe, int *ul_is_polled,
+					      int *dl_is_polled)
+{
+	int ret = 0;
+
+	/* polling for received messages not supported */
+	*dl_is_polled = 0;
+
+	switch (service_id) {
+	case ATH10K_HTC_SVC_ID_HTT_DATA_MSG:
+		/*
+		 * Host->target HTT gets its own pipe, so it can be polled
+		 * while other pipes are interrupt driven.
+		 */
+		*ul_pipe = 4;
+		/*
+		 * Use the same target->host pipe for HTC ctrl, HTC raw
+		 * streams, and HTT.
+		 */
+		*dl_pipe = 1;
+		break;
+
+	case ATH10K_HTC_SVC_ID_RSVD_CTRL:
+	case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS:
+		/*
+		 * Note: HTC_RAW_STREAMS_SVC is currently unused, and
+		 * HTC_CTRL_RSVD_SVC could share the same pipe as the
+		 * WMI services.  So, if another CE is needed, change
+		 * this to *ul_pipe = 3, which frees up CE 0.
+		 */
+		/* *ul_pipe = 3; */
+		*ul_pipe = 0;
+		*dl_pipe = 1;
+		break;
+
+	case ATH10K_HTC_SVC_ID_WMI_DATA_BK:
+	case ATH10K_HTC_SVC_ID_WMI_DATA_BE:
+	case ATH10K_HTC_SVC_ID_WMI_DATA_VI:
+	case ATH10K_HTC_SVC_ID_WMI_DATA_VO:
+
+	case ATH10K_HTC_SVC_ID_WMI_CONTROL:
+		*ul_pipe = 3;
+		*dl_pipe = 2;
+		break;
+
+		/* pipe 5 unused   */
+		/* pipe 6 reserved */
+		/* pipe 7 reserved */
+
+	default:
+		ret = -1;
+		break;
+	}
+	*ul_is_polled =
+		(host_ce_config_wlan[*ul_pipe].flags & CE_ATTR_DIS_INTR) != 0;
+
+	return ret;
+}
+
+static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar,
+						u8 *ul_pipe, u8 *dl_pipe)
+{
+	int ul_is_polled, dl_is_polled;
+
+	(void)ath10k_pci_hif_map_service_to_pipe(ar,
+						 ATH10K_HTC_SVC_ID_RSVD_CTRL,
+						 ul_pipe,
+						 dl_pipe,
+						 &ul_is_polled,
+						 &dl_is_polled);
+}
+
+static int ath10k_pci_post_rx_pipe(struct hif_ce_pipe_info *pipe_info,
+				   int num)
+{
+	struct ath10k *ar = pipe_info->hif_ce_state;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct ce_state *ce_state = pipe_info->ce_hdl;
+	struct sk_buff *skb;
+	dma_addr_t ce_data;
+	int i, ret = 0;
+
+	if (pipe_info->buf_sz == 0)
+		return 0;
+
+	for (i = 0; i < num; i++) {
+		skb = dev_alloc_skb(pipe_info->buf_sz);
+		if (!skb) {
+			ath10k_warn("could not allocate skbuff for pipe %d\n",
+				    num);
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
+
+		ce_data = dma_map_single(ar->dev, skb->data,
+					 skb->len + skb_tailroom(skb),
+					 DMA_FROM_DEVICE);
+
+		if (unlikely(dma_mapping_error(ar->dev, ce_data))) {
+			ath10k_warn("could not dma map skbuff\n");
+			dev_kfree_skb_any(skb);
+			ret = -EIO;
+			goto err;
+		}
+
+		ATH10K_SKB_CB(skb)->paddr = ce_data;
+
+		pci_dma_sync_single_for_device(ar_pci->pdev, ce_data,
+					       pipe_info->buf_sz,
+					       PCI_DMA_FROMDEVICE);
+
+		ret = ath10k_ce_recv_buf_enqueue(ce_state, (void *)skb,
+						 ce_data);
+		if (ret) {
+			ath10k_warn("could not enqueue to pipe %d (%d)\n",
+				    num, ret);
+			goto err;
+		}
+	}
+
+	return ret;
+
+err:
+	ath10k_pci_rx_pipe_cleanup(pipe_info);
+	return ret;
+}
+
+static int ath10k_pci_post_rx(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct hif_ce_pipe_info *pipe_info;
+	const struct ce_attr *attr;
+	int pipe_num, ret = 0;
+
+	for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) {
+		pipe_info = &ar_pci->pipe_info[pipe_num];
+		attr = &host_ce_config_wlan[pipe_num];
+
+		if (attr->dest_nentries == 0)
+			continue;
+
+		ret = ath10k_pci_post_rx_pipe(pipe_info,
+					      attr->dest_nentries - 1);
+		if (ret) {
+			ath10k_warn("Unable to replenish recv buffers for pipe: %d\n",
+				    pipe_num);
+
+			for (; pipe_num >= 0; pipe_num--) {
+				pipe_info = &ar_pci->pipe_info[pipe_num];
+				ath10k_pci_rx_pipe_cleanup(pipe_info);
+			}
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int ath10k_pci_hif_start(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ret;
+
+	ret = ath10k_pci_start_ce(ar);
+	if (ret) {
+		ath10k_warn("could not start CE (%d)\n", ret);
+		return ret;
+	}
+
+	/* Post buffers once to start things off. */
+	ret = ath10k_pci_post_rx(ar);
+	if (ret) {
+		ath10k_warn("could not post rx pipes (%d)\n", ret);
+		return ret;
+	}
+
+	ar_pci->started = 1;
+	return 0;
+}
+
+static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info)
+{
+	struct ath10k *ar;
+	struct ath10k_pci *ar_pci;
+	struct ce_state *ce_hdl;
+	u32 buf_sz;
+	struct sk_buff *netbuf;
+	u32 ce_data;
+
+	buf_sz = pipe_info->buf_sz;
+
+	/* Unused Copy Engine */
+	if (buf_sz == 0)
+		return;
+
+	ar = pipe_info->hif_ce_state;
+	ar_pci = ath10k_pci_priv(ar);
+
+	if (!ar_pci->started)
+		return;
+
+	ce_hdl = pipe_info->ce_hdl;
+
+	while (ath10k_ce_revoke_recv_next(ce_hdl, (void **)&netbuf,
+					  &ce_data) == 0) {
+		dma_unmap_single(ar->dev, ATH10K_SKB_CB(netbuf)->paddr,
+				 netbuf->len + skb_tailroom(netbuf),
+				 DMA_FROM_DEVICE);
+		dev_kfree_skb_any(netbuf);
+	}
+}
+
+static void ath10k_pci_tx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info)
+{
+	struct ath10k *ar;
+	struct ath10k_pci *ar_pci;
+	struct ce_state *ce_hdl;
+	struct sk_buff *netbuf;
+	u32 ce_data;
+	unsigned int nbytes;
+	unsigned int id;
+	u32 buf_sz;
+
+	buf_sz = pipe_info->buf_sz;
+
+	/* Unused Copy Engine */
+	if (buf_sz == 0)
+		return;
+
+	ar = pipe_info->hif_ce_state;
+	ar_pci = ath10k_pci_priv(ar);
+
+	if (!ar_pci->started)
+		return;
+
+	ce_hdl = pipe_info->ce_hdl;
+
+	while (ath10k_ce_cancel_send_next(ce_hdl, (void **)&netbuf,
+					  &ce_data, &nbytes, &id) == 0) {
+		if (netbuf != CE_SENDLIST_ITEM_CTXT)
+			/*
+			 * Indicate the completion to higer layer to free
+			 * the buffer
+			 */
+			ATH10K_SKB_CB(netbuf)->is_aborted = true;
+			ar_pci->msg_callbacks_current.tx_completion(ar,
+								    netbuf,
+								    id);
+	}
+}
+
+/*
+ * Cleanup residual buffers for device shutdown:
+ *    buffers that were enqueued for receive
+ *    buffers that were to be sent
+ * Note: Buffers that had completed but which were
+ * not yet processed are on a completion queue. They
+ * are handled when the completion thread shuts down.
+ */
+static void ath10k_pci_buffer_cleanup(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int pipe_num;
+
+	for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) {
+		struct hif_ce_pipe_info *pipe_info;
+
+		pipe_info = &ar_pci->pipe_info[pipe_num];
+		ath10k_pci_rx_pipe_cleanup(pipe_info);
+		ath10k_pci_tx_pipe_cleanup(pipe_info);
+	}
+}
+
+static void ath10k_pci_ce_deinit(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct hif_ce_pipe_info *pipe_info;
+	int pipe_num;
+
+	for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) {
+		pipe_info = &ar_pci->pipe_info[pipe_num];
+		if (pipe_info->ce_hdl) {
+			ath10k_ce_deinit(pipe_info->ce_hdl);
+			pipe_info->ce_hdl = NULL;
+			pipe_info->buf_sz = 0;
+		}
+	}
+}
+
+static void ath10k_pci_hif_stop(struct ath10k *ar)
+{
+	ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
+
+	ath10k_pci_stop_ce(ar);
+
+	/* At this point, asynchronous threads are stopped, the target should
+	 * not DMA nor interrupt. We process the leftovers and then free
+	 * everything else up. */
+
+	ath10k_pci_process_ce(ar);
+	ath10k_pci_cleanup_ce(ar);
+	ath10k_pci_buffer_cleanup(ar);
+	ath10k_pci_ce_deinit(ar);
+}
+
+static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
+					   void *req, u32 req_len,
+					   void *resp, u32 *resp_len)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct ce_state *ce_tx = ar_pci->pipe_info[BMI_CE_NUM_TO_TARG].ce_hdl;
+	struct ce_state *ce_rx = ar_pci->pipe_info[BMI_CE_NUM_TO_HOST].ce_hdl;
+	dma_addr_t req_paddr = 0;
+	dma_addr_t resp_paddr = 0;
+	struct bmi_xfer xfer = {};
+	void *treq, *tresp = NULL;
+	int ret = 0;
+
+	if (resp && !resp_len)
+		return -EINVAL;
+
+	if (resp && resp_len && *resp_len == 0)
+		return -EINVAL;
+
+	treq = kmemdup(req, req_len, GFP_KERNEL);
+	if (!treq)
+		return -ENOMEM;
+
+	req_paddr = dma_map_single(ar->dev, treq, req_len, DMA_TO_DEVICE);
+	ret = dma_mapping_error(ar->dev, req_paddr);
+	if (ret)
+		goto err_dma;
+
+	if (resp && resp_len) {
+		tresp = kzalloc(*resp_len, GFP_KERNEL);
+		if (!tresp) {
+			ret = -ENOMEM;
+			goto err_req;
+		}
+
+		resp_paddr = dma_map_single(ar->dev, tresp, *resp_len,
+					    DMA_FROM_DEVICE);
+		ret = dma_mapping_error(ar->dev, resp_paddr);
+		if (ret)
+			goto err_req;
+
+		xfer.wait_for_resp = true;
+		xfer.resp_len = 0;
+
+		ath10k_ce_recv_buf_enqueue(ce_rx, &xfer, resp_paddr);
+	}
+
+	init_completion(&xfer.done);
+
+	ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0);
+	if (ret)
+		goto err_resp;
+
+	ret = wait_for_completion_timeout(&xfer.done,
+					  BMI_COMMUNICATION_TIMEOUT_HZ);
+	if (ret <= 0) {
+		u32 unused_buffer;
+		unsigned int unused_nbytes;
+		unsigned int unused_id;
+
+		ret = -ETIMEDOUT;
+		ath10k_ce_cancel_send_next(ce_tx, NULL, &unused_buffer,
+					   &unused_nbytes, &unused_id);
+	} else {
+		/* non-zero means we did not time out */
+		ret = 0;
+	}
+
+err_resp:
+	if (resp) {
+		u32 unused_buffer;
+
+		ath10k_ce_revoke_recv_next(ce_rx, NULL, &unused_buffer);
+		dma_unmap_single(ar->dev, resp_paddr,
+				 *resp_len, DMA_FROM_DEVICE);
+	}
+err_req:
+	dma_unmap_single(ar->dev, req_paddr, req_len, DMA_TO_DEVICE);
+
+	if (ret == 0 && resp_len) {
+		*resp_len = min(*resp_len, xfer.resp_len);
+		memcpy(resp, tresp, xfer.resp_len);
+	}
+err_dma:
+	kfree(treq);
+	kfree(tresp);
+
+	return ret;
+}
+
+static void ath10k_pci_bmi_send_done(struct ce_state *ce_state,
+				     void *transfer_context,
+				     u32 data,
+				     unsigned int nbytes,
+				     unsigned int transfer_id)
+{
+	struct bmi_xfer *xfer = transfer_context;
+
+	if (xfer->wait_for_resp)
+		return;
+
+	complete(&xfer->done);
+}
+
+static void ath10k_pci_bmi_recv_data(struct ce_state *ce_state,
+				     void *transfer_context,
+				     u32 data,
+				     unsigned int nbytes,
+				     unsigned int transfer_id,
+				     unsigned int flags)
+{
+	struct bmi_xfer *xfer = transfer_context;
+
+	if (!xfer->wait_for_resp) {
+		ath10k_warn("unexpected: BMI data received; ignoring\n");
+		return;
+	}
+
+	xfer->resp_len = nbytes;
+	complete(&xfer->done);
+}
+
+/*
+ * Map from service/endpoint to Copy Engine.
+ * This table is derived from the CE_PCI TABLE, above.
+ * It is passed to the Target at startup for use by firmware.
+ */
+static const struct service_to_pipe target_service_to_ce_map_wlan[] = {
+	{
+		 ATH10K_HTC_SVC_ID_WMI_DATA_VO,
+		 PIPEDIR_OUT,		/* out = UL = host -> target */
+		 3,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_WMI_DATA_VO,
+		 PIPEDIR_IN,		/* in = DL = target -> host */
+		 2,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_WMI_DATA_BK,
+		 PIPEDIR_OUT,		/* out = UL = host -> target */
+		 3,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_WMI_DATA_BK,
+		 PIPEDIR_IN,		/* in = DL = target -> host */
+		 2,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_WMI_DATA_BE,
+		 PIPEDIR_OUT,		/* out = UL = host -> target */
+		 3,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_WMI_DATA_BE,
+		 PIPEDIR_IN,		/* in = DL = target -> host */
+		 2,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_WMI_DATA_VI,
+		 PIPEDIR_OUT,		/* out = UL = host -> target */
+		 3,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_WMI_DATA_VI,
+		 PIPEDIR_IN,		/* in = DL = target -> host */
+		 2,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_WMI_CONTROL,
+		 PIPEDIR_OUT,		/* out = UL = host -> target */
+		 3,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_WMI_CONTROL,
+		 PIPEDIR_IN,		/* in = DL = target -> host */
+		 2,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_RSVD_CTRL,
+		 PIPEDIR_OUT,		/* out = UL = host -> target */
+		 0,		/* could be moved to 3 (share with WMI) */
+	},
+	{
+		 ATH10K_HTC_SVC_ID_RSVD_CTRL,
+		 PIPEDIR_IN,		/* in = DL = target -> host */
+		 1,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS,	/* not currently used */
+		 PIPEDIR_OUT,		/* out = UL = host -> target */
+		 0,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS,	/* not currently used */
+		 PIPEDIR_IN,		/* in = DL = target -> host */
+		 1,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_HTT_DATA_MSG,
+		 PIPEDIR_OUT,		/* out = UL = host -> target */
+		 4,
+	},
+	{
+		 ATH10K_HTC_SVC_ID_HTT_DATA_MSG,
+		 PIPEDIR_IN,		/* in = DL = target -> host */
+		 1,
+	},
+
+	/* (Additions here) */
+
+	{				/* Must be last */
+		 0,
+		 0,
+		 0,
+	},
+};
+
+/*
+ * Send an interrupt to the device to wake up the Target CPU
+ * so it has an opportunity to notice any changed state.
+ */
+static int ath10k_pci_wake_target_cpu(struct ath10k *ar)
+{
+	int ret;
+	u32 core_ctrl;
+
+	ret = ath10k_pci_diag_read_access(ar, SOC_CORE_BASE_ADDRESS |
+					      CORE_CTRL_ADDRESS,
+					  &core_ctrl);
+	if (ret) {
+		ath10k_warn("Unable to read core ctrl\n");
+		return ret;
+	}
+
+	/* A_INUM_FIRMWARE interrupt to Target CPU */
+	core_ctrl |= CORE_CTRL_CPU_INTR_MASK;
+
+	ret = ath10k_pci_diag_write_access(ar, SOC_CORE_BASE_ADDRESS |
+					       CORE_CTRL_ADDRESS,
+					   core_ctrl);
+	if (ret)
+		ath10k_warn("Unable to set interrupt mask\n");
+
+	return ret;
+}
+
+static int ath10k_pci_init_config(struct ath10k *ar)
+{
+	u32 interconnect_targ_addr;
+	u32 pcie_state_targ_addr = 0;
+	u32 pipe_cfg_targ_addr = 0;
+	u32 svc_to_pipe_map = 0;
+	u32 pcie_config_flags = 0;
+	u32 ealloc_value;
+	u32 ealloc_targ_addr;
+	u32 flag2_value;
+	u32 flag2_targ_addr;
+	int ret = 0;
+
+	/* Download to Target the CE Config and the service-to-CE map */
+	interconnect_targ_addr =
+		host_interest_item_address(HI_ITEM(hi_interconnect_state));
+
+	/* Supply Target-side CE configuration */
+	ret = ath10k_pci_diag_read_access(ar, interconnect_targ_addr,
+					  &pcie_state_targ_addr);
+	if (ret != 0) {
+		ath10k_err("Failed to get pcie state addr: %d\n", ret);
+		return ret;
+	}
+
+	if (pcie_state_targ_addr == 0) {
+		ret = -EIO;
+		ath10k_err("Invalid pcie state addr\n");
+		return ret;
+	}
+
+	ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr +
+					  offsetof(struct pcie_state,
+						   pipe_cfg_addr),
+					  &pipe_cfg_targ_addr);
+	if (ret != 0) {
+		ath10k_err("Failed to get pipe cfg addr: %d\n", ret);
+		return ret;
+	}
+
+	if (pipe_cfg_targ_addr == 0) {
+		ret = -EIO;
+		ath10k_err("Invalid pipe cfg addr\n");
+		return ret;
+	}
+
+	ret = ath10k_pci_diag_write_mem(ar, pipe_cfg_targ_addr,
+				 target_ce_config_wlan,
+				 sizeof(target_ce_config_wlan));
+
+	if (ret != 0) {
+		ath10k_err("Failed to write pipe cfg: %d\n", ret);
+		return ret;
+	}
+
+	ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr +
+					  offsetof(struct pcie_state,
+						   svc_to_pipe_map),
+					  &svc_to_pipe_map);
+	if (ret != 0) {
+		ath10k_err("Failed to get svc/pipe map: %d\n", ret);
+		return ret;
+	}
+
+	if (svc_to_pipe_map == 0) {
+		ret = -EIO;
+		ath10k_err("Invalid svc_to_pipe map\n");
+		return ret;
+	}
+
+	ret = ath10k_pci_diag_write_mem(ar, svc_to_pipe_map,
+				 target_service_to_ce_map_wlan,
+				 sizeof(target_service_to_ce_map_wlan));
+	if (ret != 0) {
+		ath10k_err("Failed to write svc/pipe map: %d\n", ret);
+		return ret;
+	}
+
+	ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr +
+					  offsetof(struct pcie_state,
+						   config_flags),
+					  &pcie_config_flags);
+	if (ret != 0) {
+		ath10k_err("Failed to get pcie config_flags: %d\n", ret);
+		return ret;
+	}
+
+	pcie_config_flags &= ~PCIE_CONFIG_FLAG_ENABLE_L1;
+
+	ret = ath10k_pci_diag_write_mem(ar, pcie_state_targ_addr +
+				 offsetof(struct pcie_state, config_flags),
+				 &pcie_config_flags,
+				 sizeof(pcie_config_flags));
+	if (ret != 0) {
+		ath10k_err("Failed to write pcie config_flags: %d\n", ret);
+		return ret;
+	}
+
+	/* configure early allocation */
+	ealloc_targ_addr = host_interest_item_address(HI_ITEM(hi_early_alloc));
+
+	ret = ath10k_pci_diag_read_access(ar, ealloc_targ_addr, &ealloc_value);
+	if (ret != 0) {
+		ath10k_err("Faile to get early alloc val: %d\n", ret);
+		return ret;
+	}
+
+	/* first bank is switched to IRAM */
+	ealloc_value |= ((HI_EARLY_ALLOC_MAGIC << HI_EARLY_ALLOC_MAGIC_SHIFT) &
+			 HI_EARLY_ALLOC_MAGIC_MASK);
+	ealloc_value |= ((1 << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) &
+			 HI_EARLY_ALLOC_IRAM_BANKS_MASK);
+
+	ret = ath10k_pci_diag_write_access(ar, ealloc_targ_addr, ealloc_value);
+	if (ret != 0) {
+		ath10k_err("Failed to set early alloc val: %d\n", ret);
+		return ret;
+	}
+
+	/* Tell Target to proceed with initialization */
+	flag2_targ_addr = host_interest_item_address(HI_ITEM(hi_option_flag2));
+
+	ret = ath10k_pci_diag_read_access(ar, flag2_targ_addr, &flag2_value);
+	if (ret != 0) {
+		ath10k_err("Failed to get option val: %d\n", ret);
+		return ret;
+	}
+
+	flag2_value |= HI_OPTION_EARLY_CFG_DONE;
+
+	ret = ath10k_pci_diag_write_access(ar, flag2_targ_addr, flag2_value);
+	if (ret != 0) {
+		ath10k_err("Failed to set option val: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+
+
+static int ath10k_pci_ce_init(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	struct hif_ce_pipe_info *pipe_info;
+	const struct ce_attr *attr;
+	int pipe_num;
+
+	for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) {
+		pipe_info = &ar_pci->pipe_info[pipe_num];
+		pipe_info->pipe_num = pipe_num;
+		pipe_info->hif_ce_state = ar;
+		attr = &host_ce_config_wlan[pipe_num];
+
+		pipe_info->ce_hdl = ath10k_ce_init(ar, pipe_num, attr);
+		if (pipe_info->ce_hdl == NULL) {
+			ath10k_err("Unable to initialize CE for pipe: %d\n",
+				   pipe_num);
+
+			/* It is safe to call it here. It checks if ce_hdl is
+			 * valid for each pipe */
+			ath10k_pci_ce_deinit(ar);
+			return -1;
+		}
+
+		if (pipe_num == ar_pci->ce_count - 1) {
+			/*
+			 * Reserve the ultimate CE for
+			 * diagnostic Window support
+			 */
+			ar_pci->ce_diag =
+			ar_pci->pipe_info[ar_pci->ce_count - 1].ce_hdl;
+			continue;
+		}
+
+		pipe_info->buf_sz = (size_t) (attr->src_sz_max);
+	}
+
+	/*
+	 * Initially, establish CE completion handlers for use with BMI.
+	 * These are overwritten with generic handlers after we exit BMI phase.
+	 */
+	pipe_info = &ar_pci->pipe_info[BMI_CE_NUM_TO_TARG];
+	ath10k_ce_send_cb_register(pipe_info->ce_hdl,
+				   ath10k_pci_bmi_send_done, 0);
+
+	pipe_info = &ar_pci->pipe_info[BMI_CE_NUM_TO_HOST];
+	ath10k_ce_recv_cb_register(pipe_info->ce_hdl,
+				   ath10k_pci_bmi_recv_data);
+
+	return 0;
+}
+
+static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	u32 fw_indicator_address, fw_indicator;
+
+	ath10k_pci_wake(ar);
+
+	fw_indicator_address = ar_pci->fw_indicator_address;
+	fw_indicator = ath10k_pci_read32(ar, fw_indicator_address);
+
+	if (fw_indicator & FW_IND_EVENT_PENDING) {
+		/* ACK: clear Target-side pending event */
+		ath10k_pci_write32(ar, fw_indicator_address,
+				   fw_indicator & ~FW_IND_EVENT_PENDING);
+
+		if (ar_pci->started) {
+			ath10k_pci_hif_dump_area(ar);
+		} else {
+			/*
+			 * Probable Target failure before we're prepared
+			 * to handle it.  Generally unexpected.
+			 */
+			ath10k_warn("early firmware event indicated\n");
+		}
+	}
+
+	ath10k_pci_sleep(ar);
+}
+
+static const struct ath10k_hif_ops ath10k_pci_hif_ops = {
+	.send_head		= ath10k_pci_hif_send_head,
+	.exchange_bmi_msg	= ath10k_pci_hif_exchange_bmi_msg,
+	.start			= ath10k_pci_hif_start,
+	.stop			= ath10k_pci_hif_stop,
+	.map_service_to_pipe	= ath10k_pci_hif_map_service_to_pipe,
+	.get_default_pipe	= ath10k_pci_hif_get_default_pipe,
+	.send_complete_check	= ath10k_pci_hif_send_complete_check,
+	.init			= ath10k_pci_hif_post_init,
+	.get_free_queue_number	= ath10k_pci_hif_get_free_queue_number,
+};
+
+static void ath10k_pci_ce_tasklet(unsigned long ptr)
+{
+	struct hif_ce_pipe_info *pipe = (struct hif_ce_pipe_info *)ptr;
+	struct ath10k_pci *ar_pci = pipe->ar_pci;
+
+	ath10k_ce_per_engine_service(ar_pci->ar, pipe->pipe_num);
+}
+
+static void ath10k_msi_err_tasklet(unsigned long data)
+{
+	struct ath10k *ar = (struct ath10k *)data;
+
+	ath10k_pci_fw_interrupt_handler(ar);
+}
+
+/*
+ * Handler for a per-engine interrupt on a PARTICULAR CE.
+ * This is used in cases where each CE has a private MSI interrupt.
+ */
+static irqreturn_t ath10k_pci_per_engine_handler(int irq, void *arg)
+{
+	struct ath10k *ar = arg;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ce_id = irq - ar_pci->pdev->irq - MSI_ASSIGN_CE_INITIAL;
+
+	if (ce_id < 0 || ce_id >= ARRAY_SIZE(ar_pci->pipe_info)) {
+		ath10k_warn("unexpected/invalid irq %d ce_id %d\n", irq, ce_id);
+		return IRQ_HANDLED;
+	}
+
+	/*
+	 * NOTE: We are able to derive ce_id from irq because we
+	 * use a one-to-one mapping for CE's 0..5.
+	 * CE's 6 & 7 do not use interrupts at all.
+	 *
+	 * This mapping must be kept in sync with the mapping
+	 * used by firmware.
+	 */
+	tasklet_schedule(&ar_pci->pipe_info[ce_id].intr);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t ath10k_pci_msi_fw_handler(int irq, void *arg)
+{
+	struct ath10k *ar = arg;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	tasklet_schedule(&ar_pci->msi_fw_err);
+	return IRQ_HANDLED;
+}
+
+/*
+ * Top-level interrupt handler for all PCI interrupts from a Target.
+ * When a block of MSI interrupts is allocated, this top-level handler
+ * is not used; instead, we directly call the correct sub-handler.
+ */
+static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg)
+{
+	struct ath10k *ar = arg;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	if (ar_pci->num_msi_intrs == 0) {
+		/*
+		 * IMPORTANT: INTR_CLR regiser has to be set after
+		 * INTR_ENABLE is set to 0, otherwise interrupt can not be
+		 * really cleared.
+		 */
+		iowrite32(0, ar_pci->mem +
+			  (SOC_CORE_BASE_ADDRESS |
+			   PCIE_INTR_ENABLE_ADDRESS));
+		iowrite32(PCIE_INTR_FIRMWARE_MASK |
+			  PCIE_INTR_CE_MASK_ALL,
+			  ar_pci->mem + (SOC_CORE_BASE_ADDRESS |
+					 PCIE_INTR_CLR_ADDRESS));
+		/*
+		 * IMPORTANT: this extra read transaction is required to
+		 * flush the posted write buffer.
+		 */
+		(void) ioread32(ar_pci->mem +
+				(SOC_CORE_BASE_ADDRESS |
+				 PCIE_INTR_ENABLE_ADDRESS));
+	}
+
+	tasklet_schedule(&ar_pci->intr_tq);
+
+	return IRQ_HANDLED;
+}
+
+static void ath10k_pci_tasklet(unsigned long data)
+{
+	struct ath10k *ar = (struct ath10k *)data;
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	ath10k_pci_fw_interrupt_handler(ar); /* FIXME: Handle FW error */
+	ath10k_ce_per_engine_service_any(ar);
+
+	if (ar_pci->num_msi_intrs == 0) {
+		/* Enable Legacy PCI line interrupts */
+		iowrite32(PCIE_INTR_FIRMWARE_MASK |
+			  PCIE_INTR_CE_MASK_ALL,
+			  ar_pci->mem + (SOC_CORE_BASE_ADDRESS |
+					 PCIE_INTR_ENABLE_ADDRESS));
+		/*
+		 * IMPORTANT: this extra read transaction is required to
+		 * flush the posted write buffer
+		 */
+		(void) ioread32(ar_pci->mem +
+				(SOC_CORE_BASE_ADDRESS |
+				 PCIE_INTR_ENABLE_ADDRESS));
+	}
+}
+
+static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ret;
+	int i;
+
+	ret = pci_enable_msi_block(ar_pci->pdev, num);
+	if (ret)
+		return ret;
+
+	ret = request_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW,
+			  ath10k_pci_msi_fw_handler,
+			  IRQF_SHARED, "ath10k_pci", ar);
+	if (ret)
+		return ret;
+
+	for (i = MSI_ASSIGN_CE_INITIAL; i <= MSI_ASSIGN_CE_MAX; i++) {
+		ret = request_irq(ar_pci->pdev->irq + i,
+				  ath10k_pci_per_engine_handler,
+				  IRQF_SHARED, "ath10k_pci", ar);
+		if (ret) {
+			ath10k_warn("request_irq(%d) failed %d\n",
+				    ar_pci->pdev->irq + i, ret);
+
+			for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--)
+				free_irq(ar_pci->pdev->irq + i, ar);
+
+			free_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, ar);
+			pci_disable_msi(ar_pci->pdev);
+			return ret;
+		}
+	}
+
+	ath10k_info("MSI-X interrupt handling (%d intrs)\n", num);
+	return 0;
+}
+
+static int ath10k_pci_start_intr_msi(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ret;
+
+	ret = pci_enable_msi(ar_pci->pdev);
+	if (ret < 0)
+		return ret;
+
+	ret = request_irq(ar_pci->pdev->irq,
+			  ath10k_pci_interrupt_handler,
+			  IRQF_SHARED, "ath10k_pci", ar);
+	if (ret < 0) {
+		pci_disable_msi(ar_pci->pdev);
+		return ret;
+	}
+
+	ath10k_info("MSI interrupt handling\n");
+	return 0;
+}
+
+static int ath10k_pci_start_intr_legacy(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int ret;
+
+	ret = request_irq(ar_pci->pdev->irq,
+			  ath10k_pci_interrupt_handler,
+			  IRQF_SHARED, "ath10k_pci", ar);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Make sure to wake the Target before enabling Legacy
+	 * Interrupt.
+	 */
+	iowrite32(PCIE_SOC_WAKE_V_MASK,
+		  ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
+		  PCIE_SOC_WAKE_ADDRESS);
+
+	ath10k_pci_wait(ar);
+
+	/*
+	 * A potential race occurs here: The CORE_BASE write
+	 * depends on target correctly decoding AXI address but
+	 * host won't know when target writes BAR to CORE_CTRL.
+	 * This write might get lost if target has NOT written BAR.
+	 * For now, fix the race by repeating the write in below
+	 * synchronization checking.
+	 */
+	iowrite32(PCIE_INTR_FIRMWARE_MASK |
+		  PCIE_INTR_CE_MASK_ALL,
+		  ar_pci->mem + (SOC_CORE_BASE_ADDRESS |
+				 PCIE_INTR_ENABLE_ADDRESS));
+	iowrite32(PCIE_SOC_WAKE_RESET,
+		  ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
+		  PCIE_SOC_WAKE_ADDRESS);
+
+	ath10k_info("legacy interrupt handling\n");
+	return 0;
+}
+
+static int ath10k_pci_start_intr(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int num = MSI_NUM_REQUEST;
+	int ret;
+	int i;
+
+	tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long) ar);
+	tasklet_init(&ar_pci->msi_fw_err, ath10k_msi_err_tasklet,
+		     (unsigned long) ar);
+
+	for (i = 0; i < CE_COUNT; i++) {
+		ar_pci->pipe_info[i].ar_pci = ar_pci;
+		tasklet_init(&ar_pci->pipe_info[i].intr,
+			     ath10k_pci_ce_tasklet,
+			     (unsigned long)&ar_pci->pipe_info[i]);
+	}
+
+	if (!test_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features))
+		num = 1;
+
+	if (num > 1) {
+		ret = ath10k_pci_start_intr_msix(ar, num);
+		if (ret == 0)
+			goto exit;
+
+		ath10k_warn("MSI-X didn't succeed (%d), trying MSI\n", ret);
+		num = 1;
+	}
+
+	if (num == 1) {
+		ret = ath10k_pci_start_intr_msi(ar);
+		if (ret == 0)
+			goto exit;
+
+		ath10k_warn("MSI didn't succeed (%d), trying legacy INTR\n",
+			    ret);
+		num = 0;
+	}
+
+	ret = ath10k_pci_start_intr_legacy(ar);
+
+exit:
+	ar_pci->num_msi_intrs = num;
+	ar_pci->ce_count = CE_COUNT;
+	return ret;
+}
+
+static void ath10k_pci_stop_intr(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int i;
+
+	/* There's at least one interrupt irregardless whether its legacy INTR
+	 * or MSI or MSI-X */
+	for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++)
+		free_irq(ar_pci->pdev->irq + i, ar);
+
+	if (ar_pci->num_msi_intrs > 0)
+		pci_disable_msi(ar_pci->pdev);
+}
+
+static int ath10k_pci_reset_target(struct ath10k *ar)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	int wait_limit = 300; /* 3 sec */
+
+	/* Wait for Target to finish initialization before we proceed. */
+	iowrite32(PCIE_SOC_WAKE_V_MASK,
+		  ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
+		  PCIE_SOC_WAKE_ADDRESS);
+
+	ath10k_pci_wait(ar);
+
+	while (wait_limit-- &&
+	       !(ioread32(ar_pci->mem + FW_INDICATOR_ADDRESS) &
+		 FW_IND_INITIALIZED)) {
+		if (ar_pci->num_msi_intrs == 0)
+			/* Fix potential race by repeating CORE_BASE writes */
+			iowrite32(PCIE_INTR_FIRMWARE_MASK |
+				  PCIE_INTR_CE_MASK_ALL,
+				  ar_pci->mem + (SOC_CORE_BASE_ADDRESS |
+						 PCIE_INTR_ENABLE_ADDRESS));
+		mdelay(10);
+	}
+
+	if (wait_limit < 0) {
+		ath10k_err("Target stalled\n");
+		iowrite32(PCIE_SOC_WAKE_RESET,
+			  ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
+			  PCIE_SOC_WAKE_ADDRESS);
+		return -EIO;
+	}
+
+	iowrite32(PCIE_SOC_WAKE_RESET,
+		  ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
+		  PCIE_SOC_WAKE_ADDRESS);
+
+	return 0;
+}
+
+static void ath10k_pci_device_reset(struct ath10k_pci *ar_pci)
+{
+	struct ath10k *ar = ar_pci->ar;
+	void __iomem *mem = ar_pci->mem;
+	int i;
+	u32 val;
+
+	if (!SOC_GLOBAL_RESET_ADDRESS)
+		return;
+
+	if (!mem)
+		return;
+
+	ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS,
+			       PCIE_SOC_WAKE_V_MASK);
+	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
+		if (ath10k_pci_target_is_awake(ar))
+			break;
+		msleep(1);
+	}
+
+	/* Put Target, including PCIe, into RESET. */
+	val = ath10k_pci_reg_read32(mem, SOC_GLOBAL_RESET_ADDRESS);
+	val |= 1;
+	ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val);
+
+	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
+		if (ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) &
+					  RTC_STATE_COLD_RESET_MASK)
+			break;
+		msleep(1);
+	}
+
+	/* Pull Target, including PCIe, out of RESET. */
+	val &= ~1;
+	ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val);
+
+	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
+		if (!(ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) &
+					    RTC_STATE_COLD_RESET_MASK))
+			break;
+		msleep(1);
+	}
+
+	ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
+}
+
+static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci)
+{
+	int i;
+
+	for (i = 0; i < ATH10K_PCI_FEATURE_COUNT; i++) {
+		if (!test_bit(i, ar_pci->features))
+			continue;
+
+		switch (i) {
+		case ATH10K_PCI_FEATURE_MSI_X:
+			ath10k_dbg(ATH10K_DBG_PCI, "device supports MSI-X\n");
+			break;
+		case ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND:
+			ath10k_dbg(ATH10K_DBG_PCI, "QCA988X_1.0 workaround enabled\n");
+			break;
+		}
+	}
+}
+
+static int ath10k_pci_probe(struct pci_dev *pdev,
+			    const struct pci_device_id *pci_dev)
+{
+	void __iomem *mem;
+	int ret = 0;
+	struct ath10k *ar;
+	struct ath10k_pci *ar_pci;
+	u32 lcr_val;
+
+	ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
+
+	ar_pci = kzalloc(sizeof(*ar_pci), GFP_KERNEL);
+	if (ar_pci == NULL)
+		return -ENOMEM;
+
+	ar_pci->pdev = pdev;
+	ar_pci->dev = &pdev->dev;
+
+	switch (pci_dev->device) {
+	case QCA988X_1_0_DEVICE_ID:
+		set_bit(ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND, ar_pci->features);
+		break;
+	case QCA988X_2_0_DEVICE_ID:
+		set_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features);
+		break;
+	default:
+		ret = -ENODEV;
+		ath10k_err("Unkown device ID: %d\n", pci_dev->device);
+		goto err_ar_pci;
+	}
+
+	ath10k_pci_dump_features(ar_pci);
+
+	ar = ath10k_core_create(ar_pci, ar_pci->dev, ATH10K_BUS_PCI,
+				&ath10k_pci_hif_ops);
+	if (!ar) {
+		ath10k_err("ath10k_core_create failed!\n");
+		ret = -EINVAL;
+		goto err_ar_pci;
+	}
+
+	/* Enable QCA988X_1.0 HW workarounds */
+	if (test_bit(ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND, ar_pci->features))
+		spin_lock_init(&ar_pci->hw_v1_workaround_lock);
+
+	ar_pci->ar = ar;
+	ar_pci->fw_indicator_address = FW_INDICATOR_ADDRESS;
+	atomic_set(&ar_pci->keep_awake_count, 0);
+
+	pci_set_drvdata(pdev, ar);
+
+	/*
+	 * Without any knowledge of the Host, the Target may have been reset or
+	 * power cycled and its Config Space may no longer reflect the PCI
+	 * address space that was assigned earlier by the PCI infrastructure.
+	 * Refresh it now.
+	 */
+	ret = pci_assign_resource(pdev, BAR_NUM);
+	if (ret) {
+		ath10k_err("cannot assign PCI space: %d\n", ret);
+		goto err_ar;
+	}
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		ath10k_err("cannot enable PCI device: %d\n", ret);
+		goto err_ar;
+	}
+
+	/* Request MMIO resources */
+	ret = pci_request_region(pdev, BAR_NUM, "ath");
+	if (ret) {
+		ath10k_err("PCI MMIO reservation error: %d\n", ret);
+		goto err_device;
+	}
+
+	/*
+	 * Target structures have a limit of 32 bit DMA pointers.
+	 * DMA pointers can be wider than 32 bits by default on some systems.
+	 */
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (ret) {
+		ath10k_err("32-bit DMA not available: %d\n", ret);
+		goto err_region;
+	}
+
+	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (ret) {
+		ath10k_err("cannot enable 32-bit consistent DMA\n");
+		goto err_region;
+	}
+
+	/* Set bus master bit in PCI_COMMAND to enable DMA */
+	pci_set_master(pdev);
+
+	/*
+	 * Temporary FIX: disable ASPM
+	 * Will be removed after the OTP is programmed
+	 */
+	pci_read_config_dword(pdev, 0x80, &lcr_val);
+	pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00));
+
+	/* Arrange for access to Target SoC registers. */
+	mem = pci_iomap(pdev, BAR_NUM, 0);
+	if (!mem) {
+		ath10k_err("PCI iomap error\n");
+		ret = -EIO;
+		goto err_master;
+	}
+
+	ar_pci->mem = mem;
+
+	spin_lock_init(&ar_pci->ce_lock);
+
+	ar_pci->cacheline_sz = dma_get_cache_alignment();
+
+	ret = ath10k_pci_start_intr(ar);
+	if (ret) {
+		ath10k_err("could not start interrupt handling (%d)\n", ret);
+		goto err_iomap;
+	}
+
+	/*
+	 * Bring the target up cleanly.
+	 *
+	 * The target may be in an undefined state with an AUX-powered Target
+	 * and a Host in WoW mode. If the Host crashes, loses power, or is
+	 * restarted (without unloading the driver) then the Target is left
+	 * (aux) powered and running. On a subsequent driver load, the Target
+	 * is in an unexpected state. We try to catch that here in order to
+	 * reset the Target and retry the probe.
+	 */
+	ath10k_pci_device_reset(ar_pci);
+
+	ret = ath10k_pci_reset_target(ar);
+	if (ret)
+		goto err_intr;
+
+	if (ath10k_target_ps) {
+		ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save enabled\n");
+	} else {
+		/* Force AWAKE forever */
+		ath10k_dbg(ATH10K_DBG_PCI, "on-chip power save disabled\n");
+		ath10k_do_pci_wake(ar);
+	}
+
+	ret = ath10k_pci_ce_init(ar);
+	if (ret)
+		goto err_intr;
+
+	ret = ath10k_pci_init_config(ar);
+	if (ret)
+		goto err_ce;
+
+	ret = ath10k_pci_wake_target_cpu(ar);
+	if (ret) {
+		ath10k_err("could not wake up target CPU (%d)\n", ret);
+		goto err_ce;
+	}
+
+	ret = ath10k_core_register(ar);
+	if (ret) {
+		ath10k_err("could not register driver core (%d)\n", ret);
+		goto err_ce;
+	}
+
+	return 0;
+
+err_ce:
+	ath10k_pci_ce_deinit(ar);
+err_intr:
+	ath10k_pci_stop_intr(ar);
+err_iomap:
+	pci_iounmap(pdev, mem);
+err_master:
+	pci_clear_master(pdev);
+err_region:
+	pci_release_region(pdev, BAR_NUM);
+err_device:
+	pci_disable_device(pdev);
+err_ar:
+	pci_set_drvdata(pdev, NULL);
+	ath10k_core_destroy(ar);
+err_ar_pci:
+	/* call HIF PCI free here */
+	kfree(ar_pci);
+
+	return ret;
+}
+
+static void ath10k_pci_remove(struct pci_dev *pdev)
+{
+	struct ath10k *ar = pci_get_drvdata(pdev);
+	struct ath10k_pci *ar_pci;
+
+	ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
+
+	if (!ar)
+		return;
+
+	ar_pci = ath10k_pci_priv(ar);
+
+	if (!ar_pci)
+		return;
+
+	tasklet_kill(&ar_pci->msi_fw_err);
+
+	ath10k_core_unregister(ar);
+	ath10k_pci_stop_intr(ar);
+
+	pci_set_drvdata(pdev, NULL);
+	pci_iounmap(pdev, ar_pci->mem);
+	pci_release_region(pdev, BAR_NUM);
+	pci_clear_master(pdev);
+	pci_disable_device(pdev);
+
+	ath10k_core_destroy(ar);
+	kfree(ar_pci);
+}
+
+#if defined(CONFIG_PM_SLEEP)
+
+#define ATH10K_PCI_PM_CONTROL 0x44
+
+static int ath10k_pci_suspend(struct device *device)
+{
+	struct pci_dev *pdev = to_pci_dev(device);
+	struct ath10k *ar = pci_get_drvdata(pdev);
+	struct ath10k_pci *ar_pci;
+	u32 val;
+	int ret, retval;
+
+	ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
+
+	if (!ar)
+		return -ENODEV;
+
+	ar_pci = ath10k_pci_priv(ar);
+	if (!ar_pci)
+		return -ENODEV;
+
+	if (ath10k_core_target_suspend(ar))
+		return -EBUSY;
+
+	ret = wait_event_interruptible_timeout(ar->event_queue,
+						ar->is_target_paused == true,
+						1 * HZ);
+	if (ret < 0) {
+		ath10k_warn("suspend interrupted (%d)\n", ret);
+		retval = ret;
+		goto resume;
+	} else if (ret == 0) {
+		ath10k_warn("suspend timed out - target pause event never came\n");
+		retval = EIO;
+		goto resume;
+	}
+
+	/*
+	 * reset is_target_paused and host can check that in next time,
+	 * or it will always be TRUE and host just skip the waiting
+	 * condition, it causes target assert due to host already
+	 * suspend
+	 */
+	ar->is_target_paused = false;
+
+	pci_read_config_dword(pdev, ATH10K_PCI_PM_CONTROL, &val);
+
+	if ((val & 0x000000ff) != 0x3) {
+		pci_save_state(pdev);
+		pci_disable_device(pdev);
+		pci_write_config_dword(pdev, ATH10K_PCI_PM_CONTROL,
+				       (val & 0xffffff00) | 0x03);
+	}
+
+	return 0;
+resume:
+	ret = ath10k_core_target_resume(ar);
+	if (ret)
+		ath10k_warn("could not resume (%d)\n", ret);
+
+	return retval;
+}
+
+static int ath10k_pci_resume(struct device *device)
+{
+	struct pci_dev *pdev = to_pci_dev(device);
+	struct ath10k *ar = pci_get_drvdata(pdev);
+	struct ath10k_pci *ar_pci;
+	int ret;
+	u32 val;
+
+	ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
+
+	if (!ar)
+		return -ENODEV;
+	ar_pci = ath10k_pci_priv(ar);
+
+	if (!ar_pci)
+		return -ENODEV;
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		ath10k_warn("cannot enable PCI device: %d\n", ret);
+		return ret;
+	}
+
+	pci_read_config_dword(pdev, ATH10K_PCI_PM_CONTROL, &val);
+
+	if ((val & 0x000000ff) != 0) {
+		pci_restore_state(pdev);
+		pci_write_config_dword(pdev, ATH10K_PCI_PM_CONTROL,
+				       val & 0xffffff00);
+		/*
+		 * Suspend/Resume resets the PCI configuration space,
+		 * so we have to re-disable the RETRY_TIMEOUT register (0x41)
+		 * to keep PCI Tx retries from interfering with C3 CPU state
+		 */
+		pci_read_config_dword(pdev, 0x40, &val);
+
+		if ((val & 0x0000ff00) != 0)
+			pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+	}
+
+	ret = ath10k_core_target_resume(ar);
+	if (ret)
+		ath10k_warn("target resume failed: %d\n", ret);
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(ath10k_dev_pm_ops,
+			 ath10k_pci_suspend,
+			 ath10k_pci_resume);
+
+#define ATH10K_PCI_PM_OPS (&ath10k_dev_pm_ops)
+
+#else
+
+#define ATH10K_PCI_PM_OPS NULL
+
+#endif /* CONFIG_PM_SLEEP */
+
+MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table);
+
+static struct pci_driver ath10k_pci_driver = {
+	.name = "ath10k_pci",
+	.id_table = ath10k_pci_id_table,
+	.probe = ath10k_pci_probe,
+	.remove = ath10k_pci_remove,
+	.driver.pm = ATH10K_PCI_PM_OPS,
+};
+
+static int __init ath10k_pci_init(void)
+{
+	int ret;
+
+	ret = pci_register_driver(&ath10k_pci_driver);
+	if (ret)
+		ath10k_err("pci_register_driver failed [%d]\n", ret);
+
+	return ret;
+}
+module_init(ath10k_pci_init);
+
+static void __exit ath10k_pci_exit(void)
+{
+	pci_unregister_driver(&ath10k_pci_driver);
+}
+
+module_exit(ath10k_pci_exit);
+
+MODULE_AUTHOR("Qualcomm Atheros");
+MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices");
+MODULE_LICENSE("Dual BSD/GPL");
+/*(DEBLOBBED)*/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/pci.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/pci.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/pci.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _PCI_H_
+#define _PCI_H_
+
+#include <linux/interrupt.h>
+
+#include "hw.h"
+#include "ce.h"
+
+/* FW dump area */
+#define REG_DUMP_COUNT_QCA988X 60
+
+/*
+ * maximum number of bytes that can be handled atomically by DiagRead/DiagWrite
+ */
+#define DIAG_TRANSFER_LIMIT 2048
+
+/*
+ * maximum number of bytes that can be
+ * handled atomically by DiagRead/DiagWrite
+ */
+#define DIAG_TRANSFER_LIMIT 2048
+
+struct bmi_xfer {
+	struct completion done;
+	bool wait_for_resp;
+	u32 resp_len;
+};
+
+struct ath10k_pci_compl {
+	struct list_head list;
+	int send_or_recv;
+	struct ce_state *ce_state;
+	struct hif_ce_pipe_info *pipe_info;
+	void *transfer_context;
+	unsigned int nbytes;
+	unsigned int transfer_id;
+	unsigned int flags;
+};
+
+/* compl_state.send_or_recv */
+#define HIF_CE_COMPLETE_FREE 0
+#define HIF_CE_COMPLETE_SEND 1
+#define HIF_CE_COMPLETE_RECV 2
+
+/*
+ * PCI-specific Target state
+ *
+ * NOTE: Structure is shared between Host software and Target firmware!
+ *
+ * Much of this may be of interest to the Host so
+ * HOST_INTEREST->hi_interconnect_state points here
+ * (and all members are 32-bit quantities in order to
+ * facilitate Host access). In particular, Host software is
+ * required to initialize pipe_cfg_addr and svc_to_pipe_map.
+ */
+struct pcie_state {
+	/* Pipe configuration Target address */
+	/* NB: ce_pipe_config[CE_COUNT] */
+	u32 pipe_cfg_addr;
+
+	/* Service to pipe map Target address */
+	/* NB: service_to_pipe[PIPE_TO_CE_MAP_CN] */
+	u32 svc_to_pipe_map;
+
+	/* number of MSI interrupts requested */
+	u32 msi_requested;
+
+	/* number of MSI interrupts granted */
+	u32 msi_granted;
+
+	/* Message Signalled Interrupt address */
+	u32 msi_addr;
+
+	/* Base data */
+	u32 msi_data;
+
+	/*
+	 * Data for firmware interrupt;
+	 * MSI data for other interrupts are
+	 * in various SoC registers
+	 */
+	u32 msi_fw_intr_data;
+
+	/* PCIE_PWR_METHOD_* */
+	u32 power_mgmt_method;
+
+	/* PCIE_CONFIG_FLAG_* */
+	u32 config_flags;
+};
+
+/* PCIE_CONFIG_FLAG definitions */
+#define PCIE_CONFIG_FLAG_ENABLE_L1  0x0000001
+
+/* Host software's Copy Engine configuration. */
+#define CE_ATTR_FLAGS 0
+
+/*
+ * Configuration information for a Copy Engine pipe.
+ * Passed from Host to Target during startup (one per CE).
+ *
+ * NOTE: Structure is shared between Host software and Target firmware!
+ */
+struct ce_pipe_config {
+	u32 pipenum;
+	u32 pipedir;
+	u32 nentries;
+	u32 nbytes_max;
+	u32 flags;
+	u32 reserved;
+};
+
+/*
+ * Directions for interconnect pipe configuration.
+ * These definitions may be used during configuration and are shared
+ * between Host and Target.
+ *
+ * Pipe Directions are relative to the Host, so PIPEDIR_IN means
+ * "coming IN over air through Target to Host" as with a WiFi Rx operation.
+ * Conversely, PIPEDIR_OUT means "going OUT from Host through Target over air"
+ * as with a WiFi Tx operation. This is somewhat awkward for the "middle-man"
+ * Target since things that are "PIPEDIR_OUT" are coming IN to the Target
+ * over the interconnect.
+ */
+#define PIPEDIR_NONE    0
+#define PIPEDIR_IN      1  /* Target-->Host, WiFi Rx direction */
+#define PIPEDIR_OUT     2  /* Host->Target, WiFi Tx direction */
+#define PIPEDIR_INOUT   3  /* bidirectional */
+
+/* Establish a mapping between a service/direction and a pipe. */
+struct service_to_pipe {
+	u32 service_id;
+	u32 pipedir;
+	u32 pipenum;
+};
+
+enum ath10k_pci_features {
+	ATH10K_PCI_FEATURE_MSI_X		= 0,
+	ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND	= 1,
+
+	/* keep last */
+	ATH10K_PCI_FEATURE_COUNT
+};
+
+/* Per-pipe state. */
+struct hif_ce_pipe_info {
+	/* Handle of underlying Copy Engine */
+	struct ce_state *ce_hdl;
+
+	/* Our pipe number; facilitiates use of pipe_info ptrs. */
+	u8 pipe_num;
+
+	/* Convenience back pointer to hif_ce_state. */
+	struct ath10k *hif_ce_state;
+
+	size_t buf_sz;
+
+	/* protects compl_free and num_send_allowed */
+	spinlock_t pipe_lock;
+
+	/* List of free CE completion slots */
+	struct list_head compl_free;
+
+	/* Limit the number of outstanding send requests. */
+	int num_sends_allowed;
+
+	struct ath10k_pci *ar_pci;
+	struct tasklet_struct intr;
+};
+
+struct ath10k_pci {
+	struct pci_dev *pdev;
+	struct device *dev;
+	struct ath10k *ar;
+	void __iomem *mem;
+	int cacheline_sz;
+
+	DECLARE_BITMAP(features, ATH10K_PCI_FEATURE_COUNT);
+
+	/*
+	 * Number of MSI interrupts granted, 0 --> using legacy PCI line
+	 * interrupts.
+	 */
+	int num_msi_intrs;
+
+	struct tasklet_struct intr_tq;
+	struct tasklet_struct msi_fw_err;
+
+	/* Number of Copy Engines supported */
+	unsigned int ce_count;
+
+	int started;
+
+	atomic_t keep_awake_count;
+	bool verified_awake;
+
+	/* List of CE completions to be processed */
+	struct list_head compl_process;
+
+	/* protects compl_processing and compl_process */
+	spinlock_t compl_lock;
+
+	bool compl_processing;
+
+	struct hif_ce_pipe_info pipe_info[CE_COUNT_MAX];
+
+	struct ath10k_hif_cb msg_callbacks_current;
+
+	/* Target address used to signal a pending firmware event */
+	u32 fw_indicator_address;
+
+	/* Copy Engine used for Diagnostic Accesses */
+	struct ce_state *ce_diag;
+
+	/* FIXME: document what this really protects */
+	spinlock_t ce_lock;
+
+	/* Map CE id to ce_state */
+	struct ce_state *ce_id_to_state[CE_COUNT_MAX];
+
+	/* makes sure that dummy reads are atomic */
+	spinlock_t hw_v1_workaround_lock;
+};
+
+static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)
+{
+	return ar->hif.priv;
+}
+
+static inline u32 ath10k_pci_reg_read32(void __iomem *mem, u32 addr)
+{
+	return ioread32(mem + PCIE_LOCAL_BASE_ADDRESS + addr);
+}
+
+static inline void ath10k_pci_reg_write32(void __iomem *mem, u32 addr, u32 val)
+{
+	iowrite32(val, mem + PCIE_LOCAL_BASE_ADDRESS + addr);
+}
+
+#define ATH_PCI_RESET_WAIT_MAX 10 /* ms */
+#define PCIE_WAKE_TIMEOUT 5000	/* 5ms */
+
+#define BAR_NUM 0
+
+#define CDC_WAR_MAGIC_STR   0xceef0000
+#define CDC_WAR_DATA_CE     4
+
+/*
+ * TODO: Should be a function call specific to each Target-type.
+ * This convoluted macro converts from Target CPU Virtual Address Space to CE
+ * Address Space. As part of this process, we conservatively fetch the current
+ * PCIE_BAR. MOST of the time, this should match the upper bits of PCI space
+ * for this device; but that's not guaranteed.
+ */
+#define TARG_CPU_SPACE_TO_CE_SPACE(ar, pci_addr, addr)			\
+	(((ioread32((pci_addr)+(SOC_CORE_BASE_ADDRESS|			\
+	  CORE_CTRL_ADDRESS)) & 0x7ff) << 21) |				\
+	 0x100000 | ((addr) & 0xfffff))
+
+/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
+#define DIAG_ACCESS_CE_TIMEOUT_MS 10
+
+/*
+ * This API allows the Host to access Target registers directly
+ * and relatively efficiently over PCIe.
+ * This allows the Host to avoid extra overhead associated with
+ * sending a message to firmware and waiting for a response message
+ * from firmware, as is done on other interconnects.
+ *
+ * Yet there is some complexity with direct accesses because the
+ * Target's power state is not known a priori. The Host must issue
+ * special PCIe reads/writes in order to explicitly wake the Target
+ * and to verify that it is awake and will remain awake.
+ *
+ * Usage:
+ *
+ *   Use ath10k_pci_read32 and ath10k_pci_write32 to access Target space.
+ *   These calls must be bracketed by ath10k_pci_wake and
+ *   ath10k_pci_sleep.  A single BEGIN/END pair is adequate for
+ *   multiple READ/WRITE operations.
+ *
+ *   Use ath10k_pci_wake to put the Target in a state in
+ *   which it is legal for the Host to directly access it. This
+ *   may involve waking the Target from a low power state, which
+ *   may take up to 2Ms!
+ *
+ *   Use ath10k_pci_sleep to tell the Target that as far as
+ *   this code path is concerned, it no longer needs to remain
+ *   directly accessible.  BEGIN/END is under a reference counter;
+ *   multiple code paths may issue BEGIN/END on a single targid.
+ */
+static inline void ath10k_pci_write32(struct ath10k *ar, u32 offset,
+				      u32 value)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+	void __iomem *addr = ar_pci->mem;
+
+	if (test_bit(ATH10K_PCI_FEATURE_HW_1_0_WARKAROUND, ar_pci->features)) {
+		unsigned long irq_flags;
+
+		spin_lock_irqsave(&ar_pci->hw_v1_workaround_lock, irq_flags);
+
+		ioread32(addr+offset+4); /* 3rd read prior to write */
+		ioread32(addr+offset+4); /* 2nd read prior to write */
+		ioread32(addr+offset+4); /* 1st read prior to write */
+		iowrite32(value, addr+offset);
+
+		spin_unlock_irqrestore(&ar_pci->hw_v1_workaround_lock,
+				       irq_flags);
+	} else {
+		iowrite32(value, addr+offset);
+	}
+}
+
+static inline u32 ath10k_pci_read32(struct ath10k *ar, u32 offset)
+{
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	return ioread32(ar_pci->mem + offset);
+}
+
+extern unsigned int ath10k_target_ps;
+
+void ath10k_do_pci_wake(struct ath10k *ar);
+void ath10k_do_pci_sleep(struct ath10k *ar);
+
+static inline void ath10k_pci_wake(struct ath10k *ar)
+{
+	if (ath10k_target_ps)
+		ath10k_do_pci_wake(ar);
+}
+
+static inline void ath10k_pci_sleep(struct ath10k *ar)
+{
+	if (ath10k_target_ps)
+		ath10k_do_pci_sleep(ar);
+}
+
+#endif /* _PCI_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/rx_desc.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/rx_desc.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/rx_desc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/rx_desc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,990 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _RX_DESC_H_
+#define _RX_DESC_H_
+
+enum rx_attention_flags {
+	RX_ATTENTION_FLAGS_FIRST_MPDU          = 1 << 0,
+	RX_ATTENTION_FLAGS_LAST_MPDU           = 1 << 1,
+	RX_ATTENTION_FLAGS_MCAST_BCAST         = 1 << 2,
+	RX_ATTENTION_FLAGS_PEER_IDX_INVALID    = 1 << 3,
+	RX_ATTENTION_FLAGS_PEER_IDX_TIMEOUT    = 1 << 4,
+	RX_ATTENTION_FLAGS_POWER_MGMT          = 1 << 5,
+	RX_ATTENTION_FLAGS_NON_QOS             = 1 << 6,
+	RX_ATTENTION_FLAGS_NULL_DATA           = 1 << 7,
+	RX_ATTENTION_FLAGS_MGMT_TYPE           = 1 << 8,
+	RX_ATTENTION_FLAGS_CTRL_TYPE           = 1 << 9,
+	RX_ATTENTION_FLAGS_MORE_DATA           = 1 << 10,
+	RX_ATTENTION_FLAGS_EOSP                = 1 << 11,
+	RX_ATTENTION_FLAGS_U_APSD_TRIGGER      = 1 << 12,
+	RX_ATTENTION_FLAGS_FRAGMENT            = 1 << 13,
+	RX_ATTENTION_FLAGS_ORDER               = 1 << 14,
+	RX_ATTENTION_FLAGS_CLASSIFICATION      = 1 << 15,
+	RX_ATTENTION_FLAGS_OVERFLOW_ERR        = 1 << 16,
+	RX_ATTENTION_FLAGS_MSDU_LENGTH_ERR     = 1 << 17,
+	RX_ATTENTION_FLAGS_TCP_UDP_CHKSUM_FAIL = 1 << 18,
+	RX_ATTENTION_FLAGS_IP_CHKSUM_FAIL      = 1 << 19,
+	RX_ATTENTION_FLAGS_SA_IDX_INVALID      = 1 << 20,
+	RX_ATTENTION_FLAGS_DA_IDX_INVALID      = 1 << 21,
+	RX_ATTENTION_FLAGS_SA_IDX_TIMEOUT      = 1 << 22,
+	RX_ATTENTION_FLAGS_DA_IDX_TIMEOUT      = 1 << 23,
+	RX_ATTENTION_FLAGS_ENCRYPT_REQUIRED    = 1 << 24,
+	RX_ATTENTION_FLAGS_DIRECTED            = 1 << 25,
+	RX_ATTENTION_FLAGS_BUFFER_FRAGMENT     = 1 << 26,
+	RX_ATTENTION_FLAGS_MPDU_LENGTH_ERR     = 1 << 27,
+	RX_ATTENTION_FLAGS_TKIP_MIC_ERR        = 1 << 28,
+	RX_ATTENTION_FLAGS_DECRYPT_ERR         = 1 << 29,
+	RX_ATTENTION_FLAGS_FCS_ERR             = 1 << 30,
+	RX_ATTENTION_FLAGS_MSDU_DONE           = 1 << 31,
+};
+
+struct rx_attention {
+	__le32 flags; /* %RX_ATTENTION_FLAGS_ */
+} __packed;
+
+/*
+ * first_mpdu
+ *		Indicates the first MSDU of the PPDU.  If both first_mpdu
+ *		and last_mpdu are set in the MSDU then this is a not an
+ *		A-MPDU frame but a stand alone MPDU.  Interior MPDU in an
+ *		A-MPDU shall have both first_mpdu and last_mpdu bits set to
+ *		0.  The PPDU start status will only be valid when this bit
+ *		is set.
+ *
+ * last_mpdu
+ *		Indicates the last MSDU of the last MPDU of the PPDU.  The
+ *		PPDU end status will only be valid when this bit is set.
+ *
+ * mcast_bcast
+ *		Multicast / broadcast indicator.  Only set when the MAC
+ *		address 1 bit 0 is set indicating mcast/bcast and the BSSID
+ *		matches one of the 4 BSSID registers. Only set when
+ *		first_msdu is set.
+ *
+ * peer_idx_invalid
+ *		Indicates no matching entries within the the max search
+ *		count.  Only set when first_msdu is set.
+ *
+ * peer_idx_timeout
+ *		Indicates an unsuccessful search for the peer index due to
+ *		timeout.  Only set when first_msdu is set.
+ *
+ * power_mgmt
+ *		Power management bit set in the 802.11 header.  Only set
+ *		when first_msdu is set.
+ *
+ * non_qos
+ *		Set if packet is not a non-QoS data frame.  Only set when
+ *		first_msdu is set.
+ *
+ * null_data
+ *		Set if frame type indicates either null data or QoS null
+ *		data format.  Only set when first_msdu is set.
+ *
+ * mgmt_type
+ *		Set if packet is a management packet.  Only set when
+ *		first_msdu is set.
+ *
+ * ctrl_type
+ *		Set if packet is a control packet.  Only set when first_msdu
+ *		is set.
+ *
+ * more_data
+ *		Set if more bit in frame control is set.  Only set when
+ *		first_msdu is set.
+ *
+ * eosp
+ *		Set if the EOSP (end of service period) bit in the QoS
+ *		control field is set.  Only set when first_msdu is set.
+ *
+ * u_apsd_trigger
+ *		Set if packet is U-APSD trigger.  Key table will have bits
+ *		per TID to indicate U-APSD trigger.
+ *
+ * fragment
+ *		Indicates that this is an 802.11 fragment frame.  This is
+ *		set when either the more_frag bit is set in the frame
+ *		control or the fragment number is not zero.  Only set when
+ *		first_msdu is set.
+ *
+ * order
+ *		Set if the order bit in the frame control is set.  Only set
+ *		when first_msdu is set.
+ *
+ * classification
+ *		Indicates that this status has a corresponding MSDU that
+ *		requires FW processing.  The OLE will have classification
+ *		ring mask registers which will indicate the ring(s) for
+ *		packets and descriptors which need FW attention.
+ *
+ * overflow_err
+ *		PCU Receive FIFO does not have enough space to store the
+ *		full receive packet.  Enough space is reserved in the
+ *		receive FIFO for the status is written.  This MPDU remaining
+ *		packets in the PPDU will be filtered and no Ack response
+ *		will be transmitted.
+ *
+ * msdu_length_err
+ *		Indicates that the MSDU length from the 802.3 encapsulated
+ *		length field extends beyond the MPDU boundary.
+ *
+ * tcp_udp_chksum_fail
+ *		Indicates that the computed checksum (tcp_udp_chksum) did
+ *		not match the checksum in the TCP/UDP header.
+ *
+ * ip_chksum_fail
+ *		Indicates that the computed checksum did not match the
+ *		checksum in the IP header.
+ *
+ * sa_idx_invalid
+ *		Indicates no matching entry was found in the address search
+ *		table for the source MAC address.
+ *
+ * da_idx_invalid
+ *		Indicates no matching entry was found in the address search
+ *		table for the destination MAC address.
+ *
+ * sa_idx_timeout
+ *		Indicates an unsuccessful search for the source MAC address
+ *		due to the expiring of the search timer.
+ *
+ * da_idx_timeout
+ *		Indicates an unsuccessful search for the destination MAC
+ *		address due to the expiring of the search timer.
+ *
+ * encrypt_required
+ *		Indicates that this data type frame is not encrypted even if
+ *		the policy for this MPDU requires encryption as indicated in
+ *		the peer table key type.
+ *
+ * directed
+ *		MPDU is a directed packet which means that the RA matched
+ *		our STA addresses.  In proxySTA it means that the TA matched
+ *		an entry in our address search table with the corresponding
+ *		'no_ack' bit is the address search entry cleared.
+ *
+ * buffer_fragment
+ *		Indicates that at least one of the rx buffers has been
+ *		fragmented.  If set the FW should look at the rx_frag_info
+ *		descriptor described below.
+ *
+ * mpdu_length_err
+ *		Indicates that the MPDU was pre-maturely terminated
+ *		resulting in a truncated MPDU.  Don't trust the MPDU length
+ *		field.
+ *
+ * tkip_mic_err
+ *		Indicates that the MPDU Michael integrity check failed
+ *
+ * decrypt_err
+ *		Indicates that the MPDU decrypt integrity check failed
+ *
+ * fcs_err
+ *		Indicates that the MPDU FCS check failed
+ *
+ * msdu_done
+ *		If set indicates that the RX packet data, RX header data, RX
+ *		PPDU start descriptor, RX MPDU start/end descriptor, RX MSDU
+ *		start/end descriptors and RX Attention descriptor are all
+ *		valid.  This bit must be in the last octet of the
+ *		descriptor.
+ */
+
+struct rx_frag_info {
+	u8 ring0_more_count;
+	u8 ring1_more_count;
+	u8 ring2_more_count;
+	u8 ring3_more_count;
+} __packed;
+
+/*
+ * ring0_more_count
+ *		Indicates the number of more buffers associated with RX DMA
+ *		ring 0.  Field is filled in by the RX_DMA.
+ *
+ * ring1_more_count
+ *		Indicates the number of more buffers associated with RX DMA
+ *		ring 1. Field is filled in by the RX_DMA.
+ *
+ * ring2_more_count
+ *		Indicates the number of more buffers associated with RX DMA
+ *		ring 2. Field is filled in by the RX_DMA.
+ *
+ * ring3_more_count
+ *		Indicates the number of more buffers associated with RX DMA
+ *		ring 3. Field is filled in by the RX_DMA.
+ */
+
+enum htt_rx_mpdu_encrypt_type {
+	HTT_RX_MPDU_ENCRYPT_WEP40            = 0,
+	HTT_RX_MPDU_ENCRYPT_WEP104           = 1,
+	HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC = 2,
+	HTT_RX_MPDU_ENCRYPT_WEP128           = 3,
+	HTT_RX_MPDU_ENCRYPT_TKIP_WPA         = 4,
+	HTT_RX_MPDU_ENCRYPT_WAPI             = 5,
+	HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2     = 6,
+	HTT_RX_MPDU_ENCRYPT_NONE             = 7,
+};
+
+#define RX_MPDU_START_INFO0_PEER_IDX_MASK     0x000007ff
+#define RX_MPDU_START_INFO0_PEER_IDX_LSB      0
+#define RX_MPDU_START_INFO0_SEQ_NUM_MASK      0x0fff0000
+#define RX_MPDU_START_INFO0_SEQ_NUM_LSB       16
+#define RX_MPDU_START_INFO0_ENCRYPT_TYPE_MASK 0xf0000000
+#define RX_MPDU_START_INFO0_ENCRYPT_TYPE_LSB  28
+#define RX_MPDU_START_INFO0_FROM_DS           (1 << 11)
+#define RX_MPDU_START_INFO0_TO_DS             (1 << 12)
+#define RX_MPDU_START_INFO0_ENCRYPTED         (1 << 13)
+#define RX_MPDU_START_INFO0_RETRY             (1 << 14)
+#define RX_MPDU_START_INFO0_TXBF_H_INFO       (1 << 15)
+
+#define RX_MPDU_START_INFO1_TID_MASK 0xf0000000
+#define RX_MPDU_START_INFO1_TID_LSB  28
+#define RX_MPDU_START_INFO1_DIRECTED (1 << 16)
+
+struct rx_mpdu_start {
+	__le32 info0;
+	union {
+		struct {
+			__le32 pn31_0;
+			__le32 info1; /* %RX_MPDU_START_INFO1_ */
+		} __packed;
+		struct {
+			u8 pn[6];
+		} __packed;
+	} __packed;
+} __packed;
+
+/*
+ * peer_idx
+ *		The index of the address search table which associated with
+ *		the peer table entry corresponding to this MPDU.  Only valid
+ *		when first_msdu is set.
+ *
+ * fr_ds
+ *		Set if the from DS bit is set in the frame control.  Only
+ *		valid when first_msdu is set.
+ *
+ * to_ds
+ *		Set if the to DS bit is set in the frame control.  Only
+ *		valid when first_msdu is set.
+ *
+ * encrypted
+ *		Protected bit from the frame control.  Only valid when
+ *		first_msdu is set.
+ *
+ * retry
+ *		Retry bit from the frame control.  Only valid when
+ *		first_msdu is set.
+ *
+ * txbf_h_info
+ *		The MPDU data will contain H information.  Primarily used
+ *		for debug.
+ *
+ * seq_num
+ *		The sequence number from the 802.11 header.  Only valid when
+ *		first_msdu is set.
+ *
+ * encrypt_type
+ *		Indicates type of decrypt cipher used (as defined in the
+ *		peer table)
+ *		0: WEP40
+ *		1: WEP104
+ *		2: TKIP without MIC
+ *		3: WEP128
+ *		4: TKIP (WPA)
+ *		5: WAPI
+ *		6: AES-CCM (WPA2)
+ *		7: No cipher
+ *		Only valid when first_msdu_is set
+ *
+ * pn_31_0
+ *		Bits [31:0] of the PN number extracted from the IV field
+ *		WEP: IV = {key_id_octet, pn2, pn1, pn0}.  Only pn[23:0] is
+ *		valid.
+ *		TKIP: IV = {pn5, pn4, pn3, pn2, key_id_octet, pn0,
+ *		WEPSeed[1], pn1}.  Only pn[47:0] is valid.
+ *		AES-CCM: IV = {pn5, pn4, pn3, pn2, key_id_octet, 0x0, pn1,
+ *		pn0}.  Only pn[47:0] is valid.
+ *		WAPI: IV = {key_id_octet, 0x0, pn15, pn14, pn13, pn12, pn11,
+ *		pn10, pn9, pn8, pn7, pn6, pn5, pn4, pn3, pn2, pn1, pn0}.
+ *		The ext_wapi_pn[127:48] in the rx_msdu_misc descriptor and
+ *		pn[47:0] are valid.
+ *		Only valid when first_msdu is set.
+ *
+ * pn_47_32
+ *		Bits [47:32] of the PN number.   See description for
+ *		pn_31_0.  The remaining PN fields are in the rx_msdu_end
+ *		descriptor
+ *
+ * pn
+ *		Use this field to access the pn without worrying about
+ *		byte-order and bitmasking/bitshifting.
+ *
+ * directed
+ *		See definition in RX attention descriptor
+ *
+ * reserved_2
+ *		Reserved: HW should fill with zero.  FW should ignore.
+ *
+ * tid
+ *		The TID field in the QoS control field
+ */
+
+#define RX_MPDU_END_INFO0_RESERVED_0_MASK     0x00001fff
+#define RX_MPDU_END_INFO0_RESERVED_0_LSB      0
+#define RX_MPDU_END_INFO0_POST_DELIM_CNT_MASK 0x0fff0000
+#define RX_MPDU_END_INFO0_POST_DELIM_CNT_LSB  16
+#define RX_MPDU_END_INFO0_OVERFLOW_ERR        (1 << 13)
+#define RX_MPDU_END_INFO0_LAST_MPDU           (1 << 14)
+#define RX_MPDU_END_INFO0_POST_DELIM_ERR      (1 << 15)
+#define RX_MPDU_END_INFO0_MPDU_LENGTH_ERR     (1 << 28)
+#define RX_MPDU_END_INFO0_TKIP_MIC_ERR        (1 << 29)
+#define RX_MPDU_END_INFO0_DECRYPT_ERR         (1 << 30)
+#define RX_MPDU_END_INFO0_FCS_ERR             (1 << 31)
+
+struct rx_mpdu_end {
+	__le32 info0;
+} __packed;
+
+/*
+ * reserved_0
+ *		Reserved
+ *
+ * overflow_err
+ *		PCU Receive FIFO does not have enough space to store the
+ *		full receive packet.  Enough space is reserved in the
+ *		receive FIFO for the status is written.  This MPDU remaining
+ *		packets in the PPDU will be filtered and no Ack response
+ *		will be transmitted.
+ *
+ * last_mpdu
+ *		Indicates that this is the last MPDU of a PPDU.
+ *
+ * post_delim_err
+ *		Indicates that a delimiter FCS error occurred after this
+ *		MPDU before the next MPDU.  Only valid when last_msdu is
+ *		set.
+ *
+ * post_delim_cnt
+ *		Count of the delimiters after this MPDU.  This requires the
+ *		last MPDU to be held until all the EOF descriptors have been
+ *		received.  This may be inefficient in the future when
+ *		ML-MIMO is used.  Only valid when last_mpdu is set.
+ *
+ * mpdu_length_err
+ *		See definition in RX attention descriptor
+ *
+ * tkip_mic_err
+ *		See definition in RX attention descriptor
+ *
+ * decrypt_err
+ *		See definition in RX attention descriptor
+ *
+ * fcs_err
+ *		See definition in RX attention descriptor
+ */
+
+#define RX_MSDU_START_INFO0_MSDU_LENGTH_MASK    0x00003fff
+#define RX_MSDU_START_INFO0_MSDU_LENGTH_LSB     0
+#define RX_MSDU_START_INFO0_IP_OFFSET_MASK      0x000fc000
+#define RX_MSDU_START_INFO0_IP_OFFSET_LSB       14
+#define RX_MSDU_START_INFO0_RING_MASK_MASK      0x00f00000
+#define RX_MSDU_START_INFO0_RING_MASK_LSB       20
+#define RX_MSDU_START_INFO0_TCP_UDP_OFFSET_MASK 0x7f000000
+#define RX_MSDU_START_INFO0_TCP_UDP_OFFSET_LSB  24
+
+#define RX_MSDU_START_INFO1_MSDU_NUMBER_MASK    0x000000ff
+#define RX_MSDU_START_INFO1_MSDU_NUMBER_LSB     0
+#define RX_MSDU_START_INFO1_DECAP_FORMAT_MASK   0x00000300
+#define RX_MSDU_START_INFO1_DECAP_FORMAT_LSB    8
+#define RX_MSDU_START_INFO1_SA_IDX_MASK         0x07ff0000
+#define RX_MSDU_START_INFO1_SA_IDX_LSB          16
+#define RX_MSDU_START_INFO1_IPV4_PROTO          (1 << 10)
+#define RX_MSDU_START_INFO1_IPV6_PROTO          (1 << 11)
+#define RX_MSDU_START_INFO1_TCP_PROTO           (1 << 12)
+#define RX_MSDU_START_INFO1_UDP_PROTO           (1 << 13)
+#define RX_MSDU_START_INFO1_IP_FRAG             (1 << 14)
+#define RX_MSDU_START_INFO1_TCP_ONLY_ACK        (1 << 15)
+
+enum rx_msdu_decap_format {
+	RX_MSDU_DECAP_RAW           = 0,
+	RX_MSDU_DECAP_NATIVE_WIFI   = 1,
+	RX_MSDU_DECAP_ETHERNET2_DIX = 2,
+	RX_MSDU_DECAP_8023_SNAP_LLC = 3
+};
+
+struct rx_msdu_start {
+	__le32 info0; /* %RX_MSDU_START_INFO0_ */
+	__le32 flow_id_crc;
+	__le32 info1; /* %RX_MSDU_START_INFO1_ */
+} __packed;
+
+/*
+ * msdu_length
+ *		MSDU length in bytes after decapsulation.  This field is
+ *		still valid for MPDU frames without A-MSDU.  It still
+ *		represents MSDU length after decapsulation
+ *
+ * ip_offset
+ *		Indicates the IP offset in bytes from the start of the
+ *		packet after decapsulation.  Only valid if ipv4_proto or
+ *		ipv6_proto is set.
+ *
+ * ring_mask
+ *		Indicates the destination RX rings for this MSDU.
+ *
+ * tcp_udp_offset
+ *		Indicates the offset in bytes to the start of TCP or UDP
+ *		header from the start of the IP header after decapsulation.
+ *		Only valid if tcp_prot or udp_prot is set.  The value 0
+ *		indicates that the offset is longer than 127 bytes.
+ *
+ * reserved_0c
+ *		Reserved: HW should fill with zero.  FW should ignore.
+ *
+ * flow_id_crc
+ *		The flow_id_crc runs CRC32 on the following information:
+ *		IPv4 option: dest_addr[31:0], src_addr [31:0], {24'b0,
+ *		protocol[7:0]}.
+ *		IPv6 option: dest_addr[127:0], src_addr [127:0], {24'b0,
+ *		next_header[7:0]}
+ *		UDP case: sort_port[15:0], dest_port[15:0]
+ *		TCP case: sort_port[15:0], dest_port[15:0],
+ *		{header_length[3:0], 6'b0, flags[5:0], window_size[15:0]},
+ *		{16'b0, urgent_ptr[15:0]}, all options except 32-bit
+ *		timestamp.
+ *
+ * msdu_number
+ *		Indicates the MSDU number within a MPDU.  This value is
+ *		reset to zero at the start of each MPDU.  If the number of
+ *		MSDU exceeds 255 this number will wrap using modulo 256.
+ *
+ * decap_format
+ *		Indicates the format after decapsulation:
+ *		0: RAW: No decapsulation
+ *		1: Native WiFi
+ *		2: Ethernet 2 (DIX)
+ *		3: 802.3 (SNAP/LLC)
+ *
+ * ipv4_proto
+ *		Set if L2 layer indicates IPv4 protocol.
+ *
+ * ipv6_proto
+ *		Set if L2 layer indicates IPv6 protocol.
+ *
+ * tcp_proto
+ *		Set if the ipv4_proto or ipv6_proto are set and the IP
+ *		protocol indicates TCP.
+ *
+ * udp_proto
+ *		Set if the ipv4_proto or ipv6_proto are set and the IP
+ *			protocol indicates UDP.
+ *
+ * ip_frag
+ *		Indicates that either the IP More frag bit is set or IP frag
+ *		number is non-zero.  If set indicates that this is a
+ *		fragmented IP packet.
+ *
+ * tcp_only_ack
+ *		Set if only the TCP Ack bit is set in the TCP flags and if
+ *		the TCP payload is 0.
+ *
+ * sa_idx
+ *		The offset in the address table which matches the MAC source
+ *		address.
+ *
+ * reserved_2b
+ *		Reserved: HW should fill with zero.  FW should ignore.
+ */
+
+#define RX_MSDU_END_INFO0_REPORTED_MPDU_LENGTH_MASK 0x00003fff
+#define RX_MSDU_END_INFO0_REPORTED_MPDU_LENGTH_LSB  0
+#define RX_MSDU_END_INFO0_FIRST_MSDU                (1 << 14)
+#define RX_MSDU_END_INFO0_LAST_MSDU                 (1 << 15)
+#define RX_MSDU_END_INFO0_PRE_DELIM_ERR             (1 << 30)
+#define RX_MSDU_END_INFO0_RESERVED_3B               (1 << 31)
+
+struct rx_msdu_end {
+	__le16 ip_hdr_cksum;
+	__le16 tcp_hdr_cksum;
+	u8 key_id_octet;
+	u8 classification_filter;
+	u8 wapi_pn[10];
+	__le32 info0;
+} __packed;
+
+/*
+ *ip_hdr_chksum
+ *		This can include the IP header checksum or the pseudo header
+ *		checksum used by TCP/UDP checksum.
+ *
+ *tcp_udp_chksum
+ *		The value of the computed TCP/UDP checksum.  A mode bit
+ *		selects whether this checksum is the full checksum or the
+ *		partial checksum which does not include the pseudo header.
+ *
+ *key_id_octet
+ *		The key ID octet from the IV.  Only valid when first_msdu is
+ *		set.
+ *
+ *classification_filter
+ *		Indicates the number classification filter rule
+ *
+ *ext_wapi_pn_63_48
+ *		Extension PN (packet number) which is only used by WAPI.
+ *		This corresponds to WAPI PN bits [63:48] (pn6 and pn7).  The
+ *		WAPI PN bits [63:0] are in the pn field of the rx_mpdu_start
+ *		descriptor.
+ *
+ *ext_wapi_pn_95_64
+ *		Extension PN (packet number) which is only used by WAPI.
+ *		This corresponds to WAPI PN bits [95:64] (pn8, pn9, pn10 and
+ *		pn11).
+ *
+ *ext_wapi_pn_127_96
+ *		Extension PN (packet number) which is only used by WAPI.
+ *		This corresponds to WAPI PN bits [127:96] (pn12, pn13, pn14,
+ *		pn15).
+ *
+ *reported_mpdu_length
+ *		MPDU length before decapsulation.  Only valid when
+ *		first_msdu is set.  This field is taken directly from the
+ *		length field of the A-MPDU delimiter or the preamble length
+ *		field for non-A-MPDU frames.
+ *
+ *first_msdu
+ *		Indicates the first MSDU of A-MSDU.  If both first_msdu and
+ *		last_msdu are set in the MSDU then this is a non-aggregated
+ *		MSDU frame: normal MPDU.  Interior MSDU in an A-MSDU shall
+ *		have both first_mpdu and last_mpdu bits set to 0.
+ *
+ *last_msdu
+ *		Indicates the last MSDU of the A-MSDU.  MPDU end status is
+ *		only valid when last_msdu is set.
+ *
+ *reserved_3a
+ *		Reserved: HW should fill with zero.  FW should ignore.
+ *
+ *pre_delim_err
+ *		Indicates that the first delimiter had a FCS failure.  Only
+ *		valid when first_mpdu and first_msdu are set.
+ *
+ *reserved_3b
+ *		Reserved: HW should fill with zero.  FW should ignore.
+ */
+
+#define RX_PPDU_START_SIG_RATE_SELECT_OFDM 0
+#define RX_PPDU_START_SIG_RATE_SELECT_CCK  1
+
+#define RX_PPDU_START_SIG_RATE_OFDM_48 0
+#define RX_PPDU_START_SIG_RATE_OFDM_24 1
+#define RX_PPDU_START_SIG_RATE_OFDM_12 2
+#define RX_PPDU_START_SIG_RATE_OFDM_6  3
+#define RX_PPDU_START_SIG_RATE_OFDM_54 4
+#define RX_PPDU_START_SIG_RATE_OFDM_36 5
+#define RX_PPDU_START_SIG_RATE_OFDM_18 6
+#define RX_PPDU_START_SIG_RATE_OFDM_9  7
+
+#define RX_PPDU_START_SIG_RATE_CCK_LP_11  0
+#define RX_PPDU_START_SIG_RATE_CCK_LP_5_5 1
+#define RX_PPDU_START_SIG_RATE_CCK_LP_2   2
+#define RX_PPDU_START_SIG_RATE_CCK_LP_1   3
+#define RX_PPDU_START_SIG_RATE_CCK_SP_11  4
+#define RX_PPDU_START_SIG_RATE_CCK_SP_5_5 5
+#define RX_PPDU_START_SIG_RATE_CCK_SP_2   6
+
+#define HTT_RX_PPDU_START_PREAMBLE_LEGACY        0x04
+#define HTT_RX_PPDU_START_PREAMBLE_HT            0x08
+#define HTT_RX_PPDU_START_PREAMBLE_HT_WITH_TXBF  0x09
+#define HTT_RX_PPDU_START_PREAMBLE_VHT           0x0C
+#define HTT_RX_PPDU_START_PREAMBLE_VHT_WITH_TXBF 0x0D
+
+#define RX_PPDU_START_INFO0_IS_GREENFIELD (1 << 0)
+
+#define RX_PPDU_START_INFO1_L_SIG_RATE_MASK    0x0000000f
+#define RX_PPDU_START_INFO1_L_SIG_RATE_LSB     0
+#define RX_PPDU_START_INFO1_L_SIG_LENGTH_MASK  0x0001ffe0
+#define RX_PPDU_START_INFO1_L_SIG_LENGTH_LSB   5
+#define RX_PPDU_START_INFO1_L_SIG_TAIL_MASK    0x00fc0000
+#define RX_PPDU_START_INFO1_L_SIG_TAIL_LSB     18
+#define RX_PPDU_START_INFO1_PREAMBLE_TYPE_MASK 0xff000000
+#define RX_PPDU_START_INFO1_PREAMBLE_TYPE_LSB  24
+#define RX_PPDU_START_INFO1_L_SIG_RATE_SELECT  (1 << 4)
+#define RX_PPDU_START_INFO1_L_SIG_PARITY       (1 << 17)
+
+#define RX_PPDU_START_INFO2_HT_SIG_VHT_SIG_A_1_MASK 0x00ffffff
+#define RX_PPDU_START_INFO2_HT_SIG_VHT_SIG_A_1_LSB  0
+
+#define RX_PPDU_START_INFO3_HT_SIG_VHT_SIG_A_2_MASK 0x00ffffff
+#define RX_PPDU_START_INFO3_HT_SIG_VHT_SIG_A_2_LSB  0
+#define RX_PPDU_START_INFO3_TXBF_H_INFO             (1 << 24)
+
+#define RX_PPDU_START_INFO4_VHT_SIG_B_MASK 0x1fffffff
+#define RX_PPDU_START_INFO4_VHT_SIG_B_LSB  0
+
+#define RX_PPDU_START_INFO5_SERVICE_MASK 0x0000ffff
+#define RX_PPDU_START_INFO5_SERVICE_LSB  0
+
+struct rx_ppdu_start {
+	struct {
+		u8 pri20_mhz;
+		u8 ext20_mhz;
+		u8 ext40_mhz;
+		u8 ext80_mhz;
+	} rssi_chains[4];
+	u8 rssi_comb;
+	__le16 rsvd0;
+	u8 info0; /* %RX_PPDU_START_INFO0_ */
+	__le32 info1; /* %RX_PPDU_START_INFO1_ */
+	__le32 info2; /* %RX_PPDU_START_INFO2_ */
+	__le32 info3; /* %RX_PPDU_START_INFO3_ */
+	__le32 info4; /* %RX_PPDU_START_INFO4_ */
+	__le32 info5; /* %RX_PPDU_START_INFO5_ */
+} __packed;
+
+/*
+ * rssi_chain0_pri20
+ *		RSSI of RX PPDU on chain 0 of primary 20 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain0_sec20
+ *		RSSI of RX PPDU on chain 0 of secondary 20 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain0_sec40
+ *		RSSI of RX PPDU on chain 0 of secondary 40 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain0_sec80
+ *		RSSI of RX PPDU on chain 0 of secondary 80 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain1_pri20
+ *		RSSI of RX PPDU on chain 1 of primary 20 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain1_sec20
+ *		RSSI of RX PPDU on chain 1 of secondary 20 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain1_sec40
+ *		RSSI of RX PPDU on chain 1 of secondary 40 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain1_sec80
+ *		RSSI of RX PPDU on chain 1 of secondary 80 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain2_pri20
+ *		RSSI of RX PPDU on chain 2 of primary 20 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain2_sec20
+ *		RSSI of RX PPDU on chain 2 of secondary 20 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain2_sec40
+ *		RSSI of RX PPDU on chain 2 of secondary 40 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain2_sec80
+ *		RSSI of RX PPDU on chain 2 of secondary 80 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain3_pri20
+ *		RSSI of RX PPDU on chain 3 of primary 20 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain3_sec20
+ *		RSSI of RX PPDU on chain 3 of secondary 20 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain3_sec40
+ *		RSSI of RX PPDU on chain 3 of secondary 40 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_chain3_sec80
+ *		RSSI of RX PPDU on chain 3 of secondary 80 MHz bandwidth.
+ *		Value of 0x80 indicates invalid.
+ *
+ * rssi_comb
+ *		The combined RSSI of RX PPDU of all active chains and
+ *		bandwidths.  Value of 0x80 indicates invalid.
+ *
+ * reserved_4a
+ *		Reserved: HW should fill with 0, FW should ignore.
+ *
+ * is_greenfield
+ *		Do we really support this?
+ *
+ * reserved_4b
+ *		Reserved: HW should fill with 0, FW should ignore.
+ *
+ * l_sig_rate
+ *		If l_sig_rate_select is 0:
+ *		0x8: OFDM 48 Mbps
+ *		0x9: OFDM 24 Mbps
+ *		0xA: OFDM 12 Mbps
+ *		0xB: OFDM 6 Mbps
+ *		0xC: OFDM 54 Mbps
+ *		0xD: OFDM 36 Mbps
+ *		0xE: OFDM 18 Mbps
+ *		0xF: OFDM 9 Mbps
+ *		If l_sig_rate_select is 1:
+ *		0x8: CCK 11 Mbps long preamble
+ *		0x9: CCK 5.5 Mbps long preamble
+ *		0xA: CCK 2 Mbps long preamble
+ *		0xB: CCK 1 Mbps long preamble
+ *		0xC: CCK 11 Mbps short preamble
+ *		0xD: CCK 5.5 Mbps short preamble
+ *		0xE: CCK 2 Mbps short preamble
+ *
+ * l_sig_rate_select
+ *		Legacy signal rate select.  If set then l_sig_rate indicates
+ *		CCK rates.  If clear then l_sig_rate indicates OFDM rates.
+ *
+ * l_sig_length
+ *		Length of legacy frame in octets.
+ *
+ * l_sig_parity
+ *		Odd parity over l_sig_rate and l_sig_length
+ *
+ * l_sig_tail
+ *		Tail bits for Viterbi decoder
+ *
+ * preamble_type
+ *		Indicates the type of preamble ahead:
+ *		0x4: Legacy (OFDM/CCK)
+ *		0x8: HT
+ *		0x9: HT with TxBF
+ *		0xC: VHT
+ *		0xD: VHT with TxBF
+ *		0x80 - 0xFF: Reserved for special baseband data types such
+ *		as radar and spectral scan.
+ *
+ * ht_sig_vht_sig_a_1
+ *		If preamble_type == 0x8 or 0x9
+ *		HT-SIG (first 24 bits)
+ *		If preamble_type == 0xC or 0xD
+ *		VHT-SIG A (first 24 bits)
+ *		Else
+ *		Reserved
+ *
+ * reserved_6
+ *		Reserved: HW should fill with 0, FW should ignore.
+ *
+ * ht_sig_vht_sig_a_2
+ *		If preamble_type == 0x8 or 0x9
+ *		HT-SIG (last 24 bits)
+ *		If preamble_type == 0xC or 0xD
+ *		VHT-SIG A (last 24 bits)
+ *		Else
+ *		Reserved
+ *
+ * txbf_h_info
+ *		Indicates that the packet data carries H information which
+ *		is used for TxBF debug.
+ *
+ * reserved_7
+ *		Reserved: HW should fill with 0, FW should ignore.
+ *
+ * vht_sig_b
+ *		WiFi 1.0 and WiFi 2.0 will likely have this field to be all
+ *		0s since the BB does not plan on decoding VHT SIG-B.
+ *
+ * reserved_8
+ *		Reserved: HW should fill with 0, FW should ignore.
+ *
+ * service
+ *		Service field from BB for OFDM, HT and VHT packets.  CCK
+ *		packets will have service field of 0.
+ *
+ * reserved_9
+ *		Reserved: HW should fill with 0, FW should ignore.
+*/
+
+
+#define RX_PPDU_END_FLAGS_PHY_ERR             (1 << 0)
+#define RX_PPDU_END_FLAGS_RX_LOCATION         (1 << 1)
+#define RX_PPDU_END_FLAGS_TXBF_H_INFO         (1 << 2)
+
+#define RX_PPDU_END_INFO0_RX_ANTENNA_MASK     0x00ffffff
+#define RX_PPDU_END_INFO0_RX_ANTENNA_LSB      0
+#define RX_PPDU_END_INFO0_FLAGS_TX_HT_VHT_ACK (1 << 24)
+#define RX_PPDU_END_INFO0_BB_CAPTURED_CHANNEL (1 << 25)
+
+#define RX_PPDU_END_INFO1_PPDU_DONE (1 << 15)
+
+struct rx_ppdu_end {
+	__le32 evm_p0;
+	__le32 evm_p1;
+	__le32 evm_p2;
+	__le32 evm_p3;
+	__le32 evm_p4;
+	__le32 evm_p5;
+	__le32 evm_p6;
+	__le32 evm_p7;
+	__le32 evm_p8;
+	__le32 evm_p9;
+	__le32 evm_p10;
+	__le32 evm_p11;
+	__le32 evm_p12;
+	__le32 evm_p13;
+	__le32 evm_p14;
+	__le32 evm_p15;
+	__le32 tsf_timestamp;
+	__le32 wb_timestamp;
+	u8 locationing_timestamp;
+	u8 phy_err_code;
+	__le16 flags; /* %RX_PPDU_END_FLAGS_ */
+	__le32 info0; /* %RX_PPDU_END_INFO0_ */
+	__le16 bb_length;
+	__le16 info1; /* %RX_PPDU_END_INFO1_ */
+} __packed;
+
+/*
+ * evm_p0
+ *		EVM for pilot 0.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p1
+ *		EVM for pilot 1.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p2
+ *		EVM for pilot 2.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p3
+ *		EVM for pilot 3.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p4
+ *		EVM for pilot 4.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p5
+ *		EVM for pilot 5.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p6
+ *		EVM for pilot 6.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p7
+ *		EVM for pilot 7.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p8
+ *		EVM for pilot 8.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p9
+ *		EVM for pilot 9.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p10
+ *		EVM for pilot 10.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p11
+ *		EVM for pilot 11.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p12
+ *		EVM for pilot 12.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p13
+ *		EVM for pilot 13.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p14
+ *		EVM for pilot 14.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * evm_p15
+ *		EVM for pilot 15.  Contain EVM for streams: 0, 1, 2 and 3.
+ *
+ * tsf_timestamp
+ *		Receive TSF timestamp sampled on the rising edge of
+ *		rx_clear.  For PHY errors this may be the current TSF when
+ *		phy_error is asserted if the rx_clear does not assert before
+ *		the end of the PHY error.
+ *
+ * wb_timestamp
+ *		WLAN/BT timestamp is a 1 usec resolution timestamp which
+ *		does not get updated based on receive beacon like TSF.  The
+ *		same rules for capturing tsf_timestamp are used to capture
+ *		the wb_timestamp.
+ *
+ * locationing_timestamp
+ *		Timestamp used for locationing.  This timestamp is used to
+ *		indicate fractions of usec.  For example if the MAC clock is
+ *		running at 80 MHz, the timestamp will increment every 12.5
+ *		nsec.  The value starts at 0 and increments to 79 and
+ *		returns to 0 and repeats.  This information is valid for
+ *		every PPDU.  This information can be used in conjunction
+ *		with wb_timestamp to capture large delta times.
+ *
+ * phy_err_code
+ *		See the 1.10.8.1.2 for the list of the PHY error codes.
+ *
+ * phy_err
+ *		Indicates a PHY error was detected for this PPDU.
+ *
+ * rx_location
+ *		Indicates that location information was requested.
+ *
+ * txbf_h_info
+ *		Indicates that the packet data carries H information which
+ *		is used for TxBF debug.
+ *
+ * reserved_18
+ *		Reserved: HW should fill with 0, FW should ignore.
+ *
+ * rx_antenna
+ *		Receive antenna value
+ *
+ * tx_ht_vht_ack
+ *		Indicates that a HT or VHT Ack/BA frame was transmitted in
+ *		response to this receive packet.
+ *
+ * bb_captured_channel
+ *		Indicates that the BB has captured a channel dump.  FW can
+ *		then read the channel dump memory.  This may indicate that
+ *		the channel was captured either based on PCU setting the
+ *		capture_channel bit  BB descriptor or FW setting the
+ *		capture_channel mode bit.
+ *
+ * reserved_19
+ *		Reserved: HW should fill with 0, FW should ignore.
+ *
+ * bb_length
+ *		Indicates the number of bytes of baseband information for
+ *		PPDUs where the BB descriptor preamble type is 0x80 to 0xFF
+ *		which indicates that this is not a normal PPDU but rather
+ *		contains baseband debug information.
+ *
+ * reserved_20
+ *		Reserved: HW should fill with 0, FW should ignore.
+ *
+ * ppdu_done
+ *		PPDU end status is only valid when ppdu_done bit is set.
+ *		Every time HW sets this bit in memory FW/SW must clear this
+ *		bit in memory.  FW will initialize all the ppdu_done dword
+ *		to 0.
+*/
+
+#define FW_RX_DESC_INFO0_DISCARD  (1 << 0)
+#define FW_RX_DESC_INFO0_FORWARD  (1 << 1)
+#define FW_RX_DESC_INFO0_INSPECT  (1 << 5)
+#define FW_RX_DESC_INFO0_EXT_MASK 0xC0
+#define FW_RX_DESC_INFO0_EXT_LSB  6
+
+struct fw_rx_desc_base {
+	u8 info0;
+} __packed;
+
+#endif /* _RX_DESC_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/targaddrs.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/targaddrs.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/targaddrs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/targaddrs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __TARGADDRS_H__
+#define __TARGADDRS_H__
+
+/*
+ * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
+ * host_interest structure.  It must match the address of the _host_interest
+ * symbol (see linker script).
+ *
+ * Host Interest is shared between Host and Target in order to coordinate
+ * between the two, and is intended to remain constant (with additions only
+ * at the end) across software releases.
+ *
+ * All addresses are available here so that it's possible to
+ * write a single binary that works with all Target Types.
+ * May be used in assembler code as well as C.
+ */
+#define QCA988X_HOST_INTEREST_ADDRESS    0x00400800
+#define HOST_INTEREST_MAX_SIZE          0x200
+
+/*
+ * These are items that the Host may need to access via BMI or via the
+ * Diagnostic Window. The position of items in this structure must remain
+ * constant across firmware revisions! Types for each item must be fixed
+ * size across target and host platforms. More items may be added at the end.
+ */
+struct host_interest {
+	/*
+	 * Pointer to application-defined area, if any.
+	 * Set by Target application during startup.
+	 */
+	u32 hi_app_host_interest;			/* 0x00 */
+
+	/* Pointer to register dump area, valid after Target crash. */
+	u32 hi_failure_state;				/* 0x04 */
+
+	/* Pointer to debug logging header */
+	u32 hi_dbglog_hdr;				/* 0x08 */
+
+	u32 hi_unused0c;				/* 0x0c */
+
+	/*
+	 * General-purpose flag bits, similar to SOC_OPTION_* flags.
+	 * Can be used by application rather than by OS.
+	 */
+	u32 hi_option_flag;				/* 0x10 */
+
+	/*
+	 * Boolean that determines whether or not to
+	 * display messages on the serial port.
+	 */
+	u32 hi_serial_enable;				/* 0x14 */
+
+	/* Start address of DataSet index, if any */
+	u32 hi_dset_list_head;				/* 0x18 */
+
+	/* Override Target application start address */
+	u32 hi_app_start;				/* 0x1c */
+
+	/* Clock and voltage tuning */
+	u32 hi_skip_clock_init;				/* 0x20 */
+	u32 hi_core_clock_setting;			/* 0x24 */
+	u32 hi_cpu_clock_setting;			/* 0x28 */
+	u32 hi_system_sleep_setting;			/* 0x2c */
+	u32 hi_xtal_control_setting;			/* 0x30 */
+	u32 hi_pll_ctrl_setting_24ghz;			/* 0x34 */
+	u32 hi_pll_ctrl_setting_5ghz;			/* 0x38 */
+	u32 hi_ref_voltage_trim_setting;		/* 0x3c */
+	u32 hi_clock_info;				/* 0x40 */
+
+	/* Host uses BE CPU or not */
+	u32 hi_be;					/* 0x44 */
+
+	u32 hi_stack;	/* normal stack */			/* 0x48 */
+	u32 hi_err_stack; /* error stack */		/* 0x4c */
+	u32 hi_desired_cpu_speed_hz;			/* 0x50 */
+
+	/* Pointer to Board Data  */
+	u32 hi_board_data;				/* 0x54 */
+
+	/*
+	 * Indication of Board Data state:
+	 *    0: board data is not yet initialized.
+	 *    1: board data is initialized; unknown size
+	 *   >1: number of bytes of initialized board data
+	 */
+	u32 hi_board_data_initialized;			/* 0x58 */
+
+	u32 hi_dset_ram_index_table;			/* 0x5c */
+
+	u32 hi_desired_baud_rate;			/* 0x60 */
+	u32 hi_dbglog_config;				/* 0x64 */
+	u32 hi_end_ram_reserve_sz;			/* 0x68 */
+	u32 hi_mbox_io_block_sz;			/* 0x6c */
+
+	u32 hi_num_bpatch_streams;			/* 0x70 -- unused */
+	u32 hi_mbox_isr_yield_limit;			/* 0x74 */
+
+	u32 hi_refclk_hz;				/* 0x78 */
+	u32 hi_ext_clk_detected;			/* 0x7c */
+	u32 hi_dbg_uart_txpin;				/* 0x80 */
+	u32 hi_dbg_uart_rxpin;				/* 0x84 */
+	u32 hi_hci_uart_baud;				/* 0x88 */
+	u32 hi_hci_uart_pin_assignments;		/* 0x8C */
+
+	u32 hi_hci_uart_baud_scale_val;			/* 0x90 */
+	u32 hi_hci_uart_baud_step_val;			/* 0x94 */
+
+	u32 hi_allocram_start;				/* 0x98 */
+	u32 hi_allocram_sz;				/* 0x9c */
+	u32 hi_hci_bridge_flags;			/* 0xa0 */
+	u32 hi_hci_uart_support_pins;			/* 0xa4 */
+
+	u32 hi_hci_uart_pwr_mgmt_params;		/* 0xa8 */
+
+	/*
+	 * 0xa8 - [1]: 0 = UART FC active low, 1 = UART FC active high
+	 *        [31:16]: wakeup timeout in ms
+	 */
+	/* Pointer to extended board Data  */
+	u32 hi_board_ext_data;				/* 0xac */
+	u32 hi_board_ext_data_config;			/* 0xb0 */
+	/*
+	 * Bit [0]  :   valid
+	 * Bit[31:16:   size
+	 */
+	/*
+	 * hi_reset_flag is used to do some stuff when target reset.
+	 * such as restore app_start after warm reset or
+	 * preserve host Interest area, or preserve ROM data, literals etc.
+	 */
+	u32  hi_reset_flag;				/* 0xb4 */
+	/* indicate hi_reset_flag is valid */
+	u32  hi_reset_flag_valid;			/* 0xb8 */
+	u32 hi_hci_uart_pwr_mgmt_params_ext;		/* 0xbc */
+	/* 0xbc - [31:0]: idle timeout in ms */
+	/* ACS flags */
+	u32 hi_acs_flags;				/* 0xc0 */
+	u32 hi_console_flags;				/* 0xc4 */
+	u32 hi_nvram_state;				/* 0xc8 */
+	u32 hi_option_flag2;				/* 0xcc */
+
+	/* If non-zero, override values sent to Host in WMI_READY event. */
+	u32 hi_sw_version_override;			/* 0xd0 */
+	u32 hi_abi_version_override;			/* 0xd4 */
+
+	/*
+	 * Percentage of high priority RX traffic to total expected RX traffic
+	 * applicable only to ar6004
+	 */
+	u32 hi_hp_rx_traffic_ratio;			/* 0xd8 */
+
+	/* test applications flags */
+	u32 hi_test_apps_related;			/* 0xdc */
+	/* location of test script */
+	u32 hi_ota_testscript;				/* 0xe0 */
+	/* location of CAL data */
+	u32 hi_cal_data;				/* 0xe4 */
+
+	/* Number of packet log buffers */
+	u32 hi_pktlog_num_buffers;			/* 0xe8 */
+
+	/* wow extension configuration */
+	u32 hi_wow_ext_config;				/* 0xec */
+	u32 hi_pwr_save_flags;				/* 0xf0 */
+
+	/* Spatial Multiplexing Power Save (SMPS) options */
+	u32 hi_smps_options;				/* 0xf4 */
+
+	/* Interconnect-specific state */
+	u32 hi_interconnect_state;			/* 0xf8 */
+
+	/* Coex configuration flags */
+	u32 hi_coex_config;				/* 0xfc */
+
+	/* Early allocation support */
+	u32 hi_early_alloc;				/* 0x100 */
+	/* FW swap field */
+	/*
+	 * Bits of this 32bit word will be used to pass specific swap
+	 * instruction to FW
+	 */
+	/*
+	 * Bit 0 -- AP Nart descriptor no swap. When this bit is set
+	 * FW will not swap TX descriptor. Meaning packets are formed
+	 * on the target processor.
+	 */
+	/* Bit 1 - unused */
+	u32 hi_fw_swap;					/* 0x104 */
+} __packed;
+
+#define HI_ITEM(item)  offsetof(struct host_interest, item)
+
+/* Bits defined in hi_option_flag */
+
+/* Enable timer workaround */
+#define HI_OPTION_TIMER_WAR         0x01
+/* Limit BMI command credits */
+#define HI_OPTION_BMI_CRED_LIMIT    0x02
+/* Relay Dot11 hdr to/from host */
+#define HI_OPTION_RELAY_DOT11_HDR   0x04
+/* MAC addr method 0-locally administred 1-globally unique addrs */
+#define HI_OPTION_MAC_ADDR_METHOD   0x08
+/* Firmware Bridging */
+#define HI_OPTION_FW_BRIDGE         0x10
+/* Enable CPU profiling */
+#define HI_OPTION_ENABLE_PROFILE    0x20
+/* Disable debug logging */
+#define HI_OPTION_DISABLE_DBGLOG    0x40
+/* Skip Era Tracking */
+#define HI_OPTION_SKIP_ERA_TRACKING 0x80
+/* Disable PAPRD (debug) */
+#define HI_OPTION_PAPRD_DISABLE     0x100
+#define HI_OPTION_NUM_DEV_LSB       0x200
+#define HI_OPTION_NUM_DEV_MSB       0x800
+#define HI_OPTION_DEV_MODE_LSB      0x1000
+#define HI_OPTION_DEV_MODE_MSB      0x8000000
+/* Disable LowFreq Timer Stabilization */
+#define HI_OPTION_NO_LFT_STBL       0x10000000
+/* Skip regulatory scan */
+#define HI_OPTION_SKIP_REG_SCAN     0x20000000
+/*
+ * Do regulatory scan during init before
+ * sending WMI ready event to host
+ */
+#define HI_OPTION_INIT_REG_SCAN     0x40000000
+
+/* REV6: Do not adjust memory map */
+#define HI_OPTION_SKIP_MEMMAP       0x80000000
+
+#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3
+
+/* 2 bits of hi_option_flag are used to represent 3 modes */
+#define HI_OPTION_FW_MODE_IBSS    0x0 /* IBSS Mode */
+#define HI_OPTION_FW_MODE_BSS_STA 0x1 /* STA Mode */
+#define HI_OPTION_FW_MODE_AP      0x2 /* AP Mode */
+#define HI_OPTION_FW_MODE_BT30AMP 0x3 /* BT30 AMP Mode */
+
+/* 2 bits of hi_option flag are usedto represent 4 submodes */
+#define HI_OPTION_FW_SUBMODE_NONE    0x0  /* Normal mode */
+#define HI_OPTION_FW_SUBMODE_P2PDEV  0x1  /* p2p device mode */
+#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2 /* p2p client mode */
+#define HI_OPTION_FW_SUBMODE_P2PGO   0x3 /* p2p go mode */
+
+/* Num dev Mask */
+#define HI_OPTION_NUM_DEV_MASK    0x7
+#define HI_OPTION_NUM_DEV_SHIFT   0x9
+
+/* firmware bridging */
+#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
+
+/*
+Fw Mode/SubMode Mask
+|-----------------------------------------------------------------------------|
+|  SUB   |   SUB   |   SUB   |  SUB    |         |         |         |        |
+|MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0]|
+|  (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)  |
+|-----------------------------------------------------------------------------|
+*/
+#define HI_OPTION_FW_MODE_BITS         0x2
+#define HI_OPTION_FW_MODE_MASK         0x3
+#define HI_OPTION_FW_MODE_SHIFT        0xC
+#define HI_OPTION_ALL_FW_MODE_MASK     0xFF
+
+#define HI_OPTION_FW_SUBMODE_BITS      0x2
+#define HI_OPTION_FW_SUBMODE_MASK      0x3
+#define HI_OPTION_FW_SUBMODE_SHIFT     0x14
+#define HI_OPTION_ALL_FW_SUBMODE_MASK  0xFF00
+#define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8
+
+
+/* hi_option_flag2 options */
+#define HI_OPTION_OFFLOAD_AMSDU     0x01
+#define HI_OPTION_DFS_SUPPORT       0x02 /* Enable DFS support */
+#define HI_OPTION_ENABLE_RFKILL     0x04 /* RFKill Enable Feature*/
+#define HI_OPTION_RADIO_RETENTION_DISABLE 0x08 /* Disable radio retention */
+#define HI_OPTION_EARLY_CFG_DONE    0x10 /* Early configuration is complete */
+
+#define HI_OPTION_RF_KILL_SHIFT     0x2
+#define HI_OPTION_RF_KILL_MASK      0x1
+
+/* hi_reset_flag */
+/* preserve App Start address */
+#define HI_RESET_FLAG_PRESERVE_APP_START         0x01
+/* preserve host interest */
+#define HI_RESET_FLAG_PRESERVE_HOST_INTEREST     0x02
+/* preserve ROM data */
+#define HI_RESET_FLAG_PRESERVE_ROMDATA           0x04
+#define HI_RESET_FLAG_PRESERVE_NVRAM_STATE       0x08
+#define HI_RESET_FLAG_PRESERVE_BOOT_INFO         0x10
+#define HI_RESET_FLAG_WARM_RESET	0x20
+
+/* define hi_fw_swap bits */
+#define HI_DESC_IN_FW_BIT	0x01
+
+/* indicate the reset flag is valid */
+#define HI_RESET_FLAG_IS_VALID  0x12345678
+
+/* ACS is enabled */
+#define HI_ACS_FLAGS_ENABLED        (1 << 0)
+/* Use physical WWAN device */
+#define HI_ACS_FLAGS_USE_WWAN       (1 << 1)
+/* Use test VAP */
+#define HI_ACS_FLAGS_TEST_VAP       (1 << 2)
+
+/*
+ * CONSOLE FLAGS
+ *
+ * Bit Range  Meaning
+ * ---------  --------------------------------
+ *   2..0     UART ID (0 = Default)
+ *    3       Baud Select (0 = 9600, 1 = 115200)
+ *   30..4    Reserved
+ *    31      Enable Console
+ *
+ */
+
+#define HI_CONSOLE_FLAGS_ENABLE       (1 << 31)
+#define HI_CONSOLE_FLAGS_UART_MASK    (0x7)
+#define HI_CONSOLE_FLAGS_UART_SHIFT   0
+#define HI_CONSOLE_FLAGS_BAUD_SELECT  (1 << 3)
+
+/* SM power save options */
+#define HI_SMPS_ALLOW_MASK            (0x00000001)
+#define HI_SMPS_MODE_MASK             (0x00000002)
+#define HI_SMPS_MODE_STATIC           (0x00000000)
+#define HI_SMPS_MODE_DYNAMIC          (0x00000002)
+#define HI_SMPS_DISABLE_AUTO_MODE     (0x00000004)
+#define HI_SMPS_DATA_THRESH_MASK      (0x000007f8)
+#define HI_SMPS_DATA_THRESH_SHIFT     (3)
+#define HI_SMPS_RSSI_THRESH_MASK      (0x0007f800)
+#define HI_SMPS_RSSI_THRESH_SHIFT     (11)
+#define HI_SMPS_LOWPWR_CM_MASK        (0x00380000)
+#define HI_SMPS_LOWPWR_CM_SHIFT       (15)
+#define HI_SMPS_HIPWR_CM_MASK         (0x03c00000)
+#define HI_SMPS_HIPWR_CM_SHIFT        (19)
+
+/*
+ * WOW Extension configuration
+ *
+ * Bit Range  Meaning
+ * ---------  --------------------------------
+ *   8..0     Size of each WOW pattern (max 511)
+ *   15..9    Number of patterns per list (max 127)
+ *   17..16   Number of lists (max 4)
+ *   30..18   Reserved
+ *   31       Enabled
+ *
+ *  set values (except enable) to zeros for default settings
+ */
+
+#define HI_WOW_EXT_ENABLED_MASK        (1 << 31)
+#define HI_WOW_EXT_NUM_LIST_SHIFT      16
+#define HI_WOW_EXT_NUM_LIST_MASK       (0x3 << HI_WOW_EXT_NUM_LIST_SHIFT)
+#define HI_WOW_EXT_NUM_PATTERNS_SHIFT  9
+#define HI_WOW_EXT_NUM_PATTERNS_MASK   (0x7F << HI_WOW_EXT_NUM_PATTERNS_SHIFT)
+#define HI_WOW_EXT_PATTERN_SIZE_SHIFT  0
+#define HI_WOW_EXT_PATTERN_SIZE_MASK   (0x1FF << HI_WOW_EXT_PATTERN_SIZE_SHIFT)
+
+#define HI_WOW_EXT_MAKE_CONFIG(num_lists, count, size) \
+	((((num_lists) << HI_WOW_EXT_NUM_LIST_SHIFT) & \
+		HI_WOW_EXT_NUM_LIST_MASK) | \
+	(((count) << HI_WOW_EXT_NUM_PATTERNS_SHIFT) & \
+		HI_WOW_EXT_NUM_PATTERNS_MASK) | \
+	(((size) << HI_WOW_EXT_PATTERN_SIZE_SHIFT) & \
+		HI_WOW_EXT_PATTERN_SIZE_MASK))
+
+#define HI_WOW_EXT_GET_NUM_LISTS(config) \
+	(((config) & HI_WOW_EXT_NUM_LIST_MASK) >> HI_WOW_EXT_NUM_LIST_SHIFT)
+#define HI_WOW_EXT_GET_NUM_PATTERNS(config) \
+	(((config) & HI_WOW_EXT_NUM_PATTERNS_MASK) >> \
+		HI_WOW_EXT_NUM_PATTERNS_SHIFT)
+#define HI_WOW_EXT_GET_PATTERN_SIZE(config) \
+	(((config) & HI_WOW_EXT_PATTERN_SIZE_MASK) >> \
+		HI_WOW_EXT_PATTERN_SIZE_SHIFT)
+
+/*
+ * Early allocation configuration
+ * Support RAM bank configuration before BMI done and this eases the memory
+ * allocation at very early stage
+ * Bit Range  Meaning
+ * ---------  ----------------------------------
+ * [0:3]      number of bank assigned to be IRAM
+ * [4:15]     reserved
+ * [16:31]    magic number
+ *
+ * Note:
+ * 1. target firmware would check magic number and if it's a match, firmware
+ *    would consider the bits[0:15] are valid and base on that to calculate
+ *    the end of DRAM. Early allocation would be located at that area and
+ *    may be reclaimed when necesary
+ * 2. if no magic number is found, early allocation would happen at "_end"
+ *    symbol of ROM which is located before the app-data and might NOT be
+ *    re-claimable. If this is adopted, link script should keep this in
+ *    mind to avoid data corruption.
+ */
+#define HI_EARLY_ALLOC_MAGIC		0x6d8a
+#define HI_EARLY_ALLOC_MAGIC_MASK	0xffff0000
+#define HI_EARLY_ALLOC_MAGIC_SHIFT	16
+#define HI_EARLY_ALLOC_IRAM_BANKS_MASK	0x0000000f
+#define HI_EARLY_ALLOC_IRAM_BANKS_SHIFT	0
+
+#define HI_EARLY_ALLOC_VALID() \
+	((((HOST_INTEREST->hi_early_alloc) & HI_EARLY_ALLOC_MAGIC_MASK) >> \
+	HI_EARLY_ALLOC_MAGIC_SHIFT) == (HI_EARLY_ALLOC_MAGIC))
+#define HI_EARLY_ALLOC_GET_IRAM_BANKS() \
+	(((HOST_INTEREST->hi_early_alloc) & HI_EARLY_ALLOC_IRAM_BANKS_MASK) \
+	>> HI_EARLY_ALLOC_IRAM_BANKS_SHIFT)
+
+/*power save flag bit definitions*/
+#define HI_PWR_SAVE_LPL_ENABLED   0x1
+/*b1-b3 reserved*/
+/*b4-b5 : dev0 LPL type : 0 - none
+			  1- Reduce Pwr Search
+			  2- Reduce Pwr Listen*/
+/*b6-b7 : dev1 LPL type and so on for Max 8 devices*/
+#define HI_PWR_SAVE_LPL_DEV0_LSB   4
+#define HI_PWR_SAVE_LPL_DEV_MASK   0x3
+/*power save related utility macros*/
+#define HI_LPL_ENABLED() \
+	((HOST_INTEREST->hi_pwr_save_flags & HI_PWR_SAVE_LPL_ENABLED))
+#define HI_DEV_LPL_TYPE_GET(_devix) \
+	(HOST_INTEREST->hi_pwr_save_flags & ((HI_PWR_SAVE_LPL_DEV_MASK) << \
+	 (HI_PWR_SAVE_LPL_DEV0_LSB + (_devix)*2)))
+
+#define HOST_INTEREST_SMPS_IS_ALLOWED() \
+	((HOST_INTEREST->hi_smps_options & HI_SMPS_ALLOW_MASK))
+
+/* Reserve 1024 bytes for extended board data */
+#define QCA988X_BOARD_DATA_SZ     7168
+#define QCA988X_BOARD_EXT_DATA_SZ 0
+
+#endif /* __TARGADDRS_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/trace.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/trace.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/trace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/trace.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+
+#define CREATE_TRACE_POINTS
+#include "trace.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/trace.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/trace.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/trace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/trace.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
+
+#include <linux/tracepoint.h>
+
+#define _TRACE_H_
+
+/* create empty functions when tracing is disabled */
+#if !defined(CONFIG_ATH10K_TRACING)
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, ...) \
+static inline void trace_ ## name(proto) {}
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(...)
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(evt_class, name, proto, ...) \
+static inline void trace_ ## name(proto) {}
+#endif /* !CONFIG_ATH10K_TRACING || __CHECKER__ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ath10k
+
+#define ATH10K_MSG_MAX 200
+
+DECLARE_EVENT_CLASS(ath10k_log_event,
+	TP_PROTO(struct va_format *vaf),
+	TP_ARGS(vaf),
+	TP_STRUCT__entry(
+		__dynamic_array(char, msg, ATH10K_MSG_MAX)
+	),
+	TP_fast_assign(
+		WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+				       ATH10K_MSG_MAX,
+				       vaf->fmt,
+				       *vaf->va) >= ATH10K_MSG_MAX);
+	),
+	TP_printk("%s", __get_str(msg))
+);
+
+DEFINE_EVENT(ath10k_log_event, ath10k_log_err,
+	     TP_PROTO(struct va_format *vaf),
+	     TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(ath10k_log_event, ath10k_log_warn,
+	     TP_PROTO(struct va_format *vaf),
+	     TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(ath10k_log_event, ath10k_log_info,
+	     TP_PROTO(struct va_format *vaf),
+	     TP_ARGS(vaf)
+);
+
+TRACE_EVENT(ath10k_log_dbg,
+	TP_PROTO(unsigned int level, struct va_format *vaf),
+	TP_ARGS(level, vaf),
+	TP_STRUCT__entry(
+		__field(unsigned int, level)
+		__dynamic_array(char, msg, ATH10K_MSG_MAX)
+	),
+	TP_fast_assign(
+		__entry->level = level;
+		WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+				       ATH10K_MSG_MAX,
+				       vaf->fmt,
+				       *vaf->va) >= ATH10K_MSG_MAX);
+	),
+	TP_printk("%s", __get_str(msg))
+);
+
+TRACE_EVENT(ath10k_log_dbg_dump,
+	TP_PROTO(const char *msg, const char *prefix,
+		 const void *buf, size_t buf_len),
+
+	TP_ARGS(msg, prefix, buf, buf_len),
+
+	TP_STRUCT__entry(
+		__string(msg, msg)
+		__string(prefix, prefix)
+		__field(size_t, buf_len)
+		__dynamic_array(u8, buf, buf_len)
+	),
+
+	TP_fast_assign(
+		__assign_str(msg, msg);
+		__assign_str(prefix, prefix);
+		__entry->buf_len = buf_len;
+		memcpy(__get_dynamic_array(buf), buf, buf_len);
+	),
+
+	TP_printk(
+		"%s/%s\n", __get_str(prefix), __get_str(msg)
+	)
+);
+
+TRACE_EVENT(ath10k_wmi_cmd,
+	TP_PROTO(int id, void *buf, size_t buf_len),
+
+	TP_ARGS(id, buf, buf_len),
+
+	TP_STRUCT__entry(
+		__field(unsigned int, id)
+		__field(size_t, buf_len)
+		__dynamic_array(u8, buf, buf_len)
+	),
+
+	TP_fast_assign(
+		__entry->id = id;
+		__entry->buf_len = buf_len;
+		memcpy(__get_dynamic_array(buf), buf, buf_len);
+	),
+
+	TP_printk(
+		"id %d len %zu",
+		__entry->id,
+		__entry->buf_len
+	)
+);
+
+TRACE_EVENT(ath10k_wmi_event,
+	TP_PROTO(int id, void *buf, size_t buf_len),
+
+	TP_ARGS(id, buf, buf_len),
+
+	TP_STRUCT__entry(
+		__field(unsigned int, id)
+		__field(size_t, buf_len)
+		__dynamic_array(u8, buf, buf_len)
+	),
+
+	TP_fast_assign(
+		__entry->id = id;
+		__entry->buf_len = buf_len;
+		memcpy(__get_dynamic_array(buf), buf, buf_len);
+	),
+
+	TP_printk(
+		"id %d len %zu",
+		__entry->id,
+		__entry->buf_len
+	)
+);
+
+#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/
+
+/* we don't want to use include/trace/events */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/txrx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/txrx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/txrx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/txrx.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "core.h"
+#include "txrx.h"
+#include "htt.h"
+#include "mac.h"
+#include "debug.h"
+
+static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
+{
+	if (!ATH10K_SKB_CB(skb)->htt.is_offchan)
+		return;
+
+	/* If the original wait_for_completion() timed out before
+	 * {data,mgmt}_tx_completed() was called then we could complete
+	 * offchan_tx_completed for a different skb. Prevent this by using
+	 * offchan_tx_skb. */
+	spin_lock_bh(&ar->data_lock);
+	if (ar->offchan_tx_skb != skb) {
+		ath10k_warn("completed old offchannel frame\n");
+		goto out;
+	}
+
+	complete(&ar->offchan_tx_completed);
+	ar->offchan_tx_skb = NULL; /* just for sanity */
+
+	ath10k_dbg(ATH10K_DBG_HTT, "completed offchannel skb %p\n", skb);
+out:
+	spin_unlock_bh(&ar->data_lock);
+}
+
+void ath10k_txrx_tx_unref(struct ath10k_htt *htt, struct sk_buff *txdesc)
+{
+	struct device *dev = htt->ar->dev;
+	struct ieee80211_tx_info *info;
+	struct sk_buff *txfrag = ATH10K_SKB_CB(txdesc)->htt.txfrag;
+	struct sk_buff *msdu = ATH10K_SKB_CB(txdesc)->htt.msdu;
+	int ret;
+
+	if (ATH10K_SKB_CB(txdesc)->htt.refcount == 0)
+		return;
+
+	ATH10K_SKB_CB(txdesc)->htt.refcount--;
+
+	if (ATH10K_SKB_CB(txdesc)->htt.refcount > 0)
+		return;
+
+	if (txfrag) {
+		ret = ath10k_skb_unmap(dev, txfrag);
+		if (ret)
+			ath10k_warn("txfrag unmap failed (%d)\n", ret);
+
+		dev_kfree_skb_any(txfrag);
+	}
+
+	ret = ath10k_skb_unmap(dev, msdu);
+	if (ret)
+		ath10k_warn("data skb unmap failed (%d)\n", ret);
+
+	ath10k_report_offchan_tx(htt->ar, msdu);
+
+	info = IEEE80211_SKB_CB(msdu);
+	memset(&info->status, 0, sizeof(info->status));
+
+	if (ATH10K_SKB_CB(txdesc)->htt.discard) {
+		ieee80211_free_txskb(htt->ar->hw, msdu);
+		goto exit;
+	}
+
+	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
+		info->flags |= IEEE80211_TX_STAT_ACK;
+
+	if (ATH10K_SKB_CB(txdesc)->htt.no_ack)
+		info->flags &= ~IEEE80211_TX_STAT_ACK;
+
+	ieee80211_tx_status(htt->ar->hw, msdu);
+	/* we do not own the msdu anymore */
+
+exit:
+	spin_lock_bh(&htt->tx_lock);
+	htt->pending_tx[ATH10K_SKB_CB(txdesc)->htt.msdu_id] = NULL;
+	ath10k_htt_tx_free_msdu_id(htt, ATH10K_SKB_CB(txdesc)->htt.msdu_id);
+	__ath10k_htt_tx_dec_pending(htt);
+	if (bitmap_empty(htt->used_msdu_ids, htt->max_num_pending_tx))
+		wake_up(&htt->empty_tx_wq);
+	spin_unlock_bh(&htt->tx_lock);
+
+	dev_kfree_skb_any(txdesc);
+}
+
+void ath10k_txrx_tx_completed(struct ath10k_htt *htt,
+			      const struct htt_tx_done *tx_done)
+{
+	struct sk_buff *txdesc;
+
+	ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion msdu_id %u discard %d no_ack %d\n",
+		   tx_done->msdu_id, !!tx_done->discard, !!tx_done->no_ack);
+
+	if (tx_done->msdu_id >= htt->max_num_pending_tx) {
+		ath10k_warn("warning: msdu_id %d too big, ignoring\n",
+			    tx_done->msdu_id);
+		return;
+	}
+
+	txdesc = htt->pending_tx[tx_done->msdu_id];
+
+	ATH10K_SKB_CB(txdesc)->htt.discard = tx_done->discard;
+	ATH10K_SKB_CB(txdesc)->htt.no_ack = tx_done->no_ack;
+
+	ath10k_txrx_tx_unref(htt, txdesc);
+}
+
+static const u8 rx_legacy_rate_idx[] = {
+	3,	/* 0x00  - 11Mbps  */
+	2,	/* 0x01  - 5.5Mbps */
+	1,	/* 0x02  - 2Mbps   */
+	0,	/* 0x03  - 1Mbps   */
+	3,	/* 0x04  - 11Mbps  */
+	2,	/* 0x05  - 5.5Mbps */
+	1,	/* 0x06  - 2Mbps   */
+	0,	/* 0x07  - 1Mbps   */
+	10,	/* 0x08  - 48Mbps  */
+	8,	/* 0x09  - 24Mbps  */
+	6,	/* 0x0A  - 12Mbps  */
+	4,	/* 0x0B  - 6Mbps   */
+	11,	/* 0x0C  - 54Mbps  */
+	9,	/* 0x0D  - 36Mbps  */
+	7,	/* 0x0E  - 18Mbps  */
+	5,	/* 0x0F  - 9Mbps   */
+};
+
+static void process_rx_rates(struct ath10k *ar, struct htt_rx_info *info,
+			     enum ieee80211_band band,
+			     struct ieee80211_rx_status *status)
+{
+	u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
+	u8 info0 = info->rate.info0;
+	u32 info1 = info->rate.info1;
+	u32 info2 = info->rate.info2;
+	u8 preamble = 0;
+
+	/* Check if valid fields */
+	if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID))
+		return;
+
+	preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE);
+
+	switch (preamble) {
+	case HTT_RX_LEGACY:
+		cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK;
+		rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE);
+		rate_idx = 0;
+
+		if (rate < 0x08 || rate > 0x0F)
+			break;
+
+		switch (band) {
+		case IEEE80211_BAND_2GHZ:
+			if (cck)
+				rate &= ~BIT(3);
+			rate_idx = rx_legacy_rate_idx[rate];
+			break;
+		case IEEE80211_BAND_5GHZ:
+			rate_idx = rx_legacy_rate_idx[rate];
+			/* We are using same rate table registering
+			   HW - ath10k_rates[]. In case of 5GHz skip
+			   CCK rates, so -4 here */
+			rate_idx -= 4;
+			break;
+		default:
+			break;
+		}
+
+		status->rate_idx = rate_idx;
+		break;
+	case HTT_RX_HT:
+	case HTT_RX_HT_WITH_TXBF:
+		/* HT-SIG - Table 20-11 in info1 and info2 */
+		mcs = info1 & 0x1F;
+		nss = mcs >> 3;
+		bw = (info1 >> 7) & 1;
+		sgi = (info2 >> 7) & 1;
+
+		status->rate_idx = mcs;
+		status->flag |= RX_FLAG_HT;
+		if (sgi)
+			status->flag |= RX_FLAG_SHORT_GI;
+		if (bw)
+			status->flag |= RX_FLAG_40MHZ;
+		break;
+	case HTT_RX_VHT:
+	case HTT_RX_VHT_WITH_TXBF:
+		/* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2
+		   TODO check this */
+		mcs = (info2 >> 4) & 0x0F;
+		nss = (info1 >> 10) & 0x07;
+		bw = info1 & 3;
+		sgi = info2 & 1;
+
+		status->rate_idx = mcs;
+		status->vht_nss = nss;
+
+		if (sgi)
+			status->flag |= RX_FLAG_SHORT_GI;
+
+		switch (bw) {
+		/* 20MHZ */
+		case 0:
+			break;
+		/* 40MHZ */
+		case 1:
+			status->flag |= RX_FLAG_40MHZ;
+			break;
+		/* 80MHZ */
+		case 2:
+			status->flag |= RX_FLAG_80MHZ;
+		}
+
+		status->flag |= RX_FLAG_VHT;
+		break;
+	default:
+		break;
+	}
+}
+
+void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
+{
+	struct ieee80211_rx_status *status;
+	struct ieee80211_channel *ch;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;
+
+	status = IEEE80211_SKB_RXCB(info->skb);
+	memset(status, 0, sizeof(*status));
+
+	if (info->encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
+		status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
+				RX_FLAG_MMIC_STRIPPED;
+		hdr->frame_control = __cpu_to_le16(
+				__le16_to_cpu(hdr->frame_control) &
+				~IEEE80211_FCTL_PROTECTED);
+	}
+
+	if (info->status == HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR)
+		status->flag |= RX_FLAG_MMIC_ERROR;
+
+	if (info->fcs_err)
+		status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+	status->signal = info->signal;
+
+	spin_lock_bh(&ar->data_lock);
+	ch = ar->scan_channel;
+	if (!ch)
+		ch = ar->rx_channel;
+	spin_unlock_bh(&ar->data_lock);
+
+	if (!ch) {
+		ath10k_warn("no channel configured; ignoring frame!\n");
+		dev_kfree_skb_any(info->skb);
+		return;
+	}
+
+	process_rx_rates(ar, info, ch->band, status);
+	status->band = ch->band;
+	status->freq = ch->center_freq;
+
+	ath10k_dbg(ATH10K_DBG_DATA,
+		   "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u\n",
+		   info->skb,
+		   info->skb->len,
+		   status->flag == 0 ? "legacy" : "",
+		   status->flag & RX_FLAG_HT ? "ht" : "",
+		   status->flag & RX_FLAG_VHT ? "vht" : "",
+		   status->flag & RX_FLAG_40MHZ ? "40" : "",
+		   status->flag & RX_FLAG_80MHZ ? "80" : "",
+		   status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
+		   status->rate_idx,
+		   status->vht_nss,
+		   status->freq,
+		   status->band);
+
+	ieee80211_rx(ar->hw, info->skb);
+}
+
+struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
+				     const u8 *addr)
+{
+	struct ath10k_peer *peer;
+
+	lockdep_assert_held(&ar->data_lock);
+
+	list_for_each_entry(peer, &ar->peers, list) {
+		if (peer->vdev_id != vdev_id)
+			continue;
+		if (memcmp(peer->addr, addr, ETH_ALEN))
+			continue;
+
+		return peer;
+	}
+
+	return NULL;
+}
+
+static struct ath10k_peer *ath10k_peer_find_by_id(struct ath10k *ar,
+						  int peer_id)
+{
+	struct ath10k_peer *peer;
+
+	lockdep_assert_held(&ar->data_lock);
+
+	list_for_each_entry(peer, &ar->peers, list)
+		if (test_bit(peer_id, peer->peer_ids))
+			return peer;
+
+	return NULL;
+}
+
+static int ath10k_wait_for_peer_common(struct ath10k *ar, int vdev_id,
+				       const u8 *addr, bool expect_mapped)
+{
+	int ret;
+
+	ret = wait_event_timeout(ar->peer_mapping_wq, ({
+			bool mapped;
+
+			spin_lock_bh(&ar->data_lock);
+			mapped = !!ath10k_peer_find(ar, vdev_id, addr);
+			spin_unlock_bh(&ar->data_lock);
+
+			mapped == expect_mapped;
+		}), 3*HZ);
+
+	if (ret <= 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+int ath10k_wait_for_peer_created(struct ath10k *ar, int vdev_id, const u8 *addr)
+{
+	return ath10k_wait_for_peer_common(ar, vdev_id, addr, true);
+}
+
+int ath10k_wait_for_peer_deleted(struct ath10k *ar, int vdev_id, const u8 *addr)
+{
+	return ath10k_wait_for_peer_common(ar, vdev_id, addr, false);
+}
+
+void ath10k_peer_map_event(struct ath10k_htt *htt,
+			   struct htt_peer_map_event *ev)
+{
+	struct ath10k *ar = htt->ar;
+	struct ath10k_peer *peer;
+
+	spin_lock_bh(&ar->data_lock);
+	peer = ath10k_peer_find(ar, ev->vdev_id, ev->addr);
+	if (!peer) {
+		peer = kzalloc(sizeof(*peer), GFP_ATOMIC);
+		if (!peer)
+			goto exit;
+
+		peer->vdev_id = ev->vdev_id;
+		memcpy(peer->addr, ev->addr, ETH_ALEN);
+		list_add(&peer->list, &ar->peers);
+		wake_up(&ar->peer_mapping_wq);
+	}
+
+	ath10k_dbg(ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n",
+		   ev->vdev_id, ev->addr, ev->peer_id);
+
+	set_bit(ev->peer_id, peer->peer_ids);
+exit:
+	spin_unlock_bh(&ar->data_lock);
+}
+
+void ath10k_peer_unmap_event(struct ath10k_htt *htt,
+			     struct htt_peer_unmap_event *ev)
+{
+	struct ath10k *ar = htt->ar;
+	struct ath10k_peer *peer;
+
+	spin_lock_bh(&ar->data_lock);
+	peer = ath10k_peer_find_by_id(ar, ev->peer_id);
+	if (!peer) {
+		ath10k_warn("unknown peer id %d\n", ev->peer_id);
+		goto exit;
+	}
+
+	ath10k_dbg(ATH10K_DBG_HTT, "htt peer unmap vdev %d peer %pM id %d\n",
+		   peer->vdev_id, peer->addr, ev->peer_id);
+
+	clear_bit(ev->peer_id, peer->peer_ids);
+
+	if (bitmap_empty(peer->peer_ids, ATH10K_MAX_NUM_PEER_IDS)) {
+		list_del(&peer->list);
+		kfree(peer);
+		wake_up(&ar->peer_mapping_wq);
+	}
+
+exit:
+	spin_unlock_bh(&ar->data_lock);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/txrx.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/txrx.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/txrx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/txrx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef _TXRX_H_
+#define _TXRX_H_
+
+#include "htt.h"
+
+void ath10k_txrx_tx_unref(struct ath10k_htt *htt, struct sk_buff *txdesc);
+void ath10k_txrx_tx_completed(struct ath10k_htt *htt,
+			      const struct htt_tx_done *tx_done);
+void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info);
+
+struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
+				     const u8 *addr);
+int ath10k_wait_for_peer_created(struct ath10k *ar, int vdev_id,
+				 const u8 *addr);
+int ath10k_wait_for_peer_deleted(struct ath10k *ar, int vdev_id,
+				 const u8 *addr);
+
+void ath10k_peer_map_event(struct ath10k_htt *htt,
+			   struct htt_peer_map_event *ev);
+void ath10k_peer_unmap_event(struct ath10k_htt *htt,
+			     struct htt_peer_unmap_event *ev);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/wmi.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/wmi.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/wmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/wmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2081 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/skbuff.h>
+
+#include "core.h"
+#include "htc.h"
+#include "debug.h"
+#include "wmi.h"
+#include "mac.h"
+
+void ath10k_wmi_flush_tx(struct ath10k *ar)
+{
+	int ret;
+
+	ret = wait_event_timeout(ar->wmi.wq,
+				 atomic_read(&ar->wmi.pending_tx_count) == 0,
+				 5*HZ);
+	if (atomic_read(&ar->wmi.pending_tx_count) == 0)
+		return;
+
+	if (ret == 0)
+		ret = -ETIMEDOUT;
+
+	if (ret < 0)
+		ath10k_warn("wmi flush failed (%d)\n", ret);
+}
+
+int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
+{
+	int ret;
+	ret = wait_for_completion_timeout(&ar->wmi.service_ready,
+					  WMI_SERVICE_READY_TIMEOUT_HZ);
+	return ret;
+}
+
+int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar)
+{
+	int ret;
+	ret = wait_for_completion_timeout(&ar->wmi.unified_ready,
+					  WMI_UNIFIED_READY_TIMEOUT_HZ);
+	return ret;
+}
+
+static struct sk_buff *ath10k_wmi_alloc_skb(u32 len)
+{
+	struct sk_buff *skb;
+	u32 round_len = roundup(len, 4);
+
+	skb = ath10k_htc_alloc_skb(WMI_SKB_HEADROOM + round_len);
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, WMI_SKB_HEADROOM);
+	if (!IS_ALIGNED((unsigned long)skb->data, 4))
+		ath10k_warn("Unaligned WMI skb\n");
+
+	skb_put(skb, round_len);
+	memset(skb->data, 0, round_len);
+
+	return skb;
+}
+
+static void ath10k_wmi_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
+{
+	dev_kfree_skb(skb);
+
+	if (atomic_sub_return(1, &ar->wmi.pending_tx_count) == 0)
+		wake_up(&ar->wmi.wq);
+}
+
+/* WMI command API */
+static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb,
+			       enum wmi_cmd_id cmd_id)
+{
+	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
+	struct wmi_cmd_hdr *cmd_hdr;
+	int status;
+	u32 cmd = 0;
+
+	if (skb_push(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
+		return -ENOMEM;
+
+	cmd |= SM(cmd_id, WMI_CMD_HDR_CMD_ID);
+
+	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
+	cmd_hdr->cmd_id = __cpu_to_le32(cmd);
+
+	if (atomic_add_return(1, &ar->wmi.pending_tx_count) >
+	    WMI_MAX_PENDING_TX_COUNT) {
+		/* avoid using up memory when FW hangs */
+		atomic_dec(&ar->wmi.pending_tx_count);
+		return -EBUSY;
+	}
+
+	memset(skb_cb, 0, sizeof(*skb_cb));
+
+	trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len);
+
+	status = ath10k_htc_send(ar->htc, ar->wmi.eid, skb);
+	if (status) {
+		dev_kfree_skb_any(skb);
+		atomic_dec(&ar->wmi.pending_tx_count);
+		return status;
+	}
+
+	return 0;
+}
+
+static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct wmi_scan_event *event = (struct wmi_scan_event *)skb->data;
+	enum wmi_scan_event_type event_type;
+	enum wmi_scan_completion_reason reason;
+	u32 freq;
+	u32 req_id;
+	u32 scan_id;
+	u32 vdev_id;
+
+	event_type = __le32_to_cpu(event->event_type);
+	reason     = __le32_to_cpu(event->reason);
+	freq       = __le32_to_cpu(event->channel_freq);
+	req_id     = __le32_to_cpu(event->scan_req_id);
+	scan_id    = __le32_to_cpu(event->scan_id);
+	vdev_id    = __le32_to_cpu(event->vdev_id);
+
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENTID\n");
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "scan event type %d reason %d freq %d req_id %d "
+		   "scan_id %d vdev_id %d\n",
+		   event_type, reason, freq, req_id, scan_id, vdev_id);
+
+	spin_lock_bh(&ar->data_lock);
+
+	switch (event_type) {
+	case WMI_SCAN_EVENT_STARTED:
+		ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_STARTED\n");
+		if (ar->scan.in_progress && ar->scan.is_roc)
+			ieee80211_ready_on_channel(ar->hw);
+
+		complete(&ar->scan.started);
+		break;
+	case WMI_SCAN_EVENT_COMPLETED:
+		ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_COMPLETED\n");
+		switch (reason) {
+		case WMI_SCAN_REASON_COMPLETED:
+			ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_COMPLETED\n");
+			break;
+		case WMI_SCAN_REASON_CANCELLED:
+			ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_CANCELED\n");
+			break;
+		case WMI_SCAN_REASON_PREEMPTED:
+			ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_PREEMPTED\n");
+			break;
+		case WMI_SCAN_REASON_TIMEDOUT:
+			ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_TIMEDOUT\n");
+			break;
+		default:
+			break;
+		}
+
+		ar->scan_channel = NULL;
+		if (!ar->scan.in_progress) {
+			ath10k_warn("no scan requested, ignoring\n");
+			break;
+		}
+
+		if (ar->scan.is_roc) {
+			ath10k_offchan_tx_purge(ar);
+
+			if (!ar->scan.aborting)
+				ieee80211_remain_on_channel_expired(ar->hw);
+		} else {
+			ieee80211_scan_completed(ar->hw, ar->scan.aborting);
+		}
+
+		del_timer(&ar->scan.timeout);
+		complete_all(&ar->scan.completed);
+		ar->scan.in_progress = false;
+		break;
+	case WMI_SCAN_EVENT_BSS_CHANNEL:
+		ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_BSS_CHANNEL\n");
+		ar->scan_channel = NULL;
+		break;
+	case WMI_SCAN_EVENT_FOREIGN_CHANNEL:
+		ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_FOREIGN_CHANNEL\n");
+		ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq);
+		if (ar->scan.in_progress && ar->scan.is_roc &&
+		    ar->scan.roc_freq == freq) {
+			complete(&ar->scan.on_channel);
+		}
+		break;
+	case WMI_SCAN_EVENT_DEQUEUED:
+		ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_DEQUEUED\n");
+		break;
+	case WMI_SCAN_EVENT_PREEMPTED:
+		ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENT_PREEMPTED\n");
+		break;
+	case WMI_SCAN_EVENT_START_FAILED:
+		ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENT_START_FAILED\n");
+		break;
+	default:
+		break;
+	}
+
+	spin_unlock_bh(&ar->data_lock);
+	return 0;
+}
+
+static inline enum ieee80211_band phy_mode_to_band(u32 phy_mode)
+{
+	enum ieee80211_band band;
+
+	switch (phy_mode) {
+	case MODE_11A:
+	case MODE_11NA_HT20:
+	case MODE_11NA_HT40:
+	case MODE_11AC_VHT20:
+	case MODE_11AC_VHT40:
+	case MODE_11AC_VHT80:
+		band = IEEE80211_BAND_5GHZ;
+		break;
+	case MODE_11G:
+	case MODE_11B:
+	case MODE_11GONLY:
+	case MODE_11NG_HT20:
+	case MODE_11NG_HT40:
+	case MODE_11AC_VHT20_2G:
+	case MODE_11AC_VHT40_2G:
+	case MODE_11AC_VHT80_2G:
+	default:
+		band = IEEE80211_BAND_2GHZ;
+	}
+
+	return band;
+}
+
+static inline u8 get_rate_idx(u32 rate, enum ieee80211_band band)
+{
+	u8 rate_idx = 0;
+
+	/* rate in Kbps */
+	switch (rate) {
+	case 1000:
+		rate_idx = 0;
+		break;
+	case 2000:
+		rate_idx = 1;
+		break;
+	case 5500:
+		rate_idx = 2;
+		break;
+	case 11000:
+		rate_idx = 3;
+		break;
+	case 6000:
+		rate_idx = 4;
+		break;
+	case 9000:
+		rate_idx = 5;
+		break;
+	case 12000:
+		rate_idx = 6;
+		break;
+	case 18000:
+		rate_idx = 7;
+		break;
+	case 24000:
+		rate_idx = 8;
+		break;
+	case 36000:
+		rate_idx = 9;
+		break;
+	case 48000:
+		rate_idx = 10;
+		break;
+	case 54000:
+		rate_idx = 11;
+		break;
+	default:
+		break;
+	}
+
+	if (band == IEEE80211_BAND_5GHZ) {
+		if (rate_idx > 3)
+			/* Omit CCK rates */
+			rate_idx -= 4;
+		else
+			rate_idx = 0;
+	}
+
+	return rate_idx;
+}
+
+static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct wmi_mgmt_rx_event *event = (struct wmi_mgmt_rx_event *)skb->data;
+	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+	struct ieee80211_hdr *hdr;
+	u32 rx_status;
+	u32 channel;
+	u32 phy_mode;
+	u32 snr;
+	u32 rate;
+	u32 buf_len;
+	u16 fc;
+
+	channel   = __le32_to_cpu(event->hdr.channel);
+	buf_len   = __le32_to_cpu(event->hdr.buf_len);
+	rx_status = __le32_to_cpu(event->hdr.status);
+	snr       = __le32_to_cpu(event->hdr.snr);
+	phy_mode  = __le32_to_cpu(event->hdr.phy_mode);
+	rate	  = __le32_to_cpu(event->hdr.rate);
+
+	memset(status, 0, sizeof(*status));
+
+	ath10k_dbg(ATH10K_DBG_MGMT,
+		   "event mgmt rx status %08x\n", rx_status);
+
+	if (rx_status & WMI_RX_STATUS_ERR_DECRYPT) {
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+	if (rx_status & WMI_RX_STATUS_ERR_KEY_CACHE_MISS) {
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+	if (rx_status & WMI_RX_STATUS_ERR_CRC)
+		status->flag |= RX_FLAG_FAILED_FCS_CRC;
+	if (rx_status & WMI_RX_STATUS_ERR_MIC)
+		status->flag |= RX_FLAG_MMIC_ERROR;
+
+	status->band = phy_mode_to_band(phy_mode);
+	status->freq = ieee80211_channel_to_frequency(channel, status->band);
+	status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR;
+	status->rate_idx = get_rate_idx(rate, status->band);
+
+	skb_pull(skb, sizeof(event->hdr));
+
+	hdr = (struct ieee80211_hdr *)skb->data;
+	fc = le16_to_cpu(hdr->frame_control);
+
+	if (fc & IEEE80211_FCTL_PROTECTED) {
+		status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
+				RX_FLAG_MMIC_STRIPPED;
+		hdr->frame_control = __cpu_to_le16(fc &
+					~IEEE80211_FCTL_PROTECTED);
+	}
+
+	ath10k_dbg(ATH10K_DBG_MGMT,
+		   "event mgmt rx skb %p len %d ftype %02x stype %02x\n",
+		   skb, skb->len,
+		   fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE);
+
+	ath10k_dbg(ATH10K_DBG_MGMT,
+		   "event mgmt rx freq %d band %d snr %d, rate_idx %d\n",
+		   status->freq, status->band, status->signal,
+		   status->rate_idx);
+
+	/*
+	 * packets from HTC come aligned to 4byte boundaries
+	 * because they can originally come in along with a trailer
+	 */
+	skb_trim(skb, buf_len);
+
+	ieee80211_rx(ar->hw, skb);
+	return 0;
+}
+
+static void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_CHAN_INFO_EVENTID\n");
+}
+
+static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n");
+}
+
+static void ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_MESG_EVENTID\n");
+}
+
+static void ath10k_wmi_event_update_stats(struct ath10k *ar,
+					  struct sk_buff *skb)
+{
+	struct wmi_stats_event *ev = (struct wmi_stats_event *)skb->data;
+
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n");
+
+	ath10k_debug_read_target_stats(ar, ev);
+}
+
+static void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar,
+					     struct sk_buff *skb)
+{
+	struct wmi_vdev_start_response_event *ev;
+
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n");
+
+	ev = (struct wmi_vdev_start_response_event *)skb->data;
+
+	if (WARN_ON(__le32_to_cpu(ev->status)))
+		return;
+
+	complete(&ar->vdev_setup_done);
+}
+
+static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar,
+					  struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n");
+	complete(&ar->vdev_setup_done);
+}
+
+static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar,
+					      struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_PEER_STA_KICKOUT_EVENTID\n");
+}
+
+/*
+ * FIXME
+ *
+ * We don't report to mac80211 sleep state of connected
+ * stations. Due to this mac80211 can't fill in TIM IE
+ * correctly.
+ *
+ * I know of no way of getting nullfunc frames that contain
+ * sleep transition from connected stations - these do not
+ * seem to be sent from the target to the host. There also
+ * doesn't seem to be a dedicated event for that. So the
+ * only way left to do this would be to read tim_bitmap
+ * during SWBA.
+ *
+ * We could probably try using tim_bitmap from SWBA to tell
+ * mac80211 which stations are asleep and which are not. The
+ * problem here is calling mac80211 functions so many times
+ * could take too long and make us miss the time to submit
+ * the beacon to the target.
+ *
+ * So as a workaround we try to extend the TIM IE if there
+ * is unicast buffered for stations with aid > 7 and fill it
+ * in ourselves.
+ */
+static void ath10k_wmi_update_tim(struct ath10k *ar,
+				  struct ath10k_vif *arvif,
+				  struct sk_buff *bcn,
+				  struct wmi_bcn_info *bcn_info)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data;
+	struct ieee80211_tim_ie *tim;
+	u8 *ies, *ie;
+	u8 ie_len, pvm_len;
+
+	/* if next SWBA has no tim_changed the tim_bitmap is garbage.
+	 * we must copy the bitmap upon change and reuse it later */
+	if (__le32_to_cpu(bcn_info->tim_info.tim_changed)) {
+		int i;
+
+		BUILD_BUG_ON(sizeof(arvif->u.ap.tim_bitmap) !=
+			     sizeof(bcn_info->tim_info.tim_bitmap));
+
+		for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) {
+			__le32 t = bcn_info->tim_info.tim_bitmap[i / 4];
+			u32 v = __le32_to_cpu(t);
+			arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF;
+		}
+
+		/* FW reports either length 0 or 16
+		 * so we calculate this on our own */
+		arvif->u.ap.tim_len = 0;
+		for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++)
+			if (arvif->u.ap.tim_bitmap[i])
+				arvif->u.ap.tim_len = i;
+
+		arvif->u.ap.tim_len++;
+	}
+
+	ies = bcn->data;
+	ies += ieee80211_hdrlen(hdr->frame_control);
+	ies += 12; /* fixed parameters */
+
+	ie = (u8 *)cfg80211_find_ie(WLAN_EID_TIM, ies,
+				    (u8 *)skb_tail_pointer(bcn) - ies);
+	if (!ie) {
+		/* highly unlikely for mac80211 */
+		ath10k_warn("no tim ie found;\n");
+		return;
+	}
+
+	tim = (void *)ie + 2;
+	ie_len = ie[1];
+	pvm_len = ie_len - 3; /* exclude dtim count, dtim period, bmap ctl */
+
+	if (pvm_len < arvif->u.ap.tim_len) {
+		int expand_size = sizeof(arvif->u.ap.tim_bitmap) - pvm_len;
+		int move_size = skb_tail_pointer(bcn) - (ie + 2 + ie_len);
+		void *next_ie = ie + 2 + ie_len;
+
+		if (skb_put(bcn, expand_size)) {
+			memmove(next_ie + expand_size, next_ie, move_size);
+
+			ie[1] += expand_size;
+			ie_len += expand_size;
+			pvm_len += expand_size;
+		} else {
+			ath10k_warn("tim expansion failed\n");
+		}
+	}
+
+	if (pvm_len > sizeof(arvif->u.ap.tim_bitmap)) {
+		ath10k_warn("tim pvm length is too great (%d)\n", pvm_len);
+		return;
+	}
+
+	tim->bitmap_ctrl = !!__le32_to_cpu(bcn_info->tim_info.tim_mcast);
+	memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);
+
+	ath10k_dbg(ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n",
+		   tim->dtim_count, tim->dtim_period,
+		   tim->bitmap_ctrl, pvm_len);
+}
+
+static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len,
+				   struct wmi_p2p_noa_info *noa)
+{
+	struct ieee80211_p2p_noa_attr *noa_attr;
+	u8  ctwindow_oppps = noa->ctwindow_oppps;
+	u8 ctwindow = ctwindow_oppps >> WMI_P2P_OPPPS_CTWINDOW_OFFSET;
+	bool oppps = !!(ctwindow_oppps & WMI_P2P_OPPPS_ENABLE_BIT);
+	__le16 *noa_attr_len;
+	u16 attr_len;
+	u8 noa_descriptors = noa->num_descriptors;
+	int i;
+
+	/* P2P IE */
+	data[0] = WLAN_EID_VENDOR_SPECIFIC;
+	data[1] = len - 2;
+	data[2] = (WLAN_OUI_WFA >> 16) & 0xff;
+	data[3] = (WLAN_OUI_WFA >> 8) & 0xff;
+	data[4] = (WLAN_OUI_WFA >> 0) & 0xff;
+	data[5] = WLAN_OUI_TYPE_WFA_P2P;
+
+	/* NOA ATTR */
+	data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE;
+	noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */
+	noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9];
+
+	noa_attr->index = noa->index;
+	noa_attr->oppps_ctwindow = ctwindow;
+	if (oppps)
+		noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT;
+
+	for (i = 0; i < noa_descriptors; i++) {
+		noa_attr->desc[i].count =
+			__le32_to_cpu(noa->descriptors[i].type_count);
+		noa_attr->desc[i].duration = noa->descriptors[i].duration;
+		noa_attr->desc[i].interval = noa->descriptors[i].interval;
+		noa_attr->desc[i].start_time = noa->descriptors[i].start_time;
+	}
+
+	attr_len = 2; /* index + oppps_ctwindow */
+	attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
+	*noa_attr_len = __cpu_to_le16(attr_len);
+}
+
+static u32 ath10k_p2p_calc_noa_ie_len(struct wmi_p2p_noa_info *noa)
+{
+	u32 len = 0;
+	u8 noa_descriptors = noa->num_descriptors;
+	u8 opp_ps_info = noa->ctwindow_oppps;
+	bool opps_enabled = !!(opp_ps_info & WMI_P2P_OPPPS_ENABLE_BIT);
+
+
+	if (!noa_descriptors && !opps_enabled)
+		return len;
+
+	len += 1 + 1 + 4; /* EID + len + OUI */
+	len += 1 + 2; /* noa attr  + attr len */
+	len += 1 + 1; /* index + oppps_ctwindow */
+	len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
+
+	return len;
+}
+
+static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif,
+				  struct sk_buff *bcn,
+				  struct wmi_bcn_info *bcn_info)
+{
+	struct wmi_p2p_noa_info *noa = &bcn_info->p2p_noa_info;
+	u8 *new_data, *old_data = arvif->u.ap.noa_data;
+	u32 new_len;
+
+	if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
+		return;
+
+	ath10k_dbg(ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed);
+	if (noa->changed & WMI_P2P_NOA_CHANGED_BIT) {
+		new_len = ath10k_p2p_calc_noa_ie_len(noa);
+		if (!new_len)
+			goto cleanup;
+
+		new_data = kmalloc(new_len, GFP_ATOMIC);
+		if (!new_data)
+			goto cleanup;
+
+		ath10k_p2p_fill_noa_ie(new_data, new_len, noa);
+
+		spin_lock_bh(&ar->data_lock);
+		arvif->u.ap.noa_data = new_data;
+		arvif->u.ap.noa_len = new_len;
+		spin_unlock_bh(&ar->data_lock);
+		kfree(old_data);
+	}
+
+	if (arvif->u.ap.noa_data)
+		if (!pskb_expand_head(bcn, 0, arvif->u.ap.noa_len, GFP_ATOMIC))
+			memcpy(skb_put(bcn, arvif->u.ap.noa_len),
+			       arvif->u.ap.noa_data,
+			       arvif->u.ap.noa_len);
+	return;
+
+cleanup:
+	spin_lock_bh(&ar->data_lock);
+	arvif->u.ap.noa_data = NULL;
+	arvif->u.ap.noa_len = 0;
+	spin_unlock_bh(&ar->data_lock);
+	kfree(old_data);
+}
+
+
+static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct wmi_host_swba_event *ev;
+	u32 map;
+	int i = -1;
+	struct wmi_bcn_info *bcn_info;
+	struct ath10k_vif *arvif;
+	struct wmi_bcn_tx_arg arg;
+	struct sk_buff *bcn;
+	int vdev_id = 0;
+	int ret;
+
+	ath10k_dbg(ATH10K_DBG_MGMT, "WMI_HOST_SWBA_EVENTID\n");
+
+	ev = (struct wmi_host_swba_event *)skb->data;
+	map = __le32_to_cpu(ev->vdev_map);
+
+	ath10k_dbg(ATH10K_DBG_MGMT, "host swba:\n"
+		   "-vdev map 0x%x\n",
+		   ev->vdev_map);
+
+	for (; map; map >>= 1, vdev_id++) {
+		if (!(map & 0x1))
+			continue;
+
+		i++;
+
+		if (i >= WMI_MAX_AP_VDEV) {
+			ath10k_warn("swba has corrupted vdev map\n");
+			break;
+		}
+
+		bcn_info = &ev->bcn_info[i];
+
+		ath10k_dbg(ATH10K_DBG_MGMT,
+			   "-bcn_info[%d]:\n"
+			   "--tim_len %d\n"
+			   "--tim_mcast %d\n"
+			   "--tim_changed %d\n"
+			   "--tim_num_ps_pending %d\n"
+			   "--tim_bitmap 0x%08x%08x%08x%08x\n",
+			   i,
+			   __le32_to_cpu(bcn_info->tim_info.tim_len),
+			   __le32_to_cpu(bcn_info->tim_info.tim_mcast),
+			   __le32_to_cpu(bcn_info->tim_info.tim_changed),
+			   __le32_to_cpu(bcn_info->tim_info.tim_num_ps_pending),
+			   __le32_to_cpu(bcn_info->tim_info.tim_bitmap[3]),
+			   __le32_to_cpu(bcn_info->tim_info.tim_bitmap[2]),
+			   __le32_to_cpu(bcn_info->tim_info.tim_bitmap[1]),
+			   __le32_to_cpu(bcn_info->tim_info.tim_bitmap[0]));
+
+		arvif = ath10k_get_arvif(ar, vdev_id);
+		if (arvif == NULL) {
+			ath10k_warn("no vif for vdev_id %d found\n", vdev_id);
+			continue;
+		}
+
+		bcn = ieee80211_beacon_get(ar->hw, arvif->vif);
+		if (!bcn) {
+			ath10k_warn("could not get mac80211 beacon\n");
+			continue;
+		}
+
+		ath10k_tx_h_seq_no(bcn);
+		ath10k_wmi_update_tim(ar, arvif, bcn, bcn_info);
+		ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info);
+
+		arg.vdev_id = arvif->vdev_id;
+		arg.tx_rate = 0;
+		arg.tx_power = 0;
+		arg.bcn = bcn->data;
+		arg.bcn_len = bcn->len;
+
+		ret = ath10k_wmi_beacon_send(ar, &arg);
+		if (ret)
+			ath10k_warn("could not send beacon (%d)\n", ret);
+
+		dev_kfree_skb_any(bcn);
+	}
+}
+
+static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar,
+					       struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n");
+}
+
+static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_PHYERR_EVENTID\n");
+}
+
+static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n");
+}
+
+static void ath10k_wmi_event_profile_match(struct ath10k *ar,
+				    struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n");
+}
+
+static void ath10k_wmi_event_debug_print(struct ath10k *ar,
+				  struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_PRINT_EVENTID\n");
+}
+
+static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n");
+}
+
+static void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar,
+					       struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n");
+}
+
+static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar,
+					     struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n");
+}
+
+static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar,
+					     struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n");
+}
+
+static void ath10k_wmi_event_rtt_error_report(struct ath10k *ar,
+					      struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n");
+}
+
+static void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar,
+					     struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n");
+}
+
+static void ath10k_wmi_event_dcs_interference(struct ath10k *ar,
+					      struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n");
+}
+
+static void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar,
+					     struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n");
+}
+
+static void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar,
+					   struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n");
+}
+
+static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar,
+					 struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n");
+}
+
+static void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar,
+					    struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n");
+}
+
+static void ath10k_wmi_event_delba_complete(struct ath10k *ar,
+					    struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n");
+}
+
+static void ath10k_wmi_event_addba_complete(struct ath10k *ar,
+					    struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n");
+}
+
+static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar,
+						struct sk_buff *skb)
+{
+	ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n");
+}
+
+static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
+					      struct sk_buff *skb)
+{
+	struct wmi_service_ready_event *ev = (void *)skb->data;
+
+	if (skb->len < sizeof(*ev)) {
+		ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n",
+			    skb->len, sizeof(*ev));
+		return;
+	}
+
+	ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power);
+	ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power);
+	ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info);
+	ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info);
+	ar->fw_version_major =
+		(__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24;
+	ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff);
+	ar->fw_version_release =
+		(__le32_to_cpu(ev->sw_version_1) & 0xffff0000) >> 16;
+	ar->fw_version_build = (__le32_to_cpu(ev->sw_version_1) & 0x0000ffff);
+	ar->phy_capability = __le32_to_cpu(ev->phy_capability);
+
+	ar->ath_common.regulatory.current_rd =
+		__le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd);
+
+	ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap,
+				      sizeof(ev->wmi_service_bitmap));
+
+	if (strlen(ar->hw->wiphy->fw_version) == 0) {
+		snprintf(ar->hw->wiphy->fw_version,
+			 sizeof(ar->hw->wiphy->fw_version),
+			 "%u.%u.%u.%u",
+			 ar->fw_version_major,
+			 ar->fw_version_minor,
+			 ar->fw_version_release,
+			 ar->fw_version_build);
+	}
+
+	/* FIXME: it probably should be better to support this */
+	if (__le32_to_cpu(ev->num_mem_reqs) > 0) {
+		ath10k_warn("target requested %d memory chunks; ignoring\n",
+			    __le32_to_cpu(ev->num_mem_reqs));
+	}
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi event service ready sw_ver 0x%08x sw_ver1 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u\n",
+		   __le32_to_cpu(ev->sw_version),
+		   __le32_to_cpu(ev->sw_version_1),
+		   __le32_to_cpu(ev->abi_version),
+		   __le32_to_cpu(ev->phy_capability),
+		   __le32_to_cpu(ev->ht_cap_info),
+		   __le32_to_cpu(ev->vht_cap_info),
+		   __le32_to_cpu(ev->vht_supp_mcs),
+		   __le32_to_cpu(ev->sys_cap_info),
+		   __le32_to_cpu(ev->num_mem_reqs));
+
+	complete(&ar->wmi.service_ready);
+}
+
+static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct wmi_ready_event *ev = (struct wmi_ready_event *)skb->data;
+
+	if (WARN_ON(skb->len < sizeof(*ev)))
+		return -EINVAL;
+
+	memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d\n",
+		   __le32_to_cpu(ev->sw_version),
+		   __le32_to_cpu(ev->abi_version),
+		   ev->mac_addr.addr,
+		   __le32_to_cpu(ev->status));
+
+	complete(&ar->wmi.unified_ready);
+	return 0;
+}
+
+static void ath10k_wmi_event_process(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct wmi_cmd_hdr *cmd_hdr;
+	enum wmi_event_id id;
+	u16 len;
+
+	cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
+	id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
+
+	if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
+		return;
+
+	len = skb->len;
+
+	trace_ath10k_wmi_event(id, skb->data, skb->len);
+
+	switch (id) {
+	case WMI_MGMT_RX_EVENTID:
+		ath10k_wmi_event_mgmt_rx(ar, skb);
+		/* mgmt_rx() owns the skb now! */
+		return;
+	case WMI_SCAN_EVENTID:
+		ath10k_wmi_event_scan(ar, skb);
+		break;
+	case WMI_CHAN_INFO_EVENTID:
+		ath10k_wmi_event_chan_info(ar, skb);
+		break;
+	case WMI_ECHO_EVENTID:
+		ath10k_wmi_event_echo(ar, skb);
+		break;
+	case WMI_DEBUG_MESG_EVENTID:
+		ath10k_wmi_event_debug_mesg(ar, skb);
+		break;
+	case WMI_UPDATE_STATS_EVENTID:
+		ath10k_wmi_event_update_stats(ar, skb);
+		break;
+	case WMI_VDEV_START_RESP_EVENTID:
+		ath10k_wmi_event_vdev_start_resp(ar, skb);
+		break;
+	case WMI_VDEV_STOPPED_EVENTID:
+		ath10k_wmi_event_vdev_stopped(ar, skb);
+		break;
+	case WMI_PEER_STA_KICKOUT_EVENTID:
+		ath10k_wmi_event_peer_sta_kickout(ar, skb);
+		break;
+	case WMI_HOST_SWBA_EVENTID:
+		ath10k_wmi_event_host_swba(ar, skb);
+		break;
+	case WMI_TBTTOFFSET_UPDATE_EVENTID:
+		ath10k_wmi_event_tbttoffset_update(ar, skb);
+		break;
+	case WMI_PHYERR_EVENTID:
+		ath10k_wmi_event_phyerr(ar, skb);
+		break;
+	case WMI_ROAM_EVENTID:
+		ath10k_wmi_event_roam(ar, skb);
+		break;
+	case WMI_PROFILE_MATCH:
+		ath10k_wmi_event_profile_match(ar, skb);
+		break;
+	case WMI_DEBUG_PRINT_EVENTID:
+		ath10k_wmi_event_debug_print(ar, skb);
+		break;
+	case WMI_PDEV_QVIT_EVENTID:
+		ath10k_wmi_event_pdev_qvit(ar, skb);
+		break;
+	case WMI_WLAN_PROFILE_DATA_EVENTID:
+		ath10k_wmi_event_wlan_profile_data(ar, skb);
+		break;
+	case WMI_RTT_MEASUREMENT_REPORT_EVENTID:
+		ath10k_wmi_event_rtt_measurement_report(ar, skb);
+		break;
+	case WMI_TSF_MEASUREMENT_REPORT_EVENTID:
+		ath10k_wmi_event_tsf_measurement_report(ar, skb);
+		break;
+	case WMI_RTT_ERROR_REPORT_EVENTID:
+		ath10k_wmi_event_rtt_error_report(ar, skb);
+		break;
+	case WMI_WOW_WAKEUP_HOST_EVENTID:
+		ath10k_wmi_event_wow_wakeup_host(ar, skb);
+		break;
+	case WMI_DCS_INTERFERENCE_EVENTID:
+		ath10k_wmi_event_dcs_interference(ar, skb);
+		break;
+	case WMI_PDEV_TPC_CONFIG_EVENTID:
+		ath10k_wmi_event_pdev_tpc_config(ar, skb);
+		break;
+	case WMI_PDEV_FTM_INTG_EVENTID:
+		ath10k_wmi_event_pdev_ftm_intg(ar, skb);
+		break;
+	case WMI_GTK_OFFLOAD_STATUS_EVENTID:
+		ath10k_wmi_event_gtk_offload_status(ar, skb);
+		break;
+	case WMI_GTK_REKEY_FAIL_EVENTID:
+		ath10k_wmi_event_gtk_rekey_fail(ar, skb);
+		break;
+	case WMI_TX_DELBA_COMPLETE_EVENTID:
+		ath10k_wmi_event_delba_complete(ar, skb);
+		break;
+	case WMI_TX_ADDBA_COMPLETE_EVENTID:
+		ath10k_wmi_event_addba_complete(ar, skb);
+		break;
+	case WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID:
+		ath10k_wmi_event_vdev_install_key_complete(ar, skb);
+		break;
+	case WMI_SERVICE_READY_EVENTID:
+		ath10k_wmi_service_ready_event_rx(ar, skb);
+		break;
+	case WMI_READY_EVENTID:
+		ath10k_wmi_ready_event_rx(ar, skb);
+		break;
+	default:
+		ath10k_warn("Unknown eventid: %d\n", id);
+		break;
+	}
+
+	dev_kfree_skb(skb);
+}
+
+static void ath10k_wmi_event_work(struct work_struct *work)
+{
+	struct ath10k *ar = container_of(work, struct ath10k,
+					 wmi.wmi_event_work);
+	struct sk_buff *skb;
+
+	for (;;) {
+		skb = skb_dequeue(&ar->wmi.wmi_event_list);
+		if (!skb)
+			break;
+
+		ath10k_wmi_event_process(ar, skb);
+	}
+}
+
+static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb)
+{
+	struct wmi_cmd_hdr *cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
+	enum wmi_event_id event_id;
+
+	event_id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
+
+	/* some events require to be handled ASAP
+	 * thus can't be defered to a worker thread */
+	switch (event_id) {
+	case WMI_HOST_SWBA_EVENTID:
+	case WMI_MGMT_RX_EVENTID:
+		ath10k_wmi_event_process(ar, skb);
+		return;
+	default:
+		break;
+	}
+
+	skb_queue_tail(&ar->wmi.wmi_event_list, skb);
+	queue_work(ar->workqueue, &ar->wmi.wmi_event_work);
+}
+
+/* WMI Initialization functions */
+int ath10k_wmi_attach(struct ath10k *ar)
+{
+	init_completion(&ar->wmi.service_ready);
+	init_completion(&ar->wmi.unified_ready);
+	init_waitqueue_head(&ar->wmi.wq);
+
+	skb_queue_head_init(&ar->wmi.wmi_event_list);
+	INIT_WORK(&ar->wmi.wmi_event_work, ath10k_wmi_event_work);
+
+	return 0;
+}
+
+void ath10k_wmi_detach(struct ath10k *ar)
+{
+	/* HTC should've drained the packets already */
+	if (WARN_ON(atomic_read(&ar->wmi.pending_tx_count) > 0))
+		ath10k_warn("there are still pending packets\n");
+
+	cancel_work_sync(&ar->wmi.wmi_event_work);
+	skb_queue_purge(&ar->wmi.wmi_event_list);
+}
+
+int ath10k_wmi_connect_htc_service(struct ath10k *ar)
+{
+	int status;
+	struct ath10k_htc_svc_conn_req conn_req;
+	struct ath10k_htc_svc_conn_resp conn_resp;
+
+	memset(&conn_req, 0, sizeof(conn_req));
+	memset(&conn_resp, 0, sizeof(conn_resp));
+
+	/* these fields are the same for all service endpoints */
+	conn_req.ep_ops.ep_tx_complete = ath10k_wmi_htc_tx_complete;
+	conn_req.ep_ops.ep_rx_complete = ath10k_wmi_process_rx;
+
+	/* connect to control service */
+	conn_req.service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL;
+
+	status = ath10k_htc_connect_service(ar->htc, &conn_req, &conn_resp);
+	if (status) {
+		ath10k_warn("failed to connect to WMI CONTROL service status: %d\n",
+			    status);
+		return status;
+	}
+
+	ar->wmi.eid = conn_resp.eid;
+	return 0;
+}
+
+int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
+				  u16 rd5g, u16 ctl2g, u16 ctl5g)
+{
+	struct wmi_pdev_set_regdomain_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data;
+	cmd->reg_domain = __cpu_to_le32(rd);
+	cmd->reg_domain_2G = __cpu_to_le32(rd2g);
+	cmd->reg_domain_5G = __cpu_to_le32(rd5g);
+	cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g);
+	cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n",
+		   rd, rd2g, rd5g, ctl2g, ctl5g);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_REGDOMAIN_CMDID);
+}
+
+int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
+				const struct wmi_channel_arg *arg)
+{
+	struct wmi_set_channel_cmd *cmd;
+	struct sk_buff *skb;
+
+	if (arg->passive)
+		return -EINVAL;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_set_channel_cmd *)skb->data;
+	cmd->chan.mhz               = __cpu_to_le32(arg->freq);
+	cmd->chan.band_center_freq1 = __cpu_to_le32(arg->freq);
+	cmd->chan.mode              = arg->mode;
+	cmd->chan.min_power         = arg->min_power;
+	cmd->chan.max_power         = arg->max_power;
+	cmd->chan.reg_power         = arg->max_reg_power;
+	cmd->chan.reg_classid       = arg->reg_class_id;
+	cmd->chan.antenna_max       = arg->max_antenna_gain;
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi set channel mode %d freq %d\n",
+		   arg->mode, arg->freq);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_CHANNEL_CMDID);
+}
+
+int ath10k_wmi_pdev_suspend_target(struct ath10k *ar)
+{
+	struct wmi_pdev_suspend_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_pdev_suspend_cmd *)skb->data;
+	cmd->suspend_opt = WMI_PDEV_SUSPEND;
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SUSPEND_CMDID);
+}
+
+int ath10k_wmi_pdev_resume_target(struct ath10k *ar)
+{
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(0);
+	if (skb == NULL)
+		return -ENOMEM;
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_RESUME_CMDID);
+}
+
+int ath10k_wmi_pdev_set_param(struct ath10k *ar, enum wmi_pdev_param id,
+			      u32 value)
+{
+	struct wmi_pdev_set_param_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_pdev_set_param_cmd *)skb->data;
+	cmd->param_id    = __cpu_to_le32(id);
+	cmd->param_value = __cpu_to_le32(value);
+
+	ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n",
+		   id, value);
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_PARAM_CMDID);
+}
+
+int ath10k_wmi_cmd_init(struct ath10k *ar)
+{
+	struct wmi_init_cmd *cmd;
+	struct sk_buff *buf;
+	struct wmi_resource_config config = {};
+	u32 val;
+
+	config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS);
+	config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS + TARGET_NUM_VDEVS);
+	config.num_offload_peers = __cpu_to_le32(TARGET_NUM_OFFLOAD_PEERS);
+
+	config.num_offload_reorder_bufs =
+		__cpu_to_le32(TARGET_NUM_OFFLOAD_REORDER_BUFS);
+
+	config.num_peer_keys = __cpu_to_le32(TARGET_NUM_PEER_KEYS);
+	config.num_tids = __cpu_to_le32(TARGET_NUM_TIDS);
+	config.ast_skid_limit = __cpu_to_le32(TARGET_AST_SKID_LIMIT);
+	config.tx_chain_mask = __cpu_to_le32(TARGET_TX_CHAIN_MASK);
+	config.rx_chain_mask = __cpu_to_le32(TARGET_RX_CHAIN_MASK);
+	config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
+	config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
+	config.rx_timeout_pri_be = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
+	config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_RX_TIMEOUT_HI_PRI);
+	config.rx_decap_mode = __cpu_to_le32(TARGET_RX_DECAP_MODE);
+
+	config.scan_max_pending_reqs =
+		__cpu_to_le32(TARGET_SCAN_MAX_PENDING_REQS);
+
+	config.bmiss_offload_max_vdev =
+		__cpu_to_le32(TARGET_BMISS_OFFLOAD_MAX_VDEV);
+
+	config.roam_offload_max_vdev =
+		__cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_VDEV);
+
+	config.roam_offload_max_ap_profiles =
+		__cpu_to_le32(TARGET_ROAM_OFFLOAD_MAX_AP_PROFILES);
+
+	config.num_mcast_groups = __cpu_to_le32(TARGET_NUM_MCAST_GROUPS);
+	config.num_mcast_table_elems =
+		__cpu_to_le32(TARGET_NUM_MCAST_TABLE_ELEMS);
+
+	config.mcast2ucast_mode = __cpu_to_le32(TARGET_MCAST2UCAST_MODE);
+	config.tx_dbg_log_size = __cpu_to_le32(TARGET_TX_DBG_LOG_SIZE);
+	config.num_wds_entries = __cpu_to_le32(TARGET_NUM_WDS_ENTRIES);
+	config.dma_burst_size = __cpu_to_le32(TARGET_DMA_BURST_SIZE);
+	config.mac_aggr_delim = __cpu_to_le32(TARGET_MAC_AGGR_DELIM);
+
+	val = TARGET_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK;
+	config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val);
+
+	config.vow_config = __cpu_to_le32(TARGET_VOW_CONFIG);
+
+	config.gtk_offload_max_vdev =
+		__cpu_to_le32(TARGET_GTK_OFFLOAD_MAX_VDEV);
+
+	config.num_msdu_desc = __cpu_to_le32(TARGET_NUM_MSDU_DESC);
+	config.max_frag_entries = __cpu_to_le32(TARGET_MAX_FRAG_ENTRIES);
+
+	buf = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!buf)
+		return -ENOMEM;
+
+	cmd = (struct wmi_init_cmd *)buf->data;
+	cmd->num_host_mem_chunks = 0;
+	memcpy(&cmd->resource_config, &config, sizeof(config));
+
+	ath10k_dbg(ATH10K_DBG_WMI, "wmi init\n");
+	return ath10k_wmi_cmd_send(ar, buf, WMI_INIT_CMDID);
+}
+
+static int ath10k_wmi_start_scan_calc_len(const struct wmi_start_scan_arg *arg)
+{
+	int len;
+
+	len = sizeof(struct wmi_start_scan_cmd);
+
+	if (arg->ie_len) {
+		if (!arg->ie)
+			return -EINVAL;
+		if (arg->ie_len > WLAN_SCAN_PARAMS_MAX_IE_LEN)
+			return -EINVAL;
+
+		len += sizeof(struct wmi_ie_data);
+		len += roundup(arg->ie_len, 4);
+	}
+
+	if (arg->n_channels) {
+		if (!arg->channels)
+			return -EINVAL;
+		if (arg->n_channels > ARRAY_SIZE(arg->channels))
+			return -EINVAL;
+
+		len += sizeof(struct wmi_chan_list);
+		len += sizeof(__le32) * arg->n_channels;
+	}
+
+	if (arg->n_ssids) {
+		if (!arg->ssids)
+			return -EINVAL;
+		if (arg->n_ssids > WLAN_SCAN_PARAMS_MAX_SSID)
+			return -EINVAL;
+
+		len += sizeof(struct wmi_ssid_list);
+		len += sizeof(struct wmi_ssid) * arg->n_ssids;
+	}
+
+	if (arg->n_bssids) {
+		if (!arg->bssids)
+			return -EINVAL;
+		if (arg->n_bssids > WLAN_SCAN_PARAMS_MAX_BSSID)
+			return -EINVAL;
+
+		len += sizeof(struct wmi_bssid_list);
+		len += sizeof(struct wmi_mac_addr) * arg->n_bssids;
+	}
+
+	return len;
+}
+
+int ath10k_wmi_start_scan(struct ath10k *ar,
+			  const struct wmi_start_scan_arg *arg)
+{
+	struct wmi_start_scan_cmd *cmd;
+	struct sk_buff *skb;
+	struct wmi_ie_data *ie;
+	struct wmi_chan_list *channels;
+	struct wmi_ssid_list *ssids;
+	struct wmi_bssid_list *bssids;
+	u32 scan_id;
+	u32 scan_req_id;
+	int off;
+	int len = 0;
+	int i;
+
+	len = ath10k_wmi_start_scan_calc_len(arg);
+	if (len < 0)
+		return len; /* len contains error code here */
+
+	skb = ath10k_wmi_alloc_skb(len);
+	if (!skb)
+		return -ENOMEM;
+
+	scan_id  = WMI_HOST_SCAN_REQ_ID_PREFIX;
+	scan_id |= arg->scan_id;
+
+	scan_req_id  = WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
+	scan_req_id |= arg->scan_req_id;
+
+	cmd = (struct wmi_start_scan_cmd *)skb->data;
+	cmd->scan_id            = __cpu_to_le32(scan_id);
+	cmd->scan_req_id        = __cpu_to_le32(scan_req_id);
+	cmd->vdev_id            = __cpu_to_le32(arg->vdev_id);
+	cmd->scan_priority      = __cpu_to_le32(arg->scan_priority);
+	cmd->notify_scan_events = __cpu_to_le32(arg->notify_scan_events);
+	cmd->dwell_time_active  = __cpu_to_le32(arg->dwell_time_active);
+	cmd->dwell_time_passive = __cpu_to_le32(arg->dwell_time_passive);
+	cmd->min_rest_time      = __cpu_to_le32(arg->min_rest_time);
+	cmd->max_rest_time      = __cpu_to_le32(arg->max_rest_time);
+	cmd->repeat_probe_time  = __cpu_to_le32(arg->repeat_probe_time);
+	cmd->probe_spacing_time = __cpu_to_le32(arg->probe_spacing_time);
+	cmd->idle_time          = __cpu_to_le32(arg->idle_time);
+	cmd->max_scan_time      = __cpu_to_le32(arg->max_scan_time);
+	cmd->probe_delay        = __cpu_to_le32(arg->probe_delay);
+	cmd->scan_ctrl_flags    = __cpu_to_le32(arg->scan_ctrl_flags);
+
+	/* TLV list starts after fields included in the struct */
+	off = sizeof(*cmd);
+
+	if (arg->n_channels) {
+		channels = (void *)skb->data + off;
+		channels->tag = __cpu_to_le32(WMI_CHAN_LIST_TAG);
+		channels->num_chan = __cpu_to_le32(arg->n_channels);
+
+		for (i = 0; i < arg->n_channels; i++)
+			channels->channel_list[i] =
+				__cpu_to_le32(arg->channels[i]);
+
+		off += sizeof(*channels);
+		off += sizeof(__le32) * arg->n_channels;
+	}
+
+	if (arg->n_ssids) {
+		ssids = (void *)skb->data + off;
+		ssids->tag = __cpu_to_le32(WMI_SSID_LIST_TAG);
+		ssids->num_ssids = __cpu_to_le32(arg->n_ssids);
+
+		for (i = 0; i < arg->n_ssids; i++) {
+			ssids->ssids[i].ssid_len =
+				__cpu_to_le32(arg->ssids[i].len);
+			memcpy(&ssids->ssids[i].ssid,
+			       arg->ssids[i].ssid,
+			       arg->ssids[i].len);
+		}
+
+		off += sizeof(*ssids);
+		off += sizeof(struct wmi_ssid) * arg->n_ssids;
+	}
+
+	if (arg->n_bssids) {
+		bssids = (void *)skb->data + off;
+		bssids->tag = __cpu_to_le32(WMI_BSSID_LIST_TAG);
+		bssids->num_bssid = __cpu_to_le32(arg->n_bssids);
+
+		for (i = 0; i < arg->n_bssids; i++)
+			memcpy(&bssids->bssid_list[i],
+			       arg->bssids[i].bssid,
+			       ETH_ALEN);
+
+		off += sizeof(*bssids);
+		off += sizeof(struct wmi_mac_addr) * arg->n_bssids;
+	}
+
+	if (arg->ie_len) {
+		ie = (void *)skb->data + off;
+		ie->tag = __cpu_to_le32(WMI_IE_TAG);
+		ie->ie_len = __cpu_to_le32(arg->ie_len);
+		memcpy(ie->ie_data, arg->ie, arg->ie_len);
+
+		off += sizeof(*ie);
+		off += roundup(arg->ie_len, 4);
+	}
+
+	if (off != skb->len) {
+		dev_kfree_skb(skb);
+		return -EINVAL;
+	}
+
+	ath10k_dbg(ATH10K_DBG_WMI, "wmi start scan\n");
+	return ath10k_wmi_cmd_send(ar, skb, WMI_START_SCAN_CMDID);
+}
+
+void ath10k_wmi_start_scan_init(struct ath10k *ar,
+				struct wmi_start_scan_arg *arg)
+{
+	/* setup commonly used values */
+	arg->scan_req_id = 1;
+	arg->scan_priority = WMI_SCAN_PRIORITY_LOW;
+	arg->dwell_time_active = 50;
+	arg->dwell_time_passive = 150;
+	arg->min_rest_time = 50;
+	arg->max_rest_time = 500;
+	arg->repeat_probe_time = 0;
+	arg->probe_spacing_time = 0;
+	arg->idle_time = 0;
+	arg->max_scan_time = 5000;
+	arg->probe_delay = 5;
+	arg->notify_scan_events = WMI_SCAN_EVENT_STARTED
+		| WMI_SCAN_EVENT_COMPLETED
+		| WMI_SCAN_EVENT_BSS_CHANNEL
+		| WMI_SCAN_EVENT_FOREIGN_CHANNEL
+		| WMI_SCAN_EVENT_DEQUEUED;
+	arg->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES;
+	arg->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT;
+	arg->n_bssids = 1;
+	arg->bssids[0].bssid = "\xFF\xFF\xFF\xFF\xFF\xFF";
+}
+
+int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg)
+{
+	struct wmi_stop_scan_cmd *cmd;
+	struct sk_buff *skb;
+	u32 scan_id;
+	u32 req_id;
+
+	if (arg->req_id > 0xFFF)
+		return -EINVAL;
+	if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
+		return -EINVAL;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	scan_id = arg->u.scan_id;
+	scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
+
+	req_id = arg->req_id;
+	req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
+
+	cmd = (struct wmi_stop_scan_cmd *)skb->data;
+	cmd->req_type    = __cpu_to_le32(arg->req_type);
+	cmd->vdev_id     = __cpu_to_le32(arg->u.vdev_id);
+	cmd->scan_id     = __cpu_to_le32(scan_id);
+	cmd->scan_req_id = __cpu_to_le32(req_id);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n",
+		   arg->req_id, arg->req_type, arg->u.scan_id);
+	return ath10k_wmi_cmd_send(ar, skb, WMI_STOP_SCAN_CMDID);
+}
+
+int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
+			   enum wmi_vdev_type type,
+			   enum wmi_vdev_subtype subtype,
+			   const u8 macaddr[ETH_ALEN])
+{
+	struct wmi_vdev_create_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_vdev_create_cmd *)skb->data;
+	cmd->vdev_id      = __cpu_to_le32(vdev_id);
+	cmd->vdev_type    = __cpu_to_le32(type);
+	cmd->vdev_subtype = __cpu_to_le32(subtype);
+	memcpy(cmd->vdev_macaddr.addr, macaddr, ETH_ALEN);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "WMI vdev create: id %d type %d subtype %d macaddr %pM\n",
+		   vdev_id, type, subtype, macaddr);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_CREATE_CMDID);
+}
+
+int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id)
+{
+	struct wmi_vdev_delete_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_vdev_delete_cmd *)skb->data;
+	cmd->vdev_id = __cpu_to_le32(vdev_id);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "WMI vdev delete id %d\n", vdev_id);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_DELETE_CMDID);
+}
+
+static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
+				const struct wmi_vdev_start_request_arg *arg,
+				enum wmi_cmd_id cmd_id)
+{
+	struct wmi_vdev_start_request_cmd *cmd;
+	struct sk_buff *skb;
+	const char *cmdname;
+	u32 flags = 0;
+
+	if (cmd_id != WMI_VDEV_START_REQUEST_CMDID &&
+	    cmd_id != WMI_VDEV_RESTART_REQUEST_CMDID)
+		return -EINVAL;
+	if (WARN_ON(arg->ssid && arg->ssid_len == 0))
+		return -EINVAL;
+	if (WARN_ON(arg->hidden_ssid && !arg->ssid))
+		return -EINVAL;
+	if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
+		return -EINVAL;
+
+	if (cmd_id == WMI_VDEV_START_REQUEST_CMDID)
+		cmdname = "start";
+	else if (cmd_id == WMI_VDEV_RESTART_REQUEST_CMDID)
+		cmdname = "restart";
+	else
+		return -EINVAL; /* should not happen, we already check cmd_id */
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	if (arg->hidden_ssid)
+		flags |= WMI_VDEV_START_HIDDEN_SSID;
+	if (arg->pmf_enabled)
+		flags |= WMI_VDEV_START_PMF_ENABLED;
+
+	cmd = (struct wmi_vdev_start_request_cmd *)skb->data;
+	cmd->vdev_id         = __cpu_to_le32(arg->vdev_id);
+	cmd->disable_hw_ack  = __cpu_to_le32(arg->disable_hw_ack);
+	cmd->beacon_interval = __cpu_to_le32(arg->bcn_intval);
+	cmd->dtim_period     = __cpu_to_le32(arg->dtim_period);
+	cmd->flags           = __cpu_to_le32(flags);
+	cmd->bcn_tx_rate     = __cpu_to_le32(arg->bcn_tx_rate);
+	cmd->bcn_tx_power    = __cpu_to_le32(arg->bcn_tx_power);
+
+	if (arg->ssid) {
+		cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len);
+		memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
+	}
+
+	cmd->chan.mhz = __cpu_to_le32(arg->channel.freq);
+
+	cmd->chan.band_center_freq1 =
+		__cpu_to_le32(arg->channel.band_center_freq1);
+
+	cmd->chan.mode = arg->channel.mode;
+	cmd->chan.min_power = arg->channel.min_power;
+	cmd->chan.max_power = arg->channel.max_power;
+	cmd->chan.reg_power = arg->channel.max_reg_power;
+	cmd->chan.reg_classid = arg->channel.reg_class_id;
+	cmd->chan.antenna_max = arg->channel.max_antenna_gain;
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi vdev %s id 0x%x freq %d, mode %d, ch_flags: 0x%0X,"
+		   "max_power: %d\n", cmdname, arg->vdev_id, arg->channel.freq,
+		   arg->channel.mode, flags, arg->channel.max_power);
+
+	return ath10k_wmi_cmd_send(ar, skb, cmd_id);
+}
+
+int ath10k_wmi_vdev_start(struct ath10k *ar,
+			  const struct wmi_vdev_start_request_arg *arg)
+{
+	return ath10k_wmi_vdev_start_restart(ar, arg,
+					     WMI_VDEV_START_REQUEST_CMDID);
+}
+
+int ath10k_wmi_vdev_restart(struct ath10k *ar,
+		     const struct wmi_vdev_start_request_arg *arg)
+{
+	return ath10k_wmi_vdev_start_restart(ar, arg,
+					     WMI_VDEV_RESTART_REQUEST_CMDID);
+}
+
+int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id)
+{
+	struct wmi_vdev_stop_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_vdev_stop_cmd *)skb->data;
+	cmd->vdev_id = __cpu_to_le32(vdev_id);
+
+	ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_STOP_CMDID);
+}
+
+int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
+{
+	struct wmi_vdev_up_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_vdev_up_cmd *)skb->data;
+	cmd->vdev_id       = __cpu_to_le32(vdev_id);
+	cmd->vdev_assoc_id = __cpu_to_le32(aid);
+	memcpy(&cmd->vdev_bssid.addr, bssid, 6);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n",
+		   vdev_id, aid, bssid);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_UP_CMDID);
+}
+
+int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id)
+{
+	struct wmi_vdev_down_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_vdev_down_cmd *)skb->data;
+	cmd->vdev_id = __cpu_to_le32(vdev_id);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi mgmt vdev down id 0x%x\n", vdev_id);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_DOWN_CMDID);
+}
+
+int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id,
+			      enum wmi_vdev_param param_id, u32 param_value)
+{
+	struct wmi_vdev_set_param_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_vdev_set_param_cmd *)skb->data;
+	cmd->vdev_id     = __cpu_to_le32(vdev_id);
+	cmd->param_id    = __cpu_to_le32(param_id);
+	cmd->param_value = __cpu_to_le32(param_value);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi vdev id 0x%x set param %d value %d\n",
+		   vdev_id, param_id, param_value);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_SET_PARAM_CMDID);
+}
+
+int ath10k_wmi_vdev_install_key(struct ath10k *ar,
+				const struct wmi_vdev_install_key_arg *arg)
+{
+	struct wmi_vdev_install_key_cmd *cmd;
+	struct sk_buff *skb;
+
+	if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL)
+		return -EINVAL;
+	if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL)
+		return -EINVAL;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->key_len);
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_vdev_install_key_cmd *)skb->data;
+	cmd->vdev_id       = __cpu_to_le32(arg->vdev_id);
+	cmd->key_idx       = __cpu_to_le32(arg->key_idx);
+	cmd->key_flags     = __cpu_to_le32(arg->key_flags);
+	cmd->key_cipher    = __cpu_to_le32(arg->key_cipher);
+	cmd->key_len       = __cpu_to_le32(arg->key_len);
+	cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len);
+	cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
+
+	if (arg->macaddr)
+		memcpy(cmd->peer_macaddr.addr, arg->macaddr, ETH_ALEN);
+	if (arg->key_data)
+		memcpy(cmd->key_data, arg->key_data, arg->key_len);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_INSTALL_KEY_CMDID);
+}
+
+int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
+			   const u8 peer_addr[ETH_ALEN])
+{
+	struct wmi_peer_create_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_peer_create_cmd *)skb->data;
+	cmd->vdev_id = __cpu_to_le32(vdev_id);
+	memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi peer create vdev_id %d peer_addr %pM\n",
+		   vdev_id, peer_addr);
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_CREATE_CMDID);
+}
+
+int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
+			   const u8 peer_addr[ETH_ALEN])
+{
+	struct wmi_peer_delete_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_peer_delete_cmd *)skb->data;
+	cmd->vdev_id = __cpu_to_le32(vdev_id);
+	memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi peer delete vdev_id %d peer_addr %pM\n",
+		   vdev_id, peer_addr);
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_DELETE_CMDID);
+}
+
+int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
+			  const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
+{
+	struct wmi_peer_flush_tids_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_peer_flush_tids_cmd *)skb->data;
+	cmd->vdev_id         = __cpu_to_le32(vdev_id);
+	cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
+	memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n",
+		   vdev_id, peer_addr, tid_bitmap);
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_FLUSH_TIDS_CMDID);
+}
+
+int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id,
+			      const u8 *peer_addr, enum wmi_peer_param param_id,
+			      u32 param_value)
+{
+	struct wmi_peer_set_param_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_peer_set_param_cmd *)skb->data;
+	cmd->vdev_id     = __cpu_to_le32(vdev_id);
+	cmd->param_id    = __cpu_to_le32(param_id);
+	cmd->param_value = __cpu_to_le32(param_value);
+	memcpy(&cmd->peer_macaddr.addr, peer_addr, 6);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi vdev %d peer 0x%pM set param %d value %d\n",
+		   vdev_id, peer_addr, param_id, param_value);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_SET_PARAM_CMDID);
+}
+
+int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id,
+			  enum wmi_sta_ps_mode psmode)
+{
+	struct wmi_sta_powersave_mode_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_sta_powersave_mode_cmd *)skb->data;
+	cmd->vdev_id     = __cpu_to_le32(vdev_id);
+	cmd->sta_ps_mode = __cpu_to_le32(psmode);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi set powersave id 0x%x mode %d\n",
+		   vdev_id, psmode);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_STA_POWERSAVE_MODE_CMDID);
+}
+
+int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id,
+				enum wmi_sta_powersave_param param_id,
+				u32 value)
+{
+	struct wmi_sta_powersave_param_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_sta_powersave_param_cmd *)skb->data;
+	cmd->vdev_id     = __cpu_to_le32(vdev_id);
+	cmd->param_id    = __cpu_to_le32(param_id);
+	cmd->param_value = __cpu_to_le32(value);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi sta ps param vdev_id 0x%x param %d value %d\n",
+		   vdev_id, param_id, value);
+	return ath10k_wmi_cmd_send(ar, skb, WMI_STA_POWERSAVE_PARAM_CMDID);
+}
+
+int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
+			       enum wmi_ap_ps_peer_param param_id, u32 value)
+{
+	struct wmi_ap_ps_peer_cmd *cmd;
+	struct sk_buff *skb;
+
+	if (!mac)
+		return -EINVAL;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_ap_ps_peer_cmd *)skb->data;
+	cmd->vdev_id = __cpu_to_le32(vdev_id);
+	cmd->param_id = __cpu_to_le32(param_id);
+	cmd->param_value = __cpu_to_le32(value);
+	memcpy(&cmd->peer_macaddr, mac, ETH_ALEN);
+
+	ath10k_dbg(ATH10K_DBG_WMI,
+		   "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n",
+		   vdev_id, param_id, value, mac);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_AP_PS_PEER_PARAM_CMDID);
+}
+
+int ath10k_wmi_scan_chan_list(struct ath10k *ar,
+			      const struct wmi_scan_chan_list_arg *arg)
+{
+	struct wmi_scan_chan_list_cmd *cmd;
+	struct sk_buff *skb;
+	struct wmi_channel_arg *ch;
+	struct wmi_channel *ci;
+	int len;
+	int i;
+
+	len = sizeof(*cmd) + arg->n_channels * sizeof(struct wmi_channel);
+
+	skb = ath10k_wmi_alloc_skb(len);
+	if (!skb)
+		return -EINVAL;
+
+	cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
+	cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
+
+	for (i = 0; i < arg->n_channels; i++) {
+		u32 flags = 0;
+
+		ch = &arg->channels[i];
+		ci = &cmd->chan_info[i];
+
+		if (ch->passive)
+			flags |= WMI_CHAN_FLAG_PASSIVE;
+		if (ch->allow_ibss)
+			flags |= WMI_CHAN_FLAG_ADHOC_ALLOWED;
+		if (ch->allow_ht)
+			flags |= WMI_CHAN_FLAG_ALLOW_HT;
+		if (ch->allow_vht)
+			flags |= WMI_CHAN_FLAG_ALLOW_VHT;
+		if (ch->ht40plus)
+			flags |= WMI_CHAN_FLAG_HT40_PLUS;
+
+		ci->mhz               = __cpu_to_le32(ch->freq);
+		ci->band_center_freq1 = __cpu_to_le32(ch->freq);
+		ci->band_center_freq2 = 0;
+		ci->min_power         = ch->min_power;
+		ci->max_power         = ch->max_power;
+		ci->reg_power         = ch->max_reg_power;
+		ci->antenna_max       = ch->max_antenna_gain;
+		ci->antenna_max       = 0;
+
+		/* mode & flags share storage */
+		ci->mode              = ch->mode;
+		ci->flags            |= __cpu_to_le32(flags);
+	}
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_SCAN_CHAN_LIST_CMDID);
+}
+
+int ath10k_wmi_peer_assoc(struct ath10k *ar,
+			  const struct wmi_peer_assoc_complete_arg *arg)
+{
+	struct wmi_peer_assoc_complete_cmd *cmd;
+	struct sk_buff *skb;
+
+	if (arg->peer_mpdu_density > 16)
+		return -EINVAL;
+	if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
+		return -EINVAL;
+	if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
+		return -EINVAL;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_peer_assoc_complete_cmd *)skb->data;
+	cmd->vdev_id            = __cpu_to_le32(arg->vdev_id);
+	cmd->peer_new_assoc     = __cpu_to_le32(arg->peer_reassoc ? 0 : 1);
+	cmd->peer_associd       = __cpu_to_le32(arg->peer_aid);
+	cmd->peer_flags         = __cpu_to_le32(arg->peer_flags);
+	cmd->peer_caps          = __cpu_to_le32(arg->peer_caps);
+	cmd->peer_listen_intval = __cpu_to_le32(arg->peer_listen_intval);
+	cmd->peer_ht_caps       = __cpu_to_le32(arg->peer_ht_caps);
+	cmd->peer_max_mpdu      = __cpu_to_le32(arg->peer_max_mpdu);
+	cmd->peer_mpdu_density  = __cpu_to_le32(arg->peer_mpdu_density);
+	cmd->peer_rate_caps     = __cpu_to_le32(arg->peer_rate_caps);
+	cmd->peer_nss           = __cpu_to_le32(arg->peer_num_spatial_streams);
+	cmd->peer_vht_caps      = __cpu_to_le32(arg->peer_vht_caps);
+	cmd->peer_phymode       = __cpu_to_le32(arg->peer_phymode);
+
+	memcpy(cmd->peer_macaddr.addr, arg->addr, ETH_ALEN);
+
+	cmd->peer_legacy_rates.num_rates =
+		__cpu_to_le32(arg->peer_legacy_rates.num_rates);
+	memcpy(cmd->peer_legacy_rates.rates, arg->peer_legacy_rates.rates,
+	       arg->peer_legacy_rates.num_rates);
+
+	cmd->peer_ht_rates.num_rates =
+		__cpu_to_le32(arg->peer_ht_rates.num_rates);
+	memcpy(cmd->peer_ht_rates.rates, arg->peer_ht_rates.rates,
+	       arg->peer_ht_rates.num_rates);
+
+	cmd->peer_vht_rates.rx_max_rate =
+		__cpu_to_le32(arg->peer_vht_rates.rx_max_rate);
+	cmd->peer_vht_rates.rx_mcs_set =
+		__cpu_to_le32(arg->peer_vht_rates.rx_mcs_set);
+	cmd->peer_vht_rates.tx_max_rate =
+		__cpu_to_le32(arg->peer_vht_rates.tx_max_rate);
+	cmd->peer_vht_rates.tx_mcs_set =
+		__cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_ASSOC_CMDID);
+}
+
+int ath10k_wmi_beacon_send(struct ath10k *ar, const struct wmi_bcn_tx_arg *arg)
+{
+	struct wmi_bcn_tx_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->bcn_len);
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_bcn_tx_cmd *)skb->data;
+	cmd->hdr.vdev_id  = __cpu_to_le32(arg->vdev_id);
+	cmd->hdr.tx_rate  = __cpu_to_le32(arg->tx_rate);
+	cmd->hdr.tx_power = __cpu_to_le32(arg->tx_power);
+	cmd->hdr.bcn_len  = __cpu_to_le32(arg->bcn_len);
+	memcpy(cmd->bcn, arg->bcn, arg->bcn_len);
+
+	return ath10k_wmi_cmd_send(ar, skb, WMI_BCN_TX_CMDID);
+}
+
+static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params,
+					  const struct wmi_wmm_params_arg *arg)
+{
+	params->cwmin  = __cpu_to_le32(arg->cwmin);
+	params->cwmax  = __cpu_to_le32(arg->cwmax);
+	params->aifs   = __cpu_to_le32(arg->aifs);
+	params->txop   = __cpu_to_le32(arg->txop);
+	params->acm    = __cpu_to_le32(arg->acm);
+	params->no_ack = __cpu_to_le32(arg->no_ack);
+}
+
+int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
+			const struct wmi_pdev_set_wmm_params_arg *arg)
+{
+	struct wmi_pdev_set_wmm_params *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_pdev_set_wmm_params *)skb->data;
+	ath10k_wmi_pdev_set_wmm_param(&cmd->ac_be, &arg->ac_be);
+	ath10k_wmi_pdev_set_wmm_param(&cmd->ac_bk, &arg->ac_bk);
+	ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vi, &arg->ac_vi);
+	ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo);
+
+	ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set wmm params\n");
+	return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_WMM_PARAMS_CMDID);
+}
+
+int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
+{
+	struct wmi_request_stats_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_request_stats_cmd *)skb->data;
+	cmd->stats_id = __cpu_to_le32(stats_id);
+
+	ath10k_dbg(ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id);
+	return ath10k_wmi_cmd_send(ar, skb, WMI_REQUEST_STATS_CMDID);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/wmi.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/wmi.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath10k/wmi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath10k/wmi.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3052 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _WMI_H_
+#define _WMI_H_
+
+#include <linux/types.h>
+#include <net/mac80211.h>
+
+/*
+ * This file specifies the WMI interface for the Unified Software
+ * Architecture.
+ *
+ * It includes definitions of all the commands and events. Commands are
+ * messages from the host to the target. Events and Replies are messages
+ * from the target to the host.
+ *
+ * Ownership of correctness in regards to WMI commands belongs to the host
+ * driver and the target is not required to validate parameters for value,
+ * proper range, or any other checking.
+ *
+ * Guidelines for extending this interface are below.
+ *
+ * 1. Add new WMI commands ONLY within the specified range - 0x9000 - 0x9fff
+ *
+ * 2. Use ONLY u32 type for defining member variables within WMI
+ *    command/event structures. Do not use u8, u16, bool or
+ *    enum types within these structures.
+ *
+ * 3. DO NOT define bit fields within structures. Implement bit fields
+ *    using masks if necessary. Do not use the programming language's bit
+ *    field definition.
+ *
+ * 4. Define macros for encode/decode of u8, u16 fields within
+ *    the u32 variables. Use these macros for set/get of these fields.
+ *    Try to use this to optimize the structure without bloating it with
+ *    u32 variables for every lower sized field.
+ *
+ * 5. Do not use PACK/UNPACK attributes for the structures as each member
+ *    variable is already 4-byte aligned by virtue of being a u32
+ *    type.
+ *
+ * 6. Comment each parameter part of the WMI command/event structure by
+ *    using the 2 stars at the begining of C comment instead of one star to
+ *    enable HTML document generation using Doxygen.
+ *
+ */
+
+/* Control Path */
+struct wmi_cmd_hdr {
+	__le32 cmd_id;
+} __packed;
+
+#define WMI_CMD_HDR_CMD_ID_MASK   0x00FFFFFF
+#define WMI_CMD_HDR_CMD_ID_LSB    0
+#define WMI_CMD_HDR_PLT_PRIV_MASK 0xFF000000
+#define WMI_CMD_HDR_PLT_PRIV_LSB  24
+
+#define HTC_PROTOCOL_VERSION    0x0002
+#define WMI_PROTOCOL_VERSION    0x0002
+
+enum wmi_service_id {
+	WMI_SERVICE_BEACON_OFFLOAD = 0,   /* beacon offload */
+	WMI_SERVICE_SCAN_OFFLOAD,	  /* scan offload */
+	WMI_SERVICE_ROAM_OFFLOAD,	  /* roam offload */
+	WMI_SERVICE_BCN_MISS_OFFLOAD,     /* beacon miss offload */
+	WMI_SERVICE_STA_PWRSAVE,	  /* fake sleep + basic power save */
+	WMI_SERVICE_STA_ADVANCED_PWRSAVE, /* uapsd, pspoll, force sleep */
+	WMI_SERVICE_AP_UAPSD,		  /* uapsd on AP */
+	WMI_SERVICE_AP_DFS,		  /* DFS on AP */
+	WMI_SERVICE_11AC,		  /* supports 11ac */
+	WMI_SERVICE_BLOCKACK,	/* Supports triggering ADDBA/DELBA from host*/
+	WMI_SERVICE_PHYERR,		  /* PHY error */
+	WMI_SERVICE_BCN_FILTER,		  /* Beacon filter support */
+	WMI_SERVICE_RTT,		  /* RTT (round trip time) support */
+	WMI_SERVICE_RATECTRL,		  /* Rate-control */
+	WMI_SERVICE_WOW,		  /* WOW Support */
+	WMI_SERVICE_RATECTRL_CACHE,       /* Rate-control caching */
+	WMI_SERVICE_IRAM_TIDS,            /* TIDs in IRAM */
+	WMI_SERVICE_ARPNS_OFFLOAD,	  /* ARP NS Offload support */
+	WMI_SERVICE_NLO,		  /* Network list offload service */
+	WMI_SERVICE_GTK_OFFLOAD,	  /* GTK offload */
+	WMI_SERVICE_SCAN_SCH,		  /* Scan Scheduler Service */
+	WMI_SERVICE_CSA_OFFLOAD,	  /* CSA offload service */
+	WMI_SERVICE_CHATTER,		  /* Chatter service */
+	WMI_SERVICE_COEX_FREQAVOID,	  /* FW report freq range to avoid */
+	WMI_SERVICE_PACKET_POWER_SAVE,	  /* packet power save service */
+	WMI_SERVICE_FORCE_FW_HANG,        /* To test fw recovery mechanism */
+	WMI_SERVICE_GPIO,                 /* GPIO service */
+	WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, /* Modulated DTIM support */
+	WMI_STA_UAPSD_BASIC_AUTO_TRIG,    /* UAPSD AC Trigger Generation  */
+	WMI_STA_UAPSD_VAR_AUTO_TRIG,      /* -do- */
+	WMI_SERVICE_STA_KEEP_ALIVE,       /* STA keep alive mechanism support */
+	WMI_SERVICE_TX_ENCAP,             /* Packet type for TX encapsulation */
+
+	WMI_SERVICE_LAST,
+	WMI_MAX_SERVICE = 64		  /* max service */
+};
+
+static inline char *wmi_service_name(int service_id)
+{
+	switch (service_id) {
+	case WMI_SERVICE_BEACON_OFFLOAD:
+		return "BEACON_OFFLOAD";
+	case WMI_SERVICE_SCAN_OFFLOAD:
+		return "SCAN_OFFLOAD";
+	case WMI_SERVICE_ROAM_OFFLOAD:
+		return "ROAM_OFFLOAD";
+	case WMI_SERVICE_BCN_MISS_OFFLOAD:
+		return "BCN_MISS_OFFLOAD";
+	case WMI_SERVICE_STA_PWRSAVE:
+		return "STA_PWRSAVE";
+	case WMI_SERVICE_STA_ADVANCED_PWRSAVE:
+		return "STA_ADVANCED_PWRSAVE";
+	case WMI_SERVICE_AP_UAPSD:
+		return "AP_UAPSD";
+	case WMI_SERVICE_AP_DFS:
+		return "AP_DFS";
+	case WMI_SERVICE_11AC:
+		return "11AC";
+	case WMI_SERVICE_BLOCKACK:
+		return "BLOCKACK";
+	case WMI_SERVICE_PHYERR:
+		return "PHYERR";
+	case WMI_SERVICE_BCN_FILTER:
+		return "BCN_FILTER";
+	case WMI_SERVICE_RTT:
+		return "RTT";
+	case WMI_SERVICE_RATECTRL:
+		return "RATECTRL";
+	case WMI_SERVICE_WOW:
+		return "WOW";
+	case WMI_SERVICE_RATECTRL_CACHE:
+		return "RATECTRL CACHE";
+	case WMI_SERVICE_IRAM_TIDS:
+		return "IRAM TIDS";
+	case WMI_SERVICE_ARPNS_OFFLOAD:
+		return "ARPNS_OFFLOAD";
+	case WMI_SERVICE_NLO:
+		return "NLO";
+	case WMI_SERVICE_GTK_OFFLOAD:
+		return "GTK_OFFLOAD";
+	case WMI_SERVICE_SCAN_SCH:
+		return "SCAN_SCH";
+	case WMI_SERVICE_CSA_OFFLOAD:
+		return "CSA_OFFLOAD";
+	case WMI_SERVICE_CHATTER:
+		return "CHATTER";
+	case WMI_SERVICE_COEX_FREQAVOID:
+		return "COEX_FREQAVOID";
+	case WMI_SERVICE_PACKET_POWER_SAVE:
+		return "PACKET_POWER_SAVE";
+	case WMI_SERVICE_FORCE_FW_HANG:
+		return "FORCE FW HANG";
+	case WMI_SERVICE_GPIO:
+		return "GPIO";
+	case WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM:
+		return "MODULATED DTIM";
+	case WMI_STA_UAPSD_BASIC_AUTO_TRIG:
+		return "BASIC UAPSD";
+	case WMI_STA_UAPSD_VAR_AUTO_TRIG:
+		return "VAR UAPSD";
+	case WMI_SERVICE_STA_KEEP_ALIVE:
+		return "STA KEEP ALIVE";
+	case WMI_SERVICE_TX_ENCAP:
+		return "TX ENCAP";
+	default:
+		return "UNKNOWN SERVICE\n";
+	}
+}
+
+
+#define WMI_SERVICE_BM_SIZE \
+	((WMI_MAX_SERVICE + sizeof(u32) - 1)/sizeof(u32))
+
+/* 2 word representation of MAC addr */
+struct wmi_mac_addr {
+	union {
+		u8 addr[6];
+		struct {
+			u32 word0;
+			u32 word1;
+		} __packed;
+	} __packed;
+} __packed;
+
+/* macro to convert MAC address from WMI word format to char array */
+#define WMI_MAC_ADDR_TO_CHAR_ARRAY(pwmi_mac_addr, c_macaddr) do { \
+	(c_macaddr)[0] =  ((pwmi_mac_addr)->word0) & 0xff; \
+	(c_macaddr)[1] = (((pwmi_mac_addr)->word0) >> 8) & 0xff; \
+	(c_macaddr)[2] = (((pwmi_mac_addr)->word0) >> 16) & 0xff; \
+	(c_macaddr)[3] = (((pwmi_mac_addr)->word0) >> 24) & 0xff; \
+	(c_macaddr)[4] =  ((pwmi_mac_addr)->word1) & 0xff; \
+	(c_macaddr)[5] = (((pwmi_mac_addr)->word1) >> 8) & 0xff; \
+	} while (0)
+
+/*
+ * wmi command groups.
+ */
+enum wmi_cmd_group {
+	/* 0 to 2 are reserved */
+	WMI_GRP_START = 0x3,
+	WMI_GRP_SCAN = WMI_GRP_START,
+	WMI_GRP_PDEV,
+	WMI_GRP_VDEV,
+	WMI_GRP_PEER,
+	WMI_GRP_MGMT,
+	WMI_GRP_BA_NEG,
+	WMI_GRP_STA_PS,
+	WMI_GRP_DFS,
+	WMI_GRP_ROAM,
+	WMI_GRP_OFL_SCAN,
+	WMI_GRP_P2P,
+	WMI_GRP_AP_PS,
+	WMI_GRP_RATE_CTRL,
+	WMI_GRP_PROFILE,
+	WMI_GRP_SUSPEND,
+	WMI_GRP_BCN_FILTER,
+	WMI_GRP_WOW,
+	WMI_GRP_RTT,
+	WMI_GRP_SPECTRAL,
+	WMI_GRP_STATS,
+	WMI_GRP_ARP_NS_OFL,
+	WMI_GRP_NLO_OFL,
+	WMI_GRP_GTK_OFL,
+	WMI_GRP_CSA_OFL,
+	WMI_GRP_CHATTER,
+	WMI_GRP_TID_ADDBA,
+	WMI_GRP_MISC,
+	WMI_GRP_GPIO,
+};
+
+#define WMI_CMD_GRP(grp_id) (((grp_id) << 12) | 0x1)
+#define WMI_EVT_GRP_START_ID(grp_id) (((grp_id) << 12) | 0x1)
+
+/* Command IDs and commande events. */
+enum wmi_cmd_id {
+	WMI_INIT_CMDID = 0x1,
+
+	/* Scan specific commands */
+	WMI_START_SCAN_CMDID = WMI_CMD_GRP(WMI_GRP_SCAN),
+	WMI_STOP_SCAN_CMDID,
+	WMI_SCAN_CHAN_LIST_CMDID,
+	WMI_SCAN_SCH_PRIO_TBL_CMDID,
+
+	/* PDEV (physical device) specific commands */
+	WMI_PDEV_SET_REGDOMAIN_CMDID = WMI_CMD_GRP(WMI_GRP_PDEV),
+	WMI_PDEV_SET_CHANNEL_CMDID,
+	WMI_PDEV_SET_PARAM_CMDID,
+	WMI_PDEV_PKTLOG_ENABLE_CMDID,
+	WMI_PDEV_PKTLOG_DISABLE_CMDID,
+	WMI_PDEV_SET_WMM_PARAMS_CMDID,
+	WMI_PDEV_SET_HT_CAP_IE_CMDID,
+	WMI_PDEV_SET_VHT_CAP_IE_CMDID,
+	WMI_PDEV_SET_DSCP_TID_MAP_CMDID,
+	WMI_PDEV_SET_QUIET_MODE_CMDID,
+	WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID,
+	WMI_PDEV_GET_TPC_CONFIG_CMDID,
+	WMI_PDEV_SET_BASE_MACADDR_CMDID,
+
+	/* VDEV (virtual device) specific commands */
+	WMI_VDEV_CREATE_CMDID = WMI_CMD_GRP(WMI_GRP_VDEV),
+	WMI_VDEV_DELETE_CMDID,
+	WMI_VDEV_START_REQUEST_CMDID,
+	WMI_VDEV_RESTART_REQUEST_CMDID,
+	WMI_VDEV_UP_CMDID,
+	WMI_VDEV_STOP_CMDID,
+	WMI_VDEV_DOWN_CMDID,
+	WMI_VDEV_SET_PARAM_CMDID,
+	WMI_VDEV_INSTALL_KEY_CMDID,
+
+	/* peer specific commands */
+	WMI_PEER_CREATE_CMDID = WMI_CMD_GRP(WMI_GRP_PEER),
+	WMI_PEER_DELETE_CMDID,
+	WMI_PEER_FLUSH_TIDS_CMDID,
+	WMI_PEER_SET_PARAM_CMDID,
+	WMI_PEER_ASSOC_CMDID,
+	WMI_PEER_ADD_WDS_ENTRY_CMDID,
+	WMI_PEER_REMOVE_WDS_ENTRY_CMDID,
+	WMI_PEER_MCAST_GROUP_CMDID,
+
+	/* beacon/management specific commands */
+	WMI_BCN_TX_CMDID = WMI_CMD_GRP(WMI_GRP_MGMT),
+	WMI_PDEV_SEND_BCN_CMDID,
+	WMI_BCN_TMPL_CMDID,
+	WMI_BCN_FILTER_RX_CMDID,
+	WMI_PRB_REQ_FILTER_RX_CMDID,
+	WMI_MGMT_TX_CMDID,
+	WMI_PRB_TMPL_CMDID,
+
+	/* commands to directly control BA negotiation directly from host. */
+	WMI_ADDBA_CLEAR_RESP_CMDID = WMI_CMD_GRP(WMI_GRP_BA_NEG),
+	WMI_ADDBA_SEND_CMDID,
+	WMI_ADDBA_STATUS_CMDID,
+	WMI_DELBA_SEND_CMDID,
+	WMI_ADDBA_SET_RESP_CMDID,
+	WMI_SEND_SINGLEAMSDU_CMDID,
+
+	/* Station power save specific config */
+	WMI_STA_POWERSAVE_MODE_CMDID = WMI_CMD_GRP(WMI_GRP_STA_PS),
+	WMI_STA_POWERSAVE_PARAM_CMDID,
+	WMI_STA_MIMO_PS_MODE_CMDID,
+
+	/** DFS-specific commands */
+	WMI_PDEV_DFS_ENABLE_CMDID = WMI_CMD_GRP(WMI_GRP_DFS),
+	WMI_PDEV_DFS_DISABLE_CMDID,
+
+	/* Roaming specific  commands */
+	WMI_ROAM_SCAN_MODE = WMI_CMD_GRP(WMI_GRP_ROAM),
+	WMI_ROAM_SCAN_RSSI_THRESHOLD,
+	WMI_ROAM_SCAN_PERIOD,
+	WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
+	WMI_ROAM_AP_PROFILE,
+
+	/* offload scan specific commands */
+	WMI_OFL_SCAN_ADD_AP_PROFILE = WMI_CMD_GRP(WMI_GRP_OFL_SCAN),
+	WMI_OFL_SCAN_REMOVE_AP_PROFILE,
+	WMI_OFL_SCAN_PERIOD,
+
+	/* P2P specific commands */
+	WMI_P2P_DEV_SET_DEVICE_INFO = WMI_CMD_GRP(WMI_GRP_P2P),
+	WMI_P2P_DEV_SET_DISCOVERABILITY,
+	WMI_P2P_GO_SET_BEACON_IE,
+	WMI_P2P_GO_SET_PROBE_RESP_IE,
+	WMI_P2P_SET_VENDOR_IE_DATA_CMDID,
+
+	/* AP power save specific config */
+	WMI_AP_PS_PEER_PARAM_CMDID = WMI_CMD_GRP(WMI_GRP_AP_PS),
+	WMI_AP_PS_PEER_UAPSD_COEX_CMDID,
+
+	/* Rate-control specific commands */
+	WMI_PEER_RATE_RETRY_SCHED_CMDID =
+	WMI_CMD_GRP(WMI_GRP_RATE_CTRL),
+
+	/* WLAN Profiling commands. */
+	WMI_WLAN_PROFILE_TRIGGER_CMDID = WMI_CMD_GRP(WMI_GRP_PROFILE),
+	WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
+	WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
+	WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
+	WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
+
+	/* Suspend resume command Ids */
+	WMI_PDEV_SUSPEND_CMDID = WMI_CMD_GRP(WMI_GRP_SUSPEND),
+	WMI_PDEV_RESUME_CMDID,
+
+	/* Beacon filter commands */
+	WMI_ADD_BCN_FILTER_CMDID = WMI_CMD_GRP(WMI_GRP_BCN_FILTER),
+	WMI_RMV_BCN_FILTER_CMDID,
+
+	/* WOW Specific WMI commands*/
+	WMI_WOW_ADD_WAKE_PATTERN_CMDID = WMI_CMD_GRP(WMI_GRP_WOW),
+	WMI_WOW_DEL_WAKE_PATTERN_CMDID,
+	WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
+	WMI_WOW_ENABLE_CMDID,
+	WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
+
+	/* RTT measurement related cmd */
+	WMI_RTT_MEASREQ_CMDID = WMI_CMD_GRP(WMI_GRP_RTT),
+	WMI_RTT_TSF_CMDID,
+
+	/* spectral scan commands */
+	WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID = WMI_CMD_GRP(WMI_GRP_SPECTRAL),
+	WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID,
+
+	/* F/W stats */
+	WMI_REQUEST_STATS_CMDID = WMI_CMD_GRP(WMI_GRP_STATS),
+
+	/* ARP OFFLOAD REQUEST*/
+	WMI_SET_ARP_NS_OFFLOAD_CMDID = WMI_CMD_GRP(WMI_GRP_ARP_NS_OFL),
+
+	/* NS offload confid*/
+	WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID = WMI_CMD_GRP(WMI_GRP_NLO_OFL),
+
+	/* GTK offload Specific WMI commands*/
+	WMI_GTK_OFFLOAD_CMDID = WMI_CMD_GRP(WMI_GRP_GTK_OFL),
+
+	/* CSA offload Specific WMI commands*/
+	WMI_CSA_OFFLOAD_ENABLE_CMDID = WMI_CMD_GRP(WMI_GRP_CSA_OFL),
+	WMI_CSA_OFFLOAD_CHANSWITCH_CMDID,
+
+	/* Chatter commands*/
+	WMI_CHATTER_SET_MODE_CMDID = WMI_CMD_GRP(WMI_GRP_CHATTER),
+
+	/* addba specific commands */
+	WMI_PEER_TID_ADDBA_CMDID = WMI_CMD_GRP(WMI_GRP_TID_ADDBA),
+	WMI_PEER_TID_DELBA_CMDID,
+
+	/* set station mimo powersave method */
+	WMI_STA_DTIM_PS_METHOD_CMDID,
+	/* Configure the Station UAPSD AC Auto Trigger Parameters */
+	WMI_STA_UAPSD_AUTO_TRIG_CMDID,
+
+	/* STA Keep alive parameter configuration,
+	   Requires WMI_SERVICE_STA_KEEP_ALIVE */
+	WMI_STA_KEEPALIVE_CMD,
+
+	/* misc command group */
+	WMI_ECHO_CMDID = WMI_CMD_GRP(WMI_GRP_MISC),
+	WMI_PDEV_UTF_CMDID,
+	WMI_DBGLOG_CFG_CMDID,
+	WMI_PDEV_QVIT_CMDID,
+	WMI_PDEV_FTM_INTG_CMDID,
+	WMI_VDEV_SET_KEEPALIVE_CMDID,
+	WMI_VDEV_GET_KEEPALIVE_CMDID,
+
+	/* GPIO Configuration */
+	WMI_GPIO_CONFIG_CMDID = WMI_CMD_GRP(WMI_GRP_GPIO),
+	WMI_GPIO_OUTPUT_CMDID,
+};
+
+enum wmi_event_id {
+	WMI_SERVICE_READY_EVENTID = 0x1,
+	WMI_READY_EVENTID,
+
+	/* Scan specific events */
+	WMI_SCAN_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_SCAN),
+
+	/* PDEV specific events */
+	WMI_PDEV_TPC_CONFIG_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_PDEV),
+	WMI_CHAN_INFO_EVENTID,
+	WMI_PHYERR_EVENTID,
+
+	/* VDEV specific events */
+	WMI_VDEV_START_RESP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_VDEV),
+	WMI_VDEV_STOPPED_EVENTID,
+	WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID,
+
+	/* peer specific events */
+	WMI_PEER_STA_KICKOUT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_PEER),
+
+	/* beacon/mgmt specific events */
+	WMI_MGMT_RX_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_MGMT),
+	WMI_HOST_SWBA_EVENTID,
+	WMI_TBTTOFFSET_UPDATE_EVENTID,
+
+	/* ADDBA Related WMI Events*/
+	WMI_TX_DELBA_COMPLETE_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_BA_NEG),
+	WMI_TX_ADDBA_COMPLETE_EVENTID,
+
+	/* Roam event to trigger roaming on host */
+	WMI_ROAM_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_ROAM),
+	WMI_PROFILE_MATCH,
+
+	/* WoW */
+	WMI_WOW_WAKEUP_HOST_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_WOW),
+
+	/* RTT */
+	WMI_RTT_MEASUREMENT_REPORT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_RTT),
+	WMI_TSF_MEASUREMENT_REPORT_EVENTID,
+	WMI_RTT_ERROR_REPORT_EVENTID,
+
+	/* GTK offload */
+	WMI_GTK_OFFLOAD_STATUS_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_GTK_OFL),
+	WMI_GTK_REKEY_FAIL_EVENTID,
+
+	/* CSA IE received event */
+	WMI_CSA_HANDLING_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_CSA_OFL),
+
+	/* Misc events */
+	WMI_ECHO_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_MISC),
+	WMI_PDEV_UTF_EVENTID,
+	WMI_DEBUG_MESG_EVENTID,
+	WMI_UPDATE_STATS_EVENTID,
+	WMI_DEBUG_PRINT_EVENTID,
+	WMI_DCS_INTERFERENCE_EVENTID,
+	WMI_PDEV_QVIT_EVENTID,
+	WMI_WLAN_PROFILE_DATA_EVENTID,
+	WMI_PDEV_FTM_INTG_EVENTID,
+	WMI_WLAN_FREQ_AVOID_EVENTID,
+	WMI_VDEV_GET_KEEPALIVE_EVENTID,
+
+	/* GPIO Event */
+	WMI_GPIO_INPUT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_GPIO),
+};
+
+enum wmi_phy_mode {
+	MODE_11A        = 0,   /* 11a Mode */
+	MODE_11G        = 1,   /* 11b/g Mode */
+	MODE_11B        = 2,   /* 11b Mode */
+	MODE_11GONLY    = 3,   /* 11g only Mode */
+	MODE_11NA_HT20   = 4,  /* 11a HT20 mode */
+	MODE_11NG_HT20   = 5,  /* 11g HT20 mode */
+	MODE_11NA_HT40   = 6,  /* 11a HT40 mode */
+	MODE_11NG_HT40   = 7,  /* 11g HT40 mode */
+	MODE_11AC_VHT20 = 8,
+	MODE_11AC_VHT40 = 9,
+	MODE_11AC_VHT80 = 10,
+	/*    MODE_11AC_VHT160 = 11, */
+	MODE_11AC_VHT20_2G = 11,
+	MODE_11AC_VHT40_2G = 12,
+	MODE_11AC_VHT80_2G = 13,
+	MODE_UNKNOWN    = 14,
+	MODE_MAX        = 14
+};
+
+#define WMI_CHAN_LIST_TAG	0x1
+#define WMI_SSID_LIST_TAG	0x2
+#define WMI_BSSID_LIST_TAG	0x3
+#define WMI_IE_TAG		0x4
+
+struct wmi_channel {
+	__le32 mhz;
+	__le32 band_center_freq1;
+	__le32 band_center_freq2; /* valid for 11ac, 80plus80 */
+	union {
+		__le32 flags; /* WMI_CHAN_FLAG_ */
+		struct {
+			u8 mode; /* only 6 LSBs */
+		} __packed;
+	} __packed;
+	union {
+		__le32 reginfo0;
+		struct {
+			u8 min_power;
+			u8 max_power;
+			u8 reg_power;
+			u8 reg_classid;
+		} __packed;
+	} __packed;
+	union {
+		__le32 reginfo1;
+		struct {
+			u8 antenna_max;
+		} __packed;
+	} __packed;
+} __packed;
+
+struct wmi_channel_arg {
+	u32 freq;
+	u32 band_center_freq1;
+	bool passive;
+	bool allow_ibss;
+	bool allow_ht;
+	bool allow_vht;
+	bool ht40plus;
+	/* note: power unit is 1/4th of dBm */
+	u32 min_power;
+	u32 max_power;
+	u32 max_reg_power;
+	u32 max_antenna_gain;
+	u32 reg_class_id;
+	enum wmi_phy_mode mode;
+};
+
+enum wmi_channel_change_cause {
+	WMI_CHANNEL_CHANGE_CAUSE_NONE = 0,
+	WMI_CHANNEL_CHANGE_CAUSE_CSA,
+};
+
+#define WMI_CHAN_FLAG_HT40_PLUS      (1 << 6)
+#define WMI_CHAN_FLAG_PASSIVE        (1 << 7)
+#define WMI_CHAN_FLAG_ADHOC_ALLOWED  (1 << 8)
+#define WMI_CHAN_FLAG_AP_DISABLED    (1 << 9)
+#define WMI_CHAN_FLAG_DFS            (1 << 10)
+#define WMI_CHAN_FLAG_ALLOW_HT       (1 << 11)
+#define WMI_CHAN_FLAG_ALLOW_VHT      (1 << 12)
+
+/* Indicate reason for channel switch */
+#define WMI_CHANNEL_CHANGE_CAUSE_CSA (1 << 13)
+
+#define WMI_MAX_SPATIAL_STREAM   3
+
+/* HT Capabilities*/
+#define WMI_HT_CAP_ENABLED                0x0001   /* HT Enabled/ disabled */
+#define WMI_HT_CAP_HT20_SGI       0x0002   /* Short Guard Interval with HT20 */
+#define WMI_HT_CAP_DYNAMIC_SMPS           0x0004   /* Dynamic MIMO powersave */
+#define WMI_HT_CAP_TX_STBC                0x0008   /* B3 TX STBC */
+#define WMI_HT_CAP_TX_STBC_MASK_SHIFT     3
+#define WMI_HT_CAP_RX_STBC                0x0030   /* B4-B5 RX STBC */
+#define WMI_HT_CAP_RX_STBC_MASK_SHIFT     4
+#define WMI_HT_CAP_LDPC                   0x0040   /* LDPC supported */
+#define WMI_HT_CAP_L_SIG_TXOP_PROT        0x0080   /* L-SIG TXOP Protection */
+#define WMI_HT_CAP_MPDU_DENSITY           0x0700   /* MPDU Density */
+#define WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 8
+#define WMI_HT_CAP_HT40_SGI               0x0800
+
+#define WMI_HT_CAP_DEFAULT_ALL (WMI_HT_CAP_ENABLED       | \
+				WMI_HT_CAP_HT20_SGI      | \
+				WMI_HT_CAP_HT40_SGI      | \
+				WMI_HT_CAP_TX_STBC       | \
+				WMI_HT_CAP_RX_STBC       | \
+				WMI_HT_CAP_LDPC)
+
+
+/*
+ * WMI_VHT_CAP_* these maps to ieee 802.11ac vht capability information
+ * field. The fields not defined here are not supported, or reserved.
+ * Do not change these masks and if you have to add new one follow the
+ * bitmask as specified by 802.11ac draft.
+ */
+
+#define WMI_VHT_CAP_MAX_MPDU_LEN_MASK            0x00000003
+#define WMI_VHT_CAP_RX_LDPC                      0x00000010
+#define WMI_VHT_CAP_SGI_80MHZ                    0x00000020
+#define WMI_VHT_CAP_TX_STBC                      0x00000080
+#define WMI_VHT_CAP_RX_STBC_MASK                 0x00000300
+#define WMI_VHT_CAP_RX_STBC_MASK_SHIFT           8
+#define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP            0x03800000
+#define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT      23
+#define WMI_VHT_CAP_RX_FIXED_ANT                 0x10000000
+#define WMI_VHT_CAP_TX_FIXED_ANT                 0x20000000
+
+/* The following also refer for max HT AMSDU */
+#define WMI_VHT_CAP_MAX_MPDU_LEN_3839            0x00000000
+#define WMI_VHT_CAP_MAX_MPDU_LEN_7935            0x00000001
+#define WMI_VHT_CAP_MAX_MPDU_LEN_11454           0x00000002
+
+#define WMI_VHT_CAP_DEFAULT_ALL (WMI_VHT_CAP_MAX_MPDU_LEN_11454  | \
+				 WMI_VHT_CAP_RX_LDPC             | \
+				 WMI_VHT_CAP_SGI_80MHZ           | \
+				 WMI_VHT_CAP_TX_STBC             | \
+				 WMI_VHT_CAP_RX_STBC_MASK        | \
+				 WMI_VHT_CAP_MAX_AMPDU_LEN_EXP   | \
+				 WMI_VHT_CAP_RX_FIXED_ANT        | \
+				 WMI_VHT_CAP_TX_FIXED_ANT)
+
+/*
+ * Interested readers refer to Rx/Tx MCS Map definition as defined in
+ * 802.11ac
+ */
+#define WMI_VHT_MAX_MCS_4_SS_MASK(r, ss)      ((3 & (r)) << (((ss) - 1) << 1))
+#define WMI_VHT_MAX_SUPP_RATE_MASK           0x1fff0000
+#define WMI_VHT_MAX_SUPP_RATE_MASK_SHIFT     16
+
+enum {
+	REGDMN_MODE_11A              = 0x00001, /* 11a channels */
+	REGDMN_MODE_TURBO            = 0x00002, /* 11a turbo-only channels */
+	REGDMN_MODE_11B              = 0x00004, /* 11b channels */
+	REGDMN_MODE_PUREG            = 0x00008, /* 11g channels (OFDM only) */
+	REGDMN_MODE_11G              = 0x00008, /* XXX historical */
+	REGDMN_MODE_108G             = 0x00020, /* 11a+Turbo channels */
+	REGDMN_MODE_108A             = 0x00040, /* 11g+Turbo channels */
+	REGDMN_MODE_XR               = 0x00100, /* XR channels */
+	REGDMN_MODE_11A_HALF_RATE    = 0x00200, /* 11A half rate channels */
+	REGDMN_MODE_11A_QUARTER_RATE = 0x00400, /* 11A quarter rate channels */
+	REGDMN_MODE_11NG_HT20        = 0x00800, /* 11N-G HT20 channels */
+	REGDMN_MODE_11NA_HT20        = 0x01000, /* 11N-A HT20 channels */
+	REGDMN_MODE_11NG_HT40PLUS    = 0x02000, /* 11N-G HT40 + channels */
+	REGDMN_MODE_11NG_HT40MINUS   = 0x04000, /* 11N-G HT40 - channels */
+	REGDMN_MODE_11NA_HT40PLUS    = 0x08000, /* 11N-A HT40 + channels */
+	REGDMN_MODE_11NA_HT40MINUS   = 0x10000, /* 11N-A HT40 - channels */
+	REGDMN_MODE_11AC_VHT20       = 0x20000, /* 5Ghz, VHT20 */
+	REGDMN_MODE_11AC_VHT40PLUS   = 0x40000, /* 5Ghz, VHT40 + channels */
+	REGDMN_MODE_11AC_VHT40MINUS  = 0x80000, /* 5Ghz  VHT40 - channels */
+	REGDMN_MODE_11AC_VHT80       = 0x100000, /* 5Ghz, VHT80 channels */
+	REGDMN_MODE_ALL              = 0xffffffff
+};
+
+#define REGDMN_CAP1_CHAN_HALF_RATE        0x00000001
+#define REGDMN_CAP1_CHAN_QUARTER_RATE     0x00000002
+#define REGDMN_CAP1_CHAN_HAL49GHZ         0x00000004
+
+/* regulatory capabilities */
+#define REGDMN_EEPROM_EEREGCAP_EN_FCC_MIDBAND   0x0040
+#define REGDMN_EEPROM_EEREGCAP_EN_KK_U1_EVEN    0x0080
+#define REGDMN_EEPROM_EEREGCAP_EN_KK_U2         0x0100
+#define REGDMN_EEPROM_EEREGCAP_EN_KK_MIDBAND    0x0200
+#define REGDMN_EEPROM_EEREGCAP_EN_KK_U1_ODD     0x0400
+#define REGDMN_EEPROM_EEREGCAP_EN_KK_NEW_11A    0x0800
+
+struct hal_reg_capabilities {
+	/* regdomain value specified in EEPROM */
+	__le32 eeprom_rd;
+	/*regdomain */
+	__le32 eeprom_rd_ext;
+	/* CAP1 capabilities bit map. */
+	__le32 regcap1;
+	/* REGDMN EEPROM CAP. */
+	__le32 regcap2;
+	/* REGDMN MODE */
+	__le32 wireless_modes;
+	__le32 low_2ghz_chan;
+	__le32 high_2ghz_chan;
+	__le32 low_5ghz_chan;
+	__le32 high_5ghz_chan;
+} __packed;
+
+enum wlan_mode_capability {
+	WHAL_WLAN_11A_CAPABILITY   = 0x1,
+	WHAL_WLAN_11G_CAPABILITY   = 0x2,
+	WHAL_WLAN_11AG_CAPABILITY  = 0x3,
+};
+
+/* structure used by FW for requesting host memory */
+struct wlan_host_mem_req {
+	/* ID of the request */
+	__le32 req_id;
+	/* size of the  of each unit */
+	__le32 unit_size;
+	/* flags to  indicate that
+	 * the number units is dependent
+	 * on number of resources(num vdevs num peers .. etc)
+	 */
+	__le32 num_unit_info;
+	/*
+	 * actual number of units to allocate . if flags in the num_unit_info
+	 * indicate that number of units is tied to number of a particular
+	 * resource to allocate then  num_units filed is set to 0 and host
+	 * will derive the number units from number of the resources it is
+	 * requesting.
+	 */
+	__le32 num_units;
+} __packed;
+
+#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \
+	((((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \
+	(1 << ((svc_id)%(sizeof(u32))))) != 0)
+
+/*
+ * The following struct holds optional payload for
+ * wmi_service_ready_event,e.g., 11ac pass some of the
+ * device capability to the host.
+ */
+struct wmi_service_ready_event {
+	__le32 sw_version;
+	__le32 sw_version_1;
+	__le32 abi_version;
+	/* WMI_PHY_CAPABILITY */
+	__le32 phy_capability;
+	/* Maximum number of frag table entries that SW will populate less 1 */
+	__le32 max_frag_entry;
+	__le32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE];
+	__le32 num_rf_chains;
+	/*
+	 * The following field is only valid for service type
+	 * WMI_SERVICE_11AC
+	 */
+	__le32 ht_cap_info; /* WMI HT Capability */
+	__le32 vht_cap_info; /* VHT capability info field of 802.11ac */
+	__le32 vht_supp_mcs; /* VHT Supported MCS Set field Rx/Tx same */
+	__le32 hw_min_tx_power;
+	__le32 hw_max_tx_power;
+	struct hal_reg_capabilities hal_reg_capabilities;
+	__le32 sys_cap_info;
+	__le32 min_pkt_size_enable; /* Enterprise mode short pkt enable */
+	/*
+	 * Max beacon and Probe Response IE offload size
+	 * (includes optional P2P IEs)
+	 */
+	__le32 max_bcn_ie_size;
+	/*
+	 * request to host to allocate a chuck of memory and pss it down to FW
+	 * via WM_INIT. FW uses this as FW extesnsion memory for saving its
+	 * data structures. Only valid for low latency interfaces like PCIE
+	 * where FW can access this memory directly (or) by DMA.
+	 */
+	__le32 num_mem_reqs;
+	struct wlan_host_mem_req mem_reqs[1];
+} __packed;
+
+/*
+ * status consists of  upper 16 bits fo int status and lower 16 bits of
+ * module ID that retuned status
+ */
+#define WLAN_INIT_STATUS_SUCCESS   0x0
+#define WLAN_GET_INIT_STATUS_REASON(status)    ((status) & 0xffff)
+#define WLAN_GET_INIT_STATUS_MODULE_ID(status) (((status) >> 16) & 0xffff)
+
+#define WMI_SERVICE_READY_TIMEOUT_HZ (5*HZ)
+#define WMI_UNIFIED_READY_TIMEOUT_HZ (5*HZ)
+
+struct wmi_ready_event {
+	__le32 sw_version;
+	__le32 abi_version;
+	struct wmi_mac_addr mac_addr;
+	__le32 status;
+} __packed;
+
+struct wmi_resource_config {
+	/* number of virtual devices (VAPs) to support */
+	__le32 num_vdevs;
+
+	/* number of peer nodes to support */
+	__le32 num_peers;
+
+	/*
+	 * In offload mode target supports features like WOW, chatter and
+	 * other protocol offloads. In order to support them some
+	 * functionalities like reorder buffering, PN checking need to be
+	 * done in target. This determines maximum number of peers suported
+	 * by target in offload mode
+	 */
+	__le32 num_offload_peers;
+
+	/* For target-based RX reordering */
+	__le32 num_offload_reorder_bufs;
+
+	/* number of keys per peer */
+	__le32 num_peer_keys;
+
+	/* total number of TX/RX data TIDs */
+	__le32 num_tids;
+
+	/*
+	 * max skid for resolving hash collisions
+	 *
+	 *   The address search table is sparse, so that if two MAC addresses
+	 *   result in the same hash value, the second of these conflicting
+	 *   entries can slide to the next index in the address search table,
+	 *   and use it, if it is unoccupied.  This ast_skid_limit parameter
+	 *   specifies the upper bound on how many subsequent indices to search
+	 *   over to find an unoccupied space.
+	 */
+	__le32 ast_skid_limit;
+
+	/*
+	 * the nominal chain mask for transmit
+	 *
+	 *   The chain mask may be modified dynamically, e.g. to operate AP
+	 *   tx with a reduced number of chains if no clients are associated.
+	 *   This configuration parameter specifies the nominal chain-mask that
+	 *   should be used when not operating with a reduced set of tx chains.
+	 */
+	__le32 tx_chain_mask;
+
+	/*
+	 * the nominal chain mask for receive
+	 *
+	 *   The chain mask may be modified dynamically, e.g. for a client
+	 *   to use a reduced number of chains for receive if the traffic to
+	 *   the client is low enough that it doesn't require downlink MIMO
+	 *   or antenna diversity.
+	 *   This configuration parameter specifies the nominal chain-mask that
+	 *   should be used when not operating with a reduced set of rx chains.
+	 */
+	__le32 rx_chain_mask;
+
+	/*
+	 * what rx reorder timeout (ms) to use for the AC
+	 *
+	 *   Each WMM access class (voice, video, best-effort, background) will
+	 *   have its own timeout value to dictate how long to wait for missing
+	 *   rx MPDUs to arrive before flushing subsequent MPDUs that have
+	 *   already been received.
+	 *   This parameter specifies the timeout in milliseconds for each
+	 *   class.
+	 */
+	__le32 rx_timeout_pri_vi;
+	__le32 rx_timeout_pri_vo;
+	__le32 rx_timeout_pri_be;
+	__le32 rx_timeout_pri_bk;
+
+	/*
+	 * what mode the rx should decap packets to
+	 *
+	 *   MAC can decap to RAW (no decap), native wifi or Ethernet types
+	 *   THis setting also determines the default TX behavior, however TX
+	 *   behavior can be modified on a per VAP basis during VAP init
+	 */
+	__le32 rx_decap_mode;
+
+	/* what is the maximum scan requests than can be queued */
+	__le32 scan_max_pending_reqs;
+
+	/* maximum VDEV that could use BMISS offload */
+	__le32 bmiss_offload_max_vdev;
+
+	/* maximum VDEV that could use offload roaming */
+	__le32 roam_offload_max_vdev;
+
+	/* maximum AP profiles that would push to offload roaming */
+	__le32 roam_offload_max_ap_profiles;
+
+	/*
+	 * how many groups to use for mcast->ucast conversion
+	 *
+	 *   The target's WAL maintains a table to hold information regarding
+	 *   which peers belong to a given multicast group, so that if
+	 *   multicast->unicast conversion is enabled, the target can convert
+	 *   multicast tx frames to a series of unicast tx frames, to each
+	 *   peer within the multicast group.
+	     This num_mcast_groups configuration parameter tells the target how
+	 *   many multicast groups to provide storage for within its multicast
+	 *   group membership table.
+	 */
+	__le32 num_mcast_groups;
+
+	/*
+	 * size to alloc for the mcast membership table
+	 *
+	 *   This num_mcast_table_elems configuration parameter tells the
+	 *   target how many peer elements it needs to provide storage for in
+	 *   its multicast group membership table.
+	 *   These multicast group membership table elements are shared by the
+	 *   multicast groups stored within the table.
+	 */
+	__le32 num_mcast_table_elems;
+
+	/*
+	 * whether/how to do multicast->unicast conversion
+	 *
+	 *   This configuration parameter specifies whether the target should
+	 *   perform multicast --> unicast conversion on transmit, and if so,
+	 *   what to do if it finds no entries in its multicast group
+	 *   membership table for the multicast IP address in the tx frame.
+	 *   Configuration value:
+	 *   0 -> Do not perform multicast to unicast conversion.
+	 *   1 -> Convert multicast frames to unicast, if the IP multicast
+	 *        address from the tx frame is found in the multicast group
+	 *        membership table.  If the IP multicast address is not found,
+	 *        drop the frame.
+	 *   2 -> Convert multicast frames to unicast, if the IP multicast
+	 *        address from the tx frame is found in the multicast group
+	 *        membership table.  If the IP multicast address is not found,
+	 *        transmit the frame as multicast.
+	 */
+	__le32 mcast2ucast_mode;
+
+	/*
+	 * how much memory to allocate for a tx PPDU dbg log
+	 *
+	 *   This parameter controls how much memory the target will allocate
+	 *   to store a log of tx PPDU meta-information (how large the PPDU
+	 *   was, when it was sent, whether it was successful, etc.)
+	 */
+	__le32 tx_dbg_log_size;
+
+	/* how many AST entries to be allocated for WDS */
+	__le32 num_wds_entries;
+
+	/*
+	 * MAC DMA burst size, e.g., For target PCI limit can be
+	 * 0 -default, 1 256B
+	 */
+	__le32 dma_burst_size;
+
+	/*
+	 * Fixed delimiters to be inserted after every MPDU to
+	 * account for interface latency to avoid underrun.
+	 */
+	__le32 mac_aggr_delim;
+
+	/*
+	 *   determine whether target is responsible for detecting duplicate
+	 *   non-aggregate MPDU and timing out stale fragments.
+	 *
+	 *   A-MPDU reordering is always performed on the target.
+	 *
+	 *   0: target responsible for frag timeout and dup checking
+	 *   1: host responsible for frag timeout and dup checking
+	 */
+	__le32 rx_skip_defrag_timeout_dup_detection_check;
+
+	/*
+	 * Configuration for VoW :
+	 * No of Video Nodes to be supported
+	 * and Max no of descriptors for each Video link (node).
+	 */
+	__le32 vow_config;
+
+	/* maximum VDEV that could use GTK offload */
+	__le32 gtk_offload_max_vdev;
+
+	/* Number of msdu descriptors target should use */
+	__le32 num_msdu_desc;
+
+	/*
+	 * Max. number of Tx fragments per MSDU
+	 *  This parameter controls the max number of Tx fragments per MSDU.
+	 *  This is sent by the target as part of the WMI_SERVICE_READY event
+	 *  and is overriden by the OS shim as required.
+	 */
+	__le32 max_frag_entries;
+} __packed;
+
+/* strucutre describing host memory chunk. */
+struct host_memory_chunk {
+	/* id of the request that is passed up in service ready */
+	__le32 req_id;
+	/* the physical address the memory chunk */
+	__le32 ptr;
+	/* size of the chunk */
+	__le32 size;
+} __packed;
+
+struct wmi_init_cmd {
+	struct wmi_resource_config resource_config;
+	__le32 num_host_mem_chunks;
+
+	/*
+	 * variable number of host memory chunks.
+	 * This should be the last element in the structure
+	 */
+	struct host_memory_chunk host_mem_chunks[1];
+} __packed;
+
+/* TLV for channel list */
+struct wmi_chan_list {
+	__le32 tag; /* WMI_CHAN_LIST_TAG */
+	__le32 num_chan;
+	__le32 channel_list[0];
+} __packed;
+
+struct wmi_bssid_list {
+	__le32 tag; /* WMI_BSSID_LIST_TAG */
+	__le32 num_bssid;
+	struct wmi_mac_addr bssid_list[0];
+} __packed;
+
+struct wmi_ie_data {
+	__le32 tag; /* WMI_IE_TAG */
+	__le32 ie_len;
+	u8 ie_data[0];
+} __packed;
+
+struct wmi_ssid {
+	__le32 ssid_len;
+	u8 ssid[32];
+} __packed;
+
+struct wmi_ssid_list {
+	__le32 tag; /* WMI_SSID_LIST_TAG */
+	__le32 num_ssids;
+	struct wmi_ssid ssids[0];
+} __packed;
+
+/* prefix used by scan requestor ids on the host */
+#define WMI_HOST_SCAN_REQUESTOR_ID_PREFIX 0xA000
+
+/* prefix used by scan request ids generated on the host */
+/* host cycles through the lower 12 bits to generate ids */
+#define WMI_HOST_SCAN_REQ_ID_PREFIX 0xA000
+
+#define WLAN_SCAN_PARAMS_MAX_SSID    16
+#define WLAN_SCAN_PARAMS_MAX_BSSID   4
+#define WLAN_SCAN_PARAMS_MAX_IE_LEN  256
+
+/* Scan priority numbers must be sequential, starting with 0 */
+enum wmi_scan_priority {
+	WMI_SCAN_PRIORITY_VERY_LOW = 0,
+	WMI_SCAN_PRIORITY_LOW,
+	WMI_SCAN_PRIORITY_MEDIUM,
+	WMI_SCAN_PRIORITY_HIGH,
+	WMI_SCAN_PRIORITY_VERY_HIGH,
+	WMI_SCAN_PRIORITY_COUNT   /* number of priorities supported */
+};
+
+struct wmi_start_scan_cmd {
+	/* Scan ID */
+	__le32 scan_id;
+	/* Scan requestor ID */
+	__le32 scan_req_id;
+	/* VDEV id(interface) that is requesting scan */
+	__le32 vdev_id;
+	/* Scan Priority, input to scan scheduler */
+	__le32 scan_priority;
+	/* Scan events subscription */
+	__le32 notify_scan_events;
+	/* dwell time in msec on active channels */
+	__le32 dwell_time_active;
+	/* dwell time in msec on passive channels */
+	__le32 dwell_time_passive;
+	/*
+	 * min time in msec on the BSS channel,only valid if atleast one
+	 * VDEV is active
+	 */
+	__le32 min_rest_time;
+	/*
+	 * max rest time in msec on the BSS channel,only valid if at least
+	 * one VDEV is active
+	 */
+	/*
+	 * the scanner will rest on the bss channel at least min_rest_time
+	 * after min_rest_time the scanner will start checking for tx/rx
+	 * activity on all VDEVs. if there is no activity the scanner will
+	 * switch to off channel. if there is activity the scanner will let
+	 * the radio on the bss channel until max_rest_time expires.at
+	 * max_rest_time scanner will switch to off channel irrespective of
+	 * activity. activity is determined by the idle_time parameter.
+	 */
+	__le32 max_rest_time;
+	/*
+	 * time before sending next set of probe requests.
+	 * The scanner keeps repeating probe requests transmission with
+	 * period specified by repeat_probe_time.
+	 * The number of probe requests specified depends on the ssid_list
+	 * and bssid_list
+	 */
+	__le32 repeat_probe_time;
+	/* time in msec between 2 consequetive probe requests with in a set. */
+	__le32 probe_spacing_time;
+	/*
+	 * data inactivity time in msec on bss channel that will be used by
+	 * scanner for measuring the inactivity.
+	 */
+	__le32 idle_time;
+	/* maximum time in msec allowed for scan  */
+	__le32 max_scan_time;
+	/*
+	 * delay in msec before sending first probe request after switching
+	 * to a channel
+	 */
+	__le32 probe_delay;
+	/* Scan control flags */
+	__le32 scan_ctrl_flags;
+
+	/* Burst duration time in msecs */
+	__le32 burst_duration;
+	/*
+	 * TLV (tag length value )  paramerters follow the scan_cmd structure.
+	 * TLV can contain channel list, bssid list, ssid list and
+	 * ie. the TLV tags are defined above;
+	 */
+} __packed;
+
+struct wmi_ssid_arg {
+	int len;
+	const u8 *ssid;
+};
+
+struct wmi_bssid_arg {
+	const u8 *bssid;
+};
+
+struct wmi_start_scan_arg {
+	u32 scan_id;
+	u32 scan_req_id;
+	u32 vdev_id;
+	u32 scan_priority;
+	u32 notify_scan_events;
+	u32 dwell_time_active;
+	u32 dwell_time_passive;
+	u32 min_rest_time;
+	u32 max_rest_time;
+	u32 repeat_probe_time;
+	u32 probe_spacing_time;
+	u32 idle_time;
+	u32 max_scan_time;
+	u32 probe_delay;
+	u32 scan_ctrl_flags;
+
+	u32 ie_len;
+	u32 n_channels;
+	u32 n_ssids;
+	u32 n_bssids;
+
+	u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN];
+	u32 channels[64];
+	struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID];
+	struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID];
+};
+
+/* scan control flags */
+
+/* passively scan all channels including active channels */
+#define WMI_SCAN_FLAG_PASSIVE        0x1
+/* add wild card ssid probe request even though ssid_list is specified. */
+#define WMI_SCAN_ADD_BCAST_PROBE_REQ 0x2
+/* add cck rates to rates/xrate ie for the generated probe request */
+#define WMI_SCAN_ADD_CCK_RATES 0x4
+/* add ofdm rates to rates/xrate ie for the generated probe request */
+#define WMI_SCAN_ADD_OFDM_RATES 0x8
+/* To enable indication of Chan load and Noise floor to host */
+#define WMI_SCAN_CHAN_STAT_EVENT 0x10
+/* Filter Probe request frames  */
+#define WMI_SCAN_FILTER_PROBE_REQ 0x20
+/* When set, DFS channels will not be scanned */
+#define WMI_SCAN_BYPASS_DFS_CHN 0x40
+/* Different FW scan engine may choose to bail out on errors.
+ * Allow the driver to have influence over that. */
+#define WMI_SCAN_CONTINUE_ON_ERROR 0x80
+
+/* WMI_SCAN_CLASS_MASK must be the same value as IEEE80211_SCAN_CLASS_MASK */
+#define WMI_SCAN_CLASS_MASK 0xFF000000
+
+
+enum wmi_stop_scan_type {
+	WMI_SCAN_STOP_ONE	= 0x00000000, /* stop by scan_id */
+	WMI_SCAN_STOP_VDEV_ALL	= 0x01000000, /* stop by vdev_id */
+	WMI_SCAN_STOP_ALL	= 0x04000000, /* stop all scans */
+};
+
+struct wmi_stop_scan_cmd {
+	__le32 scan_req_id;
+	__le32 scan_id;
+	__le32 req_type;
+	__le32 vdev_id;
+} __packed;
+
+struct wmi_stop_scan_arg {
+	u32 req_id;
+	enum wmi_stop_scan_type req_type;
+	union {
+		u32 scan_id;
+		u32 vdev_id;
+	} u;
+};
+
+struct wmi_scan_chan_list_cmd {
+	__le32 num_scan_chans;
+	struct wmi_channel chan_info[0];
+} __packed;
+
+struct wmi_scan_chan_list_arg {
+	u32 n_channels;
+	struct wmi_channel_arg *channels;
+};
+
+enum wmi_bss_filter {
+	WMI_BSS_FILTER_NONE = 0,        /* no beacons forwarded */
+	WMI_BSS_FILTER_ALL,             /* all beacons forwarded */
+	WMI_BSS_FILTER_PROFILE,         /* only beacons matching profile */
+	WMI_BSS_FILTER_ALL_BUT_PROFILE, /* all but beacons matching profile */
+	WMI_BSS_FILTER_CURRENT_BSS,     /* only beacons matching current BSS */
+	WMI_BSS_FILTER_ALL_BUT_BSS,     /* all but beacons matching BSS */
+	WMI_BSS_FILTER_PROBED_SSID,     /* beacons matching probed ssid */
+	WMI_BSS_FILTER_LAST_BSS,        /* marker only */
+};
+
+enum wmi_scan_event_type {
+	WMI_SCAN_EVENT_STARTED         = 0x1,
+	WMI_SCAN_EVENT_COMPLETED       = 0x2,
+	WMI_SCAN_EVENT_BSS_CHANNEL     = 0x4,
+	WMI_SCAN_EVENT_FOREIGN_CHANNEL = 0x8,
+	WMI_SCAN_EVENT_DEQUEUED        = 0x10,
+	WMI_SCAN_EVENT_PREEMPTED       = 0x20, /* possibly by high-prio scan */
+	WMI_SCAN_EVENT_START_FAILED    = 0x40,
+	WMI_SCAN_EVENT_RESTARTED       = 0x80,
+	WMI_SCAN_EVENT_MAX             = 0x8000
+};
+
+enum wmi_scan_completion_reason {
+	WMI_SCAN_REASON_COMPLETED,
+	WMI_SCAN_REASON_CANCELLED,
+	WMI_SCAN_REASON_PREEMPTED,
+	WMI_SCAN_REASON_TIMEDOUT,
+	WMI_SCAN_REASON_MAX,
+};
+
+struct wmi_scan_event {
+	__le32 event_type; /* %WMI_SCAN_EVENT_ */
+	__le32 reason; /* %WMI_SCAN_REASON_ */
+	__le32 channel_freq; /* only valid for WMI_SCAN_EVENT_FOREIGN_CHANNEL */
+	__le32 scan_req_id;
+	__le32 scan_id;
+	__le32 vdev_id;
+} __packed;
+
+/*
+ * This defines how much headroom is kept in the
+ * receive frame between the descriptor and the
+ * payload, in order for the WMI PHY error and
+ * management handler to insert header contents.
+ *
+ * This is in bytes.
+ */
+#define WMI_MGMT_RX_HDR_HEADROOM    52
+
+/*
+ * This event will be used for sending scan results
+ * as well as rx mgmt frames to the host. The rx buffer
+ * will be sent as part of this WMI event. It would be a
+ * good idea to pass all the fields in the RX status
+ * descriptor up to the host.
+ */
+struct wmi_mgmt_rx_hdr {
+	__le32 channel;
+	__le32 snr;
+	__le32 rate;
+	__le32 phy_mode;
+	__le32 buf_len;
+	__le32 status; /* %WMI_RX_STATUS_ */
+} __packed;
+
+struct wmi_mgmt_rx_event {
+	struct wmi_mgmt_rx_hdr hdr;
+	u8 buf[0];
+} __packed;
+
+#define WMI_RX_STATUS_OK			0x00
+#define WMI_RX_STATUS_ERR_CRC			0x01
+#define WMI_RX_STATUS_ERR_DECRYPT		0x08
+#define WMI_RX_STATUS_ERR_MIC			0x10
+#define WMI_RX_STATUS_ERR_KEY_CACHE_MISS	0x20
+
+struct wmi_single_phyerr_rx_hdr {
+	/* TSF timestamp */
+	__le32 tsf_timestamp;
+
+	/*
+	 * Current freq1, freq2
+	 *
+	 * [7:0]:    freq1[lo]
+	 * [15:8] :   freq1[hi]
+	 * [23:16]:   freq2[lo]
+	 * [31:24]:   freq2[hi]
+	 */
+	__le16 freq1;
+	__le16 freq2;
+
+	/*
+	 * Combined RSSI over all chains and channel width for this PHY error
+	 *
+	 * [7:0]: RSSI combined
+	 * [15:8]: Channel width (MHz)
+	 * [23:16]: PHY error code
+	 * [24:16]: reserved (future use)
+	 */
+	u8 rssi_combined;
+	u8 chan_width_mhz;
+	u8 phy_err_code;
+	u8 rsvd0;
+
+	/*
+	 * RSSI on chain 0 through 3
+	 *
+	 * This is formatted the same as the PPDU_START RX descriptor
+	 * field:
+	 *
+	 * [7:0]:   pri20
+	 * [15:8]:  sec20
+	 * [23:16]: sec40
+	 * [31:24]: sec80
+	 */
+
+	__le32 rssi_chain0;
+	__le32 rssi_chain1;
+	__le32 rssi_chain2;
+	__le32 rssi_chain3;
+
+	/*
+	 * Last calibrated NF value for chain 0 through 3
+	 *
+	 * nf_list_1:
+	 *
+	 * + [15:0] - chain 0
+	 * + [31:16] - chain 1
+	 *
+	 * nf_list_2:
+	 *
+	 * + [15:0] - chain 2
+	 * + [31:16] - chain 3
+	 */
+	__le32 nf_list_1;
+	__le32 nf_list_2;
+
+
+	/* Length of the frame */
+	__le32 buf_len;
+} __packed;
+
+struct wmi_single_phyerr_rx_event {
+	/* Phy error event header */
+	struct wmi_single_phyerr_rx_hdr hdr;
+	/* frame buffer */
+	u8 bufp[0];
+} __packed;
+
+struct wmi_comb_phyerr_rx_hdr {
+	/* Phy error phy error count */
+	__le32 num_phyerr_events;
+	__le32 tsf_l32;
+	__le32 tsf_u32;
+} __packed;
+
+struct wmi_comb_phyerr_rx_event {
+	/* Phy error phy error count */
+	struct wmi_comb_phyerr_rx_hdr hdr;
+	/*
+	 * frame buffer - contains multiple payloads in the order:
+	 *                    header - payload, header - payload...
+	 *  (The header is of type: wmi_single_phyerr_rx_hdr)
+	 */
+	u8 bufp[0];
+} __packed;
+
+struct wmi_mgmt_tx_hdr {
+	__le32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+	__le32 tx_rate;
+	__le32 tx_power;
+	__le32 buf_len;
+} __packed;
+
+struct wmi_mgmt_tx_cmd {
+	struct wmi_mgmt_tx_hdr hdr;
+	u8 buf[0];
+} __packed;
+
+struct wmi_echo_event {
+	__le32 value;
+} __packed;
+
+struct wmi_echo_cmd {
+	__le32 value;
+} __packed;
+
+
+struct wmi_pdev_set_regdomain_cmd {
+	__le32 reg_domain;
+	__le32 reg_domain_2G;
+	__le32 reg_domain_5G;
+	__le32 conformance_test_limit_2G;
+	__le32 conformance_test_limit_5G;
+} __packed;
+
+/* Command to set/unset chip in quiet mode */
+struct wmi_pdev_set_quiet_cmd {
+	/* period in TUs */
+	__le32 period;
+
+	/* duration in TUs */
+	__le32 duration;
+
+	/* offset in TUs */
+	__le32 next_start;
+
+	/* enable/disable */
+	__le32 enabled;
+} __packed;
+
+
+/*
+ * 802.11g protection mode.
+ */
+enum ath10k_protmode {
+	ATH10K_PROT_NONE     = 0,    /* no protection */
+	ATH10K_PROT_CTSONLY  = 1,    /* CTS to self */
+	ATH10K_PROT_RTSCTS   = 2,    /* RTS-CTS */
+};
+
+enum wmi_beacon_gen_mode {
+	WMI_BEACON_STAGGERED_MODE = 0,
+	WMI_BEACON_BURST_MODE = 1
+};
+
+enum wmi_csa_event_ies_present_flag {
+	WMI_CSA_IE_PRESENT = 0x00000001,
+	WMI_XCSA_IE_PRESENT = 0x00000002,
+	WMI_WBW_IE_PRESENT = 0x00000004,
+	WMI_CSWARP_IE_PRESENT = 0x00000008,
+};
+
+/* wmi CSA receive event from beacon frame */
+struct wmi_csa_event {
+	__le32 i_fc_dur;
+	/* Bit 0-15: FC */
+	/* Bit 16-31: DUR */
+	struct wmi_mac_addr i_addr1;
+	struct wmi_mac_addr i_addr2;
+	__le32 csa_ie[2];
+	__le32 xcsa_ie[2];
+	__le32 wb_ie[2];
+	__le32 cswarp_ie;
+	__le32 ies_present_flag; /* wmi_csa_event_ies_present_flag */
+} __packed;
+
+/* the definition of different PDEV parameters */
+#define PDEV_DEFAULT_STATS_UPDATE_PERIOD    500
+#define VDEV_DEFAULT_STATS_UPDATE_PERIOD    500
+#define PEER_DEFAULT_STATS_UPDATE_PERIOD    500
+
+enum wmi_pdev_param {
+	/* TX chian mask */
+	WMI_PDEV_PARAM_TX_CHAIN_MASK = 0x1,
+	/* RX chian mask */
+	WMI_PDEV_PARAM_RX_CHAIN_MASK,
+	/* TX power limit for 2G Radio */
+	WMI_PDEV_PARAM_TXPOWER_LIMIT2G,
+	/* TX power limit for 5G Radio */
+	WMI_PDEV_PARAM_TXPOWER_LIMIT5G,
+	/* TX power scale */
+	WMI_PDEV_PARAM_TXPOWER_SCALE,
+	/* Beacon generation mode . 0: host, 1: target   */
+	WMI_PDEV_PARAM_BEACON_GEN_MODE,
+	/* Beacon generation mode . 0: staggered 1: bursted   */
+	WMI_PDEV_PARAM_BEACON_TX_MODE,
+	/*
+	 * Resource manager off chan mode .
+	 * 0: turn off off chan mode. 1: turn on offchan mode
+	 */
+	WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
+	/*
+	 * Protection mode:
+	 * 0: no protection 1:use CTS-to-self 2: use RTS/CTS
+	 */
+	WMI_PDEV_PARAM_PROTECTION_MODE,
+	/* Dynamic bandwidth 0: disable 1: enable */
+	WMI_PDEV_PARAM_DYNAMIC_BW,
+	/* Non aggregrate/ 11g sw retry threshold.0-disable */
+	WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
+	/* aggregrate sw retry threshold. 0-disable*/
+	WMI_PDEV_PARAM_AGG_SW_RETRY_TH,
+	/* Station kickout threshold (non of consecutive failures).0-disable */
+	WMI_PDEV_PARAM_STA_KICKOUT_TH,
+	/* Aggerate size scaling configuration per AC */
+	WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING,
+	/* LTR enable */
+	WMI_PDEV_PARAM_LTR_ENABLE,
+	/* LTR latency for BE, in us */
+	WMI_PDEV_PARAM_LTR_AC_LATENCY_BE,
+	/* LTR latency for BK, in us */
+	WMI_PDEV_PARAM_LTR_AC_LATENCY_BK,
+	/* LTR latency for VI, in us */
+	WMI_PDEV_PARAM_LTR_AC_LATENCY_VI,
+	/* LTR latency for VO, in us  */
+	WMI_PDEV_PARAM_LTR_AC_LATENCY_VO,
+	/* LTR AC latency timeout, in ms */
+	WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
+	/* LTR platform latency override, in us */
+	WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
+	/* LTR-RX override, in us */
+	WMI_PDEV_PARAM_LTR_RX_OVERRIDE,
+	/* Tx activity timeout for LTR, in us */
+	WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
+	/* L1SS state machine enable */
+	WMI_PDEV_PARAM_L1SS_ENABLE,
+	/* Deep sleep state machine enable */
+	WMI_PDEV_PARAM_DSLEEP_ENABLE,
+	/* RX buffering flush enable */
+	WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
+	/* RX buffering matermark */
+	WMI_PDEV_PARAM_PCIELP_TXBUF_WATERMARK,
+	/* RX buffering timeout enable */
+	WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
+	/* RX buffering timeout value */
+	WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
+	/* pdev level stats update period in ms */
+	WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
+	/* vdev level stats update period in ms */
+	WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
+	/* peer level stats update period in ms */
+	WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
+	/* beacon filter status update period */
+	WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
+	/* QOS Mgmt frame protection MFP/PMF 0: disable, 1: enable */
+	WMI_PDEV_PARAM_PMF_QOS,
+	/* Access category on which ARP frames are sent */
+	WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
+	/* DCS configuration */
+	WMI_PDEV_PARAM_DCS,
+	/* Enable/Disable ANI on target */
+	WMI_PDEV_PARAM_ANI_ENABLE,
+	/* configure the ANI polling period */
+	WMI_PDEV_PARAM_ANI_POLL_PERIOD,
+	/* configure the ANI listening period */
+	WMI_PDEV_PARAM_ANI_LISTEN_PERIOD,
+	/* configure OFDM immunity level */
+	WMI_PDEV_PARAM_ANI_OFDM_LEVEL,
+	/* configure CCK immunity level */
+	WMI_PDEV_PARAM_ANI_CCK_LEVEL,
+	/* Enable/Disable CDD for 1x1 STAs in rate control module */
+	WMI_PDEV_PARAM_DYNTXCHAIN,
+	/* Enable/Disable proxy STA */
+	WMI_PDEV_PARAM_PROXY_STA,
+	/* Enable/Disable low power state when all VDEVs are inactive/idle. */
+	WMI_PDEV_PARAM_IDLE_PS_CONFIG,
+	/* Enable/Disable power gating sleep */
+	WMI_PDEV_PARAM_POWER_GATING_SLEEP,
+};
+
+struct wmi_pdev_set_param_cmd {
+	__le32 param_id;
+	__le32 param_value;
+} __packed;
+
+struct wmi_pdev_get_tpc_config_cmd {
+	/* parameter   */
+	__le32 param;
+} __packed;
+
+#define WMI_TPC_RATE_MAX		160
+#define WMI_TPC_TX_N_CHAIN		4
+
+enum wmi_tpc_config_event_flag {
+	WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD	= 0x1,
+	WMI_TPC_CONFIG_EVENT_FLAG_TABLE_STBC	= 0x2,
+	WMI_TPC_CONFIG_EVENT_FLAG_TABLE_TXBF	= 0x4,
+};
+
+struct wmi_pdev_tpc_config_event {
+	__le32 reg_domain;
+	__le32 chan_freq;
+	__le32 phy_mode;
+	__le32 twice_antenna_reduction;
+	__le32 twice_max_rd_power;
+	s32 twice_antenna_gain;
+	__le32 power_limit;
+	__le32 rate_max;
+	__le32 num_tx_chain;
+	__le32 ctl;
+	__le32 flags;
+	s8 max_reg_allow_pow[WMI_TPC_TX_N_CHAIN];
+	s8 max_reg_allow_pow_agcdd[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
+	s8 max_reg_allow_pow_agstbc[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
+	s8 max_reg_allow_pow_agtxbf[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
+	u8 rates_array[WMI_TPC_RATE_MAX];
+} __packed;
+
+/* Transmit power scale factor. */
+enum wmi_tp_scale {
+	WMI_TP_SCALE_MAX    = 0,	/* no scaling (default) */
+	WMI_TP_SCALE_50     = 1,	/* 50% of max (-3 dBm) */
+	WMI_TP_SCALE_25     = 2,	/* 25% of max (-6 dBm) */
+	WMI_TP_SCALE_12     = 3,	/* 12% of max (-9 dBm) */
+	WMI_TP_SCALE_MIN    = 4,	/* min, but still on   */
+	WMI_TP_SCALE_SIZE   = 5,	/* max num of enum     */
+};
+
+struct wmi_set_channel_cmd {
+	/* channel (only frequency and mode info are used) */
+	struct wmi_channel chan;
+} __packed;
+
+struct wmi_pdev_chanlist_update_event {
+	/* number of channels */
+	__le32 num_chan;
+	/* array of channels */
+	struct wmi_channel channel_list[1];
+} __packed;
+
+#define WMI_MAX_DEBUG_MESG (sizeof(u32) * 32)
+
+struct wmi_debug_mesg_event {
+	/* message buffer, NULL terminated */
+	char bufp[WMI_MAX_DEBUG_MESG];
+} __packed;
+
+enum {
+	/* P2P device */
+	VDEV_SUBTYPE_P2PDEV = 0,
+	/* P2P client */
+	VDEV_SUBTYPE_P2PCLI,
+	/* P2P GO */
+	VDEV_SUBTYPE_P2PGO,
+	/* BT3.0 HS */
+	VDEV_SUBTYPE_BT,
+};
+
+struct wmi_pdev_set_channel_cmd {
+	/* idnore power , only use flags , mode and freq */
+	struct wmi_channel chan;
+} __packed;
+
+/* Customize the DSCP (bit) to TID (0-7) mapping for QOS */
+#define WMI_DSCP_MAP_MAX    (64)
+struct wmi_pdev_set_dscp_tid_map_cmd {
+	/* map indicating DSCP to TID conversion */
+	__le32 dscp_to_tid_map[WMI_DSCP_MAP_MAX];
+} __packed;
+
+enum mcast_bcast_rate_id {
+	WMI_SET_MCAST_RATE,
+	WMI_SET_BCAST_RATE
+};
+
+struct mcast_bcast_rate {
+	enum mcast_bcast_rate_id rate_id;
+	__le32 rate;
+} __packed;
+
+struct wmi_wmm_params {
+	__le32 cwmin;
+	__le32 cwmax;
+	__le32 aifs;
+	__le32 txop;
+	__le32 acm;
+	__le32 no_ack;
+} __packed;
+
+struct wmi_pdev_set_wmm_params {
+	struct wmi_wmm_params ac_be;
+	struct wmi_wmm_params ac_bk;
+	struct wmi_wmm_params ac_vi;
+	struct wmi_wmm_params ac_vo;
+} __packed;
+
+struct wmi_wmm_params_arg {
+	u32 cwmin;
+	u32 cwmax;
+	u32 aifs;
+	u32 txop;
+	u32 acm;
+	u32 no_ack;
+};
+
+struct wmi_pdev_set_wmm_params_arg {
+	struct wmi_wmm_params_arg ac_be;
+	struct wmi_wmm_params_arg ac_bk;
+	struct wmi_wmm_params_arg ac_vi;
+	struct wmi_wmm_params_arg ac_vo;
+};
+
+struct wal_dbg_tx_stats {
+	/* Num HTT cookies queued to dispatch list */
+	__le32 comp_queued;
+
+	/* Num HTT cookies dispatched */
+	__le32 comp_delivered;
+
+	/* Num MSDU queued to WAL */
+	__le32 msdu_enqued;
+
+	/* Num MPDU queue to WAL */
+	__le32 mpdu_enqued;
+
+	/* Num MSDUs dropped by WMM limit */
+	__le32 wmm_drop;
+
+	/* Num Local frames queued */
+	__le32 local_enqued;
+
+	/* Num Local frames done */
+	__le32 local_freed;
+
+	/* Num queued to HW */
+	__le32 hw_queued;
+
+	/* Num PPDU reaped from HW */
+	__le32 hw_reaped;
+
+	/* Num underruns */
+	__le32 underrun;
+
+	/* Num PPDUs cleaned up in TX abort */
+	__le32 tx_abort;
+
+	/* Num MPDUs requed by SW */
+	__le32 mpdus_requed;
+
+	/* excessive retries */
+	__le32 tx_ko;
+
+	/* data hw rate code */
+	__le32 data_rc;
+
+	/* Scheduler self triggers */
+	__le32 self_triggers;
+
+	/* frames dropped due to excessive sw retries */
+	__le32 sw_retry_failure;
+
+	/* illegal rate phy errors  */
+	__le32 illgl_rate_phy_err;
+
+	/* wal pdev continous xretry */
+	__le32 pdev_cont_xretry;
+
+	/* wal pdev continous xretry */
+	__le32 pdev_tx_timeout;
+
+	/* wal pdev resets  */
+	__le32 pdev_resets;
+
+	__le32 phy_underrun;
+
+	/* MPDU is more than txop limit */
+	__le32 txop_ovf;
+} __packed;
+
+struct wal_dbg_rx_stats {
+	/* Cnts any change in ring routing mid-ppdu */
+	__le32 mid_ppdu_route_change;
+
+	/* Total number of statuses processed */
+	__le32 status_rcvd;
+
+	/* Extra frags on rings 0-3 */
+	__le32 r0_frags;
+	__le32 r1_frags;
+	__le32 r2_frags;
+	__le32 r3_frags;
+
+	/* MSDUs / MPDUs delivered to HTT */
+	__le32 htt_msdus;
+	__le32 htt_mpdus;
+
+	/* MSDUs / MPDUs delivered to local stack */
+	__le32 loc_msdus;
+	__le32 loc_mpdus;
+
+	/* AMSDUs that have more MSDUs than the status ring size */
+	__le32 oversize_amsdu;
+
+	/* Number of PHY errors */
+	__le32 phy_errs;
+
+	/* Number of PHY errors drops */
+	__le32 phy_err_drop;
+
+	/* Number of mpdu errors - FCS, MIC, ENC etc. */
+	__le32 mpdu_errs;
+} __packed;
+
+struct wal_dbg_peer_stats {
+	/* REMOVE THIS ONCE REAL PEER STAT COUNTERS ARE ADDED */
+	__le32 dummy;
+} __packed;
+
+struct wal_dbg_stats {
+	struct wal_dbg_tx_stats tx;
+	struct wal_dbg_rx_stats rx;
+	struct wal_dbg_peer_stats peer;
+} __packed;
+
+enum wmi_stats_id {
+	WMI_REQUEST_PEER_STAT	= 0x01,
+	WMI_REQUEST_AP_STAT	= 0x02
+};
+
+struct wmi_request_stats_cmd {
+	__le32 stats_id;
+
+	/*
+	 * Space to add parameters like
+	 * peer mac addr
+	 */
+} __packed;
+
+/* Suspend option */
+enum {
+	/* suspend */
+	WMI_PDEV_SUSPEND,
+
+	/* suspend and disable all interrupts */
+	WMI_PDEV_SUSPEND_AND_DISABLE_INTR,
+};
+
+struct wmi_pdev_suspend_cmd {
+	/* suspend option sent to target */
+	__le32 suspend_opt;
+} __packed;
+
+struct wmi_stats_event {
+	__le32 stats_id; /* %WMI_REQUEST_ */
+	/*
+	 * number of pdev stats event structures
+	 * (wmi_pdev_stats) 0 or 1
+	 */
+	__le32 num_pdev_stats;
+	/*
+	 * number of vdev stats event structures
+	 * (wmi_vdev_stats) 0 or max vdevs
+	 */
+	__le32 num_vdev_stats;
+	/*
+	 * number of peer stats event structures
+	 * (wmi_peer_stats) 0 or max peers
+	 */
+	__le32 num_peer_stats;
+	__le32 num_bcnflt_stats;
+	/*
+	 * followed by
+	 *   num_pdev_stats * size of(struct wmi_pdev_stats)
+	 *   num_vdev_stats * size of(struct wmi_vdev_stats)
+	 *   num_peer_stats * size of(struct wmi_peer_stats)
+	 *
+	 *  By having a zero sized array, the pointer to data area
+	 *  becomes available without increasing the struct size
+	 */
+	u8 data[0];
+} __packed;
+
+/*
+ * PDEV statistics
+ * TODO: add all PDEV stats here
+ */
+struct wmi_pdev_stats {
+	__le32 chan_nf;        /* Channel noise floor */
+	__le32 tx_frame_count; /* TX frame count */
+	__le32 rx_frame_count; /* RX frame count */
+	__le32 rx_clear_count; /* rx clear count */
+	__le32 cycle_count;    /* cycle count */
+	__le32 phy_err_count;  /* Phy error count */
+	__le32 chan_tx_pwr;    /* channel tx power */
+	struct wal_dbg_stats wal; /* WAL dbg stats */
+} __packed;
+
+/*
+ * VDEV statistics
+ * TODO: add all VDEV stats here
+ */
+struct wmi_vdev_stats {
+	__le32 vdev_id;
+} __packed;
+
+/*
+ * peer statistics.
+ * TODO: add more stats
+ */
+struct wmi_peer_stats {
+	struct wmi_mac_addr peer_macaddr;
+	__le32 peer_rssi;
+	__le32 peer_tx_rate;
+} __packed;
+
+struct wmi_vdev_create_cmd {
+	__le32 vdev_id;
+	__le32 vdev_type;
+	__le32 vdev_subtype;
+	struct wmi_mac_addr vdev_macaddr;
+} __packed;
+
+enum wmi_vdev_type {
+	WMI_VDEV_TYPE_AP      = 1,
+	WMI_VDEV_TYPE_STA     = 2,
+	WMI_VDEV_TYPE_IBSS    = 3,
+	WMI_VDEV_TYPE_MONITOR = 4,
+};
+
+enum wmi_vdev_subtype {
+	WMI_VDEV_SUBTYPE_NONE       = 0,
+	WMI_VDEV_SUBTYPE_P2P_DEVICE = 1,
+	WMI_VDEV_SUBTYPE_P2P_CLIENT = 2,
+	WMI_VDEV_SUBTYPE_P2P_GO     = 3,
+};
+
+/* values for vdev_subtype */
+
+/* values for vdev_start_request flags */
+/*
+ * Indicates that AP VDEV uses hidden ssid. only valid for
+ *  AP/GO */
+#define WMI_VDEV_START_HIDDEN_SSID  (1<<0)
+/*
+ * Indicates if robust management frame/management frame
+ *  protection is enabled. For GO/AP vdevs, it indicates that
+ *  it may support station/client associations with RMF enabled.
+ *  For STA/client vdevs, it indicates that sta will
+ *  associate with AP with RMF enabled. */
+#define WMI_VDEV_START_PMF_ENABLED  (1<<1)
+
+struct wmi_p2p_noa_descriptor {
+	__le32 type_count; /* 255: continuous schedule, 0: reserved */
+	__le32 duration;  /* Absent period duration in micro seconds */
+	__le32 interval;   /* Absent period interval in micro seconds */
+	__le32 start_time; /* 32 bit tsf time when in starts */
+} __packed;
+
+struct wmi_vdev_start_request_cmd {
+	/* WMI channel */
+	struct wmi_channel chan;
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+	/* requestor id identifying the caller module */
+	__le32 requestor_id;
+	/* beacon interval from received beacon */
+	__le32 beacon_interval;
+	/* DTIM Period from the received beacon */
+	__le32 dtim_period;
+	/* Flags */
+	__le32 flags;
+	/* ssid field. Only valid for AP/GO/IBSS/BTAmp VDEV type. */
+	struct wmi_ssid ssid;
+	/* beacon/probe reponse xmit rate. Applicable for SoftAP. */
+	__le32 bcn_tx_rate;
+	/* beacon/probe reponse xmit power. Applicable for SoftAP. */
+	__le32 bcn_tx_power;
+	/* number of p2p NOA descriptor(s) from scan entry */
+	__le32 num_noa_descriptors;
+	/*
+	 * Disable H/W ack. This used by WMI_VDEV_RESTART_REQUEST_CMDID.
+	 * During CAC, Our HW shouldn't ack ditected frames
+	 */
+	__le32 disable_hw_ack;
+	/* actual p2p NOA descriptor from scan entry */
+	struct wmi_p2p_noa_descriptor noa_descriptors[2];
+} __packed;
+
+struct wmi_vdev_restart_request_cmd {
+	struct wmi_vdev_start_request_cmd vdev_start_request_cmd;
+} __packed;
+
+struct wmi_vdev_start_request_arg {
+	u32 vdev_id;
+	struct wmi_channel_arg channel;
+	u32 bcn_intval;
+	u32 dtim_period;
+	u8 *ssid;
+	u32 ssid_len;
+	u32 bcn_tx_rate;
+	u32 bcn_tx_power;
+	bool disable_hw_ack;
+	bool hidden_ssid;
+	bool pmf_enabled;
+};
+
+struct wmi_vdev_delete_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+} __packed;
+
+struct wmi_vdev_up_cmd {
+	__le32 vdev_id;
+	__le32 vdev_assoc_id;
+	struct wmi_mac_addr vdev_bssid;
+} __packed;
+
+struct wmi_vdev_stop_cmd {
+	__le32 vdev_id;
+} __packed;
+
+struct wmi_vdev_down_cmd {
+	__le32 vdev_id;
+} __packed;
+
+struct wmi_vdev_standby_response_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+} __packed;
+
+struct wmi_vdev_resume_response_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+} __packed;
+
+struct wmi_vdev_set_param_cmd {
+	__le32 vdev_id;
+	__le32 param_id;
+	__le32 param_value;
+} __packed;
+
+#define WMI_MAX_KEY_INDEX   3
+#define WMI_MAX_KEY_LEN     32
+
+#define WMI_KEY_PAIRWISE 0x00
+#define WMI_KEY_GROUP    0x01
+#define WMI_KEY_TX_USAGE 0x02 /* default tx key - static wep */
+
+struct wmi_key_seq_counter {
+	__le32 key_seq_counter_l;
+	__le32 key_seq_counter_h;
+} __packed;
+
+#define WMI_CIPHER_NONE     0x0 /* clear key */
+#define WMI_CIPHER_WEP      0x1
+#define WMI_CIPHER_TKIP     0x2
+#define WMI_CIPHER_AES_OCB  0x3
+#define WMI_CIPHER_AES_CCM  0x4
+#define WMI_CIPHER_WAPI     0x5
+#define WMI_CIPHER_CKIP     0x6
+#define WMI_CIPHER_AES_CMAC 0x7
+
+struct wmi_vdev_install_key_cmd {
+	__le32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+	__le32 key_idx;
+	__le32 key_flags;
+	__le32 key_cipher; /* %WMI_CIPHER_ */
+	struct wmi_key_seq_counter key_rsc_counter;
+	struct wmi_key_seq_counter key_global_rsc_counter;
+	struct wmi_key_seq_counter key_tsc_counter;
+	u8 wpi_key_rsc_counter[16];
+	u8 wpi_key_tsc_counter[16];
+	__le32 key_len;
+	__le32 key_txmic_len;
+	__le32 key_rxmic_len;
+
+	/* contains key followed by tx mic followed by rx mic */
+	u8 key_data[0];
+} __packed;
+
+struct wmi_vdev_install_key_arg {
+	u32 vdev_id;
+	const u8 *macaddr;
+	u32 key_idx;
+	u32 key_flags;
+	u32 key_cipher;
+	u32 key_len;
+	u32 key_txmic_len;
+	u32 key_rxmic_len;
+	const void *key_data;
+};
+
+/* Preamble types to be used with VDEV fixed rate configuration */
+enum wmi_rate_preamble {
+	WMI_RATE_PREAMBLE_OFDM,
+	WMI_RATE_PREAMBLE_CCK,
+	WMI_RATE_PREAMBLE_HT,
+	WMI_RATE_PREAMBLE_VHT,
+};
+
+/* Value to disable fixed rate setting */
+#define WMI_FIXED_RATE_NONE    (0xff)
+
+/* the definition of different VDEV parameters */
+enum wmi_vdev_param {
+	/* RTS Threshold */
+	WMI_VDEV_PARAM_RTS_THRESHOLD = 0x1,
+	/* Fragmentation threshold */
+	WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
+	/* beacon interval in TUs */
+	WMI_VDEV_PARAM_BEACON_INTERVAL,
+	/* Listen interval in TUs */
+	WMI_VDEV_PARAM_LISTEN_INTERVAL,
+	/* muticast rate in Mbps */
+	WMI_VDEV_PARAM_MULTICAST_RATE,
+	/* management frame rate in Mbps */
+	WMI_VDEV_PARAM_MGMT_TX_RATE,
+	/* slot time (long vs short) */
+	WMI_VDEV_PARAM_SLOT_TIME,
+	/* preamble (long vs short) */
+	WMI_VDEV_PARAM_PREAMBLE,
+	/* SWBA time (time before tbtt in msec) */
+	WMI_VDEV_PARAM_SWBA_TIME,
+	/* time period for updating VDEV stats */
+	WMI_VDEV_STATS_UPDATE_PERIOD,
+	/* age out time in msec for frames queued for station in power save */
+	WMI_VDEV_PWRSAVE_AGEOUT_TIME,
+	/*
+	 * Host SWBA interval (time in msec before tbtt for SWBA event
+	 * generation).
+	 */
+	WMI_VDEV_HOST_SWBA_INTERVAL,
+	/* DTIM period (specified in units of num beacon intervals) */
+	WMI_VDEV_PARAM_DTIM_PERIOD,
+	/*
+	 * scheduler air time limit for this VDEV. used by off chan
+	 * scheduler.
+	 */
+	WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
+	/* enable/dsiable WDS for this VDEV  */
+	WMI_VDEV_PARAM_WDS,
+	/* ATIM Window */
+	WMI_VDEV_PARAM_ATIM_WINDOW,
+	/* BMISS max */
+	WMI_VDEV_PARAM_BMISS_COUNT_MAX,
+	/* BMISS first time */
+	WMI_VDEV_PARAM_BMISS_FIRST_BCNT,
+	/* BMISS final time */
+	WMI_VDEV_PARAM_BMISS_FINAL_BCNT,
+	/* WMM enables/disabled */
+	WMI_VDEV_PARAM_FEATURE_WMM,
+	/* Channel width */
+	WMI_VDEV_PARAM_CHWIDTH,
+	/* Channel Offset */
+	WMI_VDEV_PARAM_CHEXTOFFSET,
+	/* Disable HT Protection */
+	WMI_VDEV_PARAM_DISABLE_HTPROTECTION,
+	/* Quick STA Kickout */
+	WMI_VDEV_PARAM_STA_QUICKKICKOUT,
+	/* Rate to be used with Management frames */
+	WMI_VDEV_PARAM_MGMT_RATE,
+	/* Protection Mode */
+	WMI_VDEV_PARAM_PROTECTION_MODE,
+	/* Fixed rate setting */
+	WMI_VDEV_PARAM_FIXED_RATE,
+	/* Short GI Enable/Disable */
+	WMI_VDEV_PARAM_SGI,
+	/* Enable LDPC */
+	WMI_VDEV_PARAM_LDPC,
+	/* Enable Tx STBC */
+	WMI_VDEV_PARAM_TX_STBC,
+	/* Enable Rx STBC */
+	WMI_VDEV_PARAM_RX_STBC,
+	/* Intra BSS forwarding  */
+	WMI_VDEV_PARAM_INTRA_BSS_FWD,
+	/* Setting Default xmit key for Vdev */
+	WMI_VDEV_PARAM_DEF_KEYID,
+	/* NSS width */
+	WMI_VDEV_PARAM_NSS,
+	/* Set the custom rate for the broadcast data frames */
+	WMI_VDEV_PARAM_BCAST_DATA_RATE,
+	/* Set the custom rate (rate-code) for multicast data frames */
+	WMI_VDEV_PARAM_MCAST_DATA_RATE,
+	/* Tx multicast packet indicate Enable/Disable */
+	WMI_VDEV_PARAM_MCAST_INDICATE,
+	/* Tx DHCP packet indicate Enable/Disable */
+	WMI_VDEV_PARAM_DHCP_INDICATE,
+	/* Enable host inspection of Tx unicast packet to unknown destination */
+	WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
+
+	/* The minimum amount of time AP begins to consider STA inactive */
+	WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
+
+	/*
+	 * An associated STA is considered inactive when there is no recent
+	 * TX/RX activity and no downlink frames are buffered for it. Once a
+	 * STA exceeds the maximum idle inactive time, the AP will send an
+	 * 802.11 data-null as a keep alive to verify the STA is still
+	 * associated. If the STA does ACK the data-null, or if the data-null
+	 * is buffered and the STA does not retrieve it, the STA will be
+	 * considered unresponsive
+	 * (see WMI_VDEV_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS).
+	 */
+	WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
+
+	/*
+	 * An associated STA is considered unresponsive if there is no recent
+	 * TX/RX activity and downlink frames are buffered for it. Once a STA
+	 * exceeds the maximum unresponsive time, the AP will send a
+	 * WMI_STA_KICKOUT event to the host so the STA can be deleted. */
+	WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
+
+	/* Enable NAWDS : MCAST INSPECT Enable, NAWDS Flag set */
+	WMI_VDEV_PARAM_AP_ENABLE_NAWDS,
+	/* Enable/Disable RTS-CTS */
+	WMI_VDEV_PARAM_ENABLE_RTSCTS,
+	/* Enable TXBFee/er */
+	WMI_VDEV_PARAM_TXBF,
+
+	/* Set packet power save */
+	WMI_VDEV_PARAM_PACKET_POWERSAVE,
+
+	/*
+	 * Drops un-encrypted packets if eceived in an encrypted connection
+	 * otherwise forwards to host.
+	 */
+	WMI_VDEV_PARAM_DROP_UNENCRY,
+
+	/*
+	 * Set the encapsulation type for frames.
+	 */
+	WMI_VDEV_PARAM_TX_ENCAP_TYPE,
+};
+
+/* slot time long */
+#define WMI_VDEV_SLOT_TIME_LONG		0x1
+/* slot time short */
+#define WMI_VDEV_SLOT_TIME_SHORT	0x2
+/* preablbe long */
+#define WMI_VDEV_PREAMBLE_LONG		0x1
+/* preablbe short */
+#define WMI_VDEV_PREAMBLE_SHORT		0x2
+
+enum wmi_start_event_param {
+	WMI_VDEV_RESP_START_EVENT = 0,
+	WMI_VDEV_RESP_RESTART_EVENT,
+};
+
+struct wmi_vdev_start_response_event {
+	__le32 vdev_id;
+	__le32 req_id;
+	__le32 resp_type; /* %WMI_VDEV_RESP_ */
+	__le32 status;
+} __packed;
+
+struct wmi_vdev_standby_req_event {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+} __packed;
+
+struct wmi_vdev_resume_req_event {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+} __packed;
+
+struct wmi_vdev_stopped_event {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+} __packed;
+
+/*
+ * common structure used for simple events
+ * (stopped, resume_req, standby response)
+ */
+struct wmi_vdev_simple_event {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+} __packed;
+
+/* VDEV start response status codes */
+/* VDEV succesfully started */
+#define WMI_INIFIED_VDEV_START_RESPONSE_STATUS_SUCCESS	0x0
+
+/* requested VDEV not found */
+#define WMI_INIFIED_VDEV_START_RESPONSE_INVALID_VDEVID	0x1
+
+/* unsupported VDEV combination */
+#define WMI_INIFIED_VDEV_START_RESPONSE_NOT_SUPPORTED	0x2
+
+/* Beacon processing related command and event structures */
+struct wmi_bcn_tx_hdr {
+	__le32 vdev_id;
+	__le32 tx_rate;
+	__le32 tx_power;
+	__le32 bcn_len;
+} __packed;
+
+struct wmi_bcn_tx_cmd {
+	struct wmi_bcn_tx_hdr hdr;
+	u8 *bcn[0];
+} __packed;
+
+struct wmi_bcn_tx_arg {
+	u32 vdev_id;
+	u32 tx_rate;
+	u32 tx_power;
+	u32 bcn_len;
+	const void *bcn;
+};
+
+/* Beacon filter */
+#define WMI_BCN_FILTER_ALL   0 /* Filter all beacons */
+#define WMI_BCN_FILTER_NONE  1 /* Pass all beacons */
+#define WMI_BCN_FILTER_RSSI  2 /* Pass Beacons RSSI >= RSSI threshold */
+#define WMI_BCN_FILTER_BSSID 3 /* Pass Beacons with matching BSSID */
+#define WMI_BCN_FILTER_SSID  4 /* Pass Beacons with matching SSID */
+
+struct wmi_bcn_filter_rx_cmd {
+	/* Filter ID */
+	__le32 bcn_filter_id;
+	/* Filter type - wmi_bcn_filter */
+	__le32 bcn_filter;
+	/* Buffer len */
+	__le32 bcn_filter_len;
+	/* Filter info (threshold, BSSID, RSSI) */
+	u8 *bcn_filter_buf;
+} __packed;
+
+/* Capabilities and IEs to be passed to firmware */
+struct wmi_bcn_prb_info {
+	/* Capabilities */
+	__le32 caps;
+	/* ERP info */
+	__le32 erp;
+	/* Advanced capabilities */
+	/* HT capabilities */
+	/* HT Info */
+	/* ibss_dfs */
+	/* wpa Info */
+	/* rsn Info */
+	/* rrm info */
+	/* ath_ext */
+	/* app IE */
+} __packed;
+
+struct wmi_bcn_tmpl_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+	/* TIM IE offset from the beginning of the template. */
+	__le32 tim_ie_offset;
+	/* beacon probe capabilities and IEs */
+	struct wmi_bcn_prb_info bcn_prb_info;
+	/* beacon buffer length */
+	__le32 buf_len;
+	/* variable length data */
+	u8 data[1];
+} __packed;
+
+struct wmi_prb_tmpl_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+	/* beacon probe capabilities and IEs */
+	struct wmi_bcn_prb_info bcn_prb_info;
+	/* beacon buffer length */
+	__le32 buf_len;
+	/* Variable length data */
+	u8 data[1];
+} __packed;
+
+enum wmi_sta_ps_mode {
+	/* enable power save for the given STA VDEV */
+	WMI_STA_PS_MODE_DISABLED = 0,
+	/* disable power save  for a given STA VDEV */
+	WMI_STA_PS_MODE_ENABLED = 1,
+};
+
+struct wmi_sta_powersave_mode_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+
+	/*
+	 * Power save mode
+	 * (see enum wmi_sta_ps_mode)
+	 */
+	__le32 sta_ps_mode;
+} __packed;
+
+enum wmi_csa_offload_en {
+	WMI_CSA_OFFLOAD_DISABLE = 0,
+	WMI_CSA_OFFLOAD_ENABLE = 1,
+};
+
+struct wmi_csa_offload_enable_cmd {
+	__le32 vdev_id;
+	__le32 csa_offload_enable;
+} __packed;
+
+struct wmi_csa_offload_chanswitch_cmd {
+	__le32 vdev_id;
+	struct wmi_channel chan;
+} __packed;
+
+/*
+ * This parameter controls the policy for retrieving frames from AP while the
+ * STA is in sleep state.
+ *
+ * Only takes affect if the sta_ps_mode is enabled
+ */
+enum wmi_sta_ps_param_rx_wake_policy {
+	/*
+	 * Wake up when ever there is an  RX activity on the VDEV. In this mode
+	 * the Power save SM(state machine) will come out of sleep by either
+	 * sending null frame (or) a data frame (with PS==0) in response to TIM
+	 * bit set in the received beacon frame from AP.
+	 */
+	WMI_STA_PS_RX_WAKE_POLICY_WAKE = 0,
+
+	/*
+	 * Here the power save state machine will not wakeup in response to TIM
+	 * bit, instead it will send a PSPOLL (or) UASPD trigger based on UAPSD
+	 * configuration setup by WMISET_PS_SET_UAPSD  WMI command.  When all
+	 * access categories are delivery-enabled, the station will send a
+	 * UAPSD trigger frame, otherwise it will send a PS-Poll.
+	 */
+	WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD = 1,
+};
+
+/*
+ * Number of tx frames/beacon  that cause the power save SM to wake up.
+ *
+ * Value 1 causes the SM to wake up for every TX. Value 0 has a special
+ * meaning, It will cause the SM to never wake up. This is useful if you want
+ * to keep the system to sleep all the time for some kind of test mode . host
+ * can change this parameter any time.  It will affect at the next tx frame.
+ */
+enum wmi_sta_ps_param_tx_wake_threshold {
+	WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER = 0,
+	WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS = 1,
+
+	/*
+	 * Values greater than one indicate that many TX attempts per beacon
+	 * interval before the STA will wake up
+	 */
+};
+
+/*
+ * The maximum number of PS-Poll frames the FW will send in response to
+ * traffic advertised in TIM before waking up (by sending a null frame with PS
+ * = 0). Value 0 has a special meaning: there is no maximum count and the FW
+ * will send as many PS-Poll as are necessary to retrieve buffered BU. This
+ * parameter is used when the RX wake policy is
+ * WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD and ignored when the RX wake
+ * policy is WMI_STA_PS_RX_WAKE_POLICY_WAKE.
+ */
+enum wmi_sta_ps_param_pspoll_count {
+	WMI_STA_PS_PSPOLL_COUNT_NO_MAX = 0,
+	/*
+	 * Values greater than 0 indicate the maximum numer of PS-Poll frames
+	 * FW will send before waking up.
+	 */
+};
+
+/*
+ * This will include the delivery and trigger enabled state for every AC.
+ * This is the negotiated state with AP. The host MLME needs to set this based
+ * on AP capability and the state Set in the association request by the
+ * station MLME.Lower 8 bits of the value specify the UAPSD configuration.
+ */
+#define WMI_UAPSD_AC_TYPE_DELI 0
+#define WMI_UAPSD_AC_TYPE_TRIG 1
+
+#define WMI_UAPSD_AC_BIT_MASK(ac, type) \
+	((type ==  WMI_UAPSD_AC_TYPE_DELI) ? (1<<(ac<<1)) : (1<<((ac<<1)+1)))
+
+enum wmi_sta_ps_param_uapsd {
+	WMI_STA_PS_UAPSD_AC0_DELIVERY_EN = (1 << 0),
+	WMI_STA_PS_UAPSD_AC0_TRIGGER_EN  = (1 << 1),
+	WMI_STA_PS_UAPSD_AC1_DELIVERY_EN = (1 << 2),
+	WMI_STA_PS_UAPSD_AC1_TRIGGER_EN  = (1 << 3),
+	WMI_STA_PS_UAPSD_AC2_DELIVERY_EN = (1 << 4),
+	WMI_STA_PS_UAPSD_AC2_TRIGGER_EN  = (1 << 5),
+	WMI_STA_PS_UAPSD_AC3_DELIVERY_EN = (1 << 6),
+	WMI_STA_PS_UAPSD_AC3_TRIGGER_EN  = (1 << 7),
+};
+
+enum wmi_sta_powersave_param {
+	/*
+	 * Controls how frames are retrievd from AP while STA is sleeping
+	 *
+	 * (see enum wmi_sta_ps_param_rx_wake_policy)
+	 */
+	WMI_STA_PS_PARAM_RX_WAKE_POLICY = 0,
+
+	/*
+	 * The STA will go active after this many TX
+	 *
+	 * (see enum wmi_sta_ps_param_tx_wake_threshold)
+	 */
+	WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD = 1,
+
+	/*
+	 * Number of PS-Poll to send before STA wakes up
+	 *
+	 * (see enum wmi_sta_ps_param_pspoll_count)
+	 *
+	 */
+	WMI_STA_PS_PARAM_PSPOLL_COUNT = 2,
+
+	/*
+	 * TX/RX inactivity time in msec before going to sleep.
+	 *
+	 * The power save SM will monitor tx/rx activity on the VDEV, if no
+	 * activity for the specified msec of the parameter the Power save
+	 * SM will go to sleep.
+	 */
+	WMI_STA_PS_PARAM_INACTIVITY_TIME = 3,
+
+	/*
+	 * Set uapsd configuration.
+	 *
+	 * (see enum wmi_sta_ps_param_uapsd)
+	 */
+	WMI_STA_PS_PARAM_UAPSD = 4,
+};
+
+struct wmi_sta_powersave_param_cmd {
+	__le32 vdev_id;
+	__le32 param_id; /* %WMI_STA_PS_PARAM_ */
+	__le32 param_value;
+} __packed;
+
+/* No MIMO power save */
+#define WMI_STA_MIMO_PS_MODE_DISABLE
+/* mimo powersave mode static*/
+#define WMI_STA_MIMO_PS_MODE_STATIC
+/* mimo powersave mode dynamic */
+#define WMI_STA_MIMO_PS_MODE_DYNAMIC
+
+struct wmi_sta_mimo_ps_mode_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+	/* mimo powersave mode as defined above */
+	__le32 mimo_pwrsave_mode;
+} __packed;
+
+/* U-APSD configuration of peer station from (re)assoc request and TSPECs */
+enum wmi_ap_ps_param_uapsd {
+	WMI_AP_PS_UAPSD_AC0_DELIVERY_EN = (1 << 0),
+	WMI_AP_PS_UAPSD_AC0_TRIGGER_EN  = (1 << 1),
+	WMI_AP_PS_UAPSD_AC1_DELIVERY_EN = (1 << 2),
+	WMI_AP_PS_UAPSD_AC1_TRIGGER_EN  = (1 << 3),
+	WMI_AP_PS_UAPSD_AC2_DELIVERY_EN = (1 << 4),
+	WMI_AP_PS_UAPSD_AC2_TRIGGER_EN  = (1 << 5),
+	WMI_AP_PS_UAPSD_AC3_DELIVERY_EN = (1 << 6),
+	WMI_AP_PS_UAPSD_AC3_TRIGGER_EN  = (1 << 7),
+};
+
+/* U-APSD maximum service period of peer station */
+enum wmi_ap_ps_peer_param_max_sp {
+	WMI_AP_PS_PEER_PARAM_MAX_SP_UNLIMITED = 0,
+	WMI_AP_PS_PEER_PARAM_MAX_SP_2 = 1,
+	WMI_AP_PS_PEER_PARAM_MAX_SP_4 = 2,
+	WMI_AP_PS_PEER_PARAM_MAX_SP_6 = 3,
+	MAX_WMI_AP_PS_PEER_PARAM_MAX_SP,
+};
+
+/*
+ * AP power save parameter
+ * Set a power save specific parameter for a peer station
+ */
+enum wmi_ap_ps_peer_param {
+	/* Set uapsd configuration for a given peer.
+	 *
+	 * Include the delivery and trigger enabled state for every AC.
+	 * The host  MLME needs to set this based on AP capability and stations
+	 * request Set in the association request  received from the station.
+	 *
+	 * Lower 8 bits of the value specify the UAPSD configuration.
+	 *
+	 * (see enum wmi_ap_ps_param_uapsd)
+	 * The default value is 0.
+	 */
+	WMI_AP_PS_PEER_PARAM_UAPSD = 0,
+
+	/*
+	 * Set the service period for a UAPSD capable station
+	 *
+	 * The service period from wme ie in the (re)assoc request frame.
+	 *
+	 * (see enum wmi_ap_ps_peer_param_max_sp)
+	 */
+	WMI_AP_PS_PEER_PARAM_MAX_SP = 1,
+
+	/* Time in seconds for aging out buffered frames for STA in PS */
+	WMI_AP_PS_PEER_PARAM_AGEOUT_TIME = 2,
+};
+
+struct wmi_ap_ps_peer_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+
+	/* peer MAC address */
+	struct wmi_mac_addr peer_macaddr;
+
+	/* AP powersave param (see enum wmi_ap_ps_peer_param) */
+	__le32 param_id;
+
+	/* AP powersave param value */
+	__le32 param_value;
+} __packed;
+
+/* 128 clients = 4 words */
+#define WMI_TIM_BITMAP_ARRAY_SIZE 4
+
+struct wmi_tim_info {
+	__le32 tim_len;
+	__le32 tim_mcast;
+	__le32 tim_bitmap[WMI_TIM_BITMAP_ARRAY_SIZE];
+	__le32 tim_changed;
+	__le32 tim_num_ps_pending;
+} __packed;
+
+/* Maximum number of NOA Descriptors supported */
+#define WMI_P2P_MAX_NOA_DESCRIPTORS 4
+#define WMI_P2P_OPPPS_ENABLE_BIT	BIT(0)
+#define WMI_P2P_OPPPS_CTWINDOW_OFFSET	1
+#define WMI_P2P_NOA_CHANGED_BIT	BIT(0)
+
+struct wmi_p2p_noa_info {
+	/* Bit 0 - Flag to indicate an update in NOA schedule
+	   Bits 7-1 - Reserved */
+	u8 changed;
+	/* NOA index */
+	u8 index;
+	/* Bit 0 - Opp PS state of the AP
+	   Bits 1-7 - Ctwindow in TUs */
+	u8 ctwindow_oppps;
+	/* Number of NOA descriptors */
+	u8 num_descriptors;
+
+	struct wmi_p2p_noa_descriptor descriptors[WMI_P2P_MAX_NOA_DESCRIPTORS];
+} __packed;
+
+struct wmi_bcn_info {
+	struct wmi_tim_info tim_info;
+	struct wmi_p2p_noa_info p2p_noa_info;
+} __packed;
+
+struct wmi_host_swba_event {
+	__le32 vdev_map;
+	struct wmi_bcn_info bcn_info[1];
+} __packed;
+
+#define WMI_MAX_AP_VDEV 16
+
+struct wmi_tbtt_offset_event {
+	__le32 vdev_map;
+	__le32 tbttoffset_list[WMI_MAX_AP_VDEV];
+} __packed;
+
+
+struct wmi_peer_create_cmd {
+	__le32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+} __packed;
+
+struct wmi_peer_delete_cmd {
+	__le32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+} __packed;
+
+struct wmi_peer_flush_tids_cmd {
+	__le32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+	__le32 peer_tid_bitmap;
+} __packed;
+
+struct wmi_fixed_rate {
+	/*
+	 * rate mode . 0: disable fixed rate (auto rate)
+	 *   1: legacy (non 11n) rate  specified as ieee rate 2*Mbps
+	 *   2: ht20 11n rate  specified as mcs index
+	 *   3: ht40 11n rate  specified as mcs index
+	 */
+	__le32  rate_mode;
+	/*
+	 * 4 rate values for 4 rate series. series 0 is stored in byte 0 (LSB)
+	 * and series 3 is stored at byte 3 (MSB)
+	 */
+	__le32  rate_series;
+	/*
+	 * 4 retry counts for 4 rate series. retry count for rate 0 is stored
+	 * in byte 0 (LSB) and retry count for rate 3 is stored at byte 3
+	 * (MSB)
+	 */
+	__le32  rate_retries;
+} __packed;
+
+struct wmi_peer_fixed_rate_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+	/* peer MAC address */
+	struct wmi_mac_addr peer_macaddr;
+	/* fixed rate */
+	struct wmi_fixed_rate peer_fixed_rate;
+} __packed;
+
+#define WMI_MGMT_TID    17
+
+struct wmi_addba_clear_resp_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+	/* peer MAC address */
+	struct wmi_mac_addr peer_macaddr;
+} __packed;
+
+struct wmi_addba_send_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+	/* peer MAC address */
+	struct wmi_mac_addr peer_macaddr;
+	/* Tid number */
+	__le32 tid;
+	/* Buffer/Window size*/
+	__le32 buffersize;
+} __packed;
+
+struct wmi_delba_send_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+	/* peer MAC address */
+	struct wmi_mac_addr peer_macaddr;
+	/* Tid number */
+	__le32 tid;
+	/* Is Initiator */
+	__le32 initiator;
+	/* Reason code */
+	__le32 reasoncode;
+} __packed;
+
+struct wmi_addba_setresponse_cmd {
+	/* unique id identifying the vdev, generated by the caller */
+	__le32 vdev_id;
+	/* peer mac address */
+	struct wmi_mac_addr peer_macaddr;
+	/* Tid number */
+	__le32 tid;
+	/* status code */
+	__le32 statuscode;
+} __packed;
+
+struct wmi_send_singleamsdu_cmd {
+	/* unique id identifying the vdev, generated by the caller */
+	__le32 vdev_id;
+	/* peer mac address */
+	struct wmi_mac_addr peer_macaddr;
+	/* Tid number */
+	__le32 tid;
+} __packed;
+
+enum wmi_peer_smps_state {
+	WMI_PEER_SMPS_PS_NONE = 0x0,
+	WMI_PEER_SMPS_STATIC  = 0x1,
+	WMI_PEER_SMPS_DYNAMIC = 0x2
+};
+
+enum wmi_peer_param {
+	WMI_PEER_SMPS_STATE = 0x1, /* see %wmi_peer_smps_state */
+	WMI_PEER_AMPDU      = 0x2,
+	WMI_PEER_AUTHORIZE  = 0x3,
+	WMI_PEER_CHAN_WIDTH = 0x4,
+	WMI_PEER_NSS        = 0x5,
+	WMI_PEER_USE_4ADDR  = 0x6
+};
+
+struct wmi_peer_set_param_cmd {
+	__le32 vdev_id;
+	struct wmi_mac_addr peer_macaddr;
+	__le32 param_id;
+	__le32 param_value;
+} __packed;
+
+#define MAX_SUPPORTED_RATES 128
+
+struct wmi_rate_set {
+	/* total number of rates */
+	__le32 num_rates;
+	/*
+	 * rates (each 8bit value) packed into a 32 bit word.
+	 * the rates are filled from least significant byte to most
+	 * significant byte.
+	 */
+	__le32 rates[(MAX_SUPPORTED_RATES/4)+1];
+} __packed;
+
+struct wmi_rate_set_arg {
+	unsigned int num_rates;
+	u8 rates[MAX_SUPPORTED_RATES];
+};
+
+/*
+ * NOTE: It would bea good idea to represent the Tx MCS
+ * info in one word and Rx in another word. This is split
+ * into multiple words for convenience
+ */
+struct wmi_vht_rate_set {
+	__le32 rx_max_rate; /* Max Rx data rate */
+	__le32 rx_mcs_set;  /* Negotiated RX VHT rates */
+	__le32 tx_max_rate; /* Max Tx data rate */
+	__le32 tx_mcs_set;  /* Negotiated TX VHT rates */
+} __packed;
+
+struct wmi_vht_rate_set_arg {
+	u32 rx_max_rate;
+	u32 rx_mcs_set;
+	u32 tx_max_rate;
+	u32 tx_mcs_set;
+};
+
+struct wmi_peer_set_rates_cmd {
+	/* peer MAC address */
+	struct wmi_mac_addr peer_macaddr;
+	/* legacy rate set */
+	struct wmi_rate_set peer_legacy_rates;
+	/* ht rate set */
+	struct wmi_rate_set peer_ht_rates;
+} __packed;
+
+struct wmi_peer_set_q_empty_callback_cmd {
+	/* unique id identifying the VDEV, generated by the caller */
+	__le32 vdev_id;
+	/* peer MAC address */
+	struct wmi_mac_addr peer_macaddr;
+	__le32 callback_enable;
+} __packed;
+
+#define WMI_PEER_AUTH           0x00000001
+#define WMI_PEER_QOS            0x00000002
+#define WMI_PEER_NEED_PTK_4_WAY 0x00000004
+#define WMI_PEER_NEED_GTK_2_WAY 0x00000010
+#define WMI_PEER_APSD           0x00000800
+#define WMI_PEER_HT             0x00001000
+#define WMI_PEER_40MHZ          0x00002000
+#define WMI_PEER_STBC           0x00008000
+#define WMI_PEER_LDPC           0x00010000
+#define WMI_PEER_DYN_MIMOPS     0x00020000
+#define WMI_PEER_STATIC_MIMOPS  0x00040000
+#define WMI_PEER_SPATIAL_MUX    0x00200000
+#define WMI_PEER_VHT            0x02000000
+#define WMI_PEER_80MHZ          0x04000000
+#define WMI_PEER_PMF            0x08000000
+
+/*
+ * Peer rate capabilities.
+ *
+ * This is of interest to the ratecontrol
+ * module which resides in the firmware. The bit definitions are
+ * consistent with that defined in if_athrate.c.
+ */
+#define WMI_RC_DS_FLAG          0x01
+#define WMI_RC_CW40_FLAG        0x02
+#define WMI_RC_SGI_FLAG         0x04
+#define WMI_RC_HT_FLAG          0x08
+#define WMI_RC_RTSCTS_FLAG      0x10
+#define WMI_RC_TX_STBC_FLAG     0x20
+#define WMI_RC_RX_STBC_FLAG     0xC0
+#define WMI_RC_RX_STBC_FLAG_S   6
+#define WMI_RC_WEP_TKIP_FLAG    0x100
+#define WMI_RC_TS_FLAG          0x200
+#define WMI_RC_UAPSD_FLAG       0x400
+
+/* Maximum listen interval supported by hw in units of beacon interval */
+#define ATH10K_MAX_HW_LISTEN_INTERVAL 5
+
+struct wmi_peer_assoc_complete_cmd {
+	struct wmi_mac_addr peer_macaddr;
+	__le32 vdev_id;
+	__le32 peer_new_assoc; /* 1=assoc, 0=reassoc */
+	__le32 peer_associd; /* 16 LSBs */
+	__le32 peer_flags;
+	__le32 peer_caps; /* 16 LSBs */
+	__le32 peer_listen_intval;
+	__le32 peer_ht_caps;
+	__le32 peer_max_mpdu;
+	__le32 peer_mpdu_density; /* 0..16 */
+	__le32 peer_rate_caps;
+	struct wmi_rate_set peer_legacy_rates;
+	struct wmi_rate_set peer_ht_rates;
+	__le32 peer_nss; /* num of spatial streams */
+	__le32 peer_vht_caps;
+	__le32 peer_phymode;
+	struct wmi_vht_rate_set peer_vht_rates;
+	/* HT Operation Element of the peer. Five bytes packed in 2
+	 *  INT32 array and filled from lsb to msb. */
+	__le32 peer_ht_info[2];
+} __packed;
+
+struct wmi_peer_assoc_complete_arg {
+	u8 addr[ETH_ALEN];
+	u32 vdev_id;
+	bool peer_reassoc;
+	u16 peer_aid;
+	u32 peer_flags; /* see %WMI_PEER_ */
+	u16 peer_caps;
+	u32 peer_listen_intval;
+	u32 peer_ht_caps;
+	u32 peer_max_mpdu;
+	u32 peer_mpdu_density; /* 0..16 */
+	u32 peer_rate_caps; /* see %WMI_RC_ */
+	struct wmi_rate_set_arg peer_legacy_rates;
+	struct wmi_rate_set_arg peer_ht_rates;
+	u32 peer_num_spatial_streams;
+	u32 peer_vht_caps;
+	enum wmi_phy_mode peer_phymode;
+	struct wmi_vht_rate_set_arg peer_vht_rates;
+};
+
+struct wmi_peer_add_wds_entry_cmd {
+	/* peer MAC address */
+	struct wmi_mac_addr peer_macaddr;
+	/* wds MAC addr */
+	struct wmi_mac_addr wds_macaddr;
+} __packed;
+
+struct wmi_peer_remove_wds_entry_cmd {
+	/* wds MAC addr */
+	struct wmi_mac_addr wds_macaddr;
+} __packed;
+
+struct wmi_peer_q_empty_callback_event {
+	/* peer MAC address */
+	struct wmi_mac_addr peer_macaddr;
+} __packed;
+
+/*
+ * Channel info WMI event
+ */
+struct wmi_chan_info_event {
+	__le32 err_code;
+	__le32 freq;
+	__le32 cmd_flags;
+	__le32 noise_floor;
+	__le32 rx_clear_count;
+	__le32 cycle_count;
+} __packed;
+
+/* Beacon filter wmi command info */
+#define BCN_FLT_MAX_SUPPORTED_IES	256
+#define BCN_FLT_MAX_ELEMS_IE_LIST	(BCN_FLT_MAX_SUPPORTED_IES / 32)
+
+struct bss_bcn_stats {
+	__le32 vdev_id;
+	__le32 bss_bcnsdropped;
+	__le32 bss_bcnsdelivered;
+} __packed;
+
+struct bcn_filter_stats {
+	__le32 bcns_dropped;
+	__le32 bcns_delivered;
+	__le32 activefilters;
+	struct bss_bcn_stats bss_stats;
+} __packed;
+
+struct wmi_add_bcn_filter_cmd {
+	u32 vdev_id;
+	u32 ie_map[BCN_FLT_MAX_ELEMS_IE_LIST];
+} __packed;
+
+enum wmi_sta_keepalive_method {
+	WMI_STA_KEEPALIVE_METHOD_NULL_FRAME = 1,
+	WMI_STA_KEEPALIVE_METHOD_UNSOLICITATED_ARP_RESPONSE = 2,
+};
+
+/* note: ip4 addresses are in network byte order, i.e. big endian */
+struct wmi_sta_keepalive_arp_resp {
+	__be32 src_ip4_addr;
+	__be32 dest_ip4_addr;
+	struct wmi_mac_addr dest_mac_addr;
+} __packed;
+
+struct wmi_sta_keepalive_cmd {
+	__le32 vdev_id;
+	__le32 enabled;
+	__le32 method; /* WMI_STA_KEEPALIVE_METHOD_ */
+	__le32 interval; /* in seconds */
+	struct wmi_sta_keepalive_arp_resp arp_resp;
+} __packed;
+
+#define ATH10K_RTS_MAX		2347
+#define ATH10K_FRAGMT_THRESHOLD_MIN	540
+#define ATH10K_FRAGMT_THRESHOLD_MAX	2346
+
+#define WMI_MAX_EVENT 0x1000
+/* Maximum number of pending TXed WMI packets */
+#define WMI_MAX_PENDING_TX_COUNT 128
+#define WMI_SKB_HEADROOM sizeof(struct wmi_cmd_hdr)
+
+/* By default disable power save for IBSS */
+#define ATH10K_DEFAULT_ATIM 0
+
+struct ath10k;
+struct ath10k_vif;
+
+int ath10k_wmi_attach(struct ath10k *ar);
+void ath10k_wmi_detach(struct ath10k *ar);
+int ath10k_wmi_wait_for_service_ready(struct ath10k *ar);
+int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
+void ath10k_wmi_flush_tx(struct ath10k *ar);
+
+int ath10k_wmi_connect_htc_service(struct ath10k *ar);
+int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
+				const struct wmi_channel_arg *);
+int ath10k_wmi_pdev_suspend_target(struct ath10k *ar);
+int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
+int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
+				  u16 rd5g, u16 ctl2g, u16 ctl5g);
+int ath10k_wmi_pdev_set_param(struct ath10k *ar, enum wmi_pdev_param id,
+			      u32 value);
+int ath10k_wmi_cmd_init(struct ath10k *ar);
+int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *);
+void ath10k_wmi_start_scan_init(struct ath10k *ar, struct wmi_start_scan_arg *);
+int ath10k_wmi_stop_scan(struct ath10k *ar,
+			 const struct wmi_stop_scan_arg *arg);
+int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
+			   enum wmi_vdev_type type,
+			   enum wmi_vdev_subtype subtype,
+			   const u8 macaddr[ETH_ALEN]);
+int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id);
+int ath10k_wmi_vdev_start(struct ath10k *ar,
+			  const struct wmi_vdev_start_request_arg *);
+int ath10k_wmi_vdev_restart(struct ath10k *ar,
+			    const struct wmi_vdev_start_request_arg *);
+int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id);
+int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
+		       const u8 *bssid);
+int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id);
+int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id,
+			      enum wmi_vdev_param param_id, u32 param_value);
+int ath10k_wmi_vdev_install_key(struct ath10k *ar,
+				const struct wmi_vdev_install_key_arg *arg);
+int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
+		    const u8 peer_addr[ETH_ALEN]);
+int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
+		    const u8 peer_addr[ETH_ALEN]);
+int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
+		   const u8 peer_addr[ETH_ALEN], u32 tid_bitmap);
+int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id,
+			      const u8 *peer_addr,
+			      enum wmi_peer_param param_id, u32 param_value);
+int ath10k_wmi_peer_assoc(struct ath10k *ar,
+			  const struct wmi_peer_assoc_complete_arg *arg);
+int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id,
+			  enum wmi_sta_ps_mode psmode);
+int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id,
+				enum wmi_sta_powersave_param param_id,
+				u32 value);
+int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
+			       enum wmi_ap_ps_peer_param param_id, u32 value);
+int ath10k_wmi_scan_chan_list(struct ath10k *ar,
+			      const struct wmi_scan_chan_list_arg *arg);
+int ath10k_wmi_beacon_send(struct ath10k *ar, const struct wmi_bcn_tx_arg *arg);
+int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
+			const struct wmi_pdev_set_wmm_params_arg *arg);
+int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id);
+
+#endif /* _WMI_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath5k/ahb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath5k/ahb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath5k/ahb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath5k/ahb.c	2013-08-25 20:43:22.000000000 -0400
@@ -185,7 +185,6 @@ static int ath_ahb_probe(struct platform
 
  err_free_hw:
 	ieee80211_free_hw(hw);
-	platform_set_drvdata(pdev, NULL);
  err_iounmap:
         iounmap(mem);
  err_out:
@@ -221,7 +220,6 @@ static int ath_ahb_remove(struct platfor
 
 	ath5k_deinit_ah(ah);
 	iounmap(ah->iobase);
-	platform_set_drvdata(pdev, NULL);
 	ieee80211_free_hw(hw);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath5k/base.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath5k/base.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath5k/base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath5k/base.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,6 +60,7 @@
 
 #include <asm/unaligned.h>
 
+#include <net/mac80211.h>
 #include "base.h"
 #include "reg.h"
 #include "debug.h"
@@ -666,9 +667,46 @@ static enum ath5k_pkt_type get_hw_packet
 	return htype;
 }
 
+static struct ieee80211_rate *
+ath5k_get_rate(const struct ieee80211_hw *hw,
+	       const struct ieee80211_tx_info *info,
+	       struct ath5k_buf *bf, int idx)
+{
+	/*
+	* convert a ieee80211_tx_rate RC-table entry to
+	* the respective ieee80211_rate struct
+	*/
+	if (bf->rates[idx].idx < 0) {
+		return NULL;
+	}
+
+	return &hw->wiphy->bands[info->band]->bitrates[ bf->rates[idx].idx ];
+}
+
+static u16
+ath5k_get_rate_hw_value(const struct ieee80211_hw *hw,
+			const struct ieee80211_tx_info *info,
+			struct ath5k_buf *bf, int idx)
+{
+	struct ieee80211_rate *rate;
+	u16 hw_rate;
+	u8 rc_flags;
+
+	rate = ath5k_get_rate(hw, info, bf, idx);
+	if (!rate)
+		return 0;
+
+	rc_flags = bf->rates[idx].flags;
+	hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+		   rate->hw_value_short : rate->hw_value;
+
+	return hw_rate;
+}
+
 static int
 ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
-		  struct ath5k_txq *txq, int padsize)
+		  struct ath5k_txq *txq, int padsize,
+		  struct ieee80211_tx_control *control)
 {
 	struct ath5k_desc *ds = bf->desc;
 	struct sk_buff *skb = bf->skb;
@@ -688,7 +726,11 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, s
 	bf->skbaddr = dma_map_single(ah->dev, skb->data, skb->len,
 			DMA_TO_DEVICE);
 
-	rate = ieee80211_get_tx_rate(ah->hw, info);
+	ieee80211_get_tx_rates(info->control.vif, (control) ? control->sta : NULL, skb, bf->rates,
+			       ARRAY_SIZE(bf->rates));
+
+	rate = ath5k_get_rate(ah->hw, info, bf, 0);
+
 	if (!rate) {
 		ret = -EINVAL;
 		goto err_unmap;
@@ -698,8 +740,8 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, s
 		flags |= AR5K_TXDESC_NOACK;
 
 	rc_flags = info->control.rates[0].flags;
-	hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
-		rate->hw_value_short : rate->hw_value;
+
+	hw_rate = ath5k_get_rate_hw_value(ah->hw, info, bf, 0);
 
 	pktlen = skb->len;
 
@@ -722,12 +764,13 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, s
 		duration = le16_to_cpu(ieee80211_ctstoself_duration(ah->hw,
 			info->control.vif, pktlen, info));
 	}
+
 	ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
 		ieee80211_get_hdrlen_from_skb(skb), padsize,
 		get_hw_packet_type(skb),
 		(ah->ah_txpower.txp_requested * 2),
 		hw_rate,
-		info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
+		bf->rates[0].count, keyidx, ah->ah_tx_ant, flags,
 		cts_rate, duration);
 	if (ret)
 		goto err_unmap;
@@ -736,13 +779,15 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, s
 	if (ah->ah_capabilities.cap_has_mrr_support) {
 		memset(mrr_rate, 0, sizeof(mrr_rate));
 		memset(mrr_tries, 0, sizeof(mrr_tries));
+
 		for (i = 0; i < 3; i++) {
-			rate = ieee80211_get_alt_retry_rate(ah->hw, info, i);
+
+			rate = ath5k_get_rate(ah->hw, info, bf, i);
 			if (!rate)
 				break;
 
-			mrr_rate[i] = rate->hw_value;
-			mrr_tries[i] = info->control.rates[i + 1].count;
+			mrr_rate[i] = ath5k_get_rate_hw_value(ah->hw, info, bf, i);
+			mrr_tries[i] = bf->rates[i].count;
 		}
 
 		ath5k_hw_setup_mrr_tx_desc(ah, ds,
@@ -1515,7 +1560,7 @@ unlock:
 
 void
 ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
-	       struct ath5k_txq *txq)
+	       struct ath5k_txq *txq, struct ieee80211_tx_control *control)
 {
 	struct ath5k_hw *ah = hw->priv;
 	struct ath5k_buf *bf;
@@ -1555,7 +1600,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw,
 
 	bf->skb = skb;
 
-	if (ath5k_txbuf_setup(ah, bf, txq, padsize)) {
+	if (ath5k_txbuf_setup(ah, bf, txq, padsize, control)) {
 		bf->skb = NULL;
 		spin_lock_irqsave(&ah->txbuflock, flags);
 		list_add_tail(&bf->list, &ah->txbuf);
@@ -1571,11 +1616,13 @@ drop_packet:
 
 static void
 ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
-			 struct ath5k_txq *txq, struct ath5k_tx_status *ts)
+			 struct ath5k_txq *txq, struct ath5k_tx_status *ts,
+			 struct ath5k_buf *bf)
 {
 	struct ieee80211_tx_info *info;
 	u8 tries[3];
 	int i;
+	int size = 0;
 
 	ah->stats.tx_all_count++;
 	ah->stats.tx_bytes_count += skb->len;
@@ -1587,6 +1634,9 @@ ath5k_tx_frame_completed(struct ath5k_hw
 
 	ieee80211_tx_info_clear_status(info);
 
+	size = min_t(int, sizeof(info->status.rates), sizeof(bf->rates));
+	memcpy(info->status.rates, bf->rates, size);
+
 	for (i = 0; i < ts->ts_final_idx; i++) {
 		struct ieee80211_tx_rate *r =
 			&info->status.rates[i];
@@ -1663,7 +1713,7 @@ ath5k_tx_processq(struct ath5k_hw *ah, s
 
 			dma_unmap_single(ah->dev, bf->skbaddr, skb->len,
 					DMA_TO_DEVICE);
-			ath5k_tx_frame_completed(ah, skb, txq, &ts);
+			ath5k_tx_frame_completed(ah, skb, txq, &ts, bf);
 		}
 
 		/*
@@ -1917,7 +1967,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
 
 	skb = ieee80211_get_buffered_bc(ah->hw, vif);
 	while (skb) {
-		ath5k_tx_queue(ah->hw, skb, ah->cabq);
+		ath5k_tx_queue(ah->hw, skb, ah->cabq, NULL);
 
 		if (ah->cabq->txq_len >= ah->cabq->txq_max)
 			break;
@@ -2442,7 +2492,8 @@ ath5k_init_ah(struct ath5k_hw *ah, const
 			IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
 			IEEE80211_HW_SIGNAL_DBM |
 			IEEE80211_HW_MFP_CAPABLE |
-			IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+			IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+			IEEE80211_HW_SUPPORTS_RC_TABLE;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_AP) |
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath5k/base.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath5k/base.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath5k/base.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath5k/base.h	2013-08-25 20:43:22.000000000 -0400
@@ -47,6 +47,7 @@ struct ath5k_hw;
 struct ath5k_txq;
 struct ieee80211_channel;
 struct ath_bus_ops;
+struct ieee80211_tx_control;
 enum nl80211_iftype;
 
 enum ath5k_srev_type {
@@ -61,11 +62,12 @@ struct ath5k_srev_name {
 };
 
 struct ath5k_buf {
-	struct list_head	list;
-	struct ath5k_desc	*desc;	/* virtual addr of desc */
-	dma_addr_t		daddr;	/* physical addr of desc */
-	struct sk_buff		*skb;	/* skbuff for buf */
-	dma_addr_t		skbaddr;/* physical addr of skb data */
+	struct list_head		list;
+	struct ath5k_desc		*desc;		/* virtual addr of desc */
+	dma_addr_t			daddr;		/* physical addr of desc */
+	struct sk_buff			*skb;		/* skbuff for buf */
+	dma_addr_t			skbaddr;	/* physical addr of skb data */
+	struct ieee80211_tx_rate	rates[4];	/* number of multi-rate stages */
 };
 
 struct ath5k_vif {
@@ -103,7 +105,7 @@ int ath5k_chan_set(struct ath5k_hw *ah,
 void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
 void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
 void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
-		    struct ath5k_txq *txq);
+		    struct ath5k_txq *txq, struct ieee80211_tx_control *control);
 
 const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath5k/mac80211-ops.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath5k/mac80211-ops.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath5k/mac80211-ops.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath5k/mac80211-ops.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,7 +66,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct
 		return;
 	}
 
-	ath5k_tx_queue(hw, skb, &ah->txqs[qnum]);
+	ath5k_tx_queue(hw, skb, &ah->txqs[qnum], control);
 }
 
 
@@ -325,7 +325,7 @@ ath5k_prepare_multicast(struct ieee80211
 	struct netdev_hw_addr *ha;
 
 	mfilt[0] = 0;
-	mfilt[1] = 1;
+	mfilt[1] = 0;
 
 	netdev_hw_addr_list_for_each(ha, mc_list) {
 		/* calculate XOR of eight 6-bit values */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/cfg80211.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/cfg80211.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/cfg80211.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/cfg80211.c	2013-08-25 20:43:22.000000000 -0400
@@ -3175,10 +3175,21 @@ static int ath6kl_mgmt_tx(struct wiphy *
 {
 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
 	struct ath6kl *ar = ath6kl_priv(vif->ndev);
-	u32 id;
+	u32 id, freq;
 	const struct ieee80211_mgmt *mgmt;
 	bool more_data, queued;
 
+	/* default to the current channel, but use the one specified as argument
+	 * if any
+	 */
+	freq = vif->ch_hint;
+	if (chan)
+		freq = chan->center_freq;
+
+	/* never send freq zero to the firmware */
+	if (WARN_ON(freq == 0))
+		return -EINVAL;
+
 	mgmt = (const struct ieee80211_mgmt *) buf;
 	if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
 	    ieee80211_is_probe_resp(mgmt->frame_control) &&
@@ -3188,8 +3199,7 @@ static int ath6kl_mgmt_tx(struct wiphy *
 		 * command to allow the target to fill in the generic IEs.
 		 */
 		*cookie = 0; /* TX status not supported */
-		return ath6kl_send_go_probe_resp(vif, buf, len,
-						 chan->center_freq);
+		return ath6kl_send_go_probe_resp(vif, buf, len, freq);
 	}
 
 	id = vif->send_action_id++;
@@ -3205,17 +3215,14 @@ static int ath6kl_mgmt_tx(struct wiphy *
 
 	/* AP mode Power saving processing */
 	if (vif->nw_type == AP_NETWORK) {
-		queued = ath6kl_mgmt_powersave_ap(vif,
-					id, chan->center_freq,
-					wait, buf,
-					len, &more_data, no_cck);
+		queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
+						  &more_data, no_cck);
 		if (queued)
 			return 0;
 	}
 
-	return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id,
-					chan->center_freq, wait,
-					buf, len, no_cck);
+	return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
+					wait, buf, len, no_cck);
 }
 
 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
@@ -3679,6 +3686,20 @@ err:
 	return NULL;
 }
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
+	.flags = WIPHY_WOWLAN_MAGIC_PKT |
+		 WIPHY_WOWLAN_DISCONNECT |
+		 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
+		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+		 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
+		 WIPHY_WOWLAN_4WAY_HANDSHAKE,
+	.n_patterns = WOW_MAX_FILTERS_PER_LIST,
+	.pattern_min_len = 1,
+	.pattern_max_len = WOW_PATTERN_SIZE,
+};
+#endif
+
 int ath6kl_cfg80211_init(struct ath6kl *ar)
 {
 	struct wiphy *wiphy = ar->wiphy;
@@ -3772,15 +3793,7 @@ int ath6kl_cfg80211_init(struct ath6kl *
 	wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 
 #ifdef CONFIG_PM
-	wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-			      WIPHY_WOWLAN_DISCONNECT |
-			      WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
-			      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
-			      WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
-			      WIPHY_WOWLAN_4WAY_HANDSHAKE;
-	wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
-	wiphy->wowlan.pattern_min_len = 1;
-	wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
+	wiphy->wowlan = &ath6kl_wowlan_support;
 #endif
 
 	wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/debug.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/debug.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -1240,20 +1240,14 @@ static ssize_t ath6kl_force_roam_write(s
 	char buf[20];
 	size_t len;
 	u8 bssid[ETH_ALEN];
-	int i;
-	int addr[ETH_ALEN];
 
 	len = min(count, sizeof(buf) - 1);
 	if (copy_from_user(buf, user_buf, len))
 		return -EFAULT;
 	buf[len] = '\0';
 
-	if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
-		   &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5])
-	    != ETH_ALEN)
+	if (!mac_pton(buf, bssid))
 		return -EINVAL;
-	for (i = 0; i < ETH_ALEN; i++)
-		bssid[i] = addr[i];
 
 	ret = ath6kl_wmi_force_roam_cmd(ar->wmi, bssid);
 	if (ret)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/init.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/init.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/init.c	2013-07-01 10:39:42.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/init.c	2013-08-31 17:59:17.000000000 -0400
@@ -1693,10 +1693,16 @@ static int __ath6kl_init_hw_start(struct
 						    test_bit(WMI_READY,
 							     &ar->flag),
 						    WMI_TIMEOUT);
+	if (timeleft <= 0) {
+		clear_bit(WMI_READY, &ar->flag);
+		ath6kl_err("wmi is not ready or wait was interrupted: %ld\n",
+			   timeleft);
+		ret = -EIO;
+		goto err_htc_stop;
+	}
 
 	ath6kl_dbg(ATH6KL_DBG_BOOT, "firmware booted\n");
 
-
 	if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) {
 		ath6kl_info("%s %s fw %s api %d%s\n",
 			    ar->hw.name,
@@ -1714,12 +1720,6 @@ static int __ath6kl_init_hw_start(struct
 		ret = -EIO;
 		goto err_htc_stop;
 	}
-
-	if (!timeleft || signal_pending(current)) {
-		ath6kl_err("wmi is not ready or wait was interrupted\n");
-		ret = -EIO;
-		goto err_htc_stop;
-	}
 
 	ath6kl_dbg(ATH6KL_DBG_TRC, "%s: wmi is ready\n", __func__);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/sdio.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/sdio.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/sdio.c	2013-07-01 10:39:46.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/sdio.c	2013-08-31 17:59:22.000000000 -0400
@@ -345,17 +345,17 @@ static int ath6kl_sdio_alloc_prep_scat_r
 {
 	struct hif_scatter_req *s_req;
 	struct bus_request *bus_req;
-	int i, scat_req_sz, scat_list_sz, sg_sz, buf_sz;
+	int i, scat_req_sz, scat_list_sz, size;
 	u8 *virt_buf;
 
 	scat_list_sz = (n_scat_entry - 1) * sizeof(struct hif_scatter_item);
 	scat_req_sz = sizeof(*s_req) + scat_list_sz;
 
 	if (!virt_scat)
-		sg_sz = sizeof(struct scatterlist) * n_scat_entry;
+		size = sizeof(struct scatterlist) * n_scat_entry;
 	else
-		buf_sz =  2 * L1_CACHE_BYTES +
-			  ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
+		size =  2 * L1_CACHE_BYTES +
+			ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
 
 	for (i = 0; i < n_scat_req; i++) {
 		/* allocate the scatter request */
@@ -364,7 +364,7 @@ static int ath6kl_sdio_alloc_prep_scat_r
 			return -ENOMEM;
 
 		if (virt_scat) {
-			virt_buf = kzalloc(buf_sz, GFP_KERNEL);
+			virt_buf = kzalloc(size, GFP_KERNEL);
 			if (!virt_buf) {
 				kfree(s_req);
 				return -ENOMEM;
@@ -374,7 +374,7 @@ static int ath6kl_sdio_alloc_prep_scat_r
 				(u8 *)L1_CACHE_ALIGN((unsigned long)virt_buf);
 		} else {
 			/* allocate sglist */
-			s_req->sgentries = kzalloc(sg_sz, GFP_KERNEL);
+			s_req->sgentries = kzalloc(size, GFP_KERNEL);
 
 			if (!s_req->sgentries) {
 				kfree(s_req);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/usb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/usb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath6kl/usb.c	2013-07-01 10:39:48.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath6kl/usb.c	2013-08-31 17:59:24.000000000 -0400
@@ -1061,6 +1061,22 @@ static void ath6kl_usb_cleanup_scatter(s
 	return;
 }
 
+static int ath6kl_usb_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+{
+	/*
+	 * cfg80211 suspend/WOW currently not supported for USB.
+	 */
+	return 0;
+}
+
+static int ath6kl_usb_resume(struct ath6kl *ar)
+{
+	/*
+	 * cfg80211 resume currently not supported for USB.
+	 */
+	return 0;
+}
+
 static const struct ath6kl_hif_ops ath6kl_usb_ops = {
 	.diag_read32 = ath6kl_usb_diag_read32,
 	.diag_write32 = ath6kl_usb_diag_write32,
@@ -1074,6 +1090,8 @@ static const struct ath6kl_hif_ops ath6k
 	.pipe_map_service = ath6kl_usb_map_service_pipe,
 	.pipe_get_free_queue_number = ath6kl_usb_get_free_queue_number,
 	.cleanup_scatter = ath6kl_usb_cleanup_scatter,
+	.suspend = ath6kl_usb_suspend,
+	.resume = ath6kl_usb_resume,
 };
 
 /* ath6kl usb driver registered functions */
@@ -1152,7 +1170,7 @@ static void ath6kl_usb_remove(struct usb
 
 #ifdef CONFIG_PM
 
-static int ath6kl_usb_suspend(struct usb_interface *interface,
+static int ath6kl_usb_pm_suspend(struct usb_interface *interface,
 			      pm_message_t message)
 {
 	struct ath6kl_usb *device;
@@ -1162,7 +1180,7 @@ static int ath6kl_usb_suspend(struct usb
 	return 0;
 }
 
-static int ath6kl_usb_resume(struct usb_interface *interface)
+static int ath6kl_usb_pm_resume(struct usb_interface *interface)
 {
 	struct ath6kl_usb *device;
 	device = usb_get_intfdata(interface);
@@ -1175,7 +1193,7 @@ static int ath6kl_usb_resume(struct usb_
 	return 0;
 }
 
-static int ath6kl_usb_reset_resume(struct usb_interface *intf)
+static int ath6kl_usb_pm_reset_resume(struct usb_interface *intf)
 {
 	if (usb_get_intfdata(intf))
 		ath6kl_usb_remove(intf);
@@ -1184,9 +1202,9 @@ static int ath6kl_usb_reset_resume(struc
 
 #else
 
-#define ath6kl_usb_suspend NULL
-#define ath6kl_usb_resume NULL
-#define ath6kl_usb_reset_resume NULL
+#define ath6kl_usb_pm_suspend NULL
+#define ath6kl_usb_pm_resume NULL
+#define ath6kl_usb_pm_reset_resume NULL
 
 #endif
 
@@ -1201,9 +1219,9 @@ MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids)
 static struct usb_driver ath6kl_usb_driver = {
 	.name = "ath6kl_usb",
 	.probe = ath6kl_usb_probe,
-	.suspend = ath6kl_usb_suspend,
-	.resume = ath6kl_usb_resume,
-	.reset_resume = ath6kl_usb_reset_resume,
+	.suspend = ath6kl_usb_pm_suspend,
+	.resume = ath6kl_usb_pm_resume,
+	.reset_resume = ath6kl_usb_pm_reset_resume,
 	.disconnect = ath6kl_usb_remove,
 	.id_table = ath6kl_usb_ids,
 	.supports_autosuspend = true,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ahb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ahb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ahb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ahb.c	2013-08-25 20:43:22.000000000 -0400
@@ -150,7 +150,6 @@ static int ath_ahb_probe(struct platform
 	free_irq(irq, sc);
  err_free_hw:
 	ieee80211_free_hw(hw);
-	platform_set_drvdata(pdev, NULL);
 	return ret;
 }
 
@@ -164,7 +163,6 @@ static int ath_ahb_remove(struct platfor
 		ath9k_deinit_device(sc);
 		free_irq(sc->irq, sc);
 		ieee80211_free_hw(sc->hw);
-		platform_set_drvdata(pdev, NULL);
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ani.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ani.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ani.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ani.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,8 +46,8 @@ static const struct ani_ofdm_level_entry
 	{  5,  4,  1  }, /* lvl 5 */
 	{  6,  5,  1  }, /* lvl 6 */
 	{  7,  6,  1  }, /* lvl 7 */
-	{  7,  6,  0  }, /* lvl 8 */
-	{  7,  7,  0  }  /* lvl 9 */
+	{  7,  7,  1  }, /* lvl 8 */
+	{  7,  8,  0  }  /* lvl 9 */
 };
 #define ATH9K_ANI_OFDM_NUM_LEVEL \
 	ARRAY_SIZE(ofdm_level_table)
@@ -91,8 +91,8 @@ static const struct ani_cck_level_entry
 	{  4,  0  }, /* lvl 4 */
 	{  5,  0  }, /* lvl 5 */
 	{  6,  0  }, /* lvl 6 */
-	{  6,  0  }, /* lvl 7 (only for high rssi) */
-	{  7,  0  }  /* lvl 8 (only for high rssi) */
+	{  7,  0  }, /* lvl 7 (only for high rssi) */
+	{  8,  0  }  /* lvl 8 (only for high rssi) */
 };
 
 #define ATH9K_ANI_CCK_NUM_LEVEL \
@@ -118,10 +118,10 @@ static void ath9k_ani_restart(struct ath
 {
 	struct ar5416AniState *aniState;
 
-	if (!DO_ANI(ah))
+	if (!ah->curchan)
 		return;
 
-	aniState = &ah->curchan->ani;
+	aniState = &ah->ani;
 	aniState->listenTime = 0;
 
 	ENABLE_REGWRITE_BUFFER(ah);
@@ -143,7 +143,7 @@ static void ath9k_ani_restart(struct ath
 static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
 				  bool scan)
 {
-	struct ar5416AniState *aniState = &ah->curchan->ani;
+	struct ar5416AniState *aniState = &ah->ani;
 	struct ath_common *common = ath9k_hw_common(ah);
 	const struct ani_ofdm_level_entry *entry_ofdm;
 	const struct ani_cck_level_entry *entry_cck;
@@ -177,10 +177,15 @@ static void ath9k_hw_set_ofdm_nil(struct
 	    BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
 		weak_sig = true;
 
-	if (aniState->ofdmWeakSigDetect != weak_sig)
-			ath9k_hw_ani_control(ah,
-				ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-				entry_ofdm->ofdm_weak_signal_on);
+	/*
+	 * OFDM Weak signal detection is always enabled for AP mode.
+	 */
+	if (ah->opmode != NL80211_IFTYPE_AP &&
+	    aniState->ofdmWeakSigDetect != weak_sig) {
+		ath9k_hw_ani_control(ah,
+				     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+				     entry_ofdm->ofdm_weak_signal_on);
+	}
 
 	if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
 		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
@@ -195,10 +200,10 @@ static void ath9k_hw_ani_ofdm_err_trigge
 {
 	struct ar5416AniState *aniState;
 
-	if (!DO_ANI(ah))
+	if (!ah->curchan)
 		return;
 
-	aniState = &ah->curchan->ani;
+	aniState = &ah->ani;
 
 	if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
 		ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false);
@@ -210,7 +215,7 @@ static void ath9k_hw_ani_ofdm_err_trigge
 static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
 				 bool scan)
 {
-	struct ar5416AniState *aniState = &ah->curchan->ani;
+	struct ar5416AniState *aniState = &ah->ani;
 	struct ath_common *common = ath9k_hw_common(ah);
 	const struct ani_ofdm_level_entry *entry_ofdm;
 	const struct ani_cck_level_entry *entry_cck;
@@ -251,10 +256,10 @@ static void ath9k_hw_ani_cck_err_trigger
 {
 	struct ar5416AniState *aniState;
 
-	if (!DO_ANI(ah))
+	if (!ah->curchan)
 		return;
 
-	aniState = &ah->curchan->ani;
+	aniState = &ah->ani;
 
 	if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
 		ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1,
@@ -269,7 +274,7 @@ static void ath9k_hw_ani_lower_immunity(
 {
 	struct ar5416AniState *aniState;
 
-	aniState = &ah->curchan->ani;
+	aniState = &ah->ani;
 
 	/* lower OFDM noise immunity */
 	if (aniState->ofdmNoiseImmunityLevel > 0 &&
@@ -292,12 +297,12 @@ static void ath9k_hw_ani_lower_immunity(
  */
 void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
 {
-	struct ar5416AniState *aniState = &ah->curchan->ani;
+	struct ar5416AniState *aniState = &ah->ani;
 	struct ath9k_channel *chan = ah->curchan;
 	struct ath_common *common = ath9k_hw_common(ah);
 	int ofdm_nil, cck_nil;
 
-	if (!DO_ANI(ah))
+	if (!ah->curchan)
 		return;
 
 	BUG_ON(aniState == NULL);
@@ -363,24 +368,13 @@ void ath9k_ani_reset(struct ath_hw *ah,
 	ath9k_hw_set_ofdm_nil(ah, ofdm_nil, is_scanning);
 	ath9k_hw_set_cck_nil(ah, cck_nil, is_scanning);
 
-	/*
-	 * enable phy counters if hw supports or if not, enable phy
-	 * interrupts (so we can count each one)
-	 */
 	ath9k_ani_restart(ah);
-
-	ENABLE_REGWRITE_BUFFER(ah);
-
-	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
-	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-
-	REGWRITE_BUFFER_FLUSH(ah);
 }
 
 static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ar5416AniState *aniState = &ah->curchan->ani;
+	struct ar5416AniState *aniState = &ah->ani;
 	u32 phyCnt1, phyCnt2;
 	int32_t listenTime;
 
@@ -415,10 +409,10 @@ void ath9k_hw_ani_monitor(struct ath_hw
 	struct ath_common *common = ath9k_hw_common(ah);
 	u32 ofdmPhyErrRate, cckPhyErrRate;
 
-	if (!DO_ANI(ah))
+	if (!ah->curchan)
 		return;
 
-	aniState = &ah->curchan->ani;
+	aniState = &ah->ani;
 	if (!ath9k_hw_ani_read_counters(ah))
 		return;
 
@@ -490,32 +484,22 @@ EXPORT_SYMBOL(ath9k_hw_disable_mib_count
 void ath9k_hw_ani_init(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
-	int i;
+	struct ar5416AniState *ani = &ah->ani;
 
 	ath_dbg(common, ANI, "Initialize ANI\n");
 
 	ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
 	ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
-
 	ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
 	ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
 
-	for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
-		struct ath9k_channel *chan = &ah->channels[i];
-		struct ar5416AniState *ani = &chan->ani;
-
-		ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
-
-		ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-
-		ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
-
-		ani->ofdmsTurn = true;
-
-		ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
-		ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
-		ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
-	}
+	ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+	ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+	ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
+	ani->ofdmsTurn = true;
+	ani->ofdmWeakSigDetect = true;
+	ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
+	ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
 
 	/*
 	 * since we expect some ongoing maintenance on the tables, let's sanity
@@ -524,9 +508,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah
 	ah->aniperiod = ATH9K_ANI_PERIOD;
 	ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
 
-	if (ah->config.enable_ani)
-		ah->proc_phyerr |= HAL_PROCESS_ANI;
-
 	ath9k_ani_restart(ah);
 	ath9k_enable_mib_counters(ah);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ani.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ani.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ani.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ani.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,32 +17,19 @@
 #ifndef ANI_H
 #define ANI_H
 
-#define HAL_PROCESS_ANI           0x00000001
-
-#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
-
 #define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
 
 /* units are errors per second */
-#define ATH9K_ANI_OFDM_TRIG_HIGH          3500
+#define ATH9K_ANI_OFDM_TRIG_HIGH           3500
 #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
 
-/* units are errors per second */
 #define ATH9K_ANI_OFDM_TRIG_LOW           400
 #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
 
-/* units are errors per second */
 #define ATH9K_ANI_CCK_TRIG_HIGH           600
-
-/* units are errors per second */
 #define ATH9K_ANI_CCK_TRIG_LOW            300
 
-#define ATH9K_ANI_NOISE_IMMUNE_LVL        4
-#define ATH9K_ANI_USE_OFDM_WEAK_SIG       true
-#define ATH9K_ANI_CCK_WEAK_SIG_THR        false
-
 #define ATH9K_ANI_SPUR_IMMUNE_LVL         3
-
 #define ATH9K_ANI_FIRSTEP_LVL             2
 
 #define ATH9K_ANI_RSSI_THR_HIGH           40
@@ -53,10 +40,6 @@
 /* in ms */
 #define ATH9K_ANI_POLLINTERVAL            1000
 
-#define HAL_NOISE_IMMUNE_MAX              4
-#define HAL_SPUR_IMMUNE_MAX               7
-#define HAL_FIRST_STEP_MAX                2
-
 #define ATH9K_SIG_FIRSTEP_SETTING_MIN     0
 #define ATH9K_SIG_FIRSTEP_SETTING_MAX     20
 #define ATH9K_SIG_SPUR_IMM_SETTING_MIN    0
@@ -111,7 +94,7 @@ struct ar5416AniState {
 	u8 mrcCCK;
 	u8 spurImmunityLevel;
 	u8 firstepLevel;
-	u8 ofdmWeakSigDetect;
+	bool ofdmWeakSigDetect;
 	u32 listenTime;
 	u32 ofdmPhyErrCount;
 	u32 cckPhyErrCount;
@@ -119,8 +102,6 @@ struct ar5416AniState {
 };
 
 struct ar5416Stats {
-	u32 ast_ani_niup;
-	u32 ast_ani_nidown;
 	u32 ast_ani_spurup;
 	u32 ast_ani_spurdown;
 	u32 ast_ani_ofdmon;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar5008_phy.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar5008_phy.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar5008_phy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar5008_phy.c	2013-08-25 20:43:22.000000000 -0400
@@ -610,7 +610,15 @@ static void ar5008_hw_override_ini(struc
 	REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 
 	if (AR_SREV_9280_20_OR_LATER(ah)) {
-		val = REG_READ(ah, AR_PCU_MISC_MODE2);
+		/*
+		 * For AR9280 and above, there is a new feature that allows
+		 * Multicast search based on both MAC Address and Key ID.
+		 * By default, this feature is enabled. But since the driver
+		 * is not using this feature, we switch it off; otherwise
+		 * multicast search based on MAC addr only will fail.
+		 */
+		val = REG_READ(ah, AR_PCU_MISC_MODE2) &
+			(~AR_ADHOC_MCAST_KEYID_ENABLE);
 
 		if (!AR_SREV_9271(ah))
 			val &= ~AR_PCU_MISC_MODE2_HWWAR1;
@@ -931,7 +939,7 @@ static bool ar5008_hw_ani_control_new(st
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_channel *chan = ah->curchan;
-	struct ar5416AniState *aniState = &chan->ani;
+	struct ar5416AniState *aniState = &ah->ani;
 	s32 value, value2;
 
 	switch (cmd & ah->ani_function) {
@@ -1207,7 +1215,7 @@ static void ar5008_hw_ani_cache_ini_regs
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_channel *chan = ah->curchan;
-	struct ar5416AniState *aniState = &chan->ani;
+	struct ar5416AniState *aniState = &ah->ani;
 	struct ath9k_ani_default *iniDef;
 	u32 val;
 
@@ -1251,7 +1259,7 @@ static void ar5008_hw_ani_cache_ini_regs
 	/* these levels just got reset to defaults by the INI */
 	aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
 	aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-	aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
+	aniState->ofdmWeakSigDetect = true;
 	aniState->mrcCCK = false; /* not available on pre AR9003 */
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9002_hw.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9002_hw.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9002_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9002_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,10 +38,6 @@ static int ar9002_hw_init_mode_regs(stru
 	else
 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
 			   ar9280PciePhy_clkreq_always_on_L1_9280);
-#ifdef CONFIG_PM_SLEEP
-		INIT_INI_ARRAY(&ah->iniPcieSerdesWow,
-			       ar9280PciePhy_awow);
-#endif
 
 	if (AR_SREV_9287_11_OR_LATER(ah)) {
 		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9002_initvals.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9002_initvals.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9002_initvals.h	2013-08-25 20:43:22.000000000 -0400
@@ -925,20 +925,6 @@ static const u32 ar9280PciePhy_clkreq_al
 	{0x00004044, 0x00000000},
 };
 
-static const u32 ar9280PciePhy_awow[][2] = {
-	/* Addr      allmodes  */
-	{0x00004040, 0x9248fd00},
-	{0x00004040, 0x24924924},
-	{0x00004040, 0xa8000019},
-	{0x00004040, 0x13160820},
-	{0x00004040, 0xe5980560},
-	{0x00004040, 0xc01dcffd},
-	{0x00004040, 0x1aaabe41},
-	{0x00004040, 0xbe105554},
-	{0x00004040, 0x00043007},
-	{0x00004044, 0x00000000},
-};
-
 static const u32 ar9285Modes_9285_1_2[][5] = {
 	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
 	{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c	2013-08-25 20:43:22.000000000 -0400
@@ -3563,14 +3563,24 @@ static void ar9003_hw_ant_ctrl_apply(str
 {
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	int chain;
-	u32 regval;
+	u32 regval, value, gpio;
 	static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
 			AR_PHY_SWITCH_CHAIN_0,
 			AR_PHY_SWITCH_CHAIN_1,
 			AR_PHY_SWITCH_CHAIN_2,
 	};
 
-	u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
+	if (AR_SREV_9485(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0)) {
+		if (ah->config.xlna_gpio)
+			gpio = ah->config.xlna_gpio;
+		else
+			gpio = AR9300_EXT_LNA_CTL_GPIO_AR9485;
+
+		ath9k_hw_cfg_output(ah, gpio,
+				    AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED);
+	}
+
+	value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
 
 	if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
 		REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
@@ -3596,7 +3606,7 @@ static void ar9003_hw_ant_ctrl_apply(str
 	 *   7:4 R/W  SWITCH_TABLE_COM_SPDT_WLAN_IDLE
 	 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
 	 */
-	if (AR_SREV_9462_20(ah) || AR_SREV_9565(ah)) {
+	if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
 		value = ar9003_switch_com_spdt_get(ah, is2ghz);
 		REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
 				AR_SWITCH_TABLE_COM_SPDT_ALL, value);
@@ -3796,7 +3806,13 @@ static void ar9003_hw_atten_apply(struct
 			REG_RMW_FIELD(ah, ext_atten_reg[i],
 				      AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
 
-			value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
+			if (AR_SREV_9485(ah) &&
+			    (ar9003_hw_get_rx_gain_idx(ah) == 0) &&
+			    ah->config.xatten_margin_cfg)
+				value = 5;
+			else
+				value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
+
 			REG_RMW_FIELD(ah, ext_atten_reg[i],
 				      AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
 				      value);
@@ -4043,8 +4059,9 @@ static void ar9003_hw_thermo_cal_apply(s
 {
 	u32 data, ko, kg;
 
-	if (!AR_SREV_9462_20(ah))
+	if (!AR_SREV_9462_20_OR_LATER(ah))
 		return;
+
 	ar9300_otp_read_word(ah, 1, &data);
 	ko = data & 0xff;
 	kg = (data >> 8) & 0xff;
@@ -4546,7 +4563,7 @@ static void ar9003_hw_get_target_power_e
 						 is2GHz);
 
 	for (i = 0; i < ar9300RateSize; i++) {
-		ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n",
+		ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
 			i, targetPowerValT2[i]);
 	}
 }
@@ -4736,7 +4753,7 @@ tempslope:
 			      AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
 	}
 
-	if (AR_SREV_9462_20(ah))
+	if (AR_SREV_9462_20_OR_LATER(ah))
 		REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
 			      AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
 
@@ -5272,7 +5289,7 @@ static void ath9k_hw_ar9300_set_txpower(
 		return;
 
 	for (i = 0; i < ar9300RateSize; i++) {
-		ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n",
+		ath_dbg(common, REGULATORY, "TPC[%02d] 0x%08x\n",
 			i, targetPowerValT2[i]);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_hw.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_hw.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,6 +24,7 @@
 #include "ar955x_1p0_initvals.h"
 #include "ar9580_1p0_initvals.h"
 #include "ar9462_2p0_initvals.h"
+#include "ar9462_2p1_initvals.h"
 #include "ar9565_1p0_initvals.h"
 
 /* General hardware code for the AR9003 hadware family */
@@ -197,6 +198,31 @@ static void ar9003_hw_init_mode_regs(str
 
 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
 				ar9485_1_1_pcie_phy_clkreq_disable_L1);
+	} else if (AR_SREV_9462_21(ah)) {
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+			       ar9462_2p1_mac_core);
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+			       ar9462_2p1_mac_postamble);
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+			       ar9462_2p1_baseband_core);
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+			       ar9462_2p1_baseband_postamble);
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+			       ar9462_2p1_radio_core);
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+			       ar9462_2p1_radio_postamble);
+		INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant,
+			       ar9462_2p1_radio_postamble_sys2ant);
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+			       ar9462_2p1_soc_preamble);
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+			       ar9462_2p1_soc_postamble);
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+			       ar9462_2p1_common_rx_gain);
+		INIT_INI_ARRAY(&ah->iniModesFastClock,
+			       ar9462_2p1_modes_fast_clock);
+		INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
+			       ar9462_2p1_baseband_core_txfir_coeff_japan_2484);
 	} else if (AR_SREV_9462_20(ah)) {
 
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core);
@@ -407,6 +433,9 @@ static void ar9003_tx_gain_table_mode0(s
 	else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9580_1p0_lowest_ob_db_tx_gain_table);
+	else if (AR_SREV_9462_21(ah))
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			ar9462_2p1_modes_low_ob_db_tx_gain);
 	else if (AR_SREV_9462_20(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9462_modes_low_ob_db_tx_gain_table_2p0);
@@ -438,6 +467,9 @@ static void ar9003_tx_gain_table_mode1(s
 	else if (AR_SREV_9550(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar955x_1p0_modes_no_xpa_tx_gain_table);
+	else if (AR_SREV_9462_21(ah))
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			ar9462_2p1_modes_high_ob_db_tx_gain);
 	else if (AR_SREV_9462_20(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9462_modes_high_ob_db_tx_gain_table_2p0);
@@ -507,6 +539,12 @@ static void ar9003_tx_gain_table_mode4(s
 	else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9580_1p0_mixed_ob_db_tx_gain_table);
+	else if (AR_SREV_9462_21(ah))
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+		       ar9462_2p1_modes_mix_ob_db_tx_gain);
+	else if (AR_SREV_9462_20(ah))
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+		       ar9462_modes_mix_ob_db_tx_gain_table_2p0);
 	else
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
@@ -584,6 +622,9 @@ static void ar9003_rx_gain_table_mode0(s
 	} else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 				ar9580_1p0_rx_gain_table);
+	else if (AR_SREV_9462_21(ah))
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+				ar9462_2p1_common_rx_gain);
 	else if (AR_SREV_9462_20(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 				ar9462_common_rx_gain_table_2p0);
@@ -606,6 +647,9 @@ static void ar9003_rx_gain_table_mode1(s
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 			ar9485Common_wo_xlna_rx_gain_1_1);
+	else if (AR_SREV_9462_21(ah))
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+			ar9462_2p1_common_wo_xlna_rx_gain);
 	else if (AR_SREV_9462_20(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 			ar9462_common_wo_xlna_rx_gain_table_2p0);
@@ -627,9 +671,40 @@ static void ar9003_rx_gain_table_mode1(s
 
 static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
 {
-	if (AR_SREV_9462_20(ah))
+	if (AR_SREV_9462_21(ah)) {
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+			       ar9462_2p1_common_mixed_rx_gain);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
+			       ar9462_2p1_baseband_core_mix_rxgain);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
+			       ar9462_2p1_baseband_postamble_mix_rxgain);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+			       ar9462_2p1_baseband_postamble_5g_xlna);
+	} else if (AR_SREV_9462_20(ah)) {
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 			       ar9462_common_mixed_rx_gain_table_2p0);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
+			       ar9462_2p0_baseband_core_mix_rxgain);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
+			       ar9462_2p0_baseband_postamble_mix_rxgain);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+			       ar9462_2p0_baseband_postamble_5g_xlna);
+	}
+}
+
+static void ar9003_rx_gain_table_mode3(struct ath_hw *ah)
+{
+	if (AR_SREV_9462_21(ah)) {
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+			       ar9462_2p1_common_5g_xlna_only_rx_gain);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+			       ar9462_2p1_baseband_postamble_5g_xlna);
+	} else if (AR_SREV_9462_20(ah)) {
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+			       ar9462_2p0_5g_xlna_only_rxgain);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+			       ar9462_2p0_baseband_postamble_5g_xlna);
+	}
 }
 
 static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
@@ -645,6 +720,9 @@ static void ar9003_rx_gain_table_apply(s
 	case 2:
 		ar9003_rx_gain_table_mode2(ah);
 		break;
+	case 3:
+		ar9003_rx_gain_table_mode3(ah);
+		break;
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_mac.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_mac.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_mac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_mac.c	2013-08-25 20:43:22.000000000 -0400
@@ -469,6 +469,7 @@ int ath9k_hw_process_rxdesc_edma(struct
 
 	rxs->rs_status = 0;
 	rxs->rs_flags =  0;
+	rxs->flag =  0;
 
 	rxs->rs_datalen = rxsp->status2 & AR_DataLen;
 	rxs->rs_tstamp =  rxsp->status3;
@@ -493,8 +494,8 @@ int ath9k_hw_process_rxdesc_edma(struct
 	rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
 	rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
 	rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
-	rxs->rs_flags  = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0;
-	rxs->rs_flags  |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0;
+	rxs->flag  |= (rxsp->status4 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
+	rxs->flag  |= (rxsp->status4 & AR_2040) ? RX_FLAG_40MHZ : 0;
 
 	rxs->evm0 = rxsp->status6;
 	rxs->evm1 = rxsp->status7;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_paprd.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_paprd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_paprd.c	2013-08-25 20:43:22.000000000 -0400
@@ -454,6 +454,8 @@ static bool create_pa_curve(u32 *data_L,
 		if (accum_cnt <= thresh_accum_cnt)
 			continue;
 
+		max_index++;
+
 		/* sum(tx amplitude) */
 		accum_tx = ((data_L[i] >> 16) & 0xffff) |
 		    ((data_U[i] & 0x7ff) << 16);
@@ -468,20 +470,21 @@ static bool create_pa_curve(u32 *data_L,
 
 		accum_tx <<= scale_factor;
 		accum_rx <<= scale_factor;
-		x_est[i + 1] = (((accum_tx + accum_cnt) / accum_cnt) + 32) >>
-		    scale_factor;
+		x_est[max_index] =
+			(((accum_tx + accum_cnt) / accum_cnt) + 32) >>
+			scale_factor;
 
-		Y[i + 1] = ((((accum_rx + accum_cnt) / accum_cnt) + 32) >>
+		Y[max_index] =
+			((((accum_rx + accum_cnt) / accum_cnt) + 32) >>
 			    scale_factor) +
-			    (1 << scale_factor) * max_index + 16;
+			(1 << scale_factor) * i + 16;
 
 		if (accum_ang >= (1 << 26))
 			accum_ang -= 1 << 27;
 
-		theta[i + 1] = ((accum_ang * (1 << scale_factor)) + accum_cnt) /
-		    accum_cnt;
-
-		max_index++;
+		theta[max_index] =
+			((accum_ang * (1 << scale_factor)) + accum_cnt) /
+			accum_cnt;
 	}
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.c	2013-08-25 20:43:22.000000000 -0400
@@ -735,22 +735,53 @@ static int ar9003_hw_process_ini(struct
 		return -EINVAL;
 	}
 
+	/*
+	 * SOC, MAC, BB, RADIO initvals.
+	 */
 	for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
 		ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex);
 		ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
 		ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
 		ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
-		if (i == ATH_INI_POST && AR_SREV_9462_20(ah))
+		if (i == ATH_INI_POST && AR_SREV_9462_20_OR_LATER(ah))
 			ar9003_hw_prog_ini(ah,
 					   &ah->ini_radio_post_sys2ant,
 					   modesIndex);
 	}
 
+	/*
+	 * RXGAIN initvals.
+	 */
 	REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites);
+
+	if (AR_SREV_9462_20_OR_LATER(ah)) {
+		/*
+		 * CUS217 mix LNA mode.
+		 */
+		if (ar9003_hw_get_rx_gain_idx(ah) == 2) {
+			REG_WRITE_ARRAY(&ah->ini_modes_rxgain_bb_core,
+					1, regWrites);
+			REG_WRITE_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
+					modesIndex, regWrites);
+		}
+
+		/*
+		 * 5G-XLNA
+		 */
+		if ((ar9003_hw_get_rx_gain_idx(ah) == 2) ||
+		    (ar9003_hw_get_rx_gain_idx(ah) == 3)) {
+			REG_WRITE_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
+					modesIndex, regWrites);
+		}
+	}
+
 	if (AR_SREV_9550(ah))
 		REG_WRITE_ARRAY(&ah->ini_modes_rx_gain_bounds, modesIndex,
 				regWrites);
 
+	/*
+	 * TXGAIN initvals.
+	 */
 	if (AR_SREV_9550(ah)) {
 		int modes_txgain_index;
 
@@ -772,8 +803,14 @@ static int ar9003_hw_process_ini(struct
 		REG_WRITE_ARRAY(&ah->iniModesFastClock,
 				modesIndex, regWrites);
 
+	/*
+	 * Clock frequency initvals.
+	 */
 	REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites);
 
+	/*
+	 * JAPAN regulatory.
+	 */
 	if (chan->channel == 2484)
 		ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1);
 
@@ -905,7 +942,12 @@ static bool ar9003_hw_ani_control(struct
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_channel *chan = ah->curchan;
-	struct ar5416AniState *aniState = &chan->ani;
+	struct ar5416AniState *aniState = &ah->ani;
+	int m1ThreshLow, m2ThreshLow;
+	int m1Thresh, m2Thresh;
+	int m2CountThr, m2CountThrLow;
+	int m1ThreshLowExt, m2ThreshLowExt;
+	int m1ThreshExt, m2ThreshExt;
 	s32 value, value2;
 
 	switch (cmd & ah->ani_function) {
@@ -919,6 +961,61 @@ static bool ar9003_hw_ani_control(struct
 		 */
 		u32 on = param ? 1 : 0;
 
+		if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
+			goto skip_ws_det;
+
+		m1ThreshLow = on ?
+			aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
+		m2ThreshLow = on ?
+			aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
+		m1Thresh = on ?
+			aniState->iniDef.m1Thresh : m1Thresh_off;
+		m2Thresh = on ?
+			aniState->iniDef.m2Thresh : m2Thresh_off;
+		m2CountThr = on ?
+			aniState->iniDef.m2CountThr : m2CountThr_off;
+		m2CountThrLow = on ?
+			aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
+		m1ThreshLowExt = on ?
+			aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
+		m2ThreshLowExt = on ?
+			aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
+		m1ThreshExt = on ?
+			aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
+		m2ThreshExt = on ?
+			aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
+
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+			      m1ThreshLow);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+			      AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+			      m2ThreshLow);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+			      AR_PHY_SFCORR_M1_THRESH,
+			      m1Thresh);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+			      AR_PHY_SFCORR_M2_THRESH,
+			      m2Thresh);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+			      AR_PHY_SFCORR_M2COUNT_THR,
+			      m2CountThr);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+			      AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+			      m2CountThrLow);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
+			      m1ThreshLowExt);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
+			      m2ThreshLowExt);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M1_THRESH,
+			      m1ThreshExt);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+			      AR_PHY_SFCORR_EXT_M2_THRESH,
+			      m2ThreshExt);
+skip_ws_det:
 		if (on)
 			REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
 				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
@@ -1173,7 +1270,7 @@ static void ar9003_hw_ani_cache_ini_regs
 	struct ath9k_ani_default *iniDef;
 	u32 val;
 
-	aniState = &ah->curchan->ani;
+	aniState = &ah->ani;
 	iniDef = &aniState->iniDef;
 
 	ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
@@ -1214,7 +1311,7 @@ static void ar9003_hw_ani_cache_ini_regs
 	/* these levels just got reset to defaults by the INI */
 	aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
 	aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-	aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
+	aniState->ofdmWeakSigDetect = true;
 	aniState->mrcCCK = true;
 }
 
@@ -1415,7 +1512,7 @@ static int ar9003_hw_fast_chan_change(st
 	ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex);
 	ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex);
 
-	if (AR_SREV_9462_20(ah))
+	if (AR_SREV_9462_20_OR_LATER(ah))
 		ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant,
 				   modesIndex);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9003_phy.h	2013-08-25 20:43:22.000000000 -0400
@@ -351,6 +351,8 @@
 
 #define AR_PHY_CCA_NOM_VAL_9330_2GHZ          -118
 
+#define AR9300_EXT_LNA_CTL_GPIO_AR9485 9
+
 /*
  * AGC Field Definitions
  */
@@ -952,7 +954,7 @@
 #define AR_PHY_TPC_5_B1         (AR_SM1_BASE + 0x208)
 #define AR_PHY_TPC_6_B1         (AR_SM1_BASE + 0x20c)
 #define AR_PHY_TPC_11_B1        (AR_SM1_BASE + 0x220)
-#define AR_PHY_PDADC_TAB_1	(AR_SM1_BASE + (AR_SREV_AR9462(ah) ? \
+#define AR_PHY_PDADC_TAB_1	(AR_SM1_BASE + (AR_SREV_9462_20_OR_LATER(ah) ? \
 					0x280 : 0x240))
 #define AR_PHY_TPC_19_B1	(AR_SM1_BASE + 0x240)
 #define AR_PHY_TPC_19_B1_ALPHA_THERM		0xff
@@ -1046,7 +1048,7 @@
 #define AR_GLB_GPIO_CONTROL	(AR_GLB_BASE)
 #define AR_PHY_GLB_CONTROL	(AR_GLB_BASE + 0x44)
 #define AR_GLB_SCRATCH(_ah)	(AR_GLB_BASE + \
-					(AR_SREV_9462_20(_ah) ? 0x4c : 0x50))
+					(AR_SREV_9462_20_OR_LATER(_ah) ? 0x4c : 0x50))
 #define AR_GLB_STATUS		(AR_GLB_BASE + 0x48)
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h	2013-08-25 20:43:22.000000000 -0400
@@ -78,7 +78,7 @@ static const u32 ar9462_2p0_baseband_pos
 	{0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
 	{0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
 	{0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
-	{0x0000a2c4, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18},
+	{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
 	{0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
 	{0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
 	{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -879,6 +879,69 @@ static const u32 ar9462_2p0_radio_postam
 	{0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
 };
 
+static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+	{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+	{0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+	{0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de},
+	{0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400},
+	{0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402},
+	{0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
+	{0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603},
+	{0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02},
+	{0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04},
+	{0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20},
+	{0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20},
+	{0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22},
+	{0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24},
+	{0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640},
+	{0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660},
+	{0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec},
+	{0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0},
+	{0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4},
+	{0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
+	{0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
+	{0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
+	{0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
+	{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
+	{0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
+	{0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
+	{0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
+	{0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
+	{0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
+	{0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
+	{0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+	{0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+	{0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+};
+
 static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
 	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
 	{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
@@ -1449,4 +1512,284 @@ static const u32 ar9462_common_mixed_rx_
 	{0x0000b1fc, 0x00000196},
 };
 
+static const u32 ar9462_2p0_baseband_postamble_5g_xlna[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
+};
+
+static const u32 ar9462_2p0_5g_xlna_only_rxgain[][2] = {
+	/* Addr      allmodes  */
+	{0x0000a000, 0x00010000},
+	{0x0000a004, 0x00030002},
+	{0x0000a008, 0x00050004},
+	{0x0000a00c, 0x00810080},
+	{0x0000a010, 0x00830082},
+	{0x0000a014, 0x01810180},
+	{0x0000a018, 0x01830182},
+	{0x0000a01c, 0x01850184},
+	{0x0000a020, 0x01890188},
+	{0x0000a024, 0x018b018a},
+	{0x0000a028, 0x018d018c},
+	{0x0000a02c, 0x03820190},
+	{0x0000a030, 0x03840383},
+	{0x0000a034, 0x03880385},
+	{0x0000a038, 0x038a0389},
+	{0x0000a03c, 0x038c038b},
+	{0x0000a040, 0x0390038d},
+	{0x0000a044, 0x03920391},
+	{0x0000a048, 0x03940393},
+	{0x0000a04c, 0x03960395},
+	{0x0000a050, 0x00000000},
+	{0x0000a054, 0x00000000},
+	{0x0000a058, 0x00000000},
+	{0x0000a05c, 0x00000000},
+	{0x0000a060, 0x00000000},
+	{0x0000a064, 0x00000000},
+	{0x0000a068, 0x00000000},
+	{0x0000a06c, 0x00000000},
+	{0x0000a070, 0x00000000},
+	{0x0000a074, 0x00000000},
+	{0x0000a078, 0x00000000},
+	{0x0000a07c, 0x00000000},
+	{0x0000a080, 0x29292929},
+	{0x0000a084, 0x29292929},
+	{0x0000a088, 0x29292929},
+	{0x0000a08c, 0x29292929},
+	{0x0000a090, 0x22292929},
+	{0x0000a094, 0x1d1d2222},
+	{0x0000a098, 0x0c111117},
+	{0x0000a09c, 0x00030303},
+	{0x0000a0a0, 0x00000000},
+	{0x0000a0a4, 0x00000000},
+	{0x0000a0a8, 0x00000000},
+	{0x0000a0ac, 0x00000000},
+	{0x0000a0b0, 0x00000000},
+	{0x0000a0b4, 0x00000000},
+	{0x0000a0b8, 0x00000000},
+	{0x0000a0bc, 0x00000000},
+	{0x0000a0c0, 0x001f0000},
+	{0x0000a0c4, 0x01000101},
+	{0x0000a0c8, 0x011e011f},
+	{0x0000a0cc, 0x011c011d},
+	{0x0000a0d0, 0x02030204},
+	{0x0000a0d4, 0x02010202},
+	{0x0000a0d8, 0x021f0200},
+	{0x0000a0dc, 0x0302021e},
+	{0x0000a0e0, 0x03000301},
+	{0x0000a0e4, 0x031e031f},
+	{0x0000a0e8, 0x0402031d},
+	{0x0000a0ec, 0x04000401},
+	{0x0000a0f0, 0x041e041f},
+	{0x0000a0f4, 0x0502041d},
+	{0x0000a0f8, 0x05000501},
+	{0x0000a0fc, 0x051e051f},
+	{0x0000a100, 0x06010602},
+	{0x0000a104, 0x061f0600},
+	{0x0000a108, 0x061d061e},
+	{0x0000a10c, 0x07020703},
+	{0x0000a110, 0x07000701},
+	{0x0000a114, 0x00000000},
+	{0x0000a118, 0x00000000},
+	{0x0000a11c, 0x00000000},
+	{0x0000a120, 0x00000000},
+	{0x0000a124, 0x00000000},
+	{0x0000a128, 0x00000000},
+	{0x0000a12c, 0x00000000},
+	{0x0000a130, 0x00000000},
+	{0x0000a134, 0x00000000},
+	{0x0000a138, 0x00000000},
+	{0x0000a13c, 0x00000000},
+	{0x0000a140, 0x001f0000},
+	{0x0000a144, 0x01000101},
+	{0x0000a148, 0x011e011f},
+	{0x0000a14c, 0x011c011d},
+	{0x0000a150, 0x02030204},
+	{0x0000a154, 0x02010202},
+	{0x0000a158, 0x021f0200},
+	{0x0000a15c, 0x0302021e},
+	{0x0000a160, 0x03000301},
+	{0x0000a164, 0x031e031f},
+	{0x0000a168, 0x0402031d},
+	{0x0000a16c, 0x04000401},
+	{0x0000a170, 0x041e041f},
+	{0x0000a174, 0x0502041d},
+	{0x0000a178, 0x05000501},
+	{0x0000a17c, 0x051e051f},
+	{0x0000a180, 0x06010602},
+	{0x0000a184, 0x061f0600},
+	{0x0000a188, 0x061d061e},
+	{0x0000a18c, 0x07020703},
+	{0x0000a190, 0x07000701},
+	{0x0000a194, 0x00000000},
+	{0x0000a198, 0x00000000},
+	{0x0000a19c, 0x00000000},
+	{0x0000a1a0, 0x00000000},
+	{0x0000a1a4, 0x00000000},
+	{0x0000a1a8, 0x00000000},
+	{0x0000a1ac, 0x00000000},
+	{0x0000a1b0, 0x00000000},
+	{0x0000a1b4, 0x00000000},
+	{0x0000a1b8, 0x00000000},
+	{0x0000a1bc, 0x00000000},
+	{0x0000a1c0, 0x00000000},
+	{0x0000a1c4, 0x00000000},
+	{0x0000a1c8, 0x00000000},
+	{0x0000a1cc, 0x00000000},
+	{0x0000a1d0, 0x00000000},
+	{0x0000a1d4, 0x00000000},
+	{0x0000a1d8, 0x00000000},
+	{0x0000a1dc, 0x00000000},
+	{0x0000a1e0, 0x00000000},
+	{0x0000a1e4, 0x00000000},
+	{0x0000a1e8, 0x00000000},
+	{0x0000a1ec, 0x00000000},
+	{0x0000a1f0, 0x00000396},
+	{0x0000a1f4, 0x00000396},
+	{0x0000a1f8, 0x00000396},
+	{0x0000a1fc, 0x00000196},
+	{0x0000b000, 0x00010000},
+	{0x0000b004, 0x00030002},
+	{0x0000b008, 0x00050004},
+	{0x0000b00c, 0x00810080},
+	{0x0000b010, 0x00830082},
+	{0x0000b014, 0x01810180},
+	{0x0000b018, 0x01830182},
+	{0x0000b01c, 0x01850184},
+	{0x0000b020, 0x02810280},
+	{0x0000b024, 0x02830282},
+	{0x0000b028, 0x02850284},
+	{0x0000b02c, 0x02890288},
+	{0x0000b030, 0x028b028a},
+	{0x0000b034, 0x0388028c},
+	{0x0000b038, 0x038a0389},
+	{0x0000b03c, 0x038c038b},
+	{0x0000b040, 0x0390038d},
+	{0x0000b044, 0x03920391},
+	{0x0000b048, 0x03940393},
+	{0x0000b04c, 0x03960395},
+	{0x0000b050, 0x00000000},
+	{0x0000b054, 0x00000000},
+	{0x0000b058, 0x00000000},
+	{0x0000b05c, 0x00000000},
+	{0x0000b060, 0x00000000},
+	{0x0000b064, 0x00000000},
+	{0x0000b068, 0x00000000},
+	{0x0000b06c, 0x00000000},
+	{0x0000b070, 0x00000000},
+	{0x0000b074, 0x00000000},
+	{0x0000b078, 0x00000000},
+	{0x0000b07c, 0x00000000},
+	{0x0000b080, 0x2a2d2f32},
+	{0x0000b084, 0x21232328},
+	{0x0000b088, 0x19191c1e},
+	{0x0000b08c, 0x12141417},
+	{0x0000b090, 0x07070e0e},
+	{0x0000b094, 0x03030305},
+	{0x0000b098, 0x00000003},
+	{0x0000b09c, 0x00000000},
+	{0x0000b0a0, 0x00000000},
+	{0x0000b0a4, 0x00000000},
+	{0x0000b0a8, 0x00000000},
+	{0x0000b0ac, 0x00000000},
+	{0x0000b0b0, 0x00000000},
+	{0x0000b0b4, 0x00000000},
+	{0x0000b0b8, 0x00000000},
+	{0x0000b0bc, 0x00000000},
+	{0x0000b0c0, 0x003f0020},
+	{0x0000b0c4, 0x00400041},
+	{0x0000b0c8, 0x0140005f},
+	{0x0000b0cc, 0x0160015f},
+	{0x0000b0d0, 0x017e017f},
+	{0x0000b0d4, 0x02410242},
+	{0x0000b0d8, 0x025f0240},
+	{0x0000b0dc, 0x027f0260},
+	{0x0000b0e0, 0x0341027e},
+	{0x0000b0e4, 0x035f0340},
+	{0x0000b0e8, 0x037f0360},
+	{0x0000b0ec, 0x04400441},
+	{0x0000b0f0, 0x0460045f},
+	{0x0000b0f4, 0x0541047f},
+	{0x0000b0f8, 0x055f0540},
+	{0x0000b0fc, 0x057f0560},
+	{0x0000b100, 0x06400641},
+	{0x0000b104, 0x0660065f},
+	{0x0000b108, 0x067e067f},
+	{0x0000b10c, 0x07410742},
+	{0x0000b110, 0x075f0740},
+	{0x0000b114, 0x077f0760},
+	{0x0000b118, 0x07800781},
+	{0x0000b11c, 0x07a0079f},
+	{0x0000b120, 0x07c107bf},
+	{0x0000b124, 0x000007c0},
+	{0x0000b128, 0x00000000},
+	{0x0000b12c, 0x00000000},
+	{0x0000b130, 0x00000000},
+	{0x0000b134, 0x00000000},
+	{0x0000b138, 0x00000000},
+	{0x0000b13c, 0x00000000},
+	{0x0000b140, 0x003f0020},
+	{0x0000b144, 0x00400041},
+	{0x0000b148, 0x0140005f},
+	{0x0000b14c, 0x0160015f},
+	{0x0000b150, 0x017e017f},
+	{0x0000b154, 0x02410242},
+	{0x0000b158, 0x025f0240},
+	{0x0000b15c, 0x027f0260},
+	{0x0000b160, 0x0341027e},
+	{0x0000b164, 0x035f0340},
+	{0x0000b168, 0x037f0360},
+	{0x0000b16c, 0x04400441},
+	{0x0000b170, 0x0460045f},
+	{0x0000b174, 0x0541047f},
+	{0x0000b178, 0x055f0540},
+	{0x0000b17c, 0x057f0560},
+	{0x0000b180, 0x06400641},
+	{0x0000b184, 0x0660065f},
+	{0x0000b188, 0x067e067f},
+	{0x0000b18c, 0x07410742},
+	{0x0000b190, 0x075f0740},
+	{0x0000b194, 0x077f0760},
+	{0x0000b198, 0x07800781},
+	{0x0000b19c, 0x07a0079f},
+	{0x0000b1a0, 0x07c107bf},
+	{0x0000b1a4, 0x000007c0},
+	{0x0000b1a8, 0x00000000},
+	{0x0000b1ac, 0x00000000},
+	{0x0000b1b0, 0x00000000},
+	{0x0000b1b4, 0x00000000},
+	{0x0000b1b8, 0x00000000},
+	{0x0000b1bc, 0x00000000},
+	{0x0000b1c0, 0x00000000},
+	{0x0000b1c4, 0x00000000},
+	{0x0000b1c8, 0x00000000},
+	{0x0000b1cc, 0x00000000},
+	{0x0000b1d0, 0x00000000},
+	{0x0000b1d4, 0x00000000},
+	{0x0000b1d8, 0x00000000},
+	{0x0000b1dc, 0x00000000},
+	{0x0000b1e0, 0x00000000},
+	{0x0000b1e4, 0x00000000},
+	{0x0000b1e8, 0x00000000},
+	{0x0000b1ec, 0x00000000},
+	{0x0000b1f0, 0x00000396},
+	{0x0000b1f4, 0x00000396},
+	{0x0000b1f8, 0x00000396},
+	{0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9462_2p0_baseband_core_mix_rxgain[][2] = {
+	/* Addr      allmodes  */
+	{0x00009fd0, 0x0a2d6b93},
+};
+
+static const u32 ar9462_2p0_baseband_postamble_mix_rxgain[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
+	{0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da},
+	{0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81},
+	{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8},
+	{0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e},
+	{0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e},
+};
+
 #endif /* INITVALS_9462_2P0_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1774 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2012 Qualcomm Atheros Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef INITVALS_9462_2P1_H
+#define INITVALS_9462_2P1_H
+
+/* AR9462 2.1 */
+
+static const u32 ar9462_2p1_mac_core[][2] = {
+	/* Addr      allmodes  */
+	{0x00000008, 0x00000000},
+	{0x00000030, 0x000e0085},
+	{0x00000034, 0x00000005},
+	{0x00000040, 0x00000000},
+	{0x00000044, 0x00000000},
+	{0x00000048, 0x00000008},
+	{0x0000004c, 0x00000010},
+	{0x00000050, 0x00000000},
+	{0x00001040, 0x002ffc0f},
+	{0x00001044, 0x002ffc0f},
+	{0x00001048, 0x002ffc0f},
+	{0x0000104c, 0x002ffc0f},
+	{0x00001050, 0x002ffc0f},
+	{0x00001054, 0x002ffc0f},
+	{0x00001058, 0x002ffc0f},
+	{0x0000105c, 0x002ffc0f},
+	{0x00001060, 0x002ffc0f},
+	{0x00001064, 0x002ffc0f},
+	{0x000010f0, 0x00000100},
+	{0x00001270, 0x00000000},
+	{0x000012b0, 0x00000000},
+	{0x000012f0, 0x00000000},
+	{0x0000143c, 0x00000000},
+	{0x0000147c, 0x00000000},
+	{0x00001810, 0x0f000003},
+	{0x00008000, 0x00000000},
+	{0x00008004, 0x00000000},
+	{0x00008008, 0x00000000},
+	{0x0000800c, 0x00000000},
+	{0x00008018, 0x00000000},
+	{0x00008020, 0x00000000},
+	{0x00008038, 0x00000000},
+	{0x0000803c, 0x00080000},
+	{0x00008040, 0x00000000},
+	{0x00008044, 0x00000000},
+	{0x00008048, 0x00000000},
+	{0x0000804c, 0xffffffff},
+	{0x00008054, 0x00000000},
+	{0x00008058, 0x00000000},
+	{0x0000805c, 0x000fc78f},
+	{0x00008060, 0x0000000f},
+	{0x00008064, 0x00000000},
+	{0x00008070, 0x00000310},
+	{0x00008074, 0x00000020},
+	{0x00008078, 0x00000000},
+	{0x0000809c, 0x0000000f},
+	{0x000080a0, 0x00000000},
+	{0x000080a4, 0x02ff0000},
+	{0x000080a8, 0x0e070605},
+	{0x000080ac, 0x0000000d},
+	{0x000080b0, 0x00000000},
+	{0x000080b4, 0x00000000},
+	{0x000080b8, 0x00000000},
+	{0x000080bc, 0x00000000},
+	{0x000080c0, 0x2a800000},
+	{0x000080c4, 0x06900168},
+	{0x000080c8, 0x13881c20},
+	{0x000080cc, 0x01f40000},
+	{0x000080d0, 0x00252500},
+	{0x000080d4, 0x00b00005},
+	{0x000080d8, 0x00400002},
+	{0x000080dc, 0x00000000},
+	{0x000080e0, 0xffffffff},
+	{0x000080e4, 0x0000ffff},
+	{0x000080e8, 0x3f3f3f3f},
+	{0x000080ec, 0x00000000},
+	{0x000080f0, 0x00000000},
+	{0x000080f4, 0x00000000},
+	{0x000080fc, 0x00020000},
+	{0x00008100, 0x00000000},
+	{0x00008108, 0x00000052},
+	{0x0000810c, 0x00000000},
+	{0x00008110, 0x00000000},
+	{0x00008114, 0x000007ff},
+	{0x00008118, 0x000000aa},
+	{0x0000811c, 0x00003210},
+	{0x00008124, 0x00000000},
+	{0x00008128, 0x00000000},
+	{0x0000812c, 0x00000000},
+	{0x00008130, 0x00000000},
+	{0x00008134, 0x00000000},
+	{0x00008138, 0x00000000},
+	{0x0000813c, 0x0000ffff},
+	{0x00008144, 0xffffffff},
+	{0x00008168, 0x00000000},
+	{0x0000816c, 0x00000000},
+	{0x00008170, 0x18486e00},
+	{0x00008174, 0x33332210},
+	{0x00008178, 0x00000000},
+	{0x0000817c, 0x00020000},
+	{0x000081c4, 0x33332210},
+	{0x000081c8, 0x00000000},
+	{0x000081cc, 0x00000000},
+	{0x000081d4, 0x00000000},
+	{0x000081ec, 0x00000000},
+	{0x000081f0, 0x00000000},
+	{0x000081f4, 0x00000000},
+	{0x000081f8, 0x00000000},
+	{0x000081fc, 0x00000000},
+	{0x00008240, 0x00100000},
+	{0x00008244, 0x0010f400},
+	{0x00008248, 0x00000800},
+	{0x0000824c, 0x0001e800},
+	{0x00008250, 0x00000000},
+	{0x00008254, 0x00000000},
+	{0x00008258, 0x00000000},
+	{0x0000825c, 0x40000000},
+	{0x00008260, 0x00080922},
+	{0x00008264, 0x99c00010},
+	{0x00008268, 0xffffffff},
+	{0x0000826c, 0x0000ffff},
+	{0x00008270, 0x00000000},
+	{0x00008274, 0x40000000},
+	{0x00008278, 0x003e4180},
+	{0x0000827c, 0x00000004},
+	{0x00008284, 0x0000002c},
+	{0x00008288, 0x0000002c},
+	{0x0000828c, 0x000000ff},
+	{0x00008294, 0x00000000},
+	{0x00008298, 0x00000000},
+	{0x0000829c, 0x00000000},
+	{0x00008300, 0x00000140},
+	{0x00008314, 0x00000000},
+	{0x0000831c, 0x0000010d},
+	{0x00008328, 0x00000000},
+	{0x0000832c, 0x0000001f},
+	{0x00008330, 0x00000302},
+	{0x00008334, 0x00000700},
+	{0x00008338, 0xffff0000},
+	{0x0000833c, 0x02400000},
+	{0x00008340, 0x000107ff},
+	{0x00008344, 0xaa48107b},
+	{0x00008348, 0x008f0000},
+	{0x0000835c, 0x00000000},
+	{0x00008360, 0xffffffff},
+	{0x00008364, 0xffffffff},
+	{0x00008368, 0x00000000},
+	{0x00008370, 0x00000000},
+	{0x00008374, 0x000000ff},
+	{0x00008378, 0x00000000},
+	{0x0000837c, 0x00000000},
+	{0x00008380, 0xffffffff},
+	{0x00008384, 0xffffffff},
+	{0x00008390, 0xffffffff},
+	{0x00008394, 0xffffffff},
+	{0x00008398, 0x00000000},
+	{0x0000839c, 0x00000000},
+	{0x000083a4, 0x0000fa14},
+	{0x000083a8, 0x000f0c00},
+	{0x000083ac, 0x33332210},
+	{0x000083b0, 0x33332210},
+	{0x000083b4, 0x33332210},
+	{0x000083b8, 0x33332210},
+	{0x000083bc, 0x00000000},
+	{0x000083c0, 0x00000000},
+	{0x000083c4, 0x00000000},
+	{0x000083c8, 0x00000000},
+	{0x000083cc, 0x00000200},
+	{0x000083d0, 0x000301ff},
+};
+
+static const u32 ar9462_2p1_mac_postamble[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
+	{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
+	{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
+	{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
+	{0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
+	{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
+	{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
+	{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
+};
+
+static const u32 ar9462_2p1_baseband_core[][2] = {
+	/* Addr      allmodes  */
+	{0x00009800, 0xafe68e30},
+	{0x00009804, 0xfd14e000},
+	{0x00009808, 0x9c0a9f6b},
+	{0x0000980c, 0x04900000},
+	{0x00009814, 0x9280c00a},
+	{0x00009818, 0x00000000},
+	{0x0000981c, 0x00020028},
+	{0x00009834, 0x6400a290},
+	{0x00009838, 0x0108ecff},
+	{0x0000983c, 0x0d000600},
+	{0x00009880, 0x201fff00},
+	{0x00009884, 0x00001042},
+	{0x000098a4, 0x00200400},
+	{0x000098b0, 0x32440bbe},
+	{0x000098d0, 0x004b6a8e},
+	{0x000098d4, 0x00000820},
+	{0x000098dc, 0x00000000},
+	{0x000098e4, 0x01ffffff},
+	{0x000098e8, 0x01ffffff},
+	{0x000098ec, 0x01ffffff},
+	{0x000098f0, 0x00000000},
+	{0x000098f4, 0x00000000},
+	{0x00009bf0, 0x80000000},
+	{0x00009c04, 0xff55ff55},
+	{0x00009c08, 0x0320ff55},
+	{0x00009c0c, 0x00000000},
+	{0x00009c10, 0x00000000},
+	{0x00009c14, 0x00046384},
+	{0x00009c18, 0x05b6b440},
+	{0x00009c1c, 0x00b6b440},
+	{0x00009d00, 0xc080a333},
+	{0x00009d04, 0x40206c10},
+	{0x00009d08, 0x009c4060},
+	{0x00009d0c, 0x9883800a},
+	{0x00009d10, 0x01834061},
+	{0x00009d14, 0x00c0040b},
+	{0x00009d18, 0x00000000},
+	{0x00009e08, 0x0038230c},
+	{0x00009e24, 0x990bb515},
+	{0x00009e28, 0x0c6f0000},
+	{0x00009e30, 0x06336f77},
+	{0x00009e34, 0x6af6532f},
+	{0x00009e38, 0x0cc80c00},
+	{0x00009e40, 0x15262820},
+	{0x00009e4c, 0x00001004},
+	{0x00009e50, 0x00ff03f1},
+	{0x00009e54, 0xe4c555c2},
+	{0x00009e58, 0xfd857722},
+	{0x00009e5c, 0xe9198724},
+	{0x00009fc0, 0x803e4788},
+	{0x00009fc4, 0x0001efb5},
+	{0x00009fcc, 0x40000014},
+	{0x00009fd0, 0x0a193b93},
+	{0x0000a20c, 0x00000000},
+	{0x0000a220, 0x00000000},
+	{0x0000a224, 0x00000000},
+	{0x0000a228, 0x10002310},
+	{0x0000a23c, 0x00000000},
+	{0x0000a244, 0x0c000000},
+	{0x0000a2a0, 0x00000001},
+	{0x0000a2c0, 0x00000001},
+	{0x0000a2c8, 0x00000000},
+	{0x0000a2cc, 0x18c43433},
+	{0x0000a2d4, 0x00000000},
+	{0x0000a2ec, 0x00000000},
+	{0x0000a2f0, 0x00000000},
+	{0x0000a2f4, 0x00000000},
+	{0x0000a2f8, 0x00000000},
+	{0x0000a344, 0x00000000},
+	{0x0000a34c, 0x00000000},
+	{0x0000a350, 0x0000a000},
+	{0x0000a364, 0x00000000},
+	{0x0000a370, 0x00000000},
+	{0x0000a390, 0x00000001},
+	{0x0000a394, 0x00000444},
+	{0x0000a398, 0x001f0e0f},
+	{0x0000a39c, 0x0075393f},
+	{0x0000a3a0, 0xb79f6427},
+	{0x0000a3c0, 0x20202020},
+	{0x0000a3c4, 0x22222220},
+	{0x0000a3c8, 0x20200020},
+	{0x0000a3cc, 0x20202020},
+	{0x0000a3d0, 0x20202020},
+	{0x0000a3d4, 0x20202020},
+	{0x0000a3d8, 0x20202020},
+	{0x0000a3dc, 0x20202020},
+	{0x0000a3e0, 0x20202020},
+	{0x0000a3e4, 0x20202020},
+	{0x0000a3e8, 0x20202020},
+	{0x0000a3ec, 0x20202020},
+	{0x0000a3f0, 0x00000000},
+	{0x0000a3f4, 0x00000006},
+	{0x0000a3f8, 0x0c9bd380},
+	{0x0000a3fc, 0x000f0f01},
+	{0x0000a400, 0x8fa91f01},
+	{0x0000a404, 0x00000000},
+	{0x0000a408, 0x0e79e5c6},
+	{0x0000a40c, 0x00820820},
+	{0x0000a414, 0x1ce739ce},
+	{0x0000a418, 0x2d001dce},
+	{0x0000a434, 0x00000000},
+	{0x0000a438, 0x00001801},
+	{0x0000a43c, 0x00100000},
+	{0x0000a444, 0x00000000},
+	{0x0000a448, 0x05000080},
+	{0x0000a44c, 0x00000001},
+	{0x0000a450, 0x00010000},
+	{0x0000a454, 0x07000000},
+	{0x0000a644, 0xbfad9d74},
+	{0x0000a648, 0x0048060a},
+	{0x0000a64c, 0x00002037},
+	{0x0000a670, 0x03020100},
+	{0x0000a674, 0x09080504},
+	{0x0000a678, 0x0d0c0b0a},
+	{0x0000a67c, 0x13121110},
+	{0x0000a680, 0x31301514},
+	{0x0000a684, 0x35343332},
+	{0x0000a688, 0x00000036},
+	{0x0000a690, 0x00000838},
+	{0x0000a6b0, 0x0000000a},
+	{0x0000a6b4, 0x00512c01},
+	{0x0000a7c0, 0x00000000},
+	{0x0000a7c4, 0xfffffffc},
+	{0x0000a7c8, 0x00000000},
+	{0x0000a7cc, 0x00000000},
+	{0x0000a7d0, 0x00000000},
+	{0x0000a7d4, 0x00000004},
+	{0x0000a7dc, 0x00000000},
+	{0x0000a7f0, 0x80000000},
+	{0x0000a8d0, 0x004b6a8e},
+	{0x0000a8d4, 0x00000820},
+	{0x0000a8dc, 0x00000000},
+	{0x0000a8f0, 0x00000000},
+	{0x0000a8f4, 0x00000000},
+	{0x0000abf0, 0x80000000},
+	{0x0000b2d0, 0x00000080},
+	{0x0000b2d4, 0x00000000},
+	{0x0000b2ec, 0x00000000},
+	{0x0000b2f0, 0x00000000},
+	{0x0000b2f4, 0x00000000},
+	{0x0000b2f8, 0x00000000},
+	{0x0000b408, 0x0e79e5c0},
+	{0x0000b40c, 0x00820820},
+	{0x0000b420, 0x00000000},
+	{0x0000b6b0, 0x0000000a},
+	{0x0000b6b4, 0x00000001},
+};
+
+static const u32 ar9462_2p1_baseband_postamble[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
+	{0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae},
+	{0x00009824, 0x63c640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da},
+	{0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x09143e81},
+	{0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+	{0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
+	{0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
+	{0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a2},
+	{0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
+	{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8},
+	{0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e},
+	{0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e},
+	{0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+	{0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+	{0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+	{0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
+	{0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27},
+	{0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
+	{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+	{0x0000a204, 0x01318fc0, 0x01318fc4, 0x01318fc4, 0x01318fc0},
+	{0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+	{0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f},
+	{0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
+	{0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
+	{0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
+	{0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
+	{0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
+	{0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
+	{0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+	{0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
+	{0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+	{0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+	{0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+	{0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
+	{0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
+	{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+	{0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
+	{0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
+	{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a3a4, 0x00000050, 0x00000050, 0x00000000, 0x00000000},
+	{0x0000a3a8, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa},
+	{0x0000a3ac, 0xaaaaaa00, 0xaa30aa30, 0xaaaaaa00, 0xaaaaaa00},
+	{0x0000a41c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
+	{0x0000a420, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce},
+	{0x0000a424, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
+	{0x0000a428, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce},
+	{0x0000a42c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
+	{0x0000a430, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
+	{0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+	{0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000},
+	{0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+	{0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+	{0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
+};
+
+static const u32 ar9462_2p1_radio_core[][2] = {
+	/* Addr      allmodes  */
+	{0x00016000, 0x36db6db6},
+	{0x00016004, 0x6db6db40},
+	{0x00016008, 0x73f00000},
+	{0x0001600c, 0x00000000},
+	{0x00016010, 0x6d820001},
+	{0x00016040, 0x7f80fff8},
+	{0x0001604c, 0x2699e04f},
+	{0x00016050, 0x6db6db6c},
+	{0x00016058, 0x6c200000},
+	{0x00016080, 0x000c0000},
+	{0x00016084, 0x9a68048c},
+	{0x00016088, 0x54214514},
+	{0x0001608c, 0x1203040b},
+	{0x00016090, 0x24926490},
+	{0x00016098, 0xd2888888},
+	{0x000160a0, 0x0a108ffe},
+	{0x000160a4, 0x812fc491},
+	{0x000160a8, 0x423c8000},
+	{0x000160b4, 0x92000000},
+	{0x000160b8, 0x0285dddc},
+	{0x000160bc, 0x02908888},
+	{0x000160c0, 0x00adb6d0},
+	{0x000160c4, 0x6db6db60},
+	{0x000160c8, 0x6db6db6c},
+	{0x000160cc, 0x0de6c1b0},
+	{0x00016100, 0x3fffbe04},
+	{0x00016104, 0xfff80000},
+	{0x00016108, 0x00200400},
+	{0x00016110, 0x00000000},
+	{0x00016144, 0x02084080},
+	{0x00016148, 0x000080c0},
+	{0x00016280, 0x050a0001},
+	{0x00016284, 0x3d841418},
+	{0x00016288, 0x00000000},
+	{0x0001628c, 0xe3000000},
+	{0x00016290, 0xa1005080},
+	{0x00016294, 0x00000020},
+	{0x00016298, 0x54a82900},
+	{0x00016340, 0x121e4276},
+	{0x00016344, 0x00300000},
+	{0x00016400, 0x36db6db6},
+	{0x00016404, 0x6db6db40},
+	{0x00016408, 0x73f00000},
+	{0x0001640c, 0x00000000},
+	{0x00016410, 0x6c800001},
+	{0x00016440, 0x7f80fff8},
+	{0x0001644c, 0x4699e04f},
+	{0x00016450, 0x6db6db6c},
+	{0x00016500, 0x3fffbe04},
+	{0x00016504, 0xfff80000},
+	{0x00016508, 0x00200400},
+	{0x00016510, 0x00000000},
+	{0x00016544, 0x02084080},
+	{0x00016548, 0x000080c0},
+};
+
+static const u32 ar9462_2p1_radio_postamble[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
+	{0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
+	{0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
+	{0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
+};
+
+static const u32 ar9462_2p1_soc_preamble[][2] = {
+	/* Addr      allmodes  */
+	{0x000040a4, 0x00a0c1c9},
+	{0x00007020, 0x00000000},
+	{0x00007034, 0x00000002},
+	{0x00007038, 0x000004c2},
+};
+
+static const u32 ar9462_2p1_soc_postamble[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033},
+};
+
+static const u32 ar9462_2p1_radio_postamble_sys2ant[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
+	{0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
+	{0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
+};
+
+static const u32 ar9462_2p1_common_rx_gain[][2] = {
+	/* Addr      allmodes  */
+	{0x0000a000, 0x00010000},
+	{0x0000a004, 0x00030002},
+	{0x0000a008, 0x00050004},
+	{0x0000a00c, 0x00810080},
+	{0x0000a010, 0x00830082},
+	{0x0000a014, 0x01810180},
+	{0x0000a018, 0x01830182},
+	{0x0000a01c, 0x01850184},
+	{0x0000a020, 0x01890188},
+	{0x0000a024, 0x018b018a},
+	{0x0000a028, 0x018d018c},
+	{0x0000a02c, 0x01910190},
+	{0x0000a030, 0x01930192},
+	{0x0000a034, 0x01950194},
+	{0x0000a038, 0x038a0196},
+	{0x0000a03c, 0x038c038b},
+	{0x0000a040, 0x0390038d},
+	{0x0000a044, 0x03920391},
+	{0x0000a048, 0x03940393},
+	{0x0000a04c, 0x03960395},
+	{0x0000a050, 0x00000000},
+	{0x0000a054, 0x00000000},
+	{0x0000a058, 0x00000000},
+	{0x0000a05c, 0x00000000},
+	{0x0000a060, 0x00000000},
+	{0x0000a064, 0x00000000},
+	{0x0000a068, 0x00000000},
+	{0x0000a06c, 0x00000000},
+	{0x0000a070, 0x00000000},
+	{0x0000a074, 0x00000000},
+	{0x0000a078, 0x00000000},
+	{0x0000a07c, 0x00000000},
+	{0x0000a080, 0x22222229},
+	{0x0000a084, 0x1d1d1d1d},
+	{0x0000a088, 0x1d1d1d1d},
+	{0x0000a08c, 0x1d1d1d1d},
+	{0x0000a090, 0x171d1d1d},
+	{0x0000a094, 0x11111717},
+	{0x0000a098, 0x00030311},
+	{0x0000a09c, 0x00000000},
+	{0x0000a0a0, 0x00000000},
+	{0x0000a0a4, 0x00000000},
+	{0x0000a0a8, 0x00000000},
+	{0x0000a0ac, 0x00000000},
+	{0x0000a0b0, 0x00000000},
+	{0x0000a0b4, 0x00000000},
+	{0x0000a0b8, 0x00000000},
+	{0x0000a0bc, 0x00000000},
+	{0x0000a0c0, 0x001f0000},
+	{0x0000a0c4, 0x01000101},
+	{0x0000a0c8, 0x011e011f},
+	{0x0000a0cc, 0x011c011d},
+	{0x0000a0d0, 0x02030204},
+	{0x0000a0d4, 0x02010202},
+	{0x0000a0d8, 0x021f0200},
+	{0x0000a0dc, 0x0302021e},
+	{0x0000a0e0, 0x03000301},
+	{0x0000a0e4, 0x031e031f},
+	{0x0000a0e8, 0x0402031d},
+	{0x0000a0ec, 0x04000401},
+	{0x0000a0f0, 0x041e041f},
+	{0x0000a0f4, 0x0502041d},
+	{0x0000a0f8, 0x05000501},
+	{0x0000a0fc, 0x051e051f},
+	{0x0000a100, 0x06010602},
+	{0x0000a104, 0x061f0600},
+	{0x0000a108, 0x061d061e},
+	{0x0000a10c, 0x07020703},
+	{0x0000a110, 0x07000701},
+	{0x0000a114, 0x00000000},
+	{0x0000a118, 0x00000000},
+	{0x0000a11c, 0x00000000},
+	{0x0000a120, 0x00000000},
+	{0x0000a124, 0x00000000},
+	{0x0000a128, 0x00000000},
+	{0x0000a12c, 0x00000000},
+	{0x0000a130, 0x00000000},
+	{0x0000a134, 0x00000000},
+	{0x0000a138, 0x00000000},
+	{0x0000a13c, 0x00000000},
+	{0x0000a140, 0x001f0000},
+	{0x0000a144, 0x01000101},
+	{0x0000a148, 0x011e011f},
+	{0x0000a14c, 0x011c011d},
+	{0x0000a150, 0x02030204},
+	{0x0000a154, 0x02010202},
+	{0x0000a158, 0x021f0200},
+	{0x0000a15c, 0x0302021e},
+	{0x0000a160, 0x03000301},
+	{0x0000a164, 0x031e031f},
+	{0x0000a168, 0x0402031d},
+	{0x0000a16c, 0x04000401},
+	{0x0000a170, 0x041e041f},
+	{0x0000a174, 0x0502041d},
+	{0x0000a178, 0x05000501},
+	{0x0000a17c, 0x051e051f},
+	{0x0000a180, 0x06010602},
+	{0x0000a184, 0x061f0600},
+	{0x0000a188, 0x061d061e},
+	{0x0000a18c, 0x07020703},
+	{0x0000a190, 0x07000701},
+	{0x0000a194, 0x00000000},
+	{0x0000a198, 0x00000000},
+	{0x0000a19c, 0x00000000},
+	{0x0000a1a0, 0x00000000},
+	{0x0000a1a4, 0x00000000},
+	{0x0000a1a8, 0x00000000},
+	{0x0000a1ac, 0x00000000},
+	{0x0000a1b0, 0x00000000},
+	{0x0000a1b4, 0x00000000},
+	{0x0000a1b8, 0x00000000},
+	{0x0000a1bc, 0x00000000},
+	{0x0000a1c0, 0x00000000},
+	{0x0000a1c4, 0x00000000},
+	{0x0000a1c8, 0x00000000},
+	{0x0000a1cc, 0x00000000},
+	{0x0000a1d0, 0x00000000},
+	{0x0000a1d4, 0x00000000},
+	{0x0000a1d8, 0x00000000},
+	{0x0000a1dc, 0x00000000},
+	{0x0000a1e0, 0x00000000},
+	{0x0000a1e4, 0x00000000},
+	{0x0000a1e8, 0x00000000},
+	{0x0000a1ec, 0x00000000},
+	{0x0000a1f0, 0x00000396},
+	{0x0000a1f4, 0x00000396},
+	{0x0000a1f8, 0x00000396},
+	{0x0000a1fc, 0x00000196},
+	{0x0000b000, 0x00010000},
+	{0x0000b004, 0x00030002},
+	{0x0000b008, 0x00050004},
+	{0x0000b00c, 0x00810080},
+	{0x0000b010, 0x00830082},
+	{0x0000b014, 0x01810180},
+	{0x0000b018, 0x01830182},
+	{0x0000b01c, 0x01850184},
+	{0x0000b020, 0x02810280},
+	{0x0000b024, 0x02830282},
+	{0x0000b028, 0x02850284},
+	{0x0000b02c, 0x02890288},
+	{0x0000b030, 0x028b028a},
+	{0x0000b034, 0x0388028c},
+	{0x0000b038, 0x038a0389},
+	{0x0000b03c, 0x038c038b},
+	{0x0000b040, 0x0390038d},
+	{0x0000b044, 0x03920391},
+	{0x0000b048, 0x03940393},
+	{0x0000b04c, 0x03960395},
+	{0x0000b050, 0x00000000},
+	{0x0000b054, 0x00000000},
+	{0x0000b058, 0x00000000},
+	{0x0000b05c, 0x00000000},
+	{0x0000b060, 0x00000000},
+	{0x0000b064, 0x00000000},
+	{0x0000b068, 0x00000000},
+	{0x0000b06c, 0x00000000},
+	{0x0000b070, 0x00000000},
+	{0x0000b074, 0x00000000},
+	{0x0000b078, 0x00000000},
+	{0x0000b07c, 0x00000000},
+	{0x0000b080, 0x2a2d2f32},
+	{0x0000b084, 0x21232328},
+	{0x0000b088, 0x19191c1e},
+	{0x0000b08c, 0x12141417},
+	{0x0000b090, 0x07070e0e},
+	{0x0000b094, 0x03030305},
+	{0x0000b098, 0x00000003},
+	{0x0000b09c, 0x00000000},
+	{0x0000b0a0, 0x00000000},
+	{0x0000b0a4, 0x00000000},
+	{0x0000b0a8, 0x00000000},
+	{0x0000b0ac, 0x00000000},
+	{0x0000b0b0, 0x00000000},
+	{0x0000b0b4, 0x00000000},
+	{0x0000b0b8, 0x00000000},
+	{0x0000b0bc, 0x00000000},
+	{0x0000b0c0, 0x003f0020},
+	{0x0000b0c4, 0x00400041},
+	{0x0000b0c8, 0x0140005f},
+	{0x0000b0cc, 0x0160015f},
+	{0x0000b0d0, 0x017e017f},
+	{0x0000b0d4, 0x02410242},
+	{0x0000b0d8, 0x025f0240},
+	{0x0000b0dc, 0x027f0260},
+	{0x0000b0e0, 0x0341027e},
+	{0x0000b0e4, 0x035f0340},
+	{0x0000b0e8, 0x037f0360},
+	{0x0000b0ec, 0x04400441},
+	{0x0000b0f0, 0x0460045f},
+	{0x0000b0f4, 0x0541047f},
+	{0x0000b0f8, 0x055f0540},
+	{0x0000b0fc, 0x057f0560},
+	{0x0000b100, 0x06400641},
+	{0x0000b104, 0x0660065f},
+	{0x0000b108, 0x067e067f},
+	{0x0000b10c, 0x07410742},
+	{0x0000b110, 0x075f0740},
+	{0x0000b114, 0x077f0760},
+	{0x0000b118, 0x07800781},
+	{0x0000b11c, 0x07a0079f},
+	{0x0000b120, 0x07c107bf},
+	{0x0000b124, 0x000007c0},
+	{0x0000b128, 0x00000000},
+	{0x0000b12c, 0x00000000},
+	{0x0000b130, 0x00000000},
+	{0x0000b134, 0x00000000},
+	{0x0000b138, 0x00000000},
+	{0x0000b13c, 0x00000000},
+	{0x0000b140, 0x003f0020},
+	{0x0000b144, 0x00400041},
+	{0x0000b148, 0x0140005f},
+	{0x0000b14c, 0x0160015f},
+	{0x0000b150, 0x017e017f},
+	{0x0000b154, 0x02410242},
+	{0x0000b158, 0x025f0240},
+	{0x0000b15c, 0x027f0260},
+	{0x0000b160, 0x0341027e},
+	{0x0000b164, 0x035f0340},
+	{0x0000b168, 0x037f0360},
+	{0x0000b16c, 0x04400441},
+	{0x0000b170, 0x0460045f},
+	{0x0000b174, 0x0541047f},
+	{0x0000b178, 0x055f0540},
+	{0x0000b17c, 0x057f0560},
+	{0x0000b180, 0x06400641},
+	{0x0000b184, 0x0660065f},
+	{0x0000b188, 0x067e067f},
+	{0x0000b18c, 0x07410742},
+	{0x0000b190, 0x075f0740},
+	{0x0000b194, 0x077f0760},
+	{0x0000b198, 0x07800781},
+	{0x0000b19c, 0x07a0079f},
+	{0x0000b1a0, 0x07c107bf},
+	{0x0000b1a4, 0x000007c0},
+	{0x0000b1a8, 0x00000000},
+	{0x0000b1ac, 0x00000000},
+	{0x0000b1b0, 0x00000000},
+	{0x0000b1b4, 0x00000000},
+	{0x0000b1b8, 0x00000000},
+	{0x0000b1bc, 0x00000000},
+	{0x0000b1c0, 0x00000000},
+	{0x0000b1c4, 0x00000000},
+	{0x0000b1c8, 0x00000000},
+	{0x0000b1cc, 0x00000000},
+	{0x0000b1d0, 0x00000000},
+	{0x0000b1d4, 0x00000000},
+	{0x0000b1d8, 0x00000000},
+	{0x0000b1dc, 0x00000000},
+	{0x0000b1e0, 0x00000000},
+	{0x0000b1e4, 0x00000000},
+	{0x0000b1e8, 0x00000000},
+	{0x0000b1ec, 0x00000000},
+	{0x0000b1f0, 0x00000396},
+	{0x0000b1f4, 0x00000396},
+	{0x0000b1f8, 0x00000396},
+	{0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9462_2p1_common_mixed_rx_gain[][2] = {
+	/* Addr      allmodes  */
+	{0x0000a000, 0x00010000},
+	{0x0000a004, 0x00030002},
+	{0x0000a008, 0x00050004},
+	{0x0000a00c, 0x00810080},
+	{0x0000a010, 0x00830082},
+	{0x0000a014, 0x01810180},
+	{0x0000a018, 0x01830182},
+	{0x0000a01c, 0x01850184},
+	{0x0000a020, 0x01890188},
+	{0x0000a024, 0x018b018a},
+	{0x0000a028, 0x018d018c},
+	{0x0000a02c, 0x03820190},
+	{0x0000a030, 0x03840383},
+	{0x0000a034, 0x03880385},
+	{0x0000a038, 0x038a0389},
+	{0x0000a03c, 0x038c038b},
+	{0x0000a040, 0x0390038d},
+	{0x0000a044, 0x03920391},
+	{0x0000a048, 0x03940393},
+	{0x0000a04c, 0x03960395},
+	{0x0000a050, 0x00000000},
+	{0x0000a054, 0x00000000},
+	{0x0000a058, 0x00000000},
+	{0x0000a05c, 0x00000000},
+	{0x0000a060, 0x00000000},
+	{0x0000a064, 0x00000000},
+	{0x0000a068, 0x00000000},
+	{0x0000a06c, 0x00000000},
+	{0x0000a070, 0x00000000},
+	{0x0000a074, 0x00000000},
+	{0x0000a078, 0x00000000},
+	{0x0000a07c, 0x00000000},
+	{0x0000a080, 0x29292929},
+	{0x0000a084, 0x29292929},
+	{0x0000a088, 0x29292929},
+	{0x0000a08c, 0x29292929},
+	{0x0000a090, 0x22292929},
+	{0x0000a094, 0x1d1d2222},
+	{0x0000a098, 0x0c111117},
+	{0x0000a09c, 0x00030303},
+	{0x0000a0a0, 0x00000000},
+	{0x0000a0a4, 0x00000000},
+	{0x0000a0a8, 0x00000000},
+	{0x0000a0ac, 0x00000000},
+	{0x0000a0b0, 0x00000000},
+	{0x0000a0b4, 0x00000000},
+	{0x0000a0b8, 0x00000000},
+	{0x0000a0bc, 0x00000000},
+	{0x0000a0c0, 0x001f0000},
+	{0x0000a0c4, 0x01000101},
+	{0x0000a0c8, 0x011e011f},
+	{0x0000a0cc, 0x011c011d},
+	{0x0000a0d0, 0x02030204},
+	{0x0000a0d4, 0x02010202},
+	{0x0000a0d8, 0x021f0200},
+	{0x0000a0dc, 0x0302021e},
+	{0x0000a0e0, 0x03000301},
+	{0x0000a0e4, 0x031e031f},
+	{0x0000a0e8, 0x0402031d},
+	{0x0000a0ec, 0x04000401},
+	{0x0000a0f0, 0x041e041f},
+	{0x0000a0f4, 0x0502041d},
+	{0x0000a0f8, 0x05000501},
+	{0x0000a0fc, 0x051e051f},
+	{0x0000a100, 0x06010602},
+	{0x0000a104, 0x061f0600},
+	{0x0000a108, 0x061d061e},
+	{0x0000a10c, 0x07020703},
+	{0x0000a110, 0x07000701},
+	{0x0000a114, 0x00000000},
+	{0x0000a118, 0x00000000},
+	{0x0000a11c, 0x00000000},
+	{0x0000a120, 0x00000000},
+	{0x0000a124, 0x00000000},
+	{0x0000a128, 0x00000000},
+	{0x0000a12c, 0x00000000},
+	{0x0000a130, 0x00000000},
+	{0x0000a134, 0x00000000},
+	{0x0000a138, 0x00000000},
+	{0x0000a13c, 0x00000000},
+	{0x0000a140, 0x001f0000},
+	{0x0000a144, 0x01000101},
+	{0x0000a148, 0x011e011f},
+	{0x0000a14c, 0x011c011d},
+	{0x0000a150, 0x02030204},
+	{0x0000a154, 0x02010202},
+	{0x0000a158, 0x021f0200},
+	{0x0000a15c, 0x0302021e},
+	{0x0000a160, 0x03000301},
+	{0x0000a164, 0x031e031f},
+	{0x0000a168, 0x0402031d},
+	{0x0000a16c, 0x04000401},
+	{0x0000a170, 0x041e041f},
+	{0x0000a174, 0x0502041d},
+	{0x0000a178, 0x05000501},
+	{0x0000a17c, 0x051e051f},
+	{0x0000a180, 0x06010602},
+	{0x0000a184, 0x061f0600},
+	{0x0000a188, 0x061d061e},
+	{0x0000a18c, 0x07020703},
+	{0x0000a190, 0x07000701},
+	{0x0000a194, 0x00000000},
+	{0x0000a198, 0x00000000},
+	{0x0000a19c, 0x00000000},
+	{0x0000a1a0, 0x00000000},
+	{0x0000a1a4, 0x00000000},
+	{0x0000a1a8, 0x00000000},
+	{0x0000a1ac, 0x00000000},
+	{0x0000a1b0, 0x00000000},
+	{0x0000a1b4, 0x00000000},
+	{0x0000a1b8, 0x00000000},
+	{0x0000a1bc, 0x00000000},
+	{0x0000a1c0, 0x00000000},
+	{0x0000a1c4, 0x00000000},
+	{0x0000a1c8, 0x00000000},
+	{0x0000a1cc, 0x00000000},
+	{0x0000a1d0, 0x00000000},
+	{0x0000a1d4, 0x00000000},
+	{0x0000a1d8, 0x00000000},
+	{0x0000a1dc, 0x00000000},
+	{0x0000a1e0, 0x00000000},
+	{0x0000a1e4, 0x00000000},
+	{0x0000a1e8, 0x00000000},
+	{0x0000a1ec, 0x00000000},
+	{0x0000a1f0, 0x00000396},
+	{0x0000a1f4, 0x00000396},
+	{0x0000a1f8, 0x00000396},
+	{0x0000a1fc, 0x00000196},
+	{0x0000b000, 0x00010000},
+	{0x0000b004, 0x00030002},
+	{0x0000b008, 0x00050004},
+	{0x0000b00c, 0x00810080},
+	{0x0000b010, 0x00830082},
+	{0x0000b014, 0x01810180},
+	{0x0000b018, 0x01830182},
+	{0x0000b01c, 0x01850184},
+	{0x0000b020, 0x02810280},
+	{0x0000b024, 0x02830282},
+	{0x0000b028, 0x02850284},
+	{0x0000b02c, 0x02890288},
+	{0x0000b030, 0x028b028a},
+	{0x0000b034, 0x0388028c},
+	{0x0000b038, 0x038a0389},
+	{0x0000b03c, 0x038c038b},
+	{0x0000b040, 0x0390038d},
+	{0x0000b044, 0x03920391},
+	{0x0000b048, 0x03940393},
+	{0x0000b04c, 0x03960395},
+	{0x0000b050, 0x00000000},
+	{0x0000b054, 0x00000000},
+	{0x0000b058, 0x00000000},
+	{0x0000b05c, 0x00000000},
+	{0x0000b060, 0x00000000},
+	{0x0000b064, 0x00000000},
+	{0x0000b068, 0x00000000},
+	{0x0000b06c, 0x00000000},
+	{0x0000b070, 0x00000000},
+	{0x0000b074, 0x00000000},
+	{0x0000b078, 0x00000000},
+	{0x0000b07c, 0x00000000},
+	{0x0000b080, 0x2a2d2f32},
+	{0x0000b084, 0x21232328},
+	{0x0000b088, 0x19191c1e},
+	{0x0000b08c, 0x12141417},
+	{0x0000b090, 0x07070e0e},
+	{0x0000b094, 0x03030305},
+	{0x0000b098, 0x00000003},
+	{0x0000b09c, 0x00000000},
+	{0x0000b0a0, 0x00000000},
+	{0x0000b0a4, 0x00000000},
+	{0x0000b0a8, 0x00000000},
+	{0x0000b0ac, 0x00000000},
+	{0x0000b0b0, 0x00000000},
+	{0x0000b0b4, 0x00000000},
+	{0x0000b0b8, 0x00000000},
+	{0x0000b0bc, 0x00000000},
+	{0x0000b0c0, 0x003f0020},
+	{0x0000b0c4, 0x00400041},
+	{0x0000b0c8, 0x0140005f},
+	{0x0000b0cc, 0x0160015f},
+	{0x0000b0d0, 0x017e017f},
+	{0x0000b0d4, 0x02410242},
+	{0x0000b0d8, 0x025f0240},
+	{0x0000b0dc, 0x027f0260},
+	{0x0000b0e0, 0x0341027e},
+	{0x0000b0e4, 0x035f0340},
+	{0x0000b0e8, 0x037f0360},
+	{0x0000b0ec, 0x04400441},
+	{0x0000b0f0, 0x0460045f},
+	{0x0000b0f4, 0x0541047f},
+	{0x0000b0f8, 0x055f0540},
+	{0x0000b0fc, 0x057f0560},
+	{0x0000b100, 0x06400641},
+	{0x0000b104, 0x0660065f},
+	{0x0000b108, 0x067e067f},
+	{0x0000b10c, 0x07410742},
+	{0x0000b110, 0x075f0740},
+	{0x0000b114, 0x077f0760},
+	{0x0000b118, 0x07800781},
+	{0x0000b11c, 0x07a0079f},
+	{0x0000b120, 0x07c107bf},
+	{0x0000b124, 0x000007c0},
+	{0x0000b128, 0x00000000},
+	{0x0000b12c, 0x00000000},
+	{0x0000b130, 0x00000000},
+	{0x0000b134, 0x00000000},
+	{0x0000b138, 0x00000000},
+	{0x0000b13c, 0x00000000},
+	{0x0000b140, 0x003f0020},
+	{0x0000b144, 0x00400041},
+	{0x0000b148, 0x0140005f},
+	{0x0000b14c, 0x0160015f},
+	{0x0000b150, 0x017e017f},
+	{0x0000b154, 0x02410242},
+	{0x0000b158, 0x025f0240},
+	{0x0000b15c, 0x027f0260},
+	{0x0000b160, 0x0341027e},
+	{0x0000b164, 0x035f0340},
+	{0x0000b168, 0x037f0360},
+	{0x0000b16c, 0x04400441},
+	{0x0000b170, 0x0460045f},
+	{0x0000b174, 0x0541047f},
+	{0x0000b178, 0x055f0540},
+	{0x0000b17c, 0x057f0560},
+	{0x0000b180, 0x06400641},
+	{0x0000b184, 0x0660065f},
+	{0x0000b188, 0x067e067f},
+	{0x0000b18c, 0x07410742},
+	{0x0000b190, 0x075f0740},
+	{0x0000b194, 0x077f0760},
+	{0x0000b198, 0x07800781},
+	{0x0000b19c, 0x07a0079f},
+	{0x0000b1a0, 0x07c107bf},
+	{0x0000b1a4, 0x000007c0},
+	{0x0000b1a8, 0x00000000},
+	{0x0000b1ac, 0x00000000},
+	{0x0000b1b0, 0x00000000},
+	{0x0000b1b4, 0x00000000},
+	{0x0000b1b8, 0x00000000},
+	{0x0000b1bc, 0x00000000},
+	{0x0000b1c0, 0x00000000},
+	{0x0000b1c4, 0x00000000},
+	{0x0000b1c8, 0x00000000},
+	{0x0000b1cc, 0x00000000},
+	{0x0000b1d0, 0x00000000},
+	{0x0000b1d4, 0x00000000},
+	{0x0000b1d8, 0x00000000},
+	{0x0000b1dc, 0x00000000},
+	{0x0000b1e0, 0x00000000},
+	{0x0000b1e4, 0x00000000},
+	{0x0000b1e8, 0x00000000},
+	{0x0000b1ec, 0x00000000},
+	{0x0000b1f0, 0x00000396},
+	{0x0000b1f4, 0x00000396},
+	{0x0000b1f8, 0x00000396},
+	{0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9462_2p1_baseband_core_mix_rxgain[][2] = {
+	/* Addr      allmodes  */
+	{0x00009fd0, 0x0a2d6b93},
+};
+
+static const u32 ar9462_2p1_baseband_postamble_mix_rxgain[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
+	{0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da},
+	{0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81},
+	{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8},
+	{0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e},
+	{0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e},
+};
+
+static const u32 ar9462_2p1_baseband_postamble_5g_xlna[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
+};
+
+static const u32 ar9462_2p1_common_wo_xlna_rx_gain[][2] = {
+	/* Addr      allmodes  */
+	{0x0000a000, 0x00010000},
+	{0x0000a004, 0x00030002},
+	{0x0000a008, 0x00050004},
+	{0x0000a00c, 0x00810080},
+	{0x0000a010, 0x00830082},
+	{0x0000a014, 0x01810180},
+	{0x0000a018, 0x01830182},
+	{0x0000a01c, 0x01850184},
+	{0x0000a020, 0x01890188},
+	{0x0000a024, 0x018b018a},
+	{0x0000a028, 0x018d018c},
+	{0x0000a02c, 0x03820190},
+	{0x0000a030, 0x03840383},
+	{0x0000a034, 0x03880385},
+	{0x0000a038, 0x038a0389},
+	{0x0000a03c, 0x038c038b},
+	{0x0000a040, 0x0390038d},
+	{0x0000a044, 0x03920391},
+	{0x0000a048, 0x03940393},
+	{0x0000a04c, 0x03960395},
+	{0x0000a050, 0x00000000},
+	{0x0000a054, 0x00000000},
+	{0x0000a058, 0x00000000},
+	{0x0000a05c, 0x00000000},
+	{0x0000a060, 0x00000000},
+	{0x0000a064, 0x00000000},
+	{0x0000a068, 0x00000000},
+	{0x0000a06c, 0x00000000},
+	{0x0000a070, 0x00000000},
+	{0x0000a074, 0x00000000},
+	{0x0000a078, 0x00000000},
+	{0x0000a07c, 0x00000000},
+	{0x0000a080, 0x29292929},
+	{0x0000a084, 0x29292929},
+	{0x0000a088, 0x29292929},
+	{0x0000a08c, 0x29292929},
+	{0x0000a090, 0x22292929},
+	{0x0000a094, 0x1d1d2222},
+	{0x0000a098, 0x0c111117},
+	{0x0000a09c, 0x00030303},
+	{0x0000a0a0, 0x00000000},
+	{0x0000a0a4, 0x00000000},
+	{0x0000a0a8, 0x00000000},
+	{0x0000a0ac, 0x00000000},
+	{0x0000a0b0, 0x00000000},
+	{0x0000a0b4, 0x00000000},
+	{0x0000a0b8, 0x00000000},
+	{0x0000a0bc, 0x00000000},
+	{0x0000a0c0, 0x001f0000},
+	{0x0000a0c4, 0x01000101},
+	{0x0000a0c8, 0x011e011f},
+	{0x0000a0cc, 0x011c011d},
+	{0x0000a0d0, 0x02030204},
+	{0x0000a0d4, 0x02010202},
+	{0x0000a0d8, 0x021f0200},
+	{0x0000a0dc, 0x0302021e},
+	{0x0000a0e0, 0x03000301},
+	{0x0000a0e4, 0x031e031f},
+	{0x0000a0e8, 0x0402031d},
+	{0x0000a0ec, 0x04000401},
+	{0x0000a0f0, 0x041e041f},
+	{0x0000a0f4, 0x0502041d},
+	{0x0000a0f8, 0x05000501},
+	{0x0000a0fc, 0x051e051f},
+	{0x0000a100, 0x06010602},
+	{0x0000a104, 0x061f0600},
+	{0x0000a108, 0x061d061e},
+	{0x0000a10c, 0x07020703},
+	{0x0000a110, 0x07000701},
+	{0x0000a114, 0x00000000},
+	{0x0000a118, 0x00000000},
+	{0x0000a11c, 0x00000000},
+	{0x0000a120, 0x00000000},
+	{0x0000a124, 0x00000000},
+	{0x0000a128, 0x00000000},
+	{0x0000a12c, 0x00000000},
+	{0x0000a130, 0x00000000},
+	{0x0000a134, 0x00000000},
+	{0x0000a138, 0x00000000},
+	{0x0000a13c, 0x00000000},
+	{0x0000a140, 0x001f0000},
+	{0x0000a144, 0x01000101},
+	{0x0000a148, 0x011e011f},
+	{0x0000a14c, 0x011c011d},
+	{0x0000a150, 0x02030204},
+	{0x0000a154, 0x02010202},
+	{0x0000a158, 0x021f0200},
+	{0x0000a15c, 0x0302021e},
+	{0x0000a160, 0x03000301},
+	{0x0000a164, 0x031e031f},
+	{0x0000a168, 0x0402031d},
+	{0x0000a16c, 0x04000401},
+	{0x0000a170, 0x041e041f},
+	{0x0000a174, 0x0502041d},
+	{0x0000a178, 0x05000501},
+	{0x0000a17c, 0x051e051f},
+	{0x0000a180, 0x06010602},
+	{0x0000a184, 0x061f0600},
+	{0x0000a188, 0x061d061e},
+	{0x0000a18c, 0x07020703},
+	{0x0000a190, 0x07000701},
+	{0x0000a194, 0x00000000},
+	{0x0000a198, 0x00000000},
+	{0x0000a19c, 0x00000000},
+	{0x0000a1a0, 0x00000000},
+	{0x0000a1a4, 0x00000000},
+	{0x0000a1a8, 0x00000000},
+	{0x0000a1ac, 0x00000000},
+	{0x0000a1b0, 0x00000000},
+	{0x0000a1b4, 0x00000000},
+	{0x0000a1b8, 0x00000000},
+	{0x0000a1bc, 0x00000000},
+	{0x0000a1c0, 0x00000000},
+	{0x0000a1c4, 0x00000000},
+	{0x0000a1c8, 0x00000000},
+	{0x0000a1cc, 0x00000000},
+	{0x0000a1d0, 0x00000000},
+	{0x0000a1d4, 0x00000000},
+	{0x0000a1d8, 0x00000000},
+	{0x0000a1dc, 0x00000000},
+	{0x0000a1e0, 0x00000000},
+	{0x0000a1e4, 0x00000000},
+	{0x0000a1e8, 0x00000000},
+	{0x0000a1ec, 0x00000000},
+	{0x0000a1f0, 0x00000396},
+	{0x0000a1f4, 0x00000396},
+	{0x0000a1f8, 0x00000396},
+	{0x0000a1fc, 0x00000196},
+	{0x0000b000, 0x00010000},
+	{0x0000b004, 0x00030002},
+	{0x0000b008, 0x00050004},
+	{0x0000b00c, 0x00810080},
+	{0x0000b010, 0x00830082},
+	{0x0000b014, 0x01810180},
+	{0x0000b018, 0x01830182},
+	{0x0000b01c, 0x01850184},
+	{0x0000b020, 0x02810280},
+	{0x0000b024, 0x02830282},
+	{0x0000b028, 0x02850284},
+	{0x0000b02c, 0x02890288},
+	{0x0000b030, 0x028b028a},
+	{0x0000b034, 0x0388028c},
+	{0x0000b038, 0x038a0389},
+	{0x0000b03c, 0x038c038b},
+	{0x0000b040, 0x0390038d},
+	{0x0000b044, 0x03920391},
+	{0x0000b048, 0x03940393},
+	{0x0000b04c, 0x03960395},
+	{0x0000b050, 0x00000000},
+	{0x0000b054, 0x00000000},
+	{0x0000b058, 0x00000000},
+	{0x0000b05c, 0x00000000},
+	{0x0000b060, 0x00000000},
+	{0x0000b064, 0x00000000},
+	{0x0000b068, 0x00000000},
+	{0x0000b06c, 0x00000000},
+	{0x0000b070, 0x00000000},
+	{0x0000b074, 0x00000000},
+	{0x0000b078, 0x00000000},
+	{0x0000b07c, 0x00000000},
+	{0x0000b080, 0x32323232},
+	{0x0000b084, 0x2f2f3232},
+	{0x0000b088, 0x23282a2d},
+	{0x0000b08c, 0x1c1e2123},
+	{0x0000b090, 0x14171919},
+	{0x0000b094, 0x0e0e1214},
+	{0x0000b098, 0x03050707},
+	{0x0000b09c, 0x00030303},
+	{0x0000b0a0, 0x00000000},
+	{0x0000b0a4, 0x00000000},
+	{0x0000b0a8, 0x00000000},
+	{0x0000b0ac, 0x00000000},
+	{0x0000b0b0, 0x00000000},
+	{0x0000b0b4, 0x00000000},
+	{0x0000b0b8, 0x00000000},
+	{0x0000b0bc, 0x00000000},
+	{0x0000b0c0, 0x003f0020},
+	{0x0000b0c4, 0x00400041},
+	{0x0000b0c8, 0x0140005f},
+	{0x0000b0cc, 0x0160015f},
+	{0x0000b0d0, 0x017e017f},
+	{0x0000b0d4, 0x02410242},
+	{0x0000b0d8, 0x025f0240},
+	{0x0000b0dc, 0x027f0260},
+	{0x0000b0e0, 0x0341027e},
+	{0x0000b0e4, 0x035f0340},
+	{0x0000b0e8, 0x037f0360},
+	{0x0000b0ec, 0x04400441},
+	{0x0000b0f0, 0x0460045f},
+	{0x0000b0f4, 0x0541047f},
+	{0x0000b0f8, 0x055f0540},
+	{0x0000b0fc, 0x057f0560},
+	{0x0000b100, 0x06400641},
+	{0x0000b104, 0x0660065f},
+	{0x0000b108, 0x067e067f},
+	{0x0000b10c, 0x07410742},
+	{0x0000b110, 0x075f0740},
+	{0x0000b114, 0x077f0760},
+	{0x0000b118, 0x07800781},
+	{0x0000b11c, 0x07a0079f},
+	{0x0000b120, 0x07c107bf},
+	{0x0000b124, 0x000007c0},
+	{0x0000b128, 0x00000000},
+	{0x0000b12c, 0x00000000},
+	{0x0000b130, 0x00000000},
+	{0x0000b134, 0x00000000},
+	{0x0000b138, 0x00000000},
+	{0x0000b13c, 0x00000000},
+	{0x0000b140, 0x003f0020},
+	{0x0000b144, 0x00400041},
+	{0x0000b148, 0x0140005f},
+	{0x0000b14c, 0x0160015f},
+	{0x0000b150, 0x017e017f},
+	{0x0000b154, 0x02410242},
+	{0x0000b158, 0x025f0240},
+	{0x0000b15c, 0x027f0260},
+	{0x0000b160, 0x0341027e},
+	{0x0000b164, 0x035f0340},
+	{0x0000b168, 0x037f0360},
+	{0x0000b16c, 0x04400441},
+	{0x0000b170, 0x0460045f},
+	{0x0000b174, 0x0541047f},
+	{0x0000b178, 0x055f0540},
+	{0x0000b17c, 0x057f0560},
+	{0x0000b180, 0x06400641},
+	{0x0000b184, 0x0660065f},
+	{0x0000b188, 0x067e067f},
+	{0x0000b18c, 0x07410742},
+	{0x0000b190, 0x075f0740},
+	{0x0000b194, 0x077f0760},
+	{0x0000b198, 0x07800781},
+	{0x0000b19c, 0x07a0079f},
+	{0x0000b1a0, 0x07c107bf},
+	{0x0000b1a4, 0x000007c0},
+	{0x0000b1a8, 0x00000000},
+	{0x0000b1ac, 0x00000000},
+	{0x0000b1b0, 0x00000000},
+	{0x0000b1b4, 0x00000000},
+	{0x0000b1b8, 0x00000000},
+	{0x0000b1bc, 0x00000000},
+	{0x0000b1c0, 0x00000000},
+	{0x0000b1c4, 0x00000000},
+	{0x0000b1c8, 0x00000000},
+	{0x0000b1cc, 0x00000000},
+	{0x0000b1d0, 0x00000000},
+	{0x0000b1d4, 0x00000000},
+	{0x0000b1d8, 0x00000000},
+	{0x0000b1dc, 0x00000000},
+	{0x0000b1e0, 0x00000000},
+	{0x0000b1e4, 0x00000000},
+	{0x0000b1e8, 0x00000000},
+	{0x0000b1ec, 0x00000000},
+	{0x0000b1f0, 0x00000396},
+	{0x0000b1f4, 0x00000396},
+	{0x0000b1f8, 0x00000396},
+	{0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9462_2p1_common_5g_xlna_only_rx_gain[][2] = {
+	/* Addr      allmodes  */
+	{0x0000a000, 0x00010000},
+	{0x0000a004, 0x00030002},
+	{0x0000a008, 0x00050004},
+	{0x0000a00c, 0x00810080},
+	{0x0000a010, 0x00830082},
+	{0x0000a014, 0x01810180},
+	{0x0000a018, 0x01830182},
+	{0x0000a01c, 0x01850184},
+	{0x0000a020, 0x01890188},
+	{0x0000a024, 0x018b018a},
+	{0x0000a028, 0x018d018c},
+	{0x0000a02c, 0x03820190},
+	{0x0000a030, 0x03840383},
+	{0x0000a034, 0x03880385},
+	{0x0000a038, 0x038a0389},
+	{0x0000a03c, 0x038c038b},
+	{0x0000a040, 0x0390038d},
+	{0x0000a044, 0x03920391},
+	{0x0000a048, 0x03940393},
+	{0x0000a04c, 0x03960395},
+	{0x0000a050, 0x00000000},
+	{0x0000a054, 0x00000000},
+	{0x0000a058, 0x00000000},
+	{0x0000a05c, 0x00000000},
+	{0x0000a060, 0x00000000},
+	{0x0000a064, 0x00000000},
+	{0x0000a068, 0x00000000},
+	{0x0000a06c, 0x00000000},
+	{0x0000a070, 0x00000000},
+	{0x0000a074, 0x00000000},
+	{0x0000a078, 0x00000000},
+	{0x0000a07c, 0x00000000},
+	{0x0000a080, 0x29292929},
+	{0x0000a084, 0x29292929},
+	{0x0000a088, 0x29292929},
+	{0x0000a08c, 0x29292929},
+	{0x0000a090, 0x22292929},
+	{0x0000a094, 0x1d1d2222},
+	{0x0000a098, 0x0c111117},
+	{0x0000a09c, 0x00030303},
+	{0x0000a0a0, 0x00000000},
+	{0x0000a0a4, 0x00000000},
+	{0x0000a0a8, 0x00000000},
+	{0x0000a0ac, 0x00000000},
+	{0x0000a0b0, 0x00000000},
+	{0x0000a0b4, 0x00000000},
+	{0x0000a0b8, 0x00000000},
+	{0x0000a0bc, 0x00000000},
+	{0x0000a0c0, 0x001f0000},
+	{0x0000a0c4, 0x01000101},
+	{0x0000a0c8, 0x011e011f},
+	{0x0000a0cc, 0x011c011d},
+	{0x0000a0d0, 0x02030204},
+	{0x0000a0d4, 0x02010202},
+	{0x0000a0d8, 0x021f0200},
+	{0x0000a0dc, 0x0302021e},
+	{0x0000a0e0, 0x03000301},
+	{0x0000a0e4, 0x031e031f},
+	{0x0000a0e8, 0x0402031d},
+	{0x0000a0ec, 0x04000401},
+	{0x0000a0f0, 0x041e041f},
+	{0x0000a0f4, 0x0502041d},
+	{0x0000a0f8, 0x05000501},
+	{0x0000a0fc, 0x051e051f},
+	{0x0000a100, 0x06010602},
+	{0x0000a104, 0x061f0600},
+	{0x0000a108, 0x061d061e},
+	{0x0000a10c, 0x07020703},
+	{0x0000a110, 0x07000701},
+	{0x0000a114, 0x00000000},
+	{0x0000a118, 0x00000000},
+	{0x0000a11c, 0x00000000},
+	{0x0000a120, 0x00000000},
+	{0x0000a124, 0x00000000},
+	{0x0000a128, 0x00000000},
+	{0x0000a12c, 0x00000000},
+	{0x0000a130, 0x00000000},
+	{0x0000a134, 0x00000000},
+	{0x0000a138, 0x00000000},
+	{0x0000a13c, 0x00000000},
+	{0x0000a140, 0x001f0000},
+	{0x0000a144, 0x01000101},
+	{0x0000a148, 0x011e011f},
+	{0x0000a14c, 0x011c011d},
+	{0x0000a150, 0x02030204},
+	{0x0000a154, 0x02010202},
+	{0x0000a158, 0x021f0200},
+	{0x0000a15c, 0x0302021e},
+	{0x0000a160, 0x03000301},
+	{0x0000a164, 0x031e031f},
+	{0x0000a168, 0x0402031d},
+	{0x0000a16c, 0x04000401},
+	{0x0000a170, 0x041e041f},
+	{0x0000a174, 0x0502041d},
+	{0x0000a178, 0x05000501},
+	{0x0000a17c, 0x051e051f},
+	{0x0000a180, 0x06010602},
+	{0x0000a184, 0x061f0600},
+	{0x0000a188, 0x061d061e},
+	{0x0000a18c, 0x07020703},
+	{0x0000a190, 0x07000701},
+	{0x0000a194, 0x00000000},
+	{0x0000a198, 0x00000000},
+	{0x0000a19c, 0x00000000},
+	{0x0000a1a0, 0x00000000},
+	{0x0000a1a4, 0x00000000},
+	{0x0000a1a8, 0x00000000},
+	{0x0000a1ac, 0x00000000},
+	{0x0000a1b0, 0x00000000},
+	{0x0000a1b4, 0x00000000},
+	{0x0000a1b8, 0x00000000},
+	{0x0000a1bc, 0x00000000},
+	{0x0000a1c0, 0x00000000},
+	{0x0000a1c4, 0x00000000},
+	{0x0000a1c8, 0x00000000},
+	{0x0000a1cc, 0x00000000},
+	{0x0000a1d0, 0x00000000},
+	{0x0000a1d4, 0x00000000},
+	{0x0000a1d8, 0x00000000},
+	{0x0000a1dc, 0x00000000},
+	{0x0000a1e0, 0x00000000},
+	{0x0000a1e4, 0x00000000},
+	{0x0000a1e8, 0x00000000},
+	{0x0000a1ec, 0x00000000},
+	{0x0000a1f0, 0x00000396},
+	{0x0000a1f4, 0x00000396},
+	{0x0000a1f8, 0x00000396},
+	{0x0000a1fc, 0x00000196},
+	{0x0000b000, 0x00010000},
+	{0x0000b004, 0x00030002},
+	{0x0000b008, 0x00050004},
+	{0x0000b00c, 0x00810080},
+	{0x0000b010, 0x00830082},
+	{0x0000b014, 0x01810180},
+	{0x0000b018, 0x01830182},
+	{0x0000b01c, 0x01850184},
+	{0x0000b020, 0x02810280},
+	{0x0000b024, 0x02830282},
+	{0x0000b028, 0x02850284},
+	{0x0000b02c, 0x02890288},
+	{0x0000b030, 0x028b028a},
+	{0x0000b034, 0x0388028c},
+	{0x0000b038, 0x038a0389},
+	{0x0000b03c, 0x038c038b},
+	{0x0000b040, 0x0390038d},
+	{0x0000b044, 0x03920391},
+	{0x0000b048, 0x03940393},
+	{0x0000b04c, 0x03960395},
+	{0x0000b050, 0x00000000},
+	{0x0000b054, 0x00000000},
+	{0x0000b058, 0x00000000},
+	{0x0000b05c, 0x00000000},
+	{0x0000b060, 0x00000000},
+	{0x0000b064, 0x00000000},
+	{0x0000b068, 0x00000000},
+	{0x0000b06c, 0x00000000},
+	{0x0000b070, 0x00000000},
+	{0x0000b074, 0x00000000},
+	{0x0000b078, 0x00000000},
+	{0x0000b07c, 0x00000000},
+	{0x0000b080, 0x2a2d2f32},
+	{0x0000b084, 0x21232328},
+	{0x0000b088, 0x19191c1e},
+	{0x0000b08c, 0x12141417},
+	{0x0000b090, 0x07070e0e},
+	{0x0000b094, 0x03030305},
+	{0x0000b098, 0x00000003},
+	{0x0000b09c, 0x00000000},
+	{0x0000b0a0, 0x00000000},
+	{0x0000b0a4, 0x00000000},
+	{0x0000b0a8, 0x00000000},
+	{0x0000b0ac, 0x00000000},
+	{0x0000b0b0, 0x00000000},
+	{0x0000b0b4, 0x00000000},
+	{0x0000b0b8, 0x00000000},
+	{0x0000b0bc, 0x00000000},
+	{0x0000b0c0, 0x003f0020},
+	{0x0000b0c4, 0x00400041},
+	{0x0000b0c8, 0x0140005f},
+	{0x0000b0cc, 0x0160015f},
+	{0x0000b0d0, 0x017e017f},
+	{0x0000b0d4, 0x02410242},
+	{0x0000b0d8, 0x025f0240},
+	{0x0000b0dc, 0x027f0260},
+	{0x0000b0e0, 0x0341027e},
+	{0x0000b0e4, 0x035f0340},
+	{0x0000b0e8, 0x037f0360},
+	{0x0000b0ec, 0x04400441},
+	{0x0000b0f0, 0x0460045f},
+	{0x0000b0f4, 0x0541047f},
+	{0x0000b0f8, 0x055f0540},
+	{0x0000b0fc, 0x057f0560},
+	{0x0000b100, 0x06400641},
+	{0x0000b104, 0x0660065f},
+	{0x0000b108, 0x067e067f},
+	{0x0000b10c, 0x07410742},
+	{0x0000b110, 0x075f0740},
+	{0x0000b114, 0x077f0760},
+	{0x0000b118, 0x07800781},
+	{0x0000b11c, 0x07a0079f},
+	{0x0000b120, 0x07c107bf},
+	{0x0000b124, 0x000007c0},
+	{0x0000b128, 0x00000000},
+	{0x0000b12c, 0x00000000},
+	{0x0000b130, 0x00000000},
+	{0x0000b134, 0x00000000},
+	{0x0000b138, 0x00000000},
+	{0x0000b13c, 0x00000000},
+	{0x0000b140, 0x003f0020},
+	{0x0000b144, 0x00400041},
+	{0x0000b148, 0x0140005f},
+	{0x0000b14c, 0x0160015f},
+	{0x0000b150, 0x017e017f},
+	{0x0000b154, 0x02410242},
+	{0x0000b158, 0x025f0240},
+	{0x0000b15c, 0x027f0260},
+	{0x0000b160, 0x0341027e},
+	{0x0000b164, 0x035f0340},
+	{0x0000b168, 0x037f0360},
+	{0x0000b16c, 0x04400441},
+	{0x0000b170, 0x0460045f},
+	{0x0000b174, 0x0541047f},
+	{0x0000b178, 0x055f0540},
+	{0x0000b17c, 0x057f0560},
+	{0x0000b180, 0x06400641},
+	{0x0000b184, 0x0660065f},
+	{0x0000b188, 0x067e067f},
+	{0x0000b18c, 0x07410742},
+	{0x0000b190, 0x075f0740},
+	{0x0000b194, 0x077f0760},
+	{0x0000b198, 0x07800781},
+	{0x0000b19c, 0x07a0079f},
+	{0x0000b1a0, 0x07c107bf},
+	{0x0000b1a4, 0x000007c0},
+	{0x0000b1a8, 0x00000000},
+	{0x0000b1ac, 0x00000000},
+	{0x0000b1b0, 0x00000000},
+	{0x0000b1b4, 0x00000000},
+	{0x0000b1b8, 0x00000000},
+	{0x0000b1bc, 0x00000000},
+	{0x0000b1c0, 0x00000000},
+	{0x0000b1c4, 0x00000000},
+	{0x0000b1c8, 0x00000000},
+	{0x0000b1cc, 0x00000000},
+	{0x0000b1d0, 0x00000000},
+	{0x0000b1d4, 0x00000000},
+	{0x0000b1d8, 0x00000000},
+	{0x0000b1dc, 0x00000000},
+	{0x0000b1e0, 0x00000000},
+	{0x0000b1e4, 0x00000000},
+	{0x0000b1e8, 0x00000000},
+	{0x0000b1ec, 0x00000000},
+	{0x0000b1f0, 0x00000396},
+	{0x0000b1f4, 0x00000396},
+	{0x0000b1f8, 0x00000396},
+	{0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9462_2p1_modes_low_ob_db_tx_gain[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+	{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+	{0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+	{0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+	{0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+	{0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
+	{0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+	{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+	{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+	{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+	{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+	{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+	{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+	{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
+	{0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
+	{0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
+	{0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
+	{0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
+	{0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
+	{0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
+	{0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
+	{0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
+	{0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
+	{0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
+	{0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+	{0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+	{0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
+	{0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060},
+	{0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
+	{0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
+	{0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000},
+	{0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
+};
+
+static const u32 ar9462_2p1_modes_high_ob_db_tx_gain[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+	{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+	{0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+	{0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de},
+	{0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
+	{0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
+	{0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
+	{0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
+	{0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
+	{0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
+	{0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
+	{0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
+	{0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
+	{0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
+	{0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
+	{0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
+	{0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
+	{0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81},
+	{0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83},
+	{0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84},
+	{0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
+	{0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
+	{0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
+	{0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
+	{0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec},
+	{0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0},
+	{0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4},
+	{0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
+	{0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
+	{0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
+	{0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
+	{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
+	{0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
+	{0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
+	{0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
+	{0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
+	{0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
+	{0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
+	{0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+	{0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+	{0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
+	{0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060},
+	{0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
+	{0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
+	{0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
+	{0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
+};
+
+static const u32 ar9462_2p1_modes_mix_ob_db_tx_gain[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
+	{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+	{0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+	{0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de},
+	{0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400},
+	{0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402},
+	{0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
+	{0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603},
+	{0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02},
+	{0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04},
+	{0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20},
+	{0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20},
+	{0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22},
+	{0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24},
+	{0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640},
+	{0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660},
+	{0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec},
+	{0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0},
+	{0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4},
+	{0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
+	{0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
+	{0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
+	{0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
+	{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
+	{0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
+	{0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
+	{0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
+	{0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
+	{0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
+	{0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
+	{0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
+	{0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+	{0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+	{0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+};
+
+static const u32 ar9462_2p1_modes_fast_clock[][3] = {
+	/* Addr      5G_HT20     5G_HT40   */
+	{0x00001030, 0x00000268, 0x000004d0},
+	{0x00001070, 0x0000018c, 0x00000318},
+	{0x000010b0, 0x00000fd0, 0x00001fa0},
+	{0x00008014, 0x044c044c, 0x08980898},
+	{0x0000801c, 0x148ec02b, 0x148ec057},
+	{0x00008318, 0x000044c0, 0x00008980},
+	{0x00009e00, 0x0372131c, 0x0372131c},
+	{0x0000a230, 0x0000400b, 0x00004016},
+	{0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9462_2p1_baseband_core_txfir_coeff_japan_2484[][2] = {
+	/* Addr      allmodes  */
+	{0x0000a398, 0x00000000},
+	{0x0000a39c, 0x6f7f0301},
+	{0x0000a3a0, 0xca9228ee},
+};
+
+#endif /* INITVALS_9462_2P1_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ath9k.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ath9k.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/ath9k.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/ath9k.h	2013-08-25 20:43:22.000000000 -0400
@@ -296,6 +296,7 @@ struct ath_tx {
 	struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
 	struct ath_descdma txdma;
 	struct ath_txq *txq_map[IEEE80211_NUM_ACS];
+	struct ath_txq *uapsdq;
 	u32 txq_max_pending[IEEE80211_NUM_ACS];
 	u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32];
 };
@@ -343,6 +344,8 @@ int ath_txq_update(struct ath_softc *sc,
 void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop);
 int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 		 struct ath_tx_control *txctl);
+void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		 struct sk_buff *skb);
 void ath_tx_tasklet(struct ath_softc *sc);
 void ath_tx_edma_tasklet(struct ath_softc *sc);
 int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -353,6 +356,11 @@ void ath_tx_aggr_resume(struct ath_softc
 void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
 void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
 		       struct ath_node *an);
+void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
+				   struct ieee80211_sta *sta,
+				   u16 tids, int nframes,
+				   enum ieee80211_frame_release_type reason,
+				   bool more_data);
 
 /********/
 /* VIFs */
@@ -623,6 +631,11 @@ void ath_ant_comb_update(struct ath_soft
 /* Main driver core */
 /********************/
 
+#define ATH9K_PCI_CUS198 0x0001
+#define ATH9K_PCI_CUS230 0x0002
+#define ATH9K_PCI_CUS217 0x0004
+#define ATH9K_PCI_WOW    0x0008
+
 /*
  * Default cache line size, in bytes.
  * Used when PCI device not fully initialized by bootrom/BIOS
@@ -642,6 +655,7 @@ enum sc_op_flags {
 	SC_OP_ANI_RUN,
 	SC_OP_PRIM_STA_VIF,
 	SC_OP_HW_RESET,
+	SC_OP_SCANNING,
 };
 
 /* Powersave flags */
@@ -706,6 +720,7 @@ struct ath_softc {
 
 	unsigned int hw_busy_count;
 	unsigned long sc_flags;
+	unsigned long driver_data;
 
 	u32 intrstatus;
 	u16 ps_flags; /* PS_* */
@@ -755,7 +770,6 @@ struct ath_softc {
 	struct rchan *rfs_chan_spec_scan;
 	enum spectral_mode spectral_mode;
 	struct ath_spec_scan spec_config;
-	int scanning;
 
 #ifdef CONFIG_PM_SLEEP
 	atomic_t wow_got_bmiss_intr;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/beacon.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/beacon.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/beacon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/beacon.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,7 +39,8 @@ static void ath9k_beaconq_config(struct
 
 	ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
 
-	if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
+	if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
+	    sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
 		/* Always burst out beacon and CAB traffic. */
 		qi.tqi_aifs = 1;
 		qi.tqi_cwmin = 0;
@@ -107,23 +108,6 @@ static void ath9k_beacon_setup(struct at
 	ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
 }
 
-static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-	struct ath_softc *sc = hw->priv;
-	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	struct ath_tx_control txctl;
-
-	memset(&txctl, 0, sizeof(struct ath_tx_control));
-	txctl.txq = sc->beacon.cabq;
-
-	ath_dbg(common, XMIT, "transmitting CABQ packet, skb: %p\n", skb);
-
-	if (ath_tx_start(hw, skb, &txctl) != 0) {
-		ath_dbg(common, XMIT, "CABQ TX failed\n");
-		ieee80211_free_txskb(hw, skb);
-	}
-}
-
 static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
 					     struct ieee80211_vif *vif)
 {
@@ -205,10 +189,8 @@ static struct ath_buf *ath9k_beacon_gene
 
 	ath9k_beacon_setup(sc, vif, bf, info->control.rates[0].idx);
 
-	while (skb) {
-		ath9k_tx_cabq(hw, skb);
-		skb = ieee80211_get_buffered_bc(hw, vif);
-	}
+	if (skb)
+		ath_tx_cabq(hw, vif, skb);
 
 	return bf;
 }
@@ -273,7 +255,8 @@ static int ath9k_beacon_choose_slot(stru
 	u64 tsf;
 	int slot;
 
-	if (sc->sc_ah->opmode != NL80211_IFTYPE_AP) {
+	if (sc->sc_ah->opmode != NL80211_IFTYPE_AP &&
+	    sc->sc_ah->opmode != NL80211_IFTYPE_MESH_POINT) {
 		ath_dbg(common, BEACON, "slot 0, tsf: %llu\n",
 			ath9k_hw_gettsf64(sc->sc_ah));
 		return 0;
@@ -765,10 +748,10 @@ void ath9k_set_beacon(struct ath_softc *
 
 	switch (sc->sc_ah->opmode) {
 	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_MESH_POINT:
 		ath9k_beacon_config_ap(sc, cur_conf);
 		break;
 	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_MESH_POINT:
 		ath9k_beacon_config_adhoc(sc, cur_conf);
 		break;
 	case NL80211_IFTYPE_STATION:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/calib.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/calib.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/calib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/calib.c	2013-08-25 20:43:22.000000000 -0400
@@ -387,7 +387,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s
 
 	if (!caldata) {
 		chan->noisefloor = nf;
-		ah->noise = ath9k_hw_getchan_noise(ah, chan);
 		return false;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/debug.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/debug.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -69,7 +69,7 @@ static ssize_t write_file_debug(struct f
 		return -EFAULT;
 
 	buf[len] = '\0';
-	if (strict_strtoul(buf, 0, &mask))
+	if (kstrtoul(buf, 0, &mask))
 		return -EINVAL;
 
 	common->debug_mask = mask;
@@ -114,7 +114,7 @@ static ssize_t write_file_tx_chainmask(s
 		return -EFAULT;
 
 	buf[len] = '\0';
-	if (strict_strtoul(buf, 0, &mask))
+	if (kstrtoul(buf, 0, &mask))
 		return -EINVAL;
 
 	ah->txchainmask = mask;
@@ -157,7 +157,7 @@ static ssize_t write_file_rx_chainmask(s
 		return -EFAULT;
 
 	buf[len] = '\0';
-	if (strict_strtoul(buf, 0, &mask))
+	if (kstrtoul(buf, 0, &mask))
 		return -EINVAL;
 
 	ah->rxchainmask = mask;
@@ -173,25 +173,69 @@ static const struct file_operations fops
 	.llseek = default_llseek,
 };
 
-static ssize_t read_file_disable_ani(struct file *file, char __user *user_buf,
+static ssize_t read_file_ani(struct file *file, char __user *user_buf,
 			     size_t count, loff_t *ppos)
 {
 	struct ath_softc *sc = file->private_data;
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	char buf[32];
-	unsigned int len;
+	struct ath_hw *ah = sc->sc_ah;
+	unsigned int len = 0, size = 1024;
+	ssize_t retval = 0;
+	char *buf;
 
-	len = sprintf(buf, "%d\n", common->disable_ani);
-	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	buf = kzalloc(size, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	if (common->disable_ani) {
+		len += snprintf(buf + len, size - len, "%s: %s\n",
+				"ANI", "DISABLED");
+		goto exit;
+	}
+
+	len += snprintf(buf + len, size - len, "%15s: %s\n",
+			"ANI", "ENABLED");
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"ANI RESET", ah->stats.ast_ani_reset);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"SPUR UP", ah->stats.ast_ani_spurup);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"SPUR DOWN", ah->stats.ast_ani_spurup);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"OFDM WS-DET ON", ah->stats.ast_ani_ofdmon);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"MRC-CCK ON", ah->stats.ast_ani_ccklow);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"MRC-CCK OFF", ah->stats.ast_ani_cckhigh);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"FIR-STEP UP", ah->stats.ast_ani_stepup);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"FIR-STEP DOWN", ah->stats.ast_ani_stepdown);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"OFDM ERRORS", ah->stats.ast_ani_ofdmerrs);
+	len += snprintf(buf + len, size - len, "%15s: %u\n",
+			"CCK ERRORS", ah->stats.ast_ani_cckerrs);
+exit:
+	if (len > size)
+		len = size;
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+
+	return retval;
 }
 
-static ssize_t write_file_disable_ani(struct file *file,
-				      const char __user *user_buf,
-				      size_t count, loff_t *ppos)
+static ssize_t write_file_ani(struct file *file,
+			      const char __user *user_buf,
+			      size_t count, loff_t *ppos)
 {
 	struct ath_softc *sc = file->private_data;
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	unsigned long disable_ani;
+	unsigned long ani;
 	char buf[32];
 	ssize_t len;
 
@@ -200,12 +244,15 @@ static ssize_t write_file_disable_ani(st
 		return -EFAULT;
 
 	buf[len] = '\0';
-	if (strict_strtoul(buf, 0, &disable_ani))
+	if (kstrtoul(buf, 0, &ani))
 		return -EINVAL;
 
-	common->disable_ani = !!disable_ani;
+	if (ani < 0 || ani > 1)
+		return -EINVAL;
 
-	if (disable_ani) {
+	common->disable_ani = !ani;
+
+	if (common->disable_ani) {
 		clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
 		ath_stop_ani(sc);
 	} else {
@@ -215,9 +262,9 @@ static ssize_t write_file_disable_ani(st
 	return count;
 }
 
-static const struct file_operations fops_disable_ani = {
-	.read = read_file_disable_ani,
-	.write = write_file_disable_ani,
+static const struct file_operations fops_ani = {
+	.read = read_file_ani,
+	.write = write_file_ani,
 	.open = simple_open,
 	.owner = THIS_MODULE,
 	.llseek = default_llseek,
@@ -253,7 +300,7 @@ static ssize_t write_file_ant_diversity(
 		goto exit;
 
 	buf[len] = '\0';
-	if (strict_strtoul(buf, 0, &antenna_diversity))
+	if (kstrtoul(buf, 0, &antenna_diversity))
 		return -EINVAL;
 
 	common->antenna_diversity = !!antenna_diversity;
@@ -738,8 +785,6 @@ void ath_debug_stat_tx(struct ath_softc
 		       struct ath_tx_status *ts, struct ath_txq *txq,
 		       unsigned int flags)
 {
-#define TX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].ts\
-			[sc->debug.tsidx].c)
 	int qnum = txq->axq_qnum;
 
 	TX_STAT_INC(qnum, tx_pkts_all);
@@ -771,37 +816,6 @@ void ath_debug_stat_tx(struct ath_softc
 		TX_STAT_INC(qnum, data_underrun);
 	if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
 		TX_STAT_INC(qnum, delim_underrun);
-
-#ifdef CONFIG_ATH9K_MAC_DEBUG
-	spin_lock(&sc->debug.samp_lock);
-	TX_SAMP_DBG(jiffies) = jiffies;
-	TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0;
-	TX_SAMP_DBG(rssi_ctl1) = ts->ts_rssi_ctl1;
-	TX_SAMP_DBG(rssi_ctl2) = ts->ts_rssi_ctl2;
-	TX_SAMP_DBG(rssi_ext0) = ts->ts_rssi_ext0;
-	TX_SAMP_DBG(rssi_ext1) = ts->ts_rssi_ext1;
-	TX_SAMP_DBG(rssi_ext2) = ts->ts_rssi_ext2;
-	TX_SAMP_DBG(rateindex) = ts->ts_rateindex;
-	TX_SAMP_DBG(isok) = !!(ts->ts_status & ATH9K_TXERR_MASK);
-	TX_SAMP_DBG(rts_fail_cnt) = ts->ts_shortretry;
-	TX_SAMP_DBG(data_fail_cnt) = ts->ts_longretry;
-	TX_SAMP_DBG(rssi) = ts->ts_rssi;
-	TX_SAMP_DBG(tid) = ts->tid;
-	TX_SAMP_DBG(qid) = ts->qid;
-
-	if (ts->ts_flags & ATH9K_TX_BA) {
-		TX_SAMP_DBG(ba_low) = ts->ba_low;
-		TX_SAMP_DBG(ba_high) = ts->ba_high;
-	} else {
-		TX_SAMP_DBG(ba_low) = 0;
-		TX_SAMP_DBG(ba_high) = 0;
-	}
-
-	sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES;
-	spin_unlock(&sc->debug.samp_lock);
-#endif
-
-#undef TX_SAMP_DBG
 }
 
 static const struct file_operations fops_xmit = {
@@ -915,8 +929,6 @@ static ssize_t read_file_recv(struct fil
 void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
 {
 #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
-#define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\
-			[sc->debug.rsidx].c)
 
 	RX_STAT_INC(rx_pkts_all);
 	sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
@@ -940,27 +952,7 @@ void ath_debug_stat_rx(struct ath_softc
 			RX_PHY_ERR_INC(rs->rs_phyerr);
 	}
 
-#ifdef CONFIG_ATH9K_MAC_DEBUG
-	spin_lock(&sc->debug.samp_lock);
-	RX_SAMP_DBG(jiffies) = jiffies;
-	RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
-	RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1;
-	RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2;
-	RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0;
-	RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1;
-	RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2;
-	RX_SAMP_DBG(antenna) = rs->rs_antenna;
-	RX_SAMP_DBG(rssi) = rs->rs_rssi;
-	RX_SAMP_DBG(rate) = rs->rs_rate;
-	RX_SAMP_DBG(is_mybeacon) = rs->is_mybeacon;
-
-	sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES;
-	spin_unlock(&sc->debug.samp_lock);
-
-#endif
-
 #undef RX_PHY_ERR_INC
-#undef RX_SAMP_DBG
 }
 
 static const struct file_operations fops_recv = {
@@ -1278,7 +1270,7 @@ static ssize_t write_file_regidx(struct
 		return -EFAULT;
 
 	buf[len] = '\0';
-	if (strict_strtoul(buf, 0, &regidx))
+	if (kstrtoul(buf, 0, &regidx))
 		return -EINVAL;
 
 	sc->debug.regidx = regidx;
@@ -1323,7 +1315,7 @@ static ssize_t write_file_regval(struct
 		return -EFAULT;
 
 	buf[len] = '\0';
-	if (strict_strtoul(buf, 0, &regval))
+	if (kstrtoul(buf, 0, &regval))
 		return -EINVAL;
 
 	ath9k_ps_wakeup(sc);
@@ -1485,283 +1477,6 @@ static const struct file_operations fops
 	.llseek = default_llseek,
 };
 
-#ifdef CONFIG_ATH9K_MAC_DEBUG
-
-void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
-{
-#define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c)
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
-	unsigned long flags;
-	int i;
-
-	ath9k_ps_wakeup(sc);
-
-	spin_lock_bh(&sc->debug.samp_lock);
-
-	spin_lock_irqsave(&common->cc_lock, flags);
-	ath_hw_cycle_counters_update(common);
-
-	ATH_SAMP_DBG(cc.cycles) = common->cc_ani.cycles;
-	ATH_SAMP_DBG(cc.rx_busy) = common->cc_ani.rx_busy;
-	ATH_SAMP_DBG(cc.rx_frame) = common->cc_ani.rx_frame;
-	ATH_SAMP_DBG(cc.tx_frame) = common->cc_ani.tx_frame;
-	spin_unlock_irqrestore(&common->cc_lock, flags);
-
-	ATH_SAMP_DBG(noise) = ah->noise;
-
-	REG_WRITE_D(ah, AR_MACMISC,
-		  ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
-		   (AR_MACMISC_MISC_OBS_BUS_1 <<
-		    AR_MACMISC_MISC_OBS_BUS_MSB_S)));
-
-	for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
-		ATH_SAMP_DBG(dma_dbg_reg_vals[i]) = REG_READ_D(ah,
-				AR_DMADBG_0 + (i * sizeof(u32)));
-
-	ATH_SAMP_DBG(pcu_obs) = REG_READ_D(ah, AR_OBS_BUS_1);
-	ATH_SAMP_DBG(pcu_cr) = REG_READ_D(ah, AR_CR);
-
-	memcpy(ATH_SAMP_DBG(nfCalHist), sc->caldata.nfCalHist,
-			sizeof(ATH_SAMP_DBG(nfCalHist)));
-
-	sc->debug.sampidx = (sc->debug.sampidx + 1) % ATH_DBG_MAX_SAMPLES;
-	spin_unlock_bh(&sc->debug.samp_lock);
-	ath9k_ps_restore(sc);
-
-#undef ATH_SAMP_DBG
-}
-
-static int open_file_bb_mac_samps(struct inode *inode, struct file *file)
-{
-#define ATH_SAMP_DBG(c) bb_mac_samp[sampidx].c
-	struct ath_softc *sc = inode->i_private;
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
-	struct ieee80211_conf *conf = &common->hw->conf;
-	struct ath_dbg_bb_mac_samp *bb_mac_samp;
-	struct ath9k_nfcal_hist *h;
-	int i, j, qcuOffset = 0, dcuOffset = 0;
-	u32 *qcuBase, *dcuBase, size = 30000, len = 0;
-	u32 sampidx = 0;
-	u8 *buf;
-	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
-	u8 nread;
-
-	if (test_bit(SC_OP_INVALID, &sc->sc_flags))
-		return -EAGAIN;
-
-	buf = vmalloc(size);
-	if (!buf)
-		return -ENOMEM;
-	bb_mac_samp = vmalloc(sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES);
-	if (!bb_mac_samp) {
-		vfree(buf);
-		return -ENOMEM;
-	}
-	/* Account the current state too */
-	ath9k_debug_samp_bb_mac(sc);
-
-	spin_lock_bh(&sc->debug.samp_lock);
-	memcpy(bb_mac_samp, sc->debug.bb_mac_samp,
-			sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES);
-	len += snprintf(buf + len, size - len,
-			"Current Sample Index: %d\n", sc->debug.sampidx);
-	spin_unlock_bh(&sc->debug.samp_lock);
-
-	len += snprintf(buf + len, size - len,
-			"Raw DMA Debug Dump:\n");
-	len += snprintf(buf + len, size - len, "Sample |\t");
-	for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
-		len += snprintf(buf + len, size - len, " DMA Reg%d |\t", i);
-	len += snprintf(buf + len, size - len, "\n");
-
-	for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
-		len += snprintf(buf + len, size - len, "%d\t", sampidx);
-
-		for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
-			len += snprintf(buf + len, size - len, " %08x\t",
-					ATH_SAMP_DBG(dma_dbg_reg_vals[i]));
-		len += snprintf(buf + len, size - len, "\n");
-	}
-	len += snprintf(buf + len, size - len, "\n");
-
-	len += snprintf(buf + len, size - len,
-			"Sample Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
-	for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
-		qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]);
-		dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]);
-
-		for (i = 0; i < ATH9K_NUM_QUEUES; i++,
-				qcuOffset += 4, dcuOffset += 5) {
-			if (i == 8) {
-				qcuOffset = 0;
-				qcuBase++;
-			}
-
-			if (i == 6) {
-				dcuOffset = 0;
-				dcuBase++;
-			}
-			if (!sc->debug.stats.txstats[i].queued)
-				continue;
-
-			len += snprintf(buf + len, size - len,
-				"%4d %7d    %2x      %1x     %2x         %2x\n",
-				sampidx, i,
-				(*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
-				(*qcuBase & (0x8 << qcuOffset)) >>
-				(qcuOffset + 3),
-				ATH_SAMP_DBG(dma_dbg_reg_vals[2]) &
-				(0x7 << (i * 3)) >> (i * 3),
-				(*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
-		}
-		len += snprintf(buf + len, size - len, "\n");
-	}
-	len += snprintf(buf + len, size - len,
-			"samp qcu_sh qcu_fh qcu_comp dcu_comp dcu_arb dcu_fp "
-			"ch_idle_dur ch_idle_dur_val txfifo_val0 txfifo_val1 "
-			"txfifo_dcu0 txfifo_dcu1 pcu_obs AR_CR\n");
-
-	for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
-		qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]);
-		dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]);
-
-		len += snprintf(buf + len, size - len, "%4d %5x %5x ", sampidx,
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x003c0000) >> 18,
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x03c00000) >> 22);
-		len += snprintf(buf + len, size - len, "%7x %8x ",
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x1c000000) >> 26,
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x3));
-		len += snprintf(buf + len, size - len, "%7x %7x ",
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x06000000) >> 25,
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x38000000) >> 27);
-		len += snprintf(buf + len, size - len, "%7d %12d ",
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x000003fc) >> 2,
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000400) >> 10);
-		len += snprintf(buf + len, size - len, "%12d %12d ",
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000800) >> 11,
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00001000) >> 12);
-		len += snprintf(buf + len, size - len, "%12d %12d ",
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x0001e000) >> 13,
-			(ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x001e0000) >> 17);
-		len += snprintf(buf + len, size - len, "0x%07x 0x%07x\n",
-				ATH_SAMP_DBG(pcu_obs), ATH_SAMP_DBG(pcu_cr));
-	}
-
-	len += snprintf(buf + len, size - len,
-			"Sample ChNoise Chain privNF #Reading Readings\n");
-	for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
-		h = ATH_SAMP_DBG(nfCalHist);
-		if (!ATH_SAMP_DBG(noise))
-			continue;
-
-		for (i = 0; i < NUM_NF_READINGS; i++) {
-			if (!(chainmask & (1 << i)) ||
-			    ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
-				continue;
-
-			nread = AR_PHY_CCA_FILTERWINDOW_LENGTH -
-				h[i].invalidNFcount;
-			len += snprintf(buf + len, size - len,
-					"%4d %5d %4d\t   %d\t %d\t",
-					sampidx, ATH_SAMP_DBG(noise),
-					i, h[i].privNF, nread);
-			for (j = 0; j < nread; j++)
-				len += snprintf(buf + len, size - len,
-					" %d", h[i].nfCalBuffer[j]);
-			len += snprintf(buf + len, size - len, "\n");
-		}
-	}
-	len += snprintf(buf + len, size - len, "\nCycle counters:\n"
-			"Sample Total    Rxbusy   Rxframes Txframes\n");
-	for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
-		if (!ATH_SAMP_DBG(cc.cycles))
-			continue;
-		len += snprintf(buf + len, size - len,
-				"%4d %08x %08x %08x %08x\n",
-				sampidx, ATH_SAMP_DBG(cc.cycles),
-				ATH_SAMP_DBG(cc.rx_busy),
-				ATH_SAMP_DBG(cc.rx_frame),
-				ATH_SAMP_DBG(cc.tx_frame));
-	}
-
-	len += snprintf(buf + len, size - len, "Tx status Dump :\n");
-	len += snprintf(buf + len, size - len,
-			"Sample rssi:- ctl0 ctl1 ctl2 ext0 ext1 ext2 comb "
-			"isok rts_fail data_fail rate tid qid "
-					"ba_low  ba_high tx_before(ms)\n");
-	for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
-		for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) {
-			if (!ATH_SAMP_DBG(ts[i].jiffies))
-				continue;
-			len += snprintf(buf + len, size - len, "%-14d"
-				"%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-8d "
-				"%-9d %-4d %-3d %-3d %08x %08x %-11d\n",
-				sampidx,
-				ATH_SAMP_DBG(ts[i].rssi_ctl0),
-				ATH_SAMP_DBG(ts[i].rssi_ctl1),
-				ATH_SAMP_DBG(ts[i].rssi_ctl2),
-				ATH_SAMP_DBG(ts[i].rssi_ext0),
-				ATH_SAMP_DBG(ts[i].rssi_ext1),
-				ATH_SAMP_DBG(ts[i].rssi_ext2),
-				ATH_SAMP_DBG(ts[i].rssi),
-				ATH_SAMP_DBG(ts[i].isok),
-				ATH_SAMP_DBG(ts[i].rts_fail_cnt),
-				ATH_SAMP_DBG(ts[i].data_fail_cnt),
-				ATH_SAMP_DBG(ts[i].rateindex),
-				ATH_SAMP_DBG(ts[i].tid),
-				ATH_SAMP_DBG(ts[i].qid),
-				ATH_SAMP_DBG(ts[i].ba_low),
-				ATH_SAMP_DBG(ts[i].ba_high),
-				jiffies_to_msecs(jiffies -
-					ATH_SAMP_DBG(ts[i].jiffies)));
-		}
-	}
-
-	len += snprintf(buf + len, size - len, "Rx status Dump :\n");
-	len += snprintf(buf + len, size - len, "Sample rssi:- ctl0 ctl1 ctl2 "
-			"ext0 ext1 ext2 comb beacon ant rate rx_before(ms)\n");
-	for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
-		for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) {
-			if (!ATH_SAMP_DBG(rs[i].jiffies))
-				continue;
-			len += snprintf(buf + len, size - len, "%-14d"
-				"%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-9s %-2d %02x %-13d\n",
-				sampidx,
-				ATH_SAMP_DBG(rs[i].rssi_ctl0),
-				ATH_SAMP_DBG(rs[i].rssi_ctl1),
-				ATH_SAMP_DBG(rs[i].rssi_ctl2),
-				ATH_SAMP_DBG(rs[i].rssi_ext0),
-				ATH_SAMP_DBG(rs[i].rssi_ext1),
-				ATH_SAMP_DBG(rs[i].rssi_ext2),
-				ATH_SAMP_DBG(rs[i].rssi),
-				ATH_SAMP_DBG(rs[i].is_mybeacon) ?
-				"True" : "False",
-				ATH_SAMP_DBG(rs[i].antenna),
-				ATH_SAMP_DBG(rs[i].rate),
-				jiffies_to_msecs(jiffies -
-					ATH_SAMP_DBG(rs[i].jiffies)));
-		}
-	}
-
-	vfree(bb_mac_samp);
-	file->private_data = buf;
-
-	return 0;
-#undef ATH_SAMP_DBG
-}
-
-static const struct file_operations fops_samps = {
-	.open = open_file_bb_mac_samps,
-	.read = ath9k_debugfs_read_buf,
-	.release = ath9k_debugfs_release_buf,
-	.owner = THIS_MODULE,
-	.llseek = default_llseek,
-};
-
-#endif
-
 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
 static ssize_t read_file_btcoex(struct file *file, char __user *user_buf,
 				size_t count, loff_t *ppos)
@@ -2059,8 +1774,8 @@ int ath9k_init_debug(struct ath_hw *ah)
 			    sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
 	debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
 			    sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
-	debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR,
-			    sc->debug.debugfs_phy, sc, &fops_disable_ani);
+	debugfs_create_file("ani", S_IRUSR | S_IWUSR,
+			    sc->debug.debugfs_phy, sc, &fops_ani);
 	debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
 			    &sc->sc_ah->config.enable_paprd);
 	debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
@@ -2095,11 +1810,6 @@ int ath9k_init_debug(struct ath_hw *ah)
 	debugfs_create_file("spectral_fft_period", S_IRUSR | S_IWUSR,
 			    sc->debug.debugfs_phy, sc,
 			    &fops_spectral_fft_period);
-
-#ifdef CONFIG_ATH9K_MAC_DEBUG
-	debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
-			    &fops_samps);
-#endif
 	debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
 			   sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
 	debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/debug.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/debug.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/debug.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/debug.h	2013-08-25 20:43:22.000000000 -0400
@@ -251,56 +251,10 @@ struct ath_stats {
 	u32 reset[__RESET_TYPE_MAX];
 };
 
-#define ATH_DBG_MAX_SAMPLES	10
-struct ath_dbg_bb_mac_samp {
-	u32 dma_dbg_reg_vals[ATH9K_NUM_DMA_DEBUG_REGS];
-	u32 pcu_obs, pcu_cr, noise;
-	struct {
-		u64 jiffies;
-		int8_t rssi_ctl0;
-		int8_t rssi_ctl1;
-		int8_t rssi_ctl2;
-		int8_t rssi_ext0;
-		int8_t rssi_ext1;
-		int8_t rssi_ext2;
-		int8_t rssi;
-		bool isok;
-		u8 rts_fail_cnt;
-		u8 data_fail_cnt;
-		u8 rateindex;
-		u8 qid;
-		u8 tid;
-		u32 ba_low;
-		u32 ba_high;
-	} ts[ATH_DBG_MAX_SAMPLES];
-	struct {
-		u64 jiffies;
-		int8_t rssi_ctl0;
-		int8_t rssi_ctl1;
-		int8_t rssi_ctl2;
-		int8_t rssi_ext0;
-		int8_t rssi_ext1;
-		int8_t rssi_ext2;
-		int8_t rssi;
-		bool is_mybeacon;
-		u8 antenna;
-		u8 rate;
-	} rs[ATH_DBG_MAX_SAMPLES];
-	struct ath_cycle_counters cc;
-	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-};
-
 struct ath9k_debug {
 	struct dentry *debugfs_phy;
 	u32 regidx;
 	struct ath_stats stats;
-#ifdef CONFIG_ATH9K_MAC_DEBUG
-	spinlock_t samp_lock;
-	struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES];
-	u8 sampidx;
-	u8 tsidx;
-	u8 rsidx;
-#endif
 };
 
 int ath9k_init_debug(struct ath_hw *ah);
@@ -364,17 +318,4 @@ static inline void ath_debug_stat_rx(str
 
 #endif /* CONFIG_ATH9K_DEBUGFS */
 
-#ifdef CONFIG_ATH9K_MAC_DEBUG
-
-void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
-
-#else
-
-static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
-{
-}
-
-#endif
-
-
 #endif /* DEBUG_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/dfs_debug.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/dfs_debug.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/dfs_debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/dfs_debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -96,7 +96,7 @@ static ssize_t write_file_dfs(struct fil
 		return -EFAULT;
 
 	buf[len] = '\0';
-	if (strict_strtoul(buf, 0, &val))
+	if (kstrtoul(buf, 0, &val))
 		return -EINVAL;
 
 	if (val == DFS_STATS_RESET_MAGIC)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/hif_usb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/hif_usb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/hif_usb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/hif_usb.c	2013-08-25 20:43:22.000000000 -0400
@@ -234,10 +234,15 @@ static inline void ath9k_skb_queue_compl
 	struct sk_buff *skb;
 
 	while ((skb = __skb_dequeue(queue)) != NULL) {
+#ifdef CONFIG_ATH9K_HTC_DEBUGFS
+		int ln = skb->len;
+#endif
 		ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
 					  skb, txok);
-		if (txok)
+		if (txok) {
 			TX_STAT_INC(skb_success);
+			TX_STAT_ADD(skb_success_bytes, ln);
+		}
 		else
 			TX_STAT_INC(skb_failed);
 	}
@@ -620,6 +625,7 @@ static void ath9k_hif_usb_rx_stream(stru
 
 err:
 	for (i = 0; i < pool_index; i++) {
+		RX_STAT_ADD(skb_completed_bytes, skb_pool[i]->len);
 		ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
 				 skb_pool[i]->len, USB_WLAN_RX_PIPE);
 		RX_STAT_INC(skb_completed);
@@ -1076,7 +1082,7 @@ static void ath9k_hif_usb_firmware_fail(
 	struct device *dev = &hif_dev->udev->dev;
 	struct device *parent = dev->parent;
 
-	complete(&hif_dev->fw_done);
+	complete_all(&hif_dev->fw_done);
 
 	if (parent)
 		device_lock(parent);
@@ -1125,7 +1131,7 @@ static void ath9k_hif_usb_firmware_cb(co
 
 	release_firmware(fw);
 	hif_dev->flags |= HIF_USB_READY;
-	complete(&hif_dev->fw_done);
+	complete_all(&hif_dev->fw_done);
 
 	return;
 
@@ -1289,7 +1295,9 @@ static void ath9k_hif_usb_disconnect(str
 
 	usb_set_intfdata(interface, NULL);
 
-	if (!unplugged && (hif_dev->flags & HIF_USB_START))
+	/* If firmware was loaded we should drop it
+	 * go back to first stage bootloader. */
+	if (!unplugged && (hif_dev->flags & HIF_USB_READY))
 		ath9k_hif_usb_reboot(udev);
 
 	kfree(hif_dev);
@@ -1310,7 +1318,10 @@ static int ath9k_hif_usb_suspend(struct
 	if (!(hif_dev->flags & HIF_USB_START))
 		ath9k_htc_suspend(hif_dev->htc_handle);
 
-	ath9k_hif_usb_dealloc_urbs(hif_dev);
+	wait_for_completion(&hif_dev->fw_done);
+
+	if (hif_dev->flags & HIF_USB_READY)
+		ath9k_hif_usb_dealloc_urbs(hif_dev);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,8 @@ void ath9k_htc_beaconq_config(struct ath
 
 	ath9k_hw_get_txq_props(ah, priv->beaconq, &qi);
 
-	if (priv->ah->opmode == NL80211_IFTYPE_AP) {
+	if (priv->ah->opmode == NL80211_IFTYPE_AP ||
+	    priv->ah->opmode == NL80211_IFTYPE_MESH_POINT) {
 		qi.tqi_aifs = 1;
 		qi.tqi_cwmin = 0;
 		qi.tqi_cwmax = 0;
@@ -628,6 +629,7 @@ void ath9k_htc_beacon_config(struct ath9
 	case NL80211_IFTYPE_ADHOC:
 		ath9k_htc_beacon_config_adhoc(priv, cur_conf);
 		break;
+	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_AP:
 		ath9k_htc_beacon_config_ap(priv, cur_conf);
 		break;
@@ -649,6 +651,7 @@ void ath9k_htc_beacon_reconfig(struct at
 	case NL80211_IFTYPE_ADHOC:
 		ath9k_htc_beacon_config_adhoc(priv, cur_conf);
 		break;
+	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_AP:
 		ath9k_htc_beacon_config_ap(priv, cur_conf);
 		break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_debug.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -471,7 +471,7 @@ static ssize_t write_file_debug(struct f
 		return -EFAULT;
 
 	buf[len] = '\0';
-	if (strict_strtoul(buf, 0, &mask))
+	if (kstrtoul(buf, 0, &mask))
 		return -EINVAL;
 
 	common->debug_mask = mask;
@@ -496,21 +496,7 @@ static ssize_t read_file_base_eeprom(str
 	ssize_t retval = 0;
 	char *buf;
 
-	/*
-	 * This can be done since all the 3 EEPROM families have the
-	 * same base header upto a certain point, and we are interested in
-	 * the data only upto that point.
-	 */
-
-	if (AR_SREV_9271(priv->ah))
-		pBase = (struct base_eep_header *)
-			&priv->ah->eeprom.map4k.baseEepHeader;
-	else if (priv->ah->hw_version.usbdev == AR9280_USB)
-		pBase = (struct base_eep_header *)
-			&priv->ah->eeprom.def.baseEepHeader;
-	else if (priv->ah->hw_version.usbdev == AR9287_USB)
-		pBase = (struct base_eep_header *)
-			&priv->ah->eeprom.map9287.baseEepHeader;
+	pBase = ath9k_htc_get_eeprom_base(priv);
 
 	if (pBase == NULL) {
 		ath_err(common, "Unknown EEPROM type\n");
@@ -916,6 +902,87 @@ static const struct file_operations fops
 	.llseek = default_llseek,
 };
 
+
+/* Ethtool support for get-stats */
+#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
+static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = {
+	"tx_pkts_nic",
+	"tx_bytes_nic",
+	"rx_pkts_nic",
+	"rx_bytes_nic",
+
+	AMKSTR(d_tx_pkts),
+
+	"d_rx_crc_err",
+	"d_rx_decrypt_crc_err",
+	"d_rx_phy_err",
+	"d_rx_mic_err",
+	"d_rx_pre_delim_crc_err",
+	"d_rx_post_delim_crc_err",
+	"d_rx_decrypt_busy_err",
+
+	"d_rx_phyerr_radar",
+	"d_rx_phyerr_ofdm_timing",
+	"d_rx_phyerr_cck_timing",
+
+};
+#define ATH9K_HTC_SSTATS_LEN ARRAY_SIZE(ath9k_htc_gstrings_stats)
+
+void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
+			      struct ieee80211_vif *vif,
+			      u32 sset, u8 *data)
+{
+	if (sset == ETH_SS_STATS)
+		memcpy(data, *ath9k_htc_gstrings_stats,
+		       sizeof(ath9k_htc_gstrings_stats));
+}
+
+int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,
+				struct ieee80211_vif *vif, int sset)
+{
+	if (sset == ETH_SS_STATS)
+		return ATH9K_HTC_SSTATS_LEN;
+	return 0;
+}
+
+#define STXBASE priv->debug.tx_stats
+#define SRXBASE priv->debug.rx_stats
+#define ASTXQ(a)					\
+	data[i++] = STXBASE.a[IEEE80211_AC_BE];		\
+	data[i++] = STXBASE.a[IEEE80211_AC_BK];		\
+	data[i++] = STXBASE.a[IEEE80211_AC_VI];		\
+	data[i++] = STXBASE.a[IEEE80211_AC_VO]
+
+void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
+			    struct ieee80211_vif *vif,
+			    struct ethtool_stats *stats, u64 *data)
+{
+	struct ath9k_htc_priv *priv = hw->priv;
+	int i = 0;
+
+	data[i++] = STXBASE.skb_success;
+	data[i++] = STXBASE.skb_success_bytes;
+	data[i++] = SRXBASE.skb_completed;
+	data[i++] = SRXBASE.skb_completed_bytes;
+
+	ASTXQ(queue_stats);
+
+	data[i++] = SRXBASE.err_crc;
+	data[i++] = SRXBASE.err_decrypt_crc;
+	data[i++] = SRXBASE.err_phy;
+	data[i++] = SRXBASE.err_mic;
+	data[i++] = SRXBASE.err_pre_delim;
+	data[i++] = SRXBASE.err_post_delim;
+	data[i++] = SRXBASE.err_decrypt_busy;
+
+	data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_RADAR];
+	data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_OFDM_TIMING];
+	data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_CCK_TIMING];
+
+	WARN_ON(i != ATH9K_HTC_SSTATS_LEN);
+}
+
+
 int ath9k_htc_init_debug(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_init.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_init.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_init.c	2013-08-25 20:43:22.000000000 -0400
@@ -517,6 +517,9 @@ static void setup_ht_cap(struct ath9k_ht
 	ath_dbg(common, CONFIG, "TX streams %d, RX streams: %d\n",
 		tx_streams, rx_streams);
 
+	if (tx_streams >= 2)
+		ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
+
 	if (tx_streams != rx_streams) {
 		ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
 		ht_info->mcs.tx_params |= ((tx_streams - 1) <<
@@ -698,6 +701,9 @@ static const struct ieee80211_iface_limi
 	{ .max = 2,	.types = BIT(NL80211_IFTYPE_STATION) |
 				 BIT(NL80211_IFTYPE_P2P_CLIENT) },
 	{ .max = 2,	.types = BIT(NL80211_IFTYPE_AP) |
+#ifdef CONFIG_MAC80211_MESH
+				 BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
 				 BIT(NL80211_IFTYPE_P2P_GO) },
 };
 
@@ -712,6 +718,7 @@ static void ath9k_set_hw_capab(struct at
 			       struct ieee80211_hw *hw)
 {
 	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct base_eep_header *pBase;
 
 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
 		IEEE80211_HW_AMPDU_AGGREGATION |
@@ -721,6 +728,7 @@ static void ath9k_set_hw_capab(struct at
 		IEEE80211_HW_SUPPORTS_PS |
 		IEEE80211_HW_PS_NULLFUNC_STACK |
 		IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+		IEEE80211_HW_MFP_CAPABLE |
 		IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
 
 	hw->wiphy->interface_modes =
@@ -728,7 +736,8 @@ static void ath9k_set_hw_capab(struct at
 		BIT(NL80211_IFTYPE_ADHOC) |
 		BIT(NL80211_IFTYPE_AP) |
 		BIT(NL80211_IFTYPE_P2P_GO) |
-		BIT(NL80211_IFTYPE_P2P_CLIENT);
+		BIT(NL80211_IFTYPE_P2P_CLIENT) |
+		BIT(NL80211_IFTYPE_MESH_POINT);
 
 	hw->wiphy->iface_combinations = &if_comb;
 	hw->wiphy->n_iface_combinations = 1;
@@ -765,6 +774,12 @@ static void ath9k_set_hw_capab(struct at
 				     &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
 	}
 
+	pBase = ath9k_htc_get_eeprom_base(priv);
+	if (pBase) {
+		hw->wiphy->available_antennas_rx = pBase->rxMask;
+		hw->wiphy->available_antennas_tx = pBase->txMask;
+	}
+
 	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
 }
 
@@ -846,6 +861,7 @@ static int ath9k_init_device(struct ath9
 	if (error != 0)
 		goto err_rx;
 
+	ath9k_hw_disable(priv->ah);
 #ifdef CONFIG_MAC80211_LEDS
 	/* must be initialized before ieee80211_register_hw */
 	priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -113,7 +113,9 @@ static void ath9k_htc_vif_iter(void *dat
 	struct ath9k_htc_priv *priv = data;
 	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 
-	if ((vif->type == NL80211_IFTYPE_AP) && bss_conf->enable_beacon)
+	if ((vif->type == NL80211_IFTYPE_AP ||
+	     vif->type == NL80211_IFTYPE_MESH_POINT) &&
+	    bss_conf->enable_beacon)
 		priv->reconfig_beacon = true;
 
 	if (bss_conf->assoc) {
@@ -180,6 +182,8 @@ static void ath9k_htc_set_opmode(struct
 		priv->ah->opmode = NL80211_IFTYPE_ADHOC;
 	else if (priv->num_ap_vif)
 		priv->ah->opmode = NL80211_IFTYPE_AP;
+	else if (priv->num_mbss_vif)
+		priv->ah->opmode = NL80211_IFTYPE_MESH_POINT;
 	else
 		priv->ah->opmode = NL80211_IFTYPE_STATION;
 
@@ -623,6 +627,8 @@ static void ath9k_htc_setup_rate(struct
 		trate->rates.ht_rates.rs_nrates = j;
 
 		caps = WLAN_RC_HT_FLAG;
+		if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
+			caps |= ATH_RC_TX_STBC_FLAG;
 		if (sta->ht_cap.mcs.rx_mask[1])
 			caps |= WLAN_RC_DS_FLAG;
 		if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
@@ -810,8 +816,7 @@ void ath9k_htc_ani_work(struct work_stru
 	}
 
 	/* Verify whether we must check ANI */
-	if (ah->config.enable_ani &&
-	    (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
+	if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
 		aniflag = true;
 		common->ani.checkani_timer = timestamp;
 	}
@@ -841,8 +846,7 @@ set_timer:
 	* short calibration and long calibration.
 	*/
 	cal_interval = ATH_LONG_CALINTERVAL;
-	if (ah->config.enable_ani)
-		cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
+	cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
 	if (!common->ani.caldone)
 		cal_interval = min(cal_interval, (u32)short_cal_interval);
 
@@ -1052,6 +1056,9 @@ static int ath9k_htc_add_interface(struc
 	case NL80211_IFTYPE_AP:
 		hvif.opmode = HTC_M_HOSTAP;
 		break;
+	case NL80211_IFTYPE_MESH_POINT:
+		hvif.opmode = HTC_M_WDS;	/* close enough */
+		break;
 	default:
 		ath_err(common,
 			"Interface type %d not yet supported\n", vif->type);
@@ -1084,6 +1091,7 @@ static int ath9k_htc_add_interface(struc
 	INC_VIF(priv, vif->type);
 
 	if ((vif->type == NL80211_IFTYPE_AP) ||
+	    (vif->type == NL80211_IFTYPE_MESH_POINT) ||
 	    (vif->type == NL80211_IFTYPE_ADHOC))
 		ath9k_htc_assign_bslot(priv, vif);
 
@@ -1134,6 +1142,7 @@ static void ath9k_htc_remove_interface(s
 	DEC_VIF(priv, vif->type);
 
 	if ((vif->type == NL80211_IFTYPE_AP) ||
+	     vif->type == NL80211_IFTYPE_MESH_POINT ||
 	    (vif->type == NL80211_IFTYPE_ADHOC))
 		ath9k_htc_remove_bslot(priv, vif);
 
@@ -1525,9 +1534,10 @@ static void ath9k_htc_bss_info_changed(s
 	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
 		/*
 		 * Disable SWBA interrupt only if there are no
-		 * AP/IBSS interfaces.
+		 * concurrent AP/mesh or IBSS interfaces.
 		 */
-		if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) {
+		if ((priv->num_ap_vif + priv->num_mbss_vif <= 1) ||
+		     priv->num_ibss_vif) {
 			ath_dbg(common, CONFIG,
 				"Beacon disabled for BSS: %pM\n",
 				bss_conf->bssid);
@@ -1538,12 +1548,15 @@ static void ath9k_htc_bss_info_changed(s
 
 	if (changed & BSS_CHANGED_BEACON_INT) {
 		/*
-		 * Reset the HW TSF for the first AP interface.
+		 * Reset the HW TSF for the first AP or mesh interface.
 		 */
-		if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
-		    (priv->nvifs == 1) &&
-		    (priv->num_ap_vif == 1) &&
-		    (vif->type == NL80211_IFTYPE_AP)) {
+		if (priv->nvifs == 1 &&
+		    ((priv->ah->opmode == NL80211_IFTYPE_AP &&
+		      vif->type == NL80211_IFTYPE_AP &&
+		      priv->num_ap_vif == 1) ||
+		    (priv->ah->opmode == NL80211_IFTYPE_MESH_POINT &&
+		      vif->type == NL80211_IFTYPE_MESH_POINT &&
+		      priv->num_mbss_vif == 1))) {
 			set_bit(OP_TSF_RESET, &priv->op_flags);
 		}
 		ath_dbg(common, CONFIG,
@@ -1761,6 +1774,43 @@ static int ath9k_htc_get_stats(struct ie
 	return 0;
 }
 
+struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv)
+{
+	struct base_eep_header *pBase = NULL;
+	/*
+	 * This can be done since all the 3 EEPROM families have the
+	 * same base header upto a certain point, and we are interested in
+	 * the data only upto that point.
+	 */
+
+	if (AR_SREV_9271(priv->ah))
+		pBase = (struct base_eep_header *)
+			&priv->ah->eeprom.map4k.baseEepHeader;
+	else if (priv->ah->hw_version.usbdev == AR9280_USB)
+		pBase = (struct base_eep_header *)
+			&priv->ah->eeprom.def.baseEepHeader;
+	else if (priv->ah->hw_version.usbdev == AR9287_USB)
+		pBase = (struct base_eep_header *)
+			&priv->ah->eeprom.map9287.baseEepHeader;
+	return pBase;
+}
+
+
+static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
+				 u32 *rx_ant)
+{
+	struct ath9k_htc_priv *priv = hw->priv;
+	struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv);
+	if (pBase) {
+		*tx_ant = pBase->txMask;
+		*rx_ant = pBase->rxMask;
+	} else {
+		*tx_ant = 0;
+		*rx_ant = 0;
+	}
+	return 0;
+}
+
 struct ieee80211_ops ath9k_htc_ops = {
 	.tx                 = ath9k_htc_tx,
 	.start              = ath9k_htc_start,
@@ -1786,4 +1836,11 @@ struct ieee80211_ops ath9k_htc_ops = {
 	.set_coverage_class = ath9k_htc_set_coverage_class,
 	.set_bitrate_mask   = ath9k_htc_set_bitrate_mask,
 	.get_stats	    = ath9k_htc_get_stats,
+	.get_antenna	    = ath9k_htc_get_antenna,
+
+#ifdef CONFIG_ATH9K_HTC_DEBUGFS
+	.get_et_sset_count  = ath9k_htc_get_et_sset_count,
+	.get_et_stats       = ath9k_htc_get_et_stats,
+	.get_et_strings     = ath9k_htc_get_et_strings,
+#endif
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c	2013-08-25 20:43:22.000000000 -0400
@@ -887,7 +887,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_
 	if (priv->rxfilter & FIF_PSPOLL)
 		rfilt |= ATH9K_RX_FILTER_PSPOLL;
 
-	if (priv->nvifs > 1)
+	if (priv->nvifs > 1 || priv->rxfilter & FIF_OTHER_BSS)
 		rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
 
 	return rfilt;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/htc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/htc.h	2013-08-25 20:43:22.000000000 -0400
@@ -142,6 +142,7 @@ struct ath9k_htc_target_aggr {
 #define WLAN_RC_40_FLAG  0x02
 #define WLAN_RC_SGI_FLAG 0x04
 #define WLAN_RC_HT_FLAG  0x08
+#define ATH_RC_TX_STBC_FLAG 0x20
 
 struct ath9k_htc_rateset {
 	u8 rs_nrates;
@@ -208,6 +209,9 @@ struct ath9k_htc_target_rx_stats {
 		case NL80211_IFTYPE_AP:		\
 			_priv->num_ap_vif++;	\
 			break;			\
+		case NL80211_IFTYPE_MESH_POINT:	\
+			_priv->num_mbss_vif++;	\
+			break;			\
 		default:			\
 			break;			\
 		}				\
@@ -224,6 +228,9 @@ struct ath9k_htc_target_rx_stats {
 		case NL80211_IFTYPE_AP:		\
 			_priv->num_ap_vif--;	\
 			break;			\
+		case NL80211_IFTYPE_MESH_POINT:	\
+			_priv->num_mbss_vif--;	\
+			break;			\
 		default:			\
 			break;			\
 		}				\
@@ -317,7 +324,9 @@ static inline struct ath9k_htc_tx_ctl *H
 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
 
 #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
+#define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
 #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
+#define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c += a)
 #define CAB_STAT_INC   priv->debug.tx_stats.cab_queued++
 
 #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
@@ -330,6 +339,7 @@ struct ath_tx_stats {
 	u32 buf_completed;
 	u32 skb_queued;
 	u32 skb_success;
+	u32 skb_success_bytes;
 	u32 skb_failed;
 	u32 cab_queued;
 	u32 queue_stats[IEEE80211_NUM_ACS];
@@ -338,6 +348,7 @@ struct ath_tx_stats {
 struct ath_rx_stats {
 	u32 skb_allocated;
 	u32 skb_completed;
+	u32 skb_completed_bytes;
 	u32 skb_dropped;
 	u32 err_crc;
 	u32 err_decrypt_crc;
@@ -355,10 +366,20 @@ struct ath9k_debug {
 	struct ath_rx_stats rx_stats;
 };
 
+void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
+			      struct ieee80211_vif *vif,
+			      u32 sset, u8 *data);
+int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,
+				struct ieee80211_vif *vif, int sset);
+void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
+			    struct ieee80211_vif *vif,
+			    struct ethtool_stats *stats, u64 *data);
 #else
 
 #define TX_STAT_INC(c) do { } while (0)
+#define TX_STAT_ADD(c, a) do { } while (0)
 #define RX_STAT_INC(c) do { } while (0)
+#define RX_STAT_ADD(c, a) do { } while (0)
 #define CAB_STAT_INC   do { } while (0)
 
 #define TX_QSTAT_INC(c) do { } while (0)
@@ -450,6 +471,7 @@ struct ath9k_htc_priv {
 	u8 sta_slot;
 	u8 vif_sta_pos[ATH9K_HTC_MAX_VIF];
 	u8 num_ibss_vif;
+	u8 num_mbss_vif;
 	u8 num_sta_vif;
 	u8 num_sta_assoc_vif;
 	u8 num_ap_vif;
@@ -575,6 +597,8 @@ bool ath9k_htc_setpower(struct ath9k_htc
 void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
 void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
 
+struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv);
+
 #ifdef CONFIG_MAC80211_LEDS
 void ath9k_init_leds(struct ath9k_htc_priv *priv);
 void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/hw.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/hw.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -452,7 +452,6 @@ static void ath9k_hw_init_config(struct
 	ah->config.pcie_clock_req = 0;
 	ah->config.pcie_waen = 0;
 	ah->config.analog_shiftreg = 1;
-	ah->config.enable_ani = true;
 
 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
 		ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -549,8 +548,7 @@ static int ath9k_hw_post_init(struct ath
 		ah->eep_ops->get_eeprom_ver(ah),
 		ah->eep_ops->get_eeprom_rev(ah));
 
-	if (ah->config.enable_ani)
-		ath9k_hw_ani_init(ah);
+	ath9k_hw_ani_init(ah);
 
 	return 0;
 }
@@ -1250,10 +1248,10 @@ static void ath9k_hw_set_operating_mode(
 
 	switch (opmode) {
 	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_MESH_POINT:
 		set |= AR_STA_ID1_ADHOC;
 		REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
 		break;
+	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_AP:
 		set |= AR_STA_ID1_STA_AP;
 		/* fall through */
@@ -1872,7 +1870,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 
 	ah->caldata = caldata;
 	if (caldata && (chan->channel != caldata->channel ||
-			chan->channelFlags != caldata->channelFlags)) {
+			chan->channelFlags != caldata->channelFlags ||
+			chan->chanmode != caldata->chanmode)) {
 		/* Operating channel changed, reset channel calibration data */
 		memset(caldata, 0, sizeof(*caldata));
 		ath9k_init_nfcal_hist_buffer(ah, chan);
@@ -2255,12 +2254,12 @@ void ath9k_hw_beaconinit(struct ath_hw *
 
 	switch (ah->opmode) {
 	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_MESH_POINT:
 		REG_SET_BIT(ah, AR_TXCFG,
 			    AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
 		REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
 			  TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
 		flags |= AR_NDP_TIMER_EN;
+	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_AP:
 		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
 		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon -
@@ -2600,17 +2599,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw
 		if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE))
 			pCap->hw_caps |= ATH9K_HW_CAP_MCI;
 
-		if (AR_SREV_9462_20(ah))
+		if (AR_SREV_9462_20_OR_LATER(ah))
 			pCap->hw_caps |= ATH9K_HW_CAP_RTT;
 	}
 
-	if (AR_SREV_9280_20_OR_LATER(ah)) {
-		pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE |
-				 ATH9K_HW_WOW_PATTERN_MATCH_EXACT;
-
-		if (AR_SREV_9280(ah))
-			pCap->hw_caps |= ATH9K_HW_WOW_PATTERN_MATCH_DWORD;
-	}
+	if (AR_SREV_9462(ah))
+		pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE;
 
 	if (AR_SREV_9300_20_OR_LATER(ah) &&
 	    ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
@@ -3048,7 +3042,7 @@ void ath9k_hw_gen_timer_start(struct ath
 
 	timer_next = tsf + trig_timeout;
 
-	ath_dbg(ath9k_hw_common(ah), HWTIMER,
+	ath_dbg(ath9k_hw_common(ah), BTCOEX,
 		"current tsf %x period %x timer_next %x\n",
 		tsf, timer_period, timer_next);
 
@@ -3147,7 +3141,7 @@ void ath_gen_timer_isr(struct ath_hw *ah
 		index = rightmost_index(timer_table, &thresh_mask);
 		timer = timer_table->timers[index];
 		BUG_ON(!timer);
-		ath_dbg(common, HWTIMER, "TSF overflow for Gen timer %d\n",
+		ath_dbg(common, BTCOEX, "TSF overflow for Gen timer %d\n",
 			index);
 		timer->overflow(timer->arg);
 	}
@@ -3156,7 +3150,7 @@ void ath_gen_timer_isr(struct ath_hw *ah
 		index = rightmost_index(timer_table, &trigger_mask);
 		timer = timer_table->timers[index];
 		BUG_ON(!timer);
-		ath_dbg(common, HWTIMER,
+		ath_dbg(common, BTCOEX,
 			"Gen timer[%d] trigger\n", index);
 		timer->trigger(timer->arg);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/hw.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/hw.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -246,9 +246,7 @@ enum ath9k_hw_caps {
 	ATH9K_HW_CAP_MCI			= BIT(15),
 	ATH9K_HW_CAP_DFS			= BIT(16),
 	ATH9K_HW_WOW_DEVICE_CAPABLE		= BIT(17),
-	ATH9K_HW_WOW_PATTERN_MATCH_EXACT	= BIT(18),
-	ATH9K_HW_WOW_PATTERN_MATCH_DWORD	= BIT(19),
-	ATH9K_HW_CAP_PAPRD			= BIT(20),
+	ATH9K_HW_CAP_PAPRD			= BIT(18),
 };
 
 /*
@@ -291,7 +289,6 @@ struct ath9k_ops_config {
 	u32 ofdm_trig_high;
 	u32 cck_trig_high;
 	u32 cck_trig_low;
-	u32 enable_ani;
 	u32 enable_paprd;
 	int serialize_regmode;
 	bool rx_intr_mitigation;
@@ -310,6 +307,10 @@ struct ath9k_ops_config {
 	u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
 	u8 max_txtrig_level;
 	u16 ani_poll_interval; /* ANI poll interval in ms */
+
+	/* Platform specific config */
+	u32 xlna_gpio;
+	bool xatten_margin_cfg;
 };
 
 enum ath9k_int {
@@ -423,7 +424,6 @@ struct ath9k_hw_cal_data {
 
 struct ath9k_channel {
 	struct ieee80211_channel *chan;
-	struct ar5416AniState ani;
 	u16 channel;
 	u32 channelFlags;
 	u32 chanmode;
@@ -854,10 +854,10 @@ struct ath_hw {
 	u32 globaltxtimeout;
 
 	/* ANI */
-	u32 proc_phyerr;
 	u32 aniperiod;
 	enum ath9k_ani_cmd ani_function;
 	u32 ani_skip_count;
+	struct ar5416AniState ani;
 
 #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
 	struct ath_btcoex_hw btcoex_hw;
@@ -882,9 +882,6 @@ struct ath_hw {
 	struct ar5416IniArray iniBank6;
 	struct ar5416IniArray iniAddac;
 	struct ar5416IniArray iniPcieSerdes;
-#ifdef CONFIG_PM_SLEEP
-	struct ar5416IniArray iniPcieSerdesWow;
-#endif
 	struct ar5416IniArray iniPcieSerdesLowPower;
 	struct ar5416IniArray iniModesFastClock;
 	struct ar5416IniArray iniAdditional;
@@ -895,6 +892,9 @@ struct ath_hw {
 	struct ar5416IniArray iniCckfirJapan2484;
 	struct ar5416IniArray iniModes_9271_ANI_reg;
 	struct ar5416IniArray ini_radio_post_sys2ant;
+	struct ar5416IniArray ini_modes_rxgain_5g_xlna;
+	struct ar5416IniArray ini_modes_rxgain_bb_core;
+	struct ar5416IniArray ini_modes_rxgain_bb_postamble;
 
 	struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT];
 	struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT];
@@ -1165,8 +1165,6 @@ static inline void ath9k_hw_wow_enable(s
 }
 #endif
 
-
-
 #define ATH9K_CLOCK_RATE_CCK		22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/init.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/init.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/ath9k_platform.h>
 #include <linux/module.h>
 #include <linux/relay.h>
+#include <net/ieee80211_radiotap.h>
 
 #include "ath9k.h"
 
@@ -431,6 +432,8 @@ static int ath9k_init_queues(struct ath_
 	sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
 	ath_cabq_update(sc);
 
+	sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0);
+
 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
 		sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
 		sc->tx.txq_map[i]->mac80211_qnum = i;
@@ -510,6 +513,27 @@ static void ath9k_init_misc(struct ath_s
 	sc->spec_config.fft_period = 0xF;
 }
 
+static void ath9k_init_platform(struct ath_softc *sc)
+{
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	if (common->bus_ops->ath_bus_type != ATH_PCI)
+		return;
+
+	if (sc->driver_data & (ATH9K_PCI_CUS198 |
+			       ATH9K_PCI_CUS230)) {
+		ah->config.xlna_gpio = 9;
+		ah->config.xatten_margin_cfg = true;
+
+		ath_info(common, "Set parameters for %s\n",
+			 (sc->driver_data & ATH9K_PCI_CUS198) ?
+			 "CUS198" : "CUS230");
+	} else if (sc->driver_data & ATH9K_PCI_CUS217) {
+		ath_info(common, "CUS217 card detected\n");
+	}
+}
+
 static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob,
 				    void *ctx)
 {
@@ -602,6 +626,11 @@ static int ath9k_init_softc(u16 devid, s
 	common->disable_ani = false;
 
 	/*
+	 * Platform quirks.
+	 */
+	ath9k_init_platform(sc);
+
+	/*
 	 * Enable Antenna diversity only when BTCOEX is disabled
 	 * and the user manually requests the feature.
 	 */
@@ -613,9 +642,6 @@ static int ath9k_init_softc(u16 devid, s
 	spin_lock_init(&sc->sc_serial_rw);
 	spin_lock_init(&sc->sc_pm_lock);
 	mutex_init(&sc->mutex);
-#ifdef CONFIG_ATH9K_MAC_DEBUG
-	spin_lock_init(&sc->debug.samp_lock);
-#endif
 	tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
 	tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
 		     (unsigned long)sc);
@@ -755,6 +781,15 @@ static const struct ieee80211_iface_comb
 	}
 };
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support ath9k_wowlan_support = {
+	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
+	.n_patterns = MAX_NUM_USER_PATTERN,
+	.pattern_min_len = 1,
+	.pattern_max_len = MAX_PATTERN_SIZE,
+};
+#endif
+
 void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
@@ -769,12 +804,19 @@ void ath9k_set_hw_capab(struct ath_softc
 		IEEE80211_HW_REPORTS_TX_ACK_STATUS |
 		IEEE80211_HW_SUPPORTS_RC_TABLE;
 
-	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
-		 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+		hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+
+		if (AR_SREV_9280_20_OR_LATER(ah))
+			hw->radiotap_mcs_details |=
+				IEEE80211_RADIOTAP_MCS_HAVE_STBC;
+	}
 
 	if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
 		hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 
+	hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
+
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_P2P_GO) |
 		BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -794,21 +836,13 @@ void ath9k_set_hw_capab(struct ath_softc
 	hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
 
 #ifdef CONFIG_PM_SLEEP
-
 	if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
-	    device_can_wakeup(sc->dev)) {
-
-		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-					  WIPHY_WOWLAN_DISCONNECT;
-		hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN;
-		hw->wiphy->wowlan.pattern_min_len = 1;
-		hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE;
-
-	}
+	    (sc->driver_data & ATH9K_PCI_WOW) &&
+	    device_can_wakeup(sc->dev))
+		hw->wiphy->wowlan = &ath9k_wowlan_support;
 
 	atomic_set(&sc->wow_sleep_proc_intr, -1);
 	atomic_set(&sc->wow_got_bmiss_intr, -1);
-
 #endif
 
 	hw->queues = 4;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,7 @@ config ATH9K
 	  Atheros IEEE 802.11n AR5008, AR9001 and AR9002 family
 	  of chipsets. For a specific list of supported external
 	  cards, laptops that already ship with these cards and
-	  APs that come with these cards refer to to ath9k wiki
+	  APs that come with these cards refer to ath9k wiki
 	  products page:
 
 	  http://wireless.kernel.org/en/users/Drivers/ath9k/products
@@ -84,14 +84,6 @@ config ATH9K_DFS_CERTIFIED
 	  developed. At this point enabling this option won't do anything
 	  except increase code size.
 
-config ATH9K_MAC_DEBUG
-	bool "Atheros MAC statistics"
-	depends on ATH9K_DEBUGFS
-	default y
-	---help---
-	  This option enables collection of statistics for Rx/Tx status
-	  data and some other MAC related statistics
-
 config ATH9K_LEGACY_RATE_CONTROL
 	bool "Atheros ath9k rate control"
 	depends on ATH9K
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/link.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/link.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/link.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/link.c	2013-08-25 20:43:22.000000000 -0400
@@ -390,9 +390,7 @@ void ath_ani_calibrate(unsigned long dat
 	}
 
 	/* Verify whether we must check ANI */
-	if (sc->sc_ah->config.enable_ani
-	    && (timestamp - common->ani.checkani_timer) >=
-	    ah->config.ani_poll_interval) {
+	if ((timestamp - common->ani.checkani_timer) >= ah->config.ani_poll_interval) {
 		aniflag = true;
 		common->ani.checkani_timer = timestamp;
 	}
@@ -418,7 +416,6 @@ void ath_ani_calibrate(unsigned long dat
 		longcal ? "long" : "", shortcal ? "short" : "",
 		aniflag ? "ani" : "", common->ani.caldone ? "true" : "false");
 
-	ath9k_debug_samp_bb_mac(sc);
 	ath9k_ps_restore(sc);
 
 set_timer:
@@ -428,9 +425,7 @@ set_timer:
 	* short calibration and long calibration.
 	*/
 	cal_interval = ATH_LONG_CALINTERVAL;
-	if (sc->sc_ah->config.enable_ani)
-		cal_interval = min(cal_interval,
-				   (u32)ah->config.ani_poll_interval);
+	cal_interval = min(cal_interval, (u32)ah->config.ani_poll_interval);
 	if (!common->ani.caldone)
 		cal_interval = min(cal_interval, (u32)short_cal_interval);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/mac.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/mac.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/mac.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/mac.c	2013-08-25 20:43:22.000000000 -0400
@@ -547,6 +547,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
 
 	rs->rs_status = 0;
 	rs->rs_flags = 0;
+	rs->flag = 0;
 
 	rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
 	rs->rs_tstamp = ads.AR_RcvTimestamp;
@@ -586,10 +587,17 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
 	rs->rs_moreaggr =
 		(ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
 	rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
-	rs->rs_flags =
-		(ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
-	rs->rs_flags |=
-		(ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
+
+	/* directly mapped flags for ieee80211_rx_status */
+	rs->flag |=
+		(ads.ds_rxstatus3 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
+	rs->flag |=
+		(ads.ds_rxstatus3 & AR_2040) ? RX_FLAG_40MHZ : 0;
+	if (AR_SREV_9280_20_OR_LATER(ah))
+		rs->flag |=
+			(ads.ds_rxstatus3 & AR_STBC) ?
+				/* we can only Nss=1 STBC */
+				(1 << RX_FLAG_STBC_SHIFT) : 0;
 
 	if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
 		rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/mac.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/mac.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/mac.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/mac.h	2013-08-25 20:43:22.000000000 -0400
@@ -149,6 +149,7 @@ struct ath_rx_status {
 	u32 evm2;
 	u32 evm3;
 	u32 evm4;
+	u32 flag; /* see enum mac80211_rx_flags */
 };
 
 struct ath_htc_rx_status {
@@ -533,7 +534,8 @@ struct ar5416_desc {
 #define AR_2040             0x00000002
 #define AR_Parallel40       0x00000004
 #define AR_Parallel40_S     2
-#define AR_RxStatusRsvd30   0x000000f8
+#define AR_STBC             0x00000008 /* on ar9280 and later */
+#define AR_RxStatusRsvd30   0x000000f0
 #define AR_RxAntenna	    0xffffff00
 #define AR_RxAntenna_S	    8
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -193,7 +193,6 @@ static bool ath_prepare_reset(struct ath
 	ath_stop_ani(sc);
 	del_timer_sync(&sc->rx_poll_timer);
 
-	ath9k_debug_samp_bb_mac(sc);
 	ath9k_hw_disable_interrupts(ah);
 
 	if (!ath_drain_all_txq(sc))
@@ -1211,13 +1210,6 @@ static int ath9k_config(struct ieee80211
 		ath_update_survey_stats(sc);
 		spin_unlock_irqrestore(&common->cc_lock, flags);
 
-		/*
-		 * Preserve the current channel values, before updating
-		 * the same channel
-		 */
-		if (ah->curchan && (old_pos == pos))
-			ath9k_hw_getnf(ah, ah->curchan);
-
 		ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
 					  curchan, channel_type);
 
@@ -1273,7 +1265,7 @@ static int ath9k_config(struct ieee80211
 				curchan->center_freq);
 		} else {
 			/* perform spectral scan if requested. */
-			if (sc->scanning &&
+			if (test_bit(SC_OP_SCANNING, &sc->sc_flags) &&
 			    sc->spectral_mode == SPECTRAL_CHANSCAN)
 				ath9k_spectral_scan_trigger(hw);
 		}
@@ -1690,7 +1682,7 @@ static int ath9k_ampdu_action(struct iee
 	bool flush = false;
 	int ret = 0;
 
-	local_bh_disable();
+	mutex_lock(&sc->mutex);
 
 	switch (action) {
 	case IEEE80211_AMPDU_RX_START:
@@ -1723,7 +1715,7 @@ static int ath9k_ampdu_action(struct iee
 		ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
 	}
 
-	local_bh_enable();
+	mutex_unlock(&sc->mutex);
 
 	return ret;
 }
@@ -2007,7 +1999,6 @@ static void ath9k_wow_add_disassoc_deaut
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath9k_hw_capabilities *pcaps = &ah->caps;
 	int pattern_count = 0;
 	int i, byte_cnt;
 	u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
@@ -2077,36 +2068,9 @@ static void ath9k_wow_add_disassoc_deaut
 
 	/* Create Disassociate pattern mask */
 
-	if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_EXACT) {
-
-		if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_DWORD) {
-			/*
-			 * for AR9280, because of hardware limitation, the
-			 * first 4 bytes have to be matched for all patterns.
-			 * the mask for disassociation and de-auth pattern
-			 * matching need to enable the first 4 bytes.
-			 * also the duration field needs to be filled.
-			 */
-			dis_deauth_mask[0] = 0xf0;
-
-			/*
-			 * fill in duration field
-			 FIXME: what is the exact value ?
-			 */
-			dis_deauth_pattern[2] = 0xff;
-			dis_deauth_pattern[3] = 0xff;
-		} else {
-			dis_deauth_mask[0] = 0xfe;
-		}
-
-		dis_deauth_mask[1] = 0x03;
-		dis_deauth_mask[2] = 0xc0;
-	} else {
-		dis_deauth_mask[0] = 0xef;
-		dis_deauth_mask[1] = 0x3f;
-		dis_deauth_mask[2] = 0x00;
-		dis_deauth_mask[3] = 0xfc;
-	}
+	dis_deauth_mask[0] = 0xfe;
+	dis_deauth_mask[1] = 0x03;
+	dis_deauth_mask[2] = 0xc0;
 
 	ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
 
@@ -2342,15 +2306,13 @@ static void ath9k_set_wakeup(struct ieee
 static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
 {
 	struct ath_softc *sc = hw->priv;
-
-	sc->scanning = 1;
+	set_bit(SC_OP_SCANNING, &sc->sc_flags);
 }
 
 static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
 {
 	struct ath_softc *sc = hw->priv;
-
-	sc->scanning = 0;
+	clear_bit(SC_OP_SCANNING, &sc->sc_flags);
 }
 
 struct ieee80211_ops ath9k_ops = {
@@ -2378,6 +2340,7 @@ struct ieee80211_ops ath9k_ops = {
 	.flush		    = ath9k_flush,
 	.tx_frames_pending  = ath9k_tx_frames_pending,
 	.tx_last_beacon     = ath9k_tx_last_beacon,
+	.release_buffered_frames = ath9k_release_buffered_frames,
 	.get_stats	    = ath9k_get_stats,
 	.set_antenna	    = ath9k_set_antenna,
 	.get_antenna	    = ath9k_get_antenna,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/pci.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/pci.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,8 +34,108 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i
 	{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI   */
 	{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
 	{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E  AR9300 */
+
+	/* PCI-E CUS198 */
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0032,
+			 PCI_VENDOR_ID_AZWAVE,
+			 0x2086),
+	  .driver_data = ATH9K_PCI_CUS198 },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0032,
+			 PCI_VENDOR_ID_AZWAVE,
+			 0x1237),
+	  .driver_data = ATH9K_PCI_CUS198 },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0032,
+			 PCI_VENDOR_ID_AZWAVE,
+			 0x2126),
+	  .driver_data = ATH9K_PCI_CUS198 },
+
+	/* PCI-E CUS230 */
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0032,
+			 PCI_VENDOR_ID_AZWAVE,
+			 0x2152),
+	  .driver_data = ATH9K_PCI_CUS230 },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0032,
+			 PCI_VENDOR_ID_FOXCONN,
+			 0xE075),
+	  .driver_data = ATH9K_PCI_CUS230 },
+
 	{ PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E  AR9485 */
 	{ PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E  AR9580 */
+
+	/* PCI-E CUS217 */
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 PCI_VENDOR_ID_AZWAVE,
+			 0x2116),
+	  .driver_data = ATH9K_PCI_CUS217 },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 0x11AD, /* LITEON */
+			 0x6661),
+	  .driver_data = ATH9K_PCI_CUS217 },
+
+	/* AR9462 with WoW support */
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 PCI_VENDOR_ID_ATHEROS,
+			 0x3117),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 PCI_VENDOR_ID_LENOVO,
+			 0x3214),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 PCI_VENDOR_ID_ATTANSIC,
+			 0x0091),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 PCI_VENDOR_ID_AZWAVE,
+			 0x2110),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 PCI_VENDOR_ID_ASUSTEK,
+			 0x850E),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 0x11AD, /* LITEON */
+			 0x6631),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 0x11AD, /* LITEON */
+			 0x6641),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 PCI_VENDOR_ID_HP,
+			 0x1864),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 0x14CD, /* USI */
+			 0x0063),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 0x14CD, /* USI */
+			 0x0064),
+	  .driver_data = ATH9K_PCI_WOW },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 0x10CF, /* Fujitsu */
+			 0x1783),
+	  .driver_data = ATH9K_PCI_WOW },
+
 	{ PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E  AR9462 */
 	{ PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E  AR1111/AR9485 */
 	{ PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E  AR9565 */
@@ -221,6 +321,7 @@ static int ath_pci_probe(struct pci_dev
 	sc->hw = hw;
 	sc->dev = &pdev->dev;
 	sc->mem = pcim_iomap_table(pdev)[0];
+	sc->driver_data = id->driver_data;
 
 	/* Will be cleared in ath9k_start() */
 	set_bit(SC_OP_INVALID, &sc->sc_flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/recv.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/recv.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/recv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/recv.c	2013-08-25 20:43:22.000000000 -0400
@@ -868,10 +868,7 @@ static int ath9k_process_rate(struct ath
 	if (rx_stats->rs_rate & 0x80) {
 		/* HT rate */
 		rxs->flag |= RX_FLAG_HT;
-		if (rx_stats->rs_flags & ATH9K_RX_2040)
-			rxs->flag |= RX_FLAG_40MHZ;
-		if (rx_stats->rs_flags & ATH9K_RX_GI)
-			rxs->flag |= RX_FLAG_SHORT_GI;
+		rxs->flag |= rx_stats->flag;
 		rxs->rate_idx = rx_stats->rs_rate & 0x7f;
 		return 0;
 	}
@@ -958,11 +955,11 @@ static int ath9k_rx_skb_preprocess(struc
 	if (rx_stats->rs_more)
 		return 0;
 
-	ath9k_process_rssi(common, hw, hdr, rx_stats);
-
 	if (ath9k_process_rate(common, hw, rx_stats, rx_status))
 		return -EINVAL;
 
+	ath9k_process_rssi(common, hw, hdr, rx_stats);
+
 	rx_status->band = hw->conf.chandef.chan->band;
 	rx_status->freq = hw->conf.chandef.chan->center_freq;
 	rx_status->signal = ah->noise + rx_stats->rs_rssi;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/reg.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/reg.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -806,6 +806,7 @@
 #define AR_SREV_REVISION_9580_10	4 /* AR9580 1.0 */
 #define AR_SREV_VERSION_9462		0x280
 #define AR_SREV_REVISION_9462_20	2
+#define AR_SREV_REVISION_9462_21	3
 #define AR_SREV_VERSION_9565            0x2C0
 #define AR_SREV_REVISION_9565_10        0
 #define AR_SREV_VERSION_9550		0x400
@@ -911,10 +912,18 @@
 
 #define AR_SREV_9462(_ah) \
 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
-
 #define AR_SREV_9462_20(_ah) \
 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
-	((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))
+	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))
+#define AR_SREV_9462_21(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
+	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_21))
+#define AR_SREV_9462_20_OR_LATER(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
+	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20))
+#define AR_SREV_9462_21_OR_LATER(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
+	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_21))
 
 #define AR_SREV_9565(_ah) \
 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/wow.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/wow.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/wow.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/wow.c	2013-08-25 20:43:22.000000000 -0400
@@ -34,17 +34,6 @@ const char *ath9k_hw_wow_event_to_string
 }
 EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
 
-static void ath9k_hw_config_serdes_wow_sleep(struct ath_hw *ah)
-{
-	int i;
-
-	for (i = 0; i < ah->iniPcieSerdesWow.ia_rows; i++)
-		REG_WRITE(ah, INI_RA(&ah->iniPcieSerdesWow, i, 0),
-			  INI_RA(&ah->iniPcieSerdesWow, i, 1));
-
-	usleep_range(1000, 1500);
-}
-
 static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
@@ -58,15 +47,8 @@ static void ath9k_hw_set_powermode_wow_s
 		ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
 			REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
 		return;
-	} else {
-		if (!AR_SREV_9300_20_OR_LATER(ah))
-			REG_WRITE(ah, AR_RXDP, 0x0);
 	}
 
-	/* AR9280 WoW has sleep issue, do not set it to sleep */
-	if (AR_SREV_9280_20(ah))
-		return;
-
 	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
 }
 
@@ -84,27 +66,16 @@ static void ath9k_wow_create_keep_alive_
 
 	/* set the transmit buffer */
 	ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
-
-	if (!(AR_SREV_9300_20_OR_LATER(ah)))
-		ctl[0] += (KAL_ANTENNA_MODE << 25);
-
 	ctl[1] = 0;
 	ctl[3] = 0xb;	/* OFDM_6M hardware value for this rate */
 	ctl[4] = 0;
 	ctl[7] = (ah->txchainmask) << 2;
-
-	if (AR_SREV_9300_20_OR_LATER(ah))
-		ctl[2] = 0xf << 16; /* tx_tries 0 */
-	else
-		ctl[2] = 0x7 << 16; /* tx_tries 0 */
-
+	ctl[2] = 0xf << 16; /* tx_tries 0 */
 
 	for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
 		REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
 
-	/* for AR9300 family 13 descriptor words */
-	if (AR_SREV_9300_20_OR_LATER(ah))
-		REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
+	REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
 
 	data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
 		       (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
@@ -183,9 +154,6 @@ void ath9k_hw_wow_apply_pattern(struct a
 
 	ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
 
-	if (!AR_SREV_9285_12_OR_LATER(ah))
-		return;
-
 	if (pattern_count < 4) {
 		/* Pattern 0-3 uses AR_WOW_LENGTH1 register */
 		set = (pattern_len & AR_WOW_LENGTH_MAX) <<
@@ -207,6 +175,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *a
 {
 	u32 wow_status = 0;
 	u32 val = 0, rval;
+
 	/*
 	 * read the WoW status register to know
 	 * the wakeup reason
@@ -223,19 +192,14 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *a
 	val &= ah->wow_event_mask;
 
 	if (val) {
-
 		if (val & AR_WOW_MAGIC_PAT_FOUND)
 			wow_status |= AH_WOW_MAGIC_PATTERN_EN;
-
 		if (AR_WOW_PATTERN_FOUND(val))
 			wow_status |= AH_WOW_USER_PATTERN_EN;
-
 		if (val & AR_WOW_KEEP_ALIVE_FAIL)
 			wow_status |= AH_WOW_LINK_CHANGE;
-
 		if (val & AR_WOW_BEACON_FAIL)
 			wow_status |= AH_WOW_BEACON_MISS;
-
 	}
 
 	/*
@@ -255,17 +219,6 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *a
 		  AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
 
 	/*
-	 * tie reset register for AR9002 family of chipsets
-	 * NB: not tieing it back might have some repurcussions.
-	 */
-
-	if (!AR_SREV_9300_20_OR_LATER(ah)) {
-		REG_SET_BIT(ah, AR_WA, AR_WA_UNTIE_RESET_EN |
-			    AR_WA_POR_SHORT | AR_WA_RESET_EN);
-	}
-
-
-	/*
 	 * restore the beacon threshold to init value
 	 */
 	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
@@ -277,8 +230,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *a
 	 * reset to our Chip's Power On Reset so that any PCI-E
 	 * reset from the bus will not reset our chip
 	 */
-
-	if (AR_SREV_9280_20_OR_LATER(ah) && ah->is_pciexpress)
+	if (ah->is_pciexpress)
 		ath9k_hw_configpcipowersave(ah, false);
 
 	ah->wow_event_mask = 0;
@@ -298,7 +250,6 @@ void ath9k_hw_wow_enable(struct ath_hw *
 	 * are from the 'pattern_enable' in this function and
 	 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
 	 */
-
 	wow_event_mask = ah->wow_event_mask;
 
 	/*
@@ -306,50 +257,15 @@ void ath9k_hw_wow_enable(struct ath_hw *
 	 * WOW sleep, we do want the Reset from the PCI-E to disturb
 	 * our hw state
 	 */
-
 	if (ah->is_pciexpress) {
-
 		/*
 		 * we need to untie the internal POR (power-on-reset)
 		 * to the external PCI-E reset. We also need to tie
 		 * the PCI-E Phy reset to the PCI-E reset.
 		 */
-
-		if (AR_SREV_9300_20_OR_LATER(ah)) {
-			set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
-			clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
-			REG_RMW(ah, AR_WA, set, clr);
-		} else {
-			if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
-				set = AR9285_WA_DEFAULT;
-			else
-				set = AR9280_WA_DEFAULT;
-
-			/*
-			 * In AR9280 and AR9285, bit 14 in WA register
-			 * (disable L1) should only be set when device
-			 * enters D3 state and be cleared when device
-			 * comes back to D0
-			 */
-
-			if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
-				set |= AR_WA_D3_L1_DISABLE;
-
-			clr = AR_WA_UNTIE_RESET_EN;
-			set |= AR_WA_RESET_EN | AR_WA_POR_SHORT;
-			REG_RMW(ah, AR_WA, set, clr);
-
-			/*
-			 * for WoW sleep, we reprogram the SerDes so that the
-			 * PLL and CLK REQ are both enabled. This uses more
-			 * power but otherwise WoW sleep is unstable and the
-			 * chip may disappear.
-			 */
-
-			if (AR_SREV_9285_12_OR_LATER(ah))
-				ath9k_hw_config_serdes_wow_sleep(ah);
-
-		}
+		set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
+		clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
+		REG_RMW(ah, AR_WA, set, clr);
 	}
 
 	/*
@@ -378,7 +294,6 @@ void ath9k_hw_wow_enable(struct ath_hw *
 	 * Program default values for pattern backoff, aifs/slot/KAL count,
 	 * beacon miss timeout, KAL timeout, etc.
 	 */
-
 	set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
 	REG_SET_BIT(ah, AR_WOW_PATTERN, set);
 
@@ -398,7 +313,7 @@ void ath9k_hw_wow_enable(struct ath_hw *
 	/*
 	 * Keep alive timo in ms except AR9280
 	 */
-	if (!pattern_enable || AR_SREV_9280(ah))
+	if (!pattern_enable)
 		set = AR_WOW_KEEP_ALIVE_NEVER;
 	else
 		set = KAL_TIMEOUT * 32;
@@ -420,7 +335,6 @@ void ath9k_hw_wow_enable(struct ath_hw *
 	/*
 	 * Configure MAC WoW Registers
 	 */
-
 	set = 0;
 	/* Send keep alive timeouts anyway */
 	clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
@@ -430,16 +344,9 @@ void ath9k_hw_wow_enable(struct ath_hw *
 	else
 		set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
 
-	/*
-	 * FIXME: For now disable keep alive frame
-	 * failure. This seems to sometimes trigger
-	 * unnecessary wake up with AR9485 chipsets.
-	 */
 	set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
-
 	REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
 
-
 	/*
 	 * we are relying on a bmiss failure. ensure we have
 	 * enough threshold to prevent false positives
@@ -473,14 +380,8 @@ void ath9k_hw_wow_enable(struct ath_hw *
 	set |= AR_WOW_MAC_INTR_EN;
 	REG_RMW(ah, AR_WOW_PATTERN, set, clr);
 
-	/*
-	 * For AR9285 and later version of chipsets
-	 * enable WoW pattern match for packets less
-	 * than 256 bytes for all patterns
-	 */
-	if (AR_SREV_9285_12_OR_LATER(ah))
-		REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
-			  AR_WOW_PATTERN_SUPPORTED);
+	REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
+		  AR_WOW_PATTERN_SUPPORTED);
 
 	/*
 	 * Set the power states appropriately and enable PME
@@ -488,43 +389,32 @@ void ath9k_hw_wow_enable(struct ath_hw *
 	clr = 0;
 	set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
 	      AR_PMCTRL_PWR_PM_CTRL_ENA;
-	/*
-	 * This is needed for AR9300 chipsets to wake-up
-	 * the host.
-	 */
-	if (AR_SREV_9300_20_OR_LATER(ah))
-		clr = AR_PCIE_PM_CTRL_ENA;
 
+	clr = AR_PCIE_PM_CTRL_ENA;
 	REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
 
-	if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
-		/*
-		 * this is needed to prevent the chip waking up
-		 * the host within 3-4 seconds with certain
-		 * platform/BIOS. The fix is to enable
-		 * D1 & D3 to match original definition and
-		 * also match the OTP value. Anyway this
-		 * is more related to SW WOW.
-		 */
-		clr = AR_PMCTRL_PWR_STATE_D1D3;
-		REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
-
-		set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
-		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
-	}
-
+	/*
+	 * this is needed to prevent the chip waking up
+	 * the host within 3-4 seconds with certain
+	 * platform/BIOS. The fix is to enable
+	 * D1 & D3 to match original definition and
+	 * also match the OTP value. Anyway this
+	 * is more related to SW WOW.
+	 */
+	clr = AR_PMCTRL_PWR_STATE_D1D3;
+	REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
 
+	set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
+	REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
 
 	REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
 
-	if (AR_SREV_9300_20_OR_LATER(ah)) {
-		/* to bring down WOW power low margin */
-		set = BIT(13);
-		REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
-		/* HW WoW */
-		clr = BIT(5);
-		REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
-	}
+	/* to bring down WOW power low margin */
+	set = BIT(13);
+	REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
+	/* HW WoW */
+	clr = BIT(5);
+	REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
 
 	ath9k_hw_set_powermode_wow_sleep(ah);
 	ah->wow_event_mask = wow_event_mask;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/xmit.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/xmit.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath9k/xmit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath9k/xmit.c	2013-08-25 20:43:22.000000000 -0400
@@ -146,6 +146,28 @@ static void ath_set_rates(struct ieee802
 			       ARRAY_SIZE(bf->rates));
 }
 
+static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
+			     struct sk_buff *skb)
+{
+	int q;
+
+	q = skb_get_queue_mapping(skb);
+	if (txq == sc->tx.uapsdq)
+		txq = sc->tx.txq_map[q];
+
+	if (txq != sc->tx.txq_map[q])
+		return;
+
+	if (WARN_ON(--txq->pending_frames < 0))
+		txq->pending_frames = 0;
+
+	if (txq->stopped &&
+	    txq->pending_frames < sc->tx.txq_max_pending[q]) {
+		ieee80211_wake_queue(sc->hw, q);
+		txq->stopped = false;
+	}
+}
+
 static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 {
 	struct ath_txq *txq = tid->ac->txq;
@@ -167,6 +189,7 @@ static void ath_tx_flush_tid(struct ath_
 		if (!bf) {
 			bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 			if (!bf) {
+				ath_txq_skb_done(sc, txq, skb);
 				ieee80211_free_txskb(sc->hw, skb);
 				continue;
 			}
@@ -518,6 +541,10 @@ static void ath_tx_complete_aggr(struct
 			ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
 				!txfail);
 		} else {
+			if (tx_info->flags & IEEE80211_TX_STATUS_EOSP) {
+				tx_info->flags &= ~IEEE80211_TX_STATUS_EOSP;
+				ieee80211_sta_eosp(sta);
+			}
 			/* retry the un-acked ones */
 			if (bf->bf_next == NULL && bf_last->bf_stale) {
 				struct ath_buf *tbf;
@@ -786,25 +813,20 @@ static int ath_compute_num_delims(struct
 	return ndelim;
 }
 
-static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
-					     struct ath_txq *txq,
-					     struct ath_atx_tid *tid,
-					     struct list_head *bf_q,
-					     int *aggr_len)
+static struct ath_buf *
+ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
+			struct ath_atx_tid *tid)
 {
-#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
-	struct ath_buf *bf, *bf_first = NULL, *bf_prev = NULL;
-	int rl = 0, nframes = 0, ndelim, prev_al = 0;
-	u16 aggr_limit = 0, al = 0, bpad = 0,
-		al_delta, h_baw = tid->baw_size / 2;
-	enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
-	struct ieee80211_tx_info *tx_info;
 	struct ath_frame_info *fi;
 	struct sk_buff *skb;
+	struct ath_buf *bf;
 	u16 seqno;
 
-	do {
+	while (1) {
 		skb = skb_peek(&tid->buf_q);
+		if (!skb)
+			break;
+
 		fi = get_frame_info(skb);
 		bf = fi->bf;
 		if (!fi->bf)
@@ -812,6 +834,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
 
 		if (!bf) {
 			__skb_unlink(skb, &tid->buf_q);
+			ath_txq_skb_done(sc, txq, skb);
 			ieee80211_free_txskb(sc->hw, skb);
 			continue;
 		}
@@ -820,10 +843,8 @@ static enum ATH_AGGR_STATUS ath_tx_form_
 		seqno = bf->bf_state.seqno;
 
 		/* do not step over block-ack window */
-		if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
-			status = ATH_AGGR_BAW_CLOSED;
+		if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno))
 			break;
-		}
 
 		if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) {
 			struct ath_tx_status ts = {};
@@ -837,6 +858,40 @@ static enum ATH_AGGR_STATUS ath_tx_form_
 			continue;
 		}
 
+		bf->bf_next = NULL;
+		bf->bf_lastbf = bf;
+		return bf;
+	}
+
+	return NULL;
+}
+
+static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
+					     struct ath_txq *txq,
+					     struct ath_atx_tid *tid,
+					     struct list_head *bf_q,
+					     int *aggr_len)
+{
+#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
+	struct ath_buf *bf, *bf_first = NULL, *bf_prev = NULL;
+	int rl = 0, nframes = 0, ndelim, prev_al = 0;
+	u16 aggr_limit = 0, al = 0, bpad = 0,
+		al_delta, h_baw = tid->baw_size / 2;
+	enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
+	struct ieee80211_tx_info *tx_info;
+	struct ath_frame_info *fi;
+	struct sk_buff *skb;
+
+	do {
+		bf = ath_tx_get_tid_subframe(sc, txq, tid);
+		if (!bf) {
+			status = ATH_AGGR_BAW_CLOSED;
+			break;
+		}
+
+		skb = bf->bf_mpdu;
+		fi = get_frame_info(skb);
+
 		if (!bf_first)
 			bf_first = bf;
 
@@ -882,7 +937,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_
 
 		/* link buffers of this frame to the aggregate */
 		if (!fi->retries)
-			ath_tx_addto_baw(sc, tid, seqno);
+			ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
 		bf->bf_state.ndelim = ndelim;
 
 		__skb_unlink(skb, &tid->buf_q);
@@ -1090,10 +1145,8 @@ static void ath_tx_fill_desc(struct ath_
 			     struct ath_txq *txq, int len)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
-	struct ath_buf *bf_first = bf;
+	struct ath_buf *bf_first = NULL;
 	struct ath_tx_info info;
-	bool aggr = !!(bf->bf_state.bf_type & BUF_AGGR);
 
 	memset(&info, 0, sizeof(info));
 	info.is_first = true;
@@ -1101,24 +1154,11 @@ static void ath_tx_fill_desc(struct ath_
 	info.txpower = MAX_RATE_POWER;
 	info.qcu = txq->axq_qnum;
 
-	info.flags = ATH9K_TXDESC_INTREQ;
-	if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
-		info.flags |= ATH9K_TXDESC_NOACK;
-	if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
-		info.flags |= ATH9K_TXDESC_LDPC;
-
-	ath_buf_set_rate(sc, bf, &info, len);
-
-	if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
-		info.flags |= ATH9K_TXDESC_CLRDMASK;
-
-	if (bf->bf_state.bfs_paprd)
-		info.flags |= (u32) bf->bf_state.bfs_paprd << ATH9K_TXDESC_PAPRD_S;
-
-
 	while (bf) {
 		struct sk_buff *skb = bf->bf_mpdu;
+		struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 		struct ath_frame_info *fi = get_frame_info(skb);
+		bool aggr = !!(bf->bf_state.bf_type & BUF_AGGR);
 
 		info.type = get_hw_packet_type(skb);
 		if (bf->bf_next)
@@ -1126,6 +1166,26 @@ static void ath_tx_fill_desc(struct ath_
 		else
 			info.link = 0;
 
+		if (!bf_first) {
+			bf_first = bf;
+
+			info.flags = ATH9K_TXDESC_INTREQ;
+			if ((tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) ||
+			    txq == sc->tx.uapsdq)
+				info.flags |= ATH9K_TXDESC_CLRDMASK;
+
+			if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
+				info.flags |= ATH9K_TXDESC_NOACK;
+			if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
+				info.flags |= ATH9K_TXDESC_LDPC;
+
+			if (bf->bf_state.bfs_paprd)
+				info.flags |= (u32) bf->bf_state.bfs_paprd <<
+					      ATH9K_TXDESC_PAPRD_S;
+
+			ath_buf_set_rate(sc, bf, &info, len);
+		}
+
 		info.buf_addr[0] = bf->bf_buf_addr;
 		info.buf_len[0] = skb->len;
 		info.pkt_len = fi->framelen;
@@ -1135,7 +1195,7 @@ static void ath_tx_fill_desc(struct ath_
 		if (aggr) {
 			if (bf == bf_first)
 				info.aggr = AGGR_BUF_FIRST;
-			else if (!bf->bf_next)
+			else if (bf == bf_first->bf_lastbf)
 				info.aggr = AGGR_BUF_LAST;
 			else
 				info.aggr = AGGR_BUF_MIDDLE;
@@ -1144,6 +1204,9 @@ static void ath_tx_fill_desc(struct ath_
 			info.aggr_len = len;
 		}
 
+		if (bf == bf_first->bf_lastbf)
+			bf_first = NULL;
+
 		ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
 		bf = bf->bf_next;
 	}
@@ -1328,6 +1391,70 @@ void ath_tx_aggr_resume(struct ath_softc
 	ath_txq_unlock_complete(sc, txq);
 }
 
+void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
+				   struct ieee80211_sta *sta,
+				   u16 tids, int nframes,
+				   enum ieee80211_frame_release_type reason,
+				   bool more_data)
+{
+	struct ath_softc *sc = hw->priv;
+	struct ath_node *an = (struct ath_node *)sta->drv_priv;
+	struct ath_txq *txq = sc->tx.uapsdq;
+	struct ieee80211_tx_info *info;
+	struct list_head bf_q;
+	struct ath_buf *bf_tail = NULL, *bf;
+	int sent = 0;
+	int i;
+
+	INIT_LIST_HEAD(&bf_q);
+	for (i = 0; tids && nframes; i++, tids >>= 1) {
+		struct ath_atx_tid *tid;
+
+		if (!(tids & 1))
+			continue;
+
+		tid = ATH_AN_2_TID(an, i);
+		if (tid->paused)
+			continue;
+
+		ath_txq_lock(sc, tid->ac->txq);
+		while (!skb_queue_empty(&tid->buf_q) && nframes > 0) {
+			bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid);
+			if (!bf)
+				break;
+
+			__skb_unlink(bf->bf_mpdu, &tid->buf_q);
+			list_add_tail(&bf->list, &bf_q);
+			ath_set_rates(tid->an->vif, tid->an->sta, bf);
+			ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
+			bf->bf_state.bf_type &= ~BUF_AGGR;
+			if (bf_tail)
+				bf_tail->bf_next = bf;
+
+			bf_tail = bf;
+			nframes--;
+			sent++;
+			TX_STAT_INC(txq->axq_qnum, a_queued_hw);
+
+			if (skb_queue_empty(&tid->buf_q))
+				ieee80211_sta_set_buffered(an->sta, i, false);
+		}
+		ath_txq_unlock_complete(sc, tid->ac->txq);
+	}
+
+	if (list_empty(&bf_q))
+		return;
+
+	info = IEEE80211_SKB_CB(bf_tail->bf_mpdu);
+	info->flags |= IEEE80211_TX_STATUS_EOSP;
+
+	bf = list_first_entry(&bf_q, struct ath_buf, list);
+	ath_txq_lock(sc, txq);
+	ath_tx_fill_desc(sc, bf, txq, 0);
+	ath_tx_txqaddbuf(sc, txq, &bf_q, false);
+	ath_txq_unlock(sc, txq);
+}
+
 /********************/
 /* Queue Management */
 /********************/
@@ -1679,14 +1806,19 @@ static void ath_tx_txqaddbuf(struct ath_
 	}
 
 	if (!internal) {
-		txq->axq_depth++;
-		if (bf_is_ampdu_not_probing(bf))
-			txq->axq_ampdu_depth++;
+		while (bf) {
+			txq->axq_depth++;
+			if (bf_is_ampdu_not_probing(bf))
+				txq->axq_ampdu_depth++;
+
+			bf = bf->bf_lastbf->bf_next;
+		}
 	}
 }
 
-static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
-			      struct sk_buff *skb, struct ath_tx_control *txctl)
+static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_txq *txq,
+			      struct ath_atx_tid *tid, struct sk_buff *skb,
+			      struct ath_tx_control *txctl)
 {
 	struct ath_frame_info *fi = get_frame_info(skb);
 	struct list_head bf_head;
@@ -1699,22 +1831,24 @@ static void ath_tx_send_ampdu(struct ath
 	 * - seqno is not within block-ack window
 	 * - h/w queue depth exceeds low water mark
 	 */
-	if (!skb_queue_empty(&tid->buf_q) || tid->paused ||
-	    !BAW_WITHIN(tid->seq_start, tid->baw_size, tid->seq_next) ||
-	    txctl->txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) {
+	if ((!skb_queue_empty(&tid->buf_q) || tid->paused ||
+	     !BAW_WITHIN(tid->seq_start, tid->baw_size, tid->seq_next) ||
+	     txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) &&
+	    txq != sc->tx.uapsdq) {
 		/*
 		 * Add this frame to software queue for scheduling later
 		 * for aggregation.
 		 */
-		TX_STAT_INC(txctl->txq->axq_qnum, a_queued_sw);
+		TX_STAT_INC(txq->axq_qnum, a_queued_sw);
 		__skb_queue_tail(&tid->buf_q, skb);
 		if (!txctl->an || !txctl->an->sleeping)
-			ath_tx_queue_tid(txctl->txq, tid);
+			ath_tx_queue_tid(txq, tid);
 		return;
 	}
 
-	bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+	bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 	if (!bf) {
+		ath_txq_skb_done(sc, txq, skb);
 		ieee80211_free_txskb(sc->hw, skb);
 		return;
 	}
@@ -1728,10 +1862,10 @@ static void ath_tx_send_ampdu(struct ath
 	ath_tx_addto_baw(sc, tid, bf->bf_state.seqno);
 
 	/* Queue to h/w without aggregation */
-	TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
+	TX_STAT_INC(txq->axq_qnum, a_queued_hw);
 	bf->bf_lastbf = bf;
-	ath_tx_fill_desc(sc, bf, txctl->txq, fi->framelen);
-	ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false);
+	ath_tx_fill_desc(sc, bf, txq, fi->framelen);
+	ath_tx_txqaddbuf(sc, txq, &bf_head, false);
 }
 
 static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
@@ -1869,22 +2003,16 @@ static struct ath_buf *ath_tx_setup_buff
 	return bf;
 }
 
-/* Upon failure caller should free skb */
-int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
-		 struct ath_tx_control *txctl)
+static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,
+			  struct ath_tx_control *txctl)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_sta *sta = txctl->sta;
 	struct ieee80211_vif *vif = info->control.vif;
 	struct ath_softc *sc = hw->priv;
-	struct ath_txq *txq = txctl->txq;
-	struct ath_atx_tid *tid = NULL;
-	struct ath_buf *bf;
-	int padpos, padsize;
 	int frmlen = skb->len + FCS_LEN;
-	u8 tidno;
-	int q;
+	int padpos, padsize;
 
 	/* NOTE:  sta can be NULL according to net/mac80211.h */
 	if (sta)
@@ -1905,6 +2033,11 @@ int ath_tx_start(struct ieee80211_hw *hw
 		hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
 	}
 
+	if ((vif && vif->type != NL80211_IFTYPE_AP &&
+	            vif->type != NL80211_IFTYPE_AP_VLAN) ||
+	    !ieee80211_is_data(hdr->frame_control))
+		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+
 	/* Add the padding after the header if this is not already done */
 	padpos = ieee80211_hdrlen(hdr->frame_control);
 	padsize = padpos & 3;
@@ -1914,16 +2047,34 @@ int ath_tx_start(struct ieee80211_hw *hw
 
 		skb_push(skb, padsize);
 		memmove(skb->data, skb->data + padsize, padpos);
-		hdr = (struct ieee80211_hdr *) skb->data;
 	}
 
-	if ((vif && vif->type != NL80211_IFTYPE_AP &&
-	            vif->type != NL80211_IFTYPE_AP_VLAN) ||
-	    !ieee80211_is_data(hdr->frame_control))
-		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
-
 	setup_frame_info(hw, sta, skb, frmlen);
+	return 0;
+}
+
 
+/* Upon failure caller should free skb */
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+		 struct ath_tx_control *txctl)
+{
+	struct ieee80211_hdr *hdr;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_sta *sta = txctl->sta;
+	struct ieee80211_vif *vif = info->control.vif;
+	struct ath_softc *sc = hw->priv;
+	struct ath_txq *txq = txctl->txq;
+	struct ath_atx_tid *tid = NULL;
+	struct ath_buf *bf;
+	u8 tidno;
+	int q;
+	int ret;
+
+	ret = ath_tx_prepare(hw, skb, txctl);
+	if (ret)
+	    return ret;
+
+	hdr = (struct ieee80211_hdr *) skb->data;
 	/*
 	 * At this point, the vif, hw_key and sta pointers in the tx control
 	 * info are no longer valid (overwritten by the ath_frame_info data.
@@ -1939,6 +2090,12 @@ int ath_tx_start(struct ieee80211_hw *hw
 		txq->stopped = true;
 	}
 
+	if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) {
+		ath_txq_unlock(sc, txq);
+		txq = sc->tx.uapsdq;
+		ath_txq_lock(sc, txq);
+	}
+
 	if (txctl->an && ieee80211_is_data_qos(hdr->frame_control)) {
 		tidno = ieee80211_get_qos_ctl(hdr)[0] &
 			IEEE80211_QOS_CTL_TID_MASK;
@@ -1952,12 +2109,13 @@ int ath_tx_start(struct ieee80211_hw *hw
 		 * Try aggregation if it's a unicast data frame
 		 * and the destination is HT capable.
 		 */
-		ath_tx_send_ampdu(sc, tid, skb, txctl);
+		ath_tx_send_ampdu(sc, txq, tid, skb, txctl);
 		goto out;
 	}
 
-	bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
+	bf = ath_tx_setup_buffer(sc, txq, tid, skb);
 	if (!bf) {
+		ath_txq_skb_done(sc, txq, skb);
 		if (txctl->paprd)
 			dev_kfree_skb_any(skb);
 		else
@@ -1971,7 +2129,7 @@ int ath_tx_start(struct ieee80211_hw *hw
 		bf->bf_state.bfs_paprd_timestamp = jiffies;
 
 	ath_set_rates(vif, sta, bf);
-	ath_tx_send_normal(sc, txctl->txq, tid, skb);
+	ath_tx_send_normal(sc, txq, tid, skb);
 
 out:
 	ath_txq_unlock(sc, txq);
@@ -1979,6 +2137,74 @@ out:
 	return 0;
 }
 
+void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		 struct sk_buff *skb)
+{
+	struct ath_softc *sc = hw->priv;
+	struct ath_tx_control txctl = {
+		.txq = sc->beacon.cabq
+	};
+	struct ath_tx_info info = {};
+	struct ieee80211_hdr *hdr;
+	struct ath_buf *bf_tail = NULL;
+	struct ath_buf *bf;
+	LIST_HEAD(bf_q);
+	int duration = 0;
+	int max_duration;
+
+	max_duration =
+		sc->cur_beacon_conf.beacon_interval * 1000 *
+		sc->cur_beacon_conf.dtim_period / ATH_BCBUF;
+
+	do {
+		struct ath_frame_info *fi = get_frame_info(skb);
+
+		if (ath_tx_prepare(hw, skb, &txctl))
+			break;
+
+		bf = ath_tx_setup_buffer(sc, txctl.txq, NULL, skb);
+		if (!bf)
+			break;
+
+		bf->bf_lastbf = bf;
+		ath_set_rates(vif, NULL, bf);
+		ath_buf_set_rate(sc, bf, &info, fi->framelen);
+		duration += info.rates[0].PktDuration;
+		if (bf_tail)
+			bf_tail->bf_next = bf;
+
+		list_add_tail(&bf->list, &bf_q);
+		bf_tail = bf;
+		skb = NULL;
+
+		if (duration > max_duration)
+			break;
+
+		skb = ieee80211_get_buffered_bc(hw, vif);
+	} while(skb);
+
+	if (skb)
+		ieee80211_free_txskb(hw, skb);
+
+	if (list_empty(&bf_q))
+		return;
+
+	bf = list_first_entry(&bf_q, struct ath_buf, list);
+	hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
+
+	if (hdr->frame_control & IEEE80211_FCTL_MOREDATA) {
+		hdr->frame_control &= ~IEEE80211_FCTL_MOREDATA;
+		dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
+			sizeof(*hdr), DMA_TO_DEVICE);
+	}
+
+	ath_txq_lock(sc, txctl.txq);
+	ath_tx_fill_desc(sc, bf, txctl.txq, 0);
+	ath_tx_txqaddbuf(sc, txctl.txq, &bf_q, false);
+	TX_STAT_INC(txctl.txq->axq_qnum, queued);
+	ath_txq_unlock(sc, txctl.txq);
+}
+
 /*****************/
 /* TX Completion */
 /*****************/
@@ -1989,7 +2215,7 @@ static void ath_tx_complete(struct ath_s
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
-	int q, padpos, padsize;
+	int padpos, padsize;
 	unsigned long flags;
 
 	ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
@@ -2024,19 +2250,8 @@ static void ath_tx_complete(struct ath_s
 	}
 	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
 
-	q = skb_get_queue_mapping(skb);
-	if (txq == sc->tx.txq_map[q]) {
-		if (WARN_ON(--txq->pending_frames < 0))
-			txq->pending_frames = 0;
-
-		if (txq->stopped &&
-		    txq->pending_frames < sc->tx.txq_max_pending[q]) {
-			ieee80211_wake_queue(sc->hw, q);
-			txq->stopped = false;
-		}
-	}
-
 	__skb_queue_tail(&txq->complete_q, skb);
+	ath_txq_skb_done(sc, txq, skb);
 }
 
 static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/ath.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/ath.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/ath.h	2013-08-25 20:43:22.000000000 -0400
@@ -239,13 +239,12 @@ enum ATH_DEBUG {
 	ATH_DBG_CONFIG		= 0x00000200,
 	ATH_DBG_FATAL		= 0x00000400,
 	ATH_DBG_PS		= 0x00000800,
-	ATH_DBG_HWTIMER		= 0x00001000,
-	ATH_DBG_BTCOEX		= 0x00002000,
-	ATH_DBG_WMI		= 0x00004000,
-	ATH_DBG_BSTUCK		= 0x00008000,
-	ATH_DBG_MCI		= 0x00010000,
-	ATH_DBG_DFS		= 0x00020000,
-	ATH_DBG_WOW		= 0x00040000,
+	ATH_DBG_BTCOEX		= 0x00001000,
+	ATH_DBG_WMI		= 0x00002000,
+	ATH_DBG_BSTUCK		= 0x00004000,
+	ATH_DBG_MCI		= 0x00008000,
+	ATH_DBG_DFS		= 0x00010000,
+	ATH_DBG_WOW		= 0x00020000,
 	ATH_DBG_ANY		= 0xffffffff
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/carl9170/carl9170.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/carl9170/carl9170.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/carl9170/carl9170.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/carl9170/carl9170.h	2013-08-25 20:43:22.000000000 -0400
@@ -133,6 +133,9 @@ struct carl9170_sta_tid {
 
 	/* Preaggregation reorder queue */
 	struct sk_buff_head queue;
+
+	struct ieee80211_sta *sta;
+	struct ieee80211_vif *vif;
 };
 
 #define CARL9170_QUEUE_TIMEOUT		256
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/carl9170/main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/carl9170/main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/carl9170/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/carl9170/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1448,6 +1448,8 @@ static int carl9170_op_ampdu_action(stru
 		tid_info->state = CARL9170_TID_STATE_PROGRESS;
 		tid_info->tid = tid;
 		tid_info->max = sta_info->ampdu_max_len;
+		tid_info->sta = sta;
+		tid_info->vif = vif;
 
 		INIT_LIST_HEAD(&tid_info->list);
 		INIT_LIST_HEAD(&tid_info->tmp_list);
@@ -1857,6 +1859,7 @@ void *carl9170_alloc(size_t priv_size)
 		     IEEE80211_HW_SUPPORTS_PS |
 		     IEEE80211_HW_PS_NULLFUNC_STACK |
 		     IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC |
+		     IEEE80211_HW_SUPPORTS_RC_TABLE |
 		     IEEE80211_HW_SIGNAL_DBM;
 
 	if (!modparam_noht) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/carl9170/tx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/carl9170/tx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/carl9170/tx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/carl9170/tx.c	2013-08-25 20:43:22.000000000 -0400
@@ -625,7 +625,7 @@ static void carl9170_tx_ampdu_timeout(st
 		    msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
 			goto unlock;
 
-		sta = __carl9170_get_tx_sta(ar, skb);
+		sta = iter->sta;
 		if (WARN_ON(!sta))
 			goto unlock;
 
@@ -866,6 +866,93 @@ static bool carl9170_tx_cts_check(struct
 	return false;
 }
 
+static void carl9170_tx_get_rates(struct ar9170 *ar,
+				  struct ieee80211_vif *vif,
+				  struct ieee80211_sta *sta,
+				  struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info;
+
+	BUILD_BUG_ON(IEEE80211_TX_MAX_RATES < CARL9170_TX_MAX_RATES);
+	BUILD_BUG_ON(IEEE80211_TX_MAX_RATES > IEEE80211_TX_RATE_TABLE_SIZE);
+
+	info = IEEE80211_SKB_CB(skb);
+
+	ieee80211_get_tx_rates(vif, sta, skb,
+			       info->control.rates,
+			       IEEE80211_TX_MAX_RATES);
+}
+
+static void carl9170_tx_apply_rateset(struct ar9170 *ar,
+				      struct ieee80211_tx_info *sinfo,
+				      struct sk_buff *skb)
+{
+	struct ieee80211_tx_rate *txrate;
+	struct ieee80211_tx_info *info;
+	struct _carl9170_tx_superframe *txc = (void *) skb->data;
+	int i;
+	bool ampdu;
+	bool no_ack;
+
+	info = IEEE80211_SKB_CB(skb);
+	ampdu = !!(info->flags & IEEE80211_TX_CTL_AMPDU);
+	no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK);
+
+	/* Set the rate control probe flag for all (sub-) frames.
+	 * This is because the TX_STATS_AMPDU flag is only set on
+	 * the last frame, so it has to be inherited.
+	 */
+	info->flags |= (sinfo->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
+
+	/* NOTE: For the first rate, the ERP & AMPDU flags are directly
+	 * taken from mac_control. For all fallback rate, the firmware
+	 * updates the mac_control flags from the rate info field.
+	 */
+	for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
+		__le32 phy_set;
+
+		txrate = &sinfo->control.rates[i];
+		if (txrate->idx < 0)
+			break;
+
+		phy_set = carl9170_tx_physet(ar, info, txrate);
+		if (i == 0) {
+			__le16 mac_tmp = cpu_to_le16(0);
+
+			/* first rate - part of the hw's frame header */
+			txc->f.phy_control = phy_set;
+
+			if (ampdu && txrate->flags & IEEE80211_TX_RC_MCS)
+				mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+
+			if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
+				mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
+			else if (carl9170_tx_cts_check(ar, txrate))
+				mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
+
+			txc->f.mac_control |= mac_tmp;
+		} else {
+			/* fallback rates are stored in the firmware's
+			 * retry rate set array.
+			 */
+			txc->s.rr[i - 1] = phy_set;
+		}
+
+		SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i],
+			txrate->count);
+
+		if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
+			txc->s.ri[i] |= (AR9170_TX_MAC_PROT_RTS <<
+				CARL9170_TX_SUPER_RI_ERP_PROT_S);
+		else if (carl9170_tx_cts_check(ar, txrate))
+			txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS <<
+				CARL9170_TX_SUPER_RI_ERP_PROT_S);
+
+		if (ampdu && (txrate->flags & IEEE80211_TX_RC_MCS))
+			txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU;
+	}
+}
+
 static int carl9170_tx_prepare(struct ar9170 *ar,
 			       struct ieee80211_sta *sta,
 			       struct sk_buff *skb)
@@ -874,13 +961,10 @@ static int carl9170_tx_prepare(struct ar
 	struct _carl9170_tx_superframe *txc;
 	struct carl9170_vif_info *cvif;
 	struct ieee80211_tx_info *info;
-	struct ieee80211_tx_rate *txrate;
 	struct carl9170_tx_info *arinfo;
 	unsigned int hw_queue;
-	int i;
 	__le16 mac_tmp;
 	u16 len;
-	bool ampdu, no_ack;
 
 	BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
 	BUILD_BUG_ON(sizeof(struct _carl9170_tx_superdesc) !=
@@ -889,8 +973,6 @@ static int carl9170_tx_prepare(struct ar
 	BUILD_BUG_ON(sizeof(struct _ar9170_tx_hwdesc) !=
 		     AR9170_TX_HWDESC_LEN);
 
-	BUILD_BUG_ON(IEEE80211_TX_MAX_RATES < CARL9170_TX_MAX_RATES);
-
 	BUILD_BUG_ON(AR9170_MAX_VIRTUAL_MAC >
 		((CARL9170_TX_SUPER_MISC_VIF_ID >>
 		 CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1));
@@ -932,8 +1014,7 @@ static int carl9170_tx_prepare(struct ar
 	mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &
 			       AR9170_TX_MAC_QOS);
 
-	no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK);
-	if (unlikely(no_ack))
+	if (unlikely(info->flags & IEEE80211_TX_CTL_NO_ACK))
 		mac_tmp |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
 
 	if (info->control.hw_key) {
@@ -954,8 +1035,7 @@ static int carl9170_tx_prepare(struct ar
 		}
 	}
 
-	ampdu = !!(info->flags & IEEE80211_TX_CTL_AMPDU);
-	if (ampdu) {
+	if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 		unsigned int density, factor;
 
 		if (unlikely(!sta || !cvif))
@@ -982,50 +1062,6 @@ static int carl9170_tx_prepare(struct ar
 			txc->s.ampdu_settings, factor);
 	}
 
-	/*
-	 * NOTE: For the first rate, the ERP & AMPDU flags are directly
-	 * taken from mac_control. For all fallback rate, the firmware
-	 * updates the mac_control flags from the rate info field.
-	 */
-	for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
-		__le32 phy_set;
-		txrate = &info->control.rates[i];
-		if (txrate->idx < 0)
-			break;
-
-		phy_set = carl9170_tx_physet(ar, info, txrate);
-		if (i == 0) {
-			/* first rate - part of the hw's frame header */
-			txc->f.phy_control = phy_set;
-
-			if (ampdu && txrate->flags & IEEE80211_TX_RC_MCS)
-				mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR);
-			if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
-				mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
-			else if (carl9170_tx_cts_check(ar, txrate))
-				mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
-
-		} else {
-			/* fallback rates are stored in the firmware's
-			 * retry rate set array.
-			 */
-			txc->s.rr[i - 1] = phy_set;
-		}
-
-		SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i],
-			txrate->count);
-
-		if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack))
-			txc->s.ri[i] |= (AR9170_TX_MAC_PROT_RTS <<
-				CARL9170_TX_SUPER_RI_ERP_PROT_S);
-		else if (carl9170_tx_cts_check(ar, txrate))
-			txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS <<
-				CARL9170_TX_SUPER_RI_ERP_PROT_S);
-
-		if (ampdu && (txrate->flags & IEEE80211_TX_RC_MCS))
-			txc->s.ri[i] |= CARL9170_TX_SUPER_RI_AMPDU;
-	}
-
 	txc->s.len = cpu_to_le16(skb->len);
 	txc->f.length = cpu_to_le16(len + FCS_LEN);
 	txc->f.mac_control = mac_tmp;
@@ -1086,31 +1122,12 @@ static void carl9170_set_ampdu_params(st
 	}
 }
 
-static bool carl9170_tx_rate_check(struct ar9170 *ar, struct sk_buff *_dest,
-				   struct sk_buff *_src)
-{
-	struct _carl9170_tx_superframe *dest, *src;
-
-	dest = (void *) _dest->data;
-	src = (void *) _src->data;
-
-	/*
-	 * The mac80211 rate control algorithm expects that all MPDUs in
-	 * an AMPDU share the same tx vectors.
-	 * This is not really obvious right now, because the hardware
-	 * does the AMPDU setup according to its own rulebook.
-	 * Our nicely assembled, strictly monotonic increasing mpdu
-	 * chains will be broken up, mashed back together...
-	 */
-
-	return (dest->f.phy_control == src->f.phy_control);
-}
-
 static void carl9170_tx_ampdu(struct ar9170 *ar)
 {
 	struct sk_buff_head agg;
 	struct carl9170_sta_tid *tid_info;
 	struct sk_buff *skb, *first;
+	struct ieee80211_tx_info *tx_info_first;
 	unsigned int i = 0, done_ampdus = 0;
 	u16 seq, queue, tmpssn;
 
@@ -1156,6 +1173,7 @@ retry:
 			goto processed;
 		}
 
+		tx_info_first = NULL;
 		while ((skb = skb_peek(&tid_info->queue))) {
 			/* strict 0, 1, ..., n - 1, n frame sequence order */
 			if (unlikely(carl9170_get_seq(skb) != seq))
@@ -1166,8 +1184,13 @@ retry:
 			    (tid_info->max - 1)))
 				break;
 
-			if (!carl9170_tx_rate_check(ar, skb, first))
-				break;
+			if (!tx_info_first) {
+				carl9170_tx_get_rates(ar, tid_info->vif,
+						      tid_info->sta, first);
+				tx_info_first = IEEE80211_SKB_CB(first);
+			}
+
+			carl9170_tx_apply_rateset(ar, tx_info_first, skb);
 
 			atomic_inc(&ar->tx_ampdu_upload);
 			tid_info->snx = seq = SEQ_NEXT(seq);
@@ -1182,8 +1205,7 @@ retry:
 		if (skb_queue_empty(&tid_info->queue) ||
 		    carl9170_get_seq(skb_peek(&tid_info->queue)) !=
 		    tid_info->snx) {
-			/*
-			 * stop TID, if A-MPDU frames are still missing,
+			/* stop TID, if A-MPDU frames are still missing,
 			 * or whenever the queue is empty.
 			 */
 
@@ -1450,12 +1472,14 @@ void carl9170_op_tx(struct ieee80211_hw
 	struct ar9170 *ar = hw->priv;
 	struct ieee80211_tx_info *info;
 	struct ieee80211_sta *sta = control->sta;
+	struct ieee80211_vif *vif;
 	bool run;
 
 	if (unlikely(!IS_STARTED(ar)))
 		goto err_free;
 
 	info = IEEE80211_SKB_CB(skb);
+	vif = info->control.vif;
 
 	if (unlikely(carl9170_tx_prepare(ar, sta, skb)))
 		goto err_free;
@@ -1486,6 +1510,8 @@ void carl9170_op_tx(struct ieee80211_hw
 	} else {
 		unsigned int queue = skb_get_queue_mapping(skb);
 
+		carl9170_tx_get_rates(ar, vif, sta, skb);
+		carl9170_tx_apply_rateset(ar, info, skb);
 		skb_queue_tail(&ar->tx_pending[queue], skb);
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -31,5 +31,6 @@ source "drivers/net/wireless/ath/carl917
 source "drivers/net/wireless/ath/ath6kl/Kconfig"
 source "drivers/net/wireless/ath/ar5523/Kconfig"
 source "drivers/net/wireless/ath/wil6210/Kconfig"
+source "drivers/net/wireless/ath/ath10k/Kconfig"
 
 endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -4,6 +4,7 @@ obj-$(CONFIG_CARL9170)		+= carl9170/
 obj-$(CONFIG_ATH6KL)		+= ath6kl/
 obj-$(CONFIG_AR5523)		+= ar5523/
 obj-$(CONFIG_WIL6210)		+= wil6210/
+obj-$(CONFIG_ATH10K)		+= ath10k/
 
 obj-$(CONFIG_ATH_COMMON)	+= ath.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/regd.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/regd.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/regd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/regd.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,11 +42,11 @@ static int __ath_regd_init(struct ath_re
 				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
 
 /* We allow IBSS on these on a case by case basis by regulatory domain */
-#define ATH9K_5GHZ_5150_5350	REG_RULE(5150-10, 5350+10, 40, 0, 30,\
+#define ATH9K_5GHZ_5150_5350	REG_RULE(5150-10, 5350+10, 80, 0, 30,\
 				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
-#define ATH9K_5GHZ_5470_5850	REG_RULE(5470-10, 5850+10, 40, 0, 30,\
+#define ATH9K_5GHZ_5470_5850	REG_RULE(5470-10, 5850+10, 80, 0, 30,\
 				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
-#define ATH9K_5GHZ_5725_5850	REG_RULE(5725-10, 5850+10, 40, 0, 30,\
+#define ATH9K_5GHZ_5725_5850	REG_RULE(5725-10, 5850+10, 80, 0, 30,\
 				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
 
 #define ATH9K_2GHZ_ALL		ATH9K_2GHZ_CH01_11, \
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/cfg80211.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/cfg80211.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/cfg80211.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/cfg80211.c	2013-08-25 20:43:22.000000000 -0400
@@ -322,12 +322,16 @@ static int wil_cfg80211_connect(struct w
 	 * FW don't support scan after connection attempt
 	 */
 	set_bit(wil_status_dontscan, &wil->status);
+	set_bit(wil_status_fwconnecting, &wil->status);
 
 	rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
 	if (rc == 0) {
 		/* Connect can take lots of time */
 		mod_timer(&wil->connect_timer,
 			  jiffies + msecs_to_jiffies(2000));
+	} else {
+		clear_bit(wil_status_dontscan, &wil->status);
+		clear_bit(wil_status_fwconnecting, &wil->status);
 	}
 
  out:
@@ -398,6 +402,30 @@ static int wil_cfg80211_set_default_key(
 	return 0;
 }
 
+static int wil_fix_bcon(struct wil6210_priv *wil,
+			struct cfg80211_beacon_data *bcon)
+{
+	struct ieee80211_mgmt *f = (struct ieee80211_mgmt *)bcon->probe_resp;
+	size_t hlen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
+	int rc = 0;
+
+	if (bcon->probe_resp_len <= hlen)
+		return 0;
+
+	if (!bcon->proberesp_ies) {
+		bcon->proberesp_ies = f->u.probe_resp.variable;
+		bcon->proberesp_ies_len = bcon->probe_resp_len - hlen;
+		rc = 1;
+	}
+	if (!bcon->assocresp_ies) {
+		bcon->assocresp_ies = f->u.probe_resp.variable;
+		bcon->assocresp_ies_len = bcon->probe_resp_len - hlen;
+		rc = 1;
+	}
+
+	return rc;
+}
+
 static int wil_cfg80211_start_ap(struct wiphy *wiphy,
 				 struct net_device *ndev,
 				 struct cfg80211_ap_settings *info)
@@ -419,10 +447,18 @@ static int wil_cfg80211_start_ap(struct
 	print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
 			     info->ssid, info->ssid_len);
 
+	if (wil_fix_bcon(wil, bcon))
+		wil_dbg_misc(wil, "Fixed bcon\n");
+
 	rc = wil_reset(wil);
 	if (rc)
 		return rc;
 
+	/* Rx VRING. */
+	rc = wil_rx_init(wil);
+	if (rc)
+		return rc;
+
 	rc = wmi_set_ssid(wil, info->ssid_len, info->ssid);
 	if (rc)
 		return rc;
@@ -451,8 +487,6 @@ static int wil_cfg80211_start_ap(struct
 	if (rc)
 		return rc;
 
-	/* Rx VRING. After MAC and beacon */
-	rc = wil_rx_init(wil);
 
 	netif_carrier_on(ndev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/debug.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/debug.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/debug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "wil6210.h"
+#include "trace.h"
+
+int wil_err(struct wil6210_priv *wil, const char *fmt, ...)
+{
+	struct net_device *ndev = wil_to_ndev(wil);
+	struct va_format vaf = {
+		.fmt = fmt,
+	};
+	va_list args;
+	int ret;
+
+	va_start(args, fmt);
+	vaf.va = &args;
+	ret = netdev_err(ndev, "%pV", &vaf);
+	trace_wil6210_log_err(&vaf);
+	va_end(args);
+
+	return ret;
+}
+
+int wil_info(struct wil6210_priv *wil, const char *fmt, ...)
+{
+	struct net_device *ndev = wil_to_ndev(wil);
+	struct va_format vaf = {
+		.fmt = fmt,
+	};
+	va_list args;
+	int ret;
+
+	va_start(args, fmt);
+	vaf.va = &args;
+	ret = netdev_info(ndev, "%pV", &vaf);
+	trace_wil6210_log_info(&vaf);
+	va_end(args);
+
+	return ret;
+}
+
+int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...)
+{
+	struct va_format vaf = {
+		.fmt = fmt,
+	};
+	va_list args;
+
+	va_start(args, fmt);
+	vaf.va = &args;
+	trace_wil6210_log_dbg(&vaf);
+	va_end(args);
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/debugfs.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/debugfs.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -145,7 +145,7 @@ static void wil_print_ring(struct seq_fi
 				   le16_to_cpu(hdr.type), hdr.flags);
 			if (len <= MAX_MBOXITEM_SIZE) {
 				int n = 0;
-				unsigned char printbuf[16 * 3 + 2];
+				char printbuf[16 * 3 + 2];
 				unsigned char databuf[MAX_MBOXITEM_SIZE];
 				void __iomem *src = wmi_buffer(wil, d.addr) +
 					sizeof(struct wil6210_mbox_hdr);
@@ -416,11 +416,17 @@ static int wil_txdesc_debugfs_show(struc
 		seq_printf(s, "  SKB = %p\n", skb);
 
 		if (skb) {
-			unsigned char printbuf[16 * 3 + 2];
+			char printbuf[16 * 3 + 2];
 			int i = 0;
-			int len = skb_headlen(skb);
+			int len = le16_to_cpu(d->dma.length);
 			void *p = skb->data;
 
+			if (len != skb_headlen(skb)) {
+				seq_printf(s, "!!! len: desc = %d skb = %d\n",
+					   len, skb_headlen(skb));
+				len = min_t(int, len, skb_headlen(skb));
+			}
+
 			seq_printf(s, "    len = %d\n", len);
 
 			while (i < len) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/interrupt.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/interrupt.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/interrupt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/interrupt.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 
 #include "wil6210.h"
+#include "trace.h"
 
 /**
  * Theory of operation:
@@ -103,14 +104,14 @@ static void wil6210_mask_irq_pseudo(stru
 	clear_bit(wil_status_irqen, &wil->status);
 }
 
-static void wil6210_unmask_irq_tx(struct wil6210_priv *wil)
+void wil6210_unmask_irq_tx(struct wil6210_priv *wil)
 {
 	iowrite32(WIL6210_IMC_TX, wil->csr +
 		  HOSTADDR(RGF_DMA_EP_TX_ICR) +
 		  offsetof(struct RGF_ICR, IMC));
 }
 
-static void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
+void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
 {
 	iowrite32(WIL6210_IMC_RX, wil->csr +
 		  HOSTADDR(RGF_DMA_EP_RX_ICR) +
@@ -168,6 +169,7 @@ static irqreturn_t wil6210_irq_rx(int ir
 					 HOSTADDR(RGF_DMA_EP_RX_ICR) +
 					 offsetof(struct RGF_ICR, ICR));
 
+	trace_wil6210_irq_rx(isr);
 	wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr);
 
 	if (!isr) {
@@ -180,13 +182,14 @@ static irqreturn_t wil6210_irq_rx(int ir
 	if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) {
 		wil_dbg_irq(wil, "RX done\n");
 		isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE;
-		wil_rx_handle(wil);
+		wil_dbg_txrx(wil, "NAPI schedule\n");
+		napi_schedule(&wil->napi_rx);
 	}
 
 	if (isr)
 		wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr);
 
-	wil6210_unmask_irq_rx(wil);
+	/* Rx IRQ will be enabled when NAPI processing finished */
 
 	return IRQ_HANDLED;
 }
@@ -198,6 +201,7 @@ static irqreturn_t wil6210_irq_tx(int ir
 					 HOSTADDR(RGF_DMA_EP_TX_ICR) +
 					 offsetof(struct RGF_ICR, ICR));
 
+	trace_wil6210_irq_tx(isr);
 	wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr);
 
 	if (!isr) {
@@ -208,23 +212,17 @@ static irqreturn_t wil6210_irq_tx(int ir
 	wil6210_mask_irq_tx(wil);
 
 	if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) {
-		uint i;
 		wil_dbg_irq(wil, "TX done\n");
+		napi_schedule(&wil->napi_tx);
 		isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
-		for (i = 0; i < 24; i++) {
-			u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i);
-			if (isr & mask) {
-				isr &= ~mask;
-				wil_dbg_irq(wil, "TX done(%i)\n", i);
-				wil_tx_complete(wil, i);
-			}
-		}
+		/* clear also all VRING interrupts */
+		isr &= ~(BIT(25) - 1UL);
 	}
 
 	if (isr)
 		wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr);
 
-	wil6210_unmask_irq_tx(wil);
+	/* Tx IRQ will be enabled when NAPI processing finished */
 
 	return IRQ_HANDLED;
 }
@@ -256,6 +254,7 @@ static irqreturn_t wil6210_irq_misc(int
 					 HOSTADDR(RGF_DMA_EP_MISC_ICR) +
 					 offsetof(struct RGF_ICR, ICR));
 
+	trace_wil6210_irq_misc(isr);
 	wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr);
 
 	if (!isr) {
@@ -301,6 +300,7 @@ static irqreturn_t wil6210_irq_misc_thre
 	struct wil6210_priv *wil = cookie;
 	u32 isr = wil->isr_misc;
 
+	trace_wil6210_irq_misc_thread(isr);
 	wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr);
 
 	if (isr & ISR_MISC_FW_ERROR) {
@@ -408,6 +408,7 @@ static irqreturn_t wil6210_hardirq(int i
 	if (wil6210_debug_irq_mask(wil, pseudo_cause))
 		return IRQ_NONE;
 
+	trace_wil6210_irq_pseudo(pseudo_cause);
 	wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause);
 
 	wil6210_mask_irq_pseudo(wil);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -27,3 +27,15 @@ config WIL6210_ISR_COR
 	  self-clear when accessed for debug purposes, it makes
 	  such monitoring impossible.
 	  Say y unless you debug interrupts
+
+config WIL6210_TRACING
+	bool "wil6210 tracing support"
+	depends on WIL6210
+	depends on EVENT_TRACING
+	default y
+	---help---
+	  Say Y here to enable tracepoints for the wil6210 driver
+	  using the kernel tracing infrastructure.  Select this
+	  option if you are interested in debugging the driver.
+
+	  If unsure, say Y to make it easier to debug problems.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,27 +56,21 @@ static void _wil6210_disconnect(struct w
 {
 	uint i;
 	struct net_device *ndev = wil_to_ndev(wil);
-	struct wireless_dev *wdev = wil->wdev;
 
 	wil_dbg_misc(wil, "%s()\n", __func__);
 
 	wil_link_off(wil);
-	clear_bit(wil_status_fwconnected, &wil->status);
-
-	switch (wdev->sme_state) {
-	case CFG80211_SME_CONNECTED:
-		cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE,
+	if (test_bit(wil_status_fwconnected, &wil->status)) {
+		clear_bit(wil_status_fwconnected, &wil->status);
+		cfg80211_disconnected(ndev,
+				      WLAN_STATUS_UNSPECIFIED_FAILURE,
 				      NULL, 0, GFP_KERNEL);
-		break;
-	case CFG80211_SME_CONNECTING:
+	} else if (test_bit(wil_status_fwconnecting, &wil->status)) {
 		cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
 					WLAN_STATUS_UNSPECIFIED_FAILURE,
 					GFP_KERNEL);
-		break;
-	default:
-		break;
 	}
-
+	clear_bit(wil_status_fwconnecting, &wil->status);
 	for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
 		wil_vring_fini_tx(wil, i);
 
@@ -292,41 +286,36 @@ static int __wil_up(struct wil6210_priv
 {
 	struct net_device *ndev = wil_to_ndev(wil);
 	struct wireless_dev *wdev = wil->wdev;
-	struct ieee80211_channel *channel = wdev->preset_chandef.chan;
 	int rc;
-	int bi;
-	u16 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
 
 	rc = wil_reset(wil);
 	if (rc)
 		return rc;
 
-	/* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */
-	wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
+	/* Rx VRING. After MAC and beacon */
+	rc = wil_rx_init(wil);
+	if (rc)
+		return rc;
+
 	switch (wdev->iftype) {
 	case NL80211_IFTYPE_STATION:
 		wil_dbg_misc(wil, "type: STATION\n");
-		bi = 0;
 		ndev->type = ARPHRD_ETHER;
 		break;
 	case NL80211_IFTYPE_AP:
 		wil_dbg_misc(wil, "type: AP\n");
-		bi = 100;
 		ndev->type = ARPHRD_ETHER;
 		break;
 	case NL80211_IFTYPE_P2P_CLIENT:
 		wil_dbg_misc(wil, "type: P2P_CLIENT\n");
-		bi = 0;
 		ndev->type = ARPHRD_ETHER;
 		break;
 	case NL80211_IFTYPE_P2P_GO:
 		wil_dbg_misc(wil, "type: P2P_GO\n");
-		bi = 100;
 		ndev->type = ARPHRD_ETHER;
 		break;
 	case NL80211_IFTYPE_MONITOR:
 		wil_dbg_misc(wil, "type: Monitor\n");
-		bi = 0;
 		ndev->type = ARPHRD_IEEE80211_RADIOTAP;
 		/* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
 		break;
@@ -334,36 +323,12 @@ static int __wil_up(struct wil6210_priv
 		return -EOPNOTSUPP;
 	}
 
-	/* Apply profile in the following order: */
-	/* SSID and channel for the AP */
-	switch (wdev->iftype) {
-	case NL80211_IFTYPE_AP:
-	case NL80211_IFTYPE_P2P_GO:
-		if (wdev->ssid_len == 0) {
-			wil_err(wil, "SSID not set\n");
-			return -EINVAL;
-		}
-		rc = wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
-		if (rc)
-			return rc;
-		break;
-	default:
-		break;
-	}
-
 	/* MAC address - pre-requisite for other commands */
 	wmi_set_mac_address(wil, ndev->dev_addr);
 
-	/* Set up beaconing if required. */
-	if (bi > 0) {
-		rc = wmi_pcp_start(wil, bi, wmi_nettype,
-				   (channel ? channel->hw_value : 0));
-		if (rc)
-			return rc;
-	}
 
-	/* Rx VRING. After MAC and beacon */
-	wil_rx_init(wil);
+	napi_enable(&wil->napi_rx);
+	napi_enable(&wil->napi_tx);
 
 	return 0;
 }
@@ -381,6 +346,9 @@ int wil_up(struct wil6210_priv *wil)
 
 static int __wil_down(struct wil6210_priv *wil)
 {
+	napi_disable(&wil->napi_rx);
+	napi_disable(&wil->napi_tx);
+
 	if (wil->scan_request) {
 		cfg80211_scan_done(wil->scan_request, true);
 		wil->scan_request = NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,15 +1,20 @@
 obj-$(CONFIG_WIL6210) += wil6210.o
 
-wil6210-objs := main.o
-wil6210-objs += netdev.o
-wil6210-objs += cfg80211.o
-wil6210-objs += pcie_bus.o
-wil6210-objs += debugfs.o
-wil6210-objs += wmi.o
-wil6210-objs += interrupt.o
-wil6210-objs += txrx.o
+wil6210-y := main.o
+wil6210-y += netdev.o
+wil6210-y += cfg80211.o
+wil6210-y += pcie_bus.o
+wil6210-y += debugfs.o
+wil6210-y += wmi.o
+wil6210-y += interrupt.o
+wil6210-y += txrx.o
+wil6210-y += debug.o
+wil6210-$(CONFIG_WIL6210_TRACING) += trace.o
 
 ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
 	subdir-ccflags-y += -Werror
 endif
+# for tracing framework to find trace.h
+CFLAGS_trace.o := -I$(src)
+
 subdir-ccflags-y += -D__CHECK_ENDIAN__
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/netdev.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/netdev.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/netdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/netdev.c	2013-08-25 20:43:22.000000000 -0400
@@ -40,6 +40,55 @@ static const struct net_device_ops wil_n
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
+static int wil6210_netdev_poll_rx(struct napi_struct *napi, int budget)
+{
+	struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
+						napi_rx);
+	int quota = budget;
+	int done;
+
+	wil_rx_handle(wil, &quota);
+	done = budget - quota;
+
+	if (done <= 1) { /* burst ends - only one packet processed */
+		napi_complete(napi);
+		wil6210_unmask_irq_rx(wil);
+		wil_dbg_txrx(wil, "NAPI RX complete\n");
+	}
+
+	wil_dbg_txrx(wil, "NAPI RX poll(%d) done %d\n", budget, done);
+
+	return done;
+}
+
+static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
+{
+	struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
+						napi_tx);
+	int tx_done = 0;
+	uint i;
+
+	/* always process ALL Tx complete, regardless budget - it is fast */
+	for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
+		struct vring *vring = &wil->vring_tx[i];
+
+		if (!vring->va)
+			continue;
+
+		tx_done += wil_tx_complete(wil, i);
+	}
+
+	if (tx_done <= 1) { /* burst ends - only one packet processed */
+		napi_complete(napi);
+		wil6210_unmask_irq_tx(wil);
+		wil_dbg_txrx(wil, "NAPI TX complete\n");
+	}
+
+	wil_dbg_txrx(wil, "NAPI TX poll(%d) done %d\n", budget, tx_done);
+
+	return min(tx_done, budget);
+}
+
 void *wil_if_alloc(struct device *dev, void __iomem *csr)
 {
 	struct net_device *ndev;
@@ -81,6 +130,11 @@ void *wil_if_alloc(struct device *dev, v
 	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
 	wdev->netdev = ndev;
 
+	netif_napi_add(ndev, &wil->napi_rx, wil6210_netdev_poll_rx,
+		       WIL6210_NAPI_BUDGET);
+	netif_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
+		       WIL6210_NAPI_BUDGET);
+
 	wil_link_off(wil);
 
 	return wil;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/trace.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/trace.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/trace.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/trace.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+
+#define CREATE_TRACE_POINTS
+#include "trace.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/trace.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/trace.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/trace.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/trace.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM wil6210
+#if !defined(WIL6210_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define WIL6210_TRACE_H
+
+#include <linux/tracepoint.h>
+#include "wil6210.h"
+#include "txrx.h"
+
+/* create empty functions when tracing is disabled */
+#if !defined(CONFIG_WIL6210_TRACING) || defined(__CHECKER__)
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, ...) \
+static inline void trace_ ## name(proto) {}
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(...)
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(evt_class, name, proto, ...) \
+static inline void trace_ ## name(proto) {}
+#endif /* !CONFIG_WIL6210_TRACING || defined(__CHECKER__) */
+
+DECLARE_EVENT_CLASS(wil6210_wmi,
+	TP_PROTO(u16 id, void *buf, u16 buf_len),
+
+	TP_ARGS(id, buf, buf_len),
+
+	TP_STRUCT__entry(
+		__field(u16, id)
+		__field(u16, buf_len)
+		__dynamic_array(u8, buf, buf_len)
+	),
+
+	TP_fast_assign(
+		__entry->id = id;
+		__entry->buf_len = buf_len;
+		memcpy(__get_dynamic_array(buf), buf, buf_len);
+	),
+
+	TP_printk(
+		"id 0x%04x len %d",
+		__entry->id, __entry->buf_len
+	)
+);
+
+DEFINE_EVENT(wil6210_wmi, wil6210_wmi_cmd,
+	TP_PROTO(u16 id, void *buf, u16 buf_len),
+	TP_ARGS(id, buf, buf_len)
+);
+
+DEFINE_EVENT(wil6210_wmi, wil6210_wmi_event,
+	TP_PROTO(u16 id, void *buf, u16 buf_len),
+	TP_ARGS(id, buf, buf_len)
+);
+
+#define WIL6210_MSG_MAX (200)
+
+DECLARE_EVENT_CLASS(wil6210_log_event,
+	TP_PROTO(struct va_format *vaf),
+	TP_ARGS(vaf),
+	TP_STRUCT__entry(
+		__dynamic_array(char, msg, WIL6210_MSG_MAX)
+	),
+	TP_fast_assign(
+		WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+				       WIL6210_MSG_MAX,
+				       vaf->fmt,
+				       *vaf->va) >= WIL6210_MSG_MAX);
+	),
+	TP_printk("%s", __get_str(msg))
+);
+
+DEFINE_EVENT(wil6210_log_event, wil6210_log_err,
+	TP_PROTO(struct va_format *vaf),
+	TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(wil6210_log_event, wil6210_log_info,
+	TP_PROTO(struct va_format *vaf),
+	TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(wil6210_log_event, wil6210_log_dbg,
+	TP_PROTO(struct va_format *vaf),
+	TP_ARGS(vaf)
+);
+
+#define wil_pseudo_irq_cause(x) __print_flags(x, "|",	\
+	{BIT_DMA_PSEUDO_CAUSE_RX,	"Rx" },		\
+	{BIT_DMA_PSEUDO_CAUSE_TX,	"Tx" },		\
+	{BIT_DMA_PSEUDO_CAUSE_MISC,	"Misc" })
+
+TRACE_EVENT(wil6210_irq_pseudo,
+	TP_PROTO(u32 x),
+	TP_ARGS(x),
+	TP_STRUCT__entry(
+		__field(u32, x)
+	),
+	TP_fast_assign(
+		__entry->x = x;
+	),
+	TP_printk("cause 0x%08x : %s", __entry->x,
+		  wil_pseudo_irq_cause(__entry->x))
+);
+
+DECLARE_EVENT_CLASS(wil6210_irq,
+	TP_PROTO(u32 x),
+	TP_ARGS(x),
+	TP_STRUCT__entry(
+		__field(u32, x)
+	),
+	TP_fast_assign(
+		__entry->x = x;
+	),
+	TP_printk("cause 0x%08x", __entry->x)
+);
+
+DEFINE_EVENT(wil6210_irq, wil6210_irq_rx,
+	TP_PROTO(u32 x),
+	TP_ARGS(x)
+);
+
+DEFINE_EVENT(wil6210_irq, wil6210_irq_tx,
+	TP_PROTO(u32 x),
+	TP_ARGS(x)
+);
+
+DEFINE_EVENT(wil6210_irq, wil6210_irq_misc,
+	TP_PROTO(u32 x),
+	TP_ARGS(x)
+);
+
+DEFINE_EVENT(wil6210_irq, wil6210_irq_misc_thread,
+	TP_PROTO(u32 x),
+	TP_ARGS(x)
+);
+
+TRACE_EVENT(wil6210_rx,
+	TP_PROTO(u16 index, struct vring_rx_desc *d),
+	TP_ARGS(index, d),
+	TP_STRUCT__entry(
+		__field(u16, index)
+		__field(unsigned int, len)
+		__field(u8, mid)
+		__field(u8, cid)
+		__field(u8, tid)
+		__field(u8, type)
+		__field(u8, subtype)
+		__field(u16, seq)
+		__field(u8, mcs)
+	),
+	TP_fast_assign(
+		__entry->index = index;
+		__entry->len = d->dma.length;
+		__entry->mid = wil_rxdesc_mid(d);
+		__entry->cid = wil_rxdesc_cid(d);
+		__entry->tid = wil_rxdesc_tid(d);
+		__entry->type = wil_rxdesc_ftype(d);
+		__entry->subtype = wil_rxdesc_subtype(d);
+		__entry->seq = wil_rxdesc_seq(d);
+		__entry->mcs = wil_rxdesc_mcs(d);
+	),
+	TP_printk("index %d len %d mid %d cid %d tid %d mcs %d seq 0x%03x"
+		  " type 0x%1x subtype 0x%1x", __entry->index, __entry->len,
+		  __entry->mid, __entry->cid, __entry->tid, __entry->mcs,
+		  __entry->seq, __entry->type, __entry->subtype)
+);
+
+TRACE_EVENT(wil6210_tx,
+	TP_PROTO(u8 vring, u16 index, unsigned int len, u8 frags),
+	TP_ARGS(vring, index, len, frags),
+	TP_STRUCT__entry(
+		__field(u8, vring)
+		__field(u8, frags)
+		__field(u16, index)
+		__field(unsigned int, len)
+	),
+	TP_fast_assign(
+		__entry->vring = vring;
+		__entry->frags = frags;
+		__entry->index = index;
+		__entry->len = len;
+	),
+	TP_printk("vring %d index %d len %d frags %d",
+		  __entry->vring, __entry->index, __entry->len, __entry->frags)
+);
+
+TRACE_EVENT(wil6210_tx_done,
+	TP_PROTO(u8 vring, u16 index, unsigned int len, u8 err),
+	TP_ARGS(vring, index, len, err),
+	TP_STRUCT__entry(
+		__field(u8, vring)
+		__field(u8, err)
+		__field(u16, index)
+		__field(unsigned int, len)
+	),
+	TP_fast_assign(
+		__entry->vring = vring;
+		__entry->index = index;
+		__entry->len = len;
+		__entry->err = err;
+	),
+	TP_printk("vring %d index %d len %d err 0x%02x",
+		  __entry->vring, __entry->index, __entry->len,
+		  __entry->err)
+);
+
+#endif /* WIL6210_TRACE_H || TRACE_HEADER_MULTI_READ*/
+
+#if defined(CONFIG_WIL6210_TRACING) && !defined(__CHECKER__)
+/* we don't want to use include/trace/events */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
+#endif /* defined(CONFIG_WIL6210_TRACING) && !defined(__CHECKER__) */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/txrx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/txrx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/txrx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/txrx.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@
 #include "wil6210.h"
 #include "wmi.h"
 #include "txrx.h"
+#include "trace.h"
 
 static bool rtap_include_phy_info;
 module_param(rtap_include_phy_info, bool, S_IRUGO);
@@ -89,8 +90,8 @@ static int wil_vring_alloc(struct wil621
 	 * we can use any
 	 */
 	for (i = 0; i < vring->size; i++) {
-		volatile struct vring_tx_desc *d = &(vring->va[i].tx);
-		d->dma.status = TX_DMA_STATUS_DU;
+		volatile struct vring_tx_desc *_d = &(vring->va[i].tx);
+		_d->dma.status = TX_DMA_STATUS_DU;
 	}
 
 	wil_dbg_misc(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
@@ -106,30 +107,39 @@ static void wil_vring_free(struct wil621
 	size_t sz = vring->size * sizeof(vring->va[0]);
 
 	while (!wil_vring_is_empty(vring)) {
+		dma_addr_t pa;
+		struct sk_buff *skb;
+		u16 dmalen;
+
 		if (tx) {
-			volatile struct vring_tx_desc *d =
+			struct vring_tx_desc dd, *d = &dd;
+			volatile struct vring_tx_desc *_d =
 					&vring->va[vring->swtail].tx;
-			dma_addr_t pa = d->dma.addr_low |
-					((u64)d->dma.addr_high << 32);
-			struct sk_buff *skb = vring->ctx[vring->swtail];
+
+			*d = *_d;
+			pa = wil_desc_addr(&d->dma.addr);
+			dmalen = le16_to_cpu(d->dma.length);
+			skb = vring->ctx[vring->swtail];
 			if (skb) {
-				dma_unmap_single(dev, pa, d->dma.length,
+				dma_unmap_single(dev, pa, dmalen,
 						 DMA_TO_DEVICE);
 				dev_kfree_skb_any(skb);
 				vring->ctx[vring->swtail] = NULL;
 			} else {
-				dma_unmap_page(dev, pa, d->dma.length,
+				dma_unmap_page(dev, pa, dmalen,
 					       DMA_TO_DEVICE);
 			}
 			vring->swtail = wil_vring_next_tail(vring);
 		} else { /* rx */
-			volatile struct vring_rx_desc *d =
+			struct vring_rx_desc dd, *d = &dd;
+			volatile struct vring_rx_desc *_d =
 					&vring->va[vring->swtail].rx;
-			dma_addr_t pa = d->dma.addr_low |
-					((u64)d->dma.addr_high << 32);
-			struct sk_buff *skb = vring->ctx[vring->swhead];
-			dma_unmap_single(dev, pa, d->dma.length,
-					 DMA_FROM_DEVICE);
+
+			*d = *_d;
+			pa = wil_desc_addr(&d->dma.addr);
+			dmalen = le16_to_cpu(d->dma.length);
+			skb = vring->ctx[vring->swhead];
+			dma_unmap_single(dev, pa, dmalen, DMA_FROM_DEVICE);
 			kfree_skb(skb);
 			wil_vring_advance_head(vring, 1);
 		}
@@ -151,7 +161,8 @@ static int wil_vring_alloc_skb(struct wi
 {
 	struct device *dev = wil_to_dev(wil);
 	unsigned int sz = RX_BUF_LEN;
-	volatile struct vring_rx_desc *d = &(vring->va[i].rx);
+	struct vring_rx_desc dd, *d = &dd;
+	volatile struct vring_rx_desc *_d = &(vring->va[i].rx);
 	dma_addr_t pa;
 
 	/* TODO align */
@@ -169,13 +180,13 @@ static int wil_vring_alloc_skb(struct wi
 	}
 
 	d->dma.d0 = BIT(9) | RX_DMA_D0_CMD_DMA_IT;
-	d->dma.addr_low = lower_32_bits(pa);
-	d->dma.addr_high = (u16)upper_32_bits(pa);
+	wil_desc_addr_set(&d->dma.addr, pa);
 	/* ip_length don't care */
 	/* b11 don't care */
 	/* error don't care */
 	d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
-	d->dma.length = sz;
+	d->dma.length = cpu_to_le16(sz);
+	*_d = *d;
 	vring->ctx[i] = skb;
 
 	return 0;
@@ -321,11 +332,12 @@ static struct sk_buff *wil_vring_reap_rx
 {
 	struct device *dev = wil_to_dev(wil);
 	struct net_device *ndev = wil_to_ndev(wil);
-	volatile struct vring_rx_desc *d;
-	struct vring_rx_desc *d1;
+	volatile struct vring_rx_desc *_d;
+	struct vring_rx_desc *d;
 	struct sk_buff *skb;
 	dma_addr_t pa;
 	unsigned int sz = RX_BUF_LEN;
+	u16 dmalen;
 	u8 ftype;
 	u8 ds_bits;
 
@@ -334,32 +346,44 @@ static struct sk_buff *wil_vring_reap_rx
 	if (wil_vring_is_empty(vring))
 		return NULL;
 
-	d = &(vring->va[vring->swhead].rx);
-	if (!(d->dma.status & RX_DMA_STATUS_DU)) {
+	_d = &(vring->va[vring->swhead].rx);
+	if (!(_d->dma.status & RX_DMA_STATUS_DU)) {
 		/* it is not error, we just reached end of Rx done area */
 		return NULL;
 	}
 
-	pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
 	skb = vring->ctx[vring->swhead];
+	d = wil_skb_rxdesc(skb);
+	*d = *_d;
+	pa = wil_desc_addr(&d->dma.addr);
+	vring->ctx[vring->swhead] = NULL;
+	wil_vring_advance_head(vring, 1);
+
 	dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
-	skb_trim(skb, d->dma.length);
+	dmalen = le16_to_cpu(d->dma.length);
 
-	d1 = wil_skb_rxdesc(skb);
-	*d1 = *d;
+	trace_wil6210_rx(vring->swhead, d);
+	wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, dmalen);
+	wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
+			  (const void *)d, sizeof(*d), false);
 
-	wil->stats.last_mcs_rx = wil_rxdesc_mcs(d1);
+	if (dmalen > sz) {
+		wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
+		kfree_skb(skb);
+		return NULL;
+	}
+	skb_trim(skb, dmalen);
+
+	wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
+			  skb->data, skb_headlen(skb), false);
+
+
+	wil->stats.last_mcs_rx = wil_rxdesc_mcs(d);
 
 	/* use radiotap header only if required */
 	if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
 		wil_rx_add_radiotap_header(wil, skb);
 
-	wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
-	wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
-			  (const void *)d, sizeof(*d), false);
-
-	wil_vring_advance_head(vring, 1);
-
 	/* no extra checks if in sniffer mode */
 	if (ndev->type != ARPHRD_ETHER)
 		return skb;
@@ -368,7 +392,7 @@ static struct sk_buff *wil_vring_reap_rx
 	 * Driver should recognize it by frame type, that is found
 	 * in Rx descriptor. If type is not data, it is 802.11 frame as is
 	 */
-	ftype = wil_rxdesc_ftype(d1) << 2;
+	ftype = wil_rxdesc_ftype(d) << 2;
 	if (ftype != IEEE80211_FTYPE_DATA) {
 		wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
 		/* TODO: process it */
@@ -383,7 +407,7 @@ static struct sk_buff *wil_vring_reap_rx
 		return NULL;
 	}
 
-	ds_bits = wil_rxdesc_ds_bits(d1);
+	ds_bits = wil_rxdesc_ds_bits(d);
 	if (ds_bits == 1) {
 		/*
 		 * HW bug - in ToDS mode, i.e. Rx on AP side,
@@ -425,6 +449,7 @@ static int wil_rx_refill(struct wil6210_
 
 /*
  * Pass Rx packet to the netif. Update statistics.
+ * Called in softirq context (NAPI poll).
  */
 static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
 {
@@ -433,10 +458,7 @@ static void wil_netif_rx_any(struct sk_b
 
 	skb_orphan(skb);
 
-	if (in_interrupt())
-		rc = netif_rx(skb);
-	else
-		rc = netif_rx_ni(skb);
+	rc = netif_receive_skb(skb);
 
 	if (likely(rc == NET_RX_SUCCESS)) {
 		ndev->stats.rx_packets++;
@@ -450,9 +472,9 @@ static void wil_netif_rx_any(struct sk_b
 /**
  * Proceed all completed skb's from Rx VRING
  *
- * Safe to call from IRQ
+ * Safe to call from NAPI poll, i.e. softirq with interrupts enabled
  */
-void wil_rx_handle(struct wil6210_priv *wil)
+void wil_rx_handle(struct wil6210_priv *wil, int *quota)
 {
 	struct net_device *ndev = wil_to_ndev(wil);
 	struct vring *v = &wil->vring_rx;
@@ -463,9 +485,8 @@ void wil_rx_handle(struct wil6210_priv *
 		return;
 	}
 	wil_dbg_txrx(wil, "%s()\n", __func__);
-	while (NULL != (skb = wil_vring_reap_rx(wil, v))) {
-		wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
-				  skb->data, skb_headlen(skb), false);
+	while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) {
+		(*quota)--;
 
 		if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
 			skb->dev = ndev;
@@ -600,18 +621,17 @@ static struct vring *wil_find_tx_vring(s
 	return NULL;
 }
 
-static int wil_tx_desc_map(volatile struct vring_tx_desc *d,
-			   dma_addr_t pa, u32 len)
+static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
+			   int vring_index)
 {
-	d->dma.addr_low = lower_32_bits(pa);
-	d->dma.addr_high = (u16)upper_32_bits(pa);
+	wil_desc_addr_set(&d->dma.addr, pa);
 	d->dma.ip_length = 0;
 	/* 0..6: mac_length; 7:ip_version 0-IP6 1-IP4*/
 	d->dma.b11 = 0/*14 | BIT(7)*/;
 	d->dma.error = 0;
 	d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
-	d->dma.length = len;
-	d->dma.d0 = 0;
+	d->dma.length = cpu_to_le16((u16)len);
+	d->dma.d0 = (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
 	d->mac.d[0] = 0;
 	d->mac.d[1] = 0;
 	d->mac.d[2] = 0;
@@ -630,7 +650,8 @@ static int wil_tx_vring(struct wil6210_p
 			struct sk_buff *skb)
 {
 	struct device *dev = wil_to_dev(wil);
-	volatile struct vring_tx_desc *d;
+	struct vring_tx_desc dd, *d = &dd;
+	volatile struct vring_tx_desc *_d;
 	u32 swhead = vring->swhead;
 	int avail = wil_vring_avail_tx(vring);
 	int nr_frags = skb_shinfo(skb)->nr_frags;
@@ -648,7 +669,7 @@ static int wil_tx_vring(struct wil6210_p
 			1 + nr_frags);
 		return -ENOMEM;
 	}
-	d = &(vring->va[i].tx);
+	_d = &(vring->va[i].tx);
 
 	/* FIXME FW can accept only unicast frames for the peer */
 	memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN);
@@ -664,28 +685,32 @@ static int wil_tx_vring(struct wil6210_p
 	if (unlikely(dma_mapping_error(dev, pa)))
 		return -EINVAL;
 	/* 1-st segment */
-	wil_tx_desc_map(d, pa, skb_headlen(skb));
+	wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index);
 	d->mac.d[2] |= ((nr_frags + 1) <<
 		       MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS);
+	if (nr_frags)
+		*_d = *d;
+
 	/* middle segments */
 	for (f = 0; f < nr_frags; f++) {
 		const struct skb_frag_struct *frag =
 				&skb_shinfo(skb)->frags[f];
 		int len = skb_frag_size(frag);
 		i = (swhead + f + 1) % vring->size;
-		d = &(vring->va[i].tx);
+		_d = &(vring->va[i].tx);
 		pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
 				DMA_TO_DEVICE);
 		if (unlikely(dma_mapping_error(dev, pa)))
 			goto dma_error;
-		wil_tx_desc_map(d, pa, len);
+		wil_tx_desc_map(d, pa, len, vring_index);
 		vring->ctx[i] = NULL;
+		*_d = *d;
 	}
 	/* for the last seg only */
 	d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS);
-	d->dma.d0 |= BIT(9); /* BUG: undocumented bit */
+	d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS);
 	d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
-	d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
+	*_d = *d;
 
 	wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
 			  (const void *)d, sizeof(*d), false);
@@ -693,6 +718,7 @@ static int wil_tx_vring(struct wil6210_p
 	/* advance swhead */
 	wil_vring_advance_head(vring, nr_frags + 1);
 	wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
+	trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags);
 	iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
 	/* hold reference to skb
 	 * to prevent skb release before accounting
@@ -705,14 +731,18 @@ static int wil_tx_vring(struct wil6210_p
 	/* unmap what we have mapped */
 	/* Note: increment @f to operate with positive index */
 	for (f++; f > 0; f--) {
+		u16 dmalen;
+
 		i = (swhead + f) % vring->size;
-		d = &(vring->va[i].tx);
-		d->dma.status = TX_DMA_STATUS_DU;
-		pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
+		_d = &(vring->va[i].tx);
+		*d = *_d;
+		_d->dma.status = TX_DMA_STATUS_DU;
+		pa = wil_desc_addr(&d->dma.addr);
+		dmalen = le16_to_cpu(d->dma.length);
 		if (vring->ctx[i])
-			dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE);
+			dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
 		else
-			dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE);
+			dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
 	}
 
 	return -EINVAL;
@@ -738,18 +768,16 @@ netdev_tx_t wil_start_xmit(struct sk_buf
 		wil_err(wil, "Xmit in monitor mode not supported\n");
 		goto drop;
 	}
-	if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
-		rc = wmi_tx_eapol(wil, skb);
-	} else {
-		/* find vring */
-		vring = wil_find_tx_vring(wil, skb);
-		if (!vring) {
-			wil_err(wil, "No Tx VRING available\n");
-			goto drop;
-		}
-		/* set up vring entry */
-		rc = wil_tx_vring(wil, vring, skb);
+
+	/* find vring */
+	vring = wil_find_tx_vring(wil, skb);
+	if (!vring) {
+		wil_err(wil, "No Tx VRING available\n");
+		goto drop;
 	}
+	/* set up vring entry */
+	rc = wil_tx_vring(wil, vring, skb);
+
 	switch (rc) {
 	case 0:
 		/* statistics will be updated on the tx_complete */
@@ -761,7 +789,6 @@ netdev_tx_t wil_start_xmit(struct sk_buf
 		break; /* goto drop; */
 	}
  drop:
-	netif_tx_stop_all_queues(ndev);
 	ndev->stats.tx_dropped++;
 	dev_kfree_skb_any(skb);
 
@@ -771,41 +798,48 @@ netdev_tx_t wil_start_xmit(struct sk_buf
 /**
  * Clean up transmitted skb's from the Tx VRING
  *
+ * Return number of descriptors cleared
+ *
  * Safe to call from IRQ
  */
-void wil_tx_complete(struct wil6210_priv *wil, int ringid)
+int wil_tx_complete(struct wil6210_priv *wil, int ringid)
 {
 	struct net_device *ndev = wil_to_ndev(wil);
 	struct device *dev = wil_to_dev(wil);
 	struct vring *vring = &wil->vring_tx[ringid];
+	int done = 0;
 
 	if (!vring->va) {
 		wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
-		return;
+		return 0;
 	}
 
 	wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
 
 	while (!wil_vring_is_empty(vring)) {
-		volatile struct vring_tx_desc *d1 =
+		volatile struct vring_tx_desc *_d =
 					      &vring->va[vring->swtail].tx;
 		struct vring_tx_desc dd, *d = &dd;
 		dma_addr_t pa;
 		struct sk_buff *skb;
+		u16 dmalen;
 
-		dd = *d1;
+		*d = *_d;
 
 		if (!(d->dma.status & TX_DMA_STATUS_DU))
 			break;
 
+		dmalen = le16_to_cpu(d->dma.length);
+		trace_wil6210_tx_done(ringid, vring->swtail, dmalen,
+				      d->dma.error);
 		wil_dbg_txrx(wil,
 			     "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n",
-			     vring->swtail, d->dma.length, d->dma.status,
+			     vring->swtail, dmalen, d->dma.status,
 			     d->dma.error);
 		wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4,
 				  (const void *)d, sizeof(*d), false);
 
-		pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
+		pa = wil_desc_addr(&d->dma.addr);
 		skb = vring->ctx[vring->swtail];
 		if (skb) {
 			if (d->dma.error == 0) {
@@ -815,18 +849,21 @@ void wil_tx_complete(struct wil6210_priv
 				ndev->stats.tx_errors++;
 			}
 
-			dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE);
+			dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
 			dev_kfree_skb_any(skb);
 			vring->ctx[vring->swtail] = NULL;
 		} else {
-			dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE);
+			dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
 		}
-		d->dma.addr_low = 0;
-		d->dma.addr_high = 0;
+		d->dma.addr.addr_low = 0;
+		d->dma.addr.addr_high = 0;
 		d->dma.length = 0;
 		d->dma.status = TX_DMA_STATUS_DU;
 		vring->swtail = wil_vring_next_tail(vring);
+		done++;
 	}
 	if (wil_vring_avail_tx(vring) > vring->size/4)
 		netif_tx_wake_all_queues(wil_to_ndev(wil));
+
+	return done;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/txrx.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/txrx.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/txrx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/txrx.h	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,28 @@
 #define WIL6210_RTAP_SIZE (128)
 
 /* Tx/Rx path */
+
+/*
+ * Common representation of physical address in Vring
+ */
+struct vring_dma_addr {
+	__le32 addr_low;
+	__le16 addr_high;
+} __packed;
+
+static inline dma_addr_t wil_desc_addr(struct vring_dma_addr *addr)
+{
+	return le32_to_cpu(addr->addr_low) |
+			   ((u64)le16_to_cpu(addr->addr_high) << 32);
+}
+
+static inline void wil_desc_addr_set(struct vring_dma_addr *addr,
+				     dma_addr_t pa)
+{
+	addr->addr_low = cpu_to_le32(lower_32_bits(pa));
+	addr->addr_high = cpu_to_le16((u16)upper_32_bits(pa));
+}
+
 /*
  * Tx descriptor - MAC part
  * [dword 0]
@@ -179,6 +201,10 @@ struct vring_tx_mac {
 #define DMA_CFG_DESC_TX_0_CMD_EOP_LEN 1
 #define DMA_CFG_DESC_TX_0_CMD_EOP_MSK 0x100
 
+#define DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS 9
+#define DMA_CFG_DESC_TX_0_CMD_MARK_WB_LEN 1
+#define DMA_CFG_DESC_TX_0_CMD_MARK_WB_MSK 0x200
+
 #define DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS 10
 #define DMA_CFG_DESC_TX_0_CMD_DMA_IT_LEN 1
 #define DMA_CFG_DESC_TX_0_CMD_DMA_IT_MSK 0x400
@@ -216,13 +242,12 @@ struct vring_tx_mac {
 
 struct vring_tx_dma {
 	u32 d0;
-	u32 addr_low;
-	u16 addr_high;
+	struct vring_dma_addr addr;
 	u8  ip_length;
 	u8  b11;       /* 0..6: mac_length; 7:ip_version */
 	u8  error;     /* 0..2: err; 3..7: reserved; */
 	u8  status;    /* 0: used; 1..7; reserved */
-	u16 length;
+	__le16 length;
 } __packed;
 
 /*
@@ -315,13 +340,12 @@ struct vring_rx_mac {
 
 struct vring_rx_dma {
 	u32 d0;
-	u32 addr_low;
-	u16 addr_high;
+	struct vring_dma_addr addr;
 	u8  ip_length;
 	u8  b11;
 	u8  error;
 	u8  status;
-	u16 length;
+	__le16 length;
 } __packed;
 
 struct vring_tx_desc {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/wil6210.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/wil6210.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/wil6210.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/wil6210.h	2013-08-25 20:43:22.000000000 -0400
@@ -34,9 +34,11 @@ static inline u32 WIL_GET_BITS(u32 x, in
 
 #define WIL6210_MEM_SIZE (2*1024*1024UL)
 
-#define WIL6210_RX_RING_SIZE (128)
-#define WIL6210_TX_RING_SIZE (128)
-#define WIL6210_MAX_TX_RINGS (24)
+#define WIL6210_RX_RING_SIZE	(128)
+#define WIL6210_TX_RING_SIZE	(128)
+#define WIL6210_MAX_TX_RINGS	(24) /* HW limit */
+#define WIL6210_MAX_CID		(8) /* HW limit */
+#define WIL6210_NAPI_BUDGET	(16) /* arbitrary */
 
 /* Hardware definitions begin */
 
@@ -184,6 +186,7 @@ struct vring {
 
 enum { /* for wil6210_priv.status */
 	wil_status_fwready = 0,
+	wil_status_fwconnecting,
 	wil_status_fwconnected,
 	wil_status_dontscan,
 	wil_status_reset_done,
@@ -239,6 +242,8 @@ struct wil6210_priv {
 	 * - consumed in thread by wmi_event_worker
 	 */
 	spinlock_t wmi_ev_lock;
+	struct napi_struct napi_rx;
+	struct napi_struct napi_tx;
 	/* DMA related */
 	struct vring vring_rx;
 	struct vring vring_tx[WIL6210_MAX_TX_RINGS];
@@ -267,9 +272,13 @@ struct wil6210_priv {
 #define wil_to_ndev(i) (wil_to_wdev(i)->netdev)
 #define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr))
 
-#define wil_dbg(wil, fmt, arg...) netdev_dbg(wil_to_ndev(wil), fmt, ##arg)
-#define wil_info(wil, fmt, arg...) netdev_info(wil_to_ndev(wil), fmt, ##arg)
-#define wil_err(wil, fmt, arg...) netdev_err(wil_to_ndev(wil), fmt, ##arg)
+int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...);
+int wil_err(struct wil6210_priv *wil, const char *fmt, ...);
+int wil_info(struct wil6210_priv *wil, const char *fmt, ...);
+#define wil_dbg(wil, fmt, arg...) do { \
+	netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \
+	wil_dbg_trace(wil, fmt, ##arg); \
+} while (0)
 
 #define wil_dbg_irq(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg)
 #define wil_dbg_txrx(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg)
@@ -320,7 +329,6 @@ int wmi_set_ssid(struct wil6210_priv *wi
 int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid);
 int wmi_set_channel(struct wil6210_priv *wil, int channel);
 int wmi_get_channel(struct wil6210_priv *wil, int *channel);
-int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb);
 int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index,
 		       const void *mac_addr);
 int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
@@ -356,10 +364,12 @@ int wil_vring_init_tx(struct wil6210_pri
 void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
 
 netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
-void wil_tx_complete(struct wil6210_priv *wil, int ringid);
+int wil_tx_complete(struct wil6210_priv *wil, int ringid);
+void wil6210_unmask_irq_tx(struct wil6210_priv *wil);
 
 /* RX API */
-void wil_rx_handle(struct wil6210_priv *wil);
+void wil_rx_handle(struct wil6210_priv *wil, int *quota);
+void wil6210_unmask_irq_rx(struct wil6210_priv *wil);
 
 int wil_iftype_nl2wmi(enum nl80211_iftype type);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/wmi.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/wmi.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ath/wil6210/wmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ath/wil6210/wmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include "wil6210.h"
 #include "txrx.h"
 #include "wmi.h"
+#include "trace.h"
 
 /**
  * WMI event receiving - theory of operations
@@ -74,10 +75,11 @@ static const struct {
 	{0x800000, 0x808000, 0x900000}, /* FW data RAM 32k */
 	{0x840000, 0x860000, 0x908000}, /* peripheral data RAM 128k/96k used */
 	{0x880000, 0x88a000, 0x880000}, /* various RGF */
-	{0x8c0000, 0x932000, 0x8c0000}, /* trivial mapping for upper area */
+	{0x8c0000, 0x949000, 0x8c0000}, /* trivial mapping for upper area */
 	/*
 	 * 920000..930000 ucode code RAM
 	 * 930000..932000 ucode data RAM
+	 * 932000..949000 back-door debug data
 	 */
 };
 
@@ -246,6 +248,8 @@ static int __wmi_send(struct wil6210_pri
 	iowrite32(r->head = next_head, wil->csr + HOST_MBOX +
 		  offsetof(struct wil6210_mbox_ctl, tx.head));
 
+	trace_wil6210_wmi_cmd(cmdid, buf, len);
+
 	/* interrupt to FW */
 	iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT);
 
@@ -311,8 +315,8 @@ static void wmi_evt_rx_mgmt(struct wil62
 
 	wil_dbg_wmi(wil, "MGMT: channel %d MCS %d SNR %d\n",
 		    data->info.channel, data->info.mcs, data->info.snr);
-	wil_dbg_wmi(wil, "status 0x%04x len %d stype %04x\n", d_status, d_len,
-		    le16_to_cpu(data->info.stype));
+	wil_dbg_wmi(wil, "status 0x%04x len %d fc 0x%04x\n", d_status, d_len,
+		    le16_to_cpu(fc));
 	wil_dbg_wmi(wil, "qid %d mid %d cid %d\n",
 		    data->info.qid, data->info.mid, data->info.cid);
 
@@ -406,7 +410,7 @@ static void wmi_evt_connect(struct wil62
 
 	if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
 	    (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
-		if (wdev->sme_state != CFG80211_SME_CONNECTING) {
+		if (!test_bit(wil_status_fwconnecting, &wil->status)) {
 			wil_err(wil, "Not in connecting state\n");
 			return;
 		}
@@ -430,6 +434,7 @@ static void wmi_evt_connect(struct wil62
 
 		cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
 	}
+	clear_bit(wil_status_fwconnecting, &wil->status);
 	set_bit(wil_status_fwconnected, &wil->status);
 
 	/* FIXME FW can transmit only ucast frames to peer */
@@ -635,8 +640,9 @@ void wmi_recv_cmd(struct wil6210_priv *w
 			    hdr.flags);
 		if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) &&
 		    (len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
-			wil_dbg_wmi(wil, "WMI event 0x%04x\n",
-				    evt->event.wmi.id);
+			u16 id = le16_to_cpu(evt->event.wmi.id);
+			wil_dbg_wmi(wil, "WMI event 0x%04x\n", id);
+			trace_wil6210_wmi_event(id, &evt->event.wmi, len);
 		}
 		wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1,
 				 &evt->event.hdr, sizeof(hdr) + len, true);
@@ -724,7 +730,7 @@ int wmi_pcp_start(struct wil6210_priv *w
 		.bcon_interval = cpu_to_le16(bi),
 		.network_type = wmi_nettype,
 		.disable_sec_offload = 1,
-		.channel = chan,
+		.channel = chan - 1,
 	};
 	struct {
 		struct wil6210_mbox_hdr_wmi wmi;
@@ -734,8 +740,12 @@ int wmi_pcp_start(struct wil6210_priv *w
 	if (!wil->secure_pcp)
 		cmd.disable_sec = 1;
 
+	/*
+	 * Processing time may be huge, in case of secure AP it takes about
+	 * 3500ms for FW to start AP
+	 */
 	rc = wmi_call(wil, WMI_PCP_START_CMDID, &cmd, sizeof(cmd),
-		      WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 100);
+		      WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 5000);
 	if (rc)
 		return rc;
 
@@ -829,40 +839,6 @@ int wmi_p2p_cfg(struct wil6210_priv *wil
 	return wmi_send(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd));
 }
 
-int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb)
-{
-	struct wmi_eapol_tx_cmd *cmd;
-	struct ethhdr *eth;
-	u16 eapol_len = skb->len - ETH_HLEN;
-	void *eapol = skb->data + ETH_HLEN;
-	uint i;
-	int rc;
-
-	skb_set_mac_header(skb, 0);
-	eth = eth_hdr(skb);
-	wil_dbg_wmi(wil, "EAPOL %d bytes to %pM\n", eapol_len, eth->h_dest);
-	for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
-		if (memcmp(wil->dst_addr[i], eth->h_dest, ETH_ALEN) == 0)
-			goto found_dest;
-	}
-
-	return -EINVAL;
-
- found_dest:
-	/* find out eapol data & len */
-	cmd = kzalloc(sizeof(*cmd) + eapol_len, GFP_KERNEL);
-	if (!cmd)
-		return -EINVAL;
-
-	memcpy(cmd->dst_mac, eth->h_dest, ETH_ALEN);
-	cmd->eapol_len = cpu_to_le16(eapol_len);
-	memcpy(cmd->eapol, eapol, eapol_len);
-	rc = wmi_send(wil, WMI_EAPOL_TX_CMDID, cmd, sizeof(*cmd) + eapol_len);
-	kfree(cmd);
-
-	return rc;
-}
-
 int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index,
 		       const void *mac_addr)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/b43/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/b43/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/b43/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/b43/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -28,18 +28,12 @@ config B43
 
 config B43_BCMA
 	bool "Support for BCMA bus"
-	depends on B43 && BCMA
-	default y
-
-config B43_BCMA_EXTRA
-	bool "Hardware support that overlaps with the brcmsmac driver"
-	depends on B43_BCMA
-	default n if BRCMSMAC
+	depends on B43 && (BCMA = y || BCMA = B43)
 	default y
 
 config B43_SSB
 	bool
-	depends on B43 && SSB
+	depends on B43 && (SSB = y || SSB = B43)
 	default y
 
 # Auto-select SSB PCI-HOST support, if possible
@@ -111,6 +105,7 @@ config B43_PIO
 config B43_PHY_N
 	bool "Support for 802.11n (N-PHY) devices"
 	depends on B43
+	default y
 	---help---
 	  Support for the N-PHY.
 
@@ -132,6 +127,7 @@ config B43_PHY_LP
 config B43_PHY_HT
 	bool "Support for HT-PHY (high throughput) devices"
 	depends on B43 && B43_BCMA
+	default y
 	---help---
 	  Support for the HT-PHY.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/b43/main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/b43/main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/b43/main.c	2013-07-01 10:38:01.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/b43/main.c	2013-08-31 17:57:35.000000000 -0400
@@ -107,13 +107,15 @@ static int b43_modparam_pio = 0;
 module_param_named(pio, b43_modparam_pio, int, 0644);
 MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
 
+static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC);
+module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
+MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
+
 #ifdef CONFIG_B43_BCMA
 static const struct bcma_device_id b43_bcma_tbl[] = {
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
-#ifdef CONFIG_B43_BCMA_EXTRA
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
-#endif
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
 	BCMA_CORETABLE_END
 };
@@ -5392,6 +5394,12 @@ static int b43_bcma_probe(struct bcma_de
 	struct b43_wl *wl;
 	int err;
 
+	if (!modparam_allhwsupport &&
+	    (core->id.rev == 0x17 || core->id.rev == 0x18)) {
+		pr_err("Support for cores revisions 0x17 and 0x18 disabled by module param allhwsupport=0. Try b43.allhwsupport=1\n");
+		return -ENOTSUPP;
+	}
+
 	dev = b43_bus_dev_bcma_init(core);
 	if (!dev)
 		return -ENODEV;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,9 +22,11 @@
 #include <linux/pci_ids.h>
 #include <linux/sched.h>
 #include <linux/completion.h>
+#include <linux/scatterlist.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
 #include <linux/platform_data/brcmfmac-sdio.h>
 
 #include <defs.h>
@@ -160,7 +162,7 @@ int brcmf_sdio_intr_unregister(struct br
 	return 0;
 }
 
-int
+static int
 brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
 {
 	int err = 0, i;
@@ -191,12 +193,33 @@ brcmf_sdcard_set_sbaddr_window(struct br
 	return err;
 }
 
+static int
+brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
+{
+	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+	int err = 0;
+
+	if (bar0 != sdiodev->sbwad) {
+		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
+		if (err)
+			return err;
+
+		sdiodev->sbwad = bar0;
+	}
+
+	*addr &= SBSDIO_SB_OFT_ADDR_MASK;
+
+	if (width == 4)
+		*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+	return 0;
+}
+
 int
 brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
 			void *data, bool write)
 {
 	u8 func_num, reg_size;
-	u32 bar;
 	s32 retry = 0;
 	int ret;
 
@@ -216,18 +239,7 @@ brcmf_sdio_regrw_helper(struct brcmf_sdi
 		func_num = SDIO_FUNC_1;
 		reg_size = 4;
 
-		/* Set the window for SB core register */
-		bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
-		if (bar != sdiodev->sbwad) {
-			ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
-			if (ret != 0) {
-				memset(data, 0xFF, reg_size);
-				return ret;
-			}
-			sdiodev->sbwad = bar;
-		}
-		addr &= SBSDIO_SB_OFT_ADDR_MASK;
-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+		brcmf_sdio_addrprep(sdiodev, reg_size, &addr);
 	}
 
 	do {
@@ -303,30 +315,207 @@ void brcmf_sdio_regwl(struct brcmf_sdio_
 		*ret = retval;
 }
 
-static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
-				     uint flags, uint width, u32 *addr)
+/**
+ * brcmf_sdio_buffrw - SDIO interface function for block data access
+ * @sdiodev: brcmfmac sdio device
+ * @fn: SDIO function number
+ * @write: direction flag
+ * @addr: dongle memory address as source/destination
+ * @pkt: skb pointer
+ *
+ * This function takes the respbonsibility as the interface function to MMC
+ * stack for block data access. It assumes that the skb passed down by the
+ * caller has already been padded and aligned.
+ */
+static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
+			     bool write, u32 addr, struct sk_buff_head *pktlist)
 {
-	uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
-	int err = 0;
+	unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
+	unsigned int max_blks, max_req_sz, orig_offset, dst_offset;
+	unsigned short max_seg_sz, seg_sz;
+	unsigned char *pkt_data, *orig_data, *dst_data;
+	struct sk_buff *pkt_next = NULL, *local_pkt_next;
+	struct sk_buff_head local_list, *target_list;
+	struct mmc_request mmc_req;
+	struct mmc_command mmc_cmd;
+	struct mmc_data mmc_dat;
+	struct sg_table st;
+	struct scatterlist *sgl;
+	struct mmc_host *host;
+	int ret = 0;
 
-	/* Async not implemented yet */
-	if (flags & SDIO_REQ_ASYNC)
-		return -ENOTSUPP;
+	if (!pktlist->qlen)
+		return -EINVAL;
 
-	if (bar0 != sdiodev->sbwad) {
-		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
-		if (err)
-			return err;
+	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
+	if (brcmf_pm_resume_error(sdiodev))
+		return -EIO;
 
-		sdiodev->sbwad = bar0;
+	/* Single skb use the standard mmc interface */
+	if (pktlist->qlen == 1) {
+		pkt_next = pktlist->next;
+		req_sz = pkt_next->len + 3;
+		req_sz &= (uint)~3;
+
+		if (write)
+			return sdio_memcpy_toio(sdiodev->func[fn], addr,
+						((u8 *)(pkt_next->data)),
+						req_sz);
+		else if (fn == 1)
+			return sdio_memcpy_fromio(sdiodev->func[fn],
+						  ((u8 *)(pkt_next->data)),
+						  addr, req_sz);
+		else
+			/* function 2 read is FIFO operation */
+			return sdio_readsb(sdiodev->func[fn],
+					   ((u8 *)(pkt_next->data)), addr,
+					   req_sz);
 	}
 
-	*addr &= SBSDIO_SB_OFT_ADDR_MASK;
+	target_list = pktlist;
+	/* for host with broken sg support, prepare a page aligned list */
+	__skb_queue_head_init(&local_list);
+	if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
+		req_sz = 0;
+		skb_queue_walk(pktlist, pkt_next)
+			req_sz += pkt_next->len;
+		req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize);
+		while (req_sz > PAGE_SIZE) {
+			pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE);
+			if (pkt_next == NULL) {
+				ret = -ENOMEM;
+				goto exit;
+			}
+			__skb_queue_tail(&local_list, pkt_next);
+			req_sz -= PAGE_SIZE;
+		}
+		pkt_next = brcmu_pkt_buf_get_skb(req_sz);
+		if (pkt_next == NULL) {
+			ret = -ENOMEM;
+			goto exit;
+		}
+		__skb_queue_tail(&local_list, pkt_next);
+		target_list = &local_list;
+	}
 
-	if (width == 4)
-		*addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+	host = sdiodev->func[fn]->card->host;
+	func_blk_sz = sdiodev->func[fn]->cur_blksize;
+	/* Blocks per command is limited by host count, host transfer
+	 * size and the maximum for IO_RW_EXTENDED of 511 blocks.
+	 */
+	max_blks = min_t(unsigned int, host->max_blk_count, 511u);
+	max_req_sz = min_t(unsigned int, host->max_req_size,
+			   max_blks * func_blk_sz);
+	max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC);
+	max_seg_sz = min_t(unsigned short, max_seg_sz, target_list->qlen);
+	seg_sz = target_list->qlen;
+	pkt_offset = 0;
+	pkt_next = target_list->next;
 
-	return 0;
+	if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	while (seg_sz) {
+		req_sz = 0;
+		sg_cnt = 0;
+		memset(&mmc_req, 0, sizeof(struct mmc_request));
+		memset(&mmc_cmd, 0, sizeof(struct mmc_command));
+		memset(&mmc_dat, 0, sizeof(struct mmc_data));
+		sgl = st.sgl;
+		/* prep sg table */
+		while (pkt_next != (struct sk_buff *)target_list) {
+			pkt_data = pkt_next->data + pkt_offset;
+			sg_data_sz = pkt_next->len - pkt_offset;
+			if (sg_data_sz > host->max_seg_size)
+				sg_data_sz = host->max_seg_size;
+			if (sg_data_sz > max_req_sz - req_sz)
+				sg_data_sz = max_req_sz - req_sz;
+
+			sg_set_buf(sgl, pkt_data, sg_data_sz);
+
+			sg_cnt++;
+			sgl = sg_next(sgl);
+			req_sz += sg_data_sz;
+			pkt_offset += sg_data_sz;
+			if (pkt_offset == pkt_next->len) {
+				pkt_offset = 0;
+				pkt_next = pkt_next->next;
+			}
+
+			if (req_sz >= max_req_sz || sg_cnt >= max_seg_sz)
+				break;
+		}
+		seg_sz -= sg_cnt;
+
+		if (req_sz % func_blk_sz != 0) {
+			brcmf_err("sg request length %u is not %u aligned\n",
+				  req_sz, func_blk_sz);
+			ret = -ENOTBLK;
+			goto exit;
+		}
+		mmc_dat.sg = st.sgl;
+		mmc_dat.sg_len = sg_cnt;
+		mmc_dat.blksz = func_blk_sz;
+		mmc_dat.blocks = req_sz / func_blk_sz;
+		mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
+		mmc_cmd.opcode = SD_IO_RW_EXTENDED;
+		mmc_cmd.arg = write ? 1<<31 : 0;	/* write flag  */
+		mmc_cmd.arg |= (fn & 0x7) << 28;	/* SDIO func num */
+		mmc_cmd.arg |= 1<<27;			/* block mode */
+		/* incrementing addr for function 1 */
+		mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
+		mmc_cmd.arg |= (addr & 0x1FFFF) << 9;	/* address */
+		mmc_cmd.arg |= mmc_dat.blocks & 0x1FF;	/* block count */
+		mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+		mmc_req.cmd = &mmc_cmd;
+		mmc_req.data = &mmc_dat;
+		if (fn == 1)
+			addr += req_sz;
+
+		mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card);
+		mmc_wait_for_req(host, &mmc_req);
+
+		ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
+		if (ret != 0) {
+			brcmf_err("CMD53 sg block %s failed %d\n",
+				  write ? "write" : "read", ret);
+			ret = -EIO;
+			break;
+		}
+	}
+
+	if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
+		local_pkt_next = local_list.next;
+		orig_offset = 0;
+		skb_queue_walk(pktlist, pkt_next) {
+			dst_offset = 0;
+			do {
+				req_sz = local_pkt_next->len - orig_offset;
+				req_sz = min_t(uint, pkt_next->len - dst_offset,
+					       req_sz);
+				orig_data = local_pkt_next->data + orig_offset;
+				dst_data = pkt_next->data + dst_offset;
+				memcpy(dst_data, orig_data, req_sz);
+				orig_offset += req_sz;
+				dst_offset += req_sz;
+				if (orig_offset == local_pkt_next->len) {
+					orig_offset = 0;
+					local_pkt_next = local_pkt_next->next;
+				}
+				if (dst_offset == pkt_next->len)
+					break;
+			} while (!skb_queue_empty(&local_list));
+		}
+	}
+
+exit:
+	sg_free_table(&st);
+	while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
+		brcmu_pkt_buf_free_skb(pkt_next);
+
+	return ret;
 }
 
 int
@@ -355,21 +544,22 @@ int
 brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		      uint flags, struct sk_buff *pkt)
 {
-	uint incr_fix;
 	uint width;
 	int err = 0;
+	struct sk_buff_head pkt_list;
 
 	brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
 		  fn, addr, pkt->len);
 
 	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
-	err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
+	err = brcmf_sdio_addrprep(sdiodev, width, &addr);
 	if (err)
 		goto done;
 
-	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
-	err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
-					 fn, addr, pkt);
+	skb_queue_head_init(&pkt_list);
+	skb_queue_tail(&pkt_list, pkt);
+	err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, &pkt_list);
+	skb_dequeue_tail(&pkt_list);
 
 done:
 	return err;
@@ -386,13 +576,12 @@ int brcmf_sdcard_recv_chain(struct brcmf
 		  fn, addr, pktq->qlen);
 
 	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
-	err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
+	err = brcmf_sdio_addrprep(sdiodev, width, &addr);
 	if (err)
 		goto done;
 
 	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
-	err = brcmf_sdioh_request_chain(sdiodev, incr_fix, SDIOH_READ, fn, addr,
-					pktq);
+	err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pktq);
 
 done:
 	return err;
@@ -424,37 +613,21 @@ int
 brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		      uint flags, struct sk_buff *pkt)
 {
-	uint incr_fix;
 	uint width;
-	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
 	int err = 0;
+	struct sk_buff_head pkt_list;
 
 	brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
 		  fn, addr, pkt->len);
 
-	/* Async not implemented yet */
-	if (flags & SDIO_REQ_ASYNC)
-		return -ENOTSUPP;
-
-	if (bar0 != sdiodev->sbwad) {
-		err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
-		if (err)
-			goto done;
-
-		sdiodev->sbwad = bar0;
-	}
-
-	addr &= SBSDIO_SB_OFT_ADDR_MASK;
-
-	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
 	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
-	if (width == 4)
-		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+	brcmf_sdio_addrprep(sdiodev, width, &addr);
 
-	err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
-					 addr, pkt);
+	skb_queue_head_init(&pkt_list);
+	skb_queue_tail(&pkt_list, pkt);
+	err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list);
+	skb_dequeue_tail(&pkt_list);
 
-done:
 	return err;
 }
 
@@ -466,6 +639,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *
 	struct sk_buff *pkt;
 	u32 sdaddr;
 	uint dsize;
+	struct sk_buff_head pkt_list;
 
 	dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
 	pkt = dev_alloc_skb(dsize);
@@ -474,6 +648,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *
 		return -EIO;
 	}
 	pkt->priority = 0;
+	skb_queue_head_init(&pkt_list);
 
 	/* Determine initial transfer parameters */
 	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
@@ -501,9 +676,10 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *
 		skb_put(pkt, dsize);
 		if (write)
 			memcpy(pkt->data, data, dsize);
-		bcmerror = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC,
-						      write, SDIO_FUNC_1,
-						      sdaddr, pkt);
+		skb_queue_tail(&pkt_list, pkt);
+		bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write,
+					     sdaddr, &pkt_list);
+		skb_dequeue_tail(&pkt_list);
 		if (bcmerror) {
 			brcmf_err("membytes transfer failed\n");
 			break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,7 +66,7 @@ MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_id
 static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
 
 
-static bool
+bool
 brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
 {
 	bool is_err = false;
@@ -76,7 +76,7 @@ brcmf_pm_resume_error(struct brcmf_sdio_
 	return is_err;
 }
 
-static void
+void
 brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
 {
 #ifdef CONFIG_PM_SLEEP
@@ -211,115 +211,6 @@ int brcmf_sdioh_request_word(struct brcm
 	return err_ret;
 }
 
-/* precondition: host controller is claimed */
-static int
-brcmf_sdioh_request_data(struct brcmf_sdio_dev *sdiodev, uint write, bool fifo,
-			 uint func, uint addr, struct sk_buff *pkt, uint pktlen)
-{
-	int err_ret = 0;
-
-	if ((write) && (!fifo)) {
-		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
-					   ((u8 *) (pkt->data)), pktlen);
-	} else if (write) {
-		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
-					   ((u8 *) (pkt->data)), pktlen);
-	} else if (fifo) {
-		err_ret = sdio_readsb(sdiodev->func[func],
-				      ((u8 *) (pkt->data)), addr, pktlen);
-	} else {
-		err_ret = sdio_memcpy_fromio(sdiodev->func[func],
-					     ((u8 *) (pkt->data)),
-					     addr, pktlen);
-	}
-
-	return err_ret;
-}
-
-/*
- * This function takes a queue of packets. The packets on the queue
- * are assumed to be properly aligned by the caller.
- */
-int
-brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
-			  uint write, uint func, uint addr,
-			  struct sk_buff_head *pktq)
-{
-	bool fifo = (fix_inc == SDIOH_DATA_FIX);
-	u32 SGCount = 0;
-	int err_ret = 0;
-
-	struct sk_buff *pkt;
-
-	brcmf_dbg(SDIO, "Enter\n");
-
-	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_chain_wait);
-	if (brcmf_pm_resume_error(sdiodev))
-		return -EIO;
-
-	skb_queue_walk(pktq, pkt) {
-		uint pkt_len = pkt->len;
-		pkt_len += 3;
-		pkt_len &= 0xFFFFFFFC;
-
-		err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
-						   addr, pkt, pkt_len);
-		if (err_ret) {
-			brcmf_err("%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
-				  write ? "TX" : "RX", pkt, SGCount, addr,
-				  pkt_len, err_ret);
-		} else {
-			brcmf_dbg(SDIO, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
-				  write ? "TX" : "RX", pkt, SGCount, addr,
-				  pkt_len);
-		}
-		if (!fifo)
-			addr += pkt_len;
-
-		SGCount++;
-	}
-
-	brcmf_dbg(SDIO, "Exit\n");
-	return err_ret;
-}
-
-/*
- * This function takes a single DMA-able packet.
- */
-int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
-			       uint fix_inc, uint write, uint func, uint addr,
-			       struct sk_buff *pkt)
-{
-	int status;
-	uint pkt_len;
-	bool fifo = (fix_inc == SDIOH_DATA_FIX);
-
-	brcmf_dbg(SDIO, "Enter\n");
-
-	if (pkt == NULL)
-		return -EINVAL;
-	pkt_len = pkt->len;
-
-	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
-	if (brcmf_pm_resume_error(sdiodev))
-		return -EIO;
-
-	pkt_len += 3;
-	pkt_len &= (uint)~3;
-
-	status = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
-					   addr, pkt, pkt_len);
-	if (status) {
-		brcmf_err("%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
-			  write ? "TX" : "RX", pkt, addr, pkt_len, status);
-	} else {
-		brcmf_dbg(SDIO, "%s xfr'd %p, addr=0x%05x, len=%d\n",
-			  write ? "TX" : "RX", pkt, addr, pkt_len);
-	}
-
-	return status;
-}
-
 static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
 {
 	/* read 24 bits and return valid 17 bit addr */
@@ -468,7 +359,6 @@ static int brcmf_ops_sdio_probe(struct s
 	atomic_set(&sdiodev->suspend, false);
 	init_waitqueue_head(&sdiodev->request_byte_wait);
 	init_waitqueue_head(&sdiodev->request_word_wait);
-	init_waitqueue_head(&sdiodev->request_chain_wait);
 	init_waitqueue_head(&sdiodev->request_buffer_wait);
 
 	brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n");
@@ -606,7 +496,8 @@ static int brcmf_sdio_pd_remove(struct p
 static struct platform_driver brcmf_sdio_pd = {
 	.remove		= brcmf_sdio_pd_remove,
 	.driver		= {
-		.name	= BRCMFMAC_SDIO_PDATA_NAME
+		.name	= BRCMFMAC_SDIO_PDATA_NAME,
+		.owner	= THIS_MODULE,
 	}
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,7 @@
 #include "dhd_bus.h"
 #include "fwsignal.h"
 #include "dhd_dbg.h"
+#include "tracepoint.h"
 
 struct brcmf_proto_cdc_dcmd {
 	__le32 cmd;	/* dongle command value */
@@ -292,6 +293,7 @@ void brcmf_proto_hdrpush(struct brcmf_pu
 	h->flags2 = 0;
 	h->data_offset = offset;
 	BDC_SET_IF_IDX(h, ifidx);
+	trace_brcmf_bdchdr(pktbuf->data);
 }
 
 int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
@@ -309,6 +311,7 @@ int brcmf_proto_hdrpull(struct brcmf_pub
 		return -EBADE;
 	}
 
+	trace_brcmf_bdchdr(pktbuf->data);
 	h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
 
 	*ifidx = BDC_GET_IF_IDX(h);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c	2013-08-25 20:43:22.000000000 -0400
@@ -156,8 +156,11 @@ ssize_t brcmf_debugfs_fws_stats_read(str
 			"txs_suppr_core:    %u\n"
 			"txs_suppr_ps:      %u\n"
 			"txs_tossed:        %u\n"
+			"txs_host_tossed:   %u\n"
+			"bus_flow_block:    %u\n"
+			"fws_flow_block:    %u\n"
 			"send_pkts:         BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
-			"fifo_credits_sent: BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
+			"requested_sent:    BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
 			fwstats->header_pulls,
 			fwstats->header_only_pkt,
 			fwstats->tlv_parse_failed,
@@ -176,14 +179,17 @@ ssize_t brcmf_debugfs_fws_stats_read(str
 			fwstats->txs_supp_core,
 			fwstats->txs_supp_ps,
 			fwstats->txs_tossed,
+			fwstats->txs_host_tossed,
+			fwstats->bus_flow_block,
+			fwstats->fws_flow_block,
 			fwstats->send_pkts[0], fwstats->send_pkts[1],
 			fwstats->send_pkts[2], fwstats->send_pkts[3],
 			fwstats->send_pkts[4],
-			fwstats->fifo_credits_sent[0],
-			fwstats->fifo_credits_sent[1],
-			fwstats->fifo_credits_sent[2],
-			fwstats->fifo_credits_sent[3],
-			fwstats->fifo_credits_sent[4]);
+			fwstats->requested_sent[0],
+			fwstats->requested_sent[1],
+			fwstats->requested_sent[2],
+			fwstats->requested_sent[3],
+			fwstats->requested_sent[4]);
 
 	return simple_read_from_buffer(data, count, ppos, buf, res);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h	2013-08-25 20:43:22.000000000 -0400
@@ -141,8 +141,7 @@ struct brcmf_fws_stats {
 	u32 header_pulls;
 	u32 pkt2bus;
 	u32 send_pkts[5];
-	u32 fifo_credits_sent[5];
-	u32 fifo_credits_back[6];
+	u32 requested_sent[5];
 	u32 generic_error;
 	u32 mac_update_failed;
 	u32 mac_ps_update_failed;
@@ -158,6 +157,9 @@ struct brcmf_fws_stats {
 	u32 txs_supp_core;
 	u32 txs_supp_ps;
 	u32 txs_tossed;
+	u32 txs_host_tossed;
+	u32 bus_flow_block;
+	u32 fws_flow_block;
 };
 
 struct brcmf_pub;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd.h	2013-08-25 20:43:22.000000000 -0400
@@ -583,6 +583,7 @@ enum brcmf_netif_stop_reason {
  * @bssidx: index of bss associated with this interface.
  * @mac_addr: assigned mac address.
  * @netif_stop: bitmap indicates reason why netif queues are stopped.
+ * @netif_stop_lock: spinlock for update netif_stop from multiple sources.
  * @pend_8021x_cnt: tracks outstanding number of 802.1x frames.
  * @pend_8021x_wait: used for signalling change in count.
  */
@@ -598,6 +599,7 @@ struct brcmf_if {
 	s32 bssidx;
 	u8 mac_addr[ETH_ALEN];
 	u8 netif_stop;
+	spinlock_t netif_stop_lock;
 	atomic_t pend_8021x_cnt;
 	wait_queue_head_t pend_8021x_wait;
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c	2013-08-25 20:43:22.000000000 -0400
@@ -179,7 +179,7 @@ static netdev_tx_t brcmf_netdev_start_xm
 	struct brcmf_pub *drvr = ifp->drvr;
 	struct ethhdr *eh;
 
-	brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
+	brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
 
 	/* Can the device send data? */
 	if (drvr->bus_if->state != BRCMF_BUS_DATA) {
@@ -240,11 +240,15 @@ done:
 void brcmf_txflowblock_if(struct brcmf_if *ifp,
 			  enum brcmf_netif_stop_reason reason, bool state)
 {
-	if (!ifp)
+	unsigned long flags;
+
+	if (!ifp || !ifp->ndev)
 		return;
 
 	brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n",
 		  ifp->bssidx, ifp->netif_stop, reason, state);
+
+	spin_lock_irqsave(&ifp->netif_stop_lock, flags);
 	if (state) {
 		if (!ifp->netif_stop)
 			netif_stop_queue(ifp->ndev);
@@ -254,6 +258,7 @@ void brcmf_txflowblock_if(struct brcmf_i
 		if (!ifp->netif_stop)
 			netif_wake_queue(ifp->ndev);
 	}
+	spin_unlock_irqrestore(&ifp->netif_stop_lock, flags);
 }
 
 void brcmf_txflowblock(struct device *dev, bool state)
@@ -264,15 +269,18 @@ void brcmf_txflowblock(struct device *de
 
 	brcmf_dbg(TRACE, "Enter\n");
 
-	for (i = 0; i < BRCMF_MAX_IFS; i++)
-		brcmf_txflowblock_if(drvr->iflist[i],
-				     BRCMF_NETIF_STOP_REASON_BLOCK_BUS, state);
+	if (brcmf_fws_fc_active(drvr->fws)) {
+		brcmf_fws_bus_blocked(drvr, state);
+	} else {
+		for (i = 0; i < BRCMF_MAX_IFS; i++)
+			brcmf_txflowblock_if(drvr->iflist[i],
+					     BRCMF_NETIF_STOP_REASON_BLOCK_BUS,
+					     state);
+	}
 }
 
 void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
 {
-	unsigned char *eth;
-	uint len;
 	struct sk_buff *skb, *pnext;
 	struct brcmf_if *ifp;
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -280,7 +288,7 @@ void brcmf_rx_frames(struct device *dev,
 	u8 ifidx;
 	int ret;
 
-	brcmf_dbg(TRACE, "Enter\n");
+	brcmf_dbg(DATA, "Enter\n");
 
 	skb_queue_walk_safe(skb_list, skb, pnext) {
 		skb_unlink(skb, skb_list);
@@ -296,33 +304,12 @@ void brcmf_rx_frames(struct device *dev,
 			continue;
 		}
 
-		/* Get the protocol, maintain skb around eth_type_trans()
-		 * The main reason for this hack is for the limitation of
-		 * Linux 2.4 where 'eth_type_trans' uses the
-		 * 'net->hard_header_len'
-		 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
-		 * coping of the packet coming from the network stack to add
-		 * BDC, Hardware header etc, during network interface
-		 * registration
-		 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
-		 * required
-		 * for BDC, Hardware header etc. and not just the ETH_HLEN
-		 */
-		eth = skb->data;
-		len = skb->len;
-
 		skb->dev = ifp->ndev;
 		skb->protocol = eth_type_trans(skb, skb->dev);
 
 		if (skb->pkt_type == PACKET_MULTICAST)
 			ifp->stats.multicast++;
 
-		skb->data = eth;
-		skb->len = len;
-
-		/* Strip header, count, deliver upward */
-		skb_pull(skb, ETH_HLEN);
-
 		/* Process special event packets */
 		brcmf_fweh_process_skb(drvr, skb);
 
@@ -338,10 +325,8 @@ void brcmf_rx_frames(struct device *dev,
 			netif_rx(skb);
 		else
 			/* If the receive is not processed inside an ISR,
-			 * the softirqd must be woken explicitly to service
-			 * the NET_RX_SOFTIRQ.  In 2.6 kernels, this is handled
-			 * by netif_rx_ni(), but in earlier kernels, we need
-			 * to do it manually.
+			 * the softirqd must be woken explicitly to service the
+			 * NET_RX_SOFTIRQ. This is handled by netif_rx_ni().
 			 */
 			netif_rx_ni(skb);
 	}
@@ -630,7 +615,7 @@ int brcmf_net_attach(struct brcmf_if *if
 	/* set appropriate operations */
 	ndev->netdev_ops = &brcmf_netdev_ops_pri;
 
-	ndev->hard_header_len = ETH_HLEN + drvr->hdrlen;
+	ndev->hard_header_len += drvr->hdrlen;
 	ndev->ethtool_ops = &brcmf_ethtool_ops;
 
 	drvr->rxsz = ndev->mtu + ndev->hard_header_len +
@@ -779,6 +764,7 @@ struct brcmf_if *brcmf_add_if(struct brc
 	ifp->bssidx = bssidx;
 
 	init_waitqueue_head(&ifp->pend_8021x_wait);
+	spin_lock_init(&ifp->netif_stop_lock);
 
 	if (mac_addr != NULL)
 		memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c	2013-07-01 10:38:10.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c	2013-08-31 17:57:45.000000000 -0400
@@ -447,8 +447,6 @@ struct brcmf_sdio {
 	uint rxblen;		/* Allocated length of rxbuf */
 	u8 *rxctl;		/* Aligned pointer into rxbuf */
 	u8 *rxctl_orig;		/* pointer for freeing rxctl */
-	u8 *databuf;		/* Buffer for receiving big glom packet */
-	u8 *dataptr;		/* Aligned pointer into databuf */
 	uint rxlen;		/* Length of valid data in buffer */
 	spinlock_t rxctl_lock;	/* protection lock for ctrl frame resources */
 
@@ -472,8 +470,6 @@ struct brcmf_sdio {
 	s32 idletime;		/* Control for activity timeout */
 	s32 idlecount;	/* Activity timeout counter */
 	s32 idleclock;	/* How to set bus driver when idle */
-	s32 sd_rxchain;
-	bool use_rxchain;	/* If brcmf should use PKT chains */
 	bool rxflow_mode;	/* Rx flow control mode */
 	bool rxflow;		/* Is rx flow control on */
 	bool alp_only;		/* Don't use HT clock (ALP only) */
@@ -494,8 +490,7 @@ struct brcmf_sdio {
 
 	struct workqueue_struct *brcmf_wq;
 	struct work_struct datawork;
-	struct list_head dpc_tsklst;
-	spinlock_t dpc_tl_lock;
+	atomic_t dpc_tskcnt;
 
 	const struct firmware *firmware;
 	u32 fw_ptr;
@@ -1025,29 +1020,6 @@ static void brcmf_sdbrcm_rxfail(struct b
 		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 }
 
-/* copy a buffer into a pkt buffer chain */
-static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_sdio *bus, uint len)
-{
-	uint n, ret = 0;
-	struct sk_buff *p;
-	u8 *buf;
-
-	buf = bus->dataptr;
-
-	/* copy the data */
-	skb_queue_walk(&bus->glom, p) {
-		n = min_t(uint, p->len, len);
-		memcpy(p->data, buf, n);
-		buf += n;
-		len -= n;
-		ret += n;
-		if (!len)
-			break;
-	}
-
-	return ret;
-}
-
 /* return total length of buffer chain */
 static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus)
 {
@@ -1201,8 +1173,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brc
 	int errcode;
 	u8 doff, sfdoff;
 
-	bool usechain = bus->use_rxchain;
-
 	struct brcmf_sdio_read rd_new;
 
 	/* If packets, issue read(s) and send up packet chain */
@@ -1237,7 +1207,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brc
 			if (sublen % BRCMF_SDALIGN) {
 				brcmf_err("sublen %d not multiple of %d\n",
 					  sublen, BRCMF_SDALIGN);
-				usechain = false;
 			}
 			totlen += sublen;
 
@@ -1304,27 +1273,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brc
 		 * packet and and copy into the chain.
 		 */
 		sdio_claim_host(bus->sdiodev->func[1]);
-		if (usechain) {
-			errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
-					bus->sdiodev->sbwad,
-					SDIO_FUNC_2, F2SYNC, &bus->glom);
-		} else if (bus->dataptr) {
-			errcode = brcmf_sdcard_recv_buf(bus->sdiodev,
-					bus->sdiodev->sbwad,
-					SDIO_FUNC_2, F2SYNC,
-					bus->dataptr, dlen);
-			sublen = (u16) brcmf_sdbrcm_glom_from_buf(bus, dlen);
-			if (sublen != dlen) {
-				brcmf_err("FAILED TO COPY, dlen %d sublen %d\n",
-					  dlen, sublen);
-				errcode = -1;
-			}
-			pnext = NULL;
-		} else {
-			brcmf_err("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
-				  dlen);
-			errcode = -1;
-		}
+		errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
+				bus->sdiodev->sbwad,
+				SDIO_FUNC_2, F2SYNC, &bus->glom);
 		sdio_release_host(bus->sdiodev->func[1]);
 		bus->sdcnt.f2rxdata++;
 
@@ -2060,23 +2011,6 @@ static inline void brcmf_sdbrcm_clrintr(
 	}
 }
 
-static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus)
-{
-	struct list_head *new_hd;
-	unsigned long flags;
-
-	if (in_interrupt())
-		new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
-	else
-		new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL);
-	if (new_hd == NULL)
-		return;
-
-	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-	list_add_tail(new_hd, &bus->dpc_tsklst);
-	spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
-}
-
 static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
 {
 	u8 idx;
@@ -2311,7 +2245,7 @@ static void brcmf_sdbrcm_dpc(struct brcm
 		   (!atomic_read(&bus->fcstate) &&
 		    brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
 		    data_ok(bus)) || PKT_AVAILABLE()) {
-		brcmf_sdbrcm_adddpctsk(bus);
+		atomic_inc(&bus->dpc_tskcnt);
 	}
 
 	/* If we're done for now, turn off clock request. */
@@ -2341,7 +2275,6 @@ static int brcmf_sdbrcm_bus_txdata(struc
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 	struct brcmf_sdio *bus = sdiodev->bus;
-	unsigned long flags;
 
 	brcmf_dbg(TRACE, "Enter\n");
 
@@ -2368,26 +2301,21 @@ static int brcmf_sdbrcm_bus_txdata(struc
 	} else {
 		ret = 0;
 	}
-	spin_unlock_bh(&bus->txqlock);
 
 	if (pktq_len(&bus->txq) >= TXHI) {
 		bus->txoff = true;
 		brcmf_txflowblock(bus->sdiodev->dev, true);
 	}
+	spin_unlock_bh(&bus->txqlock);
 
 #ifdef DEBUG
 	if (pktq_plen(&bus->txq, prec) > qcount[prec])
 		qcount[prec] = pktq_plen(&bus->txq, prec);
 #endif
 
-	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-	if (list_empty(&bus->dpc_tsklst)) {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
-
-		brcmf_sdbrcm_adddpctsk(bus);
+	if (atomic_read(&bus->dpc_tskcnt) == 0) {
+		atomic_inc(&bus->dpc_tskcnt);
 		queue_work(bus->brcmf_wq, &bus->datawork);
-	} else {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
 	}
 
 	return ret;
@@ -2524,7 +2452,6 @@ brcmf_sdbrcm_bus_txctl(struct device *de
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 	struct brcmf_sdio *bus = sdiodev->bus;
-	unsigned long flags;
 
 	brcmf_dbg(TRACE, "Enter\n");
 
@@ -2611,18 +2538,13 @@ brcmf_sdbrcm_bus_txctl(struct device *de
 		} while (ret < 0 && retries++ < TXRETRIES);
 	}
 
-	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
 	if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) &&
-	    list_empty(&bus->dpc_tsklst)) {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
-
+	    atomic_read(&bus->dpc_tskcnt) == 0) {
 		bus->activity = false;
 		sdio_claim_host(bus->sdiodev->func[1]);
 		brcmf_dbg(INFO, "idle\n");
 		brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
 		sdio_release_host(bus->sdiodev->func[1]);
-	} else {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
 	}
 
 	if (ret)
@@ -3450,7 +3372,7 @@ void brcmf_sdbrcm_isr(void *arg)
 	if (!bus->intr)
 		brcmf_err("isr w/o interrupt configured!\n");
 
-	brcmf_sdbrcm_adddpctsk(bus);
+	atomic_inc(&bus->dpc_tskcnt);
 	queue_work(bus->brcmf_wq, &bus->datawork);
 }
 
@@ -3459,7 +3381,6 @@ static bool brcmf_sdbrcm_bus_watchdog(st
 #ifdef DEBUG
 	struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
 #endif	/* DEBUG */
-	unsigned long flags;
 
 	brcmf_dbg(TIMER, "Enter\n");
 
@@ -3475,11 +3396,9 @@ static bool brcmf_sdbrcm_bus_watchdog(st
 		if (!bus->intr ||
 		    (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) {
 
-			spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-			if (list_empty(&bus->dpc_tsklst)) {
+			if (atomic_read(&bus->dpc_tskcnt) == 0) {
 				u8 devpend;
-				spin_unlock_irqrestore(&bus->dpc_tl_lock,
-						       flags);
+
 				sdio_claim_host(bus->sdiodev->func[1]);
 				devpend = brcmf_sdio_regrb(bus->sdiodev,
 							   SDIO_CCCR_INTx,
@@ -3488,9 +3407,6 @@ static bool brcmf_sdbrcm_bus_watchdog(st
 				intstatus =
 				    devpend & (INTR_STATUS_FUNC1 |
 					       INTR_STATUS_FUNC2);
-			} else {
-				spin_unlock_irqrestore(&bus->dpc_tl_lock,
-						       flags);
 			}
 
 			/* If there is something, make like the ISR and
@@ -3499,7 +3415,7 @@ static bool brcmf_sdbrcm_bus_watchdog(st
 				bus->sdcnt.pollcnt++;
 				atomic_set(&bus->ipend, 1);
 
-				brcmf_sdbrcm_adddpctsk(bus);
+				atomic_inc(&bus->dpc_tskcnt);
 				queue_work(bus->brcmf_wq, &bus->datawork);
 			}
 		}
@@ -3544,41 +3460,15 @@ static bool brcmf_sdbrcm_bus_watchdog(st
 	return (atomic_read(&bus->ipend) > 0);
 }
 
-static bool brcmf_sdbrcm_chipmatch(u16 chipid)
-{
-	if (chipid == BCM43143_CHIP_ID)
-		return true;
-	if (chipid == BCM43241_CHIP_ID)
-		return true;
-	if (chipid == BCM4329_CHIP_ID)
-		return true;
-	if (chipid == BCM4330_CHIP_ID)
-		return true;
-	if (chipid == BCM4334_CHIP_ID)
-		return true;
-	if (chipid == BCM4335_CHIP_ID)
-		return true;
-	return false;
-}
-
 static void brcmf_sdio_dataworker(struct work_struct *work)
 {
 	struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio,
 					      datawork);
-	struct list_head *cur_hd, *tmp_hd;
-	unsigned long flags;
-
-	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-	list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
 
+	while (atomic_read(&bus->dpc_tskcnt)) {
 		brcmf_sdbrcm_dpc(bus);
-
-		spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-		list_del(cur_hd);
-		kfree(cur_hd);
+		atomic_dec(&bus->dpc_tskcnt);
 	}
-	spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
 }
 
 static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus)
@@ -3588,9 +3478,6 @@ static void brcmf_sdbrcm_release_malloc(
 	kfree(bus->rxbuf);
 	bus->rxctl = bus->rxbuf = NULL;
 	bus->rxlen = 0;
-
-	kfree(bus->databuf);
-	bus->databuf = NULL;
 }
 
 static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
@@ -3603,29 +3490,10 @@ static bool brcmf_sdbrcm_probe_malloc(st
 			    ALIGNMENT) + BRCMF_SDALIGN;
 		bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
 		if (!(bus->rxbuf))
-			goto fail;
-	}
-
-	/* Allocate buffer to receive glomed packet */
-	bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
-	if (!(bus->databuf)) {
-		/* release rxbuf which was already located as above */
-		if (!bus->rxblen)
-			kfree(bus->rxbuf);
-		goto fail;
+			return false;
 	}
 
-	/* Align the buffer */
-	if ((unsigned long)bus->databuf % BRCMF_SDALIGN)
-		bus->dataptr = bus->databuf + (BRCMF_SDALIGN -
-			       ((unsigned long)bus->databuf % BRCMF_SDALIGN));
-	else
-		bus->dataptr = bus->databuf;
-
 	return true;
-
-fail:
-	return false;
 }
 
 static bool
@@ -3666,11 +3534,6 @@ brcmf_sdbrcm_probe_attach(struct brcmf_s
 		goto fail;
 	}
 
-	if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) {
-		brcmf_err("unsupported chip: 0x%04x\n", bus->ci->chip);
-		goto fail;
-	}
-
 	if (brcmf_sdbrcm_kso_init(bus)) {
 		brcmf_err("error enabling KSO\n");
 		goto fail;
@@ -3769,10 +3632,6 @@ static bool brcmf_sdbrcm_probe_init(stru
 	bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
 	bus->roundup = min(max_roundup, bus->blocksize);
 
-	/* bus module does not support packet chaining */
-	bus->use_rxchain = false;
-	bus->sd_rxchain = false;
-
 	/* SR state */
 	bus->sleeping = false;
 	bus->sr_enabled = false;
@@ -3926,8 +3785,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, str
 		bus->watchdog_tsk = NULL;
 	}
 	/* Initialize DPC thread */
-	INIT_LIST_HEAD(&bus->dpc_tsklst);
-	spin_lock_init(&bus->dpc_tl_lock);
+	atomic_set(&bus->dpc_tskcnt, 0);
 
 	/* Assign bus interface call back */
 	bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/fweh.h	2013-08-25 20:43:22.000000000 -0400
@@ -101,7 +101,8 @@ struct brcmf_event;
 	BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \
 	BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
 	BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
-	BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75)
+	BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
+	BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
 
 #define BRCMF_ENUM_DEF(id, val) \
 	BRCMF_E_##id = (val),
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/etherdevice.h>
 #include <linux/err.h>
 #include <linux/jiffies.h>
-#include <uapi/linux/nl80211.h>
 #include <net/cfg80211.h>
 
 #include <brcmu_utils.h>
@@ -142,7 +141,7 @@ static const char *brcmf_fws_get_tlv_nam
 #define BRCMF_FWS_FLOWCONTROL_HIWATER			128
 #define BRCMF_FWS_FLOWCONTROL_LOWATER			64
 
-#define BRCMF_FWS_PSQ_PREC_COUNT		((NL80211_NUM_ACS + 1) * 2)
+#define BRCMF_FWS_PSQ_PREC_COUNT		((BRCMF_FWS_FIFO_COUNT + 1) * 2)
 #define BRCMF_FWS_PSQ_LEN				256
 
 #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST			0x01
@@ -157,11 +156,13 @@ static const char *brcmf_fws_get_tlv_nam
  * @BRCMF_FWS_SKBSTATE_NEW: sk_buff is newly arrived in the driver.
  * @BRCMF_FWS_SKBSTATE_DELAYED: sk_buff had to wait on queue.
  * @BRCMF_FWS_SKBSTATE_SUPPRESSED: sk_buff has been suppressed by firmware.
+ * @BRCMF_FWS_SKBSTATE_TIM: allocated for TIM update info.
  */
 enum brcmf_fws_skb_state {
 	BRCMF_FWS_SKBSTATE_NEW,
 	BRCMF_FWS_SKBSTATE_DELAYED,
-	BRCMF_FWS_SKBSTATE_SUPPRESSED
+	BRCMF_FWS_SKBSTATE_SUPPRESSED,
+	BRCMF_FWS_SKBSTATE_TIM
 };
 
 /**
@@ -193,9 +194,8 @@ struct brcmf_skbuff_cb {
  *	b[11]  - packet sent upon firmware request.
  *	b[10]  - packet only contains signalling data.
  *	b[9]   - packet is a tx packet.
- *	b[8]   - packet uses FIFO credit (non-pspoll).
+ *	b[8]   - packet used requested credit
  *	b[7]   - interface in AP mode.
- *	b[6:4] - AC FIFO number.
  *	b[3:0] - interface index.
  */
 #define BRCMF_SKB_IF_FLAGS_REQUESTED_MASK	0x0800
@@ -204,12 +204,10 @@ struct brcmf_skbuff_cb {
 #define BRCMF_SKB_IF_FLAGS_SIGNAL_ONLY_SHIFT	10
 #define BRCMF_SKB_IF_FLAGS_TRANSMIT_MASK        0x0200
 #define BRCMF_SKB_IF_FLAGS_TRANSMIT_SHIFT	9
-#define BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK	0x0100
-#define BRCMF_SKB_IF_FLAGS_CREDITCHECK_SHIFT	8
+#define BRCMF_SKB_IF_FLAGS_REQ_CREDIT_MASK	0x0100
+#define BRCMF_SKB_IF_FLAGS_REQ_CREDIT_SHIFT	8
 #define BRCMF_SKB_IF_FLAGS_IF_AP_MASK		0x0080
 #define BRCMF_SKB_IF_FLAGS_IF_AP_SHIFT		7
-#define BRCMF_SKB_IF_FLAGS_FIFO_MASK		0x0070
-#define BRCMF_SKB_IF_FLAGS_FIFO_SHIFT		4
 #define BRCMF_SKB_IF_FLAGS_INDEX_MASK		0x000f
 #define BRCMF_SKB_IF_FLAGS_INDEX_SHIFT		0
 
@@ -246,7 +244,7 @@ struct brcmf_skbuff_cb {
 #define BRCMF_SKB_HTOD_TAG_HSLOT_MASK			0x00ffff00
 #define BRCMF_SKB_HTOD_TAG_HSLOT_SHIFT			8
 #define BRCMF_SKB_HTOD_TAG_FREERUN_MASK			0x000000ff
-#define BRCMF_SKB_HTOD_TAG_FREERUN_SHIFT			0
+#define BRCMF_SKB_HTOD_TAG_FREERUN_SHIFT		0
 
 #define brcmf_skb_htod_tag_set_field(skb, field, value) \
 	brcmu_maskset32(&(brcmf_skbcb(skb)->htod), \
@@ -278,6 +276,7 @@ struct brcmf_skbuff_cb {
 /**
  * enum brcmf_fws_fifo - fifo indices used by dongle firmware.
  *
+ * @BRCMF_FWS_FIFO_FIRST: first fifo, ie. background.
  * @BRCMF_FWS_FIFO_AC_BK: fifo for background traffic.
  * @BRCMF_FWS_FIFO_AC_BE: fifo for best-effort traffic.
  * @BRCMF_FWS_FIFO_AC_VI: fifo for video traffic.
@@ -287,7 +286,8 @@ struct brcmf_skbuff_cb {
  * @BRCMF_FWS_FIFO_COUNT: number of fifos.
  */
 enum brcmf_fws_fifo {
-	BRCMF_FWS_FIFO_AC_BK,
+	BRCMF_FWS_FIFO_FIRST,
+	BRCMF_FWS_FIFO_AC_BK = BRCMF_FWS_FIFO_FIRST,
 	BRCMF_FWS_FIFO_AC_BE,
 	BRCMF_FWS_FIFO_AC_VI,
 	BRCMF_FWS_FIFO_AC_VO,
@@ -307,12 +307,15 @@ enum brcmf_fws_fifo {
  *	firmware suppress the packet as device is already in PS mode.
  * @BRCMF_FWS_TXSTATUS_FW_TOSSED:
  *	firmware tossed the packet.
+ * @BRCMF_FWS_TXSTATUS_HOST_TOSSED:
+ *	host tossed the packet.
  */
 enum brcmf_fws_txstatus {
 	BRCMF_FWS_TXSTATUS_DISCARD,
 	BRCMF_FWS_TXSTATUS_CORE_SUPPRESS,
 	BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS,
-	BRCMF_FWS_TXSTATUS_FW_TOSSED
+	BRCMF_FWS_TXSTATUS_FW_TOSSED,
+	BRCMF_FWS_TXSTATUS_HOST_TOSSED
 };
 
 enum brcmf_fws_fcmode {
@@ -343,6 +346,7 @@ enum brcmf_fws_mac_desc_state {
  * @transit_count: packet in transit to firmware.
  */
 struct brcmf_fws_mac_descriptor {
+	char name[16];
 	u8 occupied;
 	u8 mac_handle;
 	u8 interface_id;
@@ -356,7 +360,6 @@ struct brcmf_fws_mac_descriptor {
 	u8 seq[BRCMF_FWS_FIFO_COUNT];
 	struct pktq psq;
 	int transit_count;
-	int suppress_count;
 	int suppr_transit_count;
 	bool send_tim_signal;
 	u8 traffic_pending_bmp;
@@ -383,12 +386,10 @@ enum brcmf_fws_hanger_item_state {
  * struct brcmf_fws_hanger_item - single entry for tx pending packet.
  *
  * @state: entry is either free or occupied.
- * @gen: generation.
  * @pkt: packet itself.
  */
 struct brcmf_fws_hanger_item {
 	enum brcmf_fws_hanger_item_state state;
-	u8 gen;
 	struct sk_buff *pkt;
 };
 
@@ -424,6 +425,7 @@ struct brcmf_fws_info {
 	struct brcmf_fws_stats stats;
 	struct brcmf_fws_hanger hanger;
 	enum brcmf_fws_fcmode fcmode;
+	bool bcmc_credit_check;
 	struct brcmf_fws_macdesc_table desc;
 	struct workqueue_struct *fws_wq;
 	struct work_struct fws_dequeue_work;
@@ -434,6 +436,8 @@ struct brcmf_fws_info {
 	u32 fifo_credit_map;
 	u32 fifo_delay_map;
 	unsigned long borrow_defer_timestamp;
+	bool bus_flow_blocked;
+	bool creditmap_received;
 };
 
 /*
@@ -507,7 +511,6 @@ static void brcmf_fws_hanger_init(struct
 {
 	int i;
 
-	brcmf_dbg(TRACE, "enter\n");
 	memset(hanger, 0, sizeof(*hanger));
 	for (i = 0; i < ARRAY_SIZE(hanger->items); i++)
 		hanger->items[i].state = BRCMF_FWS_HANGER_ITEM_STATE_FREE;
@@ -517,7 +520,6 @@ static u32 brcmf_fws_hanger_get_free_slo
 {
 	u32 i;
 
-	brcmf_dbg(TRACE, "enter\n");
 	i = (h->slot_pos + 1) % BRCMF_FWS_HANGER_MAXITEMS;
 
 	while (i != h->slot_pos) {
@@ -533,14 +535,12 @@ static u32 brcmf_fws_hanger_get_free_slo
 	h->failed_slotfind++;
 	i = BRCMF_FWS_HANGER_MAXITEMS;
 done:
-	brcmf_dbg(TRACE, "exit: %d\n", i);
 	return i;
 }
 
 static int brcmf_fws_hanger_pushpkt(struct brcmf_fws_hanger *h,
-					   struct sk_buff *pkt, u32 slot_id)
+				    struct sk_buff *pkt, u32 slot_id)
 {
-	brcmf_dbg(TRACE, "enter\n");
 	if (slot_id >= BRCMF_FWS_HANGER_MAXITEMS)
 		return -ENOENT;
 
@@ -560,7 +560,6 @@ static int brcmf_fws_hanger_poppkt(struc
 					  u32 slot_id, struct sk_buff **pktout,
 					  bool remove_item)
 {
-	brcmf_dbg(TRACE, "enter\n");
 	if (slot_id >= BRCMF_FWS_HANGER_MAXITEMS)
 		return -ENOENT;
 
@@ -574,23 +573,18 @@ static int brcmf_fws_hanger_poppkt(struc
 	if (remove_item) {
 		h->items[slot_id].state = BRCMF_FWS_HANGER_ITEM_STATE_FREE;
 		h->items[slot_id].pkt = NULL;
-		h->items[slot_id].gen = 0xff;
 		h->popped++;
 	}
 	return 0;
 }
 
 static int brcmf_fws_hanger_mark_suppressed(struct brcmf_fws_hanger *h,
-						   u32 slot_id, u8 gen)
+					    u32 slot_id)
 {
-	brcmf_dbg(TRACE, "enter\n");
-
 	if (slot_id >= BRCMF_FWS_HANGER_MAXITEMS)
 		return -ENOENT;
 
-	h->items[slot_id].gen = gen;
-
-	if (h->items[slot_id].state != BRCMF_FWS_HANGER_ITEM_STATE_INUSE) {
+	if (h->items[slot_id].state == BRCMF_FWS_HANGER_ITEM_STATE_FREE) {
 		brcmf_err("entry not in use\n");
 		return -EINVAL;
 	}
@@ -599,25 +593,6 @@ static int brcmf_fws_hanger_mark_suppres
 	return 0;
 }
 
-static int brcmf_fws_hanger_get_genbit(struct brcmf_fws_hanger *hanger,
-					      struct sk_buff *pkt, u32 slot_id,
-					      int *gen)
-{
-	brcmf_dbg(TRACE, "enter\n");
-	*gen = 0xff;
-
-	if (slot_id >= BRCMF_FWS_HANGER_MAXITEMS)
-		return -ENOENT;
-
-	if (hanger->items[slot_id].state == BRCMF_FWS_HANGER_ITEM_STATE_FREE) {
-		brcmf_err("slot not in use\n");
-		return -EINVAL;
-	}
-
-	*gen = hanger->items[slot_id].gen;
-	return 0;
-}
-
 static void brcmf_fws_hanger_cleanup(struct brcmf_fws_info *fws,
 				     bool (*fn)(struct sk_buff *, void *),
 				     int ifidx)
@@ -627,7 +602,6 @@ static void brcmf_fws_hanger_cleanup(str
 	int i;
 	enum brcmf_fws_hanger_item_state s;
 
-	brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
 	for (i = 0; i < ARRAY_SIZE(h->items); i++) {
 		s = h->items[i].state;
 		if (s == BRCMF_FWS_HANGER_ITEM_STATE_INUSE ||
@@ -644,14 +618,28 @@ static void brcmf_fws_hanger_cleanup(str
 	}
 }
 
-static void brcmf_fws_init_mac_descriptor(struct brcmf_fws_mac_descriptor *desc,
-					  u8 *addr, u8 ifidx)
+static void brcmf_fws_macdesc_set_name(struct brcmf_fws_info *fws,
+				       struct brcmf_fws_mac_descriptor *desc)
+{
+	if (desc == &fws->desc.other)
+		strlcpy(desc->name, "MAC-OTHER", sizeof(desc->name));
+	else if (desc->mac_handle)
+		scnprintf(desc->name, sizeof(desc->name), "MAC-%d:%d",
+			  desc->mac_handle, desc->interface_id);
+	else
+		scnprintf(desc->name, sizeof(desc->name), "MACIF:%d",
+			  desc->interface_id);
+}
+
+static void brcmf_fws_macdesc_init(struct brcmf_fws_mac_descriptor *desc,
+				   u8 *addr, u8 ifidx)
 {
 	brcmf_dbg(TRACE,
 		  "enter: desc %p ea=%pM, ifidx=%u\n", desc, addr, ifidx);
 	desc->occupied = 1;
 	desc->state = BRCMF_FWS_STATE_OPEN;
 	desc->requested_credit = 0;
+	desc->requested_packet = 0;
 	/* depending on use may need ifp->bssidx instead */
 	desc->interface_id = ifidx;
 	desc->ac_bitmap = 0xff; /* update this when handling APSD */
@@ -660,22 +648,22 @@ static void brcmf_fws_init_mac_descripto
 }
 
 static
-void brcmf_fws_clear_mac_descriptor(struct brcmf_fws_mac_descriptor *desc)
+void brcmf_fws_macdesc_deinit(struct brcmf_fws_mac_descriptor *desc)
 {
 	brcmf_dbg(TRACE,
 		  "enter: ea=%pM, ifidx=%u\n", desc->ea, desc->interface_id);
 	desc->occupied = 0;
 	desc->state = BRCMF_FWS_STATE_CLOSE;
 	desc->requested_credit = 0;
+	desc->requested_packet = 0;
 }
 
 static struct brcmf_fws_mac_descriptor *
-brcmf_fws_mac_descriptor_lookup(struct brcmf_fws_info *fws, u8 *ea)
+brcmf_fws_macdesc_lookup(struct brcmf_fws_info *fws, u8 *ea)
 {
 	struct brcmf_fws_mac_descriptor *entry;
 	int i;
 
-	brcmf_dbg(TRACE, "enter: ea=%pM\n", ea);
 	if (ea == NULL)
 		return ERR_PTR(-EINVAL);
 
@@ -690,42 +678,33 @@ brcmf_fws_mac_descriptor_lookup(struct b
 }
 
 static struct brcmf_fws_mac_descriptor*
-brcmf_fws_find_mac_desc(struct brcmf_fws_info *fws, struct brcmf_if *ifp,
-			u8 *da)
+brcmf_fws_macdesc_find(struct brcmf_fws_info *fws, struct brcmf_if *ifp, u8 *da)
 {
 	struct brcmf_fws_mac_descriptor *entry = &fws->desc.other;
 	bool multicast;
-	enum nl80211_iftype iftype;
-
-	brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx);
 
 	multicast = is_multicast_ether_addr(da);
-	iftype = brcmf_cfg80211_get_iftype(ifp);
 
-	/* Multicast destination and P2P clients get the interface entry.
-	 * STA gets the interface entry if there is no exact match. For
-	 * example, TDLS destinations have their own entry.
+	/* Multicast destination, STA and P2P clients get the interface entry.
+	 * STA/GC gets the Mac Entry for TDLS destinations, TDLS destinations
+	 * have their own entry.
 	 */
-	entry = NULL;
-	if ((multicast || iftype == NL80211_IFTYPE_STATION ||
-	     iftype == NL80211_IFTYPE_P2P_CLIENT) && ifp->fws_desc)
+	if (multicast && ifp->fws_desc) {
 		entry = ifp->fws_desc;
-
-	if (entry != NULL && iftype != NL80211_IFTYPE_STATION)
 		goto done;
+	}
 
-	entry = brcmf_fws_mac_descriptor_lookup(fws, da);
+	entry = brcmf_fws_macdesc_lookup(fws, da);
 	if (IS_ERR(entry))
-		entry = &fws->desc.other;
+		entry = ifp->fws_desc;
 
 done:
-	brcmf_dbg(TRACE, "exit: entry=%p\n", entry);
 	return entry;
 }
 
-static bool brcmf_fws_mac_desc_closed(struct brcmf_fws_info *fws,
-				      struct brcmf_fws_mac_descriptor *entry,
-				      int fifo)
+static bool brcmf_fws_macdesc_closed(struct brcmf_fws_info *fws,
+				     struct brcmf_fws_mac_descriptor *entry,
+				     int fifo)
 {
 	struct brcmf_fws_mac_descriptor *if_entry;
 	bool closed;
@@ -748,15 +727,11 @@ static bool brcmf_fws_mac_desc_closed(st
 	return closed || !(entry->ac_bitmap & BIT(fifo));
 }
 
-static void brcmf_fws_mac_desc_cleanup(struct brcmf_fws_info *fws,
-				       struct brcmf_fws_mac_descriptor *entry,
-				       int ifidx)
+static void brcmf_fws_macdesc_cleanup(struct brcmf_fws_info *fws,
+				      struct brcmf_fws_mac_descriptor *entry,
+				      int ifidx)
 {
-	brcmf_dbg(TRACE, "enter: entry=(ea=%pM, ifid=%d), ifidx=%d\n",
-		  entry->ea, entry->interface_id, ifidx);
 	if (entry->occupied && (ifidx == -1 || ifidx == entry->interface_id)) {
-		brcmf_dbg(TRACE, "flush psq: ifidx=%d, qlen=%d\n",
-			  ifidx, entry->psq.len);
 		brcmf_fws_psq_flush(fws, &entry->psq, ifidx);
 		entry->occupied = !!(entry->psq.len);
 	}
@@ -772,7 +747,6 @@ static void brcmf_fws_bus_txq_cleanup(st
 	int prec;
 	u32 hslot;
 
-	brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
 	txq = brcmf_bus_gettxq(fws->drvr->bus_if);
 	if (IS_ERR(txq)) {
 		brcmf_dbg(TRACE, "no txq to clean up\n");
@@ -798,7 +772,6 @@ static void brcmf_fws_cleanup(struct brc
 	struct brcmf_fws_mac_descriptor *table;
 	bool (*matchfn)(struct sk_buff *, void *) = NULL;
 
-	brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
 	if (fws == NULL)
 		return;
 
@@ -808,51 +781,121 @@ static void brcmf_fws_cleanup(struct brc
 	/* cleanup individual nodes */
 	table = &fws->desc.nodes[0];
 	for (i = 0; i < ARRAY_SIZE(fws->desc.nodes); i++)
-		brcmf_fws_mac_desc_cleanup(fws, &table[i], ifidx);
+		brcmf_fws_macdesc_cleanup(fws, &table[i], ifidx);
 
-	brcmf_fws_mac_desc_cleanup(fws, &fws->desc.other, ifidx);
+	brcmf_fws_macdesc_cleanup(fws, &fws->desc.other, ifidx);
 	brcmf_fws_bus_txq_cleanup(fws, matchfn, ifidx);
 	brcmf_fws_hanger_cleanup(fws, matchfn, ifidx);
 }
 
-static void brcmf_fws_tim_update(struct brcmf_fws_info *ctx,
-				 struct brcmf_fws_mac_descriptor *entry,
-				 int prec)
+static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
 {
-	brcmf_dbg(TRACE, "enter: ea=%pM\n", entry->ea);
-	if (entry->state == BRCMF_FWS_STATE_CLOSE) {
-		/* check delayedQ and suppressQ in one call using bitmap */
-		if (brcmu_pktq_mlen(&entry->psq, 3 << (prec * 2)) == 0)
-			entry->traffic_pending_bmp =
-				entry->traffic_pending_bmp & ~NBITVAL(prec);
-		else
-			entry->traffic_pending_bmp =
-				entry->traffic_pending_bmp | NBITVAL(prec);
+	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
+	u8 *wlh;
+	u16 data_offset = 0;
+	u8 fillers;
+	__le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
+
+	brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n",
+		  entry->name, brcmf_skb_if_flags_get_field(skb, INDEX),
+		  le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff);
+	if (entry->send_tim_signal)
+		data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
+
+	/* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
+	data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
+	fillers = round_up(data_offset, 4) - data_offset;
+	data_offset += fillers;
+
+	skb_push(skb, data_offset);
+	wlh = skb->data;
+
+	wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
+	wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
+	memcpy(&wlh[2], &pkttag, sizeof(pkttag));
+	wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2;
+
+	if (entry->send_tim_signal) {
+		entry->send_tim_signal = 0;
+		wlh[0] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP;
+		wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
+		wlh[2] = entry->mac_handle;
+		wlh[3] = entry->traffic_pending_bmp;
+		brcmf_dbg(TRACE, "adding TIM info: handle %d bmp 0x%X\n",
+			  entry->mac_handle, entry->traffic_pending_bmp);
+		wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2;
+		entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
 	}
-	/* request a TIM update to firmware at the next piggyback opportunity */
+	if (fillers)
+		memset(wlh, BRCMF_FWS_TYPE_FILLER, fillers);
+
+	brcmf_proto_hdrpush(fws->drvr, brcmf_skb_if_flags_get_field(skb, INDEX),
+			    data_offset >> 2, skb);
+	return 0;
+}
+
+static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
+				 struct brcmf_fws_mac_descriptor *entry,
+				 int fifo, bool send_immediately)
+{
+	struct sk_buff *skb;
+	struct brcmf_bus *bus;
+	struct brcmf_skbuff_cb *skcb;
+	s32 err;
+	u32 len;
+
+	/* check delayedQ and suppressQ in one call using bitmap */
+	if (brcmu_pktq_mlen(&entry->psq, 3 << (fifo * 2)) == 0)
+		entry->traffic_pending_bmp &= ~NBITVAL(fifo);
+	else
+		entry->traffic_pending_bmp |= NBITVAL(fifo);
+
+	entry->send_tim_signal = false;
 	if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp)
 		entry->send_tim_signal = true;
+	if (send_immediately && entry->send_tim_signal &&
+	    entry->state == BRCMF_FWS_STATE_CLOSE) {
+		/* create a dummy packet and sent that. The traffic          */
+		/* bitmap info will automatically be attached to that packet */
+		len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 +
+		      BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 +
+		      4 + fws->drvr->hdrlen;
+		skb = brcmu_pkt_buf_get_skb(len);
+		if (skb == NULL)
+			return false;
+		skb_pull(skb, len);
+		skcb = brcmf_skbcb(skb);
+		skcb->mac = entry;
+		skcb->state = BRCMF_FWS_SKBSTATE_TIM;
+		bus = fws->drvr->bus_if;
+		err = brcmf_fws_hdrpush(fws, skb);
+		if (err == 0)
+			err = brcmf_bus_txdata(bus, skb);
+		if (err)
+			brcmu_pkt_buf_free_skb(skb);
+		return true;
+	}
+	return false;
 }
 
 static void
 brcmf_fws_flow_control_check(struct brcmf_fws_info *fws, struct pktq *pq,
 			     u8 if_id)
 {
-	struct brcmf_if *ifp = fws->drvr->iflist[if_id];
+	struct brcmf_if *ifp = fws->drvr->iflist[!if_id ? 0 : if_id + 1];
 
 	if (WARN_ON(!ifp))
 		return;
 
-	brcmf_dbg(TRACE,
-		  "enter: bssidx=%d, ifidx=%d\n", ifp->bssidx, ifp->ifidx);
-
 	if ((ifp->netif_stop & BRCMF_NETIF_STOP_REASON_FWS_FC) &&
 	    pq->len <= BRCMF_FWS_FLOWCONTROL_LOWATER)
 		brcmf_txflowblock_if(ifp,
 				     BRCMF_NETIF_STOP_REASON_FWS_FC, false);
 	if (!(ifp->netif_stop & BRCMF_NETIF_STOP_REASON_FWS_FC) &&
-	    pq->len >= BRCMF_FWS_FLOWCONTROL_HIWATER)
+	    pq->len >= BRCMF_FWS_FLOWCONTROL_HIWATER) {
+		fws->stats.fws_flow_block++;
 		brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FWS_FC, true);
+	}
 	return;
 }
 
@@ -862,10 +905,26 @@ static int brcmf_fws_rssi_indicate(struc
 	return 0;
 }
 
+/* using macro so sparse checking does not complain
+ * about locking imbalance.
+ */
+#define brcmf_fws_lock(drvr, flags)				\
+do {								\
+	flags = 0;						\
+	spin_lock_irqsave(&((drvr)->fws_spinlock), (flags));	\
+} while (0)
+
+/* using macro so sparse checking does not complain
+ * about locking imbalance.
+ */
+#define brcmf_fws_unlock(drvr, flags) \
+	spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
+
 static
 int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
 {
 	struct brcmf_fws_mac_descriptor *entry, *existing;
+	ulong flags;
 	u8 mac_handle;
 	u8 ifidx;
 	u8 *addr;
@@ -876,34 +935,44 @@ int brcmf_fws_macdesc_indicate(struct br
 
 	entry = &fws->desc.nodes[mac_handle & 0x1F];
 	if (type == BRCMF_FWS_TYPE_MACDESC_DEL) {
-		brcmf_dbg(TRACE, "deleting mac %pM idx %d\n", addr, ifidx);
 		if (entry->occupied) {
-			brcmf_fws_mac_desc_cleanup(fws, entry, -1);
-			brcmf_fws_clear_mac_descriptor(entry);
+			brcmf_dbg(TRACE, "deleting %s mac %pM\n",
+				  entry->name, addr);
+			brcmf_fws_lock(fws->drvr, flags);
+			brcmf_fws_macdesc_cleanup(fws, entry, -1);
+			brcmf_fws_macdesc_deinit(entry);
+			brcmf_fws_unlock(fws->drvr, flags);
 		} else
 			fws->stats.mac_update_failed++;
 		return 0;
 	}
 
-	brcmf_dbg(TRACE,
-		  "add mac %pM handle %u idx %d\n", addr, mac_handle, ifidx);
-	existing = brcmf_fws_mac_descriptor_lookup(fws, addr);
+	existing = brcmf_fws_macdesc_lookup(fws, addr);
 	if (IS_ERR(existing)) {
 		if (!entry->occupied) {
+			brcmf_fws_lock(fws->drvr, flags);
 			entry->mac_handle = mac_handle;
-			brcmf_fws_init_mac_descriptor(entry, addr, ifidx);
+			brcmf_fws_macdesc_init(entry, addr, ifidx);
+			brcmf_fws_macdesc_set_name(fws, entry);
 			brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT,
 					BRCMF_FWS_PSQ_LEN);
+			brcmf_fws_unlock(fws->drvr, flags);
+			brcmf_dbg(TRACE, "add %s mac %pM\n", entry->name, addr);
 		} else {
 			fws->stats.mac_update_failed++;
 		}
 	} else {
 		if (entry != existing) {
-			brcmf_dbg(TRACE, "relocate mac\n");
+			brcmf_dbg(TRACE, "copy mac %s\n", existing->name);
+			brcmf_fws_lock(fws->drvr, flags);
 			memcpy(entry, existing,
 			       offsetof(struct brcmf_fws_mac_descriptor, psq));
 			entry->mac_handle = mac_handle;
-			brcmf_fws_clear_mac_descriptor(existing);
+			brcmf_fws_macdesc_deinit(existing);
+			brcmf_fws_macdesc_set_name(fws, entry);
+			brcmf_fws_unlock(fws->drvr, flags);
+			brcmf_dbg(TRACE, "relocate %s mac %pM\n", entry->name,
+				  addr);
 		} else {
 			brcmf_dbg(TRACE, "use existing\n");
 			WARN_ON(entry->mac_handle != mac_handle);
@@ -917,8 +986,9 @@ static int brcmf_fws_macdesc_state_indic
 					    u8 type, u8 *data)
 {
 	struct brcmf_fws_mac_descriptor *entry;
+	ulong flags;
 	u8 mac_handle;
-	int i;
+	int ret;
 
 	mac_handle = data[0];
 	entry = &fws->desc.nodes[mac_handle & 0x1F];
@@ -926,30 +996,35 @@ static int brcmf_fws_macdesc_state_indic
 		fws->stats.mac_ps_update_failed++;
 		return -ESRCH;
 	}
-
-	/* a state update should wipe old credits? */
+	brcmf_fws_lock(fws->drvr, flags);
+	/* a state update should wipe old credits */
 	entry->requested_credit = 0;
+	entry->requested_packet = 0;
 	if (type == BRCMF_FWS_TYPE_MAC_OPEN) {
 		entry->state = BRCMF_FWS_STATE_OPEN;
-		return BRCMF_FWS_RET_OK_SCHEDULE;
+		ret = BRCMF_FWS_RET_OK_SCHEDULE;
 	} else {
 		entry->state = BRCMF_FWS_STATE_CLOSE;
-		for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++)
-			brcmf_fws_tim_update(fws, entry, i);
+		brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BK, false);
+		brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BE, false);
+		brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VI, false);
+		brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VO, true);
+		ret = BRCMF_FWS_RET_OK_NOSCHEDULE;
 	}
-	return BRCMF_FWS_RET_OK_NOSCHEDULE;
+	brcmf_fws_unlock(fws->drvr, flags);
+	return ret;
 }
 
 static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
 					      u8 type, u8 *data)
 {
 	struct brcmf_fws_mac_descriptor *entry;
+	ulong flags;
 	u8 ifidx;
 	int ret;
 
 	ifidx = data[0];
 
-	brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
 	if (ifidx >= BRCMF_MAX_IFS) {
 		ret = -ERANGE;
 		goto fail;
@@ -961,17 +1036,26 @@ static int brcmf_fws_interface_state_ind
 		goto fail;
 	}
 
+	brcmf_dbg(TRACE, "%s (%d): %s\n", brcmf_fws_get_tlv_name(type), type,
+		  entry->name);
+	brcmf_fws_lock(fws->drvr, flags);
 	switch (type) {
 	case BRCMF_FWS_TYPE_INTERFACE_OPEN:
 		entry->state = BRCMF_FWS_STATE_OPEN;
-		return BRCMF_FWS_RET_OK_SCHEDULE;
+		ret = BRCMF_FWS_RET_OK_SCHEDULE;
+		break;
 	case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
 		entry->state = BRCMF_FWS_STATE_CLOSE;
-		return BRCMF_FWS_RET_OK_NOSCHEDULE;
+		ret = BRCMF_FWS_RET_OK_NOSCHEDULE;
+		break;
 	default:
 		ret = -EINVAL;
-		break;
+		brcmf_fws_unlock(fws->drvr, flags);
+		goto fail;
 	}
+	brcmf_fws_unlock(fws->drvr, flags);
+	return ret;
+
 fail:
 	fws->stats.if_update_failed++;
 	return ret;
@@ -981,6 +1065,7 @@ static int brcmf_fws_request_indicate(st
 				      u8 *data)
 {
 	struct brcmf_fws_mac_descriptor *entry;
+	ulong flags;
 
 	entry = &fws->desc.nodes[data[1] & 0x1F];
 	if (!entry->occupied) {
@@ -991,15 +1076,51 @@ static int brcmf_fws_request_indicate(st
 		return -ESRCH;
 	}
 
+	brcmf_dbg(TRACE, "%s (%d): %s cnt %d bmp %d\n",
+		  brcmf_fws_get_tlv_name(type), type, entry->name,
+		  data[0], data[2]);
+	brcmf_fws_lock(fws->drvr, flags);
 	if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT)
 		entry->requested_credit = data[0];
 	else
 		entry->requested_packet = data[0];
 
 	entry->ac_bitmap = data[2];
+	brcmf_fws_unlock(fws->drvr, flags);
 	return BRCMF_FWS_RET_OK_SCHEDULE;
 }
 
+static void
+brcmf_fws_macdesc_use_req_credit(struct brcmf_fws_mac_descriptor *entry,
+				 struct sk_buff *skb)
+{
+	if (entry->requested_credit > 0) {
+		entry->requested_credit--;
+		brcmf_skb_if_flags_set_field(skb, REQUESTED, 1);
+		brcmf_skb_if_flags_set_field(skb, REQ_CREDIT, 1);
+		if (entry->state != BRCMF_FWS_STATE_CLOSE)
+			brcmf_err("requested credit set while mac not closed!\n");
+	} else if (entry->requested_packet > 0) {
+		entry->requested_packet--;
+		brcmf_skb_if_flags_set_field(skb, REQUESTED, 1);
+		brcmf_skb_if_flags_set_field(skb, REQ_CREDIT, 0);
+		if (entry->state != BRCMF_FWS_STATE_CLOSE)
+			brcmf_err("requested packet set while mac not closed!\n");
+	} else {
+		brcmf_skb_if_flags_set_field(skb, REQUESTED, 0);
+		brcmf_skb_if_flags_set_field(skb, REQ_CREDIT, 0);
+	}
+}
+
+static void brcmf_fws_macdesc_return_req_credit(struct sk_buff *skb)
+{
+	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
+
+	if ((brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) &&
+	    (entry->state == BRCMF_FWS_STATE_CLOSE))
+		entry->requested_credit++;
+}
+
 static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
 				     u8 fifo, u8 credits)
 {
@@ -1010,6 +1131,8 @@ static void brcmf_fws_return_credits(str
 	if (!credits)
 		return;
 
+	fws->fifo_credit_map |= 1 << fifo;
+
 	if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
 	    (fws->credits_borrowed[0])) {
 		for (lender_ac = BRCMF_FWS_FIFO_AC_VO; lender_ac >= 0;
@@ -1031,7 +1154,6 @@ static void brcmf_fws_return_credits(str
 		}
 	}
 
-	fws->fifo_credit_map |= 1 << fifo;
 	fws->fifo_credit[fifo] += credits;
 }
 
@@ -1042,27 +1164,6 @@ static void brcmf_fws_schedule_deq(struc
 		queue_work(fws->fws_wq, &fws->fws_dequeue_work);
 }
 
-static void brcmf_skb_pick_up_credit(struct brcmf_fws_info *fws, int fifo,
-				     struct sk_buff *p)
-{
-	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(p)->mac;
-
-	if (brcmf_skbcb(p)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
-		if (fws->fcmode != BRCMF_FWS_FCMODE_IMPLIED_CREDIT)
-			return;
-		brcmf_fws_return_credits(fws, fifo, 1);
-	} else {
-		/*
-		 * if this packet did not count against FIFO credit, it
-		 * must have taken a requested_credit from the destination
-		 * entry (for pspoll etc.)
-		 */
-		if (!brcmf_skb_if_flags_get_field(p, REQUESTED))
-			entry->requested_credit++;
-	}
-	brcmf_fws_schedule_deq(fws);
-}
-
 static int brcmf_fws_enq(struct brcmf_fws_info *fws,
 			 enum brcmf_fws_skb_state state, int fifo,
 			 struct sk_buff *p)
@@ -1078,7 +1179,7 @@ static int brcmf_fws_enq(struct brcmf_fw
 		return -ENOENT;
 	}
 
-	brcmf_dbg(TRACE, "enter: ea=%pM, qlen=%d\n", entry->ea, entry->psq.len);
+	brcmf_dbg(DATA, "enter: fifo %d skb %p\n", fifo, p);
 	if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
 		prec += 1;
 		qfull_stat = &fws->stats.supprq_full_error;
@@ -1095,14 +1196,12 @@ static int brcmf_fws_enq(struct brcmf_fw
 
 	/* update the sk_buff state */
 	brcmf_skbcb(p)->state = state;
-	if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED)
-		entry->suppress_count++;
 
 	/*
 	 * A packet has been pushed so update traffic
 	 * availability bitmap, if applicable
 	 */
-	brcmf_fws_tim_update(fws, entry, fifo);
+	brcmf_fws_tim_update(fws, entry, fifo, true);
 	brcmf_fws_flow_control_check(fws, &entry->psq,
 				     brcmf_skb_if_flags_get_field(p, INDEX));
 	return 0;
@@ -1113,7 +1212,6 @@ static struct sk_buff *brcmf_fws_deq(str
 	struct brcmf_fws_mac_descriptor *table;
 	struct brcmf_fws_mac_descriptor *entry;
 	struct sk_buff *p;
-	int use_credit = 1;
 	int num_nodes;
 	int node_pos;
 	int prec_out;
@@ -1127,7 +1225,7 @@ static struct sk_buff *brcmf_fws_deq(str
 	for (i = 0; i < num_nodes; i++) {
 		entry = &table[(node_pos + i) % num_nodes];
 		if (!entry->occupied ||
-		    brcmf_fws_mac_desc_closed(fws, entry, fifo))
+		    brcmf_fws_macdesc_closed(fws, entry, fifo))
 			continue;
 
 		if (entry->suppressed)
@@ -1137,9 +1235,8 @@ static struct sk_buff *brcmf_fws_deq(str
 		p = brcmu_pktq_mdeq(&entry->psq, pmsk << (fifo * 2), &prec_out);
 		if (p == NULL) {
 			if (entry->suppressed) {
-				if (entry->suppr_transit_count >
-				    entry->suppress_count)
-					return NULL;
+				if (entry->suppr_transit_count)
+					continue;
 				entry->suppressed = false;
 				p = brcmu_pktq_mdeq(&entry->psq,
 						    1 << (fifo * 2), &prec_out);
@@ -1148,26 +1245,7 @@ static struct sk_buff *brcmf_fws_deq(str
 		if  (p == NULL)
 			continue;
 
-		/* did the packet come from suppress sub-queue? */
-		if (entry->requested_credit > 0) {
-			entry->requested_credit--;
-			/*
-			 * if the packet was pulled out while destination is in
-			 * closed state but had a non-zero packets requested,
-			 * then this should not count against the FIFO credit.
-			 * That is due to the fact that the firmware will
-			 * most likely hold onto this packet until a suitable
-			 * time later to push it to the appropriate AC FIFO.
-			 */
-			if (entry->state == BRCMF_FWS_STATE_CLOSE)
-				use_credit = 0;
-		} else if (entry->requested_packet > 0) {
-			entry->requested_packet--;
-			brcmf_skb_if_flags_set_field(p, REQUESTED, 1);
-			if (entry->state == BRCMF_FWS_STATE_CLOSE)
-				use_credit = 0;
-		}
-		brcmf_skb_if_flags_set_field(p, CREDITCHECK, use_credit);
+		brcmf_fws_macdesc_use_req_credit(entry, p);
 
 		/* move dequeue position to ensure fair round-robin */
 		fws->deq_node_pos[fifo] = (node_pos + i + 1) % num_nodes;
@@ -1179,7 +1257,7 @@ static struct sk_buff *brcmf_fws_deq(str
 		 * A packet has been picked up, update traffic
 		 * availability bitmap, if applicable
 		 */
-		brcmf_fws_tim_update(fws, entry, fifo);
+		brcmf_fws_tim_update(fws, entry, fifo, false);
 
 		/*
 		 * decrement total enqueued fifo packets and
@@ -1192,7 +1270,7 @@ static struct sk_buff *brcmf_fws_deq(str
 	}
 	p = NULL;
 done:
-	brcmf_dbg(TRACE, "exit: fifo %d skb %p\n", fifo, p);
+	brcmf_dbg(DATA, "exit: fifo %d skb %p\n", fifo, p);
 	return p;
 }
 
@@ -1202,22 +1280,26 @@ static int brcmf_fws_txstatus_suppressed
 	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
 	u32 hslot;
 	int ret;
+	u8 ifidx;
 
 	hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
 
 	/* this packet was suppressed */
-	if (!entry->suppressed || entry->generation != genbit) {
+	if (!entry->suppressed) {
 		entry->suppressed = true;
-		entry->suppress_count = brcmu_pktq_mlen(&entry->psq,
-							1 << (fifo * 2 + 1));
 		entry->suppr_transit_count = entry->transit_count;
+		brcmf_dbg(DATA, "suppress %s: transit %d\n",
+			  entry->name, entry->transit_count);
 	}
 
 	entry->generation = genbit;
 
-	ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb);
+	ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
+	if (ret == 0)
+		ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
+				    skb);
 	if (ret != 0) {
-		/* suppress q is full, drop this packet */
+		/* suppress q is full or hdrpull failed, drop this packet */
 		brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
 					true);
 	} else {
@@ -1225,26 +1307,24 @@ static int brcmf_fws_txstatus_suppressed
 		 * Mark suppressed to avoid a double free during
 		 * wlfc cleanup
 		 */
-		brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot,
-						 genbit);
-		entry->suppress_count++;
+		brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot);
 	}
 
 	return ret;
 }
 
 static int
-brcmf_fws_txstatus_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
+brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
 			   u32 genbit)
 {
 	u32 fifo;
 	int ret;
 	bool remove_from_hanger = true;
 	struct sk_buff *skb;
+	struct brcmf_skbuff_cb *skcb;
 	struct brcmf_fws_mac_descriptor *entry = NULL;
 
-	brcmf_dbg(TRACE, "status: flags=0x%X, hslot=%d\n",
-		  flags, hslot);
+	brcmf_dbg(DATA, "flags %d\n", flags);
 
 	if (flags == BRCMF_FWS_TXSTATUS_DISCARD)
 		fws->stats.txs_discard++;
@@ -1256,6 +1336,8 @@ brcmf_fws_txstatus_process(struct brcmf_
 		remove_from_hanger = false;
 	} else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED)
 		fws->stats.txs_tossed++;
+	else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)
+		fws->stats.txs_host_tossed++;
 	else
 		brcmf_err("unexpected txstatus\n");
 
@@ -1266,32 +1348,42 @@ brcmf_fws_txstatus_process(struct brcmf_
 		return ret;
 	}
 
-	entry = brcmf_skbcb(skb)->mac;
+	skcb = brcmf_skbcb(skb);
+	entry = skcb->mac;
 	if (WARN_ON(!entry)) {
 		brcmu_pkt_buf_free_skb(skb);
 		return -EINVAL;
 	}
+	entry->transit_count--;
+	if (entry->suppressed && entry->suppr_transit_count)
+		entry->suppr_transit_count--;
+
+	brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
+		  skcb->htod);
 
 	/* pick up the implicit credit from this packet */
 	fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
-	brcmf_skb_pick_up_credit(fws, fifo, skb);
+	if ((fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT) ||
+	    (brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
+	    (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)) {
+		brcmf_fws_return_credits(fws, fifo, 1);
+		brcmf_fws_schedule_deq(fws);
+	}
+	brcmf_fws_macdesc_return_req_credit(skb);
 
 	if (!remove_from_hanger)
 		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit);
 
-	if (remove_from_hanger || ret) {
-		entry->transit_count--;
-		if (entry->suppressed)
-			entry->suppr_transit_count--;
-
+	if (remove_from_hanger || ret)
 		brcmf_txfinalize(fws->drvr, skb, true);
-	}
+
 	return 0;
 }
 
 static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
 					     u8 *data)
 {
+	ulong flags;
 	int i;
 
 	if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) {
@@ -1299,17 +1391,20 @@ static int brcmf_fws_fifocreditback_indi
 		return BRCMF_FWS_RET_OK_NOSCHEDULE;
 	}
 
-	brcmf_dbg(TRACE, "enter: data %pM\n", data);
+	brcmf_dbg(DATA, "enter: data %pM\n", data);
+	brcmf_fws_lock(fws->drvr, flags);
 	for (i = 0; i < BRCMF_FWS_FIFO_COUNT; i++)
 		brcmf_fws_return_credits(fws, i, data[i]);
 
-	brcmf_dbg(INFO, "map: credit %x delay %x\n", fws->fifo_credit_map,
+	brcmf_dbg(DATA, "map: credit %x delay %x\n", fws->fifo_credit_map,
 		  fws->fifo_delay_map);
+	brcmf_fws_unlock(fws->drvr, flags);
 	return BRCMF_FWS_RET_OK_SCHEDULE;
 }
 
 static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
 {
+	ulong lflags;
 	__le32 status_le;
 	u32 status;
 	u32 hslot;
@@ -1323,7 +1418,10 @@ static int brcmf_fws_txstatus_indicate(s
 	hslot = brcmf_txstatus_get_field(status, HSLOT);
 	genbit = brcmf_txstatus_get_field(status, GENERATION);
 
-	return brcmf_fws_txstatus_process(fws, flags, hslot, genbit);
+	brcmf_fws_lock(fws->drvr, lflags);
+	brcmf_fws_txs_process(fws, flags, hslot, genbit);
+	brcmf_fws_unlock(fws->drvr, lflags);
+	return BRCMF_FWS_RET_OK_NOSCHEDULE;
 }
 
 static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
@@ -1331,26 +1429,11 @@ static int brcmf_fws_dbg_seqnum_check(st
 	__le32 timestamp;
 
 	memcpy(&timestamp, &data[2], sizeof(timestamp));
-	brcmf_dbg(INFO, "received: seq %d, timestamp %d\n", data[1],
+	brcmf_dbg(CTL, "received: seq %d, timestamp %d\n", data[1],
 		  le32_to_cpu(timestamp));
 	return 0;
 }
 
-/* using macro so sparse checking does not complain
- * about locking imbalance.
- */
-#define brcmf_fws_lock(drvr, flags)				\
-do {								\
-	flags = 0;						\
-	spin_lock_irqsave(&((drvr)->fws_spinlock), (flags));	\
-} while (0)
-
-/* using macro so sparse checking does not complain
- * about locking imbalance.
- */
-#define brcmf_fws_unlock(drvr, flags) \
-	spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
-
 static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
 				       const struct brcmf_event_msg *e,
 				       void *data)
@@ -1364,6 +1447,10 @@ static int brcmf_fws_notify_credit_map(s
 		brcmf_err("event payload too small (%d)\n", e->datalen);
 		return -EINVAL;
 	}
+	if (fws->creditmap_received)
+		return 0;
+
+	fws->creditmap_received = true;
 
 	brcmf_dbg(TRACE, "enter: credits %pM\n", credits);
 	brcmf_fws_lock(ifp->drvr, flags);
@@ -1379,11 +1466,24 @@ static int brcmf_fws_notify_credit_map(s
 	return 0;
 }
 
+static int brcmf_fws_notify_bcmc_credit_support(struct brcmf_if *ifp,
+						const struct brcmf_event_msg *e,
+						void *data)
+{
+	struct brcmf_fws_info *fws = ifp->drvr->fws;
+	ulong flags;
+
+	brcmf_fws_lock(ifp->drvr, flags);
+	if (fws)
+		fws->bcmc_credit_check = true;
+	brcmf_fws_unlock(ifp->drvr, flags);
+	return 0;
+}
+
 int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
 		      struct sk_buff *skb)
 {
 	struct brcmf_fws_info *fws = drvr->fws;
-	ulong flags;
 	u8 *signal_data;
 	s16 data_len;
 	u8 type;
@@ -1392,7 +1492,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
 	s32 status;
 	s32 err;
 
-	brcmf_dbg(TRACE, "enter: ifidx %d, skblen %u, sig %d\n",
+	brcmf_dbg(HDRS, "enter: ifidx %d, skblen %u, sig %d\n",
 		  ifidx, skb->len, signal_len);
 
 	WARN_ON(signal_len > skb->len);
@@ -1403,9 +1503,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
 		return 0;
 	}
 
-	/* lock during tlv parsing */
-	brcmf_fws_lock(drvr, flags);
-
 	fws->stats.header_pulls++;
 	data_len = signal_len;
 	signal_data = skb->data;
@@ -1426,14 +1523,15 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
 		len = signal_data[1];
 		data = signal_data + 2;
 
-		brcmf_dbg(INFO, "tlv type=%d (%s), len=%d, data[0]=%d\n", type,
-			  brcmf_fws_get_tlv_name(type), len, *data);
+		brcmf_dbg(HDRS, "tlv type=%s (%d), len=%d (%d)\n",
+			  brcmf_fws_get_tlv_name(type), type, len,
+			  brcmf_fws_get_tlv_len(fws, type));
 
 		/* abort parsing when length invalid */
 		if (data_len < len + 2)
 			break;
 
-		if (len != brcmf_fws_get_tlv_len(fws, type))
+		if (len < brcmf_fws_get_tlv_len(fws, type))
 			break;
 
 		err = BRCMF_FWS_RET_OK_NOSCHEDULE;
@@ -1498,203 +1596,74 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
 	if (skb->len == 0)
 		fws->stats.header_only_pkt++;
 
-	brcmf_fws_unlock(drvr, flags);
 	return 0;
 }
 
-static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
-{
-	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
-	u8 *wlh;
-	u16 data_offset = 0;
-	u8 fillers;
-	__le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
-
-	brcmf_dbg(TRACE, "enter: ea=%pM, ifidx=%u, pkttag=0x%08X\n",
-		  entry->ea, entry->interface_id, le32_to_cpu(pkttag));
-	if (entry->send_tim_signal)
-		data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
-
-	/* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
-	data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
-	fillers = round_up(data_offset, 4) - data_offset;
-	data_offset += fillers;
-
-	skb_push(skb, data_offset);
-	wlh = skb->data;
-
-	wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
-	wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
-	memcpy(&wlh[2], &pkttag, sizeof(pkttag));
-	wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2;
-
-	if (entry->send_tim_signal) {
-		entry->send_tim_signal = 0;
-		wlh[0] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP;
-		wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
-		wlh[2] = entry->mac_handle;
-		wlh[3] = entry->traffic_pending_bmp;
-		wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2;
-		entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
-	}
-	if (fillers)
-		memset(wlh, BRCMF_FWS_TYPE_FILLER, fillers);
-
-	brcmf_proto_hdrpush(fws->drvr, brcmf_skb_if_flags_get_field(skb, INDEX),
-			    data_offset >> 2, skb);
-	return 0;
-}
-
-static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
+static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
 				   struct sk_buff *p)
 {
 	struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
 	struct brcmf_fws_mac_descriptor *entry = skcb->mac;
-	int rc = 0;
-	bool header_needed;
-	int hslot = BRCMF_FWS_HANGER_MAXITEMS;
-	u8 free_ctr;
-	u8 ifidx;
 	u8 flags;
 
-	header_needed = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED;
-
-	if (header_needed) {
-		/* obtaining free slot may fail, but that will be caught
-		 * by the hanger push. This assures the packet has a BDC
-		 * header upon return.
-		 */
-		hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
-		free_ctr = entry->seq[fifo];
-		brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
-		brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
-		brcmf_skb_htod_tag_set_field(p, GENERATION, 1);
-		entry->transit_count++;
-	}
 	brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
-	brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
-
+	brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
 	flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
-	if (!(skcb->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)) {
+	if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
 		/*
-		Indicate that this packet is being sent in response to an
-		explicit request from the firmware side.
-		*/
+		 * Indicate that this packet is being sent in response to an
+		 * explicit request from the firmware side.
+		 */
 		flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED;
 	}
 	brcmf_skb_htod_tag_set_field(p, FLAGS, flags);
-	if (header_needed) {
-		brcmf_fws_hdrpush(fws, p);
-		rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
-		if (rc)
-			brcmf_err("hanger push failed: rc=%d\n", rc);
-	} else {
-		int gen;
-
-		/* remove old header */
-		rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, p);
-		if (rc == 0) {
-			hslot = brcmf_skb_htod_tag_get_field(p, HSLOT);
-			brcmf_fws_hanger_get_genbit(&fws->hanger, p,
-						    hslot, &gen);
-			brcmf_skb_htod_tag_set_field(p, GENERATION, gen);
-
-			/* push new header */
-			brcmf_fws_hdrpush(fws, p);
-		}
-	}
-
-	return rc;
+	brcmf_fws_hdrpush(fws, p);
 }
 
-static void
-brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, struct sk_buff *skb)
+static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
+				   struct sk_buff *skb, int fifo)
 {
-	/*
-	put the packet back to the head of queue
-
-	- suppressed packet goes back to suppress sub-queue
-	- pull out the header, if new or delayed packet
-
-	Note: hslot is used only when header removal is done.
-	*/
 	struct brcmf_fws_mac_descriptor *entry;
-	enum brcmf_fws_skb_state state;
 	struct sk_buff *pktout;
+	int qidx, hslot;
 	int rc = 0;
-	int fifo;
-	int hslot;
-	u8 ifidx;
 
-	fifo = brcmf_skb_if_flags_get_field(skb, FIFO);
-	state = brcmf_skbcb(skb)->state;
 	entry = brcmf_skbcb(skb)->mac;
+	if (entry->occupied) {
+		qidx = 2 * fifo;
+		if (brcmf_skbcb(skb)->state == BRCMF_FWS_SKBSTATE_SUPPRESSED)
+			qidx++;
 
-	if (entry != NULL) {
-		if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
-			/* wl-header is saved for suppressed packets */
-			pktout = brcmu_pktq_penq_head(&entry->psq, 2 * fifo + 1,
-						      skb);
-			if (pktout == NULL) {
-				brcmf_err("suppress queue full\n");
-				rc = -ENOSPC;
-			}
-		} else {
-			hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
-
-			/* remove header first */
-			rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
-			if (rc) {
-				brcmf_err("header removal failed\n");
-				/* free the hanger slot */
-				brcmf_fws_hanger_poppkt(&fws->hanger, hslot,
-							&pktout, true);
-				rc = -EINVAL;
-				goto fail;
-			}
-
-			/* delay-q packets are going to delay-q */
-			pktout = brcmu_pktq_penq_head(&entry->psq,
-						      2 * fifo, skb);
-			if (pktout == NULL) {
-				brcmf_err("delay queue full\n");
-				rc = -ENOSPC;
-			}
-
-			/* free the hanger slot */
-			brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &pktout,
-						true);
-
-			/* decrement sequence count */
-			entry->seq[fifo]--;
+		pktout = brcmu_pktq_penq_head(&entry->psq, qidx, skb);
+		if (pktout == NULL) {
+			brcmf_err("%s queue %d full\n", entry->name, qidx);
+			rc = -ENOSPC;
 		}
-		/*
-		if this packet did not count against FIFO credit, it must have
-		taken a requested_credit from the firmware (for pspoll etc.)
-		*/
-		if (!(brcmf_skbcb(skb)->if_flags &
-		      BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK))
-			entry->requested_credit++;
 	} else {
-		brcmf_err("no mac entry linked\n");
+		brcmf_err("%s entry removed\n", entry->name);
 		rc = -ENOENT;
 	}
 
-
-fail:
 	if (rc) {
-		brcmf_txfinalize(fws->drvr, skb, false);
 		fws->stats.rollback_failed++;
-	} else
+		hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
+		brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
+				      hslot, 0);
+	} else {
 		fws->stats.rollback_success++;
+		brcmf_fws_return_credits(fws, fifo, 1);
+		brcmf_fws_macdesc_return_req_credit(skb);
+	}
 }
 
 static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
 {
 	int lender_ac;
 
-	if (time_after(fws->borrow_defer_timestamp, jiffies))
+	if (time_after(fws->borrow_defer_timestamp, jiffies)) {
+		fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE);
 		return -ENAVAIL;
+	}
 
 	for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) {
 		if (fws->fifo_credit[lender_ac]) {
@@ -1702,66 +1671,15 @@ static int brcmf_fws_borrow_credit(struc
 			fws->fifo_credit[lender_ac]--;
 			if (fws->fifo_credit[lender_ac] == 0)
 				fws->fifo_credit_map &= ~(1 << lender_ac);
-			brcmf_dbg(TRACE, "borrow credit from: %d\n", lender_ac);
+			fws->fifo_credit_map |= (1 << BRCMF_FWS_FIFO_AC_BE);
+			brcmf_dbg(DATA, "borrow credit from: %d\n", lender_ac);
 			return 0;
 		}
 	}
+	fws->fifo_credit_map &= ~(1 << BRCMF_FWS_FIFO_AC_BE);
 	return -ENAVAIL;
 }
 
-static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo,
-				    struct sk_buff *skb)
-{
-	struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
-	int *credit = &fws->fifo_credit[fifo];
-	int use_credit = 1;
-
-	brcmf_dbg(TRACE, "enter: ac=%d, credits=%d\n", fifo, *credit);
-
-	if (entry->requested_credit > 0) {
-		/*
-		 * if the packet was pulled out while destination is in
-		 * closed state but had a non-zero packets requested,
-		 * then this should not count against the FIFO credit.
-		 * That is due to the fact that the firmware will
-		 * most likely hold onto this packet until a suitable
-		 * time later to push it to the appropriate AC FIFO.
-		 */
-		entry->requested_credit--;
-		if (entry->state == BRCMF_FWS_STATE_CLOSE)
-			use_credit = 0;
-	} else if (entry->requested_packet > 0) {
-		entry->requested_packet--;
-		brcmf_skb_if_flags_set_field(skb, REQUESTED, 1);
-		if (entry->state == BRCMF_FWS_STATE_CLOSE)
-			use_credit = 0;
-	}
-	brcmf_skb_if_flags_set_field(skb, CREDITCHECK, use_credit);
-	if (!use_credit) {
-		brcmf_dbg(TRACE, "exit: no creditcheck set\n");
-		return 0;
-	}
-
-	if (fifo != BRCMF_FWS_FIFO_AC_BE)
-		fws->borrow_defer_timestamp = jiffies +
-					      BRCMF_FWS_BORROW_DEFER_PERIOD;
-
-	if (!(*credit)) {
-		/* Try to borrow a credit from other queue */
-		if (fifo == BRCMF_FWS_FIFO_AC_BE &&
-		    brcmf_fws_borrow_credit(fws) == 0)
-			return 0;
-
-		brcmf_dbg(TRACE, "exit: ac=%d, credits depleted\n", fifo);
-		return -ENAVAIL;
-	}
-	(*credit)--;
-	if (!(*credit))
-		fws->fifo_credit_map &= ~(1 << fifo);
-	brcmf_dbg(TRACE, "exit: ac=%d, credits=%d\n", fifo, *credit);
-	return 0;
-}
-
 static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
 				struct sk_buff *skb)
 {
@@ -1769,32 +1687,51 @@ static int brcmf_fws_commit_skb(struct b
 	struct brcmf_fws_mac_descriptor *entry;
 	struct brcmf_bus *bus = fws->drvr->bus_if;
 	int rc;
+	u8 ifidx;
 
 	entry = skcb->mac;
 	if (IS_ERR(entry))
 		return PTR_ERR(entry);
 
-	rc = brcmf_fws_precommit_skb(fws, fifo, skb);
+	brcmf_fws_precommit_skb(fws, fifo, skb);
+	rc = brcmf_bus_txdata(bus, skb);
+	brcmf_dbg(DATA, "%s flags %X htod %X bus_tx %d\n", entry->name,
+		  skcb->if_flags, skcb->htod, rc);
 	if (rc < 0) {
-		fws->stats.generic_error++;
+		brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
 		goto rollback;
 	}
 
-	rc = brcmf_bus_txdata(bus, skb);
-	if (rc < 0)
-		goto rollback;
-
-	entry->seq[fifo]++;
+	entry->transit_count++;
+	if (entry->suppressed)
+		entry->suppr_transit_count++;
 	fws->stats.pkt2bus++;
-	if (brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
-		fws->stats.send_pkts[fifo]++;
-		fws->stats.fifo_credits_sent[fifo]++;
-	}
+	fws->stats.send_pkts[fifo]++;
+	if (brcmf_skb_if_flags_get_field(skb, REQUESTED))
+		fws->stats.requested_sent[fifo]++;
 
 	return rc;
 
 rollback:
-	brcmf_fws_rollback_toq(fws, skb);
+	brcmf_fws_rollback_toq(fws, skb, fifo);
+	return rc;
+}
+
+static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
+				  int fifo)
+{
+	struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
+	int rc, hslot;
+
+	hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
+	brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
+	brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]);
+	brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
+	rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
+	if (!rc)
+		skcb->mac->seq[fifo]++;
+	else
+		fws->stats.generic_error++;
 	return rc;
 }
 
@@ -1807,13 +1744,14 @@ int brcmf_fws_process_skb(struct brcmf_i
 	ulong flags;
 	int fifo = BRCMF_FWS_FIFO_BCMC;
 	bool multicast = is_multicast_ether_addr(eh->h_dest);
+	bool pae = eh->h_proto == htons(ETH_P_PAE);
 
 	/* determine the priority */
 	if (!skb->priority)
 		skb->priority = cfg80211_classify8021d(skb);
 
 	drvr->tx_multicast += !!multicast;
-	if (ntohs(eh->h_proto) == ETH_P_PAE)
+	if (pae)
 		atomic_inc(&ifp->pend_8021x_cnt);
 
 	if (!brcmf_fws_fc_active(fws)) {
@@ -1826,29 +1764,30 @@ int brcmf_fws_process_skb(struct brcmf_i
 
 	/* set control buffer information */
 	skcb->if_flags = 0;
-	skcb->mac = brcmf_fws_find_mac_desc(fws, ifp, eh->h_dest);
 	skcb->state = BRCMF_FWS_SKBSTATE_NEW;
 	brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx);
 	if (!multicast)
 		fifo = brcmf_fws_prio2fifo[skb->priority];
-	brcmf_skb_if_flags_set_field(skb, FIFO, fifo);
-
-	brcmf_dbg(TRACE, "ea=%pM, multi=%d, fifo=%d\n", eh->h_dest,
-		  multicast, fifo);
 
 	brcmf_fws_lock(drvr, flags);
-	if (skcb->mac->suppressed ||
-	    brcmf_fws_mac_desc_closed(fws, skcb->mac, fifo) ||
-	    brcmu_pktq_mlen(&skcb->mac->psq, 3 << (fifo * 2)) ||
-	    (!multicast &&
-	     brcmf_fws_consume_credit(fws, fifo, skb) < 0)) {
-		/* enqueue the packet in delayQ */
-		drvr->fws->fifo_delay_map |= 1 << fifo;
+	if (fifo != BRCMF_FWS_FIFO_AC_BE && fifo < BRCMF_FWS_FIFO_BCMC)
+		fws->borrow_defer_timestamp = jiffies +
+					      BRCMF_FWS_BORROW_DEFER_PERIOD;
+
+	skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest);
+	brcmf_dbg(DATA, "%s mac %pM multi %d fifo %d\n", skcb->mac->name,
+		  eh->h_dest, multicast, fifo);
+	if (!brcmf_fws_assign_htod(fws, skb, fifo)) {
 		brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
+		brcmf_fws_schedule_deq(fws);
 	} else {
-		if (brcmf_fws_commit_skb(fws, fifo, skb))
-			if (!multicast)
-				brcmf_skb_pick_up_credit(fws, fifo, skb);
+		brcmf_err("drop skb: no hanger slot\n");
+		if (pae) {
+			atomic_dec(&ifp->pend_8021x_cnt);
+			if (waitqueue_active(&ifp->pend_8021x_wait))
+				wake_up(&ifp->pend_8021x_wait);
+		}
+		brcmu_pkt_buf_free_skb(skb);
 	}
 	brcmf_fws_unlock(drvr, flags);
 	return 0;
@@ -1862,7 +1801,7 @@ void brcmf_fws_reset_interface(struct br
 	if (!entry)
 		return;
 
-	brcmf_fws_init_mac_descriptor(entry, ifp->mac_addr, ifp->ifidx);
+	brcmf_fws_macdesc_init(entry, ifp->mac_addr, ifp->ifidx);
 }
 
 void brcmf_fws_add_interface(struct brcmf_if *ifp)
@@ -1870,16 +1809,16 @@ void brcmf_fws_add_interface(struct brcm
 	struct brcmf_fws_info *fws = ifp->drvr->fws;
 	struct brcmf_fws_mac_descriptor *entry;
 
-	brcmf_dbg(TRACE, "enter: idx=%d, mac=%pM\n",
-		  ifp->bssidx, ifp->mac_addr);
 	if (!ifp->ndev || !ifp->drvr->fw_signals)
 		return;
 
 	entry = &fws->desc.iface[ifp->ifidx];
 	ifp->fws_desc = entry;
-	brcmf_fws_init_mac_descriptor(entry, ifp->mac_addr, ifp->ifidx);
+	brcmf_fws_macdesc_init(entry, ifp->mac_addr, ifp->ifidx);
+	brcmf_fws_macdesc_set_name(fws, entry);
 	brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT,
 			BRCMF_FWS_PSQ_LEN);
+	brcmf_dbg(TRACE, "added %s\n", entry->name);
 }
 
 void brcmf_fws_del_interface(struct brcmf_if *ifp)
@@ -1887,13 +1826,13 @@ void brcmf_fws_del_interface(struct brcm
 	struct brcmf_fws_mac_descriptor *entry = ifp->fws_desc;
 	ulong flags;
 
-	brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx);
 	if (!entry)
 		return;
 
 	brcmf_fws_lock(ifp->drvr, flags);
 	ifp->fws_desc = NULL;
-	brcmf_fws_clear_mac_descriptor(entry);
+	brcmf_dbg(TRACE, "deleting %s\n", entry->name);
+	brcmf_fws_macdesc_deinit(entry);
 	brcmf_fws_cleanup(ifp->drvr->fws, ifp->ifidx);
 	brcmf_fws_unlock(ifp->drvr, flags);
 }
@@ -1904,39 +1843,37 @@ static void brcmf_fws_dequeue_worker(str
 	struct sk_buff *skb;
 	ulong flags;
 	int fifo;
-	int credit;
 
 	fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work);
 
-	brcmf_dbg(TRACE, "enter: fws=%p\n", fws);
 	brcmf_fws_lock(fws->drvr, flags);
-	for (fifo = NL80211_NUM_ACS; fifo >= 0; fifo--) {
-		brcmf_dbg(TRACE, "fifo %d credit %d\n", fifo,
-			  fws->fifo_credit[fifo]);
-		for (credit = 0; credit < fws->fifo_credit[fifo]; /* nop */) {
+	for (fifo = BRCMF_FWS_FIFO_BCMC; fifo >= 0 && !fws->bus_flow_blocked;
+	     fifo--) {
+		while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) &&
+		       (fifo == BRCMF_FWS_FIFO_BCMC))) {
 			skb = brcmf_fws_deq(fws, fifo);
-			if (!skb || brcmf_fws_commit_skb(fws, fifo, skb))
+			if (!skb)
+				break;
+			fws->fifo_credit[fifo]--;
+			if (brcmf_fws_commit_skb(fws, fifo, skb))
+				break;
+			if (fws->bus_flow_blocked)
 				break;
-			if (brcmf_skbcb(skb)->if_flags &
-			    BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK)
-				credit++;
 		}
 		if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
-		    (credit == fws->fifo_credit[fifo])) {
-			fws->fifo_credit[fifo] -= credit;
+		    (fws->fifo_credit[fifo] == 0) &&
+		    (!fws->bus_flow_blocked)) {
 			while (brcmf_fws_borrow_credit(fws) == 0) {
 				skb = brcmf_fws_deq(fws, fifo);
 				if (!skb) {
 					brcmf_fws_return_credits(fws, fifo, 1);
 					break;
 				}
-				if (brcmf_fws_commit_skb(fws, fifo, skb)) {
-					brcmf_fws_return_credits(fws, fifo, 1);
+				if (brcmf_fws_commit_skb(fws, fifo, skb))
+					break;
+				if (fws->bus_flow_blocked)
 					break;
-				}
 			}
-		} else {
-			fws->fifo_credit[fifo] -= credit;
 		}
 	}
 	brcmf_fws_unlock(fws->drvr, flags);
@@ -1982,6 +1919,13 @@ int brcmf_fws_init(struct brcmf_pub *drv
 		brcmf_err("register credit map handler failed\n");
 		goto fail;
 	}
+	rc = brcmf_fweh_register(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT,
+				 brcmf_fws_notify_bcmc_credit_support);
+	if (rc < 0) {
+		brcmf_err("register bcmc credit handler failed\n");
+		brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP);
+		goto fail;
+	}
 
 	/* setting the iovar may fail if feature is unsupported
 	 * so leave the rc as is so driver initialization can
@@ -1993,19 +1937,20 @@ int brcmf_fws_init(struct brcmf_pub *drv
 	}
 
 	brcmf_fws_hanger_init(&drvr->fws->hanger);
-	brcmf_fws_init_mac_descriptor(&drvr->fws->desc.other, NULL, 0);
+	brcmf_fws_macdesc_init(&drvr->fws->desc.other, NULL, 0);
+	brcmf_fws_macdesc_set_name(drvr->fws, &drvr->fws->desc.other);
 	brcmu_pktq_init(&drvr->fws->desc.other.psq, BRCMF_FWS_PSQ_PREC_COUNT,
 			BRCMF_FWS_PSQ_LEN);
 
 	/* create debugfs file for statistics */
 	brcmf_debugfs_create_fws_stats(drvr, &drvr->fws->stats);
 
-	/* TODO: remove upon feature delivery */
-	brcmf_err("%s bdcv2 tlv signaling [%x]\n",
+	brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n",
 		  drvr->fw_signals ? "enabled" : "disabled", tlv);
 	return 0;
 
 fail_event:
+	brcmf_fweh_unregister(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT);
 	brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP);
 fail:
 	brcmf_fws_deinit(drvr);
@@ -2043,25 +1988,31 @@ bool brcmf_fws_fc_active(struct brcmf_fw
 	if (!fws)
 		return false;
 
-	brcmf_dbg(TRACE, "enter: mode=%d\n", fws->fcmode);
 	return fws->fcmode != BRCMF_FWS_FCMODE_NONE;
 }
 
 void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
 {
 	ulong flags;
+	u32 hslot;
 
-	brcmf_fws_lock(fws->drvr, flags);
-	brcmf_fws_txstatus_process(fws, BRCMF_FWS_TXSTATUS_FW_TOSSED,
-				   brcmf_skb_htod_tag_get_field(skb, HSLOT), 0);
-	/* the packet never reached firmware so reclaim credit */
-	if (fws->fcmode == BRCMF_FWS_FCMODE_EXPLICIT_CREDIT &&
-	    brcmf_skbcb(skb)->if_flags & BRCMF_SKB_IF_FLAGS_CREDITCHECK_MASK) {
-		brcmf_fws_return_credits(fws,
-					 brcmf_skb_htod_tag_get_field(skb,
-								      FIFO),
-					 1);
-		brcmf_fws_schedule_deq(fws);
+	if (brcmf_skbcb(skb)->state == BRCMF_FWS_SKBSTATE_TIM) {
+		brcmu_pkt_buf_free_skb(skb);
+		return;
 	}
+	brcmf_fws_lock(fws->drvr, flags);
+	hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
+	brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0);
 	brcmf_fws_unlock(fws->drvr, flags);
 }
+
+void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked)
+{
+	struct brcmf_fws_info *fws = drvr->fws;
+
+	fws->bus_flow_blocked = flow_blocked;
+	if (!flow_blocked)
+		brcmf_fws_schedule_deq(fws);
+	else
+		fws->stats.bus_flow_block++;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h	2013-08-25 20:43:22.000000000 -0400
@@ -29,5 +29,6 @@ void brcmf_fws_reset_interface(struct br
 void brcmf_fws_add_interface(struct brcmf_if *ifp);
 void brcmf_fws_del_interface(struct brcmf_if *ifp);
 void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb);
+void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked);
 
 #endif /* FWSIGNAL_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h	2013-08-25 20:43:22.000000000 -0400
@@ -170,7 +170,6 @@ struct brcmf_sdio_dev {
 	atomic_t suspend;		/* suspend flag */
 	wait_queue_head_t request_byte_wait;
 	wait_queue_head_t request_word_wait;
-	wait_queue_head_t request_chain_wait;
 	wait_queue_head_t request_buffer_wait;
 	struct device *dev;
 	struct brcmf_bus *bus_if;
@@ -230,8 +229,6 @@ brcmf_sdcard_recv_chain(struct brcmf_sdi
 #define SDIO_REQ_4BYTE	0x1
 /* Fixed address (FIFO) (vs. incrementing address) */
 #define SDIO_REQ_FIXED	0x2
-/* Async request (vs. sync request) */
-#define SDIO_REQ_ASYNC	0x4
 
 /* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
  *   rw:       read or write (0/1)
@@ -252,9 +249,6 @@ extern int brcmf_sdcard_abort(struct brc
 extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
 extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
 
-extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
-					  u32 address);
-
 /* attach, return handler on success, NULL if failed.
  *  The handler shall be provided by all subsequent calls. No local cache
  *  cfghdl points to the starting address of pci device mapped memory
@@ -272,16 +266,6 @@ brcmf_sdioh_request_word(struct brcmf_sd
 			 uint rw, uint fnc, uint addr,
 			 u32 *word, uint nbyte);
 
-/* read or write any buffer using cmd53 */
-extern int
-brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
-			   uint fix_inc, uint rw, uint fnc_num, u32 addr,
-			   struct sk_buff *pkt);
-extern int
-brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
-			  uint write, uint func, uint addr,
-			  struct sk_buff_head *pktq);
-
 /* Watchdog timer interface for pm ops */
 extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev,
 				    bool enable);
@@ -291,4 +275,8 @@ extern void brcmf_sdbrcm_disconnect(void
 extern void brcmf_sdbrcm_isr(void *arg);
 
 extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick);
+
+extern void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev,
+				 wait_queue_head_t *wq);
+extern bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev);
 #endif				/* _BRCM_SDH_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h	2013-08-25 20:43:22.000000000 -0400
@@ -87,6 +87,27 @@ TRACE_EVENT(brcmf_hexdump,
 	TP_printk("hexdump [length=%lu]", __entry->len)
 );
 
+TRACE_EVENT(brcmf_bdchdr,
+	TP_PROTO(void *data),
+	TP_ARGS(data),
+	TP_STRUCT__entry(
+		__field(u8, flags)
+		__field(u8, prio)
+		__field(u8, flags2)
+		__field(u32, siglen)
+		__dynamic_array(u8, signal, *((u8 *)data + 3) * 4)
+	),
+	TP_fast_assign(
+		__entry->flags = *(u8 *)data;
+		__entry->prio = *((u8 *)data + 1);
+		__entry->flags2 = *((u8 *)data + 2);
+		__entry->siglen = *((u8 *)data + 3) * 4;
+		memcpy(__get_dynamic_array(signal),
+		       (u8 *)data + 4, __entry->siglen);
+	),
+	TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen)
+);
+
 #ifdef CONFIG_BRCM_TRACING
 
 #undef TRACE_INCLUDE_PATH
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/usb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/usb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/usb.c	2013-07-01 10:38:12.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/usb.c	2013-08-31 17:57:47.000000000 -0400
@@ -82,6 +82,7 @@ struct brcmf_usbdev_info {
 	int tx_high_watermark;
 	int tx_freecount;
 	bool tx_flowblock;
+	spinlock_t tx_flowblock_lock;
 
 	struct brcmf_usbreq *tx_reqs;
 	struct brcmf_usbreq *rx_reqs;
@@ -411,6 +412,7 @@ static void brcmf_usb_tx_complete(struct
 {
 	struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
 	struct brcmf_usbdev_info *devinfo = req->devinfo;
+	unsigned long flags;
 
 	brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
 		  req->skb);
@@ -419,11 +421,13 @@ static void brcmf_usb_tx_complete(struct
 	brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
 	req->skb = NULL;
 	brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
+	spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
 	if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
 		devinfo->tx_flowblock) {
 		brcmf_txflowblock(devinfo->dev, false);
 		devinfo->tx_flowblock = false;
 	}
+	spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
 }
 
 static void brcmf_usb_rx_complete(struct urb *urb)
@@ -568,6 +572,7 @@ static int brcmf_usb_tx(struct device *d
 	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
 	struct brcmf_usbreq  *req;
 	int ret;
+	unsigned long flags;
 
 	brcmf_dbg(USB, "Enter, skb=%p\n", skb);
 	if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) {
@@ -599,11 +604,13 @@ static int brcmf_usb_tx(struct device *d
 		goto fail;
 	}
 
+	spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
 	if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
 	    !devinfo->tx_flowblock) {
 		brcmf_txflowblock(dev, true);
 		devinfo->tx_flowblock = true;
 	}
+	spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
 	return 0;
 
 fail:
@@ -1164,6 +1171,7 @@ struct brcmf_usbdev *brcmf_usb_attach(st
 
 	/* Initialize the spinlocks */
 	spin_lock_init(&devinfo->qlock);
+	spin_lock_init(&devinfo->tx_flowblock_lock);
 
 	INIT_LIST_HEAD(&devinfo->rx_freeq);
 	INIT_LIST_HEAD(&devinfo->rx_postq);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c	2013-08-25 20:43:22.000000000 -0400
@@ -1093,8 +1093,11 @@ static void brcmf_link_down(struct brcmf
 		brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
 		err = brcmf_fil_cmd_data_set(vif->ifp,
 					     BRCMF_C_DISASSOC, NULL, 0);
-		if (err)
+		if (err) {
 			brcmf_err("WLC_DISASSOC failed (%d)\n", err);
+			cfg80211_disconnected(vif->wdev.netdev, 0,
+					      NULL, 0, GFP_KERNEL);
+		}
 		clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
 	}
 	clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
@@ -3982,6 +3985,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip
 	struct brcmf_fil_af_params_le *af_params;
 	bool ack;
 	s32 chan_nr;
+	u32 freq;
 
 	brcmf_dbg(TRACE, "Enter\n");
 
@@ -3994,6 +3998,8 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip
 		return -EPERM;
 	}
 
+	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
+
 	if (ieee80211_is_probe_resp(mgmt->frame_control)) {
 		/* Right now the only reason to get a probe response */
 		/* is for p2p listen response or for p2p GO from     */
@@ -4009,7 +4015,6 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip
 		ie_offset =  DOT11_MGMT_HDR_LEN +
 			     DOT11_BCN_PRB_FIXED_LEN;
 		ie_len = len - ie_offset;
-		vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
 		if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
 			vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
 		err = brcmf_vif_set_mgmt_ie(vif,
@@ -4033,16 +4038,22 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip
 		memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
 		/* Add the length exepted for 802.11 header  */
 		action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
-		/* Add the channel */
-		chan_nr = ieee80211_frequency_to_channel(chan->center_freq);
+		/* Add the channel. Use the one specified as parameter if any or
+		 * the current one (got from the firmware) otherwise
+		 */
+		if (chan)
+			freq = chan->center_freq;
+		else
+			brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
+					      &freq);
+		chan_nr = ieee80211_frequency_to_channel(freq);
 		af_params->channel = cpu_to_le32(chan_nr);
 
 		memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
 		       le16_to_cpu(action_frame->len));
 
 		brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
-			  *cookie, le16_to_cpu(action_frame->len),
-			  chan->center_freq);
+			  *cookie, le16_to_cpu(action_frame->len), freq);
 
 		ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
 						  af_params);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
--- linux-libre-3.10-gnu/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c	2013-08-25 20:43:22.000000000 -0400
@@ -900,7 +900,7 @@ brcms_c_ampdu_dotxstatus_complete(struct
 		if (supr_status) {
 			update_rate = false;
 			if (supr_status == TX_STATUS_SUPR_BADCH) {
-				brcms_err(wlc->hw->d11core,
+				brcms_dbg_ht(wlc->hw->d11core,
 					  "%s: Pkt tx suppressed, illegal channel possibly %d\n",
 					  __func__, CHSPEC_CHANNEL(
 					  wlc->default_bss->chanspec));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/bh.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/bh.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/bh.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/bh.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,619 @@
+/*
+ * Device handling thread implementation for mac80211 ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * Based on:
+ * ST-Ericsson UMAC CW1200 driver, which is
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <net/mac80211.h>
+#include <linux/kthread.h>
+#include <linux/timer.h>
+
+#include "cw1200.h"
+#include "bh.h"
+#include "hwio.h"
+#include "wsm.h"
+#include "hwbus.h"
+#include "debug.h"
+#include "fwio.h"
+
+static int cw1200_bh(void *arg);
+
+#define DOWNLOAD_BLOCK_SIZE_WR	(0x1000 - 4)
+/* an SPI message cannot be bigger than (2"12-1)*2 bytes
+ * "*2" to cvt to bytes
+ */
+#define MAX_SZ_RD_WR_BUFFERS	(DOWNLOAD_BLOCK_SIZE_WR*2)
+#define PIGGYBACK_CTRL_REG	(2)
+#define EFFECTIVE_BUF_SIZE	(MAX_SZ_RD_WR_BUFFERS - PIGGYBACK_CTRL_REG)
+
+/* Suspend state privates */
+enum cw1200_bh_pm_state {
+	CW1200_BH_RESUMED = 0,
+	CW1200_BH_SUSPEND,
+	CW1200_BH_SUSPENDED,
+	CW1200_BH_RESUME,
+};
+
+typedef int (*cw1200_wsm_handler)(struct cw1200_common *priv,
+	u8 *data, size_t size);
+
+static void cw1200_bh_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+	container_of(work, struct cw1200_common, bh_work);
+	cw1200_bh(priv);
+}
+
+int cw1200_register_bh(struct cw1200_common *priv)
+{
+	int err = 0;
+	/* Realtime workqueue */
+	priv->bh_workqueue = alloc_workqueue("cw1200_bh",
+				WQ_MEM_RECLAIM | WQ_HIGHPRI
+				| WQ_CPU_INTENSIVE, 1);
+
+	if (!priv->bh_workqueue)
+		return -ENOMEM;
+
+	INIT_WORK(&priv->bh_work, cw1200_bh_work);
+
+	pr_debug("[BH] register.\n");
+
+	atomic_set(&priv->bh_rx, 0);
+	atomic_set(&priv->bh_tx, 0);
+	atomic_set(&priv->bh_term, 0);
+	atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
+	priv->bh_error = 0;
+	priv->hw_bufs_used = 0;
+	priv->buf_id_tx = 0;
+	priv->buf_id_rx = 0;
+	init_waitqueue_head(&priv->bh_wq);
+	init_waitqueue_head(&priv->bh_evt_wq);
+
+	err = !queue_work(priv->bh_workqueue, &priv->bh_work);
+	WARN_ON(err);
+	return err;
+}
+
+void cw1200_unregister_bh(struct cw1200_common *priv)
+{
+	atomic_add(1, &priv->bh_term);
+	wake_up(&priv->bh_wq);
+
+	flush_workqueue(priv->bh_workqueue);
+
+	destroy_workqueue(priv->bh_workqueue);
+	priv->bh_workqueue = NULL;
+
+	pr_debug("[BH] unregistered.\n");
+}
+
+void cw1200_irq_handler(struct cw1200_common *priv)
+{
+	pr_debug("[BH] irq.\n");
+
+	/* Disable Interrupts! */
+	/* NOTE:  hwbus_ops->lock already held */
+	__cw1200_irq_enable(priv, 0);
+
+	if (/* WARN_ON */(priv->bh_error))
+		return;
+
+	if (atomic_add_return(1, &priv->bh_rx) == 1)
+		wake_up(&priv->bh_wq);
+}
+EXPORT_SYMBOL_GPL(cw1200_irq_handler);
+
+void cw1200_bh_wakeup(struct cw1200_common *priv)
+{
+	pr_debug("[BH] wakeup.\n");
+	if (priv->bh_error) {
+		pr_err("[BH] wakeup failed (BH error)\n");
+		return;
+	}
+
+	if (atomic_add_return(1, &priv->bh_tx) == 1)
+		wake_up(&priv->bh_wq);
+}
+
+int cw1200_bh_suspend(struct cw1200_common *priv)
+{
+	pr_debug("[BH] suspend.\n");
+	if (priv->bh_error) {
+		wiphy_warn(priv->hw->wiphy, "BH error -- can't suspend\n");
+		return -EINVAL;
+	}
+
+	atomic_set(&priv->bh_suspend, CW1200_BH_SUSPEND);
+	wake_up(&priv->bh_wq);
+	return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
+		(CW1200_BH_SUSPENDED == atomic_read(&priv->bh_suspend)),
+		 1 * HZ) ? 0 : -ETIMEDOUT;
+}
+
+int cw1200_bh_resume(struct cw1200_common *priv)
+{
+	pr_debug("[BH] resume.\n");
+	if (priv->bh_error) {
+		wiphy_warn(priv->hw->wiphy, "BH error -- can't resume\n");
+		return -EINVAL;
+	}
+
+	atomic_set(&priv->bh_suspend, CW1200_BH_RESUME);
+	wake_up(&priv->bh_wq);
+	return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
+		(CW1200_BH_RESUMED == atomic_read(&priv->bh_suspend)),
+		1 * HZ) ? 0 : -ETIMEDOUT;
+}
+
+static inline void wsm_alloc_tx_buffer(struct cw1200_common *priv)
+{
+	++priv->hw_bufs_used;
+}
+
+int wsm_release_tx_buffer(struct cw1200_common *priv, int count)
+{
+	int ret = 0;
+	int hw_bufs_used = priv->hw_bufs_used;
+
+	priv->hw_bufs_used -= count;
+	if (WARN_ON(priv->hw_bufs_used < 0))
+		ret = -1;
+	else if (hw_bufs_used >= priv->wsm_caps.input_buffers)
+		ret = 1;
+	if (!priv->hw_bufs_used)
+		wake_up(&priv->bh_evt_wq);
+	return ret;
+}
+
+static int cw1200_bh_read_ctrl_reg(struct cw1200_common *priv,
+					  u16 *ctrl_reg)
+{
+	int ret;
+
+	ret = cw1200_reg_read_16(priv,
+			ST90TDS_CONTROL_REG_ID, ctrl_reg);
+	if (ret) {
+		ret = cw1200_reg_read_16(priv,
+				ST90TDS_CONTROL_REG_ID, ctrl_reg);
+		if (ret)
+			pr_err("[BH] Failed to read control register.\n");
+	}
+
+	return ret;
+}
+
+static int cw1200_device_wakeup(struct cw1200_common *priv)
+{
+	u16 ctrl_reg;
+	int ret;
+
+	pr_debug("[BH] Device wakeup.\n");
+
+	/* First, set the dpll register */
+	ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
+				  cw1200_dpll_from_clk(priv->hw_refclk));
+	if (WARN_ON(ret))
+		return ret;
+
+	/* To force the device to be always-on, the host sets WLAN_UP to 1 */
+	ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
+			ST90TDS_CONT_WUP_BIT);
+	if (WARN_ON(ret))
+		return ret;
+
+	ret = cw1200_bh_read_ctrl_reg(priv, &ctrl_reg);
+	if (WARN_ON(ret))
+		return ret;
+
+	/* If the device returns WLAN_RDY as 1, the device is active and will
+	 * remain active.
+	 */
+	if (ctrl_reg & ST90TDS_CONT_RDY_BIT) {
+		pr_debug("[BH] Device awake.\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+/* Must be called from BH thraed. */
+void cw1200_enable_powersave(struct cw1200_common *priv,
+			     bool enable)
+{
+	pr_debug("[BH] Powerave is %s.\n",
+		 enable ? "enabled" : "disabled");
+	priv->powersave_enabled = enable;
+}
+
+static int cw1200_bh_rx_helper(struct cw1200_common *priv,
+			       uint16_t *ctrl_reg,
+			       int *tx)
+{
+	size_t read_len = 0;
+	struct sk_buff *skb_rx = NULL;
+	struct wsm_hdr *wsm;
+	size_t wsm_len;
+	u16 wsm_id;
+	u8 wsm_seq;
+	int rx_resync = 1;
+
+	size_t alloc_len;
+	u8 *data;
+
+	read_len = (*ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) * 2;
+	if (!read_len)
+		return 0; /* No more work */
+
+	if (WARN_ON((read_len < sizeof(struct wsm_hdr)) ||
+		    (read_len > EFFECTIVE_BUF_SIZE))) {
+		pr_debug("Invalid read len: %zu (%04x)",
+			 read_len, *ctrl_reg);
+		goto err;
+	}
+
+	/* Add SIZE of PIGGYBACK reg (CONTROL Reg)
+	 * to the NEXT Message length + 2 Bytes for SKB
+	 */
+	read_len = read_len + 2;
+
+	alloc_len = priv->hwbus_ops->align_size(
+		priv->hwbus_priv, read_len);
+
+	/* Check if not exceeding CW1200 capabilities */
+	if (WARN_ON_ONCE(alloc_len > EFFECTIVE_BUF_SIZE)) {
+		pr_debug("Read aligned len: %zu\n",
+			 alloc_len);
+	}
+
+	skb_rx = dev_alloc_skb(alloc_len);
+	if (WARN_ON(!skb_rx))
+		goto err;
+
+	skb_trim(skb_rx, 0);
+	skb_put(skb_rx, read_len);
+	data = skb_rx->data;
+	if (WARN_ON(!data))
+		goto err;
+
+	if (WARN_ON(cw1200_data_read(priv, data, alloc_len))) {
+		pr_err("rx blew up, len %zu\n", alloc_len);
+		goto err;
+	}
+
+	/* Piggyback */
+	*ctrl_reg = __le16_to_cpu(
+		((__le16 *)data)[alloc_len / 2 - 1]);
+
+	wsm = (struct wsm_hdr *)data;
+	wsm_len = __le16_to_cpu(wsm->len);
+	if (WARN_ON(wsm_len > read_len))
+		goto err;
+
+	if (priv->wsm_enable_wsm_dumps)
+		print_hex_dump_bytes("<-- ",
+				     DUMP_PREFIX_NONE,
+				     data, wsm_len);
+
+	wsm_id  = __le16_to_cpu(wsm->id) & 0xFFF;
+	wsm_seq = (__le16_to_cpu(wsm->id) >> 13) & 7;
+
+	skb_trim(skb_rx, wsm_len);
+
+	if (wsm_id == 0x0800) {
+		wsm_handle_exception(priv,
+				     &data[sizeof(*wsm)],
+				     wsm_len - sizeof(*wsm));
+		goto err;
+	} else if (!rx_resync) {
+		if (WARN_ON(wsm_seq != priv->wsm_rx_seq))
+			goto err;
+	}
+	priv->wsm_rx_seq = (wsm_seq + 1) & 7;
+	rx_resync = 0;
+
+	if (wsm_id & 0x0400) {
+		int rc = wsm_release_tx_buffer(priv, 1);
+		if (WARN_ON(rc < 0))
+			return rc;
+		else if (rc > 0)
+			*tx = 1;
+	}
+
+	/* cw1200_wsm_rx takes care on SKB livetime */
+	if (WARN_ON(wsm_handle_rx(priv, wsm_id, wsm, &skb_rx)))
+		goto err;
+
+	if (skb_rx) {
+		dev_kfree_skb(skb_rx);
+		skb_rx = NULL;
+	}
+
+	return 0;
+
+err:
+	if (skb_rx) {
+		dev_kfree_skb(skb_rx);
+		skb_rx = NULL;
+	}
+	return -1;
+}
+
+static int cw1200_bh_tx_helper(struct cw1200_common *priv,
+			       int *pending_tx,
+			       int *tx_burst)
+{
+	size_t tx_len;
+	u8 *data;
+	int ret;
+	struct wsm_hdr *wsm;
+
+	if (priv->device_can_sleep) {
+		ret = cw1200_device_wakeup(priv);
+		if (WARN_ON(ret < 0)) { /* Error in wakeup */
+			*pending_tx = 1;
+			return 0;
+		} else if (ret) { /* Woke up */
+			priv->device_can_sleep = false;
+		} else { /* Did not awake */
+			*pending_tx = 1;
+			return 0;
+		}
+	}
+
+	wsm_alloc_tx_buffer(priv);
+	ret = wsm_get_tx(priv, &data, &tx_len, tx_burst);
+	if (ret <= 0) {
+		wsm_release_tx_buffer(priv, 1);
+		if (WARN_ON(ret < 0))
+			return ret; /* Error */
+		return 0; /* No work */
+	}
+
+	wsm = (struct wsm_hdr *)data;
+	BUG_ON(tx_len < sizeof(*wsm));
+	BUG_ON(__le16_to_cpu(wsm->len) != tx_len);
+
+	atomic_add(1, &priv->bh_tx);
+
+	tx_len = priv->hwbus_ops->align_size(
+		priv->hwbus_priv, tx_len);
+
+	/* Check if not exceeding CW1200 capabilities */
+	if (WARN_ON_ONCE(tx_len > EFFECTIVE_BUF_SIZE))
+		pr_debug("Write aligned len: %zu\n", tx_len);
+
+	wsm->id &= __cpu_to_le16(0xffff ^ WSM_TX_SEQ(WSM_TX_SEQ_MAX));
+	wsm->id |= __cpu_to_le16(WSM_TX_SEQ(priv->wsm_tx_seq));
+
+	if (WARN_ON(cw1200_data_write(priv, data, tx_len))) {
+		pr_err("tx blew up, len %zu\n", tx_len);
+		wsm_release_tx_buffer(priv, 1);
+		return -1; /* Error */
+	}
+
+	if (priv->wsm_enable_wsm_dumps)
+		print_hex_dump_bytes("--> ",
+				     DUMP_PREFIX_NONE,
+				     data,
+				     __le16_to_cpu(wsm->len));
+
+	wsm_txed(priv, data);
+	priv->wsm_tx_seq = (priv->wsm_tx_seq + 1) & WSM_TX_SEQ_MAX;
+
+	if (*tx_burst > 1) {
+		cw1200_debug_tx_burst(priv);
+		return 1; /* Work remains */
+	}
+
+	return 0;
+}
+
+static int cw1200_bh(void *arg)
+{
+	struct cw1200_common *priv = arg;
+	int rx, tx, term, suspend;
+	u16 ctrl_reg = 0;
+	int tx_allowed;
+	int pending_tx = 0;
+	int tx_burst;
+	long status;
+	u32 dummy;
+	int ret;
+
+	for (;;) {
+		if (!priv->hw_bufs_used &&
+		    priv->powersave_enabled &&
+		    !priv->device_can_sleep &&
+		    !atomic_read(&priv->recent_scan)) {
+			status = 1 * HZ;
+			pr_debug("[BH] Device wakedown. No data.\n");
+			cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID, 0);
+			priv->device_can_sleep = true;
+		} else if (priv->hw_bufs_used) {
+			/* Interrupt loss detection */
+			status = 1 * HZ;
+		} else {
+			status = MAX_SCHEDULE_TIMEOUT;
+		}
+
+		/* Dummy Read for SDIO retry mechanism*/
+		if ((priv->hw_type != -1) &&
+		    (atomic_read(&priv->bh_rx) == 0) &&
+		    (atomic_read(&priv->bh_tx) == 0))
+			cw1200_reg_read(priv, ST90TDS_CONFIG_REG_ID,
+					&dummy, sizeof(dummy));
+
+		pr_debug("[BH] waiting ...\n");
+		status = wait_event_interruptible_timeout(priv->bh_wq, ({
+				rx = atomic_xchg(&priv->bh_rx, 0);
+				tx = atomic_xchg(&priv->bh_tx, 0);
+				term = atomic_xchg(&priv->bh_term, 0);
+				suspend = pending_tx ?
+					0 : atomic_read(&priv->bh_suspend);
+				(rx || tx || term || suspend || priv->bh_error);
+			}), status);
+
+		pr_debug("[BH] - rx: %d, tx: %d, term: %d, suspend: %d, status: %ld\n",
+			 rx, tx, term, suspend, status);
+
+		/* Did an error occur? */
+		if ((status < 0 && status != -ERESTARTSYS) ||
+		    term || priv->bh_error) {
+			break;
+		}
+		if (!status) {  /* wait_event timed out */
+			unsigned long timestamp = jiffies;
+			long timeout;
+			int pending = 0;
+			int i;
+
+			/* Check to see if we have any outstanding frames */
+			if (priv->hw_bufs_used && (!rx || !tx)) {
+				wiphy_warn(priv->hw->wiphy,
+					   "Missed interrupt? (%d frames outstanding)\n",
+					   priv->hw_bufs_used);
+				rx = 1;
+
+				/* Get a timestamp of "oldest" frame */
+				for (i = 0; i < 4; ++i)
+					pending += cw1200_queue_get_xmit_timestamp(
+						&priv->tx_queue[i],
+						&timestamp,
+						priv->pending_frame_id);
+
+				/* Check if frame transmission is timed out.
+				 * Add an extra second with respect to possible
+				 * interrupt loss.
+				 */
+				timeout = timestamp +
+					WSM_CMD_LAST_CHANCE_TIMEOUT +
+					1 * HZ  -
+					jiffies;
+
+				/* And terminate BH thread if the frame is "stuck" */
+				if (pending && timeout < 0) {
+					wiphy_warn(priv->hw->wiphy,
+						   "Timeout waiting for TX confirm (%d/%d pending, %ld vs %lu).\n",
+						   priv->hw_bufs_used, pending,
+						   timestamp, jiffies);
+					break;
+				}
+			} else if (!priv->device_can_sleep &&
+				   !atomic_read(&priv->recent_scan)) {
+				pr_debug("[BH] Device wakedown. Timeout.\n");
+				cw1200_reg_write_16(priv,
+						    ST90TDS_CONTROL_REG_ID, 0);
+				priv->device_can_sleep = true;
+			}
+			goto done;
+		} else if (suspend) {
+			pr_debug("[BH] Device suspend.\n");
+			if (priv->powersave_enabled) {
+				pr_debug("[BH] Device wakedown. Suspend.\n");
+				cw1200_reg_write_16(priv,
+						    ST90TDS_CONTROL_REG_ID, 0);
+				priv->device_can_sleep = true;
+			}
+
+			atomic_set(&priv->bh_suspend, CW1200_BH_SUSPENDED);
+			wake_up(&priv->bh_evt_wq);
+			status = wait_event_interruptible(priv->bh_wq,
+							  CW1200_BH_RESUME == atomic_read(&priv->bh_suspend));
+			if (status < 0) {
+				wiphy_err(priv->hw->wiphy,
+					  "Failed to wait for resume: %ld.\n",
+					  status);
+				break;
+			}
+			pr_debug("[BH] Device resume.\n");
+			atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
+			wake_up(&priv->bh_evt_wq);
+			atomic_add(1, &priv->bh_rx);
+			goto done;
+		}
+
+	rx:
+		tx += pending_tx;
+		pending_tx = 0;
+
+		if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
+			break;
+
+		/* Don't bother trying to rx unless we have data to read */
+		if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
+			ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
+			if (ret < 0)
+				break;
+			/* Double up here if there's more data.. */
+			if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
+				ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
+				if (ret < 0)
+					break;
+			}
+		}
+
+	tx:
+		if (tx) {
+			tx = 0;
+
+			BUG_ON(priv->hw_bufs_used > priv->wsm_caps.input_buffers);
+			tx_burst = priv->wsm_caps.input_buffers - priv->hw_bufs_used;
+			tx_allowed = tx_burst > 0;
+
+			if (!tx_allowed) {
+				/* Buffers full.  Ensure we process tx
+				 * after we handle rx..
+				 */
+				pending_tx = tx;
+				goto done_rx;
+			}
+			ret = cw1200_bh_tx_helper(priv, &pending_tx, &tx_burst);
+			if (ret < 0)
+				break;
+			if (ret > 0) /* More to transmit */
+				tx = ret;
+
+			/* Re-read ctrl reg */
+			if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
+				break;
+		}
+
+	done_rx:
+		if (priv->bh_error)
+			break;
+		if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK)
+			goto rx;
+		if (tx)
+			goto tx;
+
+	done:
+		/* Re-enable device interrupts */
+		priv->hwbus_ops->lock(priv->hwbus_priv);
+		__cw1200_irq_enable(priv, 1);
+		priv->hwbus_ops->unlock(priv->hwbus_priv);
+	}
+
+	/* Explicitly disable device interrupts */
+	priv->hwbus_ops->lock(priv->hwbus_priv);
+	__cw1200_irq_enable(priv, 0);
+	priv->hwbus_ops->unlock(priv->hwbus_priv);
+
+	if (!term) {
+		pr_err("[BH] Fatal error, exiting.\n");
+		priv->bh_error = 1;
+		/* TODO: schedule_work(recovery) */
+	}
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/bh.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/bh.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/bh.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/bh.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * Device handling thread interface for mac80211 ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef CW1200_BH_H
+#define CW1200_BH_H
+
+/* extern */ struct cw1200_common;
+
+int cw1200_register_bh(struct cw1200_common *priv);
+void cw1200_unregister_bh(struct cw1200_common *priv);
+void cw1200_irq_handler(struct cw1200_common *priv);
+void cw1200_bh_wakeup(struct cw1200_common *priv);
+int cw1200_bh_suspend(struct cw1200_common *priv);
+int cw1200_bh_resume(struct cw1200_common *priv);
+/* Must be called from BH thread. */
+void cw1200_enable_powersave(struct cw1200_common *priv,
+			     bool enable);
+int wsm_release_tx_buffer(struct cw1200_common *priv, int count);
+
+#endif /* CW1200_BH_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/cw1200.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/cw1200.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/cw1200.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/cw1200.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,323 @@
+/*
+ * Common private data for ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * Based on the mac80211 Prism54 code, which is
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ *
+ * Based on the islsm (softmac prism54) driver, which is:
+ * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef CW1200_H
+#define CW1200_H
+
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <net/mac80211.h>
+
+#include "queue.h"
+#include "wsm.h"
+#include "scan.h"
+#include "txrx.h"
+#include "pm.h"
+
+/* Forward declarations */
+struct hwbus_ops;
+struct task_struct;
+struct cw1200_debug_priv;
+struct firmware;
+
+#define CW1200_MAX_CTRL_FRAME_LEN	(0x1000)
+
+#define CW1200_MAX_STA_IN_AP_MODE	(5)
+#define CW1200_LINK_ID_AFTER_DTIM	(CW1200_MAX_STA_IN_AP_MODE + 1)
+#define CW1200_LINK_ID_UAPSD		(CW1200_MAX_STA_IN_AP_MODE + 2)
+#define CW1200_LINK_ID_MAX		(CW1200_MAX_STA_IN_AP_MODE + 3)
+#define CW1200_MAX_REQUEUE_ATTEMPTS	(5)
+
+#define CW1200_MAX_TID			(8)
+
+#define CW1200_BLOCK_ACK_CNT		(30)
+#define CW1200_BLOCK_ACK_THLD		(800)
+#define CW1200_BLOCK_ACK_HIST		(3)
+#define CW1200_BLOCK_ACK_INTERVAL	(1 * HZ / CW1200_BLOCK_ACK_HIST)
+
+#define CW1200_JOIN_TIMEOUT		(1 * HZ)
+#define CW1200_AUTH_TIMEOUT		(5 * HZ)
+
+struct cw1200_ht_info {
+	struct ieee80211_sta_ht_cap     ht_cap;
+	enum nl80211_channel_type       channel_type;
+	u16                             operation_mode;
+};
+
+/* Please keep order */
+enum cw1200_join_status {
+	CW1200_JOIN_STATUS_PASSIVE = 0,
+	CW1200_JOIN_STATUS_MONITOR,
+	CW1200_JOIN_STATUS_JOINING,
+	CW1200_JOIN_STATUS_PRE_STA,
+	CW1200_JOIN_STATUS_STA,
+	CW1200_JOIN_STATUS_IBSS,
+	CW1200_JOIN_STATUS_AP,
+};
+
+enum cw1200_link_status {
+	CW1200_LINK_OFF,
+	CW1200_LINK_RESERVE,
+	CW1200_LINK_SOFT,
+	CW1200_LINK_HARD,
+	CW1200_LINK_RESET,
+	CW1200_LINK_RESET_REMAP,
+};
+
+extern int cw1200_power_mode;
+extern const char * const cw1200_fw_types[];
+
+struct cw1200_link_entry {
+	unsigned long			timestamp;
+	enum cw1200_link_status		status;
+	enum cw1200_link_status		prev_status;
+	u8				mac[ETH_ALEN];
+	u8				buffered[CW1200_MAX_TID];
+	struct sk_buff_head		rx_queue;
+};
+
+struct cw1200_common {
+	/* interfaces to the rest of the stack */
+	struct ieee80211_hw		*hw;
+	struct ieee80211_vif		*vif;
+	struct device			*pdev;
+
+	/* Statistics */
+	struct ieee80211_low_level_stats stats;
+
+	/* Our macaddr */
+	u8 mac_addr[ETH_ALEN];
+
+	/* Hardware interface */
+	const struct hwbus_ops		*hwbus_ops;
+	struct hwbus_priv		*hwbus_priv;
+
+	/* Hardware information */
+	enum {
+		HIF_9000_SILICON_VERSATILE = 0,
+		HIF_8601_VERSATILE,
+		HIF_8601_SILICON,
+	} hw_type;
+	enum {
+		CW1200_HW_REV_CUT10 = 10,
+		CW1200_HW_REV_CUT11 = 11,
+		CW1200_HW_REV_CUT20 = 20,
+		CW1200_HW_REV_CUT22 = 22,
+		CW1X60_HW_REV       = 40,
+	} hw_revision;
+	int                             hw_refclk;
+	bool				hw_have_5ghz;
+	const struct firmware		*sdd;
+	char                            *sdd_path;
+
+	struct cw1200_debug_priv	*debug;
+
+	struct workqueue_struct		*workqueue;
+	struct mutex			conf_mutex;
+
+	struct cw1200_queue		tx_queue[4];
+	struct cw1200_queue_stats	tx_queue_stats;
+	int				tx_burst_idx;
+
+	/* firmware/hardware info */
+	unsigned int tx_hdr_len;
+
+	/* Radio data */
+	int output_power;
+
+	/* BBP/MAC state */
+	struct ieee80211_rate		*rates;
+	struct ieee80211_rate		*mcs_rates;
+	struct ieee80211_channel	*channel;
+	struct wsm_edca_params		edca;
+	struct wsm_tx_queue_params	tx_queue_params;
+	struct wsm_mib_association_mode	association_mode;
+	struct wsm_set_bss_params	bss_params;
+	struct cw1200_ht_info		ht_info;
+	struct wsm_set_pm		powersave_mode;
+	struct wsm_set_pm		firmware_ps_mode;
+	int				cqm_rssi_thold;
+	unsigned			cqm_rssi_hyst;
+	bool				cqm_use_rssi;
+	int				cqm_beacon_loss_count;
+	int				channel_switch_in_progress;
+	wait_queue_head_t		channel_switch_done;
+	u8				long_frame_max_tx_count;
+	u8				short_frame_max_tx_count;
+	int				mode;
+	bool				enable_beacon;
+	int				beacon_int;
+	bool				listening;
+	struct wsm_rx_filter		rx_filter;
+	struct wsm_mib_multicast_filter multicast_filter;
+	bool				has_multicast_subscription;
+	bool				disable_beacon_filter;
+	struct work_struct		update_filtering_work;
+	struct work_struct		set_beacon_wakeup_period_work;
+
+	u8				ba_rx_tid_mask;
+	u8				ba_tx_tid_mask;
+
+	struct cw1200_pm_state		pm_state;
+
+	struct wsm_p2p_ps_modeinfo	p2p_ps_modeinfo;
+	struct wsm_uapsd_info		uapsd_info;
+	bool				setbssparams_done;
+	bool				bt_present;
+	u8				conf_listen_interval;
+	u32				listen_interval;
+	u32				erp_info;
+	u32				rts_threshold;
+
+	/* BH */
+	atomic_t			bh_rx;
+	atomic_t			bh_tx;
+	atomic_t			bh_term;
+	atomic_t			bh_suspend;
+
+	struct workqueue_struct         *bh_workqueue;
+	struct work_struct              bh_work;
+
+	int				bh_error;
+	wait_queue_head_t		bh_wq;
+	wait_queue_head_t		bh_evt_wq;
+	u8				buf_id_tx;
+	u8				buf_id_rx;
+	u8				wsm_rx_seq;
+	u8				wsm_tx_seq;
+	int				hw_bufs_used;
+	bool				powersave_enabled;
+	bool				device_can_sleep;
+
+	/* Scan status */
+	struct cw1200_scan scan;
+	/* Keep cw1200 awake (WUP = 1) 1 second after each scan to avoid
+	 * FW issue with sleeping/waking up.
+	 */
+	atomic_t			recent_scan;
+	struct delayed_work		clear_recent_scan_work;
+
+	/* WSM */
+	struct wsm_startup_ind		wsm_caps;
+	struct mutex			wsm_cmd_mux;
+	struct wsm_buf			wsm_cmd_buf;
+	struct wsm_cmd			wsm_cmd;
+	wait_queue_head_t		wsm_cmd_wq;
+	wait_queue_head_t		wsm_startup_done;
+	int                             firmware_ready;
+	atomic_t			tx_lock;
+
+	/* WSM debug */
+	int				wsm_enable_wsm_dumps;
+
+	/* WSM Join */
+	enum cw1200_join_status	join_status;
+	u32			pending_frame_id;
+	bool			join_pending;
+	struct delayed_work	join_timeout;
+	struct work_struct	unjoin_work;
+	struct work_struct	join_complete_work;
+	int			join_complete_status;
+	int			join_dtim_period;
+	bool			delayed_unjoin;
+
+	/* TX/RX and security */
+	s8			wep_default_key_id;
+	struct work_struct	wep_key_work;
+	u32			key_map;
+	struct wsm_add_key	keys[WSM_KEY_MAX_INDEX + 1];
+
+	/* AP powersave */
+	u32			link_id_map;
+	struct cw1200_link_entry link_id_db[CW1200_MAX_STA_IN_AP_MODE];
+	struct work_struct	link_id_work;
+	struct delayed_work	link_id_gc_work;
+	u32			sta_asleep_mask;
+	u32			pspoll_mask;
+	bool			aid0_bit_set;
+	spinlock_t		ps_state_lock; /* Protect power save state */
+	bool			buffered_multicasts;
+	bool			tx_multicast;
+	struct work_struct	set_tim_work;
+	struct work_struct	set_cts_work;
+	struct work_struct	multicast_start_work;
+	struct work_struct	multicast_stop_work;
+	struct timer_list	mcast_timeout;
+
+	/* WSM events and CQM implementation */
+	spinlock_t		event_queue_lock; /* Protect event queue */
+	struct list_head	event_queue;
+	struct work_struct	event_handler;
+
+	struct delayed_work	bss_loss_work;
+	spinlock_t		bss_loss_lock; /* Protect BSS loss state */
+	int                     bss_loss_state;
+	u32                     bss_loss_confirm_id;
+	int			delayed_link_loss;
+	struct work_struct	bss_params_work;
+
+	/* TX rate policy cache */
+	struct tx_policy_cache tx_policy_cache;
+	struct work_struct tx_policy_upload_work;
+
+	/* legacy PS mode switch in suspend */
+	int			ps_mode_switch_in_progress;
+	wait_queue_head_t	ps_mode_switch_done;
+
+	/* Workaround for WFD testcase 6.1.10*/
+	struct work_struct	linkid_reset_work;
+	u8			action_frame_sa[ETH_ALEN];
+	u8			action_linkid;
+};
+
+struct cw1200_sta_priv {
+	int link_id;
+};
+
+/* interfaces for the drivers */
+int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
+		      struct hwbus_priv *hwbus,
+		      struct device *pdev,
+		      struct cw1200_common **pself,
+		      int ref_clk, const u8 *macaddr,
+		      const char *sdd_path, bool have_5ghz);
+void cw1200_core_release(struct cw1200_common *self);
+
+#define FWLOAD_BLOCK_SIZE (1024)
+
+static inline int cw1200_is_ht(const struct cw1200_ht_info *ht_info)
+{
+	return ht_info->channel_type != NL80211_CHAN_NO_HT;
+}
+
+static inline int cw1200_ht_greenfield(const struct cw1200_ht_info *ht_info)
+{
+	return cw1200_is_ht(ht_info) &&
+		(ht_info->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
+		!(ht_info->operation_mode &
+		  IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+}
+
+static inline int cw1200_ht_ampdu_density(const struct cw1200_ht_info *ht_info)
+{
+	if (!cw1200_is_ht(ht_info))
+		return 0;
+	return ht_info->ht_cap.ampdu_density;
+}
+
+#endif /* CW1200_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/cw1200_sdio.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/cw1200_sdio.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/cw1200_sdio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/cw1200_sdio.c	2013-08-31 17:59:33.000000000 -0400
@@ -0,0 +1,425 @@
+/*
+ * Mac80211 SDIO driver for ST-Ericsson CW1200 device
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <net/mac80211.h>
+
+#include "cw1200.h"
+#include "hwbus.h"
+#include <linux/platform_data/net-cw1200.h>
+#include "hwio.h"
+
+MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
+MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SDIO driver");
+MODULE_LICENSE("GPL");
+
+#define SDIO_BLOCK_SIZE (512)
+
+/* Default platform data for Sagrad modules */
+static struct cw1200_platform_data_sdio sagrad_109x_evk_platform_data = {
+	.ref_clk = 38400,
+	.have_5ghz = false,
+	.sdd_file = "/*(DEBLOBBED)*/",
+};
+
+/* Allow platform data to be overridden */
+static struct cw1200_platform_data_sdio *global_plat_data = &sagrad_109x_evk_platform_data;
+
+void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata)
+{
+	global_plat_data = pdata;
+}
+
+struct hwbus_priv {
+	struct sdio_func	*func;
+	struct cw1200_common	*core;
+	const struct cw1200_platform_data_sdio *pdata;
+};
+
+#ifndef SDIO_VENDOR_ID_STE
+#define SDIO_VENDOR_ID_STE		0x0020
+#endif
+
+#ifndef SDIO_DEVICE_ID_STE_CW1200
+#define SDIO_DEVICE_ID_STE_CW1200	0x2280
+#endif
+
+static const struct sdio_device_id cw1200_sdio_ids[] = {
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) },
+	{ /* end: all zeroes */			},
+};
+
+/* hwbus_ops implemetation */
+
+static int cw1200_sdio_memcpy_fromio(struct hwbus_priv *self,
+				     unsigned int addr,
+				     void *dst, int count)
+{
+	return sdio_memcpy_fromio(self->func, dst, addr, count);
+}
+
+static int cw1200_sdio_memcpy_toio(struct hwbus_priv *self,
+				   unsigned int addr,
+				   const void *src, int count)
+{
+	return sdio_memcpy_toio(self->func, addr, (void *)src, count);
+}
+
+static void cw1200_sdio_lock(struct hwbus_priv *self)
+{
+	sdio_claim_host(self->func);
+}
+
+static void cw1200_sdio_unlock(struct hwbus_priv *self)
+{
+	sdio_release_host(self->func);
+}
+
+static void cw1200_sdio_irq_handler(struct sdio_func *func)
+{
+	struct hwbus_priv *self = sdio_get_drvdata(func);
+
+	/* note:  sdio_host already claimed here. */
+	if (self->core)
+		cw1200_irq_handler(self->core);
+}
+
+static irqreturn_t cw1200_gpio_hardirq(int irq, void *dev_id)
+{
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
+{
+	struct hwbus_priv *self = dev_id;
+
+	if (self->core) {
+		sdio_claim_host(self->func);
+		cw1200_irq_handler(self->core);
+		sdio_release_host(self->func);
+		return IRQ_HANDLED;
+	} else {
+		return IRQ_NONE;
+	}
+}
+
+static int cw1200_request_irq(struct hwbus_priv *self)
+{
+	int ret;
+	u8 cccr;
+
+	cccr = sdio_f0_readb(self->func, SDIO_CCCR_IENx, &ret);
+	if (WARN_ON(ret))
+		goto err;
+
+	/* Master interrupt enable ... */
+	cccr |= BIT(0);
+
+	/* ... for our function */
+	cccr |= BIT(self->func->num);
+
+	sdio_f0_writeb(self->func, cccr, SDIO_CCCR_IENx, &ret);
+	if (WARN_ON(ret))
+		goto err;
+
+	ret = enable_irq_wake(self->pdata->irq);
+	if (WARN_ON(ret))
+		goto err;
+
+	/* Request the IRQ */
+	ret =  request_threaded_irq(self->pdata->irq, cw1200_gpio_hardirq,
+				    cw1200_gpio_irq,
+				    IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+				    "cw1200_wlan_irq", self);
+	if (WARN_ON(ret))
+		goto err;
+
+	return 0;
+
+err:
+	return ret;
+}
+
+static int cw1200_sdio_irq_subscribe(struct hwbus_priv *self)
+{
+	int ret = 0;
+
+	pr_debug("SW IRQ subscribe\n");
+	sdio_claim_host(self->func);
+	if (self->pdata->irq)
+		ret = cw1200_request_irq(self);
+	else
+		ret = sdio_claim_irq(self->func, cw1200_sdio_irq_handler);
+
+	sdio_release_host(self->func);
+	return ret;
+}
+
+static int cw1200_sdio_irq_unsubscribe(struct hwbus_priv *self)
+{
+	int ret = 0;
+
+	pr_debug("SW IRQ unsubscribe\n");
+
+	if (self->pdata->irq) {
+		disable_irq_wake(self->pdata->irq);
+		free_irq(self->pdata->irq, self);
+	} else {
+		sdio_claim_host(self->func);
+		ret = sdio_release_irq(self->func);
+		sdio_release_host(self->func);
+	}
+	return ret;
+}
+
+static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata)
+{
+	if (pdata->reset) {
+		gpio_set_value(pdata->reset, 0);
+		msleep(30); /* Min is 2 * CLK32K cycles */
+		gpio_free(pdata->reset);
+	}
+
+	if (pdata->power_ctrl)
+		pdata->power_ctrl(pdata, false);
+	if (pdata->clk_ctrl)
+		pdata->clk_ctrl(pdata, false);
+
+	return 0;
+}
+
+static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata)
+{
+	/* Ensure I/Os are pulled low */
+	if (pdata->reset) {
+		gpio_request(pdata->reset, "cw1200_wlan_reset");
+		gpio_direction_output(pdata->reset, 0);
+	}
+	if (pdata->powerup) {
+		gpio_request(pdata->powerup, "cw1200_wlan_powerup");
+		gpio_direction_output(pdata->powerup, 0);
+	}
+	if (pdata->reset || pdata->powerup)
+		msleep(10); /* Settle time? */
+
+	/* Enable 3v3 and 1v8 to hardware */
+	if (pdata->power_ctrl) {
+		if (pdata->power_ctrl(pdata, true)) {
+			pr_err("power_ctrl() failed!\n");
+			return -1;
+		}
+	}
+
+	/* Enable CLK32K */
+	if (pdata->clk_ctrl) {
+		if (pdata->clk_ctrl(pdata, true)) {
+			pr_err("clk_ctrl() failed!\n");
+			return -1;
+		}
+		msleep(10); /* Delay until clock is stable for 2 cycles */
+	}
+
+	/* Enable POWERUP signal */
+	if (pdata->powerup) {
+		gpio_set_value(pdata->powerup, 1);
+		msleep(250); /* or more..? */
+	}
+	/* Enable RSTn signal */
+	if (pdata->reset) {
+		gpio_set_value(pdata->reset, 1);
+		msleep(50); /* Or more..? */
+	}
+	return 0;
+}
+
+static size_t cw1200_sdio_align_size(struct hwbus_priv *self, size_t size)
+{
+	if (self->pdata->no_nptb)
+		size = round_up(size, SDIO_BLOCK_SIZE);
+	else
+		size = sdio_align_size(self->func, size);
+
+	return size;
+}
+
+static int cw1200_sdio_pm(struct hwbus_priv *self, bool suspend)
+{
+	int ret = 0;
+
+	if (self->pdata->irq)
+		ret = irq_set_irq_wake(self->pdata->irq, suspend);
+	return ret;
+}
+
+static struct hwbus_ops cw1200_sdio_hwbus_ops = {
+	.hwbus_memcpy_fromio	= cw1200_sdio_memcpy_fromio,
+	.hwbus_memcpy_toio	= cw1200_sdio_memcpy_toio,
+	.lock			= cw1200_sdio_lock,
+	.unlock			= cw1200_sdio_unlock,
+	.align_size		= cw1200_sdio_align_size,
+	.power_mgmt		= cw1200_sdio_pm,
+};
+
+/* Probe Function to be called by SDIO stack when device is discovered */
+static int cw1200_sdio_probe(struct sdio_func *func,
+			     const struct sdio_device_id *id)
+{
+	struct hwbus_priv *self;
+	int status;
+
+	pr_info("cw1200_wlan_sdio: Probe called\n");
+
+	/* We are only able to handle the wlan function */
+	if (func->num != 0x01)
+		return -ENODEV;
+
+	self = kzalloc(sizeof(*self), GFP_KERNEL);
+	if (!self) {
+		pr_err("Can't allocate SDIO hwbus_priv.\n");
+		return -ENOMEM;
+	}
+
+	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
+
+	self->pdata = global_plat_data; /* FIXME */
+	self->func = func;
+	sdio_set_drvdata(func, self);
+	sdio_claim_host(func);
+	sdio_enable_func(func);
+	sdio_release_host(func);
+
+	status = cw1200_sdio_irq_subscribe(self);
+
+	status = cw1200_core_probe(&cw1200_sdio_hwbus_ops,
+				   self, &func->dev, &self->core,
+				   self->pdata->ref_clk,
+				   self->pdata->macaddr,
+				   self->pdata->sdd_file,
+				   self->pdata->have_5ghz);
+	if (status) {
+		cw1200_sdio_irq_unsubscribe(self);
+		sdio_claim_host(func);
+		sdio_disable_func(func);
+		sdio_release_host(func);
+		sdio_set_drvdata(func, NULL);
+		kfree(self);
+	}
+
+	return status;
+}
+
+/* Disconnect Function to be called by SDIO stack when
+ * device is disconnected
+ */
+static void cw1200_sdio_disconnect(struct sdio_func *func)
+{
+	struct hwbus_priv *self = sdio_get_drvdata(func);
+
+	if (self) {
+		cw1200_sdio_irq_unsubscribe(self);
+		if (self->core) {
+			cw1200_core_release(self->core);
+			self->core = NULL;
+		}
+		sdio_claim_host(func);
+		sdio_disable_func(func);
+		sdio_release_host(func);
+		sdio_set_drvdata(func, NULL);
+		kfree(self);
+	}
+}
+
+#ifdef CONFIG_PM
+static int cw1200_sdio_suspend(struct device *dev)
+{
+	int ret;
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	struct hwbus_priv *self = sdio_get_drvdata(func);
+
+	if (!cw1200_can_suspend(self->core))
+		return -EAGAIN;
+
+	/* Notify SDIO that CW1200 will remain powered during suspend */
+	ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+	if (ret)
+		pr_err("Error setting SDIO pm flags: %i\n", ret);
+
+	return ret;
+}
+
+static int cw1200_sdio_resume(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops cw1200_pm_ops = {
+	.suspend = cw1200_sdio_suspend,
+	.resume = cw1200_sdio_resume,
+};
+#endif
+
+static struct sdio_driver sdio_driver = {
+	.name		= "cw1200_wlan_sdio",
+	.id_table	= cw1200_sdio_ids,
+	.probe		= cw1200_sdio_probe,
+	.remove		= cw1200_sdio_disconnect,
+#ifdef CONFIG_PM
+	.drv = {
+		.pm = &cw1200_pm_ops,
+	}
+#endif
+};
+
+/* Init Module function -> Called by insmod */
+static int __init cw1200_sdio_init(void)
+{
+	const struct cw1200_platform_data_sdio *pdata;
+	int ret;
+
+	/* FIXME -- this won't support multiple devices */
+	pdata = global_plat_data;
+
+	if (cw1200_sdio_on(pdata)) {
+		ret = -1;
+		goto err;
+	}
+
+	ret = sdio_register_driver(&sdio_driver);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	cw1200_sdio_off(pdata);
+	return ret;
+}
+
+/* Called at Driver Unloading */
+static void __exit cw1200_sdio_exit(void)
+{
+	const struct cw1200_platform_data_sdio *pdata;
+
+	/* FIXME -- this won't support multiple devices */
+	pdata = global_plat_data;
+	sdio_unregister_driver(&sdio_driver);
+	cw1200_sdio_off(pdata);
+}
+
+
+module_init(cw1200_sdio_init);
+module_exit(cw1200_sdio_exit);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/cw1200_spi.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/cw1200_spi.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/cw1200_spi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/cw1200_spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,471 @@
+/*
+ * Mac80211 SPI driver for ST-Ericsson CW1200 device
+ *
+ * Copyright (c) 2011, Sagrad Inc.
+ * Author:  Solomon Peachy <speachy@sagrad.com>
+ *
+ * Based on cw1200_sdio.c
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <net/mac80211.h>
+
+#include <linux/spi/spi.h>
+#include <linux/device.h>
+
+#include "cw1200.h"
+#include "hwbus.h"
+#include <linux/platform_data/net-cw1200.h>
+#include "hwio.h"
+
+MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
+MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SPI driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:cw1200_wlan_spi");
+
+/* #define SPI_DEBUG */
+
+struct hwbus_priv {
+	struct spi_device	*func;
+	struct cw1200_common	*core;
+	const struct cw1200_platform_data_spi *pdata;
+	spinlock_t		lock; /* Serialize all bus operations */
+	int claimed;
+};
+
+#define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2)
+#define SET_WRITE 0x7FFF /* usage: and operation */
+#define SET_READ 0x8000  /* usage: or operation */
+
+/* Notes on byte ordering:
+   LE:  B0 B1 B2 B3
+   BE:  B3 B2 B1 B0
+
+   Hardware expects 32-bit data to be written as 16-bit BE words:
+
+   B1 B0 B3 B2
+*/
+
+static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
+				     unsigned int addr,
+				     void *dst, int count)
+{
+	int ret, i;
+	u16 regaddr;
+	struct spi_message      m;
+
+	struct spi_transfer     t_addr = {
+		.tx_buf         = &regaddr,
+		.len            = sizeof(regaddr),
+	};
+	struct spi_transfer     t_msg = {
+		.rx_buf         = dst,
+		.len            = count,
+	};
+
+	regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
+	regaddr |= SET_READ;
+	regaddr |= (count>>1);
+
+#ifdef SPI_DEBUG
+	pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr, regaddr);
+#endif
+
+	/* Header is LE16 */
+	regaddr = cpu_to_le16(regaddr);
+
+	/* We have to byteswap if the SPI bus is limited to 8b operation
+	   or we are running on a Big Endian system
+	*/
+#if defined(__LITTLE_ENDIAN)
+	if (self->func->bits_per_word == 8)
+#endif
+		regaddr = swab16(regaddr);
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t_addr, &m);
+	spi_message_add_tail(&t_msg, &m);
+	ret = spi_sync(self->func, &m);
+
+#ifdef SPI_DEBUG
+	pr_info("READ : ");
+	for (i = 0; i < t_addr.len; i++)
+		printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
+	printk(" : ");
+	for (i = 0; i < t_msg.len; i++)
+		printk("%02x ", ((u8 *)t_msg.rx_buf)[i]);
+	printk("\n");
+#endif
+
+	/* We have to byteswap if the SPI bus is limited to 8b operation
+	   or we are running on a Big Endian system
+	*/
+#if defined(__LITTLE_ENDIAN)
+	if (self->func->bits_per_word == 8)
+#endif
+	{
+		uint16_t *buf = (uint16_t *)dst;
+		for (i = 0; i < ((count + 1) >> 1); i++)
+			buf[i] = swab16(buf[i]);
+	}
+
+	return ret;
+}
+
+static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
+				   unsigned int addr,
+				   const void *src, int count)
+{
+	int rval, i;
+	u16 regaddr;
+	struct spi_transfer     t_addr = {
+		.tx_buf         = &regaddr,
+		.len            = sizeof(regaddr),
+	};
+	struct spi_transfer     t_msg = {
+		.tx_buf         = src,
+		.len            = count,
+	};
+	struct spi_message      m;
+
+	regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
+	regaddr &= SET_WRITE;
+	regaddr |= (count>>1);
+
+#ifdef SPI_DEBUG
+	pr_info("WRITE: %04d  to  0x%02x (%04x)\n", count, addr, regaddr);
+#endif
+
+	/* Header is LE16 */
+	regaddr = cpu_to_le16(regaddr);
+
+	/* We have to byteswap if the SPI bus is limited to 8b operation
+	   or we are running on a Big Endian system
+	*/
+#if defined(__LITTLE_ENDIAN)
+	if (self->func->bits_per_word == 8)
+#endif
+	{
+		uint16_t *buf = (uint16_t *)src;
+	        regaddr = swab16(regaddr);
+		for (i = 0; i < ((count + 1) >> 1); i++)
+			buf[i] = swab16(buf[i]);
+	}
+
+#ifdef SPI_DEBUG
+	pr_info("WRITE: ");
+	for (i = 0; i < t_addr.len; i++)
+		printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
+	printk(" : ");
+	for (i = 0; i < t_msg.len; i++)
+		printk("%02x ", ((u8 *)t_msg.tx_buf)[i]);
+	printk("\n");
+#endif
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t_addr, &m);
+	spi_message_add_tail(&t_msg, &m);
+	rval = spi_sync(self->func, &m);
+
+#ifdef SPI_DEBUG
+	pr_info("WROTE: %d\n", m.actual_length);
+#endif
+
+#if defined(__LITTLE_ENDIAN)
+	/* We have to byteswap if the SPI bus is limited to 8b operation */
+	if (self->func->bits_per_word == 8)
+#endif
+	{
+		uint16_t *buf = (uint16_t *)src;
+		for (i = 0; i < ((count + 1) >> 1); i++)
+			buf[i] = swab16(buf[i]);
+	}
+	return rval;
+}
+
+static void cw1200_spi_lock(struct hwbus_priv *self)
+{
+	unsigned long flags;
+
+	might_sleep();
+
+	spin_lock_irqsave(&self->lock, flags);
+	while (1) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		if (!self->claimed)
+			break;
+		spin_unlock_irqrestore(&self->lock, flags);
+		schedule();
+		spin_lock_irqsave(&self->lock, flags);
+	}
+	set_current_state(TASK_RUNNING);
+	self->claimed = 1;
+	spin_unlock_irqrestore(&self->lock, flags);
+
+	return;
+}
+
+static void cw1200_spi_unlock(struct hwbus_priv *self)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&self->lock, flags);
+	self->claimed = 0;
+	spin_unlock_irqrestore(&self->lock, flags);
+	return;
+}
+
+static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
+{
+	struct hwbus_priv *self = dev_id;
+
+	if (self->core) {
+		cw1200_irq_handler(self->core);
+		return IRQ_HANDLED;
+	} else {
+		return IRQ_NONE;
+	}
+}
+
+static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
+{
+	int ret;
+
+	pr_debug("SW IRQ subscribe\n");
+
+	ret = request_any_context_irq(self->func->irq, cw1200_spi_irq_handler,
+				      IRQF_TRIGGER_HIGH,
+				      "cw1200_wlan_irq", self);
+	if (WARN_ON(ret < 0))
+		goto exit;
+
+	ret = enable_irq_wake(self->func->irq);
+	if (WARN_ON(ret))
+		goto free_irq;
+
+	return 0;
+
+free_irq:
+	free_irq(self->func->irq, self);
+exit:
+	return ret;
+}
+
+static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
+{
+	int ret = 0;
+
+	pr_debug("SW IRQ unsubscribe\n");
+	disable_irq_wake(self->func->irq);
+	free_irq(self->func->irq, self);
+
+	return ret;
+}
+
+static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
+{
+	if (pdata->reset) {
+		gpio_set_value(pdata->reset, 0);
+		msleep(30); /* Min is 2 * CLK32K cycles */
+		gpio_free(pdata->reset);
+	}
+
+	if (pdata->power_ctrl)
+		pdata->power_ctrl(pdata, false);
+	if (pdata->clk_ctrl)
+		pdata->clk_ctrl(pdata, false);
+
+	return 0;
+}
+
+static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
+{
+	/* Ensure I/Os are pulled low */
+	if (pdata->reset) {
+		gpio_request(pdata->reset, "cw1200_wlan_reset");
+		gpio_direction_output(pdata->reset, 0);
+	}
+	if (pdata->powerup) {
+		gpio_request(pdata->powerup, "cw1200_wlan_powerup");
+		gpio_direction_output(pdata->powerup, 0);
+	}
+	if (pdata->reset || pdata->powerup)
+		msleep(10); /* Settle time? */
+
+	/* Enable 3v3 and 1v8 to hardware */
+	if (pdata->power_ctrl) {
+		if (pdata->power_ctrl(pdata, true)) {
+			pr_err("power_ctrl() failed!\n");
+			return -1;
+		}
+	}
+
+	/* Enable CLK32K */
+	if (pdata->clk_ctrl) {
+		if (pdata->clk_ctrl(pdata, true)) {
+			pr_err("clk_ctrl() failed!\n");
+			return -1;
+		}
+		msleep(10); /* Delay until clock is stable for 2 cycles */
+	}
+
+	/* Enable POWERUP signal */
+	if (pdata->powerup) {
+		gpio_set_value(pdata->powerup, 1);
+		msleep(250); /* or more..? */
+	}
+	/* Enable RSTn signal */
+	if (pdata->reset) {
+		gpio_set_value(pdata->reset, 1);
+		msleep(50); /* Or more..? */
+	}
+	return 0;
+}
+
+static size_t cw1200_spi_align_size(struct hwbus_priv *self, size_t size)
+{
+	return size & 1 ? size + 1 : size;
+}
+
+static int cw1200_spi_pm(struct hwbus_priv *self, bool suspend)
+{
+	return irq_set_irq_wake(self->func->irq, suspend);
+}
+
+static struct hwbus_ops cw1200_spi_hwbus_ops = {
+	.hwbus_memcpy_fromio	= cw1200_spi_memcpy_fromio,
+	.hwbus_memcpy_toio	= cw1200_spi_memcpy_toio,
+	.lock			= cw1200_spi_lock,
+	.unlock			= cw1200_spi_unlock,
+	.align_size		= cw1200_spi_align_size,
+	.power_mgmt		= cw1200_spi_pm,
+};
+
+/* Probe Function to be called by SPI stack when device is discovered */
+static int cw1200_spi_probe(struct spi_device *func)
+{
+	const struct cw1200_platform_data_spi *plat_data =
+		func->dev.platform_data;
+	struct hwbus_priv *self;
+	int status;
+
+	/* Sanity check speed */
+	if (func->max_speed_hz > 52000000)
+		func->max_speed_hz = 52000000;
+	if (func->max_speed_hz < 1000000)
+		func->max_speed_hz = 1000000;
+
+	/* Fix up transfer size */
+	if (plat_data->spi_bits_per_word)
+		func->bits_per_word = plat_data->spi_bits_per_word;
+	if (!func->bits_per_word)
+		func->bits_per_word = 16;
+
+	/* And finally.. */
+	func->mode = SPI_MODE_0;
+
+	pr_info("cw1200_wlan_spi: Probe called (CS %d M %d BPW %d CLK %d)\n",
+		func->chip_select, func->mode, func->bits_per_word,
+		func->max_speed_hz);
+
+	if (cw1200_spi_on(plat_data)) {
+		pr_err("spi_on() failed!\n");
+		return -1;
+	}
+
+	if (spi_setup(func)) {
+		pr_err("spi_setup() failed!\n");
+		return -1;
+	}
+
+	self = kzalloc(sizeof(*self), GFP_KERNEL);
+	if (!self) {
+		pr_err("Can't allocate SPI hwbus_priv.");
+		return -ENOMEM;
+	}
+
+	self->pdata = plat_data;
+	self->func = func;
+	spin_lock_init(&self->lock);
+
+	spi_set_drvdata(func, self);
+
+	status = cw1200_spi_irq_subscribe(self);
+
+	status = cw1200_core_probe(&cw1200_spi_hwbus_ops,
+				   self, &func->dev, &self->core,
+				   self->pdata->ref_clk,
+				   self->pdata->macaddr,
+				   self->pdata->sdd_file,
+				   self->pdata->have_5ghz);
+
+	if (status) {
+		cw1200_spi_irq_unsubscribe(self);
+		cw1200_spi_off(plat_data);
+		kfree(self);
+	}
+
+	return status;
+}
+
+/* Disconnect Function to be called by SPI stack when device is disconnected */
+static int cw1200_spi_disconnect(struct spi_device *func)
+{
+	struct hwbus_priv *self = spi_get_drvdata(func);
+
+	if (self) {
+		cw1200_spi_irq_unsubscribe(self);
+		if (self->core) {
+			cw1200_core_release(self->core);
+			self->core = NULL;
+		}
+		kfree(self);
+	}
+	cw1200_spi_off(func->dev.platform_data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int cw1200_spi_suspend(struct device *dev, pm_message_t state)
+{
+	struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev));
+
+	if (!cw1200_can_suspend(self->core))
+		return -EAGAIN;
+
+	/* XXX notify host that we have to keep CW1200 powered on? */
+	return 0;
+}
+
+static int cw1200_spi_resume(struct device *dev)
+{
+	return 0;
+}
+#endif
+
+static struct spi_driver spi_driver = {
+	.probe		= cw1200_spi_probe,
+	.remove		= cw1200_spi_disconnect,
+	.driver = {
+		.name		= "cw1200_wlan_spi",
+		.bus            = &spi_bus_type,
+		.owner          = THIS_MODULE,
+#ifdef CONFIG_PM
+		.suspend        = cw1200_spi_suspend,
+		.resume         = cw1200_spi_resume,
+#endif
+	},
+};
+
+module_spi_driver(spi_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/debug.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/debug.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/debug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,428 @@
+/*
+ * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
+ * DebugFS code
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include "cw1200.h"
+#include "debug.h"
+#include "fwio.h"
+
+/* join_status */
+static const char * const cw1200_debug_join_status[] = {
+	"passive",
+	"monitor",
+	"station (joining)",
+	"station (not authenticated yet)",
+	"station",
+	"adhoc",
+	"access point",
+};
+
+/* WSM_JOIN_PREAMBLE_... */
+static const char * const cw1200_debug_preamble[] = {
+	"long",
+	"short",
+	"long on 1 and 2 Mbps",
+};
+
+
+static const char * const cw1200_debug_link_id[] = {
+	"OFF",
+	"REQ",
+	"SOFT",
+	"HARD",
+};
+
+static const char *cw1200_debug_mode(int mode)
+{
+	switch (mode) {
+	case NL80211_IFTYPE_UNSPECIFIED:
+		return "unspecified";
+	case NL80211_IFTYPE_MONITOR:
+		return "monitor";
+	case NL80211_IFTYPE_STATION:
+		return "station";
+	case NL80211_IFTYPE_ADHOC:
+		return "adhoc";
+	case NL80211_IFTYPE_MESH_POINT:
+		return "mesh point";
+	case NL80211_IFTYPE_AP:
+		return "access point";
+	case NL80211_IFTYPE_P2P_CLIENT:
+		return "p2p client";
+	case NL80211_IFTYPE_P2P_GO:
+		return "p2p go";
+	default:
+		return "unsupported";
+	}
+}
+
+static void cw1200_queue_status_show(struct seq_file *seq,
+				     struct cw1200_queue *q)
+{
+	int i;
+	seq_printf(seq, "Queue       %d:\n", q->queue_id);
+	seq_printf(seq, "  capacity: %zu\n", q->capacity);
+	seq_printf(seq, "  queued:   %zu\n", q->num_queued);
+	seq_printf(seq, "  pending:  %zu\n", q->num_pending);
+	seq_printf(seq, "  sent:     %zu\n", q->num_sent);
+	seq_printf(seq, "  locked:   %s\n", q->tx_locked_cnt ? "yes" : "no");
+	seq_printf(seq, "  overfull: %s\n", q->overfull ? "yes" : "no");
+	seq_puts(seq,   "  link map: 0-> ");
+	for (i = 0; i < q->stats->map_capacity; ++i)
+		seq_printf(seq, "%.2d ", q->link_map_cache[i]);
+	seq_printf(seq, "<-%zu\n", q->stats->map_capacity);
+}
+
+static void cw1200_debug_print_map(struct seq_file *seq,
+				   struct cw1200_common *priv,
+				   const char *label,
+				   u32 map)
+{
+	int i;
+	seq_printf(seq, "%s0-> ", label);
+	for (i = 0; i < priv->tx_queue_stats.map_capacity; ++i)
+		seq_printf(seq, "%s ", (map & BIT(i)) ? "**" : "..");
+	seq_printf(seq, "<-%zu\n", priv->tx_queue_stats.map_capacity - 1);
+}
+
+static int cw1200_status_show(struct seq_file *seq, void *v)
+{
+	int i;
+	struct list_head *item;
+	struct cw1200_common *priv = seq->private;
+	struct cw1200_debug_priv *d = priv->debug;
+
+	seq_puts(seq,   "CW1200 Wireless LAN driver status\n");
+	seq_printf(seq, "Hardware:   %d.%d\n",
+		   priv->wsm_caps.hw_id,
+		   priv->wsm_caps.hw_subid);
+	seq_printf(seq, "Firmware:   %s %d.%d\n",
+		   cw1200_fw_types[priv->wsm_caps.fw_type],
+		   priv->wsm_caps.fw_ver,
+		   priv->wsm_caps.fw_build);
+	seq_printf(seq, "FW API:     %d\n",
+		   priv->wsm_caps.fw_api);
+	seq_printf(seq, "FW caps:    0x%.4X\n",
+		   priv->wsm_caps.fw_cap);
+	seq_printf(seq, "FW label:  '%s'\n",
+		   priv->wsm_caps.fw_label);
+	seq_printf(seq, "Mode:       %s%s\n",
+		   cw1200_debug_mode(priv->mode),
+		   priv->listening ? " (listening)" : "");
+	seq_printf(seq, "Join state: %s\n",
+		   cw1200_debug_join_status[priv->join_status]);
+	if (priv->channel)
+		seq_printf(seq, "Channel:    %d%s\n",
+			   priv->channel->hw_value,
+			   priv->channel_switch_in_progress ?
+			   " (switching)" : "");
+	if (priv->rx_filter.promiscuous)
+		seq_puts(seq,   "Filter:     promisc\n");
+	else if (priv->rx_filter.fcs)
+		seq_puts(seq,   "Filter:     fcs\n");
+	if (priv->rx_filter.bssid)
+		seq_puts(seq,   "Filter:     bssid\n");
+	if (!priv->disable_beacon_filter)
+		seq_puts(seq,   "Filter:     beacons\n");
+
+	if (priv->enable_beacon ||
+	    priv->mode == NL80211_IFTYPE_AP ||
+	    priv->mode == NL80211_IFTYPE_ADHOC ||
+	    priv->mode == NL80211_IFTYPE_MESH_POINT ||
+	    priv->mode == NL80211_IFTYPE_P2P_GO)
+		seq_printf(seq, "Beaconing:  %s\n",
+			   priv->enable_beacon ?
+			   "enabled" : "disabled");
+
+	for (i = 0; i < 4; ++i)
+		seq_printf(seq, "EDCA(%d):    %d, %d, %d, %d, %d\n", i,
+			   priv->edca.params[i].cwmin,
+			   priv->edca.params[i].cwmax,
+			   priv->edca.params[i].aifns,
+			   priv->edca.params[i].txop_limit,
+			   priv->edca.params[i].max_rx_lifetime);
+
+	if (priv->join_status == CW1200_JOIN_STATUS_STA) {
+		static const char *pm_mode = "unknown";
+		switch (priv->powersave_mode.mode) {
+		case WSM_PSM_ACTIVE:
+			pm_mode = "off";
+			break;
+		case WSM_PSM_PS:
+			pm_mode = "on";
+			break;
+		case WSM_PSM_FAST_PS:
+			pm_mode = "dynamic";
+			break;
+		}
+		seq_printf(seq, "Preamble:   %s\n",
+			   cw1200_debug_preamble[priv->association_mode.preamble]);
+		seq_printf(seq, "AMPDU spcn: %d\n",
+			   priv->association_mode.mpdu_start_spacing);
+		seq_printf(seq, "Basic rate: 0x%.8X\n",
+			   le32_to_cpu(priv->association_mode.basic_rate_set));
+		seq_printf(seq, "Bss lost:   %d beacons\n",
+			   priv->bss_params.beacon_lost_count);
+		seq_printf(seq, "AID:        %d\n",
+			   priv->bss_params.aid);
+		seq_printf(seq, "Rates:      0x%.8X\n",
+			   priv->bss_params.operational_rate_set);
+		seq_printf(seq, "Powersave:  %s\n", pm_mode);
+	}
+	seq_printf(seq, "HT:         %s\n",
+		   cw1200_is_ht(&priv->ht_info) ? "on" : "off");
+	if (cw1200_is_ht(&priv->ht_info)) {
+		seq_printf(seq, "Greenfield: %s\n",
+			   cw1200_ht_greenfield(&priv->ht_info) ? "yes" : "no");
+		seq_printf(seq, "AMPDU dens: %d\n",
+			   cw1200_ht_ampdu_density(&priv->ht_info));
+	}
+	seq_printf(seq, "RSSI thold: %d\n",
+		   priv->cqm_rssi_thold);
+	seq_printf(seq, "RSSI hyst:  %d\n",
+		   priv->cqm_rssi_hyst);
+	seq_printf(seq, "Long retr:  %d\n",
+		   priv->long_frame_max_tx_count);
+	seq_printf(seq, "Short retr: %d\n",
+		   priv->short_frame_max_tx_count);
+	spin_lock_bh(&priv->tx_policy_cache.lock);
+	i = 0;
+	list_for_each(item, &priv->tx_policy_cache.used)
+		++i;
+	spin_unlock_bh(&priv->tx_policy_cache.lock);
+	seq_printf(seq, "RC in use:  %d\n", i);
+
+	seq_puts(seq, "\n");
+	for (i = 0; i < 4; ++i) {
+		cw1200_queue_status_show(seq, &priv->tx_queue[i]);
+		seq_puts(seq, "\n");
+	}
+
+	cw1200_debug_print_map(seq, priv, "Link map:   ",
+			       priv->link_id_map);
+	cw1200_debug_print_map(seq, priv, "Asleep map: ",
+			       priv->sta_asleep_mask);
+	cw1200_debug_print_map(seq, priv, "PSPOLL map: ",
+			       priv->pspoll_mask);
+
+	seq_puts(seq, "\n");
+
+	for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
+		if (priv->link_id_db[i].status) {
+			seq_printf(seq, "Link %d:     %s, %pM\n",
+				   i + 1,
+				   cw1200_debug_link_id[priv->link_id_db[i].status],
+				   priv->link_id_db[i].mac);
+		}
+	}
+
+	seq_puts(seq, "\n");
+
+	seq_printf(seq, "BH status:  %s\n",
+		   atomic_read(&priv->bh_term) ? "terminated" : "alive");
+	seq_printf(seq, "Pending RX: %d\n",
+		   atomic_read(&priv->bh_rx));
+	seq_printf(seq, "Pending TX: %d\n",
+		   atomic_read(&priv->bh_tx));
+	if (priv->bh_error)
+		seq_printf(seq, "BH errcode: %d\n",
+			   priv->bh_error);
+	seq_printf(seq, "TX bufs:    %d x %d bytes\n",
+		   priv->wsm_caps.input_buffers,
+		   priv->wsm_caps.input_buffer_size);
+	seq_printf(seq, "Used bufs:  %d\n",
+		   priv->hw_bufs_used);
+	seq_printf(seq, "Powermgmt:  %s\n",
+		   priv->powersave_enabled ? "on" : "off");
+	seq_printf(seq, "Device:     %s\n",
+		   priv->device_can_sleep ? "asleep" : "awake");
+
+	spin_lock(&priv->wsm_cmd.lock);
+	seq_printf(seq, "WSM status: %s\n",
+		   priv->wsm_cmd.done ? "idle" : "active");
+	seq_printf(seq, "WSM cmd:    0x%.4X (%td bytes)\n",
+		   priv->wsm_cmd.cmd, priv->wsm_cmd.len);
+	seq_printf(seq, "WSM retval: %d\n",
+		   priv->wsm_cmd.ret);
+	spin_unlock(&priv->wsm_cmd.lock);
+
+	seq_printf(seq, "Datapath:   %s\n",
+		   atomic_read(&priv->tx_lock) ? "locked" : "unlocked");
+	if (atomic_read(&priv->tx_lock))
+		seq_printf(seq, "TXlock cnt: %d\n",
+			   atomic_read(&priv->tx_lock));
+
+	seq_printf(seq, "TXed:       %d\n",
+		   d->tx);
+	seq_printf(seq, "AGG TXed:   %d\n",
+		   d->tx_agg);
+	seq_printf(seq, "MULTI TXed: %d (%d)\n",
+		   d->tx_multi, d->tx_multi_frames);
+	seq_printf(seq, "RXed:       %d\n",
+		   d->rx);
+	seq_printf(seq, "AGG RXed:   %d\n",
+		   d->rx_agg);
+	seq_printf(seq, "TX miss:    %d\n",
+		   d->tx_cache_miss);
+	seq_printf(seq, "TX align:   %d\n",
+		   d->tx_align);
+	seq_printf(seq, "TX burst:   %d\n",
+		   d->tx_burst);
+	seq_printf(seq, "TX TTL:     %d\n",
+		   d->tx_ttl);
+	seq_printf(seq, "Scan:       %s\n",
+		   atomic_read(&priv->scan.in_progress) ? "active" : "idle");
+
+	return 0;
+}
+
+static int cw1200_status_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, &cw1200_status_show,
+		inode->i_private);
+}
+
+static const struct file_operations fops_status = {
+	.open = cw1200_status_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+static int cw1200_counters_show(struct seq_file *seq, void *v)
+{
+	int ret;
+	struct cw1200_common *priv = seq->private;
+	struct wsm_mib_counters_table counters;
+
+	ret = wsm_get_counters_table(priv, &counters);
+	if (ret)
+		return ret;
+
+#define PUT_COUNTER(tab, name) \
+	seq_printf(seq, "%s:" tab "%d\n", #name, \
+		__le32_to_cpu(counters.name))
+
+	PUT_COUNTER("\t\t", plcp_errors);
+	PUT_COUNTER("\t\t", fcs_errors);
+	PUT_COUNTER("\t\t", tx_packets);
+	PUT_COUNTER("\t\t", rx_packets);
+	PUT_COUNTER("\t\t", rx_packet_errors);
+	PUT_COUNTER("\t",   rx_decryption_failures);
+	PUT_COUNTER("\t\t", rx_mic_failures);
+	PUT_COUNTER("\t",   rx_no_key_failures);
+	PUT_COUNTER("\t",   tx_multicast_frames);
+	PUT_COUNTER("\t",   tx_frames_success);
+	PUT_COUNTER("\t",   tx_frame_failures);
+	PUT_COUNTER("\t",   tx_frames_retried);
+	PUT_COUNTER("\t",   tx_frames_multi_retried);
+	PUT_COUNTER("\t",   rx_frame_duplicates);
+	PUT_COUNTER("\t\t", rts_success);
+	PUT_COUNTER("\t\t", rts_failures);
+	PUT_COUNTER("\t\t", ack_failures);
+	PUT_COUNTER("\t",   rx_multicast_frames);
+	PUT_COUNTER("\t",   rx_frames_success);
+	PUT_COUNTER("\t",   rx_cmac_icv_errors);
+	PUT_COUNTER("\t\t", rx_cmac_replays);
+	PUT_COUNTER("\t",   rx_mgmt_ccmp_replays);
+
+#undef PUT_COUNTER
+
+	return 0;
+}
+
+static int cw1200_counters_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, &cw1200_counters_show,
+		inode->i_private);
+}
+
+static const struct file_operations fops_counters = {
+	.open = cw1200_counters_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+static ssize_t cw1200_wsm_dumps(struct file *file,
+	const char __user *user_buf, size_t count, loff_t *ppos)
+{
+	struct cw1200_common *priv = file->private_data;
+	char buf[1];
+
+	if (!count)
+		return -EINVAL;
+	if (copy_from_user(buf, user_buf, 1))
+		return -EFAULT;
+
+	if (buf[0] == '1')
+		priv->wsm_enable_wsm_dumps = 1;
+	else
+		priv->wsm_enable_wsm_dumps = 0;
+
+	return count;
+}
+
+static const struct file_operations fops_wsm_dumps = {
+	.open = simple_open,
+	.write = cw1200_wsm_dumps,
+	.llseek = default_llseek,
+};
+
+int cw1200_debug_init(struct cw1200_common *priv)
+{
+	int ret = -ENOMEM;
+	struct cw1200_debug_priv *d = kzalloc(sizeof(struct cw1200_debug_priv),
+			GFP_KERNEL);
+	priv->debug = d;
+	if (!d)
+		return ret;
+
+	d->debugfs_phy = debugfs_create_dir("cw1200",
+					    priv->hw->wiphy->debugfsdir);
+	if (!d->debugfs_phy)
+		goto err;
+
+	if (!debugfs_create_file("status", S_IRUSR, d->debugfs_phy,
+				 priv, &fops_status))
+		goto err;
+
+	if (!debugfs_create_file("counters", S_IRUSR, d->debugfs_phy,
+				 priv, &fops_counters))
+		goto err;
+
+	if (!debugfs_create_file("wsm_dumps", S_IWUSR, d->debugfs_phy,
+				 priv, &fops_wsm_dumps))
+		goto err;
+
+	return 0;
+
+err:
+	priv->debug = NULL;
+	debugfs_remove_recursive(d->debugfs_phy);
+	kfree(d);
+	return ret;
+}
+
+void cw1200_debug_release(struct cw1200_common *priv)
+{
+	struct cw1200_debug_priv *d = priv->debug;
+	if (d) {
+		debugfs_remove_recursive(d->debugfs_phy);
+		priv->debug = NULL;
+		kfree(d);
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/debug.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/debug.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/debug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/debug.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * DebugFS code for ST-Ericsson CW1200 mac80211 driver
+ *
+ * Copyright (c) 2011, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef CW1200_DEBUG_H_INCLUDED
+#define CW1200_DEBUG_H_INCLUDED
+
+struct cw1200_debug_priv {
+	struct dentry *debugfs_phy;
+	int tx;
+	int tx_agg;
+	int rx;
+	int rx_agg;
+	int tx_multi;
+	int tx_multi_frames;
+	int tx_cache_miss;
+	int tx_align;
+	int tx_ttl;
+	int tx_burst;
+	int ba_cnt;
+	int ba_acc;
+	int ba_cnt_rx;
+	int ba_acc_rx;
+};
+
+int cw1200_debug_init(struct cw1200_common *priv);
+void cw1200_debug_release(struct cw1200_common *priv);
+
+static inline void cw1200_debug_txed(struct cw1200_common *priv)
+{
+	++priv->debug->tx;
+}
+
+static inline void cw1200_debug_txed_agg(struct cw1200_common *priv)
+{
+	++priv->debug->tx_agg;
+}
+
+static inline void cw1200_debug_txed_multi(struct cw1200_common *priv,
+					   int count)
+{
+	++priv->debug->tx_multi;
+	priv->debug->tx_multi_frames += count;
+}
+
+static inline void cw1200_debug_rxed(struct cw1200_common *priv)
+{
+	++priv->debug->rx;
+}
+
+static inline void cw1200_debug_rxed_agg(struct cw1200_common *priv)
+{
+	++priv->debug->rx_agg;
+}
+
+static inline void cw1200_debug_tx_cache_miss(struct cw1200_common *priv)
+{
+	++priv->debug->tx_cache_miss;
+}
+
+static inline void cw1200_debug_tx_align(struct cw1200_common *priv)
+{
+	++priv->debug->tx_align;
+}
+
+static inline void cw1200_debug_tx_ttl(struct cw1200_common *priv)
+{
+	++priv->debug->tx_ttl;
+}
+
+static inline void cw1200_debug_tx_burst(struct cw1200_common *priv)
+{
+	++priv->debug->tx_burst;
+}
+
+static inline void cw1200_debug_ba(struct cw1200_common *priv,
+				   int ba_cnt, int ba_acc,
+				   int ba_cnt_rx, int ba_acc_rx)
+{
+	priv->debug->ba_cnt = ba_cnt;
+	priv->debug->ba_acc = ba_acc;
+	priv->debug->ba_cnt_rx = ba_cnt_rx;
+	priv->debug->ba_acc_rx = ba_acc_rx;
+}
+
+#endif /* CW1200_DEBUG_H_INCLUDED */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/fwio.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/fwio.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/fwio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/fwio.c	2013-08-31 17:59:29.000000000 -0400
@@ -0,0 +1,520 @@
+/*
+ * Firmware I/O code for mac80211 ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * Based on:
+ * ST-Ericsson UMAC CW1200 driver which is
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/sched.h>
+#include <linux/firmware.h>
+
+#include "cw1200.h"
+#include "fwio.h"
+#include "hwio.h"
+#include "hwbus.h"
+#include "bh.h"
+
+static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
+{
+	int hw_type = -1;
+	u32 silicon_type = (config_reg_val >> 24) & 0x7;
+	u32 silicon_vers = (config_reg_val >> 31) & 0x1;
+
+	switch (silicon_type) {
+	case 0x00:
+		*major_revision = 1;
+		hw_type = HIF_9000_SILICON_VERSATILE;
+		break;
+	case 0x01:
+	case 0x02: /* CW1x00 */
+	case 0x04: /* CW1x60 */
+		*major_revision = silicon_type;
+		if (silicon_vers)
+			hw_type = HIF_8601_VERSATILE;
+		else
+			hw_type = HIF_8601_SILICON;
+		break;
+	default:
+		break;
+	}
+
+	return hw_type;
+}
+
+static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
+{
+	int ret, block, num_blocks;
+	unsigned i;
+	u32 val32;
+	u32 put = 0, get = 0;
+	u8 *buf = NULL;
+	const char *fw_path;
+	const struct firmware *firmware = NULL;
+
+	/* Macroses are local. */
+#define APB_WRITE(reg, val) \
+	do { \
+		ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
+		if (ret < 0) \
+			goto error; \
+	} while (0)
+#define APB_READ(reg, val) \
+	do { \
+		ret = cw1200_apb_read_32(priv, CW1200_APB(reg), &(val)); \
+		if (ret < 0) \
+			goto error; \
+	} while (0)
+#define REG_WRITE(reg, val) \
+	do { \
+		ret = cw1200_reg_write_32(priv, (reg), (val)); \
+		if (ret < 0) \
+			goto error; \
+	} while (0)
+#define REG_READ(reg, val) \
+	do { \
+		ret = cw1200_reg_read_32(priv, (reg), &(val)); \
+		if (ret < 0) \
+			goto error; \
+	} while (0)
+
+	switch (priv->hw_revision) {
+	case CW1200_HW_REV_CUT10:
+		fw_path = FIRMWARE_CUT10;
+		if (!priv->sdd_path)
+			priv->sdd_path = SDD_FILE_10;
+		break;
+	case CW1200_HW_REV_CUT11:
+		fw_path = FIRMWARE_CUT11;
+		if (!priv->sdd_path)
+			priv->sdd_path = SDD_FILE_11;
+		break;
+	case CW1200_HW_REV_CUT20:
+		fw_path = FIRMWARE_CUT20;
+		if (!priv->sdd_path)
+			priv->sdd_path = SDD_FILE_20;
+		break;
+	case CW1200_HW_REV_CUT22:
+		fw_path = FIRMWARE_CUT22;
+		if (!priv->sdd_path)
+			priv->sdd_path = SDD_FILE_22;
+		break;
+	case CW1X60_HW_REV:
+		fw_path = FIRMWARE_CW1X60;
+		if (!priv->sdd_path)
+			priv->sdd_path = SDD_FILE_CW1X60;
+		break;
+	default:
+		pr_err("Invalid silicon revision %d.\n", priv->hw_revision);
+		return -EINVAL;
+	}
+
+	/* Initialize common registers */
+	APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, DOWNLOAD_ARE_YOU_HERE);
+	APB_WRITE(DOWNLOAD_PUT_REG, 0);
+	APB_WRITE(DOWNLOAD_GET_REG, 0);
+	APB_WRITE(DOWNLOAD_STATUS_REG, DOWNLOAD_PENDING);
+	APB_WRITE(DOWNLOAD_FLAGS_REG, 0);
+
+	/* Write the NOP Instruction */
+	REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000);
+	REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE);
+
+	/* Release CPU from RESET */
+	REG_READ(ST90TDS_CONFIG_REG_ID, val32);
+	val32 &= ~ST90TDS_CONFIG_CPU_RESET_BIT;
+	REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
+
+	/* Enable Clock */
+	val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT;
+	REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
+
+	/* Load a firmware file */
+	ret = reject_firmware(&firmware, fw_path, priv->pdev);
+	if (ret) {
+		pr_err("Can't load firmware file %s.\n", fw_path);
+		goto error;
+	}
+
+	buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
+	if (!buf) {
+		pr_err("Can't allocate firmware load buffer.\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	/* Check if the bootloader is ready */
+	for (i = 0; i < 100; i += 1 + i / 2) {
+		APB_READ(DOWNLOAD_IMAGE_SIZE_REG, val32);
+		if (val32 == DOWNLOAD_I_AM_HERE)
+			break;
+		mdelay(i);
+	} /* End of for loop */
+
+	if (val32 != DOWNLOAD_I_AM_HERE) {
+		pr_err("Bootloader is not ready.\n");
+		ret = -ETIMEDOUT;
+		goto error;
+	}
+
+	/* Calculcate number of download blocks */
+	num_blocks = (firmware->size - 1) / DOWNLOAD_BLOCK_SIZE + 1;
+
+	/* Updating the length in Download Ctrl Area */
+	val32 = firmware->size; /* Explicit cast from size_t to u32 */
+	APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, val32);
+
+	/* Firmware downloading loop */
+	for (block = 0; block < num_blocks; block++) {
+		size_t tx_size;
+		size_t block_size;
+
+		/* check the download status */
+		APB_READ(DOWNLOAD_STATUS_REG, val32);
+		if (val32 != DOWNLOAD_PENDING) {
+			pr_err("Bootloader reported error %d.\n", val32);
+			ret = -EIO;
+			goto error;
+		}
+
+		/* loop until put - get <= 24K */
+		for (i = 0; i < 100; i++) {
+			APB_READ(DOWNLOAD_GET_REG, get);
+			if ((put - get) <=
+			    (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE))
+				break;
+			mdelay(i);
+		}
+
+		if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
+			pr_err("Timeout waiting for FIFO.\n");
+			ret = -ETIMEDOUT;
+			goto error;
+		}
+
+		/* calculate the block size */
+		tx_size = block_size = min((size_t)(firmware->size - put),
+			(size_t)DOWNLOAD_BLOCK_SIZE);
+
+		memcpy(buf, &firmware->data[put], block_size);
+		if (block_size < DOWNLOAD_BLOCK_SIZE) {
+			memset(&buf[block_size], 0,
+			       DOWNLOAD_BLOCK_SIZE - block_size);
+			tx_size = DOWNLOAD_BLOCK_SIZE;
+		}
+
+		/* send the block to sram */
+		ret = cw1200_apb_write(priv,
+			CW1200_APB(DOWNLOAD_FIFO_OFFSET +
+				   (put & (DOWNLOAD_FIFO_SIZE - 1))),
+			buf, tx_size);
+		if (ret < 0) {
+			pr_err("Can't write firmware block @ %d!\n",
+			       put & (DOWNLOAD_FIFO_SIZE - 1));
+			goto error;
+		}
+
+		/* update the put register */
+		put += block_size;
+		APB_WRITE(DOWNLOAD_PUT_REG, put);
+	} /* End of firmware download loop */
+
+	/* Wait for the download completion */
+	for (i = 0; i < 300; i += 1 + i / 2) {
+		APB_READ(DOWNLOAD_STATUS_REG, val32);
+		if (val32 != DOWNLOAD_PENDING)
+			break;
+		mdelay(i);
+	}
+	if (val32 != DOWNLOAD_SUCCESS) {
+		pr_err("Wait for download completion failed: 0x%.8X\n", val32);
+		ret = -ETIMEDOUT;
+		goto error;
+	} else {
+		pr_info("Firmware download completed.\n");
+		ret = 0;
+	}
+
+error:
+	kfree(buf);
+	if (firmware)
+		release_firmware(firmware);
+	return ret;
+
+#undef APB_WRITE
+#undef APB_READ
+#undef REG_WRITE
+#undef REG_READ
+}
+
+
+static int config_reg_read(struct cw1200_common *priv, u32 *val)
+{
+	switch (priv->hw_type) {
+	case HIF_9000_SILICON_VERSATILE: {
+		u16 val16;
+		int ret = cw1200_reg_read_16(priv,
+					     ST90TDS_CONFIG_REG_ID,
+					     &val16);
+		if (ret < 0)
+			return ret;
+		*val = val16;
+		return 0;
+	}
+	case HIF_8601_VERSATILE:
+	case HIF_8601_SILICON:
+	default:
+		cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, val);
+		break;
+	}
+	return 0;
+}
+
+static int config_reg_write(struct cw1200_common *priv, u32 val)
+{
+	switch (priv->hw_type) {
+	case HIF_9000_SILICON_VERSATILE:
+		return cw1200_reg_write_16(priv,
+					   ST90TDS_CONFIG_REG_ID,
+					   (u16)val);
+	case HIF_8601_VERSATILE:
+	case HIF_8601_SILICON:
+	default:
+		return cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val);
+		break;
+	}
+	return 0;
+}
+
+int cw1200_load_firmware(struct cw1200_common *priv)
+{
+	int ret;
+	int i;
+	u32 val32;
+	u16 val16;
+	int major_revision = -1;
+
+	/* Read CONFIG Register */
+	ret = cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
+	if (ret < 0) {
+		pr_err("Can't read config register.\n");
+		goto out;
+	}
+
+	if (val32 == 0 || val32 == 0xffffffff) {
+		pr_err("Bad config register value (0x%08x)\n", val32);
+		ret = -EIO;
+		goto out;
+	}
+
+	priv->hw_type = cw1200_get_hw_type(val32, &major_revision);
+	if (priv->hw_type < 0) {
+		pr_err("Can't deduce hardware type.\n");
+		ret = -ENOTSUPP;
+		goto out;
+	}
+
+	/* Set DPLL Reg value, and read back to confirm writes work */
+	ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
+				  cw1200_dpll_from_clk(priv->hw_refclk));
+	if (ret < 0) {
+		pr_err("Can't write DPLL register.\n");
+		goto out;
+	}
+
+	msleep(20);
+
+	ret = cw1200_reg_read_32(priv,
+		ST90TDS_TSET_GEN_R_W_REG_ID, &val32);
+	if (ret < 0) {
+		pr_err("Can't read DPLL register.\n");
+		goto out;
+	}
+
+	if (val32 != cw1200_dpll_from_clk(priv->hw_refclk)) {
+		pr_err("Unable to initialise DPLL register. Wrote 0x%.8X, Read 0x%.8X.\n",
+		       cw1200_dpll_from_clk(priv->hw_refclk), val32);
+		ret = -EIO;
+		goto out;
+	}
+
+	/* Set wakeup bit in device */
+	ret = cw1200_reg_read_16(priv, ST90TDS_CONTROL_REG_ID, &val16);
+	if (ret < 0) {
+		pr_err("set_wakeup: can't read control register.\n");
+		goto out;
+	}
+
+	ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
+		val16 | ST90TDS_CONT_WUP_BIT);
+	if (ret < 0) {
+		pr_err("set_wakeup: can't write control register.\n");
+		goto out;
+	}
+
+	/* Wait for wakeup */
+	for (i = 0; i < 300; i += (1 + i / 2)) {
+		ret = cw1200_reg_read_16(priv,
+			ST90TDS_CONTROL_REG_ID, &val16);
+		if (ret < 0) {
+			pr_err("wait_for_wakeup: can't read control register.\n");
+			goto out;
+		}
+
+		if (val16 & ST90TDS_CONT_RDY_BIT)
+			break;
+
+		msleep(i);
+	}
+
+	if ((val16 & ST90TDS_CONT_RDY_BIT) == 0) {
+		pr_err("wait_for_wakeup: device is not responding.\n");
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+
+	switch (major_revision) {
+	case 1:
+		/* CW1200 Hardware detection logic : Check for CUT1.1 */
+		ret = cw1200_ahb_read_32(priv, CW1200_CUT_ID_ADDR, &val32);
+		if (ret) {
+			pr_err("HW detection: can't read CUT ID.\n");
+			goto out;
+		}
+
+		switch (val32) {
+		case CW1200_CUT_11_ID_STR:
+			pr_info("CW1x00 Cut 1.1 silicon detected.\n");
+			priv->hw_revision = CW1200_HW_REV_CUT11;
+			break;
+		default:
+			pr_info("CW1x00 Cut 1.0 silicon detected.\n");
+			priv->hw_revision = CW1200_HW_REV_CUT10;
+			break;
+		}
+
+		/* According to ST-E, CUT<2.0 has busted BA TID0-3.
+		   Just disable it entirely...
+		*/
+		priv->ba_rx_tid_mask = 0;
+		priv->ba_tx_tid_mask = 0;
+		break;
+	case 2: {
+		u32 ar1, ar2, ar3;
+		ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR, &ar1);
+		if (ret) {
+			pr_err("(1) HW detection: can't read CUT ID\n");
+			goto out;
+		}
+		ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 4, &ar2);
+		if (ret) {
+			pr_err("(2) HW detection: can't read CUT ID.\n");
+			goto out;
+		}
+
+		ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 8, &ar3);
+		if (ret) {
+			pr_err("(3) HW detection: can't read CUT ID.\n");
+			goto out;
+		}
+
+		if (ar1 == CW1200_CUT_22_ID_STR1 &&
+		    ar2 == CW1200_CUT_22_ID_STR2 &&
+		    ar3 == CW1200_CUT_22_ID_STR3) {
+			pr_info("CW1x00 Cut 2.2 silicon detected.\n");
+			priv->hw_revision = CW1200_HW_REV_CUT22;
+		} else {
+			pr_info("CW1x00 Cut 2.0 silicon detected.\n");
+			priv->hw_revision = CW1200_HW_REV_CUT20;
+		}
+		break;
+	}
+	case 4:
+		pr_info("CW1x60 silicon detected.\n");
+		priv->hw_revision = CW1X60_HW_REV;
+		break;
+	default:
+		pr_err("Unsupported silicon major revision %d.\n",
+		       major_revision);
+		ret = -ENOTSUPP;
+		goto out;
+	}
+
+	/* Checking for access mode */
+	ret = config_reg_read(priv, &val32);
+	if (ret < 0) {
+		pr_err("Can't read config register.\n");
+		goto out;
+	}
+
+	if (!(val32 & ST90TDS_CONFIG_ACCESS_MODE_BIT)) {
+		pr_err("Device is already in QUEUE mode!\n");
+			ret = -EINVAL;
+			goto out;
+	}
+
+	switch (priv->hw_type)  {
+	case HIF_8601_SILICON:
+		if (priv->hw_revision == CW1X60_HW_REV) {
+			pr_err("Can't handle CW1160/1260 firmware load yet.\n");
+			ret = -ENOTSUPP;
+			goto out;
+		}
+		ret = cw1200_load_firmware_cw1200(priv);
+		break;
+	default:
+		pr_err("Can't perform firmware load for hw type %d.\n",
+		       priv->hw_type);
+		ret = -ENOTSUPP;
+		goto out;
+	}
+	if (ret < 0) {
+		pr_err("Firmware load error.\n");
+		goto out;
+	}
+
+	/* Enable interrupt signalling */
+	priv->hwbus_ops->lock(priv->hwbus_priv);
+	ret = __cw1200_irq_enable(priv, 1);
+	priv->hwbus_ops->unlock(priv->hwbus_priv);
+	if (ret < 0)
+		goto unsubscribe;
+
+	/* Configure device for MESSSAGE MODE */
+	ret = config_reg_read(priv, &val32);
+	if (ret < 0) {
+		pr_err("Can't read config register.\n");
+		goto unsubscribe;
+	}
+	ret = config_reg_write(priv, val32 & ~ST90TDS_CONFIG_ACCESS_MODE_BIT);
+	if (ret < 0) {
+		pr_err("Can't write config register.\n");
+		goto unsubscribe;
+	}
+
+	/* Unless we read the CONFIG Register we are
+	 * not able to get an interrupt
+	 */
+	mdelay(10);
+	config_reg_read(priv, &val32);
+
+out:
+	return ret;
+
+unsubscribe:
+	/* Disable interrupt signalling */
+	priv->hwbus_ops->lock(priv->hwbus_priv);
+	ret = __cw1200_irq_enable(priv, 0);
+	priv->hwbus_ops->unlock(priv->hwbus_priv);
+	return ret;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/fwio.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/fwio.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/fwio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/fwio.h	2013-08-31 17:59:31.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * Firmware API for mac80211 ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * Based on:
+ * ST-Ericsson UMAC CW1200 driver which is
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef FWIO_H_INCLUDED
+#define FWIO_H_INCLUDED
+
+#define BOOTLOADER_CW1X60       "/*(DEBLOBBED)*/"
+#define FIRMWARE_CW1X60		"/*(DEBLOBBED)*/"
+#define FIRMWARE_CUT22		"/*(DEBLOBBED)*/"
+#define FIRMWARE_CUT20		"/*(DEBLOBBED)*/"
+#define FIRMWARE_CUT11		"/*(DEBLOBBED)*/"
+#define FIRMWARE_CUT10		"/*(DEBLOBBED)*/"
+#define SDD_FILE_CW1X60		"/*(DEBLOBBED)*/"
+#define SDD_FILE_22		"/*(DEBLOBBED)*/"
+#define SDD_FILE_20		"/*(DEBLOBBED)*/"
+#define SDD_FILE_11		"/*(DEBLOBBED)*/"
+#define SDD_FILE_10		"/*(DEBLOBBED)*/"
+
+int cw1200_load_firmware(struct cw1200_common *priv);
+
+/* SDD definitions */
+#define SDD_PTA_CFG_ELT_ID 0xEB
+#define SDD_REFERENCE_FREQUENCY_ELT_ID 0xc5
+u32 cw1200_dpll_from_clk(u16 clk);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/hwbus.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/hwbus.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/hwbus.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/hwbus.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,33 @@
+/*
+ * Common hwbus abstraction layer interface for cw1200 wireless driver
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef CW1200_HWBUS_H
+#define CW1200_HWBUS_H
+
+struct hwbus_priv;
+
+void cw1200_irq_handler(struct cw1200_common *priv);
+
+/* This MUST be wrapped with hwbus_ops->lock/unlock! */
+int __cw1200_irq_enable(struct cw1200_common *priv, int enable);
+
+struct hwbus_ops {
+	int (*hwbus_memcpy_fromio)(struct hwbus_priv *self, unsigned int addr,
+					void *dst, int count);
+	int (*hwbus_memcpy_toio)(struct hwbus_priv *self, unsigned int addr,
+					const void *src, int count);
+	void (*lock)(struct hwbus_priv *self);
+	void (*unlock)(struct hwbus_priv *self);
+	size_t (*align_size)(struct hwbus_priv *self, size_t size);
+	int (*power_mgmt)(struct hwbus_priv *self, bool suspend);
+};
+
+#endif /* CW1200_HWBUS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/hwio.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/hwio.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/hwio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/hwio.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,312 @@
+/*
+ * Low-level device IO routines for ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * Based on:
+ * ST-Ericsson UMAC CW1200 driver, which is
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Ajitpal Singh <ajitpal.singh@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+
+#include "cw1200.h"
+#include "hwio.h"
+#include "hwbus.h"
+
+ /* Sdio addr is 4*spi_addr */
+#define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
+#define SDIO_ADDR17BIT(buf_id, mpf, rfu, reg_id_ofs) \
+				((((buf_id)    & 0x1F) << 7) \
+				| (((mpf)        & 1) << 6) \
+				| (((rfu)        & 1) << 5) \
+				| (((reg_id_ofs) & 0x1F) << 0))
+#define MAX_RETRY		3
+
+
+static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr,
+			     void *buf, size_t buf_len, int buf_id)
+{
+	u16 addr_sdio;
+	u32 sdio_reg_addr_17bit;
+
+	/* Check if buffer is aligned to 4 byte boundary */
+	if (WARN_ON(((unsigned long)buf & 3) && (buf_len > 4))) {
+		pr_err("buffer is not aligned.\n");
+		return -EINVAL;
+	}
+
+	/* Convert to SDIO Register Address */
+	addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
+	sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
+
+	return priv->hwbus_ops->hwbus_memcpy_fromio(priv->hwbus_priv,
+						  sdio_reg_addr_17bit,
+						  buf, buf_len);
+}
+
+static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
+				const void *buf, size_t buf_len, int buf_id)
+{
+	u16 addr_sdio;
+	u32 sdio_reg_addr_17bit;
+
+	/* Convert to SDIO Register Address */
+	addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
+	sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
+
+	return priv->hwbus_ops->hwbus_memcpy_toio(priv->hwbus_priv,
+						sdio_reg_addr_17bit,
+						buf, buf_len);
+}
+
+static inline int __cw1200_reg_read_32(struct cw1200_common *priv,
+					u16 addr, u32 *val)
+{
+	__le32 tmp;
+	int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
+	*val = le32_to_cpu(tmp);
+	return i;
+}
+
+static inline int __cw1200_reg_write_32(struct cw1200_common *priv,
+					u16 addr, u32 val)
+{
+	__le32 tmp = cpu_to_le32(val);
+	return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
+}
+
+static inline int __cw1200_reg_read_16(struct cw1200_common *priv,
+					u16 addr, u16 *val)
+{
+	__le16 tmp;
+	int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
+	*val = le16_to_cpu(tmp);
+	return i;
+}
+
+static inline int __cw1200_reg_write_16(struct cw1200_common *priv,
+					u16 addr, u16 val)
+{
+	__le16 tmp = cpu_to_le16(val);
+	return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
+}
+
+int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
+			size_t buf_len)
+{
+	int ret;
+	priv->hwbus_ops->lock(priv->hwbus_priv);
+	ret = __cw1200_reg_read(priv, addr, buf, buf_len, 0);
+	priv->hwbus_ops->unlock(priv->hwbus_priv);
+	return ret;
+}
+
+int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf,
+			size_t buf_len)
+{
+	int ret;
+	priv->hwbus_ops->lock(priv->hwbus_priv);
+	ret = __cw1200_reg_write(priv, addr, buf, buf_len, 0);
+	priv->hwbus_ops->unlock(priv->hwbus_priv);
+	return ret;
+}
+
+int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
+{
+	int ret, retry = 1;
+	int buf_id_rx = priv->buf_id_rx;
+
+	priv->hwbus_ops->lock(priv->hwbus_priv);
+
+	while (retry <= MAX_RETRY) {
+		ret = __cw1200_reg_read(priv,
+					ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
+					buf_len, buf_id_rx + 1);
+		if (!ret) {
+			buf_id_rx = (buf_id_rx + 1) & 3;
+			priv->buf_id_rx = buf_id_rx;
+			break;
+		} else {
+			retry++;
+			mdelay(1);
+			pr_err("error :[%d]\n", ret);
+		}
+	}
+
+	priv->hwbus_ops->unlock(priv->hwbus_priv);
+	return ret;
+}
+
+int cw1200_data_write(struct cw1200_common *priv, const void *buf,
+			size_t buf_len)
+{
+	int ret, retry = 1;
+	int buf_id_tx = priv->buf_id_tx;
+
+	priv->hwbus_ops->lock(priv->hwbus_priv);
+
+	while (retry <= MAX_RETRY) {
+		ret = __cw1200_reg_write(priv,
+					 ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
+					 buf_len, buf_id_tx);
+		if (!ret) {
+			buf_id_tx = (buf_id_tx + 1) & 31;
+			priv->buf_id_tx = buf_id_tx;
+			break;
+		} else {
+			retry++;
+			mdelay(1);
+			pr_err("error :[%d]\n", ret);
+		}
+	}
+
+	priv->hwbus_ops->unlock(priv->hwbus_priv);
+	return ret;
+}
+
+int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
+			 size_t buf_len, u32 prefetch, u16 port_addr)
+{
+	u32 val32 = 0;
+	int i, ret;
+
+	if ((buf_len / 2) >= 0x1000) {
+		pr_err("Can't read more than 0xfff words.\n");
+		return -EINVAL;
+	}
+
+	priv->hwbus_ops->lock(priv->hwbus_priv);
+	/* Write address */
+	ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
+	if (ret < 0) {
+		pr_err("Can't write address register.\n");
+		goto out;
+	}
+
+	/* Read CONFIG Register Value - We will read 32 bits */
+	ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
+	if (ret < 0) {
+		pr_err("Can't read config register.\n");
+		goto out;
+	}
+
+	/* Set PREFETCH bit */
+	ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID,
+					val32 | prefetch);
+	if (ret < 0) {
+		pr_err("Can't write prefetch bit.\n");
+		goto out;
+	}
+
+	/* Check for PRE-FETCH bit to be cleared */
+	for (i = 0; i < 20; i++) {
+		ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
+		if (ret < 0) {
+			pr_err("Can't check prefetch bit.\n");
+			goto out;
+		}
+		if (!(val32 & prefetch))
+			break;
+
+		mdelay(i);
+	}
+
+	if (val32 & prefetch) {
+		pr_err("Prefetch bit is not cleared.\n");
+		goto out;
+	}
+
+	/* Read data port */
+	ret = __cw1200_reg_read(priv, port_addr, buf, buf_len, 0);
+	if (ret < 0) {
+		pr_err("Can't read data port.\n");
+		goto out;
+	}
+
+out:
+	priv->hwbus_ops->unlock(priv->hwbus_priv);
+	return ret;
+}
+
+int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
+			size_t buf_len)
+{
+	int ret;
+
+	if ((buf_len / 2) >= 0x1000) {
+		pr_err("Can't write more than 0xfff words.\n");
+		return -EINVAL;
+	}
+
+	priv->hwbus_ops->lock(priv->hwbus_priv);
+
+	/* Write address */
+	ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
+	if (ret < 0) {
+		pr_err("Can't write address register.\n");
+		goto out;
+	}
+
+	/* Write data port */
+	ret = __cw1200_reg_write(priv, ST90TDS_SRAM_DPORT_REG_ID,
+					buf, buf_len, 0);
+	if (ret < 0) {
+		pr_err("Can't write data port.\n");
+		goto out;
+	}
+
+out:
+	priv->hwbus_ops->unlock(priv->hwbus_priv);
+	return ret;
+}
+
+int __cw1200_irq_enable(struct cw1200_common *priv, int enable)
+{
+	u32 val32;
+	u16 val16;
+	int ret;
+
+	if (HIF_8601_SILICON == priv->hw_type) {
+		ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
+		if (ret < 0) {
+			pr_err("Can't read config register.\n");
+			return ret;
+		}
+
+		if (enable)
+			val32 |= ST90TDS_CONF_IRQ_RDY_ENABLE;
+		else
+			val32 &= ~ST90TDS_CONF_IRQ_RDY_ENABLE;
+
+		ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val32);
+		if (ret < 0) {
+			pr_err("Can't write config register.\n");
+			return ret;
+		}
+	} else {
+		ret = __cw1200_reg_read_16(priv, ST90TDS_CONFIG_REG_ID, &val16);
+		if (ret < 0) {
+			pr_err("Can't read control register.\n");
+			return ret;
+		}
+
+		if (enable)
+			val16 |= ST90TDS_CONT_IRQ_RDY_ENABLE;
+		else
+			val16 &= ~ST90TDS_CONT_IRQ_RDY_ENABLE;
+
+		ret = __cw1200_reg_write_16(priv, ST90TDS_CONFIG_REG_ID, val16);
+		if (ret < 0) {
+			pr_err("Can't write control register.\n");
+			return ret;
+		}
+	}
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/hwio.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/hwio.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/hwio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/hwio.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,247 @@
+/*
+ * Low-level API for mac80211 ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * Based on:
+ * ST-Ericsson UMAC CW1200 driver which is
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef CW1200_HWIO_H_INCLUDED
+#define CW1200_HWIO_H_INCLUDED
+
+/* extern */ struct cw1200_common;
+
+#define CW1200_CUT_11_ID_STR		(0x302E3830)
+#define CW1200_CUT_22_ID_STR1		(0x302e3132)
+#define CW1200_CUT_22_ID_STR2		(0x32302e30)
+#define CW1200_CUT_22_ID_STR3		(0x3335)
+#define CW1200_CUT_ID_ADDR		(0xFFF17F90)
+#define CW1200_CUT2_ID_ADDR		(0xFFF1FF90)
+
+/* Download control area */
+/* boot loader start address in SRAM */
+#define DOWNLOAD_BOOT_LOADER_OFFSET	(0x00000000)
+/* 32K, 0x4000 to 0xDFFF */
+#define DOWNLOAD_FIFO_OFFSET		(0x00004000)
+/* 32K */
+#define DOWNLOAD_FIFO_SIZE		(0x00008000)
+/* 128 bytes, 0xFF80 to 0xFFFF */
+#define DOWNLOAD_CTRL_OFFSET		(0x0000FF80)
+#define DOWNLOAD_CTRL_DATA_DWORDS	(32-6)
+
+struct download_cntl_t {
+	/* size of whole firmware file (including Cheksum), host init */
+	u32 image_size;
+	/* downloading flags */
+	u32 flags;
+	/* No. of bytes put into the download, init & updated by host */
+	u32 put;
+	/* last traced program counter, last ARM reg_pc */
+	u32 trace_pc;
+	/* No. of bytes read from the download, host init, device updates */
+	u32 get;
+	/* r0, boot losader status, host init to pending, device updates */
+	u32 status;
+	/* Extra debug info, r1 to r14 if status=r0=DOWNLOAD_EXCEPTION */
+	u32 debug_data[DOWNLOAD_CTRL_DATA_DWORDS];
+};
+
+#define	DOWNLOAD_IMAGE_SIZE_REG		\
+	(DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, image_size))
+#define	DOWNLOAD_FLAGS_REG		\
+	(DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, flags))
+#define DOWNLOAD_PUT_REG		\
+	(DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, put))
+#define DOWNLOAD_TRACE_PC_REG		\
+	(DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, trace_pc))
+#define	DOWNLOAD_GET_REG		\
+	(DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, get))
+#define	DOWNLOAD_STATUS_REG		\
+	(DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, status))
+#define DOWNLOAD_DEBUG_DATA_REG		\
+	(DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, debug_data))
+#define DOWNLOAD_DEBUG_DATA_LEN		(108)
+
+#define DOWNLOAD_BLOCK_SIZE		(1024)
+
+/* For boot loader detection */
+#define DOWNLOAD_ARE_YOU_HERE		(0x87654321)
+#define DOWNLOAD_I_AM_HERE		(0x12345678)
+
+/* Download error code */
+#define DOWNLOAD_PENDING		(0xFFFFFFFF)
+#define DOWNLOAD_SUCCESS		(0)
+#define DOWNLOAD_EXCEPTION		(1)
+#define DOWNLOAD_ERR_MEM_1		(2)
+#define DOWNLOAD_ERR_MEM_2		(3)
+#define DOWNLOAD_ERR_SOFTWARE		(4)
+#define DOWNLOAD_ERR_FILE_SIZE		(5)
+#define DOWNLOAD_ERR_CHECKSUM		(6)
+#define DOWNLOAD_ERR_OVERFLOW		(7)
+#define DOWNLOAD_ERR_IMAGE		(8)
+#define DOWNLOAD_ERR_HOST		(9)
+#define DOWNLOAD_ERR_ABORT		(10)
+
+
+#define SYS_BASE_ADDR_SILICON		(0)
+#define PAC_BASE_ADDRESS_SILICON	(SYS_BASE_ADDR_SILICON + 0x09000000)
+#define PAC_SHARED_MEMORY_SILICON	(PAC_BASE_ADDRESS_SILICON)
+
+#define CW1200_APB(addr)		(PAC_SHARED_MEMORY_SILICON + (addr))
+
+/* Device register definitions */
+
+/* WBF - SPI Register Addresses */
+#define ST90TDS_ADDR_ID_BASE		(0x0000)
+/* 16/32 bits */
+#define ST90TDS_CONFIG_REG_ID		(0x0000)
+/* 16/32 bits */
+#define ST90TDS_CONTROL_REG_ID		(0x0001)
+/* 16 bits, Q mode W/R */
+#define ST90TDS_IN_OUT_QUEUE_REG_ID	(0x0002)
+/* 32 bits, AHB bus R/W */
+#define ST90TDS_AHB_DPORT_REG_ID	(0x0003)
+/* 16/32 bits */
+#define ST90TDS_SRAM_BASE_ADDR_REG_ID   (0x0004)
+/* 32 bits, APB bus R/W */
+#define ST90TDS_SRAM_DPORT_REG_ID	(0x0005)
+/* 32 bits, t_settle/general */
+#define ST90TDS_TSET_GEN_R_W_REG_ID	(0x0006)
+/* 16 bits, Q mode read, no length */
+#define ST90TDS_FRAME_OUT_REG_ID	(0x0007)
+#define ST90TDS_ADDR_ID_MAX		(ST90TDS_FRAME_OUT_REG_ID)
+
+/* WBF - Control register bit set */
+/* next o/p length, bit 11 to 0 */
+#define ST90TDS_CONT_NEXT_LEN_MASK	(0x0FFF)
+#define ST90TDS_CONT_WUP_BIT		(BIT(12))
+#define ST90TDS_CONT_RDY_BIT		(BIT(13))
+#define ST90TDS_CONT_IRQ_ENABLE		(BIT(14))
+#define ST90TDS_CONT_RDY_ENABLE		(BIT(15))
+#define ST90TDS_CONT_IRQ_RDY_ENABLE	(BIT(14)|BIT(15))
+
+/* SPI Config register bit set */
+#define ST90TDS_CONFIG_FRAME_BIT	(BIT(2))
+#define ST90TDS_CONFIG_WORD_MODE_BITS	(BIT(3)|BIT(4))
+#define ST90TDS_CONFIG_WORD_MODE_1	(BIT(3))
+#define ST90TDS_CONFIG_WORD_MODE_2	(BIT(4))
+#define ST90TDS_CONFIG_ERROR_0_BIT	(BIT(5))
+#define ST90TDS_CONFIG_ERROR_1_BIT	(BIT(6))
+#define ST90TDS_CONFIG_ERROR_2_BIT	(BIT(7))
+/* TBD: Sure??? */
+#define ST90TDS_CONFIG_CSN_FRAME_BIT	(BIT(7))
+#define ST90TDS_CONFIG_ERROR_3_BIT	(BIT(8))
+#define ST90TDS_CONFIG_ERROR_4_BIT	(BIT(9))
+/* QueueM */
+#define ST90TDS_CONFIG_ACCESS_MODE_BIT	(BIT(10))
+/* AHB bus */
+#define ST90TDS_CONFIG_AHB_PRFETCH_BIT	(BIT(11))
+#define ST90TDS_CONFIG_CPU_CLK_DIS_BIT	(BIT(12))
+/* APB bus */
+#define ST90TDS_CONFIG_PRFETCH_BIT	(BIT(13))
+/* cpu reset */
+#define ST90TDS_CONFIG_CPU_RESET_BIT	(BIT(14))
+#define ST90TDS_CONFIG_CLEAR_INT_BIT	(BIT(15))
+
+/* For CW1200 the IRQ Enable and Ready Bits are in CONFIG register */
+#define ST90TDS_CONF_IRQ_ENABLE		(BIT(16))
+#define ST90TDS_CONF_RDY_ENABLE		(BIT(17))
+#define ST90TDS_CONF_IRQ_RDY_ENABLE	(BIT(16)|BIT(17))
+
+int cw1200_data_read(struct cw1200_common *priv,
+		     void *buf, size_t buf_len);
+int cw1200_data_write(struct cw1200_common *priv,
+		      const void *buf, size_t buf_len);
+
+int cw1200_reg_read(struct cw1200_common *priv, u16 addr,
+		    void *buf, size_t buf_len);
+int cw1200_reg_write(struct cw1200_common *priv, u16 addr,
+		     const void *buf, size_t buf_len);
+
+static inline int cw1200_reg_read_16(struct cw1200_common *priv,
+				     u16 addr, u16 *val)
+{
+	__le32 tmp;
+	int i;
+	i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp));
+	*val = le32_to_cpu(tmp) & 0xfffff;
+	return i;
+}
+
+static inline int cw1200_reg_write_16(struct cw1200_common *priv,
+				      u16 addr, u16 val)
+{
+	__le32 tmp = cpu_to_le32((u32)val);
+	return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp));
+}
+
+static inline int cw1200_reg_read_32(struct cw1200_common *priv,
+				     u16 addr, u32 *val)
+{
+	__le32 tmp;
+	int i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp));
+	*val = le32_to_cpu(tmp);
+	return i;
+}
+
+static inline int cw1200_reg_write_32(struct cw1200_common *priv,
+				      u16 addr, u32 val)
+{
+	__le32 tmp = cpu_to_le32(val);
+	return cw1200_reg_write(priv, addr, &tmp, sizeof(val));
+}
+
+int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
+			 size_t buf_len, u32 prefetch, u16 port_addr);
+int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
+		     size_t buf_len);
+
+static inline int cw1200_apb_read(struct cw1200_common *priv, u32 addr,
+				  void *buf, size_t buf_len)
+{
+	return cw1200_indirect_read(priv, addr, buf, buf_len,
+				    ST90TDS_CONFIG_PRFETCH_BIT,
+				    ST90TDS_SRAM_DPORT_REG_ID);
+}
+
+static inline int cw1200_ahb_read(struct cw1200_common *priv, u32 addr,
+				  void *buf, size_t buf_len)
+{
+	return cw1200_indirect_read(priv, addr, buf, buf_len,
+				    ST90TDS_CONFIG_AHB_PRFETCH_BIT,
+				    ST90TDS_AHB_DPORT_REG_ID);
+}
+
+static inline int cw1200_apb_read_32(struct cw1200_common *priv,
+				     u32 addr, u32 *val)
+{
+	__le32 tmp;
+	int i = cw1200_apb_read(priv, addr, &tmp, sizeof(tmp));
+	*val = le32_to_cpu(tmp);
+	return i;
+}
+
+static inline int cw1200_apb_write_32(struct cw1200_common *priv,
+				      u32 addr, u32 val)
+{
+	__le32 tmp = cpu_to_le32(val);
+	return cw1200_apb_write(priv, addr, &tmp, sizeof(val));
+}
+static inline int cw1200_ahb_read_32(struct cw1200_common *priv,
+				     u32 addr, u32 *val)
+{
+	__le32 tmp;
+	int i = cw1200_ahb_read(priv, addr, &tmp, sizeof(tmp));
+	*val = le32_to_cpu(tmp);
+	return i;
+}
+
+#endif /* CW1200_HWIO_H_INCLUDED */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,30 @@
+config CW1200
+	tristate "CW1200 WLAN support"
+	depends on MAC80211 && CFG80211
+	help
+	  This is a driver for the ST-E CW1100 & CW1200 WLAN chipsets.
+	  This option just enables the driver core, see below for
+	  specific bus support.
+
+if CW1200
+
+config CW1200_WLAN_SDIO
+	tristate "Support SDIO platforms"
+	depends on CW1200 && MMC
+	help
+	  Enable support for the CW1200 connected via an SDIO bus.
+	  By default this driver only supports the Sagrad SG901-1091/1098 EVK
+	  and similar designs that utilize a hardware reset circuit. To
+	  support different CW1200 SDIO designs you will need to override
+	  the default platform data by calling cw1200_sdio_set_platform_data()
+	  in your board setup file.
+
+config CW1200_WLAN_SPI
+	tristate "Support SPI platforms"
+	depends on CW1200 && SPI
+	help
+	  Enables support for the CW1200 connected via a SPI bus.  You will
+	  need to add appropriate platform data glue in your board setup
+	  file.
+
+endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,605 @@
+/*
+ * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * Based on:
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ * - stlc45xx driver
+ *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/firmware.h>
+#include <linux/etherdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <net/mac80211.h>
+
+#include "cw1200.h"
+#include "txrx.h"
+#include "hwbus.h"
+#include "fwio.h"
+#include "hwio.h"
+#include "bh.h"
+#include "sta.h"
+#include "scan.h"
+#include "debug.h"
+#include "pm.h"
+
+MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
+MODULE_DESCRIPTION("Softmac ST-Ericsson CW1200 common code");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("cw1200_core");
+
+/* Accept MAC address of the form macaddr=0x00,0x80,0xE1,0x30,0x40,0x50 */
+static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00};
+module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(macaddr, "Override platform_data MAC address");
+
+static char *cw1200_sdd_path;
+module_param(cw1200_sdd_path, charp, 0644);
+MODULE_PARM_DESC(cw1200_sdd_path, "Override platform_data SDD file");
+static int cw1200_refclk;
+module_param(cw1200_refclk, int, 0644);
+MODULE_PARM_DESC(cw1200_refclk, "Override platform_data reference clock");
+
+int cw1200_power_mode = wsm_power_mode_quiescent;
+module_param(cw1200_power_mode, int, 0644);
+MODULE_PARM_DESC(cw1200_power_mode, "WSM power mode.  0 == active, 1 == doze, 2 == quiescent (default)");
+
+#define RATETAB_ENT(_rate, _rateid, _flags)		\
+	{						\
+		.bitrate	= (_rate),		\
+		.hw_value	= (_rateid),		\
+		.flags		= (_flags),		\
+	}
+
+static struct ieee80211_rate cw1200_rates[] = {
+	RATETAB_ENT(10,  0,   0),
+	RATETAB_ENT(20,  1,   0),
+	RATETAB_ENT(55,  2,   0),
+	RATETAB_ENT(110, 3,   0),
+	RATETAB_ENT(60,  6,  0),
+	RATETAB_ENT(90,  7,  0),
+	RATETAB_ENT(120, 8,  0),
+	RATETAB_ENT(180, 9,  0),
+	RATETAB_ENT(240, 10, 0),
+	RATETAB_ENT(360, 11, 0),
+	RATETAB_ENT(480, 12, 0),
+	RATETAB_ENT(540, 13, 0),
+};
+
+static struct ieee80211_rate cw1200_mcs_rates[] = {
+	RATETAB_ENT(65,  14, IEEE80211_TX_RC_MCS),
+	RATETAB_ENT(130, 15, IEEE80211_TX_RC_MCS),
+	RATETAB_ENT(195, 16, IEEE80211_TX_RC_MCS),
+	RATETAB_ENT(260, 17, IEEE80211_TX_RC_MCS),
+	RATETAB_ENT(390, 18, IEEE80211_TX_RC_MCS),
+	RATETAB_ENT(520, 19, IEEE80211_TX_RC_MCS),
+	RATETAB_ENT(585, 20, IEEE80211_TX_RC_MCS),
+	RATETAB_ENT(650, 21, IEEE80211_TX_RC_MCS),
+};
+
+#define cw1200_a_rates		(cw1200_rates + 4)
+#define cw1200_a_rates_size	(ARRAY_SIZE(cw1200_rates) - 4)
+#define cw1200_g_rates		(cw1200_rates + 0)
+#define cw1200_g_rates_size	(ARRAY_SIZE(cw1200_rates))
+#define cw1200_n_rates		(cw1200_mcs_rates)
+#define cw1200_n_rates_size	(ARRAY_SIZE(cw1200_mcs_rates))
+
+
+#define CHAN2G(_channel, _freq, _flags) {			\
+	.band			= IEEE80211_BAND_2GHZ,		\
+	.center_freq		= (_freq),			\
+	.hw_value		= (_channel),			\
+	.flags			= (_flags),			\
+	.max_antenna_gain	= 0,				\
+	.max_power		= 30,				\
+}
+
+#define CHAN5G(_channel, _flags) {				\
+	.band			= IEEE80211_BAND_5GHZ,		\
+	.center_freq	= 5000 + (5 * (_channel)),		\
+	.hw_value		= (_channel),			\
+	.flags			= (_flags),			\
+	.max_antenna_gain	= 0,				\
+	.max_power		= 30,				\
+}
+
+static struct ieee80211_channel cw1200_2ghz_chantable[] = {
+	CHAN2G(1, 2412, 0),
+	CHAN2G(2, 2417, 0),
+	CHAN2G(3, 2422, 0),
+	CHAN2G(4, 2427, 0),
+	CHAN2G(5, 2432, 0),
+	CHAN2G(6, 2437, 0),
+	CHAN2G(7, 2442, 0),
+	CHAN2G(8, 2447, 0),
+	CHAN2G(9, 2452, 0),
+	CHAN2G(10, 2457, 0),
+	CHAN2G(11, 2462, 0),
+	CHAN2G(12, 2467, 0),
+	CHAN2G(13, 2472, 0),
+	CHAN2G(14, 2484, 0),
+};
+
+static struct ieee80211_channel cw1200_5ghz_chantable[] = {
+	CHAN5G(34, 0),		CHAN5G(36, 0),
+	CHAN5G(38, 0),		CHAN5G(40, 0),
+	CHAN5G(42, 0),		CHAN5G(44, 0),
+	CHAN5G(46, 0),		CHAN5G(48, 0),
+	CHAN5G(52, 0),		CHAN5G(56, 0),
+	CHAN5G(60, 0),		CHAN5G(64, 0),
+	CHAN5G(100, 0),		CHAN5G(104, 0),
+	CHAN5G(108, 0),		CHAN5G(112, 0),
+	CHAN5G(116, 0),		CHAN5G(120, 0),
+	CHAN5G(124, 0),		CHAN5G(128, 0),
+	CHAN5G(132, 0),		CHAN5G(136, 0),
+	CHAN5G(140, 0),		CHAN5G(149, 0),
+	CHAN5G(153, 0),		CHAN5G(157, 0),
+	CHAN5G(161, 0),		CHAN5G(165, 0),
+	CHAN5G(184, 0),		CHAN5G(188, 0),
+	CHAN5G(192, 0),		CHAN5G(196, 0),
+	CHAN5G(200, 0),		CHAN5G(204, 0),
+	CHAN5G(208, 0),		CHAN5G(212, 0),
+	CHAN5G(216, 0),
+};
+
+static struct ieee80211_supported_band cw1200_band_2ghz = {
+	.channels = cw1200_2ghz_chantable,
+	.n_channels = ARRAY_SIZE(cw1200_2ghz_chantable),
+	.bitrates = cw1200_g_rates,
+	.n_bitrates = cw1200_g_rates_size,
+	.ht_cap = {
+		.cap = IEEE80211_HT_CAP_GRN_FLD |
+			(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
+			IEEE80211_HT_CAP_MAX_AMSDU,
+		.ht_supported = 1,
+		.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
+		.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
+		.mcs = {
+			.rx_mask[0] = 0xFF,
+			.rx_highest = __cpu_to_le16(0x41),
+			.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
+		},
+	},
+};
+
+static struct ieee80211_supported_band cw1200_band_5ghz = {
+	.channels = cw1200_5ghz_chantable,
+	.n_channels = ARRAY_SIZE(cw1200_5ghz_chantable),
+	.bitrates = cw1200_a_rates,
+	.n_bitrates = cw1200_a_rates_size,
+	.ht_cap = {
+		.cap = IEEE80211_HT_CAP_GRN_FLD |
+			(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
+			IEEE80211_HT_CAP_MAX_AMSDU,
+		.ht_supported = 1,
+		.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
+		.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
+		.mcs = {
+			.rx_mask[0] = 0xFF,
+			.rx_highest = __cpu_to_le16(0x41),
+			.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
+		},
+	},
+};
+
+static const unsigned long cw1200_ttl[] = {
+	1 * HZ,	/* VO */
+	2 * HZ,	/* VI */
+	5 * HZ, /* BE */
+	10 * HZ	/* BK */
+};
+
+static const struct ieee80211_ops cw1200_ops = {
+	.start			= cw1200_start,
+	.stop			= cw1200_stop,
+	.add_interface		= cw1200_add_interface,
+	.remove_interface	= cw1200_remove_interface,
+	.change_interface	= cw1200_change_interface,
+	.tx			= cw1200_tx,
+	.hw_scan		= cw1200_hw_scan,
+	.set_tim		= cw1200_set_tim,
+	.sta_notify		= cw1200_sta_notify,
+	.sta_add		= cw1200_sta_add,
+	.sta_remove		= cw1200_sta_remove,
+	.set_key		= cw1200_set_key,
+	.set_rts_threshold	= cw1200_set_rts_threshold,
+	.config			= cw1200_config,
+	.bss_info_changed	= cw1200_bss_info_changed,
+	.prepare_multicast	= cw1200_prepare_multicast,
+	.configure_filter	= cw1200_configure_filter,
+	.conf_tx		= cw1200_conf_tx,
+	.get_stats		= cw1200_get_stats,
+	.ampdu_action		= cw1200_ampdu_action,
+	.flush			= cw1200_flush,
+#ifdef CONFIG_PM
+	.suspend		= cw1200_wow_suspend,
+	.resume			= cw1200_wow_resume,
+#endif
+	/* Intentionally not offloaded:					*/
+	/*.channel_switch	= cw1200_channel_switch,		*/
+	/*.remain_on_channel	= cw1200_remain_on_channel,		*/
+	/*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel,	*/
+};
+
+static int cw1200_ba_rx_tids = -1;
+static int cw1200_ba_tx_tids = -1;
+module_param(cw1200_ba_rx_tids, int, 0644);
+module_param(cw1200_ba_tx_tids, int, 0644);
+MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs");
+MODULE_PARM_DESC(cw1200_ba_tx_tids, "Block ACK TX TIDs");
+
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support cw1200_wowlan_support = {
+	/* Support only for limited wowlan functionalities */
+	.flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT,
+};
+#endif
+
+
+static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
+						const bool have_5ghz)
+{
+	int i, band;
+	struct ieee80211_hw *hw;
+	struct cw1200_common *priv;
+
+	hw = ieee80211_alloc_hw(sizeof(struct cw1200_common), &cw1200_ops);
+	if (!hw)
+		return NULL;
+
+	priv = hw->priv;
+	priv->hw = hw;
+	priv->hw_type = -1;
+	priv->mode = NL80211_IFTYPE_UNSPECIFIED;
+	priv->rates = cw1200_rates; /* TODO: fetch from FW */
+	priv->mcs_rates = cw1200_n_rates;
+	if (cw1200_ba_rx_tids != -1)
+		priv->ba_rx_tid_mask = cw1200_ba_rx_tids;
+	else
+		priv->ba_rx_tid_mask = 0xFF; /* Enable RX BLKACK for all TIDs */
+	if (cw1200_ba_tx_tids != -1)
+		priv->ba_tx_tid_mask = cw1200_ba_tx_tids;
+	else
+		priv->ba_tx_tid_mask = 0xff; /* Enable TX BLKACK for all TIDs */
+
+	hw->flags = IEEE80211_HW_SIGNAL_DBM |
+		    IEEE80211_HW_SUPPORTS_PS |
+		    IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
+		    IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+		    IEEE80211_HW_SUPPORTS_UAPSD |
+		    IEEE80211_HW_CONNECTION_MONITOR |
+		    IEEE80211_HW_AMPDU_AGGREGATION |
+		    IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
+		    IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC;
+
+	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+					  BIT(NL80211_IFTYPE_ADHOC) |
+					  BIT(NL80211_IFTYPE_AP) |
+					  BIT(NL80211_IFTYPE_MESH_POINT) |
+					  BIT(NL80211_IFTYPE_P2P_CLIENT) |
+					  BIT(NL80211_IFTYPE_P2P_GO);
+
+#ifdef CONFIG_PM
+	hw->wiphy->wowlan = &cw1200_wowlan_support;
+#endif
+
+	hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
+
+	hw->channel_change_time = 1000;	/* TODO: find actual value */
+	hw->queues = 4;
+
+	priv->rts_threshold = -1;
+
+	hw->max_rates = 8;
+	hw->max_rate_tries = 15;
+	hw->extra_tx_headroom = WSM_TX_EXTRA_HEADROOM +
+		8;  /* TKIP IV */
+
+	hw->sta_data_size = sizeof(struct cw1200_sta_priv);
+
+	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &cw1200_band_2ghz;
+	if (have_5ghz)
+		hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &cw1200_band_5ghz;
+
+	/* Channel params have to be cleared before registering wiphy again */
+	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+		struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
+		if (!sband)
+			continue;
+		for (i = 0; i < sband->n_channels; i++) {
+			sband->channels[i].flags = 0;
+			sband->channels[i].max_antenna_gain = 0;
+			sband->channels[i].max_power = 30;
+		}
+	}
+
+	hw->wiphy->max_scan_ssids = 2;
+	hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
+
+	if (macaddr)
+		SET_IEEE80211_PERM_ADDR(hw, (u8 *)macaddr);
+	else
+		SET_IEEE80211_PERM_ADDR(hw, cw1200_mac_template);
+
+	/* Fix up mac address if necessary */
+	if (hw->wiphy->perm_addr[3] == 0 &&
+	    hw->wiphy->perm_addr[4] == 0 &&
+	    hw->wiphy->perm_addr[5] == 0) {
+		get_random_bytes(&hw->wiphy->perm_addr[3], 3);
+	}
+
+	mutex_init(&priv->wsm_cmd_mux);
+	mutex_init(&priv->conf_mutex);
+	priv->workqueue = create_singlethread_workqueue("cw1200_wq");
+	sema_init(&priv->scan.lock, 1);
+	INIT_WORK(&priv->scan.work, cw1200_scan_work);
+	INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
+	INIT_DELAYED_WORK(&priv->scan.timeout, cw1200_scan_timeout);
+	INIT_DELAYED_WORK(&priv->clear_recent_scan_work,
+			  cw1200_clear_recent_scan_work);
+	INIT_DELAYED_WORK(&priv->join_timeout, cw1200_join_timeout);
+	INIT_WORK(&priv->unjoin_work, cw1200_unjoin_work);
+	INIT_WORK(&priv->join_complete_work, cw1200_join_complete_work);
+	INIT_WORK(&priv->wep_key_work, cw1200_wep_key_work);
+	INIT_WORK(&priv->tx_policy_upload_work, tx_policy_upload_work);
+	spin_lock_init(&priv->event_queue_lock);
+	INIT_LIST_HEAD(&priv->event_queue);
+	INIT_WORK(&priv->event_handler, cw1200_event_handler);
+	INIT_DELAYED_WORK(&priv->bss_loss_work, cw1200_bss_loss_work);
+	INIT_WORK(&priv->bss_params_work, cw1200_bss_params_work);
+	spin_lock_init(&priv->bss_loss_lock);
+	spin_lock_init(&priv->ps_state_lock);
+	INIT_WORK(&priv->set_cts_work, cw1200_set_cts_work);
+	INIT_WORK(&priv->set_tim_work, cw1200_set_tim_work);
+	INIT_WORK(&priv->multicast_start_work, cw1200_multicast_start_work);
+	INIT_WORK(&priv->multicast_stop_work, cw1200_multicast_stop_work);
+	INIT_WORK(&priv->link_id_work, cw1200_link_id_work);
+	INIT_DELAYED_WORK(&priv->link_id_gc_work, cw1200_link_id_gc_work);
+	INIT_WORK(&priv->linkid_reset_work, cw1200_link_id_reset);
+	INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
+	INIT_WORK(&priv->set_beacon_wakeup_period_work,
+		  cw1200_set_beacon_wakeup_period_work);
+	init_timer(&priv->mcast_timeout);
+	priv->mcast_timeout.data = (unsigned long)priv;
+	priv->mcast_timeout.function = cw1200_mcast_timeout;
+
+	if (cw1200_queue_stats_init(&priv->tx_queue_stats,
+				    CW1200_LINK_ID_MAX,
+				    cw1200_skb_dtor,
+				    priv)) {
+		ieee80211_free_hw(hw);
+		return NULL;
+	}
+
+	for (i = 0; i < 4; ++i) {
+		if (cw1200_queue_init(&priv->tx_queue[i],
+				      &priv->tx_queue_stats, i, 16,
+				      cw1200_ttl[i])) {
+			for (; i > 0; i--)
+				cw1200_queue_deinit(&priv->tx_queue[i - 1]);
+			cw1200_queue_stats_deinit(&priv->tx_queue_stats);
+			ieee80211_free_hw(hw);
+			return NULL;
+		}
+	}
+
+	init_waitqueue_head(&priv->channel_switch_done);
+	init_waitqueue_head(&priv->wsm_cmd_wq);
+	init_waitqueue_head(&priv->wsm_startup_done);
+	init_waitqueue_head(&priv->ps_mode_switch_done);
+	wsm_buf_init(&priv->wsm_cmd_buf);
+	spin_lock_init(&priv->wsm_cmd.lock);
+	priv->wsm_cmd.done = 1;
+	tx_policy_init(priv);
+
+	return hw;
+}
+
+static int cw1200_register_common(struct ieee80211_hw *dev)
+{
+	struct cw1200_common *priv = dev->priv;
+	int err;
+
+#ifdef CONFIG_PM
+	err = cw1200_pm_init(&priv->pm_state, priv);
+	if (err) {
+		pr_err("Cannot init PM. (%d).\n",
+		       err);
+		return err;
+	}
+#endif
+
+	err = ieee80211_register_hw(dev);
+	if (err) {
+		pr_err("Cannot register device (%d).\n",
+		       err);
+#ifdef CONFIG_PM
+		cw1200_pm_deinit(&priv->pm_state);
+#endif
+		return err;
+	}
+
+	cw1200_debug_init(priv);
+
+	pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy));
+	return 0;
+}
+
+static void cw1200_free_common(struct ieee80211_hw *dev)
+{
+	ieee80211_free_hw(dev);
+}
+
+static void cw1200_unregister_common(struct ieee80211_hw *dev)
+{
+	struct cw1200_common *priv = dev->priv;
+	int i;
+
+	ieee80211_unregister_hw(dev);
+
+	del_timer_sync(&priv->mcast_timeout);
+	cw1200_unregister_bh(priv);
+
+	cw1200_debug_release(priv);
+
+	mutex_destroy(&priv->conf_mutex);
+
+	wsm_buf_deinit(&priv->wsm_cmd_buf);
+
+	destroy_workqueue(priv->workqueue);
+	priv->workqueue = NULL;
+
+	if (priv->sdd) {
+		release_firmware(priv->sdd);
+		priv->sdd = NULL;
+	}
+
+	for (i = 0; i < 4; ++i)
+		cw1200_queue_deinit(&priv->tx_queue[i]);
+
+	cw1200_queue_stats_deinit(&priv->tx_queue_stats);
+#ifdef CONFIG_PM
+	cw1200_pm_deinit(&priv->pm_state);
+#endif
+}
+
+/* Clock is in KHz */
+u32 cw1200_dpll_from_clk(u16 clk_khz)
+{
+	switch (clk_khz) {
+	case 0x32C8: /* 13000 KHz */
+		return 0x1D89D241;
+	case 0x3E80: /* 16000 KHz */
+		return 0x000001E1;
+	case 0x41A0: /* 16800 KHz */
+		return 0x124931C1;
+	case 0x4B00: /* 19200 KHz */
+		return 0x00000191;
+	case 0x5DC0: /* 24000 KHz */
+		return 0x00000141;
+	case 0x6590: /* 26000 KHz */
+		return 0x0EC4F121;
+	case 0x8340: /* 33600 KHz */
+		return 0x092490E1;
+	case 0x9600: /* 38400 KHz */
+		return 0x100010C1;
+	case 0x9C40: /* 40000 KHz */
+		return 0x000000C1;
+	case 0xBB80: /* 48000 KHz */
+		return 0x000000A1;
+	case 0xCB20: /* 52000 KHz */
+		return 0x07627091;
+	default:
+		pr_err("Unknown Refclk freq (0x%04x), using 2600KHz\n",
+		       clk_khz);
+		return 0x0EC4F121;
+	}
+}
+
+int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
+		      struct hwbus_priv *hwbus,
+		      struct device *pdev,
+		      struct cw1200_common **core,
+		      int ref_clk, const u8 *macaddr,
+		      const char *sdd_path, bool have_5ghz)
+{
+	int err = -EINVAL;
+	struct ieee80211_hw *dev;
+	struct cw1200_common *priv;
+	struct wsm_operational_mode mode = {
+		.power_mode = cw1200_power_mode,
+		.disable_more_flag_usage = true,
+	};
+
+	dev = cw1200_init_common(macaddr, have_5ghz);
+	if (!dev)
+		goto err;
+
+	priv = dev->priv;
+	priv->hw_refclk = ref_clk;
+	if (cw1200_refclk)
+		priv->hw_refclk = cw1200_refclk;
+
+	priv->sdd_path = (char *)sdd_path;
+	if (cw1200_sdd_path)
+		priv->sdd_path = cw1200_sdd_path;
+
+	priv->hwbus_ops = hwbus_ops;
+	priv->hwbus_priv = hwbus;
+	priv->pdev = pdev;
+	SET_IEEE80211_DEV(priv->hw, pdev);
+
+	/* Pass struct cw1200_common back up */
+	*core = priv;
+
+	err = cw1200_register_bh(priv);
+	if (err)
+		goto err1;
+
+	err = cw1200_load_firmware(priv);
+	if (err)
+		goto err2;
+
+	if (wait_event_interruptible_timeout(priv->wsm_startup_done,
+					     priv->firmware_ready,
+					     3*HZ) <= 0) {
+		/* TODO: Need to find how to reset device
+		   in QUEUE mode properly.
+		*/
+		pr_err("Timeout waiting on device startup\n");
+		err = -ETIMEDOUT;
+		goto err2;
+	}
+
+	/* Set low-power mode. */
+	wsm_set_operational_mode(priv, &mode);
+
+	/* Enable multi-TX confirmation */
+	wsm_use_multi_tx_conf(priv, true);
+
+	err = cw1200_register_common(dev);
+	if (err)
+		goto err2;
+
+	return err;
+
+err2:
+	cw1200_unregister_bh(priv);
+err1:
+	cw1200_free_common(dev);
+err:
+	*core = NULL;
+	return err;
+}
+EXPORT_SYMBOL_GPL(cw1200_core_probe);
+
+void cw1200_core_release(struct cw1200_common *self)
+{
+	/* Disable device interrupts */
+	self->hwbus_ops->lock(self->hwbus_priv);
+	__cw1200_irq_enable(self, 0);
+	self->hwbus_ops->unlock(self->hwbus_priv);
+
+	/* And then clean up */
+	cw1200_unregister_common(self->hw);
+	cw1200_free_common(self->hw);
+	return;
+}
+EXPORT_SYMBOL_GPL(cw1200_core_release);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,21 @@
+cw1200_core-y := \
+		fwio.o \
+		txrx.o \
+		main.o \
+		queue.o \
+		hwio.o \
+		bh.o \
+		wsm.o \
+		sta.o \
+		scan.o \
+		debug.o
+cw1200_core-$(CONFIG_PM)	+= pm.o
+
+# CFLAGS_sta.o += -DDEBUG
+
+cw1200_wlan_sdio-y := cw1200_sdio.o
+cw1200_wlan_spi-y := cw1200_spi.o
+
+obj-$(CONFIG_CW1200) += cw1200_core.o
+obj-$(CONFIG_CW1200_WLAN_SDIO) += cw1200_wlan_sdio.o
+obj-$(CONFIG_CW1200_WLAN_SPI) += cw1200_wlan_spi.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/pm.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/pm.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/pm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,367 @@
+/*
+ * Mac80211 power management API for ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2011, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/if_ether.h>
+#include "cw1200.h"
+#include "pm.h"
+#include "sta.h"
+#include "bh.h"
+#include "hwbus.h"
+
+#define CW1200_BEACON_SKIPPING_MULTIPLIER 3
+
+struct cw1200_udp_port_filter {
+	struct wsm_udp_port_filter_hdr hdr;
+	/* Up to 4 filters are allowed. */
+	struct wsm_udp_port_filter filters[WSM_MAX_FILTER_ELEMENTS];
+} __packed;
+
+struct cw1200_ether_type_filter {
+	struct wsm_ether_type_filter_hdr hdr;
+	/* Up to 4 filters are allowed. */
+	struct wsm_ether_type_filter filters[WSM_MAX_FILTER_ELEMENTS];
+} __packed;
+
+static struct cw1200_udp_port_filter cw1200_udp_port_filter_on = {
+	.hdr.num = 2,
+	.filters = {
+		[0] = {
+			.action = WSM_FILTER_ACTION_FILTER_OUT,
+			.type = WSM_FILTER_PORT_TYPE_DST,
+			.port = __cpu_to_le16(67), /* DHCP Bootps */
+		},
+		[1] = {
+			.action = WSM_FILTER_ACTION_FILTER_OUT,
+			.type = WSM_FILTER_PORT_TYPE_DST,
+			.port = __cpu_to_le16(68), /* DHCP Bootpc */
+		},
+	}
+};
+
+static struct wsm_udp_port_filter_hdr cw1200_udp_port_filter_off = {
+	.num = 0,
+};
+
+#ifndef ETH_P_WAPI
+#define ETH_P_WAPI     0x88B4
+#endif
+
+static struct cw1200_ether_type_filter cw1200_ether_type_filter_on = {
+	.hdr.num = 4,
+	.filters = {
+		[0] = {
+			.action = WSM_FILTER_ACTION_FILTER_IN,
+			.type = __cpu_to_le16(ETH_P_IP),
+		},
+		[1] = {
+			.action = WSM_FILTER_ACTION_FILTER_IN,
+			.type = __cpu_to_le16(ETH_P_PAE),
+		},
+		[2] = {
+			.action = WSM_FILTER_ACTION_FILTER_IN,
+			.type = __cpu_to_le16(ETH_P_WAPI),
+		},
+		[3] = {
+			.action = WSM_FILTER_ACTION_FILTER_IN,
+			.type = __cpu_to_le16(ETH_P_ARP),
+		},
+	},
+};
+
+static struct wsm_ether_type_filter_hdr cw1200_ether_type_filter_off = {
+	.num = 0,
+};
+
+/* private */
+struct cw1200_suspend_state {
+	unsigned long bss_loss_tmo;
+	unsigned long join_tmo;
+	unsigned long direct_probe;
+	unsigned long link_id_gc;
+	bool beacon_skipping;
+	u8 prev_ps_mode;
+};
+
+static void cw1200_pm_stay_awake_tmo(unsigned long arg)
+{
+	/* XXX what's the point of this ? */
+}
+
+int cw1200_pm_init(struct cw1200_pm_state *pm,
+		   struct cw1200_common *priv)
+{
+	spin_lock_init(&pm->lock);
+
+	init_timer(&pm->stay_awake);
+	pm->stay_awake.data = (unsigned long)pm;
+	pm->stay_awake.function = cw1200_pm_stay_awake_tmo;
+
+	return 0;
+}
+
+void cw1200_pm_deinit(struct cw1200_pm_state *pm)
+{
+	del_timer_sync(&pm->stay_awake);
+}
+
+void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
+			  unsigned long tmo)
+{
+	long cur_tmo;
+	spin_lock_bh(&pm->lock);
+	cur_tmo = pm->stay_awake.expires - jiffies;
+	if (!timer_pending(&pm->stay_awake) || cur_tmo < (long)tmo)
+		mod_timer(&pm->stay_awake, jiffies + tmo);
+	spin_unlock_bh(&pm->lock);
+}
+
+static long cw1200_suspend_work(struct delayed_work *work)
+{
+	int ret = cancel_delayed_work(work);
+	long tmo;
+	if (ret > 0) {
+		/* Timer is pending */
+		tmo = work->timer.expires - jiffies;
+		if (tmo < 0)
+			tmo = 0;
+	} else {
+		tmo = -1;
+	}
+	return tmo;
+}
+
+static int cw1200_resume_work(struct cw1200_common *priv,
+			       struct delayed_work *work,
+			       unsigned long tmo)
+{
+	if ((long)tmo < 0)
+		return 1;
+
+	return queue_delayed_work(priv->workqueue, work, tmo);
+}
+
+int cw1200_can_suspend(struct cw1200_common *priv)
+{
+	if (atomic_read(&priv->bh_rx)) {
+		wiphy_dbg(priv->hw->wiphy, "Suspend interrupted.\n");
+		return 0;
+	}
+	return 1;
+}
+EXPORT_SYMBOL_GPL(cw1200_can_suspend);
+
+int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+{
+	struct cw1200_common *priv = hw->priv;
+	struct cw1200_pm_state *pm_state = &priv->pm_state;
+	struct cw1200_suspend_state *state;
+	int ret;
+
+	spin_lock_bh(&pm_state->lock);
+	ret = timer_pending(&pm_state->stay_awake);
+	spin_unlock_bh(&pm_state->lock);
+	if (ret)
+		return -EAGAIN;
+
+	/* Do not suspend when datapath is not idle */
+	if (priv->tx_queue_stats.num_queued)
+		return -EBUSY;
+
+	/* Make sure there is no configuration requests in progress. */
+	if (!mutex_trylock(&priv->conf_mutex))
+		return -EBUSY;
+
+	/* Ensure pending operations are done.
+	 * Note also that wow_suspend must return in ~2.5sec, before
+	 * watchdog is triggered.
+	 */
+	if (priv->channel_switch_in_progress)
+		goto revert1;
+
+	/* Do not suspend when join is pending */
+	if (priv->join_pending)
+		goto revert1;
+
+	/* Do not suspend when scanning */
+	if (down_trylock(&priv->scan.lock))
+		goto revert1;
+
+	/* Lock TX. */
+	wsm_lock_tx_async(priv);
+
+	/* Wait to avoid possible race with bh code.
+	 * But do not wait too long...
+	 */
+	if (wait_event_timeout(priv->bh_evt_wq,
+			       !priv->hw_bufs_used, HZ / 10) <= 0)
+		goto revert2;
+
+	/* Set UDP filter */
+	wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_on.hdr);
+
+	/* Set ethernet frame type filter */
+	wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_on.hdr);
+
+	/* Allocate state */
+	state = kzalloc(sizeof(struct cw1200_suspend_state), GFP_KERNEL);
+	if (!state)
+		goto revert3;
+
+	/* Change to legacy PS while going to suspend */
+	if (!priv->vif->p2p &&
+	    priv->join_status == CW1200_JOIN_STATUS_STA &&
+	    priv->powersave_mode.mode != WSM_PSM_PS) {
+		state->prev_ps_mode = priv->powersave_mode.mode;
+		priv->powersave_mode.mode = WSM_PSM_PS;
+		cw1200_set_pm(priv, &priv->powersave_mode);
+		if (wait_event_interruptible_timeout(priv->ps_mode_switch_done,
+						     !priv->ps_mode_switch_in_progress, 1*HZ) <= 0) {
+			goto revert3;
+		}
+	}
+
+	/* Store delayed work states. */
+	state->bss_loss_tmo =
+		cw1200_suspend_work(&priv->bss_loss_work);
+	state->join_tmo =
+		cw1200_suspend_work(&priv->join_timeout);
+	state->direct_probe =
+		cw1200_suspend_work(&priv->scan.probe_work);
+	state->link_id_gc =
+		cw1200_suspend_work(&priv->link_id_gc_work);
+
+	cancel_delayed_work_sync(&priv->clear_recent_scan_work);
+	atomic_set(&priv->recent_scan, 0);
+
+	/* Enable beacon skipping */
+	if (priv->join_status == CW1200_JOIN_STATUS_STA &&
+	    priv->join_dtim_period &&
+	    !priv->has_multicast_subscription) {
+		state->beacon_skipping = true;
+		wsm_set_beacon_wakeup_period(priv,
+					     priv->join_dtim_period,
+					     CW1200_BEACON_SKIPPING_MULTIPLIER * priv->join_dtim_period);
+	}
+
+	/* Stop serving thread */
+	if (cw1200_bh_suspend(priv))
+		goto revert4;
+
+	ret = timer_pending(&priv->mcast_timeout);
+	if (ret)
+		goto revert5;
+
+	/* Store suspend state */
+	pm_state->suspend_state = state;
+
+	/* Enable IRQ wake */
+	ret = priv->hwbus_ops->power_mgmt(priv->hwbus_priv, true);
+	if (ret) {
+		wiphy_err(priv->hw->wiphy,
+			  "PM request failed: %d. WoW is disabled.\n", ret);
+		cw1200_wow_resume(hw);
+		return -EBUSY;
+	}
+
+	/* Force resume if event is coming from the device. */
+	if (atomic_read(&priv->bh_rx)) {
+		cw1200_wow_resume(hw);
+		return -EAGAIN;
+	}
+
+	return 0;
+
+revert5:
+	WARN_ON(cw1200_bh_resume(priv));
+revert4:
+	cw1200_resume_work(priv, &priv->bss_loss_work,
+			   state->bss_loss_tmo);
+	cw1200_resume_work(priv, &priv->join_timeout,
+			   state->join_tmo);
+	cw1200_resume_work(priv, &priv->scan.probe_work,
+			   state->direct_probe);
+	cw1200_resume_work(priv, &priv->link_id_gc_work,
+			   state->link_id_gc);
+	kfree(state);
+revert3:
+	wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off);
+	wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_off);
+revert2:
+	wsm_unlock_tx(priv);
+	up(&priv->scan.lock);
+revert1:
+	mutex_unlock(&priv->conf_mutex);
+	return -EBUSY;
+}
+
+int cw1200_wow_resume(struct ieee80211_hw *hw)
+{
+	struct cw1200_common *priv = hw->priv;
+	struct cw1200_pm_state *pm_state = &priv->pm_state;
+	struct cw1200_suspend_state *state;
+
+	state = pm_state->suspend_state;
+	pm_state->suspend_state = NULL;
+
+	/* Disable IRQ wake */
+	priv->hwbus_ops->power_mgmt(priv->hwbus_priv, false);
+
+	/* Scan.lock must be released before BH is resumed other way
+	 * in case when BSS_LOST command arrived the processing of the
+	 * command will be delayed.
+	 */
+	up(&priv->scan.lock);
+
+	/* Resume BH thread */
+	WARN_ON(cw1200_bh_resume(priv));
+
+	/* Restores previous PS mode */
+	if (!priv->vif->p2p && priv->join_status == CW1200_JOIN_STATUS_STA) {
+		priv->powersave_mode.mode = state->prev_ps_mode;
+		cw1200_set_pm(priv, &priv->powersave_mode);
+	}
+
+	if (state->beacon_skipping) {
+		wsm_set_beacon_wakeup_period(priv, priv->beacon_int *
+					     priv->join_dtim_period >
+					     MAX_BEACON_SKIP_TIME_MS ? 1 :
+					     priv->join_dtim_period, 0);
+		state->beacon_skipping = false;
+	}
+
+	/* Resume delayed work */
+	cw1200_resume_work(priv, &priv->bss_loss_work,
+			   state->bss_loss_tmo);
+	cw1200_resume_work(priv, &priv->join_timeout,
+			   state->join_tmo);
+	cw1200_resume_work(priv, &priv->scan.probe_work,
+			   state->direct_probe);
+	cw1200_resume_work(priv, &priv->link_id_gc_work,
+			   state->link_id_gc);
+
+	/* Remove UDP port filter */
+	wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off);
+
+	/* Remove ethernet frame type filter */
+	wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_off);
+
+	/* Unlock datapath */
+	wsm_unlock_tx(priv);
+
+	/* Unlock configuration mutex */
+	mutex_unlock(&priv->conf_mutex);
+
+	/* Free memory */
+	kfree(state);
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/pm.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/pm.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/pm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/pm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ * Mac80211 power management interface for ST-Ericsson CW1200 mac80211 drivers
+ *
+ * Copyright (c) 2011, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef PM_H_INCLUDED
+#define PM_H_INCLUDED
+
+/* ******************************************************************** */
+/* mac80211 API								*/
+
+/* extern */  struct cw1200_common;
+/* private */ struct cw1200_suspend_state;
+
+struct cw1200_pm_state {
+	struct cw1200_suspend_state *suspend_state;
+	struct timer_list stay_awake;
+	struct platform_device *pm_dev;
+	spinlock_t lock; /* Protect access */
+};
+
+#ifdef CONFIG_PM
+int cw1200_pm_init(struct cw1200_pm_state *pm,
+		    struct cw1200_common *priv);
+void cw1200_pm_deinit(struct cw1200_pm_state *pm);
+int cw1200_wow_suspend(struct ieee80211_hw *hw,
+		       struct cfg80211_wowlan *wowlan);
+int cw1200_wow_resume(struct ieee80211_hw *hw);
+int cw1200_can_suspend(struct cw1200_common *priv);
+void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
+			  unsigned long tmo);
+#else
+static inline void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
+					unsigned long tmo) {
+}
+#endif
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/queue.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/queue.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/queue.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/queue.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,583 @@
+/*
+ * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <net/mac80211.h>
+#include <linux/sched.h>
+#include "queue.h"
+#include "cw1200.h"
+#include "debug.h"
+
+/* private */ struct cw1200_queue_item
+{
+	struct list_head	head;
+	struct sk_buff		*skb;
+	u32			packet_id;
+	unsigned long		queue_timestamp;
+	unsigned long		xmit_timestamp;
+	struct cw1200_txpriv	txpriv;
+	u8			generation;
+};
+
+static inline void __cw1200_queue_lock(struct cw1200_queue *queue)
+{
+	struct cw1200_queue_stats *stats = queue->stats;
+	if (queue->tx_locked_cnt++ == 0) {
+		pr_debug("[TX] Queue %d is locked.\n",
+			 queue->queue_id);
+		ieee80211_stop_queue(stats->priv->hw, queue->queue_id);
+	}
+}
+
+static inline void __cw1200_queue_unlock(struct cw1200_queue *queue)
+{
+	struct cw1200_queue_stats *stats = queue->stats;
+	BUG_ON(!queue->tx_locked_cnt);
+	if (--queue->tx_locked_cnt == 0) {
+		pr_debug("[TX] Queue %d is unlocked.\n",
+			 queue->queue_id);
+		ieee80211_wake_queue(stats->priv->hw, queue->queue_id);
+	}
+}
+
+static inline void cw1200_queue_parse_id(u32 packet_id, u8 *queue_generation,
+					 u8 *queue_id, u8 *item_generation,
+					 u8 *item_id)
+{
+	*item_id		= (packet_id >>  0) & 0xFF;
+	*item_generation	= (packet_id >>  8) & 0xFF;
+	*queue_id		= (packet_id >> 16) & 0xFF;
+	*queue_generation	= (packet_id >> 24) & 0xFF;
+}
+
+static inline u32 cw1200_queue_mk_packet_id(u8 queue_generation, u8 queue_id,
+					    u8 item_generation, u8 item_id)
+{
+	return ((u32)item_id << 0) |
+		((u32)item_generation << 8) |
+		((u32)queue_id << 16) |
+		((u32)queue_generation << 24);
+}
+
+static void cw1200_queue_post_gc(struct cw1200_queue_stats *stats,
+				 struct list_head *gc_list)
+{
+	struct cw1200_queue_item *item, *tmp;
+
+	list_for_each_entry_safe(item, tmp, gc_list, head) {
+		list_del(&item->head);
+		stats->skb_dtor(stats->priv, item->skb, &item->txpriv);
+		kfree(item);
+	}
+}
+
+static void cw1200_queue_register_post_gc(struct list_head *gc_list,
+					  struct cw1200_queue_item *item)
+{
+	struct cw1200_queue_item *gc_item;
+	gc_item = kmalloc(sizeof(struct cw1200_queue_item),
+			GFP_ATOMIC);
+	BUG_ON(!gc_item);
+	memcpy(gc_item, item, sizeof(struct cw1200_queue_item));
+	list_add_tail(&gc_item->head, gc_list);
+}
+
+static void __cw1200_queue_gc(struct cw1200_queue *queue,
+			      struct list_head *head,
+			      bool unlock)
+{
+	struct cw1200_queue_stats *stats = queue->stats;
+	struct cw1200_queue_item *item = NULL, *tmp;
+	bool wakeup_stats = false;
+
+	list_for_each_entry_safe(item, tmp, &queue->queue, head) {
+		if (jiffies - item->queue_timestamp < queue->ttl)
+			break;
+		--queue->num_queued;
+		--queue->link_map_cache[item->txpriv.link_id];
+		spin_lock_bh(&stats->lock);
+		--stats->num_queued;
+		if (!--stats->link_map_cache[item->txpriv.link_id])
+			wakeup_stats = true;
+		spin_unlock_bh(&stats->lock);
+		cw1200_debug_tx_ttl(stats->priv);
+		cw1200_queue_register_post_gc(head, item);
+		item->skb = NULL;
+		list_move_tail(&item->head, &queue->free_pool);
+	}
+
+	if (wakeup_stats)
+		wake_up(&stats->wait_link_id_empty);
+
+	if (queue->overfull) {
+		if (queue->num_queued <= (queue->capacity >> 1)) {
+			queue->overfull = false;
+			if (unlock)
+				__cw1200_queue_unlock(queue);
+		} else if (item) {
+			unsigned long tmo = item->queue_timestamp + queue->ttl;
+			mod_timer(&queue->gc, tmo);
+			cw1200_pm_stay_awake(&stats->priv->pm_state,
+					     tmo - jiffies);
+		}
+	}
+}
+
+static void cw1200_queue_gc(unsigned long arg)
+{
+	LIST_HEAD(list);
+	struct cw1200_queue *queue =
+		(struct cw1200_queue *)arg;
+
+	spin_lock_bh(&queue->lock);
+	__cw1200_queue_gc(queue, &list, true);
+	spin_unlock_bh(&queue->lock);
+	cw1200_queue_post_gc(queue->stats, &list);
+}
+
+int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
+			    size_t map_capacity,
+			    cw1200_queue_skb_dtor_t skb_dtor,
+			    struct cw1200_common *priv)
+{
+	memset(stats, 0, sizeof(*stats));
+	stats->map_capacity = map_capacity;
+	stats->skb_dtor = skb_dtor;
+	stats->priv = priv;
+	spin_lock_init(&stats->lock);
+	init_waitqueue_head(&stats->wait_link_id_empty);
+
+	stats->link_map_cache = kzalloc(sizeof(int) * map_capacity,
+					GFP_KERNEL);
+	if (!stats->link_map_cache)
+		return -ENOMEM;
+
+	return 0;
+}
+
+int cw1200_queue_init(struct cw1200_queue *queue,
+		      struct cw1200_queue_stats *stats,
+		      u8 queue_id,
+		      size_t capacity,
+		      unsigned long ttl)
+{
+	size_t i;
+
+	memset(queue, 0, sizeof(*queue));
+	queue->stats = stats;
+	queue->capacity = capacity;
+	queue->queue_id = queue_id;
+	queue->ttl = ttl;
+	INIT_LIST_HEAD(&queue->queue);
+	INIT_LIST_HEAD(&queue->pending);
+	INIT_LIST_HEAD(&queue->free_pool);
+	spin_lock_init(&queue->lock);
+	init_timer(&queue->gc);
+	queue->gc.data = (unsigned long)queue;
+	queue->gc.function = cw1200_queue_gc;
+
+	queue->pool = kzalloc(sizeof(struct cw1200_queue_item) * capacity,
+			GFP_KERNEL);
+	if (!queue->pool)
+		return -ENOMEM;
+
+	queue->link_map_cache = kzalloc(sizeof(int) * stats->map_capacity,
+			GFP_KERNEL);
+	if (!queue->link_map_cache) {
+		kfree(queue->pool);
+		queue->pool = NULL;
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < capacity; ++i)
+		list_add_tail(&queue->pool[i].head, &queue->free_pool);
+
+	return 0;
+}
+
+int cw1200_queue_clear(struct cw1200_queue *queue)
+{
+	int i;
+	LIST_HEAD(gc_list);
+	struct cw1200_queue_stats *stats = queue->stats;
+	struct cw1200_queue_item *item, *tmp;
+
+	spin_lock_bh(&queue->lock);
+	queue->generation++;
+	list_splice_tail_init(&queue->queue, &queue->pending);
+	list_for_each_entry_safe(item, tmp, &queue->pending, head) {
+		WARN_ON(!item->skb);
+		cw1200_queue_register_post_gc(&gc_list, item);
+		item->skb = NULL;
+		list_move_tail(&item->head, &queue->free_pool);
+	}
+	queue->num_queued = 0;
+	queue->num_pending = 0;
+
+	spin_lock_bh(&stats->lock);
+	for (i = 0; i < stats->map_capacity; ++i) {
+		stats->num_queued -= queue->link_map_cache[i];
+		stats->link_map_cache[i] -= queue->link_map_cache[i];
+		queue->link_map_cache[i] = 0;
+	}
+	spin_unlock_bh(&stats->lock);
+	if (queue->overfull) {
+		queue->overfull = false;
+		__cw1200_queue_unlock(queue);
+	}
+	spin_unlock_bh(&queue->lock);
+	wake_up(&stats->wait_link_id_empty);
+	cw1200_queue_post_gc(stats, &gc_list);
+	return 0;
+}
+
+void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats)
+{
+	kfree(stats->link_map_cache);
+	stats->link_map_cache = NULL;
+}
+
+void cw1200_queue_deinit(struct cw1200_queue *queue)
+{
+	cw1200_queue_clear(queue);
+	del_timer_sync(&queue->gc);
+	INIT_LIST_HEAD(&queue->free_pool);
+	kfree(queue->pool);
+	kfree(queue->link_map_cache);
+	queue->pool = NULL;
+	queue->link_map_cache = NULL;
+	queue->capacity = 0;
+}
+
+size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
+				   u32 link_id_map)
+{
+	size_t ret;
+	int i, bit;
+	size_t map_capacity = queue->stats->map_capacity;
+
+	if (!link_id_map)
+		return 0;
+
+	spin_lock_bh(&queue->lock);
+	if (link_id_map == (u32)-1) {
+		ret = queue->num_queued - queue->num_pending;
+	} else {
+		ret = 0;
+		for (i = 0, bit = 1; i < map_capacity; ++i, bit <<= 1) {
+			if (link_id_map & bit)
+				ret += queue->link_map_cache[i];
+		}
+	}
+	spin_unlock_bh(&queue->lock);
+	return ret;
+}
+
+int cw1200_queue_put(struct cw1200_queue *queue,
+		     struct sk_buff *skb,
+		     struct cw1200_txpriv *txpriv)
+{
+	int ret = 0;
+	LIST_HEAD(gc_list);
+	struct cw1200_queue_stats *stats = queue->stats;
+
+	if (txpriv->link_id >= queue->stats->map_capacity)
+		return -EINVAL;
+
+	spin_lock_bh(&queue->lock);
+	if (!WARN_ON(list_empty(&queue->free_pool))) {
+		struct cw1200_queue_item *item = list_first_entry(
+			&queue->free_pool, struct cw1200_queue_item, head);
+		BUG_ON(item->skb);
+
+		list_move_tail(&item->head, &queue->queue);
+		item->skb = skb;
+		item->txpriv = *txpriv;
+		item->generation = 0;
+		item->packet_id = cw1200_queue_mk_packet_id(queue->generation,
+							    queue->queue_id,
+							    item->generation,
+							    item - queue->pool);
+		item->queue_timestamp = jiffies;
+
+		++queue->num_queued;
+		++queue->link_map_cache[txpriv->link_id];
+
+		spin_lock_bh(&stats->lock);
+		++stats->num_queued;
+		++stats->link_map_cache[txpriv->link_id];
+		spin_unlock_bh(&stats->lock);
+
+		/* TX may happen in parallel sometimes.
+		 * Leave extra queue slots so we don't overflow.
+		 */
+		if (queue->overfull == false &&
+		    queue->num_queued >=
+		    (queue->capacity - (num_present_cpus() - 1))) {
+			queue->overfull = true;
+			__cw1200_queue_lock(queue);
+			mod_timer(&queue->gc, jiffies);
+		}
+	} else {
+		ret = -ENOENT;
+	}
+	spin_unlock_bh(&queue->lock);
+	return ret;
+}
+
+int cw1200_queue_get(struct cw1200_queue *queue,
+		     u32 link_id_map,
+		     struct wsm_tx **tx,
+		     struct ieee80211_tx_info **tx_info,
+		     const struct cw1200_txpriv **txpriv)
+{
+	int ret = -ENOENT;
+	struct cw1200_queue_item *item;
+	struct cw1200_queue_stats *stats = queue->stats;
+	bool wakeup_stats = false;
+
+	spin_lock_bh(&queue->lock);
+	list_for_each_entry(item, &queue->queue, head) {
+		if (link_id_map & BIT(item->txpriv.link_id)) {
+			ret = 0;
+			break;
+		}
+	}
+
+	if (!WARN_ON(ret)) {
+		*tx = (struct wsm_tx *)item->skb->data;
+		*tx_info = IEEE80211_SKB_CB(item->skb);
+		*txpriv = &item->txpriv;
+		(*tx)->packet_id = item->packet_id;
+		list_move_tail(&item->head, &queue->pending);
+		++queue->num_pending;
+		--queue->link_map_cache[item->txpriv.link_id];
+		item->xmit_timestamp = jiffies;
+
+		spin_lock_bh(&stats->lock);
+		--stats->num_queued;
+		if (!--stats->link_map_cache[item->txpriv.link_id])
+			wakeup_stats = true;
+		spin_unlock_bh(&stats->lock);
+	}
+	spin_unlock_bh(&queue->lock);
+	if (wakeup_stats)
+		wake_up(&stats->wait_link_id_empty);
+	return ret;
+}
+
+int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id)
+{
+	int ret = 0;
+	u8 queue_generation, queue_id, item_generation, item_id;
+	struct cw1200_queue_item *item;
+	struct cw1200_queue_stats *stats = queue->stats;
+
+	cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
+			      &item_generation, &item_id);
+
+	item = &queue->pool[item_id];
+
+	spin_lock_bh(&queue->lock);
+	BUG_ON(queue_id != queue->queue_id);
+	if (queue_generation != queue->generation) {
+		ret = -ENOENT;
+	} else if (item_id >= (unsigned) queue->capacity) {
+		WARN_ON(1);
+		ret = -EINVAL;
+	} else if (item->generation != item_generation) {
+		WARN_ON(1);
+		ret = -ENOENT;
+	} else {
+		--queue->num_pending;
+		++queue->link_map_cache[item->txpriv.link_id];
+
+		spin_lock_bh(&stats->lock);
+		++stats->num_queued;
+		++stats->link_map_cache[item->txpriv.link_id];
+		spin_unlock_bh(&stats->lock);
+
+		item->generation = ++item_generation;
+		item->packet_id = cw1200_queue_mk_packet_id(queue_generation,
+							    queue_id,
+							    item_generation,
+							    item_id);
+		list_move(&item->head, &queue->queue);
+	}
+	spin_unlock_bh(&queue->lock);
+	return ret;
+}
+
+int cw1200_queue_requeue_all(struct cw1200_queue *queue)
+{
+	struct cw1200_queue_item *item, *tmp;
+	struct cw1200_queue_stats *stats = queue->stats;
+	spin_lock_bh(&queue->lock);
+
+	list_for_each_entry_safe_reverse(item, tmp, &queue->pending, head) {
+		--queue->num_pending;
+		++queue->link_map_cache[item->txpriv.link_id];
+
+		spin_lock_bh(&stats->lock);
+		++stats->num_queued;
+		++stats->link_map_cache[item->txpriv.link_id];
+		spin_unlock_bh(&stats->lock);
+
+		++item->generation;
+		item->packet_id = cw1200_queue_mk_packet_id(queue->generation,
+							    queue->queue_id,
+							    item->generation,
+							    item - queue->pool);
+		list_move(&item->head, &queue->queue);
+	}
+	spin_unlock_bh(&queue->lock);
+
+	return 0;
+}
+
+int cw1200_queue_remove(struct cw1200_queue *queue, u32 packet_id)
+{
+	int ret = 0;
+	u8 queue_generation, queue_id, item_generation, item_id;
+	struct cw1200_queue_item *item;
+	struct cw1200_queue_stats *stats = queue->stats;
+	struct sk_buff *gc_skb = NULL;
+	struct cw1200_txpriv gc_txpriv;
+
+	cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
+			      &item_generation, &item_id);
+
+	item = &queue->pool[item_id];
+
+	spin_lock_bh(&queue->lock);
+	BUG_ON(queue_id != queue->queue_id);
+	if (queue_generation != queue->generation) {
+		ret = -ENOENT;
+	} else if (item_id >= (unsigned) queue->capacity) {
+		WARN_ON(1);
+		ret = -EINVAL;
+	} else if (item->generation != item_generation) {
+		WARN_ON(1);
+		ret = -ENOENT;
+	} else {
+		gc_txpriv = item->txpriv;
+		gc_skb = item->skb;
+		item->skb = NULL;
+		--queue->num_pending;
+		--queue->num_queued;
+		++queue->num_sent;
+		++item->generation;
+		/* Do not use list_move_tail here, but list_move:
+		 * try to utilize cache row.
+		 */
+		list_move(&item->head, &queue->free_pool);
+
+		if (queue->overfull &&
+		    (queue->num_queued <= (queue->capacity >> 1))) {
+			queue->overfull = false;
+			__cw1200_queue_unlock(queue);
+		}
+	}
+	spin_unlock_bh(&queue->lock);
+
+	if (gc_skb)
+		stats->skb_dtor(stats->priv, gc_skb, &gc_txpriv);
+
+	return ret;
+}
+
+int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
+			 struct sk_buff **skb,
+			 const struct cw1200_txpriv **txpriv)
+{
+	int ret = 0;
+	u8 queue_generation, queue_id, item_generation, item_id;
+	struct cw1200_queue_item *item;
+	cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
+			      &item_generation, &item_id);
+
+	item = &queue->pool[item_id];
+
+	spin_lock_bh(&queue->lock);
+	BUG_ON(queue_id != queue->queue_id);
+	if (queue_generation != queue->generation) {
+		ret = -ENOENT;
+	} else if (item_id >= (unsigned) queue->capacity) {
+		WARN_ON(1);
+		ret = -EINVAL;
+	} else if (item->generation != item_generation) {
+		WARN_ON(1);
+		ret = -ENOENT;
+	} else {
+		*skb = item->skb;
+		*txpriv = &item->txpriv;
+	}
+	spin_unlock_bh(&queue->lock);
+	return ret;
+}
+
+void cw1200_queue_lock(struct cw1200_queue *queue)
+{
+	spin_lock_bh(&queue->lock);
+	__cw1200_queue_lock(queue);
+	spin_unlock_bh(&queue->lock);
+}
+
+void cw1200_queue_unlock(struct cw1200_queue *queue)
+{
+	spin_lock_bh(&queue->lock);
+	__cw1200_queue_unlock(queue);
+	spin_unlock_bh(&queue->lock);
+}
+
+bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
+				     unsigned long *timestamp,
+				     u32 pending_frame_id)
+{
+	struct cw1200_queue_item *item;
+	bool ret;
+
+	spin_lock_bh(&queue->lock);
+	ret = !list_empty(&queue->pending);
+	if (ret) {
+		list_for_each_entry(item, &queue->pending, head) {
+			if (item->packet_id != pending_frame_id)
+				if (time_before(item->xmit_timestamp,
+						*timestamp))
+					*timestamp = item->xmit_timestamp;
+		}
+	}
+	spin_unlock_bh(&queue->lock);
+	return ret;
+}
+
+bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
+				 u32 link_id_map)
+{
+	bool empty = true;
+
+	spin_lock_bh(&stats->lock);
+	if (link_id_map == (u32)-1) {
+		empty = stats->num_queued == 0;
+	} else {
+		int i;
+		for (i = 0; i < stats->map_capacity; ++i) {
+			if (link_id_map & BIT(i)) {
+				if (stats->link_map_cache[i]) {
+					empty = false;
+					break;
+				}
+			}
+		}
+	}
+	spin_unlock_bh(&stats->lock);
+
+	return empty;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/queue.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/queue.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/queue.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/queue.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef CW1200_QUEUE_H_INCLUDED
+#define CW1200_QUEUE_H_INCLUDED
+
+/* private */ struct cw1200_queue_item;
+
+/* extern */ struct sk_buff;
+/* extern */ struct wsm_tx;
+/* extern */ struct cw1200_common;
+/* extern */ struct ieee80211_tx_queue_stats;
+/* extern */ struct cw1200_txpriv;
+
+/* forward */ struct cw1200_queue_stats;
+
+typedef void (*cw1200_queue_skb_dtor_t)(struct cw1200_common *priv,
+					struct sk_buff *skb,
+					const struct cw1200_txpriv *txpriv);
+
+struct cw1200_queue {
+	struct cw1200_queue_stats *stats;
+	size_t			capacity;
+	size_t			num_queued;
+	size_t			num_pending;
+	size_t			num_sent;
+	struct cw1200_queue_item *pool;
+	struct list_head	queue;
+	struct list_head	free_pool;
+	struct list_head	pending;
+	int			tx_locked_cnt;
+	int			*link_map_cache;
+	bool			overfull;
+	spinlock_t		lock; /* Protect queue entry */
+	u8			queue_id;
+	u8			generation;
+	struct timer_list	gc;
+	unsigned long		ttl;
+};
+
+struct cw1200_queue_stats {
+	spinlock_t		lock; /* Protect stats entry */
+	int			*link_map_cache;
+	int			num_queued;
+	size_t			map_capacity;
+	wait_queue_head_t	wait_link_id_empty;
+	cw1200_queue_skb_dtor_t	skb_dtor;
+	struct cw1200_common	*priv;
+};
+
+struct cw1200_txpriv {
+	u8 link_id;
+	u8 raw_link_id;
+	u8 tid;
+	u8 rate_id;
+	u8 offset;
+};
+
+int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
+			    size_t map_capacity,
+			    cw1200_queue_skb_dtor_t skb_dtor,
+			    struct cw1200_common *priv);
+int cw1200_queue_init(struct cw1200_queue *queue,
+		      struct cw1200_queue_stats *stats,
+		      u8 queue_id,
+		      size_t capacity,
+		      unsigned long ttl);
+int cw1200_queue_clear(struct cw1200_queue *queue);
+void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats);
+void cw1200_queue_deinit(struct cw1200_queue *queue);
+
+size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
+				   u32 link_id_map);
+int cw1200_queue_put(struct cw1200_queue *queue,
+		     struct sk_buff *skb,
+		     struct cw1200_txpriv *txpriv);
+int cw1200_queue_get(struct cw1200_queue *queue,
+		     u32 link_id_map,
+		     struct wsm_tx **tx,
+		     struct ieee80211_tx_info **tx_info,
+		     const struct cw1200_txpriv **txpriv);
+int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id);
+int cw1200_queue_requeue_all(struct cw1200_queue *queue);
+int cw1200_queue_remove(struct cw1200_queue *queue,
+			u32 packet_id);
+int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
+			 struct sk_buff **skb,
+			 const struct cw1200_txpriv **txpriv);
+void cw1200_queue_lock(struct cw1200_queue *queue);
+void cw1200_queue_unlock(struct cw1200_queue *queue);
+bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
+				     unsigned long *timestamp,
+				     u32 pending_frame_id);
+
+bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
+				 u32 link_id_map);
+
+static inline u8 cw1200_queue_get_queue_id(u32 packet_id)
+{
+	return (packet_id >> 16) & 0xFF;
+}
+
+static inline u8 cw1200_queue_get_generation(u32 packet_id)
+{
+	return (packet_id >>  8) & 0xFF;
+}
+
+#endif /* CW1200_QUEUE_H_INCLUDED */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/scan.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/scan.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/scan.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/scan.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,461 @@
+/*
+ * Scan implementation for ST-Ericsson CW1200 mac80211 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/sched.h>
+#include "cw1200.h"
+#include "scan.h"
+#include "sta.h"
+#include "pm.h"
+
+static void cw1200_scan_restart_delayed(struct cw1200_common *priv);
+
+static int cw1200_scan_start(struct cw1200_common *priv, struct wsm_scan *scan)
+{
+	int ret, i;
+	int tmo = 2000;
+
+	switch (priv->join_status) {
+	case CW1200_JOIN_STATUS_PRE_STA:
+	case CW1200_JOIN_STATUS_JOINING:
+		return -EBUSY;
+	default:
+		break;
+	}
+
+	wiphy_dbg(priv->hw->wiphy, "[SCAN] hw req, type %d, %d channels, flags: 0x%x.\n",
+		  scan->type, scan->num_channels, scan->flags);
+
+	for (i = 0; i < scan->num_channels; ++i)
+		tmo += scan->ch[i].max_chan_time + 10;
+
+	cancel_delayed_work_sync(&priv->clear_recent_scan_work);
+	atomic_set(&priv->scan.in_progress, 1);
+	atomic_set(&priv->recent_scan, 1);
+	cw1200_pm_stay_awake(&priv->pm_state, tmo * HZ / 1000);
+	queue_delayed_work(priv->workqueue, &priv->scan.timeout,
+			   tmo * HZ / 1000);
+	ret = wsm_scan(priv, scan);
+	if (ret) {
+		atomic_set(&priv->scan.in_progress, 0);
+		cancel_delayed_work_sync(&priv->scan.timeout);
+		cw1200_scan_restart_delayed(priv);
+	}
+	return ret;
+}
+
+int cw1200_hw_scan(struct ieee80211_hw *hw,
+		   struct ieee80211_vif *vif,
+		   struct cfg80211_scan_request *req)
+{
+	struct cw1200_common *priv = hw->priv;
+	struct wsm_template_frame frame = {
+		.frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
+	};
+	int i, ret;
+
+	if (!priv->vif)
+		return -EINVAL;
+
+	/* Scan when P2P_GO corrupt firmware MiniAP mode */
+	if (priv->join_status == CW1200_JOIN_STATUS_AP)
+		return -EOPNOTSUPP;
+
+	if (req->n_ssids == 1 && !req->ssids[0].ssid_len)
+		req->n_ssids = 0;
+
+	wiphy_dbg(hw->wiphy, "[SCAN] Scan request for %d SSIDs.\n",
+		  req->n_ssids);
+
+	if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
+		return -EINVAL;
+
+	frame.skb = ieee80211_probereq_get(hw, priv->vif, NULL, 0,
+		req->ie_len);
+	if (!frame.skb)
+		return -ENOMEM;
+
+	if (req->ie_len)
+		memcpy(skb_put(frame.skb, req->ie_len), req->ie, req->ie_len);
+
+	/* will be unlocked in cw1200_scan_work() */
+	down(&priv->scan.lock);
+	mutex_lock(&priv->conf_mutex);
+
+	ret = wsm_set_template_frame(priv, &frame);
+	if (!ret) {
+		/* Host want to be the probe responder. */
+		ret = wsm_set_probe_responder(priv, true);
+	}
+	if (ret) {
+		mutex_unlock(&priv->conf_mutex);
+		up(&priv->scan.lock);
+		dev_kfree_skb(frame.skb);
+		return ret;
+	}
+
+	wsm_lock_tx(priv);
+
+	BUG_ON(priv->scan.req);
+	priv->scan.req = req;
+	priv->scan.n_ssids = 0;
+	priv->scan.status = 0;
+	priv->scan.begin = &req->channels[0];
+	priv->scan.curr = priv->scan.begin;
+	priv->scan.end = &req->channels[req->n_channels];
+	priv->scan.output_power = priv->output_power;
+
+	for (i = 0; i < req->n_ssids; ++i) {
+		struct wsm_ssid *dst = &priv->scan.ssids[priv->scan.n_ssids];
+		memcpy(&dst->ssid[0], req->ssids[i].ssid, sizeof(dst->ssid));
+		dst->length = req->ssids[i].ssid_len;
+		++priv->scan.n_ssids;
+	}
+
+	mutex_unlock(&priv->conf_mutex);
+
+	if (frame.skb)
+		dev_kfree_skb(frame.skb);
+	queue_work(priv->workqueue, &priv->scan.work);
+	return 0;
+}
+
+void cw1200_scan_work(struct work_struct *work)
+{
+	struct cw1200_common *priv = container_of(work, struct cw1200_common,
+							scan.work);
+	struct ieee80211_channel **it;
+	struct wsm_scan scan = {
+		.type = WSM_SCAN_TYPE_FOREGROUND,
+		.flags = WSM_SCAN_FLAG_SPLIT_METHOD,
+	};
+	bool first_run = (priv->scan.begin == priv->scan.curr &&
+			  priv->scan.begin != priv->scan.end);
+	int i;
+
+	if (first_run) {
+		/* Firmware gets crazy if scan request is sent
+		 * when STA is joined but not yet associated.
+		 * Force unjoin in this case.
+		 */
+		if (cancel_delayed_work_sync(&priv->join_timeout) > 0)
+			cw1200_join_timeout(&priv->join_timeout.work);
+	}
+
+	mutex_lock(&priv->conf_mutex);
+
+	if (first_run) {
+		if (priv->join_status == CW1200_JOIN_STATUS_STA &&
+		    !(priv->powersave_mode.mode & WSM_PSM_PS)) {
+			struct wsm_set_pm pm = priv->powersave_mode;
+			pm.mode = WSM_PSM_PS;
+			cw1200_set_pm(priv, &pm);
+		} else if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
+			/* FW bug: driver has to restart p2p-dev mode
+			 * after scan
+			 */
+			cw1200_disable_listening(priv);
+		}
+	}
+
+	if (!priv->scan.req || (priv->scan.curr == priv->scan.end)) {
+		if (priv->scan.output_power != priv->output_power)
+			wsm_set_output_power(priv, priv->output_power * 10);
+		if (priv->join_status == CW1200_JOIN_STATUS_STA &&
+		    !(priv->powersave_mode.mode & WSM_PSM_PS))
+			cw1200_set_pm(priv, &priv->powersave_mode);
+
+		if (priv->scan.status < 0)
+			wiphy_dbg(priv->hw->wiphy, "[SCAN] Scan failed (%d).\n",
+				  priv->scan.status);
+		else if (priv->scan.req)
+			wiphy_dbg(priv->hw->wiphy,
+				  "[SCAN] Scan completed.\n");
+		else
+			wiphy_dbg(priv->hw->wiphy,
+				  "[SCAN] Scan canceled.\n");
+
+		priv->scan.req = NULL;
+		cw1200_scan_restart_delayed(priv);
+		wsm_unlock_tx(priv);
+		mutex_unlock(&priv->conf_mutex);
+		ieee80211_scan_completed(priv->hw, priv->scan.status ? 1 : 0);
+		up(&priv->scan.lock);
+		return;
+	} else {
+		struct ieee80211_channel *first = *priv->scan.curr;
+		for (it = priv->scan.curr + 1, i = 1;
+		     it != priv->scan.end && i < WSM_SCAN_MAX_NUM_OF_CHANNELS;
+		     ++it, ++i) {
+			if ((*it)->band != first->band)
+				break;
+			if (((*it)->flags ^ first->flags) &
+					IEEE80211_CHAN_PASSIVE_SCAN)
+				break;
+			if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
+			    (*it)->max_power != first->max_power)
+				break;
+		}
+		scan.band = first->band;
+
+		if (priv->scan.req->no_cck)
+			scan.max_tx_rate = WSM_TRANSMIT_RATE_6;
+		else
+			scan.max_tx_rate = WSM_TRANSMIT_RATE_1;
+		scan.num_probes =
+			(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2;
+		scan.num_ssids = priv->scan.n_ssids;
+		scan.ssids = &priv->scan.ssids[0];
+		scan.num_channels = it - priv->scan.curr;
+		/* TODO: Is it optimal? */
+		scan.probe_delay = 100;
+		/* It is not stated in WSM specification, however
+		 * FW team says that driver may not use FG scan
+		 * when joined.
+		 */
+		if (priv->join_status == CW1200_JOIN_STATUS_STA) {
+			scan.type = WSM_SCAN_TYPE_BACKGROUND;
+			scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
+		}
+		scan.ch = kzalloc(
+			sizeof(struct wsm_scan_ch) * (it - priv->scan.curr),
+			GFP_KERNEL);
+		if (!scan.ch) {
+			priv->scan.status = -ENOMEM;
+			goto fail;
+		}
+		for (i = 0; i < scan.num_channels; ++i) {
+			scan.ch[i].number = priv->scan.curr[i]->hw_value;
+			if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
+				scan.ch[i].min_chan_time = 50;
+				scan.ch[i].max_chan_time = 100;
+			} else {
+				scan.ch[i].min_chan_time = 10;
+				scan.ch[i].max_chan_time = 25;
+			}
+		}
+		if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
+		    priv->scan.output_power != first->max_power) {
+			priv->scan.output_power = first->max_power;
+			wsm_set_output_power(priv,
+					     priv->scan.output_power * 10);
+		}
+		priv->scan.status = cw1200_scan_start(priv, &scan);
+		kfree(scan.ch);
+		if (priv->scan.status)
+			goto fail;
+		priv->scan.curr = it;
+	}
+	mutex_unlock(&priv->conf_mutex);
+	return;
+
+fail:
+	priv->scan.curr = priv->scan.end;
+	mutex_unlock(&priv->conf_mutex);
+	queue_work(priv->workqueue, &priv->scan.work);
+	return;
+}
+
+static void cw1200_scan_restart_delayed(struct cw1200_common *priv)
+{
+	/* FW bug: driver has to restart p2p-dev mode after scan. */
+	if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
+		cw1200_enable_listening(priv);
+		cw1200_update_filtering(priv);
+	}
+
+	if (priv->delayed_unjoin) {
+		priv->delayed_unjoin = false;
+		if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
+			wsm_unlock_tx(priv);
+	} else if (priv->delayed_link_loss) {
+			wiphy_dbg(priv->hw->wiphy, "[CQM] Requeue BSS loss.\n");
+			priv->delayed_link_loss = 0;
+			cw1200_cqm_bssloss_sm(priv, 1, 0, 0);
+	}
+}
+
+static void cw1200_scan_complete(struct cw1200_common *priv)
+{
+	queue_delayed_work(priv->workqueue, &priv->clear_recent_scan_work, HZ);
+	if (priv->scan.direct_probe) {
+		wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe complete.\n");
+		cw1200_scan_restart_delayed(priv);
+		priv->scan.direct_probe = 0;
+		up(&priv->scan.lock);
+		wsm_unlock_tx(priv);
+	} else {
+		cw1200_scan_work(&priv->scan.work);
+	}
+}
+
+void cw1200_scan_failed_cb(struct cw1200_common *priv)
+{
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+		/* STA is stopped. */
+		return;
+
+	if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) {
+		priv->scan.status = -EIO;
+		queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0);
+	}
+}
+
+
+void cw1200_scan_complete_cb(struct cw1200_common *priv,
+				struct wsm_scan_complete *arg)
+{
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+		/* STA is stopped. */
+		return;
+
+	if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) {
+		priv->scan.status = 1;
+		queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0);
+	}
+}
+
+void cw1200_clear_recent_scan_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common,
+			     clear_recent_scan_work.work);
+	atomic_xchg(&priv->recent_scan, 0);
+}
+
+void cw1200_scan_timeout(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, scan.timeout.work);
+	if (atomic_xchg(&priv->scan.in_progress, 0)) {
+		if (priv->scan.status > 0) {
+			priv->scan.status = 0;
+		} else if (!priv->scan.status) {
+			wiphy_warn(priv->hw->wiphy,
+				   "Timeout waiting for scan complete notification.\n");
+			priv->scan.status = -ETIMEDOUT;
+			priv->scan.curr = priv->scan.end;
+			wsm_stop_scan(priv);
+		}
+		cw1200_scan_complete(priv);
+	}
+}
+
+void cw1200_probe_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, scan.probe_work.work);
+	u8 queue_id = cw1200_queue_get_queue_id(priv->pending_frame_id);
+	struct cw1200_queue *queue = &priv->tx_queue[queue_id];
+	const struct cw1200_txpriv *txpriv;
+	struct wsm_tx *wsm;
+	struct wsm_template_frame frame = {
+		.frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
+	};
+	struct wsm_ssid ssids[1] = {{
+		.length = 0,
+	} };
+	struct wsm_scan_ch ch[1] = {{
+		.min_chan_time = 0,
+		.max_chan_time = 10,
+	} };
+	struct wsm_scan scan = {
+		.type = WSM_SCAN_TYPE_FOREGROUND,
+		.num_probes = 1,
+		.probe_delay = 0,
+		.num_channels = 1,
+		.ssids = ssids,
+		.ch = ch,
+	};
+	u8 *ies;
+	size_t ies_len;
+	int ret;
+
+	wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe work.\n");
+
+	mutex_lock(&priv->conf_mutex);
+	if (down_trylock(&priv->scan.lock)) {
+		/* Scan is already in progress. Requeue self. */
+		schedule();
+		queue_delayed_work(priv->workqueue,
+				   &priv->scan.probe_work, HZ / 10);
+		mutex_unlock(&priv->conf_mutex);
+		return;
+	}
+
+	/* Make sure we still have a pending probe req */
+	if (cw1200_queue_get_skb(queue,	priv->pending_frame_id,
+				 &frame.skb, &txpriv)) {
+		up(&priv->scan.lock);
+		mutex_unlock(&priv->conf_mutex);
+		wsm_unlock_tx(priv);
+		return;
+	}
+	wsm = (struct wsm_tx *)frame.skb->data;
+	scan.max_tx_rate = wsm->max_tx_rate;
+	scan.band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
+		WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
+	if (priv->join_status == CW1200_JOIN_STATUS_STA ||
+	    priv->join_status == CW1200_JOIN_STATUS_IBSS) {
+		scan.type = WSM_SCAN_TYPE_BACKGROUND;
+		scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
+	}
+	ch[0].number = priv->channel->hw_value;
+
+	skb_pull(frame.skb, txpriv->offset);
+
+	ies = &frame.skb->data[sizeof(struct ieee80211_hdr_3addr)];
+	ies_len = frame.skb->len - sizeof(struct ieee80211_hdr_3addr);
+
+	if (ies_len) {
+		u8 *ssidie =
+			(u8 *)cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len);
+		if (ssidie && ssidie[1] && ssidie[1] <= sizeof(ssids[0].ssid)) {
+			u8 *nextie = &ssidie[2 + ssidie[1]];
+			/* Remove SSID from the IE list. It has to be provided
+			 * as a separate argument in cw1200_scan_start call
+			 */
+
+			/* Store SSID localy */
+			ssids[0].length = ssidie[1];
+			memcpy(ssids[0].ssid, &ssidie[2], ssids[0].length);
+			scan.num_ssids = 1;
+
+			/* Remove SSID from IE list */
+			ssidie[1] = 0;
+			memmove(&ssidie[2], nextie, &ies[ies_len] - nextie);
+			skb_trim(frame.skb, frame.skb->len - ssids[0].length);
+		}
+	}
+
+	/* FW bug: driver has to restart p2p-dev mode after scan */
+	if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
+		cw1200_disable_listening(priv);
+	ret = wsm_set_template_frame(priv, &frame);
+	priv->scan.direct_probe = 1;
+	if (!ret) {
+		wsm_flush_tx(priv);
+		ret = cw1200_scan_start(priv, &scan);
+	}
+	mutex_unlock(&priv->conf_mutex);
+
+	skb_push(frame.skb, txpriv->offset);
+	if (!ret)
+		IEEE80211_SKB_CB(frame.skb)->flags |= IEEE80211_TX_STAT_ACK;
+	BUG_ON(cw1200_queue_remove(queue, priv->pending_frame_id));
+
+	if (ret) {
+		priv->scan.direct_probe = 0;
+		up(&priv->scan.lock);
+		wsm_unlock_tx(priv);
+	}
+
+	return;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/scan.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/scan.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/scan.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/scan.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,56 @@
+/*
+ * Scan interface for ST-Ericsson CW1200 mac80211 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef SCAN_H_INCLUDED
+#define SCAN_H_INCLUDED
+
+#include <linux/semaphore.h>
+#include "wsm.h"
+
+/* external */ struct sk_buff;
+/* external */ struct cfg80211_scan_request;
+/* external */ struct ieee80211_channel;
+/* external */ struct ieee80211_hw;
+/* external */ struct work_struct;
+
+struct cw1200_scan {
+	struct semaphore lock;
+	struct work_struct work;
+	struct delayed_work timeout;
+	struct cfg80211_scan_request *req;
+	struct ieee80211_channel **begin;
+	struct ieee80211_channel **curr;
+	struct ieee80211_channel **end;
+	struct wsm_ssid ssids[WSM_SCAN_MAX_NUM_OF_SSIDS];
+	int output_power;
+	int n_ssids;
+	int status;
+	atomic_t in_progress;
+	/* Direct probe requests workaround */
+	struct delayed_work probe_work;
+	int direct_probe;
+};
+
+int cw1200_hw_scan(struct ieee80211_hw *hw,
+		   struct ieee80211_vif *vif,
+		   struct cfg80211_scan_request *req);
+void cw1200_scan_work(struct work_struct *work);
+void cw1200_scan_timeout(struct work_struct *work);
+void cw1200_clear_recent_scan_work(struct work_struct *work);
+void cw1200_scan_complete_cb(struct cw1200_common *priv,
+			     struct wsm_scan_complete *arg);
+void cw1200_scan_failed_cb(struct cw1200_common *priv);
+
+/* ******************************************************************** */
+/* Raw probe requests TX workaround					*/
+void cw1200_probe_work(struct work_struct *work);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/sta.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/sta.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/sta.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/sta.c	2013-08-31 17:59:31.000000000 -0400
@@ -0,0 +1,2400 @@
+/*
+ * Mac80211 STA API for ST-Ericsson CW1200 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/sched.h>
+#include <linux/firmware.h>
+#include <linux/module.h>
+
+#include "cw1200.h"
+#include "sta.h"
+#include "fwio.h"
+#include "bh.h"
+#include "debug.h"
+
+#ifndef ERP_INFO_BYTE_OFFSET
+#define ERP_INFO_BYTE_OFFSET 2
+#endif
+
+static void cw1200_do_join(struct cw1200_common *priv);
+static void cw1200_do_unjoin(struct cw1200_common *priv);
+
+static int cw1200_upload_beacon(struct cw1200_common *priv);
+static int cw1200_upload_pspoll(struct cw1200_common *priv);
+static int cw1200_upload_null(struct cw1200_common *priv);
+static int cw1200_upload_qosnull(struct cw1200_common *priv);
+static int cw1200_start_ap(struct cw1200_common *priv);
+static int cw1200_update_beaconing(struct cw1200_common *priv);
+static int cw1200_enable_beaconing(struct cw1200_common *priv,
+				   bool enable);
+static void __cw1200_sta_notify(struct ieee80211_hw *dev,
+				struct ieee80211_vif *vif,
+				enum sta_notify_cmd notify_cmd,
+				int link_id);
+static int __cw1200_flush(struct cw1200_common *priv, bool drop);
+
+static inline void __cw1200_free_event_queue(struct list_head *list)
+{
+	struct cw1200_wsm_event *event, *tmp;
+	list_for_each_entry_safe(event, tmp, list, link) {
+		list_del(&event->link);
+		kfree(event);
+	}
+}
+
+/* ******************************************************************** */
+/* STA API								*/
+
+int cw1200_start(struct ieee80211_hw *dev)
+{
+	struct cw1200_common *priv = dev->priv;
+	int ret = 0;
+
+	cw1200_pm_stay_awake(&priv->pm_state, HZ);
+
+	mutex_lock(&priv->conf_mutex);
+
+	/* default EDCA */
+	WSM_EDCA_SET(&priv->edca, 0, 0x0002, 0x0003, 0x0007, 47, 0xc8, false);
+	WSM_EDCA_SET(&priv->edca, 1, 0x0002, 0x0007, 0x000f, 94, 0xc8, false);
+	WSM_EDCA_SET(&priv->edca, 2, 0x0003, 0x000f, 0x03ff, 0, 0xc8, false);
+	WSM_EDCA_SET(&priv->edca, 3, 0x0007, 0x000f, 0x03ff, 0, 0xc8, false);
+	ret = wsm_set_edca_params(priv, &priv->edca);
+	if (ret)
+		goto out;
+
+	ret = cw1200_set_uapsd_param(priv, &priv->edca);
+	if (ret)
+		goto out;
+
+	priv->setbssparams_done = false;
+
+	memcpy(priv->mac_addr, dev->wiphy->perm_addr, ETH_ALEN);
+	priv->mode = NL80211_IFTYPE_MONITOR;
+	priv->wep_default_key_id = -1;
+
+	priv->cqm_beacon_loss_count = 10;
+
+	ret = cw1200_setup_mac(priv);
+	if (ret)
+		goto out;
+
+out:
+	mutex_unlock(&priv->conf_mutex);
+	return ret;
+}
+
+void cw1200_stop(struct ieee80211_hw *dev)
+{
+	struct cw1200_common *priv = dev->priv;
+	LIST_HEAD(list);
+	int i;
+
+	wsm_lock_tx(priv);
+
+	while (down_trylock(&priv->scan.lock)) {
+		/* Scan is in progress. Force it to stop. */
+		priv->scan.req = NULL;
+		schedule();
+	}
+	up(&priv->scan.lock);
+
+	cancel_delayed_work_sync(&priv->scan.probe_work);
+	cancel_delayed_work_sync(&priv->scan.timeout);
+	cancel_delayed_work_sync(&priv->clear_recent_scan_work);
+	cancel_delayed_work_sync(&priv->join_timeout);
+	cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
+	cancel_work_sync(&priv->unjoin_work);
+	cancel_delayed_work_sync(&priv->link_id_gc_work);
+	flush_workqueue(priv->workqueue);
+	del_timer_sync(&priv->mcast_timeout);
+	mutex_lock(&priv->conf_mutex);
+	priv->mode = NL80211_IFTYPE_UNSPECIFIED;
+	priv->listening = false;
+
+	spin_lock(&priv->event_queue_lock);
+	list_splice_init(&priv->event_queue, &list);
+	spin_unlock(&priv->event_queue_lock);
+	__cw1200_free_event_queue(&list);
+
+
+	priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
+	priv->join_pending = false;
+
+	for (i = 0; i < 4; i++)
+		cw1200_queue_clear(&priv->tx_queue[i]);
+	mutex_unlock(&priv->conf_mutex);
+	tx_policy_clean(priv);
+
+	/* HACK! */
+	if (atomic_xchg(&priv->tx_lock, 1) != 1)
+		pr_debug("[STA] TX is force-unlocked due to stop request.\n");
+
+	wsm_unlock_tx(priv);
+	atomic_xchg(&priv->tx_lock, 0); /* for recovery to work */
+}
+
+static int cw1200_bssloss_mitigation = 1;
+module_param(cw1200_bssloss_mitigation, int, 0644);
+MODULE_PARM_DESC(cw1200_bssloss_mitigation, "BSS Loss mitigation. 0 == disabled, 1 == enabled (default)");
+
+
+void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
+			     int init, int good, int bad)
+{
+	int tx = 0;
+
+	priv->delayed_link_loss = 0;
+	cancel_work_sync(&priv->bss_params_work);
+
+	pr_debug("[STA] CQM BSSLOSS_SM: state: %d init %d good %d bad: %d txlock: %d uj: %d\n",
+		 priv->bss_loss_state,
+		 init, good, bad,
+		 atomic_read(&priv->tx_lock),
+		 priv->delayed_unjoin);
+
+	/* If we have a pending unjoin */
+	if (priv->delayed_unjoin)
+		return;
+
+	if (init) {
+		queue_delayed_work(priv->workqueue,
+				   &priv->bss_loss_work,
+				   HZ);
+		priv->bss_loss_state = 0;
+
+		/* Skip the confimration procedure in P2P case */
+		if (!priv->vif->p2p && !atomic_read(&priv->tx_lock))
+			tx = 1;
+	} else if (good) {
+		cancel_delayed_work_sync(&priv->bss_loss_work);
+		priv->bss_loss_state = 0;
+		queue_work(priv->workqueue, &priv->bss_params_work);
+	} else if (bad) {
+		/* XXX Should we just keep going until we time out? */
+		if (priv->bss_loss_state < 3)
+			tx = 1;
+	} else {
+		cancel_delayed_work_sync(&priv->bss_loss_work);
+		priv->bss_loss_state = 0;
+	}
+
+	/* Bypass mitigation if it's disabled */
+	if (!cw1200_bssloss_mitigation)
+		tx = 0;
+
+	/* Spit out a NULL packet to our AP if necessary */
+	if (tx) {
+		struct sk_buff *skb;
+
+		priv->bss_loss_state++;
+
+		skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
+		WARN_ON(!skb);
+		if (skb)
+			cw1200_tx(priv->hw, NULL, skb);
+	}
+}
+
+int cw1200_add_interface(struct ieee80211_hw *dev,
+			 struct ieee80211_vif *vif)
+{
+	int ret;
+	struct cw1200_common *priv = dev->priv;
+	/* __le32 auto_calibration_mode = __cpu_to_le32(1); */
+
+	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
+			     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
+
+	mutex_lock(&priv->conf_mutex);
+
+	if (priv->mode != NL80211_IFTYPE_MONITOR) {
+		mutex_unlock(&priv->conf_mutex);
+		return -EOPNOTSUPP;
+	}
+
+	switch (vif->type) {
+	case NL80211_IFTYPE_STATION:
+	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_MESH_POINT:
+	case NL80211_IFTYPE_AP:
+		priv->mode = vif->type;
+		break;
+	default:
+		mutex_unlock(&priv->conf_mutex);
+		return -EOPNOTSUPP;
+	}
+
+	priv->vif = vif;
+	memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
+	ret = cw1200_setup_mac(priv);
+	/* Enable auto-calibration */
+	/* Exception in subsequent channel switch; disabled.
+	 *  wsm_write_mib(priv, WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE,
+	 *      &auto_calibration_mode, sizeof(auto_calibration_mode));
+	*/
+
+	mutex_unlock(&priv->conf_mutex);
+	return ret;
+}
+
+void cw1200_remove_interface(struct ieee80211_hw *dev,
+			     struct ieee80211_vif *vif)
+{
+	struct cw1200_common *priv = dev->priv;
+	struct wsm_reset reset = {
+		.reset_statistics = true,
+	};
+	int i;
+
+	mutex_lock(&priv->conf_mutex);
+	switch (priv->join_status) {
+	case CW1200_JOIN_STATUS_JOINING:
+	case CW1200_JOIN_STATUS_PRE_STA:
+	case CW1200_JOIN_STATUS_STA:
+	case CW1200_JOIN_STATUS_IBSS:
+		wsm_lock_tx(priv);
+		if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
+			wsm_unlock_tx(priv);
+		break;
+	case CW1200_JOIN_STATUS_AP:
+		for (i = 0; priv->link_id_map; ++i) {
+			if (priv->link_id_map & BIT(i)) {
+				reset.link_id = i;
+				wsm_reset(priv, &reset);
+				priv->link_id_map &= ~BIT(i);
+			}
+		}
+		memset(priv->link_id_db, 0, sizeof(priv->link_id_db));
+		priv->sta_asleep_mask = 0;
+		priv->enable_beacon = false;
+		priv->tx_multicast = false;
+		priv->aid0_bit_set = false;
+		priv->buffered_multicasts = false;
+		priv->pspoll_mask = 0;
+		reset.link_id = 0;
+		wsm_reset(priv, &reset);
+		break;
+	case CW1200_JOIN_STATUS_MONITOR:
+		cw1200_update_listening(priv, false);
+		break;
+	default:
+		break;
+	}
+	priv->vif = NULL;
+	priv->mode = NL80211_IFTYPE_MONITOR;
+	memset(priv->mac_addr, 0, ETH_ALEN);
+	memset(&priv->p2p_ps_modeinfo, 0, sizeof(priv->p2p_ps_modeinfo));
+	cw1200_free_keys(priv);
+	cw1200_setup_mac(priv);
+	priv->listening = false;
+	priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
+	if (!__cw1200_flush(priv, true))
+		wsm_unlock_tx(priv);
+
+	mutex_unlock(&priv->conf_mutex);
+}
+
+int cw1200_change_interface(struct ieee80211_hw *dev,
+			    struct ieee80211_vif *vif,
+			    enum nl80211_iftype new_type,
+			    bool p2p)
+{
+	int ret = 0;
+	pr_debug("change_interface new: %d (%d), old: %d (%d)\n", new_type,
+		 p2p, vif->type, vif->p2p);
+
+	if (new_type != vif->type || vif->p2p != p2p) {
+		cw1200_remove_interface(dev, vif);
+		vif->type = new_type;
+		vif->p2p = p2p;
+		ret = cw1200_add_interface(dev, vif);
+	}
+
+	return ret;
+}
+
+int cw1200_config(struct ieee80211_hw *dev, u32 changed)
+{
+	int ret = 0;
+	struct cw1200_common *priv = dev->priv;
+	struct ieee80211_conf *conf = &dev->conf;
+
+	pr_debug("CONFIG CHANGED:  %08x\n", changed);
+
+	down(&priv->scan.lock);
+	mutex_lock(&priv->conf_mutex);
+	/* TODO: IEEE80211_CONF_CHANGE_QOS */
+	/* TODO: IEEE80211_CONF_CHANGE_LISTEN_INTERVAL */
+
+	if (changed & IEEE80211_CONF_CHANGE_POWER) {
+		priv->output_power = conf->power_level;
+		pr_debug("[STA] TX power: %d\n", priv->output_power);
+		wsm_set_output_power(priv, priv->output_power * 10);
+	}
+
+	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) &&
+	    (priv->channel != conf->chandef.chan)) {
+		struct ieee80211_channel *ch = conf->chandef.chan;
+		struct wsm_switch_channel channel = {
+			.channel_number = ch->hw_value,
+		};
+		pr_debug("[STA] Freq %d (wsm ch: %d).\n",
+			 ch->center_freq, ch->hw_value);
+
+		/* __cw1200_flush() implicitly locks tx, if successful */
+		if (!__cw1200_flush(priv, false)) {
+			if (!wsm_switch_channel(priv, &channel)) {
+				ret = wait_event_timeout(priv->channel_switch_done,
+							 !priv->channel_switch_in_progress,
+							 3 * HZ);
+				if (ret) {
+					/* Already unlocks if successful */
+					priv->channel = ch;
+					ret = 0;
+				} else {
+					ret = -ETIMEDOUT;
+				}
+			} else {
+				/* Unlock if switch channel fails */
+				wsm_unlock_tx(priv);
+			}
+		}
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		if (!(conf->flags & IEEE80211_CONF_PS))
+			priv->powersave_mode.mode = WSM_PSM_ACTIVE;
+		else if (conf->dynamic_ps_timeout <= 0)
+			priv->powersave_mode.mode = WSM_PSM_PS;
+		else
+			priv->powersave_mode.mode = WSM_PSM_FAST_PS;
+
+		/* Firmware requires that value for this 1-byte field must
+		 * be specified in units of 500us. Values above the 128ms
+		 * threshold are not supported.
+		 */
+		if (conf->dynamic_ps_timeout >= 0x80)
+			priv->powersave_mode.fast_psm_idle_period = 0xFF;
+		else
+			priv->powersave_mode.fast_psm_idle_period =
+					conf->dynamic_ps_timeout << 1;
+
+		if (priv->join_status == CW1200_JOIN_STATUS_STA &&
+		    priv->bss_params.aid)
+			cw1200_set_pm(priv, &priv->powersave_mode);
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+		/* TBD: It looks like it's transparent
+		 * there's a monitor interface present -- use this
+		 * to determine for example whether to calculate
+		 * timestamps for packets or not, do not use instead
+		 * of filter flags!
+		 */
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+		struct wsm_operational_mode mode = {
+			.power_mode = cw1200_power_mode,
+			.disable_more_flag_usage = true,
+		};
+
+		wsm_lock_tx(priv);
+		/* Disable p2p-dev mode forced by TX request */
+		if ((priv->join_status == CW1200_JOIN_STATUS_MONITOR) &&
+		    (conf->flags & IEEE80211_CONF_IDLE) &&
+		    !priv->listening) {
+			cw1200_disable_listening(priv);
+			priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
+		}
+		wsm_set_operational_mode(priv, &mode);
+		wsm_unlock_tx(priv);
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+		pr_debug("[STA] Retry limits: %d (long), %d (short).\n",
+			 conf->long_frame_max_tx_count,
+			 conf->short_frame_max_tx_count);
+		spin_lock_bh(&priv->tx_policy_cache.lock);
+		priv->long_frame_max_tx_count = conf->long_frame_max_tx_count;
+		priv->short_frame_max_tx_count =
+			(conf->short_frame_max_tx_count < 0x0F) ?
+			conf->short_frame_max_tx_count : 0x0F;
+		priv->hw->max_rate_tries = priv->short_frame_max_tx_count;
+		spin_unlock_bh(&priv->tx_policy_cache.lock);
+	}
+	mutex_unlock(&priv->conf_mutex);
+	up(&priv->scan.lock);
+	return ret;
+}
+
+void cw1200_update_filtering(struct cw1200_common *priv)
+{
+	int ret;
+	bool bssid_filtering = !priv->rx_filter.bssid;
+	bool is_p2p = priv->vif && priv->vif->p2p;
+	bool is_sta = priv->vif && NL80211_IFTYPE_STATION == priv->vif->type;
+
+	static struct wsm_beacon_filter_control bf_ctrl;
+	static struct wsm_mib_beacon_filter_table bf_tbl = {
+		.entry[0].ie_id = WLAN_EID_VENDOR_SPECIFIC,
+		.entry[0].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
+					WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
+					WSM_BEACON_FILTER_IE_HAS_APPEARED,
+		.entry[0].oui[0] = 0x50,
+		.entry[0].oui[1] = 0x6F,
+		.entry[0].oui[2] = 0x9A,
+		.entry[1].ie_id = WLAN_EID_HT_OPERATION,
+		.entry[1].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
+					WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
+					WSM_BEACON_FILTER_IE_HAS_APPEARED,
+		.entry[2].ie_id = WLAN_EID_ERP_INFO,
+		.entry[2].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
+					WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
+					WSM_BEACON_FILTER_IE_HAS_APPEARED,
+	};
+
+	if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE)
+		return;
+	else if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
+		bssid_filtering = false;
+
+	if (priv->disable_beacon_filter) {
+		bf_ctrl.enabled = 0;
+		bf_ctrl.bcn_count = 1;
+		bf_tbl.num = __cpu_to_le32(0);
+	} else if (is_p2p || !is_sta) {
+		bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE |
+			WSM_BEACON_FILTER_AUTO_ERP;
+		bf_ctrl.bcn_count = 0;
+		bf_tbl.num = __cpu_to_le32(2);
+	} else {
+		bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE;
+		bf_ctrl.bcn_count = 0;
+		bf_tbl.num = __cpu_to_le32(3);
+	}
+
+	/* When acting as p2p client being connected to p2p GO, in order to
+	 * receive frames from a different p2p device, turn off bssid filter.
+	 *
+	 * WARNING: FW dependency!
+	 * This can only be used with FW WSM371 and its successors.
+	 * In that FW version even with bssid filter turned off,
+	 * device will block most of the unwanted frames.
+	 */
+	if (is_p2p)
+		bssid_filtering = false;
+
+	ret = wsm_set_rx_filter(priv, &priv->rx_filter);
+	if (!ret)
+		ret = wsm_set_beacon_filter_table(priv, &bf_tbl);
+	if (!ret)
+		ret = wsm_beacon_filter_control(priv, &bf_ctrl);
+	if (!ret)
+		ret = wsm_set_bssid_filtering(priv, bssid_filtering);
+	if (!ret)
+		ret = wsm_set_multicast_filter(priv, &priv->multicast_filter);
+	if (ret)
+		wiphy_err(priv->hw->wiphy,
+			  "Update filtering failed: %d.\n", ret);
+	return;
+}
+
+void cw1200_update_filtering_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common,
+			     update_filtering_work);
+
+	cw1200_update_filtering(priv);
+}
+
+void cw1200_set_beacon_wakeup_period_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common,
+			     set_beacon_wakeup_period_work);
+
+	wsm_set_beacon_wakeup_period(priv,
+				     priv->beacon_int * priv->join_dtim_period >
+				     MAX_BEACON_SKIP_TIME_MS ? 1 :
+				     priv->join_dtim_period, 0);
+}
+
+u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
+			     struct netdev_hw_addr_list *mc_list)
+{
+	static u8 broadcast_ipv6[ETH_ALEN] = {
+		0x33, 0x33, 0x00, 0x00, 0x00, 0x01
+	};
+	static u8 broadcast_ipv4[ETH_ALEN] = {
+		0x01, 0x00, 0x5e, 0x00, 0x00, 0x01
+	};
+	struct cw1200_common *priv = hw->priv;
+	struct netdev_hw_addr *ha;
+	int count = 0;
+
+	/* Disable multicast filtering */
+	priv->has_multicast_subscription = false;
+	memset(&priv->multicast_filter, 0x00, sizeof(priv->multicast_filter));
+
+	if (netdev_hw_addr_list_count(mc_list) > WSM_MAX_GRP_ADDRTABLE_ENTRIES)
+		return 0;
+
+	/* Enable if requested */
+	netdev_hw_addr_list_for_each(ha, mc_list) {
+		pr_debug("[STA] multicast: %pM\n", ha->addr);
+		memcpy(&priv->multicast_filter.macaddrs[count],
+		       ha->addr, ETH_ALEN);
+		if (memcmp(ha->addr, broadcast_ipv4, ETH_ALEN) &&
+		    memcmp(ha->addr, broadcast_ipv6, ETH_ALEN))
+			priv->has_multicast_subscription = true;
+		count++;
+	}
+
+	if (count) {
+		priv->multicast_filter.enable = __cpu_to_le32(1);
+		priv->multicast_filter.num_addrs = __cpu_to_le32(count);
+	}
+
+	return netdev_hw_addr_list_count(mc_list);
+}
+
+void cw1200_configure_filter(struct ieee80211_hw *dev,
+			     unsigned int changed_flags,
+			     unsigned int *total_flags,
+			     u64 multicast)
+{
+	struct cw1200_common *priv = dev->priv;
+	bool listening = !!(*total_flags &
+			    (FIF_PROMISC_IN_BSS |
+			     FIF_OTHER_BSS |
+			     FIF_BCN_PRBRESP_PROMISC |
+			     FIF_PROBE_REQ));
+
+	*total_flags &= FIF_PROMISC_IN_BSS |
+			FIF_OTHER_BSS |
+			FIF_FCSFAIL |
+			FIF_BCN_PRBRESP_PROMISC |
+			FIF_PROBE_REQ;
+
+	down(&priv->scan.lock);
+	mutex_lock(&priv->conf_mutex);
+
+	priv->rx_filter.promiscuous = (*total_flags & FIF_PROMISC_IN_BSS)
+			? 1 : 0;
+	priv->rx_filter.bssid = (*total_flags & (FIF_OTHER_BSS |
+			FIF_PROBE_REQ)) ? 1 : 0;
+	priv->rx_filter.fcs = (*total_flags & FIF_FCSFAIL) ? 1 : 0;
+	priv->disable_beacon_filter = !(*total_flags &
+					(FIF_BCN_PRBRESP_PROMISC |
+					 FIF_PROMISC_IN_BSS |
+					 FIF_PROBE_REQ));
+	if (priv->listening != listening) {
+		priv->listening = listening;
+		wsm_lock_tx(priv);
+		cw1200_update_listening(priv, listening);
+		wsm_unlock_tx(priv);
+	}
+	cw1200_update_filtering(priv);
+	mutex_unlock(&priv->conf_mutex);
+	up(&priv->scan.lock);
+}
+
+int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
+		   u16 queue, const struct ieee80211_tx_queue_params *params)
+{
+	struct cw1200_common *priv = dev->priv;
+	int ret = 0;
+	/* To prevent re-applying PM request OID again and again*/
+	bool old_uapsd_flags;
+
+	mutex_lock(&priv->conf_mutex);
+
+	if (queue < dev->queues) {
+		old_uapsd_flags = le16_to_cpu(priv->uapsd_info.uapsd_flags);
+
+		WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0);
+		ret = wsm_set_tx_queue_params(priv,
+					      &priv->tx_queue_params.params[queue], queue);
+		if (ret) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		WSM_EDCA_SET(&priv->edca, queue, params->aifs,
+			     params->cw_min, params->cw_max,
+			     params->txop, 0xc8,
+			     params->uapsd);
+		ret = wsm_set_edca_params(priv, &priv->edca);
+		if (ret) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (priv->mode == NL80211_IFTYPE_STATION) {
+			ret = cw1200_set_uapsd_param(priv, &priv->edca);
+			if (!ret && priv->setbssparams_done &&
+			    (priv->join_status == CW1200_JOIN_STATUS_STA) &&
+			    (old_uapsd_flags != le16_to_cpu(priv->uapsd_info.uapsd_flags)))
+				ret = cw1200_set_pm(priv, &priv->powersave_mode);
+		}
+	} else {
+		ret = -EINVAL;
+	}
+
+out:
+	mutex_unlock(&priv->conf_mutex);
+	return ret;
+}
+
+int cw1200_get_stats(struct ieee80211_hw *dev,
+		     struct ieee80211_low_level_stats *stats)
+{
+	struct cw1200_common *priv = dev->priv;
+
+	memcpy(stats, &priv->stats, sizeof(*stats));
+	return 0;
+}
+
+int cw1200_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
+{
+	struct wsm_set_pm pm = *arg;
+
+	if (priv->uapsd_info.uapsd_flags != 0)
+		pm.mode &= ~WSM_PSM_FAST_PS_FLAG;
+
+	if (memcmp(&pm, &priv->firmware_ps_mode,
+		   sizeof(struct wsm_set_pm))) {
+		priv->firmware_ps_mode = pm;
+		return wsm_set_pm(priv, &pm);
+	} else {
+		return 0;
+	}
+}
+
+int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
+		   struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+		   struct ieee80211_key_conf *key)
+{
+	int ret = -EOPNOTSUPP;
+	struct cw1200_common *priv = dev->priv;
+	struct ieee80211_key_seq seq;
+
+	mutex_lock(&priv->conf_mutex);
+
+	if (cmd == SET_KEY) {
+		u8 *peer_addr = NULL;
+		int pairwise = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ?
+			1 : 0;
+		int idx = cw1200_alloc_key(priv);
+		struct wsm_add_key *wsm_key = &priv->keys[idx];
+
+		if (idx < 0) {
+			ret = -EINVAL;
+			goto finally;
+		}
+
+		if (sta)
+			peer_addr = sta->addr;
+
+		key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
+
+		switch (key->cipher) {
+		case WLAN_CIPHER_SUITE_WEP40:
+		case WLAN_CIPHER_SUITE_WEP104:
+			if (key->keylen > 16) {
+				cw1200_free_key(priv, idx);
+				ret = -EINVAL;
+				goto finally;
+			}
+
+			if (pairwise) {
+				wsm_key->type = WSM_KEY_TYPE_WEP_PAIRWISE;
+				memcpy(wsm_key->wep_pairwise.peer,
+				       peer_addr, ETH_ALEN);
+				memcpy(wsm_key->wep_pairwise.keydata,
+				       &key->key[0], key->keylen);
+				wsm_key->wep_pairwise.keylen = key->keylen;
+			} else {
+				wsm_key->type = WSM_KEY_TYPE_WEP_DEFAULT;
+				memcpy(wsm_key->wep_group.keydata,
+				       &key->key[0], key->keylen);
+				wsm_key->wep_group.keylen = key->keylen;
+				wsm_key->wep_group.keyid = key->keyidx;
+			}
+			break;
+		case WLAN_CIPHER_SUITE_TKIP:
+			ieee80211_get_key_rx_seq(key, 0, &seq);
+			if (pairwise) {
+				wsm_key->type = WSM_KEY_TYPE_TKIP_PAIRWISE;
+				memcpy(wsm_key->tkip_pairwise.peer,
+				       peer_addr, ETH_ALEN);
+				memcpy(wsm_key->tkip_pairwise.keydata,
+				       &key->key[0], 16);
+				memcpy(wsm_key->tkip_pairwise.tx_mic_key,
+				       &key->key[16], 8);
+				memcpy(wsm_key->tkip_pairwise.rx_mic_key,
+				       &key->key[24], 8);
+			} else {
+				size_t mic_offset =
+					(priv->mode == NL80211_IFTYPE_AP) ?
+					16 : 24;
+				wsm_key->type = WSM_KEY_TYPE_TKIP_GROUP;
+				memcpy(wsm_key->tkip_group.keydata,
+				       &key->key[0], 16);
+				memcpy(wsm_key->tkip_group.rx_mic_key,
+				       &key->key[mic_offset], 8);
+
+				wsm_key->tkip_group.rx_seqnum[0] = seq.tkip.iv16 & 0xff;
+				wsm_key->tkip_group.rx_seqnum[1] = (seq.tkip.iv16 >> 8) & 0xff;
+				wsm_key->tkip_group.rx_seqnum[2] = seq.tkip.iv32 & 0xff;
+				wsm_key->tkip_group.rx_seqnum[3] = (seq.tkip.iv32 >> 8) & 0xff;
+				wsm_key->tkip_group.rx_seqnum[4] = (seq.tkip.iv32 >> 16) & 0xff;
+				wsm_key->tkip_group.rx_seqnum[5] = (seq.tkip.iv32 >> 24) & 0xff;
+				wsm_key->tkip_group.rx_seqnum[6] = 0;
+				wsm_key->tkip_group.rx_seqnum[7] = 0;
+
+				wsm_key->tkip_group.keyid = key->keyidx;
+			}
+			break;
+		case WLAN_CIPHER_SUITE_CCMP:
+			ieee80211_get_key_rx_seq(key, 0, &seq);
+			if (pairwise) {
+				wsm_key->type = WSM_KEY_TYPE_AES_PAIRWISE;
+				memcpy(wsm_key->aes_pairwise.peer,
+				       peer_addr, ETH_ALEN);
+				memcpy(wsm_key->aes_pairwise.keydata,
+				       &key->key[0], 16);
+			} else {
+				wsm_key->type = WSM_KEY_TYPE_AES_GROUP;
+				memcpy(wsm_key->aes_group.keydata,
+				       &key->key[0], 16);
+
+				wsm_key->aes_group.rx_seqnum[0] = seq.ccmp.pn[5];
+				wsm_key->aes_group.rx_seqnum[1] = seq.ccmp.pn[4];
+				wsm_key->aes_group.rx_seqnum[2] = seq.ccmp.pn[3];
+				wsm_key->aes_group.rx_seqnum[3] = seq.ccmp.pn[2];
+				wsm_key->aes_group.rx_seqnum[4] = seq.ccmp.pn[1];
+				wsm_key->aes_group.rx_seqnum[5] = seq.ccmp.pn[0];
+				wsm_key->aes_group.rx_seqnum[6] = 0;
+				wsm_key->aes_group.rx_seqnum[7] = 0;
+				wsm_key->aes_group.keyid = key->keyidx;
+			}
+			break;
+		case WLAN_CIPHER_SUITE_SMS4:
+			if (pairwise) {
+				wsm_key->type = WSM_KEY_TYPE_WAPI_PAIRWISE;
+				memcpy(wsm_key->wapi_pairwise.peer,
+				       peer_addr, ETH_ALEN);
+				memcpy(wsm_key->wapi_pairwise.keydata,
+				       &key->key[0], 16);
+				memcpy(wsm_key->wapi_pairwise.mic_key,
+				       &key->key[16], 16);
+				wsm_key->wapi_pairwise.keyid = key->keyidx;
+			} else {
+				wsm_key->type = WSM_KEY_TYPE_WAPI_GROUP;
+				memcpy(wsm_key->wapi_group.keydata,
+				       &key->key[0],  16);
+				memcpy(wsm_key->wapi_group.mic_key,
+				       &key->key[16], 16);
+				wsm_key->wapi_group.keyid = key->keyidx;
+			}
+			break;
+		default:
+			pr_warn("Unhandled key type %d\n", key->cipher);
+			cw1200_free_key(priv, idx);
+			ret = -EOPNOTSUPP;
+			goto finally;
+		}
+		ret = wsm_add_key(priv, wsm_key);
+		if (!ret)
+			key->hw_key_idx = idx;
+		else
+			cw1200_free_key(priv, idx);
+	} else if (cmd == DISABLE_KEY) {
+		struct wsm_remove_key wsm_key = {
+			.index = key->hw_key_idx,
+		};
+
+		if (wsm_key.index > WSM_KEY_MAX_INDEX) {
+			ret = -EINVAL;
+			goto finally;
+		}
+
+		cw1200_free_key(priv, wsm_key.index);
+		ret = wsm_remove_key(priv, &wsm_key);
+	} else {
+		pr_warn("Unhandled key command %d\n", cmd);
+	}
+
+finally:
+	mutex_unlock(&priv->conf_mutex);
+	return ret;
+}
+
+void cw1200_wep_key_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, wep_key_work);
+	u8 queue_id = cw1200_queue_get_queue_id(priv->pending_frame_id);
+	struct cw1200_queue *queue = &priv->tx_queue[queue_id];
+	__le32 wep_default_key_id = __cpu_to_le32(
+		priv->wep_default_key_id);
+
+	pr_debug("[STA] Setting default WEP key: %d\n",
+		 priv->wep_default_key_id);
+	wsm_flush_tx(priv);
+	wsm_write_mib(priv, WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
+		      &wep_default_key_id, sizeof(wep_default_key_id));
+	cw1200_queue_requeue(queue, priv->pending_frame_id);
+	wsm_unlock_tx(priv);
+}
+
+int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+	int ret = 0;
+	__le32 val32;
+	struct cw1200_common *priv = hw->priv;
+
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+		return 0;
+
+	if (value != (u32) -1)
+		val32 = __cpu_to_le32(value);
+	else
+		val32 = 0; /* disabled */
+
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
+		/* device is down, can _not_ set threshold */
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (priv->rts_threshold == value)
+		goto out;
+
+	pr_debug("[STA] Setting RTS threshold: %d\n",
+		 priv->rts_threshold);
+
+	/* mutex_lock(&priv->conf_mutex); */
+	ret = wsm_write_mib(priv, WSM_MIB_ID_DOT11_RTS_THRESHOLD,
+			    &val32, sizeof(val32));
+	if (!ret)
+		priv->rts_threshold = value;
+	/* mutex_unlock(&priv->conf_mutex); */
+
+out:
+	return ret;
+}
+
+/* If successful, LOCKS the TX queue! */
+static int __cw1200_flush(struct cw1200_common *priv, bool drop)
+{
+	int i, ret;
+
+	for (;;) {
+		/* TODO: correct flush handling is required when dev_stop.
+		 * Temporary workaround: 2s
+		 */
+		if (drop) {
+			for (i = 0; i < 4; ++i)
+				cw1200_queue_clear(&priv->tx_queue[i]);
+		} else {
+			ret = wait_event_timeout(
+				priv->tx_queue_stats.wait_link_id_empty,
+				cw1200_queue_stats_is_empty(
+					&priv->tx_queue_stats, -1),
+				2 * HZ);
+		}
+
+		if (!drop && ret <= 0) {
+			ret = -ETIMEDOUT;
+			break;
+		} else {
+			ret = 0;
+		}
+
+		wsm_lock_tx(priv);
+		if (!cw1200_queue_stats_is_empty(&priv->tx_queue_stats, -1)) {
+			/* Highly unlikely: WSM requeued frames. */
+			wsm_unlock_tx(priv);
+			continue;
+		}
+		break;
+	}
+	return ret;
+}
+
+void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
+{
+	struct cw1200_common *priv = hw->priv;
+
+	switch (priv->mode) {
+	case NL80211_IFTYPE_MONITOR:
+		drop = true;
+		break;
+	case NL80211_IFTYPE_AP:
+		if (!priv->enable_beacon)
+			drop = true;
+		break;
+	}
+
+	if (!__cw1200_flush(priv, drop))
+		wsm_unlock_tx(priv);
+
+	return;
+}
+
+/* ******************************************************************** */
+/* WSM callbacks							*/
+
+void cw1200_free_event_queue(struct cw1200_common *priv)
+{
+	LIST_HEAD(list);
+
+	spin_lock(&priv->event_queue_lock);
+	list_splice_init(&priv->event_queue, &list);
+	spin_unlock(&priv->event_queue_lock);
+
+	__cw1200_free_event_queue(&list);
+}
+
+void cw1200_event_handler(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, event_handler);
+	struct cw1200_wsm_event *event;
+	LIST_HEAD(list);
+
+	spin_lock(&priv->event_queue_lock);
+	list_splice_init(&priv->event_queue, &list);
+	spin_unlock(&priv->event_queue_lock);
+
+	list_for_each_entry(event, &list, link) {
+		switch (event->evt.id) {
+		case WSM_EVENT_ERROR:
+			pr_err("Unhandled WSM Error from LMAC\n");
+			break;
+		case WSM_EVENT_BSS_LOST:
+			pr_debug("[CQM] BSS lost.\n");
+			cancel_work_sync(&priv->unjoin_work);
+			if (!down_trylock(&priv->scan.lock)) {
+				cw1200_cqm_bssloss_sm(priv, 1, 0, 0);
+				up(&priv->scan.lock);
+			} else {
+				/* Scan is in progress. Delay reporting.
+				 * Scan complete will trigger bss_loss_work
+				 */
+				priv->delayed_link_loss = 1;
+				/* Also start a watchdog. */
+				queue_delayed_work(priv->workqueue,
+						   &priv->bss_loss_work, 5*HZ);
+			}
+			break;
+		case WSM_EVENT_BSS_REGAINED:
+			pr_debug("[CQM] BSS regained.\n");
+			cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
+			cancel_work_sync(&priv->unjoin_work);
+			break;
+		case WSM_EVENT_RADAR_DETECTED:
+			wiphy_info(priv->hw->wiphy, "radar pulse detected\n");
+			break;
+		case WSM_EVENT_RCPI_RSSI:
+		{
+			/* RSSI: signed Q8.0, RCPI: unsigned Q7.1
+			 * RSSI = RCPI / 2 - 110
+			 */
+			int rcpi_rssi = (int)(event->evt.data & 0xFF);
+			int cqm_evt;
+			if (priv->cqm_use_rssi)
+				rcpi_rssi = (s8)rcpi_rssi;
+			else
+				rcpi_rssi =  rcpi_rssi / 2 - 110;
+
+			cqm_evt = (rcpi_rssi <= priv->cqm_rssi_thold) ?
+				NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW :
+				NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
+			pr_debug("[CQM] RSSI event: %d.\n", rcpi_rssi);
+			ieee80211_cqm_rssi_notify(priv->vif, cqm_evt,
+						  GFP_KERNEL);
+			break;
+		}
+		case WSM_EVENT_BT_INACTIVE:
+			pr_warn("Unhandled BT INACTIVE from LMAC\n");
+			break;
+		case WSM_EVENT_BT_ACTIVE:
+			pr_warn("Unhandled BT ACTIVE from LMAC\n");
+			break;
+		}
+	}
+	__cw1200_free_event_queue(&list);
+}
+
+void cw1200_bss_loss_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, bss_loss_work.work);
+
+	pr_debug("[CQM] Reporting connection loss.\n");
+	wsm_lock_tx(priv);
+	if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
+		wsm_unlock_tx(priv);
+}
+
+void cw1200_bss_params_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, bss_params_work);
+	mutex_lock(&priv->conf_mutex);
+
+	priv->bss_params.reset_beacon_loss = 1;
+	wsm_set_bss_params(priv, &priv->bss_params);
+	priv->bss_params.reset_beacon_loss = 0;
+
+	mutex_unlock(&priv->conf_mutex);
+}
+
+/* ******************************************************************** */
+/* Internal API								*/
+
+/* This function is called to Parse the SDD file
+ * to extract listen_interval and PTA related information
+ * sdd is a TLV: u8 id, u8 len, u8 data[]
+ */
+static int cw1200_parse_sdd_file(struct cw1200_common *priv)
+{
+	const u8 *p = priv->sdd->data;
+	int ret = 0;
+
+	while (p + 2 <= priv->sdd->data + priv->sdd->size) {
+		if (p + p[1] + 2 > priv->sdd->data + priv->sdd->size) {
+			pr_warn("Malformed sdd structure\n");
+			return -1;
+		}
+		switch (p[0]) {
+		case SDD_PTA_CFG_ELT_ID: {
+			u16 v;
+			if (p[1] < 4) {
+				pr_warn("SDD_PTA_CFG_ELT_ID malformed\n");
+				ret = -1;
+				break;
+			}
+			v = le16_to_cpu(*((__le16 *)(p + 2)));
+			if (!v)  /* non-zero means this is enabled */
+				break;
+
+			v = le16_to_cpu(*((__le16 *)(p + 4)));
+			priv->conf_listen_interval = (v >> 7) & 0x1F;
+			pr_debug("PTA found; Listen Interval %d\n",
+				 priv->conf_listen_interval);
+			break;
+		}
+		case SDD_REFERENCE_FREQUENCY_ELT_ID: {
+			u16 clk = le16_to_cpu(*((__le16 *)(p + 2)));
+			if (clk != priv->hw_refclk)
+				pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n",
+					clk, priv->hw_refclk);
+			break;
+		}
+		default:
+			break;
+		}
+		p += p[1] + 2;
+	}
+
+	if (!priv->bt_present) {
+		pr_debug("PTA element NOT found.\n");
+		priv->conf_listen_interval = 0;
+	}
+	return ret;
+}
+
+int cw1200_setup_mac(struct cw1200_common *priv)
+{
+	int ret = 0;
+
+	/* NOTE: There is a bug in FW: it reports signal
+	 * as RSSI if RSSI subscription is enabled.
+	 * It's not enough to set WSM_RCPI_RSSI_USE_RSSI.
+	 *
+	 * NOTE2: RSSI based reports have been switched to RCPI, since
+	 * FW has a bug and RSSI reported values are not stable,
+	 * what can leads to signal level oscilations in user-end applications
+	 */
+	struct wsm_rcpi_rssi_threshold threshold = {
+		.rssiRcpiMode = WSM_RCPI_RSSI_THRESHOLD_ENABLE |
+		WSM_RCPI_RSSI_DONT_USE_UPPER |
+		WSM_RCPI_RSSI_DONT_USE_LOWER,
+		.rollingAverageCount = 16,
+	};
+
+	struct wsm_configuration cfg = {
+		.dot11StationId = &priv->mac_addr[0],
+	};
+
+	/* Remember the decission here to make sure, we will handle
+	 * the RCPI/RSSI value correctly on WSM_EVENT_RCPI_RSS
+	 */
+	if (threshold.rssiRcpiMode & WSM_RCPI_RSSI_USE_RSSI)
+		priv->cqm_use_rssi = true;
+
+	if (!priv->sdd) {
+		ret = reject_firmware(&priv->sdd, priv->sdd_path, priv->pdev);
+		if (ret) {
+			pr_err("Can't load sdd file %s.\n", priv->sdd_path);
+			return ret;
+		}
+		cw1200_parse_sdd_file(priv);
+	}
+
+	cfg.dpdData = priv->sdd->data;
+	cfg.dpdData_size = priv->sdd->size;
+	ret = wsm_configuration(priv, &cfg);
+	if (ret)
+		return ret;
+
+	/* Configure RSSI/SCPI reporting as RSSI. */
+	wsm_set_rcpi_rssi_threshold(priv, &threshold);
+
+	return 0;
+}
+
+static void cw1200_join_complete(struct cw1200_common *priv)
+{
+	pr_debug("[STA] Join complete (%d)\n", priv->join_complete_status);
+
+	priv->join_pending = false;
+	if (priv->join_complete_status) {
+		priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
+		cw1200_update_listening(priv, priv->listening);
+		cw1200_do_unjoin(priv);
+		ieee80211_connection_loss(priv->vif);
+	} else {
+		if (priv->mode == NL80211_IFTYPE_ADHOC)
+			priv->join_status = CW1200_JOIN_STATUS_IBSS;
+		else
+			priv->join_status = CW1200_JOIN_STATUS_PRE_STA;
+	}
+	wsm_unlock_tx(priv); /* Clearing the lock held before do_join() */
+}
+
+void cw1200_join_complete_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, join_complete_work);
+	mutex_lock(&priv->conf_mutex);
+	cw1200_join_complete(priv);
+	mutex_unlock(&priv->conf_mutex);
+}
+
+void cw1200_join_complete_cb(struct cw1200_common *priv,
+			     struct wsm_join_complete *arg)
+{
+	pr_debug("[STA] cw1200_join_complete_cb called, status=%d.\n",
+		 arg->status);
+
+	if (cancel_delayed_work(&priv->join_timeout)) {
+		priv->join_complete_status = arg->status;
+		queue_work(priv->workqueue, &priv->join_complete_work);
+	}
+}
+
+/* MUST be called with tx_lock held!  It will be unlocked for us. */
+static void cw1200_do_join(struct cw1200_common *priv)
+{
+	const u8 *bssid;
+	struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
+	struct cfg80211_bss *bss = NULL;
+	struct wsm_protected_mgmt_policy mgmt_policy;
+	struct wsm_join join = {
+		.mode = conf->ibss_joined ?
+				WSM_JOIN_MODE_IBSS : WSM_JOIN_MODE_BSS,
+		.preamble_type = WSM_JOIN_PREAMBLE_LONG,
+		.probe_for_join = 1,
+		.atim_window = 0,
+		.basic_rate_set = cw1200_rate_mask_to_wsm(priv,
+							  conf->basic_rates),
+	};
+	if (delayed_work_pending(&priv->join_timeout)) {
+		pr_warn("[STA] - Join request already pending, skipping..\n");
+		wsm_unlock_tx(priv);
+		return;
+	}
+
+	if (priv->join_status)
+		cw1200_do_unjoin(priv);
+
+	bssid = priv->vif->bss_conf.bssid;
+
+	bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel,
+			bssid, NULL, 0, 0, 0);
+
+	if (!bss && !conf->ibss_joined) {
+		wsm_unlock_tx(priv);
+		return;
+	}
+
+	mutex_lock(&priv->conf_mutex);
+
+	/* Under the conf lock: check scan status and
+	 * bail out if it is in progress.
+	 */
+	if (atomic_read(&priv->scan.in_progress)) {
+		wsm_unlock_tx(priv);
+		goto done_put;
+	}
+
+	priv->join_pending = true;
+
+	/* Sanity check basic rates */
+	if (!join.basic_rate_set)
+		join.basic_rate_set = 7;
+
+	/* Sanity check beacon interval */
+	if (!priv->beacon_int)
+		priv->beacon_int = 1;
+
+	join.beacon_interval = priv->beacon_int;
+
+	/* BT Coex related changes */
+	if (priv->bt_present) {
+		if (((priv->conf_listen_interval * 100) %
+		     priv->beacon_int) == 0)
+			priv->listen_interval =
+				((priv->conf_listen_interval * 100) /
+				 priv->beacon_int);
+		else
+			priv->listen_interval =
+				((priv->conf_listen_interval * 100) /
+				 priv->beacon_int + 1);
+	}
+
+	if (priv->hw->conf.ps_dtim_period)
+		priv->join_dtim_period = priv->hw->conf.ps_dtim_period;
+	join.dtim_period = priv->join_dtim_period;
+
+	join.channel_number = priv->channel->hw_value;
+	join.band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
+		WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
+
+	memcpy(join.bssid, bssid, sizeof(join.bssid));
+
+	pr_debug("[STA] Join BSSID: %pM DTIM: %d, interval: %d\n",
+		 join.bssid,
+		 join.dtim_period, priv->beacon_int);
+
+	if (!conf->ibss_joined) {
+		const u8 *ssidie;
+		rcu_read_lock();
+		ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
+		if (ssidie) {
+			join.ssid_len = ssidie[1];
+			memcpy(join.ssid, &ssidie[2], join.ssid_len);
+		}
+		rcu_read_unlock();
+	}
+
+	if (priv->vif->p2p) {
+		join.flags |= WSM_JOIN_FLAGS_P2P_GO;
+		join.basic_rate_set =
+			cw1200_rate_mask_to_wsm(priv, 0xFF0);
+	}
+
+	/* Enable asynchronous join calls */
+	if (!conf->ibss_joined) {
+		join.flags |= WSM_JOIN_FLAGS_FORCE;
+		join.flags |= WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND;
+	}
+
+	wsm_flush_tx(priv);
+
+	/* Stay Awake for Join and Auth Timeouts and a bit more */
+	cw1200_pm_stay_awake(&priv->pm_state,
+			     CW1200_JOIN_TIMEOUT + CW1200_AUTH_TIMEOUT);
+
+	cw1200_update_listening(priv, false);
+
+	/* Turn on Block ACKs */
+	wsm_set_block_ack_policy(priv, priv->ba_tx_tid_mask,
+				 priv->ba_rx_tid_mask);
+
+	/* Set up timeout */
+	if (join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND) {
+		priv->join_status = CW1200_JOIN_STATUS_JOINING;
+		queue_delayed_work(priv->workqueue,
+				   &priv->join_timeout,
+				   CW1200_JOIN_TIMEOUT);
+	}
+
+	/* 802.11w protected mgmt frames */
+	mgmt_policy.protectedMgmtEnable = 0;
+	mgmt_policy.unprotectedMgmtFramesAllowed = 1;
+	mgmt_policy.encryptionForAuthFrame = 1;
+	wsm_set_protected_mgmt_policy(priv, &mgmt_policy);
+
+	/* Perform actual join */
+	if (wsm_join(priv, &join)) {
+		pr_err("[STA] cw1200_join_work: wsm_join failed!\n");
+		cancel_delayed_work_sync(&priv->join_timeout);
+		cw1200_update_listening(priv, priv->listening);
+		/* Tx lock still held, unjoin will clear it. */
+		if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
+			wsm_unlock_tx(priv);
+	} else {
+		if (!(join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND))
+			cw1200_join_complete(priv); /* Will clear tx_lock */
+
+		/* Upload keys */
+		cw1200_upload_keys(priv);
+
+		/* Due to beacon filtering it is possible that the
+		 * AP's beacon is not known for the mac80211 stack.
+		 * Disable filtering temporary to make sure the stack
+		 * receives at least one
+		 */
+		priv->disable_beacon_filter = true;
+	}
+	cw1200_update_filtering(priv);
+
+done_put:
+	mutex_unlock(&priv->conf_mutex);
+	if (bss)
+		cfg80211_put_bss(priv->hw->wiphy, bss);
+}
+
+void cw1200_join_timeout(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, join_timeout.work);
+	pr_debug("[WSM] Join timed out.\n");
+	wsm_lock_tx(priv);
+	if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
+		wsm_unlock_tx(priv);
+}
+
+static void cw1200_do_unjoin(struct cw1200_common *priv)
+{
+	struct wsm_reset reset = {
+		.reset_statistics = true,
+	};
+
+	cancel_delayed_work_sync(&priv->join_timeout);
+
+	mutex_lock(&priv->conf_mutex);
+	priv->join_pending = false;
+
+	if (atomic_read(&priv->scan.in_progress)) {
+		if (priv->delayed_unjoin)
+			wiphy_dbg(priv->hw->wiphy, "Delayed unjoin is already scheduled.\n");
+		else
+			priv->delayed_unjoin = true;
+		goto done;
+	}
+
+	priv->delayed_link_loss = false;
+
+	if (!priv->join_status)
+		goto done;
+
+	if (priv->join_status == CW1200_JOIN_STATUS_AP)
+		goto done;
+
+	cancel_work_sync(&priv->update_filtering_work);
+	cancel_work_sync(&priv->set_beacon_wakeup_period_work);
+	priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
+
+	/* Unjoin is a reset. */
+	wsm_flush_tx(priv);
+	wsm_keep_alive_period(priv, 0);
+	wsm_reset(priv, &reset);
+	wsm_set_output_power(priv, priv->output_power * 10);
+	priv->join_dtim_period = 0;
+	cw1200_setup_mac(priv);
+	cw1200_free_event_queue(priv);
+	cancel_work_sync(&priv->event_handler);
+	cw1200_update_listening(priv, priv->listening);
+	cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
+
+	/* Disable Block ACKs */
+	wsm_set_block_ack_policy(priv, 0, 0);
+
+	priv->disable_beacon_filter = false;
+	cw1200_update_filtering(priv);
+	memset(&priv->association_mode, 0,
+	       sizeof(priv->association_mode));
+	memset(&priv->bss_params, 0, sizeof(priv->bss_params));
+	priv->setbssparams_done = false;
+	memset(&priv->firmware_ps_mode, 0,
+	       sizeof(priv->firmware_ps_mode));
+
+	pr_debug("[STA] Unjoin completed.\n");
+
+done:
+	mutex_unlock(&priv->conf_mutex);
+}
+
+void cw1200_unjoin_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, unjoin_work);
+
+	cw1200_do_unjoin(priv);
+
+	/* Tell the stack we're dead */
+	ieee80211_connection_loss(priv->vif);
+
+	wsm_unlock_tx(priv);
+}
+
+int cw1200_enable_listening(struct cw1200_common *priv)
+{
+	struct wsm_start start = {
+		.mode = WSM_START_MODE_P2P_DEV,
+		.band = WSM_PHY_BAND_2_4G,
+		.beacon_interval = 100,
+		.dtim_period = 1,
+		.probe_delay = 0,
+		.basic_rate_set = 0x0F,
+	};
+
+	if (priv->channel) {
+		start.band = priv->channel->band == IEEE80211_BAND_5GHZ ?
+			     WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
+		start.channel_number = priv->channel->hw_value;
+	} else {
+		start.band = WSM_PHY_BAND_2_4G;
+		start.channel_number = 1;
+	}
+
+	return wsm_start(priv, &start);
+}
+
+int cw1200_disable_listening(struct cw1200_common *priv)
+{
+	int ret;
+	struct wsm_reset reset = {
+		.reset_statistics = true,
+	};
+	ret = wsm_reset(priv, &reset);
+	return ret;
+}
+
+void cw1200_update_listening(struct cw1200_common *priv, bool enabled)
+{
+	if (enabled) {
+		if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE) {
+			if (!cw1200_enable_listening(priv))
+				priv->join_status = CW1200_JOIN_STATUS_MONITOR;
+			wsm_set_probe_responder(priv, true);
+		}
+	} else {
+		if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
+			if (!cw1200_disable_listening(priv))
+				priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
+			wsm_set_probe_responder(priv, false);
+		}
+	}
+}
+
+int cw1200_set_uapsd_param(struct cw1200_common *priv,
+			   const struct wsm_edca_params *arg)
+{
+	int ret;
+	u16 uapsd_flags = 0;
+
+	/* Here's the mapping AC [queue, bit]
+	 *  VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0]
+	 */
+
+	if (arg->uapsd_enable[0])
+		uapsd_flags |= 1 << 3;
+
+	if (arg->uapsd_enable[1])
+		uapsd_flags |= 1 << 2;
+
+	if (arg->uapsd_enable[2])
+		uapsd_flags |= 1 << 1;
+
+	if (arg->uapsd_enable[3])
+		uapsd_flags |= 1;
+
+	/* Currently pseudo U-APSD operation is not supported, so setting
+	 * MinAutoTriggerInterval, MaxAutoTriggerInterval and
+	 * AutoTriggerStep to 0
+	 */
+
+	priv->uapsd_info.uapsd_flags = cpu_to_le16(uapsd_flags);
+	priv->uapsd_info.min_auto_trigger_interval = 0;
+	priv->uapsd_info.max_auto_trigger_interval = 0;
+	priv->uapsd_info.auto_trigger_step = 0;
+
+	ret = wsm_set_uapsd_info(priv, &priv->uapsd_info);
+	return ret;
+}
+
+/* ******************************************************************** */
+/* AP API								*/
+
+int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		   struct ieee80211_sta *sta)
+{
+	struct cw1200_common *priv = hw->priv;
+	struct cw1200_sta_priv *sta_priv =
+			(struct cw1200_sta_priv *)&sta->drv_priv;
+	struct cw1200_link_entry *entry;
+	struct sk_buff *skb;
+
+	if (priv->mode != NL80211_IFTYPE_AP)
+		return 0;
+
+	sta_priv->link_id = cw1200_find_link_id(priv, sta->addr);
+	if (WARN_ON(!sta_priv->link_id)) {
+		wiphy_info(priv->hw->wiphy,
+			   "[AP] No more link IDs available.\n");
+		return -ENOENT;
+	}
+
+	entry = &priv->link_id_db[sta_priv->link_id - 1];
+	spin_lock_bh(&priv->ps_state_lock);
+	if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
+					IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
+		priv->sta_asleep_mask |= BIT(sta_priv->link_id);
+	entry->status = CW1200_LINK_HARD;
+	while ((skb = skb_dequeue(&entry->rx_queue)))
+		ieee80211_rx_irqsafe(priv->hw, skb);
+	spin_unlock_bh(&priv->ps_state_lock);
+	return 0;
+}
+
+int cw1200_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		      struct ieee80211_sta *sta)
+{
+	struct cw1200_common *priv = hw->priv;
+	struct cw1200_sta_priv *sta_priv =
+			(struct cw1200_sta_priv *)&sta->drv_priv;
+	struct cw1200_link_entry *entry;
+
+	if (priv->mode != NL80211_IFTYPE_AP || !sta_priv->link_id)
+		return 0;
+
+	entry = &priv->link_id_db[sta_priv->link_id - 1];
+	spin_lock_bh(&priv->ps_state_lock);
+	entry->status = CW1200_LINK_RESERVE;
+	entry->timestamp = jiffies;
+	wsm_lock_tx_async(priv);
+	if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
+		wsm_unlock_tx(priv);
+	spin_unlock_bh(&priv->ps_state_lock);
+	flush_workqueue(priv->workqueue);
+	return 0;
+}
+
+static void __cw1200_sta_notify(struct ieee80211_hw *dev,
+				struct ieee80211_vif *vif,
+				enum sta_notify_cmd notify_cmd,
+				int link_id)
+{
+	struct cw1200_common *priv = dev->priv;
+	u32 bit, prev;
+
+	/* Zero link id means "for all link IDs" */
+	if (link_id)
+		bit = BIT(link_id);
+	else if (WARN_ON_ONCE(notify_cmd != STA_NOTIFY_AWAKE))
+		bit = 0;
+	else
+		bit = priv->link_id_map;
+	prev = priv->sta_asleep_mask & bit;
+
+	switch (notify_cmd) {
+	case STA_NOTIFY_SLEEP:
+		if (!prev) {
+			if (priv->buffered_multicasts &&
+			    !priv->sta_asleep_mask)
+				queue_work(priv->workqueue,
+					   &priv->multicast_start_work);
+			priv->sta_asleep_mask |= bit;
+		}
+		break;
+	case STA_NOTIFY_AWAKE:
+		if (prev) {
+			priv->sta_asleep_mask &= ~bit;
+			priv->pspoll_mask &= ~bit;
+			if (priv->tx_multicast && link_id &&
+			    !priv->sta_asleep_mask)
+				queue_work(priv->workqueue,
+					   &priv->multicast_stop_work);
+			cw1200_bh_wakeup(priv);
+		}
+		break;
+	}
+}
+
+void cw1200_sta_notify(struct ieee80211_hw *dev,
+		       struct ieee80211_vif *vif,
+		       enum sta_notify_cmd notify_cmd,
+		       struct ieee80211_sta *sta)
+{
+	struct cw1200_common *priv = dev->priv;
+	struct cw1200_sta_priv *sta_priv =
+		(struct cw1200_sta_priv *)&sta->drv_priv;
+
+	spin_lock_bh(&priv->ps_state_lock);
+	__cw1200_sta_notify(dev, vif, notify_cmd, sta_priv->link_id);
+	spin_unlock_bh(&priv->ps_state_lock);
+}
+
+static void cw1200_ps_notify(struct cw1200_common *priv,
+		      int link_id, bool ps)
+{
+	if (link_id > CW1200_MAX_STA_IN_AP_MODE)
+		return;
+
+	pr_debug("%s for LinkId: %d. STAs asleep: %.8X\n",
+		 ps ? "Stop" : "Start",
+		 link_id, priv->sta_asleep_mask);
+
+	__cw1200_sta_notify(priv->hw, priv->vif,
+			    ps ? STA_NOTIFY_SLEEP : STA_NOTIFY_AWAKE, link_id);
+}
+
+static int cw1200_set_tim_impl(struct cw1200_common *priv, bool aid0_bit_set)
+{
+	struct sk_buff *skb;
+	struct wsm_update_ie update_ie = {
+		.what = WSM_UPDATE_IE_BEACON,
+		.count = 1,
+	};
+	u16 tim_offset, tim_length;
+
+	pr_debug("[AP] mcast: %s.\n", aid0_bit_set ? "ena" : "dis");
+
+	skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
+			&tim_offset, &tim_length);
+	if (!skb) {
+		if (!__cw1200_flush(priv, true))
+			wsm_unlock_tx(priv);
+		return -ENOENT;
+	}
+
+	if (tim_offset && tim_length >= 6) {
+		/* Ignore DTIM count from mac80211:
+		 * firmware handles DTIM internally.
+		 */
+		skb->data[tim_offset + 2] = 0;
+
+		/* Set/reset aid0 bit */
+		if (aid0_bit_set)
+			skb->data[tim_offset + 4] |= 1;
+		else
+			skb->data[tim_offset + 4] &= ~1;
+	}
+
+	update_ie.ies = &skb->data[tim_offset];
+	update_ie.length = tim_length;
+	wsm_update_ie(priv, &update_ie);
+
+	dev_kfree_skb(skb);
+
+	return 0;
+}
+
+void cw1200_set_tim_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, set_tim_work);
+	(void)cw1200_set_tim_impl(priv, priv->aid0_bit_set);
+}
+
+int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
+		   bool set)
+{
+	struct cw1200_common *priv = dev->priv;
+	queue_work(priv->workqueue, &priv->set_tim_work);
+	return 0;
+}
+
+void cw1200_set_cts_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, set_cts_work);
+
+	u8 erp_ie[3] = {WLAN_EID_ERP_INFO, 0x1, 0};
+	struct wsm_update_ie update_ie = {
+		.what = WSM_UPDATE_IE_BEACON,
+		.count = 1,
+		.ies = erp_ie,
+		.length = 3,
+	};
+	u32 erp_info;
+	__le32 use_cts_prot;
+	mutex_lock(&priv->conf_mutex);
+	erp_info = priv->erp_info;
+	mutex_unlock(&priv->conf_mutex);
+	use_cts_prot =
+		erp_info & WLAN_ERP_USE_PROTECTION ?
+		__cpu_to_le32(1) : 0;
+
+	erp_ie[ERP_INFO_BYTE_OFFSET] = erp_info;
+
+	pr_debug("[STA] ERP information 0x%x\n", erp_info);
+
+	wsm_write_mib(priv, WSM_MIB_ID_NON_ERP_PROTECTION,
+		      &use_cts_prot, sizeof(use_cts_prot));
+	wsm_update_ie(priv, &update_ie);
+
+	return;
+}
+
+static int cw1200_set_btcoexinfo(struct cw1200_common *priv)
+{
+	struct wsm_override_internal_txrate arg;
+	int ret = 0;
+
+	if (priv->mode == NL80211_IFTYPE_STATION) {
+		/* Plumb PSPOLL and NULL template */
+		cw1200_upload_pspoll(priv);
+		cw1200_upload_null(priv);
+		cw1200_upload_qosnull(priv);
+	} else {
+		return 0;
+	}
+
+	memset(&arg, 0, sizeof(struct wsm_override_internal_txrate));
+
+	if (!priv->vif->p2p) {
+		/* STATION mode */
+		if (priv->bss_params.operational_rate_set & ~0xF) {
+			pr_debug("[STA] STA has ERP rates\n");
+			/* G or BG mode */
+			arg.internalTxRate = (__ffs(
+			priv->bss_params.operational_rate_set & ~0xF));
+		} else {
+			pr_debug("[STA] STA has non ERP rates\n");
+			/* B only mode */
+			arg.internalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set)));
+		}
+		arg.nonErpInternalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set)));
+	} else {
+		/* P2P mode */
+		arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
+		arg.nonErpInternalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
+	}
+
+	pr_debug("[STA] BTCOEX_INFO MODE %d, internalTxRate : %x, nonErpInternalTxRate: %x\n",
+		 priv->mode,
+		 arg.internalTxRate,
+		 arg.nonErpInternalTxRate);
+
+	ret = wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
+			    &arg, sizeof(arg));
+
+	return ret;
+}
+
+void cw1200_bss_info_changed(struct ieee80211_hw *dev,
+			     struct ieee80211_vif *vif,
+			     struct ieee80211_bss_conf *info,
+			     u32 changed)
+{
+	struct cw1200_common *priv = dev->priv;
+	bool do_join = false;
+
+	mutex_lock(&priv->conf_mutex);
+
+	pr_debug("BSS CHANGED:  %08x\n", changed);
+
+	/* TODO: BSS_CHANGED_QOS */
+	/* TODO: BSS_CHANGED_TXPOWER */
+
+	if (changed & BSS_CHANGED_ARP_FILTER) {
+		struct wsm_mib_arp_ipv4_filter filter = {0};
+		int i;
+
+		pr_debug("[STA] BSS_CHANGED_ARP_FILTER cnt: %d\n",
+			 info->arp_addr_cnt);
+
+		/* Currently only one IP address is supported by firmware.
+		 * In case of more IPs arp filtering will be disabled.
+		 */
+		if (info->arp_addr_cnt > 0 &&
+		    info->arp_addr_cnt <= WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES) {
+			for (i = 0; i < info->arp_addr_cnt; i++) {
+				filter.ipv4addrs[i] = info->arp_addr_list[i];
+				pr_debug("[STA] addr[%d]: 0x%X\n",
+					 i, filter.ipv4addrs[i]);
+			}
+			filter.enable = __cpu_to_le32(1);
+		}
+
+		pr_debug("[STA] arp ip filter enable: %d\n",
+			 __le32_to_cpu(filter.enable));
+
+		wsm_set_arp_ipv4_filter(priv, &filter);
+	}
+
+	if (changed &
+	    (BSS_CHANGED_BEACON |
+	     BSS_CHANGED_AP_PROBE_RESP |
+	     BSS_CHANGED_BSSID |
+	     BSS_CHANGED_SSID |
+	     BSS_CHANGED_IBSS)) {
+		pr_debug("BSS_CHANGED_BEACON\n");
+		priv->beacon_int = info->beacon_int;
+		cw1200_update_beaconing(priv);
+		cw1200_upload_beacon(priv);
+	}
+
+	if (changed & BSS_CHANGED_BEACON_ENABLED) {
+		pr_debug("BSS_CHANGED_BEACON_ENABLED (%d)\n", info->enable_beacon);
+
+		if (priv->enable_beacon != info->enable_beacon) {
+			cw1200_enable_beaconing(priv, info->enable_beacon);
+			priv->enable_beacon = info->enable_beacon;
+		}
+	}
+
+	if (changed & BSS_CHANGED_BEACON_INT) {
+		pr_debug("CHANGED_BEACON_INT\n");
+		if (info->ibss_joined)
+			do_join = true;
+		else if (priv->join_status == CW1200_JOIN_STATUS_AP)
+			cw1200_update_beaconing(priv);
+	}
+
+	/* assoc/disassoc, or maybe AID changed */
+	if (changed & BSS_CHANGED_ASSOC) {
+		wsm_lock_tx(priv);
+		priv->wep_default_key_id = -1;
+		wsm_unlock_tx(priv);
+	}
+
+	if (changed & BSS_CHANGED_BSSID) {
+		pr_debug("BSS_CHANGED_BSSID\n");
+		do_join = true;
+	}
+
+	if (changed &
+	    (BSS_CHANGED_ASSOC |
+	     BSS_CHANGED_BSSID |
+	     BSS_CHANGED_IBSS |
+	     BSS_CHANGED_BASIC_RATES |
+	     BSS_CHANGED_HT)) {
+		pr_debug("BSS_CHANGED_ASSOC\n");
+		if (info->assoc) {
+			if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA) {
+				ieee80211_connection_loss(vif);
+				mutex_unlock(&priv->conf_mutex);
+				return;
+			} else if (priv->join_status == CW1200_JOIN_STATUS_PRE_STA) {
+				priv->join_status = CW1200_JOIN_STATUS_STA;
+			}
+		} else {
+			do_join = true;
+		}
+
+		if (info->assoc || info->ibss_joined) {
+			struct ieee80211_sta *sta = NULL;
+			__le32 htprot = 0;
+
+			if (info->dtim_period)
+				priv->join_dtim_period = info->dtim_period;
+			priv->beacon_int = info->beacon_int;
+
+			rcu_read_lock();
+
+			if (info->bssid && !info->ibss_joined)
+				sta = ieee80211_find_sta(vif, info->bssid);
+			if (sta) {
+				priv->ht_info.ht_cap = sta->ht_cap;
+				priv->bss_params.operational_rate_set =
+					cw1200_rate_mask_to_wsm(priv,
+								sta->supp_rates[priv->channel->band]);
+				priv->ht_info.channel_type = cfg80211_get_chandef_type(&dev->conf.chandef);
+				priv->ht_info.operation_mode = info->ht_operation_mode;
+			} else {
+				memset(&priv->ht_info, 0,
+				       sizeof(priv->ht_info));
+				priv->bss_params.operational_rate_set = -1;
+			}
+			rcu_read_unlock();
+
+			/* Non Greenfield stations present */
+			if (priv->ht_info.operation_mode &
+			    IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
+				htprot |= cpu_to_le32(WSM_NON_GREENFIELD_STA_PRESENT);
+
+			/* Set HT protection method */
+			htprot |= cpu_to_le32((priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2);
+
+			/* TODO:
+			 * STBC_param.dual_cts
+			 *  STBC_param.LSIG_TXOP_FILL
+			 */
+
+			wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION,
+				      &htprot, sizeof(htprot));
+
+			priv->association_mode.greenfield =
+				cw1200_ht_greenfield(&priv->ht_info);
+			priv->association_mode.flags =
+				WSM_ASSOCIATION_MODE_SNOOP_ASSOC_FRAMES |
+				WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE |
+				WSM_ASSOCIATION_MODE_USE_HT_MODE |
+				WSM_ASSOCIATION_MODE_USE_BASIC_RATE_SET |
+				WSM_ASSOCIATION_MODE_USE_MPDU_START_SPACING;
+			priv->association_mode.preamble =
+				info->use_short_preamble ?
+				WSM_JOIN_PREAMBLE_SHORT :
+				WSM_JOIN_PREAMBLE_LONG;
+			priv->association_mode.basic_rate_set = __cpu_to_le32(
+				cw1200_rate_mask_to_wsm(priv,
+							info->basic_rates));
+			priv->association_mode.mpdu_start_spacing =
+				cw1200_ht_ampdu_density(&priv->ht_info);
+
+			cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
+			cancel_work_sync(&priv->unjoin_work);
+
+			priv->bss_params.beacon_lost_count = priv->cqm_beacon_loss_count;
+			priv->bss_params.aid = info->aid;
+
+			if (priv->join_dtim_period < 1)
+				priv->join_dtim_period = 1;
+
+			pr_debug("[STA] DTIM %d, interval: %d\n",
+				 priv->join_dtim_period, priv->beacon_int);
+			pr_debug("[STA] Preamble: %d, Greenfield: %d, Aid: %d, Rates: 0x%.8X, Basic: 0x%.8X\n",
+				 priv->association_mode.preamble,
+				 priv->association_mode.greenfield,
+				 priv->bss_params.aid,
+				 priv->bss_params.operational_rate_set,
+				 priv->association_mode.basic_rate_set);
+			wsm_set_association_mode(priv, &priv->association_mode);
+
+			if (!info->ibss_joined) {
+				wsm_keep_alive_period(priv, 30 /* sec */);
+				wsm_set_bss_params(priv, &priv->bss_params);
+				priv->setbssparams_done = true;
+				cw1200_set_beacon_wakeup_period_work(&priv->set_beacon_wakeup_period_work);
+				cw1200_set_pm(priv, &priv->powersave_mode);
+			}
+			if (priv->vif->p2p) {
+				pr_debug("[STA] Setting p2p powersave configuration.\n");
+				wsm_set_p2p_ps_modeinfo(priv,
+							&priv->p2p_ps_modeinfo);
+			}
+			if (priv->bt_present)
+				cw1200_set_btcoexinfo(priv);
+		} else {
+			memset(&priv->association_mode, 0,
+			       sizeof(priv->association_mode));
+			memset(&priv->bss_params, 0, sizeof(priv->bss_params));
+		}
+	}
+
+	/* ERP Protection */
+	if (changed & (BSS_CHANGED_ASSOC |
+		       BSS_CHANGED_ERP_CTS_PROT |
+		       BSS_CHANGED_ERP_PREAMBLE)) {
+		u32 prev_erp_info = priv->erp_info;
+		if (info->use_cts_prot)
+			priv->erp_info |= WLAN_ERP_USE_PROTECTION;
+		else if (!(prev_erp_info & WLAN_ERP_NON_ERP_PRESENT))
+			priv->erp_info &= ~WLAN_ERP_USE_PROTECTION;
+
+		if (info->use_short_preamble)
+			priv->erp_info |= WLAN_ERP_BARKER_PREAMBLE;
+		else
+			priv->erp_info &= ~WLAN_ERP_BARKER_PREAMBLE;
+
+		pr_debug("[STA] ERP Protection: %x\n", priv->erp_info);
+
+		if (prev_erp_info != priv->erp_info)
+			queue_work(priv->workqueue, &priv->set_cts_work);
+	}
+
+	/* ERP Slottime */
+	if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_SLOT)) {
+		__le32 slot_time = info->use_short_slot ?
+			__cpu_to_le32(9) : __cpu_to_le32(20);
+		pr_debug("[STA] Slot time: %d us.\n",
+			 __le32_to_cpu(slot_time));
+		wsm_write_mib(priv, WSM_MIB_ID_DOT11_SLOT_TIME,
+			      &slot_time, sizeof(slot_time));
+	}
+
+	if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_CQM)) {
+		struct wsm_rcpi_rssi_threshold threshold = {
+			.rollingAverageCount = 8,
+		};
+		pr_debug("[CQM] RSSI threshold subscribe: %d +- %d\n",
+			 info->cqm_rssi_thold, info->cqm_rssi_hyst);
+		priv->cqm_rssi_thold = info->cqm_rssi_thold;
+		priv->cqm_rssi_hyst = info->cqm_rssi_hyst;
+
+		if (info->cqm_rssi_thold || info->cqm_rssi_hyst) {
+			/* RSSI subscription enabled */
+			/* TODO: It's not a correct way of setting threshold.
+			 * Upper and lower must be set equal here and adjusted
+			 * in callback. However current implementation is much
+			 * more relaible and stable.
+			 */
+
+			/* RSSI: signed Q8.0, RCPI: unsigned Q7.1
+			 * RSSI = RCPI / 2 - 110
+			 */
+			if (priv->cqm_use_rssi) {
+				threshold.upperThreshold =
+					info->cqm_rssi_thold + info->cqm_rssi_hyst;
+				threshold.lowerThreshold =
+					info->cqm_rssi_thold;
+				threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
+			} else {
+				threshold.upperThreshold = (info->cqm_rssi_thold + info->cqm_rssi_hyst + 110) * 2;
+				threshold.lowerThreshold = (info->cqm_rssi_thold + 110) * 2;
+			}
+			threshold.rssiRcpiMode |= WSM_RCPI_RSSI_THRESHOLD_ENABLE;
+		} else {
+			/* There is a bug in FW, see sta.c. We have to enable
+			 * dummy subscription to get correct RSSI values.
+			 */
+			threshold.rssiRcpiMode |=
+				WSM_RCPI_RSSI_THRESHOLD_ENABLE |
+				WSM_RCPI_RSSI_DONT_USE_UPPER |
+				WSM_RCPI_RSSI_DONT_USE_LOWER;
+			if (priv->cqm_use_rssi)
+				threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
+		}
+		wsm_set_rcpi_rssi_threshold(priv, &threshold);
+	}
+	mutex_unlock(&priv->conf_mutex);
+
+	if (do_join) {
+		wsm_lock_tx(priv);
+		cw1200_do_join(priv); /* Will unlock it for us */
+	}
+}
+
+void cw1200_multicast_start_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, multicast_start_work);
+	long tmo = priv->join_dtim_period *
+			(priv->beacon_int + 20) * HZ / 1024;
+
+	cancel_work_sync(&priv->multicast_stop_work);
+
+	if (!priv->aid0_bit_set) {
+		wsm_lock_tx(priv);
+		cw1200_set_tim_impl(priv, true);
+		priv->aid0_bit_set = true;
+		mod_timer(&priv->mcast_timeout, jiffies + tmo);
+		wsm_unlock_tx(priv);
+	}
+}
+
+void cw1200_multicast_stop_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, multicast_stop_work);
+
+	if (priv->aid0_bit_set) {
+		del_timer_sync(&priv->mcast_timeout);
+		wsm_lock_tx(priv);
+		priv->aid0_bit_set = false;
+		cw1200_set_tim_impl(priv, false);
+		wsm_unlock_tx(priv);
+	}
+}
+
+void cw1200_mcast_timeout(unsigned long arg)
+{
+	struct cw1200_common *priv =
+		(struct cw1200_common *)arg;
+
+	wiphy_warn(priv->hw->wiphy,
+		   "Multicast delivery timeout.\n");
+	spin_lock_bh(&priv->ps_state_lock);
+	priv->tx_multicast = priv->aid0_bit_set &&
+			priv->buffered_multicasts;
+	if (priv->tx_multicast)
+		cw1200_bh_wakeup(priv);
+	spin_unlock_bh(&priv->ps_state_lock);
+}
+
+int cw1200_ampdu_action(struct ieee80211_hw *hw,
+			struct ieee80211_vif *vif,
+			enum ieee80211_ampdu_mlme_action action,
+			struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+			u8 buf_size)
+{
+	/* Aggregation is implemented fully in firmware,
+	 * including block ack negotiation. Do not allow
+	 * mac80211 stack to do anything: it interferes with
+	 * the firmware.
+	 */
+
+	/* Note that we still need this function stubbed. */
+	return -ENOTSUPP;
+}
+
+/* ******************************************************************** */
+/* WSM callback								*/
+void cw1200_suspend_resume(struct cw1200_common *priv,
+			  struct wsm_suspend_resume *arg)
+{
+	pr_debug("[AP] %s: %s\n",
+		 arg->stop ? "stop" : "start",
+		 arg->multicast ? "broadcast" : "unicast");
+
+	if (arg->multicast) {
+		bool cancel_tmo = false;
+		spin_lock_bh(&priv->ps_state_lock);
+		if (arg->stop) {
+			priv->tx_multicast = false;
+		} else {
+			/* Firmware sends this indication every DTIM if there
+			 * is a STA in powersave connected. There is no reason
+			 * to suspend, following wakeup will consume much more
+			 * power than it could be saved.
+			 */
+			cw1200_pm_stay_awake(&priv->pm_state,
+					     priv->join_dtim_period *
+					     (priv->beacon_int + 20) * HZ / 1024);
+			priv->tx_multicast = (priv->aid0_bit_set &&
+					      priv->buffered_multicasts);
+			if (priv->tx_multicast) {
+				cancel_tmo = true;
+				cw1200_bh_wakeup(priv);
+			}
+		}
+		spin_unlock_bh(&priv->ps_state_lock);
+		if (cancel_tmo)
+			del_timer_sync(&priv->mcast_timeout);
+	} else {
+		spin_lock_bh(&priv->ps_state_lock);
+		cw1200_ps_notify(priv, arg->link_id, arg->stop);
+		spin_unlock_bh(&priv->ps_state_lock);
+		if (!arg->stop)
+			cw1200_bh_wakeup(priv);
+	}
+	return;
+}
+
+/* ******************************************************************** */
+/* AP privates								*/
+
+static int cw1200_upload_beacon(struct cw1200_common *priv)
+{
+	int ret = 0;
+	struct ieee80211_mgmt *mgmt;
+	struct wsm_template_frame frame = {
+		.frame_type = WSM_FRAME_TYPE_BEACON,
+	};
+
+	u16 tim_offset;
+	u16 tim_len;
+
+	if (priv->mode == NL80211_IFTYPE_STATION ||
+	    priv->mode == NL80211_IFTYPE_MONITOR ||
+	    priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+		goto done;
+
+	if (priv->vif->p2p)
+		frame.rate = WSM_TRANSMIT_RATE_6;
+
+	frame.skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
+					     &tim_offset, &tim_len);
+	if (!frame.skb)
+		return -ENOMEM;
+
+	ret = wsm_set_template_frame(priv, &frame);
+
+	if (ret)
+		goto done;
+
+	/* TODO: Distill probe resp; remove TIM
+	 * and any other beacon-specific IEs
+	 */
+	mgmt = (void *)frame.skb->data;
+	mgmt->frame_control =
+		__cpu_to_le16(IEEE80211_FTYPE_MGMT |
+			      IEEE80211_STYPE_PROBE_RESP);
+
+	frame.frame_type = WSM_FRAME_TYPE_PROBE_RESPONSE;
+	if (priv->vif->p2p) {
+		ret = wsm_set_probe_responder(priv, true);
+	} else {
+		ret = wsm_set_template_frame(priv, &frame);
+		wsm_set_probe_responder(priv, false);
+	}
+
+done:
+	dev_kfree_skb(frame.skb);
+
+	return ret;
+}
+
+static int cw1200_upload_pspoll(struct cw1200_common *priv)
+{
+	int ret = 0;
+	struct wsm_template_frame frame = {
+		.frame_type = WSM_FRAME_TYPE_PS_POLL,
+		.rate = 0xFF,
+	};
+
+
+	frame.skb = ieee80211_pspoll_get(priv->hw, priv->vif);
+	if (!frame.skb)
+		return -ENOMEM;
+
+	ret = wsm_set_template_frame(priv, &frame);
+
+	dev_kfree_skb(frame.skb);
+
+	return ret;
+}
+
+static int cw1200_upload_null(struct cw1200_common *priv)
+{
+	int ret = 0;
+	struct wsm_template_frame frame = {
+		.frame_type = WSM_FRAME_TYPE_NULL,
+		.rate = 0xFF,
+	};
+
+	frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
+	if (!frame.skb)
+		return -ENOMEM;
+
+	ret = wsm_set_template_frame(priv, &frame);
+
+	dev_kfree_skb(frame.skb);
+
+	return ret;
+}
+
+static int cw1200_upload_qosnull(struct cw1200_common *priv)
+{
+	int ret = 0;
+	/* TODO:  This needs to be implemented
+
+	struct wsm_template_frame frame = {
+		.frame_type = WSM_FRAME_TYPE_QOS_NULL,
+		.rate = 0xFF,
+	};
+
+	frame.skb = ieee80211_qosnullfunc_get(priv->hw, priv->vif);
+	if (!frame.skb)
+		return -ENOMEM;
+
+	ret = wsm_set_template_frame(priv, &frame);
+
+	dev_kfree_skb(frame.skb);
+
+	*/
+	return ret;
+}
+
+static int cw1200_enable_beaconing(struct cw1200_common *priv,
+				   bool enable)
+{
+	struct wsm_beacon_transmit transmit = {
+		.enable_beaconing = enable,
+	};
+
+	return wsm_beacon_transmit(priv, &transmit);
+}
+
+static int cw1200_start_ap(struct cw1200_common *priv)
+{
+	int ret;
+	struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
+	struct wsm_start start = {
+		.mode = priv->vif->p2p ?
+				WSM_START_MODE_P2P_GO : WSM_START_MODE_AP,
+		.band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
+				WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G,
+		.channel_number = priv->channel->hw_value,
+		.beacon_interval = conf->beacon_int,
+		.dtim_period = conf->dtim_period,
+		.preamble = conf->use_short_preamble ?
+				WSM_JOIN_PREAMBLE_SHORT :
+				WSM_JOIN_PREAMBLE_LONG,
+		.probe_delay = 100,
+		.basic_rate_set = cw1200_rate_mask_to_wsm(priv,
+				conf->basic_rates),
+	};
+	struct wsm_operational_mode mode = {
+		.power_mode = cw1200_power_mode,
+		.disable_more_flag_usage = true,
+	};
+
+	memset(start.ssid, 0, sizeof(start.ssid));
+	if (!conf->hidden_ssid) {
+		start.ssid_len = conf->ssid_len;
+		memcpy(start.ssid, conf->ssid, start.ssid_len);
+	}
+
+	priv->beacon_int = conf->beacon_int;
+	priv->join_dtim_period = conf->dtim_period;
+
+	memset(&priv->link_id_db, 0, sizeof(priv->link_id_db));
+
+	pr_debug("[AP] ch: %d(%d), bcn: %d(%d), brt: 0x%.8X, ssid: %.*s.\n",
+		 start.channel_number, start.band,
+		 start.beacon_interval, start.dtim_period,
+		 start.basic_rate_set,
+		 start.ssid_len, start.ssid);
+	ret = wsm_start(priv, &start);
+	if (!ret)
+		ret = cw1200_upload_keys(priv);
+	if (!ret && priv->vif->p2p) {
+		pr_debug("[AP] Setting p2p powersave configuration.\n");
+		wsm_set_p2p_ps_modeinfo(priv, &priv->p2p_ps_modeinfo);
+	}
+	if (!ret) {
+		wsm_set_block_ack_policy(priv, 0, 0);
+		priv->join_status = CW1200_JOIN_STATUS_AP;
+		cw1200_update_filtering(priv);
+	}
+	wsm_set_operational_mode(priv, &mode);
+	return ret;
+}
+
+static int cw1200_update_beaconing(struct cw1200_common *priv)
+{
+	struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
+	struct wsm_reset reset = {
+		.link_id = 0,
+		.reset_statistics = true,
+	};
+
+	if (priv->mode == NL80211_IFTYPE_AP) {
+		/* TODO: check if changed channel, band */
+		if (priv->join_status != CW1200_JOIN_STATUS_AP ||
+		    priv->beacon_int != conf->beacon_int) {
+			pr_debug("ap restarting\n");
+			wsm_lock_tx(priv);
+			if (priv->join_status != CW1200_JOIN_STATUS_PASSIVE)
+				wsm_reset(priv, &reset);
+			priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
+			cw1200_start_ap(priv);
+			wsm_unlock_tx(priv);
+		} else
+			pr_debug("ap started join_status: %d\n",
+				 priv->join_status);
+	}
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/sta.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/sta.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/sta.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/sta.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,123 @@
+/*
+ * Mac80211 STA interface for ST-Ericsson CW1200 mac80211 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef STA_H_INCLUDED
+#define STA_H_INCLUDED
+
+/* ******************************************************************** */
+/* mac80211 API								*/
+
+int cw1200_start(struct ieee80211_hw *dev);
+void cw1200_stop(struct ieee80211_hw *dev);
+int cw1200_add_interface(struct ieee80211_hw *dev,
+			 struct ieee80211_vif *vif);
+void cw1200_remove_interface(struct ieee80211_hw *dev,
+			     struct ieee80211_vif *vif);
+int cw1200_change_interface(struct ieee80211_hw *dev,
+			    struct ieee80211_vif *vif,
+			    enum nl80211_iftype new_type,
+			    bool p2p);
+int cw1200_config(struct ieee80211_hw *dev, u32 changed);
+void cw1200_configure_filter(struct ieee80211_hw *dev,
+			     unsigned int changed_flags,
+			     unsigned int *total_flags,
+			     u64 multicast);
+int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
+		   u16 queue, const struct ieee80211_tx_queue_params *params);
+int cw1200_get_stats(struct ieee80211_hw *dev,
+		     struct ieee80211_low_level_stats *stats);
+int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
+		   struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+		   struct ieee80211_key_conf *key);
+
+int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
+
+void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
+
+u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
+			     struct netdev_hw_addr_list *mc_list);
+
+int cw1200_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg);
+
+/* ******************************************************************** */
+/* WSM callbacks							*/
+
+void cw1200_join_complete_cb(struct cw1200_common *priv,
+				struct wsm_join_complete *arg);
+
+/* ******************************************************************** */
+/* WSM events								*/
+
+void cw1200_free_event_queue(struct cw1200_common *priv);
+void cw1200_event_handler(struct work_struct *work);
+void cw1200_bss_loss_work(struct work_struct *work);
+void cw1200_bss_params_work(struct work_struct *work);
+void cw1200_keep_alive_work(struct work_struct *work);
+void cw1200_tx_failure_work(struct work_struct *work);
+
+void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv, int init, int good,
+			     int bad);
+static inline void cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
+					 int init, int good, int bad)
+{
+	spin_lock(&priv->bss_loss_lock);
+	__cw1200_cqm_bssloss_sm(priv, init, good, bad);
+	spin_unlock(&priv->bss_loss_lock);
+}
+
+/* ******************************************************************** */
+/* Internal API								*/
+
+int cw1200_setup_mac(struct cw1200_common *priv);
+void cw1200_join_timeout(struct work_struct *work);
+void cw1200_unjoin_work(struct work_struct *work);
+void cw1200_join_complete_work(struct work_struct *work);
+void cw1200_wep_key_work(struct work_struct *work);
+void cw1200_update_listening(struct cw1200_common *priv, bool enabled);
+void cw1200_update_filtering(struct cw1200_common *priv);
+void cw1200_update_filtering_work(struct work_struct *work);
+void cw1200_set_beacon_wakeup_period_work(struct work_struct *work);
+int cw1200_enable_listening(struct cw1200_common *priv);
+int cw1200_disable_listening(struct cw1200_common *priv);
+int cw1200_set_uapsd_param(struct cw1200_common *priv,
+				const struct wsm_edca_params *arg);
+void cw1200_ba_work(struct work_struct *work);
+void cw1200_ba_timer(unsigned long arg);
+
+/* AP stuffs */
+int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
+		   bool set);
+int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		   struct ieee80211_sta *sta);
+int cw1200_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		      struct ieee80211_sta *sta);
+void cw1200_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
+		       enum sta_notify_cmd notify_cmd,
+		       struct ieee80211_sta *sta);
+void cw1200_bss_info_changed(struct ieee80211_hw *dev,
+			     struct ieee80211_vif *vif,
+			     struct ieee80211_bss_conf *info,
+			     u32 changed);
+int cw1200_ampdu_action(struct ieee80211_hw *hw,
+			struct ieee80211_vif *vif,
+			enum ieee80211_ampdu_mlme_action action,
+			struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+			u8 buf_size);
+
+void cw1200_suspend_resume(struct cw1200_common *priv,
+			  struct wsm_suspend_resume *arg);
+void cw1200_set_tim_work(struct work_struct *work);
+void cw1200_set_cts_work(struct work_struct *work);
+void cw1200_multicast_start_work(struct work_struct *work);
+void cw1200_multicast_stop_work(struct work_struct *work);
+void cw1200_mcast_timeout(unsigned long arg);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/txrx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/txrx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/txrx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/txrx.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1473 @@
+/*
+ * Datapath implementation for ST-Ericsson CW1200 mac80211 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include "cw1200.h"
+#include "wsm.h"
+#include "bh.h"
+#include "sta.h"
+#include "debug.h"
+
+#define CW1200_INVALID_RATE_ID (0xFF)
+
+static int cw1200_handle_action_rx(struct cw1200_common *priv,
+				   struct sk_buff *skb);
+static const struct ieee80211_rate *
+cw1200_get_tx_rate(const struct cw1200_common *priv,
+		   const struct ieee80211_tx_rate *rate);
+
+/* ******************************************************************** */
+/* TX queue lock / unlock						*/
+
+static inline void cw1200_tx_queues_lock(struct cw1200_common *priv)
+{
+	int i;
+	for (i = 0; i < 4; ++i)
+		cw1200_queue_lock(&priv->tx_queue[i]);
+}
+
+static inline void cw1200_tx_queues_unlock(struct cw1200_common *priv)
+{
+	int i;
+	for (i = 0; i < 4; ++i)
+		cw1200_queue_unlock(&priv->tx_queue[i]);
+}
+
+/* ******************************************************************** */
+/* TX policy cache implementation					*/
+
+static void tx_policy_dump(struct tx_policy *policy)
+{
+	pr_debug("[TX policy] %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X: %d\n",
+		 policy->raw[0] & 0x0F,  policy->raw[0] >> 4,
+		 policy->raw[1] & 0x0F,  policy->raw[1] >> 4,
+		 policy->raw[2] & 0x0F,  policy->raw[2] >> 4,
+		 policy->raw[3] & 0x0F,  policy->raw[3] >> 4,
+		 policy->raw[4] & 0x0F,  policy->raw[4] >> 4,
+		 policy->raw[5] & 0x0F,  policy->raw[5] >> 4,
+		 policy->raw[6] & 0x0F,  policy->raw[6] >> 4,
+		 policy->raw[7] & 0x0F,  policy->raw[7] >> 4,
+		 policy->raw[8] & 0x0F,  policy->raw[8] >> 4,
+		 policy->raw[9] & 0x0F,  policy->raw[9] >> 4,
+		 policy->raw[10] & 0x0F,  policy->raw[10] >> 4,
+		 policy->raw[11] & 0x0F,  policy->raw[11] >> 4,
+		 policy->defined);
+}
+
+static void tx_policy_build(const struct cw1200_common *priv,
+	/* [out] */ struct tx_policy *policy,
+	struct ieee80211_tx_rate *rates, size_t count)
+{
+	int i, j;
+	unsigned limit = priv->short_frame_max_tx_count;
+	unsigned total = 0;
+	BUG_ON(rates[0].idx < 0);
+	memset(policy, 0, sizeof(*policy));
+
+	/* Sort rates in descending order. */
+	for (i = 1; i < count; ++i) {
+		if (rates[i].idx < 0) {
+			count = i;
+			break;
+		}
+		if (rates[i].idx > rates[i - 1].idx) {
+			struct ieee80211_tx_rate tmp = rates[i - 1];
+			rates[i - 1] = rates[i];
+			rates[i] = tmp;
+		}
+	}
+
+	/* Eliminate duplicates. */
+	total = rates[0].count;
+	for (i = 0, j = 1; j < count; ++j) {
+		if (rates[j].idx == rates[i].idx) {
+			rates[i].count += rates[j].count;
+		} else if (rates[j].idx > rates[i].idx) {
+			break;
+		} else {
+			++i;
+			if (i != j)
+				rates[i] = rates[j];
+		}
+		total += rates[j].count;
+	}
+	count = i + 1;
+
+	/* Re-fill policy trying to keep every requested rate and with
+	 * respect to the global max tx retransmission count.
+	 */
+	if (limit < count)
+		limit = count;
+	if (total > limit) {
+		for (i = 0; i < count; ++i) {
+			int left = count - i - 1;
+			if (rates[i].count > limit - left)
+				rates[i].count = limit - left;
+			limit -= rates[i].count;
+		}
+	}
+
+	/* HACK!!! Device has problems (at least) switching from
+	 * 54Mbps CTS to 1Mbps. This switch takes enormous amount
+	 * of time (100-200 ms), leading to valuable throughput drop.
+	 * As a workaround, additional g-rates are injected to the
+	 * policy.
+	 */
+	if (count == 2 && !(rates[0].flags & IEEE80211_TX_RC_MCS) &&
+	    rates[0].idx > 4 && rates[0].count > 2 &&
+	    rates[1].idx < 2) {
+		int mid_rate = (rates[0].idx + 4) >> 1;
+
+		/* Decrease number of retries for the initial rate */
+		rates[0].count -= 2;
+
+		if (mid_rate != 4) {
+			/* Keep fallback rate at 1Mbps. */
+			rates[3] = rates[1];
+
+			/* Inject 1 transmission on lowest g-rate */
+			rates[2].idx = 4;
+			rates[2].count = 1;
+			rates[2].flags = rates[1].flags;
+
+			/* Inject 1 transmission on mid-rate */
+			rates[1].idx = mid_rate;
+			rates[1].count = 1;
+
+			/* Fallback to 1 Mbps is a really bad thing,
+			 * so let's try to increase probability of
+			 * successful transmission on the lowest g rate
+			 * even more
+			 */
+			if (rates[0].count >= 3) {
+				--rates[0].count;
+				++rates[2].count;
+			}
+
+			/* Adjust amount of rates defined */
+			count += 2;
+		} else {
+			/* Keep fallback rate at 1Mbps. */
+			rates[2] = rates[1];
+
+			/* Inject 2 transmissions on lowest g-rate */
+			rates[1].idx = 4;
+			rates[1].count = 2;
+
+			/* Adjust amount of rates defined */
+			count += 1;
+		}
+	}
+
+	policy->defined = cw1200_get_tx_rate(priv, &rates[0])->hw_value + 1;
+
+	for (i = 0; i < count; ++i) {
+		register unsigned rateid, off, shift, retries;
+
+		rateid = cw1200_get_tx_rate(priv, &rates[i])->hw_value;
+		off = rateid >> 3;		/* eq. rateid / 8 */
+		shift = (rateid & 0x07) << 2;	/* eq. (rateid % 8) * 4 */
+
+		retries = rates[i].count;
+		if (retries > 0x0F) {
+			rates[i].count = 0x0f;
+			retries = 0x0F;
+		}
+		policy->tbl[off] |= __cpu_to_le32(retries << shift);
+		policy->retry_count += retries;
+	}
+
+	pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d\n",
+		 count,
+		 rates[0].idx, rates[0].count,
+		 rates[1].idx, rates[1].count,
+		 rates[2].idx, rates[2].count,
+		 rates[3].idx, rates[3].count);
+}
+
+static inline bool tx_policy_is_equal(const struct tx_policy *wanted,
+					const struct tx_policy *cached)
+{
+	size_t count = wanted->defined >> 1;
+	if (wanted->defined > cached->defined)
+		return false;
+	if (count) {
+		if (memcmp(wanted->raw, cached->raw, count))
+			return false;
+	}
+	if (wanted->defined & 1) {
+		if ((wanted->raw[count] & 0x0F) != (cached->raw[count] & 0x0F))
+			return false;
+	}
+	return true;
+}
+
+static int tx_policy_find(struct tx_policy_cache *cache,
+				const struct tx_policy *wanted)
+{
+	/* O(n) complexity. Not so good, but there's only 8 entries in
+	 * the cache.
+	 * Also lru helps to reduce search time.
+	 */
+	struct tx_policy_cache_entry *it;
+	/* First search for policy in "used" list */
+	list_for_each_entry(it, &cache->used, link) {
+		if (tx_policy_is_equal(wanted, &it->policy))
+			return it - cache->cache;
+	}
+	/* Then - in "free list" */
+	list_for_each_entry(it, &cache->free, link) {
+		if (tx_policy_is_equal(wanted, &it->policy))
+			return it - cache->cache;
+	}
+	return -1;
+}
+
+static inline void tx_policy_use(struct tx_policy_cache *cache,
+				 struct tx_policy_cache_entry *entry)
+{
+	++entry->policy.usage_count;
+	list_move(&entry->link, &cache->used);
+}
+
+static inline int tx_policy_release(struct tx_policy_cache *cache,
+				    struct tx_policy_cache_entry *entry)
+{
+	int ret = --entry->policy.usage_count;
+	if (!ret)
+		list_move(&entry->link, &cache->free);
+	return ret;
+}
+
+void tx_policy_clean(struct cw1200_common *priv)
+{
+	int idx, locked;
+	struct tx_policy_cache *cache = &priv->tx_policy_cache;
+	struct tx_policy_cache_entry *entry;
+
+	cw1200_tx_queues_lock(priv);
+	spin_lock_bh(&cache->lock);
+	locked = list_empty(&cache->free);
+
+	for (idx = 0; idx < TX_POLICY_CACHE_SIZE; idx++) {
+		entry = &cache->cache[idx];
+		/* Policy usage count should be 0 at this time as all queues
+		   should be empty
+		 */
+		if (WARN_ON(entry->policy.usage_count)) {
+			entry->policy.usage_count = 0;
+			list_move(&entry->link, &cache->free);
+		}
+		memset(&entry->policy, 0, sizeof(entry->policy));
+	}
+	if (locked)
+		cw1200_tx_queues_unlock(priv);
+
+	cw1200_tx_queues_unlock(priv);
+	spin_unlock_bh(&cache->lock);
+}
+
+/* ******************************************************************** */
+/* External TX policy cache API						*/
+
+void tx_policy_init(struct cw1200_common *priv)
+{
+	struct tx_policy_cache *cache = &priv->tx_policy_cache;
+	int i;
+
+	memset(cache, 0, sizeof(*cache));
+
+	spin_lock_init(&cache->lock);
+	INIT_LIST_HEAD(&cache->used);
+	INIT_LIST_HEAD(&cache->free);
+
+	for (i = 0; i < TX_POLICY_CACHE_SIZE; ++i)
+		list_add(&cache->cache[i].link, &cache->free);
+}
+
+static int tx_policy_get(struct cw1200_common *priv,
+		  struct ieee80211_tx_rate *rates,
+		  size_t count, bool *renew)
+{
+	int idx;
+	struct tx_policy_cache *cache = &priv->tx_policy_cache;
+	struct tx_policy wanted;
+
+	tx_policy_build(priv, &wanted, rates, count);
+
+	spin_lock_bh(&cache->lock);
+	if (WARN_ON_ONCE(list_empty(&cache->free))) {
+		spin_unlock_bh(&cache->lock);
+		return CW1200_INVALID_RATE_ID;
+	}
+	idx = tx_policy_find(cache, &wanted);
+	if (idx >= 0) {
+		pr_debug("[TX policy] Used TX policy: %d\n", idx);
+		*renew = false;
+	} else {
+		struct tx_policy_cache_entry *entry;
+		*renew = true;
+		/* If policy is not found create a new one
+		 * using the oldest entry in "free" list
+		 */
+		entry = list_entry(cache->free.prev,
+			struct tx_policy_cache_entry, link);
+		entry->policy = wanted;
+		idx = entry - cache->cache;
+		pr_debug("[TX policy] New TX policy: %d\n", idx);
+		tx_policy_dump(&entry->policy);
+	}
+	tx_policy_use(cache, &cache->cache[idx]);
+	if (list_empty(&cache->free)) {
+		/* Lock TX queues. */
+		cw1200_tx_queues_lock(priv);
+	}
+	spin_unlock_bh(&cache->lock);
+	return idx;
+}
+
+static void tx_policy_put(struct cw1200_common *priv, int idx)
+{
+	int usage, locked;
+	struct tx_policy_cache *cache = &priv->tx_policy_cache;
+
+	spin_lock_bh(&cache->lock);
+	locked = list_empty(&cache->free);
+	usage = tx_policy_release(cache, &cache->cache[idx]);
+	if (locked && !usage) {
+		/* Unlock TX queues. */
+		cw1200_tx_queues_unlock(priv);
+	}
+	spin_unlock_bh(&cache->lock);
+}
+
+static int tx_policy_upload(struct cw1200_common *priv)
+{
+	struct tx_policy_cache *cache = &priv->tx_policy_cache;
+	int i;
+	struct wsm_set_tx_rate_retry_policy arg = {
+		.num = 0,
+	};
+	spin_lock_bh(&cache->lock);
+
+	/* Upload only modified entries. */
+	for (i = 0; i < TX_POLICY_CACHE_SIZE; ++i) {
+		struct tx_policy *src = &cache->cache[i].policy;
+		if (src->retry_count && !src->uploaded) {
+			struct wsm_tx_rate_retry_policy *dst =
+				&arg.tbl[arg.num];
+			dst->index = i;
+			dst->short_retries = priv->short_frame_max_tx_count;
+			dst->long_retries = priv->long_frame_max_tx_count;
+
+			dst->flags = WSM_TX_RATE_POLICY_FLAG_TERMINATE_WHEN_FINISHED |
+				WSM_TX_RATE_POLICY_FLAG_COUNT_INITIAL_TRANSMIT;
+			memcpy(dst->rate_count_indices, src->tbl,
+			       sizeof(dst->rate_count_indices));
+			src->uploaded = 1;
+			++arg.num;
+		}
+	}
+	spin_unlock_bh(&cache->lock);
+	cw1200_debug_tx_cache_miss(priv);
+	pr_debug("[TX policy] Upload %d policies\n", arg.num);
+	return wsm_set_tx_rate_retry_policy(priv, &arg);
+}
+
+void tx_policy_upload_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, tx_policy_upload_work);
+
+	pr_debug("[TX] TX policy upload.\n");
+	tx_policy_upload(priv);
+
+	wsm_unlock_tx(priv);
+	cw1200_tx_queues_unlock(priv);
+}
+
+/* ******************************************************************** */
+/* cw1200 TX implementation						*/
+
+struct cw1200_txinfo {
+	struct sk_buff *skb;
+	unsigned queue;
+	struct ieee80211_tx_info *tx_info;
+	const struct ieee80211_rate *rate;
+	struct ieee80211_hdr *hdr;
+	size_t hdrlen;
+	const u8 *da;
+	struct cw1200_sta_priv *sta_priv;
+	struct ieee80211_sta *sta;
+	struct cw1200_txpriv txpriv;
+};
+
+u32 cw1200_rate_mask_to_wsm(struct cw1200_common *priv, u32 rates)
+{
+	u32 ret = 0;
+	int i;
+	for (i = 0; i < 32; ++i) {
+		if (rates & BIT(i))
+			ret |= BIT(priv->rates[i].hw_value);
+	}
+	return ret;
+}
+
+static const struct ieee80211_rate *
+cw1200_get_tx_rate(const struct cw1200_common *priv,
+		   const struct ieee80211_tx_rate *rate)
+{
+	if (rate->idx < 0)
+		return NULL;
+	if (rate->flags & IEEE80211_TX_RC_MCS)
+		return &priv->mcs_rates[rate->idx];
+	return &priv->hw->wiphy->bands[priv->channel->band]->
+		bitrates[rate->idx];
+}
+
+static int
+cw1200_tx_h_calc_link_ids(struct cw1200_common *priv,
+			  struct cw1200_txinfo *t)
+{
+	if (t->sta && t->sta_priv->link_id)
+		t->txpriv.raw_link_id =
+				t->txpriv.link_id =
+				t->sta_priv->link_id;
+	else if (priv->mode != NL80211_IFTYPE_AP)
+		t->txpriv.raw_link_id =
+				t->txpriv.link_id = 0;
+	else if (is_multicast_ether_addr(t->da)) {
+		if (priv->enable_beacon) {
+			t->txpriv.raw_link_id = 0;
+			t->txpriv.link_id = CW1200_LINK_ID_AFTER_DTIM;
+		} else {
+			t->txpriv.raw_link_id = 0;
+			t->txpriv.link_id = 0;
+		}
+	} else {
+		t->txpriv.link_id = cw1200_find_link_id(priv, t->da);
+		if (!t->txpriv.link_id)
+			t->txpriv.link_id = cw1200_alloc_link_id(priv, t->da);
+		if (!t->txpriv.link_id) {
+			wiphy_err(priv->hw->wiphy,
+				  "No more link IDs available.\n");
+			return -ENOENT;
+		}
+		t->txpriv.raw_link_id = t->txpriv.link_id;
+	}
+	if (t->txpriv.raw_link_id)
+		priv->link_id_db[t->txpriv.raw_link_id - 1].timestamp =
+				jiffies;
+	if (t->sta && (t->sta->uapsd_queues & BIT(t->queue)))
+		t->txpriv.link_id = CW1200_LINK_ID_UAPSD;
+	return 0;
+}
+
+static void
+cw1200_tx_h_pm(struct cw1200_common *priv,
+	       struct cw1200_txinfo *t)
+{
+	if (ieee80211_is_auth(t->hdr->frame_control)) {
+		u32 mask = ~BIT(t->txpriv.raw_link_id);
+		spin_lock_bh(&priv->ps_state_lock);
+		priv->sta_asleep_mask &= mask;
+		priv->pspoll_mask &= mask;
+		spin_unlock_bh(&priv->ps_state_lock);
+	}
+}
+
+static void
+cw1200_tx_h_calc_tid(struct cw1200_common *priv,
+		     struct cw1200_txinfo *t)
+{
+	if (ieee80211_is_data_qos(t->hdr->frame_control)) {
+		u8 *qos = ieee80211_get_qos_ctl(t->hdr);
+		t->txpriv.tid = qos[0] & IEEE80211_QOS_CTL_TID_MASK;
+	} else if (ieee80211_is_data(t->hdr->frame_control)) {
+		t->txpriv.tid = 0;
+	}
+}
+
+static int
+cw1200_tx_h_crypt(struct cw1200_common *priv,
+		  struct cw1200_txinfo *t)
+{
+	if (!t->tx_info->control.hw_key ||
+	    !ieee80211_has_protected(t->hdr->frame_control))
+		return 0;
+
+	t->hdrlen += t->tx_info->control.hw_key->iv_len;
+	skb_put(t->skb, t->tx_info->control.hw_key->icv_len);
+
+	if (t->tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
+		skb_put(t->skb, 8); /* MIC space */
+
+	return 0;
+}
+
+static int
+cw1200_tx_h_align(struct cw1200_common *priv,
+		  struct cw1200_txinfo *t,
+		  u8 *flags)
+{
+	size_t offset = (size_t)t->skb->data & 3;
+
+	if (!offset)
+		return 0;
+
+	if (offset & 1) {
+		wiphy_err(priv->hw->wiphy,
+			  "Bug: attempt to transmit a frame with wrong alignment: %zu\n",
+			  offset);
+		return -EINVAL;
+	}
+
+	if (skb_headroom(t->skb) < offset) {
+		wiphy_err(priv->hw->wiphy,
+			  "Bug: no space allocated for DMA alignment. headroom: %d\n",
+			  skb_headroom(t->skb));
+		return -ENOMEM;
+	}
+	skb_push(t->skb, offset);
+	t->hdrlen += offset;
+	t->txpriv.offset += offset;
+	*flags |= WSM_TX_2BYTES_SHIFT;
+	cw1200_debug_tx_align(priv);
+	return 0;
+}
+
+static int
+cw1200_tx_h_action(struct cw1200_common *priv,
+		   struct cw1200_txinfo *t)
+{
+	struct ieee80211_mgmt *mgmt =
+		(struct ieee80211_mgmt *)t->hdr;
+	if (ieee80211_is_action(t->hdr->frame_control) &&
+	    mgmt->u.action.category == WLAN_CATEGORY_BACK)
+		return 1;
+	else
+		return 0;
+}
+
+/* Add WSM header */
+static struct wsm_tx *
+cw1200_tx_h_wsm(struct cw1200_common *priv,
+		struct cw1200_txinfo *t)
+{
+	struct wsm_tx *wsm;
+
+	if (skb_headroom(t->skb) < sizeof(struct wsm_tx)) {
+		wiphy_err(priv->hw->wiphy,
+			  "Bug: no space allocated for WSM header. headroom: %d\n",
+			  skb_headroom(t->skb));
+		return NULL;
+	}
+
+	wsm = (struct wsm_tx *)skb_push(t->skb, sizeof(struct wsm_tx));
+	t->txpriv.offset += sizeof(struct wsm_tx);
+	memset(wsm, 0, sizeof(*wsm));
+	wsm->hdr.len = __cpu_to_le16(t->skb->len);
+	wsm->hdr.id = __cpu_to_le16(0x0004);
+	wsm->queue_id = wsm_queue_id_to_wsm(t->queue);
+	return wsm;
+}
+
+/* BT Coex specific handling */
+static void
+cw1200_tx_h_bt(struct cw1200_common *priv,
+	       struct cw1200_txinfo *t,
+	       struct wsm_tx *wsm)
+{
+	u8 priority = 0;
+
+	if (!priv->bt_present)
+		return;
+
+	if (ieee80211_is_nullfunc(t->hdr->frame_control)) {
+		priority = WSM_EPTA_PRIORITY_MGT;
+	} else if (ieee80211_is_data(t->hdr->frame_control)) {
+		/* Skip LLC SNAP header (+6) */
+		u8 *payload = &t->skb->data[t->hdrlen];
+		__be16 *ethertype = (__be16 *)&payload[6];
+		if (be16_to_cpu(*ethertype) == ETH_P_PAE)
+			priority = WSM_EPTA_PRIORITY_EAPOL;
+	} else if (ieee80211_is_assoc_req(t->hdr->frame_control) ||
+		ieee80211_is_reassoc_req(t->hdr->frame_control)) {
+		struct ieee80211_mgmt *mgt_frame =
+				(struct ieee80211_mgmt *)t->hdr;
+
+		if (le16_to_cpu(mgt_frame->u.assoc_req.listen_interval) <
+						priv->listen_interval) {
+			pr_debug("Modified Listen Interval to %d from %d\n",
+				 priv->listen_interval,
+				 mgt_frame->u.assoc_req.listen_interval);
+			/* Replace listen interval derieved from
+			 * the one read from SDD
+			 */
+			mgt_frame->u.assoc_req.listen_interval = cpu_to_le16(priv->listen_interval);
+		}
+	}
+
+	if (!priority) {
+		if (ieee80211_is_action(t->hdr->frame_control))
+			priority = WSM_EPTA_PRIORITY_ACTION;
+		else if (ieee80211_is_mgmt(t->hdr->frame_control))
+			priority = WSM_EPTA_PRIORITY_MGT;
+		else if ((wsm->queue_id == WSM_QUEUE_VOICE))
+			priority = WSM_EPTA_PRIORITY_VOICE;
+		else if ((wsm->queue_id == WSM_QUEUE_VIDEO))
+			priority = WSM_EPTA_PRIORITY_VIDEO;
+		else
+			priority = WSM_EPTA_PRIORITY_DATA;
+	}
+
+	pr_debug("[TX] EPTA priority %d.\n", priority);
+
+	wsm->flags |= priority << 1;
+}
+
+static int
+cw1200_tx_h_rate_policy(struct cw1200_common *priv,
+			struct cw1200_txinfo *t,
+			struct wsm_tx *wsm)
+{
+	bool tx_policy_renew = false;
+
+	t->txpriv.rate_id = tx_policy_get(priv,
+		t->tx_info->control.rates, IEEE80211_TX_MAX_RATES,
+		&tx_policy_renew);
+	if (t->txpriv.rate_id == CW1200_INVALID_RATE_ID)
+		return -EFAULT;
+
+	wsm->flags |= t->txpriv.rate_id << 4;
+
+	t->rate = cw1200_get_tx_rate(priv,
+		&t->tx_info->control.rates[0]),
+	wsm->max_tx_rate = t->rate->hw_value;
+	if (t->rate->flags & IEEE80211_TX_RC_MCS) {
+		if (cw1200_ht_greenfield(&priv->ht_info))
+			wsm->ht_tx_parameters |=
+				__cpu_to_le32(WSM_HT_TX_GREENFIELD);
+		else
+			wsm->ht_tx_parameters |=
+				__cpu_to_le32(WSM_HT_TX_MIXED);
+	}
+
+	if (tx_policy_renew) {
+		pr_debug("[TX] TX policy renew.\n");
+		/* It's not so optimal to stop TX queues every now and then.
+		 * Better to reimplement task scheduling with
+		 * a counter. TODO.
+		 */
+		wsm_lock_tx_async(priv);
+		cw1200_tx_queues_lock(priv);
+		if (queue_work(priv->workqueue,
+			       &priv->tx_policy_upload_work) <= 0) {
+			cw1200_tx_queues_unlock(priv);
+			wsm_unlock_tx(priv);
+		}
+	}
+	return 0;
+}
+
+static bool
+cw1200_tx_h_pm_state(struct cw1200_common *priv,
+		     struct cw1200_txinfo *t)
+{
+	int was_buffered = 1;
+
+	if (t->txpriv.link_id == CW1200_LINK_ID_AFTER_DTIM &&
+	    !priv->buffered_multicasts) {
+		priv->buffered_multicasts = true;
+		if (priv->sta_asleep_mask)
+			queue_work(priv->workqueue,
+				   &priv->multicast_start_work);
+	}
+
+	if (t->txpriv.raw_link_id && t->txpriv.tid < CW1200_MAX_TID)
+		was_buffered = priv->link_id_db[t->txpriv.raw_link_id - 1].buffered[t->txpriv.tid]++;
+
+	return !was_buffered;
+}
+
+/* ******************************************************************** */
+
+void cw1200_tx(struct ieee80211_hw *dev,
+	       struct ieee80211_tx_control *control,
+	       struct sk_buff *skb)
+{
+	struct cw1200_common *priv = dev->priv;
+	struct cw1200_txinfo t = {
+		.skb = skb,
+		.queue = skb_get_queue_mapping(skb),
+		.tx_info = IEEE80211_SKB_CB(skb),
+		.hdr = (struct ieee80211_hdr *)skb->data,
+		.txpriv.tid = CW1200_MAX_TID,
+		.txpriv.rate_id = CW1200_INVALID_RATE_ID,
+	};
+	struct ieee80211_sta *sta;
+	struct wsm_tx *wsm;
+	bool tid_update = 0;
+	u8 flags = 0;
+	int ret;
+
+	if (priv->bh_error)
+		goto drop;
+
+	t.hdrlen = ieee80211_hdrlen(t.hdr->frame_control);
+	t.da = ieee80211_get_DA(t.hdr);
+	if (control) {
+		t.sta = control->sta;
+		t.sta_priv = (struct cw1200_sta_priv *)&t.sta->drv_priv;
+	}
+
+	if (WARN_ON(t.queue >= 4))
+		goto drop;
+
+	ret = cw1200_tx_h_calc_link_ids(priv, &t);
+	if (ret)
+		goto drop;
+
+	pr_debug("[TX] TX %d bytes (queue: %d, link_id: %d (%d)).\n",
+		 skb->len, t.queue, t.txpriv.link_id,
+		 t.txpriv.raw_link_id);
+
+	cw1200_tx_h_pm(priv, &t);
+	cw1200_tx_h_calc_tid(priv, &t);
+	ret = cw1200_tx_h_crypt(priv, &t);
+	if (ret)
+		goto drop;
+	ret = cw1200_tx_h_align(priv, &t, &flags);
+	if (ret)
+		goto drop;
+	ret = cw1200_tx_h_action(priv, &t);
+	if (ret)
+		goto drop;
+	wsm = cw1200_tx_h_wsm(priv, &t);
+	if (!wsm) {
+		ret = -ENOMEM;
+		goto drop;
+	}
+	wsm->flags |= flags;
+	cw1200_tx_h_bt(priv, &t, wsm);
+	ret = cw1200_tx_h_rate_policy(priv, &t, wsm);
+	if (ret)
+		goto drop;
+
+	rcu_read_lock();
+	sta = rcu_dereference(t.sta);
+
+	spin_lock_bh(&priv->ps_state_lock);
+	{
+		tid_update = cw1200_tx_h_pm_state(priv, &t);
+		BUG_ON(cw1200_queue_put(&priv->tx_queue[t.queue],
+					t.skb, &t.txpriv));
+	}
+	spin_unlock_bh(&priv->ps_state_lock);
+
+	if (tid_update && sta)
+		ieee80211_sta_set_buffered(sta, t.txpriv.tid, true);
+
+	rcu_read_unlock();
+
+	cw1200_bh_wakeup(priv);
+
+	return;
+
+drop:
+	cw1200_skb_dtor(priv, skb, &t.txpriv);
+	return;
+}
+
+/* ******************************************************************** */
+
+static int cw1200_handle_action_rx(struct cw1200_common *priv,
+				   struct sk_buff *skb)
+{
+	struct ieee80211_mgmt *mgmt = (void *)skb->data;
+
+	/* Filter block ACK negotiation: fully controlled by firmware */
+	if (mgmt->u.action.category == WLAN_CATEGORY_BACK)
+		return 1;
+
+	return 0;
+}
+
+static int cw1200_handle_pspoll(struct cw1200_common *priv,
+				struct sk_buff *skb)
+{
+	struct ieee80211_sta *sta;
+	struct ieee80211_pspoll *pspoll = (struct ieee80211_pspoll *)skb->data;
+	int link_id = 0;
+	u32 pspoll_mask = 0;
+	int drop = 1;
+	int i;
+
+	if (priv->join_status != CW1200_JOIN_STATUS_AP)
+		goto done;
+	if (memcmp(priv->vif->addr, pspoll->bssid, ETH_ALEN))
+		goto done;
+
+	rcu_read_lock();
+	sta = ieee80211_find_sta(priv->vif, pspoll->ta);
+	if (sta) {
+		struct cw1200_sta_priv *sta_priv;
+		sta_priv = (struct cw1200_sta_priv *)&sta->drv_priv;
+		link_id = sta_priv->link_id;
+		pspoll_mask = BIT(sta_priv->link_id);
+	}
+	rcu_read_unlock();
+	if (!link_id)
+		goto done;
+
+	priv->pspoll_mask |= pspoll_mask;
+	drop = 0;
+
+	/* Do not report pspols if data for given link id is queued already. */
+	for (i = 0; i < 4; ++i) {
+		if (cw1200_queue_get_num_queued(&priv->tx_queue[i],
+						pspoll_mask)) {
+			cw1200_bh_wakeup(priv);
+			drop = 1;
+			break;
+		}
+	}
+	pr_debug("[RX] PSPOLL: %s\n", drop ? "local" : "fwd");
+done:
+	return drop;
+}
+
+/* ******************************************************************** */
+
+void cw1200_tx_confirm_cb(struct cw1200_common *priv,
+			  int link_id,
+			  struct wsm_tx_confirm *arg)
+{
+	u8 queue_id = cw1200_queue_get_queue_id(arg->packet_id);
+	struct cw1200_queue *queue = &priv->tx_queue[queue_id];
+	struct sk_buff *skb;
+	const struct cw1200_txpriv *txpriv;
+
+	pr_debug("[TX] TX confirm: %d, %d.\n",
+		 arg->status, arg->ack_failures);
+
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
+		/* STA is stopped. */
+		return;
+	}
+
+	if (WARN_ON(queue_id >= 4))
+		return;
+
+	if (arg->status)
+		pr_debug("TX failed: %d.\n", arg->status);
+
+	if ((arg->status == WSM_REQUEUE) &&
+	    (arg->flags & WSM_TX_STATUS_REQUEUE)) {
+		/* "Requeue" means "implicit suspend" */
+		struct wsm_suspend_resume suspend = {
+			.link_id = link_id,
+			.stop = 1,
+			.multicast = !link_id,
+		};
+		cw1200_suspend_resume(priv, &suspend);
+		wiphy_warn(priv->hw->wiphy, "Requeue for link_id %d (try %d). STAs asleep: 0x%.8X\n",
+			   link_id,
+			   cw1200_queue_get_generation(arg->packet_id) + 1,
+			   priv->sta_asleep_mask);
+		cw1200_queue_requeue(queue, arg->packet_id);
+		spin_lock_bh(&priv->ps_state_lock);
+		if (!link_id) {
+			priv->buffered_multicasts = true;
+			if (priv->sta_asleep_mask) {
+				queue_work(priv->workqueue,
+					   &priv->multicast_start_work);
+			}
+		}
+		spin_unlock_bh(&priv->ps_state_lock);
+	} else if (!cw1200_queue_get_skb(queue, arg->packet_id,
+					 &skb, &txpriv)) {
+		struct ieee80211_tx_info *tx = IEEE80211_SKB_CB(skb);
+		int tx_count = arg->ack_failures;
+		u8 ht_flags = 0;
+		int i;
+
+		if (cw1200_ht_greenfield(&priv->ht_info))
+			ht_flags |= IEEE80211_TX_RC_GREEN_FIELD;
+
+		spin_lock(&priv->bss_loss_lock);
+		if (priv->bss_loss_state &&
+		    arg->packet_id == priv->bss_loss_confirm_id) {
+			if (arg->status) {
+				/* Recovery failed */
+				__cw1200_cqm_bssloss_sm(priv, 0, 0, 1);
+			} else {
+				/* Recovery succeeded */
+				__cw1200_cqm_bssloss_sm(priv, 0, 1, 0);
+			}
+		}
+		spin_unlock(&priv->bss_loss_lock);
+
+		if (!arg->status) {
+			tx->flags |= IEEE80211_TX_STAT_ACK;
+			++tx_count;
+			cw1200_debug_txed(priv);
+			if (arg->flags & WSM_TX_STATUS_AGGREGATION) {
+				/* Do not report aggregation to mac80211:
+				 * it confuses minstrel a lot.
+				 */
+				/* tx->flags |= IEEE80211_TX_STAT_AMPDU; */
+				cw1200_debug_txed_agg(priv);
+			}
+		} else {
+			if (tx_count)
+				++tx_count;
+		}
+
+		for (i = 0; i < IEEE80211_TX_MAX_RATES; ++i) {
+			if (tx->status.rates[i].count >= tx_count) {
+				tx->status.rates[i].count = tx_count;
+				break;
+			}
+			tx_count -= tx->status.rates[i].count;
+			if (tx->status.rates[i].flags & IEEE80211_TX_RC_MCS)
+				tx->status.rates[i].flags |= ht_flags;
+		}
+
+		for (++i; i < IEEE80211_TX_MAX_RATES; ++i) {
+			tx->status.rates[i].count = 0;
+			tx->status.rates[i].idx = -1;
+		}
+
+		/* Pull off any crypto trailers that we added on */
+		if (tx->control.hw_key) {
+			skb_trim(skb, skb->len - tx->control.hw_key->icv_len);
+			if (tx->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
+				skb_trim(skb, skb->len - 8); /* MIC space */
+		}
+		cw1200_queue_remove(queue, arg->packet_id);
+	}
+	/* XXX TODO:  Only wake if there are pending transmits.. */
+	cw1200_bh_wakeup(priv);
+}
+
+static void cw1200_notify_buffered_tx(struct cw1200_common *priv,
+			       struct sk_buff *skb, int link_id, int tid)
+{
+	struct ieee80211_sta *sta;
+	struct ieee80211_hdr *hdr;
+	u8 *buffered;
+	u8 still_buffered = 0;
+
+	if (link_id && tid < CW1200_MAX_TID) {
+		buffered = priv->link_id_db
+				[link_id - 1].buffered;
+
+		spin_lock_bh(&priv->ps_state_lock);
+		if (!WARN_ON(!buffered[tid]))
+			still_buffered = --buffered[tid];
+		spin_unlock_bh(&priv->ps_state_lock);
+
+		if (!still_buffered && tid < CW1200_MAX_TID) {
+			hdr = (struct ieee80211_hdr *)skb->data;
+			rcu_read_lock();
+			sta = ieee80211_find_sta(priv->vif, hdr->addr1);
+			if (sta)
+				ieee80211_sta_set_buffered(sta, tid, false);
+			rcu_read_unlock();
+		}
+	}
+}
+
+void cw1200_skb_dtor(struct cw1200_common *priv,
+		     struct sk_buff *skb,
+		     const struct cw1200_txpriv *txpriv)
+{
+	skb_pull(skb, txpriv->offset);
+	if (txpriv->rate_id != CW1200_INVALID_RATE_ID) {
+		cw1200_notify_buffered_tx(priv, skb,
+					  txpriv->raw_link_id, txpriv->tid);
+		tx_policy_put(priv, txpriv->rate_id);
+	}
+	ieee80211_tx_status(priv->hw, skb);
+}
+
+void cw1200_rx_cb(struct cw1200_common *priv,
+		  struct wsm_rx *arg,
+		  int link_id,
+		  struct sk_buff **skb_p)
+{
+	struct sk_buff *skb = *skb_p;
+	struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
+	struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+	struct cw1200_link_entry *entry = NULL;
+	unsigned long grace_period;
+
+	bool early_data = false;
+	bool p2p = priv->vif && priv->vif->p2p;
+	size_t hdrlen;
+	hdr->flag = 0;
+
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
+		/* STA is stopped. */
+		goto drop;
+	}
+
+	if (link_id && link_id <= CW1200_MAX_STA_IN_AP_MODE) {
+		entry =	&priv->link_id_db[link_id - 1];
+		if (entry->status == CW1200_LINK_SOFT &&
+		    ieee80211_is_data(frame->frame_control))
+			early_data = true;
+		entry->timestamp = jiffies;
+	} else if (p2p &&
+		   ieee80211_is_action(frame->frame_control) &&
+		   (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) {
+		pr_debug("[RX] Going to MAP&RESET link ID\n");
+		WARN_ON(work_pending(&priv->linkid_reset_work));
+		memcpy(&priv->action_frame_sa[0],
+		       ieee80211_get_SA(frame), ETH_ALEN);
+		priv->action_linkid = 0;
+		schedule_work(&priv->linkid_reset_work);
+	}
+
+	if (link_id && p2p &&
+	    ieee80211_is_action(frame->frame_control) &&
+	    (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) {
+		/* Link ID already exists for the ACTION frame.
+		 * Reset and Remap
+		 */
+		WARN_ON(work_pending(&priv->linkid_reset_work));
+		memcpy(&priv->action_frame_sa[0],
+		       ieee80211_get_SA(frame), ETH_ALEN);
+		priv->action_linkid = link_id;
+		schedule_work(&priv->linkid_reset_work);
+	}
+	if (arg->status) {
+		if (arg->status == WSM_STATUS_MICFAILURE) {
+			pr_debug("[RX] MIC failure.\n");
+			hdr->flag |= RX_FLAG_MMIC_ERROR;
+		} else if (arg->status == WSM_STATUS_NO_KEY_FOUND) {
+			pr_debug("[RX] No key found.\n");
+			goto drop;
+		} else {
+			pr_debug("[RX] Receive failure: %d.\n",
+				 arg->status);
+			goto drop;
+		}
+	}
+
+	if (skb->len < sizeof(struct ieee80211_pspoll)) {
+		wiphy_warn(priv->hw->wiphy, "Mailformed SDU rx'ed. Size is lesser than IEEE header.\n");
+		goto drop;
+	}
+
+	if (ieee80211_is_pspoll(frame->frame_control))
+		if (cw1200_handle_pspoll(priv, skb))
+			goto drop;
+
+	hdr->band = ((arg->channel_number & 0xff00) ||
+		     (arg->channel_number > 14)) ?
+			IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
+	hdr->freq = ieee80211_channel_to_frequency(
+			arg->channel_number,
+			hdr->band);
+
+	if (arg->rx_rate >= 14) {
+		hdr->flag |= RX_FLAG_HT;
+		hdr->rate_idx = arg->rx_rate - 14;
+	} else if (arg->rx_rate >= 4) {
+		hdr->rate_idx = arg->rx_rate - 2;
+	} else {
+		hdr->rate_idx = arg->rx_rate;
+	}
+
+	hdr->signal = (s8)arg->rcpi_rssi;
+	hdr->antenna = 0;
+
+	hdrlen = ieee80211_hdrlen(frame->frame_control);
+
+	if (WSM_RX_STATUS_ENCRYPTION(arg->flags)) {
+		size_t iv_len = 0, icv_len = 0;
+
+		hdr->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED;
+
+		/* Oops... There is no fast way to ask mac80211 about
+		 * IV/ICV lengths. Even defineas are not exposed.
+		 */
+		switch (WSM_RX_STATUS_ENCRYPTION(arg->flags)) {
+		case WSM_RX_STATUS_WEP:
+			iv_len = 4 /* WEP_IV_LEN */;
+			icv_len = 4 /* WEP_ICV_LEN */;
+			break;
+		case WSM_RX_STATUS_TKIP:
+			iv_len = 8 /* TKIP_IV_LEN */;
+			icv_len = 4 /* TKIP_ICV_LEN */
+				+ 8 /*MICHAEL_MIC_LEN*/;
+			hdr->flag |= RX_FLAG_MMIC_STRIPPED;
+			break;
+		case WSM_RX_STATUS_AES:
+			iv_len = 8 /* CCMP_HDR_LEN */;
+			icv_len = 8 /* CCMP_MIC_LEN */;
+			break;
+		case WSM_RX_STATUS_WAPI:
+			iv_len = 18 /* WAPI_HDR_LEN */;
+			icv_len = 16 /* WAPI_MIC_LEN */;
+			break;
+		default:
+			pr_warn("Unknown encryption type %d\n",
+				WSM_RX_STATUS_ENCRYPTION(arg->flags));
+			goto drop;
+		}
+
+		/* Firmware strips ICV in case of MIC failure. */
+		if (arg->status == WSM_STATUS_MICFAILURE)
+			icv_len = 0;
+
+		if (skb->len < hdrlen + iv_len + icv_len) {
+			wiphy_warn(priv->hw->wiphy, "Malformed SDU rx'ed. Size is lesser than crypto headers.\n");
+			goto drop;
+		}
+
+		/* Remove IV, ICV and MIC */
+		skb_trim(skb, skb->len - icv_len);
+		memmove(skb->data + iv_len, skb->data, hdrlen);
+		skb_pull(skb, iv_len);
+	}
+
+	/* Remove TSF from the end of frame */
+	if (arg->flags & WSM_RX_STATUS_TSF_INCLUDED) {
+		memcpy(&hdr->mactime, skb->data + skb->len - 8, 8);
+		hdr->mactime = le64_to_cpu(hdr->mactime);
+		if (skb->len >= 8)
+			skb_trim(skb, skb->len - 8);
+	} else {
+		hdr->mactime = 0;
+	}
+
+	cw1200_debug_rxed(priv);
+	if (arg->flags & WSM_RX_STATUS_AGGREGATE)
+		cw1200_debug_rxed_agg(priv);
+
+	if (ieee80211_is_action(frame->frame_control) &&
+	    (arg->flags & WSM_RX_STATUS_ADDRESS1)) {
+		if (cw1200_handle_action_rx(priv, skb))
+			return;
+	} else if (ieee80211_is_beacon(frame->frame_control) &&
+		   !arg->status && priv->vif &&
+		   !memcmp(ieee80211_get_SA(frame), priv->vif->bss_conf.bssid,
+			   ETH_ALEN)) {
+		const u8 *tim_ie;
+		u8 *ies = ((struct ieee80211_mgmt *)
+			  (skb->data))->u.beacon.variable;
+		size_t ies_len = skb->len - (ies - (u8 *)(skb->data));
+
+		tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len);
+		if (tim_ie) {
+			struct ieee80211_tim_ie *tim =
+				(struct ieee80211_tim_ie *)&tim_ie[2];
+
+			if (priv->join_dtim_period != tim->dtim_period) {
+				priv->join_dtim_period = tim->dtim_period;
+				queue_work(priv->workqueue,
+					   &priv->set_beacon_wakeup_period_work);
+			}
+		}
+
+		/* Disable beacon filter once we're associated... */
+		if (priv->disable_beacon_filter &&
+		    (priv->vif->bss_conf.assoc ||
+		     priv->vif->bss_conf.ibss_joined)) {
+			priv->disable_beacon_filter = false;
+			queue_work(priv->workqueue,
+				   &priv->update_filtering_work);
+		}
+	}
+
+	/* Stay awake after frame is received to give
+	 * userspace chance to react and acquire appropriate
+	 * wakelock.
+	 */
+	if (ieee80211_is_auth(frame->frame_control))
+		grace_period = 5 * HZ;
+	else if (ieee80211_is_deauth(frame->frame_control))
+		grace_period = 5 * HZ;
+	else
+		grace_period = 1 * HZ;
+	cw1200_pm_stay_awake(&priv->pm_state, grace_period);
+
+	if (early_data) {
+		spin_lock_bh(&priv->ps_state_lock);
+		/* Double-check status with lock held */
+		if (entry->status == CW1200_LINK_SOFT)
+			skb_queue_tail(&entry->rx_queue, skb);
+		else
+			ieee80211_rx_irqsafe(priv->hw, skb);
+		spin_unlock_bh(&priv->ps_state_lock);
+	} else {
+		ieee80211_rx_irqsafe(priv->hw, skb);
+	}
+	*skb_p = NULL;
+
+	return;
+
+drop:
+	/* TODO: update failure counters */
+	return;
+}
+
+/* ******************************************************************** */
+/* Security								*/
+
+int cw1200_alloc_key(struct cw1200_common *priv)
+{
+	int idx;
+
+	idx = ffs(~priv->key_map) - 1;
+	if (idx < 0 || idx > WSM_KEY_MAX_INDEX)
+		return -1;
+
+	priv->key_map |= BIT(idx);
+	priv->keys[idx].index = idx;
+	return idx;
+}
+
+void cw1200_free_key(struct cw1200_common *priv, int idx)
+{
+	BUG_ON(!(priv->key_map & BIT(idx)));
+	memset(&priv->keys[idx], 0, sizeof(priv->keys[idx]));
+	priv->key_map &= ~BIT(idx);
+}
+
+void cw1200_free_keys(struct cw1200_common *priv)
+{
+	memset(&priv->keys, 0, sizeof(priv->keys));
+	priv->key_map = 0;
+}
+
+int cw1200_upload_keys(struct cw1200_common *priv)
+{
+	int idx, ret = 0;
+	for (idx = 0; idx <= WSM_KEY_MAX_INDEX; ++idx)
+		if (priv->key_map & BIT(idx)) {
+			ret = wsm_add_key(priv, &priv->keys[idx]);
+			if (ret < 0)
+				break;
+		}
+	return ret;
+}
+
+/* Workaround for WFD test case 6.1.10 */
+void cw1200_link_id_reset(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, linkid_reset_work);
+	int temp_linkid;
+
+	if (!priv->action_linkid) {
+		/* In GO mode we can receive ACTION frames without a linkID */
+		temp_linkid = cw1200_alloc_link_id(priv,
+				&priv->action_frame_sa[0]);
+		WARN_ON(!temp_linkid);
+		if (temp_linkid) {
+			/* Make sure we execute the WQ */
+			flush_workqueue(priv->workqueue);
+			/* Release the link ID */
+			spin_lock_bh(&priv->ps_state_lock);
+			priv->link_id_db[temp_linkid - 1].prev_status =
+				priv->link_id_db[temp_linkid - 1].status;
+			priv->link_id_db[temp_linkid - 1].status =
+				CW1200_LINK_RESET;
+			spin_unlock_bh(&priv->ps_state_lock);
+			wsm_lock_tx_async(priv);
+			if (queue_work(priv->workqueue,
+				       &priv->link_id_work) <= 0)
+				wsm_unlock_tx(priv);
+		}
+	} else {
+		spin_lock_bh(&priv->ps_state_lock);
+		priv->link_id_db[priv->action_linkid - 1].prev_status =
+			priv->link_id_db[priv->action_linkid - 1].status;
+		priv->link_id_db[priv->action_linkid - 1].status =
+			CW1200_LINK_RESET_REMAP;
+		spin_unlock_bh(&priv->ps_state_lock);
+		wsm_lock_tx_async(priv);
+		if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
+			wsm_unlock_tx(priv);
+		flush_workqueue(priv->workqueue);
+	}
+}
+
+int cw1200_find_link_id(struct cw1200_common *priv, const u8 *mac)
+{
+	int i, ret = 0;
+	spin_lock_bh(&priv->ps_state_lock);
+	for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
+		if (!memcmp(mac, priv->link_id_db[i].mac, ETH_ALEN) &&
+		    priv->link_id_db[i].status) {
+			priv->link_id_db[i].timestamp = jiffies;
+			ret = i + 1;
+			break;
+		}
+	}
+	spin_unlock_bh(&priv->ps_state_lock);
+	return ret;
+}
+
+int cw1200_alloc_link_id(struct cw1200_common *priv, const u8 *mac)
+{
+	int i, ret = 0;
+	unsigned long max_inactivity = 0;
+	unsigned long now = jiffies;
+
+	spin_lock_bh(&priv->ps_state_lock);
+	for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
+		if (!priv->link_id_db[i].status) {
+			ret = i + 1;
+			break;
+		} else if (priv->link_id_db[i].status != CW1200_LINK_HARD &&
+			   !priv->tx_queue_stats.link_map_cache[i + 1]) {
+			unsigned long inactivity =
+				now - priv->link_id_db[i].timestamp;
+			if (inactivity < max_inactivity)
+				continue;
+			max_inactivity = inactivity;
+			ret = i + 1;
+		}
+	}
+	if (ret) {
+		struct cw1200_link_entry *entry = &priv->link_id_db[ret - 1];
+		pr_debug("[AP] STA added, link_id: %d\n", ret);
+		entry->status = CW1200_LINK_RESERVE;
+		memcpy(&entry->mac, mac, ETH_ALEN);
+		memset(&entry->buffered, 0, CW1200_MAX_TID);
+		skb_queue_head_init(&entry->rx_queue);
+		wsm_lock_tx_async(priv);
+		if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
+			wsm_unlock_tx(priv);
+	} else {
+		wiphy_info(priv->hw->wiphy,
+			   "[AP] Early: no more link IDs available.\n");
+	}
+
+	spin_unlock_bh(&priv->ps_state_lock);
+	return ret;
+}
+
+void cw1200_link_id_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, link_id_work);
+	wsm_flush_tx(priv);
+	cw1200_link_id_gc_work(&priv->link_id_gc_work.work);
+	wsm_unlock_tx(priv);
+}
+
+void cw1200_link_id_gc_work(struct work_struct *work)
+{
+	struct cw1200_common *priv =
+		container_of(work, struct cw1200_common, link_id_gc_work.work);
+	struct wsm_reset reset = {
+		.reset_statistics = false,
+	};
+	struct wsm_map_link map_link = {
+		.link_id = 0,
+	};
+	unsigned long now = jiffies;
+	unsigned long next_gc = -1;
+	long ttl;
+	bool need_reset;
+	u32 mask;
+	int i;
+
+	if (priv->join_status != CW1200_JOIN_STATUS_AP)
+		return;
+
+	wsm_lock_tx(priv);
+	spin_lock_bh(&priv->ps_state_lock);
+	for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
+		need_reset = false;
+		mask = BIT(i + 1);
+		if (priv->link_id_db[i].status == CW1200_LINK_RESERVE ||
+		    (priv->link_id_db[i].status == CW1200_LINK_HARD &&
+		     !(priv->link_id_map & mask))) {
+			if (priv->link_id_map & mask) {
+				priv->sta_asleep_mask &= ~mask;
+				priv->pspoll_mask &= ~mask;
+				need_reset = true;
+			}
+			priv->link_id_map |= mask;
+			if (priv->link_id_db[i].status != CW1200_LINK_HARD)
+				priv->link_id_db[i].status = CW1200_LINK_SOFT;
+			memcpy(map_link.mac_addr, priv->link_id_db[i].mac,
+			       ETH_ALEN);
+			spin_unlock_bh(&priv->ps_state_lock);
+			if (need_reset) {
+				reset.link_id = i + 1;
+				wsm_reset(priv, &reset);
+			}
+			map_link.link_id = i + 1;
+			wsm_map_link(priv, &map_link);
+			next_gc = min(next_gc, CW1200_LINK_ID_GC_TIMEOUT);
+			spin_lock_bh(&priv->ps_state_lock);
+		} else if (priv->link_id_db[i].status == CW1200_LINK_SOFT) {
+			ttl = priv->link_id_db[i].timestamp - now +
+					CW1200_LINK_ID_GC_TIMEOUT;
+			if (ttl <= 0) {
+				need_reset = true;
+				priv->link_id_db[i].status = CW1200_LINK_OFF;
+				priv->link_id_map &= ~mask;
+				priv->sta_asleep_mask &= ~mask;
+				priv->pspoll_mask &= ~mask;
+				memset(map_link.mac_addr, 0, ETH_ALEN);
+				spin_unlock_bh(&priv->ps_state_lock);
+				reset.link_id = i + 1;
+				wsm_reset(priv, &reset);
+				spin_lock_bh(&priv->ps_state_lock);
+			} else {
+				next_gc = min_t(unsigned long, next_gc, ttl);
+			}
+		} else if (priv->link_id_db[i].status == CW1200_LINK_RESET ||
+				priv->link_id_db[i].status ==
+				CW1200_LINK_RESET_REMAP) {
+			int status = priv->link_id_db[i].status;
+			priv->link_id_db[i].status =
+					priv->link_id_db[i].prev_status;
+			priv->link_id_db[i].timestamp = now;
+			reset.link_id = i + 1;
+			spin_unlock_bh(&priv->ps_state_lock);
+			wsm_reset(priv, &reset);
+			if (status == CW1200_LINK_RESET_REMAP) {
+				memcpy(map_link.mac_addr,
+				       priv->link_id_db[i].mac,
+				       ETH_ALEN);
+				map_link.link_id = i + 1;
+				wsm_map_link(priv, &map_link);
+				next_gc = min(next_gc,
+						CW1200_LINK_ID_GC_TIMEOUT);
+			}
+			spin_lock_bh(&priv->ps_state_lock);
+		}
+		if (need_reset) {
+			skb_queue_purge(&priv->link_id_db[i].rx_queue);
+			pr_debug("[AP] STA removed, link_id: %d\n",
+				 reset.link_id);
+		}
+	}
+	spin_unlock_bh(&priv->ps_state_lock);
+	if (next_gc != -1)
+		queue_delayed_work(priv->workqueue,
+				   &priv->link_id_gc_work, next_gc);
+	wsm_unlock_tx(priv);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/txrx.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/txrx.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/txrx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/txrx.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,106 @@
+/*
+ * Datapath interface for ST-Ericsson CW1200 mac80211 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef CW1200_TXRX_H
+#define CW1200_TXRX_H
+
+#include <linux/list.h>
+
+/* extern */ struct ieee80211_hw;
+/* extern */ struct sk_buff;
+/* extern */ struct wsm_tx;
+/* extern */ struct wsm_rx;
+/* extern */ struct wsm_tx_confirm;
+/* extern */ struct cw1200_txpriv;
+
+struct tx_policy {
+	union {
+		__le32 tbl[3];
+		u8 raw[12];
+	};
+	u8  defined;
+	u8  usage_count;
+	u8  retry_count;
+	u8  uploaded;
+};
+
+struct tx_policy_cache_entry {
+	struct tx_policy policy;
+	struct list_head link;
+};
+
+#define TX_POLICY_CACHE_SIZE	(8)
+struct tx_policy_cache {
+	struct tx_policy_cache_entry cache[TX_POLICY_CACHE_SIZE];
+	struct list_head used;
+	struct list_head free;
+	spinlock_t lock; /* Protect policy cache */
+};
+
+/* ******************************************************************** */
+/* TX policy cache							*/
+/* Intention of TX policy cache is an overcomplicated WSM API.
+ * Device does not accept per-PDU tx retry sequence.
+ * It uses "tx retry policy id" instead, so driver code has to sync
+ * linux tx retry sequences with a retry policy table in the device.
+ */
+void tx_policy_init(struct cw1200_common *priv);
+void tx_policy_upload_work(struct work_struct *work);
+void tx_policy_clean(struct cw1200_common *priv);
+
+/* ******************************************************************** */
+/* TX implementation							*/
+
+u32 cw1200_rate_mask_to_wsm(struct cw1200_common *priv,
+			       u32 rates);
+void cw1200_tx(struct ieee80211_hw *dev,
+	       struct ieee80211_tx_control *control,
+	       struct sk_buff *skb);
+void cw1200_skb_dtor(struct cw1200_common *priv,
+		     struct sk_buff *skb,
+		     const struct cw1200_txpriv *txpriv);
+
+/* ******************************************************************** */
+/* WSM callbacks							*/
+
+void cw1200_tx_confirm_cb(struct cw1200_common *priv,
+			  int link_id,
+			  struct wsm_tx_confirm *arg);
+void cw1200_rx_cb(struct cw1200_common *priv,
+		  struct wsm_rx *arg,
+		  int link_id,
+		  struct sk_buff **skb_p);
+
+/* ******************************************************************** */
+/* Timeout								*/
+
+void cw1200_tx_timeout(struct work_struct *work);
+
+/* ******************************************************************** */
+/* Security								*/
+int cw1200_alloc_key(struct cw1200_common *priv);
+void cw1200_free_key(struct cw1200_common *priv, int idx);
+void cw1200_free_keys(struct cw1200_common *priv);
+int cw1200_upload_keys(struct cw1200_common *priv);
+
+/* ******************************************************************** */
+/* Workaround for WFD test case 6.1.10					*/
+void cw1200_link_id_reset(struct work_struct *work);
+
+#define CW1200_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ))
+
+int cw1200_find_link_id(struct cw1200_common *priv, const u8 *mac);
+int cw1200_alloc_link_id(struct cw1200_common *priv, const u8 *mac);
+void cw1200_link_id_work(struct work_struct *work);
+void cw1200_link_id_gc_work(struct work_struct *work);
+
+
+#endif /* CW1200_TXRX_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/wsm.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/wsm.c
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/wsm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/wsm.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1822 @@
+/*
+ * WSM host interface (HI) implementation for
+ * ST-Ericsson CW1200 mac80211 drivers.
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/skbuff.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/random.h>
+
+#include "cw1200.h"
+#include "wsm.h"
+#include "bh.h"
+#include "sta.h"
+#include "debug.h"
+
+#define WSM_CMD_TIMEOUT		(2 * HZ) /* With respect to interrupt loss */
+#define WSM_CMD_START_TIMEOUT	(7 * HZ)
+#define WSM_CMD_RESET_TIMEOUT	(3 * HZ) /* 2 sec. timeout was observed.   */
+#define WSM_CMD_MAX_TIMEOUT	(3 * HZ)
+
+#define WSM_SKIP(buf, size)						\
+	do {								\
+		if ((buf)->data + size > (buf)->end)			\
+			goto underflow;					\
+		(buf)->data += size;					\
+	} while (0)
+
+#define WSM_GET(buf, ptr, size)						\
+	do {								\
+		if ((buf)->data + size > (buf)->end)			\
+			goto underflow;					\
+		memcpy(ptr, (buf)->data, size);				\
+		(buf)->data += size;					\
+	} while (0)
+
+#define __WSM_GET(buf, type, type2, cvt)				\
+	({								\
+		type val;						\
+		if ((buf)->data + sizeof(type) > (buf)->end)		\
+			goto underflow;					\
+		val = cvt(*(type2 *)(buf)->data);			\
+		(buf)->data += sizeof(type);				\
+		val;							\
+	})
+
+#define WSM_GET8(buf)  __WSM_GET(buf, u8, u8, (u8))
+#define WSM_GET16(buf) __WSM_GET(buf, u16, __le16, __le16_to_cpu)
+#define WSM_GET32(buf) __WSM_GET(buf, u32, __le32, __le32_to_cpu)
+
+#define WSM_PUT(buf, ptr, size)						\
+	do {								\
+		if ((buf)->data + size > (buf)->end)		\
+			if (wsm_buf_reserve((buf), size))	\
+				goto nomem;				\
+		memcpy((buf)->data, ptr, size);				\
+		(buf)->data += size;					\
+	} while (0)
+
+#define __WSM_PUT(buf, val, type, type2, cvt)				\
+	do {								\
+		if ((buf)->data + sizeof(type) > (buf)->end)		\
+			if (wsm_buf_reserve((buf), sizeof(type))) \
+				goto nomem;				\
+		*(type2 *)(buf)->data = cvt(val);			\
+		(buf)->data += sizeof(type);				\
+	} while (0)
+
+#define WSM_PUT8(buf, val)  __WSM_PUT(buf, val, u8, u8, (u8))
+#define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __le16, __cpu_to_le16)
+#define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __le32, __cpu_to_le32)
+
+static void wsm_buf_reset(struct wsm_buf *buf);
+static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size);
+
+static int wsm_cmd_send(struct cw1200_common *priv,
+			struct wsm_buf *buf,
+			void *arg, u16 cmd, long tmo);
+
+#define wsm_cmd_lock(__priv) mutex_lock(&((__priv)->wsm_cmd_mux))
+#define wsm_cmd_unlock(__priv) mutex_unlock(&((__priv)->wsm_cmd_mux))
+
+/* ******************************************************************** */
+/* WSM API implementation						*/
+
+static int wsm_generic_confirm(struct cw1200_common *priv,
+			     void *arg,
+			     struct wsm_buf *buf)
+{
+	u32 status = WSM_GET32(buf);
+	if (status != WSM_STATUS_SUCCESS)
+		return -EINVAL;
+	return 0;
+
+underflow:
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+int wsm_configuration(struct cw1200_common *priv, struct wsm_configuration *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT32(buf, arg->dot11MaxTransmitMsduLifeTime);
+	WSM_PUT32(buf, arg->dot11MaxReceiveLifeTime);
+	WSM_PUT32(buf, arg->dot11RtsThreshold);
+
+	/* DPD block. */
+	WSM_PUT16(buf, arg->dpdData_size + 12);
+	WSM_PUT16(buf, 1); /* DPD version */
+	WSM_PUT(buf, arg->dot11StationId, ETH_ALEN);
+	WSM_PUT16(buf, 5); /* DPD flags */
+	WSM_PUT(buf, arg->dpdData, arg->dpdData_size);
+
+	ret = wsm_cmd_send(priv, buf, arg,
+			   WSM_CONFIGURATION_REQ_ID, WSM_CMD_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+static int wsm_configuration_confirm(struct cw1200_common *priv,
+				     struct wsm_configuration *arg,
+				     struct wsm_buf *buf)
+{
+	int i;
+	int status;
+
+	status = WSM_GET32(buf);
+	if (WARN_ON(status != WSM_STATUS_SUCCESS))
+		return -EINVAL;
+
+	WSM_GET(buf, arg->dot11StationId, ETH_ALEN);
+	arg->dot11FrequencyBandsSupported = WSM_GET8(buf);
+	WSM_SKIP(buf, 1);
+	arg->supportedRateMask = WSM_GET32(buf);
+	for (i = 0; i < 2; ++i) {
+		arg->txPowerRange[i].min_power_level = WSM_GET32(buf);
+		arg->txPowerRange[i].max_power_level = WSM_GET32(buf);
+		arg->txPowerRange[i].stepping = WSM_GET32(buf);
+	}
+	return 0;
+
+underflow:
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+/* ******************************************************************** */
+
+int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+	u16 cmd = WSM_RESET_REQ_ID | WSM_TX_LINK_ID(arg->link_id);
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT32(buf, arg->reset_statistics ? 0 : 1);
+	ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_RESET_TIMEOUT);
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+struct wsm_mib {
+	u16 mib_id;
+	void *buf;
+	size_t buf_size;
+};
+
+int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
+			size_t buf_size)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+	struct wsm_mib mib_buf = {
+		.mib_id = mib_id,
+		.buf = _buf,
+		.buf_size = buf_size,
+	};
+	wsm_cmd_lock(priv);
+
+	WSM_PUT16(buf, mib_id);
+	WSM_PUT16(buf, 0);
+
+	ret = wsm_cmd_send(priv, buf, &mib_buf,
+			   WSM_READ_MIB_REQ_ID, WSM_CMD_TIMEOUT);
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+static int wsm_read_mib_confirm(struct cw1200_common *priv,
+				struct wsm_mib *arg,
+				struct wsm_buf *buf)
+{
+	u16 size;
+	if (WARN_ON(WSM_GET32(buf) != WSM_STATUS_SUCCESS))
+		return -EINVAL;
+
+	if (WARN_ON(WSM_GET16(buf) != arg->mib_id))
+		return -EINVAL;
+
+	size = WSM_GET16(buf);
+	if (size > arg->buf_size)
+		size = arg->buf_size;
+
+	WSM_GET(buf, arg->buf, size);
+	arg->buf_size = size;
+	return 0;
+
+underflow:
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+/* ******************************************************************** */
+
+int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
+			size_t buf_size)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+	struct wsm_mib mib_buf = {
+		.mib_id = mib_id,
+		.buf = _buf,
+		.buf_size = buf_size,
+	};
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT16(buf, mib_id);
+	WSM_PUT16(buf, buf_size);
+	WSM_PUT(buf, _buf, buf_size);
+
+	ret = wsm_cmd_send(priv, buf, &mib_buf,
+			   WSM_WRITE_MIB_REQ_ID, WSM_CMD_TIMEOUT);
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+static int wsm_write_mib_confirm(struct cw1200_common *priv,
+				struct wsm_mib *arg,
+				struct wsm_buf *buf)
+{
+	int ret;
+
+	ret = wsm_generic_confirm(priv, arg, buf);
+	if (ret)
+		return ret;
+
+	if (arg->mib_id == WSM_MIB_ID_OPERATIONAL_POWER_MODE) {
+		/* OperationalMode: update PM status. */
+		const char *p = arg->buf;
+		cw1200_enable_powersave(priv, (p[0] & 0x0F) ? true : false);
+	}
+	return 0;
+}
+
+/* ******************************************************************** */
+
+int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg)
+{
+	int i;
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	if (arg->num_channels > 48)
+		return -EINVAL;
+
+	if (arg->num_ssids > 2)
+		return -EINVAL;
+
+	if (arg->band > 1)
+		return -EINVAL;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT8(buf, arg->band);
+	WSM_PUT8(buf, arg->type);
+	WSM_PUT8(buf, arg->flags);
+	WSM_PUT8(buf, arg->max_tx_rate);
+	WSM_PUT32(buf, arg->auto_scan_interval);
+	WSM_PUT8(buf, arg->num_probes);
+	WSM_PUT8(buf, arg->num_channels);
+	WSM_PUT8(buf, arg->num_ssids);
+	WSM_PUT8(buf, arg->probe_delay);
+
+	for (i = 0; i < arg->num_channels; ++i) {
+		WSM_PUT16(buf, arg->ch[i].number);
+		WSM_PUT16(buf, 0);
+		WSM_PUT32(buf, arg->ch[i].min_chan_time);
+		WSM_PUT32(buf, arg->ch[i].max_chan_time);
+		WSM_PUT32(buf, 0);
+	}
+
+	for (i = 0; i < arg->num_ssids; ++i) {
+		WSM_PUT32(buf, arg->ssids[i].length);
+		WSM_PUT(buf, &arg->ssids[i].ssid[0],
+			sizeof(arg->ssids[i].ssid));
+	}
+
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_START_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_stop_scan(struct cw1200_common *priv)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+	wsm_cmd_lock(priv);
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_STOP_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
+	wsm_cmd_unlock(priv);
+	return ret;
+}
+
+
+static int wsm_tx_confirm(struct cw1200_common *priv,
+			  struct wsm_buf *buf,
+			  int link_id)
+{
+	struct wsm_tx_confirm tx_confirm;
+
+	tx_confirm.packet_id = WSM_GET32(buf);
+	tx_confirm.status = WSM_GET32(buf);
+	tx_confirm.tx_rate = WSM_GET8(buf);
+	tx_confirm.ack_failures = WSM_GET8(buf);
+	tx_confirm.flags = WSM_GET16(buf);
+	tx_confirm.media_delay = WSM_GET32(buf);
+	tx_confirm.tx_queue_delay = WSM_GET32(buf);
+
+	cw1200_tx_confirm_cb(priv, link_id, &tx_confirm);
+	return 0;
+
+underflow:
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+static int wsm_multi_tx_confirm(struct cw1200_common *priv,
+				struct wsm_buf *buf, int link_id)
+{
+	int ret;
+	int count;
+	int i;
+
+	count = WSM_GET32(buf);
+	if (WARN_ON(count <= 0))
+		return -EINVAL;
+
+	if (count > 1) {
+		/* We already released one buffer, now for the rest */
+		ret = wsm_release_tx_buffer(priv, count - 1);
+		if (ret < 0)
+			return ret;
+		else if (ret > 0)
+			cw1200_bh_wakeup(priv);
+	}
+
+	cw1200_debug_txed_multi(priv, count);
+	for (i = 0; i < count; ++i) {
+		ret = wsm_tx_confirm(priv, buf, link_id);
+		if (ret)
+			return ret;
+	}
+	return ret;
+
+underflow:
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+/* ******************************************************************** */
+
+static int wsm_join_confirm(struct cw1200_common *priv,
+			    struct wsm_join_cnf *arg,
+			    struct wsm_buf *buf)
+{
+	arg->status = WSM_GET32(buf);
+	if (WARN_ON(arg->status) != WSM_STATUS_SUCCESS)
+		return -EINVAL;
+
+	arg->min_power_level = WSM_GET32(buf);
+	arg->max_power_level = WSM_GET32(buf);
+
+	return 0;
+
+underflow:
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+int wsm_join(struct cw1200_common *priv, struct wsm_join *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+	struct wsm_join_cnf resp;
+	wsm_cmd_lock(priv);
+
+	WSM_PUT8(buf, arg->mode);
+	WSM_PUT8(buf, arg->band);
+	WSM_PUT16(buf, arg->channel_number);
+	WSM_PUT(buf, &arg->bssid[0], sizeof(arg->bssid));
+	WSM_PUT16(buf, arg->atim_window);
+	WSM_PUT8(buf, arg->preamble_type);
+	WSM_PUT8(buf, arg->probe_for_join);
+	WSM_PUT8(buf, arg->dtim_period);
+	WSM_PUT8(buf, arg->flags);
+	WSM_PUT32(buf, arg->ssid_len);
+	WSM_PUT(buf, &arg->ssid[0], sizeof(arg->ssid));
+	WSM_PUT32(buf, arg->beacon_interval);
+	WSM_PUT32(buf, arg->basic_rate_set);
+
+	priv->tx_burst_idx = -1;
+	ret = wsm_cmd_send(priv, buf, &resp,
+			   WSM_JOIN_REQ_ID, WSM_CMD_TIMEOUT);
+	/* TODO:  Update state based on resp.min|max_power_level */
+
+	priv->join_complete_status = resp.status;
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_set_bss_params(struct cw1200_common *priv,
+		       const struct wsm_set_bss_params *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT8(buf, (arg->reset_beacon_loss ?  0x1 : 0));
+	WSM_PUT8(buf, arg->beacon_lost_count);
+	WSM_PUT16(buf, arg->aid);
+	WSM_PUT32(buf, arg->operational_rate_set);
+
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_SET_BSS_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT(buf, arg, sizeof(*arg));
+
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_ADD_KEY_REQ_ID, WSM_CMD_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_remove_key(struct cw1200_common *priv, const struct wsm_remove_key *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT8(buf, arg->index);
+	WSM_PUT8(buf, 0);
+	WSM_PUT16(buf, 0);
+
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_REMOVE_KEY_REQ_ID, WSM_CMD_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_set_tx_queue_params(struct cw1200_common *priv,
+		const struct wsm_set_tx_queue_params *arg, u8 id)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+	u8 queue_id_to_wmm_aci[] = {3, 2, 0, 1};
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT8(buf, queue_id_to_wmm_aci[id]);
+	WSM_PUT8(buf, 0);
+	WSM_PUT8(buf, arg->ackPolicy);
+	WSM_PUT8(buf, 0);
+	WSM_PUT32(buf, arg->maxTransmitLifetime);
+	WSM_PUT16(buf, arg->allowedMediumTime);
+	WSM_PUT16(buf, 0);
+
+	ret = wsm_cmd_send(priv, buf, NULL, 0x0012, WSM_CMD_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_set_edca_params(struct cw1200_common *priv,
+				const struct wsm_edca_params *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+
+	/* Implemented according to specification. */
+
+	WSM_PUT16(buf, arg->params[3].cwmin);
+	WSM_PUT16(buf, arg->params[2].cwmin);
+	WSM_PUT16(buf, arg->params[1].cwmin);
+	WSM_PUT16(buf, arg->params[0].cwmin);
+
+	WSM_PUT16(buf, arg->params[3].cwmax);
+	WSM_PUT16(buf, arg->params[2].cwmax);
+	WSM_PUT16(buf, arg->params[1].cwmax);
+	WSM_PUT16(buf, arg->params[0].cwmax);
+
+	WSM_PUT8(buf, arg->params[3].aifns);
+	WSM_PUT8(buf, arg->params[2].aifns);
+	WSM_PUT8(buf, arg->params[1].aifns);
+	WSM_PUT8(buf, arg->params[0].aifns);
+
+	WSM_PUT16(buf, arg->params[3].txop_limit);
+	WSM_PUT16(buf, arg->params[2].txop_limit);
+	WSM_PUT16(buf, arg->params[1].txop_limit);
+	WSM_PUT16(buf, arg->params[0].txop_limit);
+
+	WSM_PUT32(buf, arg->params[3].max_rx_lifetime);
+	WSM_PUT32(buf, arg->params[2].max_rx_lifetime);
+	WSM_PUT32(buf, arg->params[1].max_rx_lifetime);
+	WSM_PUT32(buf, arg->params[0].max_rx_lifetime);
+
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_EDCA_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_switch_channel(struct cw1200_common *priv,
+			const struct wsm_switch_channel *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT8(buf, arg->mode);
+	WSM_PUT8(buf, arg->switch_count);
+	WSM_PUT16(buf, arg->channel_number);
+
+	priv->channel_switch_in_progress = 1;
+
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_SWITCH_CHANNEL_REQ_ID, WSM_CMD_TIMEOUT);
+	if (ret)
+		priv->channel_switch_in_progress = 0;
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+	priv->ps_mode_switch_in_progress = 1;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT8(buf, arg->mode);
+	WSM_PUT8(buf, arg->fast_psm_idle_period);
+	WSM_PUT8(buf, arg->ap_psm_change_period);
+	WSM_PUT8(buf, arg->min_auto_pspoll_period);
+
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_SET_PM_REQ_ID, WSM_CMD_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT8(buf, arg->mode);
+	WSM_PUT8(buf, arg->band);
+	WSM_PUT16(buf, arg->channel_number);
+	WSM_PUT32(buf, arg->ct_window);
+	WSM_PUT32(buf, arg->beacon_interval);
+	WSM_PUT8(buf, arg->dtim_period);
+	WSM_PUT8(buf, arg->preamble);
+	WSM_PUT8(buf, arg->probe_delay);
+	WSM_PUT8(buf, arg->ssid_len);
+	WSM_PUT(buf, arg->ssid, sizeof(arg->ssid));
+	WSM_PUT32(buf, arg->basic_rate_set);
+
+	priv->tx_burst_idx = -1;
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_START_REQ_ID, WSM_CMD_START_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_beacon_transmit(struct cw1200_common *priv,
+			const struct wsm_beacon_transmit *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT32(buf, arg->enable_beaconing ? 1 : 0);
+
+	ret = wsm_cmd_send(priv, buf, NULL,
+			   WSM_BEACON_TRANSMIT_REQ_ID, WSM_CMD_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_start_find(struct cw1200_common *priv)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+	ret = wsm_cmd_send(priv, buf, NULL, 0x0019, WSM_CMD_TIMEOUT);
+	wsm_cmd_unlock(priv);
+	return ret;
+}
+
+/* ******************************************************************** */
+
+int wsm_stop_find(struct cw1200_common *priv)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+	ret = wsm_cmd_send(priv, buf, NULL, 0x001A, WSM_CMD_TIMEOUT);
+	wsm_cmd_unlock(priv);
+	return ret;
+}
+
+/* ******************************************************************** */
+
+int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+	u16 cmd = 0x001C | WSM_TX_LINK_ID(arg->link_id);
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT(buf, &arg->mac_addr[0], sizeof(arg->mac_addr));
+	WSM_PUT16(buf, 0);
+
+	ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+
+int wsm_update_ie(struct cw1200_common *priv,
+		  const struct wsm_update_ie *arg)
+{
+	int ret;
+	struct wsm_buf *buf = &priv->wsm_cmd_buf;
+
+	wsm_cmd_lock(priv);
+
+	WSM_PUT16(buf, arg->what);
+	WSM_PUT16(buf, arg->count);
+	WSM_PUT(buf, arg->ies, arg->length);
+
+	ret = wsm_cmd_send(priv, buf, NULL, 0x001B, WSM_CMD_TIMEOUT);
+
+	wsm_cmd_unlock(priv);
+	return ret;
+
+nomem:
+	wsm_cmd_unlock(priv);
+	return -ENOMEM;
+}
+
+/* ******************************************************************** */
+int wsm_set_probe_responder(struct cw1200_common *priv, bool enable)
+{
+	priv->rx_filter.probeResponder = enable;
+	return wsm_set_rx_filter(priv, &priv->rx_filter);
+}
+
+/* ******************************************************************** */
+/* WSM indication events implementation					*/
+const char * const cw1200_fw_types[] = {
+	"ETF",
+	"WFM",
+	"WSM",
+	"HI test",
+	"Platform test"
+};
+
+static int wsm_startup_indication(struct cw1200_common *priv,
+					struct wsm_buf *buf)
+{
+	priv->wsm_caps.input_buffers     = WSM_GET16(buf);
+	priv->wsm_caps.input_buffer_size = WSM_GET16(buf);
+	priv->wsm_caps.hw_id	  = WSM_GET16(buf);
+	priv->wsm_caps.hw_subid	  = WSM_GET16(buf);
+	priv->wsm_caps.status	  = WSM_GET16(buf);
+	priv->wsm_caps.fw_cap	  = WSM_GET16(buf);
+	priv->wsm_caps.fw_type	  = WSM_GET16(buf);
+	priv->wsm_caps.fw_api	  = WSM_GET16(buf);
+	priv->wsm_caps.fw_build   = WSM_GET16(buf);
+	priv->wsm_caps.fw_ver     = WSM_GET16(buf);
+	WSM_GET(buf, priv->wsm_caps.fw_label, sizeof(priv->wsm_caps.fw_label));
+	priv->wsm_caps.fw_label[sizeof(priv->wsm_caps.fw_label) - 1] = 0; /* Do not trust FW too much... */
+
+	if (WARN_ON(priv->wsm_caps.status))
+		return -EINVAL;
+
+	if (WARN_ON(priv->wsm_caps.fw_type > 4))
+		return -EINVAL;
+
+	pr_info("CW1200 WSM init done.\n"
+		"   Input buffers: %d x %d bytes\n"
+		"   Hardware: %d.%d\n"
+		"   %s firmware [%s], ver: %d, build: %d,"
+		"   api: %d, cap: 0x%.4X\n",
+		priv->wsm_caps.input_buffers,
+		priv->wsm_caps.input_buffer_size,
+		priv->wsm_caps.hw_id, priv->wsm_caps.hw_subid,
+		cw1200_fw_types[priv->wsm_caps.fw_type],
+		priv->wsm_caps.fw_label, priv->wsm_caps.fw_ver,
+		priv->wsm_caps.fw_build,
+		priv->wsm_caps.fw_api, priv->wsm_caps.fw_cap);
+
+	/* Disable unsupported frequency bands */
+	if (!(priv->wsm_caps.fw_cap & 0x1))
+		priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
+	if (!(priv->wsm_caps.fw_cap & 0x2))
+		priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
+
+	priv->firmware_ready = 1;
+	wake_up(&priv->wsm_startup_done);
+	return 0;
+
+underflow:
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+static int wsm_receive_indication(struct cw1200_common *priv,
+				  int link_id,
+				  struct wsm_buf *buf,
+				  struct sk_buff **skb_p)
+{
+	struct wsm_rx rx;
+	struct ieee80211_hdr *hdr;
+	size_t hdr_len;
+	__le16 fctl;
+
+	rx.status = WSM_GET32(buf);
+	rx.channel_number = WSM_GET16(buf);
+	rx.rx_rate = WSM_GET8(buf);
+	rx.rcpi_rssi = WSM_GET8(buf);
+	rx.flags = WSM_GET32(buf);
+
+	/* FW Workaround: Drop probe resp or
+	   beacon when RSSI is 0
+	*/
+	hdr = (struct ieee80211_hdr *)(*skb_p)->data;
+
+	if (!rx.rcpi_rssi &&
+	    (ieee80211_is_probe_resp(hdr->frame_control) ||
+	     ieee80211_is_beacon(hdr->frame_control)))
+		return 0;
+
+	/* If no RSSI subscription has been made,
+	 * convert RCPI to RSSI here
+	 */
+	if (!priv->cqm_use_rssi)
+		rx.rcpi_rssi = rx.rcpi_rssi / 2 - 110;
+
+	fctl = *(__le16 *)buf->data;
+	hdr_len = buf->data - buf->begin;
+	skb_pull(*skb_p, hdr_len);
+	if (!rx.status && ieee80211_is_deauth(fctl)) {
+		if (priv->join_status == CW1200_JOIN_STATUS_STA) {
+			/* Shedule unjoin work */
+			pr_debug("[WSM] Issue unjoin command (RX).\n");
+			wsm_lock_tx_async(priv);
+			if (queue_work(priv->workqueue,
+				       &priv->unjoin_work) <= 0)
+				wsm_unlock_tx(priv);
+		}
+	}
+	cw1200_rx_cb(priv, &rx, link_id, skb_p);
+	if (*skb_p)
+		skb_push(*skb_p, hdr_len);
+
+	return 0;
+
+underflow:
+	return -EINVAL;
+}
+
+static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
+{
+	int first;
+	struct cw1200_wsm_event *event;
+
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
+		/* STA is stopped. */
+		return 0;
+	}
+
+	event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL);
+	if (!event)
+		return -ENOMEM;
+
+	event->evt.id = WSM_GET32(buf);
+	event->evt.data = WSM_GET32(buf);
+
+	pr_debug("[WSM] Event: %d(%d)\n",
+		 event->evt.id, event->evt.data);
+
+	spin_lock(&priv->event_queue_lock);
+	first = list_empty(&priv->event_queue);
+	list_add_tail(&event->link, &priv->event_queue);
+	spin_unlock(&priv->event_queue_lock);
+
+	if (first)
+		queue_work(priv->workqueue, &priv->event_handler);
+
+	return 0;
+
+underflow:
+	kfree(event);
+	return -EINVAL;
+}
+
+static int wsm_channel_switch_indication(struct cw1200_common *priv,
+					 struct wsm_buf *buf)
+{
+	WARN_ON(WSM_GET32(buf));
+
+	priv->channel_switch_in_progress = 0;
+	wake_up(&priv->channel_switch_done);
+
+	wsm_unlock_tx(priv);
+
+	return 0;
+
+underflow:
+	return -EINVAL;
+}
+
+static int wsm_set_pm_indication(struct cw1200_common *priv,
+				 struct wsm_buf *buf)
+{
+	/* TODO:  Check buf (struct wsm_set_pm_complete) for validity */
+	if (priv->ps_mode_switch_in_progress) {
+		priv->ps_mode_switch_in_progress = 0;
+		wake_up(&priv->ps_mode_switch_done);
+	}
+	return 0;
+}
+
+static int wsm_scan_started(struct cw1200_common *priv, void *arg,
+			    struct wsm_buf *buf)
+{
+	u32 status = WSM_GET32(buf);
+	if (status != WSM_STATUS_SUCCESS) {
+		cw1200_scan_failed_cb(priv);
+		return -EINVAL;
+	}
+	return 0;
+
+underflow:
+	WARN_ON(1);
+	return -EINVAL;
+}
+
+static int wsm_scan_complete_indication(struct cw1200_common *priv,
+					struct wsm_buf *buf)
+{
+	struct wsm_scan_complete arg;
+	arg.status = WSM_GET32(buf);
+	arg.psm = WSM_GET8(buf);
+	arg.num_channels = WSM_GET8(buf);
+	cw1200_scan_complete_cb(priv, &arg);
+
+	return 0;
+
+underflow:
+	return -EINVAL;
+}
+
+static int wsm_join_complete_indication(struct cw1200_common *priv,
+					struct wsm_buf *buf)
+{
+	struct wsm_join_complete arg;
+	arg.status = WSM_GET32(buf);
+	pr_debug("[WSM] Join complete indication, status: %d\n", arg.status);
+	cw1200_join_complete_cb(priv, &arg);
+
+	return 0;
+
+underflow:
+	return -EINVAL;
+}
+
+static int wsm_find_complete_indication(struct cw1200_common *priv,
+					struct wsm_buf *buf)
+{
+	pr_warn("Implement find_complete_indication\n");
+	return 0;
+}
+
+static int wsm_ba_timeout_indication(struct cw1200_common *priv,
+				     struct wsm_buf *buf)
+{
+	u32 dummy;
+	u8 tid;
+	u8 dummy2;
+	u8 addr[ETH_ALEN];
+
+	dummy = WSM_GET32(buf);
+	tid = WSM_GET8(buf);
+	dummy2 = WSM_GET8(buf);
+	WSM_GET(buf, addr, ETH_ALEN);
+
+	pr_info("BlockACK timeout, tid %d, addr %pM\n",
+		tid, addr);
+
+	return 0;
+
+underflow:
+	return -EINVAL;
+}
+
+static int wsm_suspend_resume_indication(struct cw1200_common *priv,
+					 int link_id, struct wsm_buf *buf)
+{
+	u32 flags;
+	struct wsm_suspend_resume arg;
+
+	flags = WSM_GET32(buf);
+	arg.link_id = link_id;
+	arg.stop = !(flags & 1);
+	arg.multicast = !!(flags & 8);
+	arg.queue = (flags >> 1) & 3;
+
+	cw1200_suspend_resume(priv, &arg);
+
+	return 0;
+
+underflow:
+	return -EINVAL;
+}
+
+
+/* ******************************************************************** */
+/* WSM TX								*/
+
+static int wsm_cmd_send(struct cw1200_common *priv,
+			struct wsm_buf *buf,
+			void *arg, u16 cmd, long tmo)
+{
+	size_t buf_len = buf->data - buf->begin;
+	int ret;
+
+	/* Don't bother if we're dead. */
+	if (priv->bh_error) {
+		ret = 0;
+		goto done;
+	}
+
+	/* Block until the cmd buffer is completed.  Tortuous. */
+	spin_lock(&priv->wsm_cmd.lock);
+	while (!priv->wsm_cmd.done) {
+		spin_unlock(&priv->wsm_cmd.lock);
+		spin_lock(&priv->wsm_cmd.lock);
+	}
+	priv->wsm_cmd.done = 0;
+	spin_unlock(&priv->wsm_cmd.lock);
+
+	if (cmd == WSM_WRITE_MIB_REQ_ID ||
+	    cmd == WSM_READ_MIB_REQ_ID)
+		pr_debug("[WSM] >>> 0x%.4X [MIB: 0x%.4X] (%zu)\n",
+			 cmd, __le16_to_cpu(((__le16 *)buf->begin)[2]),
+			 buf_len);
+	else
+		pr_debug("[WSM] >>> 0x%.4X (%zu)\n", cmd, buf_len);
+
+	/* Due to buggy SPI on CW1200, we need to
+	 * pad the message by a few bytes to ensure
+	 * that it's completely received.
+	 */
+	buf_len += 4;
+
+	/* Fill HI message header */
+	/* BH will add sequence number */
+	((__le16 *)buf->begin)[0] = __cpu_to_le16(buf_len);
+	((__le16 *)buf->begin)[1] = __cpu_to_le16(cmd);
+
+	spin_lock(&priv->wsm_cmd.lock);
+	BUG_ON(priv->wsm_cmd.ptr);
+	priv->wsm_cmd.ptr = buf->begin;
+	priv->wsm_cmd.len = buf_len;
+	priv->wsm_cmd.arg = arg;
+	priv->wsm_cmd.cmd = cmd;
+	spin_unlock(&priv->wsm_cmd.lock);
+
+	cw1200_bh_wakeup(priv);
+
+	/* Wait for command completion */
+	ret = wait_event_timeout(priv->wsm_cmd_wq,
+				 priv->wsm_cmd.done, tmo);
+
+	if (!ret && !priv->wsm_cmd.done) {
+		spin_lock(&priv->wsm_cmd.lock);
+		priv->wsm_cmd.done = 1;
+		priv->wsm_cmd.ptr = NULL;
+		spin_unlock(&priv->wsm_cmd.lock);
+		if (priv->bh_error) {
+			/* Return ok to help system cleanup */
+			ret = 0;
+		} else {
+			pr_err("CMD req (0x%04x) stuck in firmware, killing BH\n", priv->wsm_cmd.cmd);
+			print_hex_dump_bytes("REQDUMP: ", DUMP_PREFIX_NONE,
+					     buf->begin, buf_len);
+			pr_err("Outstanding outgoing frames:  %d\n", priv->hw_bufs_used);
+
+			/* Kill BH thread to report the error to the top layer. */
+			atomic_add(1, &priv->bh_term);
+			wake_up(&priv->bh_wq);
+			ret = -ETIMEDOUT;
+		}
+	} else {
+		spin_lock(&priv->wsm_cmd.lock);
+		BUG_ON(!priv->wsm_cmd.done);
+		ret = priv->wsm_cmd.ret;
+		spin_unlock(&priv->wsm_cmd.lock);
+	}
+done:
+	wsm_buf_reset(buf);
+	return ret;
+}
+
+/* ******************************************************************** */
+/* WSM TX port control							*/
+
+void wsm_lock_tx(struct cw1200_common *priv)
+{
+	wsm_cmd_lock(priv);
+	if (atomic_add_return(1, &priv->tx_lock) == 1) {
+		if (wsm_flush_tx(priv))
+			pr_debug("[WSM] TX is locked.\n");
+	}
+	wsm_cmd_unlock(priv);
+}
+
+void wsm_lock_tx_async(struct cw1200_common *priv)
+{
+	if (atomic_add_return(1, &priv->tx_lock) == 1)
+		pr_debug("[WSM] TX is locked (async).\n");
+}
+
+bool wsm_flush_tx(struct cw1200_common *priv)
+{
+	unsigned long timestamp = jiffies;
+	bool pending = false;
+	long timeout;
+	int i;
+
+	/* Flush must be called with TX lock held. */
+	BUG_ON(!atomic_read(&priv->tx_lock));
+
+	/* First check if we really need to do something.
+	 * It is safe to use unprotected access, as hw_bufs_used
+	 * can only decrements.
+	 */
+	if (!priv->hw_bufs_used)
+		return true;
+
+	if (priv->bh_error) {
+		/* In case of failure do not wait for magic. */
+		pr_err("[WSM] Fatal error occured, will not flush TX.\n");
+		return false;
+	} else {
+		/* Get a timestamp of "oldest" frame */
+		for (i = 0; i < 4; ++i)
+			pending |= cw1200_queue_get_xmit_timestamp(
+					&priv->tx_queue[i],
+					&timestamp, 0xffffffff);
+		/* If there's nothing pending, we're good */
+		if (!pending)
+			return true;
+
+		timeout = timestamp + WSM_CMD_LAST_CHANCE_TIMEOUT - jiffies;
+		if (timeout < 0 || wait_event_timeout(priv->bh_evt_wq,
+						      !priv->hw_bufs_used,
+						      timeout) <= 0) {
+			/* Hmmm... Not good. Frame had stuck in firmware. */
+			priv->bh_error = 1;
+			wiphy_err(priv->hw->wiphy, "[WSM] TX Frames (%d) stuck in firmware, killing BH\n", priv->hw_bufs_used);
+			wake_up(&priv->bh_wq);
+			return false;
+		}
+
+		/* Ok, everything is flushed. */
+		return true;
+	}
+}
+
+void wsm_unlock_tx(struct cw1200_common *priv)
+{
+	int tx_lock;
+	tx_lock = atomic_sub_return(1, &priv->tx_lock);
+	BUG_ON(tx_lock < 0);
+
+	if (tx_lock == 0) {
+		if (!priv->bh_error)
+			cw1200_bh_wakeup(priv);
+		pr_debug("[WSM] TX is unlocked.\n");
+	}
+}
+
+/* ******************************************************************** */
+/* WSM RX								*/
+
+int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len)
+{
+	struct wsm_buf buf;
+	u32 reason;
+	u32 reg[18];
+	char fname[48];
+	unsigned int i;
+
+	static const char * const reason_str[] = {
+		"undefined instruction",
+		"prefetch abort",
+		"data abort",
+		"unknown error",
+	};
+
+	buf.begin = buf.data = data;
+	buf.end = &buf.begin[len];
+
+	reason = WSM_GET32(&buf);
+	for (i = 0; i < ARRAY_SIZE(reg); ++i)
+		reg[i] = WSM_GET32(&buf);
+	WSM_GET(&buf, fname, sizeof(fname));
+
+	if (reason < 4)
+		wiphy_err(priv->hw->wiphy,
+			  "Firmware exception: %s.\n",
+			  reason_str[reason]);
+	else
+		wiphy_err(priv->hw->wiphy,
+			  "Firmware assert at %.*s, line %d\n",
+			  (int) sizeof(fname), fname, reg[1]);
+
+	for (i = 0; i < 12; i += 4)
+		wiphy_err(priv->hw->wiphy,
+			  "R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X,\n",
+			  i + 0, reg[i + 0], i + 1, reg[i + 1],
+			  i + 2, reg[i + 2], i + 3, reg[i + 3]);
+	wiphy_err(priv->hw->wiphy,
+		  "R12: 0x%.8X, SP: 0x%.8X, LR: 0x%.8X, PC: 0x%.8X,\n",
+		  reg[i + 0], reg[i + 1], reg[i + 2], reg[i + 3]);
+	i += 4;
+	wiphy_err(priv->hw->wiphy,
+		  "CPSR: 0x%.8X, SPSR: 0x%.8X\n",
+		  reg[i + 0], reg[i + 1]);
+
+	print_hex_dump_bytes("R1: ", DUMP_PREFIX_NONE,
+			     fname, sizeof(fname));
+	return 0;
+
+underflow:
+	wiphy_err(priv->hw->wiphy, "Firmware exception.\n");
+	print_hex_dump_bytes("Exception: ", DUMP_PREFIX_NONE,
+			     data, len);
+	return -EINVAL;
+}
+
+int wsm_handle_rx(struct cw1200_common *priv, u16 id,
+		  struct wsm_hdr *wsm, struct sk_buff **skb_p)
+{
+	int ret = 0;
+	struct wsm_buf wsm_buf;
+	int link_id = (id >> 6) & 0x0F;
+
+	/* Strip link id. */
+	id &= ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
+
+	wsm_buf.begin = (u8 *)&wsm[0];
+	wsm_buf.data = (u8 *)&wsm[1];
+	wsm_buf.end = &wsm_buf.begin[__le16_to_cpu(wsm->len)];
+
+	pr_debug("[WSM] <<< 0x%.4X (%td)\n", id,
+		 wsm_buf.end - wsm_buf.begin);
+
+	if (id == WSM_TX_CONFIRM_IND_ID) {
+		ret = wsm_tx_confirm(priv, &wsm_buf, link_id);
+	} else if (id == WSM_MULTI_TX_CONFIRM_ID) {
+		ret = wsm_multi_tx_confirm(priv, &wsm_buf, link_id);
+	} else if (id & 0x0400) {
+		void *wsm_arg;
+		u16 wsm_cmd;
+
+		/* Do not trust FW too much. Protection against repeated
+		 * response and race condition removal (see above).
+		 */
+		spin_lock(&priv->wsm_cmd.lock);
+		wsm_arg = priv->wsm_cmd.arg;
+		wsm_cmd = priv->wsm_cmd.cmd &
+				~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
+		priv->wsm_cmd.cmd = 0xFFFF;
+		spin_unlock(&priv->wsm_cmd.lock);
+
+		if (WARN_ON((id & ~0x0400) != wsm_cmd)) {
+			/* Note that any non-zero is a fatal retcode. */
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* Note that wsm_arg can be NULL in case of timeout in
+		 * wsm_cmd_send().
+		 */
+
+		switch (id) {
+		case WSM_READ_MIB_RESP_ID:
+			if (wsm_arg)
+				ret = wsm_read_mib_confirm(priv, wsm_arg,
+								&wsm_buf);
+			break;
+		case WSM_WRITE_MIB_RESP_ID:
+			if (wsm_arg)
+				ret = wsm_write_mib_confirm(priv, wsm_arg,
+							    &wsm_buf);
+			break;
+		case WSM_START_SCAN_RESP_ID:
+			if (wsm_arg)
+				ret = wsm_scan_started(priv, wsm_arg, &wsm_buf);
+			break;
+		case WSM_CONFIGURATION_RESP_ID:
+			if (wsm_arg)
+				ret = wsm_configuration_confirm(priv, wsm_arg,
+								&wsm_buf);
+			break;
+		case WSM_JOIN_RESP_ID:
+			if (wsm_arg)
+				ret = wsm_join_confirm(priv, wsm_arg, &wsm_buf);
+			break;
+		case WSM_STOP_SCAN_RESP_ID:
+		case WSM_RESET_RESP_ID:
+		case WSM_ADD_KEY_RESP_ID:
+		case WSM_REMOVE_KEY_RESP_ID:
+		case WSM_SET_PM_RESP_ID:
+		case WSM_SET_BSS_PARAMS_RESP_ID:
+		case 0x0412: /* set_tx_queue_params */
+		case WSM_EDCA_PARAMS_RESP_ID:
+		case WSM_SWITCH_CHANNEL_RESP_ID:
+		case WSM_START_RESP_ID:
+		case WSM_BEACON_TRANSMIT_RESP_ID:
+		case 0x0419: /* start_find */
+		case 0x041A: /* stop_find */
+		case 0x041B: /* update_ie */
+		case 0x041C: /* map_link */
+			WARN_ON(wsm_arg != NULL);
+			ret = wsm_generic_confirm(priv, wsm_arg, &wsm_buf);
+			if (ret) {
+				wiphy_warn(priv->hw->wiphy,
+					   "wsm_generic_confirm failed for request 0x%04x.\n",
+					   id & ~0x0400);
+
+				/* often 0x407 and 0x410 occur, this means we're dead.. */
+				if (priv->join_status >= CW1200_JOIN_STATUS_JOINING) {
+					wsm_lock_tx(priv);
+					if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
+						wsm_unlock_tx(priv);
+				}
+			}
+			break;
+		default:
+			wiphy_warn(priv->hw->wiphy,
+				   "Unrecognized confirmation 0x%04x\n",
+				   id & ~0x0400);
+		}
+
+		spin_lock(&priv->wsm_cmd.lock);
+		priv->wsm_cmd.ret = ret;
+		priv->wsm_cmd.done = 1;
+		spin_unlock(&priv->wsm_cmd.lock);
+
+		ret = 0; /* Error response from device should ne stop BH. */
+
+		wake_up(&priv->wsm_cmd_wq);
+	} else if (id & 0x0800) {
+		switch (id) {
+		case WSM_STARTUP_IND_ID:
+			ret = wsm_startup_indication(priv, &wsm_buf);
+			break;
+		case WSM_RECEIVE_IND_ID:
+			ret = wsm_receive_indication(priv, link_id,
+						     &wsm_buf, skb_p);
+			break;
+		case 0x0805:
+			ret = wsm_event_indication(priv, &wsm_buf);
+			break;
+		case WSM_SCAN_COMPLETE_IND_ID:
+			ret = wsm_scan_complete_indication(priv, &wsm_buf);
+			break;
+		case 0x0808:
+			ret = wsm_ba_timeout_indication(priv, &wsm_buf);
+			break;
+		case 0x0809:
+			ret = wsm_set_pm_indication(priv, &wsm_buf);
+			break;
+		case 0x080A:
+			ret = wsm_channel_switch_indication(priv, &wsm_buf);
+			break;
+		case 0x080B:
+			ret = wsm_find_complete_indication(priv, &wsm_buf);
+			break;
+		case 0x080C:
+			ret = wsm_suspend_resume_indication(priv,
+					link_id, &wsm_buf);
+			break;
+		case 0x080F:
+			ret = wsm_join_complete_indication(priv, &wsm_buf);
+			break;
+		default:
+			pr_warn("Unrecognised WSM ID %04x\n", id);
+		}
+	} else {
+		WARN_ON(1);
+		ret = -EINVAL;
+	}
+out:
+	return ret;
+}
+
+static bool wsm_handle_tx_data(struct cw1200_common *priv,
+			       struct wsm_tx *wsm,
+			       const struct ieee80211_tx_info *tx_info,
+			       const struct cw1200_txpriv *txpriv,
+			       struct cw1200_queue *queue)
+{
+	bool handled = false;
+	const struct ieee80211_hdr *frame =
+		(struct ieee80211_hdr *)&((u8 *)wsm)[txpriv->offset];
+	__le16 fctl = frame->frame_control;
+	enum {
+		do_probe,
+		do_drop,
+		do_wep,
+		do_tx,
+	} action = do_tx;
+
+	switch (priv->mode) {
+	case NL80211_IFTYPE_STATION:
+		if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
+			action = do_tx;
+		else if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA)
+			action = do_drop;
+		break;
+	case NL80211_IFTYPE_AP:
+		if (!priv->join_status) {
+			action = do_drop;
+		} else if (!(BIT(txpriv->raw_link_id) &
+			     (BIT(0) | priv->link_id_map))) {
+			wiphy_warn(priv->hw->wiphy,
+				   "A frame with expired link id is dropped.\n");
+			action = do_drop;
+		}
+		if (cw1200_queue_get_generation(wsm->packet_id) >
+				CW1200_MAX_REQUEUE_ATTEMPTS) {
+			/* HACK!!! WSM324 firmware has tendency to requeue
+			 * multicast frames in a loop, causing performance
+			 * drop and high power consumption of the driver.
+			 * In this situation it is better just to drop
+			 * the problematic frame.
+			 */
+			wiphy_warn(priv->hw->wiphy,
+				   "Too many attempts to requeue a frame; dropped.\n");
+			action = do_drop;
+		}
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		if (priv->join_status != CW1200_JOIN_STATUS_IBSS)
+			action = do_drop;
+		break;
+	case NL80211_IFTYPE_MESH_POINT:
+		action = do_tx; /* TODO:  Test me! */
+		break;
+	case NL80211_IFTYPE_MONITOR:
+	default:
+		action = do_drop;
+		break;
+	}
+
+	if (action == do_tx) {
+		if (ieee80211_is_nullfunc(fctl)) {
+			spin_lock(&priv->bss_loss_lock);
+			if (priv->bss_loss_state) {
+				priv->bss_loss_confirm_id = wsm->packet_id;
+				wsm->queue_id = WSM_QUEUE_VOICE;
+			}
+			spin_unlock(&priv->bss_loss_lock);
+		} else if (ieee80211_is_probe_req(fctl)) {
+			action = do_probe;
+		} else if (ieee80211_is_deauth(fctl) &&
+			   priv->mode != NL80211_IFTYPE_AP) {
+			pr_debug("[WSM] Issue unjoin command due to tx deauth.\n");
+			wsm_lock_tx_async(priv);
+			if (queue_work(priv->workqueue,
+				       &priv->unjoin_work) <= 0)
+				wsm_unlock_tx(priv);
+		} else if (ieee80211_has_protected(fctl) &&
+			   tx_info->control.hw_key &&
+			   tx_info->control.hw_key->keyidx != priv->wep_default_key_id &&
+			   (tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+			    tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
+			action = do_wep;
+		}
+	}
+
+	switch (action) {
+	case do_probe:
+		/* An interesting FW "feature". Device filters probe responses.
+		 * The easiest way to get it back is to convert
+		 * probe request into WSM start_scan command.
+		 */
+		pr_debug("[WSM] Convert probe request to scan.\n");
+		wsm_lock_tx_async(priv);
+		priv->pending_frame_id = wsm->packet_id;
+		if (queue_delayed_work(priv->workqueue,
+				       &priv->scan.probe_work, 0) <= 0)
+			wsm_unlock_tx(priv);
+		handled = true;
+		break;
+	case do_drop:
+		pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl);
+		BUG_ON(cw1200_queue_remove(queue, wsm->packet_id));
+		handled = true;
+		break;
+	case do_wep:
+		pr_debug("[WSM] Issue set_default_wep_key.\n");
+		wsm_lock_tx_async(priv);
+		priv->wep_default_key_id = tx_info->control.hw_key->keyidx;
+		priv->pending_frame_id = wsm->packet_id;
+		if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0)
+			wsm_unlock_tx(priv);
+		handled = true;
+		break;
+	case do_tx:
+		pr_debug("[WSM] Transmit frame.\n");
+		break;
+	default:
+		/* Do nothing */
+		break;
+	}
+	return handled;
+}
+
+static int cw1200_get_prio_queue(struct cw1200_common *priv,
+				 u32 link_id_map, int *total)
+{
+	static const int urgent = BIT(CW1200_LINK_ID_AFTER_DTIM) |
+		BIT(CW1200_LINK_ID_UAPSD);
+	struct wsm_edca_queue_params *edca;
+	unsigned score, best = -1;
+	int winner = -1;
+	int queued;
+	int i;
+
+	/* search for a winner using edca params */
+	for (i = 0; i < 4; ++i) {
+		queued = cw1200_queue_get_num_queued(&priv->tx_queue[i],
+				link_id_map);
+		if (!queued)
+			continue;
+		*total += queued;
+		edca = &priv->edca.params[i];
+		score = ((edca->aifns + edca->cwmin) << 16) +
+			((edca->cwmax - edca->cwmin) *
+			 (get_random_int() & 0xFFFF));
+		if (score < best && (winner < 0 || i != 3)) {
+			best = score;
+			winner = i;
+		}
+	}
+
+	/* override winner if bursting */
+	if (winner >= 0 && priv->tx_burst_idx >= 0 &&
+	    winner != priv->tx_burst_idx &&
+	    !cw1200_queue_get_num_queued(
+		    &priv->tx_queue[winner],
+		    link_id_map & urgent) &&
+	    cw1200_queue_get_num_queued(
+		    &priv->tx_queue[priv->tx_burst_idx],
+		    link_id_map))
+		winner = priv->tx_burst_idx;
+
+	return winner;
+}
+
+static int wsm_get_tx_queue_and_mask(struct cw1200_common *priv,
+				     struct cw1200_queue **queue_p,
+				     u32 *tx_allowed_mask_p,
+				     bool *more)
+{
+	int idx;
+	u32 tx_allowed_mask;
+	int total = 0;
+
+	/* Search for a queue with multicast frames buffered */
+	if (priv->tx_multicast) {
+		tx_allowed_mask = BIT(CW1200_LINK_ID_AFTER_DTIM);
+		idx = cw1200_get_prio_queue(priv,
+				tx_allowed_mask, &total);
+		if (idx >= 0) {
+			*more = total > 1;
+			goto found;
+		}
+	}
+
+	/* Search for unicast traffic */
+	tx_allowed_mask = ~priv->sta_asleep_mask;
+	tx_allowed_mask |= BIT(CW1200_LINK_ID_UAPSD);
+	if (priv->sta_asleep_mask) {
+		tx_allowed_mask |= priv->pspoll_mask;
+		tx_allowed_mask &= ~BIT(CW1200_LINK_ID_AFTER_DTIM);
+	} else {
+		tx_allowed_mask |= BIT(CW1200_LINK_ID_AFTER_DTIM);
+	}
+	idx = cw1200_get_prio_queue(priv,
+			tx_allowed_mask, &total);
+	if (idx < 0)
+		return -ENOENT;
+
+found:
+	*queue_p = &priv->tx_queue[idx];
+	*tx_allowed_mask_p = tx_allowed_mask;
+	return 0;
+}
+
+int wsm_get_tx(struct cw1200_common *priv, u8 **data,
+	       size_t *tx_len, int *burst)
+{
+	struct wsm_tx *wsm = NULL;
+	struct ieee80211_tx_info *tx_info;
+	struct cw1200_queue *queue = NULL;
+	int queue_num;
+	u32 tx_allowed_mask = 0;
+	const struct cw1200_txpriv *txpriv = NULL;
+	int count = 0;
+
+	/* More is used only for broadcasts. */
+	bool more = false;
+
+	if (priv->wsm_cmd.ptr) { /* CMD request */
+		++count;
+		spin_lock(&priv->wsm_cmd.lock);
+		BUG_ON(!priv->wsm_cmd.ptr);
+		*data = priv->wsm_cmd.ptr;
+		*tx_len = priv->wsm_cmd.len;
+		*burst = 1;
+		spin_unlock(&priv->wsm_cmd.lock);
+	} else {
+		for (;;) {
+			int ret;
+
+			if (atomic_add_return(0, &priv->tx_lock))
+				break;
+
+			spin_lock_bh(&priv->ps_state_lock);
+
+			ret = wsm_get_tx_queue_and_mask(priv, &queue,
+							&tx_allowed_mask, &more);
+			queue_num = queue - priv->tx_queue;
+
+			if (priv->buffered_multicasts &&
+			    (ret || !more) &&
+			    (priv->tx_multicast || !priv->sta_asleep_mask)) {
+				priv->buffered_multicasts = false;
+				if (priv->tx_multicast) {
+					priv->tx_multicast = false;
+					queue_work(priv->workqueue,
+						   &priv->multicast_stop_work);
+				}
+			}
+
+			spin_unlock_bh(&priv->ps_state_lock);
+
+			if (ret)
+				break;
+
+			if (cw1200_queue_get(queue,
+					     tx_allowed_mask,
+					     &wsm, &tx_info, &txpriv))
+				continue;
+
+			if (wsm_handle_tx_data(priv, wsm,
+					       tx_info, txpriv, queue))
+				continue;  /* Handled by WSM */
+
+			wsm->hdr.id &= __cpu_to_le16(
+				~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX));
+			wsm->hdr.id |= cpu_to_le16(
+				WSM_TX_LINK_ID(txpriv->raw_link_id));
+			priv->pspoll_mask &= ~BIT(txpriv->raw_link_id);
+
+			*data = (u8 *)wsm;
+			*tx_len = __le16_to_cpu(wsm->hdr.len);
+
+			/* allow bursting if txop is set */
+			if (priv->edca.params[queue_num].txop_limit)
+				*burst = min(*burst,
+					     (int)cw1200_queue_get_num_queued(queue, tx_allowed_mask) + 1);
+			else
+				*burst = 1;
+
+			/* store index of bursting queue */
+			if (*burst > 1)
+				priv->tx_burst_idx = queue_num;
+			else
+				priv->tx_burst_idx = -1;
+
+			if (more) {
+				struct ieee80211_hdr *hdr =
+					(struct ieee80211_hdr *)
+					&((u8 *)wsm)[txpriv->offset];
+				/* more buffered multicast/broadcast frames
+				 *  ==> set MoreData flag in IEEE 802.11 header
+				 *  to inform PS STAs
+				 */
+				hdr->frame_control |=
+					cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+			}
+
+			pr_debug("[WSM] >>> 0x%.4X (%zu) %p %c\n",
+				 0x0004, *tx_len, *data,
+				 wsm->more ? 'M' : ' ');
+			++count;
+			break;
+		}
+	}
+
+	return count;
+}
+
+void wsm_txed(struct cw1200_common *priv, u8 *data)
+{
+	if (data == priv->wsm_cmd.ptr) {
+		spin_lock(&priv->wsm_cmd.lock);
+		priv->wsm_cmd.ptr = NULL;
+		spin_unlock(&priv->wsm_cmd.lock);
+	}
+}
+
+/* ******************************************************************** */
+/* WSM buffer								*/
+
+void wsm_buf_init(struct wsm_buf *buf)
+{
+	BUG_ON(buf->begin);
+	buf->begin = kmalloc(FWLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
+	buf->end = buf->begin ? &buf->begin[FWLOAD_BLOCK_SIZE] : buf->begin;
+	wsm_buf_reset(buf);
+}
+
+void wsm_buf_deinit(struct wsm_buf *buf)
+{
+	kfree(buf->begin);
+	buf->begin = buf->data = buf->end = NULL;
+}
+
+static void wsm_buf_reset(struct wsm_buf *buf)
+{
+	if (buf->begin) {
+		buf->data = &buf->begin[4];
+		*(u32 *)buf->begin = 0;
+	} else {
+		buf->data = buf->begin;
+	}
+}
+
+static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size)
+{
+	size_t pos = buf->data - buf->begin;
+	size_t size = pos + extra_size;
+
+	size = round_up(size, FWLOAD_BLOCK_SIZE);
+
+	buf->begin = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA);
+	if (buf->begin) {
+		buf->data = &buf->begin[pos];
+		buf->end = &buf->begin[size];
+		return 0;
+	} else {
+		buf->end = buf->data = buf->begin;
+		return -ENOMEM;
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/cw1200/wsm.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/wsm.h
--- linux-libre-3.10-gnu/drivers/net/wireless/cw1200/wsm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/cw1200/wsm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1870 @@
+/*
+ * WSM host interface (HI) interface for ST-Ericsson CW1200 mac80211 drivers
+ *
+ * Copyright (c) 2010, ST-Ericsson
+ * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ *
+ * Based on CW1200 UMAC WSM API, which is
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Stewart Mathers <stewart.mathers@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef CW1200_WSM_H_INCLUDED
+#define CW1200_WSM_H_INCLUDED
+
+#include <linux/spinlock.h>
+
+struct cw1200_common;
+
+/* Bands */
+/* Radio band 2.412 -2.484 GHz. */
+#define WSM_PHY_BAND_2_4G		(0)
+
+/* Radio band 4.9375-5.8250 GHz. */
+#define WSM_PHY_BAND_5G			(1)
+
+/* Transmit rates */
+/* 1   Mbps            ERP-DSSS */
+#define WSM_TRANSMIT_RATE_1		(0)
+
+/* 2   Mbps            ERP-DSSS */
+#define WSM_TRANSMIT_RATE_2		(1)
+
+/* 5.5 Mbps            ERP-CCK */
+#define WSM_TRANSMIT_RATE_5		(2)
+
+/* 11  Mbps            ERP-CCK */
+#define WSM_TRANSMIT_RATE_11		(3)
+
+/* 22  Mbps            ERP-PBCC (Not supported) */
+/* #define WSM_TRANSMIT_RATE_22		(4) */
+
+/* 33  Mbps            ERP-PBCC (Not supported) */
+/* #define WSM_TRANSMIT_RATE_33		(5) */
+
+/* 6   Mbps   (3 Mbps) ERP-OFDM, BPSK coding rate 1/2 */
+#define WSM_TRANSMIT_RATE_6		(6)
+
+/* 9   Mbps (4.5 Mbps) ERP-OFDM, BPSK coding rate 3/4 */
+#define WSM_TRANSMIT_RATE_9		(7)
+
+/* 12  Mbps  (6 Mbps)  ERP-OFDM, QPSK coding rate 1/2 */
+#define WSM_TRANSMIT_RATE_12		(8)
+
+/* 18  Mbps  (9 Mbps)  ERP-OFDM, QPSK coding rate 3/4 */
+#define WSM_TRANSMIT_RATE_18		(9)
+
+/* 24  Mbps (12 Mbps)  ERP-OFDM, 16QAM coding rate 1/2 */
+#define WSM_TRANSMIT_RATE_24		(10)
+
+/* 36  Mbps (18 Mbps)  ERP-OFDM, 16QAM coding rate 3/4 */
+#define WSM_TRANSMIT_RATE_36		(11)
+
+/* 48  Mbps (24 Mbps)  ERP-OFDM, 64QAM coding rate 1/2 */
+#define WSM_TRANSMIT_RATE_48		(12)
+
+/* 54  Mbps (27 Mbps)  ERP-OFDM, 64QAM coding rate 3/4 */
+#define WSM_TRANSMIT_RATE_54		(13)
+
+/* 6.5 Mbps            HT-OFDM, BPSK coding rate 1/2 */
+#define WSM_TRANSMIT_RATE_HT_6		(14)
+
+/* 13  Mbps            HT-OFDM, QPSK coding rate 1/2 */
+#define WSM_TRANSMIT_RATE_HT_13		(15)
+
+/* 19.5 Mbps           HT-OFDM, QPSK coding rate 3/4 */
+#define WSM_TRANSMIT_RATE_HT_19		(16)
+
+/* 26  Mbps            HT-OFDM, 16QAM coding rate 1/2 */
+#define WSM_TRANSMIT_RATE_HT_26		(17)
+
+/* 39  Mbps            HT-OFDM, 16QAM coding rate 3/4 */
+#define WSM_TRANSMIT_RATE_HT_39		(18)
+
+/* 52  Mbps            HT-OFDM, 64QAM coding rate 2/3 */
+#define WSM_TRANSMIT_RATE_HT_52		(19)
+
+/* 58.5 Mbps           HT-OFDM, 64QAM coding rate 3/4 */
+#define WSM_TRANSMIT_RATE_HT_58		(20)
+
+/* 65  Mbps            HT-OFDM, 64QAM coding rate 5/6 */
+#define WSM_TRANSMIT_RATE_HT_65		(21)
+
+/* Scan types */
+/* Foreground scan */
+#define WSM_SCAN_TYPE_FOREGROUND	(0)
+
+/* Background scan */
+#define WSM_SCAN_TYPE_BACKGROUND	(1)
+
+/* Auto scan */
+#define WSM_SCAN_TYPE_AUTO		(2)
+
+/* Scan flags */
+/* Forced background scan means if the station cannot */
+/* enter the power-save mode, it shall force to perform a */
+/* background scan. Only valid when ScanType is */
+/* background scan. */
+#define WSM_SCAN_FLAG_FORCE_BACKGROUND	(BIT(0))
+
+/* The WLAN device scans one channel at a time so */
+/* that disturbance to the data traffic is minimized. */
+#define WSM_SCAN_FLAG_SPLIT_METHOD	(BIT(1))
+
+/* Preamble Type. Long if not set. */
+#define WSM_SCAN_FLAG_SHORT_PREAMBLE	(BIT(2))
+
+/* 11n Tx Mode. Mixed if not set. */
+#define WSM_SCAN_FLAG_11N_GREENFIELD	(BIT(3))
+
+/* Scan constraints */
+/* Maximum number of channels to be scanned. */
+#define WSM_SCAN_MAX_NUM_OF_CHANNELS	(48)
+
+/* The maximum number of SSIDs that the device can scan for. */
+#define WSM_SCAN_MAX_NUM_OF_SSIDS	(2)
+
+/* Power management modes */
+/* 802.11 Active mode */
+#define WSM_PSM_ACTIVE			(0)
+
+/* 802.11 PS mode */
+#define WSM_PSM_PS			BIT(0)
+
+/* Fast Power Save bit */
+#define WSM_PSM_FAST_PS_FLAG		BIT(7)
+
+/* Dynamic aka Fast power save */
+#define WSM_PSM_FAST_PS			(BIT(0) | BIT(7))
+
+/* Undetermined */
+/* Note : Undetermined status is reported when the */
+/* NULL data frame used to advertise the PM mode to */
+/* the AP at Pre or Post Background Scan is not Acknowledged */
+#define WSM_PSM_UNKNOWN			BIT(1)
+
+/* Queue IDs */
+/* best effort/legacy */
+#define WSM_QUEUE_BEST_EFFORT		(0)
+
+/* background */
+#define WSM_QUEUE_BACKGROUND		(1)
+
+/* video */
+#define WSM_QUEUE_VIDEO			(2)
+
+/* voice */
+#define WSM_QUEUE_VOICE			(3)
+
+/* HT TX parameters */
+/* Non-HT */
+#define WSM_HT_TX_NON_HT		(0)
+
+/* Mixed format */
+#define WSM_HT_TX_MIXED			(1)
+
+/* Greenfield format */
+#define WSM_HT_TX_GREENFIELD		(2)
+
+/* STBC allowed */
+#define WSM_HT_TX_STBC			(BIT(7))
+
+/* EPTA prioirty flags for BT Coex */
+/* default epta priority */
+#define WSM_EPTA_PRIORITY_DEFAULT	4
+/* use for normal data */
+#define WSM_EPTA_PRIORITY_DATA		4
+/* use for connect/disconnect/roaming*/
+#define WSM_EPTA_PRIORITY_MGT		5
+/* use for action frames */
+#define WSM_EPTA_PRIORITY_ACTION	5
+/* use for AC_VI data */
+#define WSM_EPTA_PRIORITY_VIDEO		5
+/* use for AC_VO data */
+#define WSM_EPTA_PRIORITY_VOICE		6
+/* use for EAPOL exchange */
+#define WSM_EPTA_PRIORITY_EAPOL		7
+
+/* TX status */
+/* Frame was sent aggregated */
+/* Only valid for WSM_SUCCESS status. */
+#define WSM_TX_STATUS_AGGREGATION	(BIT(0))
+
+/* Host should requeue this frame later. */
+/* Valid only when status is WSM_REQUEUE. */
+#define WSM_TX_STATUS_REQUEUE		(BIT(1))
+
+/* Normal Ack */
+#define WSM_TX_STATUS_NORMAL_ACK	(0<<2)
+
+/* No Ack */
+#define WSM_TX_STATUS_NO_ACK		(1<<2)
+
+/* No explicit acknowledgement */
+#define WSM_TX_STATUS_NO_EXPLICIT_ACK	(2<<2)
+
+/* Block Ack */
+/* Only valid for WSM_SUCCESS status. */
+#define WSM_TX_STATUS_BLOCK_ACK		(3<<2)
+
+/* RX status */
+/* Unencrypted */
+#define WSM_RX_STATUS_UNENCRYPTED	(0<<0)
+
+/* WEP */
+#define WSM_RX_STATUS_WEP		(1<<0)
+
+/* TKIP */
+#define WSM_RX_STATUS_TKIP		(2<<0)
+
+/* AES */
+#define WSM_RX_STATUS_AES		(3<<0)
+
+/* WAPI */
+#define WSM_RX_STATUS_WAPI		(4<<0)
+
+/* Macro to fetch encryption subfield. */
+#define WSM_RX_STATUS_ENCRYPTION(status) ((status) & 0x07)
+
+/* Frame was part of an aggregation */
+#define WSM_RX_STATUS_AGGREGATE		(BIT(3))
+
+/* Frame was first in the aggregation */
+#define WSM_RX_STATUS_AGGREGATE_FIRST	(BIT(4))
+
+/* Frame was last in the aggregation */
+#define WSM_RX_STATUS_AGGREGATE_LAST	(BIT(5))
+
+/* Indicates a defragmented frame */
+#define WSM_RX_STATUS_DEFRAGMENTED	(BIT(6))
+
+/* Indicates a Beacon frame */
+#define WSM_RX_STATUS_BEACON		(BIT(7))
+
+/* Indicates STA bit beacon TIM field */
+#define WSM_RX_STATUS_TIM		(BIT(8))
+
+/* Indicates Beacon frame's virtual bitmap contains multicast bit */
+#define WSM_RX_STATUS_MULTICAST		(BIT(9))
+
+/* Indicates frame contains a matching SSID */
+#define WSM_RX_STATUS_MATCHING_SSID	(BIT(10))
+
+/* Indicates frame contains a matching BSSI */
+#define WSM_RX_STATUS_MATCHING_BSSI	(BIT(11))
+
+/* Indicates More bit set in Framectl field */
+#define WSM_RX_STATUS_MORE_DATA		(BIT(12))
+
+/* Indicates frame received during a measurement process */
+#define WSM_RX_STATUS_MEASUREMENT	(BIT(13))
+
+/* Indicates frame received as an HT packet */
+#define WSM_RX_STATUS_HT		(BIT(14))
+
+/* Indicates frame received with STBC */
+#define WSM_RX_STATUS_STBC		(BIT(15))
+
+/* Indicates Address 1 field matches dot11StationId */
+#define WSM_RX_STATUS_ADDRESS1		(BIT(16))
+
+/* Indicates Group address present in the Address 1 field */
+#define WSM_RX_STATUS_GROUP		(BIT(17))
+
+/* Indicates Broadcast address present in the Address 1 field */
+#define WSM_RX_STATUS_BROADCAST		(BIT(18))
+
+/* Indicates group key used with encrypted frames */
+#define WSM_RX_STATUS_GROUP_KEY		(BIT(19))
+
+/* Macro to fetch encryption key index. */
+#define WSM_RX_STATUS_KEY_IDX(status)	(((status >> 20)) & 0x0F)
+
+/* Indicates TSF inclusion after 802.11 frame body */
+#define WSM_RX_STATUS_TSF_INCLUDED	(BIT(24))
+
+/* Frame Control field starts at Frame offset + 2 */
+#define WSM_TX_2BYTES_SHIFT		(BIT(7))
+
+/* Join mode */
+/* IBSS */
+#define WSM_JOIN_MODE_IBSS		(0)
+
+/* BSS */
+#define WSM_JOIN_MODE_BSS		(1)
+
+/* PLCP preamble type */
+/* For long preamble */
+#define WSM_JOIN_PREAMBLE_LONG		(0)
+
+/* For short preamble (Long for 1Mbps) */
+#define WSM_JOIN_PREAMBLE_SHORT		(1)
+
+/* For short preamble (Long for 1 and 2Mbps) */
+#define WSM_JOIN_PREAMBLE_SHORT_2	(2)
+
+/* Join flags */
+/* Unsynchronized */
+#define WSM_JOIN_FLAGS_UNSYNCRONIZED	BIT(0)
+/* The BSS owner is a P2P GO */
+#define WSM_JOIN_FLAGS_P2P_GO		BIT(1)
+/* Force to join BSS with the BSSID and the
+ * SSID specified without waiting for beacons. The
+ * ProbeForJoin parameter is ignored.
+ */
+#define WSM_JOIN_FLAGS_FORCE		BIT(2)
+/* Give probe request/response higher
+ * priority over the BT traffic
+ */
+#define WSM_JOIN_FLAGS_PRIO		BIT(3)
+/* Issue immediate join confirmation and use
+ * join complete to notify about completion
+ */
+#define WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND BIT(5)
+
+/* Key types */
+#define WSM_KEY_TYPE_WEP_DEFAULT	(0)
+#define WSM_KEY_TYPE_WEP_PAIRWISE	(1)
+#define WSM_KEY_TYPE_TKIP_GROUP		(2)
+#define WSM_KEY_TYPE_TKIP_PAIRWISE	(3)
+#define WSM_KEY_TYPE_AES_GROUP		(4)
+#define WSM_KEY_TYPE_AES_PAIRWISE	(5)
+#define WSM_KEY_TYPE_WAPI_GROUP		(6)
+#define WSM_KEY_TYPE_WAPI_PAIRWISE	(7)
+
+/* Key indexes */
+#define WSM_KEY_MAX_INDEX		(10)
+
+/* ACK policy */
+#define WSM_ACK_POLICY_NORMAL		(0)
+#define WSM_ACK_POLICY_NO_ACK		(1)
+
+/* Start modes */
+#define WSM_START_MODE_AP		(0)	/* Mini AP */
+#define WSM_START_MODE_P2P_GO		(1)	/* P2P GO */
+#define WSM_START_MODE_P2P_DEV		(2)	/* P2P device */
+
+/* SetAssociationMode MIB flags */
+#define WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE		(BIT(0))
+#define WSM_ASSOCIATION_MODE_USE_HT_MODE		(BIT(1))
+#define WSM_ASSOCIATION_MODE_USE_BASIC_RATE_SET		(BIT(2))
+#define WSM_ASSOCIATION_MODE_USE_MPDU_START_SPACING	(BIT(3))
+#define WSM_ASSOCIATION_MODE_SNOOP_ASSOC_FRAMES		(BIT(4))
+
+/* RcpiRssiThreshold MIB flags */
+#define WSM_RCPI_RSSI_THRESHOLD_ENABLE	(BIT(0))
+#define WSM_RCPI_RSSI_USE_RSSI		(BIT(1))
+#define WSM_RCPI_RSSI_DONT_USE_UPPER	(BIT(2))
+#define WSM_RCPI_RSSI_DONT_USE_LOWER	(BIT(3))
+
+/* Update-ie constants */
+#define WSM_UPDATE_IE_BEACON		(BIT(0))
+#define WSM_UPDATE_IE_PROBE_RESP	(BIT(1))
+#define WSM_UPDATE_IE_PROBE_REQ		(BIT(2))
+
+/* WSM events */
+/* Error */
+#define WSM_EVENT_ERROR			(0)
+
+/* BSS lost */
+#define WSM_EVENT_BSS_LOST		(1)
+
+/* BSS regained */
+#define WSM_EVENT_BSS_REGAINED		(2)
+
+/* Radar detected */
+#define WSM_EVENT_RADAR_DETECTED	(3)
+
+/* RCPI or RSSI threshold triggered */
+#define WSM_EVENT_RCPI_RSSI		(4)
+
+/* BT inactive */
+#define WSM_EVENT_BT_INACTIVE		(5)
+
+/* BT active */
+#define WSM_EVENT_BT_ACTIVE		(6)
+
+/* MIB IDs */
+/* 4.1  dot11StationId */
+#define WSM_MIB_ID_DOT11_STATION_ID		0x0000
+
+/* 4.2  dot11MaxtransmitMsduLifeTime */
+#define WSM_MIB_ID_DOT11_MAX_TRANSMIT_LIFTIME	0x0001
+
+/* 4.3  dot11MaxReceiveLifeTime */
+#define WSM_MIB_ID_DOT11_MAX_RECEIVE_LIFETIME	0x0002
+
+/* 4.4  dot11SlotTime */
+#define WSM_MIB_ID_DOT11_SLOT_TIME		0x0003
+
+/* 4.5  dot11GroupAddressesTable */
+#define WSM_MIB_ID_DOT11_GROUP_ADDRESSES_TABLE	0x0004
+#define WSM_MAX_GRP_ADDRTABLE_ENTRIES		8
+
+/* 4.6  dot11WepDefaultKeyId */
+#define WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID	0x0005
+
+/* 4.7  dot11CurrentTxPowerLevel */
+#define WSM_MIB_ID_DOT11_CURRENT_TX_POWER_LEVEL	0x0006
+
+/* 4.8  dot11RTSThreshold */
+#define WSM_MIB_ID_DOT11_RTS_THRESHOLD		0x0007
+
+/* 4.9  NonErpProtection */
+#define WSM_MIB_ID_NON_ERP_PROTECTION		0x1000
+
+/* 4.10 ArpIpAddressesTable */
+#define WSM_MIB_ID_ARP_IP_ADDRESSES_TABLE	0x1001
+#define WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES	1
+
+/* 4.11 TemplateFrame */
+#define WSM_MIB_ID_TEMPLATE_FRAME		0x1002
+
+/* 4.12 RxFilter */
+#define WSM_MIB_ID_RX_FILTER			0x1003
+
+/* 4.13 BeaconFilterTable */
+#define WSM_MIB_ID_BEACON_FILTER_TABLE		0x1004
+
+/* 4.14 BeaconFilterEnable */
+#define WSM_MIB_ID_BEACON_FILTER_ENABLE		0x1005
+
+/* 4.15 OperationalPowerMode */
+#define WSM_MIB_ID_OPERATIONAL_POWER_MODE	0x1006
+
+/* 4.16 BeaconWakeUpPeriod */
+#define WSM_MIB_ID_BEACON_WAKEUP_PERIOD		0x1007
+
+/* 4.17 RcpiRssiThreshold */
+#define WSM_MIB_ID_RCPI_RSSI_THRESHOLD		0x1009
+
+/* 4.18 StatisticsTable */
+#define WSM_MIB_ID_STATISTICS_TABLE		0x100A
+
+/* 4.19 IbssPsConfig */
+#define WSM_MIB_ID_IBSS_PS_CONFIG		0x100B
+
+/* 4.20 CountersTable */
+#define WSM_MIB_ID_COUNTERS_TABLE		0x100C
+
+/* 4.21 BlockAckPolicy */
+#define WSM_MIB_ID_BLOCK_ACK_POLICY		0x100E
+
+/* 4.22 OverrideInternalTxRate */
+#define WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE	0x100F
+
+/* 4.23 SetAssociationMode */
+#define WSM_MIB_ID_SET_ASSOCIATION_MODE		0x1010
+
+/* 4.24 UpdateEptaConfigData */
+#define WSM_MIB_ID_UPDATE_EPTA_CONFIG_DATA	0x1011
+
+/* 4.25 SelectCcaMethod */
+#define WSM_MIB_ID_SELECT_CCA_METHOD		0x1012
+
+/* 4.26 SetUpasdInformation */
+#define WSM_MIB_ID_SET_UAPSD_INFORMATION	0x1013
+
+/* 4.27 SetAutoCalibrationMode  WBF00004073 */
+#define WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE	0x1015
+
+/* 4.28 SetTxRateRetryPolicy */
+#define WSM_MIB_ID_SET_TX_RATE_RETRY_POLICY	0x1016
+
+/* 4.29 SetHostMessageTypeFilter */
+#define WSM_MIB_ID_SET_HOST_MSG_TYPE_FILTER	0x1017
+
+/* 4.30 P2PFindInfo */
+#define WSM_MIB_ID_P2P_FIND_INFO		0x1018
+
+/* 4.31 P2PPsModeInfo */
+#define WSM_MIB_ID_P2P_PS_MODE_INFO		0x1019
+
+/* 4.32 SetEtherTypeDataFrameFilter */
+#define WSM_MIB_ID_SET_ETHERTYPE_DATAFRAME_FILTER 0x101A
+
+/* 4.33 SetUDPPortDataFrameFilter */
+#define WSM_MIB_ID_SET_UDPPORT_DATAFRAME_FILTER	0x101B
+
+/* 4.34 SetMagicDataFrameFilter */
+#define WSM_MIB_ID_SET_MAGIC_DATAFRAME_FILTER	0x101C
+
+/* 4.35 P2PDeviceInfo */
+#define WSM_MIB_ID_P2P_DEVICE_INFO		0x101D
+
+/* 4.36 SetWCDMABand */
+#define WSM_MIB_ID_SET_WCDMA_BAND		0x101E
+
+/* 4.37 GroupTxSequenceCounter */
+#define WSM_MIB_ID_GRP_SEQ_COUNTER		0x101F
+
+/* 4.38 ProtectedMgmtPolicy */
+#define WSM_MIB_ID_PROTECTED_MGMT_POLICY	0x1020
+
+/* 4.39 SetHtProtection */
+#define WSM_MIB_ID_SET_HT_PROTECTION		0x1021
+
+/* 4.40 GPIO Command */
+#define WSM_MIB_ID_GPIO_COMMAND			0x1022
+
+/* 4.41 TSF Counter Value */
+#define WSM_MIB_ID_TSF_COUNTER			0x1023
+
+/* Test Purposes Only */
+#define WSM_MIB_ID_BLOCK_ACK_INFO		0x100D
+
+/* 4.42 UseMultiTxConfMessage */
+#define WSM_MIB_USE_MULTI_TX_CONF		0x1024
+
+/* 4.43 Keep-alive period */
+#define WSM_MIB_ID_KEEP_ALIVE_PERIOD		0x1025
+
+/* 4.44 Disable BSSID filter */
+#define WSM_MIB_ID_DISABLE_BSSID_FILTER		0x1026
+
+/* Frame template types */
+#define WSM_FRAME_TYPE_PROBE_REQUEST	(0)
+#define WSM_FRAME_TYPE_BEACON		(1)
+#define WSM_FRAME_TYPE_NULL		(2)
+#define WSM_FRAME_TYPE_QOS_NULL		(3)
+#define WSM_FRAME_TYPE_PS_POLL		(4)
+#define WSM_FRAME_TYPE_PROBE_RESPONSE	(5)
+
+#define WSM_FRAME_GREENFIELD		(0x80)	/* See 4.11 */
+
+/* Status */
+/* The WSM firmware has completed a request */
+/* successfully. */
+#define WSM_STATUS_SUCCESS              (0)
+
+/* This is a generic failure code if other error codes do */
+/* not apply. */
+#define WSM_STATUS_FAILURE              (1)
+
+/* A request contains one or more invalid parameters. */
+#define WSM_INVALID_PARAMETER           (2)
+
+/* The request cannot perform because the device is in */
+/* an inappropriate mode. */
+#define WSM_ACCESS_DENIED               (3)
+
+/* The frame received includes a decryption error. */
+#define WSM_STATUS_DECRYPTFAILURE       (4)
+
+/* A MIC failure is detected in the received packets. */
+#define WSM_STATUS_MICFAILURE           (5)
+
+/* The transmit request failed due to retry limit being */
+/* exceeded. */
+#define WSM_STATUS_RETRY_EXCEEDED       (6)
+
+/* The transmit request failed due to MSDU life time */
+/* being exceeded. */
+#define WSM_STATUS_TX_LIFETIME_EXCEEDED (7)
+
+/* The link to the AP is lost. */
+#define WSM_STATUS_LINK_LOST            (8)
+
+/* No key was found for the encrypted frame */
+#define WSM_STATUS_NO_KEY_FOUND         (9)
+
+/* Jammer was detected when transmitting this frame */
+#define WSM_STATUS_JAMMER_DETECTED      (10)
+
+/* The message should be requeued later. */
+/* This is applicable only to Transmit */
+#define WSM_REQUEUE                     (11)
+
+/* Advanced filtering options */
+#define WSM_MAX_FILTER_ELEMENTS		(4)
+
+#define WSM_FILTER_ACTION_IGNORE	(0)
+#define WSM_FILTER_ACTION_FILTER_IN	(1)
+#define WSM_FILTER_ACTION_FILTER_OUT	(2)
+
+#define WSM_FILTER_PORT_TYPE_DST	(0)
+#define WSM_FILTER_PORT_TYPE_SRC	(1)
+
+/* Actual header of WSM messages */
+struct wsm_hdr {
+	__le16 len;
+	__le16 id;
+};
+
+#define WSM_TX_SEQ_MAX			(7)
+#define WSM_TX_SEQ(seq)			\
+		((seq & WSM_TX_SEQ_MAX) << 13)
+#define WSM_TX_LINK_ID_MAX		(0x0F)
+#define WSM_TX_LINK_ID(link_id)		\
+		((link_id & WSM_TX_LINK_ID_MAX) << 6)
+
+#define MAX_BEACON_SKIP_TIME_MS 1000
+
+#define WSM_CMD_LAST_CHANCE_TIMEOUT (HZ * 3 / 2)
+
+/* ******************************************************************** */
+/* WSM capability							*/
+
+#define WSM_STARTUP_IND_ID 0x0801
+
+struct wsm_startup_ind {
+	u16 input_buffers;
+	u16 input_buffer_size;
+	u16 status;
+	u16 hw_id;
+	u16 hw_subid;
+	u16 fw_cap;
+	u16 fw_type;
+	u16 fw_api;
+	u16 fw_build;
+	u16 fw_ver;
+	char fw_label[128];
+	u32 config[4];
+};
+
+/* ******************************************************************** */
+/* WSM commands								*/
+
+/* 3.1 */
+#define WSM_CONFIGURATION_REQ_ID 0x0009
+#define WSM_CONFIGURATION_RESP_ID 0x0409
+
+struct wsm_tx_power_range {
+	int min_power_level;
+	int max_power_level;
+	u32 stepping;
+};
+
+struct wsm_configuration {
+	/* [in] */ u32 dot11MaxTransmitMsduLifeTime;
+	/* [in] */ u32 dot11MaxReceiveLifeTime;
+	/* [in] */ u32 dot11RtsThreshold;
+	/* [in, out] */ u8 *dot11StationId;
+	/* [in] */ const void *dpdData;
+	/* [in] */ size_t dpdData_size;
+	/* [out] */ u8 dot11FrequencyBandsSupported;
+	/* [out] */ u32 supportedRateMask;
+	/* [out] */ struct wsm_tx_power_range txPowerRange[2];
+};
+
+int wsm_configuration(struct cw1200_common *priv,
+		      struct wsm_configuration *arg);
+
+/* 3.3 */
+#define WSM_RESET_REQ_ID 0x000A
+#define WSM_RESET_RESP_ID 0x040A
+struct wsm_reset {
+	/* [in] */ int link_id;
+	/* [in] */ bool reset_statistics;
+};
+
+int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg);
+
+/* 3.5 */
+#define WSM_READ_MIB_REQ_ID 0x0005
+#define WSM_READ_MIB_RESP_ID 0x0405
+int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *buf,
+		 size_t buf_size);
+
+/* 3.7 */
+#define WSM_WRITE_MIB_REQ_ID 0x0006
+#define WSM_WRITE_MIB_RESP_ID 0x0406
+int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *buf,
+		  size_t buf_size);
+
+/* 3.9 */
+#define WSM_START_SCAN_REQ_ID 0x0007
+#define WSM_START_SCAN_RESP_ID 0x0407
+
+struct wsm_ssid {
+	u8 ssid[32];
+	u32 length;
+};
+
+struct wsm_scan_ch {
+	u16 number;
+	u32 min_chan_time;
+	u32 max_chan_time;
+	u32 tx_power_level;
+};
+
+struct wsm_scan {
+	/* WSM_PHY_BAND_... */
+	u8 band;
+
+	/* WSM_SCAN_TYPE_... */
+	u8 type;
+
+	/* WSM_SCAN_FLAG_... */
+	u8 flags;
+
+	/* WSM_TRANSMIT_RATE_... */
+	u8 max_tx_rate;
+
+	/* Interval period in TUs that the device shall the re- */
+	/* execute the requested scan. Max value supported by the device */
+	/* is 256s. */
+	u32 auto_scan_interval;
+
+	/* Number of probe requests (per SSID) sent to one (1) */
+	/* channel. Zero (0) means that none is send, which */
+	/* means that a passive scan is to be done. Value */
+	/* greater than zero (0) means that an active scan is to */
+	/* be done. */
+	u32 num_probes;
+
+	/* Number of channels to be scanned. */
+	/* Maximum value is WSM_SCAN_MAX_NUM_OF_CHANNELS. */
+	u8 num_channels;
+
+	/* Number of SSID provided in the scan command (this */
+	/* is zero (0) in broadcast scan) */
+	/* The maximum number of SSIDs is WSM_SCAN_MAX_NUM_OF_SSIDS. */
+	u8 num_ssids;
+
+	/* The delay time (in microseconds) period */
+	/* before sending a probe-request. */
+	u8 probe_delay;
+
+	/* SSIDs to be scanned [numOfSSIDs]; */
+	struct wsm_ssid *ssids;
+
+	/* Channels to be scanned [numOfChannels]; */
+	struct wsm_scan_ch *ch;
+};
+
+int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg);
+
+/* 3.11 */
+#define WSM_STOP_SCAN_REQ_ID 0x0008
+#define WSM_STOP_SCAN_RESP_ID 0x0408
+int wsm_stop_scan(struct cw1200_common *priv);
+
+/* 3.13 */
+#define WSM_SCAN_COMPLETE_IND_ID 0x0806
+struct wsm_scan_complete {
+	/* WSM_STATUS_... */
+	u32 status;
+
+	/* WSM_PSM_... */
+	u8 psm;
+
+	/* Number of channels that the scan operation completed. */
+	u8 num_channels;
+};
+
+/* 3.14 */
+#define WSM_TX_CONFIRM_IND_ID 0x0404
+#define WSM_MULTI_TX_CONFIRM_ID 0x041E
+
+struct wsm_tx_confirm {
+	/* Packet identifier used in wsm_tx. */
+	u32 packet_id;
+
+	/* WSM_STATUS_... */
+	u32 status;
+
+	/* WSM_TRANSMIT_RATE_... */
+	u8 tx_rate;
+
+	/* The number of times the frame was transmitted */
+	/* without receiving an acknowledgement. */
+	u8 ack_failures;
+
+	/* WSM_TX_STATUS_... */
+	u16 flags;
+
+	/* The total time in microseconds that the frame spent in */
+	/* the WLAN device before transmission as completed. */
+	u32 media_delay;
+
+	/* The total time in microseconds that the frame spent in */
+	/* the WLAN device before transmission was started. */
+	u32 tx_queue_delay;
+};
+
+/* 3.15 */
+typedef void (*wsm_tx_confirm_cb) (struct cw1200_common *priv,
+				   struct wsm_tx_confirm *arg);
+
+/* Note that ideology of wsm_tx struct is different against the rest of
+ * WSM API. wsm_hdr is /not/ a caller-adapted struct to be used as an input
+ * argument for WSM call, but a prepared bytestream to be sent to firmware.
+ * It is filled partly in cw1200_tx, partly in low-level WSM code.
+ * Please pay attention once again: ideology is different.
+ *
+ * Legend:
+ * - [in]: cw1200_tx must fill this field.
+ * - [wsm]: the field is filled by low-level WSM.
+ */
+struct wsm_tx {
+	/* common WSM header */
+	struct wsm_hdr hdr;
+
+	/* Packet identifier that meant to be used in completion. */
+	u32 packet_id;  /* Note this is actually a cookie */
+
+	/* WSM_TRANSMIT_RATE_... */
+	u8 max_tx_rate;
+
+	/* WSM_QUEUE_... */
+	u8 queue_id;
+
+	/* True: another packet is pending on the host for transmission. */
+	u8 more;
+
+	/* Bit 0 = 0 - Start expiry time from first Tx attempt (default) */
+	/* Bit 0 = 1 - Start expiry time from receipt of Tx Request */
+	/* Bits 3:1  - PTA Priority */
+	/* Bits 6:4  - Tx Rate Retry Policy */
+	/* Bit 7 - Reserved */
+	u8 flags;
+
+	/* Should be 0. */
+	u32 reserved;
+
+	/* The elapsed time in TUs, after the initial transmission */
+	/* of an MSDU, after which further attempts to transmit */
+	/* the MSDU shall be terminated. Overrides the global */
+	/* dot11MaxTransmitMsduLifeTime setting [optional] */
+	/* Device will set the default value if this is 0. */
+	u32 expire_time;
+
+	/* WSM_HT_TX_... */
+	__le32 ht_tx_parameters;
+} __packed;
+
+/* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */
+#define WSM_TX_EXTRA_HEADROOM (28)
+
+/* 3.16 */
+#define WSM_RECEIVE_IND_ID 0x0804
+
+struct wsm_rx {
+	/* WSM_STATUS_... */
+	u32 status;
+
+	/* Specifies the channel of the received packet. */
+	u16 channel_number;
+
+	/* WSM_TRANSMIT_RATE_... */
+	u8 rx_rate;
+
+	/* This value is expressed in signed Q8.0 format for */
+	/* RSSI and unsigned Q7.1 format for RCPI. */
+	u8 rcpi_rssi;
+
+	/* WSM_RX_STATUS_... */
+	u32 flags;
+};
+
+/* = sizeof(generic hi hdr) + sizeof(wsm hdr) */
+#define WSM_RX_EXTRA_HEADROOM (16)
+
+typedef void (*wsm_rx_cb) (struct cw1200_common *priv, struct wsm_rx *arg,
+			   struct sk_buff **skb_p);
+
+/* 3.17 */
+struct wsm_event {
+	/* WSM_STATUS_... */
+	/* [out] */ u32 id;
+
+	/* Indication parameters. */
+	/* For error indication, this shall be a 32-bit WSM status. */
+	/* For RCPI or RSSI indication, this should be an 8-bit */
+	/* RCPI or RSSI value. */
+	/* [out] */ u32 data;
+};
+
+struct cw1200_wsm_event {
+	struct list_head link;
+	struct wsm_event evt;
+};
+
+/* 3.18 - 3.22 */
+/* Measurement. Skipped for now. Irrelevent. */
+
+typedef void (*wsm_event_cb) (struct cw1200_common *priv,
+			      struct wsm_event *arg);
+
+/* 3.23 */
+#define WSM_JOIN_REQ_ID 0x000B
+#define WSM_JOIN_RESP_ID 0x040B
+
+struct wsm_join {
+	/* WSM_JOIN_MODE_... */
+	u8 mode;
+
+	/* WSM_PHY_BAND_... */
+	u8 band;
+
+	/* Specifies the channel number to join. The channel */
+	/* number will be mapped to an actual frequency */
+	/* according to the band */
+	u16 channel_number;
+
+	/* Specifies the BSSID of the BSS or IBSS to be joined */
+	/* or the IBSS to be started. */
+	u8 bssid[6];
+
+	/* ATIM window of IBSS */
+	/* When ATIM window is zero the initiated IBSS does */
+	/* not support power saving. */
+	u16 atim_window;
+
+	/* WSM_JOIN_PREAMBLE_... */
+	u8 preamble_type;
+
+	/* Specifies if a probe request should be send with the */
+	/* specified SSID when joining to the network. */
+	u8 probe_for_join;
+
+	/* DTIM Period (In multiples of beacon interval) */
+	u8 dtim_period;
+
+	/* WSM_JOIN_FLAGS_... */
+	u8 flags;
+
+	/* Length of the SSID */
+	u32 ssid_len;
+
+	/* Specifies the SSID of the IBSS to join or start */
+	u8 ssid[32];
+
+	/* Specifies the time between TBTTs in TUs */
+	u32 beacon_interval;
+
+	/* A bit mask that defines the BSS basic rate set. */
+	u32 basic_rate_set;
+};
+
+struct wsm_join_cnf {
+	u32 status;
+
+	/* Minimum transmission power level in units of 0.1dBm */
+	u32 min_power_level;
+
+	/* Maximum transmission power level in units of 0.1dBm */
+	u32 max_power_level;
+};
+
+int wsm_join(struct cw1200_common *priv, struct wsm_join *arg);
+
+/* 3.24 */
+struct wsm_join_complete {
+	/* WSM_STATUS_... */
+	u32 status;
+};
+
+/* 3.25 */
+#define WSM_SET_PM_REQ_ID 0x0010
+#define WSM_SET_PM_RESP_ID 0x0410
+struct wsm_set_pm {
+	/* WSM_PSM_... */
+	u8 mode;
+
+	/* in unit of 500us; 0 to use default */
+	u8 fast_psm_idle_period;
+
+	/* in unit of 500us; 0 to use default */
+	u8 ap_psm_change_period;
+
+	/* in unit of 500us; 0 to disable auto-pspoll */
+	u8 min_auto_pspoll_period;
+};
+
+int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg);
+
+/* 3.27 */
+struct wsm_set_pm_complete {
+	u8 psm;			/* WSM_PSM_... */
+};
+
+/* 3.28 */
+#define WSM_SET_BSS_PARAMS_REQ_ID 0x0011
+#define WSM_SET_BSS_PARAMS_RESP_ID 0x0411
+struct wsm_set_bss_params {
+	/* This resets the beacon loss counters only */
+	u8 reset_beacon_loss;
+
+	/* The number of lost consecutive beacons after which */
+	/* the WLAN device should indicate the BSS-Lost event */
+	/* to the WLAN host driver. */
+	u8 beacon_lost_count;
+
+	/* The AID received during the association process. */
+	u16 aid;
+
+	/* The operational rate set mask */
+	u32 operational_rate_set;
+};
+
+int wsm_set_bss_params(struct cw1200_common *priv,
+		       const struct wsm_set_bss_params *arg);
+
+/* 3.30 */
+#define WSM_ADD_KEY_REQ_ID         0x000C
+#define WSM_ADD_KEY_RESP_ID        0x040C
+struct wsm_add_key {
+	u8 type;		/* WSM_KEY_TYPE_... */
+	u8 index;		/* Key entry index: 0 -- WSM_KEY_MAX_INDEX */
+	u16 reserved;
+	union {
+		struct {
+			u8 peer[6];	/* MAC address of the peer station */
+			u8 reserved;
+			u8 keylen;		/* Key length in bytes */
+			u8 keydata[16];		/* Key data */
+		} __packed wep_pairwise;
+		struct {
+			u8 keyid;	/* Unique per key identifier (0..3) */
+			u8 keylen;		/* Key length in bytes */
+			u16 reserved;
+			u8 keydata[16];		/* Key data */
+		} __packed wep_group;
+		struct {
+			u8 peer[6];	/* MAC address of the peer station */
+			u16 reserved;
+			u8 keydata[16];	/* TKIP key data */
+			u8 rx_mic_key[8];		/* Rx MIC key */
+			u8 tx_mic_key[8];		/* Tx MIC key */
+		} __packed tkip_pairwise;
+		struct {
+			u8 keydata[16];	/* TKIP key data */
+			u8 rx_mic_key[8];		/* Rx MIC key */
+			u8 keyid;		/* Key ID */
+			u8 reserved[3];
+			u8 rx_seqnum[8];	/* Receive Sequence Counter */
+		} __packed tkip_group;
+		struct {
+			u8 peer[6];	/* MAC address of the peer station */
+			u16 reserved;
+			u8 keydata[16];	/* AES key data */
+		} __packed aes_pairwise;
+		struct {
+			u8 keydata[16];	/* AES key data */
+			u8 keyid;		/* Key ID */
+			u8 reserved[3];
+			u8 rx_seqnum[8];	/* Receive Sequence Counter */
+		} __packed aes_group;
+		struct {
+			u8 peer[6];	/* MAC address of the peer station */
+			u8 keyid;		/* Key ID */
+			u8 reserved;
+			u8 keydata[16];	/* WAPI key data */
+			u8 mic_key[16];	/* MIC key data */
+		} __packed wapi_pairwise;
+		struct {
+			u8 keydata[16];	/* WAPI key data */
+			u8 mic_key[16];	/* MIC key data */
+			u8 keyid;		/* Key ID */
+			u8 reserved[3];
+		} __packed wapi_group;
+	} __packed;
+} __packed;
+
+int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg);
+
+/* 3.32 */
+#define WSM_REMOVE_KEY_REQ_ID         0x000D
+#define WSM_REMOVE_KEY_RESP_ID        0x040D
+struct wsm_remove_key {
+	u8 index; /* Key entry index : 0-10 */
+};
+
+int wsm_remove_key(struct cw1200_common *priv,
+		   const struct wsm_remove_key *arg);
+
+/* 3.34 */
+struct wsm_set_tx_queue_params {
+	/* WSM_ACK_POLICY_... */
+	u8 ackPolicy;
+
+	/* Medium Time of TSPEC (in 32us units) allowed per */
+	/* One Second Averaging Period for this queue. */
+	u16 allowedMediumTime;
+
+	/* dot11MaxTransmitMsduLifetime to be used for the */
+	/* specified queue. */
+	u32 maxTransmitLifetime;
+};
+
+struct wsm_tx_queue_params {
+	/* NOTE: index is a linux queue id. */
+	struct wsm_set_tx_queue_params params[4];
+};
+
+
+#define WSM_TX_QUEUE_SET(queue_params, queue, ack_policy, allowed_time,\
+		max_life_time)	\
+do {							\
+	struct wsm_set_tx_queue_params *p = &(queue_params)->params[queue]; \
+	p->ackPolicy = (ack_policy);				\
+	p->allowedMediumTime = (allowed_time);				\
+	p->maxTransmitLifetime = (max_life_time);			\
+} while (0)
+
+int wsm_set_tx_queue_params(struct cw1200_common *priv,
+			    const struct wsm_set_tx_queue_params *arg, u8 id);
+
+/* 3.36 */
+#define WSM_EDCA_PARAMS_REQ_ID 0x0013
+#define WSM_EDCA_PARAMS_RESP_ID 0x0413
+struct wsm_edca_queue_params {
+	/* CWmin (in slots) for the access class. */
+	u16 cwmin;
+
+	/* CWmax (in slots) for the access class. */
+	u16 cwmax;
+
+	/* AIFS (in slots) for the access class. */
+	u16 aifns;
+
+	/* TX OP Limit (in microseconds) for the access class. */
+	u16 txop_limit;
+
+	/* dot11MaxReceiveLifetime to be used for the specified */
+	/* the access class. Overrides the global */
+	/* dot11MaxReceiveLifetime value */
+	u32 max_rx_lifetime;
+};
+
+struct wsm_edca_params {
+	/* NOTE: index is a linux queue id. */
+	struct wsm_edca_queue_params params[4];
+	bool uapsd_enable[4];
+};
+
+#define TXOP_UNIT 32
+#define WSM_EDCA_SET(__edca, __queue, __aifs, __cw_min, __cw_max, __txop, __lifetime,\
+		     __uapsd) \
+	do {							\
+		struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \
+		p->cwmin = __cw_min;					\
+		p->cwmax = __cw_max;					\
+		p->aifns = __aifs;					\
+		p->txop_limit = ((__txop) * TXOP_UNIT);			\
+		p->max_rx_lifetime = __lifetime;			\
+		(__edca)->uapsd_enable[__queue] = (__uapsd);		\
+	} while (0)
+
+int wsm_set_edca_params(struct cw1200_common *priv,
+			const struct wsm_edca_params *arg);
+
+int wsm_set_uapsd_param(struct cw1200_common *priv,
+			const struct wsm_edca_params *arg);
+
+/* 3.38 */
+/* Set-System info. Skipped for now. Irrelevent. */
+
+/* 3.40 */
+#define WSM_SWITCH_CHANNEL_REQ_ID 0x0016
+#define WSM_SWITCH_CHANNEL_RESP_ID 0x0416
+
+struct wsm_switch_channel {
+	/* 1 - means the STA shall not transmit any further */
+	/* frames until the channel switch has completed */
+	u8 mode;
+
+	/* Number of TBTTs until channel switch occurs. */
+	/* 0 - indicates switch shall occur at any time */
+	/* 1 - occurs immediately before the next TBTT */
+	u8 switch_count;
+
+	/* The new channel number to switch to. */
+	/* Note this is defined as per section 2.7. */
+	u16 channel_number;
+};
+
+int wsm_switch_channel(struct cw1200_common *priv,
+		       const struct wsm_switch_channel *arg);
+
+typedef void (*wsm_channel_switch_cb) (struct cw1200_common *priv);
+
+#define WSM_START_REQ_ID 0x0017
+#define WSM_START_RESP_ID 0x0417
+
+struct wsm_start {
+	/* WSM_START_MODE_... */
+	/* [in] */ u8 mode;
+
+	/* WSM_PHY_BAND_... */
+	/* [in] */ u8 band;
+
+	/* Channel number */
+	/* [in] */ u16 channel_number;
+
+	/* Client Traffic window in units of TU */
+	/* Valid only when mode == ..._P2P */
+	/* [in] */ u32 ct_window;
+
+	/* Interval between two consecutive */
+	/* beacon transmissions in TU. */
+	/* [in] */ u32 beacon_interval;
+
+	/* DTIM period in terms of beacon intervals */
+	/* [in] */ u8 dtim_period;
+
+	/* WSM_JOIN_PREAMBLE_... */
+	/* [in] */ u8 preamble;
+
+	/* The delay time (in microseconds) period */
+	/* before sending a probe-request. */
+	/* [in] */ u8 probe_delay;
+
+	/* Length of the SSID */
+	/* [in] */ u8 ssid_len;
+
+	/* SSID of the BSS or P2P_GO to be started now. */
+	/* [in] */ u8 ssid[32];
+
+	/* The basic supported rates for the MiniAP. */
+	/* [in] */ u32 basic_rate_set;
+};
+
+int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg);
+
+#define WSM_BEACON_TRANSMIT_REQ_ID 0x0018
+#define WSM_BEACON_TRANSMIT_RESP_ID 0x0418
+
+struct wsm_beacon_transmit {
+	/* 1: enable; 0: disable */
+	/* [in] */ u8 enable_beaconing;
+};
+
+int wsm_beacon_transmit(struct cw1200_common *priv,
+			const struct wsm_beacon_transmit *arg);
+
+int wsm_start_find(struct cw1200_common *priv);
+
+int wsm_stop_find(struct cw1200_common *priv);
+
+typedef void (*wsm_find_complete_cb) (struct cw1200_common *priv, u32 status);
+
+struct wsm_suspend_resume {
+	/* See 3.52 */
+	/* Link ID */
+	/* [out] */ int link_id;
+	/* Stop sending further Tx requests down to device for this link */
+	/* [out] */ bool stop;
+	/* Transmit multicast Frames */
+	/* [out] */ bool multicast;
+	/* The AC on which Tx to be suspended /resumed. */
+	/* This is applicable only for U-APSD */
+	/* WSM_QUEUE_... */
+	/* [out] */ int queue;
+};
+
+typedef void (*wsm_suspend_resume_cb) (struct cw1200_common *priv,
+				       struct wsm_suspend_resume *arg);
+
+/* 3.54 Update-IE request. */
+struct wsm_update_ie {
+	/* WSM_UPDATE_IE_... */
+	/* [in] */ u16 what;
+	/* [in] */ u16 count;
+	/* [in] */ u8 *ies;
+	/* [in] */ size_t length;
+};
+
+int wsm_update_ie(struct cw1200_common *priv,
+		  const struct wsm_update_ie *arg);
+
+/* 3.56 */
+struct wsm_map_link {
+	/* MAC address of the remote device */
+	/* [in] */ u8 mac_addr[6];
+	/* [in] */ u8 link_id;
+};
+
+int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg);
+
+/* ******************************************************************** */
+/* MIB shortcats							*/
+
+static inline int wsm_set_output_power(struct cw1200_common *priv,
+				       int power_level)
+{
+	__le32 val = __cpu_to_le32(power_level);
+	return wsm_write_mib(priv, WSM_MIB_ID_DOT11_CURRENT_TX_POWER_LEVEL,
+			     &val, sizeof(val));
+}
+
+static inline int wsm_set_beacon_wakeup_period(struct cw1200_common *priv,
+					       unsigned dtim_interval,
+					       unsigned listen_interval)
+{
+	struct {
+		u8 numBeaconPeriods;
+		u8 reserved;
+		__le16 listenInterval;
+	} val = {
+		dtim_interval, 0, __cpu_to_le16(listen_interval)
+	};
+
+	if (dtim_interval > 0xFF || listen_interval > 0xFFFF)
+		return -EINVAL;
+	else
+		return wsm_write_mib(priv, WSM_MIB_ID_BEACON_WAKEUP_PERIOD,
+				     &val, sizeof(val));
+}
+
+struct wsm_rcpi_rssi_threshold {
+	u8 rssiRcpiMode;	/* WSM_RCPI_RSSI_... */
+	u8 lowerThreshold;
+	u8 upperThreshold;
+	u8 rollingAverageCount;
+};
+
+static inline int wsm_set_rcpi_rssi_threshold(struct cw1200_common *priv,
+					struct wsm_rcpi_rssi_threshold *arg)
+{
+	return wsm_write_mib(priv, WSM_MIB_ID_RCPI_RSSI_THRESHOLD, arg,
+			     sizeof(*arg));
+}
+
+struct wsm_mib_counters_table {
+	__le32 plcp_errors;
+	__le32 fcs_errors;
+	__le32 tx_packets;
+	__le32 rx_packets;
+	__le32 rx_packet_errors;
+	__le32 rx_decryption_failures;
+	__le32 rx_mic_failures;
+	__le32 rx_no_key_failures;
+	__le32 tx_multicast_frames;
+	__le32 tx_frames_success;
+	__le32 tx_frame_failures;
+	__le32 tx_frames_retried;
+	__le32 tx_frames_multi_retried;
+	__le32 rx_frame_duplicates;
+	__le32 rts_success;
+	__le32 rts_failures;
+	__le32 ack_failures;
+	__le32 rx_multicast_frames;
+	__le32 rx_frames_success;
+	__le32 rx_cmac_icv_errors;
+	__le32 rx_cmac_replays;
+	__le32 rx_mgmt_ccmp_replays;
+} __packed;
+
+static inline int wsm_get_counters_table(struct cw1200_common *priv,
+					 struct wsm_mib_counters_table *arg)
+{
+	return wsm_read_mib(priv, WSM_MIB_ID_COUNTERS_TABLE,
+			    arg, sizeof(*arg));
+}
+
+static inline int wsm_get_station_id(struct cw1200_common *priv, u8 *mac)
+{
+	return wsm_read_mib(priv, WSM_MIB_ID_DOT11_STATION_ID, mac, ETH_ALEN);
+}
+
+struct wsm_rx_filter {
+	bool promiscuous;
+	bool bssid;
+	bool fcs;
+	bool probeResponder;
+};
+
+static inline int wsm_set_rx_filter(struct cw1200_common *priv,
+				    const struct wsm_rx_filter *arg)
+{
+	__le32 val = 0;
+	if (arg->promiscuous)
+		val |= __cpu_to_le32(BIT(0));
+	if (arg->bssid)
+		val |= __cpu_to_le32(BIT(1));
+	if (arg->fcs)
+		val |= __cpu_to_le32(BIT(2));
+	if (arg->probeResponder)
+		val |= __cpu_to_le32(BIT(3));
+	return wsm_write_mib(priv, WSM_MIB_ID_RX_FILTER, &val, sizeof(val));
+}
+
+int wsm_set_probe_responder(struct cw1200_common *priv, bool enable);
+
+#define WSM_BEACON_FILTER_IE_HAS_CHANGED	BIT(0)
+#define WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT	BIT(1)
+#define WSM_BEACON_FILTER_IE_HAS_APPEARED	BIT(2)
+
+struct wsm_beacon_filter_table_entry {
+	u8	ie_id;
+	u8	flags;
+	u8	oui[3];
+	u8	match_data[3];
+} __packed;
+
+struct wsm_mib_beacon_filter_table {
+	__le32 num;
+	struct wsm_beacon_filter_table_entry entry[10];
+} __packed;
+
+static inline int wsm_set_beacon_filter_table(struct cw1200_common *priv,
+					      struct wsm_mib_beacon_filter_table *ft)
+{
+	size_t size = __le32_to_cpu(ft->num) *
+		     sizeof(struct wsm_beacon_filter_table_entry) +
+		     sizeof(__le32);
+
+	return wsm_write_mib(priv, WSM_MIB_ID_BEACON_FILTER_TABLE, ft, size);
+}
+
+#define WSM_BEACON_FILTER_ENABLE	BIT(0) /* Enable/disable beacon filtering */
+#define WSM_BEACON_FILTER_AUTO_ERP	BIT(1) /* If 1 FW will handle ERP IE changes internally */
+
+struct wsm_beacon_filter_control {
+	int enabled;
+	int bcn_count;
+};
+
+static inline int wsm_beacon_filter_control(struct cw1200_common *priv,
+					struct wsm_beacon_filter_control *arg)
+{
+	struct {
+		__le32 enabled;
+		__le32 bcn_count;
+	} val;
+	val.enabled = __cpu_to_le32(arg->enabled);
+	val.bcn_count = __cpu_to_le32(arg->bcn_count);
+	return wsm_write_mib(priv, WSM_MIB_ID_BEACON_FILTER_ENABLE, &val,
+			     sizeof(val));
+}
+
+enum wsm_power_mode {
+	wsm_power_mode_active = 0,
+	wsm_power_mode_doze = 1,
+	wsm_power_mode_quiescent = 2,
+};
+
+struct wsm_operational_mode {
+	enum wsm_power_mode power_mode;
+	int disable_more_flag_usage;
+	int perform_ant_diversity;
+};
+
+static inline int wsm_set_operational_mode(struct cw1200_common *priv,
+					const struct wsm_operational_mode *arg)
+{
+	u8 val = arg->power_mode;
+	if (arg->disable_more_flag_usage)
+		val |= BIT(4);
+	if (arg->perform_ant_diversity)
+		val |= BIT(5);
+	return wsm_write_mib(priv, WSM_MIB_ID_OPERATIONAL_POWER_MODE, &val,
+			     sizeof(val));
+}
+
+struct wsm_template_frame {
+	u8 frame_type;
+	u8 rate;
+	struct sk_buff *skb;
+};
+
+static inline int wsm_set_template_frame(struct cw1200_common *priv,
+					 struct wsm_template_frame *arg)
+{
+	int ret;
+	u8 *p = skb_push(arg->skb, 4);
+	p[0] = arg->frame_type;
+	p[1] = arg->rate;
+	((__le16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4);
+	ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len);
+	skb_pull(arg->skb, 4);
+	return ret;
+}
+
+
+struct wsm_protected_mgmt_policy {
+	bool protectedMgmtEnable;
+	bool unprotectedMgmtFramesAllowed;
+	bool encryptionForAuthFrame;
+};
+
+static inline int wsm_set_protected_mgmt_policy(struct cw1200_common *priv,
+		struct wsm_protected_mgmt_policy *arg)
+{
+	__le32 val = 0;
+	int ret;
+	if (arg->protectedMgmtEnable)
+		val |= __cpu_to_le32(BIT(0));
+	if (arg->unprotectedMgmtFramesAllowed)
+		val |= __cpu_to_le32(BIT(1));
+	if (arg->encryptionForAuthFrame)
+		val |= __cpu_to_le32(BIT(2));
+	ret = wsm_write_mib(priv, WSM_MIB_ID_PROTECTED_MGMT_POLICY,
+			&val, sizeof(val));
+	return ret;
+}
+
+struct wsm_mib_block_ack_policy {
+	u8 tx_tid;
+	u8 reserved1;
+	u8 rx_tid;
+	u8 reserved2;
+} __packed;
+
+static inline int wsm_set_block_ack_policy(struct cw1200_common *priv,
+					   u8 tx_tid_policy,
+					   u8 rx_tid_policy)
+{
+	struct wsm_mib_block_ack_policy val = {
+		.tx_tid = tx_tid_policy,
+		.rx_tid = rx_tid_policy,
+	};
+	return wsm_write_mib(priv, WSM_MIB_ID_BLOCK_ACK_POLICY, &val,
+			     sizeof(val));
+}
+
+struct wsm_mib_association_mode {
+	u8 flags;		/* WSM_ASSOCIATION_MODE_... */
+	u8 preamble;	/* WSM_JOIN_PREAMBLE_... */
+	u8 greenfield;	/* 1 for greenfield */
+	u8 mpdu_start_spacing;
+	__le32 basic_rate_set;
+} __packed;
+
+static inline int wsm_set_association_mode(struct cw1200_common *priv,
+					   struct wsm_mib_association_mode *arg)
+{
+	return wsm_write_mib(priv, WSM_MIB_ID_SET_ASSOCIATION_MODE, arg,
+			     sizeof(*arg));
+}
+
+#define WSM_TX_RATE_POLICY_FLAG_TERMINATE_WHEN_FINISHED BIT(2)
+#define WSM_TX_RATE_POLICY_FLAG_COUNT_INITIAL_TRANSMIT BIT(3)
+struct wsm_tx_rate_retry_policy {
+	u8 index;
+	u8 short_retries;
+	u8 long_retries;
+	/* BIT(2) - Terminate retries when Tx rate retry policy
+	 *          finishes.
+	 * BIT(3) - Count initial frame transmission as part of
+	 *          rate retry counting but not as a retry
+	 *          attempt
+	 */
+	u8 flags;
+	u8 rate_recoveries;
+	u8 reserved[3];
+	__le32 rate_count_indices[3];
+} __packed;
+
+struct wsm_set_tx_rate_retry_policy {
+	u8 num;
+	u8 reserved[3];
+	struct wsm_tx_rate_retry_policy tbl[8];
+} __packed;
+
+static inline int wsm_set_tx_rate_retry_policy(struct cw1200_common *priv,
+				struct wsm_set_tx_rate_retry_policy *arg)
+{
+	size_t size = 4 + arg->num * sizeof(struct wsm_tx_rate_retry_policy);
+	return wsm_write_mib(priv, WSM_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg,
+			     size);
+}
+
+/* 4.32 SetEtherTypeDataFrameFilter */
+struct wsm_ether_type_filter_hdr {
+	u8 num;		/* Up to WSM_MAX_FILTER_ELEMENTS */
+	u8 reserved[3];
+} __packed;
+
+struct wsm_ether_type_filter {
+	u8 action;	/* WSM_FILTER_ACTION_XXX */
+	u8 reserved;
+	__le16 type;	/* Type of ethernet frame */
+} __packed;
+
+static inline int wsm_set_ether_type_filter(struct cw1200_common *priv,
+				struct wsm_ether_type_filter_hdr *arg)
+{
+	size_t size = sizeof(struct wsm_ether_type_filter_hdr) +
+		arg->num * sizeof(struct wsm_ether_type_filter);
+	return wsm_write_mib(priv, WSM_MIB_ID_SET_ETHERTYPE_DATAFRAME_FILTER,
+		arg, size);
+}
+
+/* 4.33 SetUDPPortDataFrameFilter */
+struct wsm_udp_port_filter_hdr {
+	u8 num;		/* Up to WSM_MAX_FILTER_ELEMENTS */
+	u8 reserved[3];
+} __packed;
+
+struct wsm_udp_port_filter {
+	u8 action;	/* WSM_FILTER_ACTION_XXX */
+	u8 type;		/* WSM_FILTER_PORT_TYPE_XXX */
+	__le16 port;		/* Port number */
+} __packed;
+
+static inline int wsm_set_udp_port_filter(struct cw1200_common *priv,
+				struct wsm_udp_port_filter_hdr *arg)
+{
+	size_t size = sizeof(struct wsm_udp_port_filter_hdr) +
+		arg->num * sizeof(struct wsm_udp_port_filter);
+	return wsm_write_mib(priv, WSM_MIB_ID_SET_UDPPORT_DATAFRAME_FILTER,
+		arg, size);
+}
+
+/* Undocumented MIBs: */
+/* 4.35 P2PDeviceInfo */
+#define D11_MAX_SSID_LEN		(32)
+
+struct wsm_p2p_device_type {
+	__le16 category_id;
+	u8 oui[4];
+	__le16 subcategory_id;
+} __packed;
+
+struct wsm_p2p_device_info {
+	struct wsm_p2p_device_type primaryDevice;
+	u8 reserved1[3];
+	u8 devname_size;
+	u8 local_devname[D11_MAX_SSID_LEN];
+	u8 reserved2[3];
+	u8 num_secdev_supported;
+	struct wsm_p2p_device_type secdevs[0];
+} __packed;
+
+/* 4.36 SetWCDMABand - WO */
+struct wsm_cdma_band {
+	u8 wcdma_band;
+	u8 reserved[3];
+} __packed;
+
+/* 4.37 GroupTxSequenceCounter - RO */
+struct wsm_group_tx_seq {
+	__le32 bits_47_16;
+	__le16 bits_15_00;
+	__le16 reserved;
+} __packed;
+
+/* 4.39 SetHtProtection - WO */
+#define WSM_DUAL_CTS_PROT_ENB		(1 << 0)
+#define WSM_NON_GREENFIELD_STA_PRESENT  (1 << 1)
+#define WSM_HT_PROT_MODE__NO_PROT	(0 << 2)
+#define WSM_HT_PROT_MODE__NON_MEMBER	(1 << 2)
+#define WSM_HT_PROT_MODE__20_MHZ	(2 << 2)
+#define WSM_HT_PROT_MODE__NON_HT_MIXED	(3 << 2)
+#define WSM_LSIG_TXOP_PROT_FULL		(1 << 4)
+#define WSM_LARGE_L_LENGTH_PROT		(1 << 5)
+
+struct wsm_ht_protection {
+	__le32 flags;
+} __packed;
+
+/* 4.40 GPIO Command - R/W */
+#define WSM_GPIO_COMMAND_SETUP	0
+#define WSM_GPIO_COMMAND_READ	1
+#define WSM_GPIO_COMMAND_WRITE	2
+#define WSM_GPIO_COMMAND_RESET	3
+#define WSM_GPIO_ALL_PINS	0xFF
+
+struct wsm_gpio_command {
+	u8 command;
+	u8 pin;
+	__le16 config;
+} __packed;
+
+/* 4.41 TSFCounter - RO */
+struct wsm_tsf_counter {
+	__le64 tsf_counter;
+} __packed;
+
+/* 4.43 Keep alive period */
+struct wsm_keep_alive_period {
+	__le16 period;
+	u8 reserved[2];
+} __packed;
+
+static inline int wsm_keep_alive_period(struct cw1200_common *priv,
+					int period)
+{
+	struct wsm_keep_alive_period arg = {
+		.period = __cpu_to_le16(period),
+	};
+	return wsm_write_mib(priv, WSM_MIB_ID_KEEP_ALIVE_PERIOD,
+			&arg, sizeof(arg));
+};
+
+/* BSSID filtering */
+struct wsm_set_bssid_filtering {
+	u8 filter;
+	u8 reserved[3];
+} __packed;
+
+static inline int wsm_set_bssid_filtering(struct cw1200_common *priv,
+					  bool enabled)
+{
+	struct wsm_set_bssid_filtering arg = {
+		.filter = !enabled,
+	};
+	return wsm_write_mib(priv, WSM_MIB_ID_DISABLE_BSSID_FILTER,
+			&arg, sizeof(arg));
+}
+
+/* Multicast filtering - 4.5 */
+struct wsm_mib_multicast_filter {
+	__le32 enable;
+	__le32 num_addrs;
+	u8 macaddrs[WSM_MAX_GRP_ADDRTABLE_ENTRIES][ETH_ALEN];
+} __packed;
+
+static inline int wsm_set_multicast_filter(struct cw1200_common *priv,
+					   struct wsm_mib_multicast_filter *fp)
+{
+	return wsm_write_mib(priv, WSM_MIB_ID_DOT11_GROUP_ADDRESSES_TABLE,
+			     fp, sizeof(*fp));
+}
+
+/* ARP IPv4 filtering - 4.10 */
+struct wsm_mib_arp_ipv4_filter {
+	__le32 enable;
+	__be32 ipv4addrs[WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES];
+} __packed;
+
+static inline int wsm_set_arp_ipv4_filter(struct cw1200_common *priv,
+					  struct wsm_mib_arp_ipv4_filter *fp)
+{
+	return wsm_write_mib(priv, WSM_MIB_ID_ARP_IP_ADDRESSES_TABLE,
+			    fp, sizeof(*fp));
+}
+
+/* P2P Power Save Mode Info - 4.31 */
+struct wsm_p2p_ps_modeinfo {
+	u8	opp_ps_ct_window;
+	u8	count;
+	u8	reserved;
+	u8	dtim_count;
+	__le32	duration;
+	__le32	interval;
+	__le32	start_time;
+} __packed;
+
+static inline int wsm_set_p2p_ps_modeinfo(struct cw1200_common *priv,
+					  struct wsm_p2p_ps_modeinfo *mi)
+{
+	return wsm_write_mib(priv, WSM_MIB_ID_P2P_PS_MODE_INFO,
+			     mi, sizeof(*mi));
+}
+
+static inline int wsm_get_p2p_ps_modeinfo(struct cw1200_common *priv,
+					  struct wsm_p2p_ps_modeinfo *mi)
+{
+	return wsm_read_mib(priv, WSM_MIB_ID_P2P_PS_MODE_INFO,
+			    mi, sizeof(*mi));
+}
+
+/* UseMultiTxConfMessage */
+
+static inline int wsm_use_multi_tx_conf(struct cw1200_common *priv,
+					bool enabled)
+{
+	__le32 arg = enabled ? __cpu_to_le32(1) : 0;
+
+	return wsm_write_mib(priv, WSM_MIB_USE_MULTI_TX_CONF,
+			&arg, sizeof(arg));
+}
+
+
+/* 4.26 SetUpasdInformation */
+struct wsm_uapsd_info {
+	__le16 uapsd_flags;
+	__le16 min_auto_trigger_interval;
+	__le16 max_auto_trigger_interval;
+	__le16 auto_trigger_step;
+};
+
+static inline int wsm_set_uapsd_info(struct cw1200_common *priv,
+				     struct wsm_uapsd_info *arg)
+{
+	return wsm_write_mib(priv, WSM_MIB_ID_SET_UAPSD_INFORMATION,
+				arg, sizeof(*arg));
+}
+
+/* 4.22 OverrideInternalTxRate */
+struct wsm_override_internal_txrate {
+	u8 internalTxRate;
+	u8 nonErpInternalTxRate;
+	u8 reserved[2];
+} __packed;
+
+static inline int wsm_set_override_internal_txrate(struct cw1200_common *priv,
+				     struct wsm_override_internal_txrate *arg)
+{
+	return wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
+				arg, sizeof(*arg));
+}
+
+/* ******************************************************************** */
+/* WSM TX port control							*/
+
+void wsm_lock_tx(struct cw1200_common *priv);
+void wsm_lock_tx_async(struct cw1200_common *priv);
+bool wsm_flush_tx(struct cw1200_common *priv);
+void wsm_unlock_tx(struct cw1200_common *priv);
+
+/* ******************************************************************** */
+/* WSM / BH API								*/
+
+int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len);
+int wsm_handle_rx(struct cw1200_common *priv, u16 id, struct wsm_hdr *wsm,
+		  struct sk_buff **skb_p);
+
+/* ******************************************************************** */
+/* wsm_buf API								*/
+
+struct wsm_buf {
+	u8 *begin;
+	u8 *data;
+	u8 *end;
+};
+
+void wsm_buf_init(struct wsm_buf *buf);
+void wsm_buf_deinit(struct wsm_buf *buf);
+
+/* ******************************************************************** */
+/* wsm_cmd API								*/
+
+struct wsm_cmd {
+	spinlock_t lock; /* Protect structure from multiple access */
+	int done;
+	u8 *ptr;
+	size_t len;
+	void *arg;
+	int ret;
+	u16 cmd;
+};
+
+/* ******************************************************************** */
+/* WSM TX buffer access							*/
+
+int wsm_get_tx(struct cw1200_common *priv, u8 **data,
+	       size_t *tx_len, int *burst);
+void wsm_txed(struct cw1200_common *priv, u8 *data);
+
+/* ******************************************************************** */
+/* Queue mapping: WSM <---> linux					*/
+/* Linux: VO VI BE BK							*/
+/* WSM:   BE BK VI VO							*/
+
+static inline u8 wsm_queue_id_to_linux(u8 queue_id)
+{
+	static const u8 queue_mapping[] = {
+		2, 3, 1, 0
+	};
+	return queue_mapping[queue_id];
+}
+
+static inline u8 wsm_queue_id_to_wsm(u8 queue_id)
+{
+	static const u8 queue_mapping[] = {
+		3, 2, 0, 1
+	};
+	return queue_mapping[queue_id];
+}
+
+#endif /* CW1200_HWIO_H_INCLUDED */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/hostap/hostap_ioctl.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/hostap/hostap_ioctl.c
--- linux-libre-3.10-gnu/drivers/net/wireless/hostap/hostap_ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/hostap/hostap_ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -523,9 +523,9 @@ static int prism2_ioctl_giwaplist(struct
 
 	data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1);
 
-	memcpy(extra, &addr, sizeof(struct sockaddr) * data->length);
+	memcpy(extra, addr, sizeof(struct sockaddr) * data->length);
 	data->flags = 1; /* has quality information */
-	memcpy(extra + sizeof(struct sockaddr) * data->length, &qual,
+	memcpy(extra + sizeof(struct sockaddr) * data->length, qual,
 	       sizeof(struct iw_quality) * data->length);
 
 	kfree(addr);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ipw2x00/ipw2100.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ipw2x00/ipw2100.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ipw2x00/ipw2100.c	2013-07-01 10:38:32.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ipw2x00/ipw2100.c	2013-08-31 17:58:07.000000000 -0400
@@ -6242,8 +6242,6 @@ static int ipw2100_pci_init_one(struct p
 	if ((val & 0x0000ff00) != 0)
 		pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
 
-	pci_set_power_state(pci_dev, PCI_D0);
-
 	if (!ipw2100_hw_is_adapter_in_system(dev)) {
 		printk(KERN_WARNING DRV_NAME
 		       "Device not found via register read.\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ipw2x00/ipw2200.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ipw2x00/ipw2200.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ipw2x00/ipw2200.c	2013-07-01 10:38:38.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ipw2x00/ipw2200.c	2013-08-31 17:58:14.000000000 -0400
@@ -3548,6 +3548,7 @@ static int ipw_load(struct ipw_priv *pri
 		ipw_rx_queue_reset(priv, priv->rxq);
 	if (!priv->rxq) {
 		IPW_ERROR("Unable to initialize Rx queue\n");
+		rc = -ENOMEM;
 		goto error;
 	}
 
@@ -8256,7 +8257,7 @@ static  int is_duplicate_packet(struct i
 			u8 *mac = header->addr2;
 			int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
 
-			__list_for_each(p, &priv->ibss_mac_hash[index]) {
+			list_for_each(p, &priv->ibss_mac_hash[index]) {
 				entry =
 				    list_entry(p, struct ipw_ibss_seq, list);
 				if (!memcmp(entry->mac, mac, ETH_ALEN))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ipw2x00/libipw_rx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ipw2x00/libipw_rx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ipw2x00/libipw_rx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ipw2x00/libipw_rx.c	2013-08-25 20:43:22.000000000 -0400
@@ -1195,7 +1195,7 @@ static int libipw_parse_info_param(struc
 #ifdef CONFIG_LIBIPW_DEBUG
 				p += snprintf(p, sizeof(rates_str) -
 					      (p - rates_str), "%02X ",
-					      network->rates[i]);
+					      network->rates_ex[i]);
 #endif
 				if (libipw_is_ofdm_rate
 				    (info_element->data[i])) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/3945.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/3945.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/3945.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/3945.c	2013-08-25 20:43:22.000000000 -0400
@@ -331,6 +331,19 @@ il3945_hdl_tx(struct il_priv *il, struct
 		return;
 	}
 
+	/*
+	 * Firmware will not transmit frame on passive channel, if it not yet
+	 * received some valid frame on that channel. When this error happen
+	 * we have to wait until firmware will unblock itself i.e. when we
+	 * note received beacon or other frame. We unblock queues in
+	 * il3945_pass_packet_to_mac80211 or in il_mac_bss_info_changed.
+	 */
+	if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) &&
+	    il->iw_mode == NL80211_IFTYPE_STATION) {
+		il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+		D_INFO("Stopped queues - RX waiting on passive channel\n");
+	}
+
 	txq->time_stamp = jiffies;
 	info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]);
 	ieee80211_tx_info_clear_status(info);
@@ -488,6 +501,11 @@ il3945_pass_packet_to_mac80211(struct il
 		return;
 	}
 
+	if (unlikely(test_bit(IL_STOP_REASON_PASSIVE, &il->stop_reason))) {
+		il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+		D_INFO("Woke queues - frame received on passive channel\n");
+	}
+
 	skb = dev_alloc_skb(128);
 	if (!skb) {
 		IL_ERR("dev_alloc_skb failed\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/3945-mac.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/3945-mac.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/3945-mac.c	2013-07-01 10:38:42.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/3945-mac.c	2013-08-31 17:58:17.000000000 -0400
@@ -3119,7 +3119,7 @@ il3945_store_debug_level(struct device *
 	unsigned long val;
 	int ret;
 
-	ret = strict_strtoul(buf, 0, &val);
+	ret = kstrtoul(buf, 0, &val);
 	if (ret)
 		IL_INFO("%s is not in hex or decimal form.\n", buf);
 	else
@@ -3727,7 +3727,8 @@ il3945_pci_probe(struct pci_dev *pdev, c
 	 * 5. Setup HW Constants
 	 * ********************/
 	/* Device-specific setup */
-	if (il3945_hw_set_hw_params(il)) {
+	err = il3945_hw_set_hw_params(il);
+	if (err) {
 		IL_ERR("failed to set hw settings\n");
 		goto out_eeprom_free;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/4965-mac.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/4965-mac.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/4965-mac.c	2013-07-01 10:39:00.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/4965-mac.c	2013-08-31 17:58:24.000000000 -0400
@@ -588,6 +588,11 @@ il4965_pass_packet_to_mac80211(struct il
 		return;
 	}
 
+	if (unlikely(test_bit(IL_STOP_REASON_PASSIVE, &il->stop_reason))) {
+		il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+		D_INFO("Woke queues - frame received on passive channel\n");
+	}
+
 	/* In case of HW accelerated crypto and bad decryption, drop */
 	if (!il->cfg->mod_params->sw_crypto &&
 	    il_set_decrypted_flag(il, hdr, ampdu_status, stats))
@@ -2806,6 +2811,19 @@ il4965_hdl_tx(struct il_priv *il, struct
 		return;
 	}
 
+	/*
+	 * Firmware will not transmit frame on passive channel, if it not yet
+	 * received some valid frame on that channel. When this error happen
+	 * we have to wait until firmware will unblock itself i.e. when we
+	 * note received beacon or other frame. We unblock queues in
+	 * il4965_pass_packet_to_mac80211 or in il_mac_bss_info_changed.
+	 */
+	if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) &&
+	    il->iw_mode == NL80211_IFTYPE_STATION) {
+		il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+		D_INFO("Stopped queues - RX waiting on passive channel\n");
+	}
+
 	spin_lock_irqsave(&il->sta_lock, flags);
 	if (txq->sched_retry) {
 		const u32 scd_ssn = il4965_get_scd_ssn(tx_resp);
@@ -4442,12 +4460,12 @@ il4965_irq_tasklet(struct il_priv *il)
 		 * is killed. Hence update the killswitch state here. The
 		 * rfkill handler will care about restarting if needed.
 		 */
-		if (!test_bit(S_ALIVE, &il->status)) {
-			if (hw_rf_kill)
-				set_bit(S_RFKILL, &il->status);
-			else
-				clear_bit(S_RFKILL, &il->status);
+		if (hw_rf_kill) {
+			set_bit(S_RFKILL, &il->status);
+		} else {
+			clear_bit(S_RFKILL, &il->status);
 			wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
+			il_force_reset(il, true);
 		}
 
 		handled |= CSR_INT_BIT_RF_KILL;
@@ -4567,7 +4585,7 @@ il4965_store_debug_level(struct device *
 	unsigned long val;
 	int ret;
 
-	ret = strict_strtoul(buf, 0, &val);
+	ret = kstrtoul(buf, 0, &val);
 	if (ret)
 		IL_ERR("%s is not in hex or decimal form.\n", buf);
 	else
@@ -4614,7 +4632,7 @@ il4965_store_tx_power(struct device *d,
 	unsigned long val;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &val);
+	ret = kstrtoul(buf, 10, &val);
 	if (ret)
 		IL_INFO("%s is not in decimal form.\n", buf);
 	else {
@@ -5316,6 +5334,9 @@ il4965_alive_start(struct il_priv *il)
 
 	il->active_rate = RATES_MASK;
 
+	il_power_update_mode(il, true);
+	D_INFO("Updated power mode\n");
+
 	if (il_is_associated(il)) {
 		struct il_rxon_cmd *active_rxon =
 		    (struct il_rxon_cmd *)&il->active;
@@ -5346,9 +5367,6 @@ il4965_alive_start(struct il_priv *il)
 	D_INFO("ALIVE processing complete.\n");
 	wake_up(&il->wait_command_queue);
 
-	il_power_update_mode(il, true);
-	D_INFO("Updated power mode\n");
-
 	return;
 
 restart:
@@ -5741,7 +5759,8 @@ il4965_mac_setup_register(struct il_priv
 	hw->flags =
 	    IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION |
 	    IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | IEEE80211_HW_SPECTRUM_MGMT |
-	    IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+	    IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS |
+	    IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
 	if (il->cfg->sku & IL_SKU_N)
 		hw->flags |=
 		    IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/commands.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/commands.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/commands.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/commands.h	2013-08-25 20:43:22.000000000 -0400
@@ -1348,14 +1348,6 @@ struct il_rx_mpdu_res_start {
 #define TX_CMD_SEC_KEY128	0x08
 
 /*
- * security overhead sizes
- */
-#define WEP_IV_LEN 4
-#define WEP_ICV_LEN 4
-#define CCMP_MIC_LEN 8
-#define TKIP_ICV_LEN 4
-
-/*
  * C_TX = 0x1c (command)
  */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/common.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/common.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/common.c	2013-08-25 20:43:22.000000000 -0400
@@ -4660,6 +4660,7 @@ il_force_reset(struct il_priv *il, bool
 
 	return 0;
 }
+EXPORT_SYMBOL(il_force_reset);
 
 int
 il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -5307,6 +5308,17 @@ il_mac_bss_info_changed(struct ieee80211
 		D_MAC80211("BSSID %pM\n", bss_conf->bssid);
 
 		/*
+		 * On passive channel we wait with blocked queues to see if
+		 * there is traffic on that channel. If no frame will be
+		 * received (what is very unlikely since scan detects AP on
+		 * that channel, but theoretically possible), mac80211 associate
+		 * procedure will time out and mac80211 will call us with NULL
+		 * bssid. We have to unblock queues on such condition.
+		 */
+		if (is_zero_ether_addr(bss_conf->bssid))
+			il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+
+		/*
 		 * If there is currently a HW scan going on in the background,
 		 * then we need to cancel it, otherwise sometimes we are not
 		 * able to authenticate (FIXME: why ?)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/common.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/common.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlegacy/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlegacy/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -1299,6 +1299,8 @@ struct il_priv {
 	/* queue refcounts */
 #define IL_MAX_HW_QUEUES	32
 	unsigned long queue_stopped[BITS_TO_LONGS(IL_MAX_HW_QUEUES)];
+#define IL_STOP_REASON_PASSIVE	0
+	unsigned long stop_reason;
 	/* for each AC */
 	atomic_t queue_stop_count[4];
 
@@ -2257,6 +2259,19 @@ il_set_swq_id(struct il_tx_queue *txq, u
 }
 
 static inline void
+_il_wake_queue(struct il_priv *il, u8 ac)
+{
+	if (atomic_dec_return(&il->queue_stop_count[ac]) <= 0)
+		ieee80211_wake_queue(il->hw, ac);
+}
+
+static inline void
+_il_stop_queue(struct il_priv *il, u8 ac)
+{
+	if (atomic_inc_return(&il->queue_stop_count[ac]) > 0)
+		ieee80211_stop_queue(il->hw, ac);
+}
+static inline void
 il_wake_queue(struct il_priv *il, struct il_tx_queue *txq)
 {
 	u8 queue = txq->swq_id;
@@ -2264,8 +2279,7 @@ il_wake_queue(struct il_priv *il, struct
 	u8 hwq = (queue >> 2) & 0x1f;
 
 	if (test_and_clear_bit(hwq, il->queue_stopped))
-		if (atomic_dec_return(&il->queue_stop_count[ac]) <= 0)
-			ieee80211_wake_queue(il->hw, ac);
+		_il_wake_queue(il, ac);
 }
 
 static inline void
@@ -2276,8 +2290,27 @@ il_stop_queue(struct il_priv *il, struct
 	u8 hwq = (queue >> 2) & 0x1f;
 
 	if (!test_and_set_bit(hwq, il->queue_stopped))
-		if (atomic_inc_return(&il->queue_stop_count[ac]) > 0)
-			ieee80211_stop_queue(il->hw, ac);
+		_il_stop_queue(il, ac);
+}
+
+static inline void
+il_wake_queues_by_reason(struct il_priv *il, int reason)
+{
+	u8 ac;
+
+	if (test_and_clear_bit(reason, &il->stop_reason))
+		for (ac = 0; ac < 4; ac++)
+			_il_wake_queue(il, ac);
+}
+
+static inline void
+il_stop_queues_by_reason(struct il_priv *il, int reason)
+{
+	u8 ac;
+
+	if (!test_and_set_bit(reason, &il->stop_reason))
+		for (ac = 0; ac < 4; ac++)
+			_il_stop_queue(il, ac);
 }
 
 #ifdef ieee80211_stop_queue
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/agn.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/agn.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/agn.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/agn.h	2013-08-25 20:43:22.000000000 -0400
@@ -76,13 +76,16 @@
 #define IWL_INVALID_STATION	255
 
 /* device operations */
-extern struct iwl_lib_ops iwl1000_lib;
-extern struct iwl_lib_ops iwl2000_lib;
-extern struct iwl_lib_ops iwl2030_lib;
-extern struct iwl_lib_ops iwl5000_lib;
-extern struct iwl_lib_ops iwl5150_lib;
-extern struct iwl_lib_ops iwl6000_lib;
-extern struct iwl_lib_ops iwl6030_lib;
+extern const struct iwl_dvm_cfg iwl_dvm_1000_cfg;
+extern const struct iwl_dvm_cfg iwl_dvm_2000_cfg;
+extern const struct iwl_dvm_cfg iwl_dvm_105_cfg;
+extern const struct iwl_dvm_cfg iwl_dvm_2030_cfg;
+extern const struct iwl_dvm_cfg iwl_dvm_5000_cfg;
+extern const struct iwl_dvm_cfg iwl_dvm_5150_cfg;
+extern const struct iwl_dvm_cfg iwl_dvm_6000_cfg;
+extern const struct iwl_dvm_cfg iwl_dvm_6005_cfg;
+extern const struct iwl_dvm_cfg iwl_dvm_6050_cfg;
+extern const struct iwl_dvm_cfg iwl_dvm_6030_cfg;
 
 
 #define TIME_UNIT		1024
@@ -291,8 +294,8 @@ void iwlagn_bt_adjust_rssi_monitor(struc
 
 static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
 {
-	return priv->cfg->bt_params &&
-	       priv->cfg->bt_params->advanced_bt_coexist;
+	return priv->lib->bt_params &&
+	       priv->lib->bt_params->advanced_bt_coexist;
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -402,43 +405,6 @@ static inline __le32 iwl_hw_set_rate_n_f
 
 extern int iwl_alive_start(struct iwl_priv *priv);
 
-/* testmode support */
-#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
-
-extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data,
-				   int len);
-extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw,
-				    struct sk_buff *skb,
-				    struct netlink_callback *cb,
-				    void *data, int len);
-extern void iwl_testmode_init(struct iwl_priv *priv);
-extern void iwl_testmode_free(struct iwl_priv *priv);
-
-#else
-
-static inline
-int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
-{
-	return -ENOSYS;
-}
-
-static inline
-int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
-		      struct netlink_callback *cb,
-		      void *data, int len)
-{
-	return -ENOSYS;
-}
-
-static inline void iwl_testmode_init(struct iwl_priv *priv)
-{
-}
-
-static inline void iwl_testmode_free(struct iwl_priv *priv)
-{
-}
-#endif
-
 #ifdef CONFIG_IWLWIFI_DEBUG
 void iwl_print_rx_config_cmd(struct iwl_priv *priv,
 			     enum iwl_rxon_context_id ctxid);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/calib.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/calib.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/calib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/calib.c	2013-08-25 20:43:22.000000000 -0400
@@ -521,7 +521,7 @@ static int iwl_enhance_sensitivity_write
 
 	iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
 
-	if (priv->cfg->base_params->hd_v2) {
+	if (priv->lib->hd_v2) {
 		cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
 			HD_INA_NON_SQUARE_DET_OFDM_DATA_V2;
 		cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
@@ -895,7 +895,7 @@ static void iwlagn_gain_computation(stru
 			continue;
 		}
 
-		delta_g = (priv->cfg->base_params->chain_noise_scale *
+		delta_g = (priv->lib->chain_noise_scale *
 			((s32)average_noise[default_chain] -
 			(s32)average_noise[i])) / 1500;
 
@@ -1051,8 +1051,8 @@ void iwl_chain_noise_calibration(struct
 		return;
 
 	/* Analyze signal for disconnected antenna */
-	if (priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist) {
+	if (priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist) {
 		/* Disable disconnected antenna algorithm for advanced
 		   bt coex, assuming valid antennas are connected */
 		data->active_chains = priv->nvm_data->valid_rx_ant;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/commands.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/commands.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/commands.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/commands.h	2013-08-25 20:43:22.000000000 -0400
@@ -838,10 +838,6 @@ struct iwl_qosparam_cmd {
 #define STA_MODIFY_DELBA_TID_MSK	0x10
 #define STA_MODIFY_SLEEP_TX_COUNT_MSK	0x20
 
-/* Receiver address (actually, Rx station's index into station table),
- * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
-#define BUILD_RAxTID(sta_id, tid)	(((sta_id) << 4) + (tid))
-
 /* agn */
 struct iwl_keyinfo {
 	__le16 key_flags;
@@ -1225,14 +1221,6 @@ struct iwl_rx_mpdu_res_start {
 #define TX_CMD_SEC_KEY128	0x08
 
 /*
- * security overhead sizes
- */
-#define WEP_IV_LEN 4
-#define WEP_ICV_LEN 4
-#define CCMP_MIC_LEN 8
-#define TKIP_ICV_LEN 4
-
-/*
  * REPLY_TX = 0x1c (command)
  */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/dev.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/dev.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/dev.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/dev.h	2013-08-25 20:43:22.000000000 -0400
@@ -52,8 +52,6 @@
 #include "rs.h"
 #include "tt.h"
 
-#include "iwl-test.h"
-
 /* CT-KILL constants */
 #define CT_KILL_THRESHOLD_LEGACY   110 /* in Celsius */
 #define CT_KILL_THRESHOLD	   114 /* in Celsius */
@@ -568,16 +566,61 @@ struct iwl_hw_params {
 	const struct iwl_sensitivity_ranges *sens;
 };
 
-struct iwl_lib_ops {
-	/* set hw dependent parameters */
+/**
+ * struct iwl_dvm_bt_params - DVM specific BT (coex) parameters
+ * @advanced_bt_coexist: support advanced bt coexist
+ * @bt_init_traffic_load: specify initial bt traffic load
+ * @bt_prio_boost: default bt priority boost value
+ * @agg_time_limit: maximum number of uSec in aggregation
+ * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
+ */
+struct iwl_dvm_bt_params {
+	bool advanced_bt_coexist;
+	u8 bt_init_traffic_load;
+	u32 bt_prio_boost;
+	u16 agg_time_limit;
+	bool bt_sco_disable;
+	bool bt_session_2;
+};
+
+/**
+ * struct iwl_dvm_cfg - DVM firmware specific device configuration
+ * @set_hw_params: set hardware parameters
+ * @set_channel_switch: send channel switch command
+ * @nic_config: apply device specific configuration
+ * @temperature: read temperature
+ * @adv_thermal_throttle: support advance thermal throttle
+ * @support_ct_kill_exit: support ct kill exit condition
+ * @plcp_delta_threshold: plcp error rate threshold used to trigger
+ *	radio tuning when there is a high receiving plcp error rate
+ * @chain_noise_scale: default chain noise scale used for gain computation
+ * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
+ * @no_idle_support: do not support idle mode
+ * @bt_params: pointer to BT parameters
+ * @need_temp_offset_calib: need to perform temperature offset calibration
+ * @no_xtal_calib: some devices do not need crystal calibration data,
+ *	don't send it to those
+ * @temp_offset_v2: support v2 of temperature offset calibration
+ * @adv_pm: advanced power management
+ */
+struct iwl_dvm_cfg {
 	void (*set_hw_params)(struct iwl_priv *priv);
 	int (*set_channel_switch)(struct iwl_priv *priv,
 				  struct ieee80211_channel_switch *ch_switch);
-	/* device specific configuration */
 	void (*nic_config)(struct iwl_priv *priv);
-
-	/* temperature */
 	void (*temperature)(struct iwl_priv *priv);
+
+	const struct iwl_dvm_bt_params *bt_params;
+	s32 chain_noise_scale;
+	u8 plcp_delta_threshold;
+	bool adv_thermal_throttle;
+	bool support_ct_kill_exit;
+	bool hd_v2;
+	bool no_idle_support;
+	bool need_temp_offset_calib;
+	bool no_xtal_calib;
+	bool temp_offset_v2;
+	bool adv_pm;
 };
 
 struct iwl_wipan_noa_data {
@@ -610,7 +653,7 @@ struct iwl_priv {
 	struct device *dev;		/* for debug prints only */
 	const struct iwl_cfg *cfg;
 	const struct iwl_fw *fw;
-	const struct iwl_lib_ops *lib;
+	const struct iwl_dvm_cfg *lib;
 	unsigned long status;
 
 	spinlock_t sta_lock;
@@ -646,10 +689,6 @@ struct iwl_priv {
 	struct iwl_spectrum_notification measure_report;
 	u8 measurement_status;
 
-#define IWL_OWNERSHIP_DRIVER	0
-#define IWL_OWNERSHIP_TM	1
-	u8 ucode_owner;
-
 	/* ucode beacon time */
 	u32 ucode_beacon_time;
 	int missed_beacon_threshold;
@@ -844,7 +883,7 @@ struct iwl_priv {
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
 	struct iwl_nvm_data *nvm_data;
-	/* eeprom blob for debugfs/testmode */
+	/* eeprom blob for debugfs */
 	u8 *eeprom_blob;
 	size_t eeprom_blob_size;
 
@@ -860,16 +899,14 @@ struct iwl_priv {
 	unsigned long blink_on, blink_off;
 	bool led_registered;
 
-#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
-	struct iwl_test tst;
-	u32 tm_fixed_rate;
-#endif
-
 	/* WoWLAN GTK rekey data */
 	u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
 	__le64 replay_ctr;
 	__le16 last_seq_ctl;
 	bool have_rekey_data;
+#ifdef CONFIG_PM_SLEEP
+	struct wiphy_wowlan_support wowlan_support;
+#endif
 
 	/* device_pointers: pointers to ucode event tables */
 	struct {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/devices.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/devices.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/devices.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/devices.c	2013-08-25 20:43:22.000000000 -0400
@@ -174,10 +174,13 @@ static void iwl1000_hw_set_hw_params(str
 	priv->hw_params.sens = &iwl1000_sensitivity;
 }
 
-struct iwl_lib_ops iwl1000_lib = {
+const struct iwl_dvm_cfg iwl_dvm_1000_cfg = {
 	.set_hw_params = iwl1000_hw_set_hw_params,
 	.nic_config = iwl1000_nic_config,
 	.temperature = iwlagn_temperature,
+	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
 
@@ -232,16 +235,56 @@ static void iwl2000_hw_set_hw_params(str
 	priv->hw_params.sens = &iwl2000_sensitivity;
 }
 
-struct iwl_lib_ops iwl2000_lib = {
+const struct iwl_dvm_cfg iwl_dvm_2000_cfg = {
 	.set_hw_params = iwl2000_hw_set_hw_params,
 	.nic_config = iwl2000_nic_config,
 	.temperature = iwlagn_temperature,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
+	.hd_v2 = true,
+	.need_temp_offset_calib = true,
+	.temp_offset_v2 = true,
 };
 
-struct iwl_lib_ops iwl2030_lib = {
+const struct iwl_dvm_cfg iwl_dvm_105_cfg = {
+	.set_hw_params = iwl2000_hw_set_hw_params,
+	.nic_config = iwl2000_nic_config,
+	.temperature = iwlagn_temperature,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
+	.hd_v2 = true,
+	.need_temp_offset_calib = true,
+	.temp_offset_v2 = true,
+	.adv_pm = true,
+};
+
+static const struct iwl_dvm_bt_params iwl2030_bt_params = {
+	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+	.advanced_bt_coexist = true,
+	.agg_time_limit = BT_AGG_THRESHOLD_DEF,
+	.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
+	.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32,
+	.bt_sco_disable = true,
+	.bt_session_2 = true,
+};
+
+const struct iwl_dvm_cfg iwl_dvm_2030_cfg = {
 	.set_hw_params = iwl2000_hw_set_hw_params,
 	.nic_config = iwl2000_nic_config,
 	.temperature = iwlagn_temperature,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
+	.hd_v2 = true,
+	.bt_params = &iwl2030_bt_params,
+	.need_temp_offset_calib = true,
+	.temp_offset_v2 = true,
+	.adv_pm = true,
 };
 
 /*
@@ -420,16 +463,23 @@ static int iwl5000_hw_channel_switch(str
 	return iwl_dvm_send_cmd(priv, &hcmd);
 }
 
-struct iwl_lib_ops iwl5000_lib = {
+const struct iwl_dvm_cfg iwl_dvm_5000_cfg = {
 	.set_hw_params = iwl5000_hw_set_hw_params,
 	.set_channel_switch = iwl5000_hw_channel_switch,
 	.temperature = iwlagn_temperature,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
+	.no_idle_support = true,
 };
 
-struct iwl_lib_ops iwl5150_lib = {
+const struct iwl_dvm_cfg iwl_dvm_5150_cfg = {
 	.set_hw_params = iwl5150_hw_set_hw_params,
 	.set_channel_switch = iwl5000_hw_channel_switch,
 	.temperature = iwl5150_temperature,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
+	.no_idle_support = true,
+	.no_xtal_calib = true,
 };
 
 
@@ -584,16 +634,59 @@ static int iwl6000_hw_channel_switch(str
 	return err;
 }
 
-struct iwl_lib_ops iwl6000_lib = {
+const struct iwl_dvm_cfg iwl_dvm_6000_cfg = {
 	.set_hw_params = iwl6000_hw_set_hw_params,
 	.set_channel_switch = iwl6000_hw_channel_switch,
 	.nic_config = iwl6000_nic_config,
 	.temperature = iwlagn_temperature,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
 };
 
-struct iwl_lib_ops iwl6030_lib = {
+const struct iwl_dvm_cfg iwl_dvm_6005_cfg = {
 	.set_hw_params = iwl6000_hw_set_hw_params,
 	.set_channel_switch = iwl6000_hw_channel_switch,
 	.nic_config = iwl6000_nic_config,
 	.temperature = iwlagn_temperature,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
+	.need_temp_offset_calib = true,
+};
+
+const struct iwl_dvm_cfg iwl_dvm_6050_cfg = {
+	.set_hw_params = iwl6000_hw_set_hw_params,
+	.set_channel_switch = iwl6000_hw_channel_switch,
+	.nic_config = iwl6000_nic_config,
+	.temperature = iwlagn_temperature,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1500,
+};
+
+static const struct iwl_dvm_bt_params iwl6000_bt_params = {
+	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
+	.advanced_bt_coexist = true,
+	.agg_time_limit = BT_AGG_THRESHOLD_DEF,
+	.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
+	.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
+	.bt_sco_disable = true,
+};
+
+const struct iwl_dvm_cfg iwl_dvm_6030_cfg = {
+	.set_hw_params = iwl6000_hw_set_hw_params,
+	.set_channel_switch = iwl6000_hw_channel_switch,
+	.nic_config = iwl6000_nic_config,
+	.temperature = iwlagn_temperature,
+	.adv_thermal_throttle = true,
+	.support_ct_kill_exit = true,
+	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+	.chain_noise_scale = 1000,
+	.bt_params = &iwl6000_bt_params,
+	.need_temp_offset_calib = true,
+	.adv_pm = true,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/lib.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/lib.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/lib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/lib.c	2013-08-25 20:43:22.000000000 -0400
@@ -254,23 +254,23 @@ void iwlagn_send_advance_bt_config(struc
 	BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
 			sizeof(basic.bt3_lookup_table));
 
-	if (priv->cfg->bt_params) {
+	if (priv->lib->bt_params) {
 		/*
 		 * newer generation of devices (2000 series and newer)
 		 * use the version 2 of the bt command
 		 * we need to make sure sending the host command
 		 * with correct data structure to avoid uCode assert
 		 */
-		if (priv->cfg->bt_params->bt_session_2) {
+		if (priv->lib->bt_params->bt_session_2) {
 			bt_cmd_v2.prio_boost = cpu_to_le32(
-				priv->cfg->bt_params->bt_prio_boost);
+				priv->lib->bt_params->bt_prio_boost);
 			bt_cmd_v2.tx_prio_boost = 0;
 			bt_cmd_v2.rx_prio_boost = 0;
 		} else {
 			/* older version only has 8 bits */
-			WARN_ON(priv->cfg->bt_params->bt_prio_boost & ~0xFF);
+			WARN_ON(priv->lib->bt_params->bt_prio_boost & ~0xFF);
 			bt_cmd_v1.prio_boost =
-				priv->cfg->bt_params->bt_prio_boost;
+				priv->lib->bt_params->bt_prio_boost;
 			bt_cmd_v1.tx_prio_boost = 0;
 			bt_cmd_v1.rx_prio_boost = 0;
 		}
@@ -330,7 +330,7 @@ void iwlagn_send_advance_bt_config(struc
 		       priv->bt_full_concurrent ?
 		       "full concurrency" : "3-wire");
 
-	if (priv->cfg->bt_params->bt_session_2) {
+	if (priv->lib->bt_params->bt_session_2) {
 		memcpy(&bt_cmd_v2.basic, &basic,
 			sizeof(basic));
 		ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
@@ -758,8 +758,8 @@ static bool is_single_rx_stream(struct i
  */
 static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
 {
-	if (priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist &&
+	if (priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist &&
 	    (priv->bt_full_concurrent ||
 	     priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
 		/*
@@ -830,8 +830,8 @@ void iwlagn_set_rxon_chain(struct iwl_pr
 	else
 		active_chains = priv->nvm_data->valid_rx_ant;
 
-	if (priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist &&
+	if (priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist &&
 	    (priv->bt_full_concurrent ||
 	     priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
 		/*
@@ -1288,12 +1288,6 @@ int iwl_dvm_send_cmd(struct iwl_priv *pr
 	if (!(cmd->flags & CMD_ASYNC))
 		lockdep_assert_held(&priv->mutex);
 
-	if (priv->ucode_owner == IWL_OWNERSHIP_TM &&
-	    !(cmd->flags & CMD_ON_DEMAND)) {
-		IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n");
-		return -EIO;
-	}
-
 	return iwl_trans_send_cmd(priv->trans, cmd);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/mac80211.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/mac80211.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/mac80211.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/mac80211.c	2013-08-25 20:43:22.000000000 -0400
@@ -208,20 +208,21 @@ int iwlagn_mac_setup_register(struct iwl
 	    priv->trans->ops->d3_suspend &&
 	    priv->trans->ops->d3_resume &&
 	    device_can_wakeup(priv->trans->dev)) {
-		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-					  WIPHY_WOWLAN_DISCONNECT |
-					  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
-					  WIPHY_WOWLAN_RFKILL_RELEASE;
+		priv->wowlan_support.flags = WIPHY_WOWLAN_MAGIC_PKT |
+					     WIPHY_WOWLAN_DISCONNECT |
+					     WIPHY_WOWLAN_EAP_IDENTITY_REQ |
+					     WIPHY_WOWLAN_RFKILL_RELEASE;
 		if (!iwlwifi_mod_params.sw_crypto)
-			hw->wiphy->wowlan.flags |=
+			priv->wowlan_support.flags |=
 				WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
 				WIPHY_WOWLAN_GTK_REKEY_FAILURE;
 
-		hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS;
-		hw->wiphy->wowlan.pattern_min_len =
+		priv->wowlan_support.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS;
+		priv->wowlan_support.pattern_min_len =
 					IWLAGN_WOWLAN_MIN_PATTERN_LEN;
-		hw->wiphy->wowlan.pattern_max_len =
+		priv->wowlan_support.pattern_max_len =
 					IWLAGN_WOWLAN_MAX_PATTERN_LEN;
+		hw->wiphy->wowlan = &priv->wowlan_support;
 	}
 #endif
 
@@ -426,7 +427,11 @@ static int iwlagn_mac_suspend(struct iee
 	if (ret)
 		goto error;
 
-	iwl_trans_d3_suspend(priv->trans);
+	/* let the ucode operate on its own */
+	iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
+		    CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
+
+	iwl_trans_d3_suspend(priv->trans, false);
 
 	goto out;
 
@@ -500,7 +505,7 @@ static int iwlagn_mac_resume(struct ieee
 	/* we'll clear ctx->vif during iwlagn_prepare_restart() */
 	vif = ctx->vif;
 
-	ret = iwl_trans_d3_resume(priv->trans, &d3_status);
+	ret = iwl_trans_d3_resume(priv->trans, &d3_status, false);
 	if (ret)
 		goto out_unlock;
 
@@ -509,6 +514,10 @@ static int iwlagn_mac_resume(struct ieee
 		goto out_unlock;
 	}
 
+	/* uCode is no longer operating by itself */
+	iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
+		    CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
+
 	base = priv->device_pointers.error_event_table;
 	if (!iwlagn_hw_valid_rtc_data_addr(base)) {
 		IWL_WARN(priv, "Invalid error table during resume!\n");
@@ -1059,7 +1068,10 @@ void iwl_chswitch_done(struct iwl_priv *
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
 
-	if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
+	if (!test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
+		return;
+
+	if (ctx->vif)
 		ieee80211_chswitch_done(ctx->vif, is_success);
 }
 
@@ -1276,8 +1288,8 @@ static void iwlagn_mac_rssi_callback(str
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 	mutex_lock(&priv->mutex);
 
-	if (priv->cfg->bt_params &&
-			priv->cfg->bt_params->advanced_bt_coexist) {
+	if (priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist) {
 		if (rssi_event == RSSI_EVENT_LOW)
 			priv->bt_enable_pspoll = true;
 		else if (rssi_event == RSSI_EVENT_HIGH)
@@ -1387,7 +1399,7 @@ static int iwl_setup_interface(struct iw
 		return err;
 	}
 
-	if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist &&
+	if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist &&
 	    vif->type == NL80211_IFTYPE_ADHOC) {
 		/*
 		 * pretend to have high BT traffic as long as we
@@ -1757,8 +1769,6 @@ struct ieee80211_ops iwlagn_hw_ops = {
 	.remain_on_channel = iwlagn_mac_remain_on_channel,
 	.cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel,
 	.rssi_callback = iwlagn_mac_rssi_callback,
-	CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd)
-	CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump)
 	.set_tim = iwlagn_mac_set_tim,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -615,7 +615,7 @@ static void iwl_rf_kill_ct_config(struct
 
 	priv->thermal_throttle.ct_kill_toggle = false;
 
-	if (priv->cfg->base_params->support_ct_kill_exit) {
+	if (priv->lib->support_ct_kill_exit) {
 		adv_cmd.critical_temperature_enter =
 			cpu_to_le32(priv->hw_params.ct_kill_threshold);
 		adv_cmd.critical_temperature_exit =
@@ -732,10 +732,10 @@ int iwl_alive_start(struct iwl_priv *pri
 	}
 
 	/* download priority table before any calibration request */
-	if (priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist) {
+	if (priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist) {
 		/* Configure Bluetooth device coexistence support */
-		if (priv->cfg->bt_params->bt_sco_disable)
+		if (priv->lib->bt_params->bt_sco_disable)
 			priv->bt_enable_pspoll = false;
 		else
 			priv->bt_enable_pspoll = true;
@@ -758,7 +758,7 @@ int iwl_alive_start(struct iwl_priv *pri
 					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
 		if (ret)
 			return ret;
-	} else {
+	} else if (priv->lib->bt_params) {
 		/*
 		 * default is 2-wire BT coexexistence support
 		 */
@@ -873,9 +873,9 @@ void iwl_down(struct iwl_priv *priv)
 	priv->bt_status = 0;
 	priv->cur_rssi_ctx = NULL;
 	priv->bt_is_sco = 0;
-	if (priv->cfg->bt_params)
+	if (priv->lib->bt_params)
 		priv->bt_traffic_load =
-			 priv->cfg->bt_params->bt_init_traffic_load;
+			 priv->lib->bt_params->bt_init_traffic_load;
 	else
 		priv->bt_traffic_load = 0;
 	priv->bt_full_concurrent = false;
@@ -1058,7 +1058,7 @@ static void iwl_setup_deferred_work(stru
 
 	iwl_setup_scan_deferred_work(priv);
 
-	if (priv->cfg->bt_params)
+	if (priv->lib->bt_params)
 		iwlagn_bt_setup_deferred_work(priv);
 
 	init_timer(&priv->statistics_periodic);
@@ -1072,7 +1072,7 @@ static void iwl_setup_deferred_work(stru
 
 void iwl_cancel_deferred_work(struct iwl_priv *priv)
 {
-	if (priv->cfg->bt_params)
+	if (priv->lib->bt_params)
 		iwlagn_bt_cancel_deferred_work(priv);
 
 	cancel_work_sync(&priv->run_time_calib_work);
@@ -1098,16 +1098,13 @@ static int iwl_init_drv(struct iwl_priv
 
 	priv->band = IEEE80211_BAND_2GHZ;
 
-	priv->plcp_delta_threshold =
-		priv->cfg->base_params->plcp_delta_threshold;
+	priv->plcp_delta_threshold = priv->lib->plcp_delta_threshold;
 
 	priv->iw_mode = NL80211_IFTYPE_STATION;
 	priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
 	priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
 	priv->agg_tids_count = 0;
 
-	priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
-
 	priv->rx_statistics_jiffies = jiffies;
 
 	/* Choose which receivers/antennas to use */
@@ -1116,8 +1113,8 @@ static int iwl_init_drv(struct iwl_priv
 	iwl_init_scan_params(priv);
 
 	/* init bt coex */
-	if (priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist) {
+	if (priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist) {
 		priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
 		priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
 		priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
@@ -1173,12 +1170,6 @@ static void iwl_option_config(struct iwl
 	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n");
 #endif
 
-#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
-	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE enabled\n");
-#else
-	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE disabled\n");
-#endif
-
 #ifdef CONFIG_IWLWIFI_P2P
 	IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n");
 #else
@@ -1264,31 +1255,37 @@ static struct iwl_op_mode *iwl_op_mode_d
 	switch (priv->cfg->device_family) {
 	case IWL_DEVICE_FAMILY_1000:
 	case IWL_DEVICE_FAMILY_100:
-		priv->lib = &iwl1000_lib;
+		priv->lib = &iwl_dvm_1000_cfg;
 		break;
 	case IWL_DEVICE_FAMILY_2000:
+		priv->lib = &iwl_dvm_2000_cfg;
+		break;
 	case IWL_DEVICE_FAMILY_105:
-		priv->lib = &iwl2000_lib;
+		priv->lib = &iwl_dvm_105_cfg;
 		break;
 	case IWL_DEVICE_FAMILY_2030:
 	case IWL_DEVICE_FAMILY_135:
-		priv->lib = &iwl2030_lib;
+		priv->lib = &iwl_dvm_2030_cfg;
 		break;
 	case IWL_DEVICE_FAMILY_5000:
-		priv->lib = &iwl5000_lib;
+		priv->lib = &iwl_dvm_5000_cfg;
 		break;
 	case IWL_DEVICE_FAMILY_5150:
-		priv->lib = &iwl5150_lib;
+		priv->lib = &iwl_dvm_5150_cfg;
 		break;
 	case IWL_DEVICE_FAMILY_6000:
-	case IWL_DEVICE_FAMILY_6005:
 	case IWL_DEVICE_FAMILY_6000i:
+		priv->lib = &iwl_dvm_6000_cfg;
+		break;
+	case IWL_DEVICE_FAMILY_6005:
+		priv->lib = &iwl_dvm_6005_cfg;
+		break;
 	case IWL_DEVICE_FAMILY_6050:
 	case IWL_DEVICE_FAMILY_6150:
-		priv->lib = &iwl6000_lib;
+		priv->lib = &iwl_dvm_6050_cfg;
 		break;
 	case IWL_DEVICE_FAMILY_6030:
-		priv->lib = &iwl6030_lib;
+		priv->lib = &iwl_dvm_6030_cfg;
 		break;
 	default:
 		break;
@@ -1350,8 +1347,8 @@ static struct iwl_op_mode *iwl_op_mode_d
 			IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
 			true : false;
 
-	/* enable/disable bt channel inhibition */
-	priv->bt_ch_announce = iwlwifi_mod_params.bt_ch_announce;
+	/* bt channel inhibition enabled*/
+	priv->bt_ch_announce = true;
 	IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
 		       (priv->bt_ch_announce) ? "On" : "Off");
 
@@ -1446,7 +1443,6 @@ static struct iwl_op_mode *iwl_op_mode_d
 	 ********************/
 	iwl_setup_deferred_work(priv);
 	iwl_setup_rx_handlers(priv);
-	iwl_testmode_init(priv);
 
 	iwl_power_initialize(priv);
 	iwl_tt_initialize(priv);
@@ -1483,7 +1479,6 @@ out_mac80211_unregister:
 	iwlagn_mac_unregister(priv);
 out_destroy_workqueue:
 	iwl_tt_exit(priv);
-	iwl_testmode_free(priv);
 	iwl_cancel_deferred_work(priv);
 	destroy_workqueue(priv->workqueue);
 	priv->workqueue = NULL;
@@ -1505,7 +1500,6 @@ static void iwl_op_mode_dvm_stop(struct
 
 	IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
 
-	iwl_testmode_free(priv);
 	iwlagn_mac_unregister(priv);
 
 	iwl_tt_exit(priv);
@@ -1854,14 +1848,9 @@ int iwl_dump_nic_event_log(struct iwl_pr
 		return pos;
 	}
 
-#ifdef CONFIG_IWLWIFI_DEBUG
 	if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log)
 		size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
 			? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
-#else
-	size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
-		? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
-#endif
 	IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n",
 		size);
 
@@ -1905,10 +1894,8 @@ static void iwlagn_fw_error(struct iwl_p
 	unsigned int reload_msec;
 	unsigned long reload_jiffies;
 
-#ifdef CONFIG_IWLWIFI_DEBUG
 	if (iwl_have_debug_level(IWL_DL_FW_ERRORS))
 		iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
-#endif
 
 	/* uCode is no longer loaded. */
 	priv->ucode_loaded = false;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -8,6 +8,5 @@ iwldvm-objs		+= scan.o led.o
 iwldvm-objs		+= rxon.o devices.o
 
 iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
-iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += testmode.o
 
 ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/power.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/power.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/power.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/power.c	2013-08-25 20:43:22.000000000 -0400
@@ -163,7 +163,7 @@ static void iwl_static_sleep_cmd(struct
 	u8 skip;
 	u32 slp_itrvl;
 
-	if (priv->cfg->adv_pm) {
+	if (priv->lib->adv_pm) {
 		table = apm_range_2;
 		if (period <= IWL_DTIM_RANGE_1_MAX)
 			table = apm_range_1;
@@ -217,7 +217,7 @@ static void iwl_static_sleep_cmd(struct
 		cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
 
 	if (iwl_advanced_bt_coexist(priv)) {
-		if (!priv->cfg->bt_params->bt_sco_disable)
+		if (!priv->lib->bt_params->bt_sco_disable)
 			cmd->flags |= IWL_POWER_BT_SCO_ENA;
 		else
 			cmd->flags &= ~IWL_POWER_BT_SCO_ENA;
@@ -293,7 +293,7 @@ static void iwl_power_build_cmd(struct i
 
 	if (priv->wowlan)
 		iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper);
-	else if (!priv->cfg->base_params->no_idle_support &&
+	else if (!priv->lib->no_idle_support &&
 		 priv->hw->conf.flags & IEEE80211_CONF_IDLE)
 		iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
 	else if (iwl_tt_is_low_power_state(priv)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/rs.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/rs.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/rs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/rs.c	2013-08-25 20:43:22.000000000 -0400
@@ -351,12 +351,6 @@ static void rs_program_fix_rate(struct i
 	lq_sta->active_mimo2_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
 	lq_sta->active_mimo3_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
 
-#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
-	/* testmode has higher priority to overwirte the fixed rate */
-	if (priv->tm_fixed_rate)
-		lq_sta->dbg_fixed_rate = priv->tm_fixed_rate;
-#endif
-
 	IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
 		lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
 
@@ -419,23 +413,18 @@ static int rs_tl_turn_on_agg_for_tid(str
 
 	load = rs_tl_get_load(lq_data, tid);
 
-	if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) {
-		IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
-				sta->addr, tid);
-		ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
-		if (ret == -EAGAIN) {
-			/*
-			 * driver and mac80211 is out of sync
-			 * this might be cause by reloading firmware
-			 * stop the tx ba session here
-			 */
-			IWL_ERR(priv, "Fail start Tx agg on tid: %d\n",
-				tid);
-			ieee80211_stop_tx_ba_session(sta, tid);
-		}
-	} else {
-		IWL_DEBUG_HT(priv, "Aggregation not enabled for tid %d "
-			"because load = %u\n", tid, load);
+	IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
+			sta->addr, tid);
+	ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
+	if (ret == -EAGAIN) {
+		/*
+		 * driver and mac80211 is out of sync
+		 * this might be cause by reloading firmware
+		 * stop the tx ba session here
+		 */
+		IWL_ERR(priv, "Fail start Tx agg on tid: %d\n",
+			tid);
+		ieee80211_stop_tx_ba_session(sta, tid);
 	}
 	return ret;
 }
@@ -1083,12 +1072,7 @@ done:
 	if (sta && sta->supp_rates[sband->band])
 		rs_rate_scale_perform(priv, skb, sta, lq_sta);
 
-#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_TESTMODE)
-	if ((priv->tm_fixed_rate) &&
-	    (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
-		rs_program_fix_rate(priv, lq_sta);
-#endif
-	if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
+	if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist)
 		rs_bt_update_lq(priv, ctx, lq_sta);
 }
 
@@ -2913,9 +2897,6 @@ void iwl_rs_rate_init(struct iwl_priv *p
 	if (sband->band == IEEE80211_BAND_5GHZ)
 		lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
 	lq_sta->is_agg = 0;
-#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
-	priv->tm_fixed_rate = 0;
-#endif
 #ifdef CONFIG_MAC80211_DEBUGFS
 	lq_sta->dbg_fixed_rate = 0;
 #endif
@@ -3064,11 +3045,11 @@ static void rs_fill_link_cmd(struct iwl_
 	 * overwrite if needed, pass aggregation time limit
 	 * to uCode in uSec
 	 */
-	if (priv && priv->cfg->bt_params &&
-	    priv->cfg->bt_params->agg_time_limit &&
+	if (priv && priv->lib->bt_params &&
+	    priv->lib->bt_params->agg_time_limit &&
 	    priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
 		lq_cmd->agg_params.agg_time_limit =
-			cpu_to_le16(priv->cfg->bt_params->agg_time_limit);
+			cpu_to_le16(priv->lib->bt_params->agg_time_limit);
 }
 
 static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/rx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/rx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/rx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/rx.c	2013-08-25 20:43:22.000000000 -0400
@@ -335,8 +335,7 @@ static void iwlagn_recover_from_statisti
 	if (msecs < 99)
 		return;
 
-	if (iwlwifi_mod_params.plcp_check &&
-	    !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
+	if (!iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
 		iwl_force_rf_reset(priv, false);
 }
 
@@ -1102,7 +1101,7 @@ void iwl_setup_rx_handlers(struct iwl_pr
 	iwl_notification_wait_init(&priv->notif_wait);
 
 	/* Set up BT Rx handlers */
-	if (priv->cfg->bt_params)
+	if (priv->lib->bt_params)
 		iwlagn_bt_rx_handler_setup(priv);
 }
 
@@ -1120,32 +1119,17 @@ int iwl_rx_dispatch(struct iwl_op_mode *
 	 */
 	iwl_notification_wait_notify(&priv->notif_wait, pkt);
 
-#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
-	/*
-	 * RX data may be forwarded to userspace in one
-	 * of two cases: the user owns the fw through testmode or when
-	 * the user requested to monitor the rx w/o affecting the regular flow.
-	 * In these cases the iwl_test object will handle forwarding the rx
-	 * data to user space.
-	 * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow
-	 * continues.
-	 */
-	iwl_test_rx(&priv->tst, rxb);
-#endif
-
-	if (priv->ucode_owner != IWL_OWNERSHIP_TM) {
-		/* Based on type of command response or notification,
-		 *   handle those that need handling via function in
-		 *   rx_handlers table.  See iwl_setup_rx_handlers() */
-		if (priv->rx_handlers[pkt->hdr.cmd]) {
-			priv->rx_handlers_stats[pkt->hdr.cmd]++;
-			err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
-		} else {
-			/* No handling needed */
-			IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n",
-				     iwl_dvm_get_cmd_string(pkt->hdr.cmd),
-				     pkt->hdr.cmd);
-		}
+	/* Based on type of command response or notification,
+	 *   handle those that need handling via function in
+	 *   rx_handlers table.  See iwl_setup_rx_handlers() */
+	if (priv->rx_handlers[pkt->hdr.cmd]) {
+		priv->rx_handlers_stats[pkt->hdr.cmd]++;
+		err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
+	} else {
+		/* No handling needed */
+		IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n",
+			     iwl_dvm_get_cmd_string(pkt->hdr.cmd),
+			     pkt->hdr.cmd);
 	}
 	return err;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/scan.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/scan.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/scan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/scan.c	2013-08-25 20:43:22.000000000 -0400
@@ -801,8 +801,8 @@ static int iwlagn_request_scan(struct iw
 		 * Internal scans are passive, so we can indiscriminately set
 		 * the BT ignore flag on 2.4 GHz since it applies to TX only.
 		 */
-		if (priv->cfg->bt_params &&
-		    priv->cfg->bt_params->advanced_bt_coexist)
+		if (priv->lib->bt_params &&
+		    priv->lib->bt_params->advanced_bt_coexist)
 			scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
 		break;
 	case IEEE80211_BAND_5GHZ:
@@ -844,8 +844,8 @@ static int iwlagn_request_scan(struct iw
 	band = priv->scan_band;
 
 	if (band == IEEE80211_BAND_2GHZ &&
-	    priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist) {
+	    priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist) {
 		/* transmit 2.4 GHz probes only on first antenna */
 		scan_tx_antennas = first_antenna(scan_tx_antennas);
 	}
@@ -873,8 +873,8 @@ static int iwlagn_request_scan(struct iw
 
 		rx_ant = first_antenna(active_chains);
 	}
-	if (priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist &&
+	if (priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist &&
 	    priv->bt_full_concurrent) {
 		/* operated as 1x1 in full concurrency mode */
 		rx_ant = first_antenna(rx_ant);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/testmode.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/testmode.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/testmode.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/testmode.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,471 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called COPYING.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <net/net_namespace.h>
-#include <linux/netdevice.h>
-#include <net/cfg80211.h>
-#include <net/mac80211.h>
-#include <net/netlink.h>
-
-#include "iwl-debug.h"
-#include "iwl-trans.h"
-#include "dev.h"
-#include "agn.h"
-#include "iwl-test.h"
-#include "iwl-testmode.h"
-
-static int iwl_testmode_send_cmd(struct iwl_op_mode *op_mode,
-				 struct iwl_host_cmd *cmd)
-{
-	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
-	return iwl_dvm_send_cmd(priv, cmd);
-}
-
-static bool iwl_testmode_valid_hw_addr(u32 addr)
-{
-	if (iwlagn_hw_valid_rtc_data_addr(addr))
-		return true;
-
-	if (IWLAGN_RTC_INST_LOWER_BOUND <= addr &&
-	    addr < IWLAGN_RTC_INST_UPPER_BOUND)
-		return true;
-
-	return false;
-}
-
-static u32 iwl_testmode_get_fw_ver(struct iwl_op_mode *op_mode)
-{
-	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
-	return priv->fw->ucode_ver;
-}
-
-static struct sk_buff*
-iwl_testmode_alloc_reply(struct iwl_op_mode *op_mode, int len)
-{
-	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
-	return cfg80211_testmode_alloc_reply_skb(priv->hw->wiphy, len);
-}
-
-static int iwl_testmode_reply(struct iwl_op_mode *op_mode, struct sk_buff *skb)
-{
-	return cfg80211_testmode_reply(skb);
-}
-
-static struct sk_buff *iwl_testmode_alloc_event(struct iwl_op_mode *op_mode,
-						int len)
-{
-	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
-	return cfg80211_testmode_alloc_event_skb(priv->hw->wiphy, len,
-						 GFP_ATOMIC);
-}
-
-static void iwl_testmode_event(struct iwl_op_mode *op_mode, struct sk_buff *skb)
-{
-	return cfg80211_testmode_event(skb, GFP_ATOMIC);
-}
-
-static struct iwl_test_ops tst_ops = {
-	.send_cmd = iwl_testmode_send_cmd,
-	.valid_hw_addr = iwl_testmode_valid_hw_addr,
-	.get_fw_ver = iwl_testmode_get_fw_ver,
-	.alloc_reply = iwl_testmode_alloc_reply,
-	.reply = iwl_testmode_reply,
-	.alloc_event = iwl_testmode_alloc_event,
-	.event = iwl_testmode_event,
-};
-
-void iwl_testmode_init(struct iwl_priv *priv)
-{
-	iwl_test_init(&priv->tst, priv->trans, &tst_ops);
-}
-
-void iwl_testmode_free(struct iwl_priv *priv)
-{
-	iwl_test_free(&priv->tst);
-}
-
-static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
-{
-	struct iwl_notification_wait calib_wait;
-	static const u8 calib_complete[] = {
-		CALIBRATION_COMPLETE_NOTIFICATION
-	};
-	int ret;
-
-	iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
-				   calib_complete, ARRAY_SIZE(calib_complete),
-				   NULL, NULL);
-	ret = iwl_init_alive_start(priv);
-	if (ret) {
-		IWL_ERR(priv, "Fail init calibration: %d\n", ret);
-		goto cfg_init_calib_error;
-	}
-
-	ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ);
-	if (ret)
-		IWL_ERR(priv, "Error detecting"
-			" CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
-	return ret;
-
-cfg_init_calib_error:
-	iwl_remove_notification(&priv->notif_wait, &calib_wait);
-	return ret;
-}
-
-/*
- * This function handles the user application commands for driver.
- *
- * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
- * handlers respectively.
- *
- * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
- * value of the actual command execution is replied to the user application.
- *
- * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
- * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
- * IWL_TM_CMD_DEV2APP_SYNC_RSP.
- *
- * @hw: ieee80211_hw object that represents the device
- * @tb: gnl message fields from the user space
- */
-static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
-{
-	struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
-	struct iwl_trans *trans = priv->trans;
-	struct sk_buff *skb;
-	unsigned char *rsp_data_ptr = NULL;
-	int status = 0, rsp_data_len = 0;
-	u32 inst_size = 0, data_size = 0;
-	const struct fw_img *img;
-
-	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
-	case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
-		rsp_data_ptr = (unsigned char *)priv->cfg->name;
-		rsp_data_len = strlen(priv->cfg->name);
-		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
-							rsp_data_len + 20);
-		if (!skb) {
-			IWL_ERR(priv, "Memory allocation fail\n");
-			return -ENOMEM;
-		}
-		if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
-				IWL_TM_CMD_DEV2APP_SYNC_RSP) ||
-		    nla_put(skb, IWL_TM_ATTR_SYNC_RSP,
-			    rsp_data_len, rsp_data_ptr))
-			goto nla_put_failure;
-		status = cfg80211_testmode_reply(skb);
-		if (status < 0)
-			IWL_ERR(priv, "Error sending msg : %d\n", status);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
-		status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT);
-		if (status)
-			IWL_ERR(priv, "Error loading init ucode: %d\n", status);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
-		iwl_testmode_cfg_init_calib(priv);
-		priv->ucode_loaded = false;
-		iwl_trans_stop_device(trans);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
-		status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR);
-		if (status) {
-			IWL_ERR(priv,
-				"Error loading runtime ucode: %d\n", status);
-			break;
-		}
-		status = iwl_alive_start(priv);
-		if (status)
-			IWL_ERR(priv,
-				"Error starting the device: %d\n", status);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
-		iwl_scan_cancel_timeout(priv, 200);
-		priv->ucode_loaded = false;
-		iwl_trans_stop_device(trans);
-		status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
-		if (status) {
-			IWL_ERR(priv,
-				"Error loading WOWLAN ucode: %d\n", status);
-			break;
-		}
-		status = iwl_alive_start(priv);
-		if (status)
-			IWL_ERR(priv,
-				"Error starting the device: %d\n", status);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_GET_EEPROM:
-		if (priv->eeprom_blob) {
-			skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
-				priv->eeprom_blob_size + 20);
-			if (!skb) {
-				IWL_ERR(priv, "Memory allocation fail\n");
-				return -ENOMEM;
-			}
-			if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
-					IWL_TM_CMD_DEV2APP_EEPROM_RSP) ||
-			    nla_put(skb, IWL_TM_ATTR_EEPROM,
-				    priv->eeprom_blob_size,
-				    priv->eeprom_blob))
-				goto nla_put_failure;
-			status = cfg80211_testmode_reply(skb);
-			if (status < 0)
-				IWL_ERR(priv, "Error sending msg : %d\n",
-					status);
-		} else
-			return -ENODATA;
-		break;
-
-	case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
-		if (!tb[IWL_TM_ATTR_FIXRATE]) {
-			IWL_ERR(priv, "Missing fixrate setting\n");
-			return -ENOMSG;
-		}
-		priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
-		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
-		if (!skb) {
-			IWL_ERR(priv, "Memory allocation fail\n");
-			return -ENOMEM;
-		}
-		if (!priv->ucode_loaded) {
-			IWL_ERR(priv, "No uCode has not been loaded\n");
-			return -EINVAL;
-		} else {
-			img = &priv->fw->img[priv->cur_ucode];
-			inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
-			data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
-		}
-		if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode) ||
-		    nla_put_u32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size) ||
-		    nla_put_u32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size))
-			goto nla_put_failure;
-		status = cfg80211_testmode_reply(skb);
-		if (status < 0)
-			IWL_ERR(priv, "Error sending msg : %d\n", status);
-		break;
-
-	default:
-		IWL_ERR(priv, "Unknown testmode driver command ID\n");
-		return -ENOSYS;
-	}
-	return status;
-
-nla_put_failure:
-	kfree_skb(skb);
-	return -EMSGSIZE;
-}
-
-/*
- * This function handles the user application switch ucode ownership.
- *
- * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and
- * decide who the current owner of the uCode
- *
- * If the current owner is OWNERSHIP_TM, then the only host command
- * can deliver to uCode is from testmode, all the other host commands
- * will dropped.
- *
- * default driver is the owner of uCode in normal operational mode
- *
- * @hw: ieee80211_hw object that represents the device
- * @tb: gnl message fields from the user space
- */
-static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
-{
-	struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
-	u8 owner;
-
-	if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
-		IWL_ERR(priv, "Missing ucode owner\n");
-		return -ENOMSG;
-	}
-
-	owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
-	if (owner == IWL_OWNERSHIP_DRIVER) {
-		priv->ucode_owner = owner;
-		iwl_test_enable_notifications(&priv->tst, false);
-	} else if (owner == IWL_OWNERSHIP_TM) {
-		priv->ucode_owner = owner;
-		iwl_test_enable_notifications(&priv->tst, true);
-	} else {
-		IWL_ERR(priv, "Invalid owner\n");
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/* The testmode gnl message handler that takes the gnl message from the
- * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
- * invoke the corresponding handlers.
- *
- * This function is invoked when there is user space application sending
- * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
- * by nl80211.
- *
- * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
- * dispatching it to the corresponding handler.
- *
- * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
- * -ENOSYS is replied to the user application if the command is unknown;
- * Otherwise, the command is dispatched to the respective handler.
- *
- * @hw: ieee80211_hw object that represents the device
- * @data: pointer to user space message
- * @len: length in byte of @data
- */
-int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
-{
-	struct nlattr *tb[IWL_TM_ATTR_MAX];
-	struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
-	int result;
-
-	result = iwl_test_parse(&priv->tst, tb, data, len);
-	if (result)
-		return result;
-
-	/* in case multiple accesses to the device happens */
-	mutex_lock(&priv->mutex);
-	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
-	case IWL_TM_CMD_APP2DEV_UCODE:
-	case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
-	case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
-	case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
-	case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
-	case IWL_TM_CMD_APP2DEV_END_TRACE:
-	case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
-	case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
-	case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
-	case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
-	case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
-		result = iwl_test_handle_cmd(&priv->tst, tb);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
-	case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
-	case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
-	case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
-	case IWL_TM_CMD_APP2DEV_GET_EEPROM:
-	case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
-	case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
-	case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
-		IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
-		result = iwl_testmode_driver(hw, tb);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_OWNERSHIP:
-		IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n");
-		result = iwl_testmode_ownership(hw, tb);
-		break;
-
-	default:
-		IWL_ERR(priv, "Unknown testmode command\n");
-		result = -ENOSYS;
-		break;
-	}
-	mutex_unlock(&priv->mutex);
-
-	if (result)
-		IWL_ERR(priv, "Test cmd failed result=%d\n", result);
-	return result;
-}
-
-int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
-		      struct netlink_callback *cb,
-		      void *data, int len)
-{
-	struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
-	int result;
-	u32 cmd;
-
-	if (cb->args[3]) {
-		/* offset by 1 since commands start at 0 */
-		cmd = cb->args[3] - 1;
-	} else {
-		struct nlattr *tb[IWL_TM_ATTR_MAX];
-
-		result = iwl_test_parse(&priv->tst, tb, data, len);
-		if (result)
-			return result;
-
-		cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
-		cb->args[3] = cmd + 1;
-	}
-
-	/* in case multiple accesses to the device happens */
-	mutex_lock(&priv->mutex);
-	result = iwl_test_dump(&priv->tst, cmd, skb, cb);
-	mutex_unlock(&priv->mutex);
-	return result;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/tt.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/tt.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/tt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/tt.c	2013-08-25 20:43:22.000000000 -0400
@@ -627,7 +627,7 @@ void iwl_tt_initialize(struct iwl_priv *
 	INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
 	INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
 
-	if (priv->cfg->base_params->adv_thermal_throttle) {
+	if (priv->lib->adv_thermal_throttle) {
 		IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n");
 		tt->restriction = kcalloc(IWL_TI_STATE_MAX,
 					  sizeof(struct iwl_tt_restriction),
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/tx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/tx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/tx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/tx.c	2013-08-25 20:43:22.000000000 -0400
@@ -83,8 +83,8 @@ static void iwlagn_tx_cmd_build_basic(st
 	else if (ieee80211_is_back_req(fc))
 		tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
 	else if (info->band == IEEE80211_BAND_2GHZ &&
-		 priv->cfg->bt_params &&
-		 priv->cfg->bt_params->advanced_bt_coexist &&
+		 priv->lib->bt_params &&
+		 priv->lib->bt_params->advanced_bt_coexist &&
 		 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
 		 ieee80211_is_reassoc_req(fc) ||
 		 skb->protocol == cpu_to_be16(ETH_P_PAE)))
@@ -162,18 +162,6 @@ static void iwlagn_tx_cmd_build_rate(str
 	if (ieee80211_is_data(fc)) {
 		tx_cmd->initial_rate_index = 0;
 		tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
-#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
-		if (priv->tm_fixed_rate) {
-			/*
-			 * rate overwrite by testmode
-			 * we not only send lq command to change rate
-			 * we also re-enforce per data pkt base.
-			 */
-			tx_cmd->tx_flags &= ~TX_CMD_FLG_STA_RATE_MSK;
-			memcpy(&tx_cmd->rate_n_flags, &priv->tm_fixed_rate,
-			       sizeof(tx_cmd->rate_n_flags));
-		}
-#endif
 		return;
 	} else if (ieee80211_is_back_req(fc))
 		tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
@@ -202,8 +190,8 @@ static void iwlagn_tx_cmd_build_rate(str
 		rate_flags |= RATE_MCS_CCK_MSK;
 
 	/* Set up antennas */
-	 if (priv->cfg->bt_params &&
-	     priv->cfg->bt_params->advanced_bt_coexist &&
+	 if (priv->lib->bt_params &&
+	     priv->lib->bt_params->advanced_bt_coexist &&
 	     priv->bt_full_concurrent) {
 		/* operated as 1x1 in full concurrency mode */
 		priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
@@ -986,8 +974,8 @@ static void iwl_rx_reply_tx_agg(struct i
 	 * notification again.
 	 */
 	if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
-	    priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist) {
+	    priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist) {
 		IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n");
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/ucode.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/ucode.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/dvm/ucode.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/dvm/ucode.c	2013-08-25 20:43:22.000000000 -0400
@@ -132,8 +132,8 @@ int iwl_init_alive_start(struct iwl_priv
 {
 	int ret;
 
-	if (priv->cfg->bt_params &&
-	    priv->cfg->bt_params->advanced_bt_coexist) {
+	if (priv->lib->bt_params &&
+	    priv->lib->bt_params->advanced_bt_coexist) {
 		/*
 		 * Tell uCode we are ready to perform calibration
 		 * need to perform this before any calibration
@@ -155,8 +155,8 @@ int iwl_init_alive_start(struct iwl_priv
 	 * temperature offset calibration is only needed for runtime ucode,
 	 * so prepare the value now.
 	 */
-	if (priv->cfg->need_temp_offset_calib) {
-		if (priv->cfg->temp_offset_v2)
+	if (priv->lib->need_temp_offset_calib) {
+		if (priv->lib->temp_offset_v2)
 			return iwl_set_temperature_offset_calib_v2(priv);
 		else
 			return iwl_set_temperature_offset_calib(priv);
@@ -277,7 +277,7 @@ static int iwl_alive_notify(struct iwl_p
 	if (ret)
 		return ret;
 
-	if (!priv->cfg->no_xtal_calib) {
+	if (!priv->lib->no_xtal_calib) {
 		ret = iwl_set_Xtal_calib(priv);
 		if (ret)
 			return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-1000.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-1000.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-1000.c	2013-07-01 10:38:54.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-1000.c	2013-08-31 17:58:36.000000000 -0400
@@ -60,9 +60,6 @@ static const struct iwl_base_params iwl1
 	.max_ll_items = OTP_MAX_LL_ITEMS_1000,
 	.shadow_ram_support = false,
 	.led_compensation = 51,
-	.support_ct_kill_exit = true,
-	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
-	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_WATCHDOG_DISABLED,
 	.max_event_log_size = 128,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-2000.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-2000.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-2000.c	2013-07-01 10:38:56.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-2000.c	2013-08-31 17:58:38.000000000 -0400
@@ -72,14 +72,9 @@ static const struct iwl_base_params iwl2
 	.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
 	.shadow_ram_support = true,
 	.led_compensation = 51,
-	.adv_thermal_throttle = true,
-	.support_ct_kill_exit = true,
-	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
-	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_DEF_WD_TIMEOUT,
 	.max_event_log_size = 512,
 	.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
-	.hd_v2 = true,
 };
 
 
@@ -90,14 +85,9 @@ static const struct iwl_base_params iwl2
 	.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
 	.shadow_ram_support = true,
 	.led_compensation = 57,
-	.adv_thermal_throttle = true,
-	.support_ct_kill_exit = true,
-	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
-	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_LONG_WD_TIMEOUT,
 	.max_event_log_size = 512,
 	.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
-	.hd_v2 = true,
 };
 
 static const struct iwl_ht_params iwl2000_ht_params = {
@@ -106,16 +96,6 @@ static const struct iwl_ht_params iwl200
 	.ht40_bands = BIT(IEEE80211_BAND_2GHZ),
 };
 
-static const struct iwl_bt_params iwl2030_bt_params = {
-	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
-	.advanced_bt_coexist = true,
-	.agg_time_limit = BT_AGG_THRESHOLD_DEF,
-	.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
-	.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32,
-	.bt_sco_disable = true,
-	.bt_session_2 = true,
-};
-
 static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
 	.regulatory_bands = {
 		EEPROM_REG_BAND_1_CHANNELS,
@@ -137,12 +117,10 @@ static const struct iwl_eeprom_params iw
 	.device_family = IWL_DEVICE_FAMILY_2000,		\
 	.max_inst_size = IWL60_RTC_INST_SIZE,			\
 	.max_data_size = IWL60_RTC_DATA_SIZE,			\
-	.nvm_ver = EEPROM_2000_EEPROM_VERSION,		\
-	.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
+	.nvm_ver = EEPROM_2000_EEPROM_VERSION,			\
+	.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION,		\
 	.base_params = &iwl2000_base_params,			\
 	.eeprom_params = &iwl20x0_eeprom_params,		\
-	.need_temp_offset_calib = true,				\
-	.temp_offset_v2 = true,					\
 	.led_mode = IWL_LED_RF_STATE
 
 const struct iwl_cfg iwl2000_2bgn_cfg = {
@@ -168,12 +146,8 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg
 	.nvm_ver = EEPROM_2000_EEPROM_VERSION,		\
 	.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
 	.base_params = &iwl2030_base_params,			\
-	.bt_params = &iwl2030_bt_params,			\
 	.eeprom_params = &iwl20x0_eeprom_params,		\
-	.need_temp_offset_calib = true,				\
-	.temp_offset_v2 = true,					\
-	.led_mode = IWL_LED_RF_STATE,				\
-	.adv_pm = true
+	.led_mode = IWL_LED_RF_STATE
 
 const struct iwl_cfg iwl2030_2bgn_cfg = {
 	.name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
@@ -193,10 +167,7 @@ const struct iwl_cfg iwl2030_2bgn_cfg =
 	.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
 	.base_params = &iwl2000_base_params,			\
 	.eeprom_params = &iwl20x0_eeprom_params,		\
-	.need_temp_offset_calib = true,				\
-	.temp_offset_v2 = true,					\
 	.led_mode = IWL_LED_RF_STATE,				\
-	.adv_pm = true,						\
 	.rx_with_siso_diversity = true
 
 const struct iwl_cfg iwl105_bgn_cfg = {
@@ -222,12 +193,8 @@ const struct iwl_cfg iwl105_bgn_d_cfg =
 	.nvm_ver = EEPROM_2000_EEPROM_VERSION,		\
 	.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
 	.base_params = &iwl2030_base_params,			\
-	.bt_params = &iwl2030_bt_params,			\
 	.eeprom_params = &iwl20x0_eeprom_params,		\
-	.need_temp_offset_calib = true,				\
-	.temp_offset_v2 = true,					\
 	.led_mode = IWL_LED_RF_STATE,				\
-	.adv_pm = true,						\
 	.rx_with_siso_diversity = true
 
 const struct iwl_cfg iwl135_bgn_cfg = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-5000.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-5000.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-5000.c	2013-07-01 10:38:48.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-5000.c	2013-08-31 17:58:31.000000000 -0400
@@ -59,11 +59,8 @@ static const struct iwl_base_params iwl5
 	.num_of_queues = IWLAGN_NUM_QUEUES,
 	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
 	.led_compensation = 51,
-	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
-	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_WATCHDOG_DISABLED,
 	.max_event_log_size = 512,
-	.no_idle_support = true,
 };
 
 static const struct iwl_ht_params iwl5000_ht_params = {
@@ -159,7 +156,6 @@ const struct iwl_cfg iwl5350_agn_cfg = {
 	.nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION,	\
 	.base_params = &iwl5000_base_params,			\
 	.eeprom_params = &iwl5000_eeprom_params,		\
-	.no_xtal_calib = true,					\
 	.led_mode = IWL_LED_BLINK,				\
 	.internal_wimax_coex = true
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-6000.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-6000.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-6000.c	2013-07-01 10:38:50.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-6000.c	2013-08-31 17:58:33.000000000 -0400
@@ -82,10 +82,6 @@ static const struct iwl_base_params iwl6
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
 	.led_compensation = 51,
-	.adv_thermal_throttle = true,
-	.support_ct_kill_exit = true,
-	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
-	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_DEF_WD_TIMEOUT,
 	.max_event_log_size = 512,
 	.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -98,10 +94,6 @@ static const struct iwl_base_params iwl6
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
 	.shadow_ram_support = true,
 	.led_compensation = 51,
-	.adv_thermal_throttle = true,
-	.support_ct_kill_exit = true,
-	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
-	.chain_noise_scale = 1500,
 	.wd_timeout = IWL_DEF_WD_TIMEOUT,
 	.max_event_log_size = 1024,
 	.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -114,10 +106,6 @@ static const struct iwl_base_params iwl6
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
 	.led_compensation = 57,
-	.adv_thermal_throttle = true,
-	.support_ct_kill_exit = true,
-	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
-	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_LONG_WD_TIMEOUT,
 	.max_event_log_size = 512,
 	.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -129,15 +117,6 @@ static const struct iwl_ht_params iwl600
 	.ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
 };
 
-static const struct iwl_bt_params iwl6000_bt_params = {
-	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
-	.advanced_bt_coexist = true,
-	.agg_time_limit = BT_AGG_THRESHOLD_DEF,
-	.bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
-	.bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
-	.bt_sco_disable = true,
-};
-
 static const struct iwl_eeprom_params iwl6000_eeprom_params = {
 	.regulatory_bands = {
 		EEPROM_REG_BAND_1_CHANNELS,
@@ -163,7 +142,6 @@ static const struct iwl_eeprom_params iw
 	.nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION,	\
 	.base_params = &iwl6000_g2_base_params,			\
 	.eeprom_params = &iwl6000_eeprom_params,		\
-	.need_temp_offset_calib = true,				\
 	.led_mode = IWL_LED_RF_STATE
 
 const struct iwl_cfg iwl6005_2agn_cfg = {
@@ -217,11 +195,8 @@ const struct iwl_cfg iwl6005_2agn_mow2_c
 	.nvm_ver = EEPROM_6030_EEPROM_VERSION,		\
 	.nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION,	\
 	.base_params = &iwl6000_g2_base_params,			\
-	.bt_params = &iwl6000_bt_params,			\
 	.eeprom_params = &iwl6000_eeprom_params,		\
-	.need_temp_offset_calib = true,				\
-	.led_mode = IWL_LED_RF_STATE,				\
-	.adv_pm = true						\
+	.led_mode = IWL_LED_RF_STATE
 
 const struct iwl_cfg iwl6030_2agn_cfg = {
 	.name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
@@ -256,11 +231,8 @@ const struct iwl_cfg iwl6030_2bg_cfg = {
 	.nvm_ver = EEPROM_6030_EEPROM_VERSION,		\
 	.nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION,	\
 	.base_params = &iwl6000_g2_base_params,			\
-	.bt_params = &iwl6000_bt_params,			\
 	.eeprom_params = &iwl6000_eeprom_params,		\
-	.need_temp_offset_calib = true,				\
-	.led_mode = IWL_LED_RF_STATE,				\
-	.adv_pm = true
+	.led_mode = IWL_LED_RF_STATE
 
 const struct iwl_cfg iwl6035_2agn_cfg = {
 	.name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-7000.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-7000.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-7000.c	2013-07-01 10:38:52.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-7000.c	2013-08-31 17:58:34.000000000 -0400
@@ -67,16 +67,16 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL7260_UCODE_API_MAX	6
-#define IWL3160_UCODE_API_MAX	6
+#define IWL7260_UCODE_API_MAX	7
+#define IWL3160_UCODE_API_MAX	7
 
 /* Oldest version we won't warn about */
-#define IWL7260_UCODE_API_OK	6
-#define IWL3160_UCODE_API_OK	6
+#define IWL7260_UCODE_API_OK	7
+#define IWL3160_UCODE_API_OK	7
 
 /* Lowest firmware API version supported */
-#define IWL7260_UCODE_API_MIN	6
-#define IWL3160_UCODE_API_MIN	6
+#define IWL7260_UCODE_API_MIN	7
+#define IWL3160_UCODE_API_MIN	7
 
 /* NVM versions */
 #define IWL7260_NVM_VERSION		0x0a1d
@@ -96,13 +96,9 @@ static const struct iwl_base_params iwl7
 	.pll_cfg_val = 0,
 	.shadow_ram_support = true,
 	.led_compensation = 57,
-	.adv_thermal_throttle = true,
-	.support_ct_kill_exit = true,
-	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
-	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_LONG_WD_TIMEOUT,
 	.max_event_log_size = 512,
-	.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
+	.shadow_reg_enable = true,
 };
 
 static const struct iwl_ht_params iwl7000_ht_params = {
@@ -118,14 +114,11 @@ static const struct iwl_ht_params iwl700
 	.max_inst_size = IWL60_RTC_INST_SIZE,			\
 	.max_data_size = IWL60_RTC_DATA_SIZE,			\
 	.base_params = &iwl7000_base_params,			\
-	/* TODO: .bt_params? */					\
-	.need_temp_offset_calib = true,				\
-	.led_mode = IWL_LED_RF_STATE,				\
-	.adv_pm = true						\
+	.led_mode = IWL_LED_RF_STATE
 
 
 const struct iwl_cfg iwl7260_2ac_cfg = {
-	.name = "Intel(R) Dual Band Wireless AC7260",
+	.name = "Intel(R) Dual Band Wireless AC 7260",
 	.fw_name_pre = IWL7260_FW_PRE,
 	IWL_DEVICE_7000,
 	.ht_params = &iwl7000_ht_params,
@@ -133,8 +126,44 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
 	.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
 };
 
-const struct iwl_cfg iwl3160_ac_cfg = {
-	.name = "Intel(R) Dual Band Wireless AC3160",
+const struct iwl_cfg iwl7260_2n_cfg = {
+	.name = "Intel(R) Dual Band Wireless N 7260",
+	.fw_name_pre = IWL7260_FW_PRE,
+	IWL_DEVICE_7000,
+	.ht_params = &iwl7000_ht_params,
+	.nvm_ver = IWL7260_NVM_VERSION,
+	.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
+};
+
+const struct iwl_cfg iwl7260_n_cfg = {
+	.name = "Intel(R) Wireless N 7260",
+	.fw_name_pre = IWL7260_FW_PRE,
+	IWL_DEVICE_7000,
+	.ht_params = &iwl7000_ht_params,
+	.nvm_ver = IWL7260_NVM_VERSION,
+	.nvm_calib_ver = IWL7260_TX_POWER_VERSION,
+};
+
+const struct iwl_cfg iwl3160_2ac_cfg = {
+	.name = "Intel(R) Dual Band Wireless AC 3160",
+	.fw_name_pre = IWL3160_FW_PRE,
+	IWL_DEVICE_7000,
+	.ht_params = &iwl7000_ht_params,
+	.nvm_ver = IWL3160_NVM_VERSION,
+	.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
+};
+
+const struct iwl_cfg iwl3160_2n_cfg = {
+	.name = "Intel(R) Dual Band Wireless N 3160",
+	.fw_name_pre = IWL3160_FW_PRE,
+	IWL_DEVICE_7000,
+	.ht_params = &iwl7000_ht_params,
+	.nvm_ver = IWL3160_NVM_VERSION,
+	.nvm_calib_ver = IWL3160_TX_POWER_VERSION,
+};
+
+const struct iwl_cfg iwl3160_n_cfg = {
+	.name = "Intel(R) Wireless N 3160",
 	.fw_name_pre = IWL3160_FW_PRE,
 	IWL_DEVICE_7000,
 	.ht_params = &iwl7000_ht_params,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-config.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-config.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-config.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-config.h	2013-08-25 20:43:22.000000000 -0400
@@ -136,17 +136,9 @@ enum iwl_led_mode {
  * @led_compensation: compensate on the led on/off time per HW according
  *	to the deviation to achieve the desired led frequency.
  *	The detail algorithm is described in iwl-led.c
- * @chain_noise_num_beacons: number of beacons used to compute chain noise
- * @adv_thermal_throttle: support advance thermal throttle
- * @support_ct_kill_exit: support ct kill exit condition
- * @plcp_delta_threshold: plcp error rate threshold used to trigger
- *	radio tuning when there is a high receiving plcp error rate
- * @chain_noise_scale: default chain noise scale used for gain computation
  * @wd_timeout: TX queues watchdog timeout
  * @max_event_log_size: size of event log buffer size for ucode event logging
  * @shadow_reg_enable: HW shadow register support
- * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
- * @no_idle_support: do not support idle mode
  */
 struct iwl_base_params {
 	int eeprom_size;
@@ -157,31 +149,9 @@ struct iwl_base_params {
 	const u16 max_ll_items;
 	const bool shadow_ram_support;
 	u16 led_compensation;
-	bool adv_thermal_throttle;
-	bool support_ct_kill_exit;
-	u8 plcp_delta_threshold;
-	s32 chain_noise_scale;
 	unsigned int wd_timeout;
 	u32 max_event_log_size;
 	const bool shadow_reg_enable;
-	const bool hd_v2;
-	const bool no_idle_support;
-};
-
-/*
- * @advanced_bt_coexist: support advanced bt coexist
- * @bt_init_traffic_load: specify initial bt traffic load
- * @bt_prio_boost: default bt priority boost value
- * @agg_time_limit: maximum number of uSec in aggregation
- * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
- */
-struct iwl_bt_params {
-	bool advanced_bt_coexist;
-	u8 bt_init_traffic_load;
-	u32 bt_prio_boost;
-	u16 agg_time_limit;
-	bool bt_sco_disable;
-	bool bt_session_2;
 };
 
 /*
@@ -231,16 +201,10 @@ struct iwl_eeprom_params {
  * @nvm_calib_ver: NVM calibration version
  * @lib: pointer to the lib ops
  * @base_params: pointer to basic parameters
- * @ht_params: point to ht patameters
- * @bt_params: pointer to bt parameters
- * @need_temp_offset_calib: need to perform temperature offset calibration
- * @no_xtal_calib: some devices do not need crystal calibration data,
- *	don't send it to those
+ * @ht_params: point to ht parameters
  * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
- * @adv_pm: advance power management
  * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
  * @internal_wimax_coex: internal wifi/wimax combo device
- * @temp_offset_v2: support v2 of temperature offset calibration
  *
  * We enable the driver to be backward compatible wrt. hardware features.
  * API differences in uCode shouldn't be handled here but through TLVs
@@ -258,26 +222,23 @@ struct iwl_cfg {
 	const u32 max_inst_size;
 	u8   valid_tx_ant;
 	u8   valid_rx_ant;
+	bool bt_shared_single_ant;
 	u16  nvm_ver;
 	u16  nvm_calib_ver;
 	/* params not likely to change within a device family */
 	const struct iwl_base_params *base_params;
 	/* params likely to change within a device family */
 	const struct iwl_ht_params *ht_params;
-	const struct iwl_bt_params *bt_params;
 	const struct iwl_eeprom_params *eeprom_params;
-	const bool need_temp_offset_calib; /* if used set to true */
-	const bool no_xtal_calib;
 	enum iwl_led_mode led_mode;
-	const bool adv_pm;
 	const bool rx_with_siso_diversity;
 	const bool internal_wimax_coex;
-	const bool temp_offset_v2;
 };
 
 /*
  * This list declares the config structures for all devices.
  */
+#if IS_ENABLED(CONFIG_IWLDVM)
 extern const struct iwl_cfg iwl5300_agn_cfg;
 extern const struct iwl_cfg iwl5100_agn_cfg;
 extern const struct iwl_cfg iwl5350_agn_cfg;
@@ -319,7 +280,14 @@ extern const struct iwl_cfg iwl6035_2agn
 extern const struct iwl_cfg iwl105_bgn_cfg;
 extern const struct iwl_cfg iwl105_bgn_d_cfg;
 extern const struct iwl_cfg iwl135_bgn_cfg;
+#endif /* CONFIG_IWLDVM */
+#if IS_ENABLED(CONFIG_IWLMVM)
 extern const struct iwl_cfg iwl7260_2ac_cfg;
-extern const struct iwl_cfg iwl3160_ac_cfg;
+extern const struct iwl_cfg iwl7260_2n_cfg;
+extern const struct iwl_cfg iwl7260_n_cfg;
+extern const struct iwl_cfg iwl3160_2ac_cfg;
+extern const struct iwl_cfg iwl3160_2n_cfg;
+extern const struct iwl_cfg iwl3160_n_cfg;
+#endif /* CONFIG_IWLMVM */
 
 #endif /* __IWL_CONFIG_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-csr.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-csr.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-csr.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-csr.h	2013-08-25 20:43:22.000000000 -0400
@@ -472,4 +472,23 @@
 #define IWL_HOST_INT_CALIB_TIMEOUT_DEF	(0x10)
 #define IWL_HOST_INT_CALIB_TIMEOUT_MIN	(0x0)
 
+/*****************************************************************************
+ *                        7000/3000 series SHR DTS addresses                 *
+ *****************************************************************************/
+
+/* Diode Results Register Structure: */
+enum dtd_diode_reg {
+	DTS_DIODE_REG_DIG_VAL			= 0x000000FF, /* bits [7:0] */
+	DTS_DIODE_REG_VREF_LOW			= 0x0000FF00, /* bits [15:8] */
+	DTS_DIODE_REG_VREF_HIGH			= 0x00FF0000, /* bits [23:16] */
+	DTS_DIODE_REG_VREF_ID			= 0x03000000, /* bits [25:24] */
+	DTS_DIODE_REG_PASS_ONCE			= 0x80000000, /* bits [31:31] */
+	DTS_DIODE_REG_FLAGS_MSK			= 0xFF000000, /* bits [31:24] */
+/* Those are the masks INSIDE the flags bit-field: */
+	DTS_DIODE_REG_FLAGS_VREFS_ID_POS	= 0,
+	DTS_DIODE_REG_FLAGS_VREFS_ID		= 0x00000003, /* bits [1:0] */
+	DTS_DIODE_REG_FLAGS_PASS_ONCE_POS	= 7,
+	DTS_DIODE_REG_FLAGS_PASS_ONCE		= 0x00000080, /* bits [7:7] */
+};
+
 #endif /* !__iwl_csr_h__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-debug.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-debug.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-debug.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-debug.h	2013-08-25 20:43:22.000000000 -0400
@@ -34,7 +34,11 @@
 
 static inline bool iwl_have_debug_level(u32 level)
 {
+#ifdef CONFIG_IWLWIFI_DEBUG
 	return iwlwifi_mod_params.debug_level & level;
+#else
+	return false;
+#endif
 }
 
 void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-drv.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-drv.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-drv.c	2013-07-01 10:38:46.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-drv.c	2013-08-31 17:58:29.000000000 -0400
@@ -1111,11 +1111,8 @@ void iwl_drv_stop(struct iwl_drv *drv)
 /* shared module parameters */
 struct iwl_mod_params iwlwifi_mod_params = {
 	.restart_fw = true,
-	.plcp_check = true,
 	.bt_coex_active = true,
 	.power_level = IWL_POWER_INDEX_1,
-	.bt_ch_announce = true,
-	.auto_agg = true,
 	.wd_disable = true,
 	/* the rest are 0 by default */
 };
@@ -1223,19 +1220,14 @@ module_param_named(antenna_coupling, iwl
 MODULE_PARM_DESC(antenna_coupling,
 		 "specify antenna coupling in dB (defualt: 0 dB)");
 
-module_param_named(bt_ch_inhibition, iwlwifi_mod_params.bt_ch_announce,
-		   bool, S_IRUGO);
-MODULE_PARM_DESC(bt_ch_inhibition,
-		 "Enable BT channel inhibition (default: enable)");
-
-module_param_named(plcp_check, iwlwifi_mod_params.plcp_check, bool, S_IRUGO);
-MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
-
 module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
 MODULE_PARM_DESC(wd_disable,
 		"Disable stuck queue watchdog timer 0=system default, "
 		"1=disable, 2=enable (default: 0)");
 
+module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
+MODULE_PARM_DESC(nvm_file, "NVM file name");
+
 /*
  * set bt_coex_active to true, uCode will do kill/defer
  * every time the priority line is asserted (BT is sending signals on the
@@ -1269,8 +1261,3 @@ module_param_named(power_level, iwlwifi_
 		int, S_IRUGO);
 MODULE_PARM_DESC(power_level,
 		 "default power save level (range from 1 - 5, default: 1)");
-
-module_param_named(auto_agg, iwlwifi_mod_params.auto_agg,
-		bool, S_IRUGO);
-MODULE_PARM_DESC(auto_agg,
-		 "enable agg w/o check traffic load (default: enable)");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-drv.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-drv.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -62,8 +62,7 @@
 
 #ifndef __iwl_drv_h__
 #define __iwl_drv_h__
-
-#include <linux/module.h>
+#include <linux/export.h>
 
 /* for all modules */
 #define DRV_NAME        "iwlwifi"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c	2013-08-25 20:43:22.000000000 -0400
@@ -732,17 +732,16 @@ int iwl_init_sband_channels(struct iwl_n
 void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
 			  struct iwl_nvm_data *data,
 			  struct ieee80211_sta_ht_cap *ht_info,
-			  enum ieee80211_band band)
+			  enum ieee80211_band band,
+			  u8 tx_chains, u8 rx_chains)
 {
 	int max_bit_rate = 0;
-	u8 rx_chains;
-	u8 tx_chains;
 
-	tx_chains = hweight8(data->valid_tx_ant);
+	tx_chains = hweight8(tx_chains);
 	if (cfg->rx_with_siso_diversity)
 		rx_chains = 1;
 	else
-		rx_chains = hweight8(data->valid_rx_ant);
+		rx_chains = hweight8(rx_chains);
 
 	if (!(data->sku_cap_11n_enable) || !cfg->ht_params) {
 		ht_info->ht_supported = false;
@@ -806,7 +805,8 @@ static void iwl_init_sbands(struct devic
 	sband->n_bitrates = N_RATES_24;
 	n_used += iwl_init_sband_channels(data, sband, n_channels,
 					  IEEE80211_BAND_2GHZ);
-	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ);
+	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
+			     data->valid_tx_ant, data->valid_rx_ant);
 
 	sband = &data->bands[IEEE80211_BAND_5GHZ];
 	sband->band = IEEE80211_BAND_5GHZ;
@@ -814,7 +814,8 @@ static void iwl_init_sbands(struct devic
 	sband->n_bitrates = N_RATES_52;
 	n_used += iwl_init_sband_channels(data, sband, n_channels,
 					  IEEE80211_BAND_5GHZ);
-	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);
+	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
+			     data->valid_tx_ant, data->valid_rx_ant);
 
 	if (n_channels != n_used)
 		IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h	2013-08-25 20:43:22.000000000 -0400
@@ -133,6 +133,7 @@ int iwl_init_sband_channels(struct iwl_n
 void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
 			  struct iwl_nvm_data *data,
 			  struct ieee80211_sta_ht_cap *ht_info,
-			  enum ieee80211_band band);
+			  enum ieee80211_band band,
+			  u8 tx_chains, u8 rx_chains);
 
 #endif /* __iwl_eeprom_parse_h__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-fw.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-fw.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-fw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-fw.h	2013-08-25 20:43:22.000000000 -0400
@@ -106,11 +106,14 @@ enum iwl_ucode_type {
 
 /*
  * enumeration of ucode section.
- * This enumeration is used for legacy tlv style (before 16.0 uCode).
+ * This enumeration is used directly for older firmware (before 16.0).
+ * For new firmware, there can be up to 4 sections (see below) but the
+ * first one packaged into the firmware file is the DATA section and
+ * some debugging code accesses that.
  */
 enum iwl_ucode_sec {
-	IWL_UCODE_SECTION_INST,
 	IWL_UCODE_SECTION_DATA,
+	IWL_UCODE_SECTION_INST,
 };
 /*
  * For 16.0 uCode and above, there is no differentiation between sections,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-modparams.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-modparams.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-modparams.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-modparams.h	2013-08-25 20:43:22.000000000 -0400
@@ -93,7 +93,6 @@ enum iwl_power_level {
  *	use IWL_DISABLE_HT_* constants
  * @amsdu_size_8K: enable 8K amsdu size, default = 0
  * @restart_fw: restart firmware, default = 1
- * @plcp_check: enable plcp health check, default = true
  * @wd_disable: enable stuck queue check, default = 0
  * @bt_coex_active: enable bt coex, default = true
  * @led_mode: system default, default = 0
@@ -101,24 +100,22 @@ enum iwl_power_level {
  * @power_level: power level, default = 1
  * @debug_level: levels are IWL_DL_*
  * @ant_coupling: antenna coupling in dB, default = 0
- * @bt_ch_announce: BT channel inhibition, default = enable
- * @auto_agg: enable agg. without check, default = true
  */
 struct iwl_mod_params {
 	int sw_crypto;
 	unsigned int disable_11n;
 	int amsdu_size_8K;
 	bool restart_fw;
-	bool plcp_check;
 	int  wd_disable;
 	bool bt_coex_active;
 	int led_mode;
 	bool power_save;
 	int power_level;
+#ifdef CONFIG_IWLWIFI_DEBUG
 	u32 debug_level;
+#endif
 	int ant_coupling;
-	bool bt_ch_announce;
-	bool auto_agg;
+	char *nvm_file;
 };
 
 #endif /* #__iwl_modparams_h__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c	2013-08-25 20:43:22.000000000 -0400
@@ -89,6 +89,7 @@ enum nvm_sku_bits {
 	NVM_SKU_CAP_BAND_24GHZ	= BIT(0),
 	NVM_SKU_CAP_BAND_52GHZ	= BIT(1),
 	NVM_SKU_CAP_11N_ENABLE	= BIT(2),
+	NVM_SKU_CAP_11AC_ENABLE	= BIT(3),
 };
 
 /* radio config bits (actual values from NVM definition) */
@@ -258,8 +259,6 @@ static void iwl_init_vht_hw_capab(const
 				  struct iwl_nvm_data *data,
 				  struct ieee80211_sta_vht_cap *vht_cap)
 {
-	/* For now, assume new devices with NVM are VHT capable */
-
 	vht_cap->vht_supported = true;
 
 	vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
@@ -292,7 +291,8 @@ static void iwl_init_vht_hw_capab(const
 }
 
 static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
-			    struct iwl_nvm_data *data, const __le16 *nvm_sw)
+			    struct iwl_nvm_data *data, const __le16 *nvm_sw,
+			    bool enable_vht, u8 tx_chains, u8 rx_chains)
 {
 	int n_channels = iwl_init_channel_map(dev, cfg, data,
 			&nvm_sw[NVM_CHANNELS]);
@@ -305,7 +305,8 @@ static void iwl_init_sbands(struct devic
 	sband->n_bitrates = N_RATES_24;
 	n_used += iwl_init_sband_channels(data, sband, n_channels,
 					  IEEE80211_BAND_2GHZ);
-	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ);
+	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
+			     tx_chains, rx_chains);
 
 	sband = &data->bands[IEEE80211_BAND_5GHZ];
 	sband->band = IEEE80211_BAND_5GHZ;
@@ -313,8 +314,10 @@ static void iwl_init_sbands(struct devic
 	sband->n_bitrates = N_RATES_52;
 	n_used += iwl_init_sband_channels(data, sband, n_channels,
 					  IEEE80211_BAND_5GHZ);
-	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);
-	iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
+	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
+			     tx_chains, rx_chains);
+	if (enable_vht)
+		iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
 
 	if (n_channels != n_used)
 		IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
@@ -324,7 +327,7 @@ static void iwl_init_sbands(struct devic
 struct iwl_nvm_data *
 iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
 		   const __le16 *nvm_hw, const __le16 *nvm_sw,
-		   const __le16 *nvm_calib)
+		   const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains)
 {
 	struct iwl_nvm_data *data;
 	u8 hw_addr[ETH_ALEN];
@@ -380,7 +383,8 @@ iwl_parse_nvm_data(struct device *dev, c
 	data->hw_addr[4] = hw_addr[5];
 	data->hw_addr[5] = hw_addr[4];
 
-	iwl_init_sbands(dev, cfg, data, nvm_sw);
+	iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE,
+			tx_chains, rx_chains);
 
 	data->calib_version = 255;   /* TODO:
 					this value will prevent some checks from
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h	2013-08-25 20:43:22.000000000 -0400
@@ -75,6 +75,6 @@
 struct iwl_nvm_data *
 iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
 		   const __le16 *nvm_hw, const __le16 *nvm_sw,
-		   const __le16 *nvm_calib);
+		   const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains);
 
 #endif /* __iwl_nvm_parse_h__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-phy-db.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-phy-db.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-phy-db.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-phy-db.c	2013-08-25 20:43:22.000000000 -0400
@@ -92,20 +92,16 @@ struct iwl_phy_db_entry {
 struct iwl_phy_db {
 	struct iwl_phy_db_entry	cfg;
 	struct iwl_phy_db_entry	calib_nch;
-	struct iwl_phy_db_entry	calib_ch;
 	struct iwl_phy_db_entry	calib_ch_group_papd[IWL_NUM_PAPD_CH_GROUPS];
 	struct iwl_phy_db_entry	calib_ch_group_txp[IWL_NUM_TXP_CH_GROUPS];
 
-	u32 channel_num;
-	u32 channel_size;
-
 	struct iwl_trans *trans;
 };
 
 enum iwl_phy_db_section_type {
 	IWL_PHY_DB_CFG = 1,
 	IWL_PHY_DB_CALIB_NCH,
-	IWL_PHY_DB_CALIB_CH,
+	IWL_PHY_DB_UNUSED,
 	IWL_PHY_DB_CALIB_CHG_PAPD,
 	IWL_PHY_DB_CALIB_CHG_TXP,
 	IWL_PHY_DB_MAX
@@ -169,8 +165,6 @@ iwl_phy_db_get_section(struct iwl_phy_db
 		return &phy_db->cfg;
 	case IWL_PHY_DB_CALIB_NCH:
 		return &phy_db->calib_nch;
-	case IWL_PHY_DB_CALIB_CH:
-		return &phy_db->calib_ch;
 	case IWL_PHY_DB_CALIB_CHG_PAPD:
 		if (chg_id >= IWL_NUM_PAPD_CH_GROUPS)
 			return NULL;
@@ -208,7 +202,6 @@ void iwl_phy_db_free(struct iwl_phy_db *
 
 	iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CFG, 0);
 	iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_NCH, 0);
-	iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CH, 0);
 	for (i = 0; i < IWL_NUM_PAPD_CH_GROUPS; i++)
 		iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_PAPD, i);
 	for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++)
@@ -248,13 +241,6 @@ int iwl_phy_db_set_section(struct iwl_ph
 
 	entry->size = size;
 
-	if (type == IWL_PHY_DB_CALIB_CH) {
-		phy_db->channel_num =
-			le32_to_cpup((__le32 *)phy_db_notif->data);
-		phy_db->channel_size =
-			(size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
-	}
-
 	IWL_DEBUG_INFO(phy_db->trans,
 		       "%s(%d): [PHYDB]SET: Type %d , Size: %d\n",
 		       __func__, __LINE__, type, size);
@@ -328,10 +314,7 @@ int iwl_phy_db_get_section_data(struct i
 				u32 type, u8 **data, u16 *size, u16 ch_id)
 {
 	struct iwl_phy_db_entry *entry;
-	u32 channel_num;
-	u32 channel_size;
 	u16 ch_group_id = 0;
-	u16 index;
 
 	if (!phy_db)
 		return -EINVAL;
@@ -346,21 +329,8 @@ int iwl_phy_db_get_section_data(struct i
 	if (!entry)
 		return -EINVAL;
 
-	if (type == IWL_PHY_DB_CALIB_CH) {
-		index = ch_id_to_ch_index(ch_id);
-		channel_num = phy_db->channel_num;
-		channel_size = phy_db->channel_size;
-		if (index >= channel_num) {
-			IWL_ERR(phy_db->trans, "Wrong channel number %d\n",
-				ch_id);
-			return -EINVAL;
-		}
-		*data = entry->data + CHANNEL_NUM_SIZE + index * channel_size;
-		*size = channel_size;
-	} else {
-		*data = entry->data;
-		*size = entry->size;
-	}
+	*data = entry->data;
+	*size = entry->size;
 
 	IWL_DEBUG_INFO(phy_db->trans,
 		       "%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
@@ -413,6 +383,9 @@ static int iwl_phy_db_send_all_channel_g
 		if (!entry)
 			return -EINVAL;
 
+		if (WARN_ON_ONCE(!entry->size))
+			continue;
+
 		/* Send the requested PHY DB section */
 		err = iwl_send_phy_db_cmd(phy_db,
 					  type,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-prph.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-prph.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-prph.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-prph.h	2013-08-25 20:43:22.000000000 -0400
@@ -100,6 +100,18 @@
 /* Device system time */
 #define DEVICE_SYSTEM_TIME_REG 0xA0206C
 
+/*****************************************************************************
+ *                        7000/3000 series SHR DTS addresses                 *
+ *****************************************************************************/
+
+#define SHR_MISC_WFM_DTS_EN	(0x00a10024)
+#define DTSC_CFG_MODE		(0x00a10604)
+#define DTSC_VREF_AVG		(0x00a10648)
+#define DTSC_VREF5_AVG		(0x00a1064c)
+#define DTSC_CFG_MODE_PERIODIC	(0x2)
+#define DTSC_PTAT_AVG		(0x00a10650)
+
+
 /**
  * Tx Scheduler
  *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-test.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-test.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-test.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-test.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,852 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called COPYING.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-
-#include <linux/export.h>
-#include <net/netlink.h>
-
-#include "iwl-drv.h"
-#include "iwl-io.h"
-#include "iwl-fh.h"
-#include "iwl-prph.h"
-#include "iwl-trans.h"
-#include "iwl-test.h"
-#include "iwl-csr.h"
-#include "iwl-testmode.h"
-
-/*
- * Periphery registers absolute lower bound. This is used in order to
- * differentiate registery access through HBUS_TARG_PRPH_* and
- * HBUS_TARG_MEM_* accesses.
- */
-#define IWL_ABS_PRPH_START (0xA00000)
-
-/*
- * The TLVs used in the gnl message policy between the kernel module and
- * user space application. iwl_testmode_gnl_msg_policy is to be carried
- * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
- * See iwl-testmode.h
- */
-static
-struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
-	[IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
-
-	[IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
-	[IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
-
-	[IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
-	[IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
-	[IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
-
-	[IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
-	[IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
-
-	[IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, },
-
-	[IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
-	[IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, },
-	[IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, },
-
-	[IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
-
-	[IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
-
-	[IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, },
-	[IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, },
-	[IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, },
-
-	[IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
-	[IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
-	[IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
-	[IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
-	[IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
-
-	[IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, },
-};
-
-static inline void iwl_test_trace_clear(struct iwl_test *tst)
-{
-	memset(&tst->trace, 0, sizeof(struct iwl_test_trace));
-}
-
-static void iwl_test_trace_stop(struct iwl_test *tst)
-{
-	if (!tst->trace.enabled)
-		return;
-
-	if (tst->trace.cpu_addr && tst->trace.dma_addr)
-		dma_free_coherent(tst->trans->dev,
-				  tst->trace.tsize,
-				  tst->trace.cpu_addr,
-				  tst->trace.dma_addr);
-
-	iwl_test_trace_clear(tst);
-}
-
-static inline void iwl_test_mem_clear(struct iwl_test *tst)
-{
-	memset(&tst->mem, 0, sizeof(struct iwl_test_mem));
-}
-
-static inline void iwl_test_mem_stop(struct iwl_test *tst)
-{
-	if (!tst->mem.in_read)
-		return;
-
-	iwl_test_mem_clear(tst);
-}
-
-/*
- * Initializes the test object
- * During the lifetime of the test object it is assumed that the transport is
- * started. The test object should be stopped before the transport is stopped.
- */
-void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans,
-		   struct iwl_test_ops *ops)
-{
-	tst->trans = trans;
-	tst->ops = ops;
-
-	iwl_test_trace_clear(tst);
-	iwl_test_mem_clear(tst);
-}
-EXPORT_SYMBOL_GPL(iwl_test_init);
-
-/*
- * Stop the test object
- */
-void iwl_test_free(struct iwl_test *tst)
-{
-	iwl_test_mem_stop(tst);
-	iwl_test_trace_stop(tst);
-}
-EXPORT_SYMBOL_GPL(iwl_test_free);
-
-static inline int iwl_test_send_cmd(struct iwl_test *tst,
-				    struct iwl_host_cmd *cmd)
-{
-	return tst->ops->send_cmd(tst->trans->op_mode, cmd);
-}
-
-static inline bool iwl_test_valid_hw_addr(struct iwl_test *tst, u32 addr)
-{
-	return tst->ops->valid_hw_addr(addr);
-}
-
-static inline u32 iwl_test_fw_ver(struct iwl_test *tst)
-{
-	return tst->ops->get_fw_ver(tst->trans->op_mode);
-}
-
-static inline struct sk_buff*
-iwl_test_alloc_reply(struct iwl_test *tst, int len)
-{
-	return tst->ops->alloc_reply(tst->trans->op_mode, len);
-}
-
-static inline int iwl_test_reply(struct iwl_test *tst, struct sk_buff *skb)
-{
-	return tst->ops->reply(tst->trans->op_mode, skb);
-}
-
-static inline struct sk_buff*
-iwl_test_alloc_event(struct iwl_test *tst, int len)
-{
-	return tst->ops->alloc_event(tst->trans->op_mode, len);
-}
-
-static inline void
-iwl_test_event(struct iwl_test *tst, struct sk_buff *skb)
-{
-	return tst->ops->event(tst->trans->op_mode, skb);
-}
-
-/*
- * This function handles the user application commands to the fw. The fw
- * commands are sent in a synchronuous manner. In case that the user requested
- * to get commands response, it is send to the user.
- */
-static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
-{
-	struct iwl_host_cmd cmd;
-	struct iwl_rx_packet *pkt;
-	struct sk_buff *skb;
-	void *reply_buf;
-	u32 reply_len;
-	int ret;
-	bool cmd_want_skb;
-
-	memset(&cmd, 0, sizeof(struct iwl_host_cmd));
-
-	if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
-	    !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
-		IWL_ERR(tst->trans, "Missing fw command mandatory fields\n");
-		return -ENOMSG;
-	}
-
-	cmd.flags = CMD_ON_DEMAND | CMD_SYNC;
-	cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]);
-	if (cmd_want_skb)
-		cmd.flags |= CMD_WANT_SKB;
-
-	cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
-	cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
-	cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
-	cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
-	IWL_DEBUG_INFO(tst->trans, "test fw cmd=0x%x, flags 0x%x, len %d\n",
-		       cmd.id, cmd.flags, cmd.len[0]);
-
-	ret = iwl_test_send_cmd(tst, &cmd);
-	if (ret) {
-		IWL_ERR(tst->trans, "Failed to send hcmd\n");
-		return ret;
-	}
-	if (!cmd_want_skb)
-		return ret;
-
-	/* Handling return of SKB to the user */
-	pkt = cmd.resp_pkt;
-	if (!pkt) {
-		IWL_ERR(tst->trans, "HCMD received a null response packet\n");
-		return ret;
-	}
-
-	reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
-	skb = iwl_test_alloc_reply(tst, reply_len + 20);
-	reply_buf = kmemdup(&pkt->hdr, reply_len, GFP_KERNEL);
-	if (!skb || !reply_buf) {
-		kfree_skb(skb);
-		kfree(reply_buf);
-		return -ENOMEM;
-	}
-
-	/* The reply is in a page, that we cannot send to user space. */
-	iwl_free_resp(&cmd);
-
-	if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
-			IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
-	    nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf))
-		goto nla_put_failure;
-	return iwl_test_reply(tst, skb);
-
-nla_put_failure:
-	IWL_DEBUG_INFO(tst->trans, "Failed creating NL attributes\n");
-	kfree(reply_buf);
-	kfree_skb(skb);
-	return -ENOMSG;
-}
-
-/*
- * Handles the user application commands for register access.
- */
-static int iwl_test_reg(struct iwl_test *tst, struct nlattr **tb)
-{
-	u32 ofs, val32, cmd;
-	u8 val8;
-	struct sk_buff *skb;
-	int status = 0;
-	struct iwl_trans *trans = tst->trans;
-
-	if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
-		IWL_ERR(trans, "Missing reg offset\n");
-		return -ENOMSG;
-	}
-
-	ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
-	IWL_DEBUG_INFO(trans, "test reg access cmd offset=0x%x\n", ofs);
-
-	cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
-
-	/*
-	 * Allow access only to FH/CSR/HBUS in direct mode.
-	 * Since we don't have the upper bounds for the CSR and HBUS segments,
-	 * we will use only the upper bound of FH for sanity check.
-	 */
-	if (ofs >= FH_MEM_UPPER_BOUND) {
-		IWL_ERR(trans, "offset out of segment (0x0 - 0x%x)\n",
-			FH_MEM_UPPER_BOUND);
-		return -EINVAL;
-	}
-
-	switch (cmd) {
-	case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
-		val32 = iwl_read_direct32(tst->trans, ofs);
-		IWL_DEBUG_INFO(trans, "32 value to read 0x%x\n", val32);
-
-		skb = iwl_test_alloc_reply(tst, 20);
-		if (!skb) {
-			IWL_ERR(trans, "Memory allocation fail\n");
-			return -ENOMEM;
-		}
-		if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32))
-			goto nla_put_failure;
-		status = iwl_test_reply(tst, skb);
-		if (status < 0)
-			IWL_ERR(trans, "Error sending msg : %d\n", status);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
-		if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
-			IWL_ERR(trans, "Missing value to write\n");
-			return -ENOMSG;
-		} else {
-			val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
-			IWL_DEBUG_INFO(trans, "32b write val=0x%x\n", val32);
-			iwl_write_direct32(tst->trans, ofs, val32);
-		}
-		break;
-
-	case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
-		if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
-			IWL_ERR(trans, "Missing value to write\n");
-			return -ENOMSG;
-		} else {
-			val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
-			IWL_DEBUG_INFO(trans, "8b write val=0x%x\n", val8);
-			iwl_write8(tst->trans, ofs, val8);
-		}
-		break;
-
-	default:
-		IWL_ERR(trans, "Unknown test register cmd ID\n");
-		return -ENOMSG;
-	}
-
-	return status;
-
-nla_put_failure:
-	kfree_skb(skb);
-	return -EMSGSIZE;
-}
-
-/*
- * Handles the request to start FW tracing. Allocates of the trace buffer
- * and sends a reply to user space with the address of the allocated buffer.
- */
-static int iwl_test_trace_begin(struct iwl_test *tst, struct nlattr **tb)
-{
-	struct sk_buff *skb;
-	int status = 0;
-
-	if (tst->trace.enabled)
-		return -EBUSY;
-
-	if (!tb[IWL_TM_ATTR_TRACE_SIZE])
-		tst->trace.size = TRACE_BUFF_SIZE_DEF;
-	else
-		tst->trace.size =
-			nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]);
-
-	if (!tst->trace.size)
-		return -EINVAL;
-
-	if (tst->trace.size < TRACE_BUFF_SIZE_MIN ||
-	    tst->trace.size > TRACE_BUFF_SIZE_MAX)
-		return -EINVAL;
-
-	tst->trace.tsize = tst->trace.size + TRACE_BUFF_PADD;
-	tst->trace.cpu_addr = dma_alloc_coherent(tst->trans->dev,
-						 tst->trace.tsize,
-						 &tst->trace.dma_addr,
-						 GFP_KERNEL);
-	if (!tst->trace.cpu_addr)
-		return -ENOMEM;
-
-	tst->trace.enabled = true;
-	tst->trace.trace_addr = (u8 *)PTR_ALIGN(tst->trace.cpu_addr, 0x100);
-
-	memset(tst->trace.trace_addr, 0x03B, tst->trace.size);
-
-	skb = iwl_test_alloc_reply(tst, sizeof(tst->trace.dma_addr) + 20);
-	if (!skb) {
-		IWL_ERR(tst->trans, "Memory allocation fail\n");
-		iwl_test_trace_stop(tst);
-		return -ENOMEM;
-	}
-
-	if (nla_put(skb, IWL_TM_ATTR_TRACE_ADDR,
-		    sizeof(tst->trace.dma_addr),
-		    (u64 *)&tst->trace.dma_addr))
-		goto nla_put_failure;
-
-	status = iwl_test_reply(tst, skb);
-	if (status < 0)
-		IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
-
-	tst->trace.nchunks = DIV_ROUND_UP(tst->trace.size,
-					  DUMP_CHUNK_SIZE);
-
-	return status;
-
-nla_put_failure:
-	kfree_skb(skb);
-	if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
-	    IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
-		iwl_test_trace_stop(tst);
-	return -EMSGSIZE;
-}
-
-/*
- * Handles indirect read from the periphery or the SRAM. The read is performed
- * to a temporary buffer. The user space application should later issue a dump
- */
-static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size)
-{
-	struct iwl_trans *trans = tst->trans;
-	unsigned long flags;
-	int i;
-
-	if (size & 0x3)
-		return -EINVAL;
-
-	tst->mem.size = size;
-	tst->mem.addr = kmalloc(tst->mem.size, GFP_KERNEL);
-	if (tst->mem.addr == NULL)
-		return -ENOMEM;
-
-	/* Hard-coded periphery absolute address */
-	if (IWL_ABS_PRPH_START <= addr &&
-	    addr < IWL_ABS_PRPH_START + PRPH_END) {
-			if (!iwl_trans_grab_nic_access(trans, false, &flags)) {
-				return -EIO;
-			}
-			iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
-				    addr | (3 << 24));
-			for (i = 0; i < size; i += 4)
-				*(u32 *)(tst->mem.addr + i) =
-					iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
-			iwl_trans_release_nic_access(trans, &flags);
-	} else { /* target memory (SRAM) */
-		iwl_trans_read_mem(trans, addr, tst->mem.addr,
-				   tst->mem.size / 4);
-	}
-
-	tst->mem.nchunks =
-		DIV_ROUND_UP(tst->mem.size, DUMP_CHUNK_SIZE);
-	tst->mem.in_read = true;
-	return 0;
-
-}
-
-/*
- * Handles indirect write to the periphery or SRAM. The  is performed to a
- * temporary buffer.
- */
-static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr,
-	u32 size, unsigned char *buf)
-{
-	struct iwl_trans *trans = tst->trans;
-	u32 val, i;
-	unsigned long flags;
-
-	if (IWL_ABS_PRPH_START <= addr &&
-	    addr < IWL_ABS_PRPH_START + PRPH_END) {
-		/* Periphery writes can be 1-3 bytes long, or DWORDs */
-		if (size < 4) {
-			memcpy(&val, buf, size);
-			if (!iwl_trans_grab_nic_access(trans, false, &flags))
-					return -EIO;
-			iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
-				    (addr & 0x0000FFFF) |
-				    ((size - 1) << 24));
-			iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
-			iwl_trans_release_nic_access(trans, &flags);
-		} else {
-			if (size % 4)
-				return -EINVAL;
-			for (i = 0; i < size; i += 4)
-				iwl_write_prph(trans, addr+i,
-					       *(u32 *)(buf+i));
-		}
-	} else if (iwl_test_valid_hw_addr(tst, addr)) {
-		iwl_trans_write_mem(trans, addr, buf, size / 4);
-	} else {
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/*
- * Handles the user application commands for indirect read/write
- * to/from the periphery or the SRAM.
- */
-static int iwl_test_indirect_mem(struct iwl_test *tst, struct nlattr **tb)
-{
-	u32 addr, size, cmd;
-	unsigned char *buf;
-
-	/* Both read and write should be blocked, for atomicity */
-	if (tst->mem.in_read)
-		return -EBUSY;
-
-	cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
-	if (!tb[IWL_TM_ATTR_MEM_ADDR]) {
-		IWL_ERR(tst->trans, "Error finding memory offset address\n");
-		return -ENOMSG;
-	}
-	addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]);
-	if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) {
-		IWL_ERR(tst->trans, "Error finding size for memory reading\n");
-		return -ENOMSG;
-	}
-	size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]);
-
-	if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ) {
-		return iwl_test_indirect_read(tst, addr,  size);
-	} else {
-		if (!tb[IWL_TM_ATTR_BUFFER_DUMP])
-			return -EINVAL;
-		buf = (unsigned char *)nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]);
-		return iwl_test_indirect_write(tst, addr, size, buf);
-	}
-}
-
-/*
- * Enable notifications to user space
- */
-static int iwl_test_notifications(struct iwl_test *tst,
-				  struct nlattr **tb)
-{
-	tst->notify = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]);
-	return 0;
-}
-
-/*
- * Handles the request to get the device id
- */
-static int iwl_test_get_dev_id(struct iwl_test *tst, struct nlattr **tb)
-{
-	u32 devid = tst->trans->hw_id;
-	struct sk_buff *skb;
-	int status;
-
-	IWL_DEBUG_INFO(tst->trans, "hw version: 0x%x\n", devid);
-
-	skb = iwl_test_alloc_reply(tst, 20);
-	if (!skb) {
-		IWL_ERR(tst->trans, "Memory allocation fail\n");
-		return -ENOMEM;
-	}
-
-	if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid))
-		goto nla_put_failure;
-	status = iwl_test_reply(tst, skb);
-	if (status < 0)
-		IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
-
-	return 0;
-
-nla_put_failure:
-	kfree_skb(skb);
-	return -EMSGSIZE;
-}
-
-/*
- * Handles the request to get the FW version
- */
-static int iwl_test_get_fw_ver(struct iwl_test *tst, struct nlattr **tb)
-{
-	struct sk_buff *skb;
-	int status;
-	u32 ver = iwl_test_fw_ver(tst);
-
-	IWL_DEBUG_INFO(tst->trans, "uCode version raw: 0x%x\n", ver);
-
-	skb = iwl_test_alloc_reply(tst, 20);
-	if (!skb) {
-		IWL_ERR(tst->trans, "Memory allocation fail\n");
-		return -ENOMEM;
-	}
-
-	if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION, ver))
-		goto nla_put_failure;
-
-	status = iwl_test_reply(tst, skb);
-	if (status < 0)
-		IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
-
-	return 0;
-
-nla_put_failure:
-	kfree_skb(skb);
-	return -EMSGSIZE;
-}
-
-/*
- * Parse the netlink message and validate that the IWL_TM_ATTR_CMD exists
- */
-int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
-		   void *data, int len)
-{
-	int result;
-
-	result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
-			iwl_testmode_gnl_msg_policy);
-	if (result) {
-		IWL_ERR(tst->trans, "Fail parse gnl msg: %d\n", result);
-		return result;
-	}
-
-	/* IWL_TM_ATTR_COMMAND is absolutely mandatory */
-	if (!tb[IWL_TM_ATTR_COMMAND]) {
-		IWL_ERR(tst->trans, "Missing testmode command type\n");
-		return -ENOMSG;
-	}
-	return 0;
-}
-IWL_EXPORT_SYMBOL(iwl_test_parse);
-
-/*
- * Handle test commands.
- * Returns 1 for unknown commands (not handled by the test object); negative
- * value in case of error.
- */
-int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb)
-{
-	int result;
-
-	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
-	case IWL_TM_CMD_APP2DEV_UCODE:
-		IWL_DEBUG_INFO(tst->trans, "test cmd to uCode\n");
-		result = iwl_test_fw_cmd(tst, tb);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
-	case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
-	case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
-		IWL_DEBUG_INFO(tst->trans, "test cmd to register\n");
-		result = iwl_test_reg(tst, tb);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
-		IWL_DEBUG_INFO(tst->trans, "test uCode trace cmd to driver\n");
-		result = iwl_test_trace_begin(tst, tb);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_END_TRACE:
-		iwl_test_trace_stop(tst);
-		result = 0;
-		break;
-
-	case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
-	case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
-		IWL_DEBUG_INFO(tst->trans, "test indirect memory cmd\n");
-		result = iwl_test_indirect_mem(tst, tb);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
-		IWL_DEBUG_INFO(tst->trans, "test notifications cmd\n");
-		result = iwl_test_notifications(tst, tb);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
-		IWL_DEBUG_INFO(tst->trans, "test get FW ver cmd\n");
-		result = iwl_test_get_fw_ver(tst, tb);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
-		IWL_DEBUG_INFO(tst->trans, "test Get device ID cmd\n");
-		result = iwl_test_get_dev_id(tst, tb);
-		break;
-
-	default:
-		IWL_DEBUG_INFO(tst->trans, "Unknown test command\n");
-		result = 1;
-		break;
-	}
-	return result;
-}
-IWL_EXPORT_SYMBOL(iwl_test_handle_cmd);
-
-static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb,
-			       struct netlink_callback *cb)
-{
-	int idx, length;
-
-	if (!tst->trace.enabled || !tst->trace.trace_addr)
-		return -EFAULT;
-
-	idx = cb->args[4];
-	if (idx >= tst->trace.nchunks)
-		return -ENOENT;
-
-	length = DUMP_CHUNK_SIZE;
-	if (((idx + 1) == tst->trace.nchunks) &&
-	    (tst->trace.size % DUMP_CHUNK_SIZE))
-		length = tst->trace.size %
-			DUMP_CHUNK_SIZE;
-
-	if (nla_put(skb, IWL_TM_ATTR_TRACE_DUMP, length,
-		    tst->trace.trace_addr + (DUMP_CHUNK_SIZE * idx)))
-		goto nla_put_failure;
-
-	cb->args[4] = ++idx;
-	return 0;
-
- nla_put_failure:
-	return -ENOBUFS;
-}
-
-static int iwl_test_buffer_dump(struct iwl_test *tst, struct sk_buff *skb,
-				struct netlink_callback *cb)
-{
-	int idx, length;
-
-	if (!tst->mem.in_read)
-		return -EFAULT;
-
-	idx = cb->args[4];
-	if (idx >= tst->mem.nchunks) {
-		iwl_test_mem_stop(tst);
-		return -ENOENT;
-	}
-
-	length = DUMP_CHUNK_SIZE;
-	if (((idx + 1) == tst->mem.nchunks) &&
-	    (tst->mem.size % DUMP_CHUNK_SIZE))
-		length = tst->mem.size % DUMP_CHUNK_SIZE;
-
-	if (nla_put(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
-		    tst->mem.addr + (DUMP_CHUNK_SIZE * idx)))
-		goto nla_put_failure;
-
-	cb->args[4] = ++idx;
-	return 0;
-
- nla_put_failure:
-	return -ENOBUFS;
-}
-
-/*
- * Handle dump commands.
- * Returns 1 for unknown commands (not handled by the test object); negative
- * value in case of error.
- */
-int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
-		  struct netlink_callback *cb)
-{
-	int result;
-
-	switch (cmd) {
-	case IWL_TM_CMD_APP2DEV_READ_TRACE:
-		IWL_DEBUG_INFO(tst->trans, "uCode trace cmd\n");
-		result = iwl_test_trace_dump(tst, skb, cb);
-		break;
-
-	case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
-		IWL_DEBUG_INFO(tst->trans, "testmode sram dump cmd\n");
-		result = iwl_test_buffer_dump(tst, skb, cb);
-		break;
-
-	default:
-		result = 1;
-		break;
-	}
-	return result;
-}
-IWL_EXPORT_SYMBOL(iwl_test_dump);
-
-/*
- * Multicast a spontaneous messages from the device to the user space.
- */
-static void iwl_test_send_rx(struct iwl_test *tst,
-			     struct iwl_rx_cmd_buffer *rxb)
-{
-	struct sk_buff *skb;
-	struct iwl_rx_packet *data;
-	int length;
-
-	data = rxb_addr(rxb);
-	length = le32_to_cpu(data->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
-
-	/* the length doesn't include len_n_flags field, so add it manually */
-	length += sizeof(__le32);
-
-	skb = iwl_test_alloc_event(tst, length + 20);
-	if (skb == NULL) {
-		IWL_ERR(tst->trans, "Out of memory for message to user\n");
-		return;
-	}
-
-	if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
-			IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
-	    nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data))
-		goto nla_put_failure;
-
-	iwl_test_event(tst, skb);
-	return;
-
-nla_put_failure:
-	kfree_skb(skb);
-	IWL_ERR(tst->trans, "Ouch, overran buffer, check allocation!\n");
-}
-
-/*
- * Called whenever a Rx frames is recevied from the device. If notifications to
- * the user space are requested, sends the frames to the user.
- */
-void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb)
-{
-	if (tst->notify)
-		iwl_test_send_rx(tst, rxb);
-}
-IWL_EXPORT_SYMBOL(iwl_test_rx);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-test.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-test.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-test.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-test.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,161 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called COPYING.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-
-#ifndef __IWL_TEST_H__
-#define __IWL_TEST_H__
-
-#include <linux/types.h>
-#include "iwl-trans.h"
-
-struct iwl_test_trace {
-	u32 size;
-	u32 tsize;
-	u32 nchunks;
-	u8 *cpu_addr;
-	u8 *trace_addr;
-	dma_addr_t dma_addr;
-	bool enabled;
-};
-
-struct iwl_test_mem {
-	u32 size;
-	u32 nchunks;
-	u8 *addr;
-	bool in_read;
-};
-
-/*
- * struct iwl_test_ops: callback to the op mode
- *
- * The structure defines the callbacks that the op_mode should handle,
- * inorder to handle logic that is out of the scope of iwl_test. The
- * op_mode must set all the callbacks.
-
- * @send_cmd: handler that is used by the test object to request the
- *  op_mode to send a command to the fw.
- *
- * @valid_hw_addr: handler that is used by the test object to request the
- *  op_mode to check if the given address is a valid address.
- *
- * @get_fw_ver: handler used to get the FW version.
- *
- * @alloc_reply: handler used by the test object to request the op_mode
- *  to allocate an skb for sending a reply to the user, and initialize
- *  the skb. It is assumed that the test object only fills the required
- *  attributes.
- *
- * @reply: handler used by the test object to request the op_mode to reply
- *  to a request. The skb is an skb previously allocated by the the
- *  alloc_reply callback.
- I
- * @alloc_event: handler used by the test object to request the op_mode
- *  to allocate an skb for sending an event, and initialize
- *  the skb. It is assumed that the test object only fills the required
- *  attributes.
- *
- * @reply: handler used by the test object to request the op_mode to send
- *  an event. The skb is an skb previously allocated by the the
- *  alloc_event callback.
- */
-struct iwl_test_ops {
-	int (*send_cmd)(struct iwl_op_mode *op_modes,
-			struct iwl_host_cmd *cmd);
-	bool (*valid_hw_addr)(u32 addr);
-	u32 (*get_fw_ver)(struct iwl_op_mode *op_mode);
-
-	struct sk_buff *(*alloc_reply)(struct iwl_op_mode *op_mode, int len);
-	int (*reply)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
-	struct sk_buff* (*alloc_event)(struct iwl_op_mode *op_mode, int len);
-	void (*event)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
-};
-
-struct iwl_test {
-	struct iwl_trans *trans;
-	struct iwl_test_ops *ops;
-	struct iwl_test_trace trace;
-	struct iwl_test_mem mem;
-	bool notify;
-};
-
-void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans,
-		   struct iwl_test_ops *ops);
-
-void iwl_test_free(struct iwl_test *tst);
-
-int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
-		   void *data, int len);
-
-int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb);
-
-int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
-		  struct netlink_callback *cb);
-
-void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb);
-
-static inline void iwl_test_enable_notifications(struct iwl_test *tst,
-						 bool enable)
-{
-	tst->notify = enable;
-}
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-testmode.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-testmode.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-testmode.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-testmode.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,309 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called COPYING.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name Intel Corporation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-#ifndef __IWL_TESTMODE_H__
-#define __IWL_TESTMODE_H__
-
-#include <linux/types.h>
-
-
-/*
- * Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and
- * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX).
- * The command ID is carried with IWL_TM_ATTR_COMMAND.
- *
- * @IWL_TM_CMD_APP2DEV_UCODE:
- *	commands from user application to the uCode,
- *	the actual uCode host command ID is carried with
- *	IWL_TM_ATTR_UCODE_CMD_ID
- *
- * @IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
- * @IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
- * @IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
- *	commands from user applicaiton to access register
- *
- * @IWL_TM_CMD_APP2DEV_GET_DEVICENAME: retrieve device name
- * @IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: load initial uCode image
- * @IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: perform calibration
- * @IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: load runtime uCode image
- * @IWL_TM_CMD_APP2DEV_GET_EEPROM: request EEPROM data
- * @IWL_TM_CMD_APP2DEV_FIXRATE_REQ: set fix MCS
- *	commands fom user space for pure driver level operations
- *
- * @IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
- * @IWL_TM_CMD_APP2DEV_END_TRACE:
- * @IWL_TM_CMD_APP2DEV_READ_TRACE:
- *	commands fom user space for uCode trace operations
- *
- * @IWL_TM_CMD_DEV2APP_SYNC_RSP:
- *	commands from kernel space to carry the synchronous response
- *	to user application
- * @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT:
- *	commands from kernel space to multicast the spontaneous messages
- *	to user application, or reply of host commands
- * @IWL_TM_CMD_DEV2APP_EEPROM_RSP:
- *	commands from kernel space to carry the eeprom response
- *	to user application
- *
- * @IWL_TM_CMD_APP2DEV_OWNERSHIP:
- *	commands from user application to own change the ownership of the uCode
- *	if application has the ownership, the only host command from
- *	testmode will deliver to uCode. Default owner is driver
- *
- * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image
- * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version
- * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device
- * @IWL_TM_CMD_APP2DEV_GET_FW_INFO:
- *	retrieve information of existing loaded uCode image
- *
- * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
- * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
- * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
- *	Commands to read/write data from periphery or SRAM memory ranges.
- *	Fore reading, a READ command is sent from the userspace and the data
- *	is returned when the user calls a DUMP command.
- *	For writing, only a WRITE command is used.
- * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
- *	Command to enable/disable notifications (currently RX packets) from the
- *	driver to userspace.
- */
-enum iwl_tm_cmd_t {
-	IWL_TM_CMD_APP2DEV_UCODE		= 1,
-	IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32	= 2,
-	IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32	= 3,
-	IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8	= 4,
-	IWL_TM_CMD_APP2DEV_GET_DEVICENAME	= 5,
-	IWL_TM_CMD_APP2DEV_LOAD_INIT_FW		= 6,
-	IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB	= 7,
-	IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW	= 8,
-	IWL_TM_CMD_APP2DEV_GET_EEPROM		= 9,
-	IWL_TM_CMD_APP2DEV_FIXRATE_REQ		= 10,
-	IWL_TM_CMD_APP2DEV_BEGIN_TRACE		= 11,
-	IWL_TM_CMD_APP2DEV_END_TRACE		= 12,
-	IWL_TM_CMD_APP2DEV_READ_TRACE		= 13,
-	IWL_TM_CMD_DEV2APP_SYNC_RSP		= 14,
-	IWL_TM_CMD_DEV2APP_UCODE_RX_PKT		= 15,
-	IWL_TM_CMD_DEV2APP_EEPROM_RSP		= 16,
-	IWL_TM_CMD_APP2DEV_OWNERSHIP		= 17,
-	RESERVED_18				= 18,
-	RESERVED_19				= 19,
-	RESERVED_20				= 20,
-	RESERVED_21				= 21,
-	IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW	= 22,
-	IWL_TM_CMD_APP2DEV_GET_FW_VERSION	= 23,
-	IWL_TM_CMD_APP2DEV_GET_DEVICE_ID	= 24,
-	IWL_TM_CMD_APP2DEV_GET_FW_INFO		= 25,
-	IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26,
-	IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27,
-	IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28,
-	IWL_TM_CMD_APP2DEV_NOTIFICATIONS	= 29,
-	IWL_TM_CMD_MAX				= 30,
-};
-
-/*
- * Atrribute filed in testmode command
- * See enum iwl_tm_cmd_t.
- *
- * @IWL_TM_ATTR_NOT_APPLICABLE:
- *	The attribute is not applicable or invalid
- * @IWL_TM_ATTR_COMMAND:
- *	From user space to kernel space:
- *	the command either destines to ucode, driver, or register;
- *	From kernel space to user space:
- *	the command either carries synchronous response,
- *	or the spontaneous message multicast from the device;
- *
- * @IWL_TM_ATTR_UCODE_CMD_ID:
- * @IWL_TM_ATTR_UCODE_CMD_DATA:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
- *	The mandatory fields are :
- *	IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
- *	IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
- *	to the ucode
- *
- * @IWL_TM_ATTR_REG_OFFSET:
- * @IWL_TM_ATTR_REG_VALUE8:
- * @IWL_TM_ATTR_REG_VALUE32:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX,
- *	The mandatory fields are:
- *	IWL_TM_ATTR_REG_OFFSET for the offset of the target register;
- *	IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value
- *
- * @IWL_TM_ATTR_SYNC_RSP:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP,
- *	The mandatory fields are:
- *	IWL_TM_ATTR_SYNC_RSP for the data content responding to the user
- *	application command
- *
- * @IWL_TM_ATTR_UCODE_RX_PKT:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
- *	The mandatory fields are:
- *	IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user
- *	application
- *
- * @IWL_TM_ATTR_EEPROM:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM,
- *	The mandatory fields are:
- *	IWL_TM_ATTR_EEPROM for the data content responging to the user
- *	application
- *
- * @IWL_TM_ATTR_TRACE_ADDR:
- * @IWL_TM_ATTR_TRACE_SIZE:
- * @IWL_TM_ATTR_TRACE_DUMP:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE,
- *	The mandatory fields are:
- *	IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address
- *	IWL_TM_ATTR_MEM_TRACE_SIZE for the trace buffer size
- *	IWL_TM_ATTR_MEM_TRACE_DUMP for the trace dump
- *
- * @IWL_TM_ATTR_FIXRATE:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
- *	The mandatory fields are:
- *	IWL_TM_ATTR_FIXRATE for the fixed rate
- *
- * @IWL_TM_ATTR_UCODE_OWNER:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_OWNERSHIP,
- *	The mandatory fields are:
- *	IWL_TM_ATTR_UCODE_OWNER for the new owner
- *
- * @IWL_TM_ATTR_MEM_ADDR:
- * @IWL_TM_ATTR_BUFFER_SIZE:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ
- *	or IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE.
- *	The mandatory fields are:
- *	IWL_TM_ATTR_MEM_ADDR for the address in SRAM/periphery to read/write
- *	IWL_TM_ATTR_BUFFER_SIZE for the buffer size of data to read/write.
- *
- * @IWL_TM_ATTR_BUFFER_DUMP:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP,
- *	IWL_TM_ATTR_BUFFER_DUMP is used for the data that was read.
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE,
- *	this attribute contains the data to write.
- *
- * @IWL_TM_ATTR_FW_VERSION:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_VERSION,
- *	IWL_TM_ATTR_FW_VERSION for the uCode version
- *
- * @IWL_TM_ATTR_DEVICE_ID:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID,
- *	IWL_TM_ATTR_DEVICE_ID for the device ID information
- *
- * @IWL_TM_ATTR_FW_TYPE:
- * @IWL_TM_ATTR_FW_INST_SIZE:
- * @IWL_TM_ATTR_FW_DATA_SIZE:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_INFO,
- *	The mandatory fields are:
- *	IWL_TM_ATTR_FW_TYPE for the uCode type (INIT/RUNTIME/...)
- *	IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section
- *	IWL_TM_ATTR_FW_DATA_SIZE for the size of data section
- *
- * @IWL_TM_ATTR_UCODE_CMD_SKB:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag
- *	indicates that the user wants to receive the response of the command
- *	in a reply SKB. If it's not present, the response is not returned.
- * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS:
- *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this
- *	flag enables (if present) or disables (if not) the forwarding
- *	to userspace.
- */
-enum iwl_tm_attr_t {
-	IWL_TM_ATTR_NOT_APPLICABLE		= 0,
-	IWL_TM_ATTR_COMMAND			= 1,
-	IWL_TM_ATTR_UCODE_CMD_ID		= 2,
-	IWL_TM_ATTR_UCODE_CMD_DATA		= 3,
-	IWL_TM_ATTR_REG_OFFSET			= 4,
-	IWL_TM_ATTR_REG_VALUE8			= 5,
-	IWL_TM_ATTR_REG_VALUE32			= 6,
-	IWL_TM_ATTR_SYNC_RSP			= 7,
-	IWL_TM_ATTR_UCODE_RX_PKT		= 8,
-	IWL_TM_ATTR_EEPROM			= 9,
-	IWL_TM_ATTR_TRACE_ADDR			= 10,
-	IWL_TM_ATTR_TRACE_SIZE			= 11,
-	IWL_TM_ATTR_TRACE_DUMP			= 12,
-	IWL_TM_ATTR_FIXRATE			= 13,
-	IWL_TM_ATTR_UCODE_OWNER			= 14,
-	IWL_TM_ATTR_MEM_ADDR			= 15,
-	IWL_TM_ATTR_BUFFER_SIZE			= 16,
-	IWL_TM_ATTR_BUFFER_DUMP			= 17,
-	IWL_TM_ATTR_FW_VERSION			= 18,
-	IWL_TM_ATTR_DEVICE_ID			= 19,
-	IWL_TM_ATTR_FW_TYPE			= 20,
-	IWL_TM_ATTR_FW_INST_SIZE		= 21,
-	IWL_TM_ATTR_FW_DATA_SIZE		= 22,
-	IWL_TM_ATTR_UCODE_CMD_SKB		= 23,
-	IWL_TM_ATTR_ENABLE_NOTIFICATION		= 24,
-	IWL_TM_ATTR_MAX				= 25,
-};
-
-/* uCode trace buffer */
-#define TRACE_BUFF_SIZE_MAX	0x200000
-#define TRACE_BUFF_SIZE_MIN	0x20000
-#define TRACE_BUFF_SIZE_DEF	TRACE_BUFF_SIZE_MIN
-#define TRACE_BUFF_PADD		0x2000
-
-/* Maximum data size of each dump it packet */
-#define DUMP_CHUNK_SIZE		(PAGE_SIZE - 1024)
-
-/* Address offset of data segment in SRAM */
-#define SRAM_DATA_SEG_OFFSET   0x800000
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-trans.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-trans.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/iwl-trans.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/iwl-trans.h	2013-08-25 20:43:22.000000000 -0400
@@ -183,13 +183,12 @@ struct iwl_rx_packet {
  * @CMD_ASYNC: Return right away and don't want for the response
  * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
  *	response. The caller needs to call iwl_free_resp when done.
- * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
  */
 enum CMD_MODE {
 	CMD_SYNC		= 0,
 	CMD_ASYNC		= BIT(0),
 	CMD_WANT_SKB		= BIT(1),
-	CMD_ON_DEMAND		= BIT(2),
+	CMD_SEND_IN_RFKILL	= BIT(2),
 };
 
 #define DEF_CMD_PAYLOAD_SIZE 320
@@ -427,8 +426,9 @@ struct iwl_trans_ops {
 	void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
 	void (*stop_device)(struct iwl_trans *trans);
 
-	void (*d3_suspend)(struct iwl_trans *trans);
-	int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status);
+	void (*d3_suspend)(struct iwl_trans *trans, bool test);
+	int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status,
+			 bool test);
 
 	int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
 
@@ -455,7 +455,7 @@ struct iwl_trans_ops {
 	int (*read_mem)(struct iwl_trans *trans, u32 addr,
 			void *buf, int dwords);
 	int (*write_mem)(struct iwl_trans *trans, u32 addr,
-			 void *buf, int dwords);
+			 const void *buf, int dwords);
 	void (*configure)(struct iwl_trans *trans,
 			  const struct iwl_trans_config *trans_cfg);
 	void (*set_pmi)(struct iwl_trans *trans, bool state);
@@ -587,17 +587,18 @@ static inline void iwl_trans_stop_device
 	trans->state = IWL_TRANS_NO_FW;
 }
 
-static inline void iwl_trans_d3_suspend(struct iwl_trans *trans)
+static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test)
 {
 	might_sleep();
-	trans->ops->d3_suspend(trans);
+	trans->ops->d3_suspend(trans, test);
 }
 
 static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
-				      enum iwl_d3_status *status)
+				      enum iwl_d3_status *status,
+				      bool test)
 {
 	might_sleep();
-	return trans->ops->d3_resume(trans, status);
+	return trans->ops->d3_resume(trans, status, test);
 }
 
 static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
@@ -761,7 +762,7 @@ static inline u32 iwl_trans_read_mem32(s
 }
 
 static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr,
-				      void *buf, int dwords)
+				      const void *buf, int dwords)
 {
 	return trans->ops->write_mem(trans, addr, buf, dwords);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -128,16 +128,6 @@ config IWLWIFI_DEVICE_TRACING
 	  occur.
 endmenu
 
-config IWLWIFI_DEVICE_TESTMODE
-	def_bool y
-	depends on IWLWIFI
-	depends on NL80211_TESTMODE
-	help
-	  This option enables the testmode support for iwlwifi device through
-	  NL80211_TESTMODE. This provide the capabilities of enable user space
-	  validation applications to interacts with the device through the
-	  generic netlink message via NL80211_TESTMODE channel.
-
 config IWLWIFI_P2P
 	def_bool y
 	bool "iwlwifi experimental P2P support"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -7,14 +7,15 @@ iwlwifi-objs		+= iwl-notif-wait.o
 iwlwifi-objs		+= iwl-eeprom-read.o iwl-eeprom-parse.o
 iwlwifi-objs		+= iwl-phy-db.o iwl-nvm-parse.o
 iwlwifi-objs		+= pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
-iwlwifi-objs		+= iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o iwl-7000.o
+iwlwifi-$(CONFIG_IWLDVM) += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o
+iwlwifi-$(CONFIG_IWLMVM) += iwl-7000.o
+
+iwlwifi-objs += $(iwlwifi-m)
 
 iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
-iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o
 
 ccflags-y += -D__CHECK_ENDIAN__ -I$(src)
 
-
 obj-$(CONFIG_IWLDVM)	+= dvm/
 obj-$(CONFIG_IWLMVM)	+= mvm/
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/bt-coex.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/bt-coex.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/bt-coex.c	2013-08-25 20:43:22.000000000 -0400
@@ -174,7 +174,7 @@ static const __le32 iwl_tight_lookup[BT_
 static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = {
 	cpu_to_le32(0xaaaaaaaa),
 	cpu_to_le32(0xaaaaaaaa),
-	cpu_to_le32(0xaeaaaaaa),
+	cpu_to_le32(0xaaaaaaaa),
 	cpu_to_le32(0xaaaaaaaa),
 	cpu_to_le32(0xcc00ff28),
 	cpu_to_le32(0x0000aaaa),
@@ -202,6 +202,22 @@ static const __le32 iwl_concurrent_looku
 	cpu_to_le32(0x00000000),
 };
 
+/* single shared antenna */
+static const __le32 iwl_single_shared_ant_lookup[BT_COEX_LUT_SIZE] = {
+	cpu_to_le32(0x40000000),
+	cpu_to_le32(0x00000000),
+	cpu_to_le32(0x44000000),
+	cpu_to_le32(0x00000000),
+	cpu_to_le32(0x40000000),
+	cpu_to_le32(0x00000000),
+	cpu_to_le32(0x44000000),
+	cpu_to_le32(0x00000000),
+	cpu_to_le32(0xC0004000),
+	cpu_to_le32(0xF0005000),
+	cpu_to_le32(0xC0004000),
+	cpu_to_le32(0xF0005000),
+};
+
 int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
 {
 	struct iwl_bt_coex_cmd cmd = {
@@ -225,7 +241,10 @@ int iwl_send_bt_init_conf(struct iwl_mvm
 					BT_VALID_REDUCED_TX_POWER |
 					BT_VALID_LUT);
 
-	if (is_loose_coex())
+	if (mvm->cfg->bt_shared_single_ant)
+		memcpy(&cmd.decision_lut, iwl_single_shared_ant_lookup,
+		       sizeof(iwl_single_shared_ant_lookup));
+	else if (is_loose_coex())
 		memcpy(&cmd.decision_lut, iwl_loose_lookup,
 		       sizeof(iwl_tight_lookup));
 	else
@@ -351,6 +370,7 @@ static void iwl_mvm_bt_notif_iterator(vo
 	enum ieee80211_band band;
 	int ave_rssi;
 
+	lockdep_assert_held(&mvm->mutex);
 	if (vif->type != NL80211_IFTYPE_STATION)
 		return;
 
@@ -365,7 +385,8 @@ static void iwl_mvm_bt_notif_iterator(vo
 	smps_mode = IEEE80211_SMPS_AUTOMATIC;
 
 	if (band != IEEE80211_BAND_2GHZ) {
-		ieee80211_request_smps(vif, smps_mode);
+		iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
+				    smps_mode);
 		return;
 	}
 
@@ -380,7 +401,7 @@ static void iwl_mvm_bt_notif_iterator(vo
 		       mvmvif->id,  data->notif->bt_status,
 		       data->notif->bt_traffic_load, smps_mode);
 
-	ieee80211_request_smps(vif, smps_mode);
+	iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode);
 
 	/* don't reduce the Tx power if in loose scheme */
 	if (is_loose_coex())
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/d3.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/d3.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/d3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/d3.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,6 +63,7 @@
 
 #include <linux/etherdevice.h>
 #include <linux/ip.h>
+#include <linux/fs.h>
 #include <net/cfg80211.h>
 #include <net/ipv6.h>
 #include <net/tcp.h>
@@ -133,7 +134,7 @@ struct wowlan_key_data {
 	struct iwl_wowlan_rsc_tsc_params_cmd *rsc_tsc;
 	struct iwl_wowlan_tkip_params_cmd *tkip;
 	bool error, use_rsc_tsc, use_tkip;
-	int gtk_key_idx;
+	int wep_key_idx;
 };
 
 static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
@@ -187,8 +188,8 @@ static void iwl_mvm_wowlan_program_keys(
 			wkc.wep_key.key_offset = 0;
 		} else {
 			/* others start at 1 */
-			data->gtk_key_idx++;
-			wkc.wep_key.key_offset = data->gtk_key_idx;
+			data->wep_key_idx++;
+			wkc.wep_key.key_offset = data->wep_key_idx;
 		}
 
 		ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, CMD_SYNC,
@@ -315,8 +316,13 @@ static void iwl_mvm_wowlan_program_keys(
 		mvm->ptk_ivlen = key->iv_len;
 		mvm->ptk_icvlen = key->icv_len;
 	} else {
-		data->gtk_key_idx++;
-		key->hw_key_idx = data->gtk_key_idx;
+		/*
+		 * firmware only supports TSC/RSC for a single key,
+		 * so if there are multiple keep overwriting them
+		 * with new ones -- this relies on mac80211 doing
+		 * list_add_tail().
+		 */
+		key->hw_key_idx = 1;
 		mvm->gtk_ivlen = key->iv_len;
 		mvm->gtk_icvlen = key->icv_len;
 	}
@@ -419,8 +425,7 @@ static __le16 pseudo_hdr_check(int len,
 	return cpu_to_le16(be16_to_cpu((__force __be16)check));
 }
 
-static void iwl_mvm_build_tcp_packet(struct iwl_mvm *mvm,
-				     struct ieee80211_vif *vif,
+static void iwl_mvm_build_tcp_packet(struct ieee80211_vif *vif,
 				     struct cfg80211_wowlan_tcp *tcp,
 				     void *_pkt, u8 *mask,
 				     __le16 *pseudo_hdr_csum,
@@ -566,21 +571,21 @@ static int iwl_mvm_send_remote_wake_cfg(
 
 	/* SYN (TX) */
 	iwl_mvm_build_tcp_packet(
-		mvm, vif, tcp, cfg->syn_tx.data, NULL,
+		vif, tcp, cfg->syn_tx.data, NULL,
 		&cfg->syn_tx.info.tcp_pseudo_header_checksum,
 		MVM_TCP_TX_SYN);
 	cfg->syn_tx.info.tcp_payload_length = 0;
 
 	/* SYN/ACK (RX) */
 	iwl_mvm_build_tcp_packet(
-		mvm, vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask,
+		vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask,
 		&cfg->synack_rx.info.tcp_pseudo_header_checksum,
 		MVM_TCP_RX_SYNACK);
 	cfg->synack_rx.info.tcp_payload_length = 0;
 
 	/* KEEPALIVE/ACK (TX) */
 	iwl_mvm_build_tcp_packet(
-		mvm, vif, tcp, cfg->keepalive_tx.data, NULL,
+		vif, tcp, cfg->keepalive_tx.data, NULL,
 		&cfg->keepalive_tx.info.tcp_pseudo_header_checksum,
 		MVM_TCP_TX_DATA);
 	cfg->keepalive_tx.info.tcp_payload_length =
@@ -604,7 +609,7 @@ static int iwl_mvm_send_remote_wake_cfg(
 
 	/* ACK (RX) */
 	iwl_mvm_build_tcp_packet(
-		mvm, vif, tcp, cfg->keepalive_ack_rx.data,
+		vif, tcp, cfg->keepalive_ack_rx.data,
 		cfg->keepalive_ack_rx.rx_mask,
 		&cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum,
 		MVM_TCP_RX_ACK);
@@ -612,7 +617,7 @@ static int iwl_mvm_send_remote_wake_cfg(
 
 	/* WAKEUP (RX) */
 	iwl_mvm_build_tcp_packet(
-		mvm, vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask,
+		vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask,
 		&cfg->wake_rx.info.tcp_pseudo_header_checksum,
 		MVM_TCP_RX_WAKE);
 	cfg->wake_rx.info.tcp_payload_length =
@@ -620,7 +625,7 @@ static int iwl_mvm_send_remote_wake_cfg(
 
 	/* FIN */
 	iwl_mvm_build_tcp_packet(
-		mvm, vif, tcp, cfg->fin_tx.data, NULL,
+		vif, tcp, cfg->fin_tx.data, NULL,
 		&cfg->fin_tx.info.tcp_pseudo_header_checksum,
 		MVM_TCP_TX_FIN);
 	cfg->fin_tx.info.tcp_payload_length = 0;
@@ -756,7 +761,9 @@ static int iwl_mvm_d3_reprogram(struct i
 	return 0;
 }
 
-int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
+			     struct cfg80211_wowlan *wowlan,
+			     bool test)
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 	struct iwl_d3_iter_data suspend_iter_data = {
@@ -769,7 +776,7 @@ int iwl_mvm_suspend(struct ieee80211_hw
 	struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
 	struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
 	struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
-	struct iwl_d3_manager_config d3_cfg_cmd = {
+	struct iwl_d3_manager_config d3_cfg_cmd_data = {
 		/*
 		 * Program the minimum sleep time to 10 seconds, as many
 		 * platforms have issues processing a wakeup signal while
@@ -777,17 +784,30 @@ int iwl_mvm_suspend(struct ieee80211_hw
 		 */
 		.min_sleep_time = cpu_to_le32(10 * 1000 * 1000),
 	};
+	struct iwl_host_cmd d3_cfg_cmd = {
+		.id = D3_CONFIG_CMD,
+		.flags = CMD_SYNC | CMD_WANT_SKB,
+		.data[0] = &d3_cfg_cmd_data,
+		.len[0] = sizeof(d3_cfg_cmd_data),
+	};
 	struct wowlan_key_data key_data = {
 		.use_rsc_tsc = false,
 		.tkip = &tkip_cmd,
 		.use_tkip = false,
 	};
 	int ret, i;
+	int len __maybe_unused;
 	u16 seq;
 	u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT;
 
-	if (WARN_ON(!wowlan))
+	if (!wowlan) {
+		/*
+		 * mac80211 shouldn't get here, but for D3 test
+		 * it doesn't warrant a warning
+		 */
+		WARN_ON(!test);
 		return -EINVAL;
+	}
 
 	key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL);
 	if (!key_data.rsc_tsc)
@@ -1007,15 +1027,37 @@ int iwl_mvm_suspend(struct ieee80211_hw
 	if (ret)
 		goto out;
 
+	ret = iwl_mvm_power_update_mode(mvm, vif);
+	if (ret)
+		goto out;
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	if (mvm->d3_wake_sysassert)
+		d3_cfg_cmd_data.wakeup_flags |=
+			cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR);
+#endif
+
 	/* must be last -- this switches firmware state */
-	ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC,
-				   sizeof(d3_cfg_cmd), &d3_cfg_cmd);
+	ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd);
 	if (ret)
 		goto out;
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	len = le32_to_cpu(d3_cfg_cmd.resp_pkt->len_n_flags) &
+		FH_RSCSR_FRAME_SIZE_MSK;
+	if (len >= sizeof(u32) * 2) {
+		mvm->d3_test_pme_ptr =
+			le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data);
+	} else if (test) {
+		/* in test mode we require the pointer */
+		ret = -EIO;
+		goto out;
+	}
+#endif
+	iwl_free_resp(&d3_cfg_cmd);
 
 	clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
 
-	iwl_trans_d3_suspend(mvm->trans);
+	iwl_trans_d3_suspend(mvm->trans, test);
  out:
 	mvm->aux_sta.sta_id = old_aux_sta_id;
 	mvm_ap_sta->sta_id = old_ap_sta_id;
@@ -1030,6 +1072,11 @@ int iwl_mvm_suspend(struct ieee80211_hw
 	return ret;
 }
 
+int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+{
+	return __iwl_mvm_suspend(hw, wowlan, false);
+}
+
 static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
 					 struct ieee80211_vif *vif)
 {
@@ -1214,9 +1261,28 @@ static void iwl_mvm_query_wakeup_reasons
 	iwl_free_resp(&cmd);
 }
 
-int iwl_mvm_resume(struct ieee80211_hw *hw)
+static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
+{
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	const struct fw_img *img = &mvm->fw->img[IWL_UCODE_WOWLAN];
+	u32 len = img->sec[IWL_UCODE_SECTION_DATA].len;
+	u32 offs = img->sec[IWL_UCODE_SECTION_DATA].offset;
+
+	if (!mvm->store_d3_resume_sram)
+		return;
+
+	if (!mvm->d3_resume_sram) {
+		mvm->d3_resume_sram = kzalloc(len, GFP_KERNEL);
+		if (!mvm->d3_resume_sram)
+			return;
+	}
+
+	iwl_trans_read_mem_bytes(mvm->trans, offs, mvm->d3_resume_sram, len);
+#endif
+}
+
+static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
 {
-	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 	struct iwl_d3_iter_data resume_iter_data = {
 		.mvm = mvm,
 	};
@@ -1236,7 +1302,7 @@ int iwl_mvm_resume(struct ieee80211_hw *
 
 	vif = resume_iter_data.vif;
 
-	ret = iwl_trans_d3_resume(mvm->trans, &d3_status);
+	ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test);
 	if (ret)
 		goto out_unlock;
 
@@ -1245,12 +1311,15 @@ int iwl_mvm_resume(struct ieee80211_hw *
 		goto out_unlock;
 	}
 
+	/* query SRAM first in case we want event logging */
+	iwl_mvm_read_d3_sram(mvm);
+
 	iwl_mvm_query_wakeup_reasons(mvm, vif);
 
  out_unlock:
 	mutex_unlock(&mvm->mutex);
 
-	if (vif)
+	if (!test && vif)
 		ieee80211_resume_disconnect(vif);
 
 	/* return 1 to reconfigure the device */
@@ -1258,9 +1327,106 @@ int iwl_mvm_resume(struct ieee80211_hw *
 	return 1;
 }
 
+int iwl_mvm_resume(struct ieee80211_hw *hw)
+{
+	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+
+	return __iwl_mvm_resume(mvm, false);
+}
+
 void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled)
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 
 	device_set_wakeup_enable(mvm->trans->dev, enabled);
 }
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
+{
+	struct iwl_mvm *mvm = inode->i_private;
+	int err;
+
+	if (mvm->d3_test_active)
+		return -EBUSY;
+
+	file->private_data = inode->i_private;
+
+	ieee80211_stop_queues(mvm->hw);
+	synchronize_net();
+
+	/* start pseudo D3 */
+	rtnl_lock();
+	err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true);
+	rtnl_unlock();
+	if (err > 0)
+		err = -EINVAL;
+	if (err) {
+		ieee80211_wake_queues(mvm->hw);
+		return err;
+	}
+	mvm->d3_test_active = true;
+	return 0;
+}
+
+static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
+				    size_t count, loff_t *ppos)
+{
+	struct iwl_mvm *mvm = file->private_data;
+	u32 pme_asserted;
+
+	while (true) {
+		pme_asserted = iwl_trans_read_mem32(mvm->trans,
+						    mvm->d3_test_pme_ptr);
+		if (pme_asserted)
+			break;
+		if (msleep_interruptible(100))
+			break;
+	}
+
+	return 0;
+}
+
+static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac,
+					      struct ieee80211_vif *vif)
+{
+	if (vif->type == NL80211_IFTYPE_STATION)
+		ieee80211_connection_loss(vif);
+}
+
+static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
+{
+	struct iwl_mvm *mvm = inode->i_private;
+	int remaining_time = 10;
+
+	mvm->d3_test_active = false;
+	__iwl_mvm_resume(mvm, true);
+	iwl_abort_notification_waits(&mvm->notif_wait);
+	ieee80211_restart_hw(mvm->hw);
+
+	/* wait for restart and disconnect all interfaces */
+	while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
+	       remaining_time > 0) {
+		remaining_time--;
+		msleep(1000);
+	}
+
+	if (remaining_time == 0)
+		IWL_ERR(mvm, "Timed out waiting for HW restart to finish!\n");
+
+	ieee80211_iterate_active_interfaces_atomic(
+		mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+		iwl_mvm_d3_test_disconn_work_iter, NULL);
+
+	ieee80211_wake_queues(mvm->hw);
+
+	return 0;
+}
+
+const struct file_operations iwl_dbgfs_d3_test_ops = {
+	.llseek = no_llseek,
+	.open = iwl_mvm_d3_test_open,
+	.read = iwl_mvm_d3_test_read,
+	.release = iwl_mvm_d3_test_release,
+};
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/debugfs.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/debugfs.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -145,15 +145,18 @@ static ssize_t iwl_dbgfs_sram_read(struc
 	char *buf;
 	u8 *ptr;
 
+	if (!mvm->ucode_loaded)
+		return -EINVAL;
+
 	/* default is to dump the entire data segment */
 	if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) {
-		mvm->dbgfs_sram_offset = 0x800000;
-		if (!mvm->ucode_loaded)
-			return -EINVAL;
 		img = &mvm->fw->img[mvm->cur_ucode];
-		mvm->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
+		ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
+		len = img->sec[IWL_UCODE_SECTION_DATA].len;
+	} else {
+		ofs = mvm->dbgfs_sram_offset;
+		len = mvm->dbgfs_sram_len;
 	}
-	len = mvm->dbgfs_sram_len;
 
 	bufsz = len * 4 + 256;
 	buf = kzalloc(bufsz, GFP_KERNEL);
@@ -167,12 +170,9 @@ static ssize_t iwl_dbgfs_sram_read(struc
 	}
 
 	pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len);
-	pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",
-			 mvm->dbgfs_sram_offset);
+	pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", ofs);
 
-	iwl_trans_read_mem_bytes(mvm->trans,
-				 mvm->dbgfs_sram_offset,
-				 ptr, len);
+	iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len);
 	for (ofs = 0; ofs < len; ofs += 16) {
 		pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs);
 		hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
@@ -300,6 +300,168 @@ static ssize_t iwl_dbgfs_power_down_d3_a
 	return count;
 }
 
+static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
+				 struct ieee80211_vif *vif,
+				 enum iwl_dbgfs_pm_mask param, int val)
+{
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
+
+	dbgfs_pm->mask |= param;
+
+	switch (param) {
+	case MVM_DEBUGFS_PM_KEEP_ALIVE: {
+		struct ieee80211_hw *hw = mvm->hw;
+		int dtimper = hw->conf.ps_dtim_period ?: 1;
+		int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
+
+		IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
+		if (val * MSEC_PER_SEC < 3 * dtimper_msec) {
+			IWL_WARN(mvm,
+				 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
+				 val * MSEC_PER_SEC, 3 * dtimper_msec);
+		}
+		dbgfs_pm->keep_alive_seconds = val;
+		break;
+	}
+	case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
+		IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
+				val ? "enabled" : "disabled");
+		dbgfs_pm->skip_over_dtim = val;
+		break;
+	case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
+		IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
+		dbgfs_pm->skip_dtim_periods = val;
+		break;
+	case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
+		IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
+		dbgfs_pm->rx_data_timeout = val;
+		break;
+	case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
+		IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
+		dbgfs_pm->tx_data_timeout = val;
+		break;
+	case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
+		IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
+		dbgfs_pm->disable_power_off = val;
+	case MVM_DEBUGFS_PM_LPRX_ENA:
+		IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
+		dbgfs_pm->lprx_ena = val;
+		break;
+	case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
+		IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
+		dbgfs_pm->lprx_rssi_threshold = val;
+		break;
+	}
+}
+
+static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct ieee80211_vif *vif = file->private_data;
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	struct iwl_mvm *mvm = mvmvif->dbgfs_data;
+	enum iwl_dbgfs_pm_mask param;
+	char buf[32] = {};
+	int val;
+	int ret;
+
+	if (copy_from_user(buf, user_buf, sizeof(buf)))
+		return -EFAULT;
+
+	if (!strncmp("keep_alive=", buf, 11)) {
+		if (sscanf(buf + 11, "%d", &val) != 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_PM_KEEP_ALIVE;
+	} else if (!strncmp("skip_over_dtim=", buf, 15)) {
+		if (sscanf(buf + 15, "%d", &val) != 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
+	} else if (!strncmp("skip_dtim_periods=", buf, 18)) {
+		if (sscanf(buf + 18, "%d", &val) != 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
+	} else if (!strncmp("rx_data_timeout=", buf, 16)) {
+		if (sscanf(buf + 16, "%d", &val) != 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
+	} else if (!strncmp("tx_data_timeout=", buf, 16)) {
+		if (sscanf(buf + 16, "%d", &val) != 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
+	} else if (!strncmp("disable_power_off=", buf, 18)) {
+		if (sscanf(buf + 18, "%d", &val) != 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
+	} else if (!strncmp("lprx=", buf, 5)) {
+		if (sscanf(buf + 5, "%d", &val) != 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_PM_LPRX_ENA;
+	} else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
+		if (sscanf(buf + 20, "%d", &val) != 1)
+			return -EINVAL;
+		if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
+		    POWER_LPRX_RSSI_THRESHOLD_MIN)
+			return -EINVAL;
+		param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
+	} else {
+		return -EINVAL;
+	}
+
+	mutex_lock(&mvm->mutex);
+	iwl_dbgfs_update_pm(mvm, vif, param, val);
+	ret = iwl_mvm_power_update_mode(mvm, vif);
+	mutex_unlock(&mvm->mutex);
+
+	return ret ?: count;
+}
+
+static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct ieee80211_vif *vif = file->private_data;
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	struct iwl_mvm *mvm = mvmvif->dbgfs_data;
+	struct iwl_powertable_cmd cmd = {};
+	char buf[256];
+	int bufsz = sizeof(buf);
+	int pos = 0;
+
+	iwl_mvm_power_build_cmd(mvm, vif, &cmd);
+
+	pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
+			 (cmd.flags &
+			 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
+			 0 : 1);
+	pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
+			 le32_to_cpu(cmd.skip_dtim_periods));
+	pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
+			 iwlmvm_mod_params.power_scheme);
+	pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
+			 le16_to_cpu(cmd.flags));
+	pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
+			 cmd.keep_alive_seconds);
+
+	if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
+		pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
+				 (cmd.flags &
+				 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
+				 1 : 0);
+		pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
+				 le32_to_cpu(cmd.rx_data_timeout));
+		pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
+				 le32_to_cpu(cmd.tx_data_timeout));
+		if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
+			pos += scnprintf(buf+pos, bufsz-pos,
+					 "lprx_rssi_threshold = %d\n",
+					 le32_to_cpu(cmd.lprx_rssi_threshold));
+	}
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
 static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
 					 char __user *user_buf,
 					 size_t count, loff_t *ppos)
@@ -481,6 +643,255 @@ static ssize_t iwl_dbgfs_fw_restart_writ
 	return count;
 }
 
+static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
+				enum iwl_dbgfs_bf_mask param, int value)
+{
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
+
+	dbgfs_bf->mask |= param;
+
+	switch (param) {
+	case MVM_DEBUGFS_BF_ENERGY_DELTA:
+		dbgfs_bf->bf_energy_delta = value;
+		break;
+	case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
+		dbgfs_bf->bf_roaming_energy_delta = value;
+		break;
+	case MVM_DEBUGFS_BF_ROAMING_STATE:
+		dbgfs_bf->bf_roaming_state = value;
+		break;
+	case MVM_DEBUGFS_BF_TEMPERATURE_DELTA:
+		dbgfs_bf->bf_temperature_delta = value;
+		break;
+	case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
+		dbgfs_bf->bf_enable_beacon_filter = value;
+		break;
+	case MVM_DEBUGFS_BF_DEBUG_FLAG:
+		dbgfs_bf->bf_debug_flag = value;
+		break;
+	case MVM_DEBUGFS_BF_ESCAPE_TIMER:
+		dbgfs_bf->bf_escape_timer = value;
+		break;
+	case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
+		dbgfs_bf->ba_enable_beacon_abort = value;
+		break;
+	case MVM_DEBUGFS_BA_ESCAPE_TIMER:
+		dbgfs_bf->ba_escape_timer = value;
+		break;
+	}
+}
+
+static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct ieee80211_vif *vif = file->private_data;
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	struct iwl_mvm *mvm = mvmvif->dbgfs_data;
+	enum iwl_dbgfs_bf_mask param;
+	char buf[256];
+	int buf_size;
+	int value;
+	int ret = 0;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	if (!strncmp("bf_energy_delta=", buf, 16)) {
+		if (sscanf(buf+16, "%d", &value) != 1)
+			return -EINVAL;
+		if (value < IWL_BF_ENERGY_DELTA_MIN ||
+		    value > IWL_BF_ENERGY_DELTA_MAX)
+			return -EINVAL;
+		param = MVM_DEBUGFS_BF_ENERGY_DELTA;
+	} else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
+		if (sscanf(buf+24, "%d", &value) != 1)
+			return -EINVAL;
+		if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
+		    value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
+			return -EINVAL;
+		param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
+	} else if (!strncmp("bf_roaming_state=", buf, 17)) {
+		if (sscanf(buf+17, "%d", &value) != 1)
+			return -EINVAL;
+		if (value < IWL_BF_ROAMING_STATE_MIN ||
+		    value > IWL_BF_ROAMING_STATE_MAX)
+			return -EINVAL;
+		param = MVM_DEBUGFS_BF_ROAMING_STATE;
+	} else if (!strncmp("bf_temperature_delta=", buf, 21)) {
+		if (sscanf(buf+21, "%d", &value) != 1)
+			return -EINVAL;
+		if (value < IWL_BF_TEMPERATURE_DELTA_MIN ||
+		    value > IWL_BF_TEMPERATURE_DELTA_MAX)
+			return -EINVAL;
+		param = MVM_DEBUGFS_BF_TEMPERATURE_DELTA;
+	} else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
+		if (sscanf(buf+24, "%d", &value) != 1)
+			return -EINVAL;
+		if (value < 0 || value > 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
+	} else if (!strncmp("bf_debug_flag=", buf, 14)) {
+		if (sscanf(buf+14, "%d", &value) != 1)
+			return -EINVAL;
+		if (value < 0 || value > 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_BF_DEBUG_FLAG;
+	} else if (!strncmp("bf_escape_timer=", buf, 16)) {
+		if (sscanf(buf+16, "%d", &value) != 1)
+			return -EINVAL;
+		if (value < IWL_BF_ESCAPE_TIMER_MIN ||
+		    value > IWL_BF_ESCAPE_TIMER_MAX)
+			return -EINVAL;
+		param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
+	} else if (!strncmp("ba_escape_timer=", buf, 16)) {
+		if (sscanf(buf+16, "%d", &value) != 1)
+			return -EINVAL;
+		if (value < IWL_BA_ESCAPE_TIMER_MIN ||
+		    value > IWL_BA_ESCAPE_TIMER_MAX)
+			return -EINVAL;
+		param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
+	} else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
+		if (sscanf(buf+23, "%d", &value) != 1)
+			return -EINVAL;
+		if (value < 0 || value > 1)
+			return -EINVAL;
+		param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
+	} else {
+		return -EINVAL;
+	}
+
+	mutex_lock(&mvm->mutex);
+	iwl_dbgfs_update_bf(vif, param, value);
+	if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) {
+		ret = iwl_mvm_disable_beacon_filter(mvm, vif);
+	} else {
+		if (mvmvif->bf_enabled)
+			ret = iwl_mvm_enable_beacon_filter(mvm, vif);
+		else
+			ret = iwl_mvm_disable_beacon_filter(mvm, vif);
+	}
+	mutex_unlock(&mvm->mutex);
+
+	return ret ?: count;
+}
+
+static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct ieee80211_vif *vif = file->private_data;
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	char buf[256];
+	int pos = 0;
+	const size_t bufsz = sizeof(buf);
+	struct iwl_beacon_filter_cmd cmd = {
+		.bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT,
+		.bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT,
+		.bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT,
+		.bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT,
+		.bf_enable_beacon_filter = IWL_BF_ENABLE_BEACON_FILTER_DEFAULT,
+		.bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT,
+		.bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT),
+		.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT),
+		.ba_enable_beacon_abort = IWL_BA_ENABLE_BEACON_ABORT_DEFAULT,
+	};
+
+	iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
+	if (mvmvif->bf_enabled)
+		cmd.bf_enable_beacon_filter = 1;
+	else
+		cmd.bf_enable_beacon_filter = 0;
+
+	pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
+			 cmd.bf_energy_delta);
+	pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
+			 cmd.bf_roaming_energy_delta);
+	pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
+			 cmd.bf_roaming_state);
+	pos += scnprintf(buf+pos, bufsz-pos, "bf_temperature_delta = %d\n",
+			 cmd.bf_temperature_delta);
+	pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
+			 cmd.bf_enable_beacon_filter);
+	pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
+			 cmd.bf_debug_flag);
+	pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
+			 cmd.bf_escape_timer);
+	pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
+			 cmd.ba_escape_timer);
+	pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
+			 cmd.ba_enable_beacon_abort);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
+				       const char __user *user_buf,
+				       size_t count, loff_t *ppos)
+{
+	struct iwl_mvm *mvm = file->private_data;
+	char buf[8] = {};
+	int store;
+
+	if (copy_from_user(buf, user_buf, sizeof(buf)))
+		return -EFAULT;
+
+	if (sscanf(buf, "%d", &store) != 1)
+		return -EINVAL;
+
+	mvm->store_d3_resume_sram = store;
+
+	return count;
+}
+
+static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct iwl_mvm *mvm = file->private_data;
+	const struct fw_img *img;
+	int ofs, len, pos = 0;
+	size_t bufsz, ret;
+	char *buf;
+	u8 *ptr = mvm->d3_resume_sram;
+
+	img = &mvm->fw->img[IWL_UCODE_WOWLAN];
+	len = img->sec[IWL_UCODE_SECTION_DATA].len;
+
+	bufsz = len * 4 + 256;
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	pos += scnprintf(buf, bufsz, "D3 SRAM capture: %sabled\n",
+			 mvm->store_d3_resume_sram ? "en" : "dis");
+
+	if (ptr) {
+		for (ofs = 0; ofs < len; ofs += 16) {
+			pos += scnprintf(buf + pos, bufsz - pos,
+					 "0x%.4x ", ofs);
+			hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
+					   bufsz - pos, false);
+			pos += strlen(buf + pos);
+			if (bufsz - pos > 0)
+				buf[pos++] = '\n';
+		}
+	} else {
+		pos += scnprintf(buf + pos, bufsz - pos,
+				 "(no data captured)\n");
+	}
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+
+	kfree(buf);
+
+	return ret;
+}
+#endif
+
 #define MVM_DEBUGFS_READ_FILE_OPS(name)					\
 static const struct file_operations iwl_dbgfs_##name##_ops = {	\
 	.read = iwl_dbgfs_##name##_read,				\
@@ -524,9 +935,14 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
 MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
 MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
+#ifdef CONFIG_PM_SLEEP
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram);
+#endif
 
 /* Interface specific debugfs entries */
 MVM_DEBUGFS_READ_FILE_OPS(mac_params);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params);
 
 int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
 {
@@ -542,6 +958,13 @@ int iwl_mvm_dbgfs_register(struct iwl_mv
 	MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR);
 	MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR);
 	MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
+#ifdef CONFIG_PM_SLEEP
+	MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
+	MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR);
+	if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR | S_IWUSR,
+				 mvm->debugfs_dir, &mvm->d3_wake_sysassert))
+		goto err;
+#endif
 
 	/*
 	 * Create a symlink with mac80211. It will be removed when mac80211
@@ -565,7 +988,11 @@ void iwl_mvm_vif_dbgfs_register(struct i
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 	char buf[100];
 
-	if (!dbgfs_dir)
+	/*
+	 * Check if debugfs directory already exist before creating it.
+	 * This may happen when, for example, resetting hw or suspend-resume
+	 */
+	if (!dbgfs_dir || mvmvif->dbgfs_dir)
 		return;
 
 	mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
@@ -577,9 +1004,19 @@ void iwl_mvm_vif_dbgfs_register(struct i
 		return;
 	}
 
+	if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
+	    vif->type == NL80211_IFTYPE_STATION && !vif->p2p)
+		MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
+					 S_IRUSR);
+
 	MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
 				 S_IRUSR);
 
+	if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
+	    mvmvif == mvm->bf_allowed_vif)
+		MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
+					 S_IRUSR | S_IWUSR);
+
 	/*
 	 * Create symlink for convenience pointing to interface specific
 	 * debugfs entries for the driver. For example, under
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h	2013-08-25 20:43:22.000000000 -0400
@@ -75,13 +75,15 @@ enum iwl_d3_wakeup_flags {
  * struct iwl_d3_manager_config - D3 manager configuration command
  * @min_sleep_time: minimum sleep time (in usec)
  * @wakeup_flags: wakeup flags, see &enum iwl_d3_wakeup_flags
+ * @wakeup_host_timer: force wakeup after this many seconds
  *
  * The structure is used for the D3_CONFIG_CMD command.
  */
 struct iwl_d3_manager_config {
 	__le32 min_sleep_time;
 	__le32 wakeup_flags;
-} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_3 */
+	__le32 wakeup_host_timer;
+} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_4 */
 
 
 /* TODO: OFFLOADS_QUERY_API_S_VER_1 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api.h	2013-08-25 20:43:22.000000000 -0400
@@ -139,6 +139,9 @@ enum {
 	/* Power */
 	POWER_TABLE_CMD = 0x77,
 
+	/* Thermal Throttling*/
+	REPLY_THERMAL_MNG_BACKOFF = 0x7e,
+
 	/* Scanning */
 	SCAN_REQUEST_CMD = 0x80,
 	SCAN_ABORT_CMD = 0x81,
@@ -161,6 +164,8 @@ enum {
 	CARD_STATE_CMD = 0xa0,
 	CARD_STATE_NOTIFICATION = 0xa1,
 
+	MISSED_BEACONS_NOTIFICATION = 0xa2,
+
 	REPLY_RX_PHY_CMD = 0xc0,
 	REPLY_RX_MPDU_CMD = 0xc1,
 	BA_NOTIF = 0xc5,
@@ -170,6 +175,8 @@ enum {
 	BT_COEX_PROT_ENV = 0xcd,
 	BT_PROFILE_NOTIFICATION = 0xce,
 
+	REPLY_BEACON_FILTERING_CMD = 0xd2,
+
 	REPLY_DEBUG_CMD = 0xf0,
 	DEBUG_LOG_MSG = 0xf7,
 
@@ -938,6 +945,24 @@ struct iwl_card_state_notif {
 } __packed; /* CARD_STATE_NTFY_API_S_VER_1 */
 
 /**
+ * struct iwl_missed_beacons_notif - information on missed beacons
+ * ( MISSED_BEACONS_NOTIFICATION = 0xa2 )
+ * @mac_id: interface ID
+ * @consec_missed_beacons_since_last_rx: number of consecutive missed
+ *	beacons since last RX.
+ * @consec_missed_beacons: number of consecutive missed beacons
+ * @num_expected_beacons:
+ * @num_recvd_beacons:
+ */
+struct iwl_missed_beacons_notif {
+	__le32 mac_id;
+	__le32 consec_missed_beacons_since_last_rx;
+	__le32 consec_missed_beacons;
+	__le32 num_expected_beacons;
+	__le32 num_recvd_beacons;
+} __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */
+
+/**
  * struct iwl_set_calib_default_cmd - set default value for calibration.
  * ( SET_CALIB_DEFAULT_CMD = 0x8e )
  * @calib_index: the calibration to set value for
@@ -975,4 +1000,212 @@ struct iwl_mcast_filter_cmd {
 	u8 addr_list[0];
 } __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */
 
+struct mvm_statistics_dbg {
+	__le32 burst_check;
+	__le32 burst_count;
+	__le32 wait_for_silence_timeout_cnt;
+	__le32 reserved[3];
+} __packed; /* STATISTICS_DEBUG_API_S_VER_2 */
+
+struct mvm_statistics_div {
+	__le32 tx_on_a;
+	__le32 tx_on_b;
+	__le32 exec_time;
+	__le32 probe_time;
+	__le32 rssi_ant;
+	__le32 reserved2;
+} __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
+
+struct mvm_statistics_general_common {
+	__le32 temperature;   /* radio temperature */
+	__le32 temperature_m; /* radio voltage */
+	struct mvm_statistics_dbg dbg;
+	__le32 sleep_time;
+	__le32 slots_out;
+	__le32 slots_idle;
+	__le32 ttl_timestamp;
+	struct mvm_statistics_div div;
+	__le32 rx_enable_counter;
+	/*
+	 * num_of_sos_states:
+	 *  count the number of times we have to re-tune
+	 *  in order to get out of bad PHY status
+	 */
+	__le32 num_of_sos_states;
+} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
+
+struct mvm_statistics_rx_non_phy {
+	__le32 bogus_cts;	/* CTS received when not expecting CTS */
+	__le32 bogus_ack;	/* ACK received when not expecting ACK */
+	__le32 non_bssid_frames;	/* number of frames with BSSID that
+					 * doesn't belong to the STA BSSID */
+	__le32 filtered_frames;	/* count frames that were dumped in the
+				 * filtering process */
+	__le32 non_channel_beacons;	/* beacons with our bss id but not on
+					 * our serving channel */
+	__le32 channel_beacons;	/* beacons with our bss id and in our
+				 * serving channel */
+	__le32 num_missed_bcon;	/* number of missed beacons */
+	__le32 adc_rx_saturation_time;	/* count in 0.8us units the time the
+					 * ADC was in saturation */
+	__le32 ina_detection_search_time;/* total time (in 0.8us) searched
+					  * for INA */
+	__le32 beacon_silence_rssi_a;	/* RSSI silence after beacon frame */
+	__le32 beacon_silence_rssi_b;	/* RSSI silence after beacon frame */
+	__le32 beacon_silence_rssi_c;	/* RSSI silence after beacon frame */
+	__le32 interference_data_flag;	/* flag for interference data
+					 * availability. 1 when data is
+					 * available. */
+	__le32 channel_load;		/* counts RX Enable time in uSec */
+	__le32 dsp_false_alarms;	/* DSP false alarm (both OFDM
+					 * and CCK) counter */
+	__le32 beacon_rssi_a;
+	__le32 beacon_rssi_b;
+	__le32 beacon_rssi_c;
+	__le32 beacon_energy_a;
+	__le32 beacon_energy_b;
+	__le32 beacon_energy_c;
+	__le32 num_bt_kills;
+	__le32 mac_id;
+	__le32 directed_data_mpdu;
+} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */
+
+struct mvm_statistics_rx_phy {
+	__le32 ina_cnt;
+	__le32 fina_cnt;
+	__le32 plcp_err;
+	__le32 crc32_err;
+	__le32 overrun_err;
+	__le32 early_overrun_err;
+	__le32 crc32_good;
+	__le32 false_alarm_cnt;
+	__le32 fina_sync_err_cnt;
+	__le32 sfd_timeout;
+	__le32 fina_timeout;
+	__le32 unresponded_rts;
+	__le32 rxe_frame_limit_overrun;
+	__le32 sent_ack_cnt;
+	__le32 sent_cts_cnt;
+	__le32 sent_ba_rsp_cnt;
+	__le32 dsp_self_kill;
+	__le32 mh_format_err;
+	__le32 re_acq_main_rssi_sum;
+	__le32 reserved;
+} __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */
+
+struct mvm_statistics_rx_ht_phy {
+	__le32 plcp_err;
+	__le32 overrun_err;
+	__le32 early_overrun_err;
+	__le32 crc32_good;
+	__le32 crc32_err;
+	__le32 mh_format_err;
+	__le32 agg_crc32_good;
+	__le32 agg_mpdu_cnt;
+	__le32 agg_cnt;
+	__le32 unsupport_mcs;
+} __packed;  /* STATISTICS_HT_RX_PHY_API_S_VER_1 */
+
+#define MAX_CHAINS 3
+
+struct mvm_statistics_tx_non_phy_agg {
+	__le32 ba_timeout;
+	__le32 ba_reschedule_frames;
+	__le32 scd_query_agg_frame_cnt;
+	__le32 scd_query_no_agg;
+	__le32 scd_query_agg;
+	__le32 scd_query_mismatch;
+	__le32 frame_not_ready;
+	__le32 underrun;
+	__le32 bt_prio_kill;
+	__le32 rx_ba_rsp_cnt;
+	__s8 txpower[MAX_CHAINS];
+	__s8 reserved;
+	__le32 reserved2;
+} __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */
+
+struct mvm_statistics_tx_channel_width {
+	__le32 ext_cca_narrow_ch20[1];
+	__le32 ext_cca_narrow_ch40[2];
+	__le32 ext_cca_narrow_ch80[3];
+	__le32 ext_cca_narrow_ch160[4];
+	__le32 last_tx_ch_width_indx;
+	__le32 rx_detected_per_ch_width[4];
+	__le32 success_per_ch_width[4];
+	__le32 fail_per_ch_width[4];
+}; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */
+
+struct mvm_statistics_tx {
+	__le32 preamble_cnt;
+	__le32 rx_detected_cnt;
+	__le32 bt_prio_defer_cnt;
+	__le32 bt_prio_kill_cnt;
+	__le32 few_bytes_cnt;
+	__le32 cts_timeout;
+	__le32 ack_timeout;
+	__le32 expected_ack_cnt;
+	__le32 actual_ack_cnt;
+	__le32 dump_msdu_cnt;
+	__le32 burst_abort_next_frame_mismatch_cnt;
+	__le32 burst_abort_missing_next_frame_cnt;
+	__le32 cts_timeout_collision;
+	__le32 ack_or_ba_timeout_collision;
+	struct mvm_statistics_tx_non_phy_agg agg;
+	struct mvm_statistics_tx_channel_width channel_width;
+} __packed; /* STATISTICS_TX_API_S_VER_4 */
+
+
+struct mvm_statistics_bt_activity {
+	__le32 hi_priority_tx_req_cnt;
+	__le32 hi_priority_tx_denied_cnt;
+	__le32 lo_priority_tx_req_cnt;
+	__le32 lo_priority_tx_denied_cnt;
+	__le32 hi_priority_rx_req_cnt;
+	__le32 hi_priority_rx_denied_cnt;
+	__le32 lo_priority_rx_req_cnt;
+	__le32 lo_priority_rx_denied_cnt;
+} __packed;  /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
+
+struct mvm_statistics_general {
+	struct mvm_statistics_general_common common;
+	__le32 beacon_filtered;
+	__le32 missed_beacons;
+	__s8 beacon_filter_everage_energy;
+	__s8 beacon_filter_reason;
+	__s8 beacon_filter_current_energy;
+	__s8 beacon_filter_reserved;
+	__le32 beacon_filter_delta_time;
+	struct mvm_statistics_bt_activity bt_activity;
+} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
+
+struct mvm_statistics_rx {
+	struct mvm_statistics_rx_phy ofdm;
+	struct mvm_statistics_rx_phy cck;
+	struct mvm_statistics_rx_non_phy general;
+	struct mvm_statistics_rx_ht_phy ofdm_ht;
+} __packed; /* STATISTICS_RX_API_S_VER_3 */
+
+/*
+ * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
+ *
+ * By default, uCode issues this notification after receiving a beacon
+ * while associated.  To disable this behavior, set DISABLE_NOTIF flag in the
+ * REPLY_STATISTICS_CMD 0x9c, above.
+ *
+ * Statistics counters continue to increment beacon after beacon, but are
+ * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
+ * 0x9c with CLEAR_STATS bit set (see above).
+ *
+ * uCode also issues this notification during scans.  uCode clears statistics
+ * appropriately so that each notification contains statistics for only the
+ * one channel that has just been scanned.
+ */
+
+struct iwl_notif_statistics { /* STATISTICS_NTFY_API_S_VER_8 */
+	__le32 flag;
+	struct mvm_statistics_rx rx;
+	struct mvm_statistics_tx tx;
+	struct mvm_statistics_general general;
+} __packed;
+
 #endif /* __fw_api_h__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h	2013-08-25 20:43:22.000000000 -0400
@@ -71,7 +71,13 @@
 #define MAC_INDEX_MIN_DRIVER	0
 #define NUM_MAC_INDEX_DRIVER	MAC_INDEX_AUX
 
-#define AC_NUM	4 /* Number of access categories */
+enum iwl_ac {
+	AC_BK,
+	AC_BE,
+	AC_VI,
+	AC_VO,
+	AC_NUM,
+};
 
 /**
  * enum iwl_mac_protection_flags - MAC context flags
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h	2013-08-25 20:43:22.000000000 -0400
@@ -66,6 +66,11 @@
 
 /* Power Management Commands, Responses, Notifications */
 
+/* Radio LP RX Energy Threshold measured in dBm */
+#define POWER_LPRX_RSSI_THRESHOLD	75
+#define POWER_LPRX_RSSI_THRESHOLD_MAX	94
+#define POWER_LPRX_RSSI_THRESHOLD_MIN	30
+
 /**
  * enum iwl_scan_flags - masks for power table command flags
  * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
@@ -101,20 +106,107 @@ enum iwl_power_flags {
  * @tx_data_timeout:    Minimum time (usec) from last Tx packet for AM to
  *			PSM transition - legacy PM
  * @sleep_interval:	not in use
- * @keep_alive_beacons:	not in use
+ * @skip_dtim_periods:	Number of DTIM periods to skip if Skip over DTIM flag
+ *			is set. For example, if it is required to skip over
+ *			one DTIM, this value need to be set to 2 (DTIM periods).
  * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
  *			Default: 80dbm
  */
 struct iwl_powertable_cmd {
-	/* PM_POWER_TABLE_CMD_API_S_VER_5 */
+	/* PM_POWER_TABLE_CMD_API_S_VER_6 */
 	__le16 flags;
 	u8 keep_alive_seconds;
 	u8 debug_flags;
 	__le32 rx_data_timeout;
 	__le32 tx_data_timeout;
 	__le32 sleep_interval[IWL_POWER_VEC_SIZE];
-	__le32 keep_alive_beacons;
+	__le32 skip_dtim_periods;
 	__le32 lprx_rssi_threshold;
 } __packed;
 
+/**
+ * struct iwl_beacon_filter_cmd
+ * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
+ * @id_and_color: MAC contex identifier
+ * @bf_energy_delta: Used for RSSI filtering, if in 'normal' state. Send beacon
+ *      to driver if delta in Energy values calculated for this and last
+ *      passed beacon is greater than this threshold. Zero value means that
+ *      the Energy change is ignored for beacon filtering, and beacon will
+ *      not be forced to be sent to driver regardless of this delta. Typical
+ *      energy delta 5dB.
+ * @bf_roaming_energy_delta: Used for RSSI filtering, if in 'roaming' state.
+ *      Send beacon to driver if delta in Energy values calculated for this
+ *      and last passed beacon is greater than this threshold. Zero value
+ *      means that the Energy change is ignored for beacon filtering while in
+ *      Roaming state, typical energy delta 1dB.
+ * @bf_roaming_state: Used for RSSI filtering. If absolute Energy values
+ *      calculated for current beacon is less than the threshold, use
+ *      Roaming Energy Delta Threshold, otherwise use normal Energy Delta
+ *      Threshold. Typical energy threshold is -72dBm.
+ * @bf_temperature_delta: Send Beacon to driver if delta in temperature values
+ *      calculated for this and the last passed beacon is greater than  this
+ *      threshold. Zero value means that the temperature changeis ignored for
+ *      beacon filtering; beacons will not be  forced to be sent to driver
+ *      regardless of whether its temerature has been changed.
+ * @bf_enable_beacon_filter: 1, beacon filtering is enabled; 0, disabled.
+ * @bf_filter_escape_timer: Send beacons to to driver if no beacons were passed
+ *      for a specific period of time. Units: Beacons.
+ * @ba_escape_timer: Fully receive and parse beacon if no beacons were passed
+ *      for a longer period of time then this escape-timeout. Units: Beacons.
+ * @ba_enable_beacon_abort: 1, beacon abort is enabled; 0, disabled.
+ */
+struct iwl_beacon_filter_cmd {
+	u8 bf_energy_delta;
+	u8 bf_roaming_energy_delta;
+	u8 bf_roaming_state;
+	u8 bf_temperature_delta;
+	u8 bf_enable_beacon_filter;
+	u8 bf_debug_flag;
+	__le16 reserved1;
+	__le32 bf_escape_timer;
+	__le32 ba_escape_timer;
+	u8 ba_enable_beacon_abort;
+	u8 reserved2[3];
+} __packed;
+
+/* Beacon filtering and beacon abort */
+#define IWL_BF_ENERGY_DELTA_DEFAULT 5
+#define IWL_BF_ENERGY_DELTA_MAX 255
+#define IWL_BF_ENERGY_DELTA_MIN 0
+
+#define IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT 1
+#define IWL_BF_ROAMING_ENERGY_DELTA_MAX 255
+#define IWL_BF_ROAMING_ENERGY_DELTA_MIN 0
+
+#define IWL_BF_ROAMING_STATE_DEFAULT 72
+#define IWL_BF_ROAMING_STATE_MAX 255
+#define IWL_BF_ROAMING_STATE_MIN 0
+
+#define IWL_BF_TEMPERATURE_DELTA_DEFAULT 5
+#define IWL_BF_TEMPERATURE_DELTA_MAX 255
+#define IWL_BF_TEMPERATURE_DELTA_MIN 0
+
+#define IWL_BF_ENABLE_BEACON_FILTER_DEFAULT 1
+
+#define IWL_BF_DEBUG_FLAG_DEFAULT 0
+
+#define IWL_BF_ESCAPE_TIMER_DEFAULT 50
+#define IWL_BF_ESCAPE_TIMER_MAX 1024
+#define IWL_BF_ESCAPE_TIMER_MIN 0
+
+#define IWL_BA_ESCAPE_TIMER_DEFAULT 3
+#define IWL_BA_ESCAPE_TIMER_MAX 1024
+#define IWL_BA_ESCAPE_TIMER_MIN 0
+
+#define IWL_BA_ENABLE_BEACON_ABORT_DEFAULT 1
+
+#define IWL_BF_CMD_CONFIG_DEFAULTS					\
+	.bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT,			\
+	.bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT,	\
+	.bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT,		\
+	.bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT,	\
+	.bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT,			\
+	.bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT),	\
+	.ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT)
+
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h	2013-08-25 20:43:22.000000000 -0400
@@ -69,7 +69,6 @@
 /* Scan Commands, Responses, Notifications */
 
 /* Masks for iwl_scan_channel.type flags */
-#define SCAN_CHANNEL_TYPE_PASSIVE	0
 #define SCAN_CHANNEL_TYPE_ACTIVE	BIT(0)
 #define SCAN_CHANNEL_NARROW_BAND	BIT(22)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h	2013-08-25 20:43:22.000000000 -0400
@@ -134,6 +134,7 @@ enum iwl_tx_flags {
 #define TX_CMD_SEC_WEP			0x01
 #define TX_CMD_SEC_CCM			0x02
 #define TX_CMD_SEC_TKIP			0x03
+#define TX_CMD_SEC_MSK			0x07
 #define TX_CMD_SEC_WEP_KEY_IDX_POS	6
 #define TX_CMD_SEC_WEP_KEY_IDX_MSK	0xc0
 #define TX_CMD_SEC_KEY128		0x08
@@ -227,10 +228,11 @@ struct iwl_tx_cmd {
 	__le16 len;
 	__le16 next_frame_len;
 	__le32 tx_flags;
-	/* DRAM_SCRATCH_API_U_VER_1 */
-	u8 try_cnt;
-	u8 btkill_cnt;
-	__le16 reserved;
+	struct {
+		u8 try_cnt;
+		u8 btkill_cnt;
+		__le16 reserved;
+	} scratch; /* DRAM_SCRATCH_API_U_VER_1 */
 	__le32 rate_n_flags;
 	u8 sta_id;
 	u8 sec_ctl;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/fw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/fw.c	2013-08-25 20:43:22.000000000 -0400
@@ -326,6 +326,17 @@ int iwl_run_init_mvm_ucode(struct iwl_mv
 	ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
 	WARN_ON(ret);
 
+	/*
+	 * abort after reading the nvm in case RF Kill is on, we will complete
+	 * the init seq later when RF kill will switch to off
+	 */
+	if (iwl_mvm_is_radio_killed(mvm)) {
+		IWL_DEBUG_RF_KILL(mvm,
+				  "jump over all phy activities due to RF kill\n");
+		iwl_remove_notification(&mvm->notif_wait, &calib_wait);
+		return 1;
+	}
+
 	/* Send TX valid antennas before triggering calibrations */
 	ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
 	if (ret)
@@ -388,6 +399,8 @@ out:
 int iwl_mvm_up(struct iwl_mvm *mvm)
 {
 	int ret, i;
+	struct ieee80211_channel *chan;
+	struct cfg80211_chan_def chandef;
 
 	lockdep_assert_held(&mvm->mutex);
 
@@ -400,8 +413,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
 		ret = iwl_run_init_mvm_ucode(mvm, false);
 		if (ret && !iwlmvm_mod_params.init_dbg) {
 			IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
+			/* this can't happen */
+			if (WARN_ON(ret > 0))
+				ret = -ERFKILL;
 			goto error;
 		}
+		/* should stop & start HW since that INIT image just loaded */
+		iwl_trans_stop_hw(mvm->trans, false);
+		ret = iwl_trans_start_hw(mvm->trans);
+		if (ret)
+			return ret;
 	}
 
 	if (iwlmvm_mod_params.init_dbg)
@@ -443,8 +464,22 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
 	if (ret)
 		goto error;
 
-	IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
+	/* Add all the PHY contexts */
+	chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
+	cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
+	for (i = 0; i < NUM_PHY_CTX; i++) {
+		/*
+		 * The channel used here isn't relevant as it's
+		 * going to be overwritten in the other flows.
+		 * For now use the first channel we have.
+		 */
+		ret = iwl_mvm_phy_ctxt_add(mvm, &mvm->phy_ctxts[i],
+					   &chandef, 1, 1);
+		if (ret)
+			goto error;
+	}
 
+	IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
 	return 0;
  error:
 	iwl_trans_stop_device(mvm->trans);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/mac80211.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/mac80211.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/mac80211.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/mac80211.c	2013-08-25 20:43:22.000000000 -0400
@@ -81,12 +81,12 @@
 static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
 	{
 		.max = 1,
-		.types = BIT(NL80211_IFTYPE_STATION) |
-			BIT(NL80211_IFTYPE_AP),
+		.types = BIT(NL80211_IFTYPE_STATION),
 	},
 	{
 		.max = 1,
-		.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
+		.types = BIT(NL80211_IFTYPE_AP) |
+			BIT(NL80211_IFTYPE_P2P_CLIENT) |
 			BIT(NL80211_IFTYPE_P2P_GO),
 	},
 	{
@@ -127,6 +127,17 @@ static const struct wiphy_wowlan_tcp_sup
 };
 #endif
 
+static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
+{
+	int i;
+
+	memset(mvm->phy_ctxts, 0, sizeof(mvm->phy_ctxts));
+	for (i = 0; i < NUM_PHY_CTX; i++) {
+		mvm->phy_ctxts[i].id = i;
+		mvm->phy_ctxts[i].ref = 0;
+	}
+}
+
 int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 {
 	struct ieee80211_hw *hw = mvm->hw;
@@ -141,7 +152,8 @@ int iwl_mvm_mac_setup_register(struct iw
 		    IEEE80211_HW_SUPPORTS_PS |
 		    IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
 		    IEEE80211_HW_AMPDU_AGGREGATION |
-		    IEEE80211_HW_TIMING_BEACON_ONLY;
+		    IEEE80211_HW_TIMING_BEACON_ONLY |
+		    IEEE80211_HW_CONNECTION_MONITOR;
 
 	hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
 	hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
@@ -158,7 +170,7 @@ int iwl_mvm_mac_setup_register(struct iw
 
 	hw->sta_data_size = sizeof(struct iwl_mvm_sta);
 	hw->vif_data_size = sizeof(struct iwl_mvm_vif);
-	hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt);
+	hw->chanctx_data_size = sizeof(u16);
 
 	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 		BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -193,6 +205,8 @@ int iwl_mvm_mac_setup_register(struct iw
 		hw->wiphy->n_addresses++;
 	}
 
+	iwl_mvm_reset_phy_ctxts(mvm);
+
 	/* we create the 802.11 header and a max-length SSID element */
 	hw->wiphy->max_scan_ie_len =
 		mvm->fw->ucode_capa.max_probe_length - 24 - 34;
@@ -222,20 +236,20 @@ int iwl_mvm_mac_setup_register(struct iw
 	    mvm->trans->ops->d3_suspend &&
 	    mvm->trans->ops->d3_resume &&
 	    device_can_wakeup(mvm->trans->dev)) {
-		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-					  WIPHY_WOWLAN_DISCONNECT |
-					  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
-					  WIPHY_WOWLAN_RFKILL_RELEASE;
+		mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
+				    WIPHY_WOWLAN_DISCONNECT |
+				    WIPHY_WOWLAN_EAP_IDENTITY_REQ |
+				    WIPHY_WOWLAN_RFKILL_RELEASE;
 		if (!iwlwifi_mod_params.sw_crypto)
-			hw->wiphy->wowlan.flags |=
-				WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
-				WIPHY_WOWLAN_GTK_REKEY_FAILURE |
-				WIPHY_WOWLAN_4WAY_HANDSHAKE;
+			mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+					     WIPHY_WOWLAN_GTK_REKEY_FAILURE |
+					     WIPHY_WOWLAN_4WAY_HANDSHAKE;
 
-		hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
-		hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
-		hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
-		hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
+		mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
+		mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
+		mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
+		mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
+		hw->wiphy->wowlan = &mvm->wowlan;
 	}
 #endif
 
@@ -243,7 +257,11 @@ int iwl_mvm_mac_setup_register(struct iw
 	if (ret)
 		return ret;
 
-	return ieee80211_register_hw(mvm->hw);
+	ret = ieee80211_register_hw(mvm->hw);
+	if (ret)
+		iwl_mvm_leds_exit(mvm);
+
+	return ret;
 }
 
 static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
@@ -252,8 +270,8 @@ static void iwl_mvm_mac_tx(struct ieee80
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 
-	if (test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status)) {
-		IWL_DEBUG_DROP(mvm, "Dropping - RF KILL\n");
+	if (iwl_mvm_is_radio_killed(mvm)) {
+		IWL_DEBUG_DROP(mvm, "Dropping - RF/CT KILL\n");
 		goto drop;
 	}
 
@@ -345,8 +363,7 @@ static void iwl_mvm_cleanup_iterator(voi
 	iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
 	spin_unlock_bh(&mvm->time_event_lock);
 
-	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
-		mvmvif->phy_ctxt = NULL;
+	mvmvif->phy_ctxt = NULL;
 }
 
 static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
@@ -363,12 +380,16 @@ static void iwl_mvm_restart_cleanup(stru
 		mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
 		iwl_mvm_cleanup_iterator, mvm);
 
+	mvm->p2p_device_vif = NULL;
+
+	iwl_mvm_reset_phy_ctxts(mvm);
 	memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
 	memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
 
 	ieee80211_wake_queues(mvm->hw);
 
 	mvm->vif_count = 0;
+	mvm->rx_ba_sessions = 0;
 }
 
 static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
@@ -456,6 +477,20 @@ static void iwl_mvm_power_update_iterato
 	iwl_mvm_power_update_mode(mvm, vif);
 }
 
+static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
+{
+	u16 i;
+
+	lockdep_assert_held(&mvm->mutex);
+
+	for (i = 0; i < NUM_PHY_CTX; i++)
+		if (!mvm->phy_ctxts[i].ref)
+			return &mvm->phy_ctxts[i];
+
+	IWL_ERR(mvm, "No available PHY context\n");
+	return NULL;
+}
+
 static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
 				     struct ieee80211_vif *vif)
 {
@@ -477,6 +512,27 @@ static int iwl_mvm_mac_add_interface(str
 		goto out_unlock;
 
 	/*
+	 * TODO: remove this temporary code.
+	 * Currently MVM FW supports power management only on single MAC.
+	 * If new interface added, disable PM on existing interface.
+	 * P2P device is a special case, since it is handled by FW similary to
+	 * scan. If P2P deviced is added, PM remains enabled on existing
+	 * interface.
+	 * Note: the method below does not count the new interface being added
+	 * at this moment.
+	 */
+	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
+		mvm->vif_count++;
+	if (mvm->vif_count > 1) {
+		IWL_DEBUG_MAC80211(mvm,
+				   "Disable power on existing interfaces\n");
+		ieee80211_iterate_active_interfaces_atomic(
+					    mvm->hw,
+					    IEEE80211_IFACE_ITER_NORMAL,
+					    iwl_mvm_pm_disable_iterator, mvm);
+	}
+
+	/*
 	 * The AP binding flow can be done only after the beacon
 	 * template is configured (which happens only in the mac80211
 	 * start_ap() flow), and adding the broadcast station can happen
@@ -499,27 +555,6 @@ static int iwl_mvm_mac_add_interface(str
 		goto out_unlock;
 	}
 
-	/*
-	 * TODO: remove this temporary code.
-	 * Currently MVM FW supports power management only on single MAC.
-	 * If new interface added, disable PM on existing interface.
-	 * P2P device is a special case, since it is handled by FW similary to
-	 * scan. If P2P deviced is added, PM remains enabled on existing
-	 * interface.
-	 * Note: the method below does not count the new interface being added
-	 * at this moment.
-	 */
-	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
-		mvm->vif_count++;
-	if (mvm->vif_count > 1) {
-		IWL_DEBUG_MAC80211(mvm,
-				   "Disable power on existing interfaces\n");
-		ieee80211_iterate_active_interfaces_atomic(
-					    mvm->hw,
-					    IEEE80211_IFACE_ITER_NORMAL,
-					    iwl_mvm_pm_disable_iterator, mvm);
-	}
-
 	ret = iwl_mvm_mac_ctxt_add(mvm, vif);
 	if (ret)
 		goto out_release;
@@ -530,32 +565,34 @@ static int iwl_mvm_mac_add_interface(str
 	 */
 	iwl_mvm_power_update_mode(mvm, vif);
 
+	/* beacon filtering */
+	if (!mvm->bf_allowed_vif &&
+	    vif->type == NL80211_IFTYPE_STATION && !vif->p2p){
+		mvm->bf_allowed_vif = mvmvif;
+		vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+	}
+
+	ret = iwl_mvm_disable_beacon_filter(mvm, vif);
+	if (ret)
+		goto out_release;
+
 	/*
 	 * P2P_DEVICE interface does not have a channel context assigned to it,
 	 * so a dedicated PHY context is allocated to it and the corresponding
 	 * MAC context is bound to it at this stage.
 	 */
 	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
-		struct ieee80211_channel *chan;
-		struct cfg80211_chan_def chandef;
-
-		mvmvif->phy_ctxt = &mvm->phy_ctxt_roc;
 
-		/*
-		 * The channel used here isn't relevant as it's
-		 * going to be overwritten as part of the ROC flow.
-		 * For now use the first channel we have.
-		 */
-		chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
-		cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
-		ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt,
-					   &chandef, 1, 1);
-		if (ret)
+		mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
+		if (!mvmvif->phy_ctxt) {
+			ret = -ENOSPC;
 			goto out_remove_mac;
+		}
 
+		iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
 		ret = iwl_mvm_binding_add_vif(mvm, vif);
 		if (ret)
-			goto out_remove_phy;
+			goto out_unref_phy;
 
 		ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
 		if (ret)
@@ -571,27 +608,17 @@ static int iwl_mvm_mac_add_interface(str
 
  out_unbind:
 	iwl_mvm_binding_remove_vif(mvm, vif);
- out_remove_phy:
-	iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
+ out_unref_phy:
+	iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
  out_remove_mac:
 	mvmvif->phy_ctxt = NULL;
 	iwl_mvm_mac_ctxt_remove(mvm, vif);
  out_release:
-	/*
-	 * TODO: remove this temporary code.
-	 * Currently MVM FW supports power management only on single MAC.
-	 * Check if only one additional interface remains after releasing
-	 * current one. Update power mode on the remaining interface.
-	 */
 	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
 		mvm->vif_count--;
-	IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
-			   mvm->vif_count);
-	if (mvm->vif_count == 1) {
-		ieee80211_iterate_active_interfaces(
-					mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
-					iwl_mvm_power_update_iterator, mvm);
-	}
+	ieee80211_iterate_active_interfaces(
+		mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+		iwl_mvm_power_update_iterator, mvm);
 	iwl_mvm_mac_ctxt_release(mvm, vif);
  out_unlock:
 	mutex_unlock(&mvm->mutex);
@@ -629,8 +656,7 @@ static void iwl_mvm_prepare_mac_removal(
 		 * By now, all the AC queues are empty. The AGG queues are
 		 * empty too. We already got all the Tx responses for all the
 		 * packets in the queues. The drain work can have been
-		 * triggered. Flush it. This work item takes the mutex, so kill
-		 * it before we take it.
+		 * triggered. Flush it.
 		 */
 		flush_work(&mvm->sta_drained_wk);
 	}
@@ -646,6 +672,11 @@ static void iwl_mvm_mac_remove_interface
 
 	mutex_lock(&mvm->mutex);
 
+	if (mvm->bf_allowed_vif == mvmvif) {
+		mvm->bf_allowed_vif = NULL;
+		vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
+	}
+
 	iwl_mvm_vif_dbgfs_clean(mvm, vif);
 
 	/*
@@ -661,7 +692,7 @@ static void iwl_mvm_mac_remove_interface
 		mvm->p2p_device_vif = NULL;
 		iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
 		iwl_mvm_binding_remove_vif(mvm, vif);
-		iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
+		iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
 		mvmvif->phy_ctxt = NULL;
 	}
 
@@ -748,7 +779,10 @@ static void iwl_mvm_bss_info_changed_sta
 			if (ret)
 				IWL_ERR(mvm, "failed to update quotas\n");
 		}
-	} else if (changes & BSS_CHANGED_DTIM_PERIOD) {
+		ret = iwl_mvm_power_update_mode(mvm, vif);
+		if (ret)
+			IWL_ERR(mvm, "failed to update power mode\n");
+	} else if (changes & BSS_CHANGED_BEACON_INFO) {
 		/*
 		 * We received a beacon _after_ association so
 		 * remove the session protection.
@@ -756,19 +790,9 @@ static void iwl_mvm_bss_info_changed_sta
 		iwl_mvm_remove_time_event(mvm, mvmvif,
 					  &mvmvif->time_event_data);
 	} else if (changes & BSS_CHANGED_PS) {
-		/*
-		 * TODO: remove this temporary code.
-		 * Currently MVM FW supports power management only on single
-		 * MAC. Avoid power mode update if more than one interface
-		 * is active.
-		 */
-		IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
-				   mvm->vif_count);
-		if (mvm->vif_count == 1) {
-			ret = iwl_mvm_power_update_mode(mvm, vif);
-			if (ret)
-				IWL_ERR(mvm, "failed to update power mode\n");
-		}
+		ret = iwl_mvm_power_update_mode(mvm, vif);
+		if (ret)
+			IWL_ERR(mvm, "failed to update power mode\n");
 	}
 }
 
@@ -987,6 +1011,21 @@ static int iwl_mvm_mac_sta_state(struct
 	mutex_lock(&mvm->mutex);
 	if (old_state == IEEE80211_STA_NOTEXIST &&
 	    new_state == IEEE80211_STA_NONE) {
+		/*
+		 * Firmware bug - it'll crash if the beacon interval is less
+		 * than 16. We can't avoid connecting at all, so refuse the
+		 * station state change, this will cause mac80211 to abandon
+		 * attempts to connect to this AP, and eventually wpa_s will
+		 * blacklist the AP...
+		 */
+		if (vif->type == NL80211_IFTYPE_STATION &&
+		    vif->bss_conf.beacon_int < 16) {
+			IWL_ERR(mvm,
+				"AP %pM beacon interval is %d, refusing due to firmware bug!\n",
+				sta->addr, vif->bss_conf.beacon_int);
+			ret = -EINVAL;
+			goto out_unlock;
+		}
 		ret = iwl_mvm_add_sta(mvm, vif, sta);
 	} else if (old_state == IEEE80211_STA_NONE &&
 		   new_state == IEEE80211_STA_AUTH) {
@@ -999,9 +1038,13 @@ static int iwl_mvm_mac_sta_state(struct
 					     mvmvif->phy_ctxt->channel->band);
 	} else if (old_state == IEEE80211_STA_ASSOC &&
 		   new_state == IEEE80211_STA_AUTHORIZED) {
+		/* enable beacon filtering */
+		WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif));
 		ret = 0;
 	} else if (old_state == IEEE80211_STA_AUTHORIZED &&
 		   new_state == IEEE80211_STA_ASSOC) {
+		/* disable beacon filtering */
+		WARN_ON(iwl_mvm_disable_beacon_filter(mvm, vif));
 		ret = 0;
 	} else if (old_state == IEEE80211_STA_ASSOC &&
 		   new_state == IEEE80211_STA_AUTH) {
@@ -1015,6 +1058,7 @@ static int iwl_mvm_mac_sta_state(struct
 	} else {
 		ret = -EIO;
 	}
+ out_unlock:
 	mutex_unlock(&mvm->mutex);
 
 	return ret;
@@ -1167,29 +1211,107 @@ static int iwl_mvm_roc(struct ieee80211_
 		       enum ieee80211_roc_type type)
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 	struct cfg80211_chan_def chandef;
-	int ret;
+	struct iwl_mvm_phy_ctxt *phy_ctxt;
+	int ret, i;
+
+	IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
+			   duration, type);
 
 	if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
 		IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
 		return -EINVAL;
 	}
 
-	IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
-			   duration, type);
-
 	mutex_lock(&mvm->mutex);
 
+	for (i = 0; i < NUM_PHY_CTX; i++) {
+		phy_ctxt = &mvm->phy_ctxts[i];
+		if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
+			continue;
+
+		if (phy_ctxt->ref && channel == phy_ctxt->channel) {
+			/*
+			 * Unbind the P2P_DEVICE from the current PHY context,
+			 * and if the PHY context is not used remove it.
+			 */
+			ret = iwl_mvm_binding_remove_vif(mvm, vif);
+			if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
+				goto out_unlock;
+
+			iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
+
+			/* Bind the P2P_DEVICE to the current PHY Context */
+			mvmvif->phy_ctxt = phy_ctxt;
+
+			ret = iwl_mvm_binding_add_vif(mvm, vif);
+			if (WARN(ret, "Failed binding P2P_DEVICE\n"))
+				goto out_unlock;
+
+			iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
+			goto schedule_time_event;
+		}
+	}
+
+	/* Need to update the PHY context only if the ROC channel changed */
+	if (channel == mvmvif->phy_ctxt->channel)
+		goto schedule_time_event;
+
 	cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
-	ret = iwl_mvm_phy_ctxt_changed(mvm, &mvm->phy_ctxt_roc,
-				       &chandef, 1, 1);
 
+	/*
+	 * Change the PHY context configuration as it is currently referenced
+	 * only by the P2P Device MAC
+	 */
+	if (mvmvif->phy_ctxt->ref == 1) {
+		ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
+					       &chandef, 1, 1);
+		if (ret)
+			goto out_unlock;
+	} else {
+		/*
+		 * The PHY context is shared with other MACs. Need to remove the
+		 * P2P Device from the binding, allocate an new PHY context and
+		 * create a new binding
+		 */
+		phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
+		if (!phy_ctxt) {
+			ret = -ENOSPC;
+			goto out_unlock;
+		}
+
+		ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef,
+					       1, 1);
+		if (ret) {
+			IWL_ERR(mvm, "Failed to change PHY context\n");
+			goto out_unlock;
+		}
+
+		/* Unbind the P2P_DEVICE from the current PHY context */
+		ret = iwl_mvm_binding_remove_vif(mvm, vif);
+		if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
+			goto out_unlock;
+
+		iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
+
+		/* Bind the P2P_DEVICE to the new allocated PHY context */
+		mvmvif->phy_ctxt = phy_ctxt;
+
+		ret = iwl_mvm_binding_add_vif(mvm, vif);
+		if (WARN(ret, "Failed binding P2P_DEVICE\n"))
+			goto out_unlock;
+
+		iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
+	}
+
+schedule_time_event:
 	/* Schedule the time events */
 	ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
 
+out_unlock:
 	mutex_unlock(&mvm->mutex);
 	IWL_DEBUG_MAC80211(mvm, "leave\n");
-
 	return ret;
 }
 
@@ -1211,15 +1333,30 @@ static int iwl_mvm_add_chanctx(struct ie
 			       struct ieee80211_chanctx_conf *ctx)
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
-	struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
+	u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
+	struct iwl_mvm_phy_ctxt *phy_ctxt;
 	int ret;
 
+	IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
+
 	mutex_lock(&mvm->mutex);
+	phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
+	if (!phy_ctxt) {
+		ret = -ENOSPC;
+		goto out;
+	}
 
-	IWL_DEBUG_MAC80211(mvm, "Add PHY context\n");
-	ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &ctx->def,
-				   ctx->rx_chains_static,
-				   ctx->rx_chains_dynamic);
+	ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
+				       ctx->rx_chains_static,
+				       ctx->rx_chains_dynamic);
+	if (ret) {
+		IWL_ERR(mvm, "Failed to add PHY context\n");
+		goto out;
+	}
+
+	iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
+	*phy_ctxt_id = phy_ctxt->id;
+out:
 	mutex_unlock(&mvm->mutex);
 	return ret;
 }
@@ -1228,10 +1365,11 @@ static void iwl_mvm_remove_chanctx(struc
 				   struct ieee80211_chanctx_conf *ctx)
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
-	struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
+	u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
+	struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
 
 	mutex_lock(&mvm->mutex);
-	iwl_mvm_phy_ctxt_remove(mvm, phy_ctxt);
+	iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
 	mutex_unlock(&mvm->mutex);
 }
 
@@ -1240,7 +1378,16 @@ static void iwl_mvm_change_chanctx(struc
 				   u32 changed)
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
-	struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
+	u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
+	struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
+
+	if (WARN_ONCE((phy_ctxt->ref > 1) &&
+		      (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
+				   IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
+				   IEEE80211_CHANCTX_CHANGE_RADAR)),
+		      "Cannot change PHY. Ref=%d, changed=0x%X\n",
+		      phy_ctxt->ref, changed))
+		return;
 
 	mutex_lock(&mvm->mutex);
 	iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
@@ -1254,13 +1401,14 @@ static int iwl_mvm_assign_vif_chanctx(st
 				      struct ieee80211_chanctx_conf *ctx)
 {
 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
-	struct iwl_mvm_phy_ctxt *phyctx = (void *)ctx->drv_priv;
+	u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
+	struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 	int ret;
 
 	mutex_lock(&mvm->mutex);
 
-	mvmvif->phy_ctxt = phyctx;
+	mvmvif->phy_ctxt = phy_ctxt;
 
 	switch (vif->type) {
 	case NL80211_IFTYPE_AP:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c	2013-08-25 20:43:22.000000000 -0400
@@ -193,14 +193,11 @@ static void iwl_mvm_mac_iface_iterator(v
 u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
 				struct ieee80211_vif *vif)
 {
-	u32 qmask, ac;
+	u32 qmask = 0, ac;
 
 	if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
 		return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
 
-	qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ?
-		BIT(vif->cab_queue) : 0;
-
 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
 		if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
 			qmask |= BIT(vif->hw_queue[ac]);
@@ -227,7 +224,7 @@ static int iwl_mvm_mac_ctxt_allocate_res
 		.found_vif = false,
 	};
 	u32 ac;
-	int ret;
+	int ret, i;
 
 	/*
 	 * Allocate a MAC ID and a TSF for this MAC, along with the queues
@@ -335,6 +332,9 @@ static int iwl_mvm_mac_ctxt_allocate_res
 	mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT;
 	mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
 
+	for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++)
+		mvmvif->smps_requests[i] = IEEE80211_SMPS_AUTOMATIC;
+
 	return 0;
 
 exit_fail:
@@ -362,7 +362,7 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm
 		break;
 	case NL80211_IFTYPE_AP:
 		iwl_trans_ac_txq_enable(mvm->trans, vif->cab_queue,
-					IWL_MVM_TX_FIFO_VO);
+					IWL_MVM_TX_FIFO_MCAST);
 		/* fall through */
 	default:
 		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
@@ -550,6 +550,10 @@ static void iwl_mvm_mac_ctxt_cmd_common(
 		cmd->ac[i].fifos_mask = BIT(iwl_mvm_ac_to_tx_fifo[i]);
 	}
 
+	/* in AP mode, the MCAST FIFO takes the EDCA params from VO */
+	if (vif->type == NL80211_IFTYPE_AP)
+		cmd->ac[AC_VO].fifos_mask |= BIT(IWL_MVM_TX_FIFO_MCAST);
+
 	if (vif->bss_conf.qos)
 		cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
 
@@ -861,6 +865,30 @@ int iwl_mvm_mac_ctxt_beacon_changed(stru
 	return ret;
 }
 
+struct iwl_mvm_mac_ap_iterator_data {
+	struct iwl_mvm *mvm;
+	struct ieee80211_vif *vif;
+	u32 beacon_device_ts;
+	u16 beacon_int;
+};
+
+/* Find the beacon_device_ts and beacon_int for a managed interface */
+static void iwl_mvm_mac_ap_iterator(void *_data, u8 *mac,
+				    struct ieee80211_vif *vif)
+{
+	struct iwl_mvm_mac_ap_iterator_data *data = _data;
+
+	if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc)
+		return;
+
+	/* Station client has higher priority over P2P client*/
+	if (vif->p2p && data->beacon_device_ts)
+		return;
+
+	data->beacon_device_ts = vif->bss_conf.sync_device_ts;
+	data->beacon_int = vif->bss_conf.beacon_int;
+}
+
 /*
  * Fill the specific data for mac context of type AP of P2P GO
  */
@@ -870,6 +898,11 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap
 					 bool add)
 {
 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	struct iwl_mvm_mac_ap_iterator_data data = {
+		.mvm = mvm,
+		.vif = vif,
+		.beacon_device_ts = 0
+	};
 
 	ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
 	ctxt_ap->bi_reciprocal =
@@ -883,16 +916,33 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap
 	ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
 
 	/*
-	 * Only read the system time when the MAC is being added, when we
+	 * Only set the beacon time when the MAC is being added, when we
 	 * just modify the MAC then we should keep the time -- the firmware
 	 * can otherwise have a "jumping" TBTT.
 	 */
-	if (add)
-		mvmvif->ap_beacon_time =
-			iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
+	if (add) {
+		/*
+		 * If there is a station/P2P client interface which is
+		 * associated, set the AP's TBTT far enough from the station's
+		 * TBTT. Otherwise, set it to the current system time
+		 */
+		ieee80211_iterate_active_interfaces_atomic(
+			mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
+			iwl_mvm_mac_ap_iterator, &data);
 
-	ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time);
+		if (data.beacon_device_ts) {
+			u32 rand = (prandom_u32() % (80 - 20)) + 20;
+			mvmvif->ap_beacon_time = data.beacon_device_ts +
+				ieee80211_tu_to_usec(data.beacon_int * rand /
+						     100);
+		} else {
+			mvmvif->ap_beacon_time =
+				iwl_read_prph(mvm->trans,
+					      DEVICE_SYSTEM_TIME_REG);
+		}
+	}
 
+	ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time);
 	ctxt_ap->beacon_tsf = 0; /* unused */
 
 	/* TODO: Assume that the beacon id == mac context id */
@@ -1047,3 +1097,28 @@ int iwl_mvm_rx_beacon_notif(struct iwl_m
 		     rate);
 	return 0;
 }
+
+static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
+					 struct ieee80211_vif *vif)
+{
+	u16 *id = _data;
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+	if (mvmvif->id == *id)
+		ieee80211_beacon_loss(vif);
+}
+
+int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
+				    struct iwl_rx_cmd_buffer *rxb,
+				    struct iwl_device_cmd *cmd)
+{
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
+	struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data;
+	u16 id = (u16)le32_to_cpu(missed_beacons->mac_id);
+
+	ieee80211_iterate_active_interfaces_atomic(mvm->hw,
+						   IEEE80211_IFACE_ITER_NORMAL,
+						   iwl_mvm_beacon_loss_iterator,
+						   &id);
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@ iwlmvm-y += fw.o mac80211.o nvm.o ops.o
 iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
 iwlmvm-y += scan.o time-event.o rs.o
 iwlmvm-y += power.o bt-coex.o
-iwlmvm-y += led.o
+iwlmvm-y += led.o tt.o
 iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
 iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/mvm.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/mvm.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/mvm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/mvm.h	2013-08-25 20:43:22.000000000 -0400
@@ -73,7 +73,6 @@
 #include "iwl-trans.h"
 #include "iwl-notif-wait.h"
 #include "iwl-eeprom-parse.h"
-#include "iwl-test.h"
 #include "iwl-trans.h"
 #include "sta.h"
 #include "fw-api.h"
@@ -88,6 +87,7 @@ enum iwl_mvm_tx_fifo {
 	IWL_MVM_TX_FIFO_BE,
 	IWL_MVM_TX_FIFO_VI,
 	IWL_MVM_TX_FIFO_VO,
+	IWL_MVM_TX_FIFO_MCAST = 5,
 };
 
 extern struct ieee80211_ops iwl_mvm_hw_ops;
@@ -109,6 +109,7 @@ extern struct iwl_mvm_mod_params iwlmvm_
 struct iwl_mvm_phy_ctxt {
 	u16 id;
 	u16 color;
+	u32 ref;
 
 	/*
 	 * TODO: This should probably be removed. Currently here only for rate
@@ -149,6 +150,64 @@ enum iwl_power_scheme {
 
 #define IWL_CONN_MAX_LISTEN_INTERVAL	70
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+enum iwl_dbgfs_pm_mask {
+	MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0),
+	MVM_DEBUGFS_PM_SKIP_OVER_DTIM = BIT(1),
+	MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS = BIT(2),
+	MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3),
+	MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4),
+	MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
+	MVM_DEBUGFS_PM_LPRX_ENA = BIT(6),
+	MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
+};
+
+struct iwl_dbgfs_pm {
+	u8 keep_alive_seconds;
+	u32 rx_data_timeout;
+	u32 tx_data_timeout;
+	bool skip_over_dtim;
+	u8 skip_dtim_periods;
+	bool disable_power_off;
+	bool lprx_ena;
+	u32 lprx_rssi_threshold;
+	int mask;
+};
+
+/* beacon filtering */
+
+enum iwl_dbgfs_bf_mask {
+	MVM_DEBUGFS_BF_ENERGY_DELTA = BIT(0),
+	MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA = BIT(1),
+	MVM_DEBUGFS_BF_ROAMING_STATE = BIT(2),
+	MVM_DEBUGFS_BF_TEMPERATURE_DELTA = BIT(3),
+	MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER = BIT(4),
+	MVM_DEBUGFS_BF_DEBUG_FLAG = BIT(5),
+	MVM_DEBUGFS_BF_ESCAPE_TIMER = BIT(6),
+	MVM_DEBUGFS_BA_ESCAPE_TIMER = BIT(7),
+	MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT = BIT(8),
+};
+
+struct iwl_dbgfs_bf {
+	u8 bf_energy_delta;
+	u8 bf_roaming_energy_delta;
+	u8 bf_roaming_state;
+	u8 bf_temperature_delta;
+	u8 bf_enable_beacon_filter;
+	u8 bf_debug_flag;
+	u32 bf_escape_timer;
+	u32 ba_escape_timer;
+	u8 ba_enable_beacon_abort;
+	int mask;
+};
+#endif
+
+enum iwl_mvm_smps_type_request {
+	IWL_MVM_SMPS_REQ_BT_COEX,
+	IWL_MVM_SMPS_REQ_TT,
+	NUM_IWL_MVM_SMPS_REQ,
+};
+
 /**
  * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
  * @id: between 0 and 3
@@ -163,6 +222,8 @@ enum iwl_power_scheme {
  * @bcast_sta: station used for broadcast packets. Used by the following
  *  vifs: P2P_DEVICE, GO and AP.
  * @beacon_skb: the skb used to hold the AP/GO beacon template
+ * @smps_requests: the requests of of differents parts of the driver, regard
+	the desired smps mode.
  */
 struct iwl_mvm_vif {
 	u16 id;
@@ -172,6 +233,8 @@ struct iwl_mvm_vif {
 	bool uploaded;
 	bool ap_active;
 	bool monitor_active;
+	/* indicate whether beacon filtering is enabled */
+	bool bf_enabled;
 
 	u32 ap_beacon_time;
 
@@ -214,7 +277,11 @@ struct iwl_mvm_vif {
 	struct dentry *dbgfs_dir;
 	struct dentry *dbgfs_slink;
 	void *dbgfs_data;
+	struct iwl_dbgfs_pm dbgfs_pm;
+	struct iwl_dbgfs_bf dbgfs_bf;
 #endif
+
+	enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ];
 };
 
 static inline struct iwl_mvm_vif *
@@ -223,12 +290,6 @@ iwl_mvm_vif_from_mac80211(struct ieee802
 	return (void *)vif->drv_priv;
 }
 
-enum iwl_mvm_status {
-	IWL_MVM_STATUS_HW_RFKILL,
-	IWL_MVM_STATUS_ROC_RUNNING,
-	IWL_MVM_STATUS_IN_HW_RESTART,
-};
-
 enum iwl_scan_status {
 	IWL_MVM_SCAN_NONE,
 	IWL_MVM_SCAN_OS,
@@ -246,6 +307,65 @@ struct iwl_nvm_section {
 	const u8 *data;
 };
 
+/*
+ * Tx-backoff threshold
+ * @temperature: The threshold in Celsius
+ * @backoff: The tx-backoff in uSec
+ */
+struct iwl_tt_tx_backoff {
+	s32 temperature;
+	u32 backoff;
+};
+
+#define TT_TX_BACKOFF_SIZE 6
+
+/**
+ * struct iwl_tt_params - thermal throttling parameters
+ * @ct_kill_entry: CT Kill entry threshold
+ * @ct_kill_exit: CT Kill exit threshold
+ * @ct_kill_duration: The time  intervals (in uSec) in which the driver needs
+ *	to checks whether to exit CT Kill.
+ * @dynamic_smps_entry: Dynamic SMPS entry threshold
+ * @dynamic_smps_exit: Dynamic SMPS exit threshold
+ * @tx_protection_entry: TX protection entry threshold
+ * @tx_protection_exit: TX protection exit threshold
+ * @tx_backoff: Array of thresholds for tx-backoff , in ascending order.
+ * @support_ct_kill: Support CT Kill?
+ * @support_dynamic_smps: Support dynamic SMPS?
+ * @support_tx_protection: Support tx protection?
+ * @support_tx_backoff: Support tx-backoff?
+ */
+struct iwl_tt_params {
+	s32 ct_kill_entry;
+	s32 ct_kill_exit;
+	u32 ct_kill_duration;
+	s32 dynamic_smps_entry;
+	s32 dynamic_smps_exit;
+	s32 tx_protection_entry;
+	s32 tx_protection_exit;
+	struct iwl_tt_tx_backoff tx_backoff[TT_TX_BACKOFF_SIZE];
+	bool support_ct_kill;
+	bool support_dynamic_smps;
+	bool support_tx_protection;
+	bool support_tx_backoff;
+};
+
+/**
+ * struct iwl_mvm_tt_mgnt - Thermal Throttling Management structure
+ * @ct_kill_exit: worker to exit thermal kill
+ * @dynamic_smps: Is thermal throttling enabled dynamic_smps?
+ * @tx_backoff: The current thremal throttling tx backoff in uSec.
+ * @params: Parameters to configure the thermal throttling algorithm.
+ * @throttle: Is thermal throttling is active?
+ */
+struct iwl_mvm_tt_mgmt {
+	struct delayed_work ct_kill_exit;
+	bool dynamic_smps;
+	u32 tx_backoff;
+	const struct iwl_tt_params *params;
+	bool throttle;
+};
+
 struct iwl_mvm {
 	/* for logger access */
 	struct device *dev;
@@ -266,6 +386,12 @@ struct iwl_mvm {
 
 	unsigned long status;
 
+	/*
+	 * for beacon filtering -
+	 * currently only one interface can be supported
+	 */
+	struct iwl_mvm_vif *bf_allowed_vif;
+
 	enum iwl_ucode_type cur_ucode;
 	bool ucode_loaded;
 	bool init_ucode_run;
@@ -293,6 +419,7 @@ struct iwl_mvm {
 	struct work_struct sta_drained_wk;
 	unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)];
 	atomic_t pending_frames[IWL_MVM_STATION_COUNT];
+	u8 rx_ba_sessions;
 
 	/* configured by mac80211 */
 	u32 rts_threshold;
@@ -313,7 +440,7 @@ struct iwl_mvm {
 	bool prevent_power_down_d3;
 #endif
 
-	struct iwl_mvm_phy_ctxt phy_ctxt_roc;
+	struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
 
 	struct list_head time_event_list;
 	spinlock_t time_event_lock;
@@ -337,12 +464,24 @@ struct iwl_mvm {
 	struct ieee80211_vif *p2p_device_vif;
 
 #ifdef CONFIG_PM_SLEEP
+	struct wiphy_wowlan_support wowlan;
 	int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */
+	bool d3_test_active;
+	bool store_d3_resume_sram;
+	void *d3_resume_sram;
+	u32 d3_test_pme_ptr;
+#endif
 #endif
 
 	/* BT-Coex */
 	u8 bt_kill_msk;
 	struct iwl_bt_coex_profile_notif last_bt_notif;
+
+	/* Thermal Throttling and CTkill */
+	struct iwl_mvm_tt_mgmt thermal_throttle;
+	s32 temperature;	/* Celsius */
 };
 
 /* Extract MVM priv from op_mode and _hw */
@@ -352,6 +491,19 @@ struct iwl_mvm {
 #define IWL_MAC80211_GET_MVM(_hw)			\
 	IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv))
 
+enum iwl_mvm_status {
+	IWL_MVM_STATUS_HW_RFKILL,
+	IWL_MVM_STATUS_HW_CTKILL,
+	IWL_MVM_STATUS_ROC_RUNNING,
+	IWL_MVM_STATUS_IN_HW_RESTART,
+};
+
+static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
+{
+	return test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status) ||
+	       test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
+}
+
 extern const u8 iwl_mvm_ac_to_tx_fifo[];
 
 struct iwl_rate_info {
@@ -443,8 +595,10 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm
 int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
 			     struct cfg80211_chan_def *chandef,
 			     u8 chains_static, u8 chains_dynamic);
-void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm,
-			     struct iwl_mvm_phy_ctxt *ctxt);
+void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm,
+			  struct iwl_mvm_phy_ctxt *ctxt);
+void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm,
+			    struct iwl_mvm_phy_ctxt *ctxt);
 
 /* MAC (virtual interface) programming */
 int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -459,6 +613,9 @@ int iwl_mvm_mac_ctxt_beacon_changed(stru
 int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
 			    struct iwl_rx_cmd_buffer *rxb,
 			    struct iwl_device_cmd *cmd);
+int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
+				    struct iwl_rx_cmd_buffer *rxb,
+				    struct iwl_device_cmd *cmd);
 
 /* Bindings */
 int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -523,6 +680,7 @@ void iwl_mvm_ipv6_addr_change(struct iee
 			      struct inet6_dev *idev);
 void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
 				     struct ieee80211_vif *vif, int idx);
+extern const struct file_operations iwl_dbgfs_d3_test_ops;
 
 /* BT Coex */
 int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
@@ -534,4 +692,31 @@ void iwl_mvm_bt_rssi_event(struct iwl_mv
 			   enum ieee80211_rssi_event rssi_event);
 void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 
+/* beacon filtering */
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+void
+iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
+					 struct iwl_beacon_filter_cmd *cmd);
+#else
+static inline void
+iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
+					 struct iwl_beacon_filter_cmd *cmd)
+{}
+#endif
+int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
+				 struct ieee80211_vif *vif);
+int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
+				  struct ieee80211_vif *vif);
+
+/* SMPS */
+void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+				enum iwl_mvm_smps_type_request req_type,
+				enum ieee80211_smps_mode smps_request);
+
+/* Thermal management and CT-kill */
+void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
+void iwl_mvm_tt_initialize(struct iwl_mvm *mvm);
+void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
+void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
+
 #endif /* __IWL_MVM_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/nvm.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/nvm.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/nvm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/nvm.c	2013-08-31 17:58:38.000000000 -0400
@@ -60,6 +60,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+#include <linux/firmware.h>
 #include "iwl-trans.h"
 #include "mvm.h"
 #include "iwl-eeprom-parse.h"
@@ -75,31 +76,56 @@ static const int nvm_to_read[] = {
 };
 
 /* Default NVM size to read */
-#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024);
+#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
+#define IWL_MAX_NVM_SECTION_SIZE 6000
 
-static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd,
-				     u16 offset, u16 length, u16 section)
+#define NVM_WRITE_OPCODE 1
+#define NVM_READ_OPCODE 0
+
+/*
+ * prepare the NVM host command w/ the pointers to the nvm buffer
+ * and send it to fw
+ */
+static int iwl_nvm_write_chunk(struct iwl_mvm *mvm, u16 section,
+			       u16 offset, u16 length, const u8 *data)
 {
-	cmd->offset = cpu_to_le16(offset);
-	cmd->length = cpu_to_le16(length);
-	cmd->type = cpu_to_le16(section);
+	struct iwl_nvm_access_cmd nvm_access_cmd = {
+		.offset = cpu_to_le16(offset),
+		.length = cpu_to_le16(length),
+		.type = cpu_to_le16(section),
+		.op_code = NVM_WRITE_OPCODE,
+	};
+	struct iwl_host_cmd cmd = {
+		.id = NVM_ACCESS_CMD,
+		.len = { sizeof(struct iwl_nvm_access_cmd), length },
+		.flags = CMD_SYNC | CMD_SEND_IN_RFKILL,
+		.data = { &nvm_access_cmd, data },
+		/* data may come from vmalloc, so use _DUP */
+		.dataflags = { 0, IWL_HCMD_DFL_DUP },
+	};
+
+	return iwl_mvm_send_cmd(mvm, &cmd);
 }
 
 static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
 			      u16 offset, u16 length, u8 *data)
 {
-	struct iwl_nvm_access_cmd nvm_access_cmd = {};
+	struct iwl_nvm_access_cmd nvm_access_cmd = {
+		.offset = cpu_to_le16(offset),
+		.length = cpu_to_le16(length),
+		.type = cpu_to_le16(section),
+		.op_code = NVM_READ_OPCODE,
+	};
 	struct iwl_nvm_access_resp *nvm_resp;
 	struct iwl_rx_packet *pkt;
 	struct iwl_host_cmd cmd = {
 		.id = NVM_ACCESS_CMD,
-		.flags = CMD_SYNC | CMD_WANT_SKB,
+		.flags = CMD_SYNC | CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
 		.data = { &nvm_access_cmd, },
 	};
 	int ret, bytes_read, offset_read;
 	u8 *resp_data;
 
-	iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section);
 	cmd.len[0] = sizeof(struct iwl_nvm_access_cmd);
 
 	ret = iwl_mvm_send_cmd(mvm, &cmd);
@@ -144,6 +170,30 @@ exit:
 	return ret;
 }
 
+static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section,
+				 const u8 *data, u16 length)
+{
+	int offset = 0;
+
+	/* copy data in chunks of 2k (and remainder if any) */
+
+	while (offset < length) {
+		int chunk_size, ret;
+
+		chunk_size = min(IWL_NVM_DEFAULT_CHUNK_SIZE,
+				 length - offset);
+
+		ret = iwl_nvm_write_chunk(mvm, section, offset,
+					  chunk_size, data + offset);
+		if (ret < 0)
+			return ret;
+
+		offset += chunk_size;
+	}
+
+	return 0;
+}
+
 /*
  * Reads an NVM section completely.
  * NICs prior to 7000 family doesn't have a real NVM, but just read
@@ -177,7 +227,8 @@ static int iwl_nvm_read_section(struct i
 		offset += ret;
 	}
 
-	IWL_INFO(mvm, "NVM section %d read completed\n", section);
+	IWL_DEBUG_EEPROM(mvm->trans->dev,
+			 "NVM section %d read completed\n", section);
 	return offset;
 }
 
@@ -200,7 +251,130 @@ iwl_parse_nvm_sections(struct iwl_mvm *m
 	hw = (const __le16 *)sections[NVM_SECTION_TYPE_HW].data;
 	sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
 	calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
-	return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib);
+	return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib,
+				  iwl_fw_valid_tx_ant(mvm->fw),
+				  iwl_fw_valid_rx_ant(mvm->fw));
+}
+
+#define MAX_NVM_FILE_LEN	16384
+
+/*
+ * HOW TO CREATE THE NVM FILE FORMAT:
+ * ------------------------------
+ * 1. create hex file, format:
+ *      3800 -> header
+ *      0000 -> header
+ *      5a40 -> data
+ *
+ *   rev - 6 bit (word1)
+ *   len - 10 bit (word1)
+ *   id - 4 bit (word2)
+ *   rsv - 12 bit (word2)
+ *
+ * 2. flip 8bits with 8 bits per line to get the right NVM file format
+ *
+ * 3. create binary file from the hex file
+ *
+ * 4. save as "iNVM_xxx.bin" under /lib/firmware
+ */
+static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm)
+{
+	int ret, section_id, section_size;
+	const struct firmware *fw_entry;
+	const struct {
+		__le16 word1;
+		__le16 word2;
+		u8 data[];
+	} *file_sec;
+	const u8 *eof;
+
+#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
+#define NVM_WORD2_ID(x) (x >> 12)
+
+	/*
+	 * Obtain NVM image via reject_firmware. Since we already used
+	 * reject_firmware_nowait() for the firmware binary load and only
+	 * get here after that we assume the NVM request can be satisfied
+	 * synchronously.
+	 */
+	ret = reject_firmware(&fw_entry, iwlwifi_mod_params.nvm_file,
+			       mvm->trans->dev);
+	if (ret) {
+		IWL_ERR(mvm, "ERROR: %s isn't available %d\n",
+			iwlwifi_mod_params.nvm_file, ret);
+		return ret;
+	}
+
+	IWL_INFO(mvm, "Loaded NVM file %s (%zu bytes)\n",
+		 iwlwifi_mod_params.nvm_file, fw_entry->size);
+
+	if (fw_entry->size < sizeof(*file_sec)) {
+		IWL_ERR(mvm, "NVM file too small\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (fw_entry->size > MAX_NVM_FILE_LEN) {
+		IWL_ERR(mvm, "NVM file too large\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	eof = fw_entry->data + fw_entry->size;
+
+	file_sec = (void *)fw_entry->data;
+
+	while (true) {
+		if (file_sec->data > eof) {
+			IWL_ERR(mvm,
+				"ERROR - NVM file too short for section header\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		/* check for EOF marker */
+		if (!file_sec->word1 && !file_sec->word2) {
+			ret = 0;
+			break;
+		}
+
+		section_size = 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
+		section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
+
+		if (section_size > IWL_MAX_NVM_SECTION_SIZE) {
+			IWL_ERR(mvm, "ERROR - section too large (%d)\n",
+				section_size);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!section_size) {
+			IWL_ERR(mvm, "ERROR - section empty\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		if (file_sec->data + section_size > eof) {
+			IWL_ERR(mvm,
+				"ERROR - NVM file too short for section (%d bytes)\n",
+				section_size);
+			ret = -EINVAL;
+			break;
+		}
+
+		ret = iwl_nvm_write_section(mvm, section_id, file_sec->data,
+					    section_size);
+		if (ret < 0) {
+			IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
+			break;
+		}
+
+		/* advance to the next section */
+		file_sec = (void *)(file_sec->data + section_size);
+	}
+out:
+	release_firmware(fw_entry);
+	return ret;
 }
 
 int iwl_nvm_init(struct iwl_mvm *mvm)
@@ -208,6 +382,17 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
 	int ret, i, section;
 	u8 *nvm_buffer, *temp;
 
+	/* load external NVM if configured */
+	if (iwlwifi_mod_params.nvm_file) {
+		/* move to External NVM flow */
+		ret = iwl_mvm_load_external_nvm(mvm);
+		if (ret)
+			return ret;
+	}
+
+	/* Read From FW NVM */
+	IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
+
 	/* TODO: find correct NVM max size for a section */
 	nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
 			     GFP_KERNEL);
@@ -231,8 +416,9 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
 	if (ret < 0)
 		return ret;
 
-	ret = 0;
 	mvm->nvm_data = iwl_parse_nvm_sections(mvm);
+	if (!mvm->nvm_data)
+		return -ENODATA;
 
-	return ret;
+	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/ops.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/ops.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/ops.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/ops.c	2013-08-25 20:43:22.000000000 -0400
@@ -215,17 +215,22 @@ static const struct iwl_rx_handlers iwl_
 	RX_HANDLER(REPLY_RX_PHY_CMD, iwl_mvm_rx_rx_phy_cmd, false),
 	RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, false),
 	RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, false),
+
+	RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
+	RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
+	RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true),
+
 	RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
 
 	RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
 	RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
 
-	RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
-	RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
-
 	RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
 	RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
 
+	RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif,
+		   false),
+
 	RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
 };
 #undef RX_HANDLER
@@ -288,11 +293,14 @@ static const char *iwl_mvm_cmd_strings[R
 	CMD(NET_DETECT_HOTSPOTS_CMD),
 	CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
 	CMD(CARD_STATE_NOTIFICATION),
+	CMD(MISSED_BEACONS_NOTIFICATION),
 	CMD(BT_COEX_PRIO_TABLE),
 	CMD(BT_COEX_PROT_ENV),
 	CMD(BT_PROFILE_NOTIFICATION),
 	CMD(BT_CONFIG),
 	CMD(MCAST_FILTER_CMD),
+	CMD(REPLY_BEACON_FILTERING_CMD),
+	CMD(REPLY_THERMAL_MNG_BACKOFF),
 };
 #undef CMD
 
@@ -393,10 +401,13 @@ iwl_op_mode_mvm_start(struct iwl_trans *
 	if (err)
 		goto out_free;
 
+	iwl_mvm_tt_initialize(mvm);
+
 	mutex_lock(&mvm->mutex);
 	err = iwl_run_init_mvm_ucode(mvm, true);
 	mutex_unlock(&mvm->mutex);
-	if (err && !iwlmvm_mod_params.init_dbg) {
+	/* returns 0 if successful, 1 if success but in rfkill */
+	if (err < 0 && !iwlmvm_mod_params.init_dbg) {
 		IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
 		goto out_free;
 	}
@@ -439,10 +450,16 @@ static void iwl_op_mode_mvm_stop(struct
 
 	iwl_mvm_leds_exit(mvm);
 
+	iwl_mvm_tt_exit(mvm);
+
 	ieee80211_unregister_hw(mvm->hw);
 
 	kfree(mvm->scan_cmd);
 
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
+	kfree(mvm->d3_resume_sram);
+#endif
+
 	iwl_trans_stop_hw(mvm->trans, true);
 
 	iwl_phy_db_free(mvm->phy_db);
@@ -589,6 +606,16 @@ static void iwl_mvm_wake_sw_queue(struct
 	ieee80211_wake_queue(mvm->hw, mq);
 }
 
+void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
+{
+	if (state)
+		set_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
+	else
+		clear_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
+
+	wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
+}
+
 static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
 {
 	struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
@@ -598,7 +625,7 @@ static void iwl_mvm_set_hw_rfkill_state(
 	else
 		clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
 
-	wiphy_rfkill_set_hw_state(mvm->hw->wiphy, state);
+	wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
 }
 
 static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c	2013-08-25 20:43:22.000000000 -0400
@@ -195,21 +195,6 @@ static int iwl_mvm_phy_ctxt_apply(struct
 	return ret;
 }
 
-
-struct phy_ctx_used_data {
-	unsigned long used[BITS_TO_LONGS(NUM_PHY_CTX)];
-};
-
-static void iwl_mvm_phy_ctx_used_iter(struct ieee80211_hw *hw,
-				      struct ieee80211_chanctx_conf *ctx,
-				      void *_data)
-{
-	struct phy_ctx_used_data *data = _data;
-	struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
-
-	__set_bit(phy_ctxt->id, data->used);
-}
-
 /*
  * Send a command to add a PHY context based on the current HW configuration.
  */
@@ -217,34 +202,28 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm
 			 struct cfg80211_chan_def *chandef,
 			 u8 chains_static, u8 chains_dynamic)
 {
-	struct phy_ctx_used_data data = {
-		.used = { },
-	};
-
-	/*
-	 * If this is a regular PHY context (not the ROC one)
-	 * skip the ROC PHY context's ID.
-	 */
-	if (ctxt != &mvm->phy_ctxt_roc)
-		__set_bit(mvm->phy_ctxt_roc.id, data.used);
+	int ret;
 
+	WARN_ON(!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
+		ctxt->ref);
 	lockdep_assert_held(&mvm->mutex);
-	ctxt->color++;
 
-	if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
-		ieee80211_iter_chan_contexts_atomic(
-			mvm->hw, iwl_mvm_phy_ctx_used_iter, &data);
+	ctxt->channel = chandef->chan;
+	ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
+				     chains_static, chains_dynamic,
+				     FW_CTXT_ACTION_ADD, 0);
 
-		ctxt->id = find_first_zero_bit(data.used, NUM_PHY_CTX);
-		if (WARN_ONCE(ctxt->id == NUM_PHY_CTX,
-			      "Failed to init PHY context - no free ID!\n"))
-			return -EIO;
-	}
+	return ret;
+}
 
-	ctxt->channel = chandef->chan;
-	return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
-				      chains_static, chains_dynamic,
-				      FW_CTXT_ACTION_ADD, 0);
+/*
+ * Update the number of references to the given PHY context. This is valid only
+ * in case the PHY context was already created, i.e., its reference count > 0.
+ */
+void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
+{
+	lockdep_assert_held(&mvm->mutex);
+	ctxt->ref++;
 }
 
 /*
@@ -264,23 +243,12 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_
 				      FW_CTXT_ACTION_MODIFY, 0);
 }
 
-/*
- * Send a command to the FW to remove the given phy context.
- * Once the command is sent, regardless of success or failure, the context is
- * marked as invalid
- */
-void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
+void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
 {
-	struct iwl_phy_context_cmd cmd;
-	int ret;
-
 	lockdep_assert_held(&mvm->mutex);
 
-	iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, FW_CTXT_ACTION_REMOVE, 0);
-	ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, CMD_SYNC,
-				   sizeof(struct iwl_phy_context_cmd),
-				   &cmd);
-	if (ret)
-		IWL_ERR(mvm, "Failed to send PHY remove: ctxt id=%d\n",
-			ctxt->id);
+	if (WARN_ON_ONCE(!ctxt))
+		return;
+
+	ctxt->ref--;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/power.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/power.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/power.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/power.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,6 +75,54 @@
 
 #define POWER_KEEP_ALIVE_PERIOD_SEC    25
 
+static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
+					  struct iwl_beacon_filter_cmd *cmd)
+{
+	int ret;
+
+	ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC,
+				   sizeof(struct iwl_beacon_filter_cmd), cmd);
+
+	if (!ret) {
+		IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
+				cmd->ba_enable_beacon_abort);
+		IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
+				cmd->ba_escape_timer);
+		IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
+				cmd->bf_debug_flag);
+		IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
+				cmd->bf_enable_beacon_filter);
+		IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
+				cmd->bf_energy_delta);
+		IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
+				cmd->bf_escape_timer);
+		IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
+				cmd->bf_roaming_energy_delta);
+		IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
+				cmd->bf_roaming_state);
+		IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n",
+				cmd->bf_temperature_delta);
+	}
+	return ret;
+}
+
+static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
+				       struct ieee80211_vif *vif, bool enable)
+{
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	struct iwl_beacon_filter_cmd cmd = {
+		IWL_BF_CMD_CONFIG_DEFAULTS,
+		.bf_enable_beacon_filter = 1,
+		.ba_enable_beacon_abort = enable,
+	};
+
+	if (!mvmvif->bf_enabled)
+		return 0;
+
+	iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
+	return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
+}
+
 static void iwl_mvm_power_log(struct iwl_mvm *mvm,
 			      struct iwl_powertable_cmd *cmd)
 {
@@ -89,8 +137,12 @@ static void iwl_mvm_power_log(struct iwl
 				le32_to_cpu(cmd->rx_data_timeout));
 		IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
 				le32_to_cpu(cmd->tx_data_timeout));
-		IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
-				cmd->lprx_rssi_threshold);
+		if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
+			IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
+					le32_to_cpu(cmd->skip_dtim_periods));
+		if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
+			IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
+					le32_to_cpu(cmd->lprx_rssi_threshold));
 	}
 }
 
@@ -103,6 +155,8 @@ void iwl_mvm_power_build_cmd(struct iwl_
 	int dtimper, dtimper_msec;
 	int keep_alive;
 	bool radar_detect = false;
+	struct iwl_mvm_vif *mvmvif __maybe_unused =
+		iwl_mvm_vif_from_mac80211(vif);
 
 	/*
 	 * Regardless of power management state the driver must set
@@ -115,12 +169,27 @@ void iwl_mvm_power_build_cmd(struct iwl_
 		return;
 
 	cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
+	if (!vif->bss_conf.assoc)
+		cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
+	    mvmvif->dbgfs_pm.disable_power_off)
+		cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
+#endif
 	if (!vif->bss_conf.ps)
 		return;
 
 	cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
 
+	if (vif->bss_conf.beacon_rate &&
+	    (vif->bss_conf.beacon_rate->bitrate == 10 ||
+	     vif->bss_conf.beacon_rate->bitrate == 60)) {
+		cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
+		cmd->lprx_rssi_threshold =
+			cpu_to_le32(POWER_LPRX_RSSI_THRESHOLD);
+	}
+
 	dtimper = hw->conf.ps_dtim_period ?: 1;
 
 	/* Check if radar detection is required on current channel */
@@ -135,8 +204,11 @@ void iwl_mvm_power_build_cmd(struct iwl_
 
 	/* Check skip over DTIM conditions */
 	if (!radar_detect && (dtimper <= 10) &&
-	    (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP))
+	    (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
+	     mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
 		cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
+		cmd->skip_dtim_periods = cpu_to_le32(3);
+	}
 
 	/* Check that keep alive period is at least 3 * DTIM */
 	dtimper_msec = dtimper * vif->bss_conf.beacon_int;
@@ -145,27 +217,85 @@ void iwl_mvm_power_build_cmd(struct iwl_
 	keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
 	cmd->keep_alive_seconds = keep_alive;
 
-	cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
-	cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
+	if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {
+		cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
+		cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
+	} else {
+		cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
+		cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
+	}
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
+		cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds;
+	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) {
+		if (mvmvif->dbgfs_pm.skip_over_dtim)
+			cmd->flags |=
+				cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
+		else
+			cmd->flags &=
+				cpu_to_le16(~POWER_FLAGS_SKIP_OVER_DTIM_MSK);
+	}
+	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_RX_DATA_TIMEOUT)
+		cmd->rx_data_timeout =
+			cpu_to_le32(mvmvif->dbgfs_pm.rx_data_timeout);
+	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_TX_DATA_TIMEOUT)
+		cmd->tx_data_timeout =
+			cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout);
+	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
+		cmd->skip_dtim_periods =
+			cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
+	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) {
+		if (mvmvif->dbgfs_pm.lprx_ena)
+			cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
+		else
+			cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK);
+	}
+	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD)
+		cmd->lprx_rssi_threshold =
+			cpu_to_le32(mvmvif->dbgfs_pm.lprx_rssi_threshold);
+#endif /* CONFIG_IWLWIFI_DEBUGFS */
 }
 
 int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
+	int ret;
+	bool ba_enable;
 	struct iwl_powertable_cmd cmd = {};
 
 	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
 		return 0;
 
+	/*
+	 * TODO: The following vif_count verification is temporary condition.
+	 * Avoid power mode update if more than one interface is currently
+	 * active. Remove this condition when FW will support power management
+	 * on multiple MACs.
+	 */
+	IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n",
+			mvm->vif_count);
+	if (mvm->vif_count > 1)
+		return 0;
+
 	iwl_mvm_power_build_cmd(mvm, vif, &cmd);
 	iwl_mvm_power_log(mvm, &cmd);
 
-	return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
-				    sizeof(cmd), &cmd);
+	ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
+				   sizeof(cmd), &cmd);
+	if (ret)
+		return ret;
+
+	ba_enable = !!(cmd.flags &
+		       cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
+
+	return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
 }
 
 int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
 	struct iwl_powertable_cmd cmd = {};
+	struct iwl_mvm_vif *mvmvif __maybe_unused =
+		iwl_mvm_vif_from_mac80211(vif);
 
 	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
 		return 0;
@@ -173,8 +303,82 @@ int iwl_mvm_power_disable(struct iwl_mvm
 	if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
 		cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
+	    mvmvif->dbgfs_pm.disable_power_off)
+		cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
+#endif
 	iwl_mvm_power_log(mvm, &cmd);
 
 	return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,
 				    sizeof(cmd), &cmd);
 }
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+void
+iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
+					 struct iwl_beacon_filter_cmd *cmd)
+{
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
+
+	if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA)
+		cmd->bf_energy_delta = dbgfs_bf->bf_energy_delta;
+	if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA)
+		cmd->bf_roaming_energy_delta =
+				 dbgfs_bf->bf_roaming_energy_delta;
+	if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE)
+		cmd->bf_roaming_state = dbgfs_bf->bf_roaming_state;
+	if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMPERATURE_DELTA)
+		cmd->bf_temperature_delta = dbgfs_bf->bf_temperature_delta;
+	if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG)
+		cmd->bf_debug_flag = dbgfs_bf->bf_debug_flag;
+	if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER)
+		cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer);
+	if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER)
+		cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer);
+	if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT)
+		cmd->ba_enable_beacon_abort = dbgfs_bf->ba_enable_beacon_abort;
+}
+#endif
+
+int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
+				 struct ieee80211_vif *vif)
+{
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	struct iwl_beacon_filter_cmd cmd = {
+		IWL_BF_CMD_CONFIG_DEFAULTS,
+		.bf_enable_beacon_filter = 1,
+	};
+	int ret;
+
+	if (mvmvif != mvm->bf_allowed_vif ||
+	    vif->type != NL80211_IFTYPE_STATION || vif->p2p)
+		return 0;
+
+	iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
+	ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
+
+	if (!ret)
+		mvmvif->bf_enabled = true;
+
+	return ret;
+}
+
+int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
+				  struct ieee80211_vif *vif)
+{
+	struct iwl_beacon_filter_cmd cmd = {};
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	int ret;
+
+	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
+		return 0;
+
+	ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
+
+	if (!ret)
+		mvmvif->bf_enabled = false;
+
+	return ret;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/quota.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/quota.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/quota.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/quota.c	2013-08-25 20:43:22.000000000 -0400
@@ -169,27 +169,34 @@ int iwl_mvm_update_quotas(struct iwl_mvm
 			num_active_bindings++;
 	}
 
-	if (!num_active_bindings)
-		goto send_cmd;
-
-	quota = IWL_MVM_MAX_QUOTA / num_active_bindings;
-	quota_rem = IWL_MVM_MAX_QUOTA % num_active_bindings;
+	quota = 0;
+	quota_rem = 0;
+	if (num_active_bindings) {
+		quota = IWL_MVM_MAX_QUOTA / num_active_bindings;
+		quota_rem = IWL_MVM_MAX_QUOTA % num_active_bindings;
+	}
 
 	for (idx = 0, i = 0; i < MAX_BINDINGS; i++) {
-		if (data.n_interfaces[i] <= 0)
+		if (data.colors[i] < 0)
 			continue;
 
 		cmd.quotas[idx].id_and_color =
 			cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i]));
-		cmd.quotas[idx].quota = cpu_to_le32(quota);
-		cmd.quotas[idx].max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
+
+		if (data.n_interfaces[i] <= 0) {
+			cmd.quotas[idx].quota = cpu_to_le32(0);
+			cmd.quotas[idx].max_duration = cpu_to_le32(0);
+		} else {
+			cmd.quotas[idx].quota = cpu_to_le32(quota);
+			cmd.quotas[idx].max_duration =
+				cpu_to_le32(IWL_MVM_MAX_QUOTA);
+		}
 		idx++;
 	}
 
 	/* Give the remainder of the session to the first binding */
 	le32_add_cpu(&cmd.quotas[0].quota, quota_rem);
 
-send_cmd:
 	ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
 				   sizeof(cmd), &cmd);
 	if (ret)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/rs.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/rs.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/rs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/rs.c	2013-08-25 20:43:22.000000000 -0400
@@ -401,24 +401,29 @@ static int rs_tl_turn_on_agg_for_tid(str
 
 	load = rs_tl_get_load(lq_data, tid);
 
-	if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) {
-		IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
-			     sta->addr, tid);
-		ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
-		if (ret == -EAGAIN) {
-			/*
-			 * driver and mac80211 is out of sync
-			 * this might be cause by reloading firmware
-			 * stop the tx ba session here
-			 */
-			IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n",
-				tid);
-			ieee80211_stop_tx_ba_session(sta, tid);
-		}
-	} else {
-		IWL_DEBUG_HT(mvm,
-			     "Aggregation not enabled for tid %d because load = %u\n",
-			     tid, load);
+	/*
+	 * Don't create TX aggregation sessions when in high
+	 * BT traffic, as they would just be disrupted by BT.
+	 */
+	if (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 2) {
+		IWL_DEBUG_COEX(mvm, "BT traffic (%d), no aggregation allowed\n",
+			       BT_MBOX_MSG(&mvm->last_bt_notif,
+					   3, TRAFFIC_LOAD));
+		return ret;
+	}
+
+	IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
+		     sta->addr, tid);
+	ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
+	if (ret == -EAGAIN) {
+		/*
+		 * driver and mac80211 is out of sync
+		 * this might be cause by reloading firmware
+		 * stop the tx ba session here
+		 */
+		IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n",
+			tid);
+		ieee80211_stop_tx_ba_session(sta, tid);
 	}
 	return ret;
 }
@@ -1519,6 +1524,29 @@ static int rs_move_siso_to_other(struct
 	u8 update_search_tbl_counter = 0;
 	int ret;
 
+	switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+	case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+		/* nothing */
+		break;
+	case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+		/* avoid antenna B unless MIMO */
+		if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
+			tbl->action = IWL_SISO_SWITCH_MIMO2_AB;
+		break;
+	case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+	case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+		/* avoid antenna B and MIMO */
+		valid_tx_ant =
+			first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
+		if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
+			tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+		break;
+	default:
+		IWL_ERR(mvm, "Invalid BT load %d",
+			BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
+		break;
+	}
+
 	start_action = tbl->action;
 	while (1) {
 		lq_sta->action_counter++;
@@ -1532,7 +1560,9 @@ static int rs_move_siso_to_other(struct
 			     tx_chains_num <= 2))
 				break;
 
-			if (window->success_ratio >= IWL_RS_GOOD_RATIO)
+			if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
+			    BT_MBOX_MSG(&mvm->last_bt_notif, 3,
+					TRAFFIC_LOAD) == 0)
 				break;
 
 			memcpy(search_tbl, tbl, sz);
@@ -1654,6 +1684,28 @@ static int rs_move_mimo2_to_other(struct
 	u8 update_search_tbl_counter = 0;
 	int ret;
 
+	switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+	case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+		/* nothing */
+		break;
+	case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+	case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+		/* avoid antenna B and MIMO */
+		if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
+			tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+		break;
+	case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+		/* avoid antenna B unless MIMO */
+		if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||
+		    tbl->action == IWL_MIMO2_SWITCH_SISO_C)
+			tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+		break;
+	default:
+		IWL_ERR(mvm, "Invalid BT load %d",
+			BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
+		break;
+	}
+
 	start_action = tbl->action;
 	while (1) {
 		lq_sta->action_counter++;
@@ -1791,6 +1843,28 @@ static int rs_move_mimo3_to_other(struct
 	int ret;
 	u8 update_search_tbl_counter = 0;
 
+	switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+	case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
+		/* nothing */
+		break;
+	case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
+	case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+		/* avoid antenna B and MIMO */
+		if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
+			tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+		break;
+	case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
+		/* avoid antenna B unless MIMO */
+		if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
+		    tbl->action == IWL_MIMO3_SWITCH_SISO_C)
+			tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+		break;
+	default:
+		IWL_ERR(mvm, "Invalid BT load %d",
+			BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
+		break;
+	}
+
 	start_action = tbl->action;
 	while (1) {
 		lq_sta->action_counter++;
@@ -2302,6 +2376,32 @@ static void rs_rate_scale_perform(struct
 	     (current_tpt > (100 * tbl->expected_tpt[low]))))
 		scale_action = 0;
 
+	if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >=
+	     IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
+	     (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
+		if (lq_sta->last_bt_traffic >
+		    BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+			/*
+			 * don't set scale_action, don't want to scale up if
+			 * the rate scale doesn't otherwise think that is a
+			 * good idea.
+			 */
+		} else if (lq_sta->last_bt_traffic <=
+			   BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
+			scale_action = -1;
+		}
+	}
+	lq_sta->last_bt_traffic =
+		BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD);
+
+	if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >=
+	     IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
+	     (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
+		/* search for a new modulation */
+		rs_stay_in_table(lq_sta, true);
+		goto lq_update;
+	}
+
 	switch (scale_action) {
 	case -1:
 		/* Decrease starting rate, update uCode's rate table */
@@ -2783,6 +2883,13 @@ static void rs_fill_link_cmd(struct iwl_
 
 	lq_cmd->agg_time_limit =
 		cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
+
+	/*
+	 * overwrite if needed, pass aggregation time limit
+	 * to uCode in uSec - This is racy - but heh, at least it helps...
+	 */
+	if (mvm && BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 2)
+		lq_cmd->agg_time_limit = cpu_to_le16(1200);
 }
 
 static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -3081,3 +3188,29 @@ void iwl_mvm_rate_control_unregister(voi
 {
 	ieee80211_rate_control_unregister(&rs_mvm_ops);
 }
+
+/**
+ * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable
+ * Tx protection, according to this rquest and previous requests,
+ * and send the LQ command.
+ * @lq: The LQ command
+ * @mvmsta: The station
+ * @enable: Enable Tx protection?
+ */
+int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
+			  struct iwl_mvm_sta *mvmsta, bool enable)
+{
+	lockdep_assert_held(&mvm->mutex);
+
+	if (enable) {
+		if (mvmsta->tx_protection == 0)
+			lq->flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK;
+		mvmsta->tx_protection++;
+	} else {
+		mvmsta->tx_protection--;
+		if (mvmsta->tx_protection == 0)
+			lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK;
+	}
+
+	return iwl_mvm_send_lq_cmd(mvm, lq, CMD_ASYNC, false);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/rs.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/rs.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/rs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/rs.h	2013-08-25 20:43:22.000000000 -0400
@@ -358,6 +358,18 @@ struct iwl_lq_sta {
 	u8 last_bt_traffic;
 };
 
+enum iwl_bt_coex_profile_traffic_load {
+	IWL_BT_COEX_TRAFFIC_LOAD_NONE		= 0,
+	IWL_BT_COEX_TRAFFIC_LOAD_LOW		= 1,
+	IWL_BT_COEX_TRAFFIC_LOAD_HIGH		= 2,
+	IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS	= 3,
+/*
+ * There are no more even though below is a u8, the
+ * indication from the BT device only has two bits.
+ */
+};
+
+
 static inline u8 num_of_ant(u8 mask)
 {
 	return  !!((mask) & ANT_A) +
@@ -390,4 +402,9 @@ extern int iwl_mvm_rate_control_register
  */
 extern void iwl_mvm_rate_control_unregister(void);
 
+struct iwl_mvm_sta;
+
+int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
+			  struct iwl_mvm_sta *mvmsta, bool enable);
+
 #endif /* __rs__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/rx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/rx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/rx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/rx.c	2013-08-25 20:43:22.000000000 -0400
@@ -363,3 +363,25 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *m
 					rxb, &rx_status);
 	return 0;
 }
+
+/*
+ * iwl_mvm_rx_statistics - STATISTICS_NOTIFICATION handler
+ *
+ * TODO: This handler is implemented partially.
+ * It only gets the NIC's temperature.
+ */
+int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
+			  struct iwl_rx_cmd_buffer *rxb,
+			  struct iwl_device_cmd *cmd)
+{
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
+	struct iwl_notif_statistics *stats = (void *)&pkt->data;
+	struct mvm_statistics_general_common *common = &stats->general.common;
+
+	if (mvm->temperature != le32_to_cpu(common->temperature)) {
+		mvm->temperature = le32_to_cpu(common->temperature);
+		iwl_mvm_tt_handler(mvm);
+	}
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/scan.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/scan.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/scan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/scan.c	2013-08-25 20:43:22.000000000 -0400
@@ -137,8 +137,8 @@ static void iwl_mvm_scan_fill_ssids(stru
 {
 	int fw_idx, req_idx;
 
-	fw_idx = 0;
-	for (req_idx = req->n_ssids - 1; req_idx > 0; req_idx--) {
+	for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0;
+	     req_idx--, fw_idx++) {
 		cmd->direct_scan[fw_idx].id = WLAN_EID_SSID;
 		cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len;
 		memcpy(cmd->direct_scan[fw_idx].ssid,
@@ -153,7 +153,9 @@ static void iwl_mvm_scan_fill_ssids(stru
  * just to notify that this scan is active and not passive.
  * In order to notify the FW of the number of SSIDs we wish to scan (including
  * the zero-length one), we need to set the corresponding bits in chan->type,
- * one for each SSID, and set the active bit (first).
+ * one for each SSID, and set the active bit (first). The first SSID is already
+ * included in the probe template, so we need to set only req->n_ssids - 1 bits
+ * in addition to the first bit.
  */
 static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids)
 {
@@ -176,19 +178,12 @@ static void iwl_mvm_scan_fill_channels(s
 	struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
 		(cmd->data + le16_to_cpu(cmd->tx_cmd.len));
 	int i;
-	__le32 chan_type_value;
-
-	if (req->n_ssids > 0)
-		chan_type_value = cpu_to_le32(BIT(req->n_ssids + 1) - 1);
-	else
-		chan_type_value = SCAN_CHANNEL_TYPE_PASSIVE;
 
 	for (i = 0; i < cmd->channel_count; i++) {
 		chan->channel = cpu_to_le16(req->channels[i]->hw_value);
+		chan->type = cpu_to_le32(BIT(req->n_ssids) - 1);
 		if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-			chan->type = SCAN_CHANNEL_TYPE_PASSIVE;
-		else
-			chan->type = chan_type_value;
+			chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
 		chan->active_dwell = cpu_to_le16(active_dwell);
 		chan->passive_dwell = cpu_to_le16(passive_dwell);
 		chan->iteration_count = cpu_to_le16(1);
@@ -298,12 +293,6 @@ int iwl_mvm_scan_request(struct iwl_mvm
 	else
 		cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
 
-	/*
-	 * TODO: This is a WA due to a bug in the FW AUX framework that does not
-	 * properly handle time events that fail to be scheduled
-	 */
-	cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
-
 	cmd->repeats = cpu_to_le32(1);
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/sta.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/sta.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/sta.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/sta.c	2013-08-25 20:43:22.000000000 -0400
@@ -64,6 +64,7 @@
 
 #include "mvm.h"
 #include "sta.h"
+#include "rs.h"
 
 static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
 {
@@ -217,6 +218,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
 						      mvmvif->color);
 	mvm_sta->vif = vif;
 	mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
+	mvm_sta->tx_protection = 0;
+	mvm_sta->tt_tx_protection = false;
 
 	/* HW restart, don't assume the memory has been zeroed */
 	atomic_set(&mvm->pending_frames[sta_id], 0);
@@ -226,9 +229,6 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
 		if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE)
 			mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]);
 
-	if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
-		mvm_sta->tfd_queue_msk |= BIT(vif->cab_queue);
-
 	/* for HW restart - need to reset the seq_number etc... */
 	memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data));
 
@@ -608,6 +608,8 @@ int iwl_mvm_rm_bcast_sta(struct iwl_mvm
 	return ret;
 }
 
+#define IWL_MAX_RX_BA_SESSIONS 16
+
 int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
 		       int tid, u16 ssn, bool start)
 {
@@ -618,11 +620,20 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *m
 
 	lockdep_assert_held(&mvm->mutex);
 
+	if (start && mvm->rx_ba_sessions >= IWL_MAX_RX_BA_SESSIONS) {
+		IWL_WARN(mvm, "Not enough RX BA SESSIONS\n");
+		return -ENOSPC;
+	}
+
 	cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color);
 	cmd.sta_id = mvm_sta->sta_id;
 	cmd.add_modify = STA_MODE_MODIFY;
-	cmd.add_immediate_ba_tid = (u8) tid;
-	cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
+	if (start) {
+		cmd.add_immediate_ba_tid = (u8) tid;
+		cmd.add_immediate_ba_ssn = cpu_to_le16(ssn);
+	} else {
+		cmd.remove_immediate_ba_tid = (u8) tid;
+	}
 	cmd.modify_mask = start ? STA_MODIFY_ADD_BA_TID :
 				  STA_MODIFY_REMOVE_BA_TID;
 
@@ -648,6 +659,14 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *m
 		break;
 	}
 
+	if (!ret) {
+		if (start)
+			mvm->rx_ba_sessions++;
+		else if (mvm->rx_ba_sessions > 0)
+			/* check that restart flow didn't zero the counter */
+			mvm->rx_ba_sessions--;
+	}
+
 	return ret;
 }
 
@@ -798,21 +817,23 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_m
 		min(mvmsta->max_agg_bufsize, buf_size);
 	mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
 
+	IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
+		     sta->addr, tid);
+
 	if (mvm->cfg->ht_params->use_rts_for_aggregation) {
 		/*
 		 * switch to RTS/CTS if it is the prefer protection
 		 * method for HT traffic
+		 * this function also sends the LQ command
 		 */
-		mvmsta->lq_sta.lq.flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK;
+		return iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq,
+					     mvmsta, true);
 		/*
 		 * TODO: remove the TLC_RTS flag when we tear down the last
 		 * AGG session (agg_tids_count in DVM)
 		 */
 	}
 
-	IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
-		     sta->addr, tid);
-
 	return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
 }
 
@@ -894,6 +915,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_
 	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
 	struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
 	u16 txq_id;
+	enum iwl_mvm_agg_state old_state;
 
 	/*
 	 * First set the agg state to OFF to avoid calling
@@ -903,13 +925,17 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_
 	txq_id = tid_data->txq_id;
 	IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
 			    mvmsta->sta_id, tid, txq_id, tid_data->state);
+	old_state = tid_data->state;
 	tid_data->state = IWL_AGG_OFF;
 	spin_unlock_bh(&mvmsta->lock);
 
-	if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
-		IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
+	if (old_state >= IWL_AGG_ON) {
+		if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
+			IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
+
+		iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
+	}
 
-	iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
 	mvm->queue_to_mac80211[tid_data->txq_id] =
 				IWL_INVALID_MAC80211_QUEUE;
 
@@ -1287,17 +1313,11 @@ void iwl_mvm_sta_modify_ps_wake(struct i
 	struct iwl_mvm_add_sta_cmd cmd = {
 		.add_modify = STA_MODE_MODIFY,
 		.sta_id = mvmsta->sta_id,
-		.modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
-		.sleep_state_flags = cpu_to_le16(STA_SLEEP_STATE_AWAKE),
+		.station_flags_msk = cpu_to_le32(STA_FLG_PS),
 		.mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
 	};
 	int ret;
 
-	/*
-	 * Same modify mask for sleep_tx_count and sleep_state_flags but this
-	 * should be fine since if we set the STA as "awake", then
-	 * sleep_tx_count is not relevant.
-	 */
 	ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
 	if (ret)
 		IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/sta.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/sta.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/sta.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/sta.h	2013-08-25 20:43:22.000000000 -0400
@@ -250,7 +250,6 @@ enum iwl_mvm_agg_state {
  *	the first packet to be sent in legacy HW queue in Tx AGG stop flow.
  *	Basically when next_reclaimed reaches ssn, we can tell mac80211 that
  *	we are ready to finish the Tx AGG stop / start flow.
- * @wait_for_ba: Expect block-ack before next Tx reply
  */
 struct iwl_mvm_tid_data {
 	u16 seq_number;
@@ -260,7 +259,6 @@ struct iwl_mvm_tid_data {
 	enum iwl_mvm_agg_state state;
 	u16 txq_id;
 	u16 ssn;
-	bool wait_for_ba;
 };
 
 /**
@@ -275,6 +273,8 @@ struct iwl_mvm_tid_data {
  * @lock: lock to protect the whole struct. Since %tid_data is access from Tx
  * and from Tx response flow, it needs a spinlock.
  * @tid_data: per tid data. Look at %iwl_mvm_tid_data.
+ * @tx_protection: reference counter for controlling the Tx protection.
+ * @tt_tx_protection: is thermal throttling enable Tx protection?
  *
  * When mac80211 creates a station it reserves some space (hw->sta_data_size)
  * in the structure for use by driver. This structure is placed in that
@@ -296,6 +296,10 @@ struct iwl_mvm_sta {
 #ifdef CONFIG_PM_SLEEP
 	u16 last_seq_ctl;
 #endif
+
+	/* Temporary, until the new TLC will control the Tx protection */
+	s8 tx_protection;
+	bool tt_tx_protection;
 };
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/time-event.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/time-event.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/time-event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/time-event.c	2013-08-25 20:43:22.000000000 -0400
@@ -138,6 +138,20 @@ static void iwl_mvm_roc_finished(struct
 	schedule_work(&mvm->roc_done_wk);
 }
 
+static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm,
+					struct ieee80211_vif *vif,
+					const char *errmsg)
+{
+	if (vif->type != NL80211_IFTYPE_STATION)
+		return false;
+	if (vif->bss_conf.assoc && vif->bss_conf.dtim_period)
+		return false;
+	if (errmsg)
+		IWL_ERR(mvm, "%s\n", errmsg);
+	ieee80211_connection_loss(vif);
+	return true;
+}
+
 /*
  * Handles a FW notification for an event that is known to the driver.
  *
@@ -163,8 +177,13 @@ static void iwl_mvm_te_handle_notif(stru
 	 * P2P Device discoveribility, while there are other higher priority
 	 * events in the system).
 	 */
-	WARN_ONCE(!le32_to_cpu(notif->status),
-		  "Failed to schedule time event\n");
+	if (WARN_ONCE(!le32_to_cpu(notif->status),
+		      "Failed to schedule time event\n")) {
+		if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, NULL)) {
+			iwl_mvm_te_clear_data(mvm, te_data);
+			return;
+		}
+	}
 
 	if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) {
 		IWL_DEBUG_TE(mvm,
@@ -180,14 +199,8 @@ static void iwl_mvm_te_handle_notif(stru
 		 * By now, we should have finished association
 		 * and know the dtim period.
 		 */
-		if (te_data->vif->type == NL80211_IFTYPE_STATION &&
-		    (!te_data->vif->bss_conf.assoc ||
-		     !te_data->vif->bss_conf.dtim_period)) {
-			IWL_ERR(mvm,
-				"No assocation and the time event is over already...\n");
-			ieee80211_connection_loss(te_data->vif);
-		}
-
+		iwl_mvm_te_check_disconnect(mvm, te_data->vif,
+			"No assocation and the time event is over already...");
 		iwl_mvm_te_clear_data(mvm, te_data);
 	} else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) {
 		te_data->running = true;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/tt.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/tt.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/tt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/tt.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,530 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2013 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+#include "mvm.h"
+#include "iwl-config.h"
+#include "iwl-io.h"
+#include "iwl-csr.h"
+#include "iwl-prph.h"
+
+#define OTP_DTS_DIODE_DEVIATION 96 /*in words*/
+/* VBG - Voltage Band Gap error data (temperature offset) */
+#define OTP_WP_DTS_VBG			(OTP_DTS_DIODE_DEVIATION + 2)
+#define MEAS_VBG_MIN_VAL		2300
+#define MEAS_VBG_MAX_VAL		3000
+#define MEAS_VBG_DEFAULT_VAL		2700
+#define DTS_DIODE_VALID(flags)		(flags & DTS_DIODE_REG_FLAGS_PASS_ONCE)
+#define MIN_TEMPERATURE			0
+#define MAX_TEMPERATURE			125
+#define TEMPERATURE_ERROR		(MAX_TEMPERATURE + 1)
+#define PTAT_DIGITAL_VALUE_MIN_VALUE	0
+#define PTAT_DIGITAL_VALUE_MAX_VALUE	0xFF
+#define DTS_VREFS_NUM			5
+static inline u32 DTS_DIODE_GET_VREFS_ID(u32 flags)
+{
+	return (flags & DTS_DIODE_REG_FLAGS_VREFS_ID) >>
+					DTS_DIODE_REG_FLAGS_VREFS_ID_POS;
+}
+
+#define CALC_VREFS_MIN_DIFF	43
+#define CALC_VREFS_MAX_DIFF	51
+#define CALC_LUT_SIZE		(1 + CALC_VREFS_MAX_DIFF - CALC_VREFS_MIN_DIFF)
+#define CALC_LUT_INDEX_OFFSET	CALC_VREFS_MIN_DIFF
+#define CALC_TEMPERATURE_RESULT_SHIFT_OFFSET	23
+
+/*
+ * @digital_value: The diode's digital-value sampled (temperature/voltage)
+ * @vref_low: The lower voltage-reference (the vref just below the diode's
+ *	sampled digital-value)
+ * @vref_high: The higher voltage-reference (the vref just above the diode's
+ *	sampled digital-value)
+ * @flags: bits[1:0]: The ID of the Vrefs pair (lowVref,highVref)
+ *	bits[6:2]: Reserved.
+ *	bits[7:7]: Indicates completion of at least 1 successful sample
+ *	since last DTS reset.
+ */
+struct iwl_mvm_dts_diode_bits {
+	u8 digital_value;
+	u8 vref_low;
+	u8 vref_high;
+	u8 flags;
+} __packed;
+
+union dts_diode_results {
+	u32 reg_value;
+	struct iwl_mvm_dts_diode_bits bits;
+} __packed;
+
+static s16 iwl_mvm_dts_get_volt_band_gap(struct iwl_mvm *mvm)
+{
+	struct iwl_nvm_section calib_sec;
+	const __le16 *calib;
+	u16 vbg;
+
+	/* TODO: move parsing to NVM code */
+	calib_sec = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION];
+	calib = (__le16 *)calib_sec.data;
+
+	vbg = le16_to_cpu(calib[OTP_WP_DTS_VBG]);
+
+	if (vbg < MEAS_VBG_MIN_VAL || vbg > MEAS_VBG_MAX_VAL)
+		vbg = MEAS_VBG_DEFAULT_VAL;
+
+	return vbg;
+}
+
+static u16 iwl_mvm_dts_get_ptat_deviation_offset(struct iwl_mvm *mvm)
+{
+	const u8 *calib;
+	u8 ptat, pa1, pa2, median;
+
+	/* TODO: move parsing to NVM code */
+	calib = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION].data;
+	ptat = calib[OTP_DTS_DIODE_DEVIATION];
+	pa1 = calib[OTP_DTS_DIODE_DEVIATION + 1];
+	pa2 = calib[OTP_DTS_DIODE_DEVIATION + 2];
+
+	/* get the median: */
+	if (ptat > pa1) {
+		if (ptat > pa2)
+			median = (pa1 > pa2) ? pa1 : pa2;
+		else
+			median = ptat;
+	} else {
+		if (pa1 > pa2)
+			median = (ptat > pa2) ? ptat : pa2;
+		else
+			median = pa1;
+	}
+
+	return ptat - median;
+}
+
+static u8 iwl_mvm_dts_calibrate_ptat_deviation(struct iwl_mvm *mvm, u8 value)
+{
+	/* Calibrate the PTAT digital value, based on PTAT deviation data: */
+	s16 new_val = value - iwl_mvm_dts_get_ptat_deviation_offset(mvm);
+
+	if (new_val > PTAT_DIGITAL_VALUE_MAX_VALUE)
+		new_val = PTAT_DIGITAL_VALUE_MAX_VALUE;
+	else if (new_val < PTAT_DIGITAL_VALUE_MIN_VALUE)
+		new_val = PTAT_DIGITAL_VALUE_MIN_VALUE;
+
+	return new_val;
+}
+
+static bool dts_get_adjacent_vrefs(struct iwl_mvm *mvm,
+				   union dts_diode_results *avg_ptat)
+{
+	u8 vrefs_results[DTS_VREFS_NUM];
+	u8 low_vref_index = 0, flags;
+	u32 reg;
+
+	reg = iwl_read_prph(mvm->trans, DTSC_VREF_AVG);
+	memcpy(vrefs_results, &reg, sizeof(reg));
+	reg = iwl_read_prph(mvm->trans, DTSC_VREF5_AVG);
+	vrefs_results[4] = reg & 0xff;
+
+	if (avg_ptat->bits.digital_value < vrefs_results[0] ||
+	    avg_ptat->bits.digital_value > vrefs_results[4])
+		return false;
+
+	if (avg_ptat->bits.digital_value > vrefs_results[3])
+		low_vref_index = 3;
+	else if (avg_ptat->bits.digital_value > vrefs_results[2])
+		low_vref_index = 2;
+	else if (avg_ptat->bits.digital_value > vrefs_results[1])
+		low_vref_index = 1;
+
+	avg_ptat->bits.vref_low  = vrefs_results[low_vref_index];
+	avg_ptat->bits.vref_high = vrefs_results[low_vref_index + 1];
+	flags = avg_ptat->bits.flags;
+	avg_ptat->bits.flags =
+		(flags & ~DTS_DIODE_REG_FLAGS_VREFS_ID) |
+		(low_vref_index & DTS_DIODE_REG_FLAGS_VREFS_ID);
+	return true;
+}
+
+/*
+ * return true it the results are valid, and false otherwise.
+ */
+static bool dts_read_ptat_avg_results(struct iwl_mvm *mvm,
+				      union dts_diode_results *avg_ptat)
+{
+	u32 reg;
+	u8 tmp;
+
+	/* fill the diode value and pass_once with avg-reg results */
+	reg = iwl_read_prph(mvm->trans, DTSC_PTAT_AVG);
+	reg &= DTS_DIODE_REG_DIG_VAL | DTS_DIODE_REG_PASS_ONCE;
+	avg_ptat->reg_value = reg;
+
+	/* calibrate the PTAT digital value */
+	tmp = avg_ptat->bits.digital_value;
+	tmp = iwl_mvm_dts_calibrate_ptat_deviation(mvm, tmp);
+	avg_ptat->bits.digital_value = tmp;
+
+	/*
+	 * fill vrefs fields, based on the avgVrefs results
+	 * and the diode value
+	 */
+	return dts_get_adjacent_vrefs(mvm, avg_ptat) &&
+		DTS_DIODE_VALID(avg_ptat->bits.flags);
+}
+
+static s32 calculate_nic_temperature(union dts_diode_results avg_ptat,
+				     u16 volt_band_gap)
+{
+	u32 tmp_result;
+	u8 vrefs_diff;
+	/*
+	 * For temperature calculation (at the end, shift right by 23)
+	 * LUT[(D2-D1)] = ROUND{ 2^23 / ((D2-D1)*9*10) }
+	 * (D2-D1) ==   43    44    45    46    47    48    49    50    51
+	 */
+	static const u16 calc_lut[CALC_LUT_SIZE] = {
+		2168, 2118, 2071, 2026, 1983, 1942, 1902, 1864, 1828,
+	};
+
+	/*
+	 * The diff between the high and low voltage-references is assumed
+	 * to be strictly be in range of [60,68]
+	 */
+	vrefs_diff = avg_ptat.bits.vref_high - avg_ptat.bits.vref_low;
+
+	if (vrefs_diff < CALC_VREFS_MIN_DIFF ||
+	    vrefs_diff > CALC_VREFS_MAX_DIFF)
+		return TEMPERATURE_ERROR;
+
+	/* calculate the result: */
+	tmp_result =
+		vrefs_diff * (DTS_DIODE_GET_VREFS_ID(avg_ptat.bits.flags) + 9);
+	tmp_result += avg_ptat.bits.digital_value;
+	tmp_result -= avg_ptat.bits.vref_high;
+
+	/* multiply by the LUT value (based on the diff) */
+	tmp_result *= calc_lut[vrefs_diff - CALC_LUT_INDEX_OFFSET];
+
+	/*
+	 * Get the BandGap (the voltage refereces source) error data
+	 * (temperature offset)
+	 */
+	tmp_result *= volt_band_gap;
+
+	/*
+	 * here, tmp_result value can be up to 32-bits. We want to right-shift
+	 * it *without* sign-extend.
+	 */
+	tmp_result = tmp_result >> CALC_TEMPERATURE_RESULT_SHIFT_OFFSET;
+
+	/*
+	 * at this point, tmp_result should be in the range:
+	 * 200 <= tmp_result <= 365
+	 */
+	return (s16)tmp_result - 240;
+}
+
+static s32 check_nic_temperature(struct iwl_mvm *mvm)
+{
+	u16 volt_band_gap;
+	union dts_diode_results avg_ptat;
+
+	volt_band_gap = iwl_mvm_dts_get_volt_band_gap(mvm);
+
+	/* disable DTS */
+	iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
+
+	/* SV initialization */
+	iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 1);
+	iwl_write_prph(mvm->trans, DTSC_CFG_MODE,
+		       DTSC_CFG_MODE_PERIODIC);
+
+	/* wait for results */
+	msleep(100);
+	if (!dts_read_ptat_avg_results(mvm, &avg_ptat))
+		return TEMPERATURE_ERROR;
+
+	/* disable DTS */
+	iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
+
+	return calculate_nic_temperature(avg_ptat, volt_band_gap);
+}
+
+static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
+{
+	u32 duration = mvm->thermal_throttle.params->ct_kill_duration;
+
+	IWL_ERR(mvm, "Enter CT Kill\n");
+	iwl_mvm_set_hw_ctkill_state(mvm, true);
+	schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
+			      round_jiffies_relative(duration * HZ));
+}
+
+static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm)
+{
+	IWL_ERR(mvm, "Exit CT Kill\n");
+	iwl_mvm_set_hw_ctkill_state(mvm, false);
+}
+
+static void check_exit_ctkill(struct work_struct *work)
+{
+	struct iwl_mvm_tt_mgmt *tt;
+	struct iwl_mvm *mvm;
+	u32 duration;
+	s32 temp;
+
+	tt = container_of(work, struct iwl_mvm_tt_mgmt, ct_kill_exit.work);
+	mvm = container_of(tt, struct iwl_mvm, thermal_throttle);
+
+	duration = tt->params->ct_kill_duration;
+
+	iwl_trans_start_hw(mvm->trans);
+	temp = check_nic_temperature(mvm);
+	iwl_trans_stop_hw(mvm->trans, false);
+
+	if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) {
+		IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n");
+		goto reschedule;
+	}
+	IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", temp);
+
+	if (temp <= tt->params->ct_kill_exit) {
+		iwl_mvm_exit_ctkill(mvm);
+		return;
+	}
+
+reschedule:
+	schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
+			      round_jiffies(duration * HZ));
+}
+
+static void iwl_mvm_tt_smps_iterator(void *_data, u8 *mac,
+				     struct ieee80211_vif *vif)
+{
+	struct iwl_mvm *mvm = _data;
+	enum ieee80211_smps_mode smps_mode;
+
+	lockdep_assert_held(&mvm->mutex);
+
+	if (mvm->thermal_throttle.dynamic_smps)
+		smps_mode = IEEE80211_SMPS_DYNAMIC;
+	else
+		smps_mode = IEEE80211_SMPS_AUTOMATIC;
+
+	if (vif->type != NL80211_IFTYPE_STATION)
+		return;
+
+	iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT, smps_mode);
+}
+
+static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
+{
+	struct ieee80211_sta *sta;
+	struct iwl_mvm_sta *mvmsta;
+	int i, err;
+
+	for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
+		sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
+						lockdep_is_held(&mvm->mutex));
+		if (IS_ERR_OR_NULL(sta))
+			continue;
+		mvmsta = (void *)sta->drv_priv;
+		if (enable == mvmsta->tt_tx_protection)
+			continue;
+		err = iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq,
+					    mvmsta, enable);
+		if (err) {
+			IWL_ERR(mvm, "Failed to %s Tx protection\n",
+				enable ? "enable" : "disable");
+		} else {
+			IWL_DEBUG_TEMP(mvm, "%s Tx protection\n",
+				       enable ? "Enable" : "Disable");
+			mvmsta->tt_tx_protection = enable;
+		}
+	}
+}
+
+static void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff)
+{
+	struct iwl_host_cmd cmd = {
+		.id = REPLY_THERMAL_MNG_BACKOFF,
+		.len = { sizeof(u32), },
+		.data = { &backoff, },
+		.flags = CMD_SYNC,
+	};
+
+	if (iwl_mvm_send_cmd(mvm, &cmd) == 0) {
+		IWL_DEBUG_TEMP(mvm, "Set Thermal Tx backoff to: %u\n",
+			       backoff);
+		mvm->thermal_throttle.tx_backoff = backoff;
+	} else {
+		IWL_ERR(mvm, "Failed to change Thermal Tx backoff\n");
+	}
+}
+
+void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
+{
+	const struct iwl_tt_params *params = mvm->thermal_throttle.params;
+	struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
+	s32 temperature = mvm->temperature;
+	bool throttle_enable = false;
+	int i;
+	u32 tx_backoff;
+
+	IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", mvm->temperature);
+
+	if (params->support_ct_kill && temperature >= params->ct_kill_entry) {
+		iwl_mvm_enter_ctkill(mvm);
+		return;
+	}
+
+	if (params->support_dynamic_smps) {
+		if (!tt->dynamic_smps &&
+		    temperature >= params->dynamic_smps_entry) {
+			IWL_DEBUG_TEMP(mvm, "Enable dynamic SMPS\n");
+			tt->dynamic_smps = true;
+			ieee80211_iterate_active_interfaces_atomic(
+					mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+					iwl_mvm_tt_smps_iterator, mvm);
+			throttle_enable = true;
+		} else if (tt->dynamic_smps &&
+			   temperature <= params->dynamic_smps_exit) {
+			IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n");
+			tt->dynamic_smps = false;
+			ieee80211_iterate_active_interfaces_atomic(
+					mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+					iwl_mvm_tt_smps_iterator, mvm);
+		}
+	}
+
+	if (params->support_tx_protection) {
+		if (temperature >= params->tx_protection_entry) {
+			iwl_mvm_tt_tx_protection(mvm, true);
+			throttle_enable = true;
+		} else if (temperature <= params->tx_protection_exit) {
+			iwl_mvm_tt_tx_protection(mvm, false);
+		}
+	}
+
+	if (params->support_tx_backoff) {
+		tx_backoff = 0;
+		for (i = 0; i < TT_TX_BACKOFF_SIZE; i++) {
+			if (temperature < params->tx_backoff[i].temperature)
+				break;
+			tx_backoff = params->tx_backoff[i].backoff;
+		}
+		if (tx_backoff != 0)
+			throttle_enable = true;
+		if (tt->tx_backoff != tx_backoff)
+			iwl_mvm_tt_tx_backoff(mvm, tx_backoff);
+	}
+
+	if (!tt->throttle && throttle_enable) {
+		IWL_WARN(mvm,
+			 "Due to high temperature thermal throttling initiated\n");
+		tt->throttle = true;
+	} else if (tt->throttle && !tt->dynamic_smps && tt->tx_backoff == 0 &&
+		   temperature <= params->tx_protection_exit) {
+		IWL_WARN(mvm,
+			 "Temperature is back to normal thermal throttling stopped\n");
+		tt->throttle = false;
+	}
+}
+
+static const struct iwl_tt_params iwl7000_tt_params = {
+	.ct_kill_entry = 118,
+	.ct_kill_exit = 96,
+	.ct_kill_duration = 5,
+	.dynamic_smps_entry = 114,
+	.dynamic_smps_exit = 110,
+	.tx_protection_entry = 114,
+	.tx_protection_exit = 108,
+	.tx_backoff = {
+		{.temperature = 112, .backoff = 200},
+		{.temperature = 113, .backoff = 600},
+		{.temperature = 114, .backoff = 1200},
+		{.temperature = 115, .backoff = 2000},
+		{.temperature = 116, .backoff = 4000},
+		{.temperature = 117, .backoff = 10000},
+	},
+	.support_ct_kill = true,
+	.support_dynamic_smps = true,
+	.support_tx_protection = true,
+	.support_tx_backoff = true,
+};
+
+void iwl_mvm_tt_initialize(struct iwl_mvm *mvm)
+{
+	struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
+
+	IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n");
+	tt->params = &iwl7000_tt_params;
+	tt->throttle = false;
+	INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
+}
+
+void iwl_mvm_tt_exit(struct iwl_mvm *mvm)
+{
+	cancel_delayed_work_sync(&mvm->thermal_throttle.ct_kill_exit);
+	IWL_DEBUG_TEMP(mvm, "Exit Thermal Throttling\n");
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/tx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/tx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/tx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/tx.c	2013-08-25 20:43:22.000000000 -0400
@@ -175,7 +175,7 @@ static void iwl_mvm_set_tx_cmd_rate(stru
 	 * table is controlled by LINK_QUALITY commands
 	 */
 
-	if (ieee80211_is_data(fc)) {
+	if (ieee80211_is_data(fc) && sta) {
 		tx_cmd->initial_rate_index = 0;
 		tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
 		return;
@@ -408,7 +408,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm,
 	IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id,
 		     tid, txq_id, seq_number);
 
-	/* NOTE: aggregation will need changes here (for txq id) */
 	if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id))
 		goto drop_unlock_sta;
 
@@ -610,8 +609,8 @@ static void iwl_mvm_rx_tx_cmd_single(str
 		    !(info->flags & IEEE80211_TX_STAT_ACK))
 			info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
 
-		/* W/A FW bug: seq_ctl is wrong when the queue is flushed */
-		if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
+		/* W/A FW bug: seq_ctl is wrong when the status isn't success */
+		if (status != TX_STATUS_SUCCESS) {
 			struct ieee80211_hdr *hdr = (void *)skb->data;
 			seq_ctl = le16_to_cpu(hdr->seq_ctrl);
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/utils.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/utils.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/mvm/utils.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/mvm/utils.c	2013-08-25 20:43:22.000000000 -0400
@@ -76,6 +76,11 @@ int iwl_mvm_send_cmd(struct iwl_mvm *mvm
 {
 	int ret;
 
+#if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
+	if (WARN_ON(mvm->d3_test_active))
+		return -EIO;
+#endif
+
 	/*
 	 * Synchronous commands from this op-mode must hold
 	 * the mutex, this ensures we don't try to send two
@@ -125,6 +130,11 @@ int iwl_mvm_send_cmd_status(struct iwl_m
 
 	lockdep_assert_held(&mvm->mutex);
 
+#if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
+	if (WARN_ON(mvm->d3_test_active))
+		return -EIO;
+#endif
+
 	/*
 	 * Only synchronous commands can wait for status,
 	 * we use WANT_SKB so the caller can't.
@@ -471,3 +481,34 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *
 
 	return iwl_mvm_send_cmd(mvm, &cmd);
 }
+
+/**
+ * iwl_mvm_update_smps - Get a requst to change the SMPS mode
+ * @req_type: The part of the driver who call for a change.
+ * @smps_requests: The request to change the SMPS mode.
+ *
+ * Get a requst to change the SMPS mode,
+ * and change it according to all other requests in the driver.
+ */
+void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+			 enum iwl_mvm_smps_type_request req_type,
+			 enum ieee80211_smps_mode smps_request)
+{
+	struct iwl_mvm_vif *mvmvif;
+	enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC;
+	int i;
+
+	lockdep_assert_held(&mvm->mutex);
+	mvmvif = iwl_mvm_vif_from_mac80211(vif);
+	mvmvif->smps_requests[req_type] = smps_request;
+	for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
+		if (mvmvif->smps_requests[i] == IEEE80211_SMPS_STATIC) {
+			smps_mode = IEEE80211_SMPS_STATIC;
+			break;
+		}
+		if (mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
+			smps_mode = IEEE80211_SMPS_DYNAMIC;
+	}
+
+	ieee80211_request_smps(vif, smps_mode);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/drv.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/drv.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -78,6 +78,7 @@
 
 /* Hardware specific file defines the PCI IDs table for that hardware module */
 static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
+#if IS_ENABLED(CONFIG_IWLDVM)
 	{IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */
 	{IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */
 	{IWL_PCI_DEVICE(0x4232, 0x1204, iwl5100_agn_cfg)}, /* Mini Card */
@@ -129,6 +130,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_ca
 	{IWL_PCI_DEVICE(0x423C, 0x1306, iwl5150_abg_cfg)}, /* Half Mini Card */
 	{IWL_PCI_DEVICE(0x423C, 0x1221, iwl5150_agn_cfg)}, /* Mini Card */
 	{IWL_PCI_DEVICE(0x423C, 0x1321, iwl5150_agn_cfg)}, /* Half Mini Card */
+	{IWL_PCI_DEVICE(0x423C, 0x1326, iwl5150_abg_cfg)}, /* Half Mini Card */
 
 	{IWL_PCI_DEVICE(0x423D, 0x1211, iwl5150_agn_cfg)}, /* Mini Card */
 	{IWL_PCI_DEVICE(0x423D, 0x1311, iwl5150_agn_cfg)}, /* Half Mini Card */
@@ -253,13 +255,60 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_ca
 	{IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)},
 	{IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)},
 	{IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)},
+#endif /* CONFIG_IWLDVM */
 
+#if IS_ENABLED(CONFIG_IWLMVM)
 /* 7000 Series */
 	{IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)},
-	{IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)},
 	{IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)},
-	{IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_ac_cfg)},
-	{IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)},
+
+/* 3160 Series */
+	{IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)},
+	{IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
+	{IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
+#endif /* CONFIG_IWLMVM */
 
 	{0}
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/internal.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/internal.h
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/internal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -217,6 +217,7 @@ struct iwl_pcie_txq_scratch_buf {
  * @trans_pcie: pointer back to transport (for timer)
  * @need_update: indicates need to update read/write index
  * @active: stores if queue is active
+ * @ampdu: true if this queue is an ampdu queue for an specific RA/TID
  *
  * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
  * descriptors) and required locking structures.
@@ -232,6 +233,7 @@ struct iwl_txq {
 	struct iwl_trans_pcie *trans_pcie;
 	u8 need_update;
 	u8 active;
+	bool ampdu;
 };
 
 static inline dma_addr_t
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/rx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/rx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/rx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/rx.c	2013-08-25 20:43:22.000000000 -0400
@@ -110,9 +110,10 @@
 /*
  * iwl_rxq_space - Return number of free slots available in queue.
  */
-static int iwl_rxq_space(const struct iwl_rxq *q)
+static int iwl_rxq_space(const struct iwl_rxq *rxq)
 {
-	int s = q->read - q->write;
+	int s = rxq->read - rxq->write;
+
 	if (s <= 0)
 		s += RX_QUEUE_SIZE;
 	/* keep some buffer to not confuse full and empty queue */
@@ -143,21 +144,22 @@ int iwl_pcie_rx_stop(struct iwl_trans *t
 /*
  * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue
  */
-static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q)
+static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
+				    struct iwl_rxq *rxq)
 {
 	unsigned long flags;
 	u32 reg;
 
-	spin_lock_irqsave(&q->lock, flags);
+	spin_lock_irqsave(&rxq->lock, flags);
 
-	if (q->need_update == 0)
+	if (rxq->need_update == 0)
 		goto exit_unlock;
 
 	if (trans->cfg->base_params->shadow_reg_enable) {
 		/* shadow register enabled */
 		/* Device expects a multiple of 8 */
-		q->write_actual = (q->write & ~0x7);
-		iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual);
+		rxq->write_actual = (rxq->write & ~0x7);
+		iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
 	} else {
 		struct iwl_trans_pcie *trans_pcie =
 			IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -175,22 +177,22 @@ static void iwl_pcie_rxq_inc_wr_ptr(stru
 				goto exit_unlock;
 			}
 
-			q->write_actual = (q->write & ~0x7);
+			rxq->write_actual = (rxq->write & ~0x7);
 			iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
-					q->write_actual);
+					   rxq->write_actual);
 
 		/* Else device is assumed to be awake */
 		} else {
 			/* Device expects a multiple of 8 */
-			q->write_actual = (q->write & ~0x7);
+			rxq->write_actual = (rxq->write & ~0x7);
 			iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
-				q->write_actual);
+					   rxq->write_actual);
 		}
 	}
-	q->need_update = 0;
+	rxq->need_update = 0;
 
  exit_unlock:
-	spin_unlock_irqrestore(&q->lock, flags);
+	spin_unlock_irqrestore(&rxq->lock, flags);
 }
 
 /*
@@ -355,19 +357,16 @@ static void iwl_pcie_rxq_free_rbs(struct
 	struct iwl_rxq *rxq = &trans_pcie->rxq;
 	int i;
 
-	/* Fill the rx_used queue with _all_ of the Rx buffers */
+	lockdep_assert_held(&rxq->lock);
+
 	for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
-		/* In the reset function, these buffers may have been allocated
-		 * to an SKB, so we need to unmap and free potential storage */
-		if (rxq->pool[i].page != NULL) {
-			dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
-				       PAGE_SIZE << trans_pcie->rx_page_order,
-				       DMA_FROM_DEVICE);
-			__free_pages(rxq->pool[i].page,
-				     trans_pcie->rx_page_order);
-			rxq->pool[i].page = NULL;
-		}
-		list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
+		if (!rxq->pool[i].page)
+			continue;
+		dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
+			       PAGE_SIZE << trans_pcie->rx_page_order,
+			       DMA_FROM_DEVICE);
+		__free_pages(rxq->pool[i].page, trans_pcie->rx_page_order);
+		rxq->pool[i].page = NULL;
 	}
 }
 
@@ -491,6 +490,20 @@ static void iwl_pcie_rx_hw_init(struct i
 	iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
 }
 
+static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq)
+{
+	int i;
+
+	lockdep_assert_held(&rxq->lock);
+
+	INIT_LIST_HEAD(&rxq->rx_free);
+	INIT_LIST_HEAD(&rxq->rx_used);
+	rxq->free_count = 0;
+
+	for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
+		list_add(&rxq->pool[i].list, &rxq->rx_used);
+}
+
 int iwl_pcie_rx_init(struct iwl_trans *trans)
 {
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -505,13 +518,12 @@ int iwl_pcie_rx_init(struct iwl_trans *t
 	}
 
 	spin_lock_irqsave(&rxq->lock, flags);
-	INIT_LIST_HEAD(&rxq->rx_free);
-	INIT_LIST_HEAD(&rxq->rx_used);
 
-	INIT_WORK(&trans_pcie->rx_replenish,
-		  iwl_pcie_rx_replenish_work);
+	INIT_WORK(&trans_pcie->rx_replenish, iwl_pcie_rx_replenish_work);
 
+	/* free all first - we might be reconfigured for a different size */
 	iwl_pcie_rxq_free_rbs(trans);
+	iwl_pcie_rx_init_rxb_lists(rxq);
 
 	for (i = 0; i < RX_QUEUE_SIZE; i++)
 		rxq->queue[i] = NULL;
@@ -520,7 +532,6 @@ int iwl_pcie_rx_init(struct iwl_trans *t
 	 * not restocked the Rx queue with fresh buffers */
 	rxq->read = rxq->write = 0;
 	rxq->write_actual = 0;
-	rxq->free_count = 0;
 	memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
 	spin_unlock_irqrestore(&rxq->lock, flags);
 
@@ -802,9 +813,6 @@ irqreturn_t iwl_pcie_irq_handler(int irq
 	u32 handled = 0;
 	unsigned long flags;
 	u32 i;
-#ifdef CONFIG_IWLWIFI_DEBUG
-	u32 inta_mask;
-#endif
 
 	lock_map_acquire(&trans->sync_cmd_lockdep_map);
 
@@ -826,14 +834,9 @@ irqreturn_t iwl_pcie_irq_handler(int irq
 
 	inta = trans_pcie->inta;
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-	if (iwl_have_debug_level(IWL_DL_ISR)) {
-		/* just for debug */
-		inta_mask = iwl_read32(trans, CSR_INT_MASK);
+	if (iwl_have_debug_level(IWL_DL_ISR))
 		IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n",
-			      inta, inta_mask);
-	}
-#endif
+			      inta, iwl_read32(trans, CSR_INT_MASK));
 
 	/* saved interrupt in inta variable now we can reset trans_pcie->inta */
 	trans_pcie->inta = 0;
@@ -855,12 +858,11 @@ irqreturn_t iwl_pcie_irq_handler(int irq
 		goto out;
 	}
 
-#ifdef CONFIG_IWLWIFI_DEBUG
 	if (iwl_have_debug_level(IWL_DL_ISR)) {
 		/* NIC fires this, but we don't use it, redundant with WAKEUP */
 		if (inta & CSR_INT_BIT_SCD) {
-			IWL_DEBUG_ISR(trans, "Scheduler finished to transmit "
-				      "the frame/frames.\n");
+			IWL_DEBUG_ISR(trans,
+				      "Scheduler finished to transmit the frame/frames.\n");
 			isr_stats->sch++;
 		}
 
@@ -870,7 +872,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq
 			isr_stats->alive++;
 		}
 	}
-#endif
+
 	/* Safely ignore these bits for debug checks below */
 	inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
 
@@ -1118,9 +1120,6 @@ static irqreturn_t iwl_pcie_isr(int irq,
 	struct iwl_trans *trans = data;
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 	u32 inta, inta_mask;
-#ifdef CONFIG_IWLWIFI_DEBUG
-	u32 inta_fh;
-#endif
 
 	lockdep_assert_held(&trans_pcie->irq_lock);
 
@@ -1159,13 +1158,11 @@ static irqreturn_t iwl_pcie_isr(int irq,
 		return IRQ_HANDLED;
 	}
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-	if (iwl_have_debug_level(IWL_DL_ISR)) {
-		inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS);
-		IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, "
-			      "fh 0x%08x\n", inta, inta_mask, inta_fh);
-	}
-#endif
+	if (iwl_have_debug_level(IWL_DL_ISR))
+		IWL_DEBUG_ISR(trans,
+			      "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+			      inta, inta_mask,
+			      iwl_read32(trans, CSR_FH_INT_STATUS));
 
 	trans_pcie->inta |= inta;
 	/* the thread will service interrupts and re-enable them */
@@ -1198,7 +1195,7 @@ irqreturn_t iwl_pcie_isr_ict(int irq, vo
 {
 	struct iwl_trans *trans = data;
 	struct iwl_trans_pcie *trans_pcie;
-	u32 inta, inta_mask;
+	u32 inta;
 	u32 val = 0;
 	u32 read;
 	unsigned long flags;
@@ -1226,7 +1223,6 @@ irqreturn_t iwl_pcie_isr_ict(int irq, vo
 	 * If we have something to service, the tasklet will re-enable ints.
 	 * If we *don't* have something, we'll re-enable before leaving here.
 	 */
-	inta_mask = iwl_read32(trans, CSR_INT_MASK);
 	iwl_write32(trans, CSR_INT_MASK, 0x00000000);
 
 	/* Ignore interrupt if there's nothing in NIC to service.
@@ -1271,8 +1267,11 @@ irqreturn_t iwl_pcie_isr_ict(int irq, vo
 		val |= 0x8000;
 
 	inta = (0xff & val) | ((0xff00 & val) << 16);
-	IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
-		      inta, inta_mask, val);
+	IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled(sw) 0x%08x ict 0x%08x\n",
+		      inta, trans_pcie->inta_mask, val);
+	if (iwl_have_debug_level(IWL_DL_ISR))
+		IWL_DEBUG_ISR(trans, "enabled(hw) 0x%08x\n",
+			      iwl_read32(trans, CSR_INT_MASK));
 
 	inta &= trans_pcie->inta_mask;
 	trans_pcie->inta |= inta;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/trans.c	2013-08-25 20:43:22.000000000 -0400
@@ -405,20 +405,27 @@ static int iwl_pcie_load_section(struct
 {
 	u8 *v_addr;
 	dma_addr_t p_addr;
-	u32 offset;
+	u32 offset, chunk_sz = section->len;
 	int ret = 0;
 
 	IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
 		     section_num);
 
-	v_addr = dma_alloc_coherent(trans->dev, PAGE_SIZE, &p_addr, GFP_KERNEL);
-	if (!v_addr)
-		return -ENOMEM;
+	v_addr = dma_alloc_coherent(trans->dev, chunk_sz, &p_addr,
+				    GFP_KERNEL | __GFP_NOWARN);
+	if (!v_addr) {
+		IWL_DEBUG_INFO(trans, "Falling back to small chunks of DMA\n");
+		chunk_sz = PAGE_SIZE;
+		v_addr = dma_alloc_coherent(trans->dev, chunk_sz,
+					    &p_addr, GFP_KERNEL);
+		if (!v_addr)
+			return -ENOMEM;
+	}
 
-	for (offset = 0; offset < section->len; offset += PAGE_SIZE) {
+	for (offset = 0; offset < section->len; offset += chunk_sz) {
 		u32 copy_size;
 
-		copy_size = min_t(u32, PAGE_SIZE, section->len - offset);
+		copy_size = min_t(u32, chunk_sz, section->len - offset);
 
 		memcpy(v_addr, (u8 *)section->data + offset, copy_size);
 		ret = iwl_pcie_load_firmware_chunk(trans,
@@ -432,7 +439,7 @@ static int iwl_pcie_load_section(struct
 		}
 	}
 
-	dma_free_coherent(trans->dev, PAGE_SIZE, v_addr, p_addr);
+	dma_free_coherent(trans->dev, chunk_sz, v_addr, p_addr);
 	return ret;
 }
 
@@ -571,13 +578,17 @@ static void iwl_trans_pcie_stop_device(s
 	clear_bit(STATUS_RFKILL, &trans_pcie->status);
 }
 
-static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans)
+static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test)
 {
-	/* let the ucode operate on its own */
-	iwl_write32(trans, CSR_UCODE_DRV_GP1_SET,
-		    CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
-
 	iwl_disable_interrupts(trans);
+
+	/*
+	 * in testing mode, the host stays awake and the
+	 * hardware won't be reset (not even partially)
+	 */
+	if (test)
+		return;
+
 	iwl_pcie_disable_ict(trans);
 
 	iwl_clear_bit(trans, CSR_GP_CNTRL,
@@ -596,11 +607,18 @@ static void iwl_trans_pcie_d3_suspend(st
 }
 
 static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
-				    enum iwl_d3_status *status)
+				    enum iwl_d3_status *status,
+				    bool test)
 {
 	u32 val;
 	int ret;
 
+	if (test) {
+		iwl_enable_interrupts(trans);
+		*status = IWL_D3_STATUS_ALIVE;
+		return 0;
+	}
+
 	iwl_pcie_set_pwr(trans, false);
 
 	val = iwl_read32(trans, CSR_RESET);
@@ -636,9 +654,6 @@ static int iwl_trans_pcie_d3_resume(stru
 		return ret;
 	}
 
-	iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
-		    CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
-
 	*status = IWL_D3_STATUS_ALIVE;
 	return 0;
 }
@@ -655,6 +670,11 @@ static int iwl_trans_pcie_start_hw(struc
 		return err;
 	}
 
+	/* Reset the entire device */
+	iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+
+	usleep_range(10, 15);
+
 	iwl_pcie_apm_init(trans);
 
 	/* From now on, the op_mode will be kept updated about RF kill state */
@@ -823,8 +843,9 @@ static bool iwl_trans_pcie_grab_nic_acce
 						unsigned long *flags)
 {
 	int ret;
-	struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans);
-	spin_lock_irqsave(&pcie_trans->reg_lock, *flags);
+	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+	spin_lock_irqsave(&trans_pcie->reg_lock, *flags);
 
 	/* this bit wakes up the NIC */
 	__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
@@ -860,7 +881,7 @@ static bool iwl_trans_pcie_grab_nic_acce
 			WARN_ONCE(1,
 				  "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
 				  val);
-			spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags);
+			spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
 			return false;
 		}
 	}
@@ -869,22 +890,22 @@ static bool iwl_trans_pcie_grab_nic_acce
 	 * Fool sparse by faking we release the lock - sparse will
 	 * track nic_access anyway.
 	 */
-	__release(&pcie_trans->reg_lock);
+	__release(&trans_pcie->reg_lock);
 	return true;
 }
 
 static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
 					      unsigned long *flags)
 {
-	struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans);
+	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
-	lockdep_assert_held(&pcie_trans->reg_lock);
+	lockdep_assert_held(&trans_pcie->reg_lock);
 
 	/*
 	 * Fool sparse by faking we acquiring the lock - sparse will
 	 * track nic_access anyway.
 	 */
-	__acquire(&pcie_trans->reg_lock);
+	__acquire(&trans_pcie->reg_lock);
 
 	__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
 				   CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -895,7 +916,7 @@ static void iwl_trans_pcie_release_nic_a
 	 * scheduled on different CPUs (after we drop reg_lock).
 	 */
 	mmiowb();
-	spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags);
+	spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
 }
 
 static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
@@ -917,11 +938,11 @@ static int iwl_trans_pcie_read_mem(struc
 }
 
 static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
-				    void *buf, int dwords)
+				    const void *buf, int dwords)
 {
 	unsigned long flags;
 	int offs, ret = 0;
-	u32 *vals = buf;
+	const u32 *vals = buf;
 
 	if (iwl_trans_grab_nic_access(trans, false, &flags)) {
 		iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
@@ -1481,16 +1502,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(s
 	spin_lock_init(&trans_pcie->reg_lock);
 	init_waitqueue_head(&trans_pcie->ucode_write_waitq);
 
-	/* W/A - seems to solve weird behavior. We need to remove this if we
-	 * don't want to stay in L1 all the time. This wastes a lot of power */
-	pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
-			       PCIE_LINK_STATE_CLKPM);
-
 	if (pci_enable_device(pdev)) {
 		err = -ENODEV;
 		goto out_no_pci;
 	}
 
+	/* W/A - seems to solve weird behavior. We need to remove this if we
+	 * don't want to stay in L1 all the time. This wastes a lot of power */
+	pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+			       PCIE_LINK_STATE_CLKPM);
+
 	pci_set_master(pdev);
 
 	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/tx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/tx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/iwlwifi/pcie/tx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/iwlwifi/pcie/tx.c	2013-08-25 20:43:22.000000000 -0400
@@ -224,13 +224,13 @@ static void iwl_pcie_txq_update_byte_cnt
 
 	switch (sec_ctl & TX_CMD_SEC_MSK) {
 	case TX_CMD_SEC_CCM:
-		len += CCMP_MIC_LEN;
+		len += IEEE80211_CCMP_MIC_LEN;
 		break;
 	case TX_CMD_SEC_TKIP:
-		len += TKIP_ICV_LEN;
+		len += IEEE80211_TKIP_ICV_LEN;
 		break;
 	case TX_CMD_SEC_WEP:
-		len += WEP_IV_LEN + WEP_ICV_LEN;
+		len += IEEE80211_WEP_IV_LEN + IEEE80211_WEP_ICV_LEN;
 		break;
 	}
 
@@ -576,10 +576,16 @@ static void iwl_pcie_txq_unmap(struct iw
 
 	spin_lock_bh(&txq->lock);
 	while (q->write_ptr != q->read_ptr) {
+		IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
+				   txq_id, q->read_ptr);
 		iwl_pcie_txq_free_tfd(trans, txq);
 		q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
 	}
+	txq->active = false;
 	spin_unlock_bh(&txq->lock);
+
+	/* just in case - this queue may have been stopped */
+	iwl_wake_queue(trans, txq);
 }
 
 /*
@@ -927,6 +933,12 @@ void iwl_trans_pcie_reclaim(struct iwl_t
 
 	spin_lock_bh(&txq->lock);
 
+	if (!txq->active) {
+		IWL_DEBUG_TX_QUEUES(trans, "Q %d inactive - ignoring idx %d\n",
+				    txq_id, ssn);
+		goto out;
+	}
+
 	if (txq->q.read_ptr == tfd_num)
 		goto out;
 
@@ -1045,6 +1057,10 @@ static inline void iwl_pcie_txq_set_inac
 		(1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
 }
 
+/* Receiver address (actually, Rx station's index into station table),
+ * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
+#define BUILD_RAxTID(sta_id, tid)	(((sta_id) << 4) + (tid))
+
 void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
 			       int sta_id, int tid, int frame_limit, u16 ssn)
 {
@@ -1069,6 +1085,7 @@ void iwl_trans_pcie_txq_enable(struct iw
 
 		/* enable aggregations for the queue */
 		iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
+		trans_pcie->txq[txq_id].ampdu = true;
 	} else {
 		/*
 		 * disable aggregations for the queue, this will also make the
@@ -1103,6 +1120,7 @@ void iwl_trans_pcie_txq_enable(struct iw
 		       (fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
 		       (1 << SCD_QUEUE_STTS_REG_POS_WSL) |
 		       SCD_QUEUE_STTS_REG_MSK);
+	trans_pcie->txq[txq_id].active = true;
 	IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
 			    txq_id, fifo, ssn & 0xff);
 }
@@ -1125,6 +1143,7 @@ void iwl_trans_pcie_txq_disable(struct i
 			    ARRAY_SIZE(zero_val));
 
 	iwl_pcie_txq_unmap(trans, txq_id);
+	trans_pcie->txq[txq_id].ampdu = false;
 
 	IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);
 }
@@ -1518,11 +1537,13 @@ static int iwl_pcie_send_hcmd_sync(struc
 	if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) {
 		IWL_ERR(trans, "FW error in SYNC CMD %s\n",
 			get_cmd_string(trans_pcie, cmd->id));
+		dump_stack();
 		ret = -EIO;
 		goto cancel;
 	}
 
-	if (test_bit(STATUS_RFKILL, &trans_pcie->status)) {
+	if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
+	    test_bit(STATUS_RFKILL, &trans_pcie->status)) {
 		IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n");
 		ret = -ERFKILL;
 		goto cancel;
@@ -1564,7 +1585,8 @@ int iwl_trans_pcie_send_hcmd(struct iwl_
 	if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
 		return -EIO;
 
-	if (test_bit(STATUS_RFKILL, &trans_pcie->status)) {
+	if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
+	    test_bit(STATUS_RFKILL, &trans_pcie->status)) {
 		IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
 				  cmd->id);
 		return -ERFKILL;
@@ -1592,7 +1614,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *
 	u8 wait_write_ptr = 0;
 	__le16 fc = hdr->frame_control;
 	u8 hdr_len = ieee80211_hdrlen(fc);
-	u16 __maybe_unused wifi_seq;
+	u16 wifi_seq;
 
 	txq = &trans_pcie->txq[txq_id];
 	q = &txq->q;
@@ -1609,13 +1631,11 @@ int iwl_trans_pcie_tx(struct iwl_trans *
 	 * the BA.
 	 * Check here that the packets are in the right place on the ring.
 	 */
-#ifdef CONFIG_IWLWIFI_DEBUG
 	wifi_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
-	WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) &&
-		  ((wifi_seq & 0xff) != q->write_ptr),
+	WARN_ONCE(trans_pcie->txq[txq_id].ampdu &&
+		  (wifi_seq & 0xff) != q->write_ptr,
 		  "Q: %d WiFi Seq %d tfdNum %d",
 		  txq_id, wifi_seq, q->write_ptr);
-#endif
 
 	/* Set up driver data for this TFD */
 	txq->entries[q->write_ptr].skb = skb;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -280,5 +280,6 @@ source "drivers/net/wireless/rtlwifi/Kco
 source "drivers/net/wireless/ti/Kconfig"
 source "drivers/net/wireless/zd1211rw/Kconfig"
 source "drivers/net/wireless/mwifiex/Kconfig"
+source "drivers/net/wireless/cw1200/Kconfig"
 
 endif # WLAN
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/libertas/mesh.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/libertas/mesh.c
--- linux-libre-3.10-gnu/drivers/net/wireless/libertas/mesh.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/libertas/mesh.c	2013-08-25 20:43:22.000000000 -0400
@@ -240,7 +240,7 @@ static ssize_t lbs_prb_rsp_limit_set(str
 	memset(&mesh_access, 0, sizeof(mesh_access));
 	mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
 
-	if (!strict_strtoul(buf, 10, &retry_limit))
+	if (!kstrtoul(buf, 10, &retry_limit))
 		return -ENOTSUPP;
 	if (retry_limit > 15)
 		return -ENOTSUPP;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -57,3 +57,5 @@ obj-$(CONFIG_MWIFIEX)	+= mwifiex/
 
 obj-$(CONFIG_BRCMFMAC)	+= brcm80211/
 obj-$(CONFIG_BRCMSMAC)	+= brcm80211/
+
+obj-$(CONFIG_CW1200)	+= cw1200/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/11h.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/11h.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/11h.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/11h.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,101 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11h
+ *
+ * Copyright (C) 2013, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "main.h"
+#include "fw.h"
+
+
+/* This function appends 11h info to a buffer while joining an
+ * infrastructure BSS
+ */
+static void
+mwifiex_11h_process_infra_join(struct mwifiex_private *priv, u8 **buffer,
+			       struct mwifiex_bssdescriptor *bss_desc)
+{
+	struct mwifiex_ie_types_header *ie_header;
+	struct mwifiex_ie_types_pwr_capability *cap;
+	struct mwifiex_ie_types_local_pwr_constraint *constraint;
+	struct ieee80211_supported_band *sband;
+	u8 radio_type;
+	int i;
+
+	if (!buffer || !(*buffer))
+		return;
+
+	radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+	sband = priv->wdev->wiphy->bands[radio_type];
+
+	cap = (struct mwifiex_ie_types_pwr_capability *)*buffer;
+	cap->header.type = cpu_to_le16(WLAN_EID_PWR_CAPABILITY);
+	cap->header.len = cpu_to_le16(2);
+	cap->min_pwr = 0;
+	cap->max_pwr = 0;
+	*buffer += sizeof(*cap);
+
+	constraint = (struct mwifiex_ie_types_local_pwr_constraint *)*buffer;
+	constraint->header.type = cpu_to_le16(WLAN_EID_PWR_CONSTRAINT);
+	constraint->header.len = cpu_to_le16(2);
+	constraint->chan = bss_desc->channel;
+	constraint->constraint = bss_desc->local_constraint;
+	*buffer += sizeof(*constraint);
+
+	ie_header = (struct mwifiex_ie_types_header *)*buffer;
+	ie_header->type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
+	ie_header->len  = cpu_to_le16(2 * sband->n_channels + 2);
+	*buffer += sizeof(*ie_header);
+	*(*buffer)++ = WLAN_EID_SUPPORTED_CHANNELS;
+	*(*buffer)++ = 2 * sband->n_channels;
+	for (i = 0; i < sband->n_channels; i++) {
+		*(*buffer)++ = ieee80211_frequency_to_channel(
+					sband->channels[i].center_freq);
+		*(*buffer)++ = 1; /* one channel in the subband */
+	}
+}
+
+/* Enable or disable the 11h extensions in the firmware */
+static int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag)
+{
+	u32 enable = flag;
+
+	return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+				     HostCmd_ACT_GEN_SET, DOT11H_I, &enable);
+}
+
+/* This functions processes TLV buffer for a pending BSS Join command.
+ *
+ * Activate 11h functionality in the firmware if the spectrum management
+ * capability bit is found in the network we are joining. Also, necessary
+ * TLVs are set based on requested network's 11h capability.
+ */
+void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
+			      struct mwifiex_bssdescriptor *bss_desc)
+{
+	if (bss_desc->sensed_11h) {
+		/* Activate 11h functions in firmware, turns on capability
+		 * bit
+		 */
+		mwifiex_11h_activate(priv, true);
+		bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_SPECTRUM_MGMT;
+		mwifiex_11h_process_infra_join(priv, buffer, bss_desc);
+	} else {
+		/* Deactivate 11h functions in the firmware */
+		mwifiex_11h_activate(priv, false);
+		bss_desc->cap_info_bitmap &= ~WLAN_CAPABILITY_SPECTRUM_MGMT;
+	}
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/cfg80211.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/cfg80211.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/cfg80211.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/cfg80211.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,9 @@
 #include "cfg80211.h"
 #include "main.h"
 
+static char *reg_alpha2;
+module_param(reg_alpha2, charp, 0);
+
 static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
 	{
 		.max = 2, .types = BIT(NL80211_IFTYPE_STATION),
@@ -1231,6 +1234,51 @@ static int mwifiex_cfg80211_change_beaco
 	return 0;
 }
 
+/* cfg80211 operation handler for del_station.
+ * Function deauthenticates station which value is provided in mac parameter.
+ * If mac is NULL/broadcast, all stations in associated station list are
+ * deauthenticated. If bss is not started or there are no stations in
+ * associated stations list, no action is taken.
+ */
+static int
+mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
+			     u8 *mac)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+	struct mwifiex_sta_node *sta_node;
+	unsigned long flags;
+
+	if (list_empty(&priv->sta_list) || !priv->bss_started)
+		return 0;
+
+	if (!mac || is_broadcast_ether_addr(mac)) {
+		wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__);
+		list_for_each_entry(sta_node, &priv->sta_list, list) {
+			if (mwifiex_send_cmd_sync(priv,
+						  HostCmd_CMD_UAP_STA_DEAUTH,
+						  HostCmd_ACT_GEN_SET, 0,
+						  sta_node->mac_addr))
+				return -1;
+			mwifiex_uap_del_sta_data(priv, sta_node);
+		}
+	} else {
+		wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, mac);
+		spin_lock_irqsave(&priv->sta_list_spinlock, flags);
+		sta_node = mwifiex_get_sta_entry(priv, mac);
+		spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
+		if (sta_node) {
+			if (mwifiex_send_cmd_sync(priv,
+						  HostCmd_CMD_UAP_STA_DEAUTH,
+						  HostCmd_ACT_GEN_SET, 0,
+						  sta_node->mac_addr))
+				return -1;
+			mwifiex_uap_del_sta_data(priv, sta_node);
+		}
+	}
+
+	return 0;
+}
+
 static int
 mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
 {
@@ -1668,9 +1716,9 @@ mwifiex_cfg80211_connect(struct wiphy *w
 	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 	int ret;
 
-	if (priv->bss_mode != NL80211_IFTYPE_STATION) {
+	if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
 		wiphy_err(wiphy,
-			  "%s: reject infra assoc request in non-STA mode\n",
+			  "%s: reject infra assoc request in non-STA role\n",
 			  dev->name);
 		return -EINVAL;
 	}
@@ -1859,6 +1907,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiph
 	int i, offset, ret;
 	struct ieee80211_channel *chan;
 	struct ieee_types_header *ie;
+	struct mwifiex_user_scan_cfg *user_scan_cfg;
 
 	wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
 
@@ -1869,20 +1918,22 @@ mwifiex_cfg80211_scan(struct wiphy *wiph
 		return -EBUSY;
 	}
 
-	if (priv->user_scan_cfg) {
+	/* Block scan request if scan operation or scan cleanup when interface
+	 * is disabled is in process
+	 */
+	if (priv->scan_request || priv->scan_aborting) {
 		dev_err(priv->adapter->dev, "cmd: Scan already in process..\n");
 		return -EBUSY;
 	}
 
-	priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
-				      GFP_KERNEL);
-	if (!priv->user_scan_cfg)
+	user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL);
+	if (!user_scan_cfg)
 		return -ENOMEM;
 
 	priv->scan_request = request;
 
-	priv->user_scan_cfg->num_ssids = request->n_ssids;
-	priv->user_scan_cfg->ssid_list = request->ssids;
+	user_scan_cfg->num_ssids = request->n_ssids;
+	user_scan_cfg->ssid_list = request->ssids;
 
 	if (request->ie && request->ie_len) {
 		offset = 0;
@@ -1902,25 +1953,25 @@ mwifiex_cfg80211_scan(struct wiphy *wiph
 	for (i = 0; i < min_t(u32, request->n_channels,
 			      MWIFIEX_USER_SCAN_CHAN_MAX); i++) {
 		chan = request->channels[i];
-		priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
-		priv->user_scan_cfg->chan_list[i].radio_type = chan->band;
+		user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
+		user_scan_cfg->chan_list[i].radio_type = chan->band;
 
 		if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-			priv->user_scan_cfg->chan_list[i].scan_type =
+			user_scan_cfg->chan_list[i].scan_type =
 						MWIFIEX_SCAN_TYPE_PASSIVE;
 		else
-			priv->user_scan_cfg->chan_list[i].scan_type =
+			user_scan_cfg->chan_list[i].scan_type =
 						MWIFIEX_SCAN_TYPE_ACTIVE;
 
-		priv->user_scan_cfg->chan_list[i].scan_time = 0;
+		user_scan_cfg->chan_list[i].scan_time = 0;
 	}
 
-	ret = mwifiex_scan_networks(priv, priv->user_scan_cfg);
+	ret = mwifiex_scan_networks(priv, user_scan_cfg);
+	kfree(user_scan_cfg);
 	if (ret) {
 		dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
+		priv->scan_aborting = false;
 		priv->scan_request = NULL;
-		kfree(priv->user_scan_cfg);
-		priv->user_scan_cfg = NULL;
 		return ret;
 	}
 
@@ -2419,6 +2470,7 @@ static struct cfg80211_ops mwifiex_cfg80
 	.change_beacon = mwifiex_cfg80211_change_beacon,
 	.set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
 	.set_antenna = mwifiex_cfg80211_set_antenna,
+	.del_station = mwifiex_cfg80211_del_station,
 #ifdef CONFIG_PM
 	.suspend = mwifiex_cfg80211_suspend,
 	.resume = mwifiex_cfg80211_resume,
@@ -2426,6 +2478,27 @@ static struct cfg80211_ops mwifiex_cfg80
 #endif
 };
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
+	.flags = WIPHY_WOWLAN_MAGIC_PKT,
+	.n_patterns = MWIFIEX_MAX_FILTERS,
+	.pattern_min_len = 1,
+	.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
+	.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
+};
+#endif
+
+static bool mwifiex_is_valid_alpha2(const char *alpha2)
+{
+	if (!alpha2 || strlen(alpha2) != 2)
+		return false;
+
+	if (isalpha(alpha2[0]) && isalpha(alpha2[1]))
+		return true;
+
+	return false;
+}
+
 /*
  * This function registers the device with CFG802.11 subsystem.
  *
@@ -2478,16 +2551,13 @@ int mwifiex_register_cfg80211(struct mwi
 			WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
 			WIPHY_FLAG_AP_UAPSD |
 			WIPHY_FLAG_CUSTOM_REGULATORY |
+			WIPHY_FLAG_STRICT_REGULATORY |
 			WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
 
 	wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
 
 #ifdef CONFIG_PM
-	wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
-	wiphy->wowlan.n_patterns = MWIFIEX_MAX_FILTERS;
-	wiphy->wowlan.pattern_min_len = 1;
-	wiphy->wowlan.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN;
-	wiphy->wowlan.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN;
+	wiphy->wowlan = &mwifiex_wowlan_support;
 #endif
 
 	wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
@@ -2519,10 +2589,16 @@ int mwifiex_register_cfg80211(struct mwi
 		wiphy_free(wiphy);
 		return ret;
 	}
-	country_code = mwifiex_11d_code_2_region(priv->adapter->region_code);
-	if (country_code)
-		dev_info(adapter->dev,
-			 "ignoring F/W country code %2.2s\n", country_code);
+
+	if (reg_alpha2 && mwifiex_is_valid_alpha2(reg_alpha2)) {
+		wiphy_info(wiphy, "driver hint alpha2: %2.2s\n", reg_alpha2);
+		regulatory_hint(wiphy, reg_alpha2);
+	} else {
+		country_code = mwifiex_11d_code_2_region(adapter->region_code);
+		if (country_code)
+			wiphy_info(wiphy, "ignoring F/W country code %2.2s\n",
+				   country_code);
+	}
 
 	adapter->wiphy = wiphy;
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/cfp.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/cfp.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/cfp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/cfp.c	2013-08-25 20:43:22.000000000 -0400
@@ -415,7 +415,8 @@ u32 mwifiex_get_supported_rates(struct m
 	u32 k = 0;
 	struct mwifiex_adapter *adapter = priv->adapter;
 
-	if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+	    priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
 		switch (adapter->config_bands) {
 		case BAND_B:
 			dev_dbg(adapter->dev, "info: infra band=%d "
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/cmdevt.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/cmdevt.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/cmdevt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/cmdevt.c	2013-08-25 20:43:22.000000000 -0400
@@ -570,6 +570,7 @@ int mwifiex_send_cmd_async(struct mwifie
 		case HostCmd_CMD_UAP_SYS_CONFIG:
 		case HostCmd_CMD_UAP_BSS_START:
 		case HostCmd_CMD_UAP_BSS_STOP:
+		case HostCmd_CMD_UAP_STA_DEAUTH:
 			ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
 						      cmd_oid, data_buf,
 						      cmd_ptr);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/fw.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/fw.h
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/fw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/fw.h	2013-08-25 20:43:22.000000000 -0400
@@ -245,6 +245,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define HT_BW_20    0
 #define HT_BW_40    1
 
+#define DFS_CHAN_MOVE_TIME      10000
+
 #define HostCmd_CMD_GET_HW_SPEC                       0x0003
 #define HostCmd_CMD_802_11_SCAN                       0x0006
 #define HostCmd_CMD_802_11_GET_LOG                    0x000b
@@ -271,6 +273,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define HostCmd_CMD_802_11_SUBSCRIBE_EVENT            0x0075
 #define HostCmd_CMD_802_11_TX_RATE_QUERY              0x007f
 #define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS     0x0083
+#define HostCmd_CMD_CFG_DATA                          0x008f
 #define HostCmd_CMD_VERSION_EXT                       0x0097
 #define HostCmd_CMD_MEF_CFG                           0x009a
 #define HostCmd_CMD_RSSI_INFO                         0x00a4
@@ -279,6 +282,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define HostCmd_CMD_UAP_SYS_CONFIG                    0x00b0
 #define HostCmd_CMD_UAP_BSS_START                     0x00b1
 #define HostCmd_CMD_UAP_BSS_STOP                      0x00b2
+#define HostCmd_CMD_UAP_STA_DEAUTH                    0x00b5
 #define HostCmd_CMD_11N_CFG                           0x00cd
 #define HostCmd_CMD_11N_ADDBA_REQ                     0x00ce
 #define HostCmd_CMD_11N_ADDBA_RSP                     0x00cf
@@ -436,6 +440,7 @@ enum P2P_MODES {
 #define EVENT_BW_CHANGE                 0x00000048
 #define EVENT_UAP_MIC_COUNTERMEASURES   0x0000004c
 #define EVENT_HOSTWAKE_STAIE		0x0000004d
+#define EVENT_CHANNEL_SWITCH_ANN        0x00000050
 #define EVENT_REMAIN_ON_CHAN_EXPIRED    0x0000005f
 
 #define EVENT_ID_MASK                   0xffff
@@ -464,6 +469,8 @@ enum P2P_MODES {
 #define MWIFIEX_CRITERIA_UNICAST	BIT(1)
 #define MWIFIEX_CRITERIA_MULTICAST	BIT(3)
 
+#define CFG_DATA_TYPE_CAL		2
+
 struct mwifiex_ie_types_header {
 	__le16 type;
 	__le16 len;
@@ -971,6 +978,7 @@ enum SNMP_MIB_INDEX {
 	LONG_RETRY_LIM_I = 7,
 	FRAG_THRESH_I = 8,
 	DOT11D_I = 9,
+	DOT11H_I = 10,
 };
 
 #define MAX_SNMP_BUF_SIZE   128
@@ -1197,6 +1205,23 @@ struct host_cmd_ds_amsdu_aggr_ctrl {
 	__le16 curr_buf_size;
 } __packed;
 
+struct host_cmd_ds_sta_deauth {
+	u8 mac[ETH_ALEN];
+	__le16 reason;
+} __packed;
+
+struct mwifiex_ie_types_pwr_capability {
+	struct mwifiex_ie_types_header header;
+	s8 min_pwr;
+	s8 max_pwr;
+};
+
+struct mwifiex_ie_types_local_pwr_constraint {
+	struct mwifiex_ie_types_header header;
+	u8 chan;
+	u8 constraint;
+};
+
 struct mwifiex_ie_types_wmm_param_set {
 	struct mwifiex_ie_types_header header;
 	u8 wmm_ie[1];
@@ -1573,6 +1598,12 @@ struct mwifiex_ie_list {
 	struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX];
 } __packed;
 
+struct host_cmd_ds_802_11_cfg_data {
+	__le16 action;
+	__le16 type;
+	__le16 data_len;
+} __packed;
+
 struct host_cmd_ds_command {
 	__le16 command;
 	__le16 size;
@@ -1630,7 +1661,9 @@ struct host_cmd_ds_command {
 		struct host_cmd_ds_802_11_eeprom_access eeprom;
 		struct host_cmd_ds_802_11_subsc_evt subsc_evt;
 		struct host_cmd_ds_sys_config uap_sys_config;
+		struct host_cmd_ds_sta_deauth sta_deauth;
 		struct host_cmd_11ac_vht_cfg vht_cfg;
+		struct host_cmd_ds_802_11_cfg_data cfg_data;
 	} params;
 } __packed;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/init.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/init.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/init.c	2013-08-25 20:43:22.000000000 -0400
@@ -52,87 +52,6 @@ static int mwifiex_add_bss_prio_tbl(stru
 	return 0;
 }
 
-static void scan_delay_timer_fn(unsigned long data)
-{
-	struct mwifiex_private *priv = (struct mwifiex_private *)data;
-	struct mwifiex_adapter *adapter = priv->adapter;
-	struct cmd_ctrl_node *cmd_node, *tmp_node;
-	unsigned long flags;
-
-	if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
-		/*
-		 * Abort scan operation by cancelling all pending scan
-		 * commands
-		 */
-		spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
-		list_for_each_entry_safe(cmd_node, tmp_node,
-					 &adapter->scan_pending_q, list) {
-			list_del(&cmd_node->list);
-			mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
-		}
-		spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
-
-		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
-		adapter->scan_processing = false;
-		adapter->scan_delay_cnt = 0;
-		adapter->empty_tx_q_cnt = 0;
-		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
-
-		if (priv->user_scan_cfg) {
-			if (priv->scan_request) {
-				dev_dbg(priv->adapter->dev,
-					"info: aborting scan\n");
-				cfg80211_scan_done(priv->scan_request, 1);
-				priv->scan_request = NULL;
-			} else {
-				dev_dbg(priv->adapter->dev,
-					"info: scan already aborted\n");
-			}
-
-			kfree(priv->user_scan_cfg);
-			priv->user_scan_cfg = NULL;
-		}
-		goto done;
-	}
-
-	if (!atomic_read(&priv->adapter->is_tx_received)) {
-		adapter->empty_tx_q_cnt++;
-		if (adapter->empty_tx_q_cnt == MWIFIEX_MAX_EMPTY_TX_Q_CNT) {
-			/*
-			 * No Tx traffic for 200msec. Get scan command from
-			 * scan pending queue and put to cmd pending queue to
-			 * resume scan operation
-			 */
-			adapter->scan_delay_cnt = 0;
-			adapter->empty_tx_q_cnt = 0;
-			spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
-			cmd_node = list_first_entry(&adapter->scan_pending_q,
-						    struct cmd_ctrl_node, list);
-			list_del(&cmd_node->list);
-			spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
-					       flags);
-
-			mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
-							true);
-			queue_work(adapter->workqueue, &adapter->main_work);
-			goto done;
-		}
-	} else {
-		adapter->empty_tx_q_cnt = 0;
-	}
-
-	/* Delay scan operation further by 20msec */
-	mod_timer(&priv->scan_delay_timer, jiffies +
-		  msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
-	adapter->scan_delay_cnt++;
-
-done:
-	if (atomic_read(&priv->adapter->is_tx_received))
-		atomic_set(&priv->adapter->is_tx_received, false);
-
-	return;
-}
-
 /*
  * This function initializes the private structure and sets default
  * values to the members.
@@ -214,8 +133,8 @@ int mwifiex_init_priv(struct mwifiex_pri
 
 	priv->scan_block = false;
 
-	setup_timer(&priv->scan_delay_timer, scan_delay_timer_fn,
-		    (unsigned long)priv);
+	priv->csa_chan = 0;
+	priv->csa_expire_time = 0;
 
 	return mwifiex_add_bss_prio_tbl(priv);
 }
@@ -447,23 +366,29 @@ static void mwifiex_free_lock_list(struc
 }
 
 /*
- * This function frees the adapter structure.
+ * This function performs cleanup for adapter structure.
  *
- * The freeing operation is done recursively, by canceling all
- * pending commands, freeing the member buffers previously
- * allocated (command buffers, scan table buffer, sleep confirm
- * command buffer), stopping the timers and calling the cleanup
- * routines for every interface, before the actual adapter
- * structure is freed.
+ * The cleanup is done recursively, by canceling all pending
+ * commands, freeing the member buffers previously allocated
+ * (command buffers, scan table buffer, sleep confirm command
+ * buffer), stopping the timers and calling the cleanup routines
+ * for every interface.
  */
 static void
-mwifiex_free_adapter(struct mwifiex_adapter *adapter)
+mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
 {
+	int i;
+
 	if (!adapter) {
 		pr_err("%s: adapter is NULL\n", __func__);
 		return;
 	}
 
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i])
+			del_timer_sync(&adapter->priv[i]->scan_delay_timer);
+	}
+
 	mwifiex_cancel_all_pending_cmd(adapter);
 
 	/* Free lock variables */
@@ -684,7 +609,6 @@ mwifiex_shutdown_drv(struct mwifiex_adap
 	int ret = -EINPROGRESS;
 	struct mwifiex_private *priv;
 	s32 i;
-	unsigned long flags;
 	struct sk_buff *skb;
 
 	/* mwifiex already shutdown */
@@ -719,7 +643,7 @@ mwifiex_shutdown_drv(struct mwifiex_adap
 		}
 	}
 
-	spin_lock_irqsave(&adapter->mwifiex_lock, flags);
+	spin_lock(&adapter->mwifiex_lock);
 
 	if (adapter->if_ops.data_complete) {
 		while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) {
@@ -733,10 +657,9 @@ mwifiex_shutdown_drv(struct mwifiex_adap
 		}
 	}
 
-	/* Free adapter structure */
-	mwifiex_free_adapter(adapter);
+	mwifiex_adapter_cleanup(adapter);
 
-	spin_unlock_irqrestore(&adapter->mwifiex_lock, flags);
+	spin_unlock(&adapter->mwifiex_lock);
 
 	/* Notify completion */
 	ret = mwifiex_shutdown_fw_complete(adapter);
@@ -770,7 +693,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapt
 		if (!ret) {
 			dev_notice(adapter->dev,
 				   "WLAN FW already running! Skip FW dnld\n");
-			goto done;
+			return 0;
 		}
 
 		poll_num = MAX_FIRMWARE_POLL_TRIES;
@@ -796,14 +719,8 @@ int mwifiex_dnld_fw(struct mwifiex_adapt
 poll_fw:
 	/* Check if the firmware is downloaded successfully or not */
 	ret = adapter->if_ops.check_fw_status(adapter, poll_num);
-	if (ret) {
+	if (ret)
 		dev_err(adapter->dev, "FW failed to be active in time\n");
-		return -1;
-	}
-done:
-	/* re-enable host interrupt for mwifiex after fw dnld is successful */
-	if (adapter->if_ops.enable_int)
-		adapter->if_ops.enable_int(adapter);
 
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/join.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/join.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/join.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/join.c	2013-08-25 20:43:22.000000000 -0400
@@ -534,6 +534,8 @@ int mwifiex_cmd_802_11_associate(struct
 
 	mwifiex_cmd_append_tsf_tlv(priv, &pos, bss_desc);
 
+	mwifiex_11h_process_join(priv, &pos, bss_desc);
+
 	cmd->size = cpu_to_le16((u16) (pos - (u8 *) assoc) + S_DS_GEN);
 
 	/* Set the Capability info at last */
@@ -919,9 +921,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct m
 	memcpy(&priv->curr_bss_params.data_rates,
 	       &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates);
 
-	dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n",
-		adhoc_start->data_rate[0], adhoc_start->data_rate[1],
-		adhoc_start->data_rate[2], adhoc_start->data_rate[3]);
+	dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%4ph\n",
+		adhoc_start->data_rate);
 
 	dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
 
@@ -1290,8 +1291,10 @@ int mwifiex_associate(struct mwifiex_pri
 {
 	u8 current_bssid[ETH_ALEN];
 
-	/* Return error if the adapter or table entry is not marked as infra */
-	if ((priv->bss_mode != NL80211_IFTYPE_STATION) ||
+	/* Return error if the adapter is not STA role or table entry
+	 * is not marked as infra.
+	 */
+	if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) ||
 	    (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
 		return -1;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -3,13 +3,13 @@ config MWIFIEX
 	depends on CFG80211
 	---help---
 	  This adds support for wireless adapters based on Marvell
-	  802.11n chipsets.
+	  802.11n/ac chipsets.
 
 	  If you choose to build it as a module, it will be called
 	  mwifiex.
 
 config MWIFIEX_SDIO
-	tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797"
+	tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797/SD8897"
 	depends on MWIFIEX && MMC
 	select FW_LOADER
 	---help---
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/main.c	2013-07-01 10:39:18.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/main.c	2013-08-31 17:58:53.000000000 -0400
@@ -25,6 +25,86 @@
 #define VERSION	"1.0"
 
 const char driver_version[] = "mwifiex " VERSION " (%s) ";
+static char *cal_data_cfg;
+module_param(cal_data_cfg, charp, 0);
+
+static void scan_delay_timer_fn(unsigned long data)
+{
+	struct mwifiex_private *priv = (struct mwifiex_private *)data;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct cmd_ctrl_node *cmd_node, *tmp_node;
+	unsigned long flags;
+
+	if (adapter->surprise_removed)
+		return;
+
+	if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
+		/*
+		 * Abort scan operation by cancelling all pending scan
+		 * commands
+		 */
+		spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+		list_for_each_entry_safe(cmd_node, tmp_node,
+					 &adapter->scan_pending_q, list) {
+			list_del(&cmd_node->list);
+			mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+		}
+		spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+		adapter->scan_processing = false;
+		adapter->scan_delay_cnt = 0;
+		adapter->empty_tx_q_cnt = 0;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
+		if (priv->scan_request) {
+			dev_dbg(adapter->dev, "info: aborting scan\n");
+			cfg80211_scan_done(priv->scan_request, 1);
+			priv->scan_request = NULL;
+		} else {
+			priv->scan_aborting = false;
+			dev_dbg(adapter->dev, "info: scan already aborted\n");
+		}
+		goto done;
+	}
+
+	if (!atomic_read(&priv->adapter->is_tx_received)) {
+		adapter->empty_tx_q_cnt++;
+		if (adapter->empty_tx_q_cnt == MWIFIEX_MAX_EMPTY_TX_Q_CNT) {
+			/*
+			 * No Tx traffic for 200msec. Get scan command from
+			 * scan pending queue and put to cmd pending queue to
+			 * resume scan operation
+			 */
+			adapter->scan_delay_cnt = 0;
+			adapter->empty_tx_q_cnt = 0;
+			spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+			cmd_node = list_first_entry(&adapter->scan_pending_q,
+						    struct cmd_ctrl_node, list);
+			list_del(&cmd_node->list);
+			spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+					       flags);
+
+			mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
+							true);
+			queue_work(adapter->workqueue, &adapter->main_work);
+			goto done;
+		}
+	} else {
+		adapter->empty_tx_q_cnt = 0;
+	}
+
+	/* Delay scan operation further by 20msec */
+	mod_timer(&priv->scan_delay_timer, jiffies +
+		  msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
+	adapter->scan_delay_cnt++;
+
+done:
+	if (atomic_read(&priv->adapter->is_tx_received))
+		atomic_set(&priv->adapter->is_tx_received, false);
+
+	return;
+}
 
 /*
  * This function registers the device and performs all the necessary
@@ -73,6 +153,10 @@ static int mwifiex_register(void *card,
 
 		adapter->priv[i]->adapter = adapter;
 		adapter->priv_num++;
+
+		setup_timer(&adapter->priv[i]->scan_delay_timer,
+			    scan_delay_timer_fn,
+			    (unsigned long)adapter->priv[i]);
 	}
 	mwifiex_init_lock_list(adapter);
 
@@ -336,6 +420,17 @@ static void mwifiex_fw_dpc(const struct
 
 	dev_notice(adapter->dev, "WLAN FW is active\n");
 
+	if (cal_data_cfg) {
+		if ((reject_firmware(&adapter->cal_data, cal_data_cfg,
+				      adapter->dev)) < 0)
+			dev_err(adapter->dev,
+				"Cal data reject_firmware() failed\n");
+	}
+
+	/* enable host interrupt after fw dnld is successful */
+	if (adapter->if_ops.enable_int)
+		adapter->if_ops.enable_int(adapter);
+
 	adapter->init_wait_q_woken = false;
 	ret = mwifiex_init_fw(adapter);
 	if (ret == -1) {
@@ -387,9 +482,15 @@ err_add_intf:
 	mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
 	rtnl_unlock();
 err_init_fw:
+	if (adapter->if_ops.disable_int)
+		adapter->if_ops.disable_int(adapter);
 	pr_debug("info: %s: unregister device\n", __func__);
 	adapter->if_ops.unregister_dev(adapter);
 done:
+	if (adapter->cal_data) {
+		release_firmware(adapter->cal_data);
+		adapter->cal_data = NULL;
+	}
 	release_firmware(adapter->firmware);
 	complete(&adapter->fw_load);
 	return;
@@ -436,6 +537,7 @@ mwifiex_close(struct net_device *dev)
 		dev_dbg(priv->adapter->dev, "aborting scan on ndo_stop\n");
 		cfg80211_scan_done(priv->scan_request, 1);
 		priv->scan_request = NULL;
+		priv->scan_aborting = true;
 	}
 
 	return 0;
@@ -573,9 +675,8 @@ static void mwifiex_set_multicast_list(s
 		mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
 	} else {
 		mcast_list.mode = MWIFIEX_MULTICAST_MODE;
-		if (netdev_mc_count(dev))
-			mcast_list.num_multicast_addr =
-				mwifiex_copy_mcast_addr(&mcast_list, dev);
+		mcast_list.num_multicast_addr =
+			mwifiex_copy_mcast_addr(&mcast_list, dev);
 	}
 	mwifiex_request_set_multicast_list(priv, &mcast_list);
 }
@@ -760,7 +861,7 @@ mwifiex_add_card(void *card, struct sema
 	INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
 
 	/* Register the device. Fill up the private data structure with relevant
-	   information from the card and request for the required IRQ. */
+	   information from the card. */
 	if (adapter->if_ops.register_dev(adapter)) {
 		pr_err("%s: failed to register mwifiex device\n", __func__);
 		goto err_registerdev;
@@ -824,6 +925,11 @@ int mwifiex_remove_card(struct mwifiex_a
 	if (!adapter)
 		goto exit_remove;
 
+	/* We can no longer handle interrupts once we start doing the teardown
+	 * below. */
+	if (adapter->if_ops.disable_int)
+		adapter->if_ops.disable_int(adapter);
+
 	adapter->surprise_removed = true;
 
 	/* Stop data */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/main.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/main.h
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/main.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/main.h	2013-08-25 20:43:22.000000000 -0400
@@ -309,6 +309,9 @@ struct mwifiex_bssdescriptor {
 	u16 wapi_offset;
 	u8 *beacon_buf;
 	u32 beacon_buf_size;
+	u8 sensed_11h;
+	u8 local_constraint;
+	u8 chan_sw_ie_present;
 };
 
 struct mwifiex_current_bss_params {
@@ -492,7 +495,6 @@ struct mwifiex_private {
 	struct semaphore async_sem;
 	u8 report_scan_result;
 	struct cfg80211_scan_request *scan_request;
-	struct mwifiex_user_scan_cfg *user_scan_cfg;
 	u8 cfg_bssid[6];
 	struct wps wps;
 	u8 scan_block;
@@ -510,6 +512,9 @@ struct mwifiex_private {
 	u8 ap_11ac_enabled;
 	u32 mgmt_frame_mask;
 	struct mwifiex_roc_cfg roc_cfg;
+	bool scan_aborting;
+	u8 csa_chan;
+	unsigned long csa_expire_time;
 };
 
 enum mwifiex_ba_status {
@@ -596,6 +601,7 @@ struct mwifiex_if_ops {
 	int (*register_dev) (struct mwifiex_adapter *);
 	void (*unregister_dev) (struct mwifiex_adapter *);
 	int (*enable_int) (struct mwifiex_adapter *);
+	void (*disable_int) (struct mwifiex_adapter *);
 	int (*process_int_status) (struct mwifiex_adapter *);
 	int (*host_to_card) (struct mwifiex_adapter *, u8, struct sk_buff *,
 			     struct mwifiex_tx_param *);
@@ -730,6 +736,7 @@ struct mwifiex_adapter {
 	u16 max_mgmt_ie_index;
 	u8 scan_delay_cnt;
 	u8 empty_tx_q_cnt;
+	const struct firmware *cal_data;
 
 	/* 11AC */
 	u32 is_hw_11ac_capable;
@@ -1017,6 +1024,24 @@ static inline bool mwifiex_is_skb_mgmt_f
 	return (*(u32 *)skb->data == PKT_TYPE_MGMT);
 }
 
+/* This function retrieves channel closed for operation by Channel
+ * Switch Announcement.
+ */
+static inline u8
+mwifiex_11h_get_csa_closed_channel(struct mwifiex_private *priv)
+{
+	if (!priv->csa_chan)
+		return 0;
+
+	/* Clear csa channel, if DFS channel move time has passed */
+	if (jiffies > priv->csa_expire_time) {
+		priv->csa_chan = 0;
+		priv->csa_expire_time = 0;
+	}
+
+	return priv->csa_chan;
+}
+
 int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
 			     u32 func_init_shutdown);
 int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
@@ -1115,6 +1140,12 @@ int mwifiex_set_mgmt_ies(struct mwifiex_
 			 struct cfg80211_beacon_data *data);
 int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
 u8 *mwifiex_11d_code_2_region(u8 code);
+void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
+			      struct mwifiex_sta_node *node);
+
+void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
+			      struct mwifiex_bssdescriptor *bss_desc);
+int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv);
 
 extern const struct ethtool_ops mwifiex_ethtool_ops;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -40,6 +40,7 @@ mwifiex-y += sta_rx.o
 mwifiex-y += uap_txrx.o
 mwifiex-y += cfg80211.o
 mwifiex-y += ethtool.o
+mwifiex-y += 11h.o
 mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
 obj-$(CONFIG_MWIFIEX) += mwifiex.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/scan.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/scan.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/scan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/scan.c	2013-08-25 20:43:22.000000000 -0400
@@ -391,6 +391,12 @@ mwifiex_is_network_compatible(struct mwi
 		return 0;
 	}
 
+	if (bss_desc->chan_sw_ie_present) {
+		dev_err(adapter->dev,
+			"Don't connect to AP with WLAN_EID_CHANNEL_SWITCH\n");
+		return -1;
+	}
+
 	if (mwifiex_is_bss_wapi(priv, bss_desc)) {
 		dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
 		return 0;
@@ -569,6 +575,9 @@ mwifiex_scan_channel_list(struct mwifiex
 		return -1;
 	}
 
+	/* Check csa channel expiry before preparing scan list */
+	mwifiex_11h_get_csa_closed_channel(priv);
+
 	chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
 
 	/* Set the temp channel struct pointer to the start of the desired
@@ -598,6 +607,11 @@ mwifiex_scan_channel_list(struct mwifiex
 		while (tlv_idx < max_chan_per_scan &&
 		       tmp_chan_list->chan_number && !done_early) {
 
+			if (tmp_chan_list->chan_number == priv->csa_chan) {
+				tmp_chan_list++;
+				continue;
+			}
+
 			dev_dbg(priv->adapter->dev,
 				"info: Scan: Chan(%3d), Radio(%d),"
 				" Mode(%d, %d), Dur(%d)\n",
@@ -1169,6 +1183,19 @@ int mwifiex_update_bss_desc_with_ie(stru
 			bss_entry->erp_flags = *(current_ptr + 2);
 			break;
 
+		case WLAN_EID_PWR_CONSTRAINT:
+			bss_entry->local_constraint = *(current_ptr + 2);
+			bss_entry->sensed_11h = true;
+			break;
+
+		case WLAN_EID_CHANNEL_SWITCH:
+			bss_entry->chan_sw_ie_present = true;
+		case WLAN_EID_PWR_CAPABILITY:
+		case WLAN_EID_TPC_REPORT:
+		case WLAN_EID_QUIET:
+			bss_entry->sensed_11h = true;
+		    break;
+
 		case WLAN_EID_EXT_SUPP_RATES:
 			/*
 			 * Only process extended supported rate
@@ -1575,6 +1602,9 @@ int mwifiex_ret_802_11_scan(struct mwifi
 		goto check_next_scan;
 	}
 
+	/* Check csa channel expiry before parsing scan response */
+	mwifiex_11h_get_csa_closed_channel(priv);
+
 	bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
 	dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
 		bytes_left);
@@ -1727,6 +1757,13 @@ int mwifiex_ret_802_11_scan(struct mwifi
 			struct ieee80211_channel *chan;
 			u8 band;
 
+			/* Skip entry if on csa closed channel */
+			if (channel == priv->csa_chan) {
+				dev_dbg(adapter->dev,
+					"Dropping entry on csa closed channel\n");
+				continue;
+			}
+
 			band = BAND_G;
 			if (chan_band_tlv) {
 				chan_band =
@@ -1784,22 +1821,17 @@ check_next_scan:
 		if (priv->report_scan_result)
 			priv->report_scan_result = false;
 
-		if (priv->user_scan_cfg) {
-			if (priv->scan_request) {
-				dev_dbg(priv->adapter->dev,
-					"info: notifying scan done\n");
-				cfg80211_scan_done(priv->scan_request, 0);
-				priv->scan_request = NULL;
-			} else {
-				dev_dbg(priv->adapter->dev,
-					"info: scan already aborted\n");
-			}
-
-			kfree(priv->user_scan_cfg);
-			priv->user_scan_cfg = NULL;
+		if (priv->scan_request) {
+			dev_dbg(adapter->dev, "info: notifying scan done\n");
+			cfg80211_scan_done(priv->scan_request, 0);
+			priv->scan_request = NULL;
+		} else {
+			priv->scan_aborting = false;
+			dev_dbg(adapter->dev, "info: scan already aborted\n");
 		}
 	} else {
-		if (priv->user_scan_cfg && !priv->scan_request) {
+		if ((priv->scan_aborting && !priv->scan_request) ||
+		    priv->scan_block) {
 			spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
 					       flags);
 			adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sdio.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sdio.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sdio.c	2013-07-01 10:39:22.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sdio.c	2013-08-31 17:58:58.000000000 -0400
@@ -51,6 +51,7 @@ static struct mwifiex_if_ops sdio_ops;
 static struct semaphore add_remove_card_sem;
 
 static int mwifiex_sdio_resume(struct device *dev);
+static void mwifiex_sdio_interrupt(struct sdio_func *func);
 
 /*
  * SDIO probe.
@@ -77,6 +78,17 @@ mwifiex_sdio_probe(struct sdio_func *fun
 
 	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
 
+	if (id->driver_data) {
+		struct mwifiex_sdio_device *data = (void *)id->driver_data;
+
+		card->firmware = data->firmware;
+		card->reg = data->reg;
+		card->max_ports = data->max_ports;
+		card->mp_agg_pkt_limit = data->mp_agg_pkt_limit;
+		card->supports_sdio_new_mode = data->supports_sdio_new_mode;
+		card->has_control_mask = data->has_control_mask;
+	}
+
 	sdio_claim_host(func);
 	ret = sdio_enable_func(func);
 	sdio_release_host(func);
@@ -251,12 +263,19 @@ static int mwifiex_sdio_resume(struct de
 #define SDIO_DEVICE_ID_MARVELL_8787   (0x9119)
 /* Device ID for SD8797 */
 #define SDIO_DEVICE_ID_MARVELL_8797   (0x9129)
+/* Device ID for SD8897 */
+#define SDIO_DEVICE_ID_MARVELL_8897   (0x912d)
 
 /* WLAN IDs */
 static const struct sdio_device_id mwifiex_ids[] = {
-	{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8786)},
-	{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)},
-	{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797)},
+	{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8786),
+		.driver_data = (unsigned long) &mwifiex_sdio_sd8786},
+	{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787),
+		.driver_data = (unsigned long) &mwifiex_sdio_sd8787},
+	{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797),
+		.driver_data = (unsigned long) &mwifiex_sdio_sd8797},
+	{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8897),
+		.driver_data = (unsigned long) &mwifiex_sdio_sd8897},
 	{},
 };
 
@@ -278,17 +297,26 @@ static struct sdio_driver mwifiex_sdio =
 	}
 };
 
+/* Write data into SDIO card register. Caller claims SDIO device. */
+static int
+mwifiex_write_reg_locked(struct sdio_func *func, u32 reg, u8 data)
+{
+	int ret = -1;
+	sdio_writeb(func, data, reg, &ret);
+	return ret;
+}
+
 /*
  * This function writes data into SDIO card register.
  */
 static int
-mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
+mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)
 {
 	struct sdio_mmc_card *card = adapter->card;
-	int ret = -1;
+	int ret;
 
 	sdio_claim_host(card->func);
-	sdio_writeb(card->func, (u8) data, reg, &ret);
+	ret = mwifiex_write_reg_locked(card->func, reg, data);
 	sdio_release_host(card->func);
 
 	return ret;
@@ -298,7 +326,7 @@ mwifiex_write_reg(struct mwifiex_adapter
  * This function reads data from SDIO card register.
  */
 static int
-mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data)
+mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data)
 {
 	struct sdio_mmc_card *card = adapter->card;
 	int ret = -1;
@@ -400,7 +428,40 @@ static int mwifiex_pm_wakeup_card_comple
 }
 
 /*
- * This function initializes the IO ports.
+ * This function is used to initialize IO ports for the
+ * chipsets supporting SDIO new mode eg SD8897.
+ */
+static int mwifiex_init_sdio_new_mode(struct mwifiex_adapter *adapter)
+{
+	u8 reg;
+
+	adapter->ioport = MEM_PORT;
+
+	/* enable sdio new mode */
+	if (mwifiex_read_reg(adapter, CARD_CONFIG_2_1_REG, &reg))
+		return -1;
+	if (mwifiex_write_reg(adapter, CARD_CONFIG_2_1_REG,
+			      reg | CMD53_NEW_MODE))
+		return -1;
+
+	/* Configure cmd port and enable reading rx length from the register */
+	if (mwifiex_read_reg(adapter, CMD_CONFIG_0, &reg))
+		return -1;
+	if (mwifiex_write_reg(adapter, CMD_CONFIG_0, reg | CMD_PORT_RD_LEN_EN))
+		return -1;
+
+	/* Enable Dnld/Upld ready auto reset for cmd port after cmd53 is
+	 * completed
+	 */
+	if (mwifiex_read_reg(adapter, CMD_CONFIG_1, &reg))
+		return -1;
+	if (mwifiex_write_reg(adapter, CMD_CONFIG_1, reg | CMD_PORT_AUTO_EN))
+		return -1;
+
+	return 0;
+}
+
+/* This function initializes the IO ports.
  *
  * The following operations are performed -
  *      - Read the IO ports (0, 1 and 2)
@@ -409,10 +470,17 @@ static int mwifiex_pm_wakeup_card_comple
  */
 static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
 {
-	u32 reg;
+	u8 reg;
+	struct sdio_mmc_card *card = adapter->card;
 
 	adapter->ioport = 0;
 
+	if (card->supports_sdio_new_mode) {
+		if (mwifiex_init_sdio_new_mode(adapter))
+			return -1;
+		goto cont;
+	}
+
 	/* Read the IO port */
 	if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, &reg))
 		adapter->ioport |= (reg & 0xff);
@@ -428,19 +496,19 @@ static int mwifiex_init_sdio_ioport(stru
 		adapter->ioport |= ((reg & 0xff) << 16);
 	else
 		return -1;
-
+cont:
 	pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport);
 
 	/* Set Host interrupt reset to read to clear */
 	if (!mwifiex_read_reg(adapter, HOST_INT_RSR_REG, &reg))
 		mwifiex_write_reg(adapter, HOST_INT_RSR_REG,
-				  reg | SDIO_INT_MASK);
+				  reg | card->reg->sdio_int_mask);
 	else
 		return -1;
 
 	/* Dnld/Upld ready set to auto reset */
-	if (!mwifiex_read_reg(adapter, CARD_MISC_CFG_REG, &reg))
-		mwifiex_write_reg(adapter, CARD_MISC_CFG_REG,
+	if (!mwifiex_read_reg(adapter, card->reg->card_misc_cfg_reg, &reg))
+		mwifiex_write_reg(adapter, card->reg->card_misc_cfg_reg,
 				  reg | AUTO_RE_ENABLE_INT);
 	else
 		return -1;
@@ -486,34 +554,42 @@ static int mwifiex_write_data_to_card(st
 static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
 {
 	struct sdio_mmc_card *card = adapter->card;
-	u16 rd_bitmap = card->mp_rd_bitmap;
+	const struct mwifiex_sdio_card_reg *reg = card->reg;
+	u32 rd_bitmap = card->mp_rd_bitmap;
 
-	dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%04x\n", rd_bitmap);
+	dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%08x\n", rd_bitmap);
 
-	if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
-		return -1;
+	if (card->supports_sdio_new_mode) {
+		if (!(rd_bitmap & reg->data_port_mask))
+			return -1;
+	} else {
+		if (!(rd_bitmap & (CTRL_PORT_MASK | reg->data_port_mask)))
+			return -1;
+	}
 
-	if (card->mp_rd_bitmap & CTRL_PORT_MASK) {
-		card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK);
+	if ((card->has_control_mask) &&
+	    (card->mp_rd_bitmap & CTRL_PORT_MASK)) {
+		card->mp_rd_bitmap &= (u32) (~CTRL_PORT_MASK);
 		*port = CTRL_PORT;
-		dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n",
+		dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%08x\n",
 			*port, card->mp_rd_bitmap);
-	} else {
-		if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) {
-			card->mp_rd_bitmap &= (u16)
-						(~(1 << card->curr_rd_port));
-			*port = card->curr_rd_port;
+		return 0;
+	}
 
-			if (++card->curr_rd_port == MAX_PORT)
-				card->curr_rd_port = 1;
-		} else {
-			return -1;
-		}
+	if (!(card->mp_rd_bitmap & (1 << card->curr_rd_port)))
+		return -1;
+
+	/* We are now handling the SDIO data ports */
+	card->mp_rd_bitmap &= (u32)(~(1 << card->curr_rd_port));
+	*port = card->curr_rd_port;
+
+	if (++card->curr_rd_port == card->max_ports)
+		card->curr_rd_port = reg->start_rd_port;
+
+	dev_dbg(adapter->dev,
+		"data: port=%d mp_rd_bitmap=0x%08x -> 0x%08x\n",
+		*port, rd_bitmap, card->mp_rd_bitmap);
 
-		dev_dbg(adapter->dev,
-			"data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
-			*port, rd_bitmap, card->mp_rd_bitmap);
-	}
 	return 0;
 }
 
@@ -524,35 +600,45 @@ static int mwifiex_get_rd_port(struct mw
  * increased (provided it does not reach the maximum limit, in which
  * case it is reset to 1)
  */
-static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
+static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port)
 {
 	struct sdio_mmc_card *card = adapter->card;
-	u16 wr_bitmap = card->mp_wr_bitmap;
+	const struct mwifiex_sdio_card_reg *reg = card->reg;
+	u32 wr_bitmap = card->mp_wr_bitmap;
 
-	dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%04x\n", wr_bitmap);
+	dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap);
 
-	if (!(wr_bitmap & card->mp_data_port_mask))
+	if (card->supports_sdio_new_mode &&
+	    !(wr_bitmap & reg->data_port_mask)) {
+		adapter->data_sent = true;
+		return -EBUSY;
+	} else if (!card->supports_sdio_new_mode &&
+		   !(wr_bitmap & card->mp_data_port_mask)) {
 		return -1;
+	}
 
 	if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {
-		card->mp_wr_bitmap &= (u16) (~(1 << card->curr_wr_port));
+		card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port));
 		*port = card->curr_wr_port;
-		if (++card->curr_wr_port == card->mp_end_port)
-			card->curr_wr_port = 1;
+		if (((card->supports_sdio_new_mode) &&
+		     (++card->curr_wr_port == card->max_ports)) ||
+		    ((!card->supports_sdio_new_mode) &&
+		     (++card->curr_wr_port == card->mp_end_port)))
+			card->curr_wr_port = reg->start_wr_port;
 	} else {
 		adapter->data_sent = true;
 		return -EBUSY;
 	}
 
-	if (*port == CTRL_PORT) {
-		dev_err(adapter->dev, "invalid data port=%d cur port=%d"
-			" mp_wr_bitmap=0x%04x -> 0x%04x\n",
+	if ((card->has_control_mask) && (*port == CTRL_PORT)) {
+		dev_err(adapter->dev,
+			"invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",
 			*port, card->curr_wr_port, wr_bitmap,
 			card->mp_wr_bitmap);
 		return -1;
 	}
 
-	dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n",
+	dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",
 		*port, wr_bitmap, card->mp_wr_bitmap);
 
 	return 0;
@@ -564,11 +650,12 @@ static int mwifiex_get_wr_port_data(stru
 static int
 mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
 {
+	struct sdio_mmc_card *card = adapter->card;
 	u32 tries;
-	u32 cs;
+	u8 cs;
 
 	for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
-		if (mwifiex_read_reg(adapter, CARD_STATUS_REG, &cs))
+		if (mwifiex_read_reg(adapter, card->reg->poll_reg, &cs))
 			break;
 		else if ((cs & bits) == bits)
 			return 0;
@@ -587,12 +674,14 @@ mwifiex_sdio_poll_card_status(struct mwi
 static int
 mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
 {
-	u32 fws0, fws1;
+	struct sdio_mmc_card *card = adapter->card;
+	const struct mwifiex_sdio_card_reg *reg = card->reg;
+	u8 fws0, fws1;
 
-	if (mwifiex_read_reg(adapter, CARD_FW_STATUS0_REG, &fws0))
+	if (mwifiex_read_reg(adapter, reg->status_reg_0, &fws0))
 		return -1;
 
-	if (mwifiex_read_reg(adapter, CARD_FW_STATUS1_REG, &fws1))
+	if (mwifiex_read_reg(adapter, reg->status_reg_1, &fws1))
 		return -1;
 
 	*dat = (u16) ((fws1 << 8) | fws0);
@@ -606,23 +695,15 @@ mwifiex_sdio_read_fw_status(struct mwifi
  * The host interrupt mask is read, the disable bit is reset and
  * written back to the card host interrupt mask register.
  */
-static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
+static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
 {
-	u32 host_int_mask;
-
-	/* Read back the host_int_mask register */
-	if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
-		return -1;
-
-	/* Update with the mask and write back to the register */
-	host_int_mask &= ~HOST_INT_DISABLE;
-
-	if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
-		dev_err(adapter->dev, "disable host interrupt failed\n");
-		return -1;
-	}
+	struct sdio_mmc_card *card = adapter->card;
+	struct sdio_func *func = card->func;
 
-	return 0;
+	sdio_claim_host(func);
+	mwifiex_write_reg_locked(func, HOST_INT_MASK_REG, 0);
+	sdio_release_irq(func);
+	sdio_release_host(func);
 }
 
 /*
@@ -633,12 +714,30 @@ static int mwifiex_sdio_disable_host_int
  */
 static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter)
 {
+	struct sdio_mmc_card *card = adapter->card;
+	struct sdio_func *func = card->func;
+	int ret;
+
+	sdio_claim_host(func);
+
+	/* Request the SDIO IRQ */
+	ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);
+	if (ret) {
+		dev_err(adapter->dev, "claim irq failed: ret=%d\n", ret);
+		goto out;
+	}
+
 	/* Simply write the mask to the register */
-	if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, HOST_INT_ENABLE)) {
+	ret = mwifiex_write_reg_locked(func, HOST_INT_MASK_REG,
+				       card->reg->host_int_enable);
+	if (ret) {
 		dev_err(adapter->dev, "enable host interrupt failed\n");
-		return -1;
+		sdio_release_irq(func);
 	}
-	return 0;
+
+out:
+	sdio_release_host(func);
+	return ret;
 }
 
 /*
@@ -686,11 +785,13 @@ static int mwifiex_sdio_card_to_host(str
 static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
 				    struct mwifiex_fw_image *fw)
 {
+	struct sdio_mmc_card *card = adapter->card;
+	const struct mwifiex_sdio_card_reg *reg = card->reg;
 	int ret;
 	u8 *firmware = fw->fw_buf;
 	u32 firmware_len = fw->fw_len;
 	u32 offset = 0;
-	u32 base0, base1;
+	u8 base0, base1;
 	u8 *fwbuf;
 	u16 len = 0;
 	u32 txlen, tx_blocks = 0, tries;
@@ -727,7 +828,7 @@ static int mwifiex_prog_fw_w_helper(stru
 			break;
 
 		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
-			ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0,
+			ret = mwifiex_read_reg(adapter, reg->base_0_reg,
 					       &base0);
 			if (ret) {
 				dev_err(adapter->dev,
@@ -736,7 +837,7 @@ static int mwifiex_prog_fw_w_helper(stru
 					base0, base0);
 				goto done;
 			}
-			ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1,
+			ret = mwifiex_read_reg(adapter, reg->base_1_reg,
 					       &base1);
 			if (ret) {
 				dev_err(adapter->dev,
@@ -828,10 +929,11 @@ done:
 static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
 				   u32 poll_num)
 {
+	struct sdio_mmc_card *card = adapter->card;
 	int ret = 0;
 	u16 firmware_stat;
 	u32 tries;
-	u32 winner_status;
+	u8 winner_status;
 
 	/* Wait for firmware initialization event */
 	for (tries = 0; tries < poll_num; tries++) {
@@ -849,7 +951,7 @@ static int mwifiex_check_fw_status(struc
 
 	if (ret) {
 		if (mwifiex_read_reg
-		    (adapter, CARD_FW_STATUS0_REG, &winner_status))
+		    (adapter, card->reg->status_reg_0, &winner_status))
 			winner_status = 0;
 
 		if (winner_status)
@@ -866,12 +968,12 @@ static int mwifiex_check_fw_status(struc
 static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
 {
 	struct sdio_mmc_card *card = adapter->card;
-	u32 sdio_ireg;
+	u8 sdio_ireg;
 	unsigned long flags;
 
-	if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS,
-				   REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK,
-				   0)) {
+	if (mwifiex_read_data_sync(adapter, card->mp_regs,
+				   card->reg->max_mp_regs,
+				   REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
 		dev_err(adapter->dev, "read mp_regs failed\n");
 		return;
 	}
@@ -880,6 +982,9 @@ static void mwifiex_interrupt_status(str
 	if (sdio_ireg) {
 		/*
 		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+		 * For SDIO new mode CMD port interrupts
+		 *	DN_LD_CMD_PORT_HOST_INT_STATUS and/or
+		 *	UP_LD_CMD_PORT_HOST_INT_STATUS
 		 * Clear the interrupt status register
 		 */
 		dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
@@ -909,9 +1014,6 @@ mwifiex_sdio_interrupt(struct sdio_func
 	}
 	adapter = card->adapter;
 
-	if (adapter->surprise_removed)
-		return;
-
 	if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
 		adapter->ps_state = PS_STATE_AWAKE;
 
@@ -1003,11 +1105,11 @@ static int mwifiex_sdio_card_to_host_mp_
 	s32 f_aggr_cur = 0;
 	struct sk_buff *skb_deaggr;
 	u32 pind;
-	u32 pkt_len, pkt_type = 0;
+	u32 pkt_len, pkt_type, mport;
 	u8 *curr_ptr;
 	u32 rx_len = skb->len;
 
-	if (port == CTRL_PORT) {
+	if ((card->has_control_mask) && (port == CTRL_PORT)) {
 		/* Read the command Resp without aggr */
 		dev_dbg(adapter->dev, "info: %s: no aggregation for cmd "
 			"response\n", __func__);
@@ -1024,7 +1126,10 @@ static int mwifiex_sdio_card_to_host_mp_
 		goto rx_curr_single;
 	}
 
-	if (card->mp_rd_bitmap & (~((u16) CTRL_PORT_MASK))) {
+	if ((!card->has_control_mask && (card->mp_rd_bitmap &
+					 card->reg->data_port_mask)) ||
+	    (card->has_control_mask && (card->mp_rd_bitmap &
+					(~((u32) CTRL_PORT_MASK))))) {
 		/* Some more data RX pending */
 		dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
 
@@ -1060,10 +1165,10 @@ static int mwifiex_sdio_card_to_host_mp_
 	if (f_aggr_cur) {
 		dev_dbg(adapter->dev, "info: current packet aggregation\n");
 		/* Curr pkt can be aggregated */
-		MP_RX_AGGR_SETUP(card, skb, port);
+		mp_rx_aggr_setup(card, skb, port);
 
 		if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
-		    MP_RX_AGGR_PORT_LIMIT_REACHED(card)) {
+		    mp_rx_aggr_port_limit_reached(card)) {
 			dev_dbg(adapter->dev, "info: %s: aggregated packet "
 				"limit reached\n", __func__);
 			/* No more pkts allowed in Aggr buf, rx it */
@@ -1076,11 +1181,28 @@ static int mwifiex_sdio_card_to_host_mp_
 		dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n",
 			card->mpa_rx.pkt_cnt);
 
+		if (card->supports_sdio_new_mode) {
+			int i;
+			u32 port_count;
+
+			for (i = 0, port_count = 0; i < card->max_ports; i++)
+				if (card->mpa_rx.ports & BIT(i))
+					port_count++;
+
+			/* Reading data from "start_port + 0" to "start_port +
+			 * port_count -1", so decrease the count by 1
+			 */
+			port_count--;
+			mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
+				 (port_count << 8)) + card->mpa_rx.start_port;
+		} else {
+			mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
+				 (card->mpa_rx.ports << 4)) +
+				 card->mpa_rx.start_port;
+		}
+
 		if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
-					   card->mpa_rx.buf_len,
-					   (adapter->ioport | 0x1000 |
-					    (card->mpa_rx.ports << 4)) +
-					   card->mpa_rx.start_port, 1))
+					   card->mpa_rx.buf_len, mport, 1))
 			goto error;
 
 		curr_ptr = card->mpa_rx.buf;
@@ -1167,6 +1289,7 @@ error:
 static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
 {
 	struct sdio_mmc_card *card = adapter->card;
+	const struct mwifiex_sdio_card_reg *reg = card->reg;
 	int ret = 0;
 	u8 sdio_ireg;
 	struct sk_buff *skb;
@@ -1175,6 +1298,8 @@ static int mwifiex_process_int_status(st
 	u32 rx_blocks;
 	u16 rx_len;
 	unsigned long flags;
+	u32 bitmap;
+	u8 cr;
 
 	spin_lock_irqsave(&adapter->int_lock, flags);
 	sdio_ireg = adapter->int_status;
@@ -1184,10 +1309,60 @@ static int mwifiex_process_int_status(st
 	if (!sdio_ireg)
 		return ret;
 
+	/* Following interrupt is only for SDIO new mode */
+	if (sdio_ireg & DN_LD_CMD_PORT_HOST_INT_STATUS && adapter->cmd_sent)
+		adapter->cmd_sent = false;
+
+	/* Following interrupt is only for SDIO new mode */
+	if (sdio_ireg & UP_LD_CMD_PORT_HOST_INT_STATUS) {
+		u32 pkt_type;
+
+		/* read the len of control packet */
+		rx_len = card->mp_regs[CMD_RD_LEN_1] << 8;
+		rx_len |= (u16) card->mp_regs[CMD_RD_LEN_0];
+		rx_blocks = DIV_ROUND_UP(rx_len, MWIFIEX_SDIO_BLOCK_SIZE);
+		if (rx_len <= INTF_HEADER_LEN ||
+		    (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
+		     MWIFIEX_RX_DATA_BUF_SIZE)
+			return -1;
+		rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
+
+		skb = dev_alloc_skb(rx_len);
+		if (!skb)
+			return -1;
+
+		skb_put(skb, rx_len);
+
+		if (mwifiex_sdio_card_to_host(adapter, &pkt_type, skb->data,
+					      skb->len, adapter->ioport |
+							CMD_PORT_SLCT)) {
+			dev_err(adapter->dev,
+				"%s: failed to card_to_host", __func__);
+			dev_kfree_skb_any(skb);
+			goto term_cmd;
+		}
+
+		if ((pkt_type != MWIFIEX_TYPE_CMD) &&
+		    (pkt_type != MWIFIEX_TYPE_EVENT))
+			dev_err(adapter->dev,
+				"%s:Received wrong packet on cmd port",
+				__func__);
+
+		mwifiex_decode_rx_packet(adapter, skb, pkt_type);
+	}
+
 	if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
-		card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8;
-		card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L];
-		dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n",
+		bitmap = (u32) card->mp_regs[reg->wr_bitmap_l];
+		bitmap |= ((u32) card->mp_regs[reg->wr_bitmap_u]) << 8;
+		if (card->supports_sdio_new_mode) {
+			bitmap |=
+				((u32) card->mp_regs[reg->wr_bitmap_1l]) << 16;
+			bitmap |=
+				((u32) card->mp_regs[reg->wr_bitmap_1u]) << 24;
+		}
+		card->mp_wr_bitmap = bitmap;
+
+		dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%x\n",
 			card->mp_wr_bitmap);
 		if (adapter->data_sent &&
 		    (card->mp_wr_bitmap & card->mp_data_port_mask)) {
@@ -1200,11 +1375,11 @@ static int mwifiex_process_int_status(st
 	/* As firmware will not generate download ready interrupt if the port
 	   updated is command port only, cmd_sent should be done for any SDIO
 	   interrupt. */
-	if (adapter->cmd_sent) {
+	if (card->has_control_mask && adapter->cmd_sent) {
 		/* Check if firmware has attach buffer at command port and
 		   update just that in wr_bit_map. */
 		card->mp_wr_bitmap |=
-			(u16) card->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
+			(u32) card->mp_regs[reg->wr_bitmap_l] & CTRL_PORT_MASK;
 		if (card->mp_wr_bitmap & CTRL_PORT_MASK)
 			adapter->cmd_sent = false;
 	}
@@ -1212,9 +1387,16 @@ static int mwifiex_process_int_status(st
 	dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
 		adapter->cmd_sent, adapter->data_sent);
 	if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
-		card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8;
-		card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L];
-		dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n",
+		bitmap = (u32) card->mp_regs[reg->rd_bitmap_l];
+		bitmap |= ((u32) card->mp_regs[reg->rd_bitmap_u]) << 8;
+		if (card->supports_sdio_new_mode) {
+			bitmap |=
+				((u32) card->mp_regs[reg->rd_bitmap_1l]) << 16;
+			bitmap |=
+				((u32) card->mp_regs[reg->rd_bitmap_1u]) << 24;
+		}
+		card->mp_rd_bitmap = bitmap;
+		dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%x\n",
 			card->mp_rd_bitmap);
 
 		while (true) {
@@ -1224,8 +1406,8 @@ static int mwifiex_process_int_status(st
 					"info: no more rd_port available\n");
 				break;
 			}
-			len_reg_l = RD_LEN_P0_L + (port << 1);
-			len_reg_u = RD_LEN_P0_U + (port << 1);
+			len_reg_l = reg->rd_len_p0_l + (port << 1);
+			len_reg_u = reg->rd_len_p0_u + (port << 1);
 			rx_len = ((u16) card->mp_regs[len_reg_u]) << 8;
 			rx_len |= (u16) card->mp_regs[len_reg_l];
 			dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n",
@@ -1257,37 +1439,33 @@ static int mwifiex_process_int_status(st
 
 			if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
 							      port)) {
-				u32 cr = 0;
-
 				dev_err(adapter->dev, "card_to_host_mpa failed:"
 					" int status=%#x\n", sdio_ireg);
-				if (mwifiex_read_reg(adapter,
-						     CONFIGURATION_REG, &cr))
-					dev_err(adapter->dev,
-						"read CFG reg failed\n");
-
-				dev_dbg(adapter->dev,
-					"info: CFG reg val = %d\n", cr);
-				if (mwifiex_write_reg(adapter,
-						      CONFIGURATION_REG,
-						      (cr | 0x04)))
-					dev_err(adapter->dev,
-						"write CFG reg failed\n");
-
-				dev_dbg(adapter->dev, "info: write success\n");
-				if (mwifiex_read_reg(adapter,
-						     CONFIGURATION_REG, &cr))
-					dev_err(adapter->dev,
-						"read CFG reg failed\n");
-
-				dev_dbg(adapter->dev,
-					"info: CFG reg val =%x\n", cr);
-				return -1;
+				goto term_cmd;
 			}
 		}
 	}
 
 	return 0;
+
+term_cmd:
+	/* terminate cmd */
+	if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr))
+		dev_err(adapter->dev, "read CFG reg failed\n");
+	else
+		dev_dbg(adapter->dev, "info: CFG reg val = %d\n", cr);
+
+	if (mwifiex_write_reg(adapter, CONFIGURATION_REG, (cr | 0x04)))
+		dev_err(adapter->dev, "write CFG reg failed\n");
+	else
+		dev_dbg(adapter->dev, "info: write success\n");
+
+	if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr))
+		dev_err(adapter->dev, "read CFG reg failed\n");
+	else
+		dev_dbg(adapter->dev, "info: CFG reg val =%x\n", cr);
+
+	return -1;
 }
 
 /*
@@ -1305,7 +1483,7 @@ static int mwifiex_process_int_status(st
  * and return.
  */
 static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
-					u8 *payload, u32 pkt_len, u8 port,
+					u8 *payload, u32 pkt_len, u32 port,
 					u32 next_pkt_len)
 {
 	struct sdio_mmc_card *card = adapter->card;
@@ -1314,8 +1492,11 @@ static int mwifiex_host_to_card_mp_aggr(
 	s32 f_send_cur_buf = 0;
 	s32 f_precopy_cur_buf = 0;
 	s32 f_postcopy_cur_buf = 0;
+	u32 mport;
 
-	if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) {
+	if (!card->mpa_tx.enabled ||
+	    (card->has_control_mask && (port == CTRL_PORT)) ||
+	    (card->supports_sdio_new_mode && (port == CMD_PORT_SLCT))) {
 		dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n",
 			__func__);
 
@@ -1329,7 +1510,7 @@ static int mwifiex_host_to_card_mp_aggr(
 			__func__);
 
 		if (MP_TX_AGGR_IN_PROGRESS(card)) {
-			if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) &&
+			if (!mp_tx_aggr_port_limit_reached(card) &&
 			    MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
 				f_precopy_cur_buf = 1;
 
@@ -1342,7 +1523,7 @@ static int mwifiex_host_to_card_mp_aggr(
 				/* No room in Aggr buf, send it */
 				f_send_aggr_buf = 1;
 
-				if (MP_TX_AGGR_PORT_LIMIT_REACHED(card) ||
+				if (mp_tx_aggr_port_limit_reached(card) ||
 				    !(card->mp_wr_bitmap &
 				      (1 << card->curr_wr_port)))
 					f_send_cur_buf = 1;
@@ -1381,7 +1562,7 @@ static int mwifiex_host_to_card_mp_aggr(
 		MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
 
 		if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||
-		    MP_TX_AGGR_PORT_LIMIT_REACHED(card))
+		    mp_tx_aggr_port_limit_reached(card))
 			/* No more pkts allowed in Aggr buf, send it */
 			f_send_aggr_buf = 1;
 	}
@@ -1390,11 +1571,28 @@ static int mwifiex_host_to_card_mp_aggr(
 		dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n",
 			__func__,
 				card->mpa_tx.start_port, card->mpa_tx.ports);
+		if (card->supports_sdio_new_mode) {
+			u32 port_count;
+			int i;
+
+			for (i = 0, port_count = 0; i < card->max_ports; i++)
+				if (card->mpa_tx.ports & BIT(i))
+					port_count++;
+
+			/* Writing data from "start_port + 0" to "start_port +
+			 * port_count -1", so decrease the count by 1
+			 */
+			port_count--;
+			mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
+				 (port_count << 8)) + card->mpa_tx.start_port;
+		} else {
+			mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
+				 (card->mpa_tx.ports << 4)) +
+				 card->mpa_tx.start_port;
+		}
+
 		ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
-						 card->mpa_tx.buf_len,
-						 (adapter->ioport | 0x1000 |
-						 (card->mpa_tx.ports << 4)) +
-						  card->mpa_tx.start_port);
+						 card->mpa_tx.buf_len, mport);
 
 		MP_TX_AGGR_BUF_RESET(card);
 	}
@@ -1434,15 +1632,15 @@ static int mwifiex_sdio_host_to_card(str
 	int ret;
 	u32 buf_block_len;
 	u32 blk_size;
-	u8 port = CTRL_PORT;
+	u32 port = CTRL_PORT;
 	u8 *payload = (u8 *)skb->data;
 	u32 pkt_len = skb->len;
 
 	/* Allocate buffer and copy payload */
 	blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
 	buf_block_len = (pkt_len + blk_size - 1) / blk_size;
-	*(u16 *) &payload[0] = (u16) pkt_len;
-	*(u16 *) &payload[2] = type;
+	*(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len);
+	*(__le16 *)&payload[2] = cpu_to_le16(type);
 
 	/*
 	 * This is SDIO specific header
@@ -1465,6 +1663,9 @@ static int mwifiex_sdio_host_to_card(str
 		    pkt_len > MWIFIEX_UPLD_SIZE)
 			dev_err(adapter->dev, "%s: payload=%p, nb=%d\n",
 				__func__, payload, pkt_len);
+
+		if (card->supports_sdio_new_mode)
+			port = CMD_PORT_SLCT;
 	}
 
 	/* Transfer data to card */
@@ -1541,9 +1742,7 @@ mwifiex_unregister_dev(struct mwifiex_ad
 	struct sdio_mmc_card *card = adapter->card;
 
 	if (adapter->card) {
-		/* Release the SDIO IRQ */
 		sdio_claim_host(card->func);
-		sdio_release_irq(card->func);
 		sdio_disable_func(card->func);
 		sdio_release_host(card->func);
 		sdio_set_drvdata(card->func, NULL);
@@ -1557,7 +1756,7 @@ mwifiex_unregister_dev(struct mwifiex_ad
  */
 static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
 {
-	int ret = 0;
+	int ret;
 	struct sdio_mmc_card *card = adapter->card;
 	struct sdio_func *func = card->func;
 
@@ -1566,49 +1765,21 @@ static int mwifiex_register_dev(struct m
 
 	sdio_claim_host(func);
 
-	/* Request the SDIO IRQ */
-	ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);
-	if (ret) {
-		pr_err("claim irq failed: ret=%d\n", ret);
-		goto disable_func;
-	}
-
 	/* Set block size */
 	ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);
+	sdio_release_host(func);
 	if (ret) {
 		pr_err("cannot set SDIO block size\n");
-		ret = -1;
-		goto release_irq;
+		return ret;
 	}
 
-	sdio_release_host(func);
 	sdio_set_drvdata(func, card);
 
 	adapter->dev = &func->dev;
 
-	switch (func->device) {
-	case SDIO_DEVICE_ID_MARVELL_8786:
-		strcpy(adapter->fw_name, SD8786_DEFAULT_FW_NAME);
-		break;
-	case SDIO_DEVICE_ID_MARVELL_8797:
-		strcpy(adapter->fw_name, SD8797_DEFAULT_FW_NAME);
-		break;
-	case SDIO_DEVICE_ID_MARVELL_8787:
-	default:
-		strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME);
-		break;
-	}
+	strcpy(adapter->fw_name, card->firmware);
 
 	return 0;
-
-release_irq:
-	sdio_release_irq(func);
-disable_func:
-	sdio_disable_func(func);
-	sdio_release_host(func);
-	adapter->card = NULL;
-
-	return -1;
 }
 
 /*
@@ -1626,8 +1797,9 @@ disable_func:
 static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
 {
 	struct sdio_mmc_card *card = adapter->card;
+	const struct mwifiex_sdio_card_reg *reg = card->reg;
 	int ret;
-	u32 sdio_ireg;
+	u8 sdio_ireg;
 
 	/*
 	 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
@@ -1636,39 +1808,41 @@ static int mwifiex_init_sdio(struct mwif
 	 */
 	mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg);
 
-	/* Disable host interrupt mask register for SDIO */
-	mwifiex_sdio_disable_host_int(adapter);
-
 	/* Get SDIO ioport */
 	mwifiex_init_sdio_ioport(adapter);
 
 	/* Initialize SDIO variables in card */
 	card->mp_rd_bitmap = 0;
 	card->mp_wr_bitmap = 0;
-	card->curr_rd_port = 1;
-	card->curr_wr_port = 1;
+	card->curr_rd_port = reg->start_rd_port;
+	card->curr_wr_port = reg->start_wr_port;
 
-	card->mp_data_port_mask = DATA_PORT_MASK;
+	card->mp_data_port_mask = reg->data_port_mask;
 
 	card->mpa_tx.buf_len = 0;
 	card->mpa_tx.pkt_cnt = 0;
 	card->mpa_tx.start_port = 0;
 
 	card->mpa_tx.enabled = 1;
-	card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
+	card->mpa_tx.pkt_aggr_limit = card->mp_agg_pkt_limit;
 
 	card->mpa_rx.buf_len = 0;
 	card->mpa_rx.pkt_cnt = 0;
 	card->mpa_rx.start_port = 0;
 
 	card->mpa_rx.enabled = 1;
-	card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
+	card->mpa_rx.pkt_aggr_limit = card->mp_agg_pkt_limit;
 
 	/* Allocate buffers for SDIO MP-A */
-	card->mp_regs = kzalloc(MAX_MP_REGS, GFP_KERNEL);
+	card->mp_regs = kzalloc(reg->max_mp_regs, GFP_KERNEL);
 	if (!card->mp_regs)
 		return -ENOMEM;
 
+	/* Allocate skb pointer buffers */
+	card->mpa_rx.skb_arr = kzalloc((sizeof(void *)) *
+				       card->mp_agg_pkt_limit, GFP_KERNEL);
+	card->mpa_rx.len_arr = kzalloc(sizeof(*card->mpa_rx.len_arr) *
+				       card->mp_agg_pkt_limit, GFP_KERNEL);
 	ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
 					     SDIO_MP_TX_AGGR_DEF_BUF_SIZE,
 					     SDIO_MP_RX_AGGR_DEF_BUF_SIZE);
@@ -1705,6 +1879,8 @@ static void mwifiex_cleanup_sdio(struct
 	struct sdio_mmc_card *card = adapter->card;
 
 	kfree(card->mp_regs);
+	kfree(card->mpa_rx.skb_arr);
+	kfree(card->mpa_rx.len_arr);
 	kfree(card->mpa_tx.buf);
 	kfree(card->mpa_rx.buf);
 }
@@ -1716,16 +1892,20 @@ static void
 mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
 {
 	struct sdio_mmc_card *card = adapter->card;
+	const struct mwifiex_sdio_card_reg *reg = card->reg;
 	int i;
 
 	card->mp_end_port = port;
 
-	card->mp_data_port_mask = DATA_PORT_MASK;
+	card->mp_data_port_mask = reg->data_port_mask;
 
-	for (i = 1; i <= MAX_PORT - card->mp_end_port; i++)
-		card->mp_data_port_mask &= ~(1 << (MAX_PORT - i));
+	if (reg->start_wr_port) {
+		for (i = 1; i <= card->max_ports - card->mp_end_port; i++)
+			card->mp_data_port_mask &=
+					~(1 << (card->max_ports - i));
+	}
 
-	card->curr_wr_port = 1;
+	card->curr_wr_port = reg->start_wr_port;
 
 	dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n",
 		port, card->mp_data_port_mask);
@@ -1769,6 +1949,7 @@ static struct mwifiex_if_ops sdio_ops =
 	.register_dev = mwifiex_register_dev,
 	.unregister_dev = mwifiex_unregister_dev,
 	.enable_int = mwifiex_sdio_enable_host_int,
+	.disable_int = mwifiex_sdio_disable_host_int,
 	.process_int_status = mwifiex_process_int_status,
 	.host_to_card = mwifiex_sdio_host_to_card,
 	.wakeup = mwifiex_pm_wakeup_card,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sdio.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sdio.h
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sdio.h	2013-07-01 10:39:20.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sdio.h	2013-08-31 17:58:55.000000000 -0400
@@ -32,30 +32,37 @@
 #define SD8786_DEFAULT_FW_NAME "/*(DEBLOBBED)*/"
 #define SD8787_DEFAULT_FW_NAME "/*(DEBLOBBED)*/"
 #define SD8797_DEFAULT_FW_NAME "/*(DEBLOBBED)*/"
+#define SD8897_DEFAULT_FW_NAME "/*(DEBLOBBED)*/"
 
 #define BLOCK_MODE	1
 #define BYTE_MODE	0
 
 #define REG_PORT			0
-#define RD_BITMAP_L			0x04
-#define RD_BITMAP_U			0x05
-#define WR_BITMAP_L			0x06
-#define WR_BITMAP_U			0x07
-#define RD_LEN_P0_L			0x08
-#define RD_LEN_P0_U			0x09
 
 #define MWIFIEX_SDIO_IO_PORT_MASK		0xfffff
 
 #define MWIFIEX_SDIO_BYTE_MODE_MASK	0x80000000
 
+#define SDIO_MPA_ADDR_BASE		0x1000
 #define CTRL_PORT			0
 #define CTRL_PORT_MASK			0x0001
-#define DATA_PORT_MASK			0xfffe
-
-#define MAX_MP_REGS			64
-#define MAX_PORT			16
 
-#define SDIO_MP_AGGR_DEF_PKT_LIMIT	8
+#define CMD_PORT_UPLD_INT_MASK		(0x1U<<6)
+#define CMD_PORT_DNLD_INT_MASK		(0x1U<<7)
+#define HOST_TERM_CMD53			(0x1U << 2)
+#define REG_PORT			0
+#define MEM_PORT			0x10000
+#define CMD_RD_LEN_0			0xB4
+#define CMD_RD_LEN_1			0xB5
+#define CARD_CONFIG_2_1_REG             0xCD
+#define CMD53_NEW_MODE			(0x1U << 0)
+#define CMD_CONFIG_0			0xB8
+#define CMD_PORT_RD_LEN_EN		(0x1U << 2)
+#define CMD_CONFIG_1			0xB9
+#define CMD_PORT_AUTO_EN		(0x1U << 0)
+#define CMD_PORT_SLCT			0x8000
+#define UP_LD_CMD_PORT_HOST_INT_STATUS	(0x40U)
+#define DN_LD_CMD_PORT_HOST_INT_STATUS	(0x80U)
 
 #define SDIO_MP_TX_AGGR_DEF_BUF_SIZE        (8192)	/* 8K */
 
@@ -75,14 +82,8 @@
 
 /* Host Control Registers : Configuration */
 #define CONFIGURATION_REG		0x00
-/* Host Control Registers : Host without Command 53 finish host*/
-#define HOST_TO_CARD_EVENT       (0x1U << 3)
-/* Host Control Registers : Host without Command 53 finish host */
-#define HOST_WO_CMD53_FINISH_HOST	(0x1U << 2)
 /* Host Control Registers : Host power up */
 #define HOST_POWER_UP			(0x1U << 1)
-/* Host Control Registers : Host power down */
-#define HOST_POWER_DOWN			(0x1U << 0)
 
 /* Host Control Registers : Host interrupt mask */
 #define HOST_INT_MASK_REG		0x02
@@ -90,10 +91,6 @@
 #define UP_LD_HOST_INT_MASK		(0x1U)
 /* Host Control Registers : Download host interrupt mask */
 #define DN_LD_HOST_INT_MASK		(0x2U)
-/* Enable Host interrupt mask */
-#define HOST_INT_ENABLE	(UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
-/* Disable Host interrupt mask */
-#define	HOST_INT_DISABLE		0xff
 
 /* Host Control Registers : Host interrupt status */
 #define HOST_INTSTATUS_REG		0x03
@@ -104,74 +101,15 @@
 
 /* Host Control Registers : Host interrupt RSR */
 #define HOST_INT_RSR_REG		0x01
-/* Host Control Registers : Upload host interrupt RSR */
-#define UP_LD_HOST_INT_RSR		(0x1U)
-#define SDIO_INT_MASK			0x3F
 
 /* Host Control Registers : Host interrupt status */
 #define HOST_INT_STATUS_REG		0x28
-/* Host Control Registers : Upload CRC error */
-#define UP_LD_CRC_ERR			(0x1U << 2)
-/* Host Control Registers : Upload restart */
-#define UP_LD_RESTART                   (0x1U << 1)
-/* Host Control Registers : Download restart */
-#define DN_LD_RESTART                   (0x1U << 0)
 
-/* Card Control Registers : Card status register */
-#define CARD_STATUS_REG                 0x30
 /* Card Control Registers : Card I/O ready */
 #define CARD_IO_READY                   (0x1U << 3)
-/* Card Control Registers : CIS card ready */
-#define CIS_CARD_RDY                    (0x1U << 2)
-/* Card Control Registers : Upload card ready */
-#define UP_LD_CARD_RDY                  (0x1U << 1)
 /* Card Control Registers : Download card ready */
 #define DN_LD_CARD_RDY                  (0x1U << 0)
 
-/* Card Control Registers : Host interrupt mask register */
-#define HOST_INTERRUPT_MASK_REG         0x34
-/* Card Control Registers : Host power interrupt mask */
-#define HOST_POWER_INT_MASK             (0x1U << 3)
-/* Card Control Registers : Abort card interrupt mask */
-#define ABORT_CARD_INT_MASK             (0x1U << 2)
-/* Card Control Registers : Upload card interrupt mask */
-#define UP_LD_CARD_INT_MASK             (0x1U << 1)
-/* Card Control Registers : Download card interrupt mask */
-#define DN_LD_CARD_INT_MASK             (0x1U << 0)
-
-/* Card Control Registers : Card interrupt status register */
-#define CARD_INTERRUPT_STATUS_REG       0x38
-/* Card Control Registers : Power up interrupt */
-#define POWER_UP_INT                    (0x1U << 4)
-/* Card Control Registers : Power down interrupt */
-#define POWER_DOWN_INT                  (0x1U << 3)
-
-/* Card Control Registers : Card interrupt RSR register */
-#define CARD_INTERRUPT_RSR_REG          0x3c
-/* Card Control Registers : Power up RSR */
-#define POWER_UP_RSR                    (0x1U << 4)
-/* Card Control Registers : Power down RSR */
-#define POWER_DOWN_RSR                  (0x1U << 3)
-
-/* Card Control Registers : Miscellaneous Configuration Register */
-#define CARD_MISC_CFG_REG               0x6C
-
-/* Host F1 read base 0 */
-#define HOST_F1_RD_BASE_0		0x0040
-/* Host F1 read base 1 */
-#define HOST_F1_RD_BASE_1		0x0041
-/* Host F1 card ready */
-#define HOST_F1_CARD_RDY		0x0020
-
-/* Firmware status 0 register */
-#define CARD_FW_STATUS0_REG		0x60
-/* Firmware status 1 register */
-#define CARD_FW_STATUS1_REG		0x61
-/* Rx length register */
-#define CARD_RX_LEN_REG			0x62
-/* Rx unit register */
-#define CARD_RX_UNIT_REG		0x63
-
 /* Max retry number of CMD53 write */
 #define MAX_WRITE_IOMEM_RETRY		2
 
@@ -192,7 +130,8 @@
 	if (a->mpa_tx.start_port <= port)				\
 		a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt));		\
 	else								\
-		a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+(MAX_PORT -	\
+		a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+		\
+						(a->max_ports -	\
 						a->mp_end_port)));	\
 	a->mpa_tx.pkt_cnt++;						\
 } while (0)
@@ -201,12 +140,6 @@
 #define MP_TX_AGGR_PKT_LIMIT_REACHED(a)					\
 			(a->mpa_tx.pkt_cnt == a->mpa_tx.pkt_aggr_limit)
 
-/* SDIO Tx aggregation port limit ? */
-#define MP_TX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_wr_port <		\
-			a->mpa_tx.start_port) && (((MAX_PORT -		\
-			a->mpa_tx.start_port) + a->curr_wr_port) >=	\
-				SDIO_MP_AGGR_DEF_PKT_LIMIT))
-
 /* Reset SDIO Tx aggregation buffer parameters */
 #define MP_TX_AGGR_BUF_RESET(a) do {					\
 	a->mpa_tx.pkt_cnt = 0;						\
@@ -219,12 +152,6 @@
 #define MP_RX_AGGR_PKT_LIMIT_REACHED(a)					\
 			(a->mpa_rx.pkt_cnt == a->mpa_rx.pkt_aggr_limit)
 
-/* SDIO Tx aggregation port limit ? */
-#define MP_RX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_rd_port <		\
-			a->mpa_rx.start_port) && (((MAX_PORT -		\
-			a->mpa_rx.start_port) + a->curr_rd_port) >=	\
-			SDIO_MP_AGGR_DEF_PKT_LIMIT))
-
 /* SDIO Rx aggregation in progress ? */
 #define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt > 0)
 
@@ -232,20 +159,6 @@
 #define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len)				\
 			((a->mpa_rx.buf_len+rx_len) <= a->mpa_rx.buf_size)
 
-/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
-#define MP_RX_AGGR_SETUP(a, skb, port) do {				\
-	a->mpa_rx.buf_len += skb->len;					\
-	if (!a->mpa_rx.pkt_cnt)						\
-		a->mpa_rx.start_port = port;				\
-	if (a->mpa_rx.start_port <= port)				\
-		a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt));		\
-	else								\
-		a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt+1));		\
-	a->mpa_rx.skb_arr[a->mpa_rx.pkt_cnt] = skb;			\
-	a->mpa_rx.len_arr[a->mpa_rx.pkt_cnt] = skb->len;		\
-	a->mpa_rx.pkt_cnt++;						\
-} while (0)
-
 /* Reset SDIO Rx aggregation buffer parameters */
 #define MP_RX_AGGR_BUF_RESET(a) do {					\
 	a->mpa_rx.pkt_cnt = 0;						\
@@ -254,14 +167,13 @@
 	a->mpa_rx.start_port = 0;					\
 } while (0)
 
-
 /* data structure for SDIO MPA TX */
 struct mwifiex_sdio_mpa_tx {
 	/* multiport tx aggregation buffer pointer */
 	u8 *buf;
 	u32 buf_len;
 	u32 pkt_cnt;
-	u16 ports;
+	u32 ports;
 	u16 start_port;
 	u8 enabled;
 	u32 buf_size;
@@ -272,11 +184,11 @@ struct mwifiex_sdio_mpa_rx {
 	u8 *buf;
 	u32 buf_len;
 	u32 pkt_cnt;
-	u16 ports;
+	u32 ports;
 	u16 start_port;
 
-	struct sk_buff *skb_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
-	u32 len_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
+	struct sk_buff **skb_arr;
+	u32 *len_arr;
 
 	u8 enabled;
 	u32 buf_size;
@@ -286,15 +198,47 @@ struct mwifiex_sdio_mpa_rx {
 int mwifiex_bus_register(void);
 void mwifiex_bus_unregister(void);
 
+struct mwifiex_sdio_card_reg {
+	u8 start_rd_port;
+	u8 start_wr_port;
+	u8 base_0_reg;
+	u8 base_1_reg;
+	u8 poll_reg;
+	u8 host_int_enable;
+	u8 status_reg_0;
+	u8 status_reg_1;
+	u8 sdio_int_mask;
+	u32 data_port_mask;
+	u8 max_mp_regs;
+	u8 rd_bitmap_l;
+	u8 rd_bitmap_u;
+	u8 rd_bitmap_1l;
+	u8 rd_bitmap_1u;
+	u8 wr_bitmap_l;
+	u8 wr_bitmap_u;
+	u8 wr_bitmap_1l;
+	u8 wr_bitmap_1u;
+	u8 rd_len_p0_l;
+	u8 rd_len_p0_u;
+	u8 card_misc_cfg_reg;
+};
+
 struct sdio_mmc_card {
 	struct sdio_func *func;
 	struct mwifiex_adapter *adapter;
 
-	u16 mp_rd_bitmap;
-	u16 mp_wr_bitmap;
+	const char *firmware;
+	const struct mwifiex_sdio_card_reg *reg;
+	u8 max_ports;
+	u8 mp_agg_pkt_limit;
+	bool supports_sdio_new_mode;
+	bool has_control_mask;
+
+	u32 mp_rd_bitmap;
+	u32 mp_wr_bitmap;
 
 	u16 mp_end_port;
-	u16 mp_data_port_mask;
+	u32 mp_data_port_mask;
 
 	u8 curr_rd_port;
 	u8 curr_wr_port;
@@ -305,6 +249,98 @@ struct sdio_mmc_card {
 	struct mwifiex_sdio_mpa_rx mpa_rx;
 };
 
+struct mwifiex_sdio_device {
+	const char *firmware;
+	const struct mwifiex_sdio_card_reg *reg;
+	u8 max_ports;
+	u8 mp_agg_pkt_limit;
+	bool supports_sdio_new_mode;
+	bool has_control_mask;
+};
+
+static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
+	.start_rd_port = 1,
+	.start_wr_port = 1,
+	.base_0_reg = 0x0040,
+	.base_1_reg = 0x0041,
+	.poll_reg = 0x30,
+	.host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK,
+	.status_reg_0 = 0x60,
+	.status_reg_1 = 0x61,
+	.sdio_int_mask = 0x3f,
+	.data_port_mask = 0x0000fffe,
+	.max_mp_regs = 64,
+	.rd_bitmap_l = 0x04,
+	.rd_bitmap_u = 0x05,
+	.wr_bitmap_l = 0x06,
+	.wr_bitmap_u = 0x07,
+	.rd_len_p0_l = 0x08,
+	.rd_len_p0_u = 0x09,
+	.card_misc_cfg_reg = 0x6c,
+};
+
+static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
+	.start_rd_port = 0,
+	.start_wr_port = 0,
+	.base_0_reg = 0x60,
+	.base_1_reg = 0x61,
+	.poll_reg = 0x50,
+	.host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK |
+			CMD_PORT_UPLD_INT_MASK | CMD_PORT_DNLD_INT_MASK,
+	.status_reg_0 = 0xc0,
+	.status_reg_1 = 0xc1,
+	.sdio_int_mask = 0xff,
+	.data_port_mask = 0xffffffff,
+	.max_mp_regs = 184,
+	.rd_bitmap_l = 0x04,
+	.rd_bitmap_u = 0x05,
+	.rd_bitmap_1l = 0x06,
+	.rd_bitmap_1u = 0x07,
+	.wr_bitmap_l = 0x08,
+	.wr_bitmap_u = 0x09,
+	.wr_bitmap_1l = 0x0a,
+	.wr_bitmap_1u = 0x0b,
+	.rd_len_p0_l = 0x0c,
+	.rd_len_p0_u = 0x0d,
+	.card_misc_cfg_reg = 0xcc,
+};
+
+static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
+	.firmware = SD8786_DEFAULT_FW_NAME,
+	.reg = &mwifiex_reg_sd87xx,
+	.max_ports = 16,
+	.mp_agg_pkt_limit = 8,
+	.supports_sdio_new_mode = false,
+	.has_control_mask = true,
+};
+
+static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
+	.firmware = SD8787_DEFAULT_FW_NAME,
+	.reg = &mwifiex_reg_sd87xx,
+	.max_ports = 16,
+	.mp_agg_pkt_limit = 8,
+	.supports_sdio_new_mode = false,
+	.has_control_mask = true,
+};
+
+static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
+	.firmware = SD8797_DEFAULT_FW_NAME,
+	.reg = &mwifiex_reg_sd87xx,
+	.max_ports = 16,
+	.mp_agg_pkt_limit = 8,
+	.supports_sdio_new_mode = false,
+	.has_control_mask = true,
+};
+
+static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
+	.firmware = SD8897_DEFAULT_FW_NAME,
+	.reg = &mwifiex_reg_sd8897,
+	.max_ports = 32,
+	.mp_agg_pkt_limit = 16,
+	.supports_sdio_new_mode = true,
+	.has_control_mask = false,
+};
+
 /*
  * .cmdrsp_complete handler
  */
@@ -325,4 +361,77 @@ static inline int mwifiex_sdio_event_com
 	return 0;
 }
 
+static inline bool
+mp_rx_aggr_port_limit_reached(struct sdio_mmc_card *card)
+{
+	u8 tmp;
+
+	if (card->curr_rd_port < card->mpa_rx.start_port) {
+		if (card->supports_sdio_new_mode)
+			tmp = card->mp_end_port >> 1;
+		else
+			tmp = card->mp_agg_pkt_limit;
+
+		if (((card->max_ports - card->mpa_rx.start_port) +
+		    card->curr_rd_port) >= tmp)
+			return true;
+	}
+
+	if (!card->supports_sdio_new_mode)
+		return false;
+
+	if ((card->curr_rd_port - card->mpa_rx.start_port) >=
+	    (card->mp_end_port >> 1))
+		return true;
+
+	return false;
+}
+
+static inline bool
+mp_tx_aggr_port_limit_reached(struct sdio_mmc_card *card)
+{
+	u16 tmp;
+
+	if (card->curr_wr_port < card->mpa_tx.start_port) {
+		if (card->supports_sdio_new_mode)
+			tmp = card->mp_end_port >> 1;
+		else
+			tmp = card->mp_agg_pkt_limit;
+
+		if (((card->max_ports - card->mpa_tx.start_port) +
+		    card->curr_wr_port) >= tmp)
+			return true;
+	}
+
+	if (!card->supports_sdio_new_mode)
+		return false;
+
+	if ((card->curr_wr_port - card->mpa_tx.start_port) >=
+	    (card->mp_end_port >> 1))
+		return true;
+
+	return false;
+}
+
+/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
+static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
+				    struct sk_buff *skb, u8 port)
+{
+	card->mpa_rx.buf_len += skb->len;
+
+	if (!card->mpa_rx.pkt_cnt)
+		card->mpa_rx.start_port = port;
+
+	if (card->supports_sdio_new_mode) {
+		card->mpa_rx.ports |= (1 << port);
+	} else {
+		if (card->mpa_rx.start_port <= port)
+			card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt);
+		else
+			card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt + 1);
+	}
+	card->mpa_rx.skb_arr[card->mpa_rx.pkt_cnt] = skb;
+	card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = skb->len;
+	card->mpa_rx.pkt_cnt++;
+}
 #endif /* _MWIFIEX_SDIO_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sta_cmd.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sta_cmd.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sta_cmd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sta_cmd.c	2013-08-25 20:43:22.000000000 -0400
@@ -1134,6 +1134,55 @@ mwifiex_cmd_mef_cfg(struct mwifiex_priva
 	return 0;
 }
 
+/* This function parse cal data from ASCII to hex */
+static u32 mwifiex_parse_cal_cfg(u8 *src, size_t len, u8 *dst)
+{
+	u8 *s = src, *d = dst;
+
+	while (s - src < len) {
+		if (*s && (isspace(*s) || *s == '\t')) {
+			s++;
+			continue;
+		}
+		if (isxdigit(*s)) {
+			*d++ = simple_strtol(s, NULL, 16);
+			s += 2;
+		} else {
+			s++;
+		}
+	}
+
+	return d - dst;
+}
+
+/* This function prepares command of set_cfg_data. */
+static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv,
+				struct host_cmd_ds_command *cmd,
+				u16 cmd_action)
+{
+	struct host_cmd_ds_802_11_cfg_data *cfg_data = &cmd->params.cfg_data;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u32 len, cal_data_offset;
+	u8 *tmp_cmd = (u8 *)cmd;
+
+	cal_data_offset = S_DS_GEN + sizeof(*cfg_data);
+	if ((adapter->cal_data->data) && (adapter->cal_data->size > 0))
+		len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data,
+					    adapter->cal_data->size,
+					    (u8 *)(tmp_cmd + cal_data_offset));
+	else
+		return -1;
+
+	cfg_data->action = cpu_to_le16(cmd_action);
+	cfg_data->type = cpu_to_le16(CFG_DATA_TYPE_CAL);
+	cfg_data->data_len = cpu_to_le16(len);
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA);
+	cmd->size = cpu_to_le16(S_DS_GEN + sizeof(*cfg_data) + len);
+
+	return 0;
+}
+
 /*
  * This function prepares the commands before sending them to the firmware.
  *
@@ -1152,6 +1201,9 @@ int mwifiex_sta_prepare_cmd(struct mwifi
 	case HostCmd_CMD_GET_HW_SPEC:
 		ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr);
 		break;
+	case HostCmd_CMD_CFG_DATA:
+		ret = mwifiex_cmd_cfg_data(priv, cmd_ptr, cmd_action);
+		break;
 	case HostCmd_CMD_MAC_CONTROL:
 		ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action,
 					      data_buf);
@@ -1384,6 +1436,7 @@ int mwifiex_sta_prepare_cmd(struct mwifi
  */
 int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
 {
+	struct mwifiex_adapter *adapter = priv->adapter;
 	int ret;
 	u16 enable = true;
 	struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
@@ -1404,6 +1457,15 @@ int mwifiex_sta_init_cmd(struct mwifiex_
 					    HostCmd_ACT_GEN_SET, 0, NULL);
 		if (ret)
 			return -1;
+
+		/* Download calibration data to firmware */
+		if (adapter->cal_data) {
+			ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA,
+						HostCmd_ACT_GEN_SET, 0, NULL);
+			if (ret)
+				return -1;
+		}
+
 		/* Read MAC address from HW */
 		ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC,
 					    HostCmd_ACT_GEN_GET, 0, NULL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sta_cmdresp.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sta_cmdresp.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sta_cmdresp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sta_cmdresp.c	2013-08-25 20:43:22.000000000 -0400
@@ -818,6 +818,18 @@ static int mwifiex_ret_subsc_evt(struct
 	return 0;
 }
 
+/* This function handles the command response of set_cfg_data */
+static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
+				struct host_cmd_ds_command *resp)
+{
+	if (resp->result != HostCmd_RESULT_OK) {
+		dev_err(priv->adapter->dev, "Cal data cmd resp failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 /*
  * This function handles the command responses.
  *
@@ -841,6 +853,9 @@ int mwifiex_process_sta_cmdresp(struct m
 	case HostCmd_CMD_GET_HW_SPEC:
 		ret = mwifiex_ret_get_hw_spec(priv, resp);
 		break;
+	case HostCmd_CMD_CFG_DATA:
+		ret = mwifiex_ret_cfg_data(priv, resp);
+		break;
 	case HostCmd_CMD_MAC_CONTROL:
 		break;
 	case HostCmd_CMD_802_11_MAC_ADDRESS:
@@ -978,6 +993,8 @@ int mwifiex_process_sta_cmdresp(struct m
 	case HostCmd_CMD_UAP_BSS_STOP:
 		priv->bss_started = 0;
 		break;
+	case HostCmd_CMD_UAP_STA_DEAUTH:
+		break;
 	case HostCmd_CMD_MEF_CFG:
 		break;
 	default:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sta_event.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sta_event.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sta_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sta_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -427,6 +427,17 @@ int mwifiex_process_sta_event(struct mwi
 
 		break;
 
+	case EVENT_CHANNEL_SWITCH_ANN:
+		dev_dbg(adapter->dev, "event: Channel Switch Announcement\n");
+		priv->csa_expire_time =
+				jiffies + msecs_to_jiffies(DFS_CHAN_MOVE_TIME);
+		priv->csa_chan = priv->curr_bss_params.bss_descriptor.channel;
+		ret = mwifiex_send_cmd_async(priv,
+			HostCmd_CMD_802_11_DEAUTHENTICATE,
+			HostCmd_ACT_GEN_SET, 0,
+			priv->curr_bss_params.bss_descriptor.mac_address);
+		break;
+
 	default:
 		dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
 			eventcause);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sta_ioctl.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sta_ioctl.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/sta_ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/sta_ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,16 +104,14 @@ int mwifiex_request_set_multicast_list(s
 		} else {
 			priv->curr_pkt_filter &=
 				~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
-			if (mcast_list->num_multicast_addr) {
-				dev_dbg(priv->adapter->dev,
-					"info: Set multicast list=%d\n",
-				       mcast_list->num_multicast_addr);
-				/* Send multicast addresses to firmware */
-				ret = mwifiex_send_cmd_async(priv,
-					HostCmd_CMD_MAC_MULTICAST_ADR,
-					HostCmd_ACT_GEN_SET, 0,
-					mcast_list);
-			}
+			dev_dbg(priv->adapter->dev,
+				"info: Set multicast list=%d\n",
+				mcast_list->num_multicast_addr);
+			/* Send multicast addresses to firmware */
+			ret = mwifiex_send_cmd_async(priv,
+				HostCmd_CMD_MAC_MULTICAST_ADR,
+				HostCmd_ACT_GEN_SET, 0,
+				mcast_list);
 		}
 	}
 	dev_dbg(priv->adapter->dev,
@@ -180,6 +178,9 @@ int mwifiex_fill_new_bss_desc(struct mwi
 	 */
 	bss_desc->disable_11ac = true;
 
+	if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_SPECTRUM_MGMT)
+		bss_desc->sensed_11h = true;
+
 	return mwifiex_update_bss_desc_with_ie(priv->adapter, bss_desc);
 }
 
@@ -256,31 +257,38 @@ int mwifiex_bss_start(struct mwifiex_pri
 			goto done;
 	}
 
-	if (priv->bss_mode == NL80211_IFTYPE_STATION) {
-		/* Infra mode */
+	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+	    priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
+		u8 config_bands;
+
 		ret = mwifiex_deauthenticate(priv, NULL);
 		if (ret)
 			goto done;
 
-		if (bss_desc) {
-			u8 config_bands = 0;
+		if (!bss_desc)
+			return -1;
 
-			if (mwifiex_band_to_radio_type((u8) bss_desc->bss_band)
-			    == HostCmd_SCAN_RADIO_TYPE_BG)
-				config_bands = BAND_B | BAND_G | BAND_GN |
-					       BAND_GAC;
-			else
-				config_bands = BAND_A | BAND_AN | BAND_AAC;
+		if (mwifiex_band_to_radio_type(bss_desc->bss_band) ==
+						HostCmd_SCAN_RADIO_TYPE_BG)
+			config_bands = BAND_B | BAND_G | BAND_GN | BAND_GAC;
+		else
+			config_bands = BAND_A | BAND_AN | BAND_AAC;
 
-			if (!((config_bands | adapter->fw_bands) &
-			      ~adapter->fw_bands))
-				adapter->config_bands = config_bands;
-		}
+		if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands))
+			adapter->config_bands = config_bands;
 
 		ret = mwifiex_check_network_compatibility(priv, bss_desc);
 		if (ret)
 			goto done;
 
+		if (mwifiex_11h_get_csa_closed_channel(priv) ==
+							(u8)bss_desc->channel) {
+			dev_err(adapter->dev,
+				"Attempt to reconnect on csa closed chan(%d)\n",
+				bss_desc->channel);
+			goto done;
+		}
+
 		dev_dbg(adapter->dev, "info: SSID found in scan list ... "
 				      "associating...\n");
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/uap_cmd.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/uap_cmd.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/uap_cmd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/uap_cmd.c	2013-08-25 20:43:22.000000000 -0400
@@ -689,6 +689,23 @@ mwifiex_cmd_uap_sys_config(struct host_c
 	return 0;
 }
 
+/* This function prepares AP specific deauth command with mac supplied in
+ * function parameter.
+ */
+static int mwifiex_cmd_uap_sta_deauth(struct mwifiex_private *priv,
+				      struct host_cmd_ds_command *cmd, u8 *mac)
+{
+	struct host_cmd_ds_sta_deauth *sta_deauth = &cmd->params.sta_deauth;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_UAP_STA_DEAUTH);
+	memcpy(sta_deauth->mac, mac, ETH_ALEN);
+	sta_deauth->reason = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
+
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_sta_deauth) +
+				S_DS_GEN);
+	return 0;
+}
+
 /* This function prepares the AP specific commands before sending them
  * to the firmware.
  * This is a generic function which calls specific command preparation
@@ -710,6 +727,10 @@ int mwifiex_uap_prepare_cmd(struct mwifi
 		cmd->command = cpu_to_le16(cmd_no);
 		cmd->size = cpu_to_le16(S_DS_GEN);
 		break;
+	case HostCmd_CMD_UAP_STA_DEAUTH:
+		if (mwifiex_cmd_uap_sta_deauth(priv, cmd, data_buf))
+			return -1;
+		break;
 	default:
 		dev_err(priv->adapter->dev,
 			"PREP_CMD: unknown cmd %#x\n", cmd_no);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/uap_event.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/uap_event.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/uap_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/uap_event.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,18 +107,15 @@ mwifiex_set_sta_ht_cap(struct mwifiex_pr
  */
 static void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac)
 {
-	struct mwifiex_sta_node *node, *tmp;
+	struct mwifiex_sta_node *node;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->sta_list_spinlock, flags);
 
 	node = mwifiex_get_sta_entry(priv, mac);
 	if (node) {
-		list_for_each_entry_safe(node, tmp, &priv->sta_list,
-					 list) {
-			list_del(&node->list);
-			kfree(node);
-		}
+		list_del(&node->list);
+		kfree(node);
 	}
 
 	spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
@@ -295,3 +292,19 @@ int mwifiex_process_uap_event(struct mwi
 
 	return 0;
 }
+
+/* This function deletes station entry from associated station list.
+ * Also if both AP and STA are 11n enabled, RxReorder tables and TxBA stream
+ * tables created for this station are deleted.
+ */
+void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
+			      struct mwifiex_sta_node *node)
+{
+	if (priv->ap_11n_enabled && node->is_11n_enabled) {
+		mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, node->mac_addr);
+		mwifiex_del_tx_ba_stream_tbl_by_ra(priv, node->mac_addr);
+	}
+	mwifiex_del_sta_entry(priv, node->mac_addr);
+
+	return;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/wmm.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/wmm.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwifiex/wmm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwifiex/wmm.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,6 +37,9 @@
 /* Offset for TOS field in the IP header */
 #define IPTOS_OFFSET 5
 
+static bool enable_tx_amsdu;
+module_param(enable_tx_amsdu, bool, 0644);
+
 /* WMM information IE */
 static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07,
 	0x00, 0x50, 0xf2, 0x02,
@@ -1233,7 +1236,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex
 				mwifiex_send_delba(priv, tid_del, ra, 1);
 			}
 		}
-		if (mwifiex_is_amsdu_allowed(priv, tid) &&
+		if (enable_tx_amsdu && mwifiex_is_amsdu_allowed(priv, tid) &&
 		    mwifiex_is_11n_aggragation_possible(priv, ptr,
 							adapter->tx_buf_size))
 			mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/mwl8k.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwl8k.c
--- linux-libre-3.10-gnu/drivers/net/wireless/mwl8k.c	2013-07-01 10:39:35.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/mwl8k.c	2013-08-31 17:59:11.000000000 -0400
@@ -1548,7 +1548,7 @@ static int mwl8k_tx_wait_empty(struct ie
 	if (!priv->pending_tx_pkts)
 		return 0;
 
-	retry = 0;
+	retry = 1;
 	rc = 0;
 
 	spin_lock_bh(&priv->tx_lock);
@@ -1572,13 +1572,19 @@ static int mwl8k_tx_wait_empty(struct ie
 
 		spin_lock_bh(&priv->tx_lock);
 
-		if (timeout) {
+		if (timeout || !priv->pending_tx_pkts) {
 			WARN_ON(priv->pending_tx_pkts);
 			if (retry)
 				wiphy_notice(hw->wiphy, "tx rings drained\n");
 			break;
 		}
 
+		if (retry) {
+			mwl8k_tx_start(priv);
+			retry = 0;
+			continue;
+		}
+
 		if (priv->pending_tx_pkts < oldcount) {
 			wiphy_notice(hw->wiphy,
 				     "waiting for tx rings to drain (%d -> %d pkts)\n",
@@ -2055,6 +2061,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
 				mwl8k_remove_stream(hw, stream);
 				spin_unlock(&priv->stream_lock);
 			}
+			mwl8k_tx_start(priv);
 			spin_unlock_bh(&priv->tx_lock);
 			pci_unmap_single(priv->pdev, dma, skb->len,
 					 PCI_DMA_TODEVICE);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/orinoco/orinoco_pci.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/orinoco/orinoco_pci.h
--- linux-libre-3.10-gnu/drivers/net/wireless/orinoco/orinoco_pci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/orinoco/orinoco_pci.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,7 @@ static int orinoco_pci_resume(struct pci
 	struct net_device *dev = priv->ndev;
 	int err;
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	err = pci_enable_device(pdev);
 	if (err) {
 		printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/orinoco/orinoco_usb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/orinoco/orinoco_usb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/orinoco/orinoco_usb.c	2013-07-01 10:38:17.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/orinoco/orinoco_usb.c	2013-08-31 17:57:52.000000000 -0400
@@ -881,7 +881,8 @@ static int ezusb_access_ltv(struct ezusb
 
 	if (!upriv->udev) {
 		dbg("Device disconnected");
-		return -ENODEV;
+		retval = -ENODEV;
+		goto exit;
 	}
 
 	if (upriv->read_urb->status != -EINPROGRESS)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/p54/p54spi.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/p54/p54spi.c
--- linux-libre-3.10-gnu/drivers/net/wireless/p54/p54spi.c	2013-07-01 10:39:55.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/p54/p54spi.c	2013-08-31 17:59:39.000000000 -0400
@@ -42,8 +42,7 @@
 
 /*(DEBLOBBED)*/
 
-/*
- * gpios should be handled in board files and provided via platform data,
+/* gpios should be handled in board files and provided via platform data,
  * but because it's currently impossible for p54spi to have a header file
  * in include/linux, let's use module paramaters for now
  */
@@ -191,8 +190,7 @@ static int p54spi_request_eeprom(struct
 	const struct firmware *eeprom;
 	int ret;
 
-	/*
-	 * allow users to customize their eeprom.
+	/* allow users to customize their eeprom.
 	 */
 
 	ret = reject_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
@@ -285,8 +283,7 @@ static void p54spi_power_on(struct p54s_
 	gpio_set_value(p54spi_gpio_power, 1);
 	enable_irq(gpio_to_irq(p54spi_gpio_irq));
 
-	/*
-	 * need to wait a while before device can be accessed, the length
+	/* need to wait a while before device can be accessed, the length
 	 * is just a guess
 	 */
 	msleep(10);
@@ -365,7 +362,8 @@ static int p54spi_rx(struct p54s_priv *p
 	/* Firmware may insert up to 4 padding bytes after the lmac header,
 	 * but it does not amend the size of SPI data transfer.
 	 * Such packets has correct data size in header, thus referencing
-	 * past the end of allocated skb. Reserve extra 4 bytes for this case */
+	 * past the end of allocated skb. Reserve extra 4 bytes for this case
+	 */
 	skb = dev_alloc_skb(len + 4);
 	if (!skb) {
 		p54spi_sleep(priv);
@@ -383,7 +381,8 @@ static int p54spi_rx(struct p54s_priv *p
 	}
 	p54spi_sleep(priv);
 	/* Put additional bytes to compensate for the possible
-	 * alignment-caused truncation */
+	 * alignment-caused truncation
+	 */
 	skb_put(skb, 4);
 
 	if (p54_rx(priv->hw, skb) == 0)
@@ -713,27 +712,7 @@ static struct spi_driver p54spi_driver =
 	.remove		= p54spi_remove,
 };
 
-static int __init p54spi_init(void)
-{
-	int ret;
-
-	ret = spi_register_driver(&p54spi_driver);
-	if (ret < 0) {
-		printk(KERN_ERR "failed to register SPI driver: %d", ret);
-		goto out;
-	}
-
-out:
-	return ret;
-}
-
-static void __exit p54spi_exit(void)
-{
-	spi_unregister_driver(&p54spi_driver);
-}
-
-module_init(p54spi_init);
-module_exit(p54spi_exit);
+module_spi_driver(p54spi_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,6 +1,6 @@
 menuconfig RT2X00
 	tristate "Ralink driver support"
-	depends on MAC80211
+	depends on MAC80211 && HAS_DMA
 	---help---
 	  This will enable the support for the Ralink drivers,
 	  developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2400pci.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2400pci.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2400pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2400pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -1767,33 +1767,45 @@ static const struct rt2x00lib_ops rt2400
 	.config			= rt2400pci_config,
 };
 
-static const struct data_queue_desc rt2400pci_queue_rx = {
-	.entry_num		= 24,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= RXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+static void rt2400pci_queue_init(struct data_queue *queue)
+{
+	switch (queue->qid) {
+	case QID_RX:
+		queue->limit = 24;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = RXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt2400pci_queue_tx = {
-	.entry_num		= 24,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_AC_VO:
+	case QID_AC_VI:
+	case QID_AC_BE:
+	case QID_AC_BK:
+		queue->limit = 24;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt2400pci_queue_bcn = {
-	.entry_num		= 1,
-	.data_size		= MGMT_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_BEACON:
+		queue->limit = 1;
+		queue->data_size = MGMT_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt2400pci_queue_atim = {
-	.entry_num		= 8,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_ATIM:
+		queue->limit = 8;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
+
+	default:
+		BUG();
+		break;
+	}
+}
 
 static const struct rt2x00_ops rt2400pci_ops = {
 	.name			= KBUILD_MODNAME,
@@ -1801,11 +1813,7 @@ static const struct rt2x00_ops rt2400pci
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= 0,
-	.rx			= &rt2400pci_queue_rx,
-	.tx			= &rt2400pci_queue_tx,
-	.bcn			= &rt2400pci_queue_bcn,
-	.atim			= &rt2400pci_queue_atim,
+	.queue_init		= rt2400pci_queue_init,
 	.lib			= &rt2400pci_rt2x00_ops,
 	.hw			= &rt2400pci_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2500pci.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2500pci.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2500pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2500pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -2056,33 +2056,45 @@ static const struct rt2x00lib_ops rt2500
 	.config			= rt2500pci_config,
 };
 
-static const struct data_queue_desc rt2500pci_queue_rx = {
-	.entry_num		= 32,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= RXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+static void rt2500pci_queue_init(struct data_queue *queue)
+{
+	switch (queue->qid) {
+	case QID_RX:
+		queue->limit = 32;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = RXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt2500pci_queue_tx = {
-	.entry_num		= 32,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_AC_VO:
+	case QID_AC_VI:
+	case QID_AC_BE:
+	case QID_AC_BK:
+		queue->limit = 32;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt2500pci_queue_bcn = {
-	.entry_num		= 1,
-	.data_size		= MGMT_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_BEACON:
+		queue->limit = 1;
+		queue->data_size = MGMT_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt2500pci_queue_atim = {
-	.entry_num		= 8,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_ATIM:
+		queue->limit = 8;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
+
+	default:
+		BUG();
+		break;
+	}
+}
 
 static const struct rt2x00_ops rt2500pci_ops = {
 	.name			= KBUILD_MODNAME,
@@ -2090,11 +2102,7 @@ static const struct rt2x00_ops rt2500pci
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= 0,
-	.rx			= &rt2500pci_queue_rx,
-	.tx			= &rt2500pci_queue_tx,
-	.bcn			= &rt2500pci_queue_bcn,
-	.atim			= &rt2500pci_queue_atim,
+	.queue_init		= rt2500pci_queue_init,
 	.lib			= &rt2500pci_rt2x00_ops,
 	.hw			= &rt2500pci_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2500usb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2500usb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2500usb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2500usb.c	2013-08-25 20:43:22.000000000 -0400
@@ -1867,33 +1867,45 @@ static const struct rt2x00lib_ops rt2500
 	.config			= rt2500usb_config,
 };
 
-static const struct data_queue_desc rt2500usb_queue_rx = {
-	.entry_num		= 32,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= RXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+static void rt2500usb_queue_init(struct data_queue *queue)
+{
+	switch (queue->qid) {
+	case QID_RX:
+		queue->limit = 32;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = RXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb);
+		break;
 
-static const struct data_queue_desc rt2500usb_queue_tx = {
-	.entry_num		= 32,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+	case QID_AC_VO:
+	case QID_AC_VI:
+	case QID_AC_BE:
+	case QID_AC_BK:
+		queue->limit = 32;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb);
+		break;
 
-static const struct data_queue_desc rt2500usb_queue_bcn = {
-	.entry_num		= 1,
-	.data_size		= MGMT_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb_bcn),
-};
+	case QID_BEACON:
+		queue->limit = 1;
+		queue->data_size = MGMT_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb_bcn);
+		break;
 
-static const struct data_queue_desc rt2500usb_queue_atim = {
-	.entry_num		= 8,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+	case QID_ATIM:
+		queue->limit = 8;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb);
+		break;
+
+	default:
+		BUG();
+		break;
+	}
+}
 
 static const struct rt2x00_ops rt2500usb_ops = {
 	.name			= KBUILD_MODNAME,
@@ -1901,11 +1913,7 @@ static const struct rt2x00_ops rt2500usb
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXD_DESC_SIZE,
-	.rx			= &rt2500usb_queue_rx,
-	.tx			= &rt2500usb_queue_tx,
-	.bcn			= &rt2500usb_queue_bcn,
-	.atim			= &rt2500usb_queue_atim,
+	.queue_init		= rt2500usb_queue_init,
 	.lib			= &rt2500usb_rt2x00_ops,
 	.hw			= &rt2500usb_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2800.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2800.h
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2800.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2800.h	2013-08-25 20:43:22.000000000 -0400
@@ -100,7 +100,7 @@
 #define CSR_REG_BASE			0x1000
 #define CSR_REG_SIZE			0x0800
 #define EEPROM_BASE			0x0000
-#define EEPROM_SIZE			0x0110
+#define EEPROM_SIZE			0x0200
 #define BBP_BASE			0x0000
 #define BBP_SIZE			0x00ff
 #define RF_BASE				0x0004
@@ -2625,11 +2625,13 @@ struct mac_iveiv_entry {
 /*
  * DMA descriptor defines.
  */
-#define TXWI_DESC_SIZE			(4 * sizeof(__le32))
-#define RXWI_DESC_SIZE			(4 * sizeof(__le32))
 
-#define TXWI_DESC_SIZE_5592		(5 * sizeof(__le32))
-#define RXWI_DESC_SIZE_5592		(6 * sizeof(__le32))
+#define TXWI_DESC_SIZE_4WORDS		(4 * sizeof(__le32))
+#define TXWI_DESC_SIZE_5WORDS		(5 * sizeof(__le32))
+
+#define RXWI_DESC_SIZE_4WORDS		(4 * sizeof(__le32))
+#define RXWI_DESC_SIZE_6WORDS		(6 * sizeof(__le32))
+
 /*
  * TX WI structure
  */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2800lib.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2800lib.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2800lib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2800lib.c	2013-08-25 20:43:22.000000000 -0400
@@ -840,7 +840,7 @@ static inline void rt2800_clear_beacon_r
 						unsigned int beacon_base)
 {
 	int i;
-	const int txwi_desc_size = rt2x00dev->ops->bcn->winfo_size;
+	const int txwi_desc_size = rt2x00dev->bcn->winfo_size;
 
 	/*
 	 * For the Beacon base registers we only need to clear
@@ -2392,7 +2392,7 @@ static void rt2800_config_channel_rf55xx
 	rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
 
 	rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
-	if (info->default_power1 > power_bound)
+	if (info->default_power2 > power_bound)
 		rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound);
 	else
 		rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2);
@@ -2678,30 +2678,53 @@ static void rt2800_config_channel(struct
 
 	tx_pin = 0;
 
-	/* Turn on unused PA or LNA when not using 1T or 1R */
-	if (rt2x00dev->default_ant.tx_chain_num == 2) {
+	switch (rt2x00dev->default_ant.tx_chain_num) {
+	case 3:
+		/* Turn on tertiary PAs */
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A2_EN,
+				   rf->channel > 14);
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G2_EN,
+				   rf->channel <= 14);
+		/* fall-through */
+	case 2:
+		/* Turn on secondary PAs */
 		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN,
 				   rf->channel > 14);
 		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN,
 				   rf->channel <= 14);
+		/* fall-through */
+	case 1:
+		/* Turn on primary PAs */
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN,
+				   rf->channel > 14);
+		if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
+			rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
+		else
+			rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
+					   rf->channel <= 14);
+		break;
 	}
 
-	/* Turn on unused PA or LNA when not using 1T or 1R */
-	if (rt2x00dev->default_ant.rx_chain_num == 2) {
+	switch (rt2x00dev->default_ant.rx_chain_num) {
+	case 3:
+		/* Turn on tertiary LNAs */
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1);
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1);
+		/* fall-through */
+	case 2:
+		/* Turn on secondary LNAs */
 		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
 		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
+		/* fall-through */
+	case 1:
+		/* Turn on primary LNAs */
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
+		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
+		break;
 	}
 
-	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
-	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
 	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
 	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
-	if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
-		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
-	else
-		rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
-				   rf->channel <= 14);
-	rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
 
 	rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
 
@@ -3960,379 +3983,577 @@ static void rt2800_init_bbp_early(struct
 	rt2800_bbp_write(rt2x00dev, 106, 0x35);
 }
 
-static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev)
+static void rt2800_disable_unused_dac_adc(struct rt2x00_dev *rt2x00dev)
 {
-	int ant, div_mode;
 	u16 eeprom;
 	u8 value;
 
-	rt2800_init_bbp_early(rt2x00dev);
+	rt2800_bbp_read(rt2x00dev, 138, &value);
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
+	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
+		value |= 0x20;
+	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
+		value &= ~0x02;
+	rt2800_bbp_write(rt2x00dev, 138, value);
+}
 
-	rt2800_bbp_read(rt2x00dev, 105, &value);
-	rt2x00_set_field8(&value, BBP105_MLD,
-			  rt2x00dev->default_ant.rx_chain_num == 2);
-	rt2800_bbp_write(rt2x00dev, 105, value);
+static void rt2800_init_bbp_305x_soc(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_bbp_write(rt2x00dev, 31, 0x08);
+
+	rt2800_bbp_write(rt2x00dev, 65, 0x2c);
+	rt2800_bbp_write(rt2x00dev, 66, 0x38);
+
+	rt2800_bbp_write(rt2x00dev, 69, 0x12);
+	rt2800_bbp_write(rt2x00dev, 73, 0x10);
+
+	rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+
+	rt2800_bbp_write(rt2x00dev, 78, 0x0e);
+	rt2800_bbp_write(rt2x00dev, 80, 0x08);
+
+	rt2800_bbp_write(rt2x00dev, 82, 0x62);
+
+	rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+
+	rt2800_bbp_write(rt2x00dev, 84, 0x99);
+
+	rt2800_bbp_write(rt2x00dev, 86, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 91, 0x04);
+
+	rt2800_bbp_write(rt2x00dev, 92, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+
+	rt2800_bbp_write(rt2x00dev, 105, 0x01);
+
+	rt2800_bbp_write(rt2x00dev, 106, 0x35);
+}
+
+static void rt2800_init_bbp_28xx(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_bbp_write(rt2x00dev, 65, 0x2c);
+	rt2800_bbp_write(rt2x00dev, 66, 0x38);
+
+	if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
+		rt2800_bbp_write(rt2x00dev, 69, 0x16);
+		rt2800_bbp_write(rt2x00dev, 73, 0x12);
+	} else {
+		rt2800_bbp_write(rt2x00dev, 69, 0x12);
+		rt2800_bbp_write(rt2x00dev, 73, 0x10);
+	}
+
+	rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+
+	rt2800_bbp_write(rt2x00dev, 81, 0x37);
+
+	rt2800_bbp_write(rt2x00dev, 82, 0x62);
+
+	rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+
+	if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
+		rt2800_bbp_write(rt2x00dev, 84, 0x19);
+	else
+		rt2800_bbp_write(rt2x00dev, 84, 0x99);
+
+	rt2800_bbp_write(rt2x00dev, 86, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 91, 0x04);
+
+	rt2800_bbp_write(rt2x00dev, 92, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 103, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 105, 0x05);
+
+	rt2800_bbp_write(rt2x00dev, 106, 0x35);
+}
+
+static void rt2800_init_bbp_30xx(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_bbp_write(rt2x00dev, 65, 0x2c);
+	rt2800_bbp_write(rt2x00dev, 66, 0x38);
+
+	rt2800_bbp_write(rt2x00dev, 69, 0x12);
+	rt2800_bbp_write(rt2x00dev, 73, 0x10);
+
+	rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+
+	rt2800_bbp_write(rt2x00dev, 79, 0x13);
+	rt2800_bbp_write(rt2x00dev, 80, 0x05);
+	rt2800_bbp_write(rt2x00dev, 81, 0x33);
+
+	rt2800_bbp_write(rt2x00dev, 82, 0x62);
+
+	rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+
+	rt2800_bbp_write(rt2x00dev, 84, 0x99);
+
+	rt2800_bbp_write(rt2x00dev, 86, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 91, 0x04);
+
+	rt2800_bbp_write(rt2x00dev, 92, 0x00);
+
+	if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
+	    rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
+	    rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E))
+		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+	else
+		rt2800_bbp_write(rt2x00dev, 103, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 105, 0x05);
+
+	rt2800_bbp_write(rt2x00dev, 106, 0x35);
+
+	if (rt2x00_rt(rt2x00dev, RT3071) ||
+	    rt2x00_rt(rt2x00dev, RT3090))
+		rt2800_disable_unused_dac_adc(rt2x00dev);
+}
+
+static void rt2800_init_bbp_3290(struct rt2x00_dev *rt2x00dev)
+{
+	u8 value;
 
 	rt2800_bbp4_mac_if_ctrl(rt2x00dev);
 
-	rt2800_bbp_write(rt2x00dev, 20, 0x06);
 	rt2800_bbp_write(rt2x00dev, 31, 0x08);
-	rt2800_bbp_write(rt2x00dev, 65, 0x2C);
-	rt2800_bbp_write(rt2x00dev, 68, 0xDD);
-	rt2800_bbp_write(rt2x00dev, 69, 0x1A);
-	rt2800_bbp_write(rt2x00dev, 70, 0x05);
+
+	rt2800_bbp_write(rt2x00dev, 65, 0x2c);
+	rt2800_bbp_write(rt2x00dev, 66, 0x38);
+
+	rt2800_bbp_write(rt2x00dev, 68, 0x0b);
+
+	rt2800_bbp_write(rt2x00dev, 69, 0x12);
 	rt2800_bbp_write(rt2x00dev, 73, 0x13);
-	rt2800_bbp_write(rt2x00dev, 74, 0x0F);
-	rt2800_bbp_write(rt2x00dev, 75, 0x4F);
+	rt2800_bbp_write(rt2x00dev, 75, 0x46);
+	rt2800_bbp_write(rt2x00dev, 76, 0x28);
+
+	rt2800_bbp_write(rt2x00dev, 77, 0x58);
+
+	rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+
+	rt2800_bbp_write(rt2x00dev, 74, 0x0b);
+	rt2800_bbp_write(rt2x00dev, 79, 0x18);
+	rt2800_bbp_write(rt2x00dev, 80, 0x09);
+	rt2800_bbp_write(rt2x00dev, 81, 0x33);
+
+	rt2800_bbp_write(rt2x00dev, 82, 0x62);
+
+	rt2800_bbp_write(rt2x00dev, 83, 0x7a);
+
+	rt2800_bbp_write(rt2x00dev, 84, 0x9a);
+
+	rt2800_bbp_write(rt2x00dev, 86, 0x38);
+
+	rt2800_bbp_write(rt2x00dev, 91, 0x04);
+
+	rt2800_bbp_write(rt2x00dev, 92, 0x02);
+
+	rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+
+	rt2800_bbp_write(rt2x00dev, 104, 0x92);
+
+	rt2800_bbp_write(rt2x00dev, 105, 0x1c);
+
+	rt2800_bbp_write(rt2x00dev, 106, 0x03);
+
+	rt2800_bbp_write(rt2x00dev, 128, 0x12);
+
+	rt2800_bbp_write(rt2x00dev, 67, 0x24);
+	rt2800_bbp_write(rt2x00dev, 143, 0x04);
+	rt2800_bbp_write(rt2x00dev, 142, 0x99);
+	rt2800_bbp_write(rt2x00dev, 150, 0x30);
+	rt2800_bbp_write(rt2x00dev, 151, 0x2e);
+	rt2800_bbp_write(rt2x00dev, 152, 0x20);
+	rt2800_bbp_write(rt2x00dev, 153, 0x34);
+	rt2800_bbp_write(rt2x00dev, 154, 0x40);
+	rt2800_bbp_write(rt2x00dev, 155, 0x3b);
+	rt2800_bbp_write(rt2x00dev, 253, 0x04);
+
+	rt2800_bbp_read(rt2x00dev, 47, &value);
+	rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1);
+	rt2800_bbp_write(rt2x00dev, 47, value);
+
+	/* Use 5-bit ADC for Acquisition and 8-bit ADC for data */
+	rt2800_bbp_read(rt2x00dev, 3, &value);
+	rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1);
+	rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1);
+	rt2800_bbp_write(rt2x00dev, 3, value);
+}
+
+static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_bbp_write(rt2x00dev, 3, 0x00);
+	rt2800_bbp_write(rt2x00dev, 4, 0x50);
+
+	rt2800_bbp_write(rt2x00dev, 31, 0x08);
+
+	rt2800_bbp_write(rt2x00dev, 47, 0x48);
+
+	rt2800_bbp_write(rt2x00dev, 65, 0x2c);
+	rt2800_bbp_write(rt2x00dev, 66, 0x38);
+
+	rt2800_bbp_write(rt2x00dev, 68, 0x0b);
+
+	rt2800_bbp_write(rt2x00dev, 69, 0x12);
+	rt2800_bbp_write(rt2x00dev, 73, 0x13);
+	rt2800_bbp_write(rt2x00dev, 75, 0x46);
 	rt2800_bbp_write(rt2x00dev, 76, 0x28);
+
 	rt2800_bbp_write(rt2x00dev, 77, 0x59);
-	rt2800_bbp_write(rt2x00dev, 84, 0x9A);
+
+	rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+
+	rt2800_bbp_write(rt2x00dev, 78, 0x0e);
+	rt2800_bbp_write(rt2x00dev, 80, 0x08);
+	rt2800_bbp_write(rt2x00dev, 81, 0x37);
+
+	rt2800_bbp_write(rt2x00dev, 82, 0x62);
+
+	rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+
+	rt2800_bbp_write(rt2x00dev, 84, 0x99);
+
 	rt2800_bbp_write(rt2x00dev, 86, 0x38);
+
 	rt2800_bbp_write(rt2x00dev, 88, 0x90);
+
 	rt2800_bbp_write(rt2x00dev, 91, 0x04);
+
 	rt2800_bbp_write(rt2x00dev, 92, 0x02);
-	rt2800_bbp_write(rt2x00dev, 95, 0x9a);
-	rt2800_bbp_write(rt2x00dev, 98, 0x12);
-	rt2800_bbp_write(rt2x00dev, 103, 0xC0);
+
+	rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+
 	rt2800_bbp_write(rt2x00dev, 104, 0x92);
-	/* FIXME BBP105 owerwrite */
-	rt2800_bbp_write(rt2x00dev, 105, 0x3C);
-	rt2800_bbp_write(rt2x00dev, 106, 0x35);
-	rt2800_bbp_write(rt2x00dev, 128, 0x12);
-	rt2800_bbp_write(rt2x00dev, 134, 0xD0);
-	rt2800_bbp_write(rt2x00dev, 135, 0xF6);
-	rt2800_bbp_write(rt2x00dev, 137, 0x0F);
 
-	/* Initialize GLRT (Generalized Likehood Radio Test) */
-	rt2800_init_bbp_5592_glrt(rt2x00dev);
+	rt2800_bbp_write(rt2x00dev, 105, 0x34);
 
-	rt2800_bbp4_mac_if_ctrl(rt2x00dev);
+	rt2800_bbp_write(rt2x00dev, 106, 0x05);
 
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
-	div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
-	ant = (div_mode == 3) ? 1 : 0;
-	rt2800_bbp_read(rt2x00dev, 152, &value);
-	if (ant == 0) {
-		/* Main antenna */
-		rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
-	} else {
-		/* Auxiliary antenna */
-		rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
-	}
-	rt2800_bbp_write(rt2x00dev, 152, value);
+	rt2800_bbp_write(rt2x00dev, 120, 0x50);
 
-	if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) {
-		rt2800_bbp_read(rt2x00dev, 254, &value);
-		rt2x00_set_field8(&value, BBP254_BIT7, 1);
-		rt2800_bbp_write(rt2x00dev, 254, value);
-	}
+	rt2800_bbp_write(rt2x00dev, 137, 0x0f);
 
-	rt2800_init_freq_calibration(rt2x00dev);
+	rt2800_bbp_write(rt2x00dev, 163, 0xbd);
+	/* Set ITxBF timeout to 0x9c40=1000msec */
+	rt2800_bbp_write(rt2x00dev, 179, 0x02);
+	rt2800_bbp_write(rt2x00dev, 180, 0x00);
+	rt2800_bbp_write(rt2x00dev, 182, 0x40);
+	rt2800_bbp_write(rt2x00dev, 180, 0x01);
+	rt2800_bbp_write(rt2x00dev, 182, 0x9c);
+	rt2800_bbp_write(rt2x00dev, 179, 0x00);
+	/* Reprogram the inband interface to put right values in RXWI */
+	rt2800_bbp_write(rt2x00dev, 142, 0x04);
+	rt2800_bbp_write(rt2x00dev, 143, 0x3b);
+	rt2800_bbp_write(rt2x00dev, 142, 0x06);
+	rt2800_bbp_write(rt2x00dev, 143, 0xa0);
+	rt2800_bbp_write(rt2x00dev, 142, 0x07);
+	rt2800_bbp_write(rt2x00dev, 143, 0xa1);
+	rt2800_bbp_write(rt2x00dev, 142, 0x08);
+	rt2800_bbp_write(rt2x00dev, 143, 0xa2);
 
-	rt2800_bbp_write(rt2x00dev, 84, 0x19);
-	if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C))
+	rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+}
+
+static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_bbp_write(rt2x00dev, 65, 0x2c);
+	rt2800_bbp_write(rt2x00dev, 66, 0x38);
+
+	rt2800_bbp_write(rt2x00dev, 69, 0x12);
+	rt2800_bbp_write(rt2x00dev, 73, 0x10);
+
+	rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+
+	rt2800_bbp_write(rt2x00dev, 79, 0x13);
+	rt2800_bbp_write(rt2x00dev, 80, 0x05);
+	rt2800_bbp_write(rt2x00dev, 81, 0x33);
+
+	rt2800_bbp_write(rt2x00dev, 82, 0x62);
+
+	rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+
+	rt2800_bbp_write(rt2x00dev, 84, 0x99);
+
+	rt2800_bbp_write(rt2x00dev, 86, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 91, 0x04);
+
+	rt2800_bbp_write(rt2x00dev, 92, 0x00);
+
+	if (rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E))
 		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+	else
+		rt2800_bbp_write(rt2x00dev, 103, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 105, 0x05);
+
+	rt2800_bbp_write(rt2x00dev, 106, 0x35);
+
+	rt2800_disable_unused_dac_adc(rt2x00dev);
 }
 
-static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
+static void rt2800_init_bbp_3572(struct rt2x00_dev *rt2x00dev)
 {
-	unsigned int i;
-	u16 eeprom;
-	u8 reg_id;
-	u8 value;
+	rt2800_bbp_write(rt2x00dev, 31, 0x08);
 
-	if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) ||
-		     rt2800_wait_bbp_ready(rt2x00dev)))
-		return -EACCES;
+	rt2800_bbp_write(rt2x00dev, 65, 0x2c);
+	rt2800_bbp_write(rt2x00dev, 66, 0x38);
 
-	if (rt2x00_rt(rt2x00dev, RT5592)) {
-		rt2800_init_bbp_5592(rt2x00dev);
-		return 0;
-	}
+	rt2800_bbp_write(rt2x00dev, 69, 0x12);
+	rt2800_bbp_write(rt2x00dev, 73, 0x10);
 
-	if (rt2x00_rt(rt2x00dev, RT3352)) {
-		rt2800_bbp_write(rt2x00dev, 3, 0x00);
-		rt2800_bbp_write(rt2x00dev, 4, 0x50);
-	}
+	rt2800_bbp_write(rt2x00dev, 70, 0x0a);
 
-	if (rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp4_mac_if_ctrl(rt2x00dev);
+	rt2800_bbp_write(rt2x00dev, 79, 0x13);
+	rt2800_bbp_write(rt2x00dev, 80, 0x05);
+	rt2800_bbp_write(rt2x00dev, 81, 0x33);
 
-	if (rt2800_is_305x_soc(rt2x00dev) ||
-	    rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT3352) ||
-	    rt2x00_rt(rt2x00dev, RT3572) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp_write(rt2x00dev, 31, 0x08);
+	rt2800_bbp_write(rt2x00dev, 82, 0x62);
 
-	if (rt2x00_rt(rt2x00dev, RT3352))
-		rt2800_bbp_write(rt2x00dev, 47, 0x48);
+	rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+
+	rt2800_bbp_write(rt2x00dev, 84, 0x99);
+
+	rt2800_bbp_write(rt2x00dev, 86, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 91, 0x04);
+
+	rt2800_bbp_write(rt2x00dev, 92, 0x00);
+
+	rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+
+	rt2800_bbp_write(rt2x00dev, 105, 0x05);
+
+	rt2800_bbp_write(rt2x00dev, 106, 0x35);
+
+	rt2800_disable_unused_dac_adc(rt2x00dev);
+}
+
+static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
+{
+	int ant, div_mode;
+	u16 eeprom;
+	u8 value;
+
+	rt2800_bbp4_mac_if_ctrl(rt2x00dev);
+
+	rt2800_bbp_write(rt2x00dev, 31, 0x08);
 
 	rt2800_bbp_write(rt2x00dev, 65, 0x2c);
 	rt2800_bbp_write(rt2x00dev, 66, 0x38);
 
-	if (rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT3352) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp_write(rt2x00dev, 68, 0x0b);
+	rt2800_bbp_write(rt2x00dev, 68, 0x0b);
 
-	if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
-		rt2800_bbp_write(rt2x00dev, 69, 0x16);
-		rt2800_bbp_write(rt2x00dev, 73, 0x12);
-	} else if (rt2x00_rt(rt2x00dev, RT3290) ||
-		   rt2x00_rt(rt2x00dev, RT3352) ||
-		   rt2x00_rt(rt2x00dev, RT5390) ||
-		   rt2x00_rt(rt2x00dev, RT5392)) {
-		rt2800_bbp_write(rt2x00dev, 69, 0x12);
-		rt2800_bbp_write(rt2x00dev, 73, 0x13);
-		rt2800_bbp_write(rt2x00dev, 75, 0x46);
-		rt2800_bbp_write(rt2x00dev, 76, 0x28);
+	rt2800_bbp_write(rt2x00dev, 69, 0x12);
+	rt2800_bbp_write(rt2x00dev, 73, 0x13);
+	rt2800_bbp_write(rt2x00dev, 75, 0x46);
+	rt2800_bbp_write(rt2x00dev, 76, 0x28);
 
-		if (rt2x00_rt(rt2x00dev, RT3290))
-			rt2800_bbp_write(rt2x00dev, 77, 0x58);
-		else
-			rt2800_bbp_write(rt2x00dev, 77, 0x59);
-	} else {
-		rt2800_bbp_write(rt2x00dev, 69, 0x12);
-		rt2800_bbp_write(rt2x00dev, 73, 0x10);
-	}
+	rt2800_bbp_write(rt2x00dev, 77, 0x59);
 
 	rt2800_bbp_write(rt2x00dev, 70, 0x0a);
 
-	if (rt2x00_rt(rt2x00dev, RT3070) ||
-	    rt2x00_rt(rt2x00dev, RT3071) ||
-	    rt2x00_rt(rt2x00dev, RT3090) ||
-	    rt2x00_rt(rt2x00dev, RT3390) ||
-	    rt2x00_rt(rt2x00dev, RT3572) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392)) {
-		rt2800_bbp_write(rt2x00dev, 79, 0x13);
-		rt2800_bbp_write(rt2x00dev, 80, 0x05);
-		rt2800_bbp_write(rt2x00dev, 81, 0x33);
-	} else if (rt2800_is_305x_soc(rt2x00dev)) {
-		rt2800_bbp_write(rt2x00dev, 78, 0x0e);
-		rt2800_bbp_write(rt2x00dev, 80, 0x08);
-	} else if (rt2x00_rt(rt2x00dev, RT3290)) {
-		rt2800_bbp_write(rt2x00dev, 74, 0x0b);
-		rt2800_bbp_write(rt2x00dev, 79, 0x18);
-		rt2800_bbp_write(rt2x00dev, 80, 0x09);
-		rt2800_bbp_write(rt2x00dev, 81, 0x33);
-	} else if (rt2x00_rt(rt2x00dev, RT3352)) {
-		rt2800_bbp_write(rt2x00dev, 78, 0x0e);
-		rt2800_bbp_write(rt2x00dev, 80, 0x08);
-		rt2800_bbp_write(rt2x00dev, 81, 0x37);
-	} else {
-		rt2800_bbp_write(rt2x00dev, 81, 0x37);
-	}
+	rt2800_bbp_write(rt2x00dev, 79, 0x13);
+	rt2800_bbp_write(rt2x00dev, 80, 0x05);
+	rt2800_bbp_write(rt2x00dev, 81, 0x33);
 
 	rt2800_bbp_write(rt2x00dev, 82, 0x62);
-	if (rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp_write(rt2x00dev, 83, 0x7a);
-	else
-		rt2800_bbp_write(rt2x00dev, 83, 0x6a);
 
-	if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
-		rt2800_bbp_write(rt2x00dev, 84, 0x19);
-	else if (rt2x00_rt(rt2x00dev, RT3290) ||
-		 rt2x00_rt(rt2x00dev, RT5390) ||
-		 rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp_write(rt2x00dev, 84, 0x9a);
-	else
-		rt2800_bbp_write(rt2x00dev, 84, 0x99);
+	rt2800_bbp_write(rt2x00dev, 83, 0x7a);
 
-	if (rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT3352) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp_write(rt2x00dev, 86, 0x38);
-	else
-		rt2800_bbp_write(rt2x00dev, 86, 0x00);
+	rt2800_bbp_write(rt2x00dev, 84, 0x9a);
 
-	if (rt2x00_rt(rt2x00dev, RT3352) ||
-	    rt2x00_rt(rt2x00dev, RT5392))
+	rt2800_bbp_write(rt2x00dev, 86, 0x38);
+
+	if (rt2x00_rt(rt2x00dev, RT5392))
 		rt2800_bbp_write(rt2x00dev, 88, 0x90);
 
 	rt2800_bbp_write(rt2x00dev, 91, 0x04);
 
-	if (rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT3352) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp_write(rt2x00dev, 92, 0x02);
-	else
-		rt2800_bbp_write(rt2x00dev, 92, 0x00);
+	rt2800_bbp_write(rt2x00dev, 92, 0x02);
 
 	if (rt2x00_rt(rt2x00dev, RT5392)) {
 		rt2800_bbp_write(rt2x00dev, 95, 0x9a);
 		rt2800_bbp_write(rt2x00dev, 98, 0x12);
 	}
 
-	if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
-	    rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
-	    rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
-	    rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
-	    rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT3352) ||
-	    rt2x00_rt(rt2x00dev, RT3572) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392) ||
-	    rt2800_is_305x_soc(rt2x00dev))
-		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
-	else
-		rt2800_bbp_write(rt2x00dev, 103, 0x00);
+	rt2800_bbp_write(rt2x00dev, 103, 0xc0);
 
-	if (rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT3352) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp_write(rt2x00dev, 104, 0x92);
+	rt2800_bbp_write(rt2x00dev, 104, 0x92);
 
-	if (rt2800_is_305x_soc(rt2x00dev))
-		rt2800_bbp_write(rt2x00dev, 105, 0x01);
-	else if (rt2x00_rt(rt2x00dev, RT3290))
-		rt2800_bbp_write(rt2x00dev, 105, 0x1c);
-	else if (rt2x00_rt(rt2x00dev, RT3352))
-		rt2800_bbp_write(rt2x00dev, 105, 0x34);
-	else if (rt2x00_rt(rt2x00dev, RT5390) ||
-		 rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp_write(rt2x00dev, 105, 0x3c);
-	else
-		rt2800_bbp_write(rt2x00dev, 105, 0x05);
+	rt2800_bbp_write(rt2x00dev, 105, 0x3c);
 
-	if (rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT5390))
+	if (rt2x00_rt(rt2x00dev, RT5390))
 		rt2800_bbp_write(rt2x00dev, 106, 0x03);
-	else if (rt2x00_rt(rt2x00dev, RT3352))
-		rt2800_bbp_write(rt2x00dev, 106, 0x05);
 	else if (rt2x00_rt(rt2x00dev, RT5392))
 		rt2800_bbp_write(rt2x00dev, 106, 0x12);
 	else
-		rt2800_bbp_write(rt2x00dev, 106, 0x35);
-
-	if (rt2x00_rt(rt2x00dev, RT3352))
-		rt2800_bbp_write(rt2x00dev, 120, 0x50);
+		WARN_ON(1);
 
-	if (rt2x00_rt(rt2x00dev, RT3290) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392))
-		rt2800_bbp_write(rt2x00dev, 128, 0x12);
+	rt2800_bbp_write(rt2x00dev, 128, 0x12);
 
 	if (rt2x00_rt(rt2x00dev, RT5392)) {
 		rt2800_bbp_write(rt2x00dev, 134, 0xd0);
 		rt2800_bbp_write(rt2x00dev, 135, 0xf6);
 	}
 
-	if (rt2x00_rt(rt2x00dev, RT3352))
-		rt2800_bbp_write(rt2x00dev, 137, 0x0f);
+	rt2800_disable_unused_dac_adc(rt2x00dev);
 
-	if (rt2x00_rt(rt2x00dev, RT3071) ||
-	    rt2x00_rt(rt2x00dev, RT3090) ||
-	    rt2x00_rt(rt2x00dev, RT3390) ||
-	    rt2x00_rt(rt2x00dev, RT3572) ||
-	    rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392)) {
-		rt2800_bbp_read(rt2x00dev, 138, &value);
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+	div_mode = rt2x00_get_field16(eeprom,
+				      EEPROM_NIC_CONF1_ANT_DIVERSITY);
+	ant = (div_mode == 3) ? 1 : 0;
 
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
-		if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
-			value |= 0x20;
-		if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
-			value &= ~0x02;
+	/* check if this is a Bluetooth combo card */
+	if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
+		u32 reg;
 
-		rt2800_bbp_write(rt2x00dev, 138, value);
+		rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
+		rt2x00_set_field32(&reg, GPIO_CTRL_DIR3, 0);
+		rt2x00_set_field32(&reg, GPIO_CTRL_DIR6, 0);
+		rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 0);
+		rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 0);
+		if (ant == 0)
+			rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 1);
+		else if (ant == 1)
+			rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 1);
+		rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
 	}
 
-	if (rt2x00_rt(rt2x00dev, RT3290)) {
-		rt2800_bbp_write(rt2x00dev, 67, 0x24);
-		rt2800_bbp_write(rt2x00dev, 143, 0x04);
-		rt2800_bbp_write(rt2x00dev, 142, 0x99);
-		rt2800_bbp_write(rt2x00dev, 150, 0x30);
-		rt2800_bbp_write(rt2x00dev, 151, 0x2e);
-		rt2800_bbp_write(rt2x00dev, 152, 0x20);
-		rt2800_bbp_write(rt2x00dev, 153, 0x34);
-		rt2800_bbp_write(rt2x00dev, 154, 0x40);
-		rt2800_bbp_write(rt2x00dev, 155, 0x3b);
-		rt2800_bbp_write(rt2x00dev, 253, 0x04);
+	/* This chip has hardware antenna diversity*/
+	if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) {
+		rt2800_bbp_write(rt2x00dev, 150, 0); /* Disable Antenna Software OFDM */
+		rt2800_bbp_write(rt2x00dev, 151, 0); /* Disable Antenna Software CCK */
+		rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */
+	}
 
-		rt2800_bbp_read(rt2x00dev, 47, &value);
-		rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1);
-		rt2800_bbp_write(rt2x00dev, 47, value);
+	rt2800_bbp_read(rt2x00dev, 152, &value);
+	if (ant == 0)
+		rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
+	else
+		rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
+	rt2800_bbp_write(rt2x00dev, 152, value);
 
-		/* Use 5-bit ADC for Acquisition and 8-bit ADC for data */
-		rt2800_bbp_read(rt2x00dev, 3, &value);
-		rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1);
-		rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1);
-		rt2800_bbp_write(rt2x00dev, 3, value);
-	}
+	rt2800_init_freq_calibration(rt2x00dev);
+}
 
-	if (rt2x00_rt(rt2x00dev, RT3352)) {
-		rt2800_bbp_write(rt2x00dev, 163, 0xbd);
-		/* Set ITxBF timeout to 0x9c40=1000msec */
-		rt2800_bbp_write(rt2x00dev, 179, 0x02);
-		rt2800_bbp_write(rt2x00dev, 180, 0x00);
-		rt2800_bbp_write(rt2x00dev, 182, 0x40);
-		rt2800_bbp_write(rt2x00dev, 180, 0x01);
-		rt2800_bbp_write(rt2x00dev, 182, 0x9c);
-		rt2800_bbp_write(rt2x00dev, 179, 0x00);
-		/* Reprogram the inband interface to put right values in RXWI */
-		rt2800_bbp_write(rt2x00dev, 142, 0x04);
-		rt2800_bbp_write(rt2x00dev, 143, 0x3b);
-		rt2800_bbp_write(rt2x00dev, 142, 0x06);
-		rt2800_bbp_write(rt2x00dev, 143, 0xa0);
-		rt2800_bbp_write(rt2x00dev, 142, 0x07);
-		rt2800_bbp_write(rt2x00dev, 143, 0xa1);
-		rt2800_bbp_write(rt2x00dev, 142, 0x08);
-		rt2800_bbp_write(rt2x00dev, 143, 0xa2);
+static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev)
+{
+	int ant, div_mode;
+	u16 eeprom;
+	u8 value;
 
-		rt2800_bbp_write(rt2x00dev, 148, 0xc8);
-	}
+	rt2800_init_bbp_early(rt2x00dev);
 
-	if (rt2x00_rt(rt2x00dev, RT5390) ||
-	    rt2x00_rt(rt2x00dev, RT5392)) {
-		int ant, div_mode;
+	rt2800_bbp_read(rt2x00dev, 105, &value);
+	rt2x00_set_field8(&value, BBP105_MLD,
+			  rt2x00dev->default_ant.rx_chain_num == 2);
+	rt2800_bbp_write(rt2x00dev, 105, value);
 
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
-		div_mode = rt2x00_get_field16(eeprom,
-					      EEPROM_NIC_CONF1_ANT_DIVERSITY);
-		ant = (div_mode == 3) ? 1 : 0;
+	rt2800_bbp4_mac_if_ctrl(rt2x00dev);
 
-		/* check if this is a Bluetooth combo card */
-		if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
-			u32 reg;
+	rt2800_bbp_write(rt2x00dev, 20, 0x06);
+	rt2800_bbp_write(rt2x00dev, 31, 0x08);
+	rt2800_bbp_write(rt2x00dev, 65, 0x2C);
+	rt2800_bbp_write(rt2x00dev, 68, 0xDD);
+	rt2800_bbp_write(rt2x00dev, 69, 0x1A);
+	rt2800_bbp_write(rt2x00dev, 70, 0x05);
+	rt2800_bbp_write(rt2x00dev, 73, 0x13);
+	rt2800_bbp_write(rt2x00dev, 74, 0x0F);
+	rt2800_bbp_write(rt2x00dev, 75, 0x4F);
+	rt2800_bbp_write(rt2x00dev, 76, 0x28);
+	rt2800_bbp_write(rt2x00dev, 77, 0x59);
+	rt2800_bbp_write(rt2x00dev, 84, 0x9A);
+	rt2800_bbp_write(rt2x00dev, 86, 0x38);
+	rt2800_bbp_write(rt2x00dev, 88, 0x90);
+	rt2800_bbp_write(rt2x00dev, 91, 0x04);
+	rt2800_bbp_write(rt2x00dev, 92, 0x02);
+	rt2800_bbp_write(rt2x00dev, 95, 0x9a);
+	rt2800_bbp_write(rt2x00dev, 98, 0x12);
+	rt2800_bbp_write(rt2x00dev, 103, 0xC0);
+	rt2800_bbp_write(rt2x00dev, 104, 0x92);
+	/* FIXME BBP105 owerwrite */
+	rt2800_bbp_write(rt2x00dev, 105, 0x3C);
+	rt2800_bbp_write(rt2x00dev, 106, 0x35);
+	rt2800_bbp_write(rt2x00dev, 128, 0x12);
+	rt2800_bbp_write(rt2x00dev, 134, 0xD0);
+	rt2800_bbp_write(rt2x00dev, 135, 0xF6);
+	rt2800_bbp_write(rt2x00dev, 137, 0x0F);
 
-			rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
-			rt2x00_set_field32(&reg, GPIO_CTRL_DIR3, 0);
-			rt2x00_set_field32(&reg, GPIO_CTRL_DIR6, 0);
-			rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 0);
-			rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 0);
-			if (ant == 0)
-				rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 1);
-			else if (ant == 1)
-				rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 1);
-			rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
-		}
+	/* Initialize GLRT (Generalized Likehood Radio Test) */
+	rt2800_init_bbp_5592_glrt(rt2x00dev);
 
-		/* This chip has hardware antenna diversity*/
-		if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) {
-			rt2800_bbp_write(rt2x00dev, 150, 0); /* Disable Antenna Software OFDM */
-			rt2800_bbp_write(rt2x00dev, 151, 0); /* Disable Antenna Software CCK */
-			rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */
-		}
+	rt2800_bbp4_mac_if_ctrl(rt2x00dev);
 
-		rt2800_bbp_read(rt2x00dev, 152, &value);
-		if (ant == 0)
-			rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
-		else
-			rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
-		rt2800_bbp_write(rt2x00dev, 152, value);
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+	div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
+	ant = (div_mode == 3) ? 1 : 0;
+	rt2800_bbp_read(rt2x00dev, 152, &value);
+	if (ant == 0) {
+		/* Main antenna */
+		rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
+	} else {
+		/* Auxiliary antenna */
+		rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
+	}
+	rt2800_bbp_write(rt2x00dev, 152, value);
 
-		rt2800_init_freq_calibration(rt2x00dev);
+	if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) {
+		rt2800_bbp_read(rt2x00dev, 254, &value);
+		rt2x00_set_field8(&value, BBP254_BIT7, 1);
+		rt2800_bbp_write(rt2x00dev, 254, value);
+	}
+
+	rt2800_init_freq_calibration(rt2x00dev);
+
+	rt2800_bbp_write(rt2x00dev, 84, 0x19);
+	if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C))
+		rt2800_bbp_write(rt2x00dev, 103, 0xc0);
+}
+
+static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+	unsigned int i;
+	u16 eeprom;
+	u8 reg_id;
+	u8 value;
+
+	if (rt2800_is_305x_soc(rt2x00dev))
+		rt2800_init_bbp_305x_soc(rt2x00dev);
+
+	switch (rt2x00dev->chip.rt) {
+	case RT2860:
+	case RT2872:
+	case RT2883:
+		rt2800_init_bbp_28xx(rt2x00dev);
+		break;
+	case RT3070:
+	case RT3071:
+	case RT3090:
+		rt2800_init_bbp_30xx(rt2x00dev);
+		break;
+	case RT3290:
+		rt2800_init_bbp_3290(rt2x00dev);
+		break;
+	case RT3352:
+		rt2800_init_bbp_3352(rt2x00dev);
+		break;
+	case RT3390:
+		rt2800_init_bbp_3390(rt2x00dev);
+		break;
+	case RT3572:
+		rt2800_init_bbp_3572(rt2x00dev);
+		break;
+	case RT5390:
+	case RT5392:
+		rt2800_init_bbp_53xx(rt2x00dev);
+		break;
+	case RT5592:
+		rt2800_init_bbp_5592(rt2x00dev);
+		return;
 	}
 
 	for (i = 0; i < EEPROM_BBP_SIZE; i++) {
@@ -4344,8 +4565,6 @@ static int rt2800_init_bbp(struct rt2x00
 			rt2800_bbp_write(rt2x00dev, reg_id, value);
 		}
 	}
-
-	return 0;
 }
 
 static void rt2800_led_open_drain_enable(struct rt2x00_dev *rt2x00dev)
@@ -5196,9 +5415,11 @@ int rt2800_enable_radio(struct rt2x00_de
 	}
 	msleep(1);
 
-	if (unlikely(rt2800_init_bbp(rt2x00dev)))
+	if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) ||
+		     rt2800_wait_bbp_ready(rt2x00dev)))
 		return -EIO;
 
+	rt2800_init_bbp(rt2x00dev);
 	rt2800_init_rfcsr(rt2x00dev);
 
 	if (rt2x00_is_usb(rt2x00dev) &&
@@ -6056,8 +6277,8 @@ static int rt2800_probe_hw_mode(struct r
 		default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
 
 		for (i = 14; i < spec->num_channels; i++) {
-			info[i].default_power1 = default_power1[i];
-			info[i].default_power2 = default_power2[i];
+			info[i].default_power1 = default_power1[i - 14];
+			info[i].default_power2 = default_power2[i - 14];
 		}
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2800pci.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2800pci.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2800pci.c	2013-07-01 10:40:16.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2800pci.c	2013-08-31 18:00:00.000000000 -0400
@@ -636,6 +636,7 @@ static void rt2800pci_write_tx_desc(stru
 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
 	__le32 *txd = entry_priv->desc;
 	u32 word;
+	const unsigned int txwi_size = entry->queue->winfo_size;
 
 	/*
 	 * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1
@@ -658,14 +659,14 @@ static void rt2800pci_write_tx_desc(stru
 			   !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
 	rt2x00_set_field32(&word, TXD_W1_BURST,
 			   test_bit(ENTRY_TXD_BURST, &txdesc->flags));
-	rt2x00_set_field32(&word, TXD_W1_SD_LEN0, TXWI_DESC_SIZE);
+	rt2x00_set_field32(&word, TXD_W1_SD_LEN0, txwi_size);
 	rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0);
 	rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);
 	rt2x00_desc_write(txd, 1, word);
 
 	word = 0;
 	rt2x00_set_field32(&word, TXD_W2_SD_PTR1,
-			   skbdesc->skb_dma + TXWI_DESC_SIZE);
+			   skbdesc->skb_dma + txwi_size);
 	rt2x00_desc_write(txd, 2, word);
 
 	word = 0;
@@ -1013,7 +1014,7 @@ static void rt2800pci_txstatus_interrupt
 	 * Since we have only one producer and one consumer we don't
 	 * need to lock the kfifo.
 	 */
-	for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
+	for (i = 0; i < rt2x00dev->tx->limit; i++) {
 		rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status);
 
 		if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
@@ -1185,29 +1186,43 @@ static const struct rt2x00lib_ops rt2800
 	.sta_remove		= rt2800_sta_remove,
 };
 
-static const struct data_queue_desc rt2800pci_queue_rx = {
-	.entry_num		= 128,
-	.data_size		= AGGREGATION_SIZE,
-	.desc_size		= RXD_DESC_SIZE,
-	.winfo_size		= RXWI_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+static void rt2800pci_queue_init(struct data_queue *queue)
+{
+	switch (queue->qid) {
+	case QID_RX:
+		queue->limit = 128;
+		queue->data_size = AGGREGATION_SIZE;
+		queue->desc_size = RXD_DESC_SIZE;
+		queue->winfo_size = RXWI_DESC_SIZE_4WORDS;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt2800pci_queue_tx = {
-	.entry_num		= 64,
-	.data_size		= AGGREGATION_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.winfo_size		= TXWI_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_AC_VO:
+	case QID_AC_VI:
+	case QID_AC_BE:
+	case QID_AC_BK:
+		queue->limit = 64;
+		queue->data_size = AGGREGATION_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->winfo_size = TXWI_DESC_SIZE_4WORDS;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt2800pci_queue_bcn = {
-	.entry_num		= 8,
-	.data_size		= 0, /* No DMA required for beacons */
-	.desc_size		= TXD_DESC_SIZE,
-	.winfo_size		= TXWI_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_BEACON:
+		queue->limit = 8;
+		queue->data_size = 0; /* No DMA required for beacons */
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->winfo_size = TXWI_DESC_SIZE_4WORDS;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
+
+	case QID_ATIM:
+		/* fallthrough */
+	default:
+		BUG();
+		break;
+	}
+}
 
 static const struct rt2x00_ops rt2800pci_ops = {
 	.name			= KBUILD_MODNAME,
@@ -1216,10 +1231,7 @@ static const struct rt2x00_ops rt2800pci
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXWI_DESC_SIZE,
-	.rx			= &rt2800pci_queue_rx,
-	.tx			= &rt2800pci_queue_tx,
-	.bcn			= &rt2800pci_queue_bcn,
+	.queue_init		= rt2800pci_queue_init,
 	.lib			= &rt2800pci_rt2x00_ops,
 	.drv			= &rt2800pci_rt2800_ops,
 	.hw			= &rt2800pci_mac80211_ops,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2800usb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2800usb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2800usb.c	2013-07-01 10:40:20.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2800usb.c	2013-08-31 18:00:05.000000000 -0400
@@ -327,7 +327,7 @@ static int rt2800usb_enable_radio(struct
 	 * this limit so reduce the number to prevent errors.
 	 */
 	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
-			   ((rt2x00dev->ops->rx->entry_num * DATA_FRAME_SIZE)
+			   ((rt2x00dev->rx->limit * DATA_FRAME_SIZE)
 			    / 1024) - 3);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
@@ -849,85 +849,63 @@ static const struct rt2x00lib_ops rt2800
 	.sta_remove		= rt2800_sta_remove,
 };
 
-static const struct data_queue_desc rt2800usb_queue_rx = {
-	.entry_num		= 128,
-	.data_size		= AGGREGATION_SIZE,
-	.desc_size		= RXINFO_DESC_SIZE,
-	.winfo_size		= RXWI_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
-
-static const struct data_queue_desc rt2800usb_queue_tx = {
-	.entry_num		= 16,
-	.data_size		= AGGREGATION_SIZE,
-	.desc_size		= TXINFO_DESC_SIZE,
-	.winfo_size		= TXWI_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
-
-static const struct data_queue_desc rt2800usb_queue_bcn = {
-	.entry_num		= 8,
-	.data_size		= MGMT_FRAME_SIZE,
-	.desc_size		= TXINFO_DESC_SIZE,
-	.winfo_size		= TXWI_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+static void rt2800usb_queue_init(struct data_queue *queue)
+{
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	unsigned short txwi_size, rxwi_size;
 
-static const struct rt2x00_ops rt2800usb_ops = {
-	.name			= KBUILD_MODNAME,
-	.drv_data_size		= sizeof(struct rt2800_drv_data),
-	.max_ap_intf		= 8,
-	.eeprom_size		= EEPROM_SIZE,
-	.rf_size		= RF_SIZE,
-	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
-	.rx			= &rt2800usb_queue_rx,
-	.tx			= &rt2800usb_queue_tx,
-	.bcn			= &rt2800usb_queue_bcn,
-	.lib			= &rt2800usb_rt2x00_ops,
-	.drv			= &rt2800usb_rt2800_ops,
-	.hw			= &rt2800usb_mac80211_ops,
-#ifdef CONFIG_RT2X00_LIB_DEBUGFS
-	.debugfs		= &rt2800_rt2x00debug,
-#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
-};
+	if (rt2x00_rt(rt2x00dev, RT5592)) {
+		txwi_size = TXWI_DESC_SIZE_5WORDS;
+		rxwi_size = RXWI_DESC_SIZE_6WORDS;
+	} else {
+		txwi_size = TXWI_DESC_SIZE_4WORDS;
+		rxwi_size = RXWI_DESC_SIZE_4WORDS;
+	}
 
-static const struct data_queue_desc rt2800usb_queue_rx_5592 = {
-	.entry_num		= 128,
-	.data_size		= AGGREGATION_SIZE,
-	.desc_size		= RXINFO_DESC_SIZE,
-	.winfo_size		= RXWI_DESC_SIZE_5592,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+	switch (queue->qid) {
+	case QID_RX:
+		queue->limit = 128;
+		queue->data_size = AGGREGATION_SIZE;
+		queue->desc_size = RXINFO_DESC_SIZE;
+		queue->winfo_size = rxwi_size;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb);
+		break;
 
-static const struct data_queue_desc rt2800usb_queue_tx_5592 = {
-	.entry_num		= 16,
-	.data_size		= AGGREGATION_SIZE,
-	.desc_size		= TXINFO_DESC_SIZE,
-	.winfo_size		= TXWI_DESC_SIZE_5592,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+	case QID_AC_VO:
+	case QID_AC_VI:
+	case QID_AC_BE:
+	case QID_AC_BK:
+		queue->limit = 16;
+		queue->data_size = AGGREGATION_SIZE;
+		queue->desc_size = TXINFO_DESC_SIZE;
+		queue->winfo_size = txwi_size;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb);
+		break;
 
-static const struct data_queue_desc rt2800usb_queue_bcn_5592 = {
-	.entry_num		= 8,
-	.data_size		= MGMT_FRAME_SIZE,
-	.desc_size		= TXINFO_DESC_SIZE,
-	.winfo_size		= TXWI_DESC_SIZE_5592,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+	case QID_BEACON:
+		queue->limit = 8;
+		queue->data_size = MGMT_FRAME_SIZE;
+		queue->desc_size = TXINFO_DESC_SIZE;
+		queue->winfo_size = txwi_size;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb);
+		break;
 
+	case QID_ATIM:
+		/* fallthrough */
+	default:
+		BUG();
+		break;
+	}
+}
 
-static const struct rt2x00_ops rt2800usb_ops_5592 = {
+static const struct rt2x00_ops rt2800usb_ops = {
 	.name			= KBUILD_MODNAME,
 	.drv_data_size		= sizeof(struct rt2800_drv_data),
 	.max_ap_intf		= 8,
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXINFO_DESC_SIZE + TXWI_DESC_SIZE_5592,
-	.rx			= &rt2800usb_queue_rx_5592,
-	.tx			= &rt2800usb_queue_tx_5592,
-	.bcn			= &rt2800usb_queue_bcn_5592,
+	.queue_init		= rt2800usb_queue_init,
 	.lib			= &rt2800usb_rt2x00_ops,
 	.drv			= &rt2800usb_rt2800_ops,
 	.hw			= &rt2800usb_mac80211_ops,
@@ -1248,15 +1226,15 @@ static struct usb_device_id rt2800usb_de
 #endif
 #ifdef CONFIG_RT2800USB_RT55XX
 	/* Arcadyan */
-	{ USB_DEVICE(0x043e, 0x7a32), .driver_info = 5592 },
+	{ USB_DEVICE(0x043e, 0x7a32) },
 	/* AVM GmbH */
-	{ USB_DEVICE(0x057c, 0x8501), .driver_info = 5592 },
+	{ USB_DEVICE(0x057c, 0x8501) },
 	/* D-Link DWA-160-B2 */
-	{ USB_DEVICE(0x2001, 0x3c1a), .driver_info = 5592 },
+	{ USB_DEVICE(0x2001, 0x3c1a) },
 	/* Proware */
-	{ USB_DEVICE(0x043e, 0x7a13), .driver_info = 5592 },
+	{ USB_DEVICE(0x043e, 0x7a13) },
 	/* Ralink */
-	{ USB_DEVICE(0x148f, 0x5572), .driver_info = 5592 },
+	{ USB_DEVICE(0x148f, 0x5572) },
 #endif
 #ifdef CONFIG_RT2800USB_UNKNOWN
 	/*
@@ -1361,9 +1339,6 @@ MODULE_LICENSE("GPL");
 static int rt2800usb_probe(struct usb_interface *usb_intf,
 			   const struct usb_device_id *id)
 {
-	if (id->driver_info == 5592)
-		return rt2x00usb_probe(usb_intf, &rt2800usb_ops_5592);
-
 	return rt2x00usb_probe(usb_intf, &rt2800usb_ops);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00dev.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00dev.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00dev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00dev.c	2013-08-25 20:43:22.000000000 -0400
@@ -334,7 +334,7 @@ void rt2x00lib_txdone(struct queue_entry
 	/*
 	 * Remove the extra tx headroom from the skb.
 	 */
-	skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom);
+	skb_pull(entry->skb, rt2x00dev->extra_tx_headroom);
 
 	/*
 	 * Signal that the TX descriptor is no longer in the skb.
@@ -1049,7 +1049,7 @@ static int rt2x00lib_probe_hw(struct rt2
 	 */
 	rt2x00dev->hw->extra_tx_headroom =
 		max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
-		      rt2x00dev->ops->extra_tx_headroom);
+		      rt2x00dev->extra_tx_headroom);
 
 	/*
 	 * Take TX headroom required for alignment into account.
@@ -1077,7 +1077,7 @@ static int rt2x00lib_probe_hw(struct rt2
 		 */
 		int kfifo_size =
 			roundup_pow_of_two(rt2x00dev->ops->tx_queues *
-					   rt2x00dev->ops->tx->entry_num *
+					   rt2x00dev->tx->limit *
 					   sizeof(u32));
 
 		status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,
@@ -1256,6 +1256,17 @@ static inline void rt2x00lib_set_if_comb
 	rt2x00dev->hw->wiphy->n_iface_combinations = 1;
 }
 
+static unsigned int rt2x00dev_extra_tx_headroom(struct rt2x00_dev *rt2x00dev)
+{
+	if (WARN_ON(!rt2x00dev->tx))
+		return 0;
+
+	if (rt2x00_is_usb(rt2x00dev))
+		return rt2x00dev->tx[0].winfo_size + rt2x00dev->tx[0].desc_size;
+
+	return rt2x00dev->tx[0].winfo_size;
+}
+
 /*
  * driver allocation handlers.
  */
@@ -1301,27 +1312,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
 		(rt2x00dev->ops->max_ap_intf - 1);
 
 	/*
-	 * Determine which operating modes are supported, all modes
-	 * which require beaconing, depend on the availability of
-	 * beacon entries.
-	 */
-	rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-	if (rt2x00dev->ops->bcn->entry_num > 0)
-		rt2x00dev->hw->wiphy->interface_modes |=
-		    BIT(NL80211_IFTYPE_ADHOC) |
-		    BIT(NL80211_IFTYPE_AP) |
-#ifdef CONFIG_MAC80211_MESH
-		    BIT(NL80211_IFTYPE_MESH_POINT) |
-#endif
-		    BIT(NL80211_IFTYPE_WDS);
-
-	rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
-
-	/*
 	 * Initialize work.
 	 */
 	rt2x00dev->workqueue =
-	    alloc_ordered_workqueue(wiphy_name(rt2x00dev->hw->wiphy), 0);
+	    alloc_ordered_workqueue("%s", 0, wiphy_name(rt2x00dev->hw->wiphy));
 	if (!rt2x00dev->workqueue) {
 		retval = -ENOMEM;
 		goto exit;
@@ -1347,6 +1341,26 @@ int rt2x00lib_probe_dev(struct rt2x00_de
 	if (retval)
 		goto exit;
 
+	/* Cache TX headroom value */
+	rt2x00dev->extra_tx_headroom = rt2x00dev_extra_tx_headroom(rt2x00dev);
+
+	/*
+	 * Determine which operating modes are supported, all modes
+	 * which require beaconing, depend on the availability of
+	 * beacon entries.
+	 */
+	rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+	if (rt2x00dev->bcn->limit > 0)
+		rt2x00dev->hw->wiphy->interface_modes |=
+		    BIT(NL80211_IFTYPE_ADHOC) |
+		    BIT(NL80211_IFTYPE_AP) |
+#ifdef CONFIG_MAC80211_MESH
+		    BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
+		    BIT(NL80211_IFTYPE_WDS);
+
+	rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
 	/*
 	 * Initialize ieee80211 structure.
 	 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00.h
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00.h	2013-08-25 20:43:22.000000000 -0400
@@ -648,11 +648,7 @@ struct rt2x00_ops {
 	const unsigned int eeprom_size;
 	const unsigned int rf_size;
 	const unsigned int tx_queues;
-	const unsigned int extra_tx_headroom;
-	const struct data_queue_desc *rx;
-	const struct data_queue_desc *tx;
-	const struct data_queue_desc *bcn;
-	const struct data_queue_desc *atim;
+	void (*queue_init)(struct data_queue *queue);
 	const struct rt2x00lib_ops *lib;
 	const void *drv;
 	const struct ieee80211_ops *hw;
@@ -1010,6 +1006,9 @@ struct rt2x00_dev {
 	 */
 	struct list_head bar_list;
 	spinlock_t bar_list_lock;
+
+	/* Extra TX headroom required for alignment purposes. */
+	unsigned int extra_tx_headroom;
 };
 
 struct rt2x00_bar_list_entry {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00pci.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00pci.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -105,11 +105,13 @@ int rt2x00pci_probe(struct pci_dev *pci_
 		goto exit_release_regions;
 	}
 
+	pci_enable_msi(pci_dev);
+
 	hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
 	if (!hw) {
 		rt2x00_probe_err("Failed to allocate hardware\n");
 		retval = -ENOMEM;
-		goto exit_release_regions;
+		goto exit_disable_msi;
 	}
 
 	pci_set_drvdata(pci_dev, hw);
@@ -150,6 +152,9 @@ exit_free_reg:
 exit_free_device:
 	ieee80211_free_hw(hw);
 
+exit_disable_msi:
+	pci_disable_msi(pci_dev);
+
 exit_release_regions:
 	pci_release_regions(pci_dev);
 
@@ -174,6 +179,8 @@ void rt2x00pci_remove(struct pci_dev *pc
 	rt2x00pci_free_reg(rt2x00dev);
 	ieee80211_free_hw(hw);
 
+	pci_disable_msi(pci_dev);
+
 	/*
 	 * Free the PCI device data.
 	 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00queue.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00queue.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00queue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00queue.c	2013-08-25 20:43:22.000000000 -0400
@@ -542,8 +542,8 @@ static int rt2x00queue_write_tx_data(str
 	/*
 	 * Add the requested extra tx headroom in front of the skb.
 	 */
-	skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom);
-	memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom);
+	skb_push(entry->skb, rt2x00dev->extra_tx_headroom);
+	memset(entry->skb->data, 0, rt2x00dev->extra_tx_headroom);
 
 	/*
 	 * Call the driver's write_tx_data function, if it exists.
@@ -596,7 +596,7 @@ static void rt2x00queue_bar_check(struct
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct ieee80211_bar *bar = (void *) (entry->skb->data +
-				    rt2x00dev->ops->extra_tx_headroom);
+				    rt2x00dev->extra_tx_headroom);
 	struct rt2x00_bar_list_entry *bar_entry;
 
 	if (likely(!ieee80211_is_back_req(bar->frame_control)))
@@ -936,13 +936,8 @@ void rt2x00queue_index_inc(struct queue_
 	spin_unlock_irqrestore(&queue->index_lock, irqflags);
 }
 
-void rt2x00queue_pause_queue(struct data_queue *queue)
+void rt2x00queue_pause_queue_nocheck(struct data_queue *queue)
 {
-	if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
-	    !test_bit(QUEUE_STARTED, &queue->flags) ||
-	    test_and_set_bit(QUEUE_PAUSED, &queue->flags))
-		return;
-
 	switch (queue->qid) {
 	case QID_AC_VO:
 	case QID_AC_VI:
@@ -958,6 +953,15 @@ void rt2x00queue_pause_queue(struct data
 		break;
 	}
 }
+void rt2x00queue_pause_queue(struct data_queue *queue)
+{
+	if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
+	    !test_bit(QUEUE_STARTED, &queue->flags) ||
+	    test_and_set_bit(QUEUE_PAUSED, &queue->flags))
+		return;
+
+	rt2x00queue_pause_queue_nocheck(queue);
+}
 EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue);
 
 void rt2x00queue_unpause_queue(struct data_queue *queue)
@@ -1019,7 +1023,7 @@ void rt2x00queue_stop_queue(struct data_
 		return;
 	}
 
-	rt2x00queue_pause_queue(queue);
+	rt2x00queue_pause_queue_nocheck(queue);
 
 	queue->rt2x00dev->ops->lib->stop_queue(queue);
 
@@ -1161,8 +1165,7 @@ void rt2x00queue_init_queues(struct rt2x
 	}
 }
 
-static int rt2x00queue_alloc_entries(struct data_queue *queue,
-				     const struct data_queue_desc *qdesc)
+static int rt2x00queue_alloc_entries(struct data_queue *queue)
 {
 	struct queue_entry *entries;
 	unsigned int entry_size;
@@ -1170,16 +1173,10 @@ static int rt2x00queue_alloc_entries(str
 
 	rt2x00queue_reset(queue);
 
-	queue->limit = qdesc->entry_num;
-	queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10);
-	queue->data_size = qdesc->data_size;
-	queue->desc_size = qdesc->desc_size;
-	queue->winfo_size = qdesc->winfo_size;
-
 	/*
 	 * Allocate all queue entries.
 	 */
-	entry_size = sizeof(*entries) + qdesc->priv_size;
+	entry_size = sizeof(*entries) + queue->priv_size;
 	entries = kcalloc(queue->limit, entry_size, GFP_KERNEL);
 	if (!entries)
 		return -ENOMEM;
@@ -1195,7 +1192,7 @@ static int rt2x00queue_alloc_entries(str
 		entries[i].entry_idx = i;
 		entries[i].priv_data =
 		    QUEUE_ENTRY_PRIV_OFFSET(entries, i, queue->limit,
-					    sizeof(*entries), qdesc->priv_size);
+					    sizeof(*entries), queue->priv_size);
 	}
 
 #undef QUEUE_ENTRY_PRIV_OFFSET
@@ -1237,23 +1234,22 @@ int rt2x00queue_initialize(struct rt2x00
 	struct data_queue *queue;
 	int status;
 
-	status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx);
+	status = rt2x00queue_alloc_entries(rt2x00dev->rx);
 	if (status)
 		goto exit;
 
 	tx_queue_for_each(rt2x00dev, queue) {
-		status = rt2x00queue_alloc_entries(queue, rt2x00dev->ops->tx);
+		status = rt2x00queue_alloc_entries(queue);
 		if (status)
 			goto exit;
 	}
 
-	status = rt2x00queue_alloc_entries(rt2x00dev->bcn, rt2x00dev->ops->bcn);
+	status = rt2x00queue_alloc_entries(rt2x00dev->bcn);
 	if (status)
 		goto exit;
 
 	if (test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) {
-		status = rt2x00queue_alloc_entries(rt2x00dev->atim,
-						   rt2x00dev->ops->atim);
+		status = rt2x00queue_alloc_entries(rt2x00dev->atim);
 		if (status)
 			goto exit;
 	}
@@ -1297,6 +1293,10 @@ static void rt2x00queue_init(struct rt2x
 	queue->aifs = 2;
 	queue->cw_min = 5;
 	queue->cw_max = 10;
+
+	rt2x00dev->ops->queue_init(queue);
+
+	queue->threshold = DIV_ROUND_UP(queue->limit, 10);
 }
 
 int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00queue.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00queue.h
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt2x00queue.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt2x00queue.h	2013-08-25 20:43:22.000000000 -0400
@@ -453,6 +453,7 @@ enum data_queue_flags {
  * @cw_max: The cw max value for outgoing frames (field ignored in RX queue).
  * @data_size: Maximum data size for the frames in this queue.
  * @desc_size: Hardware descriptor size for the data in this queue.
+ * @priv_size: Size of per-queue_entry private data.
  * @usb_endpoint: Device endpoint used for communication (USB only)
  * @usb_maxpacket: Max packet size for given endpoint (USB only)
  */
@@ -481,31 +482,13 @@ struct data_queue {
 	unsigned short data_size;
 	unsigned char  desc_size;
 	unsigned char  winfo_size;
+	unsigned short priv_size;
 
 	unsigned short usb_endpoint;
 	unsigned short usb_maxpacket;
 };
 
 /**
- * struct data_queue_desc: Data queue description
- *
- * The information in this structure is used by drivers
- * to inform rt2x00lib about the creation of the data queue.
- *
- * @entry_num: Maximum number of entries for a queue.
- * @data_size: Maximum data size for the frames in this queue.
- * @desc_size: Hardware descriptor size for the data in this queue.
- * @priv_size: Size of per-queue_entry private data.
- */
-struct data_queue_desc {
-	unsigned short entry_num;
-	unsigned short data_size;
-	unsigned char  desc_size;
-	unsigned char  winfo_size;
-	unsigned short priv_size;
-};
-
-/**
  * queue_end - Return pointer to the last queue (HELPER MACRO).
  * @__dev: Pointer to &struct rt2x00_dev
  *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt61pci.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt61pci.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt61pci.c	2013-07-01 10:40:07.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt61pci.c	2013-08-31 17:59:51.000000000 -0400
@@ -2175,7 +2175,7 @@ static void rt61pci_txdone(struct rt2x00
 	 * that the TX_STA_FIFO stack has a size of 16. We stick to our
 	 * tx ring size for now.
 	 */
-	for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
+	for (i = 0; i < rt2x00dev->tx->limit; i++) {
 		rt2x00mmio_register_read(rt2x00dev, STA_CSR4, &reg);
 		if (!rt2x00_get_field32(reg, STA_CSR4_VALID))
 			break;
@@ -2825,7 +2825,8 @@ static int rt61pci_probe_hw_mode(struct
 		tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
 		for (i = 14; i < spec->num_channels; i++) {
 			info[i].max_power = MAX_TXPOWER;
-			info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+			info[i].default_power1 =
+					TXPOWER_FROM_DEV(tx_power[i - 14]);
 		}
 	}
 
@@ -3025,26 +3026,40 @@ static const struct rt2x00lib_ops rt61pc
 	.config			= rt61pci_config,
 };
 
-static const struct data_queue_desc rt61pci_queue_rx = {
-	.entry_num		= 32,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= RXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+static void rt61pci_queue_init(struct data_queue *queue)
+{
+	switch (queue->qid) {
+	case QID_RX:
+		queue->limit = 32;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = RXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt61pci_queue_tx = {
-	.entry_num		= 32,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_AC_VO:
+	case QID_AC_VI:
+	case QID_AC_BE:
+	case QID_AC_BK:
+		queue->limit = 32;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
 
-static const struct data_queue_desc rt61pci_queue_bcn = {
-	.entry_num		= 4,
-	.data_size		= 0, /* No DMA required for beacons */
-	.desc_size		= TXINFO_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_mmio),
-};
+	case QID_BEACON:
+		queue->limit = 4;
+		queue->data_size = 0; /* No DMA required for beacons */
+		queue->desc_size = TXINFO_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
+
+	case QID_ATIM:
+		/* fallthrough */
+	default:
+		BUG();
+		break;
+	}
+}
 
 static const struct rt2x00_ops rt61pci_ops = {
 	.name			= KBUILD_MODNAME,
@@ -3052,10 +3067,7 @@ static const struct rt2x00_ops rt61pci_o
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= 0,
-	.rx			= &rt61pci_queue_rx,
-	.tx			= &rt61pci_queue_tx,
-	.bcn			= &rt61pci_queue_bcn,
+	.queue_init		= rt61pci_queue_init,
 	.lib			= &rt61pci_rt2x00_ops,
 	.hw			= &rt61pci_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt73usb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt73usb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rt2x00/rt73usb.c	2013-07-01 10:40:12.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rt2x00/rt73usb.c	2013-08-31 17:59:56.000000000 -0400
@@ -2167,7 +2167,8 @@ static int rt73usb_probe_hw_mode(struct
 		tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
 		for (i = 14; i < spec->num_channels; i++) {
 			info[i].max_power = MAX_TXPOWER;
-			info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]);
+			info[i].default_power1 =
+					TXPOWER_FROM_DEV(tx_power[i - 14]);
 		}
 	}
 
@@ -2359,26 +2360,40 @@ static const struct rt2x00lib_ops rt73us
 	.config			= rt73usb_config,
 };
 
-static const struct data_queue_desc rt73usb_queue_rx = {
-	.entry_num		= 32,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= RXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+static void rt73usb_queue_init(struct data_queue *queue)
+{
+	switch (queue->qid) {
+	case QID_RX:
+		queue->limit = 32;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = RXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb);
+		break;
 
-static const struct data_queue_desc rt73usb_queue_tx = {
-	.entry_num		= 32,
-	.data_size		= DATA_FRAME_SIZE,
-	.desc_size		= TXD_DESC_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+	case QID_AC_VO:
+	case QID_AC_VI:
+	case QID_AC_BE:
+	case QID_AC_BK:
+		queue->limit = 32;
+		queue->data_size = DATA_FRAME_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb);
+		break;
 
-static const struct data_queue_desc rt73usb_queue_bcn = {
-	.entry_num		= 4,
-	.data_size		= MGMT_FRAME_SIZE,
-	.desc_size		= TXINFO_SIZE,
-	.priv_size		= sizeof(struct queue_entry_priv_usb),
-};
+	case QID_BEACON:
+		queue->limit = 4;
+		queue->data_size = MGMT_FRAME_SIZE;
+		queue->desc_size = TXINFO_SIZE;
+		queue->priv_size = sizeof(struct queue_entry_priv_usb);
+		break;
+
+	case QID_ATIM:
+		/* fallthrough */
+	default:
+		BUG();
+		break;
+	}
+}
 
 static const struct rt2x00_ops rt73usb_ops = {
 	.name			= KBUILD_MODNAME,
@@ -2386,10 +2401,7 @@ static const struct rt2x00_ops rt73usb_o
 	.eeprom_size		= EEPROM_SIZE,
 	.rf_size		= RF_SIZE,
 	.tx_queues		= NUM_TX_QUEUES,
-	.extra_tx_headroom	= TXD_DESC_SIZE,
-	.rx			= &rt73usb_queue_rx,
-	.tx			= &rt73usb_queue_tx,
-	.bcn			= &rt73usb_queue_bcn,
+	.queue_init		= rt73usb_queue_init,
 	.lib			= &rt73usb_rt2x00_ops,
 	.hw			= &rt73usb_mac80211_ops,
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/base.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/base.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/base.c	2013-08-25 20:43:22.000000000 -0400
@@ -172,6 +172,7 @@ u8 rtl_tid_to_ac(u8 tid)
 {
 	return tid_to_ac[tid];
 }
+EXPORT_SYMBOL_GPL(rtl_tid_to_ac);
 
 static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
 				  struct ieee80211_sta_ht_cap *ht_cap)
@@ -380,7 +381,7 @@ static void _rtl_init_deferred_work(stru
 
 	/* <2> work queue */
 	rtlpriv->works.hw = hw;
-	rtlpriv->works.rtl_wq = alloc_workqueue(rtlpriv->cfg->name, 0, 0);
+	rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name);
 	INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
 			  (void *)rtl_watchdog_wq_callback);
 	INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
@@ -406,6 +407,7 @@ void rtl_deinit_deferred_work(struct iee
 	cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
 	cancel_delayed_work(&rtlpriv->works.fwevt_wq);
 }
+EXPORT_SYMBOL_GPL(rtl_deinit_deferred_work);
 
 void rtl_init_rfkill(struct ieee80211_hw *hw)
 {
@@ -439,6 +441,7 @@ void rtl_deinit_rfkill(struct ieee80211_
 {
 	wiphy_rfkill_stop_polling(hw->wiphy);
 }
+EXPORT_SYMBOL_GPL(rtl_deinit_rfkill);
 
 int rtl_init_core(struct ieee80211_hw *hw)
 {
@@ -489,10 +492,12 @@ int rtl_init_core(struct ieee80211_hw *h
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(rtl_init_core);
 
 void rtl_deinit_core(struct ieee80211_hw *hw)
 {
 }
+EXPORT_SYMBOL_GPL(rtl_deinit_core);
 
 void rtl_init_rx_config(struct ieee80211_hw *hw)
 {
@@ -501,6 +506,7 @@ void rtl_init_rx_config(struct ieee80211
 
 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
 }
+EXPORT_SYMBOL_GPL(rtl_init_rx_config);
 
 /*********************************************************
  *
@@ -879,6 +885,7 @@ bool rtl_tx_mgmt_proc(struct ieee80211_h
 
 	return true;
 }
+EXPORT_SYMBOL_GPL(rtl_tx_mgmt_proc);
 
 void rtl_get_tcb_desc(struct ieee80211_hw *hw,
 		      struct ieee80211_tx_info *info,
@@ -1052,6 +1059,7 @@ bool rtl_action_proc(struct ieee80211_hw
 
 	return true;
 }
+EXPORT_SYMBOL_GPL(rtl_action_proc);
 
 /*should call before software enc*/
 u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
@@ -1125,6 +1133,7 @@ u8 rtl_is_special_data(struct ieee80211_
 
 	return false;
 }
+EXPORT_SYMBOL_GPL(rtl_is_special_data);
 
 /*********************************************************
  *
@@ -1300,6 +1309,7 @@ void rtl_beacon_statistic(struct ieee802
 
 	rtlpriv->link_info.bcn_rx_inperiod++;
 }
+EXPORT_SYMBOL_GPL(rtl_beacon_statistic);
 
 void rtl_watchdog_wq_callback(void *data)
 {
@@ -1793,6 +1803,7 @@ void rtl_recognize_peer(struct ieee80211
 
 	mac->vendor = vendor;
 }
+EXPORT_SYMBOL_GPL(rtl_recognize_peer);
 
 /*********************************************************
  *
@@ -1817,7 +1828,7 @@ static ssize_t rtl_store_debug_level(str
 	unsigned long val;
 	int ret;
 
-	ret = strict_strtoul(buf, 0, &val);
+	ret = kstrtoul(buf, 0, &val);
 	if (ret) {
 		printk(KERN_DEBUG "%s is not in hex or decimal form.\n", buf);
 	} else {
@@ -1849,6 +1860,7 @@ struct attribute_group rtl_attribute_gro
 	.name = "rtlsysfs",
 	.attrs = rtl_sysfs_entries,
 };
+EXPORT_SYMBOL_GPL(rtl_attribute_group);
 
 MODULE_AUTHOR("lizhaoming	<chaoming_li@realsil.com.cn>");
 MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>");
@@ -1856,7 +1868,8 @@ MODULE_AUTHOR("Larry Finger	<Larry.FInge
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
 
-struct rtl_global_var global_var = {};
+struct rtl_global_var rtl_global_var = {};
+EXPORT_SYMBOL_GPL(rtl_global_var);
 
 static int __init rtl_core_module_init(void)
 {
@@ -1864,8 +1877,8 @@ static int __init rtl_core_module_init(v
 		pr_err("Unable to register rtl_rc, use default RC !!\n");
 
 	/* init some global vars */
-	INIT_LIST_HEAD(&global_var.glb_priv_list);
-	spin_lock_init(&global_var.glb_list_lock);
+	INIT_LIST_HEAD(&rtl_global_var.glb_priv_list);
+	spin_lock_init(&rtl_global_var.glb_list_lock);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/base.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/base.h
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/base.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/base.h	2013-08-25 20:43:22.000000000 -0400
@@ -147,7 +147,7 @@ void rtl_recognize_peer(struct ieee80211
 u8 rtl_tid_to_ac(u8 tid);
 extern struct attribute_group rtl_attribute_group;
 void rtl_easy_concurrent_retrytimer_callback(unsigned long data);
-extern struct rtl_global_var global_var;
+extern struct rtl_global_var rtl_global_var;
 int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
 			 bool isht, u8 desc_rate, bool first_ampdu);
 bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/core.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/core.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -1330,3 +1330,4 @@ const struct ieee80211_ops rtl_ops = {
 	.rfkill_poll = rtl_op_rfkill_poll,
 	.flush = rtl_op_flush,
 };
+EXPORT_SYMBOL_GPL(rtl_ops);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/debug.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/debug.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,3 +51,4 @@ void rtl_dbgp_flag_init(struct ieee80211
 
 	/*Init Debug flag enable condition */
 }
+EXPORT_SYMBOL_GPL(rtl_dbgp_flag_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/efuse.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/efuse.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/efuse.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/efuse.c	2013-08-25 20:43:22.000000000 -0400
@@ -229,6 +229,7 @@ void read_efuse_byte(struct ieee80211_hw
 
 	*pbuf = (u8) (value32 & 0xff);
 }
+EXPORT_SYMBOL_GPL(read_efuse_byte);
 
 void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/Kconfig linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/Kconfig
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -1,27 +1,20 @@
-config RTLWIFI
-	tristate "Realtek wireless card support"
-	depends on MAC80211
-	select FW_LOADER
-	---help---
-	  This is common code for RTL8192CE/RTL8192CU/RTL8192SE/RTL8723AE
-	  drivers.  This module does nothing by itself - the various front-end
-	  drivers need to be enabled to support any desired devices.
-
-	  If you choose to build as a module, it'll be called rtlwifi.
-
-config RTLWIFI_DEBUG
-	bool "Debugging output for rtlwifi driver family"
-	depends on RTLWIFI
+menuconfig RTL_CARDS
+	tristate "Realtek rtlwifi family of devices"
+	depends on MAC80211 && (PCI || USB)
 	default y
 	---help---
-	To use the module option that sets the dynamic-debugging level for,
-	the front-end driver, this parameter must be "Y". For memory-limited
-	systems, choose "N". If in doubt, choose "Y".
+	  This option will enable support for the Realtek mac80211-based
+	  wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de,
+	  rtl8723eu, and rtl8188eu share some common code.
+
+if RTL_CARDS
 
 config RTL8192CE
 	tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter"
-	depends on RTLWIFI && PCI
+	depends on PCI
 	select RTL8192C_COMMON
+	select RTLWIFI
+	select RTLWIFI_PCI
 	---help---
 	This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe
 	wireless network adapters.
@@ -30,7 +23,9 @@ config RTL8192CE
 
 config RTL8192SE
 	tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter"
-	depends on RTLWIFI && PCI
+	depends on PCI
+	select RTLWIFI
+	select RTLWIFI_PCI
 	---help---
 	This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe
 	wireless network adapters.
@@ -39,7 +34,9 @@ config RTL8192SE
 
 config RTL8192DE
 	tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter"
-	depends on RTLWIFI && PCI
+	depends on PCI
+	select RTLWIFI
+	select RTLWIFI_PCI
 	---help---
 	This is the driver for Realtek RTL8192DE/RTL8188DE 802.11n PCIe
 	wireless network adapters.
@@ -48,7 +45,9 @@ config RTL8192DE
 
 config RTL8723AE
 	tristate "Realtek RTL8723AE PCIe Wireless Network Adapter"
-	depends on RTLWIFI && PCI
+	depends on PCI
+	select RTLWIFI
+	select RTLWIFI_PCI
 	---help---
 	This is the driver for Realtek RTL8723AE 802.11n PCIe
 	wireless network adapters.
@@ -57,7 +56,9 @@ config RTL8723AE
 
 config RTL8188EE
 	tristate "Realtek RTL8188EE Wireless Network Adapter"
-	depends on RTLWIFI && PCI
+	depends on PCI
+	select RTLWIFI
+	select RTLWIFI_PCI
 	---help---
 	This is the driver for Realtek RTL8188EE 802.11n PCIe
 	wireless network adapters.
@@ -66,7 +67,9 @@ config RTL8188EE
 
 config RTL8192CU
 	tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
-	depends on RTLWIFI && USB
+	depends on USB
+	select RTLWIFI
+	select RTLWIFI_USB
 	select RTL8192C_COMMON
 	---help---
 	This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB
@@ -74,7 +77,28 @@ config RTL8192CU
 
 	If you choose to build it as a module, it will be called rtl8192cu
 
+config RTLWIFI
+	tristate
+	select FW_LOADER
+
+config RTLWIFI_PCI
+	tristate
+
+config RTLWIFI_USB
+	tristate
+
+config RTLWIFI_DEBUG
+	bool "Debugging output for rtlwifi driver family"
+	depends on RTLWIFI
+	default y
+	---help---
+	To use the module option that sets the dynamic-debugging level for,
+	the front-end driver, this parameter must be "Y". For memory-limited
+	systems, choose "N". If in doubt, choose "Y".
+
 config RTL8192C_COMMON
 	tristate
 	depends on RTL8192CE || RTL8192CU
-	default m
+	default y
+
+endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -12,13 +12,11 @@ rtlwifi-objs	:=		\
 
 rtl8192c_common-objs +=		\
 
-ifneq ($(CONFIG_PCI),)
-rtlwifi-objs	+= pci.o
-endif
+obj-$(CONFIG_RTLWIFI_PCI)	+= rtl_pci.o
+rtl_pci-objs	:=		pci.o
 
-ifneq ($(CONFIG_USB),)
-rtlwifi-objs	+= usb.o
-endif
+obj-$(CONFIG_RTLWIFI_USB)	+= rtl_usb.o
+rtl_usb-objs	:=		usb.o
 
 obj-$(CONFIG_RTL8192C_COMMON)	+= rtl8192c/
 obj-$(CONFIG_RTL8192CE)		+= rtl8192ce/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/pci.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/pci.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,13 @@
 #include "efuse.h"
 #include <linux/export.h>
 #include <linux/kmemleak.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("lizhaoming	<chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger	<Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PCI basic driver for rtlwifi");
 
 static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
 	PCI_VENDOR_ID_INTEL,
@@ -1008,19 +1015,6 @@ static void _rtl_pci_prepare_bcn_tasklet
 	return;
 }
 
-static void rtl_lps_change_work_callback(struct work_struct *work)
-{
-	struct rtl_works *rtlworks =
-	    container_of(work, struct rtl_works, lps_change_work);
-	struct ieee80211_hw *hw = rtlworks->hw;
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-
-	if (rtlpriv->enter_ps)
-		rtl_lps_enter(hw);
-	else
-		rtl_lps_leave(hw);
-}
-
 static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw)
 {
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -1899,7 +1893,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
 	rtlpriv->rtlhal.interface = INTF_PCI;
 	rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
 	rtlpriv->intf_ops = &rtl_pci_ops;
-	rtlpriv->glb_var = &global_var;
+	rtlpriv->glb_var = &rtl_global_var;
 
 	/*
 	 *init dbgp flags before all
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/ps.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/ps.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/ps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/ps.c	2013-08-25 20:43:22.000000000 -0400
@@ -269,6 +269,7 @@ void rtl_ips_nic_on(struct ieee80211_hw
 
 	spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags);
 }
+EXPORT_SYMBOL_GPL(rtl_ips_nic_on);
 
 /*for FW LPS*/
 
@@ -518,6 +519,7 @@ void rtl_swlps_beacon(struct ieee80211_h
 			 "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed);
 	}
 }
+EXPORT_SYMBOL_GPL(rtl_swlps_beacon);
 
 void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
 {
@@ -611,6 +613,19 @@ void rtl_swlps_rf_sleep(struct ieee80211
 			MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
 }
 
+void rtl_lps_change_work_callback(struct work_struct *work)
+{
+	struct rtl_works *rtlworks =
+	    container_of(work, struct rtl_works, lps_change_work);
+	struct ieee80211_hw *hw = rtlworks->hw;
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	if (rtlpriv->enter_ps)
+		rtl_lps_enter(hw);
+	else
+		rtl_lps_leave(hw);
+}
+EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback);
 
 void rtl_swlps_wq_callback(void *data)
 {
@@ -922,3 +937,4 @@ void rtl_p2p_info(struct ieee80211_hw *h
 	else
 		rtl_p2p_noa_ie(hw, data, len - FCS_LEN);
 }
+EXPORT_SYMBOL_GPL(rtl_p2p_info);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/ps.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/ps.h
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/ps.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/ps.h	2013-08-25 20:43:22.000000000 -0400
@@ -49,5 +49,6 @@ void rtl_swlps_rf_awake(struct ieee80211
 void rtl_swlps_rf_sleep(struct ieee80211_hw *hw);
 void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
 void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len);
+void rtl_lps_change_work_callback(struct work_struct *work);
 
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,7 +104,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(
 			tx_agc[RF90_PATH_A] = 0x10101010;
 			tx_agc[RF90_PATH_B] = 0x10101010;
 		} else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
-			   TXHIGHPWRLEVEL_LEVEL1) {
+			   TXHIGHPWRLEVEL_LEVEL2) {
 			tx_agc[RF90_PATH_A] = 0x00000000;
 			tx_agc[RF90_PATH_B] = 0x00000000;
 		} else{
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	2013-07-01 10:40:26.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	2013-08-31 18:00:11.000000000 -0400
@@ -359,6 +359,7 @@ static struct usb_device_id rtl8192c_usb
 	{RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/
 	{RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/
 	{RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/
+	{RTL_USB_DEVICE(0x2357, 0x0100, rtl92cu_hal_cfg)}, /*TP-Link WN8200ND*/
 	{RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/
 	{}
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/rtl8192de/dm.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/rtl8192de/dm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/rtl8192de/dm.c	2013-08-25 20:43:22.000000000 -0400
@@ -842,7 +842,7 @@ static void rtl92d_dm_txpower_tracking_c
 	long val_y, ele_c = 0;
 	u8 ofdm_index[2];
 	s8 cck_index = 0;
-	u8 ofdm_index_old[2];
+	u8 ofdm_index_old[2] = {0, 0};
 	s8 cck_index_old = 0;
 	u8 index;
 	int i;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/usb.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/usb.c
--- linux-libre-3.10-gnu/drivers/net/wireless/rtlwifi/usb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/rtlwifi/usb.c	2013-08-25 20:43:22.000000000 -0400
@@ -32,6 +32,13 @@
 #include "ps.h"
 #include "rtl8192c/fw_common.h"
 #include <linux/export.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("lizhaoming	<chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger	<Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("USB basic driver for rtlwifi");
 
 #define	REALTEK_USB_VENQT_READ			0xC0
 #define	REALTEK_USB_VENQT_WRITE			0x40
@@ -1070,6 +1077,8 @@ int rtl_usb_probe(struct usb_interface *
 	spin_lock_init(&rtlpriv->locks.usb_lock);
 	INIT_WORK(&rtlpriv->works.fill_h2c_cmd,
 		  rtl_fill_h2c_cmd_work_callback);
+	INIT_WORK(&rtlpriv->works.lps_change_work,
+		  rtl_lps_change_work_callback);
 
 	rtlpriv->usb_data_index = 0;
 	init_completion(&rtlpriv->firmware_loading_complete);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wl1251/spi.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wl1251/spi.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wl1251/spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wl1251/spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -93,8 +93,7 @@ static void wl1251_spi_wake(struct wl125
 	memset(&t, 0, sizeof(t));
 	spi_message_init(&m);
 
-	/*
-	 * Set WSPI_INIT_COMMAND
+	/* Set WSPI_INIT_COMMAND
 	 * the data is being send from the MSB to LSB
 	 */
 	cmd[2] = 0xff;
@@ -262,7 +261,8 @@ static int wl1251_spi_probe(struct spi_d
 	wl->if_ops = &wl1251_spi_ops;
 
 	/* This is the only SPI value that we need to set here, the rest
-	 * comes from the board-peripherals file */
+	 * comes from the board-peripherals file
+	 */
 	spi->bits_per_word = 32;
 
 	ret = spi_setup(spi);
@@ -329,29 +329,7 @@ static struct spi_driver wl1251_spi_driv
 	.remove		= wl1251_spi_remove,
 };
 
-static int __init wl1251_spi_init(void)
-{
-	int ret;
-
-	ret = spi_register_driver(&wl1251_spi_driver);
-	if (ret < 0) {
-		wl1251_error("failed to register spi driver: %d", ret);
-		goto out;
-	}
-
-out:
-	return ret;
-}
-
-static void __exit wl1251_spi_exit(void)
-{
-	spi_unregister_driver(&wl1251_spi_driver);
-
-	wl1251_notice("unloaded");
-}
-
-module_init(wl1251_spi_init);
-module_exit(wl1251_spi_exit);
+module_spi_driver(wl1251_spi_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wl18xx/main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wl18xx/main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wl18xx/main.c	2013-07-01 10:40:56.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wl18xx/main.c	2013-08-31 18:00:41.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/ip.h>
 #include <linux/firmware.h>
+#include <linux/etherdevice.h>
 
 #include "../wlcore/wlcore.h"
 #include "../wlcore/debug.h"
@@ -594,8 +595,8 @@ static const struct wlcore_partition_set
 		.mem3 = { .start = 0x00000000, .size  = 0x00000000 },
 	},
 	[PART_PHY_INIT] = {
-		.mem  = { .start = 0x80926000,
-			  .size = sizeof(struct wl18xx_mac_and_phy_params) },
+		.mem  = { .start = WL18XX_PHY_INIT_MEM_ADDR,
+			  .size  = WL18XX_PHY_INIT_MEM_SIZE },
 		.reg  = { .start = 0x00000000, .size = 0x00000000 },
 		.mem2 = { .start = 0x00000000, .size = 0x00000000 },
 		.mem3 = { .start = 0x00000000, .size = 0x00000000 },
@@ -799,6 +800,9 @@ static int wl18xx_pre_upload(struct wl12
 	u32 tmp;
 	int ret;
 
+	BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) >
+		WL18XX_PHY_INIT_MEM_SIZE);
+
 	ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
 	if (ret < 0)
 		goto out;
@@ -815,6 +819,35 @@ static int wl18xx_pre_upload(struct wl12
 	wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
 
 	ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp);
+	if (ret < 0)
+		goto out;
+
+	/*
+	 * Workaround for FDSP code RAM corruption (needed for PG2.1
+	 * and newer; for older chips it's a NOP).  Change FDSP clock
+	 * settings so that it's muxed to the ATGP clock instead of
+	 * its own clock.
+	 */
+
+	ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
+	if (ret < 0)
+		goto out;
+
+	/* disable FDSP clock */
+	ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
+			     MEM_FDSP_CLK_120_DISABLE);
+	if (ret < 0)
+		goto out;
+
+	/* set ATPG clock toward FDSP Code RAM rather than its own clock */
+	ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
+			     MEM_FDSP_CODERAM_FUNC_CLK_SEL);
+	if (ret < 0)
+		goto out;
+
+	/* re-enable FDSP clock */
+	ret = wlcore_write32(wl, WL18XX_PHY_FPGA_SPARE_1,
+			     MEM_FDSP_CLK_120_ENABLE);
 
 out:
 	return ret;
@@ -1286,6 +1319,16 @@ static int wl18xx_get_mac(struct wl1271
 		((mac1 & 0xff000000) >> 24);
 	wl->fuse_nic_addr = (mac1 & 0xffffff);
 
+	if (!wl->fuse_oui_addr && !wl->fuse_nic_addr) {
+		u8 mac[ETH_ALEN];
+
+		eth_random_addr(mac);
+
+		wl->fuse_oui_addr = (mac[0] << 16) + (mac[1] << 8) + mac[2];
+		wl->fuse_nic_addr = (mac[3] << 16) + (mac[4] << 8) + mac[5];
+		wl1271_warning("MAC address from fuse not available, using random locally administered addresses.");
+	}
+
 	ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
 
 out:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wl18xx/reg.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wl18xx/reg.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wl18xx/reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wl18xx/reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,6 +38,9 @@
 #define WL18XX_REG_BOOT_PART_SIZE  0x00014578
 
 #define WL18XX_PHY_INIT_MEM_ADDR   0x80926000
+#define WL18XX_PHY_END_MEM_ADDR	   0x8093CA44
+#define WL18XX_PHY_INIT_MEM_SIZE \
+	(WL18XX_PHY_END_MEM_ADDR - WL18XX_PHY_INIT_MEM_ADDR)
 
 #define WL18XX_SDIO_WSPI_BASE		(WL18XX_REGISTERS_BASE)
 #define WL18XX_REG_CONFIG_BASE		(WL18XX_REGISTERS_BASE + 0x02000)
@@ -217,4 +220,16 @@ static const char * const rdl_names[] =
 	[RDL_4_SP]	= "1897 MIMO",
 };
 
+/* FPGA_SPARE_1 register - used to change the PHY ATPG clock at boot time */
+#define WL18XX_PHY_FPGA_SPARE_1		0x8093CA40
+
+/* command to disable FDSP clock */
+#define MEM_FDSP_CLK_120_DISABLE        0x80000000
+
+/* command to set ATPG clock toward FDSP Code RAM rather than its own clock */
+#define MEM_FDSP_CODERAM_FUNC_CLK_SEL	0xC0000000
+
+/* command to re-enable FDSP clock */
+#define MEM_FDSP_CLK_120_ENABLE		0x40000000
+
 #endif /* __REG_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/debugfs.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/debugfs.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -1056,7 +1056,7 @@ static ssize_t dev_mem_read(struct file
 		return -EINVAL;
 
 	memset(&part, 0, sizeof(part));
-	part.mem.start = file->f_pos;
+	part.mem.start = *ppos;
 	part.mem.size = bytes;
 
 	buf = kmalloc(bytes, GFP_KERNEL);
@@ -1137,7 +1137,7 @@ static ssize_t dev_mem_write(struct file
 		return -EINVAL;
 
 	memset(&part, 0, sizeof(part));
-	part.mem.start = file->f_pos;
+	part.mem.start = *ppos;
 	part.mem.size = bytes;
 
 	buf = kmalloc(bytes, GFP_KERNEL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/main.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/main.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/main.c	2013-07-01 10:41:00.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/main.c	2013-08-31 18:00:45.000000000 -0400
@@ -1,10 +1,9 @@
 
 /*
- * This file is part of wl1271
+ * This file is part of wlcore
  *
  * Copyright (C) 2008-2010 Nokia Corporation
- *
- * Contact: Luciano Coelho <luciano.coelho@nokia.com>
+ * Copyright (C) 2011-2013 Texas Instruments Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -24,34 +23,23 @@
 
 #include <linux/module.h>
 #include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/spi/spi.h>
-#include <linux/crc32.h>
 #include <linux/etherdevice.h>
 #include <linux/vmalloc.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <linux/wl12xx.h>
-#include <linux/sched.h>
 #include <linux/interrupt.h>
 
 #include "wlcore.h"
 #include "debug.h"
 #include "wl12xx_80211.h"
 #include "io.h"
-#include "event.h"
 #include "tx.h"
-#include "rx.h"
 #include "ps.h"
 #include "init.h"
 #include "debugfs.h"
-#include "cmd.h"
-#include "boot.h"
 #include "testmode.h"
 #include "scan.h"
 #include "hw_ops.h"
-
-#define WL1271_BOOT_RETRIES 3
+#include "sysfs.h"
 
 #define WL1271_BOOT_RETRIES 3
 
@@ -65,8 +53,7 @@ static void __wl1271_op_remove_interface
 static void wlcore_op_stop_locked(struct wl1271 *wl);
 static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif);
 
-static int wl12xx_set_authorized(struct wl1271 *wl,
-				 struct wl12xx_vif *wlvif)
+static int wl12xx_set_authorized(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 {
 	int ret;
 
@@ -983,7 +970,7 @@ static int wlcore_fw_wakeup(struct wl127
 
 static int wl1271_setup(struct wl1271 *wl)
 {
-	wl->fw_status_1 = kmalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
+	wl->fw_status_1 = kzalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
 				  sizeof(*wl->fw_status_2) +
 				  wl->fw_status_priv_len, GFP_KERNEL);
 	if (!wl->fw_status_1)
@@ -993,7 +980,7 @@ static int wl1271_setup(struct wl1271 *w
 				(((u8 *) wl->fw_status_1) +
 				WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc));
 
-	wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
+	wl->tx_res_if = kzalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
 	if (!wl->tx_res_if) {
 		kfree(wl->fw_status_1);
 		return -ENOMEM;
@@ -1668,8 +1655,7 @@ static int wl1271_configure_suspend(stru
 	return 0;
 }
 
-static void wl1271_configure_resume(struct wl1271 *wl,
-				    struct wl12xx_vif *wlvif)
+static void wl1271_configure_resume(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 {
 	int ret = 0;
 	bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
@@ -2603,6 +2589,7 @@ unlock:
 	cancel_work_sync(&wlvif->rx_streaming_enable_work);
 	cancel_work_sync(&wlvif->rx_streaming_disable_work);
 	cancel_delayed_work_sync(&wlvif->connection_loss_work);
+	cancel_delayed_work_sync(&wlvif->channel_switch_work);
 
 	mutex_lock(&wl->mutex);
 }
@@ -3210,14 +3197,6 @@ static int wl1271_set_key(struct wl1271
 		if (ret < 0)
 			return ret;
 
-		/* the default WEP key needs to be configured at least once */
-		if (key_type == KEY_WEP) {
-			ret = wl12xx_cmd_set_default_wep_key(wl,
-							wlvif->default_key,
-							wlvif->sta.hlid);
-			if (ret < 0)
-				return ret;
-		}
 	}
 
 	return 0;
@@ -3374,6 +3353,46 @@ int wlcore_set_key(struct wl1271 *wl, en
 }
 EXPORT_SYMBOL_GPL(wlcore_set_key);
 
+static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw,
+					  struct ieee80211_vif *vif,
+					  int key_idx)
+{
+	struct wl1271 *wl = hw->priv;
+	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
+	int ret;
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 set default key idx %d",
+		     key_idx);
+
+	mutex_lock(&wl->mutex);
+
+	if (unlikely(wl->state != WLCORE_STATE_ON)) {
+		ret = -EAGAIN;
+		goto out_unlock;
+	}
+
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out_unlock;
+
+	wlvif->default_key = key_idx;
+
+	/* the default WEP key needs to be configured at least once */
+	if (wlvif->encryption_type == KEY_WEP) {
+		ret = wl12xx_cmd_set_default_wep_key(wl,
+				key_idx,
+				wlvif->sta.hlid);
+		if (ret < 0)
+			goto out_sleep;
+	}
+
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+
+out_unlock:
+	mutex_unlock(&wl->mutex);
+}
+
 void wlcore_regdomain_config(struct wl1271 *wl)
 {
 	int ret;
@@ -3782,8 +3801,7 @@ static int wlcore_set_beacon_template(st
 	struct ieee80211_hdr *hdr;
 	u32 min_rate;
 	int ret;
-	int ieoffset = offsetof(struct ieee80211_mgmt,
-				u.beacon.variable);
+	int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
 	struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
 	u16 tmpl_id;
 
@@ -4230,8 +4248,7 @@ static void wl1271_bss_info_changed_sta(
 	}
 
 	/* Handle new association with HT. Do this after join. */
-	if (sta_exists &&
-	    (changed & BSS_CHANGED_HT)) {
+	if (sta_exists) {
 		bool enabled =
 			bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT;
 
@@ -5368,6 +5385,7 @@ static const struct ieee80211_ops wl1271
 	.ampdu_action = wl1271_op_ampdu_action,
 	.tx_frames_pending = wl1271_tx_frames_pending,
 	.set_bitrate_mask = wl12xx_set_bitrate_mask,
+	.set_default_unicast_key = wl1271_op_set_default_key_idx,
 	.channel_switch = wl12xx_op_channel_switch,
 	.flush = wlcore_op_flush,
 	.remain_on_channel = wlcore_op_remain_on_channel,
@@ -5403,151 +5421,6 @@ u8 wlcore_rate_to_idx(struct wl1271 *wl,
 	return idx;
 }
 
-static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
-					       struct device_attribute *attr,
-					       char *buf)
-{
-	struct wl1271 *wl = dev_get_drvdata(dev);
-	ssize_t len;
-
-	len = PAGE_SIZE;
-
-	mutex_lock(&wl->mutex);
-	len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
-		       wl->sg_enabled);
-	mutex_unlock(&wl->mutex);
-
-	return len;
-
-}
-
-static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf, size_t count)
-{
-	struct wl1271 *wl = dev_get_drvdata(dev);
-	unsigned long res;
-	int ret;
-
-	ret = kstrtoul(buf, 10, &res);
-	if (ret < 0) {
-		wl1271_warning("incorrect value written to bt_coex_mode");
-		return count;
-	}
-
-	mutex_lock(&wl->mutex);
-
-	res = !!res;
-
-	if (res == wl->sg_enabled)
-		goto out;
-
-	wl->sg_enabled = res;
-
-	if (unlikely(wl->state != WLCORE_STATE_ON))
-		goto out;
-
-	ret = wl1271_ps_elp_wakeup(wl);
-	if (ret < 0)
-		goto out;
-
-	wl1271_acx_sg_enable(wl, wl->sg_enabled);
-	wl1271_ps_elp_sleep(wl);
-
- out:
-	mutex_unlock(&wl->mutex);
-	return count;
-}
-
-static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR,
-		   wl1271_sysfs_show_bt_coex_state,
-		   wl1271_sysfs_store_bt_coex_state);
-
-static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
-					   struct device_attribute *attr,
-					   char *buf)
-{
-	struct wl1271 *wl = dev_get_drvdata(dev);
-	ssize_t len;
-
-	len = PAGE_SIZE;
-
-	mutex_lock(&wl->mutex);
-	if (wl->hw_pg_ver >= 0)
-		len = snprintf(buf, len, "%d\n", wl->hw_pg_ver);
-	else
-		len = snprintf(buf, len, "n/a\n");
-	mutex_unlock(&wl->mutex);
-
-	return len;
-}
-
-static DEVICE_ATTR(hw_pg_ver, S_IRUGO,
-		   wl1271_sysfs_show_hw_pg_ver, NULL);
-
-static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj,
-				       struct bin_attribute *bin_attr,
-				       char *buffer, loff_t pos, size_t count)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct wl1271 *wl = dev_get_drvdata(dev);
-	ssize_t len;
-	int ret;
-
-	ret = mutex_lock_interruptible(&wl->mutex);
-	if (ret < 0)
-		return -ERESTARTSYS;
-
-	/* Let only one thread read the log at a time, blocking others */
-	while (wl->fwlog_size == 0) {
-		DEFINE_WAIT(wait);
-
-		prepare_to_wait_exclusive(&wl->fwlog_waitq,
-					  &wait,
-					  TASK_INTERRUPTIBLE);
-
-		if (wl->fwlog_size != 0) {
-			finish_wait(&wl->fwlog_waitq, &wait);
-			break;
-		}
-
-		mutex_unlock(&wl->mutex);
-
-		schedule();
-		finish_wait(&wl->fwlog_waitq, &wait);
-
-		if (signal_pending(current))
-			return -ERESTARTSYS;
-
-		ret = mutex_lock_interruptible(&wl->mutex);
-		if (ret < 0)
-			return -ERESTARTSYS;
-	}
-
-	/* Check if the fwlog is still valid */
-	if (wl->fwlog_size < 0) {
-		mutex_unlock(&wl->mutex);
-		return 0;
-	}
-
-	/* Seeking is not supported - old logs are not kept. Disregard pos. */
-	len = min(count, (size_t)wl->fwlog_size);
-	wl->fwlog_size -= len;
-	memcpy(buffer, wl->fwlog, len);
-
-	/* Make room for new messages */
-	memmove(wl->fwlog, wl->fwlog + len, wl->fwlog_size);
-
-	mutex_unlock(&wl->mutex);
-
-	return len;
-}
-
-static struct bin_attribute fwlog_attr = {
-	.attr = {.name = "fwlog", .mode = S_IRUSR},
-	.read = wl1271_sysfs_read_fwlog,
-};
-
 static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic)
 {
 	int i;
@@ -5827,8 +5700,6 @@ static int wl1271_init_ieee80211(struct
 	return 0;
 }
 
-#define WL1271_DEFAULT_CHANNEL 0
-
 struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
 				     u32 mbox_size)
 {
@@ -5881,7 +5752,7 @@ struct ieee80211_hw *wlcore_alloc_hw(siz
 		goto err_hw;
 	}
 
-	wl->channel = WL1271_DEFAULT_CHANNEL;
+	wl->channel = 0;
 	wl->rx_counter = 0;
 	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
 	wl->band = IEEE80211_BAND_2GHZ;
@@ -5988,11 +5859,8 @@ int wlcore_free_hw(struct wl1271 *wl)
 	wake_up_interruptible_all(&wl->fwlog_waitq);
 	mutex_unlock(&wl->mutex);
 
-	device_remove_bin_file(wl->dev, &fwlog_attr);
-
-	device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
+	wlcore_sysfs_free(wl);
 
-	device_remove_file(wl->dev, &dev_attr_bt_coex_state);
 	kfree(wl->buffer_32);
 	kfree(wl->mbox);
 	free_page((unsigned long)wl->fwlog);
@@ -6018,6 +5886,15 @@ int wlcore_free_hw(struct wl1271 *wl)
 }
 EXPORT_SYMBOL_GPL(wlcore_free_hw);
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support wlcore_wowlan_support = {
+	.flags = WIPHY_WOWLAN_ANY,
+	.n_patterns = WL1271_MAX_RX_FILTERS,
+	.pattern_min_len = 1,
+	.pattern_max_len = WL1271_RX_FILTER_MAX_PATTERN_SIZE,
+};
+#endif
+
 static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 {
 	struct wl1271 *wl = context;
@@ -6071,14 +5948,8 @@ static void wlcore_nvs_cb(const struct f
 	if (!ret) {
 		wl->irq_wake_enabled = true;
 		device_init_wakeup(wl->dev, 1);
-		if (pdata->pwr_in_suspend) {
-			wl->hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
-			wl->hw->wiphy->wowlan.n_patterns =
-				WL1271_MAX_RX_FILTERS;
-			wl->hw->wiphy->wowlan.pattern_min_len = 1;
-			wl->hw->wiphy->wowlan.pattern_max_len =
-				WL1271_RX_FILTER_MAX_PATTERN_SIZE;
-		}
+		if (pdata->pwr_in_suspend)
+			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
 	}
 #endif
 	disable_irq(wl->irq);
@@ -6101,36 +5972,13 @@ static void wlcore_nvs_cb(const struct f
 	if (ret)
 		goto out_irq;
 
-	/* Create sysfs file to control bt coex state */
-	ret = device_create_file(wl->dev, &dev_attr_bt_coex_state);
-	if (ret < 0) {
-		wl1271_error("failed to create sysfs file bt_coex_state");
+	ret = wlcore_sysfs_init(wl);
+	if (ret)
 		goto out_unreg;
-	}
-
-	/* Create sysfs file to get HW PG version */
-	ret = device_create_file(wl->dev, &dev_attr_hw_pg_ver);
-	if (ret < 0) {
-		wl1271_error("failed to create sysfs file hw_pg_ver");
-		goto out_bt_coex_state;
-	}
-
-	/* Create sysfs file for the FW log */
-	ret = device_create_bin_file(wl->dev, &fwlog_attr);
-	if (ret < 0) {
-		wl1271_error("failed to create sysfs file fwlog");
-		goto out_hw_pg_ver;
-	}
 
 	wl->initialized = true;
 	goto out;
 
-out_hw_pg_ver:
-	device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
-
-out_bt_coex_state:
-	device_remove_file(wl->dev, &dev_attr_bt_coex_state);
-
 out_unreg:
 	wl1271_unregister_hw(wl);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/Makefile linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/Makefile
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 wlcore-objs		= main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
-			  boot.o init.o debugfs.o scan.o
+			  boot.o init.o debugfs.o scan.o sysfs.o
 
 wlcore_spi-objs 	= spi.o
 wlcore_sdio-objs	= sdio.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/ps.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/ps.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/ps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/ps.c	2013-08-25 20:43:22.000000000 -0400
@@ -110,7 +110,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *
 	DECLARE_COMPLETION_ONSTACK(compl);
 	unsigned long flags;
 	int ret;
-	u32 start_time = jiffies;
+	unsigned long start_time = jiffies;
 	bool pending = false;
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/spi.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/spi.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -434,19 +434,7 @@ static struct spi_driver wl1271_spi_driv
 	.remove		= wl1271_remove,
 };
 
-static int __init wl1271_init(void)
-{
-	return spi_register_driver(&wl1271_spi_driver);
-}
-
-static void __exit wl1271_exit(void)
-{
-	spi_unregister_driver(&wl1271_spi_driver);
-}
-
-module_init(wl1271_init);
-module_exit(wl1271_exit);
-
+module_spi_driver(wl1271_spi_driver);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/sysfs.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/sysfs.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,216 @@
+/*
+ * This file is part of wlcore
+ *
+ * Copyright (C) 2013 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "wlcore.h"
+#include "debug.h"
+#include "ps.h"
+#include "sysfs.h"
+
+static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf)
+{
+	struct wl1271 *wl = dev_get_drvdata(dev);
+	ssize_t len;
+
+	len = PAGE_SIZE;
+
+	mutex_lock(&wl->mutex);
+	len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
+		       wl->sg_enabled);
+	mutex_unlock(&wl->mutex);
+
+	return len;
+
+}
+
+static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf, size_t count)
+{
+	struct wl1271 *wl = dev_get_drvdata(dev);
+	unsigned long res;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &res);
+	if (ret < 0) {
+		wl1271_warning("incorrect value written to bt_coex_mode");
+		return count;
+	}
+
+	mutex_lock(&wl->mutex);
+
+	res = !!res;
+
+	if (res == wl->sg_enabled)
+		goto out;
+
+	wl->sg_enabled = res;
+
+	if (unlikely(wl->state != WLCORE_STATE_ON))
+		goto out;
+
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	wl1271_acx_sg_enable(wl, wl->sg_enabled);
+	wl1271_ps_elp_sleep(wl);
+
+ out:
+	mutex_unlock(&wl->mutex);
+	return count;
+}
+
+static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR,
+		   wl1271_sysfs_show_bt_coex_state,
+		   wl1271_sysfs_store_bt_coex_state);
+
+static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct wl1271 *wl = dev_get_drvdata(dev);
+	ssize_t len;
+
+	len = PAGE_SIZE;
+
+	mutex_lock(&wl->mutex);
+	if (wl->hw_pg_ver >= 0)
+		len = snprintf(buf, len, "%d\n", wl->hw_pg_ver);
+	else
+		len = snprintf(buf, len, "n/a\n");
+	mutex_unlock(&wl->mutex);
+
+	return len;
+}
+
+static DEVICE_ATTR(hw_pg_ver, S_IRUGO,
+		   wl1271_sysfs_show_hw_pg_ver, NULL);
+
+static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj,
+				       struct bin_attribute *bin_attr,
+				       char *buffer, loff_t pos, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct wl1271 *wl = dev_get_drvdata(dev);
+	ssize_t len;
+	int ret;
+
+	ret = mutex_lock_interruptible(&wl->mutex);
+	if (ret < 0)
+		return -ERESTARTSYS;
+
+	/* Let only one thread read the log at a time, blocking others */
+	while (wl->fwlog_size == 0) {
+		DEFINE_WAIT(wait);
+
+		prepare_to_wait_exclusive(&wl->fwlog_waitq,
+					  &wait,
+					  TASK_INTERRUPTIBLE);
+
+		if (wl->fwlog_size != 0) {
+			finish_wait(&wl->fwlog_waitq, &wait);
+			break;
+		}
+
+		mutex_unlock(&wl->mutex);
+
+		schedule();
+		finish_wait(&wl->fwlog_waitq, &wait);
+
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+
+		ret = mutex_lock_interruptible(&wl->mutex);
+		if (ret < 0)
+			return -ERESTARTSYS;
+	}
+
+	/* Check if the fwlog is still valid */
+	if (wl->fwlog_size < 0) {
+		mutex_unlock(&wl->mutex);
+		return 0;
+	}
+
+	/* Seeking is not supported - old logs are not kept. Disregard pos. */
+	len = min(count, (size_t)wl->fwlog_size);
+	wl->fwlog_size -= len;
+	memcpy(buffer, wl->fwlog, len);
+
+	/* Make room for new messages */
+	memmove(wl->fwlog, wl->fwlog + len, wl->fwlog_size);
+
+	mutex_unlock(&wl->mutex);
+
+	return len;
+}
+
+static struct bin_attribute fwlog_attr = {
+	.attr = {.name = "fwlog", .mode = S_IRUSR},
+	.read = wl1271_sysfs_read_fwlog,
+};
+
+int wlcore_sysfs_init(struct wl1271 *wl)
+{
+	int ret;
+
+	/* Create sysfs file to control bt coex state */
+	ret = device_create_file(wl->dev, &dev_attr_bt_coex_state);
+	if (ret < 0) {
+		wl1271_error("failed to create sysfs file bt_coex_state");
+		goto out;
+	}
+
+	/* Create sysfs file to get HW PG version */
+	ret = device_create_file(wl->dev, &dev_attr_hw_pg_ver);
+	if (ret < 0) {
+		wl1271_error("failed to create sysfs file hw_pg_ver");
+		goto out_bt_coex_state;
+	}
+
+	/* Create sysfs file for the FW log */
+	ret = device_create_bin_file(wl->dev, &fwlog_attr);
+	if (ret < 0) {
+		wl1271_error("failed to create sysfs file fwlog");
+		goto out_hw_pg_ver;
+	}
+
+	goto out;
+
+out_hw_pg_ver:
+	device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
+
+out_bt_coex_state:
+	device_remove_file(wl->dev, &dev_attr_bt_coex_state);
+
+out:
+	return ret;
+}
+
+void wlcore_sysfs_free(struct wl1271 *wl)
+{
+	device_remove_bin_file(wl->dev, &fwlog_attr);
+
+	device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
+
+	device_remove_file(wl->dev, &dev_attr_bt_coex_state);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/sysfs.h linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/sysfs.h
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/sysfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/sysfs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,28 @@
+/*
+ * This file is part of wlcore
+ *
+ * Copyright (C) 2013 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __SYSFS_H__
+#define __SYSFS_H__
+
+int wlcore_sysfs_init(struct wl1271 *wl);
+void wlcore_sysfs_free(struct wl1271 *wl);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/tx.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/tx.c
--- linux-libre-3.10-gnu/drivers/net/wireless/ti/wlcore/tx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/ti/wlcore/tx.c	2013-08-25 20:43:22.000000000 -0400
@@ -386,7 +386,7 @@ static int wl1271_prepare_tx_frame(struc
 		is_wep = (cipher == WLAN_CIPHER_SUITE_WEP40) ||
 			 (cipher == WLAN_CIPHER_SUITE_WEP104);
 
-		if (unlikely(is_wep && wlvif->default_key != idx)) {
+		if (WARN_ON(is_wep && wlvif->default_key != idx)) {
 			ret = wl1271_set_default_wep_key(wl, wlvif, idx);
 			if (ret < 0)
 				return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/wireless/zd1201.c linux-libre-3.11-rc7-gnu/drivers/net/wireless/zd1201.c
--- linux-libre-3.10-gnu/drivers/net/wireless/zd1201.c	2013-07-01 10:41:04.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/wireless/zd1201.c	2013-08-31 18:00:49.000000000 -0400
@@ -98,10 +98,12 @@ static int zd1201_fw_upload(struct usb_d
 		goto exit;
 
 	err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4,
-	    USB_DIR_IN | 0x40, 0,0, &ret, sizeof(ret), ZD1201_FW_TIMEOUT);
+	    USB_DIR_IN | 0x40, 0, 0, buf, sizeof(ret), ZD1201_FW_TIMEOUT);
 	if (err < 0)
 		goto exit;
 
+	memcpy(&ret, buf, sizeof(ret));
+
 	if (ret & 0x80) {
 		err = -EIO;
 		goto exit;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/xen-netback/common.h linux-libre-3.11-rc7-gnu/drivers/net/xen-netback/common.h
--- linux-libre-3.10-gnu/drivers/net/xen-netback/common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/xen-netback/common.h	2013-08-25 20:43:22.000000000 -0400
@@ -57,8 +57,12 @@ struct xenvif {
 
 	u8               fe_dev_addr[6];
 
-	/* Physical parameters of the comms window. */
-	unsigned int     irq;
+	/* When feature-split-event-channels = 0, tx_irq = rx_irq. */
+	unsigned int tx_irq;
+	unsigned int rx_irq;
+	/* Only used when feature-split-event-channels = 1 */
+	char tx_irq_name[IFNAMSIZ+4]; /* DEVNAME-tx */
+	char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */
 
 	/* List of frontends to notify after a batch of frames sent. */
 	struct list_head notify_list;
@@ -113,13 +117,15 @@ struct xenvif *xenvif_alloc(struct devic
 			    unsigned int handle);
 
 int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
-		   unsigned long rx_ring_ref, unsigned int evtchn);
+		   unsigned long rx_ring_ref, unsigned int tx_evtchn,
+		   unsigned int rx_evtchn);
 void xenvif_disconnect(struct xenvif *vif);
 
 void xenvif_get(struct xenvif *vif);
 void xenvif_put(struct xenvif *vif);
 
 int xenvif_xenbus_init(void);
+void xenvif_xenbus_fini(void);
 
 int xenvif_schedulable(struct xenvif *vif);
 
@@ -157,4 +163,6 @@ void xenvif_carrier_off(struct xenvif *v
 /* Returns number of ring slots required to send an skb to the frontend */
 unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb);
 
+extern bool separate_tx_rx_irq;
+
 #endif /* __XEN_NETBACK__COMMON_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/xen-netback/interface.c linux-libre-3.11-rc7-gnu/drivers/net/xen-netback/interface.c
--- linux-libre-3.10-gnu/drivers/net/xen-netback/interface.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/xen-netback/interface.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,21 +60,39 @@ static int xenvif_rx_schedulable(struct
 	return xenvif_schedulable(vif) && !xen_netbk_rx_ring_full(vif);
 }
 
-static irqreturn_t xenvif_interrupt(int irq, void *dev_id)
+static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id)
 {
 	struct xenvif *vif = dev_id;
 
 	if (vif->netbk == NULL)
-		return IRQ_NONE;
+		return IRQ_HANDLED;
 
 	xen_netbk_schedule_xenvif(vif);
 
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id)
+{
+	struct xenvif *vif = dev_id;
+
+	if (vif->netbk == NULL)
+		return IRQ_HANDLED;
+
 	if (xenvif_rx_schedulable(vif))
 		netif_wake_queue(vif->dev);
 
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t xenvif_interrupt(int irq, void *dev_id)
+{
+	xenvif_tx_interrupt(irq, dev_id);
+	xenvif_rx_interrupt(irq, dev_id);
+
+	return IRQ_HANDLED;
+}
+
 static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct xenvif *vif = netdev_priv(dev);
@@ -125,13 +143,17 @@ static struct net_device_stats *xenvif_g
 static void xenvif_up(struct xenvif *vif)
 {
 	xen_netbk_add_xenvif(vif);
-	enable_irq(vif->irq);
+	enable_irq(vif->tx_irq);
+	if (vif->tx_irq != vif->rx_irq)
+		enable_irq(vif->rx_irq);
 	xen_netbk_check_rx_xenvif(vif);
 }
 
 static void xenvif_down(struct xenvif *vif)
 {
-	disable_irq(vif->irq);
+	disable_irq(vif->tx_irq);
+	if (vif->tx_irq != vif->rx_irq)
+		disable_irq(vif->rx_irq);
 	del_timer_sync(&vif->credit_timeout);
 	xen_netbk_deschedule_xenvif(vif);
 	xen_netbk_remove_xenvif(vif);
@@ -308,25 +330,52 @@ struct xenvif *xenvif_alloc(struct devic
 }
 
 int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
-		   unsigned long rx_ring_ref, unsigned int evtchn)
+		   unsigned long rx_ring_ref, unsigned int tx_evtchn,
+		   unsigned int rx_evtchn)
 {
 	int err = -ENOMEM;
 
 	/* Already connected through? */
-	if (vif->irq)
+	if (vif->tx_irq)
 		return 0;
 
+	__module_get(THIS_MODULE);
+
 	err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
 	if (err < 0)
 		goto err;
 
-	err = bind_interdomain_evtchn_to_irqhandler(
-		vif->domid, evtchn, xenvif_interrupt, 0,
-		vif->dev->name, vif);
-	if (err < 0)
-		goto err_unmap;
-	vif->irq = err;
-	disable_irq(vif->irq);
+	if (tx_evtchn == rx_evtchn) {
+		/* feature-split-event-channels == 0 */
+		err = bind_interdomain_evtchn_to_irqhandler(
+			vif->domid, tx_evtchn, xenvif_interrupt, 0,
+			vif->dev->name, vif);
+		if (err < 0)
+			goto err_unmap;
+		vif->tx_irq = vif->rx_irq = err;
+		disable_irq(vif->tx_irq);
+	} else {
+		/* feature-split-event-channels == 1 */
+		snprintf(vif->tx_irq_name, sizeof(vif->tx_irq_name),
+			 "%s-tx", vif->dev->name);
+		err = bind_interdomain_evtchn_to_irqhandler(
+			vif->domid, tx_evtchn, xenvif_tx_interrupt, 0,
+			vif->tx_irq_name, vif);
+		if (err < 0)
+			goto err_unmap;
+		vif->tx_irq = err;
+		disable_irq(vif->tx_irq);
+
+		snprintf(vif->rx_irq_name, sizeof(vif->rx_irq_name),
+			 "%s-rx", vif->dev->name);
+		err = bind_interdomain_evtchn_to_irqhandler(
+			vif->domid, rx_evtchn, xenvif_rx_interrupt, 0,
+			vif->rx_irq_name, vif);
+		if (err < 0)
+			goto err_tx_unbind;
+		vif->rx_irq = err;
+		disable_irq(vif->rx_irq);
+	}
 
 	xenvif_get(vif);
 
@@ -340,9 +389,13 @@ int xenvif_connect(struct xenvif *vif, u
 	rtnl_unlock();
 
 	return 0;
+err_tx_unbind:
+	unbind_from_irqhandler(vif->tx_irq, vif);
+	vif->tx_irq = 0;
 err_unmap:
 	xen_netbk_unmap_frontend_rings(vif);
 err:
+	module_put(THIS_MODULE);
 	return err;
 }
 
@@ -360,18 +413,37 @@ void xenvif_carrier_off(struct xenvif *v
 
 void xenvif_disconnect(struct xenvif *vif)
 {
+	/* Disconnect funtion might get called by generic framework
+	 * even before vif connects, so we need to check if we really
+	 * need to do a module_put.
+	 */
+	int need_module_put = 0;
+
 	if (netif_carrier_ok(vif->dev))
 		xenvif_carrier_off(vif);
 
 	atomic_dec(&vif->refcnt);
 	wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0);
 
-	if (vif->irq)
-		unbind_from_irqhandler(vif->irq, vif);
+	if (vif->tx_irq) {
+		if (vif->tx_irq == vif->rx_irq)
+			unbind_from_irqhandler(vif->tx_irq, vif);
+		else {
+			unbind_from_irqhandler(vif->tx_irq, vif);
+			unbind_from_irqhandler(vif->rx_irq, vif);
+		}
+		/* vif->irq is valid, we had a module_get in
+		 * xenvif_connect.
+		 */
+		need_module_put = 1;
+	}
 
 	unregister_netdev(vif->dev);
 
 	xen_netbk_unmap_frontend_rings(vif);
 
 	free_netdev(vif->dev);
+
+	if (need_module_put)
+		module_put(THIS_MODULE);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/xen-netback/netback.c linux-libre-3.11-rc7-gnu/drivers/net/xen-netback/netback.c
--- linux-libre-3.10-gnu/drivers/net/xen-netback/netback.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/xen-netback/netback.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,6 +47,13 @@
 #include <asm/xen/hypercall.h>
 #include <asm/xen/page.h>
 
+/* Provide an option to disable split event channels at load time as
+ * event channels are limited resource. Split event channels are
+ * enabled by default.
+ */
+bool separate_tx_rx_irq = 1;
+module_param(separate_tx_rx_irq, bool, 0644);
+
 /*
  * This is the maximum slots a skb can have. If a guest sends a skb
  * which exceeds this limit it is considered malicious.
@@ -783,7 +790,7 @@ static void xen_netbk_rx_action(struct x
 	}
 
 	list_for_each_entry_safe(vif, tmp, &notify, notify_list) {
-		notify_remote_via_irq(vif->irq);
+		notify_remote_via_irq(vif->rx_irq);
 		list_del_init(&vif->notify_list);
 		xenvif_put(vif);
 	}
@@ -1763,7 +1770,7 @@ static void make_tx_response(struct xenv
 	vif->tx.rsp_prod_pvt = ++i;
 	RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->tx, notify);
 	if (notify)
-		notify_remote_via_irq(vif->irq);
+		notify_remote_via_irq(vif->tx_irq);
 }
 
 static struct xen_netif_rx_response *make_rx_response(struct xenvif *vif,
@@ -1883,9 +1890,8 @@ static int __init netback_init(void)
 		return -ENODEV;
 
 	if (fatal_skb_slots < XEN_NETBK_LEGACY_SLOTS_MAX) {
-		printk(KERN_INFO
-		       "xen-netback: fatal_skb_slots too small (%d), bump it to XEN_NETBK_LEGACY_SLOTS_MAX (%d)\n",
-		       fatal_skb_slots, XEN_NETBK_LEGACY_SLOTS_MAX);
+		pr_info("fatal_skb_slots too small (%d), bump it to XEN_NETBK_LEGACY_SLOTS_MAX (%d)\n",
+			fatal_skb_slots, XEN_NETBK_LEGACY_SLOTS_MAX);
 		fatal_skb_slots = XEN_NETBK_LEGACY_SLOTS_MAX;
 	}
 
@@ -1914,7 +1920,7 @@ static int __init netback_init(void)
 					     "netback/%u", group);
 
 		if (IS_ERR(netbk->task)) {
-			printk(KERN_ALERT "kthread_create() fails at netback\n");
+			pr_alert("kthread_create() fails at netback\n");
 			del_timer(&netbk->net_timer);
 			rc = PTR_ERR(netbk->task);
 			goto failed_init;
@@ -1940,10 +1946,6 @@ static int __init netback_init(void)
 failed_init:
 	while (--group >= 0) {
 		struct xen_netbk *netbk = &xen_netbk[group];
-		for (i = 0; i < MAX_PENDING_REQS; i++) {
-			if (netbk->mmap_pages[i])
-				__free_page(netbk->mmap_pages[i]);
-		}
 		del_timer(&netbk->net_timer);
 		kthread_stop(netbk->task);
 	}
@@ -1954,5 +1956,25 @@ failed_init:
 
 module_init(netback_init);
 
+static void __exit netback_fini(void)
+{
+	int i, j;
+
+	xenvif_xenbus_fini();
+
+	for (i = 0; i < xen_netbk_group_nr; i++) {
+		struct xen_netbk *netbk = &xen_netbk[i];
+		del_timer_sync(&netbk->net_timer);
+		kthread_stop(netbk->task);
+		for (j = 0; j < MAX_PENDING_REQS; j++) {
+			if (netbk->mmap_pages[j])
+				__free_page(netbk->mmap_pages[j]);
+		}
+	}
+
+	vfree(xen_netbk);
+}
+module_exit(netback_fini);
+
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_ALIAS("xen-backend:vif");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/xen-netback/xenbus.c linux-libre-3.11-rc7-gnu/drivers/net/xen-netback/xenbus.c
--- linux-libre-3.10-gnu/drivers/net/xen-netback/xenbus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/xen-netback/xenbus.c	2013-08-25 20:43:22.000000000 -0400
@@ -122,6 +122,16 @@ static int netback_probe(struct xenbus_d
 		goto fail;
 	}
 
+	/*
+	 * Split event channels support, this is optional so it is not
+	 * put inside the above loop.
+	 */
+	err = xenbus_printf(XBT_NIL, dev->nodename,
+			    "feature-split-event-channels",
+			    "%u", separate_tx_rx_irq);
+	if (err)
+		pr_debug("Error writing feature-split-event-channels\n");
+
 	err = xenbus_switch_state(dev, XenbusStateInitWait);
 	if (err)
 		goto fail;
@@ -135,7 +145,7 @@ abort_transaction:
 	xenbus_transaction_end(xbt, 1);
 	xenbus_dev_fatal(dev, err, "%s", message);
 fail:
-	pr_debug("failed");
+	pr_debug("failed\n");
 	netback_remove(dev);
 	return err;
 }
@@ -218,15 +228,14 @@ static void frontend_changed(struct xenb
 {
 	struct backend_info *be = dev_get_drvdata(&dev->dev);
 
-	pr_debug("frontend state %s", xenbus_strstate(frontend_state));
+	pr_debug("frontend state %s\n", xenbus_strstate(frontend_state));
 
 	be->frontend_state = frontend_state;
 
 	switch (frontend_state) {
 	case XenbusStateInitialising:
 		if (dev->state == XenbusStateClosed) {
-			printk(KERN_INFO "%s: %s: prepare for reconnect\n",
-			       __func__, dev->nodename);
+			pr_info("%s: prepare for reconnect\n", dev->nodename);
 			xenbus_switch_state(dev, XenbusStateInitWait);
 		}
 		break;
@@ -393,21 +402,36 @@ static int connect_rings(struct backend_
 	struct xenvif *vif = be->vif;
 	struct xenbus_device *dev = be->dev;
 	unsigned long tx_ring_ref, rx_ring_ref;
-	unsigned int evtchn, rx_copy;
+	unsigned int tx_evtchn, rx_evtchn, rx_copy;
 	int err;
 	int val;
 
 	err = xenbus_gather(XBT_NIL, dev->otherend,
 			    "tx-ring-ref", "%lu", &tx_ring_ref,
-			    "rx-ring-ref", "%lu", &rx_ring_ref,
-			    "event-channel", "%u", &evtchn, NULL);
+			    "rx-ring-ref", "%lu", &rx_ring_ref, NULL);
 	if (err) {
 		xenbus_dev_fatal(dev, err,
-				 "reading %s/ring-ref and event-channel",
+				 "reading %s/ring-ref",
 				 dev->otherend);
 		return err;
 	}
 
+	/* Try split event channels first, then single event channel. */
+	err = xenbus_gather(XBT_NIL, dev->otherend,
+			    "event-channel-tx", "%u", &tx_evtchn,
+			    "event-channel-rx", "%u", &rx_evtchn, NULL);
+	if (err < 0) {
+		err = xenbus_scanf(XBT_NIL, dev->otherend,
+				   "event-channel", "%u", &tx_evtchn);
+		if (err < 0) {
+			xenbus_dev_fatal(dev, err,
+					 "reading %s/event-channel(-tx/rx)",
+					 dev->otherend);
+			return err;
+		}
+		rx_evtchn = tx_evtchn;
+	}
+
 	err = xenbus_scanf(XBT_NIL, dev->otherend, "request-rx-copy", "%u",
 			   &rx_copy);
 	if (err == -ENOENT) {
@@ -454,11 +478,13 @@ static int connect_rings(struct backend_
 	vif->csum = !val;
 
 	/* Map the shared frame, irq etc. */
-	err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref, evtchn);
+	err = xenvif_connect(vif, tx_ring_ref, rx_ring_ref,
+			     tx_evtchn, rx_evtchn);
 	if (err) {
 		xenbus_dev_fatal(dev, err,
-				 "mapping shared-frames %lu/%lu port %u",
-				 tx_ring_ref, rx_ring_ref, evtchn);
+				 "mapping shared-frames %lu/%lu port tx %u rx %u",
+				 tx_ring_ref, rx_ring_ref,
+				 tx_evtchn, rx_evtchn);
 		return err;
 	}
 	return 0;
@@ -485,3 +511,8 @@ int xenvif_xenbus_init(void)
 {
 	return xenbus_register_backend(&netback_driver);
 }
+
+void xenvif_xenbus_fini(void)
+{
+	return xenbus_unregister_driver(&netback_driver);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/net/xen-netfront.c linux-libre-3.11-rc7-gnu/drivers/net/xen-netfront.c
--- linux-libre-3.10-gnu/drivers/net/xen-netfront.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/net/xen-netfront.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,8 @@
  * IN THE SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
@@ -85,7 +87,15 @@ struct netfront_info {
 
 	struct napi_struct napi;
 
-	unsigned int evtchn;
+	/* Split event channels support, tx_* == rx_* when using
+	 * single event channel.
+	 */
+	unsigned int tx_evtchn, rx_evtchn;
+	unsigned int tx_irq, rx_irq;
+	/* Only used when split event channels support is enabled */
+	char tx_irq_name[IFNAMSIZ+4]; /* DEVNAME-tx */
+	char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */
+
 	struct xenbus_device *xbdev;
 
 	spinlock_t   tx_lock;
@@ -276,8 +286,7 @@ no_skb:
 			break;
 		}
 
-		__skb_fill_page_desc(skb, 0, page, 0, 0);
-		skb_shinfo(skb)->nr_frags = 1;
+		skb_add_rx_frag(skb, 0, page, 0, 0, PAGE_SIZE);
 		__skb_queue_tail(&np->rx_batch, skb);
 	}
 
@@ -330,7 +339,7 @@ no_skb:
  push:
 	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
 	if (notify)
-		notify_remote_via_irq(np->netdev->irq);
+		notify_remote_via_irq(np->rx_irq);
 }
 
 static int xennet_open(struct net_device *dev)
@@ -377,9 +386,8 @@ static void xennet_tx_buf_gc(struct net_
 			skb = np->tx_skbs[id].skb;
 			if (unlikely(gnttab_query_foreign_access(
 				np->grant_tx_ref[id]) != 0)) {
-				printk(KERN_ALERT "xennet_tx_buf_gc: warning "
-				       "-- grant still in use by backend "
-				       "domain.\n");
+				pr_alert("%s: warning -- grant still in use by backend domain\n",
+					 __func__);
 				BUG();
 			}
 			gnttab_end_foreign_access_ref(
@@ -623,7 +631,7 @@ static int xennet_start_xmit(struct sk_b
 
 	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
 	if (notify)
-		notify_remote_via_irq(np->netdev->irq);
+		notify_remote_via_irq(np->tx_irq);
 
 	u64_stats_update_begin(&stats->syncp);
 	stats->tx_bytes += skb->len;
@@ -796,14 +804,14 @@ static int xennet_set_skb_gso(struct sk_
 {
 	if (!gso->u.gso.size) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "GSO size must not be zero.\n");
+			pr_warn("GSO size must not be zero\n");
 		return -EINVAL;
 	}
 
 	/* Currently only TCPv4 S.O. is supported. */
 	if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
 		if (net_ratelimit())
-			printk(KERN_WARNING "Bad GSO type %d.\n", gso->u.gso.type);
+			pr_warn("Bad GSO type %d\n", gso->u.gso.type);
 		return -EINVAL;
 	}
 
@@ -822,7 +830,6 @@ static RING_IDX xennet_fill_frags(struct
 				  struct sk_buff_head *list)
 {
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
-	int nr_frags = shinfo->nr_frags;
 	RING_IDX cons = np->rx.rsp_cons;
 	struct sk_buff *nskb;
 
@@ -831,26 +838,27 @@ static RING_IDX xennet_fill_frags(struct
 			RING_GET_RESPONSE(&np->rx, ++cons);
 		skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0];
 
-		__skb_fill_page_desc(skb, nr_frags,
-				     skb_frag_page(nfrag),
-				     rx->offset, rx->status);
+		if (shinfo->nr_frags == MAX_SKB_FRAGS) {
+			unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
 
-		skb->data_len += rx->status;
+			BUG_ON(pull_to <= skb_headlen(skb));
+			__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
+		}
+		BUG_ON(shinfo->nr_frags >= MAX_SKB_FRAGS);
+
+		skb_add_rx_frag(skb, shinfo->nr_frags, skb_frag_page(nfrag),
+				rx->offset, rx->status, PAGE_SIZE);
 
 		skb_shinfo(nskb)->nr_frags = 0;
 		kfree_skb(nskb);
-
-		nr_frags++;
 	}
 
-	shinfo->nr_frags = nr_frags;
 	return cons;
 }
 
 static int checksum_setup(struct net_device *dev, struct sk_buff *skb)
 {
 	struct iphdr *iph;
-	unsigned char *th;
 	int err = -EPROTO;
 	int recalculate_partial_csum = 0;
 
@@ -875,27 +883,27 @@ static int checksum_setup(struct net_dev
 		goto out;
 
 	iph = (void *)skb->data;
-	th = skb->data + 4 * iph->ihl;
-	if (th >= skb_tail_pointer(skb))
-		goto out;
 
-	skb->csum_start = th - skb->head;
 	switch (iph->protocol) {
 	case IPPROTO_TCP:
-		skb->csum_offset = offsetof(struct tcphdr, check);
+		if (!skb_partial_csum_set(skb, 4 * iph->ihl,
+					  offsetof(struct tcphdr, check)))
+			goto out;
 
 		if (recalculate_partial_csum) {
-			struct tcphdr *tcph = (struct tcphdr *)th;
+			struct tcphdr *tcph = tcp_hdr(skb);
 			tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
 							 skb->len - iph->ihl*4,
 							 IPPROTO_TCP, 0);
 		}
 		break;
 	case IPPROTO_UDP:
-		skb->csum_offset = offsetof(struct udphdr, check);
+		if (!skb_partial_csum_set(skb, 4 * iph->ihl,
+					  offsetof(struct udphdr, check)))
+			goto out;
 
 		if (recalculate_partial_csum) {
-			struct udphdr *udph = (struct udphdr *)th;
+			struct udphdr *udph = udp_hdr(skb);
 			udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
 							 skb->len - iph->ihl*4,
 							 IPPROTO_UDP, 0);
@@ -903,15 +911,11 @@ static int checksum_setup(struct net_dev
 		break;
 	default:
 		if (net_ratelimit())
-			printk(KERN_ERR "Attempting to checksum a non-"
-			       "TCP/UDP packet, dropping a protocol"
-			       " %d packet", iph->protocol);
+			pr_err("Attempting to checksum a non-TCP/UDP packet, dropping a protocol %d packet\n",
+			       iph->protocol);
 		goto out;
 	}
 
-	if ((th + skb->csum_offset + 2) > skb_tail_pointer(skb))
-		goto out;
-
 	err = 0;
 
 out:
@@ -929,7 +933,8 @@ static int handle_incoming_queue(struct
 	while ((skb = __skb_dequeue(rxq)) != NULL) {
 		int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
 
-		__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
+		if (pull_to > skb_headlen(skb))
+			__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
 
 		/* Ethernet work: Delayed to here as it peeks the header. */
 		skb->protocol = eth_type_trans(skb, dev);
@@ -1015,16 +1020,10 @@ err:
 		skb_shinfo(skb)->frags[0].page_offset = rx->offset;
 		skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status);
 		skb->data_len = rx->status;
+		skb->len += rx->status;
 
 		i = xennet_fill_frags(np, skb, &tmpq);
 
-		/*
-                 * Truesize is the actual allocation size, even if the
-                 * allocation is only partially used.
-                 */
-		skb->truesize += PAGE_SIZE * skb_shinfo(skb)->nr_frags;
-		skb->len += skb->data_len;
-
 		if (rx->flags & XEN_NETRXF_csum_blank)
 			skb->ip_summed = CHECKSUM_PARTIAL;
 		else if (rx->flags & XEN_NETRXF_data_validated)
@@ -1254,23 +1253,35 @@ static int xennet_set_features(struct ne
 	return 0;
 }
 
-static irqreturn_t xennet_interrupt(int irq, void *dev_id)
+static irqreturn_t xennet_tx_interrupt(int irq, void *dev_id)
 {
-	struct net_device *dev = dev_id;
-	struct netfront_info *np = netdev_priv(dev);
+	struct netfront_info *np = dev_id;
+	struct net_device *dev = np->netdev;
 	unsigned long flags;
 
 	spin_lock_irqsave(&np->tx_lock, flags);
+	xennet_tx_buf_gc(dev);
+	spin_unlock_irqrestore(&np->tx_lock, flags);
 
-	if (likely(netif_carrier_ok(dev))) {
-		xennet_tx_buf_gc(dev);
-		/* Under tx_lock: protects access to rx shared-ring indexes. */
-		if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t xennet_rx_interrupt(int irq, void *dev_id)
+{
+	struct netfront_info *np = dev_id;
+	struct net_device *dev = np->netdev;
+
+	if (likely(netif_carrier_ok(dev) &&
+		   RING_HAS_UNCONSUMED_RESPONSES(&np->rx)))
 			napi_schedule(&np->napi);
-	}
 
-	spin_unlock_irqrestore(&np->tx_lock, flags);
+	return IRQ_HANDLED;
+}
 
+static irqreturn_t xennet_interrupt(int irq, void *dev_id)
+{
+	xennet_tx_interrupt(irq, dev_id);
+	xennet_rx_interrupt(irq, dev_id);
 	return IRQ_HANDLED;
 }
 
@@ -1343,14 +1354,14 @@ static struct net_device *xennet_create_
 	/* A grant for every tx ring slot */
 	if (gnttab_alloc_grant_references(TX_MAX_TARGET,
 					  &np->gref_tx_head) < 0) {
-		printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
+		pr_alert("can't alloc tx grant refs\n");
 		err = -ENOMEM;
 		goto exit_free_stats;
 	}
 	/* A grant for every rx ring slot */
 	if (gnttab_alloc_grant_references(RX_MAX_TARGET,
 					  &np->gref_rx_head) < 0) {
-		printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
+		pr_alert("can't alloc rx grant refs\n");
 		err = -ENOMEM;
 		goto exit_free_tx;
 	}
@@ -1414,16 +1425,14 @@ static int netfront_probe(struct xenbus_
 
 	err = register_netdev(info->netdev);
 	if (err) {
-		printk(KERN_WARNING "%s: register_netdev err=%d\n",
-		       __func__, err);
+		pr_warn("%s: register_netdev err=%d\n", __func__, err);
 		goto fail;
 	}
 
 	err = xennet_sysfs_addif(info->netdev);
 	if (err) {
 		unregister_netdev(info->netdev);
-		printk(KERN_WARNING "%s: add sysfs failed err=%d\n",
-		       __func__, err);
+		pr_warn("%s: add sysfs failed err=%d\n", __func__, err);
 		goto fail;
 	}
 
@@ -1451,9 +1460,14 @@ static void xennet_disconnect_backend(st
 	spin_unlock_irq(&info->tx_lock);
 	spin_unlock_bh(&info->rx_lock);
 
-	if (info->netdev->irq)
-		unbind_from_irqhandler(info->netdev->irq, info->netdev);
-	info->evtchn = info->netdev->irq = 0;
+	if (info->tx_irq && (info->tx_irq == info->rx_irq))
+		unbind_from_irqhandler(info->tx_irq, info);
+	if (info->tx_irq && (info->tx_irq != info->rx_irq)) {
+		unbind_from_irqhandler(info->tx_irq, info);
+		unbind_from_irqhandler(info->rx_irq, info);
+	}
+	info->tx_evtchn = info->rx_evtchn = 0;
+	info->tx_irq = info->rx_irq = 0;
 
 	/* End access and free the pages */
 	xennet_end_access(info->tx_ring_ref, info->tx.sring);
@@ -1503,12 +1517,82 @@ static int xen_net_read_mac(struct xenbu
 	return 0;
 }
 
+static int setup_netfront_single(struct netfront_info *info)
+{
+	int err;
+
+	err = xenbus_alloc_evtchn(info->xbdev, &info->tx_evtchn);
+	if (err < 0)
+		goto fail;
+
+	err = bind_evtchn_to_irqhandler(info->tx_evtchn,
+					xennet_interrupt,
+					0, info->netdev->name, info);
+	if (err < 0)
+		goto bind_fail;
+	info->rx_evtchn = info->tx_evtchn;
+	info->rx_irq = info->tx_irq = err;
+
+	return 0;
+
+bind_fail:
+	xenbus_free_evtchn(info->xbdev, info->tx_evtchn);
+	info->tx_evtchn = 0;
+fail:
+	return err;
+}
+
+static int setup_netfront_split(struct netfront_info *info)
+{
+	int err;
+
+	err = xenbus_alloc_evtchn(info->xbdev, &info->tx_evtchn);
+	if (err < 0)
+		goto fail;
+	err = xenbus_alloc_evtchn(info->xbdev, &info->rx_evtchn);
+	if (err < 0)
+		goto alloc_rx_evtchn_fail;
+
+	snprintf(info->tx_irq_name, sizeof(info->tx_irq_name),
+		 "%s-tx", info->netdev->name);
+	err = bind_evtchn_to_irqhandler(info->tx_evtchn,
+					xennet_tx_interrupt,
+					0, info->tx_irq_name, info);
+	if (err < 0)
+		goto bind_tx_fail;
+	info->tx_irq = err;
+
+	snprintf(info->rx_irq_name, sizeof(info->rx_irq_name),
+		 "%s-rx", info->netdev->name);
+	err = bind_evtchn_to_irqhandler(info->rx_evtchn,
+					xennet_rx_interrupt,
+					0, info->rx_irq_name, info);
+	if (err < 0)
+		goto bind_rx_fail;
+	info->rx_irq = err;
+
+	return 0;
+
+bind_rx_fail:
+	unbind_from_irqhandler(info->tx_irq, info);
+	info->tx_irq = 0;
+bind_tx_fail:
+	xenbus_free_evtchn(info->xbdev, info->rx_evtchn);
+	info->rx_evtchn = 0;
+alloc_rx_evtchn_fail:
+	xenbus_free_evtchn(info->xbdev, info->tx_evtchn);
+	info->tx_evtchn = 0;
+fail:
+	return err;
+}
+
 static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
 {
 	struct xen_netif_tx_sring *txs;
 	struct xen_netif_rx_sring *rxs;
 	int err;
 	struct net_device *netdev = info->netdev;
+	unsigned int feature_split_evtchn;
 
 	info->tx_ring_ref = GRANT_INVALID_REF;
 	info->rx_ring_ref = GRANT_INVALID_REF;
@@ -1516,6 +1600,12 @@ static int setup_netfront(struct xenbus_
 	info->tx.sring = NULL;
 	netdev->irq = 0;
 
+	err = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
+			   "feature-split-event-channels", "%u",
+			   &feature_split_evtchn);
+	if (err < 0)
+		feature_split_evtchn = 0;
+
 	err = xen_net_read_mac(dev, netdev->dev_addr);
 	if (err) {
 		xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename);
@@ -1532,40 +1622,50 @@ static int setup_netfront(struct xenbus_
 	FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
 
 	err = xenbus_grant_ring(dev, virt_to_mfn(txs));
-	if (err < 0) {
-		free_page((unsigned long)txs);
-		goto fail;
-	}
+	if (err < 0)
+		goto grant_tx_ring_fail;
 
 	info->tx_ring_ref = err;
 	rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH);
 	if (!rxs) {
 		err = -ENOMEM;
 		xenbus_dev_fatal(dev, err, "allocating rx ring page");
-		goto fail;
+		goto alloc_rx_ring_fail;
 	}
 	SHARED_RING_INIT(rxs);
 	FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
 
 	err = xenbus_grant_ring(dev, virt_to_mfn(rxs));
-	if (err < 0) {
-		free_page((unsigned long)rxs);
-		goto fail;
-	}
+	if (err < 0)
+		goto grant_rx_ring_fail;
 	info->rx_ring_ref = err;
 
-	err = xenbus_alloc_evtchn(dev, &info->evtchn);
+	if (feature_split_evtchn)
+		err = setup_netfront_split(info);
+	/* setup single event channel if
+	 *  a) feature-split-event-channels == 0
+	 *  b) feature-split-event-channels == 1 but failed to setup
+	 */
+	if (!feature_split_evtchn || (feature_split_evtchn && err))
+		err = setup_netfront_single(info);
+
 	if (err)
-		goto fail;
+		goto alloc_evtchn_fail;
 
-	err = bind_evtchn_to_irqhandler(info->evtchn, xennet_interrupt,
-					0, netdev->name, netdev);
-	if (err < 0)
-		goto fail;
-	netdev->irq = err;
 	return 0;
 
- fail:
+	/* If we fail to setup netfront, it is safe to just revoke access to
+	 * granted pages because backend is not accessing it at this point.
+	 */
+alloc_evtchn_fail:
+	gnttab_end_foreign_access_ref(info->rx_ring_ref, 0);
+grant_rx_ring_fail:
+	free_page((unsigned long)rxs);
+alloc_rx_ring_fail:
+	gnttab_end_foreign_access_ref(info->tx_ring_ref, 0);
+grant_tx_ring_fail:
+	free_page((unsigned long)txs);
+fail:
 	return err;
 }
 
@@ -1601,11 +1701,27 @@ again:
 		message = "writing rx ring-ref";
 		goto abort_transaction;
 	}
-	err = xenbus_printf(xbt, dev->nodename,
-			    "event-channel", "%u", info->evtchn);
-	if (err) {
-		message = "writing event-channel";
-		goto abort_transaction;
+
+	if (info->tx_evtchn == info->rx_evtchn) {
+		err = xenbus_printf(xbt, dev->nodename,
+				    "event-channel", "%u", info->tx_evtchn);
+		if (err) {
+			message = "writing event-channel";
+			goto abort_transaction;
+		}
+	} else {
+		err = xenbus_printf(xbt, dev->nodename,
+				    "event-channel-tx", "%u", info->tx_evtchn);
+		if (err) {
+			message = "writing event-channel-tx";
+			goto abort_transaction;
+		}
+		err = xenbus_printf(xbt, dev->nodename,
+				    "event-channel-rx", "%u", info->rx_evtchn);
+		if (err) {
+			message = "writing event-channel-rx";
+			goto abort_transaction;
+		}
 	}
 
 	err = xenbus_printf(xbt, dev->nodename, "request-rx-copy", "%u",
@@ -1718,7 +1834,9 @@ static int xennet_connect(struct net_dev
 	 * packets.
 	 */
 	netif_carrier_on(np->netdev);
-	notify_remote_via_irq(np->netdev->irq);
+	notify_remote_via_irq(np->tx_irq);
+	if (np->tx_irq != np->rx_irq)
+		notify_remote_via_irq(np->rx_irq);
 	xennet_tx_buf_gc(dev);
 	xennet_alloc_rx_buffers(dev);
 
@@ -1991,7 +2109,7 @@ static int __init netif_init(void)
 	if (xen_hvm_domain() && !xen_platform_pci_unplug)
 		return -ENODEV;
 
-	printk(KERN_INFO "Initialising Xen virtual ethernet driver.\n");
+	pr_info("Initialising Xen virtual ethernet driver\n");
 
 	return xenbus_register_frontend(&netfront_driver);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/nfc/Kconfig linux-libre-3.11-rc7-gnu/drivers/nfc/Kconfig
--- linux-libre-3.10-gnu/drivers/nfc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/nfc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -36,6 +36,16 @@ config NFC_MEI_PHY
 
 	  If unsure, say N.
 
+config NFC_SIM
+	tristate "NFC hardware simulator driver"
+	help
+	  This driver declares two virtual NFC devices supporting NFC-DEP
+	  protocol. An LLCP connection can be established between them and
+	  all packets sent from one device is sent back to the other, acting as
+	  loopback devices.
+
+	  If unsure, say N.
+
 source "drivers/nfc/pn544/Kconfig"
 source "drivers/nfc/microread/Kconfig"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/nfc/Makefile linux-libre-3.11-rc7-gnu/drivers/nfc/Makefile
--- linux-libre-3.10-gnu/drivers/nfc/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/nfc/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -7,5 +7,6 @@ obj-$(CONFIG_NFC_MICROREAD)	+= microread
 obj-$(CONFIG_NFC_PN533)		+= pn533.o
 obj-$(CONFIG_NFC_WILINK)	+= nfcwilink.o
 obj-$(CONFIG_NFC_MEI_PHY)	+= mei_phy.o
+obj-$(CONFIG_NFC_SIM)		+= nfcsim.o
 
 ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/nfc/mei_phy.c linux-libre-3.11-rc7-gnu/drivers/nfc/mei_phy.c
--- linux-libre-3.10-gnu/drivers/nfc/mei_phy.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/nfc/mei_phy.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,7 @@ struct mei_nfc_hdr {
 	u16 req_id;
 	u32 reserved;
 	u16 data_size;
-} __attribute__((packed));
+} __packed;
 
 #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD)
 
@@ -60,8 +60,8 @@ int nfc_mei_phy_enable(void *phy_id)
 
 	r = mei_cl_enable_device(phy->device);
 	if (r < 0) {
-                pr_err("MEI_PHY: Could not enable device\n");
-                return r;
+		pr_err("MEI_PHY: Could not enable device\n");
+		return r;
 	}
 
 	r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/nfc/microread/microread.c linux-libre-3.11-rc7-gnu/drivers/nfc/microread/microread.c
--- linux-libre-3.10-gnu/drivers/nfc/microread/microread.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/nfc/microread/microread.c	2013-08-25 20:43:22.000000000 -0400
@@ -650,7 +650,7 @@ int microread_probe(void *phy_id, struct
 {
 	struct microread_info *info;
 	unsigned long quirks = 0;
-	u32 protocols, se;
+	u32 protocols;
 	struct nfc_hci_init_data init_data;
 	int r;
 
@@ -678,10 +678,8 @@ int microread_probe(void *phy_id, struct
 		    NFC_PROTO_ISO14443_B_MASK |
 		    NFC_PROTO_NFC_DEP_MASK;
 
-	se = NFC_SE_UICC | NFC_SE_EMBEDDED;
-
 	info->hdev = nfc_hci_allocate_device(&microread_hci_ops, &init_data,
-					     quirks, protocols, se, llc_name,
+					     quirks, protocols, llc_name,
 					     phy_headroom +
 					     MICROREAD_CMDS_HEADROOM,
 					     phy_tailroom +
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/nfc/nfcsim.c linux-libre-3.11-rc7-gnu/drivers/nfc/nfcsim.c
--- linux-libre-3.10-gnu/drivers/nfc/nfcsim.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/nfc/nfcsim.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,541 @@
+/*
+ * NFC hardware simulation driver
+ * Copyright (c) 2013, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/nfc.h>
+#include <net/nfc/nfc.h>
+
+#define DEV_ERR(_dev, fmt, args...) nfc_dev_err(&_dev->nfc_dev->dev, \
+						"%s: " fmt, __func__, ## args)
+
+#define DEV_DBG(_dev, fmt, args...) nfc_dev_dbg(&_dev->nfc_dev->dev, \
+						"%s: " fmt, __func__, ## args)
+
+#define NFCSIM_VERSION "0.1"
+
+#define NFCSIM_POLL_NONE	0
+#define NFCSIM_POLL_INITIATOR	1
+#define NFCSIM_POLL_TARGET	2
+#define NFCSIM_POLL_DUAL	(NFCSIM_POLL_INITIATOR | NFCSIM_POLL_TARGET)
+
+struct nfcsim {
+	struct nfc_dev *nfc_dev;
+
+	struct mutex lock;
+
+	struct delayed_work recv_work;
+
+	struct sk_buff *clone_skb;
+
+	struct delayed_work poll_work;
+	u8 polling_mode;
+	u8 curr_polling_mode;
+
+	u8 shutting_down;
+
+	u8 up;
+
+	u8 initiator;
+
+	data_exchange_cb_t cb;
+	void *cb_context;
+
+	struct nfcsim *peer_dev;
+};
+
+static struct nfcsim *dev0;
+static struct nfcsim *dev1;
+
+struct workqueue_struct *wq;
+
+static void nfcsim_cleanup_dev(struct nfcsim *dev, u8 shutdown)
+{
+	DEV_DBG(dev, "shutdown=%d", shutdown);
+
+	mutex_lock(&dev->lock);
+
+	dev->polling_mode = NFCSIM_POLL_NONE;
+	dev->shutting_down = shutdown;
+	dev->cb = NULL;
+	dev_kfree_skb(dev->clone_skb);
+	dev->clone_skb = NULL;
+
+	mutex_unlock(&dev->lock);
+
+	cancel_delayed_work_sync(&dev->poll_work);
+	cancel_delayed_work_sync(&dev->recv_work);
+}
+
+static int nfcsim_target_found(struct nfcsim *dev)
+{
+	struct nfc_target nfc_tgt;
+
+	DEV_DBG(dev, "");
+
+	memset(&nfc_tgt, 0, sizeof(struct nfc_target));
+
+	nfc_tgt.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
+	nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1);
+
+	return 0;
+}
+
+static int nfcsim_dev_up(struct nfc_dev *nfc_dev)
+{
+	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
+
+	DEV_DBG(dev, "");
+
+	mutex_lock(&dev->lock);
+
+	dev->up = 1;
+
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+static int nfcsim_dev_down(struct nfc_dev *nfc_dev)
+{
+	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
+
+	DEV_DBG(dev, "");
+
+	mutex_lock(&dev->lock);
+
+	dev->up = 0;
+
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+static int nfcsim_dep_link_up(struct nfc_dev *nfc_dev,
+			      struct nfc_target *target,
+			      u8 comm_mode, u8 *gb, size_t gb_len)
+{
+	int rc;
+	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
+	struct nfcsim *peer = dev->peer_dev;
+	u8 *remote_gb;
+	size_t remote_gb_len;
+
+	DEV_DBG(dev, "target_idx: %d, comm_mode: %d\n", target->idx, comm_mode);
+
+	mutex_lock(&peer->lock);
+
+	nfc_tm_activated(peer->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
+			 NFC_COMM_ACTIVE, gb, gb_len);
+
+	remote_gb = nfc_get_local_general_bytes(peer->nfc_dev, &remote_gb_len);
+	if (!remote_gb) {
+		DEV_ERR(peer, "Can't get remote general bytes");
+
+		mutex_unlock(&peer->lock);
+		return -EINVAL;
+	}
+
+	mutex_unlock(&peer->lock);
+
+	mutex_lock(&dev->lock);
+
+	rc = nfc_set_remote_general_bytes(nfc_dev, remote_gb, remote_gb_len);
+	if (rc) {
+		DEV_ERR(dev, "Can't set remote general bytes");
+		mutex_unlock(&dev->lock);
+		return rc;
+	}
+
+	rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_ACTIVE,
+				NFC_RF_INITIATOR);
+
+	mutex_unlock(&dev->lock);
+
+	return rc;
+}
+
+static int nfcsim_dep_link_down(struct nfc_dev *nfc_dev)
+{
+	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
+
+	DEV_DBG(dev, "");
+
+	nfcsim_cleanup_dev(dev, 0);
+
+	return 0;
+}
+
+static int nfcsim_start_poll(struct nfc_dev *nfc_dev,
+			     u32 im_protocols, u32 tm_protocols)
+{
+	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
+	int rc;
+
+	mutex_lock(&dev->lock);
+
+	if (dev->polling_mode != NFCSIM_POLL_NONE) {
+		DEV_ERR(dev, "Already in polling mode");
+		rc = -EBUSY;
+		goto exit;
+	}
+
+	if (im_protocols & NFC_PROTO_NFC_DEP_MASK)
+		dev->polling_mode |= NFCSIM_POLL_INITIATOR;
+
+	if (tm_protocols & NFC_PROTO_NFC_DEP_MASK)
+		dev->polling_mode |= NFCSIM_POLL_TARGET;
+
+	if (dev->polling_mode == NFCSIM_POLL_NONE) {
+		DEV_ERR(dev, "Unsupported polling mode");
+		rc = -EINVAL;
+		goto exit;
+	}
+
+	dev->initiator = 0;
+	dev->curr_polling_mode = NFCSIM_POLL_NONE;
+
+	queue_delayed_work(wq, &dev->poll_work, 0);
+
+	DEV_DBG(dev, "Start polling: im: 0x%X, tm: 0x%X", im_protocols,
+		tm_protocols);
+
+	rc = 0;
+exit:
+	mutex_unlock(&dev->lock);
+
+	return rc;
+}
+
+static void nfcsim_stop_poll(struct nfc_dev *nfc_dev)
+{
+	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
+
+	DEV_DBG(dev, "Stop poll");
+
+	mutex_lock(&dev->lock);
+
+	dev->polling_mode = NFCSIM_POLL_NONE;
+
+	mutex_unlock(&dev->lock);
+
+	cancel_delayed_work_sync(&dev->poll_work);
+}
+
+static int nfcsim_activate_target(struct nfc_dev *nfc_dev,
+				  struct nfc_target *target, u32 protocol)
+{
+	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
+
+	DEV_DBG(dev, "");
+
+	return -ENOTSUPP;
+}
+
+static void nfcsim_deactivate_target(struct nfc_dev *nfc_dev,
+				     struct nfc_target *target)
+{
+	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
+
+	DEV_DBG(dev, "");
+}
+
+static void nfcsim_wq_recv(struct work_struct *work)
+{
+	struct nfcsim *dev = container_of(work, struct nfcsim,
+					  recv_work.work);
+
+	mutex_lock(&dev->lock);
+
+	if (dev->shutting_down || !dev->up || !dev->clone_skb) {
+		dev_kfree_skb(dev->clone_skb);
+		goto exit;
+	}
+
+	if (dev->initiator) {
+		if (!dev->cb) {
+			DEV_ERR(dev, "Null recv callback");
+			dev_kfree_skb(dev->clone_skb);
+			goto exit;
+		}
+
+		dev->cb(dev->cb_context, dev->clone_skb, 0);
+		dev->cb = NULL;
+	} else {
+		nfc_tm_data_received(dev->nfc_dev, dev->clone_skb);
+	}
+
+exit:
+	dev->clone_skb = NULL;
+
+	mutex_unlock(&dev->lock);
+}
+
+static int nfcsim_tx(struct nfc_dev *nfc_dev, struct nfc_target *target,
+		     struct sk_buff *skb, data_exchange_cb_t cb,
+		     void *cb_context)
+{
+	struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
+	struct nfcsim *peer = dev->peer_dev;
+	int err;
+
+	mutex_lock(&dev->lock);
+
+	if (dev->shutting_down || !dev->up) {
+		mutex_unlock(&dev->lock);
+		err = -ENODEV;
+		goto exit;
+	}
+
+	dev->cb = cb;
+	dev->cb_context = cb_context;
+
+	mutex_unlock(&dev->lock);
+
+	mutex_lock(&peer->lock);
+
+	peer->clone_skb = skb_clone(skb, GFP_KERNEL);
+
+	if (!peer->clone_skb) {
+		DEV_ERR(dev, "skb_clone failed");
+		mutex_unlock(&peer->lock);
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	/* This simulates an arbitrary transmission delay between the 2 devices.
+	 * If packet transmission occurs immediately between them, we have a
+	 * non-stop flow of several tens of thousands SYMM packets per second
+	 * and a burning cpu.
+	 *
+	 * TODO: Add support for a sysfs entry to control this delay.
+	 */
+	queue_delayed_work(wq, &peer->recv_work, msecs_to_jiffies(5));
+
+	mutex_unlock(&peer->lock);
+
+	err = 0;
+exit:
+	dev_kfree_skb(skb);
+
+	return err;
+}
+
+static int nfcsim_im_transceive(struct nfc_dev *nfc_dev,
+				struct nfc_target *target, struct sk_buff *skb,
+				data_exchange_cb_t cb, void *cb_context)
+{
+	return nfcsim_tx(nfc_dev, target, skb, cb, cb_context);
+}
+
+static int nfcsim_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb)
+{
+	return nfcsim_tx(nfc_dev, NULL, skb, NULL, NULL);
+}
+
+static struct nfc_ops nfcsim_nfc_ops = {
+	.dev_up = nfcsim_dev_up,
+	.dev_down = nfcsim_dev_down,
+	.dep_link_up = nfcsim_dep_link_up,
+	.dep_link_down = nfcsim_dep_link_down,
+	.start_poll = nfcsim_start_poll,
+	.stop_poll = nfcsim_stop_poll,
+	.activate_target = nfcsim_activate_target,
+	.deactivate_target = nfcsim_deactivate_target,
+	.im_transceive = nfcsim_im_transceive,
+	.tm_send = nfcsim_tm_send,
+};
+
+static void nfcsim_set_polling_mode(struct nfcsim *dev)
+{
+	if (dev->polling_mode == NFCSIM_POLL_NONE) {
+		dev->curr_polling_mode = NFCSIM_POLL_NONE;
+		return;
+	}
+
+	if (dev->curr_polling_mode == NFCSIM_POLL_NONE) {
+		if (dev->polling_mode & NFCSIM_POLL_INITIATOR)
+			dev->curr_polling_mode = NFCSIM_POLL_INITIATOR;
+		else
+			dev->curr_polling_mode = NFCSIM_POLL_TARGET;
+
+		return;
+	}
+
+	if (dev->polling_mode == NFCSIM_POLL_DUAL) {
+		if (dev->curr_polling_mode == NFCSIM_POLL_TARGET)
+			dev->curr_polling_mode = NFCSIM_POLL_INITIATOR;
+		else
+			dev->curr_polling_mode = NFCSIM_POLL_TARGET;
+	}
+}
+
+static void nfcsim_wq_poll(struct work_struct *work)
+{
+	struct nfcsim *dev = container_of(work, struct nfcsim, poll_work.work);
+	struct nfcsim *peer = dev->peer_dev;
+
+	/* These work items run on an ordered workqueue and are therefore
+	 * serialized. So we can take both mutexes without being dead locked.
+	 */
+	mutex_lock(&dev->lock);
+	mutex_lock(&peer->lock);
+
+	nfcsim_set_polling_mode(dev);
+
+	if (dev->curr_polling_mode == NFCSIM_POLL_NONE) {
+		DEV_DBG(dev, "Not polling");
+		goto unlock;
+	}
+
+	DEV_DBG(dev, "Polling as %s",
+		dev->curr_polling_mode == NFCSIM_POLL_INITIATOR ?
+		"initiator" : "target");
+
+	if (dev->curr_polling_mode == NFCSIM_POLL_TARGET)
+		goto sched_work;
+
+	if (peer->curr_polling_mode == NFCSIM_POLL_TARGET) {
+		peer->polling_mode = NFCSIM_POLL_NONE;
+		dev->polling_mode = NFCSIM_POLL_NONE;
+
+		dev->initiator = 1;
+
+		nfcsim_target_found(dev);
+
+		goto unlock;
+	}
+
+sched_work:
+	/* This defines the delay for an initiator to check if the other device
+	 * is polling in target mode.
+	 * If the device starts in dual mode polling, it switches between
+	 * initiator and target at every round.
+	 * Because the wq is ordered and only 1 work item is executed at a time,
+	 * we'll always have one device polling as initiator and the other as
+	 * target at some point, even if both are started in dual mode.
+	 */
+	queue_delayed_work(wq, &dev->poll_work, msecs_to_jiffies(200));
+
+unlock:
+	mutex_unlock(&peer->lock);
+	mutex_unlock(&dev->lock);
+}
+
+static struct nfcsim *nfcsim_init_dev(void)
+{
+	struct nfcsim *dev;
+	int rc = -ENOMEM;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&dev->lock);
+
+	INIT_DELAYED_WORK(&dev->recv_work, nfcsim_wq_recv);
+	INIT_DELAYED_WORK(&dev->poll_work, nfcsim_wq_poll);
+
+	dev->nfc_dev = nfc_allocate_device(&nfcsim_nfc_ops,
+					   NFC_PROTO_NFC_DEP_MASK,
+					   0, 0);
+	if (!dev->nfc_dev)
+		goto error;
+
+	nfc_set_drvdata(dev->nfc_dev, dev);
+
+	rc = nfc_register_device(dev->nfc_dev);
+	if (rc)
+		goto free_nfc_dev;
+
+	return dev;
+
+free_nfc_dev:
+	nfc_free_device(dev->nfc_dev);
+
+error:
+	kfree(dev);
+
+	return ERR_PTR(rc);
+}
+
+static void nfcsim_free_device(struct nfcsim *dev)
+{
+	nfc_unregister_device(dev->nfc_dev);
+
+	nfc_free_device(dev->nfc_dev);
+
+	kfree(dev);
+}
+
+int __init nfcsim_init(void)
+{
+	int rc;
+
+	/* We need an ordered wq to ensure that poll_work items are executed
+	 * one at a time.
+	 */
+	wq = alloc_ordered_workqueue("nfcsim", 0);
+	if (!wq) {
+		rc = -ENOMEM;
+		goto exit;
+	}
+
+	dev0 = nfcsim_init_dev();
+	if (IS_ERR(dev0)) {
+		rc = PTR_ERR(dev0);
+		goto exit;
+	}
+
+	dev1 = nfcsim_init_dev();
+	if (IS_ERR(dev1)) {
+		kfree(dev0);
+
+		rc = PTR_ERR(dev1);
+		goto exit;
+	}
+
+	dev0->peer_dev = dev1;
+	dev1->peer_dev = dev0;
+
+	pr_debug("NFCsim " NFCSIM_VERSION " initialized\n");
+
+	rc = 0;
+exit:
+	if (rc)
+		pr_err("Failed to initialize nfcsim driver (%d)\n",
+		       rc);
+
+	return rc;
+}
+
+void __exit nfcsim_exit(void)
+{
+	nfcsim_cleanup_dev(dev0, 1);
+	nfcsim_cleanup_dev(dev1, 1);
+
+	nfcsim_free_device(dev0);
+	nfcsim_free_device(dev1);
+
+	destroy_workqueue(wq);
+}
+
+module_init(nfcsim_init);
+module_exit(nfcsim_exit);
+
+MODULE_DESCRIPTION("NFCSim driver ver " NFCSIM_VERSION);
+MODULE_VERSION(NFCSIM_VERSION);
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/nfc/nfcwilink.c linux-libre-3.11-rc7-gnu/drivers/nfc/nfcwilink.c
--- linux-libre-3.10-gnu/drivers/nfc/nfcwilink.c	2013-07-01 10:37:48.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/nfc/nfcwilink.c	2013-08-31 17:57:22.000000000 -0400
@@ -109,7 +109,7 @@ enum {
 	NFCWILINK_FW_DOWNLOAD,
 };
 
-static int nfcwilink_send(struct sk_buff *skb);
+static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb);
 
 static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how)
 {
@@ -156,8 +156,6 @@ static int nfcwilink_get_bts_file_name(s
 		return -ENOMEM;
 	}
 
-	skb->dev = (void *)drv->ndev;
-
 	cmd = (struct nci_vs_nfcc_info_cmd *)
 			skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd));
 	cmd->gid = NCI_VS_NFCC_INFO_CMD_GID;
@@ -166,7 +164,7 @@ static int nfcwilink_get_bts_file_name(s
 
 	drv->nfcc_info.plen = 0;
 
-	rc = nfcwilink_send(skb);
+	rc = nfcwilink_send(drv->ndev, skb);
 	if (rc)
 		return rc;
 
@@ -232,11 +230,9 @@ static int nfcwilink_send_bts_cmd(struct
 		return -ENOMEM;
 	}
 
-	skb->dev = (void *)drv->ndev;
-
 	memcpy(skb_put(skb, len), data, len);
 
-	rc = nfcwilink_send(skb);
+	rc = nfcwilink_send(drv->ndev, skb);
 	if (rc)
 		return rc;
 
@@ -371,10 +367,8 @@ static long nfcwilink_receive(void *priv
 		return 0;
 	}
 
-	skb->dev = (void *) drv->ndev;
-
 	/* Forward skb to NCI core layer */
-	rc = nci_recv_frame(skb);
+	rc = nci_recv_frame(drv->ndev, skb);
 	if (rc < 0) {
 		nfc_dev_err(&drv->pdev->dev, "nci_recv_frame failed %d", rc);
 		return rc;
@@ -480,9 +474,8 @@ static int nfcwilink_close(struct nci_de
 	return rc;
 }
 
-static int nfcwilink_send(struct sk_buff *skb)
+static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb)
 {
-	struct nci_dev *ndev = (struct nci_dev *)skb->dev;
 	struct nfcwilink *drv = nci_get_drvdata(ndev);
 	struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000};
 	long len;
@@ -542,7 +535,6 @@ static int nfcwilink_probe(struct platfo
 
 	drv->ndev = nci_allocate_device(&nfcwilink_ops,
 					protocols,
-					NFC_SE_NONE,
 					NFCWILINK_HDR_LEN,
 					0);
 	if (!drv->ndev) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/nfc/pn533.c linux-libre-3.11-rc7-gnu/drivers/nfc/pn533.c
--- linux-libre-3.10-gnu/drivers/nfc/pn533.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/nfc/pn533.c	2013-08-25 20:43:22.000000000 -0400
@@ -258,7 +258,7 @@ static const struct pn533_poll_modulatio
 				.opcode = PN533_FELICA_OPC_SENSF_REQ,
 				.sc = PN533_FELICA_SENSF_SC_ALL,
 				.rc = PN533_FELICA_SENSF_RC_NO_SYSTEM_CODE,
-				.tsn = 0,
+				.tsn = 0x03,
 			},
 		},
 		.len = 7,
@@ -271,7 +271,7 @@ static const struct pn533_poll_modulatio
 				.opcode = PN533_FELICA_OPC_SENSF_REQ,
 				.sc = PN533_FELICA_SENSF_SC_ALL,
 				.rc = PN533_FELICA_SENSF_RC_NO_SYSTEM_CODE,
-				.tsn = 0,
+				.tsn = 0x03,
 			},
 		 },
 		.len = 7,
@@ -1235,7 +1235,7 @@ static int pn533_target_found_type_a(str
 struct pn533_target_felica {
 	u8 pol_res;
 	u8 opcode;
-	u8 nfcid2[8];
+	u8 nfcid2[NFC_NFCID2_MAXSIZE];
 	u8 pad[8];
 	/* optional */
 	u8 syst_code[];
@@ -1275,6 +1275,9 @@ static int pn533_target_found_felica(str
 	memcpy(nfc_tgt->sensf_res, &tgt_felica->opcode, 9);
 	nfc_tgt->sensf_res_len = 9;
 
+	memcpy(nfc_tgt->nfcid2, tgt_felica->nfcid2, NFC_NFCID2_MAXSIZE);
+	nfc_tgt->nfcid2_len = NFC_NFCID2_MAXSIZE;
+
 	return 0;
 }
 
@@ -1697,7 +1700,7 @@ static int pn533_poll_complete(struct pn
 		goto done;
 
 	if (!dev->poll_mod_count) {
-		nfc_dev_dbg(&dev->interface->dev, "Polling has been stoped.");
+		nfc_dev_dbg(&dev->interface->dev, "Polling has been stopped.");
 		goto done;
 	}
 
@@ -2084,6 +2087,9 @@ static int pn533_dep_link_up(struct nfc_
 	if (comm_mode == NFC_COMM_PASSIVE)
 		skb_len += PASSIVE_DATA_LEN;
 
+	if (target && target->nfcid2_len)
+		skb_len += NFC_NFCID3_MAXSIZE;
+
 	skb = pn533_alloc_skb(dev, skb_len);
 	if (!skb)
 		return -ENOMEM;
@@ -2100,6 +2106,12 @@ static int pn533_dep_link_up(struct nfc_
 		*next |= 1;
 	}
 
+	if (target && target->nfcid2_len) {
+		memcpy(skb_put(skb, NFC_NFCID3_MAXSIZE), target->nfcid2,
+		       target->nfcid2_len);
+		*next |= 2;
+	}
+
 	if (gb != NULL && gb_len > 0) {
 		memcpy(skb_put(skb, gb_len), gb, gb_len);
 		*next |= 4; /* We have some Gi */
@@ -2489,7 +2501,7 @@ static void pn533_acr122_poweron_rdr_res
 
 	nfc_dev_dbg(&urb->dev->dev, "%s", __func__);
 
-	print_hex_dump(KERN_ERR, "ACR122 RX: ", DUMP_PREFIX_NONE, 16, 1,
+	print_hex_dump_debug("ACR122 RX: ", DUMP_PREFIX_NONE, 16, 1,
 		       urb->transfer_buffer, urb->transfer_buffer_length,
 		       false);
 
@@ -2520,7 +2532,7 @@ static int pn533_acr122_poweron_rdr(stru
 	dev->out_urb->transfer_buffer = cmd;
 	dev->out_urb->transfer_buffer_length = sizeof(cmd);
 
-	print_hex_dump(KERN_ERR, "ACR122 TX: ", DUMP_PREFIX_NONE, 16, 1,
+	print_hex_dump_debug("ACR122 TX: ", DUMP_PREFIX_NONE, 16, 1,
 		       cmd, sizeof(cmd), false);
 
 	rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
@@ -2774,17 +2786,18 @@ static int pn533_probe(struct usb_interf
 		goto destroy_wq;
 
 	nfc_dev_info(&dev->interface->dev,
-		     "NXP PN533 firmware ver %d.%d now attached",
-		     fw_ver.ver, fw_ver.rev);
+		     "NXP PN5%02X firmware ver %d.%d now attached",
+		     fw_ver.ic, fw_ver.ver, fw_ver.rev);
 
 
 	dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
-					   NFC_SE_NONE,
 					   dev->ops->tx_header_len +
 					   PN533_CMD_DATAEXCH_HEAD_LEN,
 					   dev->ops->tx_tail_len);
-	if (!dev->nfc_dev)
+	if (!dev->nfc_dev) {
+		rc = -ENOMEM;
 		goto destroy_wq;
+	}
 
 	nfc_set_parent_dev(dev->nfc_dev, &interface->dev);
 	nfc_set_drvdata(dev->nfc_dev, dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/nfc/pn544/pn544.c linux-libre-3.11-rc7-gnu/drivers/nfc/pn544/pn544.c
--- linux-libre-3.10-gnu/drivers/nfc/pn544/pn544.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/nfc/pn544/pn544.c	2013-08-25 20:43:22.000000000 -0400
@@ -551,20 +551,25 @@ static int pn544_hci_complete_target_dis
 			return -EPROTO;
 		}
 
-		r = nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE,
-				     PN544_RF_READER_CMD_ACTIVATE_NEXT,
-				     uid_skb->data, uid_skb->len, NULL);
-		kfree_skb(uid_skb);
-
-		r = nfc_hci_send_cmd(hdev,
+		/* Type F NFC-DEP IDm has prefix 0x01FE */
+		if ((uid_skb->data[0] == 0x01) && (uid_skb->data[1] == 0xfe)) {
+			kfree_skb(uid_skb);
+			r = nfc_hci_send_cmd(hdev,
 					PN544_RF_READER_NFCIP1_INITIATOR_GATE,
 					PN544_HCI_CMD_CONTINUE_ACTIVATION,
 					NULL, 0, NULL);
-		if (r < 0)
-			return r;
+			if (r < 0)
+				return r;
 
-		target->hci_reader_gate = PN544_RF_READER_NFCIP1_INITIATOR_GATE;
-		target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
+			target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
+			target->hci_reader_gate =
+				PN544_RF_READER_NFCIP1_INITIATOR_GATE;
+		} else {
+			r = nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE,
+					     PN544_RF_READER_CMD_ACTIVATE_NEXT,
+					     uid_skb->data, uid_skb->len, NULL);
+			kfree_skb(uid_skb);
+		}
 	} else if (target->supported_protocols & NFC_PROTO_ISO14443_MASK) {
 		/*
 		 * TODO: maybe other ISO 14443 require some kind of continue
@@ -706,12 +711,9 @@ static int pn544_hci_check_presence(stru
 		 return nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE,
 				     PN544_RF_READER_CMD_ACTIVATE_NEXT,
 				     target->nfcid1, target->nfcid1_len, NULL);
-	} else if (target->supported_protocols & NFC_PROTO_JEWEL_MASK) {
-		return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
-					PN544_JEWEL_RAW_CMD, NULL, 0, NULL);
-	} else if (target->supported_protocols & NFC_PROTO_FELICA_MASK) {
-		return nfc_hci_send_cmd(hdev, PN544_RF_READER_F_GATE,
-					PN544_FELICA_RAW, NULL, 0, NULL);
+	} else if (target->supported_protocols & (NFC_PROTO_JEWEL_MASK |
+						NFC_PROTO_FELICA_MASK)) {
+		return -EOPNOTSUPP;
 	} else if (target->supported_protocols & NFC_PROTO_NFC_DEP_MASK) {
 		return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
 					PN544_HCI_CMD_ATTREQUEST,
@@ -801,7 +803,7 @@ int pn544_hci_probe(void *phy_id, struct
 		    struct nfc_hci_dev **hdev)
 {
 	struct pn544_hci_info *info;
-	u32 protocols, se;
+	u32 protocols;
 	struct nfc_hci_init_data init_data;
 	int r;
 
@@ -834,10 +836,8 @@ int pn544_hci_probe(void *phy_id, struct
 		    NFC_PROTO_ISO14443_B_MASK |
 		    NFC_PROTO_NFC_DEP_MASK;
 
-	se = NFC_SE_UICC | NFC_SE_EMBEDDED;
-
 	info->hdev = nfc_hci_allocate_device(&pn544_hci_ops, &init_data, 0,
-					     protocols, se, llc_name,
+					     protocols, llc_name,
 					     phy_headroom + PN544_CMDS_HEADROOM,
 					     phy_tailroom, phy_payload);
 	if (!info->hdev) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/of/address.c linux-libre-3.11-rc7-gnu/drivers/of/address.c
--- linux-libre-3.10-gnu/drivers/of/address.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/of/address.c	2013-08-25 20:43:22.000000000 -0400
@@ -106,8 +106,12 @@ static unsigned int of_bus_default_get_f
 
 static int of_bus_pci_match(struct device_node *np)
 {
-	/* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
-	return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
+	/*
+	 * "vci" is for the /chaos bridge on 1st-gen PCI powermacs
+	 * "ht" is hypertransport
+	 */
+	return !strcmp(np->type, "pci") || !strcmp(np->type, "vci") ||
+		!strcmp(np->type, "ht");
 }
 
 static void of_bus_pci_count_cells(struct device_node *np,
@@ -227,6 +231,73 @@ int of_pci_address_to_resource(struct de
 	return __of_address_to_resource(dev, addrp, size, flags, NULL, r);
 }
 EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+				struct device_node *node)
+{
+	const int na = 3, ns = 2;
+	int rlen;
+
+	parser->node = node;
+	parser->pna = of_n_addr_cells(node);
+	parser->np = parser->pna + na + ns;
+
+	parser->range = of_get_property(node, "ranges", &rlen);
+	if (parser->range == NULL)
+		return -ENOENT;
+
+	parser->end = parser->range + rlen / sizeof(__be32);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_init);
+
+struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
+						struct of_pci_range *range)
+{
+	const int na = 3, ns = 2;
+
+	if (!range)
+		return NULL;
+
+	if (!parser->range || parser->range + parser->np > parser->end)
+		return NULL;
+
+	range->pci_space = parser->range[0];
+	range->flags = of_bus_pci_get_flags(parser->range);
+	range->pci_addr = of_read_number(parser->range + 1, ns);
+	range->cpu_addr = of_translate_address(parser->node,
+				parser->range + na);
+	range->size = of_read_number(parser->range + parser->pna + na, ns);
+
+	parser->range += parser->np;
+
+	/* Now consume following elements while they are contiguous */
+	while (parser->range + parser->np <= parser->end) {
+		u32 flags, pci_space;
+		u64 pci_addr, cpu_addr, size;
+
+		pci_space = be32_to_cpup(parser->range);
+		flags = of_bus_pci_get_flags(parser->range);
+		pci_addr = of_read_number(parser->range + 1, ns);
+		cpu_addr = of_translate_address(parser->node,
+				parser->range + na);
+		size = of_read_number(parser->range + parser->pna + na, ns);
+
+		if (flags != range->flags)
+			break;
+		if (pci_addr != range->pci_addr + range->size ||
+		    cpu_addr != range->cpu_addr + range->size)
+			break;
+
+		range->size += size;
+		parser->range += parser->np;
+	}
+
+	return range;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
+
 #endif /* CONFIG_PCI */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/of/base.c linux-libre-3.11-rc7-gnu/drivers/of/base.c
--- linux-libre-3.10-gnu/drivers/of/base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/of/base.c	2013-08-25 20:43:22.000000000 -0400
@@ -812,7 +812,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_i
  *
  * @np:		device node from which the property value is to be read.
  * @propname:	name of the property to be searched.
- * @out_value:	pointer to return value, modified only if return value is 0.
+ * @out_values:	pointer to return value, modified only if return value is 0.
  * @sz:		number of array elements to read
  *
  * Search for a property in a device node and read 8-bit value(s) from
@@ -823,7 +823,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_i
  * dts entry of array should be like:
  *	property = /bits/ 8 <0x50 0x60 0x70>;
  *
- * The out_value is modified only if a valid u8 value can be decoded.
+ * The out_values is modified only if a valid u8 value can be decoded.
  */
 int of_property_read_u8_array(const struct device_node *np,
 			const char *propname, u8 *out_values, size_t sz)
@@ -845,7 +845,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u8_ar
  *
  * @np:		device node from which the property value is to be read.
  * @propname:	name of the property to be searched.
- * @out_value:	pointer to return value, modified only if return value is 0.
+ * @out_values:	pointer to return value, modified only if return value is 0.
  * @sz:		number of array elements to read
  *
  * Search for a property in a device node and read 16-bit value(s) from
@@ -856,7 +856,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u8_ar
  * dts entry of array should be like:
  *	property = /bits/ 16 <0x5000 0x6000 0x7000>;
  *
- * The out_value is modified only if a valid u16 value can be decoded.
+ * The out_values is modified only if a valid u16 value can be decoded.
  */
 int of_property_read_u16_array(const struct device_node *np,
 			const char *propname, u16 *out_values, size_t sz)
@@ -879,7 +879,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u16_a
  *
  * @np:		device node from which the property value is to be read.
  * @propname:	name of the property to be searched.
- * @out_value:	pointer to return value, modified only if return value is 0.
+ * @out_values:	pointer to return value, modified only if return value is 0.
  * @sz:		number of array elements to read
  *
  * Search for a property in a device node and read 32-bit value(s) from
@@ -887,7 +887,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u16_a
  * -ENODATA if property does not have a value, and -EOVERFLOW if the
  * property data isn't large enough.
  *
- * The out_value is modified only if a valid u32 value can be decoded.
+ * The out_values is modified only if a valid u32 value can be decoded.
  */
 int of_property_read_u32_array(const struct device_node *np,
 			       const char *propname, u32 *out_values,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/of/fdt.c linux-libre-3.11-rc7-gnu/drivers/of/fdt.c
--- linux-libre-3.10-gnu/drivers/of/fdt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/of/fdt.c	2013-08-25 20:43:22.000000000 -0400
@@ -392,6 +392,8 @@ static void __unflatten_device_tree(stru
 	mem = (unsigned long)
 		dt_alloc(size + 4, __alignof__(struct device_node));
 
+	memset((void *)mem, 0, size);
+
 	((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
 
 	pr_debug("  unflattening %lx...\n", mem);
@@ -709,7 +711,7 @@ void __init unflatten_device_tree(void)
 	__unflatten_device_tree(initial_boot_params, &of_allnodes,
 				early_init_dt_alloc_memory_arch);
 
-	/* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */
+	/* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
 	of_alias_scan(early_init_dt_alloc_memory_arch);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/of/irq.c linux-libre-3.11-rc7-gnu/drivers/of/irq.c
--- linux-libre-3.10-gnu/drivers/of/irq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/of/irq.c	2013-08-25 20:43:22.000000000 -0400
@@ -345,6 +345,7 @@ int of_irq_to_resource(struct device_nod
 	if (r && irq) {
 		const char *name = NULL;
 
+		memset(r, 0, sizeof(*r));
 		/*
 		 * Get optional "interrupts-names" property to add a name
 		 * to the resource.
@@ -482,8 +483,9 @@ void __init of_irq_init(const struct of_
 		}
 
 		/* Get the next pending parent that might have children */
-		desc = list_first_entry(&intc_parent_list, typeof(*desc), list);
-		if (list_empty(&intc_parent_list) || !desc) {
+		desc = list_first_entry_or_null(&intc_parent_list,
+						typeof(*desc), list);
+		if (!desc) {
 			pr_err("of_irq_init: children remain, but no parents\n");
 			break;
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/of/Kconfig linux-libre-3.11-rc7-gnu/drivers/of/Kconfig
--- linux-libre-3.10-gnu/drivers/of/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/of/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -48,9 +48,6 @@ config OF_IRQ
 	def_bool y
 	depends on !SPARC
 
-config OF_DEVICE
-	def_bool y
-
 config OF_I2C
 	def_tristate I2C
 	depends on I2C
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/of/Makefile linux-libre-3.11-rc7-gnu/drivers/of/Makefile
--- linux-libre-3.10-gnu/drivers/of/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/of/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,9 +1,8 @@
-obj-y = base.o
+obj-y = base.o device.o platform.o
 obj-$(CONFIG_OF_FLATTREE) += fdt.o
 obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
 obj-$(CONFIG_OF_IRQ)    += irq.o
-obj-$(CONFIG_OF_DEVICE) += device.o platform.o
 obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_NET)	+= of_net.o
 obj-$(CONFIG_OF_SELFTEST) += selftest.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/of/of_net.c linux-libre-3.11-rc7-gnu/drivers/of/of_net.c
--- linux-libre-3.10-gnu/drivers/of/of_net.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/of/of_net.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,7 @@ static const char *phy_modes[] = {
 	[PHY_INTERFACE_MODE_GMII]	= "gmii",
 	[PHY_INTERFACE_MODE_SGMII]	= "sgmii",
 	[PHY_INTERFACE_MODE_TBI]	= "tbi",
+	[PHY_INTERFACE_MODE_REVMII]	= "rev-mii",
 	[PHY_INTERFACE_MODE_RMII]	= "rmii",
 	[PHY_INTERFACE_MODE_RGMII]	= "rgmii",
 	[PHY_INTERFACE_MODE_RGMII_ID]	= "rgmii-id",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/of/of_pci.c linux-libre-3.11-rc7-gnu/drivers/of/of_pci.c
--- linux-libre-3.10-gnu/drivers/of/of_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/of/of_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -5,14 +5,15 @@
 #include <asm/prom.h>
 
 static inline int __of_pci_pci_compare(struct device_node *node,
-				       unsigned int devfn)
+				       unsigned int data)
 {
-	unsigned int size;
-	const __be32 *reg = of_get_property(node, "reg", &size);
+	int devfn;
 
-	if (!reg || size < 5 * sizeof(__be32))
+	devfn = of_pci_get_devfn(node);
+	if (devfn < 0)
 		return 0;
-	return ((be32_to_cpup(&reg[0]) >> 8) & 0xff) == devfn;
+
+	return devfn == data;
 }
 
 struct device_node *of_pci_find_child_device(struct device_node *parent,
@@ -40,3 +41,51 @@ struct device_node *of_pci_find_child_de
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(of_pci_find_child_device);
+
+/**
+ * of_pci_get_devfn() - Get device and function numbers for a device node
+ * @np: device node
+ *
+ * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
+ * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
+ * and function numbers respectively. On error a negative error code is
+ * returned.
+ */
+int of_pci_get_devfn(struct device_node *np)
+{
+	unsigned int size;
+	const __be32 *reg;
+
+	reg = of_get_property(np, "reg", &size);
+
+	if (!reg || size < 5 * sizeof(__be32))
+		return -EINVAL;
+
+	return (be32_to_cpup(reg) >> 8) & 0xff;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_devfn);
+
+/**
+ * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
+ * @node: device node
+ * @res: address to a struct resource to return the bus-range
+ *
+ * Returns 0 on success or a negative error-code on failure.
+ */
+int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
+{
+	const __be32 *values;
+	int len;
+
+	values = of_get_property(node, "bus-range", &len);
+	if (!values || len < sizeof(*values) * 2)
+		return -EINVAL;
+
+	res->name = node->name;
+	res->start = be32_to_cpup(values++);
+	res->end = be32_to_cpup(values);
+	res->flags = IORESOURCE_BUS;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/of/pdt.c linux-libre-3.11-rc7-gnu/drivers/of/pdt.c
--- linux-libre-3.10-gnu/drivers/of/pdt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/of/pdt.c	2013-08-25 20:43:22.000000000 -0400
@@ -251,6 +251,6 @@ void __init of_pdt_build_devicetree(phan
 	of_allnodes->child = of_pdt_build_tree(of_allnodes,
 			of_pdt_prom_ops->getchild(of_allnodes->phandle), &nextp);
 
-	/* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */
+	/* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
 	of_alias_scan(kernel_tree_alloc);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/oprofile/timer_int.c linux-libre-3.11-rc7-gnu/drivers/oprofile/timer_int.c
--- linux-libre-3.10-gnu/drivers/oprofile/timer_int.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/oprofile/timer_int.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,8 +74,8 @@ static void oprofile_hrtimer_stop(void)
 	put_online_cpus();
 }
 
-static int __cpuinit oprofile_cpu_notify(struct notifier_block *self,
-					 unsigned long action, void *hcpu)
+static int oprofile_cpu_notify(struct notifier_block *self,
+			       unsigned long action, void *hcpu)
 {
 	long cpu = (long) hcpu;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/parisc/eisa_eeprom.c linux-libre-3.11-rc7-gnu/drivers/parisc/eisa_eeprom.c
--- linux-libre-3.10-gnu/drivers/parisc/eisa_eeprom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/parisc/eisa_eeprom.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,20 +31,9 @@
 
 #define 	EISA_EEPROM_MINOR 241
 
-static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin )
+static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin)
 {
-	switch (origin) {
-	  case 0:
-		/* nothing to do */
-		break;
-	  case 1:
-		offset += file->f_pos;
-		break;
-	  case 2:
-		offset += HPEE_MAX_LENGTH;
-		break;
-	}
-	return (offset >= 0 && offset < HPEE_MAX_LENGTH) ? (file->f_pos = offset) : -EINVAL;
+	return fixed_size_llseek(file, offset, origin, HPEE_MAX_LENGTH);
 }
 
 static ssize_t eisa_eeprom_read(struct file * file,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/parisc/iosapic.c linux-libre-3.11-rc7-gnu/drivers/parisc/iosapic.c
--- linux-libre-3.10-gnu/drivers/parisc/iosapic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/parisc/iosapic.c	2013-08-25 20:43:22.000000000 -0400
@@ -811,18 +811,28 @@ int iosapic_fixup_irq(void *isi_obj, str
 	return pcidev->irq;
 }
 
-static struct iosapic_info *first_isi = NULL;
+static struct iosapic_info *iosapic_list;
 
 #ifdef CONFIG_64BIT
-int iosapic_serial_irq(int num)
+int iosapic_serial_irq(struct parisc_device *dev)
 {
-	struct iosapic_info *isi = first_isi;
-	struct irt_entry *irte = NULL;  /* only used if PAT PDC */
+	struct iosapic_info *isi;
+	struct irt_entry *irte;
 	struct vector_info *vi;
-	int isi_line;	/* line used by device */
+	int cnt;
+	int intin;
+
+	intin = (dev->mod_info >> 24) & 15;
 
 	/* lookup IRT entry for isi/slot/pin set */
-	irte = &irt_cell[num];
+	for (cnt = 0; cnt < irt_num_entry; cnt++) {
+		irte = &irt_cell[cnt];
+		if (COMPARE_IRTE_ADDR(irte, dev->mod0) &&
+		    irte->dest_iosapic_intin == intin)
+			break;
+	}
+	if (cnt >= irt_num_entry)
+		return 0; /* no irq found, force polling */
 
 	DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",
 		irte,
@@ -834,11 +844,17 @@ int iosapic_serial_irq(int num)
 		irte->src_seg_id,
 		irte->dest_iosapic_intin,
 		(u32) irte->dest_iosapic_addr);
-	isi_line = irte->dest_iosapic_intin;
+
+	/* search for iosapic */
+	for (isi = iosapic_list; isi; isi = isi->isi_next)
+		if (isi->isi_hpa == dev->mod0)
+			break;
+	if (!isi)
+		return 0; /* no iosapic found, force polling */
 
 	/* get vector info for this input line */
-	vi = isi->isi_vector + isi_line;
-	DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", isi_line, vi);
+	vi = isi->isi_vector + intin;
+	DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", iosapic_intin, vi);
 
 	/* If this IRQ line has already been setup, skip it */
 	if (vi->irte)
@@ -941,8 +957,8 @@ void *iosapic_register(unsigned long hpa
 		vip->irqline = (unsigned char) cnt;
 		vip->iosapic = isi;
 	}
-	if (!first_isi)
-		first_isi = isi;
+	isi->isi_next = iosapic_list;
+	iosapic_list = isi;
 	return isi;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/parisc/lba_pci.c linux-libre-3.11-rc7-gnu/drivers/parisc/lba_pci.c
--- linux-libre-3.10-gnu/drivers/parisc/lba_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/parisc/lba_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -613,6 +613,54 @@ truncate_pat_collision(struct resource *
 	return 0;	/* truncation successful */
 }
 
+/*
+ * extend_lmmio_len: extend lmmio range to maximum length
+ *
+ * This is needed at least on C8000 systems to get the ATI FireGL card
+ * working. On other systems we will currently not extend the lmmio space.
+ */
+static unsigned long
+extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len)
+{
+	struct resource *tmp;
+
+	pr_debug("LMMIO mismatch: PAT length = 0x%lx, MASK register = 0x%lx\n",
+		end - start, lba_len);
+
+	lba_len = min(lba_len+1, 256UL*1024*1024); /* limit to 256 MB */
+
+	pr_debug("LBA: lmmio_space [0x%lx-0x%lx] - original\n", start, end);
+
+	if (boot_cpu_data.cpu_type < mako) {
+		pr_info("LBA: Not a C8000 system - not extending LMMIO range.\n");
+		return end;
+	}
+
+	end += lba_len;
+	if (end < start) /* fix overflow */
+		end = -1ULL;
+
+	pr_debug("LBA: lmmio_space [0x%lx-0x%lx] - current\n", start, end);
+
+	/* first overlap */
+	for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) {
+		pr_debug("LBA: testing %pR\n", tmp);
+		if (tmp->start == start)
+			continue; /* ignore ourself */
+		if (tmp->end < start)
+			continue;
+		if (tmp->start > end)
+			continue;
+		if (end >= tmp->start)
+			end = tmp->start - 1;
+	}
+
+	pr_info("LBA: lmmio_space [0x%lx-0x%lx] - new\n", start, end);
+
+	/* return new end */
+	return end;
+}
+
 #else
 #define truncate_pat_collision(r,n)  (0)
 #endif
@@ -994,6 +1042,14 @@ lba_pat_resources(struct parisc_device *
 		case PAT_LMMIO:
 			/* used to fix up pre-initialized MEM BARs */
 			if (!lba_dev->hba.lmmio_space.flags) {
+				unsigned long lba_len;
+
+				lba_len = ~READ_REG32(lba_dev->hba.base_addr
+						+ LBA_LMMIO_MASK);
+				if ((p->end - p->start) != lba_len)
+					p->end = extend_lmmio_len(p->start,
+						p->end, lba_len);
+
 				sprintf(lba_dev->hba.lmmio_name,
 						"PCI%02x LMMIO",
 						(int)lba_dev->hba.bus_num.start);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/parport/Kconfig linux-libre-3.11-rc7-gnu/drivers/parport/Kconfig
--- linux-libre-3.10-gnu/drivers/parport/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/parport/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,9 @@ if PARPORT
 config PARPORT_PC
 	tristate "PC-style hardware"
 	depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && !S390 && \
-		(!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN && !XTENSA
+		(!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN && \
+		!XTENSA && !CRIS
+
 	---help---
 	  You should say Y here if you have a PC-style parallel port. All
 	  IBM PC compatible computers and some Alphas have PC-style
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/parport/share.c linux-libre-3.11-rc7-gnu/drivers/parport/share.c
--- linux-libre-3.10-gnu/drivers/parport/share.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/parport/share.c	2013-08-25 20:43:22.000000000 -0400
@@ -282,14 +282,13 @@ struct parport *parport_register_port(un
 	int device;
 	char *name;
 
-	tmp = kmalloc(sizeof(struct parport), GFP_KERNEL);
+	tmp = kzalloc(sizeof(struct parport), GFP_KERNEL);
 	if (!tmp) {
 		printk(KERN_WARNING "parport: memory squeeze\n");
 		return NULL;
 	}
 
 	/* Init our structure */
- 	memset(tmp, 0, sizeof(struct parport));
 	tmp->base = base;
 	tmp->irq = irq;
 	tmp->dma = dma;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/bus.c linux-libre-3.11-rc7-gnu/drivers/pci/bus.c
--- linux-libre-3.10-gnu/drivers/pci/bus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -283,6 +283,21 @@ void pci_walk_bus(struct pci_bus *top, i
 }
 EXPORT_SYMBOL_GPL(pci_walk_bus);
 
+struct pci_bus *pci_bus_get(struct pci_bus *bus)
+{
+	if (bus)
+		get_device(&bus->dev);
+	return bus;
+}
+EXPORT_SYMBOL(pci_bus_get);
+
+void pci_bus_put(struct pci_bus *bus)
+{
+	if (bus)
+		put_device(&bus->dev);
+}
+EXPORT_SYMBOL(pci_bus_put);
+
 EXPORT_SYMBOL(pci_bus_alloc_resource);
 EXPORT_SYMBOL_GPL(pci_bus_add_device);
 EXPORT_SYMBOL(pci_bus_add_devices);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/host/Kconfig linux-libre-3.11-rc7-gnu/drivers/pci/host/Kconfig
--- linux-libre-3.10-gnu/drivers/pci/host/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pci/host/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,17 @@
+menu "PCI host controller drivers"
+	depends on PCI
+
+config PCI_MVEBU
+	bool "Marvell EBU PCIe controller"
+	depends on ARCH_MVEBU || ARCH_KIRKWOOD
+
+config PCIE_DW
+	bool
+
+config PCI_EXYNOS
+	bool "Samsung Exynos PCIe controller"
+	depends on SOC_EXYNOS5440
+	select PCIEPORTBUS
+	select PCIE_DW
+
+endmenu
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/host/Makefile linux-libre-3.11-rc7-gnu/drivers/pci/host/Makefile
--- linux-libre-3.10-gnu/drivers/pci/host/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pci/host/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2 @@
+obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
+obj-$(CONFIG_PCIE_DW) += pcie-designware.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/host/pcie-designware.c linux-libre-3.11-rc7-gnu/drivers/pci/host/pcie-designware.c
--- linux-libre-3.10-gnu/drivers/pci/host/pcie-designware.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pci/host/pcie-designware.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1057 @@
+/*
+ * PCIe host controller driver for Samsung EXYNOS SoCs
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/pci_regs.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+struct pcie_port_info {
+	u32		cfg0_size;
+	u32		cfg1_size;
+	u32		io_size;
+	u32		mem_size;
+	phys_addr_t	io_bus_addr;
+	phys_addr_t	mem_bus_addr;
+};
+
+struct pcie_port {
+	struct device		*dev;
+	u8			controller;
+	u8			root_bus_nr;
+	void __iomem		*dbi_base;
+	void __iomem		*elbi_base;
+	void __iomem		*phy_base;
+	void __iomem		*purple_base;
+	u64			cfg0_base;
+	void __iomem		*va_cfg0_base;
+	u64			cfg1_base;
+	void __iomem		*va_cfg1_base;
+	u64			io_base;
+	u64			mem_base;
+	spinlock_t		conf_lock;
+	struct resource		cfg;
+	struct resource		io;
+	struct resource		mem;
+	struct pcie_port_info	config;
+	struct clk		*clk;
+	struct clk		*bus_clk;
+	int			irq;
+	int			reset_gpio;
+};
+
+/*
+ * Exynos PCIe IP consists of Synopsys specific part and Exynos
+ * specific part. Only core block is a Synopsys designware part;
+ * other parts are Exynos specific.
+ */
+
+/* Synopsis specific PCIE configuration registers */
+#define PCIE_PORT_LINK_CONTROL		0x710
+#define PORT_LINK_MODE_MASK		(0x3f << 16)
+#define PORT_LINK_MODE_4_LANES		(0x7 << 16)
+
+#define PCIE_LINK_WIDTH_SPEED_CONTROL	0x80C
+#define PORT_LOGIC_SPEED_CHANGE		(0x1 << 17)
+#define PORT_LOGIC_LINK_WIDTH_MASK	(0x1ff << 8)
+#define PORT_LOGIC_LINK_WIDTH_4_LANES	(0x7 << 8)
+
+#define PCIE_MSI_ADDR_LO		0x820
+#define PCIE_MSI_ADDR_HI		0x824
+#define PCIE_MSI_INTR0_ENABLE		0x828
+#define PCIE_MSI_INTR0_MASK		0x82C
+#define PCIE_MSI_INTR0_STATUS		0x830
+
+#define PCIE_ATU_VIEWPORT		0x900
+#define PCIE_ATU_REGION_INBOUND		(0x1 << 31)
+#define PCIE_ATU_REGION_OUTBOUND	(0x0 << 31)
+#define PCIE_ATU_REGION_INDEX1		(0x1 << 0)
+#define PCIE_ATU_REGION_INDEX0		(0x0 << 0)
+#define PCIE_ATU_CR1			0x904
+#define PCIE_ATU_TYPE_MEM		(0x0 << 0)
+#define PCIE_ATU_TYPE_IO		(0x2 << 0)
+#define PCIE_ATU_TYPE_CFG0		(0x4 << 0)
+#define PCIE_ATU_TYPE_CFG1		(0x5 << 0)
+#define PCIE_ATU_CR2			0x908
+#define PCIE_ATU_ENABLE			(0x1 << 31)
+#define PCIE_ATU_BAR_MODE_ENABLE	(0x1 << 30)
+#define PCIE_ATU_LOWER_BASE		0x90C
+#define PCIE_ATU_UPPER_BASE		0x910
+#define PCIE_ATU_LIMIT			0x914
+#define PCIE_ATU_LOWER_TARGET		0x918
+#define PCIE_ATU_BUS(x)			(((x) & 0xff) << 24)
+#define PCIE_ATU_DEV(x)			(((x) & 0x1f) << 19)
+#define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
+#define PCIE_ATU_UPPER_TARGET		0x91C
+
+/* Exynos specific PCIE configuration registers */
+
+/* PCIe ELBI registers */
+#define PCIE_IRQ_PULSE			0x000
+#define IRQ_INTA_ASSERT			(0x1 << 0)
+#define IRQ_INTB_ASSERT			(0x1 << 2)
+#define IRQ_INTC_ASSERT			(0x1 << 4)
+#define IRQ_INTD_ASSERT			(0x1 << 6)
+#define PCIE_IRQ_LEVEL			0x004
+#define PCIE_IRQ_SPECIAL		0x008
+#define PCIE_IRQ_EN_PULSE		0x00c
+#define PCIE_IRQ_EN_LEVEL		0x010
+#define PCIE_IRQ_EN_SPECIAL		0x014
+#define PCIE_PWR_RESET			0x018
+#define PCIE_CORE_RESET			0x01c
+#define PCIE_CORE_RESET_ENABLE		(0x1 << 0)
+#define PCIE_STICKY_RESET		0x020
+#define PCIE_NONSTICKY_RESET		0x024
+#define PCIE_APP_INIT_RESET		0x028
+#define PCIE_APP_LTSSM_ENABLE		0x02c
+#define PCIE_ELBI_RDLH_LINKUP		0x064
+#define PCIE_ELBI_LTSSM_ENABLE		0x1
+#define PCIE_ELBI_SLV_AWMISC		0x11c
+#define PCIE_ELBI_SLV_ARMISC		0x120
+#define PCIE_ELBI_SLV_DBI_ENABLE	(0x1 << 21)
+
+/* PCIe Purple registers */
+#define PCIE_PHY_GLOBAL_RESET		0x000
+#define PCIE_PHY_COMMON_RESET		0x004
+#define PCIE_PHY_CMN_REG		0x008
+#define PCIE_PHY_MAC_RESET		0x00c
+#define PCIE_PHY_PLL_LOCKED		0x010
+#define PCIE_PHY_TRSVREG_RESET		0x020
+#define PCIE_PHY_TRSV_RESET		0x024
+
+/* PCIe PHY registers */
+#define PCIE_PHY_IMPEDANCE		0x004
+#define PCIE_PHY_PLL_DIV_0		0x008
+#define PCIE_PHY_PLL_BIAS		0x00c
+#define PCIE_PHY_DCC_FEEDBACK		0x014
+#define PCIE_PHY_PLL_DIV_1		0x05c
+#define PCIE_PHY_TRSV0_EMP_LVL		0x084
+#define PCIE_PHY_TRSV0_DRV_LVL		0x088
+#define PCIE_PHY_TRSV0_RXCDR		0x0ac
+#define PCIE_PHY_TRSV0_LVCC		0x0dc
+#define PCIE_PHY_TRSV1_EMP_LVL		0x144
+#define PCIE_PHY_TRSV1_RXCDR		0x16c
+#define PCIE_PHY_TRSV1_LVCC		0x19c
+#define PCIE_PHY_TRSV2_EMP_LVL		0x204
+#define PCIE_PHY_TRSV2_RXCDR		0x22c
+#define PCIE_PHY_TRSV2_LVCC		0x25c
+#define PCIE_PHY_TRSV3_EMP_LVL		0x2c4
+#define PCIE_PHY_TRSV3_RXCDR		0x2ec
+#define PCIE_PHY_TRSV3_LVCC		0x31c
+
+static struct hw_pci exynos_pci;
+
+static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
+{
+	return sys->private_data;
+}
+
+static inline int cfg_read(void *addr, int where, int size, u32 *val)
+{
+	*val = readl(addr);
+
+	if (size == 1)
+		*val = (*val >> (8 * (where & 3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8 * (where & 3))) & 0xffff;
+	else if (size != 4)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int cfg_write(void *addr, int where, int size, u32 val)
+{
+	if (size == 4)
+		writel(val, addr);
+	else if (size == 2)
+		writew(val, addr + (where & 2));
+	else if (size == 1)
+		writeb(val, addr + (where & 3));
+	else
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void exynos_pcie_sideband_dbi_w_mode(struct pcie_port *pp, bool on)
+{
+	u32 val;
+
+	if (on) {
+		val = readl(pp->elbi_base + PCIE_ELBI_SLV_AWMISC);
+		val |= PCIE_ELBI_SLV_DBI_ENABLE;
+		writel(val, pp->elbi_base + PCIE_ELBI_SLV_AWMISC);
+	} else {
+		val = readl(pp->elbi_base + PCIE_ELBI_SLV_AWMISC);
+		val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
+		writel(val, pp->elbi_base + PCIE_ELBI_SLV_AWMISC);
+	}
+}
+
+static void exynos_pcie_sideband_dbi_r_mode(struct pcie_port *pp, bool on)
+{
+	u32 val;
+
+	if (on) {
+		val = readl(pp->elbi_base + PCIE_ELBI_SLV_ARMISC);
+		val |= PCIE_ELBI_SLV_DBI_ENABLE;
+		writel(val, pp->elbi_base + PCIE_ELBI_SLV_ARMISC);
+	} else {
+		val = readl(pp->elbi_base + PCIE_ELBI_SLV_ARMISC);
+		val &= ~PCIE_ELBI_SLV_DBI_ENABLE;
+		writel(val, pp->elbi_base + PCIE_ELBI_SLV_ARMISC);
+	}
+}
+
+static inline void readl_rc(struct pcie_port *pp, void *dbi_base, u32 *val)
+{
+	exynos_pcie_sideband_dbi_r_mode(pp, true);
+	*val = readl(dbi_base);
+	exynos_pcie_sideband_dbi_r_mode(pp, false);
+	return;
+}
+
+static inline void writel_rc(struct pcie_port *pp, u32 val, void *dbi_base)
+{
+	exynos_pcie_sideband_dbi_w_mode(pp, true);
+	writel(val, dbi_base);
+	exynos_pcie_sideband_dbi_w_mode(pp, false);
+	return;
+}
+
+static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
+				u32 *val)
+{
+	int ret;
+
+	exynos_pcie_sideband_dbi_r_mode(pp, true);
+	ret = cfg_read(pp->dbi_base + (where & ~0x3), where, size, val);
+	exynos_pcie_sideband_dbi_r_mode(pp, false);
+	return ret;
+}
+
+static int exynos_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
+				u32 val)
+{
+	int ret;
+
+	exynos_pcie_sideband_dbi_w_mode(pp, true);
+	ret = cfg_write(pp->dbi_base + (where & ~0x3), where, size, val);
+	exynos_pcie_sideband_dbi_w_mode(pp, false);
+	return ret;
+}
+
+static void exynos_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev)
+{
+	u32 val;
+	void __iomem *dbi_base = pp->dbi_base;
+
+	/* Program viewport 0 : OUTBOUND : CFG0 */
+	val = PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0;
+	writel_rc(pp, val, dbi_base + PCIE_ATU_VIEWPORT);
+	writel_rc(pp, pp->cfg0_base, dbi_base + PCIE_ATU_LOWER_BASE);
+	writel_rc(pp, (pp->cfg0_base >> 32), dbi_base + PCIE_ATU_UPPER_BASE);
+	writel_rc(pp, pp->cfg0_base + pp->config.cfg0_size - 1,
+			dbi_base + PCIE_ATU_LIMIT);
+	writel_rc(pp, busdev, dbi_base + PCIE_ATU_LOWER_TARGET);
+	writel_rc(pp, 0, dbi_base + PCIE_ATU_UPPER_TARGET);
+	writel_rc(pp, PCIE_ATU_TYPE_CFG0, dbi_base + PCIE_ATU_CR1);
+	val = PCIE_ATU_ENABLE;
+	writel_rc(pp, val, dbi_base + PCIE_ATU_CR2);
+}
+
+static void exynos_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev)
+{
+	u32 val;
+	void __iomem *dbi_base = pp->dbi_base;
+
+	/* Program viewport 1 : OUTBOUND : CFG1 */
+	val = PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1;
+	writel_rc(pp, val, dbi_base + PCIE_ATU_VIEWPORT);
+	writel_rc(pp, PCIE_ATU_TYPE_CFG1, dbi_base + PCIE_ATU_CR1);
+	val = PCIE_ATU_ENABLE;
+	writel_rc(pp, val, dbi_base + PCIE_ATU_CR2);
+	writel_rc(pp, pp->cfg1_base, dbi_base + PCIE_ATU_LOWER_BASE);
+	writel_rc(pp, (pp->cfg1_base >> 32), dbi_base + PCIE_ATU_UPPER_BASE);
+	writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1,
+			dbi_base + PCIE_ATU_LIMIT);
+	writel_rc(pp, busdev, dbi_base + PCIE_ATU_LOWER_TARGET);
+	writel_rc(pp, 0, dbi_base + PCIE_ATU_UPPER_TARGET);
+}
+
+static void exynos_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
+{
+	u32 val;
+	void __iomem *dbi_base = pp->dbi_base;
+
+	/* Program viewport 0 : OUTBOUND : MEM */
+	val = PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0;
+	writel_rc(pp, val, dbi_base + PCIE_ATU_VIEWPORT);
+	writel_rc(pp, PCIE_ATU_TYPE_MEM, dbi_base + PCIE_ATU_CR1);
+	val = PCIE_ATU_ENABLE;
+	writel_rc(pp, val, dbi_base + PCIE_ATU_CR2);
+	writel_rc(pp, pp->mem_base, dbi_base + PCIE_ATU_LOWER_BASE);
+	writel_rc(pp, (pp->mem_base >> 32), dbi_base + PCIE_ATU_UPPER_BASE);
+	writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
+			dbi_base + PCIE_ATU_LIMIT);
+	writel_rc(pp, pp->config.mem_bus_addr,
+			dbi_base + PCIE_ATU_LOWER_TARGET);
+	writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
+			dbi_base + PCIE_ATU_UPPER_TARGET);
+}
+
+static void exynos_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
+{
+	u32 val;
+	void __iomem *dbi_base = pp->dbi_base;
+
+	/* Program viewport 1 : OUTBOUND : IO */
+	val = PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1;
+	writel_rc(pp, val, dbi_base + PCIE_ATU_VIEWPORT);
+	writel_rc(pp, PCIE_ATU_TYPE_IO, dbi_base + PCIE_ATU_CR1);
+	val = PCIE_ATU_ENABLE;
+	writel_rc(pp, val, dbi_base + PCIE_ATU_CR2);
+	writel_rc(pp, pp->io_base, dbi_base + PCIE_ATU_LOWER_BASE);
+	writel_rc(pp, (pp->io_base >> 32), dbi_base + PCIE_ATU_UPPER_BASE);
+	writel_rc(pp, pp->io_base + pp->config.io_size - 1,
+			dbi_base + PCIE_ATU_LIMIT);
+	writel_rc(pp, pp->config.io_bus_addr,
+			dbi_base + PCIE_ATU_LOWER_TARGET);
+	writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
+			dbi_base + PCIE_ATU_UPPER_TARGET);
+}
+
+static int exynos_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
+		u32 devfn, int where, int size, u32 *val)
+{
+	int ret = PCIBIOS_SUCCESSFUL;
+	u32 address, busdev;
+
+	busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
+		 PCIE_ATU_FUNC(PCI_FUNC(devfn));
+	address = where & ~0x3;
+
+	if (bus->parent->number == pp->root_bus_nr) {
+		exynos_pcie_prog_viewport_cfg0(pp, busdev);
+		ret = cfg_read(pp->va_cfg0_base + address, where, size, val);
+		exynos_pcie_prog_viewport_mem_outbound(pp);
+	} else {
+		exynos_pcie_prog_viewport_cfg1(pp, busdev);
+		ret = cfg_read(pp->va_cfg1_base + address, where, size, val);
+		exynos_pcie_prog_viewport_io_outbound(pp);
+	}
+
+	return ret;
+}
+
+static int exynos_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
+		u32 devfn, int where, int size, u32 val)
+{
+	int ret = PCIBIOS_SUCCESSFUL;
+	u32 address, busdev;
+
+	busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
+		 PCIE_ATU_FUNC(PCI_FUNC(devfn));
+	address = where & ~0x3;
+
+	if (bus->parent->number == pp->root_bus_nr) {
+		exynos_pcie_prog_viewport_cfg0(pp, busdev);
+		ret = cfg_write(pp->va_cfg0_base + address, where, size, val);
+		exynos_pcie_prog_viewport_mem_outbound(pp);
+	} else {
+		exynos_pcie_prog_viewport_cfg1(pp, busdev);
+		ret = cfg_write(pp->va_cfg1_base + address, where, size, val);
+		exynos_pcie_prog_viewport_io_outbound(pp);
+	}
+
+	return ret;
+}
+
+static unsigned long global_io_offset;
+
+static int exynos_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+	struct pcie_port *pp;
+
+	pp = sys_to_pcie(sys);
+
+	if (!pp)
+		return 0;
+
+	if (global_io_offset < SZ_1M && pp->config.io_size > 0) {
+		sys->io_offset = global_io_offset - pp->config.io_bus_addr;
+		pci_ioremap_io(sys->io_offset, pp->io.start);
+		global_io_offset += SZ_64K;
+		pci_add_resource_offset(&sys->resources, &pp->io,
+					sys->io_offset);
+	}
+
+	sys->mem_offset = pp->mem.start - pp->config.mem_bus_addr;
+	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
+
+	return 1;
+}
+
+static int exynos_pcie_link_up(struct pcie_port *pp)
+{
+	u32 val = readl(pp->elbi_base + PCIE_ELBI_RDLH_LINKUP);
+
+	if (val == PCIE_ELBI_LTSSM_ENABLE)
+		return 1;
+
+	return 0;
+}
+
+static int exynos_pcie_valid_config(struct pcie_port *pp,
+				struct pci_bus *bus, int dev)
+{
+	/* If there is no link, then there is no device */
+	if (bus->number != pp->root_bus_nr) {
+		if (!exynos_pcie_link_up(pp))
+			return 0;
+	}
+
+	/* access only one slot on each root port */
+	if (bus->number == pp->root_bus_nr && dev > 0)
+		return 0;
+
+	/*
+	 * do not read more than one device on the bus directly attached
+	 * to RC's (Virtual Bridge's) DS side.
+	 */
+	if (bus->primary == pp->root_bus_nr && dev > 0)
+		return 0;
+
+	return 1;
+}
+
+static int exynos_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+			int size, u32 *val)
+{
+	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	unsigned long flags;
+	int ret;
+
+	if (!pp) {
+		BUG();
+		return -EINVAL;
+	}
+
+	if (exynos_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	spin_lock_irqsave(&pp->conf_lock, flags);
+	if (bus->number != pp->root_bus_nr)
+		ret = exynos_pcie_rd_other_conf(pp, bus, devfn,
+						where, size, val);
+	else
+		ret = exynos_pcie_rd_own_conf(pp, where, size, val);
+	spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+	return ret;
+}
+
+static int exynos_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+			int where, int size, u32 val)
+{
+	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	unsigned long flags;
+	int ret;
+
+	if (!pp) {
+		BUG();
+		return -EINVAL;
+	}
+
+	if (exynos_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	spin_lock_irqsave(&pp->conf_lock, flags);
+	if (bus->number != pp->root_bus_nr)
+		ret = exynos_pcie_wr_other_conf(pp, bus, devfn,
+						where, size, val);
+	else
+		ret = exynos_pcie_wr_own_conf(pp, where, size, val);
+	spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+	return ret;
+}
+
+static struct pci_ops exynos_pcie_ops = {
+	.read = exynos_pcie_rd_conf,
+	.write = exynos_pcie_wr_conf,
+};
+
+static struct pci_bus *exynos_pcie_scan_bus(int nr,
+					struct pci_sys_data *sys)
+{
+	struct pci_bus *bus;
+	struct pcie_port *pp = sys_to_pcie(sys);
+
+	if (pp) {
+		pp->root_bus_nr = sys->busnr;
+		bus = pci_scan_root_bus(NULL, sys->busnr, &exynos_pcie_ops,
+					sys, &sys->resources);
+	} else {
+		bus = NULL;
+		BUG();
+	}
+
+	return bus;
+}
+
+static int exynos_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
+
+	return pp->irq;
+}
+
+static struct hw_pci exynos_pci = {
+	.setup		= exynos_pcie_setup,
+	.scan		= exynos_pcie_scan_bus,
+	.map_irq	= exynos_pcie_map_irq,
+};
+
+static void exynos_pcie_setup_rc(struct pcie_port *pp)
+{
+	struct pcie_port_info *config = &pp->config;
+	void __iomem *dbi_base = pp->dbi_base;
+	u32 val;
+	u32 membase;
+	u32 memlimit;
+
+	/* set the number of lines as 4 */
+	readl_rc(pp, dbi_base + PCIE_PORT_LINK_CONTROL, &val);
+	val &= ~PORT_LINK_MODE_MASK;
+	val |= PORT_LINK_MODE_4_LANES;
+	writel_rc(pp, val, dbi_base + PCIE_PORT_LINK_CONTROL);
+
+	/* set link width speed control register */
+	readl_rc(pp, dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL, &val);
+	val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
+	val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
+	writel_rc(pp, val, dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
+
+	/* setup RC BARs */
+	writel_rc(pp, 0x00000004, dbi_base + PCI_BASE_ADDRESS_0);
+	writel_rc(pp, 0x00000004, dbi_base + PCI_BASE_ADDRESS_1);
+
+	/* setup interrupt pins */
+	readl_rc(pp, dbi_base + PCI_INTERRUPT_LINE, &val);
+	val &= 0xffff00ff;
+	val |= 0x00000100;
+	writel_rc(pp, val, dbi_base + PCI_INTERRUPT_LINE);
+
+	/* setup bus numbers */
+	readl_rc(pp, dbi_base + PCI_PRIMARY_BUS, &val);
+	val &= 0xff000000;
+	val |= 0x00010100;
+	writel_rc(pp, val, dbi_base + PCI_PRIMARY_BUS);
+
+	/* setup memory base, memory limit */
+	membase = ((u32)pp->mem_base & 0xfff00000) >> 16;
+	memlimit = (config->mem_size + (u32)pp->mem_base) & 0xfff00000;
+	val = memlimit | membase;
+	writel_rc(pp, val, dbi_base + PCI_MEMORY_BASE);
+
+	/* setup command register */
+	readl_rc(pp, dbi_base + PCI_COMMAND, &val);
+	val &= 0xffff0000;
+	val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
+	writel_rc(pp, val, dbi_base + PCI_COMMAND);
+}
+
+static void exynos_pcie_assert_core_reset(struct pcie_port *pp)
+{
+	u32 val;
+	void __iomem *elbi_base = pp->elbi_base;
+
+	val = readl(elbi_base + PCIE_CORE_RESET);
+	val &= ~PCIE_CORE_RESET_ENABLE;
+	writel(val, elbi_base + PCIE_CORE_RESET);
+	writel(0, elbi_base + PCIE_PWR_RESET);
+	writel(0, elbi_base + PCIE_STICKY_RESET);
+	writel(0, elbi_base + PCIE_NONSTICKY_RESET);
+}
+
+static void exynos_pcie_deassert_core_reset(struct pcie_port *pp)
+{
+	u32 val;
+	void __iomem *elbi_base = pp->elbi_base;
+	void __iomem *purple_base = pp->purple_base;
+
+	val = readl(elbi_base + PCIE_CORE_RESET);
+	val |= PCIE_CORE_RESET_ENABLE;
+	writel(val, elbi_base + PCIE_CORE_RESET);
+	writel(1, elbi_base + PCIE_STICKY_RESET);
+	writel(1, elbi_base + PCIE_NONSTICKY_RESET);
+	writel(1, elbi_base + PCIE_APP_INIT_RESET);
+	writel(0, elbi_base + PCIE_APP_INIT_RESET);
+	writel(1, purple_base + PCIE_PHY_MAC_RESET);
+}
+
+static void exynos_pcie_assert_phy_reset(struct pcie_port *pp)
+{
+	void __iomem *purple_base = pp->purple_base;
+
+	writel(0, purple_base + PCIE_PHY_MAC_RESET);
+	writel(1, purple_base + PCIE_PHY_GLOBAL_RESET);
+}
+
+static void exynos_pcie_deassert_phy_reset(struct pcie_port *pp)
+{
+	void __iomem *elbi_base = pp->elbi_base;
+	void __iomem *purple_base = pp->purple_base;
+
+	writel(0, purple_base + PCIE_PHY_GLOBAL_RESET);
+	writel(1, elbi_base + PCIE_PWR_RESET);
+	writel(0, purple_base + PCIE_PHY_COMMON_RESET);
+	writel(0, purple_base + PCIE_PHY_CMN_REG);
+	writel(0, purple_base + PCIE_PHY_TRSVREG_RESET);
+	writel(0, purple_base + PCIE_PHY_TRSV_RESET);
+}
+
+static void exynos_pcie_init_phy(struct pcie_port *pp)
+{
+	void __iomem *phy_base = pp->phy_base;
+
+	/* DCC feedback control off */
+	writel(0x29, phy_base + PCIE_PHY_DCC_FEEDBACK);
+
+	/* set TX/RX impedance */
+	writel(0xd5, phy_base + PCIE_PHY_IMPEDANCE);
+
+	/* set 50Mhz PHY clock */
+	writel(0x14, phy_base + PCIE_PHY_PLL_DIV_0);
+	writel(0x12, phy_base + PCIE_PHY_PLL_DIV_1);
+
+	/* set TX Differential output for lane 0 */
+	writel(0x7f, phy_base + PCIE_PHY_TRSV0_DRV_LVL);
+
+	/* set TX Pre-emphasis Level Control for lane 0 to minimum */
+	writel(0x0, phy_base + PCIE_PHY_TRSV0_EMP_LVL);
+
+	/* set RX clock and data recovery bandwidth */
+	writel(0xe7, phy_base + PCIE_PHY_PLL_BIAS);
+	writel(0x82, phy_base + PCIE_PHY_TRSV0_RXCDR);
+	writel(0x82, phy_base + PCIE_PHY_TRSV1_RXCDR);
+	writel(0x82, phy_base + PCIE_PHY_TRSV2_RXCDR);
+	writel(0x82, phy_base + PCIE_PHY_TRSV3_RXCDR);
+
+	/* change TX Pre-emphasis Level Control for lanes */
+	writel(0x39, phy_base + PCIE_PHY_TRSV0_EMP_LVL);
+	writel(0x39, phy_base + PCIE_PHY_TRSV1_EMP_LVL);
+	writel(0x39, phy_base + PCIE_PHY_TRSV2_EMP_LVL);
+	writel(0x39, phy_base + PCIE_PHY_TRSV3_EMP_LVL);
+
+	/* set LVCC */
+	writel(0x20, phy_base + PCIE_PHY_TRSV0_LVCC);
+	writel(0xa0, phy_base + PCIE_PHY_TRSV1_LVCC);
+	writel(0xa0, phy_base + PCIE_PHY_TRSV2_LVCC);
+	writel(0xa0, phy_base + PCIE_PHY_TRSV3_LVCC);
+}
+
+static void exynos_pcie_assert_reset(struct pcie_port *pp)
+{
+	if (pp->reset_gpio >= 0)
+		devm_gpio_request_one(pp->dev, pp->reset_gpio,
+				GPIOF_OUT_INIT_HIGH, "RESET");
+	return;
+}
+
+static int exynos_pcie_establish_link(struct pcie_port *pp)
+{
+	u32 val;
+	int count = 0;
+	void __iomem *elbi_base = pp->elbi_base;
+	void __iomem *purple_base = pp->purple_base;
+	void __iomem *phy_base = pp->phy_base;
+
+	if (exynos_pcie_link_up(pp)) {
+		dev_err(pp->dev, "Link already up\n");
+		return 0;
+	}
+
+	/* assert reset signals */
+	exynos_pcie_assert_core_reset(pp);
+	exynos_pcie_assert_phy_reset(pp);
+
+	/* de-assert phy reset */
+	exynos_pcie_deassert_phy_reset(pp);
+
+	/* initialize phy */
+	exynos_pcie_init_phy(pp);
+
+	/* pulse for common reset */
+	writel(1, purple_base + PCIE_PHY_COMMON_RESET);
+	udelay(500);
+	writel(0, purple_base + PCIE_PHY_COMMON_RESET);
+
+	/* de-assert core reset */
+	exynos_pcie_deassert_core_reset(pp);
+
+	/* setup root complex */
+	exynos_pcie_setup_rc(pp);
+
+	/* assert reset signal */
+	exynos_pcie_assert_reset(pp);
+
+	/* assert LTSSM enable */
+	writel(PCIE_ELBI_LTSSM_ENABLE, elbi_base + PCIE_APP_LTSSM_ENABLE);
+
+	/* check if the link is up or not */
+	while (!exynos_pcie_link_up(pp)) {
+		mdelay(100);
+		count++;
+		if (count == 10) {
+			while (readl(phy_base + PCIE_PHY_PLL_LOCKED) == 0) {
+				val = readl(purple_base + PCIE_PHY_PLL_LOCKED);
+				dev_info(pp->dev, "PLL Locked: 0x%x\n", val);
+			}
+			dev_err(pp->dev, "PCIe Link Fail\n");
+			return -EINVAL;
+		}
+	}
+
+	dev_info(pp->dev, "Link up\n");
+
+	return 0;
+}
+
+static void exynos_pcie_clear_irq_pulse(struct pcie_port *pp)
+{
+	u32 val;
+	void __iomem *elbi_base = pp->elbi_base;
+
+	val = readl(elbi_base + PCIE_IRQ_PULSE);
+	writel(val, elbi_base + PCIE_IRQ_PULSE);
+	return;
+}
+
+static void exynos_pcie_enable_irq_pulse(struct pcie_port *pp)
+{
+	u32 val;
+	void __iomem *elbi_base = pp->elbi_base;
+
+	/* enable INTX interrupt */
+	val = IRQ_INTA_ASSERT | IRQ_INTB_ASSERT |
+		IRQ_INTC_ASSERT | IRQ_INTD_ASSERT,
+	writel(val, elbi_base + PCIE_IRQ_EN_PULSE);
+	return;
+}
+
+static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
+{
+	struct pcie_port *pp = arg;
+
+	exynos_pcie_clear_irq_pulse(pp);
+	return IRQ_HANDLED;
+}
+
+static void exynos_pcie_enable_interrupts(struct pcie_port *pp)
+{
+	exynos_pcie_enable_irq_pulse(pp);
+	return;
+}
+
+static void exynos_pcie_host_init(struct pcie_port *pp)
+{
+	struct pcie_port_info *config = &pp->config;
+	u32 val;
+
+	/* Keep first 64K for IO */
+	pp->cfg0_base = pp->cfg.start;
+	pp->cfg1_base = pp->cfg.start + config->cfg0_size;
+	pp->io_base = pp->io.start;
+	pp->mem_base = pp->mem.start;
+
+	/* enable link */
+	exynos_pcie_establish_link(pp);
+
+	exynos_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
+
+	/* program correct class for RC */
+	exynos_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI);
+
+	exynos_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val);
+	val |= PORT_LOGIC_SPEED_CHANGE;
+	exynos_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
+
+	exynos_pcie_enable_interrupts(pp);
+}
+
+static int add_pcie_port(struct pcie_port *pp, struct platform_device *pdev)
+{
+	struct resource *elbi_base;
+	struct resource *phy_base;
+	struct resource *purple_base;
+	int ret;
+
+	elbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!elbi_base) {
+		dev_err(&pdev->dev, "couldn't get elbi base resource\n");
+		return -EINVAL;
+	}
+	pp->elbi_base = devm_ioremap_resource(&pdev->dev, elbi_base);
+	if (IS_ERR(pp->elbi_base))
+		return PTR_ERR(pp->elbi_base);
+
+	phy_base = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!phy_base) {
+		dev_err(&pdev->dev, "couldn't get phy base resource\n");
+		return -EINVAL;
+	}
+	pp->phy_base = devm_ioremap_resource(&pdev->dev, phy_base);
+	if (IS_ERR(pp->phy_base))
+		return PTR_ERR(pp->phy_base);
+
+	purple_base = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	if (!purple_base) {
+		dev_err(&pdev->dev, "couldn't get purple base resource\n");
+		return -EINVAL;
+	}
+	pp->purple_base = devm_ioremap_resource(&pdev->dev, purple_base);
+	if (IS_ERR(pp->purple_base))
+		return PTR_ERR(pp->purple_base);
+
+	pp->irq = platform_get_irq(pdev, 1);
+	if (!pp->irq) {
+		dev_err(&pdev->dev, "failed to get irq\n");
+		return -ENODEV;
+	}
+	ret = devm_request_irq(&pdev->dev, pp->irq, exynos_pcie_irq_handler,
+				IRQF_SHARED, "exynos-pcie", pp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request irq\n");
+		return ret;
+	}
+
+	pp->dbi_base = devm_ioremap(&pdev->dev, pp->cfg.start,
+				resource_size(&pp->cfg));
+	if (!pp->dbi_base) {
+		dev_err(&pdev->dev, "error with ioremap\n");
+		return -ENOMEM;
+	}
+
+	pp->root_bus_nr = -1;
+
+	spin_lock_init(&pp->conf_lock);
+	exynos_pcie_host_init(pp);
+	pp->va_cfg0_base = devm_ioremap(&pdev->dev, pp->cfg0_base,
+					pp->config.cfg0_size);
+	if (!pp->va_cfg0_base) {
+		dev_err(pp->dev, "error with ioremap in function\n");
+		return -ENOMEM;
+	}
+	pp->va_cfg1_base = devm_ioremap(&pdev->dev, pp->cfg1_base,
+					pp->config.cfg1_size);
+	if (!pp->va_cfg1_base) {
+		dev_err(pp->dev, "error with ioremap\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int __init exynos_pcie_probe(struct platform_device *pdev)
+{
+	struct pcie_port *pp;
+	struct device_node *np = pdev->dev.of_node;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	int ret;
+
+	pp = devm_kzalloc(&pdev->dev, sizeof(*pp), GFP_KERNEL);
+	if (!pp) {
+		dev_err(&pdev->dev, "no memory for pcie port\n");
+		return -ENOMEM;
+	}
+
+	pp->dev = &pdev->dev;
+
+	if (of_pci_range_parser_init(&parser, np)) {
+		dev_err(&pdev->dev, "missing ranges property\n");
+		return -EINVAL;
+	}
+
+	/* Get the I/O and memory ranges from DT */
+	for_each_of_pci_range(&parser, &range) {
+		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
+		if (restype == IORESOURCE_IO) {
+			of_pci_range_to_resource(&range, np, &pp->io);
+			pp->io.name = "I/O";
+			pp->io.start = max_t(resource_size_t,
+					     PCIBIOS_MIN_IO,
+					     range.pci_addr + global_io_offset);
+			pp->io.end = min_t(resource_size_t,
+					   IO_SPACE_LIMIT,
+					   range.pci_addr + range.size
+					   + global_io_offset);
+			pp->config.io_size = resource_size(&pp->io);
+			pp->config.io_bus_addr = range.pci_addr;
+		}
+		if (restype == IORESOURCE_MEM) {
+			of_pci_range_to_resource(&range, np, &pp->mem);
+			pp->mem.name = "MEM";
+			pp->config.mem_size = resource_size(&pp->mem);
+			pp->config.mem_bus_addr = range.pci_addr;
+		}
+		if (restype == 0) {
+			of_pci_range_to_resource(&range, np, &pp->cfg);
+			pp->config.cfg0_size = resource_size(&pp->cfg)/2;
+			pp->config.cfg1_size = resource_size(&pp->cfg)/2;
+		}
+	}
+
+	pp->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
+
+	pp->clk = devm_clk_get(&pdev->dev, "pcie");
+	if (IS_ERR(pp->clk)) {
+		dev_err(&pdev->dev, "Failed to get pcie rc clock\n");
+		return PTR_ERR(pp->clk);
+	}
+	ret = clk_prepare_enable(pp->clk);
+	if (ret)
+		return ret;
+
+	pp->bus_clk = devm_clk_get(&pdev->dev, "pcie_bus");
+	if (IS_ERR(pp->bus_clk)) {
+		dev_err(&pdev->dev, "Failed to get pcie bus clock\n");
+		ret = PTR_ERR(pp->bus_clk);
+		goto fail_clk;
+	}
+	ret = clk_prepare_enable(pp->bus_clk);
+	if (ret)
+		goto fail_clk;
+
+	ret = add_pcie_port(pp, pdev);
+	if (ret < 0)
+		goto fail_bus_clk;
+
+	pp->controller = exynos_pci.nr_controllers;
+	exynos_pci.nr_controllers = 1;
+	exynos_pci.private_data = (void **)&pp;
+
+	pci_common_init(&exynos_pci);
+	pci_assign_unassigned_resources();
+#ifdef CONFIG_PCI_DOMAINS
+	exynos_pci.domain++;
+#endif
+
+	platform_set_drvdata(pdev, pp);
+	return 0;
+
+fail_bus_clk:
+	clk_disable_unprepare(pp->bus_clk);
+fail_clk:
+	clk_disable_unprepare(pp->clk);
+	return ret;
+}
+
+static int __exit exynos_pcie_remove(struct platform_device *pdev)
+{
+	struct pcie_port *pp = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(pp->bus_clk);
+	clk_disable_unprepare(pp->clk);
+
+	return 0;
+}
+
+static const struct of_device_id exynos_pcie_of_match[] = {
+	{ .compatible = "samsung,exynos5440-pcie", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos_pcie_of_match);
+
+static struct platform_driver exynos_pcie_driver = {
+	.remove		= __exit_p(exynos_pcie_remove),
+	.driver = {
+		.name	= "exynos-pcie",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(exynos_pcie_of_match),
+	},
+};
+
+static int exynos_pcie_abort(unsigned long addr, unsigned int fsr,
+			struct pt_regs *regs)
+{
+	unsigned long pc = instruction_pointer(regs);
+	unsigned long instr = *(unsigned long *)pc;
+
+	WARN_ONCE(1, "pcie abort\n");
+
+	/*
+	 * If the instruction being executed was a read,
+	 * make it look like it read all-ones.
+	 */
+	if ((instr & 0x0c100000) == 0x04100000) {
+		int reg = (instr >> 12) & 15;
+		unsigned long val;
+
+		if (instr & 0x00400000)
+			val = 255;
+		else
+			val = -1;
+
+		regs->uregs[reg] = val;
+		regs->ARM_pc += 4;
+		return 0;
+	}
+
+	if ((instr & 0x0e100090) == 0x00100090) {
+		int reg = (instr >> 12) & 15;
+
+		regs->uregs[reg] = -1;
+		regs->ARM_pc += 4;
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Exynos PCIe driver does not allow module unload */
+
+static int __init pcie_init(void)
+{
+	hook_fault_code(16 + 6, exynos_pcie_abort, SIGBUS, 0,
+			"imprecise external abort");
+
+	platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe);
+
+	return 0;
+}
+subsys_initcall(pcie_init);
+
+MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_DESCRIPTION("Samsung PCIe host controller driver");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/host/pci-mvebu.c linux-libre-3.11-rc7-gnu/drivers/pci/host/pci-mvebu.c
--- linux-libre-3.10-gnu/drivers/pci/host/pci-mvebu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pci/host/pci-mvebu.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,889 @@
+/*
+ * PCIe driver for Marvell Armada 370 and Armada XP SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/mbus.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+/*
+ * PCIe unit register offsets.
+ */
+#define PCIE_DEV_ID_OFF		0x0000
+#define PCIE_CMD_OFF		0x0004
+#define PCIE_DEV_REV_OFF	0x0008
+#define PCIE_BAR_LO_OFF(n)	(0x0010 + ((n) << 3))
+#define PCIE_BAR_HI_OFF(n)	(0x0014 + ((n) << 3))
+#define PCIE_HEADER_LOG_4_OFF	0x0128
+#define PCIE_BAR_CTRL_OFF(n)	(0x1804 + (((n) - 1) * 4))
+#define PCIE_WIN04_CTRL_OFF(n)	(0x1820 + ((n) << 4))
+#define PCIE_WIN04_BASE_OFF(n)	(0x1824 + ((n) << 4))
+#define PCIE_WIN04_REMAP_OFF(n)	(0x182c + ((n) << 4))
+#define PCIE_WIN5_CTRL_OFF	0x1880
+#define PCIE_WIN5_BASE_OFF	0x1884
+#define PCIE_WIN5_REMAP_OFF	0x188c
+#define PCIE_CONF_ADDR_OFF	0x18f8
+#define  PCIE_CONF_ADDR_EN		0x80000000
+#define  PCIE_CONF_REG(r)		((((r) & 0xf00) << 16) | ((r) & 0xfc))
+#define  PCIE_CONF_BUS(b)		(((b) & 0xff) << 16)
+#define  PCIE_CONF_DEV(d)		(((d) & 0x1f) << 11)
+#define  PCIE_CONF_FUNC(f)		(((f) & 0x7) << 8)
+#define  PCIE_CONF_ADDR(bus, devfn, where) \
+	(PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn))    | \
+	 PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where) | \
+	 PCIE_CONF_ADDR_EN)
+#define PCIE_CONF_DATA_OFF	0x18fc
+#define PCIE_MASK_OFF		0x1910
+#define  PCIE_MASK_ENABLE_INTS          0x0f000000
+#define PCIE_CTRL_OFF		0x1a00
+#define  PCIE_CTRL_X1_MODE		0x0001
+#define PCIE_STAT_OFF		0x1a04
+#define  PCIE_STAT_BUS                  0xff00
+#define  PCIE_STAT_DEV                  0x1f0000
+#define  PCIE_STAT_LINK_DOWN		BIT(0)
+#define PCIE_DEBUG_CTRL         0x1a60
+#define  PCIE_DEBUG_SOFT_RESET		BIT(20)
+
+/*
+ * This product ID is registered by Marvell, and used when the Marvell
+ * SoC is not the root complex, but an endpoint on the PCIe bus. It is
+ * therefore safe to re-use this PCI ID for our emulated PCI-to-PCI
+ * bridge.
+ */
+#define MARVELL_EMULATED_PCI_PCI_BRIDGE_ID 0x7846
+
+/* PCI configuration space of a PCI-to-PCI bridge */
+struct mvebu_sw_pci_bridge {
+	u16 vendor;
+	u16 device;
+	u16 command;
+	u16 class;
+	u8 interface;
+	u8 revision;
+	u8 bist;
+	u8 header_type;
+	u8 latency_timer;
+	u8 cache_line_size;
+	u32 bar[2];
+	u8 primary_bus;
+	u8 secondary_bus;
+	u8 subordinate_bus;
+	u8 secondary_latency_timer;
+	u8 iobase;
+	u8 iolimit;
+	u16 secondary_status;
+	u16 membase;
+	u16 memlimit;
+	u16 iobaseupper;
+	u16 iolimitupper;
+	u8 cappointer;
+	u8 reserved1;
+	u16 reserved2;
+	u32 romaddr;
+	u8 intline;
+	u8 intpin;
+	u16 bridgectrl;
+};
+
+struct mvebu_pcie_port;
+
+/* Structure representing all PCIe interfaces */
+struct mvebu_pcie {
+	struct platform_device *pdev;
+	struct mvebu_pcie_port *ports;
+	struct resource io;
+	struct resource realio;
+	struct resource mem;
+	struct resource busn;
+	int nports;
+};
+
+/* Structure representing one PCIe interface */
+struct mvebu_pcie_port {
+	char *name;
+	void __iomem *base;
+	spinlock_t conf_lock;
+	int haslink;
+	u32 port;
+	u32 lane;
+	int devfn;
+	struct clk *clk;
+	struct mvebu_sw_pci_bridge bridge;
+	struct device_node *dn;
+	struct mvebu_pcie *pcie;
+	phys_addr_t memwin_base;
+	size_t memwin_size;
+	phys_addr_t iowin_base;
+	size_t iowin_size;
+};
+
+static bool mvebu_pcie_link_up(struct mvebu_pcie_port *port)
+{
+	return !(readl(port->base + PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN);
+}
+
+static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie_port *port, int nr)
+{
+	u32 stat;
+
+	stat = readl(port->base + PCIE_STAT_OFF);
+	stat &= ~PCIE_STAT_BUS;
+	stat |= nr << 8;
+	writel(stat, port->base + PCIE_STAT_OFF);
+}
+
+static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
+{
+	u32 stat;
+
+	stat = readl(port->base + PCIE_STAT_OFF);
+	stat &= ~PCIE_STAT_DEV;
+	stat |= nr << 16;
+	writel(stat, port->base + PCIE_STAT_OFF);
+}
+
+/*
+ * Setup PCIE BARs and Address Decode Wins:
+ * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
+ * WIN[0-3] -> DRAM bank[0-3]
+ */
+static void __init mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
+{
+	const struct mbus_dram_target_info *dram;
+	u32 size;
+	int i;
+
+	dram = mv_mbus_dram_info();
+
+	/* First, disable and clear BARs and windows. */
+	for (i = 1; i < 3; i++) {
+		writel(0, port->base + PCIE_BAR_CTRL_OFF(i));
+		writel(0, port->base + PCIE_BAR_LO_OFF(i));
+		writel(0, port->base + PCIE_BAR_HI_OFF(i));
+	}
+
+	for (i = 0; i < 5; i++) {
+		writel(0, port->base + PCIE_WIN04_CTRL_OFF(i));
+		writel(0, port->base + PCIE_WIN04_BASE_OFF(i));
+		writel(0, port->base + PCIE_WIN04_REMAP_OFF(i));
+	}
+
+	writel(0, port->base + PCIE_WIN5_CTRL_OFF);
+	writel(0, port->base + PCIE_WIN5_BASE_OFF);
+	writel(0, port->base + PCIE_WIN5_REMAP_OFF);
+
+	/* Setup windows for DDR banks.  Count total DDR size on the fly. */
+	size = 0;
+	for (i = 0; i < dram->num_cs; i++) {
+		const struct mbus_dram_window *cs = dram->cs + i;
+
+		writel(cs->base & 0xffff0000,
+		       port->base + PCIE_WIN04_BASE_OFF(i));
+		writel(0, port->base + PCIE_WIN04_REMAP_OFF(i));
+		writel(((cs->size - 1) & 0xffff0000) |
+			(cs->mbus_attr << 8) |
+			(dram->mbus_dram_target_id << 4) | 1,
+		       port->base + PCIE_WIN04_CTRL_OFF(i));
+
+		size += cs->size;
+	}
+
+	/* Round up 'size' to the nearest power of two. */
+	if ((size & (size - 1)) != 0)
+		size = 1 << fls(size);
+
+	/* Setup BAR[1] to all DRAM banks. */
+	writel(dram->cs[0].base, port->base + PCIE_BAR_LO_OFF(1));
+	writel(0, port->base + PCIE_BAR_HI_OFF(1));
+	writel(((size - 1) & 0xffff0000) | 1,
+	       port->base + PCIE_BAR_CTRL_OFF(1));
+}
+
+static void __init mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
+{
+	u16 cmd;
+	u32 mask;
+
+	/* Point PCIe unit MBUS decode windows to DRAM space. */
+	mvebu_pcie_setup_wins(port);
+
+	/* Master + slave enable. */
+	cmd = readw(port->base + PCIE_CMD_OFF);
+	cmd |= PCI_COMMAND_IO;
+	cmd |= PCI_COMMAND_MEMORY;
+	cmd |= PCI_COMMAND_MASTER;
+	writew(cmd, port->base + PCIE_CMD_OFF);
+
+	/* Enable interrupt lines A-D. */
+	mask = readl(port->base + PCIE_MASK_OFF);
+	mask |= PCIE_MASK_ENABLE_INTS;
+	writel(mask, port->base + PCIE_MASK_OFF);
+}
+
+static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
+				 struct pci_bus *bus,
+				 u32 devfn, int where, int size, u32 *val)
+{
+	writel(PCIE_CONF_ADDR(bus->number, devfn, where),
+	       port->base + PCIE_CONF_ADDR_OFF);
+
+	*val = readl(port->base + PCIE_CONF_DATA_OFF);
+
+	if (size == 1)
+		*val = (*val >> (8 * (where & 3))) & 0xff;
+	else if (size == 2)
+		*val = (*val >> (8 * (where & 3))) & 0xffff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
+				 struct pci_bus *bus,
+				 u32 devfn, int where, int size, u32 val)
+{
+	int ret = PCIBIOS_SUCCESSFUL;
+
+	writel(PCIE_CONF_ADDR(bus->number, devfn, where),
+	       port->base + PCIE_CONF_ADDR_OFF);
+
+	if (size == 4)
+		writel(val, port->base + PCIE_CONF_DATA_OFF);
+	else if (size == 2)
+		writew(val, port->base + PCIE_CONF_DATA_OFF + (where & 3));
+	else if (size == 1)
+		writeb(val, port->base + PCIE_CONF_DATA_OFF + (where & 3));
+	else
+		ret = PCIBIOS_BAD_REGISTER_NUMBER;
+
+	return ret;
+}
+
+static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
+{
+	phys_addr_t iobase;
+
+	/* Are the new iobase/iolimit values invalid? */
+	if (port->bridge.iolimit < port->bridge.iobase ||
+	    port->bridge.iolimitupper < port->bridge.iobaseupper) {
+
+		/* If a window was configured, remove it */
+		if (port->iowin_base) {
+			mvebu_mbus_del_window(port->iowin_base,
+					      port->iowin_size);
+			port->iowin_base = 0;
+			port->iowin_size = 0;
+		}
+
+		return;
+	}
+
+	/*
+	 * We read the PCI-to-PCI bridge emulated registers, and
+	 * calculate the base address and size of the address decoding
+	 * window to setup, according to the PCI-to-PCI bridge
+	 * specifications. iobase is the bus address, port->iowin_base
+	 * is the CPU address.
+	 */
+	iobase = ((port->bridge.iobase & 0xF0) << 8) |
+		(port->bridge.iobaseupper << 16);
+	port->iowin_base = port->pcie->io.start + iobase;
+	port->iowin_size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) |
+			    (port->bridge.iolimitupper << 16)) -
+			    iobase);
+
+	mvebu_mbus_add_window_remap_flags(port->name, port->iowin_base,
+					  port->iowin_size,
+					  iobase,
+					  MVEBU_MBUS_PCI_IO);
+
+	pci_ioremap_io(iobase, port->iowin_base);
+}
+
+static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
+{
+	/* Are the new membase/memlimit values invalid? */
+	if (port->bridge.memlimit < port->bridge.membase) {
+
+		/* If a window was configured, remove it */
+		if (port->memwin_base) {
+			mvebu_mbus_del_window(port->memwin_base,
+					      port->memwin_size);
+			port->memwin_base = 0;
+			port->memwin_size = 0;
+		}
+
+		return;
+	}
+
+	/*
+	 * We read the PCI-to-PCI bridge emulated registers, and
+	 * calculate the base address and size of the address decoding
+	 * window to setup, according to the PCI-to-PCI bridge
+	 * specifications.
+	 */
+	port->memwin_base  = ((port->bridge.membase & 0xFFF0) << 16);
+	port->memwin_size  =
+		(((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
+		port->memwin_base;
+
+	mvebu_mbus_add_window_remap_flags(port->name, port->memwin_base,
+					  port->memwin_size,
+					  MVEBU_MBUS_NO_REMAP,
+					  MVEBU_MBUS_PCI_MEM);
+}
+
+/*
+ * Initialize the configuration space of the PCI-to-PCI bridge
+ * associated with the given PCIe interface.
+ */
+static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port)
+{
+	struct mvebu_sw_pci_bridge *bridge = &port->bridge;
+
+	memset(bridge, 0, sizeof(struct mvebu_sw_pci_bridge));
+
+	bridge->class = PCI_CLASS_BRIDGE_PCI;
+	bridge->vendor = PCI_VENDOR_ID_MARVELL;
+	bridge->device = MARVELL_EMULATED_PCI_PCI_BRIDGE_ID;
+	bridge->header_type = PCI_HEADER_TYPE_BRIDGE;
+	bridge->cache_line_size = 0x10;
+
+	/* We support 32 bits I/O addressing */
+	bridge->iobase = PCI_IO_RANGE_TYPE_32;
+	bridge->iolimit = PCI_IO_RANGE_TYPE_32;
+}
+
+/*
+ * Read the configuration space of the PCI-to-PCI bridge associated to
+ * the given PCIe interface.
+ */
+static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port,
+				  unsigned int where, int size, u32 *value)
+{
+	struct mvebu_sw_pci_bridge *bridge = &port->bridge;
+
+	switch (where & ~3) {
+	case PCI_VENDOR_ID:
+		*value = bridge->device << 16 | bridge->vendor;
+		break;
+
+	case PCI_COMMAND:
+		*value = bridge->command;
+		break;
+
+	case PCI_CLASS_REVISION:
+		*value = bridge->class << 16 | bridge->interface << 8 |
+			 bridge->revision;
+		break;
+
+	case PCI_CACHE_LINE_SIZE:
+		*value = bridge->bist << 24 | bridge->header_type << 16 |
+			 bridge->latency_timer << 8 | bridge->cache_line_size;
+		break;
+
+	case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1:
+		*value = bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4];
+		break;
+
+	case PCI_PRIMARY_BUS:
+		*value = (bridge->secondary_latency_timer << 24 |
+			  bridge->subordinate_bus         << 16 |
+			  bridge->secondary_bus           <<  8 |
+			  bridge->primary_bus);
+		break;
+
+	case PCI_IO_BASE:
+		*value = (bridge->secondary_status << 16 |
+			  bridge->iolimit          <<  8 |
+			  bridge->iobase);
+		break;
+
+	case PCI_MEMORY_BASE:
+		*value = (bridge->memlimit << 16 | bridge->membase);
+		break;
+
+	case PCI_PREF_MEMORY_BASE:
+		*value = 0;
+		break;
+
+	case PCI_IO_BASE_UPPER16:
+		*value = (bridge->iolimitupper << 16 | bridge->iobaseupper);
+		break;
+
+	case PCI_ROM_ADDRESS1:
+		*value = 0;
+		break;
+
+	default:
+		*value = 0xffffffff;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	if (size == 2)
+		*value = (*value >> (8 * (where & 3))) & 0xffff;
+	else if (size == 1)
+		*value = (*value >> (8 * (where & 3))) & 0xff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* Write to the PCI-to-PCI bridge configuration space */
+static int mvebu_sw_pci_bridge_write(struct mvebu_pcie_port *port,
+				     unsigned int where, int size, u32 value)
+{
+	struct mvebu_sw_pci_bridge *bridge = &port->bridge;
+	u32 mask, reg;
+	int err;
+
+	if (size == 4)
+		mask = 0x0;
+	else if (size == 2)
+		mask = ~(0xffff << ((where & 3) * 8));
+	else if (size == 1)
+		mask = ~(0xff << ((where & 3) * 8));
+	else
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	err = mvebu_sw_pci_bridge_read(port, where & ~3, 4, &reg);
+	if (err)
+		return err;
+
+	value = (reg & mask) | value << ((where & 3) * 8);
+
+	switch (where & ~3) {
+	case PCI_COMMAND:
+		bridge->command = value & 0xffff;
+		break;
+
+	case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_1:
+		bridge->bar[((where & ~3) - PCI_BASE_ADDRESS_0) / 4] = value;
+		break;
+
+	case PCI_IO_BASE:
+		/*
+		 * We also keep bit 1 set, it is a read-only bit that
+		 * indicates we support 32 bits addressing for the
+		 * I/O
+		 */
+		bridge->iobase = (value & 0xff) | PCI_IO_RANGE_TYPE_32;
+		bridge->iolimit = ((value >> 8) & 0xff) | PCI_IO_RANGE_TYPE_32;
+		bridge->secondary_status = value >> 16;
+		mvebu_pcie_handle_iobase_change(port);
+		break;
+
+	case PCI_MEMORY_BASE:
+		bridge->membase = value & 0xffff;
+		bridge->memlimit = value >> 16;
+		mvebu_pcie_handle_membase_change(port);
+		break;
+
+	case PCI_IO_BASE_UPPER16:
+		bridge->iobaseupper = value & 0xffff;
+		bridge->iolimitupper = value >> 16;
+		mvebu_pcie_handle_iobase_change(port);
+		break;
+
+	case PCI_PRIMARY_BUS:
+		bridge->primary_bus             = value & 0xff;
+		bridge->secondary_bus           = (value >> 8) & 0xff;
+		bridge->subordinate_bus         = (value >> 16) & 0xff;
+		bridge->secondary_latency_timer = (value >> 24) & 0xff;
+		mvebu_pcie_set_local_bus_nr(port, bridge->secondary_bus);
+		break;
+
+	default:
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys)
+{
+	return sys->private_data;
+}
+
+static struct mvebu_pcie_port *
+mvebu_pcie_find_port(struct mvebu_pcie *pcie, struct pci_bus *bus,
+		     int devfn)
+{
+	int i;
+
+	for (i = 0; i < pcie->nports; i++) {
+		struct mvebu_pcie_port *port = &pcie->ports[i];
+		if (bus->number == 0 && port->devfn == devfn)
+			return port;
+		if (bus->number != 0 &&
+		    bus->number >= port->bridge.secondary_bus &&
+		    bus->number <= port->bridge.subordinate_bus)
+			return port;
+	}
+
+	return NULL;
+}
+
+/* PCI configuration space write function */
+static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+			      int where, int size, u32 val)
+{
+	struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
+	struct mvebu_pcie_port *port;
+	unsigned long flags;
+	int ret;
+
+	port = mvebu_pcie_find_port(pcie, bus, devfn);
+	if (!port)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Access the emulated PCI-to-PCI bridge */
+	if (bus->number == 0)
+		return mvebu_sw_pci_bridge_write(port, where, size, val);
+
+	if (!port->haslink)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/*
+	 * On the secondary bus, we don't want to expose any other
+	 * device than the device physically connected in the PCIe
+	 * slot, visible in slot 0. In slot 1, there's a special
+	 * Marvell device that only makes sense when the Armada is
+	 * used as a PCIe endpoint.
+	 */
+	if (bus->number == port->bridge.secondary_bus &&
+	    PCI_SLOT(devfn) != 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Access the real PCIe interface */
+	spin_lock_irqsave(&port->conf_lock, flags);
+	ret = mvebu_pcie_hw_wr_conf(port, bus, devfn,
+				    where, size, val);
+	spin_unlock_irqrestore(&port->conf_lock, flags);
+
+	return ret;
+}
+
+/* PCI configuration space read function */
+static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+			      int size, u32 *val)
+{
+	struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
+	struct mvebu_pcie_port *port;
+	unsigned long flags;
+	int ret;
+
+	port = mvebu_pcie_find_port(pcie, bus, devfn);
+	if (!port) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	/* Access the emulated PCI-to-PCI bridge */
+	if (bus->number == 0)
+		return mvebu_sw_pci_bridge_read(port, where, size, val);
+
+	if (!port->haslink) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	/*
+	 * On the secondary bus, we don't want to expose any other
+	 * device than the device physically connected in the PCIe
+	 * slot, visible in slot 0. In slot 1, there's a special
+	 * Marvell device that only makes sense when the Armada is
+	 * used as a PCIe endpoint.
+	 */
+	if (bus->number == port->bridge.secondary_bus &&
+	    PCI_SLOT(devfn) != 0) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	/* Access the real PCIe interface */
+	spin_lock_irqsave(&port->conf_lock, flags);
+	ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
+				    where, size, val);
+	spin_unlock_irqrestore(&port->conf_lock, flags);
+
+	return ret;
+}
+
+static struct pci_ops mvebu_pcie_ops = {
+	.read = mvebu_pcie_rd_conf,
+	.write = mvebu_pcie_wr_conf,
+};
+
+static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+	struct mvebu_pcie *pcie = sys_to_pcie(sys);
+	int i;
+
+	pci_add_resource_offset(&sys->resources, &pcie->realio, sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
+	pci_add_resource(&sys->resources, &pcie->busn);
+
+	for (i = 0; i < pcie->nports; i++) {
+		struct mvebu_pcie_port *port = &pcie->ports[i];
+		mvebu_pcie_setup_hw(port);
+	}
+
+	return 1;
+}
+
+static int __init mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct of_irq oirq;
+	int ret;
+
+	ret = of_irq_map_pci(dev, &oirq);
+	if (ret)
+		return ret;
+
+	return irq_create_of_mapping(oirq.controller, oirq.specifier,
+				     oirq.size);
+}
+
+static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	struct mvebu_pcie *pcie = sys_to_pcie(sys);
+	struct pci_bus *bus;
+
+	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
+				  &mvebu_pcie_ops, sys, &sys->resources);
+	if (!bus)
+		return NULL;
+
+	pci_scan_child_bus(bus);
+
+	return bus;
+}
+
+resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
+					  const struct resource *res,
+					  resource_size_t start,
+					  resource_size_t size,
+					  resource_size_t align)
+{
+	if (dev->bus->number != 0)
+		return start;
+
+	/*
+	 * On the PCI-to-PCI bridge side, the I/O windows must have at
+	 * least a 64 KB size and be aligned on their size, and the
+	 * memory windows must have at least a 1 MB size and be
+	 * aligned on their size
+	 */
+	if (res->flags & IORESOURCE_IO)
+		return round_up(start, max((resource_size_t)SZ_64K, size));
+	else if (res->flags & IORESOURCE_MEM)
+		return round_up(start, max((resource_size_t)SZ_1M, size));
+	else
+		return start;
+}
+
+static void __init mvebu_pcie_enable(struct mvebu_pcie *pcie)
+{
+	struct hw_pci hw;
+
+	memset(&hw, 0, sizeof(hw));
+
+	hw.nr_controllers = 1;
+	hw.private_data   = (void **)&pcie;
+	hw.setup          = mvebu_pcie_setup;
+	hw.scan           = mvebu_pcie_scan_bus;
+	hw.map_irq        = mvebu_pcie_map_irq;
+	hw.ops            = &mvebu_pcie_ops;
+	hw.align_resource = mvebu_pcie_align_resource;
+
+	pci_common_init(&hw);
+}
+
+/*
+ * Looks up the list of register addresses encoded into the reg =
+ * <...> property for one that matches the given port/lane. Once
+ * found, maps it.
+ */
+static void __iomem * __init
+mvebu_pcie_map_registers(struct platform_device *pdev,
+			 struct device_node *np,
+			 struct mvebu_pcie_port *port)
+{
+	struct resource regs;
+	int ret = 0;
+
+	ret = of_address_to_resource(np, 0, &regs);
+	if (ret)
+		return NULL;
+
+	return devm_request_and_ioremap(&pdev->dev, &regs);
+}
+
+static int __init mvebu_pcie_probe(struct platform_device *pdev)
+{
+	struct mvebu_pcie *pcie;
+	struct device_node *np = pdev->dev.of_node;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	struct device_node *child;
+	int i, ret;
+
+	pcie = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pcie),
+			    GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	pcie->pdev = pdev;
+
+	if (of_pci_range_parser_init(&parser, np))
+		return -EINVAL;
+
+	/* Get the I/O and memory ranges from DT */
+	for_each_of_pci_range(&parser, &range) {
+		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
+		if (restype == IORESOURCE_IO) {
+			of_pci_range_to_resource(&range, np, &pcie->io);
+			of_pci_range_to_resource(&range, np, &pcie->realio);
+			pcie->io.name = "I/O";
+			pcie->realio.start = max_t(resource_size_t,
+						   PCIBIOS_MIN_IO,
+						   range.pci_addr);
+			pcie->realio.end = min_t(resource_size_t,
+						 IO_SPACE_LIMIT,
+						 range.pci_addr + range.size);
+		}
+		if (restype == IORESOURCE_MEM) {
+			of_pci_range_to_resource(&range, np, &pcie->mem);
+			pcie->mem.name = "MEM";
+		}
+	}
+
+	/* Get the bus range */
+	ret = of_pci_parse_bus_range(np, &pcie->busn);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to parse bus-range property: %d\n",
+			ret);
+		return ret;
+	}
+
+	for_each_child_of_node(pdev->dev.of_node, child) {
+		if (!of_device_is_available(child))
+			continue;
+		pcie->nports++;
+	}
+
+	pcie->ports = devm_kzalloc(&pdev->dev, pcie->nports *
+				   sizeof(struct mvebu_pcie_port),
+				   GFP_KERNEL);
+	if (!pcie->ports)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node(pdev->dev.of_node, child) {
+		struct mvebu_pcie_port *port = &pcie->ports[i];
+
+		if (!of_device_is_available(child))
+			continue;
+
+		port->pcie = pcie;
+
+		if (of_property_read_u32(child, "marvell,pcie-port",
+					 &port->port)) {
+			dev_warn(&pdev->dev,
+				 "ignoring PCIe DT node, missing pcie-port property\n");
+			continue;
+		}
+
+		if (of_property_read_u32(child, "marvell,pcie-lane",
+					 &port->lane))
+			port->lane = 0;
+
+		port->name = kasprintf(GFP_KERNEL, "pcie%d.%d",
+				       port->port, port->lane);
+
+		port->devfn = of_pci_get_devfn(child);
+		if (port->devfn < 0)
+			continue;
+
+		port->base = mvebu_pcie_map_registers(pdev, child, port);
+		if (!port->base) {
+			dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",
+				port->port, port->lane);
+			continue;
+		}
+
+		mvebu_pcie_set_local_dev_nr(port, 1);
+
+		if (mvebu_pcie_link_up(port)) {
+			port->haslink = 1;
+			dev_info(&pdev->dev, "PCIe%d.%d: link up\n",
+				 port->port, port->lane);
+		} else {
+			port->haslink = 0;
+			dev_info(&pdev->dev, "PCIe%d.%d: link down\n",
+				 port->port, port->lane);
+		}
+
+		port->clk = of_clk_get_by_name(child, NULL);
+		if (IS_ERR(port->clk)) {
+			dev_err(&pdev->dev, "PCIe%d.%d: cannot get clock\n",
+			       port->port, port->lane);
+			iounmap(port->base);
+			port->haslink = 0;
+			continue;
+		}
+
+		port->dn = child;
+
+		clk_prepare_enable(port->clk);
+		spin_lock_init(&port->conf_lock);
+
+		mvebu_sw_pci_bridge_init(port);
+
+		i++;
+	}
+
+	mvebu_pcie_enable(pcie);
+
+	return 0;
+}
+
+static const struct of_device_id mvebu_pcie_of_match_table[] = {
+	{ .compatible = "marvell,armada-xp-pcie", },
+	{ .compatible = "marvell,armada-370-pcie", },
+	{ .compatible = "marvell,kirkwood-pcie", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table);
+
+static struct platform_driver mvebu_pcie_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "mvebu-pcie",
+		.of_match_table =
+		   of_match_ptr(mvebu_pcie_of_match_table),
+	},
+};
+
+static int __init mvebu_pcie_init(void)
+{
+	return platform_driver_probe(&mvebu_pcie_driver,
+				     mvebu_pcie_probe);
+}
+
+subsys_initcall(mvebu_pcie_init);
+
+MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell EBU PCIe driver");
+MODULE_LICENSE("GPLv2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/hotplug/cpqphp_sysfs.c linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/cpqphp_sysfs.c
--- linux-libre-3.10-gnu/drivers/pci/hotplug/cpqphp_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/cpqphp_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -167,26 +167,8 @@ exit:
 
 static loff_t lseek(struct file *file, loff_t off, int whence)
 {
-	struct ctrl_dbg *dbg;
-	loff_t new = -1;
-
-	mutex_lock(&cpqphp_mutex);
-	dbg = file->private_data;
-
-	switch (whence) {
-	case 0:
-		new = off;
-		break;
-	case 1:
-		new = file->f_pos + off;
-		break;
-	}
-	if (new < 0 || new > dbg->size) {
-		mutex_unlock(&cpqphp_mutex);
-		return -EINVAL;
-	}
-	mutex_unlock(&cpqphp_mutex);
-	return (file->f_pos = new);
+	struct ctrl_dbg *dbg = file->private_data;
+	return fixed_size_llseek(file, off, whence, dbg->size);
 }
 
 static ssize_t read(struct file *file, char __user *buf,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/hotplug/Kconfig linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/Kconfig
--- linux-libre-3.10-gnu/drivers/pci/hotplug/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -3,16 +3,13 @@
 #
 
 menuconfig HOTPLUG_PCI
-	tristate "Support for PCI Hotplug"
-	depends on PCI && HOTPLUG && SYSFS
+	bool "Support for PCI Hotplug"
+	depends on PCI && SYSFS
 	---help---
 	  Say Y here if you have a motherboard with a PCI Hotplug controller.
 	  This allows you to add and remove PCI cards while the machine is
 	  powered up and running.
 
-	  To compile this driver as a module, choose M here: the
-	  module will be called pci_hotplug.
-
 	  When in doubt, say N.
 
 if HOTPLUG_PCI
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/hotplug/pciehp_hpc.c linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/pciehp_hpc.c
--- linux-libre-3.10-gnu/drivers/pci/hotplug/pciehp_hpc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/pciehp_hpc.c	2013-08-25 20:43:22.000000000 -0400
@@ -773,14 +773,12 @@ static void pcie_shutdown_notification(s
 static int pcie_init_slot(struct controller *ctrl)
 {
 	struct slot *slot;
-	char name[32];
 
 	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
 	if (!slot)
 		return -ENOMEM;
 
-	snprintf(name, sizeof(name), "pciehp-%u", PSN(ctrl));
-	slot->wq = alloc_workqueue(name, 0, 0);
+	slot->wq = alloc_workqueue("pciehp-%u", 0, 0, PSN(ctrl));
 	if (!slot->wq)
 		goto abort;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/hotplug/pciehp_pci.c linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/pciehp_pci.c
--- linux-libre-3.10-gnu/drivers/pci/hotplug/pciehp_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/pciehp_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -92,7 +92,14 @@ int pciehp_unconfigure_device(struct slo
 	if (ret)
 		presence = 0;
 
-	list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
+	/*
+	 * Stopping an SR-IOV PF device removes all the associated VFs,
+	 * which will update the bus->devices list and confuse the
+	 * iterator.  Therefore, iterate in reverse so we remove the VFs
+	 * first, then the PF.  We do the same in pci_stop_bus_device().
+	 */
+	list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
+					 bus_list) {
 		pci_dev_get(dev);
 		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
 			pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/hotplug/rpadlpar_core.c linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/rpadlpar_core.c
--- linux-libre-3.10-gnu/drivers/pci/hotplug/rpadlpar_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/rpadlpar_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -388,7 +388,6 @@ int dlpar_remove_pci_slot(char *drc_name
 	/* Remove the EADS bridge device itself */
 	BUG_ON(!bus->self);
 	pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self));
-	eeh_remove_bus_device(bus->self, true);
 	pci_stop_and_remove_bus_device(bus->self);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/hotplug/s390_pci_hpc.c linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/s390_pci_hpc.c
--- linux-libre-3.10-gnu/drivers/pci/hotplug/s390_pci_hpc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/s390_pci_hpc.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,6 +41,28 @@ struct slot {
 	struct zpci_dev *zdev;
 };
 
+static inline int slot_configure(struct slot *slot)
+{
+	int ret = sclp_pci_configure(slot->zdev->fid);
+
+	zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, ret);
+	if (!ret)
+		slot->zdev->state = ZPCI_FN_STATE_CONFIGURED;
+
+	return ret;
+}
+
+static inline int slot_deconfigure(struct slot *slot)
+{
+	int ret = sclp_pci_deconfigure(slot->zdev->fid);
+
+	zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, ret);
+	if (!ret)
+		slot->zdev->state = ZPCI_FN_STATE_STANDBY;
+
+	return ret;
+}
+
 static int enable_slot(struct hotplug_slot *hotplug_slot)
 {
 	struct slot *slot = hotplug_slot->private;
@@ -49,14 +71,23 @@ static int enable_slot(struct hotplug_sl
 	if (slot->zdev->state != ZPCI_FN_STATE_STANDBY)
 		return -EIO;
 
-	rc = sclp_pci_configure(slot->zdev->fid);
-	zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, rc);
-	if (!rc) {
-		slot->zdev->state = ZPCI_FN_STATE_CONFIGURED;
-		/* automatically scan the device after is was configured */
-		zpci_enable_device(slot->zdev);
-		zpci_scan_device(slot->zdev);
-	}
+	rc = slot_configure(slot);
+	if (rc)
+		return rc;
+
+	rc = zpci_enable_device(slot->zdev);
+	if (rc)
+		goto out_deconfigure;
+
+	slot->zdev->state = ZPCI_FN_STATE_ONLINE;
+
+	pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN);
+	pci_bus_add_devices(slot->zdev->bus);
+
+	return rc;
+
+out_deconfigure:
+	slot_deconfigure(slot);
 	return rc;
 }
 
@@ -68,17 +99,14 @@ static int disable_slot(struct hotplug_s
 	if (!zpci_fn_configured(slot->zdev->state))
 		return -EIO;
 
+	if (slot->zdev->pdev)
+		pci_stop_and_remove_bus_device(slot->zdev->pdev);
+
 	rc = zpci_disable_device(slot->zdev);
 	if (rc)
 		return rc;
-	/* TODO: we rely on the user to unbind/remove the device, is that plausible
-	 *	 or do we need to trigger that here?
-	 */
-	rc = sclp_pci_deconfigure(slot->zdev->fid);
-	zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, rc);
-	if (!rc)
-		slot->zdev->state = ZPCI_FN_STATE_STANDBY;
-	return rc;
+
+	return slot_deconfigure(slot);
 }
 
 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/hotplug/shpchp_core.c linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/shpchp_core.c
--- linux-libre-3.10-gnu/drivers/pci/hotplug/shpchp_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/hotplug/shpchp_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -128,8 +128,7 @@ static int init_slots(struct controller
 		slot->hpc_ops = ctrl->hpc_ops;
 		slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i);
 
-		snprintf(name, sizeof(name), "shpchp-%d", slot->number);
-		slot->wq = alloc_workqueue(name, 0, 0);
+		slot->wq = alloc_workqueue("shpchp-%d", 0, 0, slot->number);
 		if (!slot->wq) {
 			retval = -ENOMEM;
 			goto error_info;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/ioapic.c linux-libre-3.11-rc7-gnu/drivers/pci/ioapic.c
--- linux-libre-3.10-gnu/drivers/pci/ioapic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/ioapic.c	2013-08-25 20:43:22.000000000 -0400
@@ -113,17 +113,6 @@ static struct pci_driver ioapic_driver =
 	.remove		= ioapic_remove,
 };
 
-static int __init ioapic_init(void)
-{
-	return pci_register_driver(&ioapic_driver);
-}
-
-static void __exit ioapic_exit(void)
-{
-	pci_unregister_driver(&ioapic_driver);
-}
-
-module_init(ioapic_init);
-module_exit(ioapic_exit);
+module_pci_driver(ioapic_driver);
 
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/iov.c linux-libre-3.11-rc7-gnu/drivers/pci/iov.c
--- linux-libre-3.10-gnu/drivers/pci/iov.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/iov.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,51 +47,43 @@ static struct pci_bus *virtfn_add_bus(st
 		return NULL;
 
 	pci_bus_insert_busn_res(child, busnr, busnr);
-	bus->is_added = 1;
 
 	return child;
 }
 
-static void virtfn_remove_bus(struct pci_bus *bus, int busnr)
+static void virtfn_remove_bus(struct pci_bus *physbus, struct pci_bus *virtbus)
 {
-	struct pci_bus *child;
-
-	if (bus->number == busnr)
-		return;
-
-	child = pci_find_bus(pci_domain_nr(bus), busnr);
-	BUG_ON(!child);
-
-	if (list_empty(&child->devices))
-		pci_remove_bus(child);
+	if (physbus != virtbus && list_empty(&virtbus->devices))
+		pci_remove_bus(virtbus);
 }
 
 static int virtfn_add(struct pci_dev *dev, int id, int reset)
 {
 	int i;
-	int rc;
+	int rc = -ENOMEM;
 	u64 size;
 	char buf[VIRTFN_ID_LEN];
 	struct pci_dev *virtfn;
 	struct resource *res;
 	struct pci_sriov *iov = dev->sriov;
+	struct pci_bus *bus;
 
-	virtfn = alloc_pci_dev();
+	mutex_lock(&iov->dev->sriov->lock);
+	bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
+	if (!bus)
+		goto failed;
+
+	virtfn = pci_alloc_dev(bus);
 	if (!virtfn)
-		return -ENOMEM;
+		goto failed0;
 
-	mutex_lock(&iov->dev->sriov->lock);
-	virtfn->bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
-	if (!virtfn->bus) {
-		kfree(virtfn);
-		mutex_unlock(&iov->dev->sriov->lock);
-		return -ENOMEM;
-	}
 	virtfn->devfn = virtfn_devfn(dev, id);
 	virtfn->vendor = dev->vendor;
 	pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
 	pci_setup_device(virtfn);
 	virtfn->dev.parent = dev->dev.parent;
+	virtfn->physfn = pci_dev_get(dev);
+	virtfn->is_virtfn = 1;
 
 	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
 		res = dev->resource + PCI_IOV_RESOURCES + i;
@@ -113,9 +105,6 @@ static int virtfn_add(struct pci_dev *de
 	pci_device_add(virtfn, virtfn->bus);
 	mutex_unlock(&iov->dev->sriov->lock);
 
-	virtfn->physfn = pci_dev_get(dev);
-	virtfn->is_virtfn = 1;
-
 	rc = pci_bus_add_device(virtfn);
 	sprintf(buf, "virtfn%u", id);
 	rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
@@ -135,7 +124,9 @@ failed1:
 	pci_dev_put(dev);
 	mutex_lock(&iov->dev->sriov->lock);
 	pci_stop_and_remove_bus_device(virtfn);
-	virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
+failed0:
+	virtfn_remove_bus(dev->bus, bus);
+failed:
 	mutex_unlock(&iov->dev->sriov->lock);
 
 	return rc;
@@ -144,20 +135,15 @@ failed1:
 static void virtfn_remove(struct pci_dev *dev, int id, int reset)
 {
 	char buf[VIRTFN_ID_LEN];
-	struct pci_bus *bus;
 	struct pci_dev *virtfn;
 	struct pci_sriov *iov = dev->sriov;
 
-	bus = pci_find_bus(pci_domain_nr(dev->bus), virtfn_bus(dev, id));
-	if (!bus)
-		return;
-
-	virtfn = pci_get_slot(bus, virtfn_devfn(dev, id));
+	virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus),
+					     virtfn_bus(dev, id),
+					     virtfn_devfn(dev, id));
 	if (!virtfn)
 		return;
 
-	pci_dev_put(virtfn);
-
 	if (reset) {
 		device_release_driver(&virtfn->dev);
 		__pci_reset_function(virtfn);
@@ -175,9 +161,11 @@ static void virtfn_remove(struct pci_dev
 
 	mutex_lock(&iov->dev->sriov->lock);
 	pci_stop_and_remove_bus_device(virtfn);
-	virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
+	virtfn_remove_bus(dev->bus, virtfn->bus);
 	mutex_unlock(&iov->dev->sriov->lock);
 
+	/* balance pci_get_domain_bus_and_slot() */
+	pci_dev_put(virtfn);
 	pci_dev_put(dev);
 }
 
@@ -334,13 +322,14 @@ static int sriov_enable(struct pci_dev *
 		if (!pdev)
 			return -ENODEV;
 
-		pci_dev_put(pdev);
-
-		if (!pdev->is_physfn)
+		if (!pdev->is_physfn) {
+			pci_dev_put(pdev);
 			return -ENODEV;
+		}
 
 		rc = sysfs_create_link(&dev->dev.kobj,
 					&pdev->dev.kobj, "dep_link");
+		pci_dev_put(pdev);
 		if (rc)
 			return rc;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/Kconfig linux-libre-3.11-rc7-gnu/drivers/pci/Kconfig
--- linux-libre-3.10-gnu/drivers/pci/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -55,7 +55,6 @@ config PCI_STUB
 config XEN_PCIDEV_FRONTEND
         tristate "Xen PCI Frontend"
         depends on PCI && X86 && XEN
-        select HOTPLUG
         select PCI_XEN
 	select XEN_XENBUS_FRONTEND
         default y
@@ -113,9 +112,10 @@ config PCI_IOAPIC
 	tristate "PCI IO-APIC hotplug support" if X86
 	depends on PCI
 	depends on ACPI
-	depends on HOTPLUG
 	default !X86
 
 config PCI_LABEL
 	def_bool y if (DMI || ACPI)
 	select NLS
+
+source "drivers/pci/host/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/Makefile linux-libre-3.11-rc7-gnu/drivers/pci/Makefile
--- linux-libre-3.10-gnu/drivers/pci/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -67,3 +67,6 @@ obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen
 obj-$(CONFIG_OF) += of.o
 
 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
+
+# PCI host controller drivers
+obj-y += host/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/msi.c linux-libre-3.11-rc7-gnu/drivers/pci/msi.c
--- linux-libre-3.10-gnu/drivers/pci/msi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/msi.c	2013-08-25 20:43:22.000000000 -0400
@@ -81,7 +81,10 @@ void default_teardown_msi_irqs(struct pc
 		int i, nvec;
 		if (entry->irq == 0)
 			continue;
-		nvec = 1 << entry->msi_attrib.multiple;
+		if (entry->nvec_used)
+			nvec = entry->nvec_used;
+		else
+			nvec = 1 << entry->msi_attrib.multiple;
 		for (i = 0; i < nvec; i++)
 			arch_teardown_msi_irq(entry->irq + i);
 	}
@@ -336,7 +339,10 @@ static void free_msi_irqs(struct pci_dev
 		int i, nvec;
 		if (!entry->irq)
 			continue;
-		nvec = 1 << entry->msi_attrib.multiple;
+		if (entry->nvec_used)
+			nvec = entry->nvec_used;
+		else
+			nvec = 1 << entry->msi_attrib.multiple;
 #ifdef CONFIG_GENERIC_HARDIRQS
 		for (i = 0; i < nvec; i++)
 			BUG_ON(irq_has_action(entry->irq + i));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pci-acpi.c linux-libre-3.11-rc7-gnu/drivers/pci/pci-acpi.c
--- linux-libre-3.10-gnu/drivers/pci/pci-acpi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pci-acpi.c	2013-08-25 20:43:22.000000000 -0400
@@ -186,8 +186,8 @@ static int acpi_pci_set_power_state(stru
 		[PCI_D0] = ACPI_STATE_D0,
 		[PCI_D1] = ACPI_STATE_D1,
 		[PCI_D2] = ACPI_STATE_D2,
-		[PCI_D3hot] = ACPI_STATE_D3,
-		[PCI_D3cold] = ACPI_STATE_D3
+		[PCI_D3hot] = ACPI_STATE_D3_COLD,
+		[PCI_D3cold] = ACPI_STATE_D3_COLD,
 	};
 	int error = -EINVAL;
 
@@ -211,7 +211,7 @@ static int acpi_pci_set_power_state(stru
 
 	if (!error)
 		dev_info(&dev->dev, "power state changed by ACPI to %s\n",
-			 pci_power_name(state));
+			 acpi_power_state_string(state_conv[state]));
 
 	return error;
 }
@@ -317,13 +317,20 @@ void acpi_pci_remove_bus(struct pci_bus
 /* ACPI bus type */
 static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
 {
-	struct pci_dev * pci_dev;
-	u64	addr;
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	bool is_bridge;
+	u64 addr;
 
-	pci_dev = to_pci_dev(dev);
+	/*
+	 * pci_is_bridge() is not suitable here, because pci_dev->subordinate
+	 * is set only after acpi_pci_find_device() has been called for the
+	 * given device.
+	 */
+	is_bridge = pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE
+			|| pci_dev->hdr_type == PCI_HEADER_TYPE_CARDBUS;
 	/* Please ref to ACPI spec for the syntax of _ADR */
 	addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
-	*handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
+	*handle = acpi_find_child(ACPI_HANDLE(dev->parent), addr, is_bridge);
 	if (!*handle)
 		return -ENODEV;
 	return 0;
@@ -376,12 +383,12 @@ static int __init acpi_pci_init(void)
 	int ret;
 
 	if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
-		printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
+		pr_info("ACPI FADT declares the system doesn't support MSI, so disable it\n");
 		pci_no_msi();
 	}
 
 	if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
-		printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
+		pr_info("ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
 		pcie_no_aspm();
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pci.c linux-libre-3.11-rc7-gnu/drivers/pci/pci.c
--- linux-libre-3.10-gnu/drivers/pci/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -805,7 +805,7 @@ pci_power_t pci_choose_state(struct pci_
 {
 	pci_power_t ret;
 
-	if (!pci_find_capability(dev, PCI_CAP_ID_PM))
+	if (!dev->pm_cap)
 		return PCI_D0;
 
 	ret = platform_pci_choose_state(dev);
@@ -1335,6 +1335,16 @@ int __weak pcibios_add_device (struct pc
 }
 
 /**
+ * pcibios_release_device - provide arch specific hooks when releasing device dev
+ * @dev: the PCI device being released
+ *
+ * Permits the platform to provide architecture specific functionality when
+ * devices are released. This is the default implementation. Architecture
+ * implementations can override this.
+ */
+void __weak pcibios_release_device(struct pci_dev *dev) {}
+
+/**
  * pcibios_disable_device - disable arch specific PCI resources for device dev
  * @dev: the PCI device to disable
  *
@@ -2421,7 +2431,7 @@ bool pci_acs_path_enabled(struct pci_dev
 /**
  * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
  * @dev: the PCI device
- * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD)
+ * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD)
  *
  * Perform INTx swizzling for a device behind one level of bridge.  This is
  * required by section 9.1 of the PCI-to-PCI bridge specification for devices
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pci-driver.c linux-libre-3.11-rc7-gnu/drivers/pci/pci-driver.c
--- linux-libre-3.10-gnu/drivers/pci/pci-driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pci-driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -1050,26 +1050,22 @@ static int pci_pm_runtime_idle(struct de
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	int ret = 0;
 
 	/*
 	 * If pci_dev->driver is not set (unbound), the device should
 	 * always remain in D0 regardless of the runtime PM status
 	 */
 	if (!pci_dev->driver)
-		goto out;
+		return 0;
 
 	if (!pm)
 		return -ENOSYS;
 
-	if (pm->runtime_idle) {
-		int ret = pm->runtime_idle(dev);
-		if (ret)
-			return ret;
-	}
+	if (pm->runtime_idle)
+		ret = pm->runtime_idle(dev);
 
-out:
-	pm_runtime_suspend(dev);
-	return 0;
+	return ret;
 }
 
 #else /* !CONFIG_PM_RUNTIME */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pcie/aer/aerdrv_acpi.c linux-libre-3.11-rc7-gnu/drivers/pci/pcie/aer/aerdrv_acpi.c
--- linux-libre-3.10-gnu/drivers/pci/pcie/aer/aerdrv_acpi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pcie/aer/aerdrv_acpi.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,22 @@ static inline int hest_match_pci(struct
 		 p->function == PCI_FUNC(pci->devfn));
 }
 
+static inline bool hest_match_type(struct acpi_hest_header *hest_hdr,
+				struct pci_dev *dev)
+{
+	u16 hest_type = hest_hdr->type;
+	u8 pcie_type = pci_pcie_type(dev);
+
+	if ((hest_type == ACPI_HEST_TYPE_AER_ROOT_PORT &&
+		pcie_type == PCI_EXP_TYPE_ROOT_PORT) ||
+	    (hest_type == ACPI_HEST_TYPE_AER_ENDPOINT &&
+		pcie_type == PCI_EXP_TYPE_ENDPOINT) ||
+	    (hest_type == ACPI_HEST_TYPE_AER_BRIDGE &&
+		(dev->class >> 16) == PCI_BASE_CLASS_BRIDGE))
+		return true;
+	return false;
+}
+
 struct aer_hest_parse_info {
 	struct pci_dev *pci_dev;
 	int firmware_first;
@@ -38,34 +54,16 @@ static int aer_hest_parse(struct acpi_he
 {
 	struct aer_hest_parse_info *info = data;
 	struct acpi_hest_aer_common *p;
-	u8 pcie_type = 0;
-	u8 bridge = 0;
-	int ff = 0;
-
-	switch (hest_hdr->type) {
-	case ACPI_HEST_TYPE_AER_ROOT_PORT:
-		pcie_type = PCI_EXP_TYPE_ROOT_PORT;
-		break;
-	case ACPI_HEST_TYPE_AER_ENDPOINT:
-		pcie_type = PCI_EXP_TYPE_ENDPOINT;
-		break;
-	case ACPI_HEST_TYPE_AER_BRIDGE:
-		if ((info->pci_dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
-			bridge = 1;
-		break;
-	default:
-		return 0;
-	}
+	int ff;
 
 	p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
+	ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
 	if (p->flags & ACPI_HEST_GLOBAL) {
-		if ((pci_is_pcie(info->pci_dev) &&
-		     pci_pcie_type(info->pci_dev) == pcie_type) || bridge)
-			ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
+		if (hest_match_type(hest_hdr, info->pci_dev))
+			info->firmware_first = ff;
 	} else
 		if (hest_match_pci(p, info->pci_dev))
-			ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
-	info->firmware_first = ff;
+			info->firmware_first = ff;
 
 	return 0;
 }
@@ -89,6 +87,9 @@ static void aer_set_firmware_first(struc
 
 int pcie_aer_get_firmware_first(struct pci_dev *dev)
 {
+	if (!pci_is_pcie(dev))
+		return 0;
+
 	if (!dev->__aer_firmware_first_valid)
 		aer_set_firmware_first(dev);
 	return dev->__aer_firmware_first;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pcie/aer/aerdrv_core.c linux-libre-3.11-rc7-gnu/drivers/pci/pcie/aer/aerdrv_core.c
--- linux-libre-3.10-gnu/drivers/pci/pcie/aer/aerdrv_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pcie/aer/aerdrv_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -400,16 +400,16 @@ void aer_do_secondary_bus_reset(struct p
 }
 
 /**
- * default_downstream_reset_link - default reset function for Downstream Port
- * @dev: pointer to downstream port's pci_dev data structure
+ * default_reset_link - default reset function
+ * @dev: pointer to pci_dev data structure
  *
- * Invoked when performing link reset at Downstream Port w/ no aer driver.
+ * Invoked when performing link reset on a Downstream Port or a
+ * Root Port with no aer driver.
  */
-static pci_ers_result_t default_downstream_reset_link(struct pci_dev *dev)
+static pci_ers_result_t default_reset_link(struct pci_dev *dev)
 {
 	aer_do_secondary_bus_reset(dev);
-	dev_printk(KERN_DEBUG, &dev->dev,
-		"Downstream Port link has been reset\n");
+	dev_printk(KERN_DEBUG, &dev->dev, "downstream link has been reset\n");
 	return PCI_ERS_RESULT_RECOVERED;
 }
 
@@ -458,8 +458,9 @@ static pci_ers_result_t reset_link(struc
 
 	if (driver && driver->reset_link) {
 		status = driver->reset_link(udev);
-	} else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM) {
-		status = default_downstream_reset_link(udev);
+	} else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM ||
+		pci_pcie_type(udev) == PCI_EXP_TYPE_ROOT_PORT) {
+		status = default_reset_link(udev);
 	} else {
 		dev_printk(KERN_DEBUG, &dev->dev,
 			"no link-reset support at upstream device %s\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pcie/aer/aerdrv.h linux-libre-3.11-rc7-gnu/drivers/pci/pcie/aer/aerdrv.h
--- linux-libre-3.10-gnu/drivers/pci/pcie/aer/aerdrv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pcie/aer/aerdrv.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,10 +13,6 @@
 #include <linux/aer.h>
 #include <linux/interrupt.h>
 
-#define AER_NONFATAL			0
-#define AER_FATAL			1
-#define AER_CORRECTABLE			2
-
 #define SYSTEM_ERROR_INTR_ON_MESG_MASK	(PCI_EXP_RTCTL_SECEE|	\
 					PCI_EXP_RTCTL_SENFEE|	\
 					PCI_EXP_RTCTL_SEFEE)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pcie/aspm.c linux-libre-3.11-rc7-gnu/drivers/pci/pcie/aspm.c
--- linux-libre-3.10-gnu/drivers/pci/pcie/aspm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pcie/aspm.c	2013-08-25 20:43:22.000000000 -0400
@@ -714,19 +714,12 @@ void pcie_aspm_powersave_config_link(str
 	up_read(&pci_bus_sem);
 }
 
-/*
- * pci_disable_link_state - disable pci device's link state, so the link will
- * never enter specific states
- */
 static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
 				     bool force)
 {
 	struct pci_dev *parent = pdev->bus->self;
 	struct pcie_link_state *link;
 
-	if (aspm_disabled && !force)
-		return;
-
 	if (!pci_is_pcie(pdev))
 		return;
 
@@ -736,6 +729,19 @@ static void __pci_disable_link_state(str
 	if (!parent || !parent->link_state)
 		return;
 
+	/*
+	 * A driver requested that ASPM be disabled on this device, but
+	 * if we don't have permission to manage ASPM (e.g., on ACPI
+	 * systems we have to observe the FADT ACPI_FADT_NO_ASPM bit and
+	 * the _OSC method), we can't honor that request.  Windows has
+	 * a similar mechanism using "PciASPMOptOut", which is also
+	 * ignored in this situation.
+	 */
+	if (aspm_disabled && !force) {
+		dev_warn(&pdev->dev, "can't disable ASPM; OS doesn't have ASPM control\n");
+		return;
+	}
+
 	if (sem)
 		down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
@@ -761,6 +767,15 @@ void pci_disable_link_state_locked(struc
 }
 EXPORT_SYMBOL(pci_disable_link_state_locked);
 
+/**
+ * pci_disable_link_state - Disable device's link state, so the link will
+ * never enter specific states.  Note that if the BIOS didn't grant ASPM
+ * control to the OS, this does nothing because we can't touch the LNKCTL
+ * register.
+ *
+ * @pdev: PCI device
+ * @state: ASPM link state to disable
+ */
 void pci_disable_link_state(struct pci_dev *pdev, int state)
 {
 	__pci_disable_link_state(pdev, state, true, false);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pcie/Kconfig linux-libre-3.11-rc7-gnu/drivers/pci/pcie/Kconfig
--- linux-libre-3.10-gnu/drivers/pci/pcie/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pcie/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -14,15 +14,12 @@ config PCIEPORTBUS
 # Include service Kconfig here
 #
 config HOTPLUG_PCI_PCIE
-	tristate "PCI Express Hotplug driver"
+	bool "PCI Express Hotplug driver"
 	depends on HOTPLUG_PCI && PCIEPORTBUS
 	help
 	  Say Y here if you have a motherboard that supports PCI Express Native
 	  Hotplug
 
-	  To compile this driver as a module, choose M here: the
-	  module will be called pciehp.
-
 	  When in doubt, say N.
 
 source "drivers/pci/pcie/aer/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pcie/pme.c linux-libre-3.11-rc7-gnu/drivers/pci/pcie/pme.c
--- linux-libre-3.10-gnu/drivers/pci/pcie/pme.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pcie/pme.c	2013-08-25 20:43:22.000000000 -0400
@@ -408,7 +408,7 @@ static int pcie_pme_resume(struct pcie_d
 
 /**
  * pcie_pme_remove - Prepare PCIe PME service device for removal.
- * @srv - PCIe service device to resume.
+ * @srv - PCIe service device to remove.
  */
 static void pcie_pme_remove(struct pcie_device *srv)
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/pci-sysfs.c linux-libre-3.11-rc7-gnu/drivers/pci/pci-sysfs.c
--- linux-libre-3.10-gnu/drivers/pci/pci-sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/pci-sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -66,7 +66,7 @@ static ssize_t broken_parity_status_stor
 	struct pci_dev *pdev = to_pci_dev(dev);
 	unsigned long val;
 
-	if (strict_strtoul(buf, 0, &val) < 0)
+	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
 	pdev->broken_parity_status = !!val;
@@ -188,7 +188,7 @@ static ssize_t is_enabled_store(struct d
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	unsigned long val;
-	ssize_t result = strict_strtoul(buf, 0, &val);
+	ssize_t result = kstrtoul(buf, 0, &val);
 
 	if (result < 0)
 		return result;
@@ -259,7 +259,7 @@ msi_bus_store(struct device *dev, struct
 	struct pci_dev *pdev = to_pci_dev(dev);
 	unsigned long val;
 
-	if (strict_strtoul(buf, 0, &val) < 0)
+	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
 	/* bad things may happen if the no_msi flag is changed
@@ -291,7 +291,7 @@ static ssize_t bus_rescan_store(struct b
 	unsigned long val;
 	struct pci_bus *b = NULL;
 
-	if (strict_strtoul(buf, 0, &val) < 0)
+	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
 	if (val) {
@@ -315,7 +315,7 @@ dev_rescan_store(struct device *dev, str
 	unsigned long val;
 	struct pci_dev *pdev = to_pci_dev(dev);
 
-	if (strict_strtoul(buf, 0, &val) < 0)
+	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
 	if (val) {
@@ -325,6 +325,8 @@ dev_rescan_store(struct device *dev, str
 	}
 	return count;
 }
+struct device_attribute dev_rescan_attr = __ATTR(rescan, (S_IWUSR|S_IWGRP),
+						 NULL, dev_rescan_store);
 
 static void remove_callback(struct device *dev)
 {
@@ -342,7 +344,7 @@ remove_store(struct device *dev, struct
 	int ret = 0;
 	unsigned long val;
 
-	if (strict_strtoul(buf, 0, &val) < 0)
+	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
 	/* An attribute cannot be unregistered by one of its own methods,
@@ -354,6 +356,8 @@ remove_store(struct device *dev, struct
 		count = ret;
 	return count;
 }
+struct device_attribute dev_remove_attr = __ATTR(remove, (S_IWUSR|S_IWGRP),
+						 NULL, remove_store);
 
 static ssize_t
 dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
@@ -362,7 +366,7 @@ dev_bus_rescan_store(struct device *dev,
 	unsigned long val;
 	struct pci_bus *bus = to_pci_bus(dev);
 
-	if (strict_strtoul(buf, 0, &val) < 0)
+	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
 	if (val) {
@@ -384,7 +388,7 @@ static ssize_t d3cold_allowed_store(stru
 	struct pci_dev *pdev = to_pci_dev(dev);
 	unsigned long val;
 
-	if (strict_strtoul(buf, 0, &val) < 0)
+	if (kstrtoul(buf, 0, &val) < 0)
 		return -EINVAL;
 
 	pdev->d3cold_allowed = !!val;
@@ -504,8 +508,6 @@ struct device_attribute pci_dev_attrs[]
 	__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
 		broken_parity_status_show,broken_parity_status_store),
 	__ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
-	__ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
-	__ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
 #if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI)
 	__ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store),
 #endif
@@ -1236,7 +1238,7 @@ static ssize_t reset_store(struct device
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	unsigned long val;
-	ssize_t result = strict_strtoul(buf, 0, &val);
+	ssize_t result = kstrtoul(buf, 0, &val);
 
 	if (result < 0)
 		return result;
@@ -1463,6 +1465,29 @@ static umode_t pci_dev_attrs_are_visible
 	return a->mode;
 }
 
+static struct attribute *pci_dev_hp_attrs[] = {
+	&dev_remove_attr.attr,
+	&dev_rescan_attr.attr,
+	NULL,
+};
+
+static umode_t pci_dev_hp_attrs_are_visible(struct kobject *kobj,
+						struct attribute *a, int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	if (pdev->is_virtfn)
+		return 0;
+
+	return a->mode;
+}
+
+static struct attribute_group pci_dev_hp_attr_group = {
+	.attrs = pci_dev_hp_attrs,
+	.is_visible = pci_dev_hp_attrs_are_visible,
+};
+
 #ifdef CONFIG_PCI_IOV
 static struct attribute *sriov_dev_attrs[] = {
 	&sriov_totalvfs_attr.attr,
@@ -1494,6 +1519,7 @@ static struct attribute_group pci_dev_at
 
 static const struct attribute_group *pci_dev_attr_groups[] = {
 	&pci_dev_attr_group,
+	&pci_dev_hp_attr_group,
 #ifdef CONFIG_PCI_IOV
 	&sriov_dev_attr_group,
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/probe.c linux-libre-3.11-rc7-gnu/drivers/pci/probe.c
--- linux-libre-3.10-gnu/drivers/pci/probe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/probe.c	2013-08-25 20:43:22.000000000 -0400
@@ -170,7 +170,7 @@ int __pci_read_base(struct pci_dev *dev,
 {
 	u32 l, sz, mask;
 	u16 orig_cmd;
-	struct pci_bus_region region;
+	struct pci_bus_region region, inverted_region;
 	bool bar_too_big = false, bar_disabled = false;
 
 	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
@@ -250,12 +250,10 @@ int __pci_read_base(struct pci_dev *dev,
 			pci_write_config_dword(dev, pos + 4, 0);
 			region.start = 0;
 			region.end = sz64;
-			pcibios_bus_to_resource(dev, res, &region);
 			bar_disabled = true;
 		} else {
 			region.start = l64;
 			region.end = l64 + sz64;
-			pcibios_bus_to_resource(dev, res, &region);
 		}
 	} else {
 		sz = pci_size(l, sz, mask);
@@ -265,7 +263,28 @@ int __pci_read_base(struct pci_dev *dev,
 
 		region.start = l;
 		region.end = l + sz;
-		pcibios_bus_to_resource(dev, res, &region);
+	}
+
+	pcibios_bus_to_resource(dev, res, &region);
+	pcibios_resource_to_bus(dev, &inverted_region, res);
+
+	/*
+	 * If "A" is a BAR value (a bus address), "bus_to_resource(A)" is
+	 * the corresponding resource address (the physical address used by
+	 * the CPU.  Converting that resource address back to a bus address
+	 * should yield the original BAR value:
+	 *
+	 *     resource_to_bus(bus_to_resource(A)) == A
+	 *
+	 * If it doesn't, CPU accesses to "bus_to_resource(A)" will not
+	 * be claimed by the device.
+	 */
+	if (inverted_region.start != region.start) {
+		dev_info(&dev->dev, "reg 0x%x: initial BAR value %pa invalid; forcing reassignment\n",
+			 pos, &region.start);
+		res->flags |= IORESOURCE_UNSET;
+		res->end -= res->start;
+		res->start = 0;
 	}
 
 	goto out;
@@ -278,9 +297,9 @@ out:
 		pci_write_config_word(dev, PCI_COMMAND, orig_cmd);
 
 	if (bar_too_big)
-		dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", pos);
+		dev_err(&dev->dev, "reg 0x%x: can't handle 64-bit BAR\n", pos);
 	if (res->flags && !bar_disabled)
-		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);
+		dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res);
 
 	return (res->flags & IORESOURCE_MEM_64) ? 1 : 0;
 }
@@ -451,33 +470,46 @@ void pci_read_bridge_bases(struct pci_bu
 	}
 }
 
-static struct pci_bus * pci_alloc_bus(void)
+static struct pci_bus *pci_alloc_bus(void)
 {
 	struct pci_bus *b;
 
 	b = kzalloc(sizeof(*b), GFP_KERNEL);
-	if (b) {
-		INIT_LIST_HEAD(&b->node);
-		INIT_LIST_HEAD(&b->children);
-		INIT_LIST_HEAD(&b->devices);
-		INIT_LIST_HEAD(&b->slots);
-		INIT_LIST_HEAD(&b->resources);
-		b->max_bus_speed = PCI_SPEED_UNKNOWN;
-		b->cur_bus_speed = PCI_SPEED_UNKNOWN;
-	}
+	if (!b)
+		return NULL;
+
+	INIT_LIST_HEAD(&b->node);
+	INIT_LIST_HEAD(&b->children);
+	INIT_LIST_HEAD(&b->devices);
+	INIT_LIST_HEAD(&b->slots);
+	INIT_LIST_HEAD(&b->resources);
+	b->max_bus_speed = PCI_SPEED_UNKNOWN;
+	b->cur_bus_speed = PCI_SPEED_UNKNOWN;
 	return b;
 }
 
+static void pci_release_host_bridge_dev(struct device *dev)
+{
+	struct pci_host_bridge *bridge = to_pci_host_bridge(dev);
+
+	if (bridge->release_fn)
+		bridge->release_fn(bridge);
+
+	pci_free_resource_list(&bridge->windows);
+
+	kfree(bridge);
+}
+
 static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
 {
 	struct pci_host_bridge *bridge;
 
 	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
-	if (bridge) {
-		INIT_LIST_HEAD(&bridge->windows);
-		bridge->bus = b;
-	}
+	if (!bridge)
+		return NULL;
 
+	INIT_LIST_HEAD(&bridge->windows);
+	bridge->bus = b;
 	return bridge;
 }
 
@@ -1132,6 +1164,8 @@ static void pci_release_dev(struct devic
 	pci_dev = to_pci_dev(dev);
 	pci_release_capabilities(pci_dev);
 	pci_release_of_node(pci_dev);
+	pcibios_release_device(pci_dev);
+	pci_bus_put(pci_dev->bus);
 	kfree(pci_dev);
 }
 
@@ -1188,19 +1222,7 @@ int pci_cfg_space_size(struct pci_dev *d
 	return PCI_CFG_SPACE_SIZE;
 }
 
-static void pci_release_bus_bridge_dev(struct device *dev)
-{
-	struct pci_host_bridge *bridge = to_pci_host_bridge(dev);
-
-	if (bridge->release_fn)
-		bridge->release_fn(bridge);
-
-	pci_free_resource_list(&bridge->windows);
-
-	kfree(bridge);
-}
-
-struct pci_dev *alloc_pci_dev(void)
+struct pci_dev *pci_alloc_dev(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
 
@@ -1210,9 +1232,16 @@ struct pci_dev *alloc_pci_dev(void)
 
 	INIT_LIST_HEAD(&dev->bus_list);
 	dev->dev.type = &pci_dev_type;
+	dev->bus = pci_bus_get(bus);
 
 	return dev;
 }
+EXPORT_SYMBOL(pci_alloc_dev);
+
+struct pci_dev *alloc_pci_dev(void)
+{
+	return pci_alloc_dev(NULL);
+}
 EXPORT_SYMBOL(alloc_pci_dev);
 
 bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
@@ -1263,11 +1292,10 @@ static struct pci_dev *pci_scan_device(s
 	if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000))
 		return NULL;
 
-	dev = alloc_pci_dev();
+	dev = pci_alloc_dev(bus);
 	if (!dev)
 		return NULL;
 
-	dev->bus = bus;
 	dev->devfn = devfn;
 	dev->vendor = l & 0xffff;
 	dev->device = (l >> 16) & 0xffff;
@@ -1275,6 +1303,7 @@ static struct pci_dev *pci_scan_device(s
 	pci_set_of_node(dev);
 
 	if (pci_setup_device(dev)) {
+		pci_bus_put(dev->bus);
 		kfree(dev);
 		return NULL;
 	}
@@ -1700,15 +1729,19 @@ struct pci_bus *pci_create_root_bus(stru
 		goto err_out;
 
 	bridge->dev.parent = parent;
-	bridge->dev.release = pci_release_bus_bridge_dev;
+	bridge->dev.release = pci_release_host_bridge_dev;
 	dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
 	error = pcibios_root_bridge_prepare(bridge);
-	if (error)
-		goto bridge_dev_reg_err;
+	if (error) {
+		kfree(bridge);
+		goto err_out;
+	}
 
 	error = device_register(&bridge->dev);
-	if (error)
-		goto bridge_dev_reg_err;
+	if (error) {
+		put_device(&bridge->dev);
+		goto err_out;
+	}
 	b->bridge = get_device(&bridge->dev);
 	device_enable_async_suspend(b->bridge);
 	pci_set_bus_of_node(b);
@@ -1764,8 +1797,6 @@ struct pci_bus *pci_create_root_bus(stru
 class_dev_reg_err:
 	put_device(&bridge->dev);
 	device_unregister(&bridge->dev);
-bridge_dev_reg_err:
-	kfree(bridge);
 err_out:
 	kfree(b);
 	return NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/proc.c linux-libre-3.11-rc7-gnu/drivers/pci/proc.c
--- linux-libre-3.10-gnu/drivers/pci/proc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/proc.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,27 +20,8 @@ static int proc_initialized;	/* = 0 */
 static loff_t
 proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
 {
-	loff_t new = -1;
-	struct inode *inode = file_inode(file);
-
-	mutex_lock(&inode->i_mutex);
-	switch (whence) {
-	case 0:
-		new = off;
-		break;
-	case 1:
-		new = file->f_pos + off;
-		break;
-	case 2:
-		new = inode->i_size + off;
-		break;
-	}
-	if (new < 0 || new > inode->i_size)
-		new = -EINVAL;
-	else
-		file->f_pos = new;
-	mutex_unlock(&inode->i_mutex);
-	return new;
+	struct pci_dev *dev = PDE_DATA(file_inode(file));
+	return fixed_size_llseek(file, off, whence, dev->cfg_size);
 }
 
 static ssize_t
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/quirks.c linux-libre-3.11-rc7-gnu/drivers/pci/quirks.c
--- linux-libre-3.10-gnu/drivers/pci/quirks.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/quirks.c	2013-08-25 20:43:22.000000000 -0400
@@ -1022,6 +1022,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_A
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x7900, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, 0x7900, quirk_amd_ide_mode);
 
 /*
  *	Serverworks CSB5 IDE does not fully support native mode
@@ -1832,7 +1834,6 @@ static void quirk_e100_interrupt(struct
 	u16 command, pmcsr;
 	u8 __iomem *csr;
 	u8 cmd_hi;
-	int pm;
 
 	switch (dev->device) {
 	/* PCI IDs taken from drivers/net/e100.c */
@@ -1870,9 +1871,8 @@ static void quirk_e100_interrupt(struct
 	 * Check that the device is in the D0 power state. If it's not,
 	 * there is no point to look any further.
 	 */
-	pm = pci_find_capability(dev, PCI_CAP_ID_PM);
-	if (pm) {
-		pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
+	if (dev->pm_cap) {
+		pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
 		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0)
 			return;
 	}
@@ -2865,6 +2865,31 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata);
 
 
+/*
+ * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum.  To
+ * work around this, query the size it should be configured to by the device and
+ * modify the resource end to correspond to this new size.
+ */
+static void quirk_intel_ntb(struct pci_dev *dev)
+{
+	int rc;
+	u8 val;
+
+	rc = pci_read_config_byte(dev, 0x00D0, &val);
+	if (rc)
+		return;
+
+	dev->resource[2].end = dev->resource[2].start + ((u64) 1 << val) - 1;
+
+	rc = pci_read_config_byte(dev, 0x00D1, &val);
+	if (rc)
+		return;
+
+	dev->resource[4].end = dev->resource[4].start + ((u64) 1 << val) - 1;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb);
+
 static ktime_t fixup_debug_start(struct pci_dev *dev,
 				 void (*fn)(struct pci_dev *dev))
 {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/setup-bus.c linux-libre-3.11-rc7-gnu/drivers/pci/setup-bus.c
--- linux-libre-3.10-gnu/drivers/pci/setup-bus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/setup-bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -300,6 +300,47 @@ static void assign_requested_resources_s
 	}
 }
 
+static unsigned long pci_fail_res_type_mask(struct list_head *fail_head)
+{
+	struct pci_dev_resource *fail_res;
+	unsigned long mask = 0;
+
+	/* check failed type */
+	list_for_each_entry(fail_res, fail_head, list)
+		mask |= fail_res->flags;
+
+	/*
+	 * one pref failed resource will set IORESOURCE_MEM,
+	 * as we can allocate pref in non-pref range.
+	 * Will release all assigned non-pref sibling resources
+	 * according to that bit.
+	 */
+	return mask & (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH);
+}
+
+static bool pci_need_to_release(unsigned long mask, struct resource *res)
+{
+	if (res->flags & IORESOURCE_IO)
+		return !!(mask & IORESOURCE_IO);
+
+	/* check pref at first */
+	if (res->flags & IORESOURCE_PREFETCH) {
+		if (mask & IORESOURCE_PREFETCH)
+			return true;
+		/* count pref if its parent is non-pref */
+		else if ((mask & IORESOURCE_MEM) &&
+			 !(res->parent->flags & IORESOURCE_PREFETCH))
+			return true;
+		else
+			return false;
+	}
+
+	if (res->flags & IORESOURCE_MEM)
+		return !!(mask & IORESOURCE_MEM);
+
+	return false;	/* should not get here */
+}
+
 static void __assign_resources_sorted(struct list_head *head,
 				 struct list_head *realloc_head,
 				 struct list_head *fail_head)
@@ -312,11 +353,24 @@ static void __assign_resources_sorted(st
 	 *  if could do that, could get out early.
 	 *  if could not do that, we still try to assign requested at first,
 	 *    then try to reassign add_size for some resources.
+	 *
+	 * Separate three resource type checking if we need to release
+	 * assigned resource after requested + add_size try.
+	 *	1. if there is io port assign fail, will release assigned
+	 *	   io port.
+	 *	2. if there is pref mmio assign fail, release assigned
+	 *	   pref mmio.
+	 *	   if assigned pref mmio's parent is non-pref mmio and there
+	 *	   is non-pref mmio assign fail, will release that assigned
+	 *	   pref mmio.
+	 *	3. if there is non-pref mmio assign fail or pref mmio
+	 *	   assigned fail, will release assigned non-pref mmio.
 	 */
 	LIST_HEAD(save_head);
 	LIST_HEAD(local_fail_head);
 	struct pci_dev_resource *save_res;
-	struct pci_dev_resource *dev_res;
+	struct pci_dev_resource *dev_res, *tmp_res;
+	unsigned long fail_type;
 
 	/* Check if optional add_size is there */
 	if (!realloc_head || list_empty(realloc_head))
@@ -348,6 +402,19 @@ static void __assign_resources_sorted(st
 		return;
 	}
 
+	/* check failed type */
+	fail_type = pci_fail_res_type_mask(&local_fail_head);
+	/* remove not need to be released assigned res from head list etc */
+	list_for_each_entry_safe(dev_res, tmp_res, head, list)
+		if (dev_res->res->parent &&
+		    !pci_need_to_release(fail_type, dev_res->res)) {
+			/* remove it from realloc_head list */
+			remove_from_list(realloc_head, dev_res->res);
+			remove_from_list(&save_head, dev_res->res);
+			list_del(&dev_res->list);
+			kfree(dev_res);
+		}
+
 	free_list(&local_fail_head);
 	/* Release assigned resource */
 	list_for_each_entry(dev_res, head, list)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pci/xen-pcifront.c linux-libre-3.11-rc7-gnu/drivers/pci/xen-pcifront.c
--- linux-libre-3.10-gnu/drivers/pci/xen-pcifront.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pci/xen-pcifront.c	2013-08-25 20:43:22.000000000 -0400
@@ -678,10 +678,9 @@ static int pcifront_connect_and_init_dma
 	if (!pcifront_dev) {
 		dev_info(&pdev->xdev->dev, "Installing PCI frontend\n");
 		pcifront_dev = pdev;
-	} else {
-		dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n");
+	} else
 		err = -EEXIST;
-	}
+
 	spin_unlock(&pcifront_dev_lock);
 
 	if (!err && !swiotlb_nr_tbl()) {
@@ -848,7 +847,7 @@ static int pcifront_try_connect(struct p
 		goto out;
 
 	err = pcifront_connect_and_init_dma(pdev);
-	if (err) {
+	if (err && err != -EEXIST) {
 		xenbus_dev_fatal(pdev->xdev, err,
 				 "Error setting up PCI Frontend");
 		goto out;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pcmcia/at91_cf.c linux-libre-3.11-rc7-gnu/drivers/pcmcia/at91_cf.c
--- linux-libre-3.10-gnu/drivers/pcmcia/at91_cf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pcmcia/at91_cf.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,13 +18,14 @@
 #include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/platform_data/atmel.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 
 #include <pcmcia/ss.h>
 
-#include <mach/hardware.h>
-#include <asm/io.h>
-#include <asm/sizes.h>
-
 #include <mach/at91rm9200_mc.h>
 #include <mach/at91_ramc.h>
 
@@ -41,8 +42,6 @@
 
 /*--------------------------------------------------------------------------*/
 
-static const char driver_name[] = "at91_cf";
-
 struct at91_cf_socket {
 	struct pcmcia_socket	socket;
 
@@ -76,7 +75,7 @@ static irqreturn_t at91_cf_irq(int irq,
 		/* kick pccard as needed */
 		if (present != cf->present) {
 			cf->present = present;
-			pr_debug("%s: card %s\n", driver_name,
+			dev_dbg(&cf->pdev->dev, "card %s\n",
 					present ? "present" : "gone");
 			pcmcia_parse_events(&cf->socket, SS_DETECT);
 		}
@@ -100,9 +99,9 @@ static int at91_cf_get_status(struct pcm
 		int vcc	= gpio_is_valid(cf->board->vcc_pin);
 
 		*sp = SS_DETECT | SS_3VCARD;
-		if (!rdy || gpio_get_value(rdy))
+		if (!rdy || gpio_get_value(cf->board->irq_pin))
 			*sp |= SS_READY;
-		if (!vcc || gpio_get_value(vcc))
+		if (!vcc || gpio_get_value(cf->board->vcc_pin))
 			*sp |= SS_POWERON;
 	} else
 		*sp = 0;
@@ -120,22 +119,22 @@ at91_cf_set_socket(struct pcmcia_socket
 	/* switch Vcc if needed and possible */
 	if (gpio_is_valid(cf->board->vcc_pin)) {
 		switch (s->Vcc) {
-			case 0:
-				gpio_set_value(cf->board->vcc_pin, 0);
-				break;
-			case 33:
-				gpio_set_value(cf->board->vcc_pin, 1);
-				break;
-			default:
-				return -EINVAL;
+		case 0:
+			gpio_set_value(cf->board->vcc_pin, 0);
+			break;
+		case 33:
+			gpio_set_value(cf->board->vcc_pin, 1);
+			break;
+		default:
+			return -EINVAL;
 		}
 	}
 
 	/* toggle reset if needed */
 	gpio_set_value(cf->board->rst_pin, s->flags & SS_RESET);
 
-	pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
-		driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask);
+	dev_dbg(&cf->pdev->dev, "Vcc %d, io_irq %d, flags %04x csc %04x\n",
+				s->Vcc, s->io_irq, s->flags, s->csc_mask);
 
 	return 0;
 }
@@ -171,10 +170,10 @@ static int at91_cf_set_io_map(struct pcm
 	 */
 	if (!(io->flags & (MAP_16BIT | MAP_AUTOSZ))) {
 		csr |= AT91_SMC_DBW_8;
-		pr_debug("%s: 8bit i/o bus\n", driver_name);
+		dev_dbg(&cf->pdev->dev, "8bit i/o bus\n");
 	} else {
 		csr |= AT91_SMC_DBW_16;
-		pr_debug("%s: 16bit i/o bus\n", driver_name);
+		dev_dbg(&cf->pdev->dev, "16bit i/o bus\n");
 	}
 	at91_ramc_write(0, AT91_SMC_CSR(cf->board->chipselect), csr);
 
@@ -215,6 +214,37 @@ static struct pccard_operations at91_cf_
 
 /*--------------------------------------------------------------------------*/
 
+#if defined(CONFIG_OF)
+static const struct of_device_id at91_cf_dt_ids[] = {
+	{ .compatible = "atmel,at91rm9200-cf" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, at91_cf_dt_ids);
+
+static int at91_cf_dt_init(struct platform_device *pdev)
+{
+	struct at91_cf_data *board;
+
+	board = devm_kzalloc(&pdev->dev, sizeof(*board), GFP_KERNEL);
+	if (!board)
+		return -ENOMEM;
+
+	board->irq_pin = of_get_gpio(pdev->dev.of_node, 0);
+	board->det_pin = of_get_gpio(pdev->dev.of_node, 1);
+	board->vcc_pin = of_get_gpio(pdev->dev.of_node, 2);
+	board->rst_pin = of_get_gpio(pdev->dev.of_node, 3);
+
+	pdev->dev.platform_data = board;
+
+	return 0;
+}
+#else
+static int at91_cf_dt_init(struct platform_device *pdev)
+{
+	return -ENODEV;
+}
+#endif
+
 static int __init at91_cf_probe(struct platform_device *pdev)
 {
 	struct at91_cf_socket	*cf;
@@ -222,14 +252,22 @@ static int __init at91_cf_probe(struct p
 	struct resource		*io;
 	int			status;
 
-	if (!board || !gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin))
+	if (!board) {
+		status = at91_cf_dt_init(pdev);
+		if (status)
+			return status;
+
+		board = pdev->dev.platform_data;
+	}
+
+	if (!gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin))
 		return -ENODEV;
 
 	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!io)
 		return -ENODEV;
 
-	cf = kzalloc(sizeof *cf, GFP_KERNEL);
+	cf = devm_kzalloc(&pdev->dev, sizeof(*cf), GFP_KERNEL);
 	if (!cf)
 		return -ENOMEM;
 
@@ -239,22 +277,25 @@ static int __init at91_cf_probe(struct p
 	platform_set_drvdata(pdev, cf);
 
 	/* must be a GPIO; ergo must trigger on both edges */
-	status = gpio_request(board->det_pin, "cf_det");
+	status = devm_gpio_request(&pdev->dev, board->det_pin, "cf_det");
 	if (status < 0)
-		goto fail0;
-	status = request_irq(gpio_to_irq(board->det_pin), at91_cf_irq, 0, driver_name, cf);
+		return status;
+
+	status = devm_request_irq(&pdev->dev, gpio_to_irq(board->det_pin),
+					at91_cf_irq, 0, "at91_cf detect", cf);
 	if (status < 0)
-		goto fail00;
+		return status;
+
 	device_init_wakeup(&pdev->dev, 1);
 
-	status = gpio_request(board->rst_pin, "cf_rst");
+	status = devm_gpio_request(&pdev->dev, board->rst_pin, "cf_rst");
 	if (status < 0)
 		goto fail0a;
 
 	if (gpio_is_valid(board->vcc_pin)) {
-		status = gpio_request(board->vcc_pin, "cf_vcc");
+		status = devm_gpio_request(&pdev->dev, board->vcc_pin, "cf_vcc");
 		if (status < 0)
-			goto fail0b;
+			goto fail0a;
 	}
 
 	/*
@@ -264,32 +305,33 @@ static int __init at91_cf_probe(struct p
 	 * (Note:  DK board doesn't wire the IRQ pin...)
 	 */
 	if (gpio_is_valid(board->irq_pin)) {
-		status = gpio_request(board->irq_pin, "cf_irq");
+		status = devm_gpio_request(&pdev->dev, board->irq_pin, "cf_irq");
 		if (status < 0)
-			goto fail0c;
-		status = request_irq(gpio_to_irq(board->irq_pin), at91_cf_irq,
-				IRQF_SHARED, driver_name, cf);
+			goto fail0a;
+
+		status = devm_request_irq(&pdev->dev, gpio_to_irq(board->irq_pin),
+					at91_cf_irq, IRQF_SHARED, "at91_cf", cf);
 		if (status < 0)
-			goto fail0d;
+			goto fail0a;
 		cf->socket.pci_irq = gpio_to_irq(board->irq_pin);
 	} else
 		cf->socket.pci_irq = nr_irqs + 1;
 
 	/* pcmcia layer only remaps "real" memory not iospace */
-	cf->socket.io_offset = (unsigned long)
-			ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K);
+	cf->socket.io_offset = (unsigned long) devm_ioremap(&pdev->dev,
+					cf->phys_baseaddr + CF_IO_PHYS, SZ_2K);
 	if (!cf->socket.io_offset) {
 		status = -ENXIO;
-		goto fail1;
+		goto fail0a;
 	}
 
 	/* reserve chip-select regions */
-	if (!request_mem_region(io->start, resource_size(io), driver_name)) {
+	if (!devm_request_mem_region(&pdev->dev, io->start, resource_size(io), "at91_cf")) {
 		status = -ENXIO;
-		goto fail1;
+		goto fail0a;
 	}
 
-	pr_info("%s: irqs det #%d, io #%d\n", driver_name,
+	dev_info(&pdev->dev, "irqs det #%d, io #%d\n",
 		gpio_to_irq(board->det_pin), gpio_to_irq(board->irq_pin));
 
 	cf->socket.owner = THIS_MODULE;
@@ -303,55 +345,22 @@ static int __init at91_cf_probe(struct p
 
 	status = pcmcia_register_socket(&cf->socket);
 	if (status < 0)
-		goto fail2;
+		goto fail0a;
 
 	return 0;
 
-fail2:
-	release_mem_region(io->start, resource_size(io));
-fail1:
-	if (cf->socket.io_offset)
-		iounmap((void __iomem *) cf->socket.io_offset);
-	if (gpio_is_valid(board->irq_pin)) {
-		free_irq(gpio_to_irq(board->irq_pin), cf);
-fail0d:
-		gpio_free(board->irq_pin);
-	}
-fail0c:
-	if (gpio_is_valid(board->vcc_pin))
-		gpio_free(board->vcc_pin);
-fail0b:
-	gpio_free(board->rst_pin);
 fail0a:
 	device_init_wakeup(&pdev->dev, 0);
-	free_irq(gpio_to_irq(board->det_pin), cf);
-fail00:
-	gpio_free(board->det_pin);
-fail0:
-	kfree(cf);
 	return status;
 }
 
 static int __exit at91_cf_remove(struct platform_device *pdev)
 {
 	struct at91_cf_socket	*cf = platform_get_drvdata(pdev);
-	struct at91_cf_data	*board = cf->board;
-	struct resource		*io = cf->socket.io[0].res;
 
 	pcmcia_unregister_socket(&cf->socket);
-	release_mem_region(io->start, resource_size(io));
-	iounmap((void __iomem *) cf->socket.io_offset);
-	if (gpio_is_valid(board->irq_pin)) {
-		free_irq(gpio_to_irq(board->irq_pin), cf);
-		gpio_free(board->irq_pin);
-	}
-	if (gpio_is_valid(board->vcc_pin))
-		gpio_free(board->vcc_pin);
-	gpio_free(board->rst_pin);
 	device_init_wakeup(&pdev->dev, 0);
-	free_irq(gpio_to_irq(board->det_pin), cf);
-	gpio_free(board->det_pin);
-	kfree(cf);
+
 	return 0;
 }
 
@@ -391,8 +400,9 @@ static int at91_cf_resume(struct platfor
 
 static struct platform_driver at91_cf_driver = {
 	.driver = {
-		.name		= (char *) driver_name,
+		.name		= "at91_cf",
 		.owner		= THIS_MODULE,
+		.of_match_table = of_match_ptr(at91_cf_dt_ids),
 	},
 	.remove		= __exit_p(at91_cf_remove),
 	.suspend	= at91_cf_suspend,
@@ -401,17 +411,7 @@ static struct platform_driver at91_cf_dr
 
 /*--------------------------------------------------------------------------*/
 
-static int __init at91_cf_init(void)
-{
-	return platform_driver_probe(&at91_cf_driver, at91_cf_probe);
-}
-module_init(at91_cf_init);
-
-static void __exit at91_cf_exit(void)
-{
-	platform_driver_unregister(&at91_cf_driver);
-}
-module_exit(at91_cf_exit);
+module_platform_driver_probe(at91_cf_driver, at91_cf_probe);
 
 MODULE_DESCRIPTION("AT91 Compact Flash Driver");
 MODULE_AUTHOR("David Brownell");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pcmcia/Kconfig linux-libre-3.11-rc7-gnu/drivers/pcmcia/Kconfig
--- linux-libre-3.10-gnu/drivers/pcmcia/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pcmcia/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,6 @@
 
 menuconfig PCCARD
 	tristate "PCCard (PCMCIA/CardBus) support"
-	depends on HOTPLUG
 	---help---
 	  Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
 	  computer.  These are credit-card size devices such as network cards,
@@ -243,7 +242,7 @@ config PCMCIA_DEBUG
 
 config PCMCIA_PROBE
 	bool
-	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
+	default y if ISA && !ARCH_SA1100 && !PARISC
 
 config M32R_PCC
 	bool "M32R PCMCIA I/F"
@@ -288,7 +287,7 @@ config BFIN_CFPCMCIA
 
 config AT91_CF
 	tristate "AT91 CompactFlash Controller"
-	depends on PCMCIA && ARCH_AT91RM9200
+	depends on PCMCIA && ARCH_AT91
 	help
 	  Say Y here to support the CompactFlash controller on AT91 chips.
 	  Or choose M to compile the driver as a module named "at91_cf".
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pcmcia/pd6729.c linux-libre-3.11-rc7-gnu/drivers/pcmcia/pd6729.c
--- linux-libre-3.10-gnu/drivers/pcmcia/pd6729.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pcmcia/pd6729.c	2013-08-25 20:43:22.000000000 -0400
@@ -644,6 +644,7 @@ static int pd6729_pci_probe(struct pci_d
 	if (!pci_resource_start(dev, 0)) {
 		dev_warn(&dev->dev, "refusing to load the driver as the "
 			"io_base is NULL.\n");
+		ret = -ENOMEM;
 		goto err_out_disable;
 	}
 
@@ -673,6 +674,7 @@ static int pd6729_pci_probe(struct pci_d
 	mask = pd6729_isa_scan();
 	if (irq_mode == 0 && mask == 0) {
 		dev_warn(&dev->dev, "no ISA interrupt is available.\n");
+		ret = -ENODEV;
 		goto err_out_free_res;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/core.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/core.c
--- linux-libre-3.10-gnu/drivers/pinctrl/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -41,13 +41,13 @@
 static bool pinctrl_dummy_state;
 
 /* Mutex taken to protect pinctrl_list */
-DEFINE_MUTEX(pinctrl_list_mutex);
+static DEFINE_MUTEX(pinctrl_list_mutex);
 
 /* Mutex taken to protect pinctrl_maps */
 DEFINE_MUTEX(pinctrl_maps_mutex);
 
 /* Mutex taken to protect pinctrldev_list */
-DEFINE_MUTEX(pinctrldev_list_mutex);
+static DEFINE_MUTEX(pinctrldev_list_mutex);
 
 /* Global list of pin control devices (struct pinctrl_dev) */
 static LIST_HEAD(pinctrldev_list);
@@ -101,20 +101,23 @@ EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdat
 struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname)
 {
 	struct pinctrl_dev *pctldev = NULL;
-	bool found = false;
 
 	if (!devname)
 		return NULL;
 
+	mutex_lock(&pinctrldev_list_mutex);
+
 	list_for_each_entry(pctldev, &pinctrldev_list, node) {
 		if (!strcmp(dev_name(pctldev->dev), devname)) {
 			/* Matched on device name */
-			found = true;
-			break;
+			mutex_unlock(&pinctrldev_list_mutex);
+			return pctldev;
 		}
 	}
 
-	return found ? pctldev : NULL;
+	mutex_unlock(&pinctrldev_list_mutex);
+
+	return NULL;
 }
 
 struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np)
@@ -280,6 +283,29 @@ static int pinctrl_register_pins(struct
 }
 
 /**
+ * gpio_to_pin() - GPIO range GPIO number to pin number translation
+ * @range: GPIO range used for the translation
+ * @gpio: gpio pin to translate to a pin number
+ *
+ * Finds the pin number for a given GPIO using the specified GPIO range
+ * as a base for translation. The distinction between linear GPIO ranges
+ * and pin list based GPIO ranges is managed correctly by this function.
+ *
+ * This function assumes the gpio is part of the specified GPIO range, use
+ * only after making sure this is the case (e.g. by calling it on the
+ * result of successful pinctrl_get_device_gpio_range calls)!
+ */
+static inline int gpio_to_pin(struct pinctrl_gpio_range *range,
+				unsigned int gpio)
+{
+	unsigned int offset = gpio - range->base;
+	if (range->pins)
+		return range->pins[offset];
+	else
+		return range->pin_base + offset;
+}
+
+/**
  * pinctrl_match_gpio_range() - check if a certain GPIO pin is in range
  * @pctldev: pin controller device to check
  * @gpio: gpio pin to check taken from the global GPIO pin space
@@ -326,6 +352,8 @@ static bool pinctrl_ready_for_gpio_range
 	struct pinctrl_gpio_range *range = NULL;
 	struct gpio_chip *chip = gpio_to_chip(gpio);
 
+	mutex_lock(&pinctrldev_list_mutex);
+
 	/* Loop over the pin controllers */
 	list_for_each_entry(pctldev, &pinctrldev_list, node) {
 		/* Loop over the ranges */
@@ -334,9 +362,13 @@ static bool pinctrl_ready_for_gpio_range
 			if (range->base + range->npins - 1 < chip->base ||
 			    range->base > chip->base + chip->ngpio - 1)
 				continue;
+			mutex_unlock(&pinctrldev_list_mutex);
 			return true;
 		}
 	}
+
+	mutex_unlock(&pinctrldev_list_mutex);
+
 	return false;
 }
 #else
@@ -408,8 +440,6 @@ struct pinctrl_dev *pinctrl_find_and_add
 {
 	struct pinctrl_dev *pctldev;
 
-	mutex_lock(&pinctrldev_list_mutex);
-
 	pctldev = get_pinctrl_dev_from_devname(devname);
 
 	/*
@@ -418,13 +448,10 @@ struct pinctrl_dev *pinctrl_find_and_add
 	 * range need to defer probing.
 	 */
 	if (!pctldev) {
-		mutex_unlock(&pinctrldev_list_mutex);
 		return ERR_PTR(-EPROBE_DEFER);
 	}
 	pinctrl_add_gpio_range(pctldev, range);
 
-	mutex_unlock(&pinctrldev_list_mutex);
-
 	return pctldev;
 }
 EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range);
@@ -438,21 +465,26 @@ struct pinctrl_gpio_range *
 pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev,
 				 unsigned int pin)
 {
-	struct pinctrl_gpio_range *range = NULL;
+	struct pinctrl_gpio_range *range;
 
 	mutex_lock(&pctldev->mutex);
 	/* Loop over the ranges */
 	list_for_each_entry(range, &pctldev->gpio_ranges, node) {
 		/* Check if we're in the valid range */
-		if (pin >= range->pin_base &&
-		    pin < range->pin_base + range->npins) {
-			mutex_unlock(&pctldev->mutex);
-			return range;
-		}
+		if (range->pins) {
+			int a;
+			for (a = 0; a < range->npins; a++) {
+				if (range->pins[a] == pin)
+					goto out;
+			}
+		} else if (pin >= range->pin_base &&
+			   pin < range->pin_base + range->npins)
+			goto out;
 	}
+	range = NULL;
+out:
 	mutex_unlock(&pctldev->mutex);
-
-	return NULL;
+	return range;
 }
 EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin);
 
@@ -517,22 +549,18 @@ int pinctrl_request_gpio(unsigned gpio)
 	int ret;
 	int pin;
 
-	mutex_lock(&pinctrldev_list_mutex);
-
 	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
 	if (ret) {
 		if (pinctrl_ready_for_gpio_range(gpio))
 			ret = 0;
-		mutex_unlock(&pinctrldev_list_mutex);
 		return ret;
 	}
 
 	/* Convert to the pin controllers number space */
-	pin = gpio - range->base + range->pin_base;
+	pin = gpio_to_pin(range, gpio);
 
 	ret = pinmux_request_gpio(pctldev, range, pin, gpio);
 
-	mutex_unlock(&pinctrldev_list_mutex);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(pinctrl_request_gpio);
@@ -552,22 +580,18 @@ void pinctrl_free_gpio(unsigned gpio)
 	int ret;
 	int pin;
 
-	mutex_lock(&pinctrldev_list_mutex);
-
 	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
 	if (ret) {
-		mutex_unlock(&pinctrldev_list_mutex);
 		return;
 	}
 	mutex_lock(&pctldev->mutex);
 
 	/* Convert to the pin controllers number space */
-	pin = gpio - range->base + range->pin_base;
+	pin = gpio_to_pin(range, gpio);
 
 	pinmux_free_gpio(pctldev, pin, range);
 
 	mutex_unlock(&pctldev->mutex);
-	mutex_unlock(&pinctrldev_list_mutex);
 }
 EXPORT_SYMBOL_GPL(pinctrl_free_gpio);
 
@@ -578,22 +602,18 @@ static int pinctrl_gpio_direction(unsign
 	int ret;
 	int pin;
 
-	mutex_lock(&pinctrldev_list_mutex);
-
 	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
 	if (ret) {
-		mutex_unlock(&pinctrldev_list_mutex);
 		return ret;
 	}
 
 	mutex_lock(&pctldev->mutex);
 
 	/* Convert to the pin controllers number space */
-	pin = gpio - range->base + range->pin_base;
+	pin = gpio_to_pin(range, gpio);
 	ret = pinmux_gpio_direction(pctldev, range, pin, input);
 
 	mutex_unlock(&pctldev->mutex);
-	mutex_unlock(&pinctrldev_list_mutex);
 
 	return ret;
 }
@@ -1173,6 +1193,7 @@ void pinctrl_unregister_map(struct pinct
 	list_for_each_entry(maps_node, &pinctrl_maps, node) {
 		if (maps_node->maps == map) {
 			list_del(&maps_node->node);
+			kfree(maps_node);
 			mutex_unlock(&pinctrl_maps_mutex);
 			return;
 		}
@@ -1204,6 +1225,69 @@ int pinctrl_force_default(struct pinctrl
 }
 EXPORT_SYMBOL_GPL(pinctrl_force_default);
 
+#ifdef CONFIG_PM
+
+/**
+ * pinctrl_pm_select_default_state() - select default pinctrl state for PM
+ * @dev: device to select default state for
+ */
+int pinctrl_pm_select_default_state(struct device *dev)
+{
+	struct dev_pin_info *pins = dev->pins;
+	int ret;
+
+	if (!pins)
+		return 0;
+	if (IS_ERR(pins->default_state))
+		return 0; /* No default state */
+	ret = pinctrl_select_state(pins->p, pins->default_state);
+	if (ret)
+		dev_err(dev, "failed to activate default pinctrl state\n");
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pinctrl_pm_select_default_state);
+
+/**
+ * pinctrl_pm_select_sleep_state() - select sleep pinctrl state for PM
+ * @dev: device to select sleep state for
+ */
+int pinctrl_pm_select_sleep_state(struct device *dev)
+{
+	struct dev_pin_info *pins = dev->pins;
+	int ret;
+
+	if (!pins)
+		return 0;
+	if (IS_ERR(pins->sleep_state))
+		return 0; /* No sleep state */
+	ret = pinctrl_select_state(pins->p, pins->sleep_state);
+	if (ret)
+		dev_err(dev, "failed to activate pinctrl sleep state\n");
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pinctrl_pm_select_sleep_state);
+
+/**
+ * pinctrl_pm_select_idle_state() - select idle pinctrl state for PM
+ * @dev: device to select idle state for
+ */
+int pinctrl_pm_select_idle_state(struct device *dev)
+{
+	struct dev_pin_info *pins = dev->pins;
+	int ret;
+
+	if (!pins)
+		return 0;
+	if (IS_ERR(pins->idle_state))
+		return 0; /* No idle state */
+	ret = pinctrl_select_state(pins->p, pins->idle_state);
+	if (ret)
+		dev_err(dev, "failed to activate pinctrl idle state\n");
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pinctrl_pm_select_idle_state);
+#endif
+
 #ifdef CONFIG_DEBUG_FS
 
 static int pinctrl_pins_show(struct seq_file *s, void *what)
@@ -1296,11 +1380,21 @@ static int pinctrl_gpioranges_show(struc
 
 	/* Loop over the ranges */
 	list_for_each_entry(range, &pctldev->gpio_ranges, node) {
-		seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n",
-			   range->id, range->name,
-			   range->base, (range->base + range->npins - 1),
-			   range->pin_base,
-			   (range->pin_base + range->npins - 1));
+		if (range->pins) {
+			int a;
+			seq_printf(s, "%u: %s GPIOS [%u - %u] PINS {",
+				range->id, range->name,
+				range->base, (range->base + range->npins - 1));
+			for (a = 0; a < range->npins - 1; a++)
+				seq_printf(s, "%u, ", range->pins[a]);
+			seq_printf(s, "%u}\n", range->pins[a]);
+		}
+		else
+			seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n",
+				range->id, range->name,
+				range->base, (range->base + range->npins - 1),
+				range->pin_base,
+				(range->pin_base + range->npins - 1));
 	}
 
 	mutex_unlock(&pctldev->mutex);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/Kconfig linux-libre-3.11-rc7-gnu/drivers/pinctrl/Kconfig
--- linux-libre-3.10-gnu/drivers/pinctrl/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -58,6 +58,18 @@ config PINCTRL_AT91
 	help
 	  Say Y here to enable the at91 pinctrl driver
 
+config PINCTRL_BAYTRAIL
+	bool "Intel Baytrail GPIO pin control"
+	depends on GPIOLIB && ACPI && X86
+        select IRQ_DOMAIN
+	help
+	  driver for memory mapped GPIO functionality on Intel Baytrail
+	  platforms. Supports 3 banks with 102, 28 and 44 gpios.
+	  Most pins are usually muxed to some other functionality by firmware,
+	  so only a small amount is available for gpio use.
+
+	  Requires ACPI device enumeration code to set up a platform device.
+
 config PINCTRL_BCM2835
 	bool
 	select PINMUX
@@ -108,6 +120,14 @@ config PINCTRL_IMX6SL
 	help
 	  Say Y here to enable the imx6sl pinctrl driver
 
+config PINCTRL_VF610
+	bool "Freescale Vybrid VF610 pinctrl driver"
+	depends on OF
+	depends on SOC_VF610
+	select PINCTRL_IMX
+	help
+	  Say Y here to enable the Freescale Vybrid VF610 pinctrl driver
+
 config PINCTRL_LANTIQ
 	bool
 	depends on LANTIQ
@@ -150,6 +170,12 @@ config PINCTRL_DB8540
 	bool "DB8540 pin controller driver"
 	depends on PINCTRL_NOMADIK && ARCH_U8500
 
+config PINCTRL_ROCKCHIP
+	bool
+	select PINMUX
+	select GENERIC_PINCONF
+	select GENERIC_IRQ_CHIP
+
 config PINCTRL_SINGLE
 	tristate "One-register-per-pin type device tree based pinctrl driver"
 	depends on OF
@@ -169,6 +195,12 @@ config PINCTRL_SUNXI
 	select PINMUX
 	select GENERIC_PINCONF
 
+config PINCTRL_ST
+	bool
+	depends on OF
+	select PINMUX
+	select PINCONF
+
 config PINCTRL_TEGRA
 	bool
 	select PINMUX
@@ -186,6 +218,18 @@ config PINCTRL_TEGRA114
 	bool
 	select PINCTRL_TEGRA
 
+config PINCTRL_TZ1090
+	bool "Toumaz Xenif TZ1090 pin control driver"
+	depends on SOC_TZ1090
+	select PINMUX
+	select GENERIC_PINCONF
+
+config PINCTRL_TZ1090_PDC
+	bool "Toumaz Xenif TZ1090 PDC pin control driver"
+	depends on SOC_TZ1090
+	select PINMUX
+	select PINCONF
+
 config PINCTRL_U300
 	bool "U300 pin controller driver"
 	depends on ARCH_U300
@@ -207,15 +251,21 @@ config PINCTRL_SAMSUNG
 	select PINCONF
 
 config PINCTRL_EXYNOS
-	bool "Pinctrl driver data for Samsung EXYNOS SoCs"
-	depends on OF && GPIOLIB
+	bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
+	depends on OF && GPIOLIB && ARCH_EXYNOS
 	select PINCTRL_SAMSUNG
 
 config PINCTRL_EXYNOS5440
 	bool "Samsung EXYNOS5440 SoC pinctrl driver"
+	depends on SOC_EXYNOS5440
 	select PINMUX
 	select PINCONF
 
+config PINCTRL_S3C24XX
+	bool "Samsung S3C24XX SoC pinctrl driver"
+	depends on ARCH_S3C24XX
+	select PINCTRL_SAMSUNG
+
 config PINCTRL_S3C64XX
 	bool "Samsung S3C64XX SoC pinctrl driver"
 	depends on ARCH_S3C64XX
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/Makefile linux-libre-3.11-rc7-gnu/drivers/pinctrl/Makefile
--- linux-libre-3.10-gnu/drivers/pinctrl/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -16,12 +16,14 @@ obj-$(CONFIG_PINCTRL_AB9540)	+= pinctrl-
 obj-$(CONFIG_PINCTRL_AB8505)	+= pinctrl-ab8505.o
 obj-$(CONFIG_PINCTRL_AT91)	+= pinctrl-at91.o
 obj-$(CONFIG_PINCTRL_BCM2835)	+= pinctrl-bcm2835.o
+obj-$(CONFIG_PINCTRL_BAYTRAIL)	+= pinctrl-baytrail.o
 obj-$(CONFIG_PINCTRL_IMX)	+= pinctrl-imx.o
 obj-$(CONFIG_PINCTRL_IMX35)	+= pinctrl-imx35.o
 obj-$(CONFIG_PINCTRL_IMX51)	+= pinctrl-imx51.o
 obj-$(CONFIG_PINCTRL_IMX53)	+= pinctrl-imx53.o
 obj-$(CONFIG_PINCTRL_IMX6Q)	+= pinctrl-imx6q.o
 obj-$(CONFIG_PINCTRL_IMX6Q)	+= pinctrl-imx6dl.o
+obj-$(CONFIG_PINCTRL_IMX6SL)	+= pinctrl-imx6sl.o
 obj-$(CONFIG_PINCTRL_FALCON)	+= pinctrl-falcon.o
 obj-$(CONFIG_PINCTRL_MXS)	+= pinctrl-mxs.o
 obj-$(CONFIG_PINCTRL_IMX23)	+= pinctrl-imx23.o
@@ -30,21 +32,27 @@ obj-$(CONFIG_PINCTRL_NOMADIK)	+= pinctrl
 obj-$(CONFIG_PINCTRL_STN8815)	+= pinctrl-nomadik-stn8815.o
 obj-$(CONFIG_PINCTRL_DB8500)	+= pinctrl-nomadik-db8500.o
 obj-$(CONFIG_PINCTRL_DB8540)	+= pinctrl-nomadik-db8540.o
+obj-$(CONFIG_PINCTRL_ROCKCHIP)	+= pinctrl-rockchip.o
 obj-$(CONFIG_PINCTRL_SINGLE)	+= pinctrl-single.o
-obj-$(CONFIG_PINCTRL_SIRF)	+= pinctrl-sirf.o
+obj-$(CONFIG_PINCTRL_SIRF)	+= sirf/
 obj-$(CONFIG_PINCTRL_SUNXI)	+= pinctrl-sunxi.o
 obj-$(CONFIG_PINCTRL_TEGRA)	+= pinctrl-tegra.o
 obj-$(CONFIG_PINCTRL_TEGRA20)	+= pinctrl-tegra20.o
 obj-$(CONFIG_PINCTRL_TEGRA30)	+= pinctrl-tegra30.o
 obj-$(CONFIG_PINCTRL_TEGRA114)	+= pinctrl-tegra114.o
+obj-$(CONFIG_PINCTRL_TZ1090)	+= pinctrl-tz1090.o
+obj-$(CONFIG_PINCTRL_TZ1090_PDC)	+= pinctrl-tz1090-pdc.o
 obj-$(CONFIG_PINCTRL_U300)	+= pinctrl-u300.o
 obj-$(CONFIG_PINCTRL_COH901)	+= pinctrl-coh901.o
 obj-$(CONFIG_PINCTRL_SAMSUNG)	+= pinctrl-samsung.o
 obj-$(CONFIG_PINCTRL_EXYNOS)	+= pinctrl-exynos.o
 obj-$(CONFIG_PINCTRL_EXYNOS5440)	+= pinctrl-exynos5440.o
+obj-$(CONFIG_PINCTRL_S3C24XX)	+= pinctrl-s3c24xx.o
 obj-$(CONFIG_PINCTRL_S3C64XX)	+= pinctrl-s3c64xx.o
 obj-$(CONFIG_PINCTRL_XWAY)	+= pinctrl-xway.o
 obj-$(CONFIG_PINCTRL_LANTIQ)	+= pinctrl-lantiq.o
+obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
+obj-$(CONFIG_PINCTRL_VF610)	+= pinctrl-vf610.o
 
 obj-$(CONFIG_PLAT_ORION)        += mvebu/
 obj-$(CONFIG_ARCH_SHMOBILE)	+= sh-pfc/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/mvebu/pinctrl-dove.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/mvebu/pinctrl-dove.c
--- linux-libre-3.10-gnu/drivers/pinctrl/mvebu/pinctrl-dove.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/mvebu/pinctrl-dove.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,6 +26,9 @@
 #define DOVE_MPP_VIRT_BASE		(DOVE_SB_REGS_VIRT_BASE + 0xd0200)
 #define DOVE_PMU_MPP_GENERAL_CTRL	(DOVE_MPP_VIRT_BASE + 0x10)
 #define  DOVE_AU0_AC97_SEL		BIT(16)
+#define DOVE_PMU_SIGNAL_SELECT_0	(DOVE_SB_REGS_VIRT_BASE + 0xd802C)
+#define DOVE_PMU_SIGNAL_SELECT_1	(DOVE_SB_REGS_VIRT_BASE + 0xd8030)
+#define DOVE_GLOBAL_CONFIG_1		(DOVE_SB_REGS_VIRT_BASE + 0xe802C)
 #define DOVE_GLOBAL_CONFIG_1		(DOVE_SB_REGS_VIRT_BASE + 0xe802C)
 #define  DOVE_TWSI_ENABLE_OPTION1	BIT(7)
 #define DOVE_GLOBAL_CONFIG_2		(DOVE_SB_REGS_VIRT_BASE + 0xe8030)
@@ -58,12 +61,16 @@ static int dove_pmu_mpp_ctrl_get(struct
 	unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
 	unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
 	unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
-	unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off);
+	unsigned long func;
 
-	if (pmu & (1 << ctrl->pid))
-		*config = CONFIG_PMU;
-	else
-		*config = (mpp >> shift) & MPP_MASK;
+	if (pmu & (1 << ctrl->pid)) {
+		func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
+		*config = (func >> shift) & MPP_MASK;
+		*config |= CONFIG_PMU;
+	} else {
+		func = readl(DOVE_MPP_VIRT_BASE + off);
+		*config = (func >> shift) & MPP_MASK;
+	}
 	return 0;
 }
 
@@ -73,15 +80,20 @@ static int dove_pmu_mpp_ctrl_set(struct
 	unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
 	unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
 	unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
-	unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off);
+	unsigned long func;
 
-	if (config == CONFIG_PMU)
+	if (config & CONFIG_PMU) {
 		writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
-	else {
+		func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
+		func &= ~(MPP_MASK << shift);
+		func |= (config & MPP_MASK) << shift;
+		writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off);
+	} else {
 		writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
-		mpp &= ~(MPP_MASK << shift);
-		mpp |= config << shift;
-		writel(mpp, DOVE_MPP_VIRT_BASE + off);
+		func = readl(DOVE_MPP_VIRT_BASE + off);
+		func &= ~(MPP_MASK << shift);
+		func |= (config & MPP_MASK) << shift;
+		writel(func, DOVE_MPP_VIRT_BASE + off);
 	}
 	return 0;
 }
@@ -378,20 +390,53 @@ static struct mvebu_mpp_mode dove_mpp_mo
 		MPP_FUNCTION(0x02, "uart2", "rts"),
 		MPP_FUNCTION(0x03, "sdio0", "cd"),
 		MPP_FUNCTION(0x0f, "lcd0", "pwm"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(1,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x02, "uart2", "cts"),
 		MPP_FUNCTION(0x03, "sdio0", "wp"),
 		MPP_FUNCTION(0x0f, "lcd1", "pwm"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(2,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x01, "sata", "prsnt"),
 		MPP_FUNCTION(0x02, "uart2", "txd"),
 		MPP_FUNCTION(0x03, "sdio0", "buspwr"),
 		MPP_FUNCTION(0x04, "uart1", "rts"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(3,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x01, "sata", "act"),
@@ -399,43 +444,131 @@ static struct mvebu_mpp_mode dove_mpp_mo
 		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
 		MPP_FUNCTION(0x04, "uart1", "cts"),
 		MPP_FUNCTION(0x0f, "lcd-spi", "cs1"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(4,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x02, "uart3", "rts"),
 		MPP_FUNCTION(0x03, "sdio1", "cd"),
 		MPP_FUNCTION(0x04, "spi1", "miso"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(5,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x02, "uart3", "cts"),
 		MPP_FUNCTION(0x03, "sdio1", "wp"),
 		MPP_FUNCTION(0x04, "spi1", "cs"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(6,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x02, "uart3", "txd"),
 		MPP_FUNCTION(0x03, "sdio1", "buspwr"),
 		MPP_FUNCTION(0x04, "spi1", "mosi"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(7,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x02, "uart3", "rxd"),
 		MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
 		MPP_FUNCTION(0x04, "spi1", "sck"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(8,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x01, "watchdog", "rstout"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(9,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x05, "pex1", "clkreq"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(10,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x05, "ssp", "sclk"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(11,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x01, "sata", "prsnt"),
@@ -443,33 +576,88 @@ static struct mvebu_mpp_mode dove_mpp_mo
 		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
 		MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
 		MPP_FUNCTION(0x05, "pex0", "clkreq"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(12,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x01, "sata", "act"),
 		MPP_FUNCTION(0x02, "uart2", "rts"),
 		MPP_FUNCTION(0x03, "audio0", "extclk"),
 		MPP_FUNCTION(0x04, "sdio1", "cd"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(13,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x02, "uart2", "cts"),
 		MPP_FUNCTION(0x03, "audio1", "extclk"),
 		MPP_FUNCTION(0x04, "sdio1", "wp"),
 		MPP_FUNCTION(0x05, "ssp", "extclk"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(14,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x02, "uart2", "txd"),
 		MPP_FUNCTION(0x04, "sdio1", "buspwr"),
 		MPP_FUNCTION(0x05, "ssp", "rxd"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(15,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x02, "uart2", "rxd"),
 		MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
 		MPP_FUNCTION(0x05, "ssp", "sfrm"),
-		MPP_FUNCTION(0x10, "pmu", NULL)),
+		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
+		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
+		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
 	MPP_MODE(16,
 		MPP_FUNCTION(0x00, "gpio", NULL),
 		MPP_FUNCTION(0x02, "uart3", "rts"),
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinconf.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinconf.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinconf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinconf.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,98 +75,6 @@ int pin_config_get_for_pin(struct pinctr
 	return ops->pin_config_get(pctldev, pin, config);
 }
 
-/**
- * pin_config_get() - get the configuration of a single pin parameter
- * @dev_name: name of the pin controller device for this pin
- * @name: name of the pin to get the config for
- * @config: the config pointed to by this argument will be filled in with the
- *	current pin state, it can be used directly by drivers as a numeral, or
- *	it can be dereferenced to any struct.
- */
-int pin_config_get(const char *dev_name, const char *name,
-			  unsigned long *config)
-{
-	struct pinctrl_dev *pctldev;
-	int pin;
-
-	pctldev = get_pinctrl_dev_from_devname(dev_name);
-	if (!pctldev) {
-		pin = -EINVAL;
-		return pin;
-	}
-
-	mutex_lock(&pctldev->mutex);
-
-	pin = pin_get_from_name(pctldev, name);
-	if (pin < 0)
-		goto unlock;
-
-	pin = pin_config_get_for_pin(pctldev, pin, config);
-
-unlock:
-	mutex_unlock(&pctldev->mutex);
-	return pin;
-}
-EXPORT_SYMBOL(pin_config_get);
-
-static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
-			   unsigned long config)
-{
-	const struct pinconf_ops *ops = pctldev->desc->confops;
-	int ret;
-
-	if (!ops || !ops->pin_config_set) {
-		dev_err(pctldev->dev, "cannot configure pin, missing "
-			"config function in driver\n");
-		return -EINVAL;
-	}
-
-	ret = ops->pin_config_set(pctldev, pin, config);
-	if (ret) {
-		dev_err(pctldev->dev,
-			"unable to set pin configuration on pin %d\n", pin);
-		return ret;
-	}
-
-	return 0;
-}
-
-/**
- * pin_config_set() - set the configuration of a single pin parameter
- * @dev_name: name of pin controller device for this pin
- * @name: name of the pin to set the config for
- * @config: the config in this argument will contain the desired pin state, it
- *	can be used directly by drivers as a numeral, or it can be dereferenced
- *	to any struct.
- */
-int pin_config_set(const char *dev_name, const char *name,
-		   unsigned long config)
-{
-	struct pinctrl_dev *pctldev;
-	int pin, ret;
-
-	pctldev = get_pinctrl_dev_from_devname(dev_name);
-	if (!pctldev) {
-		ret = -EINVAL;
-		return ret;
-	}
-
-	mutex_lock(&pctldev->mutex);
-
-	pin = pin_get_from_name(pctldev, name);
-	if (pin < 0) {
-		ret = pin;
-		goto unlock;
-	}
-
-	ret = pin_config_set_for_pin(pctldev, pin, config);
-
-unlock:
-	mutex_unlock(&pctldev->mutex);
-	return ret;
-}
-EXPORT_SYMBOL(pin_config_set);
-
 int pin_config_group_get(const char *dev_name, const char *pin_group,
 			 unsigned long *config)
 {
@@ -204,88 +112,6 @@ unlock:
 	mutex_unlock(&pctldev->mutex);
 	return ret;
 }
-EXPORT_SYMBOL(pin_config_group_get);
-
-int pin_config_group_set(const char *dev_name, const char *pin_group,
-			 unsigned long config)
-{
-	struct pinctrl_dev *pctldev;
-	const struct pinconf_ops *ops;
-	const struct pinctrl_ops *pctlops;
-	int selector;
-	const unsigned *pins;
-	unsigned num_pins;
-	int ret;
-	int i;
-
-	pctldev = get_pinctrl_dev_from_devname(dev_name);
-	if (!pctldev) {
-		ret = -EINVAL;
-		return ret;
-	}
-
-	mutex_lock(&pctldev->mutex);
-
-	ops = pctldev->desc->confops;
-	pctlops = pctldev->desc->pctlops;
-
-	if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
-		dev_err(pctldev->dev, "cannot configure pin group, missing "
-			"config function in driver\n");
-		ret = -EINVAL;
-		goto unlock;
-	}
-
-	selector = pinctrl_get_group_selector(pctldev, pin_group);
-	if (selector < 0) {
-		ret = selector;
-		goto unlock;
-	}
-
-	ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
-	if (ret) {
-		dev_err(pctldev->dev, "cannot configure pin group, error "
-			"getting pins\n");
-		goto unlock;
-	}
-
-	/*
-	 * If the pin controller supports handling entire groups we use that
-	 * capability.
-	 */
-	if (ops->pin_config_group_set) {
-		ret = ops->pin_config_group_set(pctldev, selector, config);
-		/*
-		 * If the pin controller prefer that a certain group be handled
-		 * pin-by-pin as well, it returns -EAGAIN.
-		 */
-		if (ret != -EAGAIN)
-			goto unlock;
-	}
-
-	/*
-	 * If the controller cannot handle entire groups, we configure each pin
-	 * individually.
-	 */
-	if (!ops->pin_config_set) {
-		ret = 0;
-		goto unlock;
-	}
-
-	for (i = 0; i < num_pins; i++) {
-		ret = ops->pin_config_set(pctldev, pins[i], config);
-		if (ret < 0)
-			goto unlock;
-	}
-
-	ret = 0;
-
-unlock:
-	mutex_unlock(&pctldev->mutex);
-
-	return ret;
-}
-EXPORT_SYMBOL(pin_config_group_set);
 
 int pinconf_map_to_setting(struct pinctrl_map const *map,
 			  struct pinctrl_setting *setting)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinconf-generic.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinconf-generic.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinconf-generic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinconf-generic.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinconf-generic.h>
+#include <linux/of.h>
 #include "core.h"
 #include "pinconf.h"
 
@@ -37,14 +38,18 @@ struct pin_config_item {
 static struct pin_config_item conf_items[] = {
 	PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL),
 	PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL),
+	PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL),
 	PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL),
 	PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL),
+	PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
+				"input bias pull to pin specific state", NULL),
 	PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL),
 	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL),
 	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL),
+	PCONFDUMP(PIN_CONFIG_DRIVE_STRENGTH, "output drive strength", "mA"),
 	PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_ENABLE, "input schmitt enabled", NULL),
 	PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL),
-	PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"),
+	PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "usec"),
 	PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"),
 	PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL),
 	PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"),
@@ -135,3 +140,100 @@ void pinconf_generic_dump_config(struct
 }
 EXPORT_SYMBOL_GPL(pinconf_generic_dump_config);
 #endif
+
+#ifdef CONFIG_OF
+struct pinconf_generic_dt_params {
+	const char * const property;
+	enum pin_config_param param;
+	u32 default_value;
+};
+
+static struct pinconf_generic_dt_params dt_params[] = {
+	{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+	{ "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
+	{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
+	{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
+	{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
+	{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
+	{ "drive-push-pull", PIN_CONFIG_DRIVE_PUSH_PULL, 0 },
+	{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
+	{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
+	{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
+	{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
+	{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
+	{ "input-debounce", PIN_CONFIG_INPUT_DEBOUNCE, 0 },
+	{ "low-power-enable", PIN_CONFIG_LOW_POWER_MODE, 1 },
+	{ "low-power-disable", PIN_CONFIG_LOW_POWER_MODE, 0 },
+	{ "output-low", PIN_CONFIG_OUTPUT, 0, },
+	{ "output-high", PIN_CONFIG_OUTPUT, 1, },
+};
+
+/**
+ * pinconf_generic_parse_dt_config()
+ * parse the config properties into generic pinconfig values.
+ * @np: node containing the pinconfig properties
+ * @configs: array with nconfigs entries containing the generic pinconf values
+ * @nconfigs: umber of configurations
+ */
+int pinconf_generic_parse_dt_config(struct device_node *np,
+				    unsigned long **configs,
+				    unsigned int *nconfigs)
+{
+	unsigned long *cfg;
+	unsigned int ncfg = 0;
+	int ret;
+	int i;
+	u32 val;
+
+	if (!np)
+		return -EINVAL;
+
+	/* allocate a temporary array big enough to hold one of each option */
+	cfg = kzalloc(sizeof(*cfg) * ARRAY_SIZE(dt_params), GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+		struct pinconf_generic_dt_params *par = &dt_params[i];
+		ret = of_property_read_u32(np, par->property, &val);
+
+		/* property not found */
+		if (ret == -EINVAL)
+			continue;
+
+		/* use default value, when no value is specified */
+		if (ret)
+			val = par->default_value;
+
+		pr_debug("found %s with value %u\n", par->property, val);
+		cfg[ncfg] = pinconf_to_config_packed(par->param, val);
+		ncfg++;
+	}
+
+	ret = 0;
+
+	/* no configs found at all */
+	if (ncfg == 0) {
+		*configs = NULL;
+		*nconfigs = 0;
+		goto out;
+	}
+
+	/*
+	 * Now limit the number of configs to the real number of
+	 * found properties.
+	 */
+	*configs = kzalloc(ncfg * sizeof(unsigned long), GFP_KERNEL);
+	if (!*configs) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(*configs, cfg, ncfg * sizeof(unsigned long));
+	*nconfigs = ncfg;
+
+out:
+	kfree(cfg);
+	return ret;
+}
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinconf.h linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinconf.h
--- linux-libre-3.10-gnu/drivers/pinctrl/pinconf.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinconf.h	2013-08-25 20:43:22.000000000 -0400
@@ -123,3 +123,9 @@ static inline void pinconf_generic_dump_
 	return;
 }
 #endif
+
+#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_OF)
+int pinconf_generic_parse_dt_config(struct device_node *np,
+				    unsigned long **configs,
+				    unsigned int *nconfigs);
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-abx500.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-abx500.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-abx500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-abx500.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,8 +30,11 @@
 #include <linux/pinctrl/pinmux.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/machine.h>
 
 #include "pinctrl-abx500.h"
+#include "core.h"
+#include "pinconf.h"
 
 /*
  * The AB9540 and AB8540 GPIO support are extended versions
@@ -93,13 +96,15 @@
 #define AB8540_GPIOX_VBAT_START	51
 #define AB8540_GPIOX_VBAT_END	54
 
+#define ABX500_GPIO_INPUT	0
+#define ABX500_GPIO_OUTPUT	1
+
 struct abx500_pinctrl {
 	struct device *dev;
 	struct pinctrl_dev *pctldev;
 	struct abx500_pinctrl_soc_data *soc;
 	struct gpio_chip chip;
 	struct ab8500 *parent;
-	struct mutex lock;
 	struct abx500_gpio_irq_cluster *irq_cluster;
 	int irq_cluster_size;
 };
@@ -129,8 +134,8 @@ static int abx500_gpio_get_bit(struct gp
 
 	if (ret < 0)
 		dev_err(pct->dev,
-			"%s read reg =%x, offset=%x failed\n",
-			__func__, reg, offset);
+			"%s read reg =%x, offset=%x failed (%d)\n",
+			__func__, reg, offset, ret);
 
 	return ret;
 }
@@ -146,7 +151,8 @@ static int abx500_gpio_set_bits(struct g
 	ret = abx500_mask_and_set_register_interruptible(pct->dev,
 				AB8500_MISC, reg, BIT(pos), val << pos);
 	if (ret < 0)
-		dev_err(pct->dev, "%s write failed\n", __func__);
+		dev_err(pct->dev, "%s write reg, %x offset %x failed (%d)\n",
+				__func__, reg, offset, ret);
 
 	return ret;
 }
@@ -160,12 +166,24 @@ static int abx500_gpio_get(struct gpio_c
 {
 	struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
 	bool bit;
+	bool is_out;
+	u8 gpio_offset = offset - 1;
 	int ret;
 
-	ret = abx500_gpio_get_bit(chip, AB8500_GPIO_IN1_REG,
-				  offset, &bit);
+	ret = abx500_gpio_get_bit(chip, AB8500_GPIO_DIR1_REG,
+			gpio_offset, &is_out);
+	if (ret < 0)
+		goto out;
+
+	if (is_out)
+		ret = abx500_gpio_get_bit(chip, AB8500_GPIO_OUT1_REG,
+				gpio_offset, &bit);
+	else
+		ret = abx500_gpio_get_bit(chip, AB8500_GPIO_IN1_REG,
+				gpio_offset, &bit);
+out:
 	if (ret < 0) {
-		dev_err(pct->dev, "%s failed\n", __func__);
+		dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
 		return ret;
 	}
 
@@ -179,13 +197,14 @@ static void abx500_gpio_set(struct gpio_
 
 	ret = abx500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
 	if (ret < 0)
-		dev_err(pct->dev, "%s write failed\n", __func__);
+		dev_err(pct->dev, "%s write failed (%d)\n", __func__, ret);
 }
 
-static int abx500_config_pull_updown(struct abx500_pinctrl *pct,
-				     int offset, enum abx500_gpio_pull_updown val)
+static int abx500_get_pull_updown(struct abx500_pinctrl *pct, int offset,
+				  enum abx500_gpio_pull_updown *pull_updown)
 {
 	u8 pos;
+	u8 val;
 	int ret;
 	struct pullud *pullud;
 
@@ -204,7 +223,41 @@ static int abx500_config_pull_updown(str
 		goto out;
 	}
 
-	pos = offset << 1;
+	ret = abx500_get_register_interruptible(pct->dev,
+			AB8500_MISC, AB8540_GPIO_PULL_UPDOWN_REG, &val);
+
+	pos = (offset - pullud->first_pin) << 1;
+	*pull_updown = (val >> pos) & AB8540_GPIO_PULL_UPDOWN_MASK;
+
+out:
+	if (ret < 0)
+		dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+
+	return ret;
+}
+
+static int abx500_set_pull_updown(struct abx500_pinctrl *pct,
+				  int offset, enum abx500_gpio_pull_updown val)
+{
+	u8 pos;
+	int ret;
+	struct pullud *pullud;
+
+	if (!pct->soc->pullud) {
+		dev_err(pct->dev, "%s AB chip doesn't support pull up/down feature",
+				__func__);
+		ret = -EPERM;
+		goto out;
+	}
+
+	pullud = pct->soc->pullud;
+
+	if ((offset < pullud->first_pin)
+		|| (offset > pullud->last_pin)) {
+		ret = -EINVAL;
+		goto out;
+	}
+	pos = (offset - pullud->first_pin) << 1;
 
 	ret = abx500_mask_and_set_register_interruptible(pct->dev,
 			AB8500_MISC, AB8540_GPIO_PULL_UPDOWN_REG,
@@ -217,33 +270,51 @@ out:
 	return ret;
 }
 
+static bool abx500_pullud_supported(struct gpio_chip *chip, unsigned gpio)
+{
+	struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
+	struct pullud *pullud = pct->soc->pullud;
+
+	return (pullud &&
+		gpio >= pullud->first_pin &&
+		gpio <= pullud->last_pin);
+}
+
 static int abx500_gpio_direction_output(struct gpio_chip *chip,
 					unsigned offset,
 					int val)
 {
 	struct abx500_pinctrl *pct = to_abx500_pinctrl(chip);
-	struct pullud *pullud = pct->soc->pullud;
 	unsigned gpio;
 	int ret;
 
 	/* set direction as output */
-	ret = abx500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 1);
+	ret = abx500_gpio_set_bits(chip,
+				AB8500_GPIO_DIR1_REG,
+				offset,
+				ABX500_GPIO_OUTPUT);
 	if (ret < 0)
-		return ret;
+		goto out;
 
 	/* disable pull down */
-	ret = abx500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, offset, 1);
+	ret = abx500_gpio_set_bits(chip,
+				AB8500_GPIO_PUD1_REG,
+				offset,
+				ABX500_GPIO_PULL_NONE);
 	if (ret < 0)
-		return ret;
+		goto out;
 
 	/* if supported, disable both pull down and pull up */
 	gpio = offset + 1;
-	if (pullud && gpio >= pullud->first_pin && gpio <= pullud->last_pin) {
-		ret = abx500_config_pull_updown(pct,
+	if (abx500_pullud_supported(chip, gpio)) {
+		ret = abx500_set_pull_updown(pct,
 				gpio,
 				ABX500_GPIO_PULL_NONE);
-		if (ret < 0)
-			return ret;
+	}
+out:
+	if (ret < 0) {
+		dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+		return ret;
 	}
 
 	/* set the output as 1 or 0 */
@@ -253,7 +324,10 @@ static int abx500_gpio_direction_output(
 static int abx500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 {
 	/* set the register as input */
-	return abx500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 0);
+	return abx500_gpio_set_bits(chip,
+				AB8500_GPIO_DIR1_REG,
+				offset,
+				ABX500_GPIO_INPUT);
 }
 
 static int abx500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
@@ -338,10 +412,16 @@ static int abx500_set_mode(struct pinctr
 		if (af.alt_bit1 != UNUSED) {
 			ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
 					offset, 0);
+			if (ret < 0)
+				goto out;
+
 			ret = abx500_gpio_set_bits(chip,
 					AB8500_GPIO_ALTFUN_REG,
 					af.alt_bit1,
 					!!(af.alta_val && BIT(0)));
+			if (ret < 0)
+				goto out;
+
 			if (af.alt_bit2 != UNUSED)
 				ret = abx500_gpio_set_bits(chip,
 					AB8500_GPIO_ALTFUN_REG,
@@ -355,8 +435,14 @@ static int abx500_set_mode(struct pinctr
 	case ABX500_ALT_B:
 		ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
 				offset, 0);
+		if (ret < 0)
+			goto out;
+
 		ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
 				af.alt_bit1, !!(af.altb_val && BIT(0)));
+		if (ret < 0)
+			goto out;
+
 		if (af.alt_bit2 != UNUSED)
 			ret = abx500_gpio_set_bits(chip,
 					AB8500_GPIO_ALTFUN_REG,
@@ -367,8 +453,14 @@ static int abx500_set_mode(struct pinctr
 	case ABX500_ALT_C:
 		ret = abx500_gpio_set_bits(chip, AB8500_GPIO_SEL1_REG,
 				offset, 0);
+		if (ret < 0)
+			goto out;
+
 		ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
 				af.alt_bit2, !!(af.altc_val && BIT(0)));
+		if (ret < 0)
+			goto out;
+
 		ret = abx500_gpio_set_bits(chip, AB8500_GPIO_ALTFUN_REG,
 				af.alt_bit2, !!(af.altc_val && BIT(1)));
 		break;
@@ -378,11 +470,14 @@ static int abx500_set_mode(struct pinctr
 
 		return -EINVAL;
 	}
+out:
+	if (ret < 0)
+		dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
 
 	return ret;
 }
 
-static u8 abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip,
+static int abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip,
 			  unsigned gpio)
 {
 	u8 mode;
@@ -393,6 +488,7 @@ static u8 abx500_get_mode(struct pinctrl
 	struct alternate_functions af = pct->soc->alternate_functions[gpio];
 	/* on ABx5xx, there is no GPIO0, so adjust the offset */
 	unsigned offset = gpio - 1;
+	int ret;
 
 	/*
 	 * if gpiosel_bit is set to unused,
@@ -402,8 +498,11 @@ static u8 abx500_get_mode(struct pinctrl
 		return ABX500_DEFAULT;
 
 	/* read GpioSelx register */
-	abx500_gpio_get_bit(chip, AB8500_GPIO_SEL1_REG + (offset / 8),
+	ret = abx500_gpio_get_bit(chip, AB8500_GPIO_SEL1_REG + (offset / 8),
 			af.gpiosel_bit, &bit_mode);
+	if (ret < 0)
+		goto out;
+
 	mode = bit_mode;
 
 	/* sanity check */
@@ -435,14 +534,19 @@ static u8 abx500_get_mode(struct pinctrl
 	 * pin use the AlternatFunction register
 	 * read alt_bit1 value
 	 */
-	abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG,
+	ret = abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG,
 			    af.alt_bit1, &alt_bit1);
+	if (ret < 0)
+		goto out;
 
-	if (af.alt_bit2 != UNUSED)
+	if (af.alt_bit2 != UNUSED) {
 		/* read alt_bit2 value */
-		abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG, af.alt_bit2,
+		ret = abx500_gpio_get_bit(chip, AB8500_GPIO_ALTFUN_REG,
+				af.alt_bit2,
 				&alt_bit2);
-	else
+		if (ret < 0)
+			goto out;
+	} else
 		alt_bit2 = 0;
 
 	mode = (alt_bit2 << 1) + alt_bit1;
@@ -452,6 +556,10 @@ static u8 abx500_get_mode(struct pinctrl
 		return ABX500_ALT_B;
 	else
 		return ABX500_ALT_C;
+
+out:
+	dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+	return ret;
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -463,11 +571,14 @@ static void abx500_gpio_dbg_show_one(str
 				     struct gpio_chip *chip,
 				     unsigned offset, unsigned gpio)
 {
+	struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
 	const char *label = gpiochip_is_requested(chip, offset - 1);
 	u8 gpio_offset = offset - 1;
 	int mode = -1;
 	bool is_out;
-	bool pull;
+	bool pd;
+	enum abx500_gpio_pull_updown pud = 0;
+	int ret;
 
 	const char *modes[] = {
 		[ABX500_DEFAULT]	= "default",
@@ -476,21 +587,48 @@ static void abx500_gpio_dbg_show_one(str
 		[ABX500_ALT_C]		= "altC",
 	};
 
-	abx500_gpio_get_bit(chip, AB8500_GPIO_DIR1_REG, gpio_offset, &is_out);
-	abx500_gpio_get_bit(chip, AB8500_GPIO_PUD1_REG, gpio_offset, &pull);
+	const char *pull_up_down[] = {
+		[ABX500_GPIO_PULL_DOWN]		= "pull down",
+		[ABX500_GPIO_PULL_NONE]		= "pull none",
+		[ABX500_GPIO_PULL_NONE + 1]	= "pull none",
+		[ABX500_GPIO_PULL_UP]		= "pull up",
+	};
+
+	ret = abx500_gpio_get_bit(chip, AB8500_GPIO_DIR1_REG,
+			gpio_offset, &is_out);
+	if (ret < 0)
+		goto out;
+
+	seq_printf(s, " gpio-%-3d (%-20.20s) %-3s",
+		   gpio, label ?: "(none)",
+		   is_out ? "out" : "in ");
+
+	if (!is_out) {
+		if (abx500_pullud_supported(chip, offset)) {
+			ret = abx500_get_pull_updown(pct, offset, &pud);
+			if (ret < 0)
+				goto out;
+
+			seq_printf(s, " %-9s", pull_up_down[pud]);
+		} else {
+			ret = abx500_gpio_get_bit(chip, AB8500_GPIO_PUD1_REG,
+					gpio_offset, &pd);
+			if (ret < 0)
+				goto out;
+
+			seq_printf(s, " %-9s", pull_up_down[pd]);
+		}
+	} else
+		seq_printf(s, " %-9s", chip->get(chip, offset) ? "hi" : "lo");
 
 	if (pctldev)
 		mode = abx500_get_mode(pctldev, chip, offset);
 
-	seq_printf(s, " gpio-%-3d (%-20.20s) %-3s %-9s %s",
-		   gpio, label ?: "(none)",
-		   is_out ? "out" : "in ",
-		   is_out ?
-		   (chip->get
-		   ? (chip->get(chip, offset) ? "hi" : "lo")
-		   : "?  ")
-		   : (pull ? "pull up" : "pull down"),
-		   (mode < 0) ? "unknown" : modes[mode]);
+	seq_printf(s, " %s", (mode < 0) ? "unknown" : modes[mode]);
+
+out:
+	if (ret < 0)
+		dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
 }
 
 static void abx500_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
@@ -594,6 +732,9 @@ static int abx500_pmx_enable(struct pinc
 		ret = abx500_set_mode(pctldev, chip, g->pins[i], g->altsetting);
 	}
 
+	if (ret < 0)
+		dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
+
 	return ret;
 }
 
@@ -642,10 +783,8 @@ static int abx500_gpio_request_enable(st
 
 	ret = abx500_set_mode(pct->pctldev, &pct->chip,
 			      offset, p->altfunc);
-	if (ret < 0) {
+	if (ret < 0)
 		dev_err(pct->dev, "%s setting altfunc failed\n", __func__);
-		return ret;
-	}
 
 	return ret;
 }
@@ -704,11 +843,193 @@ static void abx500_pin_dbg_show(struct p
 				 chip->base + offset - 1);
 }
 
+static void abx500_dt_free_map(struct pinctrl_dev *pctldev,
+		struct pinctrl_map *map, unsigned num_maps)
+{
+	int i;
+
+	for (i = 0; i < num_maps; i++)
+		if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
+			kfree(map[i].data.configs.configs);
+	kfree(map);
+}
+
+static int abx500_dt_reserve_map(struct pinctrl_map **map,
+		unsigned *reserved_maps,
+		unsigned *num_maps,
+		unsigned reserve)
+{
+	unsigned old_num = *reserved_maps;
+	unsigned new_num = *num_maps + reserve;
+	struct pinctrl_map *new_map;
+
+	if (old_num >= new_num)
+		return 0;
+
+	new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
+
+	*map = new_map;
+	*reserved_maps = new_num;
+
+	return 0;
+}
+
+static int abx500_dt_add_map_mux(struct pinctrl_map **map,
+		unsigned *reserved_maps,
+		unsigned *num_maps, const char *group,
+		const char *function)
+{
+	if (*num_maps == *reserved_maps)
+		return -ENOSPC;
+
+	(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+	(*map)[*num_maps].data.mux.group = group;
+	(*map)[*num_maps].data.mux.function = function;
+	(*num_maps)++;
+
+	return 0;
+}
+
+static int abx500_dt_add_map_configs(struct pinctrl_map **map,
+		unsigned *reserved_maps,
+		unsigned *num_maps, const char *group,
+		unsigned long *configs, unsigned num_configs)
+{
+	unsigned long *dup_configs;
+
+	if (*num_maps == *reserved_maps)
+		return -ENOSPC;
+
+	dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
+			      GFP_KERNEL);
+	if (!dup_configs)
+		return -ENOMEM;
+
+	(*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_PIN;
+
+	(*map)[*num_maps].data.configs.group_or_pin = group;
+	(*map)[*num_maps].data.configs.configs = dup_configs;
+	(*map)[*num_maps].data.configs.num_configs = num_configs;
+	(*num_maps)++;
+
+	return 0;
+}
+
+static const char *abx500_find_pin_name(struct pinctrl_dev *pctldev,
+					const char *pin_name)
+{
+	int i, pin_number;
+	struct abx500_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+	if (sscanf((char *)pin_name, "GPIO%d", &pin_number) == 1)
+		for (i = 0; i < npct->soc->npins; i++)
+			if (npct->soc->pins[i].number == pin_number)
+				return npct->soc->pins[i].name;
+	return NULL;
+}
+
+static int abx500_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+		struct device_node *np,
+		struct pinctrl_map **map,
+		unsigned *reserved_maps,
+		unsigned *num_maps)
+{
+	int ret;
+	const char *function = NULL;
+	unsigned long *configs;
+	unsigned int nconfigs = 0;
+	bool has_config = 0;
+	unsigned reserve = 0;
+	struct property *prop;
+	const char *group, *gpio_name;
+	struct device_node *np_config;
+
+	ret = of_property_read_string(np, "ste,function", &function);
+	if (ret >= 0)
+		reserve = 1;
+
+	ret = pinconf_generic_parse_dt_config(np, &configs, &nconfigs);
+	if (nconfigs)
+		has_config = 1;
+
+	np_config = of_parse_phandle(np, "ste,config", 0);
+	if (np_config) {
+		ret = pinconf_generic_parse_dt_config(np_config, &configs,
+				&nconfigs);
+		if (ret)
+			goto exit;
+		has_config |= nconfigs;
+	}
+
+	ret = of_property_count_strings(np, "ste,pins");
+	if (ret < 0)
+		goto exit;
+
+	if (has_config)
+		reserve++;
+
+	reserve *= ret;
+
+	ret = abx500_dt_reserve_map(map, reserved_maps, num_maps, reserve);
+	if (ret < 0)
+		goto exit;
+
+	of_property_for_each_string(np, "ste,pins", prop, group) {
+		if (function) {
+			ret = abx500_dt_add_map_mux(map, reserved_maps,
+					num_maps, group, function);
+			if (ret < 0)
+				goto exit;
+		}
+		if (has_config) {
+			gpio_name = abx500_find_pin_name(pctldev, group);
+
+			ret = abx500_dt_add_map_configs(map, reserved_maps,
+					num_maps, gpio_name, configs, 1);
+			if (ret < 0)
+				goto exit;
+		}
+
+	}
+exit:
+	return ret;
+}
+
+static int abx500_dt_node_to_map(struct pinctrl_dev *pctldev,
+				 struct device_node *np_config,
+				 struct pinctrl_map **map, unsigned *num_maps)
+{
+	unsigned reserved_maps;
+	struct device_node *np;
+	int ret;
+
+	reserved_maps = 0;
+	*map = NULL;
+	*num_maps = 0;
+
+	for_each_child_of_node(np_config, np) {
+		ret = abx500_dt_subnode_to_map(pctldev, np, map,
+				&reserved_maps, num_maps);
+		if (ret < 0) {
+			abx500_dt_free_map(pctldev, *map, *num_maps);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static const struct pinctrl_ops abx500_pinctrl_ops = {
 	.get_groups_count = abx500_get_groups_cnt,
 	.get_group_name = abx500_get_group_name,
 	.get_group_pins = abx500_get_group_pins,
 	.pin_dbg_show = abx500_pin_dbg_show,
+	.dt_node_to_map = abx500_dt_node_to_map,
+	.dt_free_map = abx500_dt_free_map,
 };
 
 static int abx500_pin_config_get(struct pinctrl_dev *pctldev,
@@ -723,10 +1044,9 @@ static int abx500_pin_config_set(struct
 			  unsigned long config)
 {
 	struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
-	struct pullud *pullud = pct->soc->pullud;
 	struct gpio_chip *chip = &pct->chip;
 	unsigned offset;
-	int ret;
+	int ret = -EINVAL;
 	enum pin_config_param param = pinconf_to_config_param(config);
 	enum pin_config_param argument = pinconf_to_config_argument(config);
 
@@ -739,41 +1059,83 @@ static int abx500_pin_config_set(struct
 	offset = pin - 1;
 
 	switch (param) {
-	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_DISABLE:
+		ret = abx500_gpio_direction_input(chip, offset);
+		if (ret < 0)
+			goto out;
 		/*
-		 * if argument = 1 set the pull down
-		 * else clear the pull down
+		 * Some chips only support pull down, while some actually
+		 * support both pull up and pull down. Such chips have
+		 * a "pullud" range specified for the pins that support
+		 * both features. If the pin is not within that range, we
+		 * fall back to the old bit set that only support pull down.
 		 */
+		if (abx500_pullud_supported(chip, pin))
+			ret = abx500_set_pull_updown(pct,
+				pin,
+				ABX500_GPIO_PULL_NONE);
+		else
+			/* Chip only supports pull down */
+			ret = abx500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG,
+				offset, ABX500_GPIO_PULL_NONE);
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_DOWN:
 		ret = abx500_gpio_direction_input(chip, offset);
+		if (ret < 0)
+			goto out;
 		/*
+		 * if argument = 1 set the pull down
+		 * else clear the pull down
 		 * Some chips only support pull down, while some actually
 		 * support both pull up and pull down. Such chips have
 		 * a "pullud" range specified for the pins that support
 		 * both features. If the pin is not within that range, we
 		 * fall back to the old bit set that only support pull down.
 		 */
-		if (pullud &&
-		    pin >= pullud->first_pin &&
-		    pin <= pullud->last_pin)
-			ret = abx500_config_pull_updown(pct,
+		if (abx500_pullud_supported(chip, pin))
+			ret = abx500_set_pull_updown(pct,
 				pin,
 				argument ? ABX500_GPIO_PULL_DOWN : ABX500_GPIO_PULL_NONE);
 		else
 			/* Chip only supports pull down */
 			ret = abx500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG,
-				offset, argument ? 0 : 1);
+				offset,
+				argument ? ABX500_GPIO_PULL_DOWN : ABX500_GPIO_PULL_NONE);
+		break;
+
+	case PIN_CONFIG_BIAS_PULL_UP:
+		ret = abx500_gpio_direction_input(chip, offset);
+		if (ret < 0)
+			goto out;
+		/*
+		 * if argument = 1 set the pull up
+		 * else clear the pull up
+		 */
+		ret = abx500_gpio_direction_input(chip, offset);
+		/*
+		 * Some chips only support pull down, while some actually
+		 * support both pull up and pull down. Such chips have
+		 * a "pullud" range specified for the pins that support
+		 * both features. If the pin is not within that range, do
+		 * nothing
+		 */
+		if (abx500_pullud_supported(chip, pin))
+			ret = abx500_set_pull_updown(pct,
+				pin,
+				argument ? ABX500_GPIO_PULL_UP : ABX500_GPIO_PULL_NONE);
 		break;
 
 	case PIN_CONFIG_OUTPUT:
 		ret = abx500_gpio_direction_output(chip, offset, argument);
-
 		break;
 
 	default:
 		dev_err(chip->dev, "illegal configuration requested\n");
-
-		return -EINVAL;
 	}
+out:
+	if (ret < 0)
+		dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
 
 	return ret;
 }
@@ -881,9 +1243,6 @@ static int abx500_gpio_probe(struct plat
 			id = (unsigned long)match->data;
 	}
 
-	/* initialize the lock */
-	mutex_init(&pct->lock);
-
 	/* Poke in other ASIC variants here */
 	switch (id) {
 	case PINCTRL_AB8500:
@@ -900,13 +1259,11 @@ static int abx500_gpio_probe(struct plat
 		break;
 	default:
 		dev_err(&pdev->dev, "Unsupported pinctrl sub driver (%d)\n", id);
-		mutex_destroy(&pct->lock);
 		return -EINVAL;
 	}
 
 	if (!pct->soc) {
 		dev_err(&pdev->dev, "Invalid SOC data\n");
-		mutex_destroy(&pct->lock);
 		return -EINVAL;
 	}
 
@@ -917,7 +1274,6 @@ static int abx500_gpio_probe(struct plat
 	ret = gpiochip_add(&pct->chip);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
-		mutex_destroy(&pct->lock);
 		return ret;
 	}
 	dev_info(&pdev->dev, "added gpiochip\n");
@@ -954,7 +1310,6 @@ out_rem_chip:
 	if (err)
 		dev_info(&pdev->dev, "failed to remove gpiochip\n");
 
-	mutex_destroy(&pct->lock);
 	return ret;
 }
 
@@ -974,8 +1329,6 @@ static int abx500_gpio_remove(struct pla
 		return ret;
 	}
 
-	mutex_destroy(&pct->lock);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-at91.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-at91.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-at91.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-at91.c	2013-08-25 20:43:22.000000000 -0400
@@ -1543,12 +1543,6 @@ static int at91_gpio_probe(struct platfo
 		goto err;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		ret = -ENOENT;
-		goto err;
-	}
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		ret = irq;
@@ -1561,6 +1555,7 @@ static int at91_gpio_probe(struct platfo
 		goto err;
 	}
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	at91_chip->regbase = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(at91_chip->regbase)) {
 		ret = PTR_ERR(at91_chip->regbase);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-baytrail.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-baytrail.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-baytrail.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-baytrail.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,543 @@
+/*
+ * Pinctrl GPIO driver for Intel Baytrail
+ * Copyright (c) 2012-2013, Intel Corporation.
+ *
+ * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/irqdomain.h>
+#include <linux/acpi.h>
+#include <linux/acpi_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/pinctrl/pinctrl.h>
+
+/* memory mapped register offsets */
+#define BYT_CONF0_REG		0x000
+#define BYT_CONF1_REG		0x004
+#define BYT_VAL_REG		0x008
+#define BYT_DFT_REG		0x00c
+#define BYT_INT_STAT_REG	0x800
+
+/* BYT_CONF0_REG register bits */
+#define BYT_TRIG_NEG		BIT(26)
+#define BYT_TRIG_POS		BIT(25)
+#define BYT_TRIG_LVL		BIT(24)
+#define BYT_PIN_MUX		0x07
+
+/* BYT_VAL_REG register bits */
+#define BYT_INPUT_EN		BIT(2)  /* 0: input enabled (active low)*/
+#define BYT_OUTPUT_EN		BIT(1)  /* 0: output enabled (active low)*/
+#define BYT_LEVEL		BIT(0)
+
+#define BYT_DIR_MASK		(BIT(1) | BIT(2))
+#define BYT_TRIG_MASK		(BIT(26) | BIT(25) | BIT(24))
+
+#define BYT_NGPIO_SCORE		102
+#define BYT_NGPIO_NCORE		28
+#define BYT_NGPIO_SUS		44
+
+/*
+ * Baytrail gpio controller consist of three separate sub-controllers called
+ * SCORE, NCORE and SUS. The sub-controllers are identified by their acpi UID.
+ *
+ * GPIO numbering is _not_ ordered meaning that gpio # 0 in ACPI namespace does
+ * _not_ correspond to the first gpio register at controller's gpio base.
+ * There is no logic or pattern in mapping gpio numbers to registers (pads) so
+ * each sub-controller needs to have its own mapping table
+ */
+
+/* score_pins[gpio_nr] = pad_nr */
+
+static unsigned const score_pins[BYT_NGPIO_SCORE] = {
+	85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
+	36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
+	54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
+	52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
+	95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
+	86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
+	80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
+	2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
+	31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
+	24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
+	97, 100,
+};
+
+static unsigned const ncore_pins[BYT_NGPIO_NCORE] = {
+	19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
+	14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
+	3, 6, 10, 13, 2, 5, 9, 7,
+};
+
+static unsigned const sus_pins[BYT_NGPIO_SUS] = {
+	29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
+	18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
+	0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
+	26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
+	52, 53, 59, 40,
+};
+
+static struct pinctrl_gpio_range byt_ranges[] = {
+	{
+		.name = "1", /* match with acpi _UID in probe */
+		.npins = BYT_NGPIO_SCORE,
+		.pins = score_pins,
+	},
+	{
+		.name = "2",
+		.npins = BYT_NGPIO_NCORE,
+		.pins = ncore_pins,
+	},
+	{
+		.name = "3",
+		.npins = BYT_NGPIO_SUS,
+		.pins = sus_pins,
+	},
+	{
+	},
+};
+
+struct byt_gpio {
+	struct gpio_chip		chip;
+	struct irq_domain		*domain;
+	struct platform_device		*pdev;
+	spinlock_t			lock;
+	void __iomem			*reg_base;
+	struct pinctrl_gpio_range	*range;
+};
+
+static void __iomem *byt_gpio_reg(struct gpio_chip *chip, unsigned offset,
+				 int reg)
+{
+	struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip);
+	u32 reg_offset;
+	void __iomem *ptr;
+
+	if (reg == BYT_INT_STAT_REG)
+		reg_offset = (offset / 32) * 4;
+	else
+		reg_offset = vg->range->pins[offset] * 16;
+
+	ptr = (void __iomem *) (vg->reg_base + reg_offset + reg);
+	return ptr;
+}
+
+static int byt_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip);
+
+	pm_runtime_get(&vg->pdev->dev);
+
+	return 0;
+}
+
+static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip);
+	void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
+	u32 value;
+
+	/* clear interrupt triggering */
+	value = readl(reg);
+	value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+	writel(value, reg);
+
+	pm_runtime_put(&vg->pdev->dev);
+}
+
+static int byt_irq_type(struct irq_data *d, unsigned type)
+{
+	struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
+	u32 offset = irqd_to_hwirq(d);
+	u32 value;
+	unsigned long flags;
+	void __iomem *reg = byt_gpio_reg(&vg->chip, offset, BYT_CONF0_REG);
+
+	if (offset >= vg->chip.ngpio)
+		return -EINVAL;
+
+	spin_lock_irqsave(&vg->lock, flags);
+	value = readl(reg);
+
+	/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
+	 * are used to indicate high and low level triggering
+	 */
+	value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
+
+	switch (type) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		value |= BYT_TRIG_LVL;
+	case IRQ_TYPE_EDGE_RISING:
+		value |= BYT_TRIG_POS;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		value |= BYT_TRIG_LVL;
+	case IRQ_TYPE_EDGE_FALLING:
+		value |= BYT_TRIG_NEG;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
+		break;
+	}
+	writel(value, reg);
+
+	spin_unlock_irqrestore(&vg->lock, flags);
+
+	return 0;
+}
+
+static int byt_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
+	return readl(reg) & BYT_LEVEL;
+}
+
+static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip);
+	void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
+	unsigned long flags;
+	u32 old_val;
+
+	spin_lock_irqsave(&vg->lock, flags);
+
+	old_val = readl(reg);
+
+	if (value)
+		writel(old_val | BYT_LEVEL, reg);
+	else
+		writel(old_val & ~BYT_LEVEL, reg);
+
+	spin_unlock_irqrestore(&vg->lock, flags);
+}
+
+static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip);
+	void __iomem *reg = byt_gpio_reg(chip, offset, BYT_VAL_REG);
+	unsigned long flags;
+	u32 value;
+
+	spin_lock_irqsave(&vg->lock, flags);
+
+	value = readl(reg) | BYT_DIR_MASK;
+	value = value & (~BYT_INPUT_EN); /* active low */
+	writel(value, reg);
+
+	spin_unlock_irqrestore(&vg->lock, flags);
+
+	return 0;
+}
+
+static int byt_gpio_direction_output(struct gpio_chip *chip,
+				     unsigned gpio, int value)
+{
+	struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip);
+	void __iomem *reg = byt_gpio_reg(chip, gpio, BYT_VAL_REG);
+	unsigned long flags;
+	u32 reg_val;
+
+	spin_lock_irqsave(&vg->lock, flags);
+
+	reg_val = readl(reg) | (BYT_DIR_MASK | !!value);
+	reg_val &= ~(BYT_OUTPUT_EN | !value);
+	writel(reg_val, reg);
+
+	spin_unlock_irqrestore(&vg->lock, flags);
+
+	return 0;
+}
+
+static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip);
+	int i;
+	unsigned long flags;
+	u32 conf0, val, offs;
+
+	spin_lock_irqsave(&vg->lock, flags);
+
+	for (i = 0; i < vg->chip.ngpio; i++) {
+		offs = vg->range->pins[i] * 16;
+		conf0 = readl(vg->reg_base + offs + BYT_CONF0_REG);
+		val = readl(vg->reg_base + offs + BYT_VAL_REG);
+
+		seq_printf(s,
+			   " gpio-%-3d %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s\n",
+			   i,
+			   val & BYT_INPUT_EN ? "  " : "in",
+			   val & BYT_OUTPUT_EN ? "   " : "out",
+			   val & BYT_LEVEL ? "hi" : "lo",
+			   vg->range->pins[i], offs,
+			   conf0 & 0x7,
+			   conf0 & BYT_TRIG_NEG ? "fall " : "",
+			   conf0 & BYT_TRIG_POS ? "rise " : "",
+			   conf0 & BYT_TRIG_LVL ? "lvl " : "");
+	}
+	spin_unlock_irqrestore(&vg->lock, flags);
+}
+
+static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct byt_gpio *vg = container_of(chip, struct byt_gpio, chip);
+	return irq_create_mapping(vg->domain, offset);
+}
+
+static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+	struct irq_data *data = irq_desc_get_irq_data(desc);
+	struct byt_gpio *vg = irq_data_get_irq_handler_data(data);
+	struct irq_chip *chip = irq_data_get_irq_chip(data);
+	u32 base, pin, mask;
+	void __iomem *reg;
+	u32 pending;
+	unsigned virq;
+	int looplimit = 0;
+
+	/* check from GPIO controller which pin triggered the interrupt */
+	for (base = 0; base < vg->chip.ngpio; base += 32) {
+
+		reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
+
+		while ((pending = readl(reg))) {
+			pin = __ffs(pending);
+			mask = BIT(pin);
+			/* Clear before handling so we can't lose an edge */
+			writel(mask, reg);
+
+			virq = irq_find_mapping(vg->domain, base + pin);
+			generic_handle_irq(virq);
+
+			/* In case bios or user sets triggering incorretly a pin
+			 * might remain in "interrupt triggered" state.
+			 */
+			if (looplimit++ > 32) {
+				dev_err(&vg->pdev->dev,
+					"Gpio %d interrupt flood, disabling\n",
+					base + pin);
+
+				reg = byt_gpio_reg(&vg->chip, base + pin,
+						   BYT_CONF0_REG);
+				mask = readl(reg);
+				mask &= ~(BYT_TRIG_NEG | BYT_TRIG_POS |
+					  BYT_TRIG_LVL);
+				writel(mask, reg);
+				mask = readl(reg); /* flush */
+				break;
+			}
+		}
+	}
+	chip->irq_eoi(data);
+}
+
+static void byt_irq_unmask(struct irq_data *d)
+{
+}
+
+static void byt_irq_mask(struct irq_data *d)
+{
+}
+
+static struct irq_chip byt_irqchip = {
+	.name = "BYT-GPIO",
+	.irq_mask = byt_irq_mask,
+	.irq_unmask = byt_irq_unmask,
+	.irq_set_type = byt_irq_type,
+};
+
+static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
+{
+	void __iomem *reg;
+	u32 base, value;
+
+	/* clear interrupt status trigger registers */
+	for (base = 0; base < vg->chip.ngpio; base += 32) {
+		reg = byt_gpio_reg(&vg->chip, base, BYT_INT_STAT_REG);
+		writel(0xffffffff, reg);
+		/* make sure trigger bits are cleared, if not then a pin
+		   might be misconfigured in bios */
+		value = readl(reg);
+		if (value)
+			dev_err(&vg->pdev->dev,
+				"GPIO interrupt error, pins misconfigured\n");
+	}
+}
+
+static int byt_gpio_irq_map(struct irq_domain *d, unsigned int virq,
+			    irq_hw_number_t hw)
+{
+	struct byt_gpio *vg = d->host_data;
+
+	irq_set_chip_and_handler_name(virq, &byt_irqchip, handle_simple_irq,
+				      "demux");
+	irq_set_chip_data(virq, vg);
+	irq_set_irq_type(virq, IRQ_TYPE_NONE);
+
+	return 0;
+}
+
+static const struct irq_domain_ops byt_gpio_irq_ops = {
+	.map = byt_gpio_irq_map,
+};
+
+static int byt_gpio_probe(struct platform_device *pdev)
+{
+	struct byt_gpio *vg;
+	struct gpio_chip *gc;
+	struct resource *mem_rc, *irq_rc;
+	struct device *dev = &pdev->dev;
+	struct acpi_device *acpi_dev;
+	struct pinctrl_gpio_range *range;
+	acpi_handle handle = ACPI_HANDLE(dev);
+	unsigned hwirq;
+	int ret;
+
+	if (acpi_bus_get_device(handle, &acpi_dev))
+		return -ENODEV;
+
+	vg = devm_kzalloc(dev, sizeof(struct byt_gpio), GFP_KERNEL);
+	if (!vg) {
+		dev_err(&pdev->dev, "can't allocate byt_gpio chip data\n");
+		return -ENOMEM;
+	}
+
+	for (range = byt_ranges; range->name; range++) {
+		if (!strcmp(acpi_dev->pnp.unique_id, range->name)) {
+			vg->chip.ngpio = range->npins;
+			vg->range = range;
+			break;
+		}
+	}
+
+	if (!vg->chip.ngpio || !vg->range)
+		return -ENODEV;
+
+	vg->pdev = pdev;
+	platform_set_drvdata(pdev, vg);
+
+	mem_rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	vg->reg_base = devm_ioremap_resource(dev, mem_rc);
+	if (IS_ERR(vg->reg_base))
+		return PTR_ERR(vg->reg_base);
+
+	spin_lock_init(&vg->lock);
+
+	gc = &vg->chip;
+	gc->label = dev_name(&pdev->dev);
+	gc->owner = THIS_MODULE;
+	gc->request = byt_gpio_request;
+	gc->free = byt_gpio_free;
+	gc->direction_input = byt_gpio_direction_input;
+	gc->direction_output = byt_gpio_direction_output;
+	gc->get = byt_gpio_get;
+	gc->set = byt_gpio_set;
+	gc->dbg_show = byt_gpio_dbg_show;
+	gc->base = -1;
+	gc->can_sleep = 0;
+	gc->dev = dev;
+
+	ret = gpiochip_add(gc);
+	if (ret) {
+		dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
+		return ret;
+	}
+
+	/* set up interrupts  */
+	irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (irq_rc && irq_rc->start) {
+		hwirq = irq_rc->start;
+		gc->to_irq = byt_gpio_to_irq;
+
+		vg->domain = irq_domain_add_linear(NULL, gc->ngpio,
+						   &byt_gpio_irq_ops, vg);
+		if (!vg->domain)
+			return -ENXIO;
+
+		byt_gpio_irq_init_hw(vg);
+
+		irq_set_handler_data(hwirq, vg);
+		irq_set_chained_handler(hwirq, byt_gpio_irq_handler);
+
+		/* Register interrupt handlers for gpio signaled acpi events */
+		acpi_gpiochip_request_interrupts(gc);
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+}
+
+static int byt_gpio_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int byt_gpio_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops byt_gpio_pm_ops = {
+	.runtime_suspend = byt_gpio_runtime_suspend,
+	.runtime_resume = byt_gpio_runtime_resume,
+};
+
+static const struct acpi_device_id byt_gpio_acpi_match[] = {
+	{ "INT33B2", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match);
+
+static int byt_gpio_remove(struct platform_device *pdev)
+{
+	struct byt_gpio *vg = platform_get_drvdata(pdev);
+	int err;
+	pm_runtime_disable(&pdev->dev);
+	err = gpiochip_remove(&vg->chip);
+	if (err)
+		dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
+
+	return 0;
+}
+
+static struct platform_driver byt_gpio_driver = {
+	.probe          = byt_gpio_probe,
+	.remove         = byt_gpio_remove,
+	.driver         = {
+		.name   = "byt_gpio",
+		.owner  = THIS_MODULE,
+		.pm	= &byt_gpio_pm_ops,
+		.acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
+	},
+};
+
+static int __init byt_gpio_init(void)
+{
+	return platform_driver_register(&byt_gpio_driver);
+}
+
+subsys_initcall(byt_gpio_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-bcm2835.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-bcm2835.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-bcm2835.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-bcm2835.c	2013-08-25 20:43:22.000000000 -0400
@@ -113,7 +113,7 @@ static struct lock_class_key gpio_lock_c
 
 /* pins are just named GPIO0..GPIO53 */
 #define BCM2835_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a)
-struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
+static struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
 	BCM2835_GPIO_PIN(0),
 	BCM2835_GPIO_PIN(1),
 	BCM2835_GPIO_PIN(2),
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-coh901.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-coh901.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-coh901.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-coh901.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/slab.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/pinconf-generic.h>
-#include <linux/platform_data/pinctrl-coh901.h>
 #include "pinctrl-coh901.h"
 
 #define U300_GPIO_PORT_STRIDE				(0x30)
@@ -58,8 +57,9 @@
 #define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE		(0x00000001UL)
 
 /* 8 bits per port, no version has more than 7 ports */
+#define U300_GPIO_NUM_PORTS 7
 #define U300_GPIO_PINS_PER_PORT 8
-#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * 7)
+#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS)
 
 struct u300_gpio {
 	struct gpio_chip chip;
@@ -111,9 +111,6 @@ struct u300_gpio_confdata {
 	int outval;
 };
 
-/* BS335 has seven ports of 8 bits each = GPIO pins 0..55 */
-#define BS335_GPIO_NUM_PORTS 7
-
 #define U300_FLOATING_INPUT { \
 	.bias_mode = PIN_CONFIG_BIAS_HIGH_IMPEDANCE, \
 	.output = false, \
@@ -136,7 +133,7 @@ struct u300_gpio_confdata {
 
 /* Initial configuration */
 static const struct __initconst u300_gpio_confdata
-bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
+bs335_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
 	/* Port 0, pins 0-7 */
 	{
 		U300_FLOATING_INPUT,
@@ -630,13 +627,12 @@ static void __init u300_gpio_init_pin(st
 	}
 }
 
-static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio,
-				     struct u300_gpio_platform *plat)
+static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio)
 {
 	int i, j;
 
 	/* Write default config and values to all pins */
-	for (i = 0; i < plat->ports; i++) {
+	for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
 		for (j = 0; j < 8; j++) {
 			const struct u300_gpio_confdata *conf;
 			int offset = (i*8) + j;
@@ -693,7 +689,6 @@ static struct coh901_pinpair coh901_pint
 
 static int __init u300_gpio_probe(struct platform_device *pdev)
 {
-	struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev);
 	struct u300_gpio *gpio;
 	struct resource *memres;
 	int err = 0;
@@ -707,9 +702,9 @@ static int __init u300_gpio_probe(struct
 		return -ENOMEM;
 
 	gpio->chip = u300_gpio_chip;
-	gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT;
+	gpio->chip.ngpio = U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT;
 	gpio->chip.dev = &pdev->dev;
-	gpio->chip.base = plat->gpio_base;
+	gpio->chip.base = 0;
 	gpio->dev = &pdev->dev;
 
 	memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -750,11 +745,11 @@ static int __init u300_gpio_probe(struct
 		 ((val & 0x0000FE00) >> 9) * 8);
 	writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE,
 	       gpio->base + U300_GPIO_CR);
-	u300_gpio_init_coh901571(gpio, plat);
+	u300_gpio_init_coh901571(gpio);
 
 	/* Add each port with its IRQ separately */
 	INIT_LIST_HEAD(&gpio->port_list);
-	for (portno = 0 ; portno < plat->ports; portno++) {
+	for (portno = 0 ; portno < U300_GPIO_NUM_PORTS; portno++) {
 		struct u300_gpio_port *port =
 			kmalloc(sizeof(struct u300_gpio_port), GFP_KERNEL);
 
@@ -768,8 +763,7 @@ static int __init u300_gpio_probe(struct
 		port->number = portno;
 		port->gpio = gpio;
 
-		port->irq = platform_get_irq_byname(pdev,
-						    port->name);
+		port->irq = platform_get_irq(pdev, portno);
 
 		dev_dbg(gpio->dev, "register IRQ %d for port %s\n", port->irq,
 			port->name);
@@ -806,6 +800,9 @@ static int __init u300_gpio_probe(struct
 	}
 	dev_dbg(gpio->dev, "initialized %d GPIO ports\n", portno);
 
+#ifdef CONFIG_OF_GPIO
+	gpio->chip.of_node = pdev->dev.of_node;
+#endif
 	err = gpiochip_add(&gpio->chip);
 	if (err) {
 		dev_err(gpio->dev, "unable to add gpiochip: %d\n", err);
@@ -856,13 +853,18 @@ static int __exit u300_gpio_remove(struc
 	}
 	u300_gpio_free_ports(gpio);
 	clk_disable_unprepare(gpio->clk);
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
+static const struct of_device_id u300_gpio_match[] = {
+	{ .compatible = "stericsson,gpio-coh901" },
+	{},
+};
+
 static struct platform_driver u300_gpio_driver = {
 	.driver		= {
 		.name	= "u300-gpio",
+		.of_match_table = u300_gpio_match,
 	},
 	.remove		= __exit_p(u300_gpio_remove),
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-exynos5440.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-exynos5440.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-exynos5440.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-exynos5440.c	2013-08-25 20:43:22.000000000 -0400
@@ -220,7 +220,7 @@ static int exynos5440_dt_node_to_map(str
 		dev_err(dev, "failed to alloc memory for group name\n");
 		goto free_map;
 	}
-	sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
+	snprintf(gname, strlen(np->name) + 4, "%s%s", np->name, GROUP_SUFFIX);
 
 	/*
 	 * don't have config options? then skip over to creating function
@@ -259,7 +259,8 @@ skip_cfgs:
 			dev_err(dev, "failed to alloc memory for func name\n");
 			goto free_cfg;
 		}
-		sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
+		snprintf(fname, strlen(np->name) + 4, "%s%s", np->name,
+			 FUNCTION_SUFFIX);
 
 		map[*nmaps].data.mux.group = gname;
 		map[*nmaps].data.mux.function = fname;
@@ -713,7 +714,8 @@ static int exynos5440_pinctrl_parse_dt(s
 			dev_err(dev, "failed to alloc memory for group name\n");
 			return -ENOMEM;
 		}
-		sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
+		snprintf(gname, strlen(cfg_np->name) + 4, "%s%s", cfg_np->name,
+			 GROUP_SUFFIX);
 
 		grp->name = gname;
 		grp->pins = pin_list;
@@ -733,7 +735,8 @@ skip_to_pin_function:
 			dev_err(dev, "failed to alloc memory for func name\n");
 			return -ENOMEM;
 		}
-		sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
+		snprintf(fname, strlen(cfg_np->name) + 4, "%s%s", cfg_np->name,
+			 FUNCTION_SUFFIX);
 
 		func->name = fname;
 		func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
@@ -806,7 +809,7 @@ static int exynos5440_pinctrl_register(s
 
 	/* for each pin, set the name of the pin */
 	for (pin = 0; pin < ctrldesc->npins; pin++) {
-		sprintf(pin_names, "gpio%02d", pin);
+		snprintf(pin_names, 6, "gpio%02d", pin);
 		pdesc = pindesc + pin;
 		pdesc->name = pin_names;
 		pin_names += PIN_NAME_LENGTH;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-exynos.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-exynos.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-exynos.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-exynos.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,37 +50,58 @@ static const struct of_device_id exynos_
 	{ }
 };
 
-static void exynos_gpio_irq_unmask(struct irq_data *irqd)
+static void exynos_gpio_irq_mask(struct irq_data *irqd)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 	struct samsung_pinctrl_drv_data *d = bank->drvdata;
 	unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
 	unsigned long mask;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->slock, flags);
 
 	mask = readl(d->virt_base + reg_mask);
-	mask &= ~(1 << irqd->hwirq);
+	mask |= 1 << irqd->hwirq;
 	writel(mask, d->virt_base + reg_mask);
+
+	spin_unlock_irqrestore(&bank->slock, flags);
 }
 
-static void exynos_gpio_irq_mask(struct irq_data *irqd)
+static void exynos_gpio_irq_ack(struct irq_data *irqd)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 	struct samsung_pinctrl_drv_data *d = bank->drvdata;
-	unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
-	unsigned long mask;
+	unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
 
-	mask = readl(d->virt_base + reg_mask);
-	mask |= 1 << irqd->hwirq;
-	writel(mask, d->virt_base + reg_mask);
+	writel(1 << irqd->hwirq, d->virt_base + reg_pend);
 }
 
-static void exynos_gpio_irq_ack(struct irq_data *irqd)
+static void exynos_gpio_irq_unmask(struct irq_data *irqd)
 {
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 	struct samsung_pinctrl_drv_data *d = bank->drvdata;
-	unsigned long reg_pend = d->ctrl->geint_pend + bank->eint_offset;
+	unsigned long reg_mask = d->ctrl->geint_mask + bank->eint_offset;
+	unsigned long mask;
+	unsigned long flags;
 
-	writel(1 << irqd->hwirq, d->virt_base + reg_pend);
+	/*
+	 * Ack level interrupts right before unmask
+	 *
+	 * If we don't do this we'll get a double-interrupt.  Level triggered
+	 * interrupts must not fire an interrupt if the level is not
+	 * _currently_ active, even if it was active while the interrupt was
+	 * masked.
+	 */
+	if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
+		exynos_gpio_irq_ack(irqd);
+
+	spin_lock_irqsave(&bank->slock, flags);
+
+	mask = readl(d->virt_base + reg_mask);
+	mask &= ~(1 << irqd->hwirq);
+	writel(mask, d->virt_base + reg_mask);
+
+	spin_unlock_irqrestore(&bank->slock, flags);
 }
 
 static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
@@ -258,37 +279,58 @@ err_domains:
 	return ret;
 }
 
-static void exynos_wkup_irq_unmask(struct irq_data *irqd)
+static void exynos_wkup_irq_mask(struct irq_data *irqd)
 {
 	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
 	struct samsung_pinctrl_drv_data *d = b->drvdata;
 	unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
 	unsigned long mask;
+	unsigned long flags;
+
+	spin_lock_irqsave(&b->slock, flags);
 
 	mask = readl(d->virt_base + reg_mask);
-	mask &= ~(1 << irqd->hwirq);
+	mask |= 1 << irqd->hwirq;
 	writel(mask, d->virt_base + reg_mask);
+
+	spin_unlock_irqrestore(&b->slock, flags);
 }
 
-static void exynos_wkup_irq_mask(struct irq_data *irqd)
+static void exynos_wkup_irq_ack(struct irq_data *irqd)
 {
 	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
 	struct samsung_pinctrl_drv_data *d = b->drvdata;
-	unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
-	unsigned long mask;
+	unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
 
-	mask = readl(d->virt_base + reg_mask);
-	mask |= 1 << irqd->hwirq;
-	writel(mask, d->virt_base + reg_mask);
+	writel(1 << irqd->hwirq, d->virt_base + pend);
 }
 
-static void exynos_wkup_irq_ack(struct irq_data *irqd)
+static void exynos_wkup_irq_unmask(struct irq_data *irqd)
 {
 	struct samsung_pin_bank *b = irq_data_get_irq_chip_data(irqd);
 	struct samsung_pinctrl_drv_data *d = b->drvdata;
-	unsigned long pend = d->ctrl->weint_pend + b->eint_offset;
+	unsigned long reg_mask = d->ctrl->weint_mask + b->eint_offset;
+	unsigned long mask;
+	unsigned long flags;
 
-	writel(1 << irqd->hwirq, d->virt_base + pend);
+	/*
+	 * Ack level interrupts right before unmask
+	 *
+	 * If we don't do this we'll get a double-interrupt.  Level triggered
+	 * interrupts must not fire an interrupt if the level is not
+	 * _currently_ active, even if it was active while the interrupt was
+	 * masked.
+	 */
+	if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
+		exynos_wkup_irq_ack(irqd);
+
+	spin_lock_irqsave(&b->slock, flags);
+
+	mask = readl(d->virt_base + reg_mask);
+	mask &= ~(1 << irqd->hwirq);
+	writel(mask, d->virt_base + reg_mask);
+
+	spin_unlock_irqrestore(&b->slock, flags);
 }
 
 static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
@@ -941,3 +983,121 @@ struct samsung_pin_ctrl exynos5250_pin_c
 		.label		= "exynos5250-gpio-ctrl3",
 	},
 };
+
+/* pin banks of exynos5420 pin-controller 0 */
+static struct samsung_pin_bank exynos5420_pin_banks0[] = {
+	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpy7", 0x00),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC00, "gpx0", 0x00),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC20, "gpx1", 0x04),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC40, "gpx2", 0x08),
+	EXYNOS_PIN_BANK_EINTW(8, 0xC60, "gpx3", 0x0c),
+};
+
+/* pin banks of exynos5420 pin-controller 1 */
+static struct samsung_pin_bank exynos5420_pin_banks1[] = {
+	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpc0", 0x00),
+	EXYNOS_PIN_BANK_EINTG(8, 0x020, "gpc1", 0x04),
+	EXYNOS_PIN_BANK_EINTG(7, 0x040, "gpc2", 0x08),
+	EXYNOS_PIN_BANK_EINTG(4, 0x060, "gpc3", 0x0c),
+	EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpc4", 0x10),
+	EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpd1", 0x14),
+	EXYNOS_PIN_BANK_EINTN(6, 0x0C0, "gpy0"),
+	EXYNOS_PIN_BANK_EINTN(4, 0x0E0, "gpy1"),
+	EXYNOS_PIN_BANK_EINTN(6, 0x100, "gpy2"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x120, "gpy3"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x140, "gpy4"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x160, "gpy5"),
+	EXYNOS_PIN_BANK_EINTN(8, 0x180, "gpy6"),
+};
+
+/* pin banks of exynos5420 pin-controller 2 */
+static struct samsung_pin_bank exynos5420_pin_banks2[] = {
+	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpe0", 0x00),
+	EXYNOS_PIN_BANK_EINTG(2, 0x020, "gpe1", 0x04),
+	EXYNOS_PIN_BANK_EINTG(6, 0x040, "gpf0", 0x08),
+	EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpf1", 0x0c),
+	EXYNOS_PIN_BANK_EINTG(8, 0x080, "gpg0", 0x10),
+	EXYNOS_PIN_BANK_EINTG(8, 0x0A0, "gpg1", 0x14),
+	EXYNOS_PIN_BANK_EINTG(2, 0x0C0, "gpg2", 0x18),
+	EXYNOS_PIN_BANK_EINTG(4, 0x0E0, "gpj4", 0x1c),
+};
+
+/* pin banks of exynos5420 pin-controller 3 */
+static struct samsung_pin_bank exynos5420_pin_banks3[] = {
+	EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpa0", 0x00),
+	EXYNOS_PIN_BANK_EINTG(6, 0x020, "gpa1", 0x04),
+	EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpa2", 0x08),
+	EXYNOS_PIN_BANK_EINTG(5, 0x060, "gpb0", 0x0c),
+	EXYNOS_PIN_BANK_EINTG(5, 0x080, "gpb1", 0x10),
+	EXYNOS_PIN_BANK_EINTG(4, 0x0A0, "gpb2", 0x14),
+	EXYNOS_PIN_BANK_EINTG(8, 0x0C0, "gpb3", 0x18),
+	EXYNOS_PIN_BANK_EINTG(2, 0x0E0, "gpb4", 0x1c),
+	EXYNOS_PIN_BANK_EINTG(8, 0x100, "gph0", 0x20),
+};
+
+/* pin banks of exynos5420 pin-controller 4 */
+static struct samsung_pin_bank exynos5420_pin_banks4[] = {
+	EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz", 0x00),
+};
+
+/*
+ * Samsung pinctrl driver data for Exynos5420 SoC. Exynos5420 SoC includes
+ * four gpio/pin-mux/pinconfig controllers.
+ */
+struct samsung_pin_ctrl exynos5420_pin_ctrl[] = {
+	{
+		/* pin-controller instance 0 data */
+		.pin_banks	= exynos5420_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(exynos5420_pin_banks0),
+		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
+		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
+		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
+		.weint_con	= EXYNOS_WKUP_ECON_OFFSET,
+		.weint_mask	= EXYNOS_WKUP_EMASK_OFFSET,
+		.weint_pend	= EXYNOS_WKUP_EPEND_OFFSET,
+		.svc		= EXYNOS_SVC_OFFSET,
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.eint_wkup_init = exynos_eint_wkup_init,
+		.label		= "exynos5420-gpio-ctrl0",
+	}, {
+		/* pin-controller instance 1 data */
+		.pin_banks	= exynos5420_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(exynos5420_pin_banks1),
+		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
+		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
+		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
+		.svc		= EXYNOS_SVC_OFFSET,
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.label		= "exynos5420-gpio-ctrl1",
+	}, {
+		/* pin-controller instance 2 data */
+		.pin_banks	= exynos5420_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(exynos5420_pin_banks2),
+		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
+		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
+		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
+		.svc		= EXYNOS_SVC_OFFSET,
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.label		= "exynos5420-gpio-ctrl2",
+	}, {
+		/* pin-controller instance 3 data */
+		.pin_banks	= exynos5420_pin_banks3,
+		.nr_banks	= ARRAY_SIZE(exynos5420_pin_banks3),
+		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
+		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
+		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
+		.svc		= EXYNOS_SVC_OFFSET,
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.label		= "exynos5420-gpio-ctrl3",
+	}, {
+		/* pin-controller instance 4 data */
+		.pin_banks	= exynos5420_pin_banks4,
+		.nr_banks	= ARRAY_SIZE(exynos5420_pin_banks4),
+		.geint_con	= EXYNOS_GPIO_ECON_OFFSET,
+		.geint_mask	= EXYNOS_GPIO_EMASK_OFFSET,
+		.geint_pend	= EXYNOS_GPIO_EPEND_OFFSET,
+		.svc		= EXYNOS_SVC_OFFSET,
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.label		= "exynos5420-gpio-ctrl4",
+	},
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-imx.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-imx.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-imx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-imx.c	2013-08-25 20:43:22.000000000 -0400
@@ -221,13 +221,21 @@ static int imx_pmx_enable(struct pinctrl
 		pin_id = pins[i];
 		pin_reg = &info->pin_regs[pin_id];
 
-		if (!pin_reg->mux_reg) {
+		if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->mux_reg) {
 			dev_err(ipctl->dev, "Pin(%s) does not support mux function\n",
 				info->pins[pin_id].name);
 			return -EINVAL;
 		}
 
-		writel(mux[i], ipctl->base + pin_reg->mux_reg);
+		if (info->flags & SHARE_MUX_CONF_REG) {
+			u32 reg;
+			reg = readl(ipctl->base + pin_reg->mux_reg);
+			reg &= ~(0x7 << 20);
+			reg |= (mux[i] << 20);
+			writel(reg, ipctl->base + pin_reg->mux_reg);
+		} else {
+			writel(mux[i], ipctl->base + pin_reg->mux_reg);
+		}
 		dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%x\n",
 			pin_reg->mux_reg, mux[i]);
 
@@ -287,7 +295,7 @@ static int imx_pinconf_get(struct pinctr
 	const struct imx_pinctrl_soc_info *info = ipctl->info;
 	const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
 
-	if (!pin_reg->conf_reg) {
+	if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
 		dev_err(info->dev, "Pin(%s) does not support config function\n",
 			info->pins[pin_id].name);
 		return -EINVAL;
@@ -295,6 +303,9 @@ static int imx_pinconf_get(struct pinctr
 
 	*config = readl(ipctl->base + pin_reg->conf_reg);
 
+	if (info->flags & SHARE_MUX_CONF_REG)
+		*config &= 0xffff;
+
 	return 0;
 }
 
@@ -305,7 +316,7 @@ static int imx_pinconf_set(struct pinctr
 	const struct imx_pinctrl_soc_info *info = ipctl->info;
 	const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
 
-	if (!pin_reg->conf_reg) {
+	if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
 		dev_err(info->dev, "Pin(%s) does not support config function\n",
 			info->pins[pin_id].name);
 		return -EINVAL;
@@ -314,7 +325,15 @@ static int imx_pinconf_set(struct pinctr
 	dev_dbg(ipctl->dev, "pinconf set pin %s\n",
 		info->pins[pin_id].name);
 
-	writel(config, ipctl->base + pin_reg->conf_reg);
+	if (info->flags & SHARE_MUX_CONF_REG) {
+		u32 reg;
+		reg = readl(ipctl->base + pin_reg->conf_reg);
+		reg &= ~0xffff;
+		reg |= config;
+		writel(reg, ipctl->base + pin_reg->conf_reg);
+	} else {
+		writel(config, ipctl->base + pin_reg->conf_reg);
+	}
 	dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
 		pin_reg->conf_reg, config);
 
@@ -381,19 +400,24 @@ static struct pinctrl_desc imx_pinctrl_d
  * 1 u32 CONFIG, so 24 types in total for each pin.
  */
 #define FSL_PIN_SIZE 24
+#define SHARE_FSL_PIN_SIZE 20
 
 static int imx_pinctrl_parse_groups(struct device_node *np,
 				    struct imx_pin_group *grp,
 				    struct imx_pinctrl_soc_info *info,
 				    u32 index)
 {
-	int size;
+	int size, pin_size;
 	const __be32 *list;
 	int i;
 	u32 config;
 
 	dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
 
+	if (info->flags & SHARE_MUX_CONF_REG)
+		pin_size = SHARE_FSL_PIN_SIZE;
+	else
+		pin_size = FSL_PIN_SIZE;
 	/* Initialise group */
 	grp->name = np->name;
 
@@ -403,12 +427,12 @@ static int imx_pinctrl_parse_groups(stru
 	 */
 	list = of_get_property(np, "fsl,pins", &size);
 	/* we do not check return since it's safe node passed down */
-	if (!size || size % FSL_PIN_SIZE) {
+	if (!size || size % pin_size) {
 		dev_err(info->dev, "Invalid fsl,pins property\n");
 		return -EINVAL;
 	}
 
-	grp->npins = size / FSL_PIN_SIZE;
+	grp->npins = size / pin_size;
 	grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
 				GFP_KERNEL);
 	grp->mux_mode = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
@@ -421,10 +445,17 @@ static int imx_pinctrl_parse_groups(stru
 				GFP_KERNEL);
 	for (i = 0; i < grp->npins; i++) {
 		u32 mux_reg = be32_to_cpu(*list++);
-		u32 conf_reg = be32_to_cpu(*list++);
-		unsigned int pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4;
-		struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+		u32 conf_reg;
+		unsigned int pin_id;
+		struct imx_pin_reg *pin_reg;
 
+		if (info->flags & SHARE_MUX_CONF_REG)
+			conf_reg = mux_reg;
+		else
+			conf_reg = be32_to_cpu(*list++);
+
+		pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4;
+		pin_reg = &info->pin_regs[pin_id];
 		grp->pins[i] = pin_id;
 		pin_reg->mux_reg = mux_reg;
 		pin_reg->conf_reg = conf_reg;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-imx.h linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-imx.h
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-imx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-imx.h	2013-08-25 20:43:22.000000000 -0400
@@ -74,8 +74,12 @@ struct imx_pinctrl_soc_info {
 	unsigned int ngroups;
 	struct imx_pmx_func *functions;
 	unsigned int nfunctions;
+	unsigned int flags;
 };
 
+#define ZERO_OFFSET_VALID	0x1
+#define SHARE_MUX_CONF_REG	0x2
+
 #define NO_MUX		0x0
 #define NO_PAD		0x0
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-mxs.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-mxs.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-mxs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-mxs.c	2013-08-25 20:43:22.000000000 -0400
@@ -515,7 +515,6 @@ int mxs_pinctrl_probe(struct platform_de
 	return 0;
 
 err:
-	platform_set_drvdata(pdev, NULL);
 	iounmap(d->base);
 	return ret;
 }
@@ -525,7 +524,6 @@ int mxs_pinctrl_remove(struct platform_d
 {
 	struct mxs_pinctrl_data *d = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	pinctrl_unregister(d->pctl);
 	iounmap(d->base);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-nomadik.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-nomadik.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-nomadik.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-nomadik.c	2013-08-25 20:43:22.000000000 -0400
@@ -1309,7 +1309,7 @@ static int nmk_gpio_irq_map(struct irq_d
 	return 0;
 }
 
-const struct irq_domain_ops nmk_gpio_irq_simple_ops = {
+static const struct irq_domain_ops nmk_gpio_irq_simple_ops = {
 	.map = nmk_gpio_irq_map,
 	.xlate = irq_domain_xlate_twocell,
 };
@@ -1681,7 +1681,7 @@ static bool nmk_pinctrl_dt_get_config(st
 	return has_config;
 }
 
-int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+static int nmk_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
 		struct device_node *np,
 		struct pinctrl_map **map,
 		unsigned *reserved_maps,
@@ -1740,7 +1740,7 @@ exit:
 	return ret;
 }
 
-int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+static int nmk_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
 				 struct device_node *np_config,
 				 struct pinctrl_map **map, unsigned *num_maps)
 {
@@ -2104,15 +2104,15 @@ static struct pinctrl_desc nmk_pinctrl_d
 
 static const struct of_device_id nmk_pinctrl_match[] = {
 	{
-		.compatible = "stericsson,nmk-pinctrl-stn8815",
+		.compatible = "stericsson,stn8815-pinctrl",
 		.data = (void *)PINCTRL_NMK_STN8815,
 	},
 	{
-		.compatible = "stericsson,nmk-pinctrl",
+		.compatible = "stericsson,db8500-pinctrl",
 		.data = (void *)PINCTRL_NMK_DB8500,
 	},
 	{
-		.compatible = "stericsson,nmk-pinctrl-db8540",
+		.compatible = "stericsson,db8540-pinctrl",
 		.data = (void *)PINCTRL_NMK_DB8540,
 	},
 	{},
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-rockchip.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-rockchip.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-rockchip.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-rockchip.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1394 @@
+/*
+ * Pinctrl driver for Rockchip SoCs
+ *
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * With some ideas taken from pinctrl-samsung:
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2012 Linaro Ltd
+ *		http://www.linaro.org
+ *
+ * and pinctrl-at91:
+ * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/clk-provider.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+#include "core.h"
+#include "pinconf.h"
+
+/* GPIO control registers */
+#define GPIO_SWPORT_DR		0x00
+#define GPIO_SWPORT_DDR		0x04
+#define GPIO_INTEN		0x30
+#define GPIO_INTMASK		0x34
+#define GPIO_INTTYPE_LEVEL	0x38
+#define GPIO_INT_POLARITY	0x3c
+#define GPIO_INT_STATUS		0x40
+#define GPIO_INT_RAWSTATUS	0x44
+#define GPIO_DEBOUNCE		0x48
+#define GPIO_PORTS_EOI		0x4c
+#define GPIO_EXT_PORT		0x50
+#define GPIO_LS_SYNC		0x60
+
+/**
+ * @reg_base: register base of the gpio bank
+ * @clk: clock of the gpio bank
+ * @irq: interrupt of the gpio bank
+ * @pin_base: first pin number
+ * @nr_pins: number of pins in this bank
+ * @name: name of the bank
+ * @bank_num: number of the bank, to account for holes
+ * @valid: are all necessary informations present
+ * @of_node: dt node of this bank
+ * @drvdata: common pinctrl basedata
+ * @domain: irqdomain of the gpio bank
+ * @gpio_chip: gpiolib chip
+ * @grange: gpio range
+ * @slock: spinlock for the gpio bank
+ */
+struct rockchip_pin_bank {
+	void __iomem			*reg_base;
+	struct clk			*clk;
+	int				irq;
+	u32				pin_base;
+	u8				nr_pins;
+	char				*name;
+	u8				bank_num;
+	bool				valid;
+	struct device_node		*of_node;
+	struct rockchip_pinctrl		*drvdata;
+	struct irq_domain		*domain;
+	struct gpio_chip		gpio_chip;
+	struct pinctrl_gpio_range	grange;
+	spinlock_t			slock;
+
+};
+
+#define PIN_BANK(id, pins, label)			\
+	{						\
+		.bank_num	= id,			\
+		.nr_pins	= pins,			\
+		.name		= label,		\
+	}
+
+/**
+ * @pull_auto: some SoCs don't allow pulls to be specified as up or down, but
+ *	       instead decide this automatically based on the pad-type.
+ */
+struct rockchip_pin_ctrl {
+	struct rockchip_pin_bank	*pin_banks;
+	u32				nr_banks;
+	u32				nr_pins;
+	char				*label;
+	int				mux_offset;
+	int				pull_offset;
+	bool				pull_auto;
+	int				pull_bank_stride;
+};
+
+struct rockchip_pin_config {
+	unsigned int		func;
+	unsigned long		*configs;
+	unsigned int		nconfigs;
+};
+
+/**
+ * struct rockchip_pin_group: represent group of pins of a pinmux function.
+ * @name: name of the pin group, used to lookup the group.
+ * @pins: the pins included in this group.
+ * @npins: number of pins included in this group.
+ * @func: the mux function number to be programmed when selected.
+ * @configs: the config values to be set for each pin
+ * @nconfigs: number of configs for each pin
+ */
+struct rockchip_pin_group {
+	const char			*name;
+	unsigned int			npins;
+	unsigned int			*pins;
+	struct rockchip_pin_config	*data;
+};
+
+/**
+ * struct rockchip_pmx_func: represent a pin function.
+ * @name: name of the pin function, used to lookup the function.
+ * @groups: one or more names of pin groups that provide this function.
+ * @num_groups: number of groups included in @groups.
+ */
+struct rockchip_pmx_func {
+	const char		*name;
+	const char		**groups;
+	u8			ngroups;
+};
+
+struct rockchip_pinctrl {
+	void __iomem			*reg_base;
+	struct device			*dev;
+	struct rockchip_pin_ctrl	*ctrl;
+	struct pinctrl_desc		pctl;
+	struct pinctrl_dev		*pctl_dev;
+	struct rockchip_pin_group	*groups;
+	unsigned int			ngroups;
+	struct rockchip_pmx_func	*functions;
+	unsigned int			nfunctions;
+};
+
+static inline struct rockchip_pin_bank *gc_to_pin_bank(struct gpio_chip *gc)
+{
+	return container_of(gc, struct rockchip_pin_bank, gpio_chip);
+}
+
+static const inline struct rockchip_pin_group *pinctrl_name_to_group(
+					const struct rockchip_pinctrl *info,
+					const char *name)
+{
+	const struct rockchip_pin_group *grp = NULL;
+	int i;
+
+	for (i = 0; i < info->ngroups; i++) {
+		if (strcmp(info->groups[i].name, name))
+			continue;
+
+		grp = &info->groups[i];
+		break;
+	}
+
+	return grp;
+}
+
+/*
+ * given a pin number that is local to a pin controller, find out the pin bank
+ * and the register base of the pin bank.
+ */
+static struct rockchip_pin_bank *pin_to_bank(struct rockchip_pinctrl *info,
+								unsigned pin)
+{
+	struct rockchip_pin_bank *b = info->ctrl->pin_banks;
+
+	while ((pin >= b->pin_base) &&
+			((b->pin_base + b->nr_pins - 1) < pin))
+		b++;
+
+	return b;
+}
+
+static struct rockchip_pin_bank *bank_num_to_bank(
+					struct rockchip_pinctrl *info,
+					unsigned num)
+{
+	struct rockchip_pin_bank *b = info->ctrl->pin_banks;
+	int i;
+
+	for (i = 0; i < info->ctrl->nr_banks; i++) {
+		if (b->bank_num == num)
+			break;
+
+		b++;
+	}
+
+	if (b->bank_num != num)
+		return ERR_PTR(-EINVAL);
+
+	return b;
+}
+
+/*
+ * Pinctrl_ops handling
+ */
+
+static int rockchip_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->ngroups;
+}
+
+static const char *rockchip_get_group_name(struct pinctrl_dev *pctldev,
+							unsigned selector)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->groups[selector].name;
+}
+
+static int rockchip_get_group_pins(struct pinctrl_dev *pctldev,
+				      unsigned selector, const unsigned **pins,
+				      unsigned *npins)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	*pins = info->groups[selector].pins;
+	*npins = info->groups[selector].npins;
+
+	return 0;
+}
+
+static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
+				 struct device_node *np,
+				 struct pinctrl_map **map, unsigned *num_maps)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	const struct rockchip_pin_group *grp;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num = 1;
+	int i;
+
+	/*
+	 * first find the group of this node and check if we need to create
+	 * config maps for pins
+	 */
+	grp = pinctrl_name_to_group(info, np->name);
+	if (!grp) {
+		dev_err(info->dev, "unable to find group for node %s\n",
+			np->name);
+		return -EINVAL;
+	}
+
+	map_num += grp->npins;
+	new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num,
+								GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	*map = new_map;
+	*num_maps = map_num;
+
+	/* create mux map */
+	parent = of_get_parent(np);
+	if (!parent) {
+		devm_kfree(pctldev->dev, new_map);
+		return -EINVAL;
+	}
+	new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+	new_map[0].data.mux.function = parent->name;
+	new_map[0].data.mux.group = np->name;
+	of_node_put(parent);
+
+	/* create config map */
+	new_map++;
+	for (i = 0; i < grp->npins; i++) {
+		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map[i].data.configs.group_or_pin =
+				pin_get_name(pctldev, grp->pins[i]);
+		new_map[i].data.configs.configs = grp->data[i].configs;
+		new_map[i].data.configs.num_configs = grp->data[i].nconfigs;
+	}
+
+	dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
+		(*map)->data.mux.function, (*map)->data.mux.group, map_num);
+
+	return 0;
+}
+
+static void rockchip_dt_free_map(struct pinctrl_dev *pctldev,
+				    struct pinctrl_map *map, unsigned num_maps)
+{
+}
+
+static const struct pinctrl_ops rockchip_pctrl_ops = {
+	.get_groups_count	= rockchip_get_groups_count,
+	.get_group_name		= rockchip_get_group_name,
+	.get_group_pins		= rockchip_get_group_pins,
+	.dt_node_to_map		= rockchip_dt_node_to_map,
+	.dt_free_map		= rockchip_dt_free_map,
+};
+
+/*
+ * Hardware access
+ */
+
+/*
+ * Set a new mux function for a pin.
+ *
+ * The register is divided into the upper and lower 16 bit. When changing
+ * a value, the previous register value is not read and changed. Instead
+ * it seems the changed bits are marked in the upper 16 bit, while the
+ * changed value gets set in the same offset in the lower 16 bit.
+ * All pin settings seem to be 2 bit wide in both the upper and lower
+ * parts.
+ * @bank: pin bank to change
+ * @pin: pin to change
+ * @mux: new mux function to set
+ */
+static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+	void __iomem *reg = info->reg_base + info->ctrl->mux_offset;
+	unsigned long flags;
+	u8 bit;
+	u32 data;
+
+	dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
+						bank->bank_num, pin, mux);
+
+	/* get basic quadrupel of mux registers and the correct reg inside */
+	reg += bank->bank_num * 0x10;
+	reg += (pin / 8) * 4;
+	bit = (pin % 8) * 2;
+
+	spin_lock_irqsave(&bank->slock, flags);
+
+	data = (3 << (bit + 16));
+	data |= (mux & 3) << bit;
+	writel(data, reg);
+
+	spin_unlock_irqrestore(&bank->slock, flags);
+}
+
+static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+	struct rockchip_pin_ctrl *ctrl = info->ctrl;
+	void __iomem *reg;
+	u8 bit;
+
+	/* rk3066b does support any pulls */
+	if (!ctrl->pull_offset)
+		return PIN_CONFIG_BIAS_DISABLE;
+
+	reg = info->reg_base + ctrl->pull_offset;
+
+	if (ctrl->pull_auto) {
+		reg += bank->bank_num * ctrl->pull_bank_stride;
+		reg += (pin_num / 16) * 4;
+		bit = pin_num % 16;
+
+		return !(readl_relaxed(reg) & BIT(bit))
+				? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
+				: PIN_CONFIG_BIAS_DISABLE;
+	} else {
+		dev_err(info->dev, "pull support for rk31xx not implemented\n");
+		return -EIO;
+	}
+}
+
+static int rockchip_set_pull(struct rockchip_pin_bank *bank,
+					int pin_num, int pull)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+	struct rockchip_pin_ctrl *ctrl = info->ctrl;
+	void __iomem *reg;
+	unsigned long flags;
+	u8 bit;
+	u32 data;
+
+	dev_dbg(info->dev, "setting pull of GPIO%d-%d to %d\n",
+		 bank->bank_num, pin_num, pull);
+
+	/* rk3066b does support any pulls */
+	if (!ctrl->pull_offset)
+		return pull ? -EINVAL : 0;
+
+	reg = info->reg_base + ctrl->pull_offset;
+
+	if (ctrl->pull_auto) {
+		if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
+					pull != PIN_CONFIG_BIAS_DISABLE) {
+			dev_err(info->dev, "only PIN_DEFAULT and DISABLE allowed\n");
+			return -EINVAL;
+		}
+
+		reg += bank->bank_num * ctrl->pull_bank_stride;
+		reg += (pin_num / 16) * 4;
+		bit = pin_num % 16;
+
+		spin_lock_irqsave(&bank->slock, flags);
+
+		data = BIT(bit + 16);
+		if (pull == PIN_CONFIG_BIAS_DISABLE)
+			data |= BIT(bit);
+		writel(data, reg);
+
+		spin_unlock_irqrestore(&bank->slock, flags);
+	} else {
+		if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) {
+			dev_err(info->dev, "pull direction (up/down) needs to be specified\n");
+			return -EINVAL;
+		}
+
+		dev_err(info->dev, "pull support for rk31xx not implemented\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/*
+ * Pinmux_ops handling
+ */
+
+static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->nfunctions;
+}
+
+static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev,
+					  unsigned selector)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->functions[selector].name;
+}
+
+static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev,
+				unsigned selector, const char * const **groups,
+				unsigned * const num_groups)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = info->functions[selector].groups;
+	*num_groups = info->functions[selector].ngroups;
+
+	return 0;
+}
+
+static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
+							    unsigned group)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	const unsigned int *pins = info->groups[group].pins;
+	const struct rockchip_pin_config *data = info->groups[group].data;
+	struct rockchip_pin_bank *bank;
+	int cnt;
+
+	dev_dbg(info->dev, "enable function %s group %s\n",
+		info->functions[selector].name, info->groups[group].name);
+
+	/*
+	 * for each pin in the pin group selected, program the correspoding pin
+	 * pin function number in the config register.
+	 */
+	for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
+		bank = pin_to_bank(info, pins[cnt]);
+		rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
+				 data[cnt].func);
+	}
+
+	return 0;
+}
+
+static void rockchip_pmx_disable(struct pinctrl_dev *pctldev,
+					unsigned selector, unsigned group)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	const unsigned int *pins = info->groups[group].pins;
+	struct rockchip_pin_bank *bank;
+	int cnt;
+
+	dev_dbg(info->dev, "disable function %s group %s\n",
+		info->functions[selector].name, info->groups[group].name);
+
+	for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
+		bank = pin_to_bank(info, pins[cnt]);
+		rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
+	}
+}
+
+/*
+ * The calls to gpio_direction_output() and gpio_direction_input()
+ * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
+ * function called from the gpiolib interface).
+ */
+static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+					      struct pinctrl_gpio_range *range,
+					      unsigned offset, bool input)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct rockchip_pin_bank *bank;
+	struct gpio_chip *chip;
+	int pin;
+	u32 data;
+
+	chip = range->gc;
+	bank = gc_to_pin_bank(chip);
+	pin = offset - chip->base;
+
+	dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
+		 offset, range->name, pin, input ? "input" : "output");
+
+	rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
+
+	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+	/* set bit to 1 for output, 0 for input */
+	if (!input)
+		data |= BIT(pin);
+	else
+		data &= ~BIT(pin);
+	writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
+
+	return 0;
+}
+
+static const struct pinmux_ops rockchip_pmx_ops = {
+	.get_functions_count	= rockchip_pmx_get_funcs_count,
+	.get_function_name	= rockchip_pmx_get_func_name,
+	.get_function_groups	= rockchip_pmx_get_groups,
+	.enable			= rockchip_pmx_enable,
+	.disable		= rockchip_pmx_disable,
+	.gpio_set_direction	= rockchip_pmx_gpio_set_direction,
+};
+
+/*
+ * Pinconf_ops handling
+ */
+
+static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
+					enum pin_config_param pull)
+{
+	/* rk3066b does support any pulls */
+	if (!ctrl->pull_offset)
+		return pull ? false : true;
+
+	if (ctrl->pull_auto) {
+		if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
+					pull != PIN_CONFIG_BIAS_DISABLE)
+			return false;
+	} else {
+		if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
+			return false;
+	}
+
+	return true;
+}
+
+/* set the pin config settings for a specified pin */
+static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+							unsigned long config)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct rockchip_pin_bank *bank = pin_to_bank(info, pin);
+	enum pin_config_param param = pinconf_to_config_param(config);
+	u16 arg = pinconf_to_config_argument(config);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		return rockchip_set_pull(bank, pin - bank->pin_base, param);
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+		if (!rockchip_pinconf_pull_valid(info->ctrl, param))
+			return -ENOTSUPP;
+
+		if (!arg)
+			return -EINVAL;
+
+		return rockchip_set_pull(bank, pin - bank->pin_base, param);
+		break;
+	default:
+		return -ENOTSUPP;
+		break;
+	}
+
+	return 0;
+}
+
+/* get the pin config settings for a specified pin */
+static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
+							unsigned long *config)
+{
+	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct rockchip_pin_bank *bank = pin_to_bank(info, pin);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (rockchip_get_pull(bank, pin - bank->pin_base) != param)
+			return -EINVAL;
+
+		*config = 0;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+		if (!rockchip_pinconf_pull_valid(info->ctrl, param))
+			return -ENOTSUPP;
+
+		if (rockchip_get_pull(bank, pin - bank->pin_base) != param)
+			return -EINVAL;
+
+		*config = 1;
+		break;
+	default:
+		return -ENOTSUPP;
+		break;
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops rockchip_pinconf_ops = {
+	.pin_config_get			= rockchip_pinconf_get,
+	.pin_config_set			= rockchip_pinconf_set,
+};
+
+static const char *gpio_compat = "rockchip,gpio-bank";
+
+static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info,
+						struct device_node *np)
+{
+	struct device_node *child;
+
+	for_each_child_of_node(np, child) {
+		if (of_device_is_compatible(child, gpio_compat))
+			continue;
+
+		info->nfunctions++;
+		info->ngroups += of_get_child_count(child);
+	}
+}
+
+static int rockchip_pinctrl_parse_groups(struct device_node *np,
+					      struct rockchip_pin_group *grp,
+					      struct rockchip_pinctrl *info,
+					      u32 index)
+{
+	struct rockchip_pin_bank *bank;
+	int size;
+	const __be32 *list;
+	int num;
+	int i, j;
+	int ret;
+
+	dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
+
+	/* Initialise group */
+	grp->name = np->name;
+
+	/*
+	 * the binding format is rockchip,pins = <bank pin mux CONFIG>,
+	 * do sanity check and calculate pins number
+	 */
+	list = of_get_property(np, "rockchip,pins", &size);
+	/* we do not check return since it's safe node passed down */
+	size /= sizeof(*list);
+	if (!size || size % 4) {
+		dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n");
+		return -EINVAL;
+	}
+
+	grp->npins = size / 4;
+
+	grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
+						GFP_KERNEL);
+	grp->data = devm_kzalloc(info->dev, grp->npins *
+					  sizeof(struct rockchip_pin_config),
+					GFP_KERNEL);
+	if (!grp->pins || !grp->data)
+		return -ENOMEM;
+
+	for (i = 0, j = 0; i < size; i += 4, j++) {
+		const __be32 *phandle;
+		struct device_node *np_config;
+
+		num = be32_to_cpu(*list++);
+		bank = bank_num_to_bank(info, num);
+		if (IS_ERR(bank))
+			return PTR_ERR(bank);
+
+		grp->pins[j] = bank->pin_base + be32_to_cpu(*list++);
+		grp->data[j].func = be32_to_cpu(*list++);
+
+		phandle = list++;
+		if (!phandle)
+			return -EINVAL;
+
+		np_config = of_find_node_by_phandle(be32_to_cpup(phandle));
+		ret = pinconf_generic_parse_dt_config(np_config,
+				&grp->data[j].configs, &grp->data[j].nconfigs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_pinctrl_parse_functions(struct device_node *np,
+						struct rockchip_pinctrl *info,
+						u32 index)
+{
+	struct device_node *child;
+	struct rockchip_pmx_func *func;
+	struct rockchip_pin_group *grp;
+	int ret;
+	static u32 grp_index;
+	u32 i = 0;
+
+	dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
+
+	func = &info->functions[index];
+
+	/* Initialise function */
+	func->name = np->name;
+	func->ngroups = of_get_child_count(np);
+	if (func->ngroups <= 0)
+		return 0;
+
+	func->groups = devm_kzalloc(info->dev,
+			func->ngroups * sizeof(char *), GFP_KERNEL);
+	if (!func->groups)
+		return -ENOMEM;
+
+	for_each_child_of_node(np, child) {
+		func->groups[i] = child->name;
+		grp = &info->groups[grp_index++];
+		ret = rockchip_pinctrl_parse_groups(child, grp, info, i++);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_pinctrl_parse_dt(struct platform_device *pdev,
+					      struct rockchip_pinctrl *info)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *child;
+	int ret;
+	int i;
+
+	rockchip_pinctrl_child_count(info, np);
+
+	dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
+	dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
+
+	info->functions = devm_kzalloc(dev, info->nfunctions *
+					      sizeof(struct rockchip_pmx_func),
+					      GFP_KERNEL);
+	if (!info->functions) {
+		dev_err(dev, "failed to allocate memory for function list\n");
+		return -EINVAL;
+	}
+
+	info->groups = devm_kzalloc(dev, info->ngroups *
+					    sizeof(struct rockchip_pin_group),
+					    GFP_KERNEL);
+	if (!info->groups) {
+		dev_err(dev, "failed allocate memory for ping group list\n");
+		return -EINVAL;
+	}
+
+	i = 0;
+
+	for_each_child_of_node(np, child) {
+		if (of_device_is_compatible(child, gpio_compat))
+			continue;
+		ret = rockchip_pinctrl_parse_functions(child, info, i++);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to parse function\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int rockchip_pinctrl_register(struct platform_device *pdev,
+					struct rockchip_pinctrl *info)
+{
+	struct pinctrl_desc *ctrldesc = &info->pctl;
+	struct pinctrl_pin_desc *pindesc, *pdesc;
+	struct rockchip_pin_bank *pin_bank;
+	int pin, bank, ret;
+	int k;
+
+	ctrldesc->name = "rockchip-pinctrl";
+	ctrldesc->owner = THIS_MODULE;
+	ctrldesc->pctlops = &rockchip_pctrl_ops;
+	ctrldesc->pmxops = &rockchip_pmx_ops;
+	ctrldesc->confops = &rockchip_pinconf_ops;
+
+	pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
+			info->ctrl->nr_pins, GFP_KERNEL);
+	if (!pindesc) {
+		dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
+		return -ENOMEM;
+	}
+	ctrldesc->pins = pindesc;
+	ctrldesc->npins = info->ctrl->nr_pins;
+
+	pdesc = pindesc;
+	for (bank = 0 , k = 0; bank < info->ctrl->nr_banks; bank++) {
+		pin_bank = &info->ctrl->pin_banks[bank];
+		for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) {
+			pdesc->number = k;
+			pdesc->name = kasprintf(GFP_KERNEL, "%s-%d",
+						pin_bank->name, pin);
+			pdesc++;
+		}
+	}
+
+	info->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, info);
+	if (!info->pctl_dev) {
+		dev_err(&pdev->dev, "could not register pinctrl driver\n");
+		return -EINVAL;
+	}
+
+	for (bank = 0; bank < info->ctrl->nr_banks; ++bank) {
+		pin_bank = &info->ctrl->pin_banks[bank];
+		pin_bank->grange.name = pin_bank->name;
+		pin_bank->grange.id = bank;
+		pin_bank->grange.pin_base = pin_bank->pin_base;
+		pin_bank->grange.base = pin_bank->gpio_chip.base;
+		pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
+		pin_bank->grange.gc = &pin_bank->gpio_chip;
+		pinctrl_add_gpio_range(info->pctl_dev, &pin_bank->grange);
+	}
+
+	ret = rockchip_pinctrl_parse_dt(pdev, info);
+	if (ret) {
+		pinctrl_unregister(info->pctl_dev);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * GPIO handling
+ */
+
+static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct rockchip_pin_bank *bank = gc_to_pin_bank(gc);
+	void __iomem *reg = bank->reg_base + GPIO_SWPORT_DR;
+	unsigned long flags;
+	u32 data;
+
+	spin_lock_irqsave(&bank->slock, flags);
+
+	data = readl(reg);
+	data &= ~BIT(offset);
+	if (value)
+		data |= BIT(offset);
+	writel(data, reg);
+
+	spin_unlock_irqrestore(&bank->slock, flags);
+}
+
+/*
+ * Returns the level of the pin for input direction and setting of the DR
+ * register for output gpios.
+ */
+static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct rockchip_pin_bank *bank = gc_to_pin_bank(gc);
+	u32 data;
+
+	data = readl(bank->reg_base + GPIO_EXT_PORT);
+	data >>= offset;
+	data &= 1;
+	return data;
+}
+
+/*
+ * gpiolib gpio_direction_input callback function. The setting of the pin
+ * mux function as 'gpio input' will be handled by the pinctrl susbsystem
+ * interface.
+ */
+static int rockchip_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	return pinctrl_gpio_direction_input(gc->base + offset);
+}
+
+/*
+ * gpiolib gpio_direction_output callback function. The setting of the pin
+ * mux function as 'gpio output' will be handled by the pinctrl susbsystem
+ * interface.
+ */
+static int rockchip_gpio_direction_output(struct gpio_chip *gc,
+					  unsigned offset, int value)
+{
+	rockchip_gpio_set(gc, offset, value);
+	return pinctrl_gpio_direction_output(gc->base + offset);
+}
+
+/*
+ * gpiolib gpio_to_irq callback function. Creates a mapping between a GPIO pin
+ * and a virtual IRQ, if not already present.
+ */
+static int rockchip_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+	struct rockchip_pin_bank *bank = gc_to_pin_bank(gc);
+	unsigned int virq;
+
+	if (!bank->domain)
+		return -ENXIO;
+
+	virq = irq_create_mapping(bank->domain, offset);
+
+	return (virq) ? : -ENXIO;
+}
+
+static const struct gpio_chip rockchip_gpiolib_chip = {
+	.set = rockchip_gpio_set,
+	.get = rockchip_gpio_get,
+	.direction_input = rockchip_gpio_direction_input,
+	.direction_output = rockchip_gpio_direction_output,
+	.to_irq = rockchip_gpio_to_irq,
+	.owner = THIS_MODULE,
+};
+
+/*
+ * Interrupt handling
+ */
+
+static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_get_chip(irq);
+	struct rockchip_pin_bank *bank = irq_get_handler_data(irq);
+	u32 pend;
+
+	dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name);
+
+	chained_irq_enter(chip, desc);
+
+	pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS);
+
+	while (pend) {
+		unsigned int virq;
+
+		irq = __ffs(pend);
+		pend &= ~BIT(irq);
+		virq = irq_linear_revmap(bank->domain, irq);
+
+		if (!virq) {
+			dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq);
+			continue;
+		}
+
+		dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq);
+
+		generic_handle_irq(virq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+	struct rockchip_pin_bank *bank = gc->private;
+	u32 mask = BIT(d->hwirq);
+	u32 polarity;
+	u32 level;
+	u32 data;
+
+	if (type & IRQ_TYPE_EDGE_BOTH)
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
+	else
+		__irq_set_handler_locked(d->irq, handle_level_irq);
+
+	irq_gc_lock(gc);
+
+	level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL);
+	polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY);
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		level |= mask;
+		polarity |= mask;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		level |= mask;
+		polarity &= ~mask;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		level &= ~mask;
+		polarity |= mask;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		level &= ~mask;
+		polarity &= ~mask;
+		break;
+	default:
+		irq_gc_unlock(gc);
+		return -EINVAL;
+	}
+
+	writel_relaxed(level, gc->reg_base + GPIO_INTTYPE_LEVEL);
+	writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY);
+
+	irq_gc_unlock(gc);
+
+	/* make sure the pin is configured as gpio input */
+	rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+	data &= ~mask;
+	writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
+
+	return 0;
+}
+
+static int rockchip_interrupts_register(struct platform_device *pdev,
+						struct rockchip_pinctrl *info)
+{
+	struct rockchip_pin_ctrl *ctrl = info->ctrl;
+	struct rockchip_pin_bank *bank = ctrl->pin_banks;
+	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	struct irq_chip_generic *gc;
+	int ret;
+	int i;
+
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		if (!bank->valid) {
+			dev_warn(&pdev->dev, "bank %s is not valid\n",
+				 bank->name);
+			continue;
+		}
+
+		bank->domain = irq_domain_add_linear(bank->of_node, 32,
+						&irq_generic_chip_ops, NULL);
+		if (!bank->domain) {
+			dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n",
+				 bank->name);
+			continue;
+		}
+
+		ret = irq_alloc_domain_generic_chips(bank->domain, 32, 1,
+					 "rockchip_gpio_irq", handle_level_irq,
+					 clr, 0, IRQ_GC_INIT_MASK_CACHE);
+		if (ret) {
+			dev_err(&pdev->dev, "could not alloc generic chips for bank %s\n",
+				bank->name);
+			irq_domain_remove(bank->domain);
+			continue;
+		}
+
+		gc = irq_get_domain_generic_chip(bank->domain, 0);
+		gc->reg_base = bank->reg_base;
+		gc->private = bank;
+		gc->chip_types[0].regs.mask = GPIO_INTEN;
+		gc->chip_types[0].regs.ack = GPIO_PORTS_EOI;
+		gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
+		gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+		gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+		gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
+		gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type;
+
+		irq_set_handler_data(bank->irq, bank);
+		irq_set_chained_handler(bank->irq, rockchip_irq_demux);
+	}
+
+	return 0;
+}
+
+static int rockchip_gpiolib_register(struct platform_device *pdev,
+						struct rockchip_pinctrl *info)
+{
+	struct rockchip_pin_ctrl *ctrl = info->ctrl;
+	struct rockchip_pin_bank *bank = ctrl->pin_banks;
+	struct gpio_chip *gc;
+	int ret;
+	int i;
+
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		if (!bank->valid) {
+			dev_warn(&pdev->dev, "bank %s is not valid\n",
+				 bank->name);
+			continue;
+		}
+
+		bank->gpio_chip = rockchip_gpiolib_chip;
+
+		gc = &bank->gpio_chip;
+		gc->base = bank->pin_base;
+		gc->ngpio = bank->nr_pins;
+		gc->dev = &pdev->dev;
+		gc->of_node = bank->of_node;
+		gc->label = bank->name;
+
+		ret = gpiochip_add(gc);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
+							gc->label, ret);
+			goto fail;
+		}
+	}
+
+	rockchip_interrupts_register(pdev, info);
+
+	return 0;
+
+fail:
+	for (--i, --bank; i >= 0; --i, --bank) {
+		if (!bank->valid)
+			continue;
+
+		if (gpiochip_remove(&bank->gpio_chip))
+			dev_err(&pdev->dev, "gpio chip %s remove failed\n",
+							bank->gpio_chip.label);
+	}
+	return ret;
+}
+
+static int rockchip_gpiolib_unregister(struct platform_device *pdev,
+						struct rockchip_pinctrl *info)
+{
+	struct rockchip_pin_ctrl *ctrl = info->ctrl;
+	struct rockchip_pin_bank *bank = ctrl->pin_banks;
+	int ret = 0;
+	int i;
+
+	for (i = 0; !ret && i < ctrl->nr_banks; ++i, ++bank) {
+		if (!bank->valid)
+			continue;
+
+		ret = gpiochip_remove(&bank->gpio_chip);
+	}
+
+	if (ret)
+		dev_err(&pdev->dev, "gpio chip remove failed\n");
+
+	return ret;
+}
+
+static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
+				  struct device *dev)
+{
+	struct resource res;
+
+	if (of_address_to_resource(bank->of_node, 0, &res)) {
+		dev_err(dev, "cannot find IO resource for bank\n");
+		return -ENOENT;
+	}
+
+	bank->reg_base = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(bank->reg_base))
+		return PTR_ERR(bank->reg_base);
+
+	bank->irq = irq_of_parse_and_map(bank->of_node, 0);
+
+	bank->clk = of_clk_get(bank->of_node, 0);
+	if (IS_ERR(bank->clk))
+		return PTR_ERR(bank->clk);
+
+	return clk_prepare_enable(bank->clk);
+}
+
+static const struct of_device_id rockchip_pinctrl_dt_match[];
+
+/* retrieve the soc specific data */
+static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
+						struct rockchip_pinctrl *d,
+						struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *np;
+	struct rockchip_pin_ctrl *ctrl;
+	struct rockchip_pin_bank *bank;
+	int i;
+
+	match = of_match_node(rockchip_pinctrl_dt_match, node);
+	ctrl = (struct rockchip_pin_ctrl *)match->data;
+
+	for_each_child_of_node(node, np) {
+		if (!of_find_property(np, "gpio-controller", NULL))
+			continue;
+
+		bank = ctrl->pin_banks;
+		for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+			if (!strcmp(bank->name, np->name)) {
+				bank->of_node = np;
+
+				if (!rockchip_get_bank_data(bank, &pdev->dev))
+					bank->valid = true;
+
+				break;
+			}
+		}
+	}
+
+	bank = ctrl->pin_banks;
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		spin_lock_init(&bank->slock);
+		bank->drvdata = d;
+		bank->pin_base = ctrl->nr_pins;
+		ctrl->nr_pins += bank->nr_pins;
+	}
+
+	return ctrl;
+}
+
+static int rockchip_pinctrl_probe(struct platform_device *pdev)
+{
+	struct rockchip_pinctrl *info;
+	struct device *dev = &pdev->dev;
+	struct rockchip_pin_ctrl *ctrl;
+	struct resource *res;
+	int ret;
+
+	if (!dev->of_node) {
+		dev_err(dev, "device tree node not found\n");
+		return -ENODEV;
+	}
+
+	info = devm_kzalloc(dev, sizeof(struct rockchip_pinctrl), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	ctrl = rockchip_pinctrl_get_soc_data(info, pdev);
+	if (!ctrl) {
+		dev_err(dev, "driver data not available\n");
+		return -EINVAL;
+	}
+	info->ctrl = ctrl;
+	info->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "cannot find IO resource\n");
+		return -ENOENT;
+	}
+
+	info->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(info->reg_base))
+		return PTR_ERR(info->reg_base);
+
+	ret = rockchip_gpiolib_register(pdev, info);
+	if (ret)
+		return ret;
+
+	ret = rockchip_pinctrl_register(pdev, info);
+	if (ret) {
+		rockchip_gpiolib_unregister(pdev, info);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, info);
+
+	return 0;
+}
+
+static struct rockchip_pin_bank rk2928_pin_banks[] = {
+	PIN_BANK(0, 32, "gpio0"),
+	PIN_BANK(1, 32, "gpio1"),
+	PIN_BANK(2, 32, "gpio2"),
+	PIN_BANK(3, 32, "gpio3"),
+};
+
+static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
+		.pin_banks		= rk2928_pin_banks,
+		.nr_banks		= ARRAY_SIZE(rk2928_pin_banks),
+		.label			= "RK2928-GPIO",
+		.mux_offset		= 0xa8,
+		.pull_offset		= 0x118,
+		.pull_auto		= 1,
+		.pull_bank_stride	= 8,
+};
+
+static struct rockchip_pin_bank rk3066a_pin_banks[] = {
+	PIN_BANK(0, 32, "gpio0"),
+	PIN_BANK(1, 32, "gpio1"),
+	PIN_BANK(2, 32, "gpio2"),
+	PIN_BANK(3, 32, "gpio3"),
+	PIN_BANK(4, 32, "gpio4"),
+	PIN_BANK(6, 16, "gpio6"),
+};
+
+static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
+		.pin_banks		= rk3066a_pin_banks,
+		.nr_banks		= ARRAY_SIZE(rk3066a_pin_banks),
+		.label			= "RK3066a-GPIO",
+		.mux_offset		= 0xa8,
+		.pull_offset		= 0x118,
+		.pull_auto		= 1,
+		.pull_bank_stride	= 8,
+};
+
+static struct rockchip_pin_bank rk3066b_pin_banks[] = {
+	PIN_BANK(0, 32, "gpio0"),
+	PIN_BANK(1, 32, "gpio1"),
+	PIN_BANK(2, 32, "gpio2"),
+	PIN_BANK(3, 32, "gpio3"),
+};
+
+static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
+		.pin_banks	= rk3066b_pin_banks,
+		.nr_banks	= ARRAY_SIZE(rk3066b_pin_banks),
+		.label		= "RK3066b-GPIO",
+		.mux_offset	= 0x60,
+		.pull_offset	= -EINVAL,
+};
+
+static struct rockchip_pin_bank rk3188_pin_banks[] = {
+	PIN_BANK(0, 32, "gpio0"),
+	PIN_BANK(1, 32, "gpio1"),
+	PIN_BANK(2, 32, "gpio2"),
+	PIN_BANK(3, 32, "gpio3"),
+};
+
+static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
+		.pin_banks		= rk3188_pin_banks,
+		.nr_banks		= ARRAY_SIZE(rk3188_pin_banks),
+		.label			= "RK3188-GPIO",
+		.mux_offset		= 0x68,
+		.pull_offset		= 0x164,
+		.pull_bank_stride	= 16,
+};
+
+static const struct of_device_id rockchip_pinctrl_dt_match[] = {
+	{ .compatible = "rockchip,rk2928-pinctrl",
+		.data = (void *)&rk2928_pin_ctrl },
+	{ .compatible = "rockchip,rk3066a-pinctrl",
+		.data = (void *)&rk3066a_pin_ctrl },
+	{ .compatible = "rockchip,rk3066b-pinctrl",
+		.data = (void *)&rk3066b_pin_ctrl },
+	{ .compatible = "rockchip,rk3188-pinctrl",
+		.data = (void *)&rk3188_pin_ctrl },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match);
+
+static struct platform_driver rockchip_pinctrl_driver = {
+	.probe		= rockchip_pinctrl_probe,
+	.driver = {
+		.name	= "rockchip-pinctrl",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(rockchip_pinctrl_dt_match),
+	},
+};
+
+static int __init rockchip_pinctrl_drv_register(void)
+{
+	return platform_driver_register(&rockchip_pinctrl_driver);
+}
+postcore_initcall(rockchip_pinctrl_drv_register);
+
+MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
+MODULE_DESCRIPTION("Rockchip pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-s3c24xx.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-s3c24xx.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-s3c24xx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-s3c24xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,651 @@
+/*
+ * S3C24XX specific support for Samsung pinctrl/gpiolib driver.
+ *
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file contains the SamsungS3C24XX specific information required by the
+ * Samsung pinctrl/gpiolib driver. It also includes the implementation of
+ * external gpio and wakeup interrupt support.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#include "pinctrl-samsung.h"
+
+#define NUM_EINT	24
+#define NUM_EINT_IRQ	6
+#define EINT_MAX_PER_GROUP	8
+
+#define EINTPEND_REG	0xa8
+#define EINTMASK_REG	0xa4
+
+#define EINT_GROUP(i)		((int)((i) / EINT_MAX_PER_GROUP))
+#define EINT_REG(i)		((EINT_GROUP(i) * 4) + 0x88)
+#define EINT_OFFS(i)		((i) % EINT_MAX_PER_GROUP * 4)
+
+#define EINT_LEVEL_LOW		0
+#define EINT_LEVEL_HIGH		1
+#define EINT_EDGE_FALLING	2
+#define EINT_EDGE_RISING	4
+#define EINT_EDGE_BOTH		6
+#define EINT_MASK		0xf
+
+static struct samsung_pin_bank_type bank_type_1bit = {
+	.fld_width = { 1, 1, },
+	.reg_offset = { 0x00, 0x04, },
+};
+
+static struct samsung_pin_bank_type bank_type_2bit = {
+	.fld_width = { 2, 1, 2, },
+	.reg_offset = { 0x00, 0x04, 0x08, },
+};
+
+#define PIN_BANK_A(pins, reg, id)		\
+	{						\
+		.type		= &bank_type_1bit,	\
+		.pctl_offset	= reg,			\
+		.nr_pins	= pins,			\
+		.eint_type	= EINT_TYPE_NONE,	\
+		.name		= id			\
+	}
+
+#define PIN_BANK_2BIT(pins, reg, id)		\
+	{						\
+		.type		= &bank_type_2bit,	\
+		.pctl_offset	= reg,			\
+		.nr_pins	= pins,			\
+		.eint_type	= EINT_TYPE_NONE,	\
+		.name		= id			\
+	}
+
+#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs, emask)\
+	{						\
+		.type		= &bank_type_2bit,	\
+		.pctl_offset	= reg,			\
+		.nr_pins	= pins,			\
+		.eint_type	= EINT_TYPE_WKUP,	\
+		.eint_func	= 2,			\
+		.eint_mask	= emask,		\
+		.eint_offset	= eoffs,		\
+		.name		= id			\
+	}
+
+/**
+ * struct s3c24xx_eint_data: EINT common data
+ * @drvdata: pin controller driver data
+ * @domains: IRQ domains of particular EINT interrupts
+ * @parents: mapped parent irqs in the main interrupt controller
+ */
+struct s3c24xx_eint_data {
+	struct samsung_pinctrl_drv_data *drvdata;
+	struct irq_domain *domains[NUM_EINT];
+	int parents[NUM_EINT_IRQ];
+};
+
+/**
+ * struct s3c24xx_eint_domain_data: per irq-domain data
+ * @bank: pin bank related to the domain
+ * @eint_data: common data
+ * eint0_3_parent_only: live eints 0-3 only in the main intc
+ */
+struct s3c24xx_eint_domain_data {
+	struct samsung_pin_bank *bank;
+	struct s3c24xx_eint_data *eint_data;
+	bool eint0_3_parent_only;
+};
+
+static int s3c24xx_eint_get_trigger(unsigned int type)
+{
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		return EINT_EDGE_RISING;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		return EINT_EDGE_FALLING;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		return EINT_EDGE_BOTH;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		return EINT_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		return EINT_LEVEL_LOW;
+		break;
+	default:
+		return -EINVAL;
+	}
+}
+
+static void s3c24xx_eint_set_handler(unsigned int irq, unsigned int type)
+{
+	/* Edge- and level-triggered interrupts need different handlers */
+	if (type & IRQ_TYPE_EDGE_BOTH)
+		__irq_set_handler_locked(irq, handle_edge_irq);
+	else
+		__irq_set_handler_locked(irq, handle_level_irq);
+}
+
+static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d,
+					struct samsung_pin_bank *bank, int pin)
+{
+	struct samsung_pin_bank_type *bank_type = bank->type;
+	unsigned long flags;
+	void __iomem *reg;
+	u8 shift;
+	u32 mask;
+	u32 val;
+
+	/* Make sure that pin is configured as interrupt */
+	reg = d->virt_base + bank->pctl_offset;
+	shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
+	mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
+
+	spin_lock_irqsave(&bank->slock, flags);
+
+	val = readl(reg);
+	val &= ~(mask << shift);
+	val |= bank->eint_func << shift;
+	writel(val, reg);
+
+	spin_unlock_irqrestore(&bank->slock, flags);
+}
+
+static int s3c24xx_eint_type(struct irq_data *data, unsigned int type)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	int index = bank->eint_offset + data->hwirq;
+	void __iomem *reg;
+	int trigger;
+	u8 shift;
+	u32 val;
+
+	trigger = s3c24xx_eint_get_trigger(type);
+	if (trigger < 0) {
+		dev_err(d->dev, "unsupported external interrupt type\n");
+		return -EINVAL;
+	}
+
+	s3c24xx_eint_set_handler(data->irq, type);
+
+	/* Set up interrupt trigger */
+	reg = d->virt_base + EINT_REG(index);
+	shift = EINT_OFFS(index);
+
+	val = readl(reg);
+	val &= ~(EINT_MASK << shift);
+	val |= trigger << shift;
+	writel(val, reg);
+
+	s3c24xx_eint_set_function(d, bank, data->hwirq);
+
+	return 0;
+}
+
+/* Handling of EINTs 0-3 on all except S3C2412 and S3C2413 */
+
+static void s3c2410_eint0_3_ack(struct irq_data *data)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
+	struct s3c24xx_eint_data *eint_data = ddata->eint_data;
+	int parent_irq = eint_data->parents[data->hwirq];
+	struct irq_chip *parent_chip = irq_get_chip(parent_irq);
+
+	parent_chip->irq_ack(irq_get_irq_data(parent_irq));
+}
+
+static void s3c2410_eint0_3_mask(struct irq_data *data)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
+	struct s3c24xx_eint_data *eint_data = ddata->eint_data;
+	int parent_irq = eint_data->parents[data->hwirq];
+	struct irq_chip *parent_chip = irq_get_chip(parent_irq);
+
+	parent_chip->irq_mask(irq_get_irq_data(parent_irq));
+}
+
+static void s3c2410_eint0_3_unmask(struct irq_data *data)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
+	struct s3c24xx_eint_data *eint_data = ddata->eint_data;
+	int parent_irq = eint_data->parents[data->hwirq];
+	struct irq_chip *parent_chip = irq_get_chip(parent_irq);
+
+	parent_chip->irq_unmask(irq_get_irq_data(parent_irq));
+}
+
+static struct irq_chip s3c2410_eint0_3_chip = {
+	.name		= "s3c2410-eint0_3",
+	.irq_ack	= s3c2410_eint0_3_ack,
+	.irq_mask	= s3c2410_eint0_3_mask,
+	.irq_unmask	= s3c2410_eint0_3_unmask,
+	.irq_set_type	= s3c24xx_eint_type,
+};
+
+static void s3c2410_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_data *data = irq_desc_get_irq_data(desc);
+	struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
+	unsigned int virq;
+
+	/* the first 4 eints have a simple 1 to 1 mapping */
+	virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
+	/* Something must be really wrong if an unmapped EINT is unmasked */
+	BUG_ON(!virq);
+
+	generic_handle_irq(virq);
+}
+
+/* Handling of EINTs 0-3 on S3C2412 and S3C2413 */
+
+static void s3c2412_eint0_3_ack(struct irq_data *data)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+
+	unsigned long bitval = 1UL << data->hwirq;
+	writel(bitval, d->virt_base + EINTPEND_REG);
+}
+
+static void s3c2412_eint0_3_mask(struct irq_data *data)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long mask;
+
+	mask = readl(d->virt_base + EINTMASK_REG);
+	mask |= (1UL << data->hwirq);
+	writel(mask, d->virt_base + EINTMASK_REG);
+}
+
+static void s3c2412_eint0_3_unmask(struct irq_data *data)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned long mask;
+
+	mask = readl(d->virt_base + EINTMASK_REG);
+	mask &= ~(1UL << data->hwirq);
+	writel(mask, d->virt_base + EINTMASK_REG);
+}
+
+static struct irq_chip s3c2412_eint0_3_chip = {
+	.name		= "s3c2412-eint0_3",
+	.irq_ack	= s3c2412_eint0_3_ack,
+	.irq_mask	= s3c2412_eint0_3_mask,
+	.irq_unmask	= s3c2412_eint0_3_unmask,
+	.irq_set_type	= s3c24xx_eint_type,
+};
+
+static void s3c2412_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_get_chip(irq);
+	struct irq_data *data = irq_desc_get_irq_data(desc);
+	struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
+	unsigned int virq;
+
+	chained_irq_enter(chip, desc);
+
+	/* the first 4 eints have a simple 1 to 1 mapping */
+	virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
+	/* Something must be really wrong if an unmapped EINT is unmasked */
+	BUG_ON(!virq);
+
+	generic_handle_irq(virq);
+
+	chained_irq_exit(chip, desc);
+}
+
+/* Handling of all other eints */
+
+static void s3c24xx_eint_ack(struct irq_data *data)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned char index = bank->eint_offset + data->hwirq;
+
+	writel(1UL << index, d->virt_base + EINTPEND_REG);
+}
+
+static void s3c24xx_eint_mask(struct irq_data *data)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned char index = bank->eint_offset + data->hwirq;
+	unsigned long mask;
+
+	mask = readl(d->virt_base + EINTMASK_REG);
+	mask |= (1UL << index);
+	writel(mask, d->virt_base + EINTMASK_REG);
+}
+
+static void s3c24xx_eint_unmask(struct irq_data *data)
+{
+	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
+	struct samsung_pinctrl_drv_data *d = bank->drvdata;
+	unsigned char index = bank->eint_offset + data->hwirq;
+	unsigned long mask;
+
+	mask = readl(d->virt_base + EINTMASK_REG);
+	mask &= ~(1UL << index);
+	writel(mask, d->virt_base + EINTMASK_REG);
+}
+
+static struct irq_chip s3c24xx_eint_chip = {
+	.name		= "s3c-eint",
+	.irq_ack	= s3c24xx_eint_ack,
+	.irq_mask	= s3c24xx_eint_mask,
+	.irq_unmask	= s3c24xx_eint_unmask,
+	.irq_set_type	= s3c24xx_eint_type,
+};
+
+static inline void s3c24xx_demux_eint(unsigned int irq, struct irq_desc *desc,
+				      u32 offset, u32 range)
+{
+	struct irq_chip *chip = irq_get_chip(irq);
+	struct s3c24xx_eint_data *data = irq_get_handler_data(irq);
+	struct samsung_pinctrl_drv_data *d = data->drvdata;
+	unsigned int pend, mask;
+
+	chained_irq_enter(chip, desc);
+
+	pend = readl(d->virt_base + EINTPEND_REG);
+	mask = readl(d->virt_base + EINTMASK_REG);
+
+	pend &= ~mask;
+	pend &= range;
+
+	while (pend) {
+		unsigned int virq;
+
+		irq = __ffs(pend);
+		pend &= ~(1 << irq);
+		virq = irq_linear_revmap(data->domains[irq], irq - offset);
+		/* Something is really wrong if an unmapped EINT is unmasked */
+		BUG_ON(!virq);
+
+		generic_handle_irq(virq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void s3c24xx_demux_eint4_7(unsigned int irq, struct irq_desc *desc)
+{
+	s3c24xx_demux_eint(irq, desc, 0, 0xf0);
+}
+
+static void s3c24xx_demux_eint8_23(unsigned int irq, struct irq_desc *desc)
+{
+	s3c24xx_demux_eint(irq, desc, 8, 0xffff00);
+}
+
+static irq_flow_handler_t s3c2410_eint_handlers[NUM_EINT_IRQ] = {
+	s3c2410_demux_eint0_3,
+	s3c2410_demux_eint0_3,
+	s3c2410_demux_eint0_3,
+	s3c2410_demux_eint0_3,
+	s3c24xx_demux_eint4_7,
+	s3c24xx_demux_eint8_23,
+};
+
+static irq_flow_handler_t s3c2412_eint_handlers[NUM_EINT_IRQ] = {
+	s3c2412_demux_eint0_3,
+	s3c2412_demux_eint0_3,
+	s3c2412_demux_eint0_3,
+	s3c2412_demux_eint0_3,
+	s3c24xx_demux_eint4_7,
+	s3c24xx_demux_eint8_23,
+};
+
+static int s3c24xx_gpf_irq_map(struct irq_domain *h, unsigned int virq,
+					irq_hw_number_t hw)
+{
+	struct s3c24xx_eint_domain_data *ddata = h->host_data;
+	struct samsung_pin_bank *bank = ddata->bank;
+
+	if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
+		return -EINVAL;
+
+	if (hw <= 3) {
+		if (ddata->eint0_3_parent_only)
+			irq_set_chip_and_handler(virq, &s3c2410_eint0_3_chip,
+						 handle_edge_irq);
+		else
+			irq_set_chip_and_handler(virq, &s3c2412_eint0_3_chip,
+						 handle_edge_irq);
+	} else {
+		irq_set_chip_and_handler(virq, &s3c24xx_eint_chip,
+					 handle_edge_irq);
+	}
+	irq_set_chip_data(virq, bank);
+	set_irq_flags(virq, IRQF_VALID);
+	return 0;
+}
+
+static const struct irq_domain_ops s3c24xx_gpf_irq_ops = {
+	.map	= s3c24xx_gpf_irq_map,
+	.xlate	= irq_domain_xlate_twocell,
+};
+
+static int s3c24xx_gpg_irq_map(struct irq_domain *h, unsigned int virq,
+					irq_hw_number_t hw)
+{
+	struct s3c24xx_eint_domain_data *ddata = h->host_data;
+	struct samsung_pin_bank *bank = ddata->bank;
+
+	if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
+		return -EINVAL;
+
+	irq_set_chip_and_handler(virq, &s3c24xx_eint_chip, handle_edge_irq);
+	irq_set_chip_data(virq, bank);
+	set_irq_flags(virq, IRQF_VALID);
+	return 0;
+}
+
+static const struct irq_domain_ops s3c24xx_gpg_irq_ops = {
+	.map	= s3c24xx_gpg_irq_map,
+	.xlate	= irq_domain_xlate_twocell,
+};
+
+static const struct of_device_id s3c24xx_eint_irq_ids[] = {
+	{ .compatible = "samsung,s3c2410-wakeup-eint", .data = (void *)1 },
+	{ .compatible = "samsung,s3c2412-wakeup-eint", .data = (void *)0 },
+	{ }
+};
+
+static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
+{
+	struct device *dev = d->dev;
+	const struct of_device_id *match;
+	struct device_node *eint_np = NULL;
+	struct device_node *np;
+	struct samsung_pin_bank *bank;
+	struct s3c24xx_eint_data *eint_data;
+	const struct irq_domain_ops *ops;
+	unsigned int i;
+	bool eint0_3_parent_only;
+	irq_flow_handler_t *handlers;
+
+	for_each_child_of_node(dev->of_node, np) {
+		match = of_match_node(s3c24xx_eint_irq_ids, np);
+		if (match) {
+			eint_np = np;
+			eint0_3_parent_only = (bool)match->data;
+			break;
+		}
+	}
+	if (!eint_np)
+		return -ENODEV;
+
+	eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL);
+	if (!eint_data)
+		return -ENOMEM;
+
+	eint_data->drvdata = d;
+
+	handlers = eint0_3_parent_only ? s3c2410_eint_handlers
+				       : s3c2412_eint_handlers;
+	for (i = 0; i < NUM_EINT_IRQ; ++i) {
+		unsigned int irq;
+
+		irq = irq_of_parse_and_map(eint_np, i);
+		if (!irq) {
+			dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
+			return -ENXIO;
+		}
+
+		eint_data->parents[i] = irq;
+		irq_set_chained_handler(irq, handlers[i]);
+		irq_set_handler_data(irq, eint_data);
+	}
+
+	bank = d->ctrl->pin_banks;
+	for (i = 0; i < d->ctrl->nr_banks; ++i, ++bank) {
+		struct s3c24xx_eint_domain_data *ddata;
+		unsigned int mask;
+		unsigned int irq;
+		unsigned int pin;
+
+		if (bank->eint_type != EINT_TYPE_WKUP)
+			continue;
+
+		ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+		if (!ddata)
+			return -ENOMEM;
+
+		ddata->bank = bank;
+		ddata->eint_data = eint_data;
+		ddata->eint0_3_parent_only = eint0_3_parent_only;
+
+		ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops
+					       : &s3c24xx_gpg_irq_ops;
+
+		bank->irq_domain = irq_domain_add_linear(bank->of_node,
+				bank->nr_pins, ops, ddata);
+		if (!bank->irq_domain) {
+			dev_err(dev, "wkup irq domain add failed\n");
+			return -ENXIO;
+		}
+
+		irq = bank->eint_offset;
+		mask = bank->eint_mask;
+		for (pin = 0; mask; ++pin, mask >>= 1) {
+			if (irq > NUM_EINT)
+				break;
+			if (!(mask & 1))
+				continue;
+			eint_data->domains[irq] = bank->irq_domain;
+			++irq;
+		}
+	}
+
+	return 0;
+}
+
+static struct samsung_pin_bank s3c2412_pin_banks[] = {
+	PIN_BANK_A(23, 0x000, "gpa"),
+	PIN_BANK_2BIT(11, 0x010, "gpb"),
+	PIN_BANK_2BIT(16, 0x020, "gpc"),
+	PIN_BANK_2BIT(16, 0x030, "gpd"),
+	PIN_BANK_2BIT(16, 0x040, "gpe"),
+	PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
+	PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
+	PIN_BANK_2BIT(11, 0x070, "gph"),
+	PIN_BANK_2BIT(13, 0x080, "gpj"),
+};
+
+struct samsung_pin_ctrl s3c2412_pin_ctrl[] = {
+	{
+		.pin_banks	= s3c2412_pin_banks,
+		.nr_banks	= ARRAY_SIZE(s3c2412_pin_banks),
+		.eint_wkup_init = s3c24xx_eint_init,
+		.label		= "S3C2412-GPIO",
+	},
+};
+
+static struct samsung_pin_bank s3c2416_pin_banks[] = {
+	PIN_BANK_A(27, 0x000, "gpa"),
+	PIN_BANK_2BIT(11, 0x010, "gpb"),
+	PIN_BANK_2BIT(16, 0x020, "gpc"),
+	PIN_BANK_2BIT(16, 0x030, "gpd"),
+	PIN_BANK_2BIT(16, 0x040, "gpe"),
+	PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
+	PIN_BANK_2BIT_EINTW(8, 0x060, "gpg", 8, 0xff00),
+	PIN_BANK_2BIT(15, 0x070, "gph"),
+	PIN_BANK_2BIT(16, 0x0e0, "gpk"),
+	PIN_BANK_2BIT(14, 0x0f0, "gpl"),
+	PIN_BANK_2BIT(2, 0x100, "gpm"),
+};
+
+struct samsung_pin_ctrl s3c2416_pin_ctrl[] = {
+	{
+		.pin_banks	= s3c2416_pin_banks,
+		.nr_banks	= ARRAY_SIZE(s3c2416_pin_banks),
+		.eint_wkup_init = s3c24xx_eint_init,
+		.label		= "S3C2416-GPIO",
+	},
+};
+
+static struct samsung_pin_bank s3c2440_pin_banks[] = {
+	PIN_BANK_A(25, 0x000, "gpa"),
+	PIN_BANK_2BIT(11, 0x010, "gpb"),
+	PIN_BANK_2BIT(16, 0x020, "gpc"),
+	PIN_BANK_2BIT(16, 0x030, "gpd"),
+	PIN_BANK_2BIT(16, 0x040, "gpe"),
+	PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
+	PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
+	PIN_BANK_2BIT(11, 0x070, "gph"),
+	PIN_BANK_2BIT(13, 0x0d0, "gpj"),
+};
+
+struct samsung_pin_ctrl s3c2440_pin_ctrl[] = {
+	{
+		.pin_banks	= s3c2440_pin_banks,
+		.nr_banks	= ARRAY_SIZE(s3c2440_pin_banks),
+		.eint_wkup_init = s3c24xx_eint_init,
+		.label		= "S3C2440-GPIO",
+	},
+};
+
+static struct samsung_pin_bank s3c2450_pin_banks[] = {
+	PIN_BANK_A(28, 0x000, "gpa"),
+	PIN_BANK_2BIT(11, 0x010, "gpb"),
+	PIN_BANK_2BIT(16, 0x020, "gpc"),
+	PIN_BANK_2BIT(16, 0x030, "gpd"),
+	PIN_BANK_2BIT(16, 0x040, "gpe"),
+	PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
+	PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
+	PIN_BANK_2BIT(15, 0x070, "gph"),
+	PIN_BANK_2BIT(16, 0x0d0, "gpj"),
+	PIN_BANK_2BIT(16, 0x0e0, "gpk"),
+	PIN_BANK_2BIT(15, 0x0f0, "gpl"),
+	PIN_BANK_2BIT(2, 0x100, "gpm"),
+};
+
+struct samsung_pin_ctrl s3c2450_pin_ctrl[] = {
+	{
+		.pin_banks	= s3c2450_pin_banks,
+		.nr_banks	= ARRAY_SIZE(s3c2450_pin_banks),
+		.eint_wkup_init = s3c24xx_eint_init,
+		.label		= "S3C2450-GPIO",
+	},
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-samsung.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-samsung.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-samsung.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-samsung.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,7 +50,7 @@ static struct pin_config {
 };
 
 /* Global list of devices (struct samsung_pinctrl_drv_data) */
-LIST_HEAD(drvdata_list);
+static LIST_HEAD(drvdata_list);
 
 static unsigned int pin_base;
 
@@ -1113,11 +1113,23 @@ static const struct of_device_id samsung
 		.data = (void *)exynos4x12_pin_ctrl },
 	{ .compatible = "samsung,exynos5250-pinctrl",
 		.data = (void *)exynos5250_pin_ctrl },
+	{ .compatible = "samsung,exynos5420-pinctrl",
+		.data = (void *)exynos5420_pin_ctrl },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
 	{ .compatible = "samsung,s3c64xx-pinctrl",
 		.data = s3c64xx_pin_ctrl },
 #endif
+#ifdef CONFIG_PINCTRL_S3C24XX
+	{ .compatible = "samsung,s3c2412-pinctrl",
+		.data = s3c2412_pin_ctrl },
+	{ .compatible = "samsung,s3c2416-pinctrl",
+		.data = s3c2416_pin_ctrl },
+	{ .compatible = "samsung,s3c2440-pinctrl",
+		.data = s3c2440_pin_ctrl },
+	{ .compatible = "samsung,s3c2450-pinctrl",
+		.data = s3c2450_pin_ctrl },
+#endif
 	{},
 };
 MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-samsung.h linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-samsung.h
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-samsung.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-samsung.h	2013-08-25 20:43:22.000000000 -0400
@@ -254,6 +254,11 @@ struct samsung_pmx_func {
 extern struct samsung_pin_ctrl exynos4210_pin_ctrl[];
 extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
 extern struct samsung_pin_ctrl exynos5250_pin_ctrl[];
+extern struct samsung_pin_ctrl exynos5420_pin_ctrl[];
 extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
+extern struct samsung_pin_ctrl s3c2412_pin_ctrl[];
+extern struct samsung_pin_ctrl s3c2416_pin_ctrl[];
+extern struct samsung_pin_ctrl s3c2440_pin_ctrl[];
+extern struct samsung_pin_ctrl s3c2450_pin_ctrl[];
 
 #endif /* __PINCTRL_SAMSUNG_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-single.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-single.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-single.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-single.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,7 +30,7 @@
 #define DRIVER_NAME			"pinctrl-single"
 #define PCS_MUX_PINS_NAME		"pinctrl-single,pins"
 #define PCS_MUX_BITS_NAME		"pinctrl-single,bits"
-#define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 1)
+#define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 3)
 #define PCS_OFF_DISABLED		~0U
 
 /**
@@ -163,6 +163,7 @@ struct pcs_name {
  * @foff:	value to turn mux off
  * @fmax:	max number of functions in fmask
  * @is_pinconf:	whether supports pinconf
+ * @bits_per_pin:number of bits per pin
  * @names:	array of register names for pins
  * @pins:	physical pins on the SoC
  * @pgtree:	pingroup index radix tree
@@ -190,6 +191,7 @@ struct pcs_device {
 	unsigned fmax;
 	bool bits_per_mux;
 	bool is_pinconf;
+	unsigned bits_per_pin;
 	struct pcs_name *names;
 	struct pcs_data pins;
 	struct radix_tree_root pgtree;
@@ -431,10 +433,11 @@ static int pcs_enable(struct pinctrl_dev
 
 		vals = &func->vals[i];
 		val = pcs->read(vals->reg);
-		if (!vals->mask)
-			mask = pcs->fmask;
+
+		if (pcs->bits_per_mux)
+			mask = vals->mask;
 		else
-			mask = pcs->fmask & vals->mask;
+			mask = pcs->fmask;
 
 		val &= ~mask;
 		val |= (vals->val & mask);
@@ -741,7 +744,8 @@ static const struct pinconf_ops pcs_pinc
  * @pcs: pcs driver instance
  * @offset: register offset from base
  */
-static int pcs_add_pin(struct pcs_device *pcs, unsigned offset)
+static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
+		unsigned pin_pos)
 {
 	struct pinctrl_pin_desc *pin;
 	struct pcs_name *pn;
@@ -756,8 +760,8 @@ static int pcs_add_pin(struct pcs_device
 
 	pin = &pcs->pins.pa[i];
 	pn = &pcs->names[i];
-	sprintf(pn->name, "%lx",
-		(unsigned long)pcs->res->start + offset);
+	sprintf(pn->name, "%lx.%d",
+		(unsigned long)pcs->res->start + offset, pin_pos);
 	pin->name = pn->name;
 	pin->number = i;
 	pcs->pins.cur++;
@@ -777,9 +781,17 @@ static int pcs_add_pin(struct pcs_device
 static int pcs_allocate_pin_table(struct pcs_device *pcs)
 {
 	int mux_bytes, nr_pins, i;
+	int num_pins_in_register = 0;
 
 	mux_bytes = pcs->width / BITS_PER_BYTE;
-	nr_pins = pcs->size / mux_bytes;
+
+	if (pcs->bits_per_mux) {
+		pcs->bits_per_pin = fls(pcs->fmask);
+		nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin;
+		num_pins_in_register = pcs->width / pcs->bits_per_pin;
+	} else {
+		nr_pins = pcs->size / mux_bytes;
+	}
 
 	dev_dbg(pcs->dev, "allocating %i pins\n", nr_pins);
 	pcs->pins.pa = devm_kzalloc(pcs->dev,
@@ -800,9 +812,17 @@ static int pcs_allocate_pin_table(struct
 	for (i = 0; i < pcs->desc.npins; i++) {
 		unsigned offset;
 		int res;
+		int byte_num;
+		int pin_pos = 0;
 
-		offset = i * mux_bytes;
-		res = pcs_add_pin(pcs, offset);
+		if (pcs->bits_per_mux) {
+			byte_num = (pcs->bits_per_pin * i) / BITS_PER_BYTE;
+			offset = (byte_num / mux_bytes) * mux_bytes;
+			pin_pos = i % num_pins_in_register;
+		} else {
+			offset = i * mux_bytes;
+		}
+		res = pcs_add_pin(pcs, offset, pin_pos);
 		if (res < 0) {
 			dev_err(pcs->dev, "error adding pins: %i\n", res);
 			return res;
@@ -919,7 +939,10 @@ static int pcs_get_pin_by_offset(struct
 		return -EINVAL;
 	}
 
-	index = offset / (pcs->width / BITS_PER_BYTE);
+	if (pcs->bits_per_mux)
+		index = (offset * BITS_PER_BYTE) / pcs->bits_per_pin;
+	else
+		index = offset / (pcs->width / BITS_PER_BYTE);
 
 	return index;
 }
@@ -1097,29 +1120,18 @@ static int pcs_parse_one_pinctrl_entry(s
 {
 	struct pcs_func_vals *vals;
 	const __be32 *mux;
-	int size, params, rows, *pins, index = 0, found = 0, res = -ENOMEM;
+	int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
 	struct pcs_function *function;
 
-	if (pcs->bits_per_mux) {
-		params = 3;
-		mux = of_get_property(np, PCS_MUX_BITS_NAME, &size);
-	} else {
-		params = 2;
-		mux = of_get_property(np, PCS_MUX_PINS_NAME, &size);
-	}
-
-	if (!mux) {
-		dev_err(pcs->dev, "no valid property for %s\n", np->name);
-		return -EINVAL;
-	}
-
-	if (size < (sizeof(*mux) * params)) {
-		dev_err(pcs->dev, "bad data for %s\n", np->name);
+	mux = of_get_property(np, PCS_MUX_PINS_NAME, &size);
+	if ((!mux) || (size < sizeof(*mux) * 2)) {
+		dev_err(pcs->dev, "bad data for mux %s\n",
+			np->name);
 		return -EINVAL;
 	}
 
 	size /= sizeof(*mux);	/* Number of elements in array */
-	rows = size / params;
+	rows = size / 2;
 
 	vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL);
 	if (!vals)
@@ -1137,10 +1149,6 @@ static int pcs_parse_one_pinctrl_entry(s
 		val = be32_to_cpup(mux + index++);
 		vals[found].reg = pcs->base + offset;
 		vals[found].val = val;
-		if (params == 3) {
-			val = be32_to_cpup(mux + index++);
-			vals[found].mask = val;
-		}
 
 		pin = pcs_get_pin_by_offset(pcs, offset);
 		if (pin < 0) {
@@ -1189,6 +1197,125 @@ free_vals:
 
 	return res;
 }
+
+#define PARAMS_FOR_BITS_PER_MUX 3
+
+static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
+						struct device_node *np,
+						struct pinctrl_map **map,
+						unsigned *num_maps,
+						const char **pgnames)
+{
+	struct pcs_func_vals *vals;
+	const __be32 *mux;
+	int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
+	int npins_in_row;
+	struct pcs_function *function;
+
+	mux = of_get_property(np, PCS_MUX_BITS_NAME, &size);
+
+	if (!mux) {
+		dev_err(pcs->dev, "no valid property for %s\n", np->name);
+		return -EINVAL;
+	}
+
+	if (size < (sizeof(*mux) * PARAMS_FOR_BITS_PER_MUX)) {
+		dev_err(pcs->dev, "bad data for %s\n", np->name);
+		return -EINVAL;
+	}
+
+	/* Number of elements in array */
+	size /= sizeof(*mux);
+
+	rows = size / PARAMS_FOR_BITS_PER_MUX;
+	npins_in_row = pcs->width / pcs->bits_per_pin;
+
+	vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows * npins_in_row,
+			GFP_KERNEL);
+	if (!vals)
+		return -ENOMEM;
+
+	pins = devm_kzalloc(pcs->dev, sizeof(*pins) * rows * npins_in_row,
+			GFP_KERNEL);
+	if (!pins)
+		goto free_vals;
+
+	while (index < size) {
+		unsigned offset, val;
+		unsigned mask, bit_pos, val_pos, mask_pos, submask;
+		unsigned pin_num_from_lsb;
+		int pin;
+
+		offset = be32_to_cpup(mux + index++);
+		val = be32_to_cpup(mux + index++);
+		mask = be32_to_cpup(mux + index++);
+
+		/* Parse pins in each row from LSB */
+		while (mask) {
+			bit_pos = ffs(mask);
+			pin_num_from_lsb = bit_pos / pcs->bits_per_pin;
+			mask_pos = ((pcs->fmask) << (bit_pos - 1));
+			val_pos = val & mask_pos;
+			submask = mask & mask_pos;
+			mask &= ~mask_pos;
+
+			if (submask != mask_pos) {
+				dev_warn(pcs->dev,
+						"Invalid submask 0x%x for %s at 0x%x\n",
+						submask, np->name, offset);
+				continue;
+			}
+
+			vals[found].mask = submask;
+			vals[found].reg = pcs->base + offset;
+			vals[found].val = val_pos;
+
+			pin = pcs_get_pin_by_offset(pcs, offset);
+			if (pin < 0) {
+				dev_err(pcs->dev,
+					"could not add functions for %s %ux\n",
+					np->name, offset);
+				break;
+			}
+			pins[found++] = pin + pin_num_from_lsb;
+		}
+	}
+
+	pgnames[0] = np->name;
+	function = pcs_add_function(pcs, np, np->name, vals, found, pgnames, 1);
+	if (!function)
+		goto free_pins;
+
+	res = pcs_add_pingroup(pcs, np, np->name, pins, found);
+	if (res < 0)
+		goto free_function;
+
+	(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
+	(*map)->data.mux.group = np->name;
+	(*map)->data.mux.function = np->name;
+
+	if (pcs->is_pinconf) {
+		dev_err(pcs->dev, "pinconf not supported\n");
+		goto free_pingroups;
+	}
+
+	*num_maps = 1;
+	return 0;
+
+free_pingroups:
+	pcs_free_pingroups(pcs);
+	*num_maps = 1;
+free_function:
+	pcs_remove_function(pcs, function);
+
+free_pins:
+	devm_kfree(pcs->dev, pins);
+
+free_vals:
+	devm_kfree(pcs->dev, vals);
+
+	return res;
+}
 /**
  * pcs_dt_node_to_map() - allocates and parses pinctrl maps
  * @pctldev: pinctrl instance
@@ -1219,12 +1346,22 @@ static int pcs_dt_node_to_map(struct pin
 		goto free_map;
 	}
 
-	ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, num_maps,
-					  pgnames);
-	if (ret < 0) {
-		dev_err(pcs->dev, "no pins entries for %s\n",
-			np_config->name);
-		goto free_pgnames;
+	if (pcs->bits_per_mux) {
+		ret = pcs_parse_bits_in_pinctrl_entry(pcs, np_config, map,
+				num_maps, pgnames);
+		if (ret < 0) {
+			dev_err(pcs->dev, "no pins entries for %s\n",
+				np_config->name);
+			goto free_pgnames;
+		}
+	} else {
+		ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map,
+				num_maps, pgnames);
+		if (ret < 0) {
+			dev_err(pcs->dev, "no pins entries for %s\n",
+				np_config->name);
+			goto free_pgnames;
+		}
 	}
 
 	return 0;
@@ -1346,6 +1483,31 @@ static int pcs_add_gpio_func(struct devi
 	return ret;
 }
 
+#ifdef CONFIG_PM
+static int pinctrl_single_suspend(struct platform_device *pdev,
+					pm_message_t state)
+{
+	struct pcs_device *pcs;
+
+	pcs = platform_get_drvdata(pdev);
+	if (!pcs)
+		return -EINVAL;
+
+	return pinctrl_force_sleep(pcs->pctl);
+}
+
+static int pinctrl_single_resume(struct platform_device *pdev)
+{
+	struct pcs_device *pcs;
+
+	pcs = platform_get_drvdata(pdev);
+	if (!pcs)
+		return -EINVAL;
+
+	return pinctrl_force_default(pcs->pctl);
+}
+#endif
+
 static int pcs_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -1494,6 +1656,10 @@ static struct platform_driver pcs_driver
 		.name		= DRIVER_NAME,
 		.of_match_table	= pcs_of_match,
 	},
+#ifdef CONFIG_PM
+	.suspend = pinctrl_single_suspend,
+	.resume = pinctrl_single_resume,
+#endif
 };
 
 module_platform_driver(pcs_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-sirf.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-sirf.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-sirf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-sirf.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1810 +0,0 @@
-/*
- * pinmux driver for CSR SiRFprimaII
- *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/irqdomain.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/bitops.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
-
-#define DRIVER_NAME "pinmux-sirf"
-
-#define SIRFSOC_NUM_PADS    622
-#define SIRFSOC_RSC_PIN_MUX 0x4
-
-#define SIRFSOC_GPIO_PAD_EN(g)		((g)*0x100 + 0x84)
-#define SIRFSOC_GPIO_PAD_EN_CLR(g)	((g)*0x100 + 0x90)
-#define SIRFSOC_GPIO_CTRL(g, i)			((g)*0x100 + (i)*4)
-#define SIRFSOC_GPIO_DSP_EN0			(0x80)
-#define SIRFSOC_GPIO_INT_STATUS(g)		((g)*0x100 + 0x8C)
-
-#define SIRFSOC_GPIO_CTL_INTR_LOW_MASK		0x1
-#define SIRFSOC_GPIO_CTL_INTR_HIGH_MASK		0x2
-#define SIRFSOC_GPIO_CTL_INTR_TYPE_MASK		0x4
-#define SIRFSOC_GPIO_CTL_INTR_EN_MASK		0x8
-#define SIRFSOC_GPIO_CTL_INTR_STS_MASK		0x10
-#define SIRFSOC_GPIO_CTL_OUT_EN_MASK		0x20
-#define SIRFSOC_GPIO_CTL_DATAOUT_MASK		0x40
-#define SIRFSOC_GPIO_CTL_DATAIN_MASK		0x80
-#define SIRFSOC_GPIO_CTL_PULL_MASK		0x100
-#define SIRFSOC_GPIO_CTL_PULL_HIGH		0x200
-#define SIRFSOC_GPIO_CTL_DSP_INT		0x400
-
-#define SIRFSOC_GPIO_NO_OF_BANKS        5
-#define SIRFSOC_GPIO_BANK_SIZE          32
-#define SIRFSOC_GPIO_NUM(bank, index)	(((bank)*(32)) + (index))
-
-struct sirfsoc_gpio_bank {
-	struct of_mm_gpio_chip chip;
-	struct irq_domain *domain;
-	int id;
-	int parent_irq;
-	spinlock_t lock;
-	bool is_marco; /* for marco, some registers are different with prima2 */
-};
-
-static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS];
-static DEFINE_SPINLOCK(sgpio_lock);
-
-/*
- * pad list for the pinmux subsystem
- * refer to CS-131858-DC-6A.xls
- */
-static const struct pinctrl_pin_desc sirfsoc_pads[] = {
-	PINCTRL_PIN(0, "gpio0-0"),
-	PINCTRL_PIN(1, "gpio0-1"),
-	PINCTRL_PIN(2, "gpio0-2"),
-	PINCTRL_PIN(3, "gpio0-3"),
-	PINCTRL_PIN(4, "pwm0"),
-	PINCTRL_PIN(5, "pwm1"),
-	PINCTRL_PIN(6, "pwm2"),
-	PINCTRL_PIN(7, "pwm3"),
-	PINCTRL_PIN(8, "warm_rst_b"),
-	PINCTRL_PIN(9, "odo_0"),
-	PINCTRL_PIN(10, "odo_1"),
-	PINCTRL_PIN(11, "dr_dir"),
-	PINCTRL_PIN(12, "viprom_fa"),
-	PINCTRL_PIN(13, "scl_1"),
-	PINCTRL_PIN(14, "ntrst"),
-	PINCTRL_PIN(15, "sda_1"),
-	PINCTRL_PIN(16, "x_ldd[16]"),
-	PINCTRL_PIN(17, "x_ldd[17]"),
-	PINCTRL_PIN(18, "x_ldd[18]"),
-	PINCTRL_PIN(19, "x_ldd[19]"),
-	PINCTRL_PIN(20, "x_ldd[20]"),
-	PINCTRL_PIN(21, "x_ldd[21]"),
-	PINCTRL_PIN(22, "x_ldd[22]"),
-	PINCTRL_PIN(23, "x_ldd[23], lcdrom_frdy"),
-	PINCTRL_PIN(24, "gps_sgn"),
-	PINCTRL_PIN(25, "gps_mag"),
-	PINCTRL_PIN(26, "gps_clk"),
-	PINCTRL_PIN(27,	"sd_cd_b_1"),
-	PINCTRL_PIN(28, "sd_vcc_on_1"),
-	PINCTRL_PIN(29, "sd_wp_b_1"),
-	PINCTRL_PIN(30, "sd_clk_3"),
-	PINCTRL_PIN(31, "sd_cmd_3"),
-
-	PINCTRL_PIN(32, "x_sd_dat_3[0]"),
-	PINCTRL_PIN(33, "x_sd_dat_3[1]"),
-	PINCTRL_PIN(34, "x_sd_dat_3[2]"),
-	PINCTRL_PIN(35, "x_sd_dat_3[3]"),
-	PINCTRL_PIN(36, "x_sd_clk_4"),
-	PINCTRL_PIN(37, "x_sd_cmd_4"),
-	PINCTRL_PIN(38, "x_sd_dat_4[0]"),
-	PINCTRL_PIN(39, "x_sd_dat_4[1]"),
-	PINCTRL_PIN(40, "x_sd_dat_4[2]"),
-	PINCTRL_PIN(41, "x_sd_dat_4[3]"),
-	PINCTRL_PIN(42, "x_cko_1"),
-	PINCTRL_PIN(43, "x_ac97_bit_clk"),
-	PINCTRL_PIN(44, "x_ac97_dout"),
-	PINCTRL_PIN(45, "x_ac97_din"),
-	PINCTRL_PIN(46, "x_ac97_sync"),
-	PINCTRL_PIN(47, "x_txd_1"),
-	PINCTRL_PIN(48, "x_txd_2"),
-	PINCTRL_PIN(49, "x_rxd_1"),
-	PINCTRL_PIN(50, "x_rxd_2"),
-	PINCTRL_PIN(51, "x_usclk_0"),
-	PINCTRL_PIN(52, "x_utxd_0"),
-	PINCTRL_PIN(53, "x_urxd_0"),
-	PINCTRL_PIN(54, "x_utfs_0"),
-	PINCTRL_PIN(55, "x_urfs_0"),
-	PINCTRL_PIN(56, "x_usclk_1"),
-	PINCTRL_PIN(57, "x_utxd_1"),
-	PINCTRL_PIN(58, "x_urxd_1"),
-	PINCTRL_PIN(59, "x_utfs_1"),
-	PINCTRL_PIN(60, "x_urfs_1"),
-	PINCTRL_PIN(61, "x_usclk_2"),
-	PINCTRL_PIN(62, "x_utxd_2"),
-	PINCTRL_PIN(63, "x_urxd_2"),
-
-	PINCTRL_PIN(64, "x_utfs_2"),
-	PINCTRL_PIN(65, "x_urfs_2"),
-	PINCTRL_PIN(66, "x_df_we_b"),
-	PINCTRL_PIN(67, "x_df_re_b"),
-	PINCTRL_PIN(68, "x_txd_0"),
-	PINCTRL_PIN(69, "x_rxd_0"),
-	PINCTRL_PIN(78, "x_cko_0"),
-	PINCTRL_PIN(79, "x_vip_pxd[7]"),
-	PINCTRL_PIN(80, "x_vip_pxd[6]"),
-	PINCTRL_PIN(81, "x_vip_pxd[5]"),
-	PINCTRL_PIN(82, "x_vip_pxd[4]"),
-	PINCTRL_PIN(83, "x_vip_pxd[3]"),
-	PINCTRL_PIN(84, "x_vip_pxd[2]"),
-	PINCTRL_PIN(85, "x_vip_pxd[1]"),
-	PINCTRL_PIN(86, "x_vip_pxd[0]"),
-	PINCTRL_PIN(87, "x_vip_vsync"),
-	PINCTRL_PIN(88, "x_vip_hsync"),
-	PINCTRL_PIN(89, "x_vip_pxclk"),
-	PINCTRL_PIN(90, "x_sda_0"),
-	PINCTRL_PIN(91, "x_scl_0"),
-	PINCTRL_PIN(92, "x_df_ry_by"),
-	PINCTRL_PIN(93, "x_df_cs_b[1]"),
-	PINCTRL_PIN(94, "x_df_cs_b[0]"),
-	PINCTRL_PIN(95, "x_l_pclk"),
-
-	PINCTRL_PIN(96, "x_l_lck"),
-	PINCTRL_PIN(97, "x_l_fck"),
-	PINCTRL_PIN(98, "x_l_de"),
-	PINCTRL_PIN(99, "x_ldd[0]"),
-	PINCTRL_PIN(100, "x_ldd[1]"),
-	PINCTRL_PIN(101, "x_ldd[2]"),
-	PINCTRL_PIN(102, "x_ldd[3]"),
-	PINCTRL_PIN(103, "x_ldd[4]"),
-	PINCTRL_PIN(104, "x_ldd[5]"),
-	PINCTRL_PIN(105, "x_ldd[6]"),
-	PINCTRL_PIN(106, "x_ldd[7]"),
-	PINCTRL_PIN(107, "x_ldd[8]"),
-	PINCTRL_PIN(108, "x_ldd[9]"),
-	PINCTRL_PIN(109, "x_ldd[10]"),
-	PINCTRL_PIN(110, "x_ldd[11]"),
-	PINCTRL_PIN(111, "x_ldd[12]"),
-	PINCTRL_PIN(112, "x_ldd[13]"),
-	PINCTRL_PIN(113, "x_ldd[14]"),
-	PINCTRL_PIN(114, "x_ldd[15]"),
-};
-
-/**
- * @dev: a pointer back to containing device
- * @virtbase: the offset to the controller in virtual memory
- */
-struct sirfsoc_pmx {
-	struct device *dev;
-	struct pinctrl_dev *pmx;
-	void __iomem *gpio_virtbase;
-	void __iomem *rsc_virtbase;
-	bool is_marco;
-};
-
-/* SIRFSOC_GPIO_PAD_EN set */
-struct sirfsoc_muxmask {
-	unsigned long group;
-	unsigned long mask;
-};
-
-struct sirfsoc_padmux {
-	unsigned long muxmask_counts;
-	const struct sirfsoc_muxmask *muxmask;
-	/* RSC_PIN_MUX set */
-	unsigned long funcmask;
-	unsigned long funcval;
-};
-
- /**
- * struct sirfsoc_pin_group - describes a SiRFprimaII pin group
- * @name: the name of this specific pin group
- * @pins: an array of discrete physical pins used in this group, taken
- *	from the driver-local pin enumeration space
- * @num_pins: the number of pins in this group array, i.e. the number of
- *	elements in .pins so we can iterate over that array
- */
-struct sirfsoc_pin_group {
-	const char *name;
-	const unsigned int *pins;
-	const unsigned num_pins;
-};
-
-static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = {
-	{
-		.group = 3,
-		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) |
-			BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) |
-			BIT(17) | BIT(18),
-	}, {
-		.group = 2,
-		.mask = BIT(31),
-	},
-};
-
-static const struct sirfsoc_padmux lcd_16bits_padmux = {
-	.muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask),
-	.muxmask = lcd_16bits_sirfsoc_muxmask,
-	.funcmask = BIT(4),
-	.funcval = 0,
-};
-
-static const unsigned lcd_16bits_pins[] = { 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
-	105, 106, 107, 108, 109, 110, 111, 112, 113, 114 };
-
-static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = {
-	{
-		.group = 3,
-		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) |
-			BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) |
-			BIT(17) | BIT(18),
-	}, {
-		.group = 2,
-		.mask = BIT(31),
-	}, {
-		.group = 0,
-		.mask = BIT(16) | BIT(17),
-	},
-};
-
-static const struct sirfsoc_padmux lcd_18bits_padmux = {
-	.muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask),
-	.muxmask = lcd_18bits_muxmask,
-	.funcmask = BIT(4),
-	.funcval = 0,
-};
-
-static const unsigned lcd_18bits_pins[] = { 16, 17, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
-	105, 106, 107, 108, 109, 110, 111, 112, 113, 114};
-
-static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = {
-	{
-		.group = 3,
-		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) |
-			BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) |
-			BIT(17) | BIT(18),
-	}, {
-		.group = 2,
-		.mask = BIT(31),
-	}, {
-		.group = 0,
-		.mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23),
-	},
-};
-
-static const struct sirfsoc_padmux lcd_24bits_padmux = {
-	.muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask),
-	.muxmask = lcd_24bits_muxmask,
-	.funcmask = BIT(4),
-	.funcval = 0,
-};
-
-static const unsigned lcd_24bits_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
-	105, 106, 107, 108, 109, 110, 111, 112, 113, 114 };
-
-static const struct sirfsoc_muxmask lcdrom_muxmask[] = {
-	{
-		.group = 3,
-		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) |
-			BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) |
-			BIT(17) | BIT(18),
-	}, {
-		.group = 2,
-		.mask = BIT(31),
-	}, {
-		.group = 0,
-		.mask = BIT(23),
-	},
-};
-
-static const struct sirfsoc_padmux lcdrom_padmux = {
-	.muxmask_counts = ARRAY_SIZE(lcdrom_muxmask),
-	.muxmask = lcdrom_muxmask,
-	.funcmask = BIT(4),
-	.funcval = BIT(4),
-};
-
-static const unsigned lcdrom_pins[] = { 23, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
-	105, 106, 107, 108, 109, 110, 111, 112, 113, 114 };
-
-static const struct sirfsoc_muxmask uart0_muxmask[] = {
-	{
-		.group = 2,
-		.mask = BIT(4) | BIT(5),
-	}, {
-		.group = 1,
-		.mask = BIT(23) | BIT(28),
-	},
-};
-
-static const struct sirfsoc_padmux uart0_padmux = {
-	.muxmask_counts = ARRAY_SIZE(uart0_muxmask),
-	.muxmask = uart0_muxmask,
-	.funcmask = BIT(9),
-	.funcval = BIT(9),
-};
-
-static const unsigned uart0_pins[] = { 55, 60, 68, 69 };
-
-static const struct sirfsoc_muxmask uart0_nostreamctrl_muxmask[] = {
-	{
-		.group = 2,
-		.mask = BIT(4) | BIT(5),
-	},
-};
-
-static const struct sirfsoc_padmux uart0_nostreamctrl_padmux = {
-	.muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask),
-	.muxmask = uart0_nostreamctrl_muxmask,
-};
-
-static const unsigned uart0_nostreamctrl_pins[] = { 68, 39 };
-
-static const struct sirfsoc_muxmask uart1_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(15) | BIT(17),
-	},
-};
-
-static const struct sirfsoc_padmux uart1_padmux = {
-	.muxmask_counts = ARRAY_SIZE(uart1_muxmask),
-	.muxmask = uart1_muxmask,
-};
-
-static const unsigned uart1_pins[] = { 47, 49 };
-
-static const struct sirfsoc_muxmask uart2_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(16) | BIT(18) | BIT(24) | BIT(27),
-	},
-};
-
-static const struct sirfsoc_padmux uart2_padmux = {
-	.muxmask_counts = ARRAY_SIZE(uart2_muxmask),
-	.muxmask = uart2_muxmask,
-	.funcmask = BIT(10),
-	.funcval = BIT(10),
-};
-
-static const unsigned uart2_pins[] = { 48, 50, 56, 59 };
-
-static const struct sirfsoc_muxmask uart2_nostreamctrl_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(16) | BIT(18),
-	},
-};
-
-static const struct sirfsoc_padmux uart2_nostreamctrl_padmux = {
-	.muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask),
-	.muxmask = uart2_nostreamctrl_muxmask,
-};
-
-static const unsigned uart2_nostreamctrl_pins[] = { 48, 50 };
-
-static const struct sirfsoc_muxmask sdmmc3_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(30) | BIT(31),
-	}, {
-		.group = 1,
-		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
-	},
-};
-
-static const struct sirfsoc_padmux sdmmc3_padmux = {
-	.muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask),
-	.muxmask = sdmmc3_muxmask,
-	.funcmask = BIT(7),
-	.funcval = 0,
-};
-
-static const unsigned sdmmc3_pins[] = { 30, 31, 32, 33, 34, 35 };
-
-static const struct sirfsoc_muxmask spi0_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
-	},
-};
-
-static const struct sirfsoc_padmux spi0_padmux = {
-	.muxmask_counts = ARRAY_SIZE(spi0_muxmask),
-	.muxmask = spi0_muxmask,
-	.funcmask = BIT(7),
-	.funcval = BIT(7),
-};
-
-static const unsigned spi0_pins[] = { 32, 33, 34, 35 };
-
-static const struct sirfsoc_muxmask sdmmc4_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9),
-	},
-};
-
-static const struct sirfsoc_padmux sdmmc4_padmux = {
-	.muxmask_counts = ARRAY_SIZE(sdmmc4_muxmask),
-	.muxmask = sdmmc4_muxmask,
-};
-
-static const unsigned sdmmc4_pins[] = { 36, 37, 38, 39, 40, 41 };
-
-static const struct sirfsoc_muxmask cko1_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(10),
-	},
-};
-
-static const struct sirfsoc_padmux cko1_padmux = {
-	.muxmask_counts = ARRAY_SIZE(cko1_muxmask),
-	.muxmask = cko1_muxmask,
-	.funcmask = BIT(3),
-	.funcval = 0,
-};
-
-static const unsigned cko1_pins[] = { 42 };
-
-static const struct sirfsoc_muxmask i2s_muxmask[] = {
-	{
-		.group = 1,
-		.mask =
-			BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(19)
-				| BIT(23) | BIT(28),
-	},
-};
-
-static const struct sirfsoc_padmux i2s_padmux = {
-	.muxmask_counts = ARRAY_SIZE(i2s_muxmask),
-	.muxmask = i2s_muxmask,
-	.funcmask = BIT(3) | BIT(9),
-	.funcval = BIT(3),
-};
-
-static const unsigned i2s_pins[] = { 42, 43, 44, 45, 46, 51, 55, 60 };
-
-static const struct sirfsoc_muxmask ac97_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
-	},
-};
-
-static const struct sirfsoc_padmux ac97_padmux = {
-	.muxmask_counts = ARRAY_SIZE(ac97_muxmask),
-	.muxmask = ac97_muxmask,
-	.funcmask = BIT(8),
-	.funcval = 0,
-};
-
-static const unsigned ac97_pins[] = { 33, 34, 35, 36 };
-
-static const struct sirfsoc_muxmask spi1_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
-	},
-};
-
-static const struct sirfsoc_padmux spi1_padmux = {
-	.muxmask_counts = ARRAY_SIZE(spi1_muxmask),
-	.muxmask = spi1_muxmask,
-	.funcmask = BIT(8),
-	.funcval = BIT(8),
-};
-
-static const unsigned spi1_pins[] = { 43, 44, 45, 46 };
-
-static const struct sirfsoc_muxmask sdmmc1_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(27) | BIT(28) | BIT(29),
-	},
-};
-
-static const struct sirfsoc_padmux sdmmc1_padmux = {
-	.muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask),
-	.muxmask = sdmmc1_muxmask,
-};
-
-static const unsigned sdmmc1_pins[] = { 27, 28, 29 };
-
-static const struct sirfsoc_muxmask gps_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(24) | BIT(25) | BIT(26),
-	},
-};
-
-static const struct sirfsoc_padmux gps_padmux = {
-	.muxmask_counts = ARRAY_SIZE(gps_muxmask),
-	.muxmask = gps_muxmask,
-	.funcmask = BIT(12) | BIT(13) | BIT(14),
-	.funcval = BIT(12),
-};
-
-static const unsigned gps_pins[] = { 24, 25, 26 };
-
-static const struct sirfsoc_muxmask sdmmc5_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(24) | BIT(25) | BIT(26),
-	}, {
-		.group = 1,
-		.mask = BIT(29),
-	}, {
-		.group = 2,
-		.mask = BIT(0) | BIT(1),
-	},
-};
-
-static const struct sirfsoc_padmux sdmmc5_padmux = {
-	.muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask),
-	.muxmask = sdmmc5_muxmask,
-	.funcmask = BIT(13) | BIT(14),
-	.funcval = BIT(13) | BIT(14),
-};
-
-static const unsigned sdmmc5_pins[] = { 24, 25, 26, 61, 64, 65 };
-
-static const struct sirfsoc_muxmask usp0_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23),
-	},
-};
-
-static const struct sirfsoc_padmux usp0_padmux = {
-	.muxmask_counts = ARRAY_SIZE(usp0_muxmask),
-	.muxmask = usp0_muxmask,
-	.funcmask = BIT(1) | BIT(2) | BIT(6) | BIT(9),
-	.funcval = 0,
-};
-
-static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 };
-
-static const struct sirfsoc_muxmask usp1_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28),
-	},
-};
-
-static const struct sirfsoc_padmux usp1_padmux = {
-	.muxmask_counts = ARRAY_SIZE(usp1_muxmask),
-	.muxmask = usp1_muxmask,
-	.funcmask = BIT(1) | BIT(9) | BIT(10) | BIT(11),
-	.funcval = 0,
-};
-
-static const unsigned usp1_pins[] = { 56, 57, 58, 59, 60 };
-
-static const struct sirfsoc_muxmask usp2_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(29) | BIT(30) | BIT(31),
-	}, {
-		.group = 2,
-		.mask = BIT(0) | BIT(1),
-	},
-};
-
-static const struct sirfsoc_padmux usp2_padmux = {
-	.muxmask_counts = ARRAY_SIZE(usp2_muxmask),
-	.muxmask = usp2_muxmask,
-	.funcmask = BIT(13) | BIT(14),
-	.funcval = 0,
-};
-
-static const unsigned usp2_pins[] = { 61, 62, 63, 64, 65 };
-
-static const struct sirfsoc_muxmask nand_muxmask[] = {
-	{
-		.group = 2,
-		.mask = BIT(2) | BIT(3) | BIT(28) | BIT(29) | BIT(30),
-	},
-};
-
-static const struct sirfsoc_padmux nand_padmux = {
-	.muxmask_counts = ARRAY_SIZE(nand_muxmask),
-	.muxmask = nand_muxmask,
-	.funcmask = BIT(5),
-	.funcval = 0,
-};
-
-static const unsigned nand_pins[] = { 64, 65, 92, 93, 94 };
-
-static const struct sirfsoc_padmux sdmmc0_padmux = {
-	.muxmask_counts = 0,
-	.funcmask = BIT(5),
-	.funcval = 0,
-};
-
-static const unsigned sdmmc0_pins[] = { };
-
-static const struct sirfsoc_muxmask sdmmc2_muxmask[] = {
-	{
-		.group = 2,
-		.mask = BIT(2) | BIT(3),
-	},
-};
-
-static const struct sirfsoc_padmux sdmmc2_padmux = {
-	.muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask),
-	.muxmask = sdmmc2_muxmask,
-	.funcmask = BIT(5),
-	.funcval = BIT(5),
-};
-
-static const unsigned sdmmc2_pins[] = { 66, 67 };
-
-static const struct sirfsoc_muxmask cko0_muxmask[] = {
-	{
-		.group = 2,
-		.mask = BIT(14),
-	},
-};
-
-static const struct sirfsoc_padmux cko0_padmux = {
-	.muxmask_counts = ARRAY_SIZE(cko0_muxmask),
-	.muxmask = cko0_muxmask,
-};
-
-static const unsigned cko0_pins[] = { 78 };
-
-static const struct sirfsoc_muxmask vip_muxmask[] = {
-	{
-		.group = 2,
-		.mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19)
-			| BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) |
-			BIT(25),
-	},
-};
-
-static const struct sirfsoc_padmux vip_padmux = {
-	.muxmask_counts = ARRAY_SIZE(vip_muxmask),
-	.muxmask = vip_muxmask,
-	.funcmask = BIT(0),
-	.funcval = 0,
-};
-
-static const unsigned vip_pins[] = { 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 };
-
-static const struct sirfsoc_muxmask i2c0_muxmask[] = {
-	{
-		.group = 2,
-		.mask = BIT(26) | BIT(27),
-	},
-};
-
-static const struct sirfsoc_padmux i2c0_padmux = {
-	.muxmask_counts = ARRAY_SIZE(i2c0_muxmask),
-	.muxmask = i2c0_muxmask,
-};
-
-static const unsigned i2c0_pins[] = { 90, 91 };
-
-static const struct sirfsoc_muxmask i2c1_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(13) | BIT(15),
-	},
-};
-
-static const struct sirfsoc_padmux i2c1_padmux = {
-	.muxmask_counts = ARRAY_SIZE(i2c1_muxmask),
-	.muxmask = i2c1_muxmask,
-};
-
-static const unsigned i2c1_pins[] = { 13, 15 };
-
-static const struct sirfsoc_muxmask viprom_muxmask[] = {
-	{
-		.group = 2,
-		.mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19)
-			| BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) |
-			BIT(25),
-	}, {
-		.group = 0,
-		.mask = BIT(12),
-	},
-};
-
-static const struct sirfsoc_padmux viprom_padmux = {
-	.muxmask_counts = ARRAY_SIZE(viprom_muxmask),
-	.muxmask = viprom_muxmask,
-	.funcmask = BIT(0),
-	.funcval = BIT(0),
-};
-
-static const unsigned viprom_pins[] = { 12, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 };
-
-static const struct sirfsoc_muxmask pwm0_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(4),
-	},
-};
-
-static const struct sirfsoc_padmux pwm0_padmux = {
-	.muxmask_counts = ARRAY_SIZE(pwm0_muxmask),
-	.muxmask = pwm0_muxmask,
-	.funcmask = BIT(12),
-	.funcval = 0,
-};
-
-static const unsigned pwm0_pins[] = { 4 };
-
-static const struct sirfsoc_muxmask pwm1_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(5),
-	},
-};
-
-static const struct sirfsoc_padmux pwm1_padmux = {
-	.muxmask_counts = ARRAY_SIZE(pwm1_muxmask),
-	.muxmask = pwm1_muxmask,
-};
-
-static const unsigned pwm1_pins[] = { 5 };
-
-static const struct sirfsoc_muxmask pwm2_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(6),
-	},
-};
-
-static const struct sirfsoc_padmux pwm2_padmux = {
-	.muxmask_counts = ARRAY_SIZE(pwm2_muxmask),
-	.muxmask = pwm2_muxmask,
-};
-
-static const unsigned pwm2_pins[] = { 6 };
-
-static const struct sirfsoc_muxmask pwm3_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(7),
-	},
-};
-
-static const struct sirfsoc_padmux pwm3_padmux = {
-	.muxmask_counts = ARRAY_SIZE(pwm3_muxmask),
-	.muxmask = pwm3_muxmask,
-};
-
-static const unsigned pwm3_pins[] = { 7 };
-
-static const struct sirfsoc_muxmask warm_rst_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(8),
-	},
-};
-
-static const struct sirfsoc_padmux warm_rst_padmux = {
-	.muxmask_counts = ARRAY_SIZE(warm_rst_muxmask),
-	.muxmask = warm_rst_muxmask,
-};
-
-static const unsigned warm_rst_pins[] = { 8 };
-
-static const struct sirfsoc_muxmask usb0_utmi_drvbus_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(22),
-	},
-};
-static const struct sirfsoc_padmux usb0_utmi_drvbus_padmux = {
-	.muxmask_counts = ARRAY_SIZE(usb0_utmi_drvbus_muxmask),
-	.muxmask = usb0_utmi_drvbus_muxmask,
-	.funcmask = BIT(6),
-	.funcval = BIT(6), /* refer to PAD_UTMI_DRVVBUS0_ENABLE */
-};
-
-static const unsigned usb0_utmi_drvbus_pins[] = { 54 };
-
-static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = {
-	{
-		.group = 1,
-		.mask = BIT(27),
-	},
-};
-
-static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = {
-	.muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask),
-	.muxmask = usb1_utmi_drvbus_muxmask,
-	.funcmask = BIT(11),
-	.funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */
-};
-
-static const unsigned usb1_utmi_drvbus_pins[] = { 59 };
-
-static const struct sirfsoc_muxmask pulse_count_muxmask[] = {
-	{
-		.group = 0,
-		.mask = BIT(9) | BIT(10) | BIT(11),
-	},
-};
-
-static const struct sirfsoc_padmux pulse_count_padmux = {
-	.muxmask_counts = ARRAY_SIZE(pulse_count_muxmask),
-	.muxmask = pulse_count_muxmask,
-};
-
-static const unsigned pulse_count_pins[] = { 9, 10, 11 };
-
-#define SIRFSOC_PIN_GROUP(n, p)  \
-	{			\
-		.name = n,	\
-		.pins = p,	\
-		.num_pins = ARRAY_SIZE(p),	\
-	}
-
-static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = {
-	SIRFSOC_PIN_GROUP("lcd_16bitsgrp", lcd_16bits_pins),
-	SIRFSOC_PIN_GROUP("lcd_18bitsgrp", lcd_18bits_pins),
-	SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins),
-	SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins),
-	SIRFSOC_PIN_GROUP("uart0grp", uart0_pins),
-	SIRFSOC_PIN_GROUP("uart1grp", uart1_pins),
-	SIRFSOC_PIN_GROUP("uart2grp", uart2_pins),
-	SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins),
-	SIRFSOC_PIN_GROUP("usp0grp", usp0_pins),
-	SIRFSOC_PIN_GROUP("usp1grp", usp1_pins),
-	SIRFSOC_PIN_GROUP("usp2grp", usp2_pins),
-	SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins),
-	SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins),
-	SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins),
-	SIRFSOC_PIN_GROUP("pwm1grp", pwm1_pins),
-	SIRFSOC_PIN_GROUP("pwm2grp", pwm2_pins),
-	SIRFSOC_PIN_GROUP("pwm3grp", pwm3_pins),
-	SIRFSOC_PIN_GROUP("vipgrp", vip_pins),
-	SIRFSOC_PIN_GROUP("vipromgrp", viprom_pins),
-	SIRFSOC_PIN_GROUP("warm_rstgrp", warm_rst_pins),
-	SIRFSOC_PIN_GROUP("cko0_rstgrp", cko0_pins),
-	SIRFSOC_PIN_GROUP("cko1_rstgrp", cko1_pins),
-	SIRFSOC_PIN_GROUP("sdmmc0grp", sdmmc0_pins),
-	SIRFSOC_PIN_GROUP("sdmmc1grp", sdmmc1_pins),
-	SIRFSOC_PIN_GROUP("sdmmc2grp", sdmmc2_pins),
-	SIRFSOC_PIN_GROUP("sdmmc3grp", sdmmc3_pins),
-	SIRFSOC_PIN_GROUP("sdmmc4grp", sdmmc4_pins),
-	SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins),
-	SIRFSOC_PIN_GROUP("usb0_utmi_drvbusgrp", usb0_utmi_drvbus_pins),
-	SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins),
-	SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins),
-	SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins),
-	SIRFSOC_PIN_GROUP("ac97grp", ac97_pins),
-	SIRFSOC_PIN_GROUP("nandgrp", nand_pins),
-	SIRFSOC_PIN_GROUP("spi0grp", spi0_pins),
-	SIRFSOC_PIN_GROUP("spi1grp", spi1_pins),
-	SIRFSOC_PIN_GROUP("gpsgrp", gps_pins),
-};
-
-static int sirfsoc_get_groups_count(struct pinctrl_dev *pctldev)
-{
-	return ARRAY_SIZE(sirfsoc_pin_groups);
-}
-
-static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev,
-				       unsigned selector)
-{
-	return sirfsoc_pin_groups[selector].name;
-}
-
-static int sirfsoc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
-			       const unsigned **pins,
-			       unsigned *num_pins)
-{
-	*pins = sirfsoc_pin_groups[selector].pins;
-	*num_pins = sirfsoc_pin_groups[selector].num_pins;
-	return 0;
-}
-
-static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
-		   unsigned offset)
-{
-	seq_printf(s, " " DRIVER_NAME);
-}
-
-static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev,
-				 struct device_node *np_config,
-				 struct pinctrl_map **map, unsigned *num_maps)
-{
-	struct sirfsoc_pmx *spmx = pinctrl_dev_get_drvdata(pctldev);
-	struct device_node *np;
-	struct property *prop;
-	const char *function, *group;
-	int ret, index = 0, count = 0;
-
-	/* calculate number of maps required */
-	for_each_child_of_node(np_config, np) {
-		ret = of_property_read_string(np, "sirf,function", &function);
-		if (ret < 0)
-			return ret;
-
-		ret = of_property_count_strings(np, "sirf,pins");
-		if (ret < 0)
-			return ret;
-
-		count += ret;
-	}
-
-	if (!count) {
-		dev_err(spmx->dev, "No child nodes passed via DT\n");
-		return -ENODEV;
-	}
-
-	*map = kzalloc(sizeof(**map) * count, GFP_KERNEL);
-	if (!*map)
-		return -ENOMEM;
-
-	for_each_child_of_node(np_config, np) {
-		of_property_read_string(np, "sirf,function", &function);
-		of_property_for_each_string(np, "sirf,pins", prop, group) {
-			(*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
-			(*map)[index].data.mux.group = group;
-			(*map)[index].data.mux.function = function;
-			index++;
-		}
-	}
-
-	*num_maps = count;
-
-	return 0;
-}
-
-static void sirfsoc_dt_free_map(struct pinctrl_dev *pctldev,
-		struct pinctrl_map *map, unsigned num_maps)
-{
-	kfree(map);
-}
-
-static const struct pinctrl_ops sirfsoc_pctrl_ops = {
-	.get_groups_count = sirfsoc_get_groups_count,
-	.get_group_name = sirfsoc_get_group_name,
-	.get_group_pins = sirfsoc_get_group_pins,
-	.pin_dbg_show = sirfsoc_pin_dbg_show,
-	.dt_node_to_map = sirfsoc_dt_node_to_map,
-	.dt_free_map = sirfsoc_dt_free_map,
-};
-
-struct sirfsoc_pmx_func {
-	const char *name;
-	const char * const *groups;
-	const unsigned num_groups;
-	const struct sirfsoc_padmux *padmux;
-};
-
-static const char * const lcd_16bitsgrp[] = { "lcd_16bitsgrp" };
-static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" };
-static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" };
-static const char * const lcdromgrp[] = { "lcdromgrp" };
-static const char * const uart0grp[] = { "uart0grp" };
-static const char * const uart1grp[] = { "uart1grp" };
-static const char * const uart2grp[] = { "uart2grp" };
-static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" };
-static const char * const usp0grp[] = { "usp0grp" };
-static const char * const usp1grp[] = { "usp1grp" };
-static const char * const usp2grp[] = { "usp2grp" };
-static const char * const i2c0grp[] = { "i2c0grp" };
-static const char * const i2c1grp[] = { "i2c1grp" };
-static const char * const pwm0grp[] = { "pwm0grp" };
-static const char * const pwm1grp[] = { "pwm1grp" };
-static const char * const pwm2grp[] = { "pwm2grp" };
-static const char * const pwm3grp[] = { "pwm3grp" };
-static const char * const vipgrp[] = { "vipgrp" };
-static const char * const vipromgrp[] = { "vipromgrp" };
-static const char * const warm_rstgrp[] = { "warm_rstgrp" };
-static const char * const cko0grp[] = { "cko0grp" };
-static const char * const cko1grp[] = { "cko1grp" };
-static const char * const sdmmc0grp[] = { "sdmmc0grp" };
-static const char * const sdmmc1grp[] = { "sdmmc1grp" };
-static const char * const sdmmc2grp[] = { "sdmmc2grp" };
-static const char * const sdmmc3grp[] = { "sdmmc3grp" };
-static const char * const sdmmc4grp[] = { "sdmmc4grp" };
-static const char * const sdmmc5grp[] = { "sdmmc5grp" };
-static const char * const usb0_utmi_drvbusgrp[] = { "usb0_utmi_drvbusgrp" };
-static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" };
-static const char * const pulse_countgrp[] = { "pulse_countgrp" };
-static const char * const i2sgrp[] = { "i2sgrp" };
-static const char * const ac97grp[] = { "ac97grp" };
-static const char * const nandgrp[] = { "nandgrp" };
-static const char * const spi0grp[] = { "spi0grp" };
-static const char * const spi1grp[] = { "spi1grp" };
-static const char * const gpsgrp[] = { "gpsgrp" };
-
-#define SIRFSOC_PMX_FUNCTION(n, g, m)		\
-	{					\
-		.name = n,			\
-		.groups = g,			\
-		.num_groups = ARRAY_SIZE(g),	\
-		.padmux = &m,			\
-	}
-
-static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = {
-	SIRFSOC_PMX_FUNCTION("lcd_16bits", lcd_16bitsgrp, lcd_16bits_padmux),
-	SIRFSOC_PMX_FUNCTION("lcd_18bits", lcd_18bitsgrp, lcd_18bits_padmux),
-	SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux),
-	SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux),
-	SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux),
-	SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux),
-	SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux),
-	SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux),
-	SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux),
-	SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux),
-	SIRFSOC_PMX_FUNCTION("usp2", usp2grp, usp2_padmux),
-	SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux),
-	SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux),
-	SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux),
-	SIRFSOC_PMX_FUNCTION("pwm1", pwm1grp, pwm1_padmux),
-	SIRFSOC_PMX_FUNCTION("pwm2", pwm2grp, pwm2_padmux),
-	SIRFSOC_PMX_FUNCTION("pwm3", pwm3grp, pwm3_padmux),
-	SIRFSOC_PMX_FUNCTION("vip", vipgrp, vip_padmux),
-	SIRFSOC_PMX_FUNCTION("viprom", vipromgrp, viprom_padmux),
-	SIRFSOC_PMX_FUNCTION("warm_rst", warm_rstgrp, warm_rst_padmux),
-	SIRFSOC_PMX_FUNCTION("cko0", cko0grp, cko0_padmux),
-	SIRFSOC_PMX_FUNCTION("cko1", cko1grp, cko1_padmux),
-	SIRFSOC_PMX_FUNCTION("sdmmc0", sdmmc0grp, sdmmc0_padmux),
-	SIRFSOC_PMX_FUNCTION("sdmmc1", sdmmc1grp, sdmmc1_padmux),
-	SIRFSOC_PMX_FUNCTION("sdmmc2", sdmmc2grp, sdmmc2_padmux),
-	SIRFSOC_PMX_FUNCTION("sdmmc3", sdmmc3grp, sdmmc3_padmux),
-	SIRFSOC_PMX_FUNCTION("sdmmc4", sdmmc4grp, sdmmc4_padmux),
-	SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux),
-	SIRFSOC_PMX_FUNCTION("usb0_utmi_drvbus", usb0_utmi_drvbusgrp, usb0_utmi_drvbus_padmux),
-	SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux),
-	SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux),
-	SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux),
-	SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux),
-	SIRFSOC_PMX_FUNCTION("nand", nandgrp, nand_padmux),
-	SIRFSOC_PMX_FUNCTION("spi0", spi0grp, spi0_padmux),
-	SIRFSOC_PMX_FUNCTION("spi1", spi1grp, spi1_padmux),
-	SIRFSOC_PMX_FUNCTION("gps", gpsgrp, gps_padmux),
-};
-
-static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector,
-	bool enable)
-{
-	int i;
-	const struct sirfsoc_padmux *mux = sirfsoc_pmx_functions[selector].padmux;
-	const struct sirfsoc_muxmask *mask = mux->muxmask;
-
-	for (i = 0; i < mux->muxmask_counts; i++) {
-		u32 muxval;
-		if (!spmx->is_marco) {
-			muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
-			if (enable)
-				muxval = muxval & ~mask[i].mask;
-			else
-				muxval = muxval | mask[i].mask;
-			writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
-		} else {
-			if (enable)
-				writel(mask[i].mask, spmx->gpio_virtbase +
-					SIRFSOC_GPIO_PAD_EN_CLR(mask[i].group));
-			else
-				writel(mask[i].mask, spmx->gpio_virtbase +
-					SIRFSOC_GPIO_PAD_EN(mask[i].group));
-		}
-	}
-
-	if (mux->funcmask && enable) {
-		u32 func_en_val;
-		func_en_val =
-			readl(spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX);
-		func_en_val =
-			(func_en_val & ~mux->funcmask) | (mux->
-				funcval);
-		writel(func_en_val, spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX);
-	}
-}
-
-static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector,
-	unsigned group)
-{
-	struct sirfsoc_pmx *spmx;
-
-	spmx = pinctrl_dev_get_drvdata(pmxdev);
-	sirfsoc_pinmux_endisable(spmx, selector, true);
-
-	return 0;
-}
-
-static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector,
-	unsigned group)
-{
-	struct sirfsoc_pmx *spmx;
-
-	spmx = pinctrl_dev_get_drvdata(pmxdev);
-	sirfsoc_pinmux_endisable(spmx, selector, false);
-}
-
-static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
-{
-	return ARRAY_SIZE(sirfsoc_pmx_functions);
-}
-
-static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev,
-					  unsigned selector)
-{
-	return sirfsoc_pmx_functions[selector].name;
-}
-
-static int sirfsoc_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
-			       const char * const **groups,
-			       unsigned * const num_groups)
-{
-	*groups = sirfsoc_pmx_functions[selector].groups;
-	*num_groups = sirfsoc_pmx_functions[selector].num_groups;
-	return 0;
-}
-
-static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
-	struct pinctrl_gpio_range *range, unsigned offset)
-{
-	struct sirfsoc_pmx *spmx;
-
-	int group = range->id;
-
-	u32 muxval;
-
-	spmx = pinctrl_dev_get_drvdata(pmxdev);
-
-	if (!spmx->is_marco) {
-		muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
-		muxval = muxval | (1 << (offset - range->pin_base));
-		writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
-	} else {
-		writel(1 << (offset - range->pin_base), spmx->gpio_virtbase +
-			SIRFSOC_GPIO_PAD_EN(group));
-	}
-
-	return 0;
-}
-
-static const struct pinmux_ops sirfsoc_pinmux_ops = {
-	.enable = sirfsoc_pinmux_enable,
-	.disable = sirfsoc_pinmux_disable,
-	.get_functions_count = sirfsoc_pinmux_get_funcs_count,
-	.get_function_name = sirfsoc_pinmux_get_func_name,
-	.get_function_groups = sirfsoc_pinmux_get_groups,
-	.gpio_request_enable = sirfsoc_pinmux_request_gpio,
-};
-
-static struct pinctrl_desc sirfsoc_pinmux_desc = {
-	.name = DRIVER_NAME,
-	.pins = sirfsoc_pads,
-	.npins = ARRAY_SIZE(sirfsoc_pads),
-	.pctlops = &sirfsoc_pctrl_ops,
-	.pmxops = &sirfsoc_pinmux_ops,
-	.owner = THIS_MODULE,
-};
-
-/*
- * Todo: bind irq_chip to every pinctrl_gpio_range
- */
-static struct pinctrl_gpio_range sirfsoc_gpio_ranges[] = {
-	{
-		.name = "sirfsoc-gpio*",
-		.id = 0,
-		.base = 0,
-		.pin_base = 0,
-		.npins = 32,
-	}, {
-		.name = "sirfsoc-gpio*",
-		.id = 1,
-		.base = 32,
-		.pin_base = 32,
-		.npins = 32,
-	}, {
-		.name = "sirfsoc-gpio*",
-		.id = 2,
-		.base = 64,
-		.pin_base = 64,
-		.npins = 32,
-	}, {
-		.name = "sirfsoc-gpio*",
-		.id = 3,
-		.base = 96,
-		.pin_base = 96,
-		.npins = 19,
-	},
-};
-
-static void __iomem *sirfsoc_rsc_of_iomap(void)
-{
-	const struct of_device_id rsc_ids[]  = {
-		{ .compatible = "sirf,prima2-rsc" },
-		{ .compatible = "sirf,marco-rsc" },
-		{}
-	};
-	struct device_node *np;
-
-	np = of_find_matching_node(NULL, rsc_ids);
-	if (!np)
-		panic("unable to find compatible rsc node in dtb\n");
-
-	return of_iomap(np, 0);
-}
-
-static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc,
-       const struct of_phandle_args *gpiospec,
-       u32 *flags)
-{
-       if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE)
-               return -EINVAL;
-
-       if (gc != &sgpio_bank[gpiospec->args[0] / SIRFSOC_GPIO_BANK_SIZE].chip.gc)
-               return -EINVAL;
-
-       if (flags)
-               *flags = gpiospec->args[1];
-
-       return gpiospec->args[0] % SIRFSOC_GPIO_BANK_SIZE;
-}
-
-static int sirfsoc_pinmux_probe(struct platform_device *pdev)
-{
-	int ret;
-	struct sirfsoc_pmx *spmx;
-	struct device_node *np = pdev->dev.of_node;
-	int i;
-
-	/* Create state holders etc for this driver */
-	spmx = devm_kzalloc(&pdev->dev, sizeof(*spmx), GFP_KERNEL);
-	if (!spmx)
-		return -ENOMEM;
-
-	spmx->dev = &pdev->dev;
-
-	platform_set_drvdata(pdev, spmx);
-
-	spmx->gpio_virtbase = of_iomap(np, 0);
-	if (!spmx->gpio_virtbase) {
-		ret = -ENOMEM;
-		dev_err(&pdev->dev, "can't map gpio registers\n");
-		goto out_no_gpio_remap;
-	}
-
-	spmx->rsc_virtbase = sirfsoc_rsc_of_iomap();
-	if (!spmx->rsc_virtbase) {
-		ret = -ENOMEM;
-		dev_err(&pdev->dev, "can't map rsc registers\n");
-		goto out_no_rsc_remap;
-	}
-
-	if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
-		spmx->is_marco = 1;
-
-	/* Now register the pin controller and all pins it handles */
-	spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx);
-	if (!spmx->pmx) {
-		dev_err(&pdev->dev, "could not register SIRFSOC pinmux driver\n");
-		ret = -EINVAL;
-		goto out_no_pmx;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(sirfsoc_gpio_ranges); i++) {
-		sirfsoc_gpio_ranges[i].gc = &sgpio_bank[i].chip.gc;
-		pinctrl_add_gpio_range(spmx->pmx, &sirfsoc_gpio_ranges[i]);
-	}
-
-	dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n");
-
-	return 0;
-
-out_no_pmx:
-	iounmap(spmx->rsc_virtbase);
-out_no_rsc_remap:
-	iounmap(spmx->gpio_virtbase);
-out_no_gpio_remap:
-	platform_set_drvdata(pdev, NULL);
-	return ret;
-}
-
-static const struct of_device_id pinmux_ids[] = {
-	{ .compatible = "sirf,prima2-pinctrl" },
-	{ .compatible = "sirf,marco-pinctrl" },
-	{}
-};
-
-static struct platform_driver sirfsoc_pinmux_driver = {
-	.driver = {
-		.name = DRIVER_NAME,
-		.owner = THIS_MODULE,
-		.of_match_table = pinmux_ids,
-	},
-	.probe = sirfsoc_pinmux_probe,
-};
-
-static int __init sirfsoc_pinmux_init(void)
-{
-	return platform_driver_register(&sirfsoc_pinmux_driver);
-}
-arch_initcall(sirfsoc_pinmux_init);
-
-static inline int sirfsoc_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-	struct sirfsoc_gpio_bank *bank = container_of(to_of_mm_gpio_chip(chip),
-		struct sirfsoc_gpio_bank, chip);
-
-	return irq_create_mapping(bank->domain, offset);
-}
-
-static inline int sirfsoc_gpio_to_offset(unsigned int gpio)
-{
-	return gpio % SIRFSOC_GPIO_BANK_SIZE;
-}
-
-static inline struct sirfsoc_gpio_bank *sirfsoc_gpio_to_bank(unsigned int gpio)
-{
-	return &sgpio_bank[gpio / SIRFSOC_GPIO_BANK_SIZE];
-}
-
-static inline struct sirfsoc_gpio_bank *sirfsoc_irqchip_to_bank(struct gpio_chip *chip)
-{
-	return container_of(to_of_mm_gpio_chip(chip), struct sirfsoc_gpio_bank, chip);
-}
-
-static void sirfsoc_gpio_irq_ack(struct irq_data *d)
-{
-	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE;
-	u32 val, offset;
-	unsigned long flags;
-
-	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
-
-	spin_lock_irqsave(&sgpio_lock, flags);
-
-	val = readl(bank->chip.regs + offset);
-
-	writel(val, bank->chip.regs + offset);
-
-	spin_unlock_irqrestore(&sgpio_lock, flags);
-}
-
-static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_bank *bank, int idx)
-{
-	u32 val, offset;
-	unsigned long flags;
-
-	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
-
-	spin_lock_irqsave(&sgpio_lock, flags);
-
-	val = readl(bank->chip.regs + offset);
-	val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK;
-	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
-	writel(val, bank->chip.regs + offset);
-
-	spin_unlock_irqrestore(&sgpio_lock, flags);
-}
-
-static void sirfsoc_gpio_irq_mask(struct irq_data *d)
-{
-	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-
-	__sirfsoc_gpio_irq_mask(bank, d->hwirq % SIRFSOC_GPIO_BANK_SIZE);
-}
-
-static void sirfsoc_gpio_irq_unmask(struct irq_data *d)
-{
-	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE;
-	u32 val, offset;
-	unsigned long flags;
-
-	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
-
-	spin_lock_irqsave(&sgpio_lock, flags);
-
-	val = readl(bank->chip.regs + offset);
-	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
-	val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK;
-	writel(val, bank->chip.regs + offset);
-
-	spin_unlock_irqrestore(&sgpio_lock, flags);
-}
-
-static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type)
-{
-	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE;
-	u32 val, offset;
-	unsigned long flags;
-
-	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
-
-	spin_lock_irqsave(&sgpio_lock, flags);
-
-	val = readl(bank->chip.regs + offset);
-	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
-
-	switch (type) {
-	case IRQ_TYPE_NONE:
-		break;
-	case IRQ_TYPE_EDGE_RISING:
-		val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK;
-		val &= ~SIRFSOC_GPIO_CTL_INTR_LOW_MASK;
-		break;
-	case IRQ_TYPE_EDGE_FALLING:
-		val &= ~SIRFSOC_GPIO_CTL_INTR_HIGH_MASK;
-		val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK;
-		break;
-	case IRQ_TYPE_EDGE_BOTH:
-		val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | SIRFSOC_GPIO_CTL_INTR_LOW_MASK |
-			 SIRFSOC_GPIO_CTL_INTR_TYPE_MASK;
-		break;
-	case IRQ_TYPE_LEVEL_LOW:
-		val &= ~(SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
-		val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK;
-		break;
-	case IRQ_TYPE_LEVEL_HIGH:
-		val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK;
-		val &= ~(SIRFSOC_GPIO_CTL_INTR_LOW_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
-		break;
-	}
-
-	writel(val, bank->chip.regs + offset);
-
-	spin_unlock_irqrestore(&sgpio_lock, flags);
-
-	return 0;
-}
-
-static struct irq_chip sirfsoc_irq_chip = {
-	.name = "sirf-gpio-irq",
-	.irq_ack = sirfsoc_gpio_irq_ack,
-	.irq_mask = sirfsoc_gpio_irq_mask,
-	.irq_unmask = sirfsoc_gpio_irq_unmask,
-	.irq_set_type = sirfsoc_gpio_irq_type,
-};
-
-static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc)
-{
-	struct sirfsoc_gpio_bank *bank = irq_get_handler_data(irq);
-	u32 status, ctrl;
-	int idx = 0;
-	struct irq_chip *chip = irq_get_chip(irq);
-
-	chained_irq_enter(chip, desc);
-
-	status = readl(bank->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id));
-	if (!status) {
-		printk(KERN_WARNING
-			"%s: gpio id %d status %#x no interrupt is flaged\n",
-			__func__, bank->id, status);
-		handle_bad_irq(irq, desc);
-		return;
-	}
-
-	while (status) {
-		ctrl = readl(bank->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, idx));
-
-		/*
-		 * Here we must check whether the corresponding GPIO's interrupt
-		 * has been enabled, otherwise just skip it
-		 */
-		if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) {
-			pr_debug("%s: gpio id %d idx %d happens\n",
-				__func__, bank->id, idx);
-			generic_handle_irq(irq_find_mapping(bank->domain, idx));
-		}
-
-		idx++;
-		status = status >> 1;
-	}
-
-	chained_irq_exit(chip, desc);
-}
-
-static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_bank *bank, unsigned ctrl_offset)
-{
-	u32 val;
-
-	val = readl(bank->chip.regs + ctrl_offset);
-	val &= ~SIRFSOC_GPIO_CTL_OUT_EN_MASK;
-	writel(val, bank->chip.regs + ctrl_offset);
-}
-
-static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
-	unsigned long flags;
-
-	if (pinctrl_request_gpio(chip->base + offset))
-		return -ENODEV;
-
-	spin_lock_irqsave(&bank->lock, flags);
-
-	/*
-	 * default status:
-	 * set direction as input and mask irq
-	 */
-	sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->id, offset));
-	__sirfsoc_gpio_irq_mask(bank, offset);
-
-	spin_unlock_irqrestore(&bank->lock, flags);
-
-	return 0;
-}
-
-static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
-	unsigned long flags;
-
-	spin_lock_irqsave(&bank->lock, flags);
-
-	__sirfsoc_gpio_irq_mask(bank, offset);
-	sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->id, offset));
-
-	spin_unlock_irqrestore(&bank->lock, flags);
-
-	pinctrl_free_gpio(chip->base + offset);
-}
-
-static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
-{
-	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
-	int idx = sirfsoc_gpio_to_offset(gpio);
-	unsigned long flags;
-	unsigned offset;
-
-	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
-
-	spin_lock_irqsave(&bank->lock, flags);
-
-	sirfsoc_gpio_set_input(bank, offset);
-
-	spin_unlock_irqrestore(&bank->lock, flags);
-
-	return 0;
-}
-
-static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_bank *bank, unsigned offset,
-	int value)
-{
-	u32 out_ctrl;
-	unsigned long flags;
-
-	spin_lock_irqsave(&bank->lock, flags);
-
-	out_ctrl = readl(bank->chip.regs + offset);
-	if (value)
-		out_ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK;
-	else
-		out_ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK;
-
-	out_ctrl &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK;
-	out_ctrl |= SIRFSOC_GPIO_CTL_OUT_EN_MASK;
-	writel(out_ctrl, bank->chip.regs + offset);
-
-	spin_unlock_irqrestore(&bank->lock, flags);
-}
-
-static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value)
-{
-	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
-	int idx = sirfsoc_gpio_to_offset(gpio);
-	u32 offset;
-	unsigned long flags;
-
-	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
-
-	spin_lock_irqsave(&sgpio_lock, flags);
-
-	sirfsoc_gpio_set_output(bank, offset, value);
-
-	spin_unlock_irqrestore(&sgpio_lock, flags);
-
-	return 0;
-}
-
-static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset)
-{
-	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
-	u32 val;
-	unsigned long flags;
-
-	spin_lock_irqsave(&bank->lock, flags);
-
-	val = readl(bank->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset));
-
-	spin_unlock_irqrestore(&bank->lock, flags);
-
-	return !!(val & SIRFSOC_GPIO_CTL_DATAIN_MASK);
-}
-
-static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset,
-	int value)
-{
-	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
-	u32 ctrl;
-	unsigned long flags;
-
-	spin_lock_irqsave(&bank->lock, flags);
-
-	ctrl = readl(bank->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset));
-	if (value)
-		ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK;
-	else
-		ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK;
-	writel(ctrl, bank->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset));
-
-	spin_unlock_irqrestore(&bank->lock, flags);
-}
-
-static int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq,
-				irq_hw_number_t hwirq)
-{
-	struct sirfsoc_gpio_bank *bank = d->host_data;
-
-	if (!bank)
-		return -EINVAL;
-
-	irq_set_chip(irq, &sirfsoc_irq_chip);
-	irq_set_handler(irq, handle_level_irq);
-	irq_set_chip_data(irq, bank);
-	set_irq_flags(irq, IRQF_VALID);
-
-	return 0;
-}
-
-const struct irq_domain_ops sirfsoc_gpio_irq_simple_ops = {
-	.map = sirfsoc_gpio_irq_map,
-	.xlate = irq_domain_xlate_twocell,
-};
-
-static void sirfsoc_gpio_set_pullup(const u32 *pullups)
-{
-	int i, n;
-	const unsigned long *p = (const unsigned long *)pullups;
-
-	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
-		for_each_set_bit(n, p + i, BITS_PER_LONG) {
-			u32 offset = SIRFSOC_GPIO_CTRL(i, n);
-			u32 val = readl(sgpio_bank[i].chip.regs + offset);
-			val |= SIRFSOC_GPIO_CTL_PULL_MASK;
-			val |= SIRFSOC_GPIO_CTL_PULL_HIGH;
-			writel(val, sgpio_bank[i].chip.regs + offset);
-		}
-	}
-}
-
-static void sirfsoc_gpio_set_pulldown(const u32 *pulldowns)
-{
-	int i, n;
-	const unsigned long *p = (const unsigned long *)pulldowns;
-
-	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
-		for_each_set_bit(n, p + i, BITS_PER_LONG) {
-			u32 offset = SIRFSOC_GPIO_CTRL(i, n);
-			u32 val = readl(sgpio_bank[i].chip.regs + offset);
-			val |= SIRFSOC_GPIO_CTL_PULL_MASK;
-			val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH;
-			writel(val, sgpio_bank[i].chip.regs + offset);
-		}
-	}
-}
-
-static int sirfsoc_gpio_probe(struct device_node *np)
-{
-	int i, err = 0;
-	struct sirfsoc_gpio_bank *bank;
-	void *regs;
-	struct platform_device *pdev;
-	bool is_marco = false;
-
-	u32 pullups[SIRFSOC_GPIO_NO_OF_BANKS], pulldowns[SIRFSOC_GPIO_NO_OF_BANKS];
-
-	pdev = of_find_device_by_node(np);
-	if (!pdev)
-		return -ENODEV;
-
-	regs = of_iomap(np, 0);
-	if (!regs)
-		return -ENOMEM;
-
-	if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
-		is_marco = 1;
-
-	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
-		bank = &sgpio_bank[i];
-		spin_lock_init(&bank->lock);
-		bank->chip.gc.request = sirfsoc_gpio_request;
-		bank->chip.gc.free = sirfsoc_gpio_free;
-		bank->chip.gc.direction_input = sirfsoc_gpio_direction_input;
-		bank->chip.gc.get = sirfsoc_gpio_get_value;
-		bank->chip.gc.direction_output = sirfsoc_gpio_direction_output;
-		bank->chip.gc.set = sirfsoc_gpio_set_value;
-		bank->chip.gc.to_irq = sirfsoc_gpio_to_irq;
-		bank->chip.gc.base = i * SIRFSOC_GPIO_BANK_SIZE;
-		bank->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE;
-		bank->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL);
-		bank->chip.gc.of_node = np;
-		bank->chip.gc.of_xlate = sirfsoc_gpio_of_xlate;
-		bank->chip.gc.of_gpio_n_cells = 2;
-		bank->chip.regs = regs;
-		bank->id = i;
-		bank->is_marco = is_marco;
-		bank->parent_irq = platform_get_irq(pdev, i);
-		if (bank->parent_irq < 0) {
-			err = bank->parent_irq;
-			goto out;
-		}
-
-		err = gpiochip_add(&bank->chip.gc);
-		if (err) {
-			pr_err("%s: error in probe function with status %d\n",
-				np->full_name, err);
-			goto out;
-		}
-
-		bank->domain = irq_domain_add_linear(np, SIRFSOC_GPIO_BANK_SIZE,
-						&sirfsoc_gpio_irq_simple_ops, bank);
-
-		if (!bank->domain) {
-			pr_err("%s: Failed to create irqdomain\n", np->full_name);
-			err = -ENOSYS;
-			goto out;
-		}
-
-		irq_set_chained_handler(bank->parent_irq, sirfsoc_gpio_handle_irq);
-		irq_set_handler_data(bank->parent_irq, bank);
-	}
-
-	if (!of_property_read_u32_array(np, "sirf,pullups", pullups,
-		SIRFSOC_GPIO_NO_OF_BANKS))
-		sirfsoc_gpio_set_pullup(pullups);
-
-	if (!of_property_read_u32_array(np, "sirf,pulldowns", pulldowns,
-		SIRFSOC_GPIO_NO_OF_BANKS))
-		sirfsoc_gpio_set_pulldown(pulldowns);
-
-	return 0;
-
-out:
-	iounmap(regs);
-	return err;
-}
-
-static int __init sirfsoc_gpio_init(void)
-{
-
-	struct device_node *np;
-
-	np = of_find_matching_node(NULL, pinmux_ids);
-
-	if (!np)
-		return -ENODEV;
-
-	return sirfsoc_gpio_probe(np);
-}
-subsys_initcall(sirfsoc_gpio_init);
-
-MODULE_AUTHOR("Rongjun Ying <rongjun.ying@csr.com>, "
-	"Yuping Luo <yuping.luo@csr.com>, "
-	"Barry Song <baohua.song@csr.com>");
-MODULE_DESCRIPTION("SIRFSOC pin control driver");
-MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-st.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-st.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-st.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-st.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1403 @@
+/*
+ * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
+ * Authors:
+ *	Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/platform_device.h>
+#include "core.h"
+
+/* PIO Block registers */
+/* PIO output */
+#define REG_PIO_POUT			0x00
+/* Set bits of POUT */
+#define REG_PIO_SET_POUT		0x04
+/* Clear bits of POUT */
+#define REG_PIO_CLR_POUT		0x08
+/* PIO input */
+#define REG_PIO_PIN			0x10
+/* PIO configuration */
+#define REG_PIO_PC(n)			(0x20 + (n) * 0x10)
+/* Set bits of PC[2:0] */
+#define REG_PIO_SET_PC(n)		(0x24 + (n) * 0x10)
+/* Clear bits of PC[2:0] */
+#define REG_PIO_CLR_PC(n)		(0x28 + (n) * 0x10)
+/* PIO input comparison */
+#define REG_PIO_PCOMP			0x50
+/* Set bits of PCOMP */
+#define REG_PIO_SET_PCOMP		0x54
+/* Clear bits of PCOMP */
+#define REG_PIO_CLR_PCOMP		0x58
+/* PIO input comparison mask */
+#define REG_PIO_PMASK			0x60
+/* Set bits of PMASK */
+#define REG_PIO_SET_PMASK		0x64
+/* Clear bits of PMASK */
+#define REG_PIO_CLR_PMASK		0x68
+
+#define ST_GPIO_DIRECTION_BIDIR	0x1
+#define ST_GPIO_DIRECTION_OUT	0x2
+#define ST_GPIO_DIRECTION_IN	0x4
+
+/**
+ *  Packed style retime configuration.
+ *  There are two registers cfg0 and cfg1 in this style for each bank.
+ *  Each field in this register is 8 bit corresponding to 8 pins in the bank.
+ */
+#define RT_P_CFGS_PER_BANK			2
+#define RT_P_CFG0_CLK1NOTCLK0_FIELD(reg)	REG_FIELD(reg, 0, 7)
+#define RT_P_CFG0_DELAY_0_FIELD(reg)		REG_FIELD(reg, 16, 23)
+#define RT_P_CFG0_DELAY_1_FIELD(reg)		REG_FIELD(reg, 24, 31)
+#define RT_P_CFG1_INVERTCLK_FIELD(reg)		REG_FIELD(reg, 0, 7)
+#define RT_P_CFG1_RETIME_FIELD(reg)		REG_FIELD(reg, 8, 15)
+#define RT_P_CFG1_CLKNOTDATA_FIELD(reg)		REG_FIELD(reg, 16, 23)
+#define RT_P_CFG1_DOUBLE_EDGE_FIELD(reg)	REG_FIELD(reg, 24, 31)
+
+/**
+ * Dedicated style retime Configuration register
+ * each register is dedicated per pin.
+ */
+#define RT_D_CFGS_PER_BANK		8
+#define RT_D_CFG_CLK_SHIFT		0
+#define RT_D_CFG_CLK_MASK		(0x3 << 0)
+#define RT_D_CFG_CLKNOTDATA_SHIFT	2
+#define RT_D_CFG_CLKNOTDATA_MASK	BIT(2)
+#define RT_D_CFG_DELAY_SHIFT		3
+#define RT_D_CFG_DELAY_MASK		(0xf << 3)
+#define RT_D_CFG_DELAY_INNOTOUT_SHIFT	7
+#define RT_D_CFG_DELAY_INNOTOUT_MASK	BIT(7)
+#define RT_D_CFG_DOUBLE_EDGE_SHIFT	8
+#define RT_D_CFG_DOUBLE_EDGE_MASK	BIT(8)
+#define RT_D_CFG_INVERTCLK_SHIFT	9
+#define RT_D_CFG_INVERTCLK_MASK		BIT(9)
+#define RT_D_CFG_RETIME_SHIFT		10
+#define RT_D_CFG_RETIME_MASK		BIT(10)
+
+/*
+ * Pinconf is represented in an opaque unsigned long variable.
+ * Below is the bit allocation details for each possible configuration.
+ * All the bit fields can be encapsulated into four variables
+ * (direction, retime-type, retime-clk, retime-delay)
+ *
+ *	 +----------------+
+ *[31:28]| reserved-3     |
+ *	 +----------------+-------------
+ *[27]   |	oe	  |		|
+ *	 +----------------+		v
+ *[26]   |	pu	  |	[Direction	]
+ *	 +----------------+		^
+ *[25]   |	od	  |		|
+ *	 +----------------+-------------
+ *[24]   | reserved-2     |
+ *	 +----------------+-------------
+ *[23]   |    retime      |		|
+ *	 +----------------+		|
+ *[22]   | retime-invclk  |		|
+ *	 +----------------+		v
+ *[21]   |retime-clknotdat|	[Retime-type	]
+ *	 +----------------+		^
+ *[20]   | retime-de      |		|
+ *	 +----------------+-------------
+ *[19:18]| retime-clk     |------>[Retime-Clk	]
+ *	 +----------------+
+ *[17:16]|  reserved-1    |
+ *	 +----------------+
+ *[15..0]| retime-delay   |------>[Retime Delay]
+ *	 +----------------+
+ */
+
+#define ST_PINCONF_UNPACK(conf, param)\
+				((conf >> ST_PINCONF_ ##param ##_SHIFT) \
+				& ST_PINCONF_ ##param ##_MASK)
+
+#define ST_PINCONF_PACK(conf, val, param)	(conf |=\
+				((val & ST_PINCONF_ ##param ##_MASK) << \
+					ST_PINCONF_ ##param ##_SHIFT))
+
+/* Output enable */
+#define ST_PINCONF_OE_MASK		0x1
+#define ST_PINCONF_OE_SHIFT		27
+#define ST_PINCONF_OE			BIT(27)
+#define ST_PINCONF_UNPACK_OE(conf)	ST_PINCONF_UNPACK(conf, OE)
+#define ST_PINCONF_PACK_OE(conf)	ST_PINCONF_PACK(conf, 1, OE)
+
+/* Pull Up */
+#define ST_PINCONF_PU_MASK		0x1
+#define ST_PINCONF_PU_SHIFT		26
+#define ST_PINCONF_PU			BIT(26)
+#define ST_PINCONF_UNPACK_PU(conf)	ST_PINCONF_UNPACK(conf, PU)
+#define ST_PINCONF_PACK_PU(conf)	ST_PINCONF_PACK(conf, 1, PU)
+
+/* Open Drain */
+#define ST_PINCONF_OD_MASK		0x1
+#define ST_PINCONF_OD_SHIFT		25
+#define ST_PINCONF_OD			BIT(25)
+#define ST_PINCONF_UNPACK_OD(conf)	ST_PINCONF_UNPACK(conf, OD)
+#define ST_PINCONF_PACK_OD(conf)	ST_PINCONF_PACK(conf, 1, OD)
+
+#define ST_PINCONF_RT_MASK		0x1
+#define ST_PINCONF_RT_SHIFT		23
+#define ST_PINCONF_RT			BIT(23)
+#define ST_PINCONF_UNPACK_RT(conf)	ST_PINCONF_UNPACK(conf, RT)
+#define ST_PINCONF_PACK_RT(conf)	ST_PINCONF_PACK(conf, 1, RT)
+
+#define ST_PINCONF_RT_INVERTCLK_MASK	0x1
+#define ST_PINCONF_RT_INVERTCLK_SHIFT	22
+#define ST_PINCONF_RT_INVERTCLK		BIT(22)
+#define ST_PINCONF_UNPACK_RT_INVERTCLK(conf) \
+			ST_PINCONF_UNPACK(conf, RT_INVERTCLK)
+#define ST_PINCONF_PACK_RT_INVERTCLK(conf) \
+			ST_PINCONF_PACK(conf, 1, RT_INVERTCLK)
+
+#define ST_PINCONF_RT_CLKNOTDATA_MASK	0x1
+#define ST_PINCONF_RT_CLKNOTDATA_SHIFT	21
+#define ST_PINCONF_RT_CLKNOTDATA	BIT(21)
+#define ST_PINCONF_UNPACK_RT_CLKNOTDATA(conf)	\
+				ST_PINCONF_UNPACK(conf, RT_CLKNOTDATA)
+#define ST_PINCONF_PACK_RT_CLKNOTDATA(conf) \
+				ST_PINCONF_PACK(conf, 1, RT_CLKNOTDATA)
+
+#define ST_PINCONF_RT_DOUBLE_EDGE_MASK	0x1
+#define ST_PINCONF_RT_DOUBLE_EDGE_SHIFT	20
+#define ST_PINCONF_RT_DOUBLE_EDGE	BIT(20)
+#define ST_PINCONF_UNPACK_RT_DOUBLE_EDGE(conf) \
+				ST_PINCONF_UNPACK(conf, RT_DOUBLE_EDGE)
+#define ST_PINCONF_PACK_RT_DOUBLE_EDGE(conf) \
+				ST_PINCONF_PACK(conf, 1, RT_DOUBLE_EDGE)
+
+#define ST_PINCONF_RT_CLK_MASK		0x3
+#define ST_PINCONF_RT_CLK_SHIFT		18
+#define ST_PINCONF_RT_CLK		BIT(18)
+#define ST_PINCONF_UNPACK_RT_CLK(conf)	ST_PINCONF_UNPACK(conf, RT_CLK)
+#define ST_PINCONF_PACK_RT_CLK(conf, val) ST_PINCONF_PACK(conf, val, RT_CLK)
+
+/* RETIME_DELAY in Pico Secs */
+#define ST_PINCONF_RT_DELAY_MASK	0xffff
+#define ST_PINCONF_RT_DELAY_SHIFT	0
+#define ST_PINCONF_UNPACK_RT_DELAY(conf) ST_PINCONF_UNPACK(conf, RT_DELAY)
+#define ST_PINCONF_PACK_RT_DELAY(conf, val) \
+				ST_PINCONF_PACK(conf, val, RT_DELAY)
+
+#define ST_GPIO_PINS_PER_BANK	(8)
+#define OF_GPIO_ARGS_MIN	(4)
+#define OF_RT_ARGS_MIN		(2)
+
+#define gpio_range_to_bank(chip) \
+		container_of(chip, struct st_gpio_bank, range)
+
+#define gpio_chip_to_bank(chip) \
+		container_of(chip, struct st_gpio_bank, gpio_chip)
+
+
+enum st_retime_style {
+	st_retime_style_none,
+	st_retime_style_packed,
+	st_retime_style_dedicated,
+};
+
+struct st_retime_dedicated {
+	struct regmap_field *rt[ST_GPIO_PINS_PER_BANK];
+};
+
+struct st_retime_packed {
+	struct regmap_field *clk1notclk0;
+	struct regmap_field *delay_0;
+	struct regmap_field *delay_1;
+	struct regmap_field *invertclk;
+	struct regmap_field *retime;
+	struct regmap_field *clknotdata;
+	struct regmap_field *double_edge;
+};
+
+struct st_pio_control {
+	u32 rt_pin_mask;
+	struct regmap_field *alt, *oe, *pu, *od;
+	/* retiming */
+	union {
+		struct st_retime_packed		rt_p;
+		struct st_retime_dedicated	rt_d;
+	} rt;
+};
+
+struct st_pctl_data {
+	enum st_retime_style rt_style;
+	unsigned int	*input_delays;
+	int		ninput_delays;
+	unsigned int	*output_delays;
+	int		noutput_delays;
+	/* register offset information */
+	int alt, oe, pu, od, rt;
+};
+
+struct st_pinconf {
+	int		pin;
+	const char	*name;
+	unsigned long	config;
+	int		altfunc;
+};
+
+struct st_pmx_func {
+	const char	*name;
+	const char	**groups;
+	unsigned	ngroups;
+};
+
+struct st_pctl_group {
+	const char		*name;
+	unsigned int		*pins;
+	unsigned		npins;
+	struct st_pinconf	*pin_conf;
+};
+
+struct st_gpio_bank {
+	struct gpio_chip		gpio_chip;
+	struct pinctrl_gpio_range	range;
+	void __iomem			*base;
+	struct st_pio_control		pc;
+};
+
+struct st_pinctrl {
+	struct device			*dev;
+	struct pinctrl_dev		*pctl;
+	struct st_gpio_bank		*banks;
+	int				nbanks;
+	struct st_pmx_func		*functions;
+	int				nfunctions;
+	struct st_pctl_group		*groups;
+	int				ngroups;
+	struct regmap			*regmap;
+	const struct st_pctl_data	*data;
+};
+
+/* SOC specific data */
+/* STiH415 data */
+unsigned int stih415_input_delays[] = {0, 500, 1000, 1500};
+unsigned int stih415_output_delays[] = {0, 1000, 2000, 3000};
+
+#define STIH415_PCTRL_COMMON_DATA				\
+	.rt_style	= st_retime_style_packed,		\
+	.input_delays	= stih415_input_delays,			\
+	.ninput_delays	= 4,					\
+	.output_delays = stih415_output_delays,			\
+	.noutput_delays = 4
+
+static const struct st_pctl_data  stih415_sbc_data = {
+	STIH415_PCTRL_COMMON_DATA,
+	.alt = 0, .oe = 5, .pu = 7, .od = 9, .rt = 16,
+};
+
+static const struct st_pctl_data  stih415_front_data = {
+	STIH415_PCTRL_COMMON_DATA,
+	.alt = 0, .oe = 8, .pu = 10, .od = 12, .rt = 16,
+};
+
+static const struct st_pctl_data  stih415_rear_data = {
+	STIH415_PCTRL_COMMON_DATA,
+	.alt = 0, .oe = 6, .pu = 8, .od = 10, .rt = 38,
+};
+
+static const struct st_pctl_data  stih415_left_data = {
+	STIH415_PCTRL_COMMON_DATA,
+	.alt = 0, .oe = 3, .pu = 4, .od = 5, .rt = 6,
+};
+
+static const struct st_pctl_data  stih415_right_data = {
+	STIH415_PCTRL_COMMON_DATA,
+	.alt = 0, .oe = 5, .pu = 7, .od = 9, .rt = 11,
+};
+
+/* STiH416 data */
+unsigned int stih416_delays[] = {0, 300, 500, 750, 1000, 1250, 1500,
+			1750, 2000, 2250, 2500, 2750, 3000, 3250 };
+
+static const struct st_pctl_data  stih416_data = {
+	.rt_style	= st_retime_style_dedicated,
+	.input_delays	= stih416_delays,
+	.ninput_delays	= 14,
+	.output_delays	= stih416_delays,
+	.noutput_delays = 14,
+	.alt = 0, .oe = 40, .pu = 50, .od = 60, .rt = 100,
+};
+
+/* Low level functions.. */
+static inline int st_gpio_bank(int gpio)
+{
+	return gpio/ST_GPIO_PINS_PER_BANK;
+}
+
+static inline int st_gpio_pin(int gpio)
+{
+	return gpio%ST_GPIO_PINS_PER_BANK;
+}
+
+static void st_pinconf_set_config(struct st_pio_control *pc,
+				int pin, unsigned long config)
+{
+	struct regmap_field *output_enable = pc->oe;
+	struct regmap_field *pull_up = pc->pu;
+	struct regmap_field *open_drain = pc->od;
+	unsigned int oe_value, pu_value, od_value;
+	unsigned long mask = BIT(pin);
+
+	regmap_field_read(output_enable, &oe_value);
+	regmap_field_read(pull_up, &pu_value);
+	regmap_field_read(open_drain, &od_value);
+
+	/* Clear old values */
+	oe_value &= ~mask;
+	pu_value &= ~mask;
+	od_value &= ~mask;
+
+	if (config & ST_PINCONF_OE)
+		oe_value |= mask;
+	if (config & ST_PINCONF_PU)
+		pu_value |= mask;
+	if (config & ST_PINCONF_OD)
+		od_value |= mask;
+
+	regmap_field_write(output_enable, oe_value);
+	regmap_field_write(pull_up, pu_value);
+	regmap_field_write(open_drain, od_value);
+}
+
+static void st_pctl_set_function(struct st_pio_control *pc,
+				int pin_id, int function)
+{
+	struct regmap_field *alt = pc->alt;
+	unsigned int val;
+	int pin = st_gpio_pin(pin_id);
+	int offset = pin * 4;
+
+	regmap_field_read(alt, &val);
+	val &= ~(0xf << offset);
+	val |= function << offset;
+	regmap_field_write(alt, val);
+}
+
+static unsigned long st_pinconf_delay_to_bit(unsigned int delay,
+	const struct st_pctl_data *data, unsigned long config)
+{
+	unsigned int *delay_times;
+	int num_delay_times, i, closest_index = -1;
+	unsigned int closest_divergence = UINT_MAX;
+
+	if (ST_PINCONF_UNPACK_OE(config)) {
+		delay_times = data->output_delays;
+		num_delay_times = data->noutput_delays;
+	} else {
+		delay_times = data->input_delays;
+		num_delay_times = data->ninput_delays;
+	}
+
+	for (i = 0; i < num_delay_times; i++) {
+		unsigned int divergence = abs(delay - delay_times[i]);
+
+		if (divergence == 0)
+			return i;
+
+		if (divergence < closest_divergence) {
+			closest_divergence = divergence;
+			closest_index = i;
+		}
+	}
+
+	pr_warn("Attempt to set delay %d, closest available %d\n",
+	     delay, delay_times[closest_index]);
+
+	return closest_index;
+}
+
+static unsigned long st_pinconf_bit_to_delay(unsigned int index,
+	const struct st_pctl_data *data, unsigned long output)
+{
+	unsigned int *delay_times;
+	int num_delay_times;
+
+	if (output) {
+		delay_times = data->output_delays;
+		num_delay_times = data->noutput_delays;
+	} else {
+		delay_times = data->input_delays;
+		num_delay_times = data->ninput_delays;
+	}
+
+	if (index < num_delay_times) {
+		return delay_times[index];
+	} else {
+		pr_warn("Delay not found in/out delay list\n");
+		return 0;
+	}
+}
+
+static void st_regmap_field_bit_set_clear_pin(struct regmap_field *field,
+	int enable, int pin)
+{
+	unsigned int val = 0;
+
+	regmap_field_read(field, &val);
+	if (enable)
+		val |= BIT(pin);
+	else
+		val &= ~BIT(pin);
+	regmap_field_write(field, val);
+}
+
+static void st_pinconf_set_retime_packed(struct st_pinctrl *info,
+	struct st_pio_control *pc,	unsigned long config, int pin)
+{
+	const struct st_pctl_data *data = info->data;
+	struct st_retime_packed *rt_p = &pc->rt.rt_p;
+	unsigned int delay;
+
+	st_regmap_field_bit_set_clear_pin(rt_p->clk1notclk0,
+				ST_PINCONF_UNPACK_RT_CLK(config), pin);
+
+	st_regmap_field_bit_set_clear_pin(rt_p->clknotdata,
+				ST_PINCONF_UNPACK_RT_CLKNOTDATA(config), pin);
+
+	st_regmap_field_bit_set_clear_pin(rt_p->double_edge,
+				ST_PINCONF_UNPACK_RT_DOUBLE_EDGE(config), pin);
+
+	st_regmap_field_bit_set_clear_pin(rt_p->invertclk,
+				ST_PINCONF_UNPACK_RT_INVERTCLK(config), pin);
+
+	st_regmap_field_bit_set_clear_pin(rt_p->retime,
+				ST_PINCONF_UNPACK_RT(config), pin);
+
+	delay = st_pinconf_delay_to_bit(ST_PINCONF_UNPACK_RT_DELAY(config),
+					data, config);
+	/* 2 bit delay, lsb */
+	st_regmap_field_bit_set_clear_pin(rt_p->delay_0, delay & 0x1, pin);
+	/* 2 bit delay, msb */
+	st_regmap_field_bit_set_clear_pin(rt_p->delay_1, delay & 0x2, pin);
+
+}
+
+static void st_pinconf_set_retime_dedicated(struct st_pinctrl *info,
+	struct st_pio_control *pc, unsigned long config, int pin)
+{
+	int input	= ST_PINCONF_UNPACK_OE(config) ? 0 : 1;
+	int clk		= ST_PINCONF_UNPACK_RT_CLK(config);
+	int clknotdata	= ST_PINCONF_UNPACK_RT_CLKNOTDATA(config);
+	int double_edge	= ST_PINCONF_UNPACK_RT_DOUBLE_EDGE(config);
+	int invertclk	= ST_PINCONF_UNPACK_RT_INVERTCLK(config);
+	int retime	= ST_PINCONF_UNPACK_RT(config);
+
+	unsigned long delay = st_pinconf_delay_to_bit(
+			ST_PINCONF_UNPACK_RT_DELAY(config),
+			info->data, config);
+	struct st_retime_dedicated *rt_d = &pc->rt.rt_d;
+
+	unsigned long retime_config =
+		((clk) << RT_D_CFG_CLK_SHIFT) |
+		((delay) << RT_D_CFG_DELAY_SHIFT) |
+		((input) << RT_D_CFG_DELAY_INNOTOUT_SHIFT) |
+		((retime) << RT_D_CFG_RETIME_SHIFT) |
+		((clknotdata) << RT_D_CFG_CLKNOTDATA_SHIFT) |
+		((invertclk) << RT_D_CFG_INVERTCLK_SHIFT) |
+		((double_edge) << RT_D_CFG_DOUBLE_EDGE_SHIFT);
+
+	regmap_field_write(rt_d->rt[pin], retime_config);
+}
+
+static void st_pinconf_get_direction(struct st_pio_control *pc,
+	int pin, unsigned long *config)
+{
+	unsigned int oe_value, pu_value, od_value;
+
+	regmap_field_read(pc->oe, &oe_value);
+	regmap_field_read(pc->pu, &pu_value);
+	regmap_field_read(pc->od, &od_value);
+
+	if (oe_value & BIT(pin))
+		ST_PINCONF_PACK_OE(*config);
+	if (pu_value & BIT(pin))
+		ST_PINCONF_PACK_PU(*config);
+	if (od_value & BIT(pin))
+		ST_PINCONF_PACK_OD(*config);
+
+}
+
+static int st_pinconf_get_retime_packed(struct st_pinctrl *info,
+	struct st_pio_control *pc,	int pin, unsigned long *config)
+{
+	const struct st_pctl_data *data = info->data;
+	struct st_retime_packed *rt_p = &pc->rt.rt_p;
+	unsigned int delay_bits, delay, delay0, delay1, val;
+	int output = ST_PINCONF_UNPACK_OE(*config);
+
+	if (!regmap_field_read(rt_p->retime, &val) && (val & BIT(pin)))
+		ST_PINCONF_PACK_RT(*config);
+
+	if (!regmap_field_read(rt_p->clk1notclk0, &val) && (val & BIT(pin)))
+		ST_PINCONF_PACK_RT_CLK(*config, 1);
+
+	if (!regmap_field_read(rt_p->clknotdata, &val) && (val & BIT(pin)))
+		ST_PINCONF_PACK_RT_CLKNOTDATA(*config);
+
+	if (!regmap_field_read(rt_p->double_edge, &val) && (val & BIT(pin)))
+		ST_PINCONF_PACK_RT_DOUBLE_EDGE(*config);
+
+	if (!regmap_field_read(rt_p->invertclk, &val) && (val & BIT(pin)))
+		ST_PINCONF_PACK_RT_INVERTCLK(*config);
+
+	regmap_field_read(rt_p->delay_0, &delay0);
+	regmap_field_read(rt_p->delay_1, &delay1);
+	delay_bits = (((delay1 & BIT(pin)) ? 1 : 0) << 1) |
+			(((delay0 & BIT(pin)) ? 1 : 0));
+	delay =  st_pinconf_bit_to_delay(delay_bits, data, output);
+	ST_PINCONF_PACK_RT_DELAY(*config, delay);
+
+	return 0;
+}
+
+static int st_pinconf_get_retime_dedicated(struct st_pinctrl *info,
+	struct st_pio_control *pc,	int pin, unsigned long *config)
+{
+	unsigned int value;
+	unsigned long delay_bits, delay, rt_clk;
+	int output = ST_PINCONF_UNPACK_OE(*config);
+	struct st_retime_dedicated *rt_d = &pc->rt.rt_d;
+
+	regmap_field_read(rt_d->rt[pin], &value);
+
+	rt_clk = (value & RT_D_CFG_CLK_MASK) >> RT_D_CFG_CLK_SHIFT;
+	ST_PINCONF_PACK_RT_CLK(*config, rt_clk);
+
+	delay_bits = (value & RT_D_CFG_DELAY_MASK) >> RT_D_CFG_DELAY_SHIFT;
+	delay =  st_pinconf_bit_to_delay(delay_bits, info->data, output);
+	ST_PINCONF_PACK_RT_DELAY(*config, delay);
+
+	if (value & RT_D_CFG_CLKNOTDATA_MASK)
+		ST_PINCONF_PACK_RT_CLKNOTDATA(*config);
+
+	if (value & RT_D_CFG_DOUBLE_EDGE_MASK)
+		ST_PINCONF_PACK_RT_DOUBLE_EDGE(*config);
+
+	if (value & RT_D_CFG_INVERTCLK_MASK)
+		ST_PINCONF_PACK_RT_INVERTCLK(*config);
+
+	if (value & RT_D_CFG_RETIME_MASK)
+		ST_PINCONF_PACK_RT(*config);
+
+	return 0;
+}
+
+/* GPIO related functions */
+
+static inline void __st_gpio_set(struct st_gpio_bank *bank,
+	unsigned offset, int value)
+{
+	if (value)
+		writel(BIT(offset), bank->base + REG_PIO_SET_POUT);
+	else
+		writel(BIT(offset), bank->base + REG_PIO_CLR_POUT);
+}
+
+static void st_gpio_direction(struct st_gpio_bank *bank,
+		unsigned int gpio, unsigned int direction)
+{
+	int offset = st_gpio_pin(gpio);
+	int i = 0;
+	/**
+	 * There are three configuration registers (PIOn_PC0, PIOn_PC1
+	 * and PIOn_PC2) for each port. These are used to configure the
+	 * PIO port pins. Each pin can be configured as an input, output,
+	 * bidirectional, or alternative function pin. Three bits, one bit
+	 * from each of the three registers, configure the corresponding bit of
+	 * the port. Valid bit settings is:
+	 *
+	 * PC2		PC1		PC0	Direction.
+	 * 0		0		0	[Input Weak pull-up]
+	 * 0		0 or 1		1	[Bidirection]
+	 * 0		1		0	[Output]
+	 * 1		0		0	[Input]
+	 *
+	 * PIOn_SET_PC and PIOn_CLR_PC registers are used to set and clear bits
+	 * individually.
+	 */
+	for (i = 0; i <= 2; i++) {
+		if (direction & BIT(i))
+			writel(BIT(offset), bank->base + REG_PIO_SET_PC(i));
+		else
+			writel(BIT(offset), bank->base + REG_PIO_CLR_PC(i));
+	}
+}
+
+static int st_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void st_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_free_gpio(chip->base + offset);
+}
+
+static int st_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct st_gpio_bank *bank = gpio_chip_to_bank(chip);
+
+	return !!(readl(bank->base + REG_PIO_PIN) & BIT(offset));
+}
+
+static void st_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct st_gpio_bank *bank = gpio_chip_to_bank(chip);
+	__st_gpio_set(bank, offset, value);
+}
+
+static int st_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_gpio_direction_input(chip->base + offset);
+
+	return 0;
+}
+
+static int st_gpio_direction_output(struct gpio_chip *chip,
+	unsigned offset, int value)
+{
+	struct st_gpio_bank *bank = gpio_chip_to_bank(chip);
+
+	__st_gpio_set(bank, offset, value);
+	pinctrl_gpio_direction_output(chip->base + offset);
+
+	return 0;
+}
+
+static int st_gpio_xlate(struct gpio_chip *gc,
+			const struct of_phandle_args *gpiospec, u32 *flags)
+{
+	if (WARN_ON(gc->of_gpio_n_cells < 1))
+		return -EINVAL;
+
+	if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
+		return -EINVAL;
+
+	if (gpiospec->args[0] > gc->ngpio)
+		return -EINVAL;
+
+	return gpiospec->args[0];
+}
+
+/* Pinctrl Groups */
+static int st_pctl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->ngroups;
+}
+
+static const char *st_pctl_get_group_name(struct pinctrl_dev *pctldev,
+				       unsigned selector)
+{
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->groups[selector].name;
+}
+
+static int st_pctl_get_group_pins(struct pinctrl_dev *pctldev,
+	unsigned selector, const unsigned **pins, unsigned *npins)
+{
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	*pins = info->groups[selector].pins;
+	*npins = info->groups[selector].npins;
+
+	return 0;
+}
+
+static const inline struct st_pctl_group *st_pctl_find_group_by_name(
+	const struct st_pinctrl *info, const char *name)
+{
+	int i;
+
+	for (i = 0; i < info->ngroups; i++) {
+		if (!strcmp(info->groups[i].name, name))
+			return &info->groups[i];
+	}
+
+	return NULL;
+}
+
+static int st_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
+	struct device_node *np, struct pinctrl_map **map, unsigned *num_maps)
+{
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	const struct st_pctl_group *grp;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num, i;
+
+	grp = st_pctl_find_group_by_name(info, np->name);
+	if (!grp) {
+		dev_err(info->dev, "unable to find group for node %s\n",
+			np->name);
+		return -EINVAL;
+	}
+
+	map_num = grp->npins + 1;
+	new_map = devm_kzalloc(pctldev->dev,
+				sizeof(*new_map) * map_num, GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	parent = of_get_parent(np);
+	if (!parent) {
+		devm_kfree(pctldev->dev, new_map);
+		return -EINVAL;
+	}
+
+	*map = new_map;
+	*num_maps = map_num;
+	new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+	new_map[0].data.mux.function = parent->name;
+	new_map[0].data.mux.group = np->name;
+	of_node_put(parent);
+
+	/* create config map per pin */
+	new_map++;
+	for (i = 0; i < grp->npins; i++) {
+		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map[i].data.configs.group_or_pin =
+				pin_get_name(pctldev, grp->pins[i]);
+		new_map[i].data.configs.configs = &grp->pin_conf[i].config;
+		new_map[i].data.configs.num_configs = 1;
+	}
+	dev_info(pctldev->dev, "maps: function %s group %s num %d\n",
+		(*map)->data.mux.function, grp->name, map_num);
+
+	return 0;
+}
+
+static void st_pctl_dt_free_map(struct pinctrl_dev *pctldev,
+			struct pinctrl_map *map, unsigned num_maps)
+{
+}
+
+static struct pinctrl_ops st_pctlops = {
+	.get_groups_count	= st_pctl_get_groups_count,
+	.get_group_pins		= st_pctl_get_group_pins,
+	.get_group_name		= st_pctl_get_group_name,
+	.dt_node_to_map		= st_pctl_dt_node_to_map,
+	.dt_free_map		= st_pctl_dt_free_map,
+};
+
+/* Pinmux */
+static int st_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->nfunctions;
+}
+
+const char *st_pmx_get_fname(struct pinctrl_dev *pctldev,
+	unsigned selector)
+{
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->functions[selector].name;
+}
+
+static int st_pmx_get_groups(struct pinctrl_dev *pctldev,
+	unsigned selector, const char * const **grps, unsigned * const ngrps)
+{
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	*grps = info->functions[selector].groups;
+	*ngrps = info->functions[selector].ngroups;
+
+	return 0;
+}
+
+static struct st_pio_control *st_get_pio_control(
+			struct pinctrl_dev *pctldev, int pin)
+{
+	struct pinctrl_gpio_range *range =
+			 pinctrl_find_gpio_range_from_pin(pctldev, pin);
+	struct st_gpio_bank *bank = gpio_range_to_bank(range);
+
+	return &bank->pc;
+}
+
+static int st_pmx_enable(struct pinctrl_dev *pctldev, unsigned fselector,
+		unsigned group)
+{
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct st_pinconf *conf = info->groups[group].pin_conf;
+	struct st_pio_control *pc;
+	int i;
+
+	for (i = 0; i < info->groups[group].npins; i++) {
+		pc = st_get_pio_control(pctldev, conf[i].pin);
+		st_pctl_set_function(pc, conf[i].pin, conf[i].altfunc);
+	}
+
+	return 0;
+}
+
+static void st_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector,
+		unsigned group)
+{
+}
+
+static int st_pmx_set_gpio_direction(struct pinctrl_dev *pctldev,
+			struct pinctrl_gpio_range *range, unsigned gpio,
+			bool input)
+{
+	struct st_gpio_bank *bank = gpio_range_to_bank(range);
+	/*
+	 * When a PIO bank is used in its primary function mode (altfunc = 0)
+	 * Output Enable (OE), Open Drain(OD), and Pull Up (PU)
+	 * for the primary PIO functions are driven by the related PIO block
+	 */
+	st_pctl_set_function(&bank->pc, gpio, 0);
+	st_gpio_direction(bank, gpio, input ?
+		ST_GPIO_DIRECTION_IN : ST_GPIO_DIRECTION_OUT);
+
+	return 0;
+}
+
+static struct pinmux_ops st_pmxops = {
+	.get_functions_count	= st_pmx_get_funcs_count,
+	.get_function_name	= st_pmx_get_fname,
+	.get_function_groups	= st_pmx_get_groups,
+	.enable			= st_pmx_enable,
+	.disable		= st_pmx_disable,
+	.gpio_set_direction	= st_pmx_set_gpio_direction,
+};
+
+/* Pinconf  */
+static void st_pinconf_get_retime(struct st_pinctrl *info,
+	struct st_pio_control *pc, int pin, unsigned long *config)
+{
+	if (info->data->rt_style == st_retime_style_packed)
+		st_pinconf_get_retime_packed(info, pc, pin, config);
+	else if (info->data->rt_style == st_retime_style_dedicated)
+		if ((BIT(pin) & pc->rt_pin_mask))
+			st_pinconf_get_retime_dedicated(info, pc,
+					pin, config);
+}
+
+static void st_pinconf_set_retime(struct st_pinctrl *info,
+	struct st_pio_control *pc, int pin, unsigned long config)
+{
+	if (info->data->rt_style == st_retime_style_packed)
+		st_pinconf_set_retime_packed(info, pc, config, pin);
+	else if (info->data->rt_style == st_retime_style_dedicated)
+		if ((BIT(pin) & pc->rt_pin_mask))
+			st_pinconf_set_retime_dedicated(info, pc,
+							config, pin);
+}
+
+static int st_pinconf_set(struct pinctrl_dev *pctldev,
+			     unsigned pin_id, unsigned long config)
+{
+	int pin = st_gpio_pin(pin_id);
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id);
+
+	st_pinconf_set_config(pc, pin, config);
+	st_pinconf_set_retime(info, pc, pin, config);
+
+	return 0;
+}
+
+static int st_pinconf_get(struct pinctrl_dev *pctldev,
+			     unsigned pin_id, unsigned long *config)
+{
+	int pin = st_gpio_pin(pin_id);
+	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id);
+
+	*config = 0;
+	st_pinconf_get_direction(pc, pin, config);
+	st_pinconf_get_retime(info, pc, pin, config);
+
+	return 0;
+}
+
+static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+				   struct seq_file *s, unsigned pin_id)
+{
+	unsigned long config;
+	st_pinconf_get(pctldev, pin_id, &config);
+
+	seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n"
+		"\t\t[retime:%ld,invclk:%ld,clknotdat:%ld,"
+		"de:%ld,rt-clk:%ld,rt-delay:%ld]",
+		ST_PINCONF_UNPACK_OE(config),
+		ST_PINCONF_UNPACK_PU(config),
+		ST_PINCONF_UNPACK_OD(config),
+		ST_PINCONF_UNPACK_RT(config),
+		ST_PINCONF_UNPACK_RT_INVERTCLK(config),
+		ST_PINCONF_UNPACK_RT_CLKNOTDATA(config),
+		ST_PINCONF_UNPACK_RT_DOUBLE_EDGE(config),
+		ST_PINCONF_UNPACK_RT_CLK(config),
+		ST_PINCONF_UNPACK_RT_DELAY(config));
+}
+
+static struct pinconf_ops st_confops = {
+	.pin_config_get		= st_pinconf_get,
+	.pin_config_set		= st_pinconf_set,
+	.pin_config_dbg_show	= st_pinconf_dbg_show,
+};
+
+static void st_pctl_dt_child_count(struct st_pinctrl *info,
+				     struct device_node *np)
+{
+	struct device_node *child;
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller")) {
+			info->nbanks++;
+		} else {
+			info->nfunctions++;
+			info->ngroups += of_get_child_count(child);
+		}
+	}
+}
+
+static int st_pctl_dt_setup_retime_packed(struct st_pinctrl *info,
+	int bank, struct st_pio_control *pc)
+{
+	struct device *dev = info->dev;
+	struct regmap *rm = info->regmap;
+	const struct st_pctl_data *data = info->data;
+	/* 2 registers per bank */
+	int reg = (data->rt + bank * RT_P_CFGS_PER_BANK) * 4;
+	struct st_retime_packed *rt_p = &pc->rt.rt_p;
+	/* cfg0 */
+	struct reg_field clk1notclk0 = RT_P_CFG0_CLK1NOTCLK0_FIELD(reg);
+	struct reg_field delay_0 = RT_P_CFG0_DELAY_0_FIELD(reg);
+	struct reg_field delay_1 = RT_P_CFG0_DELAY_1_FIELD(reg);
+	/* cfg1 */
+	struct reg_field invertclk = RT_P_CFG1_INVERTCLK_FIELD(reg + 4);
+	struct reg_field retime = RT_P_CFG1_RETIME_FIELD(reg + 4);
+	struct reg_field clknotdata = RT_P_CFG1_CLKNOTDATA_FIELD(reg + 4);
+	struct reg_field double_edge = RT_P_CFG1_DOUBLE_EDGE_FIELD(reg + 4);
+
+	rt_p->clk1notclk0 = devm_regmap_field_alloc(dev, rm, clk1notclk0);
+	rt_p->delay_0	= devm_regmap_field_alloc(dev, rm, delay_0);
+	rt_p->delay_1 = devm_regmap_field_alloc(dev, rm, delay_1);
+	rt_p->invertclk = devm_regmap_field_alloc(dev, rm, invertclk);
+	rt_p->retime = devm_regmap_field_alloc(dev, rm, retime);
+	rt_p->clknotdata = devm_regmap_field_alloc(dev, rm, clknotdata);
+	rt_p->double_edge = devm_regmap_field_alloc(dev, rm, double_edge);
+
+	if (IS_ERR(rt_p->clk1notclk0) || IS_ERR(rt_p->delay_0) ||
+		 IS_ERR(rt_p->delay_1) || IS_ERR(rt_p->invertclk) ||
+		 IS_ERR(rt_p->retime) || IS_ERR(rt_p->clknotdata) ||
+		 IS_ERR(rt_p->double_edge))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int st_pctl_dt_setup_retime_dedicated(struct st_pinctrl *info,
+	int bank, struct st_pio_control *pc)
+{
+	struct device *dev = info->dev;
+	struct regmap *rm = info->regmap;
+	const struct st_pctl_data *data = info->data;
+	/* 8 registers per bank */
+	int reg_offset = (data->rt + bank * RT_D_CFGS_PER_BANK) * 4;
+	struct st_retime_dedicated *rt_d = &pc->rt.rt_d;
+	unsigned int j;
+	u32 pin_mask = pc->rt_pin_mask;
+
+	for (j = 0; j < RT_D_CFGS_PER_BANK; j++) {
+		if (BIT(j) & pin_mask) {
+			struct reg_field reg = REG_FIELD(reg_offset, 0, 31);
+			rt_d->rt[j] = devm_regmap_field_alloc(dev, rm, reg);
+			if (IS_ERR(rt_d->rt[j]))
+				return -EINVAL;
+			reg_offset += 4;
+		}
+	}
+	return 0;
+}
+
+static int st_pctl_dt_setup_retime(struct st_pinctrl *info,
+	int bank, struct st_pio_control *pc)
+{
+	const struct st_pctl_data *data = info->data;
+	if (data->rt_style  == st_retime_style_packed)
+		return st_pctl_dt_setup_retime_packed(info, bank, pc);
+	else if (data->rt_style == st_retime_style_dedicated)
+		return st_pctl_dt_setup_retime_dedicated(info, bank, pc);
+
+	return -EINVAL;
+}
+
+static int st_parse_syscfgs(struct st_pinctrl *info,
+		int bank, struct device_node *np)
+{
+	const struct st_pctl_data *data = info->data;
+	/**
+	 * For a given shared register like OE/PU/OD, there are 8 bits per bank
+	 * 0:7 belongs to bank0, 8:15 belongs to bank1 ...
+	 * So each register is shared across 4 banks.
+	 */
+	int lsb = (bank%4) * ST_GPIO_PINS_PER_BANK;
+	int msb = lsb + ST_GPIO_PINS_PER_BANK - 1;
+	struct reg_field alt_reg = REG_FIELD((data->alt + bank) * 4, 0, 31);
+	struct reg_field oe_reg = REG_FIELD((data->oe + bank/4) * 4, lsb, msb);
+	struct reg_field pu_reg = REG_FIELD((data->pu + bank/4) * 4, lsb, msb);
+	struct reg_field od_reg = REG_FIELD((data->od + bank/4) * 4, lsb, msb);
+	struct st_pio_control *pc = &info->banks[bank].pc;
+	struct device *dev = info->dev;
+	struct regmap *regmap  = info->regmap;
+
+	pc->alt = devm_regmap_field_alloc(dev, regmap, alt_reg);
+	pc->oe = devm_regmap_field_alloc(dev, regmap, oe_reg);
+	pc->pu = devm_regmap_field_alloc(dev, regmap, pu_reg);
+	pc->od = devm_regmap_field_alloc(dev, regmap, od_reg);
+
+	if (IS_ERR(pc->alt) || IS_ERR(pc->oe) ||
+			IS_ERR(pc->pu) || IS_ERR(pc->od))
+		return -EINVAL;
+
+	/* retime avaiable for all pins by default */
+	pc->rt_pin_mask = 0xff;
+	of_property_read_u32(np, "st,retime-pin-mask", &pc->rt_pin_mask);
+	st_pctl_dt_setup_retime(info, bank, pc);
+
+	return 0;
+}
+
+/*
+ * Each pin is represented in of the below forms.
+ * <bank offset mux direction rt_type rt_delay rt_clk>
+ */
+static int st_pctl_dt_parse_groups(struct device_node *np,
+	struct st_pctl_group *grp, struct st_pinctrl *info, int idx)
+{
+	/* bank pad direction val altfunction */
+	const __be32 *list;
+	struct property *pp;
+	struct st_pinconf *conf;
+	phandle phandle;
+	struct device_node *pins;
+	u32 pin;
+	int i = 0, npins = 0, nr_props;
+
+	pins = of_get_child_by_name(np, "st,pins");
+	if (!pins)
+		return -ENODATA;
+
+	for_each_property_of_node(pins, pp) {
+		/* Skip those we do not want to proceed */
+		if (!strcmp(pp->name, "name"))
+			continue;
+
+		if (pp  && (pp->length/sizeof(__be32)) >= OF_GPIO_ARGS_MIN) {
+			npins++;
+		} else {
+			pr_warn("Invalid st,pins in %s node\n", np->name);
+			return -EINVAL;
+		}
+	}
+
+	grp->npins = npins;
+	grp->name = np->name;
+	grp->pins = devm_kzalloc(info->dev, npins * sizeof(u32), GFP_KERNEL);
+	grp->pin_conf = devm_kzalloc(info->dev,
+					npins * sizeof(*conf), GFP_KERNEL);
+
+	if (!grp->pins || !grp->pin_conf)
+		return -ENOMEM;
+
+	/* <bank offset mux direction rt_type rt_delay rt_clk> */
+	for_each_property_of_node(pins, pp) {
+		if (!strcmp(pp->name, "name"))
+			continue;
+		nr_props = pp->length/sizeof(u32);
+		list = pp->value;
+		conf = &grp->pin_conf[i];
+
+		/* bank & offset */
+		phandle = be32_to_cpup(list++);
+		pin = be32_to_cpup(list++);
+		conf->pin = of_get_named_gpio(pins, pp->name, 0);
+		conf->name = pp->name;
+		grp->pins[i] = conf->pin;
+		/* mux */
+		conf->altfunc = be32_to_cpup(list++);
+		conf->config = 0;
+		/* direction */
+		conf->config |= be32_to_cpup(list++);
+		/* rt_type rt_delay rt_clk */
+		if (nr_props >= OF_GPIO_ARGS_MIN + OF_RT_ARGS_MIN) {
+			/* rt_type */
+			conf->config |= be32_to_cpup(list++);
+			/* rt_delay */
+			conf->config |= be32_to_cpup(list++);
+			/* rt_clk */
+			if (nr_props > OF_GPIO_ARGS_MIN + OF_RT_ARGS_MIN)
+				conf->config |= be32_to_cpup(list++);
+		}
+		i++;
+	}
+	of_node_put(pins);
+
+	return 0;
+}
+
+static int st_pctl_parse_functions(struct device_node *np,
+			struct st_pinctrl *info, u32 index, int *grp_index)
+{
+	struct device_node *child;
+	struct st_pmx_func *func;
+	struct st_pctl_group *grp;
+	int ret, i;
+
+	func = &info->functions[index];
+	func->name = np->name;
+	func->ngroups = of_get_child_count(np);
+	if (func->ngroups <= 0) {
+		dev_err(info->dev, "No groups defined\n");
+		return -EINVAL;
+	}
+	func->groups = devm_kzalloc(info->dev,
+			func->ngroups * sizeof(char *), GFP_KERNEL);
+	if (!func->groups)
+		return -ENOMEM;
+
+	i = 0;
+	for_each_child_of_node(np, child) {
+		func->groups[i] = child->name;
+		grp = &info->groups[*grp_index];
+		*grp_index += 1;
+		ret = st_pctl_dt_parse_groups(child, grp, info, i++);
+		if (ret)
+			return ret;
+	}
+	dev_info(info->dev, "Function[%d\t name:%s,\tgroups:%d]\n",
+				index, func->name, func->ngroups);
+
+	return 0;
+}
+
+static struct gpio_chip st_gpio_template = {
+	.request		= st_gpio_request,
+	.free			= st_gpio_free,
+	.get			= st_gpio_get,
+	.set			= st_gpio_set,
+	.direction_input	= st_gpio_direction_input,
+	.direction_output	= st_gpio_direction_output,
+	.ngpio			= ST_GPIO_PINS_PER_BANK,
+	.of_gpio_n_cells	= 1,
+	.of_xlate		= st_gpio_xlate,
+};
+
+static int st_gpiolib_register_bank(struct st_pinctrl *info,
+	int bank_nr, struct device_node *np)
+{
+	struct st_gpio_bank *bank = &info->banks[bank_nr];
+	struct pinctrl_gpio_range *range = &bank->range;
+	struct device *dev = info->dev;
+	int bank_num = of_alias_get_id(np, "gpio");
+	struct resource res;
+	int err;
+
+	if (of_address_to_resource(np, 0, &res))
+		return -ENODEV;
+
+	bank->base = devm_request_and_ioremap(dev, &res);
+	if (!bank->base) {
+		dev_err(dev, "Can't get IO memory mapping!\n");
+		return -ENODEV;
+	}
+
+	bank->gpio_chip = st_gpio_template;
+	bank->gpio_chip.base = bank_num * ST_GPIO_PINS_PER_BANK;
+	bank->gpio_chip.ngpio = ST_GPIO_PINS_PER_BANK;
+	bank->gpio_chip.of_node = np;
+
+	of_property_read_string(np, "st,bank-name", &range->name);
+	bank->gpio_chip.label = range->name;
+
+	range->id = bank_num;
+	range->pin_base = range->base = range->id * ST_GPIO_PINS_PER_BANK;
+	range->npins = bank->gpio_chip.ngpio;
+	range->gc = &bank->gpio_chip;
+	err  = gpiochip_add(&bank->gpio_chip);
+	if (err) {
+		dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_num);
+		return err;
+	}
+	dev_info(dev, "%s bank added.\n", range->name);
+
+	return 0;
+}
+
+static struct of_device_id st_pctl_of_match[] = {
+	{ .compatible = "st,stih415-sbc-pinctrl", .data = &stih415_sbc_data },
+	{ .compatible = "st,stih415-rear-pinctrl", .data = &stih415_rear_data },
+	{ .compatible = "st,stih415-left-pinctrl", .data = &stih415_left_data },
+	{ .compatible = "st,stih415-right-pinctrl",
+		.data = &stih415_right_data },
+	{ .compatible = "st,stih415-front-pinctrl",
+		.data = &stih415_front_data },
+	{ .compatible = "st,stih416-sbc-pinctrl", .data = &stih416_data},
+	{ .compatible = "st,stih416-front-pinctrl", .data = &stih416_data},
+	{ .compatible = "st,stih416-rear-pinctrl", .data = &stih416_data},
+	{ .compatible = "st,stih416-fvdp-fe-pinctrl", .data = &stih416_data},
+	{ .compatible = "st,stih416-fvdp-lite-pinctrl", .data = &stih416_data},
+	{ /* sentinel */ }
+};
+
+static int st_pctl_probe_dt(struct platform_device *pdev,
+	struct pinctrl_desc *pctl_desc, struct st_pinctrl *info)
+{
+	int ret = 0;
+	int i = 0, j = 0, k = 0, bank;
+	struct pinctrl_pin_desc *pdesc;
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *child;
+	int grp_index = 0;
+
+	st_pctl_dt_child_count(info, np);
+	if (!info->nbanks) {
+		dev_err(&pdev->dev, "you need atleast one gpio bank\n");
+		return -EINVAL;
+	}
+
+	dev_info(&pdev->dev, "nbanks = %d\n", info->nbanks);
+	dev_info(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
+	dev_info(&pdev->dev, "ngroups = %d\n", info->ngroups);
+
+	info->functions = devm_kzalloc(&pdev->dev,
+		info->nfunctions * sizeof(*info->functions), GFP_KERNEL);
+
+	info->groups = devm_kzalloc(&pdev->dev,
+			info->ngroups * sizeof(*info->groups) ,	GFP_KERNEL);
+
+	info->banks = devm_kzalloc(&pdev->dev,
+			info->nbanks * sizeof(*info->banks), GFP_KERNEL);
+
+	if (!info->functions || !info->groups || !info->banks)
+		return -ENOMEM;
+
+	info->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (IS_ERR(info->regmap)) {
+		dev_err(info->dev, "No syscfg phandle specified\n");
+		return PTR_ERR(info->regmap);
+	}
+	info->data = of_match_node(st_pctl_of_match, np)->data;
+
+	pctl_desc->npins = info->nbanks * ST_GPIO_PINS_PER_BANK;
+	pdesc =	devm_kzalloc(&pdev->dev,
+			sizeof(*pdesc) * pctl_desc->npins, GFP_KERNEL);
+	if (!pdesc)
+		return -ENOMEM;
+
+	pctl_desc->pins = pdesc;
+
+	bank = 0;
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller")) {
+			const char *bank_name = NULL;
+			ret = st_gpiolib_register_bank(info, bank, child);
+			if (ret)
+				return ret;
+
+			k = info->banks[bank].range.pin_base;
+			bank_name = info->banks[bank].range.name;
+			for (j = 0; j < ST_GPIO_PINS_PER_BANK; j++, k++) {
+				pdesc->number = k;
+				pdesc->name = kasprintf(GFP_KERNEL, "%s[%d]",
+							bank_name, j);
+				pdesc++;
+			}
+			st_parse_syscfgs(info, bank, child);
+			bank++;
+		} else {
+			ret = st_pctl_parse_functions(child, info,
+							i++, &grp_index);
+			if (ret) {
+				dev_err(&pdev->dev, "No functions found.\n");
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int st_pctl_probe(struct platform_device *pdev)
+{
+	struct st_pinctrl *info;
+	struct pinctrl_desc *pctl_desc;
+	int ret, i;
+
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "device node not found.\n");
+		return -EINVAL;
+	}
+
+	pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
+	if (!pctl_desc)
+		return -ENOMEM;
+
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->dev = &pdev->dev;
+	platform_set_drvdata(pdev, info);
+	ret = st_pctl_probe_dt(pdev, pctl_desc, info);
+	if (ret)
+		return ret;
+
+	pctl_desc->owner	= THIS_MODULE,
+	pctl_desc->pctlops	= &st_pctlops,
+	pctl_desc->pmxops	= &st_pmxops,
+	pctl_desc->confops	= &st_confops,
+	pctl_desc->name		= dev_name(&pdev->dev);
+
+	info->pctl = pinctrl_register(pctl_desc, &pdev->dev, info);
+	if (!info->pctl) {
+		dev_err(&pdev->dev, "Failed pinctrl registration\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < info->nbanks; i++)
+		pinctrl_add_gpio_range(info->pctl, &info->banks[i].range);
+
+	return 0;
+}
+
+static struct platform_driver st_pctl_driver = {
+	.driver = {
+		.name = "st-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = st_pctl_of_match,
+	},
+	.probe = st_pctl_probe,
+};
+
+static int __init st_pctl_init(void)
+{
+	return platform_driver_register(&st_pctl_driver);
+}
+arch_initcall(st_pctl_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-sunxi.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-sunxi.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-sunxi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-sunxi.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,10 +13,12 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/pinctrl/pinctrl.h>
@@ -27,1319 +29,7 @@
 
 #include "core.h"
 #include "pinctrl-sunxi.h"
-
-static const struct sunxi_desc_pin sun4i_a10_pins[] = {
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ERXD3 */
-		SUNXI_FUNCTION(0x3, "spi1"),		/* CS0 */
-		SUNXI_FUNCTION(0x4, "uart2")),		/* RTS */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ERXD2 */
-		SUNXI_FUNCTION(0x3, "spi1"),		/* CLK */
-		SUNXI_FUNCTION(0x4, "uart2")),		/* CTS */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ERXD1 */
-		SUNXI_FUNCTION(0x3, "spi1"),		/* MOSI */
-		SUNXI_FUNCTION(0x4, "uart2")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ERXD0 */
-		SUNXI_FUNCTION(0x3, "spi1"),		/* MISO */
-		SUNXI_FUNCTION(0x4, "uart2")),		/* RX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ETXD3 */
-		SUNXI_FUNCTION(0x3, "spi1")),		/* CS1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ETXD2 */
-		SUNXI_FUNCTION(0x3, "spi3")),		/* CS0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ETXD1 */
-		SUNXI_FUNCTION(0x3, "spi3")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ETXD0 */
-		SUNXI_FUNCTION(0x3, "spi3")),		/* MOSI */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ERXCK */
-		SUNXI_FUNCTION(0x3, "spi3")),		/* MISO */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ERXERR */
-		SUNXI_FUNCTION(0x3, "spi3")),		/* CS1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ERXDV */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* EMDC */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* RX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA12,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* EMDIO */
-		SUNXI_FUNCTION(0x3, "uart6"),		/* TX */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* RTS */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA13,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ETXEN */
-		SUNXI_FUNCTION(0x3, "uart6"),		/* RX */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* CTS */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA14,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ETXCK */
-		SUNXI_FUNCTION(0x3, "uart7"),		/* TX */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* DTR */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA15,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ECRS */
-		SUNXI_FUNCTION(0x3, "uart7"),		/* RX */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* DSR */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA16,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ECOL */
-		SUNXI_FUNCTION(0x3, "can"),		/* TX */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* DCD */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA17,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "emac"),		/* ETXERR */
-		SUNXI_FUNCTION(0x3, "can"),		/* RX */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* RING */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c0")),		/* SCK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c0")),		/* SDA */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "pwm")),		/* PWM0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ir0")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ir0")),		/* RX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2s"),		/* MCLK */
-		SUNXI_FUNCTION(0x3, "ac97")),		/* MCLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2s"),		/* BCLK */
-		SUNXI_FUNCTION(0x3, "ac97")),		/* BCLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2s"),		/* LRCK */
-		SUNXI_FUNCTION(0x3, "ac97")),		/* SYNC */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2s"),		/* DO0 */
-		SUNXI_FUNCTION(0x3, "ac97")),		/* DO */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2s")),		/* DO1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2s")),		/* DO2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2s")),		/* DO3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB12,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2s"),		/* DI */
-		SUNXI_FUNCTION(0x3, "ac97")),		/* DI */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB13,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi2")),		/* CS1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB14,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi2"),		/* CS0 */
-		SUNXI_FUNCTION(0x3, "jtag")),		/* MS0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi2"),		/* CLK */
-		SUNXI_FUNCTION(0x3, "jtag")),		/* CK0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi2"),		/* MOSI */
-		SUNXI_FUNCTION(0x3, "jtag")),		/* DO0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi2"),		/* MISO */
-		SUNXI_FUNCTION(0x3, "jtag")),		/* DI0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c1")),		/* SCK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB19,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c1")),		/* SDA */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB20,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c2")),		/* SCK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB21,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c2")),		/* SDA */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB22,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "uart0"),		/* TX */
-		SUNXI_FUNCTION(0x3, "ir1")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB23,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "uart0"),		/* RX */
-		SUNXI_FUNCTION(0x3, "ir1")),		/* RX */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NWE */
-		SUNXI_FUNCTION(0x3, "spi0")),		/* MOSI */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NALE */
-		SUNXI_FUNCTION(0x3, "spi0")),		/* MISO */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NCLE */
-		SUNXI_FUNCTION(0x3, "spi0")),		/* SCK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NCE1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NCE0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),	/* NRE# */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NRB0 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* CMD */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NRB1 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ0 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ1 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ2 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ3 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NDQ4 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NDQ5 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NDQ6 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NDQ7 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC16,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NWP */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC17,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NCE2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC18,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NCE3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NCE4 */
-		SUNXI_FUNCTION(0x3, "spi2")),		/* CS0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC20,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NCE5 */
-		SUNXI_FUNCTION(0x3, "spi2")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC21,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NCE6 */
-		SUNXI_FUNCTION(0x3, "spi2")),		/* MOSI */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC22,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NCE7 */
-		SUNXI_FUNCTION(0x3, "spi2")),		/* MISO */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC23,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "spi0")),		/* CS0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC24,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NDQS */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D0 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VP0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D1 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VN0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D2 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VP1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D3 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VN1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D4 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VP2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D5 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VN2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D6 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VPC */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D7 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VNC */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D8 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VP3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D9 */
-		SUNXI_FUNCTION(0x3, "lvds0")),		/* VM3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D10 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VP0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D11 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VN0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D12 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VP1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D13 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VN1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D14 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VP2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D15 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VN2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD16,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D16 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VPC */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD17,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D17 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VNC */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D18 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VP3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D19 */
-		SUNXI_FUNCTION(0x3, "lvds1")),		/* VN3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D20 */
-		SUNXI_FUNCTION(0x3, "csi1")),		/* MCLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D21 */
-		SUNXI_FUNCTION(0x3, "sim")),		/* VPPEN */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D22 */
-		SUNXI_FUNCTION(0x3, "sim")),		/* VPPPP */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* D23 */
-		SUNXI_FUNCTION(0x3, "sim")),		/* DET */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* CLK */
-		SUNXI_FUNCTION(0x3, "sim")),		/* VCCEN */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* DE */
-		SUNXI_FUNCTION(0x3, "sim")),		/* RST */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* HSYNC */
-		SUNXI_FUNCTION(0x3, "sim")),		/* SCK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0"),		/* VSYNC */
-		SUNXI_FUNCTION(0x3, "sim")),		/* SDA */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* CLK */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* PCK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* ERR */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* CK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* SYNC */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* HSYNC */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* DVLD */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* VSYNC */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* D0 */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* D0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* D1 */
-		SUNXI_FUNCTION(0x3, "csi0"),		/* D1 */
-		SUNXI_FUNCTION(0x4, "sim")),		/* VPPEN */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* D2 */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* D2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* D3 */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* D3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* D4 */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* D4 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* D5 */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* D5 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* D6 */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* D6 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts0"),		/* D7 */
-		SUNXI_FUNCTION(0x3, "csi0")),		/* D7 */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc0"),		/* D1 */
-		SUNXI_FUNCTION(0x4, "jtag")),		/* MSI */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc0"),		/* D0 */
-		SUNXI_FUNCTION(0x4, "jtag")),		/* DI1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc0"),		/* CLK */
-		SUNXI_FUNCTION(0x4, "uart0")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc0"),		/* CMD */
-		SUNXI_FUNCTION(0x4, "jtag")),		/* DO1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc0"),		/* D3 */
-		SUNXI_FUNCTION(0x4, "uart0")),		/* RX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc0"),		/* D2 */
-		SUNXI_FUNCTION(0x4, "jtag")),		/* CK1 */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* CLK */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* PCK */
-		SUNXI_FUNCTION(0x4, "mmc1")),		/* CMD */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* ERR */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* CK */
-		SUNXI_FUNCTION(0x4, "mmc1")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* SYNC */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* HSYNC */
-		SUNXI_FUNCTION(0x4, "mmc1")),		/* D0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* DVLD */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* VSYNC */
-		SUNXI_FUNCTION(0x4, "mmc1")),		/* D1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* D0 */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* D0 */
-		SUNXI_FUNCTION(0x4, "mmc1"),		/* D2 */
-		SUNXI_FUNCTION(0x5, "csi0")),		/* D8 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* D1 */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* D1 */
-		SUNXI_FUNCTION(0x4, "mmc1"),		/* D3 */
-		SUNXI_FUNCTION(0x5, "csi0")),		/* D9 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* D2 */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* D2 */
-		SUNXI_FUNCTION(0x4, "uart3"),		/* TX */
-		SUNXI_FUNCTION(0x5, "csi0")),		/* D10 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* D3 */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* D3 */
-		SUNXI_FUNCTION(0x4, "uart3"),		/* RX */
-		SUNXI_FUNCTION(0x5, "csi0")),		/* D11 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* D4 */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* D4 */
-		SUNXI_FUNCTION(0x4, "uart3"),		/* RTS */
-		SUNXI_FUNCTION(0x5, "csi0")),		/* D12 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* D5 */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* D5 */
-		SUNXI_FUNCTION(0x4, "uart3"),		/* CTS */
-		SUNXI_FUNCTION(0x5, "csi0")),		/* D13 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* D6 */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* D6 */
-		SUNXI_FUNCTION(0x4, "uart4"),		/* TX */
-		SUNXI_FUNCTION(0x5, "csi0")),		/* D14 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ts1"),		/* D7 */
-		SUNXI_FUNCTION(0x3, "csi1"),		/* D7 */
-		SUNXI_FUNCTION(0x4, "uart4"),		/* RX */
-		SUNXI_FUNCTION(0x5, "csi0")),		/* D15 */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D0 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAA0 */
-		SUNXI_FUNCTION(0x4, "uart3"),		/* TX */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D1 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAA1 */
-		SUNXI_FUNCTION(0x4, "uart3"),		/* RX */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D2 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAA2 */
-		SUNXI_FUNCTION(0x4, "uart3"),		/* RTS */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D3 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAIRQ */
-		SUNXI_FUNCTION(0x4, "uart3"),		/* CTS */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D4 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD0 */
-		SUNXI_FUNCTION(0x4, "uart4"),		/* TX */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D4 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D5 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD1 */
-		SUNXI_FUNCTION(0x4, "uart4"),		/* RX */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D5 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D6 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD2 */
-		SUNXI_FUNCTION(0x4, "uart5"),		/* TX */
-		SUNXI_FUNCTION(0x5, "ms"),		/* BS */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D6 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D7 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD3 */
-		SUNXI_FUNCTION(0x4, "uart5"),		/* RX */
-		SUNXI_FUNCTION(0x5, "ms"),		/* CLK */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D7 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D8 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD4 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* IN0 */
-		SUNXI_FUNCTION(0x5, "ms"),		/* D0 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D8 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D9 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD5 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* IN1 */
-		SUNXI_FUNCTION(0x5, "ms"),		/* D1 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D9 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D10 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD6 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* IN2 */
-		SUNXI_FUNCTION(0x5, "ms"),		/* D2 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D10 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D11 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD7 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* IN3 */
-		SUNXI_FUNCTION(0x5, "ms"),		/* D3 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D11 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH12,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D12 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD8 */
-		SUNXI_FUNCTION(0x4, "ps2"),		/* SCK1 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D12 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH13,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D13 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD9 */
-		SUNXI_FUNCTION(0x4, "ps2"),		/* SDA1 */
-		SUNXI_FUNCTION(0x5, "sim"),		/* RST */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D13 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH14,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D14 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD10 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* IN4 */
-		SUNXI_FUNCTION(0x5, "sim"),		/* VPPEN */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D14 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH15,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D15 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD11 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* IN5 */
-		SUNXI_FUNCTION(0x5, "sim"),		/* VPPPP */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D15 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH16,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D16 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD12 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* IN6 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D16 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH17,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D17 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD13 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* IN7 */
-		SUNXI_FUNCTION(0x5, "sim"),		/* VCCEN */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D17 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH18,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D18 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD14 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* OUT0 */
-		SUNXI_FUNCTION(0x5, "sim"),		/* SCK */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D18 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH19,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D19 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAD15 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* OUT1 */
-		SUNXI_FUNCTION(0x5, "sim"),		/* SDA */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D19 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH20,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D20 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAOE */
-		SUNXI_FUNCTION(0x4, "can"),		/* TX */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D20 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH21,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D21 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATADREQ */
-		SUNXI_FUNCTION(0x4, "can"),		/* RX */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D21 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH22,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D22 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATADACK */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* OUT2 */
-		SUNXI_FUNCTION(0x5, "mmc1"),		/* CMD */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D22 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH23,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* D23 */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATACS0 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* OUT3 */
-		SUNXI_FUNCTION(0x5, "mmc1"),		/* CLK */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* D23 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH24,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* CLK */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATACS1 */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* OUT4 */
-		SUNXI_FUNCTION(0x5, "mmc1"),		/* D0 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* PCLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH25,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* DE */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAIORDY */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* OUT5 */
-		SUNXI_FUNCTION(0x5, "mmc1"),		/* D1 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* FIELD */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH26,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* HSYNC */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAIOR */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* OUT6 */
-		SUNXI_FUNCTION(0x5, "mmc1"),		/* D2 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* HSYNC */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH27,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd1"),		/* VSYNC */
-		SUNXI_FUNCTION(0x3, "pata"),		/* ATAIOW */
-		SUNXI_FUNCTION(0x4, "keypad"),		/* OUT7 */
-		SUNXI_FUNCTION(0x5, "mmc1"),		/* D3 */
-		SUNXI_FUNCTION(0x7, "csi1")),		/* VSYNC */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out")),
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out")),
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out")),
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "pwm")),		/* PWM1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc3")),		/* CMD */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc3")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc3")),		/* D0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc3")),		/* D1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc3")),		/* D2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc3")),		/* D3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi0"),		/* CS0 */
-		SUNXI_FUNCTION(0x3, "uart5")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi0"),		/* CLK */
-		SUNXI_FUNCTION(0x3, "uart5")),		/* RX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI12,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi0"),		/* MOSI */
-		SUNXI_FUNCTION(0x3, "uart6")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI13,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi0"),		/* MISO */
-		SUNXI_FUNCTION(0x3, "uart6")),		/* RX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI14,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi0"),		/* CS1 */
-		SUNXI_FUNCTION(0x3, "ps2"),		/* SCK1 */
-		SUNXI_FUNCTION(0x4, "timer4")),		/* TCLKIN0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI15,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi1"),		/* CS1 */
-		SUNXI_FUNCTION(0x3, "ps2"),		/* SDA1 */
-		SUNXI_FUNCTION(0x4, "timer5")),		/* TCLKIN1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI16,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi1"),		/* CS0 */
-		SUNXI_FUNCTION(0x3, "uart2")),		/* RTS */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI17,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi1"),		/* CLK */
-		SUNXI_FUNCTION(0x3, "uart2")),		/* CTS */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI18,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi1"),		/* MOSI */
-		SUNXI_FUNCTION(0x3, "uart2")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI19,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi1"),		/* MISO */
-		SUNXI_FUNCTION(0x3, "uart2")),		/* RX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI20,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ps2"),		/* SCK0 */
-		SUNXI_FUNCTION(0x3, "uart7"),		/* TX */
-		SUNXI_FUNCTION(0x4, "hdmi")),		/* HSCL */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI21,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ps2"),		/* SDA0 */
-		SUNXI_FUNCTION(0x3, "uart7"),		/* RX */
-		SUNXI_FUNCTION(0x4, "hdmi")),		/* HSDA */
-};
-
-static const struct sunxi_desc_pin sun5i_a13_pins[] = {
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c0")),		/* SCK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c0")),		/* SDA */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "pwm")),
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ir0")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "ir0")),		/* RX */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi2")),		/* CS1 */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c1")),		/* SCK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c1")),		/* SDA */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c2")),		/* SCK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "i2c2")),		/* SDA */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NWE */
-		SUNXI_FUNCTION(0x3, "spi0")),		/* MOSI */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NALE */
-		SUNXI_FUNCTION(0x3, "spi0")),		/* MISO */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NCLE */
-		SUNXI_FUNCTION(0x3, "spi0")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NCE1 */
-		SUNXI_FUNCTION(0x3, "spi0")),		/* CS0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NCE0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0")),		/* NRE */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NRB0 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* CMD */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NRB1 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ0 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ1 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ2 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ3 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ4 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D4 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ5 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D5 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ6 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D6 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ7 */
-		SUNXI_FUNCTION(0x3, "mmc2")),		/* D7 */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "nand0"),		/* NDQS */
-		SUNXI_FUNCTION(0x4, "uart3")),		/* RTS */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D4 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D5 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D6 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D7 */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D10 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D11 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D12 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D13 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D14 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D15 */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D18 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D19 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D20 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D21 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D22 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* D23 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* DE */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* HSYNC */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "lcd0")),		/* VSYNC */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* PCLK */
-		SUNXI_FUNCTION(0x4, "spi2")),		/* CS0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* MCLK */
-		SUNXI_FUNCTION(0x4, "spi2")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* HSYNC */
-		SUNXI_FUNCTION(0x4, "spi2")),		/* MOSI */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* VSYNC */
-		SUNXI_FUNCTION(0x4, "spi2")),		/* MISO */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* D0 */
-		SUNXI_FUNCTION(0x4, "mmc2")),		/* D0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* D1 */
-		SUNXI_FUNCTION(0x4, "mmc2")),		/* D1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* D2 */
-		SUNXI_FUNCTION(0x4, "mmc2")),		/* D2 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* D3 */
-		SUNXI_FUNCTION(0x4, "mmc2")),		/* D3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* D4 */
-		SUNXI_FUNCTION(0x4, "mmc2")),		/* CMD */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* D5 */
-		SUNXI_FUNCTION(0x4, "mmc2")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* D6 */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x3, "csi0"),		/* D7 */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* RX */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x4, "mmc0")),		/* D1 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x4, "mmc0")),		/* D0 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x4, "mmc0")),		/* CLK */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x4, "mmc0")),		/* CMD */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x4, "mmc0")),		/* D3 */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x4, "mmc0")),		/* D2 */
-	/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out")),
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out")),
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out")),
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc1"),		/* CMD */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "mmc1"),		/* CLK */
-		SUNXI_FUNCTION(0x4, "uart1")),		/* RX */
-/* Hole */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi1"),		/* CS0 */
-		SUNXI_FUNCTION(0x3, "uart3")),		/* TX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi1"),		/* CLK */
-		SUNXI_FUNCTION(0x3, "uart3")),		/* RX */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi1"),		/* MOSI */
-		SUNXI_FUNCTION(0x3, "uart3")),		/* CTS */
-	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG12,
-		SUNXI_FUNCTION(0x0, "gpio_in"),
-		SUNXI_FUNCTION(0x1, "gpio_out"),
-		SUNXI_FUNCTION(0x2, "spi1"),		/* MISO */
-		SUNXI_FUNCTION(0x3, "uart3")),		/* RTS */
-};
-
-static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = {
-	.pins = sun4i_a10_pins,
-	.npins = ARRAY_SIZE(sun4i_a10_pins),
-};
-
-static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = {
-	.pins = sun5i_a13_pins,
-	.npins = ARRAY_SIZE(sun5i_a13_pins),
-};
+#include "pinctrl-sunxi-pins.h"
 
 static struct sunxi_pinctrl_group *
 sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
@@ -1399,6 +89,31 @@ sunxi_pinctrl_desc_find_function_by_name
 	return NULL;
 }
 
+static struct sunxi_desc_function *
+sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl,
+					const u16 pin_num,
+					const char *func_name)
+{
+	int i;
+
+	for (i = 0; i < pctl->desc->npins; i++) {
+		const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
+
+		if (pin->pin.number == pin_num) {
+			struct sunxi_desc_function *func = pin->functions;
+
+			while (func->name) {
+				if (!strcmp(func->name, func_name))
+					return func;
+
+				func++;
+			}
+		}
+	}
+
+	return NULL;
+}
+
 static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
 {
 	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
@@ -1563,6 +278,7 @@ static int sunxi_pconf_group_set(struct
 {
 	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct sunxi_pinctrl_group *g = &pctl->groups[group];
+	unsigned long flags;
 	u32 val, mask;
 	u16 strength;
 	u8 dlevel;
@@ -1580,22 +296,35 @@ static int sunxi_pconf_group_set(struct
 		 *   3: 40mA
 		 */
 		dlevel = strength / 10 - 1;
+
+		spin_lock_irqsave(&pctl->lock, flags);
+
 		val = readl(pctl->membase + sunxi_dlevel_reg(g->pin));
 	        mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin);
 		writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin),
 			pctl->membase + sunxi_dlevel_reg(g->pin));
+
+		spin_unlock_irqrestore(&pctl->lock, flags);
 		break;
 	case PIN_CONFIG_BIAS_PULL_UP:
+		spin_lock_irqsave(&pctl->lock, flags);
+
 		val = readl(pctl->membase + sunxi_pull_reg(g->pin));
 		mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
 		writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin),
 			pctl->membase + sunxi_pull_reg(g->pin));
+
+		spin_unlock_irqrestore(&pctl->lock, flags);
 		break;
 	case PIN_CONFIG_BIAS_PULL_DOWN:
+		spin_lock_irqsave(&pctl->lock, flags);
+
 		val = readl(pctl->membase + sunxi_pull_reg(g->pin));
 		mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
 		writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin),
 			pctl->membase + sunxi_pull_reg(g->pin));
+
+		spin_unlock_irqrestore(&pctl->lock, flags);
 		break;
 	default:
 		break;
@@ -1645,11 +374,17 @@ static void sunxi_pmx_set(struct pinctrl
 				 u8 config)
 {
 	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long flags;
+	u32 val, mask;
 
-	u32 val = readl(pctl->membase + sunxi_mux_reg(pin));
-	u32 mask = MUX_PINS_MASK << sunxi_mux_offset(pin);
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	val = readl(pctl->membase + sunxi_mux_reg(pin));
+	mask = MUX_PINS_MASK << sunxi_mux_offset(pin);
 	writel((val & ~mask) | config << sunxi_mux_offset(pin),
 		pctl->membase + sunxi_mux_reg(pin));
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
 }
 
 static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
@@ -1680,37 +415,20 @@ sunxi_pmx_gpio_set_direction(struct pinc
 {
 	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct sunxi_desc_function *desc;
-	char pin_name[SUNXI_PIN_NAME_MAX_LEN];
 	const char *func;
-	u8 bank, pin;
-	int ret;
-
-	bank = (offset) / PINS_PER_BANK;
-	pin = (offset) % PINS_PER_BANK;
-
-	ret = sprintf(pin_name, "P%c%d", 'A' + bank, pin);
-	if (!ret)
-		goto error;
 
 	if (input)
 		func = "gpio_in";
 	else
 		func = "gpio_out";
 
-	desc = sunxi_pinctrl_desc_find_function_by_name(pctl,
-							pin_name,
-							func);
-	if (!desc) {
-		ret = -EINVAL;
-		goto error;
-	}
+	desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, func);
+	if (!desc)
+		return -EINVAL;
 
 	sunxi_pmx_set(pctldev, offset, desc->muxval);
 
-	ret = 0;
-
-error:
-	return ret;
+	return 0;
 }
 
 static const struct pinmux_ops sunxi_pmx_ops = {
@@ -1766,8 +484,21 @@ static void sunxi_pinctrl_gpio_set(struc
 	struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
 	u32 reg = sunxi_data_reg(offset);
 	u8 index = sunxi_data_offset(offset);
+	unsigned long flags;
+	u32 regval;
 
-	writel((value & DATA_PINS_MASK) << index, pctl->membase + reg);
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	regval = readl(pctl->membase + reg);
+
+	if (value)
+		regval |= BIT(index);
+	else
+		regval &= ~(BIT(index));
+
+	writel(regval, pctl->membase + reg);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
 }
 
 static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
@@ -1788,6 +519,26 @@ static int sunxi_pinctrl_gpio_of_xlate(s
 	return pin;
 }
 
+static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct sunxi_pinctrl *pctl = dev_get_drvdata(chip->dev);
+	struct sunxi_desc_function *desc;
+
+	if (offset > chip->ngpio)
+		return -ENXIO;
+
+	desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, "irq");
+	if (!desc)
+		return -EINVAL;
+
+	pctl->irq_array[desc->irqnum] = offset;
+
+	dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
+		chip->label, offset + chip->base, desc->irqnum);
+
+	return irq_find_mapping(pctl->domain, desc->irqnum);
+}
+
 static struct gpio_chip sunxi_pinctrl_gpio_chip = {
 	.owner			= THIS_MODULE,
 	.request		= sunxi_pinctrl_gpio_request,
@@ -1797,12 +548,144 @@ static struct gpio_chip sunxi_pinctrl_gp
 	.get			= sunxi_pinctrl_gpio_get,
 	.set			= sunxi_pinctrl_gpio_set,
 	.of_xlate		= sunxi_pinctrl_gpio_of_xlate,
+	.to_irq			= sunxi_pinctrl_gpio_to_irq,
 	.of_gpio_n_cells	= 3,
 	.can_sleep		= 0,
 };
 
+static int sunxi_pinctrl_irq_set_type(struct irq_data *d,
+				      unsigned int type)
+{
+	struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+	u32 reg = sunxi_irq_cfg_reg(d->hwirq);
+	u8 index = sunxi_irq_cfg_offset(d->hwirq);
+	unsigned long flags;
+	u32 regval;
+	u8 mode;
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		mode = IRQ_EDGE_RISING;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		mode = IRQ_EDGE_FALLING;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		mode = IRQ_EDGE_BOTH;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		mode = IRQ_LEVEL_HIGH;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		mode = IRQ_LEVEL_LOW;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	regval = readl(pctl->membase + reg);
+	regval &= ~IRQ_CFG_IRQ_MASK;
+	writel(regval | (mode << index), pctl->membase + reg);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+
+	return 0;
+}
+
+static void sunxi_pinctrl_irq_mask_ack(struct irq_data *d)
+{
+	struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+	u32 ctrl_reg = sunxi_irq_ctrl_reg(d->hwirq);
+	u8 ctrl_idx = sunxi_irq_ctrl_offset(d->hwirq);
+	u32 status_reg = sunxi_irq_status_reg(d->hwirq);
+	u8 status_idx = sunxi_irq_status_offset(d->hwirq);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	/* Mask the IRQ */
+	val = readl(pctl->membase + ctrl_reg);
+	writel(val & ~(1 << ctrl_idx), pctl->membase + ctrl_reg);
+
+	/* Clear the IRQ */
+	writel(1 << status_idx, pctl->membase + status_reg);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+}
+
+static void sunxi_pinctrl_irq_mask(struct irq_data *d)
+{
+	struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+	u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
+	u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	/* Mask the IRQ */
+	val = readl(pctl->membase + reg);
+	writel(val & ~(1 << idx), pctl->membase + reg);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+}
+
+static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
+{
+	struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+	struct sunxi_desc_function *func;
+	u32 reg = sunxi_irq_ctrl_reg(d->hwirq);
+	u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
+	unsigned long flags;
+	u32 val;
+
+	func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
+						       pctl->irq_array[d->hwirq],
+						       "irq");
+
+	/* Change muxing to INT mode */
+	sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
+
+	spin_lock_irqsave(&pctl->lock, flags);
+
+	/* Unmask the IRQ */
+	val = readl(pctl->membase + reg);
+	writel(val | (1 << idx), pctl->membase + reg);
+
+	spin_unlock_irqrestore(&pctl->lock, flags);
+}
+
+static struct irq_chip sunxi_pinctrl_irq_chip = {
+	.irq_mask	= sunxi_pinctrl_irq_mask,
+	.irq_mask_ack	= sunxi_pinctrl_irq_mask_ack,
+	.irq_unmask	= sunxi_pinctrl_irq_unmask,
+	.irq_set_type	= sunxi_pinctrl_irq_set_type,
+};
+
+static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+	struct sunxi_pinctrl *pctl = irq_get_handler_data(irq);
+	const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG);
+
+	/* Clear all interrupts */
+	writel(reg, pctl->membase + IRQ_STATUS_REG);
+
+	if (reg) {
+		int irqoffset;
+
+		for_each_set_bit(irqoffset, &reg, SUNXI_IRQ_NUMBER) {
+			int pin_irq = irq_find_mapping(pctl->domain, irqoffset);
+			generic_handle_irq(pin_irq);
+		}
+	}
+}
+
 static struct of_device_id sunxi_pinctrl_match[] = {
 	{ .compatible = "allwinner,sun4i-a10-pinctrl", .data = (void *)&sun4i_a10_pinctrl_data },
+	{ .compatible = "allwinner,sun5i-a10s-pinctrl", .data = (void *)&sun5i_a10s_pinctrl_data },
 	{ .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data },
 	{}
 };
@@ -1925,6 +808,8 @@ static int sunxi_pinctrl_probe(struct pl
 		return -ENOMEM;
 	platform_set_drvdata(pdev, pctl);
 
+	spin_lock_init(&pctl->lock);
+
 	pctl->membase = of_iomap(node, 0);
 	if (!pctl->membase)
 		return -ENOMEM;
@@ -1997,6 +882,31 @@ static int sunxi_pinctrl_probe(struct pl
 
 	clk_prepare_enable(clk);
 
+	pctl->irq = irq_of_parse_and_map(node, 0);
+	if (!pctl->irq) {
+		ret = -EINVAL;
+		goto gpiochip_error;
+	}
+
+	pctl->domain = irq_domain_add_linear(node, SUNXI_IRQ_NUMBER,
+					     &irq_domain_simple_ops, NULL);
+	if (!pctl->domain) {
+		dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
+		ret = -ENOMEM;
+		goto gpiochip_error;
+	}
+
+	for (i = 0; i < SUNXI_IRQ_NUMBER; i++) {
+		int irqno = irq_create_mapping(pctl->domain, i);
+
+		irq_set_chip_and_handler(irqno, &sunxi_pinctrl_irq_chip,
+					 handle_simple_irq);
+		irq_set_chip_data(irqno, pctl);
+	};
+
+	irq_set_chained_handler(pctl->irq, sunxi_pinctrl_irq_handler);
+	irq_set_handler_data(pctl->irq, pctl);
+
 	dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-sunxi.h linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-sunxi.h
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-sunxi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-sunxi.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@
 #define __PINCTRL_SUNXI_H
 
 #include <linux/kernel.h>
+#include <linux/spinlock.h>
 
 #define PA_BASE	0
 #define PB_BASE	32
@@ -344,9 +345,31 @@
 #define PULL_PINS_BITS		2
 #define PULL_PINS_MASK		0x03
 
+#define SUNXI_IRQ_NUMBER	32
+
+#define IRQ_CFG_REG		0x200
+#define IRQ_CFG_IRQ_PER_REG		8
+#define IRQ_CFG_IRQ_BITS		4
+#define IRQ_CFG_IRQ_MASK		((1 << IRQ_CFG_IRQ_BITS) - 1)
+#define IRQ_CTRL_REG		0x210
+#define IRQ_CTRL_IRQ_PER_REG		32
+#define IRQ_CTRL_IRQ_BITS		1
+#define IRQ_CTRL_IRQ_MASK		((1 << IRQ_CTRL_IRQ_BITS) - 1)
+#define IRQ_STATUS_REG		0x214
+#define IRQ_STATUS_IRQ_PER_REG		32
+#define IRQ_STATUS_IRQ_BITS		1
+#define IRQ_STATUS_IRQ_MASK		((1 << IRQ_STATUS_IRQ_BITS) - 1)
+
+#define IRQ_EDGE_RISING		0x00
+#define IRQ_EDGE_FALLING	0x01
+#define IRQ_LEVEL_HIGH		0x02
+#define IRQ_LEVEL_LOW		0x03
+#define IRQ_EDGE_BOTH		0x04
+
 struct sunxi_desc_function {
 	const char	*name;
 	u8		muxval;
+	u8		irqnum;
 };
 
 struct sunxi_desc_pin {
@@ -378,10 +401,14 @@ struct sunxi_pinctrl {
 	struct gpio_chip		*chip;
 	struct sunxi_pinctrl_desc	*desc;
 	struct device			*dev;
+	struct irq_domain		*domain;
 	struct sunxi_pinctrl_function	*functions;
 	unsigned			nfunctions;
 	struct sunxi_pinctrl_group	*groups;
 	unsigned			ngroups;
+	int				irq;
+	int				irq_array[SUNXI_IRQ_NUMBER];
+	spinlock_t			lock;
 	struct pinctrl_dev		*pctl_dev;
 };
 
@@ -398,6 +425,13 @@ struct sunxi_pinctrl {
 		.muxval = _val,					\
 	}
 
+#define SUNXI_FUNCTION_IRQ(_val, _irq)				\
+	{							\
+		.name = "irq",					\
+		.muxval = _val,					\
+		.irqnum = _irq,					\
+	}
+
 /*
  * The sunXi PIO registers are organized as is:
  * 0x00 - 0x0c	Muxing values.
@@ -475,4 +509,40 @@ static inline u32 sunxi_pull_offset(u16
 	return pin_num * PULL_PINS_BITS;
 }
 
+static inline u32 sunxi_irq_cfg_reg(u16 irq)
+{
+	u8 reg = irq / IRQ_CFG_IRQ_PER_REG;
+	return reg + IRQ_CFG_REG;
+}
+
+static inline u32 sunxi_irq_cfg_offset(u16 irq)
+{
+	u32 irq_num = irq % IRQ_CFG_IRQ_PER_REG;
+	return irq_num * IRQ_CFG_IRQ_BITS;
+}
+
+static inline u32 sunxi_irq_ctrl_reg(u16 irq)
+{
+	u8 reg = irq / IRQ_CTRL_IRQ_PER_REG;
+	return reg + IRQ_CTRL_REG;
+}
+
+static inline u32 sunxi_irq_ctrl_offset(u16 irq)
+{
+	u32 irq_num = irq % IRQ_CTRL_IRQ_PER_REG;
+	return irq_num * IRQ_CTRL_IRQ_BITS;
+}
+
+static inline u32 sunxi_irq_status_reg(u16 irq)
+{
+	u8 reg = irq / IRQ_STATUS_IRQ_PER_REG;
+	return reg + IRQ_STATUS_REG;
+}
+
+static inline u32 sunxi_irq_status_offset(u16 irq)
+{
+	u32 irq_num = irq % IRQ_STATUS_IRQ_PER_REG;
+	return irq_num * IRQ_STATUS_IRQ_BITS;
+}
+
 #endif /* __PINCTRL_SUNXI_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-sunxi-pins.h linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-sunxi-pins.h
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-sunxi-pins.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-sunxi-pins.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2023 @@
+/*
+ * Allwinner A1X SoCs pinctrl driver.
+ *
+ * Copyright (C) 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PINCTRL_SUNXI_PINS_H
+#define __PINCTRL_SUNXI_PINS_H
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun4i_a10_pins[] = {
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXD3 */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* CS0 */
+		  SUNXI_FUNCTION(0x4, "uart2")),	/* RTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXD2 */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* CLK */
+		  SUNXI_FUNCTION(0x4, "uart2")),	/* CTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXD1 */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* MOSI */
+		  SUNXI_FUNCTION(0x4, "uart2")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXD0 */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* MISO */
+		  SUNXI_FUNCTION(0x4, "uart2")),	/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXD3 */
+		  SUNXI_FUNCTION(0x3, "spi1")),		/* CS1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXD2 */
+		  SUNXI_FUNCTION(0x3, "spi3")),		/* CS0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXD1 */
+		  SUNXI_FUNCTION(0x3, "spi3")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXD0 */
+		  SUNXI_FUNCTION(0x3, "spi3")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXCK */
+		  SUNXI_FUNCTION(0x3, "spi3")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXERR */
+		  SUNXI_FUNCTION(0x3, "spi3")),		/* CS1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXDV */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* EMDC */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* EMDIO */
+		  SUNXI_FUNCTION(0x3, "uart6"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* RTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXEN */
+		  SUNXI_FUNCTION(0x3, "uart6"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* CTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXCK */
+		  SUNXI_FUNCTION(0x3, "uart7"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* DTR */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ECRS */
+		  SUNXI_FUNCTION(0x3, "uart7"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* DSR */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ECOL */
+		  SUNXI_FUNCTION(0x3, "can"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* DCD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXERR */
+		  SUNXI_FUNCTION(0x3, "can"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* RING */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "pwm")),		/* PWM0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir0")),		/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir0")),		/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* MCLK */
+		  SUNXI_FUNCTION(0x3, "ac97")),		/* MCLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* BCLK */
+		  SUNXI_FUNCTION(0x3, "ac97")),		/* BCLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* LRCK */
+		  SUNXI_FUNCTION(0x3, "ac97")),		/* SYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* DO0 */
+		  SUNXI_FUNCTION(0x3, "ac97")),		/* DO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s")),		/* DO1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s")),		/* DO2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s")),		/* DO3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* DI */
+		  SUNXI_FUNCTION(0x3, "ac97")),		/* DI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2")),		/* CS1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* CS0 */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* MS0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* CK0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* MOSI */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* DO0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* MISO */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* DI0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB20,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c2")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB21,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c2")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB22,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart0"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "ir1")),		/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB23,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart0"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "ir1")),		/* RX */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NWE */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NALE */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCLE */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NCE1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NCE0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NRE# */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NRB0 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* CMD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NRB1 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ0 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ1 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ2 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ3 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NDQ4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NDQ5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NDQ6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NDQ7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NWP */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NCE2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NCE3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE4 */
+		  SUNXI_FUNCTION(0x3, "spi2")),		/* CS0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC20,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE5 */
+		  SUNXI_FUNCTION(0x3, "spi2")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC21,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE6 */
+		  SUNXI_FUNCTION(0x3, "spi2")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC22,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE7 */
+		  SUNXI_FUNCTION(0x3, "spi2")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC23,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* CS0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC24,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NDQS */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D0 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VP0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D1 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VN0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VP1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D3 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VN1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D4 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VP2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D5 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VN2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D6 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VPC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D7 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D8 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VP3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D9 */
+		  SUNXI_FUNCTION(0x3, "lvds0")),	/* VM3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D10 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VP0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D11 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VN0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D12 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VP1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D13 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VN1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D14 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VP2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D15 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VN2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D16 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VPC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D17 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D18 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VP3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D19 */
+		  SUNXI_FUNCTION(0x3, "lvds1")),	/* VN3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D20 */
+		  SUNXI_FUNCTION(0x3, "csi1")),		/* MCLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D21 */
+		  SUNXI_FUNCTION(0x3, "sim")),		/* VPPEN */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D22 */
+		  SUNXI_FUNCTION(0x3, "sim")),		/* VPPPP */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D23 */
+		  SUNXI_FUNCTION(0x3, "sim")),		/* DET */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "sim")),		/* VCCEN */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* DE */
+		  SUNXI_FUNCTION(0x3, "sim")),		/* RST */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* HSYNC */
+		  SUNXI_FUNCTION(0x3, "sim")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* VSYNC */
+		  SUNXI_FUNCTION(0x3, "sim")),		/* SDA */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* PCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* ERR */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* CK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* SYNC */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* HSYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* DVLD */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* VSYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D0 */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D1 */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "sim")),		/* VPPEN */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D3 */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D4 */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* D4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D5 */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* D5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D6 */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* D6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D7 */
+		  SUNXI_FUNCTION(0x3, "csi0")),		/* D7 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "jtag")),		/* MSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D0 */
+		  SUNXI_FUNCTION(0x4, "jtag")),		/* DI1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CLK */
+		  SUNXI_FUNCTION(0x4, "uart0")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CMD */
+		  SUNXI_FUNCTION(0x4, "jtag")),		/* DO1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D3 */
+		  SUNXI_FUNCTION(0x4, "uart0")),	/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D2 */
+		  SUNXI_FUNCTION(0x4, "jtag")),		/* CK1 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* PCK */
+		  SUNXI_FUNCTION(0x4, "mmc1")),		/* CMD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* ERR */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* CK */
+		  SUNXI_FUNCTION(0x4, "mmc1")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* SYNC */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* HSYNC */
+		  SUNXI_FUNCTION(0x4, "mmc1")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* DVLD */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* VSYNC */
+		  SUNXI_FUNCTION(0x4, "mmc1")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* D0 */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* D0 */
+		  SUNXI_FUNCTION(0x4, "mmc1"),		/* D2 */
+		  SUNXI_FUNCTION(0x5, "csi0")),		/* D8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* D1 */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "mmc1"),		/* D3 */
+		  SUNXI_FUNCTION(0x5, "csi0")),		/* D9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* D2 */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* TX */
+		  SUNXI_FUNCTION(0x5, "csi0")),		/* D10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* D3 */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* D3 */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* RX */
+		  SUNXI_FUNCTION(0x5, "csi0")),		/* D11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* D4 */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* D4 */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* RTS */
+		  SUNXI_FUNCTION(0x5, "csi0")),		/* D12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* D5 */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* D5 */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* CTS */
+		  SUNXI_FUNCTION(0x5, "csi0")),		/* D13 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* D6 */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* D6 */
+		  SUNXI_FUNCTION(0x4, "uart4"),		/* TX */
+		  SUNXI_FUNCTION(0x5, "csi0")),		/* D14 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts1"),		/* D7 */
+		  SUNXI_FUNCTION(0x3, "csi1"),		/* D7 */
+		  SUNXI_FUNCTION(0x4, "uart4"),		/* RX */
+		  SUNXI_FUNCTION(0x5, "csi0")),		/* D15 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D0 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAA0 */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 0),		/* EINT0 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D1 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAA1 */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 1),		/* EINT1 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAA2 */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* RTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 2),		/* EINT2 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D3 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAIRQ */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* CTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 3),		/* EINT3 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D4 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD0 */
+		  SUNXI_FUNCTION(0x4, "uart4"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 4),		/* EINT4 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D5 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD1 */
+		  SUNXI_FUNCTION(0x4, "uart4"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 5),		/* EINT5 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D6 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD2 */
+		  SUNXI_FUNCTION(0x4, "uart5"),		/* TX */
+		  SUNXI_FUNCTION(0x5, "ms"),		/* BS */
+		  SUNXI_FUNCTION_IRQ(0x6, 6),		/* EINT6 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D7 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD3 */
+		  SUNXI_FUNCTION(0x4, "uart5"),		/* RX */
+		  SUNXI_FUNCTION(0x5, "ms"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 7),		/* EINT7 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D8 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD4 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* IN0 */
+		  SUNXI_FUNCTION(0x5, "ms"),		/* D0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 8),		/* EINT8 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D9 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD5 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* IN1 */
+		  SUNXI_FUNCTION(0x5, "ms"),		/* D1 */
+		  SUNXI_FUNCTION_IRQ(0x6, 9),		/* EINT9 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D10 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD6 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* IN2 */
+		  SUNXI_FUNCTION(0x5, "ms"),		/* D2 */
+		  SUNXI_FUNCTION_IRQ(0x6, 10),		/* EINT10 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D11 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD7 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* IN3 */
+		  SUNXI_FUNCTION(0x5, "ms"),		/* D3 */
+		  SUNXI_FUNCTION_IRQ(0x6, 11),		/* EINT11 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D12 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD8 */
+		  SUNXI_FUNCTION(0x4, "ps2"),		/* SCK1 */
+		  SUNXI_FUNCTION_IRQ(0x6, 12),		/* EINT12 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D13 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD9 */
+		  SUNXI_FUNCTION(0x4, "ps2"),		/* SDA1 */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* RST */
+		  SUNXI_FUNCTION_IRQ(0x6, 13),		/* EINT13 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D13 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D14 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD10 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* IN4 */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* VPPEN */
+		  SUNXI_FUNCTION_IRQ(0x6, 14),		/* EINT14 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D14 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D15 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD11 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* IN5 */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* VPPPP */
+		  SUNXI_FUNCTION_IRQ(0x6, 15),		/* EINT15 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D15 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D16 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD12 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* IN6 */
+		  SUNXI_FUNCTION_IRQ(0x6, 16),		/* EINT16 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D16 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D17 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD13 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* IN7 */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* VCCEN */
+		SUNXI_FUNCTION_IRQ(0x6, 17),		/* EINT17 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D17 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D18 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD14 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* OUT0 */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* SCK */
+		SUNXI_FUNCTION_IRQ(0x6, 18),		/* EINT18 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D18 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D19 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAD15 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* OUT1 */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* SDA */
+		SUNXI_FUNCTION_IRQ(0x6, 19),		/* EINT19 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D19 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH20,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D20 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAOE */
+		  SUNXI_FUNCTION(0x4, "can"),		/* TX */
+		SUNXI_FUNCTION_IRQ(0x6, 20),		/* EINT20 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D20 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH21,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D21 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATADREQ */
+		  SUNXI_FUNCTION(0x4, "can"),		/* RX */
+		SUNXI_FUNCTION_IRQ(0x6, 21),		/* EINT21 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D21 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH22,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D22 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATADACK */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* OUT2 */
+		  SUNXI_FUNCTION(0x5, "mmc1"),		/* CMD */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D22 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH23,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* D23 */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATACS0 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* OUT3 */
+		  SUNXI_FUNCTION(0x5, "mmc1"),		/* CLK */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* D23 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH24,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATACS1 */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* OUT4 */
+		  SUNXI_FUNCTION(0x5, "mmc1"),		/* D0 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* PCLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH25,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* DE */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAIORDY */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* OUT5 */
+		  SUNXI_FUNCTION(0x5, "mmc1"),		/* D1 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* FIELD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH26,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* HSYNC */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAIOR */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* OUT6 */
+		  SUNXI_FUNCTION(0x5, "mmc1"),		/* D2 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* HSYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PH27,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd1"),		/* VSYNC */
+		  SUNXI_FUNCTION(0x3, "pata"),		/* ATAIOW */
+		  SUNXI_FUNCTION(0x4, "keypad"),	/* OUT7 */
+		  SUNXI_FUNCTION(0x5, "mmc1"),		/* D3 */
+		  SUNXI_FUNCTION(0x7, "csi1")),		/* VSYNC */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "pwm")),		/* PWM1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc3")),		/* CMD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc3")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc3")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc3")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc3")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc3")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi0"),		/* CS0 */
+		  SUNXI_FUNCTION(0x3, "uart5"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 22)),		/* EINT22 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi0"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "uart5"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 23)),		/* EINT23 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi0"),		/* MOSI */
+		  SUNXI_FUNCTION(0x3, "uart6"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 24)),		/* EINT24 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi0"),		/* MISO */
+		  SUNXI_FUNCTION(0x3, "uart6"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 25)),		/* EINT25 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi0"),		/* CS1 */
+		  SUNXI_FUNCTION(0x3, "ps2"),		/* SCK1 */
+		  SUNXI_FUNCTION(0x4, "timer4"),	/* TCLKIN0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 26)),		/* EINT26 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* CS1 */
+		  SUNXI_FUNCTION(0x3, "ps2"),		/* SDA1 */
+		  SUNXI_FUNCTION(0x4, "timer5"),	/* TCLKIN1 */
+		  SUNXI_FUNCTION_IRQ(0x6, 27)),		/* EINT27 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* CS0 */
+		  SUNXI_FUNCTION(0x3, "uart2"),		/* RTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 28)),		/* EINT28 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "uart2"),		/* CTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 29)),		/* EINT29 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* MOSI */
+		  SUNXI_FUNCTION(0x3, "uart2"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 30)),		/* EINT30 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* MISO */
+		  SUNXI_FUNCTION(0x3, "uart2"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 31)),		/* EINT31 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI20,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ps2"),		/* SCK0 */
+		  SUNXI_FUNCTION(0x3, "uart7"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "hdmi")),		/* HSCL */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PI21,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ps2"),		/* SDA0 */
+		  SUNXI_FUNCTION(0x3, "uart7"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "hdmi")),		/* HSDA */
+};
+
+static const struct sunxi_desc_pin sun5i_a10s_pins[] = {
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXD3 */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* CLK */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* IN0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXD2 */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* ERR */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* IN1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXD1 */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* SYNC */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* IN2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXD0 */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* DLVD */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* IN3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXD3 */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* D0 */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* IN4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXD2 */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* D1 */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* IN5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXD1 */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* D2 */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* IN6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXD0 */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* D3 */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* IN7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXCK */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* D4 */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* DTR */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* OUT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXERR */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* D5 */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* DSR */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* OUT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ERXDV */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* D6 */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* DCD */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* OUT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* EMDC */
+		  SUNXI_FUNCTION(0x3, "ts0"),		/* D7 */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* RING */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* OUT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* EMDIO */
+		  SUNXI_FUNCTION(0x3, "uart1"),		/* TX */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* OUT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXEN */
+		  SUNXI_FUNCTION(0x3, "uart1"),		/* RX */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* OUT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXCK */
+		  SUNXI_FUNCTION(0x3, "uart1"),		/* CTS */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* TX */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* OUT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ECRS */
+		  SUNXI_FUNCTION(0x3, "uart1"),		/* RTS */
+		  SUNXI_FUNCTION(0x4, "uart3"),		/* RX */
+		  SUNXI_FUNCTION(0x5, "keypad")),	/* OUT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ECOL */
+		  SUNXI_FUNCTION(0x3, "uart2")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PA17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "emac"),		/* ETXERR */
+		  SUNXI_FUNCTION(0x3, "uart2"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 31)),		/* EINT31 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "pwm"),		/* PWM0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 16)),		/* EINT16 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir0"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 17)),		/* EINT17 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir0"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 18)),		/* EINT18 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* MCLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 19)),		/* EINT19 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* BCLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 20)),		/* EINT20 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* LRCK */
+		  SUNXI_FUNCTION_IRQ(0x6, 21)),		/* EINT21 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* DO */
+		  SUNXI_FUNCTION_IRQ(0x6, 22)),		/* EINT22 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2s"),		/* DI */
+		  SUNXI_FUNCTION_IRQ(0x6, 23)),		/* EINT23 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* CS1 */
+		  SUNXI_FUNCTION_IRQ(0x6, 24)),		/* EINT24 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* CS0 */
+		  SUNXI_FUNCTION(0x3, "jtag"),		/* MS0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 25)),		/* EINT25 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "jtag"),		/* CK0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 26)),		/* EINT26 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* MOSI */
+		  SUNXI_FUNCTION(0x3, "jtag"),		/* DO0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 27)),		/* EINT27 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* MISO */
+		  SUNXI_FUNCTION(0x3, "jtag"),		/* DI0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 28)),		/* EINT28 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c2")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c2")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart0"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 29)),		/* EINT29 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB20,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart0"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 30)),		/* EINT30 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NWE */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NALE */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCLE */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE1 */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* CS0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NCE0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NRE */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NRB0 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* CMD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NRB1 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ0 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ1 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ2 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ3 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ4 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ5 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ6 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ7 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NWP */
+		  SUNXI_FUNCTION(0x4, "uart3")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE2 */
+		  SUNXI_FUNCTION(0x4, "uart3")),	/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE3 */
+		  SUNXI_FUNCTION(0x3, "uart2"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "uart3")),	/* CTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE4 */
+		  SUNXI_FUNCTION(0x3, "uart2"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "uart3")),	/* RTS */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "uart2")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D3 */
+		  SUNXI_FUNCTION(0x3, "uart2")),	/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D4 */
+		  SUNXI_FUNCTION(0x3, "uart2")),	/* CTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D5 */
+		  SUNXI_FUNCTION(0x3, "uart2")),	/* RTS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D6 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ECRS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D7 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ECOL */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D10 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ERXD0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D11 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ERXD1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D12 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ERXD2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D13 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ERXD3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D14 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ERXCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D15 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ERXERR */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D16 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D17 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D18 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ERXDV */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D19 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ETXD0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D20 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ETXD1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D21 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ETXD2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D22 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ETXD3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D23 */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ETXEN */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ETXCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* DE */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* ETXERR */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* HSYNC */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* EMDC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* VSYNC */
+		  SUNXI_FUNCTION(0x3, "emac")),		/* EMDIO */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* PCK */
+		  SUNXI_FUNCTION(0x4, "spi2"),		/* CS0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 14)),		/* EINT14 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* ERR */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* CK */
+		  SUNXI_FUNCTION(0x4, "spi2"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 15)),		/* EINT15 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* SYNC */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* HSYNC */
+		  SUNXI_FUNCTION(0x4, "spi2")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* DVLD */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* VSYNC */
+		  SUNXI_FUNCTION(0x4, "spi2")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D0 */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D0 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D1 */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D2 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D3 */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D3 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D4 */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D4 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* CMD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D5 */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D5 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D6 */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D6 */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ts0"),		/* D7 */
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D7 */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* RX */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "jtag")),		/* MS1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D0 */
+		  SUNXI_FUNCTION(0x4, "jtag")),		/* DI1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CLK */
+		  SUNXI_FUNCTION(0x4, "uart0")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CMD */
+		  SUNXI_FUNCTION(0x4, "jtag")),		/* DO1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D3 */
+		  SUNXI_FUNCTION(0x4, "uart0")),	/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D2 */
+		  SUNXI_FUNCTION(0x4, "jtag")),		/* CK1 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x2, "gps"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 0)),		/* EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x2, "gps"),		/* SIGN */
+		  SUNXI_FUNCTION_IRQ(0x6, 1)),		/* EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x2, "gps"),		/* MAG */
+		  SUNXI_FUNCTION_IRQ(0x6, 2)),		/* EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CMD */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 3)),		/* EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CLK */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 4)),		/* EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* DO */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* CTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 5)),		/* EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* RTS */
+		  SUNXI_FUNCTION(0x5, "uart2"),		/* RTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 6)),		/* EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D2 */
+		  SUNXI_FUNCTION(0x5, "uart2"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 7)),		/* EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D3 */
+		  SUNXI_FUNCTION(0x5, "uart2"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 8)),		/* EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* CS0 */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 9)),		/* EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 10)),		/* EINT10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* MOSI */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* CTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 11)),		/* EINT11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* MISO */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* RTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 12)),		/* EINT12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* CS1 */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* PWM1 */
+		  SUNXI_FUNCTION(0x5, "uart2"),		/* CTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 13)),		/* EINT13 */
+};
+
+static const struct sunxi_desc_pin sun5i_a13_pins[] = {
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "pwm"),
+		  SUNXI_FUNCTION_IRQ(0x6, 16)),		/* EINT16 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir0"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 17)),		/* EINT17 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir0"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 18)),		/* EINT18 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* CS1 */
+		  SUNXI_FUNCTION_IRQ(0x6, 24)),		/* EINT24 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c2")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c2")),		/* SDA */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NWE */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NALE */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCLE */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE1 */
+		  SUNXI_FUNCTION(0x3, "spi0")),		/* CS0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NCE0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NRE */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NRB0 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* CMD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NRB1 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ0 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ1 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ2 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ3 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ4 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ5 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ6 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ7 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D7 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQS */
+		  SUNXI_FUNCTION(0x4, "uart3")),	/* RTS */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D7 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D13 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D14 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D15 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D18 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D19 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D20 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D21 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D22 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* D23 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* DE */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* HSYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0")),		/* VSYNC */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* PCLK */
+		  SUNXI_FUNCTION(0x4, "spi2"),		/* CS0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 14)),		/* EINT14 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* MCLK */
+		  SUNXI_FUNCTION(0x4, "spi2"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 15)),		/* EINT15 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* HSYNC */
+		  SUNXI_FUNCTION(0x4, "spi2")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* VSYNC */
+		  SUNXI_FUNCTION(0x4, "spi2")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D0 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D2 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D3 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D4 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* CMD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D5 */
+		  SUNXI_FUNCTION(0x4, "mmc2")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D6 */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "csi0"),		/* D7 */
+		  SUNXI_FUNCTION(0x4, "uart1")),	/* RX */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x4, "mmc0")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x4, "mmc0")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x4, "mmc0")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x4, "mmc0")),		/* CMD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x4, "mmc0")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x4, "mmc0")),		/* D2 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ(0x6, 0)),		/* EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ(0x6, 1)),		/* EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ(0x6, 2)),		/* EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CMD */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 3)),		/* EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CLK */
+		  SUNXI_FUNCTION(0x4, "uart1"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 4)),		/* EINT4 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* CS0 */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 9)),		/* EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 10)),		/* EINT10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* MOSI */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* CTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 11)),		/* EINT11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN_PG12,
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "spi1"),		/* MISO */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* RTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 12)),		/* EINT12 */
+};
+
+static const struct sunxi_pinctrl_desc sun4i_a10_pinctrl_data = {
+	.pins = sun4i_a10_pins,
+	.npins = ARRAY_SIZE(sun4i_a10_pins),
+};
+
+static const struct sunxi_pinctrl_desc sun5i_a10s_pinctrl_data = {
+	.pins = sun5i_a10s_pins,
+	.npins = ARRAY_SIZE(sun5i_a10s_pins),
+};
+
+static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = {
+	.pins = sun5i_a13_pins,
+	.npins = ARRAY_SIZE(sun5i_a13_pins),
+};
+
+#endif /* __PINCTRL_SUNXI_PINS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-tz1090.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-tz1090.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-tz1090.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-tz1090.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2072 @@
+/*
+ * Pinctrl driver for the Toumaz Xenif TZ1090 SoC
+ *
+ * Copyright (c) 2013, Imagination Technologies Ltd.
+ *
+ * Derived from Tegra code:
+ * Copyright (c) 2011-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Derived from code:
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010 NVIDIA Corporation
+ * Copyright (C) 2009-2011 ST-Ericsson AB
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/*
+ * The registers may be shared with other threads/cores, so we need to use the
+ * metag global lock2 for atomicity.
+ */
+#include <asm/global_lock.h>
+
+#include "core.h"
+#include "pinconf.h"
+
+/* Register offsets from bank base address */
+#define REG_PINCTRL_SELECT	0x10
+#define REG_PINCTRL_SCHMITT	0x90
+#define REG_PINCTRL_PU_PD	0xa0
+#define REG_PINCTRL_SR		0xc0
+#define REG_PINCTRL_DR		0xd0
+#define REG_PINCTRL_IF_CTL	0xe0
+
+/* REG_PINCTRL_PU_PD field values */
+#define REG_PU_PD_TRISTATE	0
+#define REG_PU_PD_UP		1
+#define REG_PU_PD_DOWN		2
+#define REG_PU_PD_REPEATER	3
+
+/* REG_PINCTRL_DR field values */
+#define REG_DR_2mA		0
+#define REG_DR_4mA		1
+#define REG_DR_8mA		2
+#define REG_DR_12mA		3
+
+/**
+ * struct tz1090_function - TZ1090 pinctrl mux function
+ * @name:	The name of the function, exported to pinctrl core.
+ * @groups:	An array of pin groups that may select this function.
+ * @ngroups:	The number of entries in @groups.
+ */
+struct tz1090_function {
+	const char		*name;
+	const char * const	*groups;
+	unsigned int		ngroups;
+};
+
+/**
+ * struct tz1090_muxdesc - TZ1090 individual mux description
+ * @funcs:	Function for each mux value.
+ * @reg:	Mux register offset. 0 if unsupported.
+ * @bit:	Mux register bit. 0 if unsupported.
+ * @width:	Mux field width. 0 if unsupported.
+ *
+ * A representation of a group of signals (possibly just one signal) in the
+ * TZ1090 which can be muxed to a set of functions or sub muxes.
+ */
+struct tz1090_muxdesc {
+	int	funcs[5];
+	u16	reg;
+	u8	bit;
+	u8	width;
+};
+
+/**
+ * struct tz1090_pingroup - TZ1090 pin group
+ * @name:	Name of pin group.
+ * @pins:	Array of pin numbers in this pin group.
+ * @npins:	Number of pins in this pin group.
+ * @mux:	Top level mux.
+ * @drv:	Drive control supported, 0 if unsupported.
+ *		This means Schmitt, Slew, and Drive strength.
+ * @slw_bit:	Slew register bit. 0 if unsupported.
+ *		The same bit is used for Schmitt, and Drive (*2).
+ * @func:	Currently muxed function.
+ * @func_count:	Number of pins using current mux function.
+ *
+ * A representation of a group of pins (possibly just one pin) in the TZ1090
+ * pin controller. Each group allows some parameter or parameters to be
+ * configured. The most common is mux function selection.
+ */
+struct tz1090_pingroup {
+	const char		*name;
+	const unsigned int	*pins;
+	unsigned int		npins;
+	struct tz1090_muxdesc	mux;
+
+	bool			drv;
+	u8			slw_bit;
+
+	int			func;
+	unsigned int		func_count;
+};
+
+/*
+ * Most pins affected by the pinmux can also be GPIOs. Define these first.
+ * These must match how the GPIO driver names/numbers its pins.
+ */
+
+enum tz1090_pin {
+	/* GPIO pins */
+	TZ1090_PIN_SDIO_CLK,
+	TZ1090_PIN_SDIO_CMD,
+	TZ1090_PIN_SDIO_D0,
+	TZ1090_PIN_SDIO_D1,
+	TZ1090_PIN_SDIO_D2,
+	TZ1090_PIN_SDIO_D3,
+	TZ1090_PIN_SDH_CD,
+	TZ1090_PIN_SDH_WP,
+	TZ1090_PIN_SPI0_MCLK,
+	TZ1090_PIN_SPI0_CS0,
+	TZ1090_PIN_SPI0_CS1,
+	TZ1090_PIN_SPI0_CS2,
+	TZ1090_PIN_SPI0_DOUT,
+	TZ1090_PIN_SPI0_DIN,
+	TZ1090_PIN_SPI1_MCLK,
+	TZ1090_PIN_SPI1_CS0,
+	TZ1090_PIN_SPI1_CS1,
+	TZ1090_PIN_SPI1_CS2,
+	TZ1090_PIN_SPI1_DOUT,
+	TZ1090_PIN_SPI1_DIN,
+	TZ1090_PIN_UART0_RXD,
+	TZ1090_PIN_UART0_TXD,
+	TZ1090_PIN_UART0_CTS,
+	TZ1090_PIN_UART0_RTS,
+	TZ1090_PIN_UART1_RXD,
+	TZ1090_PIN_UART1_TXD,
+	TZ1090_PIN_SCB0_SDAT,
+	TZ1090_PIN_SCB0_SCLK,
+	TZ1090_PIN_SCB1_SDAT,
+	TZ1090_PIN_SCB1_SCLK,
+	TZ1090_PIN_SCB2_SDAT,
+	TZ1090_PIN_SCB2_SCLK,
+	TZ1090_PIN_I2S_MCLK,
+	TZ1090_PIN_I2S_BCLK_OUT,
+	TZ1090_PIN_I2S_LRCLK_OUT,
+	TZ1090_PIN_I2S_DOUT0,
+	TZ1090_PIN_I2S_DOUT1,
+	TZ1090_PIN_I2S_DOUT2,
+	TZ1090_PIN_I2S_DIN,
+	TZ1090_PIN_PDM_A,
+	TZ1090_PIN_PDM_B,
+	TZ1090_PIN_PDM_C,
+	TZ1090_PIN_PDM_D,
+	TZ1090_PIN_TFT_RED0,
+	TZ1090_PIN_TFT_RED1,
+	TZ1090_PIN_TFT_RED2,
+	TZ1090_PIN_TFT_RED3,
+	TZ1090_PIN_TFT_RED4,
+	TZ1090_PIN_TFT_RED5,
+	TZ1090_PIN_TFT_RED6,
+	TZ1090_PIN_TFT_RED7,
+	TZ1090_PIN_TFT_GREEN0,
+	TZ1090_PIN_TFT_GREEN1,
+	TZ1090_PIN_TFT_GREEN2,
+	TZ1090_PIN_TFT_GREEN3,
+	TZ1090_PIN_TFT_GREEN4,
+	TZ1090_PIN_TFT_GREEN5,
+	TZ1090_PIN_TFT_GREEN6,
+	TZ1090_PIN_TFT_GREEN7,
+	TZ1090_PIN_TFT_BLUE0,
+	TZ1090_PIN_TFT_BLUE1,
+	TZ1090_PIN_TFT_BLUE2,
+	TZ1090_PIN_TFT_BLUE3,
+	TZ1090_PIN_TFT_BLUE4,
+	TZ1090_PIN_TFT_BLUE5,
+	TZ1090_PIN_TFT_BLUE6,
+	TZ1090_PIN_TFT_BLUE7,
+	TZ1090_PIN_TFT_VDDEN_GD,
+	TZ1090_PIN_TFT_PANELCLK,
+	TZ1090_PIN_TFT_BLANK_LS,
+	TZ1090_PIN_TFT_VSYNC_NS,
+	TZ1090_PIN_TFT_HSYNC_NR,
+	TZ1090_PIN_TFT_VD12ACB,
+	TZ1090_PIN_TFT_PWRSAVE,
+	TZ1090_PIN_TX_ON,
+	TZ1090_PIN_RX_ON,
+	TZ1090_PIN_PLL_ON,
+	TZ1090_PIN_PA_ON,
+	TZ1090_PIN_RX_HP,
+	TZ1090_PIN_GAIN0,
+	TZ1090_PIN_GAIN1,
+	TZ1090_PIN_GAIN2,
+	TZ1090_PIN_GAIN3,
+	TZ1090_PIN_GAIN4,
+	TZ1090_PIN_GAIN5,
+	TZ1090_PIN_GAIN6,
+	TZ1090_PIN_GAIN7,
+	TZ1090_PIN_ANT_SEL0,
+	TZ1090_PIN_ANT_SEL1,
+	TZ1090_PIN_SDH_CLK_IN,
+
+	/* Non-GPIO pins */
+	TZ1090_PIN_TCK,
+	TZ1090_PIN_TRST,
+	TZ1090_PIN_TDI,
+	TZ1090_PIN_TDO,
+	TZ1090_PIN_TMS,
+	TZ1090_PIN_CLK_OUT0,
+	TZ1090_PIN_CLK_OUT1,
+
+	NUM_GPIOS = TZ1090_PIN_TCK,
+};
+
+/* Pin names */
+
+static const struct pinctrl_pin_desc tz1090_pins[] = {
+	/* GPIO pins */
+	PINCTRL_PIN(TZ1090_PIN_SDIO_CLK,	"sdio_clk"),
+	PINCTRL_PIN(TZ1090_PIN_SDIO_CMD,	"sdio_cmd"),
+	PINCTRL_PIN(TZ1090_PIN_SDIO_D0,		"sdio_d0"),
+	PINCTRL_PIN(TZ1090_PIN_SDIO_D1,		"sdio_d1"),
+	PINCTRL_PIN(TZ1090_PIN_SDIO_D2,		"sdio_d2"),
+	PINCTRL_PIN(TZ1090_PIN_SDIO_D3,		"sdio_d3"),
+	PINCTRL_PIN(TZ1090_PIN_SDH_CD,		"sdh_cd"),
+	PINCTRL_PIN(TZ1090_PIN_SDH_WP,		"sdh_wp"),
+	PINCTRL_PIN(TZ1090_PIN_SPI0_MCLK,	"spi0_mclk"),
+	PINCTRL_PIN(TZ1090_PIN_SPI0_CS0,	"spi0_cs0"),
+	PINCTRL_PIN(TZ1090_PIN_SPI0_CS1,	"spi0_cs1"),
+	PINCTRL_PIN(TZ1090_PIN_SPI0_CS2,	"spi0_cs2"),
+	PINCTRL_PIN(TZ1090_PIN_SPI0_DOUT,	"spi0_dout"),
+	PINCTRL_PIN(TZ1090_PIN_SPI0_DIN,	"spi0_din"),
+	PINCTRL_PIN(TZ1090_PIN_SPI1_MCLK,	"spi1_mclk"),
+	PINCTRL_PIN(TZ1090_PIN_SPI1_CS0,	"spi1_cs0"),
+	PINCTRL_PIN(TZ1090_PIN_SPI1_CS1,	"spi1_cs1"),
+	PINCTRL_PIN(TZ1090_PIN_SPI1_CS2,	"spi1_cs2"),
+	PINCTRL_PIN(TZ1090_PIN_SPI1_DOUT,	"spi1_dout"),
+	PINCTRL_PIN(TZ1090_PIN_SPI1_DIN,	"spi1_din"),
+	PINCTRL_PIN(TZ1090_PIN_UART0_RXD,	"uart0_rxd"),
+	PINCTRL_PIN(TZ1090_PIN_UART0_TXD,	"uart0_txd"),
+	PINCTRL_PIN(TZ1090_PIN_UART0_CTS,	"uart0_cts"),
+	PINCTRL_PIN(TZ1090_PIN_UART0_RTS,	"uart0_rts"),
+	PINCTRL_PIN(TZ1090_PIN_UART1_RXD,	"uart1_rxd"),
+	PINCTRL_PIN(TZ1090_PIN_UART1_TXD,	"uart1_txd"),
+	PINCTRL_PIN(TZ1090_PIN_SCB0_SDAT,	"scb0_sdat"),
+	PINCTRL_PIN(TZ1090_PIN_SCB0_SCLK,	"scb0_sclk"),
+	PINCTRL_PIN(TZ1090_PIN_SCB1_SDAT,	"scb1_sdat"),
+	PINCTRL_PIN(TZ1090_PIN_SCB1_SCLK,	"scb1_sclk"),
+	PINCTRL_PIN(TZ1090_PIN_SCB2_SDAT,	"scb2_sdat"),
+	PINCTRL_PIN(TZ1090_PIN_SCB2_SCLK,	"scb2_sclk"),
+	PINCTRL_PIN(TZ1090_PIN_I2S_MCLK,	"i2s_mclk"),
+	PINCTRL_PIN(TZ1090_PIN_I2S_BCLK_OUT,	"i2s_bclk_out"),
+	PINCTRL_PIN(TZ1090_PIN_I2S_LRCLK_OUT,	"i2s_lrclk_out"),
+	PINCTRL_PIN(TZ1090_PIN_I2S_DOUT0,	"i2s_dout0"),
+	PINCTRL_PIN(TZ1090_PIN_I2S_DOUT1,	"i2s_dout1"),
+	PINCTRL_PIN(TZ1090_PIN_I2S_DOUT2,	"i2s_dout2"),
+	PINCTRL_PIN(TZ1090_PIN_I2S_DIN,		"i2s_din"),
+	PINCTRL_PIN(TZ1090_PIN_PDM_A,		"pdm_a"),
+	PINCTRL_PIN(TZ1090_PIN_PDM_B,		"pdm_b"),
+	PINCTRL_PIN(TZ1090_PIN_PDM_C,		"pdm_c"),
+	PINCTRL_PIN(TZ1090_PIN_PDM_D,		"pdm_d"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_RED0,	"tft_red0"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_RED1,	"tft_red1"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_RED2,	"tft_red2"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_RED3,	"tft_red3"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_RED4,	"tft_red4"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_RED5,	"tft_red5"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_RED6,	"tft_red6"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_RED7,	"tft_red7"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_GREEN0,	"tft_green0"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_GREEN1,	"tft_green1"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_GREEN2,	"tft_green2"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_GREEN3,	"tft_green3"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_GREEN4,	"tft_green4"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_GREEN5,	"tft_green5"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_GREEN6,	"tft_green6"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_GREEN7,	"tft_green7"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_BLUE0,	"tft_blue0"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_BLUE1,	"tft_blue1"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_BLUE2,	"tft_blue2"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_BLUE3,	"tft_blue3"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_BLUE4,	"tft_blue4"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_BLUE5,	"tft_blue5"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_BLUE6,	"tft_blue6"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_BLUE7,	"tft_blue7"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_VDDEN_GD,	"tft_vdden_gd"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_PANELCLK,	"tft_panelclk"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_BLANK_LS,	"tft_blank_ls"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_VSYNC_NS,	"tft_vsync_ns"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_HSYNC_NR,	"tft_hsync_nr"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_VD12ACB,	"tft_vd12acb"),
+	PINCTRL_PIN(TZ1090_PIN_TFT_PWRSAVE,	"tft_pwrsave"),
+	PINCTRL_PIN(TZ1090_PIN_TX_ON,		"tx_on"),
+	PINCTRL_PIN(TZ1090_PIN_RX_ON,		"rx_on"),
+	PINCTRL_PIN(TZ1090_PIN_PLL_ON,		"pll_on"),
+	PINCTRL_PIN(TZ1090_PIN_PA_ON,		"pa_on"),
+	PINCTRL_PIN(TZ1090_PIN_RX_HP,		"rx_hp"),
+	PINCTRL_PIN(TZ1090_PIN_GAIN0,		"gain0"),
+	PINCTRL_PIN(TZ1090_PIN_GAIN1,		"gain1"),
+	PINCTRL_PIN(TZ1090_PIN_GAIN2,		"gain2"),
+	PINCTRL_PIN(TZ1090_PIN_GAIN3,		"gain3"),
+	PINCTRL_PIN(TZ1090_PIN_GAIN4,		"gain4"),
+	PINCTRL_PIN(TZ1090_PIN_GAIN5,		"gain5"),
+	PINCTRL_PIN(TZ1090_PIN_GAIN6,		"gain6"),
+	PINCTRL_PIN(TZ1090_PIN_GAIN7,		"gain7"),
+	PINCTRL_PIN(TZ1090_PIN_ANT_SEL0,	"ant_sel0"),
+	PINCTRL_PIN(TZ1090_PIN_ANT_SEL1,	"ant_sel1"),
+	PINCTRL_PIN(TZ1090_PIN_SDH_CLK_IN,	"sdh_clk_in"),
+
+	/* Non-GPIO pins */
+	PINCTRL_PIN(TZ1090_PIN_TCK,		"tck"),
+	PINCTRL_PIN(TZ1090_PIN_TRST,		"trst"),
+	PINCTRL_PIN(TZ1090_PIN_TDI,		"tdi"),
+	PINCTRL_PIN(TZ1090_PIN_TDO,		"tdo"),
+	PINCTRL_PIN(TZ1090_PIN_TMS,		"tms"),
+	PINCTRL_PIN(TZ1090_PIN_CLK_OUT0,	"clk_out0"),
+	PINCTRL_PIN(TZ1090_PIN_CLK_OUT1,	"clk_out1"),
+};
+
+/* Pins in each pin group */
+
+static const unsigned int spi1_cs2_pins[] = {
+	TZ1090_PIN_SPI1_CS2,
+};
+
+static const unsigned int pdm_d_pins[] = {
+	TZ1090_PIN_PDM_D,
+};
+
+static const unsigned int tft_pins[] = {
+	TZ1090_PIN_TFT_RED0,
+	TZ1090_PIN_TFT_RED1,
+	TZ1090_PIN_TFT_RED2,
+	TZ1090_PIN_TFT_RED3,
+	TZ1090_PIN_TFT_RED4,
+	TZ1090_PIN_TFT_RED5,
+	TZ1090_PIN_TFT_RED6,
+	TZ1090_PIN_TFT_RED7,
+	TZ1090_PIN_TFT_GREEN0,
+	TZ1090_PIN_TFT_GREEN1,
+	TZ1090_PIN_TFT_GREEN2,
+	TZ1090_PIN_TFT_GREEN3,
+	TZ1090_PIN_TFT_GREEN4,
+	TZ1090_PIN_TFT_GREEN5,
+	TZ1090_PIN_TFT_GREEN6,
+	TZ1090_PIN_TFT_GREEN7,
+	TZ1090_PIN_TFT_BLUE0,
+	TZ1090_PIN_TFT_BLUE1,
+	TZ1090_PIN_TFT_BLUE2,
+	TZ1090_PIN_TFT_BLUE3,
+	TZ1090_PIN_TFT_BLUE4,
+	TZ1090_PIN_TFT_BLUE5,
+	TZ1090_PIN_TFT_BLUE6,
+	TZ1090_PIN_TFT_BLUE7,
+	TZ1090_PIN_TFT_VDDEN_GD,
+	TZ1090_PIN_TFT_PANELCLK,
+	TZ1090_PIN_TFT_BLANK_LS,
+	TZ1090_PIN_TFT_VSYNC_NS,
+	TZ1090_PIN_TFT_HSYNC_NR,
+	TZ1090_PIN_TFT_VD12ACB,
+	TZ1090_PIN_TFT_PWRSAVE,
+};
+
+static const unsigned int afe_pins[] = {
+	TZ1090_PIN_TX_ON,
+	TZ1090_PIN_RX_ON,
+	TZ1090_PIN_PLL_ON,
+	TZ1090_PIN_PA_ON,
+	TZ1090_PIN_RX_HP,
+	TZ1090_PIN_ANT_SEL0,
+	TZ1090_PIN_ANT_SEL1,
+	TZ1090_PIN_GAIN0,
+	TZ1090_PIN_GAIN1,
+	TZ1090_PIN_GAIN2,
+	TZ1090_PIN_GAIN3,
+	TZ1090_PIN_GAIN4,
+	TZ1090_PIN_GAIN5,
+	TZ1090_PIN_GAIN6,
+	TZ1090_PIN_GAIN7,
+};
+
+static const unsigned int sdio_pins[] = {
+	TZ1090_PIN_SDIO_CLK,
+	TZ1090_PIN_SDIO_CMD,
+	TZ1090_PIN_SDIO_D0,
+	TZ1090_PIN_SDIO_D1,
+	TZ1090_PIN_SDIO_D2,
+	TZ1090_PIN_SDIO_D3,
+};
+
+static const unsigned int sdh_pins[] = {
+	TZ1090_PIN_SDH_CD,
+	TZ1090_PIN_SDH_WP,
+	TZ1090_PIN_SDH_CLK_IN,
+};
+
+static const unsigned int spi0_pins[] = {
+	TZ1090_PIN_SPI0_MCLK,
+	TZ1090_PIN_SPI0_CS0,
+	TZ1090_PIN_SPI0_CS1,
+	TZ1090_PIN_SPI0_CS2,
+	TZ1090_PIN_SPI0_DOUT,
+	TZ1090_PIN_SPI0_DIN,
+};
+
+static const unsigned int spi1_pins[] = {
+	TZ1090_PIN_SPI1_MCLK,
+	TZ1090_PIN_SPI1_CS0,
+	TZ1090_PIN_SPI1_CS1,
+	TZ1090_PIN_SPI1_CS2,
+	TZ1090_PIN_SPI1_DOUT,
+	TZ1090_PIN_SPI1_DIN,
+};
+
+static const unsigned int uart0_pins[] = {
+	TZ1090_PIN_UART0_RTS,
+	TZ1090_PIN_UART0_CTS,
+	TZ1090_PIN_UART0_TXD,
+	TZ1090_PIN_UART0_RXD,
+};
+
+static const unsigned int uart1_pins[] = {
+	TZ1090_PIN_UART1_TXD,
+	TZ1090_PIN_UART1_RXD,
+};
+
+static const unsigned int uart_pins[] = {
+	TZ1090_PIN_UART1_TXD,
+	TZ1090_PIN_UART1_RXD,
+	TZ1090_PIN_UART0_RTS,
+	TZ1090_PIN_UART0_CTS,
+	TZ1090_PIN_UART0_TXD,
+	TZ1090_PIN_UART0_RXD,
+};
+
+static const unsigned int scb0_pins[] = {
+	TZ1090_PIN_SCB0_SDAT,
+	TZ1090_PIN_SCB0_SCLK,
+};
+
+static const unsigned int scb1_pins[] = {
+	TZ1090_PIN_SCB1_SDAT,
+	TZ1090_PIN_SCB1_SCLK,
+};
+
+static const unsigned int scb2_pins[] = {
+	TZ1090_PIN_SCB2_SDAT,
+	TZ1090_PIN_SCB2_SCLK,
+};
+
+static const unsigned int i2s_pins[] = {
+	TZ1090_PIN_I2S_MCLK,
+	TZ1090_PIN_I2S_BCLK_OUT,
+	TZ1090_PIN_I2S_LRCLK_OUT,
+	TZ1090_PIN_I2S_DOUT0,
+	TZ1090_PIN_I2S_DOUT1,
+	TZ1090_PIN_I2S_DOUT2,
+	TZ1090_PIN_I2S_DIN,
+};
+
+static const unsigned int jtag_pins[] = {
+	TZ1090_PIN_TCK,
+	TZ1090_PIN_TRST,
+	TZ1090_PIN_TDI,
+	TZ1090_PIN_TDO,
+	TZ1090_PIN_TMS,
+};
+
+/* Pins in each drive pin group */
+
+static const unsigned int drive_sdio_pins[] = {
+	TZ1090_PIN_SDIO_CLK,
+	TZ1090_PIN_SDIO_CMD,
+	TZ1090_PIN_SDIO_D0,
+	TZ1090_PIN_SDIO_D1,
+	TZ1090_PIN_SDIO_D2,
+	TZ1090_PIN_SDIO_D3,
+	TZ1090_PIN_SDH_WP,
+	TZ1090_PIN_SDH_CD,
+	TZ1090_PIN_SDH_CLK_IN,
+};
+
+static const unsigned int drive_i2s_pins[] = {
+	TZ1090_PIN_CLK_OUT1,
+	TZ1090_PIN_I2S_DIN,
+	TZ1090_PIN_I2S_DOUT0,
+	TZ1090_PIN_I2S_DOUT1,
+	TZ1090_PIN_I2S_DOUT2,
+	TZ1090_PIN_I2S_LRCLK_OUT,
+	TZ1090_PIN_I2S_BCLK_OUT,
+	TZ1090_PIN_I2S_MCLK,
+};
+
+static const unsigned int drive_scb0_pins[] = {
+	TZ1090_PIN_SCB0_SCLK,
+	TZ1090_PIN_SCB0_SDAT,
+	TZ1090_PIN_PDM_D,
+	TZ1090_PIN_PDM_C,
+};
+
+static const unsigned int drive_pdm_pins[] = {
+	TZ1090_PIN_CLK_OUT0,
+	TZ1090_PIN_PDM_B,
+	TZ1090_PIN_PDM_A,
+};
+
+/* Pin groups each function can be muxed to */
+
+/*
+ * The magic "perip" function allows otherwise non-muxing pins to be enabled in
+ * peripheral mode.
+ */
+static const char * const perip_groups[] = {
+	/* non-muxing convenient gpio pingroups */
+	"uart",
+	"uart0",
+	"uart1",
+	"spi0",
+	"spi1",
+	"scb0",
+	"scb1",
+	"scb2",
+	"i2s",
+	/* individual pins not part of a pin mux group */
+	"spi0_mclk",
+	"spi0_cs0",
+	"spi0_cs1",
+	"spi0_cs2",
+	"spi0_dout",
+	"spi0_din",
+	"spi1_mclk",
+	"spi1_cs0",
+	"spi1_cs1",
+	"spi1_dout",
+	"spi1_din",
+	"uart0_rxd",
+	"uart0_txd",
+	"uart0_cts",
+	"uart0_rts",
+	"uart1_rxd",
+	"uart1_txd",
+	"scb0_sdat",
+	"scb0_sclk",
+	"scb1_sdat",
+	"scb1_sclk",
+	"scb2_sdat",
+	"scb2_sclk",
+	"i2s_mclk",
+	"i2s_bclk_out",
+	"i2s_lrclk_out",
+	"i2s_dout0",
+	"i2s_dout1",
+	"i2s_dout2",
+	"i2s_din",
+	"pdm_a",
+	"pdm_b",
+	"pdm_c",
+};
+
+static const char * const sdh_sdio_groups[] = {
+	"sdh",
+	"sdio",
+	/* sdh pins */
+	"sdh_cd",
+	"sdh_wp",
+	"sdh_clk_in",
+	/* sdio pins */
+	"sdio_clk",
+	"sdio_cmd",
+	"sdio_d0",
+	"sdio_d1",
+	"sdio_d2",
+	"sdio_d3",
+};
+
+static const char * const spi1_cs2_groups[] = {
+	"spi1_cs2",
+};
+
+static const char * const pdm_dac_groups[] = {
+	"pdm_d",
+};
+
+static const char * const usb_vbus_groups[] = {
+	"spi1_cs2",
+	"pdm_d",
+};
+
+static const char * const afe_groups[] = {
+	"afe",
+	/* afe pins */
+	"tx_on",
+	"rx_on",
+	"pll_on",
+	"pa_on",
+	"rx_hp",
+	"ant_sel0",
+	"ant_sel1",
+	"gain0",
+	"gain1",
+	"gain2",
+	"gain3",
+	"gain4",
+	"gain5",
+	"gain6",
+	"gain7",
+};
+
+static const char * const tft_groups[] = {
+	"tft",
+	/* tft pins */
+	"tft_red0",
+	"tft_red1",
+	"tft_red2",
+	"tft_red3",
+	"tft_red4",
+	"tft_red5",
+	"tft_red6",
+	"tft_red7",
+	"tft_green0",
+	"tft_green1",
+	"tft_green2",
+	"tft_green3",
+	"tft_green4",
+	"tft_green5",
+	"tft_green6",
+	"tft_green7",
+	"tft_blue0",
+	"tft_blue1",
+	"tft_blue2",
+	"tft_blue3",
+	"tft_blue4",
+	"tft_blue5",
+	"tft_blue6",
+	"tft_blue7",
+	"tft_vdden_gd",
+	"tft_panelclk",
+	"tft_blank_ls",
+	"tft_vsync_ns",
+	"tft_hsync_nr",
+	"tft_vd12acb",
+	"tft_pwrsave",
+};
+
+/* Mux functions that can be used by a mux */
+
+enum tz1090_mux {
+	/* internal placeholder */
+	TZ1090_MUX_NA = -1,
+	/* magic per-non-muxing-GPIO-pin peripheral mode mux */
+	TZ1090_MUX_PERIP,
+	/* SDH/SDIO mux */
+	TZ1090_MUX_SDH,
+	TZ1090_MUX_SDIO,
+	/* USB_VBUS muxes */
+	TZ1090_MUX_SPI1_CS2,
+	TZ1090_MUX_PDM_DAC,
+	TZ1090_MUX_USB_VBUS,
+	/* AFE mux */
+	TZ1090_MUX_AFE,
+	TZ1090_MUX_TS_OUT_0,
+	/* EXT_DAC mux */
+	TZ1090_MUX_DAC,
+	TZ1090_MUX_NOT_IQADC_STB,
+	TZ1090_MUX_IQDAC_STB,
+	/* TFT mux */
+	TZ1090_MUX_TFT,
+	TZ1090_MUX_EXT_DAC,
+	TZ1090_MUX_TS_OUT_1,
+	TZ1090_MUX_LCD_TRACE,
+	TZ1090_MUX_PHY_RINGOSC,
+};
+
+#define FUNCTION(mux, fname, group)			\
+	[(TZ1090_MUX_ ## mux)] = {			\
+		.name = #fname,				\
+		.groups = group##_groups,		\
+		.ngroups = ARRAY_SIZE(group##_groups),	\
+	}
+/* For intermediate functions with submuxes */
+#define NULL_FUNCTION(mux, fname)			\
+	[(TZ1090_MUX_ ## mux)] = {			\
+		.name = #fname,				\
+	}
+
+/* Must correlate with enum tz1090_mux */
+static const struct tz1090_function tz1090_functions[] = {
+	/*	 FUNCTION	function name	pingroups */
+	FUNCTION(PERIP,		perip,		perip),
+	FUNCTION(SDH,		sdh,		sdh_sdio),
+	FUNCTION(SDIO,		sdio,		sdh_sdio),
+	FUNCTION(SPI1_CS2,	spi1_cs2,	spi1_cs2),
+	FUNCTION(PDM_DAC,	pdm_dac,	pdm_dac),
+	FUNCTION(USB_VBUS,	usb_vbus,	usb_vbus),
+	FUNCTION(AFE,		afe,		afe),
+	FUNCTION(TS_OUT_0,	ts_out_0,	afe),
+	FUNCTION(DAC,		ext_dac,	tft),
+	FUNCTION(NOT_IQADC_STB,	not_iqadc_stb,	tft),
+	FUNCTION(IQDAC_STB,	iqdac_stb,	tft),
+	FUNCTION(TFT,		tft,		tft),
+	NULL_FUNCTION(EXT_DAC,	_ext_dac),
+	FUNCTION(TS_OUT_1,	ts_out_1,	tft),
+	FUNCTION(LCD_TRACE,	lcd_trace,	tft),
+	FUNCTION(PHY_RINGOSC,	phy_ringosc,	tft),
+};
+
+/* Sub muxes */
+
+/**
+ * MUX() - Initialise a mux description.
+ * @f0:		Function 0 (TZ1090_MUX_ is prepended, NA for none)
+ * @f1:		Function 1 (TZ1090_MUX_ is prepended, NA for none)
+ * @f2:		Function 2 (TZ1090_MUX_ is prepended, NA for none)
+ * @f3:		Function 3 (TZ1090_MUX_ is prepended, NA for none)
+ * @f4:		Function 4 (TZ1090_MUX_ is prepended, NA for none)
+ * @mux_r:	Mux register (REG_PINCTRL_ is prepended)
+ * @mux_b:	Bit number in register that the mux field begins
+ * @mux_w:	Width of mux field in register
+ */
+#define MUX(f0, f1, f2, f3, f4, mux_r, mux_b, mux_w)		\
+	{							\
+		.funcs = {					\
+			TZ1090_MUX_ ## f0,			\
+			TZ1090_MUX_ ## f1,			\
+			TZ1090_MUX_ ## f2,			\
+			TZ1090_MUX_ ## f3,			\
+			TZ1090_MUX_ ## f4,			\
+		},						\
+		.reg = (REG_PINCTRL_ ## mux_r),			\
+		.bit = (mux_b),					\
+		.width = (mux_w),				\
+	}
+
+/**
+ * DEFINE_SUBMUX() - Defines a submux description separate from a pin group.
+ * @mux:	Mux name (_submux is appended)
+ * @f0:		Function 0 (TZ1090_MUX_ is prepended, NA for none)
+ * @f1:		Function 1 (TZ1090_MUX_ is prepended, NA for none)
+ * @f2:		Function 2 (TZ1090_MUX_ is prepended, NA for none)
+ * @f3:		Function 3 (TZ1090_MUX_ is prepended, NA for none)
+ * @f4:		Function 4 (TZ1090_MUX_ is prepended, NA for none)
+ * @mux_r:	Mux register (REG_PINCTRL_ is prepended)
+ * @mux_b:	Bit number in register that the mux field begins
+ * @mux_w:	Width of mux field in register
+ *
+ * A sub mux is a nested mux that can be bound to a magic function number used
+ * by another mux description. For example value 4 of the top level mux might
+ * correspond to a function which has a submux pointed to in tz1090_submux[].
+ * The outer mux can then take on any function in the top level mux or the
+ * submux, and if a submux function is chosen both muxes are updated to route
+ * the signal from the submux.
+ *
+ * The submux can be defined with DEFINE_SUBMUX and pointed to from
+ * tz1090_submux[] using SUBMUX.
+ */
+#define DEFINE_SUBMUX(mux, f0, f1, f2, f3, f4, mux_r, mux_b, mux_w)	\
+	static struct tz1090_muxdesc mux ## _submux =			\
+		MUX(f0, f1, f2, f3, f4, mux_r, mux_b, mux_w)
+
+/**
+ * SUBMUX() - Link a submux to a function number.
+ * @f:		Function name (TZ1090_MUX_ is prepended)
+ * @submux:	Submux name (_submux is appended)
+ *
+ * For use in tz1090_submux[] initialisation to link an intermediate function
+ * number to a particular submux description. It indicates that when the
+ * function is chosen the signal is connected to the submux.
+ */
+#define SUBMUX(f, submux)	[(TZ1090_MUX_ ## f)] = &(submux ## _submux)
+
+/**
+ * MUX_PG() - Initialise a pin group with mux control
+ * @pg_name:	Pin group name (stringified, _pins appended to get pins array)
+ * @f0:		Function 0 (TZ1090_MUX_ is prepended, NA for none)
+ * @f1:		Function 1 (TZ1090_MUX_ is prepended, NA for none)
+ * @f2:		Function 2 (TZ1090_MUX_ is prepended, NA for none)
+ * @f3:		Function 3 (TZ1090_MUX_ is prepended, NA for none)
+ * @f4:		Function 4 (TZ1090_MUX_ is prepended, NA for none)
+ * @mux_r:	Mux register (REG_PINCTRL_ is prepended)
+ * @mux_b:	Bit number in register that the mux field begins
+ * @mux_w:	Width of mux field in register
+ */
+#define MUX_PG(pg_name, f0, f1, f2, f3, f4,			\
+	       mux_r, mux_b, mux_w)				\
+	{							\
+		.name = #pg_name,				\
+		.pins = pg_name##_pins,				\
+		.npins = ARRAY_SIZE(pg_name##_pins),		\
+		.mux = MUX(f0, f1, f2, f3, f4,			\
+			   mux_r, mux_b, mux_w),		\
+	}
+
+/**
+ * SIMPLE_PG() - Initialise a simple convenience pin group
+ * @pg_name:	Pin group name (stringified, _pins appended to get pins array)
+ *
+ * A simple pin group is simply used for binding pins together so they can be
+ * referred to by a single name instead of having to list every pin
+ * individually.
+ */
+#define SIMPLE_PG(pg_name)					\
+	{							\
+		.name = #pg_name,				\
+		.pins = pg_name##_pins,				\
+		.npins = ARRAY_SIZE(pg_name##_pins),		\
+	}
+
+/**
+ * DRV_PG() - Initialise a pin group with drive control
+ * @pg_name:	Pin group name (stringified, _pins appended to get pins array)
+ * @slw_b:	Slew register bit.
+ *		The same bit is used for Schmitt, and Drive (*2).
+ */
+#define DRV_PG(pg_name, slw_b)					\
+	{							\
+		.name = #pg_name,				\
+		.pins = pg_name##_pins,				\
+		.npins = ARRAY_SIZE(pg_name##_pins),		\
+		.drv = true,					\
+		.slw_bit = (slw_b),				\
+	}
+
+/*
+ * Define main muxing pin groups
+ */
+
+/* submuxes */
+
+/*            name     f0,  f1,            f2,        f3, f4, mux r/b/w */
+DEFINE_SUBMUX(ext_dac, DAC, NOT_IQADC_STB, IQDAC_STB, NA, NA, IF_CTL, 6, 2);
+
+/* bind submuxes to internal functions */
+static struct tz1090_muxdesc *tz1090_submux[] = {
+	SUBMUX(EXT_DAC, ext_dac),
+};
+
+/*
+ * These are the pin mux groups. Pin muxing can be enabled and disabled for each
+ * pin individually so these groups are internal. The mapping of pins to pin mux
+ * group is below (tz1090_mux_pins).
+ */
+static struct tz1090_pingroup tz1090_mux_groups[] = {
+	/* Muxing pin groups */
+	/*     pg_name,  f0,       f1,       f2,       f3,        f4,          mux r/b/w */
+	MUX_PG(sdh,      SDH,      SDIO,     NA,       NA,        NA,          IF_CTL, 20, 2),
+	MUX_PG(sdio,     SDIO,     SDH,      NA,       NA,        NA,          IF_CTL, 16, 2),
+	MUX_PG(spi1_cs2, SPI1_CS2, USB_VBUS, NA,       NA,        NA,          IF_CTL, 10, 2),
+	MUX_PG(pdm_d,    PDM_DAC,  USB_VBUS, NA,       NA,        NA,          IF_CTL,  8, 2),
+	MUX_PG(afe,      AFE,      TS_OUT_0, NA,       NA,        NA,          IF_CTL,  4, 2),
+	MUX_PG(tft,      TFT,      EXT_DAC,  TS_OUT_1, LCD_TRACE, PHY_RINGOSC, IF_CTL,  0, 3),
+};
+
+/*
+ * This is the mapping from GPIO pins to pin mux groups in tz1090_mux_groups[].
+ * Pins which aren't muxable to multiple peripherals are set to
+ * TZ1090_MUX_GROUP_MAX to enable the "perip" function to enable/disable
+ * peripheral control of the pin.
+ *
+ * This array is initialised in tz1090_init_mux_pins().
+ */
+static u8 tz1090_mux_pins[NUM_GPIOS];
+
+/* TZ1090_MUX_GROUP_MAX is used in tz1090_mux_pins[] for non-muxing pins */
+#define TZ1090_MUX_GROUP_MAX ARRAY_SIZE(tz1090_mux_groups)
+
+/**
+ * tz1090_init_mux_pins() - Initialise GPIO pin to mux group mapping.
+ *
+ * Initialises the tz1090_mux_pins[] array to be the inverse of the pin lists in
+ * each pin mux group in tz1090_mux_groups[].
+ *
+ * It is assumed that no pin mux groups overlap (share pins).
+ */
+static void __init tz1090_init_mux_pins(void)
+{
+	unsigned int g, p;
+	const struct tz1090_pingroup *grp;
+	const unsigned int *pin;
+
+	for (p = 0; p < NUM_GPIOS; ++p)
+		tz1090_mux_pins[p] = TZ1090_MUX_GROUP_MAX;
+
+	grp = tz1090_mux_groups;
+	for (g = 0, grp = tz1090_mux_groups;
+	     g < ARRAY_SIZE(tz1090_mux_groups); ++g, ++grp)
+		for (pin = grp->pins, p = 0; p < grp->npins; ++p, ++pin)
+			tz1090_mux_pins[*pin] = g;
+}
+
+/*
+ * These are the externally visible pin groups. Some of them allow group control
+ * of drive configuration. Some are just simple convenience pingroups. All the
+ * internal pin mux groups in tz1090_mux_groups[] are mirrored here with the
+ * same pins.
+ * Pseudo pin groups follow in the group numbers after this array for each GPIO
+ * pin. Any group used for muxing must have all pins belonging to the same pin
+ * mux group.
+ */
+static struct tz1090_pingroup tz1090_groups[] = {
+	/* Pin groups with drive control (with no out of place pins) */
+	/*     pg_name,		slw/schmitt/drv b */
+	DRV_PG(jtag,		11 /* 11, 22 */),
+	DRV_PG(tft,		10 /* 10, 20 */),
+	DRV_PG(scb2,		9  /*  9, 18 */),
+	DRV_PG(spi0,		7  /*  7, 14 */),
+	DRV_PG(uart,		5  /*  5, 10 */),
+	DRV_PG(scb1,		4  /*  4,  8 */),
+	DRV_PG(spi1,		3  /*  3,  6 */),
+	DRV_PG(afe,		0  /*  0,  0 */),
+
+	/*
+	 * Drive specific pin groups (with odd combinations of pins which makes
+	 * the pin group naming somewhat arbitrary)
+	 */
+	/*     pg_name,		slw/schmitt/drv b */
+	DRV_PG(drive_sdio,	8  /*  8, 16 */), /* sdio_* + sdh_* */
+	DRV_PG(drive_i2s,	6  /*  6, 12 */), /* i2s_* + clk_out1 */
+	DRV_PG(drive_scb0,	2  /*  2,  4 */), /* scb0_* + pdm_{c,d} */
+	DRV_PG(drive_pdm,	1  /*  1,  2 */), /* pdm_{a,b} + clk_out0 */
+
+	/* Convenience pin groups */
+	/*        pg_name */
+	SIMPLE_PG(uart0),
+	SIMPLE_PG(uart1),
+	SIMPLE_PG(scb0),
+	SIMPLE_PG(i2s),
+	SIMPLE_PG(sdh),
+	SIMPLE_PG(sdio),
+
+	/* pseudo-pingroups for each GPIO pin follow */
+};
+
+/**
+ * struct tz1090_pmx - Private pinctrl data
+ * @dev:	Platform device
+ * @pctl:	Pin control device
+ * @regs:	Register region
+ * @lock:	Lock protecting coherency of pin_en, gpio_en, and SELECT regs
+ * @pin_en:	Pins that have been enabled (32 pins packed into each element)
+ * @gpio_en:	GPIOs that have been enabled (32 pins packed into each element)
+ */
+struct tz1090_pmx {
+	struct device		*dev;
+	struct pinctrl_dev	*pctl;
+	void __iomem		*regs;
+	spinlock_t		lock;
+	u32			pin_en[3];
+	u32			gpio_en[3];
+};
+
+static inline u32 pmx_read(struct tz1090_pmx *pmx, u32 reg)
+{
+	return ioread32(pmx->regs + reg);
+}
+
+static inline void pmx_write(struct tz1090_pmx *pmx, u32 val, u32 reg)
+{
+	iowrite32(val, pmx->regs + reg);
+}
+
+/*
+ * Pin control operations
+ */
+
+/* each GPIO pin has it's own pseudo pingroup containing only itself */
+
+static int tz1090_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(tz1090_groups) + NUM_GPIOS;
+}
+
+static const char *tz1090_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						 unsigned int group)
+{
+	if (group < ARRAY_SIZE(tz1090_groups)) {
+		/* normal pingroup */
+		return tz1090_groups[group].name;
+	} else {
+		/* individual gpio pin pseudo-pingroup */
+		unsigned int pin = group - ARRAY_SIZE(tz1090_groups);
+		return tz1090_pins[pin].name;
+	}
+}
+
+static int tz1090_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					 unsigned int group,
+					 const unsigned int **pins,
+					 unsigned int *num_pins)
+{
+	if (group < ARRAY_SIZE(tz1090_groups)) {
+		/* normal pingroup */
+		*pins = tz1090_groups[group].pins;
+		*num_pins = tz1090_groups[group].npins;
+	} else {
+		/* individual gpio pin pseudo-pingroup */
+		unsigned int pin = group - ARRAY_SIZE(tz1090_groups);
+		*pins = &tz1090_pins[pin].number;
+		*num_pins = 1;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void tz1090_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+					struct seq_file *s,
+					unsigned int offset)
+{
+	seq_printf(s, " %s", dev_name(pctldev->dev));
+}
+#endif
+
+static int reserve_map(struct device *dev, struct pinctrl_map **map,
+		       unsigned int *reserved_maps, unsigned int *num_maps,
+		       unsigned int reserve)
+{
+	unsigned int old_num = *reserved_maps;
+	unsigned int new_num = *num_maps + reserve;
+	struct pinctrl_map *new_map;
+
+	if (old_num >= new_num)
+		return 0;
+
+	new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
+	if (!new_map) {
+		dev_err(dev, "krealloc(map) failed\n");
+		return -ENOMEM;
+	}
+
+	memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
+
+	*map = new_map;
+	*reserved_maps = new_num;
+
+	return 0;
+}
+
+static int add_map_mux(struct pinctrl_map **map, unsigned int *reserved_maps,
+		       unsigned int *num_maps, const char *group,
+		       const char *function)
+{
+	if (WARN_ON(*num_maps == *reserved_maps))
+		return -ENOSPC;
+
+	(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+	(*map)[*num_maps].data.mux.group = group;
+	(*map)[*num_maps].data.mux.function = function;
+	(*num_maps)++;
+
+	return 0;
+}
+
+static int add_map_configs(struct device *dev,
+			   struct pinctrl_map **map,
+			   unsigned int *reserved_maps, unsigned int *num_maps,
+			   const char *group, unsigned long *configs,
+			   unsigned int num_configs)
+{
+	unsigned long *dup_configs;
+
+	if (WARN_ON(*num_maps == *reserved_maps))
+		return -ENOSPC;
+
+	dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
+			      GFP_KERNEL);
+	if (!dup_configs) {
+		dev_err(dev, "kmemdup(configs) failed\n");
+		return -ENOMEM;
+	}
+
+	(*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
+	(*map)[*num_maps].data.configs.group_or_pin = group;
+	(*map)[*num_maps].data.configs.configs = dup_configs;
+	(*map)[*num_maps].data.configs.num_configs = num_configs;
+	(*num_maps)++;
+
+	return 0;
+}
+
+static void tz1090_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+				       struct pinctrl_map *map,
+				       unsigned int num_maps)
+{
+	int i;
+
+	for (i = 0; i < num_maps; i++)
+		if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
+			kfree(map[i].data.configs.configs);
+
+	kfree(map);
+}
+
+static int tz1090_pinctrl_dt_subnode_to_map(struct device *dev,
+					    struct device_node *np,
+					    struct pinctrl_map **map,
+					    unsigned int *reserved_maps,
+					    unsigned int *num_maps)
+{
+	int ret;
+	const char *function;
+	unsigned long *configs = NULL;
+	unsigned int num_configs = 0;
+	unsigned int reserve;
+	struct property *prop;
+	const char *group;
+
+	ret = of_property_read_string(np, "tz1090,function", &function);
+	if (ret < 0) {
+		/* EINVAL=missing, which is fine since it's optional */
+		if (ret != -EINVAL)
+			dev_err(dev, "could not parse property function\n");
+		function = NULL;
+	}
+
+	ret = pinconf_generic_parse_dt_config(np, &configs, &num_configs);
+	if (ret)
+		return ret;
+
+	reserve = 0;
+	if (function != NULL)
+		reserve++;
+	if (num_configs)
+		reserve++;
+	ret = of_property_count_strings(np, "tz1090,pins");
+	if (ret < 0) {
+		dev_err(dev, "could not parse property pins\n");
+		goto exit;
+	}
+	reserve *= ret;
+
+	ret = reserve_map(dev, map, reserved_maps, num_maps, reserve);
+	if (ret < 0)
+		goto exit;
+
+	of_property_for_each_string(np, "tz1090,pins", prop, group) {
+		if (function) {
+			ret = add_map_mux(map, reserved_maps, num_maps,
+					  group, function);
+			if (ret < 0)
+				goto exit;
+		}
+
+		if (num_configs) {
+			ret = add_map_configs(dev, map, reserved_maps,
+					      num_maps, group, configs,
+					      num_configs);
+			if (ret < 0)
+				goto exit;
+		}
+	}
+
+	ret = 0;
+
+exit:
+	kfree(configs);
+	return ret;
+}
+
+static int tz1090_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+					 struct device_node *np_config,
+					 struct pinctrl_map **map,
+					 unsigned int *num_maps)
+{
+	unsigned int reserved_maps;
+	struct device_node *np;
+	int ret;
+
+	reserved_maps = 0;
+	*map = NULL;
+	*num_maps = 0;
+
+	for_each_child_of_node(np_config, np) {
+		ret = tz1090_pinctrl_dt_subnode_to_map(pctldev->dev, np, map,
+						       &reserved_maps,
+						       num_maps);
+		if (ret < 0) {
+			tz1090_pinctrl_dt_free_map(pctldev, *map, *num_maps);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static struct pinctrl_ops tz1090_pinctrl_ops = {
+	.get_groups_count	= tz1090_pinctrl_get_groups_count,
+	.get_group_name		= tz1090_pinctrl_get_group_name,
+	.get_group_pins		= tz1090_pinctrl_get_group_pins,
+#ifdef CONFIG_DEBUG_FS
+	.pin_dbg_show		= tz1090_pinctrl_pin_dbg_show,
+#endif
+	.dt_node_to_map		= tz1090_pinctrl_dt_node_to_map,
+	.dt_free_map		= tz1090_pinctrl_dt_free_map,
+};
+
+/*
+ * Pin mux operations
+ */
+
+static int tz1090_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(tz1090_functions);
+}
+
+static const char *tz1090_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						unsigned int function)
+{
+	return tz1090_functions[function].name;
+}
+
+static int tz1090_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+					  unsigned int function,
+					  const char * const **groups,
+					  unsigned int * const num_groups)
+{
+	/* pingroup functions */
+	*groups = tz1090_functions[function].groups;
+	*num_groups = tz1090_functions[function].ngroups;
+	return 0;
+}
+
+/**
+ * tz1090_pinctrl_select() - update bit in SELECT register
+ * @pmx:		Pinmux data
+ * @pin:		Pin number (must be within GPIO range)
+ */
+static void tz1090_pinctrl_select(struct tz1090_pmx *pmx,
+				  unsigned int pin)
+{
+	u32 reg, reg_shift, select, val;
+	unsigned int pmx_index, pmx_shift;
+	unsigned long flags;
+
+	/* uses base 32 instead of base 30 */
+	pmx_index = pin >> 5;
+	pmx_shift = pin & 0x1f;
+
+	/* select = !perip || gpio */
+	select = ((~pmx->pin_en[pmx_index] |
+		   pmx->gpio_en[pmx_index]) >> pmx_shift) & 1;
+
+	/* find register and bit offset (base 30) */
+	reg = REG_PINCTRL_SELECT + 4*(pin / 30);
+	reg_shift = pin % 30;
+
+	/* modify gpio select bit */
+	__global_lock2(flags);
+	val = pmx_read(pmx, reg);
+	val &= ~BIT(reg_shift);
+	val |= select << reg_shift;
+	pmx_write(pmx, val, reg);
+	__global_unlock2(flags);
+}
+
+/**
+ * tz1090_pinctrl_gpio_select() - enable/disable GPIO usage for a pin
+ * @pmx:		Pinmux data
+ * @pin:		Pin number
+ * @gpio_select:	true to enable pin as GPIO,
+ *			false to leave control to whatever function is enabled
+ *
+ * Records that GPIO usage is enabled/disabled so that enabling a function
+ * doesn't override the SELECT register bit.
+ */
+static void tz1090_pinctrl_gpio_select(struct tz1090_pmx *pmx,
+				       unsigned int pin,
+				       bool gpio_select)
+{
+	unsigned int index, shift;
+	u32 gpio_en;
+
+	if (pin >= NUM_GPIOS)
+		return;
+
+	/* uses base 32 instead of base 30 */
+	index = pin >> 5;
+	shift = pin & 0x1f;
+
+	spin_lock(&pmx->lock);
+
+	/* keep a record whether gpio is selected */
+	gpio_en = pmx->gpio_en[index];
+	gpio_en &= ~BIT(shift);
+	if (gpio_select)
+		gpio_en |= BIT(shift);
+	pmx->gpio_en[index] = gpio_en;
+
+	/* update the select bit */
+	tz1090_pinctrl_select(pmx, pin);
+
+	spin_unlock(&pmx->lock);
+}
+
+/**
+ * tz1090_pinctrl_perip_select() - enable/disable peripheral interface for a pin
+ * @pmx:		Pinmux data
+ * @pin:		Pin number
+ * @perip_select:	true to enable peripheral interface when not GPIO,
+ *			false to leave pin in GPIO mode
+ *
+ * Records that peripheral usage is enabled/disabled so that SELECT register can
+ * be set appropriately when GPIO is disabled.
+ */
+static void tz1090_pinctrl_perip_select(struct tz1090_pmx *pmx,
+					unsigned int pin,
+					bool perip_select)
+{
+	unsigned int index, shift;
+	u32 pin_en;
+
+	if (pin >= NUM_GPIOS)
+		return;
+
+	/* uses base 32 instead of base 30 */
+	index = pin >> 5;
+	shift = pin & 0x1f;
+
+	spin_lock(&pmx->lock);
+
+	/* keep a record whether peripheral is selected */
+	pin_en = pmx->pin_en[index];
+	pin_en &= ~BIT(shift);
+	if (perip_select)
+		pin_en |= BIT(shift);
+	pmx->pin_en[index] = pin_en;
+
+	/* update the select bit */
+	tz1090_pinctrl_select(pmx, pin);
+
+	spin_unlock(&pmx->lock);
+}
+
+/**
+ * tz1090_pinctrl_enable_mux() - Switch a pin mux group to a function.
+ * @pmx:		Pinmux data
+ * @desc:		Pinmux description
+ * @function:		Function to switch to
+ *
+ * Enable a particular function on a pin mux group. Since pin mux descriptions
+ * are nested this function is recursive.
+ */
+static int tz1090_pinctrl_enable_mux(struct tz1090_pmx *pmx,
+				     const struct tz1090_muxdesc *desc,
+				     unsigned int function)
+{
+	const int *fit;
+	unsigned long flags;
+	int mux;
+	unsigned int func, ret;
+	u32 reg, mask;
+
+	/* find the mux value for this function, searching recursively */
+	for (mux = 0, fit = desc->funcs;
+	     mux < ARRAY_SIZE(desc->funcs); ++mux, ++fit) {
+		func = *fit;
+		if (func == function)
+			goto found_mux;
+
+		/* maybe it's a sub-mux */
+		if (func < ARRAY_SIZE(tz1090_submux) && tz1090_submux[func]) {
+			ret = tz1090_pinctrl_enable_mux(pmx,
+							tz1090_submux[func],
+							function);
+			if (!ret)
+				goto found_mux;
+		}
+	}
+
+	return -EINVAL;
+found_mux:
+
+	/* Set up the mux */
+	if (desc->width) {
+		mask = (BIT(desc->width) - 1) << desc->bit;
+		__global_lock2(flags);
+		reg = pmx_read(pmx, desc->reg);
+		reg &= ~mask;
+		reg |= (mux << desc->bit) & mask;
+		pmx_write(pmx, reg, desc->reg);
+		__global_unlock2(flags);
+	}
+
+	return 0;
+}
+
+/**
+ * tz1090_pinctrl_enable() - Enable a function on a pin group.
+ * @pctldev:		Pin control data
+ * @function:		Function index to enable
+ * @group:		Group index to enable
+ *
+ * Enable a particular function on a group of pins. The per GPIO pin pseudo pin
+ * groups can be used (in which case the pin will be enabled in peripheral mode
+ * and if it belongs to a pin mux group the mux will be switched if it isn't
+ * already in use. Some convenience pin groups can also be used in which case
+ * the effect is the same as enabling the function on each individual pin in the
+ * group.
+ */
+static int tz1090_pinctrl_enable(struct pinctrl_dev *pctldev,
+				 unsigned int function, unsigned int group)
+{
+	struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	struct tz1090_pingroup *grp;
+	int ret;
+	unsigned int pin_num, mux_group, i, npins;
+	const unsigned int *pins;
+
+	/* group of pins? */
+	if (group < ARRAY_SIZE(tz1090_groups)) {
+		grp = &tz1090_groups[group];
+		npins = grp->npins;
+		pins = grp->pins;
+		/*
+		 * All pins in the group must belong to the same mux group,
+		 * which allows us to just use the mux group of the first pin.
+		 * By explicitly listing permitted pingroups for each function
+		 * the pinmux core should ensure this is always the case.
+		 */
+	} else {
+		pin_num = group - ARRAY_SIZE(tz1090_groups);
+		npins = 1;
+		pins = &pin_num;
+	}
+	mux_group = tz1090_mux_pins[*pins];
+
+	/* no mux group, but can still be individually muxed to peripheral */
+	if (mux_group >= TZ1090_MUX_GROUP_MAX) {
+		if (function == TZ1090_MUX_PERIP)
+			goto mux_pins;
+		return -EINVAL;
+	}
+
+	/* mux group already set to a different function? */
+	grp = &tz1090_mux_groups[mux_group];
+	if (grp->func_count && grp->func != function) {
+		dev_err(pctldev->dev,
+			"%s: can't mux pin(s) to '%s', group already muxed to '%s'\n",
+			__func__, tz1090_functions[function].name,
+			tz1090_functions[grp->func].name);
+		return -EBUSY;
+	}
+
+	dev_dbg(pctldev->dev, "%s: muxing %u pin(s) in '%s' to '%s'\n",
+		__func__, npins, grp->name, tz1090_functions[function].name);
+
+	/* if first pin in mux group to be enabled, enable the group mux */
+	if (!grp->func_count) {
+		grp->func = function;
+		ret = tz1090_pinctrl_enable_mux(pmx, &grp->mux, function);
+		if (ret)
+			return ret;
+	}
+	/* add pins to ref count and mux individually to peripheral */
+	grp->func_count += npins;
+mux_pins:
+	for (i = 0; i < npins; ++i)
+		tz1090_pinctrl_perip_select(pmx, pins[i], true);
+
+	return 0;
+}
+
+/**
+ * tz1090_pinctrl_disable() - Disable a function on a pin group.
+ * @pctldev:		Pin control data
+ * @function:		Function index to disable
+ * @group:		Group index to disable
+ *
+ * Disable a particular function on a group of pins. The per GPIO pin pseudo pin
+ * groups can be used (in which case the pin will be taken out of peripheral
+ * mode. Some convenience pin groups can also be used in which case the effect
+ * is the same as enabling the function on each individual pin in the group.
+ */
+static void tz1090_pinctrl_disable(struct pinctrl_dev *pctldev,
+				   unsigned int function, unsigned int group)
+{
+	struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	struct tz1090_pingroup *grp;
+	unsigned int pin_num, mux_group, i, npins;
+	const unsigned int *pins;
+
+	/* group of pins? */
+	if (group < ARRAY_SIZE(tz1090_groups)) {
+		grp = &tz1090_groups[group];
+		npins = grp->npins;
+		pins = grp->pins;
+		/*
+		 * All pins in the group must belong to the same mux group,
+		 * which allows us to just use the mux group of the first pin.
+		 * By explicitly listing permitted pingroups for each function
+		 * the pinmux core should ensure this is always the case.
+		 */
+	} else {
+		pin_num = group - ARRAY_SIZE(tz1090_groups);
+		npins = 1;
+		pins = &pin_num;
+	}
+	mux_group = tz1090_mux_pins[*pins];
+
+	/* no mux group, but can still be individually muxed to peripheral */
+	if (mux_group >= TZ1090_MUX_GROUP_MAX) {
+		if (function == TZ1090_MUX_PERIP)
+			goto unmux_pins;
+		return;
+	}
+
+	/* mux group already set to a different function? */
+	grp = &tz1090_mux_groups[mux_group];
+	dev_dbg(pctldev->dev, "%s: unmuxing %u pin(s) in '%s' from '%s'\n",
+		__func__, npins, grp->name, tz1090_functions[function].name);
+
+	/* subtract pins from ref count and unmux individually */
+	WARN_ON(grp->func_count < npins);
+	grp->func_count -= npins;
+unmux_pins:
+	for (i = 0; i < npins; ++i)
+		tz1090_pinctrl_perip_select(pmx, pins[i], false);
+}
+
+/**
+ * tz1090_pinctrl_gpio_request_enable() - Put pin in GPIO mode.
+ * @pctldev:		Pin control data
+ * @range:		GPIO range
+ * @pin:		Pin number
+ *
+ * Puts a particular pin into GPIO mode, disabling peripheral control until it's
+ * disabled again.
+ */
+static int tz1090_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
+					      struct pinctrl_gpio_range *range,
+					      unsigned int pin)
+{
+	struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	tz1090_pinctrl_gpio_select(pmx, pin, true);
+	return 0;
+}
+
+/**
+ * tz1090_pinctrl_gpio_disable_free() - Take pin out of GPIO mode.
+ * @pctldev:		Pin control data
+ * @range:		GPIO range
+ * @pin:		Pin number
+ *
+ * Take a particular pin out of GPIO mode. If the pin is enabled for a
+ * peripheral it will return to peripheral mode.
+ */
+static void tz1090_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev,
+					     struct pinctrl_gpio_range *range,
+					     unsigned int pin)
+{
+	struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	tz1090_pinctrl_gpio_select(pmx, pin, false);
+}
+
+static struct pinmux_ops tz1090_pinmux_ops = {
+	.get_functions_count	= tz1090_pinctrl_get_funcs_count,
+	.get_function_name	= tz1090_pinctrl_get_func_name,
+	.get_function_groups	= tz1090_pinctrl_get_func_groups,
+	.enable			= tz1090_pinctrl_enable,
+	.disable		= tz1090_pinctrl_disable,
+	.gpio_request_enable	= tz1090_pinctrl_gpio_request_enable,
+	.gpio_disable_free	= tz1090_pinctrl_gpio_disable_free,
+};
+
+/*
+ * Pin config operations
+ */
+
+struct tz1090_pinconf_pullup {
+	unsigned char index;
+	unsigned char shift;
+};
+
+/* The mapping of pin to pull up/down register index and shift */
+static struct tz1090_pinconf_pullup tz1090_pinconf_pullup[] = {
+	{5, 22}, /*  0 - TZ1090_PIN_SDIO_CLK */
+	{0, 14}, /*  1 - TZ1090_PIN_SDIO_CMD */
+	{0,  6}, /*  2 - TZ1090_PIN_SDIO_D0 */
+	{0,  8}, /*  3 - TZ1090_PIN_SDIO_D1 */
+	{0, 10}, /*  4 - TZ1090_PIN_SDIO_D2 */
+	{0, 12}, /*  5 - TZ1090_PIN_SDIO_D3 */
+	{0,  2}, /*  6 - TZ1090_PIN_SDH_CD */
+	{0,  4}, /*  7 - TZ1090_PIN_SDH_WP */
+	{0, 16}, /*  8 - TZ1090_PIN_SPI0_MCLK */
+	{0, 18}, /*  9 - TZ1090_PIN_SPI0_CS0 */
+	{0, 20}, /* 10 - TZ1090_PIN_SPI0_CS1 */
+	{0, 22}, /* 11 - TZ1090_PIN_SPI0_CS2 */
+	{0, 24}, /* 12 - TZ1090_PIN_SPI0_DOUT */
+	{0, 26}, /* 13 - TZ1090_PIN_SPI0_DIN */
+	{0, 28}, /* 14 - TZ1090_PIN_SPI1_MCLK */
+	{0, 30}, /* 15 - TZ1090_PIN_SPI1_CS0 */
+	{1,  0}, /* 16 - TZ1090_PIN_SPI1_CS1 */
+	{1,  2}, /* 17 - TZ1090_PIN_SPI1_CS2 */
+	{1,  4}, /* 18 - TZ1090_PIN_SPI1_DOUT */
+	{1,  6}, /* 19 - TZ1090_PIN_SPI1_DIN */
+	{1,  8}, /* 20 - TZ1090_PIN_UART0_RXD */
+	{1, 10}, /* 21 - TZ1090_PIN_UART0_TXD */
+	{1, 12}, /* 22 - TZ1090_PIN_UART0_CTS */
+	{1, 14}, /* 23 - TZ1090_PIN_UART0_RTS */
+	{1, 16}, /* 24 - TZ1090_PIN_UART1_RXD */
+	{1, 18}, /* 25 - TZ1090_PIN_UART1_TXD */
+	{1, 20}, /* 26 - TZ1090_PIN_SCB0_SDAT */
+	{1, 22}, /* 27 - TZ1090_PIN_SCB0_SCLK */
+	{1, 24}, /* 28 - TZ1090_PIN_SCB1_SDAT */
+	{1, 26}, /* 29 - TZ1090_PIN_SCB1_SCLK */
+
+	{1, 28}, /* 30 - TZ1090_PIN_SCB2_SDAT */
+	{1, 30}, /* 31 - TZ1090_PIN_SCB2_SCLK */
+	{2,  0}, /* 32 - TZ1090_PIN_I2S_MCLK */
+	{2,  2}, /* 33 - TZ1090_PIN_I2S_BCLK_OUT */
+	{2,  4}, /* 34 - TZ1090_PIN_I2S_LRCLK_OUT */
+	{2,  6}, /* 35 - TZ1090_PIN_I2S_DOUT0 */
+	{2,  8}, /* 36 - TZ1090_PIN_I2S_DOUT1 */
+	{2, 10}, /* 37 - TZ1090_PIN_I2S_DOUT2 */
+	{2, 12}, /* 38 - TZ1090_PIN_I2S_DIN */
+	{4, 12}, /* 39 - TZ1090_PIN_PDM_A */
+	{4, 14}, /* 40 - TZ1090_PIN_PDM_B */
+	{4, 18}, /* 41 - TZ1090_PIN_PDM_C */
+	{4, 20}, /* 42 - TZ1090_PIN_PDM_D */
+	{2, 14}, /* 43 - TZ1090_PIN_TFT_RED0 */
+	{2, 16}, /* 44 - TZ1090_PIN_TFT_RED1 */
+	{2, 18}, /* 45 - TZ1090_PIN_TFT_RED2 */
+	{2, 20}, /* 46 - TZ1090_PIN_TFT_RED3 */
+	{2, 22}, /* 47 - TZ1090_PIN_TFT_RED4 */
+	{2, 24}, /* 48 - TZ1090_PIN_TFT_RED5 */
+	{2, 26}, /* 49 - TZ1090_PIN_TFT_RED6 */
+	{2, 28}, /* 50 - TZ1090_PIN_TFT_RED7 */
+	{2, 30}, /* 51 - TZ1090_PIN_TFT_GREEN0 */
+	{3,  0}, /* 52 - TZ1090_PIN_TFT_GREEN1 */
+	{3,  2}, /* 53 - TZ1090_PIN_TFT_GREEN2 */
+	{3,  4}, /* 54 - TZ1090_PIN_TFT_GREEN3 */
+	{3,  6}, /* 55 - TZ1090_PIN_TFT_GREEN4 */
+	{3,  8}, /* 56 - TZ1090_PIN_TFT_GREEN5 */
+	{3, 10}, /* 57 - TZ1090_PIN_TFT_GREEN6 */
+	{3, 12}, /* 58 - TZ1090_PIN_TFT_GREEN7 */
+	{3, 14}, /* 59 - TZ1090_PIN_TFT_BLUE0 */
+
+	{3, 16}, /* 60 - TZ1090_PIN_TFT_BLUE1 */
+	{3, 18}, /* 61 - TZ1090_PIN_TFT_BLUE2 */
+	{3, 20}, /* 62 - TZ1090_PIN_TFT_BLUE3 */
+	{3, 22}, /* 63 - TZ1090_PIN_TFT_BLUE4 */
+	{3, 24}, /* 64 - TZ1090_PIN_TFT_BLUE5 */
+	{3, 26}, /* 65 - TZ1090_PIN_TFT_BLUE6 */
+	{3, 28}, /* 66 - TZ1090_PIN_TFT_BLUE7 */
+	{3, 30}, /* 67 - TZ1090_PIN_TFT_VDDEN_GD */
+	{4,  0}, /* 68 - TZ1090_PIN_TFT_PANELCLK */
+	{4,  2}, /* 69 - TZ1090_PIN_TFT_BLANK_LS */
+	{4,  4}, /* 70 - TZ1090_PIN_TFT_VSYNC_NS */
+	{4,  6}, /* 71 - TZ1090_PIN_TFT_HSYNC_NR */
+	{4,  8}, /* 72 - TZ1090_PIN_TFT_VD12ACB */
+	{4, 10}, /* 73 - TZ1090_PIN_TFT_PWRSAVE */
+	{4, 24}, /* 74 - TZ1090_PIN_TX_ON */
+	{4, 26}, /* 75 - TZ1090_PIN_RX_ON */
+	{4, 28}, /* 76 - TZ1090_PIN_PLL_ON */
+	{4, 30}, /* 77 - TZ1090_PIN_PA_ON */
+	{5,  0}, /* 78 - TZ1090_PIN_RX_HP */
+	{5,  6}, /* 79 - TZ1090_PIN_GAIN0 */
+	{5,  8}, /* 80 - TZ1090_PIN_GAIN1 */
+	{5, 10}, /* 81 - TZ1090_PIN_GAIN2 */
+	{5, 12}, /* 82 - TZ1090_PIN_GAIN3 */
+	{5, 14}, /* 83 - TZ1090_PIN_GAIN4 */
+	{5, 16}, /* 84 - TZ1090_PIN_GAIN5 */
+	{5, 18}, /* 85 - TZ1090_PIN_GAIN6 */
+	{5, 20}, /* 86 - TZ1090_PIN_GAIN7 */
+	{5,  2}, /* 87 - TZ1090_PIN_ANT_SEL0 */
+	{5,  4}, /* 88 - TZ1090_PIN_ANT_SEL1 */
+	{0,  0}, /* 89 - TZ1090_PIN_SDH_CLK_IN */
+
+	{5, 24}, /* 90 - TZ1090_PIN_TCK */
+	{5, 26}, /* 91 - TZ1090_PIN_TRST */
+	{5, 28}, /* 92 - TZ1090_PIN_TDI */
+	{5, 30}, /* 93 - TZ1090_PIN_TDO */
+	{6,  0}, /* 94 - TZ1090_PIN_TMS */
+	{4, 16}, /* 95 - TZ1090_PIN_CLK_OUT0 */
+	{4, 22}, /* 96 - TZ1090_PIN_CLK_OUT1 */
+};
+
+static int tz1090_pinconf_reg(struct pinctrl_dev *pctldev,
+			      unsigned int pin,
+			      enum pin_config_param param,
+			      bool report_err,
+			      u32 *reg, u32 *width, u32 *mask, u32 *shift,
+			      u32 *val)
+{
+	struct tz1090_pinconf_pullup *pu;
+
+	/* All supported pins have controllable input bias */
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		*val = REG_PU_PD_TRISTATE;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		*val = REG_PU_PD_UP;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		*val = REG_PU_PD_DOWN;
+		break;
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+		*val = REG_PU_PD_REPEATER;
+		break;
+	default:
+		return -ENOTSUPP;
+	};
+
+	/* Only input bias parameters supported */
+	pu = &tz1090_pinconf_pullup[pin];
+	*reg = REG_PINCTRL_PU_PD + 4*pu->index;
+	*shift = pu->shift;
+	*width = 2;
+
+	/* Calculate field information */
+	*mask = (BIT(*width) - 1) << *shift;
+
+	return 0;
+}
+
+static int tz1090_pinconf_get(struct pinctrl_dev *pctldev,
+			      unsigned int pin, unsigned long *config)
+{
+	struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	int ret;
+	u32 reg, width, mask, shift, val, tmp, arg;
+
+	/* Get register information */
+	ret = tz1090_pinconf_reg(pctldev, pin, param, true,
+				 &reg, &width, &mask, &shift, &val);
+	if (ret < 0)
+		return ret;
+
+	/* Extract field from register */
+	tmp = pmx_read(pmx, reg);
+	arg = ((tmp & mask) >> shift) == val;
+
+	/* Config not active */
+	if (!arg)
+		return -EINVAL;
+
+	/* And pack config */
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int tz1090_pinconf_set(struct pinctrl_dev *pctldev,
+			      unsigned int pin, unsigned long config)
+{
+	struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(config);
+	unsigned int arg = pinconf_to_config_argument(config);
+	int ret;
+	u32 reg, width, mask, shift, val, tmp;
+	unsigned long flags;
+
+	dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n",
+		__func__, tz1090_pins[pin].name, config);
+
+	/* Get register information */
+	ret = tz1090_pinconf_reg(pctldev, pin, param, true,
+				 &reg, &width, &mask, &shift, &val);
+	if (ret < 0)
+		return ret;
+
+	/* Unpack argument and range check it */
+	if (arg > 1) {
+		dev_dbg(pctldev->dev, "%s: arg %u out of range\n",
+			__func__, arg);
+		return -EINVAL;
+	}
+
+	/* Write register field */
+	__global_lock2(flags);
+	tmp = pmx_read(pmx, reg);
+	tmp &= ~mask;
+	if (arg)
+		tmp |= val << shift;
+	pmx_write(pmx, tmp, reg);
+	__global_unlock2(flags);
+
+	return 0;
+}
+
+static const int tz1090_boolean_map[] = {
+	[0]		= -EINVAL,
+	[1]		= 1,
+};
+
+static const int tz1090_dr_map[] = {
+	[REG_DR_2mA]	= 2,
+	[REG_DR_4mA]	= 4,
+	[REG_DR_8mA]	= 8,
+	[REG_DR_12mA]	= 12,
+};
+
+static int tz1090_pinconf_group_reg(struct pinctrl_dev *pctldev,
+				    const struct tz1090_pingroup *g,
+				    enum pin_config_param param,
+				    bool report_err,
+				    u32 *reg, u32 *width, u32 *mask, u32 *shift,
+				    const int **map)
+{
+	/* Drive configuration applies in groups, but not to all groups. */
+	if (!g->drv) {
+		if (report_err)
+			dev_dbg(pctldev->dev,
+				"%s: group %s has no drive control\n",
+				__func__, g->name);
+		return -ENOTSUPP;
+	}
+
+	/* Find information about drive parameter's register */
+	switch (param) {
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		*reg = REG_PINCTRL_SCHMITT;
+		*width = 1;
+		*map = tz1090_boolean_map;
+		break;
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		*reg = REG_PINCTRL_DR;
+		*width = 2;
+		*map = tz1090_dr_map;
+		break;
+	default:
+		return -ENOTSUPP;
+	};
+
+	/* Calculate field information */
+	*shift = g->slw_bit * *width;
+	*mask = (BIT(*width) - 1) << *shift;
+
+	return 0;
+}
+
+static int tz1090_pinconf_group_get(struct pinctrl_dev *pctldev,
+				    unsigned int group,
+				    unsigned long *config)
+{
+	struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tz1090_pingroup *g;
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	int ret, arg;
+	unsigned int pin;
+	u32 reg, width, mask, shift, val;
+	const int *map;
+
+	if (group >= ARRAY_SIZE(tz1090_groups)) {
+		pin = group - ARRAY_SIZE(tz1090_groups);
+		return tz1090_pinconf_get(pctldev, pin, config);
+	}
+
+	g = &tz1090_groups[group];
+	if (g->npins == 1) {
+		pin = g->pins[0];
+		ret = tz1090_pinconf_get(pctldev, pin, config);
+		if (ret != -ENOTSUPP)
+			return ret;
+	}
+
+	/* Get register information */
+	ret = tz1090_pinconf_group_reg(pctldev, g, param, true,
+				       &reg, &width, &mask, &shift, &map);
+	if (ret < 0)
+		return ret;
+
+	/* Extract field from register */
+	val = pmx_read(pmx, reg);
+	arg = map[(val & mask) >> shift];
+	if (arg < 0)
+		return arg;
+
+	/* And pack config */
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev,
+				    unsigned int group, unsigned long config)
+{
+	struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tz1090_pingroup *g;
+	enum pin_config_param param = pinconf_to_config_param(config);
+	unsigned int arg, pin, i;
+	const unsigned int *pit;
+	int ret;
+	u32 reg, width, mask, shift, val;
+	unsigned long flags;
+	const int *map;
+
+	if (group >= ARRAY_SIZE(tz1090_groups)) {
+		pin = group - ARRAY_SIZE(tz1090_groups);
+		return tz1090_pinconf_set(pctldev, pin, config);
+	}
+
+	g = &tz1090_groups[group];
+	if (g->npins == 1) {
+		pin = g->pins[0];
+		ret = tz1090_pinconf_set(pctldev, pin, config);
+		if (ret != -ENOTSUPP)
+			return ret;
+	}
+
+	dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n",
+		__func__, g->name, config);
+
+	/* Get register information */
+	ret = tz1090_pinconf_group_reg(pctldev, g, param, true,
+				       &reg, &width, &mask, &shift, &map);
+	if (ret < 0) {
+		/*
+		 * Maybe we're trying to set a per-pin configuration of a group,
+		 * so do the pins one by one. This is mainly as a convenience.
+		 */
+		for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) {
+			ret = tz1090_pinconf_set(pctldev, *pit, config);
+			if (ret)
+				return ret;
+		}
+		return 0;
+	}
+
+	/* Unpack argument and map it to register value */
+	arg = pinconf_to_config_argument(config);
+	for (i = 0; i < BIT(width); ++i) {
+		if (map[i] == arg || (map[i] == -EINVAL && !arg)) {
+			/* Write register field */
+			__global_lock2(flags);
+			val = pmx_read(pmx, reg);
+			val &= ~mask;
+			val |= i << shift;
+			pmx_write(pmx, val, reg);
+			__global_unlock2(flags);
+			return 0;
+		}
+	}
+
+	dev_dbg(pctldev->dev, "%s: arg %u not supported\n",
+		__func__, arg);
+	return -EINVAL;
+}
+
+static struct pinconf_ops tz1090_pinconf_ops = {
+	.is_generic			= true,
+	.pin_config_get			= tz1090_pinconf_get,
+	.pin_config_set			= tz1090_pinconf_set,
+	.pin_config_group_get		= tz1090_pinconf_group_get,
+	.pin_config_group_set		= tz1090_pinconf_group_set,
+	.pin_config_config_dbg_show	= pinconf_generic_dump_config,
+};
+
+/*
+ * Pin control driver setup
+ */
+
+static struct pinctrl_desc tz1090_pinctrl_desc = {
+	.pctlops	= &tz1090_pinctrl_ops,
+	.pmxops		= &tz1090_pinmux_ops,
+	.confops	= &tz1090_pinconf_ops,
+	.owner		= THIS_MODULE,
+};
+
+static int tz1090_pinctrl_probe(struct platform_device *pdev)
+{
+	struct tz1090_pmx *pmx;
+	struct resource *res;
+
+	pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
+	if (!pmx) {
+		dev_err(&pdev->dev, "Can't alloc tz1090_pmx\n");
+		return -ENOMEM;
+	}
+	pmx->dev = &pdev->dev;
+	spin_lock_init(&pmx->lock);
+
+	tz1090_pinctrl_desc.name = dev_name(&pdev->dev);
+	tz1090_pinctrl_desc.pins = tz1090_pins;
+	tz1090_pinctrl_desc.npins = ARRAY_SIZE(tz1090_pins);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Missing MEM resource\n");
+		return -ENODEV;
+	}
+
+	if (!devm_request_mem_region(&pdev->dev, res->start,
+				     resource_size(res),
+				     dev_name(&pdev->dev))) {
+		dev_err(&pdev->dev,
+			"Couldn't request MEM resource\n");
+		return -ENODEV;
+	}
+
+	pmx->regs = devm_ioremap(&pdev->dev, res->start,
+				 resource_size(res));
+	if (!pmx->regs) {
+		dev_err(&pdev->dev, "Couldn't ioremap regs\n");
+		return -ENODEV;
+	}
+
+	pmx->pctl = pinctrl_register(&tz1090_pinctrl_desc, &pdev->dev, pmx);
+	if (!pmx->pctl) {
+		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+		return -ENODEV;
+	}
+
+	platform_set_drvdata(pdev, pmx);
+
+	dev_info(&pdev->dev, "TZ1090 pinctrl driver initialised\n");
+
+	return 0;
+}
+
+static int tz1090_pinctrl_remove(struct platform_device *pdev)
+{
+	struct tz1090_pmx *pmx = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(pmx->pctl);
+
+	return 0;
+}
+
+static struct of_device_id tz1090_pinctrl_of_match[] = {
+	{ .compatible = "img,tz1090-pinctrl", },
+	{ },
+};
+
+static struct platform_driver tz1090_pinctrl_driver = {
+	.driver = {
+		.name		= "tz1090-pinctrl",
+		.owner		= THIS_MODULE,
+		.of_match_table	= tz1090_pinctrl_of_match,
+	},
+	.probe	= tz1090_pinctrl_probe,
+	.remove	= tz1090_pinctrl_remove,
+};
+
+static int __init tz1090_pinctrl_init(void)
+{
+	tz1090_init_mux_pins();
+	return platform_driver_register(&tz1090_pinctrl_driver);
+}
+arch_initcall(tz1090_pinctrl_init);
+
+static void __exit tz1090_pinctrl_exit(void)
+{
+	platform_driver_unregister(&tz1090_pinctrl_driver);
+}
+module_exit(tz1090_pinctrl_exit);
+
+MODULE_AUTHOR("Imagination Technologies Ltd.");
+MODULE_DESCRIPTION("Toumaz Xenif TZ1090 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, tz1090_pinctrl_of_match);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-tz1090-pdc.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-tz1090-pdc.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-tz1090-pdc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-tz1090-pdc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1024 @@
+/*
+ * Pinctrl driver for the Toumaz Xenif TZ1090 PowerDown Controller pins
+ *
+ * Copyright (c) 2013, Imagination Technologies Ltd.
+ *
+ * Derived from Tegra code:
+ * Copyright (c) 2011-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Derived from code:
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010 NVIDIA Corporation
+ * Copyright (C) 2009-2011 ST-Ericsson AB
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/slab.h>
+
+/*
+ * The registers may be shared with other threads/cores, so we need to use the
+ * metag global lock2 for atomicity.
+ */
+#include <asm/global_lock.h>
+
+#include "core.h"
+#include "pinconf.h"
+
+/* Register offsets from bank base address */
+#define REG_GPIO_CONTROL0	0x00
+#define REG_GPIO_CONTROL2	0x08
+
+/* Register field information */
+#define REG_GPIO_CONTROL2_PU_PD_S	16
+#define REG_GPIO_CONTROL2_PDC_POS_S	 4
+#define REG_GPIO_CONTROL2_PDC_DR_S	 2
+#define REG_GPIO_CONTROL2_PDC_SR_S	 1
+#define REG_GPIO_CONTROL2_PDC_SCHMITT_S	 0
+
+/* PU_PD field values */
+#define REG_PU_PD_TRISTATE	0
+#define REG_PU_PD_UP		1
+#define REG_PU_PD_DOWN		2
+#define REG_PU_PD_REPEATER	3
+
+/* DR field values */
+#define REG_DR_2mA		0
+#define REG_DR_4mA		1
+#define REG_DR_8mA		2
+#define REG_DR_12mA		3
+
+/**
+ * struct tz1090_pdc_function - TZ1090 PDC pinctrl mux function
+ * @name:	The name of the function, exported to pinctrl core.
+ * @groups:	An array of pin groups that may select this function.
+ * @ngroups:	The number of entries in @groups.
+ */
+struct tz1090_pdc_function {
+	const char		*name;
+	const char * const	*groups;
+	unsigned int		ngroups;
+};
+
+/**
+ * struct tz1090_pdc_pingroup - TZ1090 PDC pin group
+ * @name:	Name of pin group.
+ * @pins:	Array of pin numbers in this pin group.
+ * @npins:	Number of pins in this pin group.
+ * @func:	Function enabled by the mux.
+ * @reg:	Mux register offset.
+ * @bit:	Mux register bit.
+ * @drv:	Drive control supported, otherwise it's a mux.
+ *		This means Schmitt, Slew, and Drive strength.
+ *
+ * A representation of a group of pins (possibly just one pin) in the TZ1090
+ * PDC pin controller. Each group allows some parameter or parameters to be
+ * configured. The most common is mux function selection.
+ */
+struct tz1090_pdc_pingroup {
+	const char		*name;
+	const unsigned int	*pins;
+	unsigned int		npins;
+	int			func;
+	u16			reg;
+	u8			bit;
+	bool			drv;
+};
+
+/*
+ * All PDC pins can be GPIOs. Define these first to match how the GPIO driver
+ * names/numbers its pins.
+ */
+
+enum tz1090_pdc_pin {
+	TZ1090_PDC_PIN_GPIO0,
+	TZ1090_PDC_PIN_GPIO1,
+	TZ1090_PDC_PIN_SYS_WAKE0,
+	TZ1090_PDC_PIN_SYS_WAKE1,
+	TZ1090_PDC_PIN_SYS_WAKE2,
+	TZ1090_PDC_PIN_IR_DATA,
+	TZ1090_PDC_PIN_EXT_POWER,
+};
+
+/* Pin names */
+
+static const struct pinctrl_pin_desc tz1090_pdc_pins[] = {
+	/* PDC GPIOs */
+	PINCTRL_PIN(TZ1090_PDC_PIN_GPIO0,	"gpio0"),
+	PINCTRL_PIN(TZ1090_PDC_PIN_GPIO1,	"gpio1"),
+	PINCTRL_PIN(TZ1090_PDC_PIN_SYS_WAKE0,	"sys_wake0"),
+	PINCTRL_PIN(TZ1090_PDC_PIN_SYS_WAKE1,	"sys_wake1"),
+	PINCTRL_PIN(TZ1090_PDC_PIN_SYS_WAKE2,	"sys_wake2"),
+	PINCTRL_PIN(TZ1090_PDC_PIN_IR_DATA,	"ir_data"),
+	PINCTRL_PIN(TZ1090_PDC_PIN_EXT_POWER,	"ext_power"),
+};
+
+/* Pin group pins */
+
+static const unsigned int gpio0_pins[] = {
+	TZ1090_PDC_PIN_GPIO0,
+};
+
+static const unsigned int gpio1_pins[] = {
+	TZ1090_PDC_PIN_GPIO1,
+};
+
+static const unsigned int pdc_pins[] = {
+	TZ1090_PDC_PIN_GPIO0,
+	TZ1090_PDC_PIN_GPIO1,
+	TZ1090_PDC_PIN_SYS_WAKE0,
+	TZ1090_PDC_PIN_SYS_WAKE1,
+	TZ1090_PDC_PIN_SYS_WAKE2,
+	TZ1090_PDC_PIN_IR_DATA,
+	TZ1090_PDC_PIN_EXT_POWER,
+};
+
+/* Mux functions */
+
+enum tz1090_pdc_mux {
+	/* PDC_GPIO0 mux */
+	TZ1090_PDC_MUX_IR_MOD_STABLE_OUT,
+	/* PDC_GPIO1 mux */
+	TZ1090_PDC_MUX_IR_MOD_POWER_OUT,
+};
+
+/* Pin groups a function can be muxed to */
+
+static const char * const gpio0_groups[] = {
+	"gpio0",
+};
+
+static const char * const gpio1_groups[] = {
+	"gpio1",
+};
+
+#define FUNCTION(mux, fname, group)			\
+	[(TZ1090_PDC_MUX_ ## mux)] = {			\
+		.name = #fname,				\
+		.groups = group##_groups,		\
+		.ngroups = ARRAY_SIZE(group##_groups),	\
+	}
+
+/* Must correlate with enum tz1090_pdc_mux */
+static const struct tz1090_pdc_function tz1090_pdc_functions[] = {
+	/*	 MUX			fn			pingroups */
+	FUNCTION(IR_MOD_STABLE_OUT,	ir_mod_stable_out,	gpio0),
+	FUNCTION(IR_MOD_POWER_OUT,	ir_mod_power_out,	gpio1),
+};
+
+/**
+ * MUX_PG() - Initialise a pin group with mux control
+ * @pg_name:	Pin group name (stringified, _pins appended to get pins array)
+ * @f0:		Function 0 (TZ1090_PDC_MUX_ is prepended)
+ * @mux_r:	Mux register (REG_PINCTRL_ is prepended)
+ * @mux_b:	Bit number in register of mux field
+ */
+#define MUX_PG(pg_name, f0, mux_r, mux_b)			\
+	{							\
+		.name = #pg_name,				\
+		.pins = pg_name##_pins,				\
+		.npins = ARRAY_SIZE(pg_name##_pins),		\
+		.func = TZ1090_PDC_MUX_ ## f0,			\
+		.reg = (REG_ ## mux_r),				\
+		.bit = (mux_b),					\
+	}
+
+/**
+ * DRV_PG() - Initialise a pin group with drive control
+ * @pg_name:	Pin group name (stringified, _pins appended to get pins array)
+ */
+#define DRV_PG(pg_name)				\
+	{							\
+		.name = #pg_name,				\
+		.pins = pg_name##_pins,				\
+		.npins = ARRAY_SIZE(pg_name##_pins),		\
+		.drv = true,					\
+	}
+
+static const struct tz1090_pdc_pingroup tz1090_pdc_groups[] = {
+	/* Muxing pin groups */
+	/*     pg_name, f0,                 mux register,  mux bit */
+	MUX_PG(gpio0,   IR_MOD_STABLE_OUT,  GPIO_CONTROL0, 7),
+	MUX_PG(gpio1,   IR_MOD_POWER_OUT,   GPIO_CONTROL0, 6),
+
+	/* Drive pin groups */
+	/*     pg_name */
+	DRV_PG(pdc),
+};
+
+/**
+ * struct tz1090_pdc_pmx - Private pinctrl data
+ * @dev:	Platform device
+ * @pctl:	Pin control device
+ * @regs:	Register region
+ * @lock:	Lock protecting coherency of mux_en and gpio_en
+ * @mux_en:	Muxes that have been enabled
+ * @gpio_en:	Muxable GPIOs that have been enabled
+ */
+struct tz1090_pdc_pmx {
+	struct device		*dev;
+	struct pinctrl_dev	*pctl;
+	void __iomem		*regs;
+	spinlock_t		lock;
+	u32			mux_en;
+	u32			gpio_en;
+};
+
+static inline u32 pmx_read(struct tz1090_pdc_pmx *pmx, u32 reg)
+{
+	return ioread32(pmx->regs + reg);
+}
+
+static inline void pmx_write(struct tz1090_pdc_pmx *pmx, u32 val, u32 reg)
+{
+	iowrite32(val, pmx->regs + reg);
+}
+
+/*
+ * Pin control operations
+ */
+
+static int tz1090_pdc_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(tz1090_pdc_groups);
+}
+
+static const char *tz1090_pdc_pinctrl_get_group_name(struct pinctrl_dev *pctl,
+						     unsigned int group)
+{
+	return tz1090_pdc_groups[group].name;
+}
+
+static int tz1090_pdc_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					     unsigned int group,
+					     const unsigned int **pins,
+					     unsigned int *num_pins)
+{
+	*pins = tz1090_pdc_groups[group].pins;
+	*num_pins = tz1090_pdc_groups[group].npins;
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void tz1090_pdc_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+					    struct seq_file *s,
+					    unsigned int offset)
+{
+	seq_printf(s, " %s", dev_name(pctldev->dev));
+}
+#endif
+
+static int reserve_map(struct device *dev, struct pinctrl_map **map,
+		       unsigned int *reserved_maps, unsigned int *num_maps,
+		       unsigned int reserve)
+{
+	unsigned int old_num = *reserved_maps;
+	unsigned int new_num = *num_maps + reserve;
+	struct pinctrl_map *new_map;
+
+	if (old_num >= new_num)
+		return 0;
+
+	new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
+	if (!new_map) {
+		dev_err(dev, "krealloc(map) failed\n");
+		return -ENOMEM;
+	}
+
+	memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
+
+	*map = new_map;
+	*reserved_maps = new_num;
+
+	return 0;
+}
+
+static int add_map_mux(struct pinctrl_map **map, unsigned int *reserved_maps,
+		       unsigned int *num_maps, const char *group,
+		       const char *function)
+{
+	if (WARN_ON(*num_maps == *reserved_maps))
+		return -ENOSPC;
+
+	(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+	(*map)[*num_maps].data.mux.group = group;
+	(*map)[*num_maps].data.mux.function = function;
+	(*num_maps)++;
+
+	return 0;
+}
+
+/**
+ * get_group_selector() - returns the group selector for a group
+ * @pin_group: the pin group to look up
+ *
+ * This is the same as pinctrl_get_group_selector except it doesn't produce an
+ * error message if the group isn't found or debug messages.
+ */
+static int get_group_selector(const char *pin_group)
+{
+	unsigned int group;
+
+	for (group = 0; group < ARRAY_SIZE(tz1090_pdc_groups); ++group)
+		if (!strcmp(tz1090_pdc_groups[group].name, pin_group))
+			return group;
+
+	return -EINVAL;
+}
+
+static int add_map_configs(struct device *dev,
+			   struct pinctrl_map **map,
+			   unsigned int *reserved_maps, unsigned int *num_maps,
+			   const char *group, unsigned long *configs,
+			   unsigned int num_configs)
+{
+	unsigned long *dup_configs;
+	enum pinctrl_map_type type;
+
+	if (WARN_ON(*num_maps == *reserved_maps))
+		return -ENOSPC;
+
+	dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
+			      GFP_KERNEL);
+	if (!dup_configs) {
+		dev_err(dev, "kmemdup(configs) failed\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * We support both pins and pin groups, but we need to figure out which
+	 * one we have.
+	 */
+	if (get_group_selector(group) >= 0)
+		type = PIN_MAP_TYPE_CONFIGS_GROUP;
+	else
+		type = PIN_MAP_TYPE_CONFIGS_PIN;
+	(*map)[*num_maps].type = type;
+	(*map)[*num_maps].data.configs.group_or_pin = group;
+	(*map)[*num_maps].data.configs.configs = dup_configs;
+	(*map)[*num_maps].data.configs.num_configs = num_configs;
+	(*num_maps)++;
+
+	return 0;
+}
+
+static void tz1090_pdc_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+					   struct pinctrl_map *map,
+					   unsigned int num_maps)
+{
+	int i;
+
+	for (i = 0; i < num_maps; i++)
+		if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
+			kfree(map[i].data.configs.configs);
+
+	kfree(map);
+}
+
+static int tz1090_pdc_pinctrl_dt_subnode_to_map(struct device *dev,
+						struct device_node *np,
+						struct pinctrl_map **map,
+						unsigned int *reserved_maps,
+						unsigned int *num_maps)
+{
+	int ret;
+	const char *function;
+	unsigned long *configs = NULL;
+	unsigned int num_configs = 0;
+	unsigned int reserve;
+	struct property *prop;
+	const char *group;
+
+	ret = of_property_read_string(np, "tz1090,function", &function);
+	if (ret < 0) {
+		/* EINVAL=missing, which is fine since it's optional */
+		if (ret != -EINVAL)
+			dev_err(dev,
+				"could not parse property function\n");
+		function = NULL;
+	}
+
+	ret = pinconf_generic_parse_dt_config(np, &configs, &num_configs);
+	if (ret)
+		return ret;
+
+	reserve = 0;
+	if (function != NULL)
+		reserve++;
+	if (num_configs)
+		reserve++;
+	ret = of_property_count_strings(np, "tz1090,pins");
+	if (ret < 0) {
+		dev_err(dev, "could not parse property pins\n");
+		goto exit;
+	}
+	reserve *= ret;
+
+	ret = reserve_map(dev, map, reserved_maps, num_maps, reserve);
+	if (ret < 0)
+		goto exit;
+
+	of_property_for_each_string(np, "tz1090,pins", prop, group) {
+		if (function) {
+			ret = add_map_mux(map, reserved_maps, num_maps,
+					  group, function);
+			if (ret < 0)
+				goto exit;
+		}
+
+		if (num_configs) {
+			ret = add_map_configs(dev, map, reserved_maps,
+					      num_maps, group, configs,
+					      num_configs);
+			if (ret < 0)
+				goto exit;
+		}
+	}
+
+	ret = 0;
+
+exit:
+	kfree(configs);
+	return ret;
+}
+
+static int tz1090_pdc_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+					     struct device_node *np_config,
+					     struct pinctrl_map **map,
+					     unsigned int *num_maps)
+{
+	unsigned int reserved_maps;
+	struct device_node *np;
+	int ret;
+
+	reserved_maps = 0;
+	*map = NULL;
+	*num_maps = 0;
+
+	for_each_child_of_node(np_config, np) {
+		ret = tz1090_pdc_pinctrl_dt_subnode_to_map(pctldev->dev, np,
+							   map, &reserved_maps,
+							   num_maps);
+		if (ret < 0) {
+			tz1090_pdc_pinctrl_dt_free_map(pctldev, *map,
+						       *num_maps);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static struct pinctrl_ops tz1090_pdc_pinctrl_ops = {
+	.get_groups_count	= tz1090_pdc_pinctrl_get_groups_count,
+	.get_group_name		= tz1090_pdc_pinctrl_get_group_name,
+	.get_group_pins		= tz1090_pdc_pinctrl_get_group_pins,
+#ifdef CONFIG_DEBUG_FS
+	.pin_dbg_show		= tz1090_pdc_pinctrl_pin_dbg_show,
+#endif
+	.dt_node_to_map		= tz1090_pdc_pinctrl_dt_node_to_map,
+	.dt_free_map		= tz1090_pdc_pinctrl_dt_free_map,
+};
+
+/*
+ * Pin mux operations
+ */
+
+static int tz1090_pdc_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(tz1090_pdc_functions);
+}
+
+static const char *tz1090_pdc_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+						    unsigned int function)
+{
+	return tz1090_pdc_functions[function].name;
+}
+
+static int tz1090_pdc_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+					      unsigned int function,
+					      const char * const **groups,
+					      unsigned int * const num_groups)
+{
+	*groups = tz1090_pdc_functions[function].groups;
+	*num_groups = tz1090_pdc_functions[function].ngroups;
+
+	return 0;
+}
+
+/**
+ * tz1090_pdc_pinctrl_mux() - update mux bit
+ * @pmx:		Pinmux data
+ * @grp:		Pin mux group
+ */
+static void tz1090_pdc_pinctrl_mux(struct tz1090_pdc_pmx *pmx,
+				   const struct tz1090_pdc_pingroup *grp)
+{
+	u32 reg, select;
+	unsigned int pin_shift = grp->pins[0];
+	unsigned long flags;
+
+	/* select = mux && !gpio */
+	select = ((pmx->mux_en & ~pmx->gpio_en) >> pin_shift) & 1;
+
+	/* set up the mux */
+	__global_lock2(flags);
+	reg = pmx_read(pmx, grp->reg);
+	reg &= ~BIT(grp->bit);
+	reg |= select << grp->bit;
+	pmx_write(pmx, reg, grp->reg);
+	__global_unlock2(flags);
+}
+
+static int tz1090_pdc_pinctrl_enable(struct pinctrl_dev *pctldev,
+				     unsigned int function, unsigned int group)
+{
+	struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tz1090_pdc_pingroup *grp = &tz1090_pdc_groups[group];
+
+	dev_dbg(pctldev->dev, "%s(func=%u (%s), group=%u (%s))\n",
+		__func__,
+		function, tz1090_pdc_functions[function].name,
+		group, tz1090_pdc_groups[group].name);
+
+	/* is it even a mux? */
+	if (grp->drv)
+		return -EINVAL;
+
+	/* does this group even control the function? */
+	if (function != grp->func)
+		return -EINVAL;
+
+	/* record the pin being muxed and update mux bit */
+	spin_lock(&pmx->lock);
+	pmx->mux_en |= BIT(grp->pins[0]);
+	tz1090_pdc_pinctrl_mux(pmx, grp);
+	spin_unlock(&pmx->lock);
+	return 0;
+}
+
+static void tz1090_pdc_pinctrl_disable(struct pinctrl_dev *pctldev,
+				       unsigned int function,
+				       unsigned int group)
+{
+	struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tz1090_pdc_pingroup *grp = &tz1090_pdc_groups[group];
+
+	dev_dbg(pctldev->dev, "%s(func=%u (%s), group=%u (%s))\n",
+		__func__,
+		function, tz1090_pdc_functions[function].name,
+		group, tz1090_pdc_groups[group].name);
+
+	/* is it even a mux? */
+	if (grp->drv)
+		return;
+
+	/* does this group even control the function? */
+	if (function != grp->func)
+		return;
+
+	/* record the pin being unmuxed and update mux bit */
+	spin_lock(&pmx->lock);
+	pmx->mux_en &= ~BIT(grp->pins[0]);
+	tz1090_pdc_pinctrl_mux(pmx, grp);
+	spin_unlock(&pmx->lock);
+}
+
+static const struct tz1090_pdc_pingroup *find_mux_group(
+						struct tz1090_pdc_pmx *pmx,
+						unsigned int pin)
+{
+	const struct tz1090_pdc_pingroup *grp;
+	unsigned int group;
+
+	grp = tz1090_pdc_groups;
+	for (group = 0; group < ARRAY_SIZE(tz1090_pdc_groups); ++group, ++grp) {
+		/* only match muxes */
+		if (grp->drv)
+			continue;
+
+		/* with a matching pin */
+		if (grp->pins[0] == pin)
+			return grp;
+	}
+
+	return NULL;
+}
+
+static int tz1090_pdc_pinctrl_gpio_request_enable(
+					struct pinctrl_dev *pctldev,
+					struct pinctrl_gpio_range *range,
+					unsigned int pin)
+{
+	struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tz1090_pdc_pingroup *grp = find_mux_group(pmx, pin);
+
+	if (grp) {
+		/* record the pin in GPIO use and update mux bit */
+		spin_lock(&pmx->lock);
+		pmx->gpio_en |= BIT(pin);
+		tz1090_pdc_pinctrl_mux(pmx, grp);
+		spin_unlock(&pmx->lock);
+	}
+	return 0;
+}
+
+static void tz1090_pdc_pinctrl_gpio_disable_free(
+					struct pinctrl_dev *pctldev,
+					struct pinctrl_gpio_range *range,
+					unsigned int pin)
+{
+	struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tz1090_pdc_pingroup *grp = find_mux_group(pmx, pin);
+
+	if (grp) {
+		/* record the pin not in GPIO use and update mux bit */
+		spin_lock(&pmx->lock);
+		pmx->gpio_en &= ~BIT(pin);
+		tz1090_pdc_pinctrl_mux(pmx, grp);
+		spin_unlock(&pmx->lock);
+	}
+}
+
+static struct pinmux_ops tz1090_pdc_pinmux_ops = {
+	.get_functions_count	= tz1090_pdc_pinctrl_get_funcs_count,
+	.get_function_name	= tz1090_pdc_pinctrl_get_func_name,
+	.get_function_groups	= tz1090_pdc_pinctrl_get_func_groups,
+	.enable			= tz1090_pdc_pinctrl_enable,
+	.disable		= tz1090_pdc_pinctrl_disable,
+	.gpio_request_enable	= tz1090_pdc_pinctrl_gpio_request_enable,
+	.gpio_disable_free	= tz1090_pdc_pinctrl_gpio_disable_free,
+};
+
+/*
+ * Pin config operations
+ */
+
+static int tz1090_pdc_pinconf_reg(struct pinctrl_dev *pctldev,
+				  unsigned int pin,
+				  enum pin_config_param param,
+				  bool report_err,
+				  u32 *reg, u32 *width, u32 *mask, u32 *shift,
+				  u32 *val)
+{
+	/* Find information about parameter's register */
+	switch (param) {
+	case PIN_CONFIG_BIAS_DISABLE:
+	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+		*val = REG_PU_PD_TRISTATE;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		*val = REG_PU_PD_UP;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		*val = REG_PU_PD_DOWN;
+		break;
+	case PIN_CONFIG_BIAS_BUS_HOLD:
+		*val = REG_PU_PD_REPEATER;
+		break;
+	default:
+		return -ENOTSUPP;
+	};
+
+	/* Only input bias parameters supported */
+	*reg = REG_GPIO_CONTROL2;
+	*shift = REG_GPIO_CONTROL2_PU_PD_S + pin*2;
+	*width = 2;
+
+	/* Calculate field information */
+	*mask = (BIT(*width) - 1) << *shift;
+
+	return 0;
+}
+
+static int tz1090_pdc_pinconf_get(struct pinctrl_dev *pctldev,
+				  unsigned int pin, unsigned long *config)
+{
+	struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	int ret;
+	u32 reg, width, mask, shift, val, tmp, arg;
+
+	/* Get register information */
+	ret = tz1090_pdc_pinconf_reg(pctldev, pin, param, true,
+				     &reg, &width, &mask, &shift, &val);
+	if (ret < 0)
+		return ret;
+
+	/* Extract field from register */
+	tmp = pmx_read(pmx, reg);
+	arg = ((tmp & mask) >> shift) == val;
+
+	/* Config not active */
+	if (!arg)
+		return -EINVAL;
+
+	/* And pack config */
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int tz1090_pdc_pinconf_set(struct pinctrl_dev *pctldev,
+				  unsigned int pin, unsigned long config)
+{
+	struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(config);
+	unsigned int arg = pinconf_to_config_argument(config);
+	int ret;
+	u32 reg, width, mask, shift, val, tmp;
+	unsigned long flags;
+
+	dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n",
+		__func__, tz1090_pdc_pins[pin].name, config);
+
+	/* Get register information */
+	ret = tz1090_pdc_pinconf_reg(pctldev, pin, param, true,
+				     &reg, &width, &mask, &shift, &val);
+	if (ret < 0)
+		return ret;
+
+	/* Unpack argument and range check it */
+	if (arg > 1) {
+		dev_dbg(pctldev->dev, "%s: arg %u out of range\n",
+			__func__, arg);
+		return -EINVAL;
+	}
+
+	/* Write register field */
+	__global_lock2(flags);
+	tmp = pmx_read(pmx, reg);
+	tmp &= ~mask;
+	if (arg)
+		tmp |= val << shift;
+	pmx_write(pmx, tmp, reg);
+	__global_unlock2(flags);
+
+	return 0;
+}
+
+static const int tz1090_pdc_boolean_map[] = {
+	[0]		= -EINVAL,
+	[1]		= 1,
+};
+
+static const int tz1090_pdc_dr_map[] = {
+	[REG_DR_2mA]	= 2,
+	[REG_DR_4mA]	= 4,
+	[REG_DR_8mA]	= 8,
+	[REG_DR_12mA]	= 12,
+};
+
+static int tz1090_pdc_pinconf_group_reg(struct pinctrl_dev *pctldev,
+					const struct tz1090_pdc_pingroup *g,
+					enum pin_config_param param,
+					bool report_err, u32 *reg, u32 *width,
+					u32 *mask, u32 *shift, const int **map)
+{
+	/* Drive configuration applies in groups, but not to all groups. */
+	if (!g->drv) {
+		if (report_err)
+			dev_dbg(pctldev->dev,
+				"%s: group %s has no drive control\n",
+				__func__, g->name);
+		return -ENOTSUPP;
+	}
+
+	/* Find information about drive parameter's register */
+	*reg = REG_GPIO_CONTROL2;
+	switch (param) {
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		*shift = REG_GPIO_CONTROL2_PDC_SCHMITT_S;
+		*width = 1;
+		*map = tz1090_pdc_boolean_map;
+		break;
+	case PIN_CONFIG_DRIVE_STRENGTH:
+		*shift = REG_GPIO_CONTROL2_PDC_DR_S;
+		*width = 2;
+		*map = tz1090_pdc_dr_map;
+		break;
+	case PIN_CONFIG_LOW_POWER_MODE:
+		*shift = REG_GPIO_CONTROL2_PDC_POS_S;
+		*width = 1;
+		*map = tz1090_pdc_boolean_map;
+		break;
+	default:
+		return -ENOTSUPP;
+	};
+
+	/* Calculate field information */
+	*mask = (BIT(*width) - 1) << *shift;
+
+	return 0;
+}
+
+static int tz1090_pdc_pinconf_group_get(struct pinctrl_dev *pctldev,
+					unsigned int group,
+					unsigned long *config)
+{
+	struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tz1090_pdc_pingroup *g = &tz1090_pdc_groups[group];
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	int ret, arg;
+	u32 reg, width, mask, shift, val;
+	const int *map;
+
+	/* Get register information */
+	ret = tz1090_pdc_pinconf_group_reg(pctldev, g, param, true,
+					   &reg, &width, &mask, &shift, &map);
+	if (ret < 0)
+		return ret;
+
+	/* Extract field from register */
+	val = pmx_read(pmx, reg);
+	arg = map[(val & mask) >> shift];
+	if (arg < 0)
+		return arg;
+
+	/* And pack config */
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int tz1090_pdc_pinconf_group_set(struct pinctrl_dev *pctldev,
+					unsigned int group,
+					unsigned long config)
+{
+	struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tz1090_pdc_pingroup *g = &tz1090_pdc_groups[group];
+	enum pin_config_param param = pinconf_to_config_param(config);
+	const unsigned int *pit;
+	unsigned int i;
+	int ret, arg;
+	u32 reg, width, mask, shift, val;
+	unsigned long flags;
+	const int *map;
+
+	dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n",
+		__func__, g->name, config);
+
+	/* Get register information */
+	ret = tz1090_pdc_pinconf_group_reg(pctldev, g, param, true,
+					   &reg, &width, &mask, &shift, &map);
+	if (ret < 0) {
+		/*
+		 * Maybe we're trying to set a per-pin configuration of a group,
+		 * so do the pins one by one. This is mainly as a convenience.
+		 */
+		for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) {
+			ret = tz1090_pdc_pinconf_set(pctldev, *pit, config);
+			if (ret)
+				return ret;
+		}
+		return 0;
+	}
+
+	/* Unpack argument and map it to register value */
+	arg = pinconf_to_config_argument(config);
+	for (i = 0; i < BIT(width); ++i) {
+		if (map[i] == arg || (map[i] == -EINVAL && !arg)) {
+			/* Write register field */
+			__global_lock2(flags);
+			val = pmx_read(pmx, reg);
+			val &= ~mask;
+			val |= i << shift;
+			pmx_write(pmx, val, reg);
+			__global_unlock2(flags);
+			return 0;
+		}
+	}
+
+	dev_dbg(pctldev->dev, "%s: arg %u not supported\n",
+		__func__, arg);
+	return 0;
+}
+
+static struct pinconf_ops tz1090_pdc_pinconf_ops = {
+	.is_generic			= true,
+	.pin_config_get			= tz1090_pdc_pinconf_get,
+	.pin_config_set			= tz1090_pdc_pinconf_set,
+	.pin_config_group_get		= tz1090_pdc_pinconf_group_get,
+	.pin_config_group_set		= tz1090_pdc_pinconf_group_set,
+	.pin_config_config_dbg_show	= pinconf_generic_dump_config,
+};
+
+/*
+ * Pin control driver setup
+ */
+
+static struct pinctrl_desc tz1090_pdc_pinctrl_desc = {
+	.pctlops	= &tz1090_pdc_pinctrl_ops,
+	.pmxops		= &tz1090_pdc_pinmux_ops,
+	.confops	= &tz1090_pdc_pinconf_ops,
+	.owner		= THIS_MODULE,
+};
+
+static int tz1090_pdc_pinctrl_probe(struct platform_device *pdev)
+{
+	struct tz1090_pdc_pmx *pmx;
+	struct resource *res;
+
+	pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
+	if (!pmx) {
+		dev_err(&pdev->dev, "Can't alloc tz1090_pdc_pmx\n");
+		return -ENOMEM;
+	}
+	pmx->dev = &pdev->dev;
+	spin_lock_init(&pmx->lock);
+
+	tz1090_pdc_pinctrl_desc.name = dev_name(&pdev->dev);
+	tz1090_pdc_pinctrl_desc.pins = tz1090_pdc_pins;
+	tz1090_pdc_pinctrl_desc.npins = ARRAY_SIZE(tz1090_pdc_pins);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Missing MEM resource\n");
+		return -ENODEV;
+	}
+
+	if (!devm_request_mem_region(&pdev->dev, res->start,
+				     resource_size(res),
+				     dev_name(&pdev->dev))) {
+		dev_err(&pdev->dev,
+			"Couldn't request MEM resource\n");
+		return -ENODEV;
+	}
+
+	pmx->regs = devm_ioremap(&pdev->dev, res->start,
+				 resource_size(res));
+	if (!pmx->regs) {
+		dev_err(&pdev->dev, "Couldn't ioremap regs\n");
+		return -ENODEV;
+	}
+
+	pmx->pctl = pinctrl_register(&tz1090_pdc_pinctrl_desc, &pdev->dev, pmx);
+	if (!pmx->pctl) {
+		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+		return -ENODEV;
+	}
+
+	platform_set_drvdata(pdev, pmx);
+
+	dev_info(&pdev->dev, "TZ1090 PDC pinctrl driver initialised\n");
+
+	return 0;
+}
+
+static int tz1090_pdc_pinctrl_remove(struct platform_device *pdev)
+{
+	struct tz1090_pdc_pmx *pmx = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(pmx->pctl);
+
+	return 0;
+}
+
+static struct of_device_id tz1090_pdc_pinctrl_of_match[] = {
+	{ .compatible = "img,tz1090-pdc-pinctrl", },
+	{ },
+};
+
+static struct platform_driver tz1090_pdc_pinctrl_driver = {
+	.driver = {
+		.name		= "tz1090-pdc-pinctrl",
+		.owner		= THIS_MODULE,
+		.of_match_table	= tz1090_pdc_pinctrl_of_match,
+	},
+	.probe	= tz1090_pdc_pinctrl_probe,
+	.remove	= tz1090_pdc_pinctrl_remove,
+};
+
+static int __init tz1090_pdc_pinctrl_init(void)
+{
+	return platform_driver_register(&tz1090_pdc_pinctrl_driver);
+}
+arch_initcall(tz1090_pdc_pinctrl_init);
+
+static void __exit tz1090_pdc_pinctrl_exit(void)
+{
+	platform_driver_unregister(&tz1090_pdc_pinctrl_driver);
+}
+module_exit(tz1090_pdc_pinctrl_exit);
+
+MODULE_AUTHOR("Imagination Technologies Ltd.");
+MODULE_DESCRIPTION("Toumaz Xenif TZ1090 PDC pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, tz1090_pdc_pinctrl_of_match);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-u300.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-u300.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-u300.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-u300.c	2013-08-25 20:43:22.000000000 -0400
@@ -1100,15 +1100,21 @@ static int u300_pmx_remove(struct platfo
 	struct u300_pmx *upmx = platform_get_drvdata(pdev);
 
 	pinctrl_unregister(upmx->pctl);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
 
+static const struct of_device_id u300_pinctrl_match[] = {
+	{ .compatible = "stericsson,pinctrl-u300" },
+	{},
+};
+
+
 static struct platform_driver u300_pmx_driver = {
 	.driver = {
 		.name = DRIVER_NAME,
 		.owner = THIS_MODULE,
+		.of_match_table = u300_pinctrl_match,
 	},
 	.probe = u300_pmx_probe,
 	.remove = u300_pmx_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-vf610.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-vf610.c
--- linux-libre-3.10-gnu/drivers/pinctrl/pinctrl-vf610.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/pinctrl-vf610.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,338 @@
+/*
+ * VF610 pinctrl driver based on imx pinmux and pinconf core
+ *
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-imx.h"
+
+enum vf610_pads {
+	VF610_PAD_PTA6 = 0,
+	VF610_PAD_PTA8 = 1,
+	VF610_PAD_PTA9 = 2,
+	VF610_PAD_PTA10 = 3,
+	VF610_PAD_PTA11 = 4,
+	VF610_PAD_PTA12 = 5,
+	VF610_PAD_PTA16 = 6,
+	VF610_PAD_PTA17 = 7,
+	VF610_PAD_PTA18 = 8,
+	VF610_PAD_PTA19 = 9,
+	VF610_PAD_PTA20 = 10,
+	VF610_PAD_PTA21 = 11,
+	VF610_PAD_PTA22 = 12,
+	VF610_PAD_PTA23 = 13,
+	VF610_PAD_PTA24 = 14,
+	VF610_PAD_PTA25 = 15,
+	VF610_PAD_PTA26 = 16,
+	VF610_PAD_PTA27 = 17,
+	VF610_PAD_PTA28 = 18,
+	VF610_PAD_PTA29 = 19,
+	VF610_PAD_PTA30 = 20,
+	VF610_PAD_PTA31 = 21,
+	VF610_PAD_PTB0 = 22,
+	VF610_PAD_PTB1 = 23,
+	VF610_PAD_PTB2 = 24,
+	VF610_PAD_PTB3 = 25,
+	VF610_PAD_PTB4 = 26,
+	VF610_PAD_PTB5 = 27,
+	VF610_PAD_PTB6 = 28,
+	VF610_PAD_PTB7 = 29,
+	VF610_PAD_PTB8 = 30,
+	VF610_PAD_PTB9 = 31,
+	VF610_PAD_PTB10 = 32,
+	VF610_PAD_PTB11 = 33,
+	VF610_PAD_PTB12 = 34,
+	VF610_PAD_PTB13 = 35,
+	VF610_PAD_PTB14 = 36,
+	VF610_PAD_PTB15 = 37,
+	VF610_PAD_PTB16 = 38,
+	VF610_PAD_PTB17 = 39,
+	VF610_PAD_PTB18 = 40,
+	VF610_PAD_PTB19 = 41,
+	VF610_PAD_PTB20 = 42,
+	VF610_PAD_PTB21 = 43,
+	VF610_PAD_PTB22 = 44,
+	VF610_PAD_PTC0 = 45,
+	VF610_PAD_PTC1 = 46,
+	VF610_PAD_PTC2 = 47,
+	VF610_PAD_PTC3 = 48,
+	VF610_PAD_PTC4 = 49,
+	VF610_PAD_PTC5 = 50,
+	VF610_PAD_PTC6 = 51,
+	VF610_PAD_PTC7 = 52,
+	VF610_PAD_PTC8 = 53,
+	VF610_PAD_PTC9 = 54,
+	VF610_PAD_PTC10 = 55,
+	VF610_PAD_PTC11 = 56,
+	VF610_PAD_PTC12 = 57,
+	VF610_PAD_PTC13 = 58,
+	VF610_PAD_PTC14 = 59,
+	VF610_PAD_PTC15 = 60,
+	VF610_PAD_PTC16 = 61,
+	VF610_PAD_PTC17 = 62,
+	VF610_PAD_PTD31 = 63,
+	VF610_PAD_PTD30 = 64,
+	VF610_PAD_PTD29 = 65,
+	VF610_PAD_PTD28 = 66,
+	VF610_PAD_PTD27 = 67,
+	VF610_PAD_PTD26 = 68,
+	VF610_PAD_PTD25 = 69,
+	VF610_PAD_PTD24 = 70,
+	VF610_PAD_PTD23 = 71,
+	VF610_PAD_PTD22 = 72,
+	VF610_PAD_PTD21 = 73,
+	VF610_PAD_PTD20 = 74,
+	VF610_PAD_PTD19 = 75,
+	VF610_PAD_PTD18 = 76,
+	VF610_PAD_PTD17 = 77,
+	VF610_PAD_PTD16 = 78,
+	VF610_PAD_PTD0 = 79,
+	VF610_PAD_PTD1 = 80,
+	VF610_PAD_PTD2 = 81,
+	VF610_PAD_PTD3 = 82,
+	VF610_PAD_PTD4 = 83,
+	VF610_PAD_PTD5 = 84,
+	VF610_PAD_PTD6 = 85,
+	VF610_PAD_PTD7 = 86,
+	VF610_PAD_PTD8 = 87,
+	VF610_PAD_PTD9 = 88,
+	VF610_PAD_PTD10 = 89,
+	VF610_PAD_PTD11 = 90,
+	VF610_PAD_PTD12 = 91,
+	VF610_PAD_PTD13 = 92,
+	VF610_PAD_PTB23 = 93,
+	VF610_PAD_PTB24 = 94,
+	VF610_PAD_PTB25 = 95,
+	VF610_PAD_PTB26 = 96,
+	VF610_PAD_PTB27 = 97,
+	VF610_PAD_PTB28 = 98,
+	VF610_PAD_PTC26 = 99,
+	VF610_PAD_PTC27 = 100,
+	VF610_PAD_PTC28 = 101,
+	VF610_PAD_PTC29 = 102,
+	VF610_PAD_PTC30 = 103,
+	VF610_PAD_PTC31 = 104,
+	VF610_PAD_PTE0 = 105,
+	VF610_PAD_PTE1 = 106,
+	VF610_PAD_PTE2 = 107,
+	VF610_PAD_PTE3 = 108,
+	VF610_PAD_PTE4 = 109,
+	VF610_PAD_PTE5 = 110,
+	VF610_PAD_PTE6 = 111,
+	VF610_PAD_PTE7 = 112,
+	VF610_PAD_PTE8 = 113,
+	VF610_PAD_PTE9 = 114,
+	VF610_PAD_PTE10 = 115,
+	VF610_PAD_PTE11 = 116,
+	VF610_PAD_PTE12 = 117,
+	VF610_PAD_PTE13 = 118,
+	VF610_PAD_PTE14 = 119,
+	VF610_PAD_PTE15 = 120,
+	VF610_PAD_PTE16 = 121,
+	VF610_PAD_PTE17 = 122,
+	VF610_PAD_PTE18 = 123,
+	VF610_PAD_PTE19 = 124,
+	VF610_PAD_PTE20 = 125,
+	VF610_PAD_PTE21 = 126,
+	VF610_PAD_PTE22 = 127,
+	VF610_PAD_PTE23 = 128,
+	VF610_PAD_PTE24 = 129,
+	VF610_PAD_PTE25 = 130,
+	VF610_PAD_PTE26 = 131,
+	VF610_PAD_PTE27 = 132,
+	VF610_PAD_PTE28 = 133,
+	VF610_PAD_PTA7 = 134,
+};
+
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc vf610_pinctrl_pads[] = {
+	IMX_PINCTRL_PIN(VF610_PAD_PTA6),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA8),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA9),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA10),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA11),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA12),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA16),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA17),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA18),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA19),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA20),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA21),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA22),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA23),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA24),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA25),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA26),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA27),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA28),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA29),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA30),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA31),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB0),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB1),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB2),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB3),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB4),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB5),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB6),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB7),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB8),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB9),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB10),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB11),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB12),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB13),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB14),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB15),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB16),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB17),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB18),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB19),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB20),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB21),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB22),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC0),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC1),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC2),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC3),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC4),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC5),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC6),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC7),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC8),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC9),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC10),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC11),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC12),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC13),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC14),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC15),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC16),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC17),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD31),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD30),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD29),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD28),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD27),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD26),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD25),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD24),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD23),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD22),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD21),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD20),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD19),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD18),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD17),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD16),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD0),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD1),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD2),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD3),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD4),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD5),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD6),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD7),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD8),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD9),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD10),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD11),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD12),
+	IMX_PINCTRL_PIN(VF610_PAD_PTD13),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB23),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB24),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB25),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB26),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB27),
+	IMX_PINCTRL_PIN(VF610_PAD_PTB28),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC26),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC27),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC28),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC29),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC30),
+	IMX_PINCTRL_PIN(VF610_PAD_PTC31),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE0),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE1),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE2),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE3),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE4),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE5),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE6),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE7),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE8),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE9),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE10),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE11),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE12),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE13),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE14),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE15),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE16),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE17),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE18),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE19),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE20),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE21),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE22),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE23),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE24),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE25),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE26),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE27),
+	IMX_PINCTRL_PIN(VF610_PAD_PTE28),
+	IMX_PINCTRL_PIN(VF610_PAD_PTA7),
+};
+
+static struct imx_pinctrl_soc_info vf610_pinctrl_info = {
+	.pins = vf610_pinctrl_pads,
+	.npins = ARRAY_SIZE(vf610_pinctrl_pads),
+	.flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG,
+};
+
+static struct of_device_id vf610_pinctrl_of_match[] = {
+	{ .compatible = "fsl,vf610-iomuxc", },
+	{ /* sentinel */ }
+};
+
+static int vf610_pinctrl_probe(struct platform_device *pdev)
+{
+	return imx_pinctrl_probe(pdev, &vf610_pinctrl_info);
+}
+
+static struct platform_driver vf610_pinctrl_driver = {
+	.driver = {
+		.name = "vf610-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(vf610_pinctrl_of_match),
+	},
+	.probe = vf610_pinctrl_probe,
+	.remove = imx_pinctrl_remove,
+};
+
+static int __init vf610_pinctrl_init(void)
+{
+	return platform_driver_register(&vf610_pinctrl_driver);
+}
+arch_initcall(vf610_pinctrl_init);
+
+static void __exit vf610_pinctrl_exit(void)
+{
+	platform_driver_unregister(&vf610_pinctrl_driver);
+}
+module_exit(vf610_pinctrl_exit);
+
+MODULE_DESCRIPTION("Freescale VF610 pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/core.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/core.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,8 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -348,14 +350,72 @@ int sh_pfc_config_mux(struct sh_pfc *pfc
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id sh_pfc_of_table[] = {
+#ifdef CONFIG_PINCTRL_PFC_R8A73A4
+	{
+		.compatible = "renesas,pfc-r8a73a4",
+		.data = &r8a73a4_pinmux_info,
+	},
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A7740
+	{
+		.compatible = "renesas,pfc-r8a7740",
+		.data = &r8a7740_pinmux_info,
+	},
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A7778
+	{
+		.compatible = "renesas,pfc-r8a7778",
+		.data = &r8a7778_pinmux_info,
+	},
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A7779
+	{
+		.compatible = "renesas,pfc-r8a7779",
+		.data = &r8a7779_pinmux_info,
+	},
+#endif
+#ifdef CONFIG_PINCTRL_PFC_R8A7790
+	{
+		.compatible = "renesas,pfc-r8a7790",
+		.data = &r8a7790_pinmux_info,
+	},
+#endif
+#ifdef CONFIG_PINCTRL_PFC_SH7372
+	{
+		.compatible = "renesas,pfc-sh7372",
+		.data = &sh7372_pinmux_info,
+	},
+#endif
+#ifdef CONFIG_PINCTRL_PFC_SH73A0
+	{
+		.compatible = "renesas,pfc-sh73a0",
+		.data = &sh73a0_pinmux_info,
+	},
+#endif
+	{ },
+};
+MODULE_DEVICE_TABLE(of, sh_pfc_of_table);
+#endif
+
 static int sh_pfc_probe(struct platform_device *pdev)
 {
+	const struct platform_device_id *platid = platform_get_device_id(pdev);
+#ifdef CONFIG_OF
+	struct device_node *np = pdev->dev.of_node;
+#endif
 	const struct sh_pfc_soc_info *info;
 	struct sh_pfc *pfc;
 	int ret;
 
-	info = pdev->id_entry->driver_data
-	      ? (void *)pdev->id_entry->driver_data : pdev->dev.platform_data;
+#ifdef CONFIG_OF
+	if (np)
+		info = of_match_device(sh_pfc_of_table, &pdev->dev)->data;
+	else
+#endif
+		info = platid ? (const void *)platid->driver_data : NULL;
+
 	if (info == NULL)
 		return -ENODEV;
 
@@ -372,6 +432,12 @@ static int sh_pfc_probe(struct platform_
 
 	spin_lock_init(&pfc->lock);
 
+	if (info->ops && info->ops->init) {
+		ret = info->ops->init(pfc);
+		if (ret < 0)
+			return ret;
+	}
+
 	pinctrl_provide_dummies();
 
 	/*
@@ -379,7 +445,7 @@ static int sh_pfc_probe(struct platform_
 	 */
 	ret = sh_pfc_register_pinctrl(pfc);
 	if (unlikely(ret != 0))
-		return ret;
+		goto error;
 
 #ifdef CONFIG_GPIO_SH_PFC
 	/*
@@ -401,6 +467,11 @@ static int sh_pfc_probe(struct platform_
 	dev_info(pfc->dev, "%s support registered\n", info->name);
 
 	return 0;
+
+error:
+	if (info->ops && info->ops->exit)
+		info->ops->exit(pfc);
+	return ret;
 }
 
 static int sh_pfc_remove(struct platform_device *pdev)
@@ -412,6 +483,9 @@ static int sh_pfc_remove(struct platform
 #endif
 	sh_pfc_unregister_pinctrl(pfc);
 
+	if (pfc->info->ops && pfc->info->ops->exit)
+		pfc->info->ops->exit(pfc);
+
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
@@ -424,9 +498,15 @@ static const struct platform_device_id s
 #ifdef CONFIG_PINCTRL_PFC_R8A7740
 	{ "pfc-r8a7740", (kernel_ulong_t)&r8a7740_pinmux_info },
 #endif
+#ifdef CONFIG_PINCTRL_PFC_R8A7778
+	{ "pfc-r8a7778", (kernel_ulong_t)&r8a7778_pinmux_info },
+#endif
 #ifdef CONFIG_PINCTRL_PFC_R8A7779
 	{ "pfc-r8a7779", (kernel_ulong_t)&r8a7779_pinmux_info },
 #endif
+#ifdef CONFIG_PINCTRL_PFC_R8A7790
+	{ "pfc-r8a7790", (kernel_ulong_t)&r8a7790_pinmux_info },
+#endif
 #ifdef CONFIG_PINCTRL_PFC_SH7203
 	{ "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info },
 #endif
@@ -481,6 +561,7 @@ static struct platform_driver sh_pfc_dri
 	.driver		= {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(sh_pfc_of_table),
 	},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/core.h linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/core.h
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/core.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,6 +11,7 @@
 #define __SH_PFC_CORE_H__
 
 #include <linux/compiler.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 
 #include "sh_pfc.h"
@@ -27,6 +28,7 @@ struct sh_pfc_pinctrl;
 struct sh_pfc {
 	struct device *dev;
 	const struct sh_pfc_soc_info *info;
+	void *soc_data;
 	spinlock_t lock;
 
 	unsigned int num_windows;
@@ -56,7 +58,9 @@ int sh_pfc_config_mux(struct sh_pfc *pfc
 
 extern const struct sh_pfc_soc_info r8a73a4_pinmux_info;
 extern const struct sh_pfc_soc_info r8a7740_pinmux_info;
+extern const struct sh_pfc_soc_info r8a7778_pinmux_info;
 extern const struct sh_pfc_soc_info r8a7779_pinmux_info;
+extern const struct sh_pfc_soc_info r8a7790_pinmux_info;
 extern const struct sh_pfc_soc_info sh7203_pinmux_info;
 extern const struct sh_pfc_soc_info sh7264_pinmux_info;
 extern const struct sh_pfc_soc_info sh7269_pinmux_info;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/Kconfig linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/Kconfig
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -5,8 +5,6 @@
 if ARCH_SHMOBILE || SUPERH
 
 config PINCTRL_SH_PFC
-	# XXX move off the gpio dependency
-	depends on GPIOLIB
 	select GPIO_SH_PFC if ARCH_REQUIRE_GPIOLIB
 	select PINMUX
 	select PINCONF
@@ -32,11 +30,21 @@ config PINCTRL_PFC_R8A7740
 	depends on ARCH_R8A7740
 	select PINCTRL_SH_PFC
 
+config PINCTRL_PFC_R8A7778
+	def_bool y
+	depends on ARCH_R8A7778
+	select PINCTRL_SH_PFC
+
 config PINCTRL_PFC_R8A7779
 	def_bool y
 	depends on ARCH_R8A7779
 	select PINCTRL_SH_PFC
 
+config PINCTRL_PFC_R8A7790
+	def_bool y
+	depends on ARCH_R8A7790
+	select PINCTRL_SH_PFC
+
 config PINCTRL_PFC_SH7203
 	def_bool y
 	depends on CPU_SUBTYPE_SH7203
@@ -64,6 +72,7 @@ config PINCTRL_PFC_SH73A0
 	def_bool y
 	depends on ARCH_SH73A0
 	select PINCTRL_SH_PFC
+	select REGULATOR
 
 config PINCTRL_PFC_SH7720
 	def_bool y
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/Makefile linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/Makefile
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,7 +5,9 @@ endif
 obj-$(CONFIG_PINCTRL_SH_PFC)	+= sh-pfc.o
 obj-$(CONFIG_PINCTRL_PFC_R8A73A4)	+= pfc-r8a73a4.o
 obj-$(CONFIG_PINCTRL_PFC_R8A7740)	+= pfc-r8a7740.o
+obj-$(CONFIG_PINCTRL_PFC_R8A7778)	+= pfc-r8a7778.o
 obj-$(CONFIG_PINCTRL_PFC_R8A7779)	+= pfc-r8a7779.o
+obj-$(CONFIG_PINCTRL_PFC_R8A7790)	+= pfc-r8a7790.o
 obj-$(CONFIG_PINCTRL_PFC_SH7203)	+= pfc-sh7203.o
 obj-$(CONFIG_PINCTRL_PFC_SH7264)	+= pfc-sh7264.o
 obj-$(CONFIG_PINCTRL_PFC_SH7269)	+= pfc-sh7269.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c	2013-08-25 20:43:22.000000000 -0400
@@ -1488,6 +1488,66 @@ IRQC_PINS_MUX(326, 54);
 IRQC_PINS_MUX(327, 55);
 IRQC_PINS_MUX(328, 56);
 IRQC_PINS_MUX(329, 57);
+/* - MMCIF0 ----------------------------------------------------------------- */
+static const unsigned int mmc0_data1_pins[] = {
+	/* D[0] */
+	164,
+};
+static const unsigned int mmc0_data1_mux[] = {
+	MMCD0_0_MARK,
+};
+static const unsigned int mmc0_data4_pins[] = {
+	/* D[0:3] */
+	164, 165, 166, 167,
+};
+static const unsigned int mmc0_data4_mux[] = {
+	MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK,
+};
+static const unsigned int mmc0_data8_pins[] = {
+	/* D[0:7] */
+	164, 165, 166, 167, 168, 169, 170, 171,
+};
+static const unsigned int mmc0_data8_mux[] = {
+	MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK,
+	MMCD0_4_MARK, MMCD0_5_MARK, MMCD0_6_MARK, MMCD0_7_MARK,
+};
+static const unsigned int mmc0_ctrl_pins[] = {
+	/* CMD, CLK */
+	172, 173,
+};
+static const unsigned int mmc0_ctrl_mux[] = {
+	MMCCMD0_MARK, MMCCLK0_MARK,
+};
+/* - MMCIF1 ----------------------------------------------------------------- */
+static const unsigned int mmc1_data1_pins[] = {
+	/* D[0] */
+	199,
+};
+static const unsigned int mmc1_data1_mux[] = {
+	MMCD1_0_MARK,
+};
+static const unsigned int mmc1_data4_pins[] = {
+	/* D[0:3] */
+	199, 198, 197, 196,
+};
+static const unsigned int mmc1_data4_mux[] = {
+	MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK,
+};
+static const unsigned int mmc1_data8_pins[] = {
+	/* D[0:7] */
+	199, 198, 197, 196, 195, 194, 193, 192,
+};
+static const unsigned int mmc1_data8_mux[] = {
+	MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK,
+	MMCD1_4_MARK, MMCD1_5_MARK, MMCD1_6_MARK, MMCD1_7_MARK,
+};
+static const unsigned int mmc1_ctrl_pins[] = {
+	/* CMD, CLK */
+	200, 203,
+};
+static const unsigned int mmc1_ctrl_mux[] = {
+	MMCCMD1_MARK, MMCCLK1_MARK,
+};
 /* - SCIFA0 ----------------------------------------------------------------- */
 static const unsigned int scifa0_data_pins[] = {
 	/* SCIFA0_RXD, SCIFA0_TXD */
@@ -1683,6 +1743,86 @@ static const unsigned int scifb3_ctrl_b_
 static const unsigned int scifb3_ctrl_b_mux[] = {
 	SCIFB3_RTS_38_MARK, SCIFB3_CTS_39_MARK,
 };
+/* - SDHI0 ------------------------------------------------------------------ */
+static const unsigned int sdhi0_data1_pins[] = {
+	/* D0 */
+	302,
+};
+static const unsigned int sdhi0_data1_mux[] = {
+	SDHID0_0_MARK,
+};
+static const unsigned int sdhi0_data4_pins[] = {
+	/* D[0:3] */
+	302, 303, 304, 305,
+};
+static const unsigned int sdhi0_data4_mux[] = {
+	SDHID0_0_MARK, SDHID0_1_MARK, SDHID0_2_MARK, SDHID0_3_MARK,
+};
+static const unsigned int sdhi0_ctrl_pins[] = {
+	/* CLK, CMD */
+	308, 306,
+};
+static const unsigned int sdhi0_ctrl_mux[] = {
+	SDHICLK0_MARK, SDHICMD0_MARK,
+};
+static const unsigned int sdhi0_cd_pins[] = {
+	/* CD */
+	301,
+};
+static const unsigned int sdhi0_cd_mux[] = {
+	SDHICD0_MARK,
+};
+static const unsigned int sdhi0_wp_pins[] = {
+	/* WP */
+	307,
+};
+static const unsigned int sdhi0_wp_mux[] = {
+	SDHIWP0_MARK,
+};
+/* - SDHI1 ------------------------------------------------------------------ */
+static const unsigned int sdhi1_data1_pins[] = {
+	/* D0 */
+	289,
+};
+static const unsigned int sdhi1_data1_mux[] = {
+	SDHID1_0_MARK,
+};
+static const unsigned int sdhi1_data4_pins[] = {
+	/* D[0:3] */
+	289, 290, 291, 292,
+};
+static const unsigned int sdhi1_data4_mux[] = {
+	SDHID1_0_MARK, SDHID1_1_MARK, SDHID1_2_MARK, SDHID1_3_MARK,
+};
+static const unsigned int sdhi1_ctrl_pins[] = {
+	/* CLK, CMD */
+	293, 294,
+};
+static const unsigned int sdhi1_ctrl_mux[] = {
+	SDHICLK1_MARK, SDHICMD1_MARK,
+};
+/* - SDHI2 ------------------------------------------------------------------ */
+static const unsigned int sdhi2_data1_pins[] = {
+	/* D0 */
+	295,
+};
+static const unsigned int sdhi2_data1_mux[] = {
+	SDHID2_0_MARK,
+};
+static const unsigned int sdhi2_data4_pins[] = {
+	/* D[0:3] */
+	295, 296, 297, 298,
+};
+static const unsigned int sdhi2_data4_mux[] = {
+	SDHID2_0_MARK, SDHID2_1_MARK, SDHID2_2_MARK, SDHID2_3_MARK,
+};
+static const unsigned int sdhi2_ctrl_pins[] = {
+	/* CLK, CMD */
+	299, 300,
+};
+static const unsigned int sdhi2_ctrl_mux[] = {
+	SDHICLK2_MARK, SDHICMD2_MARK,
+};
 
 static const struct sh_pfc_pin_group pinmux_groups[] = {
 	SH_PFC_PIN_GROUP(irqc_irq0),
@@ -1743,6 +1883,14 @@ static const struct sh_pfc_pin_group pin
 	SH_PFC_PIN_GROUP(irqc_irq55),
 	SH_PFC_PIN_GROUP(irqc_irq56),
 	SH_PFC_PIN_GROUP(irqc_irq57),
+	SH_PFC_PIN_GROUP(mmc0_data1),
+	SH_PFC_PIN_GROUP(mmc0_data4),
+	SH_PFC_PIN_GROUP(mmc0_data8),
+	SH_PFC_PIN_GROUP(mmc0_ctrl),
+	SH_PFC_PIN_GROUP(mmc1_data1),
+	SH_PFC_PIN_GROUP(mmc1_data4),
+	SH_PFC_PIN_GROUP(mmc1_data8),
+	SH_PFC_PIN_GROUP(mmc1_ctrl),
 	SH_PFC_PIN_GROUP(scifa0_data),
 	SH_PFC_PIN_GROUP(scifa0_clk),
 	SH_PFC_PIN_GROUP(scifa0_ctrl),
@@ -1770,6 +1918,17 @@ static const struct sh_pfc_pin_group pin
 	SH_PFC_PIN_GROUP(scifb3_data_b),
 	SH_PFC_PIN_GROUP(scifb3_clk_b),
 	SH_PFC_PIN_GROUP(scifb3_ctrl_b),
+	SH_PFC_PIN_GROUP(sdhi0_data1),
+	SH_PFC_PIN_GROUP(sdhi0_data4),
+	SH_PFC_PIN_GROUP(sdhi0_ctrl),
+	SH_PFC_PIN_GROUP(sdhi0_cd),
+	SH_PFC_PIN_GROUP(sdhi0_wp),
+	SH_PFC_PIN_GROUP(sdhi1_data1),
+	SH_PFC_PIN_GROUP(sdhi1_data4),
+	SH_PFC_PIN_GROUP(sdhi1_ctrl),
+	SH_PFC_PIN_GROUP(sdhi2_data1),
+	SH_PFC_PIN_GROUP(sdhi2_data4),
+	SH_PFC_PIN_GROUP(sdhi2_ctrl),
 };
 
 static const char * const irqc_groups[] = {
@@ -1833,6 +1992,20 @@ static const char * const irqc_groups[]
 	"irqc_irq57",
 };
 
+static const char * const mmc0_groups[] = {
+	"mmc0_data1",
+	"mmc0_data4",
+	"mmc0_data8",
+	"mmc0_ctrl",
+};
+
+static const char * const mmc1_groups[] = {
+	"mmc1_data1",
+	"mmc1_data4",
+	"mmc1_data8",
+	"mmc1_ctrl",
+};
+
 static const char * const scifa0_groups[] = {
 	"scifa0_data",
 	"scifa0_clk",
@@ -1878,14 +2051,39 @@ static const char * const scifb3_groups[
 	"scifb3_ctrl_b",
 };
 
+static const char * const sdhi0_groups[] = {
+	"sdhi0_data1",
+	"sdhi0_data4",
+	"sdhi0_ctrl",
+	"sdhi0_cd",
+	"sdhi0_wp",
+};
+
+static const char * const sdhi1_groups[] = {
+	"sdhi1_data1",
+	"sdhi1_data4",
+	"sdhi1_ctrl",
+};
+
+static const char * const sdhi2_groups[] = {
+	"sdhi2_data1",
+	"sdhi2_data4",
+	"sdhi2_ctrl",
+};
+
 static const struct sh_pfc_function pinmux_functions[] = {
 	SH_PFC_FUNCTION(irqc),
+	SH_PFC_FUNCTION(mmc0),
+	SH_PFC_FUNCTION(mmc1),
 	SH_PFC_FUNCTION(scifa0),
 	SH_PFC_FUNCTION(scifa1),
 	SH_PFC_FUNCTION(scifb0),
 	SH_PFC_FUNCTION(scifb1),
 	SH_PFC_FUNCTION(scifb2),
 	SH_PFC_FUNCTION(scifb3),
+	SH_PFC_FUNCTION(sdhi0),
+	SH_PFC_FUNCTION(sdhi1),
+	SH_PFC_FUNCTION(sdhi2),
 };
 
 #undef PORTCR
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7740.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7740.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7740.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7740.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,10 +18,14 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
+#include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/pinctrl/pinconf-generic.h>
+
 #include <mach/r8a7740.h>
 #include <mach/irqs.h>
 
+#include "core.h"
 #include "sh_pfc.h"
 
 #define CPU_ALL_PORT(fn, pfx, sfx)					\
@@ -30,6 +34,29 @@
 	PORT_10(fn, pfx##20, sfx),					\
 	PORT_1(fn, pfx##210, sfx),	PORT_1(fn, pfx##211, sfx)
 
+#undef _GPIO_PORT
+#define _GPIO_PORT(gpio, sfx)						\
+	[gpio] = {							\
+		.name = __stringify(PORT##gpio),			\
+		.enum_id = PORT##gpio##_DATA,				\
+	}
+
+#define IRQC_PIN_MUX(irq, pin)						\
+static const unsigned int intc_irq##irq##_pins[] = {			\
+	pin,								\
+};									\
+static const unsigned int intc_irq##irq##_mux[] = {			\
+	IRQ##irq##_MARK,						\
+}
+
+#define IRQC_PINS_MUX(irq, idx, pin)					\
+static const unsigned int intc_irq##irq##_##idx##_pins[] = {		\
+	pin,								\
+};									\
+static const unsigned int intc_irq##irq##_##idx##_mux[] = {		\
+	IRQ##irq##_PORT##pin##_MARK,					\
+}
+
 enum {
 	PINMUX_RESERVED = 0,
 
@@ -43,16 +70,6 @@ enum {
 	PORT_ALL(IN),
 	PINMUX_INPUT_END,
 
-	/* PORT0_IN_PU -> PORT211_IN_PU */
-	PINMUX_INPUT_PULLUP_BEGIN,
-	PORT_ALL(IN_PU),
-	PINMUX_INPUT_PULLUP_END,
-
-	/* PORT0_IN_PD -> PORT211_IN_PD */
-	PINMUX_INPUT_PULLDOWN_BEGIN,
-	PORT_ALL(IN_PD),
-	PINMUX_INPUT_PULLDOWN_END,
-
 	/* PORT0_OUT -> PORT211_OUT */
 	PINMUX_OUTPUT_BEGIN,
 	PORT_ALL(OUT),
@@ -261,8 +278,6 @@ enum {
 	SCIFB_CTS_PORT173_MARK,
 
 	/* LCD0 */
-	LCDC0_SELECT_MARK,
-
 	LCD0_D0_MARK,	LCD0_D1_MARK,	LCD0_D2_MARK,	LCD0_D3_MARK,
 	LCD0_D4_MARK,	LCD0_D5_MARK,	LCD0_D6_MARK,	LCD0_D7_MARK,
 	LCD0_D8_MARK,	LCD0_D9_MARK,	LCD0_D10_MARK,	LCD0_D11_MARK,
@@ -285,8 +300,6 @@ enum {
 	LCD0_LCLK_PORT102_MARK,
 
 	/* LCD1 */
-	LCDC1_SELECT_MARK,
-
 	LCD1_D0_MARK,	LCD1_D1_MARK,	LCD1_D2_MARK,	LCD1_D3_MARK,
 	LCD1_D4_MARK,	LCD1_D5_MARK,	LCD1_D6_MARK,	LCD1_D7_MARK,
 	LCD1_D8_MARK,	LCD1_D9_MARK,	LCD1_D10_MARK,	LCD1_D11_MARK,
@@ -577,137 +590,11 @@ enum {
 	PINMUX_MARK_END,
 };
 
-static const pinmux_enum_t pinmux_data[] = {
-	/* specify valid pin states for each pin in GPIO mode */
-
-	/* I/O and Pull U/D */
-	PORT_DATA_IO_PD(0),		PORT_DATA_IO_PD(1),
-	PORT_DATA_IO_PD(2),		PORT_DATA_IO_PD(3),
-	PORT_DATA_IO_PD(4),		PORT_DATA_IO_PD(5),
-	PORT_DATA_IO_PD(6),		PORT_DATA_IO(7),
-	PORT_DATA_IO(8),		PORT_DATA_IO(9),
-
-	PORT_DATA_IO_PD(10),		PORT_DATA_IO_PD(11),
-	PORT_DATA_IO_PD(12),		PORT_DATA_IO_PU_PD(13),
-	PORT_DATA_IO_PD(14),		PORT_DATA_IO_PD(15),
-	PORT_DATA_IO_PD(16),		PORT_DATA_IO_PD(17),
-	PORT_DATA_IO(18),		PORT_DATA_IO_PU(19),
-
-	PORT_DATA_IO_PU_PD(20),		PORT_DATA_IO_PD(21),
-	PORT_DATA_IO_PU_PD(22),		PORT_DATA_IO(23),
-	PORT_DATA_IO_PU(24),		PORT_DATA_IO_PU(25),
-	PORT_DATA_IO_PU(26),		PORT_DATA_IO_PU(27),
-	PORT_DATA_IO_PU(28),		PORT_DATA_IO_PU(29),
-
-	PORT_DATA_IO_PU(30),		PORT_DATA_IO_PD(31),
-	PORT_DATA_IO_PD(32),		PORT_DATA_IO_PD(33),
-	PORT_DATA_IO_PD(34),		PORT_DATA_IO_PU(35),
-	PORT_DATA_IO_PU(36),		PORT_DATA_IO_PD(37),
-	PORT_DATA_IO_PU(38),		PORT_DATA_IO_PD(39),
-
-	PORT_DATA_IO_PU_PD(40),		PORT_DATA_IO_PD(41),
-	PORT_DATA_IO_PD(42),		PORT_DATA_IO_PU_PD(43),
-	PORT_DATA_IO_PU_PD(44),		PORT_DATA_IO_PU_PD(45),
-	PORT_DATA_IO_PU_PD(46),		PORT_DATA_IO_PU_PD(47),
-	PORT_DATA_IO_PU_PD(48),		PORT_DATA_IO_PU_PD(49),
-
-	PORT_DATA_IO_PU_PD(50),		PORT_DATA_IO_PD(51),
-	PORT_DATA_IO_PD(52),		PORT_DATA_IO_PD(53),
-	PORT_DATA_IO_PD(54),		PORT_DATA_IO_PU_PD(55),
-	PORT_DATA_IO_PU_PD(56),		PORT_DATA_IO_PU_PD(57),
-	PORT_DATA_IO_PU_PD(58),		PORT_DATA_IO_PU_PD(59),
-
-	PORT_DATA_IO_PU_PD(60),		PORT_DATA_IO_PD(61),
-	PORT_DATA_IO_PD(62),		PORT_DATA_IO_PD(63),
-	PORT_DATA_IO_PD(64),		PORT_DATA_IO_PD(65),
-	PORT_DATA_IO_PU_PD(66),		PORT_DATA_IO_PU_PD(67),
-	PORT_DATA_IO_PU_PD(68),		PORT_DATA_IO_PU_PD(69),
-
-	PORT_DATA_IO_PU_PD(70),		PORT_DATA_IO_PU_PD(71),
-	PORT_DATA_IO_PU_PD(72),		PORT_DATA_IO_PU_PD(73),
-	PORT_DATA_IO_PU_PD(74),		PORT_DATA_IO_PU_PD(75),
-	PORT_DATA_IO_PU_PD(76),		PORT_DATA_IO_PU_PD(77),
-	PORT_DATA_IO_PU_PD(78),		PORT_DATA_IO_PU_PD(79),
-
-	PORT_DATA_IO_PU_PD(80),		PORT_DATA_IO_PU_PD(81),
-	PORT_DATA_IO(82),		PORT_DATA_IO_PU_PD(83),
-	PORT_DATA_IO(84),		PORT_DATA_IO_PD(85),
-	PORT_DATA_IO_PD(86),		PORT_DATA_IO_PD(87),
-	PORT_DATA_IO_PD(88),		PORT_DATA_IO_PD(89),
-
-	PORT_DATA_IO_PD(90),		PORT_DATA_IO_PU_PD(91),
-	PORT_DATA_IO_PU_PD(92),		PORT_DATA_IO_PU_PD(93),
-	PORT_DATA_IO_PU_PD(94),		PORT_DATA_IO_PU_PD(95),
-	PORT_DATA_IO_PU_PD(96),		PORT_DATA_IO_PU_PD(97),
-	PORT_DATA_IO_PU_PD(98),		PORT_DATA_IO_PU_PD(99),
-
-	PORT_DATA_IO_PU_PD(100),	PORT_DATA_IO(101),
-	PORT_DATA_IO_PU(102),		PORT_DATA_IO_PU_PD(103),
-	PORT_DATA_IO_PU(104),		PORT_DATA_IO_PU(105),
-	PORT_DATA_IO_PU_PD(106),	PORT_DATA_IO(107),
-	PORT_DATA_IO(108),		PORT_DATA_IO(109),
-
-	PORT_DATA_IO(110),		PORT_DATA_IO(111),
-	PORT_DATA_IO(112),		PORT_DATA_IO(113),
-	PORT_DATA_IO_PU_PD(114),	PORT_DATA_IO(115),
-	PORT_DATA_IO_PD(116),		PORT_DATA_IO_PD(117),
-	PORT_DATA_IO_PD(118),		PORT_DATA_IO_PD(119),
-
-	PORT_DATA_IO_PD(120),		PORT_DATA_IO_PD(121),
-	PORT_DATA_IO_PD(122),		PORT_DATA_IO_PD(123),
-	PORT_DATA_IO_PD(124),		PORT_DATA_IO(125),
-	PORT_DATA_IO(126),		PORT_DATA_IO(127),
-	PORT_DATA_IO(128),		PORT_DATA_IO(129),
-
-	PORT_DATA_IO(130),		PORT_DATA_IO(131),
-	PORT_DATA_IO(132),		PORT_DATA_IO(133),
-	PORT_DATA_IO(134),		PORT_DATA_IO(135),
-	PORT_DATA_IO(136),		PORT_DATA_IO(137),
-	PORT_DATA_IO(138),		PORT_DATA_IO(139),
-
-	PORT_DATA_IO(140),		PORT_DATA_IO(141),
-	PORT_DATA_IO_PU(142),		PORT_DATA_IO_PU(143),
-	PORT_DATA_IO_PU(144),		PORT_DATA_IO_PU(145),
-	PORT_DATA_IO_PU(146),		PORT_DATA_IO_PU(147),
-	PORT_DATA_IO_PU(148),		PORT_DATA_IO_PU(149),
-
-	PORT_DATA_IO_PU(150),		PORT_DATA_IO_PU(151),
-	PORT_DATA_IO_PU(152),		PORT_DATA_IO_PU(153),
-	PORT_DATA_IO_PU(154),		PORT_DATA_IO_PU(155),
-	PORT_DATA_IO_PU(156),		PORT_DATA_IO_PU(157),
-	PORT_DATA_IO_PD(158),		PORT_DATA_IO_PD(159),
-
-	PORT_DATA_IO_PU_PD(160),	PORT_DATA_IO_PD(161),
-	PORT_DATA_IO_PD(162),		PORT_DATA_IO_PD(163),
-	PORT_DATA_IO_PD(164),		PORT_DATA_IO_PD(165),
-	PORT_DATA_IO_PU(166),		PORT_DATA_IO_PU(167),
-	PORT_DATA_IO_PU(168),		PORT_DATA_IO_PU(169),
-
-	PORT_DATA_IO_PU(170),		PORT_DATA_IO_PU(171),
-	PORT_DATA_IO_PD(172),		PORT_DATA_IO_PD(173),
-	PORT_DATA_IO_PD(174),		PORT_DATA_IO_PD(175),
-	PORT_DATA_IO_PU(176),		PORT_DATA_IO_PU_PD(177),
-	PORT_DATA_IO_PU(178),		PORT_DATA_IO_PD(179),
-
-	PORT_DATA_IO_PD(180),		PORT_DATA_IO_PU(181),
-	PORT_DATA_IO_PU(182),		PORT_DATA_IO(183),
-	PORT_DATA_IO_PD(184),		PORT_DATA_IO_PD(185),
-	PORT_DATA_IO_PD(186),		PORT_DATA_IO_PD(187),
-	PORT_DATA_IO_PD(188),		PORT_DATA_IO_PD(189),
-
-	PORT_DATA_IO_PD(190),		PORT_DATA_IO_PD(191),
-	PORT_DATA_IO_PD(192),		PORT_DATA_IO_PU_PD(193),
-	PORT_DATA_IO_PU_PD(194),	PORT_DATA_IO_PD(195),
-	PORT_DATA_IO_PU_PD(196),	PORT_DATA_IO_PD(197),
-	PORT_DATA_IO_PU_PD(198),	PORT_DATA_IO_PU_PD(199),
-
-	PORT_DATA_IO_PU_PD(200),	PORT_DATA_IO_PU(201),
-	PORT_DATA_IO_PU_PD(202),	PORT_DATA_IO(203),
-	PORT_DATA_IO_PU_PD(204),	PORT_DATA_IO_PU_PD(205),
-	PORT_DATA_IO_PU_PD(206),	PORT_DATA_IO_PU_PD(207),
-	PORT_DATA_IO_PU_PD(208),	PORT_DATA_IO_PD(209),
+#define _PORT_DATA(pfx, sfx)	PORT_DATA_IO(pfx)
+#define PINMUX_DATA_GP_ALL()	CPU_ALL_PORT(_PORT_DATA, , unused)
 
-	PORT_DATA_IO_PD(210),		PORT_DATA_IO_PD(211),
+static const pinmux_enum_t pinmux_data[] = {
+	PINMUX_DATA_GP_ALL(),
 
 	/* Port0 */
 	PINMUX_DATA(DBGMDT2_MARK,		PORT0_FN1),
@@ -986,7 +873,7 @@ static const pinmux_enum_t pinmux_data[]
 	PINMUX_DATA(IRQ27_PORT57_MARK,		PORT57_FN0,	MSEL1CR_27_1),
 
 	/* Port58 */
-	PINMUX_DATA(LCD0_D0_MARK,		PORT58_FN1),
+	PINMUX_DATA(LCD0_D0_MARK,		PORT58_FN1,	MSEL3CR_6_0),
 	PINMUX_DATA(KEYOUT7_MARK,		PORT58_FN3),
 	PINMUX_DATA(KEYIN0_PORT58_MARK,		PORT58_FN4,	MSEL4CR_18_1),
 	PINMUX_DATA(DV_D0_MARK,			PORT58_FN6),
@@ -1633,10 +1520,6 @@ static const pinmux_enum_t pinmux_data[]
 	PINMUX_DATA(IRQ16_PORT211_MARK,		PORT211_FN0,	MSEL1CR_16_1),
 	PINMUX_DATA(HDMI_CEC_MARK,		PORT211_FN1),
 
-	/* LCDC select */
-	PINMUX_DATA(LCDC0_SELECT_MARK,				MSEL3CR_6_0),
-	PINMUX_DATA(LCDC1_SELECT_MARK,				MSEL3CR_6_1),
-
 	/* SDENC */
 	PINMUX_DATA(SDENC_CPG_MARK,				MSEL4CR_19_0),
 	PINMUX_DATA(SDENC_DV_CLKI_MARK,				MSEL4CR_19_1),
@@ -1654,9 +1537,565 @@ static const pinmux_enum_t pinmux_data[]
 	PINMUX_DATA(TRACEAUD_FROM_MEMC_MARK,			MSEL5CR_30_1,	MSEL5CR_29_0),
 };
 
+#define R8A7740_PIN(pin, cfgs)						\
+	{								\
+		.name = __stringify(PORT##pin),				\
+		.enum_id = PORT##pin##_DATA,				\
+		.configs = cfgs,					\
+	}
+
+#define __I		(SH_PFC_PIN_CFG_INPUT)
+#define __O		(SH_PFC_PIN_CFG_OUTPUT)
+#define __IO		(SH_PFC_PIN_CFG_INPUT | SH_PFC_PIN_CFG_OUTPUT)
+#define __PD		(SH_PFC_PIN_CFG_PULL_DOWN)
+#define __PU		(SH_PFC_PIN_CFG_PULL_UP)
+#define __PUD		(SH_PFC_PIN_CFG_PULL_DOWN | SH_PFC_PIN_CFG_PULL_UP)
+
+#define R8A7740_PIN_I_PD(pin)		R8A7740_PIN(pin, __I | __PD)
+#define R8A7740_PIN_I_PU(pin)		R8A7740_PIN(pin, __I | __PU)
+#define R8A7740_PIN_I_PU_PD(pin)		R8A7740_PIN(pin, __I | __PUD)
+#define R8A7740_PIN_IO(pin)		R8A7740_PIN(pin, __IO)
+#define R8A7740_PIN_IO_PD(pin)		R8A7740_PIN(pin, __IO | __PD)
+#define R8A7740_PIN_IO_PU(pin)		R8A7740_PIN(pin, __IO | __PU)
+#define R8A7740_PIN_IO_PU_PD(pin)	R8A7740_PIN(pin, __IO | __PUD)
+#define R8A7740_PIN_O(pin)		R8A7740_PIN(pin, __O)
+#define R8A7740_PIN_O_PU_PD(pin)		R8A7740_PIN(pin, __O | __PUD)
+
 static struct sh_pfc_pin pinmux_pins[] = {
-	GPIO_PORT_ALL(),
+	/* Table 56-1 (I/O and Pull U/D) */
+	R8A7740_PIN_IO_PD(0),		R8A7740_PIN_IO_PD(1),
+	R8A7740_PIN_IO_PD(2),		R8A7740_PIN_IO_PD(3),
+	R8A7740_PIN_IO_PD(4),		R8A7740_PIN_IO_PD(5),
+	R8A7740_PIN_IO_PD(6),		R8A7740_PIN_IO(7),
+	R8A7740_PIN_IO(8),		R8A7740_PIN_IO(9),
+	R8A7740_PIN_IO_PD(10),		R8A7740_PIN_IO_PD(11),
+	R8A7740_PIN_IO_PD(12),		R8A7740_PIN_IO_PU_PD(13),
+	R8A7740_PIN_IO_PD(14),		R8A7740_PIN_IO_PD(15),
+	R8A7740_PIN_IO_PD(16),		R8A7740_PIN_IO_PD(17),
+	R8A7740_PIN_IO(18),		R8A7740_PIN_IO_PU(19),
+	R8A7740_PIN_IO_PU_PD(20),	R8A7740_PIN_IO_PD(21),
+	R8A7740_PIN_IO_PU_PD(22),	R8A7740_PIN_IO(23),
+	R8A7740_PIN_IO_PU(24),		R8A7740_PIN_IO_PU(25),
+	R8A7740_PIN_IO_PU(26),		R8A7740_PIN_IO_PU(27),
+	R8A7740_PIN_IO_PU(28),		R8A7740_PIN_IO_PU(29),
+	R8A7740_PIN_IO_PU(30),		R8A7740_PIN_IO_PD(31),
+	R8A7740_PIN_IO_PD(32),		R8A7740_PIN_IO_PD(33),
+	R8A7740_PIN_IO_PD(34),		R8A7740_PIN_IO_PU(35),
+	R8A7740_PIN_IO_PU(36),		R8A7740_PIN_IO_PD(37),
+	R8A7740_PIN_IO_PU(38),		R8A7740_PIN_IO_PD(39),
+	R8A7740_PIN_IO_PU_PD(40),	R8A7740_PIN_IO_PD(41),
+	R8A7740_PIN_IO_PD(42),		R8A7740_PIN_IO_PU_PD(43),
+	R8A7740_PIN_IO_PU_PD(44),	R8A7740_PIN_IO_PU_PD(45),
+	R8A7740_PIN_IO_PU_PD(46),	R8A7740_PIN_IO_PU_PD(47),
+	R8A7740_PIN_IO_PU_PD(48),	R8A7740_PIN_IO_PU_PD(49),
+	R8A7740_PIN_IO_PU_PD(50),	R8A7740_PIN_IO_PD(51),
+	R8A7740_PIN_IO_PD(52),		R8A7740_PIN_IO_PD(53),
+	R8A7740_PIN_IO_PD(54),		R8A7740_PIN_IO_PU_PD(55),
+	R8A7740_PIN_IO_PU_PD(56),	R8A7740_PIN_IO_PU_PD(57),
+	R8A7740_PIN_IO_PU_PD(58),	R8A7740_PIN_IO_PU_PD(59),
+	R8A7740_PIN_IO_PU_PD(60),	R8A7740_PIN_IO_PD(61),
+	R8A7740_PIN_IO_PD(62),		R8A7740_PIN_IO_PD(63),
+	R8A7740_PIN_IO_PD(64),		R8A7740_PIN_IO_PD(65),
+	R8A7740_PIN_IO_PU_PD(66),	R8A7740_PIN_IO_PU_PD(67),
+	R8A7740_PIN_IO_PU_PD(68),	R8A7740_PIN_IO_PU_PD(69),
+	R8A7740_PIN_IO_PU_PD(70),	R8A7740_PIN_IO_PU_PD(71),
+	R8A7740_PIN_IO_PU_PD(72),	R8A7740_PIN_IO_PU_PD(73),
+	R8A7740_PIN_IO_PU_PD(74),	R8A7740_PIN_IO_PU_PD(75),
+	R8A7740_PIN_IO_PU_PD(76),	R8A7740_PIN_IO_PU_PD(77),
+	R8A7740_PIN_IO_PU_PD(78),	R8A7740_PIN_IO_PU_PD(79),
+	R8A7740_PIN_IO_PU_PD(80),	R8A7740_PIN_IO_PU_PD(81),
+	R8A7740_PIN_IO(82),		R8A7740_PIN_IO_PU_PD(83),
+	R8A7740_PIN_IO(84),		R8A7740_PIN_IO_PD(85),
+	R8A7740_PIN_IO_PD(86),		R8A7740_PIN_IO_PD(87),
+	R8A7740_PIN_IO_PD(88),		R8A7740_PIN_IO_PD(89),
+	R8A7740_PIN_IO_PD(90),		R8A7740_PIN_IO_PU_PD(91),
+	R8A7740_PIN_IO_PU_PD(92),	R8A7740_PIN_IO_PU_PD(93),
+	R8A7740_PIN_IO_PU_PD(94),	R8A7740_PIN_IO_PU_PD(95),
+	R8A7740_PIN_IO_PU_PD(96),	R8A7740_PIN_IO_PU_PD(97),
+	R8A7740_PIN_IO_PU_PD(98),	R8A7740_PIN_IO_PU_PD(99),
+	R8A7740_PIN_IO_PU_PD(100),	R8A7740_PIN_IO(101),
+	R8A7740_PIN_IO_PU(102),		R8A7740_PIN_IO_PU_PD(103),
+	R8A7740_PIN_IO_PU(104),		R8A7740_PIN_IO_PU(105),
+	R8A7740_PIN_IO_PU_PD(106),	R8A7740_PIN_IO(107),
+	R8A7740_PIN_IO(108),		R8A7740_PIN_IO(109),
+	R8A7740_PIN_IO(110),		R8A7740_PIN_IO(111),
+	R8A7740_PIN_IO(112),		R8A7740_PIN_IO(113),
+	R8A7740_PIN_IO_PU_PD(114),	R8A7740_PIN_IO(115),
+	R8A7740_PIN_IO_PD(116),		R8A7740_PIN_IO_PD(117),
+	R8A7740_PIN_IO_PD(118),		R8A7740_PIN_IO_PD(119),
+	R8A7740_PIN_IO_PD(120),		R8A7740_PIN_IO_PD(121),
+	R8A7740_PIN_IO_PD(122),		R8A7740_PIN_IO_PD(123),
+	R8A7740_PIN_IO_PD(124),		R8A7740_PIN_IO(125),
+	R8A7740_PIN_IO(126),		R8A7740_PIN_IO(127),
+	R8A7740_PIN_IO(128),		R8A7740_PIN_IO(129),
+	R8A7740_PIN_IO(130),		R8A7740_PIN_IO(131),
+	R8A7740_PIN_IO(132),		R8A7740_PIN_IO(133),
+	R8A7740_PIN_IO(134),		R8A7740_PIN_IO(135),
+	R8A7740_PIN_IO(136),		R8A7740_PIN_IO(137),
+	R8A7740_PIN_IO(138),		R8A7740_PIN_IO(139),
+	R8A7740_PIN_IO(140),		R8A7740_PIN_IO(141),
+	R8A7740_PIN_IO_PU(142),		R8A7740_PIN_IO_PU(143),
+	R8A7740_PIN_IO_PU(144),		R8A7740_PIN_IO_PU(145),
+	R8A7740_PIN_IO_PU(146),		R8A7740_PIN_IO_PU(147),
+	R8A7740_PIN_IO_PU(148),		R8A7740_PIN_IO_PU(149),
+	R8A7740_PIN_IO_PU(150),		R8A7740_PIN_IO_PU(151),
+	R8A7740_PIN_IO_PU(152),		R8A7740_PIN_IO_PU(153),
+	R8A7740_PIN_IO_PU(154),		R8A7740_PIN_IO_PU(155),
+	R8A7740_PIN_IO_PU(156),		R8A7740_PIN_IO_PU(157),
+	R8A7740_PIN_IO_PD(158),		R8A7740_PIN_IO_PD(159),
+	R8A7740_PIN_IO_PU_PD(160),	R8A7740_PIN_IO_PD(161),
+	R8A7740_PIN_IO_PD(162),		R8A7740_PIN_IO_PD(163),
+	R8A7740_PIN_IO_PD(164),		R8A7740_PIN_IO_PD(165),
+	R8A7740_PIN_IO_PU(166),		R8A7740_PIN_IO_PU(167),
+	R8A7740_PIN_IO_PU(168),		R8A7740_PIN_IO_PU(169),
+	R8A7740_PIN_IO_PU(170),		R8A7740_PIN_IO_PU(171),
+	R8A7740_PIN_IO_PD(172),		R8A7740_PIN_IO_PD(173),
+	R8A7740_PIN_IO_PD(174),		R8A7740_PIN_IO_PD(175),
+	R8A7740_PIN_IO_PU(176),		R8A7740_PIN_IO_PU_PD(177),
+	R8A7740_PIN_IO_PU(178),		R8A7740_PIN_IO_PD(179),
+	R8A7740_PIN_IO_PD(180),		R8A7740_PIN_IO_PU(181),
+	R8A7740_PIN_IO_PU(182),		R8A7740_PIN_IO(183),
+	R8A7740_PIN_IO_PD(184),		R8A7740_PIN_IO_PD(185),
+	R8A7740_PIN_IO_PD(186),		R8A7740_PIN_IO_PD(187),
+	R8A7740_PIN_IO_PD(188),		R8A7740_PIN_IO_PD(189),
+	R8A7740_PIN_IO_PD(190),		R8A7740_PIN_IO_PD(191),
+	R8A7740_PIN_IO_PD(192),		R8A7740_PIN_IO_PU_PD(193),
+	R8A7740_PIN_IO_PU_PD(194),	R8A7740_PIN_IO_PD(195),
+	R8A7740_PIN_IO_PU_PD(196),	R8A7740_PIN_IO_PD(197),
+	R8A7740_PIN_IO_PU_PD(198),	R8A7740_PIN_IO_PU_PD(199),
+	R8A7740_PIN_IO_PU_PD(200),	R8A7740_PIN_IO_PU(201),
+	R8A7740_PIN_IO_PU_PD(202),	R8A7740_PIN_IO(203),
+	R8A7740_PIN_IO_PU_PD(204),	R8A7740_PIN_IO_PU_PD(205),
+	R8A7740_PIN_IO_PU_PD(206),	R8A7740_PIN_IO_PU_PD(207),
+	R8A7740_PIN_IO_PU_PD(208),	R8A7740_PIN_IO_PD(209),
+	R8A7740_PIN_IO_PD(210),		R8A7740_PIN_IO_PD(211),
+};
+
+/* - BSC -------------------------------------------------------------------- */
+static const unsigned int bsc_data8_pins[] = {
+	/* D[0:7] */
+	157, 156, 155, 154, 153, 152, 151, 150,
+};
+static const unsigned int bsc_data8_mux[] = {
+	D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, D3_NAF3_MARK,
+	D4_NAF4_MARK, D5_NAF5_MARK, D6_NAF6_MARK, D7_NAF7_MARK,
+};
+static const unsigned int bsc_data16_pins[] = {
+	/* D[0:15] */
+	157, 156, 155, 154, 153, 152, 151, 150,
+	149, 148, 147, 146, 145, 144, 143, 142,
+};
+static const unsigned int bsc_data16_mux[] = {
+	D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, D3_NAF3_MARK,
+	D4_NAF4_MARK, D5_NAF5_MARK, D6_NAF6_MARK, D7_NAF7_MARK,
+	D8_NAF8_MARK, D9_NAF9_MARK, D10_NAF10_MARK, D11_NAF11_MARK,
+	D12_NAF12_MARK, D13_NAF13_MARK, D14_NAF14_MARK, D15_NAF15_MARK,
+};
+static const unsigned int bsc_data32_pins[] = {
+	/* D[0:31] */
+	157, 156, 155, 154, 153, 152, 151, 150,
+	149, 148, 147, 146, 145, 144, 143, 142,
+	171, 170, 169, 168, 167, 166, 173, 172,
+	165, 164, 163, 162, 161, 160, 159, 158,
+};
+static const unsigned int bsc_data32_mux[] = {
+	D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, D3_NAF3_MARK,
+	D4_NAF4_MARK, D5_NAF5_MARK, D6_NAF6_MARK, D7_NAF7_MARK,
+	D8_NAF8_MARK, D9_NAF9_MARK, D10_NAF10_MARK, D11_NAF11_MARK,
+	D12_NAF12_MARK, D13_NAF13_MARK, D14_NAF14_MARK, D15_NAF15_MARK,
+	D16_MARK, D17_MARK, D18_MARK, D19_MARK,
+	D20_MARK, D21_MARK, D22_MARK, D23_MARK,
+	D24_MARK, D25_MARK, D26_MARK, D27_MARK,
+	D28_MARK, D29_MARK, D30_MARK, D31_MARK,
+};
+static const unsigned int bsc_cs0_pins[] = {
+	/* CS */
+	109,
+};
+static const unsigned int bsc_cs0_mux[] = {
+	CS0_MARK,
+};
+static const unsigned int bsc_cs2_pins[] = {
+	/* CS */
+	110,
+};
+static const unsigned int bsc_cs2_mux[] = {
+	CS2_MARK,
+};
+static const unsigned int bsc_cs4_pins[] = {
+	/* CS */
+	111,
+};
+static const unsigned int bsc_cs4_mux[] = {
+	CS4_MARK,
+};
+static const unsigned int bsc_cs5a_0_pins[] = {
+	/* CS */
+	105,
+};
+static const unsigned int bsc_cs5a_0_mux[] = {
+	CS5A_PORT105_MARK,
+};
+static const unsigned int bsc_cs5a_1_pins[] = {
+	/* CS */
+	19,
+};
+static const unsigned int bsc_cs5a_1_mux[] = {
+	CS5A_PORT19_MARK,
+};
+static const unsigned int bsc_cs5b_pins[] = {
+	/* CS */
+	103,
+};
+static const unsigned int bsc_cs5b_mux[] = {
+	CS5B_MARK,
+};
+static const unsigned int bsc_cs6a_pins[] = {
+	/* CS */
+	104,
+};
+static const unsigned int bsc_cs6a_mux[] = {
+	CS6A_MARK,
+};
+static const unsigned int bsc_rd_we8_pins[] = {
+	/* RD, WE[0] */
+	115, 113,
+};
+static const unsigned int bsc_rd_we8_mux[] = {
+	RD_FSC_MARK, WE0_FWE_MARK,
+};
+static const unsigned int bsc_rd_we16_pins[] = {
+	/* RD, WE[0:1] */
+	115, 113, 112,
+};
+static const unsigned int bsc_rd_we16_mux[] = {
+	RD_FSC_MARK, WE0_FWE_MARK, WE1_MARK,
+};
+static const unsigned int bsc_rd_we32_pins[] = {
+	/* RD, WE[0:3] */
+	115, 113, 112, 108, 107,
+};
+static const unsigned int bsc_rd_we32_mux[] = {
+	RD_FSC_MARK, WE0_FWE_MARK, WE1_MARK, WE2_ICIORD_MARK, WE3_ICIOWR_MARK,
+};
+static const unsigned int bsc_bs_pins[] = {
+	/* BS */
+	175,
+};
+static const unsigned int bsc_bs_mux[] = {
+	BS_MARK,
+};
+static const unsigned int bsc_rdwr_pins[] = {
+	/* RDWR */
+	114,
+};
+static const unsigned int bsc_rdwr_mux[] = {
+	RDWR_MARK,
+};
+/* - CEU0 ------------------------------------------------------------------- */
+static const unsigned int ceu0_data_0_7_pins[] = {
+	/* D[0:7] */
+	34, 33, 32, 31, 30, 29, 28, 27,
+};
+static const unsigned int ceu0_data_0_7_mux[] = {
+	VIO0_D0_MARK, VIO0_D1_MARK, VIO0_D2_MARK, VIO0_D3_MARK,
+	VIO0_D4_MARK, VIO0_D5_MARK, VIO0_D6_MARK, VIO0_D7_MARK,
+};
+static const unsigned int ceu0_data_8_15_0_pins[] = {
+	/* D[8:15] */
+	182, 181, 180, 179, 178, 26, 25, 24,
+};
+static const unsigned int ceu0_data_8_15_0_mux[] = {
+	VIO0_D8_MARK, VIO0_D9_MARK, VIO0_D10_MARK, VIO0_D11_MARK,
+	VIO0_D12_MARK, VIO0_D13_PORT26_MARK, VIO0_D14_PORT25_MARK,
+	VIO0_D15_PORT24_MARK,
+};
+static const unsigned int ceu0_data_8_15_1_pins[] = {
+	/* D[8:15] */
+	182, 181, 180, 179, 178, 22, 95, 96,
+};
+static const unsigned int ceu0_data_8_15_1_mux[] = {
+	VIO0_D8_MARK, VIO0_D9_MARK, VIO0_D10_MARK, VIO0_D11_MARK,
+	VIO0_D12_MARK, VIO0_D13_PORT22_MARK, VIO0_D14_PORT95_MARK,
+	VIO0_D15_PORT96_MARK,
+};
+static const unsigned int ceu0_clk_0_pins[] = {
+	/* CKO */
+	36,
+};
+static const unsigned int ceu0_clk_0_mux[] = {
+	VIO_CKO_MARK,
+};
+static const unsigned int ceu0_clk_1_pins[] = {
+	/* CKO */
+	14,
+};
+static const unsigned int ceu0_clk_1_mux[] = {
+	VIO_CKO1_MARK,
+};
+static const unsigned int ceu0_clk_2_pins[] = {
+	/* CKO */
+	15,
+};
+static const unsigned int ceu0_clk_2_mux[] = {
+	VIO_CKO2_MARK,
+};
+static const unsigned int ceu0_sync_pins[] = {
+	/* CLK, VD, HD */
+	35, 39, 37,
+};
+static const unsigned int ceu0_sync_mux[] = {
+	VIO0_CLK_MARK, VIO0_VD_MARK, VIO0_HD_MARK,
+};
+static const unsigned int ceu0_field_pins[] = {
+	/* FIELD */
+	38,
+};
+static const unsigned int ceu0_field_mux[] = {
+	VIO0_FIELD_MARK,
+};
+/* - CEU1 ------------------------------------------------------------------- */
+static const unsigned int ceu1_data_pins[] = {
+	/* D[0:7] */
+	182, 181, 180, 179, 178, 26, 25, 24,
+};
+static const unsigned int ceu1_data_mux[] = {
+	VIO1_D0_MARK, VIO1_D1_MARK, VIO1_D2_MARK, VIO1_D3_MARK,
+	VIO1_D4_MARK, VIO1_D5_MARK, VIO1_D6_MARK, VIO1_D7_MARK,
+};
+static const unsigned int ceu1_clk_pins[] = {
+	/* CKO */
+	23,
+};
+static const unsigned int ceu1_clk_mux[] = {
+	VIO_CKO_1_MARK,
+};
+static const unsigned int ceu1_sync_pins[] = {
+	/* CLK, VD, HD */
+	197, 198, 160,
+};
+static const unsigned int ceu1_sync_mux[] = {
+	VIO1_CLK_MARK, VIO1_VD_MARK, VIO1_HD_MARK,
+};
+static const unsigned int ceu1_field_pins[] = {
+	/* FIELD */
+	21,
+};
+static const unsigned int ceu1_field_mux[] = {
+	VIO1_FIELD_MARK,
+};
+/* - FSIA ------------------------------------------------------------------- */
+static const unsigned int fsia_mclk_in_pins[] = {
+	/* CK */
+	11,
+};
+static const unsigned int fsia_mclk_in_mux[] = {
+	FSIACK_MARK,
+};
+static const unsigned int fsia_mclk_out_pins[] = {
+	/* OMC */
+	10,
+};
+static const unsigned int fsia_mclk_out_mux[] = {
+	FSIAOMC_MARK,
+};
+static const unsigned int fsia_sclk_in_pins[] = {
+	/* ILR, IBT */
+	12, 13,
+};
+static const unsigned int fsia_sclk_in_mux[] = {
+	FSIAILR_MARK, FSIAIBT_MARK,
+};
+static const unsigned int fsia_sclk_out_pins[] = {
+	/* OLR, OBT */
+	7, 8,
+};
+static const unsigned int fsia_sclk_out_mux[] = {
+	FSIAOLR_MARK, FSIAOBT_MARK,
+};
+static const unsigned int fsia_data_in_0_pins[] = {
+	/* ISLD */
+	0,
+};
+static const unsigned int fsia_data_in_0_mux[] = {
+	FSIAISLD_PORT0_MARK,
+};
+static const unsigned int fsia_data_in_1_pins[] = {
+	/* ISLD */
+	5,
+};
+static const unsigned int fsia_data_in_1_mux[] = {
+	FSIAISLD_PORT5_MARK,
+};
+static const unsigned int fsia_data_out_0_pins[] = {
+	/* OSLD */
+	9,
+};
+static const unsigned int fsia_data_out_0_mux[] = {
+	FSIAOSLD_MARK,
+};
+static const unsigned int fsia_data_out_1_pins[] = {
+	/* OSLD */
+	0,
+};
+static const unsigned int fsia_data_out_1_mux[] = {
+	FSIAOSLD1_MARK,
+};
+static const unsigned int fsia_data_out_2_pins[] = {
+	/* OSLD */
+	1,
+};
+static const unsigned int fsia_data_out_2_mux[] = {
+	FSIAOSLD2_MARK,
+};
+static const unsigned int fsia_spdif_0_pins[] = {
+	/* SPDIF */
+	9,
+};
+static const unsigned int fsia_spdif_0_mux[] = {
+	FSIASPDIF_PORT9_MARK,
+};
+static const unsigned int fsia_spdif_1_pins[] = {
+	/* SPDIF */
+	18,
 };
+static const unsigned int fsia_spdif_1_mux[] = {
+	FSIASPDIF_PORT18_MARK,
+};
+/* - FSIB ------------------------------------------------------------------- */
+static const unsigned int fsib_mclk_in_pins[] = {
+	/* CK */
+	11,
+};
+static const unsigned int fsib_mclk_in_mux[] = {
+	FSIBCK_MARK,
+};
+/* - GETHER ----------------------------------------------------------------- */
+static const unsigned int gether_rmii_pins[] = {
+	/* RXD[0:1], RX_ER, CRS_DV, TXD[0:1], TX_EN, REF_CLK, MDC, MDIO */
+	195, 196, 194, 193, 200, 201, 199, 159, 202, 208,
+};
+static const unsigned int gether_rmii_mux[] = {
+	RMII_RXD0_MARK, RMII_RXD1_MARK, RMII_RX_ER_MARK, RMII_CRS_DV_MARK,
+	RMII_TXD0_MARK, RMII_TXD1_MARK, RMII_TX_EN_MARK, RMII_REF50CK_MARK,
+	RMII_MDC_MARK, RMII_MDIO_MARK,
+};
+static const unsigned int gether_mii_pins[] = {
+	/* RXD[0:3], RX_CLK, RX_DV, RX_ER
+	 * TXD[0:3], TX_CLK, TX_EN, TX_ER
+	 * CRS, COL, MDC, MDIO,
+	 */
+	185, 186, 187, 188, 174, 161, 204,
+	171, 170, 169, 168, 184, 183, 203,
+	205, 163, 206, 207,
+};
+static const unsigned int gether_mii_mux[] = {
+	ET_ERXD0_MARK, ET_ERXD1_MARK, ET_ERXD2_MARK, ET_ERXD3_MARK,
+	ET_RX_CLK_MARK, ET_RX_DV_MARK, ET_RX_ER_MARK,
+	ET_ETXD0_MARK, ET_ETXD1_MARK, ET_ETXD2_MARK, ET_ETXD3_MARK,
+	ET_TX_CLK_MARK, ET_TX_EN_MARK, ET_TX_ER_MARK,
+	ET_CRS_MARK, ET_COL_MARK, ET_MDC_MARK, ET_MDIO_MARK,
+};
+static const unsigned int gether_gmii_pins[] = {
+	/* RXD[0:7], RX_CLK, RX_DV, RX_ER
+	 * TXD[0:7], GTX_CLK, TX_CLK, TX_EN, TX_ER
+	 * CRS, COL, MDC, MDIO, REF125CK_MARK,
+	 */
+	185, 186, 187, 188, 189, 190, 191, 192, 174, 161, 204,
+	171, 170, 169, 168, 167, 166, 173, 172, 176, 184, 183, 203,
+	205, 163, 206, 207,
+};
+static const unsigned int gether_gmii_mux[] = {
+	ET_ERXD0_MARK, ET_ERXD1_MARK, ET_ERXD2_MARK, ET_ERXD3_MARK,
+	ET_ERXD4_MARK, ET_ERXD5_MARK, ET_ERXD6_MARK, ET_ERXD7_MARK,
+	ET_RX_CLK_MARK, ET_RX_DV_MARK, ET_RX_ER_MARK,
+	ET_ETXD0_MARK, ET_ETXD1_MARK, ET_ETXD2_MARK, ET_ETXD3_MARK,
+	ET_ETXD4_MARK, ET_ETXD5_MARK, ET_ETXD6_MARK, ET_ETXD7_MARK,
+	ET_GTX_CLK_MARK, ET_TX_CLK_MARK, ET_TX_EN_MARK, ET_TX_ER_MARK,
+	ET_CRS_MARK, ET_COL_MARK, ET_MDC_MARK, ET_MDIO_MARK,
+	RMII_REF125CK_MARK,
+};
+static const unsigned int gether_int_pins[] = {
+	/* PHY_INT */
+	164,
+};
+static const unsigned int gether_int_mux[] = {
+	ET_PHY_INT_MARK,
+};
+static const unsigned int gether_link_pins[] = {
+	/* LINK */
+	177,
+};
+static const unsigned int gether_link_mux[] = {
+	ET_LINK_MARK,
+};
+static const unsigned int gether_wol_pins[] = {
+	/* WOL */
+	175,
+};
+static const unsigned int gether_wol_mux[] = {
+	ET_WOL_MARK,
+};
+/* - HDMI ------------------------------------------------------------------- */
+static const unsigned int hdmi_pins[] = {
+	/* HPD, CEC */
+	210, 211,
+};
+static const unsigned int hdmi_mux[] = {
+	HDMI_HPD_MARK, HDMI_CEC_MARK,
+};
+/* - INTC ------------------------------------------------------------------- */
+IRQC_PINS_MUX(0, 0, 2);
+IRQC_PINS_MUX(0, 1, 13);
+IRQC_PIN_MUX(1, 20);
+IRQC_PINS_MUX(2, 0, 11);
+IRQC_PINS_MUX(2, 1, 12);
+IRQC_PINS_MUX(3, 0, 10);
+IRQC_PINS_MUX(3, 1, 14);
+IRQC_PINS_MUX(4, 0, 15);
+IRQC_PINS_MUX(4, 1, 172);
+IRQC_PINS_MUX(5, 0, 0);
+IRQC_PINS_MUX(5, 1, 1);
+IRQC_PINS_MUX(6, 0, 121);
+IRQC_PINS_MUX(6, 1, 173);
+IRQC_PINS_MUX(7, 0, 120);
+IRQC_PINS_MUX(7, 1, 209);
+IRQC_PIN_MUX(8, 119);
+IRQC_PINS_MUX(9, 0, 118);
+IRQC_PINS_MUX(9, 1, 210);
+IRQC_PIN_MUX(10, 19);
+IRQC_PIN_MUX(11, 104);
+IRQC_PINS_MUX(12, 0, 42);
+IRQC_PINS_MUX(12, 1, 97);
+IRQC_PINS_MUX(13, 0, 64);
+IRQC_PINS_MUX(13, 1, 98);
+IRQC_PINS_MUX(14, 0, 63);
+IRQC_PINS_MUX(14, 1, 99);
+IRQC_PINS_MUX(15, 0, 62);
+IRQC_PINS_MUX(15, 1, 100);
+IRQC_PINS_MUX(16, 0, 68);
+IRQC_PINS_MUX(16, 1, 211);
+IRQC_PIN_MUX(17, 69);
+IRQC_PIN_MUX(18, 70);
+IRQC_PIN_MUX(19, 71);
+IRQC_PIN_MUX(20, 67);
+IRQC_PIN_MUX(21, 202);
+IRQC_PIN_MUX(22, 95);
+IRQC_PIN_MUX(23, 96);
+IRQC_PIN_MUX(24, 180);
+IRQC_PIN_MUX(25, 38);
+IRQC_PINS_MUX(26, 0, 58);
+IRQC_PINS_MUX(26, 1, 81);
+IRQC_PINS_MUX(27, 0, 57);
+IRQC_PINS_MUX(27, 1, 168);
+IRQC_PINS_MUX(28, 0, 56);
+IRQC_PINS_MUX(28, 1, 169);
+IRQC_PINS_MUX(29, 0, 50);
+IRQC_PINS_MUX(29, 1, 170);
+IRQC_PINS_MUX(30, 0, 49);
+IRQC_PINS_MUX(30, 1, 171);
+IRQC_PINS_MUX(31, 0, 41);
+IRQC_PINS_MUX(31, 1, 167);
 
 /* - LCD0 ------------------------------------------------------------------- */
 static const unsigned int lcd0_data8_pins[] = {
@@ -1930,6 +2369,260 @@ static const unsigned int mmc0_ctrl_1_pi
 static const unsigned int mmc0_ctrl_1_mux[] = {
 	MMC1_CMD_PORT104_MARK, MMC1_CLK_PORT103_MARK,
 };
+/* - SCIFA0 ----------------------------------------------------------------- */
+static const unsigned int scifa0_data_pins[] = {
+	/* RXD, TXD */
+	197, 198,
+};
+static const unsigned int scifa0_data_mux[] = {
+	SCIFA0_RXD_MARK, SCIFA0_TXD_MARK,
+};
+static const unsigned int scifa0_clk_pins[] = {
+	/* SCK */
+	188,
+};
+static const unsigned int scifa0_clk_mux[] = {
+	SCIFA0_SCK_MARK,
+};
+static const unsigned int scifa0_ctrl_pins[] = {
+	/* RTS, CTS */
+	194, 193,
+};
+static const unsigned int scifa0_ctrl_mux[] = {
+	SCIFA0_RTS_MARK, SCIFA0_CTS_MARK,
+};
+/* - SCIFA1 ----------------------------------------------------------------- */
+static const unsigned int scifa1_data_pins[] = {
+	/* RXD, TXD */
+	195, 196,
+};
+static const unsigned int scifa1_data_mux[] = {
+	SCIFA1_RXD_MARK, SCIFA1_TXD_MARK,
+};
+static const unsigned int scifa1_clk_pins[] = {
+	/* SCK */
+	185,
+};
+static const unsigned int scifa1_clk_mux[] = {
+	SCIFA1_SCK_MARK,
+};
+static const unsigned int scifa1_ctrl_pins[] = {
+	/* RTS, CTS */
+	23, 21,
+};
+static const unsigned int scifa1_ctrl_mux[] = {
+	SCIFA1_RTS_MARK, SCIFA1_CTS_MARK,
+};
+/* - SCIFA2 ----------------------------------------------------------------- */
+static const unsigned int scifa2_data_pins[] = {
+	/* RXD, TXD */
+	200, 201,
+};
+static const unsigned int scifa2_data_mux[] = {
+	SCIFA2_RXD_MARK, SCIFA2_TXD_MARK,
+};
+static const unsigned int scifa2_clk_0_pins[] = {
+	/* SCK */
+	22,
+};
+static const unsigned int scifa2_clk_0_mux[] = {
+	SCIFA2_SCK_PORT22_MARK,
+};
+static const unsigned int scifa2_clk_1_pins[] = {
+	/* SCK */
+	199,
+};
+static const unsigned int scifa2_clk_1_mux[] = {
+	SCIFA2_SCK_PORT199_MARK,
+};
+static const unsigned int scifa2_ctrl_pins[] = {
+	/* RTS, CTS */
+	96, 95,
+};
+static const unsigned int scifa2_ctrl_mux[] = {
+	SCIFA2_RTS_MARK, SCIFA2_CTS_MARK,
+};
+/* - SCIFA3 ----------------------------------------------------------------- */
+static const unsigned int scifa3_data_0_pins[] = {
+	/* RXD, TXD */
+	174, 175,
+};
+static const unsigned int scifa3_data_0_mux[] = {
+	SCIFA3_RXD_PORT174_MARK, SCIFA3_TXD_PORT175_MARK,
+};
+static const unsigned int scifa3_clk_0_pins[] = {
+	/* SCK */
+	116,
+};
+static const unsigned int scifa3_clk_0_mux[] = {
+	SCIFA3_SCK_PORT116_MARK,
+};
+static const unsigned int scifa3_ctrl_0_pins[] = {
+	/* RTS, CTS */
+	105, 117,
+};
+static const unsigned int scifa3_ctrl_0_mux[] = {
+	SCIFA3_RTS_PORT105_MARK, SCIFA3_CTS_PORT117_MARK,
+};
+static const unsigned int scifa3_data_1_pins[] = {
+	/* RXD, TXD */
+	159, 160,
+};
+static const unsigned int scifa3_data_1_mux[] = {
+	SCIFA3_RXD_PORT159_MARK, SCIFA3_TXD_PORT160_MARK,
+};
+static const unsigned int scifa3_clk_1_pins[] = {
+	/* SCK */
+	158,
+};
+static const unsigned int scifa3_clk_1_mux[] = {
+	SCIFA3_SCK_PORT158_MARK,
+};
+static const unsigned int scifa3_ctrl_1_pins[] = {
+	/* RTS, CTS */
+	161, 162,
+};
+static const unsigned int scifa3_ctrl_1_mux[] = {
+	SCIFA3_RTS_PORT161_MARK, SCIFA3_CTS_PORT162_MARK,
+};
+/* - SCIFA4 ----------------------------------------------------------------- */
+static const unsigned int scifa4_data_0_pins[] = {
+	/* RXD, TXD */
+	12, 13,
+};
+static const unsigned int scifa4_data_0_mux[] = {
+	SCIFA4_RXD_PORT12_MARK, SCIFA4_TXD_PORT13_MARK,
+};
+static const unsigned int scifa4_data_1_pins[] = {
+	/* RXD, TXD */
+	204, 203,
+};
+static const unsigned int scifa4_data_1_mux[] = {
+	SCIFA4_RXD_PORT204_MARK, SCIFA4_TXD_PORT203_MARK,
+};
+static const unsigned int scifa4_data_2_pins[] = {
+	/* RXD, TXD */
+	94, 93,
+};
+static const unsigned int scifa4_data_2_mux[] = {
+	SCIFA4_RXD_PORT94_MARK, SCIFA4_TXD_PORT93_MARK,
+};
+static const unsigned int scifa4_clk_0_pins[] = {
+	/* SCK */
+	21,
+};
+static const unsigned int scifa4_clk_0_mux[] = {
+	SCIFA4_SCK_PORT21_MARK,
+};
+static const unsigned int scifa4_clk_1_pins[] = {
+	/* SCK */
+	205,
+};
+static const unsigned int scifa4_clk_1_mux[] = {
+	SCIFA4_SCK_PORT205_MARK,
+};
+/* - SCIFA5 ----------------------------------------------------------------- */
+static const unsigned int scifa5_data_0_pins[] = {
+	/* RXD, TXD */
+	10, 20,
+};
+static const unsigned int scifa5_data_0_mux[] = {
+	SCIFA5_RXD_PORT10_MARK, SCIFA5_TXD_PORT20_MARK,
+};
+static const unsigned int scifa5_data_1_pins[] = {
+	/* RXD, TXD */
+	207, 208,
+};
+static const unsigned int scifa5_data_1_mux[] = {
+	SCIFA5_RXD_PORT207_MARK, SCIFA5_TXD_PORT208_MARK,
+};
+static const unsigned int scifa5_data_2_pins[] = {
+	/* RXD, TXD */
+	92, 91,
+};
+static const unsigned int scifa5_data_2_mux[] = {
+	SCIFA5_RXD_PORT92_MARK, SCIFA5_TXD_PORT91_MARK,
+};
+static const unsigned int scifa5_clk_0_pins[] = {
+	/* SCK */
+	23,
+};
+static const unsigned int scifa5_clk_0_mux[] = {
+	SCIFA5_SCK_PORT23_MARK,
+};
+static const unsigned int scifa5_clk_1_pins[] = {
+	/* SCK */
+	206,
+};
+static const unsigned int scifa5_clk_1_mux[] = {
+	SCIFA5_SCK_PORT206_MARK,
+};
+/* - SCIFA6 ----------------------------------------------------------------- */
+static const unsigned int scifa6_data_pins[] = {
+	/* RXD, TXD */
+	25, 26,
+};
+static const unsigned int scifa6_data_mux[] = {
+	SCIFA6_RXD_MARK, SCIFA6_TXD_MARK,
+};
+static const unsigned int scifa6_clk_pins[] = {
+	/* SCK */
+	24,
+};
+static const unsigned int scifa6_clk_mux[] = {
+	SCIFA6_SCK_MARK,
+};
+/* - SCIFA7 ----------------------------------------------------------------- */
+static const unsigned int scifa7_data_pins[] = {
+	/* RXD, TXD */
+	0, 1,
+};
+static const unsigned int scifa7_data_mux[] = {
+	SCIFA7_RXD_MARK, SCIFA7_TXD_MARK,
+};
+/* - SCIFB ------------------------------------------------------------------ */
+static const unsigned int scifb_data_0_pins[] = {
+	/* RXD, TXD */
+	191, 192,
+};
+static const unsigned int scifb_data_0_mux[] = {
+	SCIFB_RXD_PORT191_MARK, SCIFB_TXD_PORT192_MARK,
+};
+static const unsigned int scifb_clk_0_pins[] = {
+	/* SCK */
+	190,
+};
+static const unsigned int scifb_clk_0_mux[] = {
+	SCIFB_SCK_PORT190_MARK,
+};
+static const unsigned int scifb_ctrl_0_pins[] = {
+	/* RTS, CTS */
+	186, 187,
+};
+static const unsigned int scifb_ctrl_0_mux[] = {
+	SCIFB_RTS_PORT186_MARK, SCIFB_CTS_PORT187_MARK,
+};
+static const unsigned int scifb_data_1_pins[] = {
+	/* RXD, TXD */
+	3, 4,
+};
+static const unsigned int scifb_data_1_mux[] = {
+	SCIFB_RXD_PORT3_MARK, SCIFB_TXD_PORT4_MARK,
+};
+static const unsigned int scifb_clk_1_pins[] = {
+	/* SCK */
+	2,
+};
+static const unsigned int scifb_clk_1_mux[] = {
+	SCIFB_SCK_PORT2_MARK,
+};
+static const unsigned int scifb_ctrl_1_pins[] = {
+	/* RTS, CTS */
+	172, 173,
+};
+static const unsigned int scifb_ctrl_1_mux[] = {
+	SCIFB_RTS_PORT172_MARK, SCIFB_CTS_PORT173_MARK,
+};
 /* - SDHI0 ------------------------------------------------------------------ */
 static const unsigned int sdhi0_data1_pins[] = {
 	/* D0 */
@@ -2052,8 +2745,141 @@ static const unsigned int sdhi2_wp_1_pin
 static const unsigned int sdhi2_wp_1_mux[] = {
 	SDHI2_WP_PORT25_MARK,
 };
+/* - TPU0 ------------------------------------------------------------------- */
+static const unsigned int tpu0_to0_pins[] = {
+	/* TO */
+	23,
+};
+static const unsigned int tpu0_to0_mux[] = {
+	TPU0TO0_MARK,
+};
+static const unsigned int tpu0_to1_pins[] = {
+	/* TO */
+	21,
+};
+static const unsigned int tpu0_to1_mux[] = {
+	TPU0TO1_MARK,
+};
+static const unsigned int tpu0_to2_0_pins[] = {
+	/* TO */
+	66,
+};
+static const unsigned int tpu0_to2_0_mux[] = {
+	TPU0TO2_PORT66_MARK,
+};
+static const unsigned int tpu0_to2_1_pins[] = {
+	/* TO */
+	202,
+};
+static const unsigned int tpu0_to2_1_mux[] = {
+	TPU0TO2_PORT202_MARK,
+};
+static const unsigned int tpu0_to3_pins[] = {
+	/* TO */
+	180,
+};
+static const unsigned int tpu0_to3_mux[] = {
+	TPU0TO3_MARK,
+};
 
 static const struct sh_pfc_pin_group pinmux_groups[] = {
+	SH_PFC_PIN_GROUP(bsc_data8),
+	SH_PFC_PIN_GROUP(bsc_data16),
+	SH_PFC_PIN_GROUP(bsc_data32),
+	SH_PFC_PIN_GROUP(bsc_cs0),
+	SH_PFC_PIN_GROUP(bsc_cs2),
+	SH_PFC_PIN_GROUP(bsc_cs4),
+	SH_PFC_PIN_GROUP(bsc_cs5a_0),
+	SH_PFC_PIN_GROUP(bsc_cs5a_1),
+	SH_PFC_PIN_GROUP(bsc_cs5b),
+	SH_PFC_PIN_GROUP(bsc_cs6a),
+	SH_PFC_PIN_GROUP(bsc_rd_we8),
+	SH_PFC_PIN_GROUP(bsc_rd_we16),
+	SH_PFC_PIN_GROUP(bsc_rd_we32),
+	SH_PFC_PIN_GROUP(bsc_bs),
+	SH_PFC_PIN_GROUP(bsc_rdwr),
+	SH_PFC_PIN_GROUP(ceu0_data_0_7),
+	SH_PFC_PIN_GROUP(ceu0_data_8_15_0),
+	SH_PFC_PIN_GROUP(ceu0_data_8_15_1),
+	SH_PFC_PIN_GROUP(ceu0_clk_0),
+	SH_PFC_PIN_GROUP(ceu0_clk_1),
+	SH_PFC_PIN_GROUP(ceu0_clk_2),
+	SH_PFC_PIN_GROUP(ceu0_sync),
+	SH_PFC_PIN_GROUP(ceu0_field),
+	SH_PFC_PIN_GROUP(ceu1_data),
+	SH_PFC_PIN_GROUP(ceu1_clk),
+	SH_PFC_PIN_GROUP(ceu1_sync),
+	SH_PFC_PIN_GROUP(ceu1_field),
+	SH_PFC_PIN_GROUP(fsia_mclk_in),
+	SH_PFC_PIN_GROUP(fsia_mclk_out),
+	SH_PFC_PIN_GROUP(fsia_sclk_in),
+	SH_PFC_PIN_GROUP(fsia_sclk_out),
+	SH_PFC_PIN_GROUP(fsia_data_in_0),
+	SH_PFC_PIN_GROUP(fsia_data_in_1),
+	SH_PFC_PIN_GROUP(fsia_data_out_0),
+	SH_PFC_PIN_GROUP(fsia_data_out_1),
+	SH_PFC_PIN_GROUP(fsia_data_out_2),
+	SH_PFC_PIN_GROUP(fsia_spdif_0),
+	SH_PFC_PIN_GROUP(fsia_spdif_1),
+	SH_PFC_PIN_GROUP(fsib_mclk_in),
+	SH_PFC_PIN_GROUP(gether_rmii),
+	SH_PFC_PIN_GROUP(gether_mii),
+	SH_PFC_PIN_GROUP(gether_gmii),
+	SH_PFC_PIN_GROUP(gether_int),
+	SH_PFC_PIN_GROUP(gether_link),
+	SH_PFC_PIN_GROUP(gether_wol),
+	SH_PFC_PIN_GROUP(hdmi),
+	SH_PFC_PIN_GROUP(intc_irq0_0),
+	SH_PFC_PIN_GROUP(intc_irq0_1),
+	SH_PFC_PIN_GROUP(intc_irq1),
+	SH_PFC_PIN_GROUP(intc_irq2_0),
+	SH_PFC_PIN_GROUP(intc_irq2_1),
+	SH_PFC_PIN_GROUP(intc_irq3_0),
+	SH_PFC_PIN_GROUP(intc_irq3_1),
+	SH_PFC_PIN_GROUP(intc_irq4_0),
+	SH_PFC_PIN_GROUP(intc_irq4_1),
+	SH_PFC_PIN_GROUP(intc_irq5_0),
+	SH_PFC_PIN_GROUP(intc_irq5_1),
+	SH_PFC_PIN_GROUP(intc_irq6_0),
+	SH_PFC_PIN_GROUP(intc_irq6_1),
+	SH_PFC_PIN_GROUP(intc_irq7_0),
+	SH_PFC_PIN_GROUP(intc_irq7_1),
+	SH_PFC_PIN_GROUP(intc_irq8),
+	SH_PFC_PIN_GROUP(intc_irq9_0),
+	SH_PFC_PIN_GROUP(intc_irq9_1),
+	SH_PFC_PIN_GROUP(intc_irq10),
+	SH_PFC_PIN_GROUP(intc_irq11),
+	SH_PFC_PIN_GROUP(intc_irq12_0),
+	SH_PFC_PIN_GROUP(intc_irq12_1),
+	SH_PFC_PIN_GROUP(intc_irq13_0),
+	SH_PFC_PIN_GROUP(intc_irq13_1),
+	SH_PFC_PIN_GROUP(intc_irq14_0),
+	SH_PFC_PIN_GROUP(intc_irq14_1),
+	SH_PFC_PIN_GROUP(intc_irq15_0),
+	SH_PFC_PIN_GROUP(intc_irq15_1),
+	SH_PFC_PIN_GROUP(intc_irq16_0),
+	SH_PFC_PIN_GROUP(intc_irq16_1),
+	SH_PFC_PIN_GROUP(intc_irq17),
+	SH_PFC_PIN_GROUP(intc_irq18),
+	SH_PFC_PIN_GROUP(intc_irq19),
+	SH_PFC_PIN_GROUP(intc_irq20),
+	SH_PFC_PIN_GROUP(intc_irq21),
+	SH_PFC_PIN_GROUP(intc_irq22),
+	SH_PFC_PIN_GROUP(intc_irq23),
+	SH_PFC_PIN_GROUP(intc_irq24),
+	SH_PFC_PIN_GROUP(intc_irq25),
+	SH_PFC_PIN_GROUP(intc_irq26_0),
+	SH_PFC_PIN_GROUP(intc_irq26_1),
+	SH_PFC_PIN_GROUP(intc_irq27_0),
+	SH_PFC_PIN_GROUP(intc_irq27_1),
+	SH_PFC_PIN_GROUP(intc_irq28_0),
+	SH_PFC_PIN_GROUP(intc_irq28_1),
+	SH_PFC_PIN_GROUP(intc_irq29_0),
+	SH_PFC_PIN_GROUP(intc_irq29_1),
+	SH_PFC_PIN_GROUP(intc_irq30_0),
+	SH_PFC_PIN_GROUP(intc_irq30_1),
+	SH_PFC_PIN_GROUP(intc_irq31_0),
+	SH_PFC_PIN_GROUP(intc_irq31_1),
 	SH_PFC_PIN_GROUP(lcd0_data8),
 	SH_PFC_PIN_GROUP(lcd0_data9),
 	SH_PFC_PIN_GROUP(lcd0_data12),
@@ -2084,6 +2910,41 @@ static const struct sh_pfc_pin_group pin
 	SH_PFC_PIN_GROUP(mmc0_data4_1),
 	SH_PFC_PIN_GROUP(mmc0_data8_1),
 	SH_PFC_PIN_GROUP(mmc0_ctrl_1),
+	SH_PFC_PIN_GROUP(scifa0_data),
+	SH_PFC_PIN_GROUP(scifa0_clk),
+	SH_PFC_PIN_GROUP(scifa0_ctrl),
+	SH_PFC_PIN_GROUP(scifa1_data),
+	SH_PFC_PIN_GROUP(scifa1_clk),
+	SH_PFC_PIN_GROUP(scifa1_ctrl),
+	SH_PFC_PIN_GROUP(scifa2_data),
+	SH_PFC_PIN_GROUP(scifa2_clk_0),
+	SH_PFC_PIN_GROUP(scifa2_clk_1),
+	SH_PFC_PIN_GROUP(scifa2_ctrl),
+	SH_PFC_PIN_GROUP(scifa3_data_0),
+	SH_PFC_PIN_GROUP(scifa3_clk_0),
+	SH_PFC_PIN_GROUP(scifa3_ctrl_0),
+	SH_PFC_PIN_GROUP(scifa3_data_1),
+	SH_PFC_PIN_GROUP(scifa3_clk_1),
+	SH_PFC_PIN_GROUP(scifa3_ctrl_1),
+	SH_PFC_PIN_GROUP(scifa4_data_0),
+	SH_PFC_PIN_GROUP(scifa4_data_1),
+	SH_PFC_PIN_GROUP(scifa4_data_2),
+	SH_PFC_PIN_GROUP(scifa4_clk_0),
+	SH_PFC_PIN_GROUP(scifa4_clk_1),
+	SH_PFC_PIN_GROUP(scifa5_data_0),
+	SH_PFC_PIN_GROUP(scifa5_data_1),
+	SH_PFC_PIN_GROUP(scifa5_data_2),
+	SH_PFC_PIN_GROUP(scifa5_clk_0),
+	SH_PFC_PIN_GROUP(scifa5_clk_1),
+	SH_PFC_PIN_GROUP(scifa6_data),
+	SH_PFC_PIN_GROUP(scifa6_clk),
+	SH_PFC_PIN_GROUP(scifa7_data),
+	SH_PFC_PIN_GROUP(scifb_data_0),
+	SH_PFC_PIN_GROUP(scifb_clk_0),
+	SH_PFC_PIN_GROUP(scifb_ctrl_0),
+	SH_PFC_PIN_GROUP(scifb_data_1),
+	SH_PFC_PIN_GROUP(scifb_clk_1),
+	SH_PFC_PIN_GROUP(scifb_ctrl_1),
 	SH_PFC_PIN_GROUP(sdhi0_data1),
 	SH_PFC_PIN_GROUP(sdhi0_data4),
 	SH_PFC_PIN_GROUP(sdhi0_ctrl),
@@ -2101,6 +2962,132 @@ static const struct sh_pfc_pin_group pin
 	SH_PFC_PIN_GROUP(sdhi2_wp_0),
 	SH_PFC_PIN_GROUP(sdhi2_cd_1),
 	SH_PFC_PIN_GROUP(sdhi2_wp_1),
+	SH_PFC_PIN_GROUP(tpu0_to0),
+	SH_PFC_PIN_GROUP(tpu0_to1),
+	SH_PFC_PIN_GROUP(tpu0_to2_0),
+	SH_PFC_PIN_GROUP(tpu0_to2_1),
+	SH_PFC_PIN_GROUP(tpu0_to3),
+};
+
+static const char * const bsc_groups[] = {
+	"bsc_data8",
+	"bsc_data16",
+	"bsc_data32",
+	"bsc_cs0",
+	"bsc_cs2",
+	"bsc_cs4",
+	"bsc_cs5a_0",
+	"bsc_cs5a_1",
+	"bsc_cs5b",
+	"bsc_cs6a",
+	"bsc_rd_we8",
+	"bsc_rd_we16",
+	"bsc_rd_we32",
+	"bsc_bs",
+	"bsc_rdwr",
+};
+
+static const char * const ceu0_groups[] = {
+	"ceu0_data_0_7",
+	"ceu0_data_8_15_0",
+	"ceu0_data_8_15_1",
+	"ceu0_clk_0",
+	"ceu0_clk_1",
+	"ceu0_clk_2",
+	"ceu0_sync",
+	"ceu0_field",
+};
+
+static const char * const ceu1_groups[] = {
+	"ceu1_data",
+	"ceu1_clk",
+	"ceu1_sync",
+	"ceu1_field",
+};
+
+static const char * const fsia_groups[] = {
+	"fsia_mclk_in",
+	"fsia_mclk_out",
+	"fsia_sclk_in",
+	"fsia_sclk_out",
+	"fsia_data_in_0",
+	"fsia_data_in_1",
+	"fsia_data_out_0",
+	"fsia_data_out_1",
+	"fsia_data_out_2",
+	"fsia_spdif_0",
+	"fsia_spdif_1",
+};
+
+static const char * const fsib_groups[] = {
+	"fsib_mclk_in",
+};
+
+static const char * const gether_groups[] = {
+	"gether_rmii",
+	"gether_mii",
+	"gether_gmii",
+	"gether_int",
+	"gether_link",
+	"gether_wol",
+};
+
+static const char * const hdmi_groups[] = {
+	"hdmi",
+};
+
+static const char * const intc_groups[] = {
+	"intc_irq0_0",
+	"intc_irq0_1",
+	"intc_irq1",
+	"intc_irq2_0",
+	"intc_irq2_1",
+	"intc_irq3_0",
+	"intc_irq3_1",
+	"intc_irq4_0",
+	"intc_irq4_1",
+	"intc_irq5_0",
+	"intc_irq5_1",
+	"intc_irq6_0",
+	"intc_irq6_1",
+	"intc_irq7_0",
+	"intc_irq7_1",
+	"intc_irq8",
+	"intc_irq9_0",
+	"intc_irq9_1",
+	"intc_irq10",
+	"intc_irq11",
+	"intc_irq12_0",
+	"intc_irq12_1",
+	"intc_irq13_0",
+	"intc_irq13_1",
+	"intc_irq14_0",
+	"intc_irq14_1",
+	"intc_irq15_0",
+	"intc_irq15_1",
+	"intc_irq16_0",
+	"intc_irq16_1",
+	"intc_irq17",
+	"intc_irq18",
+	"intc_irq19",
+	"intc_irq20",
+	"intc_irq21",
+	"intc_irq22",
+	"intc_irq23",
+	"intc_irq24",
+	"intc_irq25",
+	"intc_irq26_0",
+	"intc_irq26_1",
+	"intc_irq27_0",
+	"intc_irq27_1",
+	"intc_irq28_0",
+	"intc_irq28_1",
+	"intc_irq29_0",
+	"intc_irq29_1",
+	"intc_irq30_0",
+	"intc_irq30_1",
+	"intc_irq31_0",
+	"intc_irq31_1",
 };
 
 static const char * const lcd0_groups[] = {
@@ -2142,6 +3129,68 @@ static const char * const mmc0_groups[]
 	"mmc0_ctrl_1",
 };
 
+static const char * const scifa0_groups[] = {
+	"scifa0_data",
+	"scifa0_clk",
+	"scifa0_ctrl",
+};
+
+static const char * const scifa1_groups[] = {
+	"scifa1_data",
+	"scifa1_clk",
+	"scifa1_ctrl",
+};
+
+static const char * const scifa2_groups[] = {
+	"scifa2_data",
+	"scifa2_clk_0",
+	"scifa2_clk_1",
+	"scifa2_ctrl",
+};
+
+static const char * const scifa3_groups[] = {
+	"scifa3_data_0",
+	"scifa3_clk_0",
+	"scifa3_ctrl_0",
+	"scifa3_data_1",
+	"scifa3_clk_1",
+	"scifa3_ctrl_1",
+};
+
+static const char * const scifa4_groups[] = {
+	"scifa4_data_0",
+	"scifa4_data_1",
+	"scifa4_data_2",
+	"scifa4_clk_0",
+	"scifa4_clk_1",
+};
+
+static const char * const scifa5_groups[] = {
+	"scifa5_data_0",
+	"scifa5_data_1",
+	"scifa5_data_2",
+	"scifa5_clk_0",
+	"scifa5_clk_1",
+};
+
+static const char * const scifa6_groups[] = {
+	"scifa6_data",
+	"scifa6_clk",
+};
+
+static const char * const scifa7_groups[] = {
+	"scifa7_data",
+};
+
+static const char * const scifb_groups[] = {
+	"scifb_data_0",
+	"scifb_clk_0",
+	"scifb_ctrl_0",
+	"scifb_data_1",
+	"scifb_clk_1",
+	"scifb_ctrl_1",
+};
+
 static const char * const sdhi0_groups[] = {
 	"sdhi0_data1",
 	"sdhi0_data4",
@@ -2168,412 +3217,51 @@ static const char * const sdhi2_groups[]
 	"sdhi2_wp_1",
 };
 
+static const char * const tpu0_groups[] = {
+	"tpu0_to0",
+	"tpu0_to1",
+	"tpu0_to2_0",
+	"tpu0_to2_1",
+	"tpu0_to3",
+};
+
 static const struct sh_pfc_function pinmux_functions[] = {
+	SH_PFC_FUNCTION(bsc),
+	SH_PFC_FUNCTION(ceu0),
+	SH_PFC_FUNCTION(ceu1),
+	SH_PFC_FUNCTION(fsia),
+	SH_PFC_FUNCTION(fsib),
+	SH_PFC_FUNCTION(gether),
+	SH_PFC_FUNCTION(hdmi),
+	SH_PFC_FUNCTION(intc),
 	SH_PFC_FUNCTION(lcd0),
 	SH_PFC_FUNCTION(lcd1),
 	SH_PFC_FUNCTION(mmc0),
+	SH_PFC_FUNCTION(scifa0),
+	SH_PFC_FUNCTION(scifa1),
+	SH_PFC_FUNCTION(scifa2),
+	SH_PFC_FUNCTION(scifa3),
+	SH_PFC_FUNCTION(scifa4),
+	SH_PFC_FUNCTION(scifa5),
+	SH_PFC_FUNCTION(scifa6),
+	SH_PFC_FUNCTION(scifa7),
+	SH_PFC_FUNCTION(scifb),
 	SH_PFC_FUNCTION(sdhi0),
 	SH_PFC_FUNCTION(sdhi1),
 	SH_PFC_FUNCTION(sdhi2),
+	SH_PFC_FUNCTION(tpu0),
 };
 
-#define PINMUX_FN_BASE	ARRAY_SIZE(pinmux_pins)
-
-static const struct pinmux_func pinmux_func_gpios[] = {
-	/* IRQ */
-	GPIO_FN(IRQ0_PORT2),	GPIO_FN(IRQ0_PORT13),
-	GPIO_FN(IRQ1),
-	GPIO_FN(IRQ2_PORT11),	GPIO_FN(IRQ2_PORT12),
-	GPIO_FN(IRQ3_PORT10),	GPIO_FN(IRQ3_PORT14),
-	GPIO_FN(IRQ4_PORT15),	GPIO_FN(IRQ4_PORT172),
-	GPIO_FN(IRQ5_PORT0),	GPIO_FN(IRQ5_PORT1),
-	GPIO_FN(IRQ6_PORT121),	GPIO_FN(IRQ6_PORT173),
-	GPIO_FN(IRQ7_PORT120),	GPIO_FN(IRQ7_PORT209),
-	GPIO_FN(IRQ8),
-	GPIO_FN(IRQ9_PORT118),	GPIO_FN(IRQ9_PORT210),
-	GPIO_FN(IRQ10),
-	GPIO_FN(IRQ11),
-	GPIO_FN(IRQ12_PORT42),	GPIO_FN(IRQ12_PORT97),
-	GPIO_FN(IRQ13_PORT64),	GPIO_FN(IRQ13_PORT98),
-	GPIO_FN(IRQ14_PORT63),	GPIO_FN(IRQ14_PORT99),
-	GPIO_FN(IRQ15_PORT62),	GPIO_FN(IRQ15_PORT100),
-	GPIO_FN(IRQ16_PORT68),	GPIO_FN(IRQ16_PORT211),
-	GPIO_FN(IRQ17),
-	GPIO_FN(IRQ18),
-	GPIO_FN(IRQ19),
-	GPIO_FN(IRQ20),
-	GPIO_FN(IRQ21),
-	GPIO_FN(IRQ22),
-	GPIO_FN(IRQ23),
-	GPIO_FN(IRQ24),
-	GPIO_FN(IRQ25),
-	GPIO_FN(IRQ26_PORT58),	GPIO_FN(IRQ26_PORT81),
-	GPIO_FN(IRQ27_PORT57),	GPIO_FN(IRQ27_PORT168),
-	GPIO_FN(IRQ28_PORT56),	GPIO_FN(IRQ28_PORT169),
-	GPIO_FN(IRQ29_PORT50),	GPIO_FN(IRQ29_PORT170),
-	GPIO_FN(IRQ30_PORT49),	GPIO_FN(IRQ30_PORT171),
-	GPIO_FN(IRQ31_PORT41),	GPIO_FN(IRQ31_PORT167),
-
-	/* Function */
-
-	/* DBGT */
-	GPIO_FN(DBGMDT2),	GPIO_FN(DBGMDT1),	GPIO_FN(DBGMDT0),
-	GPIO_FN(DBGMD10),	GPIO_FN(DBGMD11),	GPIO_FN(DBGMD20),
-	GPIO_FN(DBGMD21),
-
-	/* FSI-A */
-	GPIO_FN(FSIAISLD_PORT0),	/* FSIAISLD Port 0/5 */
-	GPIO_FN(FSIAISLD_PORT5),
-	GPIO_FN(FSIASPDIF_PORT9),	/* FSIASPDIF Port 9/18 */
-	GPIO_FN(FSIASPDIF_PORT18),
-	GPIO_FN(FSIAOSLD1),	GPIO_FN(FSIAOSLD2),	GPIO_FN(FSIAOLR),
-	GPIO_FN(FSIAOBT),	GPIO_FN(FSIAOSLD),	GPIO_FN(FSIAOMC),
-	GPIO_FN(FSIACK),	GPIO_FN(FSIAILR),	GPIO_FN(FSIAIBT),
-
-	/* FSI-B */
-	GPIO_FN(FSIBCK),
-
-	/* FMSI */
-	GPIO_FN(FMSISLD_PORT1), /* FMSISLD Port 1/6 */
-	GPIO_FN(FMSISLD_PORT6),
-	GPIO_FN(FMSIILR),	GPIO_FN(FMSIIBT),	GPIO_FN(FMSIOLR),
-	GPIO_FN(FMSIOBT),	GPIO_FN(FMSICK),	GPIO_FN(FMSOILR),
-	GPIO_FN(FMSOIBT),	GPIO_FN(FMSOOLR),	GPIO_FN(FMSOOBT),
-	GPIO_FN(FMSOSLD),	GPIO_FN(FMSOCK),
-
-	/* SCIFA0 */
-	GPIO_FN(SCIFA0_SCK),	GPIO_FN(SCIFA0_CTS),	GPIO_FN(SCIFA0_RTS),
-	GPIO_FN(SCIFA0_RXD),	GPIO_FN(SCIFA0_TXD),
-
-	/* SCIFA1 */
-	GPIO_FN(SCIFA1_CTS),	GPIO_FN(SCIFA1_SCK),
-	GPIO_FN(SCIFA1_RXD),	GPIO_FN(SCIFA1_TXD),	GPIO_FN(SCIFA1_RTS),
-
-	/* SCIFA2 */
-	GPIO_FN(SCIFA2_SCK_PORT22), /* SCIFA2_SCK Port 22/199 */
-	GPIO_FN(SCIFA2_SCK_PORT199),
-	GPIO_FN(SCIFA2_RXD),	GPIO_FN(SCIFA2_TXD),
-	GPIO_FN(SCIFA2_CTS),	GPIO_FN(SCIFA2_RTS),
-
-	/* SCIFA3 */
-	GPIO_FN(SCIFA3_RTS_PORT105), /* MSEL5CR_8_0 */
-	GPIO_FN(SCIFA3_SCK_PORT116),
-	GPIO_FN(SCIFA3_CTS_PORT117),
-	GPIO_FN(SCIFA3_RXD_PORT174),
-	GPIO_FN(SCIFA3_TXD_PORT175),
-
-	GPIO_FN(SCIFA3_RTS_PORT161), /* MSEL5CR_8_1 */
-	GPIO_FN(SCIFA3_SCK_PORT158),
-	GPIO_FN(SCIFA3_CTS_PORT162),
-	GPIO_FN(SCIFA3_RXD_PORT159),
-	GPIO_FN(SCIFA3_TXD_PORT160),
-
-	/* SCIFA4 */
-	GPIO_FN(SCIFA4_RXD_PORT12), /* MSEL5CR[12:11] = 00 */
-	GPIO_FN(SCIFA4_TXD_PORT13),
-
-	GPIO_FN(SCIFA4_RXD_PORT204), /* MSEL5CR[12:11] = 01 */
-	GPIO_FN(SCIFA4_TXD_PORT203),
-
-	GPIO_FN(SCIFA4_RXD_PORT94), /* MSEL5CR[12:11] = 10 */
-	GPIO_FN(SCIFA4_TXD_PORT93),
-
-	GPIO_FN(SCIFA4_SCK_PORT21), /* SCIFA4_SCK Port 21/205 */
-	GPIO_FN(SCIFA4_SCK_PORT205),
-
-	/* SCIFA5 */
-	GPIO_FN(SCIFA5_TXD_PORT20), /* MSEL5CR[15:14] = 00 */
-	GPIO_FN(SCIFA5_RXD_PORT10),
-
-	GPIO_FN(SCIFA5_RXD_PORT207), /* MSEL5CR[15:14] = 01 */
-	GPIO_FN(SCIFA5_TXD_PORT208),
-
-	GPIO_FN(SCIFA5_TXD_PORT91), /* MSEL5CR[15:14] = 10 */
-	GPIO_FN(SCIFA5_RXD_PORT92),
-
-	GPIO_FN(SCIFA5_SCK_PORT23), /* SCIFA5_SCK Port 23/206 */
-	GPIO_FN(SCIFA5_SCK_PORT206),
-
-	/* SCIFA6 */
-	GPIO_FN(SCIFA6_SCK),	GPIO_FN(SCIFA6_RXD),	GPIO_FN(SCIFA6_TXD),
-
-	/* SCIFA7 */
-	GPIO_FN(SCIFA7_TXD),	GPIO_FN(SCIFA7_RXD),
-
-	/* SCIFAB */
-	GPIO_FN(SCIFB_SCK_PORT190), /* MSEL5CR_17_0 */
-	GPIO_FN(SCIFB_RXD_PORT191),
-	GPIO_FN(SCIFB_TXD_PORT192),
-	GPIO_FN(SCIFB_RTS_PORT186),
-	GPIO_FN(SCIFB_CTS_PORT187),
-
-	GPIO_FN(SCIFB_SCK_PORT2), /* MSEL5CR_17_1 */
-	GPIO_FN(SCIFB_RXD_PORT3),
-	GPIO_FN(SCIFB_TXD_PORT4),
-	GPIO_FN(SCIFB_RTS_PORT172),
-	GPIO_FN(SCIFB_CTS_PORT173),
-
-	/* RSPI */
-	GPIO_FN(RSPI_SSL0_A),	GPIO_FN(RSPI_SSL1_A),	GPIO_FN(RSPI_SSL2_A),
-	GPIO_FN(RSPI_SSL3_A),	GPIO_FN(RSPI_CK_A),	GPIO_FN(RSPI_MOSI_A),
-	GPIO_FN(RSPI_MISO_A),
-
-	/* VIO CKO */
-	GPIO_FN(VIO_CKO1),
-	GPIO_FN(VIO_CKO2),
-	GPIO_FN(VIO_CKO_1),
-	GPIO_FN(VIO_CKO),
-
-	/* VIO0 */
-	GPIO_FN(VIO0_D0),	GPIO_FN(VIO0_D1),	GPIO_FN(VIO0_D2),
-	GPIO_FN(VIO0_D3),	GPIO_FN(VIO0_D4),	GPIO_FN(VIO0_D5),
-	GPIO_FN(VIO0_D6),	GPIO_FN(VIO0_D7),	GPIO_FN(VIO0_D8),
-	GPIO_FN(VIO0_D9),	GPIO_FN(VIO0_D10),	GPIO_FN(VIO0_D11),
-	GPIO_FN(VIO0_D12),	GPIO_FN(VIO0_VD),	GPIO_FN(VIO0_HD),
-	GPIO_FN(VIO0_CLK),	GPIO_FN(VIO0_FIELD),
-
-	GPIO_FN(VIO0_D13_PORT26), /* MSEL5CR_27_0 */
-	GPIO_FN(VIO0_D14_PORT25),
-	GPIO_FN(VIO0_D15_PORT24),
-
-	GPIO_FN(VIO0_D13_PORT22), /* MSEL5CR_27_1 */
-	GPIO_FN(VIO0_D14_PORT95),
-	GPIO_FN(VIO0_D15_PORT96),
-
-	/* VIO1 */
-	GPIO_FN(VIO1_D0),	GPIO_FN(VIO1_D1),	GPIO_FN(VIO1_D2),
-	GPIO_FN(VIO1_D3),	GPIO_FN(VIO1_D4),	GPIO_FN(VIO1_D5),
-	GPIO_FN(VIO1_D6),	GPIO_FN(VIO1_D7),	GPIO_FN(VIO1_VD),
-	GPIO_FN(VIO1_HD),	GPIO_FN(VIO1_CLK),	GPIO_FN(VIO1_FIELD),
-
-	/* TPU0 */
-	GPIO_FN(TPU0TO0),	GPIO_FN(TPU0TO1),	GPIO_FN(TPU0TO3),
-	GPIO_FN(TPU0TO2_PORT66), /* TPU0TO2 Port 66/202 */
-	GPIO_FN(TPU0TO2_PORT202),
-
-	/* SSP1 0 */
-	GPIO_FN(STP0_IPD0),	GPIO_FN(STP0_IPD1),	GPIO_FN(STP0_IPD2),
-	GPIO_FN(STP0_IPD3),	GPIO_FN(STP0_IPD4),	GPIO_FN(STP0_IPD5),
-	GPIO_FN(STP0_IPD6),	GPIO_FN(STP0_IPD7),	GPIO_FN(STP0_IPEN),
-	GPIO_FN(STP0_IPCLK),	GPIO_FN(STP0_IPSYNC),
-
-	/* SSP1 1 */
-	GPIO_FN(STP1_IPD1),	GPIO_FN(STP1_IPD2),	GPIO_FN(STP1_IPD3),
-	GPIO_FN(STP1_IPD4),	GPIO_FN(STP1_IPD5),	GPIO_FN(STP1_IPD6),
-	GPIO_FN(STP1_IPD7),	GPIO_FN(STP1_IPCLK),	GPIO_FN(STP1_IPSYNC),
-
-	GPIO_FN(STP1_IPD0_PORT186), /* MSEL5CR_23_0 */
-	GPIO_FN(STP1_IPEN_PORT187),
-
-	GPIO_FN(STP1_IPD0_PORT194), /* MSEL5CR_23_1 */
-	GPIO_FN(STP1_IPEN_PORT193),
-
-	/* SIM */
-	GPIO_FN(SIM_RST),	GPIO_FN(SIM_CLK),
-	GPIO_FN(SIM_D_PORT22), /* SIM_D  Port 22/199 */
-	GPIO_FN(SIM_D_PORT199),
-
-	/* MSIOF2 */
-	GPIO_FN(MSIOF2_TXD),	GPIO_FN(MSIOF2_RXD),	GPIO_FN(MSIOF2_TSCK),
-	GPIO_FN(MSIOF2_SS2),	GPIO_FN(MSIOF2_TSYNC),	GPIO_FN(MSIOF2_SS1),
-	GPIO_FN(MSIOF2_MCK1),	GPIO_FN(MSIOF2_MCK0),	GPIO_FN(MSIOF2_RSYNC),
-	GPIO_FN(MSIOF2_RSCK),
-
-	/* KEYSC */
-	GPIO_FN(KEYIN4),	GPIO_FN(KEYIN5),
-	GPIO_FN(KEYIN6),	GPIO_FN(KEYIN7),
-	GPIO_FN(KEYOUT0),	GPIO_FN(KEYOUT1),	GPIO_FN(KEYOUT2),
-	GPIO_FN(KEYOUT3),	GPIO_FN(KEYOUT4),	GPIO_FN(KEYOUT5),
-	GPIO_FN(KEYOUT6),	GPIO_FN(KEYOUT7),
-
-	GPIO_FN(KEYIN0_PORT43), /* MSEL4CR_18_0 */
-	GPIO_FN(KEYIN1_PORT44),
-	GPIO_FN(KEYIN2_PORT45),
-	GPIO_FN(KEYIN3_PORT46),
-
-	GPIO_FN(KEYIN0_PORT58), /* MSEL4CR_18_1 */
-	GPIO_FN(KEYIN1_PORT57),
-	GPIO_FN(KEYIN2_PORT56),
-	GPIO_FN(KEYIN3_PORT55),
-
-	/* VOU */
-	GPIO_FN(DV_D0),		GPIO_FN(DV_D1),		GPIO_FN(DV_D2),
-	GPIO_FN(DV_D3),		GPIO_FN(DV_D4),		GPIO_FN(DV_D5),
-	GPIO_FN(DV_D6),		GPIO_FN(DV_D7),		GPIO_FN(DV_D8),
-	GPIO_FN(DV_D9),		GPIO_FN(DV_D10),	GPIO_FN(DV_D11),
-	GPIO_FN(DV_D12),	GPIO_FN(DV_D13),	GPIO_FN(DV_D14),
-	GPIO_FN(DV_D15),	GPIO_FN(DV_CLK),
-	GPIO_FN(DV_VSYNC),	GPIO_FN(DV_HSYNC),
-
-	/* MEMC */
-	GPIO_FN(MEMC_AD0),	GPIO_FN(MEMC_AD1),	GPIO_FN(MEMC_AD2),
-	GPIO_FN(MEMC_AD3),	GPIO_FN(MEMC_AD4),	GPIO_FN(MEMC_AD5),
-	GPIO_FN(MEMC_AD6),	GPIO_FN(MEMC_AD7),	GPIO_FN(MEMC_AD8),
-	GPIO_FN(MEMC_AD9),	GPIO_FN(MEMC_AD10),	GPIO_FN(MEMC_AD11),
-	GPIO_FN(MEMC_AD12),	GPIO_FN(MEMC_AD13),	GPIO_FN(MEMC_AD14),
-	GPIO_FN(MEMC_AD15),	GPIO_FN(MEMC_CS0),	GPIO_FN(MEMC_INT),
-	GPIO_FN(MEMC_NWE),	GPIO_FN(MEMC_NOE),	GPIO_FN(MEMC_CS1),
-	GPIO_FN(MEMC_A1),	GPIO_FN(MEMC_ADV),	GPIO_FN(MEMC_DREQ0),
-	GPIO_FN(MEMC_WAIT),	GPIO_FN(MEMC_DREQ1),	GPIO_FN(MEMC_BUSCLK),
-	GPIO_FN(MEMC_A0),
-
-	/* MSIOF0 */
-	GPIO_FN(MSIOF0_SS1),	GPIO_FN(MSIOF0_SS2),	GPIO_FN(MSIOF0_RXD),
-	GPIO_FN(MSIOF0_TXD),	GPIO_FN(MSIOF0_MCK0),	GPIO_FN(MSIOF0_MCK1),
-	GPIO_FN(MSIOF0_RSYNC),	GPIO_FN(MSIOF0_RSCK),	GPIO_FN(MSIOF0_TSCK),
-	GPIO_FN(MSIOF0_TSYNC),
-
-	/* MSIOF1 */
-	GPIO_FN(MSIOF1_RSCK),	GPIO_FN(MSIOF1_RSYNC),
-	GPIO_FN(MSIOF1_MCK0),	GPIO_FN(MSIOF1_MCK1),
-
-	GPIO_FN(MSIOF1_SS2_PORT116),	GPIO_FN(MSIOF1_SS1_PORT117),
-	GPIO_FN(MSIOF1_RXD_PORT118),	GPIO_FN(MSIOF1_TXD_PORT119),
-	GPIO_FN(MSIOF1_TSYNC_PORT120),
-	GPIO_FN(MSIOF1_TSCK_PORT121),	/* MSEL4CR_10_0 */
-
-	GPIO_FN(MSIOF1_SS1_PORT67),	GPIO_FN(MSIOF1_TSCK_PORT72),
-	GPIO_FN(MSIOF1_TSYNC_PORT73),	GPIO_FN(MSIOF1_TXD_PORT74),
-	GPIO_FN(MSIOF1_RXD_PORT75),
-	GPIO_FN(MSIOF1_SS2_PORT202),	/* MSEL4CR_10_1 */
-
-	/* GPIO */
-	GPIO_FN(GPO0),	GPIO_FN(GPI0),
-	GPIO_FN(GPO1),	GPIO_FN(GPI1),
-
-	/* USB0 */
-	GPIO_FN(USB0_OCI),	GPIO_FN(USB0_PPON),	GPIO_FN(VBUS),
-
-	/* USB1 */
-	GPIO_FN(USB1_OCI),	GPIO_FN(USB1_PPON),
-
-	/* BBIF1 */
-	GPIO_FN(BBIF1_RXD),	GPIO_FN(BBIF1_TXD),	GPIO_FN(BBIF1_TSYNC),
-	GPIO_FN(BBIF1_TSCK),	GPIO_FN(BBIF1_RSCK),	GPIO_FN(BBIF1_RSYNC),
-	GPIO_FN(BBIF1_FLOW),	GPIO_FN(BBIF1_RX_FLOW_N),
-
-	/* BBIF2 */
-	GPIO_FN(BBIF2_TXD2_PORT5), /* MSEL5CR_0_0 */
-	GPIO_FN(BBIF2_RXD2_PORT60),
-	GPIO_FN(BBIF2_TSYNC2_PORT6),
-	GPIO_FN(BBIF2_TSCK2_PORT59),
-
-	GPIO_FN(BBIF2_RXD2_PORT90), /* MSEL5CR_0_1 */
-	GPIO_FN(BBIF2_TXD2_PORT183),
-	GPIO_FN(BBIF2_TSCK2_PORT89),
-	GPIO_FN(BBIF2_TSYNC2_PORT184),
-
-	/* BSC / FLCTL / PCMCIA */
-	GPIO_FN(CS0),	GPIO_FN(CS2),	GPIO_FN(CS4),
-	GPIO_FN(CS5B),	GPIO_FN(CS6A),
-	GPIO_FN(CS5A_PORT105), /* CS5A PORT 19/105 */
-	GPIO_FN(CS5A_PORT19),
-	GPIO_FN(IOIS16), /* ? */
-
-	GPIO_FN(A0),	GPIO_FN(A1),	GPIO_FN(A2),	GPIO_FN(A3),
-	GPIO_FN(A4_FOE),	GPIO_FN(A5_FCDE),	/* share with FLCTL */
-	GPIO_FN(A6),	GPIO_FN(A7),	GPIO_FN(A8),	GPIO_FN(A9),
-	GPIO_FN(A10),	GPIO_FN(A11),	GPIO_FN(A12),	GPIO_FN(A13),
-	GPIO_FN(A14),	GPIO_FN(A15),	GPIO_FN(A16),	GPIO_FN(A17),
-	GPIO_FN(A18),	GPIO_FN(A19),	GPIO_FN(A20),	GPIO_FN(A21),
-	GPIO_FN(A22),	GPIO_FN(A23),	GPIO_FN(A24),	GPIO_FN(A25),
-	GPIO_FN(A26),
-
-	GPIO_FN(D0_NAF0),	GPIO_FN(D1_NAF1),	/* share with FLCTL */
-	GPIO_FN(D2_NAF2),	GPIO_FN(D3_NAF3),	/* share with FLCTL */
-	GPIO_FN(D4_NAF4),	GPIO_FN(D5_NAF5),	/* share with FLCTL */
-	GPIO_FN(D6_NAF6),	GPIO_FN(D7_NAF7),	/* share with FLCTL */
-	GPIO_FN(D8_NAF8),	GPIO_FN(D9_NAF9),	/* share with FLCTL */
-	GPIO_FN(D10_NAF10),	GPIO_FN(D11_NAF11),	/* share with FLCTL */
-	GPIO_FN(D12_NAF12),	GPIO_FN(D13_NAF13),	/* share with FLCTL */
-	GPIO_FN(D14_NAF14),	GPIO_FN(D15_NAF15),	/* share with FLCTL */
-	GPIO_FN(D16),	GPIO_FN(D17),	GPIO_FN(D18),	GPIO_FN(D19),
-	GPIO_FN(D20),	GPIO_FN(D21),	GPIO_FN(D22),	GPIO_FN(D23),
-	GPIO_FN(D24),	GPIO_FN(D25),	GPIO_FN(D26),	GPIO_FN(D27),
-	GPIO_FN(D28),	GPIO_FN(D29),	GPIO_FN(D30),	GPIO_FN(D31),
-
-	GPIO_FN(WE0_FWE),	/* share with FLCTL */
-	GPIO_FN(WE1),
-	GPIO_FN(WE2_ICIORD),	/* share with PCMCIA */
-	GPIO_FN(WE3_ICIOWR),	/* share with PCMCIA */
-	GPIO_FN(CKO),	GPIO_FN(BS),	GPIO_FN(RDWR),
-	GPIO_FN(RD_FSC),	/* share with FLCTL */
-	GPIO_FN(WAIT_PORT177), /* WAIT Port 90/177 */
-	GPIO_FN(WAIT_PORT90),
-
-	GPIO_FN(FCE0),	GPIO_FN(FCE1),	GPIO_FN(FRB), /* FLCTL */
-
-	/* IRDA */
-	GPIO_FN(IRDA_FIRSEL),	GPIO_FN(IRDA_IN),	GPIO_FN(IRDA_OUT),
-
-	/* ATAPI */
-	GPIO_FN(IDE_D0),	GPIO_FN(IDE_D1),	GPIO_FN(IDE_D2),
-	GPIO_FN(IDE_D3),	GPIO_FN(IDE_D4),	GPIO_FN(IDE_D5),
-	GPIO_FN(IDE_D6),	GPIO_FN(IDE_D7),	GPIO_FN(IDE_D8),
-	GPIO_FN(IDE_D9),	GPIO_FN(IDE_D10),	GPIO_FN(IDE_D11),
-	GPIO_FN(IDE_D12),	GPIO_FN(IDE_D13),	GPIO_FN(IDE_D14),
-	GPIO_FN(IDE_D15),	GPIO_FN(IDE_A0),	GPIO_FN(IDE_A1),
-	GPIO_FN(IDE_A2),	GPIO_FN(IDE_CS0),	GPIO_FN(IDE_CS1),
-	GPIO_FN(IDE_IOWR),	GPIO_FN(IDE_IORD),	GPIO_FN(IDE_IORDY),
-	GPIO_FN(IDE_INT),	GPIO_FN(IDE_RST),	GPIO_FN(IDE_DIRECTION),
-	GPIO_FN(IDE_EXBUF_ENB),	GPIO_FN(IDE_IODACK),	GPIO_FN(IDE_IODREQ),
-
-	/* RMII */
-	GPIO_FN(RMII_CRS_DV),	GPIO_FN(RMII_RX_ER),	GPIO_FN(RMII_RXD0),
-	GPIO_FN(RMII_RXD1),	GPIO_FN(RMII_TX_EN),	GPIO_FN(RMII_TXD0),
-	GPIO_FN(RMII_MDC),	GPIO_FN(RMII_TXD1),	GPIO_FN(RMII_MDIO),
-	GPIO_FN(RMII_REF50CK),	GPIO_FN(RMII_REF125CK),	/* for GMII */
-
-	/* GEther */
-	GPIO_FN(ET_TX_CLK),	GPIO_FN(ET_TX_EN),	GPIO_FN(ET_ETXD0),
-	GPIO_FN(ET_ETXD1),	GPIO_FN(ET_ETXD2),	GPIO_FN(ET_ETXD3),
-	GPIO_FN(ET_ETXD4),	GPIO_FN(ET_ETXD5), /* for GEther */
-	GPIO_FN(ET_ETXD6),	GPIO_FN(ET_ETXD7), /* for GEther */
-	GPIO_FN(ET_COL),	GPIO_FN(ET_TX_ER),	GPIO_FN(ET_RX_CLK),
-	GPIO_FN(ET_RX_DV),	GPIO_FN(ET_ERXD0),	GPIO_FN(ET_ERXD1),
-	GPIO_FN(ET_ERXD2),	GPIO_FN(ET_ERXD3),
-	GPIO_FN(ET_ERXD4),	GPIO_FN(ET_ERXD5), /* for GEther */
-	GPIO_FN(ET_ERXD6),	GPIO_FN(ET_ERXD7), /* for GEther */
-	GPIO_FN(ET_RX_ER),	GPIO_FN(ET_CRS),	GPIO_FN(ET_MDC),
-	GPIO_FN(ET_MDIO),	GPIO_FN(ET_LINK),	GPIO_FN(ET_PHY_INT),
-	GPIO_FN(ET_WOL),	GPIO_FN(ET_GTX_CLK),
-
-	/* DMA0 */
-	GPIO_FN(DREQ0),	GPIO_FN(DACK0),
-
-	/* DMA1 */
-	GPIO_FN(DREQ1),	GPIO_FN(DACK1),
-
-	/* SYSC */
-	GPIO_FN(RESETOUTS),
-
-	/* IRREM */
-	GPIO_FN(IROUT),
-
-	/* LCDC */
-	GPIO_FN(LCDC0_SELECT),
-	GPIO_FN(LCDC1_SELECT),
-
-	/* SDENC */
-	GPIO_FN(SDENC_CPG),
-	GPIO_FN(SDENC_DV_CLKI),
-
-	/* HDMI */
-	GPIO_FN(HDMI_HPD),
-	GPIO_FN(HDMI_CEC),
-
-	/* SYSC */
-	GPIO_FN(RESETP_PULLUP),
-	GPIO_FN(RESETP_PLAIN),
-
-	/* DEBUG */
-	GPIO_FN(EDEBGREQ_PULLDOWN),
-	GPIO_FN(EDEBGREQ_PULLUP),
-
-	GPIO_FN(TRACEAUD_FROM_VIO),
-	GPIO_FN(TRACEAUD_FROM_LCDC0),
-	GPIO_FN(TRACEAUD_FROM_MEMC),
-};
+#undef PORTCR
+#define PORTCR(nr, reg)							\
+	{								\
+		PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {		\
+			_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT),	\
+				PORT##nr##_FN0, PORT##nr##_FN1,		\
+				PORT##nr##_FN2, PORT##nr##_FN3,		\
+				PORT##nr##_FN4, PORT##nr##_FN5,		\
+				PORT##nr##_FN6, PORT##nr##_FN7 }	\
+	}
 
 static const struct pinmux_cfg_reg pinmux_config_regs[] = {
 	PORTCR(0,	0xe6050000), /* PORT0CR */
@@ -2994,48 +3682,114 @@ static const struct pinmux_data_reg pinm
 };
 
 static const struct pinmux_irq pinmux_irqs[] = {
-	PINMUX_IRQ(irq_pin(0), GPIO_PORT2,   GPIO_PORT13),	/* IRQ0A */
-	PINMUX_IRQ(irq_pin(1), GPIO_PORT20),		/* IRQ1A */
-	PINMUX_IRQ(irq_pin(2), GPIO_PORT11,  GPIO_PORT12),	/* IRQ2A */
-	PINMUX_IRQ(irq_pin(3), GPIO_PORT10,  GPIO_PORT14),	/* IRQ3A */
-	PINMUX_IRQ(irq_pin(4), GPIO_PORT15,  GPIO_PORT172),/* IRQ4A */
-	PINMUX_IRQ(irq_pin(5), GPIO_PORT0,   GPIO_PORT1),	/* IRQ5A */
-	PINMUX_IRQ(irq_pin(6), GPIO_PORT121, GPIO_PORT173),/* IRQ6A */
-	PINMUX_IRQ(irq_pin(7), GPIO_PORT120, GPIO_PORT209),/* IRQ7A */
-	PINMUX_IRQ(irq_pin(8), GPIO_PORT119),		/* IRQ8A */
-	PINMUX_IRQ(irq_pin(9), GPIO_PORT118, GPIO_PORT210),/* IRQ9A */
-	PINMUX_IRQ(irq_pin(10), GPIO_PORT19),		/* IRQ10A */
-	PINMUX_IRQ(irq_pin(11), GPIO_PORT104),		/* IRQ11A */
-	PINMUX_IRQ(irq_pin(12), GPIO_PORT42,  GPIO_PORT97),	/* IRQ12A */
-	PINMUX_IRQ(irq_pin(13), GPIO_PORT64,  GPIO_PORT98),	/* IRQ13A */
-	PINMUX_IRQ(irq_pin(14), GPIO_PORT63,  GPIO_PORT99),	/* IRQ14A */
-	PINMUX_IRQ(irq_pin(15), GPIO_PORT62,  GPIO_PORT100),/* IRQ15A */
-	PINMUX_IRQ(irq_pin(16), GPIO_PORT68,  GPIO_PORT211),/* IRQ16A */
-	PINMUX_IRQ(irq_pin(17), GPIO_PORT69),		/* IRQ17A */
-	PINMUX_IRQ(irq_pin(18), GPIO_PORT70),		/* IRQ18A */
-	PINMUX_IRQ(irq_pin(19), GPIO_PORT71),		/* IRQ19A */
-	PINMUX_IRQ(irq_pin(20), GPIO_PORT67),		/* IRQ20A */
-	PINMUX_IRQ(irq_pin(21), GPIO_PORT202),		/* IRQ21A */
-	PINMUX_IRQ(irq_pin(22), GPIO_PORT95),		/* IRQ22A */
-	PINMUX_IRQ(irq_pin(23), GPIO_PORT96),		/* IRQ23A */
-	PINMUX_IRQ(irq_pin(24), GPIO_PORT180),		/* IRQ24A */
-	PINMUX_IRQ(irq_pin(25), GPIO_PORT38),		/* IRQ25A */
-	PINMUX_IRQ(irq_pin(26), GPIO_PORT58,  GPIO_PORT81),	/* IRQ26A */
-	PINMUX_IRQ(irq_pin(27), GPIO_PORT57,  GPIO_PORT168),/* IRQ27A */
-	PINMUX_IRQ(irq_pin(28), GPIO_PORT56,  GPIO_PORT169),/* IRQ28A */
-	PINMUX_IRQ(irq_pin(29), GPIO_PORT50,  GPIO_PORT170),/* IRQ29A */
-	PINMUX_IRQ(irq_pin(30), GPIO_PORT49,  GPIO_PORT171),/* IRQ30A */
-	PINMUX_IRQ(irq_pin(31), GPIO_PORT41,  GPIO_PORT167),/* IRQ31A */
+	PINMUX_IRQ(irq_pin(0), 2,   13),	/* IRQ0A */
+	PINMUX_IRQ(irq_pin(1), 20),		/* IRQ1A */
+	PINMUX_IRQ(irq_pin(2), 11,  12),	/* IRQ2A */
+	PINMUX_IRQ(irq_pin(3), 10,  14),	/* IRQ3A */
+	PINMUX_IRQ(irq_pin(4), 15,  172),	/* IRQ4A */
+	PINMUX_IRQ(irq_pin(5), 0,   1),		/* IRQ5A */
+	PINMUX_IRQ(irq_pin(6), 121, 173),	/* IRQ6A */
+	PINMUX_IRQ(irq_pin(7), 120, 209),	/* IRQ7A */
+	PINMUX_IRQ(irq_pin(8), 119),		/* IRQ8A */
+	PINMUX_IRQ(irq_pin(9), 118, 210),	/* IRQ9A */
+	PINMUX_IRQ(irq_pin(10), 19),		/* IRQ10A */
+	PINMUX_IRQ(irq_pin(11), 104),		/* IRQ11A */
+	PINMUX_IRQ(irq_pin(12), 42,  97),	/* IRQ12A */
+	PINMUX_IRQ(irq_pin(13), 64,  98),	/* IRQ13A */
+	PINMUX_IRQ(irq_pin(14), 63,  99),	/* IRQ14A */
+	PINMUX_IRQ(irq_pin(15), 62,  100),	/* IRQ15A */
+	PINMUX_IRQ(irq_pin(16), 68,  211),	/* IRQ16A */
+	PINMUX_IRQ(irq_pin(17), 69),		/* IRQ17A */
+	PINMUX_IRQ(irq_pin(18), 70),		/* IRQ18A */
+	PINMUX_IRQ(irq_pin(19), 71),		/* IRQ19A */
+	PINMUX_IRQ(irq_pin(20), 67),		/* IRQ20A */
+	PINMUX_IRQ(irq_pin(21), 202),		/* IRQ21A */
+	PINMUX_IRQ(irq_pin(22), 95),		/* IRQ22A */
+	PINMUX_IRQ(irq_pin(23), 96),		/* IRQ23A */
+	PINMUX_IRQ(irq_pin(24), 180),		/* IRQ24A */
+	PINMUX_IRQ(irq_pin(25), 38),		/* IRQ25A */
+	PINMUX_IRQ(irq_pin(26), 58,  81),	/* IRQ26A */
+	PINMUX_IRQ(irq_pin(27), 57,  168),	/* IRQ27A */
+	PINMUX_IRQ(irq_pin(28), 56,  169),	/* IRQ28A */
+	PINMUX_IRQ(irq_pin(29), 50,  170),	/* IRQ29A */
+	PINMUX_IRQ(irq_pin(30), 49,  171),	/* IRQ30A */
+	PINMUX_IRQ(irq_pin(31), 41,  167),	/* IRQ31A */
+};
+
+#define PORTnCR_PULMD_OFF	(0 << 6)
+#define PORTnCR_PULMD_DOWN	(2 << 6)
+#define PORTnCR_PULMD_UP	(3 << 6)
+#define PORTnCR_PULMD_MASK	(3 << 6)
+
+struct r8a7740_portcr_group {
+	unsigned int end_pin;
+	unsigned int offset;
+};
+
+static const struct r8a7740_portcr_group r8a7740_portcr_offsets[] = {
+	{ 83, 0x0000 }, { 114, 0x1000 }, { 209, 0x2000 }, { 211, 0x3000 },
+};
+
+static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(r8a7740_portcr_offsets); ++i) {
+		const struct r8a7740_portcr_group *group =
+			&r8a7740_portcr_offsets[i];
+
+		if (i <= group->end_pin)
+			return pfc->window->virt + group->offset + pin;
+	}
+
+	return NULL;
+}
+
+static unsigned int r8a7740_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)
+{
+	void __iomem *addr = r8a7740_pinmux_portcr(pfc, pin);
+	u32 value = ioread8(addr) & PORTnCR_PULMD_MASK;
+
+	switch (value) {
+	case PORTnCR_PULMD_UP:
+		return PIN_CONFIG_BIAS_PULL_UP;
+	case PORTnCR_PULMD_DOWN:
+		return PIN_CONFIG_BIAS_PULL_DOWN;
+	case PORTnCR_PULMD_OFF:
+	default:
+		return PIN_CONFIG_BIAS_DISABLE;
+	}
+}
+
+static void r8a7740_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
+				   unsigned int bias)
+{
+	void __iomem *addr = r8a7740_pinmux_portcr(pfc, pin);
+	u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK;
+
+	switch (bias) {
+	case PIN_CONFIG_BIAS_PULL_UP:
+		value |= PORTnCR_PULMD_UP;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		value |= PORTnCR_PULMD_DOWN;
+		break;
+	}
+
+	iowrite8(value, addr);
+}
+
+static const struct sh_pfc_soc_operations r8a7740_pinmux_ops = {
+	.get_bias = r8a7740_pinmux_get_bias,
+	.set_bias = r8a7740_pinmux_set_bias,
 };
 
 const struct sh_pfc_soc_info r8a7740_pinmux_info = {
 	.name		= "r8a7740_pfc",
+	.ops		= &r8a7740_pinmux_ops,
+
 	.input		= { PINMUX_INPUT_BEGIN,
 			    PINMUX_INPUT_END },
-	.input_pu	= { PINMUX_INPUT_PULLUP_BEGIN,
-			    PINMUX_INPUT_PULLUP_END },
-	.input_pd	= { PINMUX_INPUT_PULLDOWN_BEGIN,
-			    PINMUX_INPUT_PULLDOWN_END },
 	.output		= { PINMUX_OUTPUT_BEGIN,
 			    PINMUX_OUTPUT_END },
 	.function	= { PINMUX_FUNCTION_BEGIN,
@@ -3048,9 +3802,6 @@ const struct sh_pfc_soc_info r8a7740_pin
 	.functions	= pinmux_functions,
 	.nr_functions	= ARRAY_SIZE(pinmux_functions),
 
-	.func_gpios	= pinmux_func_gpios,
-	.nr_func_gpios	= ARRAY_SIZE(pinmux_func_gpios),
-
 	.cfg_regs	= pinmux_config_regs,
 	.data_regs	= pinmux_data_regs,
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7778.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7778.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7778.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7778.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2783 @@
+/*
+ * r8a7778 processor support - PFC hardware block
+ *
+ * Copyright (C) 2013  Renesas Solutions Corp.
+ * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (C) 2013  Cogent Embedded, Inc.
+ *
+ * based on
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/platform_data/gpio-rcar.h>
+#include <linux/kernel.h>
+#include "sh_pfc.h"
+
+#define PORT_GP_1(bank, pin, fn, sfx) fn(bank, pin, GP_##bank##_##pin, sfx)
+
+#define PORT_GP_32(bank, fn, sfx)					\
+	PORT_GP_1(bank, 0,  fn, sfx), PORT_GP_1(bank, 1,  fn, sfx),	\
+	PORT_GP_1(bank, 2,  fn, sfx), PORT_GP_1(bank, 3,  fn, sfx),	\
+	PORT_GP_1(bank, 4,  fn, sfx), PORT_GP_1(bank, 5,  fn, sfx),	\
+	PORT_GP_1(bank, 6,  fn, sfx), PORT_GP_1(bank, 7,  fn, sfx),	\
+	PORT_GP_1(bank, 8,  fn, sfx), PORT_GP_1(bank, 9,  fn, sfx),	\
+	PORT_GP_1(bank, 10, fn, sfx), PORT_GP_1(bank, 11, fn, sfx),	\
+	PORT_GP_1(bank, 12, fn, sfx), PORT_GP_1(bank, 13, fn, sfx),	\
+	PORT_GP_1(bank, 14, fn, sfx), PORT_GP_1(bank, 15, fn, sfx),	\
+	PORT_GP_1(bank, 16, fn, sfx), PORT_GP_1(bank, 17, fn, sfx),	\
+	PORT_GP_1(bank, 18, fn, sfx), PORT_GP_1(bank, 19, fn, sfx),	\
+	PORT_GP_1(bank, 20, fn, sfx), PORT_GP_1(bank, 21, fn, sfx),	\
+	PORT_GP_1(bank, 22, fn, sfx), PORT_GP_1(bank, 23, fn, sfx),	\
+	PORT_GP_1(bank, 24, fn, sfx), PORT_GP_1(bank, 25, fn, sfx),	\
+	PORT_GP_1(bank, 26, fn, sfx), PORT_GP_1(bank, 27, fn, sfx),	\
+	PORT_GP_1(bank, 28, fn, sfx), PORT_GP_1(bank, 29, fn, sfx),	\
+	PORT_GP_1(bank, 30, fn, sfx), PORT_GP_1(bank, 31, fn, sfx)
+
+#define PORT_GP_27(bank, fn, sfx)					\
+	PORT_GP_1(bank, 0,  fn, sfx), PORT_GP_1(bank, 1,  fn, sfx),	\
+	PORT_GP_1(bank, 2,  fn, sfx), PORT_GP_1(bank, 3,  fn, sfx),	\
+	PORT_GP_1(bank, 4,  fn, sfx), PORT_GP_1(bank, 5,  fn, sfx),	\
+	PORT_GP_1(bank, 6,  fn, sfx), PORT_GP_1(bank, 7,  fn, sfx),	\
+	PORT_GP_1(bank, 8,  fn, sfx), PORT_GP_1(bank, 9,  fn, sfx),	\
+	PORT_GP_1(bank, 10, fn, sfx), PORT_GP_1(bank, 11, fn, sfx),	\
+	PORT_GP_1(bank, 12, fn, sfx), PORT_GP_1(bank, 13, fn, sfx),	\
+	PORT_GP_1(bank, 14, fn, sfx), PORT_GP_1(bank, 15, fn, sfx),	\
+	PORT_GP_1(bank, 16, fn, sfx), PORT_GP_1(bank, 17, fn, sfx),	\
+	PORT_GP_1(bank, 18, fn, sfx), PORT_GP_1(bank, 19, fn, sfx),	\
+	PORT_GP_1(bank, 20, fn, sfx), PORT_GP_1(bank, 21, fn, sfx),	\
+	PORT_GP_1(bank, 22, fn, sfx), PORT_GP_1(bank, 23, fn, sfx),	\
+	PORT_GP_1(bank, 24, fn, sfx), PORT_GP_1(bank, 25, fn, sfx),	\
+	PORT_GP_1(bank, 26, fn, sfx)
+
+#define CPU_ALL_PORT(fn, sfx)		\
+	PORT_GP_32(0, fn, sfx),		\
+	PORT_GP_32(1, fn, sfx),		\
+	PORT_GP_32(2, fn, sfx),		\
+	PORT_GP_32(3, fn, sfx),		\
+	PORT_GP_27(4, fn, sfx)
+
+#define _GP_PORT_ALL(bank, pin, name, sfx)	name##_##sfx
+
+#define _GP_GPIO(bank, pin, _name, sfx)		\
+	[RCAR_GP_PIN(bank, pin)] = {		\
+		.name = __stringify(_name),	\
+		.enum_id = _name##_DATA,	\
+	}
+
+#define _GP_DATA(bank, pin, name, sfx)		\
+	PINMUX_DATA(name##_DATA, name##_FN)
+
+#define GP_ALL(str)		CPU_ALL_PORT(_GP_PORT_ALL, str)
+#define PINMUX_GPIO_GP_ALL()	CPU_ALL_PORT(_GP_GPIO, unused)
+#define PINMUX_DATA_GP_ALL()	CPU_ALL_PORT(_GP_DATA, unused)
+
+#define PINMUX_IPSR_NOGP(ispr, fn)	PINMUX_DATA(fn##_MARK, FN_##fn)
+#define PINMUX_IPSR_DATA(ipsr, fn)	PINMUX_DATA(fn##_MARK, FN_##fn, FN_##ipsr)
+#define PINMUX_IPSR_MSEL(ipsr, fn, ms)	PINMUX_DATA(fn##_MARK, FN_##fn, FN_##ipsr, FN_##ms)
+#define PINMUX_IPSR_NOGM(ispr, fn, ms)	PINMUX_DATA(fn##_MARK, FN_##fn,            FN_##ms)
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	GP_ALL(DATA), /* GP_0_0_DATA -> GP_4_26_DATA */
+	PINMUX_DATA_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	GP_ALL(FN), /* GP_0_0_FN -> GP_4_26_FN */
+
+	/* GPSR0 */
+	FN_IP0_1_0,	FN_PENC0,	FN_PENC1,	FN_IP0_4_2,
+	FN_IP0_7_5,	FN_IP0_11_8,	FN_IP0_14_12,	FN_A1,
+	FN_A2,		FN_A3,		FN_IP0_15,	FN_IP0_16,
+	FN_IP0_17,	FN_IP0_18,	FN_IP0_19,	FN_IP0_20,
+	FN_IP0_21,	FN_IP0_22,	FN_IP0_23,	FN_IP0_24,
+	FN_IP0_25,	FN_IP0_26,	FN_IP0_27,	FN_IP0_28,
+	FN_IP0_29,	FN_IP0_30,	FN_IP1_0,	FN_IP1_1,
+	FN_IP1_4_2,	FN_IP1_7_5,	FN_IP1_10_8,	FN_IP1_14_11,
+
+	/* GPSR1 */
+	FN_IP1_23_21,	FN_WE0,		FN_IP1_24,	FN_IP1_27_25,
+	FN_IP1_29_28,	FN_IP2_2_0,	FN_IP2_5_3,	FN_IP2_8_6,
+	FN_IP2_11_9,	FN_IP2_13_12,	FN_IP2_16_14,	FN_IP2_17,
+	FN_IP2_30,	FN_IP2_31,	FN_IP3_1_0,	FN_IP3_4_2,
+	FN_IP3_7_5,	FN_IP3_9_8,	FN_IP3_12_10,	FN_IP3_15_13,
+	FN_IP3_18_16,	FN_IP3_20_19,	FN_IP3_23_21,	FN_IP3_26_24,
+	FN_IP3_27,	FN_IP3_28,	FN_IP3_29,	FN_IP3_30,
+	FN_IP3_31,	FN_IP4_0,	FN_IP4_3_1,	FN_IP4_6_4,
+
+	/* GPSR2 */
+	FN_IP4_7,	FN_IP4_8,	FN_IP4_10_9,	FN_IP4_12_11,
+	FN_IP4_14_13,	FN_IP4_16_15,	FN_IP4_20_17,	FN_IP4_24_21,
+	FN_IP4_26_25,	FN_IP4_28_27,	FN_IP4_30_29,	FN_IP5_1_0,
+	FN_IP5_3_2,	FN_IP5_5_4,	FN_IP5_6,	FN_IP5_7,
+	FN_IP5_9_8,	FN_IP5_11_10,	FN_IP5_12,	FN_IP5_14_13,
+	FN_IP5_17_15,	FN_IP5_20_18,	FN_AUDIO_CLKA,	FN_AUDIO_CLKB,
+	FN_IP5_22_21,	FN_IP5_25_23,	FN_IP5_28_26,	FN_IP5_30_29,
+	FN_IP6_1_0,	FN_IP6_4_2,	FN_IP6_6_5,	FN_IP6_7,
+
+	/* GPSR3 */
+	FN_IP6_8,	FN_IP6_9,	FN_SSI_SCK34,	FN_IP6_10,
+	FN_IP6_12_11,	FN_IP6_13,	FN_IP6_15_14,	FN_IP6_16,
+	FN_IP6_18_17,	FN_IP6_20_19,	FN_IP6_21,	FN_IP6_23_22,
+	FN_IP6_25_24,	FN_IP6_27_26,	FN_IP6_29_28,	FN_IP6_31_30,
+	FN_IP7_1_0,	FN_IP7_3_2,	FN_IP7_5_4,	FN_IP7_8_6,
+	FN_IP7_11_9,	FN_IP7_14_12,	FN_IP7_17_15,	FN_IP7_20_18,
+	FN_IP7_21,	FN_IP7_24_22,	FN_IP7_28_25,	FN_IP7_31_29,
+	FN_IP8_2_0,	FN_IP8_5_3,	FN_IP8_8_6,	FN_IP8_10_9,
+
+	/* GPSR4 */
+	FN_IP8_13_11,	FN_IP8_15_14,	FN_IP8_18_16,	FN_IP8_21_19,
+	FN_IP8_23_22,	FN_IP8_26_24,	FN_IP8_29_27,	FN_IP9_2_0,
+	FN_IP9_5_3,	FN_IP9_8_6,	FN_IP9_11_9,	FN_IP9_14_12,
+	FN_IP9_17_15,	FN_IP9_20_18,	FN_IP9_23_21,	FN_IP9_26_24,
+	FN_IP9_29_27,	FN_IP10_2_0,	FN_IP10_5_3,	FN_IP10_8_6,
+	FN_IP10_12_9,	FN_IP10_15_13,	FN_IP10_18_16,	FN_IP10_21_19,
+	FN_IP10_24_22,	FN_AVS1,	FN_AVS2,
+
+	/* IPSR0 */
+	FN_PRESETOUT,	FN_PWM1,	FN_AUDATA0,	FN_ARM_TRACEDATA_0,
+	FN_GPSCLK_C,	FN_USB_OVC0,	FN_TX2_E,	FN_SDA2_B,
+	FN_AUDATA1,	FN_ARM_TRACEDATA_1,		FN_GPSIN_C,
+	FN_USB_OVC1,	FN_RX2_E,	FN_SCL2_B,	FN_SD1_DAT2_A,
+	FN_MMC_D2,	FN_BS,		FN_ATADIR0_A,	FN_SDSELF_A,
+	FN_PWM4_B,	FN_SD1_DAT3_A,	FN_MMC_D3,	FN_A0,
+	FN_ATAG0_A,	FN_REMOCON_B,	FN_A4,		FN_A5,
+	FN_A6,		FN_A7,		FN_A8,		FN_A9,
+	FN_A10,		FN_A11,		FN_A12,		FN_A13,
+	FN_A14,		FN_A15,		FN_A16,		FN_A17,
+	FN_A18,		FN_A19,
+
+	/* IPSR1 */
+	FN_A20,		FN_HSPI_CS1_B,	FN_A21,		FN_HSPI_CLK1_B,
+	FN_A22,		FN_HRTS0_B,	FN_RX2_B,	FN_DREQ2_A,
+	FN_A23,		FN_HTX0_B,	FN_TX2_B,	FN_DACK2_A,
+	FN_TS_SDEN0_A,	FN_SD1_CD_A,	FN_MMC_D6,	FN_A24,
+	FN_DREQ1_A,	FN_HRX0_B,	FN_TS_SPSYNC0_A,
+	FN_SD1_WP_A,	FN_MMC_D7,	FN_A25,	FN_DACK1_A,
+	FN_HCTS0_B,	FN_RX3_C,	FN_TS_SDAT0_A,	FN_CLKOUT,
+	FN_HSPI_TX1_B,	FN_PWM0_B,	FN_CS0,		FN_HSPI_RX1_B,
+	FN_SSI_SCK1_B,	FN_ATAG0_B,	FN_CS1_A26,	FN_SDA2_A,
+	FN_SCK2_B,	FN_MMC_D5,	FN_ATADIR0_B,	FN_RD_WR,
+	FN_WE1,		FN_ATAWR0_B,	FN_SSI_WS1_B,	FN_EX_CS0,
+	FN_SCL2_A,	FN_TX3_C,	FN_TS_SCK0_A,	FN_EX_CS1,
+	FN_MMC_D4,
+
+	/* IPSR2 */
+	FN_SD1_CLK_A,	FN_MMC_CLK,	FN_ATACS00,	FN_EX_CS2,
+	FN_SD1_CMD_A,	FN_MMC_CMD,	FN_ATACS10,	FN_EX_CS3,
+	FN_SD1_DAT0_A,	FN_MMC_D0,	FN_ATARD0,	FN_EX_CS4,
+	FN_EX_WAIT1_A,	FN_SD1_DAT1_A,	FN_MMC_D1,	FN_ATAWR0_A,
+	FN_EX_CS5,	FN_EX_WAIT2_A,	FN_DREQ0_A,	FN_RX3_A,
+	FN_DACK0,	FN_TX3_A,	FN_DRACK0,	FN_EX_WAIT0,
+	FN_PWM0_C,	FN_D0,		FN_D1,		FN_D2,
+	FN_D3,		FN_D4,		FN_D5,		FN_D6,
+	FN_D7,		FN_D8,		FN_D9,		FN_D10,
+	FN_D11,		FN_RD_WR_B,	FN_IRQ0,	FN_MLB_CLK,
+	FN_IRQ1_A,
+
+	/* IPSR3 */
+	FN_MLB_SIG,	FN_RX5_B,	FN_SDA3_A,	FN_IRQ2_A,
+	FN_MLB_DAT,	FN_TX5_B,	FN_SCL3_A,	FN_IRQ3_A,
+	FN_SDSELF_B,	FN_SD1_CMD_B,	FN_SCIF_CLK,	FN_AUDIO_CLKOUT_B,
+	FN_CAN_CLK_B,	FN_SDA3_B,	FN_SD1_CLK_B,	FN_HTX0_A,
+	FN_TX0_A,	FN_SD1_DAT0_B,	FN_HRX0_A,	FN_RX0_A,
+	FN_SD1_DAT1_B,	FN_HSCK0,	FN_SCK0,	FN_SCL3_B,
+	FN_SD1_DAT2_B,	FN_HCTS0_A,	FN_CTS0,	FN_SD1_DAT3_B,
+	FN_HRTS0_A,	FN_RTS0,	FN_SSI_SCK4,	FN_DU0_DR0,
+	FN_LCDOUT0,	FN_AUDATA2,	FN_ARM_TRACEDATA_2,
+	FN_SDA3_C,	FN_ADICHS1,	FN_TS_SDEN0_B,	FN_SSI_WS4,
+	FN_DU0_DR1,	FN_LCDOUT1,	FN_AUDATA3,	FN_ARM_TRACEDATA_3,
+	FN_SCL3_C,	FN_ADICHS2,	FN_TS_SPSYNC0_B,
+	FN_DU0_DR2,	FN_LCDOUT2,	FN_DU0_DR3,	FN_LCDOUT3,
+	FN_DU0_DR4,	FN_LCDOUT4,	FN_DU0_DR5,	FN_LCDOUT5,
+	FN_DU0_DR6,	FN_LCDOUT6,
+
+	/* IPSR4 */
+	FN_DU0_DR7,	FN_LCDOUT7,	FN_DU0_DG0,	FN_LCDOUT8,
+	FN_AUDATA4,	FN_ARM_TRACEDATA_4,		FN_TX1_D,
+	FN_CAN0_TX_A,	FN_ADICHS0,	FN_DU0_DG1,	FN_LCDOUT9,
+	FN_AUDATA5,	FN_ARM_TRACEDATA_5,		FN_RX1_D,
+	FN_CAN0_RX_A,	FN_ADIDATA,	FN_DU0_DG2,	FN_LCDOUT10,
+	FN_DU0_DG3,	FN_LCDOUT11,	FN_DU0_DG4,	FN_LCDOUT12,
+	FN_RX0_B,	FN_DU0_DG5,	FN_LCDOUT13,	FN_TX0_B,
+	FN_DU0_DG6,	FN_LCDOUT14,	FN_RX4_A,	FN_DU0_DG7,
+	FN_LCDOUT15,	FN_TX4_A,	FN_SSI_SCK2_B,	FN_VI0_R0_B,
+	FN_DU0_DB0,	FN_LCDOUT16,	FN_AUDATA6,	FN_ARM_TRACEDATA_6,
+	FN_GPSCLK_A,	FN_PWM0_A,	FN_ADICLK,	FN_TS_SDAT0_B,
+	FN_AUDIO_CLKC,	FN_VI0_R1_B,	FN_DU0_DB1,	FN_LCDOUT17,
+	FN_AUDATA7,	FN_ARM_TRACEDATA_7,		FN_GPSIN_A,
+	FN_ADICS_SAMP,	FN_TS_SCK0_B,	FN_VI0_R2_B,	FN_DU0_DB2,
+	FN_LCDOUT18,	FN_VI0_R3_B,	FN_DU0_DB3,	FN_LCDOUT19,
+	FN_VI0_R4_B,	FN_DU0_DB4,	FN_LCDOUT20,
+
+	/* IPSR5 */
+	FN_VI0_R5_B,	FN_DU0_DB5,	FN_LCDOUT21,	FN_VI1_DATA10_B,
+	FN_DU0_DB6,	FN_LCDOUT22,	FN_VI1_DATA11_B,
+	FN_DU0_DB7,	FN_LCDOUT23,	FN_DU0_DOTCLKIN,
+	FN_QSTVA_QVS,	FN_DU0_DOTCLKO_UT0,		FN_QCLK,
+	FN_DU0_DOTCLKO_UT1,		FN_QSTVB_QVE,	FN_AUDIO_CLKOUT_A,
+	FN_REMOCON_C,	FN_SSI_WS2_B,	FN_DU0_EXHSYNC_DU0_HSYNC,
+	FN_QSTH_QHS,	FN_DU0_EXVSYNC_DU0_VSYNC,	FN_QSTB_QHE,
+	FN_DU0_EXODDF_DU0_ODDF_DISP_CDE,
+	FN_QCPV_QDE,	FN_FMCLK_D,	FN_SSI_SCK1_A,	FN_DU0_DISP,
+	FN_QPOLA,	FN_AUDCK,	FN_ARM_TRACECLK,
+	FN_BPFCLK_D,	FN_SSI_WS1_A,	FN_DU0_CDE,	FN_QPOLB,
+	FN_AUDSYNC,	FN_ARM_TRACECTL,		FN_FMIN_D,
+	FN_SD1_CD_B,	FN_SSI_SCK78,	FN_HSPI_RX0_B,	FN_TX1_B,
+	FN_SD1_WP_B,	FN_SSI_WS78,	FN_HSPI_CLK0_B,	FN_RX1_B,
+	FN_CAN_CLK_D,	FN_SSI_SDATA8,	FN_SSI_SCK2_A,	FN_HSPI_CS0_B,
+	FN_TX2_A,	FN_CAN0_TX_B,	FN_SSI_SDATA7,	FN_HSPI_TX0_B,
+	FN_RX2_A,	FN_CAN0_RX_B,
+
+	/* IPSR6 */
+	FN_SSI_SCK6,	FN_HSPI_RX2_A,	FN_FMCLK_B,	FN_CAN1_TX_B,
+	FN_SSI_WS6,	FN_HSPI_CLK2_A,	FN_BPFCLK_B,	FN_CAN1_RX_B,
+	FN_SSI_SDATA6,	FN_HSPI_TX2_A,	FN_FMIN_B,	FN_SSI_SCK5,
+	FN_RX4_C,	FN_SSI_WS5,	FN_TX4_C,	FN_SSI_SDATA5,
+	FN_RX0_D,	FN_SSI_WS34,	FN_ARM_TRACEDATA_8,
+	FN_SSI_SDATA4,	FN_SSI_WS2_A,	FN_ARM_TRACEDATA_9,
+	FN_SSI_SDATA3,	FN_ARM_TRACEDATA_10,
+	FN_SSI_SCK012,	FN_ARM_TRACEDATA_11,
+	FN_TX0_D,	FN_SSI_WS012,	FN_ARM_TRACEDATA_12,
+	FN_SSI_SDATA2,	FN_HSPI_CS2_A,	FN_ARM_TRACEDATA_13,
+	FN_SDA1_A,	FN_SSI_SDATA1,	FN_ARM_TRACEDATA_14,
+	FN_SCL1_A,	FN_SCK2_A,	FN_SSI_SDATA0,
+	FN_ARM_TRACEDATA_15,
+	FN_SD0_CLK,	FN_SUB_TDO,	FN_SD0_CMD,	FN_SUB_TRST,
+	FN_SD0_DAT0,	FN_SUB_TMS,	FN_SD0_DAT1,	FN_SUB_TCK,
+	FN_SD0_DAT2,	FN_SUB_TDI,
+
+	/* IPSR7 */
+	FN_SD0_DAT3,	FN_IRQ1_B,	FN_SD0_CD,	FN_TX5_A,
+	FN_SD0_WP,	FN_RX5_A,	FN_VI1_CLKENB,	FN_HSPI_CLK0_A,
+	FN_HTX1_A,	FN_RTS1_C,	FN_VI1_FIELD,	FN_HSPI_CS0_A,
+	FN_HRX1_A,	FN_SCK1_C,	FN_VI1_HSYNC,	FN_HSPI_RX0_A,
+	FN_HRTS1_A,	FN_FMCLK_A,	FN_RX1_C,	FN_VI1_VSYNC,
+	FN_HSPI_TX0,	FN_HCTS1_A,	FN_BPFCLK_A,	FN_TX1_C,
+	FN_TCLK0,	FN_HSCK1_A,	FN_FMIN_A,	FN_IRQ2_C,
+	FN_CTS1_C,	FN_SPEEDIN,	FN_VI0_CLK,	FN_CAN_CLK_A,
+	FN_VI0_CLKENB,	FN_SD2_DAT2_B,	FN_VI1_DATA0,	FN_DU1_DG6,
+	FN_HSPI_RX1_A,	FN_RX4_B,	FN_VI0_FIELD,	FN_SD2_DAT3_B,
+	FN_VI0_R3_C,	FN_VI1_DATA1,	FN_DU1_DG7,	FN_HSPI_CLK1_A,
+	FN_TX4_B,	FN_VI0_HSYNC,	FN_SD2_CD_B,	FN_VI1_DATA2,
+	FN_DU1_DR2,	FN_HSPI_CS1_A,	FN_RX3_B,
+
+	/* IPSR8 */
+	FN_VI0_VSYNC,	FN_SD2_WP_B,	FN_VI1_DATA3,	FN_DU1_DR3,
+	FN_HSPI_TX1_A,	FN_TX3_B,	FN_VI0_DATA0_VI0_B0,
+	FN_DU1_DG2,	FN_IRQ2_B,	FN_RX3_D,	FN_VI0_DATA1_VI0_B1,
+	FN_DU1_DG3,	FN_IRQ3_B,	FN_TX3_D,	FN_VI0_DATA2_VI0_B2,
+	FN_DU1_DG4,	FN_RX0_C,	FN_VI0_DATA3_VI0_B3,
+	FN_DU1_DG5,	FN_TX1_A,	FN_TX0_C,	FN_VI0_DATA4_VI0_B4,
+	FN_DU1_DB2,	FN_RX1_A,	FN_VI0_DATA5_VI0_B5,
+	FN_DU1_DB3,	FN_SCK1_A,	FN_PWM4,	FN_HSCK1_B,
+	FN_VI0_DATA6_VI0_G0,		FN_DU1_DB4,	FN_CTS1_A,
+	FN_PWM5,	FN_VI0_DATA7_VI0_G1,		FN_DU1_DB5,
+	FN_RTS1_A,	FN_VI0_G2,	FN_SD2_CLK_B,	FN_VI1_DATA4,
+	FN_DU1_DR4,	FN_HTX1_B,	FN_VI0_G3,	FN_SD2_CMD_B,
+	FN_VI1_DATA5,	FN_DU1_DR5,	FN_HRX1_B,
+
+	/* IPSR9 */
+	FN_VI0_G4,	FN_SD2_DAT0_B,	FN_VI1_DATA6,	FN_DU1_DR6,
+	FN_HRTS1_B,	FN_VI0_G5,	FN_SD2_DAT1_B,	FN_VI1_DATA7,
+	FN_DU1_DR7,	FN_HCTS1_B,	FN_VI0_R0_A,	FN_VI1_CLK,
+	FN_ETH_REF_CLK,	FN_DU1_DOTCLKIN,		FN_VI0_R1_A,
+	FN_VI1_DATA8,	FN_DU1_DB6,	FN_ETH_TXD0,	FN_PWM2,
+	FN_TCLK1,	FN_VI0_R2_A,	FN_VI1_DATA9,	FN_DU1_DB7,
+	FN_ETH_TXD1,	FN_PWM3,	FN_VI0_R3_A,	FN_ETH_CRS_DV,
+	FN_IECLK,	FN_SCK2_C,	FN_VI0_R4_A,	FN_ETH_TX_EN,
+	FN_IETX,	FN_TX2_C,	FN_VI0_R5_A,	FN_ETH_RX_ER,
+	FN_FMCLK_C,	FN_IERX,	FN_RX2_C,	FN_VI1_DATA10_A,
+	FN_DU1_DOTCLKOUT,		FN_ETH_RXD0,	FN_BPFCLK_C,
+	FN_TX2_D,	FN_SDA2_C,	FN_VI1_DATA11_A,
+	FN_DU1_EXHSYNC_DU1_HSYNC,	FN_ETH_RXD1,	FN_FMIN_C,
+	FN_RX2_D,	FN_SCL2_C,
+
+	/* IPSR10 */
+	FN_SD2_CLK_A,	FN_DU1_EXVSYNC_DU1_VSYNC,	FN_ATARD1,
+	FN_ETH_MDC,	FN_SDA1_B,	FN_SD2_CMD_A,
+	FN_DU1_EXODDF_DU1_ODDF_DISP_CDE,		FN_ATAWR1,
+	FN_ETH_MDIO,	FN_SCL1_B,	FN_SD2_DAT0_A,	FN_DU1_DISP,
+	FN_ATACS01,	FN_DREQ1_B,	FN_ETH_LINK,	FN_CAN1_RX_A,
+	FN_SD2_DAT1_A,	FN_DU1_CDE,	FN_ATACS11,	FN_DACK1_B,
+	FN_ETH_MAGIC,	FN_CAN1_TX_A,	FN_PWM6,	FN_SD2_DAT2_A,
+	FN_VI1_DATA12,	FN_DREQ2_B,	FN_ATADIR1,	FN_HSPI_CLK2_B,
+	FN_GPSCLK_B,	FN_SD2_DAT3_A,	FN_VI1_DATA13,	FN_DACK2_B,
+	FN_ATAG1,	FN_HSPI_CS2_B,	FN_GPSIN_B,	FN_SD2_CD_A,
+	FN_VI1_DATA14,	FN_EX_WAIT1_B,	FN_DREQ0_B,	FN_HSPI_RX2_B,
+	FN_REMOCON_A,	FN_SD2_WP_A,	FN_VI1_DATA15,	FN_EX_WAIT2_B,
+	FN_DACK0_B,	FN_HSPI_TX2_B,	FN_CAN_CLK_C,
+
+	/* SEL */
+	FN_SEL_SCIF5_A,	FN_SEL_SCIF5_B,
+	FN_SEL_SCIF4_A,	FN_SEL_SCIF4_B,	FN_SEL_SCIF4_C,
+	FN_SEL_SCIF3_A,	FN_SEL_SCIF3_B,	FN_SEL_SCIF3_C,	FN_SEL_SCIF3_D,
+	FN_SEL_SCIF2_A,	FN_SEL_SCIF2_B,	FN_SEL_SCIF2_C,	FN_SEL_SCIF2_D,	FN_SEL_SCIF2_E,
+	FN_SEL_SCIF1_A,	FN_SEL_SCIF1_B,	FN_SEL_SCIF1_C,	FN_SEL_SCIF1_D,
+	FN_SEL_SCIF0_A,	FN_SEL_SCIF0_B,	FN_SEL_SCIF0_C,	FN_SEL_SCIF0_D,
+	FN_SEL_SSI2_A,	FN_SEL_SSI2_B,
+	FN_SEL_SSI1_A,	FN_SEL_SSI1_B,
+	FN_SEL_VI1_A,	FN_SEL_VI1_B,
+	FN_SEL_VI0_A,	FN_SEL_VI0_B,	FN_SEL_VI0_C,	FN_SEL_VI0_D,
+	FN_SEL_SD2_A,	FN_SEL_SD2_B,
+	FN_SEL_SD1_A,	FN_SEL_SD1_B,
+	FN_SEL_IRQ3_A,	FN_SEL_IRQ3_B,
+	FN_SEL_IRQ2_A,	FN_SEL_IRQ2_B,	FN_SEL_IRQ2_C,
+	FN_SEL_IRQ1_A,	FN_SEL_IRQ1_B,
+	FN_SEL_DREQ2_A,	FN_SEL_DREQ2_B,
+	FN_SEL_DREQ1_A,	FN_SEL_DREQ1_B,
+	FN_SEL_DREQ0_A,	FN_SEL_DREQ0_B,
+	FN_SEL_WAIT2_A,	FN_SEL_WAIT2_B,
+	FN_SEL_WAIT1_A,	FN_SEL_WAIT1_B,
+	FN_SEL_CAN1_A,	FN_SEL_CAN1_B,
+	FN_SEL_CAN0_A,	FN_SEL_CAN0_B,
+	FN_SEL_CANCLK_A,	FN_SEL_CANCLK_B,
+	FN_SEL_CANCLK_C,	FN_SEL_CANCLK_D,
+	FN_SEL_HSCIF1_A,	FN_SEL_HSCIF1_B,
+	FN_SEL_HSCIF0_A,	FN_SEL_HSCIF0_B,
+	FN_SEL_REMOCON_A,	FN_SEL_REMOCON_B,	FN_SEL_REMOCON_C,
+	FN_SEL_FM_A,	FN_SEL_FM_B,	FN_SEL_FM_C,	FN_SEL_FM_D,
+	FN_SEL_GPS_A,	FN_SEL_GPS_B,	FN_SEL_GPS_C,
+	FN_SEL_TSIF0_A,	FN_SEL_TSIF0_B,
+	FN_SEL_HSPI2_A,	FN_SEL_HSPI2_B,
+	FN_SEL_HSPI1_A,	FN_SEL_HSPI1_B,
+	FN_SEL_HSPI0_A,	FN_SEL_HSPI0_B,
+	FN_SEL_I2C3_A,	FN_SEL_I2C3_B,	FN_SEL_I2C3_C,
+	FN_SEL_I2C2_A,	FN_SEL_I2C2_B,	FN_SEL_I2C2_C,
+	FN_SEL_I2C1_A,	FN_SEL_I2C1_B,
+	PINMUX_FUNCTION_END,
+
+	PINMUX_MARK_BEGIN,
+
+	/* GPSR0 */
+	PENC0_MARK,	PENC1_MARK,	A1_MARK,	A2_MARK,	A3_MARK,
+
+	/* GPSR1 */
+	WE0_MARK,
+
+	/* GPSR2 */
+	AUDIO_CLKA_MARK,
+	AUDIO_CLKB_MARK,
+
+	/* GPSR3 */
+	SSI_SCK34_MARK,
+
+	/* GPSR4 */
+	AVS1_MARK,
+	AVS2_MARK,
+
+	VI0_R0_C_MARK,		/* see sel_vi0 */
+	VI0_R1_C_MARK,		/* see sel_vi0 */
+	VI0_R2_C_MARK,		/* see sel_vi0 */
+	/* VI0_R3_C_MARK, */
+	VI0_R4_C_MARK,		/* see sel_vi0 */
+	VI0_R5_C_MARK,		/* see sel_vi0 */
+
+	VI0_R0_D_MARK,		/* see sel_vi0 */
+	VI0_R1_D_MARK,		/* see sel_vi0 */
+	VI0_R2_D_MARK,		/* see sel_vi0 */
+	VI0_R3_D_MARK,		/* see sel_vi0 */
+	VI0_R4_D_MARK,		/* see sel_vi0 */
+	VI0_R5_D_MARK,		/* see sel_vi0 */
+
+	/* IPSR0 */
+	PRESETOUT_MARK,	PWM1_MARK,	AUDATA0_MARK,
+	ARM_TRACEDATA_0_MARK,		GPSCLK_C_MARK,	USB_OVC0_MARK,
+	TX2_E_MARK,	SDA2_B_MARK,	AUDATA1_MARK,	ARM_TRACEDATA_1_MARK,
+	GPSIN_C_MARK,	USB_OVC1_MARK,	RX2_E_MARK,	SCL2_B_MARK,
+	SD1_DAT2_A_MARK,		MMC_D2_MARK,	BS_MARK,
+	ATADIR0_A_MARK,	SDSELF_A_MARK,	PWM4_B_MARK,	SD1_DAT3_A_MARK,
+	MMC_D3_MARK,	A0_MARK,	ATAG0_A_MARK,	REMOCON_B_MARK,
+	A4_MARK,	A5_MARK,	A6_MARK,	A7_MARK,
+	A8_MARK,	A9_MARK,	A10_MARK,	A11_MARK,
+	A12_MARK,	A13_MARK,	A14_MARK,	A15_MARK,
+	A16_MARK,	A17_MARK,	A18_MARK,	A19_MARK,
+
+	/* IPSR1 */
+	A20_MARK,	HSPI_CS1_B_MARK,		A21_MARK,
+	HSPI_CLK1_B_MARK,		A22_MARK,	HRTS0_B_MARK,
+	RX2_B_MARK,	DREQ2_A_MARK,	A23_MARK,	HTX0_B_MARK,
+	TX2_B_MARK,	DACK2_A_MARK,	TS_SDEN0_A_MARK,
+	SD1_CD_A_MARK,	MMC_D6_MARK,	A24_MARK,	DREQ1_A_MARK,
+	HRX0_B_MARK,	TS_SPSYNC0_A_MARK,		SD1_WP_A_MARK,
+	MMC_D7_MARK,	A25_MARK,	DACK1_A_MARK,	HCTS0_B_MARK,
+	RX3_C_MARK,	TS_SDAT0_A_MARK,		CLKOUT_MARK,
+	HSPI_TX1_B_MARK,		PWM0_B_MARK,	CS0_MARK,
+	HSPI_RX1_B_MARK,		SSI_SCK1_B_MARK,
+	ATAG0_B_MARK,	CS1_A26_MARK,	SDA2_A_MARK,	SCK2_B_MARK,
+	MMC_D5_MARK,	ATADIR0_B_MARK,	RD_WR_MARK,	WE1_MARK,
+	ATAWR0_B_MARK,	SSI_WS1_B_MARK,	EX_CS0_MARK,	SCL2_A_MARK,
+	TX3_C_MARK,	TS_SCK0_A_MARK,	EX_CS1_MARK,	MMC_D4_MARK,
+
+	/* IPSR2 */
+	SD1_CLK_A_MARK,	MMC_CLK_MARK,	ATACS00_MARK,	EX_CS2_MARK,
+	SD1_CMD_A_MARK,	MMC_CMD_MARK,	ATACS10_MARK,	EX_CS3_MARK,
+	SD1_DAT0_A_MARK,		MMC_D0_MARK,	ATARD0_MARK,
+	EX_CS4_MARK,	EX_WAIT1_A_MARK,		SD1_DAT1_A_MARK,
+	MMC_D1_MARK,	ATAWR0_A_MARK,	EX_CS5_MARK,	EX_WAIT2_A_MARK,
+	DREQ0_A_MARK,	RX3_A_MARK,	DACK0_MARK,	TX3_A_MARK,
+	DRACK0_MARK,	EX_WAIT0_MARK,	PWM0_C_MARK,	D0_MARK,
+	D1_MARK,	D2_MARK,	D3_MARK,	D4_MARK,
+	D5_MARK,	D6_MARK,	D7_MARK,	D8_MARK,
+	D9_MARK,	D10_MARK,	D11_MARK,	RD_WR_B_MARK,
+	IRQ0_MARK,	MLB_CLK_MARK,	IRQ1_A_MARK,
+
+	/* IPSR3 */
+	MLB_SIG_MARK,	RX5_B_MARK,	SDA3_A_MARK,	IRQ2_A_MARK,
+	MLB_DAT_MARK,	TX5_B_MARK,	SCL3_A_MARK,	IRQ3_A_MARK,
+	SDSELF_B_MARK,	SD1_CMD_B_MARK,	SCIF_CLK_MARK,	AUDIO_CLKOUT_B_MARK,
+	CAN_CLK_B_MARK,	SDA3_B_MARK,	SD1_CLK_B_MARK,	HTX0_A_MARK,
+	TX0_A_MARK,	SD1_DAT0_B_MARK,		HRX0_A_MARK,
+	RX0_A_MARK,	SD1_DAT1_B_MARK,		HSCK0_MARK,
+	SCK0_MARK,	SCL3_B_MARK,	SD1_DAT2_B_MARK,
+	HCTS0_A_MARK,	CTS0_MARK,	SD1_DAT3_B_MARK,
+	HRTS0_A_MARK,	RTS0_MARK,	SSI_SCK4_MARK,
+	DU0_DR0_MARK,	LCDOUT0_MARK,	AUDATA2_MARK,	ARM_TRACEDATA_2_MARK,
+	SDA3_C_MARK,	ADICHS1_MARK,	TS_SDEN0_B_MARK,
+	SSI_WS4_MARK,	DU0_DR1_MARK,	LCDOUT1_MARK,	AUDATA3_MARK,
+	ARM_TRACEDATA_3_MARK,		SCL3_C_MARK,	ADICHS2_MARK,
+	TS_SPSYNC0_B_MARK,		DU0_DR2_MARK,	LCDOUT2_MARK,
+	DU0_DR3_MARK,	LCDOUT3_MARK,	DU0_DR4_MARK,	LCDOUT4_MARK,
+	DU0_DR5_MARK,	LCDOUT5_MARK,	DU0_DR6_MARK,	LCDOUT6_MARK,
+
+	/* IPSR4 */
+	DU0_DR7_MARK,	LCDOUT7_MARK,	DU0_DG0_MARK,	LCDOUT8_MARK,
+	AUDATA4_MARK,	ARM_TRACEDATA_4_MARK,
+	TX1_D_MARK,	CAN0_TX_A_MARK,	ADICHS0_MARK,	DU0_DG1_MARK,
+	LCDOUT9_MARK,	AUDATA5_MARK,	ARM_TRACEDATA_5_MARK,
+	RX1_D_MARK,	CAN0_RX_A_MARK,	ADIDATA_MARK,	DU0_DG2_MARK,
+	LCDOUT10_MARK,	DU0_DG3_MARK,	LCDOUT11_MARK,	DU0_DG4_MARK,
+	LCDOUT12_MARK,	RX0_B_MARK,	DU0_DG5_MARK,	LCDOUT13_MARK,
+	TX0_B_MARK,	DU0_DG6_MARK,	LCDOUT14_MARK,	RX4_A_MARK,
+	DU0_DG7_MARK,	LCDOUT15_MARK,	TX4_A_MARK,	SSI_SCK2_B_MARK,
+	VI0_R0_B_MARK,	DU0_DB0_MARK,	LCDOUT16_MARK,	AUDATA6_MARK,
+	ARM_TRACEDATA_6_MARK,		GPSCLK_A_MARK,	PWM0_A_MARK,
+	ADICLK_MARK,	TS_SDAT0_B_MARK,		AUDIO_CLKC_MARK,
+	VI0_R1_B_MARK,	DU0_DB1_MARK,	LCDOUT17_MARK,	AUDATA7_MARK,
+	ARM_TRACEDATA_7_MARK,		GPSIN_A_MARK,	ADICS_SAMP_MARK,
+	TS_SCK0_B_MARK,	VI0_R2_B_MARK,	DU0_DB2_MARK,	LCDOUT18_MARK,
+	VI0_R3_B_MARK,	DU0_DB3_MARK,	LCDOUT19_MARK,	VI0_R4_B_MARK,
+	DU0_DB4_MARK,	LCDOUT20_MARK,
+
+	/* IPSR5 */
+	VI0_R5_B_MARK,	DU0_DB5_MARK,	LCDOUT21_MARK,	VI1_DATA10_B_MARK,
+	DU0_DB6_MARK,	LCDOUT22_MARK,	VI1_DATA11_B_MARK,
+	DU0_DB7_MARK,	LCDOUT23_MARK,	DU0_DOTCLKIN_MARK,
+	QSTVA_QVS_MARK,	DU0_DOTCLKO_UT0_MARK,
+	QCLK_MARK,	DU0_DOTCLKO_UT1_MARK,		QSTVB_QVE_MARK,
+	AUDIO_CLKOUT_A_MARK,		REMOCON_C_MARK,	SSI_WS2_B_MARK,
+	DU0_EXHSYNC_DU0_HSYNC_MARK,	QSTH_QHS_MARK,
+	DU0_EXVSYNC_DU0_VSYNC_MARK,	QSTB_QHE_MARK,
+	DU0_EXODDF_DU0_ODDF_DISP_CDE_MARK,
+	QCPV_QDE_MARK,	FMCLK_D_MARK,	SSI_SCK1_A_MARK,
+	DU0_DISP_MARK,	QPOLA_MARK,	AUDCK_MARK,	ARM_TRACECLK_MARK,
+	BPFCLK_D_MARK,	SSI_WS1_A_MARK,	DU0_CDE_MARK,	QPOLB_MARK,
+	AUDSYNC_MARK,	ARM_TRACECTL_MARK,		FMIN_D_MARK,
+	SD1_CD_B_MARK,	SSI_SCK78_MARK,	HSPI_RX0_B_MARK,
+	TX1_B_MARK,	SD1_WP_B_MARK,	SSI_WS78_MARK,	HSPI_CLK0_B_MARK,
+	RX1_B_MARK,	CAN_CLK_D_MARK,	SSI_SDATA8_MARK,
+	SSI_SCK2_A_MARK,		HSPI_CS0_B_MARK,
+	TX2_A_MARK,	CAN0_TX_B_MARK,	SSI_SDATA7_MARK,
+	HSPI_TX0_B_MARK,		RX2_A_MARK,	CAN0_RX_B_MARK,
+
+	/* IPSR6 */
+	SSI_SCK6_MARK,	HSPI_RX2_A_MARK,		FMCLK_B_MARK,
+	CAN1_TX_B_MARK,	SSI_WS6_MARK,	HSPI_CLK2_A_MARK,
+	BPFCLK_B_MARK,	CAN1_RX_B_MARK,	SSI_SDATA6_MARK,
+	HSPI_TX2_A_MARK,		FMIN_B_MARK,	SSI_SCK5_MARK,
+	RX4_C_MARK,	SSI_WS5_MARK,	TX4_C_MARK,	SSI_SDATA5_MARK,
+	RX0_D_MARK,	SSI_WS34_MARK,	ARM_TRACEDATA_8_MARK,
+	SSI_SDATA4_MARK,		SSI_WS2_A_MARK,	ARM_TRACEDATA_9_MARK,
+	SSI_SDATA3_MARK,		ARM_TRACEDATA_10_MARK,
+	SSI_SCK012_MARK,		ARM_TRACEDATA_11_MARK,
+	TX0_D_MARK,	SSI_WS012_MARK,	ARM_TRACEDATA_12_MARK,
+	SSI_SDATA2_MARK,		HSPI_CS2_A_MARK,
+	ARM_TRACEDATA_13_MARK,		SDA1_A_MARK,	SSI_SDATA1_MARK,
+	ARM_TRACEDATA_14_MARK,		SCL1_A_MARK,	SCK2_A_MARK,
+	SSI_SDATA0_MARK,		ARM_TRACEDATA_15_MARK,
+	SD0_CLK_MARK,	SUB_TDO_MARK,	SD0_CMD_MARK,	SUB_TRST_MARK,
+	SD0_DAT0_MARK,	SUB_TMS_MARK,	SD0_DAT1_MARK,	SUB_TCK_MARK,
+	SD0_DAT2_MARK,	SUB_TDI_MARK,
+
+	/* IPSR7 */
+	SD0_DAT3_MARK,	IRQ1_B_MARK,	SD0_CD_MARK,	TX5_A_MARK,
+	SD0_WP_MARK,	RX5_A_MARK,	VI1_CLKENB_MARK,
+	HSPI_CLK0_A_MARK,	HTX1_A_MARK,	RTS1_C_MARK,	VI1_FIELD_MARK,
+	HSPI_CS0_A_MARK,	HRX1_A_MARK,	SCK1_C_MARK,	VI1_HSYNC_MARK,
+	HSPI_RX0_A_MARK,	HRTS1_A_MARK,	FMCLK_A_MARK,	RX1_C_MARK,
+	VI1_VSYNC_MARK,	HSPI_TX0_MARK,	HCTS1_A_MARK,	BPFCLK_A_MARK,
+	TX1_C_MARK,	TCLK0_MARK,	HSCK1_A_MARK,	FMIN_A_MARK,
+	IRQ2_C_MARK,	CTS1_C_MARK,	SPEEDIN_MARK,	VI0_CLK_MARK,
+	CAN_CLK_A_MARK,	VI0_CLKENB_MARK,		SD2_DAT2_B_MARK,
+	VI1_DATA0_MARK,	DU1_DG6_MARK,	HSPI_RX1_A_MARK,
+	RX4_B_MARK,	VI0_FIELD_MARK,	SD2_DAT3_B_MARK,
+	VI0_R3_C_MARK,	VI1_DATA1_MARK,	DU1_DG7_MARK,	HSPI_CLK1_A_MARK,
+	TX4_B_MARK,	VI0_HSYNC_MARK,	SD2_CD_B_MARK,	VI1_DATA2_MARK,
+	DU1_DR2_MARK,	HSPI_CS1_A_MARK,		RX3_B_MARK,
+
+	/* IPSR8 */
+	VI0_VSYNC_MARK,	SD2_WP_B_MARK,	VI1_DATA3_MARK,	DU1_DR3_MARK,
+	HSPI_TX1_A_MARK,		TX3_B_MARK,	VI0_DATA0_VI0_B0_MARK,
+	DU1_DG2_MARK,	IRQ2_B_MARK,	RX3_D_MARK,	VI0_DATA1_VI0_B1_MARK,
+	DU1_DG3_MARK,	IRQ3_B_MARK,	TX3_D_MARK,	VI0_DATA2_VI0_B2_MARK,
+	DU1_DG4_MARK,	RX0_C_MARK,	VI0_DATA3_VI0_B3_MARK,
+	DU1_DG5_MARK,	TX1_A_MARK,	TX0_C_MARK,	VI0_DATA4_VI0_B4_MARK,
+	DU1_DB2_MARK,	RX1_A_MARK,	VI0_DATA5_VI0_B5_MARK,
+	DU1_DB3_MARK,	SCK1_A_MARK,	PWM4_MARK,	HSCK1_B_MARK,
+	VI0_DATA6_VI0_G0_MARK,		DU1_DB4_MARK,	CTS1_A_MARK,
+	PWM5_MARK,	VI0_DATA7_VI0_G1_MARK,		DU1_DB5_MARK,
+	RTS1_A_MARK,	VI0_G2_MARK,	SD2_CLK_B_MARK,	VI1_DATA4_MARK,
+	DU1_DR4_MARK,	HTX1_B_MARK,	VI0_G3_MARK,	SD2_CMD_B_MARK,
+	VI1_DATA5_MARK,	DU1_DR5_MARK,	HRX1_B_MARK,
+
+	/* IPSR9 */
+	VI0_G4_MARK,	SD2_DAT0_B_MARK,		VI1_DATA6_MARK,
+	DU1_DR6_MARK,	HRTS1_B_MARK,	VI0_G5_MARK,	SD2_DAT1_B_MARK,
+	VI1_DATA7_MARK,	DU1_DR7_MARK,	HCTS1_B_MARK,	VI0_R0_A_MARK,
+	VI1_CLK_MARK,	ETH_REF_CLK_MARK,		DU1_DOTCLKIN_MARK,
+	VI0_R1_A_MARK,	VI1_DATA8_MARK,	DU1_DB6_MARK,	ETH_TXD0_MARK,
+	PWM2_MARK,	TCLK1_MARK,	VI0_R2_A_MARK,	VI1_DATA9_MARK,
+	DU1_DB7_MARK,	ETH_TXD1_MARK,	PWM3_MARK,	VI0_R3_A_MARK,
+	ETH_CRS_DV_MARK,		IECLK_MARK,	SCK2_C_MARK,
+	VI0_R4_A_MARK,			ETH_TX_EN_MARK,	IETX_MARK,
+	TX2_C_MARK,	VI0_R5_A_MARK,	ETH_RX_ER_MARK,	FMCLK_C_MARK,
+	IERX_MARK,	RX2_C_MARK,	VI1_DATA10_A_MARK,
+	DU1_DOTCLKOUT_MARK,		ETH_RXD0_MARK,
+	BPFCLK_C_MARK,	TX2_D_MARK,	SDA2_C_MARK,	VI1_DATA11_A_MARK,
+	DU1_EXHSYNC_DU1_HSYNC_MARK,	ETH_RXD1_MARK,	FMIN_C_MARK,
+	RX2_D_MARK,	SCL2_C_MARK,
+
+	/* IPSR10 */
+	SD2_CLK_A_MARK,	DU1_EXVSYNC_DU1_VSYNC_MARK,	ATARD1_MARK,
+	ETH_MDC_MARK,	SDA1_B_MARK,	SD2_CMD_A_MARK,
+	DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK,		ATAWR1_MARK,
+	ETH_MDIO_MARK,	SCL1_B_MARK,	SD2_DAT0_A_MARK,
+	DU1_DISP_MARK,	ATACS01_MARK,	DREQ1_B_MARK,	ETH_LINK_MARK,
+	CAN1_RX_A_MARK,	SD2_DAT1_A_MARK,		DU1_CDE_MARK,
+	ATACS11_MARK,	DACK1_B_MARK,	ETH_MAGIC_MARK,	CAN1_TX_A_MARK,
+	PWM6_MARK,	SD2_DAT2_A_MARK,		VI1_DATA12_MARK,
+	DREQ2_B_MARK,	ATADIR1_MARK,	HSPI_CLK2_B_MARK,
+	GPSCLK_B_MARK,	SD2_DAT3_A_MARK,		VI1_DATA13_MARK,
+	DACK2_B_MARK,	ATAG1_MARK,	HSPI_CS2_B_MARK,
+	GPSIN_B_MARK,	SD2_CD_A_MARK,	VI1_DATA14_MARK,
+	EX_WAIT1_B_MARK,		DREQ0_B_MARK,	HSPI_RX2_B_MARK,
+	REMOCON_A_MARK,	SD2_WP_A_MARK,	VI1_DATA15_MARK,
+	EX_WAIT2_B_MARK,		DACK0_B_MARK,
+	HSPI_TX2_B_MARK,		CAN_CLK_C_MARK,
+
+	PINMUX_MARK_END,
+};
+
+static const pinmux_enum_t pinmux_data[] = {
+	PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */
+
+	PINMUX_DATA(PENC0_MARK,		FN_PENC0),
+	PINMUX_DATA(PENC1_MARK,		FN_PENC1),
+	PINMUX_DATA(A1_MARK,		FN_A1),
+	PINMUX_DATA(A2_MARK,		FN_A2),
+	PINMUX_DATA(A3_MARK,		FN_A3),
+	PINMUX_DATA(WE0_MARK,		FN_WE0),
+	PINMUX_DATA(AUDIO_CLKA_MARK,	FN_AUDIO_CLKA),
+	PINMUX_DATA(AUDIO_CLKB_MARK,	FN_AUDIO_CLKB),
+	PINMUX_DATA(SSI_SCK34_MARK,	FN_SSI_SCK34),
+	PINMUX_DATA(AVS1_MARK,		FN_AVS1),
+	PINMUX_DATA(AVS2_MARK,		FN_AVS2),
+
+	/* IPSR0 */
+	PINMUX_IPSR_DATA(IP0_1_0,	PRESETOUT),
+	PINMUX_IPSR_DATA(IP0_1_0,	PWM1),
+
+	PINMUX_IPSR_DATA(IP0_4_2,	AUDATA0),
+	PINMUX_IPSR_DATA(IP0_4_2,	ARM_TRACEDATA_0),
+	PINMUX_IPSR_MSEL(IP0_4_2,	GPSCLK_C,	SEL_GPS_C),
+	PINMUX_IPSR_DATA(IP0_4_2,	USB_OVC0),
+	PINMUX_IPSR_DATA(IP0_4_2,	TX2_E),
+	PINMUX_IPSR_MSEL(IP0_4_2,	SDA2_B,		SEL_I2C2_B),
+
+	PINMUX_IPSR_DATA(IP0_7_5,	AUDATA1),
+	PINMUX_IPSR_DATA(IP0_7_5,	ARM_TRACEDATA_1),
+	PINMUX_IPSR_MSEL(IP0_7_5,	GPSIN_C,	SEL_GPS_C),
+	PINMUX_IPSR_DATA(IP0_7_5,	USB_OVC1),
+	PINMUX_IPSR_MSEL(IP0_7_5,	RX2_E,		SEL_SCIF2_E),
+	PINMUX_IPSR_MSEL(IP0_7_5,	SCL2_B,		SEL_I2C2_B),
+
+	PINMUX_IPSR_MSEL(IP0_11_8,	SD1_DAT2_A,	SEL_SD1_A),
+	PINMUX_IPSR_DATA(IP0_11_8,	MMC_D2),
+	PINMUX_IPSR_DATA(IP0_11_8,	BS),
+	PINMUX_IPSR_DATA(IP0_11_8,	ATADIR0_A),
+	PINMUX_IPSR_DATA(IP0_11_8,	SDSELF_A),
+	PINMUX_IPSR_DATA(IP0_11_8,	PWM4_B),
+
+	PINMUX_IPSR_MSEL(IP0_14_12,	SD1_DAT3_A,	SEL_SD1_A),
+	PINMUX_IPSR_DATA(IP0_14_12,	MMC_D3),
+	PINMUX_IPSR_DATA(IP0_14_12,	A0),
+	PINMUX_IPSR_DATA(IP0_14_12,	ATAG0_A),
+	PINMUX_IPSR_MSEL(IP0_14_12,	REMOCON_B,	SEL_REMOCON_B),
+
+	PINMUX_IPSR_DATA(IP0_15,	A4),
+	PINMUX_IPSR_DATA(IP0_16,	A5),
+	PINMUX_IPSR_DATA(IP0_17,	A6),
+	PINMUX_IPSR_DATA(IP0_18,	A7),
+	PINMUX_IPSR_DATA(IP0_19,	A8),
+	PINMUX_IPSR_DATA(IP0_20,	A9),
+	PINMUX_IPSR_DATA(IP0_21,	A10),
+	PINMUX_IPSR_DATA(IP0_22,	A11),
+	PINMUX_IPSR_DATA(IP0_23,	A12),
+	PINMUX_IPSR_DATA(IP0_24,	A13),
+	PINMUX_IPSR_DATA(IP0_25,	A14),
+	PINMUX_IPSR_DATA(IP0_26,	A15),
+	PINMUX_IPSR_DATA(IP0_27,	A16),
+	PINMUX_IPSR_DATA(IP0_28,	A17),
+	PINMUX_IPSR_DATA(IP0_29,	A18),
+	PINMUX_IPSR_DATA(IP0_30,	A19),
+
+	/* IPSR1 */
+	PINMUX_IPSR_DATA(IP1_0,		A20),
+	PINMUX_IPSR_MSEL(IP1_0,		HSPI_CS1_B,	SEL_HSPI1_B),
+
+	PINMUX_IPSR_DATA(IP1_1,		A21),
+	PINMUX_IPSR_MSEL(IP1_1,		HSPI_CLK1_B,	SEL_HSPI1_B),
+
+	PINMUX_IPSR_DATA(IP1_4_2,	A22),
+	PINMUX_IPSR_MSEL(IP1_4_2,	HRTS0_B,	SEL_HSCIF0_B),
+	PINMUX_IPSR_MSEL(IP1_4_2,	RX2_B,		SEL_SCIF2_B),
+	PINMUX_IPSR_MSEL(IP1_4_2,	DREQ2_A,	SEL_DREQ2_A),
+
+	PINMUX_IPSR_DATA(IP1_7_5,	A23),
+	PINMUX_IPSR_DATA(IP1_7_5,	HTX0_B),
+	PINMUX_IPSR_DATA(IP1_7_5,	TX2_B),
+	PINMUX_IPSR_DATA(IP1_7_5,	DACK2_A),
+	PINMUX_IPSR_MSEL(IP1_7_5,	TS_SDEN0_A,	SEL_TSIF0_A),
+
+	PINMUX_IPSR_MSEL(IP1_10_8,	SD1_CD_A,	SEL_SD1_A),
+	PINMUX_IPSR_DATA(IP1_10_8,	MMC_D6),
+	PINMUX_IPSR_DATA(IP1_10_8,	A24),
+	PINMUX_IPSR_MSEL(IP1_10_8,	DREQ1_A,	SEL_DREQ1_A),
+	PINMUX_IPSR_MSEL(IP1_10_8,	HRX0_B,		SEL_HSCIF0_B),
+	PINMUX_IPSR_MSEL(IP1_10_8,	TS_SPSYNC0_A,	SEL_TSIF0_A),
+
+	PINMUX_IPSR_MSEL(IP1_14_11,	SD1_WP_A,	SEL_SD1_A),
+	PINMUX_IPSR_DATA(IP1_14_11,	MMC_D7),
+	PINMUX_IPSR_DATA(IP1_14_11,	A25),
+	PINMUX_IPSR_DATA(IP1_14_11,	DACK1_A),
+	PINMUX_IPSR_MSEL(IP1_14_11,	HCTS0_B,	SEL_HSCIF0_B),
+	PINMUX_IPSR_MSEL(IP1_14_11,	RX3_C,		SEL_SCIF3_C),
+	PINMUX_IPSR_MSEL(IP1_14_11,	TS_SDAT0_A,	SEL_TSIF0_A),
+
+	PINMUX_IPSR_NOGP(IP1_16_15,	CLKOUT),
+	PINMUX_IPSR_NOGP(IP1_16_15,	HSPI_TX1_B),
+	PINMUX_IPSR_NOGP(IP1_16_15,	PWM0_B),
+
+	PINMUX_IPSR_NOGP(IP1_17,	CS0),
+	PINMUX_IPSR_NOGM(IP1_17,	HSPI_RX1_B,	SEL_HSPI1_B),
+
+	PINMUX_IPSR_NOGM(IP1_20_18,	SSI_SCK1_B,	SEL_SSI1_B),
+	PINMUX_IPSR_NOGP(IP1_20_18,	ATAG0_B),
+	PINMUX_IPSR_NOGP(IP1_20_18,	CS1_A26),
+	PINMUX_IPSR_NOGM(IP1_20_18,	SDA2_A,		SEL_I2C2_A),
+	PINMUX_IPSR_NOGM(IP1_20_18,	SCK2_B,		SEL_SCIF2_B),
+
+	PINMUX_IPSR_DATA(IP1_23_21,	MMC_D5),
+	PINMUX_IPSR_DATA(IP1_23_21,	ATADIR0_B),
+	PINMUX_IPSR_DATA(IP1_23_21,	RD_WR),
+
+	PINMUX_IPSR_DATA(IP1_24,	WE1),
+	PINMUX_IPSR_DATA(IP1_24,	ATAWR0_B),
+
+	PINMUX_IPSR_MSEL(IP1_27_25,	SSI_WS1_B,	SEL_SSI1_B),
+	PINMUX_IPSR_DATA(IP1_27_25,	EX_CS0),
+	PINMUX_IPSR_MSEL(IP1_27_25,	SCL2_A,		SEL_I2C2_A),
+	PINMUX_IPSR_DATA(IP1_27_25,	TX3_C),
+	PINMUX_IPSR_MSEL(IP1_27_25,	TS_SCK0_A,	SEL_TSIF0_A),
+
+	PINMUX_IPSR_DATA(IP1_29_28,	EX_CS1),
+	PINMUX_IPSR_DATA(IP1_29_28,	MMC_D4),
+
+	/* IPSR2 */
+	PINMUX_IPSR_DATA(IP2_2_0,	SD1_CLK_A),
+	PINMUX_IPSR_DATA(IP2_2_0,	MMC_CLK),
+	PINMUX_IPSR_DATA(IP2_2_0,	ATACS00),
+	PINMUX_IPSR_DATA(IP2_2_0,	EX_CS2),
+
+	PINMUX_IPSR_MSEL(IP2_5_3,	SD1_CMD_A,	SEL_SD1_A),
+	PINMUX_IPSR_DATA(IP2_5_3,	MMC_CMD),
+	PINMUX_IPSR_DATA(IP2_5_3,	ATACS10),
+	PINMUX_IPSR_DATA(IP2_5_3,	EX_CS3),
+
+	PINMUX_IPSR_MSEL(IP2_8_6,	SD1_DAT0_A,	SEL_SD1_A),
+	PINMUX_IPSR_DATA(IP2_8_6,	MMC_D0),
+	PINMUX_IPSR_DATA(IP2_8_6,	ATARD0),
+	PINMUX_IPSR_DATA(IP2_8_6,	EX_CS4),
+	PINMUX_IPSR_MSEL(IP2_8_6,	EX_WAIT1_A,	SEL_WAIT1_A),
+
+	PINMUX_IPSR_MSEL(IP2_11_9,	SD1_DAT1_A,	SEL_SD1_A),
+	PINMUX_IPSR_DATA(IP2_11_9,	MMC_D1),
+	PINMUX_IPSR_DATA(IP2_11_9,	ATAWR0_A),
+	PINMUX_IPSR_DATA(IP2_11_9,	EX_CS5),
+	PINMUX_IPSR_MSEL(IP2_11_9,	EX_WAIT2_A,	SEL_WAIT2_A),
+
+	PINMUX_IPSR_MSEL(IP2_13_12,	DREQ0_A,	SEL_DREQ0_A),
+	PINMUX_IPSR_MSEL(IP2_13_12,	RX3_A,		SEL_SCIF3_A),
+
+	PINMUX_IPSR_DATA(IP2_16_14,	DACK0),
+	PINMUX_IPSR_DATA(IP2_16_14,	TX3_A),
+	PINMUX_IPSR_DATA(IP2_16_14,	DRACK0),
+
+	PINMUX_IPSR_DATA(IP2_17,	EX_WAIT0),
+	PINMUX_IPSR_DATA(IP2_17,	PWM0_C),
+
+	PINMUX_IPSR_NOGP(IP2_18,	D0),
+	PINMUX_IPSR_NOGP(IP2_19,	D1),
+	PINMUX_IPSR_NOGP(IP2_20,	D2),
+	PINMUX_IPSR_NOGP(IP2_21,	D3),
+	PINMUX_IPSR_NOGP(IP2_22,	D4),
+	PINMUX_IPSR_NOGP(IP2_23,	D5),
+	PINMUX_IPSR_NOGP(IP2_24,	D6),
+	PINMUX_IPSR_NOGP(IP2_25,	D7),
+	PINMUX_IPSR_NOGP(IP2_26,	D8),
+	PINMUX_IPSR_NOGP(IP2_27,	D9),
+	PINMUX_IPSR_NOGP(IP2_28,	D10),
+	PINMUX_IPSR_NOGP(IP2_29,	D11),
+
+	PINMUX_IPSR_DATA(IP2_30,	RD_WR_B),
+	PINMUX_IPSR_DATA(IP2_30,	IRQ0),
+
+	PINMUX_IPSR_DATA(IP2_31,	MLB_CLK),
+	PINMUX_IPSR_MSEL(IP2_31,	IRQ1_A,		SEL_IRQ1_A),
+
+	/* IPSR3 */
+	PINMUX_IPSR_DATA(IP3_1_0,	MLB_SIG),
+	PINMUX_IPSR_MSEL(IP3_1_0,	RX5_B,		SEL_SCIF5_B),
+	PINMUX_IPSR_MSEL(IP3_1_0,	SDA3_A,		SEL_I2C3_A),
+	PINMUX_IPSR_MSEL(IP3_1_0,	IRQ2_A,		SEL_IRQ2_A),
+
+	PINMUX_IPSR_DATA(IP3_4_2,	MLB_DAT),
+	PINMUX_IPSR_DATA(IP3_4_2,	TX5_B),
+	PINMUX_IPSR_MSEL(IP3_4_2,	SCL3_A,		SEL_I2C3_A),
+	PINMUX_IPSR_MSEL(IP3_4_2,	IRQ3_A,		SEL_IRQ3_A),
+	PINMUX_IPSR_DATA(IP3_4_2,	SDSELF_B),
+
+	PINMUX_IPSR_MSEL(IP3_7_5,	SD1_CMD_B,	SEL_SD1_B),
+	PINMUX_IPSR_DATA(IP3_7_5,	SCIF_CLK),
+	PINMUX_IPSR_DATA(IP3_7_5,	AUDIO_CLKOUT_B),
+	PINMUX_IPSR_MSEL(IP3_7_5,	CAN_CLK_B,	SEL_CANCLK_B),
+	PINMUX_IPSR_MSEL(IP3_7_5,	SDA3_B,		SEL_I2C3_B),
+
+	PINMUX_IPSR_DATA(IP3_9_8,	SD1_CLK_B),
+	PINMUX_IPSR_DATA(IP3_9_8,	HTX0_A),
+	PINMUX_IPSR_DATA(IP3_9_8,	TX0_A),
+
+	PINMUX_IPSR_MSEL(IP3_12_10,	SD1_DAT0_B,	SEL_SD1_B),
+	PINMUX_IPSR_MSEL(IP3_12_10,	HRX0_A,		SEL_HSCIF0_A),
+	PINMUX_IPSR_MSEL(IP3_12_10,	RX0_A,		SEL_SCIF0_A),
+
+	PINMUX_IPSR_MSEL(IP3_15_13,	SD1_DAT1_B,	SEL_SD1_B),
+	PINMUX_IPSR_MSEL(IP3_15_13,	HSCK0,		SEL_HSCIF0_A),
+	PINMUX_IPSR_DATA(IP3_15_13,	SCK0),
+	PINMUX_IPSR_MSEL(IP3_15_13,	SCL3_B,		SEL_I2C3_B),
+
+	PINMUX_IPSR_MSEL(IP3_18_16,	SD1_DAT2_B,	SEL_SD1_B),
+	PINMUX_IPSR_MSEL(IP3_18_16,	HCTS0_A,	SEL_HSCIF0_A),
+	PINMUX_IPSR_DATA(IP3_18_16,	CTS0),
+
+	PINMUX_IPSR_MSEL(IP3_20_19,	SD1_DAT3_B,	SEL_SD1_B),
+	PINMUX_IPSR_MSEL(IP3_20_19,	HRTS0_A,	SEL_HSCIF0_A),
+	PINMUX_IPSR_DATA(IP3_20_19,	RTS0),
+
+	PINMUX_IPSR_DATA(IP3_23_21,	SSI_SCK4),
+	PINMUX_IPSR_DATA(IP3_23_21,	DU0_DR0),
+	PINMUX_IPSR_DATA(IP3_23_21,	LCDOUT0),
+	PINMUX_IPSR_DATA(IP3_23_21,	AUDATA2),
+	PINMUX_IPSR_DATA(IP3_23_21,	ARM_TRACEDATA_2),
+	PINMUX_IPSR_MSEL(IP3_23_21,	SDA3_C,		SEL_I2C3_C),
+	PINMUX_IPSR_DATA(IP3_23_21,	ADICHS1),
+	PINMUX_IPSR_MSEL(IP3_23_21,	TS_SDEN0_B,	SEL_TSIF0_B),
+
+	PINMUX_IPSR_DATA(IP3_26_24,	SSI_WS4),
+	PINMUX_IPSR_DATA(IP3_26_24,	DU0_DR1),
+	PINMUX_IPSR_DATA(IP3_26_24,	LCDOUT1),
+	PINMUX_IPSR_DATA(IP3_26_24,	AUDATA3),
+	PINMUX_IPSR_DATA(IP3_26_24,	ARM_TRACEDATA_3),
+	PINMUX_IPSR_MSEL(IP3_26_24,	SCL3_C,		SEL_I2C3_C),
+	PINMUX_IPSR_DATA(IP3_26_24,	ADICHS2),
+	PINMUX_IPSR_MSEL(IP3_26_24,	TS_SPSYNC0_B,	SEL_TSIF0_B),
+
+	PINMUX_IPSR_DATA(IP3_27,	DU0_DR2),
+	PINMUX_IPSR_DATA(IP3_27,	LCDOUT2),
+
+	PINMUX_IPSR_DATA(IP3_28,	DU0_DR3),
+	PINMUX_IPSR_DATA(IP3_28,	LCDOUT3),
+
+	PINMUX_IPSR_DATA(IP3_29,	DU0_DR4),
+	PINMUX_IPSR_DATA(IP3_29,	LCDOUT4),
+
+	PINMUX_IPSR_DATA(IP3_30,	DU0_DR5),
+	PINMUX_IPSR_DATA(IP3_30,	LCDOUT5),
+
+	PINMUX_IPSR_DATA(IP3_31,	DU0_DR6),
+	PINMUX_IPSR_DATA(IP3_31,	LCDOUT6),
+
+	/* IPSR4 */
+	PINMUX_IPSR_DATA(IP4_0,		DU0_DR7),
+	PINMUX_IPSR_DATA(IP4_0,		LCDOUT7),
+
+	PINMUX_IPSR_DATA(IP4_3_1,	DU0_DG0),
+	PINMUX_IPSR_DATA(IP4_3_1,	LCDOUT8),
+	PINMUX_IPSR_DATA(IP4_3_1,	AUDATA4),
+	PINMUX_IPSR_DATA(IP4_3_1,	ARM_TRACEDATA_4),
+	PINMUX_IPSR_DATA(IP4_3_1,	TX1_D),
+	PINMUX_IPSR_DATA(IP4_3_1,	CAN0_TX_A),
+	PINMUX_IPSR_DATA(IP4_3_1,	ADICHS0),
+
+	PINMUX_IPSR_DATA(IP4_6_4,	DU0_DG1),
+	PINMUX_IPSR_DATA(IP4_6_4,	LCDOUT9),
+	PINMUX_IPSR_DATA(IP4_6_4,	AUDATA5),
+	PINMUX_IPSR_DATA(IP4_6_4,	ARM_TRACEDATA_5),
+	PINMUX_IPSR_MSEL(IP4_6_4,	RX1_D,		SEL_SCIF1_D),
+	PINMUX_IPSR_MSEL(IP4_6_4,	CAN0_RX_A,	SEL_CAN0_A),
+	PINMUX_IPSR_DATA(IP4_6_4,	ADIDATA),
+
+	PINMUX_IPSR_DATA(IP4_7,		DU0_DG2),
+	PINMUX_IPSR_DATA(IP4_7,		LCDOUT10),
+
+	PINMUX_IPSR_DATA(IP4_8,		DU0_DG3),
+	PINMUX_IPSR_DATA(IP4_8,		LCDOUT11),
+
+	PINMUX_IPSR_DATA(IP4_10_9,	DU0_DG4),
+	PINMUX_IPSR_DATA(IP4_10_9,	LCDOUT12),
+	PINMUX_IPSR_MSEL(IP4_10_9,	RX0_B,		SEL_SCIF0_B),
+
+	PINMUX_IPSR_DATA(IP4_12_11,	DU0_DG5),
+	PINMUX_IPSR_DATA(IP4_12_11,	LCDOUT13),
+	PINMUX_IPSR_DATA(IP4_12_11,	TX0_B),
+
+	PINMUX_IPSR_DATA(IP4_14_13,	DU0_DG6),
+	PINMUX_IPSR_DATA(IP4_14_13,	LCDOUT14),
+	PINMUX_IPSR_MSEL(IP4_14_13,	RX4_A,		SEL_SCIF4_A),
+
+	PINMUX_IPSR_DATA(IP4_16_15,	DU0_DG7),
+	PINMUX_IPSR_DATA(IP4_16_15,	LCDOUT15),
+	PINMUX_IPSR_DATA(IP4_16_15,	TX4_A),
+
+	PINMUX_IPSR_MSEL(IP4_20_17,	SSI_SCK2_B,	SEL_SSI2_B),
+	PINMUX_DATA(VI0_R0_B_MARK,	FN_IP4_20_17,	FN_VI0_R0_B,	FN_SEL_VI0_B), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R0_D_MARK,	FN_IP4_20_17,	FN_VI0_R0_B,	FN_SEL_VI0_D), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP4_20_17,	DU0_DB0),
+	PINMUX_IPSR_DATA(IP4_20_17,	LCDOUT16),
+	PINMUX_IPSR_DATA(IP4_20_17,	AUDATA6),
+	PINMUX_IPSR_DATA(IP4_20_17,	ARM_TRACEDATA_6),
+	PINMUX_IPSR_MSEL(IP4_20_17,	GPSCLK_A,	SEL_GPS_A),
+	PINMUX_IPSR_DATA(IP4_20_17,	PWM0_A),
+	PINMUX_IPSR_DATA(IP4_20_17,	ADICLK),
+	PINMUX_IPSR_MSEL(IP4_20_17,	TS_SDAT0_B,	SEL_TSIF0_B),
+
+	PINMUX_IPSR_DATA(IP4_24_21,	AUDIO_CLKC),
+	PINMUX_DATA(VI0_R1_B_MARK,	FN_IP4_24_21,	FN_VI0_R1_B,	FN_SEL_VI0_B), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R1_D_MARK,	FN_IP4_24_21,	FN_VI0_R1_B,	FN_SEL_VI0_D), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP4_24_21,	DU0_DB1),
+	PINMUX_IPSR_DATA(IP4_24_21,	LCDOUT17),
+	PINMUX_IPSR_DATA(IP4_24_21,	AUDATA7),
+	PINMUX_IPSR_DATA(IP4_24_21,	ARM_TRACEDATA_7),
+	PINMUX_IPSR_MSEL(IP4_24_21,	GPSIN_A,	SEL_GPS_A),
+	PINMUX_IPSR_DATA(IP4_24_21,	ADICS_SAMP),
+	PINMUX_IPSR_MSEL(IP4_24_21,	TS_SCK0_B,	SEL_TSIF0_B),
+
+	PINMUX_DATA(VI0_R2_B_MARK,	FN_IP4_26_25,	FN_VI0_R2_B,	FN_SEL_VI0_B), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R2_D_MARK,	FN_IP4_26_25,	FN_VI0_R2_B,	FN_SEL_VI0_D), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP4_26_25,	DU0_DB2),
+	PINMUX_IPSR_DATA(IP4_26_25,	LCDOUT18),
+
+	PINMUX_IPSR_MSEL(IP4_28_27,	VI0_R3_B,	SEL_VI0_B),
+	PINMUX_IPSR_DATA(IP4_28_27,	DU0_DB3),
+	PINMUX_IPSR_DATA(IP4_28_27,	LCDOUT19),
+
+	PINMUX_DATA(VI0_R4_B_MARK,	FN_IP4_30_29,	FN_VI0_R4_B,	FN_SEL_VI0_B), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R4_D_MARK,	FN_IP4_30_29,	FN_VI0_R4_B,	FN_SEL_VI0_D), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP4_30_29,	DU0_DB4),
+	PINMUX_IPSR_DATA(IP4_30_29,	LCDOUT20),
+
+	/* IPSR5 */
+	PINMUX_DATA(VI0_R5_B_MARK,	FN_IP5_1_0,	FN_VI0_R5_B,	FN_SEL_VI0_B), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R5_D_MARK,	FN_IP5_1_0,	FN_VI0_R5_B,	FN_SEL_VI0_D), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP5_1_0,	DU0_DB5),
+	PINMUX_IPSR_DATA(IP5_1_0,	LCDOUT21),
+
+	PINMUX_IPSR_MSEL(IP5_3_2,	VI1_DATA10_B,	SEL_VI1_B),
+	PINMUX_IPSR_DATA(IP5_3_2,	DU0_DB6),
+	PINMUX_IPSR_DATA(IP5_3_2,	LCDOUT22),
+
+	PINMUX_IPSR_MSEL(IP5_5_4,	VI1_DATA11_B,	SEL_VI1_B),
+	PINMUX_IPSR_DATA(IP5_5_4,	DU0_DB7),
+	PINMUX_IPSR_DATA(IP5_5_4,	LCDOUT23),
+
+	PINMUX_IPSR_DATA(IP5_6,		DU0_DOTCLKIN),
+	PINMUX_IPSR_DATA(IP5_6,		QSTVA_QVS),
+
+	PINMUX_IPSR_DATA(IP5_7,		DU0_DOTCLKO_UT0),
+	PINMUX_IPSR_DATA(IP5_7,		QCLK),
+
+	PINMUX_IPSR_DATA(IP5_9_8,	DU0_DOTCLKO_UT1),
+	PINMUX_IPSR_DATA(IP5_9_8,	QSTVB_QVE),
+	PINMUX_IPSR_DATA(IP5_9_8,	AUDIO_CLKOUT_A),
+	PINMUX_IPSR_MSEL(IP5_9_8,	REMOCON_C,	SEL_REMOCON_C),
+
+	PINMUX_IPSR_MSEL(IP5_11_10,	SSI_WS2_B,	SEL_SSI2_B),
+	PINMUX_IPSR_DATA(IP5_11_10,	DU0_EXHSYNC_DU0_HSYNC),
+	PINMUX_IPSR_DATA(IP5_11_10,	QSTH_QHS),
+
+	PINMUX_IPSR_DATA(IP5_12,	DU0_EXVSYNC_DU0_VSYNC),
+	PINMUX_IPSR_DATA(IP5_12,	QSTB_QHE),
+
+	PINMUX_IPSR_DATA(IP5_14_13,	DU0_EXODDF_DU0_ODDF_DISP_CDE),
+	PINMUX_IPSR_DATA(IP5_14_13,	QCPV_QDE),
+	PINMUX_IPSR_MSEL(IP5_14_13,	FMCLK_D,	SEL_FM_D),
+
+	PINMUX_IPSR_MSEL(IP5_17_15,	SSI_SCK1_A,	SEL_SSI1_A),
+	PINMUX_IPSR_DATA(IP5_17_15,	DU0_DISP),
+	PINMUX_IPSR_DATA(IP5_17_15,	QPOLA),
+	PINMUX_IPSR_DATA(IP5_17_15,	AUDCK),
+	PINMUX_IPSR_DATA(IP5_17_15,	ARM_TRACECLK),
+	PINMUX_IPSR_DATA(IP5_17_15,	BPFCLK_D),
+
+	PINMUX_IPSR_MSEL(IP5_20_18,	SSI_WS1_A,	SEL_SSI1_A),
+	PINMUX_IPSR_DATA(IP5_20_18,	DU0_CDE),
+	PINMUX_IPSR_DATA(IP5_20_18,	QPOLB),
+	PINMUX_IPSR_DATA(IP5_20_18,	AUDSYNC),
+	PINMUX_IPSR_DATA(IP5_20_18,	ARM_TRACECTL),
+	PINMUX_IPSR_MSEL(IP5_20_18,	FMIN_D,		SEL_FM_D),
+
+	PINMUX_IPSR_MSEL(IP5_22_21,	SD1_CD_B,	SEL_SD1_B),
+	PINMUX_IPSR_DATA(IP5_22_21,	SSI_SCK78),
+	PINMUX_IPSR_MSEL(IP5_22_21,	HSPI_RX0_B,	SEL_HSPI0_B),
+	PINMUX_IPSR_DATA(IP5_22_21,	TX1_B),
+
+	PINMUX_IPSR_MSEL(IP5_25_23,	SD1_WP_B,	SEL_SD1_B),
+	PINMUX_IPSR_DATA(IP5_25_23,	SSI_WS78),
+	PINMUX_IPSR_MSEL(IP5_25_23,	HSPI_CLK0_B,	SEL_HSPI0_B),
+	PINMUX_IPSR_MSEL(IP5_25_23,	RX1_B,		SEL_SCIF1_B),
+	PINMUX_IPSR_MSEL(IP5_25_23,	CAN_CLK_D,	SEL_CANCLK_D),
+
+	PINMUX_IPSR_DATA(IP5_28_26,	SSI_SDATA8),
+	PINMUX_IPSR_MSEL(IP5_28_26,	SSI_SCK2_A,	SEL_SSI2_A),
+	PINMUX_IPSR_MSEL(IP5_28_26,	HSPI_CS0_B,	SEL_HSPI0_B),
+	PINMUX_IPSR_DATA(IP5_28_26,	TX2_A),
+	PINMUX_IPSR_DATA(IP5_28_26,	CAN0_TX_B),
+
+	PINMUX_IPSR_DATA(IP5_30_29,	SSI_SDATA7),
+	PINMUX_IPSR_DATA(IP5_30_29,	HSPI_TX0_B),
+	PINMUX_IPSR_MSEL(IP5_30_29,	RX2_A,		SEL_SCIF2_A),
+	PINMUX_IPSR_MSEL(IP5_30_29,	CAN0_RX_B,	SEL_CAN0_B),
+
+	/* IPSR6 */
+	PINMUX_IPSR_DATA(IP6_1_0,	SSI_SCK6),
+	PINMUX_IPSR_MSEL(IP6_1_0,	HSPI_RX2_A,	SEL_HSPI2_A),
+	PINMUX_IPSR_MSEL(IP6_1_0,	FMCLK_B,	SEL_FM_B),
+	PINMUX_IPSR_DATA(IP6_1_0,	CAN1_TX_B),
+
+	PINMUX_IPSR_DATA(IP6_4_2,	SSI_WS6),
+	PINMUX_IPSR_MSEL(IP6_4_2,	HSPI_CLK2_A,	SEL_HSPI2_A),
+	PINMUX_IPSR_DATA(IP6_4_2,	BPFCLK_B),
+	PINMUX_IPSR_MSEL(IP6_4_2,	CAN1_RX_B,	SEL_CAN1_B),
+
+	PINMUX_IPSR_DATA(IP6_6_5,	SSI_SDATA6),
+	PINMUX_IPSR_DATA(IP6_6_5,	HSPI_TX2_A),
+	PINMUX_IPSR_MSEL(IP6_6_5,	FMIN_B,		SEL_FM_B),
+
+	PINMUX_IPSR_DATA(IP6_7,		SSI_SCK5),
+	PINMUX_IPSR_MSEL(IP6_7,		RX4_C,		SEL_SCIF4_C),
+
+	PINMUX_IPSR_DATA(IP6_8,		SSI_WS5),
+	PINMUX_IPSR_DATA(IP6_8,		TX4_C),
+
+	PINMUX_IPSR_DATA(IP6_9,		SSI_SDATA5),
+	PINMUX_IPSR_MSEL(IP6_9,		RX0_D,		SEL_SCIF0_D),
+
+	PINMUX_IPSR_DATA(IP6_10,	SSI_WS34),
+	PINMUX_IPSR_DATA(IP6_10,	ARM_TRACEDATA_8),
+
+	PINMUX_IPSR_DATA(IP6_12_11,	SSI_SDATA4),
+	PINMUX_IPSR_MSEL(IP6_12_11,	SSI_WS2_A,	SEL_SSI2_A),
+	PINMUX_IPSR_DATA(IP6_12_11,	ARM_TRACEDATA_9),
+
+	PINMUX_IPSR_DATA(IP6_13,	SSI_SDATA3),
+	PINMUX_IPSR_DATA(IP6_13,	ARM_TRACEDATA_10),
+
+	PINMUX_IPSR_DATA(IP6_15_14,	SSI_SCK012),
+	PINMUX_IPSR_DATA(IP6_15_14,	ARM_TRACEDATA_11),
+	PINMUX_IPSR_DATA(IP6_15_14,	TX0_D),
+
+	PINMUX_IPSR_DATA(IP6_16,	SSI_WS012),
+	PINMUX_IPSR_DATA(IP6_16,	ARM_TRACEDATA_12),
+
+	PINMUX_IPSR_DATA(IP6_18_17,	SSI_SDATA2),
+	PINMUX_IPSR_MSEL(IP6_18_17,	HSPI_CS2_A,	SEL_HSPI2_A),
+	PINMUX_IPSR_DATA(IP6_18_17,	ARM_TRACEDATA_13),
+	PINMUX_IPSR_MSEL(IP6_18_17,	SDA1_A,		SEL_I2C1_A),
+
+	PINMUX_IPSR_DATA(IP6_20_19,	SSI_SDATA1),
+	PINMUX_IPSR_DATA(IP6_20_19,	ARM_TRACEDATA_14),
+	PINMUX_IPSR_MSEL(IP6_20_19,	SCL1_A,		SEL_I2C1_A),
+	PINMUX_IPSR_MSEL(IP6_20_19,	SCK2_A,		SEL_SCIF2_A),
+
+	PINMUX_IPSR_DATA(IP6_21,	SSI_SDATA0),
+	PINMUX_IPSR_DATA(IP6_21,	ARM_TRACEDATA_15),
+
+	PINMUX_IPSR_DATA(IP6_23_22,	SD0_CLK),
+	PINMUX_IPSR_DATA(IP6_23_22,	SUB_TDO),
+
+	PINMUX_IPSR_DATA(IP6_25_24,	SD0_CMD),
+	PINMUX_IPSR_DATA(IP6_25_24,	SUB_TRST),
+
+	PINMUX_IPSR_DATA(IP6_27_26,	SD0_DAT0),
+	PINMUX_IPSR_DATA(IP6_27_26,	SUB_TMS),
+
+	PINMUX_IPSR_DATA(IP6_29_28,	SD0_DAT1),
+	PINMUX_IPSR_DATA(IP6_29_28,	SUB_TCK),
+
+	PINMUX_IPSR_DATA(IP6_31_30,	SD0_DAT2),
+	PINMUX_IPSR_DATA(IP6_31_30,	SUB_TDI),
+
+	/* IPSR7 */
+	PINMUX_IPSR_DATA(IP7_1_0,	SD0_DAT3),
+	PINMUX_IPSR_MSEL(IP7_1_0,	IRQ1_B,		SEL_IRQ1_B),
+
+	PINMUX_IPSR_DATA(IP7_3_2,	SD0_CD),
+	PINMUX_IPSR_DATA(IP7_3_2,	TX5_A),
+
+	PINMUX_IPSR_DATA(IP7_5_4,	SD0_WP),
+	PINMUX_IPSR_MSEL(IP7_5_4,	RX5_A,		SEL_SCIF5_A),
+
+	PINMUX_IPSR_DATA(IP7_8_6,	VI1_CLKENB),
+	PINMUX_IPSR_MSEL(IP7_8_6,	HSPI_CLK0_A,	SEL_HSPI0_A),
+	PINMUX_IPSR_DATA(IP7_8_6,	HTX1_A),
+	PINMUX_IPSR_MSEL(IP7_8_6,	RTS1_C,		SEL_SCIF1_C),
+
+	PINMUX_IPSR_DATA(IP7_11_9,	VI1_FIELD),
+	PINMUX_IPSR_MSEL(IP7_11_9,	HSPI_CS0_A,	SEL_HSPI0_A),
+	PINMUX_IPSR_MSEL(IP7_11_9,	HRX1_A,		SEL_HSCIF1_A),
+	PINMUX_IPSR_MSEL(IP7_11_9,	SCK1_C,		SEL_SCIF1_C),
+
+	PINMUX_IPSR_DATA(IP7_14_12,	VI1_HSYNC),
+	PINMUX_IPSR_MSEL(IP7_14_12,	HSPI_RX0_A,	SEL_HSPI0_A),
+	PINMUX_IPSR_MSEL(IP7_14_12,	HRTS1_A,	SEL_HSCIF1_A),
+	PINMUX_IPSR_MSEL(IP7_14_12,	FMCLK_A,	SEL_FM_A),
+	PINMUX_IPSR_MSEL(IP7_14_12,	RX1_C,		SEL_SCIF1_C),
+
+	PINMUX_IPSR_DATA(IP7_17_15,	VI1_VSYNC),
+	PINMUX_IPSR_DATA(IP7_17_15,	HSPI_TX0),
+	PINMUX_IPSR_MSEL(IP7_17_15,	HCTS1_A,	SEL_HSCIF1_A),
+	PINMUX_IPSR_DATA(IP7_17_15,	BPFCLK_A),
+	PINMUX_IPSR_DATA(IP7_17_15,	TX1_C),
+
+	PINMUX_IPSR_DATA(IP7_20_18,	TCLK0),
+	PINMUX_IPSR_MSEL(IP7_20_18,	HSCK1_A,	SEL_HSCIF1_A),
+	PINMUX_IPSR_MSEL(IP7_20_18,	FMIN_A,		SEL_FM_A),
+	PINMUX_IPSR_MSEL(IP7_20_18,	IRQ2_C,		SEL_IRQ2_C),
+	PINMUX_IPSR_MSEL(IP7_20_18,	CTS1_C,		SEL_SCIF1_C),
+	PINMUX_IPSR_DATA(IP7_20_18,	SPEEDIN),
+
+	PINMUX_IPSR_DATA(IP7_21,	VI0_CLK),
+	PINMUX_IPSR_MSEL(IP7_21,	CAN_CLK_A,	SEL_CANCLK_A),
+
+	PINMUX_IPSR_DATA(IP7_24_22,	VI0_CLKENB),
+	PINMUX_IPSR_MSEL(IP7_24_22,	SD2_DAT2_B,	SEL_SD2_B),
+	PINMUX_IPSR_DATA(IP7_24_22,	VI1_DATA0),
+	PINMUX_IPSR_DATA(IP7_24_22,	DU1_DG6),
+	PINMUX_IPSR_MSEL(IP7_24_22,	HSPI_RX1_A,	SEL_HSPI1_A),
+	PINMUX_IPSR_MSEL(IP7_24_22,	RX4_B,		SEL_SCIF4_B),
+
+	PINMUX_IPSR_DATA(IP7_28_25,	VI0_FIELD),
+	PINMUX_IPSR_MSEL(IP7_28_25,	SD2_DAT3_B,	SEL_SD2_B),
+	PINMUX_DATA(VI0_R3_C_MARK,	FN_IP7_28_25,	FN_VI0_R3_C,	FN_SEL_VI0_C), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R3_D_MARK,	FN_IP7_28_25,	FN_VI0_R3_C,	FN_SEL_VI0_D), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP7_28_25,	VI1_DATA1),
+	PINMUX_IPSR_DATA(IP7_28_25,	DU1_DG7),
+	PINMUX_IPSR_MSEL(IP7_28_25,	HSPI_CLK1_A,	SEL_HSPI1_A),
+	PINMUX_IPSR_DATA(IP7_28_25,	TX4_B),
+
+	PINMUX_IPSR_DATA(IP7_31_29,	VI0_HSYNC),
+	PINMUX_IPSR_MSEL(IP7_31_29,	SD2_CD_B,	SEL_SD2_B),
+	PINMUX_IPSR_DATA(IP7_31_29,	VI1_DATA2),
+	PINMUX_IPSR_DATA(IP7_31_29,	DU1_DR2),
+	PINMUX_IPSR_MSEL(IP7_31_29,	HSPI_CS1_A,	SEL_HSPI1_A),
+	PINMUX_IPSR_MSEL(IP7_31_29,	RX3_B,		SEL_SCIF3_B),
+
+	/* IPSR8 */
+	PINMUX_IPSR_DATA(IP8_2_0,	VI0_VSYNC),
+	PINMUX_IPSR_MSEL(IP8_2_0,	SD2_WP_B,	SEL_SD2_B),
+	PINMUX_IPSR_DATA(IP8_2_0,	VI1_DATA3),
+	PINMUX_IPSR_DATA(IP8_2_0,	DU1_DR3),
+	PINMUX_IPSR_DATA(IP8_2_0,	HSPI_TX1_A),
+	PINMUX_IPSR_DATA(IP8_2_0,	TX3_B),
+
+	PINMUX_IPSR_DATA(IP8_5_3,	VI0_DATA0_VI0_B0),
+	PINMUX_IPSR_DATA(IP8_5_3,	DU1_DG2),
+	PINMUX_IPSR_MSEL(IP8_5_3,	IRQ2_B,		SEL_IRQ2_B),
+	PINMUX_IPSR_MSEL(IP8_5_3,	RX3_D,		SEL_SCIF3_D),
+
+	PINMUX_IPSR_DATA(IP8_8_6,	VI0_DATA1_VI0_B1),
+	PINMUX_IPSR_DATA(IP8_8_6,	DU1_DG3),
+	PINMUX_IPSR_MSEL(IP8_8_6,	IRQ3_B,		SEL_IRQ3_B),
+	PINMUX_IPSR_DATA(IP8_8_6,	TX3_D),
+
+	PINMUX_IPSR_DATA(IP8_10_9,	VI0_DATA2_VI0_B2),
+	PINMUX_IPSR_DATA(IP8_10_9,	DU1_DG4),
+	PINMUX_IPSR_MSEL(IP8_10_9,	RX0_C,		SEL_SCIF0_C),
+
+	PINMUX_IPSR_DATA(IP8_13_11,	VI0_DATA3_VI0_B3),
+	PINMUX_IPSR_DATA(IP8_13_11,	DU1_DG5),
+	PINMUX_IPSR_DATA(IP8_13_11,	TX1_A),
+	PINMUX_IPSR_DATA(IP8_13_11,	TX0_C),
+
+	PINMUX_IPSR_DATA(IP8_15_14,	VI0_DATA4_VI0_B4),
+	PINMUX_IPSR_DATA(IP8_15_14,	DU1_DB2),
+	PINMUX_IPSR_MSEL(IP8_15_14,	RX1_A,		SEL_SCIF1_A),
+
+	PINMUX_IPSR_DATA(IP8_18_16,	VI0_DATA5_VI0_B5),
+	PINMUX_IPSR_DATA(IP8_18_16,	DU1_DB3),
+	PINMUX_IPSR_MSEL(IP8_18_16,	SCK1_A,		SEL_SCIF1_A),
+	PINMUX_IPSR_DATA(IP8_18_16,	PWM4),
+	PINMUX_IPSR_MSEL(IP8_18_16,	HSCK1_B,	SEL_HSCIF1_B),
+
+	PINMUX_IPSR_DATA(IP8_21_19,	VI0_DATA6_VI0_G0),
+	PINMUX_IPSR_DATA(IP8_21_19,	DU1_DB4),
+	PINMUX_IPSR_MSEL(IP8_21_19,	CTS1_A,		SEL_SCIF1_A),
+	PINMUX_IPSR_DATA(IP8_21_19,	PWM5),
+
+	PINMUX_IPSR_DATA(IP8_23_22,	VI0_DATA7_VI0_G1),
+	PINMUX_IPSR_DATA(IP8_23_22,	DU1_DB5),
+	PINMUX_IPSR_MSEL(IP8_23_22,	RTS1_A,		SEL_SCIF1_A),
+
+	PINMUX_IPSR_DATA(IP8_26_24,	VI0_G2),
+	PINMUX_IPSR_DATA(IP8_26_24,	SD2_CLK_B),
+	PINMUX_IPSR_DATA(IP8_26_24,	VI1_DATA4),
+	PINMUX_IPSR_DATA(IP8_26_24,	DU1_DR4),
+	PINMUX_IPSR_DATA(IP8_26_24,	HTX1_B),
+
+	PINMUX_IPSR_DATA(IP8_29_27,	VI0_G3),
+	PINMUX_IPSR_MSEL(IP8_29_27,	SD2_CMD_B,	SEL_SD2_B),
+	PINMUX_IPSR_DATA(IP8_29_27,	VI1_DATA5),
+	PINMUX_IPSR_DATA(IP8_29_27,	DU1_DR5),
+	PINMUX_IPSR_MSEL(IP8_29_27,	HRX1_B,		SEL_HSCIF1_B),
+
+	/* IPSR9 */
+	PINMUX_IPSR_DATA(IP9_2_0,	VI0_G4),
+	PINMUX_IPSR_MSEL(IP9_2_0,	SD2_DAT0_B,	SEL_SD2_B),
+	PINMUX_IPSR_DATA(IP9_2_0,	VI1_DATA6),
+	PINMUX_IPSR_DATA(IP9_2_0,	DU1_DR6),
+	PINMUX_IPSR_MSEL(IP9_2_0,	HRTS1_B,	SEL_HSCIF1_B),
+
+	PINMUX_IPSR_DATA(IP9_5_3,	VI0_G5),
+	PINMUX_IPSR_MSEL(IP9_5_3,	SD2_DAT1_B,	SEL_SD2_B),
+	PINMUX_IPSR_DATA(IP9_5_3,	VI1_DATA7),
+	PINMUX_IPSR_DATA(IP9_5_3,	DU1_DR7),
+	PINMUX_IPSR_MSEL(IP9_5_3,	HCTS1_B,	SEL_HSCIF1_B),
+
+	PINMUX_DATA(VI0_R0_A_MARK,	FN_IP9_8_6,	FN_VI0_R0_A,	FN_SEL_VI0_A), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R0_C_MARK,	FN_IP9_8_6,	FN_VI0_R0_A,	FN_SEL_VI0_C), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP9_8_6,	VI1_CLK),
+	PINMUX_IPSR_DATA(IP9_8_6,	ETH_REF_CLK),
+	PINMUX_IPSR_DATA(IP9_8_6,	DU1_DOTCLKIN),
+
+	PINMUX_DATA(VI0_R1_A_MARK,	FN_IP9_11_9,	FN_VI0_R1_A,	FN_SEL_VI0_A), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R1_C_MARK,	FN_IP9_11_9,	FN_VI0_R1_A,	FN_SEL_VI0_C), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP9_11_9,	VI1_DATA8),
+	PINMUX_IPSR_DATA(IP9_11_9,	DU1_DB6),
+	PINMUX_IPSR_DATA(IP9_11_9,	ETH_TXD0),
+	PINMUX_IPSR_DATA(IP9_11_9,	PWM2),
+	PINMUX_IPSR_DATA(IP9_11_9,	TCLK1),
+
+	PINMUX_DATA(VI0_R2_A_MARK,	FN_IP9_14_12,	FN_VI0_R2_A,	FN_SEL_VI0_A), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R2_C_MARK,	FN_IP9_14_12,	FN_VI0_R2_A,	FN_SEL_VI0_C), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP9_14_12,	VI1_DATA9),
+	PINMUX_IPSR_DATA(IP9_14_12,	DU1_DB7),
+	PINMUX_IPSR_DATA(IP9_14_12,	ETH_TXD1),
+	PINMUX_IPSR_DATA(IP9_14_12,	PWM3),
+
+	PINMUX_IPSR_MSEL(IP9_17_15,	VI0_R3_A,	SEL_VI0_A),
+	PINMUX_IPSR_DATA(IP9_17_15,	ETH_CRS_DV),
+	PINMUX_IPSR_DATA(IP9_17_15,	IECLK),
+	PINMUX_IPSR_MSEL(IP9_17_15,	SCK2_C,		SEL_SCIF2_C),
+
+	PINMUX_DATA(VI0_R4_A_MARK,	FN_IP9_20_18,	FN_VI0_R4_A,	FN_SEL_VI0_A), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R3_C_MARK,	FN_IP9_20_18,	FN_VI0_R4_A,	FN_SEL_VI0_C), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP9_20_18,	ETH_TX_EN),
+	PINMUX_IPSR_DATA(IP9_20_18,	IETX),
+	PINMUX_IPSR_DATA(IP9_20_18,	TX2_C),
+
+	PINMUX_DATA(VI0_R5_A_MARK,	FN_IP9_23_21,	FN_VI0_R5_A,	FN_SEL_VI0_A), /* see sel_vi0 */
+	PINMUX_DATA(VI0_R5_C_MARK,	FN_IP9_23_21,	FN_VI0_R5_A,	FN_SEL_VI0_C), /* see sel_vi0 */
+	PINMUX_IPSR_DATA(IP9_23_21,	ETH_RX_ER),
+	PINMUX_IPSR_MSEL(IP9_23_21,	FMCLK_C,	SEL_FM_C),
+	PINMUX_IPSR_DATA(IP9_23_21,	IERX),
+	PINMUX_IPSR_MSEL(IP9_23_21,	RX2_C,		SEL_SCIF2_C),
+
+	PINMUX_IPSR_MSEL(IP9_26_24,	VI1_DATA10_A,	SEL_VI1_A),
+	PINMUX_IPSR_DATA(IP9_26_24,	DU1_DOTCLKOUT),
+	PINMUX_IPSR_DATA(IP9_26_24,	ETH_RXD0),
+	PINMUX_IPSR_DATA(IP9_26_24,	BPFCLK_C),
+	PINMUX_IPSR_DATA(IP9_26_24,	TX2_D),
+	PINMUX_IPSR_MSEL(IP9_26_24,	SDA2_C,		SEL_I2C2_C),
+
+	PINMUX_IPSR_MSEL(IP9_29_27,	VI1_DATA11_A,	SEL_VI1_A),
+	PINMUX_IPSR_DATA(IP9_29_27,	DU1_EXHSYNC_DU1_HSYNC),
+	PINMUX_IPSR_DATA(IP9_29_27,	ETH_RXD1),
+	PINMUX_IPSR_MSEL(IP9_29_27,	FMIN_C,		SEL_FM_C),
+	PINMUX_IPSR_MSEL(IP9_29_27,	RX2_D,		SEL_SCIF2_D),
+	PINMUX_IPSR_MSEL(IP9_29_27,	SCL2_C,		SEL_I2C2_C),
+
+	/* IPSR10 */
+	PINMUX_IPSR_DATA(IP10_2_0,	SD2_CLK_A),
+	PINMUX_IPSR_DATA(IP10_2_0,	DU1_EXVSYNC_DU1_VSYNC),
+	PINMUX_IPSR_DATA(IP10_2_0,	ATARD1),
+	PINMUX_IPSR_DATA(IP10_2_0,	ETH_MDC),
+	PINMUX_IPSR_MSEL(IP10_2_0,	SDA1_B,		SEL_I2C1_B),
+
+	PINMUX_IPSR_MSEL(IP10_5_3,	SD2_CMD_A,	SEL_SD2_A),
+	PINMUX_IPSR_DATA(IP10_5_3,	DU1_EXODDF_DU1_ODDF_DISP_CDE),
+	PINMUX_IPSR_DATA(IP10_5_3,	ATAWR1),
+	PINMUX_IPSR_DATA(IP10_5_3,	ETH_MDIO),
+	PINMUX_IPSR_MSEL(IP10_5_3,	SCL1_B,		SEL_I2C1_B),
+
+	PINMUX_IPSR_MSEL(IP10_8_6,	SD2_DAT0_A,	SEL_SD2_A),
+	PINMUX_IPSR_DATA(IP10_8_6,	DU1_DISP),
+	PINMUX_IPSR_DATA(IP10_8_6,	ATACS01),
+	PINMUX_IPSR_MSEL(IP10_8_6,	DREQ1_B,	SEL_DREQ1_B),
+	PINMUX_IPSR_DATA(IP10_8_6,	ETH_LINK),
+	PINMUX_IPSR_MSEL(IP10_8_6,	CAN1_RX_A,	SEL_CAN1_A),
+
+	PINMUX_IPSR_MSEL(IP10_12_9,	SD2_DAT1_A,	SEL_SD2_A),
+	PINMUX_IPSR_DATA(IP10_12_9,	DU1_CDE),
+	PINMUX_IPSR_DATA(IP10_12_9,	ATACS11),
+	PINMUX_IPSR_DATA(IP10_12_9,	DACK1_B),
+	PINMUX_IPSR_DATA(IP10_12_9,	ETH_MAGIC),
+	PINMUX_IPSR_DATA(IP10_12_9,	CAN1_TX_A),
+	PINMUX_IPSR_DATA(IP10_12_9,	PWM6),
+
+	PINMUX_IPSR_MSEL(IP10_15_13,	SD2_DAT2_A,	SEL_SD2_A),
+	PINMUX_IPSR_DATA(IP10_15_13,	VI1_DATA12),
+	PINMUX_IPSR_MSEL(IP10_15_13,	DREQ2_B,	SEL_DREQ2_B),
+	PINMUX_IPSR_DATA(IP10_15_13,	ATADIR1),
+	PINMUX_IPSR_MSEL(IP10_15_13,	HSPI_CLK2_B,	SEL_HSPI2_B),
+	PINMUX_IPSR_MSEL(IP10_15_13,	GPSCLK_B,	SEL_GPS_B),
+
+	PINMUX_IPSR_MSEL(IP10_18_16,	SD2_DAT3_A,	SEL_SD2_A),
+	PINMUX_IPSR_DATA(IP10_18_16,	VI1_DATA13),
+	PINMUX_IPSR_DATA(IP10_18_16,	DACK2_B),
+	PINMUX_IPSR_DATA(IP10_18_16,	ATAG1),
+	PINMUX_IPSR_MSEL(IP10_18_16,	HSPI_CS2_B,	SEL_HSPI2_B),
+	PINMUX_IPSR_MSEL(IP10_18_16,	GPSIN_B,	SEL_GPS_B),
+
+	PINMUX_IPSR_MSEL(IP10_21_19,	SD2_CD_A,	SEL_SD2_A),
+	PINMUX_IPSR_DATA(IP10_21_19,	VI1_DATA14),
+	PINMUX_IPSR_MSEL(IP10_21_19,	EX_WAIT1_B,	SEL_WAIT1_B),
+	PINMUX_IPSR_MSEL(IP10_21_19,	DREQ0_B,	SEL_DREQ0_B),
+	PINMUX_IPSR_MSEL(IP10_21_19,	HSPI_RX2_B,	SEL_HSPI2_B),
+	PINMUX_IPSR_MSEL(IP10_21_19,	REMOCON_A,	SEL_REMOCON_A),
+
+	PINMUX_IPSR_MSEL(IP10_24_22,	SD2_WP_A,	SEL_SD2_A),
+	PINMUX_IPSR_DATA(IP10_24_22,	VI1_DATA15),
+	PINMUX_IPSR_MSEL(IP10_24_22,	EX_WAIT2_B,	SEL_WAIT2_B),
+	PINMUX_IPSR_DATA(IP10_24_22,	DACK0_B),
+	PINMUX_IPSR_DATA(IP10_24_22,	HSPI_TX2_B),
+	PINMUX_IPSR_MSEL(IP10_24_22,	CAN_CLK_C,	SEL_CANCLK_C),
+};
+
+static struct sh_pfc_pin pinmux_pins[] = {
+	PINMUX_GPIO_GP_ALL(),
+};
+
+/* Pin numbers for pins without a corresponding GPIO port number are computed
+ * from the row and column numbers with a 1000 offset to avoid collisions with
+ * GPIO port numbers.
+ */
+#define PIN_NUMBER(row, col)		(1000+((row)-1)*25+(col)-1)
+
+/* - macro */
+#define SH_PFC_PINS(name, args...) \
+	static const unsigned int name ##_pins[] = { args }
+#define SH_PFC_MUX1(name, arg1)					\
+	static const unsigned int name ##_mux[]  = { arg1##_MARK }
+#define SH_PFC_MUX2(name, arg1, arg2)					\
+	static const unsigned int name ##_mux[]  = { arg1##_MARK, arg2##_MARK, }
+#define SH_PFC_MUX3(name, arg1, arg2, arg3)					\
+	static const unsigned int name ##_mux[]  = { arg1##_MARK, arg2##_MARK,	\
+						     arg3##_MARK }
+#define SH_PFC_MUX4(name, arg1, arg2, arg3, arg4)			\
+	static const unsigned int name ##_mux[]  = { arg1##_MARK, arg2##_MARK, \
+						     arg3##_MARK, arg4##_MARK }
+#define SH_PFC_MUX8(name, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
+	static const unsigned int name ##_mux[]  = { arg1##_MARK, arg2##_MARK, \
+						     arg3##_MARK, arg4##_MARK, \
+						     arg5##_MARK, arg6##_MARK, \
+						     arg7##_MARK, arg8##_MARK, }
+
+/* - Ether ------------------------------------------------------------------ */
+SH_PFC_PINS(ether_rmii,		RCAR_GP_PIN(4, 10),	RCAR_GP_PIN(4, 11),
+				RCAR_GP_PIN(4, 13),	RCAR_GP_PIN(4, 9),
+				RCAR_GP_PIN(4, 15),	RCAR_GP_PIN(4, 16),
+				RCAR_GP_PIN(4, 12),	RCAR_GP_PIN(4, 14),
+				RCAR_GP_PIN(4, 18),	RCAR_GP_PIN(4, 17));
+static const unsigned int ether_rmii_mux[] = {
+	ETH_TXD0_MARK, ETH_TXD1_MARK, ETH_TX_EN_MARK,  ETH_REF_CLK_MARK,
+	ETH_RXD0_MARK, ETH_RXD1_MARK, ETH_CRS_DV_MARK, ETH_RX_ER_MARK,
+	ETH_MDIO_MARK, ETH_MDC_MARK,
+};
+SH_PFC_PINS(ether_link,		RCAR_GP_PIN(4, 19));
+SH_PFC_MUX1(ether_link,		ETH_LINK);
+SH_PFC_PINS(ether_magic,	RCAR_GP_PIN(4, 20));
+SH_PFC_MUX1(ether_magic,	ETH_MAGIC);
+
+/* - SCIF macro ------------------------------------------------------------- */
+#define SCIF_PFC_PIN(name, args...)	SH_PFC_PINS(name, args)
+#define SCIF_PFC_DAT(name, tx, rx)	SH_PFC_MUX2(name, tx, rx)
+#define SCIF_PFC_CTR(name, cts, rts)	SH_PFC_MUX2(name, cts, rts)
+#define SCIF_PFC_CLK(name, sck)		SH_PFC_MUX1(name, sck)
+
+/* - HSCIF0 ----------------------------------------------------------------- */
+SCIF_PFC_PIN(hscif0_data_a,	RCAR_GP_PIN(1, 17),	RCAR_GP_PIN(1, 18));
+SCIF_PFC_DAT(hscif0_data_a,	HTX0_A,			HRX0_A);
+SCIF_PFC_PIN(hscif0_data_b,	RCAR_GP_PIN(0, 29),	RCAR_GP_PIN(0, 30));
+SCIF_PFC_DAT(hscif0_data_b,	HTX0_B,			HRX0_B);
+SCIF_PFC_PIN(hscif0_ctrl_a,	RCAR_GP_PIN(1, 20),	RCAR_GP_PIN(1, 21));
+SCIF_PFC_CTR(hscif0_ctrl_a,	HCTS0_A,		HRTS0_A);
+SCIF_PFC_PIN(hscif0_ctrl_b,	RCAR_GP_PIN(0, 31),	RCAR_GP_PIN(0, 28));
+SCIF_PFC_CTR(hscif0_ctrl_b,	HCTS0_B,		HRTS0_B);
+SCIF_PFC_PIN(hscif0_clk,	RCAR_GP_PIN(1, 19));
+SCIF_PFC_CLK(hscif0_clk,	HSCK0);
+
+/* - HSCIF1 ----------------------------------------------------------------- */
+SCIF_PFC_PIN(hscif1_data_a,	RCAR_GP_PIN(3, 19),	RCAR_GP_PIN(3, 20));
+SCIF_PFC_DAT(hscif1_data_a,	HTX1_A,			HRX1_A);
+SCIF_PFC_PIN(hscif1_data_b,	RCAR_GP_PIN(4, 5),	RCAR_GP_PIN(4, 6));
+SCIF_PFC_DAT(hscif1_data_b,	HTX1_B,			HRX1_B);
+SCIF_PFC_PIN(hscif1_ctrl_a,	RCAR_GP_PIN(3, 22),	RCAR_GP_PIN(3, 21));
+SCIF_PFC_CTR(hscif1_ctrl_a,	HCTS1_A,		HRTS1_A);
+SCIF_PFC_PIN(hscif1_ctrl_b,	RCAR_GP_PIN(4, 8),	RCAR_GP_PIN(4, 7));
+SCIF_PFC_CTR(hscif1_ctrl_b,	HCTS1_B,		HRTS1_B);
+SCIF_PFC_PIN(hscif1_clk_a,	RCAR_GP_PIN(3, 23));
+SCIF_PFC_CLK(hscif1_clk_a,	HSCK1_A);
+SCIF_PFC_PIN(hscif1_clk_b,	RCAR_GP_PIN(4, 2));
+SCIF_PFC_CLK(hscif1_clk_b,	HSCK1_B);
+
+/* - HSPI macro --------------------------------------------------------------*/
+#define HSPI_PFC_PIN(name, args...)		SH_PFC_PINS(name, args)
+#define HSPI_PFC_DAT(name, clk, cs, rx, tx)	SH_PFC_MUX4(name, clk, cs, rx, tx)
+
+/* - HSPI0 -------------------------------------------------------------------*/
+HSPI_PFC_PIN(hspi0_a,	RCAR_GP_PIN(3, 19),	RCAR_GP_PIN(3, 20),
+			RCAR_GP_PIN(3, 21),	RCAR_GP_PIN(3, 22));
+HSPI_PFC_DAT(hspi0_a,	HSPI_CLK0_A,		HSPI_CS0_A,
+			HSPI_RX0_A,		HSPI_TX0);
+
+HSPI_PFC_PIN(hspi0_b,	RCAR_GP_PIN(2, 25),	RCAR_GP_PIN(2, 26),
+			RCAR_GP_PIN(2, 24),	RCAR_GP_PIN(2, 27));
+HSPI_PFC_DAT(hspi0_b,	HSPI_CLK0_B,		HSPI_CS0_B,
+			HSPI_RX0_B,		HSPI_TX0_B);
+
+/* - HSPI1 -------------------------------------------------------------------*/
+HSPI_PFC_PIN(hspi1_a,	RCAR_GP_PIN(3, 26),	RCAR_GP_PIN(3, 27),
+			RCAR_GP_PIN(3, 25),	RCAR_GP_PIN(3, 28));
+HSPI_PFC_DAT(hspi1_a,	HSPI_CLK1_A,		HSPI_CS1_A,
+			HSPI_RX1_A,		HSPI_TX1_A);
+
+HSPI_PFC_PIN(hspi1_b,	RCAR_GP_PIN(0, 27),	RCAR_GP_PIN(0, 26),
+			PIN_NUMBER(20, 1),	PIN_NUMBER(25, 2));
+HSPI_PFC_DAT(hspi1_b,	HSPI_CLK1_B,		HSPI_CS1_B,
+			HSPI_RX1_B,		HSPI_TX1_B);
+
+/* - HSPI2 -------------------------------------------------------------------*/
+HSPI_PFC_PIN(hspi2_a,	RCAR_GP_PIN(2, 29),	RCAR_GP_PIN(3, 8),
+			RCAR_GP_PIN(2, 28),	RCAR_GP_PIN(2, 30));
+HSPI_PFC_DAT(hspi2_a,	HSPI_CLK2_A,		HSPI_CS2_A,
+			HSPI_RX2_A,		HSPI_TX2_A);
+
+HSPI_PFC_PIN(hspi2_b,	RCAR_GP_PIN(4, 21),	RCAR_GP_PIN(4, 22),
+			RCAR_GP_PIN(4, 23),	RCAR_GP_PIN(4, 24));
+HSPI_PFC_DAT(hspi2_b,	HSPI_CLK2_B,		HSPI_CS2_B,
+			HSPI_RX2_B,		HSPI_TX2_B);
+
+/* - I2C macro ------------------------------------------------------------- */
+#define I2C_PFC_PIN(name, args...)	SH_PFC_PINS(name, args)
+#define I2C_PFC_MUX(name, sda, scl)	SH_PFC_MUX2(name, sda, scl)
+
+/* - I2C1 ------------------------------------------------------------------ */
+I2C_PFC_PIN(i2c1_a,	RCAR_GP_PIN(3, 8),	RCAR_GP_PIN(3, 9));
+I2C_PFC_MUX(i2c1_a,	SDA1_A,			SCL1_A);
+I2C_PFC_PIN(i2c1_b,	RCAR_GP_PIN(4, 17),	RCAR_GP_PIN(4, 18));
+I2C_PFC_MUX(i2c1_b,	SDA1_B,			SCL1_B);
+
+/* - I2C2 ------------------------------------------------------------------ */
+I2C_PFC_PIN(i2c2_a,	PIN_NUMBER(3, 20),	RCAR_GP_PIN(1, 3));
+I2C_PFC_MUX(i2c2_a,	SDA2_A,			SCL2_A);
+I2C_PFC_PIN(i2c2_b,	RCAR_GP_PIN(0, 3),	RCAR_GP_PIN(0, 4));
+I2C_PFC_MUX(i2c2_b,	SDA2_B,			SCL2_B);
+I2C_PFC_PIN(i2c2_c,	RCAR_GP_PIN(4, 15),	RCAR_GP_PIN(4, 16));
+I2C_PFC_MUX(i2c2_c,	SDA2_C,			SCL2_C);
+
+/* - I2C3 ------------------------------------------------------------------ */
+I2C_PFC_PIN(i2c3_a,	RCAR_GP_PIN(1, 14),	RCAR_GP_PIN(1, 15));
+I2C_PFC_MUX(i2c3_a,	SDA3_A,			SCL3_A);
+I2C_PFC_PIN(i2c3_b,	RCAR_GP_PIN(1, 16),	RCAR_GP_PIN(1, 19));
+I2C_PFC_MUX(i2c3_b,	SDA3_B,			SCL3_B);
+I2C_PFC_PIN(i2c3_c,	RCAR_GP_PIN(1, 22),	RCAR_GP_PIN(1, 23));
+I2C_PFC_MUX(i2c3_c,	SDA3_C,			SCL3_C);
+
+/* - MMC macro -------------------------------------------------------------- */
+#define MMC_PFC_PINS(name, args...)		SH_PFC_PINS(name, args)
+#define MMC_PFC_CTRL(name, clk, cmd)		SH_PFC_MUX2(name, clk, cmd)
+#define MMC_PFC_DAT1(name, d0)			SH_PFC_MUX1(name, d0)
+#define MMC_PFC_DAT4(name, d0, d1, d2, d3)	SH_PFC_MUX4(name, d0, d1, d2, d3)
+#define MMC_PFC_DAT8(name, d0, d1, d2, d3, d4, d5, d6, d7)	\
+			SH_PFC_MUX8(name, d0, d1, d2, d3, d4, d5, d6, d7)
+
+/* - MMC -------------------------------------------------------------------- */
+MMC_PFC_PINS(mmc_ctrl,		RCAR_GP_PIN(1, 5),	RCAR_GP_PIN(1, 6));
+MMC_PFC_CTRL(mmc_ctrl,		MMC_CLK,		MMC_CMD);
+MMC_PFC_PINS(mmc_data1,		RCAR_GP_PIN(1, 7));
+MMC_PFC_DAT1(mmc_data1,		MMC_D0);
+MMC_PFC_PINS(mmc_data4,		RCAR_GP_PIN(1, 7),	RCAR_GP_PIN(1, 8),
+				RCAR_GP_PIN(0, 5),	RCAR_GP_PIN(0, 6));
+MMC_PFC_DAT4(mmc_data4,		MMC_D0,			MMC_D1,
+				MMC_D2,			MMC_D3);
+MMC_PFC_PINS(mmc_data8,		RCAR_GP_PIN(1, 7),	RCAR_GP_PIN(1, 8),
+				RCAR_GP_PIN(0, 5),	RCAR_GP_PIN(0, 6),
+				RCAR_GP_PIN(1, 4),	RCAR_GP_PIN(1, 0),
+				RCAR_GP_PIN(0, 30),	RCAR_GP_PIN(0, 31));
+MMC_PFC_DAT8(mmc_data8,		MMC_D0,			MMC_D1,
+				MMC_D2,			MMC_D3,
+				MMC_D4,			MMC_D5,
+				MMC_D6,			MMC_D7);
+
+/* - SCIF CLOCK ------------------------------------------------------------- */
+SCIF_PFC_PIN(scif_clk,		RCAR_GP_PIN(1, 16));
+SCIF_PFC_CLK(scif_clk,		SCIF_CLK);
+
+/* - SCIF0 ------------------------------------------------------------------ */
+SCIF_PFC_PIN(scif0_data_a,	RCAR_GP_PIN(1, 17),	RCAR_GP_PIN(1, 18));
+SCIF_PFC_DAT(scif0_data_a,	TX0_A,			RX0_A);
+SCIF_PFC_PIN(scif0_data_b,	RCAR_GP_PIN(2, 3),	RCAR_GP_PIN(2, 2));
+SCIF_PFC_DAT(scif0_data_b,	TX0_B,			RX0_B);
+SCIF_PFC_PIN(scif0_data_c,	RCAR_GP_PIN(4, 0),	RCAR_GP_PIN(3, 31));
+SCIF_PFC_DAT(scif0_data_c,	TX0_C,			RX0_C);
+SCIF_PFC_PIN(scif0_data_d,	RCAR_GP_PIN(3, 6),	RCAR_GP_PIN(3, 1));
+SCIF_PFC_DAT(scif0_data_d,	TX0_D,			RX0_D);
+SCIF_PFC_PIN(scif0_ctrl,	RCAR_GP_PIN(1, 20),	RCAR_GP_PIN(1, 21));
+SCIF_PFC_CTR(scif0_ctrl,	CTS0,			RTS0);
+SCIF_PFC_PIN(scif0_clk,		RCAR_GP_PIN(1, 19));
+SCIF_PFC_CLK(scif0_clk,		SCK0);
+
+/* - SCIF1 ------------------------------------------------------------------ */
+SCIF_PFC_PIN(scif1_data_a,	RCAR_GP_PIN(4, 0),	RCAR_GP_PIN(4, 1));
+SCIF_PFC_DAT(scif1_data_a,	TX1_A,			RX1_A);
+SCIF_PFC_PIN(scif1_data_b,	RCAR_GP_PIN(2, 24),	RCAR_GP_PIN(2, 25));
+SCIF_PFC_DAT(scif1_data_b,	TX1_B,			RX1_B);
+SCIF_PFC_PIN(scif1_data_c,	RCAR_GP_PIN(3, 22),	RCAR_GP_PIN(3, 21));
+SCIF_PFC_DAT(scif1_data_c,	TX1_C,			RX1_C);
+SCIF_PFC_PIN(scif1_data_d,	RCAR_GP_PIN(1, 30),	RCAR_GP_PIN(1, 31));
+SCIF_PFC_DAT(scif1_data_d,	TX1_D,			RX1_D);
+SCIF_PFC_PIN(scif1_ctrl_a,	RCAR_GP_PIN(4, 3),	RCAR_GP_PIN(4, 4));
+SCIF_PFC_CTR(scif1_ctrl_a,	CTS1_A,			RTS1_A);
+SCIF_PFC_PIN(scif1_ctrl_c,	RCAR_GP_PIN(3, 23),	RCAR_GP_PIN(3, 19));
+SCIF_PFC_CTR(scif1_ctrl_c,	CTS1_C,			RTS1_C);
+SCIF_PFC_PIN(scif1_clk_a,	RCAR_GP_PIN(4, 2));
+SCIF_PFC_CLK(scif1_clk_a,	SCK1_A);
+SCIF_PFC_PIN(scif1_clk_c,	RCAR_GP_PIN(3, 20));
+SCIF_PFC_CLK(scif1_clk_c,	SCK1_C);
+
+/* - SCIF2 ------------------------------------------------------------------ */
+SCIF_PFC_PIN(scif2_data_a,	RCAR_GP_PIN(2, 26),	RCAR_GP_PIN(2, 27));
+SCIF_PFC_DAT(scif2_data_a,	TX2_A,			RX2_A);
+SCIF_PFC_PIN(scif2_data_b,	RCAR_GP_PIN(0, 29),	RCAR_GP_PIN(0, 28));
+SCIF_PFC_DAT(scif2_data_b,	TX2_B,			RX2_B);
+SCIF_PFC_PIN(scif2_data_c,	RCAR_GP_PIN(4, 13),	RCAR_GP_PIN(4, 14));
+SCIF_PFC_DAT(scif2_data_c,	TX2_C,			RX2_C);
+SCIF_PFC_PIN(scif2_data_d,	RCAR_GP_PIN(4, 15),	RCAR_GP_PIN(4, 16));
+SCIF_PFC_DAT(scif2_data_d,	TX2_D,			RX2_D);
+SCIF_PFC_PIN(scif2_data_e,	RCAR_GP_PIN(0, 3),	RCAR_GP_PIN(0, 4));
+SCIF_PFC_DAT(scif2_data_e,	TX2_E,			RX2_E);
+SCIF_PFC_PIN(scif2_clk_a,	RCAR_GP_PIN(3, 9));
+SCIF_PFC_CLK(scif2_clk_a,	SCK2_A);
+SCIF_PFC_PIN(scif2_clk_b,	PIN_NUMBER(3, 20));
+SCIF_PFC_CLK(scif2_clk_b,	SCK2_B);
+SCIF_PFC_PIN(scif2_clk_c,	RCAR_GP_PIN(4, 12));
+SCIF_PFC_CLK(scif2_clk_c,	SCK2_C);
+
+/* - SCIF3 ------------------------------------------------------------------ */
+SCIF_PFC_PIN(scif3_data_a,	RCAR_GP_PIN(1, 10),	RCAR_GP_PIN(1, 9));
+SCIF_PFC_DAT(scif3_data_a,	TX3_A,			RX3_A);
+SCIF_PFC_PIN(scif3_data_b,	RCAR_GP_PIN(3, 28),	RCAR_GP_PIN(3, 27));
+SCIF_PFC_DAT(scif3_data_b,	TX3_B,			RX3_B);
+SCIF_PFC_PIN(scif3_data_c,	RCAR_GP_PIN(1, 3),	RCAR_GP_PIN(0, 31));
+SCIF_PFC_DAT(scif3_data_c,	TX3_C,			RX3_C);
+SCIF_PFC_PIN(scif3_data_d,	RCAR_GP_PIN(3, 30),	RCAR_GP_PIN(3, 29));
+SCIF_PFC_DAT(scif3_data_d,	TX3_D,			RX3_D);
+
+/* - SCIF4 ------------------------------------------------------------------ */
+SCIF_PFC_PIN(scif4_data_a,	RCAR_GP_PIN(2, 5),	RCAR_GP_PIN(2, 4));
+SCIF_PFC_DAT(scif4_data_a,	TX4_A,			RX4_A);
+SCIF_PFC_PIN(scif4_data_b,	RCAR_GP_PIN(3, 26),	RCAR_GP_PIN(3, 25));
+SCIF_PFC_DAT(scif4_data_b,	TX4_B,			RX4_B);
+SCIF_PFC_PIN(scif4_data_c,	RCAR_GP_PIN(3, 0),	RCAR_GP_PIN(2, 31));
+SCIF_PFC_DAT(scif4_data_c,	TX4_C,			RX4_C);
+
+/* - SCIF5 ------------------------------------------------------------------ */
+SCIF_PFC_PIN(scif5_data_a,	RCAR_GP_PIN(3, 17),	RCAR_GP_PIN(3, 18));
+SCIF_PFC_DAT(scif5_data_a,	TX5_A,			RX5_A);
+SCIF_PFC_PIN(scif5_data_b,	RCAR_GP_PIN(1, 15),	RCAR_GP_PIN(1, 14));
+SCIF_PFC_DAT(scif5_data_b,	TX5_B,			RX5_B);
+
+/* - SDHI macro ------------------------------------------------------------- */
+#define SDHI_PFC_PINS(name, args...)		SH_PFC_PINS(name, args)
+#define SDHI_PFC_DAT1(name, d0)			SH_PFC_MUX1(name, d0)
+#define SDHI_PFC_DAT4(name, d0, d1, d2, d3)	SH_PFC_MUX4(name, d0, d1, d2, d3)
+#define SDHI_PFC_CTRL(name, clk, cmd)		SH_PFC_MUX2(name, clk, cmd)
+#define SDHI_PFC_CDPN(name, cd)			SH_PFC_MUX1(name, cd)
+#define SDHI_PFC_WPPN(name, wp)			SH_PFC_MUX1(name, wp)
+
+/* - SDHI0 ------------------------------------------------------------------ */
+SDHI_PFC_PINS(sdhi0_cd,		RCAR_GP_PIN(3, 17));
+SDHI_PFC_CDPN(sdhi0_cd,		SD0_CD);
+SDHI_PFC_PINS(sdhi0_ctrl,	RCAR_GP_PIN(3, 11),	RCAR_GP_PIN(3, 12));
+SDHI_PFC_CTRL(sdhi0_ctrl,	SD0_CLK,		SD0_CMD);
+SDHI_PFC_PINS(sdhi0_data1,	RCAR_GP_PIN(3, 13));
+SDHI_PFC_DAT1(sdhi0_data1,	SD0_DAT0);
+SDHI_PFC_PINS(sdhi0_data4,	RCAR_GP_PIN(3, 13),	RCAR_GP_PIN(3, 14),
+				RCAR_GP_PIN(3, 15),	RCAR_GP_PIN(3, 16));
+SDHI_PFC_DAT4(sdhi0_data4,	SD0_DAT0,		SD0_DAT1,
+				SD0_DAT2,		SD0_DAT3);
+SDHI_PFC_PINS(sdhi0_wp,		RCAR_GP_PIN(3, 18));
+SDHI_PFC_WPPN(sdhi0_wp,		SD0_WP);
+
+/* - SDHI1 ------------------------------------------------------------------ */
+SDHI_PFC_PINS(sdhi1_cd_a,	RCAR_GP_PIN(0, 30));
+SDHI_PFC_CDPN(sdhi1_cd_a,	SD1_CD_A);
+SDHI_PFC_PINS(sdhi1_cd_b,	RCAR_GP_PIN(2, 24));
+SDHI_PFC_CDPN(sdhi1_cd_b,	SD1_CD_B);
+SDHI_PFC_PINS(sdhi1_ctrl_a,	RCAR_GP_PIN(1, 5),	RCAR_GP_PIN(1, 6));
+SDHI_PFC_CTRL(sdhi1_ctrl_a,	SD1_CLK_A,		SD1_CMD_A);
+SDHI_PFC_PINS(sdhi1_ctrl_b,	RCAR_GP_PIN(1, 17),	RCAR_GP_PIN(1, 16));
+SDHI_PFC_CTRL(sdhi1_ctrl_b,	SD1_CLK_B,		SD1_CMD_B);
+SDHI_PFC_PINS(sdhi1_data1_a,	RCAR_GP_PIN(1, 7));
+SDHI_PFC_DAT1(sdhi1_data1_a,	SD1_DAT0_A);
+SDHI_PFC_PINS(sdhi1_data1_b,	RCAR_GP_PIN(1, 18));
+SDHI_PFC_DAT1(sdhi1_data1_b,	SD1_DAT0_B);
+SDHI_PFC_PINS(sdhi1_data4_a,	RCAR_GP_PIN(1, 7),	RCAR_GP_PIN(1, 8),
+				RCAR_GP_PIN(0, 5),	RCAR_GP_PIN(0, 6));
+SDHI_PFC_DAT4(sdhi1_data4_a,	SD1_DAT0_A,		SD1_DAT1_A,
+				SD1_DAT2_A,		SD1_DAT3_A);
+SDHI_PFC_PINS(sdhi1_data4_b,	RCAR_GP_PIN(1, 18),	RCAR_GP_PIN(1, 19),
+				RCAR_GP_PIN(1, 20),	RCAR_GP_PIN(1, 21));
+SDHI_PFC_DAT4(sdhi1_data4_b,	SD1_DAT0_B,		SD1_DAT1_B,
+				SD1_DAT2_B,		SD1_DAT3_B);
+SDHI_PFC_PINS(sdhi1_wp_a,	RCAR_GP_PIN(0, 31));
+SDHI_PFC_WPPN(sdhi1_wp_a,	SD1_WP_A);
+SDHI_PFC_PINS(sdhi1_wp_b,	RCAR_GP_PIN(2, 25));
+SDHI_PFC_WPPN(sdhi1_wp_b,	SD1_WP_B);
+
+/* - SDH2 ------------------------------------------------------------------- */
+SDHI_PFC_PINS(sdhi2_cd_a,	RCAR_GP_PIN(4, 23));
+SDHI_PFC_CDPN(sdhi2_cd_a,	SD2_CD_A);
+SDHI_PFC_PINS(sdhi2_cd_b,	RCAR_GP_PIN(3, 27));
+SDHI_PFC_CDPN(sdhi2_cd_b,	SD2_CD_B);
+SDHI_PFC_PINS(sdhi2_ctrl_a,	RCAR_GP_PIN(4, 17),	RCAR_GP_PIN(4, 18));
+SDHI_PFC_CTRL(sdhi2_ctrl_a,	SD2_CLK_A,		SD2_CMD_A);
+SDHI_PFC_PINS(sdhi2_ctrl_b,	RCAR_GP_PIN(4, 5),	RCAR_GP_PIN(4, 6));
+SDHI_PFC_CTRL(sdhi2_ctrl_b,	SD2_CLK_B,		SD2_CMD_B);
+SDHI_PFC_PINS(sdhi2_data1_a,	RCAR_GP_PIN(4, 19));
+SDHI_PFC_DAT1(sdhi2_data1_a,	SD2_DAT0_A);
+SDHI_PFC_PINS(sdhi2_data1_b,	RCAR_GP_PIN(4, 7));
+SDHI_PFC_DAT1(sdhi2_data1_b,	SD2_DAT0_B);
+SDHI_PFC_PINS(sdhi2_data4_a,	RCAR_GP_PIN(4, 19),	RCAR_GP_PIN(4, 20),
+				RCAR_GP_PIN(4, 21),	RCAR_GP_PIN(4, 22));
+SDHI_PFC_DAT4(sdhi2_data4_a,	SD2_DAT0_A,		SD2_DAT1_A,
+				SD2_DAT2_A,		SD2_DAT3_A);
+SDHI_PFC_PINS(sdhi2_data4_b,	RCAR_GP_PIN(4, 7),	RCAR_GP_PIN(4, 8),
+				RCAR_GP_PIN(3, 25),	RCAR_GP_PIN(3, 26));
+SDHI_PFC_DAT4(sdhi2_data4_b,	SD2_DAT0_B,		SD2_DAT1_B,
+				SD2_DAT2_B,		SD2_DAT3_B);
+SDHI_PFC_PINS(sdhi2_wp_a,	RCAR_GP_PIN(4, 24));
+SDHI_PFC_WPPN(sdhi2_wp_a,	SD2_WP_A);
+SDHI_PFC_PINS(sdhi2_wp_b,	RCAR_GP_PIN(3, 28));
+SDHI_PFC_WPPN(sdhi2_wp_b,	SD2_WP_B);
+
+/* - USB0 ------------------------------------------------------------------- */
+SH_PFC_PINS(usb0,		RCAR_GP_PIN(0, 1));
+SH_PFC_MUX1(usb0,		PENC0);
+SH_PFC_PINS(usb0_ovc,		RCAR_GP_PIN(0, 3));
+SH_PFC_MUX1(usb0_ovc,		USB_OVC0);
+
+/* - USB1 ------------------------------------------------------------------- */
+SH_PFC_PINS(usb1,		RCAR_GP_PIN(0, 2));
+SH_PFC_MUX1(usb1,		PENC1);
+SH_PFC_PINS(usb1_ovc,		RCAR_GP_PIN(0, 4));
+SH_PFC_MUX1(usb1_ovc,		USB_OVC1);
+
+/* - VIN macros ------------------------------------------------------------- */
+#define VIN_PFC_PINS(name, args...)		SH_PFC_PINS(name, args)
+#define VIN_PFC_DAT8(name, d0, d1, d2, d3, d4, d5, d6, d7)	\
+	SH_PFC_MUX8(name, d0, d1, d2, d3, d4, d5, d6, d7)
+#define VIN_PFC_CLK(name, clk)			SH_PFC_MUX1(name, clk)
+#define VIN_PFC_SYNC(name, hsync, vsync)	SH_PFC_MUX2(name, hsync, vsync)
+
+/* - VIN0 ------------------------------------------------------------------- */
+VIN_PFC_PINS(vin0_data8,	RCAR_GP_PIN(3, 29),	RCAR_GP_PIN(3, 30),
+				RCAR_GP_PIN(3, 31),	RCAR_GP_PIN(4, 0),
+				RCAR_GP_PIN(4, 1),	RCAR_GP_PIN(4, 2),
+				RCAR_GP_PIN(4, 3),	RCAR_GP_PIN(4, 4));
+VIN_PFC_DAT8(vin0_data8,	VI0_DATA0_VI0_B0,	VI0_DATA1_VI0_B1,
+				VI0_DATA2_VI0_B2,	VI0_DATA3_VI0_B3,
+				VI0_DATA4_VI0_B4,	VI0_DATA5_VI0_B5,
+				VI0_DATA6_VI0_G0,	VI0_DATA7_VI0_G1);
+VIN_PFC_PINS(vin0_clk,		RCAR_GP_PIN(3, 24));
+VIN_PFC_CLK(vin0_clk,		VI0_CLK);
+VIN_PFC_PINS(vin0_sync,		RCAR_GP_PIN(3, 27),	RCAR_GP_PIN(3, 28));
+VIN_PFC_SYNC(vin0_sync,		VI0_HSYNC,		VI0_VSYNC);
+/* - VIN1 ------------------------------------------------------------------- */
+VIN_PFC_PINS(vin1_data8,	RCAR_GP_PIN(3, 25),	RCAR_GP_PIN(3, 26),
+				RCAR_GP_PIN(3, 27),	RCAR_GP_PIN(3, 28),
+				RCAR_GP_PIN(4, 5),	RCAR_GP_PIN(4, 6),
+				RCAR_GP_PIN(4, 7),	RCAR_GP_PIN(4, 8));
+VIN_PFC_DAT8(vin1_data8,	VI1_DATA0,		VI1_DATA1,
+				VI1_DATA2,		VI1_DATA3,
+				VI1_DATA4,		VI1_DATA5,
+				VI1_DATA6,		VI1_DATA7);
+VIN_PFC_PINS(vin1_clk,		RCAR_GP_PIN(4, 9));
+VIN_PFC_CLK(vin1_clk,		VI1_CLK);
+VIN_PFC_PINS(vin1_sync,		RCAR_GP_PIN(3, 21),	RCAR_GP_PIN(3, 22));
+VIN_PFC_SYNC(vin1_sync,		VI1_HSYNC,		VI1_VSYNC);
+
+static const struct sh_pfc_pin_group pinmux_groups[] = {
+	SH_PFC_PIN_GROUP(ether_rmii),
+	SH_PFC_PIN_GROUP(ether_link),
+	SH_PFC_PIN_GROUP(ether_magic),
+	SH_PFC_PIN_GROUP(hscif0_data_a),
+	SH_PFC_PIN_GROUP(hscif0_data_b),
+	SH_PFC_PIN_GROUP(hscif0_ctrl_a),
+	SH_PFC_PIN_GROUP(hscif0_ctrl_b),
+	SH_PFC_PIN_GROUP(hscif0_clk),
+	SH_PFC_PIN_GROUP(hscif1_data_a),
+	SH_PFC_PIN_GROUP(hscif1_data_b),
+	SH_PFC_PIN_GROUP(hscif1_ctrl_a),
+	SH_PFC_PIN_GROUP(hscif1_ctrl_b),
+	SH_PFC_PIN_GROUP(hscif1_clk_a),
+	SH_PFC_PIN_GROUP(hscif1_clk_b),
+	SH_PFC_PIN_GROUP(hspi0_a),
+	SH_PFC_PIN_GROUP(hspi0_b),
+	SH_PFC_PIN_GROUP(hspi1_a),
+	SH_PFC_PIN_GROUP(hspi1_b),
+	SH_PFC_PIN_GROUP(hspi2_a),
+	SH_PFC_PIN_GROUP(hspi2_b),
+	SH_PFC_PIN_GROUP(i2c1_a),
+	SH_PFC_PIN_GROUP(i2c1_b),
+	SH_PFC_PIN_GROUP(i2c2_a),
+	SH_PFC_PIN_GROUP(i2c2_b),
+	SH_PFC_PIN_GROUP(i2c2_c),
+	SH_PFC_PIN_GROUP(i2c3_a),
+	SH_PFC_PIN_GROUP(i2c3_b),
+	SH_PFC_PIN_GROUP(i2c3_c),
+	SH_PFC_PIN_GROUP(mmc_ctrl),
+	SH_PFC_PIN_GROUP(mmc_data1),
+	SH_PFC_PIN_GROUP(mmc_data4),
+	SH_PFC_PIN_GROUP(mmc_data8),
+	SH_PFC_PIN_GROUP(scif_clk),
+	SH_PFC_PIN_GROUP(scif0_data_a),
+	SH_PFC_PIN_GROUP(scif0_data_b),
+	SH_PFC_PIN_GROUP(scif0_data_c),
+	SH_PFC_PIN_GROUP(scif0_data_d),
+	SH_PFC_PIN_GROUP(scif0_ctrl),
+	SH_PFC_PIN_GROUP(scif0_clk),
+	SH_PFC_PIN_GROUP(scif1_data_a),
+	SH_PFC_PIN_GROUP(scif1_data_b),
+	SH_PFC_PIN_GROUP(scif1_data_c),
+	SH_PFC_PIN_GROUP(scif1_data_d),
+	SH_PFC_PIN_GROUP(scif1_ctrl_a),
+	SH_PFC_PIN_GROUP(scif1_ctrl_c),
+	SH_PFC_PIN_GROUP(scif1_clk_a),
+	SH_PFC_PIN_GROUP(scif1_clk_c),
+	SH_PFC_PIN_GROUP(scif2_data_a),
+	SH_PFC_PIN_GROUP(scif2_data_b),
+	SH_PFC_PIN_GROUP(scif2_data_c),
+	SH_PFC_PIN_GROUP(scif2_data_d),
+	SH_PFC_PIN_GROUP(scif2_data_e),
+	SH_PFC_PIN_GROUP(scif2_clk_a),
+	SH_PFC_PIN_GROUP(scif2_clk_b),
+	SH_PFC_PIN_GROUP(scif2_clk_c),
+	SH_PFC_PIN_GROUP(scif3_data_a),
+	SH_PFC_PIN_GROUP(scif3_data_b),
+	SH_PFC_PIN_GROUP(scif3_data_c),
+	SH_PFC_PIN_GROUP(scif3_data_d),
+	SH_PFC_PIN_GROUP(scif4_data_a),
+	SH_PFC_PIN_GROUP(scif4_data_b),
+	SH_PFC_PIN_GROUP(scif4_data_c),
+	SH_PFC_PIN_GROUP(scif5_data_a),
+	SH_PFC_PIN_GROUP(scif5_data_b),
+	SH_PFC_PIN_GROUP(sdhi0_cd),
+	SH_PFC_PIN_GROUP(sdhi0_ctrl),
+	SH_PFC_PIN_GROUP(sdhi0_data1),
+	SH_PFC_PIN_GROUP(sdhi0_data4),
+	SH_PFC_PIN_GROUP(sdhi0_wp),
+	SH_PFC_PIN_GROUP(sdhi1_cd_a),
+	SH_PFC_PIN_GROUP(sdhi1_cd_b),
+	SH_PFC_PIN_GROUP(sdhi1_ctrl_a),
+	SH_PFC_PIN_GROUP(sdhi1_ctrl_b),
+	SH_PFC_PIN_GROUP(sdhi1_data1_a),
+	SH_PFC_PIN_GROUP(sdhi1_data1_b),
+	SH_PFC_PIN_GROUP(sdhi1_data4_a),
+	SH_PFC_PIN_GROUP(sdhi1_data4_b),
+	SH_PFC_PIN_GROUP(sdhi1_wp_a),
+	SH_PFC_PIN_GROUP(sdhi1_wp_b),
+	SH_PFC_PIN_GROUP(sdhi2_cd_a),
+	SH_PFC_PIN_GROUP(sdhi2_cd_b),
+	SH_PFC_PIN_GROUP(sdhi2_ctrl_a),
+	SH_PFC_PIN_GROUP(sdhi2_ctrl_b),
+	SH_PFC_PIN_GROUP(sdhi2_data1_a),
+	SH_PFC_PIN_GROUP(sdhi2_data1_b),
+	SH_PFC_PIN_GROUP(sdhi2_data4_a),
+	SH_PFC_PIN_GROUP(sdhi2_data4_b),
+	SH_PFC_PIN_GROUP(sdhi2_wp_a),
+	SH_PFC_PIN_GROUP(sdhi2_wp_b),
+	SH_PFC_PIN_GROUP(usb0),
+	SH_PFC_PIN_GROUP(usb0_ovc),
+	SH_PFC_PIN_GROUP(usb1),
+	SH_PFC_PIN_GROUP(usb1_ovc),
+	SH_PFC_PIN_GROUP(vin0_data8),
+	SH_PFC_PIN_GROUP(vin0_clk),
+	SH_PFC_PIN_GROUP(vin0_sync),
+	SH_PFC_PIN_GROUP(vin1_data8),
+	SH_PFC_PIN_GROUP(vin1_clk),
+	SH_PFC_PIN_GROUP(vin1_sync),
+};
+
+static const char * const ether_groups[] = {
+	"ether_rmii",
+	"ether_link",
+	"ether_magic",
+};
+
+static const char * const hscif0_groups[] = {
+	"hscif0_data_a",
+	"hscif0_data_b",
+	"hscif0_ctrl_a",
+	"hscif0_ctrl_b",
+	"hscif0_clk",
+};
+
+static const char * const hscif1_groups[] = {
+	"hscif1_data_a",
+	"hscif1_data_b",
+	"hscif1_ctrl_a",
+	"hscif1_ctrl_b",
+	"hscif1_clk_a",
+	"hscif1_clk_b",
+};
+
+static const char * const hspi0_groups[] = {
+	"hspi0_a",
+	"hspi0_b",
+};
+
+static const char * const hspi1_groups[] = {
+	"hspi1_a",
+	"hspi1_b",
+};
+
+static const char * const hspi2_groups[] = {
+	"hspi2_a",
+	"hspi2_b",
+};
+
+static const char * const i2c1_groups[] = {
+	"i2c1_a",
+	"i2c1_b",
+};
+
+static const char * const i2c2_groups[] = {
+	"i2c2_a",
+	"i2c2_b",
+	"i2c2_c",
+};
+
+static const char * const i2c3_groups[] = {
+	"i2c3_a",
+	"i2c3_b",
+	"i2c3_c",
+};
+
+static const char * const mmc_groups[] = {
+	"mmc_ctrl",
+	"mmc_data1",
+	"mmc_data4",
+	"mmc_data8",
+};
+
+static const char * const scif_clk_groups[] = {
+	"scif_clk",
+};
+
+static const char * const scif0_groups[] = {
+	"scif0_data_a",
+	"scif0_data_b",
+	"scif0_data_c",
+	"scif0_data_d",
+	"scif0_ctrl",
+	"scif0_clk",
+};
+
+static const char * const scif1_groups[] = {
+	"scif1_data_a",
+	"scif1_data_b",
+	"scif1_data_c",
+	"scif1_data_d",
+	"scif1_ctrl_a",
+	"scif1_ctrl_c",
+	"scif1_clk_a",
+	"scif1_clk_c",
+};
+
+static const char * const scif2_groups[] = {
+	"scif2_data_a",
+	"scif2_data_b",
+	"scif2_data_c",
+	"scif2_data_d",
+	"scif2_data_e",
+	"scif2_clk_a",
+	"scif2_clk_b",
+	"scif2_clk_c",
+};
+
+static const char * const scif3_groups[] = {
+	"scif3_data_a",
+	"scif3_data_b",
+	"scif3_data_c",
+	"scif3_data_d",
+};
+
+static const char * const scif4_groups[] = {
+	"scif4_data_a",
+	"scif4_data_b",
+	"scif4_data_c",
+};
+
+static const char * const scif5_groups[] = {
+	"scif5_data_a",
+	"scif5_data_b",
+};
+
+
+static const char * const sdhi0_groups[] = {
+	"sdhi0_cd",
+	"sdhi0_ctrl",
+	"sdhi0_data1",
+	"sdhi0_data4",
+	"sdhi0_wp",
+};
+
+static const char * const sdhi1_groups[] = {
+	"sdhi1_cd_a",
+	"sdhi1_cd_b",
+	"sdhi1_ctrl_a",
+	"sdhi1_ctrl_b",
+	"sdhi1_data1_a",
+	"sdhi1_data1_b",
+	"sdhi1_data4_a",
+	"sdhi1_data4_b",
+	"sdhi1_wp_a",
+	"sdhi1_wp_b",
+};
+
+static const char * const sdhi2_groups[] = {
+	"sdhi2_cd_a",
+	"sdhi2_cd_b",
+	"sdhi2_ctrl_a",
+	"sdhi2_ctrl_b",
+	"sdhi2_data1_a",
+	"sdhi2_data1_b",
+	"sdhi2_data4_a",
+	"sdhi2_data4_b",
+	"sdhi2_wp_a",
+	"sdhi2_wp_b",
+};
+
+static const char * const usb0_groups[] = {
+	"usb0",
+	"usb0_ovc",
+};
+
+static const char * const usb1_groups[] = {
+	"usb1",
+	"usb1_ovc",
+};
+
+static const char * const vin0_groups[] = {
+	"vin0_data8",
+	"vin0_clk",
+	"vin0_sync",
+};
+
+static const char * const vin1_groups[] = {
+	"vin1_data8",
+	"vin1_clk",
+	"vin1_sync",
+};
+
+static const struct sh_pfc_function pinmux_functions[] = {
+	SH_PFC_FUNCTION(ether),
+	SH_PFC_FUNCTION(hscif0),
+	SH_PFC_FUNCTION(hscif1),
+	SH_PFC_FUNCTION(hspi0),
+	SH_PFC_FUNCTION(hspi1),
+	SH_PFC_FUNCTION(hspi2),
+	SH_PFC_FUNCTION(i2c1),
+	SH_PFC_FUNCTION(i2c2),
+	SH_PFC_FUNCTION(i2c3),
+	SH_PFC_FUNCTION(mmc),
+	SH_PFC_FUNCTION(scif_clk),
+	SH_PFC_FUNCTION(scif0),
+	SH_PFC_FUNCTION(scif1),
+	SH_PFC_FUNCTION(scif2),
+	SH_PFC_FUNCTION(scif3),
+	SH_PFC_FUNCTION(scif4),
+	SH_PFC_FUNCTION(scif5),
+	SH_PFC_FUNCTION(sdhi0),
+	SH_PFC_FUNCTION(sdhi1),
+	SH_PFC_FUNCTION(sdhi2),
+	SH_PFC_FUNCTION(usb0),
+	SH_PFC_FUNCTION(usb1),
+	SH_PFC_FUNCTION(vin0),
+	SH_PFC_FUNCTION(vin1),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	{ PINMUX_CFG_REG("GPSR0", 0xfffc0004, 32, 1) {
+		GP_0_31_FN,	FN_IP1_14_11,
+		GP_0_30_FN,	FN_IP1_10_8,
+		GP_0_29_FN,	FN_IP1_7_5,
+		GP_0_28_FN,	FN_IP1_4_2,
+		GP_0_27_FN,	FN_IP1_1,
+		GP_0_26_FN,	FN_IP1_0,
+		GP_0_25_FN,	FN_IP0_30,
+		GP_0_24_FN,	FN_IP0_29,
+		GP_0_23_FN,	FN_IP0_28,
+		GP_0_22_FN,	FN_IP0_27,
+		GP_0_21_FN,	FN_IP0_26,
+		GP_0_20_FN,	FN_IP0_25,
+		GP_0_19_FN,	FN_IP0_24,
+		GP_0_18_FN,	FN_IP0_23,
+		GP_0_17_FN,	FN_IP0_22,
+		GP_0_16_FN,	FN_IP0_21,
+		GP_0_15_FN,	FN_IP0_20,
+		GP_0_14_FN,	FN_IP0_19,
+		GP_0_13_FN,	FN_IP0_18,
+		GP_0_12_FN,	FN_IP0_17,
+		GP_0_11_FN,	FN_IP0_16,
+		GP_0_10_FN,	FN_IP0_15,
+		GP_0_9_FN,	FN_A3,
+		GP_0_8_FN,	FN_A2,
+		GP_0_7_FN,	FN_A1,
+		GP_0_6_FN,	FN_IP0_14_12,
+		GP_0_5_FN,	FN_IP0_11_8,
+		GP_0_4_FN,	FN_IP0_7_5,
+		GP_0_3_FN,	FN_IP0_4_2,
+		GP_0_2_FN,	FN_PENC1,
+		GP_0_1_FN,	FN_PENC0,
+		GP_0_0_FN,	FN_IP0_1_0 }
+	},
+	{ PINMUX_CFG_REG("GPSR1", 0xfffc0008, 32, 1) {
+		GP_1_31_FN,	FN_IP4_6_4,
+		GP_1_30_FN,	FN_IP4_3_1,
+		GP_1_29_FN,	FN_IP4_0,
+		GP_1_28_FN,	FN_IP3_31,
+		GP_1_27_FN,	FN_IP3_30,
+		GP_1_26_FN,	FN_IP3_29,
+		GP_1_25_FN,	FN_IP3_28,
+		GP_1_24_FN,	FN_IP3_27,
+		GP_1_23_FN,	FN_IP3_26_24,
+		GP_1_22_FN,	FN_IP3_23_21,
+		GP_1_21_FN,	FN_IP3_20_19,
+		GP_1_20_FN,	FN_IP3_18_16,
+		GP_1_19_FN,	FN_IP3_15_13,
+		GP_1_18_FN,	FN_IP3_12_10,
+		GP_1_17_FN,	FN_IP3_9_8,
+		GP_1_16_FN,	FN_IP3_7_5,
+		GP_1_15_FN,	FN_IP3_4_2,
+		GP_1_14_FN,	FN_IP3_1_0,
+		GP_1_13_FN,	FN_IP2_31,
+		GP_1_12_FN,	FN_IP2_30,
+		GP_1_11_FN,	FN_IP2_17,
+		GP_1_10_FN,	FN_IP2_16_14,
+		GP_1_9_FN,	FN_IP2_13_12,
+		GP_1_8_FN,	FN_IP2_11_9,
+		GP_1_7_FN,	FN_IP2_8_6,
+		GP_1_6_FN,	FN_IP2_5_3,
+		GP_1_5_FN,	FN_IP2_2_0,
+		GP_1_4_FN,	FN_IP1_29_28,
+		GP_1_3_FN,	FN_IP1_27_25,
+		GP_1_2_FN,	FN_IP1_24,
+		GP_1_1_FN,	FN_WE0,
+		GP_1_0_FN,	FN_IP1_23_21 }
+	},
+	{ PINMUX_CFG_REG("GPSR2", 0xfffc000c, 32, 1) {
+		GP_2_31_FN,	FN_IP6_7,
+		GP_2_30_FN,	FN_IP6_6_5,
+		GP_2_29_FN,	FN_IP6_4_2,
+		GP_2_28_FN,	FN_IP6_1_0,
+		GP_2_27_FN,	FN_IP5_30_29,
+		GP_2_26_FN,	FN_IP5_28_26,
+		GP_2_25_FN,	FN_IP5_25_23,
+		GP_2_24_FN,	FN_IP5_22_21,
+		GP_2_23_FN,	FN_AUDIO_CLKB,
+		GP_2_22_FN,	FN_AUDIO_CLKA,
+		GP_2_21_FN,	FN_IP5_20_18,
+		GP_2_20_FN,	FN_IP5_17_15,
+		GP_2_19_FN,	FN_IP5_14_13,
+		GP_2_18_FN,	FN_IP5_12,
+		GP_2_17_FN,	FN_IP5_11_10,
+		GP_2_16_FN,	FN_IP5_9_8,
+		GP_2_15_FN,	FN_IP5_7,
+		GP_2_14_FN,	FN_IP5_6,
+		GP_2_13_FN,	FN_IP5_5_4,
+		GP_2_12_FN,	FN_IP5_3_2,
+		GP_2_11_FN,	FN_IP5_1_0,
+		GP_2_10_FN,	FN_IP4_30_29,
+		GP_2_9_FN,	FN_IP4_28_27,
+		GP_2_8_FN,	FN_IP4_26_25,
+		GP_2_7_FN,	FN_IP4_24_21,
+		GP_2_6_FN,	FN_IP4_20_17,
+		GP_2_5_FN,	FN_IP4_16_15,
+		GP_2_4_FN,	FN_IP4_14_13,
+		GP_2_3_FN,	FN_IP4_12_11,
+		GP_2_2_FN,	FN_IP4_10_9,
+		GP_2_1_FN,	FN_IP4_8,
+		GP_2_0_FN,	FN_IP4_7 }
+	},
+	{ PINMUX_CFG_REG("GPSR3", 0xfffc0010, 32, 1) {
+		GP_3_31_FN,	FN_IP8_10_9,
+		GP_3_30_FN,	FN_IP8_8_6,
+		GP_3_29_FN,	FN_IP8_5_3,
+		GP_3_28_FN,	FN_IP8_2_0,
+		GP_3_27_FN,	FN_IP7_31_29,
+		GP_3_26_FN,	FN_IP7_28_25,
+		GP_3_25_FN,	FN_IP7_24_22,
+		GP_3_24_FN,	FN_IP7_21,
+		GP_3_23_FN,	FN_IP7_20_18,
+		GP_3_22_FN,	FN_IP7_17_15,
+		GP_3_21_FN,	FN_IP7_14_12,
+		GP_3_20_FN,	FN_IP7_11_9,
+		GP_3_19_FN,	FN_IP7_8_6,
+		GP_3_18_FN,	FN_IP7_5_4,
+		GP_3_17_FN,	FN_IP7_3_2,
+		GP_3_16_FN,	FN_IP7_1_0,
+		GP_3_15_FN,	FN_IP6_31_30,
+		GP_3_14_FN,	FN_IP6_29_28,
+		GP_3_13_FN,	FN_IP6_27_26,
+		GP_3_12_FN,	FN_IP6_25_24,
+		GP_3_11_FN,	FN_IP6_23_22,
+		GP_3_10_FN,	FN_IP6_21,
+		GP_3_9_FN,	FN_IP6_20_19,
+		GP_3_8_FN,	FN_IP6_18_17,
+		GP_3_7_FN,	FN_IP6_16,
+		GP_3_6_FN,	FN_IP6_15_14,
+		GP_3_5_FN,	FN_IP6_13,
+		GP_3_4_FN,	FN_IP6_12_11,
+		GP_3_3_FN,	FN_IP6_10,
+		GP_3_2_FN,	FN_SSI_SCK34,
+		GP_3_1_FN,	FN_IP6_9,
+		GP_3_0_FN,	FN_IP6_8 }
+	},
+	{ PINMUX_CFG_REG("GPSR4", 0xfffc0014, 32, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_4_26_FN,	FN_AVS2,
+		GP_4_25_FN,	FN_AVS1,
+		GP_4_24_FN,	FN_IP10_24_22,
+		GP_4_23_FN,	FN_IP10_21_19,
+		GP_4_22_FN,	FN_IP10_18_16,
+		GP_4_21_FN,	FN_IP10_15_13,
+		GP_4_20_FN,	FN_IP10_12_9,
+		GP_4_19_FN,	FN_IP10_8_6,
+		GP_4_18_FN,	FN_IP10_5_3,
+		GP_4_17_FN,	FN_IP10_2_0,
+		GP_4_16_FN,	FN_IP9_29_27,
+		GP_4_15_FN,	FN_IP9_26_24,
+		GP_4_14_FN,	FN_IP9_23_21,
+		GP_4_13_FN,	FN_IP9_20_18,
+		GP_4_12_FN,	FN_IP9_17_15,
+		GP_4_11_FN,	FN_IP9_14_12,
+		GP_4_10_FN,	FN_IP9_11_9,
+		GP_4_9_FN,	FN_IP9_8_6,
+		GP_4_8_FN,	FN_IP9_5_3,
+		GP_4_7_FN,	FN_IP9_2_0,
+		GP_4_6_FN,	FN_IP8_29_27,
+		GP_4_5_FN,	FN_IP8_26_24,
+		GP_4_4_FN,	FN_IP8_23_22,
+		GP_4_3_FN,	FN_IP8_21_19,
+		GP_4_2_FN,	FN_IP8_18_16,
+		GP_4_1_FN,	FN_IP8_15_14,
+		GP_4_0_FN,	FN_IP8_13_11 }
+	},
+
+	{ PINMUX_CFG_REG_VAR("IPSR0", 0xfffc0020, 32,
+			     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+			     1, 1, 1, 1, 1, 1, 3, 4, 3, 3, 2) {
+		/* IP0_31 [1] */
+		0,	0,
+		/* IP0_30 [1] */
+		FN_A19,	0,
+		/* IP0_29 [1] */
+		FN_A18,	0,
+		/* IP0_28 [1] */
+		FN_A17,	0,
+		/* IP0_27 [1] */
+		FN_A16,	0,
+		/* IP0_26 [1] */
+		FN_A15,	0,
+		/* IP0_25 [1] */
+		FN_A14,	0,
+		/* IP0_24 [1] */
+		FN_A13,	0,
+		/* IP0_23 [1] */
+		FN_A12,	0,
+		/* IP0_22 [1] */
+		FN_A11,	0,
+		/* IP0_21 [1] */
+		FN_A10,	0,
+		/* IP0_20 [1] */
+		FN_A9,	0,
+		/* IP0_19 [1] */
+		FN_A8,	0,
+		/* IP0_18 [1] */
+		FN_A7,	0,
+		/* IP0_17 [1] */
+		FN_A6,	0,
+		/* IP0_16 [1] */
+		FN_A5,	0,
+		/* IP0_15 [1] */
+		FN_A4,	0,
+		/* IP0_14_12 [3] */
+		FN_SD1_DAT3_A,	FN_MMC_D3,	0,		FN_A0,
+		FN_ATAG0_A,	0,		FN_REMOCON_B,	0,
+		/* IP0_11_8 [4] */
+		FN_SD1_DAT2_A,	FN_MMC_D2,	0,		FN_BS,
+		FN_ATADIR0_A,	0,		FN_SDSELF_B,	0,
+		FN_PWM4_B,	0,		0,		0,
+		0,		0,		0,		0,
+		/* IP0_7_5 [3] */
+		FN_AUDATA1,	FN_ARM_TRACEDATA_1,	FN_GPSIN_C,	FN_USB_OVC1,
+		FN_RX2_E,	FN_SCL2_B,		0,		0,
+		/* IP0_4_2 [3] */
+		FN_AUDATA0,	FN_ARM_TRACEDATA_0,	FN_GPSCLK_C,	FN_USB_OVC0,
+		FN_TX2_E,	FN_SDA2_B,		0,		0,
+		/* IP0_1_0 [2] */
+		FN_PRESETOUT,	0,	FN_PWM1,	0,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR1", 0xfffc0024, 32,
+			     1, 1, 2, 3, 1, 3, 3, 1, 2, 4, 3, 3, 3, 1, 1) {
+		/* IP1_31 [1] */
+		0,	0,
+		/* IP1_30 [1] */
+		0,	0,
+		/* IP1_29_28 [2] */
+		FN_EX_CS1,	FN_MMC_D4,	0,	0,
+		/* IP1_27_25 [3] */
+		FN_SSI_WS1_B,	FN_EX_CS0,	FN_SCL2_A,	FN_TX3_C,
+		FN_TS_SCK0_A,	0,		0,		0,
+		/* IP1_24 [1] */
+		FN_WE1,		FN_ATAWR0_B,
+		/* IP1_23_21 [3] */
+		FN_MMC_D5,	FN_ATADIR0_B,	0,		FN_RD_WR,
+		0,		0,		0,		0,
+		/* IP1_20_18 [3] */
+		FN_SSI_SCK1_B,	FN_ATAG0_B,	FN_CS1_A26,	FN_SDA2_A,
+		FN_SCK2_B,	0,		0,		0,
+		/* IP1_17 [1] */
+		FN_CS0,		FN_HSPI_RX1_B,
+		/* IP1_16_15 [2] */
+		FN_CLKOUT,	FN_HSPI_TX1_B,	FN_PWM0_B,	0,
+		/* IP1_14_11 [4] */
+		FN_SD1_WP_A,	FN_MMC_D7,	0,		FN_A25,
+		FN_DACK1_A,	0,		FN_HCTS0_B,	FN_RX3_C,
+		FN_TS_SDAT0_A,	0,		0,		0,
+		0,		0,		0,		0,
+		/* IP1_10_8 [3] */
+		FN_SD1_CLK_B,	FN_MMC_D6,	0,		FN_A24,
+		FN_DREQ1_A,	0,		FN_HRX0_B,	FN_TS_SPSYNC0_A,
+		/* IP1_7_5 [3] */
+		FN_A23,		FN_HTX0_B,	FN_TX2_B,	FN_DACK2_A,
+		FN_TS_SDEN0_A,	0,		0,		0,
+		/* IP1_4_2 [3] */
+		FN_A22,		FN_HRTS0_B,	FN_RX2_B,	FN_DREQ2_A,
+		0,		0,		0,		0,
+		/* IP1_1 [1] */
+		FN_A21,		FN_HSPI_CLK1_B,
+		/* IP1_0 [1] */
+		FN_A20,		FN_HSPI_CS1_B,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR2", 0xfffc0028, 32,
+			     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+			     1, 1, 1, 1, 3, 2, 3, 3, 3, 3) {
+		/* IP2_31 [1] */
+		FN_MLB_CLK,	FN_IRQ1_A,
+		/* IP2_30 [1] */
+		FN_RD_WR_B,	FN_IRQ0,
+		/* IP2_29 [1] */
+		FN_D11,		0,
+		/* IP2_28 [1] */
+		FN_D10,		0,
+		/* IP2_27 [1] */
+		FN_D9,		0,
+		/* IP2_26 [1] */
+		FN_D8,		0,
+		/* IP2_25 [1] */
+		FN_D7,		0,
+		/* IP2_24 [1] */
+		FN_D6,		0,
+		/* IP2_23 [1] */
+		FN_D5,		0,
+		/* IP2_22 [1] */
+		FN_D4,		0,
+		/* IP2_21 [1] */
+		FN_D3,		0,
+		/* IP2_20 [1] */
+		FN_D2,		0,
+		/* IP2_19 [1] */
+		FN_D1,		0,
+		/* IP2_18 [1] */
+		FN_D0,		0,
+		/* IP2_17 [1] */
+		FN_EX_WAIT0,	FN_PWM0_C,
+		/* IP2_16_14 [3] */
+		FN_DACK0,	0,	0,	FN_TX3_A,
+		FN_DRACK0,	0,	0,	0,
+		/* IP2_13_12 [2] */
+		FN_DREQ0_A,	0,	0,	FN_RX3_A,
+		/* IP2_11_9 [3] */
+		FN_SD1_DAT1_A,	FN_MMC_D1,	0,	FN_ATAWR0_A,
+		FN_EX_CS5,	FN_EX_WAIT2_A,	0,	0,
+		/* IP2_8_6 [3] */
+		FN_SD1_DAT0_A,	FN_MMC_D0,	0,	FN_ATARD0,
+		FN_EX_CS4,	FN_EX_WAIT1_A,	0,	0,
+		/* IP2_5_3 [3] */
+		FN_SD1_CMD_A,	FN_MMC_CMD,	0,	FN_ATACS10,
+		FN_EX_CS3,	0,		0,	0,
+		/* IP2_2_0 [3] */
+		FN_SD1_CLK_A,	FN_MMC_CLK,	0,	FN_ATACS00,
+		FN_EX_CS2,	0,		0,	0,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR3", 0xfffc002c, 32,
+			     1, 1, 1, 1, 1, 3, 3, 2,
+			     3, 3, 3, 2, 3, 3, 2) {
+		/* IP3_31 [1] */
+		FN_DU0_DR6,	FN_LCDOUT6,
+		/* IP3_30 [1] */
+		FN_DU0_DR5,	FN_LCDOUT5,
+		/* IP3_29 [1] */
+		FN_DU0_DR4,	FN_LCDOUT4,
+		/* IP3_28 [1] */
+		FN_DU0_DR3,	FN_LCDOUT3,
+		/* IP3_27 [1] */
+		FN_DU0_DR2,	FN_LCDOUT2,
+		/* IP3_26_24 [3] */
+		FN_SSI_WS4,		FN_DU0_DR1,	FN_LCDOUT1,	FN_AUDATA3,
+		FN_ARM_TRACEDATA_3,	FN_SCL3_C,	FN_ADICHS2,	FN_TS_SPSYNC0_B,
+		/* IP3_23_21 [3] */
+		FN_SSI_SCK4,		FN_DU0_DR0,	FN_LCDOUT0,	FN_AUDATA2,
+		FN_ARM_TRACEDATA_2,	FN_SDA3_C,	FN_ADICHS1,	FN_TS_SDEN0_B,
+		/* IP3_20_19 [2] */
+		FN_SD1_DAT3_B,	FN_HRTS0_A,	FN_RTS0,	0,
+		/* IP3_18_16 [3] */
+		FN_SD1_DAT2_B,	FN_HCTS0_A,	FN_CTS0,	0,
+		0,		0,		0,		0,
+		/* IP3_15_13 [3] */
+		FN_SD1_DAT1_B,	FN_HSCK0,	FN_SCK0,	FN_SCL3_B,
+		0,		0,		0,		0,
+		/* IP3_12_10 [3] */
+		FN_SD1_DAT0_B,	FN_HRX0_A,	FN_RX0_A,	0,
+		0,		0,		0,		0,
+		/* IP3_9_8 [2] */
+		FN_SD1_CLK_B,	FN_HTX0_A,	FN_TX0_A,	0,
+		/* IP3_7_5 [3] */
+		FN_SD1_CMD_B,	FN_SCIF_CLK,	FN_AUDIO_CLKOUT_B,	FN_CAN_CLK_B,
+		FN_SDA3_B,	0,		0,			0,
+		/* IP3_4_2 [3] */
+		FN_MLB_DAT,	FN_TX5_B,	FN_SCL3_A,	FN_IRQ3_A,
+		FN_SDSELF_B,	0,		0,		0,
+		/* IP3_1_0 [2] */
+		FN_MLB_SIG,	FN_RX5_B,	FN_SDA3_A,	FN_IRQ2_A,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR4", 0xfffc0030, 32,
+			     1, 2, 2, 2, 4, 4, 2, 2, 2, 2, 1, 1, 3, 3, 1) {
+		/* IP4_31 [1] */
+		0,	0,
+		/* IP4_30_29 [2] */
+		FN_VI0_R4_B,	FN_DU0_DB4,	FN_LCDOUT20,	0,
+		/* IP4_28_27 [2] */
+		FN_VI0_R3_B,	FN_DU0_DB3,	FN_LCDOUT19,	0,
+		/* IP4_26_25 [2] */
+		FN_VI0_R2_B,	FN_DU0_DB2,	FN_LCDOUT18,	0,
+		/* IP4_24_21 [4] */
+		FN_AUDIO_CLKC,	FN_VI0_R1_B,		FN_DU0_DB1,	FN_LCDOUT17,
+		FN_AUDATA7,	FN_ARM_TRACEDATA_7,	FN_GPSIN_A,	0,
+		FN_ADICS_SAMP,	FN_TS_SCK0_B,		0,		0,
+		0,		0,			0,		0,
+		/* IP4_20_17 [4] */
+		FN_SSI_SCK2_B,	FN_VI0_R0_B,		FN_DU0_DB0,	FN_LCDOUT16,
+		FN_AUDATA6,	FN_ARM_TRACEDATA_6,	FN_GPSCLK_A,	FN_PWM0_A,
+		FN_ADICLK,	FN_TS_SDAT0_B,		0,		0,
+		0,		0,			0,		0,
+		/* IP4_16_15 [2] */
+		FN_DU0_DG7,	FN_LCDOUT15,	FN_TX4_A,	0,
+		/* IP4_14_13 [2] */
+		FN_DU0_DG6,	FN_LCDOUT14,	FN_RX4_A,	0,
+		/* IP4_12_11 [2] */
+		FN_DU0_DG5,	FN_LCDOUT13,	FN_TX0_B,	0,
+		/* IP4_10_9 [2] */
+		FN_DU0_DG4,	FN_LCDOUT12,	FN_RX0_B,	0,
+		/* IP4_8 [1] */
+		FN_DU0_DG3,	FN_LCDOUT11,
+		/* IP4_7 [1] */
+		FN_DU0_DG2,	FN_LCDOUT10,
+		/* IP4_6_4 [3] */
+		FN_DU0_DG1,	FN_LCDOUT9,	FN_AUDATA5,	FN_ARM_TRACEDATA_5,
+		FN_RX1_D,	FN_CAN0_RX_A,	FN_ADIDATA,	0,
+		/* IP4_3_1 [3] */
+		FN_DU0_DG0,	FN_LCDOUT8,	FN_AUDATA4,	FN_ARM_TRACEDATA_4,
+		FN_TX1_D,	FN_CAN0_TX_A,	FN_ADICHS0,	0,
+		/* IP4_0 [1] */
+		FN_DU0_DR7,	FN_LCDOUT7,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR5", 0xfffc0034, 32,
+			     1, 2, 3, 3, 2, 3, 3, 2, 1, 2, 2, 1, 1, 2, 2, 2) {
+
+		/* IP5_31 [1] */
+		0, 0,
+		/* IP5_30_29 [2] */
+		FN_SSI_SDATA7,	FN_HSPI_TX0_B,	FN_RX2_A,	FN_CAN0_RX_B,
+		/* IP5_28_26 [3] */
+		FN_SSI_SDATA8,	FN_SSI_SCK2_A,	FN_HSPI_CS0_B,	FN_TX2_A,
+		FN_CAN0_TX_B,	0,		0,		0,
+		/* IP5_25_23 [3] */
+		FN_SD1_WP_B,	FN_SSI_WS78,	FN_HSPI_CLK0_B,	FN_RX1_B,
+		FN_CAN_CLK_D,	0,		0,		0,
+		/* IP5_22_21 [2] */
+		FN_SD1_CD_B,	FN_SSI_SCK78,	FN_HSPI_RX0_B,	FN_TX1_B,
+		/* IP5_20_18 [3] */
+		FN_SSI_WS1_A,		FN_DU0_CDE,	FN_QPOLB,	FN_AUDSYNC,
+		FN_ARM_TRACECTL,	FN_FMIN_D,	0,		0,
+		/* IP5_17_15 [3] */
+		FN_SSI_SCK1_A,		FN_DU0_DISP,	FN_QPOLA,	FN_AUDCK,
+		FN_ARM_TRACECLK,	FN_BPFCLK_D,	0,		0,
+		/* IP5_14_13 [2] */
+		FN_DU0_EXODDF_DU0_ODDF_DISP_CDE,	FN_QCPV_QDE,
+		FN_FMCLK_D,				0,
+		/* IP5_12 [1] */
+		FN_DU0_EXVSYNC_DU0_VSYNC,	FN_QSTB_QHE,
+		/* IP5_11_10 [2] */
+		FN_SSI_WS2_B,	FN_DU0_EXHSYNC_DU0_HSYNC,
+		FN_QSTH_QHS,	0,
+		/* IP5_9_8 [2] */
+		FN_DU0_DOTCLKO_UT1,	FN_QSTVB_QVE,
+		FN_AUDIO_CLKOUT_A,	FN_REMOCON_C,
+		/* IP5_7 [1] */
+		FN_DU0_DOTCLKO_UT0,	FN_QCLK,
+		/* IP5_6 [1] */
+		FN_DU0_DOTCLKIN,	FN_QSTVA_QVS,
+		/* IP5_5_4 [2] */
+		FN_VI1_DATA11_B,	FN_DU0_DB7,	FN_LCDOUT23,	0,
+		/* IP5_3_2 [2] */
+		FN_VI1_DATA10_B,	FN_DU0_DB6,	FN_LCDOUT22,	0,
+		/* IP5_1_0 [2] */
+		FN_VI0_R5_B,		FN_DU0_DB5,	FN_LCDOUT21,	0,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR6", 0xfffc0038, 32,
+			     2, 2, 2, 2, 2, 1, 2, 2, 1, 2,
+			     1, 2, 1, 1, 1, 1, 2, 3, 2) {
+		/* IP6_31_30 [2] */
+		FN_SD0_DAT2,	0,	FN_SUB_TDI,	0,
+		/* IP6_29_28 [2] */
+		FN_SD0_DAT1,	0,	FN_SUB_TCK,	0,
+		/* IP6_27_26 [2] */
+		FN_SD0_DAT0,	0,	FN_SUB_TMS,	0,
+		/* IP6_25_24 [2] */
+		FN_SD0_CMD,	0,	FN_SUB_TRST,	0,
+		/* IP6_23_22 [2] */
+		FN_SD0_CLK,	0,	FN_SUB_TDO,	0,
+		/* IP6_21 [1] */
+		FN_SSI_SDATA0,		FN_ARM_TRACEDATA_15,
+		/* IP6_20_19 [2] */
+		FN_SSI_SDATA1,		FN_ARM_TRACEDATA_14,
+		FN_SCL1_A,		FN_SCK2_A,
+		/* IP6_18_17 [2] */
+		FN_SSI_SDATA2,		FN_HSPI_CS2_A,
+		FN_ARM_TRACEDATA_13,	FN_SDA1_A,
+		/* IP6_16 [1] */
+		FN_SSI_WS012,		FN_ARM_TRACEDATA_12,
+		/* IP6_15_14 [2] */
+		FN_SSI_SCK012,		FN_ARM_TRACEDATA_11,
+		FN_TX0_D,		0,
+		/* IP6_13 [1] */
+		FN_SSI_SDATA3,		FN_ARM_TRACEDATA_10,
+		/* IP6_12_11 [2] */
+		FN_SSI_SDATA4,		FN_SSI_WS2_A,
+		FN_ARM_TRACEDATA_9,	0,
+		/* IP6_10 [1] */
+		FN_SSI_WS34,		FN_ARM_TRACEDATA_8,
+		/* IP6_9 [1] */
+		FN_SSI_SDATA5,		FN_RX0_D,
+		/* IP6_8 [1] */
+		FN_SSI_WS5,		FN_TX4_C,
+		/* IP6_7 [1] */
+		FN_SSI_SCK5,		FN_RX4_C,
+		/* IP6_6_5 [2] */
+		FN_SSI_SDATA6,		FN_HSPI_TX2_A,
+		FN_FMIN_B,		0,
+		/* IP6_4_2 [3] */
+		FN_SSI_WS6,		FN_HSPI_CLK2_A,
+		FN_BPFCLK_B,		FN_CAN1_RX_B,
+		0,	0,	0,	0,
+		/* IP6_1_0 [2] */
+		FN_SSI_SCK6,		FN_HSPI_RX2_A,
+		FN_FMCLK_B,		FN_CAN1_TX_B,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR7", 0xfffc003c, 32,
+			     3, 4, 3, 1, 3, 3, 3, 3, 3, 2, 2, 2) {
+
+		/* IP7_31_29 [3] */
+		FN_VI0_HSYNC,	FN_SD2_CD_B,	FN_VI1_DATA2,	FN_DU1_DR2,
+		0,		FN_HSPI_CS1_A,	FN_RX3_B,	0,
+		/* IP7_28_25 [4] */
+		FN_VI0_FIELD,	FN_SD2_DAT3_B,	FN_VI0_R3_C,	FN_VI1_DATA1,
+		FN_DU1_DG7,	0,		FN_HSPI_CLK1_A,	FN_TX4_B,
+		0,	0,	0,	0,
+		0,	0,	0,	0,
+		/* IP7_24_22 [3] */
+		FN_VI0_CLKENB,	FN_SD2_DAT2_B,	FN_VI1_DATA0,	FN_DU1_DG6,
+		0,		FN_HSPI_RX1_A,	FN_RX4_B,	0,
+		/* IP7_21 [1] */
+		FN_VI0_CLK,	FN_CAN_CLK_A,
+		/* IP7_20_18 [3] */
+		FN_TCLK0,	FN_HSCK1_A,	FN_FMIN_A,	0,
+		FN_IRQ2_C,	FN_CTS1_C,	FN_SPEEDIN,	0,
+		/* IP7_17_15 [3] */
+		FN_VI1_VSYNC,	FN_HSPI_TX0,	FN_HCTS1_A,	FN_BPFCLK_A,
+		0,		FN_TX1_C,	0,		0,
+		/* IP7_14_12 [3] */
+		FN_VI1_HSYNC,	FN_HSPI_RX0_A,	FN_HRTS1_A,	FN_FMCLK_A,
+		0,		FN_RX1_C,	0,		0,
+		/* IP7_11_9 [3] */
+		FN_VI1_FIELD,	FN_HSPI_CS0_A,	FN_HRX1_A,	0,
+		FN_SCK1_C,	0,		0,		0,
+		/* IP7_8_6 [3] */
+		FN_VI1_CLKENB,	FN_HSPI_CLK0_A,	FN_HTX1_A,	0,
+		FN_RTS1_C,	0,		0,		0,
+		/* IP7_5_4 [2] */
+		FN_SD0_WP,	0,		FN_RX5_A,	0,
+		/* IP7_3_2 [2] */
+		FN_SD0_CD,	0,		FN_TX5_A,	0,
+		/* IP7_1_0 [2] */
+		FN_SD0_DAT3,	0,		FN_IRQ1_B,	0,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR8", 0xfffc0040, 32,
+			     1, 1, 3, 3, 2, 3, 3, 2, 3, 2, 3, 3, 3) {
+		/* IP8_31 [1] */
+		0, 0,
+		/* IP8_30 [1] */
+		0, 0,
+		/* IP8_29_27 [3] */
+		FN_VI0_G3,	FN_SD2_CMD_B,	FN_VI1_DATA5,	FN_DU1_DR5,
+		0,		FN_HRX1_B,	0,		0,
+		/* IP8_26_24 [3] */
+		FN_VI0_G2,	FN_SD2_CLK_B,	FN_VI1_DATA4,	FN_DU1_DR4,
+		0,		FN_HTX1_B,	0,		0,
+		/* IP8_23_22 [2] */
+		FN_VI0_DATA7_VI0_G1,	FN_DU1_DB5,
+		FN_RTS1_A,		0,
+		/* IP8_21_19 [3] */
+		FN_VI0_DATA6_VI0_G0,	FN_DU1_DB4,
+		FN_CTS1_A,		FN_PWM5,
+		0,	0,	0,	0,
+		/* IP8_18_16 [3] */
+		FN_VI0_DATA5_VI0_B5,	FN_DU1_DB3,	FN_SCK1_A,	FN_PWM4,
+		0,			FN_HSCK1_B,	0,		0,
+		/* IP8_15_14 [2] */
+		FN_VI0_DATA4_VI0_B4,	FN_DU1_DB2,	FN_RX1_A,	0,
+		/* IP8_13_11 [3] */
+		FN_VI0_DATA3_VI0_B3,	FN_DU1_DG5,	FN_TX1_A,	FN_TX0_C,
+		0,			 0,		0,		0,
+		/* IP8_10_9 [2] */
+		FN_VI0_DATA2_VI0_B2,	FN_DU1_DG4,	FN_RX0_C,	0,
+		/* IP8_8_6 [3] */
+		FN_VI0_DATA1_VI0_B1,	FN_DU1_DG3,	FN_IRQ3_B,	FN_TX3_D,
+		0,			 0,		0,		0,
+		/* IP8_5_3 [3] */
+		FN_VI0_DATA0_VI0_B0,	FN_DU1_DG2,	FN_IRQ2_B,	FN_RX3_D,
+		0,			 0,		0,		0,
+		/* IP8_2_0 [3] */
+		FN_VI0_VSYNC,		FN_SD2_WP_B,	FN_VI1_DATA3,	FN_DU1_DR3,
+		0,			FN_HSPI_TX1_A,	FN_TX3_B,	0,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR9", 0xfffc0044, 32,
+			     1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3) {
+		/* IP9_31 [1] */
+		0, 0,
+		/* IP9_30 [1] */
+		0, 0,
+		/* IP9_29_27 [3] */
+		FN_VI1_DATA11_A,	FN_DU1_EXHSYNC_DU1_HSYNC,
+		FN_ETH_RXD1,		FN_FMIN_C,
+		0,			FN_RX2_D,
+		FN_SCL2_C,		0,
+		/* IP9_26_24 [3] */
+		FN_VI1_DATA10_A,	FN_DU1_DOTCLKOUT,
+		FN_ETH_RXD0,		FN_BPFCLK_C,
+		0,			FN_TX2_D,
+		FN_SDA2_C,		0,
+		/* IP9_23_21 [3] */
+		FN_VI0_R5_A,	0,		FN_ETH_RX_ER,	FN_FMCLK_C,
+		FN_IERX,	FN_RX2_C,	0,		0,
+		/* IP9_20_18 [3] */
+		FN_VI0_R4_A,	FN_ETH_TX_EN,	0,		0,
+		FN_IETX,	FN_TX2_C,	0,		0,
+		/* IP9_17_15 [3] */
+		FN_VI0_R3_A,	FN_ETH_CRS_DV,	0,		FN_IECLK,
+		FN_SCK2_C,	0,		0,		0,
+		/* IP9_14_12 [3] */
+		FN_VI0_R2_A,	FN_VI1_DATA9,	FN_DU1_DB7,	FN_ETH_TXD1,
+		0,		FN_PWM3,	0,		0,
+		/* IP9_11_9 [3] */
+		FN_VI0_R1_A,	FN_VI1_DATA8,	FN_DU1_DB6,	FN_ETH_TXD0,
+		0,		FN_PWM2,	FN_TCLK1,	0,
+		/* IP9_8_6 [3] */
+		FN_VI0_R0_A,	FN_VI1_CLK,	FN_ETH_REF_CLK,	FN_DU1_DOTCLKIN,
+		0,		0,		0,		0,
+		/* IP9_5_3 [3] */
+		FN_VI0_G5,	FN_SD2_DAT1_B,	FN_VI1_DATA7,	FN_DU1_DR7,
+		0,		FN_HCTS1_B,	0,		0,
+		/* IP9_2_0 [3] */
+		FN_VI0_G4,	FN_SD2_DAT0_B,	FN_VI1_DATA6,	FN_DU1_DR6,
+		0,		FN_HRTS1_B,	0,		0,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR10", 0xfffc0048, 32,
+			     1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 4, 3, 3, 3) {
+
+		/* IP10_31 [1] */
+		0, 0,
+		/* IP10_30 [1] */
+		0, 0,
+		/* IP10_29 [1] */
+		0, 0,
+		/* IP10_28 [1] */
+		0, 0,
+		/* IP10_27 [1] */
+		0, 0,
+		/* IP10_26 [1] */
+		0, 0,
+		/* IP10_25 [1] */
+		0, 0,
+		/* IP10_24_22 [3] */
+		FN_SD2_WP_A,	FN_VI1_DATA15,	FN_EX_WAIT2_B,	FN_DACK0_B,
+		FN_HSPI_TX2_B,	FN_CAN_CLK_C,	0,		0,
+		/* IP10_21_19 [3] */
+		FN_SD2_CD_A,	FN_VI1_DATA14,	FN_EX_WAIT1_B,	FN_DREQ0_B,
+		FN_HSPI_RX2_B,	FN_REMOCON_A,	0,		0,
+		/* IP10_18_16 [3] */
+		FN_SD2_DAT3_A,	FN_VI1_DATA13,	FN_DACK2_B,	FN_ATAG1,
+		FN_HSPI_CS2_B,	FN_GPSIN_B,	0,		0,
+		/* IP10_15_13 [3] */
+		FN_SD2_DAT2_A,	FN_VI1_DATA12,	FN_DREQ2_B,	FN_ATADIR1,
+		FN_HSPI_CLK2_B,	FN_GPSCLK_B,	0,		0,
+		/* IP10_12_9 [4] */
+		FN_SD2_DAT1_A,	FN_DU1_CDE,	FN_ATACS11,	FN_DACK1_B,
+		FN_ETH_MAGIC,	FN_CAN1_TX_A,	0,		FN_PWM6,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		/* IP10_8_6 [3] */
+		FN_SD2_DAT0_A,	FN_DU1_DISP,	FN_ATACS01,	FN_DREQ1_B,
+		FN_ETH_LINK,	FN_CAN1_RX_A,	0,		0,
+		/* IP10_5_3 [3] */
+		FN_SD2_CMD_A,	FN_DU1_EXODDF_DU1_ODDF_DISP_CDE,
+		FN_ATAWR1,	FN_ETH_MDIO,
+		FN_SCL1_B,	0,
+		0,		0,
+		/* IP10_2_0 [3] */
+		FN_SD2_CLK_A,	FN_DU1_EXVSYNC_DU1_VSYNC,
+		FN_ATARD1,	FN_ETH_MDC,
+		FN_SDA1_B,	0,
+		0,		0,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("MOD_SEL0", 0xfffc0050, 32,
+			     1, 1, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2,
+			     1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1) {
+
+		/* SEL 31  [1] */
+		0, 0,
+		/* SEL_30 (SCIF5) [1] */
+		FN_SEL_SCIF5_A,		FN_SEL_SCIF5_B,
+		/* SEL_29_28 (SCIF4) [2] */
+		FN_SEL_SCIF4_A,		FN_SEL_SCIF4_B,
+		FN_SEL_SCIF4_C,		0,
+		/* SEL_27_26 (SCIF3) [2] */
+		FN_SEL_SCIF3_A,		FN_SEL_SCIF3_B,
+		FN_SEL_SCIF3_C,		FN_SEL_SCIF3_D,
+		/* SEL_25_23 (SCIF2) [3] */
+		FN_SEL_SCIF2_A,		FN_SEL_SCIF2_B,
+		FN_SEL_SCIF2_C,		FN_SEL_SCIF2_D,
+		FN_SEL_SCIF2_E,		0,
+		0,			0,
+		/* SEL_22_21 (SCIF1) [2] */
+		FN_SEL_SCIF1_A,		FN_SEL_SCIF1_B,
+		FN_SEL_SCIF1_C,		FN_SEL_SCIF1_D,
+		/* SEL_20_19 (SCIF0) [2] */
+		FN_SEL_SCIF0_A,		FN_SEL_SCIF0_B,
+		FN_SEL_SCIF0_C,		FN_SEL_SCIF0_D,
+		/* SEL_18 [1] */
+		0, 0,
+		/* SEL_17 (SSI2) [1] */
+		FN_SEL_SSI2_A,		FN_SEL_SSI2_B,
+		/* SEL_16 (SSI1) [1] */
+		FN_SEL_SSI1_A,		FN_SEL_SSI1_B,
+		/* SEL_15 (VI1) [1] */
+		FN_SEL_VI1_A,		FN_SEL_VI1_B,
+		/* SEL_14_13 (VI0) [2] */
+		FN_SEL_VI0_A,		FN_SEL_VI0_B,
+		FN_SEL_VI0_C,		FN_SEL_VI0_D,
+		/* SEL_12 [1] */
+		0, 0,
+		/* SEL_11 (SD2) [1] */
+		FN_SEL_SD2_A,		FN_SEL_SD2_B,
+		/* SEL_10 (SD1) [1] */
+		FN_SEL_SD1_A,		FN_SEL_SD1_B,
+		/* SEL_9 (IRQ3) [1] */
+		FN_SEL_IRQ3_A,		FN_SEL_IRQ3_B,
+		/* SEL_8_7 (IRQ2) [2] */
+		FN_SEL_IRQ2_A,		FN_SEL_IRQ2_B,
+		FN_SEL_IRQ2_C,		0,
+		/* SEL_6 (IRQ1) [1] */
+		FN_SEL_IRQ1_A,		FN_SEL_IRQ1_B,
+		/* SEL_5 [1] */
+		0, 0,
+		/* SEL_4 (DREQ2) [1] */
+		FN_SEL_DREQ2_A,		FN_SEL_DREQ2_B,
+		/* SEL_3 (DREQ1) [1] */
+		FN_SEL_DREQ1_A,		FN_SEL_DREQ1_B,
+		/* SEL_2 (DREQ0) [1] */
+		FN_SEL_DREQ0_A,		FN_SEL_DREQ0_B,
+		/* SEL_1 (WAIT2) [1] */
+		FN_SEL_WAIT2_A,		FN_SEL_WAIT2_B,
+		/* SEL_0 (WAIT1) [1] */
+		FN_SEL_WAIT1_A,		FN_SEL_WAIT1_B,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("MOD_SEL1", 0xfffc0054, 32,
+			     1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1,
+			     1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1) {
+
+		/* SEL_31 [1] */
+		0, 0,
+		/* SEL_30 [1] */
+		0, 0,
+		/* SEL_29 [1] */
+		0, 0,
+		/* SEL_28 [1] */
+		0, 0,
+		/* SEL_27 (CAN1) [1] */
+		FN_SEL_CAN1_A,		FN_SEL_CAN1_B,
+		/* SEL_26 (CAN0) [1] */
+		FN_SEL_CAN0_A,		FN_SEL_CAN0_B,
+		/* SEL_25_24 (CANCLK) [2] */
+		FN_SEL_CANCLK_A,	FN_SEL_CANCLK_B,
+		FN_SEL_CANCLK_C,	FN_SEL_CANCLK_D,
+		/* SEL_23 (HSCIF1) [1] */
+		FN_SEL_HSCIF1_A,	FN_SEL_HSCIF1_B,
+		/* SEL_22 (HSCIF0) [1] */
+		FN_SEL_HSCIF0_A,	FN_SEL_HSCIF0_B,
+		/* SEL_21 [1] */
+		0, 0,
+		/* SEL_20 [1] */
+		0, 0,
+		/* SEL_19 [1] */
+		0, 0,
+		/* SEL_18 [1] */
+		0, 0,
+		/* SEL_17 [1] */
+		0, 0,
+		/* SEL_16 [1] */
+		0, 0,
+		/* SEL_15 [1] */
+		0, 0,
+		/* SEL_14_13 (REMOCON) [2] */
+		FN_SEL_REMOCON_A,	FN_SEL_REMOCON_B,
+		FN_SEL_REMOCON_C,	0,
+		/* SEL_12_11 (FM) [2] */
+		FN_SEL_FM_A,		FN_SEL_FM_B,
+		FN_SEL_FM_C,		FN_SEL_FM_D,
+		/* SEL_10_9 (GPS) [2] */
+		FN_SEL_GPS_A,		FN_SEL_GPS_B,
+		FN_SEL_GPS_C,		0,
+		/* SEL_8 (TSIF0) [1] */
+		FN_SEL_TSIF0_A,		FN_SEL_TSIF0_B,
+		/* SEL_7 (HSPI2) [1] */
+		FN_SEL_HSPI2_A,		FN_SEL_HSPI2_B,
+		/* SEL_6 (HSPI1) [1] */
+		FN_SEL_HSPI1_A,		FN_SEL_HSPI1_B,
+		/* SEL_5 (HSPI0) [1] */
+		FN_SEL_HSPI0_A,		FN_SEL_HSPI0_B,
+		/* SEL_4_3 (I2C3) [2] */
+		FN_SEL_I2C3_A,		FN_SEL_I2C3_B,
+		FN_SEL_I2C3_C,		0,
+		/* SEL_2_1 (I2C2) [2] */
+		FN_SEL_I2C2_A,		FN_SEL_I2C2_B,
+		FN_SEL_I2C2_C,		0,
+		/* SEL_0 (I2C1) [1] */
+		FN_SEL_I2C1_A,		FN_SEL_I2C1_B,
+		}
+	},
+	{ },
+};
+
+const struct sh_pfc_soc_info r8a7778_pinmux_info = {
+	.name = "r8a7778_pfc",
+
+	.unlock_reg = 0xfffc0000, /* PMMR */
+
+	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+	.pins = pinmux_pins,
+	.nr_pins = ARRAY_SIZE(pinmux_pins),
+
+	.groups = pinmux_groups,
+	.nr_groups = ARRAY_SIZE(pinmux_groups),
+
+	.functions = pinmux_functions,
+	.nr_functions = ARRAY_SIZE(pinmux_functions),
+
+	.cfg_regs = pinmux_config_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7779.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7779.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7779.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7779.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,8 +1,9 @@
 /*
  * r8a7779 processor support - PFC hardware block
  *
- * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011, 2013  Renesas Solutions Corp.
  * Copyright (C) 2011  Magnus Damm
+ * Copyright (C) 2013  Cogent Embedded, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,6 +20,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/platform_data/gpio-rcar.h>
 
 #include "sh_pfc.h"
 
@@ -79,7 +81,7 @@
 #define _GP_PORT_ALL(bank, pin, name, sfx)	name##_##sfx
 
 #define _GP_GPIO(bank, pin, _name, sfx)					\
-	[(bank * 32) + pin] = {						\
+	[RCAR_GP_PIN(bank, pin)] = {					\
 		.name = __stringify(_name),				\
 		.enum_id = _name##_DATA,				\
 	}
@@ -1472,9 +1474,12 @@ static struct sh_pfc_pin pinmux_pins[] =
 /* - DU0 -------------------------------------------------------------------- */
 static const unsigned int du0_rgb666_pins[] = {
 	/* R[7:2], G[7:2], B[7:2] */
-	188, 187, 186, 185, 184, 183,
-	194, 193, 192, 191, 190, 189,
-	200, 199, 198, 197, 196, 195,
+	RCAR_GP_PIN(5, 28), RCAR_GP_PIN(5, 27), RCAR_GP_PIN(5, 26),
+	RCAR_GP_PIN(5, 25), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 23),
+	RCAR_GP_PIN(6, 2),  RCAR_GP_PIN(6, 1),  RCAR_GP_PIN(6, 0),
+	RCAR_GP_PIN(5, 31), RCAR_GP_PIN(5, 30), RCAR_GP_PIN(5, 29),
+	RCAR_GP_PIN(6, 8),  RCAR_GP_PIN(6, 7),  RCAR_GP_PIN(6, 6),
+	RCAR_GP_PIN(6, 5),  RCAR_GP_PIN(6, 4),  RCAR_GP_PIN(6, 3),
 };
 static const unsigned int du0_rgb666_mux[] = {
 	DU0_DR7_MARK, DU0_DR6_MARK, DU0_DR5_MARK, DU0_DR4_MARK,
@@ -1486,9 +1491,14 @@ static const unsigned int du0_rgb666_mux
 };
 static const unsigned int du0_rgb888_pins[] = {
 	/* R[7:0], G[7:0], B[7:0] */
-	188, 187, 186, 185, 184, 183, 24, 23,
-	194, 193, 192, 191, 190, 189, 26, 25,
-	200, 199, 198, 197, 196, 195, 28, 27,
+	RCAR_GP_PIN(5, 28), RCAR_GP_PIN(5, 27), RCAR_GP_PIN(5, 26),
+	RCAR_GP_PIN(5, 25), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 23),
+	RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 23), RCAR_GP_PIN(6, 2),
+	RCAR_GP_PIN(6, 1),  RCAR_GP_PIN(6, 0),  RCAR_GP_PIN(5, 31),
+	RCAR_GP_PIN(5, 30), RCAR_GP_PIN(5, 29), RCAR_GP_PIN(0, 26),
+	RCAR_GP_PIN(0, 25), RCAR_GP_PIN(6, 8),  RCAR_GP_PIN(6, 7),
+	RCAR_GP_PIN(6, 6),  RCAR_GP_PIN(6, 5),  RCAR_GP_PIN(6, 4),
+	RCAR_GP_PIN(6, 3),  RCAR_GP_PIN(0, 28), RCAR_GP_PIN(0, 27),
 };
 static const unsigned int du0_rgb888_mux[] = {
 	DU0_DR7_MARK, DU0_DR6_MARK, DU0_DR5_MARK, DU0_DR4_MARK,
@@ -1500,28 +1510,28 @@ static const unsigned int du0_rgb888_mux
 };
 static const unsigned int du0_clk_in_pins[] = {
 	/* CLKIN */
-	29,
+	RCAR_GP_PIN(0, 29),
 };
 static const unsigned int du0_clk_in_mux[] = {
 	DU0_DOTCLKIN_MARK,
 };
 static const unsigned int du0_clk_out_0_pins[] = {
 	/* CLKOUT */
-	180,
+	RCAR_GP_PIN(5, 20),
 };
 static const unsigned int du0_clk_out_0_mux[] = {
 	DU0_DOTCLKOUT0_MARK,
 };
 static const unsigned int du0_clk_out_1_pins[] = {
 	/* CLKOUT */
-	30,
+	RCAR_GP_PIN(0, 30),
 };
 static const unsigned int du0_clk_out_1_mux[] = {
 	DU0_DOTCLKOUT1_MARK,
 };
 static const unsigned int du0_sync_0_pins[] = {
 	/* VSYNC, HSYNC, DISP */
-	182, 181, 31,
+	RCAR_GP_PIN(5, 22), RCAR_GP_PIN(5, 21), RCAR_GP_PIN(0, 31),
 };
 static const unsigned int du0_sync_0_mux[] = {
 	DU0_EXHSYNC_DU0_HSYNC_MARK, DU0_EXVSYNC_DU0_VSYNC_MARK,
@@ -1529,7 +1539,7 @@ static const unsigned int du0_sync_0_mux
 };
 static const unsigned int du0_sync_1_pins[] = {
 	/* VSYNC, HSYNC, DISP */
-	182, 181, 32,
+	RCAR_GP_PIN(5, 22), RCAR_GP_PIN(5, 21), RCAR_GP_PIN(1, 0),
 };
 static const unsigned int du0_sync_1_mux[] = {
 	DU0_EXHSYNC_DU0_HSYNC_MARK, DU0_EXVSYNC_DU0_VSYNC_MARK,
@@ -1537,14 +1547,14 @@ static const unsigned int du0_sync_1_mux
 };
 static const unsigned int du0_oddf_pins[] = {
 	/* ODDF */
-	31,
+	RCAR_GP_PIN(0, 31),
 };
 static const unsigned int du0_oddf_mux[] = {
 	DU0_EXODDF_DU0_ODDF_DISP_CDE_MARK
 };
 static const unsigned int du0_cde_pins[] = {
 	/* CDE */
-	33,
+	RCAR_GP_PIN(1, 1),
 };
 static const unsigned int du0_cde_mux[] = {
 	DU0_CDE_MARK
@@ -1552,9 +1562,12 @@ static const unsigned int du0_cde_mux[]
 /* - DU1 -------------------------------------------------------------------- */
 static const unsigned int du1_rgb666_pins[] = {
 	/* R[7:2], G[7:2], B[7:2] */
-	41, 40, 39, 38, 37, 36,
-	49, 48, 47, 46, 45, 44,
-	57, 56, 55, 54, 53, 52,
+	RCAR_GP_PIN(1, 9),  RCAR_GP_PIN(1, 8),  RCAR_GP_PIN(1, 7),
+	RCAR_GP_PIN(1, 6),  RCAR_GP_PIN(1, 5),  RCAR_GP_PIN(1, 4),
+	RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 16), RCAR_GP_PIN(1, 15),
+	RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13), RCAR_GP_PIN(1, 12),
+	RCAR_GP_PIN(1, 25), RCAR_GP_PIN(1, 24), RCAR_GP_PIN(1, 23),
+	RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 21), RCAR_GP_PIN(1, 20),
 };
 static const unsigned int du1_rgb666_mux[] = {
 	DU1_DR7_MARK, DU1_DR6_MARK, DU1_DR5_MARK, DU1_DR4_MARK,
@@ -1566,9 +1579,14 @@ static const unsigned int du1_rgb666_mux
 };
 static const unsigned int du1_rgb888_pins[] = {
 	/* R[7:0], G[7:0], B[7:0] */
-	41, 40, 39, 38, 37, 36, 35, 34,
-	49, 48, 47, 46, 45, 44, 43, 32,
-	57, 56, 55, 54, 53, 52, 51, 50,
+	RCAR_GP_PIN(1, 9),  RCAR_GP_PIN(1, 8),  RCAR_GP_PIN(1, 7),
+	RCAR_GP_PIN(1, 6),  RCAR_GP_PIN(1, 5),  RCAR_GP_PIN(1, 4),
+	RCAR_GP_PIN(1, 3),  RCAR_GP_PIN(1, 2),  RCAR_GP_PIN(1, 17),
+	RCAR_GP_PIN(1, 16), RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14),
+	RCAR_GP_PIN(1, 13), RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 11),
+	RCAR_GP_PIN(1, 0),  RCAR_GP_PIN(1, 25), RCAR_GP_PIN(1, 24),
+	RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 21),
+	RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18),
 };
 static const unsigned int du1_rgb888_mux[] = {
 	DU1_DR7_MARK, DU1_DR6_MARK, DU1_DR5_MARK, DU1_DR4_MARK,
@@ -1580,21 +1598,21 @@ static const unsigned int du1_rgb888_mux
 };
 static const unsigned int du1_clk_in_pins[] = {
 	/* CLKIN */
-	58,
+	RCAR_GP_PIN(1, 26),
 };
 static const unsigned int du1_clk_in_mux[] = {
 	DU1_DOTCLKIN_MARK,
 };
 static const unsigned int du1_clk_out_pins[] = {
 	/* CLKOUT */
-	59,
+	RCAR_GP_PIN(1, 27),
 };
 static const unsigned int du1_clk_out_mux[] = {
 	DU1_DOTCLKOUT_MARK,
 };
 static const unsigned int du1_sync_0_pins[] = {
 	/* VSYNC, HSYNC, DISP */
-	61, 60, 62,
+	RCAR_GP_PIN(1, 29), RCAR_GP_PIN(1, 28), RCAR_GP_PIN(1, 30),
 };
 static const unsigned int du1_sync_0_mux[] = {
 	DU1_EXVSYNC_DU1_VSYNC_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK,
@@ -1602,7 +1620,7 @@ static const unsigned int du1_sync_0_mux
 };
 static const unsigned int du1_sync_1_pins[] = {
 	/* VSYNC, HSYNC, DISP */
-	61, 60, 63,
+	RCAR_GP_PIN(1, 29), RCAR_GP_PIN(1, 28), RCAR_GP_PIN(1, 31),
 };
 static const unsigned int du1_sync_1_mux[] = {
 	DU1_EXVSYNC_DU1_VSYNC_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK,
@@ -1610,22 +1628,55 @@ static const unsigned int du1_sync_1_mux
 };
 static const unsigned int du1_oddf_pins[] = {
 	/* ODDF */
-	62,
+	RCAR_GP_PIN(1, 30),
 };
 static const unsigned int du1_oddf_mux[] = {
 	DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK
 };
 static const unsigned int du1_cde_pins[] = {
 	/* CDE */
-	64,
+	RCAR_GP_PIN(2, 0),
 };
 static const unsigned int du1_cde_mux[] = {
 	DU1_CDE_MARK
 };
+/* - Ether ------------------------------------------------------------------ */
+static const unsigned int ether_rmii_pins[] = {
+	/*
+	 * ETH_TXD0, ETH_TXD1, ETH_TX_EN,  ETH_REFCLK,
+	 * ETH_RXD0, ETH_RXD1, ETH_CRS_DV, ETH_RX_ER,
+	 * ETH_MDIO, ETH_MDC
+	 */
+	RCAR_GP_PIN(2, 27), RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 18),
+	RCAR_GP_PIN(2, 26),
+	RCAR_GP_PIN(2, 20), RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 17),
+	RCAR_GP_PIN(2, 19),
+	RCAR_GP_PIN(2, 29), RCAR_GP_PIN(2, 28),
+};
+static const unsigned int ether_rmii_mux[] = {
+	ETH_TXD0_MARK, ETH_TXD1_MARK, ETH_TX_EN_MARK,  ETH_REFCLK_MARK,
+	ETH_RXD0_MARK, ETH_RXD1_MARK, ETH_CRS_DV_MARK, ETH_RX_ER_MARK,
+	ETH_MDIO_MARK, ETH_MDC_MARK,
+};
+static const unsigned int ether_link_pins[] = {
+	/* ETH_LINK */
+	RCAR_GP_PIN(2, 24),
+};
+static const unsigned int ether_link_mux[] = {
+	ETH_LINK_MARK,
+};
+static const unsigned int ether_magic_pins[] = {
+	/* ETH_MAGIC */
+	RCAR_GP_PIN(2, 25),
+};
+static const unsigned int ether_magic_mux[] = {
+	ETH_MAGIC_MARK,
+};
 /* - HSPI0 ------------------------------------------------------------------ */
 static const unsigned int hspi0_pins[] = {
 	/* CLK, CS, RX, TX */
-	150, 151, 153, 152,
+	RCAR_GP_PIN(4, 22), RCAR_GP_PIN(4, 23), RCAR_GP_PIN(4, 25),
+	RCAR_GP_PIN(4, 24),
 };
 static const unsigned int hspi0_mux[] = {
 	HSPI_CLK0_MARK, HSPI_CS0_MARK, HSPI_RX0_MARK, HSPI_TX0_MARK,
@@ -1633,28 +1684,32 @@ static const unsigned int hspi0_mux[] =
 /* - HSPI1 ------------------------------------------------------------------ */
 static const unsigned int hspi1_pins[] = {
 	/* CLK, CS, RX, TX */
-	63, 58, 64, 62,
+	RCAR_GP_PIN(1, 31), RCAR_GP_PIN(1, 26), RCAR_GP_PIN(2, 0),
+	RCAR_GP_PIN(1, 30),
 };
 static const unsigned int hspi1_mux[] = {
 	HSPI_CLK1_MARK, HSPI_CS1_MARK, HSPI_RX1_MARK, HSPI_TX1_MARK,
 };
 static const unsigned int hspi1_b_pins[] = {
 	/* CLK, CS, RX, TX */
-	90, 91, 93, 92,
+	RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 27), RCAR_GP_PIN(2, 29),
+	RCAR_GP_PIN(2, 28),
 };
 static const unsigned int hspi1_b_mux[] = {
 	HSPI_CLK1_B_MARK, HSPI_CS1_B_MARK, HSPI_RX1_B_MARK, HSPI_TX1_B_MARK,
 };
 static const unsigned int hspi1_c_pins[] = {
 	/* CLK, CS, RX, TX */
-	141, 142, 144, 143,
+	RCAR_GP_PIN(4, 13), RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 16),
+	RCAR_GP_PIN(4, 15),
 };
 static const unsigned int hspi1_c_mux[] = {
 	HSPI_CLK1_C_MARK, HSPI_CS1_C_MARK, HSPI_RX1_C_MARK, HSPI_TX1_C_MARK,
 };
 static const unsigned int hspi1_d_pins[] = {
 	/* CLK, CS, RX, TX */
-	101, 102, 104, 103,
+	RCAR_GP_PIN(3, 5), RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 8),
+	RCAR_GP_PIN(3, 7),
 };
 static const unsigned int hspi1_d_mux[] = {
 	HSPI_CLK1_D_MARK, HSPI_CS1_D_MARK, HSPI_RX1_D_MARK, HSPI_TX1_D_MARK,
@@ -1662,14 +1717,16 @@ static const unsigned int hspi1_d_mux[]
 /* - HSPI2 ------------------------------------------------------------------ */
 static const unsigned int hspi2_pins[] = {
 	/* CLK, CS, RX, TX */
-	9, 10, 11, 14,
+	RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
+	RCAR_GP_PIN(0, 14),
 };
 static const unsigned int hspi2_mux[] = {
 	HSPI_CLK2_MARK, HSPI_CS2_MARK, HSPI_RX2_MARK, HSPI_TX2_MARK,
 };
 static const unsigned int hspi2_b_pins[] = {
 	/* CLK, CS, RX, TX */
-	7, 13, 8, 6,
+	RCAR_GP_PIN(0, 7), RCAR_GP_PIN(0, 13), RCAR_GP_PIN(0, 8),
+	RCAR_GP_PIN(0, 6),
 };
 static const unsigned int hspi2_b_mux[] = {
 	HSPI_CLK2_B_MARK, HSPI_CS2_B_MARK, HSPI_RX2_B_MARK, HSPI_TX2_B_MARK,
@@ -1677,56 +1734,56 @@ static const unsigned int hspi2_b_mux[]
 /* - INTC ------------------------------------------------------------------- */
 static const unsigned int intc_irq0_pins[] = {
 	/* IRQ */
-	78,
+	RCAR_GP_PIN(2, 14),
 };
 static const unsigned int intc_irq0_mux[] = {
 	IRQ0_MARK,
 };
 static const unsigned int intc_irq0_b_pins[] = {
 	/* IRQ */
-	141,
+	RCAR_GP_PIN(4, 13),
 };
 static const unsigned int intc_irq0_b_mux[] = {
 	IRQ0_B_MARK,
 };
 static const unsigned int intc_irq1_pins[] = {
 	/* IRQ */
-	79,
+	RCAR_GP_PIN(2, 15),
 };
 static const unsigned int intc_irq1_mux[] = {
 	IRQ1_MARK,
 };
 static const unsigned int intc_irq1_b_pins[] = {
 	/* IRQ */
-	142,
+	RCAR_GP_PIN(4, 14),
 };
 static const unsigned int intc_irq1_b_mux[] = {
 	IRQ1_B_MARK,
 };
 static const unsigned int intc_irq2_pins[] = {
 	/* IRQ */
-	88,
+	RCAR_GP_PIN(2, 24),
 };
 static const unsigned int intc_irq2_mux[] = {
 	IRQ2_MARK,
 };
 static const unsigned int intc_irq2_b_pins[] = {
 	/* IRQ */
-	143,
+	RCAR_GP_PIN(4, 15),
 };
 static const unsigned int intc_irq2_b_mux[] = {
 	IRQ2_B_MARK,
 };
 static const unsigned int intc_irq3_pins[] = {
 	/* IRQ */
-	89,
+	RCAR_GP_PIN(2, 25),
 };
 static const unsigned int intc_irq3_mux[] = {
 	IRQ3_MARK,
 };
 static const unsigned int intc_irq3_b_pins[] = {
 	/* IRQ */
-	144,
+	RCAR_GP_PIN(4, 16),
 };
 static const unsigned int intc_irq3_b_mux[] = {
 	IRQ3_B_MARK,
@@ -1734,56 +1791,56 @@ static const unsigned int intc_irq3_b_mu
 /* - LSBC ------------------------------------------------------------------- */
 static const unsigned int lbsc_cs0_pins[] = {
 	/* CS */
-	13,
+	RCAR_GP_PIN(0, 13),
 };
 static const unsigned int lbsc_cs0_mux[] = {
 	CS0_MARK,
 };
 static const unsigned int lbsc_cs1_pins[] = {
 	/* CS */
-	14,
+	RCAR_GP_PIN(0, 14),
 };
 static const unsigned int lbsc_cs1_mux[] = {
 	CS1_A26_MARK,
 };
 static const unsigned int lbsc_ex_cs0_pins[] = {
 	/* CS */
-	15,
+	RCAR_GP_PIN(0, 15),
 };
 static const unsigned int lbsc_ex_cs0_mux[] = {
 	EX_CS0_MARK,
 };
 static const unsigned int lbsc_ex_cs1_pins[] = {
 	/* CS */
-	16,
+	RCAR_GP_PIN(0, 16),
 };
 static const unsigned int lbsc_ex_cs1_mux[] = {
 	EX_CS1_MARK,
 };
 static const unsigned int lbsc_ex_cs2_pins[] = {
 	/* CS */
-	17,
+	RCAR_GP_PIN(0, 17),
 };
 static const unsigned int lbsc_ex_cs2_mux[] = {
 	EX_CS2_MARK,
 };
 static const unsigned int lbsc_ex_cs3_pins[] = {
 	/* CS */
-	18,
+	RCAR_GP_PIN(0, 18),
 };
 static const unsigned int lbsc_ex_cs3_mux[] = {
 	EX_CS3_MARK,
 };
 static const unsigned int lbsc_ex_cs4_pins[] = {
 	/* CS */
-	19,
+	RCAR_GP_PIN(0, 19),
 };
 static const unsigned int lbsc_ex_cs4_mux[] = {
 	EX_CS4_MARK,
 };
 static const unsigned int lbsc_ex_cs5_pins[] = {
 	/* CS */
-	20,
+	RCAR_GP_PIN(0, 20),
 };
 static const unsigned int lbsc_ex_cs5_mux[] = {
 	EX_CS5_MARK,
@@ -1791,21 +1848,24 @@ static const unsigned int lbsc_ex_cs5_mu
 /* - MMCIF ------------------------------------------------------------------ */
 static const unsigned int mmc0_data1_pins[] = {
 	/* D[0] */
-	19,
+	RCAR_GP_PIN(0, 19),
 };
 static const unsigned int mmc0_data1_mux[] = {
 	MMC0_D0_MARK,
 };
 static const unsigned int mmc0_data4_pins[] = {
 	/* D[0:3] */
-	19, 20, 21, 2,
+	RCAR_GP_PIN(0, 19), RCAR_GP_PIN(0, 20), RCAR_GP_PIN(0, 21),
+	RCAR_GP_PIN(0, 2),
 };
 static const unsigned int mmc0_data4_mux[] = {
 	MMC0_D0_MARK, MMC0_D1_MARK, MMC0_D2_MARK, MMC0_D3_MARK,
 };
 static const unsigned int mmc0_data8_pins[] = {
 	/* D[0:7] */
-	19, 20, 21, 2, 10, 11, 15, 16,
+	RCAR_GP_PIN(0, 19), RCAR_GP_PIN(0, 20), RCAR_GP_PIN(0, 21),
+	RCAR_GP_PIN(0, 2),  RCAR_GP_PIN(0, 10), RCAR_GP_PIN(0, 11),
+	RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 16),
 };
 static const unsigned int mmc0_data8_mux[] = {
 	MMC0_D0_MARK, MMC0_D1_MARK, MMC0_D2_MARK, MMC0_D3_MARK,
@@ -1813,28 +1873,31 @@ static const unsigned int mmc0_data8_mux
 };
 static const unsigned int mmc0_ctrl_pins[] = {
 	/* CMD, CLK */
-	18, 17,
+	RCAR_GP_PIN(0, 18), RCAR_GP_PIN(0, 17),
 };
 static const unsigned int mmc0_ctrl_mux[] = {
 	MMC0_CMD_MARK, MMC0_CLK_MARK,
 };
 static const unsigned int mmc1_data1_pins[] = {
 	/* D[0] */
-	72,
+	RCAR_GP_PIN(2, 8),
 };
 static const unsigned int mmc1_data1_mux[] = {
 	MMC1_D0_MARK,
 };
 static const unsigned int mmc1_data4_pins[] = {
 	/* D[0:3] */
-	72, 73, 74, 75,
+	RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9), RCAR_GP_PIN(2, 10),
+	RCAR_GP_PIN(2, 11),
 };
 static const unsigned int mmc1_data4_mux[] = {
 	MMC1_D0_MARK, MMC1_D1_MARK, MMC1_D2_MARK, MMC1_D3_MARK,
 };
 static const unsigned int mmc1_data8_pins[] = {
 	/* D[0:7] */
-	72, 73, 74, 75, 76, 77, 80, 81,
+	RCAR_GP_PIN(2, 8),  RCAR_GP_PIN(2, 9),  RCAR_GP_PIN(2, 10),
+	RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
+	RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 17),
 };
 static const unsigned int mmc1_data8_mux[] = {
 	MMC1_D0_MARK, MMC1_D1_MARK, MMC1_D2_MARK, MMC1_D3_MARK,
@@ -1842,7 +1905,7 @@ static const unsigned int mmc1_data8_mux
 };
 static const unsigned int mmc1_ctrl_pins[] = {
 	/* CMD, CLK */
-	68, 65,
+	RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 1),
 };
 static const unsigned int mmc1_ctrl_mux[] = {
 	MMC1_CMD_MARK, MMC1_CLK_MARK,
@@ -1850,84 +1913,84 @@ static const unsigned int mmc1_ctrl_mux[
 /* - SCIF0 ------------------------------------------------------------------ */
 static const unsigned int scif0_data_pins[] = {
 	/* RXD, TXD */
-	153, 152,
+	RCAR_GP_PIN(4, 25), RCAR_GP_PIN(4, 24),
 };
 static const unsigned int scif0_data_mux[] = {
 	RX0_MARK, TX0_MARK,
 };
 static const unsigned int scif0_clk_pins[] = {
 	/* SCK */
-	156,
+	RCAR_GP_PIN(4, 28),
 };
 static const unsigned int scif0_clk_mux[] = {
 	SCK0_MARK,
 };
 static const unsigned int scif0_ctrl_pins[] = {
 	/* RTS, CTS */
-	151, 150,
+	RCAR_GP_PIN(4, 23), RCAR_GP_PIN(4, 22),
 };
 static const unsigned int scif0_ctrl_mux[] = {
 	RTS0_TANS_MARK, CTS0_MARK,
 };
 static const unsigned int scif0_data_b_pins[] = {
 	/* RXD, TXD */
-	20, 19,
+	RCAR_GP_PIN(0, 20), RCAR_GP_PIN(0, 19),
 };
 static const unsigned int scif0_data_b_mux[] = {
 	RX0_B_MARK, TX0_B_MARK,
 };
 static const unsigned int scif0_clk_b_pins[] = {
 	/* SCK */
-	33,
+	RCAR_GP_PIN(1, 1),
 };
 static const unsigned int scif0_clk_b_mux[] = {
 	SCK0_B_MARK,
 };
 static const unsigned int scif0_ctrl_b_pins[] = {
 	/* RTS, CTS */
-	18, 11,
+	RCAR_GP_PIN(0, 18), RCAR_GP_PIN(0, 11),
 };
 static const unsigned int scif0_ctrl_b_mux[] = {
 	RTS0_B_TANS_B_MARK, CTS0_B_MARK,
 };
 static const unsigned int scif0_data_c_pins[] = {
 	/* RXD, TXD */
-	146, 147,
+	RCAR_GP_PIN(4, 18), RCAR_GP_PIN(4, 19),
 };
 static const unsigned int scif0_data_c_mux[] = {
 	RX0_C_MARK, TX0_C_MARK,
 };
 static const unsigned int scif0_clk_c_pins[] = {
 	/* SCK */
-	145,
+	RCAR_GP_PIN(4, 17),
 };
 static const unsigned int scif0_clk_c_mux[] = {
 	SCK0_C_MARK,
 };
 static const unsigned int scif0_ctrl_c_pins[] = {
 	/* RTS, CTS */
-	149, 148,
+	RCAR_GP_PIN(4, 21), RCAR_GP_PIN(4, 20),
 };
 static const unsigned int scif0_ctrl_c_mux[] = {
 	RTS0_C_TANS_C_MARK, CTS0_C_MARK,
 };
 static const unsigned int scif0_data_d_pins[] = {
 	/* RXD, TXD */
-	43, 42,
+	RCAR_GP_PIN(1, 11), RCAR_GP_PIN(1, 10),
 };
 static const unsigned int scif0_data_d_mux[] = {
 	RX0_D_MARK, TX0_D_MARK,
 };
 static const unsigned int scif0_clk_d_pins[] = {
 	/* SCK */
-	50,
+	RCAR_GP_PIN(1, 18),
 };
 static const unsigned int scif0_clk_d_mux[] = {
 	SCK0_D_MARK,
 };
 static const unsigned int scif0_ctrl_d_pins[] = {
 	/* RTS, CTS */
-	51, 35,
+	RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 3),
 };
 static const unsigned int scif0_ctrl_d_mux[] = {
 	RTS0_D_TANS_D_MARK, CTS0_D_MARK,
@@ -1935,63 +1998,63 @@ static const unsigned int scif0_ctrl_d_m
 /* - SCIF1 ------------------------------------------------------------------ */
 static const unsigned int scif1_data_pins[] = {
 	/* RXD, TXD */
-	149, 148,
+	RCAR_GP_PIN(4, 21), RCAR_GP_PIN(4, 20),
 };
 static const unsigned int scif1_data_mux[] = {
 	RX1_MARK, TX1_MARK,
 };
 static const unsigned int scif1_clk_pins[] = {
 	/* SCK */
-	145,
+	RCAR_GP_PIN(4, 17),
 };
 static const unsigned int scif1_clk_mux[] = {
 	SCK1_MARK,
 };
 static const unsigned int scif1_ctrl_pins[] = {
 	/* RTS, CTS */
-	147, 146,
+	RCAR_GP_PIN(4, 19), RCAR_GP_PIN(4, 18),
 };
 static const unsigned int scif1_ctrl_mux[] = {
 	RTS1_TANS_MARK, CTS1_MARK,
 };
 static const unsigned int scif1_data_b_pins[] = {
 	/* RXD, TXD */
-	117, 114,
+	RCAR_GP_PIN(3, 21), RCAR_GP_PIN(3, 18),
 };
 static const unsigned int scif1_data_b_mux[] = {
 	RX1_B_MARK, TX1_B_MARK,
 };
 static const unsigned int scif1_clk_b_pins[] = {
 	/* SCK */
-	113,
+	RCAR_GP_PIN(3, 17),
 };
 static const unsigned int scif1_clk_b_mux[] = {
 	SCK1_B_MARK,
 };
 static const unsigned int scif1_ctrl_b_pins[] = {
 	/* RTS, CTS */
-	115, 116,
+	RCAR_GP_PIN(3, 19), RCAR_GP_PIN(3, 20),
 };
 static const unsigned int scif1_ctrl_b_mux[] = {
 	RTS1_B_TANS_B_MARK, CTS1_B_MARK,
 };
 static const unsigned int scif1_data_c_pins[] = {
 	/* RXD, TXD */
-	67, 66,
+	RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 2),
 };
 static const unsigned int scif1_data_c_mux[] = {
 	RX1_C_MARK, TX1_C_MARK,
 };
 static const unsigned int scif1_clk_c_pins[] = {
 	/* SCK */
-	86,
+	RCAR_GP_PIN(2, 22),
 };
 static const unsigned int scif1_clk_c_mux[] = {
 	SCK1_C_MARK,
 };
 static const unsigned int scif1_ctrl_c_pins[] = {
 	/* RTS, CTS */
-	69, 68,
+	RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 4),
 };
 static const unsigned int scif1_ctrl_c_mux[] = {
 	RTS1_C_TANS_C_MARK, CTS1_C_MARK,
@@ -1999,63 +2062,63 @@ static const unsigned int scif1_ctrl_c_m
 /* - SCIF2 ------------------------------------------------------------------ */
 static const unsigned int scif2_data_pins[] = {
 	/* RXD, TXD */
-	106, 105,
+	RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 9),
 };
 static const unsigned int scif2_data_mux[] = {
 	RX2_MARK, TX2_MARK,
 };
 static const unsigned int scif2_clk_pins[] = {
 	/* SCK */
-	107,
+	RCAR_GP_PIN(3, 11),
 };
 static const unsigned int scif2_clk_mux[] = {
 	SCK2_MARK,
 };
 static const unsigned int scif2_data_b_pins[] = {
 	/* RXD, TXD */
-	120, 119,
+	RCAR_GP_PIN(3, 24), RCAR_GP_PIN(3, 23),
 };
 static const unsigned int scif2_data_b_mux[] = {
 	RX2_B_MARK, TX2_B_MARK,
 };
 static const unsigned int scif2_clk_b_pins[] = {
 	/* SCK */
-	118,
+	RCAR_GP_PIN(3, 22),
 };
 static const unsigned int scif2_clk_b_mux[] = {
 	SCK2_B_MARK,
 };
 static const unsigned int scif2_data_c_pins[] = {
 	/* RXD, TXD */
-	33, 31,
+	RCAR_GP_PIN(1, 1), RCAR_GP_PIN(0, 31),
 };
 static const unsigned int scif2_data_c_mux[] = {
 	RX2_C_MARK, TX2_C_MARK,
 };
 static const unsigned int scif2_clk_c_pins[] = {
 	/* SCK */
-	32,
+	RCAR_GP_PIN(1, 0),
 };
 static const unsigned int scif2_clk_c_mux[] = {
 	SCK2_C_MARK,
 };
 static const unsigned int scif2_data_d_pins[] = {
 	/* RXD, TXD */
-	64, 62,
+	RCAR_GP_PIN(2, 0), RCAR_GP_PIN(1, 30),
 };
 static const unsigned int scif2_data_d_mux[] = {
 	RX2_D_MARK, TX2_D_MARK,
 };
 static const unsigned int scif2_clk_d_pins[] = {
 	/* SCK */
-	63,
+	RCAR_GP_PIN(1, 31),
 };
 static const unsigned int scif2_clk_d_mux[] = {
 	SCK2_D_MARK,
 };
 static const unsigned int scif2_data_e_pins[] = {
 	/* RXD, TXD */
-	20, 19,
+	RCAR_GP_PIN(0, 20), RCAR_GP_PIN(0, 19),
 };
 static const unsigned int scif2_data_e_mux[] = {
 	RX2_E_MARK, TX2_E_MARK,
@@ -2063,14 +2126,14 @@ static const unsigned int scif2_data_e_m
 /* - SCIF3 ------------------------------------------------------------------ */
 static const unsigned int scif3_data_pins[] = {
 	/* RXD, TXD */
-	137, 136,
+	RCAR_GP_PIN(4, 9), RCAR_GP_PIN(4, 8),
 };
 static const unsigned int scif3_data_mux[] = {
 	RX3_IRDA_RX_MARK, TX3_IRDA_TX_MARK,
 };
 static const unsigned int scif3_clk_pins[] = {
 	/* SCK */
-	135,
+	RCAR_GP_PIN(4, 7),
 };
 static const unsigned int scif3_clk_mux[] = {
 	SCK3_MARK,
@@ -2078,35 +2141,35 @@ static const unsigned int scif3_clk_mux[
 
 static const unsigned int scif3_data_b_pins[] = {
 	/* RXD, TXD */
-	64, 62,
+	RCAR_GP_PIN(2, 0), RCAR_GP_PIN(1, 30),
 };
 static const unsigned int scif3_data_b_mux[] = {
 	RX3_B_IRDA_RX_B_MARK, TX3_B_IRDA_TX_B_MARK,
 };
 static const unsigned int scif3_data_c_pins[] = {
 	/* RXD, TXD */
-	15, 12,
+	RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 12),
 };
 static const unsigned int scif3_data_c_mux[] = {
 	RX3_C_IRDA_RX_C_MARK, TX3C_IRDA_TX_C_MARK,
 };
 static const unsigned int scif3_data_d_pins[] = {
 	/* RXD, TXD */
-	30, 29,
+	RCAR_GP_PIN(0, 30), RCAR_GP_PIN(0, 29),
 };
 static const unsigned int scif3_data_d_mux[] = {
 	RX3_D_IRDA_RX_D_MARK, TX3_D_IRDA_TX_D_MARK,
 };
 static const unsigned int scif3_data_e_pins[] = {
 	/* RXD, TXD */
-	35, 34,
+	RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 2),
 };
 static const unsigned int scif3_data_e_mux[] = {
 	RX3_E_IRDA_RX_E_MARK, TX3_E_IRDA_TX_E_MARK,
 };
 static const unsigned int scif3_clk_e_pins[] = {
 	/* SCK */
-	42,
+	RCAR_GP_PIN(1, 10),
 };
 static const unsigned int scif3_clk_e_mux[] = {
 	SCK3_E_MARK,
@@ -2114,42 +2177,42 @@ static const unsigned int scif3_clk_e_mu
 /* - SCIF4 ------------------------------------------------------------------ */
 static const unsigned int scif4_data_pins[] = {
 	/* RXD, TXD */
-	123, 122,
+	RCAR_GP_PIN(3, 27), RCAR_GP_PIN(3, 26),
 };
 static const unsigned int scif4_data_mux[] = {
 	RX4_MARK, TX4_MARK,
 };
 static const unsigned int scif4_clk_pins[] = {
 	/* SCK */
-	121,
+	RCAR_GP_PIN(3, 25),
 };
 static const unsigned int scif4_clk_mux[] = {
 	SCK4_MARK,
 };
 static const unsigned int scif4_data_b_pins[] = {
 	/* RXD, TXD */
-	111, 110,
+	RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 14),
 };
 static const unsigned int scif4_data_b_mux[] = {
 	RX4_B_MARK, TX4_B_MARK,
 };
 static const unsigned int scif4_clk_b_pins[] = {
 	/* SCK */
-	112,
+	RCAR_GP_PIN(3, 16),
 };
 static const unsigned int scif4_clk_b_mux[] = {
 	SCK4_B_MARK,
 };
 static const unsigned int scif4_data_c_pins[] = {
 	/* RXD, TXD */
-	22, 21,
+	RCAR_GP_PIN(0, 22), RCAR_GP_PIN(0, 21),
 };
 static const unsigned int scif4_data_c_mux[] = {
 	RX4_C_MARK, TX4_C_MARK,
 };
 static const unsigned int scif4_data_d_pins[] = {
 	/* RXD, TXD */
-	69, 68,
+	RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 4),
 };
 static const unsigned int scif4_data_d_mux[] = {
 	RX4_D_MARK, TX4_D_MARK,
@@ -2157,56 +2220,56 @@ static const unsigned int scif4_data_d_m
 /* - SCIF5 ------------------------------------------------------------------ */
 static const unsigned int scif5_data_pins[] = {
 	/* RXD, TXD */
-	51, 50,
+	RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18),
 };
 static const unsigned int scif5_data_mux[] = {
 	RX5_MARK, TX5_MARK,
 };
 static const unsigned int scif5_clk_pins[] = {
 	/* SCK */
-	43,
+	RCAR_GP_PIN(1, 11),
 };
 static const unsigned int scif5_clk_mux[] = {
 	SCK5_MARK,
 };
 static const unsigned int scif5_data_b_pins[] = {
 	/* RXD, TXD */
-	18, 11,
+	RCAR_GP_PIN(0, 18), RCAR_GP_PIN(0, 11),
 };
 static const unsigned int scif5_data_b_mux[] = {
 	RX5_B_MARK, TX5_B_MARK,
 };
 static const unsigned int scif5_clk_b_pins[] = {
 	/* SCK */
-	19,
+	RCAR_GP_PIN(0, 19),
 };
 static const unsigned int scif5_clk_b_mux[] = {
 	SCK5_B_MARK,
 };
 static const unsigned int scif5_data_c_pins[] = {
 	/* RXD, TXD */
-	24, 23,
+	RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 23),
 };
 static const unsigned int scif5_data_c_mux[] = {
 	RX5_C_MARK, TX5_C_MARK,
 };
 static const unsigned int scif5_clk_c_pins[] = {
 	/* SCK */
-	28,
+	RCAR_GP_PIN(0, 28),
 };
 static const unsigned int scif5_clk_c_mux[] = {
 	SCK5_C_MARK,
 };
 static const unsigned int scif5_data_d_pins[] = {
 	/* RXD, TXD */
-	8, 6,
+	RCAR_GP_PIN(0, 8), RCAR_GP_PIN(0, 6),
 };
 static const unsigned int scif5_data_d_mux[] = {
 	RX5_D_MARK, TX5_D_MARK,
 };
 static const unsigned int scif5_clk_d_pins[] = {
 	/* SCK */
-	7,
+	RCAR_GP_PIN(0, 7),
 };
 static const unsigned int scif5_clk_d_mux[] = {
 	SCK5_D_MARK,
@@ -2214,35 +2277,36 @@ static const unsigned int scif5_clk_d_mu
 /* - SDHI0 ------------------------------------------------------------------ */
 static const unsigned int sdhi0_data1_pins[] = {
 	/* D0 */
-	117,
+	RCAR_GP_PIN(3, 21),
 };
 static const unsigned int sdhi0_data1_mux[] = {
 	SD0_DAT0_MARK,
 };
 static const unsigned int sdhi0_data4_pins[] = {
 	/* D[0:3] */
-	117, 118, 119, 120,
+	RCAR_GP_PIN(3, 21), RCAR_GP_PIN(3, 22), RCAR_GP_PIN(3, 23),
+	RCAR_GP_PIN(3, 24),
 };
 static const unsigned int sdhi0_data4_mux[] = {
 	SD0_DAT0_MARK, SD0_DAT1_MARK, SD0_DAT2_MARK, SD0_DAT3_MARK,
 };
 static const unsigned int sdhi0_ctrl_pins[] = {
 	/* CMD, CLK */
-	114, 113,
+	RCAR_GP_PIN(3, 18), RCAR_GP_PIN(3, 17),
 };
 static const unsigned int sdhi0_ctrl_mux[] = {
 	SD0_CMD_MARK, SD0_CLK_MARK,
 };
 static const unsigned int sdhi0_cd_pins[] = {
 	/* CD */
-	115,
+	RCAR_GP_PIN(3, 19),
 };
 static const unsigned int sdhi0_cd_mux[] = {
 	SD0_CD_MARK,
 };
 static const unsigned int sdhi0_wp_pins[] = {
 	/* WP */
-	116,
+	RCAR_GP_PIN(3, 20),
 };
 static const unsigned int sdhi0_wp_mux[] = {
 	SD0_WP_MARK,
@@ -2250,35 +2314,36 @@ static const unsigned int sdhi0_wp_mux[]
 /* - SDHI1 ------------------------------------------------------------------ */
 static const unsigned int sdhi1_data1_pins[] = {
 	/* D0 */
-	19,
+	RCAR_GP_PIN(0, 19),
 };
 static const unsigned int sdhi1_data1_mux[] = {
 	SD1_DAT0_MARK,
 };
 static const unsigned int sdhi1_data4_pins[] = {
 	/* D[0:3] */
-	19, 20, 21, 2,
+	RCAR_GP_PIN(0, 19), RCAR_GP_PIN(0, 20), RCAR_GP_PIN(0, 21),
+	RCAR_GP_PIN(0, 2),
 };
 static const unsigned int sdhi1_data4_mux[] = {
 	SD1_DAT0_MARK, SD1_DAT1_MARK, SD1_DAT2_MARK, SD1_DAT3_MARK,
 };
 static const unsigned int sdhi1_ctrl_pins[] = {
 	/* CMD, CLK */
-	18, 17,
+	RCAR_GP_PIN(0, 18), RCAR_GP_PIN(0, 17),
 };
 static const unsigned int sdhi1_ctrl_mux[] = {
 	SD1_CMD_MARK, SD1_CLK_MARK,
 };
 static const unsigned int sdhi1_cd_pins[] = {
 	/* CD */
-	10,
+	RCAR_GP_PIN(0, 10),
 };
 static const unsigned int sdhi1_cd_mux[] = {
 	SD1_CD_MARK,
 };
 static const unsigned int sdhi1_wp_pins[] = {
 	/* WP */
-	11,
+	RCAR_GP_PIN(0, 11),
 };
 static const unsigned int sdhi1_wp_mux[] = {
 	SD1_WP_MARK,
@@ -2286,35 +2351,36 @@ static const unsigned int sdhi1_wp_mux[]
 /* - SDHI2 ------------------------------------------------------------------ */
 static const unsigned int sdhi2_data1_pins[] = {
 	/* D0 */
-	97,
+	RCAR_GP_PIN(3, 1),
 };
 static const unsigned int sdhi2_data1_mux[] = {
 	SD2_DAT0_MARK,
 };
 static const unsigned int sdhi2_data4_pins[] = {
 	/* D[0:3] */
-	97, 98, 99, 100,
+	RCAR_GP_PIN(3, 1), RCAR_GP_PIN(3, 2), RCAR_GP_PIN(3, 3),
+	RCAR_GP_PIN(3, 4),
 };
 static const unsigned int sdhi2_data4_mux[] = {
 	SD2_DAT0_MARK, SD2_DAT1_MARK, SD2_DAT2_MARK, SD2_DAT3_MARK,
 };
 static const unsigned int sdhi2_ctrl_pins[] = {
 	/* CMD, CLK */
-	102, 101,
+	RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 5),
 };
 static const unsigned int sdhi2_ctrl_mux[] = {
 	SD2_CMD_MARK, SD2_CLK_MARK,
 };
 static const unsigned int sdhi2_cd_pins[] = {
 	/* CD */
-	103,
+	RCAR_GP_PIN(3, 7),
 };
 static const unsigned int sdhi2_cd_mux[] = {
 	SD2_CD_MARK,
 };
 static const unsigned int sdhi2_wp_pins[] = {
 	/* WP */
-	104,
+	RCAR_GP_PIN(3, 8),
 };
 static const unsigned int sdhi2_wp_mux[] = {
 	SD2_WP_MARK,
@@ -2322,35 +2388,36 @@ static const unsigned int sdhi2_wp_mux[]
 /* - SDHI3 ------------------------------------------------------------------ */
 static const unsigned int sdhi3_data1_pins[] = {
 	/* D0 */
-	50,
+	RCAR_GP_PIN(1, 18),
 };
 static const unsigned int sdhi3_data1_mux[] = {
 	SD3_DAT0_MARK,
 };
 static const unsigned int sdhi3_data4_pins[] = {
 	/* D[0:3] */
-	50, 51, 52, 53,
+	RCAR_GP_PIN(1, 18), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 20),
+	RCAR_GP_PIN(1, 21),
 };
 static const unsigned int sdhi3_data4_mux[] = {
 	SD3_DAT0_MARK, SD3_DAT1_MARK, SD3_DAT2_MARK, SD3_DAT3_MARK,
 };
 static const unsigned int sdhi3_ctrl_pins[] = {
 	/* CMD, CLK */
-	35, 34,
+	RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 2),
 };
 static const unsigned int sdhi3_ctrl_mux[] = {
 	SD3_CMD_MARK, SD3_CLK_MARK,
 };
 static const unsigned int sdhi3_cd_pins[] = {
 	/* CD */
-	62,
+	RCAR_GP_PIN(1, 30),
 };
 static const unsigned int sdhi3_cd_mux[] = {
 	SD3_CD_MARK,
 };
 static const unsigned int sdhi3_wp_pins[] = {
 	/* WP */
-	64,
+	RCAR_GP_PIN(2, 0),
 };
 static const unsigned int sdhi3_wp_mux[] = {
 	SD3_WP_MARK,
@@ -2358,14 +2425,14 @@ static const unsigned int sdhi3_wp_mux[]
 /* - USB0 ------------------------------------------------------------------- */
 static const unsigned int usb0_pins[] = {
 	/* PENC */
-	154,
+	RCAR_GP_PIN(4, 26),
 };
 static const unsigned int usb0_mux[] = {
 	USB_PENC0_MARK,
 };
 static const unsigned int usb0_ovc_pins[] = {
 	/* USB_OVC */
-	150
+	RCAR_GP_PIN(4, 22),
 };
 static const unsigned int usb0_ovc_mux[] = {
 	USB_OVC0_MARK,
@@ -2373,14 +2440,14 @@ static const unsigned int usb0_ovc_mux[]
 /* - USB1 ------------------------------------------------------------------- */
 static const unsigned int usb1_pins[] = {
 	/* PENC */
-	155,
+	RCAR_GP_PIN(4, 27),
 };
 static const unsigned int usb1_mux[] = {
 	USB_PENC1_MARK,
 };
 static const unsigned int usb1_ovc_pins[] = {
 	/* USB_OVC */
-	152,
+	RCAR_GP_PIN(4, 24),
 };
 static const unsigned int usb1_ovc_mux[] = {
 	USB_OVC1_MARK,
@@ -2388,18 +2455,122 @@ static const unsigned int usb1_ovc_mux[]
 /* - USB2 ------------------------------------------------------------------- */
 static const unsigned int usb2_pins[] = {
 	/* PENC */
-	156,
+	RCAR_GP_PIN(4, 28),
 };
 static const unsigned int usb2_mux[] = {
 	USB_PENC2_MARK,
 };
 static const unsigned int usb2_ovc_pins[] = {
 	/* USB_OVC */
-	125,
+	RCAR_GP_PIN(3, 29),
 };
 static const unsigned int usb2_ovc_mux[] = {
 	USB_OVC2_MARK,
 };
+/* - VIN0 ------------------------------------------------------------------- */
+static const unsigned int vin0_data8_pins[] = {
+	/* D[0:7] */
+	RCAR_GP_PIN(2, 6),  RCAR_GP_PIN(2, 7),  RCAR_GP_PIN(2, 8),
+	RCAR_GP_PIN(2, 9),  RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
+	RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
+};
+static const unsigned int vin0_data8_mux[] = {
+	VI0_DATA0_VI0_B0_MARK, VI0_DATA1_VI0_B1_MARK, VI0_DATA2_VI0_B2_MARK,
+	VI0_DATA3_VI0_B3_MARK, VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK,
+	VI0_DATA6_VI0_B6_MARK, VI0_DATA7_VI0_B7_MARK,
+};
+static const unsigned int vin0_clk_pins[] = {
+	/* CLK */
+	RCAR_GP_PIN(2, 1),
+};
+static const unsigned int vin0_clk_mux[] = {
+	VI0_CLK_MARK,
+};
+static const unsigned int vin0_sync_pins[] = {
+	/* HSYNC, VSYNC */
+	RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
+};
+static const unsigned int vin0_sync_mux[] = {
+	VI0_HSYNC_MARK, VI0_VSYNC_MARK,
+};
+/* - VIN1 ------------------------------------------------------------------- */
+static const unsigned int vin1_data8_pins[] = {
+	/* D[0:7] */
+	RCAR_GP_PIN(3, 1), RCAR_GP_PIN(3, 2), RCAR_GP_PIN(3, 3),
+	RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5), RCAR_GP_PIN(3, 6),
+	RCAR_GP_PIN(3, 7), RCAR_GP_PIN(3, 8),
+};
+static const unsigned int vin1_data8_mux[] = {
+	VI1_DATA0_VI1_B0_MARK, VI1_DATA1_VI1_B1_MARK, VI1_DATA2_VI1_B2_MARK,
+	VI1_DATA3_VI1_B3_MARK, VI1_DATA4_VI1_B4_MARK, VI1_DATA5_VI1_B5_MARK,
+	VI1_DATA6_VI1_B6_MARK, VI1_DATA7_VI1_B7_MARK,
+};
+static const unsigned int vin1_clk_pins[] = {
+	/* CLK */
+	RCAR_GP_PIN(2, 30),
+};
+static const unsigned int vin1_clk_mux[] = {
+	VI1_CLK_MARK,
+};
+static const unsigned int vin1_sync_pins[] = {
+	/* HSYNC, VSYNC */
+	RCAR_GP_PIN(2, 31), RCAR_GP_PIN(3, 0),
+};
+static const unsigned int vin1_sync_mux[] = {
+	VI1_HSYNC_MARK, VI1_VSYNC_MARK,
+};
+/* - VIN2 ------------------------------------------------------------------- */
+static const unsigned int vin2_data8_pins[] = {
+	/* D[0:7] */
+	RCAR_GP_PIN(1, 2),  RCAR_GP_PIN(1, 3),  RCAR_GP_PIN(1, 10),
+	RCAR_GP_PIN(1, 11), RCAR_GP_PIN(1, 18), RCAR_GP_PIN(1, 19),
+	RCAR_GP_PIN(1, 31), RCAR_GP_PIN(2, 0),
+};
+static const unsigned int vin2_data8_mux[] = {
+	VI2_DATA0_VI2_B0_MARK, VI2_DATA1_VI2_B1_MARK, VI2_DATA2_VI2_B2_MARK,
+	VI2_DATA3_VI2_B3_MARK, VI2_DATA4_VI2_B4_MARK, VI2_DATA5_VI2_B5_MARK,
+	VI2_DATA6_VI2_B6_MARK, VI2_DATA7_VI2_B7_MARK,
+};
+static const unsigned int vin2_clk_pins[] = {
+	/* CLK */
+	RCAR_GP_PIN(1, 30),
+};
+static const unsigned int vin2_clk_mux[] = {
+	VI2_CLK_MARK,
+};
+static const unsigned int vin2_sync_pins[] = {
+	/* HSYNC, VSYNC */
+	RCAR_GP_PIN(1, 28), RCAR_GP_PIN(1, 29),
+};
+static const unsigned int vin2_sync_mux[] = {
+	VI2_HSYNC_MARK, VI2_VSYNC_MARK,
+};
+/* - VIN3 ------------------------------------------------------------------- */
+static const unsigned int vin3_data8_pins[] = {
+	/* D[0:7] */
+	RCAR_GP_PIN(3, 9),  RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
+	RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 14),
+	RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 16),
+};
+static const unsigned int vin3_data8_mux[] = {
+	VI3_DATA0_MARK, VI3_DATA1_MARK, VI3_DATA2_MARK,
+	VI3_DATA3_MARK, VI3_DATA4_MARK, VI3_DATA5_MARK,
+	VI3_DATA6_MARK, VI3_DATA7_MARK,
+};
+static const unsigned int vin3_clk_pins[] = {
+	/* CLK */
+	RCAR_GP_PIN(2, 31),
+};
+static const unsigned int vin3_clk_mux[] = {
+	VI3_CLK_MARK,
+};
+static const unsigned int vin3_sync_pins[] = {
+	/* HSYNC, VSYNC */
+	RCAR_GP_PIN(1, 28), RCAR_GP_PIN(1, 29),
+};
+static const unsigned int vin3_sync_mux[] = {
+	VI3_HSYNC_MARK, VI3_VSYNC_MARK,
+};
 
 static const struct sh_pfc_pin_group pinmux_groups[] = {
 	SH_PFC_PIN_GROUP(du0_rgb666),
@@ -2419,6 +2590,9 @@ static const struct sh_pfc_pin_group pin
 	SH_PFC_PIN_GROUP(du1_sync_1),
 	SH_PFC_PIN_GROUP(du1_oddf),
 	SH_PFC_PIN_GROUP(du1_cde),
+	SH_PFC_PIN_GROUP(ether_rmii),
+	SH_PFC_PIN_GROUP(ether_link),
+	SH_PFC_PIN_GROUP(ether_magic),
 	SH_PFC_PIN_GROUP(hspi0),
 	SH_PFC_PIN_GROUP(hspi1),
 	SH_PFC_PIN_GROUP(hspi1_b),
@@ -2527,6 +2701,18 @@ static const struct sh_pfc_pin_group pin
 	SH_PFC_PIN_GROUP(usb1_ovc),
 	SH_PFC_PIN_GROUP(usb2),
 	SH_PFC_PIN_GROUP(usb2_ovc),
+	SH_PFC_PIN_GROUP(vin0_data8),
+	SH_PFC_PIN_GROUP(vin0_clk),
+	SH_PFC_PIN_GROUP(vin0_sync),
+	SH_PFC_PIN_GROUP(vin1_data8),
+	SH_PFC_PIN_GROUP(vin1_clk),
+	SH_PFC_PIN_GROUP(vin1_sync),
+	SH_PFC_PIN_GROUP(vin2_data8),
+	SH_PFC_PIN_GROUP(vin2_clk),
+	SH_PFC_PIN_GROUP(vin2_sync),
+	SH_PFC_PIN_GROUP(vin3_data8),
+	SH_PFC_PIN_GROUP(vin3_clk),
+	SH_PFC_PIN_GROUP(vin3_sync),
 };
 
 static const char * const du0_groups[] = {
@@ -2552,6 +2738,12 @@ static const char * const du1_groups[] =
 	"du1_cde",
 };
 
+static const char * const ether_groups[] = {
+	"ether_rmii",
+	"ether_link",
+	"ether_magic",
+};
+
 static const char * const hspi0_groups[] = {
 	"hspi0",
 };
@@ -2720,9 +2912,34 @@ static const char * const usb2_groups[]
 	"usb2_ovc",
 };
 
+static const char * const vin0_groups[] = {
+	"vin0_data8",
+	"vin0_clk",
+	"vin0_sync",
+};
+
+static const char * const vin1_groups[] = {
+	"vin1_data8",
+	"vin1_clk",
+	"vin1_sync",
+};
+
+static const char * const vin2_groups[] = {
+	"vin2_data8",
+	"vin2_clk",
+	"vin2_sync",
+};
+
+static const char * const vin3_groups[] = {
+	"vin3_data8",
+	"vin3_clk",
+	"vin3_sync",
+};
+
 static const struct sh_pfc_function pinmux_functions[] = {
 	SH_PFC_FUNCTION(du0),
 	SH_PFC_FUNCTION(du1),
+	SH_PFC_FUNCTION(ether),
 	SH_PFC_FUNCTION(hspi0),
 	SH_PFC_FUNCTION(hspi1),
 	SH_PFC_FUNCTION(hspi2),
@@ -2743,6 +2960,10 @@ static const struct sh_pfc_function pinm
 	SH_PFC_FUNCTION(usb0),
 	SH_PFC_FUNCTION(usb1),
 	SH_PFC_FUNCTION(usb2),
+	SH_PFC_FUNCTION(vin0),
+	SH_PFC_FUNCTION(vin1),
+	SH_PFC_FUNCTION(vin2),
+	SH_PFC_FUNCTION(vin3),
 };
 
 static const struct pinmux_cfg_reg pinmux_config_regs[] = {
@@ -3547,7 +3768,7 @@ static const struct pinmux_cfg_reg pinmu
 	    /* SEL_SCIF [2] */
 	    FN_SEL_SCIF_0, FN_SEL_SCIF_1, FN_SEL_SCIF_2, FN_SEL_SCIF_3,
 	    /* SEL_CANCLK [2] */
-	    FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, FN_SEL_CANCLK_2,
+	    FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, FN_SEL_CANCLK_2, 0,
 	    /* SEL_CAN0 [1] */
 	    FN_SEL_CAN0_0, FN_SEL_CAN0_1,
 	    /* SEL_HSCIF1 [1] */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7790.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7790.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-r8a7790.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,4014 @@
+/*
+ * R8A7790 processor support
+ *
+ * Copyright (C) 2013  Renesas Electronics Corporation
+ * Copyright (C) 2013  Magnus Damm
+ * Copyright (C) 2012  Renesas Solutions Corp.
+ * Copyright (C) 2012  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_data/gpio-rcar.h>
+
+#include "core.h"
+#include "sh_pfc.h"
+
+#define PORT_GP_1(bank, pin, fn, sfx) fn(bank, pin, GP_##bank##_##pin, sfx)
+
+#define PORT_GP_32(bank, fn, sfx)					\
+	PORT_GP_1(bank, 0,  fn, sfx), PORT_GP_1(bank, 1,  fn, sfx),	\
+	PORT_GP_1(bank, 2,  fn, sfx), PORT_GP_1(bank, 3,  fn, sfx),	\
+	PORT_GP_1(bank, 4,  fn, sfx), PORT_GP_1(bank, 5,  fn, sfx),	\
+	PORT_GP_1(bank, 6,  fn, sfx), PORT_GP_1(bank, 7,  fn, sfx),	\
+	PORT_GP_1(bank, 8,  fn, sfx), PORT_GP_1(bank, 9,  fn, sfx),	\
+	PORT_GP_1(bank, 10, fn, sfx), PORT_GP_1(bank, 11, fn, sfx),	\
+	PORT_GP_1(bank, 12, fn, sfx), PORT_GP_1(bank, 13, fn, sfx),	\
+	PORT_GP_1(bank, 14, fn, sfx), PORT_GP_1(bank, 15, fn, sfx),	\
+	PORT_GP_1(bank, 16, fn, sfx), PORT_GP_1(bank, 17, fn, sfx),	\
+	PORT_GP_1(bank, 18, fn, sfx), PORT_GP_1(bank, 19, fn, sfx),	\
+	PORT_GP_1(bank, 20, fn, sfx), PORT_GP_1(bank, 21, fn, sfx),	\
+	PORT_GP_1(bank, 22, fn, sfx), PORT_GP_1(bank, 23, fn, sfx),	\
+	PORT_GP_1(bank, 24, fn, sfx), PORT_GP_1(bank, 25, fn, sfx),	\
+	PORT_GP_1(bank, 26, fn, sfx), PORT_GP_1(bank, 27, fn, sfx),	\
+	PORT_GP_1(bank, 28, fn, sfx), PORT_GP_1(bank, 29, fn, sfx),	\
+	PORT_GP_1(bank, 30, fn, sfx), PORT_GP_1(bank, 31, fn, sfx)
+
+#define PORT_GP_32_REV(bank, fn, sfx)					\
+	PORT_GP_1(bank, 31, fn, sfx), PORT_GP_1(bank, 30, fn, sfx),	\
+	PORT_GP_1(bank, 29, fn, sfx), PORT_GP_1(bank, 28, fn, sfx),	\
+	PORT_GP_1(bank, 27, fn, sfx), PORT_GP_1(bank, 26, fn, sfx),	\
+	PORT_GP_1(bank, 25, fn, sfx), PORT_GP_1(bank, 24, fn, sfx),	\
+	PORT_GP_1(bank, 23, fn, sfx), PORT_GP_1(bank, 22, fn, sfx),	\
+	PORT_GP_1(bank, 21, fn, sfx), PORT_GP_1(bank, 20, fn, sfx),	\
+	PORT_GP_1(bank, 19, fn, sfx), PORT_GP_1(bank, 18, fn, sfx),	\
+	PORT_GP_1(bank, 17, fn, sfx), PORT_GP_1(bank, 16, fn, sfx),	\
+	PORT_GP_1(bank, 15, fn, sfx), PORT_GP_1(bank, 14, fn, sfx),	\
+	PORT_GP_1(bank, 13, fn, sfx), PORT_GP_1(bank, 12, fn, sfx),	\
+	PORT_GP_1(bank, 11, fn, sfx), PORT_GP_1(bank, 10, fn, sfx),	\
+	PORT_GP_1(bank, 9,  fn, sfx), PORT_GP_1(bank, 8,  fn, sfx),	\
+	PORT_GP_1(bank, 7,  fn, sfx), PORT_GP_1(bank, 6,  fn, sfx),	\
+	PORT_GP_1(bank, 5,  fn, sfx), PORT_GP_1(bank, 4,  fn, sfx),	\
+	PORT_GP_1(bank, 3,  fn, sfx), PORT_GP_1(bank, 2,  fn, sfx),	\
+	PORT_GP_1(bank, 1,  fn, sfx), PORT_GP_1(bank, 0,  fn, sfx)
+
+#define CPU_ALL_PORT(fn, sfx)						\
+	PORT_GP_32(0, fn, sfx),						\
+	PORT_GP_32(1, fn, sfx),						\
+	PORT_GP_32(2, fn, sfx),						\
+	PORT_GP_32(3, fn, sfx),						\
+	PORT_GP_32(4, fn, sfx),						\
+	PORT_GP_32(5, fn, sfx)
+
+#define _GP_PORT_ALL(bank, pin, name, sfx)	name##_##sfx
+
+#define _GP_GPIO(bank, pin, _name, sfx)					\
+	[(bank * 32) + pin] = {						\
+		.name = __stringify(_name),				\
+		.enum_id = _name##_DATA,				\
+	}
+
+#define _GP_DATA(bank, pin, name, sfx)					\
+	PINMUX_DATA(name##_DATA, name##_FN)
+
+#define GP_ALL(str)		CPU_ALL_PORT(_GP_PORT_ALL, str)
+#define PINMUX_GPIO_GP_ALL()	CPU_ALL_PORT(_GP_GPIO, unused)
+#define PINMUX_DATA_GP_ALL()	CPU_ALL_PORT(_GP_DATA, unused)
+
+#define PINMUX_IPSR_DATA(ipsr, fn) PINMUX_DATA(fn##_MARK, FN_##ipsr, FN_##fn)
+#define PINMUX_IPSR_MODSEL_DATA(ipsr, fn, ms) PINMUX_DATA(fn##_MARK, FN_##ms, \
+							  FN_##ipsr, FN_##fn)
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	GP_ALL(DATA),
+	PINMUX_DATA_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	GP_ALL(FN),
+
+	/* GPSR0 */
+	FN_IP0_2_0, FN_IP0_5_3, FN_IP0_8_6, FN_IP0_11_9, FN_IP0_15_12,
+	FN_IP0_19_16, FN_IP0_22_20, FN_IP0_26_23, FN_IP0_30_27,
+	FN_IP1_3_0, FN_IP1_7_4, FN_IP1_11_8, FN_IP1_14_12,
+	FN_IP1_17_15, FN_IP1_21_18, FN_IP1_25_22, FN_IP1_27_26,
+	FN_IP1_29_28, FN_IP2_2_0, FN_IP2_5_3, FN_IP2_8_6, FN_IP2_11_9,
+	FN_IP2_14_12, FN_IP2_17_15, FN_IP2_21_18, FN_IP2_25_22,
+	FN_IP2_28_26, FN_IP3_3_0, FN_IP3_7_4, FN_IP3_11_8,
+	FN_IP3_14_12, FN_IP3_17_15,
+
+	/* GPSR1 */
+	FN_IP3_19_18, FN_IP3_22_20, FN_IP3_25_23, FN_IP3_28_26,
+	FN_IP3_31_29, FN_IP4_2_0, FN_IP4_5_3, FN_IP4_8_6, FN_IP4_11_9,
+	FN_IP4_14_12, FN_IP4_17_15, FN_IP4_20_18, FN_IP4_23_21,
+	FN_IP4_26_24, FN_IP4_29_27, FN_IP5_2_0, FN_IP5_5_3, FN_IP5_9_6,
+	FN_IP5_12_10, FN_IP5_14_13, FN_IP5_17_15, FN_IP5_20_18,
+	FN_IP5_23_21, FN_IP5_26_24, FN_IP5_29_27, FN_IP6_2_0,
+	FN_IP6_5_3, FN_IP6_8_6, FN_IP6_10_9, FN_IP6_13_11,
+
+	/* GPSR2 */
+	FN_IP7_28_27, FN_IP7_30_29, FN_IP8_1_0, FN_IP8_3_2, FN_IP8_5_4,
+	FN_IP8_7_6, FN_IP8_9_8, FN_IP8_11_10, FN_IP8_13_12, FN_IP8_15_14,
+	FN_IP8_17_16, FN_IP8_19_18, FN_IP8_21_20, FN_IP8_23_22,
+	FN_IP8_25_24, FN_IP8_26, FN_IP8_27, FN_VI1_DATA7_VI1_B7,
+	FN_IP6_16_14, FN_IP6_19_17, FN_IP6_22_20, FN_IP6_25_23,
+	FN_IP6_28_26, FN_IP6_31_29, FN_IP7_2_0, FN_IP7_5_3, FN_IP7_7_6,
+	FN_IP7_9_8, FN_IP7_12_10, FN_IP7_15_13,
+
+	/* GPSR3 */
+	FN_IP8_28, FN_IP8_30_29, FN_IP9_1_0, FN_IP9_3_2, FN_IP9_5_4,
+	FN_IP9_7_6, FN_IP9_11_8, FN_IP9_15_12, FN_IP9_17_16, FN_IP9_19_18,
+	FN_IP9_21_20, FN_IP9_23_22, FN_IP9_25_24, FN_IP9_27_26,
+	FN_IP9_31_28, FN_IP10_3_0, FN_IP10_6_4, FN_IP10_10_7, FN_IP10_14_11,
+	FN_IP10_18_15, FN_IP10_22_19, FN_IP10_25_23, FN_IP10_29_26,
+	FN_IP11_3_0, FN_IP11_4, FN_IP11_6_5, FN_IP11_8_7, FN_IP11_10_9,
+	FN_IP11_12_11, FN_IP11_14_13, FN_IP11_17_15, FN_IP11_21_18,
+
+	/* GPSR4 */
+	FN_IP11_23_22, FN_IP11_26_24, FN_IP11_29_27, FN_IP11_31_30,
+	FN_IP12_1_0, FN_IP12_3_2, FN_IP12_5_4, FN_IP12_7_6, FN_IP12_10_8,
+	FN_IP12_13_11, FN_IP12_16_14, FN_IP12_19_17, FN_IP12_22_20,
+	FN_IP12_24_23, FN_IP12_27_25, FN_IP12_30_28, FN_IP13_2_0,
+	FN_IP13_6_3, FN_IP13_9_7, FN_IP13_12_10, FN_IP13_15_13,
+	FN_IP13_18_16, FN_IP13_22_19, FN_IP13_25_23, FN_IP13_28_26,
+	FN_IP13_30_29, FN_IP14_2_0, FN_IP14_5_3, FN_IP14_8_6, FN_IP14_11_9,
+	FN_IP14_15_12, FN_IP14_18_16,
+
+	/* GPSR5 */
+	FN_IP14_21_19, FN_IP14_24_22, FN_IP14_27_25, FN_IP14_30_28,
+	FN_IP15_2_0, FN_IP15_5_3, FN_IP15_8_6, FN_IP15_11_9, FN_IP15_13_12,
+	FN_IP15_15_14, FN_IP15_17_16, FN_IP15_19_18, FN_IP15_22_20,
+	FN_IP15_25_23, FN_IP15_27_26, FN_IP15_29_28, FN_IP16_2_0,
+	FN_IP16_5_3, FN_USB0_PWEN, FN_USB0_OVC_VBUS, FN_IP16_6, FN_IP16_7,
+	FN_USB2_PWEN, FN_USB2_OVC, FN_AVS1, FN_AVS2, FN_DU_DOTCLKIN0,
+	FN_IP7_26_25, FN_DU_DOTCLKIN2, FN_IP7_18_16, FN_IP7_21_19, FN_IP7_24_22,
+
+	/* IPSR0 */
+	FN_D0, FN_MSIOF3_SCK_B, FN_VI3_DATA0, FN_VI0_G4, FN_VI0_G4_B,
+	FN_D1, FN_MSIOF3_SYNC_B, FN_VI3_DATA1, FN_VI0_G5,
+	FN_VI0_G5_B, FN_D2, FN_MSIOF3_RXD_B, FN_VI3_DATA2,
+	FN_VI0_G6, FN_VI0_G6_B, FN_D3, FN_MSIOF3_TXD_B,
+	FN_VI3_DATA3, FN_VI0_G7, FN_VI0_G7_B, FN_D4,
+	FN_SCIFB1_RXD_F, FN_SCIFB0_RXD_C, FN_VI3_DATA4,
+	FN_VI0_R0, FN_VI0_R0_B, FN_RX0_B, FN_D5,
+	FN_SCIFB1_TXD_F, FN_SCIFB0_TXD_C, FN_VI3_DATA5,
+	FN_VI0_R1, FN_VI0_R1_B, FN_TX0_B, FN_D6,
+	FN_SCL2_C, FN_VI3_DATA6, FN_VI0_R2, FN_VI0_R2_B,
+	FN_SCL2_CIS_C, FN_D7, FN_AD_DI_B, FN_SDA2_C,
+	FN_VI3_DATA7, FN_VI0_R3, FN_VI0_R3_B, FN_SDA2_CIS_C,
+	FN_D8, FN_SCIFA1_SCK_C, FN_AVB_TXD0, FN_MII_TXD0,
+	FN_VI0_G0, FN_VI0_G0_B, FN_VI2_DATA0_VI2_B0,
+
+	/* IPSR1 */
+	FN_D9, FN_SCIFA1_RXD_C, FN_AVB_TXD1, FN_MII_TXD1,
+	FN_VI0_G1, FN_VI0_G1_B, FN_VI2_DATA1_VI2_B1, FN_D10,
+	FN_SCIFA1_TXD_C, FN_AVB_TXD2, FN_MII_TXD2,
+	FN_VI0_G2, FN_VI0_G2_B, FN_VI2_DATA2_VI2_B2, FN_D11,
+	FN_SCIFA1_CTS_N_C, FN_AVB_TXD3, FN_MII_TXD3,
+	FN_VI0_G3, FN_VI0_G3_B, FN_VI2_DATA3_VI2_B3,
+	FN_D12, FN_SCIFA1_RTS_N_C, FN_AVB_TXD4,
+	FN_VI0_HSYNC_N, FN_VI0_HSYNC_N_B, FN_VI2_DATA4_VI2_B4,
+	FN_D13, FN_AVB_TXD5, FN_VI0_VSYNC_N,
+	FN_VI0_VSYNC_N_B, FN_VI2_DATA5_VI2_B5, FN_D14,
+	FN_SCIFB1_RXD_C, FN_AVB_TXD6, FN_RX1_B,
+	FN_VI0_CLKENB, FN_VI0_CLKENB_B, FN_VI2_DATA6_VI2_B6,
+	FN_D15, FN_SCIFB1_TXD_C, FN_AVB_TXD7, FN_TX1_B,
+	FN_VI0_FIELD, FN_VI0_FIELD_B, FN_VI2_DATA7_VI2_B7,
+	FN_A0, FN_PWM3, FN_A1, FN_PWM4,
+
+	/* IPSR2 */
+	FN_A2, FN_PWM5, FN_MSIOF1_SS1_B, FN_A3,
+	FN_PWM6, FN_MSIOF1_SS2_B, FN_A4, FN_MSIOF1_TXD_B,
+	FN_TPU0TO0, FN_A5, FN_SCIFA1_TXD_B, FN_TPU0TO1,
+	FN_A6, FN_SCIFA1_RTS_N_B, FN_TPU0TO2, FN_A7,
+	FN_SCIFA1_SCK_B, FN_AUDIO_CLKOUT_B, FN_TPU0TO3,
+	FN_A8, FN_SCIFA1_RXD_B, FN_SSI_SCK5_B, FN_VI0_R4,
+	FN_VI0_R4_B, FN_SCIFB2_RXD_C, FN_VI2_DATA0_VI2_B0_B,
+	FN_A9, FN_SCIFA1_CTS_N_B, FN_SSI_WS5_B, FN_VI0_R5,
+	FN_VI0_R5_B, FN_SCIFB2_TXD_C, FN_VI2_DATA1_VI2_B1_B,
+	FN_A10, FN_SSI_SDATA5_B, FN_MSIOF2_SYNC, FN_VI0_R6,
+	FN_VI0_R6_B, FN_VI2_DATA2_VI2_B2_B,
+
+	/* IPSR3 */
+	FN_A11, FN_SCIFB2_CTS_N_B, FN_MSIOF2_SCK, FN_VI1_R0,
+	FN_VI1_R0_B, FN_VI2_G0, FN_VI2_DATA3_VI2_B3_B,
+	FN_A12, FN_SCIFB2_RXD_B, FN_MSIOF2_TXD, FN_VI1_R1,
+	FN_VI1_R1_B, FN_VI2_G1, FN_VI2_DATA4_VI2_B4_B,
+	FN_A13, FN_SCIFB2_RTS_N_B, FN_EX_WAIT2,
+	FN_MSIOF2_RXD, FN_VI1_R2, FN_VI1_R2_B, FN_VI2_G2,
+	FN_VI2_DATA5_VI2_B5_B, FN_A14, FN_SCIFB2_TXD_B,
+	FN_ATACS11_N, FN_MSIOF2_SS1, FN_A15, FN_SCIFB2_SCK_B,
+	FN_ATARD1_N, FN_MSIOF2_SS2, FN_A16, FN_ATAWR1_N,
+	FN_A17, FN_AD_DO_B, FN_ATADIR1_N, FN_A18,
+	FN_AD_CLK_B, FN_ATAG1_N, FN_A19, FN_AD_NCS_N_B,
+	FN_ATACS01_N, FN_EX_WAIT0_B, FN_A20, FN_SPCLK,
+	FN_VI1_R3, FN_VI1_R3_B, FN_VI2_G4,
+
+	/* IPSR4 */
+	FN_A21, FN_MOSI_IO0, FN_VI1_R4, FN_VI1_R4_B, FN_VI2_G5,
+	FN_A22, FN_MISO_IO1, FN_VI1_R5, FN_VI1_R5_B,
+	FN_VI2_G6, FN_A23, FN_IO2, FN_VI1_G7,
+	FN_VI1_G7_B, FN_VI2_G7, FN_A24, FN_IO3,
+	FN_VI1_R7, FN_VI1_R7_B, FN_VI2_CLKENB,
+	FN_VI2_CLKENB_B, FN_A25, FN_SSL, FN_VI1_G6,
+	FN_VI1_G6_B, FN_VI2_FIELD, FN_VI2_FIELD_B, FN_CS0_N,
+	FN_VI1_R6, FN_VI1_R6_B, FN_VI2_G3, FN_MSIOF0_SS2_B,
+	FN_CS1_N_A26, FN_SPEEDIN, FN_VI0_R7, FN_VI0_R7_B,
+	FN_VI2_CLK, FN_VI2_CLK_B, FN_EX_CS0_N, FN_HRX1_B,
+	FN_VI1_G5, FN_VI1_G5_B, FN_VI2_R0, FN_HTX0_B,
+	FN_MSIOF0_SS1_B, FN_EX_CS1_N, FN_GPS_CLK,
+	FN_HCTS1_N_B, FN_VI1_FIELD, FN_VI1_FIELD_B,
+	FN_VI2_R1, FN_EX_CS2_N, FN_GPS_SIGN, FN_HRTS1_N_B,
+	FN_VI3_CLKENB, FN_VI1_G0, FN_VI1_G0_B, FN_VI2_R2,
+
+	/* IPSR5 */
+	FN_EX_CS3_N, FN_GPS_MAG, FN_VI3_FIELD, FN_VI1_G1, FN_VI1_G1_B,
+	FN_VI2_R3, FN_EX_CS4_N, FN_MSIOF1_SCK_B, FN_VI3_HSYNC_N,
+	FN_VI2_HSYNC_N, FN_SCL1, FN_VI2_HSYNC_N_B,
+	FN_INTC_EN0_N, FN_SCL1_CIS, FN_EX_CS5_N, FN_CAN0_RX,
+	FN_MSIOF1_RXD_B, FN_VI3_VSYNC_N, FN_VI1_G2,
+	FN_VI1_G2_B, FN_VI2_R4, FN_SDA1, FN_INTC_EN1_N,
+	FN_SDA1_CIS, FN_BS_N, FN_IETX, FN_HTX1_B,
+	FN_CAN1_TX, FN_DRACK0, FN_IETX_C, FN_RD_N,
+	FN_CAN0_TX, FN_SCIFA0_SCK_B, FN_RD_WR_N, FN_VI1_G3,
+	FN_VI1_G3_B, FN_VI2_R5, FN_SCIFA0_RXD_B,
+	FN_INTC_IRQ4_N, FN_WE0_N, FN_IECLK, FN_CAN_CLK,
+	FN_VI2_VSYNC_N, FN_SCIFA0_TXD_B, FN_VI2_VSYNC_N_B,
+	FN_WE1_N, FN_IERX, FN_CAN1_RX, FN_VI1_G4,
+	FN_VI1_G4_B, FN_VI2_R6, FN_SCIFA0_CTS_N_B,
+	FN_IERX_C, FN_EX_WAIT0, FN_IRQ3, FN_INTC_IRQ3_N,
+	FN_VI3_CLK, FN_SCIFA0_RTS_N_B, FN_HRX0_B,
+	FN_MSIOF0_SCK_B, FN_DREQ0_N, FN_VI1_HSYNC_N,
+	FN_VI1_HSYNC_N_B, FN_VI2_R7, FN_SSI_SCK78_C,
+	FN_SSI_WS78_B,
+
+	/* IPSR6 */
+	FN_DACK0, FN_IRQ0, FN_INTC_IRQ0_N, FN_SSI_SCK6_B,
+	FN_VI1_VSYNC_N, FN_VI1_VSYNC_N_B, FN_SSI_WS78_C,
+	FN_DREQ1_N, FN_VI1_CLKENB, FN_VI1_CLKENB_B,
+	FN_SSI_SDATA7_C, FN_SSI_SCK78_B, FN_DACK1, FN_IRQ1,
+	FN_INTC_IRQ1_N, FN_SSI_WS6_B, FN_SSI_SDATA8_C,
+	FN_DREQ2_N, FN_HSCK1_B, FN_HCTS0_N_B,
+	FN_MSIOF0_TXD_B, FN_DACK2, FN_IRQ2, FN_INTC_IRQ2_N,
+	FN_SSI_SDATA6_B, FN_HRTS0_N_B, FN_MSIOF0_RXD_B,
+	FN_ETH_CRS_DV, FN_RMII_CRS_DV, FN_STP_ISCLK_0_B,
+	FN_TS_SDEN0_D, FN_GLO_Q0_C, FN_SCL2_E,
+	FN_SCL2_CIS_E, FN_ETH_RX_ER, FN_RMII_RX_ER,
+	FN_STP_ISD_0_B, FN_TS_SPSYNC0_D, FN_GLO_Q1_C,
+	FN_SDA2_E, FN_SDA2_CIS_E, FN_ETH_RXD0, FN_RMII_RXD0,
+	FN_STP_ISEN_0_B, FN_TS_SDAT0_D, FN_GLO_I0_C,
+	FN_SCIFB1_SCK_G, FN_SCK1_E, FN_ETH_RXD1,
+	FN_RMII_RXD1, FN_HRX0_E, FN_STP_ISSYNC_0_B,
+	FN_TS_SCK0_D, FN_GLO_I1_C, FN_SCIFB1_RXD_G,
+	FN_RX1_E, FN_ETH_LINK, FN_RMII_LINK, FN_HTX0_E,
+	FN_STP_IVCXO27_0_B, FN_SCIFB1_TXD_G, FN_TX1_E,
+	FN_ETH_REF_CLK, FN_RMII_REF_CLK, FN_HCTS0_N_E,
+	FN_STP_IVCXO27_1_B, FN_HRX0_F,
+
+	/* IPSR7 */
+	FN_ETH_MDIO, FN_RMII_MDIO, FN_HRTS0_N_E,
+	FN_SIM0_D_C, FN_HCTS0_N_F, FN_ETH_TXD1,
+	FN_RMII_TXD1, FN_HTX0_F, FN_BPFCLK_G, FN_RDS_CLK_F,
+	FN_ETH_TX_EN, FN_RMII_TX_EN, FN_SIM0_CLK_C,
+	FN_HRTS0_N_F, FN_ETH_MAGIC, FN_RMII_MAGIC,
+	FN_SIM0_RST_C, FN_ETH_TXD0, FN_RMII_TXD0,
+	FN_STP_ISCLK_1_B, FN_TS_SDEN1_C, FN_GLO_SCLK_C,
+	FN_ETH_MDC, FN_RMII_MDC, FN_STP_ISD_1_B,
+	FN_TS_SPSYNC1_C, FN_GLO_SDATA_C, FN_PWM0,
+	FN_SCIFA2_SCK_C, FN_STP_ISEN_1_B, FN_TS_SDAT1_C,
+	FN_GLO_SS_C, FN_PWM1, FN_SCIFA2_TXD_C,
+	FN_STP_ISSYNC_1_B, FN_TS_SCK1_C, FN_GLO_RFON_C,
+	FN_PCMOE_N, FN_PWM2, FN_PWMFSW0, FN_SCIFA2_RXD_C,
+	FN_PCMWE_N, FN_IECLK_C, FN_DU1_DOTCLKIN,
+	FN_AUDIO_CLKC, FN_AUDIO_CLKOUT_C, FN_VI0_CLK,
+	FN_ATACS00_N, FN_AVB_RXD1, FN_MII_RXD1,
+	FN_VI0_DATA0_VI0_B0, FN_ATACS10_N, FN_AVB_RXD2,
+	FN_MII_RXD2,
+
+	/* IPSR8 */
+	FN_VI0_DATA1_VI0_B1, FN_ATARD0_N, FN_AVB_RXD3,
+	FN_MII_RXD3, FN_VI0_DATA2_VI0_B2, FN_ATAWR0_N,
+	FN_AVB_RXD4, FN_VI0_DATA3_VI0_B3, FN_ATADIR0_N,
+	FN_AVB_RXD5, FN_VI0_DATA4_VI0_B4, FN_ATAG0_N,
+	FN_AVB_RXD6, FN_VI0_DATA5_VI0_B5, FN_EX_WAIT1,
+	FN_AVB_RXD7, FN_VI0_DATA6_VI0_B6, FN_AVB_RX_ER,
+	FN_MII_RX_ER, FN_VI0_DATA7_VI0_B7, FN_AVB_RX_CLK,
+	FN_MII_RX_CLK, FN_VI1_CLK, FN_AVB_RX_DV,
+	FN_MII_RX_DV, FN_VI1_DATA0_VI1_B0, FN_SCIFA1_SCK_D,
+	FN_AVB_CRS, FN_MII_CRS, FN_VI1_DATA1_VI1_B1,
+	FN_SCIFA1_RXD_D, FN_AVB_MDC, FN_MII_MDC,
+	FN_VI1_DATA2_VI1_B2, FN_SCIFA1_TXD_D, FN_AVB_MDIO,
+	FN_MII_MDIO, FN_VI1_DATA3_VI1_B3, FN_SCIFA1_CTS_N_D,
+	FN_AVB_GTX_CLK, FN_VI1_DATA4_VI1_B4, FN_SCIFA1_RTS_N_D,
+	FN_AVB_MAGIC, FN_MII_MAGIC, FN_VI1_DATA5_VI1_B5,
+	FN_AVB_PHY_INT, FN_VI1_DATA6_VI1_B6, FN_AVB_GTXREFCLK,
+	FN_SD0_CLK, FN_VI1_DATA0_VI1_B0_B, FN_SD0_CMD,
+	FN_SCIFB1_SCK_B, FN_VI1_DATA1_VI1_B1_B,
+
+	/* IPSR9 */
+	FN_SD0_DAT0, FN_SCIFB1_RXD_B, FN_VI1_DATA2_VI1_B2_B,
+	FN_SD0_DAT1, FN_SCIFB1_TXD_B, FN_VI1_DATA3_VI1_B3_B,
+	FN_SD0_DAT2, FN_SCIFB1_CTS_N_B, FN_VI1_DATA4_VI1_B4_B,
+	FN_SD0_DAT3, FN_SCIFB1_RTS_N_B, FN_VI1_DATA5_VI1_B5_B,
+	FN_SD0_CD, FN_MMC0_D6, FN_TS_SDEN0_B, FN_USB0_EXTP,
+	FN_GLO_SCLK, FN_VI1_DATA6_VI1_B6_B, FN_SCL1_B,
+	FN_SCL1_CIS_B, FN_VI2_DATA6_VI2_B6_B, FN_SD0_WP,
+	FN_MMC0_D7, FN_TS_SPSYNC0_B, FN_USB0_IDIN,
+	FN_GLO_SDATA, FN_VI1_DATA7_VI1_B7_B, FN_SDA1_B,
+	FN_SDA1_CIS_B, FN_VI2_DATA7_VI2_B7_B, FN_SD1_CLK,
+	FN_AVB_TX_EN, FN_MII_TX_EN, FN_SD1_CMD,
+	FN_AVB_TX_ER, FN_MII_TX_ER, FN_SCIFB0_SCK_B,
+	FN_SD1_DAT0, FN_AVB_TX_CLK, FN_MII_TX_CLK,
+	FN_SCIFB0_RXD_B, FN_SD1_DAT1, FN_AVB_LINK,
+	FN_MII_LINK, FN_SCIFB0_TXD_B, FN_SD1_DAT2,
+	FN_AVB_COL, FN_MII_COL, FN_SCIFB0_CTS_N_B,
+	FN_SD1_DAT3, FN_AVB_RXD0, FN_MII_RXD0,
+	FN_SCIFB0_RTS_N_B, FN_SD1_CD, FN_MMC1_D6,
+	FN_TS_SDEN1, FN_USB1_EXTP, FN_GLO_SS, FN_VI0_CLK_B,
+	FN_SCL2_D, FN_SCL2_CIS_D, FN_SIM0_CLK_B,
+	FN_VI3_CLK_B,
+
+	/* IPSR10 */
+	FN_SD1_WP, FN_MMC1_D7, FN_TS_SPSYNC1, FN_USB1_IDIN,
+	FN_GLO_RFON, FN_VI1_CLK_B, FN_SDA2_D, FN_SDA2_CIS_D,
+	FN_SIM0_D_B, FN_SD2_CLK, FN_MMC0_CLK, FN_SIM0_CLK,
+	FN_VI0_DATA0_VI0_B0_B, FN_TS_SDEN0_C, FN_GLO_SCLK_B,
+	FN_VI3_DATA0_B, FN_SD2_CMD, FN_MMC0_CMD, FN_SIM0_D,
+	FN_VI0_DATA1_VI0_B1_B, FN_SCIFB1_SCK_E, FN_SCK1_D,
+	FN_TS_SPSYNC0_C, FN_GLO_SDATA_B, FN_VI3_DATA1_B,
+	FN_SD2_DAT0, FN_MMC0_D0, FN_FMCLK_B,
+	FN_VI0_DATA2_VI0_B2_B, FN_SCIFB1_RXD_E, FN_RX1_D,
+	FN_TS_SDAT0_C, FN_GLO_SS_B, FN_VI3_DATA2_B,
+	FN_SD2_DAT1, FN_MMC0_D1, FN_FMIN_B, FN_RDS_DATA,
+	FN_VI0_DATA3_VI0_B3_B, FN_SCIFB1_TXD_E, FN_TX1_D,
+	FN_TS_SCK0_C, FN_GLO_RFON_B, FN_VI3_DATA3_B,
+	FN_SD2_DAT2, FN_MMC0_D2, FN_BPFCLK_B, FN_RDS_CLK,
+	FN_VI0_DATA4_VI0_B4_B, FN_HRX0_D, FN_TS_SDEN1_B,
+	FN_GLO_Q0_B, FN_VI3_DATA4_B, FN_SD2_DAT3,
+	FN_MMC0_D3, FN_SIM0_RST, FN_VI0_DATA5_VI0_B5_B,
+	FN_HTX0_D, FN_TS_SPSYNC1_B, FN_GLO_Q1_B,
+	FN_VI3_DATA5_B, FN_SD2_CD, FN_MMC0_D4,
+	FN_TS_SDAT0_B, FN_USB2_EXTP, FN_GLO_I0,
+	FN_VI0_DATA6_VI0_B6_B, FN_HCTS0_N_D, FN_TS_SDAT1_B,
+	FN_GLO_I0_B, FN_VI3_DATA6_B,
+
+	/* IPSR11 */
+	FN_SD2_WP, FN_MMC0_D5, FN_TS_SCK0_B, FN_USB2_IDIN,
+	FN_GLO_I1, FN_VI0_DATA7_VI0_B7_B, FN_HRTS0_N_D,
+	FN_TS_SCK1_B, FN_GLO_I1_B, FN_VI3_DATA7_B,
+	FN_SD3_CLK, FN_MMC1_CLK, FN_SD3_CMD, FN_MMC1_CMD,
+	FN_MTS_N, FN_SD3_DAT0, FN_MMC1_D0, FN_STM_N,
+	FN_SD3_DAT1, FN_MMC1_D1, FN_MDATA, FN_SD3_DAT2,
+	FN_MMC1_D2, FN_SDATA, FN_SD3_DAT3, FN_MMC1_D3,
+	FN_SCKZ, FN_SD3_CD, FN_MMC1_D4, FN_TS_SDAT1,
+	FN_VSP, FN_GLO_Q0, FN_SIM0_RST_B, FN_SD3_WP,
+	FN_MMC1_D5, FN_TS_SCK1, FN_GLO_Q1, FN_FMIN_C,
+	FN_RDS_DATA_B, FN_FMIN_E, FN_RDS_DATA_D, FN_FMIN_F,
+	FN_RDS_DATA_E, FN_MLB_CLK, FN_SCL2_B, FN_SCL2_CIS_B,
+	FN_MLB_SIG, FN_SCIFB1_RXD_D, FN_RX1_C, FN_SDA2_B,
+	FN_SDA2_CIS_B, FN_MLB_DAT, FN_SPV_EVEN,
+	FN_SCIFB1_TXD_D, FN_TX1_C, FN_BPFCLK_C,
+	FN_RDS_CLK_B, FN_SSI_SCK0129, FN_CAN_CLK_B,
+	FN_MOUT0,
+
+	/* IPSR12 */
+	FN_SSI_WS0129, FN_CAN0_TX_B, FN_MOUT1,
+	FN_SSI_SDATA0, FN_CAN0_RX_B, FN_MOUT2,
+	FN_SSI_SDATA1, FN_CAN1_TX_B, FN_MOUT5,
+	FN_SSI_SDATA2, FN_CAN1_RX_B, FN_SSI_SCK1, FN_MOUT6,
+	FN_SSI_SCK34, FN_STP_OPWM_0, FN_SCIFB0_SCK,
+	FN_MSIOF1_SCK, FN_CAN_DEBUG_HW_TRIGGER, FN_SSI_WS34,
+	FN_STP_IVCXO27_0, FN_SCIFB0_RXD, FN_MSIOF1_SYNC,
+	FN_CAN_STEP0, FN_SSI_SDATA3, FN_STP_ISCLK_0,
+	FN_SCIFB0_TXD, FN_MSIOF1_SS1, FN_CAN_TXCLK,
+	FN_SSI_SCK4, FN_STP_ISD_0, FN_SCIFB0_CTS_N,
+	FN_MSIOF1_SS2, FN_SSI_SCK5_C, FN_CAN_DEBUGOUT0,
+	FN_SSI_WS4, FN_STP_ISEN_0, FN_SCIFB0_RTS_N,
+	FN_MSIOF1_TXD, FN_SSI_WS5_C, FN_CAN_DEBUGOUT1,
+	FN_SSI_SDATA4, FN_STP_ISSYNC_0, FN_MSIOF1_RXD,
+	FN_CAN_DEBUGOUT2, FN_SSI_SCK5, FN_SCIFB1_SCK,
+	FN_IERX_B, FN_DU2_EXHSYNC_DU2_HSYNC, FN_QSTH_QHS,
+	FN_CAN_DEBUGOUT3, FN_SSI_WS5, FN_SCIFB1_RXD,
+	FN_IECLK_B, FN_DU2_EXVSYNC_DU2_VSYNC, FN_QSTB_QHE,
+	FN_CAN_DEBUGOUT4,
+
+	/* IPSR13 */
+	FN_SSI_SDATA5, FN_SCIFB1_TXD, FN_IETX_B, FN_DU2_DR2,
+	FN_LCDOUT2, FN_CAN_DEBUGOUT5, FN_SSI_SCK6,
+	FN_SCIFB1_CTS_N, FN_BPFCLK_D, FN_RDS_CLK_C,
+	FN_DU2_DR3, FN_LCDOUT3, FN_CAN_DEBUGOUT6,
+	FN_BPFCLK_F, FN_RDS_CLK_E, FN_SSI_WS6,
+	FN_SCIFB1_RTS_N, FN_CAN0_TX_D, FN_DU2_DR4,
+	FN_LCDOUT4, FN_CAN_DEBUGOUT7, FN_SSI_SDATA6,
+	FN_FMIN_D, FN_RDS_DATA_C, FN_DU2_DR5, FN_LCDOUT5,
+	FN_CAN_DEBUGOUT8, FN_SSI_SCK78, FN_STP_IVCXO27_1,
+	FN_SCK1, FN_SCIFA1_SCK, FN_DU2_DR6, FN_LCDOUT6,
+	FN_CAN_DEBUGOUT9, FN_SSI_WS78, FN_STP_ISCLK_1,
+	FN_SCIFB2_SCK, FN_SCIFA2_CTS_N, FN_DU2_DR7,
+	FN_LCDOUT7, FN_CAN_DEBUGOUT10, FN_SSI_SDATA7,
+	FN_STP_ISD_1, FN_SCIFB2_RXD, FN_SCIFA2_RTS_N,
+	FN_TCLK2, FN_QSTVA_QVS, FN_CAN_DEBUGOUT11,
+	FN_BPFCLK_E, FN_RDS_CLK_D, FN_SSI_SDATA7_B,
+	FN_FMIN_G, FN_RDS_DATA_F, FN_SSI_SDATA8,
+	FN_STP_ISEN_1, FN_SCIFB2_TXD, FN_CAN0_TX_C,
+	FN_CAN_DEBUGOUT12, FN_SSI_SDATA8_B, FN_SSI_SDATA9,
+	FN_STP_ISSYNC_1, FN_SCIFB2_CTS_N, FN_SSI_WS1,
+	FN_SSI_SDATA5_C, FN_CAN_DEBUGOUT13, FN_AUDIO_CLKA,
+	FN_SCIFB2_RTS_N, FN_CAN_DEBUGOUT14,
+
+	/* IPSR14 */
+	FN_AUDIO_CLKB, FN_SCIF_CLK, FN_CAN0_RX_D,
+	FN_DVC_MUTE, FN_CAN0_RX_C, FN_CAN_DEBUGOUT15,
+	FN_REMOCON, FN_SCIFA0_SCK, FN_HSCK1, FN_SCK0,
+	FN_MSIOF3_SS2, FN_DU2_DG2, FN_LCDOUT10, FN_SDA1_C,
+	FN_SDA1_CIS_C, FN_SCIFA0_RXD, FN_HRX1, FN_RX0,
+	FN_DU2_DR0, FN_LCDOUT0, FN_SCIFA0_TXD, FN_HTX1,
+	FN_TX0, FN_DU2_DR1, FN_LCDOUT1, FN_SCIFA0_CTS_N,
+	FN_HCTS1_N, FN_CTS0_N, FN_MSIOF3_SYNC, FN_DU2_DG3,
+	FN_LCDOUT11, FN_PWM0_B, FN_SCL1_C, FN_SCL1_CIS_C,
+	FN_SCIFA0_RTS_N, FN_HRTS1_N, FN_RTS0_N_TANS,
+	FN_MSIOF3_SS1, FN_DU2_DG0, FN_LCDOUT8, FN_PWM1_B,
+	FN_SCIFA1_RXD, FN_AD_DI, FN_RX1,
+	FN_DU2_EXODDF_DU2_ODDF_DISP_CDE, FN_QCPV_QDE,
+	FN_SCIFA1_TXD, FN_AD_DO, FN_TX1, FN_DU2_DG1,
+	FN_LCDOUT9, FN_SCIFA1_CTS_N, FN_AD_CLK,
+	FN_CTS1_N, FN_MSIOF3_RXD, FN_DU0_DOTCLKOUT, FN_QCLK,
+	FN_SCIFA1_RTS_N, FN_AD_NCS_N, FN_RTS1_N_TANS,
+	FN_MSIOF3_TXD, FN_DU1_DOTCLKOUT, FN_QSTVB_QVE,
+	FN_HRTS0_N_C,
+
+	/* IPSR15 */
+	FN_SCIFA2_SCK, FN_FMCLK, FN_MSIOF3_SCK, FN_DU2_DG7,
+	FN_LCDOUT15, FN_SCIF_CLK_B, FN_SCIFA2_RXD, FN_FMIN,
+	FN_DU2_DB0, FN_LCDOUT16, FN_SCL2, FN_SCL2_CIS,
+	FN_SCIFA2_TXD, FN_BPFCLK, FN_DU2_DB1, FN_LCDOUT17,
+	FN_SDA2, FN_SDA2_CIS, FN_HSCK0, FN_TS_SDEN0,
+	FN_DU2_DG4, FN_LCDOUT12, FN_HCTS0_N_C, FN_HRX0,
+	FN_DU2_DB2, FN_LCDOUT18, FN_HTX0, FN_DU2_DB3,
+	FN_LCDOUT19, FN_HCTS0_N, FN_SSI_SCK9, FN_DU2_DB4,
+	FN_LCDOUT20, FN_HRTS0_N, FN_SSI_WS9, FN_DU2_DB5,
+	FN_LCDOUT21, FN_MSIOF0_SCK, FN_TS_SDAT0, FN_ADICLK,
+	FN_DU2_DB6, FN_LCDOUT22, FN_MSIOF0_SYNC, FN_TS_SCK0,
+	FN_SSI_SCK2, FN_ADIDATA, FN_DU2_DB7, FN_LCDOUT23,
+	FN_SCIFA2_RXD_B, FN_MSIOF0_SS1, FN_ADICHS0,
+	FN_DU2_DG5, FN_LCDOUT13, FN_MSIOF0_TXD, FN_ADICHS1,
+	FN_DU2_DG6, FN_LCDOUT14,
+
+	/* IPSR16 */
+	FN_MSIOF0_SS2, FN_AUDIO_CLKOUT, FN_ADICHS2,
+	FN_DU2_DISP, FN_QPOLA, FN_HTX0_C, FN_SCIFA2_TXD_B,
+	FN_MSIOF0_RXD, FN_TS_SPSYNC0, FN_SSI_WS2,
+	FN_ADICS_SAMP, FN_DU2_CDE, FN_QPOLB, FN_HRX0_C,
+	FN_USB1_PWEN, FN_AUDIO_CLKOUT_D, FN_USB1_OVC,
+	FN_TCLK1_B,
+
+	FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3,
+	FN_SEL_SCIF1_4,
+	FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2,
+	FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, FN_SEL_SCIFB2_2,
+	FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, FN_SEL_SCIFB1_2, FN_SEL_SCIFB1_3,
+	FN_SEL_SCIFB1_4,
+	FN_SEL_SCIFB1_5, FN_SEL_SCIFB1_6,
+	FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, FN_SEL_SCIFA1_3,
+	FN_SEL_SCIF0_0, FN_SEL_SCIF0_1,
+	FN_SEL_SCFA_0, FN_SEL_SCFA_1,
+	FN_SEL_SOF1_0, FN_SEL_SOF1_1,
+	FN_SEL_SSI7_0, FN_SEL_SSI7_1, FN_SEL_SSI7_2,
+	FN_SEL_SSI6_0, FN_SEL_SSI6_1,
+	FN_SEL_SSI5_0, FN_SEL_SSI5_1, FN_SEL_SSI5_2,
+	FN_SEL_VI3_0, FN_SEL_VI3_1,
+	FN_SEL_VI2_0, FN_SEL_VI2_1,
+	FN_SEL_VI1_0, FN_SEL_VI1_1,
+	FN_SEL_VI0_0, FN_SEL_VI0_1,
+	FN_SEL_TSIF1_0, FN_SEL_TSIF1_1, FN_SEL_TSIF1_2,
+	FN_SEL_LBS_0, FN_SEL_LBS_1,
+	FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3,
+	FN_SEL_SOF3_0, FN_SEL_SOF3_1,
+	FN_SEL_SOF0_0, FN_SEL_SOF0_1,
+
+	FN_SEL_TMU1_0, FN_SEL_TMU1_1,
+	FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1,
+	FN_SEL_SCIFCLK_0, FN_SEL_SCIFCLK_1,
+	FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3,
+	FN_SEL_CANCLK_0, FN_SEL_CANCLK_1,
+	FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, FN_SEL_SCIFA2_2,
+	FN_SEL_CAN1_0, FN_SEL_CAN1_1,
+	FN_SEL_ADI_0, FN_SEL_ADI_1,
+	FN_SEL_SSP_0, FN_SEL_SSP_1,
+	FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, FN_SEL_FM_3,
+	FN_SEL_FM_4, FN_SEL_FM_5, FN_SEL_FM_6,
+	FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2, FN_SEL_HSCIF0_3,
+	FN_SEL_HSCIF0_4, FN_SEL_HSCIF0_5,
+	FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2,
+	FN_SEL_RDS_0, FN_SEL_RDS_1, FN_SEL_RDS_2,
+	FN_SEL_RDS_3, FN_SEL_RDS_4, FN_SEL_RDS_5,
+	FN_SEL_SIM_0, FN_SEL_SIM_1, FN_SEL_SIM_2,
+	FN_SEL_SSI8_0, FN_SEL_SSI8_1, FN_SEL_SSI8_2,
+
+	FN_SEL_IICDVFS_0, FN_SEL_IICDVFS_1,
+	FN_SEL_IIC0_0, FN_SEL_IIC0_1,
+	FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2,
+	FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3,
+	FN_SEL_IIC2_4,
+	FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2,
+	FN_SEL_I2C2_0, FN_SEL_I2C2_1, FN_SEL_I2C2_2, FN_SEL_I2C2_3,
+	FN_SEL_I2C2_4,
+	FN_SEL_I2C1_0, FN_SEL_I2C1_1, FN_SEL_I2C1_2,
+	PINMUX_FUNCTION_END,
+
+	PINMUX_MARK_BEGIN,
+
+	VI1_DATA7_VI1_B7_MARK,
+
+	USB0_PWEN_MARK, USB0_OVC_VBUS_MARK,
+	USB2_PWEN_MARK, USB2_OVC_MARK, AVS1_MARK, AVS2_MARK,
+	DU_DOTCLKIN0_MARK, DU_DOTCLKIN2_MARK,
+
+	D0_MARK, MSIOF3_SCK_B_MARK, VI3_DATA0_MARK, VI0_G4_MARK, VI0_G4_B_MARK,
+	D1_MARK, MSIOF3_SYNC_B_MARK, VI3_DATA1_MARK, VI0_G5_MARK,
+	VI0_G5_B_MARK, D2_MARK, MSIOF3_RXD_B_MARK, VI3_DATA2_MARK,
+	VI0_G6_MARK, VI0_G6_B_MARK, D3_MARK, MSIOF3_TXD_B_MARK,
+	VI3_DATA3_MARK, VI0_G7_MARK, VI0_G7_B_MARK, D4_MARK,
+	SCIFB1_RXD_F_MARK, SCIFB0_RXD_C_MARK, VI3_DATA4_MARK,
+	VI0_R0_MARK, VI0_R0_B_MARK, RX0_B_MARK, D5_MARK,
+	SCIFB1_TXD_F_MARK, SCIFB0_TXD_C_MARK, VI3_DATA5_MARK,
+	VI0_R1_MARK, VI0_R1_B_MARK, TX0_B_MARK, D6_MARK,
+	SCL2_C_MARK, VI3_DATA6_MARK, VI0_R2_MARK, VI0_R2_B_MARK,
+	SCL2_CIS_C_MARK, D7_MARK, AD_DI_B_MARK, SDA2_C_MARK,
+	VI3_DATA7_MARK, VI0_R3_MARK, VI0_R3_B_MARK, SDA2_CIS_C_MARK,
+	D8_MARK, SCIFA1_SCK_C_MARK, AVB_TXD0_MARK, MII_TXD0_MARK,
+	VI0_G0_MARK, VI0_G0_B_MARK, VI2_DATA0_VI2_B0_MARK,
+
+	D9_MARK, SCIFA1_RXD_C_MARK, AVB_TXD1_MARK, MII_TXD1_MARK,
+	VI0_G1_MARK, VI0_G1_B_MARK, VI2_DATA1_VI2_B1_MARK, D10_MARK,
+	SCIFA1_TXD_C_MARK, AVB_TXD2_MARK, MII_TXD2_MARK,
+	VI0_G2_MARK, VI0_G2_B_MARK, VI2_DATA2_VI2_B2_MARK, D11_MARK,
+	SCIFA1_CTS_N_C_MARK, AVB_TXD3_MARK, MII_TXD3_MARK,
+	VI0_G3_MARK, VI0_G3_B_MARK, VI2_DATA3_VI2_B3_MARK,
+	D12_MARK, SCIFA1_RTS_N_C_MARK, AVB_TXD4_MARK,
+	VI0_HSYNC_N_MARK, VI0_HSYNC_N_B_MARK, VI2_DATA4_VI2_B4_MARK,
+	D13_MARK, AVB_TXD5_MARK, VI0_VSYNC_N_MARK,
+	VI0_VSYNC_N_B_MARK, VI2_DATA5_VI2_B5_MARK, D14_MARK,
+	SCIFB1_RXD_C_MARK, AVB_TXD6_MARK, RX1_B_MARK,
+	VI0_CLKENB_MARK, VI0_CLKENB_B_MARK, VI2_DATA6_VI2_B6_MARK,
+	D15_MARK, SCIFB1_TXD_C_MARK, AVB_TXD7_MARK, TX1_B_MARK,
+	VI0_FIELD_MARK, VI0_FIELD_B_MARK, VI2_DATA7_VI2_B7_MARK,
+	A0_MARK, PWM3_MARK, A1_MARK, PWM4_MARK,
+
+	A2_MARK, PWM5_MARK, MSIOF1_SS1_B_MARK, A3_MARK,
+	PWM6_MARK, MSIOF1_SS2_B_MARK, A4_MARK, MSIOF1_TXD_B_MARK,
+	TPU0TO0_MARK, A5_MARK, SCIFA1_TXD_B_MARK, TPU0TO1_MARK,
+	A6_MARK, SCIFA1_RTS_N_B_MARK, TPU0TO2_MARK, A7_MARK,
+	SCIFA1_SCK_B_MARK, AUDIO_CLKOUT_B_MARK, TPU0TO3_MARK,
+	A8_MARK, SCIFA1_RXD_B_MARK, SSI_SCK5_B_MARK, VI0_R4_MARK,
+	VI0_R4_B_MARK, SCIFB2_RXD_C_MARK, VI2_DATA0_VI2_B0_B_MARK,
+	A9_MARK, SCIFA1_CTS_N_B_MARK, SSI_WS5_B_MARK, VI0_R5_MARK,
+	VI0_R5_B_MARK, SCIFB2_TXD_C_MARK, VI2_DATA1_VI2_B1_B_MARK,
+	A10_MARK, SSI_SDATA5_B_MARK, MSIOF2_SYNC_MARK, VI0_R6_MARK,
+	VI0_R6_B_MARK, VI2_DATA2_VI2_B2_B_MARK,
+
+	A11_MARK, SCIFB2_CTS_N_B_MARK, MSIOF2_SCK_MARK, VI1_R0_MARK,
+	VI1_R0_B_MARK, VI2_G0_MARK, VI2_DATA3_VI2_B3_B_MARK,
+	A12_MARK, SCIFB2_RXD_B_MARK, MSIOF2_TXD_MARK, VI1_R1_MARK,
+	VI1_R1_B_MARK, VI2_G1_MARK, VI2_DATA4_VI2_B4_B_MARK,
+	A13_MARK, SCIFB2_RTS_N_B_MARK, EX_WAIT2_MARK,
+	MSIOF2_RXD_MARK, VI1_R2_MARK, VI1_R2_B_MARK, VI2_G2_MARK,
+	VI2_DATA5_VI2_B5_B_MARK, A14_MARK, SCIFB2_TXD_B_MARK,
+	ATACS11_N_MARK, MSIOF2_SS1_MARK, A15_MARK, SCIFB2_SCK_B_MARK,
+	ATARD1_N_MARK, MSIOF2_SS2_MARK, A16_MARK, ATAWR1_N_MARK,
+	A17_MARK, AD_DO_B_MARK, ATADIR1_N_MARK, A18_MARK,
+	AD_CLK_B_MARK, ATAG1_N_MARK, A19_MARK, AD_NCS_N_B_MARK,
+	ATACS01_N_MARK, EX_WAIT0_B_MARK, A20_MARK, SPCLK_MARK,
+	VI1_R3_MARK, VI1_R3_B_MARK, VI2_G4_MARK,
+
+	A21_MARK, MOSI_IO0_MARK, VI1_R4_MARK, VI1_R4_B_MARK, VI2_G5_MARK,
+	A22_MARK, MISO_IO1_MARK, VI1_R5_MARK, VI1_R5_B_MARK,
+	VI2_G6_MARK, A23_MARK, IO2_MARK, VI1_G7_MARK,
+	VI1_G7_B_MARK, VI2_G7_MARK, A24_MARK, IO3_MARK,
+	VI1_R7_MARK, VI1_R7_B_MARK, VI2_CLKENB_MARK,
+	VI2_CLKENB_B_MARK, A25_MARK, SSL_MARK, VI1_G6_MARK,
+	VI1_G6_B_MARK, VI2_FIELD_MARK, VI2_FIELD_B_MARK, CS0_N_MARK,
+	VI1_R6_MARK, VI1_R6_B_MARK, VI2_G3_MARK, MSIOF0_SS2_B_MARK,
+	CS1_N_A26_MARK, SPEEDIN_MARK, VI0_R7_MARK, VI0_R7_B_MARK,
+	VI2_CLK_MARK, VI2_CLK_B_MARK, EX_CS0_N_MARK, HRX1_B_MARK,
+	VI1_G5_MARK, VI1_G5_B_MARK, VI2_R0_MARK, HTX0_B_MARK,
+	MSIOF0_SS1_B_MARK, EX_CS1_N_MARK, GPS_CLK_MARK,
+	HCTS1_N_B_MARK, VI1_FIELD_MARK, VI1_FIELD_B_MARK,
+	VI2_R1_MARK, EX_CS2_N_MARK, GPS_SIGN_MARK, HRTS1_N_B_MARK,
+	VI3_CLKENB_MARK, VI1_G0_MARK, VI1_G0_B_MARK, VI2_R2_MARK,
+
+	EX_CS3_N_MARK, GPS_MAG_MARK, VI3_FIELD_MARK,
+	VI1_G1_MARK, VI1_G1_B_MARK, VI2_R3_MARK,
+	EX_CS4_N_MARK, MSIOF1_SCK_B_MARK, VI3_HSYNC_N_MARK,
+	VI2_HSYNC_N_MARK, SCL1_MARK, VI2_HSYNC_N_B_MARK,
+	INTC_EN0_N_MARK, SCL1_CIS_MARK, EX_CS5_N_MARK, CAN0_RX_MARK,
+	MSIOF1_RXD_B_MARK, VI3_VSYNC_N_MARK, VI1_G2_MARK,
+	VI1_G2_B_MARK, VI2_R4_MARK, SDA1_MARK, INTC_EN1_N_MARK,
+	SDA1_CIS_MARK, BS_N_MARK, IETX_MARK, HTX1_B_MARK,
+	CAN1_TX_MARK, DRACK0_MARK, IETX_C_MARK, RD_N_MARK,
+	CAN0_TX_MARK, SCIFA0_SCK_B_MARK, RD_WR_N_MARK, VI1_G3_MARK,
+	VI1_G3_B_MARK, VI2_R5_MARK, SCIFA0_RXD_B_MARK,
+	INTC_IRQ4_N_MARK, WE0_N_MARK, IECLK_MARK, CAN_CLK_MARK,
+	VI2_VSYNC_N_MARK, SCIFA0_TXD_B_MARK, VI2_VSYNC_N_B_MARK,
+	WE1_N_MARK, IERX_MARK, CAN1_RX_MARK, VI1_G4_MARK,
+	VI1_G4_B_MARK, VI2_R6_MARK, SCIFA0_CTS_N_B_MARK,
+	IERX_C_MARK, EX_WAIT0_MARK, IRQ3_MARK, INTC_IRQ3_N_MARK,
+	VI3_CLK_MARK, SCIFA0_RTS_N_B_MARK, HRX0_B_MARK,
+	MSIOF0_SCK_B_MARK, DREQ0_N_MARK, VI1_HSYNC_N_MARK,
+	VI1_HSYNC_N_B_MARK, VI2_R7_MARK, SSI_SCK78_C_MARK,
+	SSI_WS78_B_MARK,
+
+	DACK0_MARK, IRQ0_MARK, INTC_IRQ0_N_MARK, SSI_SCK6_B_MARK,
+	VI1_VSYNC_N_MARK, VI1_VSYNC_N_B_MARK, SSI_WS78_C_MARK,
+	DREQ1_N_MARK, VI1_CLKENB_MARK, VI1_CLKENB_B_MARK,
+	SSI_SDATA7_C_MARK, SSI_SCK78_B_MARK, DACK1_MARK, IRQ1_MARK,
+	INTC_IRQ1_N_MARK, SSI_WS6_B_MARK, SSI_SDATA8_C_MARK,
+	DREQ2_N_MARK, HSCK1_B_MARK, HCTS0_N_B_MARK,
+	MSIOF0_TXD_B_MARK, DACK2_MARK, IRQ2_MARK, INTC_IRQ2_N_MARK,
+	SSI_SDATA6_B_MARK, HRTS0_N_B_MARK, MSIOF0_RXD_B_MARK,
+	ETH_CRS_DV_MARK, RMII_CRS_DV_MARK, STP_ISCLK_0_B_MARK,
+	TS_SDEN0_D_MARK, GLO_Q0_C_MARK, SCL2_E_MARK,
+	SCL2_CIS_E_MARK, ETH_RX_ER_MARK, RMII_RX_ER_MARK,
+	STP_ISD_0_B_MARK, TS_SPSYNC0_D_MARK, GLO_Q1_C_MARK,
+	SDA2_E_MARK, SDA2_CIS_E_MARK, ETH_RXD0_MARK, RMII_RXD0_MARK,
+	STP_ISEN_0_B_MARK, TS_SDAT0_D_MARK, GLO_I0_C_MARK,
+	SCIFB1_SCK_G_MARK, SCK1_E_MARK, ETH_RXD1_MARK,
+	RMII_RXD1_MARK, HRX0_E_MARK, STP_ISSYNC_0_B_MARK,
+	TS_SCK0_D_MARK, GLO_I1_C_MARK, SCIFB1_RXD_G_MARK,
+	RX1_E_MARK, ETH_LINK_MARK, RMII_LINK_MARK, HTX0_E_MARK,
+	STP_IVCXO27_0_B_MARK, SCIFB1_TXD_G_MARK, TX1_E_MARK,
+	ETH_REF_CLK_MARK, RMII_REF_CLK_MARK, HCTS0_N_E_MARK,
+	STP_IVCXO27_1_B_MARK, HRX0_F_MARK,
+
+	ETH_MDIO_MARK, RMII_MDIO_MARK, HRTS0_N_E_MARK,
+	SIM0_D_C_MARK, HCTS0_N_F_MARK, ETH_TXD1_MARK,
+	RMII_TXD1_MARK, HTX0_F_MARK, BPFCLK_G_MARK, RDS_CLK_F_MARK,
+	ETH_TX_EN_MARK, RMII_TX_EN_MARK, SIM0_CLK_C_MARK,
+	HRTS0_N_F_MARK, ETH_MAGIC_MARK, RMII_MAGIC_MARK,
+	SIM0_RST_C_MARK, ETH_TXD0_MARK, RMII_TXD0_MARK,
+	STP_ISCLK_1_B_MARK, TS_SDEN1_C_MARK, GLO_SCLK_C_MARK,
+	ETH_MDC_MARK, RMII_MDC_MARK, STP_ISD_1_B_MARK,
+	TS_SPSYNC1_C_MARK, GLO_SDATA_C_MARK, PWM0_MARK,
+	SCIFA2_SCK_C_MARK, STP_ISEN_1_B_MARK, TS_SDAT1_C_MARK,
+	GLO_SS_C_MARK, PWM1_MARK, SCIFA2_TXD_C_MARK,
+	STP_ISSYNC_1_B_MARK, TS_SCK1_C_MARK, GLO_RFON_C_MARK,
+	PCMOE_N_MARK, PWM2_MARK, PWMFSW0_MARK, SCIFA2_RXD_C_MARK,
+	PCMWE_N_MARK, IECLK_C_MARK, DU1_DOTCLKIN_MARK,
+	AUDIO_CLKC_MARK, AUDIO_CLKOUT_C_MARK, VI0_CLK_MARK,
+	ATACS00_N_MARK, AVB_RXD1_MARK, MII_RXD1_MARK,
+	VI0_DATA0_VI0_B0_MARK, ATACS10_N_MARK, AVB_RXD2_MARK,
+	MII_RXD2_MARK,
+
+	VI0_DATA1_VI0_B1_MARK, ATARD0_N_MARK, AVB_RXD3_MARK,
+	MII_RXD3_MARK, VI0_DATA2_VI0_B2_MARK, ATAWR0_N_MARK,
+	AVB_RXD4_MARK, VI0_DATA3_VI0_B3_MARK, ATADIR0_N_MARK,
+	AVB_RXD5_MARK, VI0_DATA4_VI0_B4_MARK, ATAG0_N_MARK,
+	AVB_RXD6_MARK, VI0_DATA5_VI0_B5_MARK, EX_WAIT1_MARK,
+	AVB_RXD7_MARK, VI0_DATA6_VI0_B6_MARK, AVB_RX_ER_MARK,
+	MII_RX_ER_MARK, VI0_DATA7_VI0_B7_MARK, AVB_RX_CLK_MARK,
+	MII_RX_CLK_MARK, VI1_CLK_MARK, AVB_RX_DV_MARK,
+	MII_RX_DV_MARK, VI1_DATA0_VI1_B0_MARK, SCIFA1_SCK_D_MARK,
+	AVB_CRS_MARK, MII_CRS_MARK, VI1_DATA1_VI1_B1_MARK,
+	SCIFA1_RXD_D_MARK, AVB_MDC_MARK, MII_MDC_MARK,
+	VI1_DATA2_VI1_B2_MARK, SCIFA1_TXD_D_MARK, AVB_MDIO_MARK,
+	MII_MDIO_MARK, VI1_DATA3_VI1_B3_MARK, SCIFA1_CTS_N_D_MARK,
+	AVB_GTX_CLK_MARK, VI1_DATA4_VI1_B4_MARK, SCIFA1_RTS_N_D_MARK,
+	AVB_MAGIC_MARK, MII_MAGIC_MARK, VI1_DATA5_VI1_B5_MARK,
+	AVB_PHY_INT_MARK, VI1_DATA6_VI1_B6_MARK, AVB_GTXREFCLK_MARK,
+	SD0_CLK_MARK, VI1_DATA0_VI1_B0_B_MARK, SD0_CMD_MARK,
+	SCIFB1_SCK_B_MARK, VI1_DATA1_VI1_B1_B_MARK,
+
+	SD0_DAT0_MARK, SCIFB1_RXD_B_MARK, VI1_DATA2_VI1_B2_B_MARK,
+	SD0_DAT1_MARK, SCIFB1_TXD_B_MARK, VI1_DATA3_VI1_B3_B_MARK,
+	SD0_DAT2_MARK, SCIFB1_CTS_N_B_MARK, VI1_DATA4_VI1_B4_B_MARK,
+	SD0_DAT3_MARK, SCIFB1_RTS_N_B_MARK, VI1_DATA5_VI1_B5_B_MARK,
+	SD0_CD_MARK, MMC0_D6_MARK, TS_SDEN0_B_MARK, USB0_EXTP_MARK,
+	GLO_SCLK_MARK, VI1_DATA6_VI1_B6_B_MARK, SCL1_B_MARK,
+	SCL1_CIS_B_MARK, VI2_DATA6_VI2_B6_B_MARK, SD0_WP_MARK,
+	MMC0_D7_MARK, TS_SPSYNC0_B_MARK, USB0_IDIN_MARK,
+	GLO_SDATA_MARK, VI1_DATA7_VI1_B7_B_MARK, SDA1_B_MARK,
+	SDA1_CIS_B_MARK, VI2_DATA7_VI2_B7_B_MARK, SD1_CLK_MARK,
+	AVB_TX_EN_MARK, MII_TX_EN_MARK, SD1_CMD_MARK,
+	AVB_TX_ER_MARK, MII_TX_ER_MARK, SCIFB0_SCK_B_MARK,
+	SD1_DAT0_MARK, AVB_TX_CLK_MARK, MII_TX_CLK_MARK,
+	SCIFB0_RXD_B_MARK, SD1_DAT1_MARK, AVB_LINK_MARK,
+	MII_LINK_MARK, SCIFB0_TXD_B_MARK, SD1_DAT2_MARK,
+	AVB_COL_MARK, MII_COL_MARK, SCIFB0_CTS_N_B_MARK,
+	SD1_DAT3_MARK, AVB_RXD0_MARK, MII_RXD0_MARK,
+	SCIFB0_RTS_N_B_MARK, SD1_CD_MARK, MMC1_D6_MARK,
+	TS_SDEN1_MARK, USB1_EXTP_MARK, GLO_SS_MARK, VI0_CLK_B_MARK,
+	SCL2_D_MARK, SCL2_CIS_D_MARK, SIM0_CLK_B_MARK,
+	VI3_CLK_B_MARK,
+
+	SD1_WP_MARK, MMC1_D7_MARK, TS_SPSYNC1_MARK, USB1_IDIN_MARK,
+	GLO_RFON_MARK, VI1_CLK_B_MARK, SDA2_D_MARK, SDA2_CIS_D_MARK,
+	SIM0_D_B_MARK, SD2_CLK_MARK, MMC0_CLK_MARK, SIM0_CLK_MARK,
+	VI0_DATA0_VI0_B0_B_MARK, TS_SDEN0_C_MARK, GLO_SCLK_B_MARK,
+	VI3_DATA0_B_MARK, SD2_CMD_MARK, MMC0_CMD_MARK, SIM0_D_MARK,
+	VI0_DATA1_VI0_B1_B_MARK, SCIFB1_SCK_E_MARK, SCK1_D_MARK,
+	TS_SPSYNC0_C_MARK, GLO_SDATA_B_MARK, VI3_DATA1_B_MARK,
+	SD2_DAT0_MARK, MMC0_D0_MARK, FMCLK_B_MARK,
+	VI0_DATA2_VI0_B2_B_MARK, SCIFB1_RXD_E_MARK, RX1_D_MARK,
+	TS_SDAT0_C_MARK, GLO_SS_B_MARK, VI3_DATA2_B_MARK,
+	SD2_DAT1_MARK, MMC0_D1_MARK, FMIN_B_MARK, RDS_DATA_MARK,
+	VI0_DATA3_VI0_B3_B_MARK, SCIFB1_TXD_E_MARK, TX1_D_MARK,
+	TS_SCK0_C_MARK, GLO_RFON_B_MARK, VI3_DATA3_B_MARK,
+	SD2_DAT2_MARK, MMC0_D2_MARK, BPFCLK_B_MARK, RDS_CLK_MARK,
+	VI0_DATA4_VI0_B4_B_MARK, HRX0_D_MARK, TS_SDEN1_B_MARK,
+	GLO_Q0_B_MARK, VI3_DATA4_B_MARK, SD2_DAT3_MARK,
+	MMC0_D3_MARK, SIM0_RST_MARK, VI0_DATA5_VI0_B5_B_MARK,
+	HTX0_D_MARK, TS_SPSYNC1_B_MARK, GLO_Q1_B_MARK,
+	VI3_DATA5_B_MARK, SD2_CD_MARK, MMC0_D4_MARK,
+	TS_SDAT0_B_MARK, USB2_EXTP_MARK, GLO_I0_MARK,
+	VI0_DATA6_VI0_B6_B_MARK, HCTS0_N_D_MARK, TS_SDAT1_B_MARK,
+	GLO_I0_B_MARK, VI3_DATA6_B_MARK,
+
+	SD2_WP_MARK, MMC0_D5_MARK, TS_SCK0_B_MARK, USB2_IDIN_MARK,
+	GLO_I1_MARK, VI0_DATA7_VI0_B7_B_MARK, HRTS0_N_D_MARK,
+	TS_SCK1_B_MARK, GLO_I1_B_MARK, VI3_DATA7_B_MARK,
+	SD3_CLK_MARK, MMC1_CLK_MARK, SD3_CMD_MARK, MMC1_CMD_MARK,
+	MTS_N_MARK, SD3_DAT0_MARK, MMC1_D0_MARK, STM_N_MARK,
+	SD3_DAT1_MARK, MMC1_D1_MARK, MDATA_MARK, SD3_DAT2_MARK,
+	MMC1_D2_MARK, SDATA_MARK, SD3_DAT3_MARK, MMC1_D3_MARK,
+	SCKZ_MARK, SD3_CD_MARK, MMC1_D4_MARK, TS_SDAT1_MARK,
+	VSP_MARK, GLO_Q0_MARK, SIM0_RST_B_MARK, SD3_WP_MARK,
+	MMC1_D5_MARK, TS_SCK1_MARK, GLO_Q1_MARK, FMIN_C_MARK,
+	RDS_DATA_B_MARK, FMIN_E_MARK, RDS_DATA_D_MARK, FMIN_F_MARK,
+	RDS_DATA_E_MARK, MLB_CLK_MARK, SCL2_B_MARK, SCL2_CIS_B_MARK,
+	MLB_SIG_MARK, SCIFB1_RXD_D_MARK, RX1_C_MARK, SDA2_B_MARK,
+	SDA2_CIS_B_MARK, MLB_DAT_MARK, SPV_EVEN_MARK,
+	SCIFB1_TXD_D_MARK, TX1_C_MARK, BPFCLK_C_MARK,
+	RDS_CLK_B_MARK, SSI_SCK0129_MARK, CAN_CLK_B_MARK,
+	MOUT0_MARK,
+
+	SSI_WS0129_MARK, CAN0_TX_B_MARK, MOUT1_MARK,
+	SSI_SDATA0_MARK, CAN0_RX_B_MARK, MOUT2_MARK,
+	SSI_SDATA1_MARK, CAN1_TX_B_MARK, MOUT5_MARK,
+	SSI_SDATA2_MARK, CAN1_RX_B_MARK, SSI_SCK1_MARK, MOUT6_MARK,
+	SSI_SCK34_MARK, STP_OPWM_0_MARK, SCIFB0_SCK_MARK,
+	MSIOF1_SCK_MARK, CAN_DEBUG_HW_TRIGGER_MARK, SSI_WS34_MARK,
+	STP_IVCXO27_0_MARK, SCIFB0_RXD_MARK, MSIOF1_SYNC_MARK,
+	CAN_STEP0_MARK, SSI_SDATA3_MARK, STP_ISCLK_0_MARK,
+	SCIFB0_TXD_MARK, MSIOF1_SS1_MARK, CAN_TXCLK_MARK,
+	SSI_SCK4_MARK, STP_ISD_0_MARK, SCIFB0_CTS_N_MARK,
+	MSIOF1_SS2_MARK, SSI_SCK5_C_MARK, CAN_DEBUGOUT0_MARK,
+	SSI_WS4_MARK, STP_ISEN_0_MARK, SCIFB0_RTS_N_MARK,
+	MSIOF1_TXD_MARK, SSI_WS5_C_MARK, CAN_DEBUGOUT1_MARK,
+	SSI_SDATA4_MARK, STP_ISSYNC_0_MARK, MSIOF1_RXD_MARK,
+	CAN_DEBUGOUT2_MARK, SSI_SCK5_MARK, SCIFB1_SCK_MARK,
+	IERX_B_MARK, DU2_EXHSYNC_DU2_HSYNC_MARK, QSTH_QHS_MARK,
+	CAN_DEBUGOUT3_MARK, SSI_WS5_MARK, SCIFB1_RXD_MARK,
+	IECLK_B_MARK, DU2_EXVSYNC_DU2_VSYNC_MARK, QSTB_QHE_MARK,
+	CAN_DEBUGOUT4_MARK,
+
+	SSI_SDATA5_MARK, SCIFB1_TXD_MARK, IETX_B_MARK, DU2_DR2_MARK,
+	LCDOUT2_MARK, CAN_DEBUGOUT5_MARK, SSI_SCK6_MARK,
+	SCIFB1_CTS_N_MARK, BPFCLK_D_MARK, RDS_CLK_C_MARK,
+	DU2_DR3_MARK, LCDOUT3_MARK, CAN_DEBUGOUT6_MARK,
+	BPFCLK_F_MARK, RDS_CLK_E_MARK, SSI_WS6_MARK,
+	SCIFB1_RTS_N_MARK, CAN0_TX_D_MARK, DU2_DR4_MARK,
+	LCDOUT4_MARK, CAN_DEBUGOUT7_MARK, SSI_SDATA6_MARK,
+	FMIN_D_MARK, RDS_DATA_C_MARK, DU2_DR5_MARK, LCDOUT5_MARK,
+	CAN_DEBUGOUT8_MARK, SSI_SCK78_MARK, STP_IVCXO27_1_MARK,
+	SCK1_MARK, SCIFA1_SCK_MARK, DU2_DR6_MARK, LCDOUT6_MARK,
+	CAN_DEBUGOUT9_MARK, SSI_WS78_MARK, STP_ISCLK_1_MARK,
+	SCIFB2_SCK_MARK, SCIFA2_CTS_N_MARK, DU2_DR7_MARK,
+	LCDOUT7_MARK, CAN_DEBUGOUT10_MARK, SSI_SDATA7_MARK,
+	STP_ISD_1_MARK, SCIFB2_RXD_MARK, SCIFA2_RTS_N_MARK,
+	TCLK2_MARK, QSTVA_QVS_MARK, CAN_DEBUGOUT11_MARK,
+	BPFCLK_E_MARK, RDS_CLK_D_MARK, SSI_SDATA7_B_MARK,
+	FMIN_G_MARK, RDS_DATA_F_MARK, SSI_SDATA8_MARK,
+	STP_ISEN_1_MARK, SCIFB2_TXD_MARK, CAN0_TX_C_MARK,
+	CAN_DEBUGOUT12_MARK, SSI_SDATA8_B_MARK, SSI_SDATA9_MARK,
+	STP_ISSYNC_1_MARK, SCIFB2_CTS_N_MARK, SSI_WS1_MARK,
+	SSI_SDATA5_C_MARK, CAN_DEBUGOUT13_MARK, AUDIO_CLKA_MARK,
+	SCIFB2_RTS_N_MARK, CAN_DEBUGOUT14_MARK,
+
+	AUDIO_CLKB_MARK, SCIF_CLK_MARK, CAN0_RX_D_MARK,
+	DVC_MUTE_MARK, CAN0_RX_C_MARK, CAN_DEBUGOUT15_MARK,
+	REMOCON_MARK, SCIFA0_SCK_MARK, HSCK1_MARK, SCK0_MARK,
+	MSIOF3_SS2_MARK, DU2_DG2_MARK, LCDOUT10_MARK, SDA1_C_MARK,
+	SDA1_CIS_C_MARK, SCIFA0_RXD_MARK, HRX1_MARK, RX0_MARK,
+	DU2_DR0_MARK, LCDOUT0_MARK, SCIFA0_TXD_MARK, HTX1_MARK,
+	TX0_MARK, DU2_DR1_MARK, LCDOUT1_MARK, SCIFA0_CTS_N_MARK,
+	HCTS1_N_MARK, CTS0_N_MARK, MSIOF3_SYNC_MARK, DU2_DG3_MARK,
+	LCDOUT11_MARK, PWM0_B_MARK, SCL1_C_MARK, SCL1_CIS_C_MARK,
+	SCIFA0_RTS_N_MARK, HRTS1_N_MARK, RTS0_N_TANS_MARK,
+	MSIOF3_SS1_MARK, DU2_DG0_MARK, LCDOUT8_MARK, PWM1_B_MARK,
+	SCIFA1_RXD_MARK, AD_DI_MARK, RX1_MARK,
+	DU2_EXODDF_DU2_ODDF_DISP_CDE_MARK, QCPV_QDE_MARK,
+	SCIFA1_TXD_MARK, AD_DO_MARK, TX1_MARK, DU2_DG1_MARK,
+	LCDOUT9_MARK, SCIFA1_CTS_N_MARK, AD_CLK_MARK,
+	CTS1_N_MARK, MSIOF3_RXD_MARK, DU0_DOTCLKOUT_MARK, QCLK_MARK,
+	SCIFA1_RTS_N_MARK, AD_NCS_N_MARK, RTS1_N_TANS_MARK,
+	MSIOF3_TXD_MARK, DU1_DOTCLKOUT_MARK, QSTVB_QVE_MARK,
+	HRTS0_N_C_MARK,
+
+	SCIFA2_SCK_MARK, FMCLK_MARK, MSIOF3_SCK_MARK, DU2_DG7_MARK,
+	LCDOUT15_MARK, SCIF_CLK_B_MARK, SCIFA2_RXD_MARK, FMIN_MARK,
+	DU2_DB0_MARK, LCDOUT16_MARK, SCL2_MARK, SCL2_CIS_MARK,
+	SCIFA2_TXD_MARK, BPFCLK_MARK, DU2_DB1_MARK, LCDOUT17_MARK,
+	SDA2_MARK, SDA2_CIS_MARK, HSCK0_MARK, TS_SDEN0_MARK,
+	DU2_DG4_MARK, LCDOUT12_MARK, HCTS0_N_C_MARK, HRX0_MARK,
+	DU2_DB2_MARK, LCDOUT18_MARK, HTX0_MARK, DU2_DB3_MARK,
+	LCDOUT19_MARK, HCTS0_N_MARK, SSI_SCK9_MARK, DU2_DB4_MARK,
+	LCDOUT20_MARK, HRTS0_N_MARK, SSI_WS9_MARK, DU2_DB5_MARK,
+	LCDOUT21_MARK, MSIOF0_SCK_MARK, TS_SDAT0_MARK, ADICLK_MARK,
+	DU2_DB6_MARK, LCDOUT22_MARK, MSIOF0_SYNC_MARK, TS_SCK0_MARK,
+	SSI_SCK2_MARK, ADIDATA_MARK, DU2_DB7_MARK, LCDOUT23_MARK,
+	SCIFA2_RXD_B_MARK, MSIOF0_SS1_MARK, ADICHS0_MARK,
+	DU2_DG5_MARK, LCDOUT13_MARK, MSIOF0_TXD_MARK, ADICHS1_MARK,
+	DU2_DG6_MARK, LCDOUT14_MARK,
+
+	MSIOF0_SS2_MARK, AUDIO_CLKOUT_MARK, ADICHS2_MARK,
+	DU2_DISP_MARK, QPOLA_MARK, HTX0_C_MARK, SCIFA2_TXD_B_MARK,
+	MSIOF0_RXD_MARK, TS_SPSYNC0_MARK, SSI_WS2_MARK,
+	ADICS_SAMP_MARK, DU2_CDE_MARK, QPOLB_MARK, HRX0_C_MARK,
+	USB1_PWEN_MARK, AUDIO_CLKOUT_D_MARK, USB1_OVC_MARK,
+	TCLK1_B_MARK,
+	PINMUX_MARK_END,
+};
+
+static const pinmux_enum_t pinmux_data[] = {
+	PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */
+
+	PINMUX_DATA(VI1_DATA7_VI1_B7_MARK, FN_VI1_DATA7_VI1_B7),
+	PINMUX_DATA(USB0_PWEN_MARK, FN_USB0_PWEN),
+	PINMUX_DATA(USB0_OVC_VBUS_MARK, FN_USB0_OVC_VBUS),
+	PINMUX_DATA(USB2_PWEN_MARK, FN_USB2_PWEN),
+	PINMUX_DATA(USB2_OVC_MARK, FN_USB2_OVC),
+	PINMUX_DATA(AVS1_MARK, FN_AVS1),
+	PINMUX_DATA(AVS2_MARK, FN_AVS2),
+	PINMUX_DATA(DU_DOTCLKIN0_MARK, FN_DU_DOTCLKIN0),
+	PINMUX_DATA(DU_DOTCLKIN2_MARK, FN_DU_DOTCLKIN2),
+
+	PINMUX_IPSR_DATA(IP0_2_0, D0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_2_0, MSIOF3_SCK_B, SEL_SOF3_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_2_0, VI3_DATA0, SEL_VI3_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_2_0, VI0_G4, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_2_0, VI0_G4_B, SEL_VI0_1),
+	PINMUX_IPSR_DATA(IP0_5_3, D1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_5_3, MSIOF3_SYNC_B, SEL_SOF3_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_5_3, VI3_DATA1, SEL_VI3_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_5_3, VI0_G5, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_5_3, VI0_G5_B, SEL_VI0_1),
+	PINMUX_IPSR_DATA(IP0_8_6, D2),
+	PINMUX_IPSR_MODSEL_DATA(IP0_8_6, MSIOF3_RXD_B, SEL_SOF3_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_8_6, VI3_DATA2, SEL_VI3_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_8_6, VI0_G6, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_8_6, VI0_G6_B, SEL_VI0_1),
+	PINMUX_IPSR_DATA(IP0_11_9, D3),
+	PINMUX_IPSR_MODSEL_DATA(IP0_11_9, MSIOF3_TXD_B, SEL_SOF3_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_11_9, VI3_DATA3, SEL_VI3_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_11_9, VI0_G7, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_11_9, VI0_G7_B, SEL_VI0_1),
+	PINMUX_IPSR_DATA(IP0_15_12, D4),
+	PINMUX_IPSR_MODSEL_DATA(IP0_15_12, SCIFB1_RXD_F, SEL_SCIFB1_5),
+	PINMUX_IPSR_MODSEL_DATA(IP0_15_12, SCIFB0_RXD_C, SEL_SCIFB_2),
+	PINMUX_IPSR_MODSEL_DATA(IP0_15_12, VI3_DATA4, SEL_VI3_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_15_12, VI0_R0, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_15_12, VI0_R0_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_15_12, RX0_B, SEL_SCIF0_1),
+	PINMUX_IPSR_DATA(IP0_19_16, D5),
+	PINMUX_IPSR_MODSEL_DATA(IP0_19_16, SCIFB1_TXD_F, SEL_SCIFB1_5),
+	PINMUX_IPSR_MODSEL_DATA(IP0_19_16, SCIFB0_TXD_C, SEL_SCIFB_2),
+	PINMUX_IPSR_MODSEL_DATA(IP0_19_16, VI3_DATA5, SEL_VI3_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_19_16, VI0_R1, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_19_16, VI0_R1_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_19_16, TX0_B, SEL_SCIF0_1),
+	PINMUX_IPSR_DATA(IP0_22_20, D6),
+	PINMUX_IPSR_MODSEL_DATA(IP0_22_20, SCL2_C, SEL_IIC2_2),
+	PINMUX_IPSR_MODSEL_DATA(IP0_22_20, VI3_DATA6, SEL_VI3_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_22_20, VI0_R2, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_22_20, VI0_R2_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_22_20, SCL2_CIS_C, SEL_I2C2_2),
+	PINMUX_IPSR_DATA(IP0_26_23, D7),
+	PINMUX_IPSR_MODSEL_DATA(IP0_26_23, AD_DI_B, SEL_ADI_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_26_23, SDA2_C, SEL_IIC2_2),
+	PINMUX_IPSR_MODSEL_DATA(IP0_26_23, VI3_DATA7, SEL_VI3_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_26_23, VI0_R3, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_26_23, VI0_R3_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_26_23, SDA2_CIS_C, SEL_I2C2_2),
+	PINMUX_IPSR_DATA(IP0_30_27, D8),
+	PINMUX_IPSR_MODSEL_DATA(IP0_30_27, SCIFA1_SCK_C, SEL_SCIFA1_2),
+	PINMUX_IPSR_DATA(IP0_30_27, AVB_TXD0),
+	PINMUX_IPSR_DATA(IP0_30_27, MII_TXD0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_30_27, VI0_G0, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP0_30_27, VI0_G0_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP0_30_27, VI2_DATA0_VI2_B0, SEL_VI2_0),
+
+	PINMUX_IPSR_DATA(IP1_3_0, D9),
+	PINMUX_IPSR_MODSEL_DATA(IP1_3_0, SCIFA1_RXD_C, SEL_SCIFA1_2),
+	PINMUX_IPSR_DATA(IP1_3_0, AVB_TXD1),
+	PINMUX_IPSR_DATA(IP1_3_0, MII_TXD1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_3_0, VI0_G1, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP1_3_0, VI0_G1_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_3_0, VI2_DATA1_VI2_B1, SEL_VI2_0),
+	PINMUX_IPSR_DATA(IP1_7_4, D10),
+	PINMUX_IPSR_MODSEL_DATA(IP1_7_4, SCIFA1_TXD_C, SEL_SCIFA1_2),
+	PINMUX_IPSR_DATA(IP1_7_4, AVB_TXD2),
+	PINMUX_IPSR_DATA(IP1_7_4, MII_TXD2),
+	PINMUX_IPSR_MODSEL_DATA(IP1_7_4, VI0_G2, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP1_7_4, VI0_G2_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_7_4, VI2_DATA2_VI2_B2, SEL_VI2_0),
+	PINMUX_IPSR_DATA(IP1_11_8, D11),
+	PINMUX_IPSR_MODSEL_DATA(IP1_11_8, SCIFA1_CTS_N_C, SEL_SCIFA1_2),
+	PINMUX_IPSR_DATA(IP1_11_8, AVB_TXD3),
+	PINMUX_IPSR_DATA(IP1_11_8, MII_TXD3),
+	PINMUX_IPSR_MODSEL_DATA(IP1_11_8, VI0_G3, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP1_11_8, VI0_G3_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_11_8, VI2_DATA3_VI2_B3, SEL_VI2_0),
+	PINMUX_IPSR_DATA(IP1_14_12, D12),
+	PINMUX_IPSR_MODSEL_DATA(IP1_14_12, SCIFA1_RTS_N_C, SEL_SCIFA1_2),
+	PINMUX_IPSR_DATA(IP1_14_12, AVB_TXD4),
+	PINMUX_IPSR_MODSEL_DATA(IP1_14_12, VI0_HSYNC_N, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP1_14_12, VI0_HSYNC_N_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_14_12, VI2_DATA4_VI2_B4, SEL_VI2_0),
+	PINMUX_IPSR_DATA(IP1_17_15, D13),
+	PINMUX_IPSR_MODSEL_DATA(IP1_17_15, AVB_TXD5, SEL_SCIFA1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP1_17_15, VI0_VSYNC_N, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP1_17_15, VI0_VSYNC_N_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_17_15, VI2_DATA5_VI2_B5, SEL_VI2_0),
+	PINMUX_IPSR_DATA(IP1_21_18, D14),
+	PINMUX_IPSR_MODSEL_DATA(IP1_21_18, SCIFB1_RXD_C, SEL_SCIFB1_2),
+	PINMUX_IPSR_DATA(IP1_21_18, AVB_TXD6),
+	PINMUX_IPSR_MODSEL_DATA(IP1_21_18, RX1_B, SEL_SCIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_21_18, VI0_CLKENB, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP1_21_18, VI0_CLKENB_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_21_18, VI2_DATA6_VI2_B6, SEL_VI2_0),
+	PINMUX_IPSR_DATA(IP1_25_22, D15),
+	PINMUX_IPSR_MODSEL_DATA(IP1_25_22, SCIFB1_TXD_C, SEL_SCIFB1_2),
+	PINMUX_IPSR_DATA(IP1_25_22, AVB_TXD7),
+	PINMUX_IPSR_MODSEL_DATA(IP1_25_22, TX1_B, SEL_SCIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_25_22, VI0_FIELD, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP1_25_22, VI0_FIELD_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP1_25_22, VI2_DATA7_VI2_B7, SEL_VI2_0),
+	PINMUX_IPSR_DATA(IP1_27_26, A0),
+	PINMUX_IPSR_DATA(IP1_27_26, PWM3),
+	PINMUX_IPSR_DATA(IP1_29_28, A1),
+	PINMUX_IPSR_DATA(IP1_29_28, PWM4),
+
+	PINMUX_IPSR_DATA(IP2_2_0, A2),
+	PINMUX_IPSR_DATA(IP2_2_0, PWM5),
+	PINMUX_IPSR_MODSEL_DATA(IP2_2_0, MSIOF1_SS1_B, SEL_SOF1_1),
+	PINMUX_IPSR_DATA(IP2_5_3, A3),
+	PINMUX_IPSR_DATA(IP2_5_3, PWM6),
+	PINMUX_IPSR_MODSEL_DATA(IP2_5_3, MSIOF1_SS2_B, SEL_SOF1_1),
+	PINMUX_IPSR_DATA(IP2_8_6, A4),
+	PINMUX_IPSR_MODSEL_DATA(IP2_8_6, MSIOF1_TXD_B, SEL_SOF1_1),
+	PINMUX_IPSR_DATA(IP2_8_6, TPU0TO0),
+	PINMUX_IPSR_DATA(IP2_11_9, A5),
+	PINMUX_IPSR_MODSEL_DATA(IP2_11_9, SCIFA1_TXD_B, SEL_SCIFA1_1),
+	PINMUX_IPSR_DATA(IP2_11_9, TPU0TO1),
+	PINMUX_IPSR_DATA(IP2_14_12, A6),
+	PINMUX_IPSR_MODSEL_DATA(IP2_14_12, SCIFA1_RTS_N_B, SEL_SCIFA1_1),
+	PINMUX_IPSR_DATA(IP2_14_12, TPU0TO2),
+	PINMUX_IPSR_DATA(IP2_17_15, A7),
+	PINMUX_IPSR_MODSEL_DATA(IP2_17_15, SCIFA1_SCK_B, SEL_SCIFA1_1),
+	PINMUX_IPSR_DATA(IP2_17_15, AUDIO_CLKOUT_B),
+	PINMUX_IPSR_DATA(IP2_17_15, TPU0TO3),
+	PINMUX_IPSR_DATA(IP2_21_18, A8),
+	PINMUX_IPSR_MODSEL_DATA(IP2_21_18, SCIFA1_RXD_B, SEL_SCIFA1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP2_21_18, SSI_SCK5_B, SEL_SSI5_1),
+	PINMUX_IPSR_MODSEL_DATA(IP2_21_18, VI0_R4, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP2_21_18, VI0_R4_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP2_21_18, SCIFB2_RXD_C, SEL_SCIFB2_2),
+	PINMUX_IPSR_MODSEL_DATA(IP2_21_18, VI2_DATA0_VI2_B0_B, SEL_VI2_1),
+	PINMUX_IPSR_DATA(IP2_25_22, A9),
+	PINMUX_IPSR_MODSEL_DATA(IP2_25_22, SCIFA1_CTS_N_B, SEL_SCIFA1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP2_25_22, SSI_WS5_B, SEL_SSI5_1),
+	PINMUX_IPSR_MODSEL_DATA(IP2_25_22, VI0_R5, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP2_25_22, VI0_R5_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP2_25_22, SCIFB2_TXD_C, SEL_SCIFB2_2),
+	PINMUX_IPSR_MODSEL_DATA(IP2_25_22, VI2_DATA1_VI2_B1_B, SEL_VI2_1),
+	PINMUX_IPSR_DATA(IP2_28_26, A10),
+	PINMUX_IPSR_MODSEL_DATA(IP2_28_26, SSI_SDATA5_B, SEL_SSI5_1),
+	PINMUX_IPSR_DATA(IP2_28_26, MSIOF2_SYNC),
+	PINMUX_IPSR_MODSEL_DATA(IP2_28_26, VI0_R6, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP2_28_26, VI0_R6_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP2_28_26, VI2_DATA2_VI2_B2_B, SEL_VI2_1),
+
+	PINMUX_IPSR_DATA(IP3_3_0, A11),
+	PINMUX_IPSR_MODSEL_DATA(IP3_3_0, SCIFB2_CTS_N_B, SEL_SCIFB2_1),
+	PINMUX_IPSR_DATA(IP3_3_0, MSIOF2_SCK),
+	PINMUX_IPSR_MODSEL_DATA(IP3_3_0, VI1_R0, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP3_3_0, VI1_R0_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP3_3_0, VI2_G0),
+	PINMUX_IPSR_DATA(IP3_3_0, VI2_DATA3_VI2_B3_B),
+	PINMUX_IPSR_DATA(IP3_7_4, A12),
+	PINMUX_IPSR_MODSEL_DATA(IP3_7_4, SCIFB2_RXD_B, SEL_SCIFB2_1),
+	PINMUX_IPSR_DATA(IP3_7_4, MSIOF2_TXD),
+	PINMUX_IPSR_MODSEL_DATA(IP3_7_4, VI1_R1, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP3_7_4, VI1_R1_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP3_7_4, VI2_G1),
+	PINMUX_IPSR_DATA(IP3_7_4, VI2_DATA4_VI2_B4_B),
+	PINMUX_IPSR_DATA(IP3_11_8, A13),
+	PINMUX_IPSR_MODSEL_DATA(IP3_11_8, SCIFB2_RTS_N_B, SEL_SCIFB2_1),
+	PINMUX_IPSR_DATA(IP3_11_8, EX_WAIT2),
+	PINMUX_IPSR_DATA(IP3_11_8, MSIOF2_RXD),
+	PINMUX_IPSR_MODSEL_DATA(IP3_11_8, VI1_R2, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP3_11_8, VI1_R2_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP3_11_8, VI2_G2),
+	PINMUX_IPSR_MODSEL_DATA(IP3_11_8, VI2_DATA5_VI2_B5_B, SEL_VI2_0),
+	PINMUX_IPSR_DATA(IP3_14_12, A14),
+	PINMUX_IPSR_MODSEL_DATA(IP3_14_12, SCIFB2_TXD_B, SEL_SCIFB2_1),
+	PINMUX_IPSR_DATA(IP3_14_12, ATACS11_N),
+	PINMUX_IPSR_DATA(IP3_14_12, MSIOF2_SS1),
+	PINMUX_IPSR_DATA(IP3_17_15, A15),
+	PINMUX_IPSR_MODSEL_DATA(IP3_17_15, SCIFB2_SCK_B, SEL_SCIFB2_1),
+	PINMUX_IPSR_DATA(IP3_17_15, ATARD1_N),
+	PINMUX_IPSR_DATA(IP3_17_15, MSIOF2_SS2),
+	PINMUX_IPSR_DATA(IP3_19_18, A16),
+	PINMUX_IPSR_DATA(IP3_19_18, ATAWR1_N),
+	PINMUX_IPSR_DATA(IP3_22_20, A17),
+	PINMUX_IPSR_MODSEL_DATA(IP3_22_20, AD_DO_B, SEL_ADI_1),
+	PINMUX_IPSR_DATA(IP3_22_20, ATADIR1_N),
+	PINMUX_IPSR_DATA(IP3_25_23, A18),
+	PINMUX_IPSR_MODSEL_DATA(IP3_25_23, AD_CLK_B, SEL_ADI_1),
+	PINMUX_IPSR_DATA(IP3_25_23, ATAG1_N),
+	PINMUX_IPSR_DATA(IP3_28_26, A19),
+	PINMUX_IPSR_MODSEL_DATA(IP3_28_26, AD_NCS_N_B, SEL_ADI_1),
+	PINMUX_IPSR_DATA(IP3_28_26, ATACS01_N),
+	PINMUX_IPSR_MODSEL_DATA(IP3_28_26, EX_WAIT0_B, SEL_LBS_1),
+	PINMUX_IPSR_DATA(IP3_31_29, A20),
+	PINMUX_IPSR_DATA(IP3_31_29, SPCLK),
+	PINMUX_IPSR_MODSEL_DATA(IP3_31_29, VI1_R3, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP3_31_29, VI1_R3_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP3_31_29, VI2_G4),
+
+	PINMUX_IPSR_DATA(IP4_2_0, A21),
+	PINMUX_IPSR_DATA(IP4_2_0, MOSI_IO0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_2_0, VI1_R4, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_2_0, VI1_R4_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP4_2_0, VI2_G5),
+	PINMUX_IPSR_DATA(IP4_5_3, A22),
+	PINMUX_IPSR_DATA(IP4_5_3, MISO_IO1),
+	PINMUX_IPSR_MODSEL_DATA(IP4_5_3, VI1_R5, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_5_3, VI1_R5_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP4_5_3, VI2_G6),
+	PINMUX_IPSR_DATA(IP4_8_6, A23),
+	PINMUX_IPSR_DATA(IP4_8_6, IO2),
+	PINMUX_IPSR_MODSEL_DATA(IP4_8_6, VI1_G7, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_8_6, VI1_G7_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP4_8_6, VI2_G7),
+	PINMUX_IPSR_DATA(IP4_11_9, A24),
+	PINMUX_IPSR_DATA(IP4_11_9, IO3),
+	PINMUX_IPSR_MODSEL_DATA(IP4_11_9, VI1_R7, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_11_9, VI1_R7_B, SEL_VI1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP4_11_9, VI2_CLKENB, SEL_VI2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_11_9, VI2_CLKENB_B, SEL_VI2_1),
+	PINMUX_IPSR_DATA(IP4_14_12, A25),
+	PINMUX_IPSR_DATA(IP4_14_12, SSL),
+	PINMUX_IPSR_MODSEL_DATA(IP4_14_12, VI1_G6, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_14_12, VI1_G6_B, SEL_VI1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP4_14_12, VI2_FIELD, SEL_VI2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_14_12, VI2_FIELD_B, SEL_VI2_1),
+	PINMUX_IPSR_DATA(IP4_17_15, CS0_N),
+	PINMUX_IPSR_MODSEL_DATA(IP4_17_15, VI1_R6, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_17_15, VI1_R6_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP4_17_15, VI2_G3),
+	PINMUX_IPSR_MODSEL_DATA(IP4_17_15, MSIOF0_SS2_B, SEL_SOF0_1),
+	PINMUX_IPSR_DATA(IP4_20_18, CS1_N_A26),
+	PINMUX_IPSR_DATA(IP4_20_18, SPEEDIN),
+	PINMUX_IPSR_MODSEL_DATA(IP4_20_18, VI0_R7, SEL_VI0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_20_18, VI0_R7_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP4_20_18, VI2_CLK, SEL_VI2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_20_18, VI2_CLK_B, SEL_VI2_1),
+	PINMUX_IPSR_DATA(IP4_23_21, EX_CS0_N),
+	PINMUX_IPSR_MODSEL_DATA(IP4_23_21, HRX1_B, SEL_HSCIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP4_23_21, VI1_G5, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_23_21, VI1_G5_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP4_23_21, VI2_R0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_23_21, HTX0_B, SEL_HSCIF0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP4_23_21, MSIOF0_SS1_B, SEL_SOF0_1),
+	PINMUX_IPSR_DATA(IP4_26_24, EX_CS1_N),
+	PINMUX_IPSR_DATA(IP4_26_24, GPS_CLK),
+	PINMUX_IPSR_MODSEL_DATA(IP4_26_24, HCTS1_N_B, SEL_HSCIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP4_26_24, VI1_FIELD, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_26_24, VI1_FIELD_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP4_26_24, VI2_R1),
+	PINMUX_IPSR_DATA(IP4_29_27, EX_CS2_N),
+	PINMUX_IPSR_DATA(IP4_29_27, GPS_SIGN),
+	PINMUX_IPSR_MODSEL_DATA(IP4_29_27, HRTS1_N_B, SEL_HSCIF1_1),
+	PINMUX_IPSR_DATA(IP4_29_27, VI3_CLKENB),
+	PINMUX_IPSR_MODSEL_DATA(IP4_29_27, VI1_G0, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP4_29_27, VI1_G0_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP4_29_27, VI2_R2),
+
+	PINMUX_IPSR_DATA(IP5_2_0, EX_CS3_N),
+	PINMUX_IPSR_DATA(IP5_2_0, GPS_MAG),
+	PINMUX_IPSR_DATA(IP5_2_0, VI3_FIELD),
+	PINMUX_IPSR_MODSEL_DATA(IP5_2_0, VI1_G1, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_2_0, VI1_G1_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP5_2_0, VI2_R3),
+	PINMUX_IPSR_MODSEL_DATA(IP5_5_3, EX_CS4_N, SEL_I2C1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_5_3, MSIOF1_SCK_B, SEL_SOF1_1),
+	PINMUX_IPSR_DATA(IP5_5_3, VI3_HSYNC_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_5_3, VI2_HSYNC_N, SEL_VI2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_5_3, SCL1, SEL_IIC1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_5_3, VI2_HSYNC_N_B, SEL_VI2_1),
+	PINMUX_IPSR_DATA(IP5_5_3, INTC_EN0_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_5_3, SCL1_CIS, SEL_I2C1_0),
+	PINMUX_IPSR_DATA(IP5_9_6, EX_CS5_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_9_6, CAN0_RX, SEL_CAN0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_9_6, MSIOF1_RXD_B, SEL_SOF1_1),
+	PINMUX_IPSR_DATA(IP5_9_6, VI3_VSYNC_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_9_6, VI1_G2, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_9_6, VI1_G2_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP5_9_6, VI2_R4),
+	PINMUX_IPSR_MODSEL_DATA(IP5_9_6, SDA1, SEL_IIC1_0),
+	PINMUX_IPSR_DATA(IP5_9_6, INTC_EN1_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_9_6, SDA1_CIS, SEL_I2C1_0),
+	PINMUX_IPSR_DATA(IP5_12_10, BS_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_12_10, IETX, SEL_IEB_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_12_10, HTX1_B, SEL_HSCIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP5_12_10, CAN1_TX, SEL_CAN1_0),
+	PINMUX_IPSR_DATA(IP5_12_10, DRACK0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_12_10, IETX_C, SEL_IEB_2),
+	PINMUX_IPSR_DATA(IP5_14_13, RD_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_14_13, CAN0_TX, SEL_CAN0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_14_13, SCIFA0_SCK_B, SEL_SCFA_1),
+	PINMUX_IPSR_DATA(IP5_17_15, RD_WR_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_17_15, VI1_G3, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_17_15, VI1_G3_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP5_17_15, VI2_R5),
+	PINMUX_IPSR_MODSEL_DATA(IP5_17_15, SCIFA0_RXD_B, SEL_SCFA_1),
+	PINMUX_IPSR_DATA(IP5_17_15, INTC_IRQ4_N),
+	PINMUX_IPSR_DATA(IP5_20_18, WE0_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_20_18, IECLK, SEL_IEB_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_20_18, CAN_CLK, SEL_CANCLK_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_20_18, VI2_VSYNC_N, SEL_VI2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_20_18, SCIFA0_TXD_B, SEL_SCFA_1),
+	PINMUX_IPSR_MODSEL_DATA(IP5_20_18, VI2_VSYNC_N_B, SEL_VI2_1),
+	PINMUX_IPSR_DATA(IP5_23_21, WE1_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_23_21, IERX, SEL_IEB_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_23_21, CAN1_RX, SEL_CAN1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_23_21, VI1_G4, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_23_21, VI1_G4_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP5_23_21, VI2_R6),
+	PINMUX_IPSR_MODSEL_DATA(IP5_23_21, SCIFA0_CTS_N_B, SEL_SCFA_1),
+	PINMUX_IPSR_MODSEL_DATA(IP5_23_21, IERX_C, SEL_IEB_2),
+	PINMUX_IPSR_DATA(IP5_26_24, EX_WAIT0),
+	PINMUX_IPSR_DATA(IP5_26_24, IRQ3),
+	PINMUX_IPSR_DATA(IP5_26_24, INTC_IRQ3_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_26_24, VI3_CLK, SEL_VI3_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_26_24, SCIFA0_RTS_N_B, SEL_SCFA_1),
+	PINMUX_IPSR_MODSEL_DATA(IP5_26_24, HRX0_B, SEL_HSCIF0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP5_26_24, MSIOF0_SCK_B, SEL_SOF0_1),
+	PINMUX_IPSR_DATA(IP5_29_27, DREQ0_N),
+	PINMUX_IPSR_MODSEL_DATA(IP5_29_27, VI1_HSYNC_N, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP5_29_27, VI1_HSYNC_N_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP5_29_27, VI2_R7),
+	PINMUX_IPSR_MODSEL_DATA(IP5_29_27, SSI_SCK78_C, SEL_SSI7_2),
+	PINMUX_IPSR_MODSEL_DATA(IP5_29_27, SSI_WS78_B, SEL_SSI7_1),
+
+	PINMUX_IPSR_DATA(IP6_2_0, DACK0),
+	PINMUX_IPSR_DATA(IP6_2_0, IRQ0),
+	PINMUX_IPSR_DATA(IP6_2_0, INTC_IRQ0_N),
+	PINMUX_IPSR_MODSEL_DATA(IP6_2_0, SSI_SCK6_B, SEL_SSI6_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_2_0, VI1_VSYNC_N, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP6_2_0, VI1_VSYNC_N_B, SEL_VI1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_2_0, SSI_WS78_C, SEL_SSI7_2),
+	PINMUX_IPSR_DATA(IP6_5_3, DREQ1_N),
+	PINMUX_IPSR_MODSEL_DATA(IP6_5_3, VI1_CLKENB, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP6_5_3, VI1_CLKENB_B, SEL_VI1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_5_3, SSI_SDATA7_C, SEL_SSI7_2),
+	PINMUX_IPSR_MODSEL_DATA(IP6_5_3, SSI_SCK78_B, SEL_SSI7_1),
+	PINMUX_IPSR_DATA(IP6_8_6, DACK1),
+	PINMUX_IPSR_DATA(IP6_8_6, IRQ1),
+	PINMUX_IPSR_DATA(IP6_8_6, INTC_IRQ1_N),
+	PINMUX_IPSR_MODSEL_DATA(IP6_8_6, SSI_WS6_B, SEL_SSI6_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_8_6, SSI_SDATA8_C, SEL_SSI8_2),
+	PINMUX_IPSR_DATA(IP6_10_9, DREQ2_N),
+	PINMUX_IPSR_MODSEL_DATA(IP6_10_9, HSCK1_B, SEL_HSCIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_10_9, HCTS0_N_B, SEL_HSCIF0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_10_9, MSIOF0_TXD_B, SEL_SOF0_1),
+	PINMUX_IPSR_DATA(IP6_13_11, DACK2),
+	PINMUX_IPSR_DATA(IP6_13_11, IRQ2),
+	PINMUX_IPSR_DATA(IP6_13_11, INTC_IRQ2_N),
+	PINMUX_IPSR_MODSEL_DATA(IP6_13_11, SSI_SDATA6_B, SEL_SSI6_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_13_11, HRTS0_N_B, SEL_HSCIF0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_13_11, MSIOF0_RXD_B, SEL_SOF0_1),
+	PINMUX_IPSR_DATA(IP6_16_14, ETH_CRS_DV),
+	PINMUX_IPSR_DATA(IP6_16_14, RMII_CRS_DV),
+	PINMUX_IPSR_MODSEL_DATA(IP6_16_14, STP_ISCLK_0_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_16_14, TS_SDEN0_D, SEL_TSIF0_3),
+	PINMUX_IPSR_MODSEL_DATA(IP6_16_14, GLO_Q0_C, SEL_GPS_2),
+	PINMUX_IPSR_MODSEL_DATA(IP6_16_14, SCL2_E, SEL_IIC2_4),
+	PINMUX_IPSR_MODSEL_DATA(IP6_16_14, SCL2_CIS_E, SEL_I2C2_4),
+	PINMUX_IPSR_DATA(IP6_19_17, ETH_RX_ER),
+	PINMUX_IPSR_DATA(IP6_19_17, RMII_RX_ER),
+	PINMUX_IPSR_MODSEL_DATA(IP6_19_17, STP_ISD_0_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_19_17, TS_SPSYNC0_D, SEL_TSIF0_3),
+	PINMUX_IPSR_MODSEL_DATA(IP6_19_17, GLO_Q1_C, SEL_GPS_2),
+	PINMUX_IPSR_MODSEL_DATA(IP6_19_17, SDA2_E, SEL_IIC2_4),
+	PINMUX_IPSR_MODSEL_DATA(IP6_19_17, SDA2_CIS_E, SEL_I2C2_4),
+	PINMUX_IPSR_DATA(IP6_22_20, ETH_RXD0),
+	PINMUX_IPSR_DATA(IP6_22_20, RMII_RXD0),
+	PINMUX_IPSR_MODSEL_DATA(IP6_22_20, STP_ISEN_0_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_22_20, TS_SDAT0_D, SEL_TSIF0_3),
+	PINMUX_IPSR_MODSEL_DATA(IP6_22_20, GLO_I0_C, SEL_GPS_2),
+	PINMUX_IPSR_MODSEL_DATA(IP6_22_20, SCIFB1_SCK_G, SEL_SCIFB1_6),
+	PINMUX_IPSR_MODSEL_DATA(IP6_22_20, SCK1_E, SEL_SCIF1_4),
+	PINMUX_IPSR_DATA(IP6_25_23, ETH_RXD1),
+	PINMUX_IPSR_DATA(IP6_25_23, RMII_RXD1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_25_23, HRX0_E, SEL_HSCIF0_4),
+	PINMUX_IPSR_MODSEL_DATA(IP6_25_23, STP_ISSYNC_0_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_25_23, TS_SCK0_D, SEL_TSIF0_3),
+	PINMUX_IPSR_MODSEL_DATA(IP6_25_23, GLO_I1_C, SEL_GPS_2),
+	PINMUX_IPSR_MODSEL_DATA(IP6_25_23, SCIFB1_RXD_G, SEL_SCIFB1_6),
+	PINMUX_IPSR_MODSEL_DATA(IP6_25_23, RX1_E, SEL_SCIF1_4),
+	PINMUX_IPSR_DATA(IP6_28_26, ETH_LINK),
+	PINMUX_IPSR_DATA(IP6_28_26, RMII_LINK),
+	PINMUX_IPSR_MODSEL_DATA(IP6_28_26, HTX0_E, SEL_HSCIF0_4),
+	PINMUX_IPSR_MODSEL_DATA(IP6_28_26, STP_IVCXO27_0_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_28_26, SCIFB1_TXD_G, SEL_SCIFB1_6),
+	PINMUX_IPSR_MODSEL_DATA(IP6_28_26, TX1_E, SEL_SCIF1_4),
+	PINMUX_IPSR_DATA(IP6_31_29, ETH_REF_CLK),
+	PINMUX_IPSR_DATA(IP6_31_29, RMII_REF_CLK),
+	PINMUX_IPSR_MODSEL_DATA(IP6_31_29, HCTS0_N_E, SEL_HSCIF0_4),
+	PINMUX_IPSR_MODSEL_DATA(IP6_31_29, STP_IVCXO27_1_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP6_31_29, HRX0_F, SEL_HSCIF0_5),
+
+	PINMUX_IPSR_DATA(IP7_2_0, ETH_MDIO),
+	PINMUX_IPSR_DATA(IP7_2_0, RMII_MDIO),
+	PINMUX_IPSR_MODSEL_DATA(IP7_2_0, HRTS0_N_E, SEL_HSCIF0_4),
+	PINMUX_IPSR_MODSEL_DATA(IP7_2_0, SIM0_D_C, SEL_SIM_2),
+	PINMUX_IPSR_MODSEL_DATA(IP7_2_0, HCTS0_N_F, SEL_HSCIF0_5),
+	PINMUX_IPSR_DATA(IP7_5_3, ETH_TXD1),
+	PINMUX_IPSR_DATA(IP7_5_3, RMII_TXD1),
+	PINMUX_IPSR_MODSEL_DATA(IP7_5_3, HTX0_F, SEL_HSCIF0_4),
+	PINMUX_IPSR_MODSEL_DATA(IP7_5_3, BPFCLK_G, SEL_SIM_2),
+	PINMUX_IPSR_MODSEL_DATA(IP7_5_3, RDS_CLK_F, SEL_HSCIF0_5),
+	PINMUX_IPSR_DATA(IP7_7_6, ETH_TX_EN),
+	PINMUX_IPSR_DATA(IP7_7_6, RMII_TX_EN),
+	PINMUX_IPSR_MODSEL_DATA(IP7_7_6, SIM0_CLK_C, SEL_SIM_2),
+	PINMUX_IPSR_MODSEL_DATA(IP7_7_6, HRTS0_N_F, SEL_HSCIF0_5),
+	PINMUX_IPSR_DATA(IP7_9_8, ETH_MAGIC),
+	PINMUX_IPSR_DATA(IP7_9_8, RMII_MAGIC),
+	PINMUX_IPSR_MODSEL_DATA(IP7_9_8, SIM0_RST_C, SEL_SIM_2),
+	PINMUX_IPSR_DATA(IP7_12_10, ETH_TXD0),
+	PINMUX_IPSR_DATA(IP7_12_10, RMII_TXD0),
+	PINMUX_IPSR_MODSEL_DATA(IP7_12_10, STP_ISCLK_1_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP7_12_10, TS_SDEN1_C, SEL_TSIF1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP7_12_10, GLO_SCLK_C, SEL_GPS_2),
+	PINMUX_IPSR_DATA(IP7_15_13, ETH_MDC),
+	PINMUX_IPSR_DATA(IP7_15_13, RMII_MDC),
+	PINMUX_IPSR_MODSEL_DATA(IP7_15_13, STP_ISD_1_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP7_15_13, TS_SPSYNC1_C, SEL_TSIF1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP7_15_13, GLO_SDATA_C, SEL_GPS_2),
+	PINMUX_IPSR_DATA(IP7_18_16, PWM0),
+	PINMUX_IPSR_MODSEL_DATA(IP7_18_16, SCIFA2_SCK_C, SEL_SCIFA2_2),
+	PINMUX_IPSR_MODSEL_DATA(IP7_18_16, STP_ISEN_1_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP7_18_16, TS_SDAT1_C, SEL_TSIF1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP7_18_16, GLO_SS_C, SEL_GPS_2),
+	PINMUX_IPSR_DATA(IP7_21_19, PWM1),
+	PINMUX_IPSR_MODSEL_DATA(IP7_21_19, SCIFA2_TXD_C, SEL_SCIFA2_2),
+	PINMUX_IPSR_MODSEL_DATA(IP7_21_19, STP_ISSYNC_1_B, SEL_SSP_1),
+	PINMUX_IPSR_MODSEL_DATA(IP7_21_19, TS_SCK1_C, SEL_TSIF1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP7_21_19, GLO_RFON_C, SEL_GPS_2),
+	PINMUX_IPSR_DATA(IP7_21_19, PCMOE_N),
+	PINMUX_IPSR_DATA(IP7_24_22, PWM2),
+	PINMUX_IPSR_DATA(IP7_24_22, PWMFSW0),
+	PINMUX_IPSR_MODSEL_DATA(IP7_24_22, SCIFA2_RXD_C, SEL_SCIFA2_2),
+	PINMUX_IPSR_DATA(IP7_24_22, PCMWE_N),
+	PINMUX_IPSR_MODSEL_DATA(IP7_24_22, IECLK_C, SEL_IEB_2),
+	PINMUX_IPSR_DATA(IP7_26_25, DU1_DOTCLKIN),
+	PINMUX_IPSR_DATA(IP7_26_25, AUDIO_CLKC),
+	PINMUX_IPSR_DATA(IP7_26_25, AUDIO_CLKOUT_C),
+	PINMUX_IPSR_MODSEL_DATA(IP7_28_27, VI0_CLK, SEL_VI0_0),
+	PINMUX_IPSR_DATA(IP7_28_27, ATACS00_N),
+	PINMUX_IPSR_DATA(IP7_28_27, AVB_RXD1),
+	PINMUX_IPSR_DATA(IP7_28_27, MII_RXD1),
+	PINMUX_IPSR_MODSEL_DATA(IP7_30_29, VI0_DATA0_VI0_B0, SEL_VI0_0),
+	PINMUX_IPSR_DATA(IP7_30_29, ATACS10_N),
+	PINMUX_IPSR_DATA(IP7_30_29, AVB_RXD2),
+	PINMUX_IPSR_DATA(IP7_30_29, MII_RXD2),
+
+	PINMUX_IPSR_MODSEL_DATA(IP8_1_0, VI0_DATA1_VI0_B1, SEL_VI0_0),
+	PINMUX_IPSR_DATA(IP8_1_0, ATARD0_N),
+	PINMUX_IPSR_DATA(IP8_1_0, AVB_RXD3),
+	PINMUX_IPSR_DATA(IP8_1_0, MII_RXD3),
+	PINMUX_IPSR_MODSEL_DATA(IP8_3_2, VI0_DATA2_VI0_B2, SEL_VI0_0),
+	PINMUX_IPSR_DATA(IP8_3_2, ATAWR0_N),
+	PINMUX_IPSR_DATA(IP8_3_2, AVB_RXD4),
+	PINMUX_IPSR_MODSEL_DATA(IP8_5_4, VI0_DATA3_VI0_B3, SEL_VI0_0),
+	PINMUX_IPSR_DATA(IP8_5_4, ATADIR0_N),
+	PINMUX_IPSR_DATA(IP8_5_4, AVB_RXD5),
+	PINMUX_IPSR_MODSEL_DATA(IP8_7_6, VI0_DATA4_VI0_B4, SEL_VI0_0),
+	PINMUX_IPSR_DATA(IP8_7_6, ATAG0_N),
+	PINMUX_IPSR_DATA(IP8_7_6, AVB_RXD6),
+	PINMUX_IPSR_MODSEL_DATA(IP8_9_8, VI0_DATA5_VI0_B5, SEL_VI0_0),
+	PINMUX_IPSR_DATA(IP8_9_8, EX_WAIT1),
+	PINMUX_IPSR_DATA(IP8_9_8, AVB_RXD7),
+	PINMUX_IPSR_MODSEL_DATA(IP8_11_10, VI0_DATA6_VI0_B6, SEL_VI0_0),
+	PINMUX_IPSR_DATA(IP8_11_10, AVB_RX_ER),
+	PINMUX_IPSR_DATA(IP8_11_10, MII_RX_ER),
+	PINMUX_IPSR_MODSEL_DATA(IP8_13_12, VI0_DATA7_VI0_B7, SEL_VI0_0),
+	PINMUX_IPSR_DATA(IP8_13_12, AVB_RX_CLK),
+	PINMUX_IPSR_DATA(IP8_13_12, MII_RX_CLK),
+	PINMUX_IPSR_MODSEL_DATA(IP8_15_14, VI1_CLK, SEL_VI1_0),
+	PINMUX_IPSR_DATA(IP8_15_14, AVB_RX_DV),
+	PINMUX_IPSR_DATA(IP8_15_14, MII_RX_DV),
+	PINMUX_IPSR_MODSEL_DATA(IP8_17_16, VI1_DATA0_VI1_B0, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP8_17_16, SCIFA1_SCK_D, SEL_SCIFA1_3),
+	PINMUX_IPSR_DATA(IP8_17_16, AVB_CRS),
+	PINMUX_IPSR_DATA(IP8_17_16, MII_CRS),
+	PINMUX_IPSR_MODSEL_DATA(IP8_19_18, VI1_DATA1_VI1_B1, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP8_19_18, SCIFA1_RXD_D, SEL_SCIFA1_3),
+	PINMUX_IPSR_DATA(IP8_19_18, AVB_MDC),
+	PINMUX_IPSR_DATA(IP8_19_18, MII_MDC),
+	PINMUX_IPSR_MODSEL_DATA(IP8_21_20, VI1_DATA2_VI1_B2, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP8_21_20, SCIFA1_TXD_D, SEL_SCIFA1_3),
+	PINMUX_IPSR_DATA(IP8_21_20, AVB_MDIO),
+	PINMUX_IPSR_DATA(IP8_21_20, MII_MDIO),
+	PINMUX_IPSR_MODSEL_DATA(IP8_23_22, VI1_DATA3_VI1_B3, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP8_23_22, SCIFA1_CTS_N_D, SEL_SCIFA1_3),
+	PINMUX_IPSR_DATA(IP8_23_22, AVB_GTX_CLK),
+	PINMUX_IPSR_MODSEL_DATA(IP8_25_24, VI1_DATA4_VI1_B4, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP8_25_24, SCIFA1_RTS_N_D, SEL_SCIFA1_3),
+	PINMUX_IPSR_DATA(IP8_25_24, AVB_MAGIC),
+	PINMUX_IPSR_DATA(IP8_25_24, MII_MAGIC),
+	PINMUX_IPSR_MODSEL_DATA(IP8_26, VI1_DATA5_VI1_B5, SEL_VI1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP8_26, AVB_PHY_INT, SEL_SCIFA1_3),
+	PINMUX_IPSR_MODSEL_DATA(IP8_27, VI1_DATA6_VI1_B6, SEL_VI1_0),
+	PINMUX_IPSR_DATA(IP8_27, AVB_GTXREFCLK),
+	PINMUX_IPSR_DATA(IP8_28, SD0_CLK),
+	PINMUX_IPSR_MODSEL_DATA(IP8_28, VI1_DATA0_VI1_B0_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP8_30_29, SD0_CMD),
+	PINMUX_IPSR_MODSEL_DATA(IP8_30_29, SCIFB1_SCK_B, SEL_SCIFB1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP8_30_29, VI1_DATA1_VI1_B1_B, SEL_VI1_1),
+
+	PINMUX_IPSR_DATA(IP9_1_0, SD0_DAT0),
+	PINMUX_IPSR_MODSEL_DATA(IP9_1_0, SCIFB1_RXD_B, SEL_SCIFB1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_1_0, VI1_DATA2_VI1_B2_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP9_3_2, SD0_DAT1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_3_2, SCIFB1_TXD_B, SEL_SCIFB1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_3_2, VI1_DATA3_VI1_B3_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP9_5_4, SD0_DAT2),
+	PINMUX_IPSR_MODSEL_DATA(IP9_5_4, SCIFB1_CTS_N_B, SEL_SCIFB1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_5_4, VI1_DATA4_VI1_B4_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP9_7_6, SD0_DAT3),
+	PINMUX_IPSR_MODSEL_DATA(IP9_7_6, SCIFB1_RTS_N_B, SEL_SCIFB1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_7_6, VI1_DATA5_VI1_B5_B, SEL_VI1_1),
+	PINMUX_IPSR_DATA(IP9_11_8, SD0_CD),
+	PINMUX_IPSR_DATA(IP9_11_8, MMC0_D6),
+	PINMUX_IPSR_MODSEL_DATA(IP9_11_8, TS_SDEN0_B, SEL_TSIF0_1),
+	PINMUX_IPSR_DATA(IP9_11_8, USB0_EXTP),
+	PINMUX_IPSR_MODSEL_DATA(IP9_11_8, GLO_SCLK, SEL_GPS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP9_11_8, VI1_DATA6_VI1_B6_B, SEL_VI1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_11_8, SCL1_B, SEL_IIC1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_11_8, SCL1_CIS_B, SEL_I2C1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_11_8, VI2_DATA6_VI2_B6_B, SEL_VI2_1),
+	PINMUX_IPSR_DATA(IP9_15_12, SD0_WP),
+	PINMUX_IPSR_DATA(IP9_15_12, MMC0_D7),
+	PINMUX_IPSR_MODSEL_DATA(IP9_15_12, TS_SPSYNC0_B, SEL_TSIF0_1),
+	PINMUX_IPSR_DATA(IP9_15_12, USB0_IDIN),
+	PINMUX_IPSR_MODSEL_DATA(IP9_15_12, GLO_SDATA, SEL_GPS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP9_15_12, VI1_DATA7_VI1_B7_B, SEL_VI1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_15_12, SDA1_B, SEL_IIC1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_15_12, SDA1_CIS_B, SEL_I2C1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_15_12, VI2_DATA7_VI2_B7_B, SEL_VI2_1),
+	PINMUX_IPSR_DATA(IP9_17_16, SD1_CLK),
+	PINMUX_IPSR_DATA(IP9_17_16, AVB_TX_EN),
+	PINMUX_IPSR_DATA(IP9_17_16, MII_TX_EN),
+	PINMUX_IPSR_DATA(IP9_19_18, SD1_CMD),
+	PINMUX_IPSR_DATA(IP9_19_18, AVB_TX_ER),
+	PINMUX_IPSR_DATA(IP9_19_18, MII_TX_ER),
+	PINMUX_IPSR_MODSEL_DATA(IP9_19_18, SCIFB0_SCK_B, SEL_SCIFB_1),
+	PINMUX_IPSR_DATA(IP9_21_20, SD1_DAT0),
+	PINMUX_IPSR_DATA(IP9_21_20, AVB_TX_CLK),
+	PINMUX_IPSR_DATA(IP9_21_20, MII_TX_CLK),
+	PINMUX_IPSR_MODSEL_DATA(IP9_21_20, SCIFB0_RXD_B, SEL_SCIFB_1),
+	PINMUX_IPSR_DATA(IP9_23_22, SD1_DAT1),
+	PINMUX_IPSR_DATA(IP9_23_22, AVB_LINK),
+	PINMUX_IPSR_DATA(IP9_23_22, MII_LINK),
+	PINMUX_IPSR_MODSEL_DATA(IP9_23_22, SCIFB0_TXD_B, SEL_SCIFB_1),
+	PINMUX_IPSR_DATA(IP9_25_24, SD1_DAT2),
+	PINMUX_IPSR_DATA(IP9_25_24, AVB_COL),
+	PINMUX_IPSR_DATA(IP9_25_24, MII_COL),
+	PINMUX_IPSR_MODSEL_DATA(IP9_25_24, SCIFB0_CTS_N_B, SEL_SCIFB_1),
+	PINMUX_IPSR_DATA(IP9_27_26, SD1_DAT3),
+	PINMUX_IPSR_DATA(IP9_27_26, AVB_RXD0),
+	PINMUX_IPSR_DATA(IP9_27_26, MII_RXD0),
+	PINMUX_IPSR_MODSEL_DATA(IP9_27_26, SCIFB0_RTS_N_B, SEL_SCIFB_1),
+	PINMUX_IPSR_DATA(IP9_31_28, SD1_CD),
+	PINMUX_IPSR_DATA(IP9_31_28, MMC1_D6),
+	PINMUX_IPSR_MODSEL_DATA(IP9_31_28, TS_SDEN1, SEL_TSIF1_0),
+	PINMUX_IPSR_DATA(IP9_31_28, USB1_EXTP),
+	PINMUX_IPSR_MODSEL_DATA(IP9_31_28, GLO_SS, SEL_GPS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP9_31_28, VI0_CLK_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_31_28, SCL2_D, SEL_IIC2_3),
+	PINMUX_IPSR_MODSEL_DATA(IP9_31_28, SCL2_CIS_D, SEL_I2C2_3),
+	PINMUX_IPSR_MODSEL_DATA(IP9_31_28, SIM0_CLK_B, SEL_SIM_1),
+	PINMUX_IPSR_MODSEL_DATA(IP9_31_28, VI3_CLK_B, SEL_VI3_1),
+
+	PINMUX_IPSR_DATA(IP10_3_0, SD1_WP),
+	PINMUX_IPSR_DATA(IP10_3_0, MMC1_D7),
+	PINMUX_IPSR_MODSEL_DATA(IP10_3_0, TS_SPSYNC1, SEL_TSIF1_0),
+	PINMUX_IPSR_DATA(IP10_3_0, USB1_IDIN),
+	PINMUX_IPSR_MODSEL_DATA(IP10_3_0, GLO_RFON, SEL_GPS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP10_3_0, VI1_CLK_B, SEL_VI1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_3_0, SDA2_D, SEL_IIC2_3),
+	PINMUX_IPSR_MODSEL_DATA(IP10_3_0, SDA2_CIS_D, SEL_I2C2_3),
+	PINMUX_IPSR_MODSEL_DATA(IP10_3_0, SIM0_D_B, SEL_SIM_1),
+	PINMUX_IPSR_DATA(IP10_6_4, SD2_CLK),
+	PINMUX_IPSR_DATA(IP10_6_4, MMC0_CLK),
+	PINMUX_IPSR_MODSEL_DATA(IP10_6_4, SIM0_CLK, SEL_SIM_0),
+	PINMUX_IPSR_MODSEL_DATA(IP10_6_4, VI0_DATA0_VI0_B0_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_6_4, TS_SDEN0_C, SEL_TSIF0_2),
+	PINMUX_IPSR_MODSEL_DATA(IP10_6_4, GLO_SCLK_B, SEL_GPS_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_6_4, VI3_DATA0_B, SEL_VI3_1),
+	PINMUX_IPSR_DATA(IP10_10_7, SD2_CMD),
+	PINMUX_IPSR_DATA(IP10_10_7, MMC0_CMD),
+	PINMUX_IPSR_MODSEL_DATA(IP10_10_7, SIM0_D, SEL_SIM_0),
+	PINMUX_IPSR_MODSEL_DATA(IP10_10_7, VI0_DATA1_VI0_B1_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_10_7, SCIFB1_SCK_E, SEL_SCIFB1_4),
+	PINMUX_IPSR_MODSEL_DATA(IP10_10_7, SCK1_D, SEL_SCIF1_3),
+	PINMUX_IPSR_MODSEL_DATA(IP10_10_7, TS_SPSYNC0_C, SEL_TSIF0_2),
+	PINMUX_IPSR_MODSEL_DATA(IP10_10_7, GLO_SDATA_B, SEL_GPS_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_10_7, VI3_DATA1_B, SEL_VI3_1),
+	PINMUX_IPSR_DATA(IP10_14_11, SD2_DAT0),
+	PINMUX_IPSR_DATA(IP10_14_11, MMC0_D0),
+	PINMUX_IPSR_MODSEL_DATA(IP10_14_11, FMCLK_B, SEL_FM_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_14_11, VI0_DATA2_VI0_B2_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_14_11, SCIFB1_RXD_E, SEL_SCIFB1_4),
+	PINMUX_IPSR_MODSEL_DATA(IP10_14_11, RX1_D, SEL_SCIF1_3),
+	PINMUX_IPSR_MODSEL_DATA(IP10_14_11, TS_SDAT0_C, SEL_TSIF0_2),
+	PINMUX_IPSR_MODSEL_DATA(IP10_14_11, GLO_SS_B, SEL_GPS_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_14_11, VI3_DATA2_B, SEL_VI3_1),
+	PINMUX_IPSR_DATA(IP10_18_15, SD2_DAT1),
+	PINMUX_IPSR_DATA(IP10_18_15, MMC0_D1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_18_15, FMIN_B, SEL_FM_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_18_15, RDS_DATA, SEL_RDS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP10_18_15, VI0_DATA3_VI0_B3_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_18_15, SCIFB1_TXD_E, SEL_SCIFB1_4),
+	PINMUX_IPSR_MODSEL_DATA(IP10_18_15, TX1_D, SEL_SCIF1_3),
+	PINMUX_IPSR_MODSEL_DATA(IP10_18_15, TS_SCK0_C, SEL_TSIF0_2),
+	PINMUX_IPSR_MODSEL_DATA(IP10_18_15, GLO_RFON_B, SEL_GPS_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_18_15, VI3_DATA3_B, SEL_VI3_1),
+	PINMUX_IPSR_DATA(IP10_22_19, SD2_DAT2),
+	PINMUX_IPSR_DATA(IP10_22_19, MMC0_D2),
+	PINMUX_IPSR_MODSEL_DATA(IP10_22_19, BPFCLK_B, SEL_FM_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_22_19, RDS_CLK, SEL_RDS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP10_22_19, VI0_DATA4_VI0_B4_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_22_19, HRX0_D, SEL_HSCIF0_3),
+	PINMUX_IPSR_MODSEL_DATA(IP10_22_19, TS_SDEN1_B, SEL_TSIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_22_19, GLO_Q0_B, SEL_GPS_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_22_19, VI3_DATA4_B, SEL_VI3_1),
+	PINMUX_IPSR_DATA(IP10_25_23, SD2_DAT3),
+	PINMUX_IPSR_DATA(IP10_25_23, MMC0_D3),
+	PINMUX_IPSR_MODSEL_DATA(IP10_25_23, SIM0_RST, SEL_SIM_0),
+	PINMUX_IPSR_MODSEL_DATA(IP10_25_23, VI0_DATA5_VI0_B5_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_25_23, HTX0_D, SEL_HSCIF0_3),
+	PINMUX_IPSR_MODSEL_DATA(IP10_25_23, TS_SPSYNC1_B, SEL_TSIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_25_23, GLO_Q1_B, SEL_GPS_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_25_23, VI3_DATA5_B, SEL_VI3_1),
+	PINMUX_IPSR_DATA(IP10_29_26, SD2_CD),
+	PINMUX_IPSR_DATA(IP10_29_26, MMC0_D4),
+	PINMUX_IPSR_MODSEL_DATA(IP10_29_26, TS_SDAT0_B, SEL_TSIF0_1),
+	PINMUX_IPSR_DATA(IP10_29_26, USB2_EXTP),
+	PINMUX_IPSR_MODSEL_DATA(IP10_29_26, GLO_I0, SEL_GPS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP10_29_26, VI0_DATA6_VI0_B6_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_29_26, HCTS0_N_D, SEL_HSCIF0_3),
+	PINMUX_IPSR_MODSEL_DATA(IP10_29_26, TS_SDAT1_B, SEL_TSIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_29_26, GLO_I0_B, SEL_GPS_1),
+	PINMUX_IPSR_MODSEL_DATA(IP10_29_26, VI3_DATA6_B, SEL_VI3_1),
+
+	PINMUX_IPSR_DATA(IP11_3_0, SD2_WP),
+	PINMUX_IPSR_DATA(IP11_3_0, MMC0_D5),
+	PINMUX_IPSR_MODSEL_DATA(IP11_3_0, TS_SCK0_B, SEL_TSIF0_1),
+	PINMUX_IPSR_DATA(IP11_3_0, USB2_IDIN),
+	PINMUX_IPSR_MODSEL_DATA(IP11_3_0, GLO_I1, SEL_GPS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP11_3_0, VI0_DATA7_VI0_B7_B, SEL_VI0_1),
+	PINMUX_IPSR_MODSEL_DATA(IP11_3_0, HRTS0_N_D, SEL_HSCIF0_3),
+	PINMUX_IPSR_MODSEL_DATA(IP11_3_0, TS_SCK1_B, SEL_TSIF1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP11_3_0, GLO_I1_B, SEL_GPS_1),
+	PINMUX_IPSR_MODSEL_DATA(IP11_3_0, VI3_DATA7_B, SEL_VI3_1),
+	PINMUX_IPSR_DATA(IP11_4, SD3_CLK),
+	PINMUX_IPSR_DATA(IP11_4, MMC1_CLK),
+	PINMUX_IPSR_DATA(IP11_6_5, SD3_CMD),
+	PINMUX_IPSR_DATA(IP11_6_5, MMC1_CMD),
+	PINMUX_IPSR_DATA(IP11_6_5, MTS_N),
+	PINMUX_IPSR_DATA(IP11_8_7, SD3_DAT0),
+	PINMUX_IPSR_DATA(IP11_8_7, MMC1_D0),
+	PINMUX_IPSR_DATA(IP11_8_7, STM_N),
+	PINMUX_IPSR_DATA(IP11_10_9, SD3_DAT1),
+	PINMUX_IPSR_DATA(IP11_10_9, MMC1_D1),
+	PINMUX_IPSR_DATA(IP11_10_9, MDATA),
+	PINMUX_IPSR_DATA(IP11_12_11, SD3_DAT2),
+	PINMUX_IPSR_DATA(IP11_12_11, MMC1_D2),
+	PINMUX_IPSR_DATA(IP11_12_11, SDATA),
+	PINMUX_IPSR_DATA(IP11_14_13, SD3_DAT3),
+	PINMUX_IPSR_DATA(IP11_14_13, MMC1_D3),
+	PINMUX_IPSR_DATA(IP11_14_13, SCKZ),
+	PINMUX_IPSR_DATA(IP11_17_15, SD3_CD),
+	PINMUX_IPSR_DATA(IP11_17_15, MMC1_D4),
+	PINMUX_IPSR_MODSEL_DATA(IP11_17_15, TS_SDAT1, SEL_TSIF1_0),
+	PINMUX_IPSR_DATA(IP11_17_15, VSP),
+	PINMUX_IPSR_MODSEL_DATA(IP11_17_15, GLO_Q0, SEL_GPS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP11_17_15, SIM0_RST_B, SEL_SIM_1),
+	PINMUX_IPSR_DATA(IP11_21_18, SD3_WP),
+	PINMUX_IPSR_DATA(IP11_21_18, MMC1_D5),
+	PINMUX_IPSR_MODSEL_DATA(IP11_21_18, TS_SCK1, SEL_TSIF1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP11_21_18, GLO_Q1, SEL_GPS_0),
+	PINMUX_IPSR_MODSEL_DATA(IP11_21_18, FMIN_C, SEL_FM_2),
+	PINMUX_IPSR_MODSEL_DATA(IP11_21_18, RDS_DATA_B, SEL_RDS_1),
+	PINMUX_IPSR_MODSEL_DATA(IP11_21_18, FMIN_E, SEL_FM_4),
+	PINMUX_IPSR_MODSEL_DATA(IP11_21_18, RDS_DATA_D, SEL_RDS_3),
+	PINMUX_IPSR_MODSEL_DATA(IP11_21_18, FMIN_F, SEL_FM_5),
+	PINMUX_IPSR_MODSEL_DATA(IP11_21_18, RDS_DATA_E, SEL_RDS_4),
+	PINMUX_IPSR_DATA(IP11_23_22, MLB_CLK),
+	PINMUX_IPSR_MODSEL_DATA(IP11_23_22, SCL2_B, SEL_IIC2_1),
+	PINMUX_IPSR_MODSEL_DATA(IP11_23_22, SCL2_CIS_B, SEL_I2C2_1),
+	PINMUX_IPSR_DATA(IP11_26_24, MLB_SIG),
+	PINMUX_IPSR_MODSEL_DATA(IP11_26_24, SCIFB1_RXD_D, SEL_SCIFB1_3),
+	PINMUX_IPSR_MODSEL_DATA(IP11_26_24, RX1_C, SEL_SCIF1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP11_26_24, SDA2_B, SEL_IIC2_1),
+	PINMUX_IPSR_MODSEL_DATA(IP11_26_24, SDA2_CIS_B, SEL_I2C2_1),
+	PINMUX_IPSR_DATA(IP11_29_27, MLB_DAT),
+	PINMUX_IPSR_DATA(IP11_29_27, SPV_EVEN),
+	PINMUX_IPSR_MODSEL_DATA(IP11_29_27, SCIFB1_TXD_D, SEL_SCIFB1_3),
+	PINMUX_IPSR_MODSEL_DATA(IP11_29_27, TX1_C, SEL_SCIF1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP11_29_27, BPFCLK_C, SEL_FM_2),
+	PINMUX_IPSR_MODSEL_DATA(IP11_29_27, RDS_CLK_B, SEL_RDS_1),
+	PINMUX_IPSR_DATA(IP11_31_30, SSI_SCK0129),
+	PINMUX_IPSR_MODSEL_DATA(IP11_31_30, CAN_CLK_B, SEL_CANCLK_1),
+	PINMUX_IPSR_DATA(IP11_31_30, MOUT0),
+
+	PINMUX_IPSR_DATA(IP12_1_0, SSI_WS0129),
+	PINMUX_IPSR_MODSEL_DATA(IP12_1_0, CAN0_TX_B, SEL_CAN0_1),
+	PINMUX_IPSR_DATA(IP12_1_0, MOUT1),
+	PINMUX_IPSR_DATA(IP12_3_2, SSI_SDATA0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_3_2, CAN0_RX_B, SEL_CAN0_1),
+	PINMUX_IPSR_DATA(IP12_3_2, MOUT2),
+	PINMUX_IPSR_DATA(IP12_5_4, SSI_SDATA1),
+	PINMUX_IPSR_MODSEL_DATA(IP12_5_4, CAN1_TX_B, SEL_CAN1_1),
+	PINMUX_IPSR_DATA(IP12_5_4, MOUT5),
+	PINMUX_IPSR_DATA(IP12_7_6, SSI_SDATA2),
+	PINMUX_IPSR_MODSEL_DATA(IP12_7_6, CAN1_RX_B, SEL_CAN1_1),
+	PINMUX_IPSR_MODSEL_DATA(IP12_7_6, CAN1_TX_B, SEL_CAN1_1),
+	PINMUX_IPSR_DATA(IP12_7_6, MOUT6),
+	PINMUX_IPSR_DATA(IP12_10_8, SSI_SCK34),
+	PINMUX_IPSR_DATA(IP12_10_8, STP_OPWM_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_10_8, SCIFB0_SCK, SEL_SCIFB_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_10_8, MSIOF1_SCK, SEL_SOF1_0),
+	PINMUX_IPSR_DATA(IP12_10_8, CAN_DEBUG_HW_TRIGGER),
+	PINMUX_IPSR_DATA(IP12_13_11, SSI_WS34),
+	PINMUX_IPSR_MODSEL_DATA(IP12_13_11, STP_IVCXO27_0, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_13_11, SCIFB0_RXD, SEL_SCIFB_0),
+	PINMUX_IPSR_DATA(IP12_13_11, MSIOF1_SYNC),
+	PINMUX_IPSR_DATA(IP12_13_11, CAN_STEP0),
+	PINMUX_IPSR_DATA(IP12_16_14, SSI_SDATA3),
+	PINMUX_IPSR_MODSEL_DATA(IP12_16_14, STP_ISCLK_0, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_16_14, SCIFB0_TXD, SEL_SCIFB_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_16_14, MSIOF1_SS1, SEL_SOF1_0),
+	PINMUX_IPSR_DATA(IP12_16_14, CAN_TXCLK),
+	PINMUX_IPSR_DATA(IP12_19_17, SSI_SCK4),
+	PINMUX_IPSR_MODSEL_DATA(IP12_19_17, STP_ISD_0, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_19_17, SCIFB0_CTS_N, SEL_SCIFB_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_19_17, MSIOF1_SS2, SEL_SOF1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_19_17, SSI_SCK5_C, SEL_SSI5_2),
+	PINMUX_IPSR_DATA(IP12_19_17, CAN_DEBUGOUT0),
+	PINMUX_IPSR_DATA(IP12_22_20, SSI_WS4),
+	PINMUX_IPSR_MODSEL_DATA(IP12_22_20, STP_ISEN_0, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_22_20, SCIFB0_RTS_N, SEL_SCIFB_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_22_20, MSIOF1_TXD, SEL_SOF1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_22_20, SSI_WS5_C, SEL_SSI5_2),
+	PINMUX_IPSR_DATA(IP12_22_20, CAN_DEBUGOUT1),
+	PINMUX_IPSR_DATA(IP12_24_23, SSI_SDATA4),
+	PINMUX_IPSR_MODSEL_DATA(IP12_24_23, STP_ISSYNC_0, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_24_23, MSIOF1_RXD, SEL_SOF1_0),
+	PINMUX_IPSR_DATA(IP12_24_23, CAN_DEBUGOUT2),
+	PINMUX_IPSR_MODSEL_DATA(IP12_27_25, SSI_SCK5, SEL_SSI5_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_27_25, SCIFB1_SCK, SEL_SCIFB1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_27_25, IERX_B, SEL_IEB_1),
+	PINMUX_IPSR_DATA(IP12_27_25, DU2_EXHSYNC_DU2_HSYNC),
+	PINMUX_IPSR_DATA(IP12_27_25, QSTH_QHS),
+	PINMUX_IPSR_DATA(IP12_27_25, CAN_DEBUGOUT3),
+	PINMUX_IPSR_MODSEL_DATA(IP12_30_28, SSI_WS5, SEL_SSI5_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_30_28, SCIFB1_RXD, SEL_SCIFB1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP12_30_28, IECLK_B, SEL_IEB_1),
+	PINMUX_IPSR_DATA(IP12_30_28, DU2_EXVSYNC_DU2_VSYNC),
+	PINMUX_IPSR_DATA(IP12_30_28, QSTB_QHE),
+	PINMUX_IPSR_DATA(IP12_30_28, CAN_DEBUGOUT4),
+
+	PINMUX_IPSR_MODSEL_DATA(IP13_2_0, SSI_SDATA5, SEL_SSI5_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_2_0, SCIFB1_TXD, SEL_SCIFB1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_2_0, IETX_B, SEL_IEB_1),
+	PINMUX_IPSR_DATA(IP13_2_0, DU2_DR2),
+	PINMUX_IPSR_DATA(IP13_2_0, LCDOUT2),
+	PINMUX_IPSR_DATA(IP13_2_0, CAN_DEBUGOUT5),
+	PINMUX_IPSR_MODSEL_DATA(IP13_6_3, SSI_SCK6, SEL_SSI6_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_6_3, SCIFB1_CTS_N, SEL_SCIFB1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_6_3, BPFCLK_D, SEL_FM_3),
+	PINMUX_IPSR_MODSEL_DATA(IP13_6_3, RDS_CLK_C, SEL_RDS_2),
+	PINMUX_IPSR_DATA(IP13_6_3, DU2_DR3),
+	PINMUX_IPSR_DATA(IP13_6_3, LCDOUT3),
+	PINMUX_IPSR_DATA(IP13_6_3, CAN_DEBUGOUT6),
+	PINMUX_IPSR_MODSEL_DATA(IP13_6_3, BPFCLK_F, SEL_FM_5),
+	PINMUX_IPSR_MODSEL_DATA(IP13_6_3, RDS_CLK_E, SEL_RDS_4),
+	PINMUX_IPSR_MODSEL_DATA(IP13_9_7, SSI_WS6, SEL_SSI6_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_9_7, SCIFB1_RTS_N, SEL_SCIFB1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_9_7, CAN0_TX_D, SEL_CAN0_3),
+	PINMUX_IPSR_DATA(IP13_9_7, DU2_DR4),
+	PINMUX_IPSR_DATA(IP13_9_7, LCDOUT4),
+	PINMUX_IPSR_DATA(IP13_9_7, CAN_DEBUGOUT7),
+	PINMUX_IPSR_MODSEL_DATA(IP13_12_10, SSI_SDATA6, SEL_SSI6_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_12_10, FMIN_D, SEL_FM_3),
+	PINMUX_IPSR_MODSEL_DATA(IP13_12_10, RDS_DATA_C, SEL_RDS_2),
+	PINMUX_IPSR_DATA(IP13_12_10, DU2_DR5),
+	PINMUX_IPSR_DATA(IP13_12_10, LCDOUT5),
+	PINMUX_IPSR_DATA(IP13_12_10, CAN_DEBUGOUT8),
+	PINMUX_IPSR_MODSEL_DATA(IP13_15_13, SSI_SCK78, SEL_SSI7_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_15_13, STP_IVCXO27_1, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_15_13, SCK1, SEL_SCIF1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_15_13, SCIFA1_SCK, SEL_SCIFA1_0),
+	PINMUX_IPSR_DATA(IP13_15_13, DU2_DR6),
+	PINMUX_IPSR_DATA(IP13_15_13, LCDOUT6),
+	PINMUX_IPSR_DATA(IP13_15_13, CAN_DEBUGOUT9),
+	PINMUX_IPSR_MODSEL_DATA(IP13_18_16, SSI_WS78, SEL_SSI7_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_18_16, STP_ISCLK_1, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_18_16, SCIFB2_SCK, SEL_SCIFB2_0),
+	PINMUX_IPSR_DATA(IP13_18_16, SCIFA2_CTS_N),
+	PINMUX_IPSR_DATA(IP13_18_16, DU2_DR7),
+	PINMUX_IPSR_DATA(IP13_18_16, LCDOUT7),
+	PINMUX_IPSR_DATA(IP13_18_16, CAN_DEBUGOUT10),
+	PINMUX_IPSR_MODSEL_DATA(IP13_22_19, SSI_SDATA7, SEL_SSI7_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_22_19, STP_ISD_1, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_22_19, SCIFB2_RXD, SEL_SCIFB2_0),
+	PINMUX_IPSR_DATA(IP13_22_19, SCIFA2_RTS_N),
+	PINMUX_IPSR_DATA(IP13_22_19, TCLK2),
+	PINMUX_IPSR_DATA(IP13_22_19, QSTVA_QVS),
+	PINMUX_IPSR_DATA(IP13_22_19, CAN_DEBUGOUT11),
+	PINMUX_IPSR_MODSEL_DATA(IP13_22_19, BPFCLK_E, SEL_FM_4),
+	PINMUX_IPSR_MODSEL_DATA(IP13_22_19, RDS_CLK_D, SEL_RDS_3),
+	PINMUX_IPSR_MODSEL_DATA(IP13_22_19, SSI_SDATA7_B, SEL_SSI7_1),
+	PINMUX_IPSR_MODSEL_DATA(IP13_22_19, FMIN_G, SEL_FM_6),
+	PINMUX_IPSR_MODSEL_DATA(IP13_22_19, RDS_DATA_F, SEL_RDS_5),
+	PINMUX_IPSR_MODSEL_DATA(IP13_25_23, SSI_SDATA8, SEL_SSI8_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_25_23, STP_ISEN_1, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_25_23, SCIFB2_TXD, SEL_SCIFB2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_25_23, CAN0_TX_C, SEL_CAN0_2),
+	PINMUX_IPSR_DATA(IP13_25_23, CAN_DEBUGOUT12),
+	PINMUX_IPSR_MODSEL_DATA(IP13_25_23, SSI_SDATA8_B, SEL_SSI8_1),
+	PINMUX_IPSR_DATA(IP13_28_26, SSI_SDATA9),
+	PINMUX_IPSR_MODSEL_DATA(IP13_28_26, STP_ISSYNC_1, SEL_SSP_0),
+	PINMUX_IPSR_MODSEL_DATA(IP13_28_26, SCIFB2_CTS_N, SEL_SCIFB2_0),
+	PINMUX_IPSR_DATA(IP13_28_26, SSI_WS1),
+	PINMUX_IPSR_MODSEL_DATA(IP13_28_26, SSI_SDATA5_C, SEL_SSI5_2),
+	PINMUX_IPSR_DATA(IP13_28_26, CAN_DEBUGOUT13),
+	PINMUX_IPSR_DATA(IP13_30_29, AUDIO_CLKA),
+	PINMUX_IPSR_MODSEL_DATA(IP13_30_29, SCIFB2_RTS_N, SEL_SCIFB2_0),
+	PINMUX_IPSR_DATA(IP13_30_29, CAN_DEBUGOUT14),
+
+	PINMUX_IPSR_DATA(IP14_2_0, AUDIO_CLKB),
+	PINMUX_IPSR_MODSEL_DATA(IP14_2_0, SCIF_CLK, SEL_SCIFCLK_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_2_0, CAN0_RX_D, SEL_CAN0_3),
+	PINMUX_IPSR_DATA(IP14_2_0, DVC_MUTE),
+	PINMUX_IPSR_MODSEL_DATA(IP14_2_0, CAN0_RX_C, SEL_CAN0_2),
+	PINMUX_IPSR_DATA(IP14_2_0, CAN_DEBUGOUT15),
+	PINMUX_IPSR_DATA(IP14_2_0, REMOCON),
+	PINMUX_IPSR_MODSEL_DATA(IP14_5_3, SCIFA0_SCK, SEL_SCFA_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_5_3, HSCK1, SEL_HSCIF1_0),
+	PINMUX_IPSR_DATA(IP14_5_3, SCK0),
+	PINMUX_IPSR_DATA(IP14_5_3, MSIOF3_SS2),
+	PINMUX_IPSR_DATA(IP14_5_3, DU2_DG2),
+	PINMUX_IPSR_DATA(IP14_5_3, LCDOUT10),
+	PINMUX_IPSR_MODSEL_DATA(IP14_5_3, SDA1_C, SEL_IIC1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP14_5_3, SDA1_CIS_C, SEL_I2C1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP14_8_6, SCIFA0_RXD, SEL_SCFA_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_8_6, HRX1, SEL_HSCIF1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_8_6, RX0, SEL_SCIF0_0),
+	PINMUX_IPSR_DATA(IP14_8_6, DU2_DR0),
+	PINMUX_IPSR_DATA(IP14_8_6, LCDOUT0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_11_9, SCIFA0_TXD, SEL_SCFA_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_11_9, HTX1, SEL_HSCIF1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_11_9, TX0, SEL_SCIF0_0),
+	PINMUX_IPSR_DATA(IP14_11_9, DU2_DR1),
+	PINMUX_IPSR_DATA(IP14_11_9, LCDOUT1),
+	PINMUX_IPSR_MODSEL_DATA(IP14_15_12, SCIFA0_CTS_N, SEL_SCFA_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_15_12, HCTS1_N, SEL_HSCIF1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_15_12, CTS0_N, SEL_SCIF0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_15_12, MSIOF3_SYNC, SEL_SOF3_0),
+	PINMUX_IPSR_DATA(IP14_15_12, DU2_DG3),
+	PINMUX_IPSR_MODSEL_DATA(IP14_15_12, LCDOUT11, SEL_HSCIF1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_15_12, PWM0_B, SEL_SCIF0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_15_12, SCL1_C, SEL_IIC1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP14_15_12, SCL1_CIS_C, SEL_I2C1_2),
+	PINMUX_IPSR_MODSEL_DATA(IP14_18_16, SCIFA0_RTS_N, SEL_SCFA_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_18_16, HRTS1_N, SEL_HSCIF1_0),
+	PINMUX_IPSR_DATA(IP14_18_16, RTS0_N_TANS),
+	PINMUX_IPSR_DATA(IP14_18_16, MSIOF3_SS1),
+	PINMUX_IPSR_DATA(IP14_18_16, DU2_DG0),
+	PINMUX_IPSR_DATA(IP14_18_16, LCDOUT8),
+	PINMUX_IPSR_DATA(IP14_18_16, PWM1_B),
+	PINMUX_IPSR_MODSEL_DATA(IP14_21_19, SCIFA1_RXD, SEL_SCIFA1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_21_19, AD_DI, SEL_ADI_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_21_19, RX1, SEL_SCIF1_0),
+	PINMUX_IPSR_DATA(IP14_21_19, DU2_EXODDF_DU2_ODDF_DISP_CDE),
+	PINMUX_IPSR_DATA(IP14_21_19, QCPV_QDE),
+	PINMUX_IPSR_MODSEL_DATA(IP14_24_22, SCIFA1_TXD, SEL_SCIFA1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_24_22, AD_DO, SEL_ADI_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_24_22, TX1, SEL_SCIF1_0),
+	PINMUX_IPSR_DATA(IP14_24_22, DU2_DG1),
+	PINMUX_IPSR_DATA(IP14_24_22, LCDOUT9),
+	PINMUX_IPSR_MODSEL_DATA(IP14_27_25, SCIFA1_CTS_N, SEL_SCIFA1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_27_25, AD_CLK, SEL_ADI_0),
+	PINMUX_IPSR_DATA(IP14_27_25, CTS1_N),
+	PINMUX_IPSR_MODSEL_DATA(IP14_27_25, MSIOF3_RXD, SEL_SOF3_0),
+	PINMUX_IPSR_DATA(IP14_27_25, DU0_DOTCLKOUT),
+	PINMUX_IPSR_DATA(IP14_27_25, QCLK),
+	PINMUX_IPSR_MODSEL_DATA(IP14_30_28, SCIFA1_RTS_N, SEL_SCIFA1_0),
+	PINMUX_IPSR_MODSEL_DATA(IP14_30_28, AD_NCS_N, SEL_ADI_0),
+	PINMUX_IPSR_DATA(IP14_30_28, RTS1_N_TANS),
+	PINMUX_IPSR_MODSEL_DATA(IP14_30_28, MSIOF3_TXD, SEL_SOF3_0),
+	PINMUX_IPSR_DATA(IP14_30_28, DU1_DOTCLKOUT),
+	PINMUX_IPSR_DATA(IP14_30_28, QSTVB_QVE),
+	PINMUX_IPSR_MODSEL_DATA(IP14_30_28, HRTS0_N_C, SEL_HSCIF0_2),
+
+	PINMUX_IPSR_MODSEL_DATA(IP15_2_0, SCIFA2_SCK, SEL_SCIFA2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_2_0, FMCLK, SEL_FM_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_2_0, MSIOF3_SCK, SEL_SOF3_0),
+	PINMUX_IPSR_DATA(IP15_2_0, DU2_DG7),
+	PINMUX_IPSR_DATA(IP15_2_0, LCDOUT15),
+	PINMUX_IPSR_MODSEL_DATA(IP15_2_0, SCIF_CLK_B, SEL_SCIFCLK_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_5_3, SCIFA2_RXD, SEL_SCIFA2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_5_3, FMIN, SEL_FM_0),
+	PINMUX_IPSR_DATA(IP15_5_3, DU2_DB0),
+	PINMUX_IPSR_DATA(IP15_5_3, LCDOUT16),
+	PINMUX_IPSR_MODSEL_DATA(IP15_5_3, SCL2, SEL_IIC2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_5_3, SCL2_CIS, SEL_I2C2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_8_6, SCIFA2_TXD, SEL_SCIFA2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_8_6, BPFCLK, SEL_FM_0),
+	PINMUX_IPSR_DATA(IP15_8_6, DU2_DB1),
+	PINMUX_IPSR_DATA(IP15_8_6, LCDOUT17),
+	PINMUX_IPSR_MODSEL_DATA(IP15_8_6, SDA2, SEL_IIC2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_8_6, SDA2_CIS, SEL_I2C2_0),
+	PINMUX_IPSR_DATA(IP15_11_9, HSCK0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_11_9, TS_SDEN0, SEL_TSIF0_0),
+	PINMUX_IPSR_DATA(IP15_11_9, DU2_DG4),
+	PINMUX_IPSR_DATA(IP15_11_9, LCDOUT12),
+	PINMUX_IPSR_MODSEL_DATA(IP15_11_9, HCTS0_N_C, SEL_IIC2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_11_9, SDA2_CIS, SEL_I2C2_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_13_12, HRX0, SEL_HSCIF0_0),
+	PINMUX_IPSR_DATA(IP15_13_12, DU2_DB2),
+	PINMUX_IPSR_DATA(IP15_13_12, LCDOUT18),
+	PINMUX_IPSR_MODSEL_DATA(IP15_15_14, HTX0, SEL_HSCIF0_0),
+	PINMUX_IPSR_DATA(IP15_15_14, DU2_DB3),
+	PINMUX_IPSR_DATA(IP15_15_14, LCDOUT19),
+	PINMUX_IPSR_MODSEL_DATA(IP15_17_16, HCTS0_N, SEL_HSCIF0_0),
+	PINMUX_IPSR_DATA(IP15_17_16, SSI_SCK9),
+	PINMUX_IPSR_DATA(IP15_17_16, DU2_DB4),
+	PINMUX_IPSR_DATA(IP15_17_16, LCDOUT20),
+	PINMUX_IPSR_MODSEL_DATA(IP15_19_18, HRTS0_N, SEL_HSCIF0_0),
+	PINMUX_IPSR_DATA(IP15_19_18, SSI_WS9),
+	PINMUX_IPSR_DATA(IP15_19_18, DU2_DB5),
+	PINMUX_IPSR_DATA(IP15_19_18, LCDOUT21),
+	PINMUX_IPSR_MODSEL_DATA(IP15_22_20, MSIOF0_SCK, SEL_SOF0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP15_22_20, TS_SDAT0, SEL_TSIF0_0),
+	PINMUX_IPSR_DATA(IP15_22_20, ADICLK),
+	PINMUX_IPSR_DATA(IP15_22_20, DU2_DB6),
+	PINMUX_IPSR_DATA(IP15_22_20, LCDOUT22),
+	PINMUX_IPSR_DATA(IP15_25_23, MSIOF0_SYNC),
+	PINMUX_IPSR_MODSEL_DATA(IP15_25_23, TS_SCK0, SEL_TSIF0_0),
+	PINMUX_IPSR_DATA(IP15_25_23, SSI_SCK2),
+	PINMUX_IPSR_DATA(IP15_25_23, ADIDATA),
+	PINMUX_IPSR_DATA(IP15_25_23, DU2_DB7),
+	PINMUX_IPSR_DATA(IP15_25_23, LCDOUT23),
+	PINMUX_IPSR_MODSEL_DATA(IP15_25_23, SCIFA2_RXD_B, SEL_SCIFA2_1),
+	PINMUX_IPSR_MODSEL_DATA(IP15_27_26, MSIOF0_SS1, SEL_SOF0_0),
+	PINMUX_IPSR_DATA(IP15_27_26, ADICHS0),
+	PINMUX_IPSR_DATA(IP15_27_26, DU2_DG5),
+	PINMUX_IPSR_DATA(IP15_27_26, LCDOUT13),
+	PINMUX_IPSR_MODSEL_DATA(IP15_29_28, MSIOF0_TXD, SEL_SOF0_0),
+	PINMUX_IPSR_DATA(IP15_29_28, ADICHS1),
+	PINMUX_IPSR_DATA(IP15_29_28, DU2_DG6),
+	PINMUX_IPSR_DATA(IP15_29_28, LCDOUT14),
+
+	PINMUX_IPSR_MODSEL_DATA(IP16_2_0, MSIOF0_SS2, SEL_SOF0_0),
+	PINMUX_IPSR_DATA(IP16_2_0, AUDIO_CLKOUT),
+	PINMUX_IPSR_DATA(IP16_2_0, ADICHS2),
+	PINMUX_IPSR_DATA(IP16_2_0, DU2_DISP),
+	PINMUX_IPSR_DATA(IP16_2_0, QPOLA),
+	PINMUX_IPSR_MODSEL_DATA(IP16_2_0, HTX0_C, SEL_HSCIF0_2),
+	PINMUX_IPSR_MODSEL_DATA(IP16_2_0, SCIFA2_TXD_B, SEL_SCIFA2_1),
+	PINMUX_IPSR_MODSEL_DATA(IP16_5_3, MSIOF0_RXD, SEL_SOF0_0),
+	PINMUX_IPSR_MODSEL_DATA(IP16_5_3, TS_SPSYNC0, SEL_TSIF0_0),
+	PINMUX_IPSR_DATA(IP16_5_3, SSI_WS2),
+	PINMUX_IPSR_DATA(IP16_5_3, ADICS_SAMP),
+	PINMUX_IPSR_DATA(IP16_5_3, DU2_CDE),
+	PINMUX_IPSR_DATA(IP16_5_3, QPOLB),
+	PINMUX_IPSR_MODSEL_DATA(IP16_5_3, HRX0_C, SEL_HSCIF0_2),
+	PINMUX_IPSR_DATA(IP16_6, USB1_PWEN),
+	PINMUX_IPSR_DATA(IP16_6, AUDIO_CLKOUT_D),
+	PINMUX_IPSR_DATA(IP16_7, USB1_OVC),
+	PINMUX_IPSR_MODSEL_DATA(IP16_7, TCLK1_B, SEL_TMU1_1),
+};
+
+static struct sh_pfc_pin pinmux_pins[] = {
+	PINMUX_GPIO_GP_ALL(),
+};
+
+/* - ETH -------------------------------------------------------------------- */
+static const unsigned int eth_link_pins[] = {
+	/* LINK */
+	RCAR_GP_PIN(2, 22),
+};
+static const unsigned int eth_link_mux[] = {
+	ETH_LINK_MARK,
+};
+static const unsigned int eth_magic_pins[] = {
+	/* MAGIC */
+	RCAR_GP_PIN(2, 27),
+};
+static const unsigned int eth_magic_mux[] = {
+	ETH_MAGIC_MARK,
+};
+static const unsigned int eth_mdio_pins[] = {
+	/* MDC, MDIO */
+	RCAR_GP_PIN(2, 29), RCAR_GP_PIN(2, 24),
+};
+static const unsigned int eth_mdio_mux[] = {
+	ETH_MDC_MARK, ETH_MDIO_MARK,
+};
+static const unsigned int eth_rmii_pins[] = {
+	/* RXD[0:1], RX_ER, CRS_DV, TXD[0:1], TX_EN, REF_CLK */
+	RCAR_GP_PIN(2, 20), RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 19),
+	RCAR_GP_PIN(2, 18), RCAR_GP_PIN(2, 28), RCAR_GP_PIN(2, 25),
+	RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 23),
+};
+static const unsigned int eth_rmii_mux[] = {
+	ETH_RXD0_MARK, ETH_RXD1_MARK, ETH_RX_ER_MARK, ETH_CRS_DV_MARK,
+	ETH_TXD0_MARK, ETH_TXD1_MARK, ETH_TX_EN_MARK, ETH_REF_CLK_MARK,
+};
+/* - INTC ------------------------------------------------------------------- */
+static const unsigned int intc_irq0_pins[] = {
+	/* IRQ */
+	RCAR_GP_PIN(1, 25),
+};
+static const unsigned int intc_irq0_mux[] = {
+	IRQ0_MARK,
+};
+static const unsigned int intc_irq1_pins[] = {
+	/* IRQ */
+	RCAR_GP_PIN(1, 27),
+};
+static const unsigned int intc_irq1_mux[] = {
+	IRQ1_MARK,
+};
+static const unsigned int intc_irq2_pins[] = {
+	/* IRQ */
+	RCAR_GP_PIN(1, 29),
+};
+static const unsigned int intc_irq2_mux[] = {
+	IRQ2_MARK,
+};
+static const unsigned int intc_irq3_pins[] = {
+	/* IRQ */
+	RCAR_GP_PIN(1, 23),
+};
+static const unsigned int intc_irq3_mux[] = {
+	IRQ3_MARK,
+};
+/* - SCIF0 ----------------------------------------------------------------- */
+static const unsigned int scif0_data_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 29),
+};
+static const unsigned int scif0_data_mux[] = {
+	RX0_MARK, TX0_MARK,
+};
+static const unsigned int scif0_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(4, 27),
+};
+static const unsigned int scif0_clk_mux[] = {
+	SCK0_MARK,
+};
+static const unsigned int scif0_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(4, 31), RCAR_GP_PIN(4, 30),
+};
+static const unsigned int scif0_ctrl_mux[] = {
+	RTS0_N_TANS_MARK, CTS0_N_MARK,
+};
+static const unsigned int scif0_data_b_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5),
+};
+static const unsigned int scif0_data_b_mux[] = {
+	RX0_B_MARK, TX0_B_MARK,
+};
+/* - SCIF1 ----------------------------------------------------------------- */
+static const unsigned int scif1_data_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 1),
+};
+static const unsigned int scif1_data_mux[] = {
+	RX1_MARK, TX1_MARK,
+};
+static const unsigned int scif1_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(4, 20),
+};
+static const unsigned int scif1_clk_mux[] = {
+	SCK1_MARK,
+};
+static const unsigned int scif1_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 2),
+};
+static const unsigned int scif1_ctrl_mux[] = {
+	RTS1_N_TANS_MARK, CTS1_N_MARK,
+};
+static const unsigned int scif1_data_b_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 15),
+};
+static const unsigned int scif1_data_b_mux[] = {
+	RX1_B_MARK, TX1_B_MARK,
+};
+static const unsigned int scif1_data_c_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(4, 1), RCAR_GP_PIN(4, 2),
+};
+static const unsigned int scif1_data_c_mux[] = {
+	RX1_C_MARK, TX1_C_MARK,
+};
+static const unsigned int scif1_data_d_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(3, 18), RCAR_GP_PIN(3, 19),
+};
+static const unsigned int scif1_data_d_mux[] = {
+	RX1_D_MARK, TX1_D_MARK,
+};
+static const unsigned int scif1_clk_d_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(3, 17),
+};
+static const unsigned int scif1_clk_d_mux[] = {
+	SCK1_D_MARK,
+};
+static const unsigned int scif1_data_e_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 22),
+};
+static const unsigned int scif1_data_e_mux[] = {
+	RX1_E_MARK, TX1_E_MARK,
+};
+static const unsigned int scif1_clk_e_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(2, 20),
+};
+static const unsigned int scif1_clk_e_mux[] = {
+	SCK1_E_MARK,
+};
+/* - HSCIF0 ----------------------------------------------------------------- */
+static const unsigned int hscif0_data_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(5, 8), RCAR_GP_PIN(5, 9),
+};
+static const unsigned int hscif0_data_mux[] = {
+	HRX0_MARK, HTX0_MARK,
+};
+static const unsigned int hscif0_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(5, 7),
+};
+static const unsigned int hscif0_clk_mux[] = {
+	HSCK0_MARK,
+};
+static const unsigned int hscif0_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(5, 11), RCAR_GP_PIN(5, 10),
+};
+static const unsigned int hscif0_ctrl_mux[] = {
+	HRTS0_N_MARK, HCTS0_N_MARK,
+};
+static const unsigned int hscif0_data_b_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 12),
+};
+static const unsigned int hscif0_data_b_mux[] = {
+	HRX0_B_MARK, HTX0_B_MARK,
+};
+static const unsigned int hscif0_ctrl_b_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(1, 29), RCAR_GP_PIN(1, 28),
+};
+static const unsigned int hscif0_ctrl_b_mux[] = {
+	HRTS0_N_B_MARK, HCTS0_N_B_MARK,
+};
+static const unsigned int hscif0_data_c_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 16),
+};
+static const unsigned int hscif0_data_c_mux[] = {
+	HRX0_C_MARK, HTX0_C_MARK,
+};
+static const unsigned int hscif0_ctrl_c_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 7),
+};
+static const unsigned int hscif0_ctrl_c_mux[] = {
+	HRTS0_N_C_MARK, HCTS0_N_C_MARK,
+};
+static const unsigned int hscif0_data_d_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(3, 20), RCAR_GP_PIN(3, 21),
+};
+static const unsigned int hscif0_data_d_mux[] = {
+	HRX0_D_MARK, HTX0_D_MARK,
+};
+static const unsigned int hscif0_ctrl_d_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(3, 23), RCAR_GP_PIN(3, 22),
+};
+static const unsigned int hscif0_ctrl_d_mux[] = {
+	HRTS0_N_D_MARK, HCTS0_N_D_MARK,
+};
+static const unsigned int hscif0_data_e_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 22),
+};
+static const unsigned int hscif0_data_e_mux[] = {
+	HRX0_E_MARK, HTX0_E_MARK,
+};
+static const unsigned int hscif0_ctrl_e_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(2, 24), RCAR_GP_PIN(2, 23),
+};
+static const unsigned int hscif0_ctrl_e_mux[] = {
+	HRTS0_N_E_MARK, HCTS0_N_E_MARK,
+};
+static const unsigned int hscif0_data_f_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(2, 23), RCAR_GP_PIN(2, 25),
+};
+static const unsigned int hscif0_data_f_mux[] = {
+	HRX0_F_MARK, HTX0_F_MARK,
+};
+static const unsigned int hscif0_ctrl_f_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 24),
+};
+static const unsigned int hscif0_ctrl_f_mux[] = {
+	HRTS0_N_F_MARK, HCTS0_N_F_MARK,
+};
+/* - HSCIF1 ----------------------------------------------------------------- */
+static const unsigned int hscif1_data_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 29),
+};
+static const unsigned int hscif1_data_mux[] = {
+	HRX1_MARK, HTX1_MARK,
+};
+static const unsigned int hscif1_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(4, 27),
+};
+static const unsigned int hscif1_clk_mux[] = {
+	HSCK1_MARK,
+};
+static const unsigned int hscif1_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(4, 31), RCAR_GP_PIN(4, 30),
+};
+static const unsigned int hscif1_ctrl_mux[] = {
+	HRTS1_N_MARK, HCTS1_N_MARK,
+};
+static const unsigned int hscif1_data_b_pins[] = {
+	/* RX, TX */
+	RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 18),
+};
+static const unsigned int hscif1_data_b_mux[] = {
+	HRX1_B_MARK, HTX1_B_MARK,
+};
+static const unsigned int hscif1_clk_b_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(1, 28),
+};
+static const unsigned int hscif1_clk_b_mux[] = {
+	HSCK1_B_MARK,
+};
+static const unsigned int hscif1_ctrl_b_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13),
+};
+static const unsigned int hscif1_ctrl_b_mux[] = {
+	HRTS1_N_B_MARK, HCTS1_N_B_MARK,
+};
+/* - SCIFA0 ----------------------------------------------------------------- */
+static const unsigned int scifa0_data_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 29),
+};
+static const unsigned int scifa0_data_mux[] = {
+	SCIFA0_RXD_MARK, SCIFA0_TXD_MARK,
+};
+static const unsigned int scifa0_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(4, 27),
+};
+static const unsigned int scifa0_clk_mux[] = {
+	SCIFA0_SCK_MARK,
+};
+static const unsigned int scifa0_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(4, 31), RCAR_GP_PIN(4, 30),
+};
+static const unsigned int scifa0_ctrl_mux[] = {
+	SCIFA0_RTS_N_MARK, SCIFA0_CTS_N_MARK,
+};
+static const unsigned int scifa0_data_b_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 21),
+};
+static const unsigned int scifa0_data_b_mux[] = {
+	SCIFA0_RXD_B_MARK, SCIFA0_TXD_B_MARK
+};
+static const unsigned int scifa0_clk_b_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(1, 19),
+};
+static const unsigned int scifa0_clk_b_mux[] = {
+	SCIFA0_SCK_B_MARK,
+};
+static const unsigned int scifa0_ctrl_b_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 22),
+};
+static const unsigned int scifa0_ctrl_b_mux[] = {
+	SCIFA0_RTS_N_B_MARK, SCIFA0_CTS_N_B_MARK,
+};
+/* - SCIFA1 ----------------------------------------------------------------- */
+static const unsigned int scifa1_data_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 1),
+};
+static const unsigned int scifa1_data_mux[] = {
+	SCIFA1_RXD_MARK, SCIFA1_TXD_MARK,
+};
+static const unsigned int scifa1_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(4, 20),
+};
+static const unsigned int scifa1_clk_mux[] = {
+	SCIFA1_SCK_MARK,
+};
+static const unsigned int scifa1_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 2),
+};
+static const unsigned int scifa1_ctrl_mux[] = {
+	SCIFA1_RTS_N_MARK, SCIFA1_CTS_N_MARK,
+};
+static const unsigned int scifa1_data_b_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 21),
+};
+static const unsigned int scifa1_data_b_mux[] = {
+	SCIFA1_RXD_B_MARK, SCIFA1_TXD_B_MARK,
+};
+static const unsigned int scifa1_clk_b_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(0, 23),
+};
+static const unsigned int scifa1_clk_b_mux[] = {
+	SCIFA1_SCK_B_MARK,
+};
+static const unsigned int scifa1_ctrl_b_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(0, 22), RCAR_GP_PIN(0, 25),
+};
+static const unsigned int scifa1_ctrl_b_mux[] = {
+	SCIFA1_RTS_N_B_MARK, SCIFA1_CTS_N_B_MARK,
+};
+static const unsigned int scifa1_data_c_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 10),
+};
+static const unsigned int scifa1_data_c_mux[] = {
+	SCIFA1_RXD_C_MARK, SCIFA1_TXD_C_MARK,
+};
+static const unsigned int scifa1_clk_c_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(0, 8),
+};
+static const unsigned int scifa1_clk_c_mux[] = {
+	SCIFA1_SCK_C_MARK,
+};
+static const unsigned int scifa1_ctrl_c_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11),
+};
+static const unsigned int scifa1_ctrl_c_mux[] = {
+	SCIFA1_RTS_N_C_MARK, SCIFA1_CTS_N_C_MARK,
+};
+static const unsigned int scifa1_data_d_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 12),
+};
+static const unsigned int scifa1_data_d_mux[] = {
+	SCIFA1_RXD_D_MARK, SCIFA1_TXD_D_MARK,
+};
+static const unsigned int scifa1_clk_d_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(2, 10),
+};
+static const unsigned int scifa1_clk_d_mux[] = {
+	SCIFA1_SCK_D_MARK,
+};
+static const unsigned int scifa1_ctrl_d_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 13),
+};
+static const unsigned int scifa1_ctrl_d_mux[] = {
+	SCIFA1_RTS_N_D_MARK, SCIFA1_CTS_N_D_MARK,
+};
+/* - SCIFA2 ----------------------------------------------------------------- */
+static const unsigned int scifa2_data_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 6),
+};
+static const unsigned int scifa2_data_mux[] = {
+	SCIFA2_RXD_MARK, SCIFA2_TXD_MARK,
+};
+static const unsigned int scifa2_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(5, 4),
+};
+static const unsigned int scifa2_clk_mux[] = {
+	SCIFA2_SCK_MARK,
+};
+static const unsigned int scifa2_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(4, 22), RCAR_GP_PIN(4, 21),
+};
+static const unsigned int scifa2_ctrl_mux[] = {
+	SCIFA2_RTS_N_MARK, SCIFA2_CTS_N_MARK,
+};
+static const unsigned int scifa2_data_b_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(5, 13), RCAR_GP_PIN(5, 16),
+};
+static const unsigned int scifa2_data_b_mux[] = {
+	SCIFA2_RXD_B_MARK, SCIFA2_TXD_B_MARK,
+};
+static const unsigned int scifa2_data_c_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(5, 31), RCAR_GP_PIN(5, 30),
+};
+static const unsigned int scifa2_data_c_mux[] = {
+	SCIFA2_RXD_C_MARK, SCIFA2_TXD_C_MARK,
+};
+static const unsigned int scifa2_clk_c_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(5, 29),
+};
+static const unsigned int scifa2_clk_c_mux[] = {
+	SCIFA2_SCK_C_MARK,
+};
+/* - SCIFB0 ----------------------------------------------------------------- */
+static const unsigned int scifb0_data_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(4, 9), RCAR_GP_PIN(4, 10),
+};
+static const unsigned int scifb0_data_mux[] = {
+	SCIFB0_RXD_MARK, SCIFB0_TXD_MARK,
+};
+static const unsigned int scifb0_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(4, 8),
+};
+static const unsigned int scifb0_clk_mux[] = {
+	SCIFB0_SCK_MARK,
+};
+static const unsigned int scifb0_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(4, 12), RCAR_GP_PIN(4, 11),
+};
+static const unsigned int scifb0_ctrl_mux[] = {
+	SCIFB0_RTS_N_MARK, SCIFB0_CTS_N_MARK,
+};
+static const unsigned int scifb0_data_b_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
+};
+static const unsigned int scifb0_data_b_mux[] = {
+	SCIFB0_RXD_B_MARK, SCIFB0_TXD_B_MARK,
+};
+static const unsigned int scifb0_clk_b_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(3, 9),
+};
+static const unsigned int scifb0_clk_b_mux[] = {
+	SCIFB0_SCK_B_MARK,
+};
+static const unsigned int scifb0_ctrl_b_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 12),
+};
+static const unsigned int scifb0_ctrl_b_mux[] = {
+	SCIFB0_RTS_N_B_MARK, SCIFB0_CTS_N_B_MARK,
+};
+static const unsigned int scifb0_data_c_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5),
+};
+static const unsigned int scifb0_data_c_mux[] = {
+	SCIFB0_RXD_C_MARK, SCIFB0_TXD_C_MARK,
+};
+/* - SCIFB1 ----------------------------------------------------------------- */
+static const unsigned int scifb1_data_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(4, 15), RCAR_GP_PIN(4, 16),
+};
+static const unsigned int scifb1_data_mux[] = {
+	SCIFB1_RXD_MARK, SCIFB1_TXD_MARK,
+};
+static const unsigned int scifb1_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(4, 14),
+};
+static const unsigned int scifb1_clk_mux[] = {
+	SCIFB1_SCK_MARK,
+};
+static const unsigned int scifb1_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(4, 18), RCAR_GP_PIN(4, 17),
+};
+static const unsigned int scifb1_ctrl_mux[] = {
+	SCIFB1_RTS_N_MARK, SCIFB1_CTS_N_MARK,
+};
+static const unsigned int scifb1_data_b_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(3, 2), RCAR_GP_PIN(3, 3),
+};
+static const unsigned int scifb1_data_b_mux[] = {
+	SCIFB1_RXD_B_MARK, SCIFB1_TXD_B_MARK,
+};
+static const unsigned int scifb1_clk_b_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(3, 1),
+};
+static const unsigned int scifb1_clk_b_mux[] = {
+	SCIFB1_SCK_B_MARK,
+};
+static const unsigned int scifb1_ctrl_b_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(3, 5), RCAR_GP_PIN(3, 4),
+};
+static const unsigned int scifb1_ctrl_b_mux[] = {
+	SCIFB1_RTS_N_B_MARK, SCIFB1_CTS_N_B_MARK,
+};
+static const unsigned int scifb1_data_c_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 15),
+};
+static const unsigned int scifb1_data_c_mux[] = {
+	SCIFB1_RXD_C_MARK, SCIFB1_TXD_C_MARK,
+};
+static const unsigned int scifb1_data_d_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(4, 1), RCAR_GP_PIN(4, 2),
+};
+static const unsigned int scifb1_data_d_mux[] = {
+	SCIFB1_RXD_D_MARK, SCIFB1_TXD_D_MARK,
+};
+static const unsigned int scifb1_data_e_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(3, 18), RCAR_GP_PIN(3, 19),
+};
+static const unsigned int scifb1_data_e_mux[] = {
+	SCIFB1_RXD_E_MARK, SCIFB1_TXD_E_MARK,
+};
+static const unsigned int scifb1_clk_e_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(3, 17),
+};
+static const unsigned int scifb1_clk_e_mux[] = {
+	SCIFB1_SCK_E_MARK,
+};
+static const unsigned int scifb1_data_f_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5),
+};
+static const unsigned int scifb1_data_f_mux[] = {
+	SCIFB1_RXD_F_MARK, SCIFB1_TXD_F_MARK,
+};
+static const unsigned int scifb1_data_g_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 22),
+};
+static const unsigned int scifb1_data_g_mux[] = {
+	SCIFB1_RXD_G_MARK, SCIFB1_TXD_G_MARK,
+};
+static const unsigned int scifb1_clk_g_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(2, 20),
+};
+static const unsigned int scifb1_clk_g_mux[] = {
+	SCIFB1_SCK_G_MARK,
+};
+/* - SCIFB2 ----------------------------------------------------------------- */
+static const unsigned int scifb2_data_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(4, 22), RCAR_GP_PIN(4, 23),
+};
+static const unsigned int scifb2_data_mux[] = {
+	SCIFB2_RXD_MARK, SCIFB2_TXD_MARK,
+};
+static const unsigned int scifb2_clk_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(4, 21),
+};
+static const unsigned int scifb2_clk_mux[] = {
+	SCIFB2_SCK_MARK,
+};
+static const unsigned int scifb2_ctrl_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(4, 25), RCAR_GP_PIN(4, 24),
+};
+static const unsigned int scifb2_ctrl_mux[] = {
+	SCIFB2_RTS_N_MARK, SCIFB2_CTS_N_MARK,
+};
+static const unsigned int scifb2_data_b_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(0, 28), RCAR_GP_PIN(0, 30),
+};
+static const unsigned int scifb2_data_b_mux[] = {
+	SCIFB2_RXD_B_MARK, SCIFB2_TXD_B_MARK,
+};
+static const unsigned int scifb2_clk_b_pins[] = {
+	/* SCK */
+	RCAR_GP_PIN(0, 31),
+};
+static const unsigned int scifb2_clk_b_mux[] = {
+	SCIFB2_SCK_B_MARK,
+};
+static const unsigned int scifb2_ctrl_b_pins[] = {
+	/* RTS, CTS */
+	RCAR_GP_PIN(0, 29), RCAR_GP_PIN(0, 27),
+};
+static const unsigned int scifb2_ctrl_b_mux[] = {
+	SCIFB2_RTS_N_B_MARK, SCIFB2_CTS_N_B_MARK,
+};
+static const unsigned int scifb2_data_c_pins[] = {
+	/* RXD, TXD */
+	RCAR_GP_PIN(0, 24), RCAR_GP_PIN(0, 25),
+};
+static const unsigned int scifb2_data_c_mux[] = {
+	SCIFB2_RXD_C_MARK, SCIFB2_TXD_C_MARK,
+};
+/* - TPU0 ------------------------------------------------------------------- */
+static const unsigned int tpu0_to0_pins[] = {
+	/* TO */
+	RCAR_GP_PIN(0, 20),
+};
+static const unsigned int tpu0_to0_mux[] = {
+	TPU0TO0_MARK,
+};
+static const unsigned int tpu0_to1_pins[] = {
+	/* TO */
+	RCAR_GP_PIN(0, 21),
+};
+static const unsigned int tpu0_to1_mux[] = {
+	TPU0TO1_MARK,
+};
+static const unsigned int tpu0_to2_pins[] = {
+	/* TO */
+	RCAR_GP_PIN(0, 22),
+};
+static const unsigned int tpu0_to2_mux[] = {
+	TPU0TO2_MARK,
+};
+static const unsigned int tpu0_to3_pins[] = {
+	/* TO */
+	RCAR_GP_PIN(0, 23),
+};
+static const unsigned int tpu0_to3_mux[] = {
+	TPU0TO3_MARK,
+};
+/* - MMCIF0 ----------------------------------------------------------------- */
+static const unsigned int mmc0_data1_pins[] = {
+	/* D[0] */
+	RCAR_GP_PIN(3, 18),
+};
+static const unsigned int mmc0_data1_mux[] = {
+	MMC0_D0_MARK,
+};
+static const unsigned int mmc0_data4_pins[] = {
+	/* D[0:3] */
+	RCAR_GP_PIN(3, 18), RCAR_GP_PIN(3, 19),
+	RCAR_GP_PIN(3, 20), RCAR_GP_PIN(3, 21),
+};
+static const unsigned int mmc0_data4_mux[] = {
+	MMC0_D0_MARK, MMC0_D1_MARK, MMC0_D2_MARK, MMC0_D3_MARK,
+};
+static const unsigned int mmc0_data8_pins[] = {
+	/* D[0:7] */
+	RCAR_GP_PIN(3, 18), RCAR_GP_PIN(3, 19),
+	RCAR_GP_PIN(3, 20), RCAR_GP_PIN(3, 21),
+	RCAR_GP_PIN(3, 22), RCAR_GP_PIN(3, 23),
+	RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
+};
+static const unsigned int mmc0_data8_mux[] = {
+	MMC0_D0_MARK, MMC0_D1_MARK, MMC0_D2_MARK, MMC0_D3_MARK,
+	MMC0_D4_MARK, MMC0_D5_MARK, MMC0_D6_MARK, MMC0_D7_MARK,
+};
+static const unsigned int mmc0_ctrl_pins[] = {
+	/* CLK, CMD */
+	RCAR_GP_PIN(3, 16), RCAR_GP_PIN(3, 17),
+};
+static const unsigned int mmc0_ctrl_mux[] = {
+	MMC0_CLK_MARK, MMC0_CMD_MARK,
+};
+/* - MMCIF1 ----------------------------------------------------------------- */
+static const unsigned int mmc1_data1_pins[] = {
+	/* D[0] */
+	RCAR_GP_PIN(3, 26),
+};
+static const unsigned int mmc1_data1_mux[] = {
+	MMC1_D0_MARK,
+};
+static const unsigned int mmc1_data4_pins[] = {
+	/* D[0:3] */
+	RCAR_GP_PIN(3, 26), RCAR_GP_PIN(3, 27),
+	RCAR_GP_PIN(3, 28), RCAR_GP_PIN(3, 29),
+};
+static const unsigned int mmc1_data4_mux[] = {
+	MMC1_D0_MARK, MMC1_D1_MARK, MMC1_D2_MARK, MMC1_D3_MARK,
+};
+static const unsigned int mmc1_data8_pins[] = {
+	/* D[0:7] */
+	RCAR_GP_PIN(3, 26), RCAR_GP_PIN(3, 27),
+	RCAR_GP_PIN(3, 28), RCAR_GP_PIN(3, 29),
+	RCAR_GP_PIN(3, 30), RCAR_GP_PIN(3, 31),
+	RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
+};
+static const unsigned int mmc1_data8_mux[] = {
+	MMC1_D0_MARK, MMC1_D1_MARK, MMC1_D2_MARK, MMC1_D3_MARK,
+	MMC1_D4_MARK, MMC1_D5_MARK, MMC1_D6_MARK, MMC1_D7_MARK,
+};
+static const unsigned int mmc1_ctrl_pins[] = {
+	/* CLK, CMD */
+	RCAR_GP_PIN(3, 24), RCAR_GP_PIN(3, 25),
+};
+static const unsigned int mmc1_ctrl_mux[] = {
+	MMC1_CLK_MARK, MMC1_CMD_MARK,
+};
+/* - SDHI0 ------------------------------------------------------------------ */
+static const unsigned int sdhi0_data1_pins[] = {
+	/* D0 */
+	RCAR_GP_PIN(3, 2),
+};
+static const unsigned int sdhi0_data1_mux[] = {
+	SD0_DAT0_MARK,
+};
+static const unsigned int sdhi0_data4_pins[] = {
+	/* D[0:3] */
+	RCAR_GP_PIN(3, 2), RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
+};
+static const unsigned int sdhi0_data4_mux[] = {
+	SD0_DAT0_MARK, SD0_DAT1_MARK, SD0_DAT2_MARK, SD0_DAT3_MARK,
+};
+static const unsigned int sdhi0_ctrl_pins[] = {
+	/* CLK, CMD */
+	RCAR_GP_PIN(3, 0), RCAR_GP_PIN(3, 1),
+};
+static const unsigned int sdhi0_ctrl_mux[] = {
+	SD0_CLK_MARK, SD0_CMD_MARK,
+};
+static const unsigned int sdhi0_cd_pins[] = {
+	/* CD */
+	RCAR_GP_PIN(3, 6),
+};
+static const unsigned int sdhi0_cd_mux[] = {
+	SD0_CD_MARK,
+};
+static const unsigned int sdhi0_wp_pins[] = {
+	/* WP */
+	RCAR_GP_PIN(3, 7),
+};
+static const unsigned int sdhi0_wp_mux[] = {
+	SD0_WP_MARK,
+};
+/* - SDHI1 ------------------------------------------------------------------ */
+static const unsigned int sdhi1_data1_pins[] = {
+	/* D0 */
+	RCAR_GP_PIN(3, 10),
+};
+static const unsigned int sdhi1_data1_mux[] = {
+	SD1_DAT0_MARK,
+};
+static const unsigned int sdhi1_data4_pins[] = {
+	/* D[0:3] */
+	RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11), RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
+};
+static const unsigned int sdhi1_data4_mux[] = {
+	SD1_DAT0_MARK, SD1_DAT1_MARK, SD1_DAT2_MARK, SD1_DAT3_MARK,
+};
+static const unsigned int sdhi1_ctrl_pins[] = {
+	/* CLK, CMD */
+	RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
+};
+static const unsigned int sdhi1_ctrl_mux[] = {
+	SD1_CLK_MARK, SD1_CMD_MARK,
+};
+static const unsigned int sdhi1_cd_pins[] = {
+	/* CD */
+	RCAR_GP_PIN(3, 14),
+};
+static const unsigned int sdhi1_cd_mux[] = {
+	SD1_CD_MARK,
+};
+static const unsigned int sdhi1_wp_pins[] = {
+	/* WP */
+	RCAR_GP_PIN(3, 15),
+};
+static const unsigned int sdhi1_wp_mux[] = {
+	SD1_WP_MARK,
+};
+/* - SDHI2 ------------------------------------------------------------------ */
+static const unsigned int sdhi2_data1_pins[] = {
+	/* D0 */
+	RCAR_GP_PIN(3, 18),
+};
+static const unsigned int sdhi2_data1_mux[] = {
+	SD2_DAT0_MARK,
+};
+static const unsigned int sdhi2_data4_pins[] = {
+	/* D[0:3] */
+	RCAR_GP_PIN(3, 18), RCAR_GP_PIN(3, 19), RCAR_GP_PIN(3, 20), RCAR_GP_PIN(3, 21),
+};
+static const unsigned int sdhi2_data4_mux[] = {
+	SD2_DAT0_MARK, SD2_DAT1_MARK, SD2_DAT2_MARK, SD2_DAT3_MARK,
+};
+static const unsigned int sdhi2_ctrl_pins[] = {
+	/* CLK, CMD */
+	RCAR_GP_PIN(3, 16), RCAR_GP_PIN(3, 17),
+};
+static const unsigned int sdhi2_ctrl_mux[] = {
+	SD2_CLK_MARK, SD2_CMD_MARK,
+};
+static const unsigned int sdhi2_cd_pins[] = {
+	/* CD */
+	RCAR_GP_PIN(3, 22),
+};
+static const unsigned int sdhi2_cd_mux[] = {
+	SD2_CD_MARK,
+};
+static const unsigned int sdhi2_wp_pins[] = {
+	/* WP */
+	RCAR_GP_PIN(3, 23),
+};
+static const unsigned int sdhi2_wp_mux[] = {
+	SD2_WP_MARK,
+};
+/* - SDHI3 ------------------------------------------------------------------ */
+static const unsigned int sdhi3_data1_pins[] = {
+	/* D0 */
+	RCAR_GP_PIN(3, 26),
+};
+static const unsigned int sdhi3_data1_mux[] = {
+	SD3_DAT0_MARK,
+};
+static const unsigned int sdhi3_data4_pins[] = {
+	/* D[0:3] */
+	RCAR_GP_PIN(3, 26), RCAR_GP_PIN(3, 27), RCAR_GP_PIN(3, 28), RCAR_GP_PIN(3, 29),
+};
+static const unsigned int sdhi3_data4_mux[] = {
+	SD3_DAT0_MARK, SD3_DAT1_MARK, SD3_DAT2_MARK, SD3_DAT3_MARK,
+};
+static const unsigned int sdhi3_ctrl_pins[] = {
+	/* CLK, CMD */
+	RCAR_GP_PIN(3, 24), RCAR_GP_PIN(3, 25),
+};
+static const unsigned int sdhi3_ctrl_mux[] = {
+	SD3_CLK_MARK, SD3_CMD_MARK,
+};
+static const unsigned int sdhi3_cd_pins[] = {
+	/* CD */
+	RCAR_GP_PIN(3, 30),
+};
+static const unsigned int sdhi3_cd_mux[] = {
+	SD3_CD_MARK,
+};
+static const unsigned int sdhi3_wp_pins[] = {
+	/* WP */
+	RCAR_GP_PIN(3, 31),
+};
+static const unsigned int sdhi3_wp_mux[] = {
+	SD3_WP_MARK,
+};
+
+static const struct sh_pfc_pin_group pinmux_groups[] = {
+	SH_PFC_PIN_GROUP(eth_link),
+	SH_PFC_PIN_GROUP(eth_magic),
+	SH_PFC_PIN_GROUP(eth_mdio),
+	SH_PFC_PIN_GROUP(eth_rmii),
+	SH_PFC_PIN_GROUP(hscif0_data),
+	SH_PFC_PIN_GROUP(hscif0_clk),
+	SH_PFC_PIN_GROUP(hscif0_ctrl),
+	SH_PFC_PIN_GROUP(hscif0_data_b),
+	SH_PFC_PIN_GROUP(hscif0_ctrl_b),
+	SH_PFC_PIN_GROUP(hscif0_data_c),
+	SH_PFC_PIN_GROUP(hscif0_ctrl_c),
+	SH_PFC_PIN_GROUP(hscif0_data_d),
+	SH_PFC_PIN_GROUP(hscif0_ctrl_d),
+	SH_PFC_PIN_GROUP(hscif0_data_e),
+	SH_PFC_PIN_GROUP(hscif0_ctrl_e),
+	SH_PFC_PIN_GROUP(hscif0_data_f),
+	SH_PFC_PIN_GROUP(hscif0_ctrl_f),
+	SH_PFC_PIN_GROUP(hscif1_data),
+	SH_PFC_PIN_GROUP(hscif1_clk),
+	SH_PFC_PIN_GROUP(hscif1_ctrl),
+	SH_PFC_PIN_GROUP(hscif1_data_b),
+	SH_PFC_PIN_GROUP(hscif1_clk_b),
+	SH_PFC_PIN_GROUP(hscif1_ctrl_b),
+	SH_PFC_PIN_GROUP(intc_irq0),
+	SH_PFC_PIN_GROUP(intc_irq1),
+	SH_PFC_PIN_GROUP(intc_irq2),
+	SH_PFC_PIN_GROUP(intc_irq3),
+	SH_PFC_PIN_GROUP(mmc0_data1),
+	SH_PFC_PIN_GROUP(mmc0_data4),
+	SH_PFC_PIN_GROUP(mmc0_data8),
+	SH_PFC_PIN_GROUP(mmc0_ctrl),
+	SH_PFC_PIN_GROUP(mmc1_data1),
+	SH_PFC_PIN_GROUP(mmc1_data4),
+	SH_PFC_PIN_GROUP(mmc1_data8),
+	SH_PFC_PIN_GROUP(mmc1_ctrl),
+	SH_PFC_PIN_GROUP(scif0_data),
+	SH_PFC_PIN_GROUP(scif0_clk),
+	SH_PFC_PIN_GROUP(scif0_ctrl),
+	SH_PFC_PIN_GROUP(scif0_data_b),
+	SH_PFC_PIN_GROUP(scif1_data),
+	SH_PFC_PIN_GROUP(scif1_clk),
+	SH_PFC_PIN_GROUP(scif1_ctrl),
+	SH_PFC_PIN_GROUP(scif1_data_b),
+	SH_PFC_PIN_GROUP(scif1_data_c),
+	SH_PFC_PIN_GROUP(scif1_data_d),
+	SH_PFC_PIN_GROUP(scif1_clk_d),
+	SH_PFC_PIN_GROUP(scif1_data_e),
+	SH_PFC_PIN_GROUP(scif1_clk_e),
+	SH_PFC_PIN_GROUP(scifa0_data),
+	SH_PFC_PIN_GROUP(scifa0_clk),
+	SH_PFC_PIN_GROUP(scifa0_ctrl),
+	SH_PFC_PIN_GROUP(scifa0_data_b),
+	SH_PFC_PIN_GROUP(scifa0_clk_b),
+	SH_PFC_PIN_GROUP(scifa0_ctrl_b),
+	SH_PFC_PIN_GROUP(scifa1_data),
+	SH_PFC_PIN_GROUP(scifa1_clk),
+	SH_PFC_PIN_GROUP(scifa1_ctrl),
+	SH_PFC_PIN_GROUP(scifa1_data_b),
+	SH_PFC_PIN_GROUP(scifa1_clk_b),
+	SH_PFC_PIN_GROUP(scifa1_ctrl_b),
+	SH_PFC_PIN_GROUP(scifa1_data_c),
+	SH_PFC_PIN_GROUP(scifa1_clk_c),
+	SH_PFC_PIN_GROUP(scifa1_ctrl_c),
+	SH_PFC_PIN_GROUP(scifa1_data_d),
+	SH_PFC_PIN_GROUP(scifa1_clk_d),
+	SH_PFC_PIN_GROUP(scifa1_ctrl_d),
+	SH_PFC_PIN_GROUP(scifa2_data),
+	SH_PFC_PIN_GROUP(scifa2_clk),
+	SH_PFC_PIN_GROUP(scifa2_ctrl),
+	SH_PFC_PIN_GROUP(scifa2_data_b),
+	SH_PFC_PIN_GROUP(scifa2_data_c),
+	SH_PFC_PIN_GROUP(scifa2_clk_c),
+	SH_PFC_PIN_GROUP(scifb0_data),
+	SH_PFC_PIN_GROUP(scifb0_clk),
+	SH_PFC_PIN_GROUP(scifb0_ctrl),
+	SH_PFC_PIN_GROUP(scifb0_data_b),
+	SH_PFC_PIN_GROUP(scifb0_clk_b),
+	SH_PFC_PIN_GROUP(scifb0_ctrl_b),
+	SH_PFC_PIN_GROUP(scifb0_data_c),
+	SH_PFC_PIN_GROUP(scifb1_data),
+	SH_PFC_PIN_GROUP(scifb1_clk),
+	SH_PFC_PIN_GROUP(scifb1_ctrl),
+	SH_PFC_PIN_GROUP(scifb1_data_b),
+	SH_PFC_PIN_GROUP(scifb1_clk_b),
+	SH_PFC_PIN_GROUP(scifb1_ctrl_b),
+	SH_PFC_PIN_GROUP(scifb1_data_c),
+	SH_PFC_PIN_GROUP(scifb1_data_d),
+	SH_PFC_PIN_GROUP(scifb1_data_e),
+	SH_PFC_PIN_GROUP(scifb1_clk_e),
+	SH_PFC_PIN_GROUP(scifb1_data_f),
+	SH_PFC_PIN_GROUP(scifb1_data_g),
+	SH_PFC_PIN_GROUP(scifb1_clk_g),
+	SH_PFC_PIN_GROUP(scifb2_data),
+	SH_PFC_PIN_GROUP(scifb2_clk),
+	SH_PFC_PIN_GROUP(scifb2_ctrl),
+	SH_PFC_PIN_GROUP(scifb2_data_b),
+	SH_PFC_PIN_GROUP(scifb2_clk_b),
+	SH_PFC_PIN_GROUP(scifb2_ctrl_b),
+	SH_PFC_PIN_GROUP(scifb2_data_c),
+	SH_PFC_PIN_GROUP(sdhi0_data1),
+	SH_PFC_PIN_GROUP(sdhi0_data4),
+	SH_PFC_PIN_GROUP(sdhi0_ctrl),
+	SH_PFC_PIN_GROUP(sdhi0_cd),
+	SH_PFC_PIN_GROUP(sdhi0_wp),
+	SH_PFC_PIN_GROUP(sdhi1_data1),
+	SH_PFC_PIN_GROUP(sdhi1_data4),
+	SH_PFC_PIN_GROUP(sdhi1_ctrl),
+	SH_PFC_PIN_GROUP(sdhi1_cd),
+	SH_PFC_PIN_GROUP(sdhi1_wp),
+	SH_PFC_PIN_GROUP(sdhi2_data1),
+	SH_PFC_PIN_GROUP(sdhi2_data4),
+	SH_PFC_PIN_GROUP(sdhi2_ctrl),
+	SH_PFC_PIN_GROUP(sdhi2_cd),
+	SH_PFC_PIN_GROUP(sdhi2_wp),
+	SH_PFC_PIN_GROUP(sdhi3_data1),
+	SH_PFC_PIN_GROUP(sdhi3_data4),
+	SH_PFC_PIN_GROUP(sdhi3_ctrl),
+	SH_PFC_PIN_GROUP(sdhi3_cd),
+	SH_PFC_PIN_GROUP(sdhi3_wp),
+	SH_PFC_PIN_GROUP(tpu0_to0),
+	SH_PFC_PIN_GROUP(tpu0_to1),
+	SH_PFC_PIN_GROUP(tpu0_to2),
+	SH_PFC_PIN_GROUP(tpu0_to3),
+};
+
+static const char * const eth_groups[] = {
+	"eth_link",
+	"eth_magic",
+	"eth_mdio",
+	"eth_rmii",
+};
+
+static const char * const intc_groups[] = {
+	"intc_irq0",
+	"intc_irq1",
+	"intc_irq2",
+	"intc_irq3",
+};
+
+static const char * const scif0_groups[] = {
+	"scif0_data",
+	"scif0_clk",
+	"scif0_ctrl",
+	"scif0_data_b",
+};
+
+static const char * const scif1_groups[] = {
+	"scif1_data",
+	"scif1_clk",
+	"scif1_ctrl",
+	"scif1_data_b",
+	"scif1_data_c",
+	"scif1_data_d",
+	"scif1_clk_d",
+	"scif1_data_e",
+	"scif1_clk_e",
+};
+
+static const char * const hscif0_groups[] = {
+	"hscif0_data",
+	"hscif0_clk",
+	"hscif0_ctrl",
+	"hscif0_data_b",
+	"hscif0_ctrl_b",
+	"hscif0_data_c",
+	"hscif0_ctrl_c",
+	"hscif0_data_d",
+	"hscif0_ctrl_d",
+	"hscif0_data_e",
+	"hscif0_ctrl_e",
+	"hscif0_data_f",
+	"hscif0_ctrl_f",
+};
+
+static const char * const hscif1_groups[] = {
+	"hscif1_data",
+	"hscif1_clk",
+	"hscif1_ctrl",
+	"hscif1_data_b",
+	"hscif1_clk_b",
+	"hscif1_ctrl_b",
+};
+
+static const char * const scifa0_groups[] = {
+	"scifa0_data",
+	"scifa0_clk",
+	"scifa0_ctrl",
+	"scifa0_data_b",
+	"scifa0_clk_b",
+	"scifa0_ctrl_b",
+};
+
+static const char * const scifa1_groups[] = {
+	"scifa1_data",
+	"scifa1_clk",
+	"scifa1_ctrl",
+	"scifa1_data_b",
+	"scifa1_clk_b",
+	"scifa1_ctrl_b",
+	"scifa1_data_c",
+	"scifa1_clk_c",
+	"scifa1_ctrl_c",
+	"scifa1_data_d",
+	"scifa1_clk_d",
+	"scifa1_ctrl_d",
+};
+
+static const char * const scifa2_groups[] = {
+	"scifa2_data",
+	"scifa2_clk",
+	"scifa2_ctrl",
+	"scifa2_data_b",
+	"scifa2_data_c",
+	"scifa2_clk_c",
+};
+
+static const char * const scifb0_groups[] = {
+	"scifb0_data",
+	"scifb0_clk",
+	"scifb0_ctrl",
+	"scifb0_data_b",
+	"scifb0_clk_b",
+	"scifb0_ctrl_b",
+	"scifb0_data_c",
+};
+
+static const char * const scifb1_groups[] = {
+	"scifb1_data",
+	"scifb1_clk",
+	"scifb1_ctrl",
+	"scifb1_data_b",
+	"scifb1_clk_b",
+	"scifb1_ctrl_b",
+	"scifb1_data_c",
+	"scifb1_data_d",
+	"scifb1_data_e",
+	"scifb1_clk_e",
+	"scifb1_data_f",
+	"scifb1_data_g",
+	"scifb1_clk_g",
+};
+
+static const char * const scifb2_groups[] = {
+	"scifb2_data",
+	"scifb2_clk",
+	"scifb2_ctrl",
+	"scifb2_data_b",
+	"scifb2_clk_b",
+	"scifb2_ctrl_b",
+	"scifb2_data_c",
+};
+
+static const char * const tpu0_groups[] = {
+	"tpu0_to0",
+	"tpu0_to1",
+	"tpu0_to2",
+	"tpu0_to3",
+};
+
+static const char * const mmc0_groups[] = {
+	"mmc0_data1",
+	"mmc0_data4",
+	"mmc0_data8",
+	"mmc0_ctrl",
+};
+
+static const char * const mmc1_groups[] = {
+	"mmc1_data1",
+	"mmc1_data4",
+	"mmc1_data8",
+	"mmc1_ctrl",
+};
+
+static const char * const sdhi0_groups[] = {
+	"sdhi0_data1",
+	"sdhi0_data4",
+	"sdhi0_ctrl",
+	"sdhi0_cd",
+	"sdhi0_wp",
+};
+
+static const char * const sdhi1_groups[] = {
+	"sdhi1_data1",
+	"sdhi1_data4",
+	"sdhi1_ctrl",
+	"sdhi1_cd",
+	"sdhi1_wp",
+};
+
+static const char * const sdhi2_groups[] = {
+	"sdhi2_data1",
+	"sdhi2_data4",
+	"sdhi2_ctrl",
+	"sdhi2_cd",
+	"sdhi2_wp",
+};
+
+static const char * const sdhi3_groups[] = {
+	"sdhi3_data1",
+	"sdhi3_data4",
+	"sdhi3_ctrl",
+	"sdhi3_cd",
+	"sdhi3_wp",
+};
+
+static const struct sh_pfc_function pinmux_functions[] = {
+	SH_PFC_FUNCTION(eth),
+	SH_PFC_FUNCTION(hscif0),
+	SH_PFC_FUNCTION(hscif1),
+	SH_PFC_FUNCTION(intc),
+	SH_PFC_FUNCTION(mmc0),
+	SH_PFC_FUNCTION(mmc1),
+	SH_PFC_FUNCTION(scif0),
+	SH_PFC_FUNCTION(scif1),
+	SH_PFC_FUNCTION(scifa0),
+	SH_PFC_FUNCTION(scifa1),
+	SH_PFC_FUNCTION(scifa2),
+	SH_PFC_FUNCTION(scifb0),
+	SH_PFC_FUNCTION(scifb1),
+	SH_PFC_FUNCTION(scifb2),
+	SH_PFC_FUNCTION(sdhi0),
+	SH_PFC_FUNCTION(sdhi1),
+	SH_PFC_FUNCTION(sdhi2),
+	SH_PFC_FUNCTION(sdhi3),
+	SH_PFC_FUNCTION(tpu0),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	{ PINMUX_CFG_REG("GPSR0", 0xE6060004, 32, 1) {
+		GP_0_31_FN, FN_IP3_17_15,
+		GP_0_30_FN, FN_IP3_14_12,
+		GP_0_29_FN, FN_IP3_11_8,
+		GP_0_28_FN, FN_IP3_7_4,
+		GP_0_27_FN, FN_IP3_3_0,
+		GP_0_26_FN, FN_IP2_28_26,
+		GP_0_25_FN, FN_IP2_25_22,
+		GP_0_24_FN, FN_IP2_21_18,
+		GP_0_23_FN, FN_IP2_17_15,
+		GP_0_22_FN, FN_IP2_14_12,
+		GP_0_21_FN, FN_IP2_11_9,
+		GP_0_20_FN, FN_IP2_8_6,
+		GP_0_19_FN, FN_IP2_5_3,
+		GP_0_18_FN, FN_IP2_2_0,
+		GP_0_17_FN, FN_IP1_29_28,
+		GP_0_16_FN, FN_IP1_27_26,
+		GP_0_15_FN, FN_IP1_25_22,
+		GP_0_14_FN, FN_IP1_21_18,
+		GP_0_13_FN, FN_IP1_17_15,
+		GP_0_12_FN, FN_IP1_14_12,
+		GP_0_11_FN, FN_IP1_11_8,
+		GP_0_10_FN, FN_IP1_7_4,
+		GP_0_9_FN, FN_IP1_3_0,
+		GP_0_8_FN, FN_IP0_30_27,
+		GP_0_7_FN, FN_IP0_26_23,
+		GP_0_6_FN, FN_IP0_22_20,
+		GP_0_5_FN, FN_IP0_19_16,
+		GP_0_4_FN, FN_IP0_15_12,
+		GP_0_3_FN, FN_IP0_11_9,
+		GP_0_2_FN, FN_IP0_8_6,
+		GP_0_1_FN, FN_IP0_5_3,
+		GP_0_0_FN, FN_IP0_2_0 }
+	},
+	{ PINMUX_CFG_REG("GPSR1", 0xE6060008, 32, 1) {
+		0, 0,
+		0, 0,
+		GP_1_29_FN, FN_IP6_13_11,
+		GP_1_28_FN, FN_IP6_10_9,
+		GP_1_27_FN, FN_IP6_8_6,
+		GP_1_26_FN, FN_IP6_5_3,
+		GP_1_25_FN, FN_IP6_2_0,
+		GP_1_24_FN, FN_IP5_29_27,
+		GP_1_23_FN, FN_IP5_26_24,
+		GP_1_22_FN, FN_IP5_23_21,
+		GP_1_21_FN, FN_IP5_20_18,
+		GP_1_20_FN, FN_IP5_17_15,
+		GP_1_19_FN, FN_IP5_14_13,
+		GP_1_18_FN, FN_IP5_12_10,
+		GP_1_17_FN, FN_IP5_9_6,
+		GP_1_16_FN, FN_IP5_5_3,
+		GP_1_15_FN, FN_IP5_2_0,
+		GP_1_14_FN, FN_IP4_29_27,
+		GP_1_13_FN, FN_IP4_26_24,
+		GP_1_12_FN, FN_IP4_23_21,
+		GP_1_11_FN, FN_IP4_20_18,
+		GP_1_10_FN, FN_IP4_17_15,
+		GP_1_9_FN, FN_IP4_14_12,
+		GP_1_8_FN, FN_IP4_11_9,
+		GP_1_7_FN, FN_IP4_8_6,
+		GP_1_6_FN, FN_IP4_5_3,
+		GP_1_5_FN, FN_IP4_2_0,
+		GP_1_4_FN, FN_IP3_31_29,
+		GP_1_3_FN, FN_IP3_28_26,
+		GP_1_2_FN, FN_IP3_25_23,
+		GP_1_1_FN, FN_IP3_22_20,
+		GP_1_0_FN, FN_IP3_19_18, }
+	},
+	{ PINMUX_CFG_REG("GPSR2", 0xE606000C, 32, 1) {
+		0, 0,
+		0, 0,
+		GP_2_29_FN, FN_IP7_15_13,
+		GP_2_28_FN, FN_IP7_12_10,
+		GP_2_27_FN, FN_IP7_9_8,
+		GP_2_26_FN, FN_IP7_7_6,
+		GP_2_25_FN, FN_IP7_5_3,
+		GP_2_24_FN, FN_IP7_2_0,
+		GP_2_23_FN, FN_IP6_31_29,
+		GP_2_22_FN, FN_IP6_28_26,
+		GP_2_21_FN, FN_IP6_25_23,
+		GP_2_20_FN, FN_IP6_22_20,
+		GP_2_19_FN, FN_IP6_19_17,
+		GP_2_18_FN, FN_IP6_16_14,
+		GP_2_17_FN, FN_VI1_DATA7_VI1_B7,
+		GP_2_16_FN, FN_IP8_27,
+		GP_2_15_FN, FN_IP8_26,
+		GP_2_14_FN, FN_IP8_25_24,
+		GP_2_13_FN, FN_IP8_23_22,
+		GP_2_12_FN, FN_IP8_21_20,
+		GP_2_11_FN, FN_IP8_19_18,
+		GP_2_10_FN, FN_IP8_17_16,
+		GP_2_9_FN, FN_IP8_15_14,
+		GP_2_8_FN, FN_IP8_13_12,
+		GP_2_7_FN, FN_IP8_11_10,
+		GP_2_6_FN, FN_IP8_9_8,
+		GP_2_5_FN, FN_IP8_7_6,
+		GP_2_4_FN, FN_IP8_5_4,
+		GP_2_3_FN, FN_IP8_3_2,
+		GP_2_2_FN, FN_IP8_1_0,
+		GP_2_1_FN, FN_IP7_30_29,
+		GP_2_0_FN, FN_IP7_28_27 }
+	},
+	{ PINMUX_CFG_REG("GPSR3", 0xE6060010, 32, 1) {
+		GP_3_31_FN, FN_IP11_21_18,
+		GP_3_30_FN, FN_IP11_17_15,
+		GP_3_29_FN, FN_IP11_14_13,
+		GP_3_28_FN, FN_IP11_12_11,
+		GP_3_27_FN, FN_IP11_10_9,
+		GP_3_26_FN, FN_IP11_8_7,
+		GP_3_25_FN, FN_IP11_6_5,
+		GP_3_24_FN, FN_IP11_4,
+		GP_3_23_FN, FN_IP11_3_0,
+		GP_3_22_FN, FN_IP10_29_26,
+		GP_3_21_FN, FN_IP10_25_23,
+		GP_3_20_FN, FN_IP10_22_19,
+		GP_3_19_FN, FN_IP10_18_15,
+		GP_3_18_FN, FN_IP10_14_11,
+		GP_3_17_FN, FN_IP10_10_7,
+		GP_3_16_FN, FN_IP10_6_4,
+		GP_3_15_FN, FN_IP10_3_0,
+		GP_3_14_FN, FN_IP9_31_28,
+		GP_3_13_FN, FN_IP9_27_26,
+		GP_3_12_FN, FN_IP9_25_24,
+		GP_3_11_FN, FN_IP9_23_22,
+		GP_3_10_FN, FN_IP9_21_20,
+		GP_3_9_FN, FN_IP9_19_18,
+		GP_3_8_FN, FN_IP9_17_16,
+		GP_3_7_FN, FN_IP9_15_12,
+		GP_3_6_FN, FN_IP9_11_8,
+		GP_3_5_FN, FN_IP9_7_6,
+		GP_3_4_FN, FN_IP9_5_4,
+		GP_3_3_FN, FN_IP9_3_2,
+		GP_3_2_FN, FN_IP9_1_0,
+		GP_3_1_FN, FN_IP8_30_29,
+		GP_3_0_FN, FN_IP8_28 }
+	},
+	{ PINMUX_CFG_REG("GPSR4", 0xE6060014, 32, 1) {
+		GP_4_31_FN, FN_IP14_18_16,
+		GP_4_30_FN, FN_IP14_15_12,
+		GP_4_29_FN, FN_IP14_11_9,
+		GP_4_28_FN, FN_IP14_8_6,
+		GP_4_27_FN, FN_IP14_5_3,
+		GP_4_26_FN, FN_IP14_2_0,
+		GP_4_25_FN, FN_IP13_30_29,
+		GP_4_24_FN, FN_IP13_28_26,
+		GP_4_23_FN, FN_IP13_25_23,
+		GP_4_22_FN, FN_IP13_22_19,
+		GP_4_21_FN, FN_IP13_18_16,
+		GP_4_20_FN, FN_IP13_15_13,
+		GP_4_19_FN, FN_IP13_12_10,
+		GP_4_18_FN, FN_IP13_9_7,
+		GP_4_17_FN, FN_IP13_6_3,
+		GP_4_16_FN, FN_IP13_2_0,
+		GP_4_15_FN, FN_IP12_30_28,
+		GP_4_14_FN, FN_IP12_27_25,
+		GP_4_13_FN, FN_IP12_24_23,
+		GP_4_12_FN, FN_IP12_22_20,
+		GP_4_11_FN, FN_IP12_19_17,
+		GP_4_10_FN, FN_IP12_16_14,
+		GP_4_9_FN, FN_IP12_13_11,
+		GP_4_8_FN, FN_IP12_10_8,
+		GP_4_7_FN, FN_IP12_7_6,
+		GP_4_6_FN, FN_IP12_5_4,
+		GP_4_5_FN, FN_IP12_3_2,
+		GP_4_4_FN, FN_IP12_1_0,
+		GP_4_3_FN, FN_IP11_31_30,
+		GP_4_2_FN, FN_IP11_29_27,
+		GP_4_1_FN, FN_IP11_26_24,
+		GP_4_0_FN, FN_IP11_23_22 }
+	},
+	{ PINMUX_CFG_REG("GPSR5", 0xE6060018, 32, 1) {
+		GP_5_31_FN, FN_IP7_24_22,
+		GP_5_30_FN, FN_IP7_21_19,
+		GP_5_29_FN, FN_IP7_18_16,
+		GP_5_28_FN, FN_DU_DOTCLKIN2,
+		GP_5_27_FN, FN_IP7_26_25,
+		GP_5_26_FN, FN_DU_DOTCLKIN0,
+		GP_5_25_FN, FN_AVS2,
+		GP_5_24_FN, FN_AVS1,
+		GP_5_23_FN, FN_USB2_OVC,
+		GP_5_22_FN, FN_USB2_PWEN,
+		GP_5_21_FN, FN_IP16_7,
+		GP_5_20_FN, FN_IP16_6,
+		GP_5_19_FN, FN_USB0_OVC_VBUS,
+		GP_5_18_FN, FN_USB0_PWEN,
+		GP_5_17_FN, FN_IP16_5_3,
+		GP_5_16_FN, FN_IP16_2_0,
+		GP_5_15_FN, FN_IP15_29_28,
+		GP_5_14_FN, FN_IP15_27_26,
+		GP_5_13_FN, FN_IP15_25_23,
+		GP_5_12_FN, FN_IP15_22_20,
+		GP_5_11_FN, FN_IP15_19_18,
+		GP_5_10_FN, FN_IP15_17_16,
+		GP_5_9_FN, FN_IP15_15_14,
+		GP_5_8_FN, FN_IP15_13_12,
+		GP_5_7_FN, FN_IP15_11_9,
+		GP_5_6_FN, FN_IP15_8_6,
+		GP_5_5_FN, FN_IP15_5_3,
+		GP_5_4_FN, FN_IP15_2_0,
+		GP_5_3_FN, FN_IP14_30_28,
+		GP_5_2_FN, FN_IP14_27_25,
+		GP_5_1_FN, FN_IP14_24_22,
+		GP_5_0_FN, FN_IP14_21_19 }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR0", 0xE6060020, 32,
+			     1, 4, 4, 3, 4, 4, 3, 3, 3, 3) {
+		/* IP0_31 [1] */
+		0, 0,
+		/* IP0_30_27 [4] */
+		FN_D8, FN_SCIFA1_SCK_C, FN_AVB_TXD0, FN_MII_TXD0,
+		FN_VI0_G0, FN_VI0_G0_B, FN_VI2_DATA0_VI2_B0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP0_26_23 [4] */
+		FN_D7, FN_AD_DI_B, FN_SDA2_C,
+		FN_VI3_DATA7, FN_VI0_R3, FN_VI0_R3_B, FN_SDA2_CIS_C,
+		0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP0_22_20 [3] */
+		FN_D6, FN_SCL2_C, FN_VI3_DATA6, FN_VI0_R2, FN_VI0_R2_B,
+		FN_SCL2_CIS_C, 0, 0,
+		/* IP0_19_16 [4] */
+		FN_D5, FN_SCIFB1_TXD_F, FN_SCIFB0_TXD_C, FN_VI3_DATA5,
+		FN_VI0_R1, FN_VI0_R1_B, FN_TX0_B,
+		0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP0_15_12 [4] */
+		FN_D4, FN_SCIFB1_RXD_F, FN_SCIFB0_RXD_C, FN_VI3_DATA4,
+		FN_VI0_R0, FN_VI0_R0_B, FN_RX0_B,
+		0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP0_11_9 [3] */
+		FN_D3, FN_MSIOF3_TXD_B,	FN_VI3_DATA3, FN_VI0_G7, FN_VI0_G7_B,
+		0, 0, 0,
+		/* IP0_8_6 [3] */
+		FN_D2, FN_MSIOF3_RXD_B, FN_VI3_DATA2, FN_VI0_G6, FN_VI0_G6_B,
+		0, 0, 0,
+		/* IP0_5_3 [3] */
+		FN_D1, FN_MSIOF3_SYNC_B, FN_VI3_DATA1, FN_VI0_G5, FN_VI0_G5_B,
+		0, 0, 0,
+		/* IP0_2_0 [3] */
+		FN_D0, FN_MSIOF3_SCK_B, FN_VI3_DATA0, FN_VI0_G4, FN_VI0_G4_B,
+		0, 0, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR1", 0xE6060024, 32,
+			     2, 2, 2, 4, 4, 3, 3, 4, 4, 4) {
+		/* IP1_31_30 [2] */
+		0, 0, 0, 0,
+		/* IP1_29_28 [2] */
+		FN_A1, FN_PWM4, 0, 0,
+		/* IP1_27_26 [2] */
+		FN_A0, FN_PWM3, 0, 0,
+		/* IP1_25_22 [4] */
+		FN_D15, FN_SCIFB1_TXD_C, FN_AVB_TXD7, FN_TX1_B,
+		FN_VI0_FIELD, FN_VI0_FIELD_B, FN_VI2_DATA7_VI2_B7,
+		0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP1_21_18 [4] */
+		FN_D14,	FN_SCIFB1_RXD_C, FN_AVB_TXD6, FN_RX1_B,
+		FN_VI0_CLKENB, FN_VI0_CLKENB_B, FN_VI2_DATA6_VI2_B6,
+		0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP1_17_15 [3] */
+		FN_D13, FN_AVB_TXD5, FN_VI0_VSYNC_N,
+		FN_VI0_VSYNC_N_B, FN_VI2_DATA5_VI2_B5,
+		0, 0, 0,
+		/* IP1_14_12 [3] */
+		FN_D12, FN_SCIFA1_RTS_N_C, FN_AVB_TXD4,
+		FN_VI0_HSYNC_N, FN_VI0_HSYNC_N_B, FN_VI2_DATA4_VI2_B4,
+		0, 0,
+		/* IP1_11_8 [4] */
+		FN_D11, FN_SCIFA1_CTS_N_C, FN_AVB_TXD3, FN_MII_TXD3,
+		FN_VI0_G3, FN_VI0_G3_B, FN_VI2_DATA3_VI2_B3,
+		0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP1_7_4 [4] */
+		FN_D10, FN_SCIFA1_TXD_C, FN_AVB_TXD2, FN_MII_TXD2,
+		FN_VI0_G2, FN_VI0_G2_B, FN_VI2_DATA2_VI2_B2,
+		0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP1_3_0 [4] */
+		FN_D9, FN_SCIFA1_RXD_C, FN_AVB_TXD1, FN_MII_TXD1,
+		FN_VI0_G1, FN_VI0_G1_B, FN_VI2_DATA1_VI2_B1,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR2", 0xE6060028, 32,
+			     3, 3, 4, 4, 3, 3, 3, 3, 3, 3) {
+		/* IP2_31_29 [3] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP2_28_26 [3] */
+		FN_A10, FN_SSI_SDATA5_B, FN_MSIOF2_SYNC, FN_VI0_R6,
+		FN_VI0_R6_B, FN_VI2_DATA2_VI2_B2_B, 0, 0,
+		/* IP2_25_22 [4] */
+		FN_A9, FN_SCIFA1_CTS_N_B, FN_SSI_WS5_B, FN_VI0_R5,
+		FN_VI0_R5_B, FN_SCIFB2_TXD_C, 0, FN_VI2_DATA1_VI2_B1_B,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP2_21_18 [4] */
+		FN_A8, FN_SCIFA1_RXD_B, FN_SSI_SCK5_B, FN_VI0_R4,
+		FN_VI0_R4_B, FN_SCIFB2_RXD_C, 0, FN_VI2_DATA0_VI2_B0_B,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP2_17_15 [3] */
+		FN_A7, FN_SCIFA1_SCK_B, FN_AUDIO_CLKOUT_B, FN_TPU0TO3,
+		0, 0, 0, 0,
+		/* IP2_14_12 [3] */
+		FN_A6, FN_SCIFA1_RTS_N_B, FN_TPU0TO2, 0, 0, 0, 0, 0,
+		/* IP2_11_9 [3] */
+		FN_A5, FN_SCIFA1_TXD_B, FN_TPU0TO1, 0, 0, 0, 0, 0,
+		/* IP2_8_6 [3] */
+		FN_A4, FN_MSIOF1_TXD_B,	FN_TPU0TO0, 0, 0, 0, 0, 0,
+		/* IP2_5_3 [3] */
+		FN_A3, FN_PWM6, FN_MSIOF1_SS2_B, 0, 0, 0, 0, 0,
+		/* IP2_2_0 [3] */
+		FN_A2, FN_PWM5, FN_MSIOF1_SS1_B, 0, 0, 0, 0, 0,	}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR3", 0xE606002C, 32,
+			     3, 3, 3, 3, 2, 3, 3, 4, 4, 4) {
+		/* IP3_31_29 [3] */
+		FN_A20, FN_SPCLK, FN_VI1_R3, FN_VI1_R3_B, FN_VI2_G4,
+		0, 0, 0,
+		/* IP3_28_26 [3] */
+		FN_A19, FN_AD_NCS_N_B, FN_ATACS01_N, FN_EX_WAIT0_B,
+		0, 0, 0, 0,
+		/* IP3_25_23 [3] */
+		FN_A18, FN_AD_CLK_B, FN_ATAG1_N, 0, 0, 0, 0, 0,
+		/* IP3_22_20 [3] */
+		FN_A17, FN_AD_DO_B, FN_ATADIR1_N, 0, 0, 0, 0, 0,
+		/* IP3_19_18 [2] */
+		FN_A16, FN_ATAWR1_N, 0, 0,
+		/* IP3_17_15 [3] */
+		FN_A15, FN_SCIFB2_SCK_B, FN_ATARD1_N, FN_MSIOF2_SS2,
+		0, 0, 0, 0,
+		/* IP3_14_12 [3] */
+		FN_A14, FN_SCIFB2_TXD_B, FN_ATACS11_N, FN_MSIOF2_SS1,
+		0, 0, 0, 0,
+		/* IP3_11_8 [4] */
+		FN_A13, FN_SCIFB2_RTS_N_B, FN_EX_WAIT2,
+		FN_MSIOF2_RXD, FN_VI1_R2, FN_VI1_R2_B, FN_VI2_G2,
+		FN_VI2_DATA5_VI2_B5_B, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP3_7_4 [4] */
+		FN_A12, FN_SCIFB2_RXD_B, FN_MSIOF2_TXD, FN_VI1_R1,
+		FN_VI1_R1_B, FN_VI2_G1, FN_VI2_DATA4_VI2_B4_B,
+		0, 0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP3_3_0 [4] */
+		FN_A11, FN_SCIFB2_CTS_N_B, FN_MSIOF2_SCK, FN_VI1_R0,
+		FN_VI1_R0_B, FN_VI2_G0, FN_VI2_DATA3_VI2_B3_B, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR4", 0xE6060030, 32,
+			     2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3) {
+		/* IP4_31_30 [2] */
+		0, 0, 0, 0,
+		/* IP4_29_27 [3] */
+		FN_EX_CS2_N, FN_GPS_SIGN, FN_HRTS1_N_B,
+		FN_VI3_CLKENB, FN_VI1_G0, FN_VI1_G0_B, FN_VI2_R2, 0,
+		/* IP4_26_24 [3] */
+		FN_EX_CS1_N, FN_GPS_CLK, FN_HCTS1_N_B, FN_VI1_FIELD,
+		FN_VI1_FIELD_B, FN_VI2_R1, 0, 0,
+		/* IP4_23_21 [3] */
+		FN_EX_CS0_N, FN_HRX1_B, FN_VI1_G5, FN_VI1_G5_B, FN_VI2_R0,
+		FN_HTX0_B, FN_MSIOF0_SS1_B, 0,
+		/* IP4_20_18 [3] */
+		FN_CS1_N_A26, FN_SPEEDIN, FN_VI0_R7, FN_VI0_R7_B,
+		FN_VI2_CLK, FN_VI2_CLK_B, 0, 0,
+		/* IP4_17_15 [3] */
+		FN_CS0_N, FN_VI1_R6, FN_VI1_R6_B, FN_VI2_G3, FN_MSIOF0_SS2_B,
+		0, 0, 0,
+		/* IP4_14_12 [3] */
+		FN_A25, FN_SSL, FN_VI1_G6, FN_VI1_G6_B, FN_VI2_FIELD,
+		FN_VI2_FIELD_B, 0, 0,
+		/* IP4_11_9 [3] */
+		FN_A24, FN_IO3, FN_VI1_R7, FN_VI1_R7_B, FN_VI2_CLKENB,
+		FN_VI2_CLKENB_B, 0, 0,
+		/* IP4_8_6 [3] */
+		FN_A23, FN_IO2, FN_VI1_G7, FN_VI1_G7_B, FN_VI2_G7, 0, 0, 0,
+		/* IP4_5_3 [3] */
+		FN_A22, FN_MISO_IO1, FN_VI1_R5, FN_VI1_R5_B, FN_VI2_G6, 0, 0, 0,
+		/* IP4_2_0 [3] */
+		FN_A21, FN_MOSI_IO0, FN_VI1_R4, FN_VI1_R4_B, FN_VI2_G5, 0, 0, 0,
+		}
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR5", 0xE6060034, 32,
+			     2, 3, 3, 3, 3, 3, 2, 3, 4, 3, 3) {
+		/* IP5_31_30 [2] */
+		0, 0, 0, 0,
+		/* IP5_29_27 [3] */
+		FN_DREQ0_N, FN_VI1_HSYNC_N, FN_VI1_HSYNC_N_B, FN_VI2_R7,
+		FN_SSI_SCK78_C, FN_SSI_WS78_B, 0, 0,
+		/* IP5_26_24 [3] */
+		FN_EX_WAIT0, FN_IRQ3, FN_INTC_IRQ3_N,
+		FN_VI3_CLK, FN_SCIFA0_RTS_N_B, FN_HRX0_B,
+		FN_MSIOF0_SCK_B, 0,
+		/* IP5_23_21 [3] */
+		FN_WE1_N, FN_IERX, FN_CAN1_RX, FN_VI1_G4,
+		FN_VI1_G4_B, FN_VI2_R6, FN_SCIFA0_CTS_N_B,
+		FN_IERX_C, 0,
+		/* IP5_20_18 [3] */
+		FN_WE0_N, FN_IECLK, FN_CAN_CLK,
+		FN_VI2_VSYNC_N, FN_SCIFA0_TXD_B, FN_VI2_VSYNC_N_B, 0, 0,
+		/* IP5_17_15 [3] */
+		FN_RD_WR_N, FN_VI1_G3, FN_VI1_G3_B, FN_VI2_R5, FN_SCIFA0_RXD_B,
+		FN_INTC_IRQ4_N, 0, 0,
+		/* IP5_14_13 [2] */
+		FN_RD_N, FN_CAN0_TX, FN_SCIFA0_SCK_B, 0,
+		/* IP5_12_10 [3] */
+		FN_BS_N, FN_IETX, FN_HTX1_B, FN_CAN1_TX, FN_DRACK0, FN_IETX_C,
+		0, 0,
+		/* IP5_9_6 [4] */
+		FN_EX_CS5_N, FN_CAN0_RX, FN_MSIOF1_RXD_B, FN_VI3_VSYNC_N,
+		FN_VI1_G2, FN_VI1_G2_B, FN_VI2_R4, FN_SDA1, FN_INTC_EN1_N,
+		FN_SDA1_CIS, 0, 0, 0, 0, 0, 0,
+		/* IP5_5_3 [3] */
+		FN_EX_CS4_N, FN_MSIOF1_SCK_B, FN_VI3_HSYNC_N,
+		FN_VI2_HSYNC_N, FN_SCL1, FN_VI2_HSYNC_N_B,
+		FN_INTC_EN0_N, FN_SCL1_CIS,
+		/* IP5_2_0 [3] */
+		FN_EX_CS3_N, FN_GPS_MAG, FN_VI3_FIELD, FN_VI1_G1, FN_VI1_G1_B,
+		FN_VI2_R3, 0, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR6", 0xE6060038, 32,
+			     3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3) {
+		/* IP6_31_29 [3] */
+		FN_ETH_REF_CLK, FN_RMII_REF_CLK, FN_HCTS0_N_E,
+		FN_STP_IVCXO27_1_B, FN_HRX0_F, 0, 0, 0,
+		/* IP6_28_26 [3] */
+		FN_ETH_LINK, FN_RMII_LINK, FN_HTX0_E,
+		FN_STP_IVCXO27_0_B, FN_SCIFB1_TXD_G, FN_TX1_E, 0, 0,
+		/* IP6_25_23 [3] */
+		FN_ETH_RXD1, FN_RMII_RXD1, FN_HRX0_E, FN_STP_ISSYNC_0_B,
+		FN_TS_SCK0_D, FN_GLO_I1_C, FN_SCIFB1_RXD_G, FN_RX1_E,
+		/* IP6_22_20 [3] */
+		FN_ETH_RXD0, FN_RMII_RXD0, FN_STP_ISEN_0_B, FN_TS_SDAT0_D,
+		FN_GLO_I0_C, FN_SCIFB1_SCK_G, FN_SCK1_E, 0,
+		/* IP6_19_17 [3] */
+		FN_ETH_RX_ER, FN_RMII_RX_ER, FN_STP_ISD_0_B,
+		FN_TS_SPSYNC0_D, FN_GLO_Q1_C, FN_SDA2_E, FN_SDA2_CIS_E, 0,
+		/* IP6_16_14 [3] */
+		FN_ETH_CRS_DV, FN_RMII_CRS_DV, FN_STP_ISCLK_0_B,
+		FN_TS_SDEN0_D, FN_GLO_Q0_C, FN_SCL2_E,
+		FN_SCL2_CIS_E, 0,
+		/* IP6_13_11 [3] */
+		FN_DACK2, FN_IRQ2, FN_INTC_IRQ2_N,
+		FN_SSI_SDATA6_B, FN_HRTS0_N_B, FN_MSIOF0_RXD_B, 0, 0,
+		/* IP6_10_9 [2] */
+		FN_DREQ2_N, FN_HSCK1_B, FN_HCTS0_N_B, FN_MSIOF0_TXD_B,
+		/* IP6_8_6 [3] */
+		FN_DACK1, FN_IRQ1, FN_INTC_IRQ1_N, FN_SSI_WS6_B,
+		FN_SSI_SDATA8_C, 0, 0, 0,
+		/* IP6_5_3 [3] */
+		FN_DREQ1_N, FN_VI1_CLKENB, FN_VI1_CLKENB_B,
+		FN_SSI_SDATA7_C, FN_SSI_SCK78_B, 0, 0, 0,
+		/* IP6_2_0 [3] */
+		FN_DACK0, FN_IRQ0, FN_INTC_IRQ0_N, FN_SSI_SCK6_B,
+		FN_VI1_VSYNC_N, FN_VI1_VSYNC_N_B, FN_SSI_WS78_C, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR7", 0xE606003C, 32,
+			     1, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 3, 3) {
+		/* IP7_31 [1] */
+		0, 0,
+		/* IP7_30_29 [2] */
+		FN_VI0_DATA0_VI0_B0, FN_ATACS10_N, FN_AVB_RXD2,
+		FN_MII_RXD2,
+		/* IP7_28_27 [2] */
+		FN_VI0_CLK, FN_ATACS00_N, FN_AVB_RXD1, FN_MII_RXD1,
+		/* IP7_26_25 [2] */
+		FN_DU1_DOTCLKIN, FN_AUDIO_CLKC, FN_AUDIO_CLKOUT_C, 0,
+		/* IP7_24_22 [3] */
+		FN_PWM2, FN_PWMFSW0, FN_SCIFA2_RXD_C, FN_PCMWE_N, FN_IECLK_C,
+		0, 0, 0,
+		/* IP7_21_19 [3] */
+		FN_PWM1, FN_SCIFA2_TXD_C, FN_STP_ISSYNC_1_B, FN_TS_SCK1_C,
+		FN_GLO_RFON_C, FN_PCMOE_N, 0, 0,
+		/* IP7_18_16 [3] */
+		FN_PWM0, FN_SCIFA2_SCK_C, FN_STP_ISEN_1_B, FN_TS_SDAT1_C,
+		FN_GLO_SS_C, 0, 0, 0,
+		/* IP7_15_13 [3] */
+		FN_ETH_MDC, FN_RMII_MDC, FN_STP_ISD_1_B,
+		FN_TS_SPSYNC1_C, FN_GLO_SDATA_C, 0, 0, 0,
+		/* IP7_12_10 [3] */
+		FN_ETH_TXD0, FN_RMII_TXD0, FN_STP_ISCLK_1_B, FN_TS_SDEN1_C,
+		FN_GLO_SCLK_C, 0, 0, 0,
+		/* IP7_9_8 [2] */
+		FN_ETH_MAGIC, FN_RMII_MAGIC, FN_SIM0_RST_C, 0,
+		/* IP7_7_6 [2] */
+		FN_ETH_TX_EN, FN_RMII_TX_EN, FN_SIM0_CLK_C, FN_HRTS0_N_F,
+		/* IP7_5_3 [3] */
+		FN_ETH_TXD1, FN_RMII_TXD1, FN_HTX0_F, FN_BPFCLK_G, FN_RDS_CLK_F,
+		0, 0, 0,
+		/* IP7_2_0 [3] */
+		FN_ETH_MDIO, FN_RMII_MDIO, FN_HRTS0_N_E,
+		FN_SIM0_D_C, FN_HCTS0_N_F, 0, 0, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR8", 0xE6060040, 32,
+			     1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+			     2, 2, 2, 2, 2, 2, 2) {
+		/* IP8_31 [1] */
+		0, 0,
+		/* IP8_30_29 [2] */
+		FN_SD0_CMD, FN_SCIFB1_SCK_B, FN_VI1_DATA1_VI1_B1_B, 0,
+		/* IP8_28 [1] */
+		FN_SD0_CLK, FN_VI1_DATA0_VI1_B0_B,
+		/* IP8_27 [1] */
+		FN_VI1_DATA6_VI1_B6, FN_AVB_GTXREFCLK,
+		/* IP8_26 [1] */
+		FN_VI1_DATA5_VI1_B5, FN_AVB_PHY_INT,
+		/* IP8_25_24 [2] */
+		FN_VI1_DATA4_VI1_B4, FN_SCIFA1_RTS_N_D,
+		FN_AVB_MAGIC, FN_MII_MAGIC,
+		/* IP8_23_22 [2] */
+		FN_VI1_DATA3_VI1_B3, FN_SCIFA1_CTS_N_D, FN_AVB_GTX_CLK, 0,
+		/* IP8_21_20 [2] */
+		FN_VI1_DATA2_VI1_B2, FN_SCIFA1_TXD_D, FN_AVB_MDIO,
+		FN_MII_MDIO,
+		/* IP8_19_18 [2] */
+		FN_VI1_DATA1_VI1_B1, FN_SCIFA1_RXD_D, FN_AVB_MDC, FN_MII_MDC,
+		/* IP8_17_16 [2] */
+		FN_VI1_DATA0_VI1_B0, FN_SCIFA1_SCK_D, FN_AVB_CRS, FN_MII_CRS,
+		/* IP8_15_14 [2] */
+		FN_VI1_CLK, FN_AVB_RX_DV, FN_MII_RX_DV, 0,
+		/* IP8_13_12 [2] */
+		FN_VI0_DATA7_VI0_B7, FN_AVB_RX_CLK, FN_MII_RX_CLK, 0,
+		/* IP8_11_10 [2] */
+		FN_VI0_DATA6_VI0_B6, FN_AVB_RX_ER, FN_MII_RX_ER, 0,
+		/* IP8_9_8 [2] */
+		FN_VI0_DATA5_VI0_B5, FN_EX_WAIT1, FN_AVB_RXD7, 0,
+		/* IP8_7_6 [2] */
+		FN_VI0_DATA4_VI0_B4, FN_ATAG0_N, FN_AVB_RXD6, 0,
+		/* IP8_5_4 [2] */
+		FN_VI0_DATA3_VI0_B3, FN_ATADIR0_N, FN_AVB_RXD5, 0,
+		/* IP8_3_2 [2] */
+		FN_VI0_DATA2_VI0_B2, FN_ATAWR0_N, FN_AVB_RXD4, 0,
+		/* IP8_1_0 [2] */
+		FN_VI0_DATA1_VI0_B1, FN_ATARD0_N, FN_AVB_RXD3, FN_MII_RXD3, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR9", 0xE6060044, 32,
+			     4, 2, 2, 2, 2, 2, 2, 4, 4, 2, 2, 2, 2) {
+		/* IP9_31_28 [4] */
+		FN_SD1_CD, FN_MMC1_D6, FN_TS_SDEN1, FN_USB1_EXTP,
+		FN_GLO_SS, FN_VI0_CLK_B, FN_SCL2_D, FN_SCL2_CIS_D,
+		FN_SIM0_CLK_B, FN_VI3_CLK_B, 0, 0, 0, 0, 0, 0,
+		/* IP9_27_26 [2] */
+		FN_SD1_DAT3, FN_AVB_RXD0, FN_MII_RXD0, FN_SCIFB0_RTS_N_B,
+		/* IP9_25_24 [2] */
+		FN_SD1_DAT2, FN_AVB_COL, FN_MII_COL, FN_SCIFB0_CTS_N_B,
+		/* IP9_23_22 [2] */
+		FN_SD1_DAT1, FN_AVB_LINK, FN_MII_LINK, FN_SCIFB0_TXD_B,
+		/* IP9_21_20 [2] */
+		FN_SD1_DAT0, FN_AVB_TX_CLK, FN_MII_TX_CLK, FN_SCIFB0_RXD_B,
+		/* IP9_19_18 [2] */
+		FN_SD1_CMD, FN_AVB_TX_ER, FN_MII_TX_ER, FN_SCIFB0_SCK_B,
+		/* IP9_17_16 [2] */
+		FN_SD1_CLK, FN_AVB_TX_EN, FN_MII_TX_EN, 0,
+		/* IP9_15_12 [4] */
+		FN_SD0_WP, FN_MMC0_D7, FN_TS_SPSYNC0_B, FN_USB0_IDIN,
+		FN_GLO_SDATA, FN_VI1_DATA7_VI1_B7_B, FN_SDA1_B,
+		FN_SDA1_CIS_B, FN_VI2_DATA7_VI2_B7_B, 0, 0, 0, 0, 0, 0, 0,
+		/* IP9_11_8 [4] */
+		FN_SD0_CD, FN_MMC0_D6, FN_TS_SDEN0_B, FN_USB0_EXTP,
+		FN_GLO_SCLK, FN_VI1_DATA6_VI1_B6_B, FN_SCL1_B,
+		FN_SCL1_CIS_B, FN_VI2_DATA6_VI2_B6_B, 0, 0, 0, 0, 0, 0, 0,
+		/* IP9_7_6 [2] */
+		FN_SD0_DAT3, FN_SCIFB1_RTS_N_B, FN_VI1_DATA5_VI1_B5_B, 0,
+		/* IP9_5_4 [2] */
+		FN_SD0_DAT2, FN_SCIFB1_CTS_N_B, FN_VI1_DATA4_VI1_B4_B, 0,
+		/* IP9_3_2 [2] */
+		FN_SD0_DAT1, FN_SCIFB1_TXD_B, FN_VI1_DATA3_VI1_B3_B, 0,
+		/* IP9_1_0 [2] */
+		FN_SD0_DAT0, FN_SCIFB1_RXD_B, FN_VI1_DATA2_VI1_B2_B, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR10", 0xE6060048, 32,
+			     2, 4, 3, 4, 4, 4, 4, 3, 4) {
+		/* IP10_31_30 [2] */
+		0, 0, 0, 0,
+		/* IP10_29_26 [4] */
+		FN_SD2_CD, FN_MMC0_D4, FN_TS_SDAT0_B, FN_USB2_EXTP, FN_GLO_I0,
+		FN_VI0_DATA6_VI0_B6_B, FN_HCTS0_N_D, FN_TS_SDAT1_B,
+		FN_GLO_I0_B, FN_VI3_DATA6_B, 0, 0, 0, 0, 0, 0,
+		/* IP10_25_23 [3] */
+		FN_SD2_DAT3, FN_MMC0_D3, FN_SIM0_RST, FN_VI0_DATA5_VI0_B5_B,
+		FN_HTX0_D, FN_TS_SPSYNC1_B, FN_GLO_Q1_B, FN_VI3_DATA5_B,
+		/* IP10_22_19 [4] */
+		FN_SD2_DAT2, FN_MMC0_D2, FN_BPFCLK_B, FN_RDS_CLK,
+		FN_VI0_DATA4_VI0_B4_B, FN_HRX0_D, FN_TS_SDEN1_B,
+		FN_GLO_Q0_B, FN_VI3_DATA4_B, 0, 0, 0, 0, 0, 0, 0,
+		/* IP10_18_15 [4] */
+		FN_SD2_DAT1, FN_MMC0_D1, FN_FMIN_B, FN_RDS_DATA,
+		FN_VI0_DATA3_VI0_B3_B, FN_SCIFB1_TXD_E, FN_TX1_D,
+		FN_TS_SCK0_C, FN_GLO_RFON_B, FN_VI3_DATA3_B,
+		0, 0, 0, 0, 0, 0,
+		/* IP10_14_11 [4] */
+		FN_SD2_DAT0, FN_MMC0_D0, FN_FMCLK_B,
+		FN_VI0_DATA2_VI0_B2_B, FN_SCIFB1_RXD_E, FN_RX1_D,
+		FN_TS_SDAT0_C, FN_GLO_SS_B, FN_VI3_DATA2_B,
+		0, 0, 0, 0, 0, 0, 0,
+		/* IP10_10_7 [4] */
+		FN_SD2_CMD, FN_MMC0_CMD, FN_SIM0_D,
+		FN_VI0_DATA1_VI0_B1_B, FN_SCIFB1_SCK_E, FN_SCK1_D,
+		FN_TS_SPSYNC0_C, FN_GLO_SDATA_B, FN_VI3_DATA1_B,
+		0, 0, 0, 0, 0, 0, 0,
+		/* IP10_6_4 [3] */
+		FN_SD2_CLK, FN_MMC0_CLK, FN_SIM0_CLK,
+		FN_VI0_DATA0_VI0_B0_B, FN_TS_SDEN0_C, FN_GLO_SCLK_B,
+		FN_VI3_DATA0_B, 0,
+		/* IP10_3_0 [4] */
+		FN_SD1_WP, FN_MMC1_D7, FN_TS_SPSYNC1, FN_USB1_IDIN,
+		FN_GLO_RFON, FN_VI1_CLK_B, FN_SDA2_D, FN_SDA2_CIS_D,
+		FN_SIM0_D_B, 0, 0, 0, 0, 0, 0, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR11", 0xE606004C, 32,
+			     2, 3, 3, 2, 4, 3, 2, 2, 2, 2, 2, 1, 4) {
+		/* IP11_31_30 [2] */
+		FN_SSI_SCK0129, FN_CAN_CLK_B, FN_MOUT0, 0,
+		/* IP11_29_27 [3] */
+		FN_MLB_DAT, FN_SPV_EVEN, FN_SCIFB1_TXD_D, FN_TX1_C, FN_BPFCLK_C,
+		FN_RDS_CLK_B, 0, 0,
+		/* IP11_26_24 [3] */
+		FN_MLB_SIG, FN_SCIFB1_RXD_D, FN_RX1_C, FN_SDA2_B, FN_SDA2_CIS_B,
+		0, 0, 0,
+		/* IP11_23_22 [2] */
+		FN_MLB_CLK, FN_SCL2_B, FN_SCL2_CIS_B, 0,
+		/* IP11_21_18 [4] */
+		FN_SD3_WP, FN_MMC1_D5, FN_TS_SCK1, FN_GLO_Q1, FN_FMIN_C,
+		FN_RDS_DATA_B, FN_FMIN_E, FN_RDS_DATA_D, FN_FMIN_F,
+		FN_RDS_DATA_E, 0, 0, 0, 0, 0, 0,
+		/* IP11_17_15 [3] */
+		FN_SD3_CD, FN_MMC1_D4, FN_TS_SDAT1,
+		FN_VSP, FN_GLO_Q0, FN_SIM0_RST_B, 0, 0,
+		/* IP11_14_13 [2] */
+		FN_SD3_DAT3, FN_MMC1_D3, FN_SCKZ, 0,
+		/* IP11_12_11 [2] */
+		FN_SD3_DAT2, FN_MMC1_D2, FN_SDATA, 0,
+		/* IP11_10_9 [2] */
+		FN_SD3_DAT1, FN_MMC1_D1, FN_MDATA, 0,
+		/* IP11_8_7 [2] */
+		FN_SD3_DAT0, FN_MMC1_D0, FN_STM_N, 0,
+		/* IP11_6_5 [2] */
+		FN_SD3_CMD, FN_MMC1_CMD, FN_MTS_N, 0,
+		/* IP11_4 [1] */
+		FN_SD3_CLK, FN_MMC1_CLK,
+		/* IP11_3_0 [4] */
+		FN_SD2_WP, FN_MMC0_D5, FN_TS_SCK0_B, FN_USB2_IDIN,
+		FN_GLO_I1, FN_VI0_DATA7_VI0_B7_B, FN_HRTS0_N_D,
+		FN_TS_SCK1_B, FN_GLO_I1_B, FN_VI3_DATA7_B, 0, 0, 0, 0, 0, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR12", 0xE6060050, 32,
+			     1, 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2) {
+		/* IP12_31 [1] */
+		0, 0,
+		/* IP12_30_28 [3] */
+		FN_SSI_WS5, FN_SCIFB1_RXD, FN_IECLK_B,
+		FN_DU2_EXVSYNC_DU2_VSYNC, FN_QSTB_QHE,
+		FN_CAN_DEBUGOUT4, 0, 0,
+		/* IP12_27_25 [3] */
+		FN_SSI_SCK5, FN_SCIFB1_SCK,
+		FN_IERX_B, FN_DU2_EXHSYNC_DU2_HSYNC, FN_QSTH_QHS,
+		FN_CAN_DEBUGOUT3, 0, 0,
+		/* IP12_24_23 [2] */
+		FN_SSI_SDATA4, FN_STP_ISSYNC_0, FN_MSIOF1_RXD,
+		FN_CAN_DEBUGOUT2,
+		/* IP12_22_20 [3] */
+		FN_SSI_WS4, FN_STP_ISEN_0, FN_SCIFB0_RTS_N,
+		FN_MSIOF1_TXD, FN_SSI_WS5_C, FN_CAN_DEBUGOUT1, 0, 0,
+		/* IP12_19_17 [3] */
+		FN_SSI_SCK4, FN_STP_ISD_0, FN_SCIFB0_CTS_N,
+		FN_MSIOF1_SS2, FN_SSI_SCK5_C, FN_CAN_DEBUGOUT0, 0, 0,
+		/* IP12_16_14 [3] */
+		FN_SSI_SDATA3, FN_STP_ISCLK_0,
+		FN_SCIFB0_TXD, FN_MSIOF1_SS1, FN_CAN_TXCLK, 0, 0, 0,
+		/* IP12_13_11 [3] */
+		FN_SSI_WS34, FN_STP_IVCXO27_0, FN_SCIFB0_RXD, FN_MSIOF1_SYNC,
+		FN_CAN_STEP0, 0, 0, 0,
+		/* IP12_10_8 [3] */
+		FN_SSI_SCK34, FN_STP_OPWM_0, FN_SCIFB0_SCK,
+		FN_MSIOF1_SCK, FN_CAN_DEBUG_HW_TRIGGER, 0, 0, 0,
+		/* IP12_7_6 [2] */
+		FN_SSI_SDATA2, FN_CAN1_RX_B, FN_SSI_SCK1, FN_MOUT6,
+		/* IP12_5_4 [2] */
+		FN_SSI_SDATA1, FN_CAN1_TX_B, FN_MOUT5, 0,
+		/* IP12_3_2 [2] */
+		FN_SSI_SDATA0, FN_CAN0_RX_B, FN_MOUT2, 0,
+		/* IP12_1_0 [2] */
+		FN_SSI_WS0129, FN_CAN0_TX_B, FN_MOUT1, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR13", 0xE6060054, 32,
+			     1, 2, 3, 3, 4, 3, 3, 3, 3, 4, 3) {
+		/* IP13_31 [1] */
+		0, 0,
+		/* IP13_30_29 [2] */
+		FN_AUDIO_CLKA, FN_SCIFB2_RTS_N, FN_CAN_DEBUGOUT14, 0,
+		/* IP13_28_26 [3] */
+		FN_SSI_SDATA9, FN_STP_ISSYNC_1, FN_SCIFB2_CTS_N, FN_SSI_WS1,
+		FN_SSI_SDATA5_C, FN_CAN_DEBUGOUT13, 0, 0,
+		/* IP13_25_23 [3] */
+		FN_SSI_SDATA8, FN_STP_ISEN_1, FN_SCIFB2_TXD, FN_CAN0_TX_C,
+		FN_CAN_DEBUGOUT12, FN_SSI_SDATA8_B, 0, 0,
+		/* IP13_22_19 [4] */
+		FN_SSI_SDATA7, FN_STP_ISD_1, FN_SCIFB2_RXD, FN_SCIFA2_RTS_N,
+		FN_TCLK2, FN_QSTVA_QVS, FN_CAN_DEBUGOUT11, FN_BPFCLK_E,
+		FN_RDS_CLK_D, FN_SSI_SDATA7_B, FN_FMIN_G, FN_RDS_DATA_F,
+		0, 0, 0, 0,
+		/* IP13_18_16 [3] */
+		FN_SSI_WS78, FN_STP_ISCLK_1, FN_SCIFB2_SCK, FN_SCIFA2_CTS_N,
+		FN_DU2_DR7, FN_LCDOUT7, FN_CAN_DEBUGOUT10, 0,
+		/* IP13_15_13 [3] */
+		FN_SSI_SCK78, FN_STP_IVCXO27_1, FN_SCK1, FN_SCIFA1_SCK,
+		FN_DU2_DR6, FN_LCDOUT6, FN_CAN_DEBUGOUT9, 0,
+		/* IP13_12_10 [3] */
+		FN_SSI_SDATA6, FN_FMIN_D, FN_RDS_DATA_C, FN_DU2_DR5, FN_LCDOUT5,
+		FN_CAN_DEBUGOUT8, 0, 0,
+		/* IP13_9_7 [3] */
+		FN_SSI_WS6, FN_SCIFB1_RTS_N, FN_CAN0_TX_D, FN_DU2_DR4,
+		FN_LCDOUT4, FN_CAN_DEBUGOUT7, 0, 0,
+		/* IP13_6_3 [4] */
+		FN_SSI_SCK6, FN_SCIFB1_CTS_N, FN_BPFCLK_D, FN_RDS_CLK_C,
+		FN_DU2_DR3, FN_LCDOUT3, FN_CAN_DEBUGOUT6,
+		FN_BPFCLK_F, FN_RDS_CLK_E, 0, 0, 0, 0, 0, 0, 0,
+		/* IP13_2_0 [3] */
+		FN_SSI_SDATA5, FN_SCIFB1_TXD, FN_IETX_B, FN_DU2_DR2,
+		FN_LCDOUT2, FN_CAN_DEBUGOUT5, 0, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR14", 0xE6060058, 32,
+			     1, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3) {
+		/* IP14_30 [1] */
+		0, 0,
+		/* IP14_30_28 [3] */
+		FN_SCIFA1_RTS_N, FN_AD_NCS_N, FN_RTS1_N_TANS,
+		FN_MSIOF3_TXD, FN_DU1_DOTCLKOUT, FN_QSTVB_QVE,
+		FN_HRTS0_N_C, 0,
+		/* IP14_27_25 [3] */
+		FN_SCIFA1_CTS_N, FN_AD_CLK, FN_CTS1_N, FN_MSIOF3_RXD,
+		FN_DU0_DOTCLKOUT, FN_QCLK, 0, 0,
+		/* IP14_24_22 [3] */
+		FN_SCIFA1_TXD, FN_AD_DO, FN_TX1, FN_DU2_DG1,
+		FN_LCDOUT9, 0, 0, 0,
+		/* IP14_21_19 [3] */
+		FN_SCIFA1_RXD, FN_AD_DI, FN_RX1,
+		FN_DU2_EXODDF_DU2_ODDF_DISP_CDE, FN_QCPV_QDE, 0, 0, 0,
+		/* IP14_18_16 [3] */
+		FN_SCIFA0_RTS_N, FN_HRTS1_N, FN_RTS0_N_TANS,
+		FN_MSIOF3_SS1, FN_DU2_DG0, FN_LCDOUT8, FN_PWM1_B, 0,
+		/* IP14_15_12 [4] */
+		FN_SCIFA0_CTS_N, FN_HCTS1_N, FN_CTS0_N, FN_MSIOF3_SYNC,
+		FN_DU2_DG3, FN_LCDOUT11, FN_PWM0_B, FN_SCL1_C, FN_SCL1_CIS_C,
+		0, 0, 0, 0, 0, 0, 0,
+		/* IP14_11_9 [3] */
+		FN_SCIFA0_TXD, FN_HTX1, FN_TX0, FN_DU2_DR1, FN_LCDOUT1,
+		0, 0, 0,
+		/* IP14_8_6 [3] */
+		FN_SCIFA0_RXD, FN_HRX1, FN_RX0, FN_DU2_DR0, FN_LCDOUT0,
+		0, 0, 0,
+		/* IP14_5_3 [3] */
+		FN_SCIFA0_SCK, FN_HSCK1, FN_SCK0, FN_MSIOF3_SS2, FN_DU2_DG2,
+		FN_LCDOUT10, FN_SDA1_C, FN_SDA1_CIS_C,
+		/* IP14_2_0 [3] */
+		FN_AUDIO_CLKB, FN_SCIF_CLK, FN_CAN0_RX_D,
+		FN_DVC_MUTE, FN_CAN0_RX_C, FN_CAN_DEBUGOUT15,
+		FN_REMOCON, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR15", 0xE606005C, 32,
+			     2, 2, 2, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3) {
+		/* IP15_31_30 [2] */
+		0, 0, 0, 0,
+		/* IP15_29_28 [2] */
+		FN_MSIOF0_TXD, FN_ADICHS1, FN_DU2_DG6, FN_LCDOUT14,
+		/* IP15_27_26 [2] */
+		FN_MSIOF0_SS1, FN_ADICHS0, FN_DU2_DG5, FN_LCDOUT13,
+		/* IP15_25_23 [3] */
+		FN_MSIOF0_SYNC, FN_TS_SCK0, FN_SSI_SCK2, FN_ADIDATA,
+		FN_DU2_DB7, FN_LCDOUT23, FN_SCIFA2_RXD_B, 0,
+		/* IP15_22_20 [3] */
+		FN_MSIOF0_SCK, FN_TS_SDAT0, FN_ADICLK,
+		FN_DU2_DB6, FN_LCDOUT22, 0, 0, 0,
+		/* IP15_19_18 [2] */
+		FN_HRTS0_N, FN_SSI_WS9, FN_DU2_DB5, FN_LCDOUT21,
+		/* IP15_17_16 [2] */
+		FN_HCTS0_N, FN_SSI_SCK9, FN_DU2_DB4, FN_LCDOUT20,
+		/* IP15_15_14 [2] */
+		FN_HTX0, FN_DU2_DB3, FN_LCDOUT19, 0,
+		/* IP15_13_12 [2] */
+		FN_HRX0, FN_DU2_DB2, FN_LCDOUT18, 0,
+		/* IP15_11_9 [3] */
+		FN_HSCK0, FN_TS_SDEN0, FN_DU2_DG4, FN_LCDOUT12, FN_HCTS0_N_C,
+		0, 0, 0,
+		/* IP15_8_6 [3] */
+		FN_SCIFA2_TXD, FN_BPFCLK, 0, FN_DU2_DB1, FN_LCDOUT17,
+		FN_SDA2, FN_SDA2_CIS, 0,
+		/* IP15_5_3 [3] */
+		FN_SCIFA2_RXD, FN_FMIN, 0, FN_DU2_DB0, FN_LCDOUT16,
+		FN_SCL2, FN_SCL2_CIS, 0,
+		/* IP15_2_0 [3] */
+		FN_SCIFA2_SCK, FN_FMCLK, 0, FN_MSIOF3_SCK, FN_DU2_DG7,
+		FN_LCDOUT15, FN_SCIF_CLK_B, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("IPSR16", 0xE6060160, 32,
+			     4, 4, 4, 4, 4, 4, 1, 1, 3, 3) {
+		/* IP16_31_28 [4] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP16_27_24 [4] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP16_23_20 [4] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP16_19_16 [4] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP16_15_12 [4] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP16_11_8 [4] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* IP16_7 [1] */
+		FN_USB1_OVC, FN_TCLK1_B,
+		/* IP16_6 [1] */
+		FN_USB1_PWEN, FN_AUDIO_CLKOUT_D,
+		/* IP16_5_3 [3] */
+		FN_MSIOF0_RXD, FN_TS_SPSYNC0, FN_SSI_WS2,
+		FN_ADICS_SAMP, FN_DU2_CDE, FN_QPOLB, FN_HRX0_C, 0,
+		/* IP16_2_0 [3] */
+		FN_MSIOF0_SS2, FN_AUDIO_CLKOUT, FN_ADICHS2,
+		FN_DU2_DISP, FN_QPOLA, FN_HTX0_C, FN_SCIFA2_TXD_B, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("MOD_SEL", 0xE6060090, 32,
+			     3, 2, 2, 3, 2, 1, 1, 1, 2, 1,
+			     2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1) {
+		/* SEL_SCIF1 [3] */
+		FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3,
+		FN_SEL_SCIF1_4, 0, 0, 0,
+		/* SEL_SCIFB [2] */
+		FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2, 0,
+		/* SEL_SCIFB2 [2] */
+		FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, FN_SEL_SCIFB2_2, 0,
+		/* SEL_SCIFB1 [3] */
+		FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, FN_SEL_SCIFB1_2,
+		FN_SEL_SCIFB1_3, FN_SEL_SCIFB1_4, FN_SEL_SCIFB1_5,
+		FN_SEL_SCIFB1_6, 0,
+		/* SEL_SCIFA1 [2] */
+		FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2,
+		FN_SEL_SCIFA1_3,
+		/* SEL_SCIF0 [1] */
+		FN_SEL_SCIF0_0, FN_SEL_SCIF0_1,
+		/* SEL_SCIFA [1] */
+		FN_SEL_SCFA_0, FN_SEL_SCFA_1,
+		/* SEL_SOF1 [1] */
+		FN_SEL_SOF1_0, FN_SEL_SOF1_1,
+		/* SEL_SSI7 [2] */
+		FN_SEL_SSI7_0, FN_SEL_SSI7_1, FN_SEL_SSI7_2, 0,
+		/* SEL_SSI6 [1] */
+		FN_SEL_SSI6_0, FN_SEL_SSI6_1,
+		/* SEL_SSI5 [2] */
+		FN_SEL_SSI5_0, FN_SEL_SSI5_1, FN_SEL_SSI5_2, 0,
+		/* SEL_VI3 [1] */
+		FN_SEL_VI3_0, FN_SEL_VI3_1,
+		/* SEL_VI2 [1] */
+		FN_SEL_VI2_0, FN_SEL_VI2_1,
+		/* SEL_VI1 [1] */
+		FN_SEL_VI1_0, FN_SEL_VI1_1,
+		/* SEL_VI0 [1] */
+		FN_SEL_VI0_0, FN_SEL_VI0_1,
+		/* SEL_TSIF1 [2] */
+		FN_SEL_TSIF1_0, FN_SEL_TSIF1_1, FN_SEL_TSIF1_2, 0,
+		/* RESERVED [1] */
+		0, 0,
+		/* SEL_LBS [1] */
+		FN_SEL_LBS_0, FN_SEL_LBS_1,
+		/* SEL_TSIF0 [2] */
+		FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3,
+		/* SEL_SOF3 [1] */
+		FN_SEL_SOF3_0, FN_SEL_SOF3_1,
+		/* SEL_SOF0 [1] */
+		FN_SEL_SOF0_0, FN_SEL_SOF0_1, }
+	},
+	{ PINMUX_CFG_REG_VAR("MOD_SEL2", 0xE6060094, 32,
+			     3, 1, 1, 1, 2, 1, 2, 1, 2,
+			     1, 1, 1, 3, 3, 2, 3, 2, 2) {
+		/* RESERVED [3] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* SEL_TMU1 [1] */
+		FN_SEL_TMU1_0, FN_SEL_TMU1_1,
+		/* SEL_HSCIF1 [1] */
+		FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1,
+		/* SEL_SCIFCLK [1] */
+		FN_SEL_SCIFCLK_0, FN_SEL_SCIFCLK_1,
+		/* SEL_CAN0 [2] */
+		FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3,
+		/* SEL_CANCLK [1] */
+		FN_SEL_CANCLK_0, FN_SEL_CANCLK_1,
+		/* SEL_SCIFA2 [2] */
+		FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, FN_SEL_SCIFA2_2, 0,
+		/* SEL_CAN1 [1] */
+		FN_SEL_CAN1_0, FN_SEL_CAN1_1,
+		/* RESERVED [2] */
+		0, 0, 0, 0,
+		/* RESERVED [1] (actually TX2, RX2 vs. TX2_B, RX2_B of SCIF2) */
+		0, 0,
+		/* SEL_ADI [1] */
+		FN_SEL_ADI_0, FN_SEL_ADI_1,
+		/* SEL_SSP [1] */
+		FN_SEL_SSP_0, FN_SEL_SSP_1,
+		/* SEL_FM [3] */
+		FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, FN_SEL_FM_3,
+		FN_SEL_FM_4, FN_SEL_FM_5, FN_SEL_FM_6, 0,
+		/* SEL_HSCIF0 [3] */
+		FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2,
+		FN_SEL_HSCIF0_3, FN_SEL_HSCIF0_4, FN_SEL_HSCIF0_5, 0, 0,
+		/* SEL_GPS [2] */
+		FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, 0,
+		/* SEL_RDS [3] */
+		FN_SEL_RDS_0, FN_SEL_RDS_1, FN_SEL_RDS_2,
+		FN_SEL_RDS_3, FN_SEL_RDS_4, FN_SEL_RDS_5, 0, 0,
+		/* SEL_SIM [2] */
+		FN_SEL_SIM_0, FN_SEL_SIM_1, FN_SEL_SIM_2, 0,
+		/* SEL_SSI8 [2] */
+		FN_SEL_SSI8_0, FN_SEL_SSI8_1, FN_SEL_SSI8_2, 0, }
+	},
+	{ PINMUX_CFG_REG_VAR("MOD_SEL3", 0xE6060098, 32,
+			     1, 1, 2, 4, 4, 2, 2,
+			     4, 2, 3, 2, 3, 2) {
+		/* SEL_IICDVFS [1] */
+		FN_SEL_IICDVFS_0, FN_SEL_IICDVFS_1,
+		/* SEL_IIC0 [1] */
+		FN_SEL_IIC0_0, FN_SEL_IIC0_1,
+		/* RESERVED [2] */
+		0, 0, 0, 0,
+		/* RESERVED [4] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* RESERVED [4] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* RESERVED [2] */
+		0, 0, 0, 0,
+		/* SEL_IEB [2] */
+		FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, 0,
+		/* RESERVED [4] */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* RESERVED [2] */
+		0, 0, 0, 0,
+		/* SEL_IIC2 [3] */
+		FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3,
+		FN_SEL_IIC2_4, 0, 0, 0,
+		/* SEL_IIC1 [2] */
+		FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2, 0,
+		/* SEL_I2C2 [3] */
+		FN_SEL_I2C2_0, FN_SEL_I2C2_1, FN_SEL_I2C2_2, FN_SEL_I2C2_3,
+		FN_SEL_I2C2_4, 0, 0, 0,
+		/* SEL_I2C1 [2] */
+		FN_SEL_I2C1_0, FN_SEL_I2C1_1, FN_SEL_I2C1_2, 0, }
+	},
+	{ },
+};
+
+const struct sh_pfc_soc_info r8a7790_pinmux_info = {
+	.name = "r8a77900_pfc",
+	.unlock_reg = 0xe6060000, /* PMMR */
+
+	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+	.pins = pinmux_pins,
+	.nr_pins = ARRAY_SIZE(pinmux_pins),
+	.groups = pinmux_groups,
+	.nr_groups = ARRAY_SIZE(pinmux_groups),
+	.functions = pinmux_functions,
+	.nr_functions = ARRAY_SIZE(pinmux_functions),
+
+	.cfg_regs = pinmux_config_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-sh7372.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-sh7372.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-sh7372.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-sh7372.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,10 +20,14 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
+#include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/pinctrl/pinconf-generic.h>
+
 #include <mach/irqs.h>
 #include <mach/sh7372.h>
 
+#include "core.h"
 #include "sh_pfc.h"
 
 #define CPU_ALL_PORT(fn, pfx, sfx) \
@@ -34,6 +38,35 @@
 	PORT_10(fn, pfx##16, sfx),	PORT_10(fn, pfx##17, sfx), \
 	PORT_10(fn, pfx##18, sfx),	PORT_1(fn, pfx##190, sfx)
 
+#undef _GPIO_PORT
+#define _GPIO_PORT(gpio, sfx)						\
+	[gpio] = {							\
+		.name = __stringify(PORT##gpio),			\
+		.enum_id = PORT##gpio##_DATA,				\
+	}
+
+#define IRQC_PIN_MUX(irq, pin)						\
+static const unsigned int intc_irq##irq##_pins[] = {			\
+	pin,								\
+};									\
+static const unsigned int intc_irq##irq##_mux[] = {			\
+	IRQ##irq##_MARK,						\
+}
+
+#define IRQC_PINS_MUX(irq, pin0, pin1)					\
+static const unsigned int intc_irq##irq##_0_pins[] = {			\
+	pin0,								\
+};									\
+static const unsigned int intc_irq##irq##_0_mux[] = {			\
+	IRQ##irq##_##pin0##_MARK,					\
+};									\
+static const unsigned int intc_irq##irq##_1_pins[] = {			\
+	pin1,								\
+};									\
+static const unsigned int intc_irq##irq##_1_mux[] = {			\
+	IRQ##irq##_##pin1##_MARK,					\
+}
+
 enum {
 	PINMUX_RESERVED = 0,
 
@@ -47,16 +80,6 @@ enum {
 	PORT_ALL(IN),
 	PINMUX_INPUT_END,
 
-	/* PORT0_IN_PU -> PORT190_IN_PU */
-	PINMUX_INPUT_PULLUP_BEGIN,
-	PORT_ALL(IN_PU),
-	PINMUX_INPUT_PULLUP_END,
-
-	/* PORT0_IN_PD -> PORT190_IN_PD */
-	PINMUX_INPUT_PULLDOWN_BEGIN,
-	PORT_ALL(IN_PD),
-	PINMUX_INPUT_PULLDOWN_END,
-
 	/* PORT0_OUT -> PORT190_OUT */
 	PINMUX_OUTPUT_BEGIN,
 	PORT_ALL(OUT),
@@ -368,124 +391,11 @@ enum {
 	PINMUX_MARK_END,
 };
 
-static const pinmux_enum_t pinmux_data[] = {
-
-	/* specify valid pin states for each pin in GPIO mode */
-	PORT_DATA_IO_PD(0),		PORT_DATA_IO_PD(1),
-	PORT_DATA_O(2),			PORT_DATA_I_PD(3),
-	PORT_DATA_I_PD(4),		PORT_DATA_I_PD(5),
-	PORT_DATA_IO_PU_PD(6),		PORT_DATA_I_PD(7),
-	PORT_DATA_IO_PD(8),		PORT_DATA_O(9),
-
-	PORT_DATA_O(10),		PORT_DATA_O(11),
-	PORT_DATA_IO_PU_PD(12),		PORT_DATA_IO_PD(13),
-	PORT_DATA_IO_PD(14),		PORT_DATA_O(15),
-	PORT_DATA_IO_PD(16),		PORT_DATA_IO_PD(17),
-	PORT_DATA_I_PD(18),		PORT_DATA_IO(19),
-
-	PORT_DATA_IO(20),		PORT_DATA_IO(21),
-	PORT_DATA_IO(22),		PORT_DATA_IO(23),
-	PORT_DATA_IO(24),		PORT_DATA_IO(25),
-	PORT_DATA_IO(26),		PORT_DATA_IO(27),
-	PORT_DATA_IO(28),		PORT_DATA_IO(29),
-
-	PORT_DATA_IO(30),		PORT_DATA_IO(31),
-	PORT_DATA_IO(32),		PORT_DATA_IO(33),
-	PORT_DATA_IO(34),		PORT_DATA_IO(35),
-	PORT_DATA_IO(36),		PORT_DATA_IO(37),
-	PORT_DATA_IO(38),		PORT_DATA_IO(39),
-
-	PORT_DATA_IO(40),		PORT_DATA_IO(41),
-	PORT_DATA_IO(42),		PORT_DATA_IO(43),
-	PORT_DATA_IO(44),		PORT_DATA_IO(45),
-	PORT_DATA_IO_PU(46),		PORT_DATA_IO_PU(47),
-	PORT_DATA_IO_PU(48),		PORT_DATA_IO_PU(49),
-
-	PORT_DATA_IO_PU(50),		PORT_DATA_IO_PU(51),
-	PORT_DATA_IO_PU(52),		PORT_DATA_IO_PU(53),
-	PORT_DATA_IO_PU(54),		PORT_DATA_IO_PU(55),
-	PORT_DATA_IO_PU(56),		PORT_DATA_IO_PU(57),
-	PORT_DATA_IO_PU(58),		PORT_DATA_IO_PU(59),
-
-	PORT_DATA_IO_PU(60),		PORT_DATA_IO_PU(61),
-	PORT_DATA_IO(62),		PORT_DATA_O(63),
-	PORT_DATA_O(64),		PORT_DATA_IO_PU(65),
-	PORT_DATA_O(66),		PORT_DATA_IO_PU(67),  /*66?*/
-	PORT_DATA_O(68),		PORT_DATA_IO(69),
-
-	PORT_DATA_IO(70),		PORT_DATA_IO(71),
-	PORT_DATA_O(72),		PORT_DATA_I_PU(73),
-	PORT_DATA_I_PU_PD(74),		PORT_DATA_IO_PU_PD(75),
-	PORT_DATA_IO_PU_PD(76),		PORT_DATA_IO_PU_PD(77),
-	PORT_DATA_IO_PU_PD(78),		PORT_DATA_IO_PU_PD(79),
-
-	PORT_DATA_IO_PU_PD(80),		PORT_DATA_IO_PU_PD(81),
-	PORT_DATA_IO_PU_PD(82),		PORT_DATA_IO_PU_PD(83),
-	PORT_DATA_IO_PU_PD(84),		PORT_DATA_IO_PU_PD(85),
-	PORT_DATA_IO_PU_PD(86),		PORT_DATA_IO_PU_PD(87),
-	PORT_DATA_IO_PU_PD(88),		PORT_DATA_IO_PU_PD(89),
-
-	PORT_DATA_IO_PU_PD(90),		PORT_DATA_IO_PU_PD(91),
-	PORT_DATA_IO_PU_PD(92),		PORT_DATA_IO_PU_PD(93),
-	PORT_DATA_IO_PU_PD(94),		PORT_DATA_IO_PU_PD(95),
-	PORT_DATA_IO_PU(96),		PORT_DATA_IO_PU_PD(97),
-	PORT_DATA_IO_PU_PD(98),		PORT_DATA_O(99), /*99?*/
-
-	PORT_DATA_IO_PD(100),		PORT_DATA_IO_PD(101),
-	PORT_DATA_IO_PD(102),		PORT_DATA_IO_PD(103),
-	PORT_DATA_IO_PD(104),		PORT_DATA_IO_PD(105),
-	PORT_DATA_IO_PU(106),		PORT_DATA_IO_PU(107),
-	PORT_DATA_IO_PU(108),		PORT_DATA_IO_PU(109),
-
-	PORT_DATA_IO_PU(110),		PORT_DATA_IO_PU(111),
-	PORT_DATA_IO_PD(112),		PORT_DATA_IO_PD(113),
-	PORT_DATA_IO_PU(114),		PORT_DATA_IO_PU(115),
-	PORT_DATA_IO_PU(116),		PORT_DATA_IO_PU(117),
-	PORT_DATA_IO_PU(118),		PORT_DATA_IO_PU(119),
-
-	PORT_DATA_IO_PU(120),		PORT_DATA_IO_PD(121),
-	PORT_DATA_IO_PD(122),		PORT_DATA_IO_PD(123),
-	PORT_DATA_IO_PD(124),		PORT_DATA_IO_PD(125),
-	PORT_DATA_IO_PD(126),		PORT_DATA_IO_PD(127),
-	PORT_DATA_IO_PD(128),		PORT_DATA_IO_PU_PD(129),
-
-	PORT_DATA_IO_PU_PD(130),	PORT_DATA_IO_PU_PD(131),
-	PORT_DATA_IO_PU_PD(132),	PORT_DATA_IO_PU_PD(133),
-	PORT_DATA_IO_PU_PD(134),	PORT_DATA_IO_PU_PD(135),
-	PORT_DATA_IO_PD(136),		PORT_DATA_IO_PD(137),
-	PORT_DATA_IO_PD(138),		PORT_DATA_IO_PD(139),
-
-	PORT_DATA_IO_PD(140),		PORT_DATA_IO_PD(141),
-	PORT_DATA_IO_PD(142),		PORT_DATA_IO_PU_PD(143),
-	PORT_DATA_IO_PD(144),		PORT_DATA_IO_PD(145),
-	PORT_DATA_IO_PD(146),		PORT_DATA_IO_PD(147),
-	PORT_DATA_IO_PD(148),		PORT_DATA_IO_PD(149),
-
-	PORT_DATA_IO_PD(150),		PORT_DATA_IO_PD(151),
-	PORT_DATA_IO_PU_PD(152),	PORT_DATA_I_PD(153),
-	PORT_DATA_IO_PU_PD(154),	PORT_DATA_I_PD(155),
-	PORT_DATA_IO_PD(156),		PORT_DATA_IO_PD(157),
-	PORT_DATA_I_PD(158),		PORT_DATA_IO_PD(159),
-
-	PORT_DATA_O(160),		PORT_DATA_IO_PD(161),
-	PORT_DATA_IO_PD(162),		PORT_DATA_IO_PD(163),
-	PORT_DATA_I_PD(164),		PORT_DATA_IO_PD(165),
-	PORT_DATA_I_PD(166),		PORT_DATA_I_PD(167),
-	PORT_DATA_I_PD(168),		PORT_DATA_I_PD(169),
-
-	PORT_DATA_I_PD(170),		PORT_DATA_O(171),
-	PORT_DATA_IO_PU_PD(172),	PORT_DATA_IO_PU_PD(173),
-	PORT_DATA_IO_PU_PD(174),	PORT_DATA_IO_PU_PD(175),
-	PORT_DATA_IO_PU_PD(176),	PORT_DATA_IO_PU_PD(177),
-	PORT_DATA_IO_PU_PD(178),	PORT_DATA_O(179),
-
-	PORT_DATA_IO_PU_PD(180),	PORT_DATA_IO_PU_PD(181),
-	PORT_DATA_IO_PU_PD(182),	PORT_DATA_IO_PU_PD(183),
-	PORT_DATA_IO_PU_PD(184),	PORT_DATA_O(185),
-	PORT_DATA_IO_PU_PD(186),	PORT_DATA_IO_PU_PD(187),
-	PORT_DATA_IO_PU_PD(188),	PORT_DATA_IO_PU_PD(189),
+#define _PORT_DATA(pfx, sfx)	PORT_DATA_IO(pfx)
+#define PINMUX_DATA_GP_ALL()	CPU_ALL_PORT(_PORT_DATA, , unused)
 
-	PORT_DATA_IO_PU_PD(190),
+static const pinmux_enum_t pinmux_data[] = {
+	PINMUX_DATA_GP_ALL(),
 
 	/* IRQ */
 	PINMUX_DATA(IRQ0_6_MARK,	PORT6_FN0, 	MSEL1CR_0_0),
@@ -929,10 +839,582 @@ static const pinmux_enum_t pinmux_data[]
 	PINMUX_DATA(MFIv4_MARK,		MSEL4CR_6_1),
 };
 
+#define SH7372_PIN(pin, cfgs)						\
+	{								\
+		.name = __stringify(PORT##pin),				\
+		.enum_id = PORT##pin##_DATA,				\
+		.configs = cfgs,					\
+	}
+
+#define __I		(SH_PFC_PIN_CFG_INPUT)
+#define __O		(SH_PFC_PIN_CFG_OUTPUT)
+#define __IO		(SH_PFC_PIN_CFG_INPUT | SH_PFC_PIN_CFG_OUTPUT)
+#define __PD		(SH_PFC_PIN_CFG_PULL_DOWN)
+#define __PU		(SH_PFC_PIN_CFG_PULL_UP)
+#define __PUD		(SH_PFC_PIN_CFG_PULL_DOWN | SH_PFC_PIN_CFG_PULL_UP)
+
+#define SH7372_PIN_I_PD(pin)		SH7372_PIN(pin, __I | __PD)
+#define SH7372_PIN_I_PU(pin)		SH7372_PIN(pin, __I | __PU)
+#define SH7372_PIN_I_PU_PD(pin)		SH7372_PIN(pin, __I | __PUD)
+#define SH7372_PIN_IO(pin)		SH7372_PIN(pin, __IO)
+#define SH7372_PIN_IO_PD(pin)		SH7372_PIN(pin, __IO | __PD)
+#define SH7372_PIN_IO_PU(pin)		SH7372_PIN(pin, __IO | __PU)
+#define SH7372_PIN_IO_PU_PD(pin)	SH7372_PIN(pin, __IO | __PUD)
+#define SH7372_PIN_O(pin)		SH7372_PIN(pin, __O)
+#define SH7372_PIN_O_PU_PD(pin)		SH7372_PIN(pin, __O | __PUD)
+
 static struct sh_pfc_pin pinmux_pins[] = {
-	GPIO_PORT_ALL(),
+	/* Table 57-1 (I/O and Pull U/D) */
+	SH7372_PIN_IO_PD(0),		SH7372_PIN_IO_PD(1),
+	SH7372_PIN_O(2),		SH7372_PIN_I_PD(3),
+	SH7372_PIN_I_PD(4),		SH7372_PIN_I_PD(5),
+	SH7372_PIN_IO_PU_PD(6),		SH7372_PIN_I_PD(7),
+	SH7372_PIN_IO_PD(8),		SH7372_PIN_O(9),
+	SH7372_PIN_O(10),		SH7372_PIN_O(11),
+	SH7372_PIN_IO_PU_PD(12),	SH7372_PIN_IO_PD(13),
+	SH7372_PIN_IO_PD(14),		SH7372_PIN_O(15),
+	SH7372_PIN_IO_PD(16),		SH7372_PIN_IO_PD(17),
+	SH7372_PIN_I_PD(18),		SH7372_PIN_IO(19),
+	SH7372_PIN_IO(20),		SH7372_PIN_IO(21),
+	SH7372_PIN_IO(22),		SH7372_PIN_IO(23),
+	SH7372_PIN_IO(24),		SH7372_PIN_IO(25),
+	SH7372_PIN_IO(26),		SH7372_PIN_IO(27),
+	SH7372_PIN_IO(28),		SH7372_PIN_IO(29),
+	SH7372_PIN_IO(30),		SH7372_PIN_IO(31),
+	SH7372_PIN_IO(32),		SH7372_PIN_IO(33),
+	SH7372_PIN_IO(34),		SH7372_PIN_IO(35),
+	SH7372_PIN_IO(36),		SH7372_PIN_IO(37),
+	SH7372_PIN_IO(38),		SH7372_PIN_IO(39),
+	SH7372_PIN_IO(40),		SH7372_PIN_IO(41),
+	SH7372_PIN_IO(42),		SH7372_PIN_IO(43),
+	SH7372_PIN_IO(44),		SH7372_PIN_IO(45),
+	SH7372_PIN_IO_PU(46),		SH7372_PIN_IO_PU(47),
+	SH7372_PIN_IO_PU(48),		SH7372_PIN_IO_PU(49),
+	SH7372_PIN_IO_PU(50),		SH7372_PIN_IO_PU(51),
+	SH7372_PIN_IO_PU(52),		SH7372_PIN_IO_PU(53),
+	SH7372_PIN_IO_PU(54),		SH7372_PIN_IO_PU(55),
+	SH7372_PIN_IO_PU(56),		SH7372_PIN_IO_PU(57),
+	SH7372_PIN_IO_PU(58),		SH7372_PIN_IO_PU(59),
+	SH7372_PIN_IO_PU(60),		SH7372_PIN_IO_PU(61),
+	SH7372_PIN_IO(62),		SH7372_PIN_O(63),
+	SH7372_PIN_O(64),		SH7372_PIN_IO_PU(65),
+	SH7372_PIN_O_PU_PD(66),		SH7372_PIN_IO_PU(67),
+	SH7372_PIN_O(68),		SH7372_PIN_IO(69),
+	SH7372_PIN_IO(70),		SH7372_PIN_IO(71),
+	SH7372_PIN_O(72),		SH7372_PIN_I_PU(73),
+	SH7372_PIN_I_PU_PD(74),		SH7372_PIN_IO_PU_PD(75),
+	SH7372_PIN_IO_PU_PD(76),	SH7372_PIN_IO_PU_PD(77),
+	SH7372_PIN_IO_PU_PD(78),	SH7372_PIN_IO_PU_PD(79),
+	SH7372_PIN_IO_PU_PD(80),	SH7372_PIN_IO_PU_PD(81),
+	SH7372_PIN_IO_PU_PD(82),	SH7372_PIN_IO_PU_PD(83),
+	SH7372_PIN_IO_PU_PD(84),	SH7372_PIN_IO_PU_PD(85),
+	SH7372_PIN_IO_PU_PD(86),	SH7372_PIN_IO_PU_PD(87),
+	SH7372_PIN_IO_PU_PD(88),	SH7372_PIN_IO_PU_PD(89),
+	SH7372_PIN_IO_PU_PD(90),	SH7372_PIN_IO_PU_PD(91),
+	SH7372_PIN_IO_PU_PD(92),	SH7372_PIN_IO_PU_PD(93),
+	SH7372_PIN_IO_PU_PD(94),	SH7372_PIN_IO_PU_PD(95),
+	SH7372_PIN_IO_PU(96),		SH7372_PIN_IO_PU_PD(97),
+	SH7372_PIN_IO_PU_PD(98),	SH7372_PIN_O_PU_PD(99),
+	SH7372_PIN_IO_PD(100),		SH7372_PIN_IO_PD(101),
+	SH7372_PIN_IO_PD(102),		SH7372_PIN_IO_PD(103),
+	SH7372_PIN_IO_PD(104),		SH7372_PIN_IO_PD(105),
+	SH7372_PIN_IO_PU(106),		SH7372_PIN_IO_PU(107),
+	SH7372_PIN_IO_PU(108),		SH7372_PIN_IO_PU(109),
+	SH7372_PIN_IO_PU(110),		SH7372_PIN_IO_PU(111),
+	SH7372_PIN_IO_PD(112),		SH7372_PIN_IO_PD(113),
+	SH7372_PIN_IO_PU(114),		SH7372_PIN_IO_PU(115),
+	SH7372_PIN_IO_PU(116),		SH7372_PIN_IO_PU(117),
+	SH7372_PIN_IO_PU(118),		SH7372_PIN_IO_PU(119),
+	SH7372_PIN_IO_PU(120),		SH7372_PIN_IO_PD(121),
+	SH7372_PIN_IO_PD(122),		SH7372_PIN_IO_PD(123),
+	SH7372_PIN_IO_PD(124),		SH7372_PIN_IO_PD(125),
+	SH7372_PIN_IO_PD(126),		SH7372_PIN_IO_PD(127),
+	SH7372_PIN_IO_PD(128),		SH7372_PIN_IO_PU_PD(129),
+	SH7372_PIN_IO_PU_PD(130),	SH7372_PIN_IO_PU_PD(131),
+	SH7372_PIN_IO_PU_PD(132),	SH7372_PIN_IO_PU_PD(133),
+	SH7372_PIN_IO_PU_PD(134),	SH7372_PIN_IO_PU_PD(135),
+	SH7372_PIN_IO_PD(136),		SH7372_PIN_IO_PD(137),
+	SH7372_PIN_IO_PD(138),		SH7372_PIN_IO_PD(139),
+	SH7372_PIN_IO_PD(140),		SH7372_PIN_IO_PD(141),
+	SH7372_PIN_IO_PD(142),		SH7372_PIN_IO_PU_PD(143),
+	SH7372_PIN_IO_PD(144),		SH7372_PIN_IO_PD(145),
+	SH7372_PIN_IO_PD(146),		SH7372_PIN_IO_PD(147),
+	SH7372_PIN_IO_PD(148),		SH7372_PIN_IO_PD(149),
+	SH7372_PIN_IO_PD(150),		SH7372_PIN_IO_PD(151),
+	SH7372_PIN_IO_PU_PD(152),	SH7372_PIN_I_PD(153),
+	SH7372_PIN_IO_PU_PD(154),	SH7372_PIN_I_PD(155),
+	SH7372_PIN_IO_PD(156),		SH7372_PIN_IO_PD(157),
+	SH7372_PIN_I_PD(158),		SH7372_PIN_IO_PD(159),
+	SH7372_PIN_O(160),		SH7372_PIN_IO_PD(161),
+	SH7372_PIN_IO_PD(162),		SH7372_PIN_IO_PD(163),
+	SH7372_PIN_I_PD(164),		SH7372_PIN_IO_PD(165),
+	SH7372_PIN_I_PD(166),		SH7372_PIN_I_PD(167),
+	SH7372_PIN_I_PD(168),		SH7372_PIN_I_PD(169),
+	SH7372_PIN_I_PD(170),		SH7372_PIN_O(171),
+	SH7372_PIN_IO_PU_PD(172),	SH7372_PIN_IO_PU_PD(173),
+	SH7372_PIN_IO_PU_PD(174),	SH7372_PIN_IO_PU_PD(175),
+	SH7372_PIN_IO_PU_PD(176),	SH7372_PIN_IO_PU_PD(177),
+	SH7372_PIN_IO_PU_PD(178),	SH7372_PIN_O(179),
+	SH7372_PIN_IO_PU_PD(180),	SH7372_PIN_IO_PU_PD(181),
+	SH7372_PIN_IO_PU_PD(182),	SH7372_PIN_IO_PU_PD(183),
+	SH7372_PIN_IO_PU_PD(184),	SH7372_PIN_O(185),
+	SH7372_PIN_IO_PU_PD(186),	SH7372_PIN_IO_PU_PD(187),
+	SH7372_PIN_IO_PU_PD(188),	SH7372_PIN_IO_PU_PD(189),
+	SH7372_PIN_IO_PU_PD(190),
 };
 
+/* - BSC -------------------------------------------------------------------- */
+static const unsigned int bsc_data8_pins[] = {
+	/* D[0:7] */
+	46, 47, 48, 49, 50, 51, 52, 53,
+};
+static const unsigned int bsc_data8_mux[] = {
+	D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, D3_NAF3_MARK,
+	D4_NAF4_MARK, D5_NAF5_MARK, D6_NAF6_MARK, D7_NAF7_MARK,
+};
+static const unsigned int bsc_data16_pins[] = {
+	/* D[0:15] */
+	46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+};
+static const unsigned int bsc_data16_mux[] = {
+	D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, D3_NAF3_MARK,
+	D4_NAF4_MARK, D5_NAF5_MARK, D6_NAF6_MARK, D7_NAF7_MARK,
+	D8_NAF8_MARK, D9_NAF9_MARK, D10_NAF10_MARK, D11_NAF11_MARK,
+	D12_NAF12_MARK, D13_NAF13_MARK, D14_NAF14_MARK, D15_NAF15_MARK,
+};
+static const unsigned int bsc_cs0_pins[] = {
+	/* CS */
+	62,
+};
+static const unsigned int bsc_cs0_mux[] = {
+	CS0_MARK,
+};
+static const unsigned int bsc_cs2_pins[] = {
+	/* CS */
+	63,
+};
+static const unsigned int bsc_cs2_mux[] = {
+	CS2_MARK,
+};
+static const unsigned int bsc_cs4_pins[] = {
+	/* CS */
+	64,
+};
+static const unsigned int bsc_cs4_mux[] = {
+	CS4_MARK,
+};
+static const unsigned int bsc_cs5a_pins[] = {
+	/* CS */
+	65,
+};
+static const unsigned int bsc_cs5a_mux[] = {
+	CS5A_MARK,
+};
+static const unsigned int bsc_cs5b_pins[] = {
+	/* CS */
+	66,
+};
+static const unsigned int bsc_cs5b_mux[] = {
+	CS5B_MARK,
+};
+static const unsigned int bsc_cs6a_pins[] = {
+	/* CS */
+	67,
+};
+static const unsigned int bsc_cs6a_mux[] = {
+	CS6A_MARK,
+};
+static const unsigned int bsc_rd_we8_pins[] = {
+	/* RD, WE[0] */
+	69, 70,
+};
+static const unsigned int bsc_rd_we8_mux[] = {
+	RD_FSC_MARK, WE0_FWE_MARK,
+};
+static const unsigned int bsc_rd_we16_pins[] = {
+	/* RD, WE[0:1] */
+	69, 70, 71,
+};
+static const unsigned int bsc_rd_we16_mux[] = {
+	RD_FSC_MARK, WE0_FWE_MARK, WE1_MARK,
+};
+static const unsigned int bsc_bs_pins[] = {
+	/* BS */
+	19,
+};
+static const unsigned int bsc_bs_mux[] = {
+	BS_MARK,
+};
+static const unsigned int bsc_rdwr_pins[] = {
+	/* RDWR */
+	75,
+};
+static const unsigned int bsc_rdwr_mux[] = {
+	RDWR_MARK,
+};
+static const unsigned int bsc_wait_pins[] = {
+	/* WAIT */
+	74,
+};
+static const unsigned int bsc_wait_mux[] = {
+	WAIT_MARK,
+};
+/* - CEU -------------------------------------------------------------------- */
+static const unsigned int ceu_data_0_7_pins[] = {
+	/* D[0:7] */
+	102, 103, 104, 105, 106, 107, 108, 109,
+};
+static const unsigned int ceu_data_0_7_mux[] = {
+	VIO_D0_MARK, VIO_D1_MARK, VIO_D2_MARK, VIO_D3_MARK,
+	VIO_D4_MARK, VIO_D5_MARK, VIO_D6_MARK, VIO_D7_MARK,
+};
+static const unsigned int ceu_data_8_15_pins[] = {
+	/* D[8:15] */
+	110, 111, 112, 113, 114, 115, 116, 117,
+};
+static const unsigned int ceu_data_8_15_mux[] = {
+	VIO_D8_MARK, VIO_D9_MARK, VIO_D10_MARK, VIO_D11_MARK,
+	VIO_D12_MARK, VIO_D13_MARK, VIO_D14_MARK, VIO_D15_MARK,
+};
+static const unsigned int ceu_clk_0_pins[] = {
+	/* CKO */
+	120,
+};
+static const unsigned int ceu_clk_0_mux[] = {
+	VIO_CKO_MARK,
+};
+static const unsigned int ceu_clk_1_pins[] = {
+	/* CKO */
+	16,
+};
+static const unsigned int ceu_clk_1_mux[] = {
+	VIO_CKO1_MARK,
+};
+static const unsigned int ceu_clk_2_pins[] = {
+	/* CKO */
+	17,
+};
+static const unsigned int ceu_clk_2_mux[] = {
+	VIO_CKO2_MARK,
+};
+static const unsigned int ceu_sync_pins[] = {
+	/* CLK, VD, HD */
+	118, 100, 101,
+};
+static const unsigned int ceu_sync_mux[] = {
+	VIO_CLK_MARK, VIO_VD_MARK, VIO_HD_MARK,
+};
+static const unsigned int ceu_field_pins[] = {
+	/* FIELD */
+	119,
+};
+static const unsigned int ceu_field_mux[] = {
+	VIO_FIELD_MARK,
+};
+/* - FLCTL ------------------------------------------------------------------ */
+static const unsigned int flctl_data_pins[] = {
+	/* NAF[0:15] */
+	46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+};
+static const unsigned int flctl_data_mux[] = {
+	D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, D3_NAF3_MARK,
+	D4_NAF4_MARK, D5_NAF5_MARK, D6_NAF6_MARK, D7_NAF7_MARK,
+	D8_NAF8_MARK, D9_NAF9_MARK, D10_NAF10_MARK, D11_NAF11_MARK,
+	D12_NAF12_MARK, D13_NAF13_MARK, D14_NAF14_MARK, D15_NAF15_MARK,
+};
+static const unsigned int flctl_ce0_pins[] = {
+	/* CE */
+	68,
+};
+static const unsigned int flctl_ce0_mux[] = {
+	FCE0_MARK,
+};
+static const unsigned int flctl_ce1_pins[] = {
+	/* CE */
+	66,
+};
+static const unsigned int flctl_ce1_mux[] = {
+	FCE1_MARK,
+};
+static const unsigned int flctl_ctrl_pins[] = {
+	/* FCDE, FOE, FSC, FWE, FRB */
+	24, 23, 69, 70, 73,
+};
+static const unsigned int flctl_ctrl_mux[] = {
+	A5_FCDE_MARK, A4_FOE_MARK, RD_FSC_MARK, WE0_FWE_MARK, FRB_MARK,
+};
+/* - FSIA ------------------------------------------------------------------- */
+static const unsigned int fsia_mclk_in_pins[] = {
+	/* CK */
+	4,
+};
+static const unsigned int fsia_mclk_in_mux[] = {
+	FSIACK_MARK,
+};
+static const unsigned int fsia_mclk_out_pins[] = {
+	/* OMC */
+	8,
+};
+static const unsigned int fsia_mclk_out_mux[] = {
+	FSIAOMC_MARK,
+};
+static const unsigned int fsia_sclk_in_pins[] = {
+	/* ILR, IBT */
+	5, 6,
+};
+static const unsigned int fsia_sclk_in_mux[] = {
+	FSIAILR_MARK, FSIAIBT_MARK,
+};
+static const unsigned int fsia_sclk_out_pins[] = {
+	/* OLR, OBT */
+	9, 10,
+};
+static const unsigned int fsia_sclk_out_mux[] = {
+	FSIAOLR_MARK, FSIAOBT_MARK,
+};
+static const unsigned int fsia_data_in_pins[] = {
+	/* ISLD */
+	7,
+};
+static const unsigned int fsia_data_in_mux[] = {
+	FSIAISLD_MARK,
+};
+static const unsigned int fsia_data_out_pins[] = {
+	/* OSLD */
+	11,
+};
+static const unsigned int fsia_data_out_mux[] = {
+	FSIAOSLD_MARK,
+};
+static const unsigned int fsia_spdif_0_pins[] = {
+	/* SPDIF */
+	11,
+};
+static const unsigned int fsia_spdif_0_mux[] = {
+	FSIASPDIF_11_MARK,
+};
+static const unsigned int fsia_spdif_1_pins[] = {
+	/* SPDIF */
+	15,
+};
+static const unsigned int fsia_spdif_1_mux[] = {
+	FSIASPDIF_15_MARK,
+};
+/* - FSIB ------------------------------------------------------------------- */
+static const unsigned int fsib_mclk_in_pins[] = {
+	/* CK */
+	4,
+};
+static const unsigned int fsib_mclk_in_mux[] = {
+	FSIBCK_MARK,
+};
+/* - HDMI ------------------------------------------------------------------- */
+static const unsigned int hdmi_pins[] = {
+	/* HPD, CEC */
+	169, 170,
+};
+static const unsigned int hdmi_mux[] = {
+	HDMI_HPD_MARK, HDMI_CEC_MARK,
+};
+/* - INTC ------------------------------------------------------------------- */
+IRQC_PINS_MUX(0, 6, 162);
+IRQC_PIN_MUX(1, 12);
+IRQC_PINS_MUX(2, 4, 5);
+IRQC_PINS_MUX(3, 8, 16);
+IRQC_PINS_MUX(4, 17, 163);
+IRQC_PIN_MUX(5, 18);
+IRQC_PINS_MUX(6, 39, 164);
+IRQC_PINS_MUX(7, 40, 167);
+IRQC_PINS_MUX(8, 41, 168);
+IRQC_PINS_MUX(9, 42, 169);
+IRQC_PIN_MUX(10, 65);
+IRQC_PIN_MUX(11, 67);
+IRQC_PINS_MUX(12, 80, 137);
+IRQC_PINS_MUX(13, 81, 145);
+IRQC_PINS_MUX(14, 82, 146);
+IRQC_PINS_MUX(15, 83, 147);
+IRQC_PINS_MUX(16, 84, 170);
+IRQC_PIN_MUX(17, 85);
+IRQC_PIN_MUX(18, 86);
+IRQC_PIN_MUX(19, 87);
+IRQC_PIN_MUX(20, 92);
+IRQC_PIN_MUX(21, 93);
+IRQC_PIN_MUX(22, 94);
+IRQC_PIN_MUX(23, 95);
+IRQC_PIN_MUX(24, 112);
+IRQC_PIN_MUX(25, 119);
+IRQC_PINS_MUX(26, 121, 172);
+IRQC_PINS_MUX(27, 122, 180);
+IRQC_PINS_MUX(28, 123, 181);
+IRQC_PINS_MUX(29, 129, 182);
+IRQC_PINS_MUX(30, 130, 183);
+IRQC_PINS_MUX(31, 138, 184);
+/* - KEYSC ------------------------------------------------------------------ */
+static const unsigned int keysc_in04_0_pins[] = {
+	/* KEYIN[0:4] */
+	136, 135, 134, 133, 132,
+};
+static const unsigned int keysc_in04_0_mux[] = {
+	KEYIN0_136_MARK, KEYIN1_135_MARK, KEYIN2_134_MARK, KEYIN3_133_MARK,
+	KEYIN4_MARK,
+};
+static const unsigned int keysc_in04_1_pins[] = {
+	/* KEYIN[0:4] */
+	121, 122, 123, 124, 132,
+};
+static const unsigned int keysc_in04_1_mux[] = {
+	KEYIN0_121_MARK, KEYIN1_122_MARK, KEYIN2_123_MARK, KEYIN3_124_MARK,
+	KEYIN4_MARK,
+};
+static const unsigned int keysc_in5_pins[] = {
+	/* KEYIN5 */
+	131,
+};
+static const unsigned int keysc_in5_mux[] = {
+	KEYIN5_MARK,
+};
+static const unsigned int keysc_in6_pins[] = {
+	/* KEYIN6 */
+	130,
+};
+static const unsigned int keysc_in6_mux[] = {
+	KEYIN6_MARK,
+};
+static const unsigned int keysc_in7_pins[] = {
+	/* KEYIN7 */
+	129,
+};
+static const unsigned int keysc_in7_mux[] = {
+	KEYIN7_MARK,
+};
+static const unsigned int keysc_out4_pins[] = {
+	/* KEYOUT[0:3] */
+	128, 127, 126, 125,
+};
+static const unsigned int keysc_out4_mux[] = {
+	KEYOUT0_MARK, KEYOUT1_MARK, KEYOUT2_MARK, KEYOUT3_MARK,
+};
+static const unsigned int keysc_out5_pins[] = {
+	/* KEYOUT[0:4] */
+	128, 127, 126, 125, 124,
+};
+static const unsigned int keysc_out5_mux[] = {
+	KEYOUT0_MARK, KEYOUT1_MARK, KEYOUT2_MARK, KEYOUT3_MARK,
+	KEYOUT4_MARK,
+};
+static const unsigned int keysc_out6_pins[] = {
+	/* KEYOUT[0:5] */
+	128, 127, 126, 125, 124, 123,
+};
+static const unsigned int keysc_out6_mux[] = {
+	KEYOUT0_MARK, KEYOUT1_MARK, KEYOUT2_MARK, KEYOUT3_MARK,
+	KEYOUT4_MARK, KEYOUT5_MARK,
+};
+static const unsigned int keysc_out8_pins[] = {
+	/* KEYOUT[0:7] */
+	128, 127, 126, 125, 124, 123, 122, 121,
+};
+static const unsigned int keysc_out8_mux[] = {
+	KEYOUT0_MARK, KEYOUT1_MARK, KEYOUT2_MARK, KEYOUT3_MARK,
+	KEYOUT4_MARK, KEYOUT5_MARK, KEYOUT6_MARK, KEYOUT7_MARK,
+};
+/* - LCD -------------------------------------------------------------------- */
+static const unsigned int lcd_data8_pins[] = {
+	/* D[0:7] */
+	121, 122, 123, 124, 125, 126, 127, 128,
+};
+static const unsigned int lcd_data8_mux[] = {
+	/* LCDC */
+	LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK,
+	LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK,
+};
+static const unsigned int lcd_data9_pins[] = {
+	/* D[0:8] */
+	121, 122, 123, 124, 125, 126, 127, 128,
+	129,
+	137, 138, 139, 140, 141, 142, 143, 144,
+};
+static const unsigned int lcd_data9_mux[] = {
+	LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK,
+	LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK,
+	LCDD8_MARK,
+};
+static const unsigned int lcd_data12_pins[] = {
+	/* D[0:11] */
+	121, 122, 123, 124, 125, 126, 127, 128,
+	129, 130, 131, 132,
+};
+static const unsigned int lcd_data12_mux[] = {
+	LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK,
+	LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK,
+	LCDD8_MARK, LCDD9_MARK,	LCDD10_MARK, LCDD11_MARK,
+};
+static const unsigned int lcd_data16_pins[] = {
+	/* D[0:15] */
+	121, 122, 123, 124, 125, 126, 127, 128,
+	129, 130, 131, 132, 133, 134, 135, 136,
+};
+static const unsigned int lcd_data16_mux[] = {
+	LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK,
+	LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK,
+	LCDD8_MARK, LCDD9_MARK,	LCDD10_MARK, LCDD11_MARK,
+	LCDD12_MARK, LCDD13_MARK, LCDD14_MARK, LCDD15_MARK,
+};
+static const unsigned int lcd_data18_pins[] = {
+	/* D[0:17] */
+	121, 122, 123, 124, 125, 126, 127, 128,
+	129, 130, 131, 132, 133, 134, 135, 136,
+	137, 138,
+};
+static const unsigned int lcd_data18_mux[] = {
+	LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK,
+	LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK,
+	LCDD8_MARK, LCDD9_MARK,	LCDD10_MARK, LCDD11_MARK,
+	LCDD12_MARK, LCDD13_MARK, LCDD14_MARK, LCDD15_MARK,
+	LCDD16_MARK, LCDD17_MARK,
+};
+static const unsigned int lcd_data24_pins[] = {
+	/* D[0:23] */
+	121, 122, 123, 124, 125, 126, 127, 128,
+	129, 130, 131, 132, 133, 134, 135, 136,
+	137, 138, 139, 140, 141, 142, 143, 144,
+};
+static const unsigned int lcd_data24_mux[] = {
+	LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK,
+	LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK,
+	LCDD8_MARK, LCDD9_MARK,	LCDD10_MARK, LCDD11_MARK,
+	LCDD12_MARK, LCDD13_MARK, LCDD14_MARK, LCDD15_MARK,
+	LCDD16_MARK, LCDD17_MARK, LCDD18_MARK, LCDD19_MARK,
+	LCDD20_MARK, LCDD21_MARK, LCDD22_MARK, LCDD23_MARK,
+};
+static const unsigned int lcd_display_pins[] = {
+	/* DON */
+	151,
+};
+static const unsigned int lcd_display_mux[] = {
+	LCDDON_MARK,
+};
+static const unsigned int lcd_lclk_pins[] = {
+	/* LCLK */
+	150,
+};
+static const unsigned int lcd_lclk_mux[] = {
+	LCDLCLK_MARK,
+};
+static const unsigned int lcd_sync_pins[] = {
+	/* VSYN, HSYN, DCK, DISP */
+	146, 145, 147, 149,
+};
+static const unsigned int lcd_sync_mux[] = {
+	LCDVSYN_MARK, LCDHSYN_MARK, LCDDCK_MARK, LCDDISP_MARK,
+};
+static const unsigned int lcd_sys_pins[] = {
+	/* CS, WR, RD, RS */
+	145, 147, 148, 149,
+};
+static const unsigned int lcd_sys_mux[] = {
+	LCDCS_MARK, LCDWR_MARK, LCDRD_MARK, LCDRS_MARK,
+};
 /* - MMCIF ------------------------------------------------------------------ */
 static const unsigned int mmc0_data1_0_pins[] = {
 	/* D[0] */
@@ -993,6 +1475,139 @@ static const unsigned int mmc0_ctrl_1_pi
 static const unsigned int mmc0_ctrl_1_mux[] = {
 	MMCCMD1_MARK, MMCCLK1_MARK,
 };
+/* - SCIFA0 ----------------------------------------------------------------- */
+static const unsigned int scifa0_data_pins[] = {
+	/* RXD, TXD */
+	153, 152,
+};
+static const unsigned int scifa0_data_mux[] = {
+	SCIFA0_RXD_MARK, SCIFA0_TXD_MARK,
+};
+static const unsigned int scifa0_clk_pins[] = {
+	/* SCK */
+	156,
+};
+static const unsigned int scifa0_clk_mux[] = {
+	SCIFA0_SCK_MARK,
+};
+static const unsigned int scifa0_ctrl_pins[] = {
+	/* RTS, CTS */
+	157, 158,
+};
+static const unsigned int scifa0_ctrl_mux[] = {
+	SCIFA0_RTS_MARK, SCIFA0_CTS_MARK,
+};
+/* - SCIFA1 ----------------------------------------------------------------- */
+static const unsigned int scifa1_data_pins[] = {
+	/* RXD, TXD */
+	155, 154,
+};
+static const unsigned int scifa1_data_mux[] = {
+	SCIFA1_RXD_MARK, SCIFA1_TXD_MARK,
+};
+static const unsigned int scifa1_clk_pins[] = {
+	/* SCK */
+	159,
+};
+static const unsigned int scifa1_clk_mux[] = {
+	SCIFA1_SCK_MARK,
+};
+static const unsigned int scifa1_ctrl_pins[] = {
+	/* RTS, CTS */
+	160, 161,
+};
+static const unsigned int scifa1_ctrl_mux[] = {
+	SCIFA1_RTS_MARK, SCIFA1_CTS_MARK,
+};
+/* - SCIFA2 ----------------------------------------------------------------- */
+static const unsigned int scifa2_data_pins[] = {
+	/* RXD, TXD */
+	97, 96,
+};
+static const unsigned int scifa2_data_mux[] = {
+	SCIFA2_RXD1_MARK, SCIFA2_TXD1_MARK,
+};
+static const unsigned int scifa2_clk_pins[] = {
+	/* SCK */
+	98,
+};
+static const unsigned int scifa2_clk_mux[] = {
+	SCIFA2_SCK1_MARK,
+};
+static const unsigned int scifa2_ctrl_pins[] = {
+	/* RTS, CTS */
+	95, 94,
+};
+static const unsigned int scifa2_ctrl_mux[] = {
+	SCIFA2_RTS1_MARK, SCIFA2_CTS1_MARK,
+};
+/* - SCIFA3 ----------------------------------------------------------------- */
+static const unsigned int scifa3_data_pins[] = {
+	/* RXD, TXD */
+	144, 143,
+};
+static const unsigned int scifa3_data_mux[] = {
+	SCIFA3_RXD_MARK, SCIFA3_TXD_MARK,
+};
+static const unsigned int scifa3_clk_pins[] = {
+	/* SCK */
+	142,
+};
+static const unsigned int scifa3_clk_mux[] = {
+	SCIFA3_SCK_MARK,
+};
+static const unsigned int scifa3_ctrl_0_pins[] = {
+	/* RTS, CTS */
+	44, 43,
+};
+static const unsigned int scifa3_ctrl_0_mux[] = {
+	SCIFA3_RTS_44_MARK, SCIFA3_CTS_43_MARK,
+};
+static const unsigned int scifa3_ctrl_1_pins[] = {
+	/* RTS, CTS */
+	141, 140,
+};
+static const unsigned int scifa3_ctrl_1_mux[] = {
+	SCIFA3_RTS_141_MARK, SCIFA3_CTS_140_MARK,
+};
+/* - SCIFA4 ----------------------------------------------------------------- */
+static const unsigned int scifa4_data_pins[] = {
+	/* RXD, TXD */
+	5, 6,
+};
+static const unsigned int scifa4_data_mux[] = {
+	SCIFA4_RXD_MARK, SCIFA4_TXD_MARK,
+};
+/* - SCIFA5 ----------------------------------------------------------------- */
+static const unsigned int scifa5_data_pins[] = {
+	/* RXD, TXD */
+	8, 12,
+};
+static const unsigned int scifa5_data_mux[] = {
+	SCIFA5_RXD_MARK, SCIFA5_TXD_MARK,
+};
+/* - SCIFB ------------------------------------------------------------------ */
+static const unsigned int scifb_data_pins[] = {
+	/* RXD, TXD */
+	166, 165,
+};
+static const unsigned int scifb_data_mux[] = {
+	SCIFB_RXD_MARK, SCIFB_TXD_MARK,
+};
+static const unsigned int scifb_clk_pins[] = {
+	/* SCK */
+	162,
+};
+static const unsigned int scifb_clk_mux[] = {
+	SCIFB_SCK_MARK,
+};
+static const unsigned int scifb_ctrl_pins[] = {
+	/* RTS, CTS */
+	163, 164,
+};
+static const unsigned int scifb_ctrl_mux[] = {
+	SCIFB_RTS_MARK, SCIFB_CTS_MARK,
+};
 /* - SDHI0 ------------------------------------------------------------------ */
 static const unsigned int sdhi0_data1_pins[] = {
 	/* D0 */
@@ -1073,8 +1688,169 @@ static const unsigned int sdhi2_ctrl_pin
 static const unsigned int sdhi2_ctrl_mux[] = {
 	SDHICMD2_MARK, SDHICLK2_MARK,
 };
+/* - USB0 ------------------------------------------------------------------- */
+static const unsigned int usb0_vbus_pins[] = {
+	/* VBUS */
+	167,
+};
+static const unsigned int usb0_vbus_mux[] = {
+	VBUS0_0_MARK,
+};
+static const unsigned int usb0_otg_id_pins[] = {
+	/* IDIN */
+	113,
+};
+static const unsigned int usb0_otg_id_mux[] = {
+	IDIN_0_MARK,
+};
+static const unsigned int usb0_otg_ctrl_pins[] = {
+	/* PWEN, EXTLP, OVCN, OVCN2 */
+	116, 114, 117, 115,
+};
+static const unsigned int usb0_otg_ctrl_mux[] = {
+	PWEN_0_MARK, EXTLP_0_MARK, OVCN_0_MARK, OVCN2_0_MARK,
+};
+/* - USB1 ------------------------------------------------------------------- */
+static const unsigned int usb1_vbus_pins[] = {
+	/* VBUS */
+	168,
+};
+static const unsigned int usb1_vbus_mux[] = {
+	VBUS0_1_MARK,
+};
+static const unsigned int usb1_otg_id_0_pins[] = {
+	/* IDIN */
+	113,
+};
+static const unsigned int usb1_otg_id_0_mux[] = {
+	IDIN_1_113_MARK,
+};
+static const unsigned int usb1_otg_id_1_pins[] = {
+	/* IDIN */
+	18,
+};
+static const unsigned int usb1_otg_id_1_mux[] = {
+	IDIN_1_18_MARK,
+};
+static const unsigned int usb1_otg_ctrl_0_pins[] = {
+	/* PWEN, EXTLP, OVCN, OVCN2 */
+	115, 116, 114, 117, 113,
+};
+static const unsigned int usb1_otg_ctrl_0_mux[] = {
+	PWEN_1_115_MARK, EXTLP_1_MARK, OVCN_1_114_MARK, OVCN2_1_MARK,
+};
+static const unsigned int usb1_otg_ctrl_1_pins[] = {
+	/* PWEN, EXTLP, OVCN, OVCN2 */
+	138, 116, 162, 117, 18,
+};
+static const unsigned int usb1_otg_ctrl_1_mux[] = {
+	PWEN_1_138_MARK, EXTLP_1_MARK, OVCN_1_162_MARK, OVCN2_1_MARK,
+};
 
 static const struct sh_pfc_pin_group pinmux_groups[] = {
+	SH_PFC_PIN_GROUP(bsc_data8),
+	SH_PFC_PIN_GROUP(bsc_data16),
+	SH_PFC_PIN_GROUP(bsc_cs0),
+	SH_PFC_PIN_GROUP(bsc_cs2),
+	SH_PFC_PIN_GROUP(bsc_cs4),
+	SH_PFC_PIN_GROUP(bsc_cs5a),
+	SH_PFC_PIN_GROUP(bsc_cs5b),
+	SH_PFC_PIN_GROUP(bsc_cs6a),
+	SH_PFC_PIN_GROUP(bsc_rd_we8),
+	SH_PFC_PIN_GROUP(bsc_rd_we16),
+	SH_PFC_PIN_GROUP(bsc_bs),
+	SH_PFC_PIN_GROUP(bsc_rdwr),
+	SH_PFC_PIN_GROUP(ceu_data_0_7),
+	SH_PFC_PIN_GROUP(ceu_data_8_15),
+	SH_PFC_PIN_GROUP(ceu_clk_0),
+	SH_PFC_PIN_GROUP(ceu_clk_1),
+	SH_PFC_PIN_GROUP(ceu_clk_2),
+	SH_PFC_PIN_GROUP(ceu_sync),
+	SH_PFC_PIN_GROUP(ceu_field),
+	SH_PFC_PIN_GROUP(flctl_data),
+	SH_PFC_PIN_GROUP(flctl_ce0),
+	SH_PFC_PIN_GROUP(flctl_ce1),
+	SH_PFC_PIN_GROUP(flctl_ctrl),
+	SH_PFC_PIN_GROUP(fsia_mclk_in),
+	SH_PFC_PIN_GROUP(fsia_mclk_out),
+	SH_PFC_PIN_GROUP(fsia_sclk_in),
+	SH_PFC_PIN_GROUP(fsia_sclk_out),
+	SH_PFC_PIN_GROUP(fsia_data_in),
+	SH_PFC_PIN_GROUP(fsia_data_out),
+	SH_PFC_PIN_GROUP(fsia_spdif_0),
+	SH_PFC_PIN_GROUP(fsia_spdif_1),
+	SH_PFC_PIN_GROUP(fsib_mclk_in),
+	SH_PFC_PIN_GROUP(hdmi),
+	SH_PFC_PIN_GROUP(intc_irq0_0),
+	SH_PFC_PIN_GROUP(intc_irq0_1),
+	SH_PFC_PIN_GROUP(intc_irq1),
+	SH_PFC_PIN_GROUP(intc_irq2_0),
+	SH_PFC_PIN_GROUP(intc_irq2_1),
+	SH_PFC_PIN_GROUP(intc_irq3_0),
+	SH_PFC_PIN_GROUP(intc_irq3_1),
+	SH_PFC_PIN_GROUP(intc_irq4_0),
+	SH_PFC_PIN_GROUP(intc_irq4_1),
+	SH_PFC_PIN_GROUP(intc_irq5),
+	SH_PFC_PIN_GROUP(intc_irq6_0),
+	SH_PFC_PIN_GROUP(intc_irq6_1),
+	SH_PFC_PIN_GROUP(intc_irq7_0),
+	SH_PFC_PIN_GROUP(intc_irq7_1),
+	SH_PFC_PIN_GROUP(intc_irq8_0),
+	SH_PFC_PIN_GROUP(intc_irq8_1),
+	SH_PFC_PIN_GROUP(intc_irq9_0),
+	SH_PFC_PIN_GROUP(intc_irq9_1),
+	SH_PFC_PIN_GROUP(intc_irq10),
+	SH_PFC_PIN_GROUP(intc_irq11),
+	SH_PFC_PIN_GROUP(intc_irq12_0),
+	SH_PFC_PIN_GROUP(intc_irq12_1),
+	SH_PFC_PIN_GROUP(intc_irq13_0),
+	SH_PFC_PIN_GROUP(intc_irq13_1),
+	SH_PFC_PIN_GROUP(intc_irq14_0),
+	SH_PFC_PIN_GROUP(intc_irq14_1),
+	SH_PFC_PIN_GROUP(intc_irq15_0),
+	SH_PFC_PIN_GROUP(intc_irq15_1),
+	SH_PFC_PIN_GROUP(intc_irq16_0),
+	SH_PFC_PIN_GROUP(intc_irq16_1),
+	SH_PFC_PIN_GROUP(intc_irq17),
+	SH_PFC_PIN_GROUP(intc_irq18),
+	SH_PFC_PIN_GROUP(intc_irq19),
+	SH_PFC_PIN_GROUP(intc_irq20),
+	SH_PFC_PIN_GROUP(intc_irq21),
+	SH_PFC_PIN_GROUP(intc_irq22),
+	SH_PFC_PIN_GROUP(intc_irq23),
+	SH_PFC_PIN_GROUP(intc_irq24),
+	SH_PFC_PIN_GROUP(intc_irq25),
+	SH_PFC_PIN_GROUP(intc_irq26_0),
+	SH_PFC_PIN_GROUP(intc_irq26_1),
+	SH_PFC_PIN_GROUP(intc_irq27_0),
+	SH_PFC_PIN_GROUP(intc_irq27_1),
+	SH_PFC_PIN_GROUP(intc_irq28_0),
+	SH_PFC_PIN_GROUP(intc_irq28_1),
+	SH_PFC_PIN_GROUP(intc_irq29_0),
+	SH_PFC_PIN_GROUP(intc_irq29_1),
+	SH_PFC_PIN_GROUP(intc_irq30_0),
+	SH_PFC_PIN_GROUP(intc_irq30_1),
+	SH_PFC_PIN_GROUP(intc_irq31_0),
+	SH_PFC_PIN_GROUP(intc_irq31_1),
+	SH_PFC_PIN_GROUP(keysc_in04_0),
+	SH_PFC_PIN_GROUP(keysc_in04_1),
+	SH_PFC_PIN_GROUP(keysc_in5),
+	SH_PFC_PIN_GROUP(keysc_in6),
+	SH_PFC_PIN_GROUP(keysc_in7),
+	SH_PFC_PIN_GROUP(keysc_out4),
+	SH_PFC_PIN_GROUP(keysc_out5),
+	SH_PFC_PIN_GROUP(keysc_out6),
+	SH_PFC_PIN_GROUP(keysc_out8),
+	SH_PFC_PIN_GROUP(lcd_data8),
+	SH_PFC_PIN_GROUP(lcd_data9),
+	SH_PFC_PIN_GROUP(lcd_data12),
+	SH_PFC_PIN_GROUP(lcd_data16),
+	SH_PFC_PIN_GROUP(lcd_data18),
+	SH_PFC_PIN_GROUP(lcd_data24),
+	SH_PFC_PIN_GROUP(lcd_display),
+	SH_PFC_PIN_GROUP(lcd_lclk),
+	SH_PFC_PIN_GROUP(lcd_sync),
+	SH_PFC_PIN_GROUP(lcd_sys),
 	SH_PFC_PIN_GROUP(mmc0_data1_0),
 	SH_PFC_PIN_GROUP(mmc0_data4_0),
 	SH_PFC_PIN_GROUP(mmc0_data8_0),
@@ -1083,6 +1859,24 @@ static const struct sh_pfc_pin_group pin
 	SH_PFC_PIN_GROUP(mmc0_data4_1),
 	SH_PFC_PIN_GROUP(mmc0_data8_1),
 	SH_PFC_PIN_GROUP(mmc0_ctrl_1),
+	SH_PFC_PIN_GROUP(scifa0_data),
+	SH_PFC_PIN_GROUP(scifa0_clk),
+	SH_PFC_PIN_GROUP(scifa0_ctrl),
+	SH_PFC_PIN_GROUP(scifa1_data),
+	SH_PFC_PIN_GROUP(scifa1_clk),
+	SH_PFC_PIN_GROUP(scifa1_ctrl),
+	SH_PFC_PIN_GROUP(scifa2_data),
+	SH_PFC_PIN_GROUP(scifa2_clk),
+	SH_PFC_PIN_GROUP(scifa2_ctrl),
+	SH_PFC_PIN_GROUP(scifa3_data),
+	SH_PFC_PIN_GROUP(scifa3_clk),
+	SH_PFC_PIN_GROUP(scifa3_ctrl_0),
+	SH_PFC_PIN_GROUP(scifa3_ctrl_1),
+	SH_PFC_PIN_GROUP(scifa4_data),
+	SH_PFC_PIN_GROUP(scifa5_data),
+	SH_PFC_PIN_GROUP(scifb_data),
+	SH_PFC_PIN_GROUP(scifb_clk),
+	SH_PFC_PIN_GROUP(scifb_ctrl),
 	SH_PFC_PIN_GROUP(sdhi0_data1),
 	SH_PFC_PIN_GROUP(sdhi0_data4),
 	SH_PFC_PIN_GROUP(sdhi0_ctrl),
@@ -1094,6 +1888,144 @@ static const struct sh_pfc_pin_group pin
 	SH_PFC_PIN_GROUP(sdhi2_data1),
 	SH_PFC_PIN_GROUP(sdhi2_data4),
 	SH_PFC_PIN_GROUP(sdhi2_ctrl),
+	SH_PFC_PIN_GROUP(usb0_vbus),
+	SH_PFC_PIN_GROUP(usb0_otg_id),
+	SH_PFC_PIN_GROUP(usb0_otg_ctrl),
+	SH_PFC_PIN_GROUP(usb1_vbus),
+	SH_PFC_PIN_GROUP(usb1_otg_id_0),
+	SH_PFC_PIN_GROUP(usb1_otg_id_1),
+	SH_PFC_PIN_GROUP(usb1_otg_ctrl_0),
+	SH_PFC_PIN_GROUP(usb1_otg_ctrl_1),
+};
+
+static const char * const bsc_groups[] = {
+	"bsc_data8",
+	"bsc_data16",
+	"bsc_cs0",
+	"bsc_cs2",
+	"bsc_cs4",
+	"bsc_cs5a",
+	"bsc_cs5b",
+	"bsc_cs6a",
+	"bsc_rd_we8",
+	"bsc_rd_we16",
+	"bsc_bs",
+	"bsc_rdwr",
+};
+
+static const char * const ceu_groups[] = {
+	"ceu_data_0_7",
+	"ceu_data_8_15",
+	"ceu_clk_0",
+	"ceu_clk_1",
+	"ceu_clk_2",
+	"ceu_sync",
+	"ceu_field",
+};
+
+static const char * const flctl_groups[] = {
+	"flctl_data",
+	"flctl_ce0",
+	"flctl_ce1",
+	"flctl_ctrl",
+};
+
+static const char * const fsia_groups[] = {
+	"fsia_mclk_in",
+	"fsia_mclk_out",
+	"fsia_sclk_in",
+	"fsia_sclk_out",
+	"fsia_data_in",
+	"fsia_data_out",
+	"fsia_spdif_0",
+	"fsia_spdif_1",
+};
+
+static const char * const fsib_groups[] = {
+	"fsib_mclk_in",
+};
+
+static const char * const hdmi_groups[] = {
+	"hdmi",
+};
+
+static const char * const intc_groups[] = {
+	"intc_irq0_0",
+	"intc_irq0_1",
+	"intc_irq1",
+	"intc_irq2_0",
+	"intc_irq2_1",
+	"intc_irq3_0",
+	"intc_irq3_1",
+	"intc_irq4_0",
+	"intc_irq4_1",
+	"intc_irq5",
+	"intc_irq6_0",
+	"intc_irq6_1",
+	"intc_irq7_0",
+	"intc_irq7_1",
+	"intc_irq8_0",
+	"intc_irq8_1",
+	"intc_irq9_0",
+	"intc_irq9_1",
+	"intc_irq10",
+	"intc_irq11",
+	"intc_irq12_0",
+	"intc_irq12_1",
+	"intc_irq13_0",
+	"intc_irq13_1",
+	"intc_irq14_0",
+	"intc_irq14_1",
+	"intc_irq15_0",
+	"intc_irq15_1",
+	"intc_irq16_0",
+	"intc_irq16_1",
+	"intc_irq17",
+	"intc_irq18",
+	"intc_irq19",
+	"intc_irq20",
+	"intc_irq21",
+	"intc_irq22",
+	"intc_irq23",
+	"intc_irq24",
+	"intc_irq25",
+	"intc_irq26_0",
+	"intc_irq26_1",
+	"intc_irq27_0",
+	"intc_irq27_1",
+	"intc_irq28_0",
+	"intc_irq28_1",
+	"intc_irq29_0",
+	"intc_irq29_1",
+	"intc_irq30_0",
+	"intc_irq30_1",
+	"intc_irq31_0",
+	"intc_irq31_1",
+};
+
+static const char * const keysc_groups[] = {
+	"keysc_in04_0",
+	"keysc_in04_1",
+	"keysc_in5",
+	"keysc_in6",
+	"keysc_in7",
+	"keysc_out4",
+	"keysc_out5",
+	"keysc_out6",
+	"keysc_out8",
+};
+
+static const char * const lcd_groups[] = {
+	"lcd_data8",
+	"lcd_data9",
+	"lcd_data12",
+	"lcd_data16",
+	"lcd_data18",
+	"lcd_data24",
+	"lcd_display",
+	"lcd_lclk",
+	"lcd_sync",
+	"lcd_sys",
 };
 
 static const char * const mmc0_groups[] = {
@@ -1107,6 +2039,45 @@ static const char * const mmc0_groups[]
 	"mmc0_ctrl_1",
 };
 
+static const char * const scifa0_groups[] = {
+	"scifa0_data",
+	"scifa0_clk",
+	"scifa0_ctrl",
+};
+
+static const char * const scifa1_groups[] = {
+	"scifa1_data",
+	"scifa1_clk",
+	"scifa1_ctrl",
+};
+
+static const char * const scifa2_groups[] = {
+	"scifa2_data",
+	"scifa2_clk",
+	"scifa2_ctrl",
+};
+
+static const char * const scifa3_groups[] = {
+	"scifa3_data",
+	"scifa3_clk",
+	"scifa3_ctrl_0",
+	"scifa3_ctrl_1",
+};
+
+static const char * const scifa4_groups[] = {
+	"scifa4_data",
+};
+
+static const char * const scifa5_groups[] = {
+	"scifa5_data",
+};
+
+static const char * const scifb_groups[] = {
+	"scifb_data",
+	"scifb_clk",
+	"scifb_ctrl",
+};
+
 static const char * const sdhi0_groups[] = {
 	"sdhi0_data1",
 	"sdhi0_data4",
@@ -1127,256 +2098,55 @@ static const char * const sdhi2_groups[]
 	"sdhi2_ctrl",
 };
 
+static const char * const usb0_groups[] = {
+	"usb0_vbus",
+	"usb0_otg_id",
+	"usb0_otg_ctrl",
+};
+
+static const char * const usb1_groups[] = {
+	"usb1_vbus",
+	"usb1_otg_id_0",
+	"usb1_otg_id_1",
+	"usb1_otg_ctrl_0",
+	"usb1_otg_ctrl_1",
+};
+
 static const struct sh_pfc_function pinmux_functions[] = {
+	SH_PFC_FUNCTION(bsc),
+	SH_PFC_FUNCTION(ceu),
+	SH_PFC_FUNCTION(flctl),
+	SH_PFC_FUNCTION(fsia),
+	SH_PFC_FUNCTION(fsib),
+	SH_PFC_FUNCTION(hdmi),
+	SH_PFC_FUNCTION(intc),
+	SH_PFC_FUNCTION(keysc),
+	SH_PFC_FUNCTION(lcd),
 	SH_PFC_FUNCTION(mmc0),
+	SH_PFC_FUNCTION(scifa0),
+	SH_PFC_FUNCTION(scifa1),
+	SH_PFC_FUNCTION(scifa2),
+	SH_PFC_FUNCTION(scifa3),
+	SH_PFC_FUNCTION(scifa4),
+	SH_PFC_FUNCTION(scifa5),
+	SH_PFC_FUNCTION(scifb),
 	SH_PFC_FUNCTION(sdhi0),
 	SH_PFC_FUNCTION(sdhi1),
 	SH_PFC_FUNCTION(sdhi2),
+	SH_PFC_FUNCTION(usb0),
+	SH_PFC_FUNCTION(usb1),
 };
 
-#define PINMUX_FN_BASE	ARRAY_SIZE(pinmux_pins)
-
-static const struct pinmux_func pinmux_func_gpios[] = {
-	/* IRQ */
-	GPIO_FN(IRQ0_6),	GPIO_FN(IRQ0_162),	GPIO_FN(IRQ1),
-	GPIO_FN(IRQ2_4),	GPIO_FN(IRQ2_5),	GPIO_FN(IRQ3_8),
-	GPIO_FN(IRQ3_16),	GPIO_FN(IRQ4_17),	GPIO_FN(IRQ4_163),
-	GPIO_FN(IRQ5),		GPIO_FN(IRQ6_39),	GPIO_FN(IRQ6_164),
-	GPIO_FN(IRQ7_40),	GPIO_FN(IRQ7_167),	GPIO_FN(IRQ8_41),
-	GPIO_FN(IRQ8_168),	GPIO_FN(IRQ9_42),	GPIO_FN(IRQ9_169),
-	GPIO_FN(IRQ10),		GPIO_FN(IRQ11),		GPIO_FN(IRQ12_80),
-	GPIO_FN(IRQ12_137),	GPIO_FN(IRQ13_81),	GPIO_FN(IRQ13_145),
-	GPIO_FN(IRQ14_82),	GPIO_FN(IRQ14_146),	GPIO_FN(IRQ15_83),
-	GPIO_FN(IRQ15_147),	GPIO_FN(IRQ16_84),	GPIO_FN(IRQ16_170),
-	GPIO_FN(IRQ17),		GPIO_FN(IRQ18),		GPIO_FN(IRQ19),
-	GPIO_FN(IRQ20),		GPIO_FN(IRQ21),		GPIO_FN(IRQ22),
-	GPIO_FN(IRQ23),		GPIO_FN(IRQ24),		GPIO_FN(IRQ25),
-	GPIO_FN(IRQ26_121),	GPIO_FN(IRQ26_172),	GPIO_FN(IRQ27_122),
-	GPIO_FN(IRQ27_180),	GPIO_FN(IRQ28_123),	GPIO_FN(IRQ28_181),
-	GPIO_FN(IRQ29_129),	GPIO_FN(IRQ29_182),	GPIO_FN(IRQ30_130),
-	GPIO_FN(IRQ30_183),	GPIO_FN(IRQ31_138),	GPIO_FN(IRQ31_184),
-
-	/* MSIOF0 */
-	GPIO_FN(MSIOF0_TSYNC),	GPIO_FN(MSIOF0_TSCK),	GPIO_FN(MSIOF0_RXD),
-	GPIO_FN(MSIOF0_RSCK),	GPIO_FN(MSIOF0_RSYNC),	GPIO_FN(MSIOF0_MCK0),
-	GPIO_FN(MSIOF0_MCK1),	GPIO_FN(MSIOF0_SS1),	GPIO_FN(MSIOF0_SS2),
-	GPIO_FN(MSIOF0_TXD),
-
-	/* MSIOF1 */
-	GPIO_FN(MSIOF1_TSCK_39),	GPIO_FN(MSIOF1_TSCK_88),
-	GPIO_FN(MSIOF1_TSYNC_40),	GPIO_FN(MSIOF1_TSYNC_89),
-	GPIO_FN(MSIOF1_TXD_41),		GPIO_FN(MSIOF1_TXD_90),
-	GPIO_FN(MSIOF1_RXD_42),		GPIO_FN(MSIOF1_RXD_91),
-	GPIO_FN(MSIOF1_SS1_43),		GPIO_FN(MSIOF1_SS1_92),
-	GPIO_FN(MSIOF1_SS2_44),		GPIO_FN(MSIOF1_SS2_93),
-	GPIO_FN(MSIOF1_RSCK),		GPIO_FN(MSIOF1_RSYNC),
-	GPIO_FN(MSIOF1_MCK0),		GPIO_FN(MSIOF1_MCK1),
-
-	/* MSIOF2 */
-	GPIO_FN(MSIOF2_RSCK),	GPIO_FN(MSIOF2_RSYNC),	GPIO_FN(MSIOF2_MCK0),
-	GPIO_FN(MSIOF2_MCK1),	GPIO_FN(MSIOF2_SS1),	GPIO_FN(MSIOF2_SS2),
-	GPIO_FN(MSIOF2_TSYNC),	GPIO_FN(MSIOF2_TSCK),	GPIO_FN(MSIOF2_RXD),
-	GPIO_FN(MSIOF2_TXD),
-
-	/* BBIF1 */
-	GPIO_FN(BBIF1_RXD),	GPIO_FN(BBIF1_TSYNC),	GPIO_FN(BBIF1_TSCK),
-	GPIO_FN(BBIF1_TXD),	GPIO_FN(BBIF1_RSCK),	GPIO_FN(BBIF1_RSYNC),
-	GPIO_FN(BBIF1_FLOW),	GPIO_FN(BB_RX_FLOW_N),
-
-	/* BBIF2 */
-	GPIO_FN(BBIF2_TSCK1),	GPIO_FN(BBIF2_TSYNC1),
-	GPIO_FN(BBIF2_TXD1),	GPIO_FN(BBIF2_RXD),
-
-	/* FSI */
-	GPIO_FN(FSIACK),	GPIO_FN(FSIBCK),	GPIO_FN(FSIAILR),
-	GPIO_FN(FSIAIBT),	GPIO_FN(FSIAISLD),	GPIO_FN(FSIAOMC),
-	GPIO_FN(FSIAOLR),	GPIO_FN(FSIAOBT),	GPIO_FN(FSIAOSLD),
-	GPIO_FN(FSIASPDIF_11),	GPIO_FN(FSIASPDIF_15),
-
-	/* FMSI */
-	GPIO_FN(FMSOCK),	GPIO_FN(FMSOOLR),	GPIO_FN(FMSIOLR),
-	GPIO_FN(FMSOOBT),	GPIO_FN(FMSIOBT),	GPIO_FN(FMSOSLD),
-	GPIO_FN(FMSOILR),	GPIO_FN(FMSIILR),	GPIO_FN(FMSOIBT),
-	GPIO_FN(FMSIIBT),	GPIO_FN(FMSISLD),	GPIO_FN(FMSICK),
-
-	/* SCIFA0 */
-	GPIO_FN(SCIFA0_TXD),	GPIO_FN(SCIFA0_RXD),	GPIO_FN(SCIFA0_SCK),
-	GPIO_FN(SCIFA0_RTS),	GPIO_FN(SCIFA0_CTS),
-
-	/* SCIFA1 */
-	GPIO_FN(SCIFA1_TXD),	GPIO_FN(SCIFA1_RXD),	GPIO_FN(SCIFA1_SCK),
-	GPIO_FN(SCIFA1_RTS),	GPIO_FN(SCIFA1_CTS),
-
-	/* SCIFA2 */
-	GPIO_FN(SCIFA2_CTS1),	GPIO_FN(SCIFA2_RTS1),	GPIO_FN(SCIFA2_TXD1),
-	GPIO_FN(SCIFA2_RXD1),	GPIO_FN(SCIFA2_SCK1),
-
-	/* SCIFA3 */
-	GPIO_FN(SCIFA3_CTS_43),		GPIO_FN(SCIFA3_CTS_140),
-	GPIO_FN(SCIFA3_RTS_44),		GPIO_FN(SCIFA3_RTS_141),
-	GPIO_FN(SCIFA3_SCK),		GPIO_FN(SCIFA3_TXD),
-	GPIO_FN(SCIFA3_RXD),
-
-	/* SCIFA4 */
-	GPIO_FN(SCIFA4_RXD),	GPIO_FN(SCIFA4_TXD),
-
-	/* SCIFA5 */
-	GPIO_FN(SCIFA5_RXD),	GPIO_FN(SCIFA5_TXD),
-
-	/* SCIFB */
-	GPIO_FN(SCIFB_SCK),	GPIO_FN(SCIFB_RTS),	GPIO_FN(SCIFB_CTS),
-	GPIO_FN(SCIFB_TXD),	GPIO_FN(SCIFB_RXD),
-
-	/* CEU */
-	GPIO_FN(VIO_HD),	GPIO_FN(VIO_CKO1),	GPIO_FN(VIO_CKO2),
-	GPIO_FN(VIO_VD),	GPIO_FN(VIO_CLK),	GPIO_FN(VIO_FIELD),
-	GPIO_FN(VIO_CKO),	GPIO_FN(VIO_D0),	GPIO_FN(VIO_D1),
-	GPIO_FN(VIO_D2),	GPIO_FN(VIO_D3),	GPIO_FN(VIO_D4),
-	GPIO_FN(VIO_D5),	GPIO_FN(VIO_D6),	GPIO_FN(VIO_D7),
-	GPIO_FN(VIO_D8),	GPIO_FN(VIO_D9),	GPIO_FN(VIO_D10),
-	GPIO_FN(VIO_D11),	GPIO_FN(VIO_D12),	GPIO_FN(VIO_D13),
-	GPIO_FN(VIO_D14),	GPIO_FN(VIO_D15),
-
-	/* USB0 */
-	GPIO_FN(IDIN_0),	GPIO_FN(EXTLP_0),	GPIO_FN(OVCN2_0),
-	GPIO_FN(PWEN_0),	GPIO_FN(OVCN_0),	GPIO_FN(VBUS0_0),
-
-	/* USB1 */
-	GPIO_FN(IDIN_1_18),	GPIO_FN(IDIN_1_113),
-	GPIO_FN(OVCN_1_114),	GPIO_FN(OVCN_1_162),
-	GPIO_FN(PWEN_1_115),	GPIO_FN(PWEN_1_138),
-	GPIO_FN(EXTLP_1),	GPIO_FN(OVCN2_1),
-	GPIO_FN(VBUS0_1),
-
-	/* GPIO */
-	GPIO_FN(GPI0),	GPIO_FN(GPI1),	GPIO_FN(GPO0),	GPIO_FN(GPO1),
-
-	/* BSC */
-	GPIO_FN(BS),	GPIO_FN(WE1),	GPIO_FN(CKO),
-	GPIO_FN(WAIT),	GPIO_FN(RDWR),
-
-	GPIO_FN(A0),	GPIO_FN(A1),	GPIO_FN(A2),
-	GPIO_FN(A3),	GPIO_FN(A6),	GPIO_FN(A7),
-	GPIO_FN(A8),	GPIO_FN(A9),	GPIO_FN(A10),
-	GPIO_FN(A11),	GPIO_FN(A12),	GPIO_FN(A13),
-	GPIO_FN(A14),	GPIO_FN(A15),	GPIO_FN(A16),
-	GPIO_FN(A17),	GPIO_FN(A18),	GPIO_FN(A19),
-	GPIO_FN(A20),	GPIO_FN(A21),	GPIO_FN(A22),
-	GPIO_FN(A23),	GPIO_FN(A24),	GPIO_FN(A25),
-	GPIO_FN(A26),
-
-	GPIO_FN(CS0),	GPIO_FN(CS2),	GPIO_FN(CS4),
-	GPIO_FN(CS5A),	GPIO_FN(CS5B),	GPIO_FN(CS6A),
-
-	/* BSC/FLCTL */
-	GPIO_FN(RD_FSC),	GPIO_FN(WE0_FWE),	GPIO_FN(A4_FOE),
-	GPIO_FN(A5_FCDE),	GPIO_FN(D0_NAF0),	GPIO_FN(D1_NAF1),
-	GPIO_FN(D2_NAF2),	GPIO_FN(D3_NAF3),	GPIO_FN(D4_NAF4),
-	GPIO_FN(D5_NAF5),	GPIO_FN(D6_NAF6),	GPIO_FN(D7_NAF7),
-	GPIO_FN(D8_NAF8),	GPIO_FN(D9_NAF9),	GPIO_FN(D10_NAF10),
-	GPIO_FN(D11_NAF11),	GPIO_FN(D12_NAF12),	GPIO_FN(D13_NAF13),
-	GPIO_FN(D14_NAF14),	GPIO_FN(D15_NAF15),
-
-	/* SPU2 */
-	GPIO_FN(VINT_I),
-
-	/* FLCTL */
-	GPIO_FN(FCE1),	GPIO_FN(FCE0),	GPIO_FN(FRB),
-
-	/* HSI */
-	GPIO_FN(GP_RX_FLAG),	GPIO_FN(GP_RX_DATA),	GPIO_FN(GP_TX_READY),
-	GPIO_FN(GP_RX_WAKE),	GPIO_FN(MP_TX_FLAG),	GPIO_FN(MP_TX_DATA),
-	GPIO_FN(MP_RX_READY),	GPIO_FN(MP_TX_WAKE),
-
-	/* MFI */
-	GPIO_FN(MFIv6),
-	GPIO_FN(MFIv4),
-
-	GPIO_FN(MEMC_BUSCLK_MEMC_A0),	GPIO_FN(MEMC_ADV_MEMC_DREQ0),
-	GPIO_FN(MEMC_WAIT_MEMC_DREQ1),	GPIO_FN(MEMC_CS1_MEMC_A1),
-	GPIO_FN(MEMC_CS0),	GPIO_FN(MEMC_NOE),
-	GPIO_FN(MEMC_NWE),	GPIO_FN(MEMC_INT),
-
-	GPIO_FN(MEMC_AD0),	GPIO_FN(MEMC_AD1),	GPIO_FN(MEMC_AD2),
-	GPIO_FN(MEMC_AD3),	GPIO_FN(MEMC_AD4),	GPIO_FN(MEMC_AD5),
-	GPIO_FN(MEMC_AD6),	GPIO_FN(MEMC_AD7),	GPIO_FN(MEMC_AD8),
-	GPIO_FN(MEMC_AD9),	GPIO_FN(MEMC_AD10),	GPIO_FN(MEMC_AD11),
-	GPIO_FN(MEMC_AD12),	GPIO_FN(MEMC_AD13),	GPIO_FN(MEMC_AD14),
-	GPIO_FN(MEMC_AD15),
-
-	/* SIM */
-	GPIO_FN(SIM_RST),	GPIO_FN(SIM_CLK),	GPIO_FN(SIM_D),
-
-	/* TPU */
-	GPIO_FN(TPU0TO0),	GPIO_FN(TPU0TO1),	GPIO_FN(TPU0TO2_93),
-	GPIO_FN(TPU0TO2_99),	GPIO_FN(TPU0TO3),
-
-	/* I2C2 */
-	GPIO_FN(I2C_SCL2),	GPIO_FN(I2C_SDA2),
-
-	/* I2C3(1) */
-	GPIO_FN(I2C_SCL3),	GPIO_FN(I2C_SDA3),
-
-	/* I2C3(2) */
-	GPIO_FN(I2C_SCL3S),	GPIO_FN(I2C_SDA3S),
-
-	/* I2C4(2) */
-	GPIO_FN(I2C_SCL4),	GPIO_FN(I2C_SDA4),
-
-	/* I2C4(2) */
-	GPIO_FN(I2C_SCL4S),	GPIO_FN(I2C_SDA4S),
-
-	/* KEYSC */
-	GPIO_FN(KEYOUT0),	GPIO_FN(KEYIN0_121),	GPIO_FN(KEYIN0_136),
-	GPIO_FN(KEYOUT1),	GPIO_FN(KEYIN1_122),	GPIO_FN(KEYIN1_135),
-	GPIO_FN(KEYOUT2),	GPIO_FN(KEYIN2_123),	GPIO_FN(KEYIN2_134),
-	GPIO_FN(KEYOUT3),	GPIO_FN(KEYIN3_124),	GPIO_FN(KEYIN3_133),
-	GPIO_FN(KEYOUT4),	GPIO_FN(KEYIN4),	GPIO_FN(KEYOUT5),
-	GPIO_FN(KEYIN5),	GPIO_FN(KEYOUT6),	GPIO_FN(KEYIN6),
-	GPIO_FN(KEYOUT7),	GPIO_FN(KEYIN7),
-
-	/* LCDC */
-	GPIO_FN(LCDHSYN),	GPIO_FN(LCDCS),	GPIO_FN(LCDVSYN),
-	GPIO_FN(LCDDCK),	GPIO_FN(LCDWR),	GPIO_FN(LCDRD),
-	GPIO_FN(LCDDISP),	GPIO_FN(LCDRS),	GPIO_FN(LCDLCLK),
-	GPIO_FN(LCDDON),
-
-	GPIO_FN(LCDD0),		GPIO_FN(LCDD1),		GPIO_FN(LCDD2),
-	GPIO_FN(LCDD3),		GPIO_FN(LCDD4),		GPIO_FN(LCDD5),
-	GPIO_FN(LCDD6),		GPIO_FN(LCDD7),		GPIO_FN(LCDD8),
-	GPIO_FN(LCDD9),		GPIO_FN(LCDD10),	GPIO_FN(LCDD11),
-	GPIO_FN(LCDD12),	GPIO_FN(LCDD13),	GPIO_FN(LCDD14),
-	GPIO_FN(LCDD15),	GPIO_FN(LCDD16),	GPIO_FN(LCDD17),
-	GPIO_FN(LCDD18),	GPIO_FN(LCDD19),	GPIO_FN(LCDD20),
-	GPIO_FN(LCDD21),	GPIO_FN(LCDD22),	GPIO_FN(LCDD23),
-
-	GPIO_FN(LCDC0_SELECT),
-	GPIO_FN(LCDC1_SELECT),
-
-	/* IRDA */
-	GPIO_FN(IRDA_OUT),	GPIO_FN(IRDA_IN),	GPIO_FN(IRDA_FIRSEL),
-	GPIO_FN(IROUT_139),	GPIO_FN(IROUT_140),
-
-	/* TSIF1 */
-	GPIO_FN(TS0_1SELECT),
-	GPIO_FN(TS0_2SELECT),
-	GPIO_FN(TS1_1SELECT),
-	GPIO_FN(TS1_2SELECT),
-
-	GPIO_FN(TS_SPSYNC1),	GPIO_FN(TS_SDAT1),
-	GPIO_FN(TS_SDEN1),	GPIO_FN(TS_SCK1),
-
-	/* TSIF2 */
-	GPIO_FN(TS_SPSYNC2),	GPIO_FN(TS_SDAT2),
-	GPIO_FN(TS_SDEN2),	GPIO_FN(TS_SCK2),
-
-	/* HDMI */
-	GPIO_FN(HDMI_HPD),	GPIO_FN(HDMI_CEC),
-
-	/* SDENC */
-	GPIO_FN(SDENC_CPG),
-	GPIO_FN(SDENC_DV_CLKI),
-};
+#undef PORTCR
+#define PORTCR(nr, reg)							\
+	{								\
+		PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) {		\
+			_PCRH(PORT##nr##_IN, 0, 0, PORT##nr##_OUT),     \
+				PORT##nr##_FN0, PORT##nr##_FN1,		\
+				PORT##nr##_FN2, PORT##nr##_FN3,		\
+				PORT##nr##_FN4, PORT##nr##_FN5,		\
+				PORT##nr##_FN6, PORT##nr##_FN7 }	\
+	}
 
 static const struct pinmux_cfg_reg pinmux_config_regs[] = {
 	PORTCR(0,	0xE6051000), /* PORT0CR */
@@ -1776,45 +2546,114 @@ static const struct pinmux_data_reg pinm
 #define EXT_IRQ16L(n) evt2irq(0x200 + ((n) << 5))
 #define EXT_IRQ16H(n) evt2irq(0x3200 + (((n) - 16) << 5))
 static const struct pinmux_irq pinmux_irqs[] = {
-	PINMUX_IRQ(EXT_IRQ16L(0), GPIO_PORT6, GPIO_PORT162),
-	PINMUX_IRQ(EXT_IRQ16L(1), GPIO_PORT12),
-	PINMUX_IRQ(EXT_IRQ16L(2), GPIO_PORT4, GPIO_PORT5),
-	PINMUX_IRQ(EXT_IRQ16L(3), GPIO_PORT8, GPIO_PORT16),
-	PINMUX_IRQ(EXT_IRQ16L(4), GPIO_PORT17, GPIO_PORT163),
-	PINMUX_IRQ(EXT_IRQ16L(5), GPIO_PORT18),
-	PINMUX_IRQ(EXT_IRQ16L(6), GPIO_PORT39, GPIO_PORT164),
-	PINMUX_IRQ(EXT_IRQ16L(7), GPIO_PORT40, GPIO_PORT167),
-	PINMUX_IRQ(EXT_IRQ16L(8), GPIO_PORT41, GPIO_PORT168),
-	PINMUX_IRQ(EXT_IRQ16L(9), GPIO_PORT42, GPIO_PORT169),
-	PINMUX_IRQ(EXT_IRQ16L(10), GPIO_PORT65),
-	PINMUX_IRQ(EXT_IRQ16L(11), GPIO_PORT67),
-	PINMUX_IRQ(EXT_IRQ16L(12), GPIO_PORT80, GPIO_PORT137),
-	PINMUX_IRQ(EXT_IRQ16L(13), GPIO_PORT81, GPIO_PORT145),
-	PINMUX_IRQ(EXT_IRQ16L(14), GPIO_PORT82, GPIO_PORT146),
-	PINMUX_IRQ(EXT_IRQ16L(15), GPIO_PORT83, GPIO_PORT147),
-	PINMUX_IRQ(EXT_IRQ16H(16), GPIO_PORT84, GPIO_PORT170),
-	PINMUX_IRQ(EXT_IRQ16H(17), GPIO_PORT85),
-	PINMUX_IRQ(EXT_IRQ16H(18), GPIO_PORT86),
-	PINMUX_IRQ(EXT_IRQ16H(19), GPIO_PORT87),
-	PINMUX_IRQ(EXT_IRQ16H(20), GPIO_PORT92),
-	PINMUX_IRQ(EXT_IRQ16H(21), GPIO_PORT93),
-	PINMUX_IRQ(EXT_IRQ16H(22), GPIO_PORT94),
-	PINMUX_IRQ(EXT_IRQ16H(23), GPIO_PORT95),
-	PINMUX_IRQ(EXT_IRQ16H(24), GPIO_PORT112),
-	PINMUX_IRQ(EXT_IRQ16H(25), GPIO_PORT119),
-	PINMUX_IRQ(EXT_IRQ16H(26), GPIO_PORT121, GPIO_PORT172),
-	PINMUX_IRQ(EXT_IRQ16H(27), GPIO_PORT122, GPIO_PORT180),
-	PINMUX_IRQ(EXT_IRQ16H(28), GPIO_PORT123, GPIO_PORT181),
-	PINMUX_IRQ(EXT_IRQ16H(29), GPIO_PORT129, GPIO_PORT182),
-	PINMUX_IRQ(EXT_IRQ16H(30), GPIO_PORT130, GPIO_PORT183),
-	PINMUX_IRQ(EXT_IRQ16H(31), GPIO_PORT138, GPIO_PORT184),
+	PINMUX_IRQ(EXT_IRQ16L(0), 6, 162),
+	PINMUX_IRQ(EXT_IRQ16L(1), 12),
+	PINMUX_IRQ(EXT_IRQ16L(2), 4, 5),
+	PINMUX_IRQ(EXT_IRQ16L(3), 8, 16),
+	PINMUX_IRQ(EXT_IRQ16L(4), 17, 163),
+	PINMUX_IRQ(EXT_IRQ16L(5), 18),
+	PINMUX_IRQ(EXT_IRQ16L(6), 39, 164),
+	PINMUX_IRQ(EXT_IRQ16L(7), 40, 167),
+	PINMUX_IRQ(EXT_IRQ16L(8), 41, 168),
+	PINMUX_IRQ(EXT_IRQ16L(9), 42, 169),
+	PINMUX_IRQ(EXT_IRQ16L(10), 65),
+	PINMUX_IRQ(EXT_IRQ16L(11), 67),
+	PINMUX_IRQ(EXT_IRQ16L(12), 80, 137),
+	PINMUX_IRQ(EXT_IRQ16L(13), 81, 145),
+	PINMUX_IRQ(EXT_IRQ16L(14), 82, 146),
+	PINMUX_IRQ(EXT_IRQ16L(15), 83, 147),
+	PINMUX_IRQ(EXT_IRQ16H(16), 84, 170),
+	PINMUX_IRQ(EXT_IRQ16H(17), 85),
+	PINMUX_IRQ(EXT_IRQ16H(18), 86),
+	PINMUX_IRQ(EXT_IRQ16H(19), 87),
+	PINMUX_IRQ(EXT_IRQ16H(20), 92),
+	PINMUX_IRQ(EXT_IRQ16H(21), 93),
+	PINMUX_IRQ(EXT_IRQ16H(22), 94),
+	PINMUX_IRQ(EXT_IRQ16H(23), 95),
+	PINMUX_IRQ(EXT_IRQ16H(24), 112),
+	PINMUX_IRQ(EXT_IRQ16H(25), 119),
+	PINMUX_IRQ(EXT_IRQ16H(26), 121, 172),
+	PINMUX_IRQ(EXT_IRQ16H(27), 122, 180),
+	PINMUX_IRQ(EXT_IRQ16H(28), 123, 181),
+	PINMUX_IRQ(EXT_IRQ16H(29), 129, 182),
+	PINMUX_IRQ(EXT_IRQ16H(30), 130, 183),
+	PINMUX_IRQ(EXT_IRQ16H(31), 138, 184),
+};
+
+#define PORTnCR_PULMD_OFF	(0 << 6)
+#define PORTnCR_PULMD_DOWN	(2 << 6)
+#define PORTnCR_PULMD_UP	(3 << 6)
+#define PORTnCR_PULMD_MASK	(3 << 6)
+
+struct sh7372_portcr_group {
+	unsigned int end_pin;
+	unsigned int offset;
+};
+
+static const struct sh7372_portcr_group sh7372_portcr_offsets[] = {
+	{ 45,  0x1000 }, { 75,  0x2000 }, { 99,  0x0000 }, { 120, 0x3000 },
+	{ 151, 0x0000 }, { 155, 0x3000 }, { 166, 0x0000 }, { 190, 0x2000 },
+};
+
+static void __iomem *sh7372_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(sh7372_portcr_offsets); ++i) {
+		const struct sh7372_portcr_group *group =
+			&sh7372_portcr_offsets[i];
+
+		if (i <= group->end_pin)
+			return pfc->window->virt + group->offset + pin;
+	}
+
+	return NULL;
+}
+
+static unsigned int sh7372_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin)
+{
+	void __iomem *addr = sh7372_pinmux_portcr(pfc, pin);
+	u32 value = ioread8(addr) & PORTnCR_PULMD_MASK;
+
+	switch (value) {
+	case PORTnCR_PULMD_UP:
+		return PIN_CONFIG_BIAS_PULL_UP;
+	case PORTnCR_PULMD_DOWN:
+		return PIN_CONFIG_BIAS_PULL_DOWN;
+	case PORTnCR_PULMD_OFF:
+	default:
+		return PIN_CONFIG_BIAS_DISABLE;
+	}
+}
+
+static void sh7372_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin,
+				   unsigned int bias)
+{
+	void __iomem *addr = sh7372_pinmux_portcr(pfc, pin);
+	u32 value = ioread8(addr) & ~PORTnCR_PULMD_MASK;
+
+	switch (bias) {
+	case PIN_CONFIG_BIAS_PULL_UP:
+		value |= PORTnCR_PULMD_UP;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		value |= PORTnCR_PULMD_DOWN;
+		break;
+	}
+
+	iowrite8(value, addr);
+}
+
+static const struct sh_pfc_soc_operations sh7372_pinmux_ops = {
+	.get_bias = sh7372_pinmux_get_bias,
+	.set_bias = sh7372_pinmux_set_bias,
 };
 
 const struct sh_pfc_soc_info sh7372_pinmux_info = {
 	.name = "sh7372_pfc",
+	.ops = &sh7372_pinmux_ops,
+
 	.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
-	.input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
-	.input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
 	.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
 	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
 
@@ -1825,9 +2664,6 @@ const struct sh_pfc_soc_info sh7372_pinm
 	.functions = pinmux_functions,
 	.nr_functions = ARRAY_SIZE(pinmux_functions),
 
-	.func_gpios = pinmux_func_gpios,
-	.nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios),
-
 	.cfg_regs = pinmux_config_regs,
 	.data_regs = pinmux_data_regs,
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-sh73a0.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-sh73a0.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pfc-sh73a0.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pfc-sh73a0.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,9 +20,12 @@
  */
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pinctrl/pinconf-generic.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/slab.h>
 
-#include <mach/sh73a0.h>
 #include <mach/irqs.h>
 
 #include "core.h"
@@ -2538,6 +2541,157 @@ static const unsigned int sdhi2_ctrl_pin
 static const unsigned int sdhi2_ctrl_mux[] = {
 	SDHICMD2_MARK, SDHICLK2_MARK,
 };
+/* - TPU0 ------------------------------------------------------------------- */
+static const unsigned int tpu0_to0_pins[] = {
+	/* TO */
+	55,
+};
+static const unsigned int tpu0_to0_mux[] = {
+	TPU0TO0_MARK,
+};
+static const unsigned int tpu0_to1_pins[] = {
+	/* TO */
+	59,
+};
+static const unsigned int tpu0_to1_mux[] = {
+	TPU0TO1_MARK,
+};
+static const unsigned int tpu0_to2_pins[] = {
+	/* TO */
+	140,
+};
+static const unsigned int tpu0_to2_mux[] = {
+	TPU0TO2_MARK,
+};
+static const unsigned int tpu0_to3_pins[] = {
+	/* TO */
+	141,
+};
+static const unsigned int tpu0_to3_mux[] = {
+	TPU0TO3_MARK,
+};
+/* - TPU1 ------------------------------------------------------------------- */
+static const unsigned int tpu1_to0_pins[] = {
+	/* TO */
+	246,
+};
+static const unsigned int tpu1_to0_mux[] = {
+	TPU1TO0_MARK,
+};
+static const unsigned int tpu1_to1_0_pins[] = {
+	/* TO */
+	28,
+};
+static const unsigned int tpu1_to1_0_mux[] = {
+	PORT28_TPU1TO1_MARK,
+};
+static const unsigned int tpu1_to1_1_pins[] = {
+	/* TO */
+	29,
+};
+static const unsigned int tpu1_to1_1_mux[] = {
+	PORT29_TPU1TO1_MARK,
+};
+static const unsigned int tpu1_to2_pins[] = {
+	/* TO */
+	153,
+};
+static const unsigned int tpu1_to2_mux[] = {
+	TPU1TO2_MARK,
+};
+static const unsigned int tpu1_to3_pins[] = {
+	/* TO */
+	145,
+};
+static const unsigned int tpu1_to3_mux[] = {
+	TPU1TO3_MARK,
+};
+/* - TPU2 ------------------------------------------------------------------- */
+static const unsigned int tpu2_to0_pins[] = {
+	/* TO */
+	248,
+};
+static const unsigned int tpu2_to0_mux[] = {
+	TPU2TO0_MARK,
+};
+static const unsigned int tpu2_to1_pins[] = {
+	/* TO */
+	197,
+};
+static const unsigned int tpu2_to1_mux[] = {
+	TPU2TO1_MARK,
+};
+static const unsigned int tpu2_to2_pins[] = {
+	/* TO */
+	50,
+};
+static const unsigned int tpu2_to2_mux[] = {
+	TPU2TO2_MARK,
+};
+static const unsigned int tpu2_to3_pins[] = {
+	/* TO */
+	51,
+};
+static const unsigned int tpu2_to3_mux[] = {
+	TPU2TO3_MARK,
+};
+/* - TPU3 ------------------------------------------------------------------- */
+static const unsigned int tpu3_to0_pins[] = {
+	/* TO */
+	163,
+};
+static const unsigned int tpu3_to0_mux[] = {
+	TPU3TO0_MARK,
+};
+static const unsigned int tpu3_to1_pins[] = {
+	/* TO */
+	247,
+};
+static const unsigned int tpu3_to1_mux[] = {
+	TPU3TO1_MARK,
+};
+static const unsigned int tpu3_to2_pins[] = {
+	/* TO */
+	54,
+};
+static const unsigned int tpu3_to2_mux[] = {
+	TPU3TO2_MARK,
+};
+static const unsigned int tpu3_to3_pins[] = {
+	/* TO */
+	53,
+};
+static const unsigned int tpu3_to3_mux[] = {
+	TPU3TO3_MARK,
+};
+/* - TPU4 ------------------------------------------------------------------- */
+static const unsigned int tpu4_to0_pins[] = {
+	/* TO */
+	241,
+};
+static const unsigned int tpu4_to0_mux[] = {
+	TPU4TO0_MARK,
+};
+static const unsigned int tpu4_to1_pins[] = {
+	/* TO */
+	199,
+};
+static const unsigned int tpu4_to1_mux[] = {
+	TPU4TO1_MARK,
+};
+static const unsigned int tpu4_to2_pins[] = {
+	/* TO */
+	58,
+};
+static const unsigned int tpu4_to2_mux[] = {
+	TPU4TO2_MARK,
+};
+static const unsigned int tpu4_to3_pins[] = {
+	/* TO */
+};
+static const unsigned int tpu4_to3_mux[] = {
+	TPU4TO3_MARK,
+};
 /* - USB -------------------------------------------------------------------- */
 static const unsigned int usb_vbus_pins[] = {
 	/* VBUS */
@@ -2689,6 +2843,27 @@ static const struct sh_pfc_pin_group pin
 	SH_PFC_PIN_GROUP(sdhi2_data1),
 	SH_PFC_PIN_GROUP(sdhi2_data4),
 	SH_PFC_PIN_GROUP(sdhi2_ctrl),
+	SH_PFC_PIN_GROUP(tpu0_to0),
+	SH_PFC_PIN_GROUP(tpu0_to1),
+	SH_PFC_PIN_GROUP(tpu0_to2),
+	SH_PFC_PIN_GROUP(tpu0_to3),
+	SH_PFC_PIN_GROUP(tpu1_to0),
+	SH_PFC_PIN_GROUP(tpu1_to1_0),
+	SH_PFC_PIN_GROUP(tpu1_to1_1),
+	SH_PFC_PIN_GROUP(tpu1_to2),
+	SH_PFC_PIN_GROUP(tpu1_to3),
+	SH_PFC_PIN_GROUP(tpu2_to0),
+	SH_PFC_PIN_GROUP(tpu2_to1),
+	SH_PFC_PIN_GROUP(tpu2_to2),
+	SH_PFC_PIN_GROUP(tpu2_to3),
+	SH_PFC_PIN_GROUP(tpu3_to0),
+	SH_PFC_PIN_GROUP(tpu3_to1),
+	SH_PFC_PIN_GROUP(tpu3_to2),
+	SH_PFC_PIN_GROUP(tpu3_to3),
+	SH_PFC_PIN_GROUP(tpu4_to0),
+	SH_PFC_PIN_GROUP(tpu4_to1),
+	SH_PFC_PIN_GROUP(tpu4_to2),
+	SH_PFC_PIN_GROUP(tpu4_to3),
 	SH_PFC_PIN_GROUP(usb_vbus),
 };
 
@@ -2908,6 +3083,42 @@ static const char * const usb_groups[] =
 	"usb_vbus",
 };
 
+static const char * const tpu0_groups[] = {
+	"tpu0_to0",
+	"tpu0_to1",
+	"tpu0_to2",
+	"tpu0_to3",
+};
+
+static const char * const tpu1_groups[] = {
+	"tpu1_to0",
+	"tpu1_to1_0",
+	"tpu1_to1_1",
+	"tpu1_to2",
+	"tpu1_to3",
+};
+
+static const char * const tpu2_groups[] = {
+	"tpu2_to0",
+	"tpu2_to1",
+	"tpu2_to2",
+	"tpu2_to3",
+};
+
+static const char * const tpu3_groups[] = {
+	"tpu3_to0",
+	"tpu3_to1",
+	"tpu3_to2",
+	"tpu3_to3",
+};
+
+static const char * const tpu4_groups[] = {
+	"tpu4_to0",
+	"tpu4_to1",
+	"tpu4_to2",
+	"tpu4_to3",
+};
+
 static const struct sh_pfc_function pinmux_functions[] = {
 	SH_PFC_FUNCTION(bsc),
 	SH_PFC_FUNCTION(fsia),
@@ -2933,400 +3144,14 @@ static const struct sh_pfc_function pinm
 	SH_PFC_FUNCTION(sdhi0),
 	SH_PFC_FUNCTION(sdhi1),
 	SH_PFC_FUNCTION(sdhi2),
+	SH_PFC_FUNCTION(tpu0),
+	SH_PFC_FUNCTION(tpu1),
+	SH_PFC_FUNCTION(tpu2),
+	SH_PFC_FUNCTION(tpu3),
+	SH_PFC_FUNCTION(tpu4),
 	SH_PFC_FUNCTION(usb),
 };
 
-#define PINMUX_FN_BASE	GPIO_FN_GPI0
-
-static const struct pinmux_func pinmux_func_gpios[] = {
-	/* Table 25-1 (Functions 0-7) */
-	GPIO_FN(GPI0),
-	GPIO_FN(GPI1),
-	GPIO_FN(GPI2),
-	GPIO_FN(GPI3),
-	GPIO_FN(GPI4),
-	GPIO_FN(GPI5),
-	GPIO_FN(GPI6),
-	GPIO_FN(GPI7),
-	GPIO_FN(GPO7), \
-	GPIO_FN(MFG0_OUT2),
-	GPIO_FN(GPO6), \
-	GPIO_FN(MFG1_OUT2),
-	GPIO_FN(GPO5), \
-	GPIO_FN(PORT16_VIO_CKOR),
-	GPIO_FN(PORT19_VIO_CKO2),
-	GPIO_FN(GPO0),
-	GPIO_FN(GPO1),
-	GPIO_FN(GPO2), \
-	GPIO_FN(STATUS0),
-	GPIO_FN(GPO3), \
-	GPIO_FN(STATUS1),
-	GPIO_FN(GPO4), \
-	GPIO_FN(STATUS2),
-	GPIO_FN(VINT),
-	GPIO_FN(TCKON),
-	GPIO_FN(XDVFS1), \
-	GPIO_FN(MFG0_OUT1), \
-	GPIO_FN(PORT27_IROUT),
-	GPIO_FN(XDVFS2), \
-	GPIO_FN(PORT28_TPU1TO1),
-	GPIO_FN(SIM_RST), \
-	GPIO_FN(PORT29_TPU1TO1),
-	GPIO_FN(SIM_CLK), \
-	GPIO_FN(PORT30_VIO_CKOR),
-	GPIO_FN(SIM_D), \
-	GPIO_FN(PORT31_IROUT),
-	GPIO_FN(XWUP),
-	GPIO_FN(VACK),
-	GPIO_FN(XTAL1L),
-	GPIO_FN(PORT49_IROUT), \
-	GPIO_FN(BBIF2_TSYNC2), \
-	GPIO_FN(TPU2TO2), \
-
-	GPIO_FN(BBIF2_TSCK2), \
-	GPIO_FN(TPU2TO3), \
-	GPIO_FN(BBIF2_TXD2),
-	GPIO_FN(TPU3TO3), \
-	GPIO_FN(TPU3TO2), \
-	GPIO_FN(TPU0TO0),
-	GPIO_FN(A0), \
-	GPIO_FN(BS_),
-	GPIO_FN(A12), \
-	GPIO_FN(TPU4TO2),
-	GPIO_FN(A13), \
-	GPIO_FN(TPU0TO1),
-	GPIO_FN(A14), \
-	GPIO_FN(A15), \
-	GPIO_FN(A16), \
-	GPIO_FN(MSIOF0_SS1),
-	GPIO_FN(A17), \
-	GPIO_FN(MSIOF0_TSYNC),
-	GPIO_FN(A18), \
-	GPIO_FN(MSIOF0_TSCK),
-	GPIO_FN(A19), \
-	GPIO_FN(MSIOF0_TXD),
-	GPIO_FN(A20), \
-	GPIO_FN(MSIOF0_RSCK),
-	GPIO_FN(A21), \
-	GPIO_FN(MSIOF0_RSYNC),
-	GPIO_FN(A22), \
-	GPIO_FN(MSIOF0_MCK0),
-	GPIO_FN(A23), \
-	GPIO_FN(MSIOF0_MCK1),
-	GPIO_FN(A24), \
-	GPIO_FN(MSIOF0_RXD),
-	GPIO_FN(A25), \
-	GPIO_FN(MSIOF0_SS2),
-	GPIO_FN(A26), \
-	GPIO_FN(FCE1_),
-	GPIO_FN(DACK0),
-	GPIO_FN(FCE0_), \
-	GPIO_FN(WAIT_), \
-	GPIO_FN(DREQ0),
-	GPIO_FN(FRB),
-	GPIO_FN(CKO),
-	GPIO_FN(NBRSTOUT_),
-	GPIO_FN(NBRST_),
-	GPIO_FN(BBIF2_TXD),
-	GPIO_FN(BBIF2_RXD),
-	GPIO_FN(BBIF2_SYNC),
-	GPIO_FN(BBIF2_SCK),
-	GPIO_FN(MFG3_IN2),
-	GPIO_FN(MFG3_IN1),
-	GPIO_FN(BBIF1_SS2), \
-	GPIO_FN(MFG3_OUT1),
-	GPIO_FN(HSI_RX_DATA), \
-	GPIO_FN(BBIF1_RXD),
-	GPIO_FN(HSI_TX_WAKE), \
-	GPIO_FN(BBIF1_TSCK),
-	GPIO_FN(HSI_TX_DATA), \
-	GPIO_FN(BBIF1_TSYNC),
-	GPIO_FN(HSI_TX_READY), \
-	GPIO_FN(BBIF1_TXD),
-	GPIO_FN(HSI_RX_READY), \
-	GPIO_FN(BBIF1_RSCK), \
-	GPIO_FN(HSI_RX_WAKE), \
-	GPIO_FN(BBIF1_RSYNC), \
-	GPIO_FN(HSI_RX_FLAG), \
-	GPIO_FN(BBIF1_SS1), \
-	GPIO_FN(BBIF1_FLOW),
-	GPIO_FN(HSI_TX_FLAG),
-	GPIO_FN(VIO_VD), \
-	GPIO_FN(VIO2_VD), \
-
-	GPIO_FN(VIO_HD), \
-	GPIO_FN(VIO2_HD), \
-	GPIO_FN(VIO_D0), \
-	GPIO_FN(PORT130_MSIOF2_RXD), \
-	GPIO_FN(VIO_D1), \
-	GPIO_FN(PORT131_MSIOF2_SS1), \
-	GPIO_FN(VIO_D2), \
-	GPIO_FN(PORT132_MSIOF2_SS2), \
-	GPIO_FN(VIO_D3), \
-	GPIO_FN(MSIOF2_TSYNC), \
-	GPIO_FN(VIO_D4), \
-	GPIO_FN(MSIOF2_TXD), \
-	GPIO_FN(VIO_D5), \
-	GPIO_FN(MSIOF2_TSCK), \
-	GPIO_FN(VIO_D6), \
-	GPIO_FN(VIO_D7), \
-	GPIO_FN(VIO_D8), \
-	GPIO_FN(VIO2_D0), \
-	GPIO_FN(VIO_D9), \
-	GPIO_FN(VIO2_D1), \
-	GPIO_FN(VIO_D10), \
-	GPIO_FN(TPU0TO2), \
-	GPIO_FN(VIO2_D2), \
-	GPIO_FN(VIO_D11), \
-	GPIO_FN(TPU0TO3), \
-	GPIO_FN(VIO2_D3), \
-	GPIO_FN(VIO_D12), \
-	GPIO_FN(VIO2_D4), \
-	GPIO_FN(VIO_D13), \
-	GPIO_FN(VIO2_D5), \
-	GPIO_FN(VIO_D14), \
-	GPIO_FN(VIO2_D6), \
-	GPIO_FN(VIO_D15), \
-	GPIO_FN(TPU1TO3), \
-	GPIO_FN(VIO2_D7), \
-	GPIO_FN(VIO_CLK), \
-	GPIO_FN(VIO2_CLK), \
-	GPIO_FN(VIO_FIELD), \
-	GPIO_FN(VIO2_FIELD), \
-	GPIO_FN(VIO_CKO),
-	GPIO_FN(A27), \
-	GPIO_FN(MFG0_IN1), \
-	GPIO_FN(MFG0_IN2),
-	GPIO_FN(TS_SPSYNC3), \
-	GPIO_FN(MSIOF2_RSCK),
-	GPIO_FN(TS_SDAT3), \
-	GPIO_FN(MSIOF2_RSYNC),
-	GPIO_FN(TPU1TO2), \
-	GPIO_FN(TS_SDEN3), \
-	GPIO_FN(PORT153_MSIOF2_SS1),
-	GPIO_FN(MSIOF2_MCK0),
-	GPIO_FN(MSIOF2_MCK1),
-	GPIO_FN(PORT156_MSIOF2_SS2),
-	GPIO_FN(PORT157_MSIOF2_RXD),
-	GPIO_FN(DINT_), \
-	GPIO_FN(TS_SCK3),
-	GPIO_FN(NMI),
-	GPIO_FN(TPU3TO0),
-	GPIO_FN(BBIF2_TSYNC1),
-	GPIO_FN(BBIF2_TSCK1),
-	GPIO_FN(BBIF2_TXD1),
-	GPIO_FN(MFG2_OUT2), \
-	GPIO_FN(TPU2TO1),
-	GPIO_FN(TPU4TO1), \
-	GPIO_FN(MFG4_OUT2),
-	GPIO_FN(D16),
-	GPIO_FN(D17),
-	GPIO_FN(D18),
-	GPIO_FN(D19),
-	GPIO_FN(D20),
-	GPIO_FN(D21),
-	GPIO_FN(D22),
-	GPIO_FN(PORT207_MSIOF0L_SS1), \
-	GPIO_FN(D23),
-	GPIO_FN(PORT208_MSIOF0L_SS2), \
-	GPIO_FN(D24),
-	GPIO_FN(D25),
-	GPIO_FN(DREQ2), \
-	GPIO_FN(PORT210_MSIOF0L_SS1), \
-	GPIO_FN(D26),
-	GPIO_FN(PORT211_MSIOF0L_SS2), \
-	GPIO_FN(D27),
-	GPIO_FN(TS_SPSYNC1), \
-	GPIO_FN(MSIOF0L_MCK0), \
-	GPIO_FN(D28),
-	GPIO_FN(TS_SDAT1), \
-	GPIO_FN(MSIOF0L_MCK1), \
-	GPIO_FN(D29),
-	GPIO_FN(TS_SDEN1), \
-	GPIO_FN(MSIOF0L_RSCK), \
-	GPIO_FN(D30),
-	GPIO_FN(TS_SCK1), \
-	GPIO_FN(MSIOF0L_RSYNC), \
-	GPIO_FN(D31),
-	GPIO_FN(DACK2), \
-	GPIO_FN(MSIOF0L_TSYNC), \
-	GPIO_FN(VIO2_FIELD3), \
-	GPIO_FN(DACK3), \
-	GPIO_FN(PORT218_VIO_CKOR),
-	GPIO_FN(DREQ3), \
-	GPIO_FN(MSIOF0L_TSCK), \
-	GPIO_FN(VIO2_CLK3), \
-	GPIO_FN(DREQ1), \
-	GPIO_FN(PWEN), \
-	GPIO_FN(MSIOF0L_RXD), \
-	GPIO_FN(VIO2_HD3), \
-	GPIO_FN(DACK1), \
-	GPIO_FN(OVCN), \
-	GPIO_FN(MSIOF0L_TXD), \
-	GPIO_FN(VIO2_VD3), \
-
-	GPIO_FN(OVCN2),
-	GPIO_FN(EXTLP), \
-	GPIO_FN(PORT226_VIO_CKO2),
-	GPIO_FN(IDIN),
-	GPIO_FN(MFG1_IN1),
-	GPIO_FN(MSIOF1_TXD), \
-	GPIO_FN(MSIOF1_TSYNC), \
-	GPIO_FN(MSIOF1_TSCK), \
-	GPIO_FN(MSIOF1_RXD), \
-	GPIO_FN(MSIOF1_RSCK), \
-	GPIO_FN(VIO2_CLK2), \
-	GPIO_FN(MSIOF1_RSYNC), \
-	GPIO_FN(MFG1_IN2), \
-	GPIO_FN(VIO2_VD2), \
-	GPIO_FN(MSIOF1_MCK0), \
-	GPIO_FN(MSIOF1_MCK1), \
-	GPIO_FN(MSIOF1_SS1), \
-	GPIO_FN(VIO2_FIELD2), \
-	GPIO_FN(MSIOF1_SS2), \
-	GPIO_FN(VIO2_HD2), \
-	GPIO_FN(PORT241_IROUT), \
-	GPIO_FN(MFG4_OUT1), \
-	GPIO_FN(TPU4TO0),
-	GPIO_FN(MFG4_IN2),
-	GPIO_FN(PORT243_VIO_CKO2),
-	GPIO_FN(MFG2_IN1), \
-	GPIO_FN(MSIOF2R_RXD),
-	GPIO_FN(MFG2_IN2), \
-	GPIO_FN(MSIOF2R_TXD),
-	GPIO_FN(MFG1_OUT1), \
-	GPIO_FN(TPU1TO0),
-	GPIO_FN(MFG3_OUT2), \
-	GPIO_FN(TPU3TO1),
-	GPIO_FN(MFG2_OUT1), \
-	GPIO_FN(TPU2TO0), \
-	GPIO_FN(MSIOF2R_TSCK),
-	GPIO_FN(PORT249_IROUT), \
-	GPIO_FN(MFG4_IN1), \
-	GPIO_FN(MSIOF2R_TSYNC),
-	GPIO_FN(SDHICLK0),
-	GPIO_FN(SDHICD0),
-	GPIO_FN(SDHID0_0),
-	GPIO_FN(SDHID0_1),
-	GPIO_FN(SDHID0_2),
-	GPIO_FN(SDHID0_3),
-	GPIO_FN(SDHICMD0),
-	GPIO_FN(SDHIWP0),
-	GPIO_FN(SDHICLK1),
-	GPIO_FN(SDHID1_0), \
-	GPIO_FN(TS_SPSYNC2),
-	GPIO_FN(SDHID1_1), \
-	GPIO_FN(TS_SDAT2),
-	GPIO_FN(SDHID1_2), \
-	GPIO_FN(TS_SDEN2),
-	GPIO_FN(SDHID1_3), \
-	GPIO_FN(TS_SCK2),
-	GPIO_FN(SDHICMD1),
-	GPIO_FN(SDHICLK2),
-	GPIO_FN(SDHID2_0), \
-	GPIO_FN(TS_SPSYNC4),
-	GPIO_FN(SDHID2_1), \
-	GPIO_FN(TS_SDAT4),
-	GPIO_FN(SDHID2_2), \
-	GPIO_FN(TS_SDEN4),
-	GPIO_FN(SDHID2_3), \
-	GPIO_FN(TS_SCK4),
-	GPIO_FN(SDHICMD2),
-	GPIO_FN(MMCCLK0),
-	GPIO_FN(MMCD0_0),
-	GPIO_FN(MMCD0_1),
-	GPIO_FN(MMCD0_2),
-	GPIO_FN(MMCD0_3),
-	GPIO_FN(MMCD0_4), \
-	GPIO_FN(TS_SPSYNC5),
-	GPIO_FN(MMCD0_5), \
-	GPIO_FN(TS_SDAT5),
-	GPIO_FN(MMCD0_6), \
-	GPIO_FN(TS_SDEN5),
-	GPIO_FN(MMCD0_7), \
-	GPIO_FN(TS_SCK5),
-	GPIO_FN(MMCCMD0),
-	GPIO_FN(RESETOUTS_), \
-	GPIO_FN(EXTAL2OUT),
-	GPIO_FN(MCP_WAIT__MCP_FRB),
-	GPIO_FN(MCP_CKO), \
-	GPIO_FN(MMCCLK1),
-	GPIO_FN(MCP_D15_MCP_NAF15),
-	GPIO_FN(MCP_D14_MCP_NAF14),
-	GPIO_FN(MCP_D13_MCP_NAF13),
-	GPIO_FN(MCP_D12_MCP_NAF12),
-	GPIO_FN(MCP_D11_MCP_NAF11),
-	GPIO_FN(MCP_D10_MCP_NAF10),
-	GPIO_FN(MCP_D9_MCP_NAF9),
-	GPIO_FN(MCP_D8_MCP_NAF8), \
-	GPIO_FN(MMCCMD1),
-	GPIO_FN(MCP_D7_MCP_NAF7), \
-	GPIO_FN(MMCD1_7),
-
-	GPIO_FN(MCP_D6_MCP_NAF6), \
-	GPIO_FN(MMCD1_6),
-	GPIO_FN(MCP_D5_MCP_NAF5), \
-	GPIO_FN(MMCD1_5),
-	GPIO_FN(MCP_D4_MCP_NAF4), \
-	GPIO_FN(MMCD1_4),
-	GPIO_FN(MCP_D3_MCP_NAF3), \
-	GPIO_FN(MMCD1_3),
-	GPIO_FN(MCP_D2_MCP_NAF2), \
-	GPIO_FN(MMCD1_2),
-	GPIO_FN(MCP_D1_MCP_NAF1), \
-	GPIO_FN(MMCD1_1),
-	GPIO_FN(MCP_D0_MCP_NAF0), \
-	GPIO_FN(MMCD1_0),
-	GPIO_FN(MCP_NBRSTOUT_),
-	GPIO_FN(MCP_WE0__MCP_FWE), \
-	GPIO_FN(MCP_RDWR_MCP_FWE),
-
-	/* MSEL2 special cases */
-	GPIO_FN(TSIF2_TS_XX1),
-	GPIO_FN(TSIF2_TS_XX2),
-	GPIO_FN(TSIF2_TS_XX3),
-	GPIO_FN(TSIF2_TS_XX4),
-	GPIO_FN(TSIF2_TS_XX5),
-	GPIO_FN(TSIF1_TS_XX1),
-	GPIO_FN(TSIF1_TS_XX2),
-	GPIO_FN(TSIF1_TS_XX3),
-	GPIO_FN(TSIF1_TS_XX4),
-	GPIO_FN(TSIF1_TS_XX5),
-	GPIO_FN(TSIF0_TS_XX1),
-	GPIO_FN(TSIF0_TS_XX2),
-	GPIO_FN(TSIF0_TS_XX3),
-	GPIO_FN(TSIF0_TS_XX4),
-	GPIO_FN(TSIF0_TS_XX5),
-	GPIO_FN(MST1_TS_XX1),
-	GPIO_FN(MST1_TS_XX2),
-	GPIO_FN(MST1_TS_XX3),
-	GPIO_FN(MST1_TS_XX4),
-	GPIO_FN(MST1_TS_XX5),
-	GPIO_FN(MST0_TS_XX1),
-	GPIO_FN(MST0_TS_XX2),
-	GPIO_FN(MST0_TS_XX3),
-	GPIO_FN(MST0_TS_XX4),
-	GPIO_FN(MST0_TS_XX5),
-
-	/* MSEL3 special cases */
-	GPIO_FN(SDHI0_VCCQ_MC0_ON),
-	GPIO_FN(SDHI0_VCCQ_MC0_OFF),
-	GPIO_FN(DEBUG_MON_VIO),
-	GPIO_FN(DEBUG_MON_LCDD),
-	GPIO_FN(LCDC_LCDC0),
-	GPIO_FN(LCDC_LCDC1),
-
-	/* MSEL4 special cases */
-	GPIO_FN(IRQ9_MEM_INT),
-	GPIO_FN(IRQ9_MCP_INT),
-	GPIO_FN(A11),
-	GPIO_FN(TPU4TO3),
-	GPIO_FN(RESETA_N_PU_ON),
-	GPIO_FN(RESETA_N_PU_OFF),
-	GPIO_FN(EDBGREQ_PD),
-	GPIO_FN(EDBGREQ_PU),
-};
-
 #undef PORTCR
 #define PORTCR(nr, reg)							\
 	{								\
@@ -3888,6 +3713,93 @@ static const struct pinmux_irq pinmux_ir
 	PINMUX_IRQ(EXT_IRQ16L(9), 308),
 };
 
+/* -----------------------------------------------------------------------------
+ * VCCQ MC0 regulator
+ */
+
+static void sh73a0_vccq_mc0_endisable(struct regulator_dev *reg, bool enable)
+{
+	struct sh_pfc *pfc = reg->reg_data;
+	void __iomem *addr = pfc->window[1].virt + 4;
+	unsigned long flags;
+	u32 value;
+
+	spin_lock_irqsave(&pfc->lock, flags);
+
+	value = ioread32(addr);
+
+	if (enable)
+		value |= BIT(28);
+	else
+		value &= ~BIT(28);
+
+	iowrite32(value, addr);
+
+	spin_unlock_irqrestore(&pfc->lock, flags);
+}
+
+static int sh73a0_vccq_mc0_enable(struct regulator_dev *reg)
+{
+	sh73a0_vccq_mc0_endisable(reg, true);
+	return 0;
+}
+
+static int sh73a0_vccq_mc0_disable(struct regulator_dev *reg)
+{
+	sh73a0_vccq_mc0_endisable(reg, false);
+	return 0;
+}
+
+static int sh73a0_vccq_mc0_is_enabled(struct regulator_dev *reg)
+{
+	struct sh_pfc *pfc = reg->reg_data;
+	void __iomem *addr = pfc->window[1].virt + 4;
+	unsigned long flags;
+	u32 value;
+
+	spin_lock_irqsave(&pfc->lock, flags);
+	value = ioread32(addr);
+	spin_unlock_irqrestore(&pfc->lock, flags);
+
+	return !!(value & BIT(28));
+}
+
+static int sh73a0_vccq_mc0_get_voltage(struct regulator_dev *reg)
+{
+	return 3300000;
+}
+
+static struct regulator_ops sh73a0_vccq_mc0_ops = {
+	.enable = sh73a0_vccq_mc0_enable,
+	.disable = sh73a0_vccq_mc0_disable,
+	.is_enabled = sh73a0_vccq_mc0_is_enabled,
+	.get_voltage = sh73a0_vccq_mc0_get_voltage,
+};
+
+static const struct regulator_desc sh73a0_vccq_mc0_desc = {
+	.owner = THIS_MODULE,
+	.name = "vccq_mc0",
+	.type = REGULATOR_VOLTAGE,
+	.ops = &sh73a0_vccq_mc0_ops,
+};
+
+static struct regulator_consumer_supply sh73a0_vccq_mc0_consumers[] = {
+	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+	REGULATOR_SUPPLY("vqmmc", "ee100000.sdhi"),
+};
+
+static const struct regulator_init_data sh73a0_vccq_mc0_init_data = {
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(sh73a0_vccq_mc0_consumers),
+	.consumer_supplies = sh73a0_vccq_mc0_consumers,
+};
+
+/* -----------------------------------------------------------------------------
+ * Pin bias
+ */
+
 #define PORTnCR_PULMD_OFF	(0 << 6)
 #define PORTnCR_PULMD_DOWN	(2 << 6)
 #define PORTnCR_PULMD_UP	(3 << 6)
@@ -3934,7 +3846,51 @@ static void sh73a0_pinmux_set_bias(struc
 	iowrite8(value, addr);
 }
 
+/* -----------------------------------------------------------------------------
+ * SoC information
+ */
+
+struct sh73a0_pinmux_data {
+	struct regulator_dev *vccq_mc0;
+};
+
+static int sh73a0_pinmux_soc_init(struct sh_pfc *pfc)
+{
+	struct sh73a0_pinmux_data *data;
+	struct regulator_config cfg = { };
+	int ret;
+
+	data = devm_kzalloc(pfc->dev, sizeof(*data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
+	cfg.dev = pfc->dev;
+	cfg.init_data = &sh73a0_vccq_mc0_init_data;
+	cfg.driver_data = pfc;
+
+	data->vccq_mc0 = regulator_register(&sh73a0_vccq_mc0_desc, &cfg);
+	if (IS_ERR(data->vccq_mc0)) {
+		ret = PTR_ERR(data->vccq_mc0);
+		dev_err(pfc->dev, "Failed to register VCCQ MC0 regulator: %d\n",
+			ret);
+		return ret;
+	}
+
+	pfc->soc_data = data;
+
+	return 0;
+}
+
+static void sh73a0_pinmux_soc_exit(struct sh_pfc *pfc)
+{
+	struct sh73a0_pinmux_data *data = pfc->soc_data;
+
+	regulator_unregister(data->vccq_mc0);
+}
+
 static const struct sh_pfc_soc_operations sh73a0_pinmux_ops = {
+	.init = sh73a0_pinmux_soc_init,
+	.exit = sh73a0_pinmux_soc_exit,
 	.get_bias = sh73a0_pinmux_get_bias,
 	.set_bias = sh73a0_pinmux_set_bias,
 };
@@ -3956,9 +3912,6 @@ const struct sh_pfc_soc_info sh73a0_pinm
 	.functions = pinmux_functions,
 	.nr_functions = ARRAY_SIZE(pinmux_functions),
 
-	.func_gpios = pinmux_func_gpios,
-	.nr_func_gpios = ARRAY_SIZE(pinmux_func_gpios),
-
 	.cfg_regs = pinmux_config_regs,
 	.data_regs = pinmux_data_regs,
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pinctrl.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pinctrl.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/pinctrl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/pinctrl.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,7 +14,9 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinctrl.h>
@@ -72,11 +74,214 @@ static void sh_pfc_pin_dbg_show(struct p
 	seq_printf(s, "%s", DRV_NAME);
 }
 
+#ifdef CONFIG_OF
+static int sh_pfc_map_add_config(struct pinctrl_map *map,
+				 const char *group_or_pin,
+				 enum pinctrl_map_type type,
+				 unsigned long *configs,
+				 unsigned int num_configs)
+{
+	unsigned long *cfgs;
+
+	cfgs = kmemdup(configs, num_configs * sizeof(*cfgs),
+		       GFP_KERNEL);
+	if (cfgs == NULL)
+		return -ENOMEM;
+
+	map->type = type;
+	map->data.configs.group_or_pin = group_or_pin;
+	map->data.configs.configs = cfgs;
+	map->data.configs.num_configs = num_configs;
+
+	return 0;
+}
+
+static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np,
+				    struct pinctrl_map **map,
+				    unsigned int *num_maps, unsigned int *index)
+{
+	struct pinctrl_map *maps = *map;
+	unsigned int nmaps = *num_maps;
+	unsigned int idx = *index;
+	unsigned int num_configs;
+	const char *function = NULL;
+	unsigned long *configs;
+	struct property *prop;
+	unsigned int num_groups;
+	unsigned int num_pins;
+	const char *group;
+	const char *pin;
+	int ret;
+
+	/* Parse the function and configuration properties. At least a function
+	 * or one configuration must be specified.
+	 */
+	ret = of_property_read_string(np, "renesas,function", &function);
+	if (ret < 0 && ret != -EINVAL) {
+		dev_err(dev, "Invalid function in DT\n");
+		return ret;
+	}
+
+	ret = pinconf_generic_parse_dt_config(np, &configs, &num_configs);
+	if (ret < 0)
+		return ret;
+
+	if (!function && num_configs == 0) {
+		dev_err(dev,
+			"DT node must contain at least a function or config\n");
+		goto done;
+	}
+
+	/* Count the number of pins and groups and reallocate mappings. */
+	ret = of_property_count_strings(np, "renesas,pins");
+	if (ret == -EINVAL) {
+		num_pins = 0;
+	} else if (ret < 0) {
+		dev_err(dev, "Invalid pins list in DT\n");
+		goto done;
+	} else {
+		num_pins = ret;
+	}
+
+	ret = of_property_count_strings(np, "renesas,groups");
+	if (ret == -EINVAL) {
+		num_groups = 0;
+	} else if (ret < 0) {
+		dev_err(dev, "Invalid pin groups list in DT\n");
+		goto done;
+	} else {
+		num_groups = ret;
+	}
+
+	if (!num_pins && !num_groups) {
+		dev_err(dev, "No pin or group provided in DT node\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	if (function)
+		nmaps += num_groups;
+	if (configs)
+		nmaps += num_pins + num_groups;
+
+	maps = krealloc(maps, sizeof(*maps) * nmaps, GFP_KERNEL);
+	if (maps == NULL) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	*map = maps;
+	*num_maps = nmaps;
+
+	/* Iterate over pins and groups and create the mappings. */
+	of_property_for_each_string(np, "renesas,groups", prop, group) {
+		if (function) {
+			maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;
+			maps[idx].data.mux.group = group;
+			maps[idx].data.mux.function = function;
+			idx++;
+		}
+
+		if (configs) {
+			ret = sh_pfc_map_add_config(&maps[idx], group,
+						    PIN_MAP_TYPE_CONFIGS_GROUP,
+						    configs, num_configs);
+			if (ret < 0)
+				goto done;
+
+			idx++;
+		}
+	}
+
+	if (!configs) {
+		ret = 0;
+		goto done;
+	}
+
+	of_property_for_each_string(np, "renesas,pins", prop, pin) {
+		ret = sh_pfc_map_add_config(&maps[idx], pin,
+					    PIN_MAP_TYPE_CONFIGS_PIN,
+					    configs, num_configs);
+		if (ret < 0)
+			goto done;
+
+		idx++;
+	}
+
+done:
+	*index = idx;
+	kfree(configs);
+	return ret;
+}
+
+static void sh_pfc_dt_free_map(struct pinctrl_dev *pctldev,
+			       struct pinctrl_map *map, unsigned num_maps)
+{
+	unsigned int i;
+
+	if (map == NULL)
+		return;
+
+	for (i = 0; i < num_maps; ++i) {
+		if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP ||
+		    map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
+			kfree(map[i].data.configs.configs);
+	}
+
+	kfree(map);
+}
+
+static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev,
+				 struct device_node *np,
+				 struct pinctrl_map **map, unsigned *num_maps)
+{
+	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+	struct device *dev = pmx->pfc->dev;
+	struct device_node *child;
+	unsigned int index;
+	int ret;
+
+	*map = NULL;
+	*num_maps = 0;
+	index = 0;
+
+	for_each_child_of_node(np, child) {
+		ret = sh_pfc_dt_subnode_to_map(dev, child, map, num_maps,
+					       &index);
+		if (ret < 0)
+			goto done;
+	}
+
+	/* If no mapping has been found in child nodes try the config node. */
+	if (*num_maps == 0) {
+		ret = sh_pfc_dt_subnode_to_map(dev, np, map, num_maps, &index);
+		if (ret < 0)
+			goto done;
+	}
+
+	if (*num_maps)
+		return 0;
+
+	dev_err(dev, "no mapping found in node %s\n", np->full_name);
+	ret = -EINVAL;
+
+done:
+	if (ret < 0)
+		sh_pfc_dt_free_map(pctldev, *map, *num_maps);
+
+	return ret;
+}
+#endif /* CONFIG_OF */
+
 static const struct pinctrl_ops sh_pfc_pinctrl_ops = {
 	.get_groups_count	= sh_pfc_get_groups_count,
 	.get_group_name		= sh_pfc_get_group_name,
 	.get_group_pins		= sh_pfc_get_group_pins,
 	.pin_dbg_show		= sh_pfc_pin_dbg_show,
+#ifdef CONFIG_OF
+	.dt_node_to_map		= sh_pfc_dt_node_to_map,
+	.dt_free_map		= sh_pfc_dt_free_map,
+#endif
 };
 
 static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/sh_pfc.h linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/sh_pfc.h
--- linux-libre-3.10-gnu/drivers/pinctrl/sh-pfc/sh_pfc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sh-pfc/sh_pfc.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,8 +11,8 @@
 #ifndef __SH_PFC_H
 #define __SH_PFC_H
 
+#include <linux/bug.h>
 #include <linux/stringify.h>
-#include <asm-generic/gpio.h>
 
 typedef unsigned short pinmux_enum_t;
 
@@ -129,6 +129,8 @@ struct pinmux_range {
 struct sh_pfc;
 
 struct sh_pfc_soc_operations {
+	int (*init)(struct sh_pfc *pfc);
+	void (*exit)(struct sh_pfc *pfc);
 	unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin);
 	void (*set_bias)(struct sh_pfc *pfc, unsigned int pin,
 			 unsigned int bias);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sirf/Makefile linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/Makefile
--- linux-libre-3.10-gnu/drivers/pinctrl/sirf/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,5 @@
+# CSR SiRFsoc pinmux support
+
+obj-y	+= pinctrl-sirf.o
+obj-y	+= pinctrl-prima2.o
+obj-y	+= pinctrl-atlas6.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sirf/pinctrl-atlas6.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/pinctrl-atlas6.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sirf/pinctrl-atlas6.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/pinctrl-atlas6.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,967 @@
+/*
+ * pinctrl pads, groups, functions for CSR SiRFatlasVI
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/bitops.h>
+
+#include "pinctrl-sirf.h"
+
+/*
+ * pad list for the pinmux subsystem
+ * refer to atlasVI_io_table_v0.93.xls
+ */
+static const struct pinctrl_pin_desc sirfsoc_pads[] = {
+	PINCTRL_PIN(0, "gpio0-0"),
+	PINCTRL_PIN(1, "gpio0-1"),
+	PINCTRL_PIN(2, "gpio0-2"),
+	PINCTRL_PIN(3, "gpio0-3"),
+	PINCTRL_PIN(4, "pwm0"),
+	PINCTRL_PIN(5, "pwm1"),
+	PINCTRL_PIN(6, "pwm2"),
+	PINCTRL_PIN(7, "pwm3"),
+	PINCTRL_PIN(8, "warm_rst_b"),
+	PINCTRL_PIN(9, "odo_0"),
+	PINCTRL_PIN(10, "odo_1"),
+	PINCTRL_PIN(11, "dr_dir"),
+	PINCTRL_PIN(12, "rts_0"),
+	PINCTRL_PIN(13, "scl_1"),
+	PINCTRL_PIN(14, "ntrst"),
+	PINCTRL_PIN(15, "sda_1"),
+	PINCTRL_PIN(16, "x_ldd[16]"),
+	PINCTRL_PIN(17, "x_ldd[17]"),
+	PINCTRL_PIN(18, "x_ldd[18]"),
+	PINCTRL_PIN(19, "x_ldd[19]"),
+	PINCTRL_PIN(20, "x_ldd[20]"),
+	PINCTRL_PIN(21, "x_ldd[21]"),
+	PINCTRL_PIN(22, "x_ldd[22]"),
+	PINCTRL_PIN(23, "x_ldd[23]"),
+	PINCTRL_PIN(24, "gps_sgn"),
+	PINCTRL_PIN(25, "gps_mag"),
+	PINCTRL_PIN(26, "gps_clk"),
+	PINCTRL_PIN(27,	"sd_cd_b_2"),
+	PINCTRL_PIN(28, "sd_vcc_on_2"),
+	PINCTRL_PIN(29, "sd_wp_b_2"),
+	PINCTRL_PIN(30, "sd_clk_3"),
+	PINCTRL_PIN(31, "sd_cmd_3"),
+
+	PINCTRL_PIN(32, "x_sd_dat_3[0]"),
+	PINCTRL_PIN(33, "x_sd_dat_3[1]"),
+	PINCTRL_PIN(34, "x_sd_dat_3[2]"),
+	PINCTRL_PIN(35, "x_sd_dat_3[3]"),
+	PINCTRL_PIN(36, "usb_clk"),
+	PINCTRL_PIN(37, "usb_dir"),
+	PINCTRL_PIN(38, "usb_nxt"),
+	PINCTRL_PIN(39, "usb_stp"),
+	PINCTRL_PIN(40, "usb_dat[7]"),
+	PINCTRL_PIN(41, "usb_dat[6]"),
+	PINCTRL_PIN(42, "x_cko_1"),
+	PINCTRL_PIN(43, "spi_clk_1"),
+	PINCTRL_PIN(44, "spi_dout_1"),
+	PINCTRL_PIN(45, "spi_din_1"),
+	PINCTRL_PIN(46, "spi_en_1"),
+	PINCTRL_PIN(47, "x_txd_1"),
+	PINCTRL_PIN(48, "x_txd_2"),
+	PINCTRL_PIN(49, "x_rxd_1"),
+	PINCTRL_PIN(50, "x_rxd_2"),
+	PINCTRL_PIN(51, "x_usclk_0"),
+	PINCTRL_PIN(52, "x_utxd_0"),
+	PINCTRL_PIN(53, "x_urxd_0"),
+	PINCTRL_PIN(54, "x_utfs_0"),
+	PINCTRL_PIN(55, "x_urfs_0"),
+	PINCTRL_PIN(56, "usb_dat5"),
+	PINCTRL_PIN(57, "usb_dat4"),
+	PINCTRL_PIN(58, "usb_dat3"),
+	PINCTRL_PIN(59, "usb_dat2"),
+	PINCTRL_PIN(60, "usb_dat1"),
+	PINCTRL_PIN(61, "usb_dat0"),
+	PINCTRL_PIN(62, "x_ldd[14]"),
+	PINCTRL_PIN(63, "x_ldd[15]"),
+
+	PINCTRL_PIN(64, "x_gps_gpio"),
+	PINCTRL_PIN(65, "x_ldd[13]"),
+	PINCTRL_PIN(66, "x_df_we_b"),
+	PINCTRL_PIN(67, "x_df_re_b"),
+	PINCTRL_PIN(68, "x_txd_0"),
+	PINCTRL_PIN(69, "x_rxd_0"),
+	PINCTRL_PIN(70, "x_l_lck"),
+	PINCTRL_PIN(71, "x_l_fck"),
+	PINCTRL_PIN(72, "x_l_de"),
+	PINCTRL_PIN(73, "x_ldd[0]"),
+	PINCTRL_PIN(74, "x_ldd[1]"),
+	PINCTRL_PIN(75, "x_ldd[2]"),
+	PINCTRL_PIN(76, "x_ldd[3]"),
+	PINCTRL_PIN(77, "x_ldd[4]"),
+	PINCTRL_PIN(78, "x_cko_0"),
+	PINCTRL_PIN(79, "x_ldd[5]"),
+	PINCTRL_PIN(80, "x_ldd[6]"),
+	PINCTRL_PIN(81, "x_ldd[7]"),
+	PINCTRL_PIN(82, "x_ldd[8]"),
+	PINCTRL_PIN(83, "x_ldd[9]"),
+	PINCTRL_PIN(84, "x_ldd[10]"),
+	PINCTRL_PIN(85, "x_ldd[11]"),
+	PINCTRL_PIN(86, "x_ldd[12]"),
+	PINCTRL_PIN(87, "x_vip_vsync"),
+	PINCTRL_PIN(88, "x_vip_hsync"),
+	PINCTRL_PIN(89, "x_vip_pxclk"),
+	PINCTRL_PIN(90, "x_sda_0"),
+	PINCTRL_PIN(91, "x_scl_0"),
+	PINCTRL_PIN(92, "x_df_ry_by"),
+	PINCTRL_PIN(93, "x_df_cs_b[1]"),
+	PINCTRL_PIN(94, "x_df_cs_b[0]"),
+	PINCTRL_PIN(95, "x_l_pclk"),
+
+	PINCTRL_PIN(96, "x_df_dqs"),
+	PINCTRL_PIN(97, "x_df_wp_b"),
+	PINCTRL_PIN(98, "ac97_sync"),
+	PINCTRL_PIN(99, "ac97_bit_clk "),
+	PINCTRL_PIN(100, "ac97_dout"),
+	PINCTRL_PIN(101, "ac97_din"),
+	PINCTRL_PIN(102, "x_rtc_io"),
+};
+
+static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(30) | BIT(31),
+	}, {
+		.group = 2,
+		.mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) |
+			BIT(12) | BIT(13) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) |
+			BIT(20) | BIT(21) | BIT(22) | BIT(31),
+	},
+};
+
+static const struct sirfsoc_padmux lcd_16bits_padmux = {
+	.muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask),
+	.muxmask = lcd_16bits_sirfsoc_muxmask,
+	.funcmask = BIT(4),
+	.funcval = 0,
+};
+
+static const unsigned lcd_16bits_pins[] = { 62, 63, 65, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83,
+	84, 85, 86, 95 };
+
+static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) |
+			BIT(12) | BIT(13) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) |
+			BIT(20) | BIT(21) | BIT(22) | BIT(31),
+	}, {
+		.group = 1,
+		.mask = BIT(30) | BIT(31),
+	}, {
+		.group = 0,
+		.mask = BIT(16) | BIT(17),
+	},
+};
+
+static const struct sirfsoc_padmux lcd_18bits_padmux = {
+	.muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask),
+	.muxmask = lcd_18bits_muxmask,
+	.funcmask = BIT(4) | BIT(15),
+	.funcval = 0,
+};
+
+static const unsigned lcd_18bits_pins[] = { 16, 17, 62, 63, 65, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83,
+	84, 85, 86, 95 };
+
+static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) |
+			BIT(12) | BIT(13) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) |
+			BIT(20) | BIT(21) | BIT(22) | BIT(31),
+	}, {
+		.group = 1,
+		.mask = BIT(30) | BIT(31),
+	}, {
+		.group = 0,
+		.mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23),
+	},
+};
+
+static const struct sirfsoc_padmux lcd_24bits_padmux = {
+	.muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask),
+	.muxmask = lcd_24bits_muxmask,
+	.funcmask = BIT(4) | BIT(15),
+	.funcval = 0,
+};
+
+static const unsigned lcd_24bits_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 62, 63, 65, 70, 71, 72, 73, 74, 75, 76, 77, 79,
+	80, 81, 82, 83, 84, 85, 86, 95};
+
+static const struct sirfsoc_muxmask lcdrom_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(1) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) |
+			BIT(12) | BIT(13) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) |
+			BIT(20) | BIT(21) | BIT(22) | BIT(31),
+	}, {
+		.group = 1,
+		.mask = BIT(30) | BIT(31),
+	}, {
+		.group = 0,
+		.mask = BIT(8),
+	},
+};
+
+static const struct sirfsoc_padmux lcdrom_padmux = {
+	.muxmask_counts = ARRAY_SIZE(lcdrom_muxmask),
+	.muxmask = lcdrom_muxmask,
+	.funcmask = BIT(4),
+	.funcval = BIT(4),
+};
+
+static const unsigned lcdrom_pins[] = { 8, 62, 63, 65, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83,
+	84, 85, 86, 95};
+
+static const struct sirfsoc_muxmask uart0_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(12),
+	}, {
+		.group = 1,
+		.mask = BIT(23),
+	}, {
+		.group = 2,
+		.mask = BIT(4) | BIT(5),
+	},
+};
+
+static const struct sirfsoc_padmux uart0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart0_muxmask),
+	.muxmask = uart0_muxmask,
+	.funcmask = BIT(9),
+	.funcval = BIT(9),
+};
+
+static const unsigned uart0_pins[] = { 12, 55, 68, 69 };
+
+static const struct sirfsoc_muxmask uart0_nostreamctrl_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(4) | BIT(5),
+	},
+};
+
+static const struct sirfsoc_padmux uart0_nostreamctrl_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask),
+	.muxmask = uart0_nostreamctrl_muxmask,
+};
+
+static const unsigned uart0_nostreamctrl_pins[] = { 68, 69 };
+
+static const struct sirfsoc_muxmask uart1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(15) | BIT(17),
+	},
+};
+
+static const struct sirfsoc_padmux uart1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart1_muxmask),
+	.muxmask = uart1_muxmask,
+};
+
+static const unsigned uart1_pins[] = { 47, 49 };
+
+static const struct sirfsoc_muxmask uart2_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(10) | BIT(14),
+	}, {
+		.group = 1,
+		.mask = BIT(16) | BIT(18),
+	},
+};
+
+static const struct sirfsoc_padmux uart2_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart2_muxmask),
+	.muxmask = uart2_muxmask,
+	.funcmask = BIT(10),
+	.funcval = BIT(10),
+};
+
+static const unsigned uart2_pins[] = { 10, 14, 48, 50 };
+
+static const struct sirfsoc_muxmask uart2_nostreamctrl_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(16) | BIT(18),
+	},
+};
+
+static const struct sirfsoc_padmux uart2_nostreamctrl_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask),
+	.muxmask = uart2_nostreamctrl_muxmask,
+};
+
+static const unsigned uart2_nostreamctrl_pins[] = { 48, 50 };
+
+static const struct sirfsoc_muxmask sdmmc3_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(30) | BIT(31),
+	}, {
+		.group = 1,
+		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc3_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask),
+	.muxmask = sdmmc3_muxmask,
+	.funcmask = BIT(7),
+	.funcval = 0,
+};
+
+static const unsigned sdmmc3_pins[] = { 30, 31, 32, 33, 34, 35 };
+
+static const struct sirfsoc_muxmask spi0_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(30),
+	}, {
+		.group = 1,
+		.mask = BIT(0) | BIT(2) | BIT(3),
+	},
+};
+
+static const struct sirfsoc_padmux spi0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(spi0_muxmask),
+	.muxmask = spi0_muxmask,
+	.funcmask = BIT(7),
+	.funcval = BIT(7),
+};
+
+static const unsigned spi0_pins[] = { 30, 32, 34, 35 };
+
+static const struct sirfsoc_muxmask cko1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(10),
+	},
+};
+
+static const struct sirfsoc_padmux cko1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(cko1_muxmask),
+	.muxmask = cko1_muxmask,
+	.funcmask = BIT(3),
+	.funcval = 0,
+};
+
+static const unsigned cko1_pins[] = { 42 };
+
+static const struct sirfsoc_muxmask i2s_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(10),
+	}, {
+		.group = 3,
+		.mask = BIT(2) | BIT(3) | BIT(4) | BIT(5),
+	},
+};
+
+static const struct sirfsoc_padmux i2s_padmux = {
+	.muxmask_counts = ARRAY_SIZE(i2s_muxmask),
+	.muxmask = i2s_muxmask,
+	.funcmask = BIT(3),
+	.funcval = BIT(3),
+};
+
+static const unsigned i2s_pins[] = { 42, 98, 99, 100, 101 };
+
+static const struct sirfsoc_muxmask i2s_no_din_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(10),
+	}, {
+		.group = 3,
+		.mask = BIT(2) | BIT(3) | BIT(4),
+	},
+};
+
+static const struct sirfsoc_padmux i2s_no_din_padmux = {
+	.muxmask_counts = ARRAY_SIZE(i2s_no_din_muxmask),
+	.muxmask = i2s_no_din_muxmask,
+	.funcmask = BIT(3),
+	.funcval = BIT(3),
+};
+
+static const unsigned i2s_no_din_pins[] = { 42, 98, 99, 100 };
+
+static const struct sirfsoc_muxmask i2s_6chn_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(10) | BIT(20) | BIT(23),
+	}, {
+		.group = 3,
+		.mask = BIT(2) | BIT(3) | BIT(4) | BIT(5),
+	},
+};
+
+static const struct sirfsoc_padmux i2s_6chn_padmux = {
+	.muxmask_counts = ARRAY_SIZE(i2s_6chn_muxmask),
+	.muxmask = i2s_6chn_muxmask,
+	.funcmask = BIT(1) | BIT(3) | BIT(9),
+	.funcval = BIT(1) | BIT(3) | BIT(9),
+};
+
+static const unsigned i2s_6chn_pins[] = { 42, 52, 55, 98, 99, 100, 101 };
+
+static const struct sirfsoc_muxmask ac97_muxmask[] = {
+	{
+		.group = 3,
+		.mask = BIT(2) | BIT(3) | BIT(4) | BIT(5),
+	},
+};
+
+static const struct sirfsoc_padmux ac97_padmux = {
+	.muxmask_counts = ARRAY_SIZE(ac97_muxmask),
+	.muxmask = ac97_muxmask,
+};
+
+static const unsigned ac97_pins[] = { 98, 99, 100, 101 };
+
+static const struct sirfsoc_muxmask spi1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
+	},
+};
+
+static const struct sirfsoc_padmux spi1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(spi1_muxmask),
+	.muxmask = spi1_muxmask,
+	.funcmask = BIT(16),
+	.funcval = 0,
+};
+
+static const unsigned spi1_pins[] = { 43, 44, 45, 46 };
+
+static const struct sirfsoc_muxmask sdmmc1_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(2) | BIT(3),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask),
+	.muxmask = sdmmc1_muxmask,
+	.funcmask = BIT(5),
+	.funcval = BIT(5),
+};
+
+static const unsigned sdmmc1_pins[] = { 66, 67 };
+
+static const struct sirfsoc_muxmask gps_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(24) | BIT(25) | BIT(26),
+	},
+};
+
+static const struct sirfsoc_padmux gps_padmux = {
+	.muxmask_counts = ARRAY_SIZE(gps_muxmask),
+	.muxmask = gps_muxmask,
+	.funcmask = BIT(13),
+	.funcval = 0,
+};
+
+static const unsigned gps_pins[] = { 24, 25, 26 };
+
+static const struct sirfsoc_muxmask sdmmc5_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(24) | BIT(25) | BIT(26),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc5_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask),
+	.muxmask = sdmmc5_muxmask,
+	.funcmask = BIT(13),
+	.funcval = BIT(13),
+};
+
+static const unsigned sdmmc5_pins[] = { 24, 25, 26 };
+
+static const struct sirfsoc_muxmask usp0_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23),
+	},
+};
+
+static const struct sirfsoc_padmux usp0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usp0_muxmask),
+	.muxmask = usp0_muxmask,
+	.funcmask = BIT(1) | BIT(2) | BIT(9),
+	.funcval = 0,
+};
+
+static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 };
+
+static const struct sirfsoc_muxmask usp0_uart_nostreamctrl_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(20) | BIT(21),
+	},
+};
+
+static const struct sirfsoc_padmux usp0_uart_nostreamctrl_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usp0_uart_nostreamctrl_muxmask),
+	.muxmask = usp0_uart_nostreamctrl_muxmask,
+};
+
+static const unsigned usp0_uart_nostreamctrl_pins[] = { 52, 53 };
+static const struct sirfsoc_muxmask usp1_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(15),
+	}, {
+		.group = 1,
+		.mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
+	},
+};
+
+static const struct sirfsoc_padmux usp1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usp1_muxmask),
+	.muxmask = usp1_muxmask,
+	.funcmask = BIT(16),
+	.funcval = BIT(16),
+};
+
+static const unsigned usp1_pins[] = { 15, 43, 44, 45, 46 };
+
+static const struct sirfsoc_muxmask nand_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(2) | BIT(3) | BIT(28) | BIT(29) | BIT(30),
+	}, {
+		.group = 3,
+		.mask = BIT(0) | BIT(1),
+	},
+};
+
+static const struct sirfsoc_padmux nand_padmux = {
+	.muxmask_counts = ARRAY_SIZE(nand_muxmask),
+	.muxmask = nand_muxmask,
+	.funcmask = BIT(5) | BIT(19),
+	.funcval = 0,
+};
+
+static const unsigned nand_pins[] = { 66, 67, 92, 93, 94, 96, 97 };
+
+static const struct sirfsoc_muxmask sdmmc0_muxmask[] = {
+	{
+		.group = 3,
+		.mask = BIT(1),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc0_muxmask),
+	.muxmask = sdmmc0_muxmask,
+	.funcmask = BIT(5) | BIT(19),
+	.funcval = BIT(19),
+};
+
+static const unsigned sdmmc0_pins[] = { 97 };
+
+static const struct sirfsoc_muxmask sdmmc2_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(27) | BIT(28) | BIT(29),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc2_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask),
+	.muxmask = sdmmc2_muxmask,
+	.funcmask = BIT(11),
+	.funcval = 0,
+};
+
+static const unsigned sdmmc2_pins[] = { 27, 28, 29 };
+
+static const struct sirfsoc_muxmask sdmmc2_nowp_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(27) | BIT(28),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc2_nowp_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc2_nowp_muxmask),
+	.muxmask = sdmmc2_nowp_muxmask,
+	.funcmask = BIT(11),
+	.funcval = 0,
+};
+
+static const unsigned sdmmc2_nowp_pins[] = { 27, 28 };
+
+static const struct sirfsoc_muxmask cko0_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(14),
+	},
+};
+
+static const struct sirfsoc_padmux cko0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(cko0_muxmask),
+	.muxmask = cko0_muxmask,
+};
+
+static const unsigned cko0_pins[] = { 78 };
+
+static const struct sirfsoc_muxmask vip_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(4) | BIT(5) | BIT(6) | BIT(8) | BIT(9)
+			| BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28) |
+			BIT(29),
+	},
+};
+
+static const struct sirfsoc_padmux vip_padmux = {
+	.muxmask_counts = ARRAY_SIZE(vip_muxmask),
+	.muxmask = vip_muxmask,
+	.funcmask = BIT(18),
+	.funcval = BIT(18),
+};
+
+static const unsigned vip_pins[] = { 36, 37, 38, 40, 41, 56, 57, 58, 59, 60, 61 };
+
+static const struct sirfsoc_muxmask vip_noupli_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20)
+			| BIT(21) | BIT(22) | BIT(23),
+	}, {
+		.group = 2,
+		.mask = BIT(23) | BIT(24) | BIT(25),
+	},
+};
+
+static const struct sirfsoc_padmux vip_noupli_padmux = {
+	.muxmask_counts = ARRAY_SIZE(vip_noupli_muxmask),
+	.muxmask = vip_noupli_muxmask,
+	.funcmask = BIT(15),
+	.funcval = BIT(15),
+};
+
+static const unsigned vip_noupli_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 87, 88, 89 };
+
+static const struct sirfsoc_muxmask i2c0_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(26) | BIT(27),
+	},
+};
+
+static const struct sirfsoc_padmux i2c0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(i2c0_muxmask),
+	.muxmask = i2c0_muxmask,
+};
+
+static const unsigned i2c0_pins[] = { 90, 91 };
+
+static const struct sirfsoc_muxmask i2c1_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(13) | BIT(15),
+	},
+};
+
+static const struct sirfsoc_padmux i2c1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(i2c1_muxmask),
+	.muxmask = i2c1_muxmask,
+	.funcmask = BIT(16),
+	.funcval = 0,
+};
+
+static const unsigned i2c1_pins[] = { 13, 15 };
+
+static const struct sirfsoc_muxmask pwm0_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(4),
+	},
+};
+
+static const struct sirfsoc_padmux pwm0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pwm0_muxmask),
+	.muxmask = pwm0_muxmask,
+	.funcmask = BIT(12),
+	.funcval = 0,
+};
+
+static const unsigned pwm0_pins[] = { 4 };
+
+static const struct sirfsoc_muxmask pwm1_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(5),
+	},
+};
+
+static const struct sirfsoc_padmux pwm1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pwm1_muxmask),
+	.muxmask = pwm1_muxmask,
+};
+
+static const unsigned pwm1_pins[] = { 5 };
+
+static const struct sirfsoc_muxmask pwm2_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(6),
+	},
+};
+
+static const struct sirfsoc_padmux pwm2_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pwm2_muxmask),
+	.muxmask = pwm2_muxmask,
+};
+
+static const unsigned pwm2_pins[] = { 6 };
+
+static const struct sirfsoc_muxmask pwm3_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(7),
+	},
+};
+
+static const struct sirfsoc_padmux pwm3_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pwm3_muxmask),
+	.muxmask = pwm3_muxmask,
+};
+
+static const unsigned pwm3_pins[] = { 7 };
+
+static const struct sirfsoc_muxmask pwm4_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(14),
+	},
+};
+
+static const struct sirfsoc_padmux pwm4_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pwm4_muxmask),
+	.muxmask = pwm4_muxmask,
+};
+
+static const unsigned pwm4_pins[] = { 78 };
+
+static const struct sirfsoc_muxmask warm_rst_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(8),
+	},
+};
+
+static const struct sirfsoc_padmux warm_rst_padmux = {
+	.muxmask_counts = ARRAY_SIZE(warm_rst_muxmask),
+	.muxmask = warm_rst_muxmask,
+	.funcmask = BIT(4),
+	.funcval = 0,
+};
+
+static const unsigned warm_rst_pins[] = { 8 };
+
+static const struct sirfsoc_muxmask usb0_upli_drvbus_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8)
+			| BIT(9) | BIT(24) | BIT(25) | BIT(26) |
+			BIT(27) | BIT(28) | BIT(29),
+	},
+};
+static const struct sirfsoc_padmux usb0_upli_drvbus_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usb0_upli_drvbus_muxmask),
+	.muxmask = usb0_upli_drvbus_muxmask,
+	.funcmask = BIT(18),
+	.funcval = 0,
+};
+
+static const unsigned usb0_upli_drvbus_pins[] = { 36, 37, 38, 39, 40, 41, 56, 57, 58, 59, 60, 61 };
+
+static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(28),
+	},
+};
+
+static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask),
+	.muxmask = usb1_utmi_drvbus_muxmask,
+	.funcmask = BIT(11),
+	.funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */
+};
+
+static const unsigned usb1_utmi_drvbus_pins[] = { 28 };
+
+static const struct sirfsoc_muxmask pulse_count_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(9) | BIT(10) | BIT(11),
+	},
+};
+
+static const struct sirfsoc_padmux pulse_count_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pulse_count_muxmask),
+	.muxmask = pulse_count_muxmask,
+};
+
+static const unsigned pulse_count_pins[] = { 9, 10, 11 };
+
+static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = {
+	SIRFSOC_PIN_GROUP("lcd_16bitsgrp", lcd_16bits_pins),
+	SIRFSOC_PIN_GROUP("lcd_18bitsgrp", lcd_18bits_pins),
+	SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins),
+	SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins),
+	SIRFSOC_PIN_GROUP("uart0grp", uart0_pins),
+	SIRFSOC_PIN_GROUP("uart1grp", uart1_pins),
+	SIRFSOC_PIN_GROUP("uart2grp", uart2_pins),
+	SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins),
+	SIRFSOC_PIN_GROUP("usp0grp", usp0_pins),
+	SIRFSOC_PIN_GROUP("usp0_uart_nostreamctrl_grp",
+					usp0_uart_nostreamctrl_pins),
+	SIRFSOC_PIN_GROUP("usp1grp", usp1_pins),
+	SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins),
+	SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins),
+	SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins),
+	SIRFSOC_PIN_GROUP("pwm1grp", pwm1_pins),
+	SIRFSOC_PIN_GROUP("pwm2grp", pwm2_pins),
+	SIRFSOC_PIN_GROUP("pwm3grp", pwm3_pins),
+	SIRFSOC_PIN_GROUP("pwm4grp", pwm4_pins),
+	SIRFSOC_PIN_GROUP("vipgrp", vip_pins),
+	SIRFSOC_PIN_GROUP("vip_noupligrp", vip_noupli_pins),
+	SIRFSOC_PIN_GROUP("warm_rstgrp", warm_rst_pins),
+	SIRFSOC_PIN_GROUP("cko0grp", cko0_pins),
+	SIRFSOC_PIN_GROUP("cko1grp", cko1_pins),
+	SIRFSOC_PIN_GROUP("sdmmc0grp", sdmmc0_pins),
+	SIRFSOC_PIN_GROUP("sdmmc1grp", sdmmc1_pins),
+	SIRFSOC_PIN_GROUP("sdmmc2grp", sdmmc2_pins),
+	SIRFSOC_PIN_GROUP("sdmmc2_nowpgrp", sdmmc2_nowp_pins),
+	SIRFSOC_PIN_GROUP("sdmmc3grp", sdmmc3_pins),
+	SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins),
+	SIRFSOC_PIN_GROUP("usb0_upli_drvbusgrp", usb0_upli_drvbus_pins),
+	SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins),
+	SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins),
+	SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins),
+	SIRFSOC_PIN_GROUP("i2s_no_dingrp", i2s_no_din_pins),
+	SIRFSOC_PIN_GROUP("i2s_6chngrp", i2s_6chn_pins),
+	SIRFSOC_PIN_GROUP("ac97grp", ac97_pins),
+	SIRFSOC_PIN_GROUP("nandgrp", nand_pins),
+	SIRFSOC_PIN_GROUP("spi0grp", spi0_pins),
+	SIRFSOC_PIN_GROUP("spi1grp", spi1_pins),
+	SIRFSOC_PIN_GROUP("gpsgrp", gps_pins),
+};
+
+static const char * const lcd_16bitsgrp[] = { "lcd_16bitsgrp" };
+static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" };
+static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" };
+static const char * const lcdromgrp[] = { "lcdromgrp" };
+static const char * const uart0grp[] = { "uart0grp" };
+static const char * const uart1grp[] = { "uart1grp" };
+static const char * const uart2grp[] = { "uart2grp" };
+static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" };
+static const char * const usp0_uart_nostreamctrl_grp[] = {
+					"usp0_uart_nostreamctrl_grp" };
+static const char * const usp0grp[] = { "usp0grp" };
+static const char * const usp1grp[] = { "usp1grp" };
+static const char * const i2c0grp[] = { "i2c0grp" };
+static const char * const i2c1grp[] = { "i2c1grp" };
+static const char * const pwm0grp[] = { "pwm0grp" };
+static const char * const pwm1grp[] = { "pwm1grp" };
+static const char * const pwm2grp[] = { "pwm2grp" };
+static const char * const pwm3grp[] = { "pwm3grp" };
+static const char * const pwm4grp[] = { "pwm4grp" };
+static const char * const vipgrp[] = { "vipgrp" };
+static const char * const vip_noupligrp[] = { "vip_noupligrp" };
+static const char * const warm_rstgrp[] = { "warm_rstgrp" };
+static const char * const cko0grp[] = { "cko0grp" };
+static const char * const cko1grp[] = { "cko1grp" };
+static const char * const sdmmc0grp[] = { "sdmmc0grp" };
+static const char * const sdmmc1grp[] = { "sdmmc1grp" };
+static const char * const sdmmc2grp[] = { "sdmmc2grp" };
+static const char * const sdmmc3grp[] = { "sdmmc3grp" };
+static const char * const sdmmc5grp[] = { "sdmmc5grp" };
+static const char * const sdmmc2_nowpgrp[] = { "sdmmc2_nowpgrp" };
+static const char * const usb0_upli_drvbusgrp[] = { "usb0_upli_drvbusgrp" };
+static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" };
+static const char * const pulse_countgrp[] = { "pulse_countgrp" };
+static const char * const i2sgrp[] = { "i2sgrp" };
+static const char * const i2s_no_dingrp[] = { "i2s_no_dingrp" };
+static const char * const i2s_6chngrp[] = { "i2s_6chngrp" };
+static const char * const ac97grp[] = { "ac97grp" };
+static const char * const nandgrp[] = { "nandgrp" };
+static const char * const spi0grp[] = { "spi0grp" };
+static const char * const spi1grp[] = { "spi1grp" };
+static const char * const gpsgrp[] = { "gpsgrp" };
+
+static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = {
+	SIRFSOC_PMX_FUNCTION("lcd_16bits", lcd_16bitsgrp, lcd_16bits_padmux),
+	SIRFSOC_PMX_FUNCTION("lcd_18bits", lcd_18bitsgrp, lcd_18bits_padmux),
+	SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux),
+	SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux),
+	SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux),
+	SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux),
+	SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux),
+	SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux),
+	SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux),
+	SIRFSOC_PMX_FUNCTION("usp0_uart_nostreamctrl",
+						usp0_uart_nostreamctrl_grp,
+						usp0_uart_nostreamctrl_padmux),
+	SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux),
+	SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux),
+	SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux),
+	SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux),
+	SIRFSOC_PMX_FUNCTION("pwm1", pwm1grp, pwm1_padmux),
+	SIRFSOC_PMX_FUNCTION("pwm2", pwm2grp, pwm2_padmux),
+	SIRFSOC_PMX_FUNCTION("pwm3", pwm3grp, pwm3_padmux),
+	SIRFSOC_PMX_FUNCTION("pwm4", pwm4grp, pwm4_padmux),
+	SIRFSOC_PMX_FUNCTION("vip", vipgrp, vip_padmux),
+	SIRFSOC_PMX_FUNCTION("vip_noupli", vip_noupligrp, vip_noupli_padmux),
+	SIRFSOC_PMX_FUNCTION("warm_rst", warm_rstgrp, warm_rst_padmux),
+	SIRFSOC_PMX_FUNCTION("cko0", cko0grp, cko0_padmux),
+	SIRFSOC_PMX_FUNCTION("cko1", cko1grp, cko1_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc0", sdmmc0grp, sdmmc0_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc1", sdmmc1grp, sdmmc1_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc2", sdmmc2grp, sdmmc2_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc3", sdmmc3grp, sdmmc3_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc2_nowp", sdmmc2_nowpgrp, sdmmc2_nowp_padmux),
+	SIRFSOC_PMX_FUNCTION("usb0_upli_drvbus", usb0_upli_drvbusgrp, usb0_upli_drvbus_padmux),
+	SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux),
+	SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux),
+	SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux),
+	SIRFSOC_PMX_FUNCTION("i2s_no_din", i2s_no_dingrp, i2s_no_din_padmux),
+	SIRFSOC_PMX_FUNCTION("i2s_6chn", i2s_6chngrp, i2s_6chn_padmux),
+	SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux),
+	SIRFSOC_PMX_FUNCTION("nand", nandgrp, nand_padmux),
+	SIRFSOC_PMX_FUNCTION("spi0", spi0grp, spi0_padmux),
+	SIRFSOC_PMX_FUNCTION("spi1", spi1grp, spi1_padmux),
+	SIRFSOC_PMX_FUNCTION("gps", gpsgrp, gps_padmux),
+};
+
+struct sirfsoc_pinctrl_data atlas6_pinctrl_data = {
+	(struct pinctrl_pin_desc *)sirfsoc_pads,
+	ARRAY_SIZE(sirfsoc_pads),
+	(struct sirfsoc_pin_group *)sirfsoc_pin_groups,
+	ARRAY_SIZE(sirfsoc_pin_groups),
+	(struct sirfsoc_pmx_func *)sirfsoc_pmx_functions,
+	ARRAY_SIZE(sirfsoc_pmx_functions),
+};
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sirf/pinctrl-prima2.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/pinctrl-prima2.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sirf/pinctrl-prima2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/pinctrl-prima2.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,887 @@
+/*
+ * pinctrl pads, groups, functions for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/bitops.h>
+
+#include "pinctrl-sirf.h"
+
+/*
+ * pad list for the pinmux subsystem
+ * refer to CS-131858-DC-6A.xls
+ */
+static const struct pinctrl_pin_desc sirfsoc_pads[] = {
+	PINCTRL_PIN(0, "gpio0-0"),
+	PINCTRL_PIN(1, "gpio0-1"),
+	PINCTRL_PIN(2, "gpio0-2"),
+	PINCTRL_PIN(3, "gpio0-3"),
+	PINCTRL_PIN(4, "pwm0"),
+	PINCTRL_PIN(5, "pwm1"),
+	PINCTRL_PIN(6, "pwm2"),
+	PINCTRL_PIN(7, "pwm3"),
+	PINCTRL_PIN(8, "warm_rst_b"),
+	PINCTRL_PIN(9, "odo_0"),
+	PINCTRL_PIN(10, "odo_1"),
+	PINCTRL_PIN(11, "dr_dir"),
+	PINCTRL_PIN(12, "viprom_fa"),
+	PINCTRL_PIN(13, "scl_1"),
+	PINCTRL_PIN(14, "ntrst"),
+	PINCTRL_PIN(15, "sda_1"),
+	PINCTRL_PIN(16, "x_ldd[16]"),
+	PINCTRL_PIN(17, "x_ldd[17]"),
+	PINCTRL_PIN(18, "x_ldd[18]"),
+	PINCTRL_PIN(19, "x_ldd[19]"),
+	PINCTRL_PIN(20, "x_ldd[20]"),
+	PINCTRL_PIN(21, "x_ldd[21]"),
+	PINCTRL_PIN(22, "x_ldd[22]"),
+	PINCTRL_PIN(23, "x_ldd[23], lcdrom_frdy"),
+	PINCTRL_PIN(24, "gps_sgn"),
+	PINCTRL_PIN(25, "gps_mag"),
+	PINCTRL_PIN(26, "gps_clk"),
+	PINCTRL_PIN(27,	"sd_cd_b_1"),
+	PINCTRL_PIN(28, "sd_vcc_on_1"),
+	PINCTRL_PIN(29, "sd_wp_b_1"),
+	PINCTRL_PIN(30, "sd_clk_3"),
+	PINCTRL_PIN(31, "sd_cmd_3"),
+
+	PINCTRL_PIN(32, "x_sd_dat_3[0]"),
+	PINCTRL_PIN(33, "x_sd_dat_3[1]"),
+	PINCTRL_PIN(34, "x_sd_dat_3[2]"),
+	PINCTRL_PIN(35, "x_sd_dat_3[3]"),
+	PINCTRL_PIN(36, "x_sd_clk_4"),
+	PINCTRL_PIN(37, "x_sd_cmd_4"),
+	PINCTRL_PIN(38, "x_sd_dat_4[0]"),
+	PINCTRL_PIN(39, "x_sd_dat_4[1]"),
+	PINCTRL_PIN(40, "x_sd_dat_4[2]"),
+	PINCTRL_PIN(41, "x_sd_dat_4[3]"),
+	PINCTRL_PIN(42, "x_cko_1"),
+	PINCTRL_PIN(43, "x_ac97_bit_clk"),
+	PINCTRL_PIN(44, "x_ac97_dout"),
+	PINCTRL_PIN(45, "x_ac97_din"),
+	PINCTRL_PIN(46, "x_ac97_sync"),
+	PINCTRL_PIN(47, "x_txd_1"),
+	PINCTRL_PIN(48, "x_txd_2"),
+	PINCTRL_PIN(49, "x_rxd_1"),
+	PINCTRL_PIN(50, "x_rxd_2"),
+	PINCTRL_PIN(51, "x_usclk_0"),
+	PINCTRL_PIN(52, "x_utxd_0"),
+	PINCTRL_PIN(53, "x_urxd_0"),
+	PINCTRL_PIN(54, "x_utfs_0"),
+	PINCTRL_PIN(55, "x_urfs_0"),
+	PINCTRL_PIN(56, "x_usclk_1"),
+	PINCTRL_PIN(57, "x_utxd_1"),
+	PINCTRL_PIN(58, "x_urxd_1"),
+	PINCTRL_PIN(59, "x_utfs_1"),
+	PINCTRL_PIN(60, "x_urfs_1"),
+	PINCTRL_PIN(61, "x_usclk_2"),
+	PINCTRL_PIN(62, "x_utxd_2"),
+	PINCTRL_PIN(63, "x_urxd_2"),
+
+	PINCTRL_PIN(64, "x_utfs_2"),
+	PINCTRL_PIN(65, "x_urfs_2"),
+	PINCTRL_PIN(66, "x_df_we_b"),
+	PINCTRL_PIN(67, "x_df_re_b"),
+	PINCTRL_PIN(68, "x_txd_0"),
+	PINCTRL_PIN(69, "x_rxd_0"),
+	PINCTRL_PIN(78, "x_cko_0"),
+	PINCTRL_PIN(79, "x_vip_pxd[7]"),
+	PINCTRL_PIN(80, "x_vip_pxd[6]"),
+	PINCTRL_PIN(81, "x_vip_pxd[5]"),
+	PINCTRL_PIN(82, "x_vip_pxd[4]"),
+	PINCTRL_PIN(83, "x_vip_pxd[3]"),
+	PINCTRL_PIN(84, "x_vip_pxd[2]"),
+	PINCTRL_PIN(85, "x_vip_pxd[1]"),
+	PINCTRL_PIN(86, "x_vip_pxd[0]"),
+	PINCTRL_PIN(87, "x_vip_vsync"),
+	PINCTRL_PIN(88, "x_vip_hsync"),
+	PINCTRL_PIN(89, "x_vip_pxclk"),
+	PINCTRL_PIN(90, "x_sda_0"),
+	PINCTRL_PIN(91, "x_scl_0"),
+	PINCTRL_PIN(92, "x_df_ry_by"),
+	PINCTRL_PIN(93, "x_df_cs_b[1]"),
+	PINCTRL_PIN(94, "x_df_cs_b[0]"),
+	PINCTRL_PIN(95, "x_l_pclk"),
+
+	PINCTRL_PIN(96, "x_l_lck"),
+	PINCTRL_PIN(97, "x_l_fck"),
+	PINCTRL_PIN(98, "x_l_de"),
+	PINCTRL_PIN(99, "x_ldd[0]"),
+	PINCTRL_PIN(100, "x_ldd[1]"),
+	PINCTRL_PIN(101, "x_ldd[2]"),
+	PINCTRL_PIN(102, "x_ldd[3]"),
+	PINCTRL_PIN(103, "x_ldd[4]"),
+	PINCTRL_PIN(104, "x_ldd[5]"),
+	PINCTRL_PIN(105, "x_ldd[6]"),
+	PINCTRL_PIN(106, "x_ldd[7]"),
+	PINCTRL_PIN(107, "x_ldd[8]"),
+	PINCTRL_PIN(108, "x_ldd[9]"),
+	PINCTRL_PIN(109, "x_ldd[10]"),
+	PINCTRL_PIN(110, "x_ldd[11]"),
+	PINCTRL_PIN(111, "x_ldd[12]"),
+	PINCTRL_PIN(112, "x_ldd[13]"),
+	PINCTRL_PIN(113, "x_ldd[14]"),
+	PINCTRL_PIN(114, "x_ldd[15]"),
+};
+
+static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = {
+	{
+		.group = 3,
+		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) |
+			BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) |
+			BIT(17) | BIT(18),
+	}, {
+		.group = 2,
+		.mask = BIT(31),
+	},
+};
+
+static const struct sirfsoc_padmux lcd_16bits_padmux = {
+	.muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask),
+	.muxmask = lcd_16bits_sirfsoc_muxmask,
+	.funcmask = BIT(4),
+	.funcval = 0,
+};
+
+static const unsigned lcd_16bits_pins[] = { 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+	105, 106, 107, 108, 109, 110, 111, 112, 113, 114 };
+
+static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = {
+	{
+		.group = 3,
+		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) |
+			BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) |
+			BIT(17) | BIT(18),
+	}, {
+		.group = 2,
+		.mask = BIT(31),
+	}, {
+		.group = 0,
+		.mask = BIT(16) | BIT(17),
+	},
+};
+
+static const struct sirfsoc_padmux lcd_18bits_padmux = {
+	.muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask),
+	.muxmask = lcd_18bits_muxmask,
+	.funcmask = BIT(4),
+	.funcval = 0,
+};
+
+static const unsigned lcd_18bits_pins[] = { 16, 17, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+	105, 106, 107, 108, 109, 110, 111, 112, 113, 114};
+
+static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = {
+	{
+		.group = 3,
+		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) |
+			BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) |
+			BIT(17) | BIT(18),
+	}, {
+		.group = 2,
+		.mask = BIT(31),
+	}, {
+		.group = 0,
+		.mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23),
+	},
+};
+
+static const struct sirfsoc_padmux lcd_24bits_padmux = {
+	.muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask),
+	.muxmask = lcd_24bits_muxmask,
+	.funcmask = BIT(4),
+	.funcval = 0,
+};
+
+static const unsigned lcd_24bits_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+	105, 106, 107, 108, 109, 110, 111, 112, 113, 114 };
+
+static const struct sirfsoc_muxmask lcdrom_muxmask[] = {
+	{
+		.group = 3,
+		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) |
+			BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) |
+			BIT(17) | BIT(18),
+	}, {
+		.group = 2,
+		.mask = BIT(31),
+	}, {
+		.group = 0,
+		.mask = BIT(23),
+	},
+};
+
+static const struct sirfsoc_padmux lcdrom_padmux = {
+	.muxmask_counts = ARRAY_SIZE(lcdrom_muxmask),
+	.muxmask = lcdrom_muxmask,
+	.funcmask = BIT(4),
+	.funcval = BIT(4),
+};
+
+static const unsigned lcdrom_pins[] = { 23, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+	105, 106, 107, 108, 109, 110, 111, 112, 113, 114 };
+
+static const struct sirfsoc_muxmask uart0_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(4) | BIT(5),
+	}, {
+		.group = 1,
+		.mask = BIT(23) | BIT(28),
+	},
+};
+
+static const struct sirfsoc_padmux uart0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart0_muxmask),
+	.muxmask = uart0_muxmask,
+	.funcmask = BIT(9),
+	.funcval = BIT(9),
+};
+
+static const unsigned uart0_pins[] = { 55, 60, 68, 69 };
+
+static const struct sirfsoc_muxmask uart0_nostreamctrl_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(4) | BIT(5),
+	},
+};
+
+static const struct sirfsoc_padmux uart0_nostreamctrl_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask),
+	.muxmask = uart0_nostreamctrl_muxmask,
+};
+
+static const unsigned uart0_nostreamctrl_pins[] = { 68, 69 };
+
+static const struct sirfsoc_muxmask uart1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(15) | BIT(17),
+	},
+};
+
+static const struct sirfsoc_padmux uart1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart1_muxmask),
+	.muxmask = uart1_muxmask,
+};
+
+static const unsigned uart1_pins[] = { 47, 49 };
+
+static const struct sirfsoc_muxmask uart2_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(16) | BIT(18) | BIT(24) | BIT(27),
+	},
+};
+
+static const struct sirfsoc_padmux uart2_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart2_muxmask),
+	.muxmask = uart2_muxmask,
+	.funcmask = BIT(10),
+	.funcval = BIT(10),
+};
+
+static const unsigned uart2_pins[] = { 48, 50, 56, 59 };
+
+static const struct sirfsoc_muxmask uart2_nostreamctrl_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(16) | BIT(18),
+	},
+};
+
+static const struct sirfsoc_padmux uart2_nostreamctrl_padmux = {
+	.muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask),
+	.muxmask = uart2_nostreamctrl_muxmask,
+};
+
+static const unsigned uart2_nostreamctrl_pins[] = { 48, 50 };
+
+static const struct sirfsoc_muxmask sdmmc3_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(30) | BIT(31),
+	}, {
+		.group = 1,
+		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc3_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask),
+	.muxmask = sdmmc3_muxmask,
+	.funcmask = BIT(7),
+	.funcval = 0,
+};
+
+static const unsigned sdmmc3_pins[] = { 30, 31, 32, 33, 34, 35 };
+
+static const struct sirfsoc_muxmask spi0_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(0) | BIT(1) | BIT(2) | BIT(3),
+	},
+};
+
+static const struct sirfsoc_padmux spi0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(spi0_muxmask),
+	.muxmask = spi0_muxmask,
+	.funcmask = BIT(7),
+	.funcval = BIT(7),
+};
+
+static const unsigned spi0_pins[] = { 32, 33, 34, 35 };
+
+static const struct sirfsoc_muxmask sdmmc4_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc4_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc4_muxmask),
+	.muxmask = sdmmc4_muxmask,
+};
+
+static const unsigned sdmmc4_pins[] = { 36, 37, 38, 39, 40, 41 };
+
+static const struct sirfsoc_muxmask cko1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(10),
+	},
+};
+
+static const struct sirfsoc_padmux cko1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(cko1_muxmask),
+	.muxmask = cko1_muxmask,
+	.funcmask = BIT(3),
+	.funcval = 0,
+};
+
+static const unsigned cko1_pins[] = { 42 };
+
+static const struct sirfsoc_muxmask i2s_muxmask[] = {
+	{
+		.group = 1,
+		.mask =
+			BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(19)
+				| BIT(23) | BIT(28),
+	},
+};
+
+static const struct sirfsoc_padmux i2s_padmux = {
+	.muxmask_counts = ARRAY_SIZE(i2s_muxmask),
+	.muxmask = i2s_muxmask,
+	.funcmask = BIT(3) | BIT(9),
+	.funcval = BIT(3),
+};
+
+static const unsigned i2s_pins[] = { 42, 43, 44, 45, 46, 51, 55, 60 };
+
+static const struct sirfsoc_muxmask ac97_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
+	},
+};
+
+static const struct sirfsoc_padmux ac97_padmux = {
+	.muxmask_counts = ARRAY_SIZE(ac97_muxmask),
+	.muxmask = ac97_muxmask,
+	.funcmask = BIT(8),
+	.funcval = 0,
+};
+
+static const unsigned ac97_pins[] = { 33, 34, 35, 36 };
+
+static const struct sirfsoc_muxmask spi1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(11) | BIT(12) | BIT(13) | BIT(14),
+	},
+};
+
+static const struct sirfsoc_padmux spi1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(spi1_muxmask),
+	.muxmask = spi1_muxmask,
+	.funcmask = BIT(8),
+	.funcval = BIT(8),
+};
+
+static const unsigned spi1_pins[] = { 43, 44, 45, 46 };
+
+static const struct sirfsoc_muxmask sdmmc1_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(27) | BIT(28) | BIT(29),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask),
+	.muxmask = sdmmc1_muxmask,
+};
+
+static const unsigned sdmmc1_pins[] = { 27, 28, 29 };
+
+static const struct sirfsoc_muxmask gps_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(24) | BIT(25) | BIT(26),
+	},
+};
+
+static const struct sirfsoc_padmux gps_padmux = {
+	.muxmask_counts = ARRAY_SIZE(gps_muxmask),
+	.muxmask = gps_muxmask,
+	.funcmask = BIT(12) | BIT(13) | BIT(14),
+	.funcval = BIT(12),
+};
+
+static const unsigned gps_pins[] = { 24, 25, 26 };
+
+static const struct sirfsoc_muxmask sdmmc5_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(24) | BIT(25) | BIT(26),
+	}, {
+		.group = 1,
+		.mask = BIT(29),
+	}, {
+		.group = 2,
+		.mask = BIT(0) | BIT(1),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc5_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask),
+	.muxmask = sdmmc5_muxmask,
+	.funcmask = BIT(13) | BIT(14),
+	.funcval = BIT(13) | BIT(14),
+};
+
+static const unsigned sdmmc5_pins[] = { 24, 25, 26, 61, 64, 65 };
+
+static const struct sirfsoc_muxmask usp0_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23),
+	},
+};
+
+static const struct sirfsoc_padmux usp0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usp0_muxmask),
+	.muxmask = usp0_muxmask,
+	.funcmask = BIT(1) | BIT(2) | BIT(6) | BIT(9),
+	.funcval = 0,
+};
+
+static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 };
+
+static const struct sirfsoc_muxmask usp1_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28),
+	},
+};
+
+static const struct sirfsoc_padmux usp1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usp1_muxmask),
+	.muxmask = usp1_muxmask,
+	.funcmask = BIT(1) | BIT(9) | BIT(10) | BIT(11),
+	.funcval = 0,
+};
+
+static const unsigned usp1_pins[] = { 56, 57, 58, 59, 60 };
+
+static const struct sirfsoc_muxmask usp2_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(29) | BIT(30) | BIT(31),
+	}, {
+		.group = 2,
+		.mask = BIT(0) | BIT(1),
+	},
+};
+
+static const struct sirfsoc_padmux usp2_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usp2_muxmask),
+	.muxmask = usp2_muxmask,
+	.funcmask = BIT(13) | BIT(14),
+	.funcval = 0,
+};
+
+static const unsigned usp2_pins[] = { 61, 62, 63, 64, 65 };
+
+static const struct sirfsoc_muxmask nand_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(2) | BIT(3) | BIT(28) | BIT(29) | BIT(30),
+	},
+};
+
+static const struct sirfsoc_padmux nand_padmux = {
+	.muxmask_counts = ARRAY_SIZE(nand_muxmask),
+	.muxmask = nand_muxmask,
+	.funcmask = BIT(5),
+	.funcval = 0,
+};
+
+static const unsigned nand_pins[] = { 64, 65, 92, 93, 94 };
+
+static const struct sirfsoc_padmux sdmmc0_padmux = {
+	.muxmask_counts = 0,
+	.funcmask = BIT(5),
+	.funcval = 0,
+};
+
+static const unsigned sdmmc0_pins[] = { };
+
+static const struct sirfsoc_muxmask sdmmc2_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(2) | BIT(3),
+	},
+};
+
+static const struct sirfsoc_padmux sdmmc2_padmux = {
+	.muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask),
+	.muxmask = sdmmc2_muxmask,
+	.funcmask = BIT(5),
+	.funcval = BIT(5),
+};
+
+static const unsigned sdmmc2_pins[] = { 66, 67 };
+
+static const struct sirfsoc_muxmask cko0_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(14),
+	},
+};
+
+static const struct sirfsoc_padmux cko0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(cko0_muxmask),
+	.muxmask = cko0_muxmask,
+};
+
+static const unsigned cko0_pins[] = { 78 };
+
+static const struct sirfsoc_muxmask vip_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19)
+			| BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) |
+			BIT(25),
+	},
+};
+
+static const struct sirfsoc_padmux vip_padmux = {
+	.muxmask_counts = ARRAY_SIZE(vip_muxmask),
+	.muxmask = vip_muxmask,
+	.funcmask = BIT(0),
+	.funcval = 0,
+};
+
+static const unsigned vip_pins[] = { 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 };
+
+static const struct sirfsoc_muxmask i2c0_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(26) | BIT(27),
+	},
+};
+
+static const struct sirfsoc_padmux i2c0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(i2c0_muxmask),
+	.muxmask = i2c0_muxmask,
+};
+
+static const unsigned i2c0_pins[] = { 90, 91 };
+
+static const struct sirfsoc_muxmask i2c1_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(13) | BIT(15),
+	},
+};
+
+static const struct sirfsoc_padmux i2c1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(i2c1_muxmask),
+	.muxmask = i2c1_muxmask,
+};
+
+static const unsigned i2c1_pins[] = { 13, 15 };
+
+static const struct sirfsoc_muxmask viprom_muxmask[] = {
+	{
+		.group = 2,
+		.mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19)
+			| BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) |
+			BIT(25),
+	}, {
+		.group = 0,
+		.mask = BIT(12),
+	},
+};
+
+static const struct sirfsoc_padmux viprom_padmux = {
+	.muxmask_counts = ARRAY_SIZE(viprom_muxmask),
+	.muxmask = viprom_muxmask,
+	.funcmask = BIT(0),
+	.funcval = BIT(0),
+};
+
+static const unsigned viprom_pins[] = { 12, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 };
+
+static const struct sirfsoc_muxmask pwm0_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(4),
+	},
+};
+
+static const struct sirfsoc_padmux pwm0_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pwm0_muxmask),
+	.muxmask = pwm0_muxmask,
+	.funcmask = BIT(12),
+	.funcval = 0,
+};
+
+static const unsigned pwm0_pins[] = { 4 };
+
+static const struct sirfsoc_muxmask pwm1_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(5),
+	},
+};
+
+static const struct sirfsoc_padmux pwm1_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pwm1_muxmask),
+	.muxmask = pwm1_muxmask,
+};
+
+static const unsigned pwm1_pins[] = { 5 };
+
+static const struct sirfsoc_muxmask pwm2_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(6),
+	},
+};
+
+static const struct sirfsoc_padmux pwm2_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pwm2_muxmask),
+	.muxmask = pwm2_muxmask,
+};
+
+static const unsigned pwm2_pins[] = { 6 };
+
+static const struct sirfsoc_muxmask pwm3_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(7),
+	},
+};
+
+static const struct sirfsoc_padmux pwm3_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pwm3_muxmask),
+	.muxmask = pwm3_muxmask,
+};
+
+static const unsigned pwm3_pins[] = { 7 };
+
+static const struct sirfsoc_muxmask warm_rst_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(8),
+	},
+};
+
+static const struct sirfsoc_padmux warm_rst_padmux = {
+	.muxmask_counts = ARRAY_SIZE(warm_rst_muxmask),
+	.muxmask = warm_rst_muxmask,
+};
+
+static const unsigned warm_rst_pins[] = { 8 };
+
+static const struct sirfsoc_muxmask usb0_utmi_drvbus_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(22),
+	},
+};
+static const struct sirfsoc_padmux usb0_utmi_drvbus_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usb0_utmi_drvbus_muxmask),
+	.muxmask = usb0_utmi_drvbus_muxmask,
+	.funcmask = BIT(6),
+	.funcval = BIT(6), /* refer to PAD_UTMI_DRVVBUS0_ENABLE */
+};
+
+static const unsigned usb0_utmi_drvbus_pins[] = { 54 };
+
+static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = {
+	{
+		.group = 1,
+		.mask = BIT(27),
+	},
+};
+
+static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = {
+	.muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask),
+	.muxmask = usb1_utmi_drvbus_muxmask,
+	.funcmask = BIT(11),
+	.funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */
+};
+
+static const unsigned usb1_utmi_drvbus_pins[] = { 59 };
+
+static const struct sirfsoc_muxmask pulse_count_muxmask[] = {
+	{
+		.group = 0,
+		.mask = BIT(9) | BIT(10) | BIT(11),
+	},
+};
+
+static const struct sirfsoc_padmux pulse_count_padmux = {
+	.muxmask_counts = ARRAY_SIZE(pulse_count_muxmask),
+	.muxmask = pulse_count_muxmask,
+};
+
+static const unsigned pulse_count_pins[] = { 9, 10, 11 };
+
+static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = {
+	SIRFSOC_PIN_GROUP("lcd_16bitsgrp", lcd_16bits_pins),
+	SIRFSOC_PIN_GROUP("lcd_18bitsgrp", lcd_18bits_pins),
+	SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins),
+	SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins),
+	SIRFSOC_PIN_GROUP("uart0grp", uart0_pins),
+	SIRFSOC_PIN_GROUP("uart1grp", uart1_pins),
+	SIRFSOC_PIN_GROUP("uart2grp", uart2_pins),
+	SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins),
+	SIRFSOC_PIN_GROUP("usp0grp", usp0_pins),
+	SIRFSOC_PIN_GROUP("usp1grp", usp1_pins),
+	SIRFSOC_PIN_GROUP("usp2grp", usp2_pins),
+	SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins),
+	SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins),
+	SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins),
+	SIRFSOC_PIN_GROUP("pwm1grp", pwm1_pins),
+	SIRFSOC_PIN_GROUP("pwm2grp", pwm2_pins),
+	SIRFSOC_PIN_GROUP("pwm3grp", pwm3_pins),
+	SIRFSOC_PIN_GROUP("vipgrp", vip_pins),
+	SIRFSOC_PIN_GROUP("vipromgrp", viprom_pins),
+	SIRFSOC_PIN_GROUP("warm_rstgrp", warm_rst_pins),
+	SIRFSOC_PIN_GROUP("cko0grp", cko0_pins),
+	SIRFSOC_PIN_GROUP("cko1grp", cko1_pins),
+	SIRFSOC_PIN_GROUP("sdmmc0grp", sdmmc0_pins),
+	SIRFSOC_PIN_GROUP("sdmmc1grp", sdmmc1_pins),
+	SIRFSOC_PIN_GROUP("sdmmc2grp", sdmmc2_pins),
+	SIRFSOC_PIN_GROUP("sdmmc3grp", sdmmc3_pins),
+	SIRFSOC_PIN_GROUP("sdmmc4grp", sdmmc4_pins),
+	SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins),
+	SIRFSOC_PIN_GROUP("usb0_utmi_drvbusgrp", usb0_utmi_drvbus_pins),
+	SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins),
+	SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins),
+	SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins),
+	SIRFSOC_PIN_GROUP("ac97grp", ac97_pins),
+	SIRFSOC_PIN_GROUP("nandgrp", nand_pins),
+	SIRFSOC_PIN_GROUP("spi0grp", spi0_pins),
+	SIRFSOC_PIN_GROUP("spi1grp", spi1_pins),
+	SIRFSOC_PIN_GROUP("gpsgrp", gps_pins),
+};
+
+static const char * const lcd_16bitsgrp[] = { "lcd_16bitsgrp" };
+static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" };
+static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" };
+static const char * const lcdromgrp[] = { "lcdromgrp" };
+static const char * const uart0grp[] = { "uart0grp" };
+static const char * const uart1grp[] = { "uart1grp" };
+static const char * const uart2grp[] = { "uart2grp" };
+static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" };
+static const char * const usp0grp[] = { "usp0grp" };
+static const char * const usp1grp[] = { "usp1grp" };
+static const char * const usp2grp[] = { "usp2grp" };
+static const char * const i2c0grp[] = { "i2c0grp" };
+static const char * const i2c1grp[] = { "i2c1grp" };
+static const char * const pwm0grp[] = { "pwm0grp" };
+static const char * const pwm1grp[] = { "pwm1grp" };
+static const char * const pwm2grp[] = { "pwm2grp" };
+static const char * const pwm3grp[] = { "pwm3grp" };
+static const char * const vipgrp[] = { "vipgrp" };
+static const char * const vipromgrp[] = { "vipromgrp" };
+static const char * const warm_rstgrp[] = { "warm_rstgrp" };
+static const char * const cko0grp[] = { "cko0grp" };
+static const char * const cko1grp[] = { "cko1grp" };
+static const char * const sdmmc0grp[] = { "sdmmc0grp" };
+static const char * const sdmmc1grp[] = { "sdmmc1grp" };
+static const char * const sdmmc2grp[] = { "sdmmc2grp" };
+static const char * const sdmmc3grp[] = { "sdmmc3grp" };
+static const char * const sdmmc4grp[] = { "sdmmc4grp" };
+static const char * const sdmmc5grp[] = { "sdmmc5grp" };
+static const char * const usb0_utmi_drvbusgrp[] = { "usb0_utmi_drvbusgrp" };
+static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" };
+static const char * const pulse_countgrp[] = { "pulse_countgrp" };
+static const char * const i2sgrp[] = { "i2sgrp" };
+static const char * const ac97grp[] = { "ac97grp" };
+static const char * const nandgrp[] = { "nandgrp" };
+static const char * const spi0grp[] = { "spi0grp" };
+static const char * const spi1grp[] = { "spi1grp" };
+static const char * const gpsgrp[] = { "gpsgrp" };
+
+static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = {
+	SIRFSOC_PMX_FUNCTION("lcd_16bits", lcd_16bitsgrp, lcd_16bits_padmux),
+	SIRFSOC_PMX_FUNCTION("lcd_18bits", lcd_18bitsgrp, lcd_18bits_padmux),
+	SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux),
+	SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux),
+	SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux),
+	SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux),
+	SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux),
+	SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux),
+	SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux),
+	SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux),
+	SIRFSOC_PMX_FUNCTION("usp2", usp2grp, usp2_padmux),
+	SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux),
+	SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux),
+	SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux),
+	SIRFSOC_PMX_FUNCTION("pwm1", pwm1grp, pwm1_padmux),
+	SIRFSOC_PMX_FUNCTION("pwm2", pwm2grp, pwm2_padmux),
+	SIRFSOC_PMX_FUNCTION("pwm3", pwm3grp, pwm3_padmux),
+	SIRFSOC_PMX_FUNCTION("vip", vipgrp, vip_padmux),
+	SIRFSOC_PMX_FUNCTION("viprom", vipromgrp, viprom_padmux),
+	SIRFSOC_PMX_FUNCTION("warm_rst", warm_rstgrp, warm_rst_padmux),
+	SIRFSOC_PMX_FUNCTION("cko0", cko0grp, cko0_padmux),
+	SIRFSOC_PMX_FUNCTION("cko1", cko1grp, cko1_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc0", sdmmc0grp, sdmmc0_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc1", sdmmc1grp, sdmmc1_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc2", sdmmc2grp, sdmmc2_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc3", sdmmc3grp, sdmmc3_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc4", sdmmc4grp, sdmmc4_padmux),
+	SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux),
+	SIRFSOC_PMX_FUNCTION("usb0_utmi_drvbus", usb0_utmi_drvbusgrp, usb0_utmi_drvbus_padmux),
+	SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux),
+	SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux),
+	SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux),
+	SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux),
+	SIRFSOC_PMX_FUNCTION("nand", nandgrp, nand_padmux),
+	SIRFSOC_PMX_FUNCTION("spi0", spi0grp, spi0_padmux),
+	SIRFSOC_PMX_FUNCTION("spi1", spi1grp, spi1_padmux),
+	SIRFSOC_PMX_FUNCTION("gps", gpsgrp, gps_padmux),
+};
+
+struct sirfsoc_pinctrl_data prima2_pinctrl_data = {
+	(struct pinctrl_pin_desc *)sirfsoc_pads,
+	ARRAY_SIZE(sirfsoc_pads),
+	(struct sirfsoc_pin_group *)sirfsoc_pin_groups,
+	ARRAY_SIZE(sirfsoc_pin_groups),
+	(struct sirfsoc_pmx_func *)sirfsoc_pmx_functions,
+	ARRAY_SIZE(sirfsoc_pmx_functions),
+};
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sirf/pinctrl-sirf.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/pinctrl-sirf.c
--- linux-libre-3.10-gnu/drivers/pinctrl/sirf/pinctrl-sirf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/pinctrl-sirf.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,929 @@
+/*
+ * pinmux driver for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <asm/mach/irq.h>
+
+#include "pinctrl-sirf.h"
+
+#define DRIVER_NAME "pinmux-sirf"
+
+struct sirfsoc_gpio_bank {
+	struct of_mm_gpio_chip chip;
+	struct irq_domain *domain;
+	int id;
+	int parent_irq;
+	spinlock_t lock;
+	bool is_marco; /* for marco, some registers are different with prima2 */
+};
+
+static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS];
+static DEFINE_SPINLOCK(sgpio_lock);
+
+static struct sirfsoc_pin_group *sirfsoc_pin_groups;
+static int sirfsoc_pingrp_cnt;
+
+static int sirfsoc_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	return sirfsoc_pingrp_cnt;
+}
+
+static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev,
+				       unsigned selector)
+{
+	return sirfsoc_pin_groups[selector].name;
+}
+
+static int sirfsoc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
+			       const unsigned **pins,
+			       unsigned *num_pins)
+{
+	*pins = sirfsoc_pin_groups[selector].pins;
+	*num_pins = sirfsoc_pin_groups[selector].num_pins;
+	return 0;
+}
+
+static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+		   unsigned offset)
+{
+	seq_printf(s, " " DRIVER_NAME);
+}
+
+static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev,
+				 struct device_node *np_config,
+				 struct pinctrl_map **map, unsigned *num_maps)
+{
+	struct sirfsoc_pmx *spmx = pinctrl_dev_get_drvdata(pctldev);
+	struct device_node *np;
+	struct property *prop;
+	const char *function, *group;
+	int ret, index = 0, count = 0;
+
+	/* calculate number of maps required */
+	for_each_child_of_node(np_config, np) {
+		ret = of_property_read_string(np, "sirf,function", &function);
+		if (ret < 0)
+			return ret;
+
+		ret = of_property_count_strings(np, "sirf,pins");
+		if (ret < 0)
+			return ret;
+
+		count += ret;
+	}
+
+	if (!count) {
+		dev_err(spmx->dev, "No child nodes passed via DT\n");
+		return -ENODEV;
+	}
+
+	*map = kzalloc(sizeof(**map) * count, GFP_KERNEL);
+	if (!*map)
+		return -ENOMEM;
+
+	for_each_child_of_node(np_config, np) {
+		of_property_read_string(np, "sirf,function", &function);
+		of_property_for_each_string(np, "sirf,pins", prop, group) {
+			(*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
+			(*map)[index].data.mux.group = group;
+			(*map)[index].data.mux.function = function;
+			index++;
+		}
+	}
+
+	*num_maps = count;
+
+	return 0;
+}
+
+static void sirfsoc_dt_free_map(struct pinctrl_dev *pctldev,
+		struct pinctrl_map *map, unsigned num_maps)
+{
+	kfree(map);
+}
+
+static struct pinctrl_ops sirfsoc_pctrl_ops = {
+	.get_groups_count = sirfsoc_get_groups_count,
+	.get_group_name = sirfsoc_get_group_name,
+	.get_group_pins = sirfsoc_get_group_pins,
+	.pin_dbg_show = sirfsoc_pin_dbg_show,
+	.dt_node_to_map = sirfsoc_dt_node_to_map,
+	.dt_free_map = sirfsoc_dt_free_map,
+};
+
+static struct sirfsoc_pmx_func *sirfsoc_pmx_functions;
+static int sirfsoc_pmxfunc_cnt;
+
+static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector,
+	bool enable)
+{
+	int i;
+	const struct sirfsoc_padmux *mux = sirfsoc_pmx_functions[selector].padmux;
+	const struct sirfsoc_muxmask *mask = mux->muxmask;
+
+	for (i = 0; i < mux->muxmask_counts; i++) {
+		u32 muxval;
+		if (!spmx->is_marco) {
+			muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+			if (enable)
+				muxval = muxval & ~mask[i].mask;
+			else
+				muxval = muxval | mask[i].mask;
+			writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group));
+		} else {
+			if (enable)
+				writel(mask[i].mask, spmx->gpio_virtbase +
+					SIRFSOC_GPIO_PAD_EN_CLR(mask[i].group));
+			else
+				writel(mask[i].mask, spmx->gpio_virtbase +
+					SIRFSOC_GPIO_PAD_EN(mask[i].group));
+		}
+	}
+
+	if (mux->funcmask && enable) {
+		u32 func_en_val;
+		func_en_val =
+			readl(spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX);
+		func_en_val =
+			(func_en_val & ~mux->funcmask) | (mux->
+				funcval);
+		writel(func_en_val, spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX);
+	}
+}
+
+static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector,
+	unsigned group)
+{
+	struct sirfsoc_pmx *spmx;
+
+	spmx = pinctrl_dev_get_drvdata(pmxdev);
+	sirfsoc_pinmux_endisable(spmx, selector, true);
+
+	return 0;
+}
+
+static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector,
+	unsigned group)
+{
+	struct sirfsoc_pmx *spmx;
+
+	spmx = pinctrl_dev_get_drvdata(pmxdev);
+	sirfsoc_pinmux_endisable(spmx, selector, false);
+}
+
+static int sirfsoc_pinmux_get_funcs_count(struct pinctrl_dev *pmxdev)
+{
+	return sirfsoc_pmxfunc_cnt;
+}
+
+static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev,
+					  unsigned selector)
+{
+	return sirfsoc_pmx_functions[selector].name;
+}
+
+static int sirfsoc_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
+			       const char * const **groups,
+			       unsigned * const num_groups)
+{
+	*groups = sirfsoc_pmx_functions[selector].groups;
+	*num_groups = sirfsoc_pmx_functions[selector].num_groups;
+	return 0;
+}
+
+static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev,
+	struct pinctrl_gpio_range *range, unsigned offset)
+{
+	struct sirfsoc_pmx *spmx;
+
+	int group = range->id;
+
+	u32 muxval;
+
+	spmx = pinctrl_dev_get_drvdata(pmxdev);
+
+	if (!spmx->is_marco) {
+		muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+		muxval = muxval | (1 << (offset - range->pin_base));
+		writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group));
+	} else {
+		writel(1 << (offset - range->pin_base), spmx->gpio_virtbase +
+			SIRFSOC_GPIO_PAD_EN(group));
+	}
+
+	return 0;
+}
+
+static struct pinmux_ops sirfsoc_pinmux_ops = {
+	.enable = sirfsoc_pinmux_enable,
+	.disable = sirfsoc_pinmux_disable,
+	.get_functions_count = sirfsoc_pinmux_get_funcs_count,
+	.get_function_name = sirfsoc_pinmux_get_func_name,
+	.get_function_groups = sirfsoc_pinmux_get_groups,
+	.gpio_request_enable = sirfsoc_pinmux_request_gpio,
+};
+
+static struct pinctrl_desc sirfsoc_pinmux_desc = {
+	.name = DRIVER_NAME,
+	.pctlops = &sirfsoc_pctrl_ops,
+	.pmxops = &sirfsoc_pinmux_ops,
+	.owner = THIS_MODULE,
+};
+
+/*
+ * Todo: bind irq_chip to every pinctrl_gpio_range
+ */
+static struct pinctrl_gpio_range sirfsoc_gpio_ranges[] = {
+	{
+		.name = "sirfsoc-gpio*",
+		.id = 0,
+		.base = 0,
+		.pin_base = 0,
+		.npins = 32,
+	}, {
+		.name = "sirfsoc-gpio*",
+		.id = 1,
+		.base = 32,
+		.pin_base = 32,
+		.npins = 32,
+	}, {
+		.name = "sirfsoc-gpio*",
+		.id = 2,
+		.base = 64,
+		.pin_base = 64,
+		.npins = 32,
+	}, {
+		.name = "sirfsoc-gpio*",
+		.id = 3,
+		.base = 96,
+		.pin_base = 96,
+		.npins = 19,
+	},
+};
+
+static void __iomem *sirfsoc_rsc_of_iomap(void)
+{
+	const struct of_device_id rsc_ids[]  = {
+		{ .compatible = "sirf,prima2-rsc" },
+		{ .compatible = "sirf,marco-rsc" },
+		{}
+	};
+	struct device_node *np;
+
+	np = of_find_matching_node(NULL, rsc_ids);
+	if (!np)
+		panic("unable to find compatible rsc node in dtb\n");
+
+	return of_iomap(np, 0);
+}
+
+static int sirfsoc_gpio_of_xlate(struct gpio_chip *gc,
+       const struct of_phandle_args *gpiospec,
+       u32 *flags)
+{
+       if (gpiospec->args[0] > SIRFSOC_GPIO_NO_OF_BANKS * SIRFSOC_GPIO_BANK_SIZE)
+               return -EINVAL;
+
+       if (gc != &sgpio_bank[gpiospec->args[0] / SIRFSOC_GPIO_BANK_SIZE].chip.gc)
+               return -EINVAL;
+
+       if (flags)
+               *flags = gpiospec->args[1];
+
+       return gpiospec->args[0] % SIRFSOC_GPIO_BANK_SIZE;
+}
+
+static const struct of_device_id pinmux_ids[] = {
+	{ .compatible = "sirf,prima2-pinctrl", .data = &prima2_pinctrl_data, },
+	{ .compatible = "sirf,atlas6-pinctrl", .data = &atlas6_pinctrl_data, },
+	{ .compatible = "sirf,marco-pinctrl", .data = &prima2_pinctrl_data, },
+	{}
+};
+
+static int sirfsoc_pinmux_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct sirfsoc_pmx *spmx;
+	struct device_node *np = pdev->dev.of_node;
+	const struct sirfsoc_pinctrl_data *pdata;
+	int i;
+
+	/* Create state holders etc for this driver */
+	spmx = devm_kzalloc(&pdev->dev, sizeof(*spmx), GFP_KERNEL);
+	if (!spmx)
+		return -ENOMEM;
+
+	spmx->dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, spmx);
+
+	spmx->gpio_virtbase = of_iomap(np, 0);
+	if (!spmx->gpio_virtbase) {
+		dev_err(&pdev->dev, "can't map gpio registers\n");
+		return -ENOMEM;
+	}
+
+	spmx->rsc_virtbase = sirfsoc_rsc_of_iomap();
+	if (!spmx->rsc_virtbase) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "can't map rsc registers\n");
+		goto out_no_rsc_remap;
+	}
+
+	if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
+		spmx->is_marco = 1;
+
+	pdata = of_match_node(pinmux_ids, np)->data;
+	sirfsoc_pin_groups = pdata->grps;
+	sirfsoc_pingrp_cnt = pdata->grps_cnt;
+	sirfsoc_pmx_functions = pdata->funcs;
+	sirfsoc_pmxfunc_cnt = pdata->funcs_cnt;
+	sirfsoc_pinmux_desc.pins = pdata->pads;
+	sirfsoc_pinmux_desc.npins = pdata->pads_cnt;
+
+
+	/* Now register the pin controller and all pins it handles */
+	spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx);
+	if (!spmx->pmx) {
+		dev_err(&pdev->dev, "could not register SIRFSOC pinmux driver\n");
+		ret = -EINVAL;
+		goto out_no_pmx;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sirfsoc_gpio_ranges); i++) {
+		sirfsoc_gpio_ranges[i].gc = &sgpio_bank[i].chip.gc;
+		pinctrl_add_gpio_range(spmx->pmx, &sirfsoc_gpio_ranges[i]);
+	}
+
+	dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n");
+
+	return 0;
+
+out_no_pmx:
+	iounmap(spmx->rsc_virtbase);
+out_no_rsc_remap:
+	iounmap(spmx->gpio_virtbase);
+	return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sirfsoc_pinmux_suspend_noirq(struct device *dev)
+{
+	int i, j;
+	struct sirfsoc_pmx *spmx = dev_get_drvdata(dev);
+
+	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
+		for (j = 0; j < SIRFSOC_GPIO_BANK_SIZE; j++) {
+			spmx->gpio_regs[i][j] = readl(spmx->gpio_virtbase +
+				SIRFSOC_GPIO_CTRL(i, j));
+		}
+		spmx->ints_regs[i] = readl(spmx->gpio_virtbase +
+			SIRFSOC_GPIO_INT_STATUS(i));
+		spmx->paden_regs[i] = readl(spmx->gpio_virtbase +
+			SIRFSOC_GPIO_PAD_EN(i));
+	}
+	spmx->dspen_regs = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_DSP_EN0);
+
+	for (i = 0; i < 3; i++)
+		spmx->rsc_regs[i] = readl(spmx->rsc_virtbase + 4 * i);
+
+	return 0;
+}
+
+static int sirfsoc_pinmux_resume_noirq(struct device *dev)
+{
+	int i, j;
+	struct sirfsoc_pmx *spmx = dev_get_drvdata(dev);
+
+	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
+		for (j = 0; j < SIRFSOC_GPIO_BANK_SIZE; j++) {
+			writel(spmx->gpio_regs[i][j], spmx->gpio_virtbase +
+				SIRFSOC_GPIO_CTRL(i, j));
+		}
+		writel(spmx->ints_regs[i], spmx->gpio_virtbase +
+			SIRFSOC_GPIO_INT_STATUS(i));
+		writel(spmx->paden_regs[i], spmx->gpio_virtbase +
+			SIRFSOC_GPIO_PAD_EN(i));
+	}
+	writel(spmx->dspen_regs, spmx->gpio_virtbase + SIRFSOC_GPIO_DSP_EN0);
+
+	for (i = 0; i < 3; i++)
+		writel(spmx->rsc_regs[i], spmx->rsc_virtbase + 4 * i);
+
+	return 0;
+}
+
+static const struct dev_pm_ops sirfsoc_pinmux_pm_ops = {
+	.suspend_noirq = sirfsoc_pinmux_suspend_noirq,
+	.resume_noirq = sirfsoc_pinmux_resume_noirq,
+};
+#endif
+
+static struct platform_driver sirfsoc_pinmux_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = pinmux_ids,
+#ifdef CONFIG_PM_SLEEP
+		.pm = &sirfsoc_pinmux_pm_ops,
+#endif
+	},
+	.probe = sirfsoc_pinmux_probe,
+};
+
+static int __init sirfsoc_pinmux_init(void)
+{
+	return platform_driver_register(&sirfsoc_pinmux_driver);
+}
+arch_initcall(sirfsoc_pinmux_init);
+
+static inline int sirfsoc_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct sirfsoc_gpio_bank *bank = container_of(to_of_mm_gpio_chip(chip),
+		struct sirfsoc_gpio_bank, chip);
+
+	return irq_create_mapping(bank->domain, offset);
+}
+
+static inline int sirfsoc_gpio_to_offset(unsigned int gpio)
+{
+	return gpio % SIRFSOC_GPIO_BANK_SIZE;
+}
+
+static inline struct sirfsoc_gpio_bank *sirfsoc_gpio_to_bank(unsigned int gpio)
+{
+	return &sgpio_bank[gpio / SIRFSOC_GPIO_BANK_SIZE];
+}
+
+static inline struct sirfsoc_gpio_bank *sirfsoc_irqchip_to_bank(struct gpio_chip *chip)
+{
+	return container_of(to_of_mm_gpio_chip(chip), struct sirfsoc_gpio_bank, chip);
+}
+
+static void sirfsoc_gpio_irq_ack(struct irq_data *d)
+{
+	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+	int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE;
+	u32 val, offset;
+	unsigned long flags;
+
+	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
+
+	spin_lock_irqsave(&sgpio_lock, flags);
+
+	val = readl(bank->chip.regs + offset);
+
+	writel(val, bank->chip.regs + offset);
+
+	spin_unlock_irqrestore(&sgpio_lock, flags);
+}
+
+static void __sirfsoc_gpio_irq_mask(struct sirfsoc_gpio_bank *bank, int idx)
+{
+	u32 val, offset;
+	unsigned long flags;
+
+	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
+
+	spin_lock_irqsave(&sgpio_lock, flags);
+
+	val = readl(bank->chip.regs + offset);
+	val &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK;
+	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
+	writel(val, bank->chip.regs + offset);
+
+	spin_unlock_irqrestore(&sgpio_lock, flags);
+}
+
+static void sirfsoc_gpio_irq_mask(struct irq_data *d)
+{
+	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+
+	__sirfsoc_gpio_irq_mask(bank, d->hwirq % SIRFSOC_GPIO_BANK_SIZE);
+}
+
+static void sirfsoc_gpio_irq_unmask(struct irq_data *d)
+{
+	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+	int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE;
+	u32 val, offset;
+	unsigned long flags;
+
+	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
+
+	spin_lock_irqsave(&sgpio_lock, flags);
+
+	val = readl(bank->chip.regs + offset);
+	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
+	val |= SIRFSOC_GPIO_CTL_INTR_EN_MASK;
+	writel(val, bank->chip.regs + offset);
+
+	spin_unlock_irqrestore(&sgpio_lock, flags);
+}
+
+static int sirfsoc_gpio_irq_type(struct irq_data *d, unsigned type)
+{
+	struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+	int idx = d->hwirq % SIRFSOC_GPIO_BANK_SIZE;
+	u32 val, offset;
+	unsigned long flags;
+
+	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
+
+	spin_lock_irqsave(&sgpio_lock, flags);
+
+	val = readl(bank->chip.regs + offset);
+	val &= ~SIRFSOC_GPIO_CTL_INTR_STS_MASK;
+
+	switch (type) {
+	case IRQ_TYPE_NONE:
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK;
+		val &= ~SIRFSOC_GPIO_CTL_INTR_LOW_MASK;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		val &= ~SIRFSOC_GPIO_CTL_INTR_HIGH_MASK;
+		val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | SIRFSOC_GPIO_CTL_INTR_LOW_MASK |
+			 SIRFSOC_GPIO_CTL_INTR_TYPE_MASK;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		val &= ~(SIRFSOC_GPIO_CTL_INTR_HIGH_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
+		val |= SIRFSOC_GPIO_CTL_INTR_LOW_MASK;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		val |= SIRFSOC_GPIO_CTL_INTR_HIGH_MASK;
+		val &= ~(SIRFSOC_GPIO_CTL_INTR_LOW_MASK | SIRFSOC_GPIO_CTL_INTR_TYPE_MASK);
+		break;
+	}
+
+	writel(val, bank->chip.regs + offset);
+
+	spin_unlock_irqrestore(&sgpio_lock, flags);
+
+	return 0;
+}
+
+static struct irq_chip sirfsoc_irq_chip = {
+	.name = "sirf-gpio-irq",
+	.irq_ack = sirfsoc_gpio_irq_ack,
+	.irq_mask = sirfsoc_gpio_irq_mask,
+	.irq_unmask = sirfsoc_gpio_irq_unmask,
+	.irq_set_type = sirfsoc_gpio_irq_type,
+};
+
+static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc)
+{
+	struct sirfsoc_gpio_bank *bank = irq_get_handler_data(irq);
+	u32 status, ctrl;
+	int idx = 0;
+	struct irq_chip *chip = irq_get_chip(irq);
+
+	chained_irq_enter(chip, desc);
+
+	status = readl(bank->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id));
+	if (!status) {
+		printk(KERN_WARNING
+			"%s: gpio id %d status %#x no interrupt is flaged\n",
+			__func__, bank->id, status);
+		handle_bad_irq(irq, desc);
+		return;
+	}
+
+	while (status) {
+		ctrl = readl(bank->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, idx));
+
+		/*
+		 * Here we must check whether the corresponding GPIO's interrupt
+		 * has been enabled, otherwise just skip it
+		 */
+		if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) {
+			pr_debug("%s: gpio id %d idx %d happens\n",
+				__func__, bank->id, idx);
+			generic_handle_irq(irq_find_mapping(bank->domain, idx));
+		}
+
+		idx++;
+		status = status >> 1;
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_bank *bank, unsigned ctrl_offset)
+{
+	u32 val;
+
+	val = readl(bank->chip.regs + ctrl_offset);
+	val &= ~SIRFSOC_GPIO_CTL_OUT_EN_MASK;
+	writel(val, bank->chip.regs + ctrl_offset);
+}
+
+static int sirfsoc_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
+	unsigned long flags;
+
+	if (pinctrl_request_gpio(chip->base + offset))
+		return -ENODEV;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	/*
+	 * default status:
+	 * set direction as input and mask irq
+	 */
+	sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->id, offset));
+	__sirfsoc_gpio_irq_mask(bank, offset);
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static void sirfsoc_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	__sirfsoc_gpio_irq_mask(bank, offset);
+	sirfsoc_gpio_set_input(bank, SIRFSOC_GPIO_CTRL(bank->id, offset));
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	pinctrl_free_gpio(chip->base + offset);
+}
+
+static int sirfsoc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
+	int idx = sirfsoc_gpio_to_offset(gpio);
+	unsigned long flags;
+	unsigned offset;
+
+	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	sirfsoc_gpio_set_input(bank, offset);
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static inline void sirfsoc_gpio_set_output(struct sirfsoc_gpio_bank *bank, unsigned offset,
+	int value)
+{
+	u32 out_ctrl;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	out_ctrl = readl(bank->chip.regs + offset);
+	if (value)
+		out_ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK;
+	else
+		out_ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK;
+
+	out_ctrl &= ~SIRFSOC_GPIO_CTL_INTR_EN_MASK;
+	out_ctrl |= SIRFSOC_GPIO_CTL_OUT_EN_MASK;
+	writel(out_ctrl, bank->chip.regs + offset);
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+}
+
+static int sirfsoc_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value)
+{
+	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
+	int idx = sirfsoc_gpio_to_offset(gpio);
+	u32 offset;
+	unsigned long flags;
+
+	offset = SIRFSOC_GPIO_CTRL(bank->id, idx);
+
+	spin_lock_irqsave(&sgpio_lock, flags);
+
+	sirfsoc_gpio_set_output(bank, offset, value);
+
+	spin_unlock_irqrestore(&sgpio_lock, flags);
+
+	return 0;
+}
+
+static int sirfsoc_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
+	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	val = readl(bank->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset));
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return !!(val & SIRFSOC_GPIO_CTL_DATAIN_MASK);
+}
+
+static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset,
+	int value)
+{
+	struct sirfsoc_gpio_bank *bank = sirfsoc_irqchip_to_bank(chip);
+	u32 ctrl;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	ctrl = readl(bank->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset));
+	if (value)
+		ctrl |= SIRFSOC_GPIO_CTL_DATAOUT_MASK;
+	else
+		ctrl &= ~SIRFSOC_GPIO_CTL_DATAOUT_MASK;
+	writel(ctrl, bank->chip.regs + SIRFSOC_GPIO_CTRL(bank->id, offset));
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+}
+
+static int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+				irq_hw_number_t hwirq)
+{
+	struct sirfsoc_gpio_bank *bank = d->host_data;
+
+	if (!bank)
+		return -EINVAL;
+
+	irq_set_chip(irq, &sirfsoc_irq_chip);
+	irq_set_handler(irq, handle_level_irq);
+	irq_set_chip_data(irq, bank);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static const struct irq_domain_ops sirfsoc_gpio_irq_simple_ops = {
+	.map = sirfsoc_gpio_irq_map,
+	.xlate = irq_domain_xlate_twocell,
+};
+
+static void sirfsoc_gpio_set_pullup(const u32 *pullups)
+{
+	int i, n;
+	const unsigned long *p = (const unsigned long *)pullups;
+
+	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
+		for_each_set_bit(n, p + i, BITS_PER_LONG) {
+			u32 offset = SIRFSOC_GPIO_CTRL(i, n);
+			u32 val = readl(sgpio_bank[i].chip.regs + offset);
+			val |= SIRFSOC_GPIO_CTL_PULL_MASK;
+			val |= SIRFSOC_GPIO_CTL_PULL_HIGH;
+			writel(val, sgpio_bank[i].chip.regs + offset);
+		}
+	}
+}
+
+static void sirfsoc_gpio_set_pulldown(const u32 *pulldowns)
+{
+	int i, n;
+	const unsigned long *p = (const unsigned long *)pulldowns;
+
+	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
+		for_each_set_bit(n, p + i, BITS_PER_LONG) {
+			u32 offset = SIRFSOC_GPIO_CTRL(i, n);
+			u32 val = readl(sgpio_bank[i].chip.regs + offset);
+			val |= SIRFSOC_GPIO_CTL_PULL_MASK;
+			val &= ~SIRFSOC_GPIO_CTL_PULL_HIGH;
+			writel(val, sgpio_bank[i].chip.regs + offset);
+		}
+	}
+}
+
+static int sirfsoc_gpio_probe(struct device_node *np)
+{
+	int i, err = 0;
+	struct sirfsoc_gpio_bank *bank;
+	void *regs;
+	struct platform_device *pdev;
+	bool is_marco = false;
+
+	u32 pullups[SIRFSOC_GPIO_NO_OF_BANKS], pulldowns[SIRFSOC_GPIO_NO_OF_BANKS];
+
+	pdev = of_find_device_by_node(np);
+	if (!pdev)
+		return -ENODEV;
+
+	regs = of_iomap(np, 0);
+	if (!regs)
+		return -ENOMEM;
+
+	if (of_device_is_compatible(np, "sirf,marco-pinctrl"))
+		is_marco = 1;
+
+	for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) {
+		bank = &sgpio_bank[i];
+		spin_lock_init(&bank->lock);
+		bank->chip.gc.request = sirfsoc_gpio_request;
+		bank->chip.gc.free = sirfsoc_gpio_free;
+		bank->chip.gc.direction_input = sirfsoc_gpio_direction_input;
+		bank->chip.gc.get = sirfsoc_gpio_get_value;
+		bank->chip.gc.direction_output = sirfsoc_gpio_direction_output;
+		bank->chip.gc.set = sirfsoc_gpio_set_value;
+		bank->chip.gc.to_irq = sirfsoc_gpio_to_irq;
+		bank->chip.gc.base = i * SIRFSOC_GPIO_BANK_SIZE;
+		bank->chip.gc.ngpio = SIRFSOC_GPIO_BANK_SIZE;
+		bank->chip.gc.label = kstrdup(np->full_name, GFP_KERNEL);
+		bank->chip.gc.of_node = np;
+		bank->chip.gc.of_xlate = sirfsoc_gpio_of_xlate;
+		bank->chip.gc.of_gpio_n_cells = 2;
+		bank->chip.regs = regs;
+		bank->id = i;
+		bank->is_marco = is_marco;
+		bank->parent_irq = platform_get_irq(pdev, i);
+		if (bank->parent_irq < 0) {
+			err = bank->parent_irq;
+			goto out;
+		}
+
+		err = gpiochip_add(&bank->chip.gc);
+		if (err) {
+			pr_err("%s: error in probe function with status %d\n",
+				np->full_name, err);
+			goto out;
+		}
+
+		bank->domain = irq_domain_add_linear(np, SIRFSOC_GPIO_BANK_SIZE,
+						&sirfsoc_gpio_irq_simple_ops, bank);
+
+		if (!bank->domain) {
+			pr_err("%s: Failed to create irqdomain\n", np->full_name);
+			err = -ENOSYS;
+			goto out;
+		}
+
+		irq_set_chained_handler(bank->parent_irq, sirfsoc_gpio_handle_irq);
+		irq_set_handler_data(bank->parent_irq, bank);
+	}
+
+	if (!of_property_read_u32_array(np, "sirf,pullups", pullups,
+		SIRFSOC_GPIO_NO_OF_BANKS))
+		sirfsoc_gpio_set_pullup(pullups);
+
+	if (!of_property_read_u32_array(np, "sirf,pulldowns", pulldowns,
+		SIRFSOC_GPIO_NO_OF_BANKS))
+		sirfsoc_gpio_set_pulldown(pulldowns);
+
+	return 0;
+
+out:
+	iounmap(regs);
+	return err;
+}
+
+static int __init sirfsoc_gpio_init(void)
+{
+
+	struct device_node *np;
+
+	np = of_find_matching_node(NULL, pinmux_ids);
+
+	if (!np)
+		return -ENODEV;
+
+	return sirfsoc_gpio_probe(np);
+}
+subsys_initcall(sirfsoc_gpio_init);
+
+MODULE_AUTHOR("Rongjun Ying <rongjun.ying@csr.com>, "
+	"Yuping Luo <yuping.luo@csr.com>, "
+	"Barry Song <baohua.song@csr.com>");
+MODULE_DESCRIPTION("SIRFSOC pin control driver");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/sirf/pinctrl-sirf.h linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/pinctrl-sirf.h
--- linux-libre-3.10-gnu/drivers/pinctrl/sirf/pinctrl-sirf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/sirf/pinctrl-sirf.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * pinmux driver shared headfile for CSR SiRFsoc
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef __PINMUX_SIRF_H__
+#define __PINMUX_SIRF_H__
+
+#define SIRFSOC_NUM_PADS    622
+#define SIRFSOC_RSC_PIN_MUX 0x4
+
+#define SIRFSOC_GPIO_PAD_EN(g)		((g)*0x100 + 0x84)
+#define SIRFSOC_GPIO_PAD_EN_CLR(g)	((g)*0x100 + 0x90)
+#define SIRFSOC_GPIO_CTRL(g, i)			((g)*0x100 + (i)*4)
+#define SIRFSOC_GPIO_DSP_EN0			(0x80)
+#define SIRFSOC_GPIO_INT_STATUS(g)		((g)*0x100 + 0x8C)
+
+#define SIRFSOC_GPIO_CTL_INTR_LOW_MASK		0x1
+#define SIRFSOC_GPIO_CTL_INTR_HIGH_MASK		0x2
+#define SIRFSOC_GPIO_CTL_INTR_TYPE_MASK		0x4
+#define SIRFSOC_GPIO_CTL_INTR_EN_MASK		0x8
+#define SIRFSOC_GPIO_CTL_INTR_STS_MASK		0x10
+#define SIRFSOC_GPIO_CTL_OUT_EN_MASK		0x20
+#define SIRFSOC_GPIO_CTL_DATAOUT_MASK		0x40
+#define SIRFSOC_GPIO_CTL_DATAIN_MASK		0x80
+#define SIRFSOC_GPIO_CTL_PULL_MASK		0x100
+#define SIRFSOC_GPIO_CTL_PULL_HIGH		0x200
+#define SIRFSOC_GPIO_CTL_DSP_INT		0x400
+
+#define SIRFSOC_GPIO_NO_OF_BANKS        5
+#define SIRFSOC_GPIO_BANK_SIZE          32
+#define SIRFSOC_GPIO_NUM(bank, index)	(((bank)*(32)) + (index))
+
+/**
+ * @dev: a pointer back to containing device
+ * @virtbase: the offset to the controller in virtual memory
+ */
+struct sirfsoc_pmx {
+	struct device *dev;
+	struct pinctrl_dev *pmx;
+	void __iomem *gpio_virtbase;
+	void __iomem *rsc_virtbase;
+	u32 gpio_regs[SIRFSOC_GPIO_NO_OF_BANKS][SIRFSOC_GPIO_BANK_SIZE];
+	u32 ints_regs[SIRFSOC_GPIO_NO_OF_BANKS];
+	u32 paden_regs[SIRFSOC_GPIO_NO_OF_BANKS];
+	u32 dspen_regs;
+	u32 rsc_regs[3];
+	bool is_marco;
+};
+
+/* SIRFSOC_GPIO_PAD_EN set */
+struct sirfsoc_muxmask {
+	unsigned long group;
+	unsigned long mask;
+};
+
+struct sirfsoc_padmux {
+	unsigned long muxmask_counts;
+	const struct sirfsoc_muxmask *muxmask;
+	/* RSC_PIN_MUX set */
+	unsigned long funcmask;
+	unsigned long funcval;
+};
+
+ /**
+ * struct sirfsoc_pin_group - describes a SiRFprimaII pin group
+ * @name: the name of this specific pin group
+ * @pins: an array of discrete physical pins used in this group, taken
+ *	from the driver-local pin enumeration space
+ * @num_pins: the number of pins in this group array, i.e. the number of
+ *	elements in .pins so we can iterate over that array
+ */
+struct sirfsoc_pin_group {
+	const char *name;
+	const unsigned int *pins;
+	const unsigned num_pins;
+};
+
+#define SIRFSOC_PIN_GROUP(n, p)  \
+	{			\
+		.name = n,	\
+		.pins = p,	\
+		.num_pins = ARRAY_SIZE(p),	\
+	}
+
+struct sirfsoc_pmx_func {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+	const struct sirfsoc_padmux *padmux;
+};
+
+#define SIRFSOC_PMX_FUNCTION(n, g, m)		\
+	{					\
+		.name = n,			\
+		.groups = g,			\
+		.num_groups = ARRAY_SIZE(g),	\
+		.padmux = &m,			\
+	}
+
+struct sirfsoc_pinctrl_data {
+	struct pinctrl_pin_desc *pads;
+	int pads_cnt;
+	struct sirfsoc_pin_group *grps;
+	int grps_cnt;
+	struct sirfsoc_pmx_func *funcs;
+	int funcs_cnt;
+};
+
+extern struct sirfsoc_pinctrl_data prima2_pinctrl_data;
+extern struct sirfsoc_pinctrl_data atlas6_pinctrl_data;
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/spear/pinctrl-plgpio.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/spear/pinctrl-plgpio.c
--- linux-libre-3.10-gnu/drivers/pinctrl/spear/pinctrl-plgpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/spear/pinctrl-plgpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -441,7 +441,7 @@ static int spear310_p2o(int pin)
 	return offset;
 }
 
-int spear310_o2p(int offset)
+static int spear310_o2p(int offset)
 {
 	if (offset <= 3)
 		return 101 - offset;
@@ -528,18 +528,13 @@ static int plgpio_probe(struct platform_
 	struct resource *res;
 	int ret, irq, i;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n");
-		return -EBUSY;
-	}
-
 	plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL);
 	if (!plgpio) {
 		dev_err(&pdev->dev, "memory allocation fail\n");
 		return -ENOMEM;
 	}
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	plgpio->base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(plgpio->base))
 		return PTR_ERR(plgpio->base);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pinctrl/vt8500/pinctrl-wmt.c linux-libre-3.11-rc7-gnu/drivers/pinctrl/vt8500/pinctrl-wmt.c
--- linux-libre-3.10-gnu/drivers/pinctrl/vt8500/pinctrl-wmt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pinctrl/vt8500/pinctrl-wmt.c	2013-08-25 20:43:22.000000000 -0400
@@ -569,11 +569,9 @@ int wmt_pinctrl_probe(struct platform_de
 	struct resource *res;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	data->base = devm_request_and_ioremap(&pdev->dev, res);
-	if (!data->base) {
-		dev_err(&pdev->dev, "failed to map memory resource\n");
-		return -EBUSY;
-	}
+	data->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(data->base))
+		return PTR_ERR(data->base);
 
 	wmt_desc.pins = data->pins;
 	wmt_desc.npins = data->npins;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/olpc/olpc-ec.c linux-libre-3.11-rc7-gnu/drivers/platform/olpc/olpc-ec.c
--- linux-libre-3.10-gnu/drivers/platform/olpc/olpc-ec.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/olpc/olpc-ec.c	2013-08-25 20:43:22.000000000 -0400
@@ -330,7 +330,7 @@ static int __init olpc_ec_init_module(vo
 	return platform_driver_register(&olpc_ec_plat_driver);
 }
 
-module_init(olpc_ec_init_module);
+arch_initcall(olpc_ec_init_module);
 
 MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/asus-laptop.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/asus-laptop.c
--- linux-libre-3.10-gnu/drivers/platform/x86/asus-laptop.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/asus-laptop.c	2013-08-25 20:43:22.000000000 -0400
@@ -1935,7 +1935,6 @@ fail_input:
 fail_backlight:
 	asus_platform_exit(asus);
 fail_platform:
-	kfree(asus->name);
 	kfree(asus);
 
 	return result;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/asus-nb-wmi.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/asus-nb-wmi.c
--- linux-libre-3.10-gnu/drivers/platform/x86/asus-nb-wmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/asus-nb-wmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -180,6 +180,24 @@ static struct dmi_system_id asus_quirks[
 		},
 		.driver_data = &quirk_asus_x401u,
 	},
+	{
+		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. 1015E",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "1015E"),
+		},
+		.driver_data = &quirk_asus_x401u,
+	},
+	{
+		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. 1015U",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "1015U"),
+		},
+		.driver_data = &quirk_asus_x401u,
+	},
 	{},
 };
 
@@ -256,6 +274,7 @@ static const struct key_entry asus_nb_wm
 	{ KE_KEY, 0xB5, { KEY_CALC } },
 	{ KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
 	{ KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
+	{ KE_IGNORE, 0xC6, },  /* Ambient Light Sensor notification */
 	{ KE_END, 0},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/asus-wmi.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/asus-wmi.c
--- linux-libre-3.10-gnu/drivers/platform/x86/asus-wmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/asus-wmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -558,7 +558,7 @@ static int asus_wmi_led_init(struct asus
 			goto error;
 	}
 
-	if (wlan_led_presence(asus)) {
+	if (wlan_led_presence(asus) && (asus->driver->quirks->wapf == 4)) {
 		INIT_WORK(&asus->wlan_led_work, wlan_led_update);
 
 		asus->wlan_led.name = "asus::wlan";
@@ -886,7 +886,8 @@ static int asus_new_rfkill(struct asus_w
 	if (!*rfkill)
 		return -EINVAL;
 
-	if (dev_id == ASUS_WMI_DEVID_WLAN)
+	if ((dev_id == ASUS_WMI_DEVID_WLAN) &&
+			(asus->driver->quirks->wapf == 4))
 		rfkill_set_led_trigger_name(*rfkill, "asus-wlan");
 
 	rfkill_init_sw_state(*rfkill, !result);
@@ -1045,7 +1046,7 @@ static ssize_t asus_hwmon_pwm1(struct de
 	else if (value == 3)
 		value = 255;
 	else if (value != 0) {
-		pr_err("Unknown fan speed %#x", value);
+		pr_err("Unknown fan speed %#x\n", value);
 		value = -1;
 	}
 
@@ -1557,11 +1558,11 @@ static int asus_wmi_platform_init(struct
 
 	/* INIT enable hotkeys on some models */
 	if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
-		pr_info("Initialization: %#x", rv);
+		pr_info("Initialization: %#x\n", rv);
 
 	/* We don't know yet what to do with this version... */
 	if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
-		pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF);
+		pr_info("BIOS WMI version: %d.%d\n", rv >> 16, rv & 0xFF);
 		asus->spec = rv;
 	}
 
@@ -1572,7 +1573,7 @@ static int asus_wmi_platform_init(struct
 	 * The significance of others is yet to be found.
 	 */
 	if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
-		pr_info("SFUN value: %#x", rv);
+		pr_info("SFUN value: %#x\n", rv);
 		asus->sfun = rv;
 	}
 
@@ -1712,7 +1713,7 @@ static int asus_wmi_debugfs_init(struct
 
 	asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
 	if (!asus->debug.root) {
-		pr_err("failed to create debugfs directory");
+		pr_err("failed to create debugfs directory\n");
 		goto error_debugfs;
 	}
 
@@ -1985,17 +1986,17 @@ EXPORT_SYMBOL_GPL(asus_wmi_unregister_dr
 static int __init asus_wmi_init(void)
 {
 	if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
-		pr_info("Asus Management GUID not found");
+		pr_info("Asus Management GUID not found\n");
 		return -ENODEV;
 	}
 
-	pr_info("ASUS WMI generic driver loaded");
+	pr_info("ASUS WMI generic driver loaded\n");
 	return 0;
 }
 
 static void __exit asus_wmi_exit(void)
 {
-	pr_info("ASUS WMI generic driver unloaded");
+	pr_info("ASUS WMI generic driver unloaded\n");
 }
 
 module_init(asus_wmi_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/dell-laptop.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/dell-laptop.c
--- linux-libre-3.10-gnu/drivers/platform/x86/dell-laptop.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/dell-laptop.c	2013-08-25 20:43:22.000000000 -0400
@@ -551,9 +551,10 @@ static int __init dell_init(void)
 	 * is passed to SMI handler.
 	 */
 	bufferpage = alloc_page(GFP_KERNEL | GFP_DMA32);
-
-	if (!bufferpage)
+	if (!bufferpage) {
+		ret = -ENOMEM;
 		goto fail_buffer;
+	}
 	buffer = page_address(bufferpage);
 
 	if (quirks && quirks->touchpad_led)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/hp-wmi.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/hp-wmi.c
--- linux-libre-3.10-gnu/drivers/platform/x86/hp-wmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/hp-wmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,6 +55,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE9
 #define HPWMI_WIRELESS_QUERY 0x5
 #define HPWMI_HOTKEY_QUERY 0xc
 #define HPWMI_WIRELESS2_QUERY 0x1b
+#define HPWMI_POSTCODEERROR_QUERY 0x2a
 
 enum hp_wmi_radio {
 	HPWMI_WIFI = 0,
@@ -386,6 +387,16 @@ static int hp_wmi_rfkill2_refresh(void)
 	return 0;
 }
 
+static int hp_wmi_post_code_state(void)
+{
+	int state = 0;
+	int ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 0, &state,
+				       sizeof(state), sizeof(state));
+	if (ret)
+		return -EINVAL;
+	return state;
+}
+
 static ssize_t show_display(struct device *dev, struct device_attribute *attr,
 			    char *buf)
 {
@@ -431,6 +442,16 @@ static ssize_t show_tablet(struct device
 	return sprintf(buf, "%d\n", value);
 }
 
+static ssize_t show_postcode(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	/* Get the POST error code of previous boot failure. */
+	int value = hp_wmi_post_code_state();
+	if (value < 0)
+		return -EINVAL;
+	return sprintf(buf, "0x%x\n", value);
+}
+
 static ssize_t set_als(struct device *dev, struct device_attribute *attr,
 		       const char *buf, size_t count)
 {
@@ -443,11 +464,33 @@ static ssize_t set_als(struct device *de
 	return count;
 }
 
+static ssize_t set_postcode(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
+{
+	int ret;
+	u32 tmp;
+	long unsigned int tmp2;
+
+	ret = kstrtoul(buf, 10, &tmp2);
+	if (ret || tmp2 != 1)
+		return -EINVAL;
+
+	/* Clear the POST error code. It is kept until until cleared. */
+	tmp = (u32) tmp2;
+	ret = hp_wmi_perform_query(HPWMI_POSTCODEERROR_QUERY, 1, &tmp,
+				       sizeof(tmp), sizeof(tmp));
+	if (ret)
+		return -EINVAL;
+
+	return count;
+}
+
 static DEVICE_ATTR(display, S_IRUGO, show_display, NULL);
 static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL);
 static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als);
 static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
 static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
+static DEVICE_ATTR(postcode, S_IRUGO | S_IWUSR, show_postcode, set_postcode);
 
 static void hp_wmi_notify(u32 value, void *context)
 {
@@ -628,6 +671,7 @@ static void cleanup_sysfs(struct platfor
 	device_remove_file(&device->dev, &dev_attr_als);
 	device_remove_file(&device->dev, &dev_attr_dock);
 	device_remove_file(&device->dev, &dev_attr_tablet);
+	device_remove_file(&device->dev, &dev_attr_postcode);
 }
 
 static int hp_wmi_rfkill_setup(struct platform_device *device)
@@ -845,6 +889,9 @@ static int __init hp_wmi_bios_setup(stru
 	err = device_create_file(&device->dev, &dev_attr_tablet);
 	if (err)
 		goto add_sysfs_error;
+	err = device_create_file(&device->dev, &dev_attr_postcode);
+	if (err)
+		goto add_sysfs_error;
 	return 0;
 
 add_sysfs_error:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/intel_ips.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/intel_ips.c
--- linux-libre-3.10-gnu/drivers/platform/x86/intel_ips.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/intel_ips.c	2013-08-25 20:43:22.000000000 -0400
@@ -1731,18 +1731,7 @@ static struct pci_driver ips_pci_driver
 	.shutdown = ips_shutdown,
 };
 
-static int __init ips_init(void)
-{
-	return pci_register_driver(&ips_pci_driver);
-}
-module_init(ips_init);
-
-static void ips_exit(void)
-{
-	pci_unregister_driver(&ips_pci_driver);
-	return;
-}
-module_exit(ips_exit);
+module_pci_driver(ips_pci_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jesse Barnes <jbarnes@virtuousgeek.org>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/intel_pmic_gpio.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/intel_pmic_gpio.c
--- linux-libre-3.10-gnu/drivers/platform/x86/intel_pmic_gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/intel_pmic_gpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -288,7 +288,7 @@ static int platform_pmic_gpio_probe(stru
 	retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg);
 	if (retval) {
 		pr_warn("Interrupt request failed\n");
-		goto err;
+		goto fail_request_irq;
 	}
 
 	for (i = 0; i < 8; i++) {
@@ -299,6 +299,10 @@ static int platform_pmic_gpio_probe(stru
 		irq_set_chip_data(i + pg->irq_base, pg);
 	}
 	return 0;
+
+fail_request_irq:
+	if (gpiochip_remove(&pg->chip))
+		pr_err("gpiochip_remove failed\n");
 err:
 	iounmap(pg->gpiointr);
 err2:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/intel-rst.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/intel-rst.c
--- linux-libre-3.10-gnu/drivers/platform/x86/intel-rst.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/intel-rst.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,209 @@
+/*
+ *  Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <acpi/acpi_drivers.h>
+
+MODULE_LICENSE("GPL");
+
+static ssize_t irst_show_wakeup_events(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct acpi_device *acpi;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *result;
+	acpi_status status;
+
+	acpi = to_acpi_device(dev);
+
+	status = acpi_evaluate_object(acpi->handle, "GFFS", NULL, &output);
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	result = output.pointer;
+
+	if (result->type != ACPI_TYPE_INTEGER) {
+		kfree(result);
+		return -EINVAL;
+	}
+
+	return sprintf(buf, "%lld\n", result->integer.value);
+}
+
+static ssize_t irst_store_wakeup_events(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	struct acpi_device *acpi;
+	struct acpi_object_list input;
+	union acpi_object param;
+	acpi_status status;
+	unsigned long value;
+	int error;
+
+	acpi = to_acpi_device(dev);
+
+	error = kstrtoul(buf, 0, &value);
+
+	if (error)
+		return error;
+
+	param.type = ACPI_TYPE_INTEGER;
+	param.integer.value = value;
+
+	input.count = 1;
+	input.pointer = &param;
+
+	status = acpi_evaluate_object(acpi->handle, "SFFS", &input, NULL);
+
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	return count;
+}
+
+static struct device_attribute irst_wakeup_attr = {
+	.attr = { .name = "wakeup_events", .mode = 0600 },
+	.show = irst_show_wakeup_events,
+	.store = irst_store_wakeup_events
+};
+
+static ssize_t irst_show_wakeup_time(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct acpi_device *acpi;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *result;
+	acpi_status status;
+
+	acpi = to_acpi_device(dev);
+
+	status = acpi_evaluate_object(acpi->handle, "GFTV", NULL, &output);
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	result = output.pointer;
+
+	if (result->type != ACPI_TYPE_INTEGER) {
+		kfree(result);
+		return -EINVAL;
+	}
+
+	return sprintf(buf, "%lld\n", result->integer.value);
+}
+
+static ssize_t irst_store_wakeup_time(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct acpi_device *acpi;
+	struct acpi_object_list input;
+	union acpi_object param;
+	acpi_status status;
+	unsigned long value;
+	int error;
+
+	acpi = to_acpi_device(dev);
+
+	error = kstrtoul(buf, 0, &value);
+
+	if (error)
+		return error;
+
+	param.type = ACPI_TYPE_INTEGER;
+	param.integer.value = value;
+
+	input.count = 1;
+	input.pointer = &param;
+
+	status = acpi_evaluate_object(acpi->handle, "SFTV", &input, NULL);
+
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	return count;
+}
+
+static struct device_attribute irst_timeout_attr = {
+	.attr = { .name = "wakeup_time", .mode = 0600 },
+	.show = irst_show_wakeup_time,
+	.store = irst_store_wakeup_time
+};
+
+static int irst_add(struct acpi_device *acpi)
+{
+	int error = 0;
+
+	error = device_create_file(&acpi->dev, &irst_timeout_attr);
+	if (error)
+		goto out;
+
+	error = device_create_file(&acpi->dev, &irst_wakeup_attr);
+	if (error)
+		goto out_timeout;
+
+	return 0;
+
+out_timeout:
+	device_remove_file(&acpi->dev, &irst_timeout_attr);
+out:
+	return error;
+}
+
+static int irst_remove(struct acpi_device *acpi)
+{
+	device_remove_file(&acpi->dev, &irst_wakeup_attr);
+	device_remove_file(&acpi->dev, &irst_timeout_attr);
+
+	return 0;
+}
+
+static const struct acpi_device_id irst_ids[] = {
+	{"INT3392", 0},
+	{"", 0}
+};
+
+static struct acpi_driver irst_driver = {
+	.owner = THIS_MODULE,
+	.name = "intel_rapid_start",
+	.class = "intel_rapid_start",
+	.ids = irst_ids,
+	.ops = {
+		.add = irst_add,
+		.remove = irst_remove,
+	},
+};
+
+static int irst_init(void)
+{
+	return acpi_bus_register_driver(&irst_driver);
+}
+
+static void irst_exit(void)
+{
+	acpi_bus_unregister_driver(&irst_driver);
+}
+
+module_init(irst_init);
+module_exit(irst_exit);
+
+MODULE_DEVICE_TABLE(acpi, irst_ids);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/intel-smartconnect.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/intel-smartconnect.c
--- linux-libre-3.10-gnu/drivers/platform/x86/intel-smartconnect.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/intel-smartconnect.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,90 @@
+/*
+ *  Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <acpi/acpi_drivers.h>
+
+MODULE_LICENSE("GPL");
+
+static int smartconnect_acpi_init(struct acpi_device *acpi)
+{
+	struct acpi_object_list input;
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *result;
+	union acpi_object param;
+	acpi_status status;
+
+	status = acpi_evaluate_object(acpi->handle, "GAOS", NULL, &output);
+	if (!ACPI_SUCCESS(status))
+		return -EINVAL;
+
+	result = output.pointer;
+
+	if (result->type != ACPI_TYPE_INTEGER) {
+		kfree(result);
+		return -EINVAL;
+	}
+
+	if (result->integer.value & 0x1) {
+		param.type = ACPI_TYPE_INTEGER;
+		param.integer.value = 0;
+
+		input.count = 1;
+		input.pointer = &param;
+
+		dev_info(&acpi->dev, "Disabling Intel Smart Connect\n");
+		status = acpi_evaluate_object(acpi->handle, "SAOS", &input,
+					      NULL);
+	}
+
+	kfree(result);
+
+	return 0;
+}
+
+static const struct acpi_device_id smartconnect_ids[] = {
+	{"INT33A0", 0},
+	{"", 0}
+};
+
+static struct acpi_driver smartconnect_driver = {
+	.owner = THIS_MODULE,
+	.name = "intel_smart_connect",
+	.class = "intel_smart_connect",
+	.ids = smartconnect_ids,
+	.ops = {
+		.add = smartconnect_acpi_init,
+	},
+};
+
+static int smartconnect_init(void)
+{
+	return acpi_bus_register_driver(&smartconnect_driver);
+}
+
+static void smartconnect_exit(void)
+{
+	acpi_bus_unregister_driver(&smartconnect_driver);
+}
+
+module_init(smartconnect_init);
+module_exit(smartconnect_exit);
+
+MODULE_DEVICE_TABLE(acpi, smartconnect_ids);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/Kconfig linux-libre-3.11-rc7-gnu/drivers/platform/x86/Kconfig
--- linux-libre-3.10-gnu/drivers/platform/x86/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -176,6 +176,7 @@ config FUJITSU_TABLET
 config AMILO_RFKILL
 	tristate "Fujitsu-Siemens Amilo rfkill support"
 	depends on RFKILL
+	depends on SERIO_I8042
 	---help---
 	  This is a driver for enabling wifi on some Fujitsu-Siemens Amilo
 	  laptops.
@@ -591,6 +592,7 @@ config ACPI_TOSHIBA
 	depends on BACKLIGHT_CLASS_DEVICE
 	depends on INPUT
 	depends on RFKILL || RFKILL = n
+	depends on SERIO_I8042 || SERIO_I8042 = n
 	select INPUT_POLLDEV
 	select INPUT_SPARSEKMAP
 	---help---
@@ -781,6 +783,32 @@ config APPLE_GMUX
 	  graphics as well as the backlight. Currently only backlight
 	  control is supported by the driver.
 
+config INTEL_RST
+        tristate "Intel Rapid Start Technology Driver"
+	depends on ACPI
+	---help---
+	  This driver provides support for modifying paramaters on systems
+	  equipped with Intel's Rapid Start Technology. When put in an ACPI
+	  sleep state, these devices will wake after either a configured
+	  timeout or when the system battery reaches a critical state,
+	  automatically copying memory contents to disk. On resume, the
+	  firmware will copy the memory contents back to RAM and resume the OS
+	  as usual.
+
+config INTEL_SMARTCONNECT
+        tristate "Intel Smart Connect disabling driver"
+	depends on ACPI
+	---help---
+	  Intel Smart Connect is a technology intended to permit devices to
+	  update state by resuming for a short period of time at regular
+	  intervals. If a user enables this functionality under Windows and
+	  then reboots into Linux, the system may remain configured to resume
+	  on suspend. In the absence of any userspace to support it, the system
+	  will then remain awake until something triggers another suspend.
+
+	  This driver checks to determine whether the device has Intel Smart
+	  Connect enabled, and if so disables it.
+
 config PVPANIC
 	tristate "pvpanic device support"
 	depends on ACPI
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/Makefile linux-libre-3.11-rc7-gnu/drivers/platform/x86/Makefile
--- linux-libre-3.10-gnu/drivers/platform/x86/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -51,5 +51,7 @@ obj-$(CONFIG_INTEL_OAKTRAIL)	+= intel_oa
 obj-$(CONFIG_SAMSUNG_Q10)	+= samsung-q10.o
 obj-$(CONFIG_APPLE_GMUX)	+= apple-gmux.o
 obj-$(CONFIG_CHROMEOS_LAPTOP)	+= chromeos_laptop.o
+obj-$(CONFIG_INTEL_RST)		+= intel-rst.o
+obj-$(CONFIG_INTEL_SMARTCONNECT)	+= intel-smartconnect.o
 
 obj-$(CONFIG_PVPANIC)           += pvpanic.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/msi-laptop.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/msi-laptop.c
--- linux-libre-3.10-gnu/drivers/platform/x86/msi-laptop.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/msi-laptop.c	2013-08-25 20:43:22.000000000 -0400
@@ -1098,29 +1098,29 @@ static int __init msi_init(void)
 
 	ret = platform_device_add(msipf_device);
 	if (ret)
-		goto fail_platform_device1;
+		goto fail_device_add;
 
 	if (quirks->load_scm_model && (load_scm_model_init(msipf_device) < 0)) {
 		ret = -EINVAL;
-		goto fail_platform_device1;
+		goto fail_scm_model_init;
 	}
 
 	ret = sysfs_create_group(&msipf_device->dev.kobj,
 				 &msipf_attribute_group);
 	if (ret)
-		goto fail_platform_device2;
+		goto fail_create_group;
 
 	if (!quirks->old_ec_model) {
 		if (threeg_exists)
 			ret = device_create_file(&msipf_device->dev,
 						&dev_attr_threeg);
 		if (ret)
-			goto fail_platform_device2;
+			goto fail_create_attr;
 	} else {
 		ret = sysfs_create_group(&msipf_device->dev.kobj,
 					 &msipf_old_attribute_group);
 		if (ret)
-			goto fail_platform_device2;
+			goto fail_create_attr;
 
 		/* Disable automatic brightness control by default because
 		 * this module was probably loaded to do brightness control in
@@ -1134,26 +1134,22 @@ static int __init msi_init(void)
 
 	return 0;
 
-fail_platform_device2:
-
+fail_create_attr:
+	sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
+fail_create_group:
 	if (quirks->load_scm_model) {
 		i8042_remove_filter(msi_laptop_i8042_filter);
 		cancel_delayed_work_sync(&msi_rfkill_dwork);
 		cancel_work_sync(&msi_rfkill_work);
 		rfkill_cleanup();
 	}
+fail_scm_model_init:
 	platform_device_del(msipf_device);
-
-fail_platform_device1:
-
+fail_device_add:
 	platform_device_put(msipf_device);
-
 fail_platform_driver:
-
 	platform_driver_unregister(&msipf_driver);
-
 fail_backlight:
-
 	backlight_device_unregister(msibl_device);
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/sony-laptop.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/sony-laptop.c
--- linux-libre-3.10-gnu/drivers/platform/x86/sony-laptop.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/sony-laptop.c	2013-08-25 20:43:22.000000000 -0400
@@ -2440,7 +2440,10 @@ static ssize_t sony_nc_gfx_switch_status
 	if (pos < 0)
 		return pos;
 
-	return snprintf(buffer, PAGE_SIZE, "%s\n", pos ? "speed" : "stamina");
+	return snprintf(buffer, PAGE_SIZE, "%s\n",
+					pos == SPEED ? "speed" :
+					pos == STAMINA ? "stamina" :
+					pos == AUTO ? "auto" : "unknown");
 }
 
 static int sony_nc_gfx_switch_setup(struct platform_device *pd,
@@ -4320,7 +4323,8 @@ static int sony_pic_add(struct acpi_devi
 		goto err_free_resources;
 	}
 
-	if (sonypi_compat_init())
+	result = sonypi_compat_init();
+	if (result)
 		goto err_remove_input;
 
 	/* request io port */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/platform/x86/wmi.c linux-libre-3.11-rc7-gnu/drivers/platform/x86/wmi.c
--- linux-libre-3.10-gnu/drivers/platform/x86/wmi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/platform/x86/wmi.c	2013-08-25 20:43:22.000000000 -0400
@@ -743,7 +743,7 @@ static int wmi_create_device(const struc
 	wblock->dev.class = &wmi_class;
 
 	wmi_gtoa(gblock->guid, guid_string);
-	dev_set_name(&wblock->dev, guid_string);
+	dev_set_name(&wblock->dev, "%s", guid_string);
 
 	dev_set_drvdata(&wblock->dev, wblock);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pnp/isapnp/proc.c linux-libre-3.11-rc7-gnu/drivers/pnp/isapnp/proc.c
--- linux-libre-3.10-gnu/drivers/pnp/isapnp/proc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pnp/isapnp/proc.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,27 +29,7 @@ static struct proc_dir_entry *isapnp_pro
 
 static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
 {
-	loff_t new = -1;
-	struct inode *inode = file_inode(file);
-
-	mutex_lock(&inode->i_mutex);
-	switch (whence) {
-	case 0:
-		new = off;
-		break;
-	case 1:
-		new = file->f_pos + off;
-		break;
-	case 2:
-		new = 256 + off;
-		break;
-	}
-	if (new < 0 || new > 256)
-		new = -EINVAL;
-	else
-		file->f_pos = new;
-	mutex_unlock(&inode->i_mutex);
-	return new;
+	return fixed_size_llseek(file, off, whence, 256);
 }
 
 static ssize_t isapnp_proc_bus_read(struct file *file, char __user * buf,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pnp/manager.c linux-libre-3.11-rc7-gnu/drivers/pnp/manager.c
--- linux-libre-3.10-gnu/drivers/pnp/manager.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pnp/manager.c	2013-08-25 20:43:22.000000000 -0400
@@ -211,6 +211,12 @@ static int pnp_assign_dma(struct pnp_dev
 	res->start = -1;
 	res->end = -1;
 
+	if (!rule->map) {
+		res->flags |= IORESOURCE_DISABLED;
+		pnp_dbg(&dev->dev, "  dma %d disabled\n", idx);
+		goto __add;
+	}
+
 	for (i = 0; i < 8; i++) {
 		if (rule->map & (1 << xtab[i])) {
 			res->start = res->end = xtab[i];
@@ -218,11 +224,9 @@ static int pnp_assign_dma(struct pnp_dev
 				goto __add;
 		}
 	}
-#ifdef MAX_DMA_CHANNELS
-	res->start = res->end = MAX_DMA_CHANNELS;
-#endif
-	res->flags |= IORESOURCE_DISABLED;
-	pnp_dbg(&dev->dev, "  disable dma %d\n", idx);
+
+	pnp_dbg(&dev->dev, "  couldn't assign dma %d\n", idx);
+	return -EBUSY;
 
 __add:
 	pnp_add_dma_resource(dev, res->start, res->flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pnp/pnpacpi/rsparser.c linux-libre-3.11-rc7-gnu/drivers/pnp/pnpacpi/rsparser.c
--- linux-libre-3.10-gnu/drivers/pnp/pnpacpi/rsparser.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pnp/pnpacpi/rsparser.c	2013-08-25 20:43:22.000000000 -0400
@@ -180,7 +180,7 @@ static acpi_status pnpacpi_allocated_res
 	struct pnp_dev *dev = data;
 	struct acpi_resource_dma *dma;
 	struct acpi_resource_vendor_typed *vendor_typed;
-	struct resource r;
+	struct resource r = {0};
 	int i, flags;
 
 	if (acpi_dev_resource_memory(res, &r)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pnp/resource.c linux-libre-3.11-rc7-gnu/drivers/pnp/resource.c
--- linux-libre-3.10-gnu/drivers/pnp/resource.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pnp/resource.c	2013-08-25 20:43:22.000000000 -0400
@@ -515,6 +515,7 @@ struct pnp_resource *pnp_add_resource(st
 	}
 
 	pnp_res->res = *res;
+	pnp_res->res.name = dev->name;
 	dev_dbg(&dev->dev, "%pR\n", res);
 	return pnp_res;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/88pm860x_battery.c linux-libre-3.11-rc7-gnu/drivers/power/88pm860x_battery.c
--- linux-libre-3.10-gnu/drivers/power/88pm860x_battery.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/88pm860x_battery.c	2013-08-25 20:43:22.000000000 -0400
@@ -992,7 +992,6 @@ static int pm860x_battery_remove(struct
 	free_irq(info->irq_batt, info);
 	free_irq(info->irq_cc, info);
 	power_supply_unregister(&info->battery);
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/88pm860x_charger.c linux-libre-3.11-rc7-gnu/drivers/power/88pm860x_charger.c
--- linux-libre-3.10-gnu/drivers/power/88pm860x_charger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/88pm860x_charger.c	2013-08-25 20:43:22.000000000 -0400
@@ -722,7 +722,6 @@ static int pm860x_charger_remove(struct
 	struct pm860x_charger_info *info = platform_get_drvdata(pdev);
 	int i;
 
-	platform_set_drvdata(pdev, NULL);
 	power_supply_unregister(&info->usb);
 	free_irq(info->irq[0], info);
 	for (i = 0; i < info->irq_nums; i++)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/ab8500_btemp.c linux-libre-3.11-rc7-gnu/drivers/power/ab8500_btemp.c
--- linux-libre-3.10-gnu/drivers/power/ab8500_btemp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/ab8500_btemp.c	2013-08-25 20:43:22.000000000 -0400
@@ -1045,7 +1045,6 @@ static int ab8500_btemp_remove(struct pl
 
 	flush_scheduled_work();
 	power_supply_unregister(&di->btemp_psy);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/ab8500_charger.c linux-libre-3.11-rc7-gnu/drivers/power/ab8500_charger.c
--- linux-libre-3.10-gnu/drivers/power/ab8500_charger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/ab8500_charger.c	2013-08-25 20:43:22.000000000 -0400
@@ -3425,8 +3425,6 @@ static int ab8500_charger_remove(struct
 	if (di->ac_chg.enabled && !di->ac_chg.external)
 		power_supply_unregister(&di->ac_chg.psy);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/ab8500_fg.c linux-libre-3.11-rc7-gnu/drivers/power/ab8500_fg.c
--- linux-libre-3.10-gnu/drivers/power/ab8500_fg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/ab8500_fg.c	2013-08-25 20:43:22.000000000 -0400
@@ -2465,9 +2465,9 @@ static ssize_t charge_full_store(struct
 				 size_t count)
 {
 	unsigned long charge_full;
-	ssize_t ret = -EINVAL;
+	ssize_t ret;
 
-	ret = strict_strtoul(buf, 10, &charge_full);
+	ret = kstrtoul(buf, 10, &charge_full);
 
 	dev_dbg(di->dev, "Ret %zd charge_full %lu", ret, charge_full);
 
@@ -2489,7 +2489,7 @@ static ssize_t charge_now_store(struct a
 	unsigned long charge_now;
 	ssize_t ret;
 
-	ret = strict_strtoul(buf, 10, &charge_now);
+	ret = kstrtoul(buf, 10, &charge_now);
 
 	dev_dbg(di->dev, "Ret %zd charge_now %lu was %d",
 		ret, charge_now, di->bat_cap.prev_mah);
@@ -3070,7 +3070,6 @@ static int ab8500_fg_remove(struct platf
 	flush_scheduled_work();
 	ab8500_fg_sysfs_psy_remove_attrs(di->fg_psy.dev);
 	power_supply_unregister(&di->fg_psy);
-	platform_set_drvdata(pdev, NULL);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/abx500_chargalg.c linux-libre-3.11-rc7-gnu/drivers/power/abx500_chargalg.c
--- linux-libre-3.10-gnu/drivers/power/abx500_chargalg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/abx500_chargalg.c	2013-08-25 20:43:22.000000000 -0400
@@ -2035,7 +2035,6 @@ static int abx500_chargalg_remove(struct
 	destroy_workqueue(di->chargalg_wq);
 
 	power_supply_unregister(&di->chargalg_psy);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/avs/smartreflex.c linux-libre-3.11-rc7-gnu/drivers/power/avs/smartreflex.c
--- linux-libre-3.10-gnu/drivers/power/avs/smartreflex.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/avs/smartreflex.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,8 @@
 #include <linux/pm_runtime.h>
 #include <linux/power/smartreflex.h>
 
-#define SMARTREFLEX_NAME_LEN	16
+#define DRIVER_NAME	"smartreflex"
+#define SMARTREFLEX_NAME_LEN	32
 #define NVALUE_NAME_LEN		40
 #define SR_DISABLE_TIMEOUT	200
 
@@ -207,12 +208,11 @@ static void sr_stop_vddautocomp(struct o
 static int sr_late_init(struct omap_sr *sr_info)
 {
 	struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
-	struct resource *mem;
 	int ret = 0;
 
 	if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
-		ret = request_irq(sr_info->irq, sr_interrupt,
-				  0, sr_info->name, sr_info);
+		ret = devm_request_irq(&sr_info->pdev->dev, sr_info->irq,
+				       sr_interrupt, 0, sr_info->name, sr_info);
 		if (ret)
 			goto error;
 		disable_irq(sr_info->irq);
@@ -224,14 +224,10 @@ static int sr_late_init(struct omap_sr *
 	return ret;
 
 error:
-	iounmap(sr_info->base);
-	mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
-	release_mem_region(mem->start, resource_size(mem));
 	list_del(&sr_info->node);
 	dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
 		"interrupt handler. Smartreflex will"
 		"not function as desired\n", __func__);
-	kfree(sr_info);
 
 	return ret;
 }
@@ -341,9 +337,9 @@ static struct omap_sr_nvalue_table *sr_r
 /* Public Functions */
 
 /**
- * sr_configure_errgen() - Configures the smrtreflex to perform AVS using the
+ * sr_configure_errgen() - Configures the SmartReflex to perform AVS using the
  *			 error generator module.
- * @voltdm:	VDD pointer to which the SR module to be configured belongs to.
+ * @sr:			SR module to be configured.
  *
  * This API is to be called from the smartreflex class driver to
  * configure the error generator module inside the smartreflex module.
@@ -352,17 +348,17 @@ static struct omap_sr_nvalue_table *sr_r
  * SR CLASS 2 can choose between ERROR module and MINMAXAVG
  * module. Returns 0 on success and error value in case of failure.
  */
-int sr_configure_errgen(struct voltagedomain *voltdm)
+int sr_configure_errgen(struct omap_sr *sr)
 {
 	u32 sr_config, sr_errconfig, errconfig_offs;
 	u32 vpboundint_en, vpboundint_st;
 	u32 senp_en = 0, senn_en = 0;
 	u8 senp_shift, senn_shift;
-	struct omap_sr *sr = _sr_lookup(voltdm);
 
-	if (IS_ERR(sr)) {
-		pr_warning("%s: omap_sr struct for voltdm not found\n",	__func__);
-		return PTR_ERR(sr);
+	if (!sr) {
+		pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+			(void *)_RET_IP_);
+		return -EINVAL;
 	}
 
 	if (!sr->clk_length)
@@ -414,22 +410,22 @@ int sr_configure_errgen(struct voltagedo
 
 /**
  * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component
- * @voltdm:	VDD pointer to which the SR module to be configured belongs to.
+ * @sr:			SR module to be configured.
  *
  * This API is to be called from the smartreflex class driver to
  * disable the error generator module inside the smartreflex module.
  *
  * Returns 0 on success and error value in case of failure.
  */
-int sr_disable_errgen(struct voltagedomain *voltdm)
+int sr_disable_errgen(struct omap_sr *sr)
 {
 	u32 errconfig_offs;
 	u32 vpboundint_en, vpboundint_st;
-	struct omap_sr *sr = _sr_lookup(voltdm);
 
-	if (IS_ERR(sr)) {
-		pr_warning("%s: omap_sr struct for voltdm not found\n",	__func__);
-		return PTR_ERR(sr);
+	if (!sr) {
+		pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+			(void *)_RET_IP_);
+		return -EINVAL;
 	}
 
 	switch (sr->ip_type) {
@@ -449,19 +445,24 @@ int sr_disable_errgen(struct voltagedoma
 		return -EINVAL;
 	}
 
-	/* Disable the interrupts of ERROR module */
-	sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0);
-
 	/* Disable the Sensor and errorgen */
 	sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0);
 
+	/*
+	 * Disable the interrupts of ERROR module
+	 * NOTE: modify is a read, modify,write - an implicit OCP barrier
+	 * which is required is present here - sequencing is critical
+	 * at this point (after errgen is disabled, vpboundint disable)
+	 */
+	sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0);
+
 	return 0;
 }
 
 /**
- * sr_configure_minmax() - Configures the smrtreflex to perform AVS using the
+ * sr_configure_minmax() - Configures the SmartReflex to perform AVS using the
  *			 minmaxavg module.
- * @voltdm:	VDD pointer to which the SR module to be configured belongs to.
+ * @sr:			SR module to be configured.
  *
  * This API is to be called from the smartreflex class driver to
  * configure the minmaxavg module inside the smartreflex module.
@@ -470,16 +471,16 @@ int sr_disable_errgen(struct voltagedoma
  * SR CLASS 2 can choose between ERROR module and MINMAXAVG
  * module. Returns 0 on success and error value in case of failure.
  */
-int sr_configure_minmax(struct voltagedomain *voltdm)
+int sr_configure_minmax(struct omap_sr *sr)
 {
 	u32 sr_config, sr_avgwt;
 	u32 senp_en = 0, senn_en = 0;
 	u8 senp_shift, senn_shift;
-	struct omap_sr *sr = _sr_lookup(voltdm);
 
-	if (IS_ERR(sr)) {
-		pr_warning("%s: omap_sr struct for voltdm not found\n",	__func__);
-		return PTR_ERR(sr);
+	if (!sr) {
+		pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+			(void *)_RET_IP_);
+		return -EINVAL;
 	}
 
 	if (!sr->clk_length)
@@ -546,7 +547,7 @@ int sr_configure_minmax(struct voltagedo
 
 /**
  * sr_enable() - Enables the smartreflex module.
- * @voltdm:	VDD pointer to which the SR module to be configured belongs to.
+ * @sr:		pointer to which the SR module to be configured belongs to.
  * @volt:	The voltage at which the Voltage domain associated with
  *		the smartreflex module is operating at.
  *		This is required only to program the correct Ntarget value.
@@ -555,16 +556,16 @@ int sr_configure_minmax(struct voltagedo
  * enable a smartreflex module. Returns 0 on success. Returns error
  * value if the voltage passed is wrong or if ntarget value is wrong.
  */
-int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
+int sr_enable(struct omap_sr *sr, unsigned long volt)
 {
 	struct omap_volt_data *volt_data;
-	struct omap_sr *sr = _sr_lookup(voltdm);
 	struct omap_sr_nvalue_table *nvalue_row;
 	int ret;
 
-	if (IS_ERR(sr)) {
-		pr_warning("%s: omap_sr struct for voltdm not found\n",	__func__);
-		return PTR_ERR(sr);
+	if (!sr) {
+		pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+			(void *)_RET_IP_);
+		return -EINVAL;
 	}
 
 	volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
@@ -606,17 +607,16 @@ int sr_enable(struct voltagedomain *volt
 
 /**
  * sr_disable() - Disables the smartreflex module.
- * @voltdm:	VDD pointer to which the SR module to be configured belongs to.
+ * @sr:		pointer to which the SR module to be configured belongs to.
  *
  * This API is to be called from the smartreflex class driver to
  * disable a smartreflex module.
  */
-void sr_disable(struct voltagedomain *voltdm)
+void sr_disable(struct omap_sr *sr)
 {
-	struct omap_sr *sr = _sr_lookup(voltdm);
-
-	if (IS_ERR(sr)) {
-		pr_warning("%s: omap_sr struct for voltdm not found\n",	__func__);
+	if (!sr) {
+		pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+			(void *)_RET_IP_);
 		return;
 	}
 
@@ -847,34 +847,33 @@ static int __init omap_sr_probe(struct p
 	struct dentry *nvalue_dir;
 	int i, ret = 0;
 
-	sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
+	sr_info = devm_kzalloc(&pdev->dev, sizeof(struct omap_sr), GFP_KERNEL);
 	if (!sr_info) {
 		dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
 			__func__);
 		return -ENOMEM;
 	}
 
+	sr_info->name = devm_kzalloc(&pdev->dev,
+				     SMARTREFLEX_NAME_LEN, GFP_KERNEL);
+	if (!sr_info->name) {
+		dev_err(&pdev->dev, "%s: unable to allocate SR instance name\n",
+			__func__);
+		return -ENOMEM;
+	}
+
 	platform_set_drvdata(pdev, sr_info);
 
 	if (!pdata) {
 		dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
-		ret = -EINVAL;
-		goto err_free_devinfo;
+		return -EINVAL;
 	}
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem) {
-		dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
-		ret = -ENODEV;
-		goto err_free_devinfo;
-	}
-
-	mem = request_mem_region(mem->start, resource_size(mem),
-					dev_name(&pdev->dev));
-	if (!mem) {
-		dev_err(&pdev->dev, "%s: no mem region\n", __func__);
-		ret = -EBUSY;
-		goto err_free_devinfo;
+	sr_info->base = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(sr_info->base)) {
+		dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
+		return PTR_ERR(sr_info->base);
 	}
 
 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -882,13 +881,7 @@ static int __init omap_sr_probe(struct p
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_irq_safe(&pdev->dev);
 
-	sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name);
-	if (!sr_info->name) {
-		dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n",
-			__func__);
-		ret = -ENOMEM;
-		goto err_release_region;
-	}
+	snprintf(sr_info->name, SMARTREFLEX_NAME_LEN, "%s", pdata->name);
 
 	sr_info->pdev = pdev;
 	sr_info->srid = pdev->id;
@@ -905,13 +898,6 @@ static int __init omap_sr_probe(struct p
 	sr_info->autocomp_active = false;
 	sr_info->ip_type = pdata->ip_type;
 
-	sr_info->base = ioremap(mem->start, resource_size(mem));
-	if (!sr_info->base) {
-		dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
-		ret = -ENOMEM;
-		goto err_free_name;
-	}
-
 	if (irq)
 		sr_info->irq = irq->start;
 
@@ -927,7 +913,7 @@ static int __init omap_sr_probe(struct p
 		ret = sr_late_init(sr_info);
 		if (ret) {
 			pr_warning("%s: Error in SR late init\n", __func__);
-			goto err_iounmap;
+			goto err_list_del;
 		}
 	}
 
@@ -938,7 +924,7 @@ static int __init omap_sr_probe(struct p
 			ret = PTR_ERR(sr_dbg_dir);
 			pr_err("%s:sr debugfs dir creation failed(%d)\n",
 				__func__, ret);
-			goto err_iounmap;
+			goto err_list_del;
 		}
 	}
 
@@ -991,16 +977,8 @@ static int __init omap_sr_probe(struct p
 
 err_debugfs:
 	debugfs_remove_recursive(sr_info->dbg_dir);
-err_iounmap:
+err_list_del:
 	list_del(&sr_info->node);
-	iounmap(sr_info->base);
-err_free_name:
-	kfree(sr_info->name);
-err_release_region:
-	release_mem_region(mem->start, resource_size(mem));
-err_free_devinfo:
-	kfree(sr_info);
-
 	return ret;
 }
 
@@ -1008,7 +986,6 @@ static int omap_sr_remove(struct platfor
 {
 	struct omap_sr_data *pdata = pdev->dev.platform_data;
 	struct omap_sr *sr_info;
-	struct resource *mem;
 
 	if (!pdata) {
 		dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
@@ -1027,13 +1004,8 @@ static int omap_sr_remove(struct platfor
 	if (sr_info->dbg_dir)
 		debugfs_remove_recursive(sr_info->dbg_dir);
 
+	pm_runtime_disable(&pdev->dev);
 	list_del(&sr_info->node);
-	iounmap(sr_info->base);
-	kfree(sr_info->name);
-	kfree(sr_info);
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(mem->start, resource_size(mem));
-
 	return 0;
 }
 
@@ -1064,7 +1036,7 @@ static struct platform_driver smartrefle
 	.remove         = omap_sr_remove,
 	.shutdown	= omap_sr_shutdown,
 	.driver		= {
-		.name	= "smartreflex",
+		.name	= DRIVER_NAME,
 	},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/bq27x00_battery.c linux-libre-3.11-rc7-gnu/drivers/power/bq27x00_battery.c
--- linux-libre-3.10-gnu/drivers/power/bq27x00_battery.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/bq27x00_battery.c	2013-08-25 20:43:22.000000000 -0400
@@ -966,7 +966,6 @@ static int bq27000_battery_probe(struct
 	return 0;
 
 err_free:
-	platform_set_drvdata(pdev, NULL);
 	kfree(di);
 
 	return ret;
@@ -978,7 +977,6 @@ static int bq27000_battery_remove(struct
 
 	bq27x00_powersupply_unregister(di);
 
-	platform_set_drvdata(pdev, NULL);
 	kfree(di);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/charger-manager.c linux-libre-3.11-rc7-gnu/drivers/power/charger-manager.c
--- linux-libre-3.10-gnu/drivers/power/charger-manager.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/charger-manager.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,6 +12,8 @@
  * published by the Free Software Foundation.
 **/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/irq.h>
@@ -195,8 +197,8 @@ static bool is_charging(struct charger_m
 				cm->charger_stat[i],
 				POWER_SUPPLY_PROP_ONLINE, &val);
 		if (ret) {
-			dev_warn(cm->dev, "Cannot read ONLINE value from %s.\n",
-					cm->desc->psy_charger_stat[i]);
+			dev_warn(cm->dev, "Cannot read ONLINE value from %s\n",
+				 cm->desc->psy_charger_stat[i]);
 			continue;
 		}
 		if (val.intval == 0)
@@ -210,8 +212,8 @@ static bool is_charging(struct charger_m
 				cm->charger_stat[i],
 				POWER_SUPPLY_PROP_STATUS, &val);
 		if (ret) {
-			dev_warn(cm->dev, "Cannot read STATUS value from %s.\n",
-					cm->desc->psy_charger_stat[i]);
+			dev_warn(cm->dev, "Cannot read STATUS value from %s\n",
+				 cm->desc->psy_charger_stat[i]);
 			continue;
 		}
 		if (val.intval == POWER_SUPPLY_STATUS_FULL ||
@@ -289,7 +291,7 @@ static bool is_polling_required(struct c
 		return is_charging(cm);
 	default:
 		dev_warn(cm->dev, "Incorrect polling_mode (%d)\n",
-			cm->desc->polling_mode);
+			 cm->desc->polling_mode);
 	}
 
 	return false;
@@ -331,9 +333,8 @@ static int try_charger_enable(struct cha
 
 			err = regulator_enable(desc->charger_regulators[i].consumer);
 			if (err < 0) {
-				dev_warn(cm->dev,
-					"Cannot enable %s regulator\n",
-					desc->charger_regulators[i].regulator_name);
+				dev_warn(cm->dev, "Cannot enable %s regulator\n",
+					 desc->charger_regulators[i].regulator_name);
 			}
 		}
 	} else {
@@ -350,9 +351,8 @@ static int try_charger_enable(struct cha
 
 			err = regulator_disable(desc->charger_regulators[i].consumer);
 			if (err < 0) {
-				dev_warn(cm->dev,
-					"Cannot disable %s regulator\n",
-					desc->charger_regulators[i].regulator_name);
+				dev_warn(cm->dev, "Cannot disable %s regulator\n",
+					 desc->charger_regulators[i].regulator_name);
 			}
 		}
 
@@ -365,9 +365,8 @@ static int try_charger_enable(struct cha
 				    desc->charger_regulators[i].consumer)) {
 				regulator_force_disable(
 					desc->charger_regulators[i].consumer);
-				dev_warn(cm->dev,
-					"Disable regulator(%s) forcibly.\n",
-					desc->charger_regulators[i].regulator_name);
+				dev_warn(cm->dev, "Disable regulator(%s) forcibly\n",
+					 desc->charger_regulators[i].regulator_name);
 			}
 		}
 	}
@@ -450,7 +449,7 @@ static void uevent_notify(struct charger
 	strncpy(env_str, event, UEVENT_BUF_SIZE);
 	kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
 
-	dev_info(cm->dev, event);
+	dev_info(cm->dev, "%s\n", event);
 }
 
 /**
@@ -478,7 +477,7 @@ static void fullbatt_vchk(struct work_st
 
 	err = get_batt_uV(cm, &batt_uV);
 	if (err) {
-		dev_err(cm->dev, "%s: get_batt_uV error(%d).\n", __func__, err);
+		dev_err(cm->dev, "%s: get_batt_uV error(%d)\n", __func__, err);
 		return;
 	}
 
@@ -486,7 +485,7 @@ static void fullbatt_vchk(struct work_st
 	if (diff < 0)
 		return;
 
-	dev_info(cm->dev, "VBATT dropped %duV after full-batt.\n", diff);
+	dev_info(cm->dev, "VBATT dropped %duV after full-batt\n", diff);
 
 	if (diff > desc->fullbatt_vchkdrop_uV) {
 		try_charger_restart(cm);
@@ -519,7 +518,7 @@ static int check_charging_duration(struc
 		duration = curr - cm->charging_start_time;
 
 		if (duration > desc->charging_max_duration_ms) {
-			dev_info(cm->dev, "Charging duration exceed %lldms",
+			dev_info(cm->dev, "Charging duration exceed %lldms\n",
 				 desc->charging_max_duration_ms);
 			uevent_notify(cm, "Discharging");
 			try_charger_enable(cm, false);
@@ -530,9 +529,9 @@ static int check_charging_duration(struc
 
 		if (duration > desc->charging_max_duration_ms &&
 				is_ext_pwr_online(cm)) {
-			dev_info(cm->dev, "DisCharging duration exceed %lldms",
+			dev_info(cm->dev, "Discharging duration exceed %lldms\n",
 				 desc->discharging_max_duration_ms);
-			uevent_notify(cm, "Recharing");
+			uevent_notify(cm, "Recharging");
 			try_charger_enable(cm, true);
 			ret = true;
 		}
@@ -579,7 +578,7 @@ static bool _cm_monitor(struct charger_m
 	 */
 	} else if (!cm->emergency_stop && check_charging_duration(cm)) {
 		dev_dbg(cm->dev,
-			"Charging/Discharging duration is out of range");
+			"Charging/Discharging duration is out of range\n");
 	/*
 	 * Check dropped voltage of battery. If battery voltage is more
 	 * dropped than fullbatt_vchkdrop_uV after fully charged state,
@@ -595,7 +594,7 @@ static bool _cm_monitor(struct charger_m
 	 */
 	} else if (!cm->emergency_stop && is_full_charged(cm) &&
 			cm->charger_enabled) {
-		dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n");
+		dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged\n");
 		uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]);
 
 		try_charger_enable(cm, false);
@@ -725,7 +724,7 @@ static void fullbatt_handler(struct char
 		cm->fullbatt_vchk_jiffies_at = 1;
 
 out:
-	dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n");
+	dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged\n");
 	uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]);
 }
 
@@ -972,7 +971,7 @@ static bool cm_setup_timer(void)
 	mutex_unlock(&cm_list_mtx);
 
 	if (wakeup_ms < UINT_MAX && wakeup_ms > 0) {
-		pr_info("Charger Manager wakeup timer: %u ms.\n", wakeup_ms);
+		pr_info("Charger Manager wakeup timer: %u ms\n", wakeup_ms);
 		if (rtc_dev) {
 			struct rtc_wkalrm tmp;
 			unsigned long time, now;
@@ -1005,8 +1004,7 @@ static bool cm_setup_timer(void)
 				ret = false;
 			}
 
-			pr_info("Waking up after %lu secs.\n",
-					time - now);
+			pr_info("Waking up after %lu secs\n", time - now);
 
 			rtc_time_to_tm(time, &tmp.time);
 			rtc_set_alarm(rtc_dev, &tmp);
@@ -1101,7 +1099,7 @@ int setup_charger_manager(struct charger
 	g_desc = NULL;
 
 	if (!gd->rtc_only_wakeup) {
-		pr_err("The callback rtc_only_wakeup is not given.\n");
+		pr_err("The callback rtc_only_wakeup is not given\n");
 		return -EINVAL;
 	}
 
@@ -1112,7 +1110,7 @@ int setup_charger_manager(struct charger
 			/* Retry at probe. RTC may be not registered yet */
 		}
 	} else {
-		pr_warn("No wakeup timer is given for charger manager."
+		pr_warn("No wakeup timer is given for charger manager.  "
 			"In-suspend monitoring won't work.\n");
 	}
 
@@ -1138,13 +1136,13 @@ static void charger_extcon_work(struct w
 					cable->min_uA, cable->max_uA);
 		if (ret < 0) {
 			pr_err("Cannot set current limit of %s (%s)\n",
-				cable->charger->regulator_name, cable->name);
+			       cable->charger->regulator_name, cable->name);
 			return;
 		}
 
 		pr_info("Set current limit of %s : %duA ~ %duA\n",
-					cable->charger->regulator_name,
-					cable->min_uA, cable->max_uA);
+			cable->charger->regulator_name,
+			cable->min_uA, cable->max_uA);
 	}
 
 	try_charger_enable(cable->cm, cable->attached);
@@ -1210,9 +1208,8 @@ static int charger_extcon_init(struct ch
 	ret = extcon_register_interest(&cable->extcon_dev,
 			cable->extcon_name, cable->name, &cable->nb);
 	if (ret < 0) {
-		pr_info("Cannot register extcon_dev for %s(cable: %s).\n",
-				cable->extcon_name,
-				cable->name);
+		pr_info("Cannot register extcon_dev for %s(cable: %s)\n",
+			cable->extcon_name, cable->name);
 		ret = -EINVAL;
 	}
 
@@ -1242,11 +1239,10 @@ static int charger_manager_register_extc
 
 		charger->consumer = regulator_get(cm->dev,
 					charger->regulator_name);
-		if (charger->consumer == NULL) {
-			dev_err(cm->dev, "Cannot find charger(%s)n",
-					charger->regulator_name);
-			ret = -EINVAL;
-			goto err;
+		if (IS_ERR(charger->consumer)) {
+			dev_err(cm->dev, "Cannot find charger(%s)\n",
+				charger->regulator_name);
+			return PTR_ERR(charger->consumer);
 		}
 		charger->cm = cm;
 
@@ -1255,8 +1251,8 @@ static int charger_manager_register_extc
 
 			ret = charger_extcon_init(cm, cable);
 			if (ret < 0) {
-				dev_err(cm->dev, "Cannot initialize charger(%s)n",
-						charger->regulator_name);
+				dev_err(cm->dev, "Cannot initialize charger(%s)\n",
+					charger->regulator_name);
 				goto err;
 			}
 			cable->charger = charger;
@@ -1347,10 +1343,8 @@ static ssize_t charger_externally_contro
 		}
 	} else {
 		dev_warn(cm->dev,
-			"'%s' regulator should be controlled "
-			"in charger-manager because charger-manager "
-			"must need at least one charger for charging\n",
-			charger->regulator_name);
+			 "'%s' regulator should be controlled in charger-manager because charger-manager must need at least one charger for charging\n",
+			 charger->regulator_name);
 	}
 
 	return count;
@@ -1386,8 +1380,6 @@ static int charger_manager_register_sysf
 		snprintf(buf, 10, "charger.%d", i);
 		str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL);
 		if (!str) {
-			dev_err(cm->dev, "Cannot allocate memory: %s\n",
-					charger->regulator_name);
 			ret = -ENOMEM;
 			goto err;
 		}
@@ -1423,26 +1415,21 @@ static int charger_manager_register_sysf
 				!chargers_externally_control)
 			chargers_externally_control = 0;
 
-		dev_info(cm->dev, "'%s' regulator's externally_control"
-				"is %d\n", charger->regulator_name,
-				charger->externally_control);
+		dev_info(cm->dev, "'%s' regulator's externally_control is %d\n",
+			 charger->regulator_name, charger->externally_control);
 
 		ret = sysfs_create_group(&cm->charger_psy.dev->kobj,
 					&charger->attr_g);
 		if (ret < 0) {
-			dev_err(cm->dev, "Cannot create sysfs entry"
-					"of %s regulator\n",
-					charger->regulator_name);
+			dev_err(cm->dev, "Cannot create sysfs entry of %s regulator\n",
+				charger->regulator_name);
 			ret = -EINVAL;
 			goto err;
 		}
 	}
 
 	if (chargers_externally_control) {
-		dev_err(cm->dev, "Cannot register regulator because "
-				"charger-manager must need at least "
-				"one charger for charging battery\n");
-
+		dev_err(cm->dev, "Cannot register regulator because charger-manager must need at least one charger for charging battery\n");
 		ret = -EINVAL;
 		goto err;
 	}
@@ -1463,7 +1450,7 @@ static int charger_manager_probe(struct
 		rtc_dev = rtc_class_open(g_desc->rtc_name);
 		if (IS_ERR_OR_NULL(rtc_dev)) {
 			rtc_dev = NULL;
-			dev_err(&pdev->dev, "Cannot get RTC %s.\n",
+			dev_err(&pdev->dev, "Cannot get RTC %s\n",
 				g_desc->rtc_name);
 			ret = -ENODEV;
 			goto err_alloc;
@@ -1471,14 +1458,13 @@ static int charger_manager_probe(struct
 	}
 
 	if (!desc) {
-		dev_err(&pdev->dev, "No platform data (desc) found.\n");
+		dev_err(&pdev->dev, "No platform data (desc) found\n");
 		ret = -ENODEV;
 		goto err_alloc;
 	}
 
 	cm = kzalloc(sizeof(struct charger_manager), GFP_KERNEL);
 	if (!cm) {
-		dev_err(&pdev->dev, "Cannot allocate memory.\n");
 		ret = -ENOMEM;
 		goto err_alloc;
 	}
@@ -1487,7 +1473,6 @@ static int charger_manager_probe(struct
 	cm->dev = &pdev->dev;
 	cm->desc = kmemdup(desc, sizeof(struct charger_desc), GFP_KERNEL);
 	if (!cm->desc) {
-		dev_err(&pdev->dev, "Cannot allocate memory.\n");
 		ret = -ENOMEM;
 		goto err_alloc_desc;
 	}
@@ -1498,33 +1483,28 @@ static int charger_manager_probe(struct
 	 * Users may intentionally ignore those two features.
 	 */
 	if (desc->fullbatt_uV == 0) {
-		dev_info(&pdev->dev, "Ignoring full-battery voltage threshold"
-					" as it is not supplied.");
+		dev_info(&pdev->dev, "Ignoring full-battery voltage threshold as it is not supplied\n");
 	}
 	if (!desc->fullbatt_vchkdrop_ms || !desc->fullbatt_vchkdrop_uV) {
-		dev_info(&pdev->dev, "Disabling full-battery voltage drop "
-				"checking mechanism as it is not supplied.");
+		dev_info(&pdev->dev, "Disabling full-battery voltage drop checking mechanism as it is not supplied\n");
 		desc->fullbatt_vchkdrop_ms = 0;
 		desc->fullbatt_vchkdrop_uV = 0;
 	}
 	if (desc->fullbatt_soc == 0) {
-		dev_info(&pdev->dev, "Ignoring full-battery soc(state of"
-					" charge) threshold as it is not"
-					" supplied.");
+		dev_info(&pdev->dev, "Ignoring full-battery soc(state of charge) threshold as it is not supplied\n");
 	}
 	if (desc->fullbatt_full_capacity == 0) {
-		dev_info(&pdev->dev, "Ignoring full-battery full capacity"
-					" threshold as it is not supplied.");
+		dev_info(&pdev->dev, "Ignoring full-battery full capacity threshold as it is not supplied\n");
 	}
 
 	if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
 		ret = -EINVAL;
-		dev_err(&pdev->dev, "charger_regulators undefined.\n");
+		dev_err(&pdev->dev, "charger_regulators undefined\n");
 		goto err_no_charger;
 	}
 
 	if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) {
-		dev_err(&pdev->dev, "No power supply defined.\n");
+		dev_err(&pdev->dev, "No power supply defined\n");
 		ret = -EINVAL;
 		goto err_no_charger_stat;
 	}
@@ -1544,9 +1524,8 @@ static int charger_manager_probe(struct
 		cm->charger_stat[i] = power_supply_get_by_name(
 					desc->psy_charger_stat[i]);
 		if (!cm->charger_stat[i]) {
-			dev_err(&pdev->dev, "Cannot find power supply "
-					"\"%s\"\n",
-					desc->psy_charger_stat[i]);
+			dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
+				desc->psy_charger_stat[i]);
 			ret = -ENODEV;
 			goto err_chg_stat;
 		}
@@ -1555,7 +1534,7 @@ static int charger_manager_probe(struct
 	cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
 	if (!cm->fuel_gauge) {
 		dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
-				desc->psy_fuel_gauge);
+			desc->psy_fuel_gauge);
 		ret = -ENODEV;
 		goto err_chg_stat;
 	}
@@ -1575,9 +1554,7 @@ static int charger_manager_probe(struct
 
 	if (!desc->charging_max_duration_ms ||
 			!desc->discharging_max_duration_ms) {
-		dev_info(&pdev->dev, "Cannot limit charging duration "
-			 "checking mechanism to prevent overcharge/overheat "
-			 "and control discharging duration");
+		dev_info(&pdev->dev, "Cannot limit charging duration checking mechanism to prevent overcharge/overheat and control discharging duration\n");
 		desc->charging_max_duration_ms = 0;
 		desc->discharging_max_duration_ms = 0;
 	}
@@ -1598,7 +1575,6 @@ static int charger_manager_probe(struct
 				NUM_CHARGER_PSY_OPTIONAL),
 				GFP_KERNEL);
 	if (!cm->charger_psy.properties) {
-		dev_err(&pdev->dev, "Cannot allocate for psy properties.\n");
 		ret = -ENOMEM;
 		goto err_chg_stat;
 	}
@@ -1636,8 +1612,8 @@ static int charger_manager_probe(struct
 
 	ret = power_supply_register(NULL, &cm->charger_psy);
 	if (ret) {
-		dev_err(&pdev->dev, "Cannot register charger-manager with"
-				" name \"%s\".\n", cm->charger_psy.name);
+		dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n",
+			cm->charger_psy.name);
 		goto err_register;
 	}
 
@@ -1689,7 +1665,9 @@ err_reg_extcon:
 		charger = &desc->charger_regulators[i];
 		for (j = 0; j < charger->num_cables; j++) {
 			struct charger_cable *cable = &charger->cables[j];
-			extcon_unregister_interest(&cable->extcon_dev);
+			/* Remove notifier block if only edev exists */
+			if (cable->extcon_dev.edev)
+				extcon_unregister_interest(&cable->extcon_dev);
 		}
 
 		regulator_put(desc->charger_regulators[i].consumer);
@@ -1948,7 +1926,7 @@ void cm_notify_event(struct power_supply
 		uevent_notify(cm, msg ? msg : default_event_names[type]);
 		break;
 	default:
-		dev_err(cm->dev, "%s type not specified.\n", __func__);
+		dev_err(cm->dev, "%s: type not specified\n", __func__);
 		break;
 	}
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/generic-adc-battery.c linux-libre-3.11-rc7-gnu/drivers/power/generic-adc-battery.c
--- linux-libre-3.10-gnu/drivers/power/generic-adc-battery.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/generic-adc-battery.c	2013-08-25 20:43:22.000000000 -0400
@@ -299,8 +299,10 @@ static int gab_probe(struct platform_dev
 	}
 
 	/* none of the channels are supported so let's bail out */
-	if (index == ARRAY_SIZE(gab_chan_name))
+	if (index == 0) {
+		ret = -ENODEV;
 		goto second_mem_fail;
+	}
 
 	/*
 	 * Total number of properties is equal to static properties
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/gpio-charger.c linux-libre-3.11-rc7-gnu/drivers/power/gpio-charger.c
--- linux-libre-3.10-gnu/drivers/power/gpio-charger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/gpio-charger.c	2013-08-25 20:43:22.000000000 -0400
@@ -155,8 +155,6 @@ static int gpio_charger_remove(struct pl
 
 	gpio_free(gpio_charger->pdata->gpio);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/intel_mid_battery.c linux-libre-3.11-rc7-gnu/drivers/power/intel_mid_battery.c
--- linux-libre-3.10-gnu/drivers/power/intel_mid_battery.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/intel_mid_battery.c	2013-08-25 20:43:22.000000000 -0400
@@ -756,7 +756,7 @@ static int platform_pmic_battery_probe(s
 
 static int platform_pmic_battery_remove(struct platform_device *pdev)
 {
-	struct pmic_power_module_info *pbi = dev_get_drvdata(&pdev->dev);
+	struct pmic_power_module_info *pbi = platform_get_drvdata(pdev);
 
 	free_irq(pbi->irq, pbi);
 	cancel_delayed_work_sync(&pbi->monitor_battery);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/jz4740-battery.c linux-libre-3.11-rc7-gnu/drivers/power/jz4740-battery.c
--- linux-libre-3.10-gnu/drivers/power/jz4740-battery.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/jz4740-battery.c	2013-08-25 20:43:22.000000000 -0400
@@ -292,7 +292,7 @@ static int jz_battery_probe(struct platf
 			jz_battery);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to request irq %d\n", ret);
-		goto err;
+		return ret;
 	}
 	disable_irq(jz_battery->irq);
 
@@ -349,8 +349,6 @@ err_free_gpio:
 		gpio_free(jz_battery->pdata->gpio_charge);
 err_free_irq:
 	free_irq(jz_battery->irq, jz_battery);
-err:
-	platform_set_drvdata(pdev, NULL);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/lp8727_charger.c linux-libre-3.11-rc7-gnu/drivers/power/lp8727_charger.c
--- linux-libre-3.10-gnu/drivers/power/lp8727_charger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/lp8727_charger.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/i2c.h>
 #include <linux/power_supply.h>
 #include <linux/platform_data/lp8727.h>
+#include <linux/of.h>
 
 #define LP8788_NUM_INTREGS	2
 #define DEFAULT_DEBOUNCE_MSEC	270
@@ -481,6 +482,60 @@ static void lp8727_unregister_psy(struct
 	power_supply_unregister(&psy->batt);
 }
 
+#ifdef CONFIG_OF
+static struct lp8727_chg_param
+*lp8727_parse_charge_pdata(struct device *dev, struct device_node *np)
+{
+	struct lp8727_chg_param *param;
+
+	param = devm_kzalloc(dev, sizeof(*param), GFP_KERNEL);
+	if (!param)
+		goto out;
+
+	of_property_read_u8(np, "eoc-level", (u8 *)&param->eoc_level);
+	of_property_read_u8(np, "charging-current", (u8 *)&param->ichg);
+out:
+	return param;
+}
+
+static int lp8727_parse_dt(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct device_node *child;
+	struct lp8727_platform_data *pdata;
+	const char *type;
+
+	/* If charging parameter is not defined, just skip parsing the dt */
+	if (of_get_child_count(np) == 0)
+		goto out;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	of_property_read_u32(np, "debounce-ms", &pdata->debounce_msec);
+
+	for_each_child_of_node(np, child) {
+		of_property_read_string(child, "charger-type", &type);
+
+		if (!strcmp(type, "ac"))
+			pdata->ac = lp8727_parse_charge_pdata(dev, child);
+
+		if (!strcmp(type, "usb"))
+			pdata->usb = lp8727_parse_charge_pdata(dev, child);
+	}
+
+	dev->platform_data = pdata;
+out:
+	return 0;
+}
+#else
+static int lp8727_parse_dt(struct device *dev)
+{
+	return 0;
+}
+#endif
+
 static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
 {
 	struct lp8727_chg *pchg;
@@ -489,6 +544,12 @@ static int lp8727_probe(struct i2c_clien
 	if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
 		return -EIO;
 
+	if (cl->dev.of_node) {
+		ret = lp8727_parse_dt(&cl->dev);
+		if (ret)
+			return ret;
+	}
+
 	pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL);
 	if (!pchg)
 		return -ENOMEM;
@@ -531,6 +592,12 @@ static int lp8727_remove(struct i2c_clie
 	return 0;
 }
 
+static const struct of_device_id lp8727_dt_ids[] = {
+	{ .compatible = "ti,lp8727", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, lp8727_dt_ids);
+
 static const struct i2c_device_id lp8727_ids[] = {
 	{"lp8727", 0},
 	{ }
@@ -540,6 +607,7 @@ MODULE_DEVICE_TABLE(i2c, lp8727_ids);
 static struct i2c_driver lp8727_driver = {
 	.driver = {
 		   .name = "lp8727",
+		   .of_match_table = of_match_ptr(lp8727_dt_ids),
 		   },
 	.probe = lp8727_probe,
 	.remove = lp8727_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/pcf50633-charger.c linux-libre-3.11-rc7-gnu/drivers/power/pcf50633-charger.c
--- linux-libre-3.10-gnu/drivers/power/pcf50633-charger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/pcf50633-charger.c	2013-08-25 20:43:22.000000000 -0400
@@ -191,9 +191,9 @@ static ssize_t set_usblim(struct device
 	unsigned long ma;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &ma);
+	ret = kstrtoul(buf, 10, &ma);
 	if (ret)
-		return -EINVAL;
+		return ret;
 
 	pcf50633_mbc_usb_curlim_set(mbc->pcf, ma);
 
@@ -228,9 +228,9 @@ static ssize_t set_chglim(struct device
 	if (!mbc->pcf->pdata->charger_reference_current_ma)
 		return -ENODEV;
 
-	ret = strict_strtoul(buf, 10, &ma);
+	ret = kstrtoul(buf, 10, &ma);
 	if (ret)
-		return -EINVAL;
+		return ret;
 
 	mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma;
 	if (mbcc5 > 255)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/pm2301_charger.c linux-libre-3.11-rc7-gnu/drivers/power/pm2301_charger.c
--- linux-libre-3.10-gnu/drivers/power/pm2301_charger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/pm2301_charger.c	2013-08-25 20:43:22.000000000 -0400
@@ -1007,9 +1007,14 @@ static int pm2xxx_wall_charger_probe(str
 	u8 val;
 	int i;
 
+	if (!pl_data) {
+		dev_err(&i2c_client->dev, "No platform data supplied\n");
+		return -EINVAL;
+	}
+
 	pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL);
 	if (!pm2) {
-		dev_err(pm2->dev, "pm2xxx_charger allocation failed\n");
+		dev_err(&i2c_client->dev, "pm2xxx_charger allocation failed\n");
 		return -ENOMEM;
 	}
 
@@ -1070,9 +1075,9 @@ static int pm2xxx_wall_charger_probe(str
 	pm2->ac_chg.external = true;
 
 	/* Create a work queue for the charger */
-	pm2->charger_wq =
-		create_singlethread_workqueue("pm2xxx_charger_wq");
+	pm2->charger_wq = create_singlethread_workqueue("pm2xxx_charger_wq");
 	if (pm2->charger_wq == NULL) {
+		ret = -ENOMEM;
 		dev_err(pm2->dev, "failed to create work queue\n");
 		goto free_device_info;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/power_supply_core.c linux-libre-3.11-rc7-gnu/drivers/power/power_supply_core.c
--- linux-libre-3.10-gnu/drivers/power/power_supply_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/power_supply_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -109,8 +109,10 @@ static int __power_supply_populate_suppl
 				psy->name, epsy->name);
 			psy->supplied_from[i-1] = (char *)epsy->name;
 			psy->num_supplies++;
+			of_node_put(np);
 			break;
 		}
+		of_node_put(np);
 	} while (np);
 
 	return 0;
@@ -193,8 +195,10 @@ static int power_supply_check_supplies(s
 		ret = power_supply_find_supply_from_node(np);
 		if (ret) {
 			dev_dbg(psy->dev, "Failed to find supply, defer!\n");
+			of_node_put(np);
 			return -EPROBE_DEFER;
 		}
+		of_node_put(np);
 	} while (np);
 
 	/* All supplies found, allocate char ** array for filling */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/reset/Kconfig linux-libre-3.11-rc7-gnu/drivers/power/reset/Kconfig
--- linux-libre-3.10-gnu/drivers/power/reset/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/reset/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -32,7 +32,8 @@ config POWER_RESET_RESTART
 	  user presses a key. u-boot then boots into Linux.
 
 config POWER_RESET_VEXPRESS
-	bool
+	bool "ARM Versatile Express power-off and reset driver"
+	depends on ARM || ARM64
 	depends on POWER_RESET
 	help
 	  Power off and reset support for the ARM Ltd. Versatile
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/reset/restart-poweroff.c linux-libre-3.11-rc7-gnu/drivers/power/reset/restart-poweroff.c
--- linux-libre-3.10-gnu/drivers/power/reset/restart-poweroff.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/reset/restart-poweroff.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,11 +15,12 @@
 #include <linux/platform_device.h>
 #include <linux/of_platform.h>
 #include <linux/module.h>
+#include <linux/reboot.h>
 #include <asm/system_misc.h>
 
 static void restart_poweroff_do_poweroff(void)
 {
-	arm_pm_restart('h', NULL);
+	arm_pm_restart(REBOOT_HARD, NULL);
 }
 
 static int restart_poweroff_probe(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/reset/vexpress-poweroff.c linux-libre-3.11-rc7-gnu/drivers/power/reset/vexpress-poweroff.c
--- linux-libre-3.10-gnu/drivers/power/reset/vexpress-poweroff.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/reset/vexpress-poweroff.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,7 +48,7 @@ static void vexpress_power_off(void)
 
 static struct device *vexpress_restart_device;
 
-static void vexpress_restart(char str, const char *cmd)
+static void vexpress_restart(enum reboot_mode reboot_mode, const char *cmd)
 {
 	vexpress_reset_do(vexpress_restart_device, "restart");
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/rx51_battery.c linux-libre-3.11-rc7-gnu/drivers/power/rx51_battery.c
--- linux-libre-3.10-gnu/drivers/power/rx51_battery.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/rx51_battery.c	2013-08-25 20:43:22.000000000 -0400
@@ -216,10 +216,8 @@ static int rx51_battery_probe(struct pla
 	di->bat.get_property = rx51_battery_get_property;
 
 	ret = power_supply_register(di->dev, &di->bat);
-	if (ret) {
-		platform_set_drvdata(pdev, NULL);
+	if (ret)
 		return ret;
-	}
 
 	return 0;
 }
@@ -229,7 +227,6 @@ static int rx51_battery_remove(struct pl
 	struct rx51_device_info *di = platform_get_drvdata(pdev);
 
 	power_supply_unregister(&di->bat);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/sbs-battery.c linux-libre-3.11-rc7-gnu/drivers/power/sbs-battery.c
--- linux-libre-3.10-gnu/drivers/power/sbs-battery.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/sbs-battery.c	2013-08-25 20:43:22.000000000 -0400
@@ -704,6 +704,7 @@ static int sbs_probe(struct i2c_client *
 	chip->power_supply.properties = sbs_properties;
 	chip->power_supply.num_properties = ARRAY_SIZE(sbs_properties);
 	chip->power_supply.get_property = sbs_get_property;
+	chip->power_supply.of_node = client->dev.of_node;
 	/* ignore first notification of external change, it is generated
 	 * from the power_supply_register call back
 	 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/tps65090-charger.c linux-libre-3.11-rc7-gnu/drivers/power/tps65090-charger.c
--- linux-libre-3.10-gnu/drivers/power/tps65090-charger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/tps65090-charger.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/mfd/tps65090.h>
 
 #define TPS65090_REG_INTR_STS	0x00
+#define TPS65090_REG_INTR_MASK	0x02
 #define TPS65090_REG_CG_CTRL0	0x04
 #define TPS65090_REG_CG_CTRL1	0x05
 #define TPS65090_REG_CG_CTRL2	0x06
@@ -67,8 +68,7 @@ static int tps65090_low_chrg_current(str
 	return 0;
 }
 
-static int tps65090_enable_charging(struct tps65090_charger *charger,
-	uint8_t enable)
+static int tps65090_enable_charging(struct tps65090_charger *charger)
 {
 	int ret;
 	uint8_t ctrl0 = 0;
@@ -84,7 +84,7 @@ static int tps65090_enable_charging(stru
 	ret = tps65090_write(charger->dev->parent, TPS65090_REG_CG_CTRL0,
 				(ctrl0 | TPS65090_CHARGER_ENABLE));
 	if (ret < 0) {
-		dev_err(charger->dev, "%s(): error reading in register 0x%x\n",
+		dev_err(charger->dev, "%s(): error writing in register 0x%x\n",
 				__func__, TPS65090_REG_CG_CTRL0);
 		return ret;
 	}
@@ -93,6 +93,7 @@ static int tps65090_enable_charging(stru
 
 static int tps65090_config_charger(struct tps65090_charger *charger)
 {
+	uint8_t intrmask = 0;
 	int ret;
 
 	if (charger->pdata->enable_low_current_chrg) {
@@ -104,6 +105,23 @@ static int tps65090_config_charger(struc
 		}
 	}
 
+	/* Enable the VACG interrupt for AC power detect */
+	ret = tps65090_read(charger->dev->parent, TPS65090_REG_INTR_MASK,
+			    &intrmask);
+	if (ret < 0) {
+		dev_err(charger->dev, "%s(): error reading in register 0x%x\n",
+			__func__, TPS65090_REG_INTR_MASK);
+		return ret;
+	}
+
+	ret = tps65090_write(charger->dev->parent, TPS65090_REG_INTR_MASK,
+			     (intrmask | TPS65090_VACG));
+	if (ret < 0) {
+		dev_err(charger->dev, "%s(): error writing in register 0x%x\n",
+			__func__, TPS65090_REG_CG_CTRL0);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -146,7 +164,7 @@ static irqreturn_t tps65090_charger_isr(
 	}
 
 	if (intrsts & TPS65090_VACG) {
-		ret = tps65090_enable_charging(charger, 1);
+		ret = tps65090_enable_charging(charger);
 		if (ret < 0)
 			return IRQ_HANDLED;
 		charger->ac_online = 1;
@@ -154,6 +172,13 @@ static irqreturn_t tps65090_charger_isr(
 		charger->ac_online = 0;
 	}
 
+	/* Clear interrupts. */
+	ret = tps65090_write(charger->dev->parent, TPS65090_REG_INTR_STS, 0x00);
+	if (ret < 0) {
+		dev_err(charger->dev, "%s(): Error in writing reg 0x%x\n",
+				__func__, TPS65090_REG_INTR_STS);
+	}
+
 	if (charger->prev_ac_online != charger->ac_online)
 		power_supply_changed(&charger->ac);
 
@@ -218,7 +243,7 @@ static int tps65090_charger_probe(struct
 		return -ENOMEM;
 	}
 
-	dev_set_drvdata(&pdev->dev, cdata);
+	platform_set_drvdata(pdev, cdata);
 
 	cdata->dev			= &pdev->dev;
 	cdata->pdata			= pdata;
@@ -230,6 +255,7 @@ static int tps65090_charger_probe(struct
 	cdata->ac.num_properties	= ARRAY_SIZE(tps65090_ac_props);
 	cdata->ac.supplied_to		= pdata->supplied_to;
 	cdata->ac.num_supplicants	= pdata->num_supplicants;
+	cdata->ac.of_node		= pdev->dev.of_node;
 
 	ret = power_supply_register(&pdev->dev, &cdata->ac);
 	if (ret) {
@@ -270,7 +296,7 @@ static int tps65090_charger_probe(struct
 	}
 
 	if (status1 != 0) {
-		ret = tps65090_enable_charging(cdata, 1);
+		ret = tps65090_enable_charging(cdata);
 		if (ret < 0) {
 			dev_err(cdata->dev, "error enabling charger\n");
 			goto fail_free_irq;
@@ -291,7 +317,7 @@ fail_unregister_supply:
 
 static int tps65090_charger_remove(struct platform_device *pdev)
 {
-	struct tps65090_charger *cdata = dev_get_drvdata(&pdev->dev);
+	struct tps65090_charger *cdata = platform_get_drvdata(pdev);
 
 	devm_free_irq(cdata->dev, cdata->irq, cdata);
 	power_supply_unregister(&cdata->ac);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/power/twl4030_charger.c linux-libre-3.11-rc7-gnu/drivers/power/twl4030_charger.c
--- linux-libre-3.10-gnu/drivers/power/twl4030_charger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/power/twl4030_charger.c	2013-08-25 20:43:22.000000000 -0400
@@ -594,7 +594,6 @@ fail_chg_irq:
 fail_register_usb:
 	power_supply_unregister(&bci->ac);
 fail_register_ac:
-	platform_set_drvdata(pdev, NULL);
 	kfree(bci);
 
 	return ret;
@@ -622,7 +621,6 @@ static int __exit twl4030_bci_remove(str
 	free_irq(bci->irq_chg, bci);
 	power_supply_unregister(&bci->usb);
 	power_supply_unregister(&bci->ac);
-	platform_set_drvdata(pdev, NULL);
 	kfree(bci);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pps/clients/pps-gpio.c linux-libre-3.11-rc7-gnu/drivers/pps/clients/pps-gpio.c
--- linux-libre-3.10-gnu/drivers/pps/clients/pps-gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pps/clients/pps-gpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,13 +33,17 @@
 #include <linux/pps-gpio.h>
 #include <linux/gpio.h>
 #include <linux/list.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 
 /* Info for each registered platform device */
 struct pps_gpio_device_data {
 	int irq;			/* IRQ used as PPS source */
 	struct pps_device *pps;		/* PPS source device */
 	struct pps_source_info info;	/* PPS source information */
-	const struct pps_gpio_platform_data *pdata;
+	bool assert_falling_edge;
+	bool capture_clear;
+	unsigned int gpio_pin;
 };
 
 /*
@@ -57,46 +61,25 @@ static irqreturn_t pps_gpio_irq_handler(
 
 	info = data;
 
-	rising_edge = gpio_get_value(info->pdata->gpio_pin);
-	if ((rising_edge && !info->pdata->assert_falling_edge) ||
-			(!rising_edge && info->pdata->assert_falling_edge))
+	rising_edge = gpio_get_value(info->gpio_pin);
+	if ((rising_edge && !info->assert_falling_edge) ||
+			(!rising_edge && info->assert_falling_edge))
 		pps_event(info->pps, &ts, PPS_CAPTUREASSERT, NULL);
-	else if (info->pdata->capture_clear &&
-			((rising_edge && info->pdata->assert_falling_edge) ||
-			 (!rising_edge && !info->pdata->assert_falling_edge)))
+	else if (info->capture_clear &&
+			((rising_edge && info->assert_falling_edge) ||
+			 (!rising_edge && !info->assert_falling_edge)))
 		pps_event(info->pps, &ts, PPS_CAPTURECLEAR, NULL);
 
 	return IRQ_HANDLED;
 }
 
-static int pps_gpio_setup(struct platform_device *pdev)
-{
-	int ret;
-	const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data;
-
-	ret = gpio_request(pdata->gpio_pin, pdata->gpio_label);
-	if (ret) {
-		pr_warning("failed to request GPIO %u\n", pdata->gpio_pin);
-		return -EINVAL;
-	}
-
-	ret = gpio_direction_input(pdata->gpio_pin);
-	if (ret) {
-		pr_warning("failed to set pin direction\n");
-		gpio_free(pdata->gpio_pin);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static unsigned long
-get_irqf_trigger_flags(const struct pps_gpio_platform_data *pdata)
+get_irqf_trigger_flags(const struct pps_gpio_device_data *data)
 {
-	unsigned long flags = pdata->assert_falling_edge ?
+	unsigned long flags = data->assert_falling_edge ?
 		IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
 
-	if (pdata->capture_clear) {
+	if (data->capture_clear) {
 		flags |= ((flags & IRQF_TRIGGER_RISING) ?
 				IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING);
 	}
@@ -107,38 +90,63 @@ get_irqf_trigger_flags(const struct pps_
 static int pps_gpio_probe(struct platform_device *pdev)
 {
 	struct pps_gpio_device_data *data;
-	int irq;
+	const char *gpio_label;
 	int ret;
-	int err;
 	int pps_default_params;
 	const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data;
+	struct device_node *np = pdev->dev.of_node;
 
+	/* allocate space for device info */
+	data = devm_kzalloc(&pdev->dev, sizeof(struct pps_gpio_device_data),
+			GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	if (pdata) {
+		data->gpio_pin = pdata->gpio_pin;
+		gpio_label = pdata->gpio_label;
+
+		data->assert_falling_edge = pdata->assert_falling_edge;
+		data->capture_clear = pdata->capture_clear;
+	} else {
+		ret = of_get_gpio(np, 0);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "failed to get GPIO from device tree\n");
+			return ret;
+		}
+		data->gpio_pin = ret;
+		gpio_label = PPS_GPIO_NAME;
+
+		if (of_get_property(np, "assert-falling-edge", NULL))
+			data->assert_falling_edge = true;
+	}
 
 	/* GPIO setup */
-	ret = pps_gpio_setup(pdev);
-	if (ret)
-		return -EINVAL;
+	ret = devm_gpio_request(&pdev->dev, data->gpio_pin, gpio_label);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request GPIO %u\n",
+			data->gpio_pin);
+		return ret;
+	}
 
-	/* IRQ setup */
-	irq = gpio_to_irq(pdata->gpio_pin);
-	if (irq < 0) {
-		pr_err("failed to map GPIO to IRQ: %d\n", irq);
-		err = -EINVAL;
-		goto return_error;
+	ret = gpio_direction_input(data->gpio_pin);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to set pin direction\n");
+		return -EINVAL;
 	}
 
-	/* allocate space for device info */
-	data = devm_kzalloc(&pdev->dev, sizeof(struct pps_gpio_device_data),
-			    GFP_KERNEL);
-	if (data == NULL) {
-		err = -ENOMEM;
-		goto return_error;
+	/* IRQ setup */
+	ret = gpio_to_irq(data->gpio_pin);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to map GPIO to IRQ: %d\n", ret);
+		return -EINVAL;
 	}
+	data->irq = ret;
 
 	/* initialize PPS specific parts of the bookkeeping data structure. */
 	data->info.mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT |
 		PPS_ECHOASSERT | PPS_CANWAIT | PPS_TSFMT_TSPEC;
-	if (pdata->capture_clear)
+	if (data->capture_clear)
 		data->info.mode |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR |
 			PPS_ECHOCLEAR;
 	data->info.owner = THIS_MODULE;
@@ -147,77 +155,58 @@ static int pps_gpio_probe(struct platfor
 
 	/* register PPS source */
 	pps_default_params = PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
-	if (pdata->capture_clear)
+	if (data->capture_clear)
 		pps_default_params |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR;
 	data->pps = pps_register_source(&data->info, pps_default_params);
 	if (data->pps == NULL) {
-		pr_err("failed to register IRQ %d as PPS source\n", irq);
-		err = -EINVAL;
-		goto return_error;
+		dev_err(&pdev->dev, "failed to register IRQ %d as PPS source\n",
+			data->irq);
+		return -EINVAL;
 	}
 
-	data->irq = irq;
-	data->pdata = pdata;
-
 	/* register IRQ interrupt handler */
-	ret = request_irq(irq, pps_gpio_irq_handler,
-			get_irqf_trigger_flags(pdata), data->info.name, data);
+	ret = devm_request_irq(&pdev->dev, data->irq, pps_gpio_irq_handler,
+			get_irqf_trigger_flags(data), data->info.name, data);
 	if (ret) {
 		pps_unregister_source(data->pps);
-		pr_err("failed to acquire IRQ %d\n", irq);
-		err = -EINVAL;
-		goto return_error;
+		dev_err(&pdev->dev, "failed to acquire IRQ %d\n", data->irq);
+		return -EINVAL;
 	}
 
 	platform_set_drvdata(pdev, data);
-	dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", irq);
+	dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n",
+		 data->irq);
 
 	return 0;
-
-return_error:
-	gpio_free(pdata->gpio_pin);
-	return err;
 }
 
 static int pps_gpio_remove(struct platform_device *pdev)
 {
 	struct pps_gpio_device_data *data = platform_get_drvdata(pdev);
-	const struct pps_gpio_platform_data *pdata = data->pdata;
 
 	platform_set_drvdata(pdev, NULL);
-	free_irq(data->irq, data);
-	gpio_free(pdata->gpio_pin);
 	pps_unregister_source(data->pps);
-	pr_info("removed IRQ %d as PPS source\n", data->irq);
+	dev_info(&pdev->dev, "removed IRQ %d as PPS source\n", data->irq);
 	return 0;
 }
 
+static const struct of_device_id pps_gpio_dt_ids[] = {
+	{ .compatible = "pps-gpio", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pps_gpio_dt_ids);
+
 static struct platform_driver pps_gpio_driver = {
 	.probe		= pps_gpio_probe,
 	.remove		= pps_gpio_remove,
 	.driver		= {
 		.name	= PPS_GPIO_NAME,
-		.owner	= THIS_MODULE
+		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(pps_gpio_dt_ids),
 	},
 };
 
-static int __init pps_gpio_init(void)
-{
-	int ret = platform_driver_register(&pps_gpio_driver);
-	if (ret < 0)
-		pr_err("failed to register platform driver\n");
-	return ret;
-}
-
-static void __exit pps_gpio_exit(void)
-{
-	platform_driver_unregister(&pps_gpio_driver);
-	pr_debug("unregistered platform driver\n");
-}
-
-module_init(pps_gpio_init);
-module_exit(pps_gpio_exit);
-
+module_platform_driver(pps_gpio_driver);
 MODULE_AUTHOR("Ricardo Martins <rasm@fe.up.pt>");
 MODULE_AUTHOR("James Nuss <jamesnuss@nanometrics.ca>");
 MODULE_DESCRIPTION("Use GPIO pin as PPS source");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ptp/Kconfig linux-libre-3.11-rc7-gnu/drivers/ptp/Kconfig
--- linux-libre-3.10-gnu/drivers/ptp/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ptp/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -72,6 +72,7 @@ config DP83640_PHY
 
 config PTP_1588_CLOCK_PCH
 	tristate "Intel PCH EG20T as PTP clock"
+	depends on X86 || COMPILE_TEST
 	select PTP_1588_CLOCK
 	help
 	  This driver adds support for using the PCH EG20T as a PTP
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/core.c linux-libre-3.11-rc7-gnu/drivers/pwm/core.c
--- linux-libre-3.10-gnu/drivers/pwm/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -274,6 +274,8 @@ int pwmchip_add(struct pwm_chip *chip)
 	if (IS_ENABLED(CONFIG_OF))
 		of_pwmchip_add(chip);
 
+	pwmchip_sysfs_export(chip);
+
 out:
 	mutex_unlock(&pwm_lock);
 	return ret;
@@ -310,6 +312,8 @@ int pwmchip_remove(struct pwm_chip *chip
 
 	free_pwms(chip);
 
+	pwmchip_sysfs_unexport(chip);
+
 out:
 	mutex_unlock(&pwm_lock);
 	return ret;
@@ -402,10 +406,19 @@ EXPORT_SYMBOL_GPL(pwm_free);
  */
 int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
 {
+	int err;
+
 	if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
 		return -EINVAL;
 
-	return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
+	err = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
+	if (err)
+		return err;
+
+	pwm->duty_cycle = duty_ns;
+	pwm->period = period_ns;
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(pwm_config);
 
@@ -418,6 +431,8 @@ EXPORT_SYMBOL_GPL(pwm_config);
  */
 int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
 {
+	int err;
+
 	if (!pwm || !pwm->chip->ops)
 		return -EINVAL;
 
@@ -427,7 +442,13 @@ int pwm_set_polarity(struct pwm_device *
 	if (test_bit(PWMF_ENABLED, &pwm->flags))
 		return -EBUSY;
 
-	return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
+	err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
+	if (err)
+		return err;
+
+	pwm->polarity = polarity;
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(pwm_set_polarity);
 
@@ -694,7 +715,7 @@ struct pwm_device *devm_pwm_get(struct d
 {
 	struct pwm_device **ptr, *pwm;
 
-	ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL);
+	ptr = devres_alloc(devm_pwm_release, sizeof(*ptr), GFP_KERNEL);
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 
@@ -724,7 +745,7 @@ struct pwm_device *devm_of_pwm_get(struc
 {
 	struct pwm_device **ptr, *pwm;
 
-	ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL);
+	ptr = devres_alloc(devm_pwm_release, sizeof(*ptr), GFP_KERNEL);
 	if (!ptr)
 		return ERR_PTR(-ENOMEM);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/Kconfig linux-libre-3.11-rc7-gnu/drivers/pwm/Kconfig
--- linux-libre-3.10-gnu/drivers/pwm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -28,6 +28,10 @@ menuconfig PWM
 
 if PWM
 
+config PWM_SYSFS
+	bool
+	default y if SYSFS
+
 config PWM_AB8500
 	tristate "AB8500 PWM support"
 	depends on AB8500_CORE && ARCH_U8500
@@ -97,6 +101,15 @@ config PWM_MXS
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-mxs.
 
+config PWM_PCA9685
+	tristate "NXP PCA9685 PWM driver"
+	depends on OF && REGMAP_I2C
+	help
+	  Generic PWM framework driver for NXP PCA9685 LED controller.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-pca9685.
+
 config PWM_PUV3
 	tristate "PKUnity NetBook-0916 PWM support"
 	depends on ARCH_PUV3
@@ -115,6 +128,16 @@ config PWM_PXA
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-pxa.
 
+config PWM_RENESAS_TPU
+	tristate "Renesas TPU PWM support"
+	depends on ARCH_SHMOBILE
+	help
+	  This driver exposes the Timer Pulse Unit (TPU) PWM controller found
+	  in Renesas chips through the PWM API.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-renesas-tpu.
+
 config PWM_SAMSUNG
 	tristate "Samsung PWM support"
 	depends on PLAT_SAMSUNG
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/Makefile linux-libre-3.11-rc7-gnu/drivers/pwm/Makefile
--- linux-libre-3.10-gnu/drivers/pwm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,5 @@
 obj-$(CONFIG_PWM)		+= core.o
+obj-$(CONFIG_PWM_SYSFS)		+= sysfs.o
 obj-$(CONFIG_PWM_AB8500)	+= pwm-ab8500.o
 obj-$(CONFIG_PWM_ATMEL_TCB)	+= pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
@@ -6,8 +7,10 @@ obj-$(CONFIG_PWM_IMX)		+= pwm-imx.o
 obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
 obj-$(CONFIG_PWM_LPC32XX)	+= pwm-lpc32xx.o
 obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o
+obj-$(CONFIG_PWM_PCA9685)	+= pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
+obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_SPEAR)		+= pwm-spear.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-atmel-tcb.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-atmel-tcb.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-atmel-tcb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-atmel-tcb.c	2013-08-25 20:43:22.000000000 -0400
@@ -76,7 +76,7 @@ static int atmel_tcb_pwm_request(struct
 	if (!tcbpwm)
 		return -ENOMEM;
 
-	ret = clk_enable(tc->clk[group]);
+	ret = clk_prepare_enable(tc->clk[group]);
 	if (ret) {
 		devm_kfree(chip->dev, tcbpwm);
 		return ret;
@@ -124,7 +124,7 @@ static void atmel_tcb_pwm_free(struct pw
 	struct atmel_tcb_pwm_device *tcbpwm = pwm_get_chip_data(pwm);
 	struct atmel_tc *tc = tcbpwmc->tc;
 
-	clk_disable(tc->clk[pwm->hwpwm / 2]);
+	clk_disable_unprepare(tc->clk[pwm->hwpwm / 2]);
 	tcbpwmc->pwms[pwm->hwpwm] = NULL;
 	devm_kfree(chip->dev, tcbpwm);
 }
@@ -434,6 +434,7 @@ MODULE_DEVICE_TABLE(of, atmel_tcb_pwm_dt
 static struct platform_driver atmel_tcb_pwm_driver = {
 	.driver = {
 		.name = "atmel-tcb-pwm",
+		.owner = THIS_MODULE,
 		.of_match_table = atmel_tcb_pwm_dt_ids,
 	},
 	.probe = atmel_tcb_pwm_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-bfin.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-bfin.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-bfin.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-bfin.c	2013-08-25 20:43:22.000000000 -0400
@@ -149,6 +149,7 @@ static int bfin_pwm_remove(struct platfo
 static struct platform_driver bfin_pwm_driver = {
 	.driver = {
 		.name = "bfin-pwm",
+		.owner = THIS_MODULE,
 	},
 	.probe = bfin_pwm_probe,
 	.remove = bfin_pwm_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-imx.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-imx.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-imx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-imx.c	2013-08-25 20:43:22.000000000 -0400
@@ -295,6 +295,7 @@ static int imx_pwm_remove(struct platfor
 static struct platform_driver imx_pwm_driver = {
 	.driver		= {
 		.name	= "imx-pwm",
+		.owner = THIS_MODULE,
 		.of_match_table = of_match_ptr(imx_pwm_dt_ids),
 	},
 	.probe		= imx_pwm_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-lpc32xx.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-lpc32xx.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-lpc32xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-lpc32xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -171,6 +171,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_pwm_dt_i
 static struct platform_driver lpc32xx_pwm_driver = {
 	.driver = {
 		.name = "lpc32xx-pwm",
+		.owner = THIS_MODULE,
 		.of_match_table = of_match_ptr(lpc32xx_pwm_dt_ids),
 	},
 	.probe = lpc32xx_pwm_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-mxs.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-mxs.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-mxs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-mxs.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
 #include <linux/slab.h>
@@ -130,7 +129,6 @@ static int mxs_pwm_probe(struct platform
 	struct device_node *np = pdev->dev.of_node;
 	struct mxs_pwm_chip *mxs;
 	struct resource *res;
-	struct pinctrl *pinctrl;
 	int ret;
 
 	mxs = devm_kzalloc(&pdev->dev, sizeof(*mxs), GFP_KERNEL);
@@ -142,10 +140,6 @@ static int mxs_pwm_probe(struct platform
 	if (IS_ERR(mxs->base))
 		return PTR_ERR(mxs->base);
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl))
-		return PTR_ERR(pinctrl);
-
 	mxs->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(mxs->clk))
 		return PTR_ERR(mxs->clk);
@@ -188,6 +182,7 @@ MODULE_DEVICE_TABLE(of, mxs_pwm_dt_ids);
 static struct platform_driver mxs_pwm_driver = {
 	.driver = {
 		.name = "mxs-pwm",
+		.owner = THIS_MODULE,
 		.of_match_table = of_match_ptr(mxs_pwm_dt_ids),
 	},
 	.probe = mxs_pwm_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-pca9685.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-pca9685.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-pca9685.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-pca9685.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,300 @@
+/*
+ * Driver for PCA9685 16-channel 12-bit PWM LED controller
+ *
+ * Copyright (C) 2013 Steffen Trumtrar <s.trumtrar@pengutronix.de>
+ *
+ * based on the pwm-twl-led.c driver
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define PCA9685_MODE1		0x00
+#define PCA9685_MODE2		0x01
+#define PCA9685_SUBADDR1	0x02
+#define PCA9685_SUBADDR2	0x03
+#define PCA9685_SUBADDR3	0x04
+#define PCA9685_ALLCALLADDR	0x05
+#define PCA9685_LEDX_ON_L	0x06
+#define PCA9685_LEDX_ON_H	0x07
+#define PCA9685_LEDX_OFF_L	0x08
+#define PCA9685_LEDX_OFF_H	0x09
+
+#define PCA9685_ALL_LED_ON_L	0xFA
+#define PCA9685_ALL_LED_ON_H	0xFB
+#define PCA9685_ALL_LED_OFF_L	0xFC
+#define PCA9685_ALL_LED_OFF_H	0xFD
+#define PCA9685_PRESCALE	0xFE
+
+#define PCA9685_NUMREGS		0xFF
+#define PCA9685_MAXCHAN		0x10
+
+#define LED_FULL		(1 << 4)
+#define MODE1_SLEEP		(1 << 4)
+#define MODE2_INVRT		(1 << 4)
+#define MODE2_OUTDRV		(1 << 2)
+
+#define LED_N_ON_H(N)	(PCA9685_LEDX_ON_H + (4 * (N)))
+#define LED_N_ON_L(N)	(PCA9685_LEDX_ON_L + (4 * (N)))
+#define LED_N_OFF_H(N)	(PCA9685_LEDX_OFF_H + (4 * (N)))
+#define LED_N_OFF_L(N)	(PCA9685_LEDX_OFF_L + (4 * (N)))
+
+struct pca9685 {
+	struct pwm_chip chip;
+	struct regmap *regmap;
+	int active_cnt;
+};
+
+static inline struct pca9685 *to_pca(struct pwm_chip *chip)
+{
+	return container_of(chip, struct pca9685, chip);
+}
+
+static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	struct pca9685 *pca = to_pca(chip);
+	unsigned long long duty;
+	unsigned int reg;
+
+	if (duty_ns < 1) {
+		if (pwm->hwpwm >= PCA9685_MAXCHAN)
+			reg = PCA9685_ALL_LED_OFF_H;
+		else
+			reg = LED_N_OFF_H(pwm->hwpwm);
+
+		regmap_write(pca->regmap, reg, LED_FULL);
+
+		return 0;
+	}
+
+	if (duty_ns == period_ns) {
+		if (pwm->hwpwm >= PCA9685_MAXCHAN)
+			reg = PCA9685_ALL_LED_ON_H;
+		else
+			reg = LED_N_ON_H(pwm->hwpwm);
+
+		regmap_write(pca->regmap, reg, LED_FULL);
+
+		return 0;
+	}
+
+	duty = 4096 * (unsigned long long)duty_ns;
+	duty = DIV_ROUND_UP_ULL(duty, period_ns);
+
+	if (pwm->hwpwm >= PCA9685_MAXCHAN)
+		reg = PCA9685_ALL_LED_OFF_L;
+	else
+		reg = LED_N_OFF_L(pwm->hwpwm);
+
+	regmap_write(pca->regmap, reg, (int)duty & 0xff);
+
+	if (pwm->hwpwm >= PCA9685_MAXCHAN)
+		reg = PCA9685_ALL_LED_OFF_H;
+	else
+		reg = LED_N_OFF_H(pwm->hwpwm);
+
+	regmap_write(pca->regmap, reg, ((int)duty >> 8) & 0xf);
+
+	return 0;
+}
+
+static int pca9685_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct pca9685 *pca = to_pca(chip);
+	unsigned int reg;
+
+	/*
+	 * The PWM subsystem does not support a pre-delay.
+	 * So, set the ON-timeout to 0
+	 */
+	if (pwm->hwpwm >= PCA9685_MAXCHAN)
+		reg = PCA9685_ALL_LED_ON_L;
+	else
+		reg = LED_N_ON_L(pwm->hwpwm);
+
+	regmap_write(pca->regmap, reg, 0);
+
+	if (pwm->hwpwm >= PCA9685_MAXCHAN)
+		reg = PCA9685_ALL_LED_ON_H;
+	else
+		reg = LED_N_ON_H(pwm->hwpwm);
+
+	regmap_write(pca->regmap, reg, 0);
+
+	/*
+	 * Clear the full-off bit.
+	 * It has precedence over the others and must be off.
+	 */
+	if (pwm->hwpwm >= PCA9685_MAXCHAN)
+		reg = PCA9685_ALL_LED_OFF_H;
+	else
+		reg = LED_N_OFF_H(pwm->hwpwm);
+
+	regmap_update_bits(pca->regmap, reg, LED_FULL, 0x0);
+
+	return 0;
+}
+
+static void pca9685_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct pca9685 *pca = to_pca(chip);
+	unsigned int reg;
+
+	if (pwm->hwpwm >= PCA9685_MAXCHAN)
+		reg = PCA9685_ALL_LED_OFF_H;
+	else
+		reg = LED_N_OFF_H(pwm->hwpwm);
+
+	regmap_write(pca->regmap, reg, LED_FULL);
+
+	/* Clear the LED_OFF counter. */
+	if (pwm->hwpwm >= PCA9685_MAXCHAN)
+		reg = PCA9685_ALL_LED_OFF_L;
+	else
+		reg = LED_N_OFF_L(pwm->hwpwm);
+
+	regmap_write(pca->regmap, reg, 0x0);
+}
+
+static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct pca9685 *pca = to_pca(chip);
+
+	if (pca->active_cnt++ == 0)
+		return regmap_update_bits(pca->regmap, PCA9685_MODE1,
+					  MODE1_SLEEP, 0x0);
+
+	return 0;
+}
+
+static void pca9685_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct pca9685 *pca = to_pca(chip);
+
+	if (--pca->active_cnt == 0)
+		regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP,
+				   MODE1_SLEEP);
+}
+
+static const struct pwm_ops pca9685_pwm_ops = {
+	.enable = pca9685_pwm_enable,
+	.disable = pca9685_pwm_disable,
+	.config = pca9685_pwm_config,
+	.request = pca9685_pwm_request,
+	.free = pca9685_pwm_free,
+	.owner = THIS_MODULE,
+};
+
+static struct regmap_config pca9685_regmap_i2c_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = PCA9685_NUMREGS,
+	.cache_type = REGCACHE_NONE,
+};
+
+static int pca9685_pwm_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	struct device_node *np = client->dev.of_node;
+	struct pca9685 *pca;
+	int ret;
+	int mode2;
+
+	pca = devm_kzalloc(&client->dev, sizeof(*pca), GFP_KERNEL);
+	if (!pca)
+		return -ENOMEM;
+
+	pca->regmap = devm_regmap_init_i2c(client, &pca9685_regmap_i2c_config);
+	if (IS_ERR(pca->regmap)) {
+		ret = PTR_ERR(pca->regmap);
+		dev_err(&client->dev, "Failed to initialize register map: %d\n",
+			ret);
+		return ret;
+	}
+
+	i2c_set_clientdata(client, pca);
+
+	regmap_read(pca->regmap, PCA9685_MODE2, &mode2);
+
+	if (of_property_read_bool(np, "invert"))
+		mode2 |= MODE2_INVRT;
+	else
+		mode2 &= ~MODE2_INVRT;
+
+	if (of_property_read_bool(np, "open-drain"))
+		mode2 &= ~MODE2_OUTDRV;
+	else
+		mode2 |= MODE2_OUTDRV;
+
+	regmap_write(pca->regmap, PCA9685_MODE2, mode2);
+
+	/* clear all "full off" bits */
+	regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_L, 0);
+	regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_H, 0);
+
+	pca->chip.ops = &pca9685_pwm_ops;
+	/* add an extra channel for ALL_LED */
+	pca->chip.npwm = PCA9685_MAXCHAN + 1;
+
+	pca->chip.dev = &client->dev;
+	pca->chip.base = -1;
+	pca->chip.can_sleep = true;
+
+	return pwmchip_add(&pca->chip);
+}
+
+static int pca9685_pwm_remove(struct i2c_client *client)
+{
+	struct pca9685 *pca = i2c_get_clientdata(client);
+
+	regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP,
+			   MODE1_SLEEP);
+
+	return pwmchip_remove(&pca->chip);
+}
+
+static const struct i2c_device_id pca9685_id[] = {
+	{ "pca9685", 0 },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(i2c, pca9685_id);
+
+static const struct of_device_id pca9685_dt_ids[] = {
+	{ .compatible = "nxp,pca9685-pwm", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pca9685_dt_ids);
+
+static struct i2c_driver pca9685_i2c_driver = {
+	.driver = {
+		.name = "pca9685-pwm",
+		.owner = THIS_MODULE,
+		.of_match_table = pca9685_dt_ids,
+	},
+	.probe = pca9685_pwm_probe,
+	.remove = pca9685_pwm_remove,
+	.id_table = pca9685_id,
+};
+
+module_i2c_driver(pca9685_i2c_driver);
+
+MODULE_AUTHOR("Steffen Trumtrar <s.trumtrar@pengutronix.de>");
+MODULE_DESCRIPTION("PWM driver for PCA9685");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-puv3.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-puv3.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-puv3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-puv3.c	2013-08-25 20:43:22.000000000 -0400
@@ -146,6 +146,7 @@ static int pwm_remove(struct platform_de
 static struct platform_driver puv3_pwm_driver = {
 	.driver = {
 		.name = "PKUnity-v3-PWM",
+		.owner = THIS_MODULE,
 	},
 	.probe = pwm_probe,
 	.remove = pwm_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-renesas-tpu.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-renesas-tpu.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-renesas-tpu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-renesas-tpu.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,474 @@
+/*
+ * R-Mobile TPU PWM driver
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_data/pwm-renesas-tpu.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#define TPU_TSTR		0x00	/* Timer start register (shared) */
+
+#define TPU_TCRn		0x00	/* Timer control register */
+#define TPU_TCR_CCLR_NONE	(0 << 5)
+#define TPU_TCR_CCLR_TGRA	(1 << 5)
+#define TPU_TCR_CCLR_TGRB	(2 << 5)
+#define TPU_TCR_CCLR_TGRC	(5 << 5)
+#define TPU_TCR_CCLR_TGRD	(6 << 5)
+#define TPU_TCR_CKEG_RISING	(0 << 3)
+#define TPU_TCR_CKEG_FALLING	(1 << 3)
+#define TPU_TCR_CKEG_BOTH	(2 << 3)
+#define TPU_TMDRn		0x04	/* Timer mode register */
+#define TPU_TMDR_BFWT		(1 << 6)
+#define TPU_TMDR_BFB		(1 << 5)
+#define TPU_TMDR_BFA		(1 << 4)
+#define TPU_TMDR_MD_NORMAL	(0 << 0)
+#define TPU_TMDR_MD_PWM		(2 << 0)
+#define TPU_TIORn		0x08	/* Timer I/O control register */
+#define TPU_TIOR_IOA_0		(0 << 0)
+#define TPU_TIOR_IOA_0_CLR	(1 << 0)
+#define TPU_TIOR_IOA_0_SET	(2 << 0)
+#define TPU_TIOR_IOA_0_TOGGLE	(3 << 0)
+#define TPU_TIOR_IOA_1		(4 << 0)
+#define TPU_TIOR_IOA_1_CLR	(5 << 0)
+#define TPU_TIOR_IOA_1_SET	(6 << 0)
+#define TPU_TIOR_IOA_1_TOGGLE	(7 << 0)
+#define TPU_TIERn		0x0c	/* Timer interrupt enable register */
+#define TPU_TSRn		0x10	/* Timer status register */
+#define TPU_TCNTn		0x14	/* Timer counter */
+#define TPU_TGRAn		0x18	/* Timer general register A */
+#define TPU_TGRBn		0x1c	/* Timer general register B */
+#define TPU_TGRCn		0x20	/* Timer general register C */
+#define TPU_TGRDn		0x24	/* Timer general register D */
+
+#define TPU_CHANNEL_OFFSET	0x10
+#define TPU_CHANNEL_SIZE	0x40
+
+enum tpu_pin_state {
+	TPU_PIN_INACTIVE,		/* Pin is driven inactive */
+	TPU_PIN_PWM,			/* Pin is driven by PWM */
+	TPU_PIN_ACTIVE,			/* Pin is driven active */
+};
+
+struct tpu_device;
+
+struct tpu_pwm_device {
+	bool timer_on;			/* Whether the timer is running */
+
+	struct tpu_device *tpu;
+	unsigned int channel;		/* Channel number in the TPU */
+
+	enum pwm_polarity polarity;
+	unsigned int prescaler;
+	u16 period;
+	u16 duty;
+};
+
+struct tpu_device {
+	struct platform_device *pdev;
+	struct tpu_pwm_platform_data *pdata;
+	struct pwm_chip chip;
+	spinlock_t lock;
+
+	void __iomem *base;
+	struct clk *clk;
+};
+
+#define to_tpu_device(c)	container_of(c, struct tpu_device, chip)
+
+static void tpu_pwm_write(struct tpu_pwm_device *pwm, int reg_nr, u16 value)
+{
+	void __iomem *base = pwm->tpu->base + TPU_CHANNEL_OFFSET
+			   + pwm->channel * TPU_CHANNEL_SIZE;
+
+	iowrite16(value, base + reg_nr);
+}
+
+static void tpu_pwm_set_pin(struct tpu_pwm_device *pwm,
+			    enum tpu_pin_state state)
+{
+	static const char * const states[] = { "inactive", "PWM", "active" };
+
+	dev_dbg(&pwm->tpu->pdev->dev, "%u: configuring pin as %s\n",
+		pwm->channel, states[state]);
+
+	switch (state) {
+	case TPU_PIN_INACTIVE:
+		tpu_pwm_write(pwm, TPU_TIORn,
+			      pwm->polarity == PWM_POLARITY_INVERSED ?
+			      TPU_TIOR_IOA_1 : TPU_TIOR_IOA_0);
+		break;
+	case TPU_PIN_PWM:
+		tpu_pwm_write(pwm, TPU_TIORn,
+			      pwm->polarity == PWM_POLARITY_INVERSED ?
+			      TPU_TIOR_IOA_0_SET : TPU_TIOR_IOA_1_CLR);
+		break;
+	case TPU_PIN_ACTIVE:
+		tpu_pwm_write(pwm, TPU_TIORn,
+			      pwm->polarity == PWM_POLARITY_INVERSED ?
+			      TPU_TIOR_IOA_0 : TPU_TIOR_IOA_1);
+		break;
+	}
+}
+
+static void tpu_pwm_start_stop(struct tpu_pwm_device *pwm, int start)
+{
+	unsigned long flags;
+	u16 value;
+
+	spin_lock_irqsave(&pwm->tpu->lock, flags);
+	value = ioread16(pwm->tpu->base + TPU_TSTR);
+
+	if (start)
+		value |= 1 << pwm->channel;
+	else
+		value &= ~(1 << pwm->channel);
+
+	iowrite16(value, pwm->tpu->base + TPU_TSTR);
+	spin_unlock_irqrestore(&pwm->tpu->lock, flags);
+}
+
+static int tpu_pwm_timer_start(struct tpu_pwm_device *pwm)
+{
+	int ret;
+
+	if (!pwm->timer_on) {
+		/* Wake up device and enable clock. */
+		pm_runtime_get_sync(&pwm->tpu->pdev->dev);
+		ret = clk_prepare_enable(pwm->tpu->clk);
+		if (ret) {
+			dev_err(&pwm->tpu->pdev->dev, "cannot enable clock\n");
+			return ret;
+		}
+		pwm->timer_on = true;
+	}
+
+	/*
+	 * Make sure the channel is stopped, as we need to reconfigure it
+	 * completely. First drive the pin to the inactive state to avoid
+	 * glitches.
+	 */
+	tpu_pwm_set_pin(pwm, TPU_PIN_INACTIVE);
+	tpu_pwm_start_stop(pwm, false);
+
+	/*
+	 * - Clear TCNT on TGRB match
+	 * - Count on rising edge
+	 * - Set prescaler
+	 * - Output 0 until TGRA, output 1 until TGRB (active low polarity)
+	 * - Output 1 until TGRA, output 0 until TGRB (active high polarity
+	 * - PWM mode
+	 */
+	tpu_pwm_write(pwm, TPU_TCRn, TPU_TCR_CCLR_TGRB | TPU_TCR_CKEG_RISING |
+		      pwm->prescaler);
+	tpu_pwm_write(pwm, TPU_TMDRn, TPU_TMDR_MD_PWM);
+	tpu_pwm_set_pin(pwm, TPU_PIN_PWM);
+	tpu_pwm_write(pwm, TPU_TGRAn, pwm->duty);
+	tpu_pwm_write(pwm, TPU_TGRBn, pwm->period);
+
+	dev_dbg(&pwm->tpu->pdev->dev, "%u: TGRA 0x%04x TGRB 0x%04x\n",
+		pwm->channel, pwm->duty, pwm->period);
+
+	/* Start the channel. */
+	tpu_pwm_start_stop(pwm, true);
+
+	return 0;
+}
+
+static void tpu_pwm_timer_stop(struct tpu_pwm_device *pwm)
+{
+	if (!pwm->timer_on)
+		return;
+
+	/* Disable channel. */
+	tpu_pwm_start_stop(pwm, false);
+
+	/* Stop clock and mark device as idle. */
+	clk_disable_unprepare(pwm->tpu->clk);
+	pm_runtime_put(&pwm->tpu->pdev->dev);
+
+	pwm->timer_on = false;
+}
+
+/* -----------------------------------------------------------------------------
+ * PWM API
+ */
+
+static int tpu_pwm_request(struct pwm_chip *chip, struct pwm_device *_pwm)
+{
+	struct tpu_device *tpu = to_tpu_device(chip);
+	struct tpu_pwm_device *pwm;
+
+	if (_pwm->hwpwm >= TPU_CHANNEL_MAX)
+		return -EINVAL;
+
+	pwm = kzalloc(sizeof(*pwm), GFP_KERNEL);
+	if (pwm == NULL)
+		return -ENOMEM;
+
+	pwm->tpu = tpu;
+	pwm->channel = _pwm->hwpwm;
+	pwm->polarity = tpu->pdata ? tpu->pdata->channels[pwm->channel].polarity
+		      : PWM_POLARITY_NORMAL;
+	pwm->prescaler = 0;
+	pwm->period = 0;
+	pwm->duty = 0;
+
+	pwm->timer_on = false;
+
+	pwm_set_chip_data(_pwm, pwm);
+
+	return 0;
+}
+
+static void tpu_pwm_free(struct pwm_chip *chip, struct pwm_device *_pwm)
+{
+	struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
+
+	tpu_pwm_timer_stop(pwm);
+	kfree(pwm);
+}
+
+static int tpu_pwm_config(struct pwm_chip *chip, struct pwm_device *_pwm,
+			  int duty_ns, int period_ns)
+{
+	static const unsigned int prescalers[] = { 1, 4, 16, 64 };
+	struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
+	struct tpu_device *tpu = to_tpu_device(chip);
+	unsigned int prescaler;
+	bool duty_only = false;
+	u32 clk_rate;
+	u32 period;
+	u32 duty;
+	int ret;
+
+	/*
+	 * Pick a prescaler to avoid overflowing the counter.
+	 * TODO: Pick the highest acceptable prescaler.
+	 */
+	clk_rate = clk_get_rate(tpu->clk);
+
+	for (prescaler = 0; prescaler < ARRAY_SIZE(prescalers); ++prescaler) {
+		period = clk_rate / prescalers[prescaler]
+		       / (NSEC_PER_SEC / period_ns);
+		if (period <= 0xffff)
+			break;
+	}
+
+	if (prescaler == ARRAY_SIZE(prescalers) || period == 0) {
+		dev_err(&tpu->pdev->dev, "clock rate mismatch\n");
+		return -ENOTSUPP;
+	}
+
+	if (duty_ns) {
+		duty = clk_rate / prescalers[prescaler]
+		     / (NSEC_PER_SEC / duty_ns);
+		if (duty > period)
+			return -EINVAL;
+	} else {
+		duty = 0;
+	}
+
+	dev_dbg(&tpu->pdev->dev,
+		"rate %u, prescaler %u, period %u, duty %u\n",
+		clk_rate, prescalers[prescaler], period, duty);
+
+	if (pwm->prescaler == prescaler && pwm->period == period)
+		duty_only = true;
+
+	pwm->prescaler = prescaler;
+	pwm->period = period;
+	pwm->duty = duty;
+
+	/* If the channel is disabled we're done. */
+	if (!test_bit(PWMF_ENABLED, &_pwm->flags))
+		return 0;
+
+	if (duty_only && pwm->timer_on) {
+		/*
+		 * If only the duty cycle changed and the timer is already
+		 * running, there's no need to reconfigure it completely, Just
+		 * modify the duty cycle.
+		 */
+		tpu_pwm_write(pwm, TPU_TGRAn, pwm->duty);
+		dev_dbg(&tpu->pdev->dev, "%u: TGRA 0x%04x\n", pwm->channel,
+			pwm->duty);
+	} else {
+		/* Otherwise perform a full reconfiguration. */
+		ret = tpu_pwm_timer_start(pwm);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (duty == 0 || duty == period) {
+		/*
+		 * To avoid running the timer when not strictly required, handle
+		 * 0% and 100% duty cycles as fixed levels and stop the timer.
+		 */
+		tpu_pwm_set_pin(pwm, duty ? TPU_PIN_ACTIVE : TPU_PIN_INACTIVE);
+		tpu_pwm_timer_stop(pwm);
+	}
+
+	return 0;
+}
+
+static int tpu_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *_pwm,
+				enum pwm_polarity polarity)
+{
+	struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
+
+	pwm->polarity = polarity;
+
+	return 0;
+}
+
+static int tpu_pwm_enable(struct pwm_chip *chip, struct pwm_device *_pwm)
+{
+	struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
+	int ret;
+
+	ret = tpu_pwm_timer_start(pwm);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * To avoid running the timer when not strictly required, handle 0% and
+	 * 100% duty cycles as fixed levels and stop the timer.
+	 */
+	if (pwm->duty == 0 || pwm->duty == pwm->period) {
+		tpu_pwm_set_pin(pwm, pwm->duty ?
+				TPU_PIN_ACTIVE : TPU_PIN_INACTIVE);
+		tpu_pwm_timer_stop(pwm);
+	}
+
+	return 0;
+}
+
+static void tpu_pwm_disable(struct pwm_chip *chip, struct pwm_device *_pwm)
+{
+	struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
+
+	/* The timer must be running to modify the pin output configuration. */
+	tpu_pwm_timer_start(pwm);
+	tpu_pwm_set_pin(pwm, TPU_PIN_INACTIVE);
+	tpu_pwm_timer_stop(pwm);
+}
+
+static const struct pwm_ops tpu_pwm_ops = {
+	.request = tpu_pwm_request,
+	.free = tpu_pwm_free,
+	.config = tpu_pwm_config,
+	.set_polarity = tpu_pwm_set_polarity,
+	.enable = tpu_pwm_enable,
+	.disable = tpu_pwm_disable,
+	.owner = THIS_MODULE,
+};
+
+/* -----------------------------------------------------------------------------
+ * Probe and remove
+ */
+
+static int tpu_probe(struct platform_device *pdev)
+{
+	struct tpu_device *tpu;
+	struct resource *res;
+	int ret;
+
+	tpu = devm_kzalloc(&pdev->dev, sizeof(*tpu), GFP_KERNEL);
+	if (tpu == NULL) {
+		dev_err(&pdev->dev, "failed to allocate driver data\n");
+		return -ENOMEM;
+	}
+
+	tpu->pdata = pdev->dev.platform_data;
+
+	/* Map memory, get clock and pin control. */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get I/O memory\n");
+		return -ENXIO;
+	}
+
+	tpu->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tpu->base))
+		return PTR_ERR(tpu->base);
+
+	tpu->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(tpu->clk)) {
+		dev_err(&pdev->dev, "cannot get clock\n");
+		return PTR_ERR(tpu->clk);
+	}
+
+	/* Initialize and register the device. */
+	platform_set_drvdata(pdev, tpu);
+
+	spin_lock_init(&tpu->lock);
+	tpu->pdev = pdev;
+
+	tpu->chip.dev = &pdev->dev;
+	tpu->chip.ops = &tpu_pwm_ops;
+	tpu->chip.base = -1;
+	tpu->chip.npwm = TPU_CHANNEL_MAX;
+
+	ret = pwmchip_add(&tpu->chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to register PWM chip\n");
+		return ret;
+	}
+
+	dev_info(&pdev->dev, "TPU PWM %d registered\n", tpu->pdev->id);
+
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+}
+
+static int tpu_remove(struct platform_device *pdev)
+{
+	struct tpu_device *tpu = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&tpu->chip);
+	if (ret)
+		return ret;
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static struct platform_driver tpu_driver = {
+	.probe		= tpu_probe,
+	.remove		= tpu_remove,
+	.driver		= {
+		.name	= "renesas-tpu-pwm",
+		.owner	= THIS_MODULE,
+	}
+};
+
+module_platform_driver(tpu_driver);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Renesas TPU PWM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:renesas-tpu-pwm");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-spear.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-spear.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-spear.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-spear.c	2013-08-25 20:43:22.000000000 -0400
@@ -259,6 +259,7 @@ MODULE_DEVICE_TABLE(of, spear_pwm_of_mat
 static struct platform_driver spear_pwm_driver = {
 	.driver = {
 		.name = "spear-pwm",
+		.owner = THIS_MODULE,
 		.of_match_table = spear_pwm_of_match,
 	},
 	.probe = spear_pwm_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-tegra.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-tegra.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-tegra.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-tegra.c	2013-08-25 20:43:22.000000000 -0400
@@ -239,6 +239,7 @@ MODULE_DEVICE_TABLE(of, tegra_pwm_of_mat
 static struct platform_driver tegra_pwm_driver = {
 	.driver = {
 		.name = "tegra-pwm",
+		.owner = THIS_MODULE,
 		.of_match_table = tegra_pwm_of_match,
 	},
 	.probe = tegra_pwm_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/pwm-tiehrpwm.c linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-tiehrpwm.c
--- linux-libre-3.10-gnu/drivers/pwm/pwm-tiehrpwm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/pwm-tiehrpwm.c	2013-08-25 20:43:22.000000000 -0400
@@ -359,7 +359,7 @@ static int ehrpwm_pwm_enable(struct pwm_
 	configure_polarity(pc, pwm->hwpwm);
 
 	/* Enable TBCLK before enabling PWM device */
-	ret = clk_prepare_enable(pc->tbclk);
+	ret = clk_enable(pc->tbclk);
 	if (ret) {
 		pr_err("Failed to enable TBCLK for %s\n",
 				dev_name(pc->chip.dev));
@@ -395,7 +395,7 @@ static void ehrpwm_pwm_disable(struct pw
 	ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
 
 	/* Disabling TBCLK on PWM disable */
-	clk_disable_unprepare(pc->tbclk);
+	clk_disable(pc->tbclk);
 
 	/* Stop Time base counter */
 	ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT);
@@ -482,6 +482,12 @@ static int ehrpwm_pwm_probe(struct platf
 		return PTR_ERR(pc->tbclk);
 	}
 
+	ret = clk_prepare(pc->tbclk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "clk_prepare() failed: %d\n", ret);
+		return ret;
+	}
+
 	ret = pwmchip_add(&pc->chip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
@@ -508,6 +514,7 @@ pwmss_clk_failure:
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	pwmchip_remove(&pc->chip);
+	clk_unprepare(pc->tbclk);
 	return ret;
 }
 
@@ -515,6 +522,8 @@ static int ehrpwm_pwm_remove(struct plat
 {
 	struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev);
 
+	clk_unprepare(pc->tbclk);
+
 	pm_runtime_get_sync(&pdev->dev);
 	/*
 	 * Due to hardware misbehaviour, acknowledge of the stop_req
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/pwm/sysfs.c linux-libre-3.11-rc7-gnu/drivers/pwm/sysfs.c
--- linux-libre-3.10-gnu/drivers/pwm/sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/pwm/sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,352 @@
+/*
+ * A simple sysfs interface for the generic PWM framework
+ *
+ * Copyright (C) 2013 H Hartley Sweeten <hsweeten@visionengravers.com>
+ *
+ * Based on previous work by Lars Poeschel <poeschel@lemonage.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/kdev_t.h>
+#include <linux/pwm.h>
+
+struct pwm_export {
+	struct device child;
+	struct pwm_device *pwm;
+};
+
+static struct pwm_export *child_to_pwm_export(struct device *child)
+{
+	return container_of(child, struct pwm_export, child);
+}
+
+static struct pwm_device *child_to_pwm_device(struct device *child)
+{
+	struct pwm_export *export = child_to_pwm_export(child);
+
+	return export->pwm;
+}
+
+static ssize_t pwm_period_show(struct device *child,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	const struct pwm_device *pwm = child_to_pwm_device(child);
+
+	return sprintf(buf, "%u\n", pwm->period);
+}
+
+static ssize_t pwm_period_store(struct device *child,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct pwm_device *pwm = child_to_pwm_device(child);
+	unsigned int val;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	ret = pwm_config(pwm, pwm->duty_cycle, val);
+
+	return ret ? : size;
+}
+
+static ssize_t pwm_duty_cycle_show(struct device *child,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	const struct pwm_device *pwm = child_to_pwm_device(child);
+
+	return sprintf(buf, "%u\n", pwm->duty_cycle);
+}
+
+static ssize_t pwm_duty_cycle_store(struct device *child,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	struct pwm_device *pwm = child_to_pwm_device(child);
+	unsigned int val;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	ret = pwm_config(pwm, val, pwm->period);
+
+	return ret ? : size;
+}
+
+static ssize_t pwm_enable_show(struct device *child,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	const struct pwm_device *pwm = child_to_pwm_device(child);
+	int enabled = test_bit(PWMF_ENABLED, &pwm->flags);
+
+	return sprintf(buf, "%d\n", enabled);
+}
+
+static ssize_t pwm_enable_store(struct device *child,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	struct pwm_device *pwm = child_to_pwm_device(child);
+	int val, ret;
+
+	ret = kstrtoint(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	switch (val) {
+	case 0:
+		pwm_disable(pwm);
+		break;
+	case 1:
+		ret = pwm_enable(pwm);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret ? : size;
+}
+
+static ssize_t pwm_polarity_show(struct device *child,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	const struct pwm_device *pwm = child_to_pwm_device(child);
+
+	return sprintf(buf, "%s\n", pwm->polarity ? "inversed" : "normal");
+}
+
+static ssize_t pwm_polarity_store(struct device *child,
+				  struct device_attribute *attr,
+				  const char *buf, size_t size)
+{
+	struct pwm_device *pwm = child_to_pwm_device(child);
+	enum pwm_polarity polarity;
+	int ret;
+
+	if (sysfs_streq(buf, "normal"))
+		polarity = PWM_POLARITY_NORMAL;
+	else if (sysfs_streq(buf, "inversed"))
+		polarity = PWM_POLARITY_INVERSED;
+	else
+		return -EINVAL;
+
+	ret = pwm_set_polarity(pwm, polarity);
+
+	return ret ? : size;
+}
+
+static DEVICE_ATTR(period, 0644, pwm_period_show, pwm_period_store);
+static DEVICE_ATTR(duty_cycle, 0644, pwm_duty_cycle_show, pwm_duty_cycle_store);
+static DEVICE_ATTR(enable, 0644, pwm_enable_show, pwm_enable_store);
+static DEVICE_ATTR(polarity, 0644, pwm_polarity_show, pwm_polarity_store);
+
+static struct attribute *pwm_attrs[] = {
+	&dev_attr_period.attr,
+	&dev_attr_duty_cycle.attr,
+	&dev_attr_enable.attr,
+	&dev_attr_polarity.attr,
+	NULL
+};
+
+static const struct attribute_group pwm_attr_group = {
+	.attrs		= pwm_attrs,
+};
+
+static const struct attribute_group *pwm_attr_groups[] = {
+	&pwm_attr_group,
+	NULL,
+};
+
+static void pwm_export_release(struct device *child)
+{
+	struct pwm_export *export = child_to_pwm_export(child);
+
+	kfree(export);
+}
+
+static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
+{
+	struct pwm_export *export;
+	int ret;
+
+	if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
+		return -EBUSY;
+
+	export = kzalloc(sizeof(*export), GFP_KERNEL);
+	if (!export) {
+		clear_bit(PWMF_EXPORTED, &pwm->flags);
+		return -ENOMEM;
+	}
+
+	export->pwm = pwm;
+
+	export->child.release = pwm_export_release;
+	export->child.parent = parent;
+	export->child.devt = MKDEV(0, 0);
+	export->child.groups = pwm_attr_groups;
+	dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
+
+	ret = device_register(&export->child);
+	if (ret) {
+		clear_bit(PWMF_EXPORTED, &pwm->flags);
+		kfree(export);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int pwm_unexport_match(struct device *child, void *data)
+{
+	return child_to_pwm_device(child) == data;
+}
+
+static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
+{
+	struct device *child;
+
+	if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
+		return -ENODEV;
+
+	child = device_find_child(parent, pwm, pwm_unexport_match);
+	if (!child)
+		return -ENODEV;
+
+	/* for device_find_child() */
+	put_device(child);
+	device_unregister(child);
+	pwm_put(pwm);
+
+	return 0;
+}
+
+static ssize_t pwm_export_store(struct device *parent,
+				struct device_attribute *attr,
+				const char *buf, size_t len)
+{
+	struct pwm_chip *chip = dev_get_drvdata(parent);
+	struct pwm_device *pwm;
+	unsigned int hwpwm;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &hwpwm);
+	if (ret < 0)
+		return ret;
+
+	if (hwpwm >= chip->npwm)
+		return -ENODEV;
+
+	pwm = pwm_request_from_chip(chip, hwpwm, "sysfs");
+	if (IS_ERR(pwm))
+		return PTR_ERR(pwm);
+
+	ret = pwm_export_child(parent, pwm);
+	if (ret < 0)
+		pwm_put(pwm);
+
+	return ret ? : len;
+}
+
+static ssize_t pwm_unexport_store(struct device *parent,
+				  struct device_attribute *attr,
+				  const char *buf, size_t len)
+{
+	struct pwm_chip *chip = dev_get_drvdata(parent);
+	unsigned int hwpwm;
+	int ret;
+
+	ret = kstrtouint(buf, 0, &hwpwm);
+	if (ret < 0)
+		return ret;
+
+	if (hwpwm >= chip->npwm)
+		return -ENODEV;
+
+	ret = pwm_unexport_child(parent, &chip->pwms[hwpwm]);
+
+	return ret ? : len;
+}
+
+static ssize_t pwm_npwm_show(struct device *parent,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	const struct pwm_chip *chip = dev_get_drvdata(parent);
+
+	return sprintf(buf, "%u\n", chip->npwm);
+}
+
+static struct device_attribute pwm_chip_attrs[] = {
+	__ATTR(export, 0200, NULL, pwm_export_store),
+	__ATTR(unexport, 0200, NULL, pwm_unexport_store),
+	__ATTR(npwm, 0444, pwm_npwm_show, NULL),
+	__ATTR_NULL,
+};
+
+static struct class pwm_class = {
+	.name		= "pwm",
+	.owner		= THIS_MODULE,
+	.dev_attrs	= pwm_chip_attrs,
+};
+
+static int pwmchip_sysfs_match(struct device *parent, const void *data)
+{
+	return dev_get_drvdata(parent) == data;
+}
+
+void pwmchip_sysfs_export(struct pwm_chip *chip)
+{
+	struct device *parent;
+
+	/*
+	 * If device_create() fails the pwm_chip is still usable by
+	 * the kernel its just not exported.
+	 */
+	parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
+			       "pwmchip%d", chip->base);
+	if (IS_ERR(parent)) {
+		dev_warn(chip->dev,
+			 "device_create failed for pwm_chip sysfs export\n");
+	}
+}
+
+void pwmchip_sysfs_unexport(struct pwm_chip *chip)
+{
+	struct device *parent;
+
+	parent = class_find_device(&pwm_class, NULL, chip,
+				   pwmchip_sysfs_match);
+	if (parent) {
+		/* for class_find_device() */
+		put_device(parent);
+		device_unregister(parent);
+	}
+}
+
+static int __init pwm_sysfs_init(void)
+{
+	return class_register(&pwm_class);
+}
+subsys_initcall(pwm_sysfs_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/devices/Kconfig linux-libre-3.11-rc7-gnu/drivers/rapidio/devices/Kconfig
--- linux-libre-3.10-gnu/drivers/rapidio/devices/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/devices/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
 #
 
 config RAPIDIO_TSI721
-	bool "IDT Tsi721 PCI Express SRIO Controller support"
+	tristate "IDT Tsi721 PCI Express SRIO Controller support"
 	depends on RAPIDIO && PCIEPORTBUS
 	default "n"
 	---help---
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/devices/Makefile linux-libre-3.11-rc7-gnu/drivers/rapidio/devices/Makefile
--- linux-libre-3.10-gnu/drivers/rapidio/devices/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/devices/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,6 @@
 # Makefile for RapidIO devices
 #
 
-obj-$(CONFIG_RAPIDIO_TSI721)	+= tsi721.o
-ifeq ($(CONFIG_RAPIDIO_DMA_ENGINE),y)
-obj-$(CONFIG_RAPIDIO_TSI721)	+= tsi721_dma.o
-endif
+obj-$(CONFIG_RAPIDIO_TSI721)	+= tsi721_mport.o
+tsi721_mport-y			:= tsi721.o
+tsi721_mport-$(CONFIG_RAPIDIO_DMA_ENGINE) += tsi721_dma.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/devices/tsi721.c linux-libre-3.11-rc7-gnu/drivers/rapidio/devices/tsi721.c
--- linux-libre-3.10-gnu/drivers/rapidio/devices/tsi721.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/devices/tsi721.c	2013-08-25 20:43:22.000000000 -0400
@@ -2515,9 +2515,8 @@ static int __init tsi721_init(void)
 	return pci_register_driver(&tsi721_driver);
 }
 
-static void __exit tsi721_exit(void)
-{
-	pci_unregister_driver(&tsi721_driver);
-}
-
 device_initcall(tsi721_init);
+
+MODULE_DESCRIPTION("IDT Tsi721 PCIExpress-to-SRIO bridge driver");
+MODULE_AUTHOR("Integrated Device Technology, Inc.");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/Kconfig linux-libre-3.11-rc7-gnu/drivers/rapidio/Kconfig
--- linux-libre-3.10-gnu/drivers/rapidio/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -67,4 +67,9 @@ config RAPIDIO_ENUM_BASIC
 
 endchoice
 
+menu "RapidIO Switch drivers"
+	depends on RAPIDIO
+
 source "drivers/rapidio/switches/Kconfig"
+
+endmenu
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/Makefile linux-libre-3.11-rc7-gnu/drivers/rapidio/Makefile
--- linux-libre-3.10-gnu/drivers/rapidio/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,9 @@
 #
 # Makefile for RapidIO interconnect services
 #
-obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o
+obj-$(CONFIG_RAPIDIO) += rapidio.o
+rapidio-y := rio.o rio-access.o rio-driver.o rio-sysfs.o
+
 obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o
 
 obj-$(CONFIG_RAPIDIO)		+= switches/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/rio.c linux-libre-3.11-rc7-gnu/drivers/rapidio/rio.c
--- linux-libre-3.10-gnu/drivers/rapidio/rio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/rio.c	2013-08-25 20:43:22.000000000 -0400
@@ -5,9 +5,8 @@
  * Copyright 2005 MontaVista Software, Inc.
  * Matt Porter <mporter@kernel.crashing.org>
  *
- * Copyright 2009 Integrated Device Technology, Inc.
+ * Copyright 2009 - 2013 Integrated Device Technology, Inc.
  * Alex Bounine <alexandre.bounine@idt.com>
- * - Added Port-Write/Error Management initialization and handling
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -31,10 +30,22 @@
 
 #include "rio.h"
 
+MODULE_DESCRIPTION("RapidIO Subsystem Core");
+MODULE_AUTHOR("Matt Porter <mporter@kernel.crashing.org>");
+MODULE_AUTHOR("Alexandre Bounine <alexandre.bounine@idt.com>");
+MODULE_LICENSE("GPL");
+
+static int hdid[RIO_MAX_MPORTS];
+static int ids_num;
+module_param_array(hdid, int, &ids_num, 0);
+MODULE_PARM_DESC(hdid,
+	"Destination ID assignment to local RapidIO controllers");
+
 static LIST_HEAD(rio_devices);
 static DEFINE_SPINLOCK(rio_global_list_lock);
 
 static LIST_HEAD(rio_mports);
+static LIST_HEAD(rio_scans);
 static DEFINE_MUTEX(rio_mport_list_lock);
 static unsigned char next_portid;
 static DEFINE_SPINLOCK(rio_mmap_lock);
@@ -580,44 +591,6 @@ int rio_set_port_lockout(struct rio_dev
 EXPORT_SYMBOL_GPL(rio_set_port_lockout);
 
 /**
- * rio_switch_init - Sets switch operations for a particular vendor switch
- * @rdev: RIO device
- * @do_enum: Enumeration/Discovery mode flag
- *
- * Searches the RIO switch ops table for known switch types. If the vid
- * and did match a switch table entry, then call switch initialization
- * routine to setup switch-specific routines.
- */
-void rio_switch_init(struct rio_dev *rdev, int do_enum)
-{
-	struct rio_switch_ops *cur = __start_rio_switch_ops;
-	struct rio_switch_ops *end = __end_rio_switch_ops;
-
-	while (cur < end) {
-		if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
-			pr_debug("RIO: calling init routine for %s\n",
-				 rio_name(rdev));
-			cur->init_hook(rdev, do_enum);
-			break;
-		}
-		cur++;
-	}
-
-	if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
-		pr_debug("RIO: adding STD routing ops for %s\n",
-			rio_name(rdev));
-		rdev->rswitch->add_entry = rio_std_route_add_entry;
-		rdev->rswitch->get_entry = rio_std_route_get_entry;
-		rdev->rswitch->clr_table = rio_std_route_clr_table;
-	}
-
-	if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
-		printk(KERN_ERR "RIO: missing routing ops for %s\n",
-		       rio_name(rdev));
-}
-EXPORT_SYMBOL_GPL(rio_switch_init);
-
-/**
  * rio_enable_rx_tx_port - enable input receiver and output transmitter of
  * given port
  * @port: Master port associated with the RIO network
@@ -970,8 +943,8 @@ int rio_inb_pwrite_handler(union rio_pw_
 	/*
 	 * Process the port-write notification from switch
 	 */
-	if (rdev->rswitch->em_handle)
-		rdev->rswitch->em_handle(rdev, portnum);
+	if (rdev->rswitch->ops && rdev->rswitch->ops->em_handle)
+		rdev->rswitch->ops->em_handle(rdev, portnum);
 
 	rio_read_config_32(rdev,
 			rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum),
@@ -1207,8 +1180,9 @@ struct rio_dev *rio_get_device(u16 vid,
  * @route_destid: destID entry in the RT
  * @route_port: destination port for specified destID
  */
-int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
-		       u16 table, u16 route_destid, u8 route_port)
+static int
+rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+			u16 table, u16 route_destid, u8 route_port)
 {
 	if (table == RIO_GLOBAL_TABLE) {
 		rio_mport_write_config_32(mport, destid, hopcount,
@@ -1234,8 +1208,9 @@ int rio_std_route_add_entry(struct rio_m
  * @route_destid: destID entry in the RT
  * @route_port: returned destination port for specified destID
  */
-int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
-		       u16 table, u16 route_destid, u8 *route_port)
+static int
+rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+			u16 table, u16 route_destid, u8 *route_port)
 {
 	u32 result;
 
@@ -1259,8 +1234,9 @@ int rio_std_route_get_entry(struct rio_m
  * @hopcount: Number of switch hops to the device
  * @table: routing table ID (global or port-specific)
  */
-int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
-		       u16 table)
+static int
+rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
+			u16 table)
 {
 	u32 max_destid = 0xff;
 	u32 i, pef, id_inc = 1, ext_cfg = 0;
@@ -1301,6 +1277,234 @@ int rio_std_route_clr_table(struct rio_m
 	return 0;
 }
 
+/**
+ * rio_lock_device - Acquires host device lock for specified device
+ * @port: Master port to send transaction
+ * @destid: Destination ID for device/switch
+ * @hopcount: Hopcount to reach switch
+ * @wait_ms: Max wait time in msec (0 = no timeout)
+ *
+ * Attepts to acquire host device lock for specified device
+ * Returns 0 if device lock acquired or EINVAL if timeout expires.
+ */
+int rio_lock_device(struct rio_mport *port, u16 destid,
+		    u8 hopcount, int wait_ms)
+{
+	u32 result;
+	int tcnt = 0;
+
+	/* Attempt to acquire device lock */
+	rio_mport_write_config_32(port, destid, hopcount,
+				  RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
+	rio_mport_read_config_32(port, destid, hopcount,
+				 RIO_HOST_DID_LOCK_CSR, &result);
+
+	while (result != port->host_deviceid) {
+		if (wait_ms != 0 && tcnt == wait_ms) {
+			pr_debug("RIO: timeout when locking device %x:%x\n",
+				destid, hopcount);
+			return -EINVAL;
+		}
+
+		/* Delay a bit */
+		mdelay(1);
+		tcnt++;
+		/* Try to acquire device lock again */
+		rio_mport_write_config_32(port, destid,
+			hopcount,
+			RIO_HOST_DID_LOCK_CSR,
+			port->host_deviceid);
+		rio_mport_read_config_32(port, destid,
+			hopcount,
+			RIO_HOST_DID_LOCK_CSR, &result);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rio_lock_device);
+
+/**
+ * rio_unlock_device - Releases host device lock for specified device
+ * @port: Master port to send transaction
+ * @destid: Destination ID for device/switch
+ * @hopcount: Hopcount to reach switch
+ *
+ * Returns 0 if device lock released or EINVAL if fails.
+ */
+int rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount)
+{
+	u32 result;
+
+	/* Release device lock */
+	rio_mport_write_config_32(port, destid,
+				  hopcount,
+				  RIO_HOST_DID_LOCK_CSR,
+				  port->host_deviceid);
+	rio_mport_read_config_32(port, destid, hopcount,
+		RIO_HOST_DID_LOCK_CSR, &result);
+	if ((result & 0xffff) != 0xffff) {
+		pr_debug("RIO: badness when releasing device lock %x:%x\n",
+			 destid, hopcount);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rio_unlock_device);
+
+/**
+ * rio_route_add_entry- Add a route entry to a switch routing table
+ * @rdev: RIO device
+ * @table: Routing table ID
+ * @route_destid: Destination ID to be routed
+ * @route_port: Port number to be routed
+ * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock)
+ *
+ * If available calls the switch specific add_entry() method to add a route
+ * entry into a switch routing table. Otherwise uses standard RT update method
+ * as defined by RapidIO specification. A specific routing table can be selected
+ * using the @table argument if a switch has per port routing tables or
+ * the standard (or global) table may be used by passing
+ * %RIO_GLOBAL_TABLE in @table.
+ *
+ * Returns %0 on success or %-EINVAL on failure.
+ */
+int rio_route_add_entry(struct rio_dev *rdev,
+			u16 table, u16 route_destid, u8 route_port, int lock)
+{
+	int rc = -EINVAL;
+	struct rio_switch_ops *ops = rdev->rswitch->ops;
+
+	if (lock) {
+		rc = rio_lock_device(rdev->net->hport, rdev->destid,
+				     rdev->hopcount, 1000);
+		if (rc)
+			return rc;
+	}
+
+	spin_lock(&rdev->rswitch->lock);
+
+	if (ops == NULL || ops->add_entry == NULL) {
+		rc = rio_std_route_add_entry(rdev->net->hport, rdev->destid,
+					     rdev->hopcount, table,
+					     route_destid, route_port);
+	} else if (try_module_get(ops->owner)) {
+		rc = ops->add_entry(rdev->net->hport, rdev->destid,
+				    rdev->hopcount, table, route_destid,
+				    route_port);
+		module_put(ops->owner);
+	}
+
+	spin_unlock(&rdev->rswitch->lock);
+
+	if (lock)
+		rio_unlock_device(rdev->net->hport, rdev->destid,
+				  rdev->hopcount);
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(rio_route_add_entry);
+
+/**
+ * rio_route_get_entry- Read an entry from a switch routing table
+ * @rdev: RIO device
+ * @table: Routing table ID
+ * @route_destid: Destination ID to be routed
+ * @route_port: Pointer to read port number into
+ * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock)
+ *
+ * If available calls the switch specific get_entry() method to fetch a route
+ * entry from a switch routing table. Otherwise uses standard RT read method
+ * as defined by RapidIO specification. A specific routing table can be selected
+ * using the @table argument if a switch has per port routing tables or
+ * the standard (or global) table may be used by passing
+ * %RIO_GLOBAL_TABLE in @table.
+ *
+ * Returns %0 on success or %-EINVAL on failure.
+ */
+int rio_route_get_entry(struct rio_dev *rdev, u16 table,
+			u16 route_destid, u8 *route_port, int lock)
+{
+	int rc = -EINVAL;
+	struct rio_switch_ops *ops = rdev->rswitch->ops;
+
+	if (lock) {
+		rc = rio_lock_device(rdev->net->hport, rdev->destid,
+				     rdev->hopcount, 1000);
+		if (rc)
+			return rc;
+	}
+
+	spin_lock(&rdev->rswitch->lock);
+
+	if (ops == NULL || ops->get_entry == NULL) {
+		rc = rio_std_route_get_entry(rdev->net->hport, rdev->destid,
+					     rdev->hopcount, table,
+					     route_destid, route_port);
+	} else if (try_module_get(ops->owner)) {
+		rc = ops->get_entry(rdev->net->hport, rdev->destid,
+				    rdev->hopcount, table, route_destid,
+				    route_port);
+		module_put(ops->owner);
+	}
+
+	spin_unlock(&rdev->rswitch->lock);
+
+	if (lock)
+		rio_unlock_device(rdev->net->hport, rdev->destid,
+				  rdev->hopcount);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(rio_route_get_entry);
+
+/**
+ * rio_route_clr_table - Clear a switch routing table
+ * @rdev: RIO device
+ * @table: Routing table ID
+ * @lock: apply a hardware lock on switch device flag (1=lock, 0=no_lock)
+ *
+ * If available calls the switch specific clr_table() method to clear a switch
+ * routing table. Otherwise uses standard RT write method as defined by RapidIO
+ * specification. A specific routing table can be selected using the @table
+ * argument if a switch has per port routing tables or the standard (or global)
+ * table may be used by passing %RIO_GLOBAL_TABLE in @table.
+ *
+ * Returns %0 on success or %-EINVAL on failure.
+ */
+int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock)
+{
+	int rc = -EINVAL;
+	struct rio_switch_ops *ops = rdev->rswitch->ops;
+
+	if (lock) {
+		rc = rio_lock_device(rdev->net->hport, rdev->destid,
+				     rdev->hopcount, 1000);
+		if (rc)
+			return rc;
+	}
+
+	spin_lock(&rdev->rswitch->lock);
+
+	if (ops == NULL || ops->clr_table == NULL) {
+		rc = rio_std_route_clr_table(rdev->net->hport, rdev->destid,
+					     rdev->hopcount, table);
+	} else if (try_module_get(ops->owner)) {
+		rc = ops->clr_table(rdev->net->hport, rdev->destid,
+				    rdev->hopcount, table);
+
+		module_put(ops->owner);
+	}
+
+	spin_unlock(&rdev->rswitch->lock);
+
+	if (lock)
+		rio_unlock_device(rdev->net->hport, rdev->destid,
+				  rdev->hopcount);
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(rio_route_clr_table);
+
 #ifdef CONFIG_RAPIDIO_DMA_ENGINE
 
 static bool rio_chan_filter(struct dma_chan *chan, void *arg)
@@ -1410,34 +1614,73 @@ found:
  * rio_register_scan - enumeration/discovery method registration interface
  * @mport_id: mport device ID for which fabric scan routine has to be set
  *            (RIO_MPORT_ANY = set for all available mports)
- * @scan_ops: enumeration/discovery control structure
+ * @scan_ops: enumeration/discovery operations structure
+ *
+ * Registers enumeration/discovery operations with RapidIO subsystem and
+ * attaches it to the specified mport device (or all available mports
+ * if RIO_MPORT_ANY is specified).
  *
- * Assigns enumeration or discovery method to the specified mport device (or all
- * available mports if RIO_MPORT_ANY is specified).
  * Returns error if the mport already has an enumerator attached to it.
- * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns
- * an error if was unable to find at least one available mport.
+ * In case of RIO_MPORT_ANY skips mports with valid scan routines (no error).
  */
 int rio_register_scan(int mport_id, struct rio_scan *scan_ops)
 {
 	struct rio_mport *port;
-	int rc = -EBUSY;
+	struct rio_scan_node *scan;
+	int rc = 0;
 
-	mutex_lock(&rio_mport_list_lock);
-	list_for_each_entry(port, &rio_mports, node) {
-		if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
-			if (port->nscan && mport_id == RIO_MPORT_ANY)
-				continue;
-			else if (port->nscan)
-				break;
+	pr_debug("RIO: %s for mport_id=%d\n", __func__, mport_id);
 
-			port->nscan = scan_ops;
-			rc = 0;
+	if ((mport_id != RIO_MPORT_ANY && mport_id >= RIO_MAX_MPORTS) ||
+	    !scan_ops)
+		return -EINVAL;
 
-			if (mport_id != RIO_MPORT_ANY)
-				break;
+	mutex_lock(&rio_mport_list_lock);
+
+	/*
+	 * Check if there is another enumerator already registered for
+	 * the same mport ID (including RIO_MPORT_ANY). Multiple enumerators
+	 * for the same mport ID are not supported.
+	 */
+	list_for_each_entry(scan, &rio_scans, node) {
+		if (scan->mport_id == mport_id) {
+			rc = -EBUSY;
+			goto err_out;
 		}
 	}
+
+	/*
+	 * Allocate and initialize new scan registration node.
+	 */
+	scan = kzalloc(sizeof(*scan), GFP_KERNEL);
+	if (!scan) {
+		rc = -ENOMEM;
+		goto err_out;
+	}
+
+	scan->mport_id = mport_id;
+	scan->ops = scan_ops;
+
+	/*
+	 * Traverse the list of registered mports to attach this new scan.
+	 *
+	 * The new scan with matching mport ID overrides any previously attached
+	 * scan assuming that old scan (if any) is the default one (based on the
+	 * enumerator registration check above).
+	 * If the new scan is the global one, it will be attached only to mports
+	 * that do not have their own individual operations already attached.
+	 */
+	list_for_each_entry(port, &rio_mports, node) {
+		if (port->id == mport_id) {
+			port->nscan = scan_ops;
+			break;
+		} else if (mport_id == RIO_MPORT_ANY && !port->nscan)
+			port->nscan = scan_ops;
+	}
+
+	list_add_tail(&scan->node, &rio_scans);
+
+err_out:
 	mutex_unlock(&rio_mport_list_lock);
 
 	return rc;
@@ -1447,30 +1690,83 @@ EXPORT_SYMBOL_GPL(rio_register_scan);
 /**
  * rio_unregister_scan - removes enumeration/discovery method from mport
  * @mport_id: mport device ID for which fabric scan routine has to be
- *            unregistered (RIO_MPORT_ANY = set for all available mports)
+ *            unregistered (RIO_MPORT_ANY = apply to all mports that use
+ *            the specified scan_ops)
+ * @scan_ops: enumeration/discovery operations structure
  *
  * Removes enumeration or discovery method assigned to the specified mport
- * device (or all available mports if RIO_MPORT_ANY is specified).
+ * device. If RIO_MPORT_ANY is specified, removes the specified operations from
+ * all mports that have them attached.
  */
-int rio_unregister_scan(int mport_id)
+int rio_unregister_scan(int mport_id, struct rio_scan *scan_ops)
 {
 	struct rio_mport *port;
+	struct rio_scan_node *scan;
+
+	pr_debug("RIO: %s for mport_id=%d\n", __func__, mport_id);
+
+	if (mport_id != RIO_MPORT_ANY && mport_id >= RIO_MAX_MPORTS)
+		return -EINVAL;
 
 	mutex_lock(&rio_mport_list_lock);
-	list_for_each_entry(port, &rio_mports, node) {
-		if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
-			if (port->nscan)
-				port->nscan = NULL;
-			if (mport_id != RIO_MPORT_ANY)
-				break;
+
+	list_for_each_entry(port, &rio_mports, node)
+		if (port->id == mport_id ||
+		    (mport_id == RIO_MPORT_ANY && port->nscan == scan_ops))
+			port->nscan = NULL;
+
+	list_for_each_entry(scan, &rio_scans, node) {
+		if (scan->mport_id == mport_id) {
+			list_del(&scan->node);
+			kfree(scan);
+			break;
 		}
 	}
+
 	mutex_unlock(&rio_mport_list_lock);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(rio_unregister_scan);
 
+/**
+ * rio_mport_scan - execute enumeration/discovery on the specified mport
+ * @mport_id: number (ID) of mport device
+ */
+int rio_mport_scan(int mport_id)
+{
+	struct rio_mport *port = NULL;
+	int rc;
+
+	mutex_lock(&rio_mport_list_lock);
+	list_for_each_entry(port, &rio_mports, node) {
+		if (port->id == mport_id)
+			goto found;
+	}
+	mutex_unlock(&rio_mport_list_lock);
+	return -ENODEV;
+found:
+	if (!port->nscan) {
+		mutex_unlock(&rio_mport_list_lock);
+		return -EINVAL;
+	}
+
+	if (!try_module_get(port->nscan->owner)) {
+		mutex_unlock(&rio_mport_list_lock);
+		return -ENODEV;
+	}
+
+	mutex_unlock(&rio_mport_list_lock);
+
+	if (port->host_deviceid >= 0)
+		rc = port->nscan->enumerate(port, 0);
+	else
+		rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT);
+
+	module_put(port->nscan->owner);
+	return rc;
+}
+
 static void rio_fixup_device(struct rio_dev *dev)
 {
 }
@@ -1499,7 +1795,10 @@ static void disc_work_handler(struct wor
 	work = container_of(_work, struct rio_disc_work, work);
 	pr_debug("RIO: discovery work for mport %d %s\n",
 		 work->mport->id, work->mport->name);
-	work->mport->nscan->discover(work->mport, 0);
+	if (try_module_get(work->mport->nscan->owner)) {
+		work->mport->nscan->discover(work->mport, 0);
+		module_put(work->mport->nscan->owner);
+	}
 }
 
 int rio_init_mports(void)
@@ -1518,8 +1817,10 @@ int rio_init_mports(void)
 	mutex_lock(&rio_mport_list_lock);
 	list_for_each_entry(port, &rio_mports, node) {
 		if (port->host_deviceid >= 0) {
-			if (port->nscan)
+			if (port->nscan && try_module_get(port->nscan->owner)) {
 				port->nscan->enumerate(port, 0);
+				module_put(port->nscan->owner);
+			}
 		} else
 			n++;
 	}
@@ -1533,7 +1834,7 @@ int rio_init_mports(void)
 	 * for each of them. If the code below fails to allocate needed
 	 * resources, exit without error to keep results of enumeration
 	 * process (if any).
-	 * TODO: Implement restart of dicovery process for all or
+	 * TODO: Implement restart of discovery process for all or
 	 * individual discovering mports.
 	 */
 	rio_wq = alloc_workqueue("riodisc", 0, 0);
@@ -1559,9 +1860,9 @@ int rio_init_mports(void)
 			n++;
 		}
 	}
-	mutex_unlock(&rio_mport_list_lock);
 
 	flush_workqueue(rio_wq);
+	mutex_unlock(&rio_mport_list_lock);
 	pr_debug("RIO: destroy discovery workqueue\n");
 	destroy_workqueue(rio_wq);
 	kfree(work);
@@ -1572,26 +1873,18 @@ no_disc:
 	return 0;
 }
 
-static int hdids[RIO_MAX_MPORTS + 1];
-
 static int rio_get_hdid(int index)
 {
-	if (!hdids[0] || hdids[0] <= index || index >= RIO_MAX_MPORTS)
+	if (ids_num == 0 || ids_num <= index || index >= RIO_MAX_MPORTS)
 		return -1;
 
-	return hdids[index + 1];
-}
-
-static int rio_hdid_setup(char *str)
-{
-	(void)get_options(str, ARRAY_SIZE(hdids), hdids);
-	return 1;
+	return hdid[index];
 }
 
-__setup("riohdid=", rio_hdid_setup);
-
 int rio_register_mport(struct rio_mport *port)
 {
+	struct rio_scan_node *scan = NULL;
+
 	if (next_portid >= RIO_MAX_MPORTS) {
 		pr_err("RIO: reached specified max number of mports\n");
 		return 1;
@@ -1600,11 +1893,28 @@ int rio_register_mport(struct rio_mport
 	port->id = next_portid++;
 	port->host_deviceid = rio_get_hdid(port->id);
 	port->nscan = NULL;
+
 	mutex_lock(&rio_mport_list_lock);
 	list_add_tail(&port->node, &rio_mports);
+
+	/*
+	 * Check if there are any registered enumeration/discovery operations
+	 * that have to be attached to the added mport.
+	 */
+	list_for_each_entry(scan, &rio_scans, node) {
+		if (port->id == scan->mport_id ||
+		    scan->mport_id == RIO_MPORT_ANY) {
+			port->nscan = scan->ops;
+			if (port->id == scan->mport_id)
+				break;
+		}
+	}
 	mutex_unlock(&rio_mport_list_lock);
+
+	pr_debug("RIO: %s %s id=%d\n", __func__, port->name, port->id);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(rio_register_mport);
 
 EXPORT_SYMBOL_GPL(rio_local_get_device_id);
 EXPORT_SYMBOL_GPL(rio_get_device);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/rio-driver.c linux-libre-3.11-rc7-gnu/drivers/rapidio/rio-driver.c
--- linux-libre-3.10-gnu/drivers/rapidio/rio-driver.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/rio-driver.c	2013-08-25 20:43:22.000000000 -0400
@@ -199,6 +199,23 @@ static int rio_match_bus(struct device *
       out:return 0;
 }
 
+static int rio_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	struct rio_dev *rdev;
+
+	if (!dev)
+		return -ENODEV;
+
+	rdev = to_rio_dev(dev);
+	if (!rdev)
+		return -ENODEV;
+
+	if (add_uevent_var(env, "MODALIAS=rapidio:v%04Xd%04Xav%04Xad%04X",
+			   rdev->vid, rdev->did, rdev->asm_vid, rdev->asm_did))
+		return -ENOMEM;
+	return 0;
+}
+
 struct device rio_bus = {
 	.init_name = "rapidio",
 };
@@ -210,6 +227,7 @@ struct bus_type rio_bus_type = {
 	.bus_attrs = rio_bus_attrs,
 	.probe = rio_device_probe,
 	.remove = rio_device_remove,
+	.uevent	= rio_uevent,
 };
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/rio.h linux-libre-3.11-rc7-gnu/drivers/rapidio/rio.h
--- linux-libre-3.10-gnu/drivers/rapidio/rio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/rio.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,52 +28,28 @@ extern u32 rio_mport_get_efb(struct rio_
 extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid,
 				    u8 hopcount);
 extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
-extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid,
-				   u8 hopcount, u16 table, u16 route_destid,
-				   u8 route_port);
-extern int rio_std_route_get_entry(struct rio_mport *mport, u16 destid,
-				   u8 hopcount, u16 table, u16 route_destid,
-				   u8 *route_port);
-extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid,
-				   u8 hopcount, u16 table);
+extern int rio_lock_device(struct rio_mport *port, u16 destid,
+			u8 hopcount, int wait_ms);
+extern int rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount);
+extern int rio_route_add_entry(struct rio_dev *rdev,
+			u16 table, u16 route_destid, u8 route_port, int lock);
+extern int rio_route_get_entry(struct rio_dev *rdev, u16 table,
+			u16 route_destid, u8 *route_port, int lock);
+extern int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock);
 extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock);
 extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from);
 extern int rio_add_device(struct rio_dev *rdev);
-extern void rio_switch_init(struct rio_dev *rdev, int do_enum);
 extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid,
 				 u8 hopcount, u8 port_num);
 extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops);
-extern int rio_unregister_scan(int mport_id);
+extern int rio_unregister_scan(int mport_id, struct rio_scan *scan_ops);
 extern void rio_attach_device(struct rio_dev *rdev);
 extern struct rio_mport *rio_find_mport(int mport_id);
+extern int rio_mport_scan(int mport_id);
 
 /* Structures internal to the RIO core code */
 extern struct device_attribute rio_dev_attrs[];
 extern struct bus_attribute rio_bus_attrs[];
 
-extern struct rio_switch_ops __start_rio_switch_ops[];
-extern struct rio_switch_ops __end_rio_switch_ops[];
-
-/* Helpers internal to the RIO core code */
-#define DECLARE_RIO_SWITCH_SECTION(section, name, vid, did, init_hook) \
-	static const struct rio_switch_ops __rio_switch_##name __used \
-	__section(section) = { vid, did, init_hook };
-
-/**
- * DECLARE_RIO_SWITCH_INIT - Registers switch initialization routine
- * @vid: RIO vendor ID
- * @did: RIO device ID
- * @init_hook: Callback that performs switch-specific initialization
- *
- * Manipulating switch route tables and error management in RIO
- * is switch specific. This registers a switch by vendor and device ID with
- * initialization callback for setting up switch operations and (if required)
- * hardware initialization. A &struct rio_switch_ops is initialized with
- * pointer to the init routine and placed into a RIO-specific kernel section.
- */
-#define DECLARE_RIO_SWITCH_INIT(vid, did, init_hook)		\
-	DECLARE_RIO_SWITCH_SECTION(.rio_switch_ops, vid##did, \
-			vid, did, init_hook)
-
 #define RIO_GET_DID(size, x)	(size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16))
 #define RIO_SET_DID(size, x)	(size ? (x & 0xffff) : ((x & 0x000000ff) << 16))
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/rio-scan.c linux-libre-3.11-rc7-gnu/drivers/rapidio/rio-scan.c
--- linux-libre-3.10-gnu/drivers/rapidio/rio-scan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/rio-scan.c	2013-08-25 20:43:22.000000000 -0400
@@ -406,6 +406,7 @@ static struct rio_dev *rio_setup_device(
 		rio_mport_write_config_32(port, destid, hopcount,
 					  RIO_COMPONENT_TAG_CSR, next_comptag);
 		rdev->comp_tag = next_comptag++;
+		rdev->do_enum = true;
 	}  else {
 		rio_mport_read_config_32(port, destid, hopcount,
 					 RIO_COMPONENT_TAG_CSR,
@@ -432,8 +433,8 @@ static struct rio_dev *rio_setup_device(
 	/* If a PE has both switch and other functions, show it as a switch */
 	if (rio_is_switch(rdev)) {
 		rswitch = rdev->rswitch;
-		rswitch->switchid = rdev->comp_tag & RIO_CTAG_UDEVID;
 		rswitch->port_ok = 0;
+		spin_lock_init(&rswitch->lock);
 		rswitch->route_table = kzalloc(sizeof(u8)*
 					RIO_MAX_ROUTE_ENTRIES(port->sys_size),
 					GFP_KERNEL);
@@ -444,12 +445,10 @@ static struct rio_dev *rio_setup_device(
 				rdid++)
 			rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
 		dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id,
-			     rswitch->switchid);
-		rio_switch_init(rdev, do_enum);
+			     rdev->comp_tag & RIO_CTAG_UDEVID);
 
-		if (do_enum && rswitch->clr_table)
-			rswitch->clr_table(port, destid, hopcount,
-					   RIO_GLOBAL_TABLE);
+		if (do_enum)
+			rio_route_clr_table(rdev, RIO_GLOBAL_TABLE, 0);
 
 		list_add_tail(&rswitch->node, &net->switches);
 
@@ -459,7 +458,7 @@ static struct rio_dev *rio_setup_device(
 			rio_enable_rx_tx_port(port, 0, destid, hopcount, 0);
 
 		dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id,
-			     rdev->destid);
+			     rdev->comp_tag & RIO_CTAG_UDEVID);
 	}
 
 	rio_attach_device(rdev);
@@ -533,156 +532,6 @@ rio_sport_is_active(struct rio_mport *po
 }
 
 /**
- * rio_lock_device - Acquires host device lock for specified device
- * @port: Master port to send transaction
- * @destid: Destination ID for device/switch
- * @hopcount: Hopcount to reach switch
- * @wait_ms: Max wait time in msec (0 = no timeout)
- *
- * Attepts to acquire host device lock for specified device
- * Returns 0 if device lock acquired or EINVAL if timeout expires.
- */
-static int
-rio_lock_device(struct rio_mport *port, u16 destid, u8 hopcount, int wait_ms)
-{
-	u32 result;
-	int tcnt = 0;
-
-	/* Attempt to acquire device lock */
-	rio_mport_write_config_32(port, destid, hopcount,
-				  RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
-	rio_mport_read_config_32(port, destid, hopcount,
-				 RIO_HOST_DID_LOCK_CSR, &result);
-
-	while (result != port->host_deviceid) {
-		if (wait_ms != 0 && tcnt == wait_ms) {
-			pr_debug("RIO: timeout when locking device %x:%x\n",
-				destid, hopcount);
-			return -EINVAL;
-		}
-
-		/* Delay a bit */
-		mdelay(1);
-		tcnt++;
-		/* Try to acquire device lock again */
-		rio_mport_write_config_32(port, destid,
-			hopcount,
-			RIO_HOST_DID_LOCK_CSR,
-			port->host_deviceid);
-		rio_mport_read_config_32(port, destid,
-			hopcount,
-			RIO_HOST_DID_LOCK_CSR, &result);
-	}
-
-	return 0;
-}
-
-/**
- * rio_unlock_device - Releases host device lock for specified device
- * @port: Master port to send transaction
- * @destid: Destination ID for device/switch
- * @hopcount: Hopcount to reach switch
- *
- * Returns 0 if device lock released or EINVAL if fails.
- */
-static int
-rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount)
-{
-	u32 result;
-
-	/* Release device lock */
-	rio_mport_write_config_32(port, destid,
-				  hopcount,
-				  RIO_HOST_DID_LOCK_CSR,
-				  port->host_deviceid);
-	rio_mport_read_config_32(port, destid, hopcount,
-		RIO_HOST_DID_LOCK_CSR, &result);
-	if ((result & 0xffff) != 0xffff) {
-		pr_debug("RIO: badness when releasing device lock %x:%x\n",
-			 destid, hopcount);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/**
- * rio_route_add_entry- Add a route entry to a switch routing table
- * @rdev: RIO device
- * @table: Routing table ID
- * @route_destid: Destination ID to be routed
- * @route_port: Port number to be routed
- * @lock: lock switch device flag
- *
- * Calls the switch specific add_entry() method to add a route entry
- * on a switch. The route table can be specified using the @table
- * argument if a switch has per port routing tables or the normal
- * use is to specific all tables (or the global table) by passing
- * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
- * on failure.
- */
-static int
-rio_route_add_entry(struct rio_dev *rdev,
-		    u16 table, u16 route_destid, u8 route_port, int lock)
-{
-	int rc;
-
-	if (lock) {
-		rc = rio_lock_device(rdev->net->hport, rdev->destid,
-				     rdev->hopcount, 1000);
-		if (rc)
-			return rc;
-	}
-
-	rc = rdev->rswitch->add_entry(rdev->net->hport, rdev->destid,
-				      rdev->hopcount, table,
-				      route_destid, route_port);
-	if (lock)
-		rio_unlock_device(rdev->net->hport, rdev->destid,
-				  rdev->hopcount);
-
-	return rc;
-}
-
-/**
- * rio_route_get_entry- Read a route entry in a switch routing table
- * @rdev: RIO device
- * @table: Routing table ID
- * @route_destid: Destination ID to be routed
- * @route_port: Pointer to read port number into
- * @lock: lock switch device flag
- *
- * Calls the switch specific get_entry() method to read a route entry
- * in a switch. The route table can be specified using the @table
- * argument if a switch has per port routing tables or the normal
- * use is to specific all tables (or the global table) by passing
- * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
- * on failure.
- */
-static int
-rio_route_get_entry(struct rio_dev *rdev, u16 table,
-		    u16 route_destid, u8 *route_port, int lock)
-{
-	int rc;
-
-	if (lock) {
-		rc = rio_lock_device(rdev->net->hport, rdev->destid,
-				     rdev->hopcount, 1000);
-		if (rc)
-			return rc;
-	}
-
-	rc = rdev->rswitch->get_entry(rdev->net->hport, rdev->destid,
-				      rdev->hopcount, table,
-				      route_destid, route_port);
-	if (lock)
-		rio_unlock_device(rdev->net->hport, rdev->destid,
-				  rdev->hopcount);
-
-	return rc;
-}
-
-/**
  * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device
  * @port: Master port to send transaction
  * @hopcount: Number of hops to the device
@@ -1094,12 +943,9 @@ static void rio_update_route_tables(stru
 
 				sport = RIO_GET_PORT_NUM(swrdev->swpinfo);
 
-				if (rswitch->add_entry)	{
-					rio_route_add_entry(swrdev,
-						RIO_GLOBAL_TABLE, destid,
-						sport, 0);
-					rswitch->route_table[destid] = sport;
-				}
+				rio_route_add_entry(swrdev, RIO_GLOBAL_TABLE,
+						    destid, sport, 0);
+				rswitch->route_table[destid] = sport;
 			}
 		}
 	}
@@ -1115,8 +961,8 @@ static void rio_update_route_tables(stru
 static void rio_init_em(struct rio_dev *rdev)
 {
 	if (rio_is_switch(rdev) && (rdev->em_efptr) &&
-	    (rdev->rswitch->em_init)) {
-		rdev->rswitch->em_init(rdev);
+	    rdev->rswitch->ops && rdev->rswitch->ops->em_init) {
+		rdev->rswitch->ops->em_init(rdev);
 	}
 }
 
@@ -1141,7 +987,7 @@ static void rio_pw_enable(struct rio_mpo
  * link, then start recursive peer enumeration. Returns %0 if
  * enumeration succeeds or %-EBUSY if enumeration fails.
  */
-int rio_enum_mport(struct rio_mport *mport, u32 flags)
+static int rio_enum_mport(struct rio_mport *mport, u32 flags)
 {
 	struct rio_net *net = NULL;
 	int rc = 0;
@@ -1256,7 +1102,7 @@ static void rio_build_route_tables(struc
  * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
  * on failure.
  */
-int rio_disc_mport(struct rio_mport *mport, u32 flags)
+static int rio_disc_mport(struct rio_mport *mport, u32 flags)
 {
 	struct rio_net *net = NULL;
 	unsigned long to_end;
@@ -1315,6 +1161,7 @@ bail:
 }
 
 static struct rio_scan rio_scan_ops = {
+	.owner = THIS_MODULE,
 	.enumerate = rio_enum_mport,
 	.discover = rio_disc_mport,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/rio-sysfs.c linux-libre-3.11-rc7-gnu/drivers/rapidio/rio-sysfs.c
--- linux-libre-3.10-gnu/drivers/rapidio/rio-sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/rio-sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -84,6 +84,15 @@ static ssize_t lnext_show(struct device
 	return str - buf;
 }
 
+static ssize_t modalias_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct rio_dev *rdev = to_rio_dev(dev);
+
+	return sprintf(buf, "rapidio:v%04Xd%04Xav%04Xad%04X\n",
+		       rdev->vid, rdev->did, rdev->asm_vid, rdev->asm_did);
+}
+
 struct device_attribute rio_dev_attrs[] = {
 	__ATTR_RO(did),
 	__ATTR_RO(vid),
@@ -93,6 +102,7 @@ struct device_attribute rio_dev_attrs[]
 	__ATTR_RO(asm_rev),
 	__ATTR_RO(lprev),
 	__ATTR_RO(destid),
+	__ATTR_RO(modalias),
 	__ATTR_NULL,
 };
 
@@ -257,8 +267,6 @@ int rio_create_sysfs_dev_files(struct ri
 		err |= device_create_file(&rdev->dev, &dev_attr_routes);
 		err |= device_create_file(&rdev->dev, &dev_attr_lnext);
 		err |= device_create_file(&rdev->dev, &dev_attr_hopcount);
-		if (!err && rdev->rswitch->sw_sysfs)
-			err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE);
 	}
 
 	if (err)
@@ -281,8 +289,6 @@ void rio_remove_sysfs_dev_files(struct r
 		device_remove_file(&rdev->dev, &dev_attr_routes);
 		device_remove_file(&rdev->dev, &dev_attr_lnext);
 		device_remove_file(&rdev->dev, &dev_attr_hopcount);
-		if (rdev->rswitch->sw_sysfs)
-			rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);
 	}
 }
 
@@ -290,7 +296,6 @@ static ssize_t bus_scan_store(struct bus
 				size_t count)
 {
 	long val;
-	struct rio_mport *port = NULL;
 	int rc;
 
 	if (kstrtol(buf, 0, &val) < 0)
@@ -304,21 +309,7 @@ static ssize_t bus_scan_store(struct bus
 	if (val < 0 || val >= RIO_MAX_MPORTS)
 		return -EINVAL;
 
-	port = rio_find_mport((int)val);
-
-	if (!port) {
-		pr_debug("RIO: %s: mport_%d not available\n",
-			 __func__, (int)val);
-		return -EINVAL;
-	}
-
-	if (!port->nscan)
-		return -EINVAL;
-
-	if (port->host_deviceid >= 0)
-		rc = port->nscan->enumerate(port, 0);
-	else
-		rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT);
+	rc = rio_mport_scan((int)val);
 exit:
 	if (!rc)
 		rc = count;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/switches/idtcps.c linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/idtcps.c
--- linux-libre-3.10-gnu/drivers/rapidio/switches/idtcps.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/idtcps.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/rio.h>
 #include <linux/rio_drv.h>
 #include <linux/rio_ids.h>
+#include <linux/module.h>
 #include "../rio.h"
 
 #define CPS_DEFAULT_ROUTE	0xde
@@ -118,18 +119,31 @@ idtcps_get_domain(struct rio_mport *mpor
 	return 0;
 }
 
-static int idtcps_switch_init(struct rio_dev *rdev, int do_enum)
+static struct rio_switch_ops idtcps_switch_ops = {
+	.owner = THIS_MODULE,
+	.add_entry = idtcps_route_add_entry,
+	.get_entry = idtcps_route_get_entry,
+	.clr_table = idtcps_route_clr_table,
+	.set_domain = idtcps_set_domain,
+	.get_domain = idtcps_get_domain,
+	.em_init = NULL,
+	.em_handle = NULL,
+};
+
+static int idtcps_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 {
 	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
-	rdev->rswitch->add_entry = idtcps_route_add_entry;
-	rdev->rswitch->get_entry = idtcps_route_get_entry;
-	rdev->rswitch->clr_table = idtcps_route_clr_table;
-	rdev->rswitch->set_domain = idtcps_set_domain;
-	rdev->rswitch->get_domain = idtcps_get_domain;
-	rdev->rswitch->em_init = NULL;
-	rdev->rswitch->em_handle = NULL;
 
-	if (do_enum) {
+	spin_lock(&rdev->rswitch->lock);
+
+	if (rdev->rswitch->ops) {
+		spin_unlock(&rdev->rswitch->lock);
+		return -EINVAL;
+	}
+
+	rdev->rswitch->ops = &idtcps_switch_ops;
+
+	if (rdev->do_enum) {
 		/* set TVAL = ~50us */
 		rio_write_config_32(rdev,
 			rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
@@ -138,12 +152,52 @@ static int idtcps_switch_init(struct rio
 				    RIO_STD_RTE_DEFAULT_PORT, CPS_NO_ROUTE);
 	}
 
+	spin_unlock(&rdev->rswitch->lock);
 	return 0;
 }
 
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_switch_init);
+static void idtcps_remove(struct rio_dev *rdev)
+{
+	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
+	spin_lock(&rdev->rswitch->lock);
+	if (rdev->rswitch->ops != &idtcps_switch_ops) {
+		spin_unlock(&rdev->rswitch->lock);
+		return;
+	}
+	rdev->rswitch->ops = NULL;
+	spin_unlock(&rdev->rswitch->lock);
+}
+
+static struct rio_device_id idtcps_id_table[] = {
+	{RIO_DEVICE(RIO_DID_IDTCPS6Q, RIO_VID_IDT)},
+	{RIO_DEVICE(RIO_DID_IDTCPS8, RIO_VID_IDT)},
+	{RIO_DEVICE(RIO_DID_IDTCPS10Q, RIO_VID_IDT)},
+	{RIO_DEVICE(RIO_DID_IDTCPS12, RIO_VID_IDT)},
+	{RIO_DEVICE(RIO_DID_IDTCPS16, RIO_VID_IDT)},
+	{RIO_DEVICE(RIO_DID_IDT70K200, RIO_VID_IDT)},
+	{ 0, }	/* terminate list */
+};
+
+static struct rio_driver idtcps_driver = {
+	.name = "idtcps",
+	.id_table = idtcps_id_table,
+	.probe = idtcps_probe,
+	.remove = idtcps_remove,
+};
+
+static int __init idtcps_init(void)
+{
+	return rio_register_driver(&idtcps_driver);
+}
+
+static void __exit idtcps_exit(void)
+{
+	rio_unregister_driver(&idtcps_driver);
+}
+
+device_initcall(idtcps_init);
+module_exit(idtcps_exit);
+
+MODULE_DESCRIPTION("IDT CPS Gen.1 Serial RapidIO switch family driver");
+MODULE_AUTHOR("Integrated Device Technology, Inc.");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/switches/idt_gen2.c linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/idt_gen2.c
--- linux-libre-3.10-gnu/drivers/rapidio/switches/idt_gen2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/idt_gen2.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,10 +11,13 @@
  */
 
 #include <linux/stat.h>
+#include <linux/module.h>
 #include <linux/rio.h>
 #include <linux/rio_drv.h>
 #include <linux/rio_ids.h>
 #include <linux/delay.h>
+
+#include <asm/page.h>
 #include "../rio.h"
 
 #define LOCAL_RTE_CONF_DESTID_SEL	0x010070
@@ -387,12 +390,12 @@ idtg2_show_errlog(struct device *dev, st
 
 static DEVICE_ATTR(errlog, S_IRUGO, idtg2_show_errlog, NULL);
 
-static int idtg2_sysfs(struct rio_dev *rdev, int create)
+static int idtg2_sysfs(struct rio_dev *rdev, bool create)
 {
 	struct device *dev = &rdev->dev;
 	int err = 0;
 
-	if (create == RIO_SW_SYSFS_CREATE) {
+	if (create) {
 		/* Initialize sysfs entries */
 		err = device_create_file(dev, &dev_attr_errlog);
 		if (err)
@@ -403,29 +406,90 @@ static int idtg2_sysfs(struct rio_dev *r
 	return err;
 }
 
-static int idtg2_switch_init(struct rio_dev *rdev, int do_enum)
+static struct rio_switch_ops idtg2_switch_ops = {
+	.owner = THIS_MODULE,
+	.add_entry = idtg2_route_add_entry,
+	.get_entry = idtg2_route_get_entry,
+	.clr_table = idtg2_route_clr_table,
+	.set_domain = idtg2_set_domain,
+	.get_domain = idtg2_get_domain,
+	.em_init = idtg2_em_init,
+	.em_handle = idtg2_em_handler,
+};
+
+static int idtg2_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 {
 	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
-	rdev->rswitch->add_entry = idtg2_route_add_entry;
-	rdev->rswitch->get_entry = idtg2_route_get_entry;
-	rdev->rswitch->clr_table = idtg2_route_clr_table;
-	rdev->rswitch->set_domain = idtg2_set_domain;
-	rdev->rswitch->get_domain = idtg2_get_domain;
-	rdev->rswitch->em_init = idtg2_em_init;
-	rdev->rswitch->em_handle = idtg2_em_handler;
-	rdev->rswitch->sw_sysfs = idtg2_sysfs;
 
-	if (do_enum) {
+	spin_lock(&rdev->rswitch->lock);
+
+	if (rdev->rswitch->ops) {
+		spin_unlock(&rdev->rswitch->lock);
+		return -EINVAL;
+	}
+
+	rdev->rswitch->ops = &idtg2_switch_ops;
+
+	if (rdev->do_enum) {
 		/* Ensure that default routing is disabled on startup */
 		rio_write_config_32(rdev,
 				    RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE);
 	}
 
+	/* Create device-specific sysfs attributes */
+	idtg2_sysfs(rdev, true);
+
+	spin_unlock(&rdev->rswitch->lock);
 	return 0;
 }
 
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1848, idtg2_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1616, idtg2_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTVPS1616, idtg2_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTSPS1616, idtg2_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1432, idtg2_switch_init);
+static void idtg2_remove(struct rio_dev *rdev)
+{
+	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
+	spin_lock(&rdev->rswitch->lock);
+	if (rdev->rswitch->ops != &idtg2_switch_ops) {
+		spin_unlock(&rdev->rswitch->lock);
+		return;
+	}
+	rdev->rswitch->ops = NULL;
+
+	/* Remove device-specific sysfs attributes */
+	idtg2_sysfs(rdev, false);
+
+	spin_unlock(&rdev->rswitch->lock);
+}
+
+static struct rio_device_id idtg2_id_table[] = {
+	{RIO_DEVICE(RIO_DID_IDTCPS1848, RIO_VID_IDT)},
+	{RIO_DEVICE(RIO_DID_IDTCPS1616, RIO_VID_IDT)},
+	{RIO_DEVICE(RIO_DID_IDTVPS1616, RIO_VID_IDT)},
+	{RIO_DEVICE(RIO_DID_IDTSPS1616, RIO_VID_IDT)},
+	{RIO_DEVICE(RIO_DID_IDTCPS1432, RIO_VID_IDT)},
+	{ 0, }	/* terminate list */
+};
+
+static struct rio_driver idtg2_driver = {
+	.name = "idt_gen2",
+	.id_table = idtg2_id_table,
+	.probe = idtg2_probe,
+	.remove = idtg2_remove,
+};
+
+static int __init idtg2_init(void)
+{
+	return rio_register_driver(&idtg2_driver);
+}
+
+static void __exit idtg2_exit(void)
+{
+	pr_debug("RIO: %s\n", __func__);
+	rio_unregister_driver(&idtg2_driver);
+	pr_debug("RIO: %s done\n", __func__);
+}
+
+device_initcall(idtg2_init);
+module_exit(idtg2_exit);
+
+MODULE_DESCRIPTION("IDT CPS Gen.2 Serial RapidIO switch family driver");
+MODULE_AUTHOR("Integrated Device Technology, Inc.");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/switches/Kconfig linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/Kconfig
--- linux-libre-3.10-gnu/drivers/rapidio/switches/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -2,34 +2,23 @@
 # RapidIO switches configuration
 #
 config RAPIDIO_TSI57X
-	bool "IDT Tsi57x SRIO switches support"
-	depends on RAPIDIO
+	tristate "IDT Tsi57x SRIO switches support"
 	---help---
 	  Includes support for IDT Tsi57x family of serial RapidIO switches.
 
 config RAPIDIO_CPS_XX
-	bool "IDT CPS-xx SRIO switches support"
-	depends on RAPIDIO
+	tristate "IDT CPS-xx SRIO switches support"
 	---help---
 	  Includes support for IDT CPS-16/12/10/8 serial RapidIO switches.
 
 config RAPIDIO_TSI568
-	bool "Tsi568 SRIO switch support"
-	depends on RAPIDIO
+	tristate "Tsi568 SRIO switch support"
 	default n
 	---help---
 	  Includes support for IDT Tsi568 serial RapidIO switch.
 
 config RAPIDIO_CPS_GEN2
-	bool "IDT CPS Gen.2 SRIO switch support"
-	depends on RAPIDIO
+	tristate "IDT CPS Gen.2 SRIO switch support"
 	default n
 	---help---
 	  Includes support for ITD CPS Gen.2 serial RapidIO switches.
-
-config RAPIDIO_TSI500
-	bool "Tsi500 Parallel RapidIO switch support"
-	depends on RAPIDIO
-	default n
-	---help---
-	  Includes support for IDT Tsi500 parallel RapidIO switch.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/switches/Makefile linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/Makefile
--- linux-libre-3.10-gnu/drivers/rapidio/switches/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,5 +5,4 @@
 obj-$(CONFIG_RAPIDIO_TSI57X)	+= tsi57x.o
 obj-$(CONFIG_RAPIDIO_CPS_XX)	+= idtcps.o
 obj-$(CONFIG_RAPIDIO_TSI568)	+= tsi568.o
-obj-$(CONFIG_RAPIDIO_TSI500)	+= tsi500.o
 obj-$(CONFIG_RAPIDIO_CPS_GEN2)	+= idt_gen2.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/switches/tsi500.c linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/tsi500.c
--- linux-libre-3.10-gnu/drivers/rapidio/switches/tsi500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/tsi500.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,78 +0,0 @@
-/*
- * RapidIO Tsi500 switch support
- *
- * Copyright 2009-2010 Integrated Device Technology, Inc.
- * Alexandre Bounine <alexandre.bounine@idt.com>
- *  - Modified switch operations initialization.
- *
- * Copyright 2005 MontaVista Software, Inc.
- * Matt Porter <mporter@kernel.crashing.org>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <linux/rio.h>
-#include <linux/rio_drv.h>
-#include <linux/rio_ids.h>
-#include "../rio.h"
-
-static int
-tsi500_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port)
-{
-	int i;
-	u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
-	u32 result;
-
-	if (table == 0xff) {
-		rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
-		result &= ~(0xf << (4*(route_destid & 0x7)));
-		for (i=0;i<4;i++)
-			rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*i), result | (route_port << (4*(route_destid & 0x7))));
-	}
-	else {
-		rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
-		result &= ~(0xf << (4*(route_destid & 0x7)));
-		rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*table), result | (route_port << (4*(route_destid & 0x7))));
-	}
-
-	return 0;
-}
-
-static int
-tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port)
-{
-	int ret = 0;
-	u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
-	u32 result;
-
-	if (table == 0xff)
-		rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
-	else
-		rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
-
-	result &= 0xf << (4*(route_destid & 0x7));
-	*route_port = result >> (4*(route_destid & 0x7));
-	if (*route_port > 3)
-		ret = -1;
-
-	return ret;
-}
-
-static int tsi500_switch_init(struct rio_dev *rdev, int do_enum)
-{
-	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
-	rdev->rswitch->add_entry = tsi500_route_add_entry;
-	rdev->rswitch->get_entry = tsi500_route_get_entry;
-	rdev->rswitch->clr_table = NULL;
-	rdev->rswitch->set_domain = NULL;
-	rdev->rswitch->get_domain = NULL;
-	rdev->rswitch->em_init = NULL;
-	rdev->rswitch->em_handle = NULL;
-
-	return 0;
-}
-
-DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_switch_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/switches/tsi568.c linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/tsi568.c
--- linux-libre-3.10-gnu/drivers/rapidio/switches/tsi568.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/tsi568.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/rio_drv.h>
 #include <linux/rio_ids.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include "../rio.h"
 
 /* Global (broadcast) route registers */
@@ -129,18 +130,70 @@ tsi568_em_init(struct rio_dev *rdev)
 	return 0;
 }
 
-static int tsi568_switch_init(struct rio_dev *rdev, int do_enum)
+static struct rio_switch_ops tsi568_switch_ops = {
+	.owner = THIS_MODULE,
+	.add_entry = tsi568_route_add_entry,
+	.get_entry = tsi568_route_get_entry,
+	.clr_table = tsi568_route_clr_table,
+	.set_domain = NULL,
+	.get_domain = NULL,
+	.em_init = tsi568_em_init,
+	.em_handle = NULL,
+};
+
+static int tsi568_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 {
 	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
-	rdev->rswitch->add_entry = tsi568_route_add_entry;
-	rdev->rswitch->get_entry = tsi568_route_get_entry;
-	rdev->rswitch->clr_table = tsi568_route_clr_table;
-	rdev->rswitch->set_domain = NULL;
-	rdev->rswitch->get_domain = NULL;
-	rdev->rswitch->em_init = tsi568_em_init;
-	rdev->rswitch->em_handle = NULL;
 
+	spin_lock(&rdev->rswitch->lock);
+
+	if (rdev->rswitch->ops) {
+		spin_unlock(&rdev->rswitch->lock);
+		return -EINVAL;
+	}
+
+	rdev->rswitch->ops = &tsi568_switch_ops;
+	spin_unlock(&rdev->rswitch->lock);
 	return 0;
 }
 
-DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_switch_init);
+static void tsi568_remove(struct rio_dev *rdev)
+{
+	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
+	spin_lock(&rdev->rswitch->lock);
+	if (rdev->rswitch->ops != &tsi568_switch_ops) {
+		spin_unlock(&rdev->rswitch->lock);
+		return;
+	}
+	rdev->rswitch->ops = NULL;
+	spin_unlock(&rdev->rswitch->lock);
+}
+
+static struct rio_device_id tsi568_id_table[] = {
+	{RIO_DEVICE(RIO_DID_TSI568, RIO_VID_TUNDRA)},
+	{ 0, }	/* terminate list */
+};
+
+static struct rio_driver tsi568_driver = {
+	.name = "tsi568",
+	.id_table = tsi568_id_table,
+	.probe = tsi568_probe,
+	.remove = tsi568_remove,
+};
+
+static int __init tsi568_init(void)
+{
+	return rio_register_driver(&tsi568_driver);
+}
+
+static void __exit tsi568_exit(void)
+{
+	rio_unregister_driver(&tsi568_driver);
+}
+
+device_initcall(tsi568_init);
+module_exit(tsi568_exit);
+
+MODULE_DESCRIPTION("IDT Tsi568 Serial RapidIO switch driver");
+MODULE_AUTHOR("Integrated Device Technology, Inc.");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rapidio/switches/tsi57x.c linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/tsi57x.c
--- linux-libre-3.10-gnu/drivers/rapidio/switches/tsi57x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rapidio/switches/tsi57x.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/rio_drv.h>
 #include <linux/rio_ids.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include "../rio.h"
 
 /* Global (broadcast) route registers */
@@ -292,27 +293,79 @@ exit_es:
 	return 0;
 }
 
-static int tsi57x_switch_init(struct rio_dev *rdev, int do_enum)
+static struct rio_switch_ops tsi57x_switch_ops = {
+	.owner = THIS_MODULE,
+	.add_entry = tsi57x_route_add_entry,
+	.get_entry = tsi57x_route_get_entry,
+	.clr_table = tsi57x_route_clr_table,
+	.set_domain = tsi57x_set_domain,
+	.get_domain = tsi57x_get_domain,
+	.em_init = tsi57x_em_init,
+	.em_handle = tsi57x_em_handler,
+};
+
+static int tsi57x_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 {
 	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
-	rdev->rswitch->add_entry = tsi57x_route_add_entry;
-	rdev->rswitch->get_entry = tsi57x_route_get_entry;
-	rdev->rswitch->clr_table = tsi57x_route_clr_table;
-	rdev->rswitch->set_domain = tsi57x_set_domain;
-	rdev->rswitch->get_domain = tsi57x_get_domain;
-	rdev->rswitch->em_init = tsi57x_em_init;
-	rdev->rswitch->em_handle = tsi57x_em_handler;
 
-	if (do_enum) {
+	spin_lock(&rdev->rswitch->lock);
+
+	if (rdev->rswitch->ops) {
+		spin_unlock(&rdev->rswitch->lock);
+		return -EINVAL;
+	}
+	rdev->rswitch->ops = &tsi57x_switch_ops;
+
+	if (rdev->do_enum) {
 		/* Ensure that default routing is disabled on startup */
 		rio_write_config_32(rdev, RIO_STD_RTE_DEFAULT_PORT,
 				    RIO_INVALID_ROUTE);
 	}
 
+	spin_unlock(&rdev->rswitch->lock);
 	return 0;
 }
 
-DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_switch_init);
-DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_switch_init);
+static void tsi57x_remove(struct rio_dev *rdev)
+{
+	pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
+	spin_lock(&rdev->rswitch->lock);
+	if (rdev->rswitch->ops != &tsi57x_switch_ops) {
+		spin_unlock(&rdev->rswitch->lock);
+		return;
+	}
+	rdev->rswitch->ops = NULL;
+	spin_unlock(&rdev->rswitch->lock);
+}
+
+static struct rio_device_id tsi57x_id_table[] = {
+	{RIO_DEVICE(RIO_DID_TSI572, RIO_VID_TUNDRA)},
+	{RIO_DEVICE(RIO_DID_TSI574, RIO_VID_TUNDRA)},
+	{RIO_DEVICE(RIO_DID_TSI577, RIO_VID_TUNDRA)},
+	{RIO_DEVICE(RIO_DID_TSI578, RIO_VID_TUNDRA)},
+	{ 0, }	/* terminate list */
+};
+
+static struct rio_driver tsi57x_driver = {
+	.name = "tsi57x",
+	.id_table = tsi57x_id_table,
+	.probe = tsi57x_probe,
+	.remove = tsi57x_remove,
+};
+
+static int __init tsi57x_init(void)
+{
+	return rio_register_driver(&tsi57x_driver);
+}
+
+static void __exit tsi57x_exit(void)
+{
+	rio_unregister_driver(&tsi57x_driver);
+}
+
+device_initcall(tsi57x_init);
+module_exit(tsi57x_exit);
+
+MODULE_DESCRIPTION("IDT Tsi57x Serial RapidIO switch family driver");
+MODULE_AUTHOR("Integrated Device Technology, Inc.");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/88pm8607.c linux-libre-3.11-rc7-gnu/drivers/regulator/88pm8607.c
--- linux-libre-3.10-gnu/drivers/regulator/88pm8607.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/88pm8607.c	2013-08-25 20:43:22.000000000 -0400
@@ -406,7 +406,6 @@ static int pm8607_regulator_remove(struc
 {
 	struct pm8607_regulator_info *info = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(info->regulator);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/ab8500.c linux-libre-3.11-rc7-gnu/drivers/regulator/ab8500.c
--- linux-libre-3.10-gnu/drivers/regulator/ab8500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/ab8500.c	2013-08-25 20:43:22.000000000 -0400
@@ -719,6 +719,7 @@ static struct ab8500_regulator_info
 			.n_voltages	= ARRAY_SIZE(ldo_vauxn_voltages),
 			.volt_table	= ldo_vauxn_voltages,
 			.enable_time	= 200,
+			.supply_name    = "vin",
 		},
 		.load_lp_uA		= 5000,
 		.update_bank		= 0x04,
@@ -741,6 +742,7 @@ static struct ab8500_regulator_info
 			.n_voltages	= ARRAY_SIZE(ldo_vauxn_voltages),
 			.volt_table	= ldo_vauxn_voltages,
 			.enable_time	= 200,
+			.supply_name    = "vin",
 		},
 		.load_lp_uA		= 5000,
 		.update_bank		= 0x04,
@@ -763,6 +765,7 @@ static struct ab8500_regulator_info
 			.n_voltages	= ARRAY_SIZE(ldo_vaux3_voltages),
 			.volt_table	= ldo_vaux3_voltages,
 			.enable_time	= 450,
+			.supply_name    = "vin",
 		},
 		.load_lp_uA		= 5000,
 		.update_bank		= 0x04,
@@ -2901,7 +2904,7 @@ static struct of_regulator_match ab8500_
 	{ .name	= "ab8500_ldo_tvout",   .driver_data = (void *) AB8500_LDO_TVOUT, },
 	{ .name = "ab8500_ldo_audio",   .driver_data = (void *) AB8500_LDO_AUDIO, },
 	{ .name	= "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
-	{ .name	= "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
+	{ .name	= "ab8500_ldo_anamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
 	{ .name	= "ab8500_ldo_dmic",    .driver_data = (void *) AB8500_LDO_DMIC, },
 	{ .name	= "ab8500_ldo_ana",     .driver_data = (void *) AB8500_LDO_ANA, },
 };
@@ -2917,7 +2920,7 @@ static struct of_regulator_match ab8505_
 	{ .name	= "ab8500_ldo_adc",	.driver_data = (void *) AB8505_LDO_ADC, },
 	{ .name = "ab8500_ldo_audio",   .driver_data = (void *) AB8505_LDO_AUDIO, },
 	{ .name	= "ab8500_ldo_anamic1", .driver_data = (void *) AB8505_LDO_ANAMIC1, },
-	{ .name	= "ab8500_ldo_amamic2", .driver_data = (void *) AB8505_LDO_ANAMIC2, },
+	{ .name	= "ab8500_ldo_anamic2", .driver_data = (void *) AB8505_LDO_ANAMIC2, },
 	{ .name	= "ab8500_ldo_aux8",    .driver_data = (void *) AB8505_LDO_AUX8, },
 	{ .name	= "ab8500_ldo_ana",     .driver_data = (void *) AB8505_LDO_ANA, },
 };
@@ -2933,7 +2936,7 @@ static struct of_regulator_match ab8540_
 	{ .name	= "ab8500_ldo_tvout",   .driver_data = (void *) AB8540_LDO_TVOUT, },
 	{ .name = "ab8500_ldo_audio",   .driver_data = (void *) AB8540_LDO_AUDIO, },
 	{ .name	= "ab8500_ldo_anamic1", .driver_data = (void *) AB8540_LDO_ANAMIC1, },
-	{ .name	= "ab8500_ldo_amamic2", .driver_data = (void *) AB8540_LDO_ANAMIC2, },
+	{ .name	= "ab8500_ldo_anamic2", .driver_data = (void *) AB8540_LDO_ANAMIC2, },
 	{ .name	= "ab8500_ldo_dmic",    .driver_data = (void *) AB8540_LDO_DMIC, },
 	{ .name	= "ab8500_ldo_ana",     .driver_data = (void *) AB8540_LDO_ANA, },
 	{ .name = "ab8500_ldo_sdio",    .driver_data = (void *) AB8540_LDO_SDIO, },
@@ -2948,7 +2951,7 @@ static struct of_regulator_match ab9540_
 	{ .name	= "ab8500_ldo_tvout",   .driver_data = (void *) AB9540_LDO_TVOUT, },
 	{ .name = "ab8500_ldo_audio",   .driver_data = (void *) AB9540_LDO_AUDIO, },
 	{ .name	= "ab8500_ldo_anamic1", .driver_data = (void *) AB9540_LDO_ANAMIC1, },
-	{ .name	= "ab8500_ldo_amamic2", .driver_data = (void *) AB9540_LDO_ANAMIC2, },
+	{ .name	= "ab8500_ldo_anamic2", .driver_data = (void *) AB9540_LDO_ANAMIC2, },
 	{ .name	= "ab8500_ldo_dmic",    .driver_data = (void *) AB9540_LDO_DMIC, },
 	{ .name	= "ab8500_ldo_ana",     .driver_data = (void *) AB9540_LDO_ANA, },
 };
@@ -3156,22 +3159,12 @@ static int ab8500_regulator_probe(struct
 			return err;
 	}
 
-	if (!is_ab8505(ab8500)) {
-		/* register external regulators (before Vaux1, 2 and 3) */
-		err = ab8500_ext_regulator_init(pdev);
-		if (err)
-			return err;
-	}
-
 	/* register all regulators */
 	for (i = 0; i < abx500_regulator.info_size; i++) {
 		err = ab8500_regulator_register(pdev, &pdata->regulator[i],
 						i, NULL);
-		if (err < 0) {
-			if (!is_ab8505(ab8500))
-				ab8500_ext_regulator_exit(pdev);
+		if (err < 0)
 			return err;
-		}
 	}
 
 	return 0;
@@ -3180,7 +3173,6 @@ static int ab8500_regulator_probe(struct
 static int ab8500_regulator_remove(struct platform_device *pdev)
 {
 	int i, err;
-	struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
 
 	for (i = 0; i < abx500_regulator.info_size; i++) {
 		struct ab8500_regulator_info *info = NULL;
@@ -3192,10 +3184,6 @@ static int ab8500_regulator_remove(struc
 		regulator_unregister(info->regulator);
 	}
 
-	/* remove external regulators (after Vaux1, 2 and 3) */
-	if (!is_ab8505(ab8500))
-		ab8500_ext_regulator_exit(pdev);
-
 	/* remove regulator debug */
 	err = ab8500_regulator_debug_exit(pdev);
 	if (err)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/ab8500-ext.c linux-libre-3.11-rc7-gnu/drivers/regulator/ab8500-ext.c
--- linux-libre-3.10-gnu/drivers/regulator/ab8500-ext.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/ab8500-ext.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,9 +16,11 @@
 #include <linux/kernel.h>
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/mfd/abx500.h>
 #include <linux/mfd/abx500/ab8500.h>
 #include <linux/regulator/ab8500.h>
@@ -229,6 +231,28 @@ static unsigned int ab8500_ext_regulator
 	return ret;
 }
 
+static int ab8500_ext_set_voltage(struct regulator_dev *rdev, int min_uV,
+				  int max_uV, unsigned *selector)
+{
+	struct regulation_constraints *regu_constraints = rdev->constraints;
+
+	if (!regu_constraints) {
+		dev_err(rdev_get_dev(rdev), "No regulator constraints\n");
+		return -EINVAL;
+	}
+
+	if (regu_constraints->min_uV == min_uV &&
+	    regu_constraints->max_uV == max_uV)
+		return 0;
+
+	dev_err(rdev_get_dev(rdev),
+		"Requested min %duV max %duV != constrained min %duV max %duV\n",
+		min_uV, max_uV,
+		regu_constraints->min_uV, regu_constraints->max_uV);
+
+	return -EINVAL;
+}
+
 static int ab8500_ext_list_voltage(struct regulator_dev *rdev,
 				   unsigned selector)
 {
@@ -252,6 +276,7 @@ static struct regulator_ops ab8500_ext_r
 	.is_enabled		= ab8500_ext_regulator_is_enabled,
 	.set_mode		= ab8500_ext_regulator_set_mode,
 	.get_mode		= ab8500_ext_regulator_get_mode,
+	.set_voltage		= ab8500_ext_set_voltage,
 	.list_voltage		= ab8500_ext_list_voltage,
 };
 
@@ -310,18 +335,37 @@ static struct ab8500_ext_regulator_info
 	},
 };
 
-int ab8500_ext_regulator_init(struct platform_device *pdev)
+static struct of_regulator_match ab8500_ext_regulator_match[] = {
+	{ .name = "ab8500_ext1", .driver_data = (void *) AB8500_EXT_SUPPLY1, },
+	{ .name = "ab8500_ext2", .driver_data = (void *) AB8500_EXT_SUPPLY2, },
+	{ .name = "ab8500_ext3", .driver_data = (void *) AB8500_EXT_SUPPLY3, },
+};
+
+static int ab8500_ext_regulator_probe(struct platform_device *pdev)
 {
 	struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
 	struct ab8500_platform_data *ppdata;
 	struct ab8500_regulator_platform_data *pdata;
+	struct device_node *np = pdev->dev.of_node;
 	struct regulator_config config = { };
 	int i, err;
 
+	if (np) {
+		err = of_regulator_match(&pdev->dev, np,
+					 ab8500_ext_regulator_match,
+					 ARRAY_SIZE(ab8500_ext_regulator_match));
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"Error parsing regulator init data: %d\n", err);
+			return err;
+		}
+	}
+
 	if (!ab8500) {
 		dev_err(&pdev->dev, "null mfd parent\n");
 		return -EINVAL;
 	}
+
 	ppdata = dev_get_platdata(ab8500->dev);
 	if (!ppdata) {
 		dev_err(&pdev->dev, "null parent pdata\n");
@@ -362,8 +406,11 @@ int ab8500_ext_regulator_init(struct pla
 			pdata->ext_regulator[i].driver_data;
 
 		config.dev = &pdev->dev;
-		config.init_data = &pdata->ext_regulator[i];
 		config.driver_data = info;
+		config.of_node = ab8500_ext_regulator_match[i].of_node;
+		config.init_data = (np) ?
+			ab8500_ext_regulator_match[i].init_data :
+			&pdata->ext_regulator[i];
 
 		/* register regulator with framework */
 		info->rdev = regulator_register(&info->desc, &config);
@@ -386,7 +433,7 @@ int ab8500_ext_regulator_init(struct pla
 	return 0;
 }
 
-void ab8500_ext_regulator_exit(struct platform_device *pdev)
+static int ab8500_ext_regulator_remove(struct platform_device *pdev)
 {
 	int i;
 
@@ -399,8 +446,37 @@ void ab8500_ext_regulator_exit(struct pl
 
 		regulator_unregister(info->rdev);
 	}
+
+	return 0;
 }
 
+static struct platform_driver ab8500_ext_regulator_driver = {
+	.probe = ab8500_ext_regulator_probe,
+	.remove = ab8500_ext_regulator_remove,
+	.driver         = {
+		.name   = "ab8500-ext-regulator",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init ab8500_ext_regulator_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&ab8500_ext_regulator_driver);
+	if (ret)
+		pr_err("Failed to register ab8500 ext regulator: %d\n", ret);
+
+	return ret;
+}
+subsys_initcall(ab8500_ext_regulator_init);
+
+static void __exit ab8500_ext_regulator_exit(void)
+{
+	platform_driver_unregister(&ab8500_ext_regulator_driver);
+}
+module_exit(ab8500_ext_regulator_exit);
+
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
 MODULE_DESCRIPTION("AB8500 external regulator driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/core.c linux-libre-3.11-rc7-gnu/drivers/regulator/core.c
--- linux-libre-3.10-gnu/drivers/regulator/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -2138,6 +2138,21 @@ int regulator_list_voltage(struct regula
 EXPORT_SYMBOL_GPL(regulator_list_voltage);
 
 /**
+ * regulator_get_linear_step - return the voltage step size between VSEL values
+ * @regulator: regulator source
+ *
+ * Returns the voltage step size between VSEL values for linear
+ * regulators, or return 0 if the regulator isn't a linear regulator.
+ */
+unsigned int regulator_get_linear_step(struct regulator *regulator)
+{
+	struct regulator_dev *rdev = regulator->rdev;
+
+	return rdev->desc->uV_step;
+}
+EXPORT_SYMBOL_GPL(regulator_get_linear_step);
+
+/**
  * regulator_is_supported_voltage - check if a voltage range can be supported
  *
  * @regulator: Regulator to check.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/isl6271a-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/isl6271a-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/isl6271a-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/isl6271a-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -130,7 +130,7 @@ static int isl6271a_probe(struct i2c_cli
 		if (i == 0)
 			config.init_data = init_data;
 		else
-			config.init_data = 0;
+			config.init_data = NULL;
 		config.driver_data = pmic;
 
 		pmic->rdev[i] = regulator_register(&isl_rd[i], &config);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/Kconfig linux-libre-3.11-rc7-gnu/drivers/regulator/Kconfig
--- linux-libre-3.10-gnu/drivers/regulator/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -250,6 +250,15 @@ config REGULATOR_MAX77686
 	  via I2C bus. The provided regulator is suitable for
 	  Exynos-4 chips to control VARM and VINT voltages.
 
+config REGULATOR_MAX77693
+	tristate "Maxim MAX77693 regulator"
+	depends on MFD_MAX77693
+	help
+	  This driver controls a Maxim 77693 regulator via I2C bus.
+	  The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2'
+	  and one current regulator 'CHARGER'. This is suitable for
+	  Exynos-4x12 chips.
+
 config REGULATOR_PCAP
 	tristate "Motorola PCAP2 regulator driver"
 	depends on EZX_PCAP
@@ -472,6 +481,16 @@ config REGULATOR_TWL4030
 	  This driver supports the voltage regulators provided by
 	  this family of companion chips.
 
+config REGULATOR_TI_ABB
+	bool "TI Adaptive Body Bias on-chip LDO"
+	depends on ARCH_OMAP
+	help
+	  Select this option to support Texas Instruments' on-chip Adaptive Body
+	  Bias (ABB) LDO regulators. It is recommended that this option be
+	  enabled on required TI SoC. Certain Operating Performance Points
+	  on TI SoCs may be unstable without enabling this as it provides
+	  device specific optimized bias to allow/optimize functionality.
+
 config REGULATOR_VEXPRESS
 	tristate "Versatile Express regulators"
 	depends on VEXPRESS_CONFIG
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/lp3971.c linux-libre-3.11-rc7-gnu/drivers/regulator/lp3971.c
--- linux-libre-3.10-gnu/drivers/regulator/lp3971.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/lp3971.c	2013-08-25 20:43:22.000000000 -0400
@@ -434,7 +434,7 @@ static int lp3971_i2c_probe(struct i2c_c
 		return -ENODEV;
 	}
 
-	lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
+	lp3971 = devm_kzalloc(&i2c->dev, sizeof(struct lp3971), GFP_KERNEL);
 	if (lp3971 == NULL)
 		return -ENOMEM;
 
@@ -449,19 +449,15 @@ static int lp3971_i2c_probe(struct i2c_c
 		ret = -ENODEV;
 	if (ret < 0) {
 		dev_err(&i2c->dev, "failed to detect device\n");
-		goto err_detect;
+		return ret;
 	}
 
 	ret = setup_regulators(lp3971, pdata);
 	if (ret < 0)
-		goto err_detect;
+		return ret;
 
 	i2c_set_clientdata(i2c, lp3971);
 	return 0;
-
-err_detect:
-	kfree(lp3971);
-	return ret;
 }
 
 static int lp3971_i2c_remove(struct i2c_client *i2c)
@@ -473,7 +469,6 @@ static int lp3971_i2c_remove(struct i2c_
 		regulator_unregister(lp3971->rdev[i]);
 
 	kfree(lp3971->rdev);
-	kfree(lp3971);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/lp3972.c linux-libre-3.11-rc7-gnu/drivers/regulator/lp3972.c
--- linux-libre-3.10-gnu/drivers/regulator/lp3972.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/lp3972.c	2013-08-25 20:43:22.000000000 -0400
@@ -528,7 +528,7 @@ static int lp3972_i2c_probe(struct i2c_c
 		return -ENODEV;
 	}
 
-	lp3972 = kzalloc(sizeof(struct lp3972), GFP_KERNEL);
+	lp3972 = devm_kzalloc(&i2c->dev, sizeof(struct lp3972), GFP_KERNEL);
 	if (!lp3972)
 		return -ENOMEM;
 
@@ -546,19 +546,15 @@ static int lp3972_i2c_probe(struct i2c_c
 	}
 	if (ret < 0) {
 		dev_err(&i2c->dev, "failed to detect device. ret = %d\n", ret);
-		goto err_detect;
+		return ret;
 	}
 
 	ret = setup_regulators(lp3972, pdata);
 	if (ret < 0)
-		goto err_detect;
+		return ret;
 
 	i2c_set_clientdata(i2c, lp3972);
 	return 0;
-
-err_detect:
-	kfree(lp3972);
-	return ret;
 }
 
 static int lp3972_i2c_remove(struct i2c_client *i2c)
@@ -569,7 +565,6 @@ static int lp3972_i2c_remove(struct i2c_
 	for (i = 0; i < lp3972->num_regulators; i++)
 		regulator_unregister(lp3972->rdev[i]);
 	kfree(lp3972->rdev);
-	kfree(lp3972);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/lp872x.c linux-libre-3.11-rc7-gnu/drivers/regulator/lp872x.c
--- linux-libre-3.10-gnu/drivers/regulator/lp872x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/lp872x.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,9 @@
 #include <linux/regulator/lp872x.h>
 #include <linux/regulator/driver.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/of_regulator.h>
 
 /* Registers : LP8720/8725 shared */
 #define LP872X_GENERAL_CFG		0x00
@@ -723,8 +726,8 @@ static int lp872x_init_dvs(struct lp872x
 
 	gpio = dvs->gpio;
 	if (!gpio_is_valid(gpio)) {
-		dev_err(lp->dev, "invalid gpio: %d\n", gpio);
-		return -EINVAL;
+		dev_warn(lp->dev, "invalid gpio: %d\n", gpio);
+		goto set_default_dvs_mode;
 	}
 
 	pinstate = dvs->init_state;
@@ -829,6 +832,103 @@ static const struct regmap_config lp872x
 	.max_register = MAX_REGISTERS,
 };
 
+#ifdef CONFIG_OF
+
+#define LP872X_VALID_OPMODE	(REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL)
+
+static struct of_regulator_match lp8720_matches[] = {
+	{ .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1, },
+	{ .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2, },
+	{ .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3, },
+	{ .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4, },
+	{ .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5, },
+	{ .name = "buck", .driver_data = (void *)LP8720_ID_BUCK, },
+};
+
+static struct of_regulator_match lp8725_matches[] = {
+	{ .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1, },
+	{ .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2, },
+	{ .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3, },
+	{ .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4, },
+	{ .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5, },
+	{ .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1, },
+	{ .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2, },
+	{ .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1, },
+	{ .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2, },
+};
+
+static struct lp872x_platform_data
+*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which)
+{
+	struct device_node *np = dev->of_node;
+	struct lp872x_platform_data *pdata;
+	struct of_regulator_match *match;
+	struct regulator_init_data *d;
+	int num_matches;
+	int count;
+	int i;
+	u8 dvs_state;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		goto out;
+
+	of_property_read_u8(np, "ti,general-config", &pdata->general_config);
+	if (of_find_property(np, "ti,update-config", NULL))
+		pdata->update_config = true;
+
+	pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL);
+	if (!pdata->dvs)
+		goto out;
+
+	pdata->dvs->gpio = of_get_named_gpio(np, "ti,dvs-gpio", 0);
+	of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel);
+	of_property_read_u8(np, "ti,dvs-state", &dvs_state);
+	pdata->dvs->init_state = dvs_state ? DVS_HIGH : DVS_LOW;
+
+	if (of_get_child_count(np) == 0)
+		goto out;
+
+	switch (which) {
+	case LP8720:
+		match = lp8720_matches;
+		num_matches = ARRAY_SIZE(lp8720_matches);
+		break;
+	case LP8725:
+		match = lp8725_matches;
+		num_matches = ARRAY_SIZE(lp8725_matches);
+		break;
+	default:
+		goto out;
+	}
+
+	count = of_regulator_match(dev, np, match, num_matches);
+	if (count <= 0)
+		goto out;
+
+	for (i = 0; i < num_matches; i++) {
+		pdata->regulator_data[i].id = (int)match[i].driver_data;
+		pdata->regulator_data[i].init_data = match[i].init_data;
+
+		/* Operation mode configuration for buck/buck1/buck2 */
+		if (strncmp(match[i].name, "buck", 4))
+			continue;
+
+		d = pdata->regulator_data[i].init_data;
+		d->constraints.valid_modes_mask |= LP872X_VALID_OPMODE;
+		d->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE;
+	}
+out:
+	return pdata;
+}
+#else
+static struct lp872x_platform_data
+*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which)
+{
+	return NULL;
+}
+#endif
+
 static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
 {
 	struct lp872x *lp;
@@ -838,6 +938,10 @@ static int lp872x_probe(struct i2c_clien
 		[LP8725] = LP8725_NUM_REGULATORS,
 	};
 
+	if (cl->dev.of_node)
+		cl->dev.platform_data = lp872x_populate_pdata_from_dt(&cl->dev,
+					      (enum lp872x_id)id->driver_data);
+
 	lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
 	if (!lp)
 		goto err_mem;
@@ -882,6 +986,13 @@ static int lp872x_remove(struct i2c_clie
 	return 0;
 }
 
+static const struct of_device_id lp872x_dt_ids[] = {
+	{ .compatible = "ti,lp8720", },
+	{ .compatible = "ti,lp8725", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, lp872x_dt_ids);
+
 static const struct i2c_device_id lp872x_ids[] = {
 	{"lp8720", LP8720},
 	{"lp8725", LP8725},
@@ -893,6 +1004,7 @@ static struct i2c_driver lp872x_driver =
 	.driver = {
 		.name = "lp872x",
 		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(lp872x_dt_ids),
 	},
 	.probe = lp872x_probe,
 	.remove = lp872x_remove,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/lp8755.c linux-libre-3.11-rc7-gnu/drivers/regulator/lp8755.c
--- linux-libre-3.10-gnu/drivers/regulator/lp8755.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/lp8755.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/regmap.h>
-#include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/lp8788-buck.c linux-libre-3.11-rc7-gnu/drivers/regulator/lp8788-buck.c
--- linux-libre-3.10-gnu/drivers/regulator/lp8788-buck.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/lp8788-buck.c	2013-08-25 20:43:22.000000000 -0400
@@ -533,7 +533,6 @@ static int lp8788_buck_remove(struct pla
 {
 	struct lp8788_buck *buck = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(buck->regulator);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/lp8788-ldo.c linux-libre-3.11-rc7-gnu/drivers/regulator/lp8788-ldo.c
--- linux-libre-3.10-gnu/drivers/regulator/lp8788-ldo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/lp8788-ldo.c	2013-08-25 20:43:22.000000000 -0400
@@ -561,7 +561,6 @@ static int lp8788_dldo_remove(struct pla
 {
 	struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(ldo->regulator);
 
 	return 0;
@@ -622,7 +621,6 @@ static int lp8788_aldo_remove(struct pla
 {
 	struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(ldo->regulator);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/Makefile linux-libre-3.11-rc7-gnu/drivers/regulator/Makefile
--- linux-libre-3.10-gnu/drivers/regulator/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUME
 obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
 obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
 obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
-obj-$(CONFIG_REGULATOR_AB8500)	+= ab8500.o ab8500-ext.o
+obj-$(CONFIG_REGULATOR_AB8500)	+= ab8500-ext.o ab8500.o
 obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
 obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
 obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
@@ -41,6 +41,7 @@ obj-$(CONFIG_REGULATOR_MAX8973) += max89
 obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
 obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
 obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
+obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
 obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
@@ -63,6 +64,7 @@ obj-$(CONFIG_REGULATOR_TPS65910) += tps6
 obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
 obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
+obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/max77686.c linux-libre-3.11-rc7-gnu/drivers/regulator/max77686.c
--- linux-libre-3.10-gnu/drivers/regulator/max77686.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/max77686.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,7 +24,6 @@
 
 #include <linux/kernel.h>
 #include <linux/bug.h>
-#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/max77693.c linux-libre-3.11-rc7-gnu/drivers/regulator/max77693.c
--- linux-libre-3.10-gnu/drivers/regulator/max77693.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/max77693.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,322 @@
+/*
+ * max77693.c - Regulator driver for the Maxim 77693
+ *
+ * Copyright (C) 2013 Samsung Electronics
+ * Jonghwa Lee <jonghwa3.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * This driver is based on max77686.c
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-private.h>
+#include <linux/regulator/of_regulator.h>
+
+#define CHGIN_ILIM_STEP_20mA			20000
+
+struct max77693_pmic_dev {
+	struct device *dev;
+	struct max77693_dev *iodev;
+	int num_regulators;
+	struct regulator_dev **rdev;
+};
+
+/* CHARGER regulator ops */
+/* CHARGER regulator uses two bits for enabling */
+static int max77693_chg_is_enabled(struct regulator_dev *rdev)
+{
+	int ret;
+	u8 val;
+
+	ret = max77693_read_reg(rdev->regmap, rdev->desc->enable_reg, &val);
+	if (ret)
+		return ret;
+
+	return (val & rdev->desc->enable_mask) == rdev->desc->enable_mask;
+}
+
+/*
+ * CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
+ * 0x00, 0x01, 0x2, 0x03	= 60 mA
+ * 0x04 ~ 0x7E			= (60 + (X - 3) * 20) mA
+ */
+static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
+{
+	unsigned int chg_min_uA = rdev->constraints->min_uA;
+	unsigned int chg_max_uA = rdev->constraints->max_uA;
+	u8 reg, sel;
+	unsigned int val;
+	int ret;
+
+	ret = max77693_read_reg(rdev->regmap,
+				MAX77693_CHG_REG_CHG_CNFG_09, &reg);
+	if (ret < 0)
+		return ret;
+
+	sel = reg & CHG_CNFG_09_CHGIN_ILIM_MASK;
+
+	/* the first four codes for charger current are all 60mA */
+	if (sel <= 3)
+		sel = 0;
+	else
+		sel -= 3;
+
+	val = chg_min_uA + CHGIN_ILIM_STEP_20mA * sel;
+	if (val > chg_max_uA)
+		return -EINVAL;
+
+	return val;
+}
+
+static int max77693_chg_set_current_limit(struct regulator_dev *rdev,
+						int min_uA, int max_uA)
+{
+	unsigned int chg_min_uA = rdev->constraints->min_uA;
+	int sel = 0;
+
+	while (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel < min_uA)
+		sel++;
+
+	if (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel > max_uA)
+		return -EINVAL;
+
+	/* the first four codes for charger current are all 60mA */
+	sel += 3;
+
+	return max77693_write_reg(rdev->regmap,
+				MAX77693_CHG_REG_CHG_CNFG_09, sel);
+}
+/* end of CHARGER regulator ops */
+
+static const unsigned int max77693_safeout_table[] = {
+	4850000,
+	4900000,
+	4950000,
+	3300000,
+};
+
+static struct regulator_ops max77693_safeout_ops = {
+	.list_voltage		= regulator_list_voltage_table,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+};
+
+static struct regulator_ops max77693_charger_ops = {
+	.is_enabled		= max77693_chg_is_enabled,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_current_limit	= max77693_chg_get_current_limit,
+	.set_current_limit	= max77693_chg_set_current_limit,
+};
+
+#define regulator_desc_esafeout(_num)	{			\
+	.name		= "ESAFEOUT"#_num,			\
+	.id		= MAX77693_ESAFEOUT##_num,		\
+	.n_voltages	= 4,					\
+	.ops		= &max77693_safeout_ops,		\
+	.type		= REGULATOR_VOLTAGE,			\
+	.volt_table	= max77693_safeout_table,		\
+	.vsel_reg	= MAX77693_CHG_REG_SAFEOUT_CTRL,	\
+	.vsel_mask	= SAFEOUT_CTRL_SAFEOUT##_num##_MASK,	\
+	.enable_reg	= MAX77693_CHG_REG_SAFEOUT_CTRL,	\
+	.enable_mask	= SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK ,	\
+}
+
+static struct regulator_desc regulators[] = {
+	regulator_desc_esafeout(1),
+	regulator_desc_esafeout(2),
+	{
+		.name = "CHARGER",
+		.id = MAX77693_CHARGER,
+		.ops = &max77693_charger_ops,
+		.type = REGULATOR_CURRENT,
+		.owner = THIS_MODULE,
+		.enable_reg = MAX77693_CHG_REG_CHG_CNFG_00,
+		.enable_mask = CHG_CNFG_00_CHG_MASK |
+				CHG_CNFG_00_BUCK_MASK,
+	},
+};
+
+#ifdef CONFIG_OF
+static int max77693_pmic_dt_parse_rdata(struct device *dev,
+					struct max77693_regulator_data **rdata)
+{
+	struct device_node *np;
+	struct of_regulator_match *rmatch;
+	struct max77693_regulator_data *tmp;
+	int i, matched = 0;
+
+	np = of_find_node_by_name(dev->parent->of_node, "regulators");
+	if (!np)
+		return -EINVAL;
+
+	rmatch = devm_kzalloc(dev,
+		 sizeof(*rmatch) * ARRAY_SIZE(regulators), GFP_KERNEL);
+	if (!rmatch)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(regulators); i++)
+		rmatch[i].name = regulators[i].name;
+
+	matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(regulators));
+	if (matched <= 0)
+		return matched;
+	*rdata = devm_kzalloc(dev, sizeof(**rdata) * matched, GFP_KERNEL);
+	if (!(*rdata))
+		return -ENOMEM;
+
+	tmp = *rdata;
+
+	for (i = 0; i < matched; i++) {
+		tmp->initdata = rmatch[i].init_data;
+		tmp->of_node = rmatch[i].of_node;
+		tmp->id = regulators[i].id;
+		tmp++;
+	}
+
+	return matched;
+}
+#else
+static int max77693_pmic_dt_parse_rdata(struct device *dev,
+					struct max77693_regulator_data **rdata)
+{
+	return 0;
+}
+#endif /* CONFIG_OF */
+
+static int max77693_pmic_init_rdata(struct device *dev,
+				    struct max77693_regulator_data **rdata)
+{
+	struct max77693_platform_data *pdata;
+	int num_regulators = 0;
+
+	pdata = dev_get_platdata(dev->parent);
+	if (pdata) {
+		*rdata = pdata->regulators;
+		num_regulators = pdata->num_regulators;
+	}
+
+	if (!(*rdata) && dev->parent->of_node)
+		num_regulators = max77693_pmic_dt_parse_rdata(dev, rdata);
+
+	return num_regulators;
+}
+
+static int max77693_pmic_probe(struct platform_device *pdev)
+{
+	struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+	struct max77693_pmic_dev *max77693_pmic;
+	struct max77693_regulator_data *rdata = NULL;
+	int num_rdata, i, ret;
+	struct regulator_config config;
+
+	num_rdata = max77693_pmic_init_rdata(&pdev->dev, &rdata);
+	if (!rdata || num_rdata <= 0) {
+		dev_err(&pdev->dev, "No init data supplied.\n");
+		return -ENODEV;
+	}
+
+	max77693_pmic = devm_kzalloc(&pdev->dev,
+				sizeof(struct max77693_pmic_dev),
+				GFP_KERNEL);
+	if (!max77693_pmic)
+		return -ENOMEM;
+
+	max77693_pmic->rdev = devm_kzalloc(&pdev->dev,
+				sizeof(struct regulator_dev *) * num_rdata,
+				GFP_KERNEL);
+	if (!max77693_pmic->rdev)
+		return -ENOMEM;
+
+	max77693_pmic->dev = &pdev->dev;
+	max77693_pmic->iodev = iodev;
+	max77693_pmic->num_regulators = num_rdata;
+
+	config.dev = &pdev->dev;
+	config.regmap = iodev->regmap;
+	config.driver_data = max77693_pmic;
+	platform_set_drvdata(pdev, max77693_pmic);
+
+	for (i = 0; i < max77693_pmic->num_regulators; i++) {
+		int id = rdata[i].id;
+
+		config.init_data = rdata[i].initdata;
+		config.of_node = rdata[i].of_node;
+
+		max77693_pmic->rdev[i] = regulator_register(&regulators[id],
+							    &config);
+		if (IS_ERR(max77693_pmic->rdev[i])) {
+			ret = PTR_ERR(max77693_pmic->rdev[i]);
+			dev_err(max77693_pmic->dev,
+				"Failed to initialize regulator-%d\n", id);
+			max77693_pmic->rdev[i] = NULL;
+			goto err;
+		}
+	}
+
+	return 0;
+ err:
+	while (--i >= 0)
+		regulator_unregister(max77693_pmic->rdev[i]);
+
+	return ret;
+}
+
+static int max77693_pmic_remove(struct platform_device *pdev)
+{
+	struct max77693_pmic_dev *max77693_pmic = platform_get_drvdata(pdev);
+	struct regulator_dev **rdev = max77693_pmic->rdev;
+	int i;
+
+	for (i = 0; i < max77693_pmic->num_regulators; i++)
+		if (rdev[i])
+			regulator_unregister(rdev[i]);
+
+	return 0;
+}
+
+static const struct platform_device_id max77693_pmic_id[] = {
+	{"max77693-pmic", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(platform, max77693_pmic_id);
+
+static struct platform_driver max77693_pmic_driver = {
+	.driver = {
+		   .name = "max77693-pmic",
+		   .owner = THIS_MODULE,
+		   },
+	.probe = max77693_pmic_probe,
+	.remove = max77693_pmic_remove,
+	.id_table = max77693_pmic_id,
+};
+
+module_platform_driver(max77693_pmic_driver);
+
+MODULE_DESCRIPTION("MAXIM MAX77693 regulator driver");
+MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/max8925-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/max8925-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/max8925-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/max8925-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -327,7 +327,6 @@ static int max8925_regulator_remove(stru
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(rdev);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/max8973-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/max8973-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/max8973-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/max8973-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,10 +26,12 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/max8973-regulator.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
@@ -100,6 +102,7 @@ struct max8973_chip {
 	int curr_vout_reg;
 	int curr_gpio_val;
 	bool valid_dvs_gpio;
+	struct regulator_ops ops;
 };
 
 /*
@@ -240,7 +243,7 @@ static unsigned int max8973_dcdc_get_mod
 		REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
 }
 
-static struct regulator_ops max8973_dcdc_ops = {
+static const struct regulator_ops max8973_dcdc_ops = {
 	.get_voltage_sel	= max8973_dcdc_get_voltage_sel,
 	.set_voltage_sel	= max8973_dcdc_set_voltage_sel,
 	.list_voltage		= regulator_list_voltage_linear,
@@ -369,7 +372,8 @@ static int max8973_probe(struct i2c_clie
 	int ret;
 
 	pdata = client->dev.platform_data;
-	if (!pdata) {
+
+	if (!pdata && !client->dev.of_node) {
 		dev_err(&client->dev, "No Platform data");
 		return -EIO;
 	}
@@ -388,30 +392,36 @@ static int max8973_probe(struct i2c_clie
 	}
 
 	i2c_set_clientdata(client, max);
+	max->ops = max8973_dcdc_ops;
 	max->dev = &client->dev;
 	max->desc.name = id->name;
 	max->desc.id = 0;
-	max->desc.ops = &max8973_dcdc_ops;
+	max->desc.ops = &max->ops;
 	max->desc.type = REGULATOR_VOLTAGE;
 	max->desc.owner = THIS_MODULE;
 	max->desc.min_uV = MAX8973_MIN_VOLATGE;
 	max->desc.uV_step = MAX8973_VOLATGE_STEP;
 	max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE;
 
-	if (!pdata->enable_ext_control) {
+	if (!pdata || !pdata->enable_ext_control) {
 		max->desc.enable_reg = MAX8973_VOUT;
 		max->desc.enable_mask = MAX8973_VOUT_ENABLE;
-		max8973_dcdc_ops.enable = regulator_enable_regmap;
-		max8973_dcdc_ops.disable = regulator_disable_regmap;
-		max8973_dcdc_ops.is_enabled = regulator_is_enabled_regmap;
+		max->ops.enable = regulator_enable_regmap;
+		max->ops.disable = regulator_disable_regmap;
+		max->ops.is_enabled = regulator_is_enabled_regmap;
+	}
+
+	if (pdata) {
+		max->dvs_gpio = pdata->dvs_gpio;
+		max->enable_external_control = pdata->enable_ext_control;
+		max->curr_gpio_val = pdata->dvs_def_state;
+		max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
+	} else {
+		max->dvs_gpio = -EINVAL;
+		max->curr_vout_reg = MAX8973_VOUT;
 	}
 
-	max->enable_external_control = pdata->enable_ext_control;
-	max->dvs_gpio = pdata->dvs_gpio;
-	max->curr_gpio_val = pdata->dvs_def_state;
-	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
 	max->lru_index[0] = max->curr_vout_reg;
-	max->valid_dvs_gpio = false;
 
 	if (gpio_is_valid(max->dvs_gpio)) {
 		int gpio_flags;
@@ -437,16 +447,21 @@ static int max8973_probe(struct i2c_clie
 			max->lru_index[i] = i;
 		max->lru_index[0] = max->curr_vout_reg;
 		max->lru_index[max->curr_vout_reg] = 0;
+	} else {
+		max->valid_dvs_gpio = false;
 	}
 
-	ret = max8973_init_dcdc(max, pdata);
-	if (ret < 0) {
-		dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
-		return ret;
+	if (pdata) {
+		ret = max8973_init_dcdc(max, pdata);
+		if (ret < 0) {
+			dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
+			return ret;
+		}
 	}
 
 	config.dev = &client->dev;
-	config.init_data = pdata->reg_init_data;
+	config.init_data = pdata ? pdata->reg_init_data :
+		of_get_regulator_init_data(&client->dev, client->dev.of_node);
 	config.driver_data = max;
 	config.of_node = client->dev.of_node;
 	config.regmap = max->regmap;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/max8998.c linux-libre-3.11-rc7-gnu/drivers/regulator/max8998.c
--- linux-libre-3.10-gnu/drivers/regulator/max8998.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/max8998.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,8 +28,11 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/mfd/max8998.h>
 #include <linux/mfd/max8998-private.h>
 
@@ -589,13 +592,13 @@ static struct regulator_desc regulators[
 		.type		= REGULATOR_VOLTAGE,
 		.owner		= THIS_MODULE,
 	}, {
-		.name		= "EN32KHz AP",
+		.name		= "EN32KHz-AP",
 		.id		= MAX8998_EN32KHZ_AP,
 		.ops		= &max8998_others_ops,
 		.type		= REGULATOR_VOLTAGE,
 		.owner		= THIS_MODULE,
 	}, {
-		.name		= "EN32KHz CP",
+		.name		= "EN32KHz-CP",
 		.id		= MAX8998_EN32KHZ_CP,
 		.ops		= &max8998_others_ops,
 		.type		= REGULATOR_VOLTAGE,
@@ -621,21 +624,140 @@ static struct regulator_desc regulators[
 	}
 };
 
+static int max8998_pmic_dt_parse_dvs_gpio(struct max8998_dev *iodev,
+			struct max8998_platform_data *pdata,
+			struct device_node *pmic_np)
+{
+	int gpio;
+
+	gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 0);
+	if (!gpio_is_valid(gpio)) {
+		dev_err(iodev->dev, "invalid buck1 gpio[0]: %d\n", gpio);
+		return -EINVAL;
+	}
+	pdata->buck1_set1 = gpio;
+
+	gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 1);
+	if (!gpio_is_valid(gpio)) {
+		dev_err(iodev->dev, "invalid buck1 gpio[1]: %d\n", gpio);
+		return -EINVAL;
+	}
+	pdata->buck1_set2 = gpio;
+
+	gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck2-dvs-gpio", 0);
+	if (!gpio_is_valid(gpio)) {
+		dev_err(iodev->dev, "invalid buck 2 gpio: %d\n", gpio);
+		return -EINVAL;
+	}
+	pdata->buck2_set3 = gpio;
+
+	return 0;
+}
+
+static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
+					struct max8998_platform_data *pdata)
+{
+	struct device_node *pmic_np = iodev->dev->of_node;
+	struct device_node *regulators_np, *reg_np;
+	struct max8998_regulator_data *rdata;
+	unsigned int i;
+	int ret;
+
+	regulators_np = of_get_child_by_name(pmic_np, "regulators");
+	if (!regulators_np) {
+		dev_err(iodev->dev, "could not find regulators sub-node\n");
+		return -EINVAL;
+	}
+
+	/* count the number of regulators to be supported in pmic */
+	pdata->num_regulators = of_get_child_count(regulators_np);
+
+	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
+				pdata->num_regulators, GFP_KERNEL);
+	if (!rdata)
+		return -ENOMEM;
+
+	pdata->regulators = rdata;
+	for (i = 0; i < ARRAY_SIZE(regulators); ++i) {
+		reg_np = of_get_child_by_name(regulators_np,
+							regulators[i].name);
+		if (!reg_np)
+			continue;
+
+		rdata->id = regulators[i].id;
+		rdata->initdata = of_get_regulator_init_data(
+							iodev->dev, reg_np);
+		rdata->reg_node = reg_np;
+		++rdata;
+	}
+	pdata->num_regulators = rdata - pdata->regulators;
+
+	ret = max8998_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
+	if (ret)
+		return -EINVAL;
+
+	if (of_find_property(pmic_np, "max8998,pmic-buck-voltage-lock", NULL))
+		pdata->buck_voltage_lock = true;
+
+	ret = of_property_read_u32(pmic_np,
+					"max8998,pmic-buck1-default-dvs-idx",
+					&pdata->buck1_default_idx);
+	if (!ret && pdata->buck1_default_idx >= 4) {
+		pdata->buck1_default_idx = 0;
+		dev_warn(iodev->dev, "invalid value for default dvs index, using 0 instead\n");
+	}
+
+	ret = of_property_read_u32(pmic_np,
+					"max8998,pmic-buck2-default-dvs-idx",
+					&pdata->buck2_default_idx);
+	if (!ret && pdata->buck2_default_idx >= 2) {
+		pdata->buck2_default_idx = 0;
+		dev_warn(iodev->dev, "invalid value for default dvs index, using 0 instead\n");
+	}
+
+	ret = of_property_read_u32_array(pmic_np,
+					"max8998,pmic-buck1-dvs-voltage",
+					pdata->buck1_voltage,
+					ARRAY_SIZE(pdata->buck1_voltage));
+	if (ret) {
+		dev_err(iodev->dev, "buck1 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_array(pmic_np,
+					"max8998,pmic-buck2-dvs-voltage",
+					pdata->buck2_voltage,
+					ARRAY_SIZE(pdata->buck2_voltage));
+	if (ret) {
+		dev_err(iodev->dev, "buck2 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int max8998_pmic_probe(struct platform_device *pdev)
 {
 	struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
-	struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
+	struct max8998_platform_data *pdata = iodev->pdata;
 	struct regulator_config config = { };
 	struct regulator_dev **rdev;
 	struct max8998_data *max8998;
 	struct i2c_client *i2c;
 	int i, ret, size;
+	unsigned int v;
 
 	if (!pdata) {
 		dev_err(pdev->dev.parent, "No platform init data supplied\n");
 		return -ENODEV;
 	}
 
+	if (IS_ENABLED(CONFIG_OF) && iodev->dev->of_node) {
+		ret = max8998_pmic_dt_parse_pdata(iodev, pdata);
+		if (ret)
+			return ret;
+	}
+
 	max8998 = devm_kzalloc(&pdev->dev, sizeof(struct max8998_data),
 			       GFP_KERNEL);
 	if (!max8998)
@@ -688,53 +810,21 @@ static int max8998_pmic_probe(struct pla
 		gpio_request(pdata->buck1_set2, "MAX8998 BUCK1_SET2");
 		gpio_direction_output(pdata->buck1_set2,
 				      (max8998->buck1_idx >> 1) & 0x1);
-		/* Set predefined value for BUCK1 register 1 */
-		i = 0;
-		while (buck12_voltage_map_desc.min +
-		       buck12_voltage_map_desc.step*i
-		       < pdata->buck1_voltage1)
-			i++;
-		max8998->buck1_vol[0] = i;
-		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i);
-		if (ret)
-			goto err_out;
-
-		/* Set predefined value for BUCK1 register 2 */
-		i = 0;
-		while (buck12_voltage_map_desc.min +
-		       buck12_voltage_map_desc.step*i
-		       < pdata->buck1_voltage2)
-			i++;
-
-		max8998->buck1_vol[1] = i;
-		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i);
-		if (ret)
-			goto err_out;
-
-		/* Set predefined value for BUCK1 register 3 */
-		i = 0;
-		while (buck12_voltage_map_desc.min +
-		       buck12_voltage_map_desc.step*i
-		       < pdata->buck1_voltage3)
-			i++;
-
-		max8998->buck1_vol[2] = i;
-		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i);
-		if (ret)
-			goto err_out;
 
-		/* Set predefined value for BUCK1 register 4 */
-		i = 0;
-		while (buck12_voltage_map_desc.min +
-		       buck12_voltage_map_desc.step*i
-		       < pdata->buck1_voltage4)
-			i++;
-
-		max8998->buck1_vol[3] = i;
-		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i);
-		if (ret)
-			goto err_out;
+		/* Set predefined values for BUCK1 registers */
+		for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) {
+			i = 0;
+			while (buck12_voltage_map_desc.min +
+			       buck12_voltage_map_desc.step*i
+			       < pdata->buck1_voltage[v])
+				i++;
 
+			max8998->buck1_vol[v] = i;
+			ret = max8998_write_reg(i2c,
+					MAX8998_REG_BUCK1_VOLTAGE1 + v, i);
+			if (ret)
+				goto err_out;
+		}
 	}
 
 	if (gpio_is_valid(pdata->buck2_set3)) {
@@ -750,27 +840,20 @@ static int max8998_pmic_probe(struct pla
 		gpio_direction_output(pdata->buck2_set3,
 				      max8998->buck2_idx & 0x1);
 
-		/* BUCK2 register 1 */
-		i = 0;
-		while (buck12_voltage_map_desc.min +
-		       buck12_voltage_map_desc.step*i
-		       < pdata->buck2_voltage1)
-			i++;
-		max8998->buck2_vol[0] = i;
-		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i);
-		if (ret)
-			goto err_out;
+		/* Set predefined values for BUCK2 registers */
+		for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) {
+			i = 0;
+			while (buck12_voltage_map_desc.min +
+			       buck12_voltage_map_desc.step*i
+			       < pdata->buck2_voltage[v])
+				i++;
 
-		/* BUCK2 register 2 */
-		i = 0;
-		while (buck12_voltage_map_desc.min +
-		       buck12_voltage_map_desc.step*i
-		       < pdata->buck2_voltage2)
-			i++;
-		max8998->buck2_vol[1] = i;
-		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i);
-		if (ret)
-			goto err_out;
+			max8998->buck2_vol[v] = i;
+			ret = max8998_write_reg(i2c,
+					MAX8998_REG_BUCK2_VOLTAGE1 + v, i);
+			if (ret)
+				goto err_out;
+		}
 	}
 
 	for (i = 0; i < pdata->num_regulators; i++) {
@@ -788,13 +871,15 @@ static int max8998_pmic_probe(struct pla
 		}
 
 		config.dev = max8998->dev;
+		config.of_node = pdata->regulators[i].reg_node;
 		config.init_data = pdata->regulators[i].initdata;
 		config.driver_data = max8998;
 
 		rdev[i] = regulator_register(&regulators[index], &config);
 		if (IS_ERR(rdev[i])) {
 			ret = PTR_ERR(rdev[i]);
-			dev_err(max8998->dev, "regulator init failed\n");
+			dev_err(max8998->dev, "regulator %s init failed (%d)\n",
+						regulators[index].name, ret);
 			rdev[i] = NULL;
 			goto err;
 		}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/mc13783-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/mc13783-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/mc13783-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/mc13783-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -466,8 +466,6 @@ static int mc13783_regulator_remove(stru
 	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
 	int i;
 
-	platform_set_drvdata(pdev, NULL);
-
 	for (i = 0; i < priv->num_regulators; i++)
 		regulator_unregister(priv->regulators[i]);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/mc13892-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/mc13892-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/mc13892-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/mc13892-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -636,8 +636,6 @@ static int mc13892_regulator_remove(stru
 	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
 	int i;
 
-	platform_set_drvdata(pdev, NULL);
-
 	for (i = 0; i < priv->num_regulators; i++)
 		regulator_unregister(priv->regulators[i]);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/of_regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/of_regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/of_regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/of_regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,6 +61,9 @@ static void of_get_regulation_constraint
 	else /* status change should be possible if not always on. */
 		constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;
 
+	if (of_property_read_bool(np, "regulator-allow-bypass"))
+		constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS;
+
 	ramp_delay = of_get_property(np, "regulator-ramp-delay", NULL);
 	if (ramp_delay)
 		constraints->ramp_delay = be32_to_cpu(*ramp_delay);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/palmas-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/palmas-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/palmas-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/palmas-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -838,6 +838,9 @@ static int palmas_regulators_probe(struc
 				continue;
 			ramp_delay_support = true;
 			break;
+		case PALMAS_REG_SMPS10:
+			if (!PALMAS_PMIC_HAS(palmas, SMPS10_BOOST))
+				continue;
 		}
 
 		if ((id == PALMAS_REG_SMPS6) || (id == PALMAS_REG_SMPS8))
@@ -1051,6 +1054,7 @@ static struct of_device_id of_palmas_mat
 	{ .compatible = "ti,tps65913-pmic", },
 	{ .compatible = "ti,tps65914-pmic", },
 	{ .compatible = "ti,tps80036-pmic", },
+	{ .compatible = "ti,tps659038-pmic", },
 	{ /* end */ }
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/pcap-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/pcap-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/pcap-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/pcap-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -260,7 +260,6 @@ static int pcap_regulator_remove(struct
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
 	regulator_unregister(rdev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/pcf50633-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/pcf50633-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/pcf50633-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/pcf50633-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -106,7 +106,6 @@ static int pcf50633_regulator_remove(str
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(rdev);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/s2mps11.c linux-libre-3.11-rc7-gnu/drivers/regulator/s2mps11.c
--- linux-libre-3.10-gnu/drivers/regulator/s2mps11.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/s2mps11.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,7 +12,6 @@
  */
 
 #include <linux/bug.h>
-#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
@@ -43,7 +42,7 @@ static int get_ramp_delay(int ramp_delay
 {
 	unsigned char cnt = 0;
 
-	ramp_delay /= 6;
+	ramp_delay /= 6250;
 
 	while (true) {
 		ramp_delay = ramp_delay >> 1;
@@ -114,6 +113,7 @@ static struct regulator_ops s2mps11_buck
 	.min_uV		= S2MPS11_BUCK_MIN1,			\
 	.uV_step	= S2MPS11_BUCK_STEP1,			\
 	.n_voltages	= S2MPS11_BUCK_N_VOLTAGES,		\
+	.ramp_delay	= S2MPS11_RAMP_DELAY,			\
 	.vsel_reg	= S2MPS11_REG_B1CTRL2 + (num - 1) * 2,	\
 	.vsel_mask	= S2MPS11_BUCK_VSEL_MASK,		\
 	.enable_reg	= S2MPS11_REG_B1CTRL1 + (num - 1) * 2,	\
@@ -129,6 +129,7 @@ static struct regulator_ops s2mps11_buck
 	.min_uV		= S2MPS11_BUCK_MIN1,			\
 	.uV_step	= S2MPS11_BUCK_STEP1,			\
 	.n_voltages	= S2MPS11_BUCK_N_VOLTAGES,		\
+	.ramp_delay	= S2MPS11_RAMP_DELAY,			\
 	.vsel_reg	= S2MPS11_REG_B5CTRL2,			\
 	.vsel_mask	= S2MPS11_BUCK_VSEL_MASK,		\
 	.enable_reg	= S2MPS11_REG_B5CTRL1,			\
@@ -144,6 +145,7 @@ static struct regulator_ops s2mps11_buck
 	.min_uV		= S2MPS11_BUCK_MIN1,			\
 	.uV_step	= S2MPS11_BUCK_STEP1,			\
 	.n_voltages	= S2MPS11_BUCK_N_VOLTAGES,		\
+	.ramp_delay	= S2MPS11_RAMP_DELAY,			\
 	.vsel_reg	= S2MPS11_REG_B6CTRL2 + (num - 6) * 2,	\
 	.vsel_mask	= S2MPS11_BUCK_VSEL_MASK,		\
 	.enable_reg	= S2MPS11_REG_B6CTRL1 + (num - 6) * 2,	\
@@ -159,6 +161,7 @@ static struct regulator_ops s2mps11_buck
 	.min_uV		= S2MPS11_BUCK_MIN3,			\
 	.uV_step	= S2MPS11_BUCK_STEP3,			\
 	.n_voltages	= S2MPS11_BUCK_N_VOLTAGES,		\
+	.ramp_delay	= S2MPS11_RAMP_DELAY,			\
 	.vsel_reg	= S2MPS11_REG_B9CTRL2,			\
 	.vsel_mask	= S2MPS11_BUCK_VSEL_MASK,		\
 	.enable_reg	= S2MPS11_REG_B9CTRL1,			\
@@ -174,6 +177,7 @@ static struct regulator_ops s2mps11_buck
 	.min_uV		= S2MPS11_BUCK_MIN2,			\
 	.uV_step	= S2MPS11_BUCK_STEP2,			\
 	.n_voltages	= S2MPS11_BUCK_N_VOLTAGES,		\
+	.ramp_delay	= S2MPS11_RAMP_DELAY,			\
 	.vsel_reg	= S2MPS11_REG_B10CTRL2,			\
 	.vsel_mask	= S2MPS11_BUCK_VSEL_MASK,		\
 	.enable_reg	= S2MPS11_REG_B10CTRL1,			\
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/ti-abb-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/ti-abb-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/ti-abb-regulator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/ti-abb-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,910 @@
+/*
+ * Texas Instruments SoC Adaptive Body Bias(ABB) Regulator
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Mike Turquette <mturquette@ti.com>
+ *
+ * Copyright (C) 2012-2013 Texas Instruments, Inc.
+ * Andrii Tseglytskyi <andrii.tseglytskyi@ti.com>
+ * Nishanth Menon <nm@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+/*
+ * ABB LDO operating states:
+ * NOMINAL_OPP:	bypasses the ABB LDO
+ * FAST_OPP:	sets ABB LDO to Forward Body-Bias
+ * SLOW_OPP:	sets ABB LDO to Reverse Body-Bias
+ */
+#define TI_ABB_NOMINAL_OPP	0
+#define TI_ABB_FAST_OPP		1
+#define TI_ABB_SLOW_OPP		3
+
+/**
+ * struct ti_abb_info - ABB information per voltage setting
+ * @opp_sel:	one of TI_ABB macro
+ * @vset:	(optional) vset value that LDOVBB needs to be overriden with.
+ *
+ * Array of per voltage entries organized in the same order as regulator_desc's
+ * volt_table list. (selector is used to index from this array)
+ */
+struct ti_abb_info {
+	u32 opp_sel;
+	u32 vset;
+};
+
+/**
+ * struct ti_abb_reg - Register description for ABB block
+ * @setup_reg:			setup register offset from base
+ * @control_reg:		control register offset from base
+ * @sr2_wtcnt_value_mask:	setup register- sr2_wtcnt_value mask
+ * @fbb_sel_mask:		setup register- FBB sel mask
+ * @rbb_sel_mask:		setup register- RBB sel mask
+ * @sr2_en_mask:		setup register- enable mask
+ * @opp_change_mask:		control register - mask to trigger LDOVBB change
+ * @opp_sel_mask:		control register - mask for mode to operate
+ */
+struct ti_abb_reg {
+	u32 setup_reg;
+	u32 control_reg;
+
+	/* Setup register fields */
+	u32 sr2_wtcnt_value_mask;
+	u32 fbb_sel_mask;
+	u32 rbb_sel_mask;
+	u32 sr2_en_mask;
+
+	/* Control register fields */
+	u32 opp_change_mask;
+	u32 opp_sel_mask;
+};
+
+/**
+ * struct ti_abb - ABB instance data
+ * @rdesc:			regulator descriptor
+ * @clk:			clock(usually sysclk) supplying ABB block
+ * @base:			base address of ABB block
+ * @int_base:			interrupt register base address
+ * @efuse_base:			(optional) efuse base address for ABB modes
+ * @ldo_base:			(optional) LDOVBB vset override base address
+ * @regs:			pointer to struct ti_abb_reg for ABB block
+ * @txdone_mask:		mask on int_base for tranxdone interrupt
+ * @ldovbb_override_mask:	mask to ldo_base for overriding default LDO VBB
+ *				vset with value from efuse
+ * @ldovbb_vset_mask:		mask to ldo_base for providing the VSET override
+ * @info:			array to per voltage ABB configuration
+ * @current_info_idx:		current index to info
+ * @settling_time:		SoC specific settling time for LDO VBB
+ */
+struct ti_abb {
+	struct regulator_desc rdesc;
+	struct clk *clk;
+	void __iomem *base;
+	void __iomem *int_base;
+	void __iomem *efuse_base;
+	void __iomem *ldo_base;
+
+	const struct ti_abb_reg *regs;
+	u32 txdone_mask;
+	u32 ldovbb_override_mask;
+	u32 ldovbb_vset_mask;
+
+	struct ti_abb_info *info;
+	int current_info_idx;
+
+	u32 settling_time;
+};
+
+/**
+ * ti_abb_rmw() - handy wrapper to set specific register bits
+ * @mask:	mask for register field
+ * @value:	value shifted to mask location and written
+ * @offset:	offset of register
+ * @base:	base address
+ *
+ * Return: final register value (may be unused)
+ */
+static inline u32 ti_abb_rmw(u32 mask, u32 value, u32 offset,
+			     void __iomem *base)
+{
+	u32 val;
+
+	val = readl(base + offset);
+	val &= ~mask;
+	val |= (value << __ffs(mask)) & mask;
+	writel(val, base + offset);
+
+	return val;
+}
+
+/**
+ * ti_abb_check_txdone() - handy wrapper to check ABB tranxdone status
+ * @abb:	pointer to the abb instance
+ *
+ * Return: true or false
+ */
+static inline bool ti_abb_check_txdone(const struct ti_abb *abb)
+{
+	return !!(readl(abb->int_base) & abb->txdone_mask);
+}
+
+/**
+ * ti_abb_clear_txdone() - handy wrapper to clear ABB tranxdone status
+ * @abb:	pointer to the abb instance
+ */
+static inline void ti_abb_clear_txdone(const struct ti_abb *abb)
+{
+	writel(abb->txdone_mask, abb->int_base);
+};
+
+/**
+ * ti_abb_wait_tranx() - waits for ABB tranxdone event
+ * @dev:	device
+ * @abb:	pointer to the abb instance
+ *
+ * Return: 0 on success or -ETIMEDOUT if the event is not cleared on time.
+ */
+static int ti_abb_wait_txdone(struct device *dev, struct ti_abb *abb)
+{
+	int timeout = 0;
+	bool status;
+
+	while (timeout++ <= abb->settling_time) {
+		status = ti_abb_check_txdone(abb);
+		if (status)
+			break;
+
+		udelay(1);
+	}
+
+	if (timeout > abb->settling_time) {
+		dev_warn_ratelimited(dev,
+				     "%s:TRANXDONE timeout(%duS) int=0x%08x\n",
+				     __func__, timeout, readl(abb->int_base));
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_abb_clear_all_txdone() - clears ABB tranxdone event
+ * @dev:	device
+ * @abb:	pointer to the abb instance
+ *
+ * Return: 0 on success or -ETIMEDOUT if the event is not cleared on time.
+ */
+static int ti_abb_clear_all_txdone(struct device *dev, const struct ti_abb *abb)
+{
+	int timeout = 0;
+	bool status;
+
+	while (timeout++ <= abb->settling_time) {
+		ti_abb_clear_txdone(abb);
+
+		status = ti_abb_check_txdone(abb);
+		if (!status)
+			break;
+
+		udelay(1);
+	}
+
+	if (timeout > abb->settling_time) {
+		dev_warn_ratelimited(dev,
+				     "%s:TRANXDONE timeout(%duS) int=0x%08x\n",
+				     __func__, timeout, readl(abb->int_base));
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_abb_program_ldovbb() - program LDOVBB register for override value
+ * @dev:	device
+ * @abb:	pointer to the abb instance
+ * @info:	ABB info to program
+ */
+static void ti_abb_program_ldovbb(struct device *dev, const struct ti_abb *abb,
+				  struct ti_abb_info *info)
+{
+	u32 val;
+
+	val = readl(abb->ldo_base);
+	/* clear up previous values */
+	val &= ~(abb->ldovbb_override_mask | abb->ldovbb_vset_mask);
+
+	switch (info->opp_sel) {
+	case TI_ABB_SLOW_OPP:
+	case TI_ABB_FAST_OPP:
+		val |= abb->ldovbb_override_mask;
+		val |= info->vset << __ffs(abb->ldovbb_vset_mask);
+		break;
+	}
+
+	writel(val, abb->ldo_base);
+}
+
+/**
+ * ti_abb_set_opp() - Setup ABB and LDO VBB for required bias
+ * @rdev:	regulator device
+ * @abb:	pointer to the abb instance
+ * @info:	ABB info to program
+ *
+ * Return: 0 on success or appropriate error value when fails
+ */
+static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb,
+			  struct ti_abb_info *info)
+{
+	const struct ti_abb_reg *regs = abb->regs;
+	struct device *dev = &rdev->dev;
+	int ret;
+
+	ret = ti_abb_clear_all_txdone(dev, abb);
+	if (ret)
+		goto out;
+
+	ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, regs->setup_reg,
+		   abb->base);
+
+	switch (info->opp_sel) {
+	case TI_ABB_SLOW_OPP:
+		ti_abb_rmw(regs->rbb_sel_mask, 1, regs->setup_reg, abb->base);
+		break;
+	case TI_ABB_FAST_OPP:
+		ti_abb_rmw(regs->fbb_sel_mask, 1, regs->setup_reg, abb->base);
+		break;
+	}
+
+	/* program next state of ABB ldo */
+	ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, regs->control_reg,
+		   abb->base);
+
+	/* program LDO VBB vset override if needed */
+	if (abb->ldo_base)
+		ti_abb_program_ldovbb(dev, abb, info);
+
+	/* Initiate ABB ldo change */
+	ti_abb_rmw(regs->opp_change_mask, 1, regs->control_reg, abb->base);
+
+	/* Wait for ABB LDO to complete transition to new Bias setting */
+	ret = ti_abb_wait_txdone(dev, abb);
+	if (ret)
+		goto out;
+
+	ret = ti_abb_clear_all_txdone(dev, abb);
+	if (ret)
+		goto out;
+
+out:
+	return ret;
+}
+
+/**
+ * ti_abb_set_voltage_sel() - regulator accessor function to set ABB LDO
+ * @rdev:	regulator device
+ * @sel:	selector to index into required ABB LDO settings (maps to
+ *		regulator descriptor's volt_table)
+ *
+ * Return: 0 on success or appropriate error value when fails
+ */
+static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned sel)
+{
+	const struct regulator_desc *desc = rdev->desc;
+	struct ti_abb *abb = rdev_get_drvdata(rdev);
+	struct device *dev = &rdev->dev;
+	struct ti_abb_info *info, *oinfo;
+	int ret = 0;
+
+	if (!abb) {
+		dev_err_ratelimited(dev, "%s: No regulator drvdata\n",
+				    __func__);
+		return -ENODEV;
+	}
+
+	if (!desc->n_voltages || !abb->info) {
+		dev_err_ratelimited(dev,
+				    "%s: No valid voltage table entries?\n",
+				    __func__);
+		return -EINVAL;
+	}
+
+	if (sel >= desc->n_voltages) {
+		dev_err(dev, "%s: sel idx(%d) >= n_voltages(%d)\n", __func__,
+			sel, desc->n_voltages);
+		return -EINVAL;
+	}
+
+	/* If we are in the same index as we were, nothing to do here! */
+	if (sel == abb->current_info_idx) {
+		dev_dbg(dev, "%s: Already at sel=%d\n", __func__, sel);
+		return ret;
+	}
+
+	/* If data is exactly the same, then just update index, no change */
+	info = &abb->info[sel];
+	oinfo = &abb->info[abb->current_info_idx];
+	if (!memcmp(info, oinfo, sizeof(*info))) {
+		dev_dbg(dev, "%s: Same data new idx=%d, old idx=%d\n", __func__,
+			sel, abb->current_info_idx);
+		goto out;
+	}
+
+	ret = ti_abb_set_opp(rdev, abb, info);
+
+out:
+	if (!ret)
+		abb->current_info_idx = sel;
+	else
+		dev_err_ratelimited(dev,
+				    "%s: Volt[%d] idx[%d] mode[%d] Fail(%d)\n",
+				    __func__, desc->volt_table[sel], sel,
+				    info->opp_sel, ret);
+	return ret;
+}
+
+/**
+ * ti_abb_get_voltage_sel() - Regulator accessor to get current ABB LDO setting
+ * @rdev:	regulator device
+ *
+ * Return: 0 on success or appropriate error value when fails
+ */
+static int ti_abb_get_voltage_sel(struct regulator_dev *rdev)
+{
+	const struct regulator_desc *desc = rdev->desc;
+	struct ti_abb *abb = rdev_get_drvdata(rdev);
+	struct device *dev = &rdev->dev;
+
+	if (!abb) {
+		dev_err_ratelimited(dev, "%s: No regulator drvdata\n",
+				    __func__);
+		return -ENODEV;
+	}
+
+	if (!desc->n_voltages || !abb->info) {
+		dev_err_ratelimited(dev,
+				    "%s: No valid voltage table entries?\n",
+				    __func__);
+		return -EINVAL;
+	}
+
+	if (abb->current_info_idx >= (int)desc->n_voltages) {
+		dev_err(dev, "%s: Corrupted data? idx(%d) >= n_voltages(%d)\n",
+			__func__, abb->current_info_idx, desc->n_voltages);
+		return -EINVAL;
+	}
+
+	return abb->current_info_idx;
+}
+
+/**
+ * ti_abb_init_timings() - setup ABB clock timing for the current platform
+ * @dev:	device
+ * @abb:	pointer to the abb instance
+ *
+ * Return: 0 if timing is updated, else returns error result.
+ */
+static int ti_abb_init_timings(struct device *dev, struct ti_abb *abb)
+{
+	u32 clock_cycles;
+	u32 clk_rate, sr2_wt_cnt_val, cycle_rate;
+	const struct ti_abb_reg *regs = abb->regs;
+	int ret;
+	char *pname = "ti,settling-time";
+
+	/* read device tree properties */
+	ret = of_property_read_u32(dev->of_node, pname, &abb->settling_time);
+	if (ret) {
+		dev_err(dev, "Unable to get property '%s'(%d)\n", pname, ret);
+		return ret;
+	}
+
+	/* ABB LDO cannot be settle in 0 time */
+	if (!abb->settling_time) {
+		dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
+		return -EINVAL;
+	}
+
+	pname = "ti,clock-cycles";
+	ret = of_property_read_u32(dev->of_node, pname, &clock_cycles);
+	if (ret) {
+		dev_err(dev, "Unable to get property '%s'(%d)\n", pname, ret);
+		return ret;
+	}
+	/* ABB LDO cannot be settle in 0 clock cycles */
+	if (!clock_cycles) {
+		dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
+		return -EINVAL;
+	}
+
+	abb->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(abb->clk)) {
+		ret = PTR_ERR(abb->clk);
+		dev_err(dev, "%s: Unable to get clk(%d)\n", __func__, ret);
+		return ret;
+	}
+
+	/*
+	 * SR2_WTCNT_VALUE is the settling time for the ABB ldo after a
+	 * transition and must be programmed with the correct time at boot.
+	 * The value programmed into the register is the number of SYS_CLK
+	 * clock cycles that match a given wall time profiled for the ldo.
+	 * This value depends on:
+	 * settling time of ldo in micro-seconds (varies per OMAP family)
+	 * # of clock cycles per SYS_CLK period (varies per OMAP family)
+	 * the SYS_CLK frequency in MHz (varies per board)
+	 * The formula is:
+	 *
+	 *                      ldo settling time (in micro-seconds)
+	 * SR2_WTCNT_VALUE = ------------------------------------------
+	 *                   (# system clock cycles) * (sys_clk period)
+	 *
+	 * Put another way:
+	 *
+	 * SR2_WTCNT_VALUE = settling time / (# SYS_CLK cycles / SYS_CLK rate))
+	 *
+	 * To avoid dividing by zero multiply both "# clock cycles" and
+	 * "settling time" by 10 such that the final result is the one we want.
+	 */
+
+	/* Convert SYS_CLK rate to MHz & prevent divide by zero */
+	clk_rate = DIV_ROUND_CLOSEST(clk_get_rate(abb->clk), 1000000);
+
+	/* Calculate cycle rate */
+	cycle_rate = DIV_ROUND_CLOSEST(clock_cycles * 10, clk_rate);
+
+	/* Calulate SR2_WTCNT_VALUE */
+	sr2_wt_cnt_val = DIV_ROUND_CLOSEST(abb->settling_time * 10, cycle_rate);
+
+	dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__,
+		clk_get_rate(abb->clk), sr2_wt_cnt_val);
+
+	ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, regs->setup_reg,
+		   abb->base);
+
+	return 0;
+}
+
+/**
+ * ti_abb_init_table() - Initialize ABB table from device tree
+ * @dev:	device
+ * @abb:	pointer to the abb instance
+ * @rinit_data:	regulator initdata
+ *
+ * Return: 0 on success or appropriate error value when fails
+ */
+static int ti_abb_init_table(struct device *dev, struct ti_abb *abb,
+			     struct regulator_init_data *rinit_data)
+{
+	struct ti_abb_info *info;
+	const struct property *prop;
+	const __be32 *abb_info;
+	const u32 num_values = 6;
+	char *pname = "ti,abb_info";
+	u32 num_entries, i;
+	unsigned int *volt_table;
+	int min_uV = INT_MAX, max_uV = 0;
+	struct regulation_constraints *c = &rinit_data->constraints;
+
+	prop = of_find_property(dev->of_node, pname, NULL);
+	if (!prop) {
+		dev_err(dev, "No '%s' property?\n", pname);
+		return -ENODEV;
+	}
+
+	if (!prop->value) {
+		dev_err(dev, "Empty '%s' property?\n", pname);
+		return -ENODATA;
+	}
+
+	/*
+	 * Each abb_info is a set of n-tuple, where n is num_values, consisting
+	 * of voltage and a set of detection logic for ABB information for that
+	 * voltage to apply.
+	 */
+	num_entries = prop->length / sizeof(u32);
+	if (!num_entries || (num_entries % num_values)) {
+		dev_err(dev, "All '%s' list entries need %d vals\n", pname,
+			num_values);
+		return -EINVAL;
+	}
+	num_entries /= num_values;
+
+	info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL);
+	if (!info) {
+		dev_err(dev, "Can't allocate info table for '%s' property\n",
+			pname);
+		return -ENOMEM;
+	}
+	abb->info = info;
+
+	volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries,
+				  GFP_KERNEL);
+	if (!volt_table) {
+		dev_err(dev, "Can't allocate voltage table for '%s' property\n",
+			pname);
+		return -ENOMEM;
+	}
+
+	abb->rdesc.n_voltages = num_entries;
+	abb->rdesc.volt_table = volt_table;
+	/* We do not know where the OPP voltage is at the moment */
+	abb->current_info_idx = -EINVAL;
+
+	abb_info = prop->value;
+	for (i = 0; i < num_entries; i++, info++, volt_table++) {
+		u32 efuse_offset, rbb_mask, fbb_mask, vset_mask;
+		u32 efuse_val;
+
+		/* NOTE: num_values should equal to entries picked up here */
+		*volt_table = be32_to_cpup(abb_info++);
+		info->opp_sel = be32_to_cpup(abb_info++);
+		efuse_offset = be32_to_cpup(abb_info++);
+		rbb_mask = be32_to_cpup(abb_info++);
+		fbb_mask = be32_to_cpup(abb_info++);
+		vset_mask = be32_to_cpup(abb_info++);
+
+		dev_dbg(dev,
+			"[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n",
+			i, *volt_table, info->opp_sel, efuse_offset, rbb_mask,
+			fbb_mask, vset_mask);
+
+		/* Find min/max for voltage set */
+		if (min_uV > *volt_table)
+			min_uV = *volt_table;
+		if (max_uV < *volt_table)
+			max_uV = *volt_table;
+
+		if (!abb->efuse_base) {
+			/* Ignore invalid data, but warn to help cleanup */
+			if (efuse_offset || rbb_mask || fbb_mask || vset_mask)
+				dev_err(dev, "prop '%s': v=%d,bad efuse/mask\n",
+					pname, *volt_table);
+			goto check_abb;
+		}
+
+		efuse_val = readl(abb->efuse_base + efuse_offset);
+
+		/* Use ABB recommendation from Efuse */
+		if (efuse_val & rbb_mask)
+			info->opp_sel = TI_ABB_SLOW_OPP;
+		else if (efuse_val & fbb_mask)
+			info->opp_sel = TI_ABB_FAST_OPP;
+		else if (rbb_mask || fbb_mask)
+			info->opp_sel = TI_ABB_NOMINAL_OPP;
+
+		dev_dbg(dev,
+			"[%d]v=%d efusev=0x%x final ABB=%d\n",
+			i, *volt_table, efuse_val, info->opp_sel);
+
+		/* Use recommended Vset bits from Efuse */
+		if (!abb->ldo_base) {
+			if (vset_mask)
+				dev_err(dev, "prop'%s':v=%d vst=%x LDO base?\n",
+					pname, *volt_table, vset_mask);
+			continue;
+		}
+		info->vset = efuse_val & vset_mask >> __ffs(vset_mask);
+		dev_dbg(dev, "[%d]v=%d vset=%x\n", i, *volt_table, info->vset);
+check_abb:
+		switch (info->opp_sel) {
+		case TI_ABB_NOMINAL_OPP:
+		case TI_ABB_FAST_OPP:
+		case TI_ABB_SLOW_OPP:
+			/* Valid values */
+			break;
+		default:
+			dev_err(dev, "%s:[%d]v=%d, ABB=%d is invalid! Abort!\n",
+				__func__, i, *volt_table, info->opp_sel);
+			return -EINVAL;
+		}
+	}
+
+	/* Setup the min/max voltage constraints from the supported list */
+	c->min_uV = min_uV;
+	c->max_uV = max_uV;
+
+	return 0;
+}
+
+static struct regulator_ops ti_abb_reg_ops = {
+	.list_voltage = regulator_list_voltage_table,
+
+	.set_voltage_sel = ti_abb_set_voltage_sel,
+	.get_voltage_sel = ti_abb_get_voltage_sel,
+};
+
+/* Default ABB block offsets, IF this changes in future, create new one */
+static const struct ti_abb_reg abb_regs_v1 = {
+	/* WARNING: registers are wrongly documented in TRM */
+	.setup_reg		= 0x04,
+	.control_reg		= 0x00,
+
+	.sr2_wtcnt_value_mask	= (0xff << 8),
+	.fbb_sel_mask		= (0x01 << 2),
+	.rbb_sel_mask		= (0x01 << 1),
+	.sr2_en_mask		= (0x01 << 0),
+
+	.opp_change_mask	= (0x01 << 2),
+	.opp_sel_mask		= (0x03 << 0),
+};
+
+static const struct ti_abb_reg abb_regs_v2 = {
+	.setup_reg		= 0x00,
+	.control_reg		= 0x04,
+
+	.sr2_wtcnt_value_mask	= (0xff << 8),
+	.fbb_sel_mask		= (0x01 << 2),
+	.rbb_sel_mask		= (0x01 << 1),
+	.sr2_en_mask		= (0x01 << 0),
+
+	.opp_change_mask	= (0x01 << 2),
+	.opp_sel_mask		= (0x03 << 0),
+};
+
+static const struct of_device_id ti_abb_of_match[] = {
+	{.compatible = "ti,abb-v1", .data = &abb_regs_v1},
+	{.compatible = "ti,abb-v2", .data = &abb_regs_v2},
+	{ },
+};
+
+MODULE_DEVICE_TABLE(of, ti_abb_of_match);
+
+/**
+ * ti_abb_probe() - Initialize an ABB ldo instance
+ * @pdev: ABB platform device
+ *
+ * Initializes an individual ABB LDO for required Body-Bias. ABB is used to
+ * addional bias supply to SoC modules for power savings or mandatory stability
+ * configuration at certain Operating Performance Points(OPPs).
+ *
+ * Return: 0 on success or appropriate error value when fails
+ */
+static int ti_abb_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *match;
+	struct resource *res;
+	struct ti_abb *abb;
+	struct regulator_init_data *initdata = NULL;
+	struct regulator_dev *rdev = NULL;
+	struct regulator_desc *desc;
+	struct regulation_constraints *c;
+	struct regulator_config config = { };
+	char *pname;
+	int ret = 0;
+
+	match = of_match_device(ti_abb_of_match, dev);
+	if (!match) {
+		/* We do not expect this to happen */
+		ret = -ENODEV;
+		dev_err(dev, "%s: Unable to match device\n", __func__);
+		goto err;
+	}
+	if (!match->data) {
+		ret = -EINVAL;
+		dev_err(dev, "%s: Bad data in match\n", __func__);
+		goto err;
+	}
+
+	abb = devm_kzalloc(dev, sizeof(struct ti_abb), GFP_KERNEL);
+	if (!abb) {
+		dev_err(dev, "%s: Unable to allocate ABB struct\n", __func__);
+		ret = -ENOMEM;
+		goto err;
+	}
+	abb->regs = match->data;
+
+	/* Map ABB resources */
+	pname = "base-address";
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
+	if (!res) {
+		dev_err(dev, "Missing '%s' IO resource\n", pname);
+		ret = -ENODEV;
+		goto err;
+	}
+	abb->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(abb->base)) {
+		ret = PTR_ERR(abb->base);
+		goto err;
+	}
+
+	pname = "int-address";
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
+	if (!res) {
+		dev_err(dev, "Missing '%s' IO resource\n", pname);
+		ret = -ENODEV;
+		goto err;
+	}
+	/*
+	 * We may have shared interrupt register offsets which are
+	 * write-1-to-clear between domains ensuring exclusivity.
+	 */
+	abb->int_base = devm_ioremap_nocache(dev, res->start,
+					     resource_size(res));
+	if (!abb->int_base) {
+		dev_err(dev, "Unable to map '%s'\n", pname);
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	/* Map Optional resources */
+	pname = "efuse-address";
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
+	if (!res) {
+		dev_dbg(dev, "Missing '%s' IO resource\n", pname);
+		ret = -ENODEV;
+		goto skip_opt;
+	}
+
+	/*
+	 * We may have shared efuse register offsets which are read-only
+	 * between domains
+	 */
+	abb->efuse_base = devm_ioremap_nocache(dev, res->start,
+					       resource_size(res));
+	if (!abb->efuse_base) {
+		dev_err(dev, "Unable to map '%s'\n", pname);
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	pname = "ldo-address";
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
+	if (!res) {
+		dev_dbg(dev, "Missing '%s' IO resource\n", pname);
+		ret = -ENODEV;
+		goto skip_opt;
+	}
+	abb->ldo_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(abb->ldo_base)) {
+		ret = PTR_ERR(abb->ldo_base);
+		goto err;
+	}
+
+	/* IF ldo_base is set, the following are mandatory */
+	pname = "ti,ldovbb-override-mask";
+	ret =
+	    of_property_read_u32(pdev->dev.of_node, pname,
+				 &abb->ldovbb_override_mask);
+	if (ret) {
+		dev_err(dev, "Missing '%s' (%d)\n", pname, ret);
+		goto err;
+	}
+	if (!abb->ldovbb_override_mask) {
+		dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	pname = "ti,ldovbb-vset-mask";
+	ret =
+	    of_property_read_u32(pdev->dev.of_node, pname,
+				 &abb->ldovbb_vset_mask);
+	if (ret) {
+		dev_err(dev, "Missing '%s' (%d)\n", pname, ret);
+		goto err;
+	}
+	if (!abb->ldovbb_vset_mask) {
+		dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
+		ret = -EINVAL;
+		goto err;
+	}
+
+skip_opt:
+	pname = "ti,tranxdone-status-mask";
+	ret =
+	    of_property_read_u32(pdev->dev.of_node, pname,
+				 &abb->txdone_mask);
+	if (ret) {
+		dev_err(dev, "Missing '%s' (%d)\n", pname, ret);
+		goto err;
+	}
+	if (!abb->txdone_mask) {
+		dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	initdata = of_get_regulator_init_data(dev, pdev->dev.of_node);
+	if (!initdata) {
+		ret = -ENOMEM;
+		dev_err(dev, "%s: Unable to alloc regulator init data\n",
+			__func__);
+		goto err;
+	}
+
+	/* init ABB opp_sel table */
+	ret = ti_abb_init_table(dev, abb, initdata);
+	if (ret)
+		goto err;
+
+	/* init ABB timing */
+	ret = ti_abb_init_timings(dev, abb);
+	if (ret)
+		goto err;
+
+	desc = &abb->rdesc;
+	desc->name = dev_name(dev);
+	desc->owner = THIS_MODULE;
+	desc->type = REGULATOR_VOLTAGE;
+	desc->ops = &ti_abb_reg_ops;
+
+	c = &initdata->constraints;
+	if (desc->n_voltages > 1)
+		c->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
+	c->always_on = true;
+
+	config.dev = dev;
+	config.init_data = initdata;
+	config.driver_data = abb;
+	config.of_node = pdev->dev.of_node;
+
+	rdev = regulator_register(desc, &config);
+	if (IS_ERR(rdev)) {
+		ret = PTR_ERR(rdev);
+		dev_err(dev, "%s: failed to register regulator(%d)\n",
+			__func__, ret);
+		goto err;
+	}
+	platform_set_drvdata(pdev, rdev);
+
+	/* Enable the ldo if not already done by bootloader */
+	ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->regs->setup_reg, abb->base);
+
+	return 0;
+
+err:
+	dev_err(dev, "%s: Failed to initialize(%d)\n", __func__, ret);
+	return ret;
+}
+
+/**
+ * ti_abb_remove() - cleanups
+ * @pdev: ABB platform device
+ *
+ * Return: 0
+ */
+static int ti_abb_remove(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+	regulator_unregister(rdev);
+	return 0;
+}
+
+MODULE_ALIAS("platform:ti_abb");
+
+static struct platform_driver ti_abb_driver = {
+	.probe = ti_abb_probe,
+	.remove = ti_abb_remove,
+	.driver = {
+		   .name = "ti_abb",
+		   .owner = THIS_MODULE,
+		   .of_match_table = of_match_ptr(ti_abb_of_match),
+		   },
+};
+module_platform_driver(ti_abb_driver);
+
+MODULE_DESCRIPTION("Texas Instruments ABB LDO regulator driver");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/tps62360-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/tps62360-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/tps62360-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/tps62360-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -351,7 +351,6 @@ static int tps62360_probe(struct i2c_cli
 	int chip_id;
 
 	pdata = client->dev.platform_data;
-	chip_id = id->driver_data;
 
 	if (client->dev.of_node) {
 		const struct of_device_id *match;
@@ -364,6 +363,11 @@ static int tps62360_probe(struct i2c_cli
 		chip_id = (int)match->data;
 		if (!pdata)
 			pdata = of_get_tps62360_platform_data(&client->dev);
+	} else if (id) {
+		chip_id = id->driver_data;
+	} else {
+		dev_err(&client->dev, "No device tree match or id table match found\n");
+		return -ENODEV;
 	}
 
 	if (!pdata) {
@@ -402,7 +406,7 @@ static int tps62360_probe(struct i2c_cli
 		return -ENODEV;
 	}
 
-	tps->desc.name = id->name;
+	tps->desc.name = client->name;
 	tps->desc.id = 0;
 	tps->desc.ops = &tps62360_dcdc_ops;
 	tps->desc.type = REGULATOR_VOLTAGE;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/tps65217-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/tps65217-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/tps65217-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/tps65217-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -405,8 +405,6 @@ static int tps65217_regulator_remove(str
 	for (i = 0; i < TPS65217_NUM_REGULATOR; i++)
 		regulator_unregister(tps->rdev[i]);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/twl-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/twl-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/twl-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/twl-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -109,7 +109,7 @@ struct twlreg_info {
 #define SMPS_OFFSET_EN		BIT(0)
 #define SMPS_EXTENDED_EN	BIT(1)
 
-/* twl6025 SMPS EPROM values */
+/* twl6032 SMPS EPROM values */
 #define TWL6030_SMPS_OFFSET		0xB0
 #define TWL6030_SMPS_MULT		0xB3
 #define SMPS_MULTOFFSET_SMPS4	BIT(0)
@@ -173,7 +173,7 @@ static int twl6030reg_is_enabled(struct
 	struct twlreg_info	*info = rdev_get_drvdata(rdev);
 	int			grp = 0, val;
 
-	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) {
+	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS))) {
 		grp = twlreg_grp(rdev);
 		if (grp < 0)
 			return grp;
@@ -211,7 +211,7 @@ static int twl6030reg_enable(struct regu
 	int			grp = 0;
 	int			ret;
 
-	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
 		grp = twlreg_grp(rdev);
 	if (grp < 0)
 		return grp;
@@ -245,7 +245,7 @@ static int twl6030reg_disable(struct reg
 	int			grp = 0;
 	int			ret;
 
-	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
 		grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030;
 
 	/* For 6030, set the off state for all grps enabled */
@@ -339,7 +339,7 @@ static int twl6030reg_set_mode(struct re
 	int grp = 0;
 	int val;
 
-	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
 		grp = twlreg_grp(rdev);
 
 	if (grp < 0)
@@ -899,14 +899,14 @@ static const struct twlreg_info TWL6030_
 		}, \
 	}
 
-#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \
-static const struct twlreg_info TWL6025_INFO_##label = { \
+#define TWL6032_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) \
+static const struct twlreg_info TWL6032_INFO_##label = { \
 	.base = offset, \
 	.min_mV = min_mVolts, \
 	.max_mV = max_mVolts, \
 	.desc = { \
 		.name = #label, \
-		.id = TWL6025_REG_##label, \
+		.id = TWL6032_REG_##label, \
 		.n_voltages = 32, \
 		.ops = &twl6030ldo_ops, \
 		.type = REGULATOR_VOLTAGE, \
@@ -933,14 +933,14 @@ static const struct twlreg_info TWLFIXED
 		}, \
 	}
 
-#define TWL6025_ADJUSTABLE_SMPS(label, offset) \
+#define TWL6032_ADJUSTABLE_SMPS(label, offset) \
 static const struct twlreg_info TWLSMPS_INFO_##label = { \
 	.base = offset, \
 	.min_mV = 600, \
 	.max_mV = 2100, \
 	.desc = { \
 		.name = #label, \
-		.id = TWL6025_REG_##label, \
+		.id = TWL6032_REG_##label, \
 		.n_voltages = 63, \
 		.ops = &twlsmps_ops, \
 		.type = REGULATOR_VOLTAGE, \
@@ -981,15 +981,15 @@ TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000,
 TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300);
 TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300);
 /* 6025 are renamed compared to 6030 versions */
-TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300);
-TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300);
+TWL6032_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300);
 TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08);
 TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08);
 TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08);
@@ -1001,9 +1001,9 @@ TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0);
 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0);
 TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0);
 TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0);
-TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34);
-TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10);
-TWL6025_ADJUSTABLE_SMPS(VIO, 0x16);
+TWL6032_ADJUSTABLE_SMPS(SMPS3, 0x34);
+TWL6032_ADJUSTABLE_SMPS(SMPS4, 0x10);
+TWL6032_ADJUSTABLE_SMPS(VIO, 0x16);
 
 static u8 twl_get_smps_offset(void)
 {
@@ -1031,7 +1031,7 @@ static u8 twl_get_smps_mult(void)
 
 #define TWL4030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL4030, label)
 #define TWL6030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6030, label)
-#define TWL6025_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6025, label)
+#define TWL6032_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6032, label)
 #define TWLFIXED_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLFIXED, label)
 #define TWLSMPS_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLSMPS, label)
 
@@ -1060,15 +1060,15 @@ static const struct of_device_id twl_of_
 	TWL6030_OF_MATCH("ti,twl6030-vmmc", VMMC),
 	TWL6030_OF_MATCH("ti,twl6030-vpp", VPP),
 	TWL6030_OF_MATCH("ti,twl6030-vusim", VUSIM),
-	TWL6025_OF_MATCH("ti,twl6025-ldo2", LDO2),
-	TWL6025_OF_MATCH("ti,twl6025-ldo4", LDO4),
-	TWL6025_OF_MATCH("ti,twl6025-ldo3", LDO3),
-	TWL6025_OF_MATCH("ti,twl6025-ldo5", LDO5),
-	TWL6025_OF_MATCH("ti,twl6025-ldo1", LDO1),
-	TWL6025_OF_MATCH("ti,twl6025-ldo7", LDO7),
-	TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6),
-	TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN),
-	TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB),
+	TWL6032_OF_MATCH("ti,twl6032-ldo2", LDO2),
+	TWL6032_OF_MATCH("ti,twl6032-ldo4", LDO4),
+	TWL6032_OF_MATCH("ti,twl6032-ldo3", LDO3),
+	TWL6032_OF_MATCH("ti,twl6032-ldo5", LDO5),
+	TWL6032_OF_MATCH("ti,twl6032-ldo1", LDO1),
+	TWL6032_OF_MATCH("ti,twl6032-ldo7", LDO7),
+	TWL6032_OF_MATCH("ti,twl6032-ldo6", LDO6),
+	TWL6032_OF_MATCH("ti,twl6032-ldoln", LDOLN),
+	TWL6032_OF_MATCH("ti,twl6032-ldousb", LDOUSB),
 	TWLFIXED_OF_MATCH("ti,twl4030-vintana1", VINTANA1),
 	TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG),
 	TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5),
@@ -1080,9 +1080,9 @@ static const struct of_device_id twl_of_
 	TWLFIXED_OF_MATCH("ti,twl6030-vusb", VUSB),
 	TWLFIXED_OF_MATCH("ti,twl6030-v1v8", V1V8),
 	TWLFIXED_OF_MATCH("ti,twl6030-v2v1", V2V1),
-	TWLSMPS_OF_MATCH("ti,twl6025-smps3", SMPS3),
-	TWLSMPS_OF_MATCH("ti,twl6025-smps4", SMPS4),
-	TWLSMPS_OF_MATCH("ti,twl6025-vio", VIO),
+	TWLSMPS_OF_MATCH("ti,twl6032-smps3", SMPS3),
+	TWLSMPS_OF_MATCH("ti,twl6032-smps4", SMPS4),
+	TWLSMPS_OF_MATCH("ti,twl6032-vio", VIO),
 	{},
 };
 MODULE_DEVICE_TABLE(of, twl_of_match);
@@ -1163,19 +1163,19 @@ static int twlreg_probe(struct platform_
 	}
 
 	switch (id) {
-	case TWL6025_REG_SMPS3:
+	case TWL6032_REG_SMPS3:
 		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
 			info->flags |= SMPS_EXTENDED_EN;
 		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3)
 			info->flags |= SMPS_OFFSET_EN;
 		break;
-	case TWL6025_REG_SMPS4:
+	case TWL6032_REG_SMPS4:
 		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4)
 			info->flags |= SMPS_EXTENDED_EN;
 		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4)
 			info->flags |= SMPS_OFFSET_EN;
 		break;
-	case TWL6025_REG_VIO:
+	case TWL6032_REG_VIO:
 		if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO)
 			info->flags |= SMPS_EXTENDED_EN;
 		if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/virtual.c linux-libre-3.11-rc7-gnu/drivers/regulator/virtual.c
--- linux-libre-3.10-gnu/drivers/regulator/virtual.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/virtual.c	2013-08-25 20:43:22.000000000 -0400
@@ -330,8 +330,6 @@ static int regulator_virtual_remove(stru
 	if (drvdata->enabled)
 		regulator_disable(drvdata->regulator);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/wm831x-dcdc.c linux-libre-3.11-rc7-gnu/drivers/regulator/wm831x-dcdc.c
--- linux-libre-3.10-gnu/drivers/regulator/wm831x-dcdc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/wm831x-dcdc.c	2013-08-25 20:43:22.000000000 -0400
@@ -567,8 +567,6 @@ static int wm831x_buckv_remove(struct pl
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 	struct wm831x *wm831x = dcdc->wm831x;
 
-	platform_set_drvdata(pdev, NULL);
-
 	free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "HC")),
 			    dcdc);
 	free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")),
@@ -714,8 +712,6 @@ static int wm831x_buckp_remove(struct pl
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")),
 			    dcdc);
 	regulator_unregister(dcdc->regulator);
@@ -849,8 +845,6 @@ static int wm831x_boostp_remove(struct p
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")),
 		 dcdc);
 	regulator_unregister(dcdc->regulator);
@@ -940,7 +934,6 @@ static int wm831x_epe_remove(struct plat
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(dcdc->regulator);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/wm831x-isink.c linux-libre-3.11-rc7-gnu/drivers/regulator/wm831x-isink.c
--- linux-libre-3.10-gnu/drivers/regulator/wm831x-isink.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/wm831x-isink.c	2013-08-25 20:43:22.000000000 -0400
@@ -225,8 +225,6 @@ static int wm831x_isink_remove(struct pl
 {
 	struct wm831x_isink *isink = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	free_irq(wm831x_irq(isink->wm831x, platform_get_irq(pdev, 0)), isink);
 
 	regulator_unregister(isink->regulator);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/wm831x-ldo.c linux-libre-3.11-rc7-gnu/drivers/regulator/wm831x-ldo.c
--- linux-libre-3.10-gnu/drivers/regulator/wm831x-ldo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/wm831x-ldo.c	2013-08-25 20:43:22.000000000 -0400
@@ -338,8 +338,6 @@ static int wm831x_gp_ldo_remove(struct p
 {
 	struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	free_irq(wm831x_irq(ldo->wm831x,
 			    platform_get_irq_byname(pdev, "UV")), ldo);
 	regulator_unregister(ldo->regulator);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/wm8400-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/wm8400-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/wm8400-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/wm8400-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -250,7 +250,6 @@ static int wm8400_regulator_remove(struc
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
 	regulator_unregister(rdev);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/regulator/wm8994-regulator.c linux-libre-3.11-rc7-gnu/drivers/regulator/wm8994-regulator.c
--- linux-libre-3.10-gnu/drivers/regulator/wm8994-regulator.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/regulator/wm8994-regulator.c	2013-08-25 20:43:22.000000000 -0400
@@ -185,8 +185,6 @@ static int wm8994_ldo_remove(struct plat
 {
 	struct wm8994_ldo *ldo = platform_get_drvdata(pdev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	regulator_unregister(ldo->regulator);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/remoteproc/Kconfig linux-libre-3.11-rc7-gnu/drivers/remoteproc/Kconfig
--- linux-libre-3.10-gnu/drivers/remoteproc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/remoteproc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -14,8 +14,9 @@ config OMAP_REMOTEPROC
 	depends on HAS_DMA
 	depends on ARCH_OMAP4 || SOC_OMAP5
 	depends on OMAP_IOMMU
-	depends on OMAP_MBOX_FWK
 	select REMOTEPROC
+	select MAILBOX
+	select OMAP2PLUS_MBOX
 	select RPMSG
 	help
 	  Say y here to support OMAP's remote processors (dual M3
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/remoteproc/omap_remoteproc.c linux-libre-3.11-rc7-gnu/drivers/remoteproc/omap_remoteproc.c
--- linux-libre-3.10-gnu/drivers/remoteproc/omap_remoteproc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/remoteproc/omap_remoteproc.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,8 +27,8 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/remoteproc.h>
+#include <linux/omap-mailbox.h>
 
-#include <plat/mailbox.h>
 #include <linux/platform_data/remoteproc-omap.h>
 
 #include "omap_remoteproc.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/remoteproc/remoteproc_core.c linux-libre-3.11-rc7-gnu/drivers/remoteproc/remoteproc_core.c
--- linux-libre-3.10-gnu/drivers/remoteproc/remoteproc_core.c	2013-07-01 10:43:39.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/remoteproc/remoteproc_core.c	2013-08-31 18:03:27.000000000 -0400
@@ -762,13 +762,6 @@ static void rproc_resource_cleanup(struc
 		kfree(entry);
 	}
 
-	/* clean up carveout allocations */
-	list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) {
-		dma_free_coherent(dev->parent, entry->len, entry->va, entry->dma);
-		list_del(&entry->node);
-		kfree(entry);
-	}
-
 	/* clean up iommu mapping entries */
 	list_for_each_entry_safe(entry, tmp, &rproc->mappings, node) {
 		size_t unmapped;
@@ -783,6 +776,13 @@ static void rproc_resource_cleanup(struc
 		list_del(&entry->node);
 		kfree(entry);
 	}
+
+	/* clean up carveout allocations */
+	list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) {
+		dma_free_coherent(dev->parent, entry->len, entry->va, entry->dma);
+		list_del(&entry->node);
+		kfree(entry);
+	}
 }
 
 /*
@@ -815,18 +815,17 @@ static int rproc_fw_boot(struct rproc *r
 	}
 
 	rproc->bootaddr = rproc_get_boot_addr(rproc, fw);
+	ret = -EINVAL;
 
 	/* look for the resource table */
 	table = rproc_find_rsc_table(rproc, fw, &tablesz);
 	if (!table) {
-		ret = -EINVAL;
 		goto clean_up;
 	}
 
 	/* Verify that resource table in loaded fw is unchanged */
 	if (rproc->table_csum != crc32(0, table, tablesz)) {
 		dev_err(dev, "resource checksum failed, fw changed?\n");
-		ret = -EINVAL;
 		goto clean_up;
 	}
 
@@ -852,8 +851,10 @@ static int rproc_fw_boot(struct rproc *r
 	 * copy this information to device memory.
 	 */
 	loaded_table = rproc_find_loaded_rsc_table(rproc, fw);
-	if (!loaded_table)
+	if (!loaded_table) {
+		ret = -EINVAL;
 		goto clean_up;
+	}
 
 	memcpy(loaded_table, rproc->cached_table, tablesz);
 
@@ -913,11 +914,10 @@ static void rproc_fw_config_virtio(const
 	 * will be stored in the cached_table. Before the device is started,
 	 * cached_table will be copied into devic memory.
 	 */
-	rproc->cached_table = kmalloc(tablesz, GFP_KERNEL);
+	rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL);
 	if (!rproc->cached_table)
 		goto out;
 
-	memcpy(rproc->cached_table, table, tablesz);
 	rproc->table_ptr = rproc->cached_table;
 
 	/* count the number of notify-ids */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/remoteproc/remoteproc_debugfs.c linux-libre-3.11-rc7-gnu/drivers/remoteproc/remoteproc_debugfs.c
--- linux-libre-3.10-gnu/drivers/remoteproc/remoteproc_debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/remoteproc/remoteproc_debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -248,6 +248,5 @@ void __init rproc_init_debugfs(void)
 
 void __exit rproc_exit_debugfs(void)
 {
-	if (rproc_dbg)
-		debugfs_remove(rproc_dbg);
+	debugfs_remove(rproc_dbg);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/remoteproc/remoteproc_internal.h linux-libre-3.11-rc7-gnu/drivers/remoteproc/remoteproc_internal.h
--- linux-libre-3.10-gnu/drivers/remoteproc/remoteproc_internal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/remoteproc/remoteproc_internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -107,12 +107,12 @@ struct resource_table *rproc_find_rsc_ta
 
 static inline
 struct resource_table *rproc_find_loaded_rsc_table(struct rproc *rproc,
-                                const struct firmware *fw)
+						const struct firmware *fw)
 {
 	if (rproc->fw_ops->find_loaded_rsc_table)
 		return rproc->fw_ops->find_loaded_rsc_table(rproc, fw);
 
-        return NULL;
+	return NULL;
 }
 
 extern const struct rproc_fw_ops rproc_elf_fw_ops;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/class.c linux-libre-3.11-rc7-gnu/drivers/rtc/class.c
--- linux-libre-3.10-gnu/drivers/rtc/class.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/class.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,7 @@ static void rtc_device_release(struct de
 int rtc_hctosys_ret = -ENODEV;
 #endif
 
-#if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
 /*
  * On suspend(), measure the delta between one RTC and the
  * system's wall clock; restore it on resume().
@@ -47,7 +47,7 @@ int rtc_hctosys_ret = -ENODEV;
 static struct timespec old_rtc, old_system, old_delta;
 
 
-static int rtc_suspend(struct device *dev, pm_message_t mesg)
+static int rtc_suspend(struct device *dev)
 {
 	struct rtc_device	*rtc = to_rtc_device(dev);
 	struct rtc_time		tm;
@@ -135,9 +135,10 @@ static int rtc_resume(struct device *dev
 	return 0;
 }
 
+static SIMPLE_DEV_PM_OPS(rtc_class_dev_pm_ops, rtc_suspend, rtc_resume);
+#define RTC_CLASS_DEV_PM_OPS	(&rtc_class_dev_pm_ops)
 #else
-#define rtc_suspend	NULL
-#define rtc_resume	NULL
+#define RTC_CLASS_DEV_PM_OPS	NULL
 #endif
 
 
@@ -336,8 +337,7 @@ static int __init rtc_init(void)
 		pr_err("couldn't create class\n");
 		return PTR_ERR(rtc_class);
 	}
-	rtc_class->suspend = rtc_suspend;
-	rtc_class->resume = rtc_resume;
+	rtc_class->pm = RTC_CLASS_DEV_PM_OPS;
 	rtc_dev_init();
 	rtc_sysfs_init(rtc_class);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/interface.c linux-libre-3.11-rc7-gnu/drivers/rtc/interface.c
--- linux-libre-3.10-gnu/drivers/rtc/interface.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/interface.c	2013-08-25 20:43:22.000000000 -0400
@@ -109,9 +109,9 @@ int rtc_set_mmss(struct rtc_device *rtc,
 				err = rtc->ops->set_time(rtc->dev.parent,
 						&new);
 		}
-	}
-	else
+	} else {
 		err = -EINVAL;
+	}
 
 	mutex_unlock(&rtc->ops_lock);
 	/* A timer might have just expired */
@@ -367,14 +367,14 @@ int rtc_set_alarm(struct rtc_device *rtc
 	err = mutex_lock_interruptible(&rtc->ops_lock);
 	if (err)
 		return err;
-	if (rtc->aie_timer.enabled) {
+	if (rtc->aie_timer.enabled)
 		rtc_timer_remove(rtc, &rtc->aie_timer);
-	}
+
 	rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
 	rtc->aie_timer.period = ktime_set(0, 0);
-	if (alarm->enabled) {
+	if (alarm->enabled)
 		err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
-	}
+
 	mutex_unlock(&rtc->ops_lock);
 	return err;
 }
@@ -698,9 +698,9 @@ retry:
 	spin_lock_irqsave(&rtc->irq_task_lock, flags);
 	if (rtc->irq_task != NULL && task == NULL)
 		err = -EBUSY;
-	if (rtc->irq_task != task)
+	else if (rtc->irq_task != task)
 		err = -EACCES;
-	if (!err) {
+	else {
 		if (rtc_update_hrtimer(rtc, enabled) < 0) {
 			spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
 			cpu_relax();
@@ -734,9 +734,9 @@ retry:
 	spin_lock_irqsave(&rtc->irq_task_lock, flags);
 	if (rtc->irq_task != NULL && task == NULL)
 		err = -EBUSY;
-	if (rtc->irq_task != task)
+	else if (rtc->irq_task != task)
 		err = -EACCES;
-	if (!err) {
+	else {
 		rtc->irq_freq = freq;
 		if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) {
 			spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
@@ -891,7 +891,7 @@ again:
  *
  * Kernel interface to initializing an rtc_timer.
  */
-void rtc_timer_init(struct rtc_timer *timer, void (*f)(void* p), void* data)
+void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data)
 {
 	timerqueue_init(&timer->node);
 	timer->enabled = 0;
@@ -907,7 +907,7 @@ void rtc_timer_init(struct rtc_timer *ti
  *
  * Kernel interface to set an rtc_timer
  */
-int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer,
+int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer,
 			ktime_t expires, ktime_t period)
 {
 	int ret = 0;
@@ -930,7 +930,7 @@ int rtc_timer_start(struct rtc_device *r
  *
  * Kernel interface to cancel an rtc_timer
  */
-int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer)
+int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer *timer)
 {
 	int ret = 0;
 	mutex_lock(&rtc->ops_lock);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/Kconfig linux-libre-3.11-rc7-gnu/drivers/rtc/Kconfig
--- linux-libre-3.10-gnu/drivers/rtc/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -313,6 +313,15 @@ config RTC_DRV_PALMAS
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-palma.
 
+config RTC_DRV_PCF2127
+	tristate "NXP PCF2127"
+	help
+	  If you say yes here you get support for the NXP PCF2127/29 RTC
+	  chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-pcf2127.
+
 config RTC_DRV_PCF8523
 	tristate "NXP PCF8523"
 	help
@@ -1233,6 +1242,13 @@ config RTC_DRV_SNVS
 	   This driver can also be built as a module, if so, the module
 	   will be called "rtc-snvs".
 
+config RTC_DRV_SIRFSOC
+	tristate "SiRFSOC RTC"
+	depends on ARCH_SIRF
+	help
+	  Say "yes" here to support the real time clock on SiRF SOC chips.
+	  This driver can also be built as a module called rtc-sirfsoc.
+
 comment "HID Sensor RTC drivers"
 
 config RTC_DRV_HID_SENSOR_TIME
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/Makefile linux-libre-3.11-rc7-gnu/drivers/rtc/Makefile
--- linux-libre-3.10-gnu/drivers/rtc/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -83,6 +83,7 @@ obj-$(CONFIG_RTC_DRV_NUC900)	+= rtc-nuc9
 obj-$(CONFIG_RTC_DRV_OMAP)	+= rtc-omap.o
 obj-$(CONFIG_RTC_DRV_PALMAS)	+= rtc-palmas.o
 obj-$(CONFIG_RTC_DRV_PCAP)	+= rtc-pcap.o
+obj-$(CONFIG_RTC_DRV_PCF2127)	+= rtc-pcf2127.o
 obj-$(CONFIG_RTC_DRV_PCF8523)	+= rtc-pcf8523.o
 obj-$(CONFIG_RTC_DRV_PCF8563)	+= rtc-pcf8563.o
 obj-$(CONFIG_RTC_DRV_PCF8583)	+= rtc-pcf8583.o
@@ -128,3 +129,4 @@ obj-$(CONFIG_RTC_DRV_VT8500)	+= rtc-vt85
 obj-$(CONFIG_RTC_DRV_WM831X)	+= rtc-wm831x.o
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
+obj-$(CONFIG_RTC_DRV_SIRFSOC)	+= rtc-sirfsoc.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-88pm80x.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-88pm80x.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-88pm80x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-88pm80x.c	2013-08-25 20:43:22.000000000 -0400
@@ -345,7 +345,6 @@ out:
 static int pm80x_rtc_remove(struct platform_device *pdev)
 {
 	struct pm80x_rtc_info *info = platform_get_drvdata(pdev);
-	platform_set_drvdata(pdev, NULL);
 	pm80x_free_irq(info->chip, info->irq, info);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-88pm860x.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-88pm860x.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-88pm860x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-88pm860x.c	2013-08-25 20:43:22.000000000 -0400
@@ -418,7 +418,6 @@ static int pm860x_rtc_remove(struct plat
 	pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0);
 #endif	/* VRTC_CALIBRATION */
 
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ab3100.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ab3100.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ab3100.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ab3100.c	2013-08-25 20:43:22.000000000 -0400
@@ -240,18 +240,11 @@ static int __init ab3100_rtc_probe(struc
 	return 0;
 }
 
-static int __exit ab3100_rtc_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-	return 0;
-}
-
 static struct platform_driver ab3100_rtc_driver = {
 	.driver = {
 		.name = "ab3100-rtc",
 		.owner = THIS_MODULE,
 	},
-	.remove	 = __exit_p(ab3100_rtc_remove),
 };
 
 module_platform_driver_probe(ab3100_rtc_driver, ab3100_rtc_probe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ab8500.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ab8500.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ab8500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ab8500.c	2013-08-25 20:43:22.000000000 -0400
@@ -35,6 +35,10 @@
 #define AB8500_RTC_FORCE_BKUP_REG	0x0D
 #define AB8500_RTC_CALIB_REG		0x0E
 #define AB8500_RTC_SWITCH_STAT_REG	0x0F
+#define AB8540_RTC_ALRM_SEC		0x22
+#define AB8540_RTC_ALRM_MIN_LOW_REG	0x23
+#define AB8540_RTC_ALRM_MIN_MID_REG	0x24
+#define AB8540_RTC_ALRM_MIN_HI_REG	0x25
 
 /* RtcReadRequest bits */
 #define RTC_READ_REQUEST		0x01
@@ -58,6 +62,11 @@ static const u8 ab8500_rtc_alarm_regs[]
 	AB8500_RTC_ALRM_MIN_LOW_REG
 };
 
+static const u8 ab8540_rtc_alarm_regs[] = {
+	AB8540_RTC_ALRM_MIN_HI_REG, AB8540_RTC_ALRM_MIN_MID_REG,
+	AB8540_RTC_ALRM_MIN_LOW_REG, AB8540_RTC_ALRM_SEC
+};
+
 /* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */
 static unsigned long get_elapsed_seconds(int year)
 {
@@ -267,6 +276,42 @@ static int ab8500_rtc_set_alarm(struct d
 	return ab8500_rtc_irq_enable(dev, alarm->enabled);
 }
 
+static int ab8540_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	int retval, i;
+	unsigned char buf[ARRAY_SIZE(ab8540_rtc_alarm_regs)];
+	unsigned long mins, secs = 0;
+
+	if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) {
+		dev_dbg(dev, "year should be equal to or greater than %d\n",
+				AB8500_RTC_EPOCH);
+		return -EINVAL;
+	}
+
+	/* Get the number of seconds since 1970 */
+	rtc_tm_to_time(&alarm->time, &secs);
+
+	/*
+	 * Convert it to the number of seconds since 01-01-2000 00:00:00
+	 */
+	secs -= get_elapsed_seconds(AB8500_RTC_EPOCH);
+	mins = secs / 60;
+
+	buf[3] = secs % 60;
+	buf[2] = mins & 0xFF;
+	buf[1] = (mins >> 8) & 0xFF;
+	buf[0] = (mins >> 16) & 0xFF;
+
+	/* Set the alarm time */
+	for (i = 0; i < ARRAY_SIZE(ab8540_rtc_alarm_regs); i++) {
+		retval = abx500_set_register_interruptible(dev, AB8500_RTC,
+			ab8540_rtc_alarm_regs[i], buf[i]);
+		if (retval < 0)
+			return retval;
+	}
+
+	return ab8500_rtc_irq_enable(dev, alarm->enabled);
+}
 
 static int ab8500_rtc_set_calibration(struct device *dev, int calibration)
 {
@@ -389,8 +434,22 @@ static const struct rtc_class_ops ab8500
 	.alarm_irq_enable	= ab8500_rtc_irq_enable,
 };
 
+static const struct rtc_class_ops ab8540_rtc_ops = {
+	.read_time		= ab8500_rtc_read_time,
+	.set_time		= ab8500_rtc_set_time,
+	.read_alarm		= ab8500_rtc_read_alarm,
+	.set_alarm		= ab8540_rtc_set_alarm,
+	.alarm_irq_enable	= ab8500_rtc_irq_enable,
+};
+
+static struct platform_device_id ab85xx_rtc_ids[] = {
+	{ "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, },
+	{ "ab8540-rtc", (kernel_ulong_t)&ab8540_rtc_ops, },
+};
+
 static int ab8500_rtc_probe(struct platform_device *pdev)
 {
+	const struct platform_device_id *platid = platform_get_device_id(pdev);
 	int err;
 	struct rtc_device *rtc;
 	u8 rtc_ctrl;
@@ -423,7 +482,8 @@ static int ab8500_rtc_probe(struct platf
 	device_init_wakeup(&pdev->dev, true);
 
 	rtc = devm_rtc_device_register(&pdev->dev, "ab8500-rtc",
-					&ab8500_rtc_ops, THIS_MODULE);
+				(struct rtc_class_ops *)platid->driver_data,
+				THIS_MODULE);
 	if (IS_ERR(rtc)) {
 		dev_err(&pdev->dev, "Registration failed\n");
 		err = PTR_ERR(rtc);
@@ -451,8 +511,6 @@ static int ab8500_rtc_remove(struct plat
 {
 	ab8500_sysfs_rtc_unregister(&pdev->dev);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
@@ -463,6 +521,7 @@ static struct platform_driver ab8500_rtc
 	},
 	.probe	= ab8500_rtc_probe,
 	.remove = ab8500_rtc_remove,
+	.id_table = ab85xx_rtc_ids,
 };
 
 module_platform_driver(ab8500_rtc_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-at32ap700x.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-at32ap700x.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-at32ap700x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-at32ap700x.c	2013-08-25 20:43:22.000000000 -0400
@@ -141,7 +141,7 @@ static int at32_rtc_alarm_irq_enable(str
 
 	spin_lock_irq(&rtc->lock);
 
-	if(enabled) {
+	if (enabled) {
 		if (rtc_readl(rtc, VAL) > rtc->alarm_time) {
 			ret = -EINVAL;
 			goto out;
@@ -212,23 +212,20 @@ static int __init at32_rtc_probe(struct
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!regs) {
 		dev_dbg(&pdev->dev, "no mmio resource defined\n");
-		ret = -ENXIO;
-		goto out;
+		return -ENXIO;
 	}
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq <= 0) {
 		dev_dbg(&pdev->dev, "could not get irq\n");
-		ret = -ENXIO;
-		goto out;
+		return -ENXIO;
 	}
 
 	rtc->irq = irq;
 	rtc->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
 	if (!rtc->regs) {
-		ret = -ENOMEM;
 		dev_dbg(&pdev->dev, "could not map I/O memory\n");
-		goto out;
+		return -ENOMEM;
 	}
 	spin_lock_init(&rtc->lock);
 
@@ -249,7 +246,7 @@ static int __init at32_rtc_probe(struct
 				"rtc", rtc);
 	if (ret) {
 		dev_dbg(&pdev->dev, "could not request irq %d\n", irq);
-		goto out;
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, rtc);
@@ -258,8 +255,7 @@ static int __init at32_rtc_probe(struct
 				&at32_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc)) {
 		dev_dbg(&pdev->dev, "could not register rtc device\n");
-		ret = PTR_ERR(rtc->rtc);
-		goto out;
+		return PTR_ERR(rtc->rtc);
 	}
 
 	device_init_wakeup(&pdev->dev, 1);
@@ -268,18 +264,12 @@ static int __init at32_rtc_probe(struct
 			(unsigned long)rtc->regs, rtc->irq);
 
 	return 0;
-
-out:
-	platform_set_drvdata(pdev, NULL);
-	return ret;
 }
 
 static int __exit at32_rtc_remove(struct platform_device *pdev)
 {
 	device_init_wakeup(&pdev->dev, 0);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-at91rm9200.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-at91rm9200.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-at91rm9200.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-at91rm9200.c	2013-08-25 20:43:22.000000000 -0400
@@ -31,8 +31,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #include "rtc-at91rm9200.h"
 
@@ -439,7 +438,6 @@ static int __exit at91_rtc_remove(struct
 
 	rtc_device_unregister(rtc);
 	iounmap(at91_rtc_regs);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-at91sam9.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-at91sam9.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-at91sam9.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-at91sam9.c	2013-08-25 20:43:22.000000000 -0400
@@ -324,16 +324,14 @@ static int at91_rtc_probe(struct platfor
 	rtc->rtt = devm_ioremap(&pdev->dev, r->start, resource_size(r));
 	if (!rtc->rtt) {
 		dev_err(&pdev->dev, "failed to map registers, aborting.\n");
-		ret = -ENOMEM;
-		goto fail;
+		return -ENOMEM;
 	}
 
 	rtc->gpbr = devm_ioremap(&pdev->dev, r_gpbr->start,
 				resource_size(r_gpbr));
 	if (!rtc->gpbr) {
 		dev_err(&pdev->dev, "failed to map gpbr registers, aborting.\n");
-		ret = -ENOMEM;
-		goto fail;
+		return -ENOMEM;
 	}
 
 	mr = rtt_readl(rtc, MR);
@@ -350,17 +348,15 @@ static int at91_rtc_probe(struct platfor
 
 	rtc->rtcdev = devm_rtc_device_register(&pdev->dev, pdev->name,
 					&at91_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc->rtcdev)) {
-		ret = PTR_ERR(rtc->rtcdev);
-		goto fail;
-	}
+	if (IS_ERR(rtc->rtcdev))
+		return PTR_ERR(rtc->rtcdev);
 
 	/* register irq handler after we know what name we'll use */
 	ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt,
 				IRQF_SHARED, dev_name(&rtc->rtcdev->dev), rtc);
 	if (ret) {
 		dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq);
-		goto fail;
+		return ret;
 	}
 
 	/* NOTE:  sam9260 rev A silicon has a ROM bug which resets the
@@ -374,10 +370,6 @@ static int at91_rtc_probe(struct platfor
 				dev_name(&rtc->rtcdev->dev));
 
 	return 0;
-
-fail:
-	platform_set_drvdata(pdev, NULL);
-	return ret;
 }
 
 /*
@@ -391,7 +383,6 @@ static int at91_rtc_remove(struct platfo
 	/* disable all interrupts */
 	rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN));
 
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-au1xxx.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-au1xxx.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-au1xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-au1xxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,19 +116,11 @@ out_err:
 	return ret;
 }
 
-static int au1xtoy_rtc_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
-}
-
 static struct platform_driver au1xrtc_driver = {
 	.driver		= {
 		.name	= "rtc-au1xxx",
 		.owner	= THIS_MODULE,
 	},
-	.remove		= au1xtoy_rtc_remove,
 };
 
 module_platform_driver_probe(au1xrtc_driver, au1xtoy_rtc_probe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-bfin.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-bfin.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-bfin.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-bfin.c	2013-08-25 20:43:22.000000000 -0400
@@ -391,7 +391,6 @@ static int bfin_rtc_remove(struct platfo
 	struct device *dev = &pdev->dev;
 
 	bfin_rtc_reset(dev, 0);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-bq32k.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-bq32k.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-bq32k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-bq32k.c	2013-08-25 20:43:22.000000000 -0400
@@ -163,11 +163,6 @@ static int bq32k_probe(struct i2c_client
 	return 0;
 }
 
-static int bq32k_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
 static const struct i2c_device_id bq32k_id[] = {
 	{ "bq32000", 0 },
 	{ }
@@ -180,7 +175,6 @@ static struct i2c_driver bq32k_driver =
 		.owner	= THIS_MODULE,
 	},
 	.probe		= bq32k_probe,
-	.remove		= bq32k_remove,
 	.id_table	= bq32k_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-bq4802.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-bq4802.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-bq4802.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-bq4802.c	2013-08-25 20:43:22.000000000 -0400
@@ -186,13 +186,6 @@ out:
 
 }
 
-static int bq4802_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
-}
-
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:rtc-bq4802");
 
@@ -202,7 +195,6 @@ static struct platform_driver bq4802_dri
 		.owner	= THIS_MODULE,
 	},
 	.probe		= bq4802_probe,
-	.remove		= bq4802_remove,
 };
 
 module_platform_driver(bq4802_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-cmos.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-cmos.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-cmos.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-cmos.c	2013-08-25 20:43:22.000000000 -0400
@@ -326,7 +326,7 @@ static void cmos_irq_disable(struct cmos
 static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
-       unsigned char   mon, mday, hrs, min, sec, rtc_control;
+	unsigned char mon, mday, hrs, min, sec, rtc_control;
 
 	if (!is_valid_irq(cmos->irq))
 		return -EIO;
@@ -556,17 +556,24 @@ static irqreturn_t cmos_interrupt(int ir
 	rtc_control = CMOS_READ(RTC_CONTROL);
 	if (is_hpet_enabled())
 		irqstat = (unsigned long)irq & 0xF0;
-	irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
+
+	/* If we were suspended, RTC_CONTROL may not be accurate since the
+	 * bios may have cleared it.
+	 */
+	if (!cmos_rtc.suspend_ctrl)
+		irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
+	else
+		irqstat &= (cmos_rtc.suspend_ctrl & RTC_IRQMASK) | RTC_IRQF;
 
 	/* All Linux RTC alarms should be treated as if they were oneshot.
 	 * Similar code may be needed in system wakeup paths, in case the
 	 * alarm woke the system.
 	 */
 	if (irqstat & RTC_AIE) {
+		cmos_rtc.suspend_ctrl &= ~RTC_AIE;
 		rtc_control &= ~RTC_AIE;
 		CMOS_WRITE(rtc_control, RTC_CONTROL);
 		hpet_mask_rtc_irq_bit(RTC_AIE);
-
 		CMOS_READ(RTC_INTR_FLAGS);
 	}
 	spin_unlock(&rtc_lock);
@@ -691,7 +698,7 @@ cmos_do_probe(struct device *dev, struct
 	/* FIXME:
 	 * <asm-generic/rtc.h> doesn't know 12-hour mode either.
 	 */
-       if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
+	if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) {
 		dev_warn(dev, "only 24-hr supported\n");
 		retval = -ENXIO;
 		goto cleanup1;
@@ -839,21 +846,23 @@ static inline int cmos_poweroff(struct d
 static int cmos_resume(struct device *dev)
 {
 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
-	unsigned char	tmp = cmos->suspend_ctrl;
+	unsigned char tmp;
 
+	if (cmos->enabled_wake) {
+		if (cmos->wake_off)
+			cmos->wake_off(dev);
+		else
+			disable_irq_wake(cmos->irq);
+		cmos->enabled_wake = 0;
+	}
+
+	spin_lock_irq(&rtc_lock);
+	tmp = cmos->suspend_ctrl;
+	cmos->suspend_ctrl = 0;
 	/* re-enable any irqs previously active */
 	if (tmp & RTC_IRQMASK) {
 		unsigned char	mask;
 
-		if (cmos->enabled_wake) {
-			if (cmos->wake_off)
-				cmos->wake_off(dev);
-			else
-				disable_irq_wake(cmos->irq);
-			cmos->enabled_wake = 0;
-		}
-
-		spin_lock_irq(&rtc_lock);
 		if (device_may_wakeup(dev))
 			hpet_rtc_timer_init();
 
@@ -873,8 +882,8 @@ static int cmos_resume(struct device *de
 			tmp &= ~RTC_AIE;
 			hpet_mask_rtc_irq_bit(RTC_AIE);
 		} while (mask & RTC_AIE);
-		spin_unlock_irq(&rtc_lock);
 	}
+	spin_unlock_irq(&rtc_lock);
 
 	dev_dbg(dev, "resume, ctrl %02x\n", tmp);
 
@@ -991,7 +1000,7 @@ static int cmos_pnp_probe(struct pnp_dev
 {
 	cmos_wake_setup(&pnp->dev);
 
-	if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0))
+	if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0))
 		/* Some machines contain a PNP entry for the RTC, but
 		 * don't define the IRQ. It should always be safe to
 		 * hardcode it in these cases
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-coh901331.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-coh901331.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-coh901331.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-coh901331.c	2013-08-25 20:43:22.000000000 -0400
@@ -152,12 +152,10 @@ static struct rtc_class_ops coh901331_op
 
 static int __exit coh901331_remove(struct platform_device *pdev)
 {
-	struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev);
+	struct coh901331_port *rtap = platform_get_drvdata(pdev);
 
-	if (rtap) {
+	if (rtap)
 		clk_unprepare(rtap->clk);
-		platform_set_drvdata(pdev, NULL);
-	}
 
 	return 0;
 }
@@ -220,7 +218,6 @@ static int __init coh901331_probe(struct
 	return 0;
 
  out_no_rtc:
-	platform_set_drvdata(pdev, NULL);
 	clk_unprepare(rtap->clk);
 	return ret;
 }
@@ -267,18 +264,24 @@ static SIMPLE_DEV_PM_OPS(coh901331_pm_op
 
 static void coh901331_shutdown(struct platform_device *pdev)
 {
-	struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev);
+	struct coh901331_port *rtap = platform_get_drvdata(pdev);
 
 	clk_enable(rtap->clk);
 	writel(0, rtap->virtbase + COH901331_IRQ_MASK);
 	clk_disable_unprepare(rtap->clk);
 }
 
+static const struct of_device_id coh901331_dt_match[] = {
+	{ .compatible = "stericsson,coh901331" },
+	{},
+};
+
 static struct platform_driver coh901331_driver = {
 	.driver = {
 		.name = "rtc-coh901331",
 		.owner = THIS_MODULE,
 		.pm = &coh901331_pm_ops,
+		.of_match_table = coh901331_dt_match,
 	},
 	.remove = __exit_p(coh901331_remove),
 	.shutdown = coh901331_shutdown,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-da9052.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-da9052.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-da9052.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-da9052.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
+#include <linux/err.h>
 
 #include <linux/mfd/da9052/da9052.h>
 #include <linux/mfd/da9052/reg.h>
@@ -249,22 +250,11 @@ static int da9052_rtc_probe(struct platf
 
 	rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 				       &da9052_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc->rtc))
-		return PTR_ERR(rtc->rtc);
-
-	return 0;
-}
-
-static int da9052_rtc_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
+	return PTR_RET(rtc->rtc);
 }
 
 static struct platform_driver da9052_rtc_driver = {
 	.probe	= da9052_rtc_probe,
-	.remove	= da9052_rtc_remove,
 	.driver = {
 		.name	= "da9052-rtc",
 		.owner	= THIS_MODULE,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-da9055.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-da9055.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-da9055.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-da9055.c	2013-08-25 20:43:22.000000000 -0400
@@ -315,13 +315,6 @@ err_rtc:
 
 }
 
-static int da9055_rtc_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
-}
-
 #ifdef CONFIG_PM
 /* Turn off the alarm if it should not be a wake source. */
 static int da9055_rtc_suspend(struct device *dev)
@@ -394,7 +387,6 @@ static const struct dev_pm_ops da9055_rt
 
 static struct platform_driver da9055_rtc_driver = {
 	.probe  = da9055_rtc_probe,
-	.remove = da9055_rtc_remove,
 	.driver = {
 		.name   = "da9055-rtc",
 		.owner  = THIS_MODULE,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-davinci.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-davinci.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-davinci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-davinci.c	2013-08-25 20:43:22.000000000 -0400
@@ -117,7 +117,7 @@
 static DEFINE_SPINLOCK(davinci_rtc_lock);
 
 struct davinci_rtc {
-	struct rtc_device 		*rtc;
+	struct rtc_device		*rtc;
 	void __iomem			*base;
 	resource_size_t			pbase;
 	size_t				base_size;
@@ -526,10 +526,9 @@ static int __init davinci_rtc_probe(stru
 	davinci_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 				    &davinci_rtc_ops, THIS_MODULE);
 	if (IS_ERR(davinci_rtc->rtc)) {
-		ret = PTR_ERR(davinci_rtc->rtc);
 		dev_err(dev, "unable to register RTC device, err %d\n",
 				ret);
-		goto fail1;
+		return PTR_ERR(davinci_rtc->rtc);
 	}
 
 	rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG);
@@ -543,7 +542,7 @@ static int __init davinci_rtc_probe(stru
 			  0, "davinci_rtc", davinci_rtc);
 	if (ret < 0) {
 		dev_err(dev, "unable to register davinci RTC interrupt\n");
-		goto fail1;
+		return ret;
 	}
 
 	/* Enable interrupts */
@@ -556,10 +555,6 @@ static int __init davinci_rtc_probe(stru
 	device_init_wakeup(&pdev->dev, 0);
 
 	return 0;
-
-fail1:
-	platform_set_drvdata(pdev, NULL);
-	return ret;
 }
 
 static int __exit davinci_rtc_remove(struct platform_device *pdev)
@@ -570,8 +565,6 @@ static int __exit davinci_rtc_remove(str
 
 	rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-dm355evm.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-dm355evm.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-dm355evm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-dm355evm.c	2013-08-25 20:43:22.000000000 -0400
@@ -139,19 +139,12 @@ static int dm355evm_rtc_probe(struct pla
 	return 0;
 }
 
-static int dm355evm_rtc_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-	return 0;
-}
-
 /*
  * I2C is used to talk to the MSP430, but this platform device is
  * exposed by an MFD driver that manages I2C communications.
  */
 static struct platform_driver rtc_dm355evm_driver = {
 	.probe		= dm355evm_rtc_probe,
-	.remove		= dm355evm_rtc_remove,
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= "rtc-dm355evm",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds1216.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1216.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds1216.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1216.c	2013-08-25 20:43:22.000000000 -0400
@@ -167,34 +167,17 @@ static int __init ds1216_rtc_probe(struc
 	return 0;
 }
 
-static int __exit ds1216_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 static struct platform_driver ds1216_rtc_platform_driver = {
 	.driver		= {
 		.name	= "rtc-ds1216",
 		.owner	= THIS_MODULE,
 	},
-	.remove		= __exit_p(ds1216_rtc_remove),
 };
 
-static int __init ds1216_rtc_init(void)
-{
-	return platform_driver_probe(&ds1216_rtc_platform_driver, ds1216_rtc_probe);
-}
-
-static void __exit ds1216_rtc_exit(void)
-{
-	platform_driver_unregister(&ds1216_rtc_platform_driver);
-}
+module_platform_driver_probe(ds1216_rtc_platform_driver, ds1216_rtc_probe);
 
 MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
 MODULE_DESCRIPTION("DS1216 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:rtc-ds1216");
-
-module_init(ds1216_rtc_init);
-module_exit(ds1216_rtc_exit);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds1286.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1286.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds1286.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1286.c	2013-08-25 20:43:22.000000000 -0400
@@ -353,18 +353,12 @@ static int ds1286_probe(struct platform_
 	return 0;
 }
 
-static int ds1286_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 static struct platform_driver ds1286_platform_driver = {
 	.driver		= {
 		.name	= "rtc-ds1286",
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ds1286_probe,
-	.remove		= ds1286_remove,
 };
 
 module_platform_driver(ds1286_platform_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds1302.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1302.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds1302.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1302.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,8 +23,12 @@
 #define	RTC_CMD_READ	0x81		/* Read command */
 #define	RTC_CMD_WRITE	0x80		/* Write command */
 
+#define	RTC_CMD_WRITE_ENABLE	0x00		/* Write enable */
+#define	RTC_CMD_WRITE_DISABLE	0x80		/* Write disable */
+
 #define RTC_ADDR_RAM0	0x20		/* Address of RAM0 */
 #define RTC_ADDR_TCR	0x08		/* Address of trickle charge register */
+#define	RTC_ADDR_CTRL	0x07		/* Address of control register */
 #define	RTC_ADDR_YEAR	0x06		/* Address of year register */
 #define	RTC_ADDR_DAY	0x05		/* Address of day of week register */
 #define	RTC_ADDR_MON	0x04		/* Address of month register */
@@ -161,6 +165,7 @@ static int ds1302_rtc_read_time(struct d
 
 static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
+	ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_ENABLE);
 	/* Stop RTC */
 	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
 
@@ -175,6 +180,8 @@ static int ds1302_rtc_set_time(struct de
 	/* Start RTC */
 	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
 
+	ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_DISABLE);
+
 	return 0;
 }
 
@@ -234,19 +241,11 @@ static int __init ds1302_rtc_probe(struc
 	return 0;
 }
 
-static int __exit ds1302_rtc_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
-}
-
 static struct platform_driver ds1302_platform_driver = {
 	.driver		= {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
 	},
-	.remove		= __exit_p(ds1302_rtc_remove),
 };
 
 module_platform_driver_probe(ds1302_platform_driver, ds1302_rtc_probe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds1305.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1305.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds1305.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1305.c	2013-08-25 20:43:22.000000000 -0400
@@ -158,7 +158,7 @@ static int ds1305_alarm_irq_enable(struc
 			goto done;
 		buf[1] &= ~DS1305_AEI0;
 	}
-	err = spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0);
+	err = spi_write_then_read(ds1305->spi, buf, sizeof(buf), NULL, 0);
 	if (err >= 0)
 		ds1305->ctrl[0] = buf[1];
 done:
@@ -181,8 +181,8 @@ static int ds1305_get_time(struct device
 	/* Use write-then-read to get all the date/time registers
 	 * since dma from stack is nonportable
 	 */
-	status = spi_write_then_read(ds1305->spi, &addr, sizeof addr,
-			buf, sizeof buf);
+	status = spi_write_then_read(ds1305->spi, &addr, sizeof(addr),
+			buf, sizeof(buf));
 	if (status < 0)
 		return status;
 
@@ -237,7 +237,7 @@ static int ds1305_set_time(struct device
 		buf[4], buf[5], buf[6], buf[7]);
 
 	/* use write-then-read since dma from stack is nonportable */
-	return spi_write_then_read(ds1305->spi, buf, sizeof buf,
+	return spi_write_then_read(ds1305->spi, buf, sizeof(buf),
 			NULL, 0);
 }
 
@@ -286,8 +286,8 @@ static int ds1305_get_alarm(struct devic
 	 * of EFI status is at best fragile anyway (given IRQ handlers).
 	 */
 	addr = DS1305_CONTROL;
-	status = spi_write_then_read(spi, &addr, sizeof addr,
-			ds1305->ctrl, sizeof ds1305->ctrl);
+	status = spi_write_then_read(spi, &addr, sizeof(addr),
+			ds1305->ctrl, sizeof(ds1305->ctrl));
 	if (status < 0)
 		return status;
 
@@ -296,8 +296,8 @@ static int ds1305_get_alarm(struct devic
 
 	/* get and check ALM0 registers */
 	addr = DS1305_ALM0(DS1305_SEC);
-	status = spi_write_then_read(spi, &addr, sizeof addr,
-			buf, sizeof buf);
+	status = spi_write_then_read(spi, &addr, sizeof(addr),
+			buf, sizeof(buf));
 	if (status < 0)
 		return status;
 
@@ -381,7 +381,7 @@ static int ds1305_set_alarm(struct devic
 		"alm0 write", buf[1 + DS1305_SEC], buf[1 + DS1305_MIN],
 		buf[1 + DS1305_HOUR], buf[1 + DS1305_WDAY]);
 
-	status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);
+	status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
 	if (status < 0)
 		return status;
 
@@ -474,7 +474,7 @@ static void ds1305_work(struct work_stru
 	buf[1] = ds1305->ctrl[0];
 	buf[2] = 0;
 
-	status = spi_write_then_read(spi, buf, sizeof buf,
+	status = spi_write_then_read(spi, buf, sizeof(buf),
 			NULL, 0);
 	if (status < 0)
 		dev_dbg(&spi->dev, "clear irq --> %d\n", status);
@@ -627,8 +627,8 @@ static int ds1305_probe(struct spi_devic
 
 	/* read and cache control registers */
 	addr = DS1305_CONTROL;
-	status = spi_write_then_read(spi, &addr, sizeof addr,
-			ds1305->ctrl, sizeof ds1305->ctrl);
+	status = spi_write_then_read(spi, &addr, sizeof(addr),
+			ds1305->ctrl, sizeof(ds1305->ctrl));
 	if (status < 0) {
 		dev_dbg(&spi->dev, "can't %s, %d\n",
 				"read", status);
@@ -659,7 +659,7 @@ static int ds1305_probe(struct spi_devic
 
 		buf[0] = DS1305_WRITE | DS1305_CONTROL;
 		buf[1] = ds1305->ctrl[0];
-		status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);
+		status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
 
 		dev_dbg(&spi->dev, "clear WP --> %d\n", status);
 		if (status < 0)
@@ -713,7 +713,7 @@ static int ds1305_probe(struct spi_devic
 		buf[1] = ds1305->ctrl[0];
 		buf[2] = ds1305->ctrl[1];
 		buf[3] = ds1305->ctrl[2];
-		status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);
+		status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
 		if (status < 0) {
 			dev_dbg(&spi->dev, "can't %s, %d\n",
 					"write", status);
@@ -725,8 +725,8 @@ static int ds1305_probe(struct spi_devic
 
 	/* see if non-Linux software set up AM/PM mode */
 	addr = DS1305_HOUR;
-	status = spi_write_then_read(spi, &addr, sizeof addr,
-				&value, sizeof value);
+	status = spi_write_then_read(spi, &addr, sizeof(addr),
+				&value, sizeof(value));
 	if (status < 0) {
 		dev_dbg(&spi->dev, "read HOUR --> %d\n", status);
 		return status;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds1307.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1307.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds1307.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1307.c	2013-08-25 20:43:22.000000000 -0400
@@ -683,7 +683,7 @@ static int ds1307_probe(struct i2c_clien
 	    && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
 		return -EIO;
 
-	ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL);
+	ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL);
 	if (!ds1307)
 		return -ENOMEM;
 
@@ -715,7 +715,7 @@ static int ds1307_probe(struct i2c_clien
 		if (tmp != 2) {
 			dev_dbg(&client->dev, "read error %d\n", tmp);
 			err = -EIO;
-			goto exit_free;
+			goto exit;
 		}
 
 		/* oscillator off?  turn it on, so clock can tick. */
@@ -754,7 +754,7 @@ static int ds1307_probe(struct i2c_clien
 		if (tmp != 2) {
 			dev_dbg(&client->dev, "read error %d\n", tmp);
 			err = -EIO;
-			goto exit_free;
+			goto exit;
 		}
 
 		/* oscillator off?  turn it on, so clock can tick. */
@@ -798,7 +798,7 @@ static int ds1307_probe(struct i2c_clien
 			if (tmp != 2) {
 				dev_dbg(&client->dev, "read error %d\n", tmp);
 				err = -EIO;
-				goto exit_free;
+				goto exit;
 			}
 
 			/* correct hour */
@@ -826,7 +826,7 @@ read_rtc:
 	if (tmp != 8) {
 		dev_dbg(&client->dev, "read error %d\n", tmp);
 		err = -EIO;
-		goto exit_free;
+		goto exit;
 	}
 
 	/*
@@ -868,7 +868,7 @@ read_rtc:
 		if (tmp < 0) {
 			dev_dbg(&client->dev, "read error %d\n", tmp);
 			err = -EIO;
-			goto exit_free;
+			goto exit;
 		}
 
 		/* oscillator fault?  clear flag, and warn */
@@ -927,13 +927,13 @@ read_rtc:
 				bin2bcd(tmp));
 	}
 
-	ds1307->rtc = rtc_device_register(client->name, &client->dev,
+	ds1307->rtc = devm_rtc_device_register(&client->dev, client->name,
 				&ds13xx_rtc_ops, THIS_MODULE);
 	if (IS_ERR(ds1307->rtc)) {
 		err = PTR_ERR(ds1307->rtc);
 		dev_err(&client->dev,
 			"unable to register the class device\n");
-		goto exit_free;
+		goto exit;
 	}
 
 	if (want_irq) {
@@ -942,7 +942,7 @@ read_rtc:
 		if (err) {
 			dev_err(&client->dev,
 				"unable to request IRQ!\n");
-			goto exit_irq;
+			goto exit;
 		}
 
 		device_set_wakeup_capable(&client->dev, 1);
@@ -951,11 +951,12 @@ read_rtc:
 	}
 
 	if (chip->nvram_size) {
-		ds1307->nvram = kzalloc(sizeof(struct bin_attribute),
-							GFP_KERNEL);
+		ds1307->nvram = devm_kzalloc(&client->dev,
+					sizeof(struct bin_attribute),
+					GFP_KERNEL);
 		if (!ds1307->nvram) {
 			err = -ENOMEM;
-			goto exit_nvram;
+			goto exit;
 		}
 		ds1307->nvram->attr.name = "nvram";
 		ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR;
@@ -965,21 +966,15 @@ read_rtc:
 		ds1307->nvram->size = chip->nvram_size;
 		ds1307->nvram_offset = chip->nvram_offset;
 		err = sysfs_create_bin_file(&client->dev.kobj, ds1307->nvram);
-		if (err) {
-			kfree(ds1307->nvram);
-			goto exit_nvram;
-		}
+		if (err)
+			goto exit;
 		set_bit(HAS_NVRAM, &ds1307->flags);
 		dev_info(&client->dev, "%zu bytes nvram\n", ds1307->nvram->size);
 	}
 
 	return 0;
 
-exit_nvram:
-exit_irq:
-	rtc_device_unregister(ds1307->rtc);
-exit_free:
-	kfree(ds1307);
+exit:
 	return err;
 }
 
@@ -992,13 +987,9 @@ static int ds1307_remove(struct i2c_clie
 		cancel_work_sync(&ds1307->work);
 	}
 
-	if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) {
+	if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
 		sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram);
-		kfree(ds1307->nvram);
-	}
 
-	rtc_device_unregister(ds1307->rtc);
-	kfree(ds1307);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds1374.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1374.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds1374.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1374.c	2013-08-25 20:43:22.000000000 -0400
@@ -65,7 +65,7 @@ struct ds1374 {
 static struct i2c_driver ds1374_driver;
 
 static int ds1374_read_rtc(struct i2c_client *client, u32 *time,
-                           int reg, int nbytes)
+			   int reg, int nbytes)
 {
 	u8 buf[4];
 	int ret;
@@ -90,7 +90,7 @@ static int ds1374_read_rtc(struct i2c_cl
 }
 
 static int ds1374_write_rtc(struct i2c_client *client, u32 time,
-                            int reg, int nbytes)
+			    int reg, int nbytes)
 {
 	u8 buf[4];
 	int i;
@@ -119,8 +119,7 @@ static int ds1374_check_rtc_status(struc
 
 	if (stat & DS1374_REG_SR_OSF)
 		dev_warn(&client->dev,
-		         "oscillator discontinuity flagged, "
-		         "time unreliable\n");
+			 "oscillator discontinuity flagged, time unreliable\n");
 
 	stat &= ~(DS1374_REG_SR_OSF | DS1374_REG_SR_AF);
 
@@ -363,7 +362,7 @@ static int ds1374_probe(struct i2c_clien
 
 	if (client->irq > 0) {
 		ret = devm_request_irq(&client->dev, client->irq, ds1374_irq, 0,
-		                  "ds1374", client);
+					"ds1374", client);
 		if (ret) {
 			dev_err(&client->dev, "unable to request IRQ\n");
 			return ret;
@@ -373,7 +372,7 @@ static int ds1374_probe(struct i2c_clien
 	}
 
 	ds1374->rtc = devm_rtc_device_register(&client->dev, client->name,
-	                                  &ds1374_rtc_ops, THIS_MODULE);
+						&ds1374_rtc_ops, THIS_MODULE);
 	if (IS_ERR(ds1374->rtc)) {
 		dev_err(&client->dev, "unable to register the class device\n");
 		return PTR_ERR(ds1374->rtc);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds1390.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1390.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds1390.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1390.c	2013-08-25 20:43:22.000000000 -0400
@@ -154,18 +154,12 @@ static int ds1390_probe(struct spi_devic
 	return res;
 }
 
-static int ds1390_remove(struct spi_device *spi)
-{
-	return 0;
-}
-
 static struct spi_driver ds1390_driver = {
 	.driver = {
 		.name	= "rtc-ds1390",
 		.owner	= THIS_MODULE,
 	},
 	.probe	= ds1390_probe,
-	.remove = ds1390_remove,
 };
 
 module_spi_driver(ds1390_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds1511.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1511.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds1511.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1511.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,31 +104,31 @@ static DEFINE_SPINLOCK(ds1511_lock);
 static __iomem char *ds1511_base;
 static u32 reg_spacing = 1;
 
- static noinline void
+static noinline void
 rtc_write(uint8_t val, uint32_t reg)
 {
 	writeb(val, ds1511_base + (reg * reg_spacing));
 }
 
- static inline void
+static inline void
 rtc_write_alarm(uint8_t val, enum ds1511reg reg)
 {
 	rtc_write((val | 0x80), reg);
 }
 
- static noinline uint8_t
+static noinline uint8_t
 rtc_read(enum ds1511reg reg)
 {
 	return readb(ds1511_base + (reg * reg_spacing));
 }
 
- static inline void
+static inline void
 rtc_disable_update(void)
 {
 	rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD);
 }
 
- static void
+static void
 rtc_enable_update(void)
 {
 	rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD);
@@ -145,7 +145,7 @@ rtc_enable_update(void)
  * just enough code to set the watchdog timer so that it
  * will reboot the system
  */
- void
+void
 ds1511_wdog_set(unsigned long deciseconds)
 {
 	/*
@@ -163,7 +163,7 @@ ds1511_wdog_set(unsigned long decisecond
 	rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD);
 }
 
- void
+void
 ds1511_wdog_disable(void)
 {
 	/*
@@ -191,13 +191,12 @@ static int ds1511_rtc_set_time(struct de
 	/*
 	 * won't have to change this for a while
 	 */
-	if (rtc_tm->tm_year < 1900) {
+	if (rtc_tm->tm_year < 1900)
 		rtc_tm->tm_year += 1900;
-	}
 
-	if (rtc_tm->tm_year < 1970) {
+	if (rtc_tm->tm_year < 1970)
 		return -EINVAL;
-	}
+
 	yrs = rtc_tm->tm_year % 100;
 	cen = rtc_tm->tm_year / 100;
 	mon = rtc_tm->tm_mon + 1;   /* tm_mon starts at zero */
@@ -207,17 +206,14 @@ static int ds1511_rtc_set_time(struct de
 	min = rtc_tm->tm_min;
 	sec = rtc_tm->tm_sec;
 
-	if ((mon > 12) || (day == 0)) {
+	if ((mon > 12) || (day == 0))
 		return -EINVAL;
-	}
 
-	if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year)) {
+	if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year))
 		return -EINVAL;
-	}
 
-	if ((hrs >= 24) || (min >= 60) || (sec >= 60)) {
+	if ((hrs >= 24) || (min >= 60) || (sec >= 60))
 		return -EINVAL;
-	}
 
 	/*
 	 * each register is a different number of valid bits
@@ -299,7 +295,7 @@ static int ds1511_rtc_read_time(struct d
  * date/hours/mins/secs matches.  the ds1511 has many more
  * permutations, but the kernel doesn't.
  */
- static void
+static void
 ds1511_rtc_update_alarm(struct rtc_plat_data *pdata)
 {
 	unsigned long flags;
@@ -322,7 +318,7 @@ ds1511_rtc_update_alarm(struct rtc_plat_
 	spin_unlock_irqrestore(&pdata->lock, flags);
 }
 
- static int
+static int
 ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -335,14 +331,14 @@ ds1511_rtc_set_alarm(struct device *dev,
 	pdata->alrm_hour = alrm->time.tm_hour;
 	pdata->alrm_min = alrm->time.tm_min;
 	pdata->alrm_sec = alrm->time.tm_sec;
-	if (alrm->enabled) {
+	if (alrm->enabled)
 		pdata->irqen |= RTC_AF;
-	}
+
 	ds1511_rtc_update_alarm(pdata);
 	return 0;
 }
 
- static int
+static int
 ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -359,7 +355,7 @@ ds1511_rtc_read_alarm(struct device *dev
 	return 0;
 }
 
- static irqreturn_t
+static irqreturn_t
 ds1511_interrupt(int irq, void *dev_id)
 {
 	struct platform_device *pdev = dev_id;
@@ -406,7 +402,7 @@ static const struct rtc_class_ops ds1511
 	.alarm_irq_enable	= ds1511_rtc_alarm_irq_enable,
 };
 
- static ssize_t
+static ssize_t
 ds1511_nvram_read(struct file *filp, struct kobject *kobj,
 		  struct bin_attribute *ba,
 		  char *buf, loff_t pos, size_t size)
@@ -417,26 +413,26 @@ ds1511_nvram_read(struct file *filp, str
 	 * if count is more than one, turn on "burst" mode
 	 * turn it off when you're done
 	 */
-	if (size > 1) {
+	if (size > 1)
 		rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD);
-	}
-	if (pos > DS1511_RAM_MAX) {
+
+	if (pos > DS1511_RAM_MAX)
 		pos = DS1511_RAM_MAX;
-	}
-	if (size + pos > DS1511_RAM_MAX + 1) {
+
+	if (size + pos > DS1511_RAM_MAX + 1)
 		size = DS1511_RAM_MAX - pos + 1;
-	}
+
 	rtc_write(pos, DS1511_RAMADDR_LSB);
-	for (count = 0; size > 0; count++, size--) {
+	for (count = 0; size > 0; count++, size--)
 		*buf++ = rtc_read(DS1511_RAMDATA);
-	}
-	if (count > 1) {
+
+	if (count > 1)
 		rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD);
-	}
+
 	return count;
 }
 
- static ssize_t
+static ssize_t
 ds1511_nvram_write(struct file *filp, struct kobject *kobj,
 		   struct bin_attribute *bin_attr,
 		   char *buf, loff_t pos, size_t size)
@@ -447,22 +443,22 @@ ds1511_nvram_write(struct file *filp, st
 	 * if count is more than one, turn on "burst" mode
 	 * turn it off when you're done
 	 */
-	if (size > 1) {
+	if (size > 1)
 		rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD);
-	}
-	if (pos > DS1511_RAM_MAX) {
+
+	if (pos > DS1511_RAM_MAX)
 		pos = DS1511_RAM_MAX;
-	}
-	if (size + pos > DS1511_RAM_MAX + 1) {
+
+	if (size + pos > DS1511_RAM_MAX + 1)
 		size = DS1511_RAM_MAX - pos + 1;
-	}
+
 	rtc_write(pos, DS1511_RAMADDR_LSB);
-	for (count = 0; size > 0; count++, size--) {
+	for (count = 0; size > 0; count++, size--)
 		rtc_write(*buf++, DS1511_RAMDATA);
-	}
-	if (count > 1) {
+
+	if (count > 1)
 		rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD);
-	}
+
 	return count;
 }
 
@@ -484,9 +480,9 @@ static int ds1511_rtc_probe(struct platf
 	int ret = 0;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
+	if (!res)
 		return -ENODEV;
-	}
+
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return -ENOMEM;
@@ -518,9 +514,8 @@ static int ds1511_rtc_probe(struct platf
 	/*
 	 * check for a dying bat-tree
 	 */
-	if (rtc_read(RTC_CMD1) & DS1511_BLF1) {
+	if (rtc_read(RTC_CMD1) & DS1511_BLF1)
 		dev_warn(&pdev->dev, "voltage-low detected.\n");
-	}
 
 	spin_lock_init(&pdata->lock);
 	platform_set_drvdata(pdev, pdata);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds1672.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1672.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds1672.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds1672.c	2013-08-25 20:43:22.000000000 -0400
@@ -153,11 +153,6 @@ static const struct rtc_class_ops ds1672
 	.set_mmss = ds1672_rtc_set_mmss,
 };
 
-static int ds1672_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
 static int ds1672_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -210,7 +205,6 @@ static struct i2c_driver ds1672_driver =
 		   .name = "rtc-ds1672",
 		   },
 	.probe = &ds1672_probe,
-	.remove = &ds1672_remove,
 	.id_table = ds1672_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ds3234.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds3234.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ds3234.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ds3234.c	2013-08-25 20:43:22.000000000 -0400
@@ -73,7 +73,7 @@ static int ds3234_read_time(struct devic
 	dt->tm_wday	= bcd2bin(buf[3]) - 1; /* 0 = Sun */
 	dt->tm_mday	= bcd2bin(buf[4]);
 	dt->tm_mon	= bcd2bin(buf[5] & 0x1f) - 1; /* 0 = Jan */
-	dt->tm_year 	= bcd2bin(buf[6] & 0xff) + 100; /* Assume 20YY */
+	dt->tm_year	= bcd2bin(buf[6] & 0xff) + 100; /* Assume 20YY */
 
 	return rtc_valid_tm(dt);
 }
@@ -156,18 +156,12 @@ static int ds3234_probe(struct spi_devic
 	return 0;
 }
 
-static int ds3234_remove(struct spi_device *spi)
-{
-	return 0;
-}
-
 static struct spi_driver ds3234_driver = {
 	.driver = {
 		.name	 = "ds3234",
 		.owner	= THIS_MODULE,
 	},
 	.probe	 = ds3234_probe,
-	.remove = ds3234_remove,
 };
 
 module_spi_driver(ds3234_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-efi.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-efi.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-efi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-efi.c	2013-08-25 20:43:22.000000000 -0400
@@ -201,17 +201,11 @@ static int __init efi_rtc_probe(struct p
 	return 0;
 }
 
-static int __exit efi_rtc_remove(struct platform_device *dev)
-{
-	return 0;
-}
-
 static struct platform_driver efi_rtc_driver = {
 	.driver = {
 		.name = "rtc-efi",
 		.owner = THIS_MODULE,
 	},
-	.remove = __exit_p(efi_rtc_remove),
 };
 
 module_platform_driver_probe(efi_rtc_driver, efi_rtc_probe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-em3027.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-em3027.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-em3027.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-em3027.c	2013-08-25 20:43:22.000000000 -0400
@@ -131,11 +131,6 @@ static int em3027_probe(struct i2c_clien
 	return 0;
 }
 
-static int em3027_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
 static struct i2c_device_id em3027_id[] = {
 	{ "em3027", 0 },
 	{ }
@@ -146,7 +141,6 @@ static struct i2c_driver em3027_driver =
 		   .name = "rtc-em3027",
 	},
 	.probe = &em3027_probe,
-	.remove = &em3027_remove,
 	.id_table = em3027_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ep93xx.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ep93xx.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ep93xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ep93xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -167,7 +167,6 @@ static int ep93xx_rtc_probe(struct platf
 	return 0;
 
 exit:
-	platform_set_drvdata(pdev, NULL);
 	pdev->dev.platform_data = NULL;
 	return err;
 }
@@ -175,7 +174,6 @@ exit:
 static int ep93xx_rtc_remove(struct platform_device *pdev)
 {
 	sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
-	platform_set_drvdata(pdev, NULL);
 	pdev->dev.platform_data = NULL;
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-fm3130.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-fm3130.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-fm3130.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-fm3130.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,7 +47,7 @@
 
 struct fm3130 {
 	u8			reg_addr_time;
-	u8 			reg_addr_alarm;
+	u8			reg_addr_alarm;
 	u8			regs[15];
 	struct i2c_msg		msg[4];
 	struct i2c_client	*client;
@@ -520,18 +520,12 @@ exit_free:
 	return err;
 }
 
-static int fm3130_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
 static struct i2c_driver fm3130_driver = {
 	.driver = {
 		.name	= "rtc-fm3130",
 		.owner	= THIS_MODULE,
 	},
 	.probe		= fm3130_probe,
-	.remove		= fm3130_remove,
 	.id_table	= fm3130_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-generic.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-generic.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-generic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-generic.c	2013-08-25 20:43:22.000000000 -0400
@@ -48,17 +48,11 @@ static int __init generic_rtc_probe(stru
 	return 0;
 }
 
-static int __exit generic_rtc_remove(struct platform_device *dev)
-{
-	return 0;
-}
-
 static struct platform_driver generic_rtc_driver = {
 	.driver = {
 		.name = "rtc-generic",
 		.owner = THIS_MODULE,
 	},
-	.remove = __exit_p(generic_rtc_remove),
 };
 
 module_platform_driver_probe(generic_rtc_driver, generic_rtc_probe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-hid-sensor-time.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-hid-sensor-time.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-hid-sensor-time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-hid-sensor-time.c	2013-08-25 20:43:22.000000000 -0400
@@ -76,6 +76,20 @@ static int hid_time_proc_event(struct hi
 	return 0;
 }
 
+static u32 hid_time_value(size_t raw_len, char *raw_data)
+{
+	switch (raw_len) {
+	case 1:
+		return *(u8 *)raw_data;
+	case 2:
+		return *(u16 *)raw_data;
+	case 4:
+		return *(u32 *)raw_data;
+	default:
+		return (u32)(~0U); /* 0xff... or -1 to denote an error */
+	}
+}
+
 static int hid_time_capture_sample(struct hid_sensor_hub_device *hsdev,
 				unsigned usage_id, size_t raw_len,
 				char *raw_data, void *priv)
@@ -85,26 +99,35 @@ static int hid_time_capture_sample(struc
 
 	switch (usage_id) {
 	case HID_USAGE_SENSOR_TIME_YEAR:
-		time_buf->tm_year = *(u8 *)raw_data;
-		if (time_buf->tm_year < 70)
-			/* assume we are in 1970...2069 */
-			time_buf->tm_year += 100;
+		/*
+		 * The draft for HID-sensors (HUTRR39) currently doesn't define
+		 * the range for the year attribute. Therefor we support
+		 * 8 bit (0-99) and 16 or 32 bits (full) as size for the year.
+		 */
+		if (raw_len == 1) {
+			time_buf->tm_year = *(u8 *)raw_data;
+			if (time_buf->tm_year < 70)
+				/* assume we are in 1970...2069 */
+				time_buf->tm_year += 100;
+		} else
+			time_buf->tm_year =
+				(int)hid_time_value(raw_len, raw_data)-1900;
 		break;
 	case HID_USAGE_SENSOR_TIME_MONTH:
-		/* sensor sending the month as 1-12, we need 0-11 */
-		time_buf->tm_mon = *(u8 *)raw_data-1;
+		/* sensors are sending the month as 1-12, we need 0-11 */
+		time_buf->tm_mon = (int)hid_time_value(raw_len, raw_data)-1;
 		break;
 	case HID_USAGE_SENSOR_TIME_DAY:
-		time_buf->tm_mday = *(u8 *)raw_data;
+		time_buf->tm_mday = (int)hid_time_value(raw_len, raw_data);
 		break;
 	case HID_USAGE_SENSOR_TIME_HOUR:
-		time_buf->tm_hour = *(u8 *)raw_data;
+		time_buf->tm_hour = (int)hid_time_value(raw_len, raw_data);
 		break;
 	case HID_USAGE_SENSOR_TIME_MINUTE:
-		time_buf->tm_min = *(u8 *)raw_data;
+		time_buf->tm_min = (int)hid_time_value(raw_len, raw_data);
 		break;
 	case HID_USAGE_SENSOR_TIME_SECOND:
-		time_buf->tm_sec = *(u8 *)raw_data;
+		time_buf->tm_sec = (int)hid_time_value(raw_len, raw_data);
 		break;
 	default:
 		return -EINVAL;
@@ -150,9 +173,10 @@ static int hid_time_parse_report(struct
 				"not all needed attributes inside the same report!\n");
 			return -EINVAL;
 		}
-		if (time_state->info[i].size != 1) {
+		if (time_state->info[i].size == 3 ||
+				time_state->info[i].size > 4) {
 			dev_err(&pdev->dev,
-				"attribute '%s' not 8 bits wide!\n",
+				"attribute '%s' not 8, 16 or 32 bits wide!\n",
 				hid_time_attrib_name(
 					time_state->info[i].attrib_id));
 			return -EINVAL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-isl12022.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-isl12022.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-isl12022.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-isl12022.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/rtc.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/err.h>
 
 #define DRV_VERSION "0.1"
 
@@ -267,15 +268,7 @@ static int isl12022_probe(struct i2c_cli
 	isl12022->rtc = devm_rtc_device_register(&client->dev,
 					isl12022_driver.driver.name,
 					&isl12022_rtc_ops, THIS_MODULE);
-	if (IS_ERR(isl12022->rtc))
-		return PTR_ERR(isl12022->rtc);
-
-	return 0;
-}
-
-static int isl12022_remove(struct i2c_client *client)
-{
-	return 0;
+	return PTR_RET(isl12022->rtc);
 }
 
 static const struct i2c_device_id isl12022_id[] = {
@@ -289,7 +282,6 @@ static struct i2c_driver isl12022_driver
 		.name	= "rtc-isl12022",
 	},
 	.probe		= isl12022_probe,
-	.remove		= isl12022_remove,
 	.id_table	= isl12022_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-jz4740.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-jz4740.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-jz4740.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-jz4740.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,6 +14,7 @@
  *
  */
 
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -216,37 +217,34 @@ static int jz4740_rtc_probe(struct platf
 	struct jz4740_rtc *rtc;
 	uint32_t scratchpad;
 
-	rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
+	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
 	if (!rtc)
 		return -ENOMEM;
 
 	rtc->irq = platform_get_irq(pdev, 0);
 	if (rtc->irq < 0) {
-		ret = -ENOENT;
 		dev_err(&pdev->dev, "Failed to get platform irq\n");
-		goto err_free;
+		return -ENOENT;
 	}
 
 	rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!rtc->mem) {
-		ret = -ENOENT;
 		dev_err(&pdev->dev, "Failed to get platform mmio memory\n");
-		goto err_free;
+		return -ENOENT;
 	}
 
-	rtc->mem = request_mem_region(rtc->mem->start, resource_size(rtc->mem),
-					pdev->name);
+	rtc->mem = devm_request_mem_region(&pdev->dev, rtc->mem->start,
+					resource_size(rtc->mem), pdev->name);
 	if (!rtc->mem) {
-		ret = -EBUSY;
 		dev_err(&pdev->dev, "Failed to request mmio memory region\n");
-		goto err_free;
+		return -EBUSY;
 	}
 
-	rtc->base = ioremap_nocache(rtc->mem->start, resource_size(rtc->mem));
+	rtc->base = devm_ioremap_nocache(&pdev->dev, rtc->mem->start,
+					resource_size(rtc->mem));
 	if (!rtc->base) {
-		ret = -EBUSY;
 		dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
-		goto err_release_mem_region;
+		return -EBUSY;
 	}
 
 	spin_lock_init(&rtc->lock);
@@ -255,19 +253,19 @@ static int jz4740_rtc_probe(struct platf
 
 	device_init_wakeup(&pdev->dev, 1);
 
-	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops,
-					THIS_MODULE);
+	rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+					&jz4740_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc)) {
 		ret = PTR_ERR(rtc->rtc);
 		dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret);
-		goto err_iounmap;
+		return ret;
 	}
 
-	ret = request_irq(rtc->irq, jz4740_rtc_irq, 0,
+	ret = devm_request_irq(&pdev->dev, rtc->irq, jz4740_rtc_irq, 0,
 				pdev->name, rtc);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret);
-		goto err_unregister_rtc;
+		return ret;
 	}
 
 	scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD);
@@ -276,46 +274,13 @@ static int jz4740_rtc_probe(struct platf
 		ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0);
 		if (ret) {
 			dev_err(&pdev->dev, "Could not write write to RTC registers\n");
-			goto err_free_irq;
+			return ret;
 		}
 	}
 
 	return 0;
-
-err_free_irq:
-	free_irq(rtc->irq, rtc);
-err_unregister_rtc:
-	rtc_device_unregister(rtc->rtc);
-err_iounmap:
-	platform_set_drvdata(pdev, NULL);
-	iounmap(rtc->base);
-err_release_mem_region:
-	release_mem_region(rtc->mem->start, resource_size(rtc->mem));
-err_free:
-	kfree(rtc);
-
-	return ret;
-}
-
-static int jz4740_rtc_remove(struct platform_device *pdev)
-{
-	struct jz4740_rtc *rtc = platform_get_drvdata(pdev);
-
-	free_irq(rtc->irq, rtc);
-
-	rtc_device_unregister(rtc->rtc);
-
-	iounmap(rtc->base);
-	release_mem_region(rtc->mem->start, resource_size(rtc->mem));
-
-	kfree(rtc);
-
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
 }
 
-
 #ifdef CONFIG_PM
 static int jz4740_rtc_suspend(struct device *dev)
 {
@@ -347,7 +312,6 @@ static const struct dev_pm_ops jz4740_pm
 
 static struct platform_driver jz4740_rtc_driver = {
 	.probe	 = jz4740_rtc_probe,
-	.remove	 = jz4740_rtc_remove,
 	.driver	 = {
 		.name  = "jz4740-rtc",
 		.owner = THIS_MODULE,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-lp8788.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-lp8788.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-lp8788.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-lp8788.c	2013-08-25 20:43:22.000000000 -0400
@@ -312,16 +312,8 @@ static int lp8788_rtc_probe(struct platf
 	return 0;
 }
 
-static int lp8788_rtc_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
-}
-
 static struct platform_driver lp8788_rtc_driver = {
 	.probe = lp8788_rtc_probe,
-	.remove = lp8788_rtc_remove,
 	.driver = {
 		.name = LP8788_DEV_RTC,
 		.owner = THIS_MODULE,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-lpc32xx.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-lpc32xx.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-lpc32xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-lpc32xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -277,7 +277,6 @@ static int lpc32xx_rtc_probe(struct plat
 					&lpc32xx_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc)) {
 		dev_err(&pdev->dev, "Can't get RTC\n");
-		platform_set_drvdata(pdev, NULL);
 		return PTR_ERR(rtc->rtc);
 	}
 
@@ -306,8 +305,6 @@ static int lpc32xx_rtc_remove(struct pla
 	if (rtc->irq >= 0)
 		device_init_wakeup(&pdev->dev, 0);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ls1x.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ls1x.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ls1x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ls1x.c	2013-08-25 20:43:22.000000000 -0400
@@ -185,19 +185,11 @@ err:
 	return ret;
 }
 
-static int ls1x_rtc_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
-}
-
 static struct platform_driver  ls1x_rtc_driver = {
 	.driver		= {
 		.name	= "ls1x-rtc",
 		.owner	= THIS_MODULE,
 	},
-	.remove		= ls1x_rtc_remove,
 	.probe		= ls1x_rtc_probe,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-m41t80.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m41t80.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-m41t80.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m41t80.c	2013-08-25 20:43:22.000000000 -0400
@@ -168,7 +168,7 @@ static int m41t80_set_datetime(struct i2
 	buf[M41T80_REG_MIN] =
 		bin2bcd(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f);
 	buf[M41T80_REG_HOUR] =
-		bin2bcd(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f) ;
+		bin2bcd(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f);
 	buf[M41T80_REG_WDAY] =
 		(tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07);
 	buf[M41T80_REG_DAY] =
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-m41t93.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m41t93.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-m41t93.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m41t93.c	2013-08-25 20:43:22.000000000 -0400
@@ -194,19 +194,12 @@ static int m41t93_probe(struct spi_devic
 	return 0;
 }
 
-
-static int m41t93_remove(struct spi_device *spi)
-{
-	return 0;
-}
-
 static struct spi_driver m41t93_driver = {
 	.driver = {
 		.name	= "rtc-m41t93",
 		.owner	= THIS_MODULE,
 	},
 	.probe	= m41t93_probe,
-	.remove = m41t93_remove,
 };
 
 module_spi_driver(m41t93_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-m41t94.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m41t94.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-m41t94.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m41t94.c	2013-08-25 20:43:22.000000000 -0400
@@ -134,18 +134,12 @@ static int m41t94_probe(struct spi_devic
 	return 0;
 }
 
-static int m41t94_remove(struct spi_device *spi)
-{
-	return 0;
-}
-
 static struct spi_driver m41t94_driver = {
 	.driver = {
 		.name	= "rtc-m41t94",
 		.owner	= THIS_MODULE,
 	},
 	.probe	= m41t94_probe,
-	.remove = m41t94_remove,
 };
 
 module_spi_driver(m41t94_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-m48t35.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m48t35.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-m48t35.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m48t35.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/bcd.h>
 #include <linux/io.h>
+#include <linux/err.h>
 
 #define DRV_VERSION		"1.0"
 
@@ -174,15 +175,7 @@ static int m48t35_probe(struct platform_
 
 	priv->rtc = devm_rtc_device_register(&pdev->dev, "m48t35",
 				  &m48t35_ops, THIS_MODULE);
-	if (IS_ERR(priv->rtc))
-		return PTR_ERR(priv->rtc);
-
-	return 0;
-}
-
-static int m48t35_remove(struct platform_device *pdev)
-{
-	return 0;
+	return PTR_RET(priv->rtc);
 }
 
 static struct platform_driver m48t35_platform_driver = {
@@ -191,7 +184,6 @@ static struct platform_driver m48t35_pla
 		.owner	= THIS_MODULE,
 	},
 	.probe		= m48t35_probe,
-	.remove		= m48t35_remove,
 };
 
 module_platform_driver(m48t35_platform_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-m48t59.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m48t59.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-m48t59.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m48t59.c	2013-08-25 20:43:22.000000000 -0400
@@ -409,7 +409,8 @@ static int m48t59_rtc_probe(struct platf
 	} else if (res->flags & IORESOURCE_MEM) {
 		/* we are memory-mapped */
 		if (!pdata) {
-			pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+			pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata),
+						GFP_KERNEL);
 			if (!pdata)
 				return -ENOMEM;
 			/* Ensure we only kmalloc platform data once */
@@ -425,7 +426,7 @@ static int m48t59_rtc_probe(struct platf
 			pdata->read_byte = m48t59_mem_readb;
 	}
 
-	m48t59 = kzalloc(sizeof(*m48t59), GFP_KERNEL);
+	m48t59 = devm_kzalloc(&pdev->dev, sizeof(*m48t59), GFP_KERNEL);
 	if (!m48t59)
 		return -ENOMEM;
 
@@ -433,9 +434,10 @@ static int m48t59_rtc_probe(struct platf
 
 	if (!m48t59->ioaddr) {
 		/* ioaddr not mapped externally */
-		m48t59->ioaddr = ioremap(res->start, resource_size(res));
+		m48t59->ioaddr = devm_ioremap(&pdev->dev, res->start,
+						resource_size(res));
 		if (!m48t59->ioaddr)
-			goto out;
+			return ret;
 	}
 
 	/* Try to get irq number. We also can work in
@@ -446,10 +448,11 @@ static int m48t59_rtc_probe(struct platf
 		m48t59->irq = NO_IRQ;
 
 	if (m48t59->irq != NO_IRQ) {
-		ret = request_irq(m48t59->irq, m48t59_rtc_interrupt,
-			IRQF_SHARED, "rtc-m48t59", &pdev->dev);
+		ret = devm_request_irq(&pdev->dev, m48t59->irq,
+				m48t59_rtc_interrupt, IRQF_SHARED,
+				"rtc-m48t59", &pdev->dev);
 		if (ret)
-			goto out;
+			return ret;
 	}
 	switch (pdata->type) {
 	case M48T59RTC_TYPE_M48T59:
@@ -469,52 +472,29 @@ static int m48t59_rtc_probe(struct platf
 		break;
 	default:
 		dev_err(&pdev->dev, "Unknown RTC type\n");
-		ret = -ENODEV;
-		goto out;
+		return -ENODEV;
 	}
 
 	spin_lock_init(&m48t59->lock);
 	platform_set_drvdata(pdev, m48t59);
 
-	m48t59->rtc = rtc_device_register(name, &pdev->dev, ops, THIS_MODULE);
-	if (IS_ERR(m48t59->rtc)) {
-		ret = PTR_ERR(m48t59->rtc);
-		goto out;
-	}
+	m48t59->rtc = devm_rtc_device_register(&pdev->dev, name, ops,
+						THIS_MODULE);
+	if (IS_ERR(m48t59->rtc))
+		return PTR_ERR(m48t59->rtc);
 
 	m48t59_nvram_attr.size = pdata->offset;
 
 	ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
-	if (ret) {
-		rtc_device_unregister(m48t59->rtc);
-		goto out;
-	}
+	if (ret)
+		return ret;
 
 	return 0;
-
-out:
-	if (m48t59->irq != NO_IRQ)
-		free_irq(m48t59->irq, &pdev->dev);
-	if (m48t59->ioaddr)
-		iounmap(m48t59->ioaddr);
-		kfree(m48t59);
-	return ret;
 }
 
 static int m48t59_rtc_remove(struct platform_device *pdev)
 {
-	struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
-	struct m48t59_plat_data *pdata = pdev->dev.platform_data;
-
 	sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
-	if (!IS_ERR(m48t59->rtc))
-		rtc_device_unregister(m48t59->rtc);
-	if (m48t59->ioaddr && !pdata->ioaddr)
-		iounmap(m48t59->ioaddr);
-	if (m48t59->irq != NO_IRQ)
-		free_irq(m48t59->irq, &pdev->dev);
-	platform_set_drvdata(pdev, NULL);
-	kfree(m48t59);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-m48t86.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m48t86.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-m48t86.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-m48t86.c	2013-08-25 20:43:22.000000000 -0400
@@ -166,20 +166,12 @@ static int m48t86_rtc_probe(struct platf
 	return 0;
 }
 
-static int m48t86_rtc_remove(struct platform_device *dev)
-{
-	platform_set_drvdata(dev, NULL);
-
-	return 0;
-}
-
 static struct platform_driver m48t86_rtc_platform_driver = {
 	.driver		= {
 		.name	= "rtc-m48t86",
 		.owner	= THIS_MODULE,
 	},
 	.probe		= m48t86_rtc_probe,
-	.remove		= m48t86_rtc_remove,
 };
 
 module_platform_driver(m48t86_rtc_platform_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-max6900.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max6900.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-max6900.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max6900.c	2013-08-25 20:43:22.000000000 -0400
@@ -212,11 +212,6 @@ static int max6900_rtc_set_time(struct d
 	return max6900_i2c_set_time(to_i2c_client(dev), tm);
 }
 
-static int max6900_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
 static const struct rtc_class_ops max6900_rtc_ops = {
 	.read_time = max6900_rtc_read_time,
 	.set_time = max6900_rtc_set_time,
@@ -252,7 +247,6 @@ static struct i2c_driver max6900_driver
 		   .name = "rtc-max6900",
 		   },
 	.probe = max6900_probe,
-	.remove = max6900_remove,
 	.id_table = max6900_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-max6902.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max6902.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-max6902.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max6902.c	2013-08-25 20:43:22.000000000 -0400
@@ -143,23 +143,17 @@ static int max6902_probe(struct spi_devi
 	return 0;
 }
 
-static int max6902_remove(struct spi_device *spi)
-{
-	return 0;
-}
-
 static struct spi_driver max6902_driver = {
 	.driver = {
 		.name	= "rtc-max6902",
 		.owner	= THIS_MODULE,
 	},
 	.probe	= max6902_probe,
-	.remove = max6902_remove,
 };
 
 module_spi_driver(max6902_driver);
 
-MODULE_DESCRIPTION ("max6902 spi RTC driver");
-MODULE_AUTHOR ("Raphael Assenat");
-MODULE_LICENSE ("GPL");
+MODULE_DESCRIPTION("max6902 spi RTC driver");
+MODULE_AUTHOR("Raphael Assenat");
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("spi:rtc-max6902");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-max77686.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max77686.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-max77686.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max77686.c	2013-08-25 20:43:22.000000000 -0400
@@ -119,7 +119,7 @@ static int max77686_rtc_tm_to_data(struc
 	data[RTC_WEEKDAY] = 1 << tm->tm_wday;
 	data[RTC_DATE] = tm->tm_mday;
 	data[RTC_MONTH] = tm->tm_mon + 1;
-	data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0 ;
+	data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
 
 	if (tm->tm_year < 100) {
 		pr_warn("%s: MAX77686 RTC cannot handle the year %d."
@@ -567,11 +567,6 @@ err_rtc:
 	return ret;
 }
 
-static int max77686_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 static void max77686_rtc_shutdown(struct platform_device *pdev)
 {
 #ifdef MAX77686_RTC_WTSR_SMPL
@@ -610,7 +605,6 @@ static struct platform_driver max77686_r
 		.owner	= THIS_MODULE,
 	},
 	.probe		= max77686_rtc_probe,
-	.remove		= max77686_rtc_remove,
 	.shutdown	= max77686_rtc_shutdown,
 	.id_table	= rtc_id,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-max8907.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max8907.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-max8907.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max8907.c	2013-08-25 20:43:22.000000000 -0400
@@ -213,18 +213,12 @@ static int max8907_rtc_probe(struct plat
 	return ret;
 }
 
-static int max8907_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 static struct platform_driver max8907_rtc_driver = {
 	.driver = {
 		.name = "max8907-rtc",
 		.owner = THIS_MODULE,
 	},
 	.probe = max8907_rtc_probe,
-	.remove = max8907_rtc_remove,
 };
 module_platform_driver(max8907_rtc_driver);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-max8925.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max8925.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-max8925.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max8925.c	2013-08-25 20:43:22.000000000 -0400
@@ -268,7 +268,7 @@ static int max8925_rtc_probe(struct plat
 	if (ret < 0) {
 		dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
 			info->irq, ret);
-		goto err;
+		return ret;
 	}
 
 	dev_set_drvdata(&pdev->dev, info);
@@ -282,18 +282,10 @@ static int max8925_rtc_probe(struct plat
 	ret = PTR_ERR(info->rtc_dev);
 	if (IS_ERR(info->rtc_dev)) {
 		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
-		goto err;
+		return ret;
 	}
 
 	return 0;
-err:
-	platform_set_drvdata(pdev, NULL);
-	return ret;
-}
-
-static int max8925_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -326,7 +318,6 @@ static struct platform_driver max8925_rt
 		.pm     = &max8925_rtc_pm_ops,
 	},
 	.probe		= max8925_rtc_probe,
-	.remove		= max8925_rtc_remove,
 };
 
 module_platform_driver(max8925_rtc_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-max8997.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max8997.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-max8997.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max8997.c	2013-08-25 20:43:22.000000000 -0400
@@ -104,7 +104,7 @@ static int max8997_rtc_tm_to_data(struct
 	data[RTC_WEEKDAY] = 1 << tm->tm_wday;
 	data[RTC_DATE] = tm->tm_mday;
 	data[RTC_MONTH] = tm->tm_mon + 1;
-	data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0 ;
+	data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
 
 	if (tm->tm_year < 100) {
 		pr_warn("%s: MAX8997 RTC cannot handle the year %d."
@@ -507,11 +507,6 @@ err_out:
 	return ret;
 }
 
-static int max8997_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 static void max8997_rtc_shutdown(struct platform_device *pdev)
 {
 	struct max8997_rtc_info *info = platform_get_drvdata(pdev);
@@ -531,7 +526,6 @@ static struct platform_driver max8997_rt
 		.owner	= THIS_MODULE,
 	},
 	.probe		= max8997_rtc_probe,
-	.remove		= max8997_rtc_remove,
 	.shutdown	= max8997_rtc_shutdown,
 	.id_table	= rtc_id,
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-max8998.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max8998.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-max8998.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-max8998.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/bcd.h>
+#include <linux/irqdomain.h>
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/max8998.h>
@@ -252,7 +253,7 @@ static const struct rtc_class_ops max899
 static int max8998_rtc_probe(struct platform_device *pdev)
 {
 	struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent);
-	struct max8998_platform_data *pdata = dev_get_platdata(max8998->dev);
+	struct max8998_platform_data *pdata = max8998->pdata;
 	struct max8998_rtc_info *info;
 	int ret;
 
@@ -264,7 +265,6 @@ static int max8998_rtc_probe(struct plat
 	info->dev = &pdev->dev;
 	info->max8998 = max8998;
 	info->rtc = max8998->rtc;
-	info->irq = max8998->irq_base + MAX8998_IRQ_ALARM0;
 
 	platform_set_drvdata(pdev, info);
 
@@ -274,7 +274,16 @@ static int max8998_rtc_probe(struct plat
 	if (IS_ERR(info->rtc_dev)) {
 		ret = PTR_ERR(info->rtc_dev);
 		dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
-		goto out_rtc;
+		return ret;
+	}
+
+	if (!max8998->irq_domain)
+		goto no_irq;
+
+	info->irq = irq_create_mapping(max8998->irq_domain, MAX8998_IRQ_ALARM0);
+	if (!info->irq) {
+		dev_warn(&pdev->dev, "Failed to map alarm IRQ\n");
+		goto no_irq;
 	}
 
 	ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
@@ -284,6 +293,7 @@ static int max8998_rtc_probe(struct plat
 		dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
 			info->irq, ret);
 
+no_irq:
 	dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name);
 	if (pdata && pdata->rtc_delay) {
 		info->lp3974_bug_workaround = true;
@@ -292,15 +302,6 @@ static int max8998_rtc_probe(struct plat
 	}
 
 	return 0;
-
-out_rtc:
-	platform_set_drvdata(pdev, NULL);
-	return ret;
-}
-
-static int max8998_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
 }
 
 static const struct platform_device_id max8998_rtc_id[] = {
@@ -315,7 +316,6 @@ static struct platform_driver max8998_rt
 		.owner	= THIS_MODULE,
 	},
 	.probe		= max8998_rtc_probe,
-	.remove		= max8998_rtc_remove,
 	.id_table	= max8998_rtc_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-mc13xxx.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-mc13xxx.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-mc13xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-mc13xxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -370,8 +370,6 @@ err_reset_irq_status:
 err_reset_irq_request:
 
 		mc13xxx_unlock(mc13xxx);
-
-		platform_set_drvdata(pdev, NULL);
 	}
 
 	return ret;
@@ -389,8 +387,6 @@ static int __exit mc13xxx_rtc_remove(str
 
 	mc13xxx_unlock(priv->mc13xxx);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-mpc5121.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-mpc5121.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-mpc5121.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-mpc5121.c	2013-08-25 20:43:22.000000000 -0400
@@ -68,7 +68,7 @@ struct mpc5121_rtc_regs {
 	u32 target_time;	/* RTC + 0x20 */
 	/*
 	 * actual_time:
-	 * 	readonly time since VBAT_RTC was last connected
+	 *	readonly time since VBAT_RTC was last connected
 	 */
 	u32 actual_time;	/* RTC + 0x24 */
 	u32 keep_alive;		/* RTC + 0x28 */
@@ -312,20 +312,19 @@ static int mpc5121_rtc_probe(struct plat
 	struct mpc5121_rtc_data *rtc;
 	int err = 0;
 
-	rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
+	rtc = devm_kzalloc(&op->dev, sizeof(*rtc), GFP_KERNEL);
 	if (!rtc)
 		return -ENOMEM;
 
 	rtc->regs = of_iomap(op->dev.of_node, 0);
 	if (!rtc->regs) {
 		dev_err(&op->dev, "%s: couldn't map io space\n", __func__);
-		err = -ENOSYS;
-		goto out_free;
+		return -ENOSYS;
 	}
 
 	device_init_wakeup(&op->dev, 1);
 
-	dev_set_drvdata(&op->dev, rtc);
+	platform_set_drvdata(op, rtc);
 
 	rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1);
 	err = request_irq(rtc->irq, mpc5121_rtc_handler, 0,
@@ -354,10 +353,10 @@ static int mpc5121_rtc_probe(struct plat
 			out_be32(&rtc->regs->keep_alive, ka);
 		}
 
-		rtc->rtc = rtc_device_register("mpc5121-rtc", &op->dev,
+		rtc->rtc = devm_rtc_device_register(&op->dev, "mpc5121-rtc",
 						&mpc5121_rtc_ops, THIS_MODULE);
 	} else {
-		rtc->rtc = rtc_device_register("mpc5200-rtc", &op->dev,
+		rtc->rtc = devm_rtc_device_register(&op->dev, "mpc5200-rtc",
 						&mpc5200_rtc_ops, THIS_MODULE);
 	}
 
@@ -377,29 +376,24 @@ out_dispose2:
 out_dispose:
 	irq_dispose_mapping(rtc->irq);
 	iounmap(rtc->regs);
-out_free:
-	kfree(rtc);
 
 	return err;
 }
 
 static int mpc5121_rtc_remove(struct platform_device *op)
 {
-	struct mpc5121_rtc_data *rtc = dev_get_drvdata(&op->dev);
+	struct mpc5121_rtc_data *rtc = platform_get_drvdata(op);
 	struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
 
 	/* disable interrupt, so there are no nasty surprises */
 	out_8(&regs->alm_enable, 0);
 	out_8(&regs->int_enable, in_8(&regs->int_enable) & ~0x1);
 
-	rtc_device_unregister(rtc->rtc);
 	iounmap(rtc->regs);
 	free_irq(rtc->irq, &op->dev);
 	free_irq(rtc->irq_periodic, &op->dev);
 	irq_dispose_mapping(rtc->irq);
 	irq_dispose_mapping(rtc->irq_periodic);
-	dev_set_drvdata(&op->dev, NULL);
-	kfree(rtc);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-msm6242.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-msm6242.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-msm6242.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-msm6242.c	2013-08-25 20:43:22.000000000 -0400
@@ -111,8 +111,8 @@ static void msm6242_lock(struct msm6242_
 	}
 
 	if (!cnt)
-		pr_warning("msm6242: timed out waiting for RTC (0x%x)\n",
-			   msm6242_read(priv, MSM6242_CD));
+		pr_warn("msm6242: timed out waiting for RTC (0x%x)\n",
+			msm6242_read(priv, MSM6242_CD));
 }
 
 static void msm6242_unlock(struct msm6242_priv *priv)
@@ -199,7 +199,6 @@ static int __init msm6242_rtc_probe(stru
 	struct resource *res;
 	struct msm6242_priv *priv;
 	struct rtc_device *rtc;
-	int error;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
@@ -216,22 +215,11 @@ static int __init msm6242_rtc_probe(stru
 
 	rtc = devm_rtc_device_register(&pdev->dev, "rtc-msm6242",
 				&msm6242_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		error = PTR_ERR(rtc);
-		goto out_unmap;
-	}
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 
 	priv->rtc = rtc;
 	return 0;
-
-out_unmap:
-	platform_set_drvdata(pdev, NULL);
-	return error;
-}
-
-static int __exit msm6242_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
 }
 
 static struct platform_driver msm6242_rtc_driver = {
@@ -239,7 +227,6 @@ static struct platform_driver msm6242_rt
 		.name	= "rtc-msm6242",
 		.owner	= THIS_MODULE,
 	},
-	.remove	= __exit_p(msm6242_rtc_remove),
 };
 
 module_platform_driver_probe(msm6242_rtc_driver, msm6242_rtc_probe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-mxc.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-mxc.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-mxc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-mxc.c	2013-08-25 20:43:22.000000000 -0400
@@ -436,22 +436,20 @@ static int mxc_rtc_probe(struct platform
 		pdata->irq = -1;
 	}
 
-	if (pdata->irq >=0)
+	if (pdata->irq >= 0)
 		device_init_wakeup(&pdev->dev, 1);
 
 	rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &mxc_rtc_ops,
 				  THIS_MODULE);
 	if (IS_ERR(rtc)) {
 		ret = PTR_ERR(rtc);
-		goto exit_clr_drvdata;
+		goto exit_put_clk;
 	}
 
 	pdata->rtc = rtc;
 
 	return 0;
 
-exit_clr_drvdata:
-	platform_set_drvdata(pdev, NULL);
 exit_put_clk:
 	clk_disable_unprepare(pdata->clk);
 
@@ -465,7 +463,6 @@ static int mxc_rtc_remove(struct platfor
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 
 	clk_disable_unprepare(pdata->clk);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-nuc900.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-nuc900.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-nuc900.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-nuc900.c	2013-08-25 20:43:22.000000000 -0400
@@ -260,15 +260,7 @@ static int __init nuc900_rtc_probe(struc
 	return 0;
 }
 
-static int __exit nuc900_rtc_remove(struct platform_device *pdev)
-{
-	platform_set_drvdata(pdev, NULL);
-
-	return 0;
-}
-
 static struct platform_driver nuc900_rtc_driver = {
-	.remove		= __exit_p(nuc900_rtc_remove),
 	.driver		= {
 		.name	= "nuc900-rtc",
 		.owner	= THIS_MODULE,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-omap.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-omap.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-omap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-omap.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,9 +23,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/pm_runtime.h>
-
-#include <asm/io.h>
-
+#include <linux/io.h>
 
 /* The OMAP1 RTC is a year/month/day/hours/minutes/seconds BCD clock
  * with century-range alarm matching, driven by the 32kHz clock.
@@ -423,6 +421,8 @@ static int __init omap_rtc_probe(struct
 	 *    is write-only, and always reads as zero...)
 	 */
 
+	device_init_wakeup(&pdev->dev, true);
+
 	if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT)
 		pr_info("%s: split power mode\n", pdev->name);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-palmas.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-palmas.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-palmas.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-palmas.c	2013-08-25 20:43:22.000000000 -0400
@@ -265,6 +265,7 @@ static int palmas_rtc_probe(struct platf
 
 	palmas_rtc->irq = platform_get_irq(pdev, 0);
 
+	device_init_wakeup(&pdev->dev, 1);
 	palmas_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 				&palmas_rtc_ops, THIS_MODULE);
 	if (IS_ERR(palmas_rtc->rtc)) {
@@ -283,7 +284,6 @@ static int palmas_rtc_probe(struct platf
 		return ret;
 	}
 
-	device_set_wakeup_capable(&pdev->dev, 1);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-pcap.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcap.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-pcap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcap.c	2013-08-25 20:43:22.000000000 -0400
@@ -156,10 +156,8 @@ static int __init pcap_rtc_probe(struct
 
 	pcap_rtc->rtc = devm_rtc_device_register(&pdev->dev, "pcap",
 					&pcap_rtc_ops, THIS_MODULE);
-	if (IS_ERR(pcap_rtc->rtc)) {
-		err = PTR_ERR(pcap_rtc->rtc);
-		goto fail;
-	}
+	if (IS_ERR(pcap_rtc->rtc))
+		return PTR_ERR(pcap_rtc->rtc);
 
 	timer_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ);
 	alarm_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA);
@@ -167,17 +165,14 @@ static int __init pcap_rtc_probe(struct
 	err = devm_request_irq(&pdev->dev, timer_irq, pcap_rtc_irq, 0,
 				"RTC Timer", pcap_rtc);
 	if (err)
-		goto fail;
+		return err;
 
 	err = devm_request_irq(&pdev->dev, alarm_irq, pcap_rtc_irq, 0,
 				"RTC Alarm", pcap_rtc);
 	if (err)
-		goto fail;
+		return err;
 
 	return 0;
-fail:
-	platform_set_drvdata(pdev, NULL);
-	return err;
 }
 
 static int __exit pcap_rtc_remove(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-pcf2123.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf2123.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-pcf2123.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf2123.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,11 +18,11 @@
  * should look something like:
  *
  * static struct spi_board_info ek_spi_devices[] = {
- * 	...
- * 	{
- * 		.modalias		= "rtc-pcf2123",
- * 		.chip_select		= 1,
- * 		.controller_data	= (void *)AT91_PIN_PA10,
+ *	...
+ *	{
+ *		.modalias		= "rtc-pcf2123",
+ *		.chip_select		= 1,
+ *		.controller_data	= (void *)AT91_PIN_PA10,
  *		.max_speed_hz		= 1000 * 1000,
  *		.mode			= SPI_CS_HIGH,
  *		.bus_num		= 0,
@@ -94,8 +94,9 @@ static ssize_t pcf2123_show(struct devic
 
 	r = container_of(attr, struct pcf2123_sysfs_reg, attr);
 
-	if (strict_strtoul(r->name, 16, &reg))
-		return -EINVAL;
+	ret = kstrtoul(r->name, 16, &reg);
+	if (ret)
+		return ret;
 
 	txbuf[0] = PCF2123_READ | reg;
 	ret = spi_write_then_read(spi, txbuf, 1, rxbuf, 1);
@@ -117,9 +118,13 @@ static ssize_t pcf2123_store(struct devi
 
 	r = container_of(attr, struct pcf2123_sysfs_reg, attr);
 
-	if (strict_strtoul(r->name, 16, &reg)
-		|| strict_strtoul(buffer, 10, &val))
-		return -EINVAL;
+	ret = kstrtoul(r->name, 16, &reg);
+	if (ret)
+		return ret;
+
+	ret = kstrtoul(buffer, 10, &val);
+	if (ret)
+		return ret;
 
 	txbuf[0] = PCF2123_WRITE | reg;
 	txbuf[1] = val;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-pcf2127.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf2127.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-pcf2127.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf2127.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,241 @@
+/*
+ * An I2C driver for the NXP PCF2127 RTC
+ * Copyright 2013 Til-Technologies
+ *
+ * Author: Renaud Cerrato <r.cerrato@til-technologies.fr>
+ *
+ * based on the other drivers in this same directory.
+ *
+ * http://www.nxp.com/documents/data_sheet/PCF2127AT.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/i2c.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#define DRV_VERSION "0.0.1"
+
+#define PCF2127_REG_CTRL1       (0x00)  /* Control Register 1 */
+#define PCF2127_REG_CTRL2       (0x01)  /* Control Register 2 */
+#define PCF2127_REG_CTRL3       (0x02)  /* Control Register 3 */
+#define PCF2127_REG_SC          (0x03)  /* datetime */
+#define PCF2127_REG_MN          (0x04)
+#define PCF2127_REG_HR          (0x05)
+#define PCF2127_REG_DM          (0x06)
+#define PCF2127_REG_DW          (0x07)
+#define PCF2127_REG_MO          (0x08)
+#define PCF2127_REG_YR          (0x09)
+
+static struct i2c_driver pcf2127_driver;
+
+struct pcf2127 {
+	struct rtc_device *rtc;
+	int voltage_low; /* indicates if a low_voltage was detected */
+};
+
+/*
+ * In the routines that deal directly with the pcf2127 hardware, we use
+ * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
+ */
+static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm)
+{
+	struct pcf2127 *pcf2127 = i2c_get_clientdata(client);
+	unsigned char buf[10] = { PCF2127_REG_CTRL1 };
+
+	/* read registers */
+	if (i2c_master_send(client, buf, 1) != 1 ||
+		i2c_master_recv(client, buf, sizeof(buf)) != sizeof(buf)) {
+		dev_err(&client->dev, "%s: read error\n", __func__);
+		return -EIO;
+	}
+
+	if (buf[PCF2127_REG_CTRL3] & 0x04) {
+		pcf2127->voltage_low = 1;
+		dev_info(&client->dev,
+			"low voltage detected, date/time is not reliable.\n");
+	}
+
+	dev_dbg(&client->dev,
+		"%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, "
+		"sec=%02x, min=%02x, hr=%02x, "
+		"mday=%02x, wday=%02x, mon=%02x, year=%02x\n",
+		__func__,
+		buf[0], buf[1], buf[2],
+		buf[3], buf[4], buf[5],
+		buf[6], buf[7], buf[8], buf[9]);
+
+
+	tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F);
+	tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F);
+	tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F); /* rtc hr 0-23 */
+	tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F);
+	tm->tm_wday = buf[PCF2127_REG_DW] & 0x07;
+	tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
+	tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]);
+	if (tm->tm_year < 70)
+		tm->tm_year += 100;	/* assume we are in 1970...2069 */
+
+	dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
+		"mday=%d, mon=%d, year=%d, wday=%d\n",
+		__func__,
+		tm->tm_sec, tm->tm_min, tm->tm_hour,
+		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
+
+	/* the clock can give out invalid datetime, but we cannot return
+	 * -EINVAL otherwise hwclock will refuse to set the time on bootup.
+	 */
+	if (rtc_valid_tm(tm) < 0)
+		dev_err(&client->dev, "retrieved date/time is not valid.\n");
+
+	return 0;
+}
+
+static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm)
+{
+	unsigned char buf[8];
+	int i = 0, err;
+
+	dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
+		"mday=%d, mon=%d, year=%d, wday=%d\n",
+		__func__,
+		tm->tm_sec, tm->tm_min, tm->tm_hour,
+		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
+
+	/* start register address */
+	buf[i++] = PCF2127_REG_SC;
+
+	/* hours, minutes and seconds */
+	buf[i++] = bin2bcd(tm->tm_sec);
+	buf[i++] = bin2bcd(tm->tm_min);
+	buf[i++] = bin2bcd(tm->tm_hour);
+	buf[i++] = bin2bcd(tm->tm_mday);
+	buf[i++] = tm->tm_wday & 0x07;
+
+	/* month, 1 - 12 */
+	buf[i++] = bin2bcd(tm->tm_mon + 1);
+
+	/* year */
+	buf[i++] = bin2bcd(tm->tm_year % 100);
+
+	/* write register's data */
+	err = i2c_master_send(client, buf, i);
+	if (err != i) {
+		dev_err(&client->dev,
+			"%s: err=%d", __func__, err);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_RTC_INTF_DEV
+static int pcf2127_rtc_ioctl(struct device *dev,
+				unsigned int cmd, unsigned long arg)
+{
+	struct pcf2127 *pcf2127 = i2c_get_clientdata(to_i2c_client(dev));
+
+	switch (cmd) {
+	case RTC_VL_READ:
+		if (pcf2127->voltage_low)
+			dev_info(dev, "low voltage detected, date/time is not reliable.\n");
+
+		if (copy_to_user((void __user *)arg, &pcf2127->voltage_low,
+					sizeof(int)))
+			return -EFAULT;
+		return 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+#else
+#define pcf2127_rtc_ioctl NULL
+#endif
+
+static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	return pcf2127_get_datetime(to_i2c_client(dev), tm);
+}
+
+static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	return pcf2127_set_datetime(to_i2c_client(dev), tm);
+}
+
+static const struct rtc_class_ops pcf2127_rtc_ops = {
+	.ioctl		= pcf2127_rtc_ioctl,
+	.read_time	= pcf2127_rtc_read_time,
+	.set_time	= pcf2127_rtc_set_time,
+};
+
+static int pcf2127_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	struct pcf2127 *pcf2127;
+
+	dev_dbg(&client->dev, "%s\n", __func__);
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+		return -ENODEV;
+
+	pcf2127 = devm_kzalloc(&client->dev, sizeof(struct pcf2127),
+				GFP_KERNEL);
+	if (!pcf2127)
+		return -ENOMEM;
+
+	dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
+
+	i2c_set_clientdata(client, pcf2127);
+
+	pcf2127->rtc = devm_rtc_device_register(&client->dev,
+				pcf2127_driver.driver.name,
+				&pcf2127_rtc_ops, THIS_MODULE);
+
+	if (IS_ERR(pcf2127->rtc))
+		return PTR_ERR(pcf2127->rtc);
+
+	return 0;
+}
+
+static int pcf2127_remove(struct i2c_client *client)
+{
+	return 0;
+}
+
+static const struct i2c_device_id pcf2127_id[] = {
+	{ "pcf2127", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, pcf2127_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id pcf2127_of_match[] = {
+	{ .compatible = "nxp,pcf2127" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, pcf2127_of_match);
+#endif
+
+static struct i2c_driver pcf2127_driver = {
+	.driver		= {
+		.name	= "rtc-pcf2127",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(pcf2127_of_match),
+	},
+	.probe		= pcf2127_probe,
+	.remove		= pcf2127_remove,
+	.id_table	= pcf2127_id,
+};
+
+module_i2c_driver(pcf2127_driver);
+
+MODULE_AUTHOR("Renaud Cerrato <r.cerrato@til-technologies.fr>");
+MODULE_DESCRIPTION("NXP PCF2127 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-pcf8523.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf8523.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-pcf8523.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf8523.c	2013-08-25 20:43:22.000000000 -0400
@@ -317,11 +317,6 @@ static int pcf8523_probe(struct i2c_clie
 	return 0;
 }
 
-static int pcf8523_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
 static const struct i2c_device_id pcf8523_id[] = {
 	{ "pcf8523", 0 },
 	{ }
@@ -343,7 +338,6 @@ static struct i2c_driver pcf8523_driver
 		.of_match_table = of_match_ptr(pcf8523_of_match),
 	},
 	.probe = pcf8523_probe,
-	.remove = pcf8523_remove,
 	.id_table = pcf8523_id,
 };
 module_i2c_driver(pcf8523_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-pcf8563.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf8563.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-pcf8563.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf8563.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/err.h>
 
 #define DRV_VERSION "0.4.3"
 
@@ -263,15 +264,7 @@ static int pcf8563_probe(struct i2c_clie
 				pcf8563_driver.driver.name,
 				&pcf8563_rtc_ops, THIS_MODULE);
 
-	if (IS_ERR(pcf8563->rtc))
-		return PTR_ERR(pcf8563->rtc);
-
-	return 0;
-}
-
-static int pcf8563_remove(struct i2c_client *client)
-{
-	return 0;
+	return PTR_RET(pcf8563->rtc);
 }
 
 static const struct i2c_device_id pcf8563_id[] = {
@@ -296,7 +289,6 @@ static struct i2c_driver pcf8563_driver
 		.of_match_table = of_match_ptr(pcf8563_of_match),
 	},
 	.probe		= pcf8563_probe,
-	.remove		= pcf8563_remove,
 	.id_table	= pcf8563_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-pcf8583.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf8583.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-pcf8583.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pcf8583.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/rtc.h>
 #include <linux/init.h>
+#include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/bcd.h>
 
@@ -188,7 +189,8 @@ static int pcf8583_rtc_read_time(struct
 		dev_warn(dev, "resetting control %02x -> %02x\n",
 			ctrl, new_ctrl);
 
-		if ((err = pcf8583_set_ctrl(client, &new_ctrl)) < 0)
+		err = pcf8583_set_ctrl(client, &new_ctrl);
+		if (err < 0)
 			return err;
 	}
 
@@ -283,15 +285,7 @@ static int pcf8583_probe(struct i2c_clie
 				pcf8583_driver.driver.name,
 				&pcf8583_rtc_ops, THIS_MODULE);
 
-	if (IS_ERR(pcf8583->rtc))
-		return PTR_ERR(pcf8583->rtc);
-
-	return 0;
-}
-
-static int pcf8583_remove(struct i2c_client *client)
-{
-	return 0;
+	return PTR_RET(pcf8583->rtc);
 }
 
 static const struct i2c_device_id pcf8583_id[] = {
@@ -306,7 +300,6 @@ static struct i2c_driver pcf8583_driver
 		.owner	= THIS_MODULE,
 	},
 	.probe		= pcf8583_probe,
-	.remove		= pcf8583_remove,
 	.id_table	= pcf8583_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-pm8xxx.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pm8xxx.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-pm8xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pm8xxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -395,7 +395,7 @@ static int pm8xxx_rtc_probe(struct platf
 	if (pdata != NULL)
 		rtc_write_enable = pdata->rtc_write_enable;
 
-	rtc_dd = kzalloc(sizeof(*rtc_dd), GFP_KERNEL);
+	rtc_dd = devm_kzalloc(&pdev->dev, sizeof(*rtc_dd), GFP_KERNEL);
 	if (rtc_dd == NULL) {
 		dev_err(&pdev->dev, "Unable to allocate memory!\n");
 		return -ENOMEM;
@@ -407,16 +407,14 @@ static int pm8xxx_rtc_probe(struct platf
 	rtc_dd->rtc_alarm_irq = platform_get_irq(pdev, 0);
 	if (rtc_dd->rtc_alarm_irq < 0) {
 		dev_err(&pdev->dev, "Alarm IRQ resource absent!\n");
-		rc = -ENXIO;
-		goto fail_rtc_enable;
+		return -ENXIO;
 	}
 
 	rtc_resource = platform_get_resource_byname(pdev, IORESOURCE_IO,
 							"pmic_rtc_base");
 	if (!(rtc_resource && rtc_resource->start)) {
 		dev_err(&pdev->dev, "RTC IO resource absent!\n");
-		rc = -ENXIO;
-		goto fail_rtc_enable;
+		return -ENXIO;
 	}
 
 	rtc_dd->rtc_base = rtc_resource->start;
@@ -432,7 +430,7 @@ static int pm8xxx_rtc_probe(struct platf
 	rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "RTC control register read failed!\n");
-		goto fail_rtc_enable;
+		return rc;
 	}
 
 	if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) {
@@ -442,7 +440,7 @@ static int pm8xxx_rtc_probe(struct platf
 		if (rc < 0) {
 			dev_err(&pdev->dev, "Write to RTC control register "
 								"failed\n");
-			goto fail_rtc_enable;
+			return rc;
 		}
 	}
 
@@ -453,13 +451,12 @@ static int pm8xxx_rtc_probe(struct platf
 	platform_set_drvdata(pdev, rtc_dd);
 
 	/* Register the RTC device */
-	rtc_dd->rtc = rtc_device_register("pm8xxx_rtc", &pdev->dev,
+	rtc_dd->rtc = devm_rtc_device_register(&pdev->dev, "pm8xxx_rtc",
 				&pm8xxx_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc_dd->rtc)) {
 		dev_err(&pdev->dev, "%s: RTC registration failed (%ld)\n",
 					__func__, PTR_ERR(rtc_dd->rtc));
-		rc = PTR_ERR(rtc_dd->rtc);
-		goto fail_rtc_enable;
+		return PTR_ERR(rtc_dd->rtc);
 	}
 
 	/* Request the alarm IRQ */
@@ -468,7 +465,7 @@ static int pm8xxx_rtc_probe(struct platf
 				 "pm8xxx_rtc_alarm", rtc_dd);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "Request IRQ failed (%d)\n", rc);
-		goto fail_req_irq;
+		return rc;
 	}
 
 	device_init_wakeup(&pdev->dev, 1);
@@ -476,13 +473,6 @@ static int pm8xxx_rtc_probe(struct platf
 	dev_dbg(&pdev->dev, "Probe success !!\n");
 
 	return 0;
-
-fail_req_irq:
-	rtc_device_unregister(rtc_dd->rtc);
-fail_rtc_enable:
-	platform_set_drvdata(pdev, NULL);
-	kfree(rtc_dd);
-	return rc;
 }
 
 static int pm8xxx_rtc_remove(struct platform_device *pdev)
@@ -491,9 +481,6 @@ static int pm8xxx_rtc_remove(struct plat
 
 	device_init_wakeup(&pdev->dev, 0);
 	free_irq(rtc_dd->rtc_alarm_irq, rtc_dd);
-	rtc_device_unregister(rtc_dd->rtc);
-	platform_set_drvdata(pdev, NULL);
-	kfree(rtc_dd);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-ps3.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ps3.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-ps3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-ps3.c	2013-08-25 20:43:22.000000000 -0400
@@ -71,17 +71,11 @@ static int __init ps3_rtc_probe(struct p
 	return 0;
 }
 
-static int __exit ps3_rtc_remove(struct platform_device *dev)
-{
-	return 0;
-}
-
 static struct platform_driver ps3_rtc_driver = {
 	.driver = {
 		.name = "rtc-ps3",
 		.owner = THIS_MODULE,
 	},
-	.remove = __exit_p(ps3_rtc_remove),
 };
 
 module_platform_driver_probe(ps3_rtc_driver, ps3_rtc_probe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-puv3.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-puv3.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-puv3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-puv3.c	2013-08-25 20:43:22.000000000 -0400
@@ -224,7 +224,6 @@ static int puv3_rtc_remove(struct platfo
 {
 	struct rtc_device *rtc = platform_get_drvdata(dev);
 
-	platform_set_drvdata(dev, NULL);
 	rtc_device_unregister(rtc);
 
 	puv3_rtc_setpie(&dev->dev, 0);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-pxa.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pxa.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-pxa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-pxa.c	2013-08-25 20:43:22.000000000 -0400
@@ -324,37 +324,35 @@ static int __init pxa_rtc_probe(struct p
 	int ret;
 	u32 rttr;
 
-	pxa_rtc = kzalloc(sizeof(struct pxa_rtc), GFP_KERNEL);
+	pxa_rtc = devm_kzalloc(dev, sizeof(*pxa_rtc), GFP_KERNEL);
 	if (!pxa_rtc)
 		return -ENOMEM;
 
 	spin_lock_init(&pxa_rtc->lock);
 	platform_set_drvdata(pdev, pxa_rtc);
 
-	ret = -ENXIO;
 	pxa_rtc->ress = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!pxa_rtc->ress) {
 		dev_err(dev, "No I/O memory resource defined\n");
-		goto err_ress;
+		return -ENXIO;
 	}
 
 	pxa_rtc->irq_1Hz = platform_get_irq(pdev, 0);
 	if (pxa_rtc->irq_1Hz < 0) {
 		dev_err(dev, "No 1Hz IRQ resource defined\n");
-		goto err_ress;
+		return -ENXIO;
 	}
 	pxa_rtc->irq_Alrm = platform_get_irq(pdev, 1);
 	if (pxa_rtc->irq_Alrm < 0) {
 		dev_err(dev, "No alarm IRQ resource defined\n");
-		goto err_ress;
+		return -ENXIO;
 	}
 	pxa_rtc_open(dev);
-	ret = -ENOMEM;
-	pxa_rtc->base = ioremap(pxa_rtc->ress->start,
+	pxa_rtc->base = devm_ioremap(dev, pxa_rtc->ress->start,
 				resource_size(pxa_rtc->ress));
 	if (!pxa_rtc->base) {
-		dev_err(&pdev->dev, "Unable to map pxa RTC I/O memory\n");
-		goto err_map;
+		dev_err(dev, "Unable to map pxa RTC I/O memory\n");
+		return -ENOMEM;
 	}
 
 	/*
@@ -370,41 +368,24 @@ static int __init pxa_rtc_probe(struct p
 
 	rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_RDALE1 | RTSR_HZE);
 
-	pxa_rtc->rtc = rtc_device_register("pxa-rtc", &pdev->dev, &pxa_rtc_ops,
-					   THIS_MODULE);
-	ret = PTR_ERR(pxa_rtc->rtc);
+	pxa_rtc->rtc = devm_rtc_device_register(&pdev->dev, "pxa-rtc",
+						&pxa_rtc_ops, THIS_MODULE);
 	if (IS_ERR(pxa_rtc->rtc)) {
+		ret = PTR_ERR(pxa_rtc->rtc);
 		dev_err(dev, "Failed to register RTC device -> %d\n", ret);
-		goto err_rtc_reg;
+		return ret;
 	}
 
 	device_init_wakeup(dev, 1);
 
 	return 0;
-
-err_rtc_reg:
-	 iounmap(pxa_rtc->base);
-err_ress:
-err_map:
-	kfree(pxa_rtc);
-	return ret;
 }
 
 static int __exit pxa_rtc_remove(struct platform_device *pdev)
 {
-	struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev);
-
 	struct device *dev = &pdev->dev;
-	pxa_rtc_release(dev);
-
-	rtc_device_unregister(pxa_rtc->rtc);
-
-	spin_lock_irq(&pxa_rtc->lock);
-	iounmap(pxa_rtc->base);
-	spin_unlock_irq(&pxa_rtc->lock);
-
-	kfree(pxa_rtc);
 
+	pxa_rtc_release(dev);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-rc5t583.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rc5t583.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-rc5t583.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rc5t583.c	2013-08-25 20:43:22.000000000 -0400
@@ -273,7 +273,7 @@ static int rc5t583_rtc_probe(struct plat
  */
 static int rc5t583_rtc_remove(struct platform_device *pdev)
 {
-	struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(&pdev->dev);
+	struct rc5t583_rtc *rc5t583_rtc = platform_get_drvdata(pdev);
 
 	rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-rp5c01.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rp5c01.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-rp5c01.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rp5c01.c	2013-08-25 20:43:22.000000000 -0400
@@ -251,21 +251,15 @@ static int __init rp5c01_rtc_probe(struc
 
 	rtc = devm_rtc_device_register(&dev->dev, "rtc-rp5c01", &rp5c01_rtc_ops,
 				  THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		error = PTR_ERR(rtc);
-		goto out;
-	}
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 	priv->rtc = rtc;
 
 	error = sysfs_create_bin_file(&dev->dev.kobj, &priv->nvram_attr);
 	if (error)
-		goto out;
+		return error;
 
 	return 0;
-
-out:
-	platform_set_drvdata(dev, NULL);
-	return error;
 }
 
 static int __exit rp5c01_rtc_remove(struct platform_device *dev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-rs5c313.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rs5c313.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-rs5c313.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rs5c313.c	2013-08-25 20:43:22.000000000 -0400
@@ -47,10 +47,10 @@
 #include <linux/platform_device.h>
 #include <linux/bcd.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define DRV_NAME	"rs5c313"
-#define DRV_VERSION 	"1.13"
+#define DRV_VERSION	"1.13"
 
 #ifdef CONFIG_SH_LANDISK
 /*****************************************************/
@@ -301,7 +301,7 @@ static int rs5c313_rtc_set_time(struct d
 	rs5c313_write_reg(RS5C313_ADDR_SEC10, (data >> 4));
 
 	data = bin2bcd(tm->tm_min);
-	rs5c313_write_reg(RS5C313_ADDR_MIN, data );
+	rs5c313_write_reg(RS5C313_ADDR_MIN, data);
 	rs5c313_write_reg(RS5C313_ADDR_MIN10, (data >> 4));
 
 	data = bin2bcd(tm->tm_hour);
@@ -310,7 +310,7 @@ static int rs5c313_rtc_set_time(struct d
 
 	data = bin2bcd(tm->tm_mday);
 	rs5c313_write_reg(RS5C313_ADDR_DAY, data);
-	rs5c313_write_reg(RS5C313_ADDR_DAY10, (data>> 4));
+	rs5c313_write_reg(RS5C313_ADDR_DAY10, (data >> 4));
 
 	data = bin2bcd(tm->tm_mon + 1);
 	rs5c313_write_reg(RS5C313_ADDR_MON, data);
@@ -349,9 +349,9 @@ static void rs5c313_check_xstp_bit(void)
 		}
 
 		memset(&tm, 0, sizeof(struct rtc_time));
-		tm.tm_mday 	= 1;
-		tm.tm_mon 	= 1 - 1;
-		tm.tm_year 	= 2000 - 1900;
+		tm.tm_mday	= 1;
+		tm.tm_mon	= 1 - 1;
+		tm.tm_year	= 2000 - 1900;
 
 		rs5c313_rtc_set_time(NULL, &tm);
 		pr_err("invalid value, resetting to 1 Jan 2000\n");
@@ -378,18 +378,12 @@ static int rs5c313_rtc_probe(struct plat
 	return 0;
 }
 
-static int rs5c313_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 static struct platform_driver rs5c313_rtc_platform_driver = {
 	.driver         = {
 		.name   = DRV_NAME,
 		.owner  = THIS_MODULE,
 	},
-	.probe 	= rs5c313_rtc_probe,
-	.remove = rs5c313_rtc_remove,
+	.probe	= rs5c313_rtc_probe,
 };
 
 static int __init rs5c313_rtc_init(void)
@@ -408,7 +402,7 @@ static int __init rs5c313_rtc_init(void)
 
 static void __exit rs5c313_rtc_exit(void)
 {
-	platform_driver_unregister( &rs5c313_rtc_platform_driver );
+	platform_driver_unregister(&rs5c313_rtc_platform_driver);
 }
 
 module_init(rs5c313_rtc_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-rs5c348.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rs5c348.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-rs5c348.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rs5c348.c	2013-08-25 20:43:22.000000000 -0400
@@ -218,18 +218,12 @@ static int rs5c348_probe(struct spi_devi
 	return ret;
 }
 
-static int rs5c348_remove(struct spi_device *spi)
-{
-	return 0;
-}
-
 static struct spi_driver rs5c348_driver = {
 	.driver = {
 		.name	= "rtc-rs5c348",
 		.owner	= THIS_MODULE,
 	},
 	.probe	= rs5c348_probe,
-	.remove	= rs5c348_remove,
 };
 
 module_spi_driver(rs5c348_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-rv3029c2.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rv3029c2.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-rv3029c2.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rv3029c2.c	2013-08-25 20:43:22.000000000 -0400
@@ -310,7 +310,7 @@ static int rv3029c2_rtc_i2c_set_alarm(st
 		dev_dbg(&client->dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1);
+		ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 0);
 		if (ret)
 			return ret;
 
@@ -412,17 +412,11 @@ static int rv3029c2_probe(struct i2c_cli
 	return 0;
 }
 
-static int rv3029c2_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
 static struct i2c_driver rv3029c2_driver = {
 	.driver = {
 		.name = "rtc-rv3029c2",
 	},
 	.probe = rv3029c2_probe,
-	.remove = rv3029c2_remove,
 	.id_table = rv3029c2_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-rx4581.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rx4581.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-rx4581.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rx4581.c	2013-08-25 20:43:22.000000000 -0400
@@ -282,11 +282,6 @@ static int rx4581_probe(struct spi_devic
 	return 0;
 }
 
-static int rx4581_remove(struct spi_device *spi)
-{
-	return 0;
-}
-
 static const struct spi_device_id rx4581_id[] = {
 	{ "rx4581", 0 },
 	{ }
@@ -299,7 +294,6 @@ static struct spi_driver rx4581_driver =
 		.owner	= THIS_MODULE,
 	},
 	.probe	= rx4581_probe,
-	.remove = rx4581_remove,
 	.id_table = rx4581_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-rx8025.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rx8025.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-rx8025.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rx8025.c	2013-08-25 20:43:22.000000000 -0400
@@ -549,7 +549,7 @@ static int rx8025_probe(struct i2c_clien
 		goto errout;
 	}
 
-	rx8025 = kzalloc(sizeof(*rx8025), GFP_KERNEL);
+	rx8025 = devm_kzalloc(&client->dev, sizeof(*rx8025), GFP_KERNEL);
 	if (!rx8025) {
 		dev_err(&adapter->dev, "failed to alloc memory\n");
 		err = -ENOMEM;
@@ -562,7 +562,7 @@ static int rx8025_probe(struct i2c_clien
 
 	err = rx8025_init_client(client, &need_reset);
 	if (err)
-		goto errout_free;
+		goto errout;
 
 	if (need_reset) {
 		struct rtc_time tm;
@@ -572,12 +572,12 @@ static int rx8025_probe(struct i2c_clien
 		rx8025_set_time(&client->dev, &tm);
 	}
 
-	rx8025->rtc = rtc_device_register(client->name, &client->dev,
+	rx8025->rtc = devm_rtc_device_register(&client->dev, client->name,
 					  &rx8025_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rx8025->rtc)) {
 		err = PTR_ERR(rx8025->rtc);
 		dev_err(&client->dev, "unable to register the class device\n");
-		goto errout_free;
+		goto errout;
 	}
 
 	if (client->irq > 0) {
@@ -586,7 +586,7 @@ static int rx8025_probe(struct i2c_clien
 				  0, "rx8025", client);
 		if (err) {
 			dev_err(&client->dev, "unable to request IRQ\n");
-			goto errout_reg;
+			goto errout;
 		}
 	}
 
@@ -603,12 +603,6 @@ errout_irq:
 	if (client->irq > 0)
 		free_irq(client->irq, client);
 
-errout_reg:
-	rtc_device_unregister(rx8025->rtc);
-
-errout_free:
-	kfree(rx8025);
-
 errout:
 	dev_err(&adapter->dev, "probing for rx8025 failed\n");
 	return err;
@@ -629,8 +623,6 @@ static int rx8025_remove(struct i2c_clie
 	}
 
 	rx8025_sysfs_unregister(&client->dev);
-	rtc_device_unregister(rx8025->rtc);
-	kfree(rx8025);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-rx8581.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rx8581.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-rx8581.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-rx8581.c	2013-08-25 20:43:22.000000000 -0400
@@ -251,11 +251,6 @@ static int rx8581_probe(struct i2c_clien
 	return 0;
 }
 
-static int rx8581_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
 static const struct i2c_device_id rx8581_id[] = {
 	{ "rx8581", 0 },
 	{ }
@@ -268,7 +263,6 @@ static struct i2c_driver rx8581_driver =
 		.owner	= THIS_MODULE,
 	},
 	.probe		= rx8581_probe,
-	.remove		= rx8581_remove,
 	.id_table	= rx8581_id,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-s3c.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-s3c.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-s3c.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-s3c.c	2013-08-25 20:43:22.000000000 -0400
@@ -421,8 +421,6 @@ static void s3c_rtc_enable(struct platfo
 
 static int s3c_rtc_remove(struct platform_device *dev)
 {
-	platform_set_drvdata(dev, NULL);
-
 	s3c_rtc_setaie(&dev->dev, 0);
 
 	clk_unprepare(rtc_clk);
@@ -549,23 +547,20 @@ static int s3c_rtc_probe(struct platform
 			  0,  "s3c2410-rtc alarm", rtc);
 	if (ret) {
 		dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret);
-		goto err_alarm_irq;
+		goto err_nortc;
 	}
 
 	ret = devm_request_irq(&pdev->dev, s3c_rtc_tickno, s3c_rtc_tickirq,
 			  0,  "s3c2410-rtc tick", rtc);
 	if (ret) {
 		dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);
-		goto err_alarm_irq;
+		goto err_nortc;
 	}
 
 	clk_disable(rtc_clk);
 
 	return 0;
 
- err_alarm_irq:
-	platform_set_drvdata(pdev, NULL);
-
  err_nortc:
 	s3c_rtc_enable(pdev, 0);
 	clk_disable_unprepare(rtc_clk);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-sa1100.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sa1100.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-sa1100.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sa1100.c	2013-08-25 20:43:22.000000000 -0400
@@ -249,7 +249,7 @@ static int sa1100_rtc_probe(struct platf
 
 	ret = clk_prepare_enable(info->clk);
 	if (ret)
-		goto err_enable_clk;
+		return ret;
 	/*
 	 * According to the manual we should be able to let RTTR be zero
 	 * and then a default diviser for a 32.768KHz clock is used.
@@ -303,8 +303,6 @@ static int sa1100_rtc_probe(struct platf
 	return 0;
 err_dev:
 	clk_disable_unprepare(info->clk);
-err_enable_clk:
-	platform_set_drvdata(pdev, NULL);
 	return ret;
 }
 
@@ -312,10 +310,8 @@ static int sa1100_rtc_remove(struct plat
 {
 	struct sa1100_rtc *info = platform_get_drvdata(pdev);
 
-	if (info) {
+	if (info)
 		clk_disable_unprepare(info->clk);
-		platform_set_drvdata(pdev, NULL);
-	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-sh.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sh.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-sh.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sh.c	2013-08-25 20:43:22.000000000 -0400
@@ -593,7 +593,7 @@ static int __init sh_rtc_probe(struct pl
 	char clk_name[6];
 	int clk_id, ret;
 
-	rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
+	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
 	if (unlikely(!rtc))
 		return -ENOMEM;
 
@@ -602,9 +602,8 @@ static int __init sh_rtc_probe(struct pl
 	/* get periodic/carry/alarm irqs */
 	ret = platform_get_irq(pdev, 0);
 	if (unlikely(ret <= 0)) {
-		ret = -ENOENT;
 		dev_err(&pdev->dev, "No IRQ resource\n");
-		goto err_badres;
+		return -ENOENT;
 	}
 
 	rtc->periodic_irq = ret;
@@ -613,24 +612,21 @@ static int __init sh_rtc_probe(struct pl
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 	if (unlikely(res == NULL)) {
-		ret = -ENOENT;
 		dev_err(&pdev->dev, "No IO resource\n");
-		goto err_badres;
+		return -ENOENT;
 	}
 
 	rtc->regsize = resource_size(res);
 
-	rtc->res = request_mem_region(res->start, rtc->regsize, pdev->name);
-	if (unlikely(!rtc->res)) {
-		ret = -EBUSY;
-		goto err_badres;
-	}
+	rtc->res = devm_request_mem_region(&pdev->dev, res->start,
+					rtc->regsize, pdev->name);
+	if (unlikely(!rtc->res))
+		return -EBUSY;
 
-	rtc->regbase = ioremap_nocache(rtc->res->start, rtc->regsize);
-	if (unlikely(!rtc->regbase)) {
-		ret = -EINVAL;
-		goto err_badmap;
-	}
+	rtc->regbase = devm_ioremap_nocache(&pdev->dev, rtc->res->start,
+					rtc->regsize);
+	if (unlikely(!rtc->regbase))
+		return -EINVAL;
 
 	clk_id = pdev->id;
 	/* With a single device, the clock id is still "rtc0" */
@@ -639,7 +635,7 @@ static int __init sh_rtc_probe(struct pl
 
 	snprintf(clk_name, sizeof(clk_name), "rtc%d", clk_id);
 
-	rtc->clk = clk_get(&pdev->dev, clk_name);
+	rtc->clk = devm_clk_get(&pdev->dev, clk_name);
 	if (IS_ERR(rtc->clk)) {
 		/*
 		 * No error handling for rtc->clk intentionally, not all
@@ -665,8 +661,8 @@ static int __init sh_rtc_probe(struct pl
 
 	if (rtc->carry_irq <= 0) {
 		/* register shared periodic/carry/alarm irq */
-		ret = request_irq(rtc->periodic_irq, sh_rtc_shared,
-				  0, "sh-rtc", rtc);
+		ret = devm_request_irq(&pdev->dev, rtc->periodic_irq,
+				sh_rtc_shared, 0, "sh-rtc", rtc);
 		if (unlikely(ret)) {
 			dev_err(&pdev->dev,
 				"request IRQ failed with %d, IRQ %d\n", ret,
@@ -675,8 +671,8 @@ static int __init sh_rtc_probe(struct pl
 		}
 	} else {
 		/* register periodic/carry/alarm irqs */
-		ret = request_irq(rtc->periodic_irq, sh_rtc_periodic,
-				  0, "sh-rtc period", rtc);
+		ret = devm_request_irq(&pdev->dev, rtc->periodic_irq,
+				sh_rtc_periodic, 0, "sh-rtc period", rtc);
 		if (unlikely(ret)) {
 			dev_err(&pdev->dev,
 				"request period IRQ failed with %d, IRQ %d\n",
@@ -684,24 +680,21 @@ static int __init sh_rtc_probe(struct pl
 			goto err_unmap;
 		}
 
-		ret = request_irq(rtc->carry_irq, sh_rtc_interrupt,
-				  0, "sh-rtc carry", rtc);
+		ret = devm_request_irq(&pdev->dev, rtc->carry_irq,
+				sh_rtc_interrupt, 0, "sh-rtc carry", rtc);
 		if (unlikely(ret)) {
 			dev_err(&pdev->dev,
 				"request carry IRQ failed with %d, IRQ %d\n",
 				ret, rtc->carry_irq);
-			free_irq(rtc->periodic_irq, rtc);
 			goto err_unmap;
 		}
 
-		ret = request_irq(rtc->alarm_irq, sh_rtc_alarm,
-				  0, "sh-rtc alarm", rtc);
+		ret = devm_request_irq(&pdev->dev, rtc->alarm_irq,
+				sh_rtc_alarm, 0, "sh-rtc alarm", rtc);
 		if (unlikely(ret)) {
 			dev_err(&pdev->dev,
 				"request alarm IRQ failed with %d, IRQ %d\n",
 				ret, rtc->alarm_irq);
-			free_irq(rtc->carry_irq, rtc);
-			free_irq(rtc->periodic_irq, rtc);
 			goto err_unmap;
 		}
 	}
@@ -714,13 +707,10 @@ static int __init sh_rtc_probe(struct pl
 	sh_rtc_setaie(&pdev->dev, 0);
 	sh_rtc_setcie(&pdev->dev, 0);
 
-	rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
+	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, "sh",
 					   &sh_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
 		ret = PTR_ERR(rtc->rtc_dev);
-		free_irq(rtc->periodic_irq, rtc);
-		free_irq(rtc->carry_irq, rtc);
-		free_irq(rtc->alarm_irq, rtc);
 		goto err_unmap;
 	}
 
@@ -737,12 +727,6 @@ static int __init sh_rtc_probe(struct pl
 
 err_unmap:
 	clk_disable(rtc->clk);
-	clk_put(rtc->clk);
-	iounmap(rtc->regbase);
-err_badmap:
-	release_mem_region(rtc->res->start, rtc->regsize);
-err_badres:
-	kfree(rtc);
 
 	return ret;
 }
@@ -751,28 +735,12 @@ static int __exit sh_rtc_remove(struct p
 {
 	struct sh_rtc *rtc = platform_get_drvdata(pdev);
 
-	rtc_device_unregister(rtc->rtc_dev);
 	sh_rtc_irq_set_state(&pdev->dev, 0);
 
 	sh_rtc_setaie(&pdev->dev, 0);
 	sh_rtc_setcie(&pdev->dev, 0);
 
-	free_irq(rtc->periodic_irq, rtc);
-
-	if (rtc->carry_irq > 0) {
-		free_irq(rtc->carry_irq, rtc);
-		free_irq(rtc->alarm_irq, rtc);
-	}
-
-	iounmap(rtc->regbase);
-	release_mem_region(rtc->res->start, rtc->regsize);
-
 	clk_disable(rtc->clk);
-	clk_put(rtc->clk);
-
-	platform_set_drvdata(pdev, NULL);
-
-	kfree(rtc);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-sirfsoc.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sirfsoc.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-sirfsoc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sirfsoc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,475 @@
+/*
+ * SiRFSoC Real Time Clock interface for Linux
+ *
+ * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/rtc/sirfsoc_rtciobrg.h>
+
+
+#define RTC_CN			0x00
+#define RTC_ALARM0		0x04
+#define RTC_ALARM1		0x18
+#define RTC_STATUS		0x08
+#define RTC_SW_VALUE            0x40
+#define SIRFSOC_RTC_AL1E	(1<<6)
+#define SIRFSOC_RTC_AL1		(1<<4)
+#define SIRFSOC_RTC_HZE		(1<<3)
+#define SIRFSOC_RTC_AL0E	(1<<2)
+#define SIRFSOC_RTC_HZ		(1<<1)
+#define SIRFSOC_RTC_AL0		(1<<0)
+#define RTC_DIV			0x0c
+#define RTC_DEEP_CTRL		0x14
+#define RTC_CLOCK_SWITCH	0x1c
+#define SIRFSOC_RTC_CLK		0x03	/* others are reserved */
+
+/* Refer to RTC DIV switch */
+#define RTC_HZ			16
+
+/* This macro is also defined in arch/arm/plat-sirfsoc/cpu.c */
+#define RTC_SHIFT		4
+
+#define INTR_SYSRTC_CN		0x48
+
+struct sirfsoc_rtc_drv {
+	struct rtc_device	*rtc;
+	u32			rtc_base;
+	u32			irq;
+	/* Overflow for every 8 years extra time */
+	u32			overflow_rtc;
+#ifdef CONFIG_PM
+	u32		saved_counter;
+	u32		saved_overflow_rtc;
+#endif
+};
+
+static int sirfsoc_rtc_read_alarm(struct device *dev,
+		struct rtc_wkalrm *alrm)
+{
+	unsigned long rtc_alarm, rtc_count;
+	struct sirfsoc_rtc_drv *rtcdrv;
+
+	rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
+
+	local_irq_disable();
+
+	rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
+
+	rtc_alarm = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_ALARM0);
+	memset(alrm, 0, sizeof(struct rtc_wkalrm));
+
+	/*
+	 * assume alarm interval not beyond one round counter overflow_rtc:
+	 * 0->0xffffffff
+	 */
+	/* if alarm is in next overflow cycle */
+	if (rtc_count > rtc_alarm)
+		rtc_time_to_tm((rtcdrv->overflow_rtc + 1)
+				<< (BITS_PER_LONG - RTC_SHIFT)
+				| rtc_alarm >> RTC_SHIFT, &(alrm->time));
+	else
+		rtc_time_to_tm(rtcdrv->overflow_rtc
+				<< (BITS_PER_LONG - RTC_SHIFT)
+				| rtc_alarm >> RTC_SHIFT, &(alrm->time));
+	if (sirfsoc_rtc_iobrg_readl(
+			rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E)
+		alrm->enabled = 1;
+	local_irq_enable();
+
+	return 0;
+}
+
+static int sirfsoc_rtc_set_alarm(struct device *dev,
+		struct rtc_wkalrm *alrm)
+{
+	unsigned long rtc_status_reg, rtc_alarm;
+	struct sirfsoc_rtc_drv *rtcdrv;
+	rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
+
+	if (alrm->enabled) {
+		rtc_tm_to_time(&(alrm->time), &rtc_alarm);
+
+		local_irq_disable();
+
+		rtc_status_reg = sirfsoc_rtc_iobrg_readl(
+				rtcdrv->rtc_base + RTC_STATUS);
+		if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
+			/*
+			 * An ongoing alarm in progress - ingore it and not
+			 * to return EBUSY
+			 */
+			dev_info(dev, "An old alarm was set, will be replaced by a new one\n");
+		}
+
+		sirfsoc_rtc_iobrg_writel(
+			rtc_alarm << RTC_SHIFT, rtcdrv->rtc_base + RTC_ALARM0);
+		rtc_status_reg &= ~0x07; /* mask out the lower status bits */
+		/*
+		 * This bit RTC_AL sets it as a wake-up source for Sleep Mode
+		 * Writing 1 into this bit will clear it
+		 */
+		rtc_status_reg |= SIRFSOC_RTC_AL0;
+		/* enable the RTC alarm interrupt */
+		rtc_status_reg |= SIRFSOC_RTC_AL0E;
+		sirfsoc_rtc_iobrg_writel(
+			rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
+		local_irq_enable();
+	} else {
+		/*
+		 * if this function was called with enabled=0
+		 * then it could mean that the application is
+		 * trying to cancel an ongoing alarm
+		 */
+		local_irq_disable();
+
+		rtc_status_reg = sirfsoc_rtc_iobrg_readl(
+				rtcdrv->rtc_base + RTC_STATUS);
+		if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
+			/* clear the RTC status register's alarm bit */
+			rtc_status_reg &= ~0x07;
+			/* write 1 into SIRFSOC_RTC_AL0 to force a clear */
+			rtc_status_reg |= (SIRFSOC_RTC_AL0);
+			/* Clear the Alarm enable bit */
+			rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
+
+			sirfsoc_rtc_iobrg_writel(rtc_status_reg,
+					rtcdrv->rtc_base + RTC_STATUS);
+		}
+
+		local_irq_enable();
+	}
+
+	return 0;
+}
+
+static int sirfsoc_rtc_read_time(struct device *dev,
+		struct rtc_time *tm)
+{
+	unsigned long tmp_rtc = 0;
+	struct sirfsoc_rtc_drv *rtcdrv;
+	rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
+	/*
+	 * This patch is taken from WinCE - Need to validate this for
+	 * correctness. To work around sirfsoc RTC counter double sync logic
+	 * fail, read several times to make sure get stable value.
+	 */
+	do {
+		tmp_rtc = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
+		cpu_relax();
+	} while (tmp_rtc != sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN));
+
+	rtc_time_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT) |
+					tmp_rtc >> RTC_SHIFT, tm);
+	return 0;
+}
+
+static int sirfsoc_rtc_set_time(struct device *dev,
+		struct rtc_time *tm)
+{
+	unsigned long rtc_time;
+	struct sirfsoc_rtc_drv *rtcdrv;
+	rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
+
+	rtc_tm_to_time(tm, &rtc_time);
+
+	rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT);
+
+	sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc,
+			rtcdrv->rtc_base + RTC_SW_VALUE);
+	sirfsoc_rtc_iobrg_writel(
+			rtc_time << RTC_SHIFT, rtcdrv->rtc_base + RTC_CN);
+
+	return 0;
+}
+
+static int sirfsoc_rtc_ioctl(struct device *dev, unsigned int cmd,
+		unsigned long arg)
+{
+	switch (cmd) {
+	case RTC_PIE_ON:
+	case RTC_PIE_OFF:
+	case RTC_UIE_ON:
+	case RTC_UIE_OFF:
+	case RTC_AIE_ON:
+	case RTC_AIE_OFF:
+		return 0;
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static const struct rtc_class_ops sirfsoc_rtc_ops = {
+	.read_time = sirfsoc_rtc_read_time,
+	.set_time = sirfsoc_rtc_set_time,
+	.read_alarm = sirfsoc_rtc_read_alarm,
+	.set_alarm = sirfsoc_rtc_set_alarm,
+	.ioctl = sirfsoc_rtc_ioctl
+};
+
+static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
+{
+	struct sirfsoc_rtc_drv *rtcdrv = pdata;
+	unsigned long rtc_status_reg = 0x0;
+	unsigned long events = 0x0;
+
+	rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS);
+	/* this bit will be set ONLY if an alarm was active
+	 * and it expired NOW
+	 * So this is being used as an ASSERT
+	 */
+	if (rtc_status_reg & SIRFSOC_RTC_AL0) {
+		/*
+		 * clear the RTC status register's alarm bit
+		 * mask out the lower status bits
+		 */
+		rtc_status_reg &= ~0x07;
+		/* write 1 into SIRFSOC_RTC_AL0 to ACK the alarm interrupt */
+		rtc_status_reg |= (SIRFSOC_RTC_AL0);
+		/* Clear the Alarm enable bit */
+		rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
+	}
+	sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
+	/* this should wake up any apps polling/waiting on the read
+	 * after setting the alarm
+	 */
+	events |= RTC_IRQF | RTC_AF;
+	rtc_update_irq(rtcdrv->rtc, 1, events);
+
+	return IRQ_HANDLED;
+}
+
+static const struct of_device_id sirfsoc_rtc_of_match[] = {
+	{ .compatible = "sirf,prima2-sysrtc"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, sirfsoc_rtc_of_match);
+
+static int sirfsoc_rtc_probe(struct platform_device *pdev)
+{
+	int err;
+	unsigned long rtc_div;
+	struct sirfsoc_rtc_drv *rtcdrv;
+	struct device_node *np = pdev->dev.of_node;
+
+	rtcdrv = devm_kzalloc(&pdev->dev,
+		sizeof(struct sirfsoc_rtc_drv), GFP_KERNEL);
+	if (rtcdrv == NULL) {
+		dev_err(&pdev->dev,
+			"%s: can't alloc mem for drv struct\n",
+			pdev->name);
+		return -ENOMEM;
+	}
+
+	err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
+	if (err) {
+		dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");
+		goto error;
+	}
+
+	platform_set_drvdata(pdev, rtcdrv);
+
+	/* Register rtc alarm as a wakeup source */
+	device_init_wakeup(&pdev->dev, 1);
+
+	/*
+	 * Set SYS_RTC counter in RTC_HZ HZ Units
+	 * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
+	 * If 16HZ, therefore RTC_DIV = 1023;
+	 */
+	rtc_div = ((32768 / RTC_HZ) / 2) - 1;
+	sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV);
+
+	rtcdrv->rtc = rtc_device_register(pdev->name, &(pdev->dev),
+			&sirfsoc_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtcdrv->rtc)) {
+		err = PTR_ERR(rtcdrv->rtc);
+		dev_err(&pdev->dev, "can't register RTC device\n");
+		return err;
+	}
+
+	/* 0x3 -> RTC_CLK */
+	sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK,
+			rtcdrv->rtc_base + RTC_CLOCK_SWITCH);
+
+	/* reset SYS RTC ALARM0 */
+	sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0);
+
+	/* reset SYS RTC ALARM1 */
+	sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1);
+
+	/* Restore RTC Overflow From Register After Command Reboot */
+	rtcdrv->overflow_rtc =
+		sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE);
+
+	rtcdrv->irq = platform_get_irq(pdev, 0);
+	err = devm_request_irq(
+			&pdev->dev,
+			rtcdrv->irq,
+			sirfsoc_rtc_irq_handler,
+			IRQF_SHARED,
+			pdev->name,
+			rtcdrv);
+	if (err) {
+		dev_err(&pdev->dev, "Unable to register for the SiRF SOC RTC IRQ\n");
+		goto error;
+	}
+
+	return 0;
+
+error:
+	if (rtcdrv->rtc)
+		rtc_device_unregister(rtcdrv->rtc);
+
+	return err;
+}
+
+static int sirfsoc_rtc_remove(struct platform_device *pdev)
+{
+	struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev);
+
+	device_init_wakeup(&pdev->dev, 0);
+	rtc_device_unregister(rtcdrv->rtc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int sirfsoc_rtc_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev);
+	rtcdrv->overflow_rtc =
+		sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE);
+
+	rtcdrv->saved_counter =
+		sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
+	rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc;
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(rtcdrv->irq);
+
+	return 0;
+}
+
+static int sirfsoc_rtc_freeze(struct device *dev)
+{
+	sirfsoc_rtc_suspend(dev);
+
+	return 0;
+}
+
+static int sirfsoc_rtc_thaw(struct device *dev)
+{
+	u32 tmp;
+	struct sirfsoc_rtc_drv *rtcdrv;
+	rtcdrv = (struct sirfsoc_rtc_drv *)dev_get_drvdata(dev);
+
+	/*
+	 * if resume from snapshot and the rtc power is losed,
+	 * restroe the rtc settings
+	 */
+	if (SIRFSOC_RTC_CLK != sirfsoc_rtc_iobrg_readl(
+			rtcdrv->rtc_base + RTC_CLOCK_SWITCH)) {
+		u32 rtc_div;
+		/* 0x3 -> RTC_CLK */
+		sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK,
+			rtcdrv->rtc_base + RTC_CLOCK_SWITCH);
+		/*
+		 * Set SYS_RTC counter in RTC_HZ HZ Units
+		 * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
+		 * If 16HZ, therefore RTC_DIV = 1023;
+		 */
+		rtc_div = ((32768 / RTC_HZ) / 2) - 1;
+
+		sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV);
+
+		/* reset SYS RTC ALARM0 */
+		sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM0);
+
+		/* reset SYS RTC ALARM1 */
+		sirfsoc_rtc_iobrg_writel(0x0, rtcdrv->rtc_base + RTC_ALARM1);
+	}
+	rtcdrv->overflow_rtc = rtcdrv->saved_overflow_rtc;
+
+	/*
+	 * if current counter is small than previous,
+	 * it means overflow in sleep
+	 */
+	tmp = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
+	if (tmp <= rtcdrv->saved_counter)
+		rtcdrv->overflow_rtc++;
+	/*
+	 *PWRC Value Be Changed When Suspend, Restore Overflow
+	 * In Memory To Register
+	 */
+	sirfsoc_rtc_iobrg_writel(rtcdrv->overflow_rtc,
+			rtcdrv->rtc_base + RTC_SW_VALUE);
+
+	return 0;
+}
+
+static int sirfsoc_rtc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev);
+	sirfsoc_rtc_thaw(dev);
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(rtcdrv->irq);
+
+	return 0;
+}
+
+static int sirfsoc_rtc_restore(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sirfsoc_rtc_drv *rtcdrv = platform_get_drvdata(pdev);
+
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(rtcdrv->irq);
+	return 0;
+}
+
+#else
+#define sirfsoc_rtc_suspend	NULL
+#define sirfsoc_rtc_resume	NULL
+#define sirfsoc_rtc_freeze	NULL
+#define sirfsoc_rtc_thaw	NULL
+#define sirfsoc_rtc_restore	NULL
+#endif
+
+static const struct dev_pm_ops sirfsoc_rtc_pm_ops = {
+	.suspend = sirfsoc_rtc_suspend,
+	.resume = sirfsoc_rtc_resume,
+	.freeze = sirfsoc_rtc_freeze,
+	.thaw = sirfsoc_rtc_thaw,
+	.restore = sirfsoc_rtc_restore,
+};
+
+static struct platform_driver sirfsoc_rtc_driver = {
+	.driver = {
+		.name = "sirfsoc-rtc",
+		.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm = &sirfsoc_rtc_pm_ops,
+#endif
+		.of_match_table = of_match_ptr(sirfsoc_rtc_of_match),
+	},
+	.probe = sirfsoc_rtc_probe,
+	.remove = sirfsoc_rtc_remove,
+};
+module_platform_driver(sirfsoc_rtc_driver);
+
+MODULE_DESCRIPTION("SiRF SoC rtc driver");
+MODULE_AUTHOR("Xianglong Du <Xianglong.Du@csr.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sirfsoc-rtc");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-snvs.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-snvs.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-snvs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-snvs.c	2013-08-25 20:43:22.000000000 -0400
@@ -294,11 +294,6 @@ static int snvs_rtc_probe(struct platfor
 	return 0;
 }
 
-static int snvs_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 #ifdef CONFIG_PM_SLEEP
 static int snvs_rtc_suspend(struct device *dev)
 {
@@ -337,7 +332,6 @@ static struct platform_driver snvs_rtc_d
 		.of_match_table = of_match_ptr(snvs_dt_ids),
 	},
 	.probe		= snvs_rtc_probe,
-	.remove		= snvs_rtc_remove,
 };
 module_platform_driver(snvs_rtc_driver);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-spear.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-spear.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-spear.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-spear.c	2013-08-25 20:43:22.000000000 -0400
@@ -417,7 +417,6 @@ static int spear_rtc_probe(struct platfo
 	return 0;
 
 err_disable_clock:
-	platform_set_drvdata(pdev, NULL);
 	clk_disable_unprepare(config->clk);
 
 	return status;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-starfire.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-starfire.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-starfire.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-starfire.c	2013-08-25 20:43:22.000000000 -0400
@@ -51,17 +51,11 @@ static int __init starfire_rtc_probe(str
 	return 0;
 }
 
-static int __exit starfire_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 static struct platform_driver starfire_rtc_driver = {
 	.driver		= {
 		.name	= "rtc-starfire",
 		.owner	= THIS_MODULE,
 	},
-	.remove		= __exit_p(starfire_rtc_remove),
 };
 
 module_platform_driver_probe(starfire_rtc_driver, starfire_rtc_probe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-stmp3xxx.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-stmp3xxx.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-stmp3xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-stmp3xxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/delay.h>
 #include <linux/rtc.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -119,24 +120,39 @@ static void stmp3xxx_wdt_register(struct
 }
 #endif /* CONFIG_STMP3XXX_RTC_WATCHDOG */
 
-static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data)
+static int stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data)
 {
+	int timeout = 5000; /* 3ms according to i.MX28 Ref Manual */
 	/*
-	 * The datasheet doesn't say which way round the
-	 * NEW_REGS/STALE_REGS bitfields go. In fact it's 0x1=P0,
-	 * 0x2=P1, .., 0x20=P5, 0x40=ALARM, 0x80=SECONDS
+	 * The i.MX28 Applications Processor Reference Manual, Rev. 1, 2010
+	 * states:
+	 * | The order in which registers are updated is
+	 * | Persistent 0, 1, 2, 3, 4, 5, Alarm, Seconds.
+	 * | (This list is in bitfield order, from LSB to MSB, as they would
+	 * | appear in the STALE_REGS and NEW_REGS bitfields of the HW_RTC_STAT
+	 * | register. For example, the Seconds register corresponds to
+	 * | STALE_REGS or NEW_REGS containing 0x80.)
 	 */
-	while (readl(rtc_data->io + STMP3XXX_RTC_STAT) &
-			(0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT))
-		cpu_relax();
+	do {
+		if (!(readl(rtc_data->io + STMP3XXX_RTC_STAT) &
+				(0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)))
+			return 0;
+		udelay(1);
+	} while (--timeout > 0);
+	return (readl(rtc_data->io + STMP3XXX_RTC_STAT) &
+		(0x80 << STMP3XXX_RTC_STAT_STALE_SHIFT)) ? -ETIME : 0;
 }
 
 /* Time read/write */
 static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
 {
+	int ret;
 	struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
 
-	stmp3xxx_wait_time(rtc_data);
+	ret = stmp3xxx_wait_time(rtc_data);
+	if (ret)
+		return ret;
+
 	rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm);
 	return 0;
 }
@@ -146,8 +162,7 @@ static int stmp3xxx_rtc_set_mmss(struct
 	struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
 
 	writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS);
-	stmp3xxx_wait_time(rtc_data);
-	return 0;
+	return stmp3xxx_wait_time(rtc_data);
 }
 
 /* interrupt(s) handler */
@@ -225,7 +240,6 @@ static int stmp3xxx_rtc_remove(struct pl
 
 	writel(STMP3XXX_RTC_CTRL_ALARM_IRQ_EN,
 			rtc_data->io + STMP3XXX_RTC_CTRL_CLR);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
@@ -262,7 +276,12 @@ static int stmp3xxx_rtc_probe(struct pla
 
 	platform_set_drvdata(pdev, rtc_data);
 
-	stmp_reset_block(rtc_data->io);
+	err = stmp_reset_block(rtc_data->io);
+	if (err) {
+		dev_err(&pdev->dev, "stmp_reset_block failed: %d\n", err);
+		return err;
+	}
+
 	writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
 			STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
 			STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE,
@@ -274,25 +293,19 @@ static int stmp3xxx_rtc_probe(struct pla
 
 	rtc_data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 				&stmp3xxx_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc_data->rtc)) {
-		err = PTR_ERR(rtc_data->rtc);
-		goto out;
-	}
+	if (IS_ERR(rtc_data->rtc))
+		return PTR_ERR(rtc_data->rtc);
 
 	err = devm_request_irq(&pdev->dev, rtc_data->irq_alarm,
 			stmp3xxx_rtc_interrupt, 0, "RTC alarm", &pdev->dev);
 	if (err) {
 		dev_err(&pdev->dev, "Cannot claim IRQ%d\n",
 			rtc_data->irq_alarm);
-		goto out;
+		return err;
 	}
 
 	stmp3xxx_wdt_register(pdev);
 	return 0;
-
-out:
-	platform_set_drvdata(pdev, NULL);
-	return err;
 }
 
 #ifdef CONFIG_PM_SLEEP
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-sun4v.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sun4v.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-sun4v.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sun4v.c	2013-08-25 20:43:22.000000000 -0400
@@ -92,17 +92,11 @@ static int __init sun4v_rtc_probe(struct
 	return 0;
 }
 
-static int __exit sun4v_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 static struct platform_driver sun4v_rtc_driver = {
 	.driver		= {
 		.name	= "rtc-sun4v",
 		.owner	= THIS_MODULE,
 	},
-	.remove		= __exit_p(sun4v_rtc_remove),
 };
 
 module_platform_driver_probe(sun4v_rtc_driver, sun4v_rtc_probe);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-sysfs.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sysfs.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -164,6 +164,7 @@ rtc_sysfs_set_wakealarm(struct device *d
 {
 	ssize_t retval;
 	unsigned long now, alarm;
+	unsigned long push = 0;
 	struct rtc_wkalrm alm;
 	struct rtc_device *rtc = to_rtc_device(dev);
 	char *buf_ptr;
@@ -180,13 +181,17 @@ rtc_sysfs_set_wakealarm(struct device *d
 	buf_ptr = (char *)buf;
 	if (*buf_ptr == '+') {
 		buf_ptr++;
-		adjust = 1;
+		if (*buf_ptr == '=') {
+			buf_ptr++;
+			push = 1;
+		} else
+			adjust = 1;
 	}
 	alarm = simple_strtoul(buf_ptr, NULL, 0);
 	if (adjust) {
 		alarm += now;
 	}
-	if (alarm > now) {
+	if (alarm > now || push) {
 		/* Avoid accidentally clobbering active alarms; we can't
 		 * entirely prevent that here, without even the minimal
 		 * locking from the /dev/rtcN api.
@@ -194,9 +199,14 @@ rtc_sysfs_set_wakealarm(struct device *d
 		retval = rtc_read_alarm(rtc, &alm);
 		if (retval < 0)
 			return retval;
-		if (alm.enabled)
-			return -EBUSY;
-
+		if (alm.enabled) {
+			if (push) {
+				rtc_tm_to_time(&alm.time, &push);
+				alarm += push;
+			} else
+				return -EBUSY;
+		} else if (push)
+			return -EINVAL;
 		alm.enabled = 1;
 	} else {
 		alm.enabled = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-tile.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-tile.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-tile.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-tile.c	2013-08-25 20:43:22.000000000 -0400
@@ -91,23 +91,12 @@ static int tile_rtc_probe(struct platfor
 	return 0;
 }
 
-/*
- * Device cleanup routine.
- */
-static int tile_rtc_remove(struct platform_device *dev)
-{
-	platform_set_drvdata(dev, NULL);
-
-	return 0;
-}
-
 static struct platform_driver tile_rtc_platform_driver = {
 	.driver		= {
 		.name	= "rtc-tile",
 		.owner	= THIS_MODULE,
 	},
 	.probe		= tile_rtc_probe,
-	.remove		= tile_rtc_remove,
 };
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-tps80031.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-tps80031.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-tps80031.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-tps80031.c	2013-08-25 20:43:22.000000000 -0400
@@ -298,11 +298,6 @@ static int tps80031_rtc_probe(struct pla
 	return 0;
 }
 
-static int tps80031_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 #ifdef CONFIG_PM_SLEEP
 static int tps80031_rtc_suspend(struct device *dev)
 {
@@ -333,7 +328,6 @@ static struct platform_driver tps80031_r
 		.pm	= &tps80031_pm_ops,
 	},
 	.probe	= tps80031_rtc_probe,
-	.remove	= tps80031_rtc_remove,
 };
 
 module_platform_driver(tps80031_rtc_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-twl.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-twl.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-twl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-twl.c	2013-08-25 20:43:22.000000000 -0400
@@ -213,12 +213,24 @@ static int mask_rtc_irq_bit(unsigned cha
 
 static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
 {
+	struct platform_device *pdev = to_platform_device(dev);
+	int irq = platform_get_irq(pdev, 0);
+	static bool twl_rtc_wake_enabled;
 	int ret;
 
-	if (enabled)
+	if (enabled) {
 		ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-	else
+		if (device_can_wakeup(dev) && !twl_rtc_wake_enabled) {
+			enable_irq_wake(irq);
+			twl_rtc_wake_enabled = true;
+		}
+	} else {
 		ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+		if (twl_rtc_wake_enabled) {
+			disable_irq_wake(irq);
+			twl_rtc_wake_enabled = false;
+		}
+	}
 
 	return ret;
 }
@@ -469,6 +481,12 @@ static int twl_rtc_probe(struct platform
 	if (irq <= 0)
 		goto out1;
 
+	/* Initialize the register map */
+	if (twl_class_is_4030())
+		rtc_reg_map = (u8 *)twl4030_rtc_reg_map;
+	else
+		rtc_reg_map = (u8 *)twl6030_rtc_reg_map;
+
 	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
 	if (ret < 0)
 		goto out1;
@@ -506,6 +524,8 @@ static int twl_rtc_probe(struct platform
 	if (ret < 0)
 		goto out1;
 
+	device_init_wakeup(&pdev->dev, 1);
+
 	rtc = rtc_device_register(pdev->name,
 				  &pdev->dev, &twl_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc)) {
@@ -524,7 +544,6 @@ static int twl_rtc_probe(struct platform
 	}
 
 	platform_set_drvdata(pdev, rtc);
-	device_init_wakeup(&pdev->dev, 1);
 	return 0;
 
 out2:
@@ -556,7 +575,6 @@ static int twl_rtc_remove(struct platfor
 	free_irq(irq, rtc);
 
 	rtc_device_unregister(rtc);
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
@@ -609,22 +627,7 @@ static struct platform_driver twl4030rtc
 	},
 };
 
-static int __init twl_rtc_init(void)
-{
-	if (twl_class_is_4030())
-		rtc_reg_map = (u8 *) twl4030_rtc_reg_map;
-	else
-		rtc_reg_map = (u8 *) twl6030_rtc_reg_map;
-
-	return platform_driver_register(&twl4030rtc_driver);
-}
-module_init(twl_rtc_init);
-
-static void __exit twl_rtc_exit(void)
-{
-	platform_driver_unregister(&twl4030rtc_driver);
-}
-module_exit(twl_rtc_exit);
+module_platform_driver(twl4030rtc_driver);
 
 MODULE_AUTHOR("Texas Instruments, MontaVista Software");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-v3020.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-v3020.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-v3020.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-v3020.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,7 +16,7 @@
  *				- Use the generic rtc class
  *
  *  ??-???-2004: Someone at Compulab
- *  			- Initial driver creation.
+ *			- Initial driver creation.
  *
  */
 #include <linux/platform_device.h>
@@ -278,13 +278,13 @@ static int v3020_set_time(struct device
 	dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
 
 	/* Write all the values to ram... */
-	v3020_set_reg(chip, V3020_SECONDS, 	bin2bcd(dt->tm_sec));
-	v3020_set_reg(chip, V3020_MINUTES, 	bin2bcd(dt->tm_min));
-	v3020_set_reg(chip, V3020_HOURS, 	bin2bcd(dt->tm_hour));
+	v3020_set_reg(chip, V3020_SECONDS,	bin2bcd(dt->tm_sec));
+	v3020_set_reg(chip, V3020_MINUTES,	bin2bcd(dt->tm_min));
+	v3020_set_reg(chip, V3020_HOURS,	bin2bcd(dt->tm_hour));
 	v3020_set_reg(chip, V3020_MONTH_DAY,	bin2bcd(dt->tm_mday));
-	v3020_set_reg(chip, V3020_MONTH,     bin2bcd(dt->tm_mon + 1));
-	v3020_set_reg(chip, V3020_WEEK_DAY, 	bin2bcd(dt->tm_wday));
-	v3020_set_reg(chip, V3020_YEAR, 	bin2bcd(dt->tm_year % 100));
+	v3020_set_reg(chip, V3020_MONTH,	bin2bcd(dt->tm_mon + 1));
+	v3020_set_reg(chip, V3020_WEEK_DAY,	bin2bcd(dt->tm_wday));
+	v3020_set_reg(chip, V3020_YEAR,		bin2bcd(dt->tm_year % 100));
 
 	/* ...and set the clock. */
 	v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0);
@@ -320,7 +320,7 @@ static int rtc_probe(struct platform_dev
 
 	retval = chip->ops->map_io(chip, pdev, pdata);
 	if (retval)
-		goto err_chip;
+		return retval;
 
 	/* Make sure the v3020 expects a communication cycle
 	 * by reading 8 times */
@@ -364,7 +364,7 @@ static int rtc_probe(struct platform_dev
 
 err_io:
 	chip->ops->unmap_io(chip);
-err_chip:
+
 	return retval;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-vr41xx.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-vr41xx.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-vr41xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-vr41xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -103,7 +103,7 @@ static inline unsigned long read_elapsed
 		second_mid = rtc1_read(ETIMEMREG);
 		second_high = rtc1_read(ETIMEHREG);
 	} while (first_low != second_low || first_mid != second_mid ||
-	         first_high != second_high);
+		 first_high != second_high);
 
 	return (first_high << 17) | (first_mid << 1) | (first_low >> 15);
 }
@@ -154,7 +154,7 @@ static int vr41xx_rtc_set_time(struct de
 
 	epoch_sec = mktime(epoch, 1, 1, 0, 0, 0);
 	current_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
-	                     time->tm_hour, time->tm_min, time->tm_sec);
+			     time->tm_hour, time->tm_min, time->tm_sec);
 
 	write_elapsed_second(current_sec - epoch_sec);
 
@@ -186,7 +186,7 @@ static int vr41xx_rtc_set_alarm(struct d
 	struct rtc_time *time = &wkalrm->time;
 
 	alarm_sec = mktime(time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
-	                   time->tm_hour, time->tm_min, time->tm_sec);
+			   time->tm_hour, time->tm_min, time->tm_sec);
 
 	spin_lock_irq(&rtc_lock);
 
@@ -334,16 +334,18 @@ static int rtc_probe(struct platform_dev
 	}
 
 	retval = request_irq(aie_irq, elapsedtime_interrupt, 0,
-	                     "elapsed_time", pdev);
+			     "elapsed_time", pdev);
 	if (retval < 0)
 		goto err_device_unregister;
 
 	pie_irq = platform_get_irq(pdev, 1);
-	if (pie_irq <= 0)
+	if (pie_irq <= 0) {
+		retval = -EBUSY;
 		goto err_free_irq;
+	}
 
 	retval = request_irq(pie_irq, rtclong1_interrupt, 0,
-		             "rtclong1", pdev);
+			     "rtclong1", pdev);
 	if (retval < 0)
 		goto err_free_irq;
 
@@ -381,8 +383,6 @@ static int rtc_remove(struct platform_de
 	if (rtc)
 		rtc_device_unregister(rtc);
 
-	platform_set_drvdata(pdev, NULL);
-
 	free_irq(aie_irq, pdev);
 	free_irq(pie_irq, pdev);
 	if (rtc1_base)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-vt8500.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-vt8500.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-vt8500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-vt8500.c	2013-08-25 20:43:22.000000000 -0400
@@ -282,8 +282,6 @@ static int vt8500_rtc_remove(struct plat
 	/* Disable alarm matching */
 	writel(0, vt8500_rtc->regbase + VT8500_RTC_IS);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-wm831x.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-wm831x.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-wm831x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-wm831x.c	2013-08-25 20:43:22.000000000 -0400
@@ -460,11 +460,6 @@ err:
 	return ret;
 }
 
-static int wm831x_rtc_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
 static const struct dev_pm_ops wm831x_rtc_pm_ops = {
 	.suspend = wm831x_rtc_suspend,
 	.resume = wm831x_rtc_resume,
@@ -478,7 +473,6 @@ static const struct dev_pm_ops wm831x_rt
 
 static struct platform_driver wm831x_rtc_driver = {
 	.probe = wm831x_rtc_probe,
-	.remove = wm831x_rtc_remove,
 	.driver = {
 		.name = "wm831x-rtc",
 		.pm = &wm831x_rtc_pm_ops,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/rtc/rtc-x1205.c linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-x1205.c
--- linux-libre-3.10-gnu/drivers/rtc/rtc-x1205.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/rtc/rtc-x1205.c	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,7 @@
  * Copyright 2005 Alessandro Zummo
  *
  * please send all reports to:
- * 	Karen Spearel <kas111 at gmail dot com>
+ *	Karen Spearel <kas111 at gmail dot com>
  *	Alessandro Zummo <a.zummo@towertech.it>
  *
  * based on a lot of other RTC drivers.
@@ -215,12 +215,14 @@ static int x1205_set_datetime(struct i2c
 			buf[i] |= 0x80;
 
 	/* this sequence is required to unlock the chip */
-	if ((xfer = i2c_master_send(client, wel, 3)) != 3) {
+	xfer = i2c_master_send(client, wel, 3);
+	if (xfer != 3) {
 		dev_err(&client->dev, "%s: wel - %d\n", __func__, xfer);
 		return -EIO;
 	}
 
-	if ((xfer = i2c_master_send(client, rwel, 3)) != 3) {
+	xfer = i2c_master_send(client, rwel, 3);
+	if (xfer != 3) {
 		dev_err(&client->dev, "%s: rwel - %d\n", __func__, xfer);
 		return -EIO;
 	}
@@ -269,7 +271,8 @@ static int x1205_set_datetime(struct i2c
 	}
 
 	/* disable further writes */
-	if ((xfer = i2c_master_send(client, diswe, 3)) != 3) {
+	xfer = i2c_master_send(client, diswe, 3);
+	if (xfer != 3) {
 		dev_err(&client->dev, "%s: diswe - %d\n", __func__, xfer);
 		return -EIO;
 	}
@@ -375,8 +378,7 @@ static int x1205_get_atrim(struct i2c_cl
 	return 0;
 }
 
-struct x1205_limit
-{
+struct x1205_limit {
 	unsigned char reg, mask, min, max;
 };
 
@@ -430,7 +432,8 @@ static int x1205_validate_client(struct
 			},
 		};
 
-		if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
+		xfer = i2c_transfer(client->adapter, msgs, 2);
+		if (xfer != 2) {
 			dev_err(&client->dev,
 				"%s: could not read register %x\n",
 				__func__, probe_zero_pattern[i]);
@@ -467,7 +470,8 @@ static int x1205_validate_client(struct
 			},
 		};
 
-		if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) {
+		xfer = i2c_transfer(client->adapter, msgs, 2);
+		if (xfer != 2) {
 			dev_err(&client->dev,
 				"%s: could not read register %x\n",
 				__func__, probe_limits_pattern[i].reg);
@@ -548,10 +552,12 @@ static int x1205_rtc_proc(struct device
 {
 	int err, dtrim, atrim;
 
-	if ((err = x1205_get_dtrim(to_i2c_client(dev), &dtrim)) == 0)
+	err = x1205_get_dtrim(to_i2c_client(dev), &dtrim);
+	if (!err)
 		seq_printf(seq, "digital_trim\t: %d ppm\n", dtrim);
 
-	if ((err = x1205_get_atrim(to_i2c_client(dev), &atrim)) == 0)
+	err = x1205_get_atrim(to_i2c_client(dev), &atrim);
+	if (!err)
 		seq_printf(seq, "analog_trim\t: %d.%02d pF\n",
 			atrim / 1000, atrim % 1000);
 	return 0;
@@ -639,7 +645,8 @@ static int x1205_probe(struct i2c_client
 	i2c_set_clientdata(client, rtc);
 
 	/* Check for power failures and eventually enable the osc */
-	if ((err = x1205_get_status(client, &sr)) == 0) {
+	err = x1205_get_status(client, &sr);
+	if (!err) {
 		if (sr & X1205_SR_RTCF) {
 			dev_err(&client->dev,
 				"power failure detected, "
@@ -647,9 +654,9 @@ static int x1205_probe(struct i2c_client
 			udelay(50);
 			x1205_fix_osc(client);
 		}
-	}
-	else
+	} else {
 		dev_err(&client->dev, "couldn't read status\n");
+	}
 
 	err = x1205_sysfs_register(&client->dev);
 	if (err)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/block/dasd.c linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd.c
--- linux-libre-3.10-gnu/drivers/s390/block/dasd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,9 +38,6 @@
  */
 #define DASD_CHANQ_MAX_SIZE 4
 
-#define DASD_SLEEPON_START_TAG	(void *) 1
-#define DASD_SLEEPON_END_TAG	(void *) 2
-
 /*
  * SECTION: exported variables of dasd.c
  */
@@ -1787,11 +1784,11 @@ static void __dasd_device_process_ccw_qu
 	list_for_each_safe(l, n, &device->ccw_queue) {
 		cqr = list_entry(l, struct dasd_ccw_req, devlist);
 
-		/* Stop list processing at the first non-final request. */
+		/* Skip any non-final request. */
 		if (cqr->status == DASD_CQR_QUEUED ||
 		    cqr->status == DASD_CQR_IN_IO ||
 		    cqr->status == DASD_CQR_CLEAR_PENDING)
-			break;
+			continue;
 		if (cqr->status == DASD_CQR_ERROR) {
 			__dasd_device_recovery(device, cqr);
 		}
@@ -2183,7 +2180,7 @@ static int _dasd_sleep_on(struct dasd_cc
 		    test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
 		    (!dasd_eer_enabled(device))) {
 			cqr->status = DASD_CQR_FAILED;
-			cqr->intrc = -EAGAIN;
+			cqr->intrc = -ENOLINK;
 			continue;
 		}
 		/* Don't try to start requests if device is stopped */
@@ -2395,6 +2392,12 @@ int dasd_sleep_on_immediatly(struct dasd
 		rc = cqr->intrc;
 	else
 		rc = -EIO;
+
+	/* kick tasklets */
+	dasd_schedule_device_bh(device);
+	if (device->block)
+		dasd_schedule_block_bh(device->block);
+
 	return rc;
 }
 
@@ -2402,8 +2405,7 @@ int dasd_sleep_on_immediatly(struct dasd
  * Cancels a request that was started with dasd_sleep_on_req.
  * This is useful to timeout requests. The request will be
  * terminated if it is currently in i/o.
- * Returns 1 if the request has been terminated.
- *	   0 if there was no need to terminate the request (not started yet)
+ * Returns 0 if request termination was successful
  *	   negative error code if termination failed
  * Cancellation of a request is an asynchronous operation! The calling
  * function has to wait until the request is properly returned via callback.
@@ -2440,7 +2442,6 @@ int dasd_cancel_req(struct dasd_ccw_req
 	return rc;
 }
 
-
 /*
  * SECTION: Operations of the dasd_block layer.
  */
@@ -2537,6 +2538,16 @@ static void __dasd_process_request_queue
 			__blk_end_request_all(req, -EIO);
 			continue;
 		}
+		if (test_bit(DASD_FLAG_ABORTALL, &basedev->flags) &&
+		    (basedev->features & DASD_FEATURE_FAILFAST ||
+		     blk_noretry_request(req))) {
+			DBF_DEV_EVENT(DBF_ERR, basedev,
+				      "Rejecting failfast request %p",
+				      req);
+			blk_start_request(req);
+			__blk_end_request_all(req, -ETIMEDOUT);
+			continue;
+		}
 		cqr = basedev->discipline->build_cp(basedev, block, req);
 		if (IS_ERR(cqr)) {
 			if (PTR_ERR(cqr) == -EBUSY)
@@ -2575,8 +2586,10 @@ static void __dasd_process_request_queue
 		 */
 		cqr->callback_data = (void *) req;
 		cqr->status = DASD_CQR_FILLED;
+		req->completion_data = cqr;
 		blk_start_request(req);
 		list_add_tail(&cqr->blocklist, &block->ccw_queue);
+		INIT_LIST_HEAD(&cqr->devlist);
 		dasd_profile_start(block, cqr, req);
 	}
 }
@@ -2590,8 +2603,17 @@ static void __dasd_cleanup_cqr(struct da
 	req = (struct request *) cqr->callback_data;
 	dasd_profile_end(cqr->block, cqr, req);
 	status = cqr->block->base->discipline->free_cp(cqr, req);
-	if (status <= 0)
-		error = status ? status : -EIO;
+	if (status < 0)
+		error = status;
+	else if (status == 0) {
+		if (cqr->intrc == -EPERM)
+			error = -EBADE;
+		else if (cqr->intrc == -ENOLINK ||
+			 cqr->intrc == -ETIMEDOUT)
+			error = cqr->intrc;
+		else
+			error = -EIO;
+	}
 	__blk_end_request_all(req, error);
 }
 
@@ -2692,6 +2714,7 @@ static void __dasd_block_start_head(stru
 		    test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
 		    (!dasd_eer_enabled(block->base))) {
 			cqr->status = DASD_CQR_FAILED;
+			cqr->intrc = -ENOLINK;
 			dasd_schedule_block_bh(block);
 			continue;
 		}
@@ -2864,6 +2887,82 @@ static void do_dasd_request(struct reque
 }
 
 /*
+ * Block timeout callback, called from the block layer
+ *
+ * request_queue lock is held on entry.
+ *
+ * Return values:
+ * BLK_EH_RESET_TIMER if the request should be left running
+ * BLK_EH_NOT_HANDLED if the request is handled or terminated
+ *		      by the driver.
+ */
+enum blk_eh_timer_return dasd_times_out(struct request *req)
+{
+	struct dasd_ccw_req *cqr = req->completion_data;
+	struct dasd_block *block = req->q->queuedata;
+	struct dasd_device *device;
+	int rc = 0;
+
+	if (!cqr)
+		return BLK_EH_NOT_HANDLED;
+
+	device = cqr->startdev ? cqr->startdev : block->base;
+	if (!device->blk_timeout)
+		return BLK_EH_RESET_TIMER;
+	DBF_DEV_EVENT(DBF_WARNING, device,
+		      " dasd_times_out cqr %p status %x",
+		      cqr, cqr->status);
+
+	spin_lock(&block->queue_lock);
+	spin_lock(get_ccwdev_lock(device->cdev));
+	cqr->retries = -1;
+	cqr->intrc = -ETIMEDOUT;
+	if (cqr->status >= DASD_CQR_QUEUED) {
+		spin_unlock(get_ccwdev_lock(device->cdev));
+		rc = dasd_cancel_req(cqr);
+	} else if (cqr->status == DASD_CQR_FILLED ||
+		   cqr->status == DASD_CQR_NEED_ERP) {
+		cqr->status = DASD_CQR_TERMINATED;
+		spin_unlock(get_ccwdev_lock(device->cdev));
+	} else if (cqr->status == DASD_CQR_IN_ERP) {
+		struct dasd_ccw_req *searchcqr, *nextcqr, *tmpcqr;
+
+		list_for_each_entry_safe(searchcqr, nextcqr,
+					 &block->ccw_queue, blocklist) {
+			tmpcqr = searchcqr;
+			while (tmpcqr->refers)
+				tmpcqr = tmpcqr->refers;
+			if (tmpcqr != cqr)
+				continue;
+			/* searchcqr is an ERP request for cqr */
+			searchcqr->retries = -1;
+			searchcqr->intrc = -ETIMEDOUT;
+			if (searchcqr->status >= DASD_CQR_QUEUED) {
+				spin_unlock(get_ccwdev_lock(device->cdev));
+				rc = dasd_cancel_req(searchcqr);
+				spin_lock(get_ccwdev_lock(device->cdev));
+			} else if ((searchcqr->status == DASD_CQR_FILLED) ||
+				   (searchcqr->status == DASD_CQR_NEED_ERP)) {
+				searchcqr->status = DASD_CQR_TERMINATED;
+				rc = 0;
+			} else if (searchcqr->status == DASD_CQR_IN_ERP) {
+				/*
+				 * Shouldn't happen; most recent ERP
+				 * request is at the front of queue
+				 */
+				continue;
+			}
+			break;
+		}
+		spin_unlock(get_ccwdev_lock(device->cdev));
+	}
+	dasd_schedule_block_bh(block);
+	spin_unlock(&block->queue_lock);
+
+	return rc ? BLK_EH_RESET_TIMER : BLK_EH_NOT_HANDLED;
+}
+
+/*
  * Allocate and initialize request queue and default I/O scheduler.
  */
 static int dasd_alloc_queue(struct dasd_block *block)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/block/dasd_devmap.c linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_devmap.c
--- linux-libre-3.10-gnu/drivers/s390/block/dasd_devmap.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_devmap.c	2013-08-25 20:43:22.000000000 -0400
@@ -1240,6 +1240,101 @@ dasd_expires_store(struct device *dev, s
 
 static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
 
+static ssize_t
+dasd_retries_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct dasd_device *device;
+	int len;
+
+	device = dasd_device_from_cdev(to_ccwdev(dev));
+	if (IS_ERR(device))
+		return -ENODEV;
+	len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_retries);
+	dasd_put_device(device);
+	return len;
+}
+
+static ssize_t
+dasd_retries_store(struct device *dev, struct device_attribute *attr,
+		   const char *buf, size_t count)
+{
+	struct dasd_device *device;
+	unsigned long val;
+
+	device = dasd_device_from_cdev(to_ccwdev(dev));
+	if (IS_ERR(device))
+		return -ENODEV;
+
+	if ((strict_strtoul(buf, 10, &val) != 0) ||
+	    (val > DASD_RETRIES_MAX)) {
+		dasd_put_device(device);
+		return -EINVAL;
+	}
+
+	if (val)
+		device->default_retries = val;
+
+	dasd_put_device(device);
+	return count;
+}
+
+static DEVICE_ATTR(retries, 0644, dasd_retries_show, dasd_retries_store);
+
+static ssize_t
+dasd_timeout_show(struct device *dev, struct device_attribute *attr,
+		  char *buf)
+{
+	struct dasd_device *device;
+	int len;
+
+	device = dasd_device_from_cdev(to_ccwdev(dev));
+	if (IS_ERR(device))
+		return -ENODEV;
+	len = snprintf(buf, PAGE_SIZE, "%lu\n", device->blk_timeout);
+	dasd_put_device(device);
+	return len;
+}
+
+static ssize_t
+dasd_timeout_store(struct device *dev, struct device_attribute *attr,
+		   const char *buf, size_t count)
+{
+	struct dasd_device *device;
+	struct request_queue *q;
+	unsigned long val, flags;
+
+	device = dasd_device_from_cdev(to_ccwdev(dev));
+	if (IS_ERR(device) || !device->block)
+		return -ENODEV;
+
+	if ((strict_strtoul(buf, 10, &val) != 0) ||
+	    val > UINT_MAX / HZ) {
+		dasd_put_device(device);
+		return -EINVAL;
+	}
+	q = device->block->request_queue;
+	if (!q) {
+		dasd_put_device(device);
+		return -ENODEV;
+	}
+	spin_lock_irqsave(&device->block->request_queue_lock, flags);
+	if (!val)
+		blk_queue_rq_timed_out(q, NULL);
+	else
+		blk_queue_rq_timed_out(q, dasd_times_out);
+
+	device->blk_timeout = val;
+
+	blk_queue_rq_timeout(q, device->blk_timeout * HZ);
+	spin_unlock_irqrestore(&device->block->request_queue_lock, flags);
+
+	dasd_put_device(device);
+	return count;
+}
+
+static DEVICE_ATTR(timeout, 0644,
+		   dasd_timeout_show, dasd_timeout_store);
+
 static ssize_t dasd_reservation_policy_show(struct device *dev,
 					    struct device_attribute *attr,
 					    char *buf)
@@ -1350,6 +1445,8 @@ static struct attribute * dasd_attrs[] =
 	&dev_attr_erplog.attr,
 	&dev_attr_failfast.attr,
 	&dev_attr_expires.attr,
+	&dev_attr_retries.attr,
+	&dev_attr_timeout.attr,
 	&dev_attr_reservation_policy.attr,
 	&dev_attr_last_known_reservation_state.attr,
 	&dev_attr_safe_offline.attr,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/block/dasd_diag.c linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_diag.c
--- linux-libre-3.10-gnu/drivers/s390/block/dasd_diag.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_diag.c	2013-08-25 20:43:22.000000000 -0400
@@ -359,6 +359,7 @@ dasd_diag_check_device(struct dasd_devic
 	}
 
 	device->default_expires = DIAG_TIMEOUT;
+	device->default_retries = DIAG_MAX_RETRIES;
 
 	/* Figure out position of label block */
 	switch (private->rdc_data.vdev_class) {
@@ -555,7 +556,7 @@ static struct dasd_ccw_req *dasd_diag_bu
 			recid++;
 		}
 	}
-	cqr->retries = DIAG_MAX_RETRIES;
+	cqr->retries = memdev->default_retries;
 	cqr->buildclk = get_tod_clock();
 	if (blk_noretry_request(req) ||
 	    block->base->features & DASD_FEATURE_FAILFAST)
@@ -582,7 +583,10 @@ dasd_diag_free_cp(struct dasd_ccw_req *c
 
 static void dasd_diag_handle_terminated_request(struct dasd_ccw_req *cqr)
 {
-	cqr->status = DASD_CQR_FILLED;
+	if (cqr->retries < 0)
+		cqr->status = DASD_CQR_FAILED;
+	else
+		cqr->status = DASD_CQR_FILLED;
 };
 
 /* Fill in IOCTL data for device. */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/block/dasd_eckd.c linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_eckd.c
--- linux-libre-3.10-gnu/drivers/s390/block/dasd_eckd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_eckd.c	2013-08-25 20:43:22.000000000 -0400
@@ -1682,6 +1682,9 @@ dasd_eckd_check_characteristics(struct d
 
 	/* set default timeout */
 	device->default_expires = DASD_EXPIRES;
+	/* set default retry count */
+	device->default_retries = DASD_RETRIES;
+
 	if (private->gneq) {
 		value = 1;
 		for (i = 0; i < private->gneq->timeout.value; i++)
@@ -2378,6 +2381,10 @@ sleep:
 
 static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr)
 {
+	if (cqr->retries < 0) {
+		cqr->status = DASD_CQR_FAILED;
+		return;
+	}
 	cqr->status = DASD_CQR_FILLED;
 	if (cqr->block && (cqr->startdev != cqr->block->base)) {
 		dasd_eckd_reset_ccw_to_base_io(cqr);
@@ -2659,7 +2666,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	cqr->block = block;
 	cqr->expires = startdev->default_expires * HZ;	/* default 5 minutes */
 	cqr->lpm = startdev->path_data.ppm;
-	cqr->retries = 256;
+	cqr->retries = startdev->default_retries;
 	cqr->buildclk = get_tod_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
@@ -2834,7 +2841,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	cqr->block = block;
 	cqr->expires = startdev->default_expires * HZ;	/* default 5 minutes */
 	cqr->lpm = startdev->path_data.ppm;
-	cqr->retries = 256;
+	cqr->retries = startdev->default_retries;
 	cqr->buildclk = get_tod_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
@@ -2968,7 +2975,7 @@ static int prepare_itcw(struct itcw *itc
 
 	dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
 		     &pfxdata, sizeof(pfxdata), total_data_size);
-	return IS_ERR(dcw) ? PTR_ERR(dcw) : 0;
+	return PTR_RET(dcw);
 }
 
 static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
@@ -3127,7 +3134,7 @@ static struct dasd_ccw_req *dasd_eckd_bu
 	cqr->block = block;
 	cqr->expires = startdev->default_expires * HZ;	/* default 5 minutes */
 	cqr->lpm = startdev->path_data.ppm;
-	cqr->retries = 256;
+	cqr->retries = startdev->default_retries;
 	cqr->buildclk = get_tod_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
@@ -3330,7 +3337,7 @@ static struct dasd_ccw_req *dasd_raw_bui
 	cqr->block = block;
 	cqr->expires = startdev->default_expires * HZ;
 	cqr->lpm = startdev->path_data.ppm;
-	cqr->retries = 256;
+	cqr->retries = startdev->default_retries;
 	cqr->buildclk = get_tod_clock();
 	cqr->status = DASD_CQR_FILLED;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/block/dasd_erp.c linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_erp.c
--- linux-libre-3.10-gnu/drivers/s390/block/dasd_erp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_erp.c	2013-08-25 20:43:22.000000000 -0400
@@ -159,6 +159,14 @@ dasd_log_sense(struct dasd_ccw_req *cqr,
 	struct dasd_device *device;
 
 	device = cqr->startdev;
+	if (cqr->intrc == -ETIMEDOUT) {
+		dev_err(&device->cdev->dev, "cqr %p timeout error", cqr);
+		return;
+	}
+	if (cqr->intrc == -ENOLINK) {
+		dev_err(&device->cdev->dev, "cqr %p transport error", cqr);
+		return;
+	}
 	/* dump sense data */
 	if (device->discipline && device->discipline->dump_sense)
 		device->discipline->dump_sense(device, cqr, irb);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/block/dasd_fba.c linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_fba.c
--- linux-libre-3.10-gnu/drivers/s390/block/dasd_fba.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_fba.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,8 @@
 #endif				/* PRINTK_HEADER */
 #define PRINTK_HEADER "dasd(fba):"
 
+#define FBA_DEFAULT_RETRIES 32
+
 #define DASD_FBA_CCW_WRITE 0x41
 #define DASD_FBA_CCW_READ 0x42
 #define DASD_FBA_CCW_LOCATE 0x43
@@ -167,6 +169,7 @@ dasd_fba_check_characteristics(struct da
 	}
 
 	device->default_expires = DASD_EXPIRES;
+	device->default_retries = FBA_DEFAULT_RETRIES;
 	device->path_data.opm = LPM_ANYPATH;
 
 	readonly = dasd_device_is_ro(device);
@@ -369,7 +372,7 @@ static struct dasd_ccw_req *dasd_fba_bui
 	cqr->memdev = memdev;
 	cqr->block = block;
 	cqr->expires = memdev->default_expires * HZ;	/* default 5 minutes */
-	cqr->retries = 32;
+	cqr->retries = memdev->default_retries;
 	cqr->buildclk = get_tod_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
@@ -425,7 +428,10 @@ out:
 
 static void dasd_fba_handle_terminated_request(struct dasd_ccw_req *cqr)
 {
-	cqr->status = DASD_CQR_FILLED;
+	if (cqr->retries < 0)
+		cqr->status = DASD_CQR_FAILED;
+	else
+		cqr->status = DASD_CQR_FILLED;
 };
 
 static int
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/block/dasd_int.h linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_int.h
--- linux-libre-3.10-gnu/drivers/s390/block/dasd_int.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_int.h	2013-08-25 20:43:22.000000000 -0400
@@ -224,6 +224,8 @@ struct dasd_ccw_req {
 /* default expiration time*/
 #define DASD_EXPIRES	  300
 #define DASD_EXPIRES_MAX  40000000
+#define DASD_RETRIES	  256
+#define DASD_RETRIES_MAX  32768
 
 /* per dasd_ccw_req flags */
 #define DASD_CQR_FLAGS_USE_ERP   0	/* use ERP for this request */
@@ -466,6 +468,9 @@ struct dasd_device {
 
 	/* default expiration time in s */
 	unsigned long default_expires;
+	unsigned long default_retries;
+
+	unsigned long blk_timeout;
 
 	struct dentry *debugfs_dentry;
 	struct dasd_profile profile;
@@ -519,7 +524,10 @@ struct dasd_block {
 #define DASD_FLAG_SUSPENDED	9	/* The device was suspended */
 #define DASD_FLAG_SAFE_OFFLINE	10	/* safe offline processing requested*/
 #define DASD_FLAG_SAFE_OFFLINE_RUNNING	11	/* safe offline running */
+#define DASD_FLAG_ABORTALL	12	/* Abort all noretry requests */
 
+#define DASD_SLEEPON_START_TAG	((void *) 1)
+#define DASD_SLEEPON_END_TAG	((void *) 2)
 
 void dasd_put_device_wake(struct dasd_device *);
 
@@ -660,6 +668,8 @@ void dasd_free_device(struct dasd_device
 struct dasd_block *dasd_alloc_block(void);
 void dasd_free_block(struct dasd_block *);
 
+enum blk_eh_timer_return dasd_times_out(struct request *req);
+
 void dasd_enable_device(struct dasd_device *);
 void dasd_set_target_state(struct dasd_device *, int);
 void dasd_kick_device(struct dasd_device *);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/block/dasd_ioctl.c linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_ioctl.c
--- linux-libre-3.10-gnu/drivers/s390/block/dasd_ioctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/block/dasd_ioctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -141,6 +141,59 @@ static int dasd_ioctl_resume(struct dasd
 }
 
 /*
+ * Abort all failfast I/O on a device.
+ */
+static int dasd_ioctl_abortio(struct dasd_block *block)
+{
+	unsigned long flags;
+	struct dasd_device *base;
+	struct dasd_ccw_req *cqr, *n;
+
+	base = block->base;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	if (test_and_set_bit(DASD_FLAG_ABORTALL, &base->flags))
+		return 0;
+	DBF_DEV_EVENT(DBF_NOTICE, base, "%s", "abortall flag set");
+
+	spin_lock_irqsave(&block->request_queue_lock, flags);
+	spin_lock(&block->queue_lock);
+	list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) {
+		if (test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
+		    cqr->callback_data &&
+		    cqr->callback_data != DASD_SLEEPON_START_TAG &&
+		    cqr->callback_data != DASD_SLEEPON_END_TAG) {
+			spin_unlock(&block->queue_lock);
+			blk_abort_request(cqr->callback_data);
+			spin_lock(&block->queue_lock);
+		}
+	}
+	spin_unlock(&block->queue_lock);
+	spin_unlock_irqrestore(&block->request_queue_lock, flags);
+
+	dasd_schedule_block_bh(block);
+	return 0;
+}
+
+/*
+ * Allow I/O on a device
+ */
+static int dasd_ioctl_allowio(struct dasd_block *block)
+{
+	struct dasd_device *base;
+
+	base = block->base;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	if (test_and_clear_bit(DASD_FLAG_ABORTALL, &base->flags))
+		DBF_DEV_EVENT(DBF_NOTICE, base, "%s", "abortall flag unset");
+
+	return 0;
+}
+
+/*
  * performs formatting of _device_ according to _fdata_
  * Note: The discipline's format_function is assumed to deliver formatting
  * commands to format multiple units of the device. In terms of the ECKD
@@ -458,6 +511,12 @@ int dasd_ioctl(struct block_device *bdev
 	case BIODASDRESUME:
 		rc = dasd_ioctl_resume(block);
 		break;
+	case BIODASDABORTIO:
+		rc = dasd_ioctl_abortio(block);
+		break;
+	case BIODASDALLOWIO:
+		rc = dasd_ioctl_allowio(block);
+		break;
 	case BIODASDFMT:
 		rc = dasd_ioctl_format(bdev, argp);
 		break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/Makefile linux-libre-3.11-rc7-gnu/drivers/s390/char/Makefile
--- linux-libre-3.10-gnu/drivers/s390/char/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
 #
 
 obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \
-	 sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o
+	 sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o
 
 obj-$(CONFIG_TN3270) += raw3270.o
 obj-$(CONFIG_TN3270_CONSOLE) += con3270.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/sclp.c linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp.c
--- linux-libre-3.10-gnu/drivers/s390/char/sclp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,11 +50,42 @@ static char sclp_init_sccb[PAGE_SIZE] __
 /* Suspend request */
 static DECLARE_COMPLETION(sclp_request_queue_flushed);
 
+/* Number of console pages to allocate, used by sclp_con.c and sclp_vt220.c */
+int sclp_console_pages = SCLP_CONSOLE_PAGES;
+/* Flag to indicate if buffer pages are dropped on buffer full condition */
+int sclp_console_drop = 0;
+/* Number of times the console dropped buffer pages */
+unsigned long sclp_console_full;
+
 static void sclp_suspend_req_cb(struct sclp_req *req, void *data)
 {
 	complete(&sclp_request_queue_flushed);
 }
 
+static int __init sclp_setup_console_pages(char *str)
+{
+	int pages, rc;
+
+	rc = kstrtoint(str, 0, &pages);
+	if (!rc && pages >= SCLP_CONSOLE_PAGES)
+		sclp_console_pages = pages;
+	return 1;
+}
+
+__setup("sclp_con_pages=", sclp_setup_console_pages);
+
+static int __init sclp_setup_console_drop(char *str)
+{
+	int drop, rc;
+
+	rc = kstrtoint(str, 0, &drop);
+	if (!rc && drop)
+		sclp_console_drop = 1;
+	return 1;
+}
+
+__setup("sclp_con_drop=", sclp_setup_console_drop);
+
 static struct sclp_req sclp_suspend_req;
 
 /* Timer for request retries. */
@@ -117,14 +148,19 @@ static int sclp_init(void);
 int
 sclp_service_call(sclp_cmdw_t command, void *sccb)
 {
-	int cc;
+	int cc = 4; /* Initialize for program check handling */
 
 	asm volatile(
-		"	.insn	rre,0xb2200000,%1,%2\n"  /* servc %1,%2 */
-		"	ipm	%0\n"
-		"	srl	%0,28"
-		: "=&d" (cc) : "d" (command), "a" (__pa(sccb))
+		"0:	.insn	rre,0xb2200000,%1,%2\n"  /* servc %1,%2 */
+		"1:	ipm	%0\n"
+		"	srl	%0,28\n"
+		"2:\n"
+		EX_TABLE(0b, 2b)
+		EX_TABLE(1b, 2b)
+		: "+&d" (cc) : "d" (command), "a" (__pa(sccb))
 		: "cc", "memory");
+	if (cc == 4)
+		return -EINVAL;
 	if (cc == 3)
 		return -EIO;
 	if (cc == 2)
@@ -1013,11 +1049,47 @@ static const struct dev_pm_ops sclp_pm_o
 	.restore	= sclp_restore,
 };
 
+static ssize_t sclp_show_console_pages(struct device_driver *dev, char *buf)
+{
+	return sprintf(buf, "%i\n", sclp_console_pages);
+}
+
+static DRIVER_ATTR(con_pages, S_IRUSR, sclp_show_console_pages, NULL);
+
+static ssize_t sclp_show_con_drop(struct device_driver *dev, char *buf)
+{
+	return sprintf(buf, "%i\n", sclp_console_drop);
+}
+
+static DRIVER_ATTR(con_drop, S_IRUSR, sclp_show_con_drop, NULL);
+
+static ssize_t sclp_show_console_full(struct device_driver *dev, char *buf)
+{
+	return sprintf(buf, "%lu\n", sclp_console_full);
+}
+
+static DRIVER_ATTR(con_full, S_IRUSR, sclp_show_console_full, NULL);
+
+static struct attribute *sclp_drv_attrs[] = {
+	&driver_attr_con_pages.attr,
+	&driver_attr_con_drop.attr,
+	&driver_attr_con_full.attr,
+	NULL,
+};
+static struct attribute_group sclp_drv_attr_group = {
+	.attrs = sclp_drv_attrs,
+};
+static const struct attribute_group *sclp_drv_attr_groups[] = {
+	&sclp_drv_attr_group,
+	NULL,
+};
+
 static struct platform_driver sclp_pdrv = {
 	.driver = {
 		.name	= "sclp",
 		.owner	= THIS_MODULE,
 		.pm	= &sclp_pm_ops,
+		.groups = sclp_drv_attr_groups,
 	},
 };
 
@@ -1096,10 +1168,12 @@ static __init int sclp_initcall(void)
 	rc = platform_driver_register(&sclp_pdrv);
 	if (rc)
 		return rc;
+
 	sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
-	rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
+	rc = PTR_RET(sclp_pdev);
 	if (rc)
 		goto fail_platform_driver_unregister;
+
 	rc = atomic_notifier_chain_register(&panic_notifier_list,
 					    &sclp_on_panic_nb);
 	if (rc)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/sclp_cmd.c linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp_cmd.c
--- linux-libre-3.10-gnu/drivers/s390/char/sclp_cmd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp_cmd.c	2013-08-25 20:43:22.000000000 -0400
@@ -195,7 +195,7 @@ static void sclp_sync_callback(struct sc
 	complete(completion);
 }
 
-static int do_sync_request(sclp_cmdw_t cmd, void *sccb)
+int sclp_sync_request(sclp_cmdw_t cmd, void *sccb)
 {
 	struct completion completion;
 	struct sclp_req *request;
@@ -270,7 +270,7 @@ int sclp_get_cpu_info(struct sclp_cpu_in
 	if (!sccb)
 		return -ENOMEM;
 	sccb->header.length = sizeof(*sccb);
-	rc = do_sync_request(SCLP_CMDW_READ_CPU_INFO, sccb);
+	rc = sclp_sync_request(SCLP_CMDW_READ_CPU_INFO, sccb);
 	if (rc)
 		goto out;
 	if (sccb->header.response_code != 0x0010) {
@@ -304,7 +304,7 @@ static int do_cpu_configure(sclp_cmdw_t
 	if (!sccb)
 		return -ENOMEM;
 	sccb->header.length = sizeof(*sccb);
-	rc = do_sync_request(cmd, sccb);
+	rc = sclp_sync_request(cmd, sccb);
 	if (rc)
 		goto out;
 	switch (sccb->header.response_code) {
@@ -374,7 +374,7 @@ static int do_assign_storage(sclp_cmdw_t
 		return -ENOMEM;
 	sccb->header.length = PAGE_SIZE;
 	sccb->rn = rn;
-	rc = do_sync_request(cmd, sccb);
+	rc = sclp_sync_request(cmd, sccb);
 	if (rc)
 		goto out;
 	switch (sccb->header.response_code) {
@@ -429,7 +429,7 @@ static int sclp_attach_storage(u8 id)
 	if (!sccb)
 		return -ENOMEM;
 	sccb->header.length = PAGE_SIZE;
-	rc = do_sync_request(0x00080001 | id << 8, sccb);
+	rc = sclp_sync_request(0x00080001 | id << 8, sccb);
 	if (rc)
 		goto out;
 	switch (sccb->header.response_code) {
@@ -627,7 +627,7 @@ static int __init sclp_detect_standby_me
 	for (id = 0; id <= sclp_max_storage_id; id++) {
 		memset(sccb, 0, PAGE_SIZE);
 		sccb->header.length = PAGE_SIZE;
-		rc = do_sync_request(0x00040001 | id << 8, sccb);
+		rc = sclp_sync_request(0x00040001 | id << 8, sccb);
 		if (rc)
 			goto out;
 		switch (sccb->header.response_code) {
@@ -668,7 +668,7 @@ static int __init sclp_detect_standby_me
 	if (rc)
 		goto out;
 	sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0);
-	rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
+	rc = PTR_RET(sclp_pdev);
 	if (rc)
 		goto out_driver;
 	sclp_add_standby_memory();
@@ -714,7 +714,7 @@ static int do_pci_configure(sclp_cmdw_t
 	sccb->header.length = PAGE_SIZE;
 	sccb->atype = SCLP_RECONFIG_PCI_ATPYE;
 	sccb->aid = fid;
-	rc = do_sync_request(cmd, sccb);
+	rc = sclp_sync_request(cmd, sccb);
 	if (rc)
 		goto out;
 	switch (sccb->header.response_code) {
@@ -771,7 +771,7 @@ static int do_chp_configure(sclp_cmdw_t
 	if (!sccb)
 		return -ENOMEM;
 	sccb->header.length = sizeof(*sccb);
-	rc = do_sync_request(cmd, sccb);
+	rc = sclp_sync_request(cmd, sccb);
 	if (rc)
 		goto out;
 	switch (sccb->header.response_code) {
@@ -846,7 +846,7 @@ int sclp_chp_read_info(struct sclp_chp_i
 	if (!sccb)
 		return -ENOMEM;
 	sccb->header.length = sizeof(*sccb);
-	rc = do_sync_request(SCLP_CMDW_READ_CHPATH_INFORMATION, sccb);
+	rc = sclp_sync_request(SCLP_CMDW_READ_CHPATH_INFORMATION, sccb);
 	if (rc)
 		goto out;
 	if (sccb->header.response_code != 0x0010) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/sclp_con.c linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp_con.c
--- linux-libre-3.10-gnu/drivers/s390/char/sclp_con.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp_con.c	2013-08-25 20:43:22.000000000 -0400
@@ -130,6 +130,31 @@ sclp_console_timeout(unsigned long data)
 }
 
 /*
+ * Drop oldest console buffer if sclp_con_drop is set
+ */
+static int
+sclp_console_drop_buffer(void)
+{
+	struct list_head *list;
+	struct sclp_buffer *buffer;
+	void *page;
+
+	if (!sclp_console_drop)
+		return 0;
+	list = sclp_con_outqueue.next;
+	if (sclp_con_queue_running)
+		/* The first element is in I/O */
+		list = list->next;
+	if (list == &sclp_con_outqueue)
+		return 0;
+	list_del(list);
+	buffer = list_entry(list, struct sclp_buffer, list);
+	page = sclp_unmake_buffer(buffer);
+	list_add_tail((struct list_head *) page, &sclp_con_pages);
+	return 1;
+}
+
+/*
  * Writes the given message to S390 system console
  */
 static void
@@ -150,9 +175,13 @@ sclp_console_write(struct console *conso
 	do {
 		/* make sure we have a console output buffer */
 		if (sclp_conbuf == NULL) {
+			if (list_empty(&sclp_con_pages))
+				sclp_console_full++;
 			while (list_empty(&sclp_con_pages)) {
 				if (sclp_con_suspended)
 					goto out;
+				if (sclp_console_drop_buffer())
+					break;
 				spin_unlock_irqrestore(&sclp_con_lock, flags);
 				sclp_sync_wait();
 				spin_lock_irqsave(&sclp_con_lock, flags);
@@ -297,7 +326,7 @@ sclp_console_init(void)
 		return rc;
 	/* Allocate pages for output buffering */
 	INIT_LIST_HEAD(&sclp_con_pages);
-	for (i = 0; i < MAX_CONSOLE_PAGES; i++) {
+	for (i = 0; i < sclp_console_pages; i++) {
 		page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
 		list_add_tail(page, &sclp_con_pages);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/sclp_ctl.c linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp_ctl.c
--- linux-libre-3.10-gnu/drivers/s390/char/sclp_ctl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp_ctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,144 @@
+/*
+ * IOCTL interface for SCLP
+ *
+ * Copyright IBM Corp. 2012
+ *
+ * Author: Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#include <linux/compat.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/gfp.h>
+#include <linux/module.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <asm/compat.h>
+#include <asm/sclp_ctl.h>
+#include <asm/sclp.h>
+
+#include "sclp.h"
+
+/*
+ * Supported command words
+ */
+static unsigned int sclp_ctl_sccb_wlist[] = {
+	0x00400002,
+	0x00410002,
+};
+
+/*
+ * Check if command word is supported
+ */
+static int sclp_ctl_cmdw_supported(unsigned int cmdw)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sclp_ctl_sccb_wlist); i++) {
+		if (cmdw == sclp_ctl_sccb_wlist[i])
+			return 1;
+	}
+	return 0;
+}
+
+static void __user *u64_to_uptr(u64 value)
+{
+	if (is_compat_task())
+		return compat_ptr(value);
+	else
+		return (void __user *)(unsigned long)value;
+}
+
+/*
+ * Start SCLP request
+ */
+static int sclp_ctl_ioctl_sccb(void __user *user_area)
+{
+	struct sclp_ctl_sccb ctl_sccb;
+	struct sccb_header *sccb;
+	int rc;
+
+	if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb)))
+		return -EFAULT;
+	if (!sclp_ctl_cmdw_supported(ctl_sccb.cmdw))
+		return -EOPNOTSUPP;
+	sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
+	if (!sccb)
+		return -ENOMEM;
+	if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sizeof(*sccb))) {
+		rc = -EFAULT;
+		goto out_free;
+	}
+	if (sccb->length > PAGE_SIZE || sccb->length < 8)
+		return -EINVAL;
+	if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sccb->length)) {
+		rc = -EFAULT;
+		goto out_free;
+	}
+	rc = sclp_sync_request(ctl_sccb.cmdw, sccb);
+	if (rc)
+		goto out_free;
+	if (copy_to_user(u64_to_uptr(ctl_sccb.sccb), sccb, sccb->length))
+		rc = -EFAULT;
+out_free:
+	free_page((unsigned long) sccb);
+	return rc;
+}
+
+/*
+ * SCLP SCCB ioctl function
+ */
+static long sclp_ctl_ioctl(struct file *filp, unsigned int cmd,
+			   unsigned long arg)
+{
+	void __user *argp;
+
+	if (is_compat_task())
+		argp = compat_ptr(arg);
+	else
+		argp = (void __user *) arg;
+	switch (cmd) {
+	case SCLP_CTL_SCCB:
+		return sclp_ctl_ioctl_sccb(argp);
+	default: /* unknown ioctl number */
+		return -ENOTTY;
+	}
+}
+
+/*
+ * File operations
+ */
+static const struct file_operations sclp_ctl_fops = {
+	.owner = THIS_MODULE,
+	.open = nonseekable_open,
+	.unlocked_ioctl = sclp_ctl_ioctl,
+	.compat_ioctl = sclp_ctl_ioctl,
+	.llseek = no_llseek,
+};
+
+/*
+ * Misc device definition
+ */
+static struct miscdevice sclp_ctl_device = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "sclp",
+	.fops = &sclp_ctl_fops,
+};
+
+/*
+ * Register sclp_ctl misc device
+ */
+static int __init sclp_ctl_init(void)
+{
+	return misc_register(&sclp_ctl_device);
+}
+module_init(sclp_ctl_init);
+
+/*
+ * Deregister sclp_ctl misc device
+ */
+static void __exit sclp_ctl_exit(void)
+{
+	misc_deregister(&sclp_ctl_device);
+}
+module_exit(sclp_ctl_exit);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/sclp.h linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp.h
--- linux-libre-3.10-gnu/drivers/s390/char/sclp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp.h	2013-08-25 20:43:22.000000000 -0400
@@ -15,7 +15,7 @@
 
 /* maximum number of pages concerning our own memory management */
 #define MAX_KMEM_PAGES (sizeof(unsigned long) << 3)
-#define MAX_CONSOLE_PAGES	6
+#define SCLP_CONSOLE_PAGES	6
 
 #define EVTYP_OPCMD		0x01
 #define EVTYP_MSG		0x02
@@ -171,10 +171,15 @@ int sclp_remove_processed(struct sccb_he
 int sclp_deactivate(void);
 int sclp_reactivate(void);
 int sclp_service_call(sclp_cmdw_t command, void *sccb);
+int sclp_sync_request(sclp_cmdw_t command, void *sccb);
 
 int sclp_sdias_init(void);
 void sclp_sdias_exit(void);
 
+extern int sclp_console_pages;
+extern int sclp_console_drop;
+extern unsigned long sclp_console_full;
+
 /* useful inlines */
 
 /* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/sclp_vt220.c linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp_vt220.c
--- linux-libre-3.10-gnu/drivers/s390/char/sclp_vt220.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/sclp_vt220.c	2013-08-25 20:43:22.000000000 -0400
@@ -362,6 +362,31 @@ sclp_vt220_timeout(unsigned long data)
 
 #define BUFFER_MAX_DELAY	HZ/20
 
+/*
+ * Drop oldest console buffer if sclp_con_drop is set
+ */
+static int
+sclp_vt220_drop_buffer(void)
+{
+	struct list_head *list;
+	struct sclp_vt220_request *request;
+	void *page;
+
+	if (!sclp_console_drop)
+		return 0;
+	list = sclp_vt220_outqueue.next;
+	if (sclp_vt220_queue_running)
+		/* The first element is in I/O */
+		list = list->next;
+	if (list == &sclp_vt220_outqueue)
+		return 0;
+	list_del(list);
+	request = list_entry(list, struct sclp_vt220_request, list);
+	page = request->sclp_req.sccb;
+	list_add_tail((struct list_head *) page, &sclp_vt220_empty);
+	return 1;
+}
+
 /* 
  * Internal implementation of the write function. Write COUNT bytes of data
  * from memory at BUF
@@ -390,12 +415,16 @@ __sclp_vt220_write(const unsigned char *
 	do {
 		/* Create an sclp output buffer if none exists yet */
 		if (sclp_vt220_current_request == NULL) {
+			if (list_empty(&sclp_vt220_empty))
+				sclp_console_full++;
 			while (list_empty(&sclp_vt220_empty)) {
-				spin_unlock_irqrestore(&sclp_vt220_lock, flags);
 				if (may_fail || sclp_vt220_suspended)
 					goto out;
-				else
-					sclp_sync_wait();
+				if (sclp_vt220_drop_buffer())
+					break;
+				spin_unlock_irqrestore(&sclp_vt220_lock, flags);
+
+				sclp_sync_wait();
 				spin_lock_irqsave(&sclp_vt220_lock, flags);
 			}
 			page = (void *) sclp_vt220_empty.next;
@@ -428,8 +457,8 @@ __sclp_vt220_write(const unsigned char *
 		sclp_vt220_timer.expires = jiffies + BUFFER_MAX_DELAY;
 		add_timer(&sclp_vt220_timer);
 	}
-	spin_unlock_irqrestore(&sclp_vt220_lock, flags);
 out:
+	spin_unlock_irqrestore(&sclp_vt220_lock, flags);
 	return overall_written;
 }
 
@@ -803,7 +832,7 @@ sclp_vt220_con_init(void)
 
 	if (!CONSOLE_IS_SCLP)
 		return 0;
-	rc = __sclp_vt220_init(MAX_CONSOLE_PAGES);
+	rc = __sclp_vt220_init(sclp_console_pages);
 	if (rc)
 		return rc;
 	/* Attach linux console */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/tape_class.c linux-libre-3.11-rc7-gnu/drivers/s390/char/tape_class.c
--- linux-libre-3.10-gnu/drivers/s390/char/tape_class.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/tape_class.c	2013-08-25 20:43:22.000000000 -0400
@@ -77,7 +77,7 @@ struct tape_class_device *register_tape_
 	tcd->class_device = device_create(tape_class, device,
 					  tcd->char_device->dev, NULL,
 					  "%s", tcd->device_name);
-	rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0;
+	rc = PTR_RET(tcd->class_device);
 	if (rc)
 		goto fail_with_cdev;
 	rc = sysfs_create_link(
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/vmur.c linux-libre-3.11-rc7-gnu/drivers/s390/char/vmur.c
--- linux-libre-3.10-gnu/drivers/s390/char/vmur.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/vmur.c	2013-08-25 20:43:22.000000000 -0400
@@ -89,7 +89,7 @@ static DEFINE_MUTEX(vmur_mutex);
  * urd references:
  * - ur_probe gets a urd reference, ur_remove drops the reference
  *   dev_get_drvdata(&cdev->dev)
- * - ur_open gets a urd reference, ur_relase drops the reference
+ * - ur_open gets a urd reference, ur_release drops the reference
  *   (urf->urd)
  *
  * cdev references:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/char/vmwatchdog.c linux-libre-3.11-rc7-gnu/drivers/s390/char/vmwatchdog.c
--- linux-libre-3.10-gnu/drivers/s390/char/vmwatchdog.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/char/vmwatchdog.c	2013-08-25 20:43:22.000000000 -0400
@@ -112,7 +112,8 @@ static int vmwdt_keepalive(void)
 
 static int vmwdt_disable(void)
 {
-	int ret = __diag288(wdt_cancel, 0, "", 0);
+	char cmd[] = {'\0'};
+	int ret = __diag288(wdt_cancel, 0, cmd, 0);
 	WARN_ON(ret != 0);
 	clear_bit(VMWDT_RUNNING, &vmwdt_is_open);
 	return ret;
@@ -124,7 +125,7 @@ static int __init vmwdt_probe(void)
 	 * so we try initializing it with a NOP command ("BEGIN")
 	 * that won't cause any harm even if the following disable
 	 * fails for some reason */
-	static char __initdata ebc_begin[] = {
+	char ebc_begin[] = {
 		194, 197, 199, 201, 213
 	};
 	if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/cio/airq.c linux-libre-3.11-rc7-gnu/drivers/s390/cio/airq.c
--- linux-libre-3.10-gnu/drivers/s390/cio/airq.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/cio/airq.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,142 +9,87 @@
  */
 
 #include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/rculist.h>
 #include <linux/slab.h>
-#include <linux/rcupdate.h>
 
 #include <asm/airq.h>
 #include <asm/isc.h>
 
 #include "cio.h"
 #include "cio_debug.h"
+#include "ioasm.h"
 
-#define NR_AIRQS		32
-#define NR_AIRQS_PER_WORD	sizeof(unsigned long)
-#define NR_AIRQ_WORDS		(NR_AIRQS / NR_AIRQS_PER_WORD)
-
-union indicator_t {
-	unsigned long word[NR_AIRQ_WORDS];
-	unsigned char byte[NR_AIRQS];
-} __attribute__((packed));
-
-struct airq_t {
-	adapter_int_handler_t handler;
-	void *drv_data;
-};
-
-static union indicator_t indicators[MAX_ISC+1];
-static struct airq_t *airqs[MAX_ISC+1][NR_AIRQS];
-
-static int register_airq(struct airq_t *airq, u8 isc)
-{
-	int i;
-
-	for (i = 0; i < NR_AIRQS; i++)
-		if (!cmpxchg(&airqs[isc][i], NULL, airq))
-			return i;
-	return -ENOMEM;
-}
+static DEFINE_SPINLOCK(airq_lists_lock);
+static struct hlist_head airq_lists[MAX_ISC+1];
 
 /**
- * s390_register_adapter_interrupt() - register adapter interrupt handler
- * @handler: adapter handler to be registered
- * @drv_data: driver data passed with each call to the handler
- * @isc: isc for which the handler should be called
+ * register_adapter_interrupt() - register adapter interrupt handler
+ * @airq: pointer to adapter interrupt descriptor
  *
- * Returns:
- *  Pointer to the indicator to be used on success
- *  ERR_PTR() if registration failed
+ * Returns 0 on success, or -EINVAL.
  */
-void *s390_register_adapter_interrupt(adapter_int_handler_t handler,
-				      void *drv_data, u8 isc)
+int register_adapter_interrupt(struct airq_struct *airq)
 {
-	struct airq_t *airq;
-	char dbf_txt[16];
-	int ret;
+	char dbf_txt[32];
 
-	if (isc > MAX_ISC)
-		return ERR_PTR(-EINVAL);
-	airq = kmalloc(sizeof(struct airq_t), GFP_KERNEL);
-	if (!airq) {
-		ret = -ENOMEM;
-		goto out;
+	if (!airq->handler || airq->isc > MAX_ISC)
+		return -EINVAL;
+	if (!airq->lsi_ptr) {
+		airq->lsi_ptr = kzalloc(1, GFP_KERNEL);
+		if (!airq->lsi_ptr)
+			return -ENOMEM;
+		airq->flags |= AIRQ_PTR_ALLOCATED;
 	}
-	airq->handler = handler;
-	airq->drv_data = drv_data;
-
-	ret = register_airq(airq, isc);
-out:
-	snprintf(dbf_txt, sizeof(dbf_txt), "rairq:%d", ret);
+	if (!airq->lsi_mask)
+		airq->lsi_mask = 0xff;
+	snprintf(dbf_txt, sizeof(dbf_txt), "rairq:%p", airq);
 	CIO_TRACE_EVENT(4, dbf_txt);
-	if (ret < 0) {
-		kfree(airq);
-		return ERR_PTR(ret);
-	} else
-		return &indicators[isc].byte[ret];
+	isc_register(airq->isc);
+	spin_lock(&airq_lists_lock);
+	hlist_add_head_rcu(&airq->list, &airq_lists[airq->isc]);
+	spin_unlock(&airq_lists_lock);
+	return 0;
 }
-EXPORT_SYMBOL(s390_register_adapter_interrupt);
+EXPORT_SYMBOL(register_adapter_interrupt);
 
 /**
- * s390_unregister_adapter_interrupt - unregister adapter interrupt handler
- * @ind: indicator for which the handler is to be unregistered
- * @isc: interruption subclass
+ * unregister_adapter_interrupt - unregister adapter interrupt handler
+ * @airq: pointer to adapter interrupt descriptor
  */
-void s390_unregister_adapter_interrupt(void *ind, u8 isc)
+void unregister_adapter_interrupt(struct airq_struct *airq)
 {
-	struct airq_t *airq;
-	char dbf_txt[16];
-	int i;
+	char dbf_txt[32];
 
-	i = (int) ((addr_t) ind) - ((addr_t) &indicators[isc].byte[0]);
-	snprintf(dbf_txt, sizeof(dbf_txt), "urairq:%d", i);
+	if (hlist_unhashed(&airq->list))
+		return;
+	snprintf(dbf_txt, sizeof(dbf_txt), "urairq:%p", airq);
 	CIO_TRACE_EVENT(4, dbf_txt);
-	indicators[isc].byte[i] = 0;
-	airq = xchg(&airqs[isc][i], NULL);
-	/*
-	 * Allow interrupts to complete. This will ensure that the airq handle
-	 * is no longer referenced by any interrupt handler.
-	 */
-	synchronize_sched();
-	kfree(airq);
+	spin_lock(&airq_lists_lock);
+	hlist_del_rcu(&airq->list);
+	spin_unlock(&airq_lists_lock);
+	synchronize_rcu();
+	isc_unregister(airq->isc);
+	if (airq->flags & AIRQ_PTR_ALLOCATED) {
+		kfree(airq->lsi_ptr);
+		airq->lsi_ptr = NULL;
+		airq->flags &= ~AIRQ_PTR_ALLOCATED;
+	}
 }
-EXPORT_SYMBOL(s390_unregister_adapter_interrupt);
-
-#define INDICATOR_MASK	(0xffUL << ((NR_AIRQS_PER_WORD - 1) * 8))
+EXPORT_SYMBOL(unregister_adapter_interrupt);
 
 void do_adapter_IO(u8 isc)
 {
-	int w;
-	int i;
-	unsigned long word;
-	struct airq_t *airq;
+	struct airq_struct *airq;
+	struct hlist_head *head;
 
-	/*
-	 * Access indicator array in word-sized chunks to minimize storage
-	 * fetch operations.
-	 */
-	for (w = 0; w < NR_AIRQ_WORDS; w++) {
-		word = indicators[isc].word[w];
-		i = w * NR_AIRQS_PER_WORD;
-		/*
-		 * Check bytes within word for active indicators.
-		 */
-		while (word) {
-			if (word & INDICATOR_MASK) {
-				airq = airqs[isc][i];
-				/* Make sure gcc reads from airqs only once. */
-				barrier();
-				if (likely(airq))
-					airq->handler(&indicators[isc].byte[i],
-						      airq->drv_data);
-				else
-					/*
-					 * Reset ill-behaved indicator.
-					 */
-					indicators[isc].byte[i] = 0;
-			}
-			word <<= 8;
-			i++;
-		}
-	}
+	head = &airq_lists[isc];
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(airq, head, list)
+		if ((*airq->lsi_ptr & airq->lsi_mask) != 0)
+			airq->handler(airq);
+	rcu_read_unlock();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/cio/chsc.c linux-libre-3.11-rc7-gnu/drivers/s390/cio/chsc.c
--- linux-libre-3.10-gnu/drivers/s390/cio/chsc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/cio/chsc.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <asm/chpid.h>
 #include <asm/chsc.h>
 #include <asm/crw.h>
+#include <asm/isc.h>
 
 #include "css.h"
 #include "cio.h"
@@ -144,6 +145,65 @@ out:
 	return ret;
 }
 
+/**
+ * chsc_ssqd() - store subchannel QDIO data (SSQD)
+ * @schid: id of the subchannel on which SSQD is performed
+ * @ssqd: request and response block for SSQD
+ *
+ * Returns 0 on success.
+ */
+int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd)
+{
+	memset(ssqd, 0, sizeof(*ssqd));
+	ssqd->request.length = 0x0010;
+	ssqd->request.code = 0x0024;
+	ssqd->first_sch = schid.sch_no;
+	ssqd->last_sch = schid.sch_no;
+	ssqd->ssid = schid.ssid;
+
+	if (chsc(ssqd))
+		return -EIO;
+
+	return chsc_error_from_response(ssqd->response.code);
+}
+EXPORT_SYMBOL_GPL(chsc_ssqd);
+
+/**
+ * chsc_sadc() - set adapter device controls (SADC)
+ * @schid: id of the subchannel on which SADC is performed
+ * @scssc: request and response block for SADC
+ * @summary_indicator_addr: summary indicator address
+ * @subchannel_indicator_addr: subchannel indicator address
+ *
+ * Returns 0 on success.
+ */
+int chsc_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc,
+	      u64 summary_indicator_addr, u64 subchannel_indicator_addr)
+{
+	memset(scssc, 0, sizeof(*scssc));
+	scssc->request.length = 0x0fe0;
+	scssc->request.code = 0x0021;
+	scssc->operation_code = 0;
+
+	scssc->summary_indicator_addr = summary_indicator_addr;
+	scssc->subchannel_indicator_addr = subchannel_indicator_addr;
+
+	scssc->ks = PAGE_DEFAULT_KEY >> 4;
+	scssc->kc = PAGE_DEFAULT_KEY >> 4;
+	scssc->isc = QDIO_AIRQ_ISC;
+	scssc->schid = schid;
+
+	/* enable the time delay disablement facility */
+	if (css_general_characteristics.aif_tdd)
+		scssc->word_with_d_bit = 0x10000000;
+
+	if (chsc(scssc))
+		return -EIO;
+
+	return chsc_error_from_response(scssc->response.code);
+}
+EXPORT_SYMBOL_GPL(chsc_sadc);
+
 static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data)
 {
 	spin_lock_irq(sch->lock);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/cio/chsc.h linux-libre-3.11-rc7-gnu/drivers/s390/cio/chsc.h
--- linux-libre-3.10-gnu/drivers/s390/cio/chsc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/cio/chsc.h	2013-08-25 20:43:22.000000000 -0400
@@ -7,14 +7,10 @@
 #include <asm/chpid.h>
 #include <asm/chsc.h>
 #include <asm/schid.h>
+#include <asm/qdio.h>
 
 #define CHSC_SDA_OC_MSS   0x2
 
-struct chsc_header {
-	u16 length;
-	u16 code;
-} __attribute__ ((packed));
-
 #define NR_MEASUREMENT_CHARS 5
 struct cmg_chars {
 	u32 values[NR_MEASUREMENT_CHARS];
@@ -77,6 +73,40 @@ struct chsc_ssd_info {
 	u16 fla[8];
 };
 
+struct chsc_ssqd_area {
+	struct chsc_header request;
+	u16:10;
+	u8 ssid:2;
+	u8 fmt:4;
+	u16 first_sch;
+	u16:16;
+	u16 last_sch;
+	u32:32;
+	struct chsc_header response;
+	u32:32;
+	struct qdio_ssqd_desc qdio_ssqd;
+} __packed;
+
+struct chsc_scssc_area {
+	struct chsc_header request;
+	u16 operation_code;
+	u16:16;
+	u32:32;
+	u32:32;
+	u64 summary_indicator_addr;
+	u64 subchannel_indicator_addr;
+	u32 ks:4;
+	u32 kc:4;
+	u32:21;
+	u32 isc:3;
+	u32 word_with_d_bit;
+	u32:32;
+	struct subchannel_id schid;
+	u32 reserved[1004];
+	struct chsc_header response;
+	u32:32;
+} __packed;
+
 struct chsc_scpd {
 	struct chsc_header request;
 	u32:2;
@@ -116,7 +146,9 @@ int chsc_determine_fmt1_channel_path_des
 void chsc_chp_online(struct chp_id chpid);
 void chsc_chp_offline(struct chp_id chpid);
 int chsc_get_channel_measurement_chars(struct channel_path *chp);
-
+int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd);
+int chsc_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc,
+	      u64 summary_indicator_addr, u64 subchannel_indicator_addr);
 int chsc_error_from_response(int response);
 
 int chsc_siosl(struct subchannel_id schid);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/cio/chsc_sch.c linux-libre-3.11-rc7-gnu/drivers/s390/cio/chsc_sch.c
--- linux-libre-3.10-gnu/drivers/s390/cio/chsc_sch.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/cio/chsc_sch.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,6 +29,10 @@
 static debug_info_t *chsc_debug_msg_id;
 static debug_info_t *chsc_debug_log_id;
 
+static struct chsc_request *on_close_request;
+static struct chsc_async_area *on_close_chsc_area;
+static DEFINE_MUTEX(on_close_mutex);
+
 #define CHSC_MSG(imp, args...) do {					\
 		debug_sprintf_event(chsc_debug_msg_id, imp , ##args);	\
 	} while (0)
@@ -258,7 +262,7 @@ static int chsc_async(struct chsc_async_
 		CHSC_LOG(2, "schid");
 		CHSC_LOG_HEX(2, &sch->schid, sizeof(sch->schid));
 		cc = chsc(chsc_area);
-		sprintf(dbf, "cc:%d", cc);
+		snprintf(dbf, sizeof(dbf), "cc:%d", cc);
 		CHSC_LOG(2, dbf);
 		switch (cc) {
 		case 0:
@@ -287,11 +291,11 @@ static int chsc_async(struct chsc_async_
 	return ret;
 }
 
-static void chsc_log_command(struct chsc_async_area *chsc_area)
+static void chsc_log_command(void *chsc_area)
 {
 	char dbf[10];
 
-	sprintf(dbf, "CHSC:%x", chsc_area->header.code);
+	snprintf(dbf, sizeof(dbf), "CHSC:%x", ((uint16_t *)chsc_area)[1]);
 	CHSC_LOG(0, dbf);
 	CHSC_LOG_HEX(0, chsc_area, 32);
 }
@@ -355,13 +359,106 @@ static int chsc_ioctl_start(void __user
 		if (copy_to_user(user_area, chsc_area, PAGE_SIZE))
 			ret = -EFAULT;
 out_free:
-	sprintf(dbf, "ret:%d", ret);
+	snprintf(dbf, sizeof(dbf), "ret:%d", ret);
 	CHSC_LOG(0, dbf);
 	kfree(request);
 	free_page((unsigned long)chsc_area);
 	return ret;
 }
 
+static int chsc_ioctl_on_close_set(void __user *user_area)
+{
+	char dbf[13];
+	int ret;
+
+	mutex_lock(&on_close_mutex);
+	if (on_close_chsc_area) {
+		ret = -EBUSY;
+		goto out_unlock;
+	}
+	on_close_request = kzalloc(sizeof(*on_close_request), GFP_KERNEL);
+	if (!on_close_request) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
+	on_close_chsc_area = (void *)get_zeroed_page(GFP_DMA | GFP_KERNEL);
+	if (!on_close_chsc_area) {
+		ret = -ENOMEM;
+		goto out_free_request;
+	}
+	if (copy_from_user(on_close_chsc_area, user_area, PAGE_SIZE)) {
+		ret = -EFAULT;
+		goto out_free_chsc;
+	}
+	ret = 0;
+	goto out_unlock;
+
+out_free_chsc:
+	free_page((unsigned long)on_close_chsc_area);
+	on_close_chsc_area = NULL;
+out_free_request:
+	kfree(on_close_request);
+	on_close_request = NULL;
+out_unlock:
+	mutex_unlock(&on_close_mutex);
+	snprintf(dbf, sizeof(dbf), "ocsret:%d", ret);
+	CHSC_LOG(0, dbf);
+	return ret;
+}
+
+static int chsc_ioctl_on_close_remove(void)
+{
+	char dbf[13];
+	int ret;
+
+	mutex_lock(&on_close_mutex);
+	if (!on_close_chsc_area) {
+		ret = -ENOENT;
+		goto out_unlock;
+	}
+	free_page((unsigned long)on_close_chsc_area);
+	on_close_chsc_area = NULL;
+	kfree(on_close_request);
+	on_close_request = NULL;
+	ret = 0;
+out_unlock:
+	mutex_unlock(&on_close_mutex);
+	snprintf(dbf, sizeof(dbf), "ocrret:%d", ret);
+	CHSC_LOG(0, dbf);
+	return ret;
+}
+
+static int chsc_ioctl_start_sync(void __user *user_area)
+{
+	struct chsc_sync_area *chsc_area;
+	int ret, ccode;
+
+	chsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
+	if (!chsc_area)
+		return -ENOMEM;
+	if (copy_from_user(chsc_area, user_area, PAGE_SIZE)) {
+		ret = -EFAULT;
+		goto out_free;
+	}
+	if (chsc_area->header.code & 0x4000) {
+		ret = -EINVAL;
+		goto out_free;
+	}
+	chsc_log_command(chsc_area);
+	ccode = chsc(chsc_area);
+	if (ccode != 0) {
+		ret = -EIO;
+		goto out_free;
+	}
+	if (copy_to_user(user_area, chsc_area, PAGE_SIZE))
+		ret = -EFAULT;
+	else
+		ret = 0;
+out_free:
+	free_page((unsigned long)chsc_area);
+	return ret;
+}
+
 static int chsc_ioctl_info_channel_path(void __user *user_cd)
 {
 	struct chsc_chp_cd *cd;
@@ -795,6 +892,8 @@ static long chsc_ioctl(struct file *filp
 	switch (cmd) {
 	case CHSC_START:
 		return chsc_ioctl_start(argp);
+	case CHSC_START_SYNC:
+		return chsc_ioctl_start_sync(argp);
 	case CHSC_INFO_CHANNEL_PATH:
 		return chsc_ioctl_info_channel_path(argp);
 	case CHSC_INFO_CU:
@@ -809,14 +908,60 @@ static long chsc_ioctl(struct file *filp
 		return chsc_ioctl_chpd(argp);
 	case CHSC_INFO_DCAL:
 		return chsc_ioctl_dcal(argp);
+	case CHSC_ON_CLOSE_SET:
+		return chsc_ioctl_on_close_set(argp);
+	case CHSC_ON_CLOSE_REMOVE:
+		return chsc_ioctl_on_close_remove();
 	default: /* unknown ioctl number */
 		return -ENOIOCTLCMD;
 	}
 }
 
+static atomic_t chsc_ready_for_use = ATOMIC_INIT(1);
+
+static int chsc_open(struct inode *inode, struct file *file)
+{
+	if (!atomic_dec_and_test(&chsc_ready_for_use)) {
+		atomic_inc(&chsc_ready_for_use);
+		return -EBUSY;
+	}
+	return nonseekable_open(inode, file);
+}
+
+static int chsc_release(struct inode *inode, struct file *filp)
+{
+	char dbf[13];
+	int ret;
+
+	mutex_lock(&on_close_mutex);
+	if (!on_close_chsc_area)
+		goto out_unlock;
+	init_completion(&on_close_request->completion);
+	CHSC_LOG(0, "on_close");
+	chsc_log_command(on_close_chsc_area);
+	spin_lock_irq(&chsc_lock);
+	ret = chsc_async(on_close_chsc_area, on_close_request);
+	spin_unlock_irq(&chsc_lock);
+	if (ret == -EINPROGRESS) {
+		wait_for_completion(&on_close_request->completion);
+		ret = chsc_examine_irb(on_close_request);
+	}
+	snprintf(dbf, sizeof(dbf), "relret:%d", ret);
+	CHSC_LOG(0, dbf);
+	free_page((unsigned long)on_close_chsc_area);
+	on_close_chsc_area = NULL;
+	kfree(on_close_request);
+	on_close_request = NULL;
+out_unlock:
+	mutex_unlock(&on_close_mutex);
+	atomic_inc(&chsc_ready_for_use);
+	return 0;
+}
+
 static const struct file_operations chsc_fops = {
 	.owner = THIS_MODULE,
-	.open = nonseekable_open,
+	.open = chsc_open,
+	.release = chsc_release,
 	.unlocked_ioctl = chsc_ioctl,
 	.compat_ioctl = chsc_ioctl,
 	.llseek = no_llseek,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/cio/cio.c linux-libre-3.11-rc7-gnu/drivers/s390/cio/cio.c
--- linux-libre-3.10-gnu/drivers/s390/cio/cio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/cio/cio.c	2013-08-25 20:43:22.000000000 -0400
@@ -568,7 +568,7 @@ out:
  */
 void __irq_entry do_IRQ(struct pt_regs *regs)
 {
-	struct tpi_info *tpi_info;
+	struct tpi_info *tpi_info = (struct tpi_info *) &regs->int_code;
 	struct subchannel *sch;
 	struct irb *irb;
 	struct pt_regs *old_regs;
@@ -579,46 +579,34 @@ void __irq_entry do_IRQ(struct pt_regs *
 	if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
 		/* Serve timer interrupts first. */
 		clock_comparator_work();
-	/*
-	 * Get interrupt information from lowcore
-	 */
-	tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id;
-	irb = (struct irb *)&S390_lowcore.irb;
-	do {
-		kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL);
-		if (tpi_info->adapter_IO) {
-			do_adapter_IO(tpi_info->isc);
-			continue;
-		}
-		sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
-		if (!sch) {
-			/* Clear pending interrupt condition. */
-			inc_irq_stat(IRQIO_CIO);
-			tsch(tpi_info->schid, irb);
-			continue;
-		}
-		spin_lock(sch->lock);
-		/* Store interrupt response block to lowcore. */
-		if (tsch(tpi_info->schid, irb) == 0) {
-			/* Keep subchannel information word up to date. */
-			memcpy (&sch->schib.scsw, &irb->scsw,
-				sizeof (irb->scsw));
-			/* Call interrupt handler if there is one. */
-			if (sch->driver && sch->driver->irq)
-				sch->driver->irq(sch);
-			else
-				inc_irq_stat(IRQIO_CIO);
-		} else
+
+	kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL);
+	irb = (struct irb *) &S390_lowcore.irb;
+	if (tpi_info->adapter_IO) {
+		do_adapter_IO(tpi_info->isc);
+		goto out;
+	}
+	sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
+	if (!sch) {
+		/* Clear pending interrupt condition. */
+		inc_irq_stat(IRQIO_CIO);
+		tsch(tpi_info->schid, irb);
+		goto out;
+	}
+	spin_lock(sch->lock);
+	/* Store interrupt response block to lowcore. */
+	if (tsch(tpi_info->schid, irb) == 0) {
+		/* Keep subchannel information word up to date. */
+		memcpy (&sch->schib.scsw, &irb->scsw, sizeof (irb->scsw));
+		/* Call interrupt handler if there is one. */
+		if (sch->driver && sch->driver->irq)
+			sch->driver->irq(sch);
+		else
 			inc_irq_stat(IRQIO_CIO);
-		spin_unlock(sch->lock);
-		/*
-		 * Are more interrupts pending?
-		 * If so, the tpi instruction will update the lowcore
-		 * to hold the info for the next interrupt.
-		 * We don't do this for VM because a tpi drops the cpu
-		 * out of the sie which costs more cycles than it saves.
-		 */
-	} while (MACHINE_IS_LPAR && tpi(NULL) != 0);
+	} else
+		inc_irq_stat(IRQIO_CIO);
+	spin_unlock(sch->lock);
+out:
 	irq_exit();
 	set_irq_regs(old_regs);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/cio/qdio.h linux-libre-3.11-rc7-gnu/drivers/s390/cio/qdio.h
--- linux-libre-3.10-gnu/drivers/s390/cio/qdio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/cio/qdio.h	2013-08-25 20:43:22.000000000 -0400
@@ -140,40 +140,6 @@ struct siga_flag {
 	u8:3;
 } __attribute__ ((packed));
 
-struct chsc_ssqd_area {
-	struct chsc_header request;
-	u16:10;
-	u8 ssid:2;
-	u8 fmt:4;
-	u16 first_sch;
-	u16:16;
-	u16 last_sch;
-	u32:32;
-	struct chsc_header response;
-	u32:32;
-	struct qdio_ssqd_desc qdio_ssqd;
-} __attribute__ ((packed));
-
-struct scssc_area {
-	struct chsc_header request;
-	u16 operation_code;
-	u16:16;
-	u32:32;
-	u32:32;
-	u64 summary_indicator_addr;
-	u64 subchannel_indicator_addr;
-	u32 ks:4;
-	u32 kc:4;
-	u32:21;
-	u32 isc:3;
-	u32 word_with_d_bit;
-	u32:32;
-	struct subchannel_id schid;
-	u32 reserved[1004];
-	struct chsc_header response;
-	u32:32;
-} __attribute__ ((packed));
-
 struct qdio_dev_perf_stat {
 	unsigned int adapter_int;
 	unsigned int qdio_int;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/cio/qdio_main.c linux-libre-3.11-rc7-gnu/drivers/s390/cio/qdio_main.c
--- linux-libre-3.10-gnu/drivers/s390/cio/qdio_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/cio/qdio_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -608,50 +608,6 @@ static inline int contains_aobs(struct q
 	return !q->is_input_q && q->u.out.use_cq;
 }
 
-static inline void qdio_trace_aob(struct qdio_irq *irq, struct qdio_q *q,
-				int i, struct qaob *aob)
-{
-	int tmp;
-
-	DBF_DEV_EVENT(DBF_INFO, irq, "AOB%d:%lx", i,
-			(unsigned long) virt_to_phys(aob));
-	DBF_DEV_EVENT(DBF_INFO, irq, "RES00:%lx",
-			(unsigned long) aob->res0[0]);
-	DBF_DEV_EVENT(DBF_INFO, irq, "RES01:%lx",
-			(unsigned long) aob->res0[1]);
-	DBF_DEV_EVENT(DBF_INFO, irq, "RES02:%lx",
-			(unsigned long) aob->res0[2]);
-	DBF_DEV_EVENT(DBF_INFO, irq, "RES03:%lx",
-			(unsigned long) aob->res0[3]);
-	DBF_DEV_EVENT(DBF_INFO, irq, "RES04:%lx",
-			(unsigned long) aob->res0[4]);
-	DBF_DEV_EVENT(DBF_INFO, irq, "RES05:%lx",
-			(unsigned long) aob->res0[5]);
-	DBF_DEV_EVENT(DBF_INFO, irq, "RES1:%x", aob->res1);
-	DBF_DEV_EVENT(DBF_INFO, irq, "RES2:%x", aob->res2);
-	DBF_DEV_EVENT(DBF_INFO, irq, "RES3:%x", aob->res3);
-	DBF_DEV_EVENT(DBF_INFO, irq, "AORC:%u", aob->aorc);
-	DBF_DEV_EVENT(DBF_INFO, irq, "FLAGS:%u", aob->flags);
-	DBF_DEV_EVENT(DBF_INFO, irq, "CBTBS:%u", aob->cbtbs);
-	DBF_DEV_EVENT(DBF_INFO, irq, "SBC:%u", aob->sb_count);
-	for (tmp = 0; tmp < QDIO_MAX_ELEMENTS_PER_BUFFER; ++tmp) {
-		DBF_DEV_EVENT(DBF_INFO, irq, "SBA%d:%lx", tmp,
-				(unsigned long) aob->sba[tmp]);
-		DBF_DEV_EVENT(DBF_INFO, irq, "rSBA%d:%lx", tmp,
-				(unsigned long) q->sbal[i]->element[tmp].addr);
-		DBF_DEV_EVENT(DBF_INFO, irq, "DC%d:%u", tmp, aob->dcount[tmp]);
-		DBF_DEV_EVENT(DBF_INFO, irq, "rDC%d:%u", tmp,
-				q->sbal[i]->element[tmp].length);
-	}
-	DBF_DEV_EVENT(DBF_INFO, irq, "USER0:%lx", (unsigned long) aob->user0);
-	for (tmp = 0; tmp < 2; ++tmp) {
-		DBF_DEV_EVENT(DBF_INFO, irq, "RES4%d:%lx", tmp,
-			(unsigned long) aob->res4[tmp]);
-	}
-	DBF_DEV_EVENT(DBF_INFO, irq, "USER1:%lx", (unsigned long) aob->user1);
-	DBF_DEV_EVENT(DBF_INFO, irq, "USER2:%lx", (unsigned long) aob->user2);
-}
-
 static inline void qdio_handle_aobs(struct qdio_q *q, int start, int count)
 {
 	unsigned char state = 0;
@@ -1541,7 +1497,7 @@ static inline int buf_in_between(int buf
 static int handle_inbound(struct qdio_q *q, unsigned int callflags,
 			  int bufnr, int count)
 {
-	int used, diff;
+	int diff;
 
 	qperf_inc(q, inbound_call);
 
@@ -1574,7 +1530,7 @@ static int handle_inbound(struct qdio_q
 
 set:
 	count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count);
-	used = atomic_add_return(count, &q->nr_buf_used) - count;
+	atomic_add(count, &q->nr_buf_used);
 
 	if (need_siga_in(q))
 		return qdio_siga_input(q);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/cio/qdio_setup.c linux-libre-3.11-rc7-gnu/drivers/s390/cio/qdio_setup.c
--- linux-libre-3.10-gnu/drivers/s390/cio/qdio_setup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/cio/qdio_setup.c	2013-08-25 20:43:22.000000000 -0400
@@ -254,40 +254,31 @@ int qdio_setup_get_ssqd(struct qdio_irq
 	int rc;
 
 	DBF_EVENT("getssqd:%4x", schid->sch_no);
-	if (irq_ptr != NULL)
-		ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page;
-	else
+	if (!irq_ptr) {
 		ssqd = (struct chsc_ssqd_area *)__get_free_page(GFP_KERNEL);
-	memset(ssqd, 0, PAGE_SIZE);
-
-	ssqd->request = (struct chsc_header) {
-		.length = 0x0010,
-		.code	= 0x0024,
-	};
-	ssqd->first_sch = schid->sch_no;
-	ssqd->last_sch = schid->sch_no;
-	ssqd->ssid = schid->ssid;
+		if (!ssqd)
+			return -ENOMEM;
+	} else {
+		ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page;
+	}
 
-	if (chsc(ssqd))
-		return -EIO;
-	rc = chsc_error_from_response(ssqd->response.code);
+	rc = chsc_ssqd(*schid, ssqd);
 	if (rc)
-		return rc;
+		goto out;
 
 	if (!(ssqd->qdio_ssqd.flags & CHSC_FLAG_QDIO_CAPABILITY) ||
 	    !(ssqd->qdio_ssqd.flags & CHSC_FLAG_VALIDITY) ||
 	    (ssqd->qdio_ssqd.sch != schid->sch_no))
-		return -EINVAL;
+		rc = -EINVAL;
 
-	if (irq_ptr != NULL)
-		memcpy(&irq_ptr->ssqd_desc, &ssqd->qdio_ssqd,
-		       sizeof(struct qdio_ssqd_desc));
-	else {
-		memcpy(data, &ssqd->qdio_ssqd,
-		       sizeof(struct qdio_ssqd_desc));
+	if (!rc)
+		memcpy(data, &ssqd->qdio_ssqd, sizeof(*data));
+
+out:
+	if (!irq_ptr)
 		free_page((unsigned long)ssqd);
-	}
-	return 0;
+
+	return rc;
 }
 
 void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
@@ -295,7 +286,7 @@ void qdio_setup_ssqd_info(struct qdio_ir
 	unsigned char qdioac;
 	int rc;
 
-	rc = qdio_setup_get_ssqd(irq_ptr, &irq_ptr->schid, NULL);
+	rc = qdio_setup_get_ssqd(irq_ptr, &irq_ptr->schid, &irq_ptr->ssqd_desc);
 	if (rc) {
 		DBF_ERROR("%4x ssqd ERR", irq_ptr->schid.sch_no);
 		DBF_ERROR("rc:%x", rc);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/cio/qdio_thinint.c linux-libre-3.11-rc7-gnu/drivers/s390/cio/qdio_thinint.c
--- linux-libre-3.10-gnu/drivers/s390/cio/qdio_thinint.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/cio/qdio_thinint.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,8 +36,13 @@ struct indicator_t {
 static LIST_HEAD(tiq_list);
 static DEFINE_MUTEX(tiq_list_lock);
 
-/* adapter local summary indicator */
-static u8 *tiqdio_alsi;
+/* Adapter interrupt definitions */
+static void tiqdio_thinint_handler(struct airq_struct *airq);
+
+static struct airq_struct tiqdio_airq = {
+	.handler = tiqdio_thinint_handler,
+	.isc = QDIO_AIRQ_ISC,
+};
 
 static struct indicator_t *q_indicators;
 
@@ -176,7 +181,7 @@ static inline void tiqdio_call_inq_handl
  * @alsi: pointer to adapter local summary indicator
  * @data: NULL
  */
-static void tiqdio_thinint_handler(void *alsi, void *data)
+static void tiqdio_thinint_handler(struct airq_struct *airq)
 {
 	u32 si_used = clear_shared_ind();
 	struct qdio_q *q;
@@ -208,51 +213,31 @@ static void tiqdio_thinint_handler(void
 
 static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset)
 {
-	struct scssc_area *scssc_area;
+	struct chsc_scssc_area *scssc = (void *)irq_ptr->chsc_page;
+	u64 summary_indicator_addr, subchannel_indicator_addr;
 	int rc;
 
-	scssc_area = (struct scssc_area *)irq_ptr->chsc_page;
-	memset(scssc_area, 0, PAGE_SIZE);
-
 	if (reset) {
-		scssc_area->summary_indicator_addr = 0;
-		scssc_area->subchannel_indicator_addr = 0;
+		summary_indicator_addr = 0;
+		subchannel_indicator_addr = 0;
 	} else {
-		scssc_area->summary_indicator_addr = virt_to_phys(tiqdio_alsi);
-		scssc_area->subchannel_indicator_addr =
-			virt_to_phys(irq_ptr->dsci);
+		summary_indicator_addr = virt_to_phys(tiqdio_airq.lsi_ptr);
+		subchannel_indicator_addr = virt_to_phys(irq_ptr->dsci);
 	}
 
-	scssc_area->request = (struct chsc_header) {
-		.length = 0x0fe0,
-		.code	= 0x0021,
-	};
-	scssc_area->operation_code = 0;
-	scssc_area->ks = PAGE_DEFAULT_KEY >> 4;
-	scssc_area->kc = PAGE_DEFAULT_KEY >> 4;
-	scssc_area->isc = QDIO_AIRQ_ISC;
-	scssc_area->schid = irq_ptr->schid;
-
-	/* enable the time delay disablement facility */
-	if (css_general_characteristics.aif_tdd)
-		scssc_area->word_with_d_bit = 0x10000000;
-
-	rc = chsc(scssc_area);
-	if (rc)
-		return -EIO;
-
-	rc = chsc_error_from_response(scssc_area->response.code);
+	rc = chsc_sadc(irq_ptr->schid, scssc, summary_indicator_addr,
+		       subchannel_indicator_addr);
 	if (rc) {
 		DBF_ERROR("%4x SSI r:%4x", irq_ptr->schid.sch_no,
-			  scssc_area->response.code);
-		DBF_ERROR_HEX(&scssc_area->response, sizeof(void *));
-		return rc;
+			  scssc->response.code);
+		goto out;
 	}
 
 	DBF_EVENT("setscind");
-	DBF_HEX(&scssc_area->summary_indicator_addr, sizeof(unsigned long));
-	DBF_HEX(&scssc_area->subchannel_indicator_addr,	sizeof(unsigned long));
-	return 0;
+	DBF_HEX(&summary_indicator_addr, sizeof(summary_indicator_addr));
+	DBF_HEX(&subchannel_indicator_addr, sizeof(subchannel_indicator_addr));
+out:
+	return rc;
 }
 
 /* allocate non-shared indicators and shared indicator */
@@ -272,14 +257,12 @@ void tiqdio_free_memory(void)
 
 int __init tiqdio_register_thinints(void)
 {
-	isc_register(QDIO_AIRQ_ISC);
-	tiqdio_alsi = s390_register_adapter_interrupt(&tiqdio_thinint_handler,
-						      NULL, QDIO_AIRQ_ISC);
-	if (IS_ERR(tiqdio_alsi)) {
-		DBF_EVENT("RTI:%lx", PTR_ERR(tiqdio_alsi));
-		tiqdio_alsi = NULL;
-		isc_unregister(QDIO_AIRQ_ISC);
-		return -ENOMEM;
+	int rc;
+
+	rc = register_adapter_interrupt(&tiqdio_airq);
+	if (rc) {
+		DBF_EVENT("RTI:%x", rc);
+		return rc;
 	}
 	return 0;
 }
@@ -312,9 +295,5 @@ void qdio_shutdown_thinint(struct qdio_i
 void __exit tiqdio_unregister_thinints(void)
 {
 	WARN_ON(!list_empty(&tiq_list));
-
-	if (tiqdio_alsi) {
-		s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC);
-		isc_unregister(QDIO_AIRQ_ISC);
-	}
+	unregister_adapter_interrupt(&tiqdio_airq);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/crypto/ap_bus.c linux-libre-3.11-rc7-gnu/drivers/s390/crypto/ap_bus.c
--- linux-libre-3.10-gnu/drivers/s390/crypto/ap_bus.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/crypto/ap_bus.c	2013-08-25 20:43:22.000000000 -0400
@@ -58,7 +58,7 @@ static inline void ap_schedule_poll_time
 static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags);
 static int ap_device_remove(struct device *dev);
 static int ap_device_probe(struct device *dev);
-static void ap_interrupt_handler(void *unused1, void *unused2);
+static void ap_interrupt_handler(struct airq_struct *airq);
 static void ap_reset(struct ap_device *ap_dev);
 static void ap_config_timeout(unsigned long ptr);
 static int ap_select_domain(void);
@@ -71,6 +71,7 @@ MODULE_AUTHOR("IBM Corporation");
 MODULE_DESCRIPTION("Adjunct Processor Bus driver, " \
 		   "Copyright IBM Corp. 2006, 2012");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("z90crypt");
 
 /*
  * Module parameter
@@ -106,7 +107,6 @@ static DECLARE_WAIT_QUEUE_HEAD(ap_poll_w
 static struct task_struct *ap_poll_kthread = NULL;
 static DEFINE_MUTEX(ap_poll_thread_mutex);
 static DEFINE_SPINLOCK(ap_poll_timer_lock);
-static void *ap_interrupt_indicator;
 static struct hrtimer ap_poll_timer;
 /* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
  * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
@@ -120,13 +120,21 @@ static int ap_suspend_flag;
 static int user_set_domain = 0;
 static struct bus_type ap_bus_type;
 
+/* Adapter interrupt definitions */
+static int ap_airq_flag;
+
+static struct airq_struct ap_airq = {
+	.handler = ap_interrupt_handler,
+	.isc = AP_ISC,
+};
+
 /**
  * ap_using_interrupts() - Returns non-zero if interrupt support is
  * available.
  */
 static inline int ap_using_interrupts(void)
 {
-	return ap_interrupt_indicator != NULL;
+	return ap_airq_flag;
 }
 
 /**
@@ -588,7 +596,7 @@ static int ap_init_queue(ap_qid_t qid)
 		}
 	}
 	if (rc == 0 && ap_using_interrupts()) {
-		rc = ap_queue_enable_interruption(qid, ap_interrupt_indicator);
+		rc = ap_queue_enable_interruption(qid, ap_airq.lsi_ptr);
 		/* If interruption mode is supported by the machine,
 		* but an AP can not be enabled for interruption then
 		* the AP will be discarded.    */
@@ -821,13 +829,22 @@ static int ap_bus_suspend(struct device
 
 static int ap_bus_resume(struct device *dev)
 {
-	int rc = 0;
 	struct ap_device *ap_dev = to_ap_dev(dev);
+	int rc;
 
 	if (ap_suspend_flag) {
 		ap_suspend_flag = 0;
-		if (!ap_interrupts_available())
-			ap_interrupt_indicator = NULL;
+		if (ap_interrupts_available()) {
+			if (!ap_using_interrupts()) {
+				rc = register_adapter_interrupt(&ap_airq);
+				ap_airq_flag = (rc == 0);
+			}
+		} else {
+			if (ap_using_interrupts()) {
+				unregister_adapter_interrupt(&ap_airq);
+				ap_airq_flag = 0;
+			}
+		}
 		ap_query_configuration();
 		if (!user_set_domain) {
 			ap_domain_index = -1;
@@ -848,7 +865,10 @@ static int ap_bus_resume(struct device *
 			tasklet_schedule(&ap_tasklet);
 		if (ap_thread_flag)
 			rc = ap_poll_thread_start();
-	}
+		else
+			rc = 0;
+	} else
+		rc = 0;
 	if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
 		spin_lock_bh(&ap_dev->lock);
 		ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
@@ -1266,7 +1286,7 @@ out:
 	return rc;
 }
 
-static void ap_interrupt_handler(void *unused1, void *unused2)
+static void ap_interrupt_handler(struct airq_struct *airq)
 {
 	inc_irq_stat(IRQIO_APB);
 	tasklet_schedule(&ap_tasklet);
@@ -1722,7 +1742,7 @@ static void ap_poll_all(unsigned long du
 	 * important that no requests on any AP get lost.
 	 */
 	if (ap_using_interrupts())
-		xchg((u8 *)ap_interrupt_indicator, 0);
+		xchg(ap_airq.lsi_ptr, 0);
 	do {
 		flags = 0;
 		spin_lock(&ap_device_list_lock);
@@ -1795,7 +1815,7 @@ static int ap_poll_thread_start(void)
 	mutex_lock(&ap_poll_thread_mutex);
 	if (!ap_poll_kthread) {
 		ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
-		rc = IS_ERR(ap_poll_kthread) ? PTR_ERR(ap_poll_kthread) : 0;
+		rc = PTR_RET(ap_poll_kthread);
 		if (rc)
 			ap_poll_kthread = NULL;
 	}
@@ -1881,13 +1901,8 @@ int __init ap_module_init(void)
 		return -ENODEV;
 	}
 	if (ap_interrupts_available()) {
-		isc_register(AP_ISC);
-		ap_interrupt_indicator = s390_register_adapter_interrupt(
-			&ap_interrupt_handler, NULL, AP_ISC);
-		if (IS_ERR(ap_interrupt_indicator)) {
-			ap_interrupt_indicator = NULL;
-			isc_unregister(AP_ISC);
-		}
+		rc = register_adapter_interrupt(&ap_airq);
+		ap_airq_flag = (rc == 0);
 	}
 
 	register_reset_call(&ap_reset_call);
@@ -1904,7 +1919,7 @@ int __init ap_module_init(void)
 
 	/* Create /sys/devices/ap. */
 	ap_root_device = root_device_register("ap");
-	rc = IS_ERR(ap_root_device) ? PTR_ERR(ap_root_device) : 0;
+	rc = PTR_RET(ap_root_device);
 	if (rc)
 		goto out_bus;
 
@@ -1955,10 +1970,8 @@ out_bus:
 	bus_unregister(&ap_bus_type);
 out:
 	unregister_reset_call(&ap_reset_call);
-	if (ap_using_interrupts()) {
-		s390_unregister_adapter_interrupt(ap_interrupt_indicator, AP_ISC);
-		isc_unregister(AP_ISC);
-	}
+	if (ap_using_interrupts())
+		unregister_adapter_interrupt(&ap_airq);
 	return rc;
 }
 
@@ -1994,10 +2007,8 @@ void ap_module_exit(void)
 		bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
 	bus_unregister(&ap_bus_type);
 	unregister_reset_call(&ap_reset_call);
-	if (ap_using_interrupts()) {
-		s390_unregister_adapter_interrupt(ap_interrupt_indicator, AP_ISC);
-		isc_unregister(AP_ISC);
-	}
+	if (ap_using_interrupts())
+		unregister_adapter_interrupt(&ap_airq);
 }
 
 module_init(ap_module_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/net/claw.c linux-libre-3.11-rc7-gnu/drivers/s390/net/claw.c
--- linux-libre-3.10-gnu/drivers/s390/net/claw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/net/claw.c	2013-08-25 20:43:22.000000000 -0400
@@ -3348,7 +3348,7 @@ static int __init claw_init(void)
 	}
 	CLAW_DBF_TEXT(2, setup, "init_mod");
 	claw_root_dev = root_device_register("claw");
-	ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0;
+	ret = PTR_RET(claw_root_dev);
 	if (ret)
 		goto register_err;
 	ret = ccw_driver_register(&claw_ccw_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/net/ctcm_main.c linux-libre-3.11-rc7-gnu/drivers/s390/net/ctcm_main.c
--- linux-libre-3.10-gnu/drivers/s390/net/ctcm_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/net/ctcm_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1837,7 +1837,7 @@ static int __init ctcm_init(void)
 	if (ret)
 		goto out_err;
 	ctcm_root_dev = root_device_register("ctcm");
-	ret = IS_ERR(ctcm_root_dev) ? PTR_ERR(ctcm_root_dev) : 0;
+	ret = PTR_RET(ctcm_root_dev);
 	if (ret)
 		goto register_err;
 	ret = ccw_driver_register(&ctcm_ccw_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/net/lcs.c linux-libre-3.11-rc7-gnu/drivers/s390/net/lcs.c
--- linux-libre-3.10-gnu/drivers/s390/net/lcs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/net/lcs.c	2013-08-25 20:43:22.000000000 -0400
@@ -2441,7 +2441,7 @@ __init lcs_init_module(void)
 	if (rc)
 		goto out_err;
 	lcs_root_dev = root_device_register("lcs");
-	rc = IS_ERR(lcs_root_dev) ? PTR_ERR(lcs_root_dev) : 0;
+	rc = PTR_RET(lcs_root_dev);
 	if (rc)
 		goto register_err;
 	rc = ccw_driver_register(&lcs_ccw_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/net/netiucv.c linux-libre-3.11-rc7-gnu/drivers/s390/net/netiucv.c
--- linux-libre-3.10-gnu/drivers/s390/net/netiucv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/net/netiucv.c	2013-08-25 20:43:22.000000000 -0400
@@ -130,26 +130,6 @@ static inline int iucv_dbf_passes(debug_
 /**
  * some more debug stuff
  */
-#define IUCV_HEXDUMP16(importance,header,ptr) \
-PRINT_##importance(header "%02x %02x %02x %02x  %02x %02x %02x %02x  " \
-		   "%02x %02x %02x %02x  %02x %02x %02x %02x\n", \
-		   *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \
-		   *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \
-		   *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \
-		   *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \
-		   *(((char*)ptr)+12),*(((char*)ptr)+13), \
-		   *(((char*)ptr)+14),*(((char*)ptr)+15)); \
-PRINT_##importance(header "%02x %02x %02x %02x  %02x %02x %02x %02x  " \
-		   "%02x %02x %02x %02x  %02x %02x %02x %02x\n", \
-		   *(((char*)ptr)+16),*(((char*)ptr)+17), \
-		   *(((char*)ptr)+18),*(((char*)ptr)+19), \
-		   *(((char*)ptr)+20),*(((char*)ptr)+21), \
-		   *(((char*)ptr)+22),*(((char*)ptr)+23), \
-		   *(((char*)ptr)+24),*(((char*)ptr)+25), \
-		   *(((char*)ptr)+26),*(((char*)ptr)+27), \
-		   *(((char*)ptr)+28),*(((char*)ptr)+29), \
-		   *(((char*)ptr)+30),*(((char*)ptr)+31));
-
 #define PRINTK_HEADER " iucv: "       /* for debugging */
 
 /* dummy device to make sure netiucv_pm functions are called */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/net/qeth_core.h linux-libre-3.11-rc7-gnu/drivers/s390/net/qeth_core.h
--- linux-libre-3.10-gnu/drivers/s390/net/qeth_core.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/net/qeth_core.h	2013-08-25 20:43:22.000000000 -0400
@@ -738,7 +738,7 @@ struct qeth_rx {
 	int qdio_err;
 };
 
-#define QETH_NAPI_WEIGHT 128
+#define QETH_NAPI_WEIGHT NAPI_POLL_WEIGHT
 
 struct qeth_card {
 	struct list_head list;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/net/qeth_core_main.c linux-libre-3.11-rc7-gnu/drivers/s390/net/qeth_core_main.c
--- linux-libre-3.10-gnu/drivers/s390/net/qeth_core_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/net/qeth_core_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -1282,8 +1282,10 @@ static void qeth_free_qdio_buffers(struc
 
 	qeth_free_cq(card);
 	cancel_delayed_work_sync(&card->buffer_reclaim_work);
-	for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
-		dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb);
+	for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
+		if (card->qdio.in_q->bufs[j].rx_skb)
+			dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb);
+	}
 	kfree(card->qdio.in_q);
 	card->qdio.in_q = NULL;
 	/* inbound buffer pool */
@@ -1729,14 +1731,14 @@ static void qeth_configure_blkt_default(
 	QETH_DBF_TEXT(SETUP, 2, "cfgblkt");
 
 	if (prcd[74] == 0xF0 && prcd[75] == 0xF0 &&
-	    (prcd[76] == 0xF5 || prcd[76] == 0xF6)) {
-		card->info.blkt.time_total = 250;
-		card->info.blkt.inter_packet = 5;
-		card->info.blkt.inter_packet_jumbo = 15;
-	} else {
+	    prcd[76] >= 0xF1 && prcd[76] <= 0xF4) {
 		card->info.blkt.time_total = 0;
 		card->info.blkt.inter_packet = 0;
 		card->info.blkt.inter_packet_jumbo = 0;
+	} else {
+		card->info.blkt.time_total = 250;
+		card->info.blkt.inter_packet = 5;
+		card->info.blkt.inter_packet_jumbo = 15;
 	}
 }
 
@@ -2198,11 +2200,11 @@ static inline int qeth_get_initial_mtu_f
 		case QETH_LINK_TYPE_LANE_TR:
 			return 2000;
 		default:
-			return 1492;
+			return card->options.layer2 ? 1500 : 1492;
 		}
 	case QETH_CARD_TYPE_OSM:
 	case QETH_CARD_TYPE_OSX:
-		return 1492;
+		return card->options.layer2 ? 1500 : 1492;
 	default:
 		return 1500;
 	}
@@ -2275,9 +2277,10 @@ static int qeth_ulp_enable_cb(struct qet
 		card->info.max_mtu = mtu;
 		card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE;
 	} else {
-		card->info.initial_mtu = qeth_get_initial_mtu_for_card(card);
 		card->info.max_mtu = *(__u16 *)QETH_ULP_ENABLE_RESP_MAX_MTU(
 			iob->data);
+		card->info.initial_mtu = min(card->info.max_mtu,
+					qeth_get_initial_mtu_for_card(card));
 		card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
 	}
 
@@ -5705,7 +5708,7 @@ static int __init qeth_core_init(void)
 	if (rc)
 		goto out_err;
 	qeth_core_root_dev = root_device_register("qeth");
-	rc = IS_ERR(qeth_core_root_dev) ? PTR_ERR(qeth_core_root_dev) : 0;
+	rc = PTR_RET(qeth_core_root_dev);
 	if (rc)
 		goto register_err;
 	qeth_core_header_cache = kmem_cache_create("qeth_hdr",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/net/qeth_l3_sys.c linux-libre-3.11-rc7-gnu/drivers/s390/net/qeth_l3_sys.c
--- linux-libre-3.10-gnu/drivers/s390/net/qeth_l3_sys.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/net/qeth_l3_sys.c	2013-08-25 20:43:22.000000000 -0400
@@ -315,10 +315,8 @@ static ssize_t qeth_l3_dev_hsuid_store(s
 	if (qeth_configure_cq(card, QETH_CQ_ENABLED))
 		return -EPERM;
 
-	for (i = 0; i < 8; i++)
-		card->options.hsuid[i] = ' ';
-	card->options.hsuid[8] = '\0';
-	strncpy(card->options.hsuid, tmp, strlen(tmp));
+	snprintf(card->options.hsuid, sizeof(card->options.hsuid),
+		 "%-8s", tmp);
 	ASCEBC(card->options.hsuid, 8);
 	if (card->dev)
 		memcpy(card->dev->perm_addr, card->options.hsuid, 9);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/Makefile linux-libre-3.11-rc7-gnu/drivers/s390/scsi/Makefile
--- linux-libre-3.10-gnu/drivers/s390/scsi/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,7 @@
 # Makefile for the S/390 specific device drivers
 #
 
-zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_cfdc.o zfcp_dbf.o zfcp_erp.o \
+zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_dbf.o zfcp_erp.o \
 	     zfcp_fc.o zfcp_fsf.o zfcp_qdio.o zfcp_scsi.o zfcp_sysfs.o \
 	     zfcp_unit.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_aux.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_aux.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_aux.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_aux.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Module interface and handling of zfcp data structures.
  *
- * Copyright IBM Corp. 2002, 2010
+ * Copyright IBM Corp. 2002, 2013
  */
 
 /*
@@ -23,6 +23,7 @@
  *            Christof Schmitt
  *            Martin Petermann
  *            Sven Schuetz
+ *            Steffen Maier
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -140,13 +141,6 @@ static int __init zfcp_module_init(void)
 	scsi_transport_reserve_device(zfcp_scsi_transport_template,
 				      sizeof(struct zfcp_scsi_dev));
 
-
-	retval = misc_register(&zfcp_cfdc_misc);
-	if (retval) {
-		pr_err("Registering the misc device zfcp_cfdc failed\n");
-		goto out_misc;
-	}
-
 	retval = ccw_driver_register(&zfcp_ccw_driver);
 	if (retval) {
 		pr_err("The zfcp device driver could not register with "
@@ -159,8 +153,6 @@ static int __init zfcp_module_init(void)
 	return 0;
 
 out_ccw_register:
-	misc_deregister(&zfcp_cfdc_misc);
-out_misc:
 	fc_release_transport(zfcp_scsi_transport_template);
 out_transport:
 	kmem_cache_destroy(zfcp_fc_req_cache);
@@ -175,7 +167,6 @@ module_init(zfcp_module_init);
 static void __exit zfcp_module_exit(void)
 {
 	ccw_driver_unregister(&zfcp_ccw_driver);
-	misc_deregister(&zfcp_cfdc_misc);
 	fc_release_transport(zfcp_scsi_transport_template);
 	kmem_cache_destroy(zfcp_fc_req_cache);
 	kmem_cache_destroy(zfcp_fsf_qtcb_cache);
@@ -415,6 +406,8 @@ struct zfcp_adapter *zfcp_adapter_enqueu
 	adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN;
 	adapter->ccw_device->dev.dma_parms = &adapter->dma_parms;
 
+	adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM;
+
 	if (!zfcp_scsi_adapter_register(adapter))
 		return adapter;
 
@@ -464,20 +457,6 @@ void zfcp_adapter_release(struct kref *r
 	put_device(&cdev->dev);
 }
 
-/**
- * zfcp_device_unregister - remove port, unit from system
- * @dev: reference to device which is to be removed
- * @grp: related reference to attribute group
- *
- * Helper function to unregister port, unit from system
- */
-void zfcp_device_unregister(struct device *dev,
-			    const struct attribute_group *grp)
-{
-	sysfs_remove_group(&dev->kobj, grp);
-	device_unregister(dev);
-}
-
 static void zfcp_port_release(struct device *dev)
 {
 	struct zfcp_port *port = container_of(dev, struct zfcp_port, dev);
@@ -530,6 +509,7 @@ struct zfcp_port *zfcp_port_enqueue(stru
 	port->wwpn = wwpn;
 	port->rport_task = RPORT_NONE;
 	port->dev.parent = &adapter->ccw_device->dev;
+	port->dev.groups = zfcp_port_attr_groups;
 	port->dev.release = zfcp_port_release;
 
 	if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) {
@@ -543,10 +523,6 @@ struct zfcp_port *zfcp_port_enqueue(stru
 		goto err_out;
 	}
 
-	if (sysfs_create_group(&port->dev.kobj,
-			       &zfcp_sysfs_port_attrs))
-		goto err_out_put;
-
 	write_lock_irq(&adapter->port_list_lock);
 	list_add_tail(&port->list, &adapter->port_list);
 	write_unlock_irq(&adapter->port_list_lock);
@@ -555,8 +531,6 @@ struct zfcp_port *zfcp_port_enqueue(stru
 
 	return port;
 
-err_out_put:
-	device_unregister(&port->dev);
 err_out:
 	zfcp_ccw_adapter_put(adapter);
 	return ERR_PTR(retval);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_ccw.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_ccw.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_ccw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_ccw.c	2013-08-25 20:43:22.000000000 -0400
@@ -72,15 +72,6 @@ static struct ccw_device_id zfcp_ccw_dev
 MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id);
 
 /**
- * zfcp_ccw_priv_sch - check if subchannel is privileged
- * @adapter: Adapter/Subchannel to check
- */
-int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter)
-{
-	return adapter->ccw_device->id.dev_model == ZFCP_MODEL_PRIV;
-}
-
-/**
  * zfcp_ccw_probe - probe function of zfcp driver
  * @cdev: pointer to belonging ccw device
  *
@@ -129,10 +120,10 @@ static void zfcp_ccw_remove(struct ccw_d
 	zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */
 
 	list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
-		zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
+		device_unregister(&unit->dev);
 
 	list_for_each_entry_safe(port, p, &port_remove_lh, list)
-		zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
+		device_unregister(&port->dev);
 
 	zfcp_adapter_unregister(adapter);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_cfdc.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_cfdc.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_cfdc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_cfdc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,446 +0,0 @@
-/*
- * zfcp device driver
- *
- * Userspace interface for accessing the
- * Access Control Lists / Control File Data Channel;
- * handling of response code and states for ports and LUNs.
- *
- * Copyright IBM Corp. 2008, 2010
- */
-
-#define KMSG_COMPONENT "zfcp"
-#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
-
-#include <linux/compat.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/miscdevice.h>
-#include <asm/compat.h>
-#include <asm/ccwdev.h>
-#include "zfcp_def.h"
-#include "zfcp_ext.h"
-#include "zfcp_fsf.h"
-
-#define ZFCP_CFDC_CMND_DOWNLOAD_NORMAL		0x00010001
-#define ZFCP_CFDC_CMND_DOWNLOAD_FORCE		0x00010101
-#define ZFCP_CFDC_CMND_FULL_ACCESS		0x00000201
-#define ZFCP_CFDC_CMND_RESTRICTED_ACCESS	0x00000401
-#define ZFCP_CFDC_CMND_UPLOAD			0x00010002
-
-#define ZFCP_CFDC_DOWNLOAD			0x00000001
-#define ZFCP_CFDC_UPLOAD			0x00000002
-#define ZFCP_CFDC_WITH_CONTROL_FILE		0x00010000
-
-#define ZFCP_CFDC_IOC_MAGIC                     0xDD
-#define ZFCP_CFDC_IOC \
-	_IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_data)
-
-/**
- * struct zfcp_cfdc_data - data for ioctl cfdc interface
- * @signature: request signature
- * @devno: FCP adapter device number
- * @command: command code
- * @fsf_status: returns status of FSF command to userspace
- * @fsf_status_qual: returned to userspace
- * @payloads: access conflicts list
- * @control_file: access control table
- */
-struct zfcp_cfdc_data {
-	u32 signature;
-	u32 devno;
-	u32 command;
-	u32 fsf_status;
-	u8  fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
-	u8  payloads[256];
-	u8  control_file[0];
-};
-
-static int zfcp_cfdc_copy_from_user(struct scatterlist *sg,
-				    void __user *user_buffer)
-{
-	unsigned int length;
-	unsigned int size = ZFCP_CFDC_MAX_SIZE;
-
-	while (size) {
-		length = min((unsigned int)size, sg->length);
-		if (copy_from_user(sg_virt(sg++), user_buffer, length))
-			return -EFAULT;
-		user_buffer += length;
-		size -= length;
-	}
-	return 0;
-}
-
-static int zfcp_cfdc_copy_to_user(void __user  *user_buffer,
-				  struct scatterlist *sg)
-{
-	unsigned int length;
-	unsigned int size = ZFCP_CFDC_MAX_SIZE;
-
-	while (size) {
-		length = min((unsigned int) size, sg->length);
-		if (copy_to_user(user_buffer, sg_virt(sg++), length))
-			return -EFAULT;
-		user_buffer += length;
-		size -= length;
-	}
-	return 0;
-}
-
-static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
-{
-	char busid[9];
-	struct ccw_device *cdev;
-	struct zfcp_adapter *adapter;
-
-	snprintf(busid, sizeof(busid), "0.0.%04x", devno);
-	cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
-	if (!cdev)
-		return NULL;
-
-	adapter = zfcp_ccw_adapter_by_cdev(cdev);
-
-	put_device(&cdev->dev);
-	return adapter;
-}
-
-static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command)
-{
-	switch (command) {
-	case ZFCP_CFDC_CMND_DOWNLOAD_NORMAL:
-		fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE;
-		fsf_cfdc->option = FSF_CFDC_OPTION_NORMAL_MODE;
-		break;
-	case ZFCP_CFDC_CMND_DOWNLOAD_FORCE:
-		fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE;
-		fsf_cfdc->option = FSF_CFDC_OPTION_FORCE;
-		break;
-	case ZFCP_CFDC_CMND_FULL_ACCESS:
-		fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE;
-		fsf_cfdc->option = FSF_CFDC_OPTION_FULL_ACCESS;
-		break;
-	case ZFCP_CFDC_CMND_RESTRICTED_ACCESS:
-		fsf_cfdc->command = FSF_QTCB_DOWNLOAD_CONTROL_FILE;
-		fsf_cfdc->option = FSF_CFDC_OPTION_RESTRICTED_ACCESS;
-		break;
-	case ZFCP_CFDC_CMND_UPLOAD:
-		fsf_cfdc->command = FSF_QTCB_UPLOAD_CONTROL_FILE;
-		fsf_cfdc->option = 0;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int zfcp_cfdc_sg_setup(int command, struct scatterlist *sg,
-			      u8 __user *control_file)
-{
-	int retval;
-	retval = zfcp_sg_setup_table(sg, ZFCP_CFDC_PAGES);
-	if (retval)
-		return retval;
-
-	sg[ZFCP_CFDC_PAGES - 1].length = ZFCP_CFDC_MAX_SIZE % PAGE_SIZE;
-
-	if (command & ZFCP_CFDC_WITH_CONTROL_FILE &&
-	    command & ZFCP_CFDC_DOWNLOAD) {
-		retval = zfcp_cfdc_copy_from_user(sg, control_file);
-		if (retval) {
-			zfcp_sg_free_table(sg, ZFCP_CFDC_PAGES);
-			return -EFAULT;
-		}
-	}
-
-	return 0;
-}
-
-static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data,
-				   struct zfcp_fsf_req *req)
-{
-	data->fsf_status = req->qtcb->header.fsf_status;
-	memcpy(&data->fsf_status_qual, &req->qtcb->header.fsf_status_qual,
-	       sizeof(union fsf_status_qual));
-	memcpy(&data->payloads, &req->qtcb->bottom.support.els,
-	       sizeof(req->qtcb->bottom.support.els));
-}
-
-static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
-				unsigned long arg)
-{
-	struct zfcp_cfdc_data *data;
-	struct zfcp_cfdc_data __user *data_user;
-	struct zfcp_adapter *adapter;
-	struct zfcp_fsf_req *req;
-	struct zfcp_fsf_cfdc *fsf_cfdc;
-	int retval;
-
-	if (command != ZFCP_CFDC_IOC)
-		return -ENOTTY;
-
-	if (is_compat_task())
-		data_user = compat_ptr(arg);
-	else
-		data_user = (void __user *)arg;
-
-	if (!data_user)
-		return -EINVAL;
-
-	fsf_cfdc = kmalloc(sizeof(struct zfcp_fsf_cfdc), GFP_KERNEL);
-	if (!fsf_cfdc)
-		return -ENOMEM;
-
-	data = memdup_user(data_user, sizeof(*data_user));
-	if (IS_ERR(data)) {
-		retval = PTR_ERR(data);
-		goto no_mem_sense;
-	}
-
-	if (data->signature != 0xCFDCACDF) {
-		retval = -EINVAL;
-		goto free_buffer;
-	}
-
-	retval = zfcp_cfdc_set_fsf(fsf_cfdc, data->command);
-
-	adapter = zfcp_cfdc_get_adapter(data->devno);
-	if (!adapter) {
-		retval = -ENXIO;
-		goto free_buffer;
-	}
-
-	retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
-				    data_user->control_file);
-	if (retval)
-		goto adapter_put;
-	req = zfcp_fsf_control_file(adapter, fsf_cfdc);
-	if (IS_ERR(req)) {
-		retval = PTR_ERR(req);
-		goto free_sg;
-	}
-
-	if (req->status & ZFCP_STATUS_FSFREQ_ERROR) {
-		retval = -ENXIO;
-		goto free_fsf;
-	}
-
-	zfcp_cfdc_req_to_sense(data, req);
-	retval = copy_to_user(data_user, data, sizeof(*data_user));
-	if (retval) {
-		retval = -EFAULT;
-		goto free_fsf;
-	}
-
-	if (data->command & ZFCP_CFDC_UPLOAD)
-		retval = zfcp_cfdc_copy_to_user(&data_user->control_file,
-						fsf_cfdc->sg);
-
- free_fsf:
-	zfcp_fsf_req_free(req);
- free_sg:
-	zfcp_sg_free_table(fsf_cfdc->sg, ZFCP_CFDC_PAGES);
- adapter_put:
-	zfcp_ccw_adapter_put(adapter);
- free_buffer:
-	kfree(data);
- no_mem_sense:
-	kfree(fsf_cfdc);
-	return retval;
-}
-
-static const struct file_operations zfcp_cfdc_fops = {
-	.open = nonseekable_open,
-	.unlocked_ioctl = zfcp_cfdc_dev_ioctl,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl = zfcp_cfdc_dev_ioctl,
-#endif
-	.llseek = no_llseek,
-};
-
-struct miscdevice zfcp_cfdc_misc = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "zfcp_cfdc",
-	.fops = &zfcp_cfdc_fops,
-};
-
-/**
- * zfcp_cfdc_adapter_access_changed - Process change in adapter ACT
- * @adapter: Adapter where the Access Control Table (ACT) changed
- *
- * After a change in the adapter ACT, check if access to any
- * previously denied resources is now possible.
- */
-void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
-{
-	unsigned long flags;
-	struct zfcp_port *port;
-	struct scsi_device *sdev;
-	struct zfcp_scsi_dev *zfcp_sdev;
-	int status;
-
-	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
-		return;
-
-	read_lock_irqsave(&adapter->port_list_lock, flags);
-	list_for_each_entry(port, &adapter->port_list, list) {
-		status = atomic_read(&port->status);
-		if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
-		    (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
-			zfcp_erp_port_reopen(port,
-					     ZFCP_STATUS_COMMON_ERP_FAILED,
-					     "cfaac_1");
-	}
-	read_unlock_irqrestore(&adapter->port_list_lock, flags);
-
-	shost_for_each_device(sdev, adapter->scsi_host) {
-		zfcp_sdev = sdev_to_zfcp(sdev);
-		status = atomic_read(&zfcp_sdev->status);
-		if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
-		    (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
-			zfcp_erp_lun_reopen(sdev,
-					    ZFCP_STATUS_COMMON_ERP_FAILED,
-					    "cfaac_2");
-	}
-}
-
-static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table)
-{
-	u16 subtable = table >> 16;
-	u16 rule = table & 0xffff;
-	const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" };
-
-	if (subtable && subtable < ARRAY_SIZE(act_type))
-		dev_warn(&adapter->ccw_device->dev,
-			 "Access denied according to ACT rule type %s, "
-			 "rule %d\n", act_type[subtable], rule);
-}
-
-/**
- * zfcp_cfdc_port_denied - Process "access denied" for port
- * @port: The port where the access has been denied
- * @qual: The FSF status qualifier for the access denied FSF status
- */
-void zfcp_cfdc_port_denied(struct zfcp_port *port,
-			   union fsf_status_qual *qual)
-{
-	dev_warn(&port->adapter->ccw_device->dev,
-		 "Access denied to port 0x%016Lx\n",
-		 (unsigned long long)port->wwpn);
-
-	zfcp_act_eval_err(port->adapter, qual->halfword[0]);
-	zfcp_act_eval_err(port->adapter, qual->halfword[1]);
-	zfcp_erp_set_port_status(port,
-				 ZFCP_STATUS_COMMON_ERP_FAILED |
-				 ZFCP_STATUS_COMMON_ACCESS_DENIED);
-}
-
-/**
- * zfcp_cfdc_lun_denied - Process "access denied" for LUN
- * @sdev: The SCSI device / LUN where the access has been denied
- * @qual: The FSF status qualifier for the access denied FSF status
- */
-void zfcp_cfdc_lun_denied(struct scsi_device *sdev,
-			  union fsf_status_qual *qual)
-{
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
-
-	dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
-		 "Access denied to LUN 0x%016Lx on port 0x%016Lx\n",
-		 zfcp_scsi_dev_lun(sdev),
-		 (unsigned long long)zfcp_sdev->port->wwpn);
-	zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]);
-	zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]);
-	zfcp_erp_set_lun_status(sdev,
-				ZFCP_STATUS_COMMON_ERP_FAILED |
-				ZFCP_STATUS_COMMON_ACCESS_DENIED);
-
-	atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
-	atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
-}
-
-/**
- * zfcp_cfdc_lun_shrng_vltn - Evaluate LUN sharing violation status
- * @sdev: The LUN / SCSI device where sharing violation occurred
- * @qual: The FSF status qualifier from the LUN sharing violation
- */
-void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *sdev,
-			      union fsf_status_qual *qual)
-{
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
-
-	if (qual->word[0])
-		dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
-			 "LUN 0x%Lx on port 0x%Lx is already in "
-			 "use by CSS%d, MIF Image ID %x\n",
-			 zfcp_scsi_dev_lun(sdev),
-			 (unsigned long long)zfcp_sdev->port->wwpn,
-			 qual->fsf_queue_designator.cssid,
-			 qual->fsf_queue_designator.hla);
-	else
-		zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]);
-
-	zfcp_erp_set_lun_status(sdev,
-				ZFCP_STATUS_COMMON_ERP_FAILED |
-				ZFCP_STATUS_COMMON_ACCESS_DENIED);
-	atomic_clear_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
-	atomic_clear_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
-}
-
-/**
- * zfcp_cfdc_open_lun_eval - Eval access ctrl. status for successful "open lun"
- * @sdev: The SCSI device / LUN where to evaluate the status
- * @bottom: The qtcb bottom with the status from the "open lun"
- *
- * Returns: 0 if LUN is usable, -EACCES if the access control table
- *          reports an unsupported configuration.
- */
-int zfcp_cfdc_open_lun_eval(struct scsi_device *sdev,
-			    struct fsf_qtcb_bottom_support *bottom)
-{
-	int shared, rw;
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
-	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
-
-	if ((adapter->connection_features & FSF_FEATURE_NPIV_MODE) ||
-	    !(adapter->adapter_features & FSF_FEATURE_LUN_SHARING) ||
-	    zfcp_ccw_priv_sch(adapter))
-		return 0;
-
-	shared = !(bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE);
-	rw = (bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER);
-
-	if (shared)
-		atomic_set_mask(ZFCP_STATUS_LUN_SHARED, &zfcp_sdev->status);
-
-	if (!rw) {
-		atomic_set_mask(ZFCP_STATUS_LUN_READONLY, &zfcp_sdev->status);
-		dev_info(&adapter->ccw_device->dev, "SCSI device at LUN "
-			 "0x%016Lx on port 0x%016Lx opened read-only\n",
-			 zfcp_scsi_dev_lun(sdev),
-			 (unsigned long long)zfcp_sdev->port->wwpn);
-	}
-
-	if (!shared && !rw) {
-		dev_err(&adapter->ccw_device->dev, "Exclusive read-only access "
-			"not supported (LUN 0x%016Lx, port 0x%016Lx)\n",
-			zfcp_scsi_dev_lun(sdev),
-			(unsigned long long)zfcp_sdev->port->wwpn);
-		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
-		zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6");
-		return -EACCES;
-	}
-
-	if (shared && rw) {
-		dev_err(&adapter->ccw_device->dev,
-			"Shared read-write access not supported "
-			"(LUN 0x%016Lx, port 0x%016Lx)\n",
-			zfcp_scsi_dev_lun(sdev),
-			(unsigned long long)zfcp_sdev->port->wwpn);
-		zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED);
-		zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8");
-		return -EACCES;
-	}
-
-	return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_dbf.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_dbf.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_dbf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_dbf.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Debug traces for zfcp.
  *
- * Copyright IBM Corp. 2002, 2010
+ * Copyright IBM Corp. 2002, 2013
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -23,6 +23,13 @@ module_param(dbfsize, uint, 0400);
 MODULE_PARM_DESC(dbfsize,
 		 "number of pages for each debug feature area (default 4)");
 
+static u32 dbflevel = 3;
+
+module_param(dbflevel, uint, 0400);
+MODULE_PARM_DESC(dbflevel,
+		 "log level for each debug feature area "
+		 "(default 3, range 0..6)");
+
 static inline unsigned int zfcp_dbf_plen(unsigned int offset)
 {
 	return sizeof(struct zfcp_dbf_pay) + offset - ZFCP_DBF_PAY_MAX_REC;
@@ -447,7 +454,7 @@ static debug_info_t *zfcp_dbf_reg(const
 		return NULL;
 
 	debug_register_view(d, &debug_hex_ascii_view);
-	debug_set_level(d, 3);
+	debug_set_level(d, dbflevel);
 
 	return d;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_def.h linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_def.h
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_def.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_def.h	2013-08-25 20:43:22.000000000 -0400
@@ -86,10 +86,6 @@ struct zfcp_reqlist;
 #define ZFCP_STATUS_PORT_PHYS_OPEN		0x00000001
 #define ZFCP_STATUS_PORT_LINK_TEST		0x00000002
 
-/* logical unit status */
-#define ZFCP_STATUS_LUN_SHARED			0x00000004
-#define ZFCP_STATUS_LUN_READONLY		0x00000008
-
 /* FSF request status (this does not have a common part) */
 #define ZFCP_STATUS_FSFREQ_ERROR		0x00000008
 #define ZFCP_STATUS_FSFREQ_CLEANUP		0x00000010
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_erp.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_erp.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_erp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_erp.c	2013-08-25 20:43:22.000000000 -0400
@@ -102,10 +102,13 @@ static void zfcp_erp_action_dismiss_port
 
 	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE)
 		zfcp_erp_action_dismiss(&port->erp_action);
-	else
-		shost_for_each_device(sdev, port->adapter->scsi_host)
+	else {
+		spin_lock(port->adapter->scsi_host->host_lock);
+		__shost_for_each_device(sdev, port->adapter->scsi_host)
 			if (sdev_to_zfcp(sdev)->port == port)
 				zfcp_erp_action_dismiss_lun(sdev);
+		spin_unlock(port->adapter->scsi_host->host_lock);
+	}
 }
 
 static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
@@ -592,9 +595,11 @@ static void _zfcp_erp_lun_reopen_all(str
 {
 	struct scsi_device *sdev;
 
-	shost_for_each_device(sdev, port->adapter->scsi_host)
+	spin_lock(port->adapter->scsi_host->host_lock);
+	__shost_for_each_device(sdev, port->adapter->scsi_host)
 		if (sdev_to_zfcp(sdev)->port == port)
 			_zfcp_erp_lun_reopen(sdev, clear, id, 0);
+	spin_unlock(port->adapter->scsi_host->host_lock);
 }
 
 static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
@@ -950,8 +955,7 @@ static void zfcp_erp_lun_strategy_clears
 {
 	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
 
-	atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
-			  ZFCP_STATUS_LUN_SHARED | ZFCP_STATUS_LUN_READONLY,
+	atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
 			  &zfcp_sdev->status);
 }
 
@@ -1435,8 +1439,10 @@ void zfcp_erp_set_adapter_status(struct
 		atomic_set_mask(common_mask, &port->status);
 	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 
-	shost_for_each_device(sdev, adapter->scsi_host)
+	spin_lock_irqsave(adapter->scsi_host->host_lock, flags);
+	__shost_for_each_device(sdev, adapter->scsi_host)
 		atomic_set_mask(common_mask, &sdev_to_zfcp(sdev)->status);
+	spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags);
 }
 
 /**
@@ -1470,11 +1476,13 @@ void zfcp_erp_clear_adapter_status(struc
 	}
 	read_unlock_irqrestore(&adapter->port_list_lock, flags);
 
-	shost_for_each_device(sdev, adapter->scsi_host) {
+	spin_lock_irqsave(adapter->scsi_host->host_lock, flags);
+	__shost_for_each_device(sdev, adapter->scsi_host) {
 		atomic_clear_mask(common_mask, &sdev_to_zfcp(sdev)->status);
 		if (clear_counter)
 			atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0);
 	}
+	spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags);
 }
 
 /**
@@ -1488,16 +1496,19 @@ void zfcp_erp_set_port_status(struct zfc
 {
 	struct scsi_device *sdev;
 	u32 common_mask = mask & ZFCP_COMMON_FLAGS;
+	unsigned long flags;
 
 	atomic_set_mask(mask, &port->status);
 
 	if (!common_mask)
 		return;
 
-	shost_for_each_device(sdev, port->adapter->scsi_host)
+	spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags);
+	__shost_for_each_device(sdev, port->adapter->scsi_host)
 		if (sdev_to_zfcp(sdev)->port == port)
 			atomic_set_mask(common_mask,
 					&sdev_to_zfcp(sdev)->status);
+	spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags);
 }
 
 /**
@@ -1512,6 +1523,7 @@ void zfcp_erp_clear_port_status(struct z
 	struct scsi_device *sdev;
 	u32 common_mask = mask & ZFCP_COMMON_FLAGS;
 	u32 clear_counter = mask & ZFCP_STATUS_COMMON_ERP_FAILED;
+	unsigned long flags;
 
 	atomic_clear_mask(mask, &port->status);
 
@@ -1521,13 +1533,15 @@ void zfcp_erp_clear_port_status(struct z
 	if (clear_counter)
 		atomic_set(&port->erp_counter, 0);
 
-	shost_for_each_device(sdev, port->adapter->scsi_host)
+	spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags);
+	__shost_for_each_device(sdev, port->adapter->scsi_host)
 		if (sdev_to_zfcp(sdev)->port == port) {
 			atomic_clear_mask(common_mask,
 					  &sdev_to_zfcp(sdev)->status);
 			if (clear_counter)
 				atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0);
 		}
+	spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags);
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_ext.h linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_ext.h
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_ext.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_ext.h	2013-08-25 20:43:22.000000000 -0400
@@ -21,28 +21,14 @@ extern struct zfcp_port *zfcp_port_enque
 					   u32);
 extern void zfcp_sg_free_table(struct scatterlist *, int);
 extern int zfcp_sg_setup_table(struct scatterlist *, int);
-extern void zfcp_device_unregister(struct device *,
-				   const struct attribute_group *);
 extern void zfcp_adapter_release(struct kref *);
 extern void zfcp_adapter_unregister(struct zfcp_adapter *);
 
 /* zfcp_ccw.c */
-extern int zfcp_ccw_priv_sch(struct zfcp_adapter *);
 extern struct ccw_driver zfcp_ccw_driver;
 extern struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *);
 extern void zfcp_ccw_adapter_put(struct zfcp_adapter *);
 
-/* zfcp_cfdc.c */
-extern struct miscdevice zfcp_cfdc_misc;
-extern void zfcp_cfdc_port_denied(struct zfcp_port *, union fsf_status_qual *);
-extern void zfcp_cfdc_lun_denied(struct scsi_device *, union fsf_status_qual *);
-extern void zfcp_cfdc_lun_shrng_vltn(struct scsi_device *,
-				     union fsf_status_qual *);
-extern int zfcp_cfdc_open_lun_eval(struct scsi_device *,
-				   struct fsf_qtcb_bottom_support *);
-extern void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *);
-
-
 /* zfcp_dbf.c */
 extern int zfcp_dbf_adapter_register(struct zfcp_adapter *);
 extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *);
@@ -117,8 +103,6 @@ extern int zfcp_fsf_exchange_config_data
 extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *);
 extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *,
 					    struct fsf_qtcb_bottom_port *);
-extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *,
-						  struct zfcp_fsf_cfdc *);
 extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
 extern int zfcp_fsf_status_read(struct zfcp_qdio *);
 extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
@@ -158,9 +142,9 @@ extern void zfcp_scsi_set_prot(struct zf
 extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int);
 
 /* zfcp_sysfs.c */
-extern struct attribute_group zfcp_sysfs_unit_attrs;
+extern const struct attribute_group *zfcp_unit_attr_groups[];
 extern struct attribute_group zfcp_sysfs_adapter_attrs;
-extern struct attribute_group zfcp_sysfs_port_attrs;
+extern const struct attribute_group *zfcp_port_attr_groups[];
 extern struct mutex zfcp_sysfs_port_units_mutex;
 extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
 extern struct device_attribute *zfcp_sysfs_shost_attrs[];
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_fc.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_fc.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_fc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_fc.c	2013-08-25 20:43:22.000000000 -0400
@@ -668,7 +668,7 @@ static int zfcp_fc_eval_gpn_ft(struct zf
 
 	list_for_each_entry_safe(port, tmp, &remove_lh, list) {
 		zfcp_erp_port_shutdown(port, 0, "fcegpf2");
-		zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
+		device_unregister(&port->dev);
 	}
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_fsf.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_fsf.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_fsf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_fsf.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Implementation of FSF commands.
  *
- * Copyright IBM Corp. 2002, 2010
+ * Copyright IBM Corp. 2002, 2013
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -254,14 +254,9 @@ static void zfcp_fsf_status_read_handler
 
 		break;
 	case FSF_STATUS_READ_NOTIFICATION_LOST:
-		if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED)
-			zfcp_cfdc_adapter_access_changed(adapter);
 		if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
 			zfcp_fc_conditional_port_scan(adapter);
 		break;
-	case FSF_STATUS_READ_CFDC_UPDATED:
-		zfcp_cfdc_adapter_access_changed(adapter);
-		break;
 	case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
 		adapter->adapter_features = sr_buf->payload.word[0];
 		break;
@@ -483,12 +478,8 @@ static int zfcp_fsf_exchange_config_eval
 
 	fc_host_port_name(shost) = nsp->fl_wwpn;
 	fc_host_node_name(shost) = nsp->fl_wwnn;
-	fc_host_port_id(shost) = ntoh24(bottom->s_id);
-	fc_host_speed(shost) =
-		zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
 	fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
 
-	adapter->hydra_version = bottom->adapter_type;
 	adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK;
 	adapter->stat_read_buf_num = max(bottom->status_read_buf_num,
 					 (u16)FSF_STATUS_READS_RECOM);
@@ -496,6 +487,19 @@ static int zfcp_fsf_exchange_config_eval
 	if (fc_host_permanent_port_name(shost) == -1)
 		fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
 
+	zfcp_scsi_set_prot(adapter);
+
+	/* no error return above here, otherwise must fix call chains */
+	/* do not evaluate invalid fields */
+	if (req->qtcb->header.fsf_status == FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE)
+		return 0;
+
+	fc_host_port_id(shost) = ntoh24(bottom->s_id);
+	fc_host_speed(shost) =
+		zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
+
+	adapter->hydra_version = bottom->adapter_type;
+
 	switch (bottom->fc_topology) {
 	case FSF_TOPO_P2P:
 		adapter->peer_d_id = ntoh24(bottom->peer_d_id);
@@ -517,8 +521,6 @@ static int zfcp_fsf_exchange_config_eval
 		return -EIO;
 	}
 
-	zfcp_scsi_set_prot(adapter);
-
 	return 0;
 }
 
@@ -563,8 +565,14 @@ static void zfcp_fsf_exchange_config_dat
 		fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
 		adapter->hydra_version = 0;
 
+		/* avoids adapter shutdown to be able to recognize
+		 * events such as LINK UP */
+		atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
+				&adapter->status);
 		zfcp_fsf_link_down_info_eval(req,
 			&qtcb->header.fsf_status_qual.link_down_info);
+		if (zfcp_fsf_exchange_config_evaluate(req))
+			return;
 		break;
 	default:
 		zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3");
@@ -931,8 +939,6 @@ static void zfcp_fsf_send_ct_handler(str
 			break;
                 }
                 break;
-	case FSF_ACCESS_DENIED:
-		break;
         case FSF_PORT_BOXED:
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
@@ -1086,7 +1092,6 @@ out:
 static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
 {
 	struct zfcp_fsf_ct_els *send_els = req->data;
-	struct zfcp_port *port = send_els->port;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
 	send_els->status = -EINVAL;
@@ -1116,12 +1121,6 @@ static void zfcp_fsf_send_els_handler(st
 	case FSF_REQUEST_SIZE_TOO_LARGE:
 	case FSF_RESPONSE_SIZE_TOO_LARGE:
 		break;
-	case FSF_ACCESS_DENIED:
-		if (port) {
-			zfcp_cfdc_port_denied(port, &header->fsf_status_qual);
-			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
-		}
-		break;
 	case FSF_SBAL_MISMATCH:
 		/* should never occur, avoided in zfcp_fsf_send_els */
 		/* fall through */
@@ -1209,8 +1208,6 @@ int zfcp_fsf_exchange_config_data(struct
 	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
 
 	req->qtcb->bottom.config.feature_selection =
-			FSF_FEATURE_CFDC |
-			FSF_FEATURE_LUN_SHARING |
 			FSF_FEATURE_NOTIFICATION_LOST |
 			FSF_FEATURE_UPDATE_ALERT;
 	req->erp_action = erp_action;
@@ -1250,8 +1247,6 @@ int zfcp_fsf_exchange_config_data_sync(s
 	req->handler = zfcp_fsf_exchange_config_data_handler;
 
 	req->qtcb->bottom.config.feature_selection =
-			FSF_FEATURE_CFDC |
-			FSF_FEATURE_LUN_SHARING |
 			FSF_FEATURE_NOTIFICATION_LOST |
 			FSF_FEATURE_UPDATE_ALERT;
 
@@ -1378,10 +1373,6 @@ static void zfcp_fsf_open_port_handler(s
 	switch (header->fsf_status) {
 	case FSF_PORT_ALREADY_OPEN:
 		break;
-	case FSF_ACCESS_DENIED:
-		zfcp_cfdc_port_denied(port, &header->fsf_status_qual);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
-		break;
 	case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED:
 		dev_warn(&req->adapter->ccw_device->dev,
 			 "Not enough FCP adapter resources to open "
@@ -1564,8 +1555,6 @@ static void zfcp_fsf_open_wka_port_handl
 		/* fall through */
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
-		/* fall through */
-	case FSF_ACCESS_DENIED:
 		wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE;
 		break;
 	case FSF_GOOD:
@@ -1685,9 +1674,6 @@ static void zfcp_fsf_close_physical_port
 		zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1");
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
-	case FSF_ACCESS_DENIED:
-		zfcp_cfdc_port_denied(port, &header->fsf_status_qual);
-		break;
 	case FSF_PORT_BOXED:
 		/* can't use generic zfcp_erp_modify_port_status because
 		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */
@@ -1773,7 +1759,7 @@ static void zfcp_fsf_open_lun_handler(st
 	struct scsi_device *sdev = req->data;
 	struct zfcp_scsi_dev *zfcp_sdev;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
-	struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support;
+	union fsf_status_qual *qual = &header->fsf_status_qual;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		return;
@@ -1781,9 +1767,7 @@ static void zfcp_fsf_open_lun_handler(st
 	zfcp_sdev = sdev_to_zfcp(sdev);
 
 	atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
-			  ZFCP_STATUS_COMMON_ACCESS_BOXED |
-			  ZFCP_STATUS_LUN_SHARED |
-			  ZFCP_STATUS_LUN_READONLY,
+			  ZFCP_STATUS_COMMON_ACCESS_BOXED,
 			  &zfcp_sdev->status);
 
 	switch (header->fsf_status) {
@@ -1793,10 +1777,6 @@ static void zfcp_fsf_open_lun_handler(st
 		/* fall through */
 	case FSF_LUN_ALREADY_OPEN:
 		break;
-	case FSF_ACCESS_DENIED:
-		zfcp_cfdc_lun_denied(sdev, &header->fsf_status_qual);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
-		break;
 	case FSF_PORT_BOXED:
 		zfcp_erp_set_port_status(zfcp_sdev->port,
 					 ZFCP_STATUS_COMMON_ACCESS_BOXED);
@@ -1805,7 +1785,17 @@ static void zfcp_fsf_open_lun_handler(st
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_LUN_SHARING_VIOLATION:
-		zfcp_cfdc_lun_shrng_vltn(sdev, &header->fsf_status_qual);
+		if (qual->word[0])
+			dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
+				 "LUN 0x%Lx on port 0x%Lx is already in "
+				 "use by CSS%d, MIF Image ID %x\n",
+				 zfcp_scsi_dev_lun(sdev),
+				 (unsigned long long)zfcp_sdev->port->wwpn,
+				 qual->fsf_queue_designator.cssid,
+				 qual->fsf_queue_designator.hla);
+		zfcp_erp_set_lun_status(sdev,
+					ZFCP_STATUS_COMMON_ERP_FAILED |
+					ZFCP_STATUS_COMMON_ACCESS_DENIED);
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED:
@@ -1833,7 +1823,6 @@ static void zfcp_fsf_open_lun_handler(st
 	case FSF_GOOD:
 		zfcp_sdev->lun_handle = header->lun_handle;
 		atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &zfcp_sdev->status);
-		zfcp_cfdc_open_lun_eval(sdev, bottom);
 		break;
 	}
 }
@@ -2061,10 +2050,6 @@ static void zfcp_fsf_fcp_handler_common(
 	case FSF_SERVICE_CLASS_NOT_SUPPORTED:
 		zfcp_fsf_class_not_supp(req);
 		break;
-	case FSF_ACCESS_DENIED:
-		zfcp_cfdc_lun_denied(sdev, &header->fsf_status_qual);
-		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
-		break;
 	case FSF_DIRECTION_INDICATOR_NOT_VALID:
 		dev_err(&req->adapter->ccw_device->dev,
 			"Incorrect direction %d, LUN 0x%016Lx on port "
@@ -2365,79 +2350,6 @@ out:
 	return req;
 }
 
-static void zfcp_fsf_control_file_handler(struct zfcp_fsf_req *req)
-{
-}
-
-/**
- * zfcp_fsf_control_file - control file upload/download
- * @adapter: pointer to struct zfcp_adapter
- * @fsf_cfdc: pointer to struct zfcp_fsf_cfdc
- * Returns: on success pointer to struct zfcp_fsf_req, NULL otherwise
- */
-struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
-					   struct zfcp_fsf_cfdc *fsf_cfdc)
-{
-	struct zfcp_qdio *qdio = adapter->qdio;
-	struct zfcp_fsf_req *req = NULL;
-	struct fsf_qtcb_bottom_support *bottom;
-	int retval = -EIO;
-	u8 direction;
-
-	if (!(adapter->adapter_features & FSF_FEATURE_CFDC))
-		return ERR_PTR(-EOPNOTSUPP);
-
-	switch (fsf_cfdc->command) {
-	case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
-		direction = SBAL_SFLAGS0_TYPE_WRITE;
-		break;
-	case FSF_QTCB_UPLOAD_CONTROL_FILE:
-		direction = SBAL_SFLAGS0_TYPE_READ;
-		break;
-	default:
-		return ERR_PTR(-EINVAL);
-	}
-
-	spin_lock_irq(&qdio->req_q_lock);
-	if (zfcp_qdio_sbal_get(qdio))
-		goto out;
-
-	req = zfcp_fsf_req_create(qdio, fsf_cfdc->command, direction, NULL);
-	if (IS_ERR(req)) {
-		retval = -EPERM;
-		goto out;
-	}
-
-	req->handler = zfcp_fsf_control_file_handler;
-
-	bottom = &req->qtcb->bottom.support;
-	bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE;
-	bottom->option = fsf_cfdc->option;
-
-	retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, fsf_cfdc->sg);
-
-	if (retval ||
-		(zfcp_qdio_real_bytes(fsf_cfdc->sg) != ZFCP_CFDC_MAX_SIZE)) {
-		zfcp_fsf_req_free(req);
-		retval = -EIO;
-		goto out;
-	}
-	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
-	if (zfcp_adapter_multi_buffer_active(adapter))
-		zfcp_qdio_set_scount(qdio, &req->qdio_req);
-
-	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
-	retval = zfcp_fsf_req_send(req);
-out:
-	spin_unlock_irq(&qdio->req_q_lock);
-
-	if (!retval) {
-		wait_for_completion(&req->completion);
-		return req;
-	}
-	return ERR_PTR(retval);
-}
-
 /**
  * zfcp_fsf_reqid_check - validate req_id contained in SBAL returned by QDIO
  * @adapter: pointer to struct zfcp_adapter
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_fsf.h linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_fsf.h
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_fsf.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_fsf.h	2013-08-25 20:43:22.000000000 -0400
@@ -36,13 +36,6 @@
 #define FSF_CONFIG_COMMAND			0x00000003
 #define FSF_PORT_COMMAND			0x00000004
 
-/* FSF control file upload/download operations' subtype and options */
-#define FSF_CFDC_OPERATION_SUBTYPE		0x00020001
-#define FSF_CFDC_OPTION_NORMAL_MODE		0x00000000
-#define FSF_CFDC_OPTION_FORCE			0x00000001
-#define FSF_CFDC_OPTION_FULL_ACCESS		0x00000002
-#define FSF_CFDC_OPTION_RESTRICTED_ACCESS	0x00000004
-
 /* FSF protocol states */
 #define FSF_PROT_GOOD				0x00000001
 #define FSF_PROT_QTCB_VERSION_ERROR		0x00000010
@@ -64,7 +57,6 @@
 #define FSF_HANDLE_MISMATCH			0x00000005
 #define FSF_SERVICE_CLASS_NOT_SUPPORTED		0x00000006
 #define FSF_FCPLUN_NOT_VALID			0x00000009
-#define FSF_ACCESS_DENIED			0x00000010
 #define FSF_LUN_SHARING_VIOLATION               0x00000012
 #define FSF_FCP_COMMAND_DOES_NOT_EXIST		0x00000022
 #define FSF_DIRECTION_INDICATOR_NOT_VALID	0x00000030
@@ -130,7 +122,6 @@
 #define FSF_STATUS_READ_LINK_DOWN		0x00000005
 #define FSF_STATUS_READ_LINK_UP          	0x00000006
 #define FSF_STATUS_READ_NOTIFICATION_LOST	0x00000009
-#define FSF_STATUS_READ_CFDC_UPDATED		0x0000000A
 #define FSF_STATUS_READ_FEATURE_UPDATE_ALERT	0x0000000C
 
 /* status subtypes for link down */
@@ -140,7 +131,6 @@
 
 /* status subtypes for unsolicited status notification lost */
 #define FSF_STATUS_READ_SUB_INCOMING_ELS	0x00000001
-#define FSF_STATUS_READ_SUB_ACT_UPDATED		0x00000020
 
 /* topologie that is detected by the adapter */
 #define FSF_TOPO_P2P				0x00000001
@@ -166,8 +156,6 @@
 #define FSF_QTCB_LOG_SIZE			1024
 
 /* channel features */
-#define FSF_FEATURE_CFDC			0x00000002
-#define FSF_FEATURE_LUN_SHARING			0x00000004
 #define FSF_FEATURE_NOTIFICATION_LOST		0x00000008
 #define FSF_FEATURE_HBAAPI_MANAGEMENT           0x00000010
 #define FSF_FEATURE_ELS_CT_CHAINED_SBALS	0x00000020
@@ -182,20 +170,6 @@
 /* option */
 #define FSF_OPEN_LUN_SUPPRESS_BOXING		0x00000001
 
-/* open LUN access flags*/
-#define FSF_UNIT_ACCESS_EXCLUSIVE		0x02000000
-#define FSF_UNIT_ACCESS_OUTBOUND_TRANSFER	0x10000000
-
-/* FSF interface for CFDC */
-#define ZFCP_CFDC_MAX_SIZE		127 * 1024
-#define ZFCP_CFDC_PAGES 		PFN_UP(ZFCP_CFDC_MAX_SIZE)
-
-struct zfcp_fsf_cfdc {
-	struct scatterlist sg[ZFCP_CFDC_PAGES];
-	u32 command;
-	u32 option;
-};
-
 struct fsf_queue_designator {
 	u8  cssid;
 	u8  chpid;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_qdio.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_qdio.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_qdio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_qdio.c	2013-08-25 20:43:22.000000000 -0400
@@ -224,11 +224,9 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_
 
 static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio)
 {
-	spin_lock_irq(&qdio->req_q_lock);
 	if (atomic_read(&qdio->req_q_free) ||
 	    !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
 		return 1;
-	spin_unlock_irq(&qdio->req_q_lock);
 	return 0;
 }
 
@@ -246,9 +244,8 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio
 {
 	long ret;
 
-	spin_unlock_irq(&qdio->req_q_lock);
-	ret = wait_event_interruptible_timeout(qdio->req_q_wq,
-			       zfcp_qdio_sbal_check(qdio), 5 * HZ);
+	ret = wait_event_interruptible_lock_irq_timeout(qdio->req_q_wq,
+		       zfcp_qdio_sbal_check(qdio), qdio->req_q_lock, 5 * HZ);
 
 	if (!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
 		return -EIO;
@@ -262,7 +259,6 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio
 		zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1");
 	}
 
-	spin_lock_irq(&qdio->req_q_lock);
 	return -EIO;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_scsi.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_scsi.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_scsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_scsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * Interface to Linux SCSI midlayer.
  *
- * Copyright IBM Corp. 2002, 2010
+ * Copyright IBM Corp. 2002, 2013
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -311,8 +311,12 @@ static struct scsi_host_template zfcp_sc
 	.proc_name		 = "zfcp",
 	.can_queue		 = 4096,
 	.this_id		 = -1,
-	.sg_tablesize		 = 1, /* adjusted later */
-	.max_sectors		 = 8, /* adjusted later */
+	.sg_tablesize		 = (((QDIO_MAX_ELEMENTS_PER_BUFFER - 1)
+				     * ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2),
+				   /* GCD, adjusted later */
+	.max_sectors		 = (((QDIO_MAX_ELEMENTS_PER_BUFFER - 1)
+				     * ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2) * 8,
+				   /* GCD, adjusted later */
 	.dma_boundary		 = ZFCP_QDIO_SBALE_LEN - 1,
 	.cmd_per_lun		 = 1,
 	.use_clustering		 = 1,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_sysfs.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_sysfs.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,16 @@ static ssize_t zfcp_sysfs_##_feat##_##_n
 static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO,				       \
 		     zfcp_sysfs_##_feat##_##_name##_show, NULL);
 
+#define ZFCP_DEFINE_ATTR_CONST(_feat, _name, _format, _value)		       \
+static ssize_t zfcp_sysfs_##_feat##_##_name##_show(struct device *dev,	       \
+						   struct device_attribute *at,\
+						   char *buf)		       \
+{									       \
+	return sprintf(buf, _format, _value);				       \
+}									       \
+static ZFCP_DEV_ATTR(_feat, _name, S_IRUGO,				       \
+		     zfcp_sysfs_##_feat##_##_name##_show, NULL);
+
 #define ZFCP_DEFINE_A_ATTR(_name, _format, _value)			     \
 static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev,	     \
 						 struct device_attribute *at,\
@@ -75,12 +85,8 @@ ZFCP_DEFINE_ATTR(zfcp_unit, unit, in_rec
 ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_denied, "%d\n",
 		 (zfcp_unit_sdev_status(unit) &
 		  ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0);
-ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_shared, "%d\n",
-		 (zfcp_unit_sdev_status(unit) &
-		  ZFCP_STATUS_LUN_SHARED) != 0);
-ZFCP_DEFINE_ATTR(zfcp_unit, unit, access_readonly, "%d\n",
-		 (zfcp_unit_sdev_status(unit) &
-		  ZFCP_STATUS_LUN_READONLY) != 0);
+ZFCP_DEFINE_ATTR_CONST(unit, access_shared, "%d\n", 0);
+ZFCP_DEFINE_ATTR_CONST(unit, access_readonly, "%d\n", 0);
 
 static ssize_t zfcp_sysfs_port_failed_show(struct device *dev,
 					   struct device_attribute *attr,
@@ -268,7 +274,7 @@ static ssize_t zfcp_sysfs_port_remove_st
 	put_device(&port->dev);
 
 	zfcp_erp_port_shutdown(port, 0, "syprs_1");
-	zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs);
+	device_unregister(&port->dev);
  out:
 	zfcp_ccw_adapter_put(adapter);
 	return retval ? retval : (ssize_t) count;
@@ -340,13 +346,13 @@ static struct attribute *zfcp_port_attrs
 	&dev_attr_port_access_denied.attr,
 	NULL
 };
-
-/**
- * zfcp_sysfs_port_attrs - sysfs attributes for all other ports
- */
-struct attribute_group zfcp_sysfs_port_attrs = {
+static struct attribute_group zfcp_port_attr_group = {
 	.attrs = zfcp_port_attrs,
 };
+const struct attribute_group *zfcp_port_attr_groups[] = {
+	&zfcp_port_attr_group,
+	NULL,
+};
 
 static struct attribute *zfcp_unit_attrs[] = {
 	&dev_attr_unit_failed.attr,
@@ -357,10 +363,13 @@ static struct attribute *zfcp_unit_attrs
 	&dev_attr_unit_access_readonly.attr,
 	NULL
 };
-
-struct attribute_group zfcp_sysfs_unit_attrs = {
+static struct attribute_group zfcp_unit_attr_group = {
 	.attrs = zfcp_unit_attrs,
 };
+const struct attribute_group *zfcp_unit_attr_groups[] = {
+	&zfcp_unit_attr_group,
+	NULL,
+};
 
 #define ZFCP_DEFINE_LATENCY_ATTR(_name) 				\
 static ssize_t								\
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_unit.c linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_unit.c
--- linux-libre-3.10-gnu/drivers/s390/scsi/zfcp_unit.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/s390/scsi/zfcp_unit.c	2013-08-25 20:43:22.000000000 -0400
@@ -145,6 +145,7 @@ int zfcp_unit_add(struct zfcp_port *port
 	unit->fcp_lun = fcp_lun;
 	unit->dev.parent = &port->dev;
 	unit->dev.release = zfcp_unit_release;
+	unit->dev.groups = zfcp_unit_attr_groups;
 	INIT_WORK(&unit->scsi_work, zfcp_unit_scsi_scan_work);
 
 	if (dev_set_name(&unit->dev, "0x%016llx",
@@ -160,12 +161,6 @@ int zfcp_unit_add(struct zfcp_port *port
 		goto out;
 	}
 
-	if (sysfs_create_group(&unit->dev.kobj, &zfcp_sysfs_unit_attrs)) {
-		device_unregister(&unit->dev);
-		retval = -EINVAL;
-		goto out;
-	}
-
 	atomic_inc(&port->units); /* under zfcp_sysfs_port_units_mutex ! */
 
 	write_lock_irq(&port->unit_list_lock);
@@ -254,7 +249,7 @@ int zfcp_unit_remove(struct zfcp_port *p
 
 	put_device(&unit->dev);
 
-	zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs);
+	device_unregister(&unit->dev);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/3w-xxxx.c linux-libre-3.11-rc7-gnu/drivers/scsi/3w-xxxx.c
--- linux-libre-3.10-gnu/drivers/scsi/3w-xxxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/3w-xxxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -216,6 +216,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_eh.h>
 #include "3w-xxxx.h"
 
 /* Globals */
@@ -2009,7 +2010,8 @@ static int tw_scsi_queue_lck(struct scsi
 			printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
 			tw_dev->state[request_id] = TW_S_COMPLETED;
 			tw_state_request_finish(tw_dev, request_id);
-			SCpnt->result = (DID_BAD_TARGET << 16);
+			SCpnt->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
+			scsi_build_sense_buffer(1, SCpnt->sense_buffer, ILLEGAL_REQUEST, 0x20, 0);
 			done(SCpnt);
 			retval = 0;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/a3000.c linux-libre-3.11-rc7-gnu/drivers/scsi/a3000.c
--- linux-libre-3.10-gnu/drivers/scsi/a3000.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/a3000.c	2013-08-25 20:43:22.000000000 -0400
@@ -280,18 +280,7 @@ static struct platform_driver amiga_a300
 	},
 };
 
-static int __init amiga_a3000_scsi_init(void)
-{
-	return platform_driver_probe(&amiga_a3000_scsi_driver,
-				     amiga_a3000_scsi_probe);
-}
-module_init(amiga_a3000_scsi_init);
-
-static void __exit amiga_a3000_scsi_exit(void)
-{
-	platform_driver_unregister(&amiga_a3000_scsi_driver);
-}
-module_exit(amiga_a3000_scsi_exit);
+module_platform_driver_probe(amiga_a3000_scsi_driver, amiga_a3000_scsi_probe);
 
 MODULE_DESCRIPTION("Amiga 3000 built-in SCSI");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/a4000t.c linux-libre-3.11-rc7-gnu/drivers/scsi/a4000t.c
--- linux-libre-3.10-gnu/drivers/scsi/a4000t.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/a4000t.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,20 +116,7 @@ static struct platform_driver amiga_a400
 	},
 };
 
-static int __init amiga_a4000t_scsi_init(void)
-{
-	return platform_driver_probe(&amiga_a4000t_scsi_driver,
-				     amiga_a4000t_scsi_probe);
-}
-
-module_init(amiga_a4000t_scsi_init);
-
-static void __exit amiga_a4000t_scsi_exit(void)
-{
-	platform_driver_unregister(&amiga_a4000t_scsi_driver);
-}
-
-module_exit(amiga_a4000t_scsi_exit);
+module_platform_driver_probe(amiga_a4000t_scsi_driver, amiga_a4000t_scsi_probe);
 
 MODULE_AUTHOR("Alan Hourihane <alanh@fairlite.demon.co.uk> / "
 	      "Kars de Jong <jongk@linux-m68k.org>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/aacraid/commctrl.c linux-libre-3.11-rc7-gnu/drivers/scsi/aacraid/commctrl.c
--- linux-libre-3.10-gnu/drivers/scsi/aacraid/commctrl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/aacraid/commctrl.c	2013-08-25 20:43:22.000000000 -0400
@@ -318,7 +318,8 @@ return_fib:
 			kthread_stop(dev->thread);
 			ssleep(1);
 			dev->aif_thread = 0;
-			dev->thread = kthread_run(aac_command_thread, dev, dev->name);
+			dev->thread = kthread_run(aac_command_thread, dev,
+						  "%s", dev->name);
 			ssleep(1);
 		}
 		if (f.wait) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/aacraid/commsup.c linux-libre-3.11-rc7-gnu/drivers/scsi/aacraid/commsup.c
--- linux-libre-3.10-gnu/drivers/scsi/aacraid/commsup.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/aacraid/commsup.c	2013-08-25 20:43:22.000000000 -0400
@@ -1336,7 +1336,8 @@ static int _aac_reset_adapter(struct aac
 		if ((retval = pci_set_dma_mask(aac->pdev, DMA_BIT_MASK(32))))
 			goto out;
 	if (jafo) {
-		aac->thread = kthread_run(aac_command_thread, aac, aac->name);
+		aac->thread = kthread_run(aac_command_thread, aac, "%s",
+					  aac->name);
 		if (IS_ERR(aac->thread)) {
 			retval = PTR_ERR(aac->thread);
 			goto out;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/aacraid/src.c linux-libre-3.11-rc7-gnu/drivers/scsi/aacraid/src.c
--- linux-libre-3.10-gnu/drivers/scsi/aacraid/src.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/aacraid/src.c	2013-08-25 20:43:22.000000000 -0400
@@ -93,6 +93,9 @@ static irqreturn_t aac_src_intr_message(
 			int send_it = 0;
 			extern int aac_sync_mode;
 
+			src_writel(dev, MUnit.ODR_C, bellbits);
+			src_readl(dev, MUnit.ODR_C);
+
 			if (!aac_sync_mode) {
 				src_writel(dev, MUnit.ODR_C, bellbits);
 				src_readl(dev, MUnit.ODR_C);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/aic7xxx_old/aic7xxx.seq linux-libre-3.11-rc7-gnu/drivers/scsi/aic7xxx_old/aic7xxx.seq
--- linux-libre-3.10-gnu/drivers/scsi/aic7xxx_old/aic7xxx.seq	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/aic7xxx_old/aic7xxx.seq	2013-08-25 20:43:22.000000000 -0400
@@ -693,7 +693,7 @@ p_status:
  * it's own message.
  * 
  * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message.
- * This is done to allow the hsot to send messages outside of an identify
+ * This is done to allow the host to send messages outside of an identify
  * sequence while protecting the seqencer from testing the MK_MESSAGE bit
  * on an SCB that might not be for the current nexus. (For example, a
  * BDR message in response to a bad reselection would leave us pointed to
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/aic94xx/aic94xx_task.c linux-libre-3.11-rc7-gnu/drivers/scsi/aic94xx/aic94xx_task.c
--- linux-libre-3.10-gnu/drivers/scsi/aic94xx/aic94xx_task.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/aic94xx/aic94xx_task.c	2013-08-25 20:43:22.000000000 -0400
@@ -505,7 +505,8 @@ static int asd_build_ssp_ascb(struct asd
 		scb->ssp_task.ssp_cmd.efb_prio_attr |= EFB_MASK;
 	scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_prio << 3);
 	scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_attr & 7);
-	memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cdb, 16);
+	memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cmd->cmnd,
+	       task->ssp_task.cmd->cmd_len);
 
 	scb->ssp_task.sister_scb = cpu_to_le16(0xFFFF);
 	scb->ssp_task.conn_handle = cpu_to_le16(
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/be2iscsi/be_main.c linux-libre-3.11-rc7-gnu/drivers/scsi/be2iscsi/be_main.c
--- linux-libre-3.10-gnu/drivers/scsi/be2iscsi/be_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/be2iscsi/be_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -4996,7 +4996,7 @@ static int beiscsi_dev_probe(struct pci_
 
 	snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_%02x_wq",
 		 phba->shost->host_no);
-	phba->wq = alloc_workqueue(phba->wq_name, WQ_MEM_RECLAIM, 1);
+	phba->wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 1, phba->wq_name);
 	if (!phba->wq) {
 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
 			    "BM_%d : beiscsi_dev_probe-"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_core.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_core.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -1432,6 +1432,7 @@ bfa_iocfc_disable_cbfn(void *bfa_arg)
 {
 	struct bfa_s	*bfa = bfa_arg;
 
+	bfa->queue_process = BFA_FALSE;
 	bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_DISABLED);
 }
 
@@ -1567,7 +1568,6 @@ bfa_iocfc_start(struct bfa_s *bfa)
 void
 bfa_iocfc_stop(struct bfa_s *bfa)
 {
-	bfa->queue_process = BFA_FALSE;
 	bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_STOP);
 }
 
@@ -1674,7 +1674,6 @@ bfa_iocfc_disable(struct bfa_s *bfa)
 	bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
 		     "IOC Disable");
 
-	bfa->queue_process = BFA_FALSE;
 	bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DISABLE);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_attr.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_attr.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_attr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_attr.c	2013-08-25 20:43:22.000000000 -0400
@@ -335,23 +335,10 @@ bfad_im_reset_stats(struct Scsi_Host *sh
 }
 
 /*
- * FC transport template entry, get rport loss timeout.
- */
-static void
-bfad_im_get_rport_loss_tmo(struct fc_rport *rport)
-{
-	struct bfad_itnim_data_s *itnim_data = rport->dd_data;
-	struct bfad_itnim_s   *itnim = itnim_data->itnim;
-	struct bfad_s         *bfad = itnim->im->bfad;
-	unsigned long   flags;
-
-	spin_lock_irqsave(&bfad->bfad_lock, flags);
-	rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa);
-	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
-}
-
-/*
  * FC transport template entry, set rport loss timeout.
+ * Update dev_loss_tmo based on the value pushed down by the stack
+ * In case it is lesser than path_tov of driver, set it to path_tov + 1
+ * to ensure that the driver times out before the application
  */
 static void
 bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
@@ -359,15 +346,11 @@ bfad_im_set_rport_loss_tmo(struct fc_rpo
 	struct bfad_itnim_data_s *itnim_data = rport->dd_data;
 	struct bfad_itnim_s   *itnim = itnim_data->itnim;
 	struct bfad_s         *bfad = itnim->im->bfad;
-	unsigned long   flags;
-
-	if (timeout > 0) {
-		spin_lock_irqsave(&bfad->bfad_lock, flags);
-		bfa_fcpim_path_tov_set(&bfad->bfa, timeout);
-		rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa);
-		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
-	}
+	uint16_t path_tov = bfa_fcpim_path_tov_get(&bfad->bfa);
 
+	rport->dev_loss_tmo = timeout;
+	if (timeout < path_tov)
+		rport->dev_loss_tmo = path_tov + 1;
 }
 
 static int
@@ -665,7 +648,6 @@ struct fc_function_template bfad_im_fc_f
 	.show_rport_maxframe_size = 1,
 	.show_rport_supported_classes = 1,
 	.show_rport_dev_loss_tmo = 1,
-	.get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo,
 	.set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
 	.issue_fc_host_lip = bfad_im_issue_fc_host_lip,
 	.vport_create = bfad_im_vport_create,
@@ -723,7 +705,6 @@ struct fc_function_template bfad_im_vpor
 	.show_rport_maxframe_size = 1,
 	.show_rport_supported_classes = 1,
 	.show_rport_dev_loss_tmo = 1,
-	.get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo,
 	.set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_bsg.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_bsg.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_bsg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_bsg.c	2013-08-25 20:43:22.000000000 -0400
@@ -402,25 +402,43 @@ bfad_iocmd_port_cfg_maxfrsize(struct bfa
 }
 
 int
-bfad_iocmd_port_cfg_bbsc(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
+bfad_iocmd_port_cfg_bbcr(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
 {
-	struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
-	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
-	unsigned long	flags;
+	struct bfa_bsg_bbcr_enable_s *iocmd =
+			(struct bfa_bsg_bbcr_enable_s *)pcmd;
+	unsigned long flags;
+	int rc;
 
 	spin_lock_irqsave(&bfad->bfad_lock, flags);
-	if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) {
-		if (v_cmd == IOCMD_PORT_BBSC_ENABLE)
-			fcport->cfg.bb_scn_state = BFA_TRUE;
-		else if (v_cmd == IOCMD_PORT_BBSC_DISABLE)
-			fcport->cfg.bb_scn_state = BFA_FALSE;
+	if (cmd == IOCMD_PORT_BBCR_ENABLE)
+		rc = bfa_fcport_cfg_bbcr(&bfad->bfa, BFA_TRUE, iocmd->bb_scn);
+	else if (cmd == IOCMD_PORT_BBCR_DISABLE)
+		rc = bfa_fcport_cfg_bbcr(&bfad->bfa, BFA_FALSE, 0);
+	else {
+		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+		return -EINVAL;
 	}
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
-	iocmd->status = BFA_STATUS_OK;
+	iocmd->status = rc;
 	return 0;
 }
 
+int
+bfad_iocmd_port_get_bbcr_attr(struct bfad_s *bfad, void *pcmd)
+{
+	struct bfa_bsg_bbcr_attr_s *iocmd = (struct bfa_bsg_bbcr_attr_s *) pcmd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	iocmd->status =
+		bfa_fcport_get_bbcr_attr(&bfad->bfa, &iocmd->attr);
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+	return 0;
+}
+
+
 static int
 bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd)
 {
@@ -1767,51 +1785,87 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *b
 }
 
 int
-bfad_iocmd_diag_cfg_dport(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
+bfad_iocmd_diag_dport_enable(struct bfad_s *bfad, void *pcmd)
 {
-	struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
+	struct bfa_bsg_dport_enable_s *iocmd =
+				(struct bfa_bsg_dport_enable_s *)pcmd;
 	unsigned long	flags;
 	struct bfad_hal_comp fcomp;
 
 	init_completion(&fcomp.comp);
 	spin_lock_irqsave(&bfad->bfad_lock, flags);
-	if (cmd == IOCMD_DIAG_DPORT_ENABLE)
-		iocmd->status = bfa_dport_enable(&bfad->bfa,
-					bfad_hcb_comp, &fcomp);
-	else if (cmd == IOCMD_DIAG_DPORT_DISABLE)
-		iocmd->status = bfa_dport_disable(&bfad->bfa,
-					bfad_hcb_comp, &fcomp);
+	iocmd->status = bfa_dport_enable(&bfad->bfa, iocmd->lpcnt,
+					iocmd->pat, bfad_hcb_comp, &fcomp);
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+	if (iocmd->status != BFA_STATUS_OK)
+		bfa_trc(bfad, iocmd->status);
 	else {
-		bfa_trc(bfad, 0);
-		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
-		return -EINVAL;
+		wait_for_completion(&fcomp.comp);
+		iocmd->status = fcomp.status;
 	}
-	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+	return 0;
+}
+
+int
+bfad_iocmd_diag_dport_disable(struct bfad_s *bfad, void *pcmd)
+{
+	struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
+	unsigned long	flags;
+	struct bfad_hal_comp fcomp;
 
+	init_completion(&fcomp.comp);
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	iocmd->status = bfa_dport_disable(&bfad->bfa, bfad_hcb_comp, &fcomp);
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 	if (iocmd->status != BFA_STATUS_OK)
 		bfa_trc(bfad, iocmd->status);
 	else {
 		wait_for_completion(&fcomp.comp);
 		iocmd->status = fcomp.status;
 	}
+	return 0;
+}
+
+int
+bfad_iocmd_diag_dport_start(struct bfad_s *bfad, void *pcmd)
+{
+	struct bfa_bsg_dport_enable_s *iocmd =
+				(struct bfa_bsg_dport_enable_s *)pcmd;
+	unsigned long   flags;
+	struct bfad_hal_comp fcomp;
+
+	init_completion(&fcomp.comp);
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	iocmd->status = bfa_dport_start(&bfad->bfa, iocmd->lpcnt,
+					iocmd->pat, bfad_hcb_comp,
+					&fcomp);
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+
+	if (iocmd->status != BFA_STATUS_OK) {
+		bfa_trc(bfad, iocmd->status);
+	} else {
+		wait_for_completion(&fcomp.comp);
+		iocmd->status = fcomp.status;
+	}
 
 	return 0;
 }
 
 int
-bfad_iocmd_diag_dport_get_state(struct bfad_s *bfad, void *pcmd)
+bfad_iocmd_diag_dport_show(struct bfad_s *bfad, void *pcmd)
 {
-	struct bfa_bsg_diag_dport_get_state_s *iocmd =
-			(struct bfa_bsg_diag_dport_get_state_s *)pcmd;
-	unsigned long	flags;
+	struct bfa_bsg_diag_dport_show_s *iocmd =
+				(struct bfa_bsg_diag_dport_show_s *)pcmd;
+	unsigned long   flags;
 
 	spin_lock_irqsave(&bfad->bfad_lock, flags);
-	iocmd->status = bfa_dport_get_state(&bfad->bfa, &iocmd->state);
+	iocmd->status = bfa_dport_show(&bfad->bfa, &iocmd->result);
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
 	return 0;
 }
 
+
 int
 bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd)
 {
@@ -2662,7 +2716,7 @@ bfad_iocmd_fruvpd_update(struct bfad_s *
 	spin_lock_irqsave(&bfad->bfad_lock, flags);
 	iocmd->status = bfa_fruvpd_update(BFA_FRU(&bfad->bfa),
 				&iocmd->data, iocmd->len, iocmd->offset,
-				bfad_hcb_comp, &fcomp);
+				bfad_hcb_comp, &fcomp, iocmd->trfr_cmpl);
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 	if (iocmd->status == BFA_STATUS_OK) {
 		wait_for_completion(&fcomp.comp);
@@ -2750,9 +2804,12 @@ bfad_iocmd_handler(struct bfad_s *bfad,
 	case IOCMD_PORT_CFG_MAXFRSZ:
 		rc = bfad_iocmd_port_cfg_maxfrsize(bfad, iocmd);
 		break;
-	case IOCMD_PORT_BBSC_ENABLE:
-	case IOCMD_PORT_BBSC_DISABLE:
-		rc = bfad_iocmd_port_cfg_bbsc(bfad, iocmd, cmd);
+	case IOCMD_PORT_BBCR_ENABLE:
+	case IOCMD_PORT_BBCR_DISABLE:
+		rc = bfad_iocmd_port_cfg_bbcr(bfad, cmd, iocmd);
+		break;
+	case IOCMD_PORT_BBCR_GET_ATTR:
+		rc = bfad_iocmd_port_get_bbcr_attr(bfad, iocmd);
 		break;
 	case IOCMD_LPORT_GET_ATTR:
 		rc = bfad_iocmd_lport_get_attr(bfad, iocmd);
@@ -2913,11 +2970,16 @@ bfad_iocmd_handler(struct bfad_s *bfad,
 		rc = bfad_iocmd_diag_lb_stat(bfad, iocmd);
 		break;
 	case IOCMD_DIAG_DPORT_ENABLE:
+		rc = bfad_iocmd_diag_dport_enable(bfad, iocmd);
+		break;
 	case IOCMD_DIAG_DPORT_DISABLE:
-		rc = bfad_iocmd_diag_cfg_dport(bfad, cmd, iocmd);
+		rc = bfad_iocmd_diag_dport_disable(bfad, iocmd);
 		break;
-	case IOCMD_DIAG_DPORT_GET_STATE:
-		rc = bfad_iocmd_diag_dport_get_state(bfad, iocmd);
+	case IOCMD_DIAG_DPORT_SHOW:
+		rc = bfad_iocmd_diag_dport_show(bfad, iocmd);
+		break;
+	case IOCMD_DIAG_DPORT_START:
+		rc = bfad_iocmd_diag_dport_start(bfad, iocmd);
 		break;
 	case IOCMD_PHY_GET_ATTR:
 		rc = bfad_iocmd_phy_get_attr(bfad, iocmd);
@@ -3309,7 +3371,8 @@ bfad_im_bsg_els_ct_request(struct fc_bsg
 		goto out;
 	}
 
-	if (copy_from_user((uint8_t *)bsg_fcpt, bsg_data->payload,
+	if (copy_from_user((uint8_t *)bsg_fcpt,
+				(void *)(unsigned long)bsg_data->payload,
 				bsg_data->payload_len)) {
 		kfree(bsg_fcpt);
 		rc = -EIO;
@@ -3463,8 +3526,8 @@ out_free_mem:
 	kfree(rsp_kbuf);
 
 	/* Need a copy to user op */
-	if (copy_to_user(bsg_data->payload, (void *) bsg_fcpt,
-			 bsg_data->payload_len))
+	if (copy_to_user((void *)(unsigned long)bsg_data->payload,
+			(void *)bsg_fcpt, bsg_data->payload_len))
 		rc = -EIO;
 
 	kfree(bsg_fcpt);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_bsg.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_bsg.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_bsg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_bsg.h	2013-08-25 20:43:22.000000000 -0400
@@ -46,8 +46,9 @@ enum {
 	IOCMD_PORT_CFG_ALPA,
 	IOCMD_PORT_CFG_MAXFRSZ,
 	IOCMD_PORT_CLR_ALPA,
-	IOCMD_PORT_BBSC_ENABLE,
-	IOCMD_PORT_BBSC_DISABLE,
+	IOCMD_PORT_BBCR_ENABLE,
+	IOCMD_PORT_BBCR_DISABLE,
+	IOCMD_PORT_BBCR_GET_ATTR,
 	IOCMD_LPORT_GET_ATTR,
 	IOCMD_LPORT_GET_RPORTS,
 	IOCMD_LPORT_GET_STATS,
@@ -143,7 +144,6 @@ enum {
 	IOCMD_FCPIM_LUNMASK_DELETE,
 	IOCMD_DIAG_DPORT_ENABLE,
 	IOCMD_DIAG_DPORT_DISABLE,
-	IOCMD_DIAG_DPORT_GET_STATE,
 	IOCMD_QOS_SET_BW,
 	IOCMD_FCPIM_THROTTLE_QUERY,
 	IOCMD_FCPIM_THROTTLE_SET,
@@ -152,6 +152,8 @@ enum {
 	IOCMD_FRUVPD_READ,
 	IOCMD_FRUVPD_UPDATE,
 	IOCMD_FRUVPD_GET_MAX_SIZE,
+	IOCMD_DIAG_DPORT_SHOW,
+	IOCMD_DIAG_DPORT_START,
 };
 
 struct bfa_bsg_gen_s {
@@ -495,6 +497,20 @@ struct bfa_bsg_port_cfg_mode_s {
 	struct bfa_port_cfg_mode_s cfg;
 };
 
+struct bfa_bsg_bbcr_enable_s {
+	bfa_status_t    status;
+	u16		bfad_num;
+	u8		bb_scn;
+	u8		rsvd;
+};
+
+struct bfa_bsg_bbcr_attr_s {
+	bfa_status_t    status;
+	u16		bfad_num;
+	u16		rsvd;
+	struct bfa_bbcr_attr_s attr;
+};
+
 struct bfa_bsg_faa_attr_s {
 	bfa_status_t		status;
 	u16			bfad_num;
@@ -578,6 +594,21 @@ struct bfa_bsg_diag_loopback_s {
 	struct bfa_diag_loopback_result_s result;
 };
 
+struct bfa_bsg_diag_dport_show_s {
+	bfa_status_t	status;
+	u16		bfad_num;
+	u16		rsvd;
+	struct bfa_diag_dport_result_s result;
+};
+
+struct bfa_bsg_dport_enable_s {
+	bfa_status_t	status;
+	u16		bfad_num;
+	u16		rsvd;
+	u16		lpcnt;
+	u16		pat;
+};
+
 struct bfa_bsg_diag_fwping_s {
 	bfa_status_t	status;
 	u16		bfad_num;
@@ -625,13 +656,6 @@ struct bfa_bsg_diag_lb_stat_s {
 	u16		rsvd;
 };
 
-struct bfa_bsg_diag_dport_get_state_s {
-	bfa_status_t	status;
-	u16		bfad_num;
-	u16		rsvd;
-	enum bfa_dport_state state;
-};
-
 struct bfa_bsg_phy_attr_s {
 	bfa_status_t	status;
 	u16	bfad_num;
@@ -770,10 +794,12 @@ struct bfa_bsg_tfru_s {
 struct bfa_bsg_fruvpd_s {
 	bfa_status_t	status;
 	u16		bfad_num;
-	u16		rsvd;
+	u16		rsvd1;
 	u32		offset;
 	u32		len;
 	u8		data[BFA_MAX_FRUVPD_TRANSFER_SIZE];
+	u8		trfr_cmpl;
+	u8		rsvd2[3];
 };
 
 struct bfa_bsg_fruvpd_max_size_s {
@@ -795,10 +821,12 @@ struct bfa_bsg_fcpt_s {
 };
 #define bfa_bsg_fcpt_t struct bfa_bsg_fcpt_s
 
+#pragma pack(1)
 struct bfa_bsg_data {
 	int payload_len;
-	void *payload;
+	u64 payload;
 };
+#pragma pack()
 
 #define bfad_chk_iocmd_sz(__payload_len, __hdrsz, __bufsz)	\
 	(((__payload_len) != ((__hdrsz) + (__bufsz))) ?		\
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfad.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfad.c	2013-07-01 10:42:40.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad.c	2013-08-31 18:02:28.000000000 -0400
@@ -1718,6 +1718,14 @@ struct pci_device_id bfad_id_table[] = {
 		.class_mask = ~0,
 	},
 
+	{
+		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
+		.device = BFA_PCI_DEVICE_ID_CT2_QUAD,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.class = (PCI_CLASS_SERIAL_FIBER << 8),
+		.class_mask = ~0,
+	},
 	{0, 0},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_debugfs.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_debugfs.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -173,31 +173,9 @@ bfad_debugfs_open_reg(struct inode *inod
 static loff_t
 bfad_debugfs_lseek(struct file *file, loff_t offset, int orig)
 {
-	struct bfad_debug_info *debug;
-	loff_t pos = file->f_pos;
-
-	debug = file->private_data;
-
-	switch (orig) {
-	case 0:
-		file->f_pos = offset;
-		break;
-	case 1:
-		file->f_pos += offset;
-		break;
-	case 2:
-		file->f_pos = debug->buffer_len + offset;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (file->f_pos < 0 || file->f_pos > debug->buffer_len) {
-		file->f_pos = pos;
-		return -EINVAL;
-	}
-
-	return file->f_pos;
+	struct bfad_debug_info *debug = file->private_data;
+	return fixed_size_llseek(file, offset, orig,
+				debug->buffer_len);
 }
 
 static ssize_t
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_drv.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_drv.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_drv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_drv.h	2013-08-25 20:43:22.000000000 -0400
@@ -57,7 +57,7 @@
 #ifdef BFA_DRIVER_VERSION
 #define BFAD_DRIVER_VERSION    BFA_DRIVER_VERSION
 #else
-#define BFAD_DRIVER_VERSION    "3.1.2.1"
+#define BFAD_DRIVER_VERSION    "3.2.21.1"
 #endif
 
 #define BFAD_PROTO_NAME FCPI_NAME
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_defs.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_defs.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_defs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_defs.h	2013-08-25 20:43:22.000000000 -0400
@@ -45,6 +45,7 @@ enum {
 	BFA_MFG_TYPE_PROWLER_C = 1710,   /*  Prowler CNA only cards	*/
 	BFA_MFG_TYPE_PROWLER_D = 1860,   /*  Prowler Dual cards		*/
 	BFA_MFG_TYPE_CHINOOK   = 1867,   /*  Chinook cards		*/
+	BFA_MFG_TYPE_CHINOOK2   = 1869,	 /*!< Chinook2 cards		*/
 	BFA_MFG_TYPE_INVALID = 0,        /*  Invalid card type		*/
 };
 
@@ -59,7 +60,8 @@ enum {
 	(type) == BFA_MFG_TYPE_ASTRA || \
 	(type) == BFA_MFG_TYPE_LIGHTNING_P0 || \
 	(type) == BFA_MFG_TYPE_LIGHTNING || \
-	(type) == BFA_MFG_TYPE_CHINOOK))
+	(type) == BFA_MFG_TYPE_CHINOOK || \
+	(type) == BFA_MFG_TYPE_CHINOOK2))
 
 /*
  * Check if the card having old wwn/mac handling
@@ -185,6 +187,8 @@ enum bfa_status {
 	BFA_STATUS_FAA_DISABLED = 198,	/* FAA is already disabled */
 	BFA_STATUS_FAA_ACQUIRED = 199,	/* FAA is already acquired */
 	BFA_STATUS_FAA_ACQ_ADDR = 200,	/* Acquiring addr */
+	BFA_STATUS_BBCR_FC_ONLY = 201, /*!< BBCredit Recovery is supported for *
+					* FC mode only */
 	BFA_STATUS_ERROR_TRUNK_ENABLED = 203,	/* Trunk enabled on adapter */
 	BFA_STATUS_MAX_ENTRY_REACHED = 212,	/* MAX entry reached */
 	BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */
@@ -197,7 +201,34 @@ enum bfa_status {
 	BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */
 	BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */
 	BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */
+	BFA_STATUS_DPORT_NO_SFP = 243, /* SFP is not present.\n D-port will be
+					* enabled but it will be operational
+					* only after inserting a valid SFP. */
 	BFA_STATUS_DPORT_ERR = 245,	/* D-port mode is enabled */
+	BFA_STATUS_DPORT_ENOSYS = 254, /* Switch has no D_Port functionality */
+	BFA_STATUS_DPORT_CANT_PERF = 255, /* Switch port is not D_Port capable
+					* or D_Port is disabled */
+	BFA_STATUS_DPORT_LOGICALERR = 256, /* Switch D_Port fail */
+	BFA_STATUS_DPORT_SWBUSY = 257, /* Switch port busy */
+	BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT = 258, /*!< BB credit recovery is
+					* supported at max port speed alone */
+	BFA_STATUS_ERROR_BBCR_ENABLED  = 259, /*!< BB credit recovery
+					* is enabled */
+	BFA_STATUS_INVALID_BBSCN = 260, /*!< Invalid BBSCN value.
+					 * Valid range is [1-15] */
+	BFA_STATUS_DDPORT_ERR = 261, /* Dynamic D_Port mode is active.\n To
+					* exit dynamic mode, disable D_Port on
+					* the remote port */
+	BFA_STATUS_DPORT_SFPWRAP_ERR = 262, /* Clear e/o_wrap fail, check or
+						* replace SFP */
+	BFA_STATUS_BBCR_CFG_NO_CHANGE = 265, /*!< BBCR is operational.
+			* Disable BBCR and try this operation again. */
+	BFA_STATUS_DPORT_SW_NOTREADY = 268, /* Remote port is not ready to
+					* start dport test. Check remote
+					* port status. */
+	BFA_STATUS_DPORT_INV_SFP = 271, /* Invalid SFP for D-PORT mode. */
+	BFA_STATUS_DPORT_CMD_NOTSUPP    = 273, /* Dport is not supported by
+					* remote port */
 	BFA_STATUS_MAX_VAL		/* Unknown error code */
 };
 #define bfa_status_t enum bfa_status
@@ -234,6 +265,7 @@ enum {
 	BFA_ADAPTER_MFG_NAME_LEN    = 8,   /*  manufacturer name length */
 	BFA_ADAPTER_SYM_NAME_LEN    = 64,  /*  adapter symbolic name length */
 	BFA_ADAPTER_OS_TYPE_LEN	    = 64,  /*  adapter os type length */
+	BFA_ADAPTER_UUID_LEN	    = 16,  /* adapter uuid length */
 };
 
 struct bfa_adapter_attr_s {
@@ -267,6 +299,7 @@ struct bfa_adapter_attr_s {
 	u8		mfg_month;	/* manufacturing month */
 	u16		mfg_year;	/* manufacturing year */
 	u16		rsvd;
+	u8		uuid[BFA_ADAPTER_UUID_LEN];
 };
 
 /*
@@ -380,7 +413,8 @@ struct bfa_ioc_attr_s {
 	u8				port_mode;	/*  bfa_mode_s	*/
 	u8				cap_bm;		/*  capability	*/
 	u8				port_mode_cfg;	/*  bfa_mode_s	*/
-	u8				rsvd[4];	/*  64bit align	*/
+	u8				def_fn;		/* 1 if default fn */
+	u8				rsvd[3];	/*  64bit align	*/
 };
 
 /*
@@ -517,17 +551,6 @@ struct bfa_ioc_aen_data_s {
 };
 
 /*
- *	D-port states
- *
-*/
-enum bfa_dport_state {
-	BFA_DPORT_ST_DISABLED	= 0,	/* D-port is Disabled */
-	BFA_DPORT_ST_DISABLING	= 1,	/* D-port is Disabling */
-	BFA_DPORT_ST_ENABLING	= 2,	/* D-port is Enabling */
-	BFA_DPORT_ST_ENABLED	= 3,	/* D-port is Enabled */
-};
-
-/*
  * ---------------------- mfg definitions ------------
  */
 
@@ -614,6 +637,7 @@ enum {
 	BFA_PCI_DEVICE_ID_CT		= 0x14,
 	BFA_PCI_DEVICE_ID_CT_FC		= 0x21,
 	BFA_PCI_DEVICE_ID_CT2		= 0x22,
+	BFA_PCI_DEVICE_ID_CT2_QUAD	= 0x23,
 };
 
 #define bfa_asic_id_cb(__d)			\
@@ -622,7 +646,9 @@ enum {
 #define bfa_asic_id_ct(__d)			\
 	((__d) == BFA_PCI_DEVICE_ID_CT ||	\
 	 (__d) == BFA_PCI_DEVICE_ID_CT_FC)
-#define bfa_asic_id_ct2(__d)	((__d) == BFA_PCI_DEVICE_ID_CT2)
+#define bfa_asic_id_ct2(__d)			\
+	((__d) == BFA_PCI_DEVICE_ID_CT2 ||	\
+	(__d) == BFA_PCI_DEVICE_ID_CT2_QUAD)
 #define bfa_asic_id_ctc(__d)	\
 	(bfa_asic_id_ct(__d) || bfa_asic_id_ct2(__d))
 
@@ -1126,6 +1152,7 @@ struct bfa_flash_attr_s {
 #define LB_PATTERN_DEFAULT	0xB5B5B5B5
 #define QTEST_CNT_DEFAULT	10
 #define QTEST_PAT_DEFAULT	LB_PATTERN_DEFAULT
+#define DPORT_ENABLE_LOOPCNT_DEFAULT (1024 * 1024)
 
 struct bfa_diag_memtest_s {
 	u8	algo;
@@ -1154,6 +1181,54 @@ struct bfa_diag_loopback_result_s {
 	u8	rsvd[3];
 };
 
+enum bfa_diag_dport_test_status {
+	DPORT_TEST_ST_IDLE	= 0,    /* the test has not started yet. */
+	DPORT_TEST_ST_FINAL	= 1,    /* the test done successfully */
+	DPORT_TEST_ST_SKIP	= 2,    /* the test skipped */
+	DPORT_TEST_ST_FAIL	= 3,    /* the test failed */
+	DPORT_TEST_ST_INPRG	= 4,    /* the testing is in progress */
+	DPORT_TEST_ST_RESPONDER	= 5,    /* test triggered from remote port */
+	DPORT_TEST_ST_STOPPED	= 6,    /* the test stopped by user. */
+	DPORT_TEST_ST_MAX
+};
+
+enum bfa_diag_dport_test_type {
+	DPORT_TEST_ELOOP	= 0,
+	DPORT_TEST_OLOOP	= 1,
+	DPORT_TEST_ROLOOP	= 2,
+	DPORT_TEST_LINK		= 3,
+	DPORT_TEST_MAX
+};
+
+enum bfa_diag_dport_test_opmode {
+	BFA_DPORT_OPMODE_AUTO	= 0,
+	BFA_DPORT_OPMODE_MANU	= 1,
+};
+
+struct bfa_diag_dport_subtest_result_s {
+	u8	status;		/* bfa_diag_dport_test_status */
+	u8	rsvd[7];	/* 64bit align */
+	u64	start_time;	/* timestamp  */
+};
+
+struct bfa_diag_dport_result_s {
+	wwn_t	rp_pwwn;	/* switch port wwn  */
+	wwn_t	rp_nwwn;	/* switch node wwn  */
+	u64	start_time;	/* user/sw start time */
+	u64	end_time;	/* timestamp  */
+	u8	status;		/* bfa_diag_dport_test_status */
+	u8	mode;		/* bfa_diag_dport_test_opmode */
+	u8	rsvd;		/* 64bit align */
+	u8	speed;		/* link speed for buf_reqd */
+	u16	buffer_required;
+	u16	frmsz;		/* frame size for buf_reqd */
+	u32	lpcnt;		/* Frame count */
+	u32	pat;		/* Pattern */
+	u32	roundtrip_latency;	/* in nano sec */
+	u32	est_cable_distance;	/* in meter */
+	struct bfa_diag_dport_subtest_result_s subtest[DPORT_TEST_MAX];
+};
+
 struct bfa_diag_ledtest_s {
 	u32	cmd;    /* bfa_led_op_t */
 	u32	color;  /* bfa_led_color_t */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_defs_svc.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_defs_svc.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_defs_svc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_defs_svc.h	2013-08-25 20:43:22.000000000 -0400
@@ -105,6 +105,9 @@ struct bfa_fw_ioim_stats_s {
 					 *  an error condition*/
 	u32	wait_for_si;		/*  FW wait for SI */
 	u32	rec_rsp_inval;		/*  REC rsp invalid */
+	u32     rec_rsp_xchg_comp;	/*  REC rsp xchg complete */
+	u32     rec_rsp_rd_si_ownd;	/*  REC rsp read si owned */
+
 	u32	seqr_io_abort;		/*  target does not know cmd so abort */
 	u32	seqr_io_retry;		/*  SEQR failed so retry IO */
 
@@ -257,8 +260,6 @@ struct bfa_fw_port_lksm_stats_s {
 	u32    nos_tx;             /*  No. of times NOS tx started         */
 	u32    hwsm_lrr_rx;        /*  No. of times LRR rx-ed by HWSM      */
 	u32    hwsm_lr_rx;         /*  No. of times LR rx-ed by HWSM       */
-	u32    bbsc_lr;		   /* LKSM LR tx for credit recovery       */
-	u32	rsvd;
 };
 
 struct bfa_fw_port_snsm_stats_s {
@@ -409,7 +410,7 @@ struct bfa_fw_trunk_stats_s {
 	u32 rsvd;		/*  padding for 64 bit alignment */
 };
 
-struct bfa_fw_advsm_stats_s {
+struct bfa_fw_aport_stats_s {
 	u32 flogi_sent;		/*  Flogi sent			*/
 	u32 flogi_acc_recvd;	/*  Flogi Acc received		*/
 	u32 flogi_rjt_recvd;	/*  Flogi rejects received	*/
@@ -419,6 +420,12 @@ struct bfa_fw_advsm_stats_s {
 	u32 elp_accepted;	/*  ELP Accepted		*/
 	u32 elp_rejected;	/*  ELP rejected		*/
 	u32 elp_dropped;	/*  ELP dropped			*/
+
+	u32 bbcr_lr_count;	/*!< BBCR Link Resets		*/
+	u32 frame_lost_intrs;	/*!< BBCR Frame loss intrs	*/
+	u32 rrdy_lost_intrs;	/*!< BBCR Rrdy loss intrs	*/
+
+	u32 rsvd;
 };
 
 /*
@@ -479,6 +486,14 @@ struct bfa_fw_ct_mod_stats_s {
 };
 
 /*
+ * RDS mod stats
+ */
+struct bfa_fw_rds_stats_s {
+	u32	no_fid_drop_err; /* RDS no fid drop error */
+	u32	rsvd;		 /* 64bit align */
+};
+
+/*
  * IOC firmware stats
  */
 struct bfa_fw_stats_s {
@@ -489,10 +504,11 @@ struct bfa_fw_stats_s {
 	struct bfa_fw_fcxchg_stats_s	fcxchg_stats;
 	struct bfa_fw_lps_stats_s	lps_stats;
 	struct bfa_fw_trunk_stats_s	trunk_stats;
-	struct bfa_fw_advsm_stats_s	advsm_stats;
+	struct bfa_fw_aport_stats_s	aport_stats;
 	struct bfa_fw_mac_mod_stats_s	macmod_stats;
 	struct bfa_fw_ct_mod_stats_s	ctmod_stats;
 	struct bfa_fw_eth_sndrcv_stats_s	ethsndrcv_stats;
+	struct bfa_fw_rds_stats_s	rds_stats;
 };
 
 #define BFA_IOCFC_PATHTOV_MAX	60
@@ -545,6 +561,27 @@ struct bfa_qos_attr_s {
 	struct bfa_qos_bw_s qos_bw_op;	/* QOS bw operational */
 };
 
+enum bfa_bbcr_state {
+	BFA_BBCR_DISABLED,	/*!< BBCR is disable */
+	BFA_BBCR_ONLINE,	/*!< BBCR is online  */
+	BFA_BBCR_OFFLINE,	/*!< BBCR is offline */
+};
+
+enum bfa_bbcr_err_reason {
+	BFA_BBCR_ERR_REASON_NONE, /*!< Unknown */
+	BFA_BBCR_ERR_REASON_SPEED_UNSUP, /*!< Port speed < max sup_speed */
+	BFA_BBCR_ERR_REASON_PEER_UNSUP,	/*!< BBCR is disable on peer port */
+	BFA_BBCR_ERR_REASON_NON_BRCD_SW, /*!< Connected to non BRCD switch */
+	BFA_BBCR_ERR_REASON_FLOGI_RJT, /*!< Login rejected by the switch */
+};
+
+struct bfa_bbcr_attr_s {
+	u8	state;
+	u8	peer_bb_scn;
+	u8	reason;
+	u8	rsvd;
+};
+
 /*
  * These fields should be displayed only from the CLI.
  * There will be a separate BFAL API (get_qos_vc_attr ?)
@@ -736,6 +773,7 @@ enum bfa_port_states {
 	BFA_PORT_ST_TOGGLING_QWAIT	= 14,
 	BFA_PORT_ST_FAA_MISCONFIG	= 15,
 	BFA_PORT_ST_DPORT		= 16,
+	BFA_PORT_ST_DDPORT		= 17,
 	BFA_PORT_ST_MAX_STATE,
 };
 
@@ -857,6 +895,15 @@ enum bfa_lunmask_state_s {
 	BFA_LUNMASK_UNINITIALIZED = 0xff,
 };
 
+/**
+ * FEC states
+ */
+enum bfa_fec_state_s {
+	BFA_FEC_ONLINE = 1,		/*!< FEC is online */
+	BFA_FEC_OFFLINE = 2,		/*!< FEC is offline */
+	BFA_FEC_OFFLINE_NOT_16G = 3,	/*!< FEC is offline (speed not 16Gig) */
+};
+
 #pragma pack(1)
 /*
  * LUN mask configuration
@@ -892,6 +939,9 @@ struct bfa_defs_fcpim_throttle_s {
 	u16	rsvd;
 };
 
+#define BFA_BB_SCN_DEF 3
+#define BFA_BB_SCN_MAX 0x0F
+
 /*
  *      Physical port configuration
  */
@@ -907,8 +957,8 @@ struct bfa_port_cfg_s {
 	u8	 tx_bbcredit;	/*  transmit buffer credits	*/
 	u8	 ratelimit;	/*  ratelimit enabled or not	*/
 	u8	 trl_def_speed;	/*  ratelimit default speed	*/
-	u8	 bb_scn;	/*  BB_SCN value from FLOGI Exchg */
-	u8	 bb_scn_state;	/*  Config state of BB_SCN */
+	u8	 bb_cr_enabled; /*!< Config state of BB_SCN	*/
+	u8	 bb_scn;	/*!< BB_SCN value for FLOGI Exchg */
 	u8	 faa_state;	/*  FAA enabled/disabled        */
 	u8	 rsvd1;
 	u16	 path_tov;	/*  device path timeout	*/
@@ -950,6 +1000,7 @@ struct bfa_port_attr_s {
 	bfa_boolean_t		link_e2e_beacon; /* link beacon is on */
 	bfa_boolean_t		bbsc_op_status;	/* fc credit recovery oper
 						 * state */
+	enum bfa_fec_state_s	fec_state;	/*!< current FEC state */
 
 	/*
 	 * Dynamic field - info from FCS
@@ -961,7 +1012,7 @@ struct bfa_port_attr_s {
 
 	/* FCoE specific  */
 	u16			fcoe_vlan;
-	u8			rsvd1[6];
+	u8			rsvd1[2];
 };
 
 /*
@@ -1048,10 +1099,12 @@ struct bfa_port_link_s {
 	u8	 speed;		/*  Link speed (1/2/4/8 G) */
 	u32	 linkstate_opt; /*  Linkstate optional data (debug) */
 	u8	 trunked;	/*  Trunked or not (1 or 0) */
-	u8	 resvd[7];
+	u8	 fec_state;	/*!< State of FEC */
+	u8	 resvd[6];
 	struct bfa_qos_attr_s  qos_attr;   /* QoS Attributes */
 	union {
 		struct bfa_fcport_loop_info_s loop_info;
+		struct bfa_bbcr_attr_s bbcr_attr;
 		union {
 			struct bfa_qos_vc_attr_s qos_vc_attr;
 					/*  VC info from ELP */
@@ -1215,9 +1268,11 @@ struct bfa_port_fc_stats_s {
 	u64     bad_os_count;   /*  Invalid ordered sets        */
 	u64     err_enc_out;    /*  Encoding err nonframe_8b10b */
 	u64     err_enc;        /*  Encoding err frame_8b10b    */
-	u64	bbsc_frames_lost; /* Credit Recovery-Frames Lost  */
-	u64	bbsc_credits_lost; /* Credit Recovery-Credits Lost */
-	u64	bbsc_link_resets; /* Credit Recovery-Link Resets   */
+	u64	bbcr_frames_lost; /*!< BBCR Frames Lost */
+	u64	bbcr_rrdys_lost; /*!< BBCR RRDYs Lost */
+	u64	bbcr_link_resets; /*!< BBCR Link Resets */
+	u64	bbcr_frame_lost_intrs; /*!< BBCR Frame loss intrs */
+	u64	bbcr_rrdy_lost_intrs; /*!< BBCR Rrdy loss intrs */
 	u64	loop_timeouts;	/*  Loop timeouts		*/
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_im.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_im.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfad_im.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfad_im.c	2013-08-25 20:43:22.000000000 -0400
@@ -944,13 +944,15 @@ static int
 bfad_im_slave_alloc(struct scsi_device *sdev)
 {
 	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
-	struct bfad_itnim_data_s *itnim_data =
-				(struct bfad_itnim_data_s *) rport->dd_data;
-	struct bfa_s *bfa = itnim_data->itnim->bfa_itnim->bfa;
+	struct bfad_itnim_data_s *itnim_data;
+	struct bfa_s *bfa;
 
 	if (!rport || fc_remote_port_chkready(rport))
 		return -ENXIO;
 
+	itnim_data = (struct bfad_itnim_data_s *) rport->dd_data;
+	bfa = itnim_data->itnim->bfa_itnim->bfa;
+
 	if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_ENABLED) {
 		/*
 		 * We should not mask LUN 0 - since this will translate
@@ -1035,7 +1037,7 @@ bfad_fc_host_init(struct bfad_im_port_s
 	/* For fibre channel services type 0x20 */
 	fc_host_supported_fc4s(host)[7] = 1;
 
-	strncpy(symname, bfad->bfa_fcs.fabric.bport.port_cfg.sym_name.symname,
+	strlcpy(symname, bfad->bfa_fcs.fabric.bport.port_cfg.sym_name.symname,
 		BFA_SYMNAME_MAXLEN);
 	sprintf(fc_host_symbolic_name(host), "%s", symname);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fc.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fc.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fc.h	2013-08-25 20:43:22.000000000 -0400
@@ -1531,6 +1531,12 @@ enum fdmi_hba_attribute_type {
 	FDMI_HBA_ATTRIB_FW_VERSION,	/* 0x0009 */
 	FDMI_HBA_ATTRIB_OS_NAME,	/* 0x000A */
 	FDMI_HBA_ATTRIB_MAX_CT,		/* 0x000B */
+	FDMI_HBA_ATTRIB_NODE_SYM_NAME,  /* 0x000C */
+	FDMI_HBA_ATTRIB_VENDOR_INFO,    /* 0x000D */
+	FDMI_HBA_ATTRIB_NUM_PORTS,  /* 0x000E */
+	FDMI_HBA_ATTRIB_FABRIC_NAME,    /* 0x000F */
+	FDMI_HBA_ATTRIB_BIOS_VER,   /* 0x0010 */
+	FDMI_HBA_ATTRIB_VENDOR_ID = 0x00E0,
 
 	FDMI_HBA_ATTRIB_MAX_TYPE
 };
@@ -1545,6 +1551,15 @@ enum fdmi_port_attribute_type {
 	FDMI_PORT_ATTRIB_FRAME_SIZE,	/* 0x0004 */
 	FDMI_PORT_ATTRIB_DEV_NAME,	/* 0x0005 */
 	FDMI_PORT_ATTRIB_HOST_NAME,	/* 0x0006 */
+	FDMI_PORT_ATTRIB_NODE_NAME,     /* 0x0007 */
+	FDMI_PORT_ATTRIB_PORT_NAME,     /* 0x0008 */
+	FDMI_PORT_ATTRIB_PORT_SYM_NAME, /* 0x0009 */
+	FDMI_PORT_ATTRIB_PORT_TYPE,     /* 0x000A */
+	FDMI_PORT_ATTRIB_SUPP_COS,      /* 0x000B */
+	FDMI_PORT_ATTRIB_PORT_FAB_NAME, /* 0x000C */
+	FDMI_PORT_ATTRIB_PORT_FC4_TYPE, /* 0x000D */
+	FDMI_PORT_ATTRIB_PORT_STATE = 0x101,    /* 0x0101 */
+	FDMI_PORT_ATTRIB_PORT_NUM_RPRT = 0x102, /* 0x0102 */
 
 	FDMI_PORT_ATTR_MAX_TYPE
 };
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcpim.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcpim.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcpim.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcpim.c	2013-08-25 20:43:22.000000000 -0400
@@ -2882,7 +2882,7 @@ bfa_ioim_good_comp_isr(struct bfa_s *bfa
 	iotag = be16_to_cpu(rsp->io_tag);
 
 	ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
-	WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag);
+	WARN_ON(ioim->iotag != iotag);
 
 	bfa_ioim_cb_profile_comp(fcpim, ioim);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcs.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcs.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcs.c	2013-08-25 20:43:22.000000000 -0400
@@ -240,9 +240,6 @@ static void bfa_fcs_fabric_flogiacc_comp
 					 u32 rsp_len,
 					 u32 resid_len,
 					 struct fchs_s *rspfchs);
-static u8 bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric);
-static bfa_boolean_t bfa_fcs_fabric_is_bbscn_enabled(
-				struct bfa_fcs_fabric_s *fabric);
 
 static void	bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
 					 enum bfa_fcs_fabric_event event);
@@ -404,8 +401,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_f
 	case BFA_FCS_FABRIC_SM_CONT_OP:
 
 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
-					   fabric->bb_credit,
-					   bfa_fcs_fabric_oper_bbscn(fabric));
+					   fabric->bb_credit);
 		fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
 
 		if (fabric->auth_reqd && fabric->is_auth) {
@@ -433,8 +429,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_f
 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
 		fabric->fab_type = BFA_FCS_FABRIC_N2N;
 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
-					   fabric->bb_credit,
-					   bfa_fcs_fabric_oper_bbscn(fabric));
+					   fabric->bb_credit);
 		bfa_fcs_fabric_notify_online(fabric);
 		bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
 		break;
@@ -602,8 +597,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fc
 	case BFA_FCS_FABRIC_SM_NO_FABRIC:
 		bfa_trc(fabric->fcs, fabric->bb_credit);
 		bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa,
-					   fabric->bb_credit,
-					   bfa_fcs_fabric_oper_bbscn(fabric));
+					   fabric->bb_credit);
 		break;
 
 	case BFA_FCS_FABRIC_SM_RETRY_OP:
@@ -965,10 +959,6 @@ bfa_cb_lps_flogi_comp(void *bfad, void *
 
 	case BFA_STATUS_FABRIC_RJT:
 		fabric->stats.flogi_rejects++;
-		if (fabric->lps->lsrjt_rsn == FC_LS_RJT_RSN_LOGICAL_ERROR &&
-		    fabric->lps->lsrjt_expl == FC_LS_RJT_EXP_NO_ADDL_INFO)
-			fabric->fcs->bbscn_flogi_rjt = BFA_TRUE;
-
 		bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
 		return;
 
@@ -1014,14 +1004,11 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabr
 {
 	struct bfa_s		*bfa = fabric->fcs->bfa;
 	struct bfa_lport_cfg_s	*pcfg = &fabric->bport.port_cfg;
-	u8			alpa = 0, bb_scn = 0;
+	u8			alpa = 0;
 
-	if (bfa_fcs_fabric_is_bbscn_enabled(fabric) &&
-	    (!fabric->fcs->bbscn_flogi_rjt))
-		bb_scn = BFA_FCS_PORT_DEF_BB_SCN;
 
 	bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
-		      pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd, bb_scn);
+		      pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
 
 	fabric->stats.flogi_sent++;
 }
@@ -1102,40 +1089,6 @@ bfa_fcs_fabric_stop(struct bfa_fcs_fabri
 }
 
 /*
- * Computes operating BB_SCN value
- */
-static u8
-bfa_fcs_fabric_oper_bbscn(struct bfa_fcs_fabric_s *fabric)
-{
-	u8	pr_bbscn = fabric->lps->pr_bbscn;
-	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fabric->fcs->bfa);
-
-	if (!(fcport->cfg.bb_scn_state && pr_bbscn))
-		return 0;
-
-	/* return max of local/remote bb_scn values */
-	return ((pr_bbscn > BFA_FCS_PORT_DEF_BB_SCN) ?
-		pr_bbscn : BFA_FCS_PORT_DEF_BB_SCN);
-}
-
-/*
- * Check if BB_SCN can be enabled.
- */
-static bfa_boolean_t
-bfa_fcs_fabric_is_bbscn_enabled(struct bfa_fcs_fabric_s *fabric)
-{
-	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fabric->fcs->bfa);
-
-	if (bfa_ioc_get_fcmode(&fabric->fcs->bfa->ioc) &&
-			fcport->cfg.bb_scn_state &&
-			!bfa_fcport_is_qos_enabled(fabric->fcs->bfa) &&
-			!bfa_fcport_is_trunk_enabled(fabric->fcs->bfa))
-		return BFA_TRUE;
-	else
-		return BFA_FALSE;
-}
-
-/*
  * Delete all vports and wait for vport delete completions.
  */
 static void
@@ -1273,7 +1226,6 @@ void
 bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
 {
 	bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
-	fabric->fcs->bbscn_flogi_rjt = BFA_FALSE;
 	bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
 }
 
@@ -1480,7 +1432,6 @@ bfa_fcs_fabric_process_flogi(struct bfa_
 	}
 
 	fabric->bb_credit = be16_to_cpu(flogi->csp.bbcred);
-	fabric->lps->pr_bbscn = (be16_to_cpu(flogi->csp.rxsz) >> 12);
 	bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
 	bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
 
@@ -1513,8 +1464,7 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa
 				    n2n_port->reply_oxid, pcfg->pwwn,
 				    pcfg->nwwn,
 				    bfa_fcport_get_maxfrsize(bfa),
-				    bfa_fcport_get_rx_bbcredit(bfa),
-				    bfa_fcs_fabric_oper_bbscn(fabric));
+				    bfa_fcport_get_rx_bbcredit(bfa), 0);
 
 	bfa_fcxp_send(fcxp, NULL, fabric->vf_id, fabric->lps->bfa_tag,
 		      BFA_FALSE, FC_CLASS_3,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcs.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcs.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcs.h	2013-08-25 20:43:22.000000000 -0400
@@ -243,24 +243,21 @@ struct bfa_fcs_fabric_s;
  *  Symbolic Name.
  *
  *  Physical Port's symbolic name Format : (Total 128 bytes)
- *  Adapter Model number/name : 12 bytes
+ *  Adapter Model number/name : 16 bytes
  *  Driver Version     : 10 bytes
  *  Host Machine Name  : 30 bytes
- *  Host OS Info	   : 48 bytes
+ *  Host OS Info	   : 44 bytes
  *  Host OS PATCH Info : 16 bytes
  *  ( remaining 12 bytes reserved to be used for separator)
  */
 #define BFA_FCS_PORT_SYMBNAME_SEPARATOR			" | "
 
-#define BFA_FCS_PORT_SYMBNAME_MODEL_SZ			12
+#define BFA_FCS_PORT_SYMBNAME_MODEL_SZ			16
 #define BFA_FCS_PORT_SYMBNAME_VERSION_SZ		10
 #define BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ		30
-#define BFA_FCS_PORT_SYMBNAME_OSINFO_SZ			48
+#define BFA_FCS_PORT_SYMBNAME_OSINFO_SZ			44
 #define BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ		16
 
-/* bb_scn value in 2^bb_scn */
-#define BFA_FCS_PORT_DEF_BB_SCN				3
-
 /*
  * Get FC port ID for a logical port.
  */
@@ -630,6 +627,9 @@ void bfa_fcs_fcpim_uf_recv(struct bfa_fc
 
 #define BFA_FCS_FDMI_SUPP_SPEEDS_10G	FDMI_TRANS_SPEED_10G
 
+#define BFA_FCS_FDMI_VENDOR_INFO_LEN    8
+#define BFA_FCS_FDMI_FC4_TYPE_LEN       32
+
 /*
  * HBA Attribute Block : BFA internal representation. Note : Some variable
  * sizes have been trimmed to suit BFA For Ex : Model will be "Brocade". Based
@@ -640,25 +640,39 @@ struct bfa_fcs_fdmi_hba_attr_s {
 	u8         manufacturer[64];
 	u8         serial_num[64];
 	u8         model[16];
-	u8         model_desc[256];
+	u8         model_desc[128];
 	u8         hw_version[8];
 	u8         driver_version[BFA_VERSION_LEN];
 	u8         option_rom_ver[BFA_VERSION_LEN];
 	u8         fw_version[BFA_VERSION_LEN];
 	u8         os_name[256];
 	__be32        max_ct_pyld;
+	struct      bfa_lport_symname_s node_sym_name;
+	u8     vendor_info[BFA_FCS_FDMI_VENDOR_INFO_LEN];
+	__be32    num_ports;
+	wwn_t       fabric_name;
+	u8     bios_ver[BFA_VERSION_LEN];
 };
 
 /*
  * Port Attribute Block
  */
 struct bfa_fcs_fdmi_port_attr_s {
-	u8         supp_fc4_types[32];	/* supported FC4 types */
+	u8         supp_fc4_types[BFA_FCS_FDMI_FC4_TYPE_LEN];
 	__be32        supp_speed;	/* supported speed */
 	__be32        curr_speed;	/* current Speed */
 	__be32        max_frm_size;	/* max frame size */
 	u8         os_device_name[256];	/* OS device Name */
 	u8         host_name[256];	/* host name */
+	wwn_t       port_name;
+	wwn_t       node_name;
+	struct      bfa_lport_symname_s port_sym_name;
+	__be32    port_type;
+	enum fc_cos    scos;
+	wwn_t       port_fabric_name;
+	u8     port_act_fc4_type[BFA_FCS_FDMI_FC4_TYPE_LEN];
+	__be32    port_state;
+	__be32    num_ports;
 };
 
 struct bfa_fcs_stats_s {
@@ -683,8 +697,6 @@ struct bfa_fcs_s {
 	struct bfa_trc_mod_s  *trcmod;	/*  tracing module */
 	bfa_boolean_t	vf_enabled;	/*  VF mode is enabled */
 	bfa_boolean_t	fdmi_enabled;	/*  FDMI is enabled */
-	bfa_boolean_t	bbscn_enabled;	/*  Driver Config Parameter */
-	bfa_boolean_t	bbscn_flogi_rjt;/*  FLOGI reject due to BB_SCN */
 	bfa_boolean_t min_cfg;		/* min cfg enabled/disabled */
 	u16	port_vfid;	/*  port default VF ID */
 	struct bfa_fcs_driver_info_s driver_info;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcs_lport.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcs_lport.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcs_lport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcs_lport.c	2013-08-25 20:43:22.000000000 -0400
@@ -2048,10 +2048,71 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struc
 	attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_MAX_CT);
 	templen = sizeof(fcs_hba_attr->max_ct_pyld);
 	memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, templen);
+	templen = fc_roundup(templen, sizeof(u32));
+	curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
 	len += templen;
 	count++;
 	attr->len = cpu_to_be16(templen + sizeof(attr->type) +
 			     sizeof(templen));
+	/*
+	 * Send extended attributes ( FOS 7.1 support )
+	 */
+	if (fdmi->retry_cnt == 0) {
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NODE_SYM_NAME);
+		templen = sizeof(fcs_hba_attr->node_sym_name);
+		memcpy(attr->value, &fcs_hba_attr->node_sym_name, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		count++;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+					sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_VENDOR_ID);
+		templen = sizeof(fcs_hba_attr->vendor_info);
+		memcpy(attr->value, &fcs_hba_attr->vendor_info, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		count++;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+					sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_NUM_PORTS);
+		templen = sizeof(fcs_hba_attr->num_ports);
+		memcpy(attr->value, &fcs_hba_attr->num_ports, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		count++;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+					sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_FABRIC_NAME);
+		templen = sizeof(fcs_hba_attr->fabric_name);
+		memcpy(attr->value, &fcs_hba_attr->fabric_name, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		count++;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+					sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_HBA_ATTRIB_BIOS_VER);
+		templen = sizeof(fcs_hba_attr->bios_ver);
+		memcpy(attr->value, &fcs_hba_attr->bios_ver, templen);
+		templen = fc_roundup(attr->len, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		count++;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+					sizeof(templen));
+	}
 
 	/*
 	 * Update size of payload
@@ -2252,6 +2313,113 @@ bfa_fcs_lport_fdmi_build_portattr_block(
 				sizeof(templen));
 	}
 
+	if (fdmi->retry_cnt == 0) {
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_NODE_NAME);
+		templen = sizeof(fcs_port_attr.node_name);
+		memcpy(attr->value, &fcs_port_attr.node_name, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		++count;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+				 sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NAME);
+		templen = sizeof(fcs_port_attr.port_name);
+		memcpy(attr->value, &fcs_port_attr.port_name, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(attr->len) + templen;
+		len += templen;
+		++count;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+				 sizeof(templen));
+
+		if (fcs_port_attr.port_sym_name.symname[0] != '\0') {
+			attr = (struct fdmi_attr_s *) curr_ptr;
+			attr->type =
+				cpu_to_be16(FDMI_PORT_ATTRIB_PORT_SYM_NAME);
+			templen = sizeof(fcs_port_attr.port_sym_name);
+			memcpy(attr->value,
+				&fcs_port_attr.port_sym_name, templen);
+			templen = fc_roundup(templen, sizeof(u32));
+			curr_ptr += sizeof(attr->type) +
+					sizeof(templen) + templen;
+			len += templen;
+			++count;
+			attr->len = cpu_to_be16(templen +
+				sizeof(attr->type) + sizeof(templen));
+		}
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_TYPE);
+		templen = sizeof(fcs_port_attr.port_type);
+		memcpy(attr->value, &fcs_port_attr.port_type, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		++count;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+				 sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_SUPP_COS);
+		templen = sizeof(fcs_port_attr.scos);
+		memcpy(attr->value, &fcs_port_attr.scos, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		++count;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+				 sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FAB_NAME);
+		templen = sizeof(fcs_port_attr.port_fabric_name);
+		memcpy(attr->value, &fcs_port_attr.port_fabric_name, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		++count;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+				 sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_FC4_TYPE);
+		templen = sizeof(fcs_port_attr.port_act_fc4_type);
+		memcpy(attr->value, fcs_port_attr.port_act_fc4_type,
+				templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		++count;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+				 sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_STATE);
+		templen = sizeof(fcs_port_attr.port_state);
+		memcpy(attr->value, &fcs_port_attr.port_state, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		++count;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+				 sizeof(templen));
+
+		attr = (struct fdmi_attr_s *) curr_ptr;
+		attr->type = cpu_to_be16(FDMI_PORT_ATTRIB_PORT_NUM_RPRT);
+		templen = sizeof(fcs_port_attr.num_ports);
+		memcpy(attr->value, &fcs_port_attr.num_ports, templen);
+		templen = fc_roundup(templen, sizeof(u32));
+		curr_ptr += sizeof(attr->type) + sizeof(templen) + templen;
+		len += templen;
+		++count;
+		attr->len = cpu_to_be16(templen + sizeof(attr->type) +
+				sizeof(templen));
+	}
+
 	/*
 	 * Update size of payload
 	 */
@@ -2458,6 +2626,15 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_
 	/* Retrieve the max frame size from the port attr */
 	bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
 	hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size;
+
+	strncpy(hba_attr->node_sym_name.symname,
+		port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN);
+	strcpy(hba_attr->vendor_info, "BROCADE");
+	hba_attr->num_ports =
+		cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc));
+	hba_attr->fabric_name = port->fabric->lps->pr_nwwn;
+	strncpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN);
+
 }
 
 static void
@@ -2467,6 +2644,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs
 	struct bfa_fcs_lport_s *port = fdmi->ms->port;
 	struct bfa_fcs_driver_info_s  *driver_info = &port->fcs->driver_info;
 	struct bfa_port_attr_s pport_attr;
+	struct bfa_lport_attr_s lport_attr;
 
 	memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
 
@@ -2531,6 +2709,18 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs
 	strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
 		sizeof(port_attr->host_name));
 
+	port_attr->node_name = bfa_fcs_lport_get_nwwn(port);
+	port_attr->port_name = bfa_fcs_lport_get_pwwn(port);
+
+	strncpy(port_attr->port_sym_name.symname,
+		(char *)&bfa_fcs_lport_get_psym_name(port), BFA_SYMNAME_MAXLEN);
+	bfa_fcs_lport_get_attr(port, &lport_attr);
+	port_attr->port_type = cpu_to_be32(lport_attr.port_type);
+	port_attr->scos = pport_attr.cos_supported;
+	port_attr->port_fabric_name = port->fabric->lps->pr_nwwn;
+	fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->port_act_fc4_type);
+	port_attr->port_state = cpu_to_be32(pport_attr.port_state);
+	port_attr->num_ports = cpu_to_be32(port->num_rports);
 }
 
 /*
@@ -5798,6 +5988,7 @@ enum bfa_fcs_vport_event {
 	BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12,	/*  Dup wnn error*/
 	BFA_FCS_VPORT_SM_RSP_FAILED = 13,	/*  non-retryable failure */
 	BFA_FCS_VPORT_SM_STOPCOMP = 14,	/* vport delete completion */
+	BFA_FCS_VPORT_SM_FABRIC_MAX = 15, /* max vports on fabric */
 };
 
 static void     bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
@@ -5983,6 +6174,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vp
 		break;
 
 	case BFA_FCS_VPORT_SM_RSP_FAILED:
+	case BFA_FCS_VPORT_SM_FABRIC_MAX:
 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
 		break;
 
@@ -6053,6 +6245,7 @@ bfa_fcs_vport_sm_fdisc_rsp_wait(struct b
 	case BFA_FCS_VPORT_SM_OFFLINE:
 	case BFA_FCS_VPORT_SM_RSP_ERROR:
 	case BFA_FCS_VPORT_SM_RSP_FAILED:
+	case BFA_FCS_VPORT_SM_FABRIC_MAX:
 	case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
 		bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
 		bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE);
@@ -6338,7 +6531,7 @@ bfa_fcs_vport_fdisc_rejected(struct bfa_
 		else {
 			bfa_fcs_vport_aen_post(&vport->lport,
 					BFA_LPORT_AEN_NPIV_FABRIC_MAX);
-			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
+			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_FABRIC_MAX);
 		}
 		break;
 
@@ -6724,7 +6917,19 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *
 			break;
 		}
 
-		bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
+		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
+			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
+		else
+			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
+
+		break;
+
+	case BFA_STATUS_ETIMER:
+		vport->vport_stats.fdisc_timeouts++;
+		if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
+			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
+		else
+			bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
 		break;
 
 	case BFA_STATUS_FABRIC_RJT:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcs_rport.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcs_rport.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_fcs_rport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_fcs_rport.c	2013-08-25 20:43:22.000000000 -0400
@@ -189,8 +189,8 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_r
 		break;
 
 	case RPSM_EVENT_PLOGI_RCVD:
-		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
-		bfa_fcs_rport_fcs_online_action(rport);
+		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
+		bfa_fcs_rport_send_plogiacc(rport, NULL);
 		break;
 
 	case RPSM_EVENT_PLOGI_COMP:
@@ -2577,7 +2577,7 @@ bfa_fcs_rport_update(struct bfa_fcs_rpor
 
 		port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
 		bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
-					  port->fabric->bb_credit, 0);
+					  port->fabric->bb_credit);
 	}
 
 }
@@ -3430,9 +3430,10 @@ bfa_fcs_rpf_rpsc2_response(void *fcsarg,
 		num_ents = be16_to_cpu(rpsc2_acc->num_pids);
 		bfa_trc(rport->fcs, num_ents);
 		if (num_ents > 0) {
-			WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid);
+			WARN_ON(be32_to_cpu(rpsc2_acc->port_info[0].pid) !=
+						bfa_ntoh3b(rport->pid));
 			bfa_trc(rport->fcs,
-				be16_to_cpu(rpsc2_acc->port_info[0].pid));
+				be32_to_cpu(rpsc2_acc->port_info[0].pid));
 			bfa_trc(rport->fcs,
 				be16_to_cpu(rpsc2_acc->port_info[0].speed));
 			bfa_trc(rport->fcs,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_ioc.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_ioc.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_ioc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_ioc.c	2013-08-25 20:43:22.000000000 -0400
@@ -67,6 +67,14 @@ BFA_TRC_FILE(CNA, IOC);
 			((__ioc)->ioc_hwif->ioc_sync_ack(__ioc))
 #define bfa_ioc_sync_complete(__ioc)            \
 			((__ioc)->ioc_hwif->ioc_sync_complete(__ioc))
+#define bfa_ioc_set_cur_ioc_fwstate(__ioc, __fwstate)		\
+			((__ioc)->ioc_hwif->ioc_set_fwstate(__ioc, __fwstate))
+#define bfa_ioc_get_cur_ioc_fwstate(__ioc)		\
+			((__ioc)->ioc_hwif->ioc_get_fwstate(__ioc))
+#define bfa_ioc_set_alt_ioc_fwstate(__ioc, __fwstate)		\
+		((__ioc)->ioc_hwif->ioc_set_alt_fwstate(__ioc, __fwstate))
+#define bfa_ioc_get_alt_ioc_fwstate(__ioc)		\
+			((__ioc)->ioc_hwif->ioc_get_alt_fwstate(__ioc))
 
 #define bfa_ioc_mbox_cmd_pending(__ioc)		\
 			(!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \
@@ -698,7 +706,7 @@ bfa_iocpf_sm_fwcheck_entry(struct bfa_io
 	}
 
 	/* h/w sem init */
-	fwstate = readl(iocpf->ioc->ioc_regs.ioc_fwstate);
+	fwstate = bfa_ioc_get_cur_ioc_fwstate(iocpf->ioc);
 	if (fwstate == BFI_IOC_UNINIT) {
 		writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg);
 		goto sem_get;
@@ -725,8 +733,8 @@ bfa_iocpf_sm_fwcheck_entry(struct bfa_io
 
 	bfa_trc(iocpf->ioc, fwstate);
 	bfa_trc(iocpf->ioc, swab32(fwhdr.exec));
-	writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.ioc_fwstate);
-	writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.alt_ioc_fwstate);
+	bfa_ioc_set_cur_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT);
+	bfa_ioc_set_alt_ioc_fwstate(iocpf->ioc, BFI_IOC_UNINIT);
 
 	/*
 	 * Unlock the hw semaphore. Should be here only once per boot.
@@ -1037,7 +1045,7 @@ bfa_iocpf_sm_disabling(struct bfa_iocpf_
 		 */
 
 	case IOCPF_E_TIMEOUT:
-		writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+		bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
 		bfa_fsm_set_state(iocpf, bfa_iocpf_sm_disabling_sync);
 		break;
 
@@ -1138,7 +1146,7 @@ bfa_iocpf_sm_initfail_sync(struct bfa_io
 	case IOCPF_E_SEMLOCKED:
 		bfa_ioc_notify_fail(ioc);
 		bfa_ioc_sync_leave(ioc);
-		writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+		bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
 		writel(1, ioc->ioc_regs.ioc_sem_reg);
 		bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
 		break;
@@ -1227,7 +1235,7 @@ bfa_iocpf_sm_fail_sync(struct bfa_iocpf_
 		bfa_ioc_notify_fail(ioc);
 		if (!iocpf->auto_recover) {
 			bfa_ioc_sync_leave(ioc);
-			writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+			bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
 			writel(1, ioc->ioc_regs.ioc_sem_reg);
 			bfa_fsm_set_state(iocpf, bfa_iocpf_sm_fail);
 		} else {
@@ -1519,7 +1527,7 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bf
 	u32 boot_type;
 	u32 boot_env;
 
-	ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+	ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
 
 	if (force)
 		ioc_fwstate = BFI_IOC_UNINIT;
@@ -1850,7 +1858,7 @@ bfa_ioc_smem_read(struct bfa_ioc_s *ioc,
 	bfa_trc(ioc, len);
 	for (i = 0; i < len; i++) {
 		r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
-		buf[i] = be32_to_cpu(r32);
+		buf[i] = swab32(r32);
 		loff += sizeof(u32);
 
 		/*
@@ -2006,11 +2014,11 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32
 	 * Initialize IOC state of all functions on a chip reset.
 	 */
 	if (boot_type == BFI_FWBOOT_TYPE_MEMTEST) {
-		writel(BFI_IOC_MEMTEST, ioc->ioc_regs.ioc_fwstate);
-		writel(BFI_IOC_MEMTEST, ioc->ioc_regs.alt_ioc_fwstate);
+		bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_MEMTEST);
+		bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_MEMTEST);
 	} else {
-		writel(BFI_IOC_INITING, ioc->ioc_regs.ioc_fwstate);
-		writel(BFI_IOC_INITING, ioc->ioc_regs.alt_ioc_fwstate);
+		bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_INITING);
+		bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_INITING);
 	}
 
 	bfa_ioc_msgflush(ioc);
@@ -2038,7 +2046,7 @@ bfa_ioc_is_operational(struct bfa_ioc_s
 bfa_boolean_t
 bfa_ioc_is_initialized(struct bfa_ioc_s *ioc)
 {
-	u32 r32 = readl(ioc->ioc_regs.ioc_fwstate);
+	u32 r32 = bfa_ioc_get_cur_ioc_fwstate(ioc);
 
 	return ((r32 != BFI_IOC_UNINIT) &&
 		(r32 != BFI_IOC_INITING) &&
@@ -2188,6 +2196,7 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc,
 		break;
 
 	case BFA_PCI_DEVICE_ID_CT2:
+	case BFA_PCI_DEVICE_ID_CT2_QUAD:
 		ioc->asic_gen = BFI_ASIC_GEN_CT2;
 		if (clscode == BFI_PCIFN_CLASS_FC &&
 		    pcidev->ssid == BFA_PCI_CT2_SSID_FC) {
@@ -2430,12 +2439,12 @@ bfa_ioc_adapter_is_disabled(struct bfa_i
 	if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
 		return BFA_FALSE;
 
-	ioc_state = readl(ioc->ioc_regs.ioc_fwstate);
+	ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc);
 	if (!bfa_ioc_state_disabled(ioc_state))
 		return BFA_FALSE;
 
 	if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_FC_8G1P) {
-		ioc_state = readl(ioc->ioc_regs.alt_ioc_fwstate);
+		ioc_state = bfa_ioc_get_cur_ioc_fwstate(ioc);
 		if (!bfa_ioc_state_disabled(ioc_state))
 			return BFA_FALSE;
 	}
@@ -2449,8 +2458,8 @@ bfa_ioc_adapter_is_disabled(struct bfa_i
 void
 bfa_ioc_reset_fwstate(struct bfa_ioc_s *ioc)
 {
-	writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
-	writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
+	bfa_ioc_set_cur_ioc_fwstate(ioc, BFI_IOC_UNINIT);
+	bfa_ioc_set_alt_ioc_fwstate(ioc, BFI_IOC_UNINIT);
 }
 
 #define BFA_MFG_NAME "Brocade"
@@ -2500,6 +2509,7 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_
 	ad_attr->mfg_day = ioc_attr->mfg_day;
 	ad_attr->mfg_month = ioc_attr->mfg_month;
 	ad_attr->mfg_year = ioc_attr->mfg_year;
+	memcpy(ad_attr->uuid, ioc_attr->uuid, BFA_ADAPTER_UUID_LEN);
 }
 
 enum bfa_ioc_type_e
@@ -2564,13 +2574,19 @@ void
 bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model)
 {
 	struct bfi_ioc_attr_s	*ioc_attr;
+	u8 nports = bfa_ioc_get_nports(ioc);
 
 	WARN_ON(!model);
 	memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN);
 
 	ioc_attr = ioc->attr;
 
-	snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
+	if (bfa_asic_id_ct2(ioc->pcidev.device_id) &&
+		(!bfa_mfg_is_mezz(ioc_attr->card_type)))
+		snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u-%u%s",
+			BFA_MFG_NAME, ioc_attr->card_type, nports, "p");
+	else
+		snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u",
 			BFA_MFG_NAME, ioc_attr->card_type);
 }
 
@@ -2620,7 +2636,7 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc,
 	memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
 
 	ioc_attr->state = bfa_ioc_get_state(ioc);
-	ioc_attr->port_id = ioc->port_id;
+	ioc_attr->port_id = bfa_ioc_portid(ioc);
 	ioc_attr->port_mode = ioc->port_mode;
 	ioc_attr->port_mode_cfg = ioc->port_mode_cfg;
 	ioc_attr->cap_bm = ioc->ad_cap_bm;
@@ -2629,8 +2645,9 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc,
 
 	bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
 
-	ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
-	ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
+	ioc_attr->pci_attr.device_id = bfa_ioc_devid(ioc);
+	ioc_attr->pci_attr.pcifn = bfa_ioc_pcifn(ioc);
+	ioc_attr->def_fn = (bfa_ioc_pcifn(ioc) == bfa_ioc_portid(ioc));
 	bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev);
 }
 
@@ -2917,7 +2934,7 @@ bfa_iocpf_sem_timeout(void *ioc_arg)
 static void
 bfa_ioc_poll_fwinit(struct bfa_ioc_s *ioc)
 {
-	u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+	u32 fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
 
 	bfa_trc(ioc, fwstate);
 
@@ -6010,6 +6027,7 @@ bfa_fru_write_send(void *cbarg, enum bfi
 	 */
 	msg->last = (len == fru->residue) ? 1 : 0;
 
+	msg->trfr_cmpl = (len == fru->residue) ? fru->trfr_cmpl : 0;
 	bfi_h2i_set(msg->mh, BFI_MC_FRU, msg_type, bfa_ioc_portid(fru->ioc));
 	bfa_alen_set(&msg->alen, len, fru->dbuf_pa);
 
@@ -6124,13 +6142,14 @@ bfa_fru_memclaim(struct bfa_fru_s *fru,
  */
 bfa_status_t
 bfa_fruvpd_update(struct bfa_fru_s *fru, void *buf, u32 len, u32 offset,
-		  bfa_cb_fru_t cbfn, void *cbarg)
+		  bfa_cb_fru_t cbfn, void *cbarg, u8 trfr_cmpl)
 {
 	bfa_trc(fru, BFI_FRUVPD_H2I_WRITE_REQ);
 	bfa_trc(fru, len);
 	bfa_trc(fru, offset);
 
-	if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
+	if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2 &&
+		fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
 		return BFA_STATUS_FRU_NOT_PRESENT;
 
 	if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK)
@@ -6152,6 +6171,7 @@ bfa_fruvpd_update(struct bfa_fru_s *fru,
 	fru->offset = 0;
 	fru->addr_off = offset;
 	fru->ubuf = buf;
+	fru->trfr_cmpl = trfr_cmpl;
 
 	bfa_fru_write_send(fru, BFI_FRUVPD_H2I_WRITE_REQ);
 
@@ -6181,7 +6201,8 @@ bfa_fruvpd_read(struct bfa_fru_s *fru, v
 	if (fru->ioc->asic_gen != BFI_ASIC_GEN_CT2)
 		return BFA_STATUS_FRU_NOT_PRESENT;
 
-	if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK)
+	if (fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK &&
+		fru->ioc->attr->card_type != BFA_MFG_TYPE_CHINOOK2)
 		return BFA_STATUS_CMD_NOTSUPP;
 
 	if (!bfa_ioc_is_operational(fru->ioc))
@@ -6222,7 +6243,8 @@ bfa_fruvpd_get_max_size(struct bfa_fru_s
 	if (!bfa_ioc_is_operational(fru->ioc))
 		return BFA_STATUS_IOC_NON_OP;
 
-	if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK)
+	if (fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK ||
+		fru->ioc->attr->card_type == BFA_MFG_TYPE_CHINOOK2)
 		*max_size = BFA_FRU_CHINOOK_MAX_SIZE;
 	else
 		return BFA_STATUS_CMD_NOTSUPP;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_ioc_cb.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_ioc_cb.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_ioc_cb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_ioc_cb.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,6 +22,8 @@
 
 BFA_TRC_FILE(CNA, IOC_CB);
 
+#define bfa_ioc_cb_join_pos(__ioc) ((u32) (1 << BFA_IOC_CB_JOIN_SH))
+
 /*
  * forward declarations
  */
@@ -37,6 +39,12 @@ static void bfa_ioc_cb_sync_join(struct
 static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc);
 static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc);
 static bfa_boolean_t bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_set_cur_ioc_fwstate(
+			struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate);
+static enum bfi_ioc_state bfa_ioc_cb_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc);
+static void bfa_ioc_cb_set_alt_ioc_fwstate(
+			struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate);
+static enum bfi_ioc_state bfa_ioc_cb_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc);
 
 static struct bfa_ioc_hwif_s hwif_cb;
 
@@ -59,6 +67,10 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *io
 	hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave;
 	hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack;
 	hwif_cb.ioc_sync_complete = bfa_ioc_cb_sync_complete;
+	hwif_cb.ioc_set_fwstate = bfa_ioc_cb_set_cur_ioc_fwstate;
+	hwif_cb.ioc_get_fwstate = bfa_ioc_cb_get_cur_ioc_fwstate;
+	hwif_cb.ioc_set_alt_fwstate = bfa_ioc_cb_set_alt_ioc_fwstate;
+	hwif_cb.ioc_get_alt_fwstate = bfa_ioc_cb_get_alt_ioc_fwstate;
 
 	ioc->ioc_hwif = &hwif_cb;
 }
@@ -187,6 +199,20 @@ bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s
 static bfa_boolean_t
 bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc)
 {
+	u32 ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+
+	/**
+	 * Driver load time.  If the join bit is set,
+	 * it is due to an unclean exit by the driver for this
+	 * PCI fn in the previous incarnation. Whoever comes here first
+	 * should clean it up, no matter which PCI fn.
+	 */
+	if (ioc_fwstate & BFA_IOC_CB_JOIN_MASK) {
+		writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+		writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
+		return BFA_TRUE;
+	}
+
 	return bfa_ioc_cb_sync_complete(ioc);
 }
 
@@ -212,24 +238,66 @@ bfa_ioc_cb_ownership_reset(struct bfa_io
 static void
 bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc)
 {
+	u32 r32 = readl(ioc->ioc_regs.ioc_fwstate);
+	u32 join_pos = bfa_ioc_cb_join_pos(ioc);
+
+	writel((r32 | join_pos), ioc->ioc_regs.ioc_fwstate);
 }
 
 static void
 bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc)
 {
+	u32 r32 = readl(ioc->ioc_regs.ioc_fwstate);
+	u32 join_pos = bfa_ioc_cb_join_pos(ioc);
+
+	writel((r32 & ~join_pos), ioc->ioc_regs.ioc_fwstate);
+}
+
+static void
+bfa_ioc_cb_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc,
+			enum bfi_ioc_state fwstate)
+{
+	u32 r32 = readl(ioc->ioc_regs.ioc_fwstate);
+
+	writel((fwstate | (r32 & BFA_IOC_CB_JOIN_MASK)),
+				ioc->ioc_regs.ioc_fwstate);
+}
+
+static enum bfi_ioc_state
+bfa_ioc_cb_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc)
+{
+	return (enum bfi_ioc_state)(readl(ioc->ioc_regs.ioc_fwstate) &
+			BFA_IOC_CB_FWSTATE_MASK);
+}
+
+static void
+bfa_ioc_cb_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc,
+			enum bfi_ioc_state fwstate)
+{
+	u32 r32 = readl(ioc->ioc_regs.alt_ioc_fwstate);
+
+	writel((fwstate | (r32 & BFA_IOC_CB_JOIN_MASK)),
+				ioc->ioc_regs.alt_ioc_fwstate);
+}
+
+static enum bfi_ioc_state
+bfa_ioc_cb_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc)
+{
+	return (enum bfi_ioc_state)(readl(ioc->ioc_regs.alt_ioc_fwstate) &
+			BFA_IOC_CB_FWSTATE_MASK);
 }
 
 static void
 bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc)
 {
-	writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
+	bfa_ioc_cb_set_cur_ioc_fwstate(ioc, BFI_IOC_FAIL);
 }
 
 static bfa_boolean_t
 bfa_ioc_cb_sync_complete(struct bfa_ioc_s *ioc)
 {
-	uint32_t fwstate, alt_fwstate;
-	fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+	u32 fwstate, alt_fwstate;
+	fwstate = bfa_ioc_cb_get_cur_ioc_fwstate(ioc);
 
 	/*
 	 * At this point, this IOC is hoding the hw sem in the
@@ -257,7 +325,7 @@ bfa_ioc_cb_sync_complete(struct bfa_ioc_
 		fwstate == BFI_IOC_OP)
 		return BFA_TRUE;
 	else {
-		alt_fwstate = readl(ioc->ioc_regs.alt_ioc_fwstate);
+		alt_fwstate = bfa_ioc_cb_get_alt_ioc_fwstate(ioc);
 		if (alt_fwstate == BFI_IOC_FAIL ||
 			alt_fwstate == BFI_IOC_DISABLED ||
 			alt_fwstate == BFI_IOC_UNINIT ||
@@ -272,7 +340,7 @@ bfa_ioc_cb_sync_complete(struct bfa_ioc_
 bfa_status_t
 bfa_ioc_cb_pll_init(void __iomem *rb, enum bfi_asic_mode fcmode)
 {
-	u32	pll_sclk, pll_fclk;
+	u32	pll_sclk, pll_fclk, join_bits;
 
 	pll_sclk = __APP_PLL_SCLK_ENABLE | __APP_PLL_SCLK_LRESETN |
 		__APP_PLL_SCLK_P0_1(3U) |
@@ -282,8 +350,12 @@ bfa_ioc_cb_pll_init(void __iomem *rb, en
 		__APP_PLL_LCLK_RSEL200500 | __APP_PLL_LCLK_P0_1(3U) |
 		__APP_PLL_LCLK_JITLMT0_1(3U) |
 		__APP_PLL_LCLK_CNTLMT0_1(3U);
-	writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG));
-	writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG));
+	join_bits = readl(rb + BFA_IOC0_STATE_REG) &
+			BFA_IOC_CB_JOIN_MASK;
+	writel((BFI_IOC_UNINIT | join_bits), (rb + BFA_IOC0_STATE_REG));
+	join_bits = readl(rb + BFA_IOC1_STATE_REG) &
+			BFA_IOC_CB_JOIN_MASK;
+	writel((BFI_IOC_UNINIT | join_bits), (rb + BFA_IOC1_STATE_REG));
 	writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
 	writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
 	writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_ioc_ct.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_ioc_ct.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_ioc_ct.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_ioc_ct.c	2013-08-25 20:43:22.000000000 -0400
@@ -43,6 +43,12 @@ static void bfa_ioc_ct_sync_join(struct
 static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc);
 static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc);
 static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_set_cur_ioc_fwstate(
+			struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate);
+static enum bfi_ioc_state bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_set_alt_ioc_fwstate(
+			struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate);
+static enum bfi_ioc_state bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc);
 
 static struct bfa_ioc_hwif_s hwif_ct;
 static struct bfa_ioc_hwif_s hwif_ct2;
@@ -512,6 +518,10 @@ bfa_ioc_set_ctx_hwif(struct bfa_ioc_s *i
 	hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave;
 	hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack;
 	hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete;
+	hwif->ioc_set_fwstate = bfa_ioc_ct_set_cur_ioc_fwstate;
+	hwif->ioc_get_fwstate = bfa_ioc_ct_get_cur_ioc_fwstate;
+	hwif->ioc_set_alt_fwstate = bfa_ioc_ct_set_alt_ioc_fwstate;
+	hwif->ioc_get_alt_fwstate = bfa_ioc_ct_get_alt_ioc_fwstate;
 }
 
 /**
@@ -918,6 +928,16 @@ bfa_ioc_ct2_pll_init(void __iomem *rb, e
 
 		}
 	}
+	/*
+	* The very first PCIe DMA Read done by LPU fails with a fatal error,
+	* when Address Translation Cache (ATC) has been enabled by system BIOS.
+	*
+	* Workaround:
+	* Disable Invalidated Tag Match Enable capability by setting the bit 26
+	* of CHIP_MISC_PRG to 0, by default it is set to 1.
+	*/
+	r32 = readl(rb + CT2_CHIP_MISC_PRG);
+	writel((r32 & 0xfbffffff), (rb + CT2_CHIP_MISC_PRG));
 
 	/*
 	 * Mask the interrupts and clear any
@@ -949,3 +969,29 @@ bfa_ioc_ct2_pll_init(void __iomem *rb, e
 
 	return BFA_STATUS_OK;
 }
+
+static void
+bfa_ioc_ct_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc,
+		enum bfi_ioc_state fwstate)
+{
+	writel(fwstate, ioc->ioc_regs.ioc_fwstate);
+}
+
+static enum bfi_ioc_state
+bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc)
+{
+	return (enum bfi_ioc_state)readl(ioc->ioc_regs.ioc_fwstate);
+}
+
+static void
+bfa_ioc_ct_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc,
+		enum bfi_ioc_state fwstate)
+{
+	writel(fwstate, ioc->ioc_regs.alt_ioc_fwstate);
+}
+
+static enum bfi_ioc_state
+bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc)
+{
+	return (enum bfi_ioc_state) readl(ioc->ioc_regs.alt_ioc_fwstate);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_ioc.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_ioc.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_ioc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_ioc.h	2013-08-25 20:43:22.000000000 -0400
@@ -346,6 +346,12 @@ struct bfa_ioc_hwif_s {
 	void		(*ioc_sync_ack)		(struct bfa_ioc_s *ioc);
 	bfa_boolean_t	(*ioc_sync_complete)	(struct bfa_ioc_s *ioc);
 	bfa_boolean_t	(*ioc_lpu_read_stat)	(struct bfa_ioc_s *ioc);
+	void		(*ioc_set_fwstate)	(struct bfa_ioc_s *ioc,
+					enum bfi_ioc_state fwstate);
+	enum bfi_ioc_state	(*ioc_get_fwstate)	(struct bfa_ioc_s *ioc);
+	void		(*ioc_set_alt_fwstate)	(struct bfa_ioc_s *ioc,
+					enum bfi_ioc_state fwstate);
+	enum bfi_ioc_state	(*ioc_get_alt_fwstate)	(struct bfa_ioc_s *ioc);
 };
 
 /*
@@ -725,6 +731,7 @@ struct bfa_fru_s {
 	struct bfa_mbox_cmd_s mb;	/* mailbox */
 	struct bfa_ioc_notify_s ioc_notify; /* ioc event notify */
 	struct bfa_mem_dma_s	fru_dma;
+	u8		trfr_cmpl;
 };
 
 #define BFA_FRU(__bfa)	(&(__bfa)->modules.fru)
@@ -732,7 +739,7 @@ struct bfa_fru_s {
 
 bfa_status_t bfa_fruvpd_update(struct bfa_fru_s *fru,
 			void *buf, u32 len, u32 offset,
-			bfa_cb_fru_t cbfn, void *cbarg);
+			bfa_cb_fru_t cbfn, void *cbarg, u8 trfr_cmpl);
 bfa_status_t bfa_fruvpd_read(struct bfa_fru_s *fru,
 			void *buf, u32 len, u32 offset,
 			bfa_cb_fru_t cbfn, void *cbarg);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_svc.c linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_svc.c
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_svc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_svc.c	2013-08-25 20:43:22.000000000 -0400
@@ -70,6 +70,8 @@ enum bfa_fcport_sm_event {
 	BFA_FCPORT_SM_DPORTENABLE = 10, /*  enable dport      */
 	BFA_FCPORT_SM_DPORTDISABLE = 11,/*  disable dport     */
 	BFA_FCPORT_SM_FAA_MISCONFIG = 12,	/* FAA misconfiguratin */
+	BFA_FCPORT_SM_DDPORTENABLE  = 13,	/* enable ddport	*/
+	BFA_FCPORT_SM_DDPORTDISABLE = 14,	/* disable ddport	*/
 };
 
 /*
@@ -202,6 +204,8 @@ static void     bfa_fcport_sm_iocfail(st
 					enum bfa_fcport_sm_event event);
 static void	bfa_fcport_sm_dport(struct bfa_fcport_s *fcport,
 					enum bfa_fcport_sm_event event);
+static void     bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport,
+					enum bfa_fcport_sm_event event);
 static void	bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport,
 					enum bfa_fcport_sm_event event);
 
@@ -234,6 +238,7 @@ static struct bfa_sm_table_s hal_port_sm
 	{BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN},
 	{BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN},
 	{BFA_SM(bfa_fcport_sm_dport), BFA_PORT_ST_DPORT},
+	{BFA_SM(bfa_fcport_sm_ddport), BFA_PORT_ST_DDPORT},
 	{BFA_SM(bfa_fcport_sm_faa_misconfig), BFA_PORT_ST_FAA_MISCONFIG},
 };
 
@@ -1276,7 +1281,6 @@ bfa_lps_sm_login(struct bfa_lps_s *lps,
 
 	switch (event) {
 	case BFA_LPS_SM_FWRSP:
-	case BFA_LPS_SM_OFFLINE:
 		if (lps->status == BFA_STATUS_OK) {
 			bfa_sm_set_state(lps, bfa_lps_sm_online);
 			if (lps->fdisc)
@@ -1305,6 +1309,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps,
 		bfa_lps_login_comp(lps);
 		break;
 
+	case BFA_LPS_SM_OFFLINE:
 	case BFA_LPS_SM_DELETE:
 		bfa_sm_set_state(lps, bfa_lps_sm_init);
 		break;
@@ -1614,7 +1619,6 @@ bfa_lps_login_rsp(struct bfa_s *bfa, str
 		lps->lp_mac	= rsp->lp_mac;
 		lps->brcd_switch = rsp->brcd_switch;
 		lps->fcf_mac	= rsp->fcf_mac;
-		lps->pr_bbscn	= rsp->bb_scn;
 
 		break;
 
@@ -1744,7 +1748,6 @@ bfa_lps_send_login(struct bfa_lps_s *lps
 	m->nwwn		= lps->nwwn;
 	m->fdisc	= lps->fdisc;
 	m->auth_en	= lps->auth_en;
-	m->bb_scn	= lps->bb_scn;
 
 	bfa_reqq_produce(lps->bfa, lps->reqq, m->mh);
 	list_del(&lps->qe);
@@ -1940,7 +1943,7 @@ bfa_lps_delete(struct bfa_lps_s *lps)
  */
 void
 bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
-	wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en, uint8_t bb_scn)
+	wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en)
 {
 	lps->uarg	= uarg;
 	lps->alpa	= alpa;
@@ -1949,7 +1952,6 @@ bfa_lps_flogi(struct bfa_lps_s *lps, voi
 	lps->nwwn	= nwwn;
 	lps->fdisc	= BFA_FALSE;
 	lps->auth_en	= auth_en;
-	lps->bb_scn	= bb_scn;
 	bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
 }
 
@@ -2649,6 +2651,10 @@ bfa_fcport_sm_disabled(struct bfa_fcport
 		bfa_sm_set_state(fcport, bfa_fcport_sm_dport);
 		break;
 
+	case BFA_FCPORT_SM_DDPORTENABLE:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_ddport);
+		break;
+
 	default:
 		bfa_sm_fault(fcport->bfa, event);
 	}
@@ -2762,6 +2768,40 @@ bfa_fcport_sm_dport(struct bfa_fcport_s
 }
 
 static void
+bfa_fcport_sm_ddport(struct bfa_fcport_s *fcport,
+			enum bfa_fcport_sm_event event)
+{
+	bfa_trc(fcport->bfa, event);
+
+	switch (event) {
+	case BFA_FCPORT_SM_DISABLE:
+	case BFA_FCPORT_SM_DDPORTDISABLE:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
+		break;
+
+	case BFA_FCPORT_SM_DPORTENABLE:
+	case BFA_FCPORT_SM_DPORTDISABLE:
+	case BFA_FCPORT_SM_ENABLE:
+	case BFA_FCPORT_SM_START:
+		/**
+		 * Ignore event for a port that is ddport
+		 */
+		break;
+
+	case BFA_FCPORT_SM_STOP:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
+		break;
+
+	case BFA_FCPORT_SM_HWFAIL:
+		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
+		break;
+
+	default:
+		bfa_sm_fault(fcport->bfa, event);
+	}
+}
+
+static void
 bfa_fcport_sm_faa_misconfig(struct bfa_fcport_s *fcport,
 			    enum bfa_fcport_sm_event event)
 {
@@ -3082,6 +3122,8 @@ bfa_fcport_attach(struct bfa_s *bfa, voi
 	port_cfg->qos_bw.med = BFA_QOS_BW_MED;
 	port_cfg->qos_bw.low = BFA_QOS_BW_LOW;
 
+	fcport->fec_state = BFA_FEC_OFFLINE;
+
 	INIT_LIST_HEAD(&fcport->stats_pending_q);
 	INIT_LIST_HEAD(&fcport->statsclr_pending_q);
 
@@ -3158,6 +3200,11 @@ bfa_fcport_update_linkinfo(struct bfa_fc
 	fcport->qos_attr = pevent->link_state.qos_attr;
 	fcport->qos_vc_attr = pevent->link_state.attr.vc_fcf.qos_vc_attr;
 
+	if (fcport->cfg.bb_cr_enabled)
+		fcport->bbcr_attr = pevent->link_state.attr.bbcr_attr;
+
+	fcport->fec_state = pevent->link_state.fec_state;
+
 	/*
 	 * update trunk state if applicable
 	 */
@@ -3177,7 +3224,7 @@ bfa_fcport_reset_linkinfo(struct bfa_fcp
 {
 	fcport->speed = BFA_PORT_SPEED_UNKNOWN;
 	fcport->topology = BFA_PORT_TOPOLOGY_NONE;
-	fcport->bbsc_op_state = BFA_FALSE;
+	fcport->fec_state = BFA_FEC_OFFLINE;
 }
 
 /*
@@ -3629,6 +3676,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct
 			fcport->qos_attr.qos_bw_op =
 					i2hmsg.penable_rsp->port_cfg.qos_bw;
 
+			if (fcport->cfg.bb_cr_enabled)
+				fcport->bbcr_attr.state = BFA_BBCR_OFFLINE;
+			else
+				fcport->bbcr_attr.state = BFA_BBCR_DISABLED;
+
 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
 		}
 		break;
@@ -3639,6 +3691,11 @@ bfa_fcport_isr(struct bfa_s *bfa, struct
 		break;
 
 	case BFI_FCPORT_I2H_EVENT:
+		if (fcport->cfg.bb_cr_enabled)
+			fcport->bbcr_attr.state = BFA_BBCR_OFFLINE;
+		else
+			fcport->bbcr_attr.state = BFA_BBCR_DISABLED;
+
 		if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP)
 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
 		else {
@@ -3846,6 +3903,8 @@ bfa_fcport_cfg_topology(struct bfa_s *bf
 			return BFA_STATUS_LOOP_UNSUPP_MEZZ;
 		if (bfa_fcport_is_dport(bfa) != BFA_FALSE)
 			return BFA_STATUS_DPORT_ERR;
+		if (bfa_fcport_is_ddport(bfa) != BFA_FALSE)
+			return BFA_STATUS_DPORT_ERR;
 		break;
 
 	case BFA_PORT_TOPOLOGY_AUTO:
@@ -3964,14 +4023,11 @@ bfa_fcport_get_rx_bbcredit(struct bfa_s
 }
 
 void
-bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn)
+bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
 {
 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
 
 	fcport->cfg.tx_bbcredit = (u8)tx_bbcredit;
-	fcport->cfg.bb_scn = bb_scn;
-	if (bb_scn)
-		fcport->bbsc_op_state = BFA_TRUE;
 }
 
 /*
@@ -4021,7 +4077,8 @@ bfa_fcport_get_attr(struct bfa_s *bfa, s
 	attr->pport_cfg.path_tov  = bfa_fcpim_path_tov_get(bfa);
 	attr->pport_cfg.q_depth  = bfa_fcpim_qdepth_get(bfa);
 	attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm);
-	attr->bbsc_op_status =  fcport->bbsc_op_state;
+
+	attr->fec_state = fcport->fec_state;
 
 	/* PBC Disabled State */
 	if (bfa_fcport_is_pbcdisabled(bfa))
@@ -4115,6 +4172,15 @@ bfa_fcport_is_dport(struct bfa_s *bfa)
 		BFA_PORT_ST_DPORT);
 }
 
+bfa_boolean_t
+bfa_fcport_is_ddport(struct bfa_s *bfa)
+{
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+
+	return (bfa_sm_to_state(hal_port_sm_table, fcport->sm) ==
+		BFA_PORT_ST_DDPORT);
+}
+
 bfa_status_t
 bfa_fcport_set_qos_bw(struct bfa_s *bfa, struct bfa_qos_bw_s *qos_bw)
 {
@@ -4217,6 +4283,77 @@ bfa_fcport_is_trunk_enabled(struct bfa_s
 	return fcport->cfg.trunked;
 }
 
+bfa_status_t
+bfa_fcport_cfg_bbcr(struct bfa_s *bfa, bfa_boolean_t on_off, u8 bb_scn)
+{
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+
+	bfa_trc(bfa, on_off);
+
+	if (bfa_ioc_get_type(&fcport->bfa->ioc) != BFA_IOC_TYPE_FC)
+		return BFA_STATUS_BBCR_FC_ONLY;
+
+	if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type) &&
+		(bfa->ioc.attr->card_type != BFA_MFG_TYPE_CHINOOK))
+		return BFA_STATUS_CMD_NOTSUPP_MEZZ;
+
+	if (on_off) {
+		if (fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP)
+			return BFA_STATUS_TOPOLOGY_LOOP;
+
+		if (fcport->cfg.qos_enabled)
+			return BFA_STATUS_ERROR_QOS_ENABLED;
+
+		if (fcport->cfg.trunked)
+			return BFA_STATUS_TRUNK_ENABLED;
+
+		if ((fcport->cfg.speed != BFA_PORT_SPEED_AUTO) &&
+			(fcport->cfg.speed < bfa_ioc_speed_sup(&bfa->ioc)))
+			return BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT;
+
+		if (bfa_ioc_speed_sup(&bfa->ioc) < BFA_PORT_SPEED_8GBPS)
+			return BFA_STATUS_FEATURE_NOT_SUPPORTED;
+
+		if (fcport->cfg.bb_cr_enabled) {
+			if (bb_scn != fcport->cfg.bb_scn)
+				return BFA_STATUS_BBCR_CFG_NO_CHANGE;
+			else
+				return BFA_STATUS_NO_CHANGE;
+		}
+
+		if ((bb_scn == 0) || (bb_scn > BFA_BB_SCN_MAX))
+			bb_scn = BFA_BB_SCN_DEF;
+
+		fcport->cfg.bb_cr_enabled = on_off;
+		fcport->cfg.bb_scn = bb_scn;
+	} else {
+		if (!fcport->cfg.bb_cr_enabled)
+			return BFA_STATUS_NO_CHANGE;
+
+		fcport->cfg.bb_cr_enabled = on_off;
+		fcport->cfg.bb_scn = 0;
+	}
+
+	return BFA_STATUS_OK;
+}
+
+bfa_status_t
+bfa_fcport_get_bbcr_attr(struct bfa_s *bfa,
+		struct bfa_bbcr_attr_s *bbcr_attr)
+{
+	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
+
+	if (bfa_ioc_get_type(&fcport->bfa->ioc) != BFA_IOC_TYPE_FC)
+		return BFA_STATUS_BBCR_FC_ONLY;
+
+	if (fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP)
+		return BFA_STATUS_TOPOLOGY_LOOP;
+
+	*bbcr_attr = fcport->bbcr_attr;
+
+	return BFA_STATUS_OK;
+}
+
 void
 bfa_fcport_dportenable(struct bfa_s *bfa)
 {
@@ -4237,6 +4374,24 @@ bfa_fcport_dportdisable(struct bfa_s *bf
 	bfa_port_set_dportenabled(&bfa->modules.port, BFA_FALSE);
 }
 
+void
+bfa_fcport_ddportenable(struct bfa_s *bfa)
+{
+	/*
+	 * Assume caller check for port is in disable state
+	 */
+	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTENABLE);
+}
+
+void
+bfa_fcport_ddportdisable(struct bfa_s *bfa)
+{
+	/*
+	 * Assume caller check for port is in disable state
+	 */
+	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DDPORTDISABLE);
+}
+
 /*
  * Rport State machine functions
  */
@@ -5622,6 +5777,14 @@ bfa_uf_res_recfg(struct bfa_s *bfa, u16
  *	Dport forward declaration
  */
 
+enum bfa_dport_test_state_e {
+	BFA_DPORT_ST_DISABLED	= 0,	/*!< dport is disabled */
+	BFA_DPORT_ST_INP	= 1,	/*!< test in progress */
+	BFA_DPORT_ST_COMP	= 2,	/*!< test complete successfully */
+	BFA_DPORT_ST_NO_SFP	= 3,	/*!< sfp is not present */
+	BFA_DPORT_ST_NOTSTART	= 4,	/*!< test not start dport is enabled */
+};
+
 /*
  * BFA DPORT state machine events
  */
@@ -5631,6 +5794,9 @@ enum bfa_dport_sm_event {
 	BFA_DPORT_SM_FWRSP      = 3,    /* fw enable/disable rsp      */
 	BFA_DPORT_SM_QRESUME    = 4,    /* CQ space available         */
 	BFA_DPORT_SM_HWFAIL     = 5,    /* IOC h/w failure            */
+	BFA_DPORT_SM_START	= 6,	/* re-start dport test        */
+	BFA_DPORT_SM_REQFAIL	= 7,	/* request failure            */
+	BFA_DPORT_SM_SCN	= 8,	/* state change notify frm fw */
 };
 
 static void bfa_dport_sm_disabled(struct bfa_dport_s *dport,
@@ -5645,9 +5811,19 @@ static void bfa_dport_sm_disabling_qwait
 				 enum bfa_dport_sm_event event);
 static void bfa_dport_sm_disabling(struct bfa_dport_s *dport,
 				   enum bfa_dport_sm_event event);
+static void bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport,
+					enum bfa_dport_sm_event event);
+static void bfa_dport_sm_starting(struct bfa_dport_s *dport,
+				  enum bfa_dport_sm_event event);
+static void bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport,
+				   enum bfa_dport_sm_event event);
+static void bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport,
+				   enum bfa_dport_sm_event event);
 static void bfa_dport_qresume(void *cbarg);
 static void bfa_dport_req_comp(struct bfa_dport_s *dport,
-			       bfi_diag_dport_rsp_t *msg);
+				struct bfi_diag_dport_rsp_s *msg);
+static void bfa_dport_scn(struct bfa_dport_s *dport,
+				struct bfi_diag_dport_scn_s *msg);
 
 /*
  *	BFA fcdiag module
@@ -5689,6 +5865,8 @@ bfa_fcdiag_attach(struct bfa_s *bfa, voi
 	bfa_reqq_winit(&dport->reqq_wait, bfa_dport_qresume, dport);
 	dport->cbfn = NULL;
 	dport->cbarg = NULL;
+	dport->test_state = BFA_DPORT_ST_DISABLED;
+	memset(&dport->result, 0, sizeof(struct bfa_diag_dport_result_s));
 }
 
 static void
@@ -5891,7 +6069,12 @@ bfa_fcdiag_intr(struct bfa_s *bfa, struc
 		bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg);
 		break;
 	case BFI_DIAG_I2H_DPORT:
-		bfa_dport_req_comp(&fcdiag->dport, (bfi_diag_dport_rsp_t *)msg);
+		bfa_dport_req_comp(&fcdiag->dport,
+				(struct bfi_diag_dport_rsp_s *)msg);
+		break;
+	case BFI_DIAG_I2H_DPORT_SCN:
+		bfa_dport_scn(&fcdiag->dport,
+				(struct bfi_diag_dport_scn_s *)msg);
 		break;
 	default:
 		bfa_trc(fcdiag, msg->mhdr.msg_id);
@@ -5986,7 +6169,11 @@ bfa_fcdiag_loopback(struct bfa_s *bfa, e
 				return BFA_STATUS_UNSUPP_SPEED;
 		}
 	}
-
+	/* check to see if fcport is dport */
+	if (bfa_fcport_is_dport(bfa)) {
+		bfa_trc(fcdiag, fcdiag->lb.lock);
+		return BFA_STATUS_DPORT_ENABLED;
+	}
 	/* check to see if there is another destructive diag cmd running */
 	if (fcdiag->lb.lock) {
 		bfa_trc(fcdiag, fcdiag->lb.lock);
@@ -6090,6 +6277,15 @@ bfa_fcdiag_lb_is_running(struct bfa_s *b
 /*
  *	D-port
  */
+#define bfa_dport_result_start(__dport, __mode) do {			\
+		(__dport)->result.start_time = bfa_get_log_time();	\
+		(__dport)->result.status = DPORT_TEST_ST_INPRG;		\
+		(__dport)->result.mode = (__mode);			\
+		(__dport)->result.rp_pwwn = (__dport)->rp_pwwn;		\
+		(__dport)->result.rp_nwwn = (__dport)->rp_nwwn;		\
+		(__dport)->result.lpcnt = (__dport)->lpcnt;		\
+} while (0)
+
 static bfa_boolean_t bfa_dport_send_req(struct bfa_dport_s *dport,
 					enum bfi_dport_req req);
 static void
@@ -6124,6 +6320,18 @@ bfa_dport_sm_disabled(struct bfa_dport_s
 		/* ignore */
 		break;
 
+	case BFA_DPORT_SM_SCN:
+		if (dport->i2hmsg.scn.state ==  BFI_DPORT_SCN_DDPORT_ENABLE) {
+			bfa_fcport_ddportenable(dport->bfa);
+			dport->dynamic = BFA_TRUE;
+			dport->test_state = BFA_DPORT_ST_NOTSTART;
+			bfa_sm_set_state(dport, bfa_dport_sm_enabled);
+		} else {
+			bfa_trc(dport->bfa, dport->i2hmsg.scn.state);
+			WARN_ON(1);
+		}
+		break;
+
 	default:
 		bfa_sm_fault(dport->bfa, event);
 	}
@@ -6159,9 +6367,23 @@ bfa_dport_sm_enabling(struct bfa_dport_s
 
 	switch (event) {
 	case BFA_DPORT_SM_FWRSP:
+		memset(&dport->result, 0,
+				sizeof(struct bfa_diag_dport_result_s));
+		if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) {
+			dport->test_state = BFA_DPORT_ST_NO_SFP;
+		} else {
+			dport->test_state = BFA_DPORT_ST_INP;
+			bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO);
+		}
 		bfa_sm_set_state(dport, bfa_dport_sm_enabled);
 		break;
 
+	case BFA_DPORT_SM_REQFAIL:
+		dport->test_state = BFA_DPORT_ST_DISABLED;
+		bfa_fcport_dportdisable(dport->bfa);
+		bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+		break;
+
 	case BFA_DPORT_SM_HWFAIL:
 		bfa_sm_set_state(dport, bfa_dport_sm_disabled);
 		bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
@@ -6178,8 +6400,11 @@ bfa_dport_sm_enabled(struct bfa_dport_s
 	bfa_trc(dport->bfa, event);
 
 	switch (event) {
-	case BFA_DPORT_SM_ENABLE:
-		/* Already enabled */
+	case BFA_DPORT_SM_START:
+		if (bfa_dport_send_req(dport, BFI_DPORT_START))
+			bfa_sm_set_state(dport, bfa_dport_sm_starting);
+		else
+			bfa_sm_set_state(dport, bfa_dport_sm_starting_qwait);
 		break;
 
 	case BFA_DPORT_SM_DISABLE:
@@ -6194,6 +6419,48 @@ bfa_dport_sm_enabled(struct bfa_dport_s
 		bfa_sm_set_state(dport, bfa_dport_sm_disabled);
 		break;
 
+	case BFA_DPORT_SM_SCN:
+		switch (dport->i2hmsg.scn.state) {
+		case BFI_DPORT_SCN_TESTCOMP:
+			dport->test_state = BFA_DPORT_ST_COMP;
+			break;
+
+		case BFI_DPORT_SCN_TESTSTART:
+			dport->test_state = BFA_DPORT_ST_INP;
+			break;
+
+		case BFI_DPORT_SCN_TESTSKIP:
+		case BFI_DPORT_SCN_SUBTESTSTART:
+			/* no state change */
+			break;
+
+		case BFI_DPORT_SCN_SFP_REMOVED:
+			dport->test_state = BFA_DPORT_ST_NO_SFP;
+			break;
+
+		case BFI_DPORT_SCN_DDPORT_DISABLE:
+			bfa_fcport_ddportdisable(dport->bfa);
+
+			if (bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE))
+				bfa_sm_set_state(dport,
+					 bfa_dport_sm_dynamic_disabling);
+			else
+				bfa_sm_set_state(dport,
+					 bfa_dport_sm_dynamic_disabling_qwait);
+			break;
+
+		case BFI_DPORT_SCN_FCPORT_DISABLE:
+			bfa_fcport_ddportdisable(dport->bfa);
+
+			bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+			dport->dynamic = BFA_FALSE;
+			break;
+
+		default:
+			bfa_trc(dport->bfa, dport->i2hmsg.scn.state);
+			bfa_sm_fault(dport->bfa, event);
+		}
+		break;
 	default:
 		bfa_sm_fault(dport->bfa, event);
 	}
@@ -6217,6 +6484,10 @@ bfa_dport_sm_disabling_qwait(struct bfa_
 		bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
 		break;
 
+	case BFA_DPORT_SM_SCN:
+		/* ignore */
+		break;
+
 	default:
 		bfa_sm_fault(dport->bfa, event);
 	}
@@ -6229,7 +6500,98 @@ bfa_dport_sm_disabling(struct bfa_dport_
 
 	switch (event) {
 	case BFA_DPORT_SM_FWRSP:
+		dport->test_state = BFA_DPORT_ST_DISABLED;
+		bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+		break;
+
+	case BFA_DPORT_SM_HWFAIL:
+		bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+		bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
+		break;
+
+	case BFA_DPORT_SM_SCN:
+		/* no state change */
+		break;
+
+	default:
+		bfa_sm_fault(dport->bfa, event);
+	}
+}
+
+static void
+bfa_dport_sm_starting_qwait(struct bfa_dport_s *dport,
+			    enum bfa_dport_sm_event event)
+{
+	bfa_trc(dport->bfa, event);
+
+	switch (event) {
+	case BFA_DPORT_SM_QRESUME:
+		bfa_sm_set_state(dport, bfa_dport_sm_starting);
+		bfa_dport_send_req(dport, BFI_DPORT_START);
+		break;
+
+	case BFA_DPORT_SM_HWFAIL:
+		bfa_reqq_wcancel(&dport->reqq_wait);
+		bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+		bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
+		break;
+
+	default:
+		bfa_sm_fault(dport->bfa, event);
+	}
+}
+
+static void
+bfa_dport_sm_starting(struct bfa_dport_s *dport, enum bfa_dport_sm_event event)
+{
+	bfa_trc(dport->bfa, event);
+
+	switch (event) {
+	case BFA_DPORT_SM_FWRSP:
+		memset(&dport->result, 0,
+				sizeof(struct bfa_diag_dport_result_s));
+		if (dport->i2hmsg.rsp.status == BFA_STATUS_DPORT_INV_SFP) {
+			dport->test_state = BFA_DPORT_ST_NO_SFP;
+		} else {
+			dport->test_state = BFA_DPORT_ST_INP;
+			bfa_dport_result_start(dport, BFA_DPORT_OPMODE_MANU);
+		}
+		/* fall thru */
+
+	case BFA_DPORT_SM_REQFAIL:
+		bfa_sm_set_state(dport, bfa_dport_sm_enabled);
+		break;
+
+	case BFA_DPORT_SM_HWFAIL:
 		bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+		bfa_cb_fcdiag_dport(dport, BFA_STATUS_FAILED);
+		break;
+
+	default:
+		bfa_sm_fault(dport->bfa, event);
+	}
+}
+
+static void
+bfa_dport_sm_dynamic_disabling(struct bfa_dport_s *dport,
+			       enum bfa_dport_sm_event event)
+{
+	bfa_trc(dport->bfa, event);
+
+	switch (event) {
+	case BFA_DPORT_SM_SCN:
+		switch (dport->i2hmsg.scn.state) {
+		case BFI_DPORT_SCN_DDPORT_DISABLED:
+			bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+			dport->dynamic = BFA_FALSE;
+			bfa_fcport_enable(dport->bfa);
+			break;
+
+		default:
+			bfa_trc(dport->bfa, dport->i2hmsg.scn.state);
+			bfa_sm_fault(dport->bfa, event);
+
+		}
 		break;
 
 	case BFA_DPORT_SM_HWFAIL:
@@ -6242,6 +6604,32 @@ bfa_dport_sm_disabling(struct bfa_dport_
 	}
 }
 
+static void
+bfa_dport_sm_dynamic_disabling_qwait(struct bfa_dport_s *dport,
+			    enum bfa_dport_sm_event event)
+{
+	bfa_trc(dport->bfa, event);
+
+	switch (event) {
+	case BFA_DPORT_SM_QRESUME:
+		bfa_sm_set_state(dport, bfa_dport_sm_dynamic_disabling);
+		bfa_dport_send_req(dport, BFI_DPORT_DYN_DISABLE);
+		break;
+
+	case BFA_DPORT_SM_HWFAIL:
+		bfa_sm_set_state(dport, bfa_dport_sm_disabled);
+		bfa_reqq_wcancel(&dport->reqq_wait);
+		bfa_cb_fcdiag_dport(dport, BFA_STATUS_OK);
+		break;
+
+	case BFA_DPORT_SM_SCN:
+		/* ignore */
+		break;
+
+	default:
+		bfa_sm_fault(dport->bfa, event);
+	}
+}
 
 static bfa_boolean_t
 bfa_dport_send_req(struct bfa_dport_s *dport, enum bfi_dport_req req)
@@ -6249,12 +6637,6 @@ bfa_dport_send_req(struct bfa_dport_s *d
 	struct bfi_diag_dport_req_s *m;
 
 	/*
-	 * Increment message tag before queue check, so that responses to old
-	 * requests are discarded.
-	 */
-	dport->msgtag++;
-
-	/*
 	 * check for room in queue to send request now
 	 */
 	m = bfa_reqq_next(dport->bfa, BFA_REQQ_DIAG);
@@ -6266,7 +6648,10 @@ bfa_dport_send_req(struct bfa_dport_s *d
 	bfi_h2i_set(m->mh, BFI_MC_DIAG, BFI_DIAG_H2I_DPORT,
 		    bfa_fn_lpu(dport->bfa));
 	m->req  = req;
-	m->msgtag = dport->msgtag;
+	if ((req == BFI_DPORT_ENABLE) || (req == BFI_DPORT_START)) {
+		m->lpcnt = cpu_to_be32(dport->lpcnt);
+		m->payload = cpu_to_be32(dport->payload);
+	}
 
 	/*
 	 * queue I/O message to firmware
@@ -6285,19 +6670,131 @@ bfa_dport_qresume(void *cbarg)
 }
 
 static void
-bfa_dport_req_comp(struct bfa_dport_s *dport, bfi_diag_dport_rsp_t *msg)
+bfa_dport_req_comp(struct bfa_dport_s *dport, struct bfi_diag_dport_rsp_s *msg)
 {
-	bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP);
+	msg->status = cpu_to_be32(msg->status);
+	dport->i2hmsg.rsp.status = msg->status;
+	dport->rp_pwwn = msg->pwwn;
+	dport->rp_nwwn = msg->nwwn;
+
+	if ((msg->status == BFA_STATUS_OK) ||
+	    (msg->status == BFA_STATUS_DPORT_NO_SFP)) {
+		bfa_trc(dport->bfa, msg->status);
+		bfa_trc(dport->bfa, dport->rp_pwwn);
+		bfa_trc(dport->bfa, dport->rp_nwwn);
+		bfa_sm_send_event(dport, BFA_DPORT_SM_FWRSP);
+
+	} else {
+		bfa_trc(dport->bfa, msg->status);
+		bfa_sm_send_event(dport, BFA_DPORT_SM_REQFAIL);
+	}
 	bfa_cb_fcdiag_dport(dport, msg->status);
 }
 
+static bfa_boolean_t
+bfa_dport_is_sending_req(struct bfa_dport_s *dport)
+{
+	if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling)	||
+	    bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
+	    bfa_sm_cmp_state(dport, bfa_dport_sm_disabling)	||
+	    bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait) ||
+	    bfa_sm_cmp_state(dport, bfa_dport_sm_starting)	||
+	    bfa_sm_cmp_state(dport, bfa_dport_sm_starting_qwait)) {
+		return BFA_TRUE;
+	} else {
+		return BFA_FALSE;
+	}
+}
+
+static void
+bfa_dport_scn(struct bfa_dport_s *dport, struct bfi_diag_dport_scn_s *msg)
+{
+	int i;
+	uint8_t subtesttype;
+
+	bfa_trc(dport->bfa, msg->state);
+	dport->i2hmsg.scn.state = msg->state;
+
+	switch (dport->i2hmsg.scn.state) {
+	case BFI_DPORT_SCN_TESTCOMP:
+		dport->result.end_time = bfa_get_log_time();
+		bfa_trc(dport->bfa, dport->result.end_time);
+
+		dport->result.status = msg->info.testcomp.status;
+		bfa_trc(dport->bfa, dport->result.status);
+
+		dport->result.roundtrip_latency =
+			cpu_to_be32(msg->info.testcomp.latency);
+		dport->result.est_cable_distance =
+			cpu_to_be32(msg->info.testcomp.distance);
+		dport->result.buffer_required =
+			be16_to_cpu(msg->info.testcomp.numbuffer);
+
+		dport->result.frmsz = be16_to_cpu(msg->info.testcomp.frm_sz);
+		dport->result.speed = msg->info.testcomp.speed;
+
+		bfa_trc(dport->bfa, dport->result.roundtrip_latency);
+		bfa_trc(dport->bfa, dport->result.est_cable_distance);
+		bfa_trc(dport->bfa, dport->result.buffer_required);
+		bfa_trc(dport->bfa, dport->result.frmsz);
+		bfa_trc(dport->bfa, dport->result.speed);
+
+		for (i = DPORT_TEST_ELOOP; i < DPORT_TEST_MAX; i++) {
+			dport->result.subtest[i].status =
+				msg->info.testcomp.subtest_status[i];
+			bfa_trc(dport->bfa, dport->result.subtest[i].status);
+		}
+		break;
+
+	case BFI_DPORT_SCN_TESTSKIP:
+	case BFI_DPORT_SCN_DDPORT_ENABLE:
+		memset(&dport->result, 0,
+				sizeof(struct bfa_diag_dport_result_s));
+		break;
+
+	case BFI_DPORT_SCN_TESTSTART:
+		memset(&dport->result, 0,
+				sizeof(struct bfa_diag_dport_result_s));
+		dport->rp_pwwn = msg->info.teststart.pwwn;
+		dport->rp_nwwn = msg->info.teststart.nwwn;
+		dport->lpcnt = cpu_to_be32(msg->info.teststart.numfrm);
+		bfa_dport_result_start(dport, BFA_DPORT_OPMODE_AUTO);
+		break;
+
+	case BFI_DPORT_SCN_SUBTESTSTART:
+		subtesttype = msg->info.teststart.type;
+		dport->result.subtest[subtesttype].start_time =
+			bfa_get_log_time();
+		dport->result.subtest[subtesttype].status =
+			DPORT_TEST_ST_INPRG;
+
+		bfa_trc(dport->bfa, subtesttype);
+		bfa_trc(dport->bfa,
+			dport->result.subtest[subtesttype].start_time);
+		break;
+
+	case BFI_DPORT_SCN_SFP_REMOVED:
+	case BFI_DPORT_SCN_DDPORT_DISABLED:
+	case BFI_DPORT_SCN_DDPORT_DISABLE:
+	case BFI_DPORT_SCN_FCPORT_DISABLE:
+		dport->result.status = DPORT_TEST_ST_IDLE;
+		break;
+
+	default:
+		bfa_sm_fault(dport->bfa, msg->state);
+	}
+
+	bfa_sm_send_event(dport, BFA_DPORT_SM_SCN);
+}
+
 /*
  * Dport enable
  *
  * @param[in] *bfa            - bfa data struct
  */
 bfa_status_t
-bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn, void *cbarg)
+bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat,
+				bfa_cb_diag_t cbfn, void *cbarg)
 {
 	struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
 	struct bfa_dport_s  *dport = &fcdiag->dport;
@@ -6311,6 +6808,14 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_
 	}
 
 	/*
+	 * Dport is supported in CT2 or above
+	 */
+	if (!(bfa_asic_id_ct2(dport->bfa->ioc.pcidev.device_id))) {
+		bfa_trc(dport->bfa, dport->bfa->ioc.pcidev.device_id);
+		return BFA_STATUS_FEATURE_NOT_SUPPORTED;
+	}
+
+	/*
 	 * Check to see if IOC is down
 	*/
 	if (!bfa_iocfc_is_operational(bfa))
@@ -6348,6 +6853,14 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_
 	}
 
 	/*
+	 * Check if diag loopback is running
+	 */
+	if (bfa_fcdiag_lb_is_running(bfa)) {
+		bfa_trc(dport->bfa, 0);
+		return BFA_STATUS_DIAG_BUSY;
+	}
+
+	/*
 	 * Check to see if port is disable or in dport state
 	 */
 	if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) &&
@@ -6357,14 +6870,16 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_
 	}
 
 	/*
+	 * Check if dport is in dynamic mode
+	 */
+	if (dport->dynamic)
+		return BFA_STATUS_DDPORT_ERR;
+
+	/*
 	 * Check if dport is busy
 	 */
-	if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
-	    bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
-	    bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
-	    bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait)) {
+	if (bfa_dport_is_sending_req(dport))
 		return BFA_STATUS_DEVBUSY;
-	}
 
 	/*
 	 * Check if dport is already enabled
@@ -6374,6 +6889,10 @@ bfa_dport_enable(struct bfa_s *bfa, bfa_
 		return BFA_STATUS_DPORT_ENABLED;
 	}
 
+	bfa_trc(dport->bfa, lpcnt);
+	bfa_trc(dport->bfa, pat);
+	dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT;
+	dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT;
 	dport->cbfn = cbfn;
 	dport->cbarg = cbarg;
 
@@ -6402,6 +6921,13 @@ bfa_dport_disable(struct bfa_s *bfa, bfa
 	}
 
 	/*
+	 * Check if dport is in dynamic mode
+	 */
+	if (dport->dynamic) {
+		return BFA_STATUS_DDPORT_ERR;
+	}
+
+	/*
 	 * Check to see if port is disable or in dport state
 	 */
 	if ((bfa_fcport_is_disabled(bfa) == BFA_FALSE) &&
@@ -6413,10 +6939,7 @@ bfa_dport_disable(struct bfa_s *bfa, bfa
 	/*
 	 * Check if dport is busy
 	 */
-	if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
-	    bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait) ||
-	    bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
-	    bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait))
+	if (bfa_dport_is_sending_req(dport))
 		return BFA_STATUS_DEVBUSY;
 
 	/*
@@ -6435,30 +6958,105 @@ bfa_dport_disable(struct bfa_s *bfa, bfa
 }
 
 /*
- *	Get D-port state
+ * Dport start -- restart dport test
  *
- * @param[in] *bfa            - bfa data struct
+ *   @param[in] *bfa		- bfa data struct
  */
+bfa_status_t
+bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat,
+			bfa_cb_diag_t cbfn, void *cbarg)
+{
+	struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
+	struct bfa_dport_s *dport = &fcdiag->dport;
 
+	/*
+	 * Check to see if IOC is down
+	 */
+	if (!bfa_iocfc_is_operational(bfa))
+		return BFA_STATUS_IOC_NON_OP;
+
+	/*
+	 * Check if dport is in dynamic mode
+	 */
+	if (dport->dynamic)
+		return BFA_STATUS_DDPORT_ERR;
+
+	/*
+	 * Check if dport is busy
+	 */
+	if (bfa_dport_is_sending_req(dport))
+		return BFA_STATUS_DEVBUSY;
+
+	/*
+	 * Check if dport is in enabled state.
+	 * Test can only be restart when previous test has completed
+	 */
+	if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) {
+		bfa_trc(dport->bfa, 0);
+		return BFA_STATUS_DPORT_DISABLED;
+
+	} else {
+		if (dport->test_state == BFA_DPORT_ST_NO_SFP)
+			return BFA_STATUS_DPORT_INV_SFP;
+
+		if (dport->test_state == BFA_DPORT_ST_INP)
+			return BFA_STATUS_DEVBUSY;
+
+		WARN_ON(dport->test_state != BFA_DPORT_ST_COMP);
+	}
+
+	bfa_trc(dport->bfa, lpcnt);
+	bfa_trc(dport->bfa, pat);
+
+	dport->lpcnt = (lpcnt) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT;
+	dport->payload = (pat) ? pat : LB_PATTERN_DEFAULT;
+
+	dport->cbfn = cbfn;
+	dport->cbarg = cbarg;
+
+	bfa_sm_send_event(dport, BFA_DPORT_SM_START);
+	return BFA_STATUS_OK;
+}
+
+/*
+ * Dport show -- return dport test result
+ *
+ *   @param[in] *bfa		- bfa data struct
+ */
 bfa_status_t
-bfa_dport_get_state(struct bfa_s *bfa, enum bfa_dport_state *state)
+bfa_dport_show(struct bfa_s *bfa, struct bfa_diag_dport_result_s *result)
 {
 	struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
 	struct bfa_dport_s *dport = &fcdiag->dport;
 
-	if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabled))
-		*state = BFA_DPORT_ST_ENABLED;
-	else if (bfa_sm_cmp_state(dport, bfa_dport_sm_enabling) ||
-		 bfa_sm_cmp_state(dport, bfa_dport_sm_enabling_qwait))
-		*state = BFA_DPORT_ST_ENABLING;
-	else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabled))
-		*state = BFA_DPORT_ST_DISABLED;
-	else if (bfa_sm_cmp_state(dport, bfa_dport_sm_disabling) ||
-		 bfa_sm_cmp_state(dport, bfa_dport_sm_disabling_qwait))
-		*state = BFA_DPORT_ST_DISABLING;
-	else {
-		bfa_trc(dport->bfa, BFA_STATUS_EINVAL);
-		return BFA_STATUS_EINVAL;
+	/*
+	 * Check to see if IOC is down
+	 */
+	if (!bfa_iocfc_is_operational(bfa))
+		return BFA_STATUS_IOC_NON_OP;
+
+	/*
+	 * Check if dport is busy
+	 */
+	if (bfa_dport_is_sending_req(dport))
+		return BFA_STATUS_DEVBUSY;
+
+	/*
+	 * Check if dport is in enabled state.
+	 */
+	if (!bfa_sm_cmp_state(dport, bfa_dport_sm_enabled)) {
+		bfa_trc(dport->bfa, 0);
+		return BFA_STATUS_DPORT_DISABLED;
+
 	}
+
+	/*
+	 * Check if there is SFP
+	 */
+	if (dport->test_state == BFA_DPORT_ST_NO_SFP)
+		return BFA_STATUS_DPORT_INV_SFP;
+
+	memcpy(result, &dport->result, sizeof(struct bfa_diag_dport_result_s));
+
 	return BFA_STATUS_OK;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_svc.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_svc.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfa_svc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfa_svc.h	2013-08-25 20:43:22.000000000 -0400
@@ -405,8 +405,6 @@ struct bfa_lps_s {
 	bfa_status_t	status;		/*  login status		*/
 	u16		pdusz;		/*  max receive PDU size	*/
 	u16		pr_bbcred;	/*  BB_CREDIT from peer		*/
-	u8		pr_bbscn;	/*  BB_SCN from peer		*/
-	u8		bb_scn;		/*  local BB_SCN		*/
 	u8		lsrjt_rsn;	/*  LSRJT reason		*/
 	u8		lsrjt_expl;	/*  LSRJT explanation		*/
 	u8		lun_mask;	/*  LUN mask flag		*/
@@ -510,11 +508,12 @@ struct bfa_fcport_s {
 	bfa_boolean_t		diag_busy; /*  diag busy status */
 	bfa_boolean_t		beacon; /*  port beacon status */
 	bfa_boolean_t		link_e2e_beacon; /*  link beacon status */
-	bfa_boolean_t		bbsc_op_state;	/* Cred recov Oper State */
 	struct bfa_fcport_trunk_s trunk;
 	u16		fcoe_vlan;
 	struct bfa_mem_dma_s	fcport_dma;
 	bfa_boolean_t		stats_dma_ready;
+	struct bfa_bbcr_attr_s	bbcr_attr;
+	enum bfa_fec_state_s	fec_state;
 };
 
 #define BFA_FCPORT_MOD(__bfa)	(&(__bfa)->modules.fcport)
@@ -552,11 +551,12 @@ void bfa_fcport_event_register(struct bf
 			enum bfa_port_linkstate event), void *event_cbarg);
 bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
 bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa);
+bfa_boolean_t bfa_fcport_is_ddport(struct bfa_s *bfa);
 bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa,
 				   struct bfa_qos_bw_s *qos_bw);
 enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
 
-void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn);
+void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
 bfa_boolean_t     bfa_fcport_is_ratelim(struct bfa_s *bfa);
 void bfa_fcport_beacon(void *dev, bfa_boolean_t beacon,
 			bfa_boolean_t link_e2e_beacon);
@@ -571,6 +571,10 @@ void bfa_fcport_dportenable(struct bfa_s
 void bfa_fcport_dportdisable(struct bfa_s *bfa);
 bfa_status_t bfa_fcport_is_pbcdisabled(struct bfa_s *bfa);
 void bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state);
+bfa_status_t bfa_fcport_cfg_bbcr(struct bfa_s *bfa,
+			bfa_boolean_t on_off, u8 bb_scn);
+bfa_status_t bfa_fcport_get_bbcr_attr(struct bfa_s *bfa,
+			struct bfa_bbcr_attr_s *bbcr_attr);
 
 /*
  * bfa rport API functions
@@ -667,7 +671,7 @@ struct bfa_lps_s *bfa_lps_alloc(struct b
 void bfa_lps_delete(struct bfa_lps_s *lps);
 void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa,
 		   u16 pdusz, wwn_t pwwn, wwn_t nwwn,
-		   bfa_boolean_t auth_en, u8 bb_scn);
+		   bfa_boolean_t auth_en);
 void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz,
 		   wwn_t pwwn, wwn_t nwwn);
 void bfa_lps_fdisclogo(struct bfa_lps_s *lps);
@@ -712,10 +716,18 @@ struct bfa_fcdiag_lb_s {
 struct bfa_dport_s {
 	struct bfa_s	*bfa;		/* Back pointer to BFA	*/
 	bfa_sm_t	sm;		/* finite state machine */
-	u32		msgtag;		/* firmware msg tag for reply */
 	struct bfa_reqq_wait_s reqq_wait;
 	bfa_cb_diag_t	cbfn;
 	void		*cbarg;
+	union bfi_diag_dport_msg_u i2hmsg;
+	u8		test_state;	/* enum dport_test_state  */
+	u8		dynamic;	/* boolean_t  */
+	u8		rsvd[2];
+	u32		lpcnt;
+	u32		payload;	/* user defined payload pattern */
+	wwn_t		rp_pwwn;
+	wwn_t		rp_nwwn;
+	struct bfa_diag_dport_result_s result;
 };
 
 struct bfa_fcdiag_s {
@@ -739,11 +751,13 @@ bfa_status_t	bfa_fcdiag_queuetest(struct
 			u32 queue, struct bfa_diag_qtest_result_s *result,
 			bfa_cb_diag_t cbfn, void *cbarg);
 bfa_status_t	bfa_fcdiag_lb_is_running(struct bfa_s *bfa);
-bfa_status_t	bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn,
-				 void *cbarg);
+bfa_status_t	bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat,
+					bfa_cb_diag_t cbfn, void *cbarg);
 bfa_status_t	bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn,
 				  void *cbarg);
-bfa_status_t	bfa_dport_get_state(struct bfa_s *bfa,
-				    enum bfa_dport_state *state);
+bfa_status_t	bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat,
+				bfa_cb_diag_t cbfn, void *cbarg);
+bfa_status_t	bfa_dport_show(struct bfa_s *bfa,
+				struct bfa_diag_dport_result_s *result);
 
 #endif /* __BFA_SVC_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfi.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfi.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfi.h	2013-08-25 20:43:22.000000000 -0400
@@ -264,6 +264,7 @@ struct bfi_ioc_getattr_req_s {
 	union bfi_addr_u	attr_addr;
 };
 
+#define BFI_IOC_ATTR_UUID_SZ	16
 struct bfi_ioc_attr_s {
 	wwn_t		mfg_pwwn;	/*  Mfg port wwn	   */
 	wwn_t		mfg_nwwn;	/*  Mfg node wwn	   */
@@ -292,6 +293,7 @@ struct bfi_ioc_attr_s {
 	u8	mfg_day;	/* manufacturing day */
 	u8	mfg_month;	/* manufacturing month */
 	u16	mfg_year;	/* manufacturing year */
+	u8	uuid[BFI_IOC_ATTR_UUID_SZ];	/*!< chinook uuid */
 };
 
 /*
@@ -374,6 +376,10 @@ enum bfi_ioc_state {
 	BFI_IOC_MEMTEST		= 9,	/*  IOC is doing memtest	     */
 };
 
+#define BFA_IOC_CB_JOIN_SH	16
+#define BFA_IOC_CB_FWSTATE_MASK	0x0000ffff
+#define BFA_IOC_CB_JOIN_MASK	0xffff0000
+
 #define BFI_IOC_ENDIAN_SIG  0x12345678
 
 enum {
@@ -973,6 +979,7 @@ enum bfi_diag_i2h {
 	BFI_DIAG_I2H_LEDTEST = BFA_I2HM(BFI_DIAG_H2I_LEDTEST),
 	BFI_DIAG_I2H_QTEST      = BFA_I2HM(BFI_DIAG_H2I_QTEST),
 	BFI_DIAG_I2H_DPORT	= BFA_I2HM(BFI_DIAG_H2I_DPORT),
+	BFI_DIAG_I2H_DPORT_SCN	= BFA_I2HM(8),
 };
 
 #define BFI_DIAG_MAX_SGES	2
@@ -1064,16 +1071,73 @@ struct bfi_diag_qtest_req_s {
 enum bfi_dport_req {
 	BFI_DPORT_DISABLE	= 0,	/* disable dport request	*/
 	BFI_DPORT_ENABLE	= 1,	/* enable dport request		*/
+	BFI_DPORT_START		= 2,	/* start dport request	*/
+	BFI_DPORT_SHOW		= 3,	/* show dport request	*/
+	BFI_DPORT_DYN_DISABLE	= 4,	/* disable dynamic dport request */
+};
+
+enum bfi_dport_scn {
+	BFI_DPORT_SCN_TESTSTART		= 1,
+	BFI_DPORT_SCN_TESTCOMP		= 2,
+	BFI_DPORT_SCN_SFP_REMOVED	= 3,
+	BFI_DPORT_SCN_DDPORT_ENABLE	= 4,
+	BFI_DPORT_SCN_DDPORT_DISABLE	= 5,
+	BFI_DPORT_SCN_FCPORT_DISABLE	= 6,
+	BFI_DPORT_SCN_SUBTESTSTART	= 7,
+	BFI_DPORT_SCN_TESTSKIP		= 8,
+	BFI_DPORT_SCN_DDPORT_DISABLED	= 9,
 };
 
 struct bfi_diag_dport_req_s {
 	struct bfi_mhdr_s	mh;	/* 4 bytes                      */
-	u8			req;    /* request 1: enable 0: disable */
-	u8			status; /* reply status			*/
-	u8			rsvd[2];
-	u32			msgtag; /* msgtag for reply		*/
+	u8			req;	/* request 1: enable 0: disable	*/
+	u8			rsvd[3];
+	u32			lpcnt;
+	u32			payload;
+};
+
+struct bfi_diag_dport_rsp_s {
+	struct bfi_mhdr_s	mh;	/* header 4 bytes		*/
+	bfa_status_t		status;	/* reply status			*/
+	wwn_t			pwwn;	/* switch port wwn. 8 bytes	*/
+	wwn_t			nwwn;	/* switch node wwn. 8 bytes	*/
+};
+
+struct bfi_diag_dport_scn_teststart_s {
+	wwn_t	pwwn;	/* switch port wwn. 8 bytes */
+	wwn_t	nwwn;	/* switch node wwn. 8 bytes */
+	u8	type;	/* bfa_diag_dport_test_type_e */
+	u8	rsvd[3];
+	u32	numfrm; /* from switch uint in 1M */
+};
+
+struct bfi_diag_dport_scn_testcomp_s {
+	u8	status; /* bfa_diag_dport_test_status_e */
+	u8	speed;  /* bfa_port_speed_t  */
+	u16	numbuffer; /* from switch  */
+	u8	subtest_status[DPORT_TEST_MAX];  /* 4 bytes */
+	u32	latency;   /* from switch  */
+	u32	distance;  /* from swtich unit in meters  */
+			/* Buffers required to saturate the link */
+	u16	frm_sz;	/* from switch for buf_reqd */
+	u8	rsvd[2];
+};
+
+struct bfi_diag_dport_scn_s {		/* max size == RDS_RMESZ	*/
+	struct bfi_mhdr_s	mh;	/* header 4 bytes		*/
+	u8			state;  /* new state			*/
+	u8			rsvd[3];
+	union {
+		struct bfi_diag_dport_scn_teststart_s teststart;
+		struct bfi_diag_dport_scn_testcomp_s testcomp;
+	} info;
+};
+
+union bfi_diag_dport_msg_u {
+	struct bfi_diag_dport_req_s	req;
+	struct bfi_diag_dport_rsp_s	rsp;
+	struct bfi_diag_dport_scn_s	scn;
 };
-#define bfi_diag_dport_rsp_t struct bfi_diag_dport_req_s
 
 /*
  *	PHY module specific
@@ -1191,7 +1255,9 @@ enum bfi_fru_i2h_msgs {
 struct bfi_fru_write_req_s {
 	struct bfi_mhdr_s	mh;	/* Common msg header */
 	u8			last;
-	u8			rsv[3];
+	u8			rsv_1[3];
+	u8			trfr_cmpl;
+	u8			rsv_2[3];
 	u32			offset;
 	u32			length;
 	struct bfi_alen_s	alen;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/bfa/bfi_ms.h linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfi_ms.h
--- linux-libre-3.10-gnu/drivers/scsi/bfa/bfi_ms.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/bfa/bfi_ms.h	2013-08-25 20:43:22.000000000 -0400
@@ -276,8 +276,7 @@ struct bfi_fcport_enable_req_s {
 struct bfi_fcport_set_svc_params_req_s {
 	struct bfi_mhdr_s  mh;		/*  msg header */
 	__be16	   tx_bbcredit;	/*  Tx credits */
-	u8	bb_scn;		/* BB_SC FC credit recovery */
-	u8	rsvd;
+	u8	rsvd[2];
 };
 
 /*
@@ -446,8 +445,8 @@ struct bfi_lps_login_rsp_s {
 	mac_t		fcf_mac;
 	u8		ext_status;
 	u8		brcd_switch;	/*  attached peer is brcd switch */
-	u8		bb_scn;		/* atatched port's bb_scn */
 	u8		bfa_tag;
+	u8		rsvd;
 };
 
 struct bfi_lps_logout_req_s {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/BusLogic.c linux-libre-3.11-rc7-gnu/drivers/scsi/BusLogic.c
--- linux-libre-3.10-gnu/drivers/scsi/BusLogic.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/BusLogic.c	2013-08-25 20:43:22.000000000 -0400
@@ -26,8 +26,8 @@
 
 */
 
-#define BusLogic_DriverVersion		"2.1.16"
-#define BusLogic_DriverDate		"18 July 2002"
+#define blogic_drvr_version		"2.1.16"
+#define blogic_drvr_date		"18 July 2002"
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -60,24 +60,24 @@
 #define FAILURE (-1)
 #endif
 
-static struct scsi_host_template Bus_Logic_template;
+static struct scsi_host_template blogic_template;
 
 /*
-  BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
+  blogic_drvr_options_count is a count of the number of BusLogic Driver
   Options specifications provided via the Linux Kernel Command Line or via
   the Loadable Kernel Module Installation Facility.
 */
 
-static int BusLogic_DriverOptionsCount;
+static int blogic_drvr_options_count;
 
 
 /*
-  BusLogic_DriverOptions is an array of Driver Options structures representing
+  blogic_drvr_options is an array of Driver Options structures representing
   BusLogic Driver Options specifications provided via the Linux Kernel Command
   Line or via the Loadable Kernel Module Installation Facility.
 */
 
-static struct BusLogic_DriverOptions BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
+static struct blogic_drvr_options blogic_drvr_options[BLOGIC_MAX_ADAPTERS];
 
 
 /*
@@ -92,241 +92,251 @@ module_param(BusLogic, charp, 0);
 
 
 /*
-  BusLogic_ProbeOptions is a set of Probe Options to be applied across
+  blogic_probe_options is a set of Probe Options to be applied across
   all BusLogic Host Adapters.
 */
 
-static struct BusLogic_ProbeOptions BusLogic_ProbeOptions;
+static struct blogic_probe_options blogic_probe_options;
 
 
 /*
-  BusLogic_GlobalOptions is a set of Global Options to be applied across
+  blogic_global_options is a set of Global Options to be applied across
   all BusLogic Host Adapters.
 */
 
-static struct BusLogic_GlobalOptions BusLogic_GlobalOptions;
+static struct blogic_global_options blogic_global_options;
 
-static LIST_HEAD(BusLogic_host_list);
+static LIST_HEAD(blogic_host_list);
 
 /*
-  BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
+  blogic_probeinfo_count is the number of entries in blogic_probeinfo_list.
 */
 
-static int BusLogic_ProbeInfoCount;
+static int blogic_probeinfo_count;
 
 
 /*
-  BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
+  blogic_probeinfo_list is the list of I/O Addresses and Bus Probe Information
   to be checked for potential BusLogic Host Adapters.  It is initialized by
   interrogating the PCI Configuration Space on PCI machines as well as from the
   list of standard BusLogic I/O Addresses.
 */
 
-static struct BusLogic_ProbeInfo *BusLogic_ProbeInfoList;
+static struct blogic_probeinfo *blogic_probeinfo_list;
 
 
 /*
-  BusLogic_CommandFailureReason holds a string identifying the reason why a
-  call to BusLogic_Command failed.  It is only non-NULL when BusLogic_Command
+  blogic_cmd_failure_reason holds a string identifying the reason why a
+  call to blogic_cmd failed.  It is only non-NULL when blogic_cmd
   returns a failure code.
 */
 
-static char *BusLogic_CommandFailureReason;
+static char *blogic_cmd_failure_reason;
 
 /*
-  BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
+  blogic_announce_drvr announces the Driver Version and Date, Author's
   Name, Copyright Notice, and Electronic Mail Address.
 */
 
-static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter)
+static void blogic_announce_drvr(struct blogic_adapter *adapter)
 {
-	BusLogic_Announce("***** BusLogic SCSI Driver Version " BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n", HostAdapter);
-	BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff " "<lnz@dandelion.com>\n", HostAdapter);
+	blogic_announce("***** BusLogic SCSI Driver Version " blogic_drvr_version " of " blogic_drvr_date " *****\n", adapter);
+	blogic_announce("Copyright 1995-1998 by Leonard N. Zubkoff " "<lnz@dandelion.com>\n", adapter);
 }
 
 
 /*
-  BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
+  blogic_drvr_info returns the Host Adapter Name to identify this SCSI
   Driver and Host Adapter.
 */
 
-static const char *BusLogic_DriverInfo(struct Scsi_Host *Host)
+static const char *blogic_drvr_info(struct Scsi_Host *host)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
-	return HostAdapter->FullModelName;
+	struct blogic_adapter *adapter =
+				(struct blogic_adapter *) host->hostdata;
+	return adapter->full_model;
 }
 
 /*
-  BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
-  for Host Adapter from the BlockSize bytes located at BlockPointer.  The newly
+  blogic_init_ccbs initializes a group of Command Control Blocks (CCBs)
+  for Host Adapter from the blk_size bytes located at blk_pointer.  The newly
   created CCBs are added to Host Adapter's free list.
 */
 
-static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, void *BlockPointer, int BlockSize, dma_addr_t BlockPointerHandle)
+static void blogic_init_ccbs(struct blogic_adapter *adapter, void *blk_pointer,
+				int blk_size, dma_addr_t blkp)
 {
-	struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) BlockPointer;
+	struct blogic_ccb *ccb = (struct blogic_ccb *) blk_pointer;
 	unsigned int offset = 0;
-	memset(BlockPointer, 0, BlockSize);
-	CCB->AllocationGroupHead = BlockPointerHandle;
-	CCB->AllocationGroupSize = BlockSize;
-	while ((BlockSize -= sizeof(struct BusLogic_CCB)) >= 0) {
-		CCB->Status = BusLogic_CCB_Free;
-		CCB->HostAdapter = HostAdapter;
-		CCB->DMA_Handle = (u32) BlockPointerHandle + offset;
-		if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
-			CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
-			CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
+	memset(blk_pointer, 0, blk_size);
+	ccb->allocgrp_head = blkp;
+	ccb->allocgrp_size = blk_size;
+	while ((blk_size -= sizeof(struct blogic_ccb)) >= 0) {
+		ccb->status = BLOGIC_CCB_FREE;
+		ccb->adapter = adapter;
+		ccb->dma_handle = (u32) blkp + offset;
+		if (blogic_flashpoint_type(adapter)) {
+			ccb->callback = blogic_qcompleted_ccb;
+			ccb->base_addr = adapter->fpinfo.base_addr;
 		}
-		CCB->Next = HostAdapter->Free_CCBs;
-		CCB->NextAll = HostAdapter->All_CCBs;
-		HostAdapter->Free_CCBs = CCB;
-		HostAdapter->All_CCBs = CCB;
-		HostAdapter->AllocatedCCBs++;
-		CCB++;
-		offset += sizeof(struct BusLogic_CCB);
+		ccb->next = adapter->free_ccbs;
+		ccb->next_all = adapter->all_ccbs;
+		adapter->free_ccbs = ccb;
+		adapter->all_ccbs = ccb;
+		adapter->alloc_ccbs++;
+		ccb++;
+		offset += sizeof(struct blogic_ccb);
 	}
 }
 
 
 /*
-  BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
+  blogic_create_initccbs allocates the initial CCBs for Host Adapter.
 */
 
-static bool __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter)
+static bool __init blogic_create_initccbs(struct blogic_adapter *adapter)
 {
-	int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
-	void *BlockPointer;
-	dma_addr_t BlockPointerHandle;
-	while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs) {
-		BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle);
-		if (BlockPointer == NULL) {
-			BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n", HostAdapter);
+	int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
+	void *blk_pointer;
+	dma_addr_t blkp;
+
+	while (adapter->alloc_ccbs < adapter->initccbs) {
+		blk_pointer = pci_alloc_consistent(adapter->pci_device,
+							blk_size, &blkp);
+		if (blk_pointer == NULL) {
+			blogic_err("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
+					adapter);
 			return false;
 		}
-		BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle);
+		blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
 	}
 	return true;
 }
 
 
 /*
-  BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
+  blogic_destroy_ccbs deallocates the CCBs for Host Adapter.
 */
 
-static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter)
+static void blogic_destroy_ccbs(struct blogic_adapter *adapter)
 {
-	struct BusLogic_CCB *NextCCB = HostAdapter->All_CCBs, *CCB, *Last_CCB = NULL;
-	HostAdapter->All_CCBs = NULL;
-	HostAdapter->Free_CCBs = NULL;
-	while ((CCB = NextCCB) != NULL) {
-		NextCCB = CCB->NextAll;
-		if (CCB->AllocationGroupHead) {
-			if (Last_CCB)
-				pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead);
-			Last_CCB = CCB;
+	struct blogic_ccb *next_ccb = adapter->all_ccbs, *ccb, *lastccb = NULL;
+	adapter->all_ccbs = NULL;
+	adapter->free_ccbs = NULL;
+	while ((ccb = next_ccb) != NULL) {
+		next_ccb = ccb->next_all;
+		if (ccb->allocgrp_head) {
+			if (lastccb)
+				pci_free_consistent(adapter->pci_device,
+						lastccb->allocgrp_size, lastccb,
+						lastccb->allocgrp_head);
+			lastccb = ccb;
 		}
 	}
-	if (Last_CCB)
-		pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead);
+	if (lastccb)
+		pci_free_consistent(adapter->pci_device, lastccb->allocgrp_size,
+					lastccb, lastccb->allocgrp_head);
 }
 
 
 /*
-  BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter.  If
+  blogic_create_addlccbs allocates Additional CCBs for Host Adapter.  If
   allocation fails and there are no remaining CCBs available, the Driver Queue
   Depth is decreased to a known safe value to avoid potential deadlocks when
   multiple host adapters share the same IRQ Channel.
 */
 
-static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, bool SuccessMessageP)
+static void blogic_create_addlccbs(struct blogic_adapter *adapter,
+					int addl_ccbs, bool print_success)
 {
-	int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
-	int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
-	void *BlockPointer;
-	dma_addr_t BlockPointerHandle;
-	if (AdditionalCCBs <= 0)
+	int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
+	int prev_alloc = adapter->alloc_ccbs;
+	void *blk_pointer;
+	dma_addr_t blkp;
+	if (addl_ccbs <= 0)
 		return;
-	while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs) {
-		BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle);
-		if (BlockPointer == NULL)
+	while (adapter->alloc_ccbs - prev_alloc < addl_ccbs) {
+		blk_pointer = pci_alloc_consistent(adapter->pci_device,
+							blk_size, &blkp);
+		if (blk_pointer == NULL)
 			break;
-		BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle);
+		blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
 	}
-	if (HostAdapter->AllocatedCCBs > PreviouslyAllocated) {
-		if (SuccessMessageP)
-			BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n", HostAdapter, HostAdapter->AllocatedCCBs - PreviouslyAllocated, HostAdapter->AllocatedCCBs);
+	if (adapter->alloc_ccbs > prev_alloc) {
+		if (print_success)
+			blogic_notice("Allocated %d additional CCBs (total now %d)\n", adapter, adapter->alloc_ccbs - prev_alloc, adapter->alloc_ccbs);
 		return;
 	}
-	BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
-	if (HostAdapter->DriverQueueDepth > HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount) {
-		HostAdapter->DriverQueueDepth = HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
-		HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
+	blogic_notice("Failed to allocate additional CCBs\n", adapter);
+	if (adapter->drvr_qdepth > adapter->alloc_ccbs - adapter->tgt_count) {
+		adapter->drvr_qdepth = adapter->alloc_ccbs - adapter->tgt_count;
+		adapter->scsi_host->can_queue = adapter->drvr_qdepth;
 	}
 }
 
 /*
-  BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
+  blogic_alloc_ccb allocates a CCB from Host Adapter's free list,
   allocating more memory from the Kernel if necessary.  The Host Adapter's
   Lock should already have been acquired by the caller.
 */
 
-static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter
-						 *HostAdapter)
+static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
 {
-	static unsigned long SerialNumber = 0;
-	struct BusLogic_CCB *CCB;
-	CCB = HostAdapter->Free_CCBs;
-	if (CCB != NULL) {
-		CCB->SerialNumber = ++SerialNumber;
-		HostAdapter->Free_CCBs = CCB->Next;
-		CCB->Next = NULL;
-		if (HostAdapter->Free_CCBs == NULL)
-			BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true);
-		return CCB;
+	static unsigned long serial;
+	struct blogic_ccb *ccb;
+	ccb = adapter->free_ccbs;
+	if (ccb != NULL) {
+		ccb->serial = ++serial;
+		adapter->free_ccbs = ccb->next;
+		ccb->next = NULL;
+		if (adapter->free_ccbs == NULL)
+			blogic_create_addlccbs(adapter, adapter->inc_ccbs,
+						true);
+		return ccb;
 	}
-	BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true);
-	CCB = HostAdapter->Free_CCBs;
-	if (CCB == NULL)
+	blogic_create_addlccbs(adapter, adapter->inc_ccbs, true);
+	ccb = adapter->free_ccbs;
+	if (ccb == NULL)
 		return NULL;
-	CCB->SerialNumber = ++SerialNumber;
-	HostAdapter->Free_CCBs = CCB->Next;
-	CCB->Next = NULL;
-	return CCB;
+	ccb->serial = ++serial;
+	adapter->free_ccbs = ccb->next;
+	ccb->next = NULL;
+	return ccb;
 }
 
 
 /*
-  BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
+  blogic_dealloc_ccb deallocates a CCB, returning it to the Host Adapter's
   free list.  The Host Adapter's Lock should already have been acquired by the
   caller.
 */
 
-static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB)
+static void blogic_dealloc_ccb(struct blogic_ccb *ccb)
 {
-	struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
+	struct blogic_adapter *adapter = ccb->adapter;
 
-	scsi_dma_unmap(CCB->Command);
-	pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer,
-			 CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
+	scsi_dma_unmap(ccb->command);
+	pci_unmap_single(adapter->pci_device, ccb->sensedata,
+			 ccb->sense_datalen, PCI_DMA_FROMDEVICE);
 
-	CCB->Command = NULL;
-	CCB->Status = BusLogic_CCB_Free;
-	CCB->Next = HostAdapter->Free_CCBs;
-	HostAdapter->Free_CCBs = CCB;
+	ccb->command = NULL;
+	ccb->status = BLOGIC_CCB_FREE;
+	ccb->next = adapter->free_ccbs;
+	adapter->free_ccbs = ccb;
 }
 
 
 /*
-  BusLogic_Command sends the command OperationCode to HostAdapter, optionally
-  providing ParameterLength bytes of ParameterData and receiving at most
-  ReplyLength bytes of ReplyData; any excess reply data is received but
+  blogic_cmd sends the command opcode to adapter, optionally
+  providing paramlen bytes of param and receiving at most
+  replylen bytes of reply; any excess reply data is received but
   discarded.
 
   On success, this function returns the number of reply bytes read from
   the Host Adapter (including any discarded data); on failure, it returns
   -1 if the command was invalid, or -2 if a timeout occurred.
 
-  BusLogic_Command is called exclusively during host adapter detection and
+  blogic_cmd is called exclusively during host adapter detection and
   initialization, so performance and latency are not critical, and exclusive
   access to the Host Adapter hardware is assumed.  Once the host adapter and
   driver are initialized, the only Host Adapter command that is issued is the
@@ -334,255 +344,274 @@ static void BusLogic_DeallocateCCB(struc
   waiting for the Host Adapter Ready bit to be set in the Status Register.
 */
 
-static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_OperationCode OperationCode, void *ParameterData, int ParameterLength, void *ReplyData, int ReplyLength)
+static int blogic_cmd(struct blogic_adapter *adapter, enum blogic_opcode opcode,
+			void *param, int paramlen, void *reply, int replylen)
 {
-	unsigned char *ParameterPointer = (unsigned char *) ParameterData;
-	unsigned char *ReplyPointer = (unsigned char *) ReplyData;
-	union BusLogic_StatusRegister StatusRegister;
-	union BusLogic_InterruptRegister InterruptRegister;
-	unsigned long ProcessorFlags = 0;
-	int ReplyBytes = 0, Result;
-	long TimeoutCounter;
+	unsigned char *param_p = (unsigned char *) param;
+	unsigned char *reply_p = (unsigned char *) reply;
+	union blogic_stat_reg statusreg;
+	union blogic_int_reg intreg;
+	unsigned long processor_flag = 0;
+	int reply_b = 0, result;
+	long timeout;
 	/*
 	   Clear out the Reply Data if provided.
 	 */
-	if (ReplyLength > 0)
-		memset(ReplyData, 0, ReplyLength);
+	if (replylen > 0)
+		memset(reply, 0, replylen);
 	/*
-	   If the IRQ Channel has not yet been acquired, then interrupts must be
-	   disabled while issuing host adapter commands since a Command Complete
-	   interrupt could occur if the IRQ Channel was previously enabled by another
-	   BusLogic Host Adapter or another driver sharing the same IRQ Channel.
+	   If the IRQ Channel has not yet been acquired, then interrupts
+	   must be disabled while issuing host adapter commands since a
+	   Command Complete interrupt could occur if the IRQ Channel was
+	   previously enabled by another BusLogic Host Adapter or another
+	   driver sharing the same IRQ Channel.
 	 */
-	if (!HostAdapter->IRQ_ChannelAcquired)
-		local_irq_save(ProcessorFlags);
+	if (!adapter->irq_acquired)
+		local_irq_save(processor_flag);
 	/*
-	   Wait for the Host Adapter Ready bit to be set and the Command/Parameter
-	   Register Busy bit to be reset in the Status Register.
+	   Wait for the Host Adapter Ready bit to be set and the
+	   Command/Parameter Register Busy bit to be reset in the Status
+	   Register.
 	 */
-	TimeoutCounter = 10000;
-	while (--TimeoutCounter >= 0) {
-		StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
-		if (StatusRegister.sr.HostAdapterReady && !StatusRegister.sr.CommandParameterRegisterBusy)
+	timeout = 10000;
+	while (--timeout >= 0) {
+		statusreg.all = blogic_rdstatus(adapter);
+		if (statusreg.sr.adapter_ready && !statusreg.sr.cmd_param_busy)
 			break;
 		udelay(100);
 	}
-	if (TimeoutCounter < 0) {
-		BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
-		Result = -2;
-		goto Done;
+	if (timeout < 0) {
+		blogic_cmd_failure_reason =
+				"Timeout waiting for Host Adapter Ready";
+		result = -2;
+		goto done;
 	}
 	/*
-	   Write the OperationCode to the Command/Parameter Register.
+	   Write the opcode to the Command/Parameter Register.
 	 */
-	HostAdapter->HostAdapterCommandCompleted = false;
-	BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
+	adapter->adapter_cmd_complete = false;
+	blogic_setcmdparam(adapter, opcode);
 	/*
 	   Write any additional Parameter Bytes.
 	 */
-	TimeoutCounter = 10000;
-	while (ParameterLength > 0 && --TimeoutCounter >= 0) {
+	timeout = 10000;
+	while (paramlen > 0 && --timeout >= 0) {
 		/*
-		   Wait 100 microseconds to give the Host Adapter enough time to determine
-		   whether the last value written to the Command/Parameter Register was
-		   valid or not.  If the Command Complete bit is set in the Interrupt
-		   Register, then the Command Invalid bit in the Status Register will be
-		   reset if the Operation Code or Parameter was valid and the command
-		   has completed, or set if the Operation Code or Parameter was invalid.
-		   If the Data In Register Ready bit is set in the Status Register, then
-		   the Operation Code was valid, and data is waiting to be read back
-		   from the Host Adapter.  Otherwise, wait for the Command/Parameter
-		   Register Busy bit in the Status Register to be reset.
+		   Wait 100 microseconds to give the Host Adapter enough
+		   time to determine whether the last value written to the
+		   Command/Parameter Register was valid or not. If the
+		   Command Complete bit is set in the Interrupt Register,
+		   then the Command Invalid bit in the Status Register will
+		   be reset if the Operation Code or Parameter was valid
+		   and the command has completed, or set if the Operation
+		   Code or Parameter was invalid. If the Data In Register
+		   Ready bit is set in the Status Register, then the
+		   Operation Code was valid, and data is waiting to be read
+		   back from the Host Adapter. Otherwise, wait for the
+		   Command/Parameter Register Busy bit in the Status
+		   Register to be reset.
 		 */
 		udelay(100);
-		InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
-		StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
-		if (InterruptRegister.ir.CommandComplete)
+		intreg.all = blogic_rdint(adapter);
+		statusreg.all = blogic_rdstatus(adapter);
+		if (intreg.ir.cmd_complete)
 			break;
-		if (HostAdapter->HostAdapterCommandCompleted)
+		if (adapter->adapter_cmd_complete)
 			break;
-		if (StatusRegister.sr.DataInRegisterReady)
+		if (statusreg.sr.datain_ready)
 			break;
-		if (StatusRegister.sr.CommandParameterRegisterBusy)
+		if (statusreg.sr.cmd_param_busy)
 			continue;
-		BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
-		ParameterLength--;
+		blogic_setcmdparam(adapter, *param_p++);
+		paramlen--;
 	}
-	if (TimeoutCounter < 0) {
-		BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance";
-		Result = -2;
-		goto Done;
+	if (timeout < 0) {
+		blogic_cmd_failure_reason =
+				"Timeout waiting for Parameter Acceptance";
+		result = -2;
+		goto done;
 	}
 	/*
-	   The Modify I/O Address command does not cause a Command Complete Interrupt.
+	   The Modify I/O Address command does not cause a Command Complete
+	   Interrupt.
 	 */
-	if (OperationCode == BusLogic_ModifyIOAddress) {
-		StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
-		if (StatusRegister.sr.CommandInvalid) {
-			BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
-			Result = -1;
-			goto Done;
+	if (opcode == BLOGIC_MOD_IOADDR) {
+		statusreg.all = blogic_rdstatus(adapter);
+		if (statusreg.sr.cmd_invalid) {
+			blogic_cmd_failure_reason =
+					"Modify I/O Address Invalid";
+			result = -1;
+			goto done;
 		}
-		if (BusLogic_GlobalOptions.TraceConfiguration)
-			BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: " "(Modify I/O Address)\n", HostAdapter, OperationCode, StatusRegister.All);
-		Result = 0;
-		goto Done;
+		if (blogic_global_options.trace_config)
+			blogic_notice("blogic_cmd(%02X) Status = %02X: " "(Modify I/O Address)\n", adapter, opcode, statusreg.all);
+		result = 0;
+		goto done;
 	}
 	/*
 	   Select an appropriate timeout value for awaiting command completion.
 	 */
-	switch (OperationCode) {
-	case BusLogic_InquireInstalledDevicesID0to7:
-	case BusLogic_InquireInstalledDevicesID8to15:
-	case BusLogic_InquireTargetDevices:
+	switch (opcode) {
+	case BLOGIC_INQ_DEV0TO7:
+	case BLOGIC_INQ_DEV8TO15:
+	case BLOGIC_INQ_DEV:
 		/* Approximately 60 seconds. */
-		TimeoutCounter = 60 * 10000;
+		timeout = 60 * 10000;
 		break;
 	default:
 		/* Approximately 1 second. */
-		TimeoutCounter = 10000;
+		timeout = 10000;
 		break;
 	}
 	/*
-	   Receive any Reply Bytes, waiting for either the Command Complete bit to
-	   be set in the Interrupt Register, or for the Interrupt Handler to set the
-	   Host Adapter Command Completed bit in the Host Adapter structure.
+	   Receive any Reply Bytes, waiting for either the Command
+	   Complete bit to be set in the Interrupt Register, or for the
+	   Interrupt Handler to set the Host Adapter Command Completed
+	   bit in the Host Adapter structure.
 	 */
-	while (--TimeoutCounter >= 0) {
-		InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
-		StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
-		if (InterruptRegister.ir.CommandComplete)
+	while (--timeout >= 0) {
+		intreg.all = blogic_rdint(adapter);
+		statusreg.all = blogic_rdstatus(adapter);
+		if (intreg.ir.cmd_complete)
 			break;
-		if (HostAdapter->HostAdapterCommandCompleted)
+		if (adapter->adapter_cmd_complete)
 			break;
-		if (StatusRegister.sr.DataInRegisterReady) {
-			if (++ReplyBytes <= ReplyLength)
-				*ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
+		if (statusreg.sr.datain_ready) {
+			if (++reply_b <= replylen)
+				*reply_p++ = blogic_rddatain(adapter);
 			else
-				BusLogic_ReadDataInRegister(HostAdapter);
+				blogic_rddatain(adapter);
 		}
-		if (OperationCode == BusLogic_FetchHostAdapterLocalRAM && StatusRegister.sr.HostAdapterReady)
+		if (opcode == BLOGIC_FETCH_LOCALRAM &&
+				statusreg.sr.adapter_ready)
 			break;
 		udelay(100);
 	}
-	if (TimeoutCounter < 0) {
-		BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
-		Result = -2;
-		goto Done;
+	if (timeout < 0) {
+		blogic_cmd_failure_reason =
+					"Timeout waiting for Command Complete";
+		result = -2;
+		goto done;
 	}
 	/*
 	   Clear any pending Command Complete Interrupt.
 	 */
-	BusLogic_InterruptReset(HostAdapter);
+	blogic_intreset(adapter);
 	/*
 	   Provide tracing information if requested.
 	 */
-	if (BusLogic_GlobalOptions.TraceConfiguration) {
+	if (blogic_global_options.trace_config) {
 		int i;
-		BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:", HostAdapter, OperationCode, StatusRegister.All, ReplyLength, ReplyBytes);
-		if (ReplyLength > ReplyBytes)
-			ReplyLength = ReplyBytes;
-		for (i = 0; i < ReplyLength; i++)
-			BusLogic_Notice(" %02X", HostAdapter, ((unsigned char *) ReplyData)[i]);
-		BusLogic_Notice("\n", HostAdapter);
+		blogic_notice("blogic_cmd(%02X) Status = %02X: %2d ==> %2d:",
+				adapter, opcode, statusreg.all, replylen,
+				reply_b);
+		if (replylen > reply_b)
+			replylen = reply_b;
+		for (i = 0; i < replylen; i++)
+			blogic_notice(" %02X", adapter,
+					((unsigned char *) reply)[i]);
+		blogic_notice("\n", adapter);
 	}
 	/*
 	   Process Command Invalid conditions.
 	 */
-	if (StatusRegister.sr.CommandInvalid) {
+	if (statusreg.sr.cmd_invalid) {
 		/*
-		   Some early BusLogic Host Adapters may not recover properly from
-		   a Command Invalid condition, so if this appears to be the case,
-		   a Soft Reset is issued to the Host Adapter.  Potentially invalid
-		   commands are never attempted after Mailbox Initialization is
-		   performed, so there should be no Host Adapter state lost by a
+		   Some early BusLogic Host Adapters may not recover
+		   properly from a Command Invalid condition, so if this
+		   appears to be the case, a Soft Reset is issued to the
+		   Host Adapter.  Potentially invalid commands are never
+		   attempted after Mailbox Initialization is performed,
+		   so there should be no Host Adapter state lost by a
 		   Soft Reset in response to a Command Invalid condition.
 		 */
 		udelay(1000);
-		StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
-		if (StatusRegister.sr.CommandInvalid ||
-		    StatusRegister.sr.Reserved ||
-		    StatusRegister.sr.DataInRegisterReady ||
-		    StatusRegister.sr.CommandParameterRegisterBusy || !StatusRegister.sr.HostAdapterReady || !StatusRegister.sr.InitializationRequired || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.DiagnosticFailure) {
-			BusLogic_SoftReset(HostAdapter);
+		statusreg.all = blogic_rdstatus(adapter);
+		if (statusreg.sr.cmd_invalid || statusreg.sr.rsvd ||
+				statusreg.sr.datain_ready ||
+				statusreg.sr.cmd_param_busy ||
+				!statusreg.sr.adapter_ready ||
+				!statusreg.sr.init_reqd ||
+				statusreg.sr.diag_active ||
+				statusreg.sr.diag_failed) {
+			blogic_softreset(adapter);
 			udelay(1000);
 		}
-		BusLogic_CommandFailureReason = "Command Invalid";
-		Result = -1;
-		goto Done;
+		blogic_cmd_failure_reason = "Command Invalid";
+		result = -1;
+		goto done;
 	}
 	/*
 	   Handle Excess Parameters Supplied conditions.
 	 */
-	if (ParameterLength > 0) {
-		BusLogic_CommandFailureReason = "Excess Parameters Supplied";
-		Result = -1;
-		goto Done;
+	if (paramlen > 0) {
+		blogic_cmd_failure_reason = "Excess Parameters Supplied";
+		result = -1;
+		goto done;
 	}
 	/*
 	   Indicate the command completed successfully.
 	 */
-	BusLogic_CommandFailureReason = NULL;
-	Result = ReplyBytes;
+	blogic_cmd_failure_reason = NULL;
+	result = reply_b;
 	/*
 	   Restore the interrupt status if necessary and return.
 	 */
-      Done:
-	if (!HostAdapter->IRQ_ChannelAcquired)
-		local_irq_restore(ProcessorFlags);
-	return Result;
+done:
+	if (!adapter->irq_acquired)
+		local_irq_restore(processor_flag);
+	return result;
 }
 
 
 /*
-  BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
+  blogic_add_probeaddr_isa appends a single ISA I/O Address to the list
   of I/O Address and Bus Probe Information to be checked for potential BusLogic
   Host Adapters.
 */
 
-static void __init BusLogic_AppendProbeAddressISA(unsigned long IO_Address)
+static void __init blogic_add_probeaddr_isa(unsigned long io_addr)
 {
-	struct BusLogic_ProbeInfo *ProbeInfo;
-	if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
+	struct blogic_probeinfo *probeinfo;
+	if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
 		return;
-	ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
-	ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
-	ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
-	ProbeInfo->IO_Address = IO_Address;
-	ProbeInfo->PCI_Device = NULL;
+	probeinfo = &blogic_probeinfo_list[blogic_probeinfo_count++];
+	probeinfo->adapter_type = BLOGIC_MULTIMASTER;
+	probeinfo->adapter_bus_type = BLOGIC_ISA_BUS;
+	probeinfo->io_addr = io_addr;
+	probeinfo->pci_device = NULL;
 }
 
 
 /*
-  BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
+  blogic_init_probeinfo_isa initializes the list of I/O Address and
   Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
   only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
 */
 
-static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapter
-						       *PrototypeHostAdapter)
+static void __init blogic_init_probeinfo_isa(struct blogic_adapter *adapter)
 {
 	/*
-	   If BusLogic Driver Options specifications requested that ISA Bus Probes
-	   be inhibited, do not proceed further.
+	   If BusLogic Driver Options specifications requested that ISA
+	   Bus Probes be inhibited, do not proceed further.
 	 */
-	if (BusLogic_ProbeOptions.NoProbeISA)
+	if (blogic_probe_options.noprobe_isa)
 		return;
 	/*
 	   Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
 	 */
-	if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe330)
-		BusLogic_AppendProbeAddressISA(0x330);
-	if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe334)
-		BusLogic_AppendProbeAddressISA(0x334);
-	if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe230)
-		BusLogic_AppendProbeAddressISA(0x230);
-	if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe234)
-		BusLogic_AppendProbeAddressISA(0x234);
-	if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe130)
-		BusLogic_AppendProbeAddressISA(0x130);
-	if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe134)
-		BusLogic_AppendProbeAddressISA(0x134);
+	if (!blogic_probe_options.limited_isa || blogic_probe_options.probe330)
+		blogic_add_probeaddr_isa(0x330);
+	if (!blogic_probe_options.limited_isa || blogic_probe_options.probe334)
+		blogic_add_probeaddr_isa(0x334);
+	if (!blogic_probe_options.limited_isa || blogic_probe_options.probe230)
+		blogic_add_probeaddr_isa(0x230);
+	if (!blogic_probe_options.limited_isa || blogic_probe_options.probe234)
+		blogic_add_probeaddr_isa(0x234);
+	if (!blogic_probe_options.limited_isa || blogic_probe_options.probe130)
+		blogic_add_probeaddr_isa(0x130);
+	if (!blogic_probe_options.limited_isa || blogic_probe_options.probe134)
+		blogic_add_probeaddr_isa(0x134);
 }
 
 
@@ -590,25 +619,35 @@ static void __init BusLogic_InitializePr
 
 
 /*
-  BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
+  blogic_sort_probeinfo sorts a section of blogic_probeinfo_list in order
   of increasing PCI Bus and Device Number.
 */
 
-static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoList, int ProbeInfoCount)
+static void __init blogic_sort_probeinfo(struct blogic_probeinfo
+					*probeinfo_list, int probeinfo_cnt)
 {
-	int LastInterchange = ProbeInfoCount - 1, Bound, j;
-	while (LastInterchange > 0) {
-		Bound = LastInterchange;
-		LastInterchange = 0;
-		for (j = 0; j < Bound; j++) {
-			struct BusLogic_ProbeInfo *ProbeInfo1 = &ProbeInfoList[j];
-			struct BusLogic_ProbeInfo *ProbeInfo2 = &ProbeInfoList[j + 1];
-			if (ProbeInfo1->Bus > ProbeInfo2->Bus || (ProbeInfo1->Bus == ProbeInfo2->Bus && (ProbeInfo1->Device > ProbeInfo2->Device))) {
-				struct BusLogic_ProbeInfo TempProbeInfo;
-				memcpy(&TempProbeInfo, ProbeInfo1, sizeof(struct BusLogic_ProbeInfo));
-				memcpy(ProbeInfo1, ProbeInfo2, sizeof(struct BusLogic_ProbeInfo));
-				memcpy(ProbeInfo2, &TempProbeInfo, sizeof(struct BusLogic_ProbeInfo));
-				LastInterchange = j;
+	int last_exchange = probeinfo_cnt - 1, bound, j;
+
+	while (last_exchange > 0) {
+		bound = last_exchange;
+		last_exchange = 0;
+		for (j = 0; j < bound; j++) {
+			struct blogic_probeinfo *probeinfo1 =
+							&probeinfo_list[j];
+			struct blogic_probeinfo *probeinfo2 =
+							&probeinfo_list[j + 1];
+			if (probeinfo1->bus > probeinfo2->bus ||
+				(probeinfo1->bus == probeinfo2->bus &&
+				(probeinfo1->dev > probeinfo2->dev))) {
+				struct blogic_probeinfo tmp_probeinfo;
+
+				memcpy(&tmp_probeinfo, probeinfo1,
+					sizeof(struct blogic_probeinfo));
+				memcpy(probeinfo1, probeinfo2,
+					sizeof(struct blogic_probeinfo));
+				memcpy(probeinfo2, &tmp_probeinfo,
+					sizeof(struct blogic_probeinfo));
+				last_exchange = j;
 			}
 		}
 	}
@@ -616,84 +655,88 @@ static void __init BusLogic_SortProbeInf
 
 
 /*
-  BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
+  blogic_init_mm_probeinfo initializes the list of I/O Address
   and Bus Probe Information to be checked for potential BusLogic MultiMaster
   SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
   machines as well as from the list of standard BusLogic MultiMaster ISA
   I/O Addresses.  It returns the number of PCI MultiMaster Host Adapters found.
 */
 
-static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAdapter
-							  *PrototypeHostAdapter)
+static int __init blogic_init_mm_probeinfo(struct blogic_adapter *adapter)
 {
-	struct BusLogic_ProbeInfo *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
-	int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
-	int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
-	bool ForceBusDeviceScanningOrder = false;
-	bool ForceBusDeviceScanningOrderChecked = false;
-	bool StandardAddressSeen[6];
-	struct pci_dev *PCI_Device = NULL;
+	struct blogic_probeinfo *pr_probeinfo =
+		&blogic_probeinfo_list[blogic_probeinfo_count];
+	int nonpr_mmindex = blogic_probeinfo_count + 1;
+	int nonpr_mmcount = 0, mmcount = 0;
+	bool force_scan_order = false;
+	bool force_scan_order_checked = false;
+	bool addr_seen[6];
+	struct pci_dev *pci_device = NULL;
 	int i;
-	if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
+	if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
 		return 0;
-	BusLogic_ProbeInfoCount++;
+	blogic_probeinfo_count++;
 	for (i = 0; i < 6; i++)
-		StandardAddressSeen[i] = false;
+		addr_seen[i] = false;
 	/*
-	   Iterate over the MultiMaster PCI Host Adapters.  For each enumerated host
-	   adapter, determine whether its ISA Compatible I/O Port is enabled and if
-	   so, whether it is assigned the Primary I/O Address.  A host adapter that is
-	   assigned the Primary I/O Address will always be the preferred boot device.
-	   The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
-	   Address, then any other PCI host adapters, and finally any host adapters
-	   located at the remaining standard ISA I/O Addresses.  When a PCI host
-	   adapter is found with its ISA Compatible I/O Port enabled, a command is
-	   issued to disable the ISA Compatible I/O Port, and it is noted that the
+	   Iterate over the MultiMaster PCI Host Adapters.  For each
+	   enumerated host adapter, determine whether its ISA Compatible
+	   I/O Port is enabled and if so, whether it is assigned the
+	   Primary I/O Address.  A host adapter that is assigned the
+	   Primary I/O Address will always be the preferred boot device.
+	   The MultiMaster BIOS will first recognize a host adapter at
+	   the Primary I/O Address, then any other PCI host adapters,
+	   and finally any host adapters located at the remaining
+	   standard ISA I/O Addresses.  When a PCI host adapter is found
+	   with its ISA Compatible I/O Port enabled, a command is issued
+	   to disable the ISA Compatible I/O Port, and it is noted that the
 	   particular standard ISA I/O Address need not be probed.
 	 */
-	PrimaryProbeInfo->IO_Address = 0;
-	while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_Device)) != NULL) {
-		struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
-		struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
-		enum BusLogic_ISACompatibleIOPort ModifyIOAddressRequest;
-		unsigned char Bus;
-		unsigned char Device;
-		unsigned int IRQ_Channel;
-		unsigned long BaseAddress0;
-		unsigned long BaseAddress1;
-		unsigned long IO_Address;
-		unsigned long PCI_Address;
+	pr_probeinfo->io_addr = 0;
+	while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
+					PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
+					pci_device)) != NULL) {
+		struct blogic_adapter *adapter = adapter;
+		struct blogic_adapter_info adapter_info;
+		enum blogic_isa_ioport mod_ioaddr_req;
+		unsigned char bus;
+		unsigned char device;
+		unsigned int irq_ch;
+		unsigned long base_addr0;
+		unsigned long base_addr1;
+		unsigned long io_addr;
+		unsigned long pci_addr;
 
-		if (pci_enable_device(PCI_Device))
+		if (pci_enable_device(pci_device))
 			continue;
 
-		if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32) ))
+		if (pci_set_dma_mask(pci_device, DMA_BIT_MASK(32)))
 			continue;
 
-		Bus = PCI_Device->bus->number;
-		Device = PCI_Device->devfn >> 3;
-		IRQ_Channel = PCI_Device->irq;
-		IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
-		PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
+		bus = pci_device->bus->number;
+		device = pci_device->devfn >> 3;
+		irq_ch = pci_device->irq;
+		io_addr = base_addr0 = pci_resource_start(pci_device, 0);
+		pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
 
-		if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
-			BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, BaseAddress0);
-			BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
+		if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
+			blogic_err("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, base_addr0);
+			blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
 			continue;
 		}
-		if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) {
-			BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, BaseAddress1);
-			BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address);
+		if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
+			blogic_err("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, base_addr1);
+			blogic_err("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, bus, device, pci_addr);
 			continue;
 		}
-		if (IRQ_Channel == 0) {
-			BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
-			BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
+		if (irq_ch == 0) {
+			blogic_err("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, irq_ch);
+			blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
 			continue;
 		}
-		if (BusLogic_GlobalOptions.TraceProbe) {
-			BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL);
-			BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address);
+		if (blogic_global_options.trace_probe) {
+			blogic_notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL);
+			blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, bus, device, io_addr, pci_addr);
 		}
 		/*
 		   Issue the Inquire PCI Host Adapter Information command to determine
@@ -701,238 +744,258 @@ static int __init BusLogic_InitializeMul
 		   known and enabled, note that the particular Standard ISA I/O
 		   Address should not be probed.
 		 */
-		HostAdapter->IO_Address = IO_Address;
-		BusLogic_InterruptReset(HostAdapter);
-		if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
-		    == sizeof(PCIHostAdapterInformation)) {
-			if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
-				StandardAddressSeen[PCIHostAdapterInformation.ISACompatibleIOPort] = true;
+		adapter->io_addr = io_addr;
+		blogic_intreset(adapter);
+		if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
+				&adapter_info, sizeof(adapter_info)) ==
+				sizeof(adapter_info)) {
+			if (adapter_info.isa_port < 6)
+				addr_seen[adapter_info.isa_port] = true;
 		} else
-			PCIHostAdapterInformation.ISACompatibleIOPort = BusLogic_IO_Disable;
+			adapter_info.isa_port = BLOGIC_IO_DISABLE;
 		/*
-		 * Issue the Modify I/O Address command to disable the ISA Compatible
-		 * I/O Port.  On PCI Host Adapters, the Modify I/O Address command
-		 * allows modification of the ISA compatible I/O Address that the Host
-		 * Adapter responds to; it does not affect the PCI compliant I/O Address
-		 * assigned at system initialization.
+		   Issue the Modify I/O Address command to disable the
+		   ISA Compatible I/O Port. On PCI Host Adapters, the
+		   Modify I/O Address command allows modification of the
+		   ISA compatible I/O Address that the Host Adapter
+		   responds to; it does not affect the PCI compliant
+		   I/O Address assigned at system initialization.
 		 */
-		ModifyIOAddressRequest = BusLogic_IO_Disable;
-		BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress, &ModifyIOAddressRequest, sizeof(ModifyIOAddressRequest), NULL, 0);
+		mod_ioaddr_req = BLOGIC_IO_DISABLE;
+		blogic_cmd(adapter, BLOGIC_MOD_IOADDR, &mod_ioaddr_req,
+				sizeof(mod_ioaddr_req), NULL, 0);
 		/*
-		   For the first MultiMaster Host Adapter enumerated, issue the Fetch
-		   Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
-		   for the setting of the "Use Bus And Device # For PCI Scanning Seq."
-		   option.  Issue the Inquire Board ID command since this option is
+		   For the first MultiMaster Host Adapter enumerated,
+		   issue the Fetch Host Adapter Local RAM command to read
+		   byte 45 of the AutoSCSI area, for the setting of the
+		   "Use Bus And Device # For PCI Scanning Seq." option.
+		   Issue the Inquire Board ID command since this option is
 		   only valid for the BT-948/958/958D.
 		 */
-		if (!ForceBusDeviceScanningOrderChecked) {
-			struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
-			struct BusLogic_AutoSCSIByte45 AutoSCSIByte45;
-			struct BusLogic_BoardID BoardID;
-			FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset + 45;
-			FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte45);
-			BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIByte45, sizeof(AutoSCSIByte45));
-			BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID));
-			if (BoardID.FirmwareVersion1stDigit == '5')
-				ForceBusDeviceScanningOrder = AutoSCSIByte45.ForceBusDeviceScanningOrder;
-			ForceBusDeviceScanningOrderChecked = true;
+		if (!force_scan_order_checked) {
+			struct blogic_fetch_localram fetch_localram;
+			struct blogic_autoscsi_byte45 autoscsi_byte45;
+			struct blogic_board_id id;
+
+			fetch_localram.offset = BLOGIC_AUTOSCSI_BASE + 45;
+			fetch_localram.count = sizeof(autoscsi_byte45);
+			blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM,
+					&fetch_localram, sizeof(fetch_localram),
+					&autoscsi_byte45,
+					sizeof(autoscsi_byte45));
+			blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id,
+					sizeof(id));
+			if (id.fw_ver_digit1 == '5')
+				force_scan_order =
+					autoscsi_byte45.force_scan_order;
+			force_scan_order_checked = true;
 		}
 		/*
-		   Determine whether this MultiMaster Host Adapter has its ISA
-		   Compatible I/O Port enabled and is assigned the Primary I/O Address.
-		   If it does, then it is the Primary MultiMaster Host Adapter and must
-		   be recognized first.  If it does not, then it is added to the list
-		   for probing after any Primary MultiMaster Host Adapter is probed.
+		   Determine whether this MultiMaster Host Adapter has its
+		   ISA Compatible I/O Port enabled and is assigned the
+		   Primary I/O Address. If it does, then it is the Primary
+		   MultiMaster Host Adapter and must be recognized first.
+		   If it does not, then it is added to the list for probing
+		   after any Primary MultiMaster Host Adapter is probed.
 		 */
-		if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330) {
-			PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
-			PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
-			PrimaryProbeInfo->IO_Address = IO_Address;
-			PrimaryProbeInfo->PCI_Address = PCI_Address;
-			PrimaryProbeInfo->Bus = Bus;
-			PrimaryProbeInfo->Device = Device;
-			PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
-			PrimaryProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
-			PCIMultiMasterCount++;
-		} else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) {
-			struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
-			ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
-			ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
-			ProbeInfo->IO_Address = IO_Address;
-			ProbeInfo->PCI_Address = PCI_Address;
-			ProbeInfo->Bus = Bus;
-			ProbeInfo->Device = Device;
-			ProbeInfo->IRQ_Channel = IRQ_Channel;
-			ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
-			NonPrimaryPCIMultiMasterCount++;
-			PCIMultiMasterCount++;
+		if (adapter_info.isa_port == BLOGIC_IO_330) {
+			pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
+			pr_probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
+			pr_probeinfo->io_addr = io_addr;
+			pr_probeinfo->pci_addr = pci_addr;
+			pr_probeinfo->bus = bus;
+			pr_probeinfo->dev = device;
+			pr_probeinfo->irq_ch = irq_ch;
+			pr_probeinfo->pci_device = pci_dev_get(pci_device);
+			mmcount++;
+		} else if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
+			struct blogic_probeinfo *probeinfo =
+				&blogic_probeinfo_list[blogic_probeinfo_count++];
+			probeinfo->adapter_type = BLOGIC_MULTIMASTER;
+			probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
+			probeinfo->io_addr = io_addr;
+			probeinfo->pci_addr = pci_addr;
+			probeinfo->bus = bus;
+			probeinfo->dev = device;
+			probeinfo->irq_ch = irq_ch;
+			probeinfo->pci_device = pci_dev_get(pci_device);
+			nonpr_mmcount++;
+			mmcount++;
 		} else
-			BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL);
+			blogic_warn("BusLogic: Too many Host Adapters " "detected\n", NULL);
 	}
 	/*
-	   If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
-	   for the first enumerated MultiMaster Host Adapter, and if that host adapter
-	   is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
-	   Host Adapters in the order of increasing PCI Bus and Device Number.  In
-	   that case, sort the probe information into the same order the BIOS uses.
-	   If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
-	   Host Adapters in the order they are enumerated by the PCI BIOS, and hence
-	   no sorting is necessary.
+	   If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq."
+	   option is ON for the first enumerated MultiMaster Host Adapter,
+	   and if that host adapter is a BT-948/958/958D, then the
+	   MultiMaster BIOS will recognize MultiMaster Host Adapters in
+	   the order of increasing PCI Bus and Device Number. In that case,
+	   sort the probe information into the same order the BIOS uses.
+	   If this option is OFF, then the MultiMaster BIOS will recognize
+	   MultiMaster Host Adapters in the order they are enumerated by
+	   the PCI BIOS, and hence no sorting is necessary.
 	 */
-	if (ForceBusDeviceScanningOrder)
-		BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[NonPrimaryPCIMultiMasterIndex], NonPrimaryPCIMultiMasterCount);
+	if (force_scan_order)
+		blogic_sort_probeinfo(&blogic_probeinfo_list[nonpr_mmindex],
+					nonpr_mmcount);
 	/*
-	   If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
-	   then the Primary I/O Address must be probed explicitly before any PCI
-	   host adapters are probed.
+	   If no PCI MultiMaster Host Adapter is assigned the Primary
+	   I/O Address, then the Primary I/O Address must be probed
+	   explicitly before any PCI host adapters are probed.
 	 */
-	if (!BusLogic_ProbeOptions.NoProbeISA)
-		if (PrimaryProbeInfo->IO_Address == 0 &&
-				(!BusLogic_ProbeOptions.LimitedProbeISA ||
-				 BusLogic_ProbeOptions.Probe330)) {
-			PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
-			PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
-			PrimaryProbeInfo->IO_Address = 0x330;
+	if (!blogic_probe_options.noprobe_isa)
+		if (pr_probeinfo->io_addr == 0 &&
+				(!blogic_probe_options.limited_isa ||
+				 blogic_probe_options.probe330)) {
+			pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
+			pr_probeinfo->adapter_bus_type = BLOGIC_ISA_BUS;
+			pr_probeinfo->io_addr = 0x330;
 		}
 	/*
 	   Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
 	   omitting the Primary I/O Address which has already been handled.
 	 */
-	if (!BusLogic_ProbeOptions.NoProbeISA) {
-		if (!StandardAddressSeen[1] &&
-				(!BusLogic_ProbeOptions.LimitedProbeISA ||
-				 BusLogic_ProbeOptions.Probe334))
-			BusLogic_AppendProbeAddressISA(0x334);
-		if (!StandardAddressSeen[2] &&
-				(!BusLogic_ProbeOptions.LimitedProbeISA ||
-				 BusLogic_ProbeOptions.Probe230))
-			BusLogic_AppendProbeAddressISA(0x230);
-		if (!StandardAddressSeen[3] &&
-				(!BusLogic_ProbeOptions.LimitedProbeISA ||
-				 BusLogic_ProbeOptions.Probe234))
-			BusLogic_AppendProbeAddressISA(0x234);
-		if (!StandardAddressSeen[4] &&
-				(!BusLogic_ProbeOptions.LimitedProbeISA ||
-				 BusLogic_ProbeOptions.Probe130))
-			BusLogic_AppendProbeAddressISA(0x130);
-		if (!StandardAddressSeen[5] &&
-				(!BusLogic_ProbeOptions.LimitedProbeISA ||
-				 BusLogic_ProbeOptions.Probe134))
-			BusLogic_AppendProbeAddressISA(0x134);
+	if (!blogic_probe_options.noprobe_isa) {
+		if (!addr_seen[1] &&
+				(!blogic_probe_options.limited_isa ||
+				 blogic_probe_options.probe334))
+			blogic_add_probeaddr_isa(0x334);
+		if (!addr_seen[2] &&
+				(!blogic_probe_options.limited_isa ||
+				 blogic_probe_options.probe230))
+			blogic_add_probeaddr_isa(0x230);
+		if (!addr_seen[3] &&
+				(!blogic_probe_options.limited_isa ||
+				 blogic_probe_options.probe234))
+			blogic_add_probeaddr_isa(0x234);
+		if (!addr_seen[4] &&
+				(!blogic_probe_options.limited_isa ||
+				 blogic_probe_options.probe130))
+			blogic_add_probeaddr_isa(0x130);
+		if (!addr_seen[5] &&
+				(!blogic_probe_options.limited_isa ||
+				 blogic_probe_options.probe134))
+			blogic_add_probeaddr_isa(0x134);
 	}
 	/*
 	   Iterate over the older non-compliant MultiMaster PCI Host Adapters,
 	   noting the PCI bus location and assigned IRQ Channel.
 	 */
-	PCI_Device = NULL;
-	while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, PCI_Device)) != NULL) {
-		unsigned char Bus;
-		unsigned char Device;
-		unsigned int IRQ_Channel;
-		unsigned long IO_Address;
+	pci_device = NULL;
+	while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
+					PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
+					pci_device)) != NULL) {
+		unsigned char bus;
+		unsigned char device;
+		unsigned int irq_ch;
+		unsigned long io_addr;
 
-		if (pci_enable_device(PCI_Device))
+		if (pci_enable_device(pci_device))
 			continue;
 
-		if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32)))
+		if (pci_set_dma_mask(pci_device, DMA_BIT_MASK(32)))
 			continue;
 
-		Bus = PCI_Device->bus->number;
-		Device = PCI_Device->devfn >> 3;
-		IRQ_Channel = PCI_Device->irq;
-		IO_Address = pci_resource_start(PCI_Device, 0);
+		bus = pci_device->bus->number;
+		device = pci_device->devfn >> 3;
+		irq_ch = pci_device->irq;
+		io_addr = pci_resource_start(pci_device, 0);
 
-		if (IO_Address == 0 || IRQ_Channel == 0)
+		if (io_addr == 0 || irq_ch == 0)
 			continue;
-		for (i = 0; i < BusLogic_ProbeInfoCount; i++) {
-			struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[i];
-			if (ProbeInfo->IO_Address == IO_Address && ProbeInfo->HostAdapterType == BusLogic_MultiMaster) {
-				ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
-				ProbeInfo->PCI_Address = 0;
-				ProbeInfo->Bus = Bus;
-				ProbeInfo->Device = Device;
-				ProbeInfo->IRQ_Channel = IRQ_Channel;
-				ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
+		for (i = 0; i < blogic_probeinfo_count; i++) {
+			struct blogic_probeinfo *probeinfo =
+						&blogic_probeinfo_list[i];
+			if (probeinfo->io_addr == io_addr &&
+				probeinfo->adapter_type == BLOGIC_MULTIMASTER) {
+				probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
+				probeinfo->pci_addr = 0;
+				probeinfo->bus = bus;
+				probeinfo->dev = device;
+				probeinfo->irq_ch = irq_ch;
+				probeinfo->pci_device = pci_dev_get(pci_device);
 				break;
 			}
 		}
 	}
-	return PCIMultiMasterCount;
+	return mmcount;
 }
 
 
 /*
-  BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
+  blogic_init_fp_probeinfo initializes the list of I/O Address
   and Bus Probe Information to be checked for potential BusLogic FlashPoint
   Host Adapters by interrogating the PCI Configuration Space.  It returns the
   number of FlashPoint Host Adapters found.
 */
 
-static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAdapter
-							 *PrototypeHostAdapter)
+static int __init blogic_init_fp_probeinfo(struct blogic_adapter *adapter)
 {
-	int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
-	struct pci_dev *PCI_Device = NULL;
+	int fpindex = blogic_probeinfo_count, fpcount = 0;
+	struct pci_dev *pci_device = NULL;
 	/*
 	   Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
 	 */
-	while ((PCI_Device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, PCI_Device)) != NULL) {
-		unsigned char Bus;
-		unsigned char Device;
-		unsigned int IRQ_Channel;
-		unsigned long BaseAddress0;
-		unsigned long BaseAddress1;
-		unsigned long IO_Address;
-		unsigned long PCI_Address;
+	while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
+					PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
+					pci_device)) != NULL) {
+		unsigned char bus;
+		unsigned char device;
+		unsigned int irq_ch;
+		unsigned long base_addr0;
+		unsigned long base_addr1;
+		unsigned long io_addr;
+		unsigned long pci_addr;
 
-		if (pci_enable_device(PCI_Device))
+		if (pci_enable_device(pci_device))
 			continue;
 
-		if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32)))
+		if (pci_set_dma_mask(pci_device, DMA_BIT_MASK(32)))
 			continue;
 
-		Bus = PCI_Device->bus->number;
-		Device = PCI_Device->devfn >> 3;
-		IRQ_Channel = PCI_Device->irq;
-		IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
-		PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
+		bus = pci_device->bus->number;
+		device = pci_device->devfn >> 3;
+		irq_ch = pci_device->irq;
+		io_addr = base_addr0 = pci_resource_start(pci_device, 0);
+		pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
 #ifdef CONFIG_SCSI_FLASHPOINT
-		if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
-			BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0);
-			BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
+		if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
+			blogic_err("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, base_addr0);
+			blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
 			continue;
 		}
-		if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) {
-			BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, BaseAddress1);
-			BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address);
+		if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
+			blogic_err("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, base_addr1);
+			blogic_err("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, bus, device, pci_addr);
 			continue;
 		}
-		if (IRQ_Channel == 0) {
-			BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
-			BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
+		if (irq_ch == 0) {
+			blogic_err("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, irq_ch);
+			blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
 			continue;
 		}
-		if (BusLogic_GlobalOptions.TraceProbe) {
-			BusLogic_Notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL);
-			BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address);
+		if (blogic_global_options.trace_probe) {
+			blogic_notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL);
+			blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, bus, device, io_addr, pci_addr);
 		}
-		if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) {
-			struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
-			ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
-			ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
-			ProbeInfo->IO_Address = IO_Address;
-			ProbeInfo->PCI_Address = PCI_Address;
-			ProbeInfo->Bus = Bus;
-			ProbeInfo->Device = Device;
-			ProbeInfo->IRQ_Channel = IRQ_Channel;
-			ProbeInfo->PCI_Device = pci_dev_get(PCI_Device);
-			FlashPointCount++;
+		if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
+			struct blogic_probeinfo *probeinfo =
+				&blogic_probeinfo_list[blogic_probeinfo_count++];
+			probeinfo->adapter_type = BLOGIC_FLASHPOINT;
+			probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
+			probeinfo->io_addr = io_addr;
+			probeinfo->pci_addr = pci_addr;
+			probeinfo->bus = bus;
+			probeinfo->dev = device;
+			probeinfo->irq_ch = irq_ch;
+			probeinfo->pci_device = pci_dev_get(pci_device);
+			fpcount++;
 		} else
-			BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL);
+			blogic_warn("BusLogic: Too many Host Adapters " "detected\n", NULL);
 #else
-		BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, Bus, Device);
-		BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
-		BusLogic_Error("BusLogic: support was omitted in this kernel " "configuration.\n", NULL);
+		blogic_err("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, bus, device);
+		blogic_err("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, io_addr, pci_addr, irq_ch);
+		blogic_err("BusLogic: support was omitted in this kernel " "configuration.\n", NULL);
 #endif
 	}
 	/*
@@ -940,13 +1003,13 @@ static int __init BusLogic_InitializeFla
 	   increasing PCI Bus and Device Number, so sort the probe information into
 	   the same order the BIOS uses.
 	 */
-	BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex], FlashPointCount);
-	return FlashPointCount;
+	blogic_sort_probeinfo(&blogic_probeinfo_list[fpindex], fpcount);
+	return fpcount;
 }
 
 
 /*
-  BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
+  blogic_init_probeinfo_list initializes the list of I/O Address and Bus
   Probe Information to be checked for potential BusLogic SCSI Host Adapters by
   interrogating the PCI Configuration Space on PCI machines as well as from the
   list of standard BusLogic MultiMaster ISA I/O Addresses.  By default, if both
@@ -958,104 +1021,125 @@ static int __init BusLogic_InitializeFla
   a particular probe order.
 */
 
-static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
-						    *PrototypeHostAdapter)
+static void __init blogic_init_probeinfo_list(struct blogic_adapter *adapter)
 {
 	/*
-	   If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
-	   Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
+	   If a PCI BIOS is present, interrogate it for MultiMaster and
+	   FlashPoint Host Adapters; otherwise, default to the standard
+	   ISA MultiMaster probe.
 	 */
-	if (!BusLogic_ProbeOptions.NoProbePCI) {
-		if (BusLogic_ProbeOptions.MultiMasterFirst) {
-			BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
-			BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
-		} else if (BusLogic_ProbeOptions.FlashPointFirst) {
-			BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
-			BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
+	if (!blogic_probe_options.noprobe_pci) {
+		if (blogic_probe_options.multimaster_first) {
+			blogic_init_mm_probeinfo(adapter);
+			blogic_init_fp_probeinfo(adapter);
+		} else if (blogic_probe_options.flashpoint_first) {
+			blogic_init_fp_probeinfo(adapter);
+			blogic_init_mm_probeinfo(adapter);
 		} else {
-			int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
-			int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
-			if (FlashPointCount > 0 && PCIMultiMasterCount > 0) {
-				struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[FlashPointCount];
-				struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
-				struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
-				struct BusLogic_BIOSDriveMapByte Drive0MapByte;
-				while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
-					ProbeInfo++;
-				HostAdapter->IO_Address = ProbeInfo->IO_Address;
-				FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
-				FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(Drive0MapByte);
-				BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &Drive0MapByte, sizeof(Drive0MapByte));
+			int fpcount = blogic_init_fp_probeinfo(adapter);
+			int mmcount = blogic_init_mm_probeinfo(adapter);
+			if (fpcount > 0 && mmcount > 0) {
+				struct blogic_probeinfo *probeinfo =
+					&blogic_probeinfo_list[fpcount];
+				struct blogic_adapter *myadapter = adapter;
+				struct blogic_fetch_localram fetch_localram;
+				struct blogic_bios_drvmap d0_mapbyte;
+
+				while (probeinfo->adapter_bus_type !=
+						BLOGIC_PCI_BUS)
+					probeinfo++;
+				myadapter->io_addr = probeinfo->io_addr;
+				fetch_localram.offset =
+					BLOGIC_BIOS_BASE + BLOGIC_BIOS_DRVMAP;
+				fetch_localram.count = sizeof(d0_mapbyte);
+				blogic_cmd(myadapter, BLOGIC_FETCH_LOCALRAM,
+						&fetch_localram,
+						sizeof(fetch_localram),
+						&d0_mapbyte,
+						sizeof(d0_mapbyte));
 				/*
-				   If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
-				   is controlled by this PCI MultiMaster Host Adapter, then
-				   reverse the probe order so that MultiMaster Host Adapters are
-				   probed before FlashPoint Host Adapters.
+				   If the Map Byte for BIOS Drive 0 indicates
+				   that BIOS Drive 0 is controlled by this
+				   PCI MultiMaster Host Adapter, then reverse
+				   the probe order so that MultiMaster Host
+				   Adapters are probed before FlashPoint Host
+				   Adapters.
 				 */
-				if (Drive0MapByte.DiskGeometry != BusLogic_BIOS_Disk_Not_Installed) {
-					struct BusLogic_ProbeInfo SavedProbeInfo[BusLogic_MaxHostAdapters];
-					int MultiMasterCount = BusLogic_ProbeInfoCount - FlashPointCount;
-					memcpy(SavedProbeInfo, BusLogic_ProbeInfoList, BusLogic_ProbeInfoCount * sizeof(struct BusLogic_ProbeInfo));
-					memcpy(&BusLogic_ProbeInfoList[0], &SavedProbeInfo[FlashPointCount], MultiMasterCount * sizeof(struct BusLogic_ProbeInfo));
-					memcpy(&BusLogic_ProbeInfoList[MultiMasterCount], &SavedProbeInfo[0], FlashPointCount * sizeof(struct BusLogic_ProbeInfo));
+				if (d0_mapbyte.diskgeom != BLOGIC_BIOS_NODISK) {
+					struct blogic_probeinfo saved_probeinfo[BLOGIC_MAX_ADAPTERS];
+					int mmcount = blogic_probeinfo_count - fpcount;
+
+					memcpy(saved_probeinfo,
+						blogic_probeinfo_list,
+						blogic_probeinfo_count * sizeof(struct blogic_probeinfo));
+					memcpy(&blogic_probeinfo_list[0],
+						&saved_probeinfo[fpcount],
+						mmcount * sizeof(struct blogic_probeinfo));
+					memcpy(&blogic_probeinfo_list[mmcount],
+						&saved_probeinfo[0],
+						fpcount * sizeof(struct blogic_probeinfo));
 				}
 			}
 		}
-	} else
-		BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
+	} else {
+		blogic_init_probeinfo_isa(adapter);
+	}
 }
 
 
 #else
-#define BusLogic_InitializeProbeInfoList(adapter) \
-		BusLogic_InitializeProbeInfoListISA(adapter)
+#define blogic_init_probeinfo_list(adapter) \
+		blogic_init_probeinfo_isa(adapter)
 #endif				/* CONFIG_PCI */
 
 
 /*
-  BusLogic_Failure prints a standardized error message, and then returns false.
+  blogic_failure prints a standardized error message, and then returns false.
 */
 
-static bool BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage)
+static bool blogic_failure(struct blogic_adapter *adapter, char *msg)
 {
-	BusLogic_AnnounceDriver(HostAdapter);
-	if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) {
-		BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n", HostAdapter);
-		BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device, HostAdapter->IO_Address, HostAdapter->PCI_Address);
+	blogic_announce_drvr(adapter);
+	if (adapter->adapter_bus_type == BLOGIC_PCI_BUS) {
+		blogic_err("While configuring BusLogic PCI Host Adapter at\n",
+				adapter);
+		blogic_err("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n", adapter, adapter->bus, adapter->dev, adapter->io_addr, adapter->pci_addr);
 	} else
-		BusLogic_Error("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", HostAdapter, HostAdapter->IO_Address);
-	BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
-	if (BusLogic_CommandFailureReason != NULL)
-		BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter, BusLogic_CommandFailureReason);
+		blogic_err("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", adapter, adapter->io_addr);
+	blogic_err("%s FAILED - DETACHING\n", adapter, msg);
+	if (blogic_cmd_failure_reason != NULL)
+		blogic_err("ADDITIONAL FAILURE INFO - %s\n", adapter,
+				blogic_cmd_failure_reason);
 	return false;
 }
 
 
 /*
-  BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
+  blogic_probe probes for a BusLogic Host Adapter.
 */
 
-static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
+static bool __init blogic_probe(struct blogic_adapter *adapter)
 {
-	union BusLogic_StatusRegister StatusRegister;
-	union BusLogic_InterruptRegister InterruptRegister;
-	union BusLogic_GeometryRegister GeometryRegister;
+	union blogic_stat_reg statusreg;
+	union blogic_int_reg intreg;
+	union blogic_geo_reg georeg;
 	/*
 	   FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
 	 */
-	if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
-		struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
-		FlashPointInfo->BaseAddress = (u32) HostAdapter->IO_Address;
-		FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
-		FlashPointInfo->Present = false;
-		if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && FlashPointInfo->Present)) {
-			BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
-			BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", HostAdapter, HostAdapter->IO_Address, HostAdapter->PCI_Address);
-			BusLogic_Error("BusLogic: Probe Function failed to validate it.\n", HostAdapter);
+	if (blogic_flashpoint_type(adapter)) {
+		struct fpoint_info *fpinfo = &adapter->fpinfo;
+		fpinfo->base_addr = (u32) adapter->io_addr;
+		fpinfo->irq_ch = adapter->irq_ch;
+		fpinfo->present = false;
+		if (!(FlashPoint_ProbeHostAdapter(fpinfo) == 0 &&
+					fpinfo->present)) {
+			blogic_err("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", adapter, adapter->bus, adapter->dev);
+			blogic_err("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", adapter, adapter->io_addr, adapter->pci_addr);
+			blogic_err("BusLogic: Probe Function failed to validate it.\n", adapter);
 			return false;
 		}
-		if (BusLogic_GlobalOptions.TraceProbe)
-			BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", HostAdapter, HostAdapter->IO_Address);
+		if (blogic_global_options.trace_probe)
+			blogic_notice("BusLogic_Probe(0x%X): FlashPoint Found\n", adapter, adapter->io_addr);
 		/*
 		   Indicate the Host Adapter Probe completed successfully.
 		 */
@@ -1068,28 +1152,32 @@ static bool __init BusLogic_ProbeHostAda
 	   case there is definitely no BusLogic Host Adapter at this base I/O Address.
 	   The test here is a subset of that used by the BusLogic Host Adapter BIOS.
 	 */
-	StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
-	InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
-	GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
-	if (BusLogic_GlobalOptions.TraceProbe)
-		BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All, InterruptRegister.All, GeometryRegister.All);
-	if (StatusRegister.All == 0 || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.CommandParameterRegisterBusy || StatusRegister.sr.Reserved || StatusRegister.sr.CommandInvalid || InterruptRegister.ir.Reserved != 0)
+	statusreg.all = blogic_rdstatus(adapter);
+	intreg.all = blogic_rdint(adapter);
+	georeg.all = blogic_rdgeom(adapter);
+	if (blogic_global_options.trace_probe)
+		blogic_notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", adapter, adapter->io_addr, statusreg.all, intreg.all, georeg.all);
+	if (statusreg.all == 0 || statusreg.sr.diag_active ||
+			statusreg.sr.cmd_param_busy || statusreg.sr.rsvd ||
+			statusreg.sr.cmd_invalid || intreg.ir.rsvd != 0)
 		return false;
 	/*
-	   Check the undocumented Geometry Register to test if there is an I/O port
-	   that responded.  Adaptec Host Adapters do not implement the Geometry
-	   Register, so this test helps serve to avoid incorrectly recognizing an
-	   Adaptec 1542A or 1542B as a BusLogic.  Unfortunately, the Adaptec 1542C
-	   series does respond to the Geometry Register I/O port, but it will be
-	   rejected later when the Inquire Extended Setup Information command is
-	   issued in BusLogic_CheckHostAdapter.  The AMI FastDisk Host Adapter is a
-	   BusLogic clone that implements the same interface as earlier BusLogic
-	   Host Adapters, including the undocumented commands, and is therefore
-	   supported by this driver.  However, the AMI FastDisk always returns 0x00
-	   upon reading the Geometry Register, so the extended translation option
-	   should always be left disabled on the AMI FastDisk.
+	   Check the undocumented Geometry Register to test if there is
+	   an I/O port that responded.  Adaptec Host Adapters do not
+	   implement the Geometry Register, so this test helps serve to
+	   avoid incorrectly recognizing an Adaptec 1542A or 1542B as a
+	   BusLogic.  Unfortunately, the Adaptec 1542C series does respond
+	   to the Geometry Register I/O port, but it will be rejected
+	   later when the Inquire Extended Setup Information command is
+	   issued in blogic_checkadapter.  The AMI FastDisk Host Adapter
+	   is a BusLogic clone that implements the same interface as
+	   earlier BusLogic Host Adapters, including the undocumented
+	   commands, and is therefore supported by this driver. However,
+	   the AMI FastDisk always returns 0x00 upon reading the Geometry
+	   Register, so the extended translation option should always be
+	   left disabled on the AMI FastDisk.
 	 */
-	if (GeometryRegister.All == 0xFF)
+	if (georeg.all == 0xFF)
 		return false;
 	/*
 	   Indicate the Host Adapter Probe completed successfully.
@@ -1099,27 +1187,28 @@ static bool __init BusLogic_ProbeHostAda
 
 
 /*
-  BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
-  and waits for Host Adapter Diagnostics to complete.  If HardReset is true, a
+  blogic_hwreset issues a Hardware Reset to the Host Adapter
+  and waits for Host Adapter Diagnostics to complete.  If hard_reset is true, a
   Hard Reset is performed which also initiates a SCSI Bus Reset.  Otherwise, a
   Soft Reset is performed which only resets the Host Adapter without forcing a
   SCSI Bus Reset.
 */
 
-static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
-						 *HostAdapter, bool HardReset)
+static bool blogic_hwreset(struct blogic_adapter *adapter, bool hard_reset)
 {
-	union BusLogic_StatusRegister StatusRegister;
-	int TimeoutCounter;
+	union blogic_stat_reg statusreg;
+	int timeout;
 	/*
-	   FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
+	   FlashPoint Host Adapters are Hard Reset by the FlashPoint
+	   SCCB Manager.
 	 */
-	if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
-		struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
-		FlashPointInfo->HostSoftReset = !HardReset;
-		FlashPointInfo->ReportDataUnderrun = true;
-		HostAdapter->CardHandle = FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
-		if (HostAdapter->CardHandle == FlashPoint_BadCardHandle)
+	if (blogic_flashpoint_type(adapter)) {
+		struct fpoint_info *fpinfo = &adapter->fpinfo;
+		fpinfo->softreset = !hard_reset;
+		fpinfo->report_underrun = true;
+		adapter->cardhandle =
+			FlashPoint_HardwareResetHostAdapter(fpinfo);
+		if (adapter->cardhandle == (void *)FPOINT_BADCARD_HANDLE)
 			return false;
 		/*
 		   Indicate the Host Adapter Hard Reset completed successfully.
@@ -1127,26 +1216,27 @@ static bool BusLogic_HardwareResetHostAd
 		return true;
 	}
 	/*
-	   Issue a Hard Reset or Soft Reset Command to the Host Adapter.  The Host
-	   Adapter should respond by setting Diagnostic Active in the Status Register.
+	   Issue a Hard Reset or Soft Reset Command to the Host Adapter.
+	   The Host Adapter should respond by setting Diagnostic Active in
+	   the Status Register.
 	 */
-	if (HardReset)
-		BusLogic_HardReset(HostAdapter);
+	if (hard_reset)
+		blogic_hardreset(adapter);
 	else
-		BusLogic_SoftReset(HostAdapter);
+		blogic_softreset(adapter);
 	/*
 	   Wait until Diagnostic Active is set in the Status Register.
 	 */
-	TimeoutCounter = 5 * 10000;
-	while (--TimeoutCounter >= 0) {
-		StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
-		if (StatusRegister.sr.DiagnosticActive)
+	timeout = 5 * 10000;
+	while (--timeout >= 0) {
+		statusreg.all = blogic_rdstatus(adapter);
+		if (statusreg.sr.diag_active)
 			break;
 		udelay(100);
 	}
-	if (BusLogic_GlobalOptions.TraceHardwareReset)
-		BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
-	if (TimeoutCounter < 0)
+	if (blogic_global_options.trace_hw_reset)
+		blogic_notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
+	if (timeout < 0)
 		return false;
 	/*
 	   Wait 100 microseconds to allow completion of any initial diagnostic
@@ -1157,45 +1247,47 @@ static bool BusLogic_HardwareResetHostAd
 	/*
 	   Wait until Diagnostic Active is reset in the Status Register.
 	 */
-	TimeoutCounter = 10 * 10000;
-	while (--TimeoutCounter >= 0) {
-		StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
-		if (!StatusRegister.sr.DiagnosticActive)
+	timeout = 10 * 10000;
+	while (--timeout >= 0) {
+		statusreg.all = blogic_rdstatus(adapter);
+		if (!statusreg.sr.diag_active)
 			break;
 		udelay(100);
 	}
-	if (BusLogic_GlobalOptions.TraceHardwareReset)
-		BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
-	if (TimeoutCounter < 0)
+	if (blogic_global_options.trace_hw_reset)
+		blogic_notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
+	if (timeout < 0)
 		return false;
 	/*
-	   Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
-	   or Data In Register Ready bits is set in the Status Register.
+	   Wait until at least one of the Diagnostic Failure, Host Adapter
+	   Ready, or Data In Register Ready bits is set in the Status Register.
 	 */
-	TimeoutCounter = 10000;
-	while (--TimeoutCounter >= 0) {
-		StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
-		if (StatusRegister.sr.DiagnosticFailure || StatusRegister.sr.HostAdapterReady || StatusRegister.sr.DataInRegisterReady)
+	timeout = 10000;
+	while (--timeout >= 0) {
+		statusreg.all = blogic_rdstatus(adapter);
+		if (statusreg.sr.diag_failed || statusreg.sr.adapter_ready ||
+				statusreg.sr.datain_ready)
 			break;
 		udelay(100);
 	}
-	if (BusLogic_GlobalOptions.TraceHardwareReset)
-		BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All);
-	if (TimeoutCounter < 0)
+	if (blogic_global_options.trace_hw_reset)
+		blogic_notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
+	if (timeout < 0)
 		return false;
 	/*
-	   If Diagnostic Failure is set or Host Adapter Ready is reset, then an
-	   error occurred during the Host Adapter diagnostics.  If Data In Register
-	   Ready is set, then there is an Error Code available.
+	   If Diagnostic Failure is set or Host Adapter Ready is reset,
+	   then an error occurred during the Host Adapter diagnostics.
+	   If Data In Register Ready is set, then there is an Error Code
+	   available.
 	 */
-	if (StatusRegister.sr.DiagnosticFailure || !StatusRegister.sr.HostAdapterReady) {
-		BusLogic_CommandFailureReason = NULL;
-		BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
-		BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", HostAdapter, StatusRegister.All);
-		if (StatusRegister.sr.DataInRegisterReady) {
-			unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
-			BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n", HostAdapter, ErrorCode);
-		}
+	if (statusreg.sr.diag_failed || !statusreg.sr.adapter_ready) {
+		blogic_cmd_failure_reason = NULL;
+		blogic_failure(adapter, "HARD RESET DIAGNOSTICS");
+		blogic_err("HOST ADAPTER STATUS REGISTER = %02X\n", adapter,
+				statusreg.all);
+		if (statusreg.sr.datain_ready)
+			blogic_err("HOST ADAPTER ERROR CODE = %d\n", adapter,
+					blogic_rddatain(adapter));
 		return false;
 	}
 	/*
@@ -1206,161 +1298,175 @@ static bool BusLogic_HardwareResetHostAd
 
 
 /*
-  BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
+  blogic_checkadapter checks to be sure this really is a BusLogic
   Host Adapter.
 */
 
-static bool __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
+static bool __init blogic_checkadapter(struct blogic_adapter *adapter)
 {
-	struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
-	unsigned char RequestedReplyLength;
-	bool Result = true;
+	struct blogic_ext_setup ext_setupinfo;
+	unsigned char req_replylen;
+	bool result = true;
 	/*
 	   FlashPoint Host Adapters do not require this protection.
 	 */
-	if (BusLogic_FlashPointHostAdapterP(HostAdapter))
+	if (blogic_flashpoint_type(adapter))
 		return true;
 	/*
-	   Issue the Inquire Extended Setup Information command.  Only genuine
-	   BusLogic Host Adapters and true clones support this command.  Adaptec 1542C
-	   series Host Adapters that respond to the Geometry Register I/O port will
-	   fail this command.
+	   Issue the Inquire Extended Setup Information command. Only genuine
+	   BusLogic Host Adapters and true clones support this command.
+	   Adaptec 1542C series Host Adapters that respond to the Geometry
+	   Register I/O port will fail this command.
 	 */
-	RequestedReplyLength = sizeof(ExtendedSetupInformation);
-	if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
-	    != sizeof(ExtendedSetupInformation))
-		Result = false;
+	req_replylen = sizeof(ext_setupinfo);
+	if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
+				sizeof(req_replylen), &ext_setupinfo,
+				sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
+		result = false;
 	/*
 	   Provide tracing information if requested and return.
 	 */
-	if (BusLogic_GlobalOptions.TraceProbe)
-		BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
-	return Result;
+	if (blogic_global_options.trace_probe)
+		blogic_notice("BusLogic_Check(0x%X): MultiMaster %s\n", adapter,
+				adapter->io_addr,
+				(result ? "Found" : "Not Found"));
+	return result;
 }
 
 
 /*
-  BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
+  blogic_rdconfig reads the Configuration Information
   from Host Adapter and initializes the Host Adapter structure.
 */
 
-static bool __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter
-							    *HostAdapter)
+static bool __init blogic_rdconfig(struct blogic_adapter *adapter)
 {
-	struct BusLogic_BoardID BoardID;
-	struct BusLogic_Configuration Configuration;
-	struct BusLogic_SetupInformation SetupInformation;
-	struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
-	unsigned char HostAdapterModelNumber[5];
-	unsigned char FirmwareVersion3rdDigit;
-	unsigned char FirmwareVersionLetter;
-	struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
-	struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
-	struct BusLogic_AutoSCSIData AutoSCSIData;
-	union BusLogic_GeometryRegister GeometryRegister;
-	unsigned char RequestedReplyLength;
-	unsigned char *TargetPointer, Character;
-	int TargetID, i;
+	struct blogic_board_id id;
+	struct blogic_config config;
+	struct blogic_setup_info setupinfo;
+	struct blogic_ext_setup ext_setupinfo;
+	unsigned char model[5];
+	unsigned char fw_ver_digit3;
+	unsigned char fw_ver_letter;
+	struct blogic_adapter_info adapter_info;
+	struct blogic_fetch_localram fetch_localram;
+	struct blogic_autoscsi autoscsi;
+	union blogic_geo_reg georeg;
+	unsigned char req_replylen;
+	unsigned char *tgt, ch;
+	int tgt_id, i;
 	/*
-	   Configuration Information for FlashPoint Host Adapters is provided in the
-	   FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
-	   Initialize fields in the Host Adapter structure from the FlashPoint_Info
-	   structure.
+	   Configuration Information for FlashPoint Host Adapters is
+	   provided in the fpoint_info structure by the FlashPoint
+	   SCCB Manager's Probe Function. Initialize fields in the
+	   Host Adapter structure from the fpoint_info structure.
 	 */
-	if (BusLogic_FlashPointHostAdapterP(HostAdapter)) {
-		struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
-		TargetPointer = HostAdapter->ModelName;
-		*TargetPointer++ = 'B';
-		*TargetPointer++ = 'T';
-		*TargetPointer++ = '-';
-		for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
-			*TargetPointer++ = FlashPointInfo->ModelNumber[i];
-		*TargetPointer++ = '\0';
-		strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
-		HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
-		HostAdapter->ExtendedTranslationEnabled = FlashPointInfo->ExtendedTranslationEnabled;
-		HostAdapter->ParityCheckingEnabled = FlashPointInfo->ParityCheckingEnabled;
-		HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
-		HostAdapter->LevelSensitiveInterrupt = true;
-		HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
-		HostAdapter->HostDifferentialSCSI = false;
-		HostAdapter->HostSupportsSCAM = true;
-		HostAdapter->HostUltraSCSI = true;
-		HostAdapter->ExtendedLUNSupport = true;
-		HostAdapter->TerminationInfoValid = true;
-		HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
-		HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
-		HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
-		HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
-		HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
-		HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
-		HostAdapter->MaxLogicalUnits = 32;
-		HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
-		HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
-		HostAdapter->DriverQueueDepth = 255;
-		HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
-		HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
-		HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
-		HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
-		HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
-		HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
-		HostAdapter->TaggedQueuingPermitted = 0xFFFF;
-		goto Common;
+	if (blogic_flashpoint_type(adapter)) {
+		struct fpoint_info *fpinfo = &adapter->fpinfo;
+		tgt = adapter->model;
+		*tgt++ = 'B';
+		*tgt++ = 'T';
+		*tgt++ = '-';
+		for (i = 0; i < sizeof(fpinfo->model); i++)
+			*tgt++ = fpinfo->model[i];
+		*tgt++ = '\0';
+		strcpy(adapter->fw_ver, FLASHPOINT_FW_VER);
+		adapter->scsi_id = fpinfo->scsi_id;
+		adapter->ext_trans_enable = fpinfo->ext_trans_enable;
+		adapter->parity = fpinfo->parity;
+		adapter->reset_enabled = !fpinfo->softreset;
+		adapter->level_int = true;
+		adapter->wide = fpinfo->wide;
+		adapter->differential = false;
+		adapter->scam = true;
+		adapter->ultra = true;
+		adapter->ext_lun = true;
+		adapter->terminfo_valid = true;
+		adapter->low_term = fpinfo->low_term;
+		adapter->high_term = fpinfo->high_term;
+		adapter->scam_enabled = fpinfo->scam_enabled;
+		adapter->scam_lev2 = fpinfo->scam_lev2;
+		adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
+		adapter->maxdev = (adapter->wide ? 16 : 8);
+		adapter->maxlun = 32;
+		adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
+		adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
+		adapter->drvr_qdepth = 255;
+		adapter->adapter_qdepth = adapter->drvr_qdepth;
+		adapter->sync_ok = fpinfo->sync_ok;
+		adapter->fast_ok = fpinfo->fast_ok;
+		adapter->ultra_ok = fpinfo->ultra_ok;
+		adapter->wide_ok = fpinfo->wide_ok;
+		adapter->discon_ok = fpinfo->discon_ok;
+		adapter->tagq_ok = 0xFFFF;
+		goto common;
 	}
 	/*
 	   Issue the Inquire Board ID command.
 	 */
-	if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)) != sizeof(BoardID))
-		return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
+	if (blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id,
+				sizeof(id)) != sizeof(id))
+		return blogic_failure(adapter, "INQUIRE BOARD ID");
 	/*
 	   Issue the Inquire Configuration command.
 	 */
-	if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0, &Configuration, sizeof(Configuration))
-	    != sizeof(Configuration))
-		return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
+	if (blogic_cmd(adapter, BLOGIC_INQ_CONFIG, NULL, 0, &config,
+				sizeof(config))
+	    != sizeof(config))
+		return blogic_failure(adapter, "INQUIRE CONFIGURATION");
 	/*
 	   Issue the Inquire Setup Information command.
 	 */
-	RequestedReplyLength = sizeof(SetupInformation);
-	if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
-	    != sizeof(SetupInformation))
-		return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
+	req_replylen = sizeof(setupinfo);
+	if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
+				sizeof(req_replylen), &setupinfo,
+				sizeof(setupinfo)) != sizeof(setupinfo))
+		return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
 	/*
 	   Issue the Inquire Extended Setup Information command.
 	 */
-	RequestedReplyLength = sizeof(ExtendedSetupInformation);
-	if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation))
-	    != sizeof(ExtendedSetupInformation))
-		return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
+	req_replylen = sizeof(ext_setupinfo);
+	if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
+				sizeof(req_replylen), &ext_setupinfo,
+				sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
+		return blogic_failure(adapter,
+					"INQUIRE EXTENDED SETUP INFORMATION");
 	/*
 	   Issue the Inquire Firmware Version 3rd Digit command.
 	 */
-	FirmwareVersion3rdDigit = '\0';
-	if (BoardID.FirmwareVersion1stDigit > '0')
-		if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, NULL, 0, &FirmwareVersion3rdDigit, sizeof(FirmwareVersion3rdDigit))
-		    != sizeof(FirmwareVersion3rdDigit))
-			return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
+	fw_ver_digit3 = '\0';
+	if (id.fw_ver_digit1 > '0')
+		if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_D3, NULL, 0,
+				&fw_ver_digit3,
+				sizeof(fw_ver_digit3)) != sizeof(fw_ver_digit3))
+			return blogic_failure(adapter,
+						"INQUIRE FIRMWARE 3RD DIGIT");
 	/*
 	   Issue the Inquire Host Adapter Model Number command.
 	 */
-	if (ExtendedSetupInformation.BusType == 'A' && BoardID.FirmwareVersion1stDigit == '2')
+	if (ext_setupinfo.bus_type == 'A' && id.fw_ver_digit1 == '2')
 		/* BusLogic BT-542B ISA 2.xx */
-		strcpy(HostAdapterModelNumber, "542B");
-	else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '2' && (BoardID.FirmwareVersion2ndDigit <= '1' || (BoardID.FirmwareVersion2ndDigit == '2' && FirmwareVersion3rdDigit == '0')))
+		strcpy(model, "542B");
+	else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '2' &&
+			(id.fw_ver_digit2 <= '1' || (id.fw_ver_digit2 == '2' &&
+						     fw_ver_digit3 == '0')))
 		/* BusLogic BT-742A EISA 2.1x or 2.20 */
-		strcpy(HostAdapterModelNumber, "742A");
-	else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '0')
+		strcpy(model, "742A");
+	else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '0')
 		/* AMI FastDisk EISA Series 441 0.x */
-		strcpy(HostAdapterModelNumber, "747A");
+		strcpy(model, "747A");
 	else {
-		RequestedReplyLength = sizeof(HostAdapterModelNumber);
-		if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber, &RequestedReplyLength, sizeof(RequestedReplyLength), &HostAdapterModelNumber, sizeof(HostAdapterModelNumber))
-		    != sizeof(HostAdapterModelNumber))
-			return BusLogic_Failure(HostAdapter, "INQUIRE HOST ADAPTER MODEL NUMBER");
+		req_replylen = sizeof(model);
+		if (blogic_cmd(adapter, BLOGIC_INQ_MODELNO, &req_replylen,
+					sizeof(req_replylen), &model,
+					sizeof(model)) != sizeof(model))
+			return blogic_failure(adapter,
+					"INQUIRE HOST ADAPTER MODEL NUMBER");
 	}
 	/*
-	   BusLogic MultiMaster Host Adapters can be identified by their model number
-	   and the major version number of their firmware as follows:
+	   BusLogic MultiMaster Host Adapters can be identified by their
+	   model number and the major version number of their firmware
+	   as follows:
 
 	   5.xx       BusLogic "W" Series Host Adapters:
 	   BT-948/958/958D
@@ -1374,497 +1480,535 @@ static bool __init BusLogic_ReadHostAdap
 	   0.xx       AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
 	 */
 	/*
-	   Save the Model Name and Host Adapter Name in the Host Adapter structure.
+	   Save the Model Name and Host Adapter Name in the Host Adapter
+	   structure.
 	 */
-	TargetPointer = HostAdapter->ModelName;
-	*TargetPointer++ = 'B';
-	*TargetPointer++ = 'T';
-	*TargetPointer++ = '-';
-	for (i = 0; i < sizeof(HostAdapterModelNumber); i++) {
-		Character = HostAdapterModelNumber[i];
-		if (Character == ' ' || Character == '\0')
+	tgt = adapter->model;
+	*tgt++ = 'B';
+	*tgt++ = 'T';
+	*tgt++ = '-';
+	for (i = 0; i < sizeof(model); i++) {
+		ch = model[i];
+		if (ch == ' ' || ch == '\0')
 			break;
-		*TargetPointer++ = Character;
+		*tgt++ = ch;
 	}
-	*TargetPointer++ = '\0';
+	*tgt++ = '\0';
 	/*
 	   Save the Firmware Version in the Host Adapter structure.
 	 */
-	TargetPointer = HostAdapter->FirmwareVersion;
-	*TargetPointer++ = BoardID.FirmwareVersion1stDigit;
-	*TargetPointer++ = '.';
-	*TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
-	if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
-		*TargetPointer++ = FirmwareVersion3rdDigit;
-	*TargetPointer = '\0';
+	tgt = adapter->fw_ver;
+	*tgt++ = id.fw_ver_digit1;
+	*tgt++ = '.';
+	*tgt++ = id.fw_ver_digit2;
+	if (fw_ver_digit3 != ' ' && fw_ver_digit3 != '\0')
+		*tgt++ = fw_ver_digit3;
+	*tgt = '\0';
 	/*
 	   Issue the Inquire Firmware Version Letter command.
 	 */
-	if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0) {
-		if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter, NULL, 0, &FirmwareVersionLetter, sizeof(FirmwareVersionLetter))
-		    != sizeof(FirmwareVersionLetter))
-			return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
-		if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
-			*TargetPointer++ = FirmwareVersionLetter;
-		*TargetPointer = '\0';
+	if (strcmp(adapter->fw_ver, "3.3") >= 0) {
+		if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_LETTER, NULL, 0,
+				&fw_ver_letter,
+				sizeof(fw_ver_letter)) != sizeof(fw_ver_letter))
+			return blogic_failure(adapter,
+					"INQUIRE FIRMWARE VERSION LETTER");
+		if (fw_ver_letter != ' ' && fw_ver_letter != '\0')
+			*tgt++ = fw_ver_letter;
+		*tgt = '\0';
 	}
 	/*
 	   Save the Host Adapter SCSI ID in the Host Adapter structure.
 	 */
-	HostAdapter->SCSI_ID = Configuration.HostAdapterID;
+	adapter->scsi_id = config.id;
 	/*
-	   Determine the Bus Type and save it in the Host Adapter structure, determine
-	   and save the IRQ Channel if necessary, and determine and save the DMA
-	   Channel for ISA Host Adapters.
+	   Determine the Bus Type and save it in the Host Adapter structure,
+	   determine and save the IRQ Channel if necessary, and determine
+	   and save the DMA Channel for ISA Host Adapters.
 	 */
-	HostAdapter->HostAdapterBusType = BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
-	if (HostAdapter->IRQ_Channel == 0) {
-		if (Configuration.IRQ_Channel9)
-			HostAdapter->IRQ_Channel = 9;
-		else if (Configuration.IRQ_Channel10)
-			HostAdapter->IRQ_Channel = 10;
-		else if (Configuration.IRQ_Channel11)
-			HostAdapter->IRQ_Channel = 11;
-		else if (Configuration.IRQ_Channel12)
-			HostAdapter->IRQ_Channel = 12;
-		else if (Configuration.IRQ_Channel14)
-			HostAdapter->IRQ_Channel = 14;
-		else if (Configuration.IRQ_Channel15)
-			HostAdapter->IRQ_Channel = 15;
+	adapter->adapter_bus_type =
+			blogic_adater_bus_types[adapter->model[3] - '4'];
+	if (adapter->irq_ch == 0) {
+		if (config.irq_ch9)
+			adapter->irq_ch = 9;
+		else if (config.irq_ch10)
+			adapter->irq_ch = 10;
+		else if (config.irq_ch11)
+			adapter->irq_ch = 11;
+		else if (config.irq_ch12)
+			adapter->irq_ch = 12;
+		else if (config.irq_ch14)
+			adapter->irq_ch = 14;
+		else if (config.irq_ch15)
+			adapter->irq_ch = 15;
 	}
-	if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) {
-		if (Configuration.DMA_Channel5)
-			HostAdapter->DMA_Channel = 5;
-		else if (Configuration.DMA_Channel6)
-			HostAdapter->DMA_Channel = 6;
-		else if (Configuration.DMA_Channel7)
-			HostAdapter->DMA_Channel = 7;
+	if (adapter->adapter_bus_type == BLOGIC_ISA_BUS) {
+		if (config.dma_ch5)
+			adapter->dma_ch = 5;
+		else if (config.dma_ch6)
+			adapter->dma_ch = 6;
+		else if (config.dma_ch7)
+			adapter->dma_ch = 7;
 	}
 	/*
 	   Determine whether Extended Translation is enabled and save it in
 	   the Host Adapter structure.
 	 */
-	GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
-	HostAdapter->ExtendedTranslationEnabled = GeometryRegister.gr.ExtendedTranslationEnabled;
+	georeg.all = blogic_rdgeom(adapter);
+	adapter->ext_trans_enable = georeg.gr.ext_trans_enable;
 	/*
 	   Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
 	   SCSI flag, Differential SCSI flag, SCAM Supported flag, and
 	   Ultra SCSI flag in the Host Adapter structure.
 	 */
-	HostAdapter->HostAdapterScatterGatherLimit = ExtendedSetupInformation.ScatterGatherLimit;
-	HostAdapter->DriverScatterGatherLimit = HostAdapter->HostAdapterScatterGatherLimit;
-	if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
-		HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
-	if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
-		HostAdapter->LevelSensitiveInterrupt = true;
-	HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
-	HostAdapter->HostDifferentialSCSI = ExtendedSetupInformation.HostDifferentialSCSI;
-	HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
-	HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
+	adapter->adapter_sglimit = ext_setupinfo.sg_limit;
+	adapter->drvr_sglimit = adapter->adapter_sglimit;
+	if (adapter->adapter_sglimit > BLOGIC_SG_LIMIT)
+		adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
+	if (ext_setupinfo.misc.level_int)
+		adapter->level_int = true;
+	adapter->wide = ext_setupinfo.wide;
+	adapter->differential = ext_setupinfo.differential;
+	adapter->scam = ext_setupinfo.scam;
+	adapter->ultra = ext_setupinfo.ultra;
 	/*
 	   Determine whether Extended LUN Format CCBs are supported and save the
 	   information in the Host Adapter structure.
 	 */
-	if (HostAdapter->FirmwareVersion[0] == '5' || (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
-		HostAdapter->ExtendedLUNSupport = true;
+	if (adapter->fw_ver[0] == '5' || (adapter->fw_ver[0] == '4' &&
+				adapter->wide))
+		adapter->ext_lun = true;
 	/*
 	   Issue the Inquire PCI Host Adapter Information command to read the
 	   Termination Information from "W" series MultiMaster Host Adapters.
 	 */
-	if (HostAdapter->FirmwareVersion[0] == '5') {
-		if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation))
-		    != sizeof(PCIHostAdapterInformation))
-			return BusLogic_Failure(HostAdapter, "INQUIRE PCI HOST ADAPTER INFORMATION");
+	if (adapter->fw_ver[0] == '5') {
+		if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
+				&adapter_info,
+				sizeof(adapter_info)) != sizeof(adapter_info))
+			return blogic_failure(adapter,
+					"INQUIRE PCI HOST ADAPTER INFORMATION");
 		/*
-		   Save the Termination Information in the Host Adapter structure.
+		   Save the Termination Information in the Host Adapter
+		   structure.
 		 */
-		if (PCIHostAdapterInformation.GenericInfoValid) {
-			HostAdapter->TerminationInfoValid = true;
-			HostAdapter->LowByteTerminated = PCIHostAdapterInformation.LowByteTerminated;
-			HostAdapter->HighByteTerminated = PCIHostAdapterInformation.HighByteTerminated;
+		if (adapter_info.genericinfo_valid) {
+			adapter->terminfo_valid = true;
+			adapter->low_term = adapter_info.low_term;
+			adapter->high_term = adapter_info.high_term;
 		}
 	}
 	/*
-	   Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
-	   from "W" and "C" series MultiMaster Host Adapters.
+	   Issue the Fetch Host Adapter Local RAM command to read the
+	   AutoSCSI data from "W" and "C" series MultiMaster Host Adapters.
 	 */
-	if (HostAdapter->FirmwareVersion[0] >= '4') {
-		FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset;
-		FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
-		if (BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIData, sizeof(AutoSCSIData))
-		    != sizeof(AutoSCSIData))
-			return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
+	if (adapter->fw_ver[0] >= '4') {
+		fetch_localram.offset = BLOGIC_AUTOSCSI_BASE;
+		fetch_localram.count = sizeof(autoscsi);
+		if (blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM, &fetch_localram,
+					sizeof(fetch_localram), &autoscsi,
+					sizeof(autoscsi)) != sizeof(autoscsi))
+			return blogic_failure(adapter,
+						"FETCH HOST ADAPTER LOCAL RAM");
 		/*
-		   Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
-		   Information in the Host Adapter structure.
+		   Save the Parity Checking Enabled, Bus Reset Enabled,
+		   and Termination Information in the Host Adapter structure.
 		 */
-		HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
-		HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
-		if (HostAdapter->FirmwareVersion[0] == '4') {
-			HostAdapter->TerminationInfoValid = true;
-			HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
-			HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
+		adapter->parity = autoscsi.parity;
+		adapter->reset_enabled = autoscsi.reset_enabled;
+		if (adapter->fw_ver[0] == '4') {
+			adapter->terminfo_valid = true;
+			adapter->low_term = autoscsi.low_term;
+			adapter->high_term = autoscsi.high_term;
 		}
 		/*
-		   Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
-		   Disconnect Permitted, Ultra Permitted, and SCAM Information in the
-		   Host Adapter structure.
+		   Save the Wide Permitted, Fast Permitted, Synchronous
+		   Permitted, Disconnect Permitted, Ultra Permitted, and
+		   SCAM Information in the Host Adapter structure.
 		 */
-		HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
-		HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
-		HostAdapter->SynchronousPermitted = AutoSCSIData.SynchronousPermitted;
-		HostAdapter->DisconnectPermitted = AutoSCSIData.DisconnectPermitted;
-		if (HostAdapter->HostUltraSCSI)
-			HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
-		if (HostAdapter->HostSupportsSCAM) {
-			HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
-			HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
+		adapter->wide_ok = autoscsi.wide_ok;
+		adapter->fast_ok = autoscsi.fast_ok;
+		adapter->sync_ok = autoscsi.sync_ok;
+		adapter->discon_ok = autoscsi.discon_ok;
+		if (adapter->ultra)
+			adapter->ultra_ok = autoscsi.ultra_ok;
+		if (adapter->scam) {
+			adapter->scam_enabled = autoscsi.scam_enabled;
+			adapter->scam_lev2 = autoscsi.scam_lev2;
 		}
 	}
 	/*
-	   Initialize fields in the Host Adapter structure for "S" and "A" series
-	   MultiMaster Host Adapters.
+	   Initialize fields in the Host Adapter structure for "S" and "A"
+	   series MultiMaster Host Adapters.
 	 */
-	if (HostAdapter->FirmwareVersion[0] < '4') {
-		if (SetupInformation.SynchronousInitiationEnabled) {
-			HostAdapter->SynchronousPermitted = 0xFF;
-			if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus) {
-				if (ExtendedSetupInformation.Misc.FastOnEISA)
-					HostAdapter->FastPermitted = 0xFF;
-				if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
-					HostAdapter->WidePermitted = 0xFF;
+	if (adapter->fw_ver[0] < '4') {
+		if (setupinfo.sync) {
+			adapter->sync_ok = 0xFF;
+			if (adapter->adapter_bus_type == BLOGIC_EISA_BUS) {
+				if (ext_setupinfo.misc.fast_on_eisa)
+					adapter->fast_ok = 0xFF;
+				if (strcmp(adapter->model, "BT-757") == 0)
+					adapter->wide_ok = 0xFF;
 			}
 		}
-		HostAdapter->DisconnectPermitted = 0xFF;
-		HostAdapter->ParityCheckingEnabled = SetupInformation.ParityCheckingEnabled;
-		HostAdapter->BusResetEnabled = true;
+		adapter->discon_ok = 0xFF;
+		adapter->parity = setupinfo.parity;
+		adapter->reset_enabled = true;
 	}
 	/*
-	   Determine the maximum number of Target IDs and Logical Units supported by
-	   this driver for Wide and Narrow Host Adapters.
+	   Determine the maximum number of Target IDs and Logical Units
+	   supported by this driver for Wide and Narrow Host Adapters.
 	 */
-	HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
-	HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
+	adapter->maxdev = (adapter->wide ? 16 : 8);
+	adapter->maxlun = (adapter->ext_lun ? 32 : 8);
 	/*
 	   Select appropriate values for the Mailbox Count, Driver Queue Depth,
-	   Initial CCBs, and Incremental CCBs variables based on whether or not Strict
-	   Round Robin Mode is supported.  If Strict Round Robin Mode is supported,
-	   then there is no performance degradation in using the maximum possible
-	   number of Outgoing and Incoming Mailboxes and allowing the Tagged and
-	   Untagged Queue Depths to determine the actual utilization.  If Strict Round
-	   Robin Mode is not supported, then the Host Adapter must scan all the
-	   Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
-	   cause a substantial performance penalty.  The host adapters actually have
-	   room to store the following number of CCBs internally; that is, they can
-	   internally queue and manage this many active commands on the SCSI bus
-	   simultaneously.  Performance measurements demonstrate that the Driver Queue
-	   Depth should be set to the Mailbox Count, rather than the Host Adapter
-	   Queue Depth (internal CCB capacity), as it is more efficient to have the
-	   queued commands waiting in Outgoing Mailboxes if necessary than to block
-	   the process in the higher levels of the SCSI Subsystem.
+	   Initial CCBs, and Incremental CCBs variables based on whether
+	   or not Strict Round Robin Mode is supported.  If Strict Round
+	   Robin Mode is supported, then there is no performance degradation
+	   in using the maximum possible number of Outgoing and Incoming
+	   Mailboxes and allowing the Tagged and Untagged Queue Depths to
+	   determine the actual utilization.  If Strict Round Robin Mode is
+	   not supported, then the Host Adapter must scan all the Outgoing
+	   Mailboxes whenever an Outgoing Mailbox entry is made, which can
+	   cause a substantial performance penalty.  The host adapters
+	   actually have room to store the following number of CCBs
+	   internally; that is, they can internally queue and manage this
+	   many active commands on the SCSI bus simultaneously.  Performance
+	   measurements demonstrate that the Driver Queue Depth should be
+	   set to the Mailbox Count, rather than the Host Adapter Queue
+	   Depth (internal CCB capacity), as it is more efficient to have the
+	   queued commands waiting in Outgoing Mailboxes if necessary than
+	   to block the process in the higher levels of the SCSI Subsystem.
 
 	   192          BT-948/958/958D
 	   100          BT-946C/956C/956CD/747C/757C/757CD/445C
 	   50   BT-545C/540CF
 	   30   BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
 	 */
-	if (HostAdapter->FirmwareVersion[0] == '5')
-		HostAdapter->HostAdapterQueueDepth = 192;
-	else if (HostAdapter->FirmwareVersion[0] == '4')
-		HostAdapter->HostAdapterQueueDepth = (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
+	if (adapter->fw_ver[0] == '5')
+		adapter->adapter_qdepth = 192;
+	else if (adapter->fw_ver[0] == '4')
+		adapter->adapter_qdepth = (adapter->adapter_bus_type !=
+						BLOGIC_ISA_BUS ? 100 : 50);
 	else
-		HostAdapter->HostAdapterQueueDepth = 30;
-	if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) {
-		HostAdapter->StrictRoundRobinModeSupport = true;
-		HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
+		adapter->adapter_qdepth = 30;
+	if (strcmp(adapter->fw_ver, "3.31") >= 0) {
+		adapter->strict_rr = true;
+		adapter->mbox_count = BLOGIC_MAX_MAILBOX;
 	} else {
-		HostAdapter->StrictRoundRobinModeSupport = false;
-		HostAdapter->MailboxCount = 32;
+		adapter->strict_rr = false;
+		adapter->mbox_count = 32;
 	}
-	HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
-	HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
-	HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
+	adapter->drvr_qdepth = adapter->mbox_count;
+	adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
+	adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
 	/*
-	   Tagged Queuing support is available and operates properly on all "W" series
-	   MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
-	   firmware version 4.22 and above, and on "S" series MultiMaster Host
-	   Adapters with firmware version 3.35 and above.
+	   Tagged Queuing support is available and operates properly on
+	   all "W" series MultiMaster Host Adapters, on "C" series
+	   MultiMaster Host Adapters with firmware version 4.22 and above,
+	   and on "S" series MultiMaster Host Adapters with firmware version
+	   3.35 and above.
 	 */
-	HostAdapter->TaggedQueuingPermitted = 0;
-	switch (HostAdapter->FirmwareVersion[0]) {
+	adapter->tagq_ok = 0;
+	switch (adapter->fw_ver[0]) {
 	case '5':
-		HostAdapter->TaggedQueuingPermitted = 0xFFFF;
+		adapter->tagq_ok = 0xFFFF;
 		break;
 	case '4':
-		if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
-			HostAdapter->TaggedQueuingPermitted = 0xFFFF;
+		if (strcmp(adapter->fw_ver, "4.22") >= 0)
+			adapter->tagq_ok = 0xFFFF;
 		break;
 	case '3':
-		if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
-			HostAdapter->TaggedQueuingPermitted = 0xFFFF;
+		if (strcmp(adapter->fw_ver, "3.35") >= 0)
+			adapter->tagq_ok = 0xFFFF;
 		break;
 	}
 	/*
 	   Determine the Host Adapter BIOS Address if the BIOS is enabled and
 	   save it in the Host Adapter structure.  The BIOS is disabled if the
-	   BIOS_Address is 0.
+	   bios_addr is 0.
 	 */
-	HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
+	adapter->bios_addr = ext_setupinfo.bios_addr << 12;
 	/*
-	   ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
+	   ISA Host Adapters require Bounce Buffers if there is more than
+	   16MB memory.
 	 */
-	if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
-		HostAdapter->BounceBuffersRequired = true;
+	if (adapter->adapter_bus_type == BLOGIC_ISA_BUS &&
+			(void *) high_memory > (void *) MAX_DMA_ADDRESS)
+		adapter->need_bouncebuf = true;
 	/*
-	   BusLogic BT-445S Host Adapters prior to board revision E have a hardware
-	   bug whereby when the BIOS is enabled, transfers to/from the same address
-	   range the BIOS occupies modulo 16MB are handled incorrectly.  Only properly
-	   functioning BT-445S Host Adapters have firmware version 3.37, so require
-	   that ISA Bounce Buffers be used for the buggy BT-445S models if there is
-	   more than 16MB memory.
+	   BusLogic BT-445S Host Adapters prior to board revision E have a
+	   hardware bug whereby when the BIOS is enabled, transfers to/from
+	   the same address range the BIOS occupies modulo 16MB are handled
+	   incorrectly.  Only properly functioning BT-445S Host Adapters
+	   have firmware version 3.37, so require that ISA Bounce Buffers
+	   be used for the buggy BT-445S models if there is more than 16MB
+	   memory.
 	 */
-	if (HostAdapter->BIOS_Address > 0 && strcmp(HostAdapter->ModelName, "BT-445S") == 0 && strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 && (void *) high_memory > (void *) MAX_DMA_ADDRESS)
-		HostAdapter->BounceBuffersRequired = true;
+	if (adapter->bios_addr > 0 && strcmp(adapter->model, "BT-445S") == 0 &&
+			strcmp(adapter->fw_ver, "3.37") < 0 &&
+			(void *) high_memory > (void *) MAX_DMA_ADDRESS)
+		adapter->need_bouncebuf = true;
 	/*
-	   Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
+	   Initialize parameters common to MultiMaster and FlashPoint
+	   Host Adapters.
 	 */
-      Common:
+common:
 	/*
 	   Initialize the Host Adapter Full Model Name from the Model Name.
 	 */
-	strcpy(HostAdapter->FullModelName, "BusLogic ");
-	strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
+	strcpy(adapter->full_model, "BusLogic ");
+	strcat(adapter->full_model, adapter->model);
 	/*
 	   Select an appropriate value for the Tagged Queue Depth either from a
 	   BusLogic Driver Options specification, or based on whether this Host
-	   Adapter requires that ISA Bounce Buffers be used.  The Tagged Queue Depth
-	   is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
-	   Initialize the Untagged Queue Depth.
+	   Adapter requires that ISA Bounce Buffers be used.  The Tagged Queue
+	   Depth is left at 0 for automatic determination in
+	   BusLogic_SelectQueueDepths. Initialize the Untagged Queue Depth.
 	 */
-	for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
-		unsigned char QueueDepth = 0;
-		if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
-			QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
-		else if (HostAdapter->BounceBuffersRequired)
-			QueueDepth = BusLogic_TaggedQueueDepthBB;
-		HostAdapter->QueueDepth[TargetID] = QueueDepth;
+	for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
+		unsigned char qdepth = 0;
+		if (adapter->drvr_opts != NULL &&
+				adapter->drvr_opts->qdepth[tgt_id] > 0)
+			qdepth = adapter->drvr_opts->qdepth[tgt_id];
+		else if (adapter->need_bouncebuf)
+			qdepth = BLOGIC_TAG_DEPTH_BB;
+		adapter->qdepth[tgt_id] = qdepth;
 	}
-	if (HostAdapter->BounceBuffersRequired)
-		HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
+	if (adapter->need_bouncebuf)
+		adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH_BB;
 	else
-		HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
-	if (HostAdapter->DriverOptions != NULL)
-		HostAdapter->CommonQueueDepth = HostAdapter->DriverOptions->CommonQueueDepth;
-	if (HostAdapter->CommonQueueDepth > 0 && HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
-		HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
+		adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH;
+	if (adapter->drvr_opts != NULL)
+		adapter->common_qdepth = adapter->drvr_opts->common_qdepth;
+	if (adapter->common_qdepth > 0 &&
+			adapter->common_qdepth < adapter->untag_qdepth)
+		adapter->untag_qdepth = adapter->common_qdepth;
 	/*
 	   Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
 	   Therefore, mask the Tagged Queuing Permitted Default bits with the
 	   Disconnect/Reconnect Permitted bits.
 	 */
-	HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
+	adapter->tagq_ok &= adapter->discon_ok;
 	/*
-	   Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
-	   Options Tagged Queuing specification.
+	   Combine the default Tagged Queuing Permitted bits with any
+	   BusLogic Driver Options Tagged Queuing specification.
 	 */
-	if (HostAdapter->DriverOptions != NULL)
-		HostAdapter->TaggedQueuingPermitted =
-		    (HostAdapter->DriverOptions->TaggedQueuingPermitted & HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | (HostAdapter->TaggedQueuingPermitted & ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
+	if (adapter->drvr_opts != NULL)
+		adapter->tagq_ok = (adapter->drvr_opts->tagq_ok &
+				adapter->drvr_opts->tagq_ok_mask) |
+			(adapter->tagq_ok & ~adapter->drvr_opts->tagq_ok_mask);
 
 	/*
-	   Select an appropriate value for Bus Settle Time either from a BusLogic
-	   Driver Options specification, or from BusLogic_DefaultBusSettleTime.
+	   Select an appropriate value for Bus Settle Time either from a
+	   BusLogic Driver Options specification, or from
+	   BLOGIC_BUS_SETTLE_TIME.
 	 */
-	if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->BusSettleTime > 0)
-		HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
+	if (adapter->drvr_opts != NULL &&
+			adapter->drvr_opts->bus_settle_time > 0)
+		adapter->bus_settle_time = adapter->drvr_opts->bus_settle_time;
 	else
-		HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
+		adapter->bus_settle_time = BLOGIC_BUS_SETTLE_TIME;
 	/*
-	   Indicate reading the Host Adapter Configuration completed successfully.
+	   Indicate reading the Host Adapter Configuration completed
+	   successfully.
 	 */
 	return true;
 }
 
 
 /*
-  BusLogic_ReportHostAdapterConfiguration reports the configuration of
-  Host Adapter.
+  blogic_reportconfig reports the configuration of Host Adapter.
 */
 
-static bool __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter
-							      *HostAdapter)
+static bool __init blogic_reportconfig(struct blogic_adapter *adapter)
 {
-	unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
-	unsigned short SynchronousPermitted, FastPermitted;
-	unsigned short UltraPermitted, WidePermitted;
-	unsigned short DisconnectPermitted, TaggedQueuingPermitted;
-	bool CommonSynchronousNegotiation, CommonTaggedQueueDepth;
-	char SynchronousString[BusLogic_MaxTargetDevices + 1];
-	char WideString[BusLogic_MaxTargetDevices + 1];
-	char DisconnectString[BusLogic_MaxTargetDevices + 1];
-	char TaggedQueuingString[BusLogic_MaxTargetDevices + 1];
-	char *SynchronousMessage = SynchronousString;
-	char *WideMessage = WideString;
-	char *DisconnectMessage = DisconnectString;
-	char *TaggedQueuingMessage = TaggedQueuingString;
-	int TargetID;
-	BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
-		      HostAdapter, HostAdapter->ModelName,
-		      BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType], (HostAdapter->HostWideSCSI ? " Wide" : ""), (HostAdapter->HostDifferentialSCSI ? " Differential" : ""), (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
-	BusLogic_Info("  Firmware Version: %s, I/O Address: 0x%X, " "IRQ Channel: %d/%s\n", HostAdapter, HostAdapter->FirmwareVersion, HostAdapter->IO_Address, HostAdapter->IRQ_Channel, (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
-	if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus) {
-		BusLogic_Info("  DMA Channel: ", HostAdapter);
-		if (HostAdapter->DMA_Channel > 0)
-			BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
+	unsigned short alltgt_mask = (1 << adapter->maxdev) - 1;
+	unsigned short sync_ok, fast_ok;
+	unsigned short ultra_ok, wide_ok;
+	unsigned short discon_ok, tagq_ok;
+	bool common_syncneg, common_tagq_depth;
+	char syncstr[BLOGIC_MAXDEV + 1];
+	char widestr[BLOGIC_MAXDEV + 1];
+	char discon_str[BLOGIC_MAXDEV + 1];
+	char tagq_str[BLOGIC_MAXDEV + 1];
+	char *syncmsg = syncstr;
+	char *widemsg = widestr;
+	char *discon_msg = discon_str;
+	char *tagq_msg = tagq_str;
+	int tgt_id;
+
+	blogic_info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n", adapter, adapter->model, blogic_adapter_busnames[adapter->adapter_bus_type], (adapter->wide ? " Wide" : ""), (adapter->differential ? " Differential" : ""), (adapter->ultra ? " Ultra" : ""));
+	blogic_info("  Firmware Version: %s, I/O Address: 0x%X, " "IRQ Channel: %d/%s\n", adapter, adapter->fw_ver, adapter->io_addr, adapter->irq_ch, (adapter->level_int ? "Level" : "Edge"));
+	if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) {
+		blogic_info("  DMA Channel: ", adapter);
+		if (adapter->dma_ch > 0)
+			blogic_info("%d, ", adapter, adapter->dma_ch);
 		else
-			BusLogic_Info("None, ", HostAdapter);
-		if (HostAdapter->BIOS_Address > 0)
-			BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter, HostAdapter->BIOS_Address);
+			blogic_info("None, ", adapter);
+		if (adapter->bios_addr > 0)
+			blogic_info("BIOS Address: 0x%X, ", adapter,
+					adapter->bios_addr);
 		else
-			BusLogic_Info("BIOS Address: None, ", HostAdapter);
+			blogic_info("BIOS Address: None, ", adapter);
 	} else {
-		BusLogic_Info("  PCI Bus: %d, Device: %d, Address: ", HostAdapter, HostAdapter->Bus, HostAdapter->Device);
-		if (HostAdapter->PCI_Address > 0)
-			BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
+		blogic_info("  PCI Bus: %d, Device: %d, Address: ", adapter,
+				adapter->bus, adapter->dev);
+		if (adapter->pci_addr > 0)
+			blogic_info("0x%X, ", adapter, adapter->pci_addr);
 		else
-			BusLogic_Info("Unassigned, ", HostAdapter);
+			blogic_info("Unassigned, ", adapter);
 	}
-	BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter, HostAdapter->SCSI_ID);
-	BusLogic_Info("  Parity Checking: %s, Extended Translation: %s\n", HostAdapter, (HostAdapter->ParityCheckingEnabled ? "Enabled" : "Disabled"), (HostAdapter->ExtendedTranslationEnabled ? "Enabled" : "Disabled"));
-	AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
-	SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
-	FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
-	UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
-	if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) && (HostAdapter->FirmwareVersion[0] >= '4' || HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) || BusLogic_FlashPointHostAdapterP(HostAdapter)) {
-		CommonSynchronousNegotiation = false;
-		if (SynchronousPermitted == 0) {
-			SynchronousMessage = "Disabled";
-			CommonSynchronousNegotiation = true;
-		} else if (SynchronousPermitted == AllTargetsMask) {
-			if (FastPermitted == 0) {
-				SynchronousMessage = "Slow";
-				CommonSynchronousNegotiation = true;
-			} else if (FastPermitted == AllTargetsMask) {
-				if (UltraPermitted == 0) {
-					SynchronousMessage = "Fast";
-					CommonSynchronousNegotiation = true;
-				} else if (UltraPermitted == AllTargetsMask) {
-					SynchronousMessage = "Ultra";
-					CommonSynchronousNegotiation = true;
+	blogic_info("Host Adapter SCSI ID: %d\n", adapter, adapter->scsi_id);
+	blogic_info("  Parity Checking: %s, Extended Translation: %s\n",
+			adapter, (adapter->parity ? "Enabled" : "Disabled"),
+			(adapter->ext_trans_enable ? "Enabled" : "Disabled"));
+	alltgt_mask &= ~(1 << adapter->scsi_id);
+	sync_ok = adapter->sync_ok & alltgt_mask;
+	fast_ok = adapter->fast_ok & alltgt_mask;
+	ultra_ok = adapter->ultra_ok & alltgt_mask;
+	if ((blogic_multimaster_type(adapter) &&
+			(adapter->fw_ver[0] >= '4' ||
+			 adapter->adapter_bus_type == BLOGIC_EISA_BUS)) ||
+			blogic_flashpoint_type(adapter)) {
+		common_syncneg = false;
+		if (sync_ok == 0) {
+			syncmsg = "Disabled";
+			common_syncneg = true;
+		} else if (sync_ok == alltgt_mask) {
+			if (fast_ok == 0) {
+				syncmsg = "Slow";
+				common_syncneg = true;
+			} else if (fast_ok == alltgt_mask) {
+				if (ultra_ok == 0) {
+					syncmsg = "Fast";
+					common_syncneg = true;
+				} else if (ultra_ok == alltgt_mask) {
+					syncmsg = "Ultra";
+					common_syncneg = true;
 				}
 			}
 		}
-		if (!CommonSynchronousNegotiation) {
-			for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-				SynchronousString[TargetID] = ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' : (!(FastPermitted & (1 << TargetID)) ? 'S' : (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
-			SynchronousString[HostAdapter->SCSI_ID] = '#';
-			SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
+		if (!common_syncneg) {
+			for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+				syncstr[tgt_id] = ((!(sync_ok & (1 << tgt_id))) ? 'N' : (!(fast_ok & (1 << tgt_id)) ? 'S' : (!(ultra_ok & (1 << tgt_id)) ? 'F' : 'U')));
+			syncstr[adapter->scsi_id] = '#';
+			syncstr[adapter->maxdev] = '\0';
 		}
 	} else
-		SynchronousMessage = (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
-	WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
-	if (WidePermitted == 0)
-		WideMessage = "Disabled";
-	else if (WidePermitted == AllTargetsMask)
-		WideMessage = "Enabled";
+		syncmsg = (sync_ok == 0 ? "Disabled" : "Enabled");
+	wide_ok = adapter->wide_ok & alltgt_mask;
+	if (wide_ok == 0)
+		widemsg = "Disabled";
+	else if (wide_ok == alltgt_mask)
+		widemsg = "Enabled";
 	else {
-		for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-			WideString[TargetID] = ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
-		WideString[HostAdapter->SCSI_ID] = '#';
-		WideString[HostAdapter->MaxTargetDevices] = '\0';
+		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+			widestr[tgt_id] = ((wide_ok & (1 << tgt_id)) ? 'Y' : 'N');
+		widestr[adapter->scsi_id] = '#';
+		widestr[adapter->maxdev] = '\0';
 	}
-	DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
-	if (DisconnectPermitted == 0)
-		DisconnectMessage = "Disabled";
-	else if (DisconnectPermitted == AllTargetsMask)
-		DisconnectMessage = "Enabled";
+	discon_ok = adapter->discon_ok & alltgt_mask;
+	if (discon_ok == 0)
+		discon_msg = "Disabled";
+	else if (discon_ok == alltgt_mask)
+		discon_msg = "Enabled";
 	else {
-		for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-			DisconnectString[TargetID] = ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
-		DisconnectString[HostAdapter->SCSI_ID] = '#';
-		DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
+		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+			discon_str[tgt_id] = ((discon_ok & (1 << tgt_id)) ? 'Y' : 'N');
+		discon_str[adapter->scsi_id] = '#';
+		discon_str[adapter->maxdev] = '\0';
 	}
-	TaggedQueuingPermitted = HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
-	if (TaggedQueuingPermitted == 0)
-		TaggedQueuingMessage = "Disabled";
-	else if (TaggedQueuingPermitted == AllTargetsMask)
-		TaggedQueuingMessage = "Enabled";
+	tagq_ok = adapter->tagq_ok & alltgt_mask;
+	if (tagq_ok == 0)
+		tagq_msg = "Disabled";
+	else if (tagq_ok == alltgt_mask)
+		tagq_msg = "Enabled";
 	else {
-		for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-			TaggedQueuingString[TargetID] = ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
-		TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
-		TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
+		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+			tagq_str[tgt_id] = ((tagq_ok & (1 << tgt_id)) ? 'Y' : 'N');
+		tagq_str[adapter->scsi_id] = '#';
+		tagq_str[adapter->maxdev] = '\0';
 	}
-	BusLogic_Info("  Synchronous Negotiation: %s, Wide Negotiation: %s\n", HostAdapter, SynchronousMessage, WideMessage);
-	BusLogic_Info("  Disconnect/Reconnect: %s, Tagged Queuing: %s\n", HostAdapter, DisconnectMessage, TaggedQueuingMessage);
-	if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
-		BusLogic_Info("  Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", HostAdapter, HostAdapter->DriverScatterGatherLimit, HostAdapter->HostAdapterScatterGatherLimit, HostAdapter->MailboxCount);
-		BusLogic_Info("  Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->HostAdapterQueueDepth);
+	blogic_info("  Synchronous Negotiation: %s, Wide Negotiation: %s\n",
+			adapter, syncmsg, widemsg);
+	blogic_info("  Disconnect/Reconnect: %s, Tagged Queuing: %s\n", adapter,
+			discon_msg, tagq_msg);
+	if (blogic_multimaster_type(adapter)) {
+		blogic_info("  Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", adapter, adapter->drvr_sglimit, adapter->adapter_sglimit, adapter->mbox_count);
+		blogic_info("  Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", adapter, adapter->drvr_qdepth, adapter->adapter_qdepth);
 	} else
-		BusLogic_Info("  Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->DriverScatterGatherLimit);
-	BusLogic_Info("  Tagged Queue Depth: ", HostAdapter);
-	CommonTaggedQueueDepth = true;
-	for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-		if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) {
-			CommonTaggedQueueDepth = false;
+		blogic_info("  Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", adapter, adapter->drvr_qdepth, adapter->drvr_sglimit);
+	blogic_info("  Tagged Queue Depth: ", adapter);
+	common_tagq_depth = true;
+	for (tgt_id = 1; tgt_id < adapter->maxdev; tgt_id++)
+		if (adapter->qdepth[tgt_id] != adapter->qdepth[0]) {
+			common_tagq_depth = false;
 			break;
 		}
-	if (CommonTaggedQueueDepth) {
-		if (HostAdapter->QueueDepth[0] > 0)
-			BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
+	if (common_tagq_depth) {
+		if (adapter->qdepth[0] > 0)
+			blogic_info("%d", adapter, adapter->qdepth[0]);
 		else
-			BusLogic_Info("Automatic", HostAdapter);
+			blogic_info("Automatic", adapter);
 	} else
-		BusLogic_Info("Individual", HostAdapter);
-	BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, HostAdapter->UntaggedQueueDepth);
-	if (HostAdapter->TerminationInfoValid) {
-		if (HostAdapter->HostWideSCSI)
-			BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? (HostAdapter->HighByteTerminated ? "Both Enabled" : "Low Enabled")
-										  : (HostAdapter->HighByteTerminated ? "High Enabled" : "Both Disabled")));
+		blogic_info("Individual", adapter);
+	blogic_info(", Untagged Queue Depth: %d\n", adapter,
+			adapter->untag_qdepth);
+	if (adapter->terminfo_valid) {
+		if (adapter->wide)
+			blogic_info("  SCSI Bus Termination: %s", adapter,
+				(adapter->low_term ? (adapter->high_term ? "Both Enabled" : "Low Enabled") : (adapter->high_term ? "High Enabled" : "Both Disabled")));
 		else
-			BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled"));
-		if (HostAdapter->HostSupportsSCAM)
-			BusLogic_Info(", SCAM: %s", HostAdapter, (HostAdapter->SCAM_Enabled ? (HostAdapter->SCAM_Level2 ? "Enabled, Level 2" : "Enabled, Level 1")
-								  : "Disabled"));
-		BusLogic_Info("\n", HostAdapter);
+			blogic_info("  SCSI Bus Termination: %s", adapter,
+				(adapter->low_term ? "Enabled" : "Disabled"));
+		if (adapter->scam)
+			blogic_info(", SCAM: %s", adapter,
+				(adapter->scam_enabled ? (adapter->scam_lev2 ? "Enabled, Level 2" : "Enabled, Level 1") : "Disabled"));
+		blogic_info("\n", adapter);
 	}
 	/*
-	   Indicate reporting the Host Adapter configuration completed successfully.
+	   Indicate reporting the Host Adapter configuration completed
+	   successfully.
 	 */
 	return true;
 }
 
 
 /*
-  BusLogic_AcquireResources acquires the system resources necessary to use
+  blogic_getres acquires the system resources necessary to use
   Host Adapter.
 */
 
-static bool __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter)
+static bool __init blogic_getres(struct blogic_adapter *adapter)
 {
-	if (HostAdapter->IRQ_Channel == 0) {
-		BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter);
+	if (adapter->irq_ch == 0) {
+		blogic_err("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
+				adapter);
 		return false;
 	}
 	/*
 	   Acquire shared access to the IRQ Channel.
 	 */
-	if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, IRQF_SHARED, HostAdapter->FullModelName, HostAdapter) < 0) {
-		BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->IRQ_Channel);
+	if (request_irq(adapter->irq_ch, blogic_inthandler, IRQF_SHARED,
+				adapter->full_model, adapter) < 0) {
+		blogic_err("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
+				adapter, adapter->irq_ch);
 		return false;
 	}
-	HostAdapter->IRQ_ChannelAcquired = true;
+	adapter->irq_acquired = true;
 	/*
 	   Acquire exclusive access to the DMA Channel.
 	 */
-	if (HostAdapter->DMA_Channel > 0) {
-		if (request_dma(HostAdapter->DMA_Channel, HostAdapter->FullModelName) < 0) {
-			BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->DMA_Channel);
+	if (adapter->dma_ch > 0) {
+		if (request_dma(adapter->dma_ch, adapter->full_model) < 0) {
+			blogic_err("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", adapter, adapter->dma_ch);
 			return false;
 		}
-		set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
-		enable_dma(HostAdapter->DMA_Channel);
-		HostAdapter->DMA_ChannelAcquired = true;
+		set_dma_mode(adapter->dma_ch, DMA_MODE_CASCADE);
+		enable_dma(adapter->dma_ch);
+		adapter->dma_chan_acquired = true;
 	}
 	/*
 	   Indicate the System Resource Acquisition completed successfully,
@@ -1874,127 +2018,146 @@ static bool __init BusLogic_AcquireResou
 
 
 /*
-  BusLogic_ReleaseResources releases any system resources previously acquired
-  by BusLogic_AcquireResources.
+  blogic_relres releases any system resources previously acquired
+  by blogic_getres.
 */
 
-static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter)
+static void blogic_relres(struct blogic_adapter *adapter)
 {
 	/*
 	   Release shared access to the IRQ Channel.
 	 */
-	if (HostAdapter->IRQ_ChannelAcquired)
-		free_irq(HostAdapter->IRQ_Channel, HostAdapter);
+	if (adapter->irq_acquired)
+		free_irq(adapter->irq_ch, adapter);
 	/*
 	   Release exclusive access to the DMA Channel.
 	 */
-	if (HostAdapter->DMA_ChannelAcquired)
-		free_dma(HostAdapter->DMA_Channel);
+	if (adapter->dma_chan_acquired)
+		free_dma(adapter->dma_ch);
 	/*
 	   Release any allocated memory structs not released elsewhere
 	 */
-	if (HostAdapter->MailboxSpace)
-		pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, HostAdapter->MailboxSpace, HostAdapter->MailboxSpaceHandle);
-	pci_dev_put(HostAdapter->PCI_Device);
-	HostAdapter->MailboxSpace = NULL;
-	HostAdapter->MailboxSpaceHandle = 0;
-	HostAdapter->MailboxSize = 0;
+	if (adapter->mbox_space)
+		pci_free_consistent(adapter->pci_device, adapter->mbox_sz,
+			adapter->mbox_space, adapter->mbox_space_handle);
+	pci_dev_put(adapter->pci_device);
+	adapter->mbox_space = NULL;
+	adapter->mbox_space_handle = 0;
+	adapter->mbox_sz = 0;
 }
 
 
 /*
-  BusLogic_InitializeHostAdapter initializes Host Adapter.  This is the only
+  blogic_initadapter initializes Host Adapter.  This is the only
   function called during SCSI Host Adapter detection which modifies the state
   of the Host Adapter from its initial power on or hard reset state.
 */
 
-static bool BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
-					      *HostAdapter)
+static bool blogic_initadapter(struct blogic_adapter *adapter)
 {
-	struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest;
-	enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest;
-	enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest;
-	int TargetID;
+	struct blogic_extmbox_req extmbox_req;
+	enum blogic_rr_req rr_req;
+	enum blogic_setccb_fmt setccb_fmt;
+	int tgt_id;
+
 	/*
-	   Initialize the pointers to the first and last CCBs that are queued for
-	   completion processing.
+	   Initialize the pointers to the first and last CCBs that are
+	   queued for completion processing.
 	 */
-	HostAdapter->FirstCompletedCCB = NULL;
-	HostAdapter->LastCompletedCCB = NULL;
+	adapter->firstccb = NULL;
+	adapter->lastccb = NULL;
+
 	/*
 	   Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
 	   Command Successful Flag, Active Commands, and Commands Since Reset
 	   for each Target Device.
 	 */
-	for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
-		HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
-		HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
-		HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
-		HostAdapter->ActiveCommands[TargetID] = 0;
-		HostAdapter->CommandsSinceReset[TargetID] = 0;
+	for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
+		adapter->bdr_pend[tgt_id] = NULL;
+		adapter->tgt_flags[tgt_id].tagq_active = false;
+		adapter->tgt_flags[tgt_id].cmd_good = false;
+		adapter->active_cmds[tgt_id] = 0;
+		adapter->cmds_since_rst[tgt_id] = 0;
 	}
+
 	/*
 	   FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
 	 */
-	if (BusLogic_FlashPointHostAdapterP(HostAdapter))
-		goto Done;
+	if (blogic_flashpoint_type(adapter))
+		goto done;
+
 	/*
 	   Initialize the Outgoing and Incoming Mailbox pointers.
 	 */
-	HostAdapter->MailboxSize = HostAdapter->MailboxCount * (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox));
-	HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle);
-	if (HostAdapter->MailboxSpace == NULL)
-		return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION");
-	HostAdapter->FirstOutgoingMailbox = (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace;
-	HostAdapter->LastOutgoingMailbox = HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
-	HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
-	HostAdapter->FirstIncomingMailbox = (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1);
-	HostAdapter->LastIncomingMailbox = HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
-	HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
+	adapter->mbox_sz = adapter->mbox_count * (sizeof(struct blogic_outbox) + sizeof(struct blogic_inbox));
+	adapter->mbox_space = pci_alloc_consistent(adapter->pci_device,
+				adapter->mbox_sz, &adapter->mbox_space_handle);
+	if (adapter->mbox_space == NULL)
+		return blogic_failure(adapter, "MAILBOX ALLOCATION");
+	adapter->first_outbox = (struct blogic_outbox *) adapter->mbox_space;
+	adapter->last_outbox = adapter->first_outbox + adapter->mbox_count - 1;
+	adapter->next_outbox = adapter->first_outbox;
+	adapter->first_inbox = (struct blogic_inbox *) (adapter->last_outbox + 1);
+	adapter->last_inbox = adapter->first_inbox + adapter->mbox_count - 1;
+	adapter->next_inbox = adapter->first_inbox;
 
 	/*
 	   Initialize the Outgoing and Incoming Mailbox structures.
 	 */
-	memset(HostAdapter->FirstOutgoingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox));
-	memset(HostAdapter->FirstIncomingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox));
+	memset(adapter->first_outbox, 0,
+			adapter->mbox_count * sizeof(struct blogic_outbox));
+	memset(adapter->first_inbox, 0,
+			adapter->mbox_count * sizeof(struct blogic_inbox));
+
 	/*
-	   Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
+	   Initialize the Host Adapter's Pointer to the Outgoing/Incoming
+	   Mailboxes.
 	 */
-	ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
-	ExtendedMailboxRequest.BaseMailboxAddress = (u32) HostAdapter->MailboxSpaceHandle;
-	if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox, &ExtendedMailboxRequest, sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
-		return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
+	extmbox_req.mbox_count = adapter->mbox_count;
+	extmbox_req.base_mbox_addr = (u32) adapter->mbox_space_handle;
+	if (blogic_cmd(adapter, BLOGIC_INIT_EXT_MBOX, &extmbox_req,
+				sizeof(extmbox_req), NULL, 0) < 0)
+		return blogic_failure(adapter, "MAILBOX INITIALIZATION");
 	/*
-	   Enable Strict Round Robin Mode if supported by the Host Adapter.  In
-	   Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
-	   Mailbox for each new command, rather than scanning through all the
-	   Outgoing Mailboxes to find any that have new commands in them.  Strict
-	   Round Robin Mode is significantly more efficient.
+	   Enable Strict Round Robin Mode if supported by the Host Adapter. In
+	   Strict Round Robin Mode, the Host Adapter only looks at the next
+	   Outgoing Mailbox for each new command, rather than scanning
+	   through all the Outgoing Mailboxes to find any that have new
+	   commands in them.  Strict Round Robin Mode is significantly more
+	   efficient.
 	 */
-	if (HostAdapter->StrictRoundRobinModeSupport) {
-		RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
-		if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode, &RoundRobinModeRequest, sizeof(RoundRobinModeRequest), NULL, 0) < 0)
-			return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
+	if (adapter->strict_rr) {
+		rr_req = BLOGIC_STRICT_RR_MODE;
+		if (blogic_cmd(adapter, BLOGIC_STRICT_RR, &rr_req,
+					sizeof(rr_req), NULL, 0) < 0)
+			return blogic_failure(adapter,
+					"ENABLE STRICT ROUND ROBIN MODE");
 	}
+
 	/*
-	   For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
-	   Format command to allow 32 Logical Units per Target Device.
+	   For Host Adapters that support Extended LUN Format CCBs, issue the
+	   Set CCB Format command to allow 32 Logical Units per Target Device.
 	 */
-	if (HostAdapter->ExtendedLUNSupport) {
-		SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
-		if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat, &SetCCBFormatRequest, sizeof(SetCCBFormatRequest), NULL, 0) < 0)
-			return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
+	if (adapter->ext_lun) {
+		setccb_fmt = BLOGIC_EXT_LUN_CCB;
+		if (blogic_cmd(adapter, BLOGIC_SETCCB_FMT, &setccb_fmt,
+					sizeof(setccb_fmt), NULL, 0) < 0)
+			return blogic_failure(adapter, "SET CCB FORMAT");
 	}
+
 	/*
 	   Announce Successful Initialization.
 	 */
-      Done:
-	if (!HostAdapter->HostAdapterInitialized) {
-		BusLogic_Info("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
-		BusLogic_Info("\n", HostAdapter);
+done:
+	if (!adapter->adapter_initd) {
+		blogic_info("*** %s Initialized Successfully ***\n", adapter,
+				adapter->full_model);
+		blogic_info("\n", adapter);
 	} else
-		BusLogic_Warning("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName);
-	HostAdapter->HostAdapterInitialized = true;
+		blogic_warn("*** %s Initialized Successfully ***\n", adapter,
+				adapter->full_model);
+	adapter->adapter_initd = true;
+
 	/*
 	   Indicate the Host Adapter Initialization completed successfully.
 	 */
@@ -2003,109 +2166,116 @@ static bool BusLogic_InitializeHostAdapt
 
 
 /*
-  BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
+  blogic_inquiry inquires about the Target Devices accessible
   through Host Adapter.
 */
 
-static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter
-						   *HostAdapter)
+static bool __init blogic_inquiry(struct blogic_adapter *adapter)
 {
-	u16 InstalledDevices;
-	u8 InstalledDevicesID0to7[8];
-	struct BusLogic_SetupInformation SetupInformation;
-	u8 SynchronousPeriod[BusLogic_MaxTargetDevices];
-	unsigned char RequestedReplyLength;
-	int TargetID;
+	u16 installed_devs;
+	u8 installed_devs0to7[8];
+	struct blogic_setup_info setupinfo;
+	u8 sync_period[BLOGIC_MAXDEV];
+	unsigned char req_replylen;
+	int tgt_id;
+
 	/*
-	   Wait a few seconds between the Host Adapter Hard Reset which initiates
-	   a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
-	   confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
+	   Wait a few seconds between the Host Adapter Hard Reset which
+	   initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
+	   SCSI devices get confused if they receive SCSI Commands too soon
+	   after a SCSI Bus Reset.
 	 */
-	BusLogic_Delay(HostAdapter->BusSettleTime);
+	blogic_delay(adapter->bus_settle_time);
 	/*
 	   FlashPoint Host Adapters do not provide for Target Device Inquiry.
 	 */
-	if (BusLogic_FlashPointHostAdapterP(HostAdapter))
+	if (blogic_flashpoint_type(adapter))
 		return true;
 	/*
 	   Inhibit the Target Device Inquiry if requested.
 	 */
-	if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
+	if (adapter->drvr_opts != NULL && adapter->drvr_opts->stop_tgt_inquiry)
 		return true;
 	/*
-	   Issue the Inquire Target Devices command for host adapters with firmware
-	   version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
-	   for older host adapters.  This is necessary to force Synchronous Transfer
-	   Negotiation so that the Inquire Setup Information and Inquire Synchronous
-	   Period commands will return valid data.  The Inquire Target Devices command
-	   is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
-	   Logical Unit 0 of each Target Device.
+	   Issue the Inquire Target Devices command for host adapters with
+	   firmware version 4.25 or later, or the Inquire Installed Devices
+	   ID 0 to 7 command for older host adapters.  This is necessary to
+	   force Synchronous Transfer Negotiation so that the Inquire Setup
+	   Information and Inquire Synchronous Period commands will return
+	   valid data.  The Inquire Target Devices command is preferable to
+	   Inquire Installed Devices ID 0 to 7 since it only probes Logical
+	   Unit 0 of each Target Device.
 	 */
-	if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) {
+	if (strcmp(adapter->fw_ver, "4.25") >= 0) {
 
 		/*
-		 * Issue a Inquire Target Devices command.  Inquire Target Devices only
-		 * tests Logical Unit 0 of each Target Device unlike the Inquire Installed
-		 * Devices commands which test Logical Units 0 - 7.  Two bytes are
-		 * returned, where byte 0 bit 0 set indicates that Target Device 0 exists,
-		 * and so on.
+		   Issue a Inquire Target Devices command. Inquire Target
+		   Devices only tests Logical Unit 0 of each Target Device
+		   unlike the Inquire Installed Devices commands which test
+		   Logical Units 0 - 7.  Two bytes are returned, where byte
+		   0 bit 0 set indicates that Target Device 0 exists, and so on.
 		 */
 
-		if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0, &InstalledDevices, sizeof(InstalledDevices))
-		    != sizeof(InstalledDevices))
-			return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
-		for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-			HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? true : false);
+		if (blogic_cmd(adapter, BLOGIC_INQ_DEV, NULL, 0,
+					&installed_devs, sizeof(installed_devs))
+		    != sizeof(installed_devs))
+			return blogic_failure(adapter, "INQUIRE TARGET DEVICES");
+		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+			adapter->tgt_flags[tgt_id].tgt_exists =
+				(installed_devs & (1 << tgt_id) ? true : false);
 	} else {
 
 		/*
-		 * Issue an Inquire Installed Devices command.  For each Target Device,
-		 * a byte is returned where bit 0 set indicates that Logical Unit 0
-		 * exists, bit 1 set indicates that Logical Unit 1 exists, and so on.
+		   Issue an Inquire Installed Devices command. For each
+		   Target Device, a byte is returned where bit 0 set
+		   indicates that Logical Unit 0 * exists, bit 1 set
+		   indicates that Logical Unit 1 exists, and so on.
 		 */
 
-		if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7, NULL, 0, &InstalledDevicesID0to7, sizeof(InstalledDevicesID0to7))
-		    != sizeof(InstalledDevicesID0to7))
-			return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
-		for (TargetID = 0; TargetID < 8; TargetID++)
-			HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
+		if (blogic_cmd(adapter, BLOGIC_INQ_DEV0TO7, NULL, 0,
+				&installed_devs0to7, sizeof(installed_devs0to7))
+		    != sizeof(installed_devs0to7))
+			return blogic_failure(adapter,
+					"INQUIRE INSTALLED DEVICES ID 0 TO 7");
+		for (tgt_id = 0; tgt_id < 8; tgt_id++)
+			adapter->tgt_flags[tgt_id].tgt_exists =
+				(installed_devs0to7[tgt_id] != 0 ? true : false);
 	}
 	/*
 	   Issue the Inquire Setup Information command.
 	 */
-	RequestedReplyLength = sizeof(SetupInformation);
-	if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation))
-	    != sizeof(SetupInformation))
-		return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
-	for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-		HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset : SetupInformation.SynchronousValuesID8to15[TargetID - 8].Offset);
-	if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
-		for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-			HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
-												  ? true : false)
-										  : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID - 8))
-										     ? true : false));
+	req_replylen = sizeof(setupinfo);
+	if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
+			sizeof(req_replylen), &setupinfo, sizeof(setupinfo))
+	    != sizeof(setupinfo))
+		return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
+	for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+		adapter->sync_offset[tgt_id] = (tgt_id < 8 ? setupinfo.sync0to7[tgt_id].offset : setupinfo.sync8to15[tgt_id - 8].offset);
+	if (strcmp(adapter->fw_ver, "5.06L") >= 0)
+		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+			adapter->tgt_flags[tgt_id].wide_active = (tgt_id < 8 ? (setupinfo.wide_tx_active0to7 & (1 << tgt_id) ? true : false) : (setupinfo.wide_tx_active8to15 & (1 << (tgt_id - 8)) ? true : false));
 	/*
 	   Issue the Inquire Synchronous Period command.
 	 */
-	if (HostAdapter->FirmwareVersion[0] >= '3') {
+	if (adapter->fw_ver[0] >= '3') {
 
-		/* Issue a Inquire Synchronous Period command.  For each Target Device,
-		 * a byte is returned which represents the Synchronous Transfer Period
-		 * in units of 10 nanoseconds.
+		/* Issue a Inquire Synchronous Period command. For each
+		   Target Device, a byte is returned which represents the
+		   Synchronous Transfer Period in units of 10 nanoseconds.
 		 */
 
-		RequestedReplyLength = sizeof(SynchronousPeriod);
-		if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod, &RequestedReplyLength, sizeof(RequestedReplyLength), &SynchronousPeriod, sizeof(SynchronousPeriod))
-		    != sizeof(SynchronousPeriod))
-			return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
-		for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-			HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
+		req_replylen = sizeof(sync_period);
+		if (blogic_cmd(adapter, BLOGIC_INQ_SYNC_PERIOD, &req_replylen,
+				sizeof(req_replylen), &sync_period,
+				sizeof(sync_period)) != sizeof(sync_period))
+			return blogic_failure(adapter,
+					"INQUIRE SYNCHRONOUS PERIOD");
+		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+			adapter->sync_period[tgt_id] = sync_period[tgt_id];
 	} else
-		for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-			if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
-				HostAdapter->SynchronousPeriod[TargetID] = 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
-				    .TransferPeriod;
+		for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+			if (setupinfo.sync0to7[tgt_id].offset > 0)
+				adapter->sync_period[tgt_id] = 20 + 5 * setupinfo.sync0to7[tgt_id].tx_period;
 	/*
 	   Indicate the Target Device Inquiry completed successfully.
 	 */
@@ -2113,7 +2283,7 @@ static bool __init BusLogic_TargetDevice
 }
 
 /*
-  BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
+  blogic_inithoststruct initializes the fields in the SCSI Host
   structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
   SCSI Host structure are intentionally left uninitialized, as this driver
   handles acquisition and release of these resources explicitly, as well as
@@ -2121,517 +2291,555 @@ static bool __init BusLogic_TargetDevice
   through explicit acquisition and release of the Host Adapter's Lock.
 */
 
-static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter
-						    *HostAdapter, struct Scsi_Host *Host)
+static void __init blogic_inithoststruct(struct blogic_adapter *adapter,
+		struct Scsi_Host *host)
 {
-	Host->max_id = HostAdapter->MaxTargetDevices;
-	Host->max_lun = HostAdapter->MaxLogicalUnits;
-	Host->max_channel = 0;
-	Host->unique_id = HostAdapter->IO_Address;
-	Host->this_id = HostAdapter->SCSI_ID;
-	Host->can_queue = HostAdapter->DriverQueueDepth;
-	Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
-	Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
-	Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
+	host->max_id = adapter->maxdev;
+	host->max_lun = adapter->maxlun;
+	host->max_channel = 0;
+	host->unique_id = adapter->io_addr;
+	host->this_id = adapter->scsi_id;
+	host->can_queue = adapter->drvr_qdepth;
+	host->sg_tablesize = adapter->drvr_sglimit;
+	host->unchecked_isa_dma = adapter->need_bouncebuf;
+	host->cmd_per_lun = adapter->untag_qdepth;
 }
 
 /*
-  BusLogic_SlaveConfigure will actually set the queue depth on individual
+  blogic_slaveconfig will actually set the queue depth on individual
   scsi devices as they are permanently added to the device chain.  We
   shamelessly rip off the SelectQueueDepths code to make this work mostly
   like it used to.  Since we don't get called once at the end of the scan
   but instead get called for each device, we have to do things a bit
   differently.
 */
-static int BusLogic_SlaveConfigure(struct scsi_device *Device)
+static int blogic_slaveconfig(struct scsi_device *dev)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Device->host->hostdata;
-	int TargetID = Device->id;
-	int QueueDepth = HostAdapter->QueueDepth[TargetID];
+	struct blogic_adapter *adapter =
+		(struct blogic_adapter *) dev->host->hostdata;
+	int tgt_id = dev->id;
+	int qdepth = adapter->qdepth[tgt_id];
 
-	if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
-		if (QueueDepth == 0)
-			QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
-		HostAdapter->QueueDepth[TargetID] = QueueDepth;
-		scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth);
+	if (adapter->tgt_flags[tgt_id].tagq_ok &&
+			(adapter->tagq_ok & (1 << tgt_id))) {
+		if (qdepth == 0)
+			qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH;
+		adapter->qdepth[tgt_id] = qdepth;
+		scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, qdepth);
 	} else {
-		HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
-		QueueDepth = HostAdapter->UntaggedQueueDepth;
-		HostAdapter->QueueDepth[TargetID] = QueueDepth;
-		scsi_adjust_queue_depth(Device, 0, QueueDepth);
+		adapter->tagq_ok &= ~(1 << tgt_id);
+		qdepth = adapter->untag_qdepth;
+		adapter->qdepth[tgt_id] = qdepth;
+		scsi_adjust_queue_depth(dev, 0, qdepth);
 	}
-	QueueDepth = 0;
-	for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
-		if (HostAdapter->TargetFlags[TargetID].TargetExists) {
-			QueueDepth += HostAdapter->QueueDepth[TargetID];
-		}
-	if (QueueDepth > HostAdapter->AllocatedCCBs)
-		BusLogic_CreateAdditionalCCBs(HostAdapter, QueueDepth - HostAdapter->AllocatedCCBs, false);
+	qdepth = 0;
+	for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
+		if (adapter->tgt_flags[tgt_id].tgt_exists)
+			qdepth += adapter->qdepth[tgt_id];
+	if (qdepth > adapter->alloc_ccbs)
+		blogic_create_addlccbs(adapter, qdepth - adapter->alloc_ccbs,
+				false);
 	return 0;
 }
 
 /*
-  BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
+  blogic_init probes for BusLogic Host Adapters at the standard
   I/O Addresses where they may be located, initializing, registering, and
   reporting the configuration of each BusLogic Host Adapter it finds.  It
   returns the number of BusLogic Host Adapters successfully initialized and
   registered.
 */
 
-static int __init BusLogic_init(void)
+static int __init blogic_init(void)
 {
-	int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
-	struct BusLogic_HostAdapter *PrototypeHostAdapter;
+	int adapter_count = 0, drvr_optindex = 0, probeindex;
+	struct blogic_adapter *adapter;
 	int ret = 0;
 
 #ifdef MODULE
 	if (BusLogic)
-		BusLogic_Setup(BusLogic);
+		blogic_setup(BusLogic);
 #endif
 
-	if (BusLogic_ProbeOptions.NoProbe)
+	if (blogic_probe_options.noprobe)
 		return -ENODEV;
-	BusLogic_ProbeInfoList =
-	    kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL);
-	if (BusLogic_ProbeInfoList == NULL) {
-		BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
+	blogic_probeinfo_list =
+	    kzalloc(BLOGIC_MAX_ADAPTERS * sizeof(struct blogic_probeinfo),
+			    GFP_KERNEL);
+	if (blogic_probeinfo_list == NULL) {
+		blogic_err("BusLogic: Unable to allocate Probe Info List\n",
+				NULL);
 		return -ENOMEM;
 	}
 
-	PrototypeHostAdapter =
-	    kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL);
-	if (PrototypeHostAdapter == NULL) {
-		kfree(BusLogic_ProbeInfoList);
-		BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL);
+	adapter = kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL);
+	if (adapter == NULL) {
+		kfree(blogic_probeinfo_list);
+		blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL);
 		return -ENOMEM;
 	}
 
 #ifdef MODULE
 	if (BusLogic != NULL)
-		BusLogic_Setup(BusLogic);
+		blogic_setup(BusLogic);
 #endif
-	BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
-	for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) {
-		struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
-		struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
-		struct Scsi_Host *Host;
-		if (ProbeInfo->IO_Address == 0)
+	blogic_init_probeinfo_list(adapter);
+	for (probeindex = 0; probeindex < blogic_probeinfo_count; probeindex++) {
+		struct blogic_probeinfo *probeinfo =
+			&blogic_probeinfo_list[probeindex];
+		struct blogic_adapter *myadapter = adapter;
+		struct Scsi_Host *host;
+
+		if (probeinfo->io_addr == 0)
 			continue;
-		memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
-		HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
-		HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
-		HostAdapter->IO_Address = ProbeInfo->IO_Address;
-		HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
-		HostAdapter->Bus = ProbeInfo->Bus;
-		HostAdapter->Device = ProbeInfo->Device;
-		HostAdapter->PCI_Device = ProbeInfo->PCI_Device;
-		HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
-		HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
+		memset(myadapter, 0, sizeof(struct blogic_adapter));
+		myadapter->adapter_type = probeinfo->adapter_type;
+		myadapter->adapter_bus_type = probeinfo->adapter_bus_type;
+		myadapter->io_addr = probeinfo->io_addr;
+		myadapter->pci_addr = probeinfo->pci_addr;
+		myadapter->bus = probeinfo->bus;
+		myadapter->dev = probeinfo->dev;
+		myadapter->pci_device = probeinfo->pci_device;
+		myadapter->irq_ch = probeinfo->irq_ch;
+		myadapter->addr_count =
+			blogic_adapter_addr_count[myadapter->adapter_type];
 
 		/*
 		   Make sure region is free prior to probing.
 		 */
-		if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
+		if (!request_region(myadapter->io_addr, myadapter->addr_count,
 					"BusLogic"))
 			continue;
 		/*
-		   Probe the Host Adapter.  If unsuccessful, abort further initialization.
+		   Probe the Host Adapter. If unsuccessful, abort further
+		   initialization.
 		 */
-		if (!BusLogic_ProbeHostAdapter(HostAdapter)) {
-			release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
+		if (!blogic_probe(myadapter)) {
+			release_region(myadapter->io_addr,
+					myadapter->addr_count);
 			continue;
 		}
 		/*
 		   Hard Reset the Host Adapter.  If unsuccessful, abort further
 		   initialization.
 		 */
-		if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) {
-			release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
+		if (!blogic_hwreset(myadapter, true)) {
+			release_region(myadapter->io_addr,
+					myadapter->addr_count);
 			continue;
 		}
 		/*
-		   Check the Host Adapter.  If unsuccessful, abort further initialization.
+		   Check the Host Adapter.  If unsuccessful, abort further
+		   initialization.
 		 */
-		if (!BusLogic_CheckHostAdapter(HostAdapter)) {
-			release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
+		if (!blogic_checkadapter(myadapter)) {
+			release_region(myadapter->io_addr,
+					myadapter->addr_count);
 			continue;
 		}
 		/*
 		   Initialize the Driver Options field if provided.
 		 */
-		if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
-			HostAdapter->DriverOptions = &BusLogic_DriverOptions[DriverOptionsIndex++];
+		if (drvr_optindex < blogic_drvr_options_count)
+			myadapter->drvr_opts =
+				&blogic_drvr_options[drvr_optindex++];
 		/*
-		   Announce the Driver Version and Date, Author's Name, Copyright Notice,
-		   and Electronic Mail Address.
+		   Announce the Driver Version and Date, Author's Name,
+		   Copyright Notice, and Electronic Mail Address.
 		 */
-		BusLogic_AnnounceDriver(HostAdapter);
+		blogic_announce_drvr(myadapter);
 		/*
 		   Register the SCSI Host structure.
 		 */
 
-		Host = scsi_host_alloc(&Bus_Logic_template, sizeof(struct BusLogic_HostAdapter));
-		if (Host == NULL) {
-			release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
+		host = scsi_host_alloc(&blogic_template,
+				sizeof(struct blogic_adapter));
+		if (host == NULL) {
+			release_region(myadapter->io_addr,
+					myadapter->addr_count);
 			continue;
 		}
-		HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
-		memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter));
-		HostAdapter->SCSI_Host = Host;
-		HostAdapter->HostNumber = Host->host_no;
+		myadapter = (struct blogic_adapter *) host->hostdata;
+		memcpy(myadapter, adapter, sizeof(struct blogic_adapter));
+		myadapter->scsi_host = host;
+		myadapter->host_no = host->host_no;
 		/*
-		   Add Host Adapter to the end of the list of registered BusLogic
-		   Host Adapters.
+		   Add Host Adapter to the end of the list of registered
+		   BusLogic Host Adapters.
 		 */
-		list_add_tail(&HostAdapter->host_list, &BusLogic_host_list);
+		list_add_tail(&myadapter->host_list, &blogic_host_list);
 
 		/*
-		   Read the Host Adapter Configuration, Configure the Host Adapter,
-		   Acquire the System Resources necessary to use the Host Adapter, then
-		   Create the Initial CCBs, Initialize the Host Adapter, and finally
-		   perform Target Device Inquiry.
-
-		   From this point onward, any failure will be assumed to be due to a
-		   problem with the Host Adapter, rather than due to having mistakenly
-		   identified this port as belonging to a BusLogic Host Adapter.  The
-		   I/O Address range will not be released, thereby preventing it from
-		   being incorrectly identified as any other type of Host Adapter.
+		   Read the Host Adapter Configuration, Configure the Host
+		   Adapter, Acquire the System Resources necessary to use
+		   the Host Adapter, then Create the Initial CCBs, Initialize
+		   the Host Adapter, and finally perform Target Device
+		   Inquiry. From this point onward, any failure will be
+		   assumed to be due to a problem with the Host Adapter,
+		   rather than due to having mistakenly identified this port
+		   as belonging to a BusLogic Host Adapter. The I/O Address
+		   range will not be released, thereby preventing it from
+		   being incorrectly identified as any other type of Host
+		   Adapter.
 		 */
-		if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
-		    BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
-		    BusLogic_AcquireResources(HostAdapter) &&
-		    BusLogic_CreateInitialCCBs(HostAdapter) &&
-		    BusLogic_InitializeHostAdapter(HostAdapter) &&
-		    BusLogic_TargetDeviceInquiry(HostAdapter)) {
+		if (blogic_rdconfig(myadapter) &&
+		    blogic_reportconfig(myadapter) &&
+		    blogic_getres(myadapter) &&
+		    blogic_create_initccbs(myadapter) &&
+		    blogic_initadapter(myadapter) &&
+		    blogic_inquiry(myadapter)) {
 			/*
-			   Initialization has been completed successfully.  Release and
-			   re-register usage of the I/O Address range so that the Model
-			   Name of the Host Adapter will appear, and initialize the SCSI
-			   Host structure.
+			   Initialization has been completed successfully.
+			   Release and re-register usage of the I/O Address
+			   range so that the Model Name of the Host Adapter
+			   will appear, and initialize the SCSI Host structure.
 			 */
-			release_region(HostAdapter->IO_Address,
-				       HostAdapter->AddressCount);
-			if (!request_region(HostAdapter->IO_Address,
-					    HostAdapter->AddressCount,
-					    HostAdapter->FullModelName)) {
+			release_region(myadapter->io_addr,
+				       myadapter->addr_count);
+			if (!request_region(myadapter->io_addr,
+					    myadapter->addr_count,
+					    myadapter->full_model)) {
 				printk(KERN_WARNING
 					"BusLogic: Release and re-register of "
 					"port 0x%04lx failed \n",
-					(unsigned long)HostAdapter->IO_Address);
-				BusLogic_DestroyCCBs(HostAdapter);
-				BusLogic_ReleaseResources(HostAdapter);
-				list_del(&HostAdapter->host_list);
-				scsi_host_put(Host);
+					(unsigned long)myadapter->io_addr);
+				blogic_destroy_ccbs(myadapter);
+				blogic_relres(myadapter);
+				list_del(&myadapter->host_list);
+				scsi_host_put(host);
 				ret = -ENOMEM;
 			} else {
-				BusLogic_InitializeHostStructure(HostAdapter,
-								 Host);
-				if (scsi_add_host(Host, HostAdapter->PCI_Device
-						? &HostAdapter->PCI_Device->dev
+				blogic_inithoststruct(myadapter,
+								 host);
+				if (scsi_add_host(host, myadapter->pci_device
+						? &myadapter->pci_device->dev
 						  : NULL)) {
 					printk(KERN_WARNING
 					       "BusLogic: scsi_add_host()"
 					       "failed!\n");
-					BusLogic_DestroyCCBs(HostAdapter);
-					BusLogic_ReleaseResources(HostAdapter);
-					list_del(&HostAdapter->host_list);
-					scsi_host_put(Host);
+					blogic_destroy_ccbs(myadapter);
+					blogic_relres(myadapter);
+					list_del(&myadapter->host_list);
+					scsi_host_put(host);
 					ret = -ENODEV;
 				} else {
-					scsi_scan_host(Host);
-					BusLogicHostAdapterCount++;
+					scsi_scan_host(host);
+					adapter_count++;
 				}
 			}
 		} else {
 			/*
-			   An error occurred during Host Adapter Configuration Querying, Host
-			   Adapter Configuration, Resource Acquisition, CCB Creation, Host
-			   Adapter Initialization, or Target Device Inquiry, so remove Host
-			   Adapter from the list of registered BusLogic Host Adapters, destroy
-			   the CCBs, Release the System Resources, and Unregister the SCSI
+			   An error occurred during Host Adapter Configuration
+			   Querying, Host Adapter Configuration, Resource
+			   Acquisition, CCB Creation, Host Adapter
+			   Initialization, or Target Device Inquiry, so
+			   remove Host Adapter from the list of registered
+			   BusLogic Host Adapters, destroy the CCBs, Release
+			   the System Resources, and Unregister the SCSI
 			   Host.
 			 */
-			BusLogic_DestroyCCBs(HostAdapter);
-			BusLogic_ReleaseResources(HostAdapter);
-			list_del(&HostAdapter->host_list);
-			scsi_host_put(Host);
+			blogic_destroy_ccbs(myadapter);
+			blogic_relres(myadapter);
+			list_del(&myadapter->host_list);
+			scsi_host_put(host);
 			ret = -ENODEV;
 		}
 	}
-	kfree(PrototypeHostAdapter);
-	kfree(BusLogic_ProbeInfoList);
-	BusLogic_ProbeInfoList = NULL;
+	kfree(adapter);
+	kfree(blogic_probeinfo_list);
+	blogic_probeinfo_list = NULL;
 	return ret;
 }
 
 
 /*
-  BusLogic_ReleaseHostAdapter releases all resources previously acquired to
+  blogic_deladapter releases all resources previously acquired to
   support a specific Host Adapter, including the I/O Address range, and
   unregisters the BusLogic Host Adapter.
 */
 
-static int __exit BusLogic_ReleaseHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
+static int __exit blogic_deladapter(struct blogic_adapter *adapter)
 {
-	struct Scsi_Host *Host = HostAdapter->SCSI_Host;
+	struct Scsi_Host *host = adapter->scsi_host;
 
-	scsi_remove_host(Host);
+	scsi_remove_host(host);
 
 	/*
 	   FlashPoint Host Adapters must first be released by the FlashPoint
 	   SCCB Manager.
 	 */
-	if (BusLogic_FlashPointHostAdapterP(HostAdapter))
-		FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
+	if (blogic_flashpoint_type(adapter))
+		FlashPoint_ReleaseHostAdapter(adapter->cardhandle);
 	/*
 	   Destroy the CCBs and release any system resources acquired to
 	   support Host Adapter.
 	 */
-	BusLogic_DestroyCCBs(HostAdapter);
-	BusLogic_ReleaseResources(HostAdapter);
+	blogic_destroy_ccbs(adapter);
+	blogic_relres(adapter);
 	/*
 	   Release usage of the I/O Address range.
 	 */
-	release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
+	release_region(adapter->io_addr, adapter->addr_count);
 	/*
-	   Remove Host Adapter from the list of registered BusLogic Host Adapters.
+	   Remove Host Adapter from the list of registered BusLogic
+	   Host Adapters.
 	 */
-	list_del(&HostAdapter->host_list);
+	list_del(&adapter->host_list);
 
-	scsi_host_put(Host);
+	scsi_host_put(host);
 	return 0;
 }
 
 
 /*
-  BusLogic_QueueCompletedCCB queues CCB for completion processing.
+  blogic_qcompleted_ccb queues CCB for completion processing.
 */
 
-static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB)
+static void blogic_qcompleted_ccb(struct blogic_ccb *ccb)
 {
-	struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
-	CCB->Status = BusLogic_CCB_Completed;
-	CCB->Next = NULL;
-	if (HostAdapter->FirstCompletedCCB == NULL) {
-		HostAdapter->FirstCompletedCCB = CCB;
-		HostAdapter->LastCompletedCCB = CCB;
+	struct blogic_adapter *adapter = ccb->adapter;
+
+	ccb->status = BLOGIC_CCB_COMPLETE;
+	ccb->next = NULL;
+	if (adapter->firstccb == NULL) {
+		adapter->firstccb = ccb;
+		adapter->lastccb = ccb;
 	} else {
-		HostAdapter->LastCompletedCCB->Next = CCB;
-		HostAdapter->LastCompletedCCB = CCB;
+		adapter->lastccb->next = ccb;
+		adapter->lastccb = ccb;
 	}
-	HostAdapter->ActiveCommands[CCB->TargetID]--;
+	adapter->active_cmds[ccb->tgt_id]--;
 }
 
 
 /*
-  BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
+  blogic_resultcode computes a SCSI Subsystem Result Code from
   the Host Adapter Status and Target Device Status.
 */
 
-static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_HostAdapterStatus HostAdapterStatus, enum BusLogic_TargetDeviceStatus TargetDeviceStatus)
+static int blogic_resultcode(struct blogic_adapter *adapter,
+		enum blogic_adapter_status adapter_status,
+		enum blogic_tgt_status tgt_status)
 {
-	int HostStatus;
-	switch (HostAdapterStatus) {
-	case BusLogic_CommandCompletedNormally:
-	case BusLogic_LinkedCommandCompleted:
-	case BusLogic_LinkedCommandCompletedWithFlag:
-		HostStatus = DID_OK;
+	int hoststatus;
+
+	switch (adapter_status) {
+	case BLOGIC_CMD_CMPLT_NORMAL:
+	case BLOGIC_LINK_CMD_CMPLT:
+	case BLOGIC_LINK_CMD_CMPLT_FLAG:
+		hoststatus = DID_OK;
 		break;
-	case BusLogic_SCSISelectionTimeout:
-		HostStatus = DID_TIME_OUT;
+	case BLOGIC_SELECT_TIMEOUT:
+		hoststatus = DID_TIME_OUT;
 		break;
-	case BusLogic_InvalidOutgoingMailboxActionCode:
-	case BusLogic_InvalidCommandOperationCode:
-	case BusLogic_InvalidCommandParameter:
-		BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n", HostAdapter, HostAdapterStatus);
-	case BusLogic_DataUnderRun:
-	case BusLogic_DataOverRun:
-	case BusLogic_UnexpectedBusFree:
-	case BusLogic_LinkedCCBhasInvalidLUN:
-	case BusLogic_AutoRequestSenseFailed:
-	case BusLogic_TaggedQueuingMessageRejected:
-	case BusLogic_UnsupportedMessageReceived:
-	case BusLogic_HostAdapterHardwareFailed:
-	case BusLogic_TargetDeviceReconnectedImproperly:
-	case BusLogic_AbortQueueGenerated:
-	case BusLogic_HostAdapterSoftwareError:
-	case BusLogic_HostAdapterHardwareTimeoutError:
-	case BusLogic_SCSIParityErrorDetected:
-		HostStatus = DID_ERROR;
+	case BLOGIC_INVALID_OUTBOX_CODE:
+	case BLOGIC_INVALID_CMD_CODE:
+	case BLOGIC_BAD_CMD_PARAM:
+		blogic_warn("BusLogic Driver Protocol Error 0x%02X\n",
+				adapter, adapter_status);
+	case BLOGIC_DATA_UNDERRUN:
+	case BLOGIC_DATA_OVERRUN:
+	case BLOGIC_NOEXPECT_BUSFREE:
+	case BLOGIC_LINKCCB_BADLUN:
+	case BLOGIC_AUTOREQSENSE_FAIL:
+	case BLOGIC_TAGQUEUE_REJECT:
+	case BLOGIC_BAD_MSG_RCVD:
+	case BLOGIC_HW_FAIL:
+	case BLOGIC_BAD_RECONNECT:
+	case BLOGIC_ABRT_QUEUE:
+	case BLOGIC_ADAPTER_SW_ERROR:
+	case BLOGIC_HW_TIMEOUT:
+	case BLOGIC_PARITY_ERR:
+		hoststatus = DID_ERROR;
 		break;
-	case BusLogic_InvalidBusPhaseRequested:
-	case BusLogic_TargetFailedResponseToATN:
-	case BusLogic_HostAdapterAssertedRST:
-	case BusLogic_OtherDeviceAssertedRST:
-	case BusLogic_HostAdapterAssertedBusDeviceReset:
-		HostStatus = DID_RESET;
+	case BLOGIC_INVALID_BUSPHASE:
+	case BLOGIC_NORESPONSE_TO_ATN:
+	case BLOGIC_HW_RESET:
+	case BLOGIC_RST_FROM_OTHERDEV:
+	case BLOGIC_HW_BDR:
+		hoststatus = DID_RESET;
 		break;
 	default:
-		BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n", HostAdapter, HostAdapterStatus);
-		HostStatus = DID_ERROR;
+		blogic_warn("Unknown Host Adapter Status 0x%02X\n", adapter,
+				adapter_status);
+		hoststatus = DID_ERROR;
 		break;
 	}
-	return (HostStatus << 16) | TargetDeviceStatus;
+	return (hoststatus << 16) | tgt_status;
 }
 
 
 /*
-  BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
+  blogic_scan_inbox scans the Incoming Mailboxes saving any
   Incoming Mailbox entries for completion processing.
 */
 
-static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdapter)
+static void blogic_scan_inbox(struct blogic_adapter *adapter)
 {
 	/*
-	   Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
-	   any completed CCBs for further processing.  It is essential that for each
-	   CCB and SCSI Command issued, command completion processing is performed
-	   exactly once.  Therefore, only Incoming Mailboxes with completion code
-	   Command Completed Without Error, Command Completed With Error, or Command
-	   Aborted At Host Request are saved for completion processing.  When an
-	   Incoming Mailbox has a completion code of Aborted Command Not Found, the
-	   CCB had already completed or been aborted before the current Abort request
-	   was processed, and so completion processing has already occurred and no
-	   further action should be taken.
+	   Scan through the Incoming Mailboxes in Strict Round Robin
+	   fashion, saving any completed CCBs for further processing. It
+	   is essential that for each CCB and SCSI Command issued, command
+	   completion processing is performed exactly once.  Therefore,
+	   only Incoming Mailboxes with completion code Command Completed
+	   Without Error, Command Completed With Error, or Command Aborted
+	   At Host Request are saved for completion processing. When an
+	   Incoming Mailbox has a completion code of Aborted Command Not
+	   Found, the CCB had already completed or been aborted before the
+	   current Abort request was processed, and so completion processing
+	   has already occurred and no further action should be taken.
 	 */
-	struct BusLogic_IncomingMailbox *NextIncomingMailbox = HostAdapter->NextIncomingMailbox;
-	enum BusLogic_CompletionCode CompletionCode;
-	while ((CompletionCode = NextIncomingMailbox->CompletionCode) != BusLogic_IncomingMailboxFree) {
+	struct blogic_inbox *next_inbox = adapter->next_inbox;
+	enum blogic_cmplt_code comp_code;
+
+	while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) {
 		/*
-		   We are only allowed to do this because we limit our architectures we
-		   run on to machines where bus_to_virt() actually works.  There *needs*
-		   to be a dma_addr_to_virt() in the new PCI DMA mapping interface to
-		   replace bus_to_virt() or else this code is going to become very
+		   We are only allowed to do this because we limit our
+		   architectures we run on to machines where bus_to_virt(
+		   actually works.  There *needs* to be a dma_addr_to_virt()
+		   in the new PCI DMA mapping interface to replace
+		   bus_to_virt() or else this code is going to become very
 		   innefficient.
 		 */
-		struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) Bus_to_Virtual(NextIncomingMailbox->CCB);
-		if (CompletionCode != BusLogic_AbortedCommandNotFound) {
-			if (CCB->Status == BusLogic_CCB_Active || CCB->Status == BusLogic_CCB_Reset) {
+		struct blogic_ccb *ccb =
+			(struct blogic_ccb *) bus_to_virt(next_inbox->ccb);
+		if (comp_code != BLOGIC_CMD_NOTFOUND) {
+			if (ccb->status == BLOGIC_CCB_ACTIVE ||
+					ccb->status == BLOGIC_CCB_RESET) {
 				/*
-				   Save the Completion Code for this CCB and queue the CCB
-				   for completion processing.
+				   Save the Completion Code for this CCB and
+				   queue the CCB for completion processing.
 				 */
-				CCB->CompletionCode = CompletionCode;
-				BusLogic_QueueCompletedCCB(CCB);
+				ccb->comp_code = comp_code;
+				blogic_qcompleted_ccb(ccb);
 			} else {
 				/*
-				   If a CCB ever appears in an Incoming Mailbox and is not marked
-				   as status Active or Reset, then there is most likely a bug in
+				   If a CCB ever appears in an Incoming Mailbox
+				   and is not marked as status Active or Reset,
+				   then there is most likely a bug in
 				   the Host Adapter firmware.
 				 */
-				BusLogic_Warning("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", HostAdapter, CCB->SerialNumber, CCB->Status);
+				blogic_warn("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", adapter, ccb->serial, ccb->status);
 			}
 		}
-		NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
-		if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
-			NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
+		next_inbox->comp_code = BLOGIC_INBOX_FREE;
+		if (++next_inbox > adapter->last_inbox)
+			next_inbox = adapter->first_inbox;
 	}
-	HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
+	adapter->next_inbox = next_inbox;
 }
 
 
 /*
-  BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
+  blogic_process_ccbs iterates over the completed CCBs for Host
   Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
   calling the SCSI Subsystem Completion Routines.  The Host Adapter's Lock
   should already have been acquired by the caller.
 */
 
-static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapter)
+static void blogic_process_ccbs(struct blogic_adapter *adapter)
 {
-	if (HostAdapter->ProcessCompletedCCBsActive)
+	if (adapter->processing_ccbs)
 		return;
-	HostAdapter->ProcessCompletedCCBsActive = true;
-	while (HostAdapter->FirstCompletedCCB != NULL) {
-		struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB;
-		struct scsi_cmnd *Command = CCB->Command;
-		HostAdapter->FirstCompletedCCB = CCB->Next;
-		if (HostAdapter->FirstCompletedCCB == NULL)
-			HostAdapter->LastCompletedCCB = NULL;
+	adapter->processing_ccbs = true;
+	while (adapter->firstccb != NULL) {
+		struct blogic_ccb *ccb = adapter->firstccb;
+		struct scsi_cmnd *command = ccb->command;
+		adapter->firstccb = ccb->next;
+		if (adapter->firstccb == NULL)
+			adapter->lastccb = NULL;
 		/*
 		   Process the Completed CCB.
 		 */
-		if (CCB->Opcode == BusLogic_BusDeviceReset) {
-			int TargetID = CCB->TargetID;
-			BusLogic_Warning("Bus Device Reset CCB #%ld to Target " "%d Completed\n", HostAdapter, CCB->SerialNumber, TargetID);
-			BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
-			HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
-			HostAdapter->CommandsSinceReset[TargetID] = 0;
-			HostAdapter->LastResetCompleted[TargetID] = jiffies;
+		if (ccb->opcode == BLOGIC_BDR) {
+			int tgt_id = ccb->tgt_id;
+
+			blogic_warn("Bus Device Reset CCB #%ld to Target " "%d Completed\n", adapter, ccb->serial, tgt_id);
+			blogic_inc_count(&adapter->tgt_stats[tgt_id].bdr_done);
+			adapter->tgt_flags[tgt_id].tagq_active = false;
+			adapter->cmds_since_rst[tgt_id] = 0;
+			adapter->last_resetdone[tgt_id] = jiffies;
 			/*
 			   Place CCB back on the Host Adapter's free list.
 			 */
-			BusLogic_DeallocateCCB(CCB);
+			blogic_dealloc_ccb(ccb);
 #if 0				/* this needs to be redone different for new EH */
 			/*
-			   Bus Device Reset CCBs have the Command field non-NULL only when a
-			   Bus Device Reset was requested for a Command that did not have a
-			   currently active CCB in the Host Adapter (i.e., a Synchronous
-			   Bus Device Reset), and hence would not have its Completion Routine
-			   called otherwise.
+			   Bus Device Reset CCBs have the command field
+			   non-NULL only when a Bus Device Reset was requested
+			   for a command that did not have a currently active
+			   CCB in the Host Adapter (i.e., a Synchronous Bus
+			   Device Reset), and hence would not have its
+			   Completion Routine called otherwise.
 			 */
-			while (Command != NULL) {
-				struct scsi_cmnd *NextCommand = Command->reset_chain;
-				Command->reset_chain = NULL;
-				Command->result = DID_RESET << 16;
-				Command->scsi_done(Command);
-				Command = NextCommand;
+			while (command != NULL) {
+				struct scsi_cmnd *nxt_cmd =
+					command->reset_chain;
+				command->reset_chain = NULL;
+				command->result = DID_RESET << 16;
+				command->scsi_done(command);
+				command = nxt_cmd;
 			}
 #endif
 			/*
-			   Iterate over the CCBs for this Host Adapter performing completion
-			   processing for any CCBs marked as Reset for this Target.
+			   Iterate over the CCBs for this Host Adapter
+			   performing completion processing for any CCBs
+			   marked as Reset for this Target.
 			 */
-			for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
-				if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID) {
-					Command = CCB->Command;
-					BusLogic_DeallocateCCB(CCB);
-					HostAdapter->ActiveCommands[TargetID]--;
-					Command->result = DID_RESET << 16;
-					Command->scsi_done(Command);
+			for (ccb = adapter->all_ccbs; ccb != NULL;
+					ccb = ccb->next_all)
+				if (ccb->status == BLOGIC_CCB_RESET &&
+						ccb->tgt_id == tgt_id) {
+					command = ccb->command;
+					blogic_dealloc_ccb(ccb);
+					adapter->active_cmds[tgt_id]--;
+					command->result = DID_RESET << 16;
+					command->scsi_done(command);
 				}
-			HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
+			adapter->bdr_pend[tgt_id] = NULL;
 		} else {
 			/*
-			   Translate the Completion Code, Host Adapter Status, and Target
-			   Device Status into a SCSI Subsystem Result Code.
+			   Translate the Completion Code, Host Adapter Status,
+			   and Target Device Status into a SCSI Subsystem
+			   Result Code.
 			 */
-			switch (CCB->CompletionCode) {
-			case BusLogic_IncomingMailboxFree:
-			case BusLogic_AbortedCommandNotFound:
-			case BusLogic_InvalidCCB:
-				BusLogic_Warning("CCB #%ld to Target %d Impossible State\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
+			switch (ccb->comp_code) {
+			case BLOGIC_INBOX_FREE:
+			case BLOGIC_CMD_NOTFOUND:
+			case BLOGIC_INVALID_CCB:
+				blogic_warn("CCB #%ld to Target %d Impossible State\n", adapter, ccb->serial, ccb->tgt_id);
 				break;
-			case BusLogic_CommandCompletedWithoutError:
-				HostAdapter->TargetStatistics[CCB->TargetID]
-				    .CommandsCompleted++;
-				HostAdapter->TargetFlags[CCB->TargetID]
-				    .CommandSuccessfulFlag = true;
-				Command->result = DID_OK << 16;
+			case BLOGIC_CMD_COMPLETE_GOOD:
+				adapter->tgt_stats[ccb->tgt_id]
+				    .cmds_complete++;
+				adapter->tgt_flags[ccb->tgt_id]
+				    .cmd_good = true;
+				command->result = DID_OK << 16;
 				break;
-			case BusLogic_CommandAbortedAtHostRequest:
-				BusLogic_Warning("CCB #%ld to Target %d Aborted\n", HostAdapter, CCB->SerialNumber, CCB->TargetID);
-				BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[CCB->TargetID]
-							       .CommandAbortsCompleted);
-				Command->result = DID_ABORT << 16;
+			case BLOGIC_CMD_ABORT_BY_HOST:
+				blogic_warn("CCB #%ld to Target %d Aborted\n",
+					adapter, ccb->serial, ccb->tgt_id);
+				blogic_inc_count(&adapter->tgt_stats[ccb->tgt_id].aborts_done);
+				command->result = DID_ABORT << 16;
 				break;
-			case BusLogic_CommandCompletedWithError:
-				Command->result = BusLogic_ComputeResultCode(HostAdapter, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
-				if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) {
-					HostAdapter->TargetStatistics[CCB->TargetID]
-					    .CommandsCompleted++;
-					if (BusLogic_GlobalOptions.TraceErrors) {
+			case BLOGIC_CMD_COMPLETE_ERROR:
+				command->result = blogic_resultcode(adapter,
+					ccb->adapter_status, ccb->tgt_status);
+				if (ccb->adapter_status != BLOGIC_SELECT_TIMEOUT) {
+					adapter->tgt_stats[ccb->tgt_id]
+					    .cmds_complete++;
+					if (blogic_global_options.trace_err) {
 						int i;
-						BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
-								"Adapter Status %02X " "Target Status %02X\n", HostAdapter, CCB->SerialNumber, CCB->TargetID, Command->result, CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
-						BusLogic_Notice("CDB   ", HostAdapter);
-						for (i = 0; i < CCB->CDB_Length; i++)
-							BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
-						BusLogic_Notice("\n", HostAdapter);
-						BusLogic_Notice("Sense ", HostAdapter);
-						for (i = 0; i < CCB->SenseDataLength; i++)
-							BusLogic_Notice(" %02X", HostAdapter, Command->sense_buffer[i]);
-						BusLogic_Notice("\n", HostAdapter);
+						blogic_notice("CCB #%ld Target %d: Result %X Host "
+								"Adapter Status %02X " "Target Status %02X\n", adapter, ccb->serial, ccb->tgt_id, command->result, ccb->adapter_status, ccb->tgt_status);
+						blogic_notice("CDB   ", adapter);
+						for (i = 0; i < ccb->cdblen; i++)
+							blogic_notice(" %02X", adapter, ccb->cdb[i]);
+						blogic_notice("\n", adapter);
+						blogic_notice("Sense ", adapter);
+						for (i = 0; i < ccb->sense_datalen; i++)
+							blogic_notice(" %02X", adapter, command->sense_buffer[i]);
+						blogic_notice("\n", adapter);
 					}
 				}
 				break;
@@ -2641,141 +2849,145 @@ static void BusLogic_ProcessCompletedCCB
 			   CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
 			   Wide Data Transfers Supported) bits.
 			 */
-			if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) {
-				struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID];
-				struct SCSI_Inquiry *InquiryResult =
-					(struct SCSI_Inquiry *) scsi_sglist(Command);
-				TargetFlags->TargetExists = true;
-				TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
-				TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
+			if (ccb->cdb[0] == INQUIRY && ccb->cdb[1] == 0 &&
+				ccb->adapter_status == BLOGIC_CMD_CMPLT_NORMAL) {
+				struct blogic_tgt_flags *tgt_flags =
+					&adapter->tgt_flags[ccb->tgt_id];
+				struct scsi_inquiry *inquiry =
+					(struct scsi_inquiry *) scsi_sglist(command);
+				tgt_flags->tgt_exists = true;
+				tgt_flags->tagq_ok = inquiry->CmdQue;
+				tgt_flags->wide_ok = inquiry->WBus16;
 			}
 			/*
 			   Place CCB back on the Host Adapter's free list.
 			 */
-			BusLogic_DeallocateCCB(CCB);
+			blogic_dealloc_ccb(ccb);
 			/*
 			   Call the SCSI Command Completion Routine.
 			 */
-			Command->scsi_done(Command);
+			command->scsi_done(command);
 		}
 	}
-	HostAdapter->ProcessCompletedCCBsActive = false;
+	adapter->processing_ccbs = false;
 }
 
 
 /*
-  BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
+  blogic_inthandler handles hardware interrupts from BusLogic Host
   Adapters.
 */
 
-static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier)
+static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier;
-	unsigned long ProcessorFlags;
+	struct blogic_adapter *adapter = (struct blogic_adapter *) devid;
+	unsigned long processor_flag;
 	/*
 	   Acquire exclusive access to Host Adapter.
 	 */
-	spin_lock_irqsave(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
+	spin_lock_irqsave(adapter->scsi_host->host_lock, processor_flag);
 	/*
 	   Handle Interrupts appropriately for each Host Adapter type.
 	 */
-	if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
-		union BusLogic_InterruptRegister InterruptRegister;
+	if (blogic_multimaster_type(adapter)) {
+		union blogic_int_reg intreg;
 		/*
 		   Read the Host Adapter Interrupt Register.
 		 */
-		InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
-		if (InterruptRegister.ir.InterruptValid) {
+		intreg.all = blogic_rdint(adapter);
+		if (intreg.ir.int_valid) {
 			/*
 			   Acknowledge the interrupt and reset the Host Adapter
 			   Interrupt Register.
 			 */
-			BusLogic_InterruptReset(HostAdapter);
+			blogic_intreset(adapter);
 			/*
-			   Process valid External SCSI Bus Reset and Incoming Mailbox
-			   Loaded Interrupts.  Command Complete Interrupts are noted,
-			   and Outgoing Mailbox Available Interrupts are ignored, as
-			   they are never enabled.
+			   Process valid External SCSI Bus Reset and Incoming
+			   Mailbox Loaded Interrupts. Command Complete
+			   Interrupts are noted, and Outgoing Mailbox Available
+			   Interrupts are ignored, as they are never enabled.
 			 */
-			if (InterruptRegister.ir.ExternalBusReset)
-				HostAdapter->HostAdapterExternalReset = true;
-			else if (InterruptRegister.ir.IncomingMailboxLoaded)
-				BusLogic_ScanIncomingMailboxes(HostAdapter);
-			else if (InterruptRegister.ir.CommandComplete)
-				HostAdapter->HostAdapterCommandCompleted = true;
+			if (intreg.ir.ext_busreset)
+				adapter->adapter_extreset = true;
+			else if (intreg.ir.mailin_loaded)
+				blogic_scan_inbox(adapter);
+			else if (intreg.ir.cmd_complete)
+				adapter->adapter_cmd_complete = true;
 		}
 	} else {
 		/*
 		   Check if there is a pending interrupt for this Host Adapter.
 		 */
-		if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
-			switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle)) {
-			case FlashPoint_NormalInterrupt:
+		if (FlashPoint_InterruptPending(adapter->cardhandle))
+			switch (FlashPoint_HandleInterrupt(adapter->cardhandle)) {
+			case FPOINT_NORMAL_INT:
 				break;
-			case FlashPoint_ExternalBusReset:
-				HostAdapter->HostAdapterExternalReset = true;
+			case FPOINT_EXT_RESET:
+				adapter->adapter_extreset = true;
 				break;
-			case FlashPoint_InternalError:
-				BusLogic_Warning("Internal FlashPoint Error detected" " - Resetting Host Adapter\n", HostAdapter);
-				HostAdapter->HostAdapterInternalError = true;
+			case FPOINT_INTERN_ERR:
+				blogic_warn("Internal FlashPoint Error detected - Resetting Host Adapter\n", adapter);
+				adapter->adapter_intern_err = true;
 				break;
 			}
 	}
 	/*
 	   Process any completed CCBs.
 	 */
-	if (HostAdapter->FirstCompletedCCB != NULL)
-		BusLogic_ProcessCompletedCCBs(HostAdapter);
+	if (adapter->firstccb != NULL)
+		blogic_process_ccbs(adapter);
 	/*
 	   Reset the Host Adapter if requested.
 	 */
-	if (HostAdapter->HostAdapterExternalReset) {
-		BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", HostAdapter, HostAdapter->FullModelName);
-		BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
-		BusLogic_ResetHostAdapter(HostAdapter, false);
-		HostAdapter->HostAdapterExternalReset = false;
-	} else if (HostAdapter->HostAdapterInternalError) {
-		BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", HostAdapter, HostAdapter->FullModelName);
-		BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
-		BusLogic_ResetHostAdapter(HostAdapter, true);
-		HostAdapter->HostAdapterInternalError = false;
+	if (adapter->adapter_extreset) {
+		blogic_warn("Resetting %s due to External SCSI Bus Reset\n", adapter, adapter->full_model);
+		blogic_inc_count(&adapter->ext_resets);
+		blogic_resetadapter(adapter, false);
+		adapter->adapter_extreset = false;
+	} else if (adapter->adapter_intern_err) {
+		blogic_warn("Resetting %s due to Host Adapter Internal Error\n", adapter, adapter->full_model);
+		blogic_inc_count(&adapter->adapter_intern_errors);
+		blogic_resetadapter(adapter, true);
+		adapter->adapter_intern_err = false;
 	}
 	/*
 	   Release exclusive access to Host Adapter.
 	 */
-	spin_unlock_irqrestore(HostAdapter->SCSI_Host->host_lock, ProcessorFlags);
+	spin_unlock_irqrestore(adapter->scsi_host->host_lock, processor_flag);
 	return IRQ_HANDLED;
 }
 
 
 /*
-  BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
+  blogic_write_outbox places CCB and Action Code into an Outgoing
   Mailbox for execution by Host Adapter.  The Host Adapter's Lock should
   already have been acquired by the caller.
 */
 
-static bool BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter
-					     *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB)
+static bool blogic_write_outbox(struct blogic_adapter *adapter,
+		enum blogic_action action, struct blogic_ccb *ccb)
 {
-	struct BusLogic_OutgoingMailbox *NextOutgoingMailbox;
-	NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
-	if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree) {
-		CCB->Status = BusLogic_CCB_Active;
+	struct blogic_outbox *next_outbox;
+
+	next_outbox = adapter->next_outbox;
+	if (next_outbox->action == BLOGIC_OUTBOX_FREE) {
+		ccb->status = BLOGIC_CCB_ACTIVE;
 		/*
-		   The CCB field must be written before the Action Code field since
-		   the Host Adapter is operating asynchronously and the locking code
-		   does not protect against simultaneous access by the Host Adapter.
+		   The CCB field must be written before the Action Code field
+		   since the Host Adapter is operating asynchronously and the
+		   locking code does not protect against simultaneous access
+		   by the Host Adapter.
 		 */
-		NextOutgoingMailbox->CCB = CCB->DMA_Handle;
-		NextOutgoingMailbox->ActionCode = ActionCode;
-		BusLogic_StartMailboxCommand(HostAdapter);
-		if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
-			NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
-		HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
-		if (ActionCode == BusLogic_MailboxStartCommand) {
-			HostAdapter->ActiveCommands[CCB->TargetID]++;
-			if (CCB->Opcode != BusLogic_BusDeviceReset)
-				HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
+		next_outbox->ccb = ccb->dma_handle;
+		next_outbox->action = action;
+		blogic_execmbox(adapter);
+		if (++next_outbox > adapter->last_outbox)
+			next_outbox = adapter->first_outbox;
+		adapter->next_outbox = next_outbox;
+		if (action == BLOGIC_MBOX_START) {
+			adapter->active_cmds[ccb->tgt_id]++;
+			if (ccb->opcode != BLOGIC_BDR)
+				adapter->tgt_stats[ccb->tgt_id].cmds_tried++;
 		}
 		return true;
 	}
@@ -2784,65 +2996,72 @@ static bool BusLogic_WriteOutgoingMailbo
 
 /* Error Handling (EH) support */
 
-static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
+static int blogic_hostreset(struct scsi_cmnd *SCpnt)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata;
+	struct blogic_adapter *adapter =
+		(struct blogic_adapter *) SCpnt->device->host->hostdata;
 
 	unsigned int id = SCpnt->device->id;
-	struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
+	struct blogic_tgt_stats *stats = &adapter->tgt_stats[id];
 	int rc;
 
 	spin_lock_irq(SCpnt->device->host->host_lock);
 
-	BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
+	blogic_inc_count(&stats->adatper_reset_req);
 
-	rc = BusLogic_ResetHostAdapter(HostAdapter, false);
+	rc = blogic_resetadapter(adapter, false);
 	spin_unlock_irq(SCpnt->device->host->host_lock);
 	return rc;
 }
 
 /*
-  BusLogic_QueueCommand creates a CCB for Command and places it into an
+  blogic_qcmd creates a CCB for Command and places it into an
   Outgoing Mailbox for execution by the associated Host Adapter.
 */
 
-static int BusLogic_QueueCommand_lck(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *))
+static int blogic_qcmd_lck(struct scsi_cmnd *command,
+		void (*comp_cb) (struct scsi_cmnd *))
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
-	struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id];
-	struct BusLogic_TargetStatistics *TargetStatistics = HostAdapter->TargetStatistics;
-	unsigned char *CDB = Command->cmnd;
-	int CDB_Length = Command->cmd_len;
-	int TargetID = Command->device->id;
-	int LogicalUnit = Command->device->lun;
-	int BufferLength = scsi_bufflen(Command);
-	int Count;
-	struct BusLogic_CCB *CCB;
+	struct blogic_adapter *adapter =
+		(struct blogic_adapter *) command->device->host->hostdata;
+	struct blogic_tgt_flags *tgt_flags =
+		&adapter->tgt_flags[command->device->id];
+	struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
+	unsigned char *cdb = command->cmnd;
+	int cdblen = command->cmd_len;
+	int tgt_id = command->device->id;
+	int lun = command->device->lun;
+	int buflen = scsi_bufflen(command);
+	int count;
+	struct blogic_ccb *ccb;
+
 	/*
-	   SCSI REQUEST_SENSE commands will be executed automatically by the Host
-	   Adapter for any errors, so they should not be executed explicitly unless
-	   the Sense Data is zero indicating that no error occurred.
+	   SCSI REQUEST_SENSE commands will be executed automatically by the
+	   Host Adapter for any errors, so they should not be executed
+	   explicitly unless the Sense Data is zero indicating that no error
+	   occurred.
 	 */
-	if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) {
-		Command->result = DID_OK << 16;
-		CompletionRoutine(Command);
+	if (cdb[0] == REQUEST_SENSE && command->sense_buffer[0] != 0) {
+		command->result = DID_OK << 16;
+		comp_cb(command);
 		return 0;
 	}
 	/*
-	   Allocate a CCB from the Host Adapter's free list.  In the unlikely event
-	   that there are none available and memory allocation fails, wait 1 second
-	   and try again.  If that fails, the Host Adapter is probably hung so signal
-	   an error as a Host Adapter Hard Reset should be initiated soon.
+	   Allocate a CCB from the Host Adapter's free list. In the unlikely
+	   event that there are none available and memory allocation fails,
+	   wait 1 second and try again. If that fails, the Host Adapter is
+	   probably hung so signal an error as a Host Adapter Hard Reset
+	   should be initiated soon.
 	 */
-	CCB = BusLogic_AllocateCCB(HostAdapter);
-	if (CCB == NULL) {
-		spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
-		BusLogic_Delay(1);
-		spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
-		CCB = BusLogic_AllocateCCB(HostAdapter);
-		if (CCB == NULL) {
-			Command->result = DID_ERROR << 16;
-			CompletionRoutine(Command);
+	ccb = blogic_alloc_ccb(adapter);
+	if (ccb == NULL) {
+		spin_unlock_irq(adapter->scsi_host->host_lock);
+		blogic_delay(1);
+		spin_lock_irq(adapter->scsi_host->host_lock);
+		ccb = blogic_alloc_ccb(adapter);
+		if (ccb == NULL) {
+			command->result = DID_ERROR << 16;
+			comp_cb(command);
 			return 0;
 		}
 	}
@@ -2850,217 +3069,241 @@ static int BusLogic_QueueCommand_lck(str
 	/*
 	   Initialize the fields in the BusLogic Command Control Block (CCB).
 	 */
-	Count = scsi_dma_map(Command);
-	BUG_ON(Count < 0);
-	if (Count) {
+	count = scsi_dma_map(command);
+	BUG_ON(count < 0);
+	if (count) {
 		struct scatterlist *sg;
 		int i;
 
-		CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
-		CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment);
-		if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
-			CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB);
+		ccb->opcode = BLOGIC_INITIATOR_CCB_SG;
+		ccb->datalen = count * sizeof(struct blogic_sg_seg);
+		if (blogic_multimaster_type(adapter))
+			ccb->data = (void *)((unsigned int) ccb->dma_handle +
+					((unsigned long) &ccb->sglist -
+					(unsigned long) ccb));
 		else
-			CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
+			ccb->data = ccb->sglist;
 
-		scsi_for_each_sg(Command, sg, Count, i) {
-			CCB->ScatterGatherList[i].SegmentByteCount =
-				sg_dma_len(sg);
-			CCB->ScatterGatherList[i].SegmentDataPointer =
-				sg_dma_address(sg);
+		scsi_for_each_sg(command, sg, count, i) {
+			ccb->sglist[i].segbytes = sg_dma_len(sg);
+			ccb->sglist[i].segdata = sg_dma_address(sg);
 		}
-	} else if (!Count) {
-		CCB->Opcode = BusLogic_InitiatorCCB;
-		CCB->DataLength = BufferLength;
-		CCB->DataPointer = 0;
+	} else if (!count) {
+		ccb->opcode = BLOGIC_INITIATOR_CCB;
+		ccb->datalen = buflen;
+		ccb->data = 0;
 	}
 
-	switch (CDB[0]) {
+	switch (cdb[0]) {
 	case READ_6:
 	case READ_10:
-		CCB->DataDirection = BusLogic_DataInLengthChecked;
-		TargetStatistics[TargetID].ReadCommands++;
-		BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesRead, BufferLength);
-		BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
+		ccb->datadir = BLOGIC_DATAIN_CHECKED;
+		tgt_stats[tgt_id].read_cmds++;
+		blogic_addcount(&tgt_stats[tgt_id].bytesread, buflen);
+		blogic_incszbucket(tgt_stats[tgt_id].read_sz_buckets, buflen);
 		break;
 	case WRITE_6:
 	case WRITE_10:
-		CCB->DataDirection = BusLogic_DataOutLengthChecked;
-		TargetStatistics[TargetID].WriteCommands++;
-		BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
-		BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
+		ccb->datadir = BLOGIC_DATAOUT_CHECKED;
+		tgt_stats[tgt_id].write_cmds++;
+		blogic_addcount(&tgt_stats[tgt_id].byteswritten, buflen);
+		blogic_incszbucket(tgt_stats[tgt_id].write_sz_buckets, buflen);
 		break;
 	default:
-		CCB->DataDirection = BusLogic_UncheckedDataTransfer;
+		ccb->datadir = BLOGIC_UNCHECKED_TX;
 		break;
 	}
-	CCB->CDB_Length = CDB_Length;
-	CCB->HostAdapterStatus = 0;
-	CCB->TargetDeviceStatus = 0;
-	CCB->TargetID = TargetID;
-	CCB->LogicalUnit = LogicalUnit;
-	CCB->TagEnable = false;
-	CCB->LegacyTagEnable = false;
+	ccb->cdblen = cdblen;
+	ccb->adapter_status = 0;
+	ccb->tgt_status = 0;
+	ccb->tgt_id = tgt_id;
+	ccb->lun = lun;
+	ccb->tag_enable = false;
+	ccb->legacytag_enable = false;
 	/*
-	   BusLogic recommends that after a Reset the first couple of commands that
-	   are sent to a Target Device be sent in a non Tagged Queue fashion so that
-	   the Host Adapter and Target Device can establish Synchronous and Wide
-	   Transfer before Queue Tag messages can interfere with the Synchronous and
-	   Wide Negotiation messages.  By waiting to enable Tagged Queuing until after
-	   the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
-	   assured that after a Reset any pending commands are requeued before Tagged
-	   Queuing is enabled and that the Tagged Queuing message will not occur while
-	   the partition table is being printed.  In addition, some devices do not
-	   properly handle the transition from non-tagged to tagged commands, so it is
-	   necessary to wait until there are no pending commands for a target device
+	   BusLogic recommends that after a Reset the first couple of
+	   commands that are sent to a Target Device be sent in a non
+	   Tagged Queue fashion so that the Host Adapter and Target Device
+	   can establish Synchronous and Wide Transfer before Queue Tag
+	   messages can interfere with the Synchronous and Wide Negotiation
+	   messages.  By waiting to enable Tagged Queuing until after the
+	   first BLOGIC_MAX_TAG_DEPTH commands have been queued, it is
+	   assured that after a Reset any pending commands are requeued
+	   before Tagged Queuing is enabled and that the Tagged Queuing
+	   message will not occur while the partition table is being printed.
+	   In addition, some devices do not properly handle the transition
+	   from non-tagged to tagged commands, so it is necessary to wait
+	   until there are no pending commands for a target device
 	   before queuing tagged commands.
 	 */
-	if (HostAdapter->CommandsSinceReset[TargetID]++ >=
-	    BusLogic_MaxTaggedQueueDepth && !TargetFlags->TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] == 0 && TargetFlags->TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) {
-		TargetFlags->TaggedQueuingActive = true;
-		BusLogic_Notice("Tagged Queuing now active for Target %d\n", HostAdapter, TargetID);
+	if (adapter->cmds_since_rst[tgt_id]++ >= BLOGIC_MAX_TAG_DEPTH &&
+			!tgt_flags->tagq_active &&
+			adapter->active_cmds[tgt_id] == 0
+			&& tgt_flags->tagq_ok &&
+			(adapter->tagq_ok & (1 << tgt_id))) {
+		tgt_flags->tagq_active = true;
+		blogic_notice("Tagged Queuing now active for Target %d\n",
+					adapter, tgt_id);
 	}
-	if (TargetFlags->TaggedQueuingActive) {
-		enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag;
+	if (tgt_flags->tagq_active) {
+		enum blogic_queuetag queuetag = BLOGIC_SIMPLETAG;
 		/*
-		   When using Tagged Queuing with Simple Queue Tags, it appears that disk
-		   drive controllers do not guarantee that a queued command will not
-		   remain in a disconnected state indefinitely if commands that read or
-		   write nearer the head position continue to arrive without interruption.
-		   Therefore, for each Target Device this driver keeps track of the last
-		   time either the queue was empty or an Ordered Queue Tag was issued.  If
-		   more than 4 seconds (one fifth of the 20 second disk timeout) have
-		   elapsed since this last sequence point, this command will be issued
-		   with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
-		   the Target Device to complete all previously queued commands before
-		   this command may be executed.
+		   When using Tagged Queuing with Simple Queue Tags, it
+		   appears that disk drive controllers do not guarantee that
+		   a queued command will not remain in a disconnected state
+		   indefinitely if commands that read or write nearer the
+		   head position continue to arrive without interruption.
+		   Therefore, for each Target Device this driver keeps track
+		   of the last time either the queue was empty or an Ordered
+		   Queue Tag was issued. If more than 4 seconds (one fifth
+		   of the 20 second disk timeout) have elapsed since this
+		   last sequence point, this command will be issued with an
+		   Ordered Queue Tag rather than a Simple Queue Tag, which
+		   forces the Target Device to complete all previously
+		   queued commands before this command may be executed.
 		 */
-		if (HostAdapter->ActiveCommands[TargetID] == 0)
-			HostAdapter->LastSequencePoint[TargetID] = jiffies;
-		else if (time_after(jiffies, HostAdapter->LastSequencePoint[TargetID] + 4 * HZ)) {
-			HostAdapter->LastSequencePoint[TargetID] = jiffies;
-			QueueTag = BusLogic_OrderedQueueTag;
+		if (adapter->active_cmds[tgt_id] == 0)
+			adapter->last_seqpoint[tgt_id] = jiffies;
+		else if (time_after(jiffies,
+				adapter->last_seqpoint[tgt_id] + 4 * HZ)) {
+			adapter->last_seqpoint[tgt_id] = jiffies;
+			queuetag = BLOGIC_ORDEREDTAG;
 		}
-		if (HostAdapter->ExtendedLUNSupport) {
-			CCB->TagEnable = true;
-			CCB->QueueTag = QueueTag;
+		if (adapter->ext_lun) {
+			ccb->tag_enable = true;
+			ccb->queuetag = queuetag;
 		} else {
-			CCB->LegacyTagEnable = true;
-			CCB->LegacyQueueTag = QueueTag;
+			ccb->legacytag_enable = true;
+			ccb->legacy_tag = queuetag;
 		}
 	}
-	memcpy(CCB->CDB, CDB, CDB_Length);
-	CCB->SenseDataLength = SCSI_SENSE_BUFFERSIZE;
-	CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, Command->sense_buffer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
-	CCB->Command = Command;
-	Command->scsi_done = CompletionRoutine;
-	if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
+	memcpy(ccb->cdb, cdb, cdblen);
+	ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
+	ccb->sensedata = pci_map_single(adapter->pci_device,
+				command->sense_buffer, ccb->sense_datalen,
+				PCI_DMA_FROMDEVICE);
+	ccb->command = command;
+	command->scsi_done = comp_cb;
+	if (blogic_multimaster_type(adapter)) {
 		/*
-		   Place the CCB in an Outgoing Mailbox.  The higher levels of the SCSI
-		   Subsystem should not attempt to queue more commands than can be placed
-		   in Outgoing Mailboxes, so there should always be one free.  In the
-		   unlikely event that there are none available, wait 1 second and try
-		   again.  If that fails, the Host Adapter is probably hung so signal an
-		   error as a Host Adapter Hard Reset should be initiated soon.
+		   Place the CCB in an Outgoing Mailbox. The higher levels
+		   of the SCSI Subsystem should not attempt to queue more
+		   commands than can be placed in Outgoing Mailboxes, so
+		   there should always be one free.  In the unlikely event
+		   that there are none available, wait 1 second and try
+		   again. If that fails, the Host Adapter is probably hung
+		   so signal an error as a Host Adapter Hard Reset should
+		   be initiated soon.
 		 */
-		if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
-			spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
-			BusLogic_Warning("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", HostAdapter);
-			BusLogic_Delay(1);
-			spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
-			if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) {
-				BusLogic_Warning("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", HostAdapter);
-				BusLogic_DeallocateCCB(CCB);
-				Command->result = DID_ERROR << 16;
-				Command->scsi_done(Command);
+		if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
+			spin_unlock_irq(adapter->scsi_host->host_lock);
+			blogic_warn("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", adapter);
+			blogic_delay(1);
+			spin_lock_irq(adapter->scsi_host->host_lock);
+			if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
+						ccb)) {
+				blogic_warn("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", adapter);
+				blogic_dealloc_ccb(ccb);
+				command->result = DID_ERROR << 16;
+				command->scsi_done(command);
 			}
 		}
 	} else {
 		/*
-		   Call the FlashPoint SCCB Manager to start execution of the CCB.
+		   Call the FlashPoint SCCB Manager to start execution of
+		   the CCB.
 		 */
-		CCB->Status = BusLogic_CCB_Active;
-		HostAdapter->ActiveCommands[TargetID]++;
-		TargetStatistics[TargetID].CommandsAttempted++;
-		FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
+		ccb->status = BLOGIC_CCB_ACTIVE;
+		adapter->active_cmds[tgt_id]++;
+		tgt_stats[tgt_id].cmds_tried++;
+		FlashPoint_StartCCB(adapter->cardhandle, ccb);
 		/*
-		   The Command may have already completed and BusLogic_QueueCompletedCCB
-		   been called, or it may still be pending.
+		   The Command may have already completed and
+		   blogic_qcompleted_ccb been called, or it may still be
+		   pending.
 		 */
-		if (CCB->Status == BusLogic_CCB_Completed)
-			BusLogic_ProcessCompletedCCBs(HostAdapter);
+		if (ccb->status == BLOGIC_CCB_COMPLETE)
+			blogic_process_ccbs(adapter);
 	}
 	return 0;
 }
 
-static DEF_SCSI_QCMD(BusLogic_QueueCommand)
+static DEF_SCSI_QCMD(blogic_qcmd)
 
 #if 0
 /*
-  BusLogic_AbortCommand aborts Command if possible.
+  blogic_abort aborts Command if possible.
 */
 
-static int BusLogic_AbortCommand(struct scsi_cmnd *Command)
+static int blogic_abort(struct scsi_cmnd *command)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
+	struct blogic_adapter *adapter =
+		(struct blogic_adapter *) command->device->host->hostdata;
+
+	int tgt_id = command->device->id;
+	struct blogic_ccb *ccb;
+	blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request);
 
-	int TargetID = Command->device->id;
-	struct BusLogic_CCB *CCB;
-	BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
 	/*
-	   Attempt to find an Active CCB for this Command.  If no Active CCB for this
-	   Command is found, then no Abort is necessary.
+	   Attempt to find an Active CCB for this Command. If no Active
+	   CCB for this Command is found, then no Abort is necessary.
 	 */
-	for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
-		if (CCB->Command == Command)
+	for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
+		if (ccb->command == command)
 			break;
-	if (CCB == NULL) {
-		BusLogic_Warning("Unable to Abort Command to Target %d - " "No CCB Found\n", HostAdapter, TargetID);
+	if (ccb == NULL) {
+		blogic_warn("Unable to Abort Command to Target %d - No CCB Found\n", adapter, tgt_id);
 		return SUCCESS;
-	} else if (CCB->Status == BusLogic_CCB_Completed) {
-		BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Completed\n", HostAdapter, TargetID);
+	} else if (ccb->status == BLOGIC_CCB_COMPLETE) {
+		blogic_warn("Unable to Abort Command to Target %d - CCB Completed\n", adapter, tgt_id);
 		return SUCCESS;
-	} else if (CCB->Status == BusLogic_CCB_Reset) {
-		BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Reset\n", HostAdapter, TargetID);
+	} else if (ccb->status == BLOGIC_CCB_RESET) {
+		blogic_warn("Unable to Abort Command to Target %d - CCB Reset\n", adapter, tgt_id);
 		return SUCCESS;
 	}
-	if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) {
+	if (blogic_multimaster_type(adapter)) {
 		/*
-		   Attempt to Abort this CCB.  MultiMaster Firmware versions prior to 5.xx
-		   do not generate Abort Tag messages, but only generate the non-tagged
-		   Abort message.  Since non-tagged commands are not sent by the Host
-		   Adapter until the queue of outstanding tagged commands has completed,
-		   and the Abort message is treated as a non-tagged command, it is
-		   effectively impossible to abort commands when Tagged Queuing is active.
-		   Firmware version 5.xx does generate Abort Tag messages, so it is
-		   possible to abort commands when Tagged Queuing is active.
+		   Attempt to Abort this CCB.  MultiMaster Firmware versions
+		   prior to 5.xx do not generate Abort Tag messages, but only
+		   generate the non-tagged Abort message.  Since non-tagged
+		   commands are not sent by the Host Adapter until the queue
+		   of outstanding tagged commands has completed, and the
+		   Abort message is treated as a non-tagged command, it is
+		   effectively impossible to abort commands when Tagged
+		   Queuing is active. Firmware version 5.xx does generate
+		   Abort Tag messages, so it is possible to abort commands
+		   when Tagged Queuing is active.
 		 */
-		if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && HostAdapter->FirmwareVersion[0] < '5') {
-			BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "Abort Tag Not Supported\n", HostAdapter, CCB->SerialNumber, TargetID);
+		if (adapter->tgt_flags[tgt_id].tagq_active &&
+				adapter->fw_ver[0] < '5') {
+			blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id);
 			return FAILURE;
-		} else if (BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxAbortCommand, CCB)) {
-			BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
-			BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
+		} else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT,
+					ccb)) {
+			blogic_warn("Aborting CCB #%ld to Target %d\n",
+					adapter, ccb->serial, tgt_id);
+			blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
 			return SUCCESS;
 		} else {
-			BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "No Outgoing Mailboxes\n", HostAdapter, CCB->SerialNumber, TargetID);
+			blogic_warn("Unable to Abort CCB #%ld to Target %d - No Outgoing Mailboxes\n", adapter, ccb->serial, tgt_id);
 			return FAILURE;
 		}
 	} else {
 		/*
-		   Call the FlashPoint SCCB Manager to abort execution of the CCB.
+		   Call the FlashPoint SCCB Manager to abort execution of
+		   the CCB.
 		 */
-		BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID);
-		BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
-		FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
+		blogic_warn("Aborting CCB #%ld to Target %d\n", adapter,
+				ccb->serial, tgt_id);
+		blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
+		FlashPoint_AbortCCB(adapter->cardhandle, ccb);
 		/*
 		   The Abort may have already been completed and
-		   BusLogic_QueueCompletedCCB been called, or it
+		   blogic_qcompleted_ccb been called, or it
 		   may still be pending.
 		 */
-		if (CCB->Status == BusLogic_CCB_Completed) {
-			BusLogic_ProcessCompletedCCBs(HostAdapter);
-		}
+		if (ccb->status == BLOGIC_CCB_COMPLETE)
+			blogic_process_ccbs(adapter);
 		return SUCCESS;
 	}
 	return SUCCESS;
@@ -3068,21 +3311,23 @@ static int BusLogic_AbortCommand(struct
 
 #endif
 /*
-  BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
+  blogic_resetadapter resets Host Adapter if possible, marking all
   currently executing SCSI Commands as having been Reset.
 */
 
-static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, bool HardReset)
+static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
 {
-	struct BusLogic_CCB *CCB;
-	int TargetID;
+	struct blogic_ccb *ccb;
+	int tgt_id;
 
 	/*
 	 * Attempt to Reset and Reinitialize the Host Adapter.
 	 */
 
-	if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && BusLogic_InitializeHostAdapter(HostAdapter))) {
-		BusLogic_Error("Resetting %s Failed\n", HostAdapter, HostAdapter->FullModelName);
+	if (!(blogic_hwreset(adapter, hard_reset) &&
+				blogic_initadapter(adapter))) {
+		blogic_err("Resetting %s Failed\n", adapter,
+						adapter->full_model);
 		return FAILURE;
 	}
 
@@ -3090,9 +3335,9 @@ static int BusLogic_ResetHostAdapter(str
 	 * Deallocate all currently executing CCBs.
 	 */
 
-	for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
-		if (CCB->Status == BusLogic_CCB_Active)
-			BusLogic_DeallocateCCB(CCB);
+	for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
+		if (ccb->status == BLOGIC_CCB_ACTIVE)
+			blogic_dealloc_ccb(ccb);
 	/*
 	 * Wait a few seconds between the Host Adapter Hard Reset which
 	 * initiates a SCSI Bus Reset and issuing any SCSI Commands.  Some
@@ -3100,21 +3345,21 @@ static int BusLogic_ResetHostAdapter(str
 	 * after a SCSI Bus Reset.
 	 */
 
-	if (HardReset) {
-		spin_unlock_irq(HostAdapter->SCSI_Host->host_lock);
-		BusLogic_Delay(HostAdapter->BusSettleTime);
-		spin_lock_irq(HostAdapter->SCSI_Host->host_lock);
+	if (hard_reset) {
+		spin_unlock_irq(adapter->scsi_host->host_lock);
+		blogic_delay(adapter->bus_settle_time);
+		spin_lock_irq(adapter->scsi_host->host_lock);
 	}
 
-	for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
-		HostAdapter->LastResetAttempted[TargetID] = jiffies;
-		HostAdapter->LastResetCompleted[TargetID] = jiffies;
+	for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
+		adapter->last_resettried[tgt_id] = jiffies;
+		adapter->last_resetdone[tgt_id] = jiffies;
 	}
 	return SUCCESS;
 }
 
 /*
-  BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
+  blogic_diskparam returns the Heads/Sectors/Cylinders BIOS Disk
   Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
   the appropriate number of cylinders so as not to exceed drive capacity.  In
   order for disks equal to or larger than 1 GB to be addressable by the BIOS
@@ -3130,66 +3375,70 @@ static int BusLogic_ResetHostAdapter(str
   the BIOS, and a warning may be displayed.
 */
 
-static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, sector_t capacity, int *Parameters)
+static int blogic_diskparam(struct scsi_device *sdev, struct block_device *dev,
+		sector_t capacity, int *params)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata;
-	struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters;
+	struct blogic_adapter *adapter =
+				(struct blogic_adapter *) sdev->host->hostdata;
+	struct bios_diskparam *diskparam = (struct bios_diskparam *) params;
 	unsigned char *buf;
-	if (HostAdapter->ExtendedTranslationEnabled && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */ ) {
-		if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */ ) {
-			DiskParameters->Heads = 255;
-			DiskParameters->Sectors = 63;
+
+	if (adapter->ext_trans_enable && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */) {
+		if (capacity >= 4 * 1024 * 1024 /* 2 GB in 512 byte sectors */) {
+			diskparam->heads = 255;
+			diskparam->sectors = 63;
 		} else {
-			DiskParameters->Heads = 128;
-			DiskParameters->Sectors = 32;
+			diskparam->heads = 128;
+			diskparam->sectors = 32;
 		}
 	} else {
-		DiskParameters->Heads = 64;
-		DiskParameters->Sectors = 32;
+		diskparam->heads = 64;
+		diskparam->sectors = 32;
 	}
-	DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
-	buf = scsi_bios_ptable(Device);
+	diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
+	buf = scsi_bios_ptable(dev);
 	if (buf == NULL)
 		return 0;
 	/*
-	   If the boot sector partition table flag is valid, search for a partition
-	   table entry whose end_head matches one of the standard BusLogic geometry
-	   translations (64/32, 128/32, or 255/63).
+	   If the boot sector partition table flag is valid, search for
+	   a partition table entry whose end_head matches one of the
+	   standard BusLogic geometry translations (64/32, 128/32, or 255/63).
 	 */
 	if (*(unsigned short *) (buf + 64) == 0xAA55) {
-		struct partition *FirstPartitionEntry = (struct partition *) buf;
-		struct partition *PartitionEntry = FirstPartitionEntry;
-		int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
-		unsigned char PartitionEntryEndHead = 0, PartitionEntryEndSector = 0;
-		for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) {
-			PartitionEntryEndHead = PartitionEntry->end_head;
-			PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
-			if (PartitionEntryEndHead == 64 - 1) {
-				DiskParameters->Heads = 64;
-				DiskParameters->Sectors = 32;
+		struct partition *part1_entry = (struct partition *) buf;
+		struct partition *part_entry = part1_entry;
+		int saved_cyl = diskparam->cylinders, part_no;
+		unsigned char part_end_head = 0, part_end_sector = 0;
+
+		for (part_no = 0; part_no < 4; part_no++) {
+			part_end_head = part_entry->end_head;
+			part_end_sector = part_entry->end_sector & 0x3F;
+			if (part_end_head == 64 - 1) {
+				diskparam->heads = 64;
+				diskparam->sectors = 32;
 				break;
-			} else if (PartitionEntryEndHead == 128 - 1) {
-				DiskParameters->Heads = 128;
-				DiskParameters->Sectors = 32;
+			} else if (part_end_head == 128 - 1) {
+				diskparam->heads = 128;
+				diskparam->sectors = 32;
 				break;
-			} else if (PartitionEntryEndHead == 255 - 1) {
-				DiskParameters->Heads = 255;
-				DiskParameters->Sectors = 63;
+			} else if (part_end_head == 255 - 1) {
+				diskparam->heads = 255;
+				diskparam->sectors = 63;
 				break;
 			}
-			PartitionEntry++;
+			part_entry++;
 		}
-		if (PartitionNumber == 4) {
-			PartitionEntryEndHead = FirstPartitionEntry->end_head;
-			PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
+		if (part_no == 4) {
+			part_end_head = part1_entry->end_head;
+			part_end_sector = part1_entry->end_sector & 0x3F;
 		}
-		DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors);
-		if (PartitionNumber < 4 && PartitionEntryEndSector == DiskParameters->Sectors) {
-			if (DiskParameters->Cylinders != SavedCylinders)
-				BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
-		} else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0) {
-			BusLogic_Warning("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", HostAdapter, PartitionEntryEndHead + 1, PartitionEntryEndSector);
-			BusLogic_Warning("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors);
+		diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
+		if (part_no < 4 && part_end_sector == diskparam->sectors) {
+			if (diskparam->cylinders != saved_cyl)
+				blogic_warn("Adopting Geometry %d/%d from Partition Table\n", adapter, diskparam->heads, diskparam->sectors);
+		} else if (part_end_head > 0 || part_end_sector > 0) {
+			blogic_warn("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", adapter, part_end_head + 1, part_end_sector);
+			blogic_warn("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", adapter, diskparam->heads, diskparam->sectors);
 		}
 	}
 	kfree(buf);
@@ -3201,92 +3450,94 @@ static int BusLogic_BIOSDiskParameters(s
   BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
 */
 
-static int BusLogic_write_info(struct Scsi_Host *shost, char *ProcBuffer, int BytesAvailable)
+static int blogic_write_info(struct Scsi_Host *shost, char *procbuf,
+				int bytes_avail)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata;
-	struct BusLogic_TargetStatistics *TargetStatistics;
+	struct blogic_adapter *adapter =
+				(struct blogic_adapter *) shost->hostdata;
+	struct blogic_tgt_stats *tgt_stats;
 
-	TargetStatistics = HostAdapter->TargetStatistics;
-	HostAdapter->ExternalHostAdapterResets = 0;
-	HostAdapter->HostAdapterInternalErrors = 0;
-	memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics));
+	tgt_stats = adapter->tgt_stats;
+	adapter->ext_resets = 0;
+	adapter->adapter_intern_errors = 0;
+	memset(tgt_stats, 0, BLOGIC_MAXDEV * sizeof(struct blogic_tgt_stats));
 	return 0;
 }
 
-static int BusLogic_show_info(struct seq_file *m, struct Scsi_Host *shost)
+static int blogic_show_info(struct seq_file *m, struct Scsi_Host *shost)
 {
-	struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) shost->hostdata;
-	struct BusLogic_TargetStatistics *TargetStatistics;
-	int TargetID;
+	struct blogic_adapter *adapter = (struct blogic_adapter *) shost->hostdata;
+	struct blogic_tgt_stats *tgt_stats;
+	int tgt;
 
-	TargetStatistics = HostAdapter->TargetStatistics;
-	seq_write(m, HostAdapter->MessageBuffer, HostAdapter->MessageBufferLength);
+	tgt_stats = adapter->tgt_stats;
+	seq_write(m, adapter->msgbuf, adapter->msgbuflen);
 	seq_printf(m, "\n\
 Current Driver Queue Depth:	%d\n\
-Currently Allocated CCBs:	%d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs);
+Currently Allocated CCBs:	%d\n", adapter->drvr_qdepth, adapter->alloc_ccbs);
 	seq_printf(m, "\n\n\
 			   DATA TRANSFER STATISTICS\n\
 \n\
 Target	Tagged Queuing	Queue Depth  Active  Attempted	Completed\n\
 ======	==============	===========  ======  =========	=========\n");
-	for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
-		struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
-		if (!TargetFlags->TargetExists)
+	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
+		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
+		if (!tgt_flags->tgt_exists)
 			continue;
-		seq_printf(m, "  %2d	%s", TargetID, (TargetFlags->TaggedQueuingSupported ? (TargetFlags->TaggedQueuingActive ? "    Active" : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
+		seq_printf(m, "  %2d	%s", tgt, (tgt_flags->tagq_ok ? (tgt_flags->tagq_active ? "    Active" : (adapter->tagq_ok & (1 << tgt)
 																				    ? "  Permitted" : "   Disabled"))
 									  : "Not Supported"));
 		seq_printf(m,
-				  "	    %3d       %3u    %9u	%9u\n", HostAdapter->QueueDepth[TargetID], HostAdapter->ActiveCommands[TargetID], TargetStatistics[TargetID].CommandsAttempted, TargetStatistics[TargetID].CommandsCompleted);
+				  "	    %3d       %3u    %9u	%9u\n", adapter->qdepth[tgt], adapter->active_cmds[tgt], tgt_stats[tgt].cmds_tried, tgt_stats[tgt].cmds_complete);
 	}
 	seq_printf(m, "\n\
 Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Written\n\
 ======  =============  ==============  ===================  ===================\n");
-	for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
-		struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
-		if (!TargetFlags->TargetExists)
+	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
+		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
+		if (!tgt_flags->tgt_exists)
 			continue;
-		seq_printf(m, "  %2d	  %9u	 %9u", TargetID, TargetStatistics[TargetID].ReadCommands, TargetStatistics[TargetID].WriteCommands);
-		if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
-			seq_printf(m, "     %9u%09u", TargetStatistics[TargetID].TotalBytesRead.Billions, TargetStatistics[TargetID].TotalBytesRead.Units);
+		seq_printf(m, "  %2d	  %9u	 %9u", tgt, tgt_stats[tgt].read_cmds, tgt_stats[tgt].write_cmds);
+		if (tgt_stats[tgt].bytesread.billions > 0)
+			seq_printf(m, "     %9u%09u", tgt_stats[tgt].bytesread.billions, tgt_stats[tgt].bytesread.units);
 		else
-			seq_printf(m, "		%9u", TargetStatistics[TargetID].TotalBytesRead.Units);
-		if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
-			seq_printf(m, "   %9u%09u\n", TargetStatistics[TargetID].TotalBytesWritten.Billions, TargetStatistics[TargetID].TotalBytesWritten.Units);
+			seq_printf(m, "		%9u", tgt_stats[tgt].bytesread.units);
+		if (tgt_stats[tgt].byteswritten.billions > 0)
+			seq_printf(m, "   %9u%09u\n", tgt_stats[tgt].byteswritten.billions, tgt_stats[tgt].byteswritten.units);
 		else
-			seq_printf(m, "	     %9u\n", TargetStatistics[TargetID].TotalBytesWritten.Units);
+			seq_printf(m, "	     %9u\n", tgt_stats[tgt].byteswritten.units);
 	}
 	seq_printf(m, "\n\
 Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KB\n\
 ======  =======  =========  =========  =========  =========  =========\n");
-	for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
-		struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
-		if (!TargetFlags->TargetExists)
+	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
+		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
+		if (!tgt_flags->tgt_exists)
 			continue;
 		seq_printf(m,
-			    "  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
-			    TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
-			    TargetStatistics[TargetID].ReadCommandSizeBuckets[1], TargetStatistics[TargetID].ReadCommandSizeBuckets[2], TargetStatistics[TargetID].ReadCommandSizeBuckets[3], TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
+			    "  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", tgt,
+			    tgt_stats[tgt].read_sz_buckets[0],
+			    tgt_stats[tgt].read_sz_buckets[1], tgt_stats[tgt].read_sz_buckets[2], tgt_stats[tgt].read_sz_buckets[3], tgt_stats[tgt].read_sz_buckets[4]);
 		seq_printf(m,
-			    "  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
-			    TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
-			    TargetStatistics[TargetID].WriteCommandSizeBuckets[1], TargetStatistics[TargetID].WriteCommandSizeBuckets[2], TargetStatistics[TargetID].WriteCommandSizeBuckets[3], TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
+			    "  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", tgt,
+			    tgt_stats[tgt].write_sz_buckets[0],
+			    tgt_stats[tgt].write_sz_buckets[1], tgt_stats[tgt].write_sz_buckets[2], tgt_stats[tgt].write_sz_buckets[3], tgt_stats[tgt].write_sz_buckets[4]);
 	}
 	seq_printf(m, "\n\
 Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+\n\
 ======  =======  =========  =========  =========  =========  =========\n");
-	for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
-		struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
-		if (!TargetFlags->TargetExists)
+	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
+		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
+		if (!tgt_flags->tgt_exists)
 			continue;
 		seq_printf(m,
-			    "  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
-			    TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
-			    TargetStatistics[TargetID].ReadCommandSizeBuckets[6], TargetStatistics[TargetID].ReadCommandSizeBuckets[7], TargetStatistics[TargetID].ReadCommandSizeBuckets[8], TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
+			    "  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", tgt,
+			    tgt_stats[tgt].read_sz_buckets[5],
+			    tgt_stats[tgt].read_sz_buckets[6], tgt_stats[tgt].read_sz_buckets[7], tgt_stats[tgt].read_sz_buckets[8], tgt_stats[tgt].read_sz_buckets[9]);
 		seq_printf(m,
-			    "  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
-			    TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
-			    TargetStatistics[TargetID].WriteCommandSizeBuckets[6], TargetStatistics[TargetID].WriteCommandSizeBuckets[7], TargetStatistics[TargetID].WriteCommandSizeBuckets[8], TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
+			    "  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", tgt,
+			    tgt_stats[tgt].write_sz_buckets[5],
+			    tgt_stats[tgt].write_sz_buckets[6], tgt_stats[tgt].write_sz_buckets[7], tgt_stats[tgt].write_sz_buckets[8], tgt_stats[tgt].write_sz_buckets[9]);
 	}
 	seq_printf(m, "\n\n\
 			   ERROR RECOVERY STATISTICS\n\
@@ -3295,84 +3546,86 @@ Target  Command   16-32KB    32-64KB   6
 Target	Requested Completed  Requested Completed  Requested Completed\n\
   ID	\\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////\n\
 ======	 ===== ===== =====    ===== ===== =====	   ===== ===== =====\n");
-	for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
-		struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
-		if (!TargetFlags->TargetExists)
+	for (tgt = 0; tgt < adapter->maxdev; tgt++) {
+		struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
+		if (!tgt_flags->tgt_exists)
 			continue;
 		seq_printf(m, "\
-  %2d	 %5d %5d %5d    %5d %5d %5d	   %5d %5d %5d\n", TargetID, TargetStatistics[TargetID].CommandAbortsRequested, TargetStatistics[TargetID].CommandAbortsAttempted, TargetStatistics[TargetID].CommandAbortsCompleted, TargetStatistics[TargetID].BusDeviceResetsRequested, TargetStatistics[TargetID].BusDeviceResetsAttempted, TargetStatistics[TargetID].BusDeviceResetsCompleted, TargetStatistics[TargetID].HostAdapterResetsRequested, TargetStatistics[TargetID].HostAdapterResetsAttempted, TargetStatistics[TargetID].HostAdapterResetsCompleted);
+  %2d	 %5d %5d %5d    %5d %5d %5d	   %5d %5d %5d\n", tgt, tgt_stats[tgt].aborts_request, tgt_stats[tgt].aborts_tried, tgt_stats[tgt].aborts_done, tgt_stats[tgt].bdr_request, tgt_stats[tgt].bdr_tried, tgt_stats[tgt].bdr_done, tgt_stats[tgt].adatper_reset_req, tgt_stats[tgt].adapter_reset_attempt, tgt_stats[tgt].adapter_reset_done);
 	}
-	seq_printf(m, "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets);
-	seq_printf(m, "Host Adapter Internal Errors: %d\n", HostAdapter->HostAdapterInternalErrors);
+	seq_printf(m, "\nExternal Host Adapter Resets: %d\n", adapter->ext_resets);
+	seq_printf(m, "Host Adapter Internal Errors: %d\n", adapter->adapter_intern_errors);
 	return 0;
 }
 
 
 /*
-  BusLogic_Message prints Driver Messages.
+  blogic_msg prints Driver Messages.
 */
 
-static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...)
+static void blogic_msg(enum blogic_msglevel msglevel, char *fmt,
+			struct blogic_adapter *adapter, ...)
 {
-	static char Buffer[BusLogic_LineBufferSize];
-	static bool BeginningOfLine = true;
-	va_list Arguments;
-	int Length = 0;
-	va_start(Arguments, HostAdapter);
-	Length = vsprintf(Buffer, Format, Arguments);
-	va_end(Arguments);
-	if (MessageLevel == BusLogic_AnnounceLevel) {
-		static int AnnouncementLines = 0;
-		strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
-		HostAdapter->MessageBufferLength += Length;
-		if (++AnnouncementLines <= 2)
-			printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
-	} else if (MessageLevel == BusLogic_InfoLevel) {
-		strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer);
-		HostAdapter->MessageBufferLength += Length;
-		if (BeginningOfLine) {
-			if (Buffer[0] != '\n' || Length > 1)
-				printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
+	static char buf[BLOGIC_LINEBUF_SIZE];
+	static bool begin = true;
+	va_list args;
+	int len = 0;
+
+	va_start(args, adapter);
+	len = vsprintf(buf, fmt, args);
+	va_end(args);
+	if (msglevel == BLOGIC_ANNOUNCE_LEVEL) {
+		static int msglines = 0;
+		strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
+		adapter->msgbuflen += len;
+		if (++msglines <= 2)
+			printk("%sscsi: %s", blogic_msglevelmap[msglevel], buf);
+	} else if (msglevel == BLOGIC_INFO_LEVEL) {
+		strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
+		adapter->msgbuflen += len;
+		if (begin) {
+			if (buf[0] != '\n' || len > 1)
+				printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
 		} else
-			printk("%s", Buffer);
+			printk("%s", buf);
 	} else {
-		if (BeginningOfLine) {
-			if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
-				printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], HostAdapter->HostNumber, Buffer);
+		if (begin) {
+			if (adapter != NULL && adapter->adapter_initd)
+				printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
 			else
-				printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
+				printk("%s%s", blogic_msglevelmap[msglevel], buf);
 		} else
-			printk("%s", Buffer);
+			printk("%s", buf);
 	}
-	BeginningOfLine = (Buffer[Length - 1] == '\n');
+	begin = (buf[len - 1] == '\n');
 }
 
 
 /*
-  BusLogic_ParseKeyword parses an individual option keyword.  It returns true
+  blogic_parse parses an individual option keyword.  It returns true
   and updates the pointer if the keyword is recognized and false otherwise.
 */
 
-static bool __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
+static bool __init blogic_parse(char **str, char *keyword)
 {
-	char *Pointer = *StringPointer;
-	while (*Keyword != '\0') {
-		char StringChar = *Pointer++;
-		char KeywordChar = *Keyword++;
-		if (StringChar >= 'A' && StringChar <= 'Z')
-			StringChar += 'a' - 'Z';
-		if (KeywordChar >= 'A' && KeywordChar <= 'Z')
-			KeywordChar += 'a' - 'Z';
-		if (StringChar != KeywordChar)
+	char *pointer = *str;
+	while (*keyword != '\0') {
+		char strch = *pointer++;
+		char keywordch = *keyword++;
+		if (strch >= 'A' && strch <= 'Z')
+			strch += 'a' - 'Z';
+		if (keywordch >= 'A' && keywordch <= 'Z')
+			keywordch += 'a' - 'Z';
+		if (strch != keywordch)
 			return false;
 	}
-	*StringPointer = Pointer;
+	*str = pointer;
 	return true;
 }
 
 
 /*
-  BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
+  blogic_parseopts handles processing of BusLogic Driver Options
   specifications.
 
   BusLogic Driver Options may be specified either via the Linux Kernel Command
@@ -3388,164 +3641,177 @@ static bool __init BusLogic_ParseKeyword
   <file:Documentation/scsi/BusLogic.txt>.
 */
 
-static int __init BusLogic_ParseDriverOptions(char *OptionsString)
+static int __init blogic_parseopts(char *options)
 {
 	while (true) {
-		struct BusLogic_DriverOptions *DriverOptions = &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
-		int TargetID;
-		memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions));
-		while (*OptionsString != '\0' && *OptionsString != ';') {
+		struct blogic_drvr_options *drvr_opts =
+			&blogic_drvr_options[blogic_drvr_options_count++];
+		int tgt_id;
+
+		memset(drvr_opts, 0, sizeof(struct blogic_drvr_options));
+		while (*options != '\0' && *options != ';') {
 			/* Probing Options. */
-			if (BusLogic_ParseKeyword(&OptionsString, "IO:")) {
-				unsigned long IO_Address = simple_strtoul(OptionsString, &OptionsString, 0);
-				BusLogic_ProbeOptions.LimitedProbeISA = true;
-				switch (IO_Address) {
+			if (blogic_parse(&options, "IO:")) {
+				unsigned long io_addr = simple_strtoul(options,
+								&options, 0);
+				blogic_probe_options.limited_isa = true;
+				switch (io_addr) {
 				case 0x330:
-					BusLogic_ProbeOptions.Probe330 = true;
+					blogic_probe_options.probe330 = true;
 					break;
 				case 0x334:
-					BusLogic_ProbeOptions.Probe334 = true;
+					blogic_probe_options.probe334 = true;
 					break;
 				case 0x230:
-					BusLogic_ProbeOptions.Probe230 = true;
+					blogic_probe_options.probe230 = true;
 					break;
 				case 0x234:
-					BusLogic_ProbeOptions.Probe234 = true;
+					blogic_probe_options.probe234 = true;
 					break;
 				case 0x130:
-					BusLogic_ProbeOptions.Probe130 = true;
+					blogic_probe_options.probe130 = true;
 					break;
 				case 0x134:
-					BusLogic_ProbeOptions.Probe134 = true;
+					blogic_probe_options.probe134 = true;
 					break;
 				default:
-					BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, IO_Address);
+					blogic_err("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, io_addr);
 					return 0;
 				}
-			} else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
-				BusLogic_ProbeOptions.NoProbeISA = true;
-			else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
-				BusLogic_ProbeOptions.NoProbePCI = true;
-			else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
-				BusLogic_ProbeOptions.NoProbe = true;
-			else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
-				BusLogic_ProbeOptions.NoSortPCI = true;
-			else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
-				BusLogic_ProbeOptions.MultiMasterFirst = true;
-			else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
-				BusLogic_ProbeOptions.FlashPointFirst = true;
+			} else if (blogic_parse(&options, "NoProbeISA"))
+				blogic_probe_options.noprobe_isa = true;
+			else if (blogic_parse(&options, "NoProbePCI"))
+				blogic_probe_options.noprobe_pci = true;
+			else if (blogic_parse(&options, "NoProbe"))
+				blogic_probe_options.noprobe = true;
+			else if (blogic_parse(&options, "NoSortPCI"))
+				blogic_probe_options.nosort_pci = true;
+			else if (blogic_parse(&options, "MultiMasterFirst"))
+				blogic_probe_options.multimaster_first = true;
+			else if (blogic_parse(&options, "FlashPointFirst"))
+				blogic_probe_options.flashpoint_first = true;
 			/* Tagged Queuing Options. */
-			else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") || BusLogic_ParseKeyword(&OptionsString, "QD:[")) {
-				for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) {
-					unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
-					if (QueueDepth > BusLogic_MaxTaggedQueueDepth) {
-						BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
+			else if (blogic_parse(&options, "QueueDepth:[") ||
+					blogic_parse(&options, "QD:[")) {
+				for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
+					unsigned short qdepth = simple_strtoul(options, &options, 0);
+					if (qdepth > BLOGIC_MAX_TAG_DEPTH) {
+						blogic_err("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, qdepth);
 						return 0;
 					}
-					DriverOptions->QueueDepth[TargetID] = QueueDepth;
-					if (*OptionsString == ',')
-						OptionsString++;
-					else if (*OptionsString == ']')
+					drvr_opts->qdepth[tgt_id] = qdepth;
+					if (*options == ',')
+						options++;
+					else if (*options == ']')
 						break;
 					else {
-						BusLogic_Error("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, OptionsString);
+						blogic_err("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, options);
 						return 0;
 					}
 				}
-				if (*OptionsString != ']') {
-					BusLogic_Error("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, OptionsString);
+				if (*options != ']') {
+					blogic_err("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, options);
 					return 0;
 				} else
-					OptionsString++;
-			} else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") || BusLogic_ParseKeyword(&OptionsString, "QD:")) {
-				unsigned short QueueDepth = simple_strtoul(OptionsString, &OptionsString, 0);
-				if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth) {
-					BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, QueueDepth);
+					options++;
+			} else if (blogic_parse(&options, "QueueDepth:") || blogic_parse(&options, "QD:")) {
+				unsigned short qdepth = simple_strtoul(options, &options, 0);
+				if (qdepth == 0 ||
+						qdepth > BLOGIC_MAX_TAG_DEPTH) {
+					blogic_err("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, qdepth);
 					return 0;
 				}
-				DriverOptions->CommonQueueDepth = QueueDepth;
-				for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
-					DriverOptions->QueueDepth[TargetID] = QueueDepth;
-			} else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") || BusLogic_ParseKeyword(&OptionsString, "TQ:")) {
-				if (BusLogic_ParseKeyword(&OptionsString, "Default")) {
-					DriverOptions->TaggedQueuingPermitted = 0x0000;
-					DriverOptions->TaggedQueuingPermittedMask = 0x0000;
-				} else if (BusLogic_ParseKeyword(&OptionsString, "Enable")) {
-					DriverOptions->TaggedQueuingPermitted = 0xFFFF;
-					DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
-				} else if (BusLogic_ParseKeyword(&OptionsString, "Disable")) {
-					DriverOptions->TaggedQueuingPermitted = 0x0000;
-					DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
+				drvr_opts->common_qdepth = qdepth;
+				for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
+					drvr_opts->qdepth[tgt_id] = qdepth;
+			} else if (blogic_parse(&options, "TaggedQueuing:") ||
+					blogic_parse(&options, "TQ:")) {
+				if (blogic_parse(&options, "Default")) {
+					drvr_opts->tagq_ok = 0x0000;
+					drvr_opts->tagq_ok_mask = 0x0000;
+				} else if (blogic_parse(&options, "Enable")) {
+					drvr_opts->tagq_ok = 0xFFFF;
+					drvr_opts->tagq_ok_mask = 0xFFFF;
+				} else if (blogic_parse(&options, "Disable")) {
+					drvr_opts->tagq_ok = 0x0000;
+					drvr_opts->tagq_ok_mask = 0xFFFF;
 				} else {
-					unsigned short TargetBit;
-					for (TargetID = 0, TargetBit = 1; TargetID < BusLogic_MaxTargetDevices; TargetID++, TargetBit <<= 1)
-						switch (*OptionsString++) {
+					unsigned short tgt_bit;
+					for (tgt_id = 0, tgt_bit = 1;
+						tgt_id < BLOGIC_MAXDEV;
+						tgt_id++, tgt_bit <<= 1)
+						switch (*options++) {
 						case 'Y':
-							DriverOptions->TaggedQueuingPermitted |= TargetBit;
-							DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
+							drvr_opts->tagq_ok |= tgt_bit;
+							drvr_opts->tagq_ok_mask |= tgt_bit;
 							break;
 						case 'N':
-							DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
-							DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
+							drvr_opts->tagq_ok &= ~tgt_bit;
+							drvr_opts->tagq_ok_mask |= tgt_bit;
 							break;
 						case 'X':
 							break;
 						default:
-							OptionsString--;
-							TargetID = BusLogic_MaxTargetDevices;
+							options--;
+							tgt_id = BLOGIC_MAXDEV;
 							break;
 						}
 				}
 			}
 			/* Miscellaneous Options. */
-			else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") || BusLogic_ParseKeyword(&OptionsString, "BST:")) {
-				unsigned short BusSettleTime = simple_strtoul(OptionsString, &OptionsString, 0);
-				if (BusSettleTime > 5 * 60) {
-					BusLogic_Error("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, BusSettleTime);
+			else if (blogic_parse(&options, "BusSettleTime:") ||
+					blogic_parse(&options, "BST:")) {
+				unsigned short bus_settle_time =
+					simple_strtoul(options, &options, 0);
+				if (bus_settle_time > 5 * 60) {
+					blogic_err("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, bus_settle_time);
 					return 0;
 				}
-				DriverOptions->BusSettleTime = BusSettleTime;
-			} else if (BusLogic_ParseKeyword(&OptionsString, "InhibitTargetInquiry"))
-				DriverOptions->LocalOptions.InhibitTargetInquiry = true;
+				drvr_opts->bus_settle_time = bus_settle_time;
+			} else if (blogic_parse(&options,
+						"InhibitTargetInquiry"))
+				drvr_opts->stop_tgt_inquiry = true;
 			/* Debugging Options. */
-			else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
-				BusLogic_GlobalOptions.TraceProbe = true;
-			else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
-				BusLogic_GlobalOptions.TraceHardwareReset = true;
-			else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
-				BusLogic_GlobalOptions.TraceConfiguration = true;
-			else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
-				BusLogic_GlobalOptions.TraceErrors = true;
-			else if (BusLogic_ParseKeyword(&OptionsString, "Debug")) {
-				BusLogic_GlobalOptions.TraceProbe = true;
-				BusLogic_GlobalOptions.TraceHardwareReset = true;
-				BusLogic_GlobalOptions.TraceConfiguration = true;
-				BusLogic_GlobalOptions.TraceErrors = true;
+			else if (blogic_parse(&options, "TraceProbe"))
+				blogic_global_options.trace_probe = true;
+			else if (blogic_parse(&options, "TraceHardwareReset"))
+				blogic_global_options.trace_hw_reset = true;
+			else if (blogic_parse(&options, "TraceConfiguration"))
+				blogic_global_options.trace_config = true;
+			else if (blogic_parse(&options, "TraceErrors"))
+				blogic_global_options.trace_err = true;
+			else if (blogic_parse(&options, "Debug")) {
+				blogic_global_options.trace_probe = true;
+				blogic_global_options.trace_hw_reset = true;
+				blogic_global_options.trace_config = true;
+				blogic_global_options.trace_err = true;
 			}
-			if (*OptionsString == ',')
-				OptionsString++;
-			else if (*OptionsString != ';' && *OptionsString != '\0') {
-				BusLogic_Error("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, OptionsString);
-				*OptionsString = '\0';
+			if (*options == ',')
+				options++;
+			else if (*options != ';' && *options != '\0') {
+				blogic_err("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, options);
+				*options = '\0';
 			}
 		}
-		if (!(BusLogic_DriverOptionsCount == 0 || BusLogic_ProbeInfoCount == 0 || BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount)) {
-			BusLogic_Error("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL);
+		if (!(blogic_drvr_options_count == 0 ||
+			blogic_probeinfo_count == 0 ||
+			blogic_drvr_options_count == blogic_probeinfo_count)) {
+			blogic_err("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL);
 			return 0;
 		}
 		/*
 		   Tagged Queuing is disabled when the Queue Depth is 1 since queuing
 		   multiple commands is not possible.
 		 */
-		for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
-			if (DriverOptions->QueueDepth[TargetID] == 1) {
-				unsigned short TargetBit = 1 << TargetID;
-				DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
-				DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
+		for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
+			if (drvr_opts->qdepth[tgt_id] == 1) {
+				unsigned short tgt_bit = 1 << tgt_id;
+				drvr_opts->tagq_ok &= ~tgt_bit;
+				drvr_opts->tagq_ok_mask |= tgt_bit;
 			}
-		if (*OptionsString == ';')
-			OptionsString++;
-		if (*OptionsString == '\0')
+		if (*options == ';')
+			options++;
+		if (*options == '\0')
 			return 0;
 	}
 	return 1;
@@ -3555,19 +3821,19 @@ static int __init BusLogic_ParseDriverOp
   Get it all started
 */
 
-static struct scsi_host_template Bus_Logic_template = {
+static struct scsi_host_template blogic_template = {
 	.module = THIS_MODULE,
 	.proc_name = "BusLogic",
-	.write_info = BusLogic_write_info,
-	.show_info = BusLogic_show_info,
+	.write_info = blogic_write_info,
+	.show_info = blogic_show_info,
 	.name = "BusLogic",
-	.info = BusLogic_DriverInfo,
-	.queuecommand = BusLogic_QueueCommand,
-	.slave_configure = BusLogic_SlaveConfigure,
-	.bios_param = BusLogic_BIOSDiskParameters,
-	.eh_host_reset_handler = BusLogic_host_reset,
+	.info = blogic_drvr_info,
+	.queuecommand = blogic_qcmd,
+	.slave_configure = blogic_slaveconfig,
+	.bios_param = blogic_diskparam,
+	.eh_host_reset_handler = blogic_hostreset,
 #if 0
-	.eh_abort_handler = BusLogic_AbortCommand,
+	.eh_abort_handler = blogic_abort,
 #endif
 	.unchecked_isa_dma = 1,
 	.max_sectors = 128,
@@ -3575,40 +3841,40 @@ static struct scsi_host_template Bus_Log
 };
 
 /*
-  BusLogic_Setup handles processing of Kernel Command Line Arguments.
+  blogic_setup handles processing of Kernel Command Line Arguments.
 */
 
-static int __init BusLogic_Setup(char *str)
+static int __init blogic_setup(char *str)
 {
 	int ints[3];
 
 	(void) get_options(str, ARRAY_SIZE(ints), ints);
 
 	if (ints[0] != 0) {
-		BusLogic_Error("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL);
+		blogic_err("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL);
 		return 0;
 	}
 	if (str == NULL || *str == '\0')
 		return 0;
-	return BusLogic_ParseDriverOptions(str);
+	return blogic_parseopts(str);
 }
 
 /*
  * Exit function.  Deletes all hosts associated with this driver.
  */
 
-static void __exit BusLogic_exit(void)
+static void __exit blogic_exit(void)
 {
-	struct BusLogic_HostAdapter *ha, *next;
+	struct blogic_adapter *ha, *next;
 
-	list_for_each_entry_safe(ha, next, &BusLogic_host_list, host_list)
-		BusLogic_ReleaseHostAdapter(ha);
+	list_for_each_entry_safe(ha, next, &blogic_host_list, host_list)
+		blogic_deladapter(ha);
 }
 
-__setup("BusLogic=", BusLogic_Setup);
+__setup("BusLogic=", blogic_setup);
 
 #ifdef MODULE
-static struct pci_device_id BusLogic_pci_tbl[] = {
+/*static struct pci_device_id blogic_pci_tbl[] = {
 	{ PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
@@ -3616,9 +3882,15 @@ static struct pci_device_id BusLogic_pci
 	{ PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ }
+};*/
+static DEFINE_PCI_DEVICE_TABLE(blogic_pci_tbl) = {
+	{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)},
+	{0, },
 };
 #endif
-MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl);
+MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
 
-module_init(BusLogic_init);
-module_exit(BusLogic_exit);
+module_init(blogic_init);
+module_exit(blogic_exit);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/BusLogic.h linux-libre-3.11-rc7-gnu/drivers/scsi/BusLogic.h
--- linux-libre-3.10-gnu/drivers/scsi/BusLogic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/BusLogic.h	2013-08-25 20:43:22.000000000 -0400
@@ -37,14 +37,14 @@
   Define the maximum number of BusLogic Host Adapters supported by this driver.
 */
 
-#define BusLogic_MaxHostAdapters		16
+#define BLOGIC_MAX_ADAPTERS		16
 
 
 /*
   Define the maximum number of Target Devices supported by this driver.
 */
 
-#define BusLogic_MaxTargetDevices		16
+#define BLOGIC_MAXDEV			16
 
 
 /*
@@ -53,7 +53,7 @@
   large as the largest single request generated by the I/O Subsystem.
 */
 
-#define BusLogic_ScatterGatherLimit		128
+#define BLOGIC_SG_LIMIT		128
 
 
 /*
@@ -62,12 +62,12 @@
   Tagged Queuing and whether or not ISA Bounce Buffers are required.
 */
 
-#define BusLogic_MaxTaggedQueueDepth		64
-#define BusLogic_MaxAutomaticTaggedQueueDepth	28
-#define BusLogic_MinAutomaticTaggedQueueDepth	7
-#define BusLogic_TaggedQueueDepthBB		3
-#define BusLogic_UntaggedQueueDepth		3
-#define BusLogic_UntaggedQueueDepthBB		2
+#define BLOGIC_MAX_TAG_DEPTH		64
+#define BLOGIC_MAX_AUTO_TAG_DEPTH	28
+#define BLOGIC_MIN_AUTO_TAG_DEPTH	7
+#define BLOGIC_TAG_DEPTH_BB		3
+#define BLOGIC_UNTAG_DEPTH		3
+#define BLOGIC_UNTAG_DEPTH_BB		2
 
 
 /*
@@ -77,7 +77,7 @@
   a SCSI Bus Reset.
 */
 
-#define BusLogic_DefaultBusSettleTime		2
+#define BLOGIC_BUS_SETTLE_TIME		2
 
 
 /*
@@ -87,7 +87,7 @@
   does not cross an allocation block size boundary.
 */
 
-#define BusLogic_MaxMailboxes			211
+#define BLOGIC_MAX_MAILBOX		211
 
 
 /*
@@ -95,50 +95,50 @@
   Kernel memory allocation.
 */
 
-#define BusLogic_CCB_AllocationGroupSize	7
+#define BLOGIC_CCB_GRP_ALLOCSIZE	7
 
 
 /*
   Define the Host Adapter Line and Message Buffer Sizes.
 */
 
-#define BusLogic_LineBufferSize			100
-#define BusLogic_MessageBufferSize		9700
+#define BLOGIC_LINEBUF_SIZE		100
+#define BLOGIC_MSGBUF_SIZE		9700
 
 
 /*
   Define the Driver Message Levels.
 */
 
-enum BusLogic_MessageLevel {
-	BusLogic_AnnounceLevel = 0,
-	BusLogic_InfoLevel = 1,
-	BusLogic_NoticeLevel = 2,
-	BusLogic_WarningLevel = 3,
-	BusLogic_ErrorLevel = 4
+enum blogic_msglevel {
+	BLOGIC_ANNOUNCE_LEVEL = 0,
+	BLOGIC_INFO_LEVEL = 1,
+	BLOGIC_NOTICE_LEVEL = 2,
+	BLOGIC_WARN_LEVEL = 3,
+	BLOGIC_ERR_LEVEL = 4
 };
 
-static char *BusLogic_MessageLevelMap[] = { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING, KERN_ERR };
+static char *blogic_msglevelmap[] = { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING, KERN_ERR };
 
 
 /*
   Define Driver Message macros.
 */
 
-#define BusLogic_Announce(Format, Arguments...) \
-  BusLogic_Message(BusLogic_AnnounceLevel, Format, ##Arguments)
+#define blogic_announce(format, args...) \
+	blogic_msg(BLOGIC_ANNOUNCE_LEVEL, format, ##args)
 
-#define BusLogic_Info(Format, Arguments...) \
-  BusLogic_Message(BusLogic_InfoLevel, Format, ##Arguments)
+#define blogic_info(format, args...) \
+	blogic_msg(BLOGIC_INFO_LEVEL, format, ##args)
 
-#define BusLogic_Notice(Format, Arguments...) \
-  BusLogic_Message(BusLogic_NoticeLevel, Format, ##Arguments)
+#define blogic_notice(format, args...) \
+	blogic_msg(BLOGIC_NOTICE_LEVEL, format, ##args)
 
-#define BusLogic_Warning(Format, Arguments...) \
-  BusLogic_Message(BusLogic_WarningLevel, Format, ##Arguments)
+#define blogic_warn(format, args...) \
+	blogic_msg(BLOGIC_WARN_LEVEL, format, ##args)
 
-#define BusLogic_Error(Format, Arguments...) \
-  BusLogic_Message(BusLogic_ErrorLevel, Format, ##Arguments)
+#define blogic_err(format, args...) \
+	blogic_msg(BLOGIC_ERR_LEVEL, format, ##args)
 
 
 /*
@@ -146,15 +146,15 @@ static char *BusLogic_MessageLevelMap[]
   of I/O Addresses required by each type.
 */
 
-enum BusLogic_HostAdapterType {
-	BusLogic_MultiMaster = 1,
-	BusLogic_FlashPoint = 2
+enum blogic_adapter_type {
+	BLOGIC_MULTIMASTER = 1,
+	BLOGIC_FLASHPOINT = 2
 } PACKED;
 
-#define BusLogic_MultiMasterAddressCount	4
-#define BusLogic_FlashPointAddressCount		256
+#define BLOGIC_MULTIMASTER_ADDR_COUNT	4
+#define BLOGIC_FLASHPOINT_ADDR_COUNT	256
 
-static int BusLogic_HostAdapterAddressCount[3] = { 0, BusLogic_MultiMasterAddressCount, BusLogic_FlashPointAddressCount };
+static int blogic_adapter_addr_count[3] = { 0, BLOGIC_MULTIMASTER_ADDR_COUNT, BLOGIC_FLASHPOINT_ADDR_COUNT };
 
 
 /*
@@ -163,19 +163,16 @@ static int BusLogic_HostAdapterAddressCo
 
 #ifdef CONFIG_SCSI_FLASHPOINT
 
-#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \
-  (HostAdapter->HostAdapterType == BusLogic_MultiMaster)
+#define blogic_multimaster_type(adapter) \
+	(adapter->adapter_type == BLOGIC_MULTIMASTER)
 
-#define BusLogic_FlashPointHostAdapterP(HostAdapter) \
-  (HostAdapter->HostAdapterType == BusLogic_FlashPoint)
+#define blogic_flashpoint_type(adapter) \
+	(adapter->adapter_type == BLOGIC_FLASHPOINT)
 
 #else
 
-#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \
-  (true)
-
-#define BusLogic_FlashPointHostAdapterP(HostAdapter) \
-  (false)
+#define blogic_multimaster_type(adapter)	(true)
+#define blogic_flashpoint_type(adapter)		(false)
 
 #endif
 
@@ -184,35 +181,35 @@ static int BusLogic_HostAdapterAddressCo
   Define the possible Host Adapter Bus Types.
 */
 
-enum BusLogic_HostAdapterBusType {
-	BusLogic_Unknown_Bus = 0,
-	BusLogic_ISA_Bus = 1,
-	BusLogic_EISA_Bus = 2,
-	BusLogic_PCI_Bus = 3,
-	BusLogic_VESA_Bus = 4,
-	BusLogic_MCA_Bus = 5
+enum blogic_adapter_bus_type {
+	BLOGIC_UNKNOWN_BUS = 0,
+	BLOGIC_ISA_BUS = 1,
+	BLOGIC_EISA_BUS = 2,
+	BLOGIC_PCI_BUS = 3,
+	BLOGIC_VESA_BUS = 4,
+	BLOGIC_MCA_BUS = 5
 } PACKED;
 
-static char *BusLogic_HostAdapterBusNames[] = { "Unknown", "ISA", "EISA", "PCI", "VESA", "MCA" };
+static char *blogic_adapter_busnames[] = { "Unknown", "ISA", "EISA", "PCI", "VESA", "MCA" };
 
-static enum BusLogic_HostAdapterBusType BusLogic_HostAdapterBusTypes[] = {
-	BusLogic_VESA_Bus,	/* BT-4xx */
-	BusLogic_ISA_Bus,	/* BT-5xx */
-	BusLogic_MCA_Bus,	/* BT-6xx */
-	BusLogic_EISA_Bus,	/* BT-7xx */
-	BusLogic_Unknown_Bus,	/* BT-8xx */
-	BusLogic_PCI_Bus	/* BT-9xx */
+static enum blogic_adapter_bus_type blogic_adater_bus_types[] = {
+	BLOGIC_VESA_BUS,	/* BT-4xx */
+	BLOGIC_ISA_BUS,		/* BT-5xx */
+	BLOGIC_MCA_BUS,		/* BT-6xx */
+	BLOGIC_EISA_BUS,	/* BT-7xx */
+	BLOGIC_UNKNOWN_BUS,	/* BT-8xx */
+	BLOGIC_PCI_BUS		/* BT-9xx */
 };
 
 /*
   Define the possible Host Adapter BIOS Disk Geometry Translations.
 */
 
-enum BusLogic_BIOS_DiskGeometryTranslation {
-	BusLogic_BIOS_Disk_Not_Installed = 0,
-	BusLogic_BIOS_Disk_Installed_64x32 = 1,
-	BusLogic_BIOS_Disk_Installed_128x32 = 2,
-	BusLogic_BIOS_Disk_Installed_255x63 = 3
+enum blogic_bios_diskgeometry {
+	BLOGIC_BIOS_NODISK = 0,
+	BLOGIC_BIOS_DISK64x32 = 1,
+	BLOGIC_BIOS_DISK128x32 = 2,
+	BLOGIC_BIOS_DISK255x63 = 3
 } PACKED;
 
 
@@ -220,9 +217,9 @@ enum BusLogic_BIOS_DiskGeometryTranslati
   Define a 10^18 Statistics Byte Counter data type.
 */
 
-struct BusLogic_ByteCounter {
-	unsigned int Units;
-	unsigned int Billions;
+struct blogic_byte_count {
+	unsigned int units;
+	unsigned int billions;
 };
 
 
@@ -230,79 +227,71 @@ struct BusLogic_ByteCounter {
   Define the structure for I/O Address and Bus Probing Information.
 */
 
-struct BusLogic_ProbeInfo {
-	enum BusLogic_HostAdapterType HostAdapterType;
-	enum BusLogic_HostAdapterBusType HostAdapterBusType;
-	unsigned long IO_Address;
-	unsigned long PCI_Address;
-	struct pci_dev *PCI_Device;
-	unsigned char Bus;
-	unsigned char Device;
-	unsigned char IRQ_Channel;
+struct blogic_probeinfo {
+	enum blogic_adapter_type adapter_type;
+	enum blogic_adapter_bus_type adapter_bus_type;
+	unsigned long io_addr;
+	unsigned long pci_addr;
+	struct pci_dev *pci_device;
+	unsigned char bus;
+	unsigned char dev;
+	unsigned char irq_ch;
 };
 
 /*
   Define the Probe Options.
 */
 
-struct BusLogic_ProbeOptions {
-	bool NoProbe:1;		/* Bit 0 */
-	bool NoProbeISA:1;	/* Bit 1 */
-	bool NoProbePCI:1;	/* Bit 2 */
-	bool NoSortPCI:1;	/* Bit 3 */
-	bool MultiMasterFirst:1;/* Bit 4 */
-	bool FlashPointFirst:1;	/* Bit 5 */
-	bool LimitedProbeISA:1;	/* Bit 6 */
-	bool Probe330:1;	/* Bit 7 */
-	bool Probe334:1;	/* Bit 8 */
-	bool Probe230:1;	/* Bit 9 */
-	bool Probe234:1;	/* Bit 10 */
-	bool Probe130:1;	/* Bit 11 */
-	bool Probe134:1;	/* Bit 12 */
+struct blogic_probe_options {
+	bool noprobe:1;			/* Bit 0 */
+	bool noprobe_isa:1;		/* Bit 1 */
+	bool noprobe_pci:1;		/* Bit 2 */
+	bool nosort_pci:1;		/* Bit 3 */
+	bool multimaster_first:1;	/* Bit 4 */
+	bool flashpoint_first:1;	/* Bit 5 */
+	bool limited_isa:1;		/* Bit 6 */
+	bool probe330:1;		/* Bit 7 */
+	bool probe334:1;		/* Bit 8 */
+	bool probe230:1;		/* Bit 9 */
+	bool probe234:1;		/* Bit 10 */
+	bool probe130:1;		/* Bit 11 */
+	bool probe134:1;		/* Bit 12 */
 };
 
 /*
   Define the Global Options.
 */
 
-struct BusLogic_GlobalOptions {
-	bool TraceProbe:1;	/* Bit 0 */
-	bool TraceHardwareReset:1;	/* Bit 1 */
-	bool TraceConfiguration:1;	/* Bit 2 */
-	bool TraceErrors:1;	/* Bit 3 */
-};
-
-/*
-  Define the Local Options.
-*/
-
-struct BusLogic_LocalOptions {
-	bool InhibitTargetInquiry:1;	/* Bit 0 */
+struct blogic_global_options {
+	bool trace_probe:1;	/* Bit 0 */
+	bool trace_hw_reset:1;	/* Bit 1 */
+	bool trace_config:1;	/* Bit 2 */
+	bool trace_err:1;	/* Bit 3 */
 };
 
 /*
   Define the BusLogic SCSI Host Adapter I/O Register Offsets.
 */
 
-#define BusLogic_ControlRegisterOffset		0	/* WO register */
-#define BusLogic_StatusRegisterOffset		0	/* RO register */
-#define BusLogic_CommandParameterRegisterOffset	1	/* WO register */
-#define BusLogic_DataInRegisterOffset		1	/* RO register */
-#define BusLogic_InterruptRegisterOffset	2	/* RO register */
-#define BusLogic_GeometryRegisterOffset		3	/* RO register */
+#define BLOGIC_CNTRL_REG	0	/* WO register */
+#define BLOGIC_STATUS_REG	0	/* RO register */
+#define BLOGIC_CMD_PARM_REG	1	/* WO register */
+#define BLOGIC_DATAIN_REG	1	/* RO register */
+#define BLOGIC_INT_REG		2	/* RO register */
+#define BLOGIC_GEOMETRY_REG	3	/* RO register */
 
 /*
   Define the structure of the write-only Control Register.
 */
 
-union BusLogic_ControlRegister {
-	unsigned char All;
+union blogic_cntrl_reg {
+	unsigned char all;
 	struct {
 		unsigned char:4;	/* Bits 0-3 */
-		bool SCSIBusReset:1;	/* Bit 4 */
-		bool InterruptReset:1;	/* Bit 5 */
-		bool SoftReset:1;	/* Bit 6 */
-		bool HardReset:1;	/* Bit 7 */
+		bool bus_reset:1;	/* Bit 4 */
+		bool int_reset:1;	/* Bit 5 */
+		bool soft_reset:1;	/* Bit 6 */
+		bool hard_reset:1;	/* Bit 7 */
 	} cr;
 };
 
@@ -310,17 +299,17 @@ union BusLogic_ControlRegister {
   Define the structure of the read-only Status Register.
 */
 
-union BusLogic_StatusRegister {
-	unsigned char All;
+union blogic_stat_reg {
+	unsigned char all;
 	struct {
-		bool CommandInvalid:1;		/* Bit 0 */
-		bool Reserved:1;		/* Bit 1 */
-		bool DataInRegisterReady:1;	/* Bit 2 */
-		bool CommandParameterRegisterBusy:1;	/* Bit 3 */
-		bool HostAdapterReady:1;	/* Bit 4 */
-		bool InitializationRequired:1;	/* Bit 5 */
-		bool DiagnosticFailure:1;	/* Bit 6 */
-		bool DiagnosticActive:1;	/* Bit 7 */
+		bool cmd_invalid:1;	/* Bit 0 */
+		bool rsvd:1;		/* Bit 1 */
+		bool datain_ready:1;	/* Bit 2 */
+		bool cmd_param_busy:1;	/* Bit 3 */
+		bool adapter_ready:1;	/* Bit 4 */
+		bool init_reqd:1;	/* Bit 5 */
+		bool diag_failed:1;	/* Bit 6 */
+		bool diag_active:1;	/* Bit 7 */
 	} sr;
 };
 
@@ -328,15 +317,15 @@ union BusLogic_StatusRegister {
   Define the structure of the read-only Interrupt Register.
 */
 
-union BusLogic_InterruptRegister {
-	unsigned char All;
+union blogic_int_reg {
+	unsigned char all;
 	struct {
-		bool IncomingMailboxLoaded:1;	/* Bit 0 */
-		bool OutgoingMailboxAvailable:1;/* Bit 1 */
-		bool CommandComplete:1;		/* Bit 2 */
-		bool ExternalBusReset:1;	/* Bit 3 */
-		unsigned char Reserved:3;	/* Bits 4-6 */
-		bool InterruptValid:1;		/* Bit 7 */
+		bool mailin_loaded:1;	/* Bit 0 */
+		bool mailout_avail:1;	/* Bit 1 */
+		bool cmd_complete:1;	/* Bit 2 */
+		bool ext_busreset:1;	/* Bit 3 */
+		unsigned char rsvd:3;	/* Bits 4-6 */
+		bool int_valid:1;	/* Bit 7 */
 	} ir;
 };
 
@@ -344,13 +333,13 @@ union BusLogic_InterruptRegister {
   Define the structure of the read-only Geometry Register.
 */
 
-union BusLogic_GeometryRegister {
-	unsigned char All;
+union blogic_geo_reg {
+	unsigned char all;
 	struct {
-		enum BusLogic_BIOS_DiskGeometryTranslation Drive0Geometry:2;	/* Bits 0-1 */
-		enum BusLogic_BIOS_DiskGeometryTranslation Drive1Geometry:2;	/* Bits 2-3 */
+		enum blogic_bios_diskgeometry d0_geo:2;	/* Bits 0-1 */
+		enum blogic_bios_diskgeometry d1_geo:2;	/* Bits 2-3 */
 		unsigned char:3;	/* Bits 4-6 */
-		bool ExtendedTranslationEnabled:1;	/* Bit 7 */
+		bool ext_trans_enable:1;	/* Bit 7 */
 	} gr;
 };
 
@@ -358,82 +347,82 @@ union BusLogic_GeometryRegister {
   Define the BusLogic SCSI Host Adapter Command Register Operation Codes.
 */
 
-enum BusLogic_OperationCode {
-	BusLogic_TestCommandCompleteInterrupt = 0x00,
-	BusLogic_InitializeMailbox = 0x01,
-	BusLogic_ExecuteMailboxCommand = 0x02,
-	BusLogic_ExecuteBIOSCommand = 0x03,
-	BusLogic_InquireBoardID = 0x04,
-	BusLogic_EnableOutgoingMailboxAvailableInt = 0x05,
-	BusLogic_SetSCSISelectionTimeout = 0x06,
-	BusLogic_SetPreemptTimeOnBus = 0x07,
-	BusLogic_SetTimeOffBus = 0x08,
-	BusLogic_SetBusTransferRate = 0x09,
-	BusLogic_InquireInstalledDevicesID0to7 = 0x0A,
-	BusLogic_InquireConfiguration = 0x0B,
-	BusLogic_EnableTargetMode = 0x0C,
-	BusLogic_InquireSetupInformation = 0x0D,
-	BusLogic_WriteAdapterLocalRAM = 0x1A,
-	BusLogic_ReadAdapterLocalRAM = 0x1B,
-	BusLogic_WriteBusMasterChipFIFO = 0x1C,
-	BusLogic_ReadBusMasterChipFIFO = 0x1D,
-	BusLogic_EchoCommandData = 0x1F,
-	BusLogic_HostAdapterDiagnostic = 0x20,
-	BusLogic_SetAdapterOptions = 0x21,
-	BusLogic_InquireInstalledDevicesID8to15 = 0x23,
-	BusLogic_InquireTargetDevices = 0x24,
-	BusLogic_DisableHostAdapterInterrupt = 0x25,
-	BusLogic_InitializeExtendedMailbox = 0x81,
-	BusLogic_ExecuteSCSICommand = 0x83,
-	BusLogic_InquireFirmwareVersion3rdDigit = 0x84,
-	BusLogic_InquireFirmwareVersionLetter = 0x85,
-	BusLogic_InquirePCIHostAdapterInformation = 0x86,
-	BusLogic_InquireHostAdapterModelNumber = 0x8B,
-	BusLogic_InquireSynchronousPeriod = 0x8C,
-	BusLogic_InquireExtendedSetupInformation = 0x8D,
-	BusLogic_EnableStrictRoundRobinMode = 0x8F,
-	BusLogic_StoreHostAdapterLocalRAM = 0x90,
-	BusLogic_FetchHostAdapterLocalRAM = 0x91,
-	BusLogic_StoreLocalDataInEEPROM = 0x92,
-	BusLogic_UploadAutoSCSICode = 0x94,
-	BusLogic_ModifyIOAddress = 0x95,
-	BusLogic_SetCCBFormat = 0x96,
-	BusLogic_WriteInquiryBuffer = 0x9A,
-	BusLogic_ReadInquiryBuffer = 0x9B,
-	BusLogic_FlashROMUploadDownload = 0xA7,
-	BusLogic_ReadSCAMData = 0xA8,
-	BusLogic_WriteSCAMData = 0xA9
+enum blogic_opcode {
+	BLOGIC_TEST_CMP_COMPLETE = 0x00,
+	BLOGIC_INIT_MBOX = 0x01,
+	BLOGIC_EXEC_MBOX_CMD = 0x02,
+	BLOGIC_EXEC_BIOS_CMD = 0x03,
+	BLOGIC_GET_BOARD_ID = 0x04,
+	BLOGIC_ENABLE_OUTBOX_AVAIL_INT = 0x05,
+	BLOGIC_SET_SELECT_TIMEOUT = 0x06,
+	BLOGIC_SET_PREEMPT_TIME = 0x07,
+	BLOGIC_SET_TIMEOFF_BUS = 0x08,
+	BLOGIC_SET_TXRATE = 0x09,
+	BLOGIC_INQ_DEV0TO7 = 0x0A,
+	BLOGIC_INQ_CONFIG = 0x0B,
+	BLOGIC_TGT_MODE = 0x0C,
+	BLOGIC_INQ_SETUPINFO = 0x0D,
+	BLOGIC_WRITE_LOCALRAM = 0x1A,
+	BLOGIC_READ_LOCALRAM = 0x1B,
+	BLOGIC_WRITE_BUSMASTER_FIFO = 0x1C,
+	BLOGIC_READ_BUSMASTER_FIFO = 0x1D,
+	BLOGIC_ECHO_CMDDATA = 0x1F,
+	BLOGIC_ADAPTER_DIAG = 0x20,
+	BLOGIC_SET_OPTIONS = 0x21,
+	BLOGIC_INQ_DEV8TO15 = 0x23,
+	BLOGIC_INQ_DEV = 0x24,
+	BLOGIC_DISABLE_INT = 0x25,
+	BLOGIC_INIT_EXT_MBOX = 0x81,
+	BLOGIC_EXEC_SCS_CMD = 0x83,
+	BLOGIC_INQ_FWVER_D3 = 0x84,
+	BLOGIC_INQ_FWVER_LETTER = 0x85,
+	BLOGIC_INQ_PCI_INFO = 0x86,
+	BLOGIC_INQ_MODELNO = 0x8B,
+	BLOGIC_INQ_SYNC_PERIOD = 0x8C,
+	BLOGIC_INQ_EXTSETUP = 0x8D,
+	BLOGIC_STRICT_RR = 0x8F,
+	BLOGIC_STORE_LOCALRAM = 0x90,
+	BLOGIC_FETCH_LOCALRAM = 0x91,
+	BLOGIC_STORE_TO_EEPROM = 0x92,
+	BLOGIC_LOAD_AUTOSCSICODE = 0x94,
+	BLOGIC_MOD_IOADDR = 0x95,
+	BLOGIC_SETCCB_FMT = 0x96,
+	BLOGIC_WRITE_INQBUF = 0x9A,
+	BLOGIC_READ_INQBUF = 0x9B,
+	BLOGIC_FLASH_LOAD = 0xA7,
+	BLOGIC_READ_SCAMDATA = 0xA8,
+	BLOGIC_WRITE_SCAMDATA = 0xA9
 };
 
 /*
   Define the Inquire Board ID reply structure.
 */
 
-struct BusLogic_BoardID {
-	unsigned char BoardType;	/* Byte 0 */
-	unsigned char CustomFeatures;	/* Byte 1 */
-	unsigned char FirmwareVersion1stDigit;	/* Byte 2 */
-	unsigned char FirmwareVersion2ndDigit;	/* Byte 3 */
+struct blogic_board_id {
+	unsigned char type;		/* Byte 0 */
+	unsigned char custom_features;	/* Byte 1 */
+	unsigned char fw_ver_digit1;	/* Byte 2 */
+	unsigned char fw_ver_digit2;	/* Byte 3 */
 };
 
 /*
   Define the Inquire Configuration reply structure.
 */
 
-struct BusLogic_Configuration {
+struct blogic_config {
 	unsigned char:5;	/* Byte 0 Bits 0-4 */
-	bool DMA_Channel5:1;	/* Byte 0 Bit 5 */
-	bool DMA_Channel6:1;	/* Byte 0 Bit 6 */
-	bool DMA_Channel7:1;	/* Byte 0 Bit 7 */
-	bool IRQ_Channel9:1;	/* Byte 1 Bit 0 */
-	bool IRQ_Channel10:1;	/* Byte 1 Bit 1 */
-	bool IRQ_Channel11:1;	/* Byte 1 Bit 2 */
-	bool IRQ_Channel12:1;	/* Byte 1 Bit 3 */
+	bool dma_ch5:1;		/* Byte 0 Bit 5 */
+	bool dma_ch6:1;		/* Byte 0 Bit 6 */
+	bool dma_ch7:1;		/* Byte 0 Bit 7 */
+	bool irq_ch9:1;		/* Byte 1 Bit 0 */
+	bool irq_ch10:1;	/* Byte 1 Bit 1 */
+	bool irq_ch11:1;	/* Byte 1 Bit 2 */
+	bool irq_ch12:1;	/* Byte 1 Bit 3 */
 	unsigned char:1;	/* Byte 1 Bit 4 */
-	bool IRQ_Channel14:1;	/* Byte 1 Bit 5 */
-	bool IRQ_Channel15:1;	/* Byte 1 Bit 6 */
+	bool irq_ch14:1;	/* Byte 1 Bit 5 */
+	bool irq_ch15:1;	/* Byte 1 Bit 6 */
 	unsigned char:1;	/* Byte 1 Bit 7 */
-	unsigned char HostAdapterID:4;	/* Byte 2 Bits 0-3 */
+	unsigned char id:4;	/* Byte 2 Bits 0-3 */
 	unsigned char:4;	/* Byte 2 Bits 4-7 */
 };
 
@@ -441,42 +430,42 @@ struct BusLogic_Configuration {
   Define the Inquire Setup Information reply structure.
 */
 
-struct BusLogic_SynchronousValue {
-	unsigned char Offset:4;	/* Bits 0-3 */
-	unsigned char TransferPeriod:3;	/* Bits 4-6 */
-	bool Synchronous:1;	/* Bit 7 */
+struct blogic_syncval {
+	unsigned char offset:4;		/* Bits 0-3 */
+	unsigned char tx_period:3;	/* Bits 4-6 */
+	bool sync:1;			/* Bit 7 */
 };
 
-struct BusLogic_SetupInformation {
-	bool SynchronousInitiationEnabled:1;	/* Byte 0 Bit 0 */
-	bool ParityCheckingEnabled:1;		/* Byte 0 Bit 1 */
-	unsigned char:6;	/* Byte 0 Bits 2-7 */
-	unsigned char BusTransferRate;	/* Byte 1 */
-	unsigned char PreemptTimeOnBus;	/* Byte 2 */
-	unsigned char TimeOffBus;	/* Byte 3 */
-	unsigned char MailboxCount;	/* Byte 4 */
-	unsigned char MailboxAddress[3];	/* Bytes 5-7 */
-	struct BusLogic_SynchronousValue SynchronousValuesID0to7[8];	/* Bytes 8-15 */
-	unsigned char DisconnectPermittedID0to7;	/* Byte 16 */
-	unsigned char Signature;	/* Byte 17 */
-	unsigned char CharacterD;	/* Byte 18 */
-	unsigned char HostBusType;	/* Byte 19 */
-	unsigned char WideTransfersPermittedID0to7;	/* Byte 20 */
-	unsigned char WideTransfersActiveID0to7;	/* Byte 21 */
-	struct BusLogic_SynchronousValue SynchronousValuesID8to15[8];	/* Bytes 22-29 */
-	unsigned char DisconnectPermittedID8to15;	/* Byte 30 */
-	unsigned char:8;	/* Byte 31 */
-	unsigned char WideTransfersPermittedID8to15;	/* Byte 32 */
-	unsigned char WideTransfersActiveID8to15;	/* Byte 33 */
+struct blogic_setup_info {
+	bool sync:1;				/* Byte 0 Bit 0 */
+	bool parity:1;				/* Byte 0 Bit 1 */
+	unsigned char:6;			/* Byte 0 Bits 2-7 */
+	unsigned char tx_rate;			/* Byte 1 */
+	unsigned char preempt_time;		/* Byte 2 */
+	unsigned char timeoff_bus;		/* Byte 3 */
+	unsigned char mbox_count;		/* Byte 4 */
+	unsigned char mbox_addr[3];		/* Bytes 5-7 */
+	struct blogic_syncval sync0to7[8];	/* Bytes 8-15 */
+	unsigned char disconnect_ok0to7;	/* Byte 16 */
+	unsigned char sig;			/* Byte 17 */
+	unsigned char char_d;			/* Byte 18 */
+	unsigned char bus_type;			/* Byte 19 */
+	unsigned char wide_tx_ok0to7;		/* Byte 20 */
+	unsigned char wide_tx_active0to7;	/* Byte 21 */
+	struct blogic_syncval sync8to15[8];	/* Bytes 22-29 */
+	unsigned char disconnect_ok8to15;	/* Byte 30 */
+	unsigned char:8;			/* Byte 31 */
+	unsigned char wide_tx_ok8to15;		/* Byte 32 */
+	unsigned char wide_tx_active8to15;	/* Byte 33 */
 };
 
 /*
   Define the Initialize Extended Mailbox request structure.
 */
 
-struct BusLogic_ExtendedMailboxRequest {
-	unsigned char MailboxCount;	/* Byte 0 */
-	u32 BaseMailboxAddress;	/* Bytes 1-4 */
+struct blogic_extmbox_req {
+	unsigned char mbox_count;	/* Byte 0 */
+	u32 base_mbox_addr;		/* Bytes 1-4 */
 } PACKED;
 
 
@@ -486,63 +475,63 @@ struct BusLogic_ExtendedMailboxRequest {
   the Modify I/O Address command.
 */
 
-enum BusLogic_ISACompatibleIOPort {
-	BusLogic_IO_330 = 0,
-	BusLogic_IO_334 = 1,
-	BusLogic_IO_230 = 2,
-	BusLogic_IO_234 = 3,
-	BusLogic_IO_130 = 4,
-	BusLogic_IO_134 = 5,
-	BusLogic_IO_Disable = 6,
-	BusLogic_IO_Disable2 = 7
+enum blogic_isa_ioport {
+	BLOGIC_IO_330 = 0,
+	BLOGIC_IO_334 = 1,
+	BLOGIC_IO_230 = 2,
+	BLOGIC_IO_234 = 3,
+	BLOGIC_IO_130 = 4,
+	BLOGIC_IO_134 = 5,
+	BLOGIC_IO_DISABLE = 6,
+	BLOGIC_IO_DISABLE2 = 7
 } PACKED;
 
-struct BusLogic_PCIHostAdapterInformation {
-	enum BusLogic_ISACompatibleIOPort ISACompatibleIOPort;	/* Byte 0 */
-	unsigned char PCIAssignedIRQChannel;	/* Byte 1 */
-	bool LowByteTerminated:1;	/* Byte 2 Bit 0 */
-	bool HighByteTerminated:1;	/* Byte 2 Bit 1 */
-	unsigned char:2;	/* Byte 2 Bits 2-3 */
-	bool JP1:1;		/* Byte 2 Bit 4 */
-	bool JP2:1;		/* Byte 2 Bit 5 */
-	bool JP3:1;		/* Byte 2 Bit 6 */
-	bool GenericInfoValid:1;/* Byte 2 Bit 7 */
-	unsigned char:8;	/* Byte 3 */
+struct blogic_adapter_info {
+	enum blogic_isa_ioport isa_port;	/* Byte 0 */
+	unsigned char irq_ch;		/* Byte 1 */
+	bool low_term:1;		/* Byte 2 Bit 0 */
+	bool high_term:1;		/* Byte 2 Bit 1 */
+	unsigned char:2;		/* Byte 2 Bits 2-3 */
+	bool JP1:1;			/* Byte 2 Bit 4 */
+	bool JP2:1;			/* Byte 2 Bit 5 */
+	bool JP3:1;			/* Byte 2 Bit 6 */
+	bool genericinfo_valid:1;	/* Byte 2 Bit 7 */
+	unsigned char:8;		/* Byte 3 */
 };
 
 /*
   Define the Inquire Extended Setup Information reply structure.
 */
 
-struct BusLogic_ExtendedSetupInformation {
-	unsigned char BusType;	/* Byte 0 */
-	unsigned char BIOS_Address;	/* Byte 1 */
-	unsigned short ScatterGatherLimit;	/* Bytes 2-3 */
-	unsigned char MailboxCount;	/* Byte 4 */
-	u32 BaseMailboxAddress;	/* Bytes 5-8 */
+struct blogic_ext_setup {
+	unsigned char bus_type;		/* Byte 0 */
+	unsigned char bios_addr;	/* Byte 1 */
+	unsigned short sg_limit;	/* Bytes 2-3 */
+	unsigned char mbox_count;	/* Byte 4 */
+	u32 base_mbox_addr;		/* Bytes 5-8 */
 	struct {
 		unsigned char:2;	/* Byte 9 Bits 0-1 */
-		bool FastOnEISA:1;	/* Byte 9 Bit 2 */
+		bool fast_on_eisa:1;	/* Byte 9 Bit 2 */
 		unsigned char:3;	/* Byte 9 Bits 3-5 */
-		bool LevelSensitiveInterrupt:1;	/* Byte 9 Bit 6 */
+		bool level_int:1;	/* Byte 9 Bit 6 */
 		unsigned char:1;	/* Byte 9 Bit 7 */
-	} Misc;
-	unsigned char FirmwareRevision[3];	/* Bytes 10-12 */
-	bool HostWideSCSI:1;		/* Byte 13 Bit 0 */
-	bool HostDifferentialSCSI:1;	/* Byte 13 Bit 1 */
-	bool HostSupportsSCAM:1;	/* Byte 13 Bit 2 */
-	bool HostUltraSCSI:1;		/* Byte 13 Bit 3 */
-	bool HostSmartTermination:1;	/* Byte 13 Bit 4 */
-	unsigned char:3;	/* Byte 13 Bits 5-7 */
+	} misc;
+	unsigned char fw_rev[3];	/* Bytes 10-12 */
+	bool wide:1;			/* Byte 13 Bit 0 */
+	bool differential:1;		/* Byte 13 Bit 1 */
+	bool scam:1;			/* Byte 13 Bit 2 */
+	bool ultra:1;			/* Byte 13 Bit 3 */
+	bool smart_term:1;		/* Byte 13 Bit 4 */
+	unsigned char:3;		/* Byte 13 Bits 5-7 */
 } PACKED;
 
 /*
   Define the Enable Strict Round Robin Mode request type.
 */
 
-enum BusLogic_RoundRobinModeRequest {
-	BusLogic_AggressiveRoundRobinMode = 0,
-	BusLogic_StrictRoundRobinMode = 1
+enum blogic_rr_req {
+	BLOGIC_AGGRESSIVE_RR = 0,
+	BLOGIC_STRICT_RR_MODE = 1
 } PACKED;
 
 
@@ -550,95 +539,95 @@ enum BusLogic_RoundRobinModeRequest {
   Define the Fetch Host Adapter Local RAM request type.
 */
 
-#define BusLogic_BIOS_BaseOffset		0
-#define BusLogic_AutoSCSI_BaseOffset		64
+#define BLOGIC_BIOS_BASE		0
+#define BLOGIC_AUTOSCSI_BASE		64
 
-struct BusLogic_FetchHostAdapterLocalRAMRequest {
-	unsigned char ByteOffset;	/* Byte 0 */
-	unsigned char ByteCount;	/* Byte 1 */
+struct blogic_fetch_localram {
+	unsigned char offset;	/* Byte 0 */
+	unsigned char count;	/* Byte 1 */
 };
 
 /*
   Define the Host Adapter Local RAM AutoSCSI structure.
 */
 
-struct BusLogic_AutoSCSIData {
-	unsigned char InternalFactorySignature[2];	/* Bytes 0-1 */
-	unsigned char InformationByteCount;	/* Byte 2 */
-	unsigned char HostAdapterType[6];	/* Bytes 3-8 */
-	unsigned char:8;	/* Byte 9 */
-	bool FloppyEnabled:1;		/* Byte 10 Bit 0 */
-	bool FloppySecondary:1;		/* Byte 10 Bit 1 */
-	bool LevelSensitiveInterrupt:1;	/* Byte 10 Bit 2 */
-	unsigned char:2;	/* Byte 10 Bits 3-4 */
-	unsigned char SystemRAMAreaForBIOS:3;	/* Byte 10 Bits 5-7 */
-	unsigned char DMA_Channel:7;	/* Byte 11 Bits 0-6 */
-	bool DMA_AutoConfiguration:1;	/* Byte 11 Bit 7 */
-	unsigned char IRQ_Channel:7;	/* Byte 12 Bits 0-6 */
-	bool IRQ_AutoConfiguration:1;	/* Byte 12 Bit 7 */
-	unsigned char DMA_TransferRate;	/* Byte 13 */
-	unsigned char SCSI_ID;	/* Byte 14 */
-	bool LowByteTerminated:1;	/* Byte 15 Bit 0 */
-	bool ParityCheckingEnabled:1;	/* Byte 15 Bit 1 */
-	bool HighByteTerminated:1;	/* Byte 15 Bit 2 */
-	bool NoisyCablingEnvironment:1;	/* Byte 15 Bit 3 */
-	bool FastSynchronousNegotiation:1;	/* Byte 15 Bit 4 */
-	bool BusResetEnabled:1;		/* Byte 15 Bit 5 */
-	 bool:1;		/* Byte 15 Bit 6 */
-	bool ActiveNegationEnabled:1;	/* Byte 15 Bit 7 */
-	unsigned char BusOnDelay;	/* Byte 16 */
-	unsigned char BusOffDelay;	/* Byte 17 */
-	bool HostAdapterBIOSEnabled:1;		/* Byte 18 Bit 0 */
-	bool BIOSRedirectionOfINT19Enabled:1;	/* Byte 18 Bit 1 */
-	bool ExtendedTranslationEnabled:1;	/* Byte 18 Bit 2 */
-	bool MapRemovableAsFixedEnabled:1;	/* Byte 18 Bit 3 */
-	 bool:1;		/* Byte 18 Bit 4 */
-	bool BIOSSupportsMoreThan2DrivesEnabled:1;	/* Byte 18 Bit 5 */
-	bool BIOSInterruptModeEnabled:1;	/* Byte 18 Bit 6 */
-	bool FlopticalSupportEnabled:1;		/* Byte 19 Bit 7 */
-	unsigned short DeviceEnabled;	/* Bytes 19-20 */
-	unsigned short WidePermitted;	/* Bytes 21-22 */
-	unsigned short FastPermitted;	/* Bytes 23-24 */
-	unsigned short SynchronousPermitted;	/* Bytes 25-26 */
-	unsigned short DisconnectPermitted;	/* Bytes 27-28 */
-	unsigned short SendStartUnitCommand;	/* Bytes 29-30 */
-	unsigned short IgnoreInBIOSScan;	/* Bytes 31-32 */
-	unsigned char PCIInterruptPin:2;	/* Byte 33 Bits 0-1 */
-	unsigned char HostAdapterIOPortAddress:2;	/* Byte 33 Bits 2-3 */
-	bool StrictRoundRobinModeEnabled:1;	/* Byte 33 Bit 4 */
-	bool VESABusSpeedGreaterThan33MHz:1;	/* Byte 33 Bit 5 */
-	bool VESABurstWriteEnabled:1;	/* Byte 33 Bit 6 */
-	bool VESABurstReadEnabled:1;	/* Byte 33 Bit 7 */
-	unsigned short UltraPermitted;	/* Bytes 34-35 */
-	unsigned int:32;	/* Bytes 36-39 */
-	unsigned char:8;	/* Byte 40 */
-	unsigned char AutoSCSIMaximumLUN;	/* Byte 41 */
-	 bool:1;		/* Byte 42 Bit 0 */
-	bool SCAM_Dominant:1;	/* Byte 42 Bit 1 */
-	bool SCAM_Enabled:1;	/* Byte 42 Bit 2 */
-	bool SCAM_Level2:1;	/* Byte 42 Bit 3 */
-	unsigned char:4;	/* Byte 42 Bits 4-7 */
-	bool INT13ExtensionEnabled:1;	/* Byte 43 Bit 0 */
-	 bool:1;		/* Byte 43 Bit 1 */
-	bool CDROMBootEnabled:1;	/* Byte 43 Bit 2 */
-	unsigned char:5;	/* Byte 43 Bits 3-7 */
-	unsigned char BootTargetID:4;	/* Byte 44 Bits 0-3 */
-	unsigned char BootChannel:4;	/* Byte 44 Bits 4-7 */
-	unsigned char ForceBusDeviceScanningOrder:1;	/* Byte 45 Bit 0 */
-	unsigned char:7;	/* Byte 45 Bits 1-7 */
-	unsigned short NonTaggedToAlternateLUNPermitted;	/* Bytes 46-47 */
-	unsigned short RenegotiateSyncAfterCheckCondition;	/* Bytes 48-49 */
-	unsigned char Reserved[10];	/* Bytes 50-59 */
-	unsigned char ManufacturingDiagnostic[2];	/* Bytes 60-61 */
-	unsigned short Checksum;	/* Bytes 62-63 */
+struct blogic_autoscsi {
+	unsigned char factory_sig[2];		/* Bytes 0-1 */
+	unsigned char info_bytes;		/* Byte 2 */
+	unsigned char adapter_type[6];		/* Bytes 3-8 */
+	unsigned char:8;			/* Byte 9 */
+	bool floppy:1;				/* Byte 10 Bit 0 */
+	bool floppy_sec:1;			/* Byte 10 Bit 1 */
+	bool level_int:1;			/* Byte 10 Bit 2 */
+	unsigned char:2;			/* Byte 10 Bits 3-4 */
+	unsigned char systemram_bios:3;		/* Byte 10 Bits 5-7 */
+	unsigned char dma_ch:7;			/* Byte 11 Bits 0-6 */
+	bool dma_autoconf:1;			/* Byte 11 Bit 7 */
+	unsigned char irq_ch:7;			/* Byte 12 Bits 0-6 */
+	bool irq_autoconf:1;			/* Byte 12 Bit 7 */
+	unsigned char dma_tx_rate;		/* Byte 13 */
+	unsigned char scsi_id;			/* Byte 14 */
+	bool low_term:1;			/* Byte 15 Bit 0 */
+	bool parity:1;				/* Byte 15 Bit 1 */
+	bool high_term:1;			/* Byte 15 Bit 2 */
+	bool noisy_cable:1;			/* Byte 15 Bit 3 */
+	bool fast_sync_neg:1;			/* Byte 15 Bit 4 */
+	bool reset_enabled:1;			/* Byte 15 Bit 5 */
+	bool:1;					/* Byte 15 Bit 6 */
+	bool active_negation:1;			/* Byte 15 Bit 7 */
+	unsigned char bus_on_delay;		/* Byte 16 */
+	unsigned char bus_off_delay;		/* Byte 17 */
+	bool bios_enabled:1;			/* Byte 18 Bit 0 */
+	bool int19_redir_enabled:1;		/* Byte 18 Bit 1 */
+	bool ext_trans_enable:1;		/* Byte 18 Bit 2 */
+	bool removable_as_fixed:1;		/* Byte 18 Bit 3 */
+	bool:1;					/* Byte 18 Bit 4 */
+	bool morethan2_drives:1;		/* Byte 18 Bit 5 */
+	bool bios_int:1;			/* Byte 18 Bit 6 */
+	bool floptical:1;			/* Byte 19 Bit 7 */
+	unsigned short dev_enabled;		/* Bytes 19-20 */
+	unsigned short wide_ok;			/* Bytes 21-22 */
+	unsigned short fast_ok;			/* Bytes 23-24 */
+	unsigned short sync_ok;			/* Bytes 25-26 */
+	unsigned short discon_ok;		/* Bytes 27-28 */
+	unsigned short send_start_unit;		/* Bytes 29-30 */
+	unsigned short ignore_bios_scan;	/* Bytes 31-32 */
+	unsigned char pci_int_pin:2;		/* Byte 33 Bits 0-1 */
+	unsigned char adapter_ioport:2;		/* Byte 33 Bits 2-3 */
+	bool strict_rr_enabled:1;		/* Byte 33 Bit 4 */
+	bool vesabus_33mhzplus:1;		/* Byte 33 Bit 5 */
+	bool vesa_burst_write:1;		/* Byte 33 Bit 6 */
+	bool vesa_burst_read:1;			/* Byte 33 Bit 7 */
+	unsigned short ultra_ok;		/* Bytes 34-35 */
+	unsigned int:32;			/* Bytes 36-39 */
+	unsigned char:8;			/* Byte 40 */
+	unsigned char autoscsi_maxlun;		/* Byte 41 */
+	bool:1;					/* Byte 42 Bit 0 */
+	bool scam_dominant:1;			/* Byte 42 Bit 1 */
+	bool scam_enabled:1;			/* Byte 42 Bit 2 */
+	bool scam_lev2:1;			/* Byte 42 Bit 3 */
+	unsigned char:4;			/* Byte 42 Bits 4-7 */
+	bool int13_exten:1;			/* Byte 43 Bit 0 */
+	bool:1;					/* Byte 43 Bit 1 */
+	bool cd_boot:1;				/* Byte 43 Bit 2 */
+	unsigned char:5;			/* Byte 43 Bits 3-7 */
+	unsigned char boot_id:4;		/* Byte 44 Bits 0-3 */
+	unsigned char boot_ch:4;		/* Byte 44 Bits 4-7 */
+	unsigned char force_scan_order:1;	/* Byte 45 Bit 0 */
+	unsigned char:7;			/* Byte 45 Bits 1-7 */
+	unsigned short nontagged_to_alt_ok;	/* Bytes 46-47 */
+	unsigned short reneg_sync_on_check;	/* Bytes 48-49 */
+	unsigned char rsvd[10];			/* Bytes 50-59 */
+	unsigned char manuf_diag[2];		/* Bytes 60-61 */
+	unsigned short cksum;			/* Bytes 62-63 */
 } PACKED;
 
 /*
   Define the Host Adapter Local RAM Auto SCSI Byte 45 structure.
 */
 
-struct BusLogic_AutoSCSIByte45 {
-	unsigned char ForceBusDeviceScanningOrder:1;	/* Bit 0 */
+struct blogic_autoscsi_byte45 {
+	unsigned char force_scan_order:1;	/* Bit 0 */
 	unsigned char:7;	/* Bits 1-7 */
 };
 
@@ -646,13 +635,13 @@ struct BusLogic_AutoSCSIByte45 {
   Define the Host Adapter Local RAM BIOS Drive Map Byte structure.
 */
 
-#define BusLogic_BIOS_DriveMapOffset		17
+#define BLOGIC_BIOS_DRVMAP		17
 
-struct BusLogic_BIOSDriveMapByte {
-	unsigned char TargetIDBit3:1;	/* Bit 0 */
-	unsigned char:2;	/* Bits 1-2 */
-	enum BusLogic_BIOS_DiskGeometryTranslation DiskGeometry:2;	/* Bits 3-4 */
-	unsigned char TargetID:3;	/* Bits 5-7 */
+struct blogic_bios_drvmap {
+	unsigned char tgt_idbit3:1;			/* Bit 0 */
+	unsigned char:2;				/* Bits 1-2 */
+	enum blogic_bios_diskgeometry diskgeom:2;	/* Bits 3-4 */
+	unsigned char tgt_id:3;				/* Bits 5-7 */
 };
 
 /*
@@ -660,19 +649,19 @@ struct BusLogic_BIOSDriveMapByte {
   necessary to support more than 8 Logical Units per Target Device.
 */
 
-enum BusLogic_SetCCBFormatRequest {
-	BusLogic_LegacyLUNFormatCCB = 0,
-	BusLogic_ExtendedLUNFormatCCB = 1
+enum blogic_setccb_fmt {
+	BLOGIC_LEGACY_LUN_CCB = 0,
+	BLOGIC_EXT_LUN_CCB = 1
 } PACKED;
 
 /*
   Define the Outgoing Mailbox Action Codes.
 */
 
-enum BusLogic_ActionCode {
-	BusLogic_OutgoingMailboxFree = 0x00,
-	BusLogic_MailboxStartCommand = 0x01,
-	BusLogic_MailboxAbortCommand = 0x02
+enum blogic_action {
+	BLOGIC_OUTBOX_FREE = 0x00,
+	BLOGIC_MBOX_START = 0x01,
+	BLOGIC_MBOX_ABORT = 0x02
 } PACKED;
 
 
@@ -682,26 +671,26 @@ enum BusLogic_ActionCode {
   completion codes are stored in the CCB; it only uses codes 1, 2, 4, and 5.
 */
 
-enum BusLogic_CompletionCode {
-	BusLogic_IncomingMailboxFree = 0x00,
-	BusLogic_CommandCompletedWithoutError = 0x01,
-	BusLogic_CommandAbortedAtHostRequest = 0x02,
-	BusLogic_AbortedCommandNotFound = 0x03,
-	BusLogic_CommandCompletedWithError = 0x04,
-	BusLogic_InvalidCCB = 0x05
+enum blogic_cmplt_code {
+	BLOGIC_INBOX_FREE = 0x00,
+	BLOGIC_CMD_COMPLETE_GOOD = 0x01,
+	BLOGIC_CMD_ABORT_BY_HOST = 0x02,
+	BLOGIC_CMD_NOTFOUND = 0x03,
+	BLOGIC_CMD_COMPLETE_ERROR = 0x04,
+	BLOGIC_INVALID_CCB = 0x05
 } PACKED;
 
 /*
   Define the Command Control Block (CCB) Opcodes.
 */
 
-enum BusLogic_CCB_Opcode {
-	BusLogic_InitiatorCCB = 0x00,
-	BusLogic_TargetCCB = 0x01,
-	BusLogic_InitiatorCCB_ScatterGather = 0x02,
-	BusLogic_InitiatorCCB_ResidualDataLength = 0x03,
-	BusLogic_InitiatorCCB_ScatterGatherResidual = 0x04,
-	BusLogic_BusDeviceReset = 0x81
+enum blogic_ccb_opcode {
+	BLOGIC_INITIATOR_CCB = 0x00,
+	BLOGIC_TGT_CCB = 0x01,
+	BLOGIC_INITIATOR_CCB_SG = 0x02,
+	BLOGIC_INITIATOR_CCBB_RESIDUAL = 0x03,
+	BLOGIC_INITIATOR_CCB_SG_RESIDUAL = 0x04,
+	BLOGIC_BDR = 0x81
 } PACKED;
 
 
@@ -709,11 +698,11 @@ enum BusLogic_CCB_Opcode {
   Define the CCB Data Direction Codes.
 */
 
-enum BusLogic_DataDirection {
-	BusLogic_UncheckedDataTransfer = 0,
-	BusLogic_DataInLengthChecked = 1,
-	BusLogic_DataOutLengthChecked = 2,
-	BusLogic_NoDataTransfer = 3
+enum blogic_datadir {
+	BLOGIC_UNCHECKED_TX = 0,
+	BLOGIC_DATAIN_CHECKED = 1,
+	BLOGIC_DATAOUT_CHECKED = 2,
+	BLOGIC_NOTX = 3
 };
 
 
@@ -722,32 +711,32 @@ enum BusLogic_DataDirection {
   return status code 0x0C; it uses 0x12 for both overruns and underruns.
 */
 
-enum BusLogic_HostAdapterStatus {
-	BusLogic_CommandCompletedNormally = 0x00,
-	BusLogic_LinkedCommandCompleted = 0x0A,
-	BusLogic_LinkedCommandCompletedWithFlag = 0x0B,
-	BusLogic_DataUnderRun = 0x0C,
-	BusLogic_SCSISelectionTimeout = 0x11,
-	BusLogic_DataOverRun = 0x12,
-	BusLogic_UnexpectedBusFree = 0x13,
-	BusLogic_InvalidBusPhaseRequested = 0x14,
-	BusLogic_InvalidOutgoingMailboxActionCode = 0x15,
-	BusLogic_InvalidCommandOperationCode = 0x16,
-	BusLogic_LinkedCCBhasInvalidLUN = 0x17,
-	BusLogic_InvalidCommandParameter = 0x1A,
-	BusLogic_AutoRequestSenseFailed = 0x1B,
-	BusLogic_TaggedQueuingMessageRejected = 0x1C,
-	BusLogic_UnsupportedMessageReceived = 0x1D,
-	BusLogic_HostAdapterHardwareFailed = 0x20,
-	BusLogic_TargetFailedResponseToATN = 0x21,
-	BusLogic_HostAdapterAssertedRST = 0x22,
-	BusLogic_OtherDeviceAssertedRST = 0x23,
-	BusLogic_TargetDeviceReconnectedImproperly = 0x24,
-	BusLogic_HostAdapterAssertedBusDeviceReset = 0x25,
-	BusLogic_AbortQueueGenerated = 0x26,
-	BusLogic_HostAdapterSoftwareError = 0x27,
-	BusLogic_HostAdapterHardwareTimeoutError = 0x30,
-	BusLogic_SCSIParityErrorDetected = 0x34
+enum blogic_adapter_status {
+	BLOGIC_CMD_CMPLT_NORMAL = 0x00,
+	BLOGIC_LINK_CMD_CMPLT = 0x0A,
+	BLOGIC_LINK_CMD_CMPLT_FLAG = 0x0B,
+	BLOGIC_DATA_UNDERRUN = 0x0C,
+	BLOGIC_SELECT_TIMEOUT = 0x11,
+	BLOGIC_DATA_OVERRUN = 0x12,
+	BLOGIC_NOEXPECT_BUSFREE = 0x13,
+	BLOGIC_INVALID_BUSPHASE = 0x14,
+	BLOGIC_INVALID_OUTBOX_CODE = 0x15,
+	BLOGIC_INVALID_CMD_CODE = 0x16,
+	BLOGIC_LINKCCB_BADLUN = 0x17,
+	BLOGIC_BAD_CMD_PARAM = 0x1A,
+	BLOGIC_AUTOREQSENSE_FAIL = 0x1B,
+	BLOGIC_TAGQUEUE_REJECT = 0x1C,
+	BLOGIC_BAD_MSG_RCVD = 0x1D,
+	BLOGIC_HW_FAIL = 0x20,
+	BLOGIC_NORESPONSE_TO_ATN = 0x21,
+	BLOGIC_HW_RESET = 0x22,
+	BLOGIC_RST_FROM_OTHERDEV = 0x23,
+	BLOGIC_BAD_RECONNECT = 0x24,
+	BLOGIC_HW_BDR = 0x25,
+	BLOGIC_ABRT_QUEUE = 0x26,
+	BLOGIC_ADAPTER_SW_ERROR = 0x27,
+	BLOGIC_HW_TIMEOUT = 0x30,
+	BLOGIC_PARITY_ERR = 0x34
 } PACKED;
 
 
@@ -755,30 +744,28 @@ enum BusLogic_HostAdapterStatus {
   Define the SCSI Target Device Status Codes.
 */
 
-enum BusLogic_TargetDeviceStatus {
-	BusLogic_OperationGood = 0x00,
-	BusLogic_CheckCondition = 0x02,
-	BusLogic_DeviceBusy = 0x08
+enum blogic_tgt_status {
+	BLOGIC_OP_GOOD = 0x00,
+	BLOGIC_CHECKCONDITION = 0x02,
+	BLOGIC_DEVBUSY = 0x08
 } PACKED;
 
 /*
   Define the Queue Tag Codes.
 */
 
-enum BusLogic_QueueTag {
-	BusLogic_SimpleQueueTag = 0,
-	BusLogic_HeadOfQueueTag = 1,
-	BusLogic_OrderedQueueTag = 2,
-	BusLogic_ReservedQT = 3
+enum blogic_queuetag {
+	BLOGIC_SIMPLETAG = 0,
+	BLOGIC_HEADTAG = 1,
+	BLOGIC_ORDEREDTAG = 2,
+	BLOGIC_RSVDTAG = 3
 };
 
 /*
   Define the SCSI Command Descriptor Block (CDB).
 */
 
-#define BusLogic_CDB_MaxLength			12
-
-typedef unsigned char SCSI_CDB_T[BusLogic_CDB_MaxLength];
+#define BLOGIC_CDB_MAXLEN			12
 
 
 /*
@@ -786,20 +773,20 @@ typedef unsigned char SCSI_CDB_T[BusLogi
   Firmware Interface and the FlashPoint SCCB Manager.
 */
 
-struct BusLogic_ScatterGatherSegment {
-	u32 SegmentByteCount;	/* Bytes 0-3 */
-	u32 SegmentDataPointer;	/* Bytes 4-7 */
+struct blogic_sg_seg {
+	u32 segbytes;	/* Bytes 0-3 */
+	u32 segdata;	/* Bytes 4-7 */
 };
 
 /*
   Define the Driver CCB Status Codes.
 */
 
-enum BusLogic_CCB_Status {
-	BusLogic_CCB_Free = 0,
-	BusLogic_CCB_Active = 1,
-	BusLogic_CCB_Completed = 2,
-	BusLogic_CCB_Reset = 3
+enum blogic_ccb_status {
+	BLOGIC_CCB_FREE = 0,
+	BLOGIC_CCB_ACTIVE = 1,
+	BLOGIC_CCB_COMPLETE = 2,
+	BLOGIC_CCB_RESET = 3
 } PACKED;
 
 
@@ -822,79 +809,81 @@ enum BusLogic_CCB_Status {
   32 Logical Units per Target Device.
 */
 
-struct BusLogic_CCB {
+struct blogic_ccb {
 	/*
 	   MultiMaster Firmware and FlashPoint SCCB Manager Common Portion.
 	 */
-	enum BusLogic_CCB_Opcode Opcode;	/* Byte 0 */
-	unsigned char:3;	/* Byte 1 Bits 0-2 */
-	enum BusLogic_DataDirection DataDirection:2;	/* Byte 1 Bits 3-4 */
-	bool TagEnable:1;	/* Byte 1 Bit 5 */
-	enum BusLogic_QueueTag QueueTag:2;	/* Byte 1 Bits 6-7 */
-	unsigned char CDB_Length;	/* Byte 2 */
-	unsigned char SenseDataLength;	/* Byte 3 */
-	u32 DataLength;		/* Bytes 4-7 */
-	u32 DataPointer;	/* Bytes 8-11 */
-	unsigned char:8;	/* Byte 12 */
-	unsigned char:8;	/* Byte 13 */
-	enum BusLogic_HostAdapterStatus HostAdapterStatus;	/* Byte 14 */
-	enum BusLogic_TargetDeviceStatus TargetDeviceStatus;	/* Byte 15 */
-	unsigned char TargetID;	/* Byte 16 */
-	unsigned char LogicalUnit:5;	/* Byte 17 Bits 0-4 */
-	bool LegacyTagEnable:1;	/* Byte 17 Bit 5 */
-	enum BusLogic_QueueTag LegacyQueueTag:2;	/* Byte 17 Bits 6-7 */
-	SCSI_CDB_T CDB;		/* Bytes 18-29 */
-	unsigned char:8;	/* Byte 30 */
-	unsigned char:8;	/* Byte 31 */
-	unsigned int:32;	/* Bytes 32-35 */
-	u32 SenseDataPointer;	/* Bytes 36-39 */
+	enum blogic_ccb_opcode opcode;			/* Byte 0 */
+	unsigned char:3;				/* Byte 1 Bits 0-2 */
+	enum blogic_datadir datadir:2;			/* Byte 1 Bits 3-4 */
+	bool tag_enable:1;				/* Byte 1 Bit 5 */
+	enum blogic_queuetag queuetag:2;		/* Byte 1 Bits 6-7 */
+	unsigned char cdblen;				/* Byte 2 */
+	unsigned char sense_datalen;			/* Byte 3 */
+	u32 datalen;					/* Bytes 4-7 */
+	void *data;					/* Bytes 8-11 */
+	unsigned char:8;				/* Byte 12 */
+	unsigned char:8;				/* Byte 13 */
+	enum blogic_adapter_status adapter_status;	/* Byte 14 */
+	enum blogic_tgt_status tgt_status;		/* Byte 15 */
+	unsigned char tgt_id;				/* Byte 16 */
+	unsigned char lun:5;				/* Byte 17 Bits 0-4 */
+	bool legacytag_enable:1;			/* Byte 17 Bit 5 */
+	enum blogic_queuetag legacy_tag:2;		/* Byte 17 Bits 6-7 */
+	unsigned char cdb[BLOGIC_CDB_MAXLEN];		/* Bytes 18-29 */
+	unsigned char:8;				/* Byte 30 */
+	unsigned char:8;				/* Byte 31 */
+	u32 rsvd_int;					/* Bytes 32-35 */
+	u32 sensedata;					/* Bytes 36-39 */
 	/*
 	   FlashPoint SCCB Manager Defined Portion.
 	 */
-	void (*CallbackFunction) (struct BusLogic_CCB *);	/* Bytes 40-43 */
-	u32 BaseAddress;	/* Bytes 44-47 */
-	enum BusLogic_CompletionCode CompletionCode;	/* Byte 48 */
+	void (*callback) (struct blogic_ccb *);		/* Bytes 40-43 */
+	u32 base_addr;					/* Bytes 44-47 */
+	enum blogic_cmplt_code comp_code;		/* Byte 48 */
 #ifdef CONFIG_SCSI_FLASHPOINT
-	unsigned char:8;	/* Byte 49 */
-	unsigned short OS_Flags;	/* Bytes 50-51 */
-	unsigned char Private[48];	/* Bytes 52-99 */
+	unsigned char:8;				/* Byte 49 */
+	u16 os_flags;					/* Bytes 50-51 */
+	unsigned char private[24];			/* Bytes 52-99 */
+	void *rsvd1;
+	void *rsvd2;
+	unsigned char private2[16];
 #endif
 	/*
 	   BusLogic Linux Driver Defined Portion.
 	 */
-	dma_addr_t AllocationGroupHead;
-	unsigned int AllocationGroupSize;
-	u32 DMA_Handle;
-	enum BusLogic_CCB_Status Status;
-	unsigned long SerialNumber;
-	struct scsi_cmnd *Command;
-	struct BusLogic_HostAdapter *HostAdapter;
-	struct BusLogic_CCB *Next;
-	struct BusLogic_CCB *NextAll;
-	struct BusLogic_ScatterGatherSegment
-	 ScatterGatherList[BusLogic_ScatterGatherLimit];
+	dma_addr_t allocgrp_head;
+	unsigned int allocgrp_size;
+	u32 dma_handle;
+	enum blogic_ccb_status status;
+	unsigned long serial;
+	struct scsi_cmnd *command;
+	struct blogic_adapter *adapter;
+	struct blogic_ccb *next;
+	struct blogic_ccb *next_all;
+	struct blogic_sg_seg sglist[BLOGIC_SG_LIMIT];
 };
 
 /*
   Define the 32 Bit Mode Outgoing Mailbox structure.
 */
 
-struct BusLogic_OutgoingMailbox {
-	u32 CCB;		/* Bytes 0-3 */
-	unsigned int:24;	/* Bytes 4-6 */
-	enum BusLogic_ActionCode ActionCode;	/* Byte 7 */
+struct blogic_outbox {
+	u32 ccb;			/* Bytes 0-3 */
+	u32:24;				/* Bytes 4-6 */
+	enum blogic_action action;	/* Byte 7 */
 };
 
 /*
   Define the 32 Bit Mode Incoming Mailbox structure.
 */
 
-struct BusLogic_IncomingMailbox {
-	u32 CCB;		/* Bytes 0-3 */
-	enum BusLogic_HostAdapterStatus HostAdapterStatus;	/* Byte 4 */
-	enum BusLogic_TargetDeviceStatus TargetDeviceStatus;	/* Byte 5 */
-	unsigned char:8;	/* Byte 6 */
-	enum BusLogic_CompletionCode CompletionCode;	/* Byte 7 */
+struct blogic_inbox {
+	u32 ccb;					/* Bytes 0-3 */
+	enum blogic_adapter_status adapter_status;	/* Byte 4 */
+	enum blogic_tgt_status tgt_status;		/* Byte 5 */
+	unsigned char:8;				/* Byte 6 */
+	enum blogic_cmplt_code comp_code;		/* Byte 7 */
 };
 
 
@@ -902,64 +891,60 @@ struct BusLogic_IncomingMailbox {
   Define the BusLogic Driver Options structure.
 */
 
-struct BusLogic_DriverOptions {
-	unsigned short TaggedQueuingPermitted;
-	unsigned short TaggedQueuingPermittedMask;
-	unsigned short BusSettleTime;
-	struct BusLogic_LocalOptions LocalOptions;
-	unsigned char CommonQueueDepth;
-	unsigned char QueueDepth[BusLogic_MaxTargetDevices];
+struct blogic_drvr_options {
+	unsigned short tagq_ok;
+	unsigned short tagq_ok_mask;
+	unsigned short bus_settle_time;
+	unsigned short stop_tgt_inquiry;
+	unsigned char common_qdepth;
+	unsigned char qdepth[BLOGIC_MAXDEV];
 };
 
 /*
   Define the Host Adapter Target Flags structure.
 */
 
-struct BusLogic_TargetFlags {
-	bool TargetExists:1;
-	bool TaggedQueuingSupported:1;
-	bool WideTransfersSupported:1;
-	bool TaggedQueuingActive:1;
-	bool WideTransfersActive:1;
-	bool CommandSuccessfulFlag:1;
-	bool TargetInfoReported:1;
+struct blogic_tgt_flags {
+	bool tgt_exists:1;
+	bool tagq_ok:1;
+	bool wide_ok:1;
+	bool tagq_active:1;
+	bool wide_active:1;
+	bool cmd_good:1;
+	bool tgt_info_in:1;
 };
 
 /*
   Define the Host Adapter Target Statistics structure.
 */
 
-#define BusLogic_SizeBuckets			10
-
-typedef unsigned int BusLogic_CommandSizeBuckets_T[BusLogic_SizeBuckets];
+#define BLOGIC_SZ_BUCKETS			10
 
-struct BusLogic_TargetStatistics {
-	unsigned int CommandsAttempted;
-	unsigned int CommandsCompleted;
-	unsigned int ReadCommands;
-	unsigned int WriteCommands;
-	struct BusLogic_ByteCounter TotalBytesRead;
-	struct BusLogic_ByteCounter TotalBytesWritten;
-	BusLogic_CommandSizeBuckets_T ReadCommandSizeBuckets;
-	BusLogic_CommandSizeBuckets_T WriteCommandSizeBuckets;
-	unsigned short CommandAbortsRequested;
-	unsigned short CommandAbortsAttempted;
-	unsigned short CommandAbortsCompleted;
-	unsigned short BusDeviceResetsRequested;
-	unsigned short BusDeviceResetsAttempted;
-	unsigned short BusDeviceResetsCompleted;
-	unsigned short HostAdapterResetsRequested;
-	unsigned short HostAdapterResetsAttempted;
-	unsigned short HostAdapterResetsCompleted;
+struct blogic_tgt_stats {
+	unsigned int cmds_tried;
+	unsigned int cmds_complete;
+	unsigned int read_cmds;
+	unsigned int write_cmds;
+	struct blogic_byte_count bytesread;
+	struct blogic_byte_count byteswritten;
+	unsigned int read_sz_buckets[BLOGIC_SZ_BUCKETS];
+	unsigned int write_sz_buckets[BLOGIC_SZ_BUCKETS];
+	unsigned short aborts_request;
+	unsigned short aborts_tried;
+	unsigned short aborts_done;
+	unsigned short bdr_request;
+	unsigned short bdr_tried;
+	unsigned short bdr_done;
+	unsigned short adatper_reset_req;
+	unsigned short adapter_reset_attempt;
+	unsigned short adapter_reset_done;
 };
 
 /*
   Define the FlashPoint Card Handle data type.
 */
 
-#define FlashPoint_BadCardHandle		0xFFFFFFFF
-
-typedef unsigned int FlashPoint_CardHandle_T;
+#define FPOINT_BADCARD_HANDLE		0xFFFFFFFFL
 
 
 /*
@@ -967,179 +952,179 @@ typedef unsigned int FlashPoint_CardHand
   by the FlashPoint SCCB Manager.
 */
 
-struct FlashPoint_Info {
-	u32 BaseAddress;	/* Bytes 0-3 */
-	bool Present;		/* Byte 4 */
-	unsigned char IRQ_Channel;	/* Byte 5 */
-	unsigned char SCSI_ID;	/* Byte 6 */
-	unsigned char SCSI_LUN;	/* Byte 7 */
-	unsigned short FirmwareRevision;	/* Bytes 8-9 */
-	unsigned short SynchronousPermitted;	/* Bytes 10-11 */
-	unsigned short FastPermitted;	/* Bytes 12-13 */
-	unsigned short UltraPermitted;	/* Bytes 14-15 */
-	unsigned short DisconnectPermitted;	/* Bytes 16-17 */
-	unsigned short WidePermitted;	/* Bytes 18-19 */
-	bool ParityCheckingEnabled:1;	/* Byte 20 Bit 0 */
-	bool HostWideSCSI:1;		/* Byte 20 Bit 1 */
-	bool HostSoftReset:1;		/* Byte 20 Bit 2 */
-	bool ExtendedTranslationEnabled:1;	/* Byte 20 Bit 3 */
-	bool LowByteTerminated:1;	/* Byte 20 Bit 4 */
-	bool HighByteTerminated:1;	/* Byte 20 Bit 5 */
-	bool ReportDataUnderrun:1;	/* Byte 20 Bit 6 */
-	bool SCAM_Enabled:1;	/* Byte 20 Bit 7 */
-	bool SCAM_Level2:1;	/* Byte 21 Bit 0 */
-	unsigned char:7;	/* Byte 21 Bits 1-7 */
-	unsigned char Family;	/* Byte 22 */
-	unsigned char BusType;	/* Byte 23 */
-	unsigned char ModelNumber[3];	/* Bytes 24-26 */
-	unsigned char RelativeCardNumber;	/* Byte 27 */
-	unsigned char Reserved[4];	/* Bytes 28-31 */
-	unsigned int OS_Reserved;	/* Bytes 32-35 */
-	unsigned char TranslationInfo[4];	/* Bytes 36-39 */
-	unsigned int Reserved2[5];	/* Bytes 40-59 */
-	unsigned int SecondaryRange;	/* Bytes 60-63 */
+struct fpoint_info {
+	u32 base_addr;				/* Bytes 0-3 */
+	bool present;				/* Byte 4 */
+	unsigned char irq_ch;			/* Byte 5 */
+	unsigned char scsi_id;			/* Byte 6 */
+	unsigned char scsi_lun;			/* Byte 7 */
+	u16 fw_rev;				/* Bytes 8-9 */
+	u16 sync_ok;				/* Bytes 10-11 */
+	u16 fast_ok;				/* Bytes 12-13 */
+	u16 ultra_ok;				/* Bytes 14-15 */
+	u16 discon_ok;				/* Bytes 16-17 */
+	u16 wide_ok;				/* Bytes 18-19 */
+	bool parity:1;				/* Byte 20 Bit 0 */
+	bool wide:1;				/* Byte 20 Bit 1 */
+	bool softreset:1;			/* Byte 20 Bit 2 */
+	bool ext_trans_enable:1;		/* Byte 20 Bit 3 */
+	bool low_term:1;			/* Byte 20 Bit 4 */
+	bool high_term:1;			/* Byte 20 Bit 5 */
+	bool report_underrun:1;			/* Byte 20 Bit 6 */
+	bool scam_enabled:1;			/* Byte 20 Bit 7 */
+	bool scam_lev2:1;			/* Byte 21 Bit 0 */
+	unsigned char:7;			/* Byte 21 Bits 1-7 */
+	unsigned char family;			/* Byte 22 */
+	unsigned char bus_type;			/* Byte 23 */
+	unsigned char model[3];			/* Bytes 24-26 */
+	unsigned char relative_cardnum;		/* Byte 27 */
+	unsigned char rsvd[4];			/* Bytes 28-31 */
+	u32 os_rsvd;				/* Bytes 32-35 */
+	unsigned char translation_info[4];	/* Bytes 36-39 */
+	u32 rsvd2[5];				/* Bytes 40-59 */
+	u32 sec_range;				/* Bytes 60-63 */
 };
 
 /*
   Define the BusLogic Driver Host Adapter structure.
 */
 
-struct BusLogic_HostAdapter {
-	struct Scsi_Host *SCSI_Host;
-	struct pci_dev *PCI_Device;
-	enum BusLogic_HostAdapterType HostAdapterType;
-	enum BusLogic_HostAdapterBusType HostAdapterBusType;
-	unsigned long IO_Address;
-	unsigned long PCI_Address;
-	unsigned short AddressCount;
-	unsigned char HostNumber;
-	unsigned char ModelName[9];
-	unsigned char FirmwareVersion[6];
-	unsigned char FullModelName[18];
-	unsigned char Bus;
-	unsigned char Device;
-	unsigned char IRQ_Channel;
-	unsigned char DMA_Channel;
-	unsigned char SCSI_ID;
-	bool IRQ_ChannelAcquired:1;
-	bool DMA_ChannelAcquired:1;
-	bool ExtendedTranslationEnabled:1;
-	bool ParityCheckingEnabled:1;
-	bool BusResetEnabled:1;
-	bool LevelSensitiveInterrupt:1;
-	bool HostWideSCSI:1;
-	bool HostDifferentialSCSI:1;
-	bool HostSupportsSCAM:1;
-	bool HostUltraSCSI:1;
-	bool ExtendedLUNSupport:1;
-	bool TerminationInfoValid:1;
-	bool LowByteTerminated:1;
-	bool HighByteTerminated:1;
-	bool BounceBuffersRequired:1;
-	bool StrictRoundRobinModeSupport:1;
-	bool SCAM_Enabled:1;
-	bool SCAM_Level2:1;
-	bool HostAdapterInitialized:1;
-	bool HostAdapterExternalReset:1;
-	bool HostAdapterInternalError:1;
-	bool ProcessCompletedCCBsActive;
-	volatile bool HostAdapterCommandCompleted;
-	unsigned short HostAdapterScatterGatherLimit;
-	unsigned short DriverScatterGatherLimit;
-	unsigned short MaxTargetDevices;
-	unsigned short MaxLogicalUnits;
-	unsigned short MailboxCount;
-	unsigned short InitialCCBs;
-	unsigned short IncrementalCCBs;
-	unsigned short AllocatedCCBs;
-	unsigned short DriverQueueDepth;
-	unsigned short HostAdapterQueueDepth;
-	unsigned short UntaggedQueueDepth;
-	unsigned short CommonQueueDepth;
-	unsigned short BusSettleTime;
-	unsigned short SynchronousPermitted;
-	unsigned short FastPermitted;
-	unsigned short UltraPermitted;
-	unsigned short WidePermitted;
-	unsigned short DisconnectPermitted;
-	unsigned short TaggedQueuingPermitted;
-	unsigned short ExternalHostAdapterResets;
-	unsigned short HostAdapterInternalErrors;
-	unsigned short TargetDeviceCount;
-	unsigned short MessageBufferLength;
-	u32 BIOS_Address;
-	struct BusLogic_DriverOptions *DriverOptions;
-	struct FlashPoint_Info FlashPointInfo;
-	FlashPoint_CardHandle_T CardHandle;
+struct blogic_adapter {
+	struct Scsi_Host *scsi_host;
+	struct pci_dev *pci_device;
+	enum blogic_adapter_type adapter_type;
+	enum blogic_adapter_bus_type adapter_bus_type;
+	unsigned long io_addr;
+	unsigned long pci_addr;
+	unsigned short addr_count;
+	unsigned char host_no;
+	unsigned char model[9];
+	unsigned char fw_ver[6];
+	unsigned char full_model[18];
+	unsigned char bus;
+	unsigned char dev;
+	unsigned char irq_ch;
+	unsigned char dma_ch;
+	unsigned char scsi_id;
+	bool irq_acquired:1;
+	bool dma_chan_acquired:1;
+	bool ext_trans_enable:1;
+	bool parity:1;
+	bool reset_enabled:1;
+	bool level_int:1;
+	bool wide:1;
+	bool differential:1;
+	bool scam:1;
+	bool ultra:1;
+	bool ext_lun:1;
+	bool terminfo_valid:1;
+	bool low_term:1;
+	bool high_term:1;
+	bool need_bouncebuf:1;
+	bool strict_rr:1;
+	bool scam_enabled:1;
+	bool scam_lev2:1;
+	bool adapter_initd:1;
+	bool adapter_extreset:1;
+	bool adapter_intern_err:1;
+	bool processing_ccbs;
+	volatile bool adapter_cmd_complete;
+	unsigned short adapter_sglimit;
+	unsigned short drvr_sglimit;
+	unsigned short maxdev;
+	unsigned short maxlun;
+	unsigned short mbox_count;
+	unsigned short initccbs;
+	unsigned short inc_ccbs;
+	unsigned short alloc_ccbs;
+	unsigned short drvr_qdepth;
+	unsigned short adapter_qdepth;
+	unsigned short untag_qdepth;
+	unsigned short common_qdepth;
+	unsigned short bus_settle_time;
+	unsigned short sync_ok;
+	unsigned short fast_ok;
+	unsigned short ultra_ok;
+	unsigned short wide_ok;
+	unsigned short discon_ok;
+	unsigned short tagq_ok;
+	unsigned short ext_resets;
+	unsigned short adapter_intern_errors;
+	unsigned short tgt_count;
+	unsigned short msgbuflen;
+	u32 bios_addr;
+	struct blogic_drvr_options *drvr_opts;
+	struct fpoint_info fpinfo;
+	void *cardhandle;
 	struct list_head host_list;
-	struct BusLogic_CCB *All_CCBs;
-	struct BusLogic_CCB *Free_CCBs;
-	struct BusLogic_CCB *FirstCompletedCCB;
-	struct BusLogic_CCB *LastCompletedCCB;
-	struct BusLogic_CCB *BusDeviceResetPendingCCB[BusLogic_MaxTargetDevices];
-	struct BusLogic_TargetFlags TargetFlags[BusLogic_MaxTargetDevices];
-	unsigned char QueueDepth[BusLogic_MaxTargetDevices];
-	unsigned char SynchronousPeriod[BusLogic_MaxTargetDevices];
-	unsigned char SynchronousOffset[BusLogic_MaxTargetDevices];
-	unsigned char ActiveCommands[BusLogic_MaxTargetDevices];
-	unsigned int CommandsSinceReset[BusLogic_MaxTargetDevices];
-	unsigned long LastSequencePoint[BusLogic_MaxTargetDevices];
-	unsigned long LastResetAttempted[BusLogic_MaxTargetDevices];
-	unsigned long LastResetCompleted[BusLogic_MaxTargetDevices];
-	struct BusLogic_OutgoingMailbox *FirstOutgoingMailbox;
-	struct BusLogic_OutgoingMailbox *LastOutgoingMailbox;
-	struct BusLogic_OutgoingMailbox *NextOutgoingMailbox;
-	struct BusLogic_IncomingMailbox *FirstIncomingMailbox;
-	struct BusLogic_IncomingMailbox *LastIncomingMailbox;
-	struct BusLogic_IncomingMailbox *NextIncomingMailbox;
-	struct BusLogic_TargetStatistics TargetStatistics[BusLogic_MaxTargetDevices];
-	unsigned char *MailboxSpace;
-	dma_addr_t MailboxSpaceHandle;
-	unsigned int MailboxSize;
-	unsigned long CCB_Offset;
-	char MessageBuffer[BusLogic_MessageBufferSize];
+	struct blogic_ccb *all_ccbs;
+	struct blogic_ccb *free_ccbs;
+	struct blogic_ccb *firstccb;
+	struct blogic_ccb *lastccb;
+	struct blogic_ccb *bdr_pend[BLOGIC_MAXDEV];
+	struct blogic_tgt_flags tgt_flags[BLOGIC_MAXDEV];
+	unsigned char qdepth[BLOGIC_MAXDEV];
+	unsigned char sync_period[BLOGIC_MAXDEV];
+	unsigned char sync_offset[BLOGIC_MAXDEV];
+	unsigned char active_cmds[BLOGIC_MAXDEV];
+	unsigned int cmds_since_rst[BLOGIC_MAXDEV];
+	unsigned long last_seqpoint[BLOGIC_MAXDEV];
+	unsigned long last_resettried[BLOGIC_MAXDEV];
+	unsigned long last_resetdone[BLOGIC_MAXDEV];
+	struct blogic_outbox *first_outbox;
+	struct blogic_outbox *last_outbox;
+	struct blogic_outbox *next_outbox;
+	struct blogic_inbox *first_inbox;
+	struct blogic_inbox *last_inbox;
+	struct blogic_inbox *next_inbox;
+	struct blogic_tgt_stats tgt_stats[BLOGIC_MAXDEV];
+	unsigned char *mbox_space;
+	dma_addr_t mbox_space_handle;
+	unsigned int mbox_sz;
+	unsigned long ccb_offset;
+	char msgbuf[BLOGIC_MSGBUF_SIZE];
 };
 
 /*
   Define a structure for the BIOS Disk Parameters.
 */
 
-struct BIOS_DiskParameters {
-	int Heads;
-	int Sectors;
-	int Cylinders;
+struct bios_diskparam {
+	int heads;
+	int sectors;
+	int cylinders;
 };
 
 /*
   Define a structure for the SCSI Inquiry command results.
 */
 
-struct SCSI_Inquiry {
-	unsigned char PeripheralDeviceType:5;	/* Byte 0 Bits 0-4 */
-	unsigned char PeripheralQualifier:3;	/* Byte 0 Bits 5-7 */
-	unsigned char DeviceTypeModifier:7;	/* Byte 1 Bits 0-6 */
-	bool RMB:1;		/* Byte 1 Bit 7 */
-	unsigned char ANSI_ApprovedVersion:3;	/* Byte 2 Bits 0-2 */
-	unsigned char ECMA_Version:3;	/* Byte 2 Bits 3-5 */
-	unsigned char ISO_Version:2;	/* Byte 2 Bits 6-7 */
-	unsigned char ResponseDataFormat:4;	/* Byte 3 Bits 0-3 */
-	unsigned char:2;	/* Byte 3 Bits 4-5 */
-	bool TrmIOP:1;		/* Byte 3 Bit 6 */
-	bool AENC:1;		/* Byte 3 Bit 7 */
-	unsigned char AdditionalLength;	/* Byte 4 */
-	unsigned char:8;	/* Byte 5 */
-	unsigned char:8;	/* Byte 6 */
-	bool SftRe:1;		/* Byte 7 Bit 0 */
-	bool CmdQue:1;		/* Byte 7 Bit 1 */
-	 bool:1;		/* Byte 7 Bit 2 */
-	bool Linked:1;		/* Byte 7 Bit 3 */
-	bool Sync:1;		/* Byte 7 Bit 4 */
-	bool WBus16:1;		/* Byte 7 Bit 5 */
-	bool WBus32:1;		/* Byte 7 Bit 6 */
-	bool RelAdr:1;		/* Byte 7 Bit 7 */
-	unsigned char VendorIdentification[8];	/* Bytes 8-15 */
-	unsigned char ProductIdentification[16];	/* Bytes 16-31 */
-	unsigned char ProductRevisionLevel[4];	/* Bytes 32-35 */
+struct scsi_inquiry {
+	unsigned char devtype:5;	/* Byte 0 Bits 0-4 */
+	unsigned char dev_qual:3;	/* Byte 0 Bits 5-7 */
+	unsigned char dev_modifier:7;	/* Byte 1 Bits 0-6 */
+	bool rmb:1;			/* Byte 1 Bit 7 */
+	unsigned char ansi_ver:3;	/* Byte 2 Bits 0-2 */
+	unsigned char ecma_ver:3;	/* Byte 2 Bits 3-5 */
+	unsigned char iso_ver:2;	/* Byte 2 Bits 6-7 */
+	unsigned char resp_fmt:4;	/* Byte 3 Bits 0-3 */
+	unsigned char:2;		/* Byte 3 Bits 4-5 */
+	bool TrmIOP:1;			/* Byte 3 Bit 6 */
+	bool AENC:1;			/* Byte 3 Bit 7 */
+	unsigned char addl_len;		/* Byte 4 */
+	unsigned char:8;		/* Byte 5 */
+	unsigned char:8;		/* Byte 6 */
+	bool SftRe:1;			/* Byte 7 Bit 0 */
+	bool CmdQue:1;			/* Byte 7 Bit 1 */
+	bool:1;				/* Byte 7 Bit 2 */
+	bool linked:1;			/* Byte 7 Bit 3 */
+	bool sync:1;			/* Byte 7 Bit 4 */
+	bool WBus16:1;			/* Byte 7 Bit 5 */
+	bool WBus32:1;			/* Byte 7 Bit 6 */
+	bool RelAdr:1;			/* Byte 7 Bit 7 */
+	unsigned char vendor[8];	/* Bytes 8-15 */
+	unsigned char product[16];	/* Bytes 16-31 */
+	unsigned char product_rev[4];	/* Bytes 32-35 */
 };
 
 
@@ -1148,184 +1133,170 @@ struct SCSI_Inquiry {
   Host Adapter I/O Registers.
 */
 
-static inline void BusLogic_SCSIBusReset(struct BusLogic_HostAdapter *HostAdapter)
+static inline void blogic_busreset(struct blogic_adapter *adapter)
 {
-	union BusLogic_ControlRegister ControlRegister;
-	ControlRegister.All = 0;
-	ControlRegister.cr.SCSIBusReset = true;
-	outb(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
+	union blogic_cntrl_reg cr;
+	cr.all = 0;
+	cr.cr.bus_reset = true;
+	outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
 }
 
-static inline void BusLogic_InterruptReset(struct BusLogic_HostAdapter *HostAdapter)
+static inline void blogic_intreset(struct blogic_adapter *adapter)
 {
-	union BusLogic_ControlRegister ControlRegister;
-	ControlRegister.All = 0;
-	ControlRegister.cr.InterruptReset = true;
-	outb(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
+	union blogic_cntrl_reg cr;
+	cr.all = 0;
+	cr.cr.int_reset = true;
+	outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
 }
 
-static inline void BusLogic_SoftReset(struct BusLogic_HostAdapter *HostAdapter)
+static inline void blogic_softreset(struct blogic_adapter *adapter)
 {
-	union BusLogic_ControlRegister ControlRegister;
-	ControlRegister.All = 0;
-	ControlRegister.cr.SoftReset = true;
-	outb(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
+	union blogic_cntrl_reg cr;
+	cr.all = 0;
+	cr.cr.soft_reset = true;
+	outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
 }
 
-static inline void BusLogic_HardReset(struct BusLogic_HostAdapter *HostAdapter)
+static inline void blogic_hardreset(struct blogic_adapter *adapter)
 {
-	union BusLogic_ControlRegister ControlRegister;
-	ControlRegister.All = 0;
-	ControlRegister.cr.HardReset = true;
-	outb(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
+	union blogic_cntrl_reg cr;
+	cr.all = 0;
+	cr.cr.hard_reset = true;
+	outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
 }
 
-static inline unsigned char BusLogic_ReadStatusRegister(struct BusLogic_HostAdapter *HostAdapter)
+static inline unsigned char blogic_rdstatus(struct blogic_adapter *adapter)
 {
-	return inb(HostAdapter->IO_Address + BusLogic_StatusRegisterOffset);
+	return inb(adapter->io_addr + BLOGIC_STATUS_REG);
 }
 
-static inline void BusLogic_WriteCommandParameterRegister(struct BusLogic_HostAdapter
-							  *HostAdapter, unsigned char Value)
+static inline void blogic_setcmdparam(struct blogic_adapter *adapter,
+					unsigned char value)
 {
-	outb(Value, HostAdapter->IO_Address + BusLogic_CommandParameterRegisterOffset);
+	outb(value, adapter->io_addr + BLOGIC_CMD_PARM_REG);
 }
 
-static inline unsigned char BusLogic_ReadDataInRegister(struct BusLogic_HostAdapter *HostAdapter)
+static inline unsigned char blogic_rddatain(struct blogic_adapter *adapter)
 {
-	return inb(HostAdapter->IO_Address + BusLogic_DataInRegisterOffset);
+	return inb(adapter->io_addr + BLOGIC_DATAIN_REG);
 }
 
-static inline unsigned char BusLogic_ReadInterruptRegister(struct BusLogic_HostAdapter *HostAdapter)
+static inline unsigned char blogic_rdint(struct blogic_adapter *adapter)
 {
-	return inb(HostAdapter->IO_Address + BusLogic_InterruptRegisterOffset);
+	return inb(adapter->io_addr + BLOGIC_INT_REG);
 }
 
-static inline unsigned char BusLogic_ReadGeometryRegister(struct BusLogic_HostAdapter *HostAdapter)
+static inline unsigned char blogic_rdgeom(struct blogic_adapter *adapter)
 {
-	return inb(HostAdapter->IO_Address + BusLogic_GeometryRegisterOffset);
+	return inb(adapter->io_addr + BLOGIC_GEOMETRY_REG);
 }
 
 /*
-  BusLogic_StartMailboxCommand issues an Execute Mailbox Command, which
+  blogic_execmbox issues an Execute Mailbox Command, which
   notifies the Host Adapter that an entry has been made in an Outgoing
   Mailbox.
 */
 
-static inline void BusLogic_StartMailboxCommand(struct BusLogic_HostAdapter *HostAdapter)
-{
-	BusLogic_WriteCommandParameterRegister(HostAdapter, BusLogic_ExecuteMailboxCommand);
-}
-
-/*
-  BusLogic_Delay waits for Seconds to elapse.
-*/
-
-static inline void BusLogic_Delay(int Seconds)
+static inline void blogic_execmbox(struct blogic_adapter *adapter)
 {
-	mdelay(1000 * Seconds);
+	blogic_setcmdparam(adapter, BLOGIC_EXEC_MBOX_CMD);
 }
 
 /*
-  Virtual_to_Bus and Bus_to_Virtual map between Kernel Virtual Addresses
-  and PCI/VLB/EISA/ISA Bus Addresses.
+  blogic_delay waits for Seconds to elapse.
 */
 
-static inline u32 Virtual_to_Bus(void *VirtualAddress)
-{
-	return (u32) virt_to_bus(VirtualAddress);
-}
-
-static inline void *Bus_to_Virtual(u32 BusAddress)
+static inline void blogic_delay(int seconds)
 {
-	return (void *) bus_to_virt(BusAddress);
+	mdelay(1000 * seconds);
 }
 
 /*
-  Virtual_to_32Bit_Virtual maps between Kernel Virtual Addresses and
+  virt_to_32bit_virt maps between Kernel Virtual Addresses and
   32 bit Kernel Virtual Addresses.  This avoids compilation warnings
   on 64 bit architectures.
 */
 
-static inline u32 Virtual_to_32Bit_Virtual(void *VirtualAddress)
+static inline u32 virt_to_32bit_virt(void *virt_addr)
 {
-	return (u32) (unsigned long) VirtualAddress;
+	return (u32) (unsigned long) virt_addr;
 }
 
 /*
-  BusLogic_IncrementErrorCounter increments Error Counter by 1, stopping at
+  blogic_inc_count increments counter by 1, stopping at
   65535 rather than wrapping around to 0.
 */
 
-static inline void BusLogic_IncrementErrorCounter(unsigned short *ErrorCounter)
+static inline void blogic_inc_count(unsigned short *count)
 {
-	if (*ErrorCounter < 65535)
-		(*ErrorCounter)++;
+	if (*count < 65535)
+		(*count)++;
 }
 
 /*
-  BusLogic_IncrementByteCounter increments Byte Counter by Amount.
+  blogic_addcount increments Byte Counter by Amount.
 */
 
-static inline void BusLogic_IncrementByteCounter(struct BusLogic_ByteCounter
-						 *ByteCounter, unsigned int Amount)
+static inline void blogic_addcount(struct blogic_byte_count *bytecount,
+					unsigned int amount)
 {
-	ByteCounter->Units += Amount;
-	if (ByteCounter->Units > 999999999) {
-		ByteCounter->Units -= 1000000000;
-		ByteCounter->Billions++;
+	bytecount->units += amount;
+	if (bytecount->units > 999999999) {
+		bytecount->units -= 1000000000;
+		bytecount->billions++;
 	}
 }
 
 /*
-  BusLogic_IncrementSizeBucket increments the Bucket for Amount.
+  blogic_incszbucket increments the Bucket for Amount.
 */
 
-static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T CommandSizeBuckets, unsigned int Amount)
+static inline void blogic_incszbucket(unsigned int *cmdsz_buckets,
+					unsigned int amount)
 {
-	int Index = 0;
-	if (Amount < 8 * 1024) {
-		if (Amount < 2 * 1024)
-			Index = (Amount < 1 * 1024 ? 0 : 1);
+	int index = 0;
+	if (amount < 8 * 1024) {
+		if (amount < 2 * 1024)
+			index = (amount < 1 * 1024 ? 0 : 1);
 		else
-			Index = (Amount < 4 * 1024 ? 2 : 3);
-	} else if (Amount < 128 * 1024) {
-		if (Amount < 32 * 1024)
-			Index = (Amount < 16 * 1024 ? 4 : 5);
+			index = (amount < 4 * 1024 ? 2 : 3);
+	} else if (amount < 128 * 1024) {
+		if (amount < 32 * 1024)
+			index = (amount < 16 * 1024 ? 4 : 5);
 		else
-			Index = (Amount < 64 * 1024 ? 6 : 7);
+			index = (amount < 64 * 1024 ? 6 : 7);
 	} else
-		Index = (Amount < 256 * 1024 ? 8 : 9);
-	CommandSizeBuckets[Index]++;
+		index = (amount < 256 * 1024 ? 8 : 9);
+	cmdsz_buckets[index]++;
 }
 
 /*
   Define the version number of the FlashPoint Firmware (SCCB Manager).
 */
 
-#define FlashPoint_FirmwareVersion		"5.02"
+#define FLASHPOINT_FW_VER		"5.02"
 
 /*
   Define the possible return values from FlashPoint_HandleInterrupt.
 */
 
-#define FlashPoint_NormalInterrupt		0x00
-#define FlashPoint_InternalError		0xFE
-#define FlashPoint_ExternalBusReset		0xFF
+#define FPOINT_NORMAL_INT		0x00
+#define FPOINT_INTERN_ERR		0xFE
+#define FPOINT_EXT_RESET		0xFF
 
 /*
   Define prototypes for the forward referenced BusLogic Driver
   Internal Functions.
 */
 
-static const char *BusLogic_DriverInfo(struct Scsi_Host *);
-static int BusLogic_QueueCommand(struct Scsi_Host *h, struct scsi_cmnd *);
-static int BusLogic_BIOSDiskParameters(struct scsi_device *, struct block_device *, sector_t, int *);
-static int BusLogic_SlaveConfigure(struct scsi_device *);
-static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *);
-static irqreturn_t BusLogic_InterruptHandler(int, void *);
-static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *, bool HardReset);
-static void BusLogic_Message(enum BusLogic_MessageLevel, char *, struct BusLogic_HostAdapter *, ...);
-static int __init BusLogic_Setup(char *);
+static const char *blogic_drvr_info(struct Scsi_Host *);
+static int blogic_qcmd(struct Scsi_Host *h, struct scsi_cmnd *);
+static int blogic_diskparam(struct scsi_device *, struct block_device *, sector_t, int *);
+static int blogic_slaveconfig(struct scsi_device *);
+static void blogic_qcompleted_ccb(struct blogic_ccb *);
+static irqreturn_t blogic_inthandler(int, void *);
+static int blogic_resetadapter(struct blogic_adapter *, bool hard_reset);
+static void blogic_msg(enum blogic_msglevel, char *, struct blogic_adapter *, ...);
+static int __init blogic_setup(char *);
 
 #endif				/* _BUSLOGIC_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/constants.c linux-libre-3.11-rc7-gnu/drivers/scsi/constants.c
--- linux-libre-3.10-gnu/drivers/scsi/constants.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/constants.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,10 +1,10 @@
-/* 
+/*
  * ASCII values for a number of symbolic constants, printing functions,
  * etc.
  * Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422)
  * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002)
  *   by D. Gilbert and aeb (20020609)
- * Update to SPC-4 T10/1713-D Rev 20, 22 May 2009, D. Gilbert 20090624
+ * Updated to SPC-4 T10/1713-D Rev 36g, D. Gilbert 20130701
  */
 
 #include <linux/blkdev.h>
@@ -21,12 +21,13 @@
 
 
 /* Commands with service actions that change the command name */
-#define MAINTENANCE_IN 0xa3
-#define MAINTENANCE_OUT 0xa4
 #define SERVICE_ACTION_IN_12 0xab
 #define SERVICE_ACTION_OUT_12 0xa9
+#define SERVICE_ACTION_BIDIRECTIONAL 0x9d
 #define SERVICE_ACTION_IN_16 0x9e
 #define SERVICE_ACTION_OUT_16 0x9f
+#define THIRD_PARTY_COPY_OUT 0x83
+#define THIRD_PARTY_COPY_IN 0x84
 
 
 
@@ -36,11 +37,11 @@ static const char * cdb_byte0_names[] =
 /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL,
 	    "Reassign Blocks",
 /* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL,
-/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
+/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",
 /* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)",
 	    "Reserve(6)",
 /* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)",
-/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", 
+/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic",
 /* 1e-1f */ "Prevent/Allow Medium Removal", NULL,
 /* 20-22 */  NULL, NULL, NULL,
 /* 23-28 */ "Read Format Capacities", "Set Window",
@@ -48,16 +49,16 @@ static const char * cdb_byte0_names[] =
 /* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)",
             "Read updated block",
 /* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal",
-/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", 
+/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position",
 /* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)",
-	    "Read Defect Data(10)", 
-/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", 
-            "Read Buffer", 
+	    "Read Defect Data(10)",
+/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer",
+	    "Read Buffer",
 /* 3d-3f */ "Update Block", "Read Long(10)",  "Write Long(10)",
 /* 40-41 */ "Change Definition", "Write Same(10)",
 /* 42-48 */ "Unmap/Read sub-channel", "Read TOC/PMA/ATIP",
 	    "Read density support", "Play audio(10)", "Get configuration",
-	    "Play audio msf", "Play audio track/index",
+	    "Play audio msf", "Sanitize/Play audio track/index",
 /* 49-4f */ "Play track relative(10)", "Get event status notification",
             "Pause/resume", "Log Select", "Log Sense", "Stop play/scan",
             NULL,
@@ -72,17 +73,17 @@ static const char * cdb_byte0_names[] =
 /* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 /* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, "Extended CDB",
 	    "Variable length",
-/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy",
-            "Receive copy results",
+/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)",
+	    "Third party copy out", "Third party copy in",
 /* 85-89 */ "ATA command pass through(16)", "Access control in",
-	    "Access control out", "Read(16)", "Memory Export Out(16)",
+	    "Access control out", "Read(16)", "Compare and Write",
 /* 8a-8f */ "Write(16)", "ORWrite", "Read attributes", "Write attributes",
             "Write and verify(16)", "Verify(16)",
 /* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)",
             "Lock/unlock cache(16)", "Write same(16)", NULL,
 /* 95-99 */ NULL, NULL, NULL, NULL, NULL,
-/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in(16)",
-            "Service action out(16)",
+/* 9a-9f */ NULL, NULL, NULL, "Service action bidirectional",
+	    "Service action in(16)", "Service action out(16)",
 /* a0-a5 */ "Report luns", "ATA command pass through(12)/Blank",
             "Security protocol in", "Maintenance in", "Maintenance out",
 	    "Move medium/play audio(12)",
@@ -122,6 +123,7 @@ static const struct value_name_pair main
 	{0x6, "Set identifying information"},
 	{0xa, "Set target port groups"},
 	{0xb, "Change aliases"},
+	{0xc, "Remove I_T nexus"},
 	{0xe, "Set priority"},
 	{0xf, "Set timestamp"},
 	{0x10, "Management protocol out"},
@@ -138,10 +140,16 @@ static const struct value_name_pair serv
 };
 #define SERV_OUT12_SZ ARRAY_SIZE(serv_out12_arr)
 
+static const struct value_name_pair serv_bidi_arr[] = {
+	{-1, "dummy entry"},
+};
+#define SERV_BIDI_SZ ARRAY_SIZE(serv_bidi_arr)
+
 static const struct value_name_pair serv_in16_arr[] = {
 	{0x10, "Read capacity(16)"},
 	{0x11, "Read long(16)"},
 	{0x12, "Get LBA status"},
+	{0x13, "Report referrals"},
 };
 #define SERV_IN16_SZ ARRAY_SIZE(serv_in16_arr)
 
@@ -151,6 +159,51 @@ static const struct value_name_pair serv
 };
 #define SERV_OUT16_SZ ARRAY_SIZE(serv_out16_arr)
 
+static const struct value_name_pair pr_in_arr[] = {
+	{0x0, "Persistent reserve in, read keys"},
+	{0x1, "Persistent reserve in, read reservation"},
+	{0x2, "Persistent reserve in, report capabilities"},
+	{0x3, "Persistent reserve in, read full status"},
+};
+#define PR_IN_SZ ARRAY_SIZE(pr_in_arr)
+
+static const struct value_name_pair pr_out_arr[] = {
+	{0x0, "Persistent reserve out, register"},
+	{0x1, "Persistent reserve out, reserve"},
+	{0x2, "Persistent reserve out, release"},
+	{0x3, "Persistent reserve out, clear"},
+	{0x4, "Persistent reserve out, preempt"},
+	{0x5, "Persistent reserve out, preempt and abort"},
+	{0x6, "Persistent reserve out, register and ignore existing key"},
+	{0x7, "Persistent reserve out, register and move"},
+};
+#define PR_OUT_SZ ARRAY_SIZE(pr_out_arr)
+
+/* SPC-4 rev 34 renamed the Extended Copy opcode to Third Party Copy Out.
+   LID1 (List Identifier length: 1 byte) is the Extended Copy found in SPC-2
+   and SPC-3 */
+static const struct value_name_pair tpc_out_arr[] = {
+	{0x0, "Extended copy(LID1)"},
+	{0x1, "Extended copy(LID4)"},
+	{0x10, "Populate token"},
+	{0x11, "Write using token"},
+	{0x1c, "Copy operation abort"},
+};
+#define TPC_OUT_SZ ARRAY_SIZE(tpc_out_arr)
+
+static const struct value_name_pair tpc_in_arr[] = {
+	{0x0, "Receive copy status(LID1)"},
+	{0x1, "Receive copy data(LID1)"},
+	{0x3, "Receive copy operating parameters"},
+	{0x4, "Receive copy failure details(LID1)"},
+	{0x5, "Receive copy status(LID4)"},
+	{0x6, "Receive copy data(LID4)"},
+	{0x7, "Receive ROD token information"},
+	{0x8, "Report all ROD tokens"},
+};
+#define TPC_IN_SZ ARRAY_SIZE(tpc_in_arr)
+
+
 static const struct value_name_pair variable_length_arr[] = {
 	{0x1, "Rebuild(32)"},
 	{0x2, "Regenerate(32)"},
@@ -207,6 +260,7 @@ static const char * get_sa_name(const st
 static void print_opcode_name(unsigned char * cdbp, int cdb_len)
 {
 	int sa, len, cdb0;
+	int fin_name = 0;
 	const char * name;
 
 	cdb0 = cdbp[0];
@@ -219,7 +273,8 @@ static void print_opcode_name(unsigned c
 			break;
 		}
 		sa = (cdbp[8] << 8) + cdbp[9];
-		name = get_sa_name(variable_length_arr, VARIABLE_LENGTH_SZ, sa);
+		name = get_sa_name(variable_length_arr, VARIABLE_LENGTH_SZ,
+				   sa);
 		if (name)
 			printk("%s", name);
 		else
@@ -232,50 +287,57 @@ static void print_opcode_name(unsigned c
 	case MAINTENANCE_IN:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
-		if (name)
-			printk("%s", name);
-		else
-			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
+		fin_name = 1;
 		break;
 	case MAINTENANCE_OUT:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa);
-		if (name)
-			printk("%s", name);
-		else
-			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
+		fin_name = 1;
+		break;
+	case PERSISTENT_RESERVE_IN:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(pr_in_arr, PR_IN_SZ, sa);
+		fin_name = 1;
+		break;
+	case PERSISTENT_RESERVE_OUT:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(pr_out_arr, PR_OUT_SZ, sa);
+		fin_name = 1;
 		break;
 	case SERVICE_ACTION_IN_12:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa);
-		if (name)
-			printk("%s", name);
-		else
-			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
+		fin_name = 1;
 		break;
 	case SERVICE_ACTION_OUT_12:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa);
-		if (name)
-			printk("%s", name);
-		else
-			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
+		fin_name = 1;
+		break;
+	case SERVICE_ACTION_BIDIRECTIONAL:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(serv_bidi_arr, SERV_BIDI_SZ, sa);
+		fin_name = 1;
 		break;
 	case SERVICE_ACTION_IN_16:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa);
-		if (name)
-			printk("%s", name);
-		else
-			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
+		fin_name = 1;
 		break;
 	case SERVICE_ACTION_OUT_16:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa);
-		if (name)
-			printk("%s", name);
-		else
-			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
+		fin_name = 1;
+		break;
+	case THIRD_PARTY_COPY_IN:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(tpc_in_arr, TPC_IN_SZ, sa);
+		fin_name = 1;
+		break;
+	case THIRD_PARTY_COPY_OUT:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(tpc_out_arr, TPC_OUT_SZ, sa);
+		fin_name = 1;
 		break;
 	default:
 		if (cdb0 < 0xc0) {
@@ -288,6 +350,12 @@ static void print_opcode_name(unsigned c
 			printk("cdb[0]=0x%x (vendor)", cdb0);
 		break;
 	}
+	if (fin_name) {
+		if (name)
+			printk("%s", name);
+		else
+			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
+	}
 }
 
 #else /* ifndef CONFIG_SCSI_CONSTANTS */
@@ -312,10 +380,15 @@ static void print_opcode_name(unsigned c
 		break;
 	case MAINTENANCE_IN:
 	case MAINTENANCE_OUT:
+	case PERSISTENT_RESERVE_IN:
+	case PERSISTENT_RESERVE_OUT:
 	case SERVICE_ACTION_IN_12:
 	case SERVICE_ACTION_OUT_12:
+	case SERVICE_ACTION_BIDIRECTIONAL:
 	case SERVICE_ACTION_IN_16:
 	case SERVICE_ACTION_OUT_16:
+	case THIRD_PARTY_COPY_IN:
+	case THIRD_PARTY_COPY_OUT:
 		sa = cdbp[1] & 0x1f;
 		printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 		break;
@@ -327,7 +400,7 @@ static void print_opcode_name(unsigned c
 		break;
 	}
 }
-#endif  
+#endif
 
 void __scsi_print_command(unsigned char *cdb)
 {
@@ -336,7 +409,7 @@ void __scsi_print_command(unsigned char
 	print_opcode_name(cdb, 0);
 	len = scsi_command_size(cdb);
 	/* print out all bytes in cdb */
-	for (k = 0; k < len; ++k) 
+	for (k = 0; k < len; ++k)
 		printk(" %02x", cdb[k]);
 	printk("\n");
 }
@@ -404,8 +477,9 @@ struct error_info {
 
 /*
  * The canonical list of T10 Additional Sense Codes is available at:
- * http://www.t10.org/lists/asc-num.txt
+ * http://www.t10.org/lists/asc-num.txt [most recent: 20130605]
  */
+
 static const struct error_info additional[] =
 {
 	{0x0000, "No additional sense information"},
@@ -430,6 +504,8 @@ static const struct error_info additiona
 	{0x001C, "Verify operation in progress"},
 	{0x001D, "ATA pass through information available"},
 	{0x001E, "Conflicting SA creation request"},
+	{0x001F, "Logical unit transitioning to another power condition"},
+	{0x0020, "Extended copy information available"},
 
 	{0x0100, "No index/sector signal"},
 
@@ -460,6 +536,17 @@ static const struct error_info additiona
 	{0x0412, "Logical unit not ready, offline"},
 	{0x0413, "Logical unit not ready, SA creation in progress"},
 	{0x0414, "Logical unit not ready, space allocation in progress"},
+	{0x0415, "Logical unit not ready, robotics disabled"},
+	{0x0416, "Logical unit not ready, configuration required"},
+	{0x0417, "Logical unit not ready, calibration required"},
+	{0x0418, "Logical unit not ready, a door is open"},
+	{0x0419, "Logical unit not ready, operating in sequential mode"},
+	{0x041A, "Logical unit not ready, start stop unit command in "
+	 "progress"},
+	{0x041B, "Logical unit not ready, sanitize in progress"},
+	{0x041C, "Logical unit not ready, additional power use not yet "
+	 "granted"},
+	{0x041D, "Logical unit not ready, configuration in progress"},
 
 	{0x0500, "Logical unit does not respond to selection"},
 
@@ -490,6 +577,7 @@ static const struct error_info additiona
 	{0x0B06, "Warning - non-volatile cache now volatile"},
 	{0x0B07, "Warning - degraded power to non-volatile cache"},
 	{0x0B08, "Warning - power loss expected"},
+	{0x0B09, "Warning - device statistics notification active"},
 
 	{0x0C00, "Write error"},
 	{0x0C01, "Write error - recovered with auto reallocation"},
@@ -505,6 +593,7 @@ static const struct error_info additiona
 	{0x0C0B, "Auxiliary memory write error"},
 	{0x0C0C, "Write error - unexpected unsolicited data"},
 	{0x0C0D, "Write error - not enough unsolicited data"},
+	{0x0C0E, "Multiple write errors"},
 	{0x0C0F, "Defects in error window"},
 
 	{0x0D00, "Error detected by third party temporary initiator"},
@@ -523,6 +612,8 @@ static const struct error_info additiona
 	{0x1001, "Logical block guard check failed"},
 	{0x1002, "Logical block application tag check failed"},
 	{0x1003, "Logical block reference tag check failed"},
+	{0x1004, "Logical block protection error on recover buffered data"},
+	{0x1005, "Logical block protection method error"},
 
 	{0x1100, "Unrecovered read error"},
 	{0x1101, "Read retries exhausted"},
@@ -545,6 +636,7 @@ static const struct error_info additiona
 	{0x1112, "Auxiliary memory read error"},
 	{0x1113, "Read error - failed retransmission request"},
 	{0x1114, "Read error - lba marked bad by application client"},
+	{0x1115, "Write after sanitize required"},
 
 	{0x1200, "Address mark not found for id field"},
 
@@ -622,6 +714,7 @@ static const struct error_info additiona
 	{0x2009, "Access denied - invalid LU identifier"},
 	{0x200A, "Access denied - invalid proxy token"},
 	{0x200B, "Access denied - ACL LUN conflict"},
+	{0x200C, "Illegal command when not in append-only mode"},
 
 	{0x2100, "Logical block address out of range"},
 	{0x2101, "Invalid element address"},
@@ -630,6 +723,19 @@ static const struct error_info additiona
 
 	{0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"},
 
+	{0x2300, "Invalid token operation, cause not reportable"},
+	{0x2301, "Invalid token operation, unsupported token type"},
+	{0x2302, "Invalid token operation, remote token usage not supported"},
+	{0x2303, "Invalid token operation, remote rod token creation not "
+	 "supported"},
+	{0x2304, "Invalid token operation, token unknown"},
+	{0x2305, "Invalid token operation, token corrupt"},
+	{0x2306, "Invalid token operation, token revoked"},
+	{0x2307, "Invalid token operation, token expired"},
+	{0x2308, "Invalid token operation, token cancelled"},
+	{0x2309, "Invalid token operation, token deleted"},
+	{0x230A, "Invalid token operation, invalid token length"},
+
 	{0x2400, "Invalid field in cdb"},
 	{0x2401, "CDB decryption error"},
 	{0x2402, "Obsolete"},
@@ -705,6 +811,7 @@ static const struct error_info additiona
 		 "event"},
 	{0x2A13, "Data encryption key instance counter has changed"},
 	{0x2A14, "SA creation capabilities data has changed"},
+	{0x2A15, "Medium removal prevention preempted"},
 
 	{0x2B00, "Copy cannot execute since host cannot disconnect"},
 
@@ -720,6 +827,7 @@ static const struct error_info additiona
 	{0x2C09, "Previous reservation conflict status"},
 	{0x2C0A, "Partition or collection contains user objects"},
 	{0x2C0B, "Not reserved"},
+	{0x2C0C, "Orwrite generation does not match"},
 
 	{0x2D00, "Overwrite error on update in place"},
 
@@ -728,6 +836,7 @@ static const struct error_info additiona
 	{0x2F00, "Commands cleared by another initiator"},
 	{0x2F01, "Commands cleared by power loss notification"},
 	{0x2F02, "Commands cleared by device server"},
+	{0x2F03, "Some commands cleared by queuing layer event"},
 
 	{0x3000, "Incompatible medium installed"},
 	{0x3001, "Cannot read medium - unknown format"},
@@ -745,10 +854,12 @@ static const struct error_info additiona
 	{0x3010, "Medium not formatted"},
 	{0x3011, "Incompatible volume type"},
 	{0x3012, "Incompatible volume qualifier"},
+	{0x3013, "Cleaning volume expired"},
 
 	{0x3100, "Medium format corrupted"},
 	{0x3101, "Format command failed"},
 	{0x3102, "Zoned formatting failed due to spare linking"},
+	{0x3103, "Sanitize command failed"},
 
 	{0x3200, "No defect spare location available"},
 	{0x3201, "Defect list update failure"},
@@ -809,6 +920,8 @@ static const struct error_info additiona
 	{0x3B19, "Element enabled"},
 	{0x3B1A, "Data transfer device removed"},
 	{0x3B1B, "Data transfer device inserted"},
+	{0x3B1C, "Too many logical objects on partition to support "
+	 "operation"},
 
 	{0x3D00, "Invalid bits in identify message"},
 
@@ -839,6 +952,7 @@ static const struct error_info additiona
 	{0x3F12, "iSCSI IP address added"},
 	{0x3F13, "iSCSI IP address removed"},
 	{0x3F14, "iSCSI IP address changed"},
+	{0x3F15, "Inspect referrals sense descriptors"},
 /*
  *	{0x40NN, "Ram failure"},
  *	{0x40NN, "Diagnostic failure on component nn"},
@@ -848,6 +962,7 @@ static const struct error_info additiona
 	{0x4300, "Message error"},
 
 	{0x4400, "Internal target failure"},
+	{0x4401, "Persistent reservation information lost"},
 	{0x4471, "ATA device failed set features"},
 
 	{0x4500, "Select or reselect failure"},
@@ -876,6 +991,21 @@ static const struct error_info additiona
 	{0x4B04, "Nak received"},
 	{0x4B05, "Data offset error"},
 	{0x4B06, "Initiator response timeout"},
+	{0x4B07, "Connection lost"},
+	{0x4B08, "Data-in buffer overflow - data buffer size"},
+	{0x4B09, "Data-in buffer overflow - data buffer descriptor area"},
+	{0x4B0A, "Data-in buffer error"},
+	{0x4B0B, "Data-out buffer overflow - data buffer size"},
+	{0x4B0C, "Data-out buffer overflow - data buffer descriptor area"},
+	{0x4B0D, "Data-out buffer error"},
+	{0x4B0E, "PCIe fabric error"},
+	{0x4B0F, "PCIe completion timeout"},
+	{0x4B10, "PCIe completer abort"},
+	{0x4B11, "PCIe poisoned tlp received"},
+	{0x4B12, "PCIe eCRC check failed"},
+	{0x4B13, "PCIe unsupported request"},
+	{0x4B14, "PCIe acs violation"},
+	{0x4B15, "PCIe tlp prefix blocked"},
 
 	{0x4C00, "Logical unit failed self-configuration"},
 /*
@@ -897,6 +1027,10 @@ static const struct error_info additiona
 	{0x5302, "Medium removal prevented"},
 	{0x5303, "Medium removal prevented by data transfer element"},
 	{0x5304, "Medium thread or unthread failure"},
+	{0x5305, "Volume identifier invalid"},
+	{0x5306, "Volume identifier missing"},
+	{0x5307, "Duplicate volume identifier"},
+	{0x5308, "Element status unknown"},
 
 	{0x5400, "Scsi to host system interface failure"},
 
@@ -911,6 +1045,9 @@ static const struct error_info additiona
 	{0x5508, "Maximum number of supplemental decryption keys exceeded"},
 	{0x5509, "Medium auxiliary memory not accessible"},
 	{0x550A, "Data currently unavailable"},
+	{0x550B, "Insufficient power for operation"},
+	{0x550C, "Insufficient resources to create rod"},
+	{0x550D, "Insufficient resources to create rod token"},
 
 	{0x5700, "Unable to recover table-of-contents"},
 
@@ -1069,6 +1206,7 @@ static const struct error_info additiona
 	{0x670B, "ATA device feature not enabled"},
 
 	{0x6800, "Logical unit not configured"},
+	{0x6801, "Subsidiary logical unit not configured"},
 
 	{0x6900, "Data loss on logical unit"},
 	{0x6901, "Multiple logical unit failures"},
@@ -1185,10 +1323,13 @@ static const char * const snstext[] = {
 	"Vendor Specific(9)",
 	"Copy Aborted",	    /* A: COPY or COMPARE was aborted */
 	"Aborted Command",  /* B: The target aborted the command */
-	"Equal",	    /* C: A SEARCH DATA command found data equal */
+	"Equal",	    /* C: A SEARCH DATA command found data equal,
+				  reserved in SPC-4 rev 36 */
 	"Volume Overflow",  /* D: Medium full with still data to be written */
 	"Miscompare",	    /* E: Source data and data on the medium
 				  do not agree */
+	"Completed",	    /* F: command completed sense data reported,
+				  may occur for successful command */
 };
 #endif
 
@@ -1306,7 +1447,7 @@ scsi_decode_sense_buffer(const unsigned
 		       struct scsi_sense_hdr *sshdr)
 {
 	int k, num, res;
-    
+
 	res = scsi_normalize_sense(sense_buffer, sense_len, sshdr);
 	if (0 == res) {
 		/* this may be SCSI-1 sense data */
@@ -1459,5 +1600,3 @@ void scsi_print_result(struct scsi_cmnd
 	scsi_show_result(cmd->result);
 }
 EXPORT_SYMBOL(scsi_print_result);
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_hw.c linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_hw.c
--- linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_hw.c	2013-07-01 10:42:40.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_hw.c	2013-08-31 18:02:28.000000000 -0400
@@ -1597,87 +1597,6 @@ out:
 	return rv;
 }
 
-static int
-csio_config_global_rss(struct csio_hw *hw)
-{
-	struct csio_mb	*mbp;
-	enum fw_retval retval;
-
-	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
-	if (!mbp) {
-		CSIO_INC_STATS(hw, n_err_nomem);
-		return -ENOMEM;
-	}
-
-	csio_rss_glb_config(hw, mbp, CSIO_MB_DEFAULT_TMO,
-			    FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL,
-			    FW_RSS_GLB_CONFIG_CMD_TNLMAPEN |
-			    FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ |
-			    FW_RSS_GLB_CONFIG_CMD_TNLALLLKP,
-			    NULL);
-
-	if (csio_mb_issue(hw, mbp)) {
-		csio_err(hw, "Issue of FW_RSS_GLB_CONFIG_CMD failed!\n");
-		mempool_free(mbp, hw->mb_mempool);
-		return -EINVAL;
-	}
-
-	retval = csio_mb_fw_retval(mbp);
-	if (retval != FW_SUCCESS) {
-		csio_err(hw, "FW_RSS_GLB_CONFIG_CMD returned 0x%x!\n", retval);
-		mempool_free(mbp, hw->mb_mempool);
-		return -EINVAL;
-	}
-
-	mempool_free(mbp, hw->mb_mempool);
-
-	return 0;
-}
-
-/*
- * csio_config_pfvf - Configure Physical/Virtual functions settings.
- * @hw: HW module
- *
- */
-static int
-csio_config_pfvf(struct csio_hw *hw)
-{
-	struct csio_mb	*mbp;
-	enum fw_retval retval;
-
-	mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
-	if (!mbp) {
-		CSIO_INC_STATS(hw, n_err_nomem);
-		return -ENOMEM;
-	}
-
-	/*
-	 * For now, allow all PFs to access to all ports using a pmask
-	 * value of 0xF (M_FW_PFVF_CMD_PMASK). Once we have VFs, we will
-	 * need to provide access based on some rule.
-	 */
-	csio_mb_pfvf(hw, mbp, CSIO_MB_DEFAULT_TMO, hw->pfn, 0, CSIO_NEQ,
-		     CSIO_NETH_CTRL, CSIO_NIQ_FLINT, 0, 0, CSIO_NVI, CSIO_CMASK,
-		     CSIO_PMASK, CSIO_NEXACTF, CSIO_R_CAPS, CSIO_WX_CAPS, NULL);
-
-	if (csio_mb_issue(hw, mbp)) {
-		csio_err(hw, "Issue of FW_PFVF_CMD failed!\n");
-		mempool_free(mbp, hw->mb_mempool);
-		return -EINVAL;
-	}
-
-	retval = csio_mb_fw_retval(mbp);
-	if (retval != FW_SUCCESS) {
-		csio_err(hw, "FW_PFVF_CMD returned 0x%x!\n", retval);
-		mempool_free(mbp, hw->mb_mempool);
-		return -EINVAL;
-	}
-
-	mempool_free(mbp, hw->mb_mempool);
-
-	return 0;
-}
-
 /*
  * csio_enable_ports - Bring up all available ports.
  * @hw: HW module.
@@ -2056,16 +1975,6 @@ csio_hw_no_fwconfig(struct csio_hw *hw,
 	if (rv != 0)
 		goto out;
 
-	/* Config Global RSS command */
-	rv = csio_config_global_rss(hw);
-	if (rv != 0)
-		goto out;
-
-	/* Configure PF/VF capabilities of device */
-	rv = csio_config_pfvf(hw);
-	if (rv != 0)
-		goto out;
-
 	/* device parameters */
 	rv = csio_get_device_params(hw);
 	if (rv != 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_hw.h linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_hw.h
--- linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -153,17 +153,6 @@ enum {
 	CSIO_SGE_INT_CNT_VAL_1		= 4,
 	CSIO_SGE_INT_CNT_VAL_2		= 8,
 	CSIO_SGE_INT_CNT_VAL_3		= 16,
-
-	/* Storage specific - used by FW_PFVF_CMD */
-	CSIO_WX_CAPS			= FW_CMD_CAP_PF, /* w/x all */
-	CSIO_R_CAPS			= FW_CMD_CAP_PF, /* r all */
-	CSIO_NVI			= 4,
-	CSIO_NIQ_FLINT			= 34,
-	CSIO_NETH_CTRL			= 32,
-	CSIO_NEQ			= 66,
-	CSIO_NEXACTF			= 32,
-	CSIO_CMASK			= FW_PFVF_CMD_CMASK_MASK,
-	CSIO_PMASK			= FW_PFVF_CMD_PMASK_MASK,
 };
 
 /* Slowpath events */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_mb.c linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_mb.c
--- linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_mb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_mb.c	2013-08-25 20:43:22.000000000 -0400
@@ -326,83 +326,6 @@ csio_mb_caps_config(struct csio_hw *hw,
 		cmdp->fcoecaps |= htons(FW_CAPS_CONFIG_FCOE_TARGET);
 }
 
-void
-csio_rss_glb_config(struct csio_hw *hw, struct csio_mb *mbp,
-		    uint32_t tmo, uint8_t mode, unsigned int flags,
-		    void (*cbfn)(struct csio_hw *, struct csio_mb *))
-{
-	struct fw_rss_glb_config_cmd *cmdp =
-				(struct fw_rss_glb_config_cmd *)(mbp->mb);
-
-	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1);
-
-	cmdp->op_to_write = htonl(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
-				  FW_CMD_REQUEST | FW_CMD_WRITE);
-	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));
-
-	if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) {
-		cmdp->u.manual.mode_pkd =
-			htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
-	} else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) {
-		cmdp->u.basicvirtual.mode_pkd =
-			htonl(FW_RSS_GLB_CONFIG_CMD_MODE(mode));
-		cmdp->u.basicvirtual.synmapen_to_hashtoeplitz = htonl(flags);
-	}
-}
-
-
-/*
- * csio_mb_pfvf - FW Write PF/VF capabilities command helper.
- * @hw: The HW structure
- * @mbp: Mailbox structure
- * @pf:
- * @vf:
- * @txq:
- * @txq_eht_ctrl:
- * @rxqi:
- * @rxq:
- * @tc:
- * @vi:
- * @pmask:
- * @rcaps:
- * @wxcaps:
- * @cbfn: Callback, if any.
- *
- */
-void
-csio_mb_pfvf(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
-	     unsigned int pf, unsigned int vf, unsigned int txq,
-	     unsigned int txq_eth_ctrl, unsigned int rxqi,
-	     unsigned int rxq, unsigned int tc, unsigned int vi,
-	     unsigned int cmask, unsigned int pmask, unsigned int nexactf,
-	     unsigned int rcaps, unsigned int wxcaps,
-	     void (*cbfn) (struct csio_hw *, struct csio_mb *))
-{
-	struct fw_pfvf_cmd *cmdp = (struct fw_pfvf_cmd *)(mbp->mb);
-
-	CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1);
-
-	cmdp->op_to_vfn = htonl(FW_CMD_OP(FW_PFVF_CMD)			|
-				FW_CMD_REQUEST				|
-				FW_CMD_WRITE				|
-				FW_PFVF_CMD_PFN(pf)			|
-				FW_PFVF_CMD_VFN(vf));
-	cmdp->retval_len16 = htonl(FW_CMD_LEN16(sizeof(*cmdp) / 16));
-	cmdp->niqflint_niq = htonl(FW_PFVF_CMD_NIQFLINT(rxqi)		|
-					     FW_PFVF_CMD_NIQ(rxq));
-
-	cmdp->type_to_neq = htonl(FW_PFVF_CMD_TYPE			|
-				  FW_PFVF_CMD_CMASK(cmask)		|
-				  FW_PFVF_CMD_PMASK(pmask)		|
-				  FW_PFVF_CMD_NEQ(txq));
-	cmdp->tc_to_nexactf = htonl(FW_PFVF_CMD_TC(tc)			|
-				    FW_PFVF_CMD_NVI(vi)			|
-				    FW_PFVF_CMD_NEXACTF(nexactf));
-	cmdp->r_caps_to_nethctrl = htonl(FW_PFVF_CMD_R_CAPS(rcaps)	|
-					 FW_PFVF_CMD_WX_CAPS(wxcaps)	|
-					 FW_PFVF_CMD_NETHCTRL(txq_eth_ctrl));
-}
-
 #define CSIO_ADVERT_MASK     (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
 			      FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_ANEG)
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_mb.h linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_mb.h
--- linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_mb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_mb.h	2013-08-25 20:43:22.000000000 -0400
@@ -183,17 +183,6 @@ void csio_mb_caps_config(struct csio_hw
 			    bool, bool, bool, bool,
 			    void (*)(struct csio_hw *, struct csio_mb *));
 
-void csio_rss_glb_config(struct csio_hw *, struct csio_mb *,
-			 uint32_t, uint8_t, unsigned int,
-			 void (*)(struct csio_hw *, struct csio_mb *));
-
-void csio_mb_pfvf(struct csio_hw *, struct csio_mb *, uint32_t,
-		  unsigned int, unsigned int, unsigned int,
-		  unsigned int, unsigned int, unsigned int,
-		  unsigned int, unsigned int, unsigned int,
-		  unsigned int, unsigned int, unsigned int,
-		  unsigned int, void (*) (struct csio_hw *, struct csio_mb *));
-
 void csio_mb_port(struct csio_hw *, struct csio_mb *, uint32_t,
 		  uint8_t, bool, uint32_t, uint16_t,
 		  void (*) (struct csio_hw *, struct csio_mb *));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_scsi.c linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_scsi.c
--- linux-libre-3.10-gnu/drivers/scsi/csiostor/csio_scsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/csiostor/csio_scsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -1479,8 +1479,8 @@ csio_store_dbg_level(struct device *dev,
 }
 
 static DEVICE_ATTR(hw_state, S_IRUGO, csio_show_hw_state, NULL);
-static DEVICE_ATTR(device_reset, S_IRUGO | S_IWUSR, NULL, csio_device_reset);
-static DEVICE_ATTR(disable_port, S_IRUGO | S_IWUSR, NULL, csio_disable_port);
+static DEVICE_ATTR(device_reset, S_IWUSR, NULL, csio_device_reset);
+static DEVICE_ATTR(disable_port, S_IWUSR, NULL, csio_disable_port);
 static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 		  csio_store_dbg_level);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c linux-libre-3.11-rc7-gnu/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
--- linux-libre-3.10-gnu/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <net/dst.h>
 #include <linux/netdevice.h>
 
+#include "t4_regs.h"
 #include "t4_msg.h"
 #include "cxgb4.h"
 #include "cxgb4_uld.h"
@@ -32,13 +33,12 @@ static unsigned int dbg_level;
 #include "../libcxgbi.h"
 
 #define	DRV_MODULE_NAME		"cxgb4i"
-#define DRV_MODULE_DESC		"Chelsio T4 iSCSI Driver"
-#define	DRV_MODULE_VERSION	"0.9.1"
-#define	DRV_MODULE_RELDATE	"Aug. 2010"
+#define DRV_MODULE_DESC		"Chelsio T4/T5 iSCSI Driver"
+#define	DRV_MODULE_VERSION	"0.9.4"
 
 static char version[] =
 	DRV_MODULE_DESC " " DRV_MODULE_NAME
-	" v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+	" v" DRV_MODULE_VERSION "\n";
 
 MODULE_AUTHOR("Chelsio Communications, Inc.");
 MODULE_DESCRIPTION(DRV_MODULE_DESC);
@@ -175,10 +175,56 @@ static inline int is_ofld_imm(const stru
 			sizeof(struct fw_ofld_tx_data_wr));
 }
 
+
+#define VLAN_NONE 0xfff
+#define FILTER_SEL_VLAN_NONE 0xffff
+#define FILTER_SEL_WIDTH_P_FC (3+1) /* port uses 3 bits, FCoE one bit */
+#define FILTER_SEL_WIDTH_VIN_P_FC \
+	(6 + 7 + FILTER_SEL_WIDTH_P_FC) /* 6 bits are unused, VF uses 7 bits*/
+#define FILTER_SEL_WIDTH_TAG_P_FC \
+	(3 + FILTER_SEL_WIDTH_VIN_P_FC) /* PF uses 3 bits */
+#define FILTER_SEL_WIDTH_VLD_TAG_P_FC (1 + FILTER_SEL_WIDTH_TAG_P_FC)
+
+static unsigned int select_ntuple(struct cxgbi_device *cdev,
+				struct l2t_entry *l2t)
+{
+	struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
+	unsigned int ntuple = 0;
+	u32 viid;
+
+	switch (lldi->filt_mode) {
+
+	/* default filter mode */
+	case HW_TPL_FR_MT_PR_IV_P_FC:
+		if (l2t->vlan == VLAN_NONE)
+			ntuple |= FILTER_SEL_VLAN_NONE << FILTER_SEL_WIDTH_P_FC;
+		else {
+			ntuple |= l2t->vlan << FILTER_SEL_WIDTH_P_FC;
+			ntuple |= 1 << FILTER_SEL_WIDTH_VLD_TAG_P_FC;
+		}
+		ntuple |= l2t->lport << S_PORT | IPPROTO_TCP <<
+			  FILTER_SEL_WIDTH_VLD_TAG_P_FC;
+		break;
+	case HW_TPL_FR_MT_PR_OV_P_FC: {
+		viid = cxgb4_port_viid(l2t->neigh->dev);
+
+		ntuple |= FW_VIID_VIN_GET(viid) << FILTER_SEL_WIDTH_P_FC;
+		ntuple |= FW_VIID_PFN_GET(viid) << FILTER_SEL_WIDTH_VIN_P_FC;
+		ntuple |= FW_VIID_VIVLD_GET(viid) << FILTER_SEL_WIDTH_TAG_P_FC;
+		ntuple |= l2t->lport << S_PORT | IPPROTO_TCP <<
+			  FILTER_SEL_WIDTH_VLD_TAG_P_FC;
+		break;
+	}
+	default:
+		break;
+	}
+	return ntuple;
+}
+
 static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
 				struct l2t_entry *e)
 {
-	struct cpl_act_open_req *req;
+	struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev);
 	int wscale = cxgbi_sock_compute_wscale(csk->mss_idx);
 	unsigned long long opt0;
 	unsigned int opt2;
@@ -195,29 +241,58 @@ static void send_act_open_req(struct cxg
 		RCV_BUFSIZ(cxgb4i_rcv_win >> 10);
 	opt2 = RX_CHANNEL(0) |
 		RSS_QUEUE_VALID |
-		(1 << 20) | (1 << 22) |
+		(1 << 20) |
 		RSS_QUEUE(csk->rss_qid);
 
-	set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id);
-	req = (struct cpl_act_open_req *)skb->head;
+	if (is_t4(lldi->adapter_type)) {
+		struct cpl_act_open_req *req =
+				(struct cpl_act_open_req *)skb->head;
 
-	INIT_TP_WR(req, 0);
-	OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
+		req = (struct cpl_act_open_req *)skb->head;
+
+		INIT_TP_WR(req, 0);
+		OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
 					qid_atid));
-	req->local_port = csk->saddr.sin_port;
-	req->peer_port = csk->daddr.sin_port;
-	req->local_ip = csk->saddr.sin_addr.s_addr;
-	req->peer_ip = csk->daddr.sin_addr.s_addr;
-	req->opt0 = cpu_to_be64(opt0);
-	req->params = 0;
-	req->opt2 = cpu_to_be32(opt2);
+		req->local_port = csk->saddr.sin_port;
+		req->peer_port = csk->daddr.sin_port;
+		req->local_ip = csk->saddr.sin_addr.s_addr;
+		req->peer_ip = csk->daddr.sin_addr.s_addr;
+		req->opt0 = cpu_to_be64(opt0);
+		req->params = cpu_to_be32(select_ntuple(csk->cdev, csk->l2t));
+		opt2 |= 1 << 22;
+		req->opt2 = cpu_to_be32(opt2);
 
-	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
-		"csk 0x%p, %pI4:%u-%pI4:%u, atid %d, qid %u.\n",
-		csk, &req->local_ip, ntohs(req->local_port),
-		&req->peer_ip, ntohs(req->peer_port),
-		csk->atid, csk->rss_qid);
+		log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+			"csk t4 0x%p, %pI4:%u-%pI4:%u, atid %d, qid %u.\n",
+			csk, &req->local_ip, ntohs(req->local_port),
+			&req->peer_ip, ntohs(req->peer_port),
+			csk->atid, csk->rss_qid);
+	} else {
+		struct cpl_t5_act_open_req *req =
+				(struct cpl_t5_act_open_req *)skb->head;
+
+		req = (struct cpl_t5_act_open_req *)skb->head;
+
+		INIT_TP_WR(req, 0);
+		OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
+					qid_atid));
+		req->local_port = csk->saddr.sin_port;
+		req->peer_port = csk->daddr.sin_port;
+		req->local_ip = csk->saddr.sin_addr.s_addr;
+		req->peer_ip = csk->daddr.sin_addr.s_addr;
+		req->opt0 = cpu_to_be64(opt0);
+		req->params = cpu_to_be32(select_ntuple(csk->cdev, csk->l2t));
+		opt2 |= 1 << 31;
+		req->opt2 = cpu_to_be32(opt2);
 
+		log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
+			"csk t5 0x%p, %pI4:%u-%pI4:%u, atid %d, qid %u.\n",
+			csk, &req->local_ip, ntohs(req->local_port),
+			&req->peer_ip, ntohs(req->peer_port),
+			csk->atid, csk->rss_qid);
+	}
+
+	set_wr_txq(skb, CPL_PRIORITY_SETUP, csk->port_id);
 	cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t);
 }
 
@@ -358,7 +433,7 @@ static inline unsigned int calc_tx_flits
 		return DIV_ROUND_UP(skb->len, 8);
 	flits = skb_transport_offset(skb) / 8;
 	cnt = skb_shinfo(skb)->nr_frags;
-	if (skb->tail != skb->transport_header)
+	if (skb_tail_pointer(skb) != skb_transport_header(skb))
 		cnt++;
 	return flits + sgl_len(cnt);
 }
@@ -632,6 +707,7 @@ static void csk_act_open_retry_timer(uns
 {
 	struct sk_buff *skb;
 	struct cxgbi_sock *csk = (struct cxgbi_sock *)data;
+	struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(csk->cdev);
 
 	log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
 		"csk 0x%p,%u,0x%lx,%u.\n",
@@ -639,7 +715,10 @@ static void csk_act_open_retry_timer(uns
 
 	cxgbi_sock_get(csk);
 	spin_lock_bh(&csk->lock);
-	skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC);
+	skb = alloc_wr(is_t4(lldi->adapter_type) ?
+				sizeof(struct cpl_act_open_req) :
+				sizeof(struct cpl_t5_act_open_req),
+			0, GFP_ATOMIC);
 	if (!skb)
 		cxgbi_sock_fail_act_open(csk, -ENOMEM);
 	else {
@@ -871,7 +950,7 @@ static void do_rx_iscsi_hdr(struct cxgbi
 
 	if (!csk->skb_ulp_lhdr) {
 		unsigned char *bhs;
-		unsigned int hlen, dlen;
+		unsigned int hlen, dlen, plen;
 
 		log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX,
 			"csk 0x%p,%u,0x%lx, tid %u, skb 0x%p header.\n",
@@ -890,11 +969,15 @@ static void do_rx_iscsi_hdr(struct cxgbi
 		hlen = ntohs(cpl->len);
 		dlen = ntohl(*(unsigned int *)(bhs + 4)) & 0xFFFFFF;
 
-		if ((hlen + dlen) != ISCSI_PDU_LEN(pdu_len_ddp) - 40) {
+		plen = ISCSI_PDU_LEN(pdu_len_ddp);
+		if (is_t4(lldi->adapter_type))
+			plen -= 40;
+
+		if ((hlen + dlen) != plen) {
 			pr_info("tid 0x%x, CPL_ISCSI_HDR, pdu len "
 				"mismatch %u != %u + %u, seq 0x%x.\n",
-				csk->tid, ISCSI_PDU_LEN(pdu_len_ddp) - 40,
-				hlen, dlen, cxgbi_skcb_tcp_seq(skb));
+				csk->tid, plen, hlen, dlen,
+				cxgbi_skcb_tcp_seq(skb));
 			goto abort_conn;
 		}
 
@@ -1154,7 +1237,10 @@ static int init_act_open(struct cxgbi_so
 	}
 	cxgbi_sock_get(csk);
 
-	skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL);
+	skb = alloc_wr(is_t4(lldi->adapter_type) ?
+				sizeof(struct cpl_act_open_req) :
+				sizeof(struct cpl_t5_act_open_req),
+			0, GFP_ATOMIC);
 	if (!skb)
 		goto rel_resource;
 	skb->sk = (struct sock *)csk;
@@ -1193,6 +1279,8 @@ rel_resource:
 	return -EINVAL;
 }
 
+#define CPL_ISCSI_DATA		0xB2
+#define CPL_RX_ISCSI_DDP	0x49
 cxgb4i_cplhandler_func cxgb4i_cplhandlers[NUM_CPL_CMDS] = {
 	[CPL_ACT_ESTABLISH] = do_act_establish,
 	[CPL_ACT_OPEN_RPL] = do_act_open_rpl,
@@ -1202,8 +1290,10 @@ cxgb4i_cplhandler_func cxgb4i_cplhandler
 	[CPL_CLOSE_CON_RPL] = do_close_con_rpl,
 	[CPL_FW4_ACK] = do_fw4_ack,
 	[CPL_ISCSI_HDR] = do_rx_iscsi_hdr,
+	[CPL_ISCSI_DATA] = do_rx_iscsi_hdr,
 	[CPL_SET_TCB_RPL] = do_set_tcb_rpl,
 	[CPL_RX_DATA_DDP] = do_rx_data_ddp,
+	[CPL_RX_ISCSI_DDP] = do_rx_data_ddp,
 };
 
 int cxgb4i_ofld_init(struct cxgbi_device *cdev)
@@ -1234,14 +1324,20 @@ int cxgb4i_ofld_init(struct cxgbi_device
  * functions to program the pagepod in h/w
  */
 #define ULPMEM_IDATA_MAX_NPPODS	4 /* 256/PPOD_SIZE */
-static inline void ulp_mem_io_set_hdr(struct ulp_mem_io *req,
+static inline void ulp_mem_io_set_hdr(struct cxgb4_lld_info *lldi,
+				struct ulp_mem_io *req,
 				unsigned int wr_len, unsigned int dlen,
 				unsigned int pm_addr)
 {
 	struct ulptx_idata *idata = (struct ulptx_idata *)(req + 1);
 
 	INIT_ULPTX_WR(req, wr_len, 0, 0);
-	req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) | (1 << 23));
+	if (is_t4(lldi->adapter_type))
+		req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) |
+					(ULP_MEMIO_ORDER(1)));
+	else
+		req->cmd = htonl(ULPTX_CMD(ULP_TX_MEM_WRITE) |
+					(V_T5_ULP_MEMIO_IMM(1)));
 	req->dlen = htonl(ULP_MEMIO_DATA_LEN(dlen >> 5));
 	req->lock_addr = htonl(ULP_MEMIO_ADDR(pm_addr >> 5));
 	req->len16 = htonl(DIV_ROUND_UP(wr_len - sizeof(req->wr), 16));
@@ -1257,6 +1353,7 @@ static int ddp_ppod_write_idata(struct c
 				unsigned int gl_pidx)
 {
 	struct cxgbi_ddp_info *ddp = cdev->ddp;
+	struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev);
 	struct sk_buff *skb;
 	struct ulp_mem_io *req;
 	struct ulptx_idata *idata;
@@ -1276,7 +1373,7 @@ static int ddp_ppod_write_idata(struct c
 	req = (struct ulp_mem_io *)skb->head;
 	set_queue(skb, CPL_PRIORITY_CONTROL, NULL);
 
-	ulp_mem_io_set_hdr(req, wr_len, dlen, pm_addr);
+	ulp_mem_io_set_hdr(lldi, req, wr_len, dlen, pm_addr);
 	idata = (struct ulptx_idata *)(req + 1);
 	ppod = (struct cxgbi_pagepod *)(idata + 1);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/fcoe/fcoe.c linux-libre-3.11-rc7-gnu/drivers/scsi/fcoe/fcoe.c
--- linux-libre-3.10-gnu/drivers/scsi/fcoe/fcoe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/fcoe/fcoe.c	2013-08-25 20:43:22.000000000 -0400
@@ -774,7 +774,6 @@ static void fcoe_fdmi_info(struct fc_lpo
 	struct fcoe_port *port;
 	struct net_device *realdev;
 	int rc;
-	struct netdev_fcoe_hbainfo fdmi;
 
 	port = lport_priv(lport);
 	fcoe = port->priv;
@@ -788,9 +787,13 @@ static void fcoe_fdmi_info(struct fc_lpo
 		return;
 
 	if (realdev->netdev_ops->ndo_fcoe_get_hbainfo) {
-		memset(&fdmi, 0, sizeof(fdmi));
+		struct netdev_fcoe_hbainfo *fdmi;
+		fdmi = kzalloc(sizeof(*fdmi), GFP_KERNEL);
+		if (!fdmi)
+			return;
+
 		rc = realdev->netdev_ops->ndo_fcoe_get_hbainfo(realdev,
-							       &fdmi);
+							       fdmi);
 		if (rc) {
 			printk(KERN_INFO "fcoe: Failed to retrieve FDMI "
 					"information from netdev.\n");
@@ -800,38 +803,39 @@ static void fcoe_fdmi_info(struct fc_lpo
 		snprintf(fc_host_serial_number(lport->host),
 			 FC_SERIAL_NUMBER_SIZE,
 			 "%s",
-			 fdmi.serial_number);
+			 fdmi->serial_number);
 		snprintf(fc_host_manufacturer(lport->host),
 			 FC_SERIAL_NUMBER_SIZE,
 			 "%s",
-			 fdmi.manufacturer);
+			 fdmi->manufacturer);
 		snprintf(fc_host_model(lport->host),
 			 FC_SYMBOLIC_NAME_SIZE,
 			 "%s",
-			 fdmi.model);
+			 fdmi->model);
 		snprintf(fc_host_model_description(lport->host),
 			 FC_SYMBOLIC_NAME_SIZE,
 			 "%s",
-			 fdmi.model_description);
+			 fdmi->model_description);
 		snprintf(fc_host_hardware_version(lport->host),
 			 FC_VERSION_STRING_SIZE,
 			 "%s",
-			 fdmi.hardware_version);
+			 fdmi->hardware_version);
 		snprintf(fc_host_driver_version(lport->host),
 			 FC_VERSION_STRING_SIZE,
 			 "%s",
-			 fdmi.driver_version);
+			 fdmi->driver_version);
 		snprintf(fc_host_optionrom_version(lport->host),
 			 FC_VERSION_STRING_SIZE,
 			 "%s",
-			 fdmi.optionrom_version);
+			 fdmi->optionrom_version);
 		snprintf(fc_host_firmware_version(lport->host),
 			 FC_VERSION_STRING_SIZE,
 			 "%s",
-			 fdmi.firmware_version);
+			 fdmi->firmware_version);
 
 		/* Enable FDMI lport states */
 		lport->fdmi_enabled = 1;
+		kfree(fdmi);
 	} else {
 		lport->fdmi_enabled = 0;
 		printk(KERN_INFO "fcoe: No FDMI support.\n");
@@ -1978,7 +1982,7 @@ static int fcoe_device_notification(stru
 {
 	struct fcoe_ctlr_device *cdev;
 	struct fc_lport *lport = NULL;
-	struct net_device *netdev = ptr;
+	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
 	struct fcoe_ctlr *ctlr;
 	struct fcoe_interface *fcoe;
 	struct fcoe_port *port;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/fcoe/fcoe_ctlr.c linux-libre-3.11-rc7-gnu/drivers/scsi/fcoe/fcoe_ctlr.c
--- linux-libre-3.10-gnu/drivers/scsi/fcoe/fcoe_ctlr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/fcoe/fcoe_ctlr.c	2013-08-25 20:43:22.000000000 -0400
@@ -2090,7 +2090,11 @@ static struct fc_rport_operations fcoe_c
  */
 static void fcoe_ctlr_disc_stop_locked(struct fc_lport *lport)
 {
+	struct fc_rport_priv *rdata;
+
 	mutex_lock(&lport->disc.disc_mutex);
+	list_for_each_entry_rcu(rdata, &lport->disc.rports, peers)
+		lport->tt.rport_logoff(rdata);
 	lport->disc.disc_callback = NULL;
 	mutex_unlock(&lport->disc.disc_mutex);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/fcoe/fcoe_sysfs.c linux-libre-3.11-rc7-gnu/drivers/scsi/fcoe/fcoe_sysfs.c
--- linux-libre-3.10-gnu/drivers/scsi/fcoe/fcoe_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/fcoe/fcoe_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -507,7 +507,7 @@ static const struct attribute_group *fco
 	NULL,
 };
 
-struct bus_type fcoe_bus_type;
+static struct bus_type fcoe_bus_type;
 
 static int fcoe_bus_match(struct device *dev,
 			  struct device_driver *drv)
@@ -541,25 +541,25 @@ static void fcoe_fcf_device_release(stru
 	kfree(fcf);
 }
 
-struct device_type fcoe_ctlr_device_type = {
+static struct device_type fcoe_ctlr_device_type = {
 	.name = "fcoe_ctlr",
 	.groups = fcoe_ctlr_attr_groups,
 	.release = fcoe_ctlr_device_release,
 };
 
-struct device_type fcoe_fcf_device_type = {
+static struct device_type fcoe_fcf_device_type = {
 	.name = "fcoe_fcf",
 	.groups = fcoe_fcf_attr_groups,
 	.release = fcoe_fcf_device_release,
 };
 
-struct bus_attribute fcoe_bus_attr_group[] = {
+static struct bus_attribute fcoe_bus_attr_group[] = {
 	__ATTR(ctlr_create, S_IWUSR, NULL, fcoe_ctlr_create_store),
 	__ATTR(ctlr_destroy, S_IWUSR, NULL, fcoe_ctlr_destroy_store),
 	__ATTR_NULL
 };
 
-struct bus_type fcoe_bus_type = {
+static struct bus_type fcoe_bus_type = {
 	.name = "fcoe",
 	.match = &fcoe_bus_match,
 	.bus_attrs = fcoe_bus_attr_group,
@@ -569,7 +569,7 @@ struct bus_type fcoe_bus_type = {
  * fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue
  * @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed
  */
-void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
+static void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
 {
 	if (!fcoe_ctlr_work_q(ctlr)) {
 		printk(KERN_ERR
@@ -590,8 +590,8 @@ void fcoe_ctlr_device_flush_work(struct
  * Return value:
  *	1 on success / 0 already queued / < 0 for error
  */
-int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
-			       struct work_struct *work)
+static int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
+				       struct work_struct *work)
 {
 	if (unlikely(!fcoe_ctlr_work_q(ctlr))) {
 		printk(KERN_ERR
@@ -609,7 +609,7 @@ int fcoe_ctlr_device_queue_work(struct f
  * fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue
  * @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed
  */
-void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
+static void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
 {
 	if (!fcoe_ctlr_devloss_work_q(ctlr)) {
 		printk(KERN_ERR
@@ -631,9 +631,9 @@ void fcoe_ctlr_device_flush_devloss(stru
  * Return value:
  *	1 on success / 0 already queued / < 0 for error
  */
-int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr,
-				       struct delayed_work *work,
-				       unsigned long delay)
+static int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr,
+					       struct delayed_work *work,
+					       unsigned long delay)
 {
 	if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) {
 		printk(KERN_ERR
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/fcoe/fcoe_transport.c linux-libre-3.11-rc7-gnu/drivers/scsi/fcoe/fcoe_transport.c
--- linux-libre-3.10-gnu/drivers/scsi/fcoe/fcoe_transport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/fcoe/fcoe_transport.c	2013-08-25 20:43:22.000000000 -0400
@@ -180,24 +180,10 @@ void fcoe_ctlr_get_lesb(struct fcoe_ctlr
 {
 	struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev);
 	struct net_device *netdev = fcoe_get_netdev(fip->lp);
-	struct fcoe_fc_els_lesb *fcoe_lesb;
-	struct fc_els_lesb fc_lesb;
-
-	__fcoe_get_lesb(fip->lp, &fc_lesb, netdev);
-	fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb);
+	struct fc_els_lesb *fc_lesb;
 
-	ctlr_dev->lesb.lesb_link_fail =
-		ntohl(fcoe_lesb->lesb_link_fail);
-	ctlr_dev->lesb.lesb_vlink_fail =
-		ntohl(fcoe_lesb->lesb_vlink_fail);
-	ctlr_dev->lesb.lesb_miss_fka =
-		ntohl(fcoe_lesb->lesb_miss_fka);
-	ctlr_dev->lesb.lesb_symb_err =
-		ntohl(fcoe_lesb->lesb_symb_err);
-	ctlr_dev->lesb.lesb_err_block =
-		ntohl(fcoe_lesb->lesb_err_block);
-	ctlr_dev->lesb.lesb_fcs_error =
-		ntohl(fcoe_lesb->lesb_fcs_error);
+	fc_lesb = (struct fc_els_lesb *)(&ctlr_dev->lesb);
+	__fcoe_get_lesb(fip->lp, fc_lesb, netdev);
 }
 EXPORT_SYMBOL_GPL(fcoe_ctlr_get_lesb);
 
@@ -704,7 +690,7 @@ static struct net_device *fcoe_if_to_net
 static int libfcoe_device_notification(struct notifier_block *notifier,
 				    ulong event, void *ptr)
 {
-	struct net_device *netdev = ptr;
+	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
 
 	switch (event) {
 	case NETDEV_UNREGISTER:
@@ -721,7 +707,6 @@ ssize_t fcoe_ctlr_create_store(struct bu
 {
 	struct net_device *netdev = NULL;
 	struct fcoe_transport *ft = NULL;
-	struct fcoe_ctlr_device *ctlr_dev = NULL;
 	int rc = 0;
 	int err;
 
@@ -768,9 +753,8 @@ ssize_t fcoe_ctlr_create_store(struct bu
 		goto out_putdev;
 	}
 
-	LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n",
-			      ft->name, (ctlr_dev) ? "succeeded" : "failed",
-			      netdev->name);
+	LIBFCOE_TRANSPORT_DBG("transport %s succeeded to create fcoe on %s.\n",
+			      ft->name, netdev->name);
 
 out_putdev:
 	dev_put(netdev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/FlashPoint.c linux-libre-3.11-rc7-gnu/drivers/scsi/FlashPoint.c
--- linux-libre-3.10-gnu/drivers/scsi/FlashPoint.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/FlashPoint.c	2013-08-25 20:43:22.000000000 -0400
@@ -29,27 +29,27 @@ struct sccb;
 typedef void (*CALL_BK_FN) (struct sccb *);
 
 struct sccb_mgr_info {
-	unsigned long si_baseaddr;
+	u32 si_baseaddr;
 	unsigned char si_present;
 	unsigned char si_intvect;
 	unsigned char si_id;
 	unsigned char si_lun;
-	unsigned short si_fw_revision;
-	unsigned short si_per_targ_init_sync;
-	unsigned short si_per_targ_fast_nego;
-	unsigned short si_per_targ_ultra_nego;
-	unsigned short si_per_targ_no_disc;
-	unsigned short si_per_targ_wide_nego;
-	unsigned short si_flags;
+	u16 si_fw_revision;
+	u16 si_per_targ_init_sync;
+	u16 si_per_targ_fast_nego;
+	u16 si_per_targ_ultra_nego;
+	u16 si_per_targ_no_disc;
+	u16 si_per_targ_wide_nego;
+	u16 si_flags;
 	unsigned char si_card_family;
 	unsigned char si_bustype;
 	unsigned char si_card_model[3];
 	unsigned char si_relative_cardnum;
 	unsigned char si_reserved[4];
-	unsigned long si_OS_reserved;
+	u32 si_OS_reserved;
 	unsigned char si_XlatInfo[4];
-	unsigned long si_reserved2[5];
-	unsigned long si_secondary_range;
+	u32 si_reserved2[5];
+	u32 si_secondary_range;
 };
 
 #define SCSI_PARITY_ENA		  0x0001
@@ -70,14 +70,14 @@ struct sccb_mgr_info {
  * The UCB Manager treats the SCCB as it's 'native hardware structure' 
  */
 
-#pragma pack(1)
+/*#pragma pack(1)*/
 struct sccb {
 	unsigned char OperationCode;
 	unsigned char ControlByte;
 	unsigned char CdbLength;
 	unsigned char RequestSenseLength;
-	unsigned long DataLength;
-	unsigned long DataPointer;
+	u32 DataLength;
+	void *DataPointer;
 	unsigned char CcbRes[2];
 	unsigned char HostStatus;
 	unsigned char TargetStatus;
@@ -86,32 +86,32 @@ struct sccb {
 	unsigned char Cdb[12];
 	unsigned char CcbRes1;
 	unsigned char Reserved1;
-	unsigned long Reserved2;
-	unsigned long SensePointer;
+	u32 Reserved2;
+	u32 SensePointer;
 
 	CALL_BK_FN SccbCallback;	/* VOID (*SccbCallback)(); */
-	unsigned long SccbIOPort;	/* Identifies board base port */
+	u32 SccbIOPort;			/* Identifies board base port */
 	unsigned char SccbStatus;
 	unsigned char SCCBRes2;
-	unsigned short SccbOSFlags;
+	u16 SccbOSFlags;
 
-	unsigned long Sccb_XferCnt;	/* actual transfer count */
-	unsigned long Sccb_ATC;
-	unsigned long SccbVirtDataPtr;	/* virtual addr for OS/2 */
-	unsigned long Sccb_res1;
-	unsigned short Sccb_MGRFlags;
-	unsigned short Sccb_sgseg;
+	u32 Sccb_XferCnt;	/* actual transfer count */
+	u32 Sccb_ATC;
+	u32 SccbVirtDataPtr;	/* virtual addr for OS/2 */
+	u32 Sccb_res1;
+	u16 Sccb_MGRFlags;
+	u16 Sccb_sgseg;
 	unsigned char Sccb_scsimsg;	/* identify msg for selection */
 	unsigned char Sccb_tag;
 	unsigned char Sccb_scsistat;
 	unsigned char Sccb_idmsg;	/* image of last msg in */
 	struct sccb *Sccb_forwardlink;
 	struct sccb *Sccb_backlink;
-	unsigned long Sccb_savedATC;
+	u32 Sccb_savedATC;
 	unsigned char Save_Cdb[6];
 	unsigned char Save_CdbLen;
 	unsigned char Sccb_XferState;
-	unsigned long Sccb_SGoffset;
+	u32 Sccb_SGoffset;
 };
 
 #pragma pack()
@@ -223,15 +223,21 @@ struct sccb_mgr_tar_info {
 };
 
 struct nvram_info {
-	unsigned char niModel;	/* Model No. of card */
-	unsigned char niCardNo;	/* Card no. */
-	unsigned long niBaseAddr;	/* Port Address of card */
-	unsigned char niSysConf;	/* Adapter Configuration byte - Byte 16 of eeprom map */
-	unsigned char niScsiConf;	/* SCSI Configuration byte - Byte 17 of eeprom map */
-	unsigned char niScamConf;	/* SCAM Configuration byte - Byte 20 of eeprom map */
-	unsigned char niAdapId;	/* Host Adapter ID - Byte 24 of eerpom map */
-	unsigned char niSyncTbl[MAX_SCSI_TAR / 2];	/* Sync/Wide byte of targets */
-	unsigned char niScamTbl[MAX_SCSI_TAR][4];	/* Compressed Scam name string of Targets */
+	unsigned char niModel;		/* Model No. of card */
+	unsigned char niCardNo;		/* Card no. */
+	u32 niBaseAddr;			/* Port Address of card */
+	unsigned char niSysConf;	/* Adapter Configuration byte -
+					   Byte 16 of eeprom map */
+	unsigned char niScsiConf;	/* SCSI Configuration byte -
+					   Byte 17 of eeprom map */
+	unsigned char niScamConf;	/* SCAM Configuration byte -
+					   Byte 20 of eeprom map */
+	unsigned char niAdapId;		/* Host Adapter ID -
+					   Byte 24 of eerpom map */
+	unsigned char niSyncTbl[MAX_SCSI_TAR / 2];	/* Sync/Wide byte
+							   of targets */
+	unsigned char niScamTbl[MAX_SCSI_TAR][4];	/* Compressed Scam name
+							   string of Targets */
 };
 
 #define	MODEL_LT		1
@@ -243,7 +249,7 @@ struct sccb_card {
 	struct sccb *currentSCCB;
 	struct sccb_mgr_info *cardInfo;
 
-	unsigned long ioPort;
+	u32 ioPort;
 
 	unsigned short cmdCounter;
 	unsigned char discQCount;
@@ -780,37 +786,37 @@ typedef struct SCCBscam_info {
 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
                              (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
 
-static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card,
+static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
 				 unsigned char syncFlag);
-static void FPT_ssel(unsigned long port, unsigned char p_card);
-static void FPT_sres(unsigned long port, unsigned char p_card,
+static void FPT_ssel(u32 port, unsigned char p_card);
+static void FPT_sres(u32 port, unsigned char p_card,
 		     struct sccb_card *pCurrCard);
-static void FPT_shandem(unsigned long port, unsigned char p_card,
+static void FPT_shandem(u32 port, unsigned char p_card,
 			struct sccb *pCurrSCCB);
-static void FPT_stsyncn(unsigned long port, unsigned char p_card);
-static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse,
+static void FPT_stsyncn(u32 port, unsigned char p_card);
+static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
 			unsigned char offset);
-static void FPT_sssyncv(unsigned long p_port, unsigned char p_id,
+static void FPT_sssyncv(u32 p_port, unsigned char p_id,
 			unsigned char p_sync_value,
 			struct sccb_mgr_tar_info *currTar_Info);
-static void FPT_sresb(unsigned long port, unsigned char p_card);
-static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
-static void FPT_schkdd(unsigned long port, unsigned char p_card);
-static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
-static void FPT_WrStack(unsigned long portBase, unsigned char index,
+static void FPT_sresb(u32 port, unsigned char p_card);
+static void FPT_sxfrp(u32 p_port, unsigned char p_card);
+static void FPT_schkdd(u32 port, unsigned char p_card);
+static unsigned char FPT_RdStack(u32 port, unsigned char index);
+static void FPT_WrStack(u32 portBase, unsigned char index,
 			unsigned char data);
-static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
+static unsigned char FPT_ChkIfChipInitialized(u32 ioPort);
 
-static void FPT_SendMsg(unsigned long port, unsigned char message);
+static void FPT_SendMsg(u32 port, unsigned char message);
 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
 				   unsigned char error_code);
 
 static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
 static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
 
-static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
-static void FPT_stwidn(unsigned long port, unsigned char p_card);
-static void FPT_siwidr(unsigned long port, unsigned char width);
+static unsigned char FPT_siwidn(u32 port, unsigned char p_card);
+static void FPT_stwidn(u32 port, unsigned char p_card);
+static void FPT_siwidr(u32 port, unsigned char width);
 
 static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
 				unsigned char p_card);
@@ -827,45 +833,45 @@ static void FPT_utilUpdateResidual(struc
 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
 
-static void FPT_Wait1Second(unsigned long p_port);
-static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
-static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode);
-static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data,
+static void FPT_Wait1Second(u32 p_port);
+static void FPT_Wait(u32 p_port, unsigned char p_delay);
+static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode);
+static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
 			    unsigned short ee_addr);
-static unsigned short FPT_utilEERead(unsigned long p_port,
+static unsigned short FPT_utilEERead(u32 p_port,
 				     unsigned short ee_addr);
-static unsigned short FPT_utilEEReadOrg(unsigned long p_port,
+static unsigned short FPT_utilEEReadOrg(u32 p_port,
 					unsigned short ee_addr);
-static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd,
+static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
 				  unsigned short ee_addr);
 
-static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
-static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
-static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
-static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
-static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
-static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
-static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
+static void FPT_phaseDataOut(u32 port, unsigned char p_card);
+static void FPT_phaseDataIn(u32 port, unsigned char p_card);
+static void FPT_phaseCommand(u32 port, unsigned char p_card);
+static void FPT_phaseStatus(u32 port, unsigned char p_card);
+static void FPT_phaseMsgOut(u32 port, unsigned char p_card);
+static void FPT_phaseMsgIn(u32 port, unsigned char p_card);
+static void FPT_phaseIllegal(u32 port, unsigned char p_card);
 
-static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
-static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
-static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
+static void FPT_phaseDecode(u32 port, unsigned char p_card);
+static void FPT_phaseChkFifo(u32 port, unsigned char p_card);
+static void FPT_phaseBusFree(u32 p_port, unsigned char p_card);
 
-static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
-static void FPT_BusMasterInit(unsigned long p_port);
-static void FPT_DiagEEPROM(unsigned long p_port);
+static void FPT_XbowInit(u32 port, unsigned char scamFlg);
+static void FPT_BusMasterInit(u32 p_port);
+static void FPT_DiagEEPROM(u32 p_port);
 
-static void FPT_dataXferProcessor(unsigned long port,
+static void FPT_dataXferProcessor(u32 port,
 				  struct sccb_card *pCurrCard);
-static void FPT_busMstrSGDataXferStart(unsigned long port,
+static void FPT_busMstrSGDataXferStart(u32 port,
 				       struct sccb *pCurrSCCB);
-static void FPT_busMstrDataXferStart(unsigned long port,
+static void FPT_busMstrDataXferStart(u32 port,
 				     struct sccb *pCurrSCCB);
-static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card,
+static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
 				  struct sccb *pCurrSCCB);
 static void FPT_hostDataXferRestart(struct sccb *currSCCB);
 
-static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port,
+static unsigned char FPT_SccbMgr_bad_isr(u32 p_port,
 					 unsigned char p_card,
 					 struct sccb_card *pCurrCard,
 					 unsigned short p_int);
@@ -879,28 +885,28 @@ static void FPT_SccbMgrTableInitTarget(u
 static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
 		      unsigned char p_power_up);
 
-static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
-static void FPT_scbusf(unsigned long p_port);
-static void FPT_scsel(unsigned long p_port);
-static void FPT_scasid(unsigned char p_card, unsigned long p_port);
-static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
-static unsigned char FPT_scsendi(unsigned long p_port,
+static int FPT_scarb(u32 p_port, unsigned char p_sel_type);
+static void FPT_scbusf(u32 p_port);
+static void FPT_scsel(u32 p_port);
+static void FPT_scasid(unsigned char p_card, u32 p_port);
+static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data);
+static unsigned char FPT_scsendi(u32 p_port,
 				 unsigned char p_id_string[]);
-static unsigned char FPT_sciso(unsigned long p_port,
+static unsigned char FPT_sciso(u32 p_port,
 			       unsigned char p_id_string[]);
-static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
-static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
+static void FPT_scwirod(u32 p_port, unsigned char p_data_bit);
+static void FPT_scwiros(u32 p_port, unsigned char p_data_bit);
 static unsigned char FPT_scvalq(unsigned char p_quintet);
-static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
-static void FPT_scwtsel(unsigned long p_port);
-static void FPT_inisci(unsigned char p_card, unsigned long p_port,
+static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id);
+static void FPT_scwtsel(u32 p_port);
+static void FPT_inisci(unsigned char p_card, u32 p_port,
 		       unsigned char p_our_id);
-static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
+static void FPT_scsavdi(unsigned char p_card, u32 p_port);
 static unsigned char FPT_scmachid(unsigned char p_card,
 				  unsigned char p_id_string[]);
 
-static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
-static void FPT_autoLoadDefaultMap(unsigned long p_port);
+static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card);
+static void FPT_autoLoadDefaultMap(u32 p_port);
 
 static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
     { {{0}} };
@@ -918,7 +924,7 @@ static unsigned char FPT_scamHAString[]
 
 static unsigned short FPT_default_intena = 0;
 
-static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char) = {
+static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = {
 0};
 
 /*---------------------------------------------------------------------
@@ -935,7 +941,7 @@ static int FlashPoint_ProbeHostAdapter(s
 
 	unsigned char i, j, id, ScamFlg;
 	unsigned short temp, temp2, temp3, temp4, temp5, temp6;
-	unsigned long ioport;
+	u32 ioport;
 	struct nvram_info *pCurrNvRam;
 
 	ioport = pCardInfo->si_baseaddr;
@@ -1201,23 +1207,21 @@ static int FlashPoint_ProbeHostAdapter(s
  *
  *---------------------------------------------------------------------*/
 
-static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
+static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
 							 *pCardInfo)
 {
 	struct sccb_card *CurrCard = NULL;
 	struct nvram_info *pCurrNvRam;
 	unsigned char i, j, thisCard, ScamFlg;
 	unsigned short temp, sync_bit_map, id;
-	unsigned long ioport;
+	u32 ioport;
 
 	ioport = pCardInfo->si_baseaddr;
 
 	for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
 
-		if (thisCard == MAX_CARDS) {
-
-			return FAILURE;
-		}
+		if (thisCard == MAX_CARDS)
+			return (void *)FAILURE;
 
 		if (FPT_BL_Card[thisCard].ioPort == ioport) {
 
@@ -1384,16 +1388,16 @@ static unsigned long FlashPoint_Hardware
 		   (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
 				   SCCB_MGR_PRESENT));
 
-	return (unsigned long)CurrCard;
+	return (void *)CurrCard;
 }
 
-static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
+static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
 {
 	unsigned char i;
-	unsigned long portBase;
-	unsigned long regOffset;
-	unsigned long scamData;
-	unsigned long *pScamTbl;
+	u32 portBase;
+	u32 regOffset;
+	u32 scamData;
+	u32 *pScamTbl;
 	struct nvram_info *pCurrNvRam;
 
 	pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
@@ -1414,7 +1418,7 @@ static void FlashPoint_ReleaseHostAdapte
 
 		for (i = 0; i < MAX_SCSI_TAR; i++) {
 			regOffset = hp_aramBase + 64 + i * 4;
-			pScamTbl = (unsigned long *)&pCurrNvRam->niScamTbl[i];
+			pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
 			scamData = *pScamTbl;
 			WR_HARP32(portBase, regOffset, scamData);
 		}
@@ -1427,10 +1431,10 @@ static void FlashPoint_ReleaseHostAdapte
 static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
 {
 	unsigned char i;
-	unsigned long portBase;
-	unsigned long regOffset;
-	unsigned long scamData;
-	unsigned long *pScamTbl;
+	u32 portBase;
+	u32 regOffset;
+	u32 scamData;
+	u32 *pScamTbl;
 
 	pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
 	pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
@@ -1447,26 +1451,25 @@ static void FPT_RNVRamData(struct nvram_
 	for (i = 0; i < MAX_SCSI_TAR; i++) {
 		regOffset = hp_aramBase + 64 + i * 4;
 		RD_HARP32(portBase, regOffset, scamData);
-		pScamTbl = (unsigned long *)&pNvRamInfo->niScamTbl[i];
+		pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
 		*pScamTbl = scamData;
 	}
 
 }
 
-static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
+static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
 {
 	WR_HARPOON(portBase + hp_stack_addr, index);
 	return RD_HARPOON(portBase + hp_stack_data);
 }
 
-static void FPT_WrStack(unsigned long portBase, unsigned char index,
-			unsigned char data)
+static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
 {
 	WR_HARPOON(portBase + hp_stack_addr, index);
 	WR_HARPOON(portBase + hp_stack_data, data);
 }
 
-static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
+static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
 {
 	if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
 		return 0;
@@ -1489,15 +1492,16 @@ static unsigned char FPT_ChkIfChipInitia
  *              callback function.
  *
  *---------------------------------------------------------------------*/
-static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb)
+static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
 {
-	unsigned long ioport;
+	u32 ioport;
 	unsigned char thisCard, lun;
 	struct sccb *pSaveSccb;
 	CALL_BK_FN callback;
+	struct sccb_card *pCurrCard = curr_card;
 
-	thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
-	ioport = ((struct sccb_card *)pCurrCard)->ioPort;
+	thisCard = pCurrCard->cardIndex;
+	ioport = pCurrCard->ioPort;
 
 	if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
 
@@ -1512,18 +1516,18 @@ static void FlashPoint_StartCCB(unsigned
 
 	FPT_sinits(p_Sccb, thisCard);
 
-	if (!((struct sccb_card *)pCurrCard)->cmdCounter) {
+	if (!pCurrCard->cmdCounter) {
 		WR_HARPOON(ioport + hp_semaphore,
 			   (RD_HARPOON(ioport + hp_semaphore)
 			    | SCCB_MGR_ACTIVE));
 
-		if (((struct sccb_card *)pCurrCard)->globalFlags & F_GREEN_PC) {
+		if (pCurrCard->globalFlags & F_GREEN_PC) {
 			WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
 			WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
 		}
 	}
 
-	((struct sccb_card *)pCurrCard)->cmdCounter++;
+	pCurrCard->cmdCounter++;
 
 	if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
 
@@ -1532,10 +1536,10 @@ static void FlashPoint_StartCCB(unsigned
 			    | TICKLE_ME));
 		if (p_Sccb->OperationCode == RESET_COMMAND) {
 			pSaveSccb =
-			    ((struct sccb_card *)pCurrCard)->currentSCCB;
-			((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb;
+			    pCurrCard->currentSCCB;
+			pCurrCard->currentSCCB = p_Sccb;
 			FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
-			((struct sccb_card *)pCurrCard)->currentSCCB =
+			pCurrCard->currentSCCB =
 			    pSaveSccb;
 		} else {
 			FPT_queueAddSccb(p_Sccb, thisCard);
@@ -1546,10 +1550,10 @@ static void FlashPoint_StartCCB(unsigned
 
 		if (p_Sccb->OperationCode == RESET_COMMAND) {
 			pSaveSccb =
-			    ((struct sccb_card *)pCurrCard)->currentSCCB;
-			((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb;
+			    pCurrCard->currentSCCB;
+			pCurrCard->currentSCCB = p_Sccb;
 			FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
-			((struct sccb_card *)pCurrCard)->currentSCCB =
+			pCurrCard->currentSCCB =
 			    pSaveSccb;
 		} else {
 			FPT_queueAddSccb(p_Sccb, thisCard);
@@ -1560,34 +1564,29 @@ static void FlashPoint_StartCCB(unsigned
 
 		MDISABLE_INT(ioport);
 
-		if ((((struct sccb_card *)pCurrCard)->globalFlags & F_CONLUN_IO)
-		    &&
+		if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
 		    ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
 		      TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
 			lun = p_Sccb->Lun;
 		else
 			lun = 0;
-		if ((((struct sccb_card *)pCurrCard)->currentSCCB == NULL) &&
+		if ((pCurrCard->currentSCCB == NULL) &&
 		    (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
 		    && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
 			== 0)) {
 
-			((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb;
+			pCurrCard->currentSCCB = p_Sccb;
 			FPT_ssel(p_Sccb->SccbIOPort, thisCard);
 		}
 
 		else {
 
 			if (p_Sccb->OperationCode == RESET_COMMAND) {
-				pSaveSccb =
-				    ((struct sccb_card *)pCurrCard)->
-				    currentSCCB;
-				((struct sccb_card *)pCurrCard)->currentSCCB =
-				    p_Sccb;
+				pSaveSccb = pCurrCard->currentSCCB;
+				pCurrCard->currentSCCB = p_Sccb;
 				FPT_queueSelectFail(&FPT_BL_Card[thisCard],
 						    thisCard);
-				((struct sccb_card *)pCurrCard)->currentSCCB =
-				    pSaveSccb;
+				pCurrCard->currentSCCB = pSaveSccb;
 			} else {
 				FPT_queueAddSccb(p_Sccb, thisCard);
 			}
@@ -1607,9 +1606,9 @@ static void FlashPoint_StartCCB(unsigned
  *              callback function.
  *
  *---------------------------------------------------------------------*/
-static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb *p_Sccb)
+static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
 {
-	unsigned long ioport;
+	u32 ioport;
 
 	unsigned char thisCard;
 	CALL_BK_FN callback;
@@ -1715,9 +1714,9 @@ static int FlashPoint_AbortCCB(unsigned
  *              interrupt for this card and disable the IRQ Pin if so.
  *
  *---------------------------------------------------------------------*/
-static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
+static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
 {
-	unsigned long ioport;
+	u32 ioport;
 
 	ioport = ((struct sccb_card *)pCurrCard)->ioPort;
 
@@ -1739,38 +1738,36 @@ static unsigned char FlashPoint_Interrup
  *              us.
  *
  *---------------------------------------------------------------------*/
-static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
+static int FlashPoint_HandleInterrupt(void *pcard)
 {
 	struct sccb *currSCCB;
 	unsigned char thisCard, result, bm_status, bm_int_st;
 	unsigned short hp_int;
 	unsigned char i, target;
-	unsigned long ioport;
+	struct sccb_card *pCurrCard = pcard;
+	u32 ioport;
 
-	thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
-	ioport = ((struct sccb_card *)pCurrCard)->ioPort;
+	thisCard = pCurrCard->cardIndex;
+	ioport = pCurrCard->ioPort;
 
 	MDISABLE_INT(ioport);
 
 	if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON)
-		bm_status =
-		    RD_HARPOON(ioport +
-			       hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
+		bm_status = RD_HARPOON(ioport + hp_ext_status) &
+					(unsigned char)BAD_EXT_STATUS;
 	else
 		bm_status = 0;
 
 	WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
 
-	while ((hp_int =
-		RDW_HARPOON((ioport +
-			     hp_intstat)) & FPT_default_intena) | bm_status) {
+	while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
+				FPT_default_intena) | bm_status) {
 
-		currSCCB = ((struct sccb_card *)pCurrCard)->currentSCCB;
+		currSCCB = pCurrCard->currentSCCB;
 
 		if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
 			result =
-			    FPT_SccbMgr_bad_isr(ioport, thisCard,
-						((struct sccb_card *)pCurrCard),
+			    FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
 						hp_int);
 			WRW_HARPOON((ioport + hp_intstat),
 				    (FIFO | TIMEOUT | RESET | SCAM_SEL));
@@ -1796,8 +1793,7 @@ static int FlashPoint_HandleInterrupt(un
 					(BUS_FREE | RSEL))) ;
 			}
 
-			if (((struct sccb_card *)pCurrCard)->
-			    globalFlags & F_HOST_XFER_ACT)
+			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
 
 				FPT_phaseChkFifo(ioport, thisCard);
 
@@ -1813,14 +1809,11 @@ static int FlashPoint_HandleInterrupt(un
 
 		else if (hp_int & ITAR_DISC) {
 
-			if (((struct sccb_card *)pCurrCard)->
-			    globalFlags & F_HOST_XFER_ACT) {
-
+			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
 				FPT_phaseChkFifo(ioport, thisCard);
 
-			}
-
-			if (RD_HARPOON(ioport + hp_gp_reg_1) == SMSAVE_DATA_PTR) {
+			if (RD_HARPOON(ioport + hp_gp_reg_1) ==
+					SMSAVE_DATA_PTR) {
 
 				WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
 				currSCCB->Sccb_XferState |= F_NO_DATA_YET;
@@ -1859,8 +1852,7 @@ static int FlashPoint_HandleInterrupt(un
 			WRW_HARPOON((ioport + hp_intstat),
 				    (BUS_FREE | ITAR_DISC));
 
-			((struct sccb_card *)pCurrCard)->globalFlags |=
-			    F_NEW_SCCB_CMD;
+			pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
 
 		}
 
@@ -1870,10 +1862,8 @@ static int FlashPoint_HandleInterrupt(un
 				    (PROG_HLT | RSEL | PHASE | BUS_FREE));
 
 			if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
-				if (((struct sccb_card *)pCurrCard)->
-				    globalFlags & F_HOST_XFER_ACT) {
+				if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
 					FPT_phaseChkFifo(ioport, thisCard);
-				}
 
 				if (RD_HARPOON(ioport + hp_gp_reg_1) ==
 				    SMSAVE_DATA_PTR) {
@@ -1890,8 +1880,7 @@ static int FlashPoint_HandleInterrupt(un
 				FPT_queueDisconnect(currSCCB, thisCard);
 			}
 
-			FPT_sres(ioport, thisCard,
-				 ((struct sccb_card *)pCurrCard));
+			FPT_sres(ioport, thisCard, pCurrCard);
 			FPT_phaseDecode(ioport, thisCard);
 
 		}
@@ -1948,8 +1937,7 @@ static int FlashPoint_HandleInterrupt(un
 
 			WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
 
-			if (((struct sccb_card *)pCurrCard)->
-			    globalFlags & F_HOST_XFER_ACT) {
+			if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
 
 				FPT_hostDataXferAbort(ioport, thisCard,
 						      currSCCB);
@@ -1961,27 +1949,19 @@ static int FlashPoint_HandleInterrupt(un
 		else if (hp_int & ITICKLE) {
 
 			WRW_HARPOON((ioport + hp_intstat), ITICKLE);
-			((struct sccb_card *)pCurrCard)->globalFlags |=
-			    F_NEW_SCCB_CMD;
+			pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
 		}
 
 		if (((struct sccb_card *)pCurrCard)->
 		    globalFlags & F_NEW_SCCB_CMD) {
 
-			((struct sccb_card *)pCurrCard)->globalFlags &=
-			    ~F_NEW_SCCB_CMD;
-
-			if (((struct sccb_card *)pCurrCard)->currentSCCB ==
-			    NULL) {
+			pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
 
-				FPT_queueSearchSelect(((struct sccb_card *)
-						       pCurrCard), thisCard);
-			}
+			if (pCurrCard->currentSCCB == NULL)
+				FPT_queueSearchSelect(pCurrCard, thisCard);
 
-			if (((struct sccb_card *)pCurrCard)->currentSCCB !=
-			    NULL) {
-				((struct sccb_card *)pCurrCard)->globalFlags &=
-				    ~F_NEW_SCCB_CMD;
+			if (pCurrCard->currentSCCB != NULL) {
+				pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
 				FPT_ssel(ioport, thisCard);
 			}
 
@@ -2006,8 +1986,7 @@ static int FlashPoint_HandleInterrupt(un
  *              processing time.
  *
  *---------------------------------------------------------------------*/
-static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port,
-					 unsigned char p_card,
+static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
 					 struct sccb_card *pCurrCard,
 					 unsigned short p_int)
 {
@@ -2254,7 +2233,7 @@ static void FPT_SccbMgrTableInitTarget(u
  *
  *---------------------------------------------------------------------*/
 
-static unsigned char FPT_sfm(unsigned long port, struct sccb *pCurrSCCB)
+static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
 {
 	unsigned char message;
 	unsigned short TimeOutLoop;
@@ -2322,12 +2301,12 @@ static unsigned char FPT_sfm(unsigned lo
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_ssel(unsigned long port, unsigned char p_card)
+static void FPT_ssel(u32 port, unsigned char p_card)
 {
 
 	unsigned char auto_loaded, i, target, *theCCB;
 
-	unsigned long cdb_reg;
+	u32 cdb_reg;
 	struct sccb_card *CurrCard;
 	struct sccb *currSCCB;
 	struct sccb_mgr_tar_info *currTar_Info;
@@ -2621,7 +2600,7 @@ static void FPT_ssel(unsigned long port,
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_sres(unsigned long port, unsigned char p_card,
+static void FPT_sres(u32 port, unsigned char p_card,
 		     struct sccb_card *pCurrCard)
 {
 
@@ -2857,7 +2836,7 @@ static void FPT_sres(unsigned long port,
 	       (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
 }
 
-static void FPT_SendMsg(unsigned long port, unsigned char message)
+static void FPT_SendMsg(u32 port, unsigned char message)
 {
 	while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
 		if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
@@ -2904,8 +2883,7 @@ static void FPT_SendMsg(unsigned long po
  *              target device.
  *
  *---------------------------------------------------------------------*/
-static void FPT_sdecm(unsigned char message, unsigned long port,
-		      unsigned char p_card)
+static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
 {
 	struct sccb *currSCCB;
 	struct sccb_card *CurrCard;
@@ -3085,8 +3063,7 @@ static void FPT_sdecm(unsigned char mess
  * Description: Decide what to do with the extended message.
  *
  *---------------------------------------------------------------------*/
-static void FPT_shandem(unsigned long port, unsigned char p_card,
-			struct sccb *pCurrSCCB)
+static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
 {
 	unsigned char length, message;
 
@@ -3153,7 +3130,7 @@ static void FPT_shandem(unsigned long po
  *
  *---------------------------------------------------------------------*/
 
-static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card,
+static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
 				 unsigned char syncFlag)
 {
 	struct sccb *currSCCB;
@@ -3234,7 +3211,7 @@ static unsigned char FPT_sisyncn(unsigne
  *              necessary.
  *
  *---------------------------------------------------------------------*/
-static void FPT_stsyncn(unsigned long port, unsigned char p_card)
+static void FPT_stsyncn(u32 port, unsigned char p_card)
 {
 	unsigned char sync_msg, offset, sync_reg, our_sync_msg;
 	struct sccb *currSCCB;
@@ -3363,7 +3340,7 @@ static void FPT_stsyncn(unsigned long po
  * Description: Answer the targets sync message.
  *
  *---------------------------------------------------------------------*/
-static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse,
+static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
 			unsigned char offset)
 {
 	ARAM_ACCESS(port);
@@ -3394,7 +3371,7 @@ static void FPT_sisyncr(unsigned long po
  *
  *---------------------------------------------------------------------*/
 
-static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
+static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
 {
 	struct sccb *currSCCB;
 	struct sccb_mgr_tar_info *currTar_Info;
@@ -3449,7 +3426,7 @@ static unsigned char FPT_siwidn(unsigned
  *              necessary.
  *
  *---------------------------------------------------------------------*/
-static void FPT_stwidn(unsigned long port, unsigned char p_card)
+static void FPT_stwidn(u32 port, unsigned char p_card)
 {
 	unsigned char width;
 	struct sccb *currSCCB;
@@ -3520,7 +3497,7 @@ static void FPT_stwidn(unsigned long por
  * Description: Answer the targets Wide nego message.
  *
  *---------------------------------------------------------------------*/
-static void FPT_siwidr(unsigned long port, unsigned char width)
+static void FPT_siwidr(u32 port, unsigned char width)
 {
 	ARAM_ACCESS(port);
 	WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
@@ -3548,7 +3525,7 @@ static void FPT_siwidr(unsigned long por
  *              ID specified.
  *
  *---------------------------------------------------------------------*/
-static void FPT_sssyncv(unsigned long p_port, unsigned char p_id,
+static void FPT_sssyncv(u32 p_port, unsigned char p_id,
 			unsigned char p_sync_value,
 			struct sccb_mgr_tar_info *currTar_Info)
 {
@@ -3620,7 +3597,7 @@ static void FPT_sssyncv(unsigned long p_
  * Description: Reset the desired card's SCSI bus.
  *
  *---------------------------------------------------------------------*/
-static void FPT_sresb(unsigned long port, unsigned char p_card)
+static void FPT_sresb(u32 port, unsigned char p_card)
 {
 	unsigned char scsiID, i;
 
@@ -3713,7 +3690,7 @@ static void FPT_ssenss(struct sccb_card
 	currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
 	currSCCB->Cdb[5] = 0x00;
 
-	currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
+	currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
 
 	currSCCB->Sccb_ATC = 0x00;
 
@@ -3737,7 +3714,7 @@ static void FPT_ssenss(struct sccb_card
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
+static void FPT_sxfrp(u32 p_port, unsigned char p_card)
 {
 	unsigned char curr_phz;
 
@@ -3819,7 +3796,7 @@ static void FPT_sxfrp(unsigned long p_po
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_schkdd(unsigned long port, unsigned char p_card)
+static void FPT_schkdd(u32 port, unsigned char p_card)
 {
 	unsigned short TimeOutLoop;
 	unsigned char sPhase;
@@ -3998,10 +3975,10 @@ static void FPT_sinits(struct sccb *p_sc
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
+static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
 {
 	unsigned char phase_ref;
-	void (*phase) (unsigned long, unsigned char);
+	void (*phase) (u32, unsigned char);
 
 	DISABLE_AUTO(p_port);
 
@@ -4021,7 +3998,7 @@ static void FPT_phaseDecode(unsigned lon
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
+static void FPT_phaseDataOut(u32 port, unsigned char p_card)
 {
 
 	struct sccb *currSCCB;
@@ -4062,7 +4039,7 @@ static void FPT_phaseDataOut(unsigned lo
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
+static void FPT_phaseDataIn(u32 port, unsigned char p_card)
 {
 
 	struct sccb *currSCCB;
@@ -4106,10 +4083,10 @@ static void FPT_phaseDataIn(unsigned lon
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
+static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
 {
 	struct sccb *currSCCB;
-	unsigned long cdb_reg;
+	u32 cdb_reg;
 	unsigned char i;
 
 	currSCCB = FPT_BL_Card[p_card].currentSCCB;
@@ -4157,7 +4134,7 @@ static void FPT_phaseCommand(unsigned lo
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
+static void FPT_phaseStatus(u32 port, unsigned char p_card)
 {
 	/* Start-up the automation to finish off this command and let the
 	   isr handle the interrupt for command complete when it comes in.
@@ -4178,7 +4155,7 @@ static void FPT_phaseStatus(unsigned lon
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
+static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
 {
 	unsigned char message, scsiID;
 	struct sccb *currSCCB;
@@ -4317,7 +4294,7 @@ static void FPT_phaseMsgOut(unsigned lon
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
+static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
 {
 	unsigned char message;
 	struct sccb *currSCCB;
@@ -4364,7 +4341,7 @@ static void FPT_phaseMsgIn(unsigned long
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
+static void FPT_phaseIllegal(u32 port, unsigned char p_card)
 {
 	struct sccb *currSCCB;
 
@@ -4390,9 +4367,9 @@ static void FPT_phaseIllegal(unsigned lo
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
+static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
 {
-	unsigned long xfercnt;
+	u32 xfercnt;
 	struct sccb *currSCCB;
 
 	currSCCB = FPT_BL_Card[p_card].currentSCCB;
@@ -4461,7 +4438,7 @@ static void FPT_phaseChkFifo(unsigned lo
  *              because of command complete or from a disconnect.
  *
  *---------------------------------------------------------------------*/
-static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
+static void FPT_phaseBusFree(u32 port, unsigned char p_card)
 {
 	struct sccb *currSCCB;
 
@@ -4557,9 +4534,9 @@ static void FPT_phaseBusFree(unsigned lo
  * Description: Load the Automation RAM with the defualt map values.
  *
  *---------------------------------------------------------------------*/
-static void FPT_autoLoadDefaultMap(unsigned long p_port)
+static void FPT_autoLoadDefaultMap(u32 p_port)
 {
-	unsigned long map_addr;
+	u32 map_addr;
 
 	ARAM_ACCESS(p_port);
 	map_addr = p_port + hp_aramBase;
@@ -4663,7 +4640,7 @@ static void FPT_autoLoadDefaultMap(unsig
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
+static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
 {
 	struct sccb *currSCCB;
 	unsigned char status_byte;
@@ -4936,8 +4913,7 @@ static void FPT_autoCmdCmplt(unsigned lo
  *              
  *---------------------------------------------------------------------*/
 
-static void FPT_dataXferProcessor(unsigned long port,
-				  struct sccb_card *pCurrCard)
+static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
 {
 	struct sccb *currSCCB;
 
@@ -4970,22 +4946,18 @@ static void FPT_dataXferProcessor(unsign
  * Description:
  *
  *---------------------------------------------------------------------*/
-static void FPT_busMstrSGDataXferStart(unsigned long p_port,
-				       struct sccb *pcurrSCCB)
+static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
 {
-	unsigned long count, addr, tmpSGCnt;
+	u32 count, addr, tmpSGCnt;
 	unsigned int sg_index;
 	unsigned char sg_count, i;
-	unsigned long reg_offset;
-
-	if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
-
-		count = ((unsigned long)HOST_RD_CMD) << 24;
-	}
+	u32 reg_offset;
+	struct blogic_sg_seg *segp;
 
-	else {
-		count = ((unsigned long)HOST_WRT_CMD) << 24;
-	}
+	if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
+		count = ((u32)HOST_RD_CMD) << 24;
+	else
+		count = ((u32)HOST_WRT_CMD) << 24;
 
 	sg_count = 0;
 	tmpSGCnt = 0;
@@ -4998,25 +4970,20 @@ static void FPT_busMstrSGDataXferStart(u
 	WR_HARPOON(p_port + hp_page_ctrl, i);
 
 	while ((sg_count < (unsigned char)SG_BUF_CNT) &&
-	       ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) <
-		pcurrSCCB->DataLength)) {
-
-		tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer) +
-			      (sg_index * 2));
-
-		count |= *(((unsigned long *)pcurrSCCB->DataPointer) +
-			   (sg_index * 2));
+			((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
+			pcurrSCCB->DataLength)) {
 
-		addr = *(((unsigned long *)pcurrSCCB->DataPointer) +
-			 ((sg_index * 2) + 1));
+		segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
+				sg_index;
+		tmpSGCnt += segp->segbytes;
+		count |= segp->segbytes;
+		addr = segp->segdata;
 
 		if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
-
 			addr +=
 			    ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
 			count =
 			    (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
-
 			tmpSGCnt = count & 0x00FFFFFFL;
 		}
 
@@ -5072,17 +5039,15 @@ static void FPT_busMstrSGDataXferStart(u
  * Description: 
  *
  *---------------------------------------------------------------------*/
-static void FPT_busMstrDataXferStart(unsigned long p_port,
-				     struct sccb *pcurrSCCB)
+static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
 {
-	unsigned long addr, count;
+	u32 addr, count;
 
 	if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
 
 		count = pcurrSCCB->Sccb_XferCnt;
 
-		addr =
-		    (unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
+		addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
 	}
 
 	else {
@@ -5127,7 +5092,7 @@ static void FPT_busMstrDataXferStart(uns
  *               command busy is also time out, it'll just give up.
  *
  *---------------------------------------------------------------------*/
-static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
+static unsigned char FPT_busMstrTimeOut(u32 p_port)
 {
 	unsigned long timeout;
 
@@ -5166,13 +5131,14 @@ static unsigned char FPT_busMstrTimeOut(
  * Description: Abort any in progress transfer.
  *
  *---------------------------------------------------------------------*/
-static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card,
+static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
 				  struct sccb *pCurrSCCB)
 {
 
 	unsigned long timeout;
 	unsigned long remain_cnt;
-	unsigned int sg_ptr;
+	u32 sg_ptr;
+	struct blogic_sg_seg *segp;
 
 	FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
 
@@ -5236,9 +5202,8 @@ static void FPT_hostDataXferAbort(unsign
 			    (unsigned int)(pCurrSCCB->DataLength /
 					   SG_ELEMENT_SIZE)) {
 
-				sg_ptr =
-				    (unsigned int)(pCurrSCCB->DataLength /
-						   SG_ELEMENT_SIZE);
+				sg_ptr = (u32)(pCurrSCCB->DataLength /
+							SG_ELEMENT_SIZE);
 			}
 
 			remain_cnt = pCurrSCCB->Sccb_XferCnt;
@@ -5246,23 +5211,13 @@ static void FPT_hostDataXferAbort(unsign
 			while (remain_cnt < 0x01000000L) {
 
 				sg_ptr--;
-
-				if (remain_cnt >
-				    (unsigned
-				     long)(*(((unsigned long *)pCurrSCCB->
-					      DataPointer) + (sg_ptr * 2)))) {
-
+				segp = (struct blogic_sg_seg *)(pCurrSCCB->
+						DataPointer) + (sg_ptr * 2);
+				if (remain_cnt > (unsigned long)segp->segbytes)
 					remain_cnt -=
-					    (unsigned
-					     long)(*(((unsigned long *)
-						      pCurrSCCB->DataPointer) +
-						     (sg_ptr * 2)));
-				}
-
-				else {
-
+						(unsigned long)segp->segbytes;
+				else
 					break;
-				}
 			}
 
 			if (remain_cnt < 0x01000000L) {
@@ -5418,23 +5373,18 @@ static void FPT_hostDataXferAbort(unsign
 
 			pCurrSCCB->Sccb_SGoffset = 0x00;
 
-			if ((unsigned long)(pCurrSCCB->Sccb_sgseg *
-					    SG_ELEMENT_SIZE) >=
-			    pCurrSCCB->DataLength) {
+			if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
+					pCurrSCCB->DataLength) {
 
 				pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
-
 				pCurrSCCB->Sccb_sgseg =
 				    (unsigned short)(pCurrSCCB->DataLength /
 						     SG_ELEMENT_SIZE);
-
 			}
 		}
 
 		else {
-
 			if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
-
 				pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
 		}
 	}
@@ -5454,21 +5404,22 @@ static void FPT_hostDataXferRestart(stru
 {
 	unsigned long data_count;
 	unsigned int sg_index;
-	unsigned long *sg_ptr;
+	struct blogic_sg_seg *segp;
 
 	if (currSCCB->Sccb_XferState & F_SG_XFER) {
 
 		currSCCB->Sccb_XferCnt = 0;
 
 		sg_index = 0xffff;	/*Index by long words into sg list. */
-		data_count = 0;	/*Running count of SG xfer counts. */
+		data_count = 0;		/*Running count of SG xfer counts. */
 
-		sg_ptr = (unsigned long *)currSCCB->DataPointer;
 
 		while (data_count < currSCCB->Sccb_ATC) {
 
 			sg_index++;
-			data_count += *(sg_ptr + (sg_index * 2));
+			segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
+						(sg_index * 2);
+			data_count += segp->segbytes;
 		}
 
 		if (data_count == currSCCB->Sccb_ATC) {
@@ -5504,7 +5455,7 @@ static void FPT_scini(unsigned char p_ca
 {
 
 	unsigned char loser, assigned_id;
-	unsigned long p_port;
+	u32 p_port;
 
 	unsigned char i, k, ScamFlg;
 	struct sccb_card *currCard;
@@ -5709,7 +5660,7 @@ static void FPT_scini(unsigned char p_ca
  *
  *---------------------------------------------------------------------*/
 
-static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
+static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
 {
 	if (p_sel_type == INIT_SELTD) {
 
@@ -5771,7 +5722,7 @@ static int FPT_scarb(unsigned long p_por
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_scbusf(unsigned long p_port)
+static void FPT_scbusf(u32 p_port)
 {
 	WR_HARPOON(p_port + hp_page_ctrl,
 		   (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
@@ -5803,7 +5754,7 @@ static void FPT_scbusf(unsigned long p_p
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_scasid(unsigned char p_card, unsigned long p_port)
+static void FPT_scasid(unsigned char p_card, u32 p_port)
 {
 	unsigned char temp_id_string[ID_STRING_LENGTH];
 
@@ -5880,7 +5831,7 @@ static void FPT_scasid(unsigned char p_c
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_scsel(unsigned long p_port)
+static void FPT_scsel(u32 p_port)
 {
 
 	WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
@@ -5914,7 +5865,7 @@ static void FPT_scsel(unsigned long p_po
  *
  *---------------------------------------------------------------------*/
 
-static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
+static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
 {
 	unsigned char curr_data, ret_data;
 
@@ -5964,8 +5915,7 @@ static unsigned char FPT_scxferc(unsigne
  *
  *---------------------------------------------------------------------*/
 
-static unsigned char FPT_scsendi(unsigned long p_port,
-				 unsigned char p_id_string[])
+static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
 {
 	unsigned char ret_data, byte_cnt, bit_cnt, defer;
 
@@ -6016,8 +5966,7 @@ static unsigned char FPT_scsendi(unsigne
  *
  *---------------------------------------------------------------------*/
 
-static unsigned char FPT_sciso(unsigned long p_port,
-			       unsigned char p_id_string[])
+static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
 {
 	unsigned char ret_data, the_data, byte_cnt, bit_cnt;
 
@@ -6075,7 +6024,7 @@ static unsigned char FPT_sciso(unsigned
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
+static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
 {
 	unsigned char i;
 
@@ -6102,7 +6051,7 @@ static void FPT_scwirod(unsigned long p_
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
+static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
 {
 	unsigned char i;
 
@@ -6154,7 +6103,7 @@ static unsigned char FPT_scvalq(unsigned
  *
  *---------------------------------------------------------------------*/
 
-static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
+static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
 {
 	unsigned long i;
 
@@ -6236,7 +6185,7 @@ static unsigned char FPT_scsell(unsigned
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_scwtsel(unsigned long p_port)
+static void FPT_scwtsel(u32 p_port)
 {
 	while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
 	}
@@ -6250,8 +6199,7 @@ static void FPT_scwtsel(unsigned long p_
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_inisci(unsigned char p_card, unsigned long p_port,
-		       unsigned char p_our_id)
+static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
 {
 	unsigned char i, k, max_id;
 	unsigned short ee_data;
@@ -6437,7 +6385,7 @@ static unsigned char FPT_scmachid(unsign
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
+static void FPT_scsavdi(unsigned char p_card, u32 p_port)
 {
 	unsigned char i, k, max_id;
 	unsigned short ee_data, sum_data;
@@ -6482,7 +6430,7 @@ static void FPT_scsavdi(unsigned char p_
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
+static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
 {
 	unsigned char i;
 
@@ -6531,7 +6479,7 @@ static void FPT_XbowInit(unsigned long p
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_BusMasterInit(unsigned long p_port)
+static void FPT_BusMasterInit(u32 p_port)
 {
 
 	WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
@@ -6558,7 +6506,7 @@ static void FPT_BusMasterInit(unsigned l
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_DiagEEPROM(unsigned long p_port)
+static void FPT_DiagEEPROM(u32 p_port)
 {
 	unsigned short index, temp, max_wd_cnt;
 
@@ -7206,7 +7154,7 @@ static void FPT_utilUpdateResidual(struc
 {
 	unsigned long partial_cnt;
 	unsigned int sg_index;
-	unsigned long *sg_ptr;
+	struct blogic_sg_seg *segp;
 
 	if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
 
@@ -7219,7 +7167,6 @@ static void FPT_utilUpdateResidual(struc
 
 		sg_index = p_SCCB->Sccb_sgseg;
 
-		sg_ptr = (unsigned long *)p_SCCB->DataPointer;
 
 		if (p_SCCB->Sccb_SGoffset) {
 
@@ -7229,8 +7176,9 @@ static void FPT_utilUpdateResidual(struc
 
 		while (((unsigned long)sg_index *
 			(unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
-
-			partial_cnt += *(sg_ptr + (sg_index * 2));
+			segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
+					(sg_index * 2);
+			partial_cnt += segp->segbytes;
 			sg_index++;
 		}
 
@@ -7251,7 +7199,7 @@ static void FPT_utilUpdateResidual(struc
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_Wait1Second(unsigned long p_port)
+static void FPT_Wait1Second(u32 p_port)
 {
 	unsigned char i;
 
@@ -7275,7 +7223,7 @@ static void FPT_Wait1Second(unsigned lon
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
+static void FPT_Wait(u32 p_port, unsigned char p_delay)
 {
 	unsigned char old_timer;
 	unsigned char green_flag;
@@ -7321,7 +7269,7 @@ static void FPT_Wait(unsigned long p_por
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode)
+static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
 {
 	unsigned char ee_value;
 
@@ -7350,7 +7298,7 @@ static void FPT_utilEEWriteOnOff(unsigne
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data,
+static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
 			    unsigned short ee_addr)
 {
 
@@ -7401,7 +7349,7 @@ static void FPT_utilEEWrite(unsigned lon
  *
  *---------------------------------------------------------------------*/
 
-static unsigned short FPT_utilEERead(unsigned long p_port,
+static unsigned short FPT_utilEERead(u32 p_port,
 				     unsigned short ee_addr)
 {
 	unsigned short i, ee_data1, ee_data2;
@@ -7431,8 +7379,7 @@ static unsigned short FPT_utilEERead(uns
  *
  *---------------------------------------------------------------------*/
 
-static unsigned short FPT_utilEEReadOrg(unsigned long p_port,
-					unsigned short ee_addr)
+static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
 {
 
 	unsigned char ee_value;
@@ -7479,7 +7426,7 @@ static unsigned short FPT_utilEEReadOrg(
  *
  *---------------------------------------------------------------------*/
 
-static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd,
+static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
 				  unsigned short ee_addr)
 {
 	unsigned char ee_value;
@@ -7573,47 +7520,45 @@ static unsigned char FPT_CalcLrc(unsigne
 */
 
 static inline unsigned char
-FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
+FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
 {
 	return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
 					   FlashPointInfo);
 }
 
-static inline FlashPoint_CardHandle_T
-FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
+static inline void *
+FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
 {
 	return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
 						   FlashPointInfo);
 }
 
 static inline void
-FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
+FlashPoint__ReleaseHostAdapter(void *CardHandle)
 {
 	FlashPoint_ReleaseHostAdapter(CardHandle);
 }
 
 static inline void
-FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle,
-		     struct BusLogic_CCB *CCB)
+FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
 {
 	FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
 }
 
 static inline void
-FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle,
-		     struct BusLogic_CCB *CCB)
+FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
 {
 	FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
 }
 
 static inline bool
-FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
+FlashPoint__InterruptPending(void *CardHandle)
 {
 	return FlashPoint_InterruptPending(CardHandle);
 }
 
 static inline int
-FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
+FlashPoint__HandleInterrupt(void *CardHandle)
 {
 	return FlashPoint_HandleInterrupt(CardHandle);
 }
@@ -7632,13 +7577,12 @@ FlashPoint__HandleInterrupt(FlashPoint_C
   Define prototypes for the FlashPoint SCCB Manager Functions.
 */
 
-extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
-extern FlashPoint_CardHandle_T
-FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
-extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
-extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
-extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
-extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
-extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
+extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
+extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
+extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
+extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
+extern bool FlashPoint_InterruptPending(void *);
+extern int FlashPoint_HandleInterrupt(void *);
+extern void FlashPoint_ReleaseHostAdapter(void *);
 
 #endif				/* CONFIG_SCSI_FLASHPOINT */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/fnic/fnic_debugfs.c linux-libre-3.11-rc7-gnu/drivers/scsi/fnic/fnic_debugfs.c
--- linux-libre-3.10-gnu/drivers/scsi/fnic/fnic_debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/fnic/fnic_debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -164,20 +164,8 @@ static loff_t fnic_trace_debugfs_lseek(s
 					int howto)
 {
 	fnic_dbgfs_t *fnic_dbg_prt = file->private_data;
-	loff_t pos = -1;
-
-	switch (howto) {
-	case 0:
-		pos = offset;
-		break;
-	case 1:
-		pos = file->f_pos + offset;
-		break;
-	case 2:
-		pos = fnic_dbg_prt->buffer_len + offset;
-	}
-	return (pos < 0 || pos > fnic_dbg_prt->buffer_len) ?
-			  -EINVAL : (file->f_pos = pos);
+	return fixed_size_llseek(file, offset, howto,
+				fnic_dbg_prt->buffer_len);
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/fnic/fnic.h linux-libre-3.11-rc7-gnu/drivers/scsi/fnic/fnic.h
--- linux-libre-3.10-gnu/drivers/scsi/fnic/fnic.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/fnic/fnic.h	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,7 @@
 
 #define DRV_NAME		"fnic"
 #define DRV_DESCRIPTION		"Cisco FCoE HBA Driver"
-#define DRV_VERSION		"1.5.0.22"
+#define DRV_VERSION		"1.5.0.23"
 #define PFX			DRV_NAME ": "
 #define DFX                     DRV_NAME "%d: "
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/fnic/fnic_main.c linux-libre-3.11-rc7-gnu/drivers/scsi/fnic/fnic_main.c
--- linux-libre-3.10-gnu/drivers/scsi/fnic/fnic_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/fnic/fnic_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -642,19 +642,6 @@ static int fnic_probe(struct pci_dev *pd
 		INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame);
 		INIT_WORK(&fnic->event_work, fnic_handle_event);
 		skb_queue_head_init(&fnic->fip_frame_queue);
-		spin_lock_irqsave(&fnic_list_lock, flags);
-		if (!fnic_fip_queue) {
-			fnic_fip_queue =
-				create_singlethread_workqueue("fnic_fip_q");
-			if (!fnic_fip_queue) {
-				spin_unlock_irqrestore(&fnic_list_lock, flags);
-				printk(KERN_ERR PFX "fnic FIP work queue "
-						 "create failed\n");
-				err = -ENOMEM;
-				goto err_out_free_max_pool;
-			}
-		}
-		spin_unlock_irqrestore(&fnic_list_lock, flags);
 		INIT_LIST_HEAD(&fnic->evlist);
 		INIT_LIST_HEAD(&fnic->vlans);
 	} else {
@@ -960,6 +947,13 @@ static int __init fnic_init_module(void)
 	spin_lock_init(&fnic_list_lock);
 	INIT_LIST_HEAD(&fnic_list);
 
+	fnic_fip_queue = create_singlethread_workqueue("fnic_fip_q");
+	if (!fnic_fip_queue) {
+		printk(KERN_ERR PFX "fnic FIP work queue create failed\n");
+		err = -ENOMEM;
+		goto err_create_fip_workq;
+	}
+
 	fnic_fc_transport = fc_attach_transport(&fnic_fc_functions);
 	if (!fnic_fc_transport) {
 		printk(KERN_ERR PFX "fc_attach_transport error\n");
@@ -978,6 +972,8 @@ static int __init fnic_init_module(void)
 err_pci_register:
 	fc_release_transport(fnic_fc_transport);
 err_fc_transport:
+	destroy_workqueue(fnic_fip_queue);
+err_create_fip_workq:
 	destroy_workqueue(fnic_event_queue);
 err_create_fnic_workq:
 	kmem_cache_destroy(fnic_io_req_cache);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/fnic/fnic_scsi.c linux-libre-3.11-rc7-gnu/drivers/scsi/fnic/fnic_scsi.c
--- linux-libre-3.10-gnu/drivers/scsi/fnic/fnic_scsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/fnic/fnic_scsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -2432,11 +2432,9 @@ int fnic_is_abts_pending(struct fnic *fn
 			      "Found IO in %s on lun\n",
 			      fnic_ioreq_state_to_str(CMD_STATE(sc)));
 
-		if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) {
-			spin_unlock_irqrestore(io_lock, flags);
+		if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING)
 			ret = 1;
-			continue;
-		}
+		spin_unlock_irqrestore(io_lock, flags);
 	}
 
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/ipr.c linux-libre-3.11-rc7-gnu/drivers/scsi/ipr.c
--- linux-libre-3.10-gnu/drivers/scsi/ipr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/ipr.c	2013-08-25 20:43:22.000000000 -0400
@@ -281,12 +281,22 @@ struct ipr_error_table_t ipr_error_table
 	"FFF6: Failure prediction threshold exceeded"},
 	{0x015D9200, 0, IPR_DEFAULT_LOG_LEVEL,
 	"8009: Impending cache battery pack failure"},
+	{0x02040100, 0, 0,
+	"Logical Unit in process of becoming ready"},
+	{0x02040200, 0, 0,
+	"Initializing command required"},
 	{0x02040400, 0, 0,
 	"34FF: Disk device format in progress"},
+	{0x02040C00, 0, 0,
+	"Logical unit not accessible, target port in unavailable state"},
 	{0x02048000, 0, IPR_DEFAULT_LOG_LEVEL,
 	"9070: IOA requested reset"},
 	{0x023F0000, 0, 0,
 	"Synchronization required"},
+	{0x02408500, 0, 0,
+	"IOA microcode download required"},
+	{0x02408600, 0, 0,
+	"Device bus connection is prohibited by host"},
 	{0x024E0000, 0, 0,
 	"No ready, IOA shutdown"},
 	{0x025A0000, 0, 0,
@@ -385,6 +395,8 @@ struct ipr_error_table_t ipr_error_table
 	"4030: Incorrect multipath connection"},
 	{0x04679000, 0, IPR_DEFAULT_LOG_LEVEL,
 	"4110: Unsupported enclosure function"},
+	{0x04679800, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4120: SAS cable VPD cannot be read"},
 	{0x046E0000, 0, IPR_DEFAULT_LOG_LEVEL,
 	"FFF4: Command to logical unit failed"},
 	{0x05240000, 1, 0,
@@ -407,10 +419,18 @@ struct ipr_error_table_t ipr_error_table
 	"Illegal request, command sequence error"},
 	{0x052C8000, 1, 0,
 	"Illegal request, dual adapter support not enabled"},
+	{0x052C8100, 1, 0,
+	"Illegal request, another cable connector was physically disabled"},
+	{0x054E8000, 1, 0,
+	"Illegal request, inconsistent group id/group count"},
 	{0x06040500, 0, IPR_DEFAULT_LOG_LEVEL,
 	"9031: Array protection temporarily suspended, protection resuming"},
 	{0x06040600, 0, IPR_DEFAULT_LOG_LEVEL,
 	"9040: Array protection temporarily suspended, protection resuming"},
+	{0x060B0100, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4080: IOA exceeded maximum operating temperature"},
+	{0x060B8000, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4085: Service required"},
 	{0x06288000, 0, IPR_DEFAULT_LOG_LEVEL,
 	"3140: Device bus not ready to ready transition"},
 	{0x06290000, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -423,6 +443,8 @@ struct ipr_error_table_t ipr_error_table
 	"FFFB: SCSI bus was reset by another initiator"},
 	{0x063F0300, 0, IPR_DEFAULT_LOG_LEVEL,
 	"3029: A device replacement has occurred"},
+	{0x063F8300, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4102: Device bus fabric performance degradation"},
 	{0x064C8000, 0, IPR_DEFAULT_LOG_LEVEL,
 	"9051: IOA cache data exists for a missing or failed device"},
 	{0x064C8100, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -445,6 +467,14 @@ struct ipr_error_table_t ipr_error_table
 	"9076: Configuration error, missing remote IOA"},
 	{0x06679100, 0, IPR_DEFAULT_LOG_LEVEL,
 	"4050: Enclosure does not support a required multipath function"},
+	{0x06679800, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4121: Configuration error, required cable is missing"},
+	{0x06679900, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4122: Cable is not plugged into the correct location on remote IOA"},
+	{0x06679A00, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4123: Configuration error, invalid cable vital product data"},
+	{0x06679B00, 0, IPR_DEFAULT_LOG_LEVEL,
+	"4124: Configuration error, both cable ends are plugged into the same IOA"},
 	{0x06690000, 0, IPR_DEFAULT_LOG_LEVEL,
 	"4070: Logically bad block written on device"},
 	{0x06690200, 0, IPR_DEFAULT_LOG_LEVEL,
@@ -507,10 +537,18 @@ struct ipr_error_table_t ipr_error_table
 	"9062: One or more disks are missing from an array"},
 	{0x07279900, 0, IPR_DEFAULT_LOG_LEVEL,
 	"9063: Maximum number of functional arrays has been exceeded"},
+	{0x07279A00, 0, 0,
+	"Data protect, other volume set problem"},
 	{0x0B260000, 0, 0,
 	"Aborted command, invalid descriptor"},
+	{0x0B3F9000, 0, 0,
+	"Target operating conditions have changed, dual adapter takeover"},
+	{0x0B530200, 0, 0,
+	"Aborted command, medium removal prevented"},
 	{0x0B5A0000, 0, 0,
-	"Command terminated by host"}
+	"Command terminated by host"},
+	{0x0B5B8000, 0, 0,
+	"Aborted command, command terminated by host"}
 };
 
 static const struct ipr_ses_table_entry ipr_ses_table[] = {
@@ -6662,7 +6700,6 @@ static bool ipr_qc_fill_rtf(struct ata_q
 	tf->hob_lbal = g->hob_lbal;
 	tf->hob_lbam = g->hob_lbam;
 	tf->hob_lbah = g->hob_lbah;
-	tf->ctl = g->alt_status;
 
 	return true;
 }
@@ -9392,7 +9429,7 @@ static int ipr_probe_ioa(struct pci_dev
 	void __iomem *ipr_regs;
 	int rc = PCIBIOS_SUCCESSFUL;
 	volatile u32 mask, uproc, interrupts;
-	unsigned long lock_flags;
+	unsigned long lock_flags, driver_lock_flags;
 
 	ENTER;
 
@@ -9615,9 +9652,9 @@ static int ipr_probe_ioa(struct pci_dev
 	} else
 		ioa_cfg->reset = ipr_reset_start_bist;
 
-	spin_lock(&ipr_driver_lock);
+	spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags);
 	list_add_tail(&ioa_cfg->queue, &ipr_ioa_head);
-	spin_unlock(&ipr_driver_lock);
+	spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags);
 
 	LEAVE;
 out:
@@ -9700,6 +9737,7 @@ static void __ipr_remove(struct pci_dev
 	unsigned long host_lock_flags = 0;
 	struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
 	int i;
+	unsigned long driver_lock_flags;
 	ENTER;
 
 	spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
@@ -9723,9 +9761,9 @@ static void __ipr_remove(struct pci_dev
 	INIT_LIST_HEAD(&ioa_cfg->used_res_q);
 	spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
 
-	spin_lock(&ipr_driver_lock);
+	spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags);
 	list_del(&ioa_cfg->queue);
-	spin_unlock(&ipr_driver_lock);
+	spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags);
 
 	if (ioa_cfg->sdt_state == ABORT_DUMP)
 		ioa_cfg->sdt_state = WAIT_FOR_DUMP;
@@ -9991,12 +10029,12 @@ static int ipr_halt(struct notifier_bloc
 {
 	struct ipr_cmnd *ipr_cmd;
 	struct ipr_ioa_cfg *ioa_cfg;
-	unsigned long flags = 0;
+	unsigned long flags = 0, driver_lock_flags;
 
 	if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
 		return NOTIFY_DONE;
 
-	spin_lock(&ipr_driver_lock);
+	spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags);
 
 	list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) {
 		spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
@@ -10014,7 +10052,7 @@ static int ipr_halt(struct notifier_bloc
 		ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
 		spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
 	}
-	spin_unlock(&ipr_driver_lock);
+	spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags);
 
 	return NOTIFY_OK;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/isci/request.c linux-libre-3.11-rc7-gnu/drivers/scsi/isci/request.c
--- linux-libre-3.10-gnu/drivers/scsi/isci/request.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/isci/request.c	2013-08-25 20:43:22.000000000 -0400
@@ -184,8 +184,8 @@ static void sci_io_request_build_ssp_com
 	cmd_iu->task_attr = task->ssp_task.task_attr;
 	cmd_iu->_r_c = 0;
 
-	sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb,
-		       sizeof(task->ssp_task.cdb) / sizeof(u32));
+	sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cmd->cmnd,
+		       (task->ssp_task.cmd->cmd_len+3) / sizeof(u32));
 }
 
 static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/isci/task.c linux-libre-3.11-rc7-gnu/drivers/scsi/isci/task.c
--- linux-libre-3.10-gnu/drivers/scsi/isci/task.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/isci/task.c	2013-08-25 20:43:22.000000000 -0400
@@ -491,6 +491,7 @@ int isci_task_abort_task(struct sas_task
 	struct isci_tmf           tmf;
 	int                       ret = TMF_RESP_FUNC_FAILED;
 	unsigned long             flags;
+	int                       target_done_already = 0;
 
 	/* Get the isci_request reference from the task.  Note that
 	 * this check does not depend on the pending request list
@@ -505,9 +506,11 @@ int isci_task_abort_task(struct sas_task
 	/* If task is already done, the request isn't valid */
 	if (!(task->task_state_flags & SAS_TASK_STATE_DONE) &&
 	    (task->task_state_flags & SAS_TASK_AT_INITIATOR) &&
-	    old_request)
+	    old_request) {
 		idev = isci_get_device(task->dev->lldd_dev);
-
+		target_done_already = test_bit(IREQ_COMPLETE_IN_TARGET,
+					       &old_request->flags);
+	}
 	spin_unlock(&task->task_state_lock);
 	spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
@@ -561,7 +564,7 @@ int isci_task_abort_task(struct sas_task
 
 	if (task->task_proto == SAS_PROTOCOL_SMP ||
 	    sas_protocol_ata(task->task_proto) ||
-	    test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags) ||
+	    target_done_already ||
 	    test_bit(IDEV_GONE, &idev->flags)) {
 
 		spin_unlock_irqrestore(&ihost->scic_lock, flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/Kconfig linux-libre-3.11-rc7-gnu/drivers/scsi/Kconfig
--- linux-libre-3.10-gnu/drivers/scsi/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -633,7 +633,7 @@ config SCSI_BUSLOGIC
 
 config SCSI_FLASHPOINT
 	bool "FlashPoint support"
-	depends on SCSI_BUSLOGIC && PCI && X86_32
+	depends on SCSI_BUSLOGIC && PCI
 	help
 	  This option allows you to add FlashPoint support to the
 	  BusLogic SCSI driver. The FlashPoint SCCB Manager code is
@@ -1353,7 +1353,6 @@ config SCSI_LPFC
 	tristate "Emulex LightPulse Fibre Channel Support"
 	depends on PCI && SCSI
 	select SCSI_FC_ATTRS
-	select GENERIC_CSUM
 	select CRC_T10DIF
 	help
           This lpfc driver supports the Emulex LightPulse
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/libfc/fc_exch.c linux-libre-3.11-rc7-gnu/drivers/scsi/libfc/fc_exch.c
--- linux-libre-3.10-gnu/drivers/scsi/libfc/fc_exch.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/libfc/fc_exch.c	2013-08-25 20:43:22.000000000 -0400
@@ -337,7 +337,7 @@ static void fc_exch_release(struct fc_ex
  * fc_exch_timer_cancel() - cancel exch timer
  * @ep:		The exchange whose timer to be canceled
  */
-static inline  void fc_exch_timer_cancel(struct fc_exch *ep)
+static inline void fc_exch_timer_cancel(struct fc_exch *ep)
 {
 	if (cancel_delayed_work(&ep->timeout_work)) {
 		FC_EXCH_DBG(ep, "Exchange timer canceled\n");
@@ -1567,7 +1567,7 @@ static void fc_exch_abts_resp(struct fc_
 		    fc_exch_rctl_name(fh->fh_r_ctl));
 
 	if (cancel_delayed_work_sync(&ep->timeout_work)) {
-		FC_EXCH_DBG(ep, "Exchange timer canceled\n");
+		FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n");
 		fc_exch_release(ep);	/* release from pending timer hold */
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/libfc/fc_fcp.c linux-libre-3.11-rc7-gnu/drivers/scsi/libfc/fc_fcp.c
--- linux-libre-3.10-gnu/drivers/scsi/libfc/fc_fcp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/libfc/fc_fcp.c	2013-08-25 20:43:22.000000000 -0400
@@ -2043,7 +2043,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd
 		spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
 		return SUCCESS;
 	}
-	/* grab a ref so the fsp and sc_cmd cannot be relased from under us */
+	/* grab a ref so the fsp and sc_cmd cannot be released from under us */
 	fc_fcp_pkt_hold(fsp);
 	spin_unlock_irqrestore(&si->scsi_queue_lock, flags);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/libfc/fc_rport.c linux-libre-3.11-rc7-gnu/drivers/scsi/libfc/fc_rport.c
--- linux-libre-3.10-gnu/drivers/scsi/libfc/fc_rport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/libfc/fc_rport.c	2013-08-25 20:43:22.000000000 -0400
@@ -926,6 +926,20 @@ err:
 	kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
 }
 
+static bool
+fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata)
+{
+	if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN)
+		return true;
+	if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) &&
+	    (lport->service_params & FCP_SPPF_INIT_FCN))
+		return true;
+	if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) &&
+	    (lport->service_params & FCP_SPPF_TARG_FCN))
+		return true;
+	return false;
+}
+
 /**
  * fc_rport_enter_plogi() - Send Port Login (PLOGI) request
  * @rdata: The remote port to send a PLOGI to
@@ -938,6 +952,12 @@ static void fc_rport_enter_plogi(struct
 	struct fc_lport *lport = rdata->local_port;
 	struct fc_frame *fp;
 
+	if (!fc_rport_compatible_roles(lport, rdata)) {
+		FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n");
+		fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
+		return;
+	}
+
 	FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n",
 		     fc_rport_state(rdata));
 
@@ -1646,6 +1666,13 @@ static void fc_rport_recv_plogi_req(stru
 		rjt_data.explan = ELS_EXPL_NONE;
 		goto reject;
 	}
+	if (!fc_rport_compatible_roles(lport, rdata)) {
+		FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n");
+		mutex_unlock(&rdata->rp_mutex);
+		rjt_data.reason = ELS_RJT_LOGIC;
+		rjt_data.explan = ELS_EXPL_NONE;
+		goto reject;
+	}
 
 	/*
 	 * Get session payload size from incoming PLOGI.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/libiscsi.c linux-libre-3.11-rc7-gnu/drivers/scsi/libiscsi.c
--- linux-libre-3.10-gnu/drivers/scsi/libiscsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/libiscsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -2808,6 +2808,9 @@ void iscsi_session_teardown(struct iscsi
 	kfree(session->targetname);
 	kfree(session->targetalias);
 	kfree(session->initiatorname);
+	kfree(session->boot_root);
+	kfree(session->boot_nic);
+	kfree(session->boot_target);
 	kfree(session->ifacename);
 
 	iscsi_destroy_session(cls_session);
@@ -3248,6 +3251,12 @@ int iscsi_set_param(struct iscsi_cls_con
 		return iscsi_switch_str_param(&session->ifacename, buf);
 	case ISCSI_PARAM_INITIATOR_NAME:
 		return iscsi_switch_str_param(&session->initiatorname, buf);
+	case ISCSI_PARAM_BOOT_ROOT:
+		return iscsi_switch_str_param(&session->boot_root, buf);
+	case ISCSI_PARAM_BOOT_NIC:
+		return iscsi_switch_str_param(&session->boot_nic, buf);
+	case ISCSI_PARAM_BOOT_TARGET:
+		return iscsi_switch_str_param(&session->boot_target, buf);
 	default:
 		return -ENOSYS;
 	}
@@ -3326,6 +3335,15 @@ int iscsi_session_get_param(struct iscsi
 	case ISCSI_PARAM_INITIATOR_NAME:
 		len = sprintf(buf, "%s\n", session->initiatorname);
 		break;
+	case ISCSI_PARAM_BOOT_ROOT:
+		len = sprintf(buf, "%s\n", session->boot_root);
+		break;
+	case ISCSI_PARAM_BOOT_NIC:
+		len = sprintf(buf, "%s\n", session->boot_nic);
+		break;
+	case ISCSI_PARAM_BOOT_TARGET:
+		len = sprintf(buf, "%s\n", session->boot_target);
+		break;
 	default:
 		return -ENOSYS;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/libiscsi_tcp.c linux-libre-3.11-rc7-gnu/drivers/scsi/libiscsi_tcp.c
--- linux-libre-3.10-gnu/drivers/scsi/libiscsi_tcp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/libiscsi_tcp.c	2013-08-25 20:43:22.000000000 -0400
@@ -558,7 +558,7 @@ static int iscsi_tcp_r2t_rsp(struct iscs
 	if (!rc) {
 		iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
 				  "Target has sent more R2Ts than it "
-				  "negotiated for or driver has has leaked.\n");
+				  "negotiated for or driver has leaked.\n");
 		return ISCSI_ERR_PROTO;
 	}
 
@@ -906,7 +906,6 @@ int iscsi_tcp_recv_skb(struct iscsi_conn
 			ISCSI_DBG_TCP(conn, "no more data avail. Consumed %d\n",
 				      consumed);
 			*status = ISCSI_TCP_SKB_DONE;
-			skb_abort_seq_read(&seq);
 			goto skb_done;
 		}
 		BUG_ON(segment->copied >= segment->size);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/libsas/sas_scsi_host.c linux-libre-3.11-rc7-gnu/drivers/scsi/libsas/sas_scsi_host.c
--- linux-libre-3.10-gnu/drivers/scsi/libsas/sas_scsi_host.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/libsas/sas_scsi_host.c	2013-08-25 20:43:22.000000000 -0400
@@ -167,7 +167,7 @@ static struct sas_task *sas_create_task(
 	int_to_scsilun(cmd->device->lun, &lun);
 	memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8);
 	task->ssp_task.task_attr = TASK_ATTR_SIMPLE;
-	memcpy(task->ssp_task.cdb, cmd->cmnd, 16);
+	task->ssp_task.cmd = cmd;
 
 	task->scatter = scsi_sglist(cmd);
 	task->num_scatter = scsi_sg_count(cmd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_attr.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_attr.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_attr.c	2013-07-01 10:42:44.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_attr.c	2013-08-31 18:02:32.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -4070,11 +4070,28 @@ LPFC_VPORT_ATTR(discovery_threads, 32, 1
 		 "during discovery");
 
 /*
-# lpfc_max_luns: maximum allowed LUN.
+# lpfc_max_luns: maximum allowed LUN ID. This is the highest LUN ID that
+#    will be scanned by the SCSI midlayer when sequential scanning is
+#    used; and is also the highest LUN ID allowed when the SCSI midlayer
+#    parses REPORT_LUN responses. The lpfc driver has no LUN count or
+#    LUN ID limit, but the SCSI midlayer requires this field for the uses
+#    above. The lpfc driver limits the default value to 255 for two reasons.
+#    As it bounds the sequential scan loop, scanning for thousands of luns
+#    on a target can take minutes of wall clock time.  Additionally,
+#    there are FC targets, such as JBODs, that only recognize 8-bits of
+#    LUN ID. When they receive a value greater than 8 bits, they chop off
+#    the high order bits. In other words, they see LUN IDs 0, 256, 512,
+#    and so on all as LUN ID 0. This causes the linux kernel, which sees
+#    valid responses at each of the LUN IDs, to believe there are multiple
+#    devices present, when in fact, there is only 1.
+#    A customer that is aware of their target behaviors, and the results as
+#    indicated above, is welcome to increase the lpfc_max_luns value.
+#    As mentioned, this value is not used by the lpfc driver, only the
+#    SCSI midlayer.
 # Value range is [0,65535]. Default value is 255.
 # NOTE: The SCSI layer might probe all allowed LUN on some old targets.
 */
-LPFC_VPORT_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN");
+LPFC_VPORT_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID");
 
 /*
 # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_bsg.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_bsg.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_bsg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_bsg.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2009-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2009-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -3392,6 +3392,7 @@ static int lpfc_bsg_check_cmd_access(str
 	case MBX_DOWN_LOAD:
 	case MBX_UPDATE_CFG:
 	case MBX_KILL_BOARD:
+	case MBX_READ_TOPOLOGY:
 	case MBX_LOAD_AREA:
 	case MBX_LOAD_EXP_ROM:
 	case MBX_BEACON:
@@ -3422,7 +3423,6 @@ static int lpfc_bsg_check_cmd_access(str
 		}
 		break;
 	case MBX_READ_SPARM64:
-	case MBX_READ_TOPOLOGY:
 	case MBX_REG_LOGIN:
 	case MBX_REG_LOGIN64:
 	case MBX_CONFIG_PORT:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_crtn.h linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_crtn.h
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_crtn.h	2013-07-01 10:42:44.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_crtn.h	2013-08-31 18:02:32.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2011 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_ct.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_ct.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_ct.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_ct.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2010 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_debugfs.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_debugfs.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_debugfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_debugfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -1165,22 +1165,8 @@ out:
 static loff_t
 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
 {
-	struct lpfc_debug *debug;
-	loff_t pos = -1;
-
-	debug = file->private_data;
-
-	switch (whence) {
-	case 0:
-		pos = off;
-		break;
-	case 1:
-		pos = file->f_pos + off;
-		break;
-	case 2:
-		pos = debug->len + off;
-	}
-	return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
+	struct lpfc_debug *debug = file->private_data;
+	return fixed_size_llseek(file, off, whence, debug->len);
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_els.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_els.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_els.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_els.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc.h linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc.h
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc.h	2013-07-01 10:42:44.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc.h	2013-08-31 18:02:32.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_hbadisc.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_hbadisc.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_hbadisc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_hbadisc.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -6158,12 +6158,44 @@ lpfc_read_fcf_conn_tbl(struct lpfc_hba *
 		memcpy(&conn_entry->conn_rec, &conn_rec[i],
 			sizeof(struct lpfc_fcf_conn_rec));
 		conn_entry->conn_rec.vlan_tag =
-			le16_to_cpu(conn_entry->conn_rec.vlan_tag) & 0xFFF;
+			conn_entry->conn_rec.vlan_tag;
 		conn_entry->conn_rec.flags =
-			le16_to_cpu(conn_entry->conn_rec.flags);
+			conn_entry->conn_rec.flags;
 		list_add_tail(&conn_entry->list,
 			&phba->fcf_conn_rec_list);
 	}
+
+	if (!list_empty(&phba->fcf_conn_rec_list)) {
+		i = 0;
+		list_for_each_entry(conn_entry, &phba->fcf_conn_rec_list,
+				    list) {
+			conn_rec = &conn_entry->conn_rec;
+			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+					"3345 FCF connection list rec[%02d]: "
+					"flags:x%04x, vtag:x%04x, "
+					"fabric_name:x%02x:%02x:%02x:%02x:"
+					"%02x:%02x:%02x:%02x, "
+					"switch_name:x%02x:%02x:%02x:%02x:"
+					"%02x:%02x:%02x:%02x\n", i++,
+					conn_rec->flags, conn_rec->vlan_tag,
+					conn_rec->fabric_name[0],
+					conn_rec->fabric_name[1],
+					conn_rec->fabric_name[2],
+					conn_rec->fabric_name[3],
+					conn_rec->fabric_name[4],
+					conn_rec->fabric_name[5],
+					conn_rec->fabric_name[6],
+					conn_rec->fabric_name[7],
+					conn_rec->switch_name[0],
+					conn_rec->switch_name[1],
+					conn_rec->switch_name[2],
+					conn_rec->switch_name[3],
+					conn_rec->switch_name[4],
+					conn_rec->switch_name[5],
+					conn_rec->switch_name[6],
+					conn_rec->switch_name[7]);
+		}
+	}
 }
 
 /**
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_hw4.h linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_hw4.h
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_hw4.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_hw4.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2009-2012 Emulex.  All rights reserved.                *
+ * Copyright (C) 2009-2013 Emulex.  All rights reserved.                *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_hw.h linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_hw.h
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2011 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_init.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_init.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_init.c	2013-07-01 10:42:44.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_init.c	2013-08-31 18:02:32.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -60,7 +60,8 @@ unsigned long _dump_buf_dif_order;
 spinlock_t _dump_buf_lock;
 
 /* Used when mapping IRQ vectors in a driver centric manner */
-uint16_t lpfc_used_cpu[LPFC_MAX_CPU];
+uint16_t *lpfc_used_cpu;
+uint32_t lpfc_present_cpu;
 
 static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *);
 static int lpfc_post_rcv_buf(struct lpfc_hba *);
@@ -4049,52 +4050,6 @@ lpfc_sli4_perform_all_vport_cvl(struct l
 }
 
 /**
- * lpfc_sli4_perform_inuse_fcf_recovery - Perform inuse fcf recovery
- * @vport: pointer to lpfc hba data structure.
- *
- * This routine is to perform FCF recovery when the in-use FCF either dead or
- * got modified.
- **/
-static void
-lpfc_sli4_perform_inuse_fcf_recovery(struct lpfc_hba *phba,
-				     struct lpfc_acqe_fip *acqe_fip)
-{
-	int rc;
-
-	spin_lock_irq(&phba->hbalock);
-	/* Mark the fast failover process in progress */
-	phba->fcf.fcf_flag |= FCF_DEAD_DISC;
-	spin_unlock_irq(&phba->hbalock);
-
-	lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
-			"2771 Start FCF fast failover process due to in-use "
-			"FCF DEAD/MODIFIED event: evt_tag:x%x, index:x%x\n",
-			acqe_fip->event_tag, acqe_fip->index);
-	rc = lpfc_sli4_redisc_fcf_table(phba);
-	if (rc) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
-				"2772 Issue FCF rediscover mabilbox command "
-				"failed, fail through to FCF dead event\n");
-		spin_lock_irq(&phba->hbalock);
-		phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
-		spin_unlock_irq(&phba->hbalock);
-		/*
-		 * Last resort will fail over by treating this as a link
-		 * down to FCF registration.
-		 */
-		lpfc_sli4_fcf_dead_failthrough(phba);
-	} else {
-		/* Reset FCF roundrobin bmask for new discovery */
-		lpfc_sli4_clear_fcf_rr_bmask(phba);
-		/*
-		 * Handling fast FCF failover to a DEAD FCF event is
-		 * considered equalivant to receiving CVL to all vports.
-		 */
-		lpfc_sli4_perform_all_vport_cvl(phba);
-	}
-}
-
-/**
  * lpfc_sli4_async_fip_evt - Process the asynchronous FCoE FIP event
  * @phba: pointer to lpfc hba data structure.
  * @acqe_link: pointer to the async fcoe completion queue entry.
@@ -4159,22 +4114,9 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba
 			break;
 		}
 
-		/* If FCF has been in discovered state, perform rediscovery
-		 * only if the FCF with the same index of the in-use FCF got
-		 * modified during normal operation. Otherwise, do nothing.
-		 */
-		if (phba->pport->port_state > LPFC_FLOGI) {
+		/* If the FCF has been in discovered state, do nothing. */
+		if (phba->fcf.fcf_flag & FCF_SCAN_DONE) {
 			spin_unlock_irq(&phba->hbalock);
-			if (phba->fcf.current_rec.fcf_indx ==
-			    acqe_fip->index) {
-				lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
-						"3300 In-use FCF (%d) "
-						"modified, perform FCF "
-						"rediscovery\n",
-						acqe_fip->index);
-				lpfc_sli4_perform_inuse_fcf_recovery(phba,
-								     acqe_fip);
-			}
 			break;
 		}
 		spin_unlock_irq(&phba->hbalock);
@@ -4227,7 +4169,39 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba
 		 * is no longer valid as we are not in the middle of FCF
 		 * failover process already.
 		 */
-		lpfc_sli4_perform_inuse_fcf_recovery(phba, acqe_fip);
+		spin_lock_irq(&phba->hbalock);
+		/* Mark the fast failover process in progress */
+		phba->fcf.fcf_flag |= FCF_DEAD_DISC;
+		spin_unlock_irq(&phba->hbalock);
+
+		lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
+				"2771 Start FCF fast failover process due to "
+				"FCF DEAD event: evt_tag:x%x, fcf_index:x%x "
+				"\n", acqe_fip->event_tag, acqe_fip->index);
+		rc = lpfc_sli4_redisc_fcf_table(phba);
+		if (rc) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
+					LOG_DISCOVERY,
+					"2772 Issue FCF rediscover mabilbox "
+					"command failed, fail through to FCF "
+					"dead event\n");
+			spin_lock_irq(&phba->hbalock);
+			phba->fcf.fcf_flag &= ~FCF_DEAD_DISC;
+			spin_unlock_irq(&phba->hbalock);
+			/*
+			 * Last resort will fail over by treating this
+			 * as a link down to FCF registration.
+			 */
+			lpfc_sli4_fcf_dead_failthrough(phba);
+		} else {
+			/* Reset FCF roundrobin bmask for new discovery */
+			lpfc_sli4_clear_fcf_rr_bmask(phba);
+			/*
+			 * Handling fast FCF failover to a DEAD FCF event is
+			 * considered equalivant to receiving CVL to all vports.
+			 */
+			lpfc_sli4_perform_all_vport_cvl(phba);
+		}
 		break;
 	case LPFC_FIP_EVENT_TYPE_CVL:
 		phba->fcoe_cvl_eventtag = acqe_fip->event_tag;
@@ -5213,6 +5187,21 @@ lpfc_sli4_driver_resource_setup(struct l
 		rc = -ENOMEM;
 		goto out_free_msix;
 	}
+	if (lpfc_used_cpu == NULL) {
+		lpfc_used_cpu = kzalloc((sizeof(uint16_t) * lpfc_present_cpu),
+					 GFP_KERNEL);
+		if (!lpfc_used_cpu) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"3335 Failed allocate memory for msi-x "
+					"interrupt vector mapping\n");
+			kfree(phba->sli4_hba.cpu_map);
+			rc = -ENOMEM;
+			goto out_free_msix;
+		}
+		for (i = 0; i < lpfc_present_cpu; i++)
+			lpfc_used_cpu[i] = LPFC_VECTOR_MAP_EMPTY;
+	}
+
 	/* Initialize io channels for round robin */
 	cpup = phba->sli4_hba.cpu_map;
 	rc = 0;
@@ -6824,8 +6813,6 @@ lpfc_sli4_queue_verify(struct lpfc_hba *
 	int cfg_fcp_io_channel;
 	uint32_t cpu;
 	uint32_t i = 0;
-	uint32_t j = 0;
-
 
 	/*
 	 * Sanity check for configured queue parameters against the run-time
@@ -6839,10 +6826,9 @@ lpfc_sli4_queue_verify(struct lpfc_hba *
 	for_each_present_cpu(cpu) {
 		if (cpu_online(cpu))
 			i++;
-		j++;
 	}
 	phba->sli4_hba.num_online_cpu = i;
-	phba->sli4_hba.num_present_cpu = j;
+	phba->sli4_hba.num_present_cpu = lpfc_present_cpu;
 
 	if (i < cfg_fcp_io_channel) {
 		lpfc_printf_log(phba,
@@ -10967,8 +10953,10 @@ lpfc_init(void)
 	}
 
 	/* Initialize in case vector mapping is needed */
-	for (cpu = 0; cpu < LPFC_MAX_CPU; cpu++)
-		lpfc_used_cpu[cpu] = LPFC_VECTOR_MAP_EMPTY;
+	lpfc_used_cpu = NULL;
+	lpfc_present_cpu = 0;
+	for_each_present_cpu(cpu)
+		lpfc_present_cpu++;
 
 	error = pci_register_driver(&lpfc_driver);
 	if (error) {
@@ -11008,6 +10996,7 @@ lpfc_exit(void)
 				(1L << _dump_buf_dif_order), _dump_buf_dif);
 		free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order);
 	}
+	kfree(lpfc_used_cpu);
 }
 
 module_init(lpfc_init);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_mbox.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_mbox.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_mbox.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_mbox.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2009 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_nportdisc.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_nportdisc.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_nportdisc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_nportdisc.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
  /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_scsi.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_scsi.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_scsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_scsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -68,14 +68,12 @@ struct scsi_dif_tuple {
 	__be32 ref_tag;         /* Target LBA or indirect LBA */
 };
 
-#if !defined(SCSI_PROT_GUARD_CHECK) || !defined(SCSI_PROT_REF_CHECK)
-#define scsi_prot_flagged(sc, flg)	sc
-#endif
-
 static void
 lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
 static void
 lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
+static int
+lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc);
 
 static void
 lpfc_debug_save_data(struct lpfc_hba *phba, struct scsi_cmnd *cmnd)
@@ -134,6 +132,30 @@ lpfc_debug_save_dif(struct lpfc_hba *phb
 	}
 }
 
+static inline unsigned
+lpfc_cmd_blksize(struct scsi_cmnd *sc)
+{
+	return sc->device->sector_size;
+}
+
+#define LPFC_CHECK_PROTECT_GUARD	1
+#define LPFC_CHECK_PROTECT_REF		2
+static inline unsigned
+lpfc_cmd_protect(struct scsi_cmnd *sc, int flag)
+{
+	return 1;
+}
+
+static inline unsigned
+lpfc_cmd_guard_csum(struct scsi_cmnd *sc)
+{
+	if (lpfc_prot_group_type(NULL, sc) == LPFC_PG_TYPE_NO_DIF)
+		return 0;
+	if (scsi_host_get_guard(sc->device->host) == SHOST_DIX_GUARD_IP)
+		return 1;
+	return 0;
+}
+
 /**
  * lpfc_sli4_set_rsp_sgl_last - Set the last bit in the response sge.
  * @phba: Pointer to HBA object.
@@ -1144,13 +1166,14 @@ lpfc_get_scsi_buf_s3(struct lpfc_hba *ph
 static struct lpfc_scsi_buf*
 lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 {
-	struct lpfc_scsi_buf *lpfc_cmd ;
+	struct lpfc_scsi_buf *lpfc_cmd, *lpfc_cmd_next;
 	unsigned long gflag = 0;
 	unsigned long pflag = 0;
 	int found = 0;
 
 	spin_lock_irqsave(&phba->scsi_buf_list_get_lock, gflag);
-	list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list_get, list) {
+	list_for_each_entry_safe(lpfc_cmd, lpfc_cmd_next,
+				 &phba->lpfc_scsi_buf_list_get, list) {
 		if (lpfc_test_rrq_active(phba, ndlp,
 					 lpfc_cmd->cur_iocbq.sli4_lxritag))
 			continue;
@@ -1164,8 +1187,8 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *ph
 			    &phba->lpfc_scsi_buf_list_get);
 		INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_put);
 		spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, pflag);
-		list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list_get,
-				    list) {
+		list_for_each_entry_safe(lpfc_cmd, lpfc_cmd_next,
+					 &phba->lpfc_scsi_buf_list_get, list) {
 			if (lpfc_test_rrq_active(
 				phba, ndlp, lpfc_cmd->cur_iocbq.sli4_lxritag))
 				continue;
@@ -1409,12 +1432,6 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hb
 	return 0;
 }
 
-static inline unsigned
-lpfc_cmd_blksize(struct scsi_cmnd *sc)
-{
-	return sc->device->sector_size;
-}
-
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
 /* Return if if error injection is detected by Initiator */
@@ -1847,10 +1864,9 @@ static int
 lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 		uint8_t *txop, uint8_t *rxop)
 {
-	uint8_t guard_type = scsi_host_get_guard(sc->device->host);
 	uint8_t ret = 0;
 
-	if (guard_type == SHOST_DIX_GUARD_IP) {
+	if (lpfc_cmd_guard_csum(sc)) {
 		switch (scsi_get_prot_op(sc)) {
 		case SCSI_PROT_READ_INSERT:
 		case SCSI_PROT_WRITE_STRIP:
@@ -1928,10 +1944,9 @@ static int
 lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 		uint8_t *txop, uint8_t *rxop)
 {
-	uint8_t guard_type = scsi_host_get_guard(sc->device->host);
 	uint8_t ret = 0;
 
-	if (guard_type == SHOST_DIX_GUARD_IP) {
+	if (lpfc_cmd_guard_csum(sc)) {
 		switch (scsi_get_prot_op(sc)) {
 		case SCSI_PROT_READ_INSERT:
 		case SCSI_PROT_WRITE_STRIP:
@@ -2078,12 +2093,12 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba,
 	 * protection data is automatically generated, not checked.
 	 */
 	if (datadir == DMA_FROM_DEVICE) {
-		if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK))
+		if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD))
 			bf_set(pde6_ce, pde6, checking);
 		else
 			bf_set(pde6_ce, pde6, 0);
 
-		if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK))
+		if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF))
 			bf_set(pde6_re, pde6, checking);
 		else
 			bf_set(pde6_re, pde6, 0);
@@ -2240,12 +2255,12 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *
 		bf_set(pde6_optx, pde6, txop);
 		bf_set(pde6_oprx, pde6, rxop);
 
-		if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK))
+		if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD))
 			bf_set(pde6_ce, pde6, checking);
 		else
 			bf_set(pde6_ce, pde6, 0);
 
-		if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK))
+		if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF))
 			bf_set(pde6_re, pde6, checking);
 		else
 			bf_set(pde6_re, pde6, 0);
@@ -2454,12 +2469,12 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba,
 	 * protection data is automatically generated, not checked.
 	 */
 	if (sc->sc_data_direction == DMA_FROM_DEVICE) {
-		if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK))
+		if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD))
 			bf_set(lpfc_sli4_sge_dif_ce, diseed, checking);
 		else
 			bf_set(lpfc_sli4_sge_dif_ce, diseed, 0);
 
-		if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK))
+		if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF))
 			bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
 		else
 			bf_set(lpfc_sli4_sge_dif_re, diseed, 0);
@@ -2610,7 +2625,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *
 		diseed->ref_tag = cpu_to_le32(reftag);
 		diseed->ref_tag_tran = diseed->ref_tag;
 
-		if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) {
+		if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_GUARD)) {
 			bf_set(lpfc_sli4_sge_dif_ce, diseed, checking);
 
 		} else {
@@ -2629,7 +2644,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *
 		}
 
 
-		if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK))
+		if (lpfc_cmd_protect(sc, LPFC_CHECK_PROTECT_REF))
 			bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
 		else
 			bf_set(lpfc_sli4_sge_dif_re, diseed, 0);
@@ -2792,11 +2807,12 @@ lpfc_prot_group_type(struct lpfc_hba *ph
 		ret = LPFC_PG_TYPE_DIF_BUF;
 		break;
 	default:
-		lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
-				"9021 Unsupported protection op:%d\n", op);
+		if (phba)
+			lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+					"9021 Unsupported protection op:%d\n",
+					op);
 		break;
 	}
-
 	return ret;
 }
 
@@ -2821,22 +2837,22 @@ lpfc_bg_scsi_adjust_dl(struct lpfc_hba *
 
 	/* Check if there is protection data on the wire */
 	if (sc->sc_data_direction == DMA_FROM_DEVICE) {
-		/* Read */
+		/* Read check for protection data */
 		if (scsi_get_prot_op(sc) ==  SCSI_PROT_READ_INSERT)
 			return fcpdl;
 
 	} else {
-		/* Write */
+		/* Write check for protection data */
 		if (scsi_get_prot_op(sc) ==  SCSI_PROT_WRITE_STRIP)
 			return fcpdl;
 	}
 
 	/*
 	 * If we are in DIF Type 1 mode every data block has a 8 byte
-	 * DIF (trailer) attached to it. Must ajust FCP data length.
+	 * DIF (trailer) attached to it. Must ajust FCP data length
+	 * to account for the protection data.
 	 */
-	if (scsi_prot_flagged(sc, SCSI_PROT_TRANSFER_PI))
-		fcpdl += (fcpdl / lpfc_cmd_blksize(sc)) * 8;
+	fcpdl += (fcpdl / lpfc_cmd_blksize(sc)) * 8;
 
 	return fcpdl;
 }
@@ -3073,9 +3089,9 @@ lpfc_calc_bg_err(struct lpfc_hba *phba,
 			chk_guard = 1;
 		guard_type = scsi_host_get_guard(cmd->device->host);
 
+		src = (struct scsi_dif_tuple *)sg_virt(sgpe);
 		start_ref_tag = (uint32_t)scsi_get_lba(cmd); /* Truncate LBA */
 		start_app_tag = src->app_tag;
-		src = (struct scsi_dif_tuple *)sg_virt(sgpe);
 		len = sgpe->length;
 		while (src && protsegcnt) {
 			while (len) {
@@ -3090,25 +3106,10 @@ lpfc_calc_bg_err(struct lpfc_hba *phba,
 					goto skipit;
 				}
 
-				/* App Tag checking */
-				app_tag = src->app_tag;
-				if (chk_app && (app_tag != start_app_tag)) {
-					err_type = BGS_APPTAG_ERR_MASK;
-					goto out;
-				}
-
-				/* Reference Tag checking */
-				ref_tag = be32_to_cpu(src->ref_tag);
-				if (chk_ref && (ref_tag != start_ref_tag)) {
-					err_type = BGS_REFTAG_ERR_MASK;
-					goto out;
-				}
-				start_ref_tag++;
-
-				/* Guard Tag checking */
+				/* First Guard Tag checking */
 				if (chk_guard) {
 					guard_tag = src->guard_tag;
-					if (guard_type == SHOST_DIX_GUARD_IP)
+					if (lpfc_cmd_guard_csum(cmd))
 						sum = lpfc_bg_csum(data_src,
 								   blksize);
 					else
@@ -3119,6 +3120,21 @@ lpfc_calc_bg_err(struct lpfc_hba *phba,
 						goto out;
 					}
 				}
+
+				/* Reference Tag checking */
+				ref_tag = be32_to_cpu(src->ref_tag);
+				if (chk_ref && (ref_tag != start_ref_tag)) {
+					err_type = BGS_REFTAG_ERR_MASK;
+					goto out;
+				}
+				start_ref_tag++;
+
+				/* App Tag checking */
+				app_tag = src->app_tag;
+				if (chk_app && (app_tag != start_app_tag)) {
+					err_type = BGS_APPTAG_ERR_MASK;
+					goto out;
+				}
 skipit:
 				len -= sizeof(struct scsi_dif_tuple);
 				if (len < 0)
@@ -4074,7 +4090,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba
 			 cmd->device ? cmd->device->id : 0xffff,
 			 cmd->device ? cmd->device->lun : 0xffff,
 			 lpfc_cmd->status, lpfc_cmd->result,
-			 vport->fc_myDID, pnode->nlp_DID,
+			 vport->fc_myDID,
+			 (pnode) ? pnode->nlp_DID : 0,
 			 phba->sli_rev == LPFC_SLI_REV4 ?
 			     lpfc_cmd->cur_iocbq.sli4_xritag : 0xffff,
 			 pIocbOut->iocb.ulpContext,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_scsi.h linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_scsi.h
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_scsi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_scsi.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_sli4.h linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_sli4.h
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_sli4.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_sli4.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2009-2011 Emulex.  All rights reserved.           *
+ * Copyright (C) 2009-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -444,7 +444,6 @@ struct lpfc_vector_map_info {
 	struct cpumask	maskbits;
 };
 #define LPFC_VECTOR_MAP_EMPTY	0xffff
-#define LPFC_MAX_CPU		256
 
 /* SLI4 HBA data structure entries */
 struct lpfc_sli4_hba {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_sli.c linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_sli.c
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_sli.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_sli.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -1011,17 +1011,6 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_
 	else
 		sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_lxritag);
 
-	/*
-	** This should have been removed from the txcmplq before calling
-	** iocbq_release. The normal completion
-	** path should have already done the list_del_init.
-	*/
-	if (unlikely(!list_empty(&iocbq->list))) {
-		if (iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ)
-			iocbq->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ;
-		list_del_init(&iocbq->list);
-	}
-
 
 	if (sglq)  {
 		if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) &&
@@ -1070,13 +1059,6 @@ __lpfc_sli_release_iocbq_s3(struct lpfc_
 {
 	size_t start_clean = offsetof(struct lpfc_iocbq, iocb);
 
-	/*
-	** This should have been removed from the txcmplq before calling
-	** iocbq_release. The normal completion
-	** path should have already done the list_del_init.
-	*/
-	if (unlikely(!list_empty(&iocbq->list)))
-		list_del_init(&iocbq->list);
 
 	/*
 	 * Clean all volatile data fields, preserve iotag and node struct.
@@ -3279,7 +3261,7 @@ lpfc_sli_sp_handle_rspiocb(struct lpfc_h
 		if (free_saveq) {
 			list_for_each_entry_safe(rspiocbp, next_iocb,
 						 &saveq->list, list) {
-				list_del(&rspiocbp->list);
+				list_del_init(&rspiocbp->list);
 				__lpfc_sli_release_iocbq(phba, rspiocbp);
 			}
 			__lpfc_sli_release_iocbq(phba, saveq);
@@ -4584,7 +4566,8 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba
 		} else {
 			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
 					"2708 This device does not support "
-					"Advanced Error Reporting (AER)\n");
+					"Advanced Error Reporting (AER): %d\n",
+					rc);
 			phba->cfg_aer_support = 0;
 		}
 	}
@@ -8731,7 +8714,7 @@ lpfc_sli4_abts_err_handler(struct lpfc_h
 	lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
 			"3116 Port generated FCP XRI ABORT event on "
 			"vpi %d rpi %d xri x%x status 0x%x parameter x%x\n",
-			ndlp->vport->vpi, ndlp->nlp_rpi,
+			ndlp->vport->vpi, phba->sli4_hba.rpi_ids[ndlp->nlp_rpi],
 			bf_get(lpfc_wcqe_xa_xri, axri),
 			bf_get(lpfc_wcqe_xa_status, axri),
 			axri->parameter);
@@ -9787,7 +9770,7 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba
 			struct lpfc_iocbq *rspiocb)
 {
 	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
-			"3096 ABORT_XRI_CN completing on xri x%x "
+			"3096 ABORT_XRI_CN completing on rpi x%x "
 			"original iotag x%x, abort cmd iotag x%x "
 			"status 0x%x, reason 0x%x\n",
 			cmdiocb->iocb.un.acxri.abortContextTag,
@@ -10109,12 +10092,13 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba
 			 uint32_t timeout)
 {
 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
+	MAILBOX_t *mb = NULL;
 	int retval;
 	unsigned long flag;
 
-	/* The caller must leave context1 empty. */
+	/* The caller might set context1 for extended buffer */
 	if (pmboxq->context1)
-		return MBX_NOT_FINISHED;
+		mb = (MAILBOX_t *)pmboxq->context1;
 
 	pmboxq->mbox_flag &= ~LPFC_MBX_WAKE;
 	/* setup wake call as IOCB callback */
@@ -10130,7 +10114,8 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba
 				msecs_to_jiffies(timeout * 1000));
 
 		spin_lock_irqsave(&phba->hbalock, flag);
-		pmboxq->context1 = NULL;
+		/* restore the possible extended buffer for free resource */
+		pmboxq->context1 = (uint8_t *)mb;
 		/*
 		 * if LPFC_MBX_WAKE flag is set the mailbox is completed
 		 * else do not free the resources.
@@ -10143,6 +10128,9 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba
 			pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 		}
 		spin_unlock_irqrestore(&phba->hbalock, flag);
+	} else {
+		/* restore the possible extended buffer for free resource */
+		pmboxq->context1 = (uint8_t *)mb;
 	}
 
 	return retval;
@@ -16304,7 +16292,7 @@ lpfc_drain_txq(struct lpfc_hba *phba)
 	union lpfc_wqe wqe;
 	int txq_cnt = 0;
 
-	spin_lock_irqsave(&phba->hbalock, iflags);
+	spin_lock_irqsave(&pring->ring_lock, iflags);
 	list_for_each_entry(piocbq, &pring->txq, list) {
 		txq_cnt++;
 	}
@@ -16312,14 +16300,14 @@ lpfc_drain_txq(struct lpfc_hba *phba)
 	if (txq_cnt > pring->txq_max)
 		pring->txq_max = txq_cnt;
 
-	spin_unlock_irqrestore(&phba->hbalock, iflags);
+	spin_unlock_irqrestore(&pring->ring_lock, iflags);
 
 	while (!list_empty(&pring->txq)) {
-		spin_lock_irqsave(&phba->hbalock, iflags);
+		spin_lock_irqsave(&pring->ring_lock, iflags);
 
 		piocbq = lpfc_sli_ringtx_get(phba, pring);
 		if (!piocbq) {
-			spin_unlock_irqrestore(&phba->hbalock, iflags);
+			spin_unlock_irqrestore(&pring->ring_lock, iflags);
 			lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"2823 txq empty and txq_cnt is %d\n ",
 				txq_cnt);
@@ -16328,7 +16316,7 @@ lpfc_drain_txq(struct lpfc_hba *phba)
 		sglq = __lpfc_sli_get_sglq(phba, piocbq);
 		if (!sglq) {
 			__lpfc_sli_ringtx_put(phba, pring, piocbq);
-			spin_unlock_irqrestore(&phba->hbalock, iflags);
+			spin_unlock_irqrestore(&pring->ring_lock, iflags);
 			break;
 		}
 		txq_cnt--;
@@ -16356,7 +16344,7 @@ lpfc_drain_txq(struct lpfc_hba *phba)
 					piocbq->iotag, piocbq->sli4_xritag);
 			list_add_tail(&piocbq->list, &completions);
 		}
-		spin_unlock_irqrestore(&phba->hbalock, iflags);
+		spin_unlock_irqrestore(&pring->ring_lock, iflags);
 	}
 
 	/* Cancel all the IOCBs that cannot be issued */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_version.h linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_version.h
--- linux-libre-3.10-gnu/drivers/scsi/lpfc/lpfc_version.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/lpfc/lpfc_version.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2013 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.39"
+#define LPFC_DRIVER_VERSION "8.3.40"
 #define LPFC_DRIVER_NAME		"lpfc"
 
 /* Used for SLI 2/3 */
@@ -30,4 +30,4 @@
 
 #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
 		LPFC_DRIVER_VERSION
-#define LPFC_COPYRIGHT "Copyright(c) 2004-2009 Emulex.  All rights reserved."
+#define LPFC_COPYRIGHT "Copyright(c) 2004-2013 Emulex.  All rights reserved."
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas_base.c linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_base.c
--- linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas_base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_base.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,7 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  *  FILE: megaraid_sas_base.c
- *  Version : v06.506.00.00-rc1
+ *  Version : 06.600.18.00-rc1
  *
  *  Authors: LSI Corporation
  *           Sreenivas Bagalkote
@@ -122,6 +122,8 @@ static struct pci_device_id megasas_pci_
 	/* Fusion */
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_INVADER)},
 	/* Invader */
+	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FURY)},
+	/* Fury */
 	{}
 };
 
@@ -169,8 +171,6 @@ megasas_sync_map_info(struct megasas_ins
 int
 wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd);
 void megasas_reset_reply_desc(struct megasas_instance *instance);
-u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
-		      struct LD_LOAD_BALANCE_INFO *lbInfo);
 int megasas_reset_fusion(struct Scsi_Host *shost);
 void megasas_fusion_ocr_wq(struct work_struct *work);
 
@@ -223,6 +223,7 @@ megasas_return_cmd(struct megasas_instan
 	cmd->frame_count = 0;
 	if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
 	    (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
+	    (instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
 	    (reset_devices))
 		cmd->frame->hdr.cmd = MFI_CMD_INVALID;
 	list_add_tail(&cmd->list, &instance->cmd_pool);
@@ -241,8 +242,10 @@ megasas_return_cmd(struct megasas_instan
  * @regs:			MFI register set
  */
 static inline void
-megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
+megasas_enable_intr_xscale(struct megasas_instance *instance)
 {
+	struct megasas_register_set __iomem *regs;
+	regs = instance->reg_set;
 	writel(0, &(regs)->outbound_intr_mask);
 
 	/* Dummy readl to force pci flush */
@@ -254,9 +257,11 @@ megasas_enable_intr_xscale(struct megasa
  * @regs:			MFI register set
  */
 static inline void
-megasas_disable_intr_xscale(struct megasas_register_set __iomem * regs)
+megasas_disable_intr_xscale(struct megasas_instance *instance)
 {
+	struct megasas_register_set __iomem *regs;
 	u32 mask = 0x1f;
+	regs = instance->reg_set;
 	writel(mask, &regs->outbound_intr_mask);
 	/* Dummy readl to force pci flush */
 	readl(&regs->outbound_intr_mask);
@@ -410,8 +415,10 @@ static struct megasas_instance_template
  * @regs:			MFI register set
  */
 static inline void
-megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
+megasas_enable_intr_ppc(struct megasas_instance *instance)
 {
+	struct megasas_register_set __iomem *regs;
+	regs = instance->reg_set;
 	writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
 
 	writel(~0x80000000, &(regs)->outbound_intr_mask);
@@ -425,9 +432,11 @@ megasas_enable_intr_ppc(struct megasas_r
  * @regs:			MFI register set
  */
 static inline void
-megasas_disable_intr_ppc(struct megasas_register_set __iomem * regs)
+megasas_disable_intr_ppc(struct megasas_instance *instance)
 {
+	struct megasas_register_set __iomem *regs;
 	u32 mask = 0xFFFFFFFF;
+	regs = instance->reg_set;
 	writel(mask, &regs->outbound_intr_mask);
 	/* Dummy readl to force pci flush */
 	readl(&regs->outbound_intr_mask);
@@ -528,8 +537,10 @@ static struct megasas_instance_template
  * @regs:			MFI register set
  */
 static inline void
-megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
+megasas_enable_intr_skinny(struct megasas_instance *instance)
 {
+	struct megasas_register_set __iomem *regs;
+	regs = instance->reg_set;
 	writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
 
 	writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
@@ -543,9 +554,11 @@ megasas_enable_intr_skinny(struct megasa
  * @regs:			MFI register set
  */
 static inline void
-megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
+megasas_disable_intr_skinny(struct megasas_instance *instance)
 {
+	struct megasas_register_set __iomem *regs;
 	u32 mask = 0xFFFFFFFF;
+	regs = instance->reg_set;
 	writel(mask, &regs->outbound_intr_mask);
 	/* Dummy readl to force pci flush */
 	readl(&regs->outbound_intr_mask);
@@ -583,7 +596,7 @@ megasas_clear_intr_skinny(struct megasas
 	/*
 	 * Check if it is our interrupt
 	 */
-	if ((megasas_read_fw_status_reg_gen2(regs) & MFI_STATE_MASK) ==
+	if ((megasas_read_fw_status_reg_skinny(regs) & MFI_STATE_MASK) ==
 	    MFI_STATE_FAULT) {
 		mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
 	} else
@@ -663,8 +676,10 @@ static struct megasas_instance_template
  * @regs:                      MFI register set
  */
 static inline void
-megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs)
+megasas_enable_intr_gen2(struct megasas_instance *instance)
 {
+	struct megasas_register_set __iomem *regs;
+	regs = instance->reg_set;
 	writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
 
 	/* write ~0x00000005 (4 & 1) to the intr mask*/
@@ -679,9 +694,11 @@ megasas_enable_intr_gen2(struct megasas_
  * @regs:                      MFI register set
  */
 static inline void
-megasas_disable_intr_gen2(struct megasas_register_set __iomem *regs)
+megasas_disable_intr_gen2(struct megasas_instance *instance)
 {
+	struct megasas_register_set __iomem *regs;
 	u32 mask = 0xFFFFFFFF;
+	regs = instance->reg_set;
 	writel(mask, &regs->outbound_intr_mask);
 	/* Dummy readl to force pci flush */
 	readl(&regs->outbound_intr_mask);
@@ -711,7 +728,7 @@ megasas_clear_intr_gen2(struct megasas_r
 	 */
 	status = readl(&regs->outbound_intr_status);
 
-	if (status & MFI_GEN2_ENABLE_INTERRUPT_MASK) {
+	if (status & MFI_INTR_FLAG_REPLY_MESSAGE) {
 		mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
 	}
 	if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT) {
@@ -1471,6 +1488,14 @@ megasas_queue_command_lck(struct scsi_cm
 		return SCSI_MLQUEUE_HOST_BUSY;
 
 	spin_lock_irqsave(&instance->hba_lock, flags);
+
+	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
+		spin_unlock_irqrestore(&instance->hba_lock, flags);
+		scmd->result = DID_ERROR << 16;
+		done(scmd);
+		return 0;
+	}
+
 	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
 		spin_unlock_irqrestore(&instance->hba_lock, flags);
 		return SCSI_MLQUEUE_HOST_BUSY;
@@ -1591,7 +1616,8 @@ void megaraid_sas_kill_hba(struct megasa
 	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
 	    (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
 	    (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) {
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
 		writel(MFI_STOP_ADP, &instance->reg_set->doorbell);
 	} else {
 		writel(MFI_STOP_ADP, &instance->reg_set->inbound_doorbell);
@@ -1615,10 +1641,7 @@ megasas_check_and_restore_queue_depth(st
 
 		spin_lock_irqsave(instance->host->host_lock, flags);
 		instance->flag &= ~MEGASAS_FW_BUSY;
-		if ((instance->pdev->device ==
-			PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
-			(instance->pdev->device ==
-			PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+		if (instance->is_imr) {
 			instance->host->can_queue =
 				instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
 		} else
@@ -1695,7 +1718,7 @@ void megasas_do_ocr(struct megasas_insta
 	(instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) {
 		*instance->consumer     = MEGASAS_ADPRESET_INPROG_SIGN;
 	}
-	instance->instancet->disable_intr(instance->reg_set);
+	instance->instancet->disable_intr(instance);
 	instance->adprecovery   = MEGASAS_ADPRESET_SM_INFAULT;
 	instance->issuepend_done = 0;
 
@@ -1966,7 +1989,8 @@ static int megasas_reset_bus_host(struct
 	 * First wait for all commands to complete
 	 */
 	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER))
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
 		ret = megasas_reset_fusion(scmd->device->host);
 	else
 		ret = megasas_generic_reset(scmd);
@@ -2266,6 +2290,7 @@ megasas_complete_cmd(struct megasas_inst
 		/* Check for LD map update */
 		if ((cmd->frame->dcmd.opcode == MR_DCMD_LD_MAP_GET_INFO) &&
 		    (cmd->frame->dcmd.mbox.b[1] == 1)) {
+			fusion->fast_path_io = 0;
 			spin_lock_irqsave(instance->host->host_lock, flags);
 			if (cmd->frame->hdr.cmd_status != 0) {
 				if (cmd->frame->hdr.cmd_status !=
@@ -2283,9 +2308,13 @@ megasas_complete_cmd(struct megasas_inst
 			} else
 				instance->map_id++;
 			megasas_return_cmd(instance, cmd);
-			if (MR_ValidateMapInfo(
-				    fusion->ld_map[(instance->map_id & 1)],
-				    fusion->load_balance_info))
+
+			/*
+			 * Set fast path IO to ZERO.
+			 * Validate Map will set proper value.
+			 * Meanwhile all IOs will go as LD IO.
+			 */
+			if (MR_ValidateMapInfo(instance))
 				fusion->fast_path_io = 1;
 			else
 				fusion->fast_path_io = 0;
@@ -2477,7 +2506,7 @@ process_fw_state_change_wq(struct work_s
 		printk(KERN_NOTICE "megaraid_sas: FW detected to be in fault"
 					"state, restarting it...\n");
 
-		instance->instancet->disable_intr(instance->reg_set);
+		instance->instancet->disable_intr(instance);
 		atomic_set(&instance->fw_outstanding, 0);
 
 		atomic_set(&instance->fw_reset_no_pci_access, 1);
@@ -2518,7 +2547,7 @@ process_fw_state_change_wq(struct work_s
 		spin_lock_irqsave(&instance->hba_lock, flags);
 		instance->adprecovery	= MEGASAS_HBA_OPERATIONAL;
 		spin_unlock_irqrestore(&instance->hba_lock, flags);
-		instance->instancet->enable_intr(instance->reg_set);
+		instance->instancet->enable_intr(instance);
 
 		megasas_issue_pending_cmds_again(instance);
 		instance->issuepend_done = 1;
@@ -2581,7 +2610,7 @@ megasas_deplete_reply_queue(struct megas
 			}
 
 
-			instance->instancet->disable_intr(instance->reg_set);
+			instance->instancet->disable_intr(instance);
 			instance->adprecovery	= MEGASAS_ADPRESET_SM_INFAULT;
 			instance->issuepend_done = 0;
 
@@ -2672,9 +2701,11 @@ megasas_transition_to_ready(struct megas
 				(instance->pdev->device ==
 				 PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
 				(instance->pdev->device ==
-				 PCI_DEVICE_ID_LSI_FUSION) ||
+				PCI_DEVICE_ID_LSI_FUSION) ||
 				(instance->pdev->device ==
-				PCI_DEVICE_ID_LSI_INVADER)) {
+				PCI_DEVICE_ID_LSI_INVADER) ||
+				(instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_FURY)) {
 				writel(
 				  MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
 				  &instance->reg_set->doorbell);
@@ -2696,7 +2727,9 @@ megasas_transition_to_ready(struct megas
 			    (instance->pdev->device ==
 			     PCI_DEVICE_ID_LSI_FUSION) ||
 			    (instance->pdev->device ==
-			     PCI_DEVICE_ID_LSI_INVADER)) {
+			     PCI_DEVICE_ID_LSI_INVADER) ||
+			    (instance->pdev->device ==
+			     PCI_DEVICE_ID_LSI_FURY)) {
 				writel(MFI_INIT_HOTPLUG,
 				       &instance->reg_set->doorbell);
 			} else
@@ -2711,7 +2744,7 @@ megasas_transition_to_ready(struct megas
 			/*
 			 * Bring it to READY state; assuming max wait 10 secs
 			 */
-			instance->instancet->disable_intr(instance->reg_set);
+			instance->instancet->disable_intr(instance);
 			if ((instance->pdev->device ==
 				PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
 				(instance->pdev->device ==
@@ -2719,13 +2752,17 @@ megasas_transition_to_ready(struct megas
 				(instance->pdev->device
 					== PCI_DEVICE_ID_LSI_FUSION) ||
 				(instance->pdev->device
-					== PCI_DEVICE_ID_LSI_INVADER)) {
+					== PCI_DEVICE_ID_LSI_INVADER) ||
+				(instance->pdev->device
+					== PCI_DEVICE_ID_LSI_FURY)) {
 				writel(MFI_RESET_FLAGS,
 					&instance->reg_set->doorbell);
 				if ((instance->pdev->device ==
-				    PCI_DEVICE_ID_LSI_FUSION) ||
-				    (instance->pdev->device ==
-				     PCI_DEVICE_ID_LSI_INVADER)) {
+					PCI_DEVICE_ID_LSI_FUSION) ||
+					(instance->pdev->device ==
+					PCI_DEVICE_ID_LSI_INVADER) ||
+					(instance->pdev->device ==
+					PCI_DEVICE_ID_LSI_FURY)) {
 					for (i = 0; i < (10 * 1000); i += 20) {
 						if (readl(
 							    &instance->
@@ -2950,6 +2987,7 @@ static int megasas_create_frame_pool(str
 		cmd->frame->io.pad_0 = 0;
 		if ((instance->pdev->device != PCI_DEVICE_ID_LSI_FUSION) &&
 		    (instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) &&
+			(instance->pdev->device != PCI_DEVICE_ID_LSI_FURY) &&
 		    (reset_devices))
 			cmd->frame->hdr.cmd = MFI_CMD_INVALID;
 	}
@@ -3352,7 +3390,7 @@ megasas_issue_init_mfi(struct megasas_in
 	/*
 	 * disable the intr before firing the init frame to FW
 	 */
-	instance->instancet->disable_intr(instance->reg_set);
+	instance->instancet->disable_intr(instance);
 
 	/*
 	 * Issue the init frame in polled mode
@@ -3459,11 +3497,11 @@ static int megasas_init_fw(struct megasa
 {
 	u32 max_sectors_1;
 	u32 max_sectors_2;
-	u32 tmp_sectors, msix_enable;
+	u32 tmp_sectors, msix_enable, scratch_pad_2;
 	struct megasas_register_set __iomem *reg_set;
 	struct megasas_ctrl_info *ctrl_info;
 	unsigned long bar_list;
-	int i;
+	int i, loop, fw_msix_count = 0;
 
 	/* Find first memory bar */
 	bar_list = pci_select_bars(instance->pdev, IORESOURCE_MEM);
@@ -3487,6 +3525,7 @@ static int megasas_init_fw(struct megasa
 	switch (instance->pdev->device) {
 	case PCI_DEVICE_ID_LSI_FUSION:
 	case PCI_DEVICE_ID_LSI_INVADER:
+	case PCI_DEVICE_ID_LSI_FURY:
 		instance->instancet = &megasas_instance_template_fusion;
 		break;
 	case PCI_DEVICE_ID_LSI_SAS1078R:
@@ -3508,26 +3547,65 @@ static int megasas_init_fw(struct megasa
 		break;
 	}
 
+	if (megasas_transition_to_ready(instance, 0)) {
+		atomic_set(&instance->fw_reset_no_pci_access, 1);
+		instance->instancet->adp_reset
+			(instance, instance->reg_set);
+		atomic_set(&instance->fw_reset_no_pci_access, 0);
+		dev_info(&instance->pdev->dev,
+			"megasas: FW restarted successfully from %s!\n",
+			__func__);
+
+		/*waitting for about 30 second before retry*/
+		ssleep(30);
+
+		if (megasas_transition_to_ready(instance, 0))
+			goto fail_ready_state;
+	}
+
 	/*
-	 * We expect the FW state to be READY
+	 * MSI-X host index 0 is common for all adapter.
+	 * It is used for all MPT based Adapters.
 	 */
-	if (megasas_transition_to_ready(instance, 0))
-		goto fail_ready_state;
+	instance->reply_post_host_index_addr[0] =
+		(u32 *)((u8 *)instance->reg_set +
+		MPI2_REPLY_POST_HOST_INDEX_OFFSET);
 
 	/* Check if MSI-X is supported while in ready state */
 	msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
 		       0x4000000) >> 0x1a;
 	if (msix_enable && !msix_disable) {
+		scratch_pad_2 = readl
+			(&instance->reg_set->outbound_scratch_pad_2);
 		/* Check max MSI-X vectors */
-		if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-		    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) {
-			instance->msix_vectors = (readl(&instance->reg_set->
-							outbound_scratch_pad_2
-							  ) & 0x1F) + 1;
+		if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) {
+			instance->msix_vectors = (scratch_pad_2
+				& MR_MAX_REPLY_QUEUES_OFFSET) + 1;
+			fw_msix_count = instance->msix_vectors;
 			if (msix_vectors)
 				instance->msix_vectors =
 					min(msix_vectors,
 					    instance->msix_vectors);
+		} else if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
+			|| (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+			/* Invader/Fury supports more than 8 MSI-X */
+			instance->msix_vectors = ((scratch_pad_2
+				& MR_MAX_REPLY_QUEUES_EXT_OFFSET)
+				>> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
+			fw_msix_count = instance->msix_vectors;
+			/* Save 1-15 reply post index address to local memory
+			 * Index 0 is already saved from reg offset
+			 * MPI2_REPLY_POST_HOST_INDEX_OFFSET
+			 */
+			for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY; loop++) {
+				instance->reply_post_host_index_addr[loop] =
+					(u32 *)((u8 *)instance->reg_set +
+					MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET
+					+ (loop * 0x10));
+			}
+			if (msix_vectors)
+				instance->msix_vectors = min(msix_vectors,
+					instance->msix_vectors);
 		} else
 			instance->msix_vectors = 1;
 		/* Don't bother allocating more MSI-X vectors than cpus */
@@ -3547,6 +3625,12 @@ static int megasas_init_fw(struct megasa
 			}
 		} else
 			instance->msix_vectors = 0;
+
+		dev_info(&instance->pdev->dev, "[scsi%d]: FW supports"
+			"<%d> MSIX vector,Online CPUs: <%d>,"
+			"Current MSIX <%d>\n", instance->host->host_no,
+			fw_msix_count, (unsigned int)num_online_cpus(),
+			instance->msix_vectors);
 	}
 
 	/* Get operational params, sge flags, send init cmd to controller */
@@ -3585,8 +3669,32 @@ static int megasas_init_fw(struct megasa
 		max_sectors_2 = ctrl_info->max_request_size;
 
 		tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2);
+
+		/*Check whether controller is iMR or MR */
+		if (ctrl_info->memory_size) {
+			instance->is_imr = 0;
+			dev_info(&instance->pdev->dev, "Controller type: MR,"
+				"Memory size is: %dMB\n",
+				ctrl_info->memory_size);
+		} else {
+			instance->is_imr = 1;
+			dev_info(&instance->pdev->dev,
+				"Controller type: iMR\n");
+		}
 		instance->disableOnlineCtrlReset =
 		ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
+		instance->UnevenSpanSupport =
+			ctrl_info->adapterOperations2.supportUnevenSpans;
+		if (instance->UnevenSpanSupport) {
+			struct fusion_context *fusion = instance->ctrl_context;
+			dev_info(&instance->pdev->dev, "FW supports: "
+			"UnevenSpanSupport=%x\n", instance->UnevenSpanSupport);
+			if (MR_ValidateMapInfo(instance))
+				fusion->fast_path_io = 1;
+			else
+				fusion->fast_path_io = 0;
+
+		}
 	}
 
 	instance->max_sectors_per_req = instance->max_num_sge *
@@ -3597,8 +3705,7 @@ static int megasas_init_fw(struct megasa
 	kfree(ctrl_info);
 
 	/* Check for valid throttlequeuedepth module parameter */
-	if (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY ||
-	    instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) {
+	if (instance->is_imr) {
 		if (throttlequeuedepth > (instance->max_fw_cmds -
 					  MEGASAS_SKINNY_INT_CMDS))
 			instance->throttlequeuedepth =
@@ -3882,8 +3989,7 @@ static int megasas_io_attach(struct mega
 	 */
 	host->irq = instance->pdev->irq;
 	host->unique_id = instance->unique_id;
-	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
-		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+	if (instance->is_imr) {
 		host->can_queue =
 			instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
 	} else
@@ -3925,7 +4031,8 @@ static int megasas_io_attach(struct mega
 
 	/* Fusion only supports host reset */
 	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)) {
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
 		host->hostt->eh_device_reset_handler = NULL;
 		host->hostt->eh_bus_reset_handler = NULL;
 	}
@@ -4036,6 +4143,7 @@ static int megasas_probe_one(struct pci_
 	switch (instance->pdev->device) {
 	case PCI_DEVICE_ID_LSI_FUSION:
 	case PCI_DEVICE_ID_LSI_INVADER:
+	case PCI_DEVICE_ID_LSI_FURY:
 	{
 		struct fusion_context *fusion;
 
@@ -4076,6 +4184,7 @@ static int megasas_probe_one(struct pci_
 	instance->ev = NULL;
 	instance->issuepend_done = 1;
 	instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
+	instance->is_imr = 0;
 	megasas_poll_wait_aen = 0;
 
 	instance->evt_detail = pci_alloc_consistent(pdev,
@@ -4126,9 +4235,11 @@ static int megasas_probe_one(struct pci_
 	instance->unload = 1;
 	instance->last_time = 0;
 	instance->disableOnlineCtrlReset = 1;
+	instance->UnevenSpanSupport = 0;
 
 	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER))
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
 		INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq);
 	else
 		INIT_WORK(&instance->work_init, process_fw_state_change_wq);
@@ -4139,6 +4250,7 @@ static int megasas_probe_one(struct pci_
 	if (megasas_init_fw(instance))
 		goto fail_init_mfi;
 
+retry_irq_register:
 	/*
 	 * Register IRQ
 	 */
@@ -4156,7 +4268,9 @@ static int megasas_probe_one(struct pci_
 					free_irq(
 						instance->msixentry[j].vector,
 						&instance->irq_context[j]);
-				goto fail_irq;
+				/* Retry irq register for IO_APIC */
+				instance->msix_vectors = 0;
+				goto retry_irq_register;
 			}
 		}
 	} else {
@@ -4170,7 +4284,7 @@ static int megasas_probe_one(struct pci_
 		}
 	}
 
-	instance->instancet->enable_intr(instance->reg_set);
+	instance->instancet->enable_intr(instance);
 
 	/*
 	 * Store instance in PCI softstate
@@ -4210,7 +4324,7 @@ static int megasas_probe_one(struct pci_
 	megasas_mgmt_info.max_index--;
 
 	pci_set_drvdata(pdev, NULL);
-	instance->instancet->disable_intr(instance->reg_set);
+	instance->instancet->disable_intr(instance);
 	if (instance->msix_vectors)
 		for (i = 0 ; i < instance->msix_vectors; i++)
 			free_irq(instance->msixentry[i].vector,
@@ -4219,7 +4333,8 @@ static int megasas_probe_one(struct pci_
 		free_irq(instance->pdev->irq, &instance->irq_context[0]);
 fail_irq:
 	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
-	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER))
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
 		megasas_release_fusion(instance);
 	else
 		megasas_release_mfi(instance);
@@ -4359,7 +4474,7 @@ megasas_suspend(struct pci_dev *pdev, pm
 	tasklet_kill(&instance->isr_tasklet);
 
 	pci_set_drvdata(instance->pdev, instance);
-	instance->instancet->disable_intr(instance->reg_set);
+	instance->instancet->disable_intr(instance);
 
 	if (instance->msix_vectors)
 		for (i = 0 ; i < instance->msix_vectors; i++)
@@ -4430,6 +4545,7 @@ megasas_resume(struct pci_dev *pdev)
 	switch (instance->pdev->device) {
 	case PCI_DEVICE_ID_LSI_FUSION:
 	case PCI_DEVICE_ID_LSI_INVADER:
+	case PCI_DEVICE_ID_LSI_FURY:
 	{
 		megasas_reset_reply_desc(instance);
 		if (megasas_ioc_init_fusion(instance)) {
@@ -4483,7 +4599,7 @@ megasas_resume(struct pci_dev *pdev)
 		}
 	}
 
-	instance->instancet->enable_intr(instance->reg_set);
+	instance->instancet->enable_intr(instance);
 	instance->unload = 0;
 
 	/*
@@ -4565,7 +4681,7 @@ static void megasas_detach_one(struct pc
 
 	pci_set_drvdata(instance->pdev, NULL);
 
-	instance->instancet->disable_intr(instance->reg_set);
+	instance->instancet->disable_intr(instance);
 
 	if (instance->msix_vectors)
 		for (i = 0 ; i < instance->msix_vectors; i++)
@@ -4579,6 +4695,7 @@ static void megasas_detach_one(struct pc
 	switch (instance->pdev->device) {
 	case PCI_DEVICE_ID_LSI_FUSION:
 	case PCI_DEVICE_ID_LSI_INVADER:
+	case PCI_DEVICE_ID_LSI_FURY:
 		megasas_release_fusion(instance);
 		for (i = 0; i < 2 ; i++)
 			if (fusion->ld_map[i])
@@ -4591,10 +4708,6 @@ static void megasas_detach_one(struct pc
 		break;
 	default:
 		megasas_release_mfi(instance);
-		pci_free_consistent(pdev,
-				    sizeof(struct megasas_evt_detail),
-				    instance->evt_detail,
-				    instance->evt_detail_h);
 		pci_free_consistent(pdev, sizeof(u32),
 				    instance->producer,
 				    instance->producer_h);
@@ -4604,6 +4717,9 @@ static void megasas_detach_one(struct pc
 		break;
 	}
 
+	if (instance->evt_detail)
+		pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
+				instance->evt_detail, instance->evt_detail_h);
 	scsi_host_put(host);
 
 	pci_set_drvdata(pdev, NULL);
@@ -4625,7 +4741,7 @@ static void megasas_shutdown(struct pci_
 	instance->unload = 1;
 	megasas_flush_cache(instance);
 	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
-	instance->instancet->disable_intr(instance->reg_set);
+	instance->instancet->disable_intr(instance);
 	if (instance->msix_vectors)
 		for (i = 0 ; i < instance->msix_vectors; i++)
 			free_irq(instance->msixentry[i].vector,
@@ -4852,10 +4968,12 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
 				    sense, sense_handle);
 	}
 
-	for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) {
-		dma_free_coherent(&instance->pdev->dev,
-				    kern_sge32[i].length,
-				    kbuff_arr[i], kern_sge32[i].phys_addr);
+	for (i = 0; i < ioc->sge_count; i++) {
+		if (kbuff_arr[i])
+			dma_free_coherent(&instance->pdev->dev,
+					  kern_sge32[i].length,
+					  kbuff_arr[i],
+					  kern_sge32[i].phys_addr);
 	}
 
 	megasas_return_cmd(instance, cmd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas_fp.c linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_fp.c
--- linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas_fp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_fp.c	2013-08-25 20:43:22.000000000 -0400
@@ -60,10 +60,22 @@
 #define FALSE 0
 #define TRUE 1
 
+#define SPAN_DEBUG 0
+#define SPAN_ROW_SIZE(map, ld, index_) (MR_LdSpanPtrGet(ld, index_, map)->spanRowSize)
+#define SPAN_ROW_DATA_SIZE(map_, ld, index_)   (MR_LdSpanPtrGet(ld, index_, map)->spanRowDataSize)
+#define SPAN_INVALID  0xff
+
 /* Prototypes */
-void
-mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map,
-			      struct LD_LOAD_BALANCE_INFO *lbInfo);
+void mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map,
+	struct LD_LOAD_BALANCE_INFO *lbInfo);
+
+static void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map,
+	PLD_SPAN_INFO ldSpanInfo);
+static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
+	u64 stripRow, u16 stripRef, struct IO_REQUEST_INFO *io_info,
+	struct RAID_CONTEXT *pRAID_Context, struct MR_FW_RAID_MAP_ALL *map);
+static u64 get_row_from_strip(struct megasas_instance *instance, u32 ld,
+	u64 strip, struct MR_FW_RAID_MAP_ALL *map);
 
 u32 mega_mod64(u64 dividend, u32 divisor)
 {
@@ -148,9 +160,12 @@ static struct MR_LD_SPAN *MR_LdSpanPtrGe
 /*
  * This function will validate Map info data provided by FW
  */
-u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
-		      struct LD_LOAD_BALANCE_INFO *lbInfo)
+u8 MR_ValidateMapInfo(struct megasas_instance *instance)
 {
+	struct fusion_context *fusion = instance->ctrl_context;
+	struct MR_FW_RAID_MAP_ALL *map = fusion->ld_map[(instance->map_id & 1)];
+	struct LD_LOAD_BALANCE_INFO *lbInfo = fusion->load_balance_info;
+	PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span;
 	struct MR_FW_RAID_MAP *pFwRaidMap = &map->raidMap;
 
 	if (pFwRaidMap->totalSize !=
@@ -167,13 +182,16 @@ u8 MR_ValidateMapInfo(struct MR_FW_RAID_
 		return 0;
 	}
 
+	if (instance->UnevenSpanSupport)
+		mr_update_span_set(map, ldSpanInfo);
+
 	mr_update_load_balance_params(map, lbInfo);
 
 	return 1;
 }
 
 u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
-		    struct MR_FW_RAID_MAP_ALL *map, int *div_error)
+		    struct MR_FW_RAID_MAP_ALL *map)
 {
 	struct MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map);
 	struct MR_QUAD_ELEMENT    *quad;
@@ -185,10 +203,8 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64
 		for (j = 0; j < pSpanBlock->block_span_info.noElements; j++) {
 			quad = &pSpanBlock->block_span_info.quad[j];
 
-			if (quad->diff == 0) {
-				*div_error = 1;
-				return span;
-			}
+			if (quad->diff == 0)
+				return SPAN_INVALID;
 			if (quad->logStart <= row  &&  row <= quad->logEnd  &&
 			    (mega_mod64(row-quad->logStart, quad->diff)) == 0) {
 				if (span_blk != NULL) {
@@ -207,7 +223,456 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64
 			}
 		}
 	}
-	return span;
+	return SPAN_INVALID;
+}
+
+/*
+******************************************************************************
+*
+* Function to print info about span set created in driver from FW raid map
+*
+* Inputs :
+* map    - LD map
+* ldSpanInfo - ldSpanInfo per HBA instance
+*/
+#if SPAN_DEBUG
+static int getSpanInfo(struct MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo)
+{
+
+	u8   span;
+	u32    element;
+	struct MR_LD_RAID *raid;
+	LD_SPAN_SET *span_set;
+	struct MR_QUAD_ELEMENT    *quad;
+	int ldCount;
+	u16 ld;
+
+	for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
+		ld = MR_TargetIdToLdGet(ldCount, map);
+			if (ld >= MAX_LOGICAL_DRIVES)
+				continue;
+		raid = MR_LdRaidGet(ld, map);
+		dev_dbg(&instance->pdev->dev, "LD %x: span_depth=%x\n",
+			ld, raid->spanDepth);
+		for (span = 0; span < raid->spanDepth; span++)
+			dev_dbg(&instance->pdev->dev, "Span=%x,"
+			" number of quads=%x\n", span,
+			map->raidMap.ldSpanMap[ld].spanBlock[span].
+			block_span_info.noElements);
+		for (element = 0; element < MAX_QUAD_DEPTH; element++) {
+			span_set = &(ldSpanInfo[ld].span_set[element]);
+			if (span_set->span_row_data_width == 0)
+				break;
+
+			dev_dbg(&instance->pdev->dev, "Span Set %x:"
+				"width=%x, diff=%x\n", element,
+				(unsigned int)span_set->span_row_data_width,
+				(unsigned int)span_set->diff);
+			dev_dbg(&instance->pdev->dev, "logical LBA"
+				"start=0x%08lx, end=0x%08lx\n",
+				(long unsigned int)span_set->log_start_lba,
+				(long unsigned int)span_set->log_end_lba);
+			dev_dbg(&instance->pdev->dev, "span row start=0x%08lx,"
+				" end=0x%08lx\n",
+				(long unsigned int)span_set->span_row_start,
+				(long unsigned int)span_set->span_row_end);
+			dev_dbg(&instance->pdev->dev, "data row start=0x%08lx,"
+				" end=0x%08lx\n",
+				(long unsigned int)span_set->data_row_start,
+				(long unsigned int)span_set->data_row_end);
+			dev_dbg(&instance->pdev->dev, "data strip start=0x%08lx,"
+				" end=0x%08lx\n",
+				(long unsigned int)span_set->data_strip_start,
+				(long unsigned int)span_set->data_strip_end);
+
+			for (span = 0; span < raid->spanDepth; span++) {
+				if (map->raidMap.ldSpanMap[ld].spanBlock[span].
+					block_span_info.noElements >=
+					element + 1) {
+					quad = &map->raidMap.ldSpanMap[ld].
+						spanBlock[span].block_span_info.
+						quad[element];
+				dev_dbg(&instance->pdev->dev, "Span=%x,"
+					"Quad=%x, diff=%x\n", span,
+					element, quad->diff);
+				dev_dbg(&instance->pdev->dev,
+					"offset_in_span=0x%08lx\n",
+					(long unsigned int)quad->offsetInSpan);
+				dev_dbg(&instance->pdev->dev,
+					"logical start=0x%08lx, end=0x%08lx\n",
+					(long unsigned int)quad->logStart,
+					(long unsigned int)quad->logEnd);
+				}
+			}
+		}
+	}
+	return 0;
+}
+#endif
+
+/*
+******************************************************************************
+*
+* This routine calculates the Span block for given row using spanset.
+*
+* Inputs :
+*    instance - HBA instance
+*    ld   - Logical drive number
+*    row        - Row number
+*    map    - LD map
+*
+* Outputs :
+*
+*    span          - Span number
+*    block         - Absolute Block number in the physical disk
+*    div_error	   - Devide error code.
+*/
+
+u32 mr_spanset_get_span_block(struct megasas_instance *instance,
+		u32 ld, u64 row, u64 *span_blk, struct MR_FW_RAID_MAP_ALL *map)
+{
+	struct fusion_context *fusion = instance->ctrl_context;
+	struct MR_LD_RAID         *raid = MR_LdRaidGet(ld, map);
+	LD_SPAN_SET *span_set;
+	struct MR_QUAD_ELEMENT    *quad;
+	u32    span, info;
+	PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span;
+
+	for (info = 0; info < MAX_QUAD_DEPTH; info++) {
+		span_set = &(ldSpanInfo[ld].span_set[info]);
+
+		if (span_set->span_row_data_width == 0)
+			break;
+
+		if (row > span_set->data_row_end)
+			continue;
+
+		for (span = 0; span < raid->spanDepth; span++)
+			if (map->raidMap.ldSpanMap[ld].spanBlock[span].
+				block_span_info.noElements >= info+1) {
+				quad = &map->raidMap.ldSpanMap[ld].
+					spanBlock[span].
+					block_span_info.quad[info];
+				if (quad->diff == 0)
+					return SPAN_INVALID;
+				if (quad->logStart <= row  &&
+					row <= quad->logEnd  &&
+					(mega_mod64(row - quad->logStart,
+						quad->diff)) == 0) {
+					if (span_blk != NULL) {
+						u64  blk;
+						blk = mega_div64_32
+						    ((row - quad->logStart),
+						    quad->diff);
+						blk = (blk + quad->offsetInSpan)
+							 << raid->stripeShift;
+						*span_blk = blk;
+					}
+					return span;
+				}
+			}
+	}
+	return SPAN_INVALID;
+}
+
+/*
+******************************************************************************
+*
+* This routine calculates the row for given strip using spanset.
+*
+* Inputs :
+*    instance - HBA instance
+*    ld   - Logical drive number
+*    Strip        - Strip
+*    map    - LD map
+*
+* Outputs :
+*
+*    row         - row associated with strip
+*/
+
+static u64  get_row_from_strip(struct megasas_instance *instance,
+	u32 ld, u64 strip, struct MR_FW_RAID_MAP_ALL *map)
+{
+	struct fusion_context *fusion = instance->ctrl_context;
+	struct MR_LD_RAID	*raid = MR_LdRaidGet(ld, map);
+	LD_SPAN_SET	*span_set;
+	PLD_SPAN_INFO	ldSpanInfo = fusion->log_to_span;
+	u32		info, strip_offset, span, span_offset;
+	u64		span_set_Strip, span_set_Row, retval;
+
+	for (info = 0; info < MAX_QUAD_DEPTH; info++) {
+		span_set = &(ldSpanInfo[ld].span_set[info]);
+
+		if (span_set->span_row_data_width == 0)
+			break;
+		if (strip > span_set->data_strip_end)
+			continue;
+
+		span_set_Strip = strip - span_set->data_strip_start;
+		strip_offset = mega_mod64(span_set_Strip,
+				span_set->span_row_data_width);
+		span_set_Row = mega_div64_32(span_set_Strip,
+				span_set->span_row_data_width) * span_set->diff;
+		for (span = 0, span_offset = 0; span < raid->spanDepth; span++)
+			if (map->raidMap.ldSpanMap[ld].spanBlock[span].
+				block_span_info.noElements >= info+1) {
+				if (strip_offset >=
+					span_set->strip_offset[span])
+					span_offset++;
+				else
+					break;
+			}
+#if SPAN_DEBUG
+		dev_info(&instance->pdev->dev, "Strip 0x%llx,"
+			"span_set_Strip 0x%llx, span_set_Row 0x%llx"
+			"data width 0x%llx span offset 0x%x\n", strip,
+			(unsigned long long)span_set_Strip,
+			(unsigned long long)span_set_Row,
+			(unsigned long long)span_set->span_row_data_width,
+			span_offset);
+		dev_info(&instance->pdev->dev, "For strip 0x%llx"
+			"row is 0x%llx\n", strip,
+			(unsigned long long) span_set->data_row_start +
+			(unsigned long long) span_set_Row + (span_offset - 1));
+#endif
+		retval = (span_set->data_row_start + span_set_Row +
+				(span_offset - 1));
+		return retval;
+	}
+	return -1LLU;
+}
+
+
+/*
+******************************************************************************
+*
+* This routine calculates the Start Strip for given row using spanset.
+*
+* Inputs :
+*    instance - HBA instance
+*    ld   - Logical drive number
+*    row        - Row number
+*    map    - LD map
+*
+* Outputs :
+*
+*    Strip         - Start strip associated with row
+*/
+
+static u64 get_strip_from_row(struct megasas_instance *instance,
+		u32 ld, u64 row, struct MR_FW_RAID_MAP_ALL *map)
+{
+	struct fusion_context *fusion = instance->ctrl_context;
+	struct MR_LD_RAID         *raid = MR_LdRaidGet(ld, map);
+	LD_SPAN_SET *span_set;
+	struct MR_QUAD_ELEMENT    *quad;
+	PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span;
+	u32    span, info;
+	u64  strip;
+
+	for (info = 0; info < MAX_QUAD_DEPTH; info++) {
+		span_set = &(ldSpanInfo[ld].span_set[info]);
+
+		if (span_set->span_row_data_width == 0)
+			break;
+		if (row > span_set->data_row_end)
+			continue;
+
+		for (span = 0; span < raid->spanDepth; span++)
+			if (map->raidMap.ldSpanMap[ld].spanBlock[span].
+				block_span_info.noElements >= info+1) {
+				quad = &map->raidMap.ldSpanMap[ld].
+					spanBlock[span].block_span_info.quad[info];
+				if (quad->logStart <= row  &&
+					row <= quad->logEnd  &&
+					mega_mod64((row - quad->logStart),
+					quad->diff) == 0) {
+					strip = mega_div64_32
+						(((row - span_set->data_row_start)
+							- quad->logStart),
+							quad->diff);
+					strip *= span_set->span_row_data_width;
+					strip += span_set->data_strip_start;
+					strip += span_set->strip_offset[span];
+					return strip;
+				}
+			}
+	}
+	dev_err(&instance->pdev->dev, "get_strip_from_row"
+		"returns invalid strip for ld=%x, row=%lx\n",
+		ld, (long unsigned int)row);
+	return -1;
+}
+
+/*
+******************************************************************************
+*
+* This routine calculates the Physical Arm for given strip using spanset.
+*
+* Inputs :
+*    instance - HBA instance
+*    ld   - Logical drive number
+*    strip      - Strip
+*    map    - LD map
+*
+* Outputs :
+*
+*    Phys Arm         - Phys Arm associated with strip
+*/
+
+static u32 get_arm_from_strip(struct megasas_instance *instance,
+	u32 ld, u64 strip, struct MR_FW_RAID_MAP_ALL *map)
+{
+	struct fusion_context *fusion = instance->ctrl_context;
+	struct MR_LD_RAID         *raid = MR_LdRaidGet(ld, map);
+	LD_SPAN_SET *span_set;
+	PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span;
+	u32    info, strip_offset, span, span_offset, retval;
+
+	for (info = 0 ; info < MAX_QUAD_DEPTH; info++) {
+		span_set = &(ldSpanInfo[ld].span_set[info]);
+
+		if (span_set->span_row_data_width == 0)
+			break;
+		if (strip > span_set->data_strip_end)
+			continue;
+
+		strip_offset = (uint)mega_mod64
+				((strip - span_set->data_strip_start),
+				span_set->span_row_data_width);
+
+		for (span = 0, span_offset = 0; span < raid->spanDepth; span++)
+			if (map->raidMap.ldSpanMap[ld].spanBlock[span].
+				block_span_info.noElements >= info+1) {
+				if (strip_offset >=
+					span_set->strip_offset[span])
+					span_offset =
+						span_set->strip_offset[span];
+				else
+					break;
+			}
+#if SPAN_DEBUG
+		dev_info(&instance->pdev->dev, "get_arm_from_strip:"
+			"for ld=0x%x strip=0x%lx arm is  0x%x\n", ld,
+			(long unsigned int)strip, (strip_offset - span_offset));
+#endif
+		retval = (strip_offset - span_offset);
+		return retval;
+	}
+
+	dev_err(&instance->pdev->dev, "get_arm_from_strip"
+		"returns invalid arm for ld=%x strip=%lx\n",
+		ld, (long unsigned int)strip);
+
+	return -1;
+}
+
+/* This Function will return Phys arm */
+u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe,
+		struct MR_FW_RAID_MAP_ALL *map)
+{
+	struct MR_LD_RAID  *raid = MR_LdRaidGet(ld, map);
+	/* Need to check correct default value */
+	u32    arm = 0;
+
+	switch (raid->level) {
+	case 0:
+	case 5:
+	case 6:
+		arm = mega_mod64(stripe, SPAN_ROW_SIZE(map, ld, span));
+		break;
+	case 1:
+		/* start with logical arm */
+		arm = get_arm_from_strip(instance, ld, stripe, map);
+		if (arm != -1U)
+			arm *= 2;
+		break;
+	}
+
+	return arm;
+}
+
+
+/*
+******************************************************************************
+*
+* This routine calculates the arm, span and block for the specified stripe and
+* reference in stripe using spanset
+*
+* Inputs :
+*
+*    ld   - Logical drive number
+*    stripRow        - Stripe number
+*    stripRef    - Reference in stripe
+*
+* Outputs :
+*
+*    span          - Span number
+*    block         - Absolute Block number in the physical disk
+*/
+static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
+		u64 stripRow, u16 stripRef, struct IO_REQUEST_INFO *io_info,
+		struct RAID_CONTEXT *pRAID_Context,
+		struct MR_FW_RAID_MAP_ALL *map)
+{
+	struct MR_LD_RAID  *raid = MR_LdRaidGet(ld, map);
+	u32     pd, arRef;
+	u8      physArm, span;
+	u64     row;
+	u8	retval = TRUE;
+	u8	do_invader = 0;
+	u64	*pdBlock = &io_info->pdBlock;
+	u16	*pDevHandle = &io_info->devHandle;
+	u32	logArm, rowMod, armQ, arm;
+
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
+		instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+		do_invader = 1;
+
+	/*Get row and span from io_info for Uneven Span IO.*/
+	row	    = io_info->start_row;
+	span	    = io_info->start_span;
+
+
+	if (raid->level == 6) {
+		logArm = get_arm_from_strip(instance, ld, stripRow, map);
+		if (logArm == -1U)
+			return FALSE;
+		rowMod = mega_mod64(row, SPAN_ROW_SIZE(map, ld, span));
+		armQ = SPAN_ROW_SIZE(map, ld, span) - 1 - rowMod;
+		arm = armQ + 1 + logArm;
+		if (arm >= SPAN_ROW_SIZE(map, ld, span))
+			arm -= SPAN_ROW_SIZE(map, ld, span);
+		physArm = (u8)arm;
+	} else
+		/* Calculate the arm */
+		physArm = get_arm(instance, ld, span, stripRow, map);
+	if (physArm == 0xFF)
+		return FALSE;
+
+	arRef       = MR_LdSpanArrayGet(ld, span, map);
+	pd          = MR_ArPdGet(arRef, physArm, map);
+
+	if (pd != MR_PD_INVALID)
+		*pDevHandle = MR_PdDevHandleGet(pd, map);
+	else {
+		*pDevHandle = MR_PD_INVALID;
+		if ((raid->level >= 5) &&
+			(!do_invader  || (do_invader &&
+			(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
+			pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
+		else if (raid->level == 1) {
+			pd = MR_ArPdGet(arRef, physArm + 1, map);
+			if (pd != MR_PD_INVALID)
+				*pDevHandle = MR_PdDevHandleGet(pd, map);
+		}
+	}
+
+	*pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
+	pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
+					physArm;
+	return retval;
 }
 
 /*
@@ -228,16 +693,22 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64
 *    block         - Absolute Block number in the physical disk
 */
 u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
-		   u16 stripRef, u64 *pdBlock, u16 *pDevHandle,
-		   struct RAID_CONTEXT *pRAID_Context,
-		   struct MR_FW_RAID_MAP_ALL *map)
+		u16 stripRef, struct IO_REQUEST_INFO *io_info,
+		struct RAID_CONTEXT *pRAID_Context,
+		struct MR_FW_RAID_MAP_ALL *map)
 {
 	struct MR_LD_RAID  *raid = MR_LdRaidGet(ld, map);
 	u32         pd, arRef;
 	u8          physArm, span;
 	u64         row;
 	u8	    retval = TRUE;
-	int	    error_code = 0;
+	u8          do_invader = 0;
+	u64	    *pdBlock = &io_info->pdBlock;
+	u16	    *pDevHandle = &io_info->devHandle;
+
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
+		instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+		do_invader = 1;
 
 	row =  mega_div64_32(stripRow, raid->rowDataSize);
 
@@ -267,8 +738,8 @@ u8 MR_GetPhyParams(struct megasas_instan
 		span = 0;
 		*pdBlock = row << raid->stripeShift;
 	} else {
-		span = (u8)MR_GetSpanBlock(ld, row, pdBlock, map, &error_code);
-		if (error_code == 1)
+		span = (u8)MR_GetSpanBlock(ld, row, pdBlock, map);
+		if (span == SPAN_INVALID)
 			return FALSE;
 	}
 
@@ -282,9 +753,8 @@ u8 MR_GetPhyParams(struct megasas_instan
 	else {
 		*pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */
 		if ((raid->level >= 5) &&
-		    ((instance->pdev->device != PCI_DEVICE_ID_LSI_INVADER) ||
-		     (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER &&
-		      raid->regTypeReqOnRead != REGION_TYPE_UNUSED)))
+			(!do_invader  || (do_invader &&
+			(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
 			pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
 		else if (raid->level == 1) {
 			/* Get alternate Pd. */
@@ -327,17 +797,42 @@ MR_BuildRaidContext(struct megasas_insta
 	u32         numBlocks, ldTgtId;
 	u8          isRead;
 	u8	    retval = 0;
+	u8	    startlba_span = SPAN_INVALID;
+	u64 *pdBlock = &io_info->pdBlock;
 
 	ldStartBlock = io_info->ldStartBlock;
 	numBlocks = io_info->numBlocks;
 	ldTgtId = io_info->ldTgtId;
 	isRead = io_info->isRead;
+	io_info->IoforUnevenSpan = 0;
+	io_info->start_span	= SPAN_INVALID;
 
 	ld = MR_TargetIdToLdGet(ldTgtId, map);
 	raid = MR_LdRaidGet(ld, map);
 
+	/*
+	 * if rowDataSize @RAID map and spanRowDataSize @SPAN INFO are zero
+	 * return FALSE
+	 */
+	if (raid->rowDataSize == 0) {
+		if (MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize == 0)
+			return FALSE;
+		else if (instance->UnevenSpanSupport) {
+			io_info->IoforUnevenSpan = 1;
+		} else {
+			dev_info(&instance->pdev->dev,
+				"raid->rowDataSize is 0, but has SPAN[0]"
+				"rowDataSize = 0x%0x,"
+				"but there is _NO_ UnevenSpanSupport\n",
+				MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize);
+			return FALSE;
+		}
+	}
+
 	stripSize = 1 << raid->stripeShift;
 	stripe_mask = stripSize-1;
+
+
 	/*
 	 * calculate starting row and stripe, and number of strips and rows
 	 */
@@ -347,11 +842,50 @@ MR_BuildRaidContext(struct megasas_insta
 	ref_in_end_stripe   = (u16)(endLba & stripe_mask);
 	endStrip            = endLba >> raid->stripeShift;
 	num_strips          = (u8)(endStrip - start_strip + 1); /* End strip */
-	if (raid->rowDataSize == 0)
-		return FALSE;
-	start_row           =  mega_div64_32(start_strip, raid->rowDataSize);
-	endRow              =  mega_div64_32(endStrip, raid->rowDataSize);
-	numRows             = (u8)(endRow - start_row + 1);
+
+	if (io_info->IoforUnevenSpan) {
+		start_row = get_row_from_strip(instance, ld, start_strip, map);
+		endRow	  = get_row_from_strip(instance, ld, endStrip, map);
+		if (start_row == -1ULL || endRow == -1ULL) {
+			dev_info(&instance->pdev->dev, "return from %s %d."
+				"Send IO w/o region lock.\n",
+				__func__, __LINE__);
+			return FALSE;
+		}
+
+		if (raid->spanDepth == 1) {
+			startlba_span = 0;
+			*pdBlock = start_row << raid->stripeShift;
+		} else
+			startlba_span = (u8)mr_spanset_get_span_block(instance,
+						ld, start_row, pdBlock, map);
+		if (startlba_span == SPAN_INVALID) {
+			dev_info(&instance->pdev->dev, "return from %s %d"
+				"for row 0x%llx,start strip %llx"
+				"endSrip %llx\n", __func__, __LINE__,
+				(unsigned long long)start_row,
+				(unsigned long long)start_strip,
+				(unsigned long long)endStrip);
+			return FALSE;
+		}
+		io_info->start_span	= startlba_span;
+		io_info->start_row	= start_row;
+#if SPAN_DEBUG
+		dev_dbg(&instance->pdev->dev, "Check Span number from %s %d"
+			"for row 0x%llx, start strip 0x%llx end strip 0x%llx"
+			" span 0x%x\n", __func__, __LINE__,
+			(unsigned long long)start_row,
+			(unsigned long long)start_strip,
+			(unsigned long long)endStrip, startlba_span);
+		dev_dbg(&instance->pdev->dev, "start_row 0x%llx endRow 0x%llx"
+			"Start span 0x%x\n", (unsigned long long)start_row,
+			(unsigned long long)endRow, startlba_span);
+#endif
+	} else {
+		start_row = mega_div64_32(start_strip, raid->rowDataSize);
+		endRow    = mega_div64_32(endStrip, raid->rowDataSize);
+	}
+	numRows = (u8)(endRow - start_row + 1);
 
 	/*
 	 * calculate region info.
@@ -384,28 +918,56 @@ MR_BuildRaidContext(struct megasas_insta
 			regSize = numBlocks;
 		}
 		/* multi-strip IOs always need to full stripe locked */
-	} else {
+	} else if (io_info->IoforUnevenSpan == 0) {
+		/*
+		 * For Even span region lock optimization.
+		 * If the start strip is the last in the start row
+		 */
 		if (start_strip == (start_row + 1) * raid->rowDataSize - 1) {
-			/* If the start strip is the last in the start row */
 			regStart += ref_in_start_stripe;
-			regSize = stripSize - ref_in_start_stripe;
 			/* initialize count to sectors from startref to end
 			   of strip */
+			regSize = stripSize - ref_in_start_stripe;
 		}
 
+		/* add complete rows in the middle of the transfer */
 		if (numRows > 2)
-			/* Add complete rows in the middle of the transfer */
 			regSize += (numRows-2) << raid->stripeShift;
 
-		/* if IO ends within first strip of last row */
+		/* if IO ends within first strip of last row*/
 		if (endStrip == endRow*raid->rowDataSize)
 			regSize += ref_in_end_stripe+1;
 		else
 			regSize += stripSize;
+	} else {
+		/*
+		 * For Uneven span region lock optimization.
+		 * If the start strip is the last in the start row
+		 */
+		if (start_strip == (get_strip_from_row(instance, ld, start_row, map) +
+				SPAN_ROW_DATA_SIZE(map, ld, startlba_span) - 1)) {
+			regStart += ref_in_start_stripe;
+			/* initialize count to sectors from
+			 * startRef to end of strip
+			 */
+			regSize = stripSize - ref_in_start_stripe;
+		}
+		/* Add complete rows in the middle of the transfer*/
+
+		if (numRows > 2)
+			/* Add complete rows in the middle of the transfer*/
+			regSize += (numRows-2) << raid->stripeShift;
+
+		/* if IO ends within first strip of last row */
+		if (endStrip == get_strip_from_row(instance, ld, endRow, map))
+			regSize += ref_in_end_stripe + 1;
+		else
+			regSize += stripSize;
 	}
 
 	pRAID_Context->timeoutValue     = map->raidMap.fpPdIoTimeoutSec;
-	if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER)
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
 		pRAID_Context->regLockFlags = (isRead) ?
 			raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
 	else
@@ -419,30 +981,161 @@ MR_BuildRaidContext(struct megasas_insta
 	/*Get Phy Params only if FP capable, or else leave it to MR firmware
 	  to do the calculation.*/
 	if (io_info->fpOkForIo) {
-		retval = MR_GetPhyParams(instance, ld, start_strip,
-					 ref_in_start_stripe,
-					 &io_info->pdBlock,
-					 &io_info->devHandle, pRAID_Context,
-					 map);
-		/* If IO on an invalid Pd, then FP i snot possible */
+		retval = io_info->IoforUnevenSpan ?
+				mr_spanset_get_phy_params(instance, ld,
+					start_strip, ref_in_start_stripe,
+					io_info, pRAID_Context, map) :
+				MR_GetPhyParams(instance, ld, start_strip,
+					ref_in_start_stripe, io_info,
+					pRAID_Context, map);
+		/* If IO on an invalid Pd, then FP is not possible.*/
 		if (io_info->devHandle == MR_PD_INVALID)
 			io_info->fpOkForIo = FALSE;
 		return retval;
 	} else if (isRead) {
 		uint stripIdx;
 		for (stripIdx = 0; stripIdx < num_strips; stripIdx++) {
-			if (!MR_GetPhyParams(instance, ld,
-					     start_strip + stripIdx,
-					     ref_in_start_stripe,
-					     &io_info->pdBlock,
-					     &io_info->devHandle,
-					     pRAID_Context, map))
+			retval = io_info->IoforUnevenSpan ?
+				mr_spanset_get_phy_params(instance, ld,
+				    start_strip + stripIdx,
+				    ref_in_start_stripe, io_info,
+				    pRAID_Context, map) :
+				MR_GetPhyParams(instance, ld,
+				    start_strip + stripIdx, ref_in_start_stripe,
+				    io_info, pRAID_Context, map);
+			if (!retval)
 				return TRUE;
 		}
 	}
+
+#if SPAN_DEBUG
+	/* Just for testing what arm we get for strip.*/
+	if (io_info->IoforUnevenSpan)
+		get_arm_from_strip(instance, ld, start_strip, map);
+#endif
 	return TRUE;
 }
 
+/*
+******************************************************************************
+*
+* This routine pepare spanset info from Valid Raid map and store it into
+* local copy of ldSpanInfo per instance data structure.
+*
+* Inputs :
+* map    - LD map
+* ldSpanInfo - ldSpanInfo per HBA instance
+*
+*/
+void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map,
+			PLD_SPAN_INFO ldSpanInfo)
+{
+	u8   span, count;
+	u32  element, span_row_width;
+	u64  span_row;
+	struct MR_LD_RAID *raid;
+	LD_SPAN_SET *span_set, *span_set_prev;
+	struct MR_QUAD_ELEMENT    *quad;
+	int ldCount;
+	u16 ld;
+
+
+	for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
+		ld = MR_TargetIdToLdGet(ldCount, map);
+		if (ld >= MAX_LOGICAL_DRIVES)
+			continue;
+		raid = MR_LdRaidGet(ld, map);
+		for (element = 0; element < MAX_QUAD_DEPTH; element++) {
+			for (span = 0; span < raid->spanDepth; span++) {
+				if (map->raidMap.ldSpanMap[ld].spanBlock[span].
+					block_span_info.noElements <
+					element + 1)
+					continue;
+				span_set = &(ldSpanInfo[ld].span_set[element]);
+				quad = &map->raidMap.ldSpanMap[ld].
+					spanBlock[span].block_span_info.
+					quad[element];
+
+				span_set->diff = quad->diff;
+
+				for (count = 0, span_row_width = 0;
+					count < raid->spanDepth; count++) {
+					if (map->raidMap.ldSpanMap[ld].
+						spanBlock[count].
+						block_span_info.
+						noElements >= element + 1) {
+						span_set->strip_offset[count] =
+							span_row_width;
+						span_row_width +=
+							MR_LdSpanPtrGet
+							(ld, count, map)->spanRowDataSize;
+						printk(KERN_INFO "megasas:"
+							"span %x rowDataSize %x\n",
+							count, MR_LdSpanPtrGet
+							(ld, count, map)->spanRowDataSize);
+					}
+				}
+
+				span_set->span_row_data_width = span_row_width;
+				span_row = mega_div64_32(((quad->logEnd -
+					quad->logStart) + quad->diff),
+					quad->diff);
+
+				if (element == 0) {
+					span_set->log_start_lba = 0;
+					span_set->log_end_lba =
+						((span_row << raid->stripeShift)
+						* span_row_width) - 1;
+
+					span_set->span_row_start = 0;
+					span_set->span_row_end = span_row - 1;
+
+					span_set->data_strip_start = 0;
+					span_set->data_strip_end =
+						(span_row * span_row_width) - 1;
+
+					span_set->data_row_start = 0;
+					span_set->data_row_end =
+						(span_row * quad->diff) - 1;
+				} else {
+					span_set_prev = &(ldSpanInfo[ld].
+							span_set[element - 1]);
+					span_set->log_start_lba =
+						span_set_prev->log_end_lba + 1;
+					span_set->log_end_lba =
+						span_set->log_start_lba +
+						((span_row << raid->stripeShift)
+						* span_row_width) - 1;
+
+					span_set->span_row_start =
+						span_set_prev->span_row_end + 1;
+					span_set->span_row_end =
+					span_set->span_row_start + span_row - 1;
+
+					span_set->data_strip_start =
+					span_set_prev->data_strip_end + 1;
+					span_set->data_strip_end =
+						span_set->data_strip_start +
+						(span_row * span_row_width) - 1;
+
+					span_set->data_row_start =
+						span_set_prev->data_row_end + 1;
+					span_set->data_row_end =
+						span_set->data_row_start +
+						(span_row * quad->diff) - 1;
+				}
+				break;
+		}
+		if (span == raid->spanDepth)
+			break;
+	    }
+	}
+#if SPAN_DEBUG
+	getSpanInfo(map, ldSpanInfo);
+#endif
+
+}
+
 void
 mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map,
 			      struct LD_LOAD_BALANCE_INFO *lbInfo)
@@ -503,8 +1196,9 @@ u8 megasas_get_best_arm(struct LD_LOAD_B
 	diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]);
 	bestArm = (diff0 <= diff1 ? 0 : 1);
 
-	if ((bestArm == arm && pend0 > pend1 + 16)  ||
-	    (bestArm != arm && pend1 > pend0 + 16))
+	/*Make balance count from 16 to 4 to keep driver in sync with Firmware*/
+	if ((bestArm == arm && pend0 > pend1 + 4)  ||
+	    (bestArm != arm && pend1 > pend0 + 4))
 		bestArm ^= 1;
 
 	/* Update the last accessed block on the correct pd */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.c linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.c
--- linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.c	2013-08-25 20:43:22.000000000 -0400
@@ -86,8 +86,6 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_FW_R
 void
 megasas_check_and_restore_queue_depth(struct megasas_instance *instance);
 
-u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
-		      struct LD_LOAD_BALANCE_INFO *lbInfo);
 u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo,
 			   struct IO_REQUEST_INFO *in_info);
 int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
@@ -101,8 +99,10 @@ extern int resetwaittime;
  * @regs:			MFI register set
  */
 void
-megasas_enable_intr_fusion(struct megasas_register_set __iomem *regs)
+megasas_enable_intr_fusion(struct megasas_instance *instance)
 {
+	struct megasas_register_set __iomem *regs;
+	regs = instance->reg_set;
 	/* For Thunderbolt/Invader also clear intr on enable */
 	writel(~0, &regs->outbound_intr_status);
 	readl(&regs->outbound_intr_status);
@@ -111,6 +111,7 @@ megasas_enable_intr_fusion(struct megasa
 
 	/* Dummy readl to force pci flush */
 	readl(&regs->outbound_intr_mask);
+	instance->mask_interrupts = 0;
 }
 
 /**
@@ -118,10 +119,13 @@ megasas_enable_intr_fusion(struct megasa
  * @regs:			 MFI register set
  */
 void
-megasas_disable_intr_fusion(struct megasas_register_set __iomem *regs)
+megasas_disable_intr_fusion(struct megasas_instance *instance)
 {
 	u32 mask = 0xFFFFFFFF;
 	u32 status;
+	struct megasas_register_set __iomem *regs;
+	regs = instance->reg_set;
+	instance->mask_interrupts = 1;
 
 	writel(mask, &regs->outbound_intr_mask);
 	/* Dummy readl to force pci flush */
@@ -643,6 +647,12 @@ megasas_ioc_init_fusion(struct megasas_i
 	init_frame->cmd	= MFI_CMD_INIT;
 	init_frame->cmd_status = 0xFF;
 
+	/* driver support Extended MSIX */
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+		init_frame->driver_operations.
+			mfi_capabilities.support_additional_msix = 1;
+
 	init_frame->queue_info_new_phys_addr_lo = ioc_init_handle;
 	init_frame->data_xfer_len = sizeof(struct MPI2_IOC_INIT_REQUEST);
 
@@ -657,7 +667,7 @@ megasas_ioc_init_fusion(struct megasas_i
 	/*
 	 * disable the intr before firing the init frame
 	 */
-	instance->instancet->disable_intr(instance->reg_set);
+	instance->instancet->disable_intr(instance);
 
 	for (i = 0; i < (10 * 1000); i += 20) {
 		if (readl(&instance->reg_set->doorbell) & 1)
@@ -770,8 +780,7 @@ megasas_get_map_info(struct megasas_inst
 
 	fusion->fast_path_io = 0;
 	if (!megasas_get_ld_map_info(instance)) {
-		if (MR_ValidateMapInfo(fusion->ld_map[(instance->map_id & 1)],
-				       fusion->load_balance_info)) {
+		if (MR_ValidateMapInfo(instance)) {
 			fusion->fast_path_io = 1;
 			return 0;
 		}
@@ -864,6 +873,66 @@ megasas_sync_map_info(struct megasas_ins
 	return ret;
 }
 
+/*
+ * meagasas_display_intel_branding - Display branding string
+ * @instance: per adapter object
+ *
+ * Return nothing.
+ */
+static void
+megasas_display_intel_branding(struct megasas_instance *instance)
+{
+	if (instance->pdev->subsystem_vendor != PCI_VENDOR_ID_INTEL)
+		return;
+
+	switch (instance->pdev->device) {
+	case PCI_DEVICE_ID_LSI_INVADER:
+		switch (instance->pdev->subsystem_device) {
+		case MEGARAID_INTEL_RS3DC080_SSDID:
+			dev_info(&instance->pdev->dev, "scsi host %d: %s\n",
+				instance->host->host_no,
+				MEGARAID_INTEL_RS3DC080_BRANDING);
+			break;
+		case MEGARAID_INTEL_RS3DC040_SSDID:
+			dev_info(&instance->pdev->dev, "scsi host %d: %s\n",
+				instance->host->host_no,
+				MEGARAID_INTEL_RS3DC040_BRANDING);
+			break;
+		case MEGARAID_INTEL_RS3SC008_SSDID:
+			dev_info(&instance->pdev->dev, "scsi host %d: %s\n",
+				instance->host->host_no,
+				MEGARAID_INTEL_RS3SC008_BRANDING);
+			break;
+		case MEGARAID_INTEL_RS3MC044_SSDID:
+			dev_info(&instance->pdev->dev, "scsi host %d: %s\n",
+				instance->host->host_no,
+				MEGARAID_INTEL_RS3MC044_BRANDING);
+			break;
+		default:
+			break;
+		}
+		break;
+	case PCI_DEVICE_ID_LSI_FURY:
+		switch (instance->pdev->subsystem_device) {
+		case MEGARAID_INTEL_RS3WC080_SSDID:
+			dev_info(&instance->pdev->dev, "scsi host %d: %s\n",
+				instance->host->host_no,
+				MEGARAID_INTEL_RS3WC080_BRANDING);
+			break;
+		case MEGARAID_INTEL_RS3WC040_SSDID:
+			dev_info(&instance->pdev->dev, "scsi host %d: %s\n",
+				instance->host->host_no,
+				MEGARAID_INTEL_RS3WC040_BRANDING);
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+}
+
 /**
  * megasas_init_adapter_fusion -	Initializes the FW
  * @instance:		Adapter soft state
@@ -944,6 +1013,8 @@ megasas_init_adapter_fusion(struct megas
 	if (megasas_ioc_init_fusion(instance))
 		goto fail_ioc_init;
 
+	megasas_display_intel_branding(instance);
+
 	instance->flag_ieee = 1;
 
 	fusion->map_sz =  sizeof(struct MR_FW_RAID_MAP) +
@@ -1071,7 +1142,8 @@ megasas_make_sgl_fusion(struct megasas_i
 
 	fusion = instance->ctrl_context;
 
-	if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
 		struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = sgl_ptr;
 		sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
 		sgl_ptr_end->Flags = 0;
@@ -1088,7 +1160,8 @@ megasas_make_sgl_fusion(struct megasas_i
 		sgl_ptr->Length = sg_dma_len(os_sgl);
 		sgl_ptr->Address = sg_dma_address(os_sgl);
 		sgl_ptr->Flags = 0;
-		if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
+		if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+			(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
 			if (i == sge_count - 1)
 				sgl_ptr->Flags = IEEE_SGE_FLAGS_END_OF_LIST;
 		}
@@ -1100,8 +1173,10 @@ megasas_make_sgl_fusion(struct megasas_i
 		    (sge_count > fusion->max_sge_in_main_msg)) {
 
 			struct MPI25_IEEE_SGE_CHAIN64 *sg_chain;
-			if (instance->pdev->device ==
-			    PCI_DEVICE_ID_LSI_INVADER) {
+			if ((instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_INVADER) ||
+				(instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_FURY)) {
 				if ((cmd->io_request->IoFlags &
 				MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) !=
 				MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)
@@ -1117,8 +1192,10 @@ megasas_make_sgl_fusion(struct megasas_i
 			sg_chain = sgl_ptr;
 			/* Prepare chain element */
 			sg_chain->NextChainOffset = 0;
-			if (instance->pdev->device ==
-			    PCI_DEVICE_ID_LSI_INVADER)
+			if ((instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_INVADER) ||
+				(instance->pdev->device ==
+				PCI_DEVICE_ID_LSI_FURY))
 				sg_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT;
 			else
 				sg_chain->Flags =
@@ -1434,7 +1511,8 @@ megasas_build_ldio_fusion(struct megasas
 		cmd->request_desc->SCSIIO.RequestFlags =
 			(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-		if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
+		if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+			(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
 			if (io_request->RaidContext.regLockFlags ==
 			    REGION_TYPE_UNUSED)
 				cmd->request_desc->SCSIIO.RequestFlags =
@@ -1465,7 +1543,8 @@ megasas_build_ldio_fusion(struct megasas
 		cmd->request_desc->SCSIIO.RequestFlags =
 			(MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-		if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
+		if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+			(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
 			if (io_request->RaidContext.regLockFlags ==
 			    REGION_TYPE_UNUSED)
 				cmd->request_desc->SCSIIO.RequestFlags =
@@ -1522,11 +1601,27 @@ megasas_build_dcdb_fusion(struct megasas
 		io_request->RaidContext.RAIDFlags =
 			MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD <<
 			MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
+		if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+			(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+			io_request->IoFlags |=
+				MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
 		cmd->request_desc->SCSIIO.RequestFlags =
 			(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
 			 MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 		cmd->request_desc->SCSIIO.DevHandle =
 			local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
+		/*
+		 * If the command is for the tape device, set the
+		 * FP timeout to the os layer timeout value.
+		 */
+		if (scmd->device->type == TYPE_TAPE) {
+			if ((scmd->request->timeout / HZ) > 0xFFFF)
+				io_request->RaidContext.timeoutValue =
+					0xFFFF;
+			else
+				io_request->RaidContext.timeoutValue =
+					scmd->request->timeout / HZ;
+		}
 	} else {
 		io_request->Function  = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
 		io_request->DevHandle = device_id;
@@ -1825,8 +1920,15 @@ complete_cmd_fusion(struct megasas_insta
 		return IRQ_NONE;
 
 	wmb();
-	writel((MSIxIndex << 24) | fusion->last_reply_idx[MSIxIndex],
-	       &instance->reg_set->reply_post_host_index);
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
+		writel(((MSIxIndex & 0x7) << 24) |
+			fusion->last_reply_idx[MSIxIndex],
+			instance->reply_post_host_index_addr[MSIxIndex/8]);
+	else
+		writel((MSIxIndex << 24) |
+			fusion->last_reply_idx[MSIxIndex],
+			instance->reply_post_host_index_addr[0]);
 	megasas_check_and_restore_queue_depth(instance);
 	return IRQ_HANDLED;
 }
@@ -1868,6 +1970,9 @@ irqreturn_t megasas_isr_fusion(int irq,
 	struct megasas_instance *instance = irq_context->instance;
 	u32 mfiStatus, fw_state;
 
+	if (instance->mask_interrupts)
+		return IRQ_NONE;
+
 	if (!instance->msix_vectors) {
 		mfiStatus = instance->instancet->clear_intr(instance->reg_set);
 		if (!mfiStatus)
@@ -1929,7 +2034,8 @@ build_mpt_mfi_pass_thru(struct megasas_i
 	fusion = instance->ctrl_context;
 	io_req = cmd->io_request;
 
-	if (instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) {
+	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+		(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
 		struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end =
 			(struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL;
 		sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
@@ -2132,7 +2238,7 @@ int megasas_reset_fusion(struct Scsi_Hos
 	mutex_lock(&instance->reset_mutex);
 	set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
 	instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
-	instance->instancet->disable_intr(instance->reg_set);
+	instance->instancet->disable_intr(instance);
 	msleep(1000);
 
 	/* First try waiting for commands to complete */
@@ -2256,7 +2362,7 @@ int megasas_reset_fusion(struct Scsi_Hos
 
 			clear_bit(MEGASAS_FUSION_IN_RESET,
 				  &instance->reset_flags);
-			instance->instancet->enable_intr(instance->reg_set);
+			instance->instancet->enable_intr(instance);
 			instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
 
 			/* Re-fire management commands */
@@ -2318,7 +2424,7 @@ int megasas_reset_fusion(struct Scsi_Hos
 		retval = FAILED;
 	} else {
 		clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
-		instance->instancet->enable_intr(instance->reg_set);
+		instance->instancet->enable_intr(instance);
 		instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
 	}
 out:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.h linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.h
--- linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.h	2013-08-25 20:43:22.000000000 -0400
@@ -43,7 +43,7 @@
 #define HOST_DIAG_WRITE_ENABLE			    0x80
 #define HOST_DIAG_RESET_ADAPTER			    0x4
 #define MEGASAS_FUSION_MAX_RESET_TRIES		    3
-#define MAX_MSIX_QUEUES_FUSION			    16
+#define MAX_MSIX_QUEUES_FUSION			    128
 
 /* Invader defines */
 #define MPI2_TYPE_CUDA				    0x2
@@ -62,6 +62,9 @@
 #define MEGASAS_RD_WR_PROTECT_CHECK_ALL		    0x20
 #define MEGASAS_RD_WR_PROTECT_CHECK_NONE	    0x60
 
+#define MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET   (0x0000030C)
+#define MPI2_REPLY_POST_HOST_INDEX_OFFSET	(0x0000006C)
+
 /*
  * Raid context flags
  */
@@ -460,6 +463,7 @@ struct MPI2_IOC_INIT_REQUEST {
 /* mrpriv defines */
 #define MR_PD_INVALID 0xFFFF
 #define MAX_SPAN_DEPTH 8
+#define MAX_QUAD_DEPTH	MAX_SPAN_DEPTH
 #define MAX_RAIDMAP_SPAN_DEPTH (MAX_SPAN_DEPTH)
 #define MAX_ROW_SIZE 32
 #define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE)
@@ -501,7 +505,9 @@ struct MR_LD_SPAN {
 	u64      startBlk;
 	u64      numBlks;
 	u16      arrayRef;
-	u8       reserved[6];
+	u8       spanRowSize;
+	u8       spanRowDataSize;
+	u8       reserved[4];
 };
 
 struct MR_SPAN_BLOCK_INFO {
@@ -587,6 +593,10 @@ struct IO_REQUEST_INFO {
 	u16 devHandle;
 	u64 pdBlock;
 	u8 fpOkForIo;
+	u8 IoforUnevenSpan;
+	u8 start_span;
+	u8 reserved;
+	u64 start_row;
 };
 
 struct MR_LD_TARGET_SYNC {
@@ -648,6 +658,26 @@ struct LD_LOAD_BALANCE_INFO {
 	u64     last_accessed_block[2];
 };
 
+/* SPAN_SET is info caclulated from span info from Raid map per LD */
+typedef struct _LD_SPAN_SET {
+	u64  log_start_lba;
+	u64  log_end_lba;
+	u64  span_row_start;
+	u64  span_row_end;
+	u64  data_strip_start;
+	u64  data_strip_end;
+	u64  data_row_start;
+	u64  data_row_end;
+	u8   strip_offset[MAX_SPAN_DEPTH];
+	u32    span_row_data_width;
+	u32    diff;
+	u32    reserved[2];
+} LD_SPAN_SET, *PLD_SPAN_SET;
+
+typedef struct LOG_BLOCK_SPAN_INFO {
+	LD_SPAN_SET  span_set[MAX_SPAN_DEPTH];
+} LD_SPAN_INFO, *PLD_SPAN_INFO;
+
 struct MR_FW_RAID_MAP_ALL {
 	struct MR_FW_RAID_MAP raidMap;
 	struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES - 1];
@@ -692,6 +722,7 @@ struct fusion_context {
 	u32 map_sz;
 	u8 fast_path_io;
 	struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES];
+	LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES];
 };
 
 union desc_value {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas.h linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas.h
--- linux-libre-3.10-gnu/drivers/scsi/megaraid/megaraid_sas.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid/megaraid_sas.h	2013-08-25 20:43:22.000000000 -0400
@@ -33,9 +33,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"06.506.00.00-rc1"
-#define MEGASAS_RELDATE				"Feb. 9, 2013"
-#define MEGASAS_EXT_VERSION			"Sat. Feb. 9 17:00:00 PDT 2013"
+#define MEGASAS_VERSION				"06.600.18.00-rc1"
+#define MEGASAS_RELDATE				"May. 15, 2013"
+#define MEGASAS_EXT_VERSION			"Wed. May. 15 17:00:00 PDT 2013"
 
 /*
  * Device IDs
@@ -49,6 +49,33 @@
 #define	PCI_DEVICE_ID_LSI_SAS0071SKINNY		0x0071
 #define	PCI_DEVICE_ID_LSI_FUSION		0x005b
 #define PCI_DEVICE_ID_LSI_INVADER		0x005d
+#define PCI_DEVICE_ID_LSI_FURY			0x005f
+
+/*
+ * Intel HBA SSDIDs
+ */
+#define MEGARAID_INTEL_RS3DC080_SSDID		0x9360
+#define MEGARAID_INTEL_RS3DC040_SSDID		0x9362
+#define MEGARAID_INTEL_RS3SC008_SSDID		0x9380
+#define MEGARAID_INTEL_RS3MC044_SSDID		0x9381
+#define MEGARAID_INTEL_RS3WC080_SSDID		0x9341
+#define MEGARAID_INTEL_RS3WC040_SSDID		0x9343
+
+/*
+ * Intel HBA branding
+ */
+#define MEGARAID_INTEL_RS3DC080_BRANDING	\
+	"Intel(R) RAID Controller RS3DC080"
+#define MEGARAID_INTEL_RS3DC040_BRANDING	\
+	"Intel(R) RAID Controller RS3DC040"
+#define MEGARAID_INTEL_RS3SC008_BRANDING	\
+	"Intel(R) RAID Controller RS3SC008"
+#define MEGARAID_INTEL_RS3MC044_BRANDING	\
+	"Intel(R) RAID Controller RS3MC044"
+#define MEGARAID_INTEL_RS3WC080_BRANDING	\
+	"Intel(R) RAID Controller RS3WC080"
+#define MEGARAID_INTEL_RS3WC040_BRANDING	\
+	"Intel(R) RAID Controller RS3WC040"
 
 /*
  * =====================================
@@ -163,6 +190,12 @@
 #define MR_DCMD_PD_LIST_QUERY                   0x02010100
 
 /*
+ * Global functions
+ */
+extern u8 MR_ValidateMapInfo(struct megasas_instance *instance);
+
+
+/*
  * MFI command completion codes
  */
 enum MFI_STAT {
@@ -702,8 +735,126 @@ struct megasas_ctrl_info {
 	 */
 	char package_version[0x60];
 
-	u8 pad[0x800 - 0x6a0];
 
+	/*
+	* If adapterOperations.supportMoreThan8Phys is set,
+	* and deviceInterface.portCount is greater than 8,
+	* SAS Addrs for first 8 ports shall be populated in
+	* deviceInterface.portAddr, and the rest shall be
+	* populated in deviceInterfacePortAddr2.
+	*/
+	u64         deviceInterfacePortAddr2[8]; /*6a0h */
+	u8          reserved3[128];              /*6e0h */
+
+	struct {                                /*760h */
+		u16 minPdRaidLevel_0:4;
+		u16 maxPdRaidLevel_0:12;
+
+		u16 minPdRaidLevel_1:4;
+		u16 maxPdRaidLevel_1:12;
+
+		u16 minPdRaidLevel_5:4;
+		u16 maxPdRaidLevel_5:12;
+
+		u16 minPdRaidLevel_1E:4;
+		u16 maxPdRaidLevel_1E:12;
+
+		u16 minPdRaidLevel_6:4;
+		u16 maxPdRaidLevel_6:12;
+
+		u16 minPdRaidLevel_10:4;
+		u16 maxPdRaidLevel_10:12;
+
+		u16 minPdRaidLevel_50:4;
+		u16 maxPdRaidLevel_50:12;
+
+		u16 minPdRaidLevel_60:4;
+		u16 maxPdRaidLevel_60:12;
+
+		u16 minPdRaidLevel_1E_RLQ0:4;
+		u16 maxPdRaidLevel_1E_RLQ0:12;
+
+		u16 minPdRaidLevel_1E0_RLQ0:4;
+		u16 maxPdRaidLevel_1E0_RLQ0:12;
+
+		u16 reserved[6];
+	} pdsForRaidLevels;
+
+	u16 maxPds;                             /*780h */
+	u16 maxDedHSPs;                         /*782h */
+	u16 maxGlobalHSPs;                      /*784h */
+	u16 ddfSize;                            /*786h */
+	u8  maxLdsPerArray;                     /*788h */
+	u8  partitionsInDDF;                    /*789h */
+	u8  lockKeyBinding;                     /*78ah */
+	u8  maxPITsPerLd;                       /*78bh */
+	u8  maxViewsPerLd;                      /*78ch */
+	u8  maxTargetId;                        /*78dh */
+	u16 maxBvlVdSize;                       /*78eh */
+
+	u16 maxConfigurableSSCSize;             /*790h */
+	u16 currentSSCsize;                     /*792h */
+
+	char    expanderFwVersion[12];          /*794h */
+
+	u16 PFKTrialTimeRemaining;              /*7A0h */
+
+	u16 cacheMemorySize;                    /*7A2h */
+
+	struct {                                /*7A4h */
+		u32     supportPIcontroller:1;
+		u32     supportLdPIType1:1;
+		u32     supportLdPIType2:1;
+		u32     supportLdPIType3:1;
+		u32     supportLdBBMInfo:1;
+		u32     supportShieldState:1;
+		u32     blockSSDWriteCacheChange:1;
+		u32     supportSuspendResumeBGops:1;
+		u32     supportEmergencySpares:1;
+		u32     supportSetLinkSpeed:1;
+		u32     supportBootTimePFKChange:1;
+		u32     supportJBOD:1;
+		u32     disableOnlinePFKChange:1;
+		u32     supportPerfTuning:1;
+		u32     supportSSDPatrolRead:1;
+		u32     realTimeScheduler:1;
+
+		u32     supportResetNow:1;
+		u32     supportEmulatedDrives:1;
+		u32     headlessMode:1;
+		u32     dedicatedHotSparesLimited:1;
+
+
+		u32     supportUnevenSpans:1;
+		u32     reserved:11;
+	} adapterOperations2;
+
+	u8  driverVersion[32];                  /*7A8h */
+	u8  maxDAPdCountSpinup60;               /*7C8h */
+	u8  temperatureROC;                     /*7C9h */
+	u8  temperatureCtrl;                    /*7CAh */
+	u8  reserved4;                          /*7CBh */
+	u16 maxConfigurablePds;                 /*7CCh */
+
+
+	u8  reserved5[2];                       /*0x7CDh */
+
+	/*
+	* HA cluster information
+	*/
+	struct {
+		u32     peerIsPresent:1;
+		u32     peerIsIncompatible:1;
+		u32     hwIncompatible:1;
+		u32     fwVersionMismatch:1;
+		u32     ctrlPropIncompatible:1;
+		u32     premiumFeatureMismatch:1;
+		u32     reserved:26;
+	} cluster;
+
+	char clusterId[16];                     /*7D4h */
+
+	u8          pad[0x800-0x7E4];           /*7E4 */
 } __packed;
 
 /*
@@ -759,7 +910,7 @@ struct megasas_ctrl_info {
 #define MEGASAS_INT_CMDS			32
 #define MEGASAS_SKINNY_INT_CMDS			5
 
-#define MEGASAS_MAX_MSIX_QUEUES			16
+#define MEGASAS_MAX_MSIX_QUEUES			128
 /*
  * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
  * SGLs based on the size of dma_addr_t
@@ -784,6 +935,11 @@ struct megasas_ctrl_info {
 #define MFI_1068_PCSR_OFFSET			0x84
 #define MFI_1068_FW_HANDSHAKE_OFFSET		0x64
 #define MFI_1068_FW_READY			0xDDDD0000
+
+#define MR_MAX_REPLY_QUEUES_OFFSET              0X0000001F
+#define MR_MAX_REPLY_QUEUES_EXT_OFFSET          0X003FC000
+#define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT    14
+#define MR_MAX_MSIX_REG_ARRAY                   16
 /*
 * register set for both 1068 and 1078 controllers
 * structure extended for 1078 registers
@@ -893,6 +1049,15 @@ union megasas_sgl_frame {
 
 } __attribute__ ((packed));
 
+typedef union _MFI_CAPABILITIES {
+	struct {
+		u32     support_fp_remote_lun:1;
+		u32     support_additional_msix:1;
+		u32     reserved:30;
+	} mfi_capabilities;
+	u32     reg;
+} MFI_CAPABILITIES;
+
 struct megasas_init_frame {
 
 	u8 cmd;			/*00h */
@@ -900,7 +1065,7 @@ struct megasas_init_frame {
 	u8 cmd_status;		/*02h */
 
 	u8 reserved_1;		/*03h */
-	u32 reserved_2;		/*04h */
+	MFI_CAPABILITIES driver_operations; /*04h*/
 
 	u32 context;		/*08h */
 	u32 pad_0;		/*0Ch */
@@ -1297,7 +1462,7 @@ struct megasas_instance {
 
 	unsigned long base_addr;
 	struct megasas_register_set __iomem *reg_set;
-
+	u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
 	struct megasas_pd_list          pd_list[MEGASAS_MAX_PD];
 	u8     ld_ids[MEGASAS_MAX_LD_IDS];
 	s8 init_id;
@@ -1348,6 +1513,7 @@ struct megasas_instance {
 	u8 flag_ieee;
 	u8 issuepend_done;
 	u8 disableOnlineCtrlReset;
+	u8 UnevenSpanSupport;
 	u8 adprecovery;
 	unsigned long last_time;
 	u32 mfiStatus;
@@ -1366,6 +1532,8 @@ struct megasas_instance {
 	long reset_flags;
 	struct mutex reset_mutex;
 	int throttlequeuedepth;
+	u8 mask_interrupts;
+	u8 is_imr;
 };
 
 enum {
@@ -1381,8 +1549,8 @@ struct megasas_instance_template {
 	void (*fire_cmd)(struct megasas_instance *, dma_addr_t, \
 		u32, struct megasas_register_set __iomem *);
 
-	void (*enable_intr)(struct megasas_register_set __iomem *) ;
-	void (*disable_intr)(struct megasas_register_set __iomem *);
+	void (*enable_intr)(struct megasas_instance *);
+	void (*disable_intr)(struct megasas_instance *);
 
 	int (*clear_intr)(struct megasas_register_set __iomem *);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/megaraid.c linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid.c
--- linux-libre-3.10-gnu/drivers/scsi/megaraid.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/megaraid.c	2013-08-25 20:43:22.000000000 -0400
@@ -2026,7 +2026,7 @@ megaraid_abort_and_reset(adapter_t *adap
 static inline int
 make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
 {
-	*pdev = alloc_pci_dev();
+	*pdev = pci_alloc_dev(NULL);
 
 	if( *pdev == NULL ) return -1;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2.h	2013-08-25 20:43:22.000000000 -0400
@@ -8,7 +8,7 @@
  *                  scatter/gather formats.
  *  Creation Date:  June 21, 2006
  *
- *  mpi2.h Version:  02.00.25
+ *  mpi2.h Version:  02.00.27
  *
  *  Version History
  *  ---------------
@@ -75,6 +75,8 @@
  *  02-06-12  02.00.24  Bumped MPI2_HEADER_VERSION_UNIT.
  *  03-29-12  02.00.25  Bumped MPI2_HEADER_VERSION_UNIT.
  *                      Added Hard Reset delay timings.
+ *  07-10-12  02.00.26  Bumped MPI2_HEADER_VERSION_UNIT.
+ *  07-26-12  02.00.27  Bumped MPI2_HEADER_VERSION_UNIT.
  *  --------------------------------------------------------------------------
  */
 
@@ -100,7 +102,7 @@
 #define MPI2_VERSION_02_00                  (0x0200)
 
 /* versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x19)
+#define MPI2_HEADER_VERSION_UNIT            (0x1B)
 #define MPI2_HEADER_VERSION_DEV             (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2_init.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2_init.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2_init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2_init.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  *          Title:  MPI SCSI initiator mode messages and structures
  *  Creation Date:  June 23, 2006
  *
- *    mpi2_init.h Version:  02.00.13
+ *    mpi2_init.h Version:  02.00.14
  *
  *  Version History
  *  ---------------
@@ -36,6 +36,7 @@
  *  11-10-10  02.00.11  Added MPI2_SCSIIO_NUM_SGLOFFSETS define.
  *  02-06-12  02.00.13  Added alternate defines for Task Priority / Command
  *                      Priority to match SAM-4.
+ *  07-10-12  02.00.14  Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION.
  *  --------------------------------------------------------------------------
  */
 
@@ -189,6 +190,7 @@ typedef struct _MPI2_SCSI_IO_REQUEST
 #define MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT     (26)
 
 #define MPI2_SCSIIO_CONTROL_DATADIRECTION_MASK  (0x03000000)
+#define MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION (24)
 #define MPI2_SCSIIO_CONTROL_NODATATRANSFER      (0x00000000)
 #define MPI2_SCSIIO_CONTROL_WRITE               (0x01000000)
 #define MPI2_SCSIIO_CONTROL_READ                (0x02000000)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  October 11, 2006
  *
- *  mpi2_ioc.h Version:  02.00.21
+ *  mpi2_ioc.h Version:  02.00.22
  *
  *  Version History
  *  ---------------
@@ -118,6 +118,9 @@
  *                      MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE structure.
  *                      Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete.
  *  03-29-12  02.00.21  Added a product specific range to event values.
+ *  07-26-12  02.00.22  Added MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE.
+ *                      Added ElapsedSeconds field to
+ *                      MPI2_EVENT_DATA_IR_OPERATION_STATUS.
  *  --------------------------------------------------------------------------
  */
 
@@ -284,6 +287,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY
 #define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT              (0)
 
 /* IOCExceptions */
+#define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE     (0x0200)
 #define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX      (0x0100)
 
 #define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_MASK              (0x00E0)
@@ -624,7 +628,7 @@ typedef struct _MPI2_EVENT_DATA_IR_OPERA
     U8                      RAIDOperation;              /* 0x04 */
     U8                      PercentComplete;            /* 0x05 */
     U16                     Reserved2;                  /* 0x06 */
-    U32                     Resereved3;                 /* 0x08 */
+	U32                     ElapsedSeconds;             /* 0x08 */
 } MPI2_EVENT_DATA_IR_OPERATION_STATUS,
   MPI2_POINTER PTR_MPI2_EVENT_DATA_IR_OPERATION_STATUS,
   Mpi2EventDataIrOperationStatus_t,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2_raid.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2_raid.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2_raid.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2_raid.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,7 @@
  *          Title:  MPI Integrated RAID messages and structures
  *  Creation Date:  April 26, 2007
  *
- *    mpi2_raid.h Version:  02.00.08
+ *    mpi2_raid.h Version:  02.00.09
  *
  *  Version History
  *  ---------------
@@ -27,6 +27,8 @@
  *                      related structures and defines.
  *                      Added product-specific range to RAID Action values.
  *  02-06-12  02.00.08  Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN.
+ *  07-26-12  02.00.09  Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR.
+ *                      Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define.
  *  --------------------------------------------------------------------------
  */
 
@@ -276,10 +278,13 @@ typedef struct _MPI2_RAID_VOL_INDICATOR
     U64                     TotalBlocks;                    /* 0x00 */
     U64                     BlocksRemaining;                /* 0x08 */
     U32                     Flags;                          /* 0x10 */
+	U32                     ElapsedSeconds;                 /* 0x14 */
 } MPI2_RAID_VOL_INDICATOR, MPI2_POINTER PTR_MPI2_RAID_VOL_INDICATOR,
   Mpi2RaidVolIndicator_t, MPI2_POINTER pMpi2RaidVolIndicator_t;
 
 /* defines for RAID Volume Indicator Flags field */
+#define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID   (0x80000000)
+
 #define MPI2_RAID_VOL_FLAGS_OP_MASK                 (0x0000000F)
 #define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT      (0x00000000)
 #define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001)
@@ -320,7 +325,7 @@ MPI2_POINTER pMpi2RaidCompatibilityResul
 /* RAID Action Reply ActionData union */
 typedef union _MPI2_RAID_ACTION_REPLY_DATA
 {
-	U32                                     Word[5];
+	U32                                     Word[6];
 	MPI2_RAID_VOL_INDICATOR                 RaidVolumeIndicator;
 	U16                                     VolDevHandle;
 	U8                                      VolumeState;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2_tool.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpi/mpi2_tool.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpi/mpi2_tool.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2010 LSI Corporation.
+ *  Copyright (c) 2000-2012 LSI Corporation.
  *
  *
  *           Name:  mpi2_tool.h
  *          Title:  MPI diagnostic tool structures and definitions
  *  Creation Date:  March 26, 2007
  *
- *    mpi2_tool.h Version:  02.00.07
+ *    mpi2_tool.h Version:  02.00.10
  *
  *  Version History
  *  ---------------
@@ -27,6 +27,8 @@
  *                      Post Request.
  *  05-25-11  02.00.07  Added Flags field and related defines to
  *                      MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST.
+ *  07-26-12  02.00.10  Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that
+ *			it uses MPI Chain SGE as well as MPI Simple SGE.
  *  --------------------------------------------------------------------------
  */
 
@@ -270,7 +272,7 @@ typedef struct _MPI2_TOOLBOX_BEACON_REQU
 
 #define MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH    (0x5C)
 
-/* Toolbox Diagnostic CLI Tool request message */
+/* MPI v2.0 Toolbox Diagnostic CLI Tool request message */
 typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST {
     U8                      Tool;                       /* 0x00 */
     U8                      Reserved1;                  /* 0x01 */
@@ -288,7 +290,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_
     U32                     DataLength;                 /* 0x10 */
     U8                      DiagnosticCliCommand
 		[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];     /* 0x14 */
-    MPI2_SGE_SIMPLE_UNION   SGL;                        /* 0x70 */
+	MPI2_MPI_SGE_IO_UNION   SGL;                        /* 0x70 */
 } MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
   MPI2_POINTER PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
   Mpi2ToolboxDiagnosticCliRequest_t,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpt2sas_base.c linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpt2sas_base.c
--- linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpt2sas_base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpt2sas_base.c	2013-08-25 20:43:22.000000000 -0400
@@ -80,10 +80,6 @@ static int msix_disable = -1;
 module_param(msix_disable, int, 0);
 MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
 
-static int missing_delay[2] = {-1, -1};
-module_param_array(missing_delay, int, NULL, 0);
-MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
-
 static int mpt2sas_fwfault_debug;
 MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
 	"and halt firmware - (default=0)");
@@ -2199,7 +2195,7 @@ _base_display_ioc_capabilities(struct MP
 }
 
 /**
- * _base_update_missing_delay - change the missing delay timers
+ * mpt2sas_base_update_missing_delay - change the missing delay timers
  * @ioc: per adapter object
  * @device_missing_delay: amount of time till device is reported missing
  * @io_missing_delay: interval IO is returned when there is a missing device
@@ -2210,8 +2206,8 @@ _base_display_ioc_capabilities(struct MP
  * delay, as well as the io missing delay. This should be called at driver
  * load time.
  */
-static void
-_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc,
+void
+mpt2sas_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc,
 	u16 device_missing_delay, u8 io_missing_delay)
 {
 	u16 dmd, dmd_new, dmd_orignal;
@@ -2507,23 +2503,25 @@ _base_allocate_memory_pools(struct MPT2S
 	/* reply free queue sizing - taking into account for 64 FW events */
 	ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64;
 
+	/* calculate reply descriptor post queue depth */
+	ioc->reply_post_queue_depth = ioc->hba_queue_depth +
+					ioc->reply_free_queue_depth +  1;
 	/* align the reply post queue on the next 16 count boundary */
-	if (!ioc->reply_free_queue_depth % 16)
-		ioc->reply_post_queue_depth = ioc->reply_free_queue_depth + 16;
-	else
-		ioc->reply_post_queue_depth = ioc->reply_free_queue_depth +
-				32 - (ioc->reply_free_queue_depth % 16);
+	if (ioc->reply_post_queue_depth % 16)
+		ioc->reply_post_queue_depth += 16 -
+			(ioc->reply_post_queue_depth % 16);
+
+
 	if (ioc->reply_post_queue_depth >
 	    facts->MaxReplyDescriptorPostQueueDepth) {
-		ioc->reply_post_queue_depth = min_t(u16,
-		    (facts->MaxReplyDescriptorPostQueueDepth -
-		    (facts->MaxReplyDescriptorPostQueueDepth % 16)),
-		    (ioc->hba_queue_depth - (ioc->hba_queue_depth % 16)));
-		ioc->reply_free_queue_depth = ioc->reply_post_queue_depth - 16;
-		ioc->hba_queue_depth = ioc->reply_free_queue_depth - 64;
+		ioc->reply_post_queue_depth =
+			facts->MaxReplyDescriptorPostQueueDepth -
+		    (facts->MaxReplyDescriptorPostQueueDepth % 16);
+		ioc->hba_queue_depth =
+			((ioc->reply_post_queue_depth - 64) / 2) - 1;
+		ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64;
 	}
 
-
 	dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: "
 	    "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), "
 	    "chains_per_io(%d)\n", ioc->name, ioc->max_sges_in_main_message,
@@ -3940,11 +3938,15 @@ _base_diag_reset(struct MPT2SAS_ADAPTER
 	writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER,
 	     &ioc->chip->HostDiagnostic);
 
-	/* don't access any registers for 50 milliseconds */
-	msleep(50);
+	/* This delay allows the chip PCIe hardware time to finish reset tasks*/
+	if (sleep_flag == CAN_SLEEP)
+		msleep(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000);
+	else
+		mdelay(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000);
 
-	/* 300 second max wait */
-	for (count = 0; count < 3000000 ; count++) {
+	/* Approximately 300 second max wait */
+	for (count = 0; count < (300000000 /
+	    MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) {
 
 		host_diagnostic = readl(&ioc->chip->HostDiagnostic);
 
@@ -3953,11 +3955,13 @@ _base_diag_reset(struct MPT2SAS_ADAPTER
 		if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER))
 			break;
 
-		/* wait 100 msec */
+		/* Wait to pass the second read delay window */
 		if (sleep_flag == CAN_SLEEP)
-			msleep(1);
+			msleep(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC
+			       /1000);
 		else
-			mdelay(1);
+			mdelay(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC
+			       /1000);
 	}
 
 	if (host_diagnostic & MPI2_DIAG_HCB_MODE) {
@@ -4407,9 +4411,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPT
 	if (r)
 		goto out_free_resources;
 
-	if (missing_delay[0] != -1 && missing_delay[1] != -1)
-		_base_update_missing_delay(ioc, missing_delay[0],
-		    missing_delay[1]);
 	ioc->non_operational_loop = 0;
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpt2sas_base.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpt2sas_base.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpt2sas_base.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpt2sas_base.h	2013-08-25 20:43:22.000000000 -0400
@@ -69,8 +69,8 @@
 #define MPT2SAS_DRIVER_NAME		"mpt2sas"
 #define MPT2SAS_AUTHOR	"LSI Corporation <DL-MPTFusionLinux@lsi.com>"
 #define MPT2SAS_DESCRIPTION	"LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION		"14.100.00.00"
-#define MPT2SAS_MAJOR_VERSION		14
+#define MPT2SAS_DRIVER_VERSION		"15.100.00.00"
+#define MPT2SAS_MAJOR_VERSION		15
 #define MPT2SAS_MINOR_VERSION		100
 #define MPT2SAS_BUILD_VERSION		00
 #define MPT2SAS_RELEASE_VERSION		00
@@ -1055,6 +1055,9 @@ void mpt2sas_base_validate_event_type(st
 
 void mpt2sas_halt_firmware(struct MPT2SAS_ADAPTER *ioc);
 
+void mpt2sas_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc,
+	u16 device_missing_delay, u8 io_missing_delay);
+
 int mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc);
 
 /* scsih shared API */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpt2sas_scsih.c linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpt2sas_scsih.c
--- linux-libre-3.10-gnu/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2013-08-25 20:43:22.000000000 -0400
@@ -101,6 +101,10 @@ static ushort max_sectors = 0xFFFF;
 module_param(max_sectors, ushort, 0);
 MODULE_PARM_DESC(max_sectors, "max sectors, range 64 to 32767  default=32767");
 
+static int missing_delay[2] = {-1, -1};
+module_param_array(missing_delay, int, NULL, 0);
+MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay");
+
 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
 #define MPT2SAS_MAX_LUN (16895)
 static int max_lun = MPT2SAS_MAX_LUN;
@@ -3994,11 +3998,7 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd,
 			else
 				mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
 		} else
-/* MPI Revision I (UNIT = 0xA) - removed MPI2_SCSIIO_CONTROL_UNTAGGED */
-/*			mpi_control |= MPI2_SCSIIO_CONTROL_UNTAGGED;
- */
-			mpi_control |= (0x500);
-
+			mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
 	} else
 		mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
 	/* Make sure Device is not raid volume.
@@ -5815,9 +5815,10 @@ _scsih_sas_broadcast_primitive_event(str
 	u8 task_abort_retries;
 
 	mutex_lock(&ioc->tm_cmds.mutex);
-	dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: phy number(%d), "
-	    "width(%d)\n", ioc->name, __func__, event_data->PhyNum,
-	     event_data->PortWidth));
+	pr_info(MPT2SAS_FMT
+		"%s: enter: phy number(%d), width(%d)\n",
+		ioc->name, __func__, event_data->PhyNum,
+		event_data->PortWidth);
 
 	_scsih_block_io_all_device(ioc);
 
@@ -7093,12 +7094,15 @@ _scsih_scan_for_devices_after_reset(stru
 	struct _sas_device *sas_device;
 	struct _sas_node *expander_device;
 	static struct _raid_device *raid_device;
+	u8 retry_count;
 	unsigned long flags;
 
 	printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name);
 
 	_scsih_sas_host_refresh(ioc);
 
+	printk(MPT2SAS_INFO_FMT "\tscan devices: expanders start\n",
+		ioc->name);
 	/* expanders */
 	handle = 0xFFFF;
 	while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
@@ -7107,6 +7111,13 @@ _scsih_scan_for_devices_after_reset(stru
 		    MPI2_IOCSTATUS_MASK;
 		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
 			break;
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+			printk(MPT2SAS_INFO_FMT "\tbreak from expander scan: "
+				"ioc_status(0x%04x), loginfo(0x%08x)\n",
+				ioc->name, ioc_status,
+				le32_to_cpu(mpi_reply.IOCLogInfo));
+			break;
+		}
 		handle = le16_to_cpu(expander_pg0.DevHandle);
 		spin_lock_irqsave(&ioc->sas_node_lock, flags);
 		expander_device = mpt2sas_scsih_expander_find_by_sas_address(
@@ -7115,13 +7126,26 @@ _scsih_scan_for_devices_after_reset(stru
 		if (expander_device)
 			_scsih_refresh_expander_links(ioc, expander_device,
 			    handle);
-		else
+		else {
+			printk(MPT2SAS_INFO_FMT "\tBEFORE adding expander: "
+				"handle (0x%04x), sas_addr(0x%016llx)\n",
+				ioc->name, handle, (unsigned long long)
+				le64_to_cpu(expander_pg0.SASAddress));
 			_scsih_expander_add(ioc, handle);
+			printk(MPT2SAS_INFO_FMT "\tAFTER adding expander: "
+				"handle (0x%04x), sas_addr(0x%016llx)\n",
+				ioc->name, handle, (unsigned long long)
+				le64_to_cpu(expander_pg0.SASAddress));
+		}
 	}
 
+	printk(MPT2SAS_INFO_FMT "\tscan devices: expanders complete\n",
+		ioc->name);
+
 	if (!ioc->ir_firmware)
 		goto skip_to_sas;
 
+	printk(MPT2SAS_INFO_FMT "\tscan devices phys disk start\n", ioc->name);
 	/* phys disk */
 	phys_disk_num = 0xFF;
 	while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
@@ -7131,6 +7155,13 @@ _scsih_scan_for_devices_after_reset(stru
 		    MPI2_IOCSTATUS_MASK;
 		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
 			break;
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+			printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan:"
+				"ioc_status(0x%04x), loginfo(0x%08x)\n",
+				ioc->name, ioc_status,
+				le32_to_cpu(mpi_reply.IOCLogInfo));
+			break;
+		}
 		phys_disk_num = pd_pg0.PhysDiskNum;
 		handle = le16_to_cpu(pd_pg0.DevHandle);
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
@@ -7142,17 +7173,46 @@ _scsih_scan_for_devices_after_reset(stru
 		    &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
 		    handle) != 0)
 			continue;
+		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+			MPI2_IOCSTATUS_MASK;
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+			printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan "
+				"ioc_status(0x%04x), loginfo(0x%08x)\n",
+				ioc->name, ioc_status,
+				le32_to_cpu(mpi_reply.IOCLogInfo));
+			break;
+		}
 		parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
 		if (!_scsih_get_sas_address(ioc, parent_handle,
 		    &sas_address)) {
+			printk(MPT2SAS_INFO_FMT "\tBEFORE adding phys disk: "
+				" handle (0x%04x), sas_addr(0x%016llx)\n",
+				ioc->name, handle, (unsigned long long)
+				le64_to_cpu(sas_device_pg0.SASAddress));
 			mpt2sas_transport_update_links(ioc, sas_address,
 			    handle, sas_device_pg0.PhyNum,
 			    MPI2_SAS_NEG_LINK_RATE_1_5);
 			set_bit(handle, ioc->pd_handles);
-			_scsih_add_device(ioc, handle, 0, 1);
+			retry_count = 0;
+			/* This will retry adding the end device.
+			* _scsih_add_device() will decide on retries and
+			* return "1" when it should be retried
+			*/
+			while (_scsih_add_device(ioc, handle, retry_count++,
+				1)) {
+					ssleep(1);
+			}
+			printk(MPT2SAS_INFO_FMT "\tAFTER adding phys disk: "
+				" handle (0x%04x), sas_addr(0x%016llx)\n",
+				ioc->name, handle, (unsigned long long)
+				le64_to_cpu(sas_device_pg0.SASAddress));
 		}
 	}
 
+	printk(MPT2SAS_INFO_FMT "\tscan devices: phys disk complete\n",
+		ioc->name);
+
+	printk(MPT2SAS_INFO_FMT "\tscan devices: volumes start\n", ioc->name);
 	/* volumes */
 	handle = 0xFFFF;
 	while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
@@ -7161,6 +7221,13 @@ _scsih_scan_for_devices_after_reset(stru
 		    MPI2_IOCSTATUS_MASK;
 		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
 			break;
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+			printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: "
+				"ioc_status(0x%04x), loginfo(0x%08x)\n",
+				ioc->name, ioc_status,
+				le32_to_cpu(mpi_reply.IOCLogInfo));
+			break;
+		}
 		handle = le16_to_cpu(volume_pg1.DevHandle);
 		spin_lock_irqsave(&ioc->raid_device_lock, flags);
 		raid_device = _scsih_raid_device_find_by_wwid(ioc,
@@ -7172,18 +7239,38 @@ _scsih_scan_for_devices_after_reset(stru
 		    &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
 		     sizeof(Mpi2RaidVolPage0_t)))
 			continue;
+		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+			MPI2_IOCSTATUS_MASK;
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+			printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: "
+				"ioc_status(0x%04x), loginfo(0x%08x)\n",
+				ioc->name, ioc_status,
+				le32_to_cpu(mpi_reply.IOCLogInfo));
+			break;
+		}
 		if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
 		    volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
 		    volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) {
 			memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t));
 			element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED;
 			element.VolDevHandle = volume_pg1.DevHandle;
+			printk(MPT2SAS_INFO_FMT "\tBEFORE adding volume: "
+				" handle (0x%04x)\n", ioc->name,
+				volume_pg1.DevHandle);
 			_scsih_sas_volume_add(ioc, &element);
+			printk(MPT2SAS_INFO_FMT "\tAFTER adding volume: "
+				" handle (0x%04x)\n", ioc->name,
+				volume_pg1.DevHandle);
 		}
 	}
 
+	printk(MPT2SAS_INFO_FMT "\tscan devices: volumes complete\n",
+		ioc->name);
+
  skip_to_sas:
 
+	printk(MPT2SAS_INFO_FMT "\tscan devices: end devices start\n",
+		ioc->name);
 	/* sas devices */
 	handle = 0xFFFF;
 	while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
@@ -7193,6 +7280,13 @@ _scsih_scan_for_devices_after_reset(stru
 		    MPI2_IOCSTATUS_MASK;
 		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
 			break;
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+			printk(MPT2SAS_INFO_FMT "\tbreak from end device scan:"
+				" ioc_status(0x%04x), loginfo(0x%08x)\n",
+				ioc->name, ioc_status,
+				le32_to_cpu(mpi_reply.IOCLogInfo));
+				break;
+		}
 		handle = le16_to_cpu(sas_device_pg0.DevHandle);
 		if (!(_scsih_is_end_device(
 		    le32_to_cpu(sas_device_pg0.DeviceInfo))))
@@ -7205,12 +7299,31 @@ _scsih_scan_for_devices_after_reset(stru
 			continue;
 		parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
 		if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
+			printk(MPT2SAS_INFO_FMT "\tBEFORE adding end device: "
+				"handle (0x%04x), sas_addr(0x%016llx)\n",
+				ioc->name, handle, (unsigned long long)
+				le64_to_cpu(sas_device_pg0.SASAddress));
 			mpt2sas_transport_update_links(ioc, sas_address, handle,
 			    sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
-			_scsih_add_device(ioc, handle, 0, 0);
+			retry_count = 0;
+			/* This will retry adding the end device.
+			 * _scsih_add_device() will decide on retries and
+			 * return "1" when it should be retried
+			 */
+			while (_scsih_add_device(ioc, handle, retry_count++,
+				0)) {
+					ssleep(1);
+			}
+			printk(MPT2SAS_INFO_FMT "\tAFTER adding end device: "
+				"handle (0x%04x), sas_addr(0x%016llx)\n",
+				ioc->name, handle, (unsigned long long)
+				le64_to_cpu(sas_device_pg0.SASAddress));
 		}
 	}
 
+	printk(MPT2SAS_INFO_FMT "\tscan devices: end devices complete\n",
+		ioc->name);
+
 	printk(MPT2SAS_INFO_FMT "scan devices: complete\n", ioc->name);
 }
 
@@ -7303,7 +7416,9 @@ _firmware_event_work(struct work_struct
 	case MPT2SAS_PORT_ENABLE_COMPLETE:
 		ioc->start_scan = 0;
 
-
+		if (missing_delay[0] != -1 && missing_delay[1] != -1)
+			mpt2sas_base_update_missing_delay(ioc, missing_delay[0],
+				missing_delay[1]);
 
 		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "port enable: complete "
 		    "from worker thread\n", ioc->name));
@@ -8070,8 +8185,8 @@ _scsih_probe(struct pci_dev *pdev, const
 	if (max_sectors != 0xFFFF) {
 		if (max_sectors < 64) {
 			shost->max_sectors = 64;
-			printk(MPT2SAS_WARN_FMT "Invalid value %d passed "\
-			    "for max_sectors, range is 64 to 32767. Assigning "\
+			printk(MPT2SAS_WARN_FMT "Invalid value %d passed "
+			    "for max_sectors, range is 64 to 32767. Assigning "
 			    "value of 64.\n", ioc->name, max_sectors);
 		} else if (max_sectors > 32767) {
 			shost->max_sectors = 32767;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/Kconfig linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/Kconfig
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,7 @@
 # Kernel configuration file for the MPT3SAS
 #
 # This code is based on drivers/scsi/mpt3sas/Kconfig
-# Copyright (C) 2012  LSI Corporation
+# Copyright (C) 2012-2013  LSI Corporation
 #  (mailto:DL-MPTFusionLinux@lsi.com)
 
 # This program is free software; you can redistribute it and/or
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2011 LSI Corporation.
+ * Copyright (c) 2000-2013 LSI Corporation.
  *
  *
  *          Name:  mpi2_cnfg.h
  *         Title:  MPI Configuration messages and pages
  * Creation Date:  November 10, 2006
  *
- *   mpi2_cnfg.h Version:  02.00.22
+ *   mpi2_cnfg.h Version:  02.00.24
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -155,6 +155,11 @@
  *                     Added UEFIVersion field to BIOS Page 1 and defined new
  *                     BiosOptions bits.
  *                     Incorporating additions for MPI v2.5.
+ * 11-27-12  02.00.23  Added MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER.
+ *                     Added MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID.
+ * 12-20-12  02.00.24  Marked MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION as
+ *                     obsolete for MPI v2.5 and later.
+ *                     Added some defines for 12G SAS speeds.
  * --------------------------------------------------------------------------
  */
 
@@ -714,6 +719,7 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_7 {
 #define MPI2_MANUFACTURING7_PAGEVERSION                 (0x01)
 
 /*defines for the Flags field */
+#define MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER       (0x00000002)
 #define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO                (0x00000001)
 
 
@@ -1310,6 +1316,9 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_1
 #define MPI2_BIOSPAGE1_PAGEVERSION                      (0x05)
 
 /*values for BIOS Page 1 BiosOptions field */
+#define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID                  (0x000000F0)
+#define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID                   (0x00000000)
+
 #define MPI2_BIOSPAGE1_OPTIONS_MASK_UEFI_HII_REGISTRATION   (0x00000006)
 #define MPI2_BIOSPAGE1_OPTIONS_ENABLE_UEFI_HII              (0x00000000)
 #define MPI2_BIOSPAGE1_OPTIONS_DISABLE_UEFI_HII             (0x00000002)
@@ -1884,6 +1893,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDIS
 #define MPI2_SAS_PRATE_MAX_RATE_1_5                     (0x80)
 #define MPI2_SAS_PRATE_MAX_RATE_3_0                     (0x90)
 #define MPI2_SAS_PRATE_MAX_RATE_6_0                     (0xA0)
+#define MPI25_SAS_PRATE_MAX_RATE_12_0                   (0xB0)
 #define MPI2_SAS_PRATE_MIN_RATE_MASK                    (0x0F)
 #define MPI2_SAS_PRATE_MIN_RATE_NOT_PROGRAMMABLE        (0x00)
 #define MPI2_SAS_PRATE_MIN_RATE_1_5                     (0x08)
@@ -1897,6 +1907,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDIS
 #define MPI2_SAS_HWRATE_MAX_RATE_1_5                    (0x80)
 #define MPI2_SAS_HWRATE_MAX_RATE_3_0                    (0x90)
 #define MPI2_SAS_HWRATE_MAX_RATE_6_0                    (0xA0)
+#define MPI25_SAS_HWRATE_MAX_RATE_12_0                  (0xB0)
 #define MPI2_SAS_HWRATE_MIN_RATE_MASK                   (0x0F)
 #define MPI2_SAS_HWRATE_MIN_RATE_1_5                    (0x08)
 #define MPI2_SAS_HWRATE_MIN_RATE_3_0                    (0x09)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2012 LSI Corporation.
+ * Copyright (c) 2000-2013 LSI Corporation.
  *
  *
  *          Name:  mpi2.h
@@ -8,7 +8,7 @@
  *                 scatter/gather formats.
  * Creation Date:  June 21, 2006
  *
- * mpi2.h Version:  02.00.26
+ * mpi2.h Version:  02.00.29
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -82,6 +82,10 @@
  * 03-29-12  02.00.25  Bumped MPI2_HEADER_VERSION_UNIT.
  *                     Added Hard Reset delay timings.
  * 07-10-12  02.00.26  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 07-26-12  02.00.27  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 11-27-12  02.00.28  Bumped MPI2_HEADER_VERSION_UNIT.
+ * 12-20-12  02.00.29  Bumped MPI2_HEADER_VERSION_UNIT.
+ *                     Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET.
  * --------------------------------------------------------------------------
  */
 
@@ -115,7 +119,7 @@
 #define MPI2_VERSION_02_05                  (0x0205)
 
 /*Unit and Dev versioning for this MPI header set */
-#define MPI2_HEADER_VERSION_UNIT            (0x1A)
+#define MPI2_HEADER_VERSION_UNIT            (0x1D)
 #define MPI2_HEADER_VERSION_DEV             (0x00)
 #define MPI2_HEADER_VERSION_UNIT_MASK       (0xFF00)
 #define MPI2_HEADER_VERSION_UNIT_SHIFT      (8)
@@ -274,6 +278,8 @@ typedef volatile struct _MPI2_SYSTEM_INT
 #define MPI2_REPLY_POST_HOST_INDEX_MASK         (0x00FFFFFF)
 #define MPI2_RPHI_MSIX_INDEX_MASK               (0xFF000000)
 #define MPI2_RPHI_MSIX_INDEX_SHIFT              (24)
+#define MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET  (0x0000030C) /*MPI v2.5 only*/
+
 
 /*
  *Defines for the HCBSize and address
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_init.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_init.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_init.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2012 LSI Corporation.
+ * Copyright (c) 2000-2013 LSI Corporation.
  *
  *
  *          Name:  mpi2_init.h
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2012 LSI Corporation.
+ * Copyright (c) 2000-2013 LSI Corporation.
  *
  *
  *          Name:  mpi2_ioc.h
  *         Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  * Creation Date:  October 11, 2006
  *
- * mpi2_ioc.h Version:  02.00.21
+ * mpi2_ioc.h Version:  02.00.22
  *
  * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
  *       prefix are for use only on MPI v2.5 products, and must not be used
@@ -124,6 +124,9 @@
  *                     Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete.
  * 11-18-11  02.00.20  Incorporating additions for MPI v2.5.
  * 03-29-12  02.00.21  Added a product specific range to event values.
+ * 07-26-12  02.00.22  Added MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE.
+ *                     Added ElapsedSeconds field to
+ *                     MPI2_EVENT_DATA_IR_OPERATION_STATUS.
  * --------------------------------------------------------------------------
  */
 
@@ -283,6 +286,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY {
 #define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT              (0)
 
 /*IOCExceptions */
+#define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE     (0x0200)
 #define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX      (0x0100)
 
 #define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_MASK              (0x00E0)
@@ -634,7 +638,7 @@ typedef struct _MPI2_EVENT_DATA_IR_OPERA
 	U8 RAIDOperation;	/*0x04 */
 	U8 PercentComplete;	/*0x05 */
 	U16 Reserved2;		/*0x06 */
-	U32 Resereved3;		/*0x08 */
+	U32 ElapsedSeconds;	/*0x08 */
 } MPI2_EVENT_DATA_IR_OPERATION_STATUS,
 	*PTR_MPI2_EVENT_DATA_IR_OPERATION_STATUS,
 	Mpi2EventDataIrOperationStatus_t,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_raid.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_raid.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_raid.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_raid.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2012 LSI Corporation.
+ * Copyright (c) 2000-2013 LSI Corporation.
  *
  *
  *          Name:  mpi2_raid.h
  *         Title:  MPI Integrated RAID messages and structures
  * Creation Date:  April 26, 2007
  *
- *   mpi2_raid.h Version:  02.00.08
+ *   mpi2_raid.h Version:  02.00.09
  *
  * Version History
  * ---------------
@@ -28,6 +28,8 @@
  *                     Added product-specific range to RAID Action values.
  * 11-18-11  02.00.07  Incorporating additions for MPI v2.5.
  * 02-06-12  02.00.08  Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN.
+ * 07-26-12  02.00.09  Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR.
+ *                     Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define.
  * --------------------------------------------------------------------------
  */
 
@@ -269,10 +271,12 @@ typedef struct _MPI2_RAID_VOL_INDICATOR
 	U64 TotalBlocks;	/*0x00 */
 	U64 BlocksRemaining;	/*0x08 */
 	U32 Flags;		/*0x10 */
+	U32 ElapsedSeconds;	/* 0x14 */
 } MPI2_RAID_VOL_INDICATOR, *PTR_MPI2_RAID_VOL_INDICATOR,
 	Mpi2RaidVolIndicator_t, *pMpi2RaidVolIndicator_t;
 
 /*defines for RAID Volume Indicator Flags field */
+#define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID   (0x80000000)
 #define MPI2_RAID_VOL_FLAGS_OP_MASK                 (0x0000000F)
 #define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT      (0x00000000)
 #define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001)
@@ -312,7 +316,7 @@ typedef struct _MPI2_RAID_COMPATIBILITY_
 
 /*RAID Action Reply ActionData union */
 typedef union _MPI2_RAID_ACTION_REPLY_DATA {
-	U32 Word[5];
+	U32 Word[6];
 	MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator;
 	U16 VolDevHandle;
 	U8 VolumeState;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_sas.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_sas.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_sas.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_sas.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2012 LSI Corporation.
+ * Copyright (c) 2000-2013 LSI Corporation.
  *
  *
  *          Name:  mpi2_sas.h
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_tool.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_tool.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_tool.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_tool.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2000-2012 LSI Corporation.
+ * Copyright (c) 2000-2013 LSI Corporation.
  *
  *
  *          Name:  mpi2_tool.h
  *         Title:  MPI diagnostic tool structures and definitions
  * Creation Date:  March 26, 2007
  *
- *   mpi2_tool.h Version:  02.00.09
+ *   mpi2_tool.h Version:  02.00.10
  *
  * Version History
  * ---------------
@@ -30,6 +30,8 @@
  * 11-18-11  02.00.08  Incorporating additions for MPI v2.5.
  * 07-10-12  02.00.09  Add MPI v2.5 Toolbox Diagnostic CLI Tool Request
  *                     message.
+ * 07-26-12  02.00.10  Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that
+ *                     it uses MPI Chain SGE as well as MPI Simple SGE.
  * --------------------------------------------------------------------------
  */
 
@@ -279,7 +281,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_
 	U16 Reserved6;		/*0x0E */
 	U32 DataLength;		/*0x10 */
 	U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */
-	MPI2_SGE_SIMPLE_UNION SGL;	/*0x70 */
+	MPI2_MPI_SGE_IO_UNION SGL;	/*0x70 */
 } MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
 	*PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
 	Mpi2ToolboxDiagnosticCliRequest_t,
@@ -302,7 +304,7 @@ typedef struct _MPI25_TOOLBOX_DIAGNOSTIC
 	U32 Reserved5;		/*0x0C */
 	U32 DataLength;		/*0x10 */
 	U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */
-	MPI25_SGE_IO_UNION SGL;	/*0x70 */
+	MPI25_SGE_IO_UNION      SGL;                        /* 0x70 */
 } MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
 	*PTR_MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
 	Mpi25ToolboxDiagnosticCliRequest_t,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_type.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_type.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpi/mpi2_type.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpi/mpi2_type.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000-2007 LSI Corporation.
+ *  Copyright (c) 2000-2013 LSI Corporation.
  *
  *
  *           Name:  mpi2_type.h
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_base.c linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_base.c
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_base.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_base.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  * for access to MPT (Message Passing Technology) firmware.
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -4090,11 +4090,15 @@ _base_diag_reset(struct MPT3SAS_ADAPTER
 	writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER,
 	     &ioc->chip->HostDiagnostic);
 
-	/* don't access any registers for 50 milliseconds */
-	msleep(50);
+	/*This delay allows the chip PCIe hardware time to finish reset tasks*/
+	if (sleep_flag == CAN_SLEEP)
+		msleep(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000);
+	else
+		mdelay(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000);
 
-	/* 300 second max wait */
-	for (count = 0; count < 3000000 ; count++) {
+	/* Approximately 300 second max wait */
+	for (count = 0; count < (300000000 /
+		MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) {
 
 		host_diagnostic = readl(&ioc->chip->HostDiagnostic);
 
@@ -4103,11 +4107,13 @@ _base_diag_reset(struct MPT3SAS_ADAPTER
 		if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER))
 			break;
 
-		/* wait 1 msec */
+		/* Wait to pass the second read delay window */
 		if (sleep_flag == CAN_SLEEP)
-			usleep_range(1000, 1500);
+			msleep(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC
+								/ 1000);
 		else
-			mdelay(1);
+			mdelay(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC
+								/ 1000);
 	}
 
 	if (host_diagnostic & MPI2_DIAG_HCB_MODE) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_base.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_base.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_base.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_base.h	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  * for access to MPT (Message Passing Technology) firmware.
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -70,10 +70,10 @@
 #define MPT3SAS_DRIVER_NAME		"mpt3sas"
 #define MPT3SAS_AUTHOR	"LSI Corporation <DL-MPTFusionLinux@lsi.com>"
 #define MPT3SAS_DESCRIPTION	"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION		"01.100.01.00"
-#define MPT3SAS_MAJOR_VERSION		1
+#define MPT3SAS_DRIVER_VERSION		"02.100.00.00"
+#define MPT3SAS_MAJOR_VERSION		2
 #define MPT3SAS_MINOR_VERSION		100
-#define MPT3SAS_BUILD_VERSION		1
+#define MPT3SAS_BUILD_VERSION		0
 #define MPT3SAS_RELEASE_VERSION	00
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_config.c linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_config.c
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_config.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_config.c	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,7 @@
  * This module provides common API for accessing firmware configuration pages
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_ctl.c linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_ctl.c
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_ctl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_ctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  * controllers
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.c
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_ctl.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_ctl.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_ctl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_ctl.h	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  * controllers
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.h
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_debug.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_debug.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_debug.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_debug.h	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,7 @@
  * Logging Support for MPT (Message Passing Technology) based controllers
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_debug.c
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,7 @@
  * Scsi Host Layer for MPT (Message Passing Technology) based controllers
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_scsih.c
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -675,11 +675,12 @@ _scsih_sas_device_add(struct MPT3SAS_ADA
 		 * devices while scanning is turned on due to an oops in
 		 * scsi_sysfs_add_sdev()->add_device()->sysfs_addrm_start()
 		 */
-		if (!ioc->is_driver_loading)
+		if (!ioc->is_driver_loading) {
 			mpt3sas_transport_port_remove(ioc,
 			    sas_device->sas_address,
 			    sas_device->sas_address_parent);
-		_scsih_sas_device_remove(ioc, sas_device);
+			_scsih_sas_device_remove(ioc, sas_device);
+		}
 	}
 }
 
@@ -1273,6 +1274,7 @@ _scsih_slave_alloc(struct scsi_device *s
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
 	struct scsi_target *starget;
 	struct _raid_device *raid_device;
+	struct _sas_device *sas_device;
 	unsigned long flags;
 
 	sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
@@ -1301,6 +1303,19 @@ _scsih_slave_alloc(struct scsi_device *s
 		spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
 	}
 
+	if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
+		spin_lock_irqsave(&ioc->sas_device_lock, flags);
+		sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc,
+					sas_target_priv_data->sas_address);
+		if (sas_device && (sas_device->starget == NULL)) {
+			sdev_printk(KERN_INFO, sdev,
+			"%s : sas_device->starget set to starget @ %d\n",
+				__func__, __LINE__);
+			sas_device->starget = starget;
+		}
+		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+	}
+
 	return 0;
 }
 
@@ -6392,7 +6407,7 @@ _scsih_search_responding_sas_devices(str
 	    handle))) {
 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
 			break;
 		handle = le16_to_cpu(sas_device_pg0.DevHandle);
 		device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
@@ -6494,7 +6509,7 @@ _scsih_search_responding_raid_devices(st
 	    &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
 			break;
 		handle = le16_to_cpu(volume_pg1.DevHandle);
 
@@ -6518,7 +6533,7 @@ _scsih_search_responding_raid_devices(st
 		    phys_disk_num))) {
 			ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 			    MPI2_IOCSTATUS_MASK;
-			if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+			if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
 				break;
 			phys_disk_num = pd_pg0.PhysDiskNum;
 			handle = le16_to_cpu(pd_pg0.DevHandle);
@@ -6597,7 +6612,7 @@ _scsih_search_responding_expanders(struc
 
 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
 			break;
 
 		handle = le16_to_cpu(expander_pg0.DevHandle);
@@ -6742,8 +6757,6 @@ _scsih_scan_for_devices_after_reset(stru
 	    MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
-			break;
 		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 			pr_info(MPT3SAS_FMT "\tbreak from expander scan: " \
 			    "ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -6787,8 +6800,6 @@ _scsih_scan_for_devices_after_reset(stru
 	    phys_disk_num))) {
 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
-			break;
 		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 			pr_info(MPT3SAS_FMT "\tbreak from phys disk scan: "\
 			    "ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -6854,8 +6865,6 @@ _scsih_scan_for_devices_after_reset(stru
 	    &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
-			break;
 		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 			pr_info(MPT3SAS_FMT "\tbreak from volume scan: " \
 			    "ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -6914,8 +6923,6 @@ _scsih_scan_for_devices_after_reset(stru
 	    handle))) {
 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
-			break;
 		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
 			pr_info(MPT3SAS_FMT "\tbreak from end device scan:"\
 			    " ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -7525,10 +7532,12 @@ _scsih_probe_boot_devices(struct MPT3SAS
 		    sas_address_parent)) {
 			_scsih_sas_device_remove(ioc, sas_device);
 		} else if (!sas_device->starget) {
-			if (!ioc->is_driver_loading)
-				mpt3sas_transport_port_remove(ioc, sas_address,
+			if (!ioc->is_driver_loading) {
+				mpt3sas_transport_port_remove(ioc,
+				    sas_address,
 				    sas_address_parent);
-			_scsih_sas_device_remove(ioc, sas_device);
+				_scsih_sas_device_remove(ioc, sas_device);
+			}
 		}
 	}
 }
@@ -7584,13 +7593,14 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER
 			 * oops in scsi_sysfs_add_sdev()->add_device()->
 			 * sysfs_addrm_start()
 			 */
-			if (!ioc->is_driver_loading)
+			if (!ioc->is_driver_loading) {
 				mpt3sas_transport_port_remove(ioc,
 				    sas_device->sas_address,
 				    sas_device->sas_address_parent);
-			list_del(&sas_device->list);
-			kfree(sas_device);
-			continue;
+				list_del(&sas_device->list);
+				kfree(sas_device);
+				continue;
+			}
 		}
 
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_transport.c linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_transport.c
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_transport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_transport.c	2013-08-25 20:43:22.000000000 -0400
@@ -2,7 +2,7 @@
  * SAS Transport Layer for MPT (Message Passing Technology) based controllers
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_transport.c
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,7 +3,7 @@
  * (Message Passing Technology) based controllers
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h
--- linux-libre-3.10-gnu/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,7 @@
  * controllers
  *
  * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h
- * Copyright (C) 2012  LSI Corporation
+ * Copyright (C) 2012-2013  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mvsas/mv_sas.c linux-libre-3.11-rc7-gnu/drivers/scsi/mvsas/mv_sas.c
--- linux-libre-3.10-gnu/drivers/scsi/mvsas/mv_sas.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mvsas/mv_sas.c	2013-08-25 20:43:22.000000000 -0400
@@ -686,7 +686,8 @@ static int mvs_task_prep_ssp(struct mvs_
 	if (ssp_hdr->frame_type != SSP_TASK) {
 		buf_cmd[9] = fburst | task->ssp_task.task_attr |
 				(task->ssp_task.task_prio << 3);
-		memcpy(buf_cmd + 12, &task->ssp_task.cdb, 16);
+		memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd,
+		       task->ssp_task.cmd->cmd_len);
 	} else{
 		buf_cmd[10] = tmf->tmf;
 		switch (tmf->tmf) {
@@ -1856,11 +1857,16 @@ int mvs_slot_complete(struct mvs_info *m
 		goto out;
 	}
 
-	/* error info record present */
-	if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) {
+	/*
+	 * error info record present; slot->response is 32 bit aligned but may
+	 * not be 64 bit aligned, so check for zero in two 32 bit reads
+	 */
+	if (unlikely((rx_desc & RXQ_ERR)
+		     && (*((u32 *)slot->response)
+			 || *(((u32 *)slot->response) + 1)))) {
 		mv_dprintk("port %d slot %d rx_desc %X has error info"
 			"%016llX.\n", slot->port->sas_port.id, slot_idx,
-			 rx_desc, (u64)(*(u64 *)slot->response));
+			 rx_desc, get_unaligned_le64(slot->response));
 		tstat->stat = mvs_slot_err(mvi, task, slot_idx);
 		tstat->resp = SAS_TASK_COMPLETE;
 		goto out;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/mvsas/mv_sas.h linux-libre-3.11-rc7-gnu/drivers/scsi/mvsas/mv_sas.h
--- linux-libre-3.10-gnu/drivers/scsi/mvsas/mv_sas.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/mvsas/mv_sas.h	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/irq.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <asm/unaligned.h>
 #include <scsi/libsas.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_tcq.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/nsp32.c linux-libre-3.11-rc7-gnu/drivers/scsi/nsp32.c
--- linux-libre-3.10-gnu/drivers/scsi/nsp32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/nsp32.c	2013-08-25 20:43:22.000000000 -0400
@@ -2899,7 +2899,7 @@ static void nsp32_do_bus_reset(nsp32_hw_
 	 * reset SCSI bus
 	 */
 	nsp32_write1(base, SCSI_BUS_CONTROL, BUSCTL_RST);
-	udelay(RESET_HOLD_TIME);
+	mdelay(RESET_HOLD_TIME / 1000);
 	nsp32_write1(base, SCSI_BUS_CONTROL, 0);
 	for(i = 0; i < 5; i++) {
 		intrdat = nsp32_read2(base, IRQ_STATUS); /* dummy read */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/osd/osd_uld.c linux-libre-3.11-rc7-gnu/drivers/scsi/osd/osd_uld.c
--- linux-libre-3.10-gnu/drivers/scsi/osd/osd_uld.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/osd/osd_uld.c	2013-08-25 20:43:22.000000000 -0400
@@ -485,7 +485,7 @@ static int osd_probe(struct device *dev)
 	oud->class_dev.class = &osd_uld_class;
 	oud->class_dev.parent = dev;
 	oud->class_dev.release = __remove;
-	error = dev_set_name(&oud->class_dev, disk->disk_name);
+	error = dev_set_name(&oud->class_dev, "%s", disk->disk_name);
 	if (error) {
 		OSD_ERR("dev_set_name failed => %d\n", error);
 		goto err_put_cdev;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/pm8001/pm8001_hwi.c linux-libre-3.11-rc7-gnu/drivers/scsi/pm8001/pm8001_hwi.c
--- linux-libre-3.10-gnu/drivers/scsi/pm8001/pm8001_hwi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/pm8001/pm8001_hwi.c	2013-08-25 20:43:22.000000000 -0400
@@ -3740,7 +3740,7 @@ int pm8001_mpi_task_abort_resp(struct pm
 	pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
 	mb();
 
-	if ((pm8001_dev->id & NCQ_ABORT_ALL_FLAG) && t)	{
+	if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) {
 		pm8001_tag_free(pm8001_ha, tag);
 		sas_free_task(t);
 		/* clear the flag */
@@ -4291,7 +4291,8 @@ static int pm8001_chip_ssp_io_req(struct
 		ssp_cmd.ssp_iu.efb_prio_attr |= 0x80;
 	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3);
 	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
-	memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16);
+	memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
+	       task->ssp_task.cmd->cmd_len);
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	/* fill in PRD (scatter/gather) table, if any */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/pm8001/pm8001_init.c linux-libre-3.11-rc7-gnu/drivers/scsi/pm8001/pm8001_init.c
--- linux-libre-3.10-gnu/drivers/scsi/pm8001/pm8001_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/pm8001/pm8001_init.c	2013-08-25 20:43:22.000000000 -0400
@@ -912,14 +912,13 @@ static int pm8001_pci_suspend(struct pci
 {
 	struct sas_ha_struct *sha = pci_get_drvdata(pdev);
 	struct pm8001_hba_info *pm8001_ha;
-	int i , pos;
+	int i;
 	u32 device_state;
 	pm8001_ha = sha->lldd_ha;
 	flush_workqueue(pm8001_wq);
 	scsi_block_requests(pm8001_ha->shost);
-	pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
-	if (pos == 0) {
-		printk(KERN_ERR " PCI PM not supported\n");
+	if (!pdev->pm_cap) {
+		dev_err(&pdev->dev, " PCI PM not supported\n");
 		return -ENODEV;
 	}
 	PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/pm8001/pm80xx_hwi.c linux-libre-3.11-rc7-gnu/drivers/scsi/pm8001/pm80xx_hwi.c
--- linux-libre-3.10-gnu/drivers/scsi/pm8001/pm80xx_hwi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/pm8001/pm80xx_hwi.c	2013-08-25 20:43:22.000000000 -0400
@@ -3204,7 +3204,7 @@ static void process_one_iomb(struct pm80
 		break;
 	case OPC_OUB_DEREG_DEV:
 		PM8001_MSG_DBG(pm8001_ha,
-			pm8001_printk("unresgister the deviece\n"));
+			pm8001_printk("unregister the device\n"));
 		pm8001_mpi_dereg_resp(pm8001_ha, piomb);
 		break;
 	case OPC_OUB_GET_DEV_HANDLE:
@@ -3559,9 +3559,9 @@ err_out:
 
 static int check_enc_sas_cmd(struct sas_task *task)
 {
-	if ((task->ssp_task.cdb[0] == READ_10)
-		|| (task->ssp_task.cdb[0] == WRITE_10)
-		|| (task->ssp_task.cdb[0] == WRITE_VERIFY))
+	u8 cmd = task->ssp_task.cmd->cmnd[0];
+
+	if (cmd == READ_10 || cmd == WRITE_10 || cmd == WRITE_VERIFY)
 		return 1;
 	else
 		return 0;
@@ -3624,7 +3624,8 @@ static int pm80xx_chip_ssp_io_req(struct
 		ssp_cmd.ssp_iu.efb_prio_attr |= 0x80;
 	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3);
 	ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
-	memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16);
+	memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
+		       task->ssp_task.cmd->cmd_len);
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
 
 	/* Check if encryption is set */
@@ -3632,7 +3633,7 @@ static int pm80xx_chip_ssp_io_req(struct
 		!(pm8001_ha->encrypt_info.status) && check_enc_sas_cmd(task)) {
 		PM8001_IO_DBG(pm8001_ha, pm8001_printk(
 			"Encryption enabled.Sending Encrypt SAS command 0x%x\n",
-			task->ssp_task.cdb[0]));
+			task->ssp_task.cmd->cmnd[0]));
 		opc = OPC_INB_SSP_INI_DIF_ENC_IO;
 		/* enable encryption. 0 for SAS 1.1 and SAS 2.0 compatible TLR*/
 		ssp_cmd.dad_dir_m_tlr =	cpu_to_le32
@@ -3666,14 +3667,14 @@ static int pm80xx_chip_ssp_io_req(struct
 		/* XTS mode. All other fields are 0 */
 		ssp_cmd.key_cmode = 0x6 << 4;
 		/* set tweak values. Should be the start lba */
-		ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cdb[2] << 24) |
-						(task->ssp_task.cdb[3] << 16) |
-						(task->ssp_task.cdb[4] << 8) |
-						(task->ssp_task.cdb[5]));
+		ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cmd->cmnd[2] << 24) |
+						(task->ssp_task.cmd->cmnd[3] << 16) |
+						(task->ssp_task.cmd->cmnd[4] << 8) |
+						(task->ssp_task.cmd->cmnd[5]));
 	} else {
 		PM8001_IO_DBG(pm8001_ha, pm8001_printk(
 			"Sending Normal SAS command 0x%x inb q %x\n",
-			task->ssp_task.cdb[0], inb));
+			task->ssp_task.cmd->cmnd[0], inb));
 		/* fill in PRD (scatter/gather) table, if any */
 		if (task->num_scatter > 1) {
 			pm8001_chip_make_sg(task->scatter, ccb->n_elem,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/pmcraid.c linux-libre-3.11-rc7-gnu/drivers/scsi/pmcraid.c
--- linux-libre-3.10-gnu/drivers/scsi/pmcraid.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/pmcraid.c	2013-08-25 20:43:22.000000000 -0400
@@ -6092,7 +6092,7 @@ static int __init pmcraid_init(void)
 
 	if (IS_ERR(pmcraid_class)) {
 		error = PTR_ERR(pmcraid_class);
-		pmcraid_err("failed to register with with sysfs, error = %x\n",
+		pmcraid_err("failed to register with sysfs, error = %x\n",
 			    error);
 		goto out_unreg_chrdev;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_attr.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_attr.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_attr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_attr.c	2013-08-25 20:43:22.000000000 -0400
@@ -1691,6 +1691,9 @@ qla2x00_get_fc_host_stats(struct Scsi_Ho
 	if (unlikely(pci_channel_offline(ha->pdev)))
 		goto done;
 
+	if (qla2x00_reset_active(vha))
+		goto done;
+
 	stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma);
 	if (stats == NULL) {
 		ql_log(ql_log_warn, vha, 0x707d,
@@ -1703,7 +1706,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Ho
 	if (IS_FWI2_CAPABLE(ha)) {
 		rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma);
 	} else if (atomic_read(&base_vha->loop_state) == LOOP_READY &&
-	    !qla2x00_reset_active(vha) && !ha->dpc_active) {
+	    !ha->dpc_active) {
 		/* Must be in a 'READY' state for statistics retrieval. */
 		rval = qla2x00_get_link_status(base_vha, base_vha->loop_id,
 						stats, stats_dma);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_bsg.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_bsg.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_bsg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_bsg.c	2013-08-25 20:43:22.000000000 -0400
@@ -269,6 +269,12 @@ qla2x00_process_els(struct fc_bsg_job *b
 		type = "FC_BSG_HST_ELS_NOLOGIN";
 	}
 
+	if (!vha->flags.online) {
+		ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
+		rval = -EIO;
+		goto done;
+	}
+
 	/* pass through is supported only for ISP 4Gb or higher */
 	if (!IS_FWI2_CAPABLE(ha)) {
 		ql_dbg(ql_dbg_user, vha, 0x7001,
@@ -326,12 +332,6 @@ qla2x00_process_els(struct fc_bsg_job *b
 			NPH_FABRIC_CONTROLLER : NPH_F_PORT;
 	}
 
-	if (!vha->flags.online) {
-		ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
-		rval = -EIO;
-		goto done;
-	}
-
 	req_sg_cnt =
 		dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
@@ -399,7 +399,7 @@ done_unmap_sg:
 	goto done_free_fcport;
 
 done_free_fcport:
-	if (bsg_job->request->msgcode == FC_BSG_HST_ELS_NOLOGIN)
+	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS)
 		kfree(fcport);
 done:
 	return rval;
@@ -1084,14 +1084,6 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_
 		return -EINVAL;
 	}
 
-	ql84_mgmt = (struct qla_bsg_a84_mgmt *)((char *)bsg_job->request +
-		sizeof(struct fc_bsg_request));
-	if (!ql84_mgmt) {
-		ql_log(ql_log_warn, vha, 0x703b,
-		    "MGMT header not provided, exiting.\n");
-		return -EINVAL;
-	}
-
 	mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
 	if (!mn) {
 		ql_log(ql_log_warn, vha, 0x703c,
@@ -1102,7 +1094,7 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_
 	memset(mn, 0, sizeof(struct access_chip_84xx));
 	mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
 	mn->entry_count = 1;
-
+	ql84_mgmt = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
 	switch (ql84_mgmt->mgmt.cmd) {
 	case QLA84_MGMT_READ_MEM:
 	case QLA84_MGMT_GET_INFO:
@@ -1282,14 +1274,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job
 		return -EINVAL;
 	}
 
-	port_param = (struct qla_port_param *)((char *)bsg_job->request +
-		sizeof(struct fc_bsg_request));
-	if (!port_param) {
-		ql_log(ql_log_warn, vha, 0x7047,
-		    "port_param header not provided.\n");
-		return -EINVAL;
-	}
-
+	port_param = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
 	if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) {
 		ql_log(ql_log_warn, vha, 0x7048,
 		    "Invalid destination type.\n");
@@ -2153,6 +2138,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *b
 					(sp->type == SRB_ELS_CMD_HST) ||
 					(sp->type == SRB_FXIOCB_BCMD))
 					&& (sp->u.bsg_job == bsg_job)) {
+					req->outstanding_cmds[cnt] = NULL;
 					spin_unlock_irqrestore(&ha->hardware_lock, flags);
 					if (ha->isp_ops->abort_command(sp)) {
 						ql_log(ql_log_warn, vha, 0x7089,
@@ -2180,8 +2166,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *b
 
 done:
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
-	if (bsg_job->request->msgcode == FC_BSG_HST_CT)
-		kfree(sp->fcport);
-	qla2x00_rel_sp(vha, sp);
+	sp->free(vha, sp);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_dbg.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_dbg.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_dbg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_dbg.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,9 +12,10 @@
  * |             Level            |   Last Value Used  |     Holes	|
  * ----------------------------------------------------------------------
  * | Module Init and Probe        |       0x014f       | 0x4b,0xba,0xfa |
- * | Mailbox commands             |       0x1179       | 0x111a-0x111b  |
+ * | Mailbox commands             |       0x117a       | 0x111a-0x111b  |
  * |                              |                    | 0x1155-0x1158  |
  * | Device Discovery             |       0x2095       | 0x2020-0x2022, |
+ * |                              |                    | 0x2011-0x2012, |
  * |                              |                    | 0x2016         |
  * | Queue Command and IO tracing |       0x3058       | 0x3006-0x300b  |
  * |                              |                    | 0x3027-0x3028  |
@@ -35,7 +36,8 @@
  * |                              |                    | 0x70a5,0x70a6, |
  * |                              |                    | 0x70a8,0x70ab, |
  * |                              |                    | 0x70ad-0x70ae, |
- * |                              |                    | 0x70d1-0x70da  |
+ * |                              |                    | 0x70d1-0x70da, |
+ * |                              |                    | 0x7047,0x703b	|
  * | Task Management              |       0x803c       | 0x8025-0x8026  |
  * |                              |                    | 0x800b,0x8039  |
  * | AER/EEH                      |       0x9011       |		|
@@ -1468,7 +1470,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, in
 
 	nxt = qla2xxx_copy_queues(ha, nxt);
 
-	nxt = qla24xx_copy_eft(ha, nxt);
+	qla24xx_copy_eft(ha, nxt);
 
 	/* Chain entries -- started with MQ. */
 	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
@@ -1787,7 +1789,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, in
 
 	nxt = qla2xxx_copy_queues(ha, nxt);
 
-	nxt = qla24xx_copy_eft(ha, nxt);
+	qla24xx_copy_eft(ha, nxt);
 
 	/* Chain entries -- started with MQ. */
 	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
@@ -2289,7 +2291,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, in
 copy_queue:
 	nxt = qla2xxx_copy_queues(ha, nxt);
 
-	nxt = qla24xx_copy_eft(ha, nxt);
+	qla24xx_copy_eft(ha, nxt);
 
 	/* Chain entries -- started with MQ. */
 	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_def.h linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_def.h
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_def.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_def.h	2013-08-25 20:43:22.000000000 -0400
@@ -323,7 +323,7 @@ struct srb_iocb {
 			uint32_t lun;
 			uint32_t data;
 			struct completion comp;
-			uint32_t comp_status;
+			__le16 comp_status;
 		} tmf;
 		struct {
 #define SRB_FXDISC_REQ_DMA_VALID	BIT_0
@@ -338,21 +338,21 @@ struct srb_iocb {
 			void *rsp_addr;
 			dma_addr_t req_dma_handle;
 			dma_addr_t rsp_dma_handle;
-			uint32_t adapter_id;
-			uint32_t adapter_id_hi;
-			uint32_t req_func_type;
-			uint32_t req_data;
-			uint32_t req_data_extra;
-			uint32_t result;
-			uint32_t seq_number;
-			uint32_t fw_flags;
+			__le32 adapter_id;
+			__le32 adapter_id_hi;
+			__le16 req_func_type;
+			__le32 req_data;
+			__le32 req_data_extra;
+			__le32 result;
+			__le32 seq_number;
+			__le16 fw_flags;
 			struct completion fxiocb_comp;
-			uint32_t reserved_0;
+			__le32 reserved_0;
 			uint8_t reserved_1;
 		} fxiocb;
 		struct {
 			uint32_t cmd_hndl;
-			uint32_t comp_status;
+			__le16 comp_status;
 			struct completion comp;
 		} abt;
 	} u;
@@ -1196,14 +1196,14 @@ typedef struct {
 struct init_cb_fx {
 	uint16_t	version;
 	uint16_t	reserved_1[13];
-	uint16_t	request_q_outpointer;
-	uint16_t	response_q_inpointer;
+	__le16		request_q_outpointer;
+	__le16		response_q_inpointer;
 	uint16_t	reserved_2[2];
-	uint16_t	response_q_length;
-	uint16_t	request_q_length;
+	__le16		response_q_length;
+	__le16		request_q_length;
 	uint16_t	reserved_3[2];
-	uint32_t	request_q_address[2];
-	uint32_t	response_q_address[2];
+	__le32		request_q_address[2];
+	__le32		response_q_address[2];
 	uint16_t	reserved_4[4];
 	uint8_t		response_q_msivec;
 	uint8_t		reserved_5[19];
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_gbl.h linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_gbl.h
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_gbl.h	2013-07-01 10:42:44.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_gbl.h	2013-08-31 18:02:32.000000000 -0400
@@ -587,7 +587,7 @@ extern int qlafx00_init_firmware(scsi_ql
 extern int qlafx00_fw_ready(scsi_qla_host_t *);
 extern int qlafx00_configure_devices(scsi_qla_host_t *);
 extern int qlafx00_reset_initialize(scsi_qla_host_t *);
-extern int qlafx00_fx_disc(scsi_qla_host_t *, fc_port_t *, uint8_t);
+extern int qlafx00_fx_disc(scsi_qla_host_t *, fc_port_t *, uint16_t);
 extern int qlafx00_process_aen(struct scsi_qla_host *, struct qla_work_evt *);
 extern int qlafx00_post_aenfx_work(struct scsi_qla_host *,  uint32_t,
 				   uint32_t *, int);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_gs.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_gs.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_gs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_gs.c	2013-08-25 20:43:22.000000000 -0400
@@ -99,17 +99,17 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *vh
  * Returns a pointer to the intitialized @ct_req.
  */
 static inline struct ct_sns_req *
-qla2x00_prep_ct_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size)
+qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size)
 {
-	memset(ct_req, 0, sizeof(struct ct_sns_pkt));
+	memset(p, 0, sizeof(struct ct_sns_pkt));
 
-	ct_req->header.revision = 0x01;
-	ct_req->header.gs_type = 0xFC;
-	ct_req->header.gs_subtype = 0x02;
-	ct_req->command = cpu_to_be16(cmd);
-	ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
+	p->p.req.header.revision = 0x01;
+	p->p.req.header.gs_type = 0xFC;
+	p->p.req.header.gs_subtype = 0x02;
+	p->p.req.command = cpu_to_be16(cmd);
+	p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
 
-	return (ct_req);
+	return &p->p.req;
 }
 
 static int
@@ -188,7 +188,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_
 	    GA_NXT_RSP_SIZE);
 
 	/* Prepare CT request */
-	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD,
+	ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD,
 	    GA_NXT_RSP_SIZE);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
@@ -284,8 +284,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_
 	    gid_pt_rsp_size);
 
 	/* Prepare CT request */
-	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD,
-	    gid_pt_rsp_size);
+	ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
 	/* Prepare CT arguments -- port_type */
@@ -359,7 +358,7 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_
 		    GPN_ID_RSP_SIZE);
 
 		/* Prepare CT request */
-		ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GPN_ID_CMD,
+		ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD,
 		    GPN_ID_RSP_SIZE);
 		ct_rsp = &ha->ct_sns->p.rsp;
 
@@ -421,7 +420,7 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_
 		    GNN_ID_RSP_SIZE);
 
 		/* Prepare CT request */
-		ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GNN_ID_CMD,
+		ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD,
 		    GNN_ID_RSP_SIZE);
 		ct_rsp = &ha->ct_sns->p.rsp;
 
@@ -495,7 +494,7 @@ qla2x00_rft_id(scsi_qla_host_t *vha)
 	    RFT_ID_RSP_SIZE);
 
 	/* Prepare CT request */
-	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD,
+	ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFT_ID_CMD,
 	    RFT_ID_RSP_SIZE);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
@@ -551,7 +550,7 @@ qla2x00_rff_id(scsi_qla_host_t *vha)
 	    RFF_ID_RSP_SIZE);
 
 	/* Prepare CT request */
-	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD,
+	ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFF_ID_CMD,
 	    RFF_ID_RSP_SIZE);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
@@ -606,8 +605,7 @@ qla2x00_rnn_id(scsi_qla_host_t *vha)
 	    RNN_ID_RSP_SIZE);
 
 	/* Prepare CT request */
-	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD,
-	    RNN_ID_RSP_SIZE);
+	ct_req = qla2x00_prep_ct_req(ha->ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
 	/* Prepare CT arguments -- port_id, node_name */
@@ -676,7 +674,7 @@ qla2x00_rsnn_nn(scsi_qla_host_t *vha)
 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, 0, RSNN_NN_RSP_SIZE);
 
 	/* Prepare CT request */
-	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD,
+	ct_req = qla2x00_prep_ct_req(ha->ct_sns, RSNN_NN_CMD,
 	    RSNN_NN_RSP_SIZE);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
@@ -1262,18 +1260,18 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_hos
  * Returns a pointer to the intitialized @ct_req.
  */
 static inline struct ct_sns_req *
-qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd,
+qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
     uint16_t rsp_size)
 {
-	memset(ct_req, 0, sizeof(struct ct_sns_pkt));
+	memset(p, 0, sizeof(struct ct_sns_pkt));
 
-	ct_req->header.revision = 0x01;
-	ct_req->header.gs_type = 0xFA;
-	ct_req->header.gs_subtype = 0x10;
-	ct_req->command = cpu_to_be16(cmd);
-	ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
+	p->p.req.header.revision = 0x01;
+	p->p.req.header.gs_type = 0xFA;
+	p->p.req.header.gs_subtype = 0x10;
+	p->p.req.command = cpu_to_be16(cmd);
+	p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
 
-	return ct_req;
+	return &p->p.req;
 }
 
 /**
@@ -1301,8 +1299,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
 	ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE);
 
 	/* Prepare CT request */
-	ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD,
-	    RHBA_RSP_SIZE);
+	ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
 	/* Prepare FDMI command arguments -- attribute block, attributes. */
@@ -1370,8 +1367,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha)
 	/* Model description. */
 	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
 	eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
-	if (ha->model_desc)
-		strncpy(eiter->a.model_desc, ha->model_desc, 80);
+	strncpy(eiter->a.model_desc, ha->model_desc, 80);
 	alen = strlen(eiter->a.model_desc);
 	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
 	eiter->len = cpu_to_be16(4 + alen);
@@ -1491,8 +1487,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
 	    DHBA_RSP_SIZE);
 
 	/* Prepare CT request */
-	ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD,
-	    DHBA_RSP_SIZE);
+	ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
 	/* Prepare FDMI command arguments -- portname. */
@@ -1548,8 +1543,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
 	ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE);
 
 	/* Prepare CT request */
-	ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD,
-	    RPA_RSP_SIZE);
+	ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
 	/* Prepare FDMI command arguments -- attribute block, attributes. */
@@ -1776,7 +1770,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *vha, sw
 		    GFPN_ID_RSP_SIZE);
 
 		/* Prepare CT request */
-		ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD,
+		ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD,
 		    GFPN_ID_RSP_SIZE);
 		ct_rsp = &ha->ct_sns->p.rsp;
 
@@ -1843,18 +1837,18 @@ qla24xx_prep_ms_fm_iocb(scsi_qla_host_t
 
 
 static inline struct ct_sns_req *
-qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd,
+qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
     uint16_t rsp_size)
 {
-	memset(ct_req, 0, sizeof(struct ct_sns_pkt));
+	memset(p, 0, sizeof(struct ct_sns_pkt));
 
-	ct_req->header.revision = 0x01;
-	ct_req->header.gs_type = 0xFA;
-	ct_req->header.gs_subtype = 0x01;
-	ct_req->command = cpu_to_be16(cmd);
-	ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
+	p->p.req.header.revision = 0x01;
+	p->p.req.header.gs_type = 0xFA;
+	p->p.req.header.gs_subtype = 0x01;
+	p->p.req.command = cpu_to_be16(cmd);
+	p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
 
-	return ct_req;
+	return &p->p.req;
 }
 
 /**
@@ -1890,8 +1884,8 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_in
 		    GPSC_RSP_SIZE);
 
 		/* Prepare CT request */
-		ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req,
-		    GPSC_CMD, GPSC_RSP_SIZE);
+		ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD,
+		    GPSC_RSP_SIZE);
 		ct_rsp = &ha->ct_sns->p.rsp;
 
 		/* Prepare CT arguments -- port_name */
@@ -2001,7 +1995,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_
 		    GFF_ID_RSP_SIZE);
 
 		/* Prepare CT request */
-		ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFF_ID_CMD,
+		ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD,
 		    GFF_ID_RSP_SIZE);
 		ct_rsp = &ha->ct_sns->p.rsp;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_init.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_init.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_init.c	2013-07-01 10:42:44.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_init.c	2013-08-31 18:02:32.000000000 -0400
@@ -2309,14 +2309,6 @@ qla2x00_configure_hba(scsi_qla_host_t *v
 		    "Topology - %s, Host Loop address 0x%x.\n",
 		    connect_type, vha->loop_id);
 
-	if (rval) {
-		ql_log(ql_log_warn, vha, 0x2011,
-		    "%s FAILED\n", __func__);
-	} else {
-		ql_dbg(ql_dbg_disc, vha, 0x2012,
-		    "%s success\n", __func__);
-	}
-
 	return(rval);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_inline.h linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_inline.h
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_inline.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_inline.h	2013-08-25 20:43:22.000000000 -0400
@@ -83,7 +83,7 @@ static inline void
 host_to_adap(uint8_t *src, uint8_t *dst, uint32_t bsize)
 {
 	uint32_t *isrc = (uint32_t *) src;
-	uint32_t *odest = (uint32_t *) dst;
+	__le32 *odest = (__le32 *) dst;
 	uint32_t iter = bsize >> 2;
 
 	for (; iter ; iter--)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_iocb.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_iocb.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_iocb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_iocb.c	2013-08-25 20:43:22.000000000 -0400
@@ -419,6 +419,8 @@ qla2x00_start_scsi(srb_t *sp)
 			    __constant_cpu_to_le16(CF_SIMPLE_TAG);
 			break;
 		}
+	} else {
+		cmd_pkt->control_flags = __constant_cpu_to_le16(CF_SIMPLE_TAG);
 	}
 
 	/* Load SCSI command packet. */
@@ -1189,7 +1191,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp
 	uint32_t		*cur_dsd, *fcp_dl;
 	scsi_qla_host_t		*vha;
 	struct scsi_cmnd	*cmd;
-	struct scatterlist	*cur_seg;
 	int			sgc;
 	uint32_t		total_bytes = 0;
 	uint32_t		data_bytes;
@@ -1308,11 +1309,11 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp
 		    fcp_cmnd->task_attribute = TSK_ORDERED;
 		    break;
 		default:
-		    fcp_cmnd->task_attribute = 0;
+		    fcp_cmnd->task_attribute = TSK_SIMPLE;
 		    break;
 		}
 	} else {
-		fcp_cmnd->task_attribute = 0;
+		fcp_cmnd->task_attribute = TSK_SIMPLE;
 	}
 
 	cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */
@@ -1396,7 +1397,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp
 
 	if (bundling && tot_prot_dsds) {
 		/* Walks dif segments */
-		cur_seg = scsi_prot_sglist(cmd);
 		cmd_pkt->control_flags |=
 			__constant_cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE);
 		cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address;
@@ -1527,7 +1527,12 @@ qla24xx_start_scsi(srb_t *sp)
 		case ORDERED_QUEUE_TAG:
 			cmd_pkt->task = TSK_ORDERED;
 			break;
+		default:
+		    cmd_pkt->task = TSK_SIMPLE;
+		    break;
 		}
+	} else {
+		cmd_pkt->task = TSK_SIMPLE;
 	}
 
 	/* Load SCSI command packet. */
@@ -1863,8 +1868,8 @@ skip_cmd_array:
 	pkt = req->ring_ptr;
 	memset(pkt, 0, REQUEST_ENTRY_SIZE);
 	if (IS_QLAFX00(ha)) {
-		WRT_REG_BYTE(&pkt->entry_count, req_cnt);
-		WRT_REG_WORD(&pkt->handle, handle);
+		WRT_REG_BYTE((void __iomem *)&pkt->entry_count, req_cnt);
+		WRT_REG_WORD((void __iomem *)&pkt->handle, handle);
 	} else {
 		pkt->entry_count = req_cnt;
 		pkt->handle = handle;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_isr.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_isr.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_isr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_isr.c	2013-08-25 20:43:22.000000000 -0400
@@ -2485,6 +2485,7 @@ qla2xxx_check_risc_status(scsi_qla_host_
 	if (rval == QLA_SUCCESS)
 		goto next_test;
 
+	rval = QLA_SUCCESS;
 	WRT_REG_DWORD(&reg->iobase_window, 0x0003);
 	for (cnt = 100; (RD_REG_DWORD(&reg->iobase_window) & BIT_0) == 0 &&
 	    rval == QLA_SUCCESS; cnt--) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_mbx.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_mbx.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_mbx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_mbx.c	2013-08-25 20:43:22.000000000 -0400
@@ -177,8 +177,14 @@ qla2x00_mailbox_command(scsi_qla_host_t
 			WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-		wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);
-
+		if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
+		    mcp->tov * HZ)) {
+			ql_dbg(ql_dbg_mbx, vha, 0x117a,
+			    "cmd=%x Timeout.\n", command);
+			spin_lock_irqsave(&ha->hardware_lock, flags);
+			clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
+			spin_unlock_irqrestore(&ha->hardware_lock, flags);
+		}
 	} else {
 		ql_dbg(ql_dbg_mbx, vha, 0x1011,
 		    "Cmd=%x Polling Mode.\n", command);
@@ -275,9 +281,11 @@ qla2x00_mailbox_command(scsi_qla_host_t
 
 		/*
 		 * Attempt to capture a firmware dump for further analysis
-		 * of the current firmware state
+		 * of the current firmware state.  We do not need to do this
+		 * if we are intentionally generating a dump.
 		 */
-		ha->isp_ops->fw_dump(vha, 0);
+		if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
+			ha->isp_ops->fw_dump(vha, 0);
 
 		rval = QLA_FUNCTION_TIMEOUT;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_mr.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_mr.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_mr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_mr.c	2013-08-25 20:43:22.000000000 -0400
@@ -707,7 +707,7 @@ qlafx00_tmf_iocb_timeout(void *data)
 	srb_t *sp = (srb_t *)data;
 	struct srb_iocb *tmf = &sp->u.iocb_cmd;
 
-	tmf->u.tmf.comp_status = CS_TIMEOUT;
+	tmf->u.tmf.comp_status = cpu_to_le16((uint16_t)CS_TIMEOUT);
 	complete(&tmf->u.tmf.comp);
 }
 
@@ -1418,7 +1418,8 @@ qlafx00_init_response_q_entries(struct r
 	pkt = rsp->ring_ptr;
 	for (cnt = 0; cnt < rsp->length; cnt++) {
 		pkt->signature = RESPONSE_PROCESSED;
-		WRT_REG_DWORD(&pkt->signature, RESPONSE_PROCESSED);
+		WRT_REG_DWORD((void __iomem *)&pkt->signature,
+		    RESPONSE_PROCESSED);
 		pkt++;
 	}
 }
@@ -1733,7 +1734,7 @@ qla2x00_fxdisc_sp_done(void *data, void
 }
 
 int
-qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t fx_type)
+qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
 {
 	srb_t *sp;
 	struct srb_iocb *fdisc;
@@ -1759,13 +1760,13 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc
 		fdisc->u.fxiocb.flags =
 		    SRB_FXDISC_RESP_DMA_VALID | SRB_FXDISC_REQ_DWRD_VALID;
 		fdisc->u.fxiocb.rsp_len = QLAFX00_PORT_DATA_INFO;
-		fdisc->u.fxiocb.req_data = fcport->port_id;
+		fdisc->u.fxiocb.req_data = cpu_to_le32(fcport->port_id);
 		break;
 	case FXDISC_GET_TGT_NODE_INFO:
 		fdisc->u.fxiocb.flags =
 		    SRB_FXDISC_RESP_DMA_VALID | SRB_FXDISC_REQ_DWRD_VALID;
 		fdisc->u.fxiocb.rsp_len = QLAFX00_TGT_NODE_INFO;
-		fdisc->u.fxiocb.req_data = fcport->tgt_id;
+		fdisc->u.fxiocb.req_data = cpu_to_le32(fcport->tgt_id);
 		break;
 	case FXDISC_GET_TGT_NODE_LIST:
 		fdisc->u.fxiocb.flags =
@@ -1851,7 +1852,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc
 	sp->name = "fxdisc";
 	qla2x00_init_timer(sp, FXDISC_TIMEOUT);
 	fdisc->timeout = qla2x00_fxdisc_iocb_timeout;
-	fdisc->u.fxiocb.req_func_type = fx_type;
+	fdisc->u.fxiocb.req_func_type = cpu_to_le16(fx_type);
 	sp->done = qla2x00_fxdisc_sp_done;
 
 	rval = qla2x00_start_sp(sp);
@@ -1904,7 +1905,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc
 		    (uint8_t *)pinfo, 16);
 		memcpy(vha->hw->gid_list, pinfo, QLAFX00_TGT_NODE_LIST_SIZE);
 	}
-	rval = fdisc->u.fxiocb.result;
+	rval = le32_to_cpu(fdisc->u.fxiocb.result);
 
 done_unmap_dma:
 	if (fdisc->u.fxiocb.rsp_addr)
@@ -1927,7 +1928,7 @@ qlafx00_abort_iocb_timeout(void *data)
 	srb_t *sp = (srb_t *)data;
 	struct srb_iocb *abt = &sp->u.iocb_cmd;
 
-	abt->u.abt.comp_status = CS_TIMEOUT;
+	abt->u.abt.comp_status = cpu_to_le16((uint16_t)CS_TIMEOUT);
 	complete(&abt->u.abt.comp);
 }
 
@@ -2169,14 +2170,14 @@ qlafx00_handle_sense(srb_t *sp, uint8_t
 static void
 qlafx00_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 		      struct tsk_mgmt_entry_fx00 *pkt, srb_t *sp,
-		      uint16_t sstatus, uint16_t cpstatus)
+		      __le16 sstatus, __le16 cpstatus)
 {
 	struct srb_iocb *tmf;
 
 	tmf = &sp->u.iocb_cmd;
-	if (cpstatus != CS_COMPLETE ||
-	    (sstatus & SS_RESPONSE_INFO_LEN_VALID))
-		cpstatus = CS_INCOMPLETE;
+	if (cpstatus != cpu_to_le16((uint16_t)CS_COMPLETE) ||
+	    (sstatus & cpu_to_le16((uint16_t)SS_RESPONSE_INFO_LEN_VALID)))
+		cpstatus = cpu_to_le16((uint16_t)CS_INCOMPLETE);
 	tmf->u.tmf.comp_status = cpstatus;
 	sp->done(vha, sp, 0);
 }
@@ -2194,7 +2195,7 @@ qlafx00_abort_iocb_entry(scsi_qla_host_t
 		return;
 
 	abt = &sp->u.iocb_cmd;
-	abt->u.abt.comp_status = le32_to_cpu(pkt->tgt_id_sts);
+	abt->u.abt.comp_status = pkt->tgt_id_sts;
 	sp->done(vha, sp, 0);
 }
 
@@ -2216,12 +2217,12 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t
 
 	if (sp->type == SRB_FXIOCB_DCMD) {
 		iocb_job = &sp->u.iocb_cmd;
-		iocb_job->u.fxiocb.seq_number = le32_to_cpu(pkt->seq_no);
-		iocb_job->u.fxiocb.fw_flags = le32_to_cpu(pkt->fw_iotcl_flags);
-		iocb_job->u.fxiocb.result = le32_to_cpu(pkt->status);
+		iocb_job->u.fxiocb.seq_number = pkt->seq_no;
+		iocb_job->u.fxiocb.fw_flags = pkt->fw_iotcl_flags;
+		iocb_job->u.fxiocb.result = pkt->status;
 		if (iocb_job->u.fxiocb.flags & SRB_FXDISC_RSP_DWRD_VALID)
 			iocb_job->u.fxiocb.req_data =
-			    le32_to_cpu(pkt->dataword_r);
+			    pkt->dataword_r;
 	} else {
 		bsg_job = sp->u.bsg_job;
 
@@ -2275,10 +2276,10 @@ qlafx00_status_entry(scsi_qla_host_t *vh
 	fc_port_t	*fcport;
 	struct scsi_cmnd *cp;
 	struct sts_entry_fx00 *sts;
-	uint16_t	comp_status;
-	uint16_t	scsi_status;
+	__le16		comp_status;
+	__le16		scsi_status;
 	uint16_t	ox_id;
-	uint8_t		lscsi_status;
+	__le16		lscsi_status;
 	int32_t		resid;
 	uint32_t	sense_len, par_sense_len, rsp_info_len, resid_len,
 	    fw_resid_len;
@@ -2292,8 +2293,8 @@ qlafx00_status_entry(scsi_qla_host_t *vh
 
 	sts = (struct sts_entry_fx00 *) pkt;
 
-	comp_status = le16_to_cpu(sts->comp_status);
-	scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
+	comp_status = sts->comp_status;
+	scsi_status = sts->scsi_status & cpu_to_le16((uint16_t)SS_MASK);
 	hindex = sts->handle;
 	handle = LSW(hindex);
 
@@ -2339,38 +2340,40 @@ qlafx00_status_entry(scsi_qla_host_t *vh
 		return;
 	}
 
-	lscsi_status = scsi_status & STATUS_MASK;
+	lscsi_status = scsi_status & cpu_to_le16((uint16_t)STATUS_MASK);
 
 	fcport = sp->fcport;
 
 	ox_id = 0;
 	sense_len = par_sense_len = rsp_info_len = resid_len =
 		fw_resid_len = 0;
-	if (scsi_status & SS_SENSE_LEN_VALID)
-		sense_len = le32_to_cpu(sts->sense_len);
-	if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER))
+	if (scsi_status & cpu_to_le16((uint16_t)SS_SENSE_LEN_VALID))
+		sense_len = sts->sense_len;
+	if (scsi_status & cpu_to_le16(((uint16_t)SS_RESIDUAL_UNDER
+	    | (uint16_t)SS_RESIDUAL_OVER)))
 		resid_len = le32_to_cpu(sts->residual_len);
-	if (comp_status == CS_DATA_UNDERRUN)
+	if (comp_status == cpu_to_le16((uint16_t)CS_DATA_UNDERRUN))
 		fw_resid_len = le32_to_cpu(sts->residual_len);
 	rsp_info = sense_data = sts->data;
 	par_sense_len = sizeof(sts->data);
 
 	/* Check for overrun. */
 	if (comp_status == CS_COMPLETE &&
-	    scsi_status & SS_RESIDUAL_OVER)
-		comp_status = CS_DATA_OVERRUN;
+	    scsi_status & cpu_to_le16((uint16_t)SS_RESIDUAL_OVER))
+		comp_status = cpu_to_le16((uint16_t)CS_DATA_OVERRUN);
 
 	/*
 	 * Based on Host and scsi status generate status code for Linux
 	 */
-	switch (comp_status) {
+	switch (le16_to_cpu(comp_status)) {
 	case CS_COMPLETE:
 	case CS_QUEUE_FULL:
 		if (scsi_status == 0) {
 			res = DID_OK << 16;
 			break;
 		}
-		if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
+		if (scsi_status & cpu_to_le16(((uint16_t)SS_RESIDUAL_UNDER
+		    | (uint16_t)SS_RESIDUAL_OVER))) {
 			resid = resid_len;
 			scsi_set_resid(cp, resid);
 
@@ -2386,19 +2389,20 @@ qlafx00_status_entry(scsi_qla_host_t *vh
 				break;
 			}
 		}
-		res = DID_OK << 16 | lscsi_status;
+		res = DID_OK << 16 | le16_to_cpu(lscsi_status);
 
-		if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
+		if (lscsi_status ==
+		    cpu_to_le16((uint16_t)SAM_STAT_TASK_SET_FULL)) {
 			ql_dbg(ql_dbg_io, fcport->vha, 0x3051,
 			    "QUEUE FULL detected.\n");
 			break;
 		}
 		logit = 0;
-		if (lscsi_status != SS_CHECK_CONDITION)
+		if (lscsi_status != cpu_to_le16((uint16_t)SS_CHECK_CONDITION))
 			break;
 
 		memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
-		if (!(scsi_status & SS_SENSE_LEN_VALID))
+		if (!(scsi_status & cpu_to_le16((uint16_t)SS_SENSE_LEN_VALID)))
 			break;
 
 		qlafx00_handle_sense(sp, sense_data, par_sense_len, sense_len,
@@ -2412,7 +2416,7 @@ qlafx00_status_entry(scsi_qla_host_t *vh
 		else
 			resid = resid_len;
 		scsi_set_resid(cp, resid);
-		if (scsi_status & SS_RESIDUAL_UNDER) {
+		if (scsi_status & cpu_to_le16((uint16_t)SS_RESIDUAL_UNDER)) {
 			if ((IS_FWI2_CAPABLE(ha) || IS_QLAFX00(ha))
 			    && fw_resid_len != resid_len) {
 				ql_dbg(ql_dbg_io, fcport->vha, 0x3052,
@@ -2420,7 +2424,8 @@ qlafx00_status_entry(scsi_qla_host_t *vh
 				    "(0x%x of 0x%x bytes).\n",
 				    resid, scsi_bufflen(cp));
 
-				res = DID_ERROR << 16 | lscsi_status;
+				res = DID_ERROR << 16 |
+				    le16_to_cpu(lscsi_status);
 				goto check_scsi_status;
 			}
 
@@ -2436,8 +2441,9 @@ qlafx00_status_entry(scsi_qla_host_t *vh
 				res = DID_ERROR << 16;
 				break;
 			}
-		} else if (lscsi_status != SAM_STAT_TASK_SET_FULL &&
-			    lscsi_status != SAM_STAT_BUSY) {
+		} else if (lscsi_status !=
+		    cpu_to_le16((uint16_t)SAM_STAT_TASK_SET_FULL) &&
+		    lscsi_status != cpu_to_le16((uint16_t)SAM_STAT_BUSY)) {
 			/*
 			 * scsi status of task set and busy are considered
 			 * to be task not completed.
@@ -2448,7 +2454,7 @@ qlafx00_status_entry(scsi_qla_host_t *vh
 			    "of 0x%x bytes).\n", resid,
 			    scsi_bufflen(cp));
 
-			res = DID_ERROR << 16 | lscsi_status;
+			res = DID_ERROR << 16 | le16_to_cpu(lscsi_status);
 			goto check_scsi_status;
 		} else {
 			ql_dbg(ql_dbg_io, fcport->vha, 0x3055,
@@ -2456,7 +2462,7 @@ qlafx00_status_entry(scsi_qla_host_t *vh
 			    scsi_status, lscsi_status);
 		}
 
-		res = DID_OK << 16 | lscsi_status;
+		res = DID_OK << 16 | le16_to_cpu(lscsi_status);
 		logit = 0;
 
 check_scsi_status:
@@ -2465,17 +2471,20 @@ check_scsi_status:
 		 * Status.
 		 */
 		if (lscsi_status != 0) {
-			if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
+			if (lscsi_status ==
+			    cpu_to_le16((uint16_t)SAM_STAT_TASK_SET_FULL)) {
 				ql_dbg(ql_dbg_io, fcport->vha, 0x3056,
 				    "QUEUE FULL detected.\n");
 				logit = 1;
 				break;
 			}
-			if (lscsi_status != SS_CHECK_CONDITION)
+			if (lscsi_status !=
+			    cpu_to_le16((uint16_t)SS_CHECK_CONDITION))
 				break;
 
 			memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
-			if (!(scsi_status & SS_SENSE_LEN_VALID))
+			if (!(scsi_status &
+			    cpu_to_le16((uint16_t)SS_SENSE_LEN_VALID)))
 				break;
 
 			qlafx00_handle_sense(sp, sense_data, par_sense_len,
@@ -2629,7 +2638,7 @@ qlafx00_multistatus_entry(struct scsi_ql
 	uint32_t handle, hindex, handle_count, i;
 	uint16_t que;
 	struct req_que *req;
-	uint32_t *handle_ptr;
+	__le32 *handle_ptr;
 
 	stsmfx = (struct multi_sts_entry_fx00 *) pkt;
 
@@ -2643,7 +2652,7 @@ qlafx00_multistatus_entry(struct scsi_ql
 		return;
 	}
 
-	handle_ptr = (uint32_t *) &stsmfx->handles[0];
+	handle_ptr =  &stsmfx->handles[0];
 
 	for (i = 0; i < handle_count; i++) {
 		hindex = le32_to_cpu(*handle_ptr);
@@ -2714,10 +2723,11 @@ qlafx00_process_response_queue(struct sc
 	if (!vha->flags.online)
 		return;
 
-	while (RD_REG_DWORD(&(rsp->ring_ptr->signature)) !=
+	while (RD_REG_DWORD((void __iomem *)&(rsp->ring_ptr->signature)) !=
 	    RESPONSE_PROCESSED) {
 		lptr = rsp->ring_ptr;
-		memcpy_fromio(rsp->rsp_pkt, lptr, sizeof(rsp->rsp_pkt));
+		memcpy_fromio(rsp->rsp_pkt, (void __iomem *)lptr,
+		    sizeof(rsp->rsp_pkt));
 		pkt = (struct sts_entry_fx00 *)rsp->rsp_pkt;
 
 		rsp->ring_index++;
@@ -2768,7 +2778,8 @@ qlafx00_process_response_queue(struct sc
 			break;
 		}
 next_iter:
-		WRT_REG_DWORD(&lptr->signature, RESPONSE_PROCESSED);
+		WRT_REG_DWORD((void __iomem *)&lptr->signature,
+		    RESPONSE_PROCESSED);
 		wmb();
 	}
 
@@ -2958,8 +2969,7 @@ qlafx00_prep_cont_type1_iocb(struct req_
 	cont_pkt = (cont_a64_entry_t *)req->ring_ptr;
 
 	/* Load packet defaults. */
-	*((uint32_t *)(&lcont_pkt->entry_type)) =
-	    __constant_cpu_to_le32(CONTINUE_A64_TYPE_FX00);
+	lcont_pkt->entry_type = CONTINUE_A64_TYPE_FX00;
 
 	return cont_pkt;
 }
@@ -2969,7 +2979,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, stru
 			 uint16_t tot_dsds, struct cmd_type_7_fx00 *lcmd_pkt)
 {
 	uint16_t	avail_dsds;
-	uint32_t	*cur_dsd;
+	__le32 *cur_dsd;
 	scsi_qla_host_t	*vha;
 	struct scsi_cmnd *cmd;
 	struct scatterlist *sg;
@@ -2986,8 +2996,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, stru
 	cont_pkt = NULL;
 
 	/* Update entry type to indicate Command Type 3 IOCB */
-	*((uint32_t *)(&lcmd_pkt->entry_type)) =
-	    __constant_cpu_to_le32(FX00_COMMAND_TYPE_7);
+	lcmd_pkt->entry_type = FX00_COMMAND_TYPE_7;
 
 	/* No data transfer */
 	if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
@@ -3006,7 +3015,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, stru
 
 	/* One DSD is available in the Command Type 3 IOCB */
 	avail_dsds = 1;
-	cur_dsd = (uint32_t *)&lcmd_pkt->dseg_0_address;
+	cur_dsd = (__le32 *)&lcmd_pkt->dseg_0_address;
 
 	/* Load data segments */
 	scsi_for_each_sg(cmd, sg, tot_dsds, i) {
@@ -3021,7 +3030,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, stru
 			memset(&lcont_pkt, 0, REQUEST_ENTRY_SIZE);
 			cont_pkt =
 			    qlafx00_prep_cont_type1_iocb(req, &lcont_pkt);
-			cur_dsd = (uint32_t *)lcont_pkt.dseg_0_address;
+			cur_dsd = (__le32 *)lcont_pkt.dseg_0_address;
 			avail_dsds = 5;
 			cont = 1;
 		}
@@ -3224,13 +3233,13 @@ qlafx00_tm_iocb(srb_t *sp, struct tsk_mg
 	tm_iocb.timeout = cpu_to_le16(qla2x00_get_async_timeout(vha) + 2);
 	tm_iocb.tgt_id = cpu_to_le16(sp->fcport->tgt_id);
 	tm_iocb.control_flags = cpu_to_le32(fxio->u.tmf.flags);
-	if (tm_iocb.control_flags == TCF_LUN_RESET) {
+	if (tm_iocb.control_flags == cpu_to_le32((uint32_t)TCF_LUN_RESET)) {
 		int_to_scsilun(fxio->u.tmf.lun, &llun);
 		host_to_adap((uint8_t *)&llun, (uint8_t *)&tm_iocb.lun,
 		    sizeof(struct scsi_lun));
 	}
 
-	memcpy((void __iomem *)ptm_iocb, &tm_iocb,
+	memcpy((void *)ptm_iocb, &tm_iocb,
 	    sizeof(struct tsk_mgmt_entry_fx00));
 	wmb();
 }
@@ -3252,7 +3261,7 @@ qlafx00_abort_iocb(srb_t *sp, struct abo
 	abt_iocb.tgt_id_sts = cpu_to_le16(sp->fcport->tgt_id);
 	abt_iocb.req_que_no = cpu_to_le16(req->id);
 
-	memcpy((void __iomem *)pabt_iocb, &abt_iocb,
+	memcpy((void *)pabt_iocb, &abt_iocb,
 	    sizeof(struct abort_iocb_entry_fx00));
 	wmb();
 }
@@ -3273,13 +3282,12 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fx
 
 	if (sp->type == SRB_FXIOCB_DCMD) {
 		fx_iocb.func_num =
-		    cpu_to_le16(sp->u.iocb_cmd.u.fxiocb.req_func_type);
-		fx_iocb.adapid = cpu_to_le32(fxio->u.fxiocb.adapter_id);
-		fx_iocb.adapid_hi = cpu_to_le32(fxio->u.fxiocb.adapter_id_hi);
-		fx_iocb.reserved_0 = cpu_to_le32(fxio->u.fxiocb.reserved_0);
-		fx_iocb.reserved_1 = cpu_to_le32(fxio->u.fxiocb.reserved_1);
-		fx_iocb.dataword_extra =
-		    cpu_to_le32(fxio->u.fxiocb.req_data_extra);
+		    sp->u.iocb_cmd.u.fxiocb.req_func_type;
+		fx_iocb.adapid = fxio->u.fxiocb.adapter_id;
+		fx_iocb.adapid_hi = fxio->u.fxiocb.adapter_id_hi;
+		fx_iocb.reserved_0 = fxio->u.fxiocb.reserved_0;
+		fx_iocb.reserved_1 = fxio->u.fxiocb.reserved_1;
+		fx_iocb.dataword_extra = fxio->u.fxiocb.req_data_extra;
 
 		if (fxio->u.fxiocb.flags & SRB_FXDISC_REQ_DMA_VALID) {
 			fx_iocb.req_dsdcnt = cpu_to_le16(1);
@@ -3306,8 +3314,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fx
 		}
 
 		if (fxio->u.fxiocb.flags & SRB_FXDISC_REQ_DWRD_VALID) {
-			fx_iocb.dataword =
-			    cpu_to_le32(fxio->u.fxiocb.req_data);
+			fx_iocb.dataword = fxio->u.fxiocb.req_data;
 		}
 		fx_iocb.flags = fxio->u.fxiocb.flags;
 	} else {
@@ -3323,21 +3330,21 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fx
 		fx_iocb.reserved_1 = piocb_rqst->reserved_1;
 		fx_iocb.dataword_extra = piocb_rqst->dataword_extra;
 		fx_iocb.dataword = piocb_rqst->dataword;
-		fx_iocb.req_xfrcnt = cpu_to_le16(piocb_rqst->req_len);
-		fx_iocb.rsp_xfrcnt = cpu_to_le16(piocb_rqst->rsp_len);
+		fx_iocb.req_xfrcnt = piocb_rqst->req_len;
+		fx_iocb.rsp_xfrcnt = piocb_rqst->rsp_len;
 
 		if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID) {
 			int avail_dsds, tot_dsds;
 			cont_a64_entry_t lcont_pkt;
 			cont_a64_entry_t *cont_pkt = NULL;
-			uint32_t *cur_dsd;
+			__le32 *cur_dsd;
 			int index = 0, cont = 0;
 
 			fx_iocb.req_dsdcnt =
 			    cpu_to_le16(bsg_job->request_payload.sg_cnt);
 			tot_dsds =
-			    cpu_to_le32(bsg_job->request_payload.sg_cnt);
-			cur_dsd = (uint32_t *)&fx_iocb.dseg_rq_address[0];
+			    bsg_job->request_payload.sg_cnt;
+			cur_dsd = (__le32 *)&fx_iocb.dseg_rq_address[0];
 			avail_dsds = 1;
 			for_each_sg(bsg_job->request_payload.sg_list, sg,
 			    tot_dsds, index) {
@@ -3355,7 +3362,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fx
 					    qlafx00_prep_cont_type1_iocb(
 						sp->fcport->vha->req,
 						&lcont_pkt);
-					cur_dsd = (uint32_t *)
+					cur_dsd = (__le32 *)
 					    lcont_pkt.dseg_0_address;
 					avail_dsds = 5;
 					cont = 1;
@@ -3393,13 +3400,13 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fx
 			int avail_dsds, tot_dsds;
 			cont_a64_entry_t lcont_pkt;
 			cont_a64_entry_t *cont_pkt = NULL;
-			uint32_t *cur_dsd;
+			__le32 *cur_dsd;
 			int index = 0, cont = 0;
 
 			fx_iocb.rsp_dsdcnt =
 			   cpu_to_le16(bsg_job->reply_payload.sg_cnt);
-			tot_dsds = cpu_to_le32(bsg_job->reply_payload.sg_cnt);
-			cur_dsd = (uint32_t *)&fx_iocb.dseg_rsp_address[0];
+			tot_dsds = bsg_job->reply_payload.sg_cnt;
+			cur_dsd = (__le32 *)&fx_iocb.dseg_rsp_address[0];
 			avail_dsds = 1;
 
 			for_each_sg(bsg_job->reply_payload.sg_list, sg,
@@ -3418,7 +3425,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fx
 					    qlafx00_prep_cont_type1_iocb(
 						sp->fcport->vha->req,
 						&lcont_pkt);
-					cur_dsd = (uint32_t *)
+					cur_dsd = (__le32 *)
 					    lcont_pkt.dseg_0_address;
 					avail_dsds = 5;
 					cont = 1;
@@ -3453,7 +3460,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fx
 		}
 
 		if (piocb_rqst->flags & SRB_FXDISC_REQ_DWRD_VALID)
-			fx_iocb.dataword = cpu_to_le32(piocb_rqst->dataword);
+			fx_iocb.dataword = piocb_rqst->dataword;
 		fx_iocb.flags = piocb_rqst->flags;
 		fx_iocb.entry_count = entry_cnt;
 	}
@@ -3462,7 +3469,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fx
 	    sp->fcport->vha, 0x3047,
 	    (uint8_t *)&fx_iocb, sizeof(struct fxdisc_entry_fx00));
 
-	memcpy((void __iomem *)pfxiocb, &fx_iocb,
+	memcpy((void *)pfxiocb, &fx_iocb,
 	    sizeof(struct fxdisc_entry_fx00));
 	wmb();
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_mr.h linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_mr.h
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_mr.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_mr.h	2013-08-25 20:43:22.000000000 -0400
@@ -24,10 +24,10 @@ struct cmd_type_7_fx00 {
 	uint32_t handle;		/* System handle. */
 	uint32_t handle_hi;
 
-	uint16_t tgt_idx;		/* Target Idx. */
+	__le16 tgt_idx;		/* Target Idx. */
 	uint16_t timeout;		/* Command timeout. */
 
-	uint16_t dseg_count;		/* Data segment count. */
+	__le16 dseg_count;		/* Data segment count. */
 	uint16_t scsi_rsp_dsd_len;
 
 	struct scsi_lun lun;		/* LUN (LE). */
@@ -41,7 +41,7 @@ struct cmd_type_7_fx00 {
 	uint8_t crn;
 
 	uint8_t fcp_cdb[MAX_CMDSZ];	/* SCSI command words. */
-	uint32_t byte_count;		/* Total byte count. */
+	__le32 byte_count;		/* Total byte count. */
 
 	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
 	uint32_t dseg_0_len;		/* Data segment 0 length. */
@@ -81,16 +81,16 @@ struct sts_entry_fx00 {
 	uint32_t handle;		/* System handle. */
 	uint32_t handle_hi;		/* System handle. */
 
-	uint16_t comp_status;		/* Completion status. */
+	__le16 comp_status;		/* Completion status. */
 	uint16_t reserved_0;		/* OX_ID used by the firmware. */
 
-	uint32_t residual_len;		/* FW calc residual transfer length. */
+	__le32 residual_len;		/* FW calc residual transfer length. */
 
 	uint16_t reserved_1;
 	uint16_t state_flags;		/* State flags. */
 
 	uint16_t reserved_2;
-	uint16_t scsi_status;		/* SCSI status. */
+	__le16 scsi_status;		/* SCSI status. */
 
 	uint32_t sense_len;		/* FCP SENSE length. */
 	uint8_t data[32];		/* FCP response/sense information. */
@@ -106,7 +106,7 @@ struct multi_sts_entry_fx00 {
 	uint8_t handle_count;
 	uint8_t entry_status;
 
-	uint32_t handles[MAX_HANDLE_COUNT];
+	__le32 handles[MAX_HANDLE_COUNT];
 };
 
 #define TSK_MGMT_IOCB_TYPE_FX00		0x05
@@ -116,21 +116,21 @@ struct tsk_mgmt_entry_fx00 {
 	uint8_t sys_define;
 	uint8_t entry_status;		/* Entry Status. */
 
-	uint32_t handle;		/* System handle. */
+	__le32 handle;		/* System handle. */
 
 	uint32_t handle_hi;		/* System handle. */
 
-	uint16_t tgt_id;		/* Target Idx. */
+	__le16 tgt_id;		/* Target Idx. */
 
 	uint16_t reserved_1;
 
 	uint16_t delay;			/* Activity delay in seconds. */
 
-	uint16_t timeout;		/* Command timeout. */
+	__le16 timeout;		/* Command timeout. */
 
 	struct scsi_lun lun;		/* LUN (LE). */
 
-	uint32_t control_flags;		/* Control Flags. */
+	__le32 control_flags;		/* Control Flags. */
 
 	uint8_t reserved_2[32];
 };
@@ -143,16 +143,16 @@ struct abort_iocb_entry_fx00 {
 	uint8_t sys_define;		/* System defined. */
 	uint8_t entry_status;		/* Entry Status. */
 
-	uint32_t handle;		/* System handle. */
-	uint32_t handle_hi;		/* System handle. */
+	__le32 handle;		/* System handle. */
+	__le32 handle_hi;		/* System handle. */
 
-	uint16_t tgt_id_sts;		/* Completion status. */
-	uint16_t options;
+	__le16 tgt_id_sts;		/* Completion status. */
+	__le16 options;
 
-	uint32_t abort_handle;		/* System handle. */
-	uint32_t abort_handle_hi;	/* System handle. */
+	__le32 abort_handle;		/* System handle. */
+	__le32 abort_handle_hi;	/* System handle. */
 
-	uint16_t req_que_no;
+	__le16 req_que_no;
 	uint8_t reserved_1[38];
 };
 
@@ -167,17 +167,17 @@ struct ioctl_iocb_entry_fx00 {
 	uint32_t reserved_0;		/* System handle. */
 
 	uint16_t comp_func_num;
-	uint16_t fw_iotcl_flags;
+	__le16 fw_iotcl_flags;
 
-	uint32_t dataword_r;		/* Data word returned */
+	__le32 dataword_r;		/* Data word returned */
 	uint32_t adapid;		/* Adapter ID */
 	uint32_t adapid_hi;		/* Adapter ID high */
 	uint32_t reserved_1;
 
-	uint32_t seq_no;
+	__le32 seq_no;
 	uint8_t reserved_2[20];
 	uint32_t residuallen;
-	uint32_t status;
+	__le32 status;
 };
 
 #define STATUS_CONT_TYPE_FX00 0x04
@@ -189,26 +189,26 @@ struct fxdisc_entry_fx00 {
 	uint8_t sys_define;		/* System Defined. */
 	uint8_t entry_status;		/* Entry Status. */
 
-	uint32_t handle;		/* System handle. */
-	uint32_t reserved_0;		/* System handle. */
+	__le32 handle;		/* System handle. */
+	__le32 reserved_0;		/* System handle. */
 
-	uint16_t func_num;
-	uint16_t req_xfrcnt;
-	uint16_t req_dsdcnt;
-	uint16_t rsp_xfrcnt;
-	uint16_t rsp_dsdcnt;
+	__le16 func_num;
+	__le16 req_xfrcnt;
+	__le16 req_dsdcnt;
+	__le16 rsp_xfrcnt;
+	__le16 rsp_dsdcnt;
 	uint8_t flags;
 	uint8_t reserved_1;
 
-	uint32_t dseg_rq_address[2];	/* Data segment 0 address. */
-	uint32_t dseg_rq_len;		/* Data segment 0 length. */
-	uint32_t dseg_rsp_address[2];	/* Data segment 1 address. */
-	uint32_t dseg_rsp_len;		/* Data segment 1 length. */
+	__le32 dseg_rq_address[2];	/* Data segment 0 address. */
+	__le32 dseg_rq_len;		/* Data segment 0 length. */
+	__le32 dseg_rsp_address[2];	/* Data segment 1 address. */
+	__le32 dseg_rsp_len;		/* Data segment 1 length. */
 
-	uint32_t dataword;
-	uint32_t adapid;
-	uint32_t adapid_hi;
-	uint32_t dataword_extra;
+	__le32 dataword;
+	__le32 adapid;
+	__le32 adapid_hi;
+	__le32 dataword_extra;
 };
 
 struct qlafx00_tgt_node_info {
@@ -421,43 +421,43 @@ struct config_info_data {
 	WRT_REG_DWORD((ha)->cregbase + off, val)
 
 struct qla_mt_iocb_rqst_fx00 {
-	uint32_t reserved_0;
+	__le32 reserved_0;
 
-	uint16_t func_type;
+	__le16 func_type;
 	uint8_t flags;
 	uint8_t reserved_1;
 
-	uint32_t dataword;
+	__le32 dataword;
 
-	uint32_t adapid;
-	uint32_t adapid_hi;
+	__le32 adapid;
+	__le32 adapid_hi;
 
-	uint32_t dataword_extra;
+	__le32 dataword_extra;
 
-	uint32_t req_len;
+	__le32 req_len;
 
-	uint32_t rsp_len;
+	__le32 rsp_len;
 };
 
 struct qla_mt_iocb_rsp_fx00 {
 	uint32_t reserved_1;
 
 	uint16_t func_type;
-	uint16_t ioctl_flags;
+	__le16 ioctl_flags;
 
-	uint32_t ioctl_data;
+	__le32 ioctl_data;
 
 	uint32_t adapid;
 	uint32_t adapid_hi;
 
 	uint32_t reserved_2;
-	uint32_t seq_number;
+	__le32 seq_number;
 
 	uint8_t reserved_3[20];
 
 	int32_t res_count;
 
-	uint32_t status;
+	__le32 status;
 };
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_os.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_os.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_os.c	2013-07-01 10:42:48.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_os.c	2013-08-31 18:02:36.000000000 -0400
@@ -104,8 +104,6 @@ MODULE_PARM_DESC(ql2xshiftctondsd,
 		"Set to control shifting of command type processing "
 		"based on total number of SG elements.");
 
-static void qla2x00_free_device(scsi_qla_host_t *);
-
 int ql2xfdmienable=1;
 module_param(ql2xfdmienable, int, S_IRUGO);
 MODULE_PARM_DESC(ql2xfdmienable,
@@ -237,6 +235,7 @@ static int qla2xxx_eh_host_reset(struct
 
 static int qla2x00_change_queue_depth(struct scsi_device *, int, int);
 static int qla2x00_change_queue_type(struct scsi_device *, int);
+static void qla2x00_free_device(scsi_qla_host_t *);
 
 struct scsi_host_template qla2xxx_driver_template = {
 	.module			= THIS_MODULE,
@@ -2840,8 +2839,7 @@ skip_dpc:
 	qla2x00_dfs_setup(base_vha);
 
 	ql_log(ql_log_info, base_vha, 0x00fb,
-	    "QLogic %s - %s.\n",
-	    ha->model_number, ha->model_desc ? ha->model_desc : "");
+	    "QLogic %s - %s.\n", ha->model_number, ha->model_desc);
 	ql_log(ql_log_info, base_vha, 0x00fc,
 	    "ISP%04X: %s @ %s hdma%c host#=%ld fw=%s.\n",
 	    pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info),
@@ -2981,14 +2979,12 @@ qla2x00_remove_one(struct pci_dev *pdev)
 	set_bit(UNLOADING, &base_vha->dpc_flags);
 	mutex_lock(&ha->vport_lock);
 	while (ha->cur_vport_count) {
-		struct Scsi_Host *scsi_host;
-
 		spin_lock_irqsave(&ha->vport_slock, flags);
 
 		BUG_ON(base_vha->list.next == &ha->vp_list);
 		/* This assumes first entry in ha->vp_list is always base vha */
 		vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list);
-		scsi_host = scsi_host_get(vha->host);
+		scsi_host_get(vha->host);
 
 		spin_unlock_irqrestore(&ha->vport_slock, flags);
 		mutex_unlock(&ha->vport_lock);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_target.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_target.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/qla_target.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/qla_target.c	2013-08-25 20:43:22.000000000 -0400
@@ -544,102 +544,6 @@ out_free_id_list:
 	return res;
 }
 
-static bool qlt_check_fcport_exist(struct scsi_qla_host *vha,
-	struct qla_tgt_sess *sess)
-{
-	struct qla_hw_data *ha = vha->hw;
-	struct qla_port_24xx_data *pmap24;
-	bool res, found = false;
-	int rc, i;
-	uint16_t loop_id = 0xFFFF; /* to eliminate compiler's warning */
-	uint16_t entries;
-	void *pmap;
-	int pmap_len;
-	fc_port_t *fcport;
-	int global_resets;
-	unsigned long flags;
-
-retry:
-	global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count);
-
-	rc = qla2x00_get_node_name_list(vha, &pmap, &pmap_len);
-	if (rc != QLA_SUCCESS) {
-		res = false;
-		goto out;
-	}
-
-	pmap24 = pmap;
-	entries = pmap_len/sizeof(*pmap24);
-
-	for (i = 0; i < entries; ++i) {
-		if (!memcmp(sess->port_name, pmap24[i].port_name, WWN_SIZE)) {
-			loop_id = le16_to_cpu(pmap24[i].loop_id);
-			found = true;
-			break;
-		}
-	}
-
-	kfree(pmap);
-
-	if (!found) {
-		res = false;
-		goto out;
-	}
-
-	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf046,
-	    "qlt_check_fcport_exist(): loop_id %d", loop_id);
-
-	fcport = kzalloc(sizeof(*fcport), GFP_KERNEL);
-	if (fcport == NULL) {
-		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf047,
-		    "qla_target(%d): Allocation of tmp FC port failed",
-		    vha->vp_idx);
-		res = false;
-		goto out;
-	}
-
-	fcport->loop_id = loop_id;
-
-	rc = qla2x00_get_port_database(vha, fcport, 0);
-	if (rc != QLA_SUCCESS) {
-		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf048,
-		    "qla_target(%d): Failed to retrieve fcport "
-		    "information -- get_port_database() returned %x "
-		    "(loop_id=0x%04x)", vha->vp_idx, rc, loop_id);
-		res = false;
-		goto out_free_fcport;
-	}
-
-	if (global_resets !=
-	    atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)) {
-		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf002,
-		    "qla_target(%d): global reset during session discovery"
-		    " (counter was %d, new %d), retrying",
-		    vha->vp_idx, global_resets,
-		    atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count));
-		goto retry;
-	}
-
-	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003,
-	    "Updating sess %p s_id %x:%x:%x, loop_id %d) to d_id %x:%x:%x, "
-	    "loop_id %d", sess, sess->s_id.b.domain, sess->s_id.b.al_pa,
-	    sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain,
-	    fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id);
-
-	spin_lock_irqsave(&ha->hardware_lock, flags);
-	ha->tgt.tgt_ops->update_sess(sess, fcport->d_id, fcport->loop_id,
-				(fcport->flags & FCF_CONF_COMP_SUPPORTED));
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
-	res = true;
-
-out_free_fcport:
-	kfree(fcport);
-
-out:
-	return res;
-}
-
 /* ha->hardware_lock supposed to be held on entry */
 static void qlt_undelete_sess(struct qla_tgt_sess *sess)
 {
@@ -663,43 +567,13 @@ static void qlt_del_sess_work_fn(struct
 		sess = list_entry(tgt->del_sess_list.next, typeof(*sess),
 		    del_list_entry);
 		if (time_after_eq(jiffies, sess->expires)) {
-			bool cancel;
-
 			qlt_undelete_sess(sess);
 
-			spin_unlock_irqrestore(&ha->hardware_lock, flags);
-			cancel = qlt_check_fcport_exist(vha, sess);
-
-			if (cancel) {
-				if (sess->deleted) {
-					/*
-					 * sess was again deleted while we were
-					 * discovering it
-					 */
-					spin_lock_irqsave(&ha->hardware_lock,
-					    flags);
-					continue;
-				}
-
-				ql_dbg(ql_dbg_tgt_mgt, vha, 0xf049,
-				    "qla_target(%d): cancel deletion of "
-				    "session for port %02x:%02x:%02x:%02x:%02x:"
-				    "%02x:%02x:%02x (loop ID %d), because "
-				    " it isn't deleted by firmware",
-				    vha->vp_idx, sess->port_name[0],
-				    sess->port_name[1], sess->port_name[2],
-				    sess->port_name[3], sess->port_name[4],
-				    sess->port_name[5], sess->port_name[6],
-				    sess->port_name[7], sess->loop_id);
-			} else {
-				ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004,
-				    "Timeout: sess %p about to be deleted\n",
-				    sess);
-				ha->tgt.tgt_ops->shutdown_sess(sess);
-				ha->tgt.tgt_ops->put_sess(sess);
-			}
-
-			spin_lock_irqsave(&ha->hardware_lock, flags);
+			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004,
+			    "Timeout: sess %p about to be deleted\n",
+			    sess);
+			ha->tgt.tgt_ops->shutdown_sess(sess);
+			ha->tgt.tgt_ops->put_sess(sess);
 		} else {
 			schedule_delayed_work(&tgt->sess_del_work,
 			    jiffies - sess->expires);
@@ -884,9 +758,8 @@ void qlt_fc_port_added(struct scsi_qla_h
 		    sess->loop_id);
 		sess->local = 0;
 	}
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
 	ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
 void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport)
@@ -2706,7 +2579,9 @@ static void qlt_do_work(struct work_stru
 	/*
 	 * Drop extra session reference from qla_tgt_handle_cmd_for_atio*(
 	 */
+	spin_lock_irqsave(&ha->hardware_lock, flags);
 	ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	return;
 
 out_term:
@@ -2718,9 +2593,9 @@ out_term:
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	qlt_send_term_exchange(vha, NULL, &cmd->atio, 1);
 	kmem_cache_free(qla_tgt_cmd_cachep, cmd);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	if (sess)
 		ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
 /* ha->hardware_lock supposed to be held on entry */
@@ -4169,16 +4044,16 @@ static void qlt_abort_work(struct qla_tg
 	rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess);
 	if (rc != 0)
 		goto out_term;
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	return;
 
 out_term:
 	qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	if (sess)
 		ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
 static void qlt_tmr_work(struct qla_tgt *tgt,
@@ -4226,16 +4101,16 @@ static void qlt_tmr_work(struct qla_tgt
 	rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0);
 	if (rc != 0)
 		goto out_term;
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	return;
 
 out_term:
 	qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	if (sess)
 		ha->tgt.tgt_ops->put_sess(sess);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
 static void qlt_sess_work_fn(struct work_struct *work)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla2xxx/tcm_qla2xxx.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/tcm_qla2xxx.c
--- linux-libre-3.10-gnu/drivers/scsi/qla2xxx/tcm_qla2xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla2xxx/tcm_qla2xxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -703,7 +703,7 @@ static int tcm_qla2xxx_queue_status(stru
 	return qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status);
 }
 
-static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
+static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
 {
 	struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
 	struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd,
@@ -735,8 +735,6 @@ static int tcm_qla2xxx_queue_tm_rsp(stru
 	 * CTIO response packet.
 	 */
 	qlt_xmit_tm_rsp(mcmd);
-
-	return 0;
 }
 
 /* Local pointer to allocated TCM configfs fabric module */
@@ -799,12 +797,14 @@ static void tcm_qla2xxx_put_session(stru
 
 static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess)
 {
-	tcm_qla2xxx_put_session(sess->se_sess);
+	assert_spin_locked(&sess->vha->hw->hardware_lock);
+	kref_put(&sess->se_sess->sess_kref, tcm_qla2xxx_release_session);
 }
 
 static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess)
 {
-	tcm_qla2xxx_shutdown_session(sess->se_sess);
+	assert_spin_locked(&sess->vha->hw->hardware_lock);
+	target_sess_cmd_list_set_waiting(sess->se_sess);
 }
 
 static struct se_node_acl *tcm_qla2xxx_make_nodeacl(
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/qla4xxx/ql4_os.c linux-libre-3.11-rc7-gnu/drivers/scsi/qla4xxx/ql4_os.c
--- linux-libre-3.10-gnu/drivers/scsi/qla4xxx/ql4_os.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/qla4xxx/ql4_os.c	2013-08-25 20:43:22.000000000 -0400
@@ -7060,8 +7060,8 @@ skip_retry_init:
 	}
 	INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc);
 
-	sprintf(buf, "qla4xxx_%lu_task", ha->host_no);
-	ha->task_wq = alloc_workqueue(buf, WQ_MEM_RECLAIM, 1);
+	ha->task_wq = alloc_workqueue("qla4xxx_%lu_task", WQ_MEM_RECLAIM, 1,
+				      ha->host_no);
 	if (!ha->task_wq) {
 		ql4_printk(KERN_WARNING, ha, "Unable to start task thread!\n");
 		ret = -ENODEV;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -1031,6 +1031,9 @@ int scsi_get_vpd_page(struct scsi_device
 {
 	int i, result;
 
+	if (sdev->skip_vpd_pages)
+		goto fail;
+
 	/* Ask for all the pages supported by this device */
 	result = scsi_vpd_inquiry(sdev, buf, 0, buf_len);
 	if (result)
@@ -1070,8 +1073,8 @@ EXPORT_SYMBOL_GPL(scsi_get_vpd_page);
  * @opcode:	opcode for command to look up
  *
  * Uses the REPORT SUPPORTED OPERATION CODES to look up the given
- * opcode. Returns 0 if RSOC fails or if the command opcode is
- * unsupported. Returns 1 if the device claims to support the command.
+ * opcode. Returns -EINVAL if RSOC fails, 0 if the command opcode is
+ * unsupported and 1 if the device claims to support the command.
  */
 int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
 		       unsigned int len, unsigned char opcode)
@@ -1081,7 +1084,7 @@ int scsi_report_opcode(struct scsi_devic
 	int result;
 
 	if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3)
-		return 0;
+		return -EINVAL;
 
 	memset(cmd, 0, 16);
 	cmd[0] = MAINTENANCE_IN;
@@ -1097,7 +1100,7 @@ int scsi_report_opcode(struct scsi_devic
 	if (result && scsi_sense_valid(&sshdr) &&
 	    sshdr.sense_key == ILLEGAL_REQUEST &&
 	    (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00)
-		return 0;
+		return -EINVAL;
 
 	if ((buffer[1] & 3) == 3) /* Command supported */
 		return 1;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi_debug.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_debug.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi_debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -258,7 +258,7 @@ struct sdebug_queued_cmd {
 static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE];
 
 static unsigned char * fake_storep;	/* ramdisk storage */
-static unsigned char *dif_storep;	/* protection info */
+static struct sd_dif_tuple *dif_storep;	/* protection info */
 static void *map_storep;		/* provisioning map */
 
 static unsigned long map_size;
@@ -277,11 +277,6 @@ static char sdebug_proc_name[] = "scsi_d
 
 static struct bus_type pseudo_lld_bus;
 
-static inline sector_t dif_offset(sector_t sector)
-{
-	return sector << 3;
-}
-
 static struct device_driver sdebug_driverfs_driver = {
 	.name 		= sdebug_proc_name,
 	.bus		= &pseudo_lld_bus,
@@ -439,10 +434,7 @@ static int fill_from_dev_buffer(struct s
 
 	act_len = sg_copy_from_buffer(sdb->table.sgl, sdb->table.nents,
 				      arr, arr_len);
-	if (sdb->resid)
-		sdb->resid -= act_len;
-	else
-		sdb->resid = scsi_bufflen(scp) - act_len;
+	sdb->resid = scsi_bufflen(scp) - act_len;
 
 	return 0;
 }
@@ -1693,28 +1685,96 @@ static int check_device_access_params(st
 	return 0;
 }
 
+/* Returns number of bytes copied or -1 if error. */
 static int do_device_access(struct scsi_cmnd *scmd,
 			    struct sdebug_dev_info *devi,
 			    unsigned long long lba, unsigned int num, int write)
 {
 	int ret;
 	unsigned long long block, rest = 0;
-	int (*func)(struct scsi_cmnd *, unsigned char *, int);
+	struct scsi_data_buffer *sdb;
+	enum dma_data_direction dir;
+	size_t (*func)(struct scatterlist *, unsigned int, void *, size_t,
+		       off_t);
 
-	func = write ? fetch_to_dev_buffer : fill_from_dev_buffer;
+	if (write) {
+		sdb = scsi_out(scmd);
+		dir = DMA_TO_DEVICE;
+		func = sg_pcopy_to_buffer;
+	} else {
+		sdb = scsi_in(scmd);
+		dir = DMA_FROM_DEVICE;
+		func = sg_pcopy_from_buffer;
+	}
+
+	if (!sdb->length)
+		return 0;
+	if (!(scsi_bidi_cmnd(scmd) || scmd->sc_data_direction == dir))
+		return -1;
 
 	block = do_div(lba, sdebug_store_sectors);
 	if (block + num > sdebug_store_sectors)
 		rest = block + num - sdebug_store_sectors;
 
-	ret = func(scmd, fake_storep + (block * scsi_debug_sector_size),
-		   (num - rest) * scsi_debug_sector_size);
-	if (!ret && rest)
-		ret = func(scmd, fake_storep, rest * scsi_debug_sector_size);
+	ret = func(sdb->table.sgl, sdb->table.nents,
+		   fake_storep + (block * scsi_debug_sector_size),
+		   (num - rest) * scsi_debug_sector_size, 0);
+	if (ret != (num - rest) * scsi_debug_sector_size)
+		return ret;
+
+	if (rest) {
+		ret += func(sdb->table.sgl, sdb->table.nents,
+			    fake_storep, rest * scsi_debug_sector_size,
+			    (num - rest) * scsi_debug_sector_size);
+	}
 
 	return ret;
 }
 
+static u16 dif_compute_csum(const void *buf, int len)
+{
+	u16 csum;
+
+	switch (scsi_debug_guard) {
+	case 1:
+		csum = ip_compute_csum(buf, len);
+		break;
+	case 0:
+		csum = cpu_to_be16(crc_t10dif(buf, len));
+		break;
+	}
+	return csum;
+}
+
+static int dif_verify(struct sd_dif_tuple *sdt, const void *data,
+		      sector_t sector, u32 ei_lba)
+{
+	u16 csum = dif_compute_csum(data, scsi_debug_sector_size);
+
+	if (sdt->guard_tag != csum) {
+		pr_err("%s: GUARD check failed on sector %lu rcvd 0x%04x, data 0x%04x\n",
+			__func__,
+			(unsigned long)sector,
+			be16_to_cpu(sdt->guard_tag),
+			be16_to_cpu(csum));
+		return 0x01;
+	}
+	if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
+	    be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) {
+		pr_err("%s: REF check failed on sector %lu\n",
+			__func__, (unsigned long)sector);
+		return 0x03;
+	}
+	if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
+	    be32_to_cpu(sdt->ref_tag) != ei_lba) {
+		pr_err("%s: REF check failed on sector %lu\n",
+			__func__, (unsigned long)sector);
+			dif_errors++;
+		return 0x03;
+	}
+	return 0;
+}
+
 static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
 			    unsigned int sectors, u32 ei_lba)
 {
@@ -1727,71 +1787,38 @@ static int prot_verify_read(struct scsi_
 
 	start_sec = do_div(tmp_sec, sdebug_store_sectors);
 
-	sdt = (struct sd_dif_tuple *)(dif_storep + dif_offset(start_sec));
+	sdt = dif_storep + start_sec;
 
 	for (i = 0 ; i < sectors ; i++) {
-		u16 csum;
+		int ret;
 
 		if (sdt[i].app_tag == 0xffff)
 			continue;
 
 		sector = start_sec + i;
 
-		switch (scsi_debug_guard) {
-		case 1:
-			csum = ip_compute_csum(fake_storep +
-					       sector * scsi_debug_sector_size,
-					       scsi_debug_sector_size);
-			break;
-		case 0:
-			csum = crc_t10dif(fake_storep +
-					  sector * scsi_debug_sector_size,
-					  scsi_debug_sector_size);
-			csum = cpu_to_be16(csum);
-			break;
-		default:
-			BUG();
-		}
-
-		if (sdt[i].guard_tag != csum) {
-			printk(KERN_ERR "%s: GUARD check failed on sector %lu" \
-			       " rcvd 0x%04x, data 0x%04x\n", __func__,
-			       (unsigned long)sector,
-			       be16_to_cpu(sdt[i].guard_tag),
-			       be16_to_cpu(csum));
-			dif_errors++;
-			return 0x01;
-		}
-
-		if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
-		    be32_to_cpu(sdt[i].ref_tag) != (sector & 0xffffffff)) {
-			printk(KERN_ERR "%s: REF check failed on sector %lu\n",
-			       __func__, (unsigned long)sector);
-			dif_errors++;
-			return 0x03;
-		}
-
-		if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
-		    be32_to_cpu(sdt[i].ref_tag) != ei_lba) {
-			printk(KERN_ERR "%s: REF check failed on sector %lu\n",
-			       __func__, (unsigned long)sector);
+		ret = dif_verify(&sdt[i],
+				 fake_storep + sector * scsi_debug_sector_size,
+				 sector, ei_lba);
+		if (ret) {
 			dif_errors++;
-			return 0x03;
+			return ret;
 		}
 
 		ei_lba++;
 	}
 
-	resid = sectors * 8; /* Bytes of protection data to copy into sgl */
+	/* Bytes of protection data to copy into sgl */
+	resid = sectors * sizeof(*dif_storep);
 	sector = start_sec;
 
 	scsi_for_each_prot_sg(SCpnt, psgl, scsi_prot_sg_count(SCpnt), i) {
 		int len = min(psgl->length, resid);
 
 		paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
-		memcpy(paddr, dif_storep + dif_offset(sector), len);
+		memcpy(paddr, dif_storep + sector, len);
 
-		sector += len >> 3;
+		sector += len / sizeof(*dif_storep);
 		if (sector >= sdebug_store_sectors) {
 			/* Force wrap */
 			tmp_sec = sector;
@@ -1849,7 +1876,12 @@ static int resp_read(struct scsi_cmnd *S
 	read_lock_irqsave(&atomic_rw, iflags);
 	ret = do_device_access(SCpnt, devip, lba, num, 0);
 	read_unlock_irqrestore(&atomic_rw, iflags);
-	return ret;
+	if (ret == -1)
+		return DID_ERROR << 16;
+
+	scsi_in(SCpnt)->resid = scsi_bufflen(SCpnt) - ret;
+
+	return 0;
 }
 
 void dump_sector(unsigned char *buf, int len)
@@ -1884,22 +1916,21 @@ static int prot_verify_write(struct scsi
 	sector_t tmp_sec = start_sec;
 	sector_t sector;
 	int ppage_offset;
-	unsigned short csum;
 
 	sector = do_div(tmp_sec, sdebug_store_sectors);
 
 	BUG_ON(scsi_sg_count(SCpnt) == 0);
 	BUG_ON(scsi_prot_sg_count(SCpnt) == 0);
 
-	paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
 	ppage_offset = 0;
 
 	/* For each data page */
 	scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) {
 		daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset;
+		paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
 
 		/* For each sector-sized chunk in data page */
-		for (j = 0 ; j < dsgl->length ; j += scsi_debug_sector_size) {
+		for (j = 0; j < dsgl->length; j += scsi_debug_sector_size) {
 
 			/* If we're at the end of the current
 			 * protection page advance to the next one
@@ -1915,51 +1946,9 @@ static int prot_verify_write(struct scsi
 
 			sdt = paddr + ppage_offset;
 
-			switch (scsi_debug_guard) {
-			case 1:
-				csum = ip_compute_csum(daddr,
-						       scsi_debug_sector_size);
-				break;
-			case 0:
-				csum = cpu_to_be16(crc_t10dif(daddr,
-						      scsi_debug_sector_size));
-				break;
-			default:
-				BUG();
-				ret = 0;
-				goto out;
-			}
-
-			if (sdt->guard_tag != csum) {
-				printk(KERN_ERR
-				       "%s: GUARD check failed on sector %lu " \
-				       "rcvd 0x%04x, calculated 0x%04x\n",
-				       __func__, (unsigned long)sector,
-				       be16_to_cpu(sdt->guard_tag),
-				       be16_to_cpu(csum));
-				ret = 0x01;
-				dump_sector(daddr, scsi_debug_sector_size);
-				goto out;
-			}
-
-			if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
-			    be32_to_cpu(sdt->ref_tag)
-			    != (start_sec & 0xffffffff)) {
-				printk(KERN_ERR
-				       "%s: REF check failed on sector %lu\n",
-				       __func__, (unsigned long)sector);
-				ret = 0x03;
-				dump_sector(daddr, scsi_debug_sector_size);
-				goto out;
-			}
-
-			if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
-			    be32_to_cpu(sdt->ref_tag) != ei_lba) {
-				printk(KERN_ERR
-				       "%s: REF check failed on sector %lu\n",
-				       __func__, (unsigned long)sector);
-				ret = 0x03;
-				dump_sector(daddr, scsi_debug_sector_size);
+			ret = dif_verify(sdt, daddr + j, start_sec, ei_lba);
+			if (ret) {
+				dump_sector(daddr + j, scsi_debug_sector_size);
 				goto out;
 			}
 
@@ -1968,7 +1957,7 @@ static int prot_verify_write(struct scsi
 			 * correctness we need to verify each sector
 			 * before writing it to "stable" storage
 			 */
-			memcpy(dif_storep + dif_offset(sector), sdt, 8);
+			memcpy(dif_storep + sector, sdt, sizeof(*sdt));
 
 			sector++;
 
@@ -1977,23 +1966,21 @@ static int prot_verify_write(struct scsi
 
 			start_sec++;
 			ei_lba++;
-			daddr += scsi_debug_sector_size;
 			ppage_offset += sizeof(struct sd_dif_tuple);
 		}
 
+		kunmap_atomic(paddr);
 		kunmap_atomic(daddr);
 	}
 
-	kunmap_atomic(paddr);
-
 	dix_writes++;
 
 	return 0;
 
 out:
 	dif_errors++;
-	kunmap_atomic(daddr);
 	kunmap_atomic(paddr);
+	kunmap_atomic(daddr);
 	return ret;
 }
 
@@ -2066,6 +2053,11 @@ static void unmap_region(sector_t lba, u
 				       scsi_debug_sector_size *
 				       scsi_debug_unmap_granularity);
 			}
+			if (dif_storep) {
+				memset(dif_storep + lba, 0xff,
+				       sizeof(*dif_storep) *
+				       scsi_debug_unmap_granularity);
+			}
 		}
 		lba = map_index_to_lba(index + 1);
 	}
@@ -3374,7 +3366,7 @@ static int __init scsi_debug_init(void)
 	if (scsi_debug_num_parts > 0)
 		sdebug_build_parts(fake_storep, sz);
 
-	if (scsi_debug_dif) {
+	if (scsi_debug_dix) {
 		int dif_size;
 
 		dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi_devinfo.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_devinfo.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi_devinfo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_devinfo.c	2013-08-25 20:43:22.000000000 -0400
@@ -228,6 +228,7 @@ static struct {
 	{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
 	{"SEAGATE", "ST34555N", "0930", BLIST_NOTQ},	/* Chokes on tagged INQUIRY */
 	{"SEAGATE", "ST3390N", "9546", BLIST_NOTQ},
+	{"SEAGATE", "ST900MM0006", NULL, BLIST_SKIP_VPD_PAGES},
 	{"SGI", "RAID3", "*", BLIST_SPARSELUN},
 	{"SGI", "RAID5", "*", BLIST_SPARSELUN},
 	{"SGI", "TP9100", "*", BLIST_REPORTLUN2},
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi_error.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_error.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi_error.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_error.c	2013-08-25 20:43:22.000000000 -0400
@@ -45,8 +45,6 @@
 
 static void scsi_eh_done(struct scsi_cmnd *scmd);
 
-#define SENSE_TIMEOUT		(10*HZ)
-
 /*
  * These should *probably* be handled by the host itself.
  * Since it is allowed to sleep, it probably should.
@@ -538,7 +536,7 @@ static void scsi_eh_done(struct scsi_cmn
 
 /**
  * scsi_try_host_reset - ask host adapter to reset itself
- * @scmd:	SCSI cmd to send hsot reset.
+ * @scmd:	SCSI cmd to send host reset.
  */
 static int scsi_try_host_reset(struct scsi_cmnd *scmd)
 {
@@ -881,7 +879,7 @@ retry:
  */
 static int scsi_request_sense(struct scsi_cmnd *scmd)
 {
-	return scsi_send_eh_cmnd(scmd, NULL, 0, SENSE_TIMEOUT, ~0);
+	return scsi_send_eh_cmnd(scmd, NULL, 0, scmd->device->eh_timeout, ~0);
 }
 
 /**
@@ -982,7 +980,8 @@ static int scsi_eh_tur(struct scsi_cmnd
 	int retry_cnt = 1, rtn;
 
 retry_tur:
-	rtn = scsi_send_eh_cmnd(scmd, tur_command, 6, SENSE_TIMEOUT, 0);
+	rtn = scsi_send_eh_cmnd(scmd, tur_command, 6,
+				scmd->device->eh_timeout, 0);
 
 	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n",
 		__func__, scmd, rtn));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi_lib.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_lib.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi_lib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_lib.c	2013-08-25 20:43:22.000000000 -0400
@@ -434,6 +434,8 @@ static void scsi_run_queue(struct reques
 	list_splice_init(&shost->starved_list, &starved_list);
 
 	while (!list_empty(&starved_list)) {
+		struct request_queue *slq;
+
 		/*
 		 * As long as shost is accepting commands and we have
 		 * starved queues, call blk_run_queue. scsi_request_fn
@@ -456,11 +458,25 @@ static void scsi_run_queue(struct reques
 			continue;
 		}
 
-		spin_unlock(shost->host_lock);
-		spin_lock(sdev->request_queue->queue_lock);
-		__blk_run_queue(sdev->request_queue);
-		spin_unlock(sdev->request_queue->queue_lock);
-		spin_lock(shost->host_lock);
+		/*
+		 * Once we drop the host lock, a racing scsi_remove_device()
+		 * call may remove the sdev from the starved list and destroy
+		 * it and the queue.  Mitigate by taking a reference to the
+		 * queue and never touching the sdev again after we drop the
+		 * host lock.  Note: if __scsi_remove_device() invokes
+		 * blk_cleanup_queue() before the queue is run from this
+		 * function then blk_run_queue() will return immediately since
+		 * blk_cleanup_queue() marks the queue with QUEUE_FLAG_DYING.
+		 */
+		slq = sdev->request_queue;
+		if (!blk_get_queue(slq))
+			continue;
+		spin_unlock_irqrestore(shost->host_lock, flags);
+
+		blk_run_queue(slq);
+		blk_put_queue(slq);
+
+		spin_lock_irqsave(shost->host_lock, flags);
 	}
 	/* put any unprocessed entries back */
 	list_splice(&starved_list, &shost->starved_list);
@@ -2177,6 +2193,7 @@ scsi_device_set_state(struct scsi_device
 		case SDEV_OFFLINE:
 		case SDEV_TRANSPORT_OFFLINE:
 		case SDEV_CANCEL:
+		case SDEV_CREATED_BLOCK:
 			break;
 		default:
 			goto illegal;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi_pm.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_pm.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi_pm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_pm.c	2013-08-25 20:43:22.000000000 -0400
@@ -229,8 +229,6 @@ static int scsi_runtime_resume(struct de
 
 static int scsi_runtime_idle(struct device *dev)
 {
-	int err;
-
 	dev_dbg(dev, "scsi_runtime_idle\n");
 
 	/* Insert hooks here for targets, hosts, and transport classes */
@@ -240,14 +238,11 @@ static int scsi_runtime_idle(struct devi
 
 		if (sdev->request_queue->dev) {
 			pm_runtime_mark_last_busy(dev);
-			err = pm_runtime_autosuspend(dev);
-		} else {
-			err = pm_runtime_suspend(dev);
+			pm_runtime_autosuspend(dev);
+			return -EBUSY;
 		}
-	} else {
-		err = pm_runtime_suspend(dev);
 	}
-	return err;
+	return 0;
 }
 
 int scsi_autopm_get_device(struct scsi_device *sdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi_scan.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_scan.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi_scan.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_scan.c	2013-08-25 20:43:22.000000000 -0400
@@ -924,6 +924,11 @@ static int scsi_add_lun(struct scsi_devi
 	if (*bflags & BLIST_NO_DIF)
 		sdev->no_dif = 1;
 
+	sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT;
+
+	if (*bflags & BLIST_SKIP_VPD_PAGES)
+		sdev->skip_vpd_pages = 1;
+
 	transport_configure_device(&sdev->sdev_gendev);
 
 	if (sdev->host->hostt->slave_configure) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi_sysfs.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_sysfs.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -560,6 +560,35 @@ sdev_store_timeout (struct device *dev,
 static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout);
 
 static ssize_t
+sdev_show_eh_timeout(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct scsi_device *sdev;
+	sdev = to_scsi_device(dev);
+	return snprintf(buf, 20, "%u\n", sdev->eh_timeout / HZ);
+}
+
+static ssize_t
+sdev_store_eh_timeout(struct device *dev, struct device_attribute *attr,
+		    const char *buf, size_t count)
+{
+	struct scsi_device *sdev;
+	unsigned int eh_timeout;
+	int err;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	sdev = to_scsi_device(dev);
+	err = kstrtouint(buf, 10, &eh_timeout);
+	if (err)
+		return err;
+	sdev->eh_timeout = eh_timeout * HZ;
+
+	return count;
+}
+static DEVICE_ATTR(eh_timeout, S_IRUGO | S_IWUSR, sdev_show_eh_timeout, sdev_store_eh_timeout);
+
+static ssize_t
 store_rescan_field (struct device *dev, struct device_attribute *attr,
 		    const char *buf, size_t count)
 {
@@ -723,6 +752,7 @@ static struct attribute *scsi_sdev_attrs
 	&dev_attr_delete.attr,
 	&dev_attr_state.attr,
 	&dev_attr_timeout.attr,
+	&dev_attr_eh_timeout.attr,
 	&dev_attr_iocounterbits.attr,
 	&dev_attr_iorequest_cnt.attr,
 	&dev_attr_iodone_cnt.attr,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi_transport_fc.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_transport_fc.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi_transport_fc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_transport_fc.c	2013-08-25 20:43:22.000000000 -0400
@@ -435,7 +435,7 @@ static int fc_host_setup(struct transpor
 
 	snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name),
 		 "fc_wq_%d", shost->host_no);
-	fc_host->work_q = alloc_workqueue(fc_host->work_q_name, 0, 0);
+	fc_host->work_q = alloc_workqueue("%s", 0, 0, fc_host->work_q_name);
 	if (!fc_host->work_q)
 		return -ENOMEM;
 
@@ -443,8 +443,8 @@ static int fc_host_setup(struct transpor
 	snprintf(fc_host->devloss_work_q_name,
 		 sizeof(fc_host->devloss_work_q_name),
 		 "fc_dl_%d", shost->host_no);
-	fc_host->devloss_work_q =
-			alloc_workqueue(fc_host->devloss_work_q_name, 0, 0);
+	fc_host->devloss_work_q = alloc_workqueue("%s", 0, 0,
+					fc_host->devloss_work_q_name);
 	if (!fc_host->devloss_work_q) {
 		destroy_workqueue(fc_host->work_q);
 		fc_host->work_q = NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/scsi_transport_iscsi.c linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_transport_iscsi.c
--- linux-libre-3.10-gnu/drivers/scsi/scsi_transport_iscsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/scsi_transport_iscsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -3473,6 +3473,9 @@ iscsi_session_attr(tgt_reset_tmo, ISCSI_
 iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0);
 iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0);
 iscsi_session_attr(targetalias, ISCSI_PARAM_TARGET_ALIAS, 0);
+iscsi_session_attr(boot_root, ISCSI_PARAM_BOOT_ROOT, 0);
+iscsi_session_attr(boot_nic, ISCSI_PARAM_BOOT_NIC, 0);
+iscsi_session_attr(boot_target, ISCSI_PARAM_BOOT_TARGET, 0);
 
 static ssize_t
 show_priv_session_state(struct device *dev, struct device_attribute *attr,
@@ -3568,6 +3571,9 @@ static struct attribute *iscsi_session_a
 	&dev_attr_sess_ifacename.attr,
 	&dev_attr_sess_initiatorname.attr,
 	&dev_attr_sess_targetalias.attr,
+	&dev_attr_sess_boot_root.attr,
+	&dev_attr_sess_boot_nic.attr,
+	&dev_attr_sess_boot_target.attr,
 	&dev_attr_priv_sess_recovery_tmo.attr,
 	&dev_attr_priv_sess_state.attr,
 	&dev_attr_priv_sess_creator.attr,
@@ -3631,6 +3637,12 @@ static umode_t iscsi_session_attr_is_vis
 		param = ISCSI_PARAM_INITIATOR_NAME;
 	else if (attr == &dev_attr_sess_targetalias.attr)
 		param = ISCSI_PARAM_TARGET_ALIAS;
+	else if (attr == &dev_attr_sess_boot_root.attr)
+		param = ISCSI_PARAM_BOOT_ROOT;
+	else if (attr == &dev_attr_sess_boot_nic.attr)
+		param = ISCSI_PARAM_BOOT_NIC;
+	else if (attr == &dev_attr_sess_boot_target.attr)
+		param = ISCSI_PARAM_BOOT_TARGET;
 	else if (attr == &dev_attr_priv_sess_recovery_tmo.attr)
 		return S_IRUGO | S_IWUSR;
 	else if (attr == &dev_attr_priv_sess_state.attr)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/sd.c linux-libre-3.11-rc7-gnu/drivers/scsi/sd.c
--- linux-libre-3.10-gnu/drivers/scsi/sd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/sd.c	2013-08-25 20:43:22.000000000 -0400
@@ -142,7 +142,7 @@ sd_store_cache_type(struct device *dev,
 	char *buffer_data;
 	struct scsi_mode_data data;
 	struct scsi_sense_hdr sshdr;
-	const char *temp = "temporary ";
+	static const char temp[] = "temporary ";
 	int len;
 
 	if (sdp->type != TYPE_DISK)
@@ -442,8 +442,10 @@ sd_store_write_same_blocks(struct device
 
 	if (max == 0)
 		sdp->no_write_same = 1;
-	else if (max <= SD_MAX_WS16_BLOCKS)
+	else if (max <= SD_MAX_WS16_BLOCKS) {
+		sdp->no_write_same = 0;
 		sdkp->max_ws_blocks = max;
+	}
 
 	sd_config_write_same(sdkp);
 
@@ -504,6 +506,16 @@ static struct scsi_driver sd_template =
 };
 
 /*
+ * Dummy kobj_map->probe function.
+ * The default ->probe function will call modprobe, which is
+ * pointless as this module is already loaded.
+ */
+static struct kobject *sd_default_probe(dev_t devt, int *partno, void *data)
+{
+	return NULL;
+}
+
+/*
  * Device no to disk mapping:
  * 
  *       major         disc2     disc  p1
@@ -740,7 +752,6 @@ static void sd_config_write_same(struct
 {
 	struct request_queue *q = sdkp->disk->queue;
 	unsigned int logical_block_size = sdkp->device->sector_size;
-	unsigned int blocks = 0;
 
 	if (sdkp->device->no_write_same) {
 		sdkp->max_ws_blocks = 0;
@@ -752,18 +763,20 @@ static void sd_config_write_same(struct
 	 * blocks per I/O unless the device explicitly advertises a
 	 * bigger limit.
 	 */
-	if (sdkp->max_ws_blocks == 0)
-		sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS;
-
-	if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS)
-		blocks = min_not_zero(sdkp->max_ws_blocks,
-				      (u32)SD_MAX_WS16_BLOCKS);
-	else
-		blocks = min_not_zero(sdkp->max_ws_blocks,
-				      (u32)SD_MAX_WS10_BLOCKS);
+	if (sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS)
+		sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks,
+						   (u32)SD_MAX_WS16_BLOCKS);
+	else if (sdkp->ws16 || sdkp->ws10 || sdkp->device->no_report_opcodes)
+		sdkp->max_ws_blocks = min_not_zero(sdkp->max_ws_blocks,
+						   (u32)SD_MAX_WS10_BLOCKS);
+	else {
+		sdkp->device->no_write_same = 1;
+		sdkp->max_ws_blocks = 0;
+	}
 
 out:
-	blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9));
+	blk_queue_max_write_same_sectors(q, sdkp->max_ws_blocks *
+					 (logical_block_size >> 9));
 }
 
 /**
@@ -825,10 +838,17 @@ static int scsi_setup_flush_cmnd(struct
 
 static void sd_unprep_fn(struct request_queue *q, struct request *rq)
 {
+	struct scsi_cmnd *SCpnt = rq->special;
+
 	if (rq->cmd_flags & REQ_DISCARD) {
 		free_page((unsigned long)rq->buffer);
 		rq->buffer = NULL;
 	}
+	if (SCpnt->cmnd != rq->cmd) {
+		mempool_free(SCpnt->cmnd, sd_cdb_pool);
+		SCpnt->cmnd = NULL;
+		SCpnt->cmd_len = 0;
+	}
 }
 
 /**
@@ -1707,21 +1727,6 @@ static int sd_done(struct scsi_cmnd *SCp
 	if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt))
 		sd_dif_complete(SCpnt, good_bytes);
 
-	if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type)
-	    == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) {
-
-		/* We have to print a failed command here as the
-		 * extended CDB gets freed before scsi_io_completion()
-		 * is called.
-		 */
-		if (result)
-			scsi_print_command(SCpnt);
-
-		mempool_free(SCpnt->cmnd, sd_cdb_pool);
-		SCpnt->cmnd = NULL;
-		SCpnt->cmd_len = 0;
-	}
-
 	return good_bytes;
 }
 
@@ -2635,9 +2640,24 @@ static void sd_read_block_provisioning(s
 
 static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
 {
-	if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE,
-			       WRITE_SAME_16))
+	struct scsi_device *sdev = sdkp->device;
+
+	if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY) < 0) {
+		sdev->no_report_opcodes = 1;
+
+		/* Disable WRITE SAME if REPORT SUPPORTED OPERATION
+		 * CODES is unsupported and the device has an ATA
+		 * Information VPD page (SAT).
+		 */
+		if (!scsi_get_vpd_page(sdev, 0x89, buffer, SD_BUF_SIZE))
+			sdev->no_write_same = 1;
+	}
+
+	if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME_16) == 1)
 		sdkp->ws16 = 1;
+
+	if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME) == 1)
+		sdkp->ws10 = 1;
 }
 
 static int sd_try_extended_inquiry(struct scsi_device *sdp)
@@ -2931,7 +2951,7 @@ static int sd_probe(struct device *dev)
 	device_initialize(&sdkp->dev);
 	sdkp->dev.parent = dev;
 	sdkp->dev.class = &sd_disk_class;
-	dev_set_name(&sdkp->dev, dev_name(dev));
+	dev_set_name(&sdkp->dev, "%s", dev_name(dev));
 
 	if (device_add(&sdkp->dev))
 		goto out_free_index;
@@ -2970,8 +2990,10 @@ static int sd_probe(struct device *dev)
 static int sd_remove(struct device *dev)
 {
 	struct scsi_disk *sdkp;
+	dev_t devt;
 
 	sdkp = dev_get_drvdata(dev);
+	devt = disk_devt(sdkp->disk);
 	scsi_autopm_get_device(sdkp->device);
 
 	async_synchronize_full_domain(&scsi_sd_probe_domain);
@@ -2981,6 +3003,9 @@ static int sd_remove(struct device *dev)
 	del_gendisk(sdkp->disk);
 	sd_shutdown(dev);
 
+	blk_register_region(devt, SD_MINORS, NULL,
+			    sd_default_probe, NULL, NULL);
+
 	mutex_lock(&sd_ref_mutex);
 	dev_set_drvdata(dev, NULL);
 	put_device(&sdkp->dev);
@@ -3124,9 +3149,13 @@ static int __init init_sd(void)
 
 	SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
 
-	for (i = 0; i < SD_MAJORS; i++)
-		if (register_blkdev(sd_major(i), "sd") == 0)
-			majors++;
+	for (i = 0; i < SD_MAJORS; i++) {
+		if (register_blkdev(sd_major(i), "sd") != 0)
+			continue;
+		majors++;
+		blk_register_region(sd_major(i), SD_MINORS, NULL,
+				    sd_default_probe, NULL, NULL);
+	}
 
 	if (!majors)
 		return -ENODEV;
@@ -3185,8 +3214,10 @@ static void __exit exit_sd(void)
 
 	class_unregister(&sd_disk_class);
 
-	for (i = 0; i < SD_MAJORS; i++)
+	for (i = 0; i < SD_MAJORS; i++) {
+		blk_unregister_region(sd_major(i), SD_MINORS);
 		unregister_blkdev(sd_major(i), "sd");
+	}
 }
 
 module_init(init_sd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/sd.h linux-libre-3.11-rc7-gnu/drivers/scsi/sd.h
--- linux-libre-3.10-gnu/drivers/scsi/sd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/sd.h	2013-08-25 20:43:22.000000000 -0400
@@ -84,6 +84,7 @@ struct scsi_disk {
 	unsigned	lbpws : 1;
 	unsigned	lbpws10 : 1;
 	unsigned	lbpvpd : 1;
+	unsigned	ws10 : 1;
 	unsigned	ws16 : 1;
 };
 #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/storvsc_drv.c linux-libre-3.11-rc7-gnu/drivers/scsi/storvsc_drv.c
--- linux-libre-3.10-gnu/drivers/scsi/storvsc_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/storvsc_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -55,10 +55,15 @@
  * V1 RC < 2008/1/31: 1.0
  * V1 RC > 2008/1/31:  2.0
  * Win7: 4.2
+ * Win8: 5.1
  */
 
-#define VMSTOR_CURRENT_MAJOR  4
-#define VMSTOR_CURRENT_MINOR  2
+
+#define VMSTOR_WIN7_MAJOR 4
+#define VMSTOR_WIN7_MINOR 2
+
+#define VMSTOR_WIN8_MAJOR 5
+#define VMSTOR_WIN8_MINOR 1
 
 
 /*  Packet structure describing virtual storage requests. */
@@ -74,18 +79,103 @@ enum vstor_packet_operation {
 	VSTOR_OPERATION_QUERY_PROTOCOL_VERSION	= 9,
 	VSTOR_OPERATION_QUERY_PROPERTIES	= 10,
 	VSTOR_OPERATION_ENUMERATE_BUS		= 11,
-	VSTOR_OPERATION_MAXIMUM			= 11
+	VSTOR_OPERATION_FCHBA_DATA              = 12,
+	VSTOR_OPERATION_CREATE_SUB_CHANNELS     = 13,
+	VSTOR_OPERATION_MAXIMUM                 = 13
+};
+
+/*
+ * WWN packet for Fibre Channel HBA
+ */
+
+struct hv_fc_wwn_packet {
+	bool	primary_active;
+	u8	reserved1;
+	u8	reserved2;
+	u8	primary_port_wwn[8];
+	u8	primary_node_wwn[8];
+	u8	secondary_port_wwn[8];
+	u8	secondary_node_wwn[8];
 };
 
+
+
+/*
+ * SRB Flag Bits
+ */
+
+#define SRB_FLAGS_QUEUE_ACTION_ENABLE		0x00000002
+#define SRB_FLAGS_DISABLE_DISCONNECT		0x00000004
+#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER	0x00000008
+#define SRB_FLAGS_BYPASS_FROZEN_QUEUE		0x00000010
+#define SRB_FLAGS_DISABLE_AUTOSENSE		0x00000020
+#define SRB_FLAGS_DATA_IN			0x00000040
+#define SRB_FLAGS_DATA_OUT			0x00000080
+#define SRB_FLAGS_NO_DATA_TRANSFER		0x00000000
+#define SRB_FLAGS_UNSPECIFIED_DIRECTION	(SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)
+#define SRB_FLAGS_NO_QUEUE_FREEZE		0x00000100
+#define SRB_FLAGS_ADAPTER_CACHE_ENABLE		0x00000200
+#define SRB_FLAGS_FREE_SENSE_BUFFER		0x00000400
+
+/*
+ * This flag indicates the request is part of the workflow for processing a D3.
+ */
+#define SRB_FLAGS_D3_PROCESSING			0x00000800
+#define SRB_FLAGS_IS_ACTIVE			0x00010000
+#define SRB_FLAGS_ALLOCATED_FROM_ZONE		0x00020000
+#define SRB_FLAGS_SGLIST_FROM_POOL		0x00040000
+#define SRB_FLAGS_BYPASS_LOCKED_QUEUE		0x00080000
+#define SRB_FLAGS_NO_KEEP_AWAKE			0x00100000
+#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE	0x00200000
+#define SRB_FLAGS_PORT_DRIVER_SENSEHASPORT	0x00400000
+#define SRB_FLAGS_DONT_START_NEXT_PACKET	0x00800000
+#define SRB_FLAGS_PORT_DRIVER_RESERVED		0x0F000000
+#define SRB_FLAGS_CLASS_DRIVER_RESERVED		0xF0000000
+
+
 /*
  * Platform neutral description of a scsi request -
  * this remains the same across the write regardless of 32/64 bit
  * note: it's patterned off the SCSI_PASS_THROUGH structure
  */
 #define STORVSC_MAX_CMD_LEN			0x10
-#define STORVSC_SENSE_BUFFER_SIZE		0x12
+
+#define POST_WIN7_STORVSC_SENSE_BUFFER_SIZE	0x14
+#define PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE	0x12
+
+#define STORVSC_SENSE_BUFFER_SIZE		0x14
 #define STORVSC_MAX_BUF_LEN_WITH_PADDING	0x14
 
+/*
+ * Sense buffer size changed in win8; have a run-time
+ * variable to track the size we should use.
+ */
+static int sense_buffer_size;
+
+/*
+ * The size of the vmscsi_request has changed in win8. The
+ * additional size is because of new elements added to the
+ * structure. These elements are valid only when we are talking
+ * to a win8 host.
+ * Track the correction to size we need to apply.
+ */
+
+static int vmscsi_size_delta;
+static int vmstor_current_major;
+static int vmstor_current_minor;
+
+struct vmscsi_win8_extension {
+	/*
+	 * The following were added in Windows 8
+	 */
+	u16 reserve;
+	u8  queue_tag;
+	u8  queue_action;
+	u32 srb_flags;
+	u32 time_out_value;
+	u32 queue_sort_ey;
+} __packed;
+
 struct vmscsi_request {
 	u16 length;
 	u8 srb_status;
@@ -108,6 +198,11 @@ struct vmscsi_request {
 		u8 sense_data[STORVSC_SENSE_BUFFER_SIZE];
 		u8 reserved_array[STORVSC_MAX_BUF_LEN_WITH_PADDING];
 	};
+	/*
+	 * The following was added in win8.
+	 */
+	struct vmscsi_win8_extension win8_extension;
+
 } __attribute((packed));
 
 
@@ -115,22 +210,18 @@ struct vmscsi_request {
  * This structure is sent during the intialization phase to get the different
  * properties of the channel.
  */
+
+#define STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL		0x1
+
 struct vmstorage_channel_properties {
-	u16 protocol_version;
-	u8  path_id;
-	u8 target_id;
+	u32 reserved;
+	u16 max_channel_cnt;
+	u16 reserved1;
 
-	/* Note: port number is only really known on the client side */
-	u32  port_number;
-	u32  flags;
+	u32 flags;
 	u32   max_transfer_bytes;
 
-	/*
-	 * This id is unique for each channel and will correspond with
-	 * vendor specific data in the inquiry data.
-	 */
-
-	u64  unique_id;
+	u64  reserved2;
 } __packed;
 
 /*  This structure is sent during the storage protocol negotiations. */
@@ -175,6 +266,15 @@ struct vstor_packet {
 
 		/* Used during version negotiations. */
 		struct vmstorage_protocol_version version;
+
+		/* Fibre channel address packet */
+		struct hv_fc_wwn_packet wwn_packet;
+
+		/* Number of sub-channels to create */
+		u16 sub_channel_count;
+
+		/* This will be the maximum of the union members */
+		u8  buffer[0x34];
 	};
 } __packed;
 
@@ -221,7 +321,14 @@ static int storvsc_ringbuffer_size = (20
 module_param(storvsc_ringbuffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
 
-#define STORVSC_MAX_IO_REQUESTS				128
+/*
+ * Timeout in seconds for all devices managed by this driver.
+ */
+static int storvsc_timeout = 180;
+
+#define STORVSC_MAX_IO_REQUESTS				200
+
+static void storvsc_on_channel_callback(void *context);
 
 /*
  * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
@@ -259,6 +366,7 @@ struct storvsc_device {
 
 	bool	 destroy;
 	bool	 drain_notify;
+	bool	 open_sub_channel;
 	atomic_t num_outstanding_req;
 	struct Scsi_Host *host;
 
@@ -650,12 +758,104 @@ static unsigned int copy_to_bounce_buffe
 	return total_copied;
 }
 
+static void handle_sc_creation(struct vmbus_channel *new_sc)
+{
+	struct hv_device *device = new_sc->primary_channel->device_obj;
+	struct storvsc_device *stor_device;
+	struct vmstorage_channel_properties props;
+
+	stor_device = get_out_stor_device(device);
+	if (!stor_device)
+		return;
+
+	if (stor_device->open_sub_channel == false)
+		return;
+
+	memset(&props, 0, sizeof(struct vmstorage_channel_properties));
+
+	vmbus_open(new_sc,
+		   storvsc_ringbuffer_size,
+		   storvsc_ringbuffer_size,
+		   (void *)&props,
+		   sizeof(struct vmstorage_channel_properties),
+		   storvsc_on_channel_callback, new_sc);
+}
+
+static void  handle_multichannel_storage(struct hv_device *device, int max_chns)
+{
+	struct storvsc_device *stor_device;
+	int num_cpus = num_online_cpus();
+	int num_sc;
+	struct storvsc_cmd_request *request;
+	struct vstor_packet *vstor_packet;
+	int ret, t;
+
+	num_sc = ((max_chns > num_cpus) ? num_cpus : max_chns);
+	stor_device = get_out_stor_device(device);
+	if (!stor_device)
+		return;
+
+	request = &stor_device->init_request;
+	vstor_packet = &request->vstor_packet;
+
+	stor_device->open_sub_channel = true;
+	/*
+	 * Establish a handler for dealing with subchannels.
+	 */
+	vmbus_set_sc_create_callback(device->channel, handle_sc_creation);
+
+	/*
+	 * Check to see if sub-channels have already been created. This
+	 * can happen when this driver is re-loaded after unloading.
+	 */
+
+	if (vmbus_are_subchannels_present(device->channel))
+		return;
+
+	stor_device->open_sub_channel = false;
+	/*
+	 * Request the host to create sub-channels.
+	 */
+	memset(request, 0, sizeof(struct storvsc_cmd_request));
+	init_completion(&request->wait_event);
+	vstor_packet->operation = VSTOR_OPERATION_CREATE_SUB_CHANNELS;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+	vstor_packet->sub_channel_count = num_sc;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       (sizeof(struct vstor_packet) -
+			       vmscsi_size_delta),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	if (ret != 0)
+		return;
+
+	t = wait_for_completion_timeout(&request->wait_event, 10*HZ);
+	if (t == 0)
+		return;
+
+	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+	    vstor_packet->status != 0)
+		return;
+
+	/*
+	 * Now that we created the sub-channels, invoke the check; this
+	 * may trigger the callback.
+	 */
+	stor_device->open_sub_channel = true;
+	vmbus_are_subchannels_present(device->channel);
+}
+
 static int storvsc_channel_init(struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
 	struct storvsc_cmd_request *request;
 	struct vstor_packet *vstor_packet;
 	int ret, t;
+	int max_chns;
+	bool process_sub_channels = false;
 
 	stor_device = get_out_stor_device(device);
 	if (!stor_device)
@@ -674,7 +874,8 @@ static int storvsc_channel_init(struct h
 	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
+			       (sizeof(struct vstor_packet) -
+			       vmscsi_size_delta),
 			       (unsigned long)request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -698,7 +899,7 @@ static int storvsc_channel_init(struct h
 	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
 	vstor_packet->version.major_minor =
-		storvsc_get_version(VMSTOR_CURRENT_MAJOR, VMSTOR_CURRENT_MINOR);
+		storvsc_get_version(vmstor_current_major, vmstor_current_minor);
 
 	/*
 	 * The revision number is only used in Windows; set it to 0.
@@ -706,7 +907,8 @@ static int storvsc_channel_init(struct h
 	vstor_packet->version.revision = 0;
 
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
+			       (sizeof(struct vstor_packet) -
+				vmscsi_size_delta),
 			       (unsigned long)request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -727,11 +929,10 @@ static int storvsc_channel_init(struct h
 	memset(vstor_packet, 0, sizeof(struct vstor_packet));
 	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
 	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-	vstor_packet->storage_channel_properties.port_number =
-					stor_device->port_number;
 
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
+			       (sizeof(struct vstor_packet) -
+				vmscsi_size_delta),
 			       (unsigned long)request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -749,16 +950,26 @@ static int storvsc_channel_init(struct h
 	    vstor_packet->status != 0)
 		goto cleanup;
 
-	stor_device->path_id = vstor_packet->storage_channel_properties.path_id;
-	stor_device->target_id
-		= vstor_packet->storage_channel_properties.target_id;
+	/*
+	 * Check to see if multi-channel support is there.
+	 * Hosts that implement protocol version of 5.1 and above
+	 * support multi-channel.
+	 */
+	max_chns = vstor_packet->storage_channel_properties.max_channel_cnt;
+	if ((vmbus_proto_version != VERSION_WIN7) &&
+	   (vmbus_proto_version != VERSION_WS2008))  {
+		if (vstor_packet->storage_channel_properties.flags &
+		    STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
+			process_sub_channels = true;
+	}
 
 	memset(vstor_packet, 0, sizeof(struct vstor_packet));
 	vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
 	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
+			       (sizeof(struct vstor_packet) -
+				vmscsi_size_delta),
 			       (unsigned long)request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -776,6 +987,9 @@ static int storvsc_channel_init(struct h
 	    vstor_packet->status != 0)
 		goto cleanup;
 
+	if (process_sub_channels)
+		handle_multichannel_storage(device, max_chns);
+
 
 cleanup:
 	return ret;
@@ -997,7 +1211,8 @@ static void storvsc_on_receive(struct hv
 
 static void storvsc_on_channel_callback(void *context)
 {
-	struct hv_device *device = (struct hv_device *)context;
+	struct vmbus_channel *channel = (struct vmbus_channel *)context;
+	struct hv_device *device;
 	struct storvsc_device *stor_device;
 	u32 bytes_recvd;
 	u64 request_id;
@@ -1005,14 +1220,19 @@ static void storvsc_on_channel_callback(
 	struct storvsc_cmd_request *request;
 	int ret;
 
+	if (channel->primary_channel != NULL)
+		device = channel->primary_channel->device_obj;
+	else
+		device = channel->device_obj;
 
 	stor_device = get_in_stor_device(device);
 	if (!stor_device)
 		return;
 
 	do {
-		ret = vmbus_recvpacket(device->channel, packet,
-				       ALIGN(sizeof(struct vstor_packet), 8),
+		ret = vmbus_recvpacket(channel, packet,
+				       ALIGN((sizeof(struct vstor_packet) -
+					     vmscsi_size_delta), 8),
 				       &bytes_recvd, &request_id);
 		if (ret == 0 && bytes_recvd > 0) {
 
@@ -1023,7 +1243,8 @@ static void storvsc_on_channel_callback(
 			    (request == &stor_device->reset_request)) {
 
 				memcpy(&request->vstor_packet, packet,
-				       sizeof(struct vstor_packet));
+				       (sizeof(struct vstor_packet) -
+					vmscsi_size_delta));
 				complete(&request->wait_event);
 			} else {
 				storvsc_on_receive(device,
@@ -1050,7 +1271,7 @@ static int storvsc_connect_to_vsp(struct
 			 ring_size,
 			 (void *)&props,
 			 sizeof(struct vmstorage_channel_properties),
-			 storvsc_on_channel_callback, device);
+			 storvsc_on_channel_callback, device->channel);
 
 	if (ret != 0)
 		return ret;
@@ -1102,6 +1323,7 @@ static int storvsc_do_io(struct hv_devic
 {
 	struct storvsc_device *stor_device;
 	struct vstor_packet *vstor_packet;
+	struct vmbus_channel *outgoing_channel;
 	int ret = 0;
 
 	vstor_packet = &request->vstor_packet;
@@ -1112,14 +1334,20 @@ static int storvsc_do_io(struct hv_devic
 
 
 	request->device  = device;
+	/*
+	 * Select an an appropriate channel to send the request out.
+	 */
+
+	outgoing_channel = vmbus_get_outgoing_channel(device->channel);
 
 
 	vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
 
-	vstor_packet->vm_srb.length = sizeof(struct vmscsi_request);
+	vstor_packet->vm_srb.length = (sizeof(struct vmscsi_request) -
+					vmscsi_size_delta);
 
 
-	vstor_packet->vm_srb.sense_info_length = STORVSC_SENSE_BUFFER_SIZE;
+	vstor_packet->vm_srb.sense_info_length = sense_buffer_size;
 
 
 	vstor_packet->vm_srb.data_transfer_length =
@@ -1128,14 +1356,16 @@ static int storvsc_do_io(struct hv_devic
 	vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
 
 	if (request->data_buffer.len) {
-		ret = vmbus_sendpacket_multipagebuffer(device->channel,
+		ret = vmbus_sendpacket_multipagebuffer(outgoing_channel,
 				&request->data_buffer,
 				vstor_packet,
-				sizeof(struct vstor_packet),
+				(sizeof(struct vstor_packet) -
+				vmscsi_size_delta),
 				(unsigned long)request);
 	} else {
 		ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
+			       (sizeof(struct vstor_packet) -
+				vmscsi_size_delta),
 			       (unsigned long)request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -1204,6 +1434,8 @@ static int storvsc_device_configure(stru
 
 	blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
 
+	blk_queue_rq_timeout(sdevice->request_queue, (storvsc_timeout * HZ));
+
 	sdevice->no_write_same = 1;
 
 	return 0;
@@ -1257,7 +1489,8 @@ static int storvsc_host_reset_handler(st
 	vstor_packet->vm_srb.path_id = stor_device->path_id;
 
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
+			       (sizeof(struct vstor_packet) -
+				vmscsi_size_delta),
 			       (unsigned long)&stor_device->reset_request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
@@ -1342,18 +1575,28 @@ static int storvsc_queuecommand(struct S
 	scmnd->host_scribble = (unsigned char *)cmd_request;
 
 	vm_srb = &cmd_request->vstor_packet.vm_srb;
+	vm_srb->win8_extension.time_out_value = 60;
 
 
 	/* Build the SRB */
 	switch (scmnd->sc_data_direction) {
 	case DMA_TO_DEVICE:
 		vm_srb->data_in = WRITE_TYPE;
+		vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_OUT;
+		vm_srb->win8_extension.srb_flags |=
+			(SRB_FLAGS_QUEUE_ACTION_ENABLE |
+			SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
 		break;
 	case DMA_FROM_DEVICE:
 		vm_srb->data_in = READ_TYPE;
+		vm_srb->win8_extension.srb_flags |= SRB_FLAGS_DATA_IN;
+		vm_srb->win8_extension.srb_flags |=
+			(SRB_FLAGS_QUEUE_ACTION_ENABLE |
+			SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
 		break;
 	default:
 		vm_srb->data_in = UNKNOWN_TYPE;
+		vm_srb->win8_extension.srb_flags = 0;
 		break;
 	}
 
@@ -1459,6 +1702,7 @@ static struct scsi_host_template scsi_dr
 enum {
 	SCSI_GUID,
 	IDE_GUID,
+	SFC_GUID,
 };
 
 static const struct hv_vmbus_device_id id_table[] = {
@@ -1470,6 +1714,11 @@ static const struct hv_vmbus_device_id i
 	{ HV_IDE_GUID,
 	  .driver_data = IDE_GUID
 	},
+	/* Fibre Channel GUID */
+	{
+	  HV_SYNTHFC_GUID,
+	  .driver_data = SFC_GUID
+	},
 	{ },
 };
 
@@ -1485,6 +1734,24 @@ static int storvsc_probe(struct hv_devic
 	int target = 0;
 	struct storvsc_device *stor_device;
 
+	/*
+	 * Based on the windows host we are running on,
+	 * set state to properly communicate with the host.
+	 */
+
+	if (vmbus_proto_version == VERSION_WIN8) {
+		sense_buffer_size = POST_WIN7_STORVSC_SENSE_BUFFER_SIZE;
+		vmscsi_size_delta = 0;
+		vmstor_current_major = VMSTOR_WIN8_MAJOR;
+		vmstor_current_minor = VMSTOR_WIN8_MINOR;
+	} else {
+		sense_buffer_size = PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE;
+		vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
+		vmstor_current_major = VMSTOR_WIN7_MAJOR;
+		vmstor_current_minor = VMSTOR_WIN7_MINOR;
+	}
+
+
 	host = scsi_host_alloc(&scsi_driver,
 			       sizeof(struct hv_host_device));
 	if (!host)
@@ -1504,6 +1771,7 @@ static int storvsc_probe(struct hv_devic
 	}
 
 	stor_device->destroy = false;
+	stor_device->open_sub_channel = false;
 	init_waitqueue_head(&stor_device->waiting_to_drain);
 	stor_device->device = device;
 	stor_device->host = host;
@@ -1594,7 +1862,8 @@ static int __init storvsc_drv_init(void)
 	max_outstanding_req_per_channel =
 		((storvsc_ringbuffer_size - PAGE_SIZE) /
 		ALIGN(MAX_MULTIPAGE_BUFFER_PACKET +
-		sizeof(struct vstor_packet) + sizeof(u64),
+		sizeof(struct vstor_packet) + sizeof(u64) -
+		vmscsi_size_delta,
 		sizeof(u64)));
 
 	if (max_outstanding_req_per_channel <
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/ufs/Kconfig linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/Kconfig
--- linux-libre-3.10-gnu/drivers/scsi/ufs/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -34,7 +34,7 @@
 
 config SCSI_UFSHCD
 	tristate "Universal Flash Storage Controller Driver Core"
-	depends on SCSI
+	depends on SCSI && SCSI_DMA
 	---help---
 	This selects the support for UFS devices in Linux, say Y and make
 	  sure that you know the name of your UFS host adapter (the card
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/ufs/ufshcd.c linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshcd.c
--- linux-libre-3.10-gnu/drivers/scsi/ufs/ufshcd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshcd.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,8 +33,16 @@
  * this program.
  */
 
+#include <linux/async.h>
+
 #include "ufshcd.h"
 
+#define UFSHCD_ENABLE_INTRS	(UTP_TRANSFER_REQ_COMPL |\
+				 UTP_TASK_REQ_COMPL |\
+				 UFSHCD_ERROR_MASK)
+/* UIC command timeout, unit: ms */
+#define UIC_CMD_TIMEOUT	500
+
 enum {
 	UFSHCD_MAX_CHANNEL	= 0,
 	UFSHCD_MAX_ID		= 1,
@@ -64,6 +72,20 @@ enum {
 };
 
 /**
+ * ufshcd_get_intr_mask - Get the interrupt bit mask
+ * @hba - Pointer to adapter instance
+ *
+ * Returns interrupt bit mask per version
+ */
+static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba)
+{
+	if (hba->ufs_version == UFSHCI_VERSION_10)
+		return INTERRUPT_MASK_ALL_VER_10;
+	else
+		return INTERRUPT_MASK_ALL_VER_11;
+}
+
+/**
  * ufshcd_get_ufs_version - Get the UFS version supported by the HBA
  * @hba - Pointer to adapter instance
  *
@@ -71,7 +93,7 @@ enum {
  */
 static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba)
 {
-	return readl(hba->mmio_base + REG_UFS_VERSION);
+	return ufshcd_readl(hba, REG_UFS_VERSION);
 }
 
 /**
@@ -130,8 +152,7 @@ static inline int ufshcd_get_tm_free_slo
  */
 static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
 {
-	writel(~(1 << pos),
-		(hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_CLEAR));
+	ufshcd_writel(hba, ~(1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
 }
 
 /**
@@ -165,43 +186,11 @@ static inline int ufshcd_get_lists_statu
  */
 static inline int ufshcd_get_uic_cmd_result(struct ufs_hba *hba)
 {
-	return readl(hba->mmio_base + REG_UIC_COMMAND_ARG_2) &
+	return ufshcd_readl(hba, REG_UIC_COMMAND_ARG_2) &
 	       MASK_UIC_COMMAND_RESULT;
 }
 
 /**
- * ufshcd_free_hba_memory - Free allocated memory for LRB, request
- *			    and task lists
- * @hba: Pointer to adapter instance
- */
-static inline void ufshcd_free_hba_memory(struct ufs_hba *hba)
-{
-	size_t utmrdl_size, utrdl_size, ucdl_size;
-
-	kfree(hba->lrb);
-
-	if (hba->utmrdl_base_addr) {
-		utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs;
-		dma_free_coherent(hba->dev, utmrdl_size,
-				  hba->utmrdl_base_addr, hba->utmrdl_dma_addr);
-	}
-
-	if (hba->utrdl_base_addr) {
-		utrdl_size =
-		(sizeof(struct utp_transfer_req_desc) * hba->nutrs);
-		dma_free_coherent(hba->dev, utrdl_size,
-				  hba->utrdl_base_addr, hba->utrdl_dma_addr);
-	}
-
-	if (hba->ucdl_base_addr) {
-		ucdl_size =
-		(sizeof(struct utp_transfer_cmd_desc) * hba->nutrs);
-		dma_free_coherent(hba->dev, ucdl_size,
-				  hba->ucdl_base_addr, hba->ucdl_dma_addr);
-	}
-}
-
-/**
  * ufshcd_is_valid_req_rsp - checks if controller TR response is valid
  * @ucd_rsp_ptr: pointer to response UPIU
  *
@@ -243,18 +232,15 @@ ufshcd_config_int_aggr(struct ufs_hba *h
 {
 	switch (option) {
 	case INT_AGGR_RESET:
-		writel((INT_AGGR_ENABLE |
-			INT_AGGR_COUNTER_AND_TIMER_RESET),
-			(hba->mmio_base +
-			 REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL));
+		ufshcd_writel(hba, INT_AGGR_ENABLE |
+			      INT_AGGR_COUNTER_AND_TIMER_RESET,
+			      REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
 		break;
 	case INT_AGGR_CONFIG:
-		writel((INT_AGGR_ENABLE |
-			INT_AGGR_PARAM_WRITE |
-			INT_AGGR_COUNTER_THRESHOLD_VALUE |
-			INT_AGGR_TIMEOUT_VALUE),
-			(hba->mmio_base +
-			 REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL));
+		ufshcd_writel(hba, INT_AGGR_ENABLE | INT_AGGR_PARAM_WRITE |
+			      INT_AGGR_COUNTER_THRESHOLD_VALUE |
+			      INT_AGGR_TIMEOUT_VALUE,
+			      REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
 		break;
 	}
 }
@@ -267,12 +253,10 @@ ufshcd_config_int_aggr(struct ufs_hba *h
  */
 static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba)
 {
-	writel(UTP_TASK_REQ_LIST_RUN_STOP_BIT,
-	       (hba->mmio_base +
-		REG_UTP_TASK_REQ_LIST_RUN_STOP));
-	writel(UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT,
-	       (hba->mmio_base +
-		REG_UTP_TRANSFER_REQ_LIST_RUN_STOP));
+	ufshcd_writel(hba, UTP_TASK_REQ_LIST_RUN_STOP_BIT,
+		      REG_UTP_TASK_REQ_LIST_RUN_STOP);
+	ufshcd_writel(hba, UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT,
+		      REG_UTP_TRANSFER_REQ_LIST_RUN_STOP);
 }
 
 /**
@@ -281,7 +265,7 @@ static void ufshcd_enable_run_stop_reg(s
  */
 static inline void ufshcd_hba_start(struct ufs_hba *hba)
 {
-	writel(CONTROLLER_ENABLE , (hba->mmio_base + REG_CONTROLLER_ENABLE));
+	ufshcd_writel(hba, CONTROLLER_ENABLE, REG_CONTROLLER_ENABLE);
 }
 
 /**
@@ -292,7 +276,7 @@ static inline void ufshcd_hba_start(stru
  */
 static inline int ufshcd_is_hba_active(struct ufs_hba *hba)
 {
-	return (readl(hba->mmio_base + REG_CONTROLLER_ENABLE) & 0x1) ? 0 : 1;
+	return (ufshcd_readl(hba, REG_CONTROLLER_ENABLE) & 0x1) ? 0 : 1;
 }
 
 /**
@@ -304,8 +288,7 @@ static inline
 void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
 {
 	__set_bit(task_tag, &hba->outstanding_reqs);
-	writel((1 << task_tag),
-	       (hba->mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL));
+	ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL);
 }
 
 /**
@@ -329,8 +312,7 @@ static inline void ufshcd_copy_sense_dat
  */
 static inline void ufshcd_hba_capabilities(struct ufs_hba *hba)
 {
-	hba->capabilities =
-		readl(hba->mmio_base + REG_CONTROLLER_CAPABILITIES);
+	hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES);
 
 	/* nutrs and nutmrs are 0 based values */
 	hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1;
@@ -339,24 +321,119 @@ static inline void ufshcd_hba_capabiliti
 }
 
 /**
- * ufshcd_send_uic_command - Send UIC commands to unipro layers
+ * ufshcd_ready_for_uic_cmd - Check if controller is ready
+ *                            to accept UIC commands
  * @hba: per adapter instance
- * @uic_command: UIC command
+ * Return true on success, else false
+ */
+static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba)
+{
+	if (ufshcd_readl(hba, REG_CONTROLLER_STATUS) & UIC_COMMAND_READY)
+		return true;
+	else
+		return false;
+}
+
+/**
+ * ufshcd_dispatch_uic_cmd - Dispatch UIC commands to unipro layers
+ * @hba: per adapter instance
+ * @uic_cmd: UIC command
+ *
+ * Mutex must be held.
  */
 static inline void
-ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd)
+ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
 {
+	WARN_ON(hba->active_uic_cmd);
+
+	hba->active_uic_cmd = uic_cmd;
+
 	/* Write Args */
-	writel(uic_cmnd->argument1,
-	      (hba->mmio_base + REG_UIC_COMMAND_ARG_1));
-	writel(uic_cmnd->argument2,
-	      (hba->mmio_base + REG_UIC_COMMAND_ARG_2));
-	writel(uic_cmnd->argument3,
-	      (hba->mmio_base + REG_UIC_COMMAND_ARG_3));
+	ufshcd_writel(hba, uic_cmd->argument1, REG_UIC_COMMAND_ARG_1);
+	ufshcd_writel(hba, uic_cmd->argument2, REG_UIC_COMMAND_ARG_2);
+	ufshcd_writel(hba, uic_cmd->argument3, REG_UIC_COMMAND_ARG_3);
 
 	/* Write UIC Cmd */
-	writel((uic_cmnd->command & COMMAND_OPCODE_MASK),
-	       (hba->mmio_base + REG_UIC_COMMAND));
+	ufshcd_writel(hba, uic_cmd->command & COMMAND_OPCODE_MASK,
+		      REG_UIC_COMMAND);
+}
+
+/**
+ * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command
+ * @hba: per adapter instance
+ * @uic_command: UIC command
+ *
+ * Must be called with mutex held.
+ * Returns 0 only if success.
+ */
+static int
+ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
+{
+	int ret;
+	unsigned long flags;
+
+	if (wait_for_completion_timeout(&uic_cmd->done,
+					msecs_to_jiffies(UIC_CMD_TIMEOUT)))
+		ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT;
+	else
+		ret = -ETIMEDOUT;
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	hba->active_uic_cmd = NULL;
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	return ret;
+}
+
+/**
+ * __ufshcd_send_uic_cmd - Send UIC commands and retrieve the result
+ * @hba: per adapter instance
+ * @uic_cmd: UIC command
+ *
+ * Identical to ufshcd_send_uic_cmd() expect mutex. Must be called
+ * with mutex held.
+ * Returns 0 only if success.
+ */
+static int
+__ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
+{
+	int ret;
+	unsigned long flags;
+
+	if (!ufshcd_ready_for_uic_cmd(hba)) {
+		dev_err(hba->dev,
+			"Controller not ready to accept UIC commands\n");
+		return -EIO;
+	}
+
+	init_completion(&uic_cmd->done);
+
+	spin_lock_irqsave(hba->host->host_lock, flags);
+	ufshcd_dispatch_uic_cmd(hba, uic_cmd);
+	spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+	ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd);
+
+	return ret;
+}
+
+/**
+ * ufshcd_send_uic_cmd - Send UIC commands and retrieve the result
+ * @hba: per adapter instance
+ * @uic_cmd: UIC command
+ *
+ * Returns 0 only if success.
+ */
+static int
+ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
+{
+	int ret;
+
+	mutex_lock(&hba->uic_cmd_mutex);
+	ret = __ufshcd_send_uic_cmd(hba, uic_cmd);
+	mutex_unlock(&hba->uic_cmd_mutex);
+
+	return ret;
 }
 
 /**
@@ -400,26 +477,45 @@ static int ufshcd_map_sg(struct ufshcd_l
 }
 
 /**
- * ufshcd_int_config - enable/disable interrupts
+ * ufshcd_enable_intr - enable interrupts
  * @hba: per adapter instance
- * @option: interrupt option
+ * @intrs: interrupt bits
  */
-static void ufshcd_int_config(struct ufs_hba *hba, u32 option)
+static void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs)
 {
-	switch (option) {
-	case UFSHCD_INT_ENABLE:
-		writel(hba->int_enable_mask,
-		      (hba->mmio_base + REG_INTERRUPT_ENABLE));
-		break;
-	case UFSHCD_INT_DISABLE:
-		if (hba->ufs_version == UFSHCI_VERSION_10)
-			writel(INTERRUPT_DISABLE_MASK_10,
-			      (hba->mmio_base + REG_INTERRUPT_ENABLE));
-		else
-			writel(INTERRUPT_DISABLE_MASK_11,
-			       (hba->mmio_base + REG_INTERRUPT_ENABLE));
-		break;
+	u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+	if (hba->ufs_version == UFSHCI_VERSION_10) {
+		u32 rw;
+		rw = set & INTERRUPT_MASK_RW_VER_10;
+		set = rw | ((set ^ intrs) & intrs);
+	} else {
+		set |= intrs;
 	}
+
+	ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
+}
+
+/**
+ * ufshcd_disable_intr - disable interrupts
+ * @hba: per adapter instance
+ * @intrs: interrupt bits
+ */
+static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs)
+{
+	u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+	if (hba->ufs_version == UFSHCI_VERSION_10) {
+		u32 rw;
+		rw = (set & INTERRUPT_MASK_RW_VER_10) &
+			~(intrs & INTERRUPT_MASK_RW_VER_10);
+		set = rw | ((set & intrs) & ~INTERRUPT_MASK_RW_VER_10);
+
+	} else {
+		set &= ~intrs;
+	}
+
+	ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
 }
 
 /**
@@ -562,10 +658,10 @@ static int ufshcd_memory_alloc(struct uf
 
 	/* Allocate memory for UTP command descriptors */
 	ucdl_size = (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs);
-	hba->ucdl_base_addr = dma_alloc_coherent(hba->dev,
-						 ucdl_size,
-						 &hba->ucdl_dma_addr,
-						 GFP_KERNEL);
+	hba->ucdl_base_addr = dmam_alloc_coherent(hba->dev,
+						  ucdl_size,
+						  &hba->ucdl_dma_addr,
+						  GFP_KERNEL);
 
 	/*
 	 * UFSHCI requires UTP command descriptor to be 128 byte aligned.
@@ -585,10 +681,10 @@ static int ufshcd_memory_alloc(struct uf
 	 * UFSHCI requires 1024 byte alignment of UTRD
 	 */
 	utrdl_size = (sizeof(struct utp_transfer_req_desc) * hba->nutrs);
-	hba->utrdl_base_addr = dma_alloc_coherent(hba->dev,
-						  utrdl_size,
-						  &hba->utrdl_dma_addr,
-						  GFP_KERNEL);
+	hba->utrdl_base_addr = dmam_alloc_coherent(hba->dev,
+						   utrdl_size,
+						   &hba->utrdl_dma_addr,
+						   GFP_KERNEL);
 	if (!hba->utrdl_base_addr ||
 	    WARN_ON(hba->utrdl_dma_addr & (PAGE_SIZE - 1))) {
 		dev_err(hba->dev,
@@ -601,10 +697,10 @@ static int ufshcd_memory_alloc(struct uf
 	 * UFSHCI requires 1024 byte alignment of UTMRD
 	 */
 	utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs;
-	hba->utmrdl_base_addr = dma_alloc_coherent(hba->dev,
-						   utmrdl_size,
-						   &hba->utmrdl_dma_addr,
-						   GFP_KERNEL);
+	hba->utmrdl_base_addr = dmam_alloc_coherent(hba->dev,
+						    utmrdl_size,
+						    &hba->utmrdl_dma_addr,
+						    GFP_KERNEL);
 	if (!hba->utmrdl_base_addr ||
 	    WARN_ON(hba->utmrdl_dma_addr & (PAGE_SIZE - 1))) {
 		dev_err(hba->dev,
@@ -613,14 +709,15 @@ static int ufshcd_memory_alloc(struct uf
 	}
 
 	/* Allocate memory for local reference block */
-	hba->lrb = kcalloc(hba->nutrs, sizeof(struct ufshcd_lrb), GFP_KERNEL);
+	hba->lrb = devm_kzalloc(hba->dev,
+				hba->nutrs * sizeof(struct ufshcd_lrb),
+				GFP_KERNEL);
 	if (!hba->lrb) {
 		dev_err(hba->dev, "LRB Memory allocation failed\n");
 		goto out;
 	}
 	return 0;
 out:
-	ufshcd_free_hba_memory(hba);
 	return -ENOMEM;
 }
 
@@ -674,7 +771,7 @@ static void ufshcd_host_memory_configure
 		utrdlp[i].prd_table_offset =
 				cpu_to_le16((prdt_offset >> 2));
 		utrdlp[i].response_upiu_length =
-				cpu_to_le16(ALIGNED_UPIU_SIZE);
+				cpu_to_le16(ALIGNED_UPIU_SIZE >> 2);
 
 		hba->lrb[i].utr_descriptor_ptr = (utrdlp + i);
 		hba->lrb[i].ucd_cmd_ptr =
@@ -699,35 +796,16 @@ static void ufshcd_host_memory_configure
  */
 static int ufshcd_dme_link_startup(struct ufs_hba *hba)
 {
-	struct uic_command *uic_cmd;
-	unsigned long flags;
-
-	/* check if controller is ready to accept UIC commands */
-	if (((readl(hba->mmio_base + REG_CONTROLLER_STATUS)) &
-	    UIC_COMMAND_READY) == 0x0) {
-		dev_err(hba->dev,
-			"Controller not ready"
-			" to accept UIC commands\n");
-		return -EIO;
-	}
-
-	spin_lock_irqsave(hba->host->host_lock, flags);
-
-	/* form UIC command */
-	uic_cmd = &hba->active_uic_cmd;
-	uic_cmd->command = UIC_CMD_DME_LINK_STARTUP;
-	uic_cmd->argument1 = 0;
-	uic_cmd->argument2 = 0;
-	uic_cmd->argument3 = 0;
+	struct uic_command uic_cmd = {0};
+	int ret;
 
-	/* enable UIC related interrupts */
-	hba->int_enable_mask |= UIC_COMMAND_COMPL;
-	ufshcd_int_config(hba, UFSHCD_INT_ENABLE);
+	uic_cmd.command = UIC_CMD_DME_LINK_STARTUP;
 
-	/* sending UIC commands to controller */
-	ufshcd_send_uic_command(hba, uic_cmd);
-	spin_unlock_irqrestore(hba->host->host_lock, flags);
-	return 0;
+	ret = ufshcd_send_uic_cmd(hba, &uic_cmd);
+	if (ret)
+		dev_err(hba->dev,
+			"dme-link-startup: error code %d\n", ret);
+	return ret;
 }
 
 /**
@@ -736,9 +814,10 @@ static int ufshcd_dme_link_startup(struc
  *
  * To bring UFS host controller to operational state,
  * 1. Check if device is present
- * 2. Configure run-stop-registers
- * 3. Enable required interrupts
- * 4. Configure interrupt aggregation
+ * 2. Enable required interrupts
+ * 3. Configure interrupt aggregation
+ * 4. Program UTRL and UTMRL base addres
+ * 5. Configure run-stop-registers
  *
  * Returns 0 on success, non-zero value on failure
  */
@@ -748,13 +827,29 @@ static int ufshcd_make_hba_operational(s
 	u32 reg;
 
 	/* check if device present */
-	reg = readl((hba->mmio_base + REG_CONTROLLER_STATUS));
+	reg = ufshcd_readl(hba, REG_CONTROLLER_STATUS);
 	if (!ufshcd_is_device_present(reg)) {
 		dev_err(hba->dev, "cc: Device not present\n");
 		err = -ENXIO;
 		goto out;
 	}
 
+	/* Enable required interrupts */
+	ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS);
+
+	/* Configure interrupt aggregation */
+	ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG);
+
+	/* Configure UTRL and UTMRL base address registers */
+	ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr),
+			REG_UTP_TRANSFER_REQ_LIST_BASE_L);
+	ufshcd_writel(hba, upper_32_bits(hba->utrdl_dma_addr),
+			REG_UTP_TRANSFER_REQ_LIST_BASE_H);
+	ufshcd_writel(hba, lower_32_bits(hba->utmrdl_dma_addr),
+			REG_UTP_TASK_REQ_LIST_BASE_L);
+	ufshcd_writel(hba, upper_32_bits(hba->utmrdl_dma_addr),
+			REG_UTP_TASK_REQ_LIST_BASE_H);
+
 	/*
 	 * UCRDY, UTMRLDY and UTRLRDY bits must be 1
 	 * DEI, HEI bits must be 0
@@ -768,23 +863,11 @@ static int ufshcd_make_hba_operational(s
 		goto out;
 	}
 
-	/* Enable required interrupts */
-	hba->int_enable_mask |= (UTP_TRANSFER_REQ_COMPL |
-				 UIC_ERROR |
-				 UTP_TASK_REQ_COMPL |
-				 DEVICE_FATAL_ERROR |
-				 CONTROLLER_FATAL_ERROR |
-				 SYSTEM_BUS_FATAL_ERROR);
-	ufshcd_int_config(hba, UFSHCD_INT_ENABLE);
-
-	/* Configure interrupt aggregation */
-	ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG);
-
 	if (hba->ufshcd_state == UFSHCD_STATE_RESET)
 		scsi_unblock_requests(hba->host);
 
 	hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL;
-	scsi_scan_host(hba->host);
+
 out:
 	return err;
 }
@@ -853,34 +936,28 @@ static int ufshcd_hba_enable(struct ufs_
 }
 
 /**
- * ufshcd_initialize_hba - start the initialization process
+ * ufshcd_link_startup - Initialize unipro link startup
  * @hba: per adapter instance
  *
- * 1. Enable the controller via ufshcd_hba_enable.
- * 2. Program the Transfer Request List Address with the starting address of
- * UTRDL.
- * 3. Program the Task Management Request List Address with starting address
- * of UTMRDL.
- *
- * Returns 0 on success, non-zero value on failure.
+ * Returns 0 for success, non-zero in case of failure
  */
-static int ufshcd_initialize_hba(struct ufs_hba *hba)
+static int ufshcd_link_startup(struct ufs_hba *hba)
 {
-	if (ufshcd_hba_enable(hba))
-		return -EIO;
+	int ret;
 
-	/* Configure UTRL and UTMRL base address registers */
-	writel(lower_32_bits(hba->utrdl_dma_addr),
-	       (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_L));
-	writel(upper_32_bits(hba->utrdl_dma_addr),
-	       (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_H));
-	writel(lower_32_bits(hba->utmrdl_dma_addr),
-	       (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_L));
-	writel(upper_32_bits(hba->utmrdl_dma_addr),
-	       (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_H));
+	/* enable UIC related interrupts */
+	ufshcd_enable_intr(hba, UIC_COMMAND_COMPL);
 
-	/* Initialize unipro link startup procedure */
-	return ufshcd_dme_link_startup(hba);
+	ret = ufshcd_dme_link_startup(hba);
+	if (ret)
+		goto out;
+
+	ret = ufshcd_make_hba_operational(hba);
+
+out:
+	if (ret)
+		dev_err(hba->dev, "link startup failed %d\n", ret);
+	return ret;
 }
 
 /**
@@ -920,12 +997,19 @@ static int ufshcd_do_reset(struct ufs_hb
 	hba->outstanding_reqs = 0;
 	hba->outstanding_tasks = 0;
 
-	/* start the initialization process */
-	if (ufshcd_initialize_hba(hba)) {
+	/* Host controller enable */
+	if (ufshcd_hba_enable(hba)) {
 		dev_err(hba->dev,
 			"Reset: Controller initialization failed\n");
 		return FAILED;
 	}
+
+	if (ufshcd_link_startup(hba)) {
+		dev_err(hba->dev,
+			"Reset: Link start-up failed\n");
+		return FAILED;
+	}
+
 	return SUCCESS;
 }
 
@@ -1157,6 +1241,19 @@ ufshcd_transfer_rsp_status(struct ufs_hb
 }
 
 /**
+ * ufshcd_uic_cmd_compl - handle completion of uic command
+ * @hba: per adapter instance
+ */
+static void ufshcd_uic_cmd_compl(struct ufs_hba *hba)
+{
+	if (hba->active_uic_cmd) {
+		hba->active_uic_cmd->argument2 |=
+			ufshcd_get_uic_cmd_result(hba);
+		complete(&hba->active_uic_cmd->done);
+	}
+}
+
+/**
  * ufshcd_transfer_req_compl - handle SCSI and query command completion
  * @hba: per adapter instance
  */
@@ -1169,8 +1266,7 @@ static void ufshcd_transfer_req_compl(st
 	int index;
 
 	lrb = hba->lrb;
-	tr_doorbell =
-		readl(hba->mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL);
+	tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
 	completed_reqs = tr_doorbell ^ hba->outstanding_reqs;
 
 	for (index = 0; index < hba->nutrs; index++) {
@@ -1197,28 +1293,6 @@ static void ufshcd_transfer_req_compl(st
 }
 
 /**
- * ufshcd_uic_cc_handler - handle UIC command completion
- * @work: pointer to a work queue structure
- *
- * Returns 0 on success, non-zero value on failure
- */
-static void ufshcd_uic_cc_handler (struct work_struct *work)
-{
-	struct ufs_hba *hba;
-
-	hba = container_of(work, struct ufs_hba, uic_workq);
-
-	if ((hba->active_uic_cmd.command == UIC_CMD_DME_LINK_STARTUP) &&
-	    !(ufshcd_get_uic_cmd_result(hba))) {
-
-		if (ufshcd_make_hba_operational(hba))
-			dev_err(hba->dev,
-				"cc: hba not operational state\n");
-		return;
-	}
-}
-
-/**
  * ufshcd_fatal_err_handler - handle fatal errors
  * @hba: per adapter instance
  */
@@ -1244,9 +1318,7 @@ static void ufshcd_err_handler(struct uf
 		goto fatal_eh;
 
 	if (hba->errors & UIC_ERROR) {
-
-		reg = readl(hba->mmio_base +
-			    REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER);
+		reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DATA_LINK_LAYER);
 		if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT)
 			goto fatal_eh;
 	}
@@ -1264,7 +1336,7 @@ static void ufshcd_tmc_handler(struct uf
 {
 	u32 tm_doorbell;
 
-	tm_doorbell = readl(hba->mmio_base + REG_UTP_TASK_REQ_DOOR_BELL);
+	tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
 	hba->tm_condition = tm_doorbell ^ hba->outstanding_tasks;
 	wake_up_interruptible(&hba->ufshcd_tm_wait_queue);
 }
@@ -1281,7 +1353,7 @@ static void ufshcd_sl_intr(struct ufs_hb
 		ufshcd_err_handler(hba);
 
 	if (intr_status & UIC_COMMAND_COMPL)
-		schedule_work(&hba->uic_workq);
+		ufshcd_uic_cmd_compl(hba);
 
 	if (intr_status & UTP_TASK_REQ_COMPL)
 		ufshcd_tmc_handler(hba);
@@ -1305,15 +1377,11 @@ static irqreturn_t ufshcd_intr(int irq,
 	struct ufs_hba *hba = __hba;
 
 	spin_lock(hba->host->host_lock);
-	intr_status = readl(hba->mmio_base + REG_INTERRUPT_STATUS);
+	intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
 
 	if (intr_status) {
+		ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
 		ufshcd_sl_intr(hba, intr_status);
-
-		/* If UFSHCI 1.0 then clear interrupt status register */
-		if (hba->ufs_version == UFSHCI_VERSION_10)
-			writel(intr_status,
-			       (hba->mmio_base + REG_INTERRUPT_STATUS));
 		retval = IRQ_HANDLED;
 	}
 	spin_unlock(hba->host->host_lock);
@@ -1378,8 +1446,7 @@ ufshcd_issue_tm_cmd(struct ufs_hba *hba,
 
 	/* send command to the controller */
 	__set_bit(free_slot, &hba->outstanding_tasks);
-	writel((1 << free_slot),
-	       (hba->mmio_base + REG_UTP_TASK_REQ_DOOR_BELL));
+	ufshcd_writel(hba, 1 << free_slot, REG_UTP_TASK_REQ_DOOR_BELL);
 
 	spin_unlock_irqrestore(host->host_lock, flags);
 
@@ -1509,6 +1576,21 @@ out:
 	return err;
 }
 
+/**
+ * ufshcd_async_scan - asynchronous execution for link startup
+ * @data: data pointer to pass to this function
+ * @cookie: cookie data
+ */
+static void ufshcd_async_scan(void *data, async_cookie_t cookie)
+{
+	struct ufs_hba *hba = (struct ufs_hba *)data;
+	int ret;
+
+	ret = ufshcd_link_startup(hba);
+	if (!ret)
+		scsi_scan_host(hba->host);
+}
+
 static struct scsi_host_template ufshcd_driver_template = {
 	.module			= THIS_MODULE,
 	.name			= UFSHCD,
@@ -1569,17 +1651,6 @@ int ufshcd_resume(struct ufs_hba *hba)
 EXPORT_SYMBOL_GPL(ufshcd_resume);
 
 /**
- * ufshcd_hba_free - free allocated memory for
- *			host memory space data structures
- * @hba: per adapter instance
- */
-static void ufshcd_hba_free(struct ufs_hba *hba)
-{
-	iounmap(hba->mmio_base);
-	ufshcd_free_hba_memory(hba);
-}
-
-/**
  * ufshcd_remove - de-allocate SCSI host and host memory space
  *		data structure memory
  * @hba - per adapter instance
@@ -1587,10 +1658,8 @@ static void ufshcd_hba_free(struct ufs_h
 void ufshcd_remove(struct ufs_hba *hba)
 {
 	/* disable interrupts */
-	ufshcd_int_config(hba, UFSHCD_INT_DISABLE);
-
+	ufshcd_disable_intr(hba, hba->intr_mask);
 	ufshcd_hba_stop(hba);
-	ufshcd_hba_free(hba);
 
 	scsi_remove_host(hba->host);
 	scsi_host_put(hba->host);
@@ -1645,6 +1714,9 @@ int ufshcd_init(struct device *dev, stru
 	/* Get UFS version supported by the controller */
 	hba->ufs_version = ufshcd_get_ufs_version(hba);
 
+	/* Get Interrupt bit mask per version */
+	hba->intr_mask = ufshcd_get_intr_mask(hba);
+
 	/* Allocate memory for host memory space */
 	err = ufshcd_memory_alloc(hba);
 	if (err) {
@@ -1667,45 +1739,46 @@ int ufshcd_init(struct device *dev, stru
 	init_waitqueue_head(&hba->ufshcd_tm_wait_queue);
 
 	/* Initialize work queues */
-	INIT_WORK(&hba->uic_workq, ufshcd_uic_cc_handler);
 	INIT_WORK(&hba->feh_workq, ufshcd_fatal_err_handler);
 
+	/* Initialize UIC command mutex */
+	mutex_init(&hba->uic_cmd_mutex);
+
 	/* IRQ registration */
-	err = request_irq(irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
+	err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
 	if (err) {
 		dev_err(hba->dev, "request irq failed\n");
-		goto out_lrb_free;
+		goto out_disable;
 	}
 
 	/* Enable SCSI tag mapping */
 	err = scsi_init_shared_tag_map(host, host->can_queue);
 	if (err) {
 		dev_err(hba->dev, "init shared queue failed\n");
-		goto out_free_irq;
+		goto out_disable;
 	}
 
 	err = scsi_add_host(host, hba->dev);
 	if (err) {
 		dev_err(hba->dev, "scsi_add_host failed\n");
-		goto out_free_irq;
+		goto out_disable;
 	}
 
-	/* Initialization routine */
-	err = ufshcd_initialize_hba(hba);
+	/* Host controller enable */
+	err = ufshcd_hba_enable(hba);
 	if (err) {
-		dev_err(hba->dev, "Initialization failed\n");
+		dev_err(hba->dev, "Host controller enable failed\n");
 		goto out_remove_scsi_host;
 	}
+
 	*hba_handle = hba;
 
+	async_schedule(ufshcd_async_scan, hba);
+
 	return 0;
 
 out_remove_scsi_host:
 	scsi_remove_host(hba->host);
-out_free_irq:
-	free_irq(irq, hba);
-out_lrb_free:
-	ufshcd_free_hba_memory(hba);
 out_disable:
 	scsi_host_put(host);
 out_error:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/ufs/ufshcd.h linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshcd.h
--- linux-libre-3.10-gnu/drivers/scsi/ufs/ufshcd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshcd.h	2013-08-25 20:43:22.000000000 -0400
@@ -51,6 +51,7 @@
 #include <linux/bitops.h>
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
+#include <linux/completion.h>
 
 #include <asm/irq.h>
 #include <asm/byteorder.h>
@@ -75,6 +76,7 @@
  * @argument3: UIC command argument 3
  * @cmd_active: Indicate if UIC command is outstanding
  * @result: UIC command result
+ * @done: UIC command completion
  */
 struct uic_command {
 	u32 command;
@@ -83,6 +85,7 @@ struct uic_command {
 	u32 argument3;
 	int cmd_active;
 	int result;
+	struct completion done;
 };
 
 /**
@@ -136,11 +139,11 @@ struct ufshcd_lrb {
  * @ufs_version: UFS Version to which controller complies
  * @irq: Irq number of the controller
  * @active_uic_cmd: handle of active UIC command
+ * @uic_cmd_mutex: mutex for uic command
  * @ufshcd_tm_wait_queue: wait queue for task management
  * @tm_condition: condition variable for task management
  * @ufshcd_state: UFSHCD states
- * @int_enable_mask: Interrupt Mask Bits
- * @uic_workq: Work queue for UIC completion handling
+ * @intr_mask: Interrupt Mask Bits
  * @feh_workq: Work queue for fatal controller error handling
  * @errors: HBA errors
  */
@@ -171,21 +174,27 @@ struct ufs_hba {
 	u32 ufs_version;
 	unsigned int irq;
 
-	struct uic_command active_uic_cmd;
+	struct uic_command *active_uic_cmd;
+	struct mutex uic_cmd_mutex;
+
 	wait_queue_head_t ufshcd_tm_wait_queue;
 	unsigned long tm_condition;
 
 	u32 ufshcd_state;
-	u32 int_enable_mask;
+	u32 intr_mask;
 
 	/* Work Queues */
-	struct work_struct uic_workq;
 	struct work_struct feh_workq;
 
 	/* HBA Errors */
 	u32 errors;
 };
 
+#define ufshcd_writel(hba, val, reg)	\
+	writel((val), (hba)->mmio_base + (reg))
+#define ufshcd_readl(hba, reg)	\
+	readl((hba)->mmio_base + (reg))
+
 int ufshcd_init(struct device *, struct ufs_hba ** , void __iomem * ,
 			unsigned int);
 void ufshcd_remove(struct ufs_hba *);
@@ -196,7 +205,7 @@ void ufshcd_remove(struct ufs_hba *);
  */
 static inline void ufshcd_hba_stop(struct ufs_hba *hba)
 {
-	writel(CONTROLLER_DISABLE, (hba->mmio_base + REG_CONTROLLER_ENABLE));
+	ufshcd_writel(hba, CONTROLLER_DISABLE,  REG_CONTROLLER_ENABLE);
 }
 
 #endif /* End of Header */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/ufs/ufshcd-pci.c linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshcd-pci.c
--- linux-libre-3.10-gnu/drivers/scsi/ufs/ufshcd-pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshcd-pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -92,7 +92,6 @@ static void ufshcd_pci_remove(struct pci
 	struct ufs_hba *hba = pci_get_drvdata(pdev);
 
 	disable_irq(pdev->irq);
-	free_irq(pdev->irq, hba);
 	ufshcd_remove(hba);
 	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/ufs/ufshcd-pltfrm.c linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshcd-pltfrm.c
--- linux-libre-3.10-gnu/drivers/scsi/ufs/ufshcd-pltfrm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshcd-pltfrm.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,9 +33,10 @@
  * this program.
  */
 
-#include "ufshcd.h"
 #include <linux/platform_device.h>
 
+#include "ufshcd.h"
+
 #ifdef CONFIG_PM
 /**
  * ufshcd_pltfrm_suspend - suspend power management function
@@ -97,62 +98,39 @@ static int ufshcd_pltfrm_probe(struct pl
 	struct ufs_hba *hba;
 	void __iomem *mmio_base;
 	struct resource *mem_res;
-	struct resource *irq_res;
-	resource_size_t mem_size;
-	int err;
+	int irq, err;
 	struct device *dev = &pdev->dev;
 
 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mem_res) {
-		dev_err(&pdev->dev,
-			"Memory resource not available\n");
+		dev_err(dev, "Memory resource not available\n");
 		err = -ENODEV;
-		goto out_error;
-	}
-
-	mem_size = resource_size(mem_res);
-	if (!request_mem_region(mem_res->start, mem_size, "ufshcd")) {
-		dev_err(&pdev->dev,
-			"Cannot reserve the memory resource\n");
-		err = -EBUSY;
-		goto out_error;
+		goto out;
 	}
 
-	mmio_base = ioremap_nocache(mem_res->start, mem_size);
-	if (!mmio_base) {
-		dev_err(&pdev->dev, "memory map failed\n");
-		err = -ENOMEM;
-		goto out_release_regions;
+	mmio_base = devm_ioremap_resource(dev, mem_res);
+	if (IS_ERR(mmio_base)) {
+		dev_err(dev, "memory map failed\n");
+		err = PTR_ERR(mmio_base);
+		goto out;
 	}
 
-	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!irq_res) {
-		dev_err(&pdev->dev, "IRQ resource not available\n");
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(dev, "IRQ resource not available\n");
 		err = -ENODEV;
-		goto out_iounmap;
-	}
-
-	err = dma_set_coherent_mask(dev, dev->coherent_dma_mask);
-	if (err) {
-		dev_err(&pdev->dev, "set dma mask failed\n");
-		goto out_iounmap;
+		goto out;
 	}
 
-	err = ufshcd_init(&pdev->dev, &hba, mmio_base, irq_res->start);
+	err = ufshcd_init(dev, &hba, mmio_base, irq);
 	if (err) {
-		dev_err(&pdev->dev, "Intialization failed\n");
-		goto out_iounmap;
+		dev_err(dev, "Intialization failed\n");
+		goto out;
 	}
 
 	platform_set_drvdata(pdev, hba);
 
-	return 0;
-
-out_iounmap:
-	iounmap(mmio_base);
-out_release_regions:
-	release_mem_region(mem_res->start, mem_size);
-out_error:
+out:
 	return err;
 }
 
@@ -164,32 +142,16 @@ out_error:
  */
 static int ufshcd_pltfrm_remove(struct platform_device *pdev)
 {
-	struct resource *mem_res;
-	resource_size_t mem_size;
 	struct ufs_hba *hba =  platform_get_drvdata(pdev);
 
 	disable_irq(hba->irq);
-
-	/* Some buggy controllers raise interrupt after
-	 * the resources are removed. So first we unregister the
-	 * irq handler and then the resources used by driver
-	 */
-
-	free_irq(hba->irq, hba);
 	ufshcd_remove(hba);
-	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem_res)
-		dev_err(&pdev->dev, "ufshcd: Memory resource not available\n");
-	else {
-		mem_size = resource_size(mem_res);
-		release_mem_region(mem_res->start, mem_size);
-	}
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
 static const struct of_device_id ufs_of_match[] = {
 	{ .compatible = "jedec,ufs-1.1"},
+	{},
 };
 
 static const struct dev_pm_ops ufshcd_dev_pm_ops = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/ufs/ufshci.h linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshci.h
--- linux-libre-3.10-gnu/drivers/scsi/ufs/ufshci.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/ufs/ufshci.h	2013-08-25 20:43:22.000000000 -0400
@@ -232,10 +232,11 @@ enum {
 /* Interrupt disable masks */
 enum {
 	/* Interrupt disable mask for UFSHCI v1.0 */
-	INTERRUPT_DISABLE_MASK_10	= 0xFFFF,
+	INTERRUPT_MASK_ALL_VER_10	= 0x30FFF,
+	INTERRUPT_MASK_RW_VER_10	= 0x30000,
 
 	/* Interrupt disable mask for UFSHCI v1.1 */
-	INTERRUPT_DISABLE_MASK_11	= 0x0,
+	INTERRUPT_MASK_ALL_VER_11	= 0x31FFF,
 };
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/scsi/virtio_scsi.c linux-libre-3.11-rc7-gnu/drivers/scsi/virtio_scsi.c
--- linux-libre-3.10-gnu/drivers/scsi/virtio_scsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/scsi/virtio_scsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -751,7 +751,7 @@ static void __virtscsi_set_affinity(stru
 
 		vscsi->affinity_hint_set = true;
 	} else {
-		for (i = 0; i < vscsi->num_queues - VIRTIO_SCSI_VQ_BASE; i++)
+		for (i = 0; i < vscsi->num_queues; i++)
 			virtqueue_set_affinity(vscsi->req_vqs[i].vq, -1);
 
 		vscsi->affinity_hint_set = false;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/sh/clk/core.c linux-libre-3.11-rc7-gnu/drivers/sh/clk/core.c
--- linux-libre-3.10-gnu/drivers/sh/clk/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/sh/clk/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -63,12 +63,12 @@ void clk_rate_table_build(struct clk *cl
 		else
 			freq = clk->parent->rate * mult / div;
 
-		freq_table[i].index = i;
+		freq_table[i].driver_data = i;
 		freq_table[i].frequency = freq;
 	}
 
 	/* Termination entry */
-	freq_table[i].index = i;
+	freq_table[i].driver_data = i;
 	freq_table[i].frequency = CPUFREQ_TABLE_END;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/sh/pm_runtime.c linux-libre-3.11-rc7-gnu/drivers/sh/pm_runtime.c
--- linux-libre-3.10-gnu/drivers/sh/pm_runtime.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/sh/pm_runtime.c	2013-08-25 20:43:22.000000000 -0400
@@ -25,7 +25,7 @@
 static int default_platform_runtime_idle(struct device *dev)
 {
 	/* suspend synchronously to disable clocks immediately */
-	return pm_runtime_suspend(dev);
+	return 0;
 }
 
 static struct dev_pm_domain default_pm_domain = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/Kconfig linux-libre-3.11-rc7-gnu/drivers/spi/Kconfig
--- linux-libre-3.10-gnu/drivers/spi/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -266,7 +266,7 @@ config SPI_OC_TINY
 
 config SPI_OCTEON
 	tristate "Cavium OCTEON SPI controller"
-	depends on CPU_CAVIUM_OCTEON
+	depends on CAVIUM_OCTEON_SOC
 	help
 	  SPI host driver for the hardware found on some Cavium OCTEON
 	  SOCs.
@@ -404,7 +404,7 @@ config SPI_SH_HSPI
 
 config SPI_SIRF
 	tristate "CSR SiRFprimaII SPI controller"
-	depends on ARCH_PRIMA2
+	depends on ARCH_SIRF
 	select SPI_BITBANG
 	help
 	  SPI driver for CSR SiRFprimaII SoCs
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-altera.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-altera.c
--- linux-libre-3.10-gnu/drivers/spi/spi-altera.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-altera.c	2013-08-25 20:43:22.000000000 -0400
@@ -285,7 +285,6 @@ static int altera_spi_probe(struct platf
 exit_busy:
 	err = -EBUSY;
 exit:
-	platform_set_drvdata(pdev, NULL);
 	spi_master_put(master);
 	return err;
 }
@@ -296,7 +295,6 @@ static int altera_spi_remove(struct plat
 	struct spi_master *master = hw->bitbang.master;
 
 	spi_bitbang_stop(&hw->bitbang);
-	platform_set_drvdata(dev, NULL);
 	spi_master_put(master);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-ath79.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-ath79.c
--- linux-libre-3.10-gnu/drivers/spi/spi-ath79.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-ath79.c	2013-08-25 20:43:22.000000000 -0400
@@ -155,9 +155,6 @@ static int ath79_spi_setup(struct spi_de
 {
 	int status = 0;
 
-	if (spi->bits_per_word > 32)
-		return -EINVAL;
-
 	if (!spi->controller_state) {
 		status = ath79_spi_setup_cs(spi);
 		if (status)
@@ -226,6 +223,7 @@ static int ath79_spi_probe(struct platfo
 
 	pdata = pdev->dev.platform_data;
 
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
 	master->setup = ath79_spi_setup;
 	master->cleanup = ath79_spi_cleanup;
 	if (pdata) {
@@ -287,7 +285,6 @@ err_clk_put:
 err_unmap:
 	iounmap(sp->base);
 err_put_master:
-	platform_set_drvdata(pdev, NULL);
 	spi_master_put(sp->bitbang.master);
 
 	return ret;
@@ -302,7 +299,6 @@ static int ath79_spi_remove(struct platf
 	clk_disable(sp->clk);
 	clk_put(sp->clk);
 	iounmap(sp->base);
-	platform_set_drvdata(pdev, NULL);
 	spi_master_put(sp->bitbang.master);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-atmel.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-atmel.c
--- linux-libre-3.10-gnu/drivers/spi/spi-atmel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-atmel.c	2013-08-25 20:43:22.000000000 -0400
@@ -424,10 +424,15 @@ static int atmel_spi_dma_slave_config(st
 	return err;
 }
 
-static bool filter(struct dma_chan *chan, void *slave)
+static bool filter(struct dma_chan *chan, void *pdata)
 {
-	struct	at_dma_slave *sl = slave;
+	struct atmel_spi_dma *sl_pdata = pdata;
+	struct at_dma_slave *sl;
 
+	if (!sl_pdata)
+		return false;
+
+	sl = &sl_pdata->dma_slave;
 	if (sl->dma_dev == chan->device->dev) {
 		chan->private = sl;
 		return true;
@@ -438,24 +443,31 @@ static bool filter(struct dma_chan *chan
 
 static int atmel_spi_configure_dma(struct atmel_spi *as)
 {
-	struct at_dma_slave *sdata = &as->dma.dma_slave;
 	struct dma_slave_config	slave_config;
+	struct device *dev = &as->pdev->dev;
 	int err;
 
-	if (sdata && sdata->dma_dev) {
-		dma_cap_mask_t mask;
+	dma_cap_mask_t mask;
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
 
-		/* Try to grab two DMA channels */
-		dma_cap_zero(mask);
-		dma_cap_set(DMA_SLAVE, mask);
-		as->dma.chan_tx = dma_request_channel(mask, filter, sdata);
-		if (as->dma.chan_tx)
-			as->dma.chan_rx =
-				dma_request_channel(mask, filter, sdata);
+	as->dma.chan_tx = dma_request_slave_channel_compat(mask, filter,
+							   &as->dma,
+							   dev, "tx");
+	if (!as->dma.chan_tx) {
+		dev_err(dev,
+			"DMA TX channel not available, SPI unable to use DMA\n");
+		err = -EBUSY;
+		goto error;
 	}
-	if (!as->dma.chan_rx || !as->dma.chan_tx) {
-		dev_err(&as->pdev->dev,
-			"DMA channel not available, SPI unable to use DMA\n");
+
+	as->dma.chan_rx = dma_request_slave_channel_compat(mask, filter,
+							   &as->dma,
+							   dev, "rx");
+
+	if (!as->dma.chan_rx) {
+		dev_err(dev,
+			"DMA RX channel not available, SPI unable to use DMA\n");
 		err = -EBUSY;
 		goto error;
 	}
@@ -1268,13 +1280,6 @@ static int atmel_spi_setup(struct spi_de
 		return -EINVAL;
 	}
 
-	if (bits < 8 || bits > 16) {
-		dev_dbg(&spi->dev,
-				"setup: invalid bits_per_word %u (8 to 16)\n",
-				bits);
-		return -EINVAL;
-	}
-
 	/* see notes above re chipselect */
 	if (!atmel_spi_is_v2(as)
 			&& spi->chip_select == 0
@@ -1515,7 +1520,7 @@ static int atmel_spi_probe(struct platfo
 
 	/* the spi->mode bits understood by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
-
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16);
 	master->dev.of_node = pdev->dev.of_node;
 	master->bus_num = pdev->id;
 	master->num_chipselect = master->dev.of_node ? 0 : 4;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-au1550.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-au1550.c
--- linux-libre-3.10-gnu/drivers/spi/spi-au1550.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-au1550.c	2013-08-25 20:43:22.000000000 -0400
@@ -248,11 +248,6 @@ static int au1550_spi_setupxfer(struct s
 			hz = t->speed_hz;
 	}
 
-	if (bpw < 4 || bpw > 24) {
-		dev_err(&spi->dev, "setupxfer: invalid bits_per_word=%d\n",
-			bpw);
-		return -EINVAL;
-	}
 	if (hz > spi->max_speed_hz || hz > hw->freq_max || hz < hw->freq_min) {
 		dev_err(&spi->dev, "setupxfer: clock rate=%d out of range\n",
 			hz);
@@ -296,12 +291,6 @@ static int au1550_spi_setup(struct spi_d
 {
 	struct au1550_spi *hw = spi_master_get_devdata(spi->master);
 
-	if (spi->bits_per_word < 4 || spi->bits_per_word > 24) {
-		dev_err(&spi->dev, "setup: invalid bits_per_word=%d\n",
-			spi->bits_per_word);
-		return -EINVAL;
-	}
-
 	if (spi->max_speed_hz == 0)
 		spi->max_speed_hz = hw->freq_max;
 	if (spi->max_speed_hz > hw->freq_max
@@ -782,6 +771,7 @@ static int au1550_spi_probe(struct platf
 
 	/* the spi->mode bits understood by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 24);
 
 	hw = spi_master_get_devdata(master);
 
@@ -987,8 +977,6 @@ static int au1550_spi_remove(struct plat
 		au1xxx_dbdma_chan_free(hw->dma_tx_ch);
 	}
 
-	platform_set_drvdata(pdev, NULL);
-
 	spi_master_put(hw->master);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-bcm2835.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-bcm2835.c
--- linux-libre-3.10-gnu/drivers/spi/spi-bcm2835.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-bcm2835.c	2013-08-25 20:43:22.000000000 -0400
@@ -331,10 +331,9 @@ static int bcm2835_spi_probe(struct plat
 		goto out_master_put;
 	}
 
-	bs->regs = devm_request_and_ioremap(&pdev->dev, res);
-	if (!bs->regs) {
-		dev_err(&pdev->dev, "could not request/map memory region\n");
-		err = -ENODEV;
+	bs->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(bs->regs)) {
+		err = PTR_ERR(bs->regs);
 		goto out_master_put;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-bcm63xx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-bcm63xx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-bcm63xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-bcm63xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -124,17 +124,6 @@ static void bcm63xx_spi_setup_transfer(s
 /* the spi->mode bits understood by this driver: */
 #define MODEBITS (SPI_CPOL | SPI_CPHA)
 
-static int bcm63xx_spi_setup(struct spi_device *spi)
-{
-	if (spi->bits_per_word != 8) {
-		dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
-			__func__, spi->bits_per_word);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
 				unsigned int num_transfers)
 {
@@ -277,13 +266,6 @@ static int bcm63xx_spi_transfer_one(stru
 	 * full-duplex transfers.
 	 */
 	list_for_each_entry(t, &m->transfers, transfer_list) {
-		if (t->bits_per_word != 8) {
-			dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
-				__func__, t->bits_per_word);
-			status = -EINVAL;
-			goto exit;
-		}
-
 		if (!first)
 			first = t;
 
@@ -430,11 +412,11 @@ static int bcm63xx_spi_probe(struct plat
 
 	master->bus_num = pdata->bus_num;
 	master->num_chipselect = pdata->num_chipselect;
-	master->setup = bcm63xx_spi_setup;
 	master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
 	master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
 	master->transfer_one_message = bcm63xx_spi_transfer_one;
 	master->mode_bits = MODEBITS;
+	master->bits_per_word_mask = SPI_BPW_MASK(8);
 	bs->msg_type_shift = pdata->msg_type_shift;
 	bs->msg_ctl_width = pdata->msg_ctl_width;
 	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
@@ -469,7 +451,6 @@ static int bcm63xx_spi_probe(struct plat
 out_clk_disable:
 	clk_disable_unprepare(clk);
 out_err:
-	platform_set_drvdata(pdev, NULL);
 	spi_master_put(master);
 out_clk:
 	clk_put(clk);
@@ -491,8 +472,6 @@ static int bcm63xx_spi_remove(struct pla
 	clk_disable_unprepare(bs->clk);
 	clk_put(bs->clk);
 
-	platform_set_drvdata(pdev, 0);
-
 	spi_master_put(master);
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-bfin5xx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-bfin5xx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-bfin5xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-bfin5xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -643,21 +643,16 @@ static void bfin_spi_pump_transfers(unsi
 
 	/* Bits per word setup */
 	bits_per_word = transfer->bits_per_word;
-	if (bits_per_word % 16 == 0) {
+	if (bits_per_word == 16) {
 		drv_data->n_bytes = bits_per_word/8;
 		drv_data->len = (transfer->len) >> 1;
 		cr_width = BIT_CTL_WORDSIZE;
 		drv_data->ops = &bfin_bfin_spi_transfer_ops_u16;
-	} else if (bits_per_word % 8 == 0) {
+	} else if (bits_per_word == 8) {
 		drv_data->n_bytes = bits_per_word/8;
 		drv_data->len = transfer->len;
 		cr_width = 0;
 		drv_data->ops = &bfin_bfin_spi_transfer_ops_u8;
-	} else {
-		dev_err(&drv_data->pdev->dev, "transfer: unsupported bits_per_word\n");
-		message->status = -EINVAL;
-		bfin_spi_giveback(drv_data);
-		return;
 	}
 	cr = bfin_read(&drv_data->regs->ctl) & ~(BIT_CTL_TIMOD | BIT_CTL_WORDSIZE);
 	cr |= cr_width;
@@ -808,13 +803,13 @@ static void bfin_spi_pump_transfers(unsi
 			bfin_write(&drv_data->regs->tdbr, chip->idle_tx_val);
 		else {
 			int loop;
-			if (bits_per_word % 16 == 0) {
+			if (bits_per_word == 16) {
 				u16 *buf = (u16 *)drv_data->tx;
 				for (loop = 0; loop < bits_per_word / 16;
 						loop++) {
 					bfin_write(&drv_data->regs->tdbr, *buf++);
 				}
-			} else if (bits_per_word % 8 == 0) {
+			} else if (bits_per_word == 8) {
 				u8 *buf = (u8 *)drv_data->tx;
 				for (loop = 0; loop < bits_per_word / 8; loop++)
 					bfin_write(&drv_data->regs->tdbr, *buf++);
@@ -1033,12 +1028,6 @@ static int bfin_spi_setup(struct spi_dev
 		chip->ctl_reg &= bfin_ctl_reg;
 	}
 
-	if (spi->bits_per_word % 8) {
-		dev_err(&spi->dev, "%d bits_per_word is not supported\n",
-				spi->bits_per_word);
-		goto error;
-	}
-
 	/* translate common spi framework into our register */
 	if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) {
 		dev_err(&spi->dev, "unsupported spi modes detected\n");
@@ -1299,7 +1288,7 @@ static int bfin_spi_probe(struct platfor
 
 	/* the spi->mode bits supported by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
-
+	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 	master->bus_num = pdev->id;
 	master->num_chipselect = platform_info->num_chipselect;
 	master->cleanup = bfin_spi_cleanup;
@@ -1418,9 +1407,6 @@ static int bfin_spi_remove(struct platfo
 
 	peripheral_free_list(drv_data->pin_req);
 
-	/* Prevent double remove */
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-bfin-sport.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-bfin-sport.c
--- linux-libre-3.10-gnu/drivers/spi/spi-bfin-sport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-bfin-sport.c	2013-08-25 20:43:22.000000000 -0400
@@ -417,7 +417,7 @@ bfin_sport_spi_pump_transfers(unsigned l
 
 	/* Bits per word setup */
 	bits_per_word = transfer->bits_per_word;
-	if (bits_per_word % 16 == 0)
+	if (bits_per_word == 16)
 		drv_data->ops = &bfin_sport_transfer_ops_u16;
 	else
 		drv_data->ops = &bfin_sport_transfer_ops_u8;
@@ -600,13 +600,6 @@ bfin_sport_spi_setup(struct spi_device *
 		}
 	}
 
-	if (spi->bits_per_word % 8) {
-		dev_err(&spi->dev, "%d bits_per_word is not supported\n",
-				spi->bits_per_word);
-		ret = -EINVAL;
-		goto error;
-	}
-
 	/* translate common spi framework into our register
 	 * following configure contents are same for tx and rx.
 	 */
@@ -778,6 +771,7 @@ static int bfin_sport_spi_probe(struct p
 	drv_data->pin_req = platform_info->pin_req;
 
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
+	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 	master->bus_num = pdev->id;
 	master->num_chipselect = platform_info->num_chipselect;
 	master->cleanup = bfin_sport_spi_cleanup;
@@ -882,9 +876,6 @@ static int bfin_sport_spi_remove(struct
 
 	peripheral_free_list(drv_data->pin_req);
 
-	/* Prevent double remove */
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi.c linux-libre-3.11-rc7-gnu/drivers/spi/spi.c
--- linux-libre-3.10-gnu/drivers/spi/spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -223,7 +223,7 @@ static const struct dev_pm_ops spi_pm =
 	SET_RUNTIME_PM_OPS(
 		pm_generic_runtime_suspend,
 		pm_generic_runtime_resume,
-		pm_generic_runtime_idle
+		NULL
 	)
 };
 
@@ -601,7 +601,7 @@ static int spi_init_queue(struct spi_mas
 
 	init_kthread_worker(&master->kworker);
 	master->kworker_task = kthread_run(kthread_worker_fn,
-					   &master->kworker,
+					   &master->kworker, "%s",
 					   dev_name(&master->dev));
 	if (IS_ERR(master->kworker_task)) {
 		dev_err(&master->dev, "failed to create message pump task\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-clps711x.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-clps711x.c
--- linux-libre-3.10-gnu/drivers/spi/spi-clps711x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-clps711x.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,12 +42,6 @@ static int spi_clps711x_setup(struct spi
 {
 	struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master);
 
-	if (spi->bits_per_word != 8) {
-		dev_err(&spi->dev, "Unsupported master bus width %i\n",
-			spi->bits_per_word);
-		return -EINVAL;
-	}
-
 	/* We are expect that SPI-device is not selected */
 	gpio_direction_output(hw->chipselect[spi->chip_select],
 			      !(spi->mode & SPI_CS_HIGH));
@@ -190,6 +184,7 @@ static int spi_clps711x_probe(struct pla
 
 	master->bus_num = pdev->id;
 	master->mode_bits = SPI_CPHA | SPI_CS_HIGH;
+	master->bits_per_word_mask = SPI_BPW_MASK(8);
 	master->num_chipselect = pdata->num_chipselect;
 	master->setup = spi_clps711x_setup;
 	master->transfer_one_message = spi_clps711x_transfer_one_message;
@@ -254,7 +249,6 @@ err_out:
 		if (gpio_is_valid(hw->chipselect[i]))
 			gpio_free(hw->chipselect[i]);
 
-	platform_set_drvdata(pdev, NULL);
 	spi_master_put(master);
 	kfree(master);
 
@@ -274,7 +268,6 @@ static int spi_clps711x_remove(struct pl
 			gpio_free(hw->chipselect[i]);
 
 	devm_clk_put(&pdev->dev, hw->spi_clk);
-	platform_set_drvdata(pdev, NULL);
 	spi_unregister_master(master);
 	kfree(master);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-coldfire-qspi.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-coldfire-qspi.c
--- linux-libre-3.10-gnu/drivers/spi/spi-coldfire-qspi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-coldfire-qspi.c	2013-08-25 20:43:22.000000000 -0400
@@ -312,10 +312,7 @@ static int mcfqspi_transfer_one_message(
 		bool cs_high = spi->mode & SPI_CS_HIGH;
 		u16 qmr = MCFQSPI_QMR_MSTR;
 
-		if (t->bits_per_word)
-			qmr |= t->bits_per_word << 10;
-		else
-			qmr |= spi->bits_per_word << 10;
+		qmr |= t->bits_per_word << 10;
 		if (spi->mode & SPI_CPHA)
 			qmr |= MCFQSPI_QMR_CPHA;
 		if (spi->mode & SPI_CPOL)
@@ -377,11 +374,6 @@ static int mcfqspi_unprepare_transfer_hw
 
 static int mcfqspi_setup(struct spi_device *spi)
 {
-	if ((spi->bits_per_word < 8) || (spi->bits_per_word > 16)) {
-		dev_dbg(&spi->dev, "%d bits per word is not supported\n",
-			spi->bits_per_word);
-		return -EINVAL;
-	}
 	if (spi->chip_select >= spi->master->num_chipselect) {
 		dev_dbg(&spi->dev, "%d chip select is out of range\n",
 			spi->chip_select);
@@ -408,6 +400,12 @@ static int mcfqspi_probe(struct platform
 	struct mcfqspi_platform_data *pdata;
 	int status;
 
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_dbg(&pdev->dev, "platform data is missing\n");
+		return -ENOENT;
+	}
+
 	master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi));
 	if (master == NULL) {
 		dev_dbg(&pdev->dev, "spi_alloc_master failed\n");
@@ -458,11 +456,6 @@ static int mcfqspi_probe(struct platform
 	}
 	clk_enable(mcfqspi->clk);
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		dev_dbg(&pdev->dev, "platform data is missing\n");
-		goto fail4;
-	}
 	master->bus_num = pdata->bus_num;
 	master->num_chipselect = pdata->num_chipselect;
 
@@ -477,6 +470,7 @@ static int mcfqspi_probe(struct platform
 	mcfqspi->dev = &pdev->dev;
 
 	master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16);
 	master->setup = mcfqspi_setup;
 	master->transfer_one_message = mcfqspi_transfer_one_message;
 	master->prepare_transfer_hardware = mcfqspi_prepare_transfer_hw;
@@ -524,7 +518,6 @@ static int mcfqspi_remove(struct platfor
 	/* disable the hardware (set the baud rate to 0) */
 	mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
 
-	platform_set_drvdata(pdev, NULL);
 	mcfqspi_cs_teardown(mcfqspi);
 	clk_disable(mcfqspi->clk);
 	clk_put(mcfqspi->clk);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-davinci.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-davinci.c
--- linux-libre-3.10-gnu/drivers/spi/spi-davinci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-davinci.c	2013-08-25 20:43:22.000000000 -0400
@@ -299,16 +299,15 @@ static int davinci_spi_setup_transfer(st
 	 * Assign function pointer to appropriate transfer method
 	 * 8bit, 16bit or 32bit transfer
 	 */
-	if (bits_per_word <= 8 && bits_per_word >= 2) {
+	if (bits_per_word <= 8) {
 		dspi->get_rx = davinci_spi_rx_buf_u8;
 		dspi->get_tx = davinci_spi_tx_buf_u8;
 		dspi->bytes_per_word[spi->chip_select] = 1;
-	} else if (bits_per_word <= 16 && bits_per_word >= 2) {
+	} else {
 		dspi->get_rx = davinci_spi_rx_buf_u16;
 		dspi->get_tx = davinci_spi_tx_buf_u16;
 		dspi->bytes_per_word[spi->chip_select] = 2;
-	} else
-		return -EINVAL;
+	}
 
 	if (!hz)
 		hz = spi->max_speed_hz;
@@ -610,7 +609,7 @@ static int davinci_spi_bufs(struct spi_d
 		else
 			buf = (void *)t->tx_buf;
 		t->tx_dma = dma_map_single(&spi->dev, buf,
-				t->len, DMA_FROM_DEVICE);
+				t->len, DMA_TO_DEVICE);
 		if (!t->tx_dma) {
 			ret = -EFAULT;
 			goto err_tx_map;
@@ -865,7 +864,7 @@ static int davinci_spi_probe(struct plat
 		goto err;
 	}
 
-	dev_set_drvdata(&pdev->dev, master);
+	platform_set_drvdata(pdev, master);
 
 	dspi = spi_master_get_devdata(master);
 	if (dspi == NULL) {
@@ -933,6 +932,7 @@ static int davinci_spi_probe(struct plat
 	master->dev.of_node = pdev->dev.of_node;
 	master->bus_num = pdev->id;
 	master->num_chipselect = pdata->num_chipselect;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16);
 	master->setup = davinci_spi_setup;
 
 	dspi->bitbang.chipselect = davinci_spi_chipselect;
@@ -1044,7 +1044,7 @@ static int davinci_spi_remove(struct pla
 	struct spi_master *master;
 	struct resource *r;
 
-	master = dev_get_drvdata(&pdev->dev);
+	master = platform_get_drvdata(pdev);
 	dspi = spi_master_get_devdata(master);
 
 	spi_bitbang_stop(&dspi->bitbang);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-dw.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-dw.c
--- linux-libre-3.10-gnu/drivers/spi/spi-dw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-dw.c	2013-08-25 20:43:22.000000000 -0400
@@ -457,19 +457,7 @@ static void pump_transfers(unsigned long
 	}
 	if (transfer->bits_per_word) {
 		bits = transfer->bits_per_word;
-
-		switch (bits) {
-		case 8:
-		case 16:
-			dws->n_bytes = dws->dma_width = bits >> 3;
-			break;
-		default:
-			printk(KERN_ERR "MRST SPI0: unsupported bits:"
-				"%db\n", bits);
-			message->status = -EIO;
-			goto early_exit;
-		}
-
+		dws->n_bytes = dws->dma_width = bits >> 3;
 		cr0 = (bits - 1)
 			| (chip->type << SPI_FRF_OFFSET)
 			| (spi->mode << SPI_MODE_OFFSET)
@@ -629,9 +617,6 @@ static int dw_spi_setup(struct spi_devic
 	struct dw_spi_chip *chip_info = NULL;
 	struct chip_data *chip;
 
-	if (spi->bits_per_word != 8 && spi->bits_per_word != 16)
-		return -EINVAL;
-
 	/* Only alloc on first setup */
 	chip = spi_get_ctldata(spi);
 	if (!chip) {
@@ -660,16 +645,12 @@ static int dw_spi_setup(struct spi_devic
 		chip->enable_dma = chip_info->enable_dma;
 	}
 
-	if (spi->bits_per_word <= 8) {
+	if (spi->bits_per_word == 8) {
 		chip->n_bytes = 1;
 		chip->dma_width = 1;
-	} else if (spi->bits_per_word <= 16) {
+	} else if (spi->bits_per_word == 16) {
 		chip->n_bytes = 2;
 		chip->dma_width = 2;
-	} else {
-		/* Never take >16b case for MRST SPIC */
-		dev_err(&spi->dev, "invalid wordsize\n");
-		return -EINVAL;
 	}
 	chip->bits_per_word = spi->bits_per_word;
 
@@ -824,6 +805,7 @@ int dw_spi_add_host(struct dw_spi *dws)
 	}
 
 	master->mode_bits = SPI_CPOL | SPI_CPHA;
+	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 	master->bus_num = dws->bus_num;
 	master->num_chipselect = dws->num_cs;
 	master->cleanup = dw_spi_cleanup;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-dw-mmio.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-dw-mmio.c
--- linux-libre-3.10-gnu/drivers/spi/spi-dw-mmio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-dw-mmio.c	2013-08-25 20:43:22.000000000 -0400
@@ -111,8 +111,6 @@ static int dw_spi_mmio_remove(struct pla
 	struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev);
 	struct resource *mem;
 
-	platform_set_drvdata(pdev, NULL);
-
 	clk_disable(dwsmmio->clk);
 	clk_put(dwsmmio->clk);
 	dwsmmio->clk = NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-ep93xx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-ep93xx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-ep93xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-ep93xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -296,12 +296,6 @@ static int ep93xx_spi_setup(struct spi_d
 	struct ep93xx_spi *espi = spi_master_get_devdata(spi->master);
 	struct ep93xx_spi_chip *chip;
 
-	if (spi->bits_per_word < 4 || spi->bits_per_word > 16) {
-		dev_err(&espi->pdev->dev, "invalid bits per word %d\n",
-			spi->bits_per_word);
-		return -EINVAL;
-	}
-
 	chip = spi_get_ctldata(spi);
 	if (!chip) {
 		dev_dbg(&espi->pdev->dev, "initial setup for %s\n",
@@ -365,10 +359,6 @@ static int ep93xx_spi_transfer(struct sp
 
 	/* first validate each transfer */
 	list_for_each_entry(t, &msg->transfers, transfer_list) {
-		if (t->bits_per_word) {
-			if (t->bits_per_word < 4 || t->bits_per_word > 16)
-				return -EINVAL;
-		}
 		if (t->speed_hz && t->speed_hz < espi->min_rate)
 				return -EINVAL;
 	}
@@ -1046,6 +1036,7 @@ static int ep93xx_spi_probe(struct platf
 	master->bus_num = pdev->id;
 	master->num_chipselect = info->num_chipselect;
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
 
 	platform_set_drvdata(pdev, master);
 
@@ -1104,6 +1095,7 @@ static int ep93xx_spi_probe(struct platf
 	espi->wq = create_singlethread_workqueue("ep93xx_spid");
 	if (!espi->wq) {
 		dev_err(&pdev->dev, "unable to create workqueue\n");
+		error = -ENOMEM;
 		goto fail_free_dma;
 	}
 	INIT_WORK(&espi->msg_work, ep93xx_spi_work);
@@ -1132,7 +1124,6 @@ fail_put_clock:
 	clk_put(espi->clk);
 fail_release_master:
 	spi_master_put(master);
-	platform_set_drvdata(pdev, NULL);
 
 	return error;
 }
@@ -1167,7 +1158,6 @@ static int ep93xx_spi_remove(struct plat
 
 	ep93xx_spi_release_dma(espi);
 	clk_put(espi->clk);
-	platform_set_drvdata(pdev, NULL);
 
 	spi_unregister_master(master);
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-fsl-espi.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-fsl-espi.c
--- linux-libre-3.10-gnu/drivers/spi/spi-fsl-espi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-fsl-espi.c	2013-08-25 20:43:22.000000000 -0400
@@ -144,10 +144,6 @@ static int fsl_espi_setup_transfer(struc
 	if (!bits_per_word)
 		bits_per_word = spi->bits_per_word;
 
-	/* Make sure its a bit width we support [4..16] */
-	if ((bits_per_word < 4) || (bits_per_word > 16))
-		return -EINVAL;
-
 	if (!hz)
 		hz = spi->max_speed_hz;
 
@@ -157,12 +153,10 @@ static int fsl_espi_setup_transfer(struc
 	cs->get_tx = mpc8xxx_spi_tx_buf_u32;
 	if (bits_per_word <= 8) {
 		cs->rx_shift = 8 - bits_per_word;
-	} else if (bits_per_word <= 16) {
+	} else {
 		cs->rx_shift = 16 - bits_per_word;
 		if (spi->mode & SPI_LSB_FIRST)
 			cs->get_tx = fsl_espi_tx_buf_lsb;
-	} else {
-		return -EINVAL;
 	}
 
 	mpc8xxx_spi->rx_shift = cs->rx_shift;
@@ -609,6 +603,7 @@ static struct spi_master * fsl_espi_prob
 	if (ret)
 		goto err_probe;
 
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
 	master->setup = fsl_espi_setup;
 
 	mpc8xxx_spi = spi_master_get_devdata(master);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-fsl-lib.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-fsl-lib.c
--- linux-libre-3.10-gnu/drivers/spi/spi-fsl-lib.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-fsl-lib.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,7 +61,7 @@ struct mpc8xxx_spi_probe_info *to_of_pin
 	return container_of(pdata, struct mpc8xxx_spi_probe_info, pdata);
 }
 
-void mpc8xxx_spi_work(struct work_struct *work)
+static void mpc8xxx_spi_work(struct work_struct *work)
 {
 	struct mpc8xxx_spi *mpc8xxx_spi = container_of(work, struct mpc8xxx_spi,
 						       work);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-fsl-spi.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-fsl-spi.c
--- linux-libre-3.10-gnu/drivers/spi/spi-fsl-spi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-fsl-spi.c	2013-08-25 20:43:22.000000000 -0400
@@ -853,7 +853,7 @@ err:
 
 static int of_fsl_spi_remove(struct platform_device *ofdev)
 {
-	struct spi_master *master = dev_get_drvdata(&ofdev->dev);
+	struct spi_master *master = platform_get_drvdata(ofdev);
 	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
 	int ret;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-gpio.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-gpio.c
--- linux-libre-3.10-gnu/drivers/spi/spi-gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-gpio.c	2013-08-25 20:43:22.000000000 -0400
@@ -239,9 +239,6 @@ static int spi_gpio_setup(struct spi_dev
 	struct spi_gpio		*spi_gpio = spi_to_spi_gpio(spi);
 	struct device_node	*np = spi->master->dev.of_node;
 
-	if (spi->bits_per_word > 32)
-		return -EINVAL;
-
 	if (np) {
 		/*
 		 * In DT environments, the CS GPIOs have already been
@@ -446,6 +443,7 @@ static int spi_gpio_probe(struct platfor
 	if (pdata)
 		spi_gpio->pdata = *pdata;
 
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
 	master->flags = master_flags;
 	master->bus_num = pdev->id;
 	master->num_chipselect = SPI_N_CHIPSEL;
@@ -514,8 +512,6 @@ static int spi_gpio_remove(struct platfo
 	status = spi_bitbang_stop(&spi_gpio->bitbang);
 	spi_master_put(spi_gpio->bitbang.master);
 
-	platform_set_drvdata(pdev, NULL);
-
 	if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
 		gpio_free(SPI_MISO_GPIO);
 	if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-imx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-imx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-imx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-imx.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,7 +37,6 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
-#include <linux/pinctrl/consumer.h>
 
 #include <linux/platform_data/spi-imx.h>
 
@@ -698,11 +697,10 @@ static int spi_imx_setupxfer(struct spi_
 	} else if (config.bpw <= 16) {
 		spi_imx->rx = spi_imx_buf_rx_u16;
 		spi_imx->tx = spi_imx_buf_tx_u16;
-	} else if (config.bpw <= 32) {
+	} else {
 		spi_imx->rx = spi_imx_buf_rx_u32;
 		spi_imx->tx = spi_imx_buf_tx_u32;
-	} else
-		BUG();
+	}
 
 	spi_imx->devtype_data->config(spi_imx, &config);
 
@@ -760,7 +758,6 @@ static int spi_imx_probe(struct platform
 	struct spi_master *master;
 	struct spi_imx_data *spi_imx;
 	struct resource *res;
-	struct pinctrl *pinctrl;
 	int i, ret, num_cs;
 
 	if (!np && !mxc_platform_info) {
@@ -783,6 +780,7 @@ static int spi_imx_probe(struct platform
 
 	platform_set_drvdata(pdev, master);
 
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
 	master->bus_num = pdev->id;
 	master->num_chipselect = num_cs;
 
@@ -848,12 +846,6 @@ static int spi_imx_probe(struct platform
 		goto out_iounmap;
 	}
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl)) {
-		ret = PTR_ERR(pinctrl);
-		goto out_free_irq;
-	}
-
 	spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
 	if (IS_ERR(spi_imx->clk_ipg)) {
 		ret = PTR_ERR(spi_imx->clk_ipg);
@@ -902,7 +894,6 @@ out_gpio_free:
 	}
 	spi_master_put(master);
 	kfree(master);
-	platform_set_drvdata(pdev, NULL);
 	return ret;
 }
 
@@ -929,8 +920,6 @@ static int spi_imx_remove(struct platfor
 
 	release_mem_region(res->start, resource_size(res));
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-mpc512x-psc.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-mpc512x-psc.c
--- linux-libre-3.10-gnu/drivers/spi/spi-mpc512x-psc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-mpc512x-psc.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,7 +21,6 @@
 #include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
-#include <linux/workqueue.h>
 #include <linux/completion.h>
 #include <linux/io.h>
 #include <linux/delay.h>
@@ -33,24 +32,15 @@
 
 struct mpc512x_psc_spi {
 	void (*cs_control)(struct spi_device *spi, bool on);
-	u32 sysclk;
 
 	/* driver internal data */
 	struct mpc52xx_psc __iomem *psc;
 	struct mpc512x_psc_fifo __iomem *fifo;
 	unsigned int irq;
 	u8 bits_per_word;
-	u8 busy;
 	u32 mclk;
-	u8 eofbyte;
 
-	struct workqueue_struct *workqueue;
-	struct work_struct work;
-
-	struct list_head queue;
-	spinlock_t lock;	/* Message queue lock */
-
-	struct completion done;
+	struct completion txisrdone;
 };
 
 /* controller state */
@@ -136,145 +126,223 @@ static int mpc512x_psc_spi_transfer_rxtx
 					 struct spi_transfer *t)
 {
 	struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
-	struct mpc52xx_psc __iomem *psc = mps->psc;
 	struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
-	size_t len = t->len;
+	size_t tx_len = t->len;
+	size_t rx_len = t->len;
 	u8 *tx_buf = (u8 *)t->tx_buf;
 	u8 *rx_buf = (u8 *)t->rx_buf;
 
 	if (!tx_buf && !rx_buf && t->len)
 		return -EINVAL;
 
-	/* Zero MR2 */
-	in_8(&psc->mode);
-	out_8(&psc->mode, 0x0);
-
-	/* enable transmiter/receiver */
-	out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
-
-	while (len) {
-		int count;
-		int i;
+	while (rx_len || tx_len) {
+		size_t txcount;
 		u8 data;
 		size_t fifosz;
-		int rxcount;
+		size_t rxcount;
+		int rxtries;
 
 		/*
-		 * The number of bytes that can be sent at a time
-		 * depends on the fifo size.
+		 * send the TX bytes in as large a chunk as possible
+		 * but neither exceed the TX nor the RX FIFOs
 		 */
 		fifosz = MPC512x_PSC_FIFO_SZ(in_be32(&fifo->txsz));
-		count = min(fifosz, len);
+		txcount = min(fifosz, tx_len);
+		fifosz = MPC512x_PSC_FIFO_SZ(in_be32(&fifo->rxsz));
+		fifosz -= in_be32(&fifo->rxcnt) + 1;
+		txcount = min(fifosz, txcount);
+		if (txcount) {
 
-		for (i = count; i > 0; i--) {
-			data = tx_buf ? *tx_buf++ : 0;
-			if (len == EOFBYTE && t->cs_change)
-				setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF);
-			out_8(&fifo->txdata_8, data);
-			len--;
-		}
+			/* fill the TX FIFO */
+			while (txcount-- > 0) {
+				data = tx_buf ? *tx_buf++ : 0;
+				if (tx_len == EOFBYTE && t->cs_change)
+					setbits32(&fifo->txcmd,
+						  MPC512x_PSC_FIFO_EOF);
+				out_8(&fifo->txdata_8, data);
+				tx_len--;
+			}
 
-		INIT_COMPLETION(mps->done);
+			/* have the ISR trigger when the TX FIFO is empty */
+			INIT_COMPLETION(mps->txisrdone);
+			out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
+			out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY);
+			wait_for_completion(&mps->txisrdone);
+		}
 
-		/* interrupt on tx fifo empty */
-		out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
-		out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY);
+		/*
+		 * consume as much RX data as the FIFO holds, while we
+		 * iterate over the transfer's TX data length
+		 *
+		 * only insist in draining all the remaining RX bytes
+		 * when the TX bytes were exhausted (that's at the very
+		 * end of this transfer, not when still iterating over
+		 * the transfer's chunks)
+		 */
+		rxtries = 50;
+		do {
 
-		wait_for_completion(&mps->done);
+			/*
+			 * grab whatever was in the FIFO when we started
+			 * looking, don't bother fetching what was added to
+			 * the FIFO while we read from it -- we'll return
+			 * here eventually and prefer sending out remaining
+			 * TX data
+			 */
+			fifosz = in_be32(&fifo->rxcnt);
+			rxcount = min(fifosz, rx_len);
+			while (rxcount-- > 0) {
+				data = in_8(&fifo->rxdata_8);
+				if (rx_buf)
+					*rx_buf++ = data;
+				rx_len--;
+			}
 
-		mdelay(1);
+			/*
+			 * come back later if there still is TX data to send,
+			 * bail out of the RX drain loop if all of the TX data
+			 * was sent and all of the RX data was received (i.e.
+			 * when the transmission has completed)
+			 */
+			if (tx_len)
+				break;
+			if (!rx_len)
+				break;
 
-		/* rx fifo should have count bytes in it */
-		rxcount = in_be32(&fifo->rxcnt);
-		if (rxcount != count)
-			mdelay(1);
+			/*
+			 * TX data transmission has completed while RX data
+			 * is still pending -- that's a transient situation
+			 * which depends on wire speed and specific
+			 * hardware implementation details (buffering) yet
+			 * should resolve very quickly
+			 *
+			 * just yield for a moment to not hog the CPU for
+			 * too long when running SPI at low speed
+			 *
+			 * the timeout range is rather arbitrary and tries
+			 * to balance throughput against system load; the
+			 * chosen values result in a minimal timeout of 50
+			 * times 10us and thus work at speeds as low as
+			 * some 20kbps, while the maximum timeout at the
+			 * transfer's end could be 5ms _if_ nothing else
+			 * ticks in the system _and_ RX data still wasn't
+			 * received, which only occurs in situations that
+			 * are exceptional; removing the unpredictability
+			 * of the timeout either decreases throughput
+			 * (longer timeouts), or puts more load on the
+			 * system (fixed short timeouts) or requires the
+			 * use of a timeout API instead of a counter and an
+			 * unknown inner delay
+			 */
+			usleep_range(10, 100);
 
-		rxcount = in_be32(&fifo->rxcnt);
-		if (rxcount != count) {
-			dev_warn(&spi->dev, "expected %d bytes in rx fifo "
-				 "but got %d\n", count, rxcount);
+		} while (--rxtries > 0);
+		if (!tx_len && rx_len && !rxtries) {
+			/*
+			 * not enough RX bytes even after several retries
+			 * and the resulting rather long timeout?
+			 */
+			rxcount = in_be32(&fifo->rxcnt);
+			dev_warn(&spi->dev,
+				 "short xfer, missing %zd RX bytes, FIFO level %zd\n",
+				 rx_len, rxcount);
 		}
 
-		rxcount = min(rxcount, count);
-		for (i = rxcount; i > 0; i--) {
-			data = in_8(&fifo->rxdata_8);
-			if (rx_buf)
-				*rx_buf++ = data;
-		}
-		while (in_be32(&fifo->rxcnt)) {
-			in_8(&fifo->rxdata_8);
+		/*
+		 * drain and drop RX data which "should not be there" in
+		 * the first place, for undisturbed transmission this turns
+		 * into a NOP (except for the FIFO level fetch)
+		 */
+		if (!tx_len && !rx_len) {
+			while (in_be32(&fifo->rxcnt))
+				in_8(&fifo->rxdata_8);
 		}
+
 	}
-	/* disable transmiter/receiver and fifo interrupt */
-	out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
-	out_be32(&fifo->tximr, 0);
 	return 0;
 }
 
-static void mpc512x_psc_spi_work(struct work_struct *work)
+static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
+				    struct spi_message *m)
 {
-	struct mpc512x_psc_spi *mps = container_of(work,
-						   struct mpc512x_psc_spi,
-						   work);
+	struct spi_device *spi;
+	unsigned cs_change;
+	int status;
+	struct spi_transfer *t;
 
-	spin_lock_irq(&mps->lock);
-	mps->busy = 1;
-	while (!list_empty(&mps->queue)) {
-		struct spi_message *m;
-		struct spi_device *spi;
-		struct spi_transfer *t = NULL;
-		unsigned cs_change;
-		int status;
+	spi = m->spi;
+	cs_change = 1;
+	status = 0;
+	list_for_each_entry(t, &m->transfers, transfer_list) {
+		if (t->bits_per_word || t->speed_hz) {
+			status = mpc512x_psc_spi_transfer_setup(spi, t);
+			if (status < 0)
+				break;
+		}
 
-		m = container_of(mps->queue.next, struct spi_message, queue);
-		list_del_init(&m->queue);
-		spin_unlock_irq(&mps->lock);
+		if (cs_change)
+			mpc512x_psc_spi_activate_cs(spi);
+		cs_change = t->cs_change;
 
-		spi = m->spi;
-		cs_change = 1;
-		status = 0;
-		list_for_each_entry(t, &m->transfers, transfer_list) {
-			if (t->bits_per_word || t->speed_hz) {
-				status = mpc512x_psc_spi_transfer_setup(spi, t);
-				if (status < 0)
-					break;
-			}
+		status = mpc512x_psc_spi_transfer_rxtx(spi, t);
+		if (status)
+			break;
+		m->actual_length += t->len;
 
-			if (cs_change)
-				mpc512x_psc_spi_activate_cs(spi);
-			cs_change = t->cs_change;
+		if (t->delay_usecs)
+			udelay(t->delay_usecs);
 
-			status = mpc512x_psc_spi_transfer_rxtx(spi, t);
-			if (status)
-				break;
-			m->actual_length += t->len;
+		if (cs_change)
+			mpc512x_psc_spi_deactivate_cs(spi);
+	}
 
-			if (t->delay_usecs)
-				udelay(t->delay_usecs);
+	m->status = status;
+	m->complete(m->context);
 
-			if (cs_change)
-				mpc512x_psc_spi_deactivate_cs(spi);
-		}
+	if (status || !cs_change)
+		mpc512x_psc_spi_deactivate_cs(spi);
 
-		m->status = status;
-		m->complete(m->context);
+	mpc512x_psc_spi_transfer_setup(spi, NULL);
 
-		if (status || !cs_change)
-			mpc512x_psc_spi_deactivate_cs(spi);
+	spi_finalize_current_message(master);
+	return status;
+}
 
-		mpc512x_psc_spi_transfer_setup(spi, NULL);
+static int mpc512x_psc_spi_prep_xfer_hw(struct spi_master *master)
+{
+	struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
+	struct mpc52xx_psc __iomem *psc = mps->psc;
 
-		spin_lock_irq(&mps->lock);
-	}
-	mps->busy = 0;
-	spin_unlock_irq(&mps->lock);
+	dev_dbg(&master->dev, "%s()\n", __func__);
+
+	/* Zero MR2 */
+	in_8(&psc->mode);
+	out_8(&psc->mode, 0x0);
+
+	/* enable transmitter/receiver */
+	out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
+
+	return 0;
+}
+
+static int mpc512x_psc_spi_unprep_xfer_hw(struct spi_master *master)
+{
+	struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
+	struct mpc52xx_psc __iomem *psc = mps->psc;
+	struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
+
+	dev_dbg(&master->dev, "%s()\n", __func__);
+
+	/* disable transmitter/receiver and fifo interrupt */
+	out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
+	out_be32(&fifo->tximr, 0);
+
+	return 0;
 }
 
 static int mpc512x_psc_spi_setup(struct spi_device *spi)
 {
-	struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
 	struct mpc512x_psc_spi_cs *cs = spi->controller_state;
-	unsigned long flags;
 	int ret;
 
 	if (spi->bits_per_word % 8)
@@ -303,28 +371,6 @@ static int mpc512x_psc_spi_setup(struct
 	cs->bits_per_word = spi->bits_per_word;
 	cs->speed_hz = spi->max_speed_hz;
 
-	spin_lock_irqsave(&mps->lock, flags);
-	if (!mps->busy)
-		mpc512x_psc_spi_deactivate_cs(spi);
-	spin_unlock_irqrestore(&mps->lock, flags);
-
-	return 0;
-}
-
-static int mpc512x_psc_spi_transfer(struct spi_device *spi,
-				    struct spi_message *m)
-{
-	struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
-	unsigned long flags;
-
-	m->actual_length = 0;
-	m->status = -EINPROGRESS;
-
-	spin_lock_irqsave(&mps->lock, flags);
-	list_add_tail(&m->queue, &mps->queue);
-	queue_work(mps->workqueue, &mps->work);
-	spin_unlock_irqrestore(&mps->lock, flags);
-
 	return 0;
 }
 
@@ -407,12 +453,12 @@ static irqreturn_t mpc512x_psc_spi_isr(i
 	struct mpc512x_psc_spi *mps = (struct mpc512x_psc_spi *)dev_id;
 	struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
 
-	/* clear interrupt and wake up the work queue */
+	/* clear interrupt and wake up the rx/tx routine */
 	if (in_be32(&fifo->txisr) &
 	    in_be32(&fifo->tximr) & MPC512x_PSC_FIFO_EMPTY) {
 		out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
 		out_be32(&fifo->tximr, 0);
-		complete(&mps->done);
+		complete(&mps->txisrdone);
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
@@ -444,18 +490,18 @@ static int mpc512x_psc_spi_do_probe(stru
 
 	if (pdata == NULL) {
 		mps->cs_control = mpc512x_spi_cs_control;
-		mps->sysclk = 0;
 		master->bus_num = bus_num;
 	} else {
 		mps->cs_control = pdata->cs_control;
-		mps->sysclk = pdata->sysclk;
 		master->bus_num = pdata->bus_num;
 		master->num_chipselect = pdata->max_chipselect;
 	}
 
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
 	master->setup = mpc512x_psc_spi_setup;
-	master->transfer = mpc512x_psc_spi_transfer;
+	master->prepare_transfer_hardware = mpc512x_psc_spi_prep_xfer_hw;
+	master->transfer_one_message = mpc512x_psc_spi_msg_xfer;
+	master->unprepare_transfer_hardware = mpc512x_psc_spi_unprep_xfer_hw;
 	master->cleanup = mpc512x_psc_spi_cleanup;
 	master->dev.of_node = dev->of_node;
 
@@ -473,31 +519,18 @@ static int mpc512x_psc_spi_do_probe(stru
 			  "mpc512x-psc-spi", mps);
 	if (ret)
 		goto free_master;
+	init_completion(&mps->txisrdone);
 
 	ret = mpc512x_psc_spi_port_config(master, mps);
 	if (ret < 0)
 		goto free_irq;
 
-	spin_lock_init(&mps->lock);
-	init_completion(&mps->done);
-	INIT_WORK(&mps->work, mpc512x_psc_spi_work);
-	INIT_LIST_HEAD(&mps->queue);
-
-	mps->workqueue =
-		create_singlethread_workqueue(dev_name(master->dev.parent));
-	if (mps->workqueue == NULL) {
-		ret = -EBUSY;
-		goto free_irq;
-	}
-
 	ret = spi_register_master(master);
 	if (ret < 0)
-		goto unreg_master;
+		goto free_irq;
 
 	return ret;
 
-unreg_master:
-	destroy_workqueue(mps->workqueue);
 free_irq:
 	free_irq(mps->irq, mps);
 free_master:
@@ -513,8 +546,6 @@ static int mpc512x_psc_spi_do_remove(str
 	struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
 	struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
 
-	flush_workqueue(mps->workqueue);
-	destroy_workqueue(mps->workqueue);
 	spi_unregister_master(master);
 	free_irq(mps->irq, mps);
 	if (mps->psc)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-mpc52xx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-mpc52xx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-mpc52xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-mpc52xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -438,7 +438,7 @@ static int mpc52xx_spi_probe(struct plat
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
 	master->dev.of_node = op->dev.of_node;
 
-	dev_set_drvdata(&op->dev, master);
+	platform_set_drvdata(op, master);
 
 	ms = spi_master_get_devdata(master);
 	ms->master = master;
@@ -529,7 +529,7 @@ static int mpc52xx_spi_probe(struct plat
 
 static int mpc52xx_spi_remove(struct platform_device *op)
 {
-	struct spi_master *master = spi_master_get(dev_get_drvdata(&op->dev));
+	struct spi_master *master = spi_master_get(platform_get_drvdata(op));
 	struct mpc52xx_spi *ms = spi_master_get_devdata(master);
 	int i;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-mpc52xx-psc.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-mpc52xx-psc.c
--- linux-libre-3.10-gnu/drivers/spi/spi-mpc52xx-psc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-mpc52xx-psc.c	2013-08-25 20:43:22.000000000 -0400
@@ -481,7 +481,7 @@ static int mpc52xx_psc_spi_of_probe(stru
 
 static int mpc52xx_psc_spi_of_remove(struct platform_device *op)
 {
-	struct spi_master *master = spi_master_get(dev_get_drvdata(&op->dev));
+	struct spi_master *master = spi_master_get(platform_get_drvdata(op));
 	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(master);
 
 	flush_workqueue(mps->workqueue);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-mxs.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-mxs.c
--- linux-libre-3.10-gnu/drivers/spi/spi-mxs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-mxs.c	2013-08-25 20:43:22.000000000 -0400
@@ -46,7 +46,6 @@
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/module.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/stmp_device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/mxs-spi.h>
@@ -75,12 +74,6 @@ static int mxs_spi_setup_transfer(struct
 	if (t && t->bits_per_word)
 		bits_per_word = t->bits_per_word;
 
-	if (bits_per_word != 8) {
-		dev_err(&dev->dev, "%s, unsupported bits_per_word=%d\n",
-					__func__, bits_per_word);
-		return -EINVAL;
-	}
-
 	hz = dev->max_speed_hz;
 	if (t && t->speed_hz)
 		hz = min(hz, t->speed_hz);
@@ -506,7 +499,6 @@ static int mxs_spi_probe(struct platform
 	struct mxs_spi *spi;
 	struct mxs_ssp *ssp;
 	struct resource *iores;
-	struct pinctrl *pinctrl;
 	struct clk *clk;
 	void __iomem *base;
 	int devid, clk_freq;
@@ -528,10 +520,6 @@ static int mxs_spi_probe(struct platform
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl))
-		return PTR_ERR(pinctrl);
-
 	clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
@@ -548,6 +536,7 @@ static int mxs_spi_probe(struct platform
 
 	master->transfer_one_message = mxs_spi_transfer_one;
 	master->setup = mxs_spi_setup;
+	master->bits_per_word_mask = SPI_BPW_MASK(8);
 	master->mode_bits = SPI_CPOL | SPI_CPHA;
 	master->num_chipselect = 3;
 	master->dev.of_node = np;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-nuc900.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-nuc900.c
--- linux-libre-3.10-gnu/drivers/spi/spi-nuc900.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-nuc900.c	2013-08-25 20:43:22.000000000 -0400
@@ -459,8 +459,6 @@ static int nuc900_spi_remove(struct plat
 
 	free_irq(hw->irq, hw);
 
-	platform_set_drvdata(dev, NULL);
-
 	spi_bitbang_stop(&hw->bitbang);
 
 	clk_disable(hw->clk);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-oc-tiny.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-oc-tiny.c
--- linux-libre-3.10-gnu/drivers/spi/spi-oc-tiny.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-oc-tiny.c	2013-08-25 20:43:22.000000000 -0400
@@ -368,7 +368,6 @@ exit_gpio:
 exit_busy:
 	err = -EBUSY;
 exit:
-	platform_set_drvdata(pdev, NULL);
 	spi_master_put(master);
 	return err;
 }
@@ -382,7 +381,6 @@ static int tiny_spi_remove(struct platfo
 	spi_bitbang_stop(&hw->bitbang);
 	for (i = 0; i < hw->gpio_cs_count; i++)
 		gpio_free(hw->gpio_cs[i]);
-	platform_set_drvdata(pdev, NULL);
 	spi_master_put(master);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-omap-100k.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-omap-100k.c
--- linux-libre-3.10-gnu/drivers/spi/spi-omap-100k.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-omap-100k.c	2013-08-25 20:43:22.000000000 -0400
@@ -298,12 +298,6 @@ static int omap1_spi100k_setup(struct sp
 	struct omap1_spi100k    *spi100k;
 	struct omap1_spi100k_cs *cs = spi->controller_state;
 
-	if (spi->bits_per_word < 4 || spi->bits_per_word > 32) {
-		 dev_dbg(&spi->dev, "setup: unsupported %d bit words\n",
-			spi->bits_per_word);
-		 return -EINVAL;
-	}
-
 	spi100k = spi_master_get_devdata(spi->master);
 
 	if (!cs) {
@@ -451,10 +445,7 @@ static int omap1_spi100k_transfer(struct
 		unsigned        len = t->len;
 
 		if (t->speed_hz > OMAP1_SPI100K_MAX_FREQ
-				|| (len && !(rx_buf || tx_buf))
-				|| (t->bits_per_word &&
-					(  t->bits_per_word < 4
-					|| t->bits_per_word > 32))) {
+				|| (len && !(rx_buf || tx_buf))) {
 			dev_dbg(&spi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",
 					t->speed_hz,
 					len,
@@ -509,8 +500,9 @@ static int omap1_spi100k_probe(struct pl
 	master->cleanup = NULL;
 	master->num_chipselect = 2;
 	master->mode_bits = MODEBITS;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
 
-	dev_set_drvdata(&pdev->dev, master);
+	platform_set_drvdata(pdev, master);
 
 	spi100k = spi_master_get_devdata(master);
 	spi100k->master = master;
@@ -569,7 +561,7 @@ static int omap1_spi100k_remove(struct p
 	unsigned long		flags;
 	int			status = 0;
 
-	master = dev_get_drvdata(&pdev->dev);
+	master = platform_get_drvdata(pdev);
 	spi100k = spi_master_get_devdata(master);
 
 	spin_lock_irqsave(&spi100k->lock, flags);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-omap2-mcspi.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-omap2-mcspi.c
--- linux-libre-3.10-gnu/drivers/spi/spi-omap2-mcspi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-omap2-mcspi.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,13 +38,15 @@
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/pinctrl/consumer.h>
+#include <linux/gcd.h>
 
 #include <linux/spi/spi.h>
 
 #include <linux/platform_data/spi-omap2-mcspi.h>
 
 #define OMAP2_MCSPI_MAX_FREQ		48000000
+#define OMAP2_MCSPI_MAX_FIFODEPTH	64
+#define OMAP2_MCSPI_MAX_FIFOWCNT	0xFFFF
 #define SPI_AUTOSUSPEND_TIMEOUT		2000
 
 #define OMAP2_MCSPI_REVISION		0x00
@@ -54,6 +56,7 @@
 #define OMAP2_MCSPI_WAKEUPENABLE	0x20
 #define OMAP2_MCSPI_SYST		0x24
 #define OMAP2_MCSPI_MODULCTRL		0x28
+#define OMAP2_MCSPI_XFERLEVEL		0x7c
 
 /* per-channel banks, 0x14 bytes each, first is: */
 #define OMAP2_MCSPI_CHCONF0		0x2c
@@ -63,6 +66,7 @@
 #define OMAP2_MCSPI_RX0			0x3c
 
 /* per-register bitmasks: */
+#define OMAP2_MCSPI_IRQSTATUS_EOW	BIT(17)
 
 #define OMAP2_MCSPI_MODULCTRL_SINGLE	BIT(0)
 #define OMAP2_MCSPI_MODULCTRL_MS	BIT(2)
@@ -83,10 +87,13 @@
 #define OMAP2_MCSPI_CHCONF_IS		BIT(18)
 #define OMAP2_MCSPI_CHCONF_TURBO	BIT(19)
 #define OMAP2_MCSPI_CHCONF_FORCE	BIT(20)
+#define OMAP2_MCSPI_CHCONF_FFET		BIT(27)
+#define OMAP2_MCSPI_CHCONF_FFER		BIT(28)
 
 #define OMAP2_MCSPI_CHSTAT_RXS		BIT(0)
 #define OMAP2_MCSPI_CHSTAT_TXS		BIT(1)
 #define OMAP2_MCSPI_CHSTAT_EOT		BIT(2)
+#define OMAP2_MCSPI_CHSTAT_TXFFE	BIT(3)
 
 #define OMAP2_MCSPI_CHCTRL_EN		BIT(0)
 
@@ -102,6 +109,9 @@ struct omap2_mcspi_dma {
 
 	struct completion dma_tx_completion;
 	struct completion dma_rx_completion;
+
+	char dma_rx_ch_name[14];
+	char dma_tx_ch_name[14];
 };
 
 /* use PIO for small transfers, avoiding DMA setup/teardown overhead and
@@ -129,6 +139,7 @@ struct omap2_mcspi {
 	struct omap2_mcspi_dma	*dma_channels;
 	struct device		*dev;
 	struct omap2_mcspi_regs ctx;
+	int			fifo_depth;
 	unsigned int		pin_dir:1;
 };
 
@@ -187,6 +198,16 @@ static inline void mcspi_write_chconf0(c
 	mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0);
 }
 
+static inline int mcspi_bytes_per_word(int word_len)
+{
+	if (word_len <= 8)
+		return 1;
+	else if (word_len <= 16)
+		return 2;
+	else /* word_len <= 32 */
+		return 4;
+}
+
 static void omap2_mcspi_set_dma_req(const struct spi_device *spi,
 		int is_read, int enable)
 {
@@ -248,6 +269,58 @@ static void omap2_mcspi_set_master_mode(
 	ctx->modulctrl = l;
 }
 
+static void omap2_mcspi_set_fifo(const struct spi_device *spi,
+				struct spi_transfer *t, int enable)
+{
+	struct spi_master *master = spi->master;
+	struct omap2_mcspi_cs *cs = spi->controller_state;
+	struct omap2_mcspi *mcspi;
+	unsigned int wcnt;
+	int fifo_depth, bytes_per_word;
+	u32 chconf, xferlevel;
+
+	mcspi = spi_master_get_devdata(master);
+
+	chconf = mcspi_cached_chconf0(spi);
+	if (enable) {
+		bytes_per_word = mcspi_bytes_per_word(cs->word_len);
+		if (t->len % bytes_per_word != 0)
+			goto disable_fifo;
+
+		fifo_depth = gcd(t->len, OMAP2_MCSPI_MAX_FIFODEPTH);
+		if (fifo_depth < 2 || fifo_depth % bytes_per_word != 0)
+			goto disable_fifo;
+
+		wcnt = t->len / bytes_per_word;
+		if (wcnt > OMAP2_MCSPI_MAX_FIFOWCNT)
+			goto disable_fifo;
+
+		xferlevel = wcnt << 16;
+		if (t->rx_buf != NULL) {
+			chconf |= OMAP2_MCSPI_CHCONF_FFER;
+			xferlevel |= (fifo_depth - 1) << 8;
+		} else {
+			chconf |= OMAP2_MCSPI_CHCONF_FFET;
+			xferlevel |= fifo_depth - 1;
+		}
+
+		mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL, xferlevel);
+		mcspi_write_chconf0(spi, chconf);
+		mcspi->fifo_depth = fifo_depth;
+
+		return;
+	}
+
+disable_fifo:
+	if (t->rx_buf != NULL)
+		chconf &= ~OMAP2_MCSPI_CHCONF_FFER;
+	else
+		chconf &= ~OMAP2_MCSPI_CHCONF_FFET;
+
+	mcspi_write_chconf0(spi, chconf);
+	mcspi->fifo_depth = 0;
+}
+
 static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
 {
 	struct spi_master	*spi_cntrl = mcspi->master;
@@ -364,7 +437,7 @@ omap2_mcspi_rx_dma(struct spi_device *sp
 {
 	struct omap2_mcspi	*mcspi;
 	struct omap2_mcspi_dma  *mcspi_dma;
-	unsigned int		count;
+	unsigned int		count, dma_count;
 	u32			l;
 	int			elements = 0;
 	int			word_len, element_count;
@@ -372,6 +445,11 @@ omap2_mcspi_rx_dma(struct spi_device *sp
 	mcspi = spi_master_get_devdata(spi->master);
 	mcspi_dma = &mcspi->dma_channels[spi->chip_select];
 	count = xfer->len;
+	dma_count = xfer->len;
+
+	if (mcspi->fifo_depth == 0)
+		dma_count -= es;
+
 	word_len = cs->word_len;
 	l = mcspi_cached_chconf0(spi);
 
@@ -385,16 +463,15 @@ omap2_mcspi_rx_dma(struct spi_device *sp
 	if (mcspi_dma->dma_rx) {
 		struct dma_async_tx_descriptor *tx;
 		struct scatterlist sg;
-		size_t len = xfer->len - es;
 
 		dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
 
-		if (l & OMAP2_MCSPI_CHCONF_TURBO)
-			len -= es;
+		if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0)
+			dma_count -= es;
 
 		sg_init_table(&sg, 1);
 		sg_dma_address(&sg) = xfer->rx_dma;
-		sg_dma_len(&sg) = len;
+		sg_dma_len(&sg) = dma_count;
 
 		tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1,
 				DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT |
@@ -414,6 +491,10 @@ omap2_mcspi_rx_dma(struct spi_device *sp
 	wait_for_completion(&mcspi_dma->dma_rx_completion);
 	dma_unmap_single(mcspi->dev, xfer->rx_dma, count,
 			 DMA_FROM_DEVICE);
+
+	if (mcspi->fifo_depth > 0)
+		return count;
+
 	omap2_mcspi_set_enable(spi, 0);
 
 	elements = element_count - 1;
@@ -433,10 +514,9 @@ omap2_mcspi_rx_dma(struct spi_device *sp
 			else /* word_len <= 32 */
 				((u32 *)xfer->rx_buf)[elements++] = w;
 		} else {
+			int bytes_per_word = mcspi_bytes_per_word(word_len);
 			dev_err(&spi->dev, "DMA RX penultimate word empty");
-			count -= (word_len <= 8)  ? 2 :
-				(word_len <= 16) ? 4 :
-				/* word_len <= 32 */ 8;
+			count -= (bytes_per_word << 1);
 			omap2_mcspi_set_enable(spi, 1);
 			return count;
 		}
@@ -454,9 +534,7 @@ omap2_mcspi_rx_dma(struct spi_device *sp
 			((u32 *)xfer->rx_buf)[elements] = w;
 	} else {
 		dev_err(&spi->dev, "DMA RX last word empty");
-		count -= (word_len <= 8)  ? 1 :
-			 (word_len <= 16) ? 2 :
-		       /* word_len <= 32 */ 4;
+		count -= mcspi_bytes_per_word(word_len);
 	}
 	omap2_mcspi_set_enable(spi, 1);
 	return count;
@@ -475,7 +553,10 @@ omap2_mcspi_txrx_dma(struct spi_device *
 	struct dma_slave_config	cfg;
 	enum dma_slave_buswidth width;
 	unsigned es;
+	u32			burst;
 	void __iomem		*chstat_reg;
+	void __iomem            *irqstat_reg;
+	int			wait_res;
 
 	mcspi = spi_master_get_devdata(spi->master);
 	mcspi_dma = &mcspi->dma_channels[spi->chip_select];
@@ -493,19 +574,27 @@ omap2_mcspi_txrx_dma(struct spi_device *
 		es = 4;
 	}
 
+	count = xfer->len;
+	burst = 1;
+
+	if (mcspi->fifo_depth > 0) {
+		if (count > mcspi->fifo_depth)
+			burst = mcspi->fifo_depth / es;
+		else
+			burst = count / es;
+	}
+
 	memset(&cfg, 0, sizeof(cfg));
 	cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0;
 	cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0;
 	cfg.src_addr_width = width;
 	cfg.dst_addr_width = width;
-	cfg.src_maxburst = 1;
-	cfg.dst_maxburst = 1;
+	cfg.src_maxburst = burst;
+	cfg.dst_maxburst = burst;
 
 	rx = xfer->rx_buf;
 	tx = xfer->tx_buf;
 
-	count = xfer->len;
-
 	if (tx != NULL)
 		omap2_mcspi_tx_dma(spi, xfer, cfg);
 
@@ -513,18 +602,38 @@ omap2_mcspi_txrx_dma(struct spi_device *
 		count = omap2_mcspi_rx_dma(spi, xfer, cfg, es);
 
 	if (tx != NULL) {
-		chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
 		wait_for_completion(&mcspi_dma->dma_tx_completion);
 		dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len,
 				 DMA_TO_DEVICE);
 
+		if (mcspi->fifo_depth > 0) {
+			irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS;
+
+			if (mcspi_wait_for_reg_bit(irqstat_reg,
+						OMAP2_MCSPI_IRQSTATUS_EOW) < 0)
+				dev_err(&spi->dev, "EOW timed out\n");
+
+			mcspi_write_reg(mcspi->master, OMAP2_MCSPI_IRQSTATUS,
+					OMAP2_MCSPI_IRQSTATUS_EOW);
+		}
+
 		/* for TX_ONLY mode, be sure all words have shifted out */
 		if (rx == NULL) {
-			if (mcspi_wait_for_reg_bit(chstat_reg,
-						OMAP2_MCSPI_CHSTAT_TXS) < 0)
-				dev_err(&spi->dev, "TXS timed out\n");
-			else if (mcspi_wait_for_reg_bit(chstat_reg,
-						OMAP2_MCSPI_CHSTAT_EOT) < 0)
+			chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
+			if (mcspi->fifo_depth > 0) {
+				wait_res = mcspi_wait_for_reg_bit(chstat_reg,
+						OMAP2_MCSPI_CHSTAT_TXFFE);
+				if (wait_res < 0)
+					dev_err(&spi->dev, "TXFFE timed out\n");
+			} else {
+				wait_res = mcspi_wait_for_reg_bit(chstat_reg,
+						OMAP2_MCSPI_CHSTAT_TXS);
+				if (wait_res < 0)
+					dev_err(&spi->dev, "TXS timed out\n");
+			}
+			if (wait_res >= 0 &&
+				(mcspi_wait_for_reg_bit(chstat_reg,
+					OMAP2_MCSPI_CHSTAT_EOT) < 0))
 				dev_err(&spi->dev, "EOT timed out\n");
 		}
 	}
@@ -830,12 +939,20 @@ static int omap2_mcspi_request_dma(struc
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 	sig = mcspi_dma->dma_rx_sync_dev;
-	mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+
+	mcspi_dma->dma_rx =
+		dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+						 &sig, &master->dev,
+						 mcspi_dma->dma_rx_ch_name);
 	if (!mcspi_dma->dma_rx)
 		goto no_dma;
 
 	sig = mcspi_dma->dma_tx_sync_dev;
-	mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+	mcspi_dma->dma_tx =
+		dma_request_slave_channel_compat(mask, omap_dma_filter_fn,
+						 &sig, &master->dev,
+						 mcspi_dma->dma_tx_ch_name);
+
 	if (!mcspi_dma->dma_tx) {
 		dma_release_channel(mcspi_dma->dma_rx);
 		mcspi_dma->dma_rx = NULL;
@@ -857,12 +974,6 @@ static int omap2_mcspi_setup(struct spi_
 	struct omap2_mcspi_dma	*mcspi_dma;
 	struct omap2_mcspi_cs	*cs = spi->controller_state;
 
-	if (spi->bits_per_word < 4 || spi->bits_per_word > 32) {
-		dev_dbg(&spi->dev, "setup: unsupported %d bit words\n",
-			spi->bits_per_word);
-		return -EINVAL;
-	}
-
 	mcspi_dma = &mcspi->dma_channels[spi->chip_select];
 
 	if (!cs) {
@@ -951,7 +1062,7 @@ static void omap2_mcspi_work(struct omap
 	cs = spi->controller_state;
 	cd = spi->controller_data;
 
-	omap2_mcspi_set_enable(spi, 1);
+	omap2_mcspi_set_enable(spi, 0);
 	list_for_each_entry(t, &m->transfers, transfer_list) {
 		if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
 			status = -EINVAL;
@@ -999,6 +1110,12 @@ static void omap2_mcspi_work(struct omap
 		if (t->len) {
 			unsigned	count;
 
+			if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) &&
+			    (m->is_dma_mapped || t->len >= DMA_MIN_BYTES))
+				omap2_mcspi_set_fifo(spi, t, 1);
+
+			omap2_mcspi_set_enable(spi, 1);
+
 			/* RX_ONLY mode needs dummy data in TX reg */
 			if (t->tx_buf == NULL)
 				__raw_writel(0, cs->base
@@ -1025,6 +1142,11 @@ static void omap2_mcspi_work(struct omap
 			omap2_mcspi_force_cs(spi, 0);
 			cs_active = 0;
 		}
+
+		omap2_mcspi_set_enable(spi, 0);
+
+		if (mcspi->fifo_depth > 0)
+			omap2_mcspi_set_fifo(spi, t, 0);
 	}
 	/* Restore defaults if they were overriden */
 	if (par_override) {
@@ -1045,8 +1167,10 @@ static void omap2_mcspi_work(struct omap
 
 	omap2_mcspi_set_enable(spi, 0);
 
-	m->status = status;
+	if (mcspi->fifo_depth > 0 && t)
+		omap2_mcspi_set_fifo(spi, t, 0);
 
+	m->status = status;
 }
 
 static int omap2_mcspi_transfer_one_message(struct spi_master *master,
@@ -1072,10 +1196,7 @@ static int omap2_mcspi_transfer_one_mess
 		unsigned	len = t->len;
 
 		if (t->speed_hz > OMAP2_MCSPI_MAX_FREQ
-				|| (len && !(rx_buf || tx_buf))
-				|| (t->bits_per_word &&
-					(  t->bits_per_word < 4
-					   || t->bits_per_word > 32))) {
+				|| (len && !(rx_buf || tx_buf))) {
 			dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n",
 					t->speed_hz,
 					len,
@@ -1186,7 +1307,6 @@ static int omap2_mcspi_probe(struct plat
 	static int		bus_num = 1;
 	struct device_node	*node = pdev->dev.of_node;
 	const struct of_device_id *match;
-	struct pinctrl *pinctrl;
 
 	master = spi_alloc_master(&pdev->dev, sizeof *mcspi);
 	if (master == NULL) {
@@ -1196,7 +1316,7 @@ static int omap2_mcspi_probe(struct plat
 
 	/* the spi->mode bits understood by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
-
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
 	master->setup = omap2_mcspi_setup;
 	master->prepare_transfer_hardware = omap2_prepare_transfer;
 	master->unprepare_transfer_hardware = omap2_unprepare_transfer;
@@ -1204,7 +1324,7 @@ static int omap2_mcspi_probe(struct plat
 	master->cleanup = omap2_mcspi_cleanup;
 	master->dev.of_node = node;
 
-	dev_set_drvdata(&pdev->dev, master);
+	platform_set_drvdata(pdev, master);
 
 	mcspi = spi_master_get_devdata(master);
 	mcspi->master = master;
@@ -1256,39 +1376,47 @@ static int omap2_mcspi_probe(struct plat
 		goto free_master;
 
 	for (i = 0; i < master->num_chipselect; i++) {
-		char dma_ch_name[14];
+		char *dma_rx_ch_name = mcspi->dma_channels[i].dma_rx_ch_name;
+		char *dma_tx_ch_name = mcspi->dma_channels[i].dma_tx_ch_name;
 		struct resource *dma_res;
 
-		sprintf(dma_ch_name, "rx%d", i);
-		dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA,
-				dma_ch_name);
-		if (!dma_res) {
-			dev_dbg(&pdev->dev, "cannot get DMA RX channel\n");
-			status = -ENODEV;
-			break;
-		}
+		sprintf(dma_rx_ch_name, "rx%d", i);
+		if (!pdev->dev.of_node) {
+			dma_res =
+				platform_get_resource_byname(pdev,
+							     IORESOURCE_DMA,
+							     dma_rx_ch_name);
+			if (!dma_res) {
+				dev_dbg(&pdev->dev,
+					"cannot get DMA RX channel\n");
+				status = -ENODEV;
+				break;
+			}
 
-		mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start;
-		sprintf(dma_ch_name, "tx%d", i);
-		dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA,
-				dma_ch_name);
-		if (!dma_res) {
-			dev_dbg(&pdev->dev, "cannot get DMA TX channel\n");
-			status = -ENODEV;
-			break;
+			mcspi->dma_channels[i].dma_rx_sync_dev =
+				dma_res->start;
 		}
+		sprintf(dma_tx_ch_name, "tx%d", i);
+		if (!pdev->dev.of_node) {
+			dma_res =
+				platform_get_resource_byname(pdev,
+							     IORESOURCE_DMA,
+							     dma_tx_ch_name);
+			if (!dma_res) {
+				dev_dbg(&pdev->dev,
+					"cannot get DMA TX channel\n");
+				status = -ENODEV;
+				break;
+			}
 
-		mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start;
+			mcspi->dma_channels[i].dma_tx_sync_dev =
+				dma_res->start;
+		}
 	}
 
 	if (status < 0)
 		goto dma_chnl_free;
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl))
-		dev_warn(&pdev->dev,
-				"pins are not configured from the driver\n");
-
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT);
 	pm_runtime_enable(&pdev->dev);
@@ -1318,7 +1446,7 @@ static int omap2_mcspi_remove(struct pla
 	struct omap2_mcspi	*mcspi;
 	struct omap2_mcspi_dma	*dma_channels;
 
-	master = dev_get_drvdata(&pdev->dev);
+	master = platform_get_drvdata(pdev);
 	mcspi = spi_master_get_devdata(master);
 	dma_channels = mcspi->dma_channels;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-omap-uwire.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-omap-uwire.c
--- linux-libre-3.10-gnu/drivers/spi/spi-omap-uwire.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-omap-uwire.c	2013-08-25 20:43:22.000000000 -0400
@@ -495,7 +495,7 @@ static int uwire_probe(struct platform_d
 		return -ENOMEM;
 	}
 
-	dev_set_drvdata(&pdev->dev, uwire);
+	platform_set_drvdata(pdev, uwire);
 
 	uwire->ck = clk_get(&pdev->dev, "fck");
 	if (IS_ERR(uwire->ck)) {
@@ -538,7 +538,7 @@ static int uwire_probe(struct platform_d
 
 static int uwire_remove(struct platform_device *pdev)
 {
-	struct uwire_spi	*uwire = dev_get_drvdata(&pdev->dev);
+	struct uwire_spi	*uwire = platform_get_drvdata(pdev);
 	int			status;
 
 	// FIXME remove all child devices, somewhere ...
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-orion.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-orion.c
--- linux-libre-3.10-gnu/drivers/spi/spi-orion.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-orion.c	2013-08-25 20:43:22.000000000 -0400
@@ -428,7 +428,7 @@ static int orion_spi_probe(struct platfo
 	master->transfer_one_message = orion_spi_transfer_one_message;
 	master->num_chipselect = ORION_NUM_CHIPSELECTS;
 
-	dev_set_drvdata(&pdev->dev, master);
+	platform_set_drvdata(pdev, master);
 
 	spi = spi_master_get_devdata(master);
 	spi->master = master;
@@ -485,7 +485,7 @@ static int orion_spi_remove(struct platf
 	struct resource *r;
 	struct orion_spi *spi;
 
-	master = dev_get_drvdata(&pdev->dev);
+	master = platform_get_drvdata(pdev);
 	spi = spi_master_get_devdata(master);
 
 	clk_disable_unprepare(spi->clk);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-pl022.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-pl022.c
--- linux-libre-3.10-gnu/drivers/spi/spi-pl022.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-pl022.c	2013-08-25 20:43:22.000000000 -0400
@@ -368,11 +368,6 @@ struct pl022 {
 	resource_size_t			phybase;
 	void __iomem			*virtbase;
 	struct clk			*clk;
-	/* Two optional pin states - default & sleep */
-	struct pinctrl			*pinctrl;
-	struct pinctrl_state		*pins_default;
-	struct pinctrl_state		*pins_idle;
-	struct pinctrl_state		*pins_sleep;
 	struct spi_master		*master;
 	struct pl022_ssp_controller	*master_info;
 	/* Message per-transfer pump */
@@ -2083,6 +2078,7 @@ pl022_platform_data_dt_get(struct device
 	}
 
 	pd->bus_id = -1;
+	pd->enable_dma = 1;
 	of_property_read_u32(np, "num-cs", &tmp);
 	pd->num_chipselect = tmp;
 	of_property_read_u32(np, "pl022,autosuspend-delay",
@@ -2133,32 +2129,7 @@ static int pl022_probe(struct amba_devic
 	pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),
 					  GFP_KERNEL);
 
-	pl022->pinctrl = devm_pinctrl_get(dev);
-	if (IS_ERR(pl022->pinctrl)) {
-		status = PTR_ERR(pl022->pinctrl);
-		goto err_no_pinctrl;
-	}
-
-	pl022->pins_default = pinctrl_lookup_state(pl022->pinctrl,
-						 PINCTRL_STATE_DEFAULT);
-	/* enable pins to be muxed in and configured */
-	if (!IS_ERR(pl022->pins_default)) {
-		status = pinctrl_select_state(pl022->pinctrl,
-				pl022->pins_default);
-		if (status)
-			dev_err(dev, "could not set default pins\n");
-	} else
-		dev_err(dev, "could not get default pinstate\n");
-
-	pl022->pins_idle = pinctrl_lookup_state(pl022->pinctrl,
-					      PINCTRL_STATE_IDLE);
-	if (IS_ERR(pl022->pins_idle))
-		dev_dbg(dev, "could not get idle pinstate\n");
-
-	pl022->pins_sleep = pinctrl_lookup_state(pl022->pinctrl,
-					       PINCTRL_STATE_SLEEP);
-	if (IS_ERR(pl022->pins_sleep))
-		dev_dbg(dev, "could not get sleep pinstate\n");
+	pinctrl_pm_select_default_state(dev);
 
 	/*
 	 * Bus Number Which has been Assigned to this SSP controller
@@ -2308,7 +2279,6 @@ static int pl022_probe(struct amba_devic
 	amba_release_regions(adev);
  err_no_ioregion:
  err_no_gpio:
- err_no_pinctrl:
 	spi_master_put(master);
 	return status;
 }
@@ -2348,44 +2318,21 @@ pl022_remove(struct amba_device *adev)
  */
 static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
 {
-	int ret;
-	struct pinctrl_state *pins_state;
-
 	clk_disable(pl022->clk);
 
-	pins_state = runtime ? pl022->pins_idle : pl022->pins_sleep;
-	/* Optionally let pins go into sleep states */
-	if (!IS_ERR(pins_state)) {
-		ret = pinctrl_select_state(pl022->pinctrl, pins_state);
-		if (ret)
-			dev_err(&pl022->adev->dev, "could not set %s pins\n",
-				runtime ? "idle" : "sleep");
-	}
+	if (runtime)
+		pinctrl_pm_select_idle_state(&pl022->adev->dev);
+	else
+		pinctrl_pm_select_sleep_state(&pl022->adev->dev);
 }
 
 static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
 {
-	int ret;
-
-	/* Optionaly enable pins to be muxed in and configured */
 	/* First go to the default state */
-	if (!IS_ERR(pl022->pins_default)) {
-		ret = pinctrl_select_state(pl022->pinctrl, pl022->pins_default);
-		if (ret)
-			dev_err(&pl022->adev->dev,
-				"could not set default pins\n");
-	}
-
-	if (!runtime) {
+	pinctrl_pm_select_default_state(&pl022->adev->dev);
+	if (!runtime)
 		/* Then let's idle the pins until the next transfer happens */
-		if (!IS_ERR(pl022->pins_idle)) {
-			ret = pinctrl_select_state(pl022->pinctrl,
-					pl022->pins_idle);
-		if (ret)
-			dev_err(&pl022->adev->dev,
-				"could not set idle pins\n");
-		}
-	}
+		pinctrl_pm_select_idle_state(&pl022->adev->dev);
 
 	clk_enable(pl022->clk);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-ppc4xx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-ppc4xx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-ppc4xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-ppc4xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -190,12 +190,6 @@ static int spi_ppc4xx_setupxfer(struct s
 			speed = min(t->speed_hz, spi->max_speed_hz);
 	}
 
-	if (bits_per_word != 8) {
-		dev_err(&spi->dev, "invalid bits-per-word (%d)\n",
-				bits_per_word);
-		return -EINVAL;
-	}
-
 	if (!speed || (speed > spi->max_speed_hz)) {
 		dev_err(&spi->dev, "invalid speed_hz (%d)\n", speed);
 		return -EINVAL;
@@ -229,12 +223,6 @@ static int spi_ppc4xx_setup(struct spi_d
 {
 	struct spi_ppc4xx_cs *cs = spi->controller_state;
 
-	if (spi->bits_per_word != 8) {
-		dev_err(&spi->dev, "invalid bits-per-word (%d)\n",
-			spi->bits_per_word);
-		return -EINVAL;
-	}
-
 	if (!spi->max_speed_hz) {
 		dev_err(&spi->dev, "invalid max_speed_hz (must be non-zero)\n");
 		return -EINVAL;
@@ -406,7 +394,7 @@ static int spi_ppc4xx_of_probe(struct pl
 	if (master == NULL)
 		return -ENOMEM;
 	master->dev.of_node = np;
-	dev_set_drvdata(dev, master);
+	platform_set_drvdata(op, master);
 	hw = spi_master_get_devdata(master);
 	hw->master = spi_master_get(master);
 	hw->dev = dev;
@@ -465,6 +453,7 @@ static int spi_ppc4xx_of_probe(struct pl
 	bbp->use_dma = 0;
 	bbp->master->setup = spi_ppc4xx_setup;
 	bbp->master->cleanup = spi_ppc4xx_cleanup;
+	bbp->master->bits_per_word_mask = SPI_BPW_MASK(8);
 
 	/* the spi->mode bits understood by this driver: */
 	bbp->master->mode_bits =
@@ -553,7 +542,6 @@ request_mem_error:
 free_gpios:
 	free_gpios(hw);
 free_master:
-	dev_set_drvdata(dev, NULL);
 	spi_master_put(master);
 
 	dev_err(dev, "initialization failed\n");
@@ -562,11 +550,10 @@ free_master:
 
 static int spi_ppc4xx_of_remove(struct platform_device *op)
 {
-	struct spi_master *master = dev_get_drvdata(&op->dev);
+	struct spi_master *master = platform_get_drvdata(op);
 	struct ppc4xx_spi *hw = spi_master_get_devdata(master);
 
 	spi_bitbang_stop(&hw->bitbang);
-	dev_set_drvdata(&op->dev, NULL);
 	release_mem_region(hw->mapbase, hw->mapsize);
 	free_irq(hw->irqnum, hw);
 	iounmap(hw->regs);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-pxa2xx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-pxa2xx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-pxa2xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-pxa2xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -881,21 +881,6 @@ static int setup(struct spi_device *spi)
 		rx_thres = RX_THRESH_DFLT;
 	}
 
-	if (!pxa25x_ssp_comp(drv_data)
-		&& (spi->bits_per_word < 4 || spi->bits_per_word > 32)) {
-		dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d "
-				"b/w not 4-32 for type non-PXA25x_SSP\n",
-				drv_data->ssp_type, spi->bits_per_word);
-		return -EINVAL;
-	} else if (pxa25x_ssp_comp(drv_data)
-			&& (spi->bits_per_word < 4
-				|| spi->bits_per_word > 16)) {
-		dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d "
-				"b/w not 4-16 for type PXA25x_SSP\n",
-				drv_data->ssp_type, spi->bits_per_word);
-		return -EINVAL;
-	}
-
 	/* Only alloc on first setup */
 	chip = spi_get_ctldata(spi);
 	if (!chip) {
@@ -1011,9 +996,6 @@ static int setup(struct spi_device *spi)
 		chip->n_bytes = 4;
 		chip->read = u32_reader;
 		chip->write = u32_writer;
-	} else {
-		dev_err(&spi->dev, "invalid wordsize\n");
-		return -ENODEV;
 	}
 	chip->bits_per_word = spi->bits_per_word;
 
@@ -1040,32 +1022,10 @@ static void cleanup(struct spi_device *s
 }
 
 #ifdef CONFIG_ACPI
-static int pxa2xx_spi_acpi_add_dma(struct acpi_resource *res, void *data)
-{
-	struct pxa2xx_spi_master *pdata = data;
-
-	if (res->type == ACPI_RESOURCE_TYPE_FIXED_DMA) {
-		const struct acpi_resource_fixed_dma *dma;
-
-		dma = &res->data.fixed_dma;
-		if (pdata->tx_slave_id < 0) {
-			pdata->tx_slave_id = dma->request_lines;
-			pdata->tx_chan_id = dma->channels;
-		} else if (pdata->rx_slave_id < 0) {
-			pdata->rx_slave_id = dma->request_lines;
-			pdata->rx_chan_id = dma->channels;
-		}
-	}
-
-	/* Tell the ACPI core to skip this resource */
-	return 1;
-}
-
 static struct pxa2xx_spi_master *
 pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)
 {
 	struct pxa2xx_spi_master *pdata;
-	struct list_head resource_list;
 	struct acpi_device *adev;
 	struct ssp_device *ssp;
 	struct resource *res;
@@ -1091,7 +1051,7 @@ pxa2xx_spi_acpi_get_pdata(struct platfor
 	ssp->phys_base = res->start;
 	ssp->mmio_base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(ssp->mmio_base))
-		return PTR_ERR(ssp->mmio_base);
+		return NULL;
 
 	ssp->clk = devm_clk_get(&pdev->dev, NULL);
 	ssp->irq = platform_get_irq(pdev, 0);
@@ -1103,15 +1063,7 @@ pxa2xx_spi_acpi_get_pdata(struct platfor
 		ssp->port_id = devid;
 
 	pdata->num_chipselect = 1;
-	pdata->rx_slave_id = -1;
-	pdata->tx_slave_id = -1;
-
-	INIT_LIST_HEAD(&resource_list);
-	acpi_dev_get_resources(adev, &resource_list, pxa2xx_spi_acpi_add_dma,
-			       pdata);
-	acpi_dev_free_resource_list(&resource_list);
-
-	pdata->enable_dma = pdata->rx_slave_id >= 0 && pdata->tx_slave_id >= 0;
+	pdata->enable_dma = true;
 
 	return pdata;
 }
@@ -1119,6 +1071,7 @@ pxa2xx_spi_acpi_get_pdata(struct platfor
 static struct acpi_device_id pxa2xx_spi_acpi_match[] = {
 	{ "INT33C0", 0 },
 	{ "INT33C1", 0 },
+	{ "80860F0E", 0 },
 	{ },
 };
 MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match);
@@ -1190,11 +1143,13 @@ static int pxa2xx_spi_probe(struct platf
 	drv_data->ioaddr = ssp->mmio_base;
 	drv_data->ssdr_physical = ssp->phys_base + SSDR;
 	if (pxa25x_ssp_comp(drv_data)) {
+		master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
 		drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
 		drv_data->dma_cr1 = 0;
 		drv_data->clear_sr = SSSR_ROR;
 		drv_data->mask_sr = SSSR_RFS | SSSR_TFS | SSSR_ROR;
 	} else {
+		master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
 		drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE;
 		drv_data->dma_cr1 = DEFAULT_DMA_CR1;
 		drv_data->clear_sr = SSSR_ROR | SSSR_TINT;
@@ -1214,7 +1169,7 @@ static int pxa2xx_spi_probe(struct platf
 	if (platform_info->enable_dma) {
 		status = pxa2xx_spi_dma_setup(drv_data);
 		if (status) {
-			dev_warn(dev, "failed to setup DMA, using PIO\n");
+			dev_dbg(dev, "no DMA channels available, using PIO\n");
 			platform_info->enable_dma = false;
 		}
 	}
@@ -1299,9 +1254,6 @@ static int pxa2xx_spi_remove(struct plat
 	/* Disconnect from the SPI framework */
 	spi_unregister_master(drv_data->master);
 
-	/* Prevent double remove */
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-pxa2xx-dma.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-pxa2xx-dma.c
--- linux-libre-3.10-gnu/drivers/spi/spi-pxa2xx-dma.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-pxa2xx-dma.c	2013-08-25 20:43:22.000000000 -0400
@@ -327,22 +327,23 @@ void pxa2xx_spi_dma_start(struct driver_
 int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
 {
 	struct pxa2xx_spi_master *pdata = drv_data->master_info;
+	struct device *dev = &drv_data->pdev->dev;
 	dma_cap_mask_t mask;
 
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
-	drv_data->dummy = devm_kzalloc(&drv_data->pdev->dev, SZ_2K, GFP_KERNEL);
+	drv_data->dummy = devm_kzalloc(dev, SZ_2K, GFP_KERNEL);
 	if (!drv_data->dummy)
 		return -ENOMEM;
 
-	drv_data->tx_chan = dma_request_channel(mask, pxa2xx_spi_dma_filter,
-						pdata);
+	drv_data->tx_chan = dma_request_slave_channel_compat(mask,
+				pxa2xx_spi_dma_filter, pdata, dev, "tx");
 	if (!drv_data->tx_chan)
 		return -ENODEV;
 
-	drv_data->rx_chan = dma_request_channel(mask, pxa2xx_spi_dma_filter,
-						pdata);
+	drv_data->rx_chan = dma_request_slave_channel_compat(mask,
+				pxa2xx_spi_dma_filter, pdata, dev, "rx");
 	if (!drv_data->rx_chan) {
 		dma_release_channel(drv_data->tx_chan);
 		drv_data->tx_chan = NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-rspi.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-rspi.c
--- linux-libre-3.10-gnu/drivers/spi/spi-rspi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-rspi.c	2013-08-25 20:43:22.000000000 -0400
@@ -719,7 +719,7 @@ static void rspi_release_dma(struct rspi
 
 static int rspi_remove(struct platform_device *pdev)
 {
-	struct rspi_data *rspi = dev_get_drvdata(&pdev->dev);
+	struct rspi_data *rspi = platform_get_drvdata(pdev);
 
 	spi_unregister_master(rspi->master);
 	rspi_release_dma(rspi);
@@ -759,7 +759,7 @@ static int rspi_probe(struct platform_de
 	}
 
 	rspi = spi_master_get_devdata(master);
-	dev_set_drvdata(&pdev->dev, rspi);
+	platform_set_drvdata(pdev, rspi);
 
 	rspi->master = master;
 	rspi->addr = ioremap(res->start, resource_size(res));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-s3c24xx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-s3c24xx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-s3c24xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-s3c24xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -667,8 +667,6 @@ static int s3c24xx_spi_remove(struct pla
 {
 	struct s3c24xx_spi *hw = platform_get_drvdata(dev);
 
-	platform_set_drvdata(dev, NULL);
-
 	spi_bitbang_stop(&hw->bitbang);
 
 	clk_disable(hw->clk);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-s3c64xx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-s3c64xx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-s3c64xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-s3c64xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -39,6 +39,7 @@
 #endif
 
 #define MAX_SPI_PORTS		3
+#define S3C64XX_SPI_QUIRK_POLL		(1 << 0)
 
 /* Registers and bit-fields */
 
@@ -130,6 +131,7 @@
 #define S3C64XX_SPI_TRAILCNT		S3C64XX_SPI_MAX_TRAILCNT
 
 #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+#define is_polling(x)	(x->port_conf->quirks & S3C64XX_SPI_QUIRK_POLL)
 
 #define RXBUSY    (1<<2)
 #define TXBUSY    (1<<3)
@@ -158,6 +160,7 @@ struct s3c64xx_spi_port_config {
 	int	fifo_lvl_mask[MAX_SPI_PORTS];
 	int	rx_lvl_offset;
 	int	tx_st_done;
+	int	quirks;
 	bool	high_speed;
 	bool	clk_from_cmu;
 };
@@ -205,6 +208,7 @@ struct s3c64xx_spi_driver_data {
 	struct s3c64xx_spi_port_config	*port_conf;
 	unsigned int			port_id;
 	unsigned long			gpios[4];
+	bool				cs_gpio;
 };
 
 static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
@@ -344,8 +348,12 @@ static int s3c64xx_spi_prepare_transfer(
 {
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
 
-	/* Acquire DMA channels */
-	while (!acquire_dma(sdd))
+	/*
+	 * If DMA resource was not available during
+	 * probe, no need to continue with dma requests
+	 * else Acquire DMA channels
+	 */
+	while (!is_polling(sdd) && !acquire_dma(sdd))
 		usleep_range(10000, 11000);
 
 	pm_runtime_get_sync(&sdd->pdev->dev);
@@ -358,9 +366,12 @@ static int s3c64xx_spi_unprepare_transfe
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
 
 	/* Free DMA channels */
-	sdd->ops->release((enum dma_ch)sdd->rx_dma.ch, &s3c64xx_spi_dma_client);
-	sdd->ops->release((enum dma_ch)sdd->tx_dma.ch, &s3c64xx_spi_dma_client);
-
+	if (!is_polling(sdd)) {
+		sdd->ops->release((enum dma_ch)sdd->rx_dma.ch,
+					&s3c64xx_spi_dma_client);
+		sdd->ops->release((enum dma_ch)sdd->tx_dma.ch,
+					&s3c64xx_spi_dma_client);
+	}
 	pm_runtime_put(&sdd->pdev->dev);
 
 	return 0;
@@ -423,6 +434,9 @@ static int s3c64xx_spi_prepare_transfer(
 	dma_cap_mask_t mask;
 	int ret;
 
+	if (is_polling(sdd))
+		return 0;
+
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
@@ -464,8 +478,10 @@ static int s3c64xx_spi_unprepare_transfe
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
 
 	/* Free DMA channels */
-	dma_release_channel(sdd->rx_dma.ch);
-	dma_release_channel(sdd->tx_dma.ch);
+	if (!is_polling(sdd)) {
+		dma_release_channel(sdd->rx_dma.ch);
+		dma_release_channel(sdd->tx_dma.ch);
+	}
 
 	pm_runtime_put(&sdd->pdev->dev);
 	return 0;
@@ -558,14 +574,40 @@ static inline void enable_cs(struct s3c6
 		if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
 			/* Deselect the last toggled device */
 			cs = sdd->tgl_spi->controller_data;
-			gpio_set_value(cs->line,
-				spi->mode & SPI_CS_HIGH ? 0 : 1);
+			if (sdd->cs_gpio)
+				gpio_set_value(cs->line,
+					spi->mode & SPI_CS_HIGH ? 0 : 1);
 		}
 		sdd->tgl_spi = NULL;
 	}
 
 	cs = spi->controller_data;
-	gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
+	if (sdd->cs_gpio)
+		gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
+
+	/* Start the signals */
+	writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
+}
+
+static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
+					int timeout_ms)
+{
+	void __iomem *regs = sdd->regs;
+	unsigned long val = 1;
+	u32 status;
+
+	/* max fifo depth available */
+	u32 max_fifo = (FIFO_LVL_MASK(sdd) >> 1) + 1;
+
+	if (timeout_ms)
+		val = msecs_to_loops(timeout_ms);
+
+	do {
+		status = readl(regs + S3C64XX_SPI_STATUS);
+	} while (RX_FIFO_LVL(status, sdd) < max_fifo && --val);
+
+	/* return the actual received data length */
+	return RX_FIFO_LVL(status, sdd);
 }
 
 static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
@@ -590,20 +632,19 @@ static int wait_for_xfer(struct s3c64xx_
 		} while (RX_FIFO_LVL(status, sdd) < xfer->len && --val);
 	}
 
-	if (!val)
-		return -EIO;
-
 	if (dma_mode) {
 		u32 status;
 
 		/*
+		 * If the previous xfer was completed within timeout, then
+		 * proceed further else return -EIO.
 		 * DmaTx returns after simply writing data in the FIFO,
 		 * w/o waiting for real transmission on the bus to finish.
 		 * DmaRx returns only after Dma read data from FIFO which
 		 * needs bus transmission to finish, so we don't worry if
 		 * Xfer involved Rx(with or without Tx).
 		 */
-		if (xfer->rx_buf == NULL) {
+		if (val && !xfer->rx_buf) {
 			val = msecs_to_loops(10);
 			status = readl(regs + S3C64XX_SPI_STATUS);
 			while ((TX_FIFO_LVL(status, sdd)
@@ -613,30 +654,54 @@ static int wait_for_xfer(struct s3c64xx_
 				status = readl(regs + S3C64XX_SPI_STATUS);
 			}
 
-			if (!val)
-				return -EIO;
 		}
+
+		/* If timed out while checking rx/tx status return error */
+		if (!val)
+			return -EIO;
 	} else {
+		int loops;
+		u32 cpy_len;
+		u8 *buf;
+
 		/* If it was only Tx */
-		if (xfer->rx_buf == NULL) {
+		if (!xfer->rx_buf) {
 			sdd->state &= ~TXBUSY;
 			return 0;
 		}
 
-		switch (sdd->cur_bpw) {
-		case 32:
-			ioread32_rep(regs + S3C64XX_SPI_RX_DATA,
-				xfer->rx_buf, xfer->len / 4);
-			break;
-		case 16:
-			ioread16_rep(regs + S3C64XX_SPI_RX_DATA,
-				xfer->rx_buf, xfer->len / 2);
-			break;
-		default:
-			ioread8_rep(regs + S3C64XX_SPI_RX_DATA,
-				xfer->rx_buf, xfer->len);
-			break;
-		}
+		/*
+		 * If the receive length is bigger than the controller fifo
+		 * size, calculate the loops and read the fifo as many times.
+		 * loops = length / max fifo size (calculated by using the
+		 * fifo mask).
+		 * For any size less than the fifo size the below code is
+		 * executed atleast once.
+		 */
+		loops = xfer->len / ((FIFO_LVL_MASK(sdd) >> 1) + 1);
+		buf = xfer->rx_buf;
+		do {
+			/* wait for data to be received in the fifo */
+			cpy_len = s3c64xx_spi_wait_for_timeout(sdd,
+						(loops ? ms : 0));
+
+			switch (sdd->cur_bpw) {
+			case 32:
+				ioread32_rep(regs + S3C64XX_SPI_RX_DATA,
+					buf, cpy_len / 4);
+				break;
+			case 16:
+				ioread16_rep(regs + S3C64XX_SPI_RX_DATA,
+					buf, cpy_len / 2);
+				break;
+			default:
+				ioread8_rep(regs + S3C64XX_SPI_RX_DATA,
+					buf, cpy_len);
+				break;
+			}
+
+			buf = buf + cpy_len;
+		} while (loops--);
 		sdd->state &= ~RXBUSY;
 	}
 
@@ -651,7 +716,11 @@ static inline void disable_cs(struct s3c
 	if (sdd->tgl_spi == spi)
 		sdd->tgl_spi = NULL;
 
-	gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1);
+	if (sdd->cs_gpio)
+		gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1);
+
+	/* Quiese the signals */
+	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 }
 
 static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
@@ -733,7 +802,7 @@ static int s3c64xx_spi_map_mssg(struct s
 	struct device *dev = &sdd->pdev->dev;
 	struct spi_transfer *xfer;
 
-	if (msg->is_dma_mapped)
+	if (is_polling(sdd) || msg->is_dma_mapped)
 		return 0;
 
 	/* First mark all xfer unmapped */
@@ -782,7 +851,7 @@ static void s3c64xx_spi_unmap_mssg(struc
 	struct device *dev = &sdd->pdev->dev;
 	struct spi_transfer *xfer;
 
-	if (msg->is_dma_mapped)
+	if (is_polling(sdd) || msg->is_dma_mapped)
 		return;
 
 	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
@@ -861,8 +930,9 @@ static int s3c64xx_spi_transfer_one_mess
 
 		/* Polling method for xfers not bigger than FIFO capacity */
 		use_dma = 0;
-		if (sdd->rx_dma.ch && sdd->tx_dma.ch &&
-		    (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1)))
+		if (!is_polling(sdd) &&
+			(sdd->rx_dma.ch && sdd->tx_dma.ch &&
+			(xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1))))
 			use_dma = 1;
 
 		spin_lock_irqsave(&sdd->lock, flags);
@@ -876,17 +946,10 @@ static int s3c64xx_spi_transfer_one_mess
 		/* Slave Select */
 		enable_cs(sdd, spi);
 
-		/* Start the signals */
-		writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
-
 		spin_unlock_irqrestore(&sdd->lock, flags);
 
 		status = wait_for_xfer(sdd, xfer, use_dma);
 
-		/* Quiese the signals */
-		writel(S3C64XX_SPI_SLAVE_SIG_INACT,
-		       sdd->regs + S3C64XX_SPI_SLAVE_SEL);
-
 		if (status) {
 			dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
 				xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
@@ -942,8 +1005,10 @@ static struct s3c64xx_spi_csinfo *s3c64x
 {
 	struct s3c64xx_spi_csinfo *cs;
 	struct device_node *slave_np, *data_np = NULL;
+	struct s3c64xx_spi_driver_data *sdd;
 	u32 fb_delay = 0;
 
+	sdd = spi_master_get_devdata(spi->master);
 	slave_np = spi->dev.of_node;
 	if (!slave_np) {
 		dev_err(&spi->dev, "device node not found\n");
@@ -963,7 +1028,10 @@ static struct s3c64xx_spi_csinfo *s3c64x
 		return ERR_PTR(-ENOMEM);
 	}
 
-	cs->line = of_get_named_gpio(data_np, "cs-gpio", 0);
+	/* The CS line is asserted/deasserted by the gpio pin */
+	if (sdd->cs_gpio)
+		cs->line = of_get_named_gpio(data_np, "cs-gpio", 0);
+
 	if (!gpio_is_valid(cs->line)) {
 		dev_err(&spi->dev, "chip select gpio is not specified or invalid\n");
 		kfree(cs);
@@ -1003,7 +1071,8 @@ static int s3c64xx_spi_setup(struct spi_
 		return -ENODEV;
 	}
 
-	if (!spi_get_ctldata(spi)) {
+	/* Request gpio only if cs line is asserted by gpio pins */
+	if (sdd->cs_gpio) {
 		err = gpio_request_one(cs->line, GPIOF_OUT_INIT_HIGH,
 				       dev_name(&spi->dev));
 		if (err) {
@@ -1012,9 +1081,11 @@ static int s3c64xx_spi_setup(struct spi_
 				cs->line, err);
 			goto err_gpio_req;
 		}
-		spi_set_ctldata(spi, cs);
 	}
 
+	if (!spi_get_ctldata(spi))
+		spi_set_ctldata(spi, cs);
+
 	sci = sdd->cntrlr_info;
 
 	spin_lock_irqsave(&sdd->lock, flags);
@@ -1092,8 +1163,10 @@ err_gpio_req:
 static void s3c64xx_spi_cleanup(struct spi_device *spi)
 {
 	struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
+	struct s3c64xx_spi_driver_data *sdd;
 
-	if (cs) {
+	sdd = spi_master_get_devdata(spi->master);
+	if (cs && sdd->cs_gpio) {
 		gpio_free(cs->line);
 		if (spi->dev.of_node)
 			kfree(cs);
@@ -1270,7 +1343,11 @@ static int s3c64xx_spi_probe(struct plat
 	sdd->cntrlr_info = sci;
 	sdd->pdev = pdev;
 	sdd->sfr_start = mem_res->start;
+	sdd->cs_gpio = true;
 	if (pdev->dev.of_node) {
+		if (!of_find_property(pdev->dev.of_node, "cs-gpio", NULL))
+			sdd->cs_gpio = false;
+
 		ret = of_alias_get_id(pdev->dev.of_node, "spi");
 		if (ret < 0) {
 			dev_err(&pdev->dev, "failed to get alias id, errno %d\n",
@@ -1287,19 +1364,19 @@ static int s3c64xx_spi_probe(struct plat
 	if (!sdd->pdev->dev.of_node) {
 		res = platform_get_resource(pdev, IORESOURCE_DMA,  0);
 		if (!res) {
-			dev_err(&pdev->dev, "Unable to get SPI tx dma "
-					"resource\n");
-			return -ENXIO;
-		}
-		sdd->tx_dma.dmach = res->start;
+			dev_warn(&pdev->dev, "Unable to get SPI tx dma "
+					"resource. Switching to poll mode\n");
+			sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL;
+		} else
+			sdd->tx_dma.dmach = res->start;
 
 		res = platform_get_resource(pdev, IORESOURCE_DMA,  1);
 		if (!res) {
-			dev_err(&pdev->dev, "Unable to get SPI rx dma "
-					"resource\n");
-			return -ENXIO;
-		}
-		sdd->rx_dma.dmach = res->start;
+			dev_warn(&pdev->dev, "Unable to get SPI rx dma "
+					"resource. Switching to poll mode\n");
+			sdd->port_conf->quirks = S3C64XX_SPI_QUIRK_POLL;
+		} else
+			sdd->rx_dma.dmach = res->start;
 	}
 
 	sdd->tx_dma.direction = DMA_MEM_TO_DEV;
@@ -1314,7 +1391,8 @@ static int s3c64xx_spi_probe(struct plat
 	master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
 	master->num_chipselect = sci->num_cs;
 	master->dma_alignment = 8;
-	master->bits_per_word_mask = BIT(32 - 1) | BIT(16 - 1) | BIT(8 - 1);
+	master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
+					SPI_BPW_MASK(8);
 	/* the spi->mode bits understood by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 
@@ -1399,7 +1477,6 @@ err3:
 err2:
 	clk_disable_unprepare(sdd->clk);
 err0:
-	platform_set_drvdata(pdev, NULL);
 	spi_master_put(master);
 
 	return ret;
@@ -1420,7 +1497,6 @@ static int s3c64xx_spi_remove(struct pla
 
 	clk_disable_unprepare(sdd->clk);
 
-	platform_set_drvdata(pdev, NULL);
 	spi_master_put(master);
 
 	return 0;
@@ -1535,6 +1611,15 @@ static struct s3c64xx_spi_port_config ex
 	.clk_from_cmu	= true,
 };
 
+static struct s3c64xx_spi_port_config exynos5440_spi_port_config = {
+	.fifo_lvl_mask	= { 0x1ff },
+	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
+	.high_speed	= true,
+	.clk_from_cmu	= true,
+	.quirks		= S3C64XX_SPI_QUIRK_POLL,
+};
+
 static struct platform_device_id s3c64xx_spi_driver_ids[] = {
 	{
 		.name		= "s3c2443-spi",
@@ -1558,15 +1643,16 @@ static struct platform_device_id s3c64xx
 	{ },
 };
 
-#ifdef CONFIG_OF
 static const struct of_device_id s3c64xx_spi_dt_match[] = {
 	{ .compatible = "samsung,exynos4210-spi",
 			.data = (void *)&exynos4_spi_port_config,
 	},
+	{ .compatible = "samsung,exynos5440-spi",
+			.data = (void *)&exynos5440_spi_port_config,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);
-#endif /* CONFIG_OF */
 
 static struct platform_driver s3c64xx_spi_driver = {
 	.driver = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-sh.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-sh.c
--- linux-libre-3.10-gnu/drivers/spi/spi-sh.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-sh.c	2013-08-25 20:43:22.000000000 -0400
@@ -434,7 +434,7 @@ static irqreturn_t spi_sh_irq(int irq, v
 
 static int spi_sh_remove(struct platform_device *pdev)
 {
-	struct spi_sh_data *ss = dev_get_drvdata(&pdev->dev);
+	struct spi_sh_data *ss = platform_get_drvdata(pdev);
 
 	spi_unregister_master(ss->master);
 	destroy_workqueue(ss->workqueue);
@@ -471,7 +471,7 @@ static int spi_sh_probe(struct platform_
 	}
 
 	ss = spi_master_get_devdata(master);
-	dev_set_drvdata(&pdev->dev, ss);
+	platform_set_drvdata(pdev, ss);
 
 	switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
 	case IORESOURCE_MEM_8BIT:
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-sh-hspi.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-sh-hspi.c
--- linux-libre-3.10-gnu/drivers/spi/spi-sh-hspi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-sh-hspi.c	2013-08-25 20:43:22.000000000 -0400
@@ -297,7 +297,7 @@ static int hspi_probe(struct platform_de
 	}
 
 	hspi = spi_master_get_devdata(master);
-	dev_set_drvdata(&pdev->dev, hspi);
+	platform_set_drvdata(pdev, hspi);
 
 	/* init hspi */
 	hspi->master	= master;
@@ -341,7 +341,7 @@ static int hspi_probe(struct platform_de
 
 static int hspi_remove(struct platform_device *pdev)
 {
-	struct hspi_priv *hspi = dev_get_drvdata(&pdev->dev);
+	struct hspi_priv *hspi = platform_get_drvdata(pdev);
 
 	pm_runtime_disable(&pdev->dev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-sirf.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-sirf.c
--- linux-libre-3.10-gnu/drivers/spi/spi-sirf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-sirf.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/of_gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
-#include <linux/pinctrl/consumer.h>
 
 #define DRIVER_NAME "sirfsoc_spi"
 
@@ -127,7 +126,6 @@ struct sirfsoc_spi {
 	void __iomem *base;
 	u32 ctrl_freq;  /* SPI controller clock speed */
 	struct clk *clk;
-	struct pinctrl *p;
 
 	/* rx & tx bufs from the spi_transfer */
 	const void *tx;
@@ -142,9 +140,6 @@ struct sirfsoc_spi {
 	unsigned int left_tx_cnt;
 	unsigned int left_rx_cnt;
 
-	/* tasklet to push tx msg into FIFO */
-	struct tasklet_struct tasklet_tx;
-
 	int chipselect[0];
 };
 
@@ -236,17 +231,6 @@ static void spi_sirfsoc_tx_word_u32(stru
 	sspi->left_tx_cnt--;
 }
 
-static void spi_sirfsoc_tasklet_tx(unsigned long arg)
-{
-	struct sirfsoc_spi *sspi = (struct sirfsoc_spi *)arg;
-
-	/* Fill Tx FIFO while there are left words to be transmitted */
-	while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) &
-			SIRFSOC_SPI_FIFO_FULL)) &&
-			sspi->left_tx_cnt)
-		sspi->tx_word(sspi);
-}
-
 static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id)
 {
 	struct sirfsoc_spi *sspi = dev_id;
@@ -261,25 +245,25 @@ static irqreturn_t spi_sirfsoc_irq(int i
 		writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
 	}
 
-	if (spi_stat & SIRFSOC_SPI_FRM_END) {
+	if (spi_stat & (SIRFSOC_SPI_FRM_END
+			| SIRFSOC_SPI_RXFIFO_THD_REACH))
 		while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS)
 				& SIRFSOC_SPI_FIFO_EMPTY)) &&
 				sspi->left_rx_cnt)
 			sspi->rx_word(sspi);
 
-		/* Received all words */
-		if ((sspi->left_rx_cnt == 0) && (sspi->left_tx_cnt == 0)) {
-			complete(&sspi->done);
-			writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
-		}
-	}
-
-	if (spi_stat & SIRFSOC_SPI_RXFIFO_THD_REACH ||
-		spi_stat & SIRFSOC_SPI_TXFIFO_THD_REACH ||
-		spi_stat & SIRFSOC_SPI_RX_FIFO_FULL ||
-		spi_stat & SIRFSOC_SPI_TXFIFO_EMPTY)
-		tasklet_schedule(&sspi->tasklet_tx);
+	if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY
+			| SIRFSOC_SPI_TXFIFO_THD_REACH))
+		while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS)
+				& SIRFSOC_SPI_FIFO_FULL)) &&
+				sspi->left_tx_cnt)
+			sspi->tx_word(sspi);
 
+	/* Received all words */
+	if ((sspi->left_rx_cnt == 0) && (sspi->left_tx_cnt == 0)) {
+		complete(&sspi->done);
+		writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
+	}
 	return IRQ_HANDLED;
 }
 
@@ -426,9 +410,7 @@ spi_sirfsoc_setup_transfer(struct spi_de
 					SIRFSOC_SPI_FIFO_WIDTH_DWORD;
 		break;
 	default:
-		dev_err(&spi->dev, "Bits per word %d not supported\n",
-		       bits_per_word);
-		return -EINVAL;
+		BUG();
 	}
 
 	if (!(spi->mode & SPI_CS_HIGH))
@@ -556,26 +538,20 @@ static int spi_sirfsoc_probe(struct plat
 	sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer;
 	sspi->bitbang.master->setup = spi_sirfsoc_setup;
 	master->bus_num = pdev->id;
+	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(12) |
+					SPI_BPW_MASK(16) | SPI_BPW_MASK(32);
 	sspi->bitbang.master->dev.of_node = pdev->dev.of_node;
 
-	sspi->p = pinctrl_get_select_default(&pdev->dev);
-	ret = IS_ERR(sspi->p);
-	if (ret)
-		goto free_master;
-
 	sspi->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(sspi->clk)) {
 		ret = -EINVAL;
-		goto free_pin;
+		goto free_master;
 	}
 	clk_prepare_enable(sspi->clk);
 	sspi->ctrl_freq = clk_get_rate(sspi->clk);
 
 	init_completion(&sspi->done);
 
-	tasklet_init(&sspi->tasklet_tx, spi_sirfsoc_tasklet_tx,
-		     (unsigned long)sspi);
-
 	writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
 	writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP);
 	writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
@@ -594,8 +570,6 @@ static int spi_sirfsoc_probe(struct plat
 free_clk:
 	clk_disable_unprepare(sspi->clk);
 	clk_put(sspi->clk);
-free_pin:
-	pinctrl_put(sspi->p);
 free_master:
 	spi_master_put(master);
 err_cs:
@@ -618,7 +592,6 @@ static int  spi_sirfsoc_remove(struct pl
 	}
 	clk_disable_unprepare(sspi->clk);
 	clk_put(sspi->clk);
-	pinctrl_put(sspi->p);
 	spi_master_put(master);
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-tegra114.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-tegra114.c
--- linux-libre-3.10-gnu/drivers/spi/spi-tegra114.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-tegra114.c	2013-08-25 20:43:22.000000000 -0400
@@ -1041,7 +1041,7 @@ static int tegra_spi_probe(struct platfo
 		dev_err(&pdev->dev, "master allocation failed\n");
 		return -ENOMEM;
 	}
-	dev_set_drvdata(&pdev->dev, master);
+	platform_set_drvdata(pdev, master);
 	tspi = spi_master_get_devdata(master);
 
 	/* Parse DT */
@@ -1152,7 +1152,7 @@ exit_free_master:
 
 static int tegra_spi_remove(struct platform_device *pdev)
 {
-	struct spi_master *master = dev_get_drvdata(&pdev->dev);
+	struct spi_master *master = platform_get_drvdata(pdev);
 	struct tegra_spi_data	*tspi = spi_master_get_devdata(master);
 
 	free_irq(tspi->irq, tspi);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-tegra20-sflash.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-tegra20-sflash.c
--- linux-libre-3.10-gnu/drivers/spi/spi-tegra20-sflash.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-tegra20-sflash.c	2013-08-25 20:43:22.000000000 -0400
@@ -480,7 +480,7 @@ static int tegra_sflash_probe(struct pla
 	master->num_chipselect = MAX_CHIP_SELECT;
 	master->bus_num = -1;
 
-	dev_set_drvdata(&pdev->dev, master);
+	platform_set_drvdata(pdev, master);
 	tsd = spi_master_get_devdata(master);
 	tsd->master = master;
 	tsd->dev = &pdev->dev;
@@ -555,7 +555,7 @@ exit_free_master:
 
 static int tegra_sflash_remove(struct platform_device *pdev)
 {
-	struct spi_master *master = dev_get_drvdata(&pdev->dev);
+	struct spi_master *master = platform_get_drvdata(pdev);
 	struct tegra_sflash_data	*tsd = spi_master_get_devdata(master);
 
 	free_irq(tsd->irq, tsd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-tegra20-slink.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-tegra20-slink.c
--- linux-libre-3.10-gnu/drivers/spi/spi-tegra20-slink.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-tegra20-slink.c	2013-08-25 20:43:22.000000000 -0400
@@ -1089,7 +1089,7 @@ static int tegra_slink_probe(struct plat
 	master->num_chipselect = MAX_CHIP_SELECT;
 	master->bus_num = -1;
 
-	dev_set_drvdata(&pdev->dev, master);
+	platform_set_drvdata(pdev, master);
 	tspi = spi_master_get_devdata(master);
 	tspi->master = master;
 	tspi->dev = &pdev->dev;
@@ -1193,7 +1193,7 @@ exit_free_master:
 
 static int tegra_slink_remove(struct platform_device *pdev)
 {
-	struct spi_master *master = dev_get_drvdata(&pdev->dev);
+	struct spi_master *master = platform_get_drvdata(pdev);
 	struct tegra_slink_data	*tspi = spi_master_get_devdata(master);
 
 	free_irq(tspi->irq, tspi);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-ti-ssp.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-ti-ssp.c
--- linux-libre-3.10-gnu/drivers/spi/spi-ti-ssp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-ti-ssp.c	2013-08-25 20:43:22.000000000 -0400
@@ -237,14 +237,6 @@ static void ti_ssp_spi_work(struct work_
 	spin_unlock(&hw->lock);
 }
 
-static int ti_ssp_spi_setup(struct spi_device *spi)
-{
-	if (spi->bits_per_word > 32)
-		return -EINVAL;
-
-	return 0;
-}
-
 static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m)
 {
 	struct ti_ssp_spi	*hw;
@@ -269,12 +261,6 @@ static int ti_ssp_spi_transfer(struct sp
 			dev_err(&spi->dev, "invalid xfer, full duplex\n");
 			return -EINVAL;
 		}
-
-		if (t->bits_per_word > 32) {
-			dev_err(&spi->dev, "invalid xfer width %d\n",
-				t->bits_per_word);
-			return -EINVAL;
-		}
 	}
 
 	spin_lock(&hw->lock);
@@ -337,8 +323,8 @@ static int ti_ssp_spi_probe(struct platf
 	master->bus_num		= pdev->id;
 	master->num_chipselect	= pdata->num_cs;
 	master->mode_bits	= MODE_BITS;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
 	master->flags		= SPI_MASTER_HALF_DUPLEX;
-	master->setup		= ti_ssp_spi_setup;
 	master->transfer	= ti_ssp_spi_transfer;
 
 	error = spi_register_master(master);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-topcliff-pch.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-topcliff-pch.c
--- linux-libre-3.10-gnu/drivers/spi/spi-topcliff-pch.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-topcliff-pch.c	2013-08-25 20:43:22.000000000 -0400
@@ -367,7 +367,7 @@ static irqreturn_t pch_spi_handler(int i
 
 	if (reg_spsr_val & SPSR_ORF_BIT) {
 		dev_err(&board_dat->pdev->dev, "%s Over run error\n", __func__);
-		if (data->current_msg->complete != 0) {
+		if (data->current_msg->complete) {
 			data->transfer_complete = true;
 			data->current_msg->status = -EIO;
 			data->current_msg->complete(data->current_msg->context);
@@ -472,11 +472,6 @@ static int pch_spi_setup(struct spi_devi
 		dev_dbg(&pspi->dev, "%s 8 bits per word\n", __func__);
 	}
 
-	if ((pspi->bits_per_word != 8) && (pspi->bits_per_word != 16)) {
-		dev_err(&pspi->dev, "%s Invalid bits per word\n", __func__);
-		return -EINVAL;
-	}
-
 	/* Check baud rate setting */
 	/* if baud rate of chip is greater than
 	   max we can support,return error */
@@ -537,17 +532,6 @@ static int pch_spi_transfer(struct spi_d
 		/* if baud rate has been specified validate the same */
 		if (transfer->speed_hz > PCH_MAX_BAUDRATE)
 			transfer->speed_hz = PCH_MAX_BAUDRATE;
-
-		/* if bits per word has been specified validate the same */
-		if (transfer->bits_per_word) {
-			if ((transfer->bits_per_word != 8)
-			    && (transfer->bits_per_word != 16)) {
-				retval = -EINVAL;
-				dev_err(&pspi->dev,
-					"%s Invalid bits per word\n", __func__);
-				goto err_return_spinlock;
-			}
-		}
 	}
 	spin_unlock_irqrestore(&data->lock, flags);
 
@@ -659,7 +643,7 @@ static void pch_spi_set_tx(struct pch_sp
 		list_for_each_entry_safe(pmsg, tmp, data->queue.next, queue) {
 			pmsg->status = -ENOMEM;
 
-			if (pmsg->complete != 0)
+			if (pmsg->complete)
 				pmsg->complete(pmsg->context);
 
 			/* delete from queue */
@@ -709,7 +693,7 @@ static void pch_spi_nomore_transfer(stru
 	 * [To the spi core..indicating end of transfer] */
 	data->current_msg->status = 0;
 
-	if (data->current_msg->complete != 0) {
+	if (data->current_msg->complete) {
 		dev_dbg(&data->master->dev,
 			"%s:Invoking callback of SPI core\n", __func__);
 		data->current_msg->complete(data->current_msg->context);
@@ -1202,7 +1186,7 @@ static void pch_spi_process_messages(str
 		list_for_each_entry_safe(pmsg, tmp, data->queue.next, queue) {
 			pmsg->status = -EIO;
 
-			if (pmsg->complete != 0) {
+			if (pmsg->complete) {
 				spin_unlock(&data->lock);
 				pmsg->complete(pmsg->context);
 				spin_lock(&data->lock);
@@ -1442,6 +1426,7 @@ static int pch_spi_pd_probe(struct platf
 	master->setup = pch_spi_setup;
 	master->transfer = pch_spi_transfer;
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
+	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 
 	data->board_dat = board_dat;
 	data->plat_dev = plat_dev;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-txx9.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-txx9.c
--- linux-libre-3.10-gnu/drivers/spi/spi-txx9.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-txx9.c	2013-08-25 20:43:22.000000000 -0400
@@ -116,17 +116,12 @@ static void txx9spi_cs_func(struct spi_d
 static int txx9spi_setup(struct spi_device *spi)
 {
 	struct txx9spi *c = spi_master_get_devdata(spi->master);
-	u8 bits_per_word;
 
 	if (!spi->max_speed_hz
 			|| spi->max_speed_hz > c->max_speed_hz
 			|| spi->max_speed_hz < c->min_speed_hz)
 		return -EINVAL;
 
-	bits_per_word = spi->bits_per_word;
-	if (bits_per_word != 8 && bits_per_word != 16)
-		return -EINVAL;
-
 	if (gpio_direction_output(spi->chip_select,
 			!(spi->mode & SPI_CS_HIGH))) {
 		dev_err(&spi->dev, "Cannot setup GPIO for chipselect.\n");
@@ -319,8 +314,6 @@ static int txx9spi_transfer(struct spi_d
 
 		if (!t->tx_buf && !t->rx_buf && t->len)
 			return -EINVAL;
-		if (bits_per_word != 8 && bits_per_word != 16)
-			return -EINVAL;
 		if (t->len & ((bits_per_word >> 3) - 1))
 			return -EINVAL;
 		if (speed_hz < c->min_speed_hz || speed_hz > c->max_speed_hz)
@@ -411,6 +404,7 @@ static int txx9spi_probe(struct platform
 	master->setup = txx9spi_setup;
 	master->transfer = txx9spi_transfer;
 	master->num_chipselect = (u16)UINT_MAX; /* any GPIO numbers */
+	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 
 	ret = spi_register_master(master);
 	if (ret)
@@ -425,7 +419,6 @@ exit:
 		clk_disable(c->clk);
 		clk_put(c->clk);
 	}
-	platform_set_drvdata(dev, NULL);
 	spi_master_put(master);
 	return ret;
 }
@@ -436,7 +429,6 @@ static int txx9spi_remove(struct platfor
 	struct txx9spi *c = spi_master_get_devdata(master);
 
 	spi_unregister_master(master);
-	platform_set_drvdata(dev, NULL);
 	destroy_workqueue(c->workqueue);
 	clk_disable(c->clk);
 	clk_put(c->clk);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-xcomm.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-xcomm.c
--- linux-libre-3.10-gnu/drivers/spi/spi-xcomm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-xcomm.c	2013-08-25 20:43:22.000000000 -0400
@@ -76,7 +76,7 @@ static int spi_xcomm_setup_transfer(stru
 {
 	unsigned int speed;
 
-	if ((t->bits_per_word && t->bits_per_word != 8) || t->len > 62)
+	if (t->len > 62)
 		return -EINVAL;
 
 	speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz;
@@ -209,14 +209,6 @@ static int spi_xcomm_transfer_one(struct
 	return status;
 }
 
-static int spi_xcomm_setup(struct spi_device *spi)
-{
-	if (spi->bits_per_word != 8)
-		return -EINVAL;
-
-	return 0;
-}
-
 static int spi_xcomm_probe(struct i2c_client *i2c,
 	const struct i2c_device_id *id)
 {
@@ -233,8 +225,8 @@ static int spi_xcomm_probe(struct i2c_cl
 
 	master->num_chipselect = 16;
 	master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_3WIRE;
+	master->bits_per_word_mask = SPI_BPW_MASK(8);
 	master->flags = SPI_MASTER_HALF_DUPLEX;
-	master->setup = spi_xcomm_setup;
 	master->transfer_one_message = spi_xcomm_transfer_one;
 	master->dev.of_node = i2c->dev.of_node;
 	i2c_set_clientdata(i2c, master);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/spi/spi-xilinx.c linux-libre-3.11-rc7-gnu/drivers/spi/spi-xilinx.c
--- linux-libre-3.10-gnu/drivers/spi/spi-xilinx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/spi/spi-xilinx.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,7 @@
  */
 #define XSPI_CR_OFFSET		0x60	/* Control Register */
 
+#define XSPI_CR_LOOP		0x01
 #define XSPI_CR_ENABLE		0x02
 #define XSPI_CR_MASTER_MODE	0x04
 #define XSPI_CR_CPOL		0x08
@@ -315,7 +316,7 @@ static int xilinx_spi_txrx_bufs(struct s
 		}
 
 		/* See if there is more data to send */
-		if (!xspi->remaining_bytes > 0)
+		if (xspi->remaining_bytes <= 0)
 			break;
 	}
 
@@ -355,11 +356,12 @@ static const struct of_device_id xilinx_
 MODULE_DEVICE_TABLE(of, xilinx_spi_of_match);
 
 struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
-	u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word)
+	u32 irq, s16 bus_num, int num_cs, int bits_per_word)
 {
 	struct spi_master *master;
 	struct xilinx_spi *xspi;
 	int ret;
+	u32 tmp;
 
 	master = spi_alloc_master(dev, sizeof(struct xilinx_spi));
 	if (!master)
@@ -392,13 +394,25 @@ struct spi_master *xilinx_spi_init(struc
 
 	xspi->mem = *mem;
 	xspi->irq = irq;
-	if (little_endian) {
-		xspi->read_fn = xspi_read32;
-		xspi->write_fn = xspi_write32;
-	} else {
+
+	/*
+	 * Detect endianess on the IP via loop bit in CR. Detection
+	 * must be done before reset is sent because incorrect reset
+	 * value generates error interrupt.
+	 * Setup little endian helper functions first and try to use them
+	 * and check if bit was correctly setup or not.
+	 */
+	xspi->read_fn = xspi_read32;
+	xspi->write_fn = xspi_write32;
+
+	xspi->write_fn(XSPI_CR_LOOP, xspi->regs + XSPI_CR_OFFSET);
+	tmp = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET);
+	tmp &= XSPI_CR_LOOP;
+	if (tmp != XSPI_CR_LOOP) {
 		xspi->read_fn = xspi_read32_be;
 		xspi->write_fn = xspi_write32_be;
 	}
+
 	xspi->bits_per_word = bits_per_word;
 	if (xspi->bits_per_word == 8) {
 		xspi->tx_fn = xspi_tx8;
@@ -462,14 +476,13 @@ static int xilinx_spi_probe(struct platf
 {
 	struct xspi_platform_data *pdata;
 	struct resource *r;
-	int irq, num_cs = 0, little_endian = 0, bits_per_word = 8;
+	int irq, num_cs = 0, bits_per_word = 8;
 	struct spi_master *master;
 	u8 i;
 
 	pdata = dev->dev.platform_data;
 	if (pdata) {
 		num_cs = pdata->num_chipselect;
-		little_endian = pdata->little_endian;
 		bits_per_word = pdata->bits_per_word;
 	}
 
@@ -501,7 +514,7 @@ static int xilinx_spi_probe(struct platf
 		return -ENXIO;
 
 	master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs,
-				 little_endian, bits_per_word);
+				 bits_per_word);
 	if (!master)
 		return -ENODEV;
 
@@ -517,7 +530,6 @@ static int xilinx_spi_probe(struct platf
 static int xilinx_spi_remove(struct platform_device *dev)
 {
 	xilinx_spi_deinit(platform_get_drvdata(dev));
-	platform_set_drvdata(dev, 0);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ssb/driver_chipcommon_sflash.c linux-libre-3.11-rc7-gnu/drivers/ssb/driver_chipcommon_sflash.c
--- linux-libre-3.10-gnu/drivers/ssb/driver_chipcommon_sflash.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ssb/driver_chipcommon_sflash.c	2013-08-25 20:43:22.000000000 -0400
@@ -9,6 +9,19 @@
 
 #include "ssb_private.h"
 
+static struct resource ssb_sflash_resource = {
+	.name	= "ssb_sflash",
+	.start	= SSB_FLASH2,
+	.end	= 0,
+	.flags  = IORESOURCE_MEM | IORESOURCE_READONLY,
+};
+
+struct platform_device ssb_sflash_dev = {
+	.name		= "ssb_sflash",
+	.resource	= &ssb_sflash_resource,
+	.num_resources	= 1,
+};
+
 struct ssb_sflash_tbl_e {
 	char *name;
 	u32 id;
@@ -16,7 +29,7 @@ struct ssb_sflash_tbl_e {
 	u16 numblocks;
 };
 
-static struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = {
+static const struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = {
 	{ "M25P20", 0x11, 0x10000, 4, },
 	{ "M25P40", 0x12, 0x10000, 8, },
 
@@ -27,7 +40,7 @@ static struct ssb_sflash_tbl_e ssb_sflas
 	{ 0 },
 };
 
-static struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = {
+static const struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = {
 	{ "SST25WF512", 1, 0x1000, 16, },
 	{ "SST25VF512", 0x48, 0x1000, 16, },
 	{ "SST25WF010", 2, 0x1000, 32, },
@@ -45,7 +58,7 @@ static struct ssb_sflash_tbl_e ssb_sflas
 	{ 0 },
 };
 
-static struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = {
+static const struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = {
 	{ "AT45DB011", 0xc, 256, 512, },
 	{ "AT45DB021", 0x14, 256, 1024, },
 	{ "AT45DB041", 0x1c, 256, 2048, },
@@ -73,7 +86,8 @@ static void ssb_sflash_cmd(struct ssb_ch
 /* Initialize serial flash access */
 int ssb_sflash_init(struct ssb_chipcommon *cc)
 {
-	struct ssb_sflash_tbl_e *e;
+	struct ssb_sflash *sflash = &cc->dev->bus->mipscore.sflash;
+	const struct ssb_sflash_tbl_e *e;
 	u32 id, id2;
 
 	switch (cc->capabilities & SSB_CHIPCO_CAP_FLASHT) {
@@ -131,9 +145,21 @@ int ssb_sflash_init(struct ssb_chipcommo
 		return -ENOTSUPP;
 	}
 
+	sflash->window = SSB_FLASH2;
+	sflash->blocksize = e->blocksize;
+	sflash->numblocks = e->numblocks;
+	sflash->size = sflash->blocksize * sflash->numblocks;
+	sflash->present = true;
+
 	pr_info("Found %s serial flash (blocksize: 0x%X, blocks: %d)\n",
 		e->name, e->blocksize, e->numblocks);
 
+	/* Prepare platform device, but don't register it yet. It's too early,
+	 * malloc (required by device_private_init) is not available yet. */
+	ssb_sflash_dev.resource[0].end = ssb_sflash_dev.resource[0].start +
+					 sflash->size;
+	ssb_sflash_dev.dev.platform_data = sflash;
+
 	pr_err("Serial flash support is not implemented yet!\n");
 
 	return -ENOTSUPP;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ssb/Kconfig linux-libre-3.11-rc7-gnu/drivers/ssb/Kconfig
--- linux-libre-3.10-gnu/drivers/ssb/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ssb/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -144,7 +144,7 @@ config SSB_SFLASH
 # Assumption: We are on embedded, if we compile the MIPS core.
 config SSB_EMBEDDED
 	bool
-	depends on SSB_DRIVER_MIPS
+	depends on SSB_DRIVER_MIPS && SSB_PCICORE_HOSTMODE
 	default y
 
 config SSB_DRIVER_EXTIF
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ssb/main.c linux-libre-3.11-rc7-gnu/drivers/ssb/main.c
--- linux-libre-3.10-gnu/drivers/ssb/main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ssb/main.c	2013-08-25 20:43:22.000000000 -0400
@@ -553,6 +553,14 @@ static int ssb_devices_register(struct s
 	}
 #endif
 
+#ifdef CONFIG_SSB_SFLASH
+	if (bus->mipscore.sflash.present) {
+		err = platform_device_register(&ssb_sflash_dev);
+		if (err)
+			pr_err("Error registering serial flash\n");
+	}
+#endif
+
 	return 0;
 error:
 	/* Unwind the already registered devices. */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ssb/pcihost_wrapper.c linux-libre-3.11-rc7-gnu/drivers/ssb/pcihost_wrapper.c
--- linux-libre-3.10-gnu/drivers/ssb/pcihost_wrapper.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ssb/pcihost_wrapper.c	2013-08-25 20:43:22.000000000 -0400
@@ -38,7 +38,7 @@ static int ssb_pcihost_resume(struct pci
 	struct ssb_bus *ssb = pci_get_drvdata(dev);
 	int err;
 
-	pci_set_power_state(dev, 0);
+	pci_set_power_state(dev, PCI_D0);
 	err = pci_enable_device(dev);
 	if (err)
 		return err;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ssb/sprom.c linux-libre-3.11-rc7-gnu/drivers/ssb/sprom.c
--- linux-libre-3.10-gnu/drivers/ssb/sprom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ssb/sprom.c	2013-08-25 20:43:22.000000000 -0400
@@ -54,7 +54,7 @@ static int hex2sprom(u16 *sprom, const c
 	while (cnt < sprom_size_words) {
 		memcpy(tmp, dump, 4);
 		dump += 4;
-		err = strict_strtoul(tmp, 16, &parsed);
+		err = kstrtoul(tmp, 16, &parsed);
 		if (err)
 			return err;
 		sprom[cnt++] = swab16((u16)parsed);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ssb/ssb_private.h linux-libre-3.11-rc7-gnu/drivers/ssb/ssb_private.h
--- linux-libre-3.10-gnu/drivers/ssb/ssb_private.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ssb/ssb_private.h	2013-08-25 20:43:22.000000000 -0400
@@ -243,6 +243,10 @@ static inline int ssb_sflash_init(struct
 extern struct platform_device ssb_pflash_dev;
 #endif
 
+#ifdef CONFIG_SSB_SFLASH
+extern struct platform_device ssb_sflash_dev;
+#endif
+
 #ifdef CONFIG_SSB_DRIVER_EXTIF
 extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks);
 extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ssbi/Kconfig linux-libre-3.11-rc7-gnu/drivers/ssbi/Kconfig
--- linux-libre-3.10-gnu/drivers/ssbi/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ssbi/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-#
-# SSBI bus support
-#
-
-menu "Qualcomm MSM SSBI bus support"
-
-config SSBI
-	tristate "Qualcomm Single-wire Serial Bus Interface (SSBI)"
-	help
-	  If you say yes to this option, support will be included for the
-	  built-in SSBI interface on Qualcomm MSM family processors.
-
-	  This is required for communicating with Qualcomm PMICs and
-	  other devices that have the SSBI interface.
-
-endmenu
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ssbi/Makefile linux-libre-3.11-rc7-gnu/drivers/ssbi/Makefile
--- linux-libre-3.10-gnu/drivers/ssbi/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ssbi/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-obj-$(CONFIG_SSBI) += ssbi.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/ssbi/ssbi.c linux-libre-3.11-rc7-gnu/drivers/ssbi/ssbi.c
--- linux-libre-3.10-gnu/drivers/ssbi/ssbi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/ssbi/ssbi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,379 +0,0 @@
-/* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
- * Copyright (c) 2010, Google Inc.
- *
- * Original authors: Code Aurora Forum
- *
- * Author: Dima Zavin <dima@android.com>
- *  - Largely rewritten from original to not be an i2c driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/ssbi.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-
-/* SSBI 2.0 controller registers */
-#define SSBI2_CMD			0x0008
-#define SSBI2_RD			0x0010
-#define SSBI2_STATUS			0x0014
-#define SSBI2_MODE2			0x001C
-
-/* SSBI_CMD fields */
-#define SSBI_CMD_RDWRN			(1 << 24)
-
-/* SSBI_STATUS fields */
-#define SSBI_STATUS_RD_READY		(1 << 2)
-#define SSBI_STATUS_READY		(1 << 1)
-#define SSBI_STATUS_MCHN_BUSY		(1 << 0)
-
-/* SSBI_MODE2 fields */
-#define SSBI_MODE2_REG_ADDR_15_8_SHFT	0x04
-#define SSBI_MODE2_REG_ADDR_15_8_MASK	(0x7f << SSBI_MODE2_REG_ADDR_15_8_SHFT)
-
-#define SET_SSBI_MODE2_REG_ADDR_15_8(MD, AD) \
-	(((MD) & 0x0F) | ((((AD) >> 8) << SSBI_MODE2_REG_ADDR_15_8_SHFT) & \
-	SSBI_MODE2_REG_ADDR_15_8_MASK))
-
-/* SSBI PMIC Arbiter command registers */
-#define SSBI_PA_CMD			0x0000
-#define SSBI_PA_RD_STATUS		0x0004
-
-/* SSBI_PA_CMD fields */
-#define SSBI_PA_CMD_RDWRN		(1 << 24)
-#define SSBI_PA_CMD_ADDR_MASK		0x7fff /* REG_ADDR_7_0, REG_ADDR_8_14*/
-
-/* SSBI_PA_RD_STATUS fields */
-#define SSBI_PA_RD_STATUS_TRANS_DONE	(1 << 27)
-#define SSBI_PA_RD_STATUS_TRANS_DENIED	(1 << 26)
-
-#define SSBI_TIMEOUT_US			100
-
-struct ssbi {
-	struct device		*slave;
-	void __iomem		*base;
-	spinlock_t		lock;
-	enum ssbi_controller_type controller_type;
-	int (*read)(struct ssbi *, u16 addr, u8 *buf, int len);
-	int (*write)(struct ssbi *, u16 addr, u8 *buf, int len);
-};
-
-#define to_ssbi(dev)	platform_get_drvdata(to_platform_device(dev))
-
-static inline u32 ssbi_readl(struct ssbi *ssbi, u32 reg)
-{
-	return readl(ssbi->base + reg);
-}
-
-static inline void ssbi_writel(struct ssbi *ssbi, u32 val, u32 reg)
-{
-	writel(val, ssbi->base + reg);
-}
-
-/*
- * Via private exchange with one of the original authors, the hardware
- * should generally finish a transaction in about 5us.  The worst
- * case, is when using the arbiter and both other CPUs have just
- * started trying to use the SSBI bus will result in a time of about
- * 20us.  It should never take longer than this.
- *
- * As such, this wait merely spins, with a udelay.
- */
-static int ssbi_wait_mask(struct ssbi *ssbi, u32 set_mask, u32 clr_mask)
-{
-	u32 timeout = SSBI_TIMEOUT_US;
-	u32 val;
-
-	while (timeout--) {
-		val = ssbi_readl(ssbi, SSBI2_STATUS);
-		if (((val & set_mask) == set_mask) && ((val & clr_mask) == 0))
-			return 0;
-		udelay(1);
-	}
-
-	return -ETIMEDOUT;
-}
-
-static int
-ssbi_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
-{
-	u32 cmd = SSBI_CMD_RDWRN | ((addr & 0xff) << 16);
-	int ret = 0;
-
-	if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
-		u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
-		mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
-		ssbi_writel(ssbi, mode2, SSBI2_MODE2);
-	}
-
-	while (len) {
-		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
-		if (ret)
-			goto err;
-
-		ssbi_writel(ssbi, cmd, SSBI2_CMD);
-		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_RD_READY, 0);
-		if (ret)
-			goto err;
-		*buf++ = ssbi_readl(ssbi, SSBI2_RD) & 0xff;
-		len--;
-	}
-
-err:
-	return ret;
-}
-
-static int
-ssbi_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
-{
-	int ret = 0;
-
-	if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
-		u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
-		mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
-		ssbi_writel(ssbi, mode2, SSBI2_MODE2);
-	}
-
-	while (len) {
-		ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
-		if (ret)
-			goto err;
-
-		ssbi_writel(ssbi, ((addr & 0xff) << 16) | *buf, SSBI2_CMD);
-		ret = ssbi_wait_mask(ssbi, 0, SSBI_STATUS_MCHN_BUSY);
-		if (ret)
-			goto err;
-		buf++;
-		len--;
-	}
-
-err:
-	return ret;
-}
-
-/*
- * See ssbi_wait_mask for an explanation of the time and the
- * busywait.
- */
-static inline int
-ssbi_pa_transfer(struct ssbi *ssbi, u32 cmd, u8 *data)
-{
-	u32 timeout = SSBI_TIMEOUT_US;
-	u32 rd_status = 0;
-
-	ssbi_writel(ssbi, cmd, SSBI_PA_CMD);
-
-	while (timeout--) {
-		rd_status = ssbi_readl(ssbi, SSBI_PA_RD_STATUS);
-
-		if (rd_status & SSBI_PA_RD_STATUS_TRANS_DENIED)
-			return -EPERM;
-
-		if (rd_status & SSBI_PA_RD_STATUS_TRANS_DONE) {
-			if (data)
-				*data = rd_status & 0xff;
-			return 0;
-		}
-		udelay(1);
-	}
-
-	return -ETIMEDOUT;
-}
-
-static int
-ssbi_pa_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
-{
-	u32 cmd;
-	int ret = 0;
-
-	cmd = SSBI_PA_CMD_RDWRN | (addr & SSBI_PA_CMD_ADDR_MASK) << 8;
-
-	while (len) {
-		ret = ssbi_pa_transfer(ssbi, cmd, buf);
-		if (ret)
-			goto err;
-		buf++;
-		len--;
-	}
-
-err:
-	return ret;
-}
-
-static int
-ssbi_pa_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
-{
-	u32 cmd;
-	int ret = 0;
-
-	while (len) {
-		cmd = (addr & SSBI_PA_CMD_ADDR_MASK) << 8 | *buf;
-		ret = ssbi_pa_transfer(ssbi, cmd, NULL);
-		if (ret)
-			goto err;
-		buf++;
-		len--;
-	}
-
-err:
-	return ret;
-}
-
-int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
-{
-	struct ssbi *ssbi = to_ssbi(dev);
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&ssbi->lock, flags);
-	ret = ssbi->read(ssbi, addr, buf, len);
-	spin_unlock_irqrestore(&ssbi->lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(ssbi_read);
-
-int ssbi_write(struct device *dev, u16 addr, u8 *buf, int len)
-{
-	struct ssbi *ssbi = to_ssbi(dev);
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&ssbi->lock, flags);
-	ret = ssbi->write(ssbi, addr, buf, len);
-	spin_unlock_irqrestore(&ssbi->lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(ssbi_write);
-
-static int ssbi_probe(struct platform_device *pdev)
-{
-	struct device_node *np = pdev->dev.of_node;
-	struct resource *mem_res;
-	struct ssbi *ssbi;
-	int ret = 0;
-	const char *type;
-
-	ssbi = kzalloc(sizeof(struct ssbi), GFP_KERNEL);
-	if (!ssbi) {
-		pr_err("can not allocate ssbi_data\n");
-		return -ENOMEM;
-	}
-
-	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem_res) {
-		pr_err("missing mem resource\n");
-		ret = -EINVAL;
-		goto err_get_mem_res;
-	}
-
-	ssbi->base = ioremap(mem_res->start, resource_size(mem_res));
-	if (!ssbi->base) {
-		pr_err("ioremap of 0x%p failed\n", (void *)mem_res->start);
-		ret = -EINVAL;
-		goto err_ioremap;
-	}
-	platform_set_drvdata(pdev, ssbi);
-
-	type = of_get_property(np, "qcom,controller-type", NULL);
-	if (type == NULL) {
-		pr_err("Missing qcom,controller-type property\n");
-		ret = -EINVAL;
-		goto err_ssbi_controller;
-	}
-	dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type);
-	if (strcmp(type, "ssbi") == 0)
-		ssbi->controller_type = MSM_SBI_CTRL_SSBI;
-	else if (strcmp(type, "ssbi2") == 0)
-		ssbi->controller_type = MSM_SBI_CTRL_SSBI2;
-	else if (strcmp(type, "pmic-arbiter") == 0)
-		ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER;
-	else {
-		pr_err("Unknown qcom,controller-type\n");
-		ret = -EINVAL;
-		goto err_ssbi_controller;
-	}
-
-	if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
-		ssbi->read = ssbi_pa_read_bytes;
-		ssbi->write = ssbi_pa_write_bytes;
-	} else {
-		ssbi->read = ssbi_read_bytes;
-		ssbi->write = ssbi_write_bytes;
-	}
-
-	spin_lock_init(&ssbi->lock);
-
-	ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
-	if (ret)
-		goto err_ssbi_controller;
-
-	return 0;
-
-err_ssbi_controller:
-	platform_set_drvdata(pdev, NULL);
-	iounmap(ssbi->base);
-err_ioremap:
-err_get_mem_res:
-	kfree(ssbi);
-	return ret;
-}
-
-static int ssbi_remove(struct platform_device *pdev)
-{
-	struct ssbi *ssbi = platform_get_drvdata(pdev);
-
-	platform_set_drvdata(pdev, NULL);
-	iounmap(ssbi->base);
-	kfree(ssbi);
-	return 0;
-}
-
-static struct of_device_id ssbi_match_table[] = {
-	{ .compatible = "qcom,ssbi" },
-	{}
-};
-
-static struct platform_driver ssbi_driver = {
-	.probe		= ssbi_probe,
-	.remove		= ssbi_remove,
-	.driver		= {
-		.name	= "ssbi",
-		.owner	= THIS_MODULE,
-		.of_match_table = ssbi_match_table,
-	},
-};
-
-static int __init ssbi_init(void)
-{
-	return platform_driver_register(&ssbi_driver);
-}
-module_init(ssbi_init);
-
-static void __exit ssbi_exit(void)
-{
-	platform_driver_unregister(&ssbi_driver);
-}
-module_exit(ssbi_exit)
-
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:ssbi");
-MODULE_AUTHOR("Dima Zavin <dima@android.com>");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/android/ashmem.c linux-libre-3.11-rc7-gnu/drivers/staging/android/ashmem.c
--- linux-libre-3.10-gnu/drivers/staging/android/ashmem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/android/ashmem.c	2013-08-25 20:43:22.000000000 -0400
@@ -704,7 +704,8 @@ static long ashmem_ioctl(struct file *fi
 
 /* support of 32bit userspace on 64bit platforms */
 #ifdef CONFIG_COMPAT
-static long compat_ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long compat_ashmem_ioctl(struct file *file, unsigned int cmd,
+				unsigned long arg)
 {
 
 	switch (cmd) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/android/binder.c linux-libre-3.11-rc7-gnu/drivers/staging/android/binder.c
--- linux-libre-3.10-gnu/drivers/staging/android/binder.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/android/binder.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,6 +20,7 @@
 #include <asm/cacheflush.h>
 #include <linux/fdtable.h>
 #include <linux/file.h>
+#include <linux/freezer.h>
 #include <linux/fs.h>
 #include <linux/list.h>
 #include <linux/miscdevice.h>
@@ -790,7 +791,7 @@ static void binder_delete_free_buffer(st
 	list_del(&buffer->entry);
 	if (free_page_start || free_page_end) {
 		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
-			     "%d: merge free, buffer %p do not share page%s%s with with %p or %p\n",
+			     "%d: merge free, buffer %p do not share page%s%s with %p or %p\n",
 			     proc->pid, buffer, free_page_start ? "" : " end",
 			     free_page_end ? "" : " start", prev, next);
 		binder_update_page_range(proc, 0, free_page_start ?
@@ -2140,13 +2141,13 @@ retry:
 			if (!binder_has_proc_work(proc, thread))
 				ret = -EAGAIN;
 		} else
-			ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));
+			ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
 	} else {
 		if (non_block) {
 			if (!binder_has_thread_work(thread))
 				ret = -EAGAIN;
 		} else
-			ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
+			ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread));
 	}
 
 	binder_lock(__func__);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/android/logger.c linux-libre-3.11-rc7-gnu/drivers/staging/android/logger.c
--- linux-libre-3.10-gnu/drivers/staging/android/logger.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/android/logger.c	2013-08-25 20:43:22.000000000 -0400
@@ -469,7 +469,7 @@ static ssize_t logger_aio_write(struct k
 			 unsigned long nr_segs, loff_t ppos)
 {
 	struct logger_log *log = file_get_log(iocb->ki_filp);
-	size_t orig = log->w_off;
+	size_t orig;
 	struct logger_entry header;
 	struct timespec now;
 	ssize_t ret = 0;
@@ -490,6 +490,8 @@ static ssize_t logger_aio_write(struct k
 
 	mutex_lock(&log->mutex);
 
+	orig = log->w_off;
+
 	/*
 	 * Fix up any readers, pulling them forward to the first readable
 	 * entry after (what will be) the new write offset. We do this now
@@ -696,7 +698,7 @@ static long logger_ioctl(struct file *fi
 			ret = -EBADF;
 			break;
 		}
-		if (!(in_egroup_p(file->f_dentry->d_inode->i_gid) ||
+		if (!(in_egroup_p(file_inode(file)->i_gid) ||
 				capable(CAP_SYSLOG))) {
 			ret = -EPERM;
 			break;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/android/sw_sync.c linux-libre-3.11-rc7-gnu/drivers/staging/android/sw_sync.c
--- linux-libre-3.10-gnu/drivers/staging/android/sw_sync.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/android/sw_sync.c	2013-08-25 20:43:22.000000000 -0400
@@ -160,7 +160,8 @@ static int sw_sync_release(struct inode
 	return 0;
 }
 
-static long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, unsigned long arg)
+static long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj,
+				       unsigned long arg)
 {
 	int fd = get_unused_fd();
 	int err;
@@ -218,7 +219,8 @@ static long sw_sync_ioctl_inc(struct sw_
 	return 0;
 }
 
-static long sw_sync_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long sw_sync_ioctl(struct file *file, unsigned int cmd,
+			  unsigned long arg)
 {
 	struct sw_sync_timeline *obj = file->private_data;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/android/sync.c linux-libre-3.11-rc7-gnu/drivers/staging/android/sync.c
--- linux-libre-3.10-gnu/drivers/staging/android/sync.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/android/sync.c	2013-08-25 20:43:22.000000000 -0400
@@ -125,9 +125,9 @@ static void sync_timeline_remove_pt(stru
 	spin_unlock_irqrestore(&obj->active_list_lock, flags);
 
 	spin_lock_irqsave(&obj->child_list_lock, flags);
-	if (!list_empty(&pt->child_list)) {
+	if (!list_empty(&pt->child_list))
 		list_del_init(&pt->child_list);
-	}
+
 	spin_unlock_irqrestore(&obj->child_list_lock, flags);
 }
 
@@ -876,11 +876,11 @@ static void sync_print_pt(struct seq_fil
 			seq_printf(s, " / %s", value);
 		}
 	} else if (pt->parent->ops->print_pt) {
-		seq_printf(s, ": ");
+		seq_puts(s, ": ");
 		pt->parent->ops->print_pt(s, pt);
 	}
 
-	seq_printf(s, "\n");
+	seq_puts(s, "\n");
 }
 
 static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
@@ -895,11 +895,11 @@ static void sync_print_obj(struct seq_fi
 		obj->ops->timeline_value_str(obj, value, sizeof(value));
 		seq_printf(s, ": %s", value);
 	} else if (obj->ops->print_obj) {
-		seq_printf(s, ": ");
+		seq_puts(s, ": ");
 		obj->ops->print_obj(s, obj);
 	}
 
-	seq_printf(s, "\n");
+	seq_puts(s, "\n");
 
 	spin_lock_irqsave(&obj->child_list_lock, flags);
 	list_for_each(pos, &obj->child_list_head) {
@@ -940,7 +940,7 @@ static int sync_debugfs_show(struct seq_
 	unsigned long flags;
 	struct list_head *pos;
 
-	seq_printf(s, "objs:\n--------------\n");
+	seq_puts(s, "objs:\n--------------\n");
 
 	spin_lock_irqsave(&sync_timeline_list_lock, flags);
 	list_for_each(pos, &sync_timeline_list_head) {
@@ -949,11 +949,11 @@ static int sync_debugfs_show(struct seq_
 				     sync_timeline_list);
 
 		sync_print_obj(s, obj);
-		seq_printf(s, "\n");
+		seq_puts(s, "\n");
 	}
 	spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
 
-	seq_printf(s, "fences:\n--------------\n");
+	seq_puts(s, "fences:\n--------------\n");
 
 	spin_lock_irqsave(&sync_fence_list_lock, flags);
 	list_for_each(pos, &sync_fence_list_head) {
@@ -961,7 +961,7 @@ static int sync_debugfs_show(struct seq_
 			container_of(pos, struct sync_fence, sync_fence_list);
 
 		sync_print_fence(s, fence);
-		seq_printf(s, "\n");
+		seq_puts(s, "\n");
 	}
 	spin_unlock_irqrestore(&sync_fence_list_lock, flags);
 	return 0;
@@ -988,7 +988,7 @@ late_initcall(sync_debugfs_init);
 
 #define DUMP_CHUNK 256
 static char sync_dump_buf[64 * 1024];
-void sync_dump(void)
+static void sync_dump(void)
 {
 	struct seq_file s = {
 		.buf = sync_dump_buf,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/android/timed_output.c linux-libre-3.11-rc7-gnu/drivers/staging/android/timed_output.c
--- linux-libre-3.10-gnu/drivers/staging/android/timed_output.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/android/timed_output.c	2013-08-25 20:43:22.000000000 -0400
@@ -78,7 +78,7 @@ int timed_output_dev_register(struct tim
 
 	tdev->index = atomic_inc_return(&device_count);
 	tdev->dev = device_create(timed_output_class, NULL,
-		MKDEV(0, tdev->index), NULL, tdev->name);
+		MKDEV(0, tdev->index), NULL, "%s", tdev->name);
 	if (IS_ERR(tdev->dev))
 		return PTR_ERR(tdev->dev);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/asus_oled/asus_oled.c linux-libre-3.11-rc7-gnu/drivers/staging/asus_oled/asus_oled.c
--- linux-libre-3.10-gnu/drivers/staging/asus_oled/asus_oled.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/asus_oled/asus_oled.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,9 +50,9 @@
 #define ASUS_OLED_DISP_HEIGHT		32
 #define ASUS_OLED_PACKET_BUF_SIZE	256
 
-#define USB_VENDOR_ID_ASUS      0x0b05
-#define USB_DEVICE_ID_ASUS_LCM      0x1726
-#define USB_DEVICE_ID_ASUS_LCM2     0x175b
+#define USB_VENDOR_ID_ASUS		0x0b05
+#define USB_DEVICE_ID_ASUS_LCM		0x1726
+#define USB_DEVICE_ID_ASUS_LCM2		0x175b
 
 MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
 MODULE_DESCRIPTION("Asus OLED Driver");
@@ -324,9 +324,11 @@ static void send_data(struct asus_oled_d
 		return;
 
 	if (odev->pack_mode == PACK_MODE_G1) {
-		/* When sending roll-mode data the display updated only
-		   first packet.  I have no idea why, but when static picture
-		   is sent just before rolling picture everything works fine. */
+		/*
+		 * When sending roll-mode data the display updated only
+		 * first packet.  I have no idea why, but when static picture
+		 * is sent just before rolling picture everything works fine.
+		 */
 		if (odev->pic_mode == ASUS_OLED_ROLL)
 			send_packets(odev->udev, packet, odev->buf,
 				     ASUS_OLED_STATIC, 2);
@@ -363,9 +365,11 @@ static int append_values(struct asus_ole
 
 		switch (odev->pack_mode) {
 		case PACK_MODE_G1:
-			/* i = (x/128)*640 + 127 - x + (y/8)*128;
-			   This one for 128 is the same, but might be better
-			   for different widths? */
+			/*
+			 * i = (x/128)*640 + 127 - x + (y/8)*128;
+			 * This one for 128 is the same, but might be better
+			 * for different widths?
+			 */
 			i = (x/odev->dev_width)*640 +
 				odev->dev_width - 1 - x +
 				(y/8)*odev->dev_width;
@@ -383,10 +387,8 @@ static int append_values(struct asus_ole
 		}
 
 		if (i >= odev->buf_size) {
-			dev_err(odev->dev, "Buffer overflow! Report a bug:"
-			       "offs: %d >= %d i: %d (x: %d y: %d)\n",
-			       (int) odev->buf_offs, (int) odev->buf_size,
-			       (int) i, (int) x, (int) y);
+			dev_err(odev->dev, "Buffer overflow! Report a bug: offs: %zu >= %zu i: %zu (x: %zu y: %zu)\n",
+			       odev->buf_offs, odev->buf_size, i, x, y);
 			return -EIO;
 		}
 
@@ -401,7 +403,7 @@ static int append_values(struct asus_ole
 
 		default:
 			/* cannot get here; stops gcc complaining*/
-			;
+			break;
 		}
 
 		odev->buf_offs++;
@@ -566,9 +568,11 @@ static ssize_t odev_set_picture(struct a
 			if (ret < 0)
 				return ret;
 		} else if (buf[offs] == '\n') {
-			/* New line detected. Lets assume, that all characters
-			   till the end of the line were equal to the last
-			   character in this line.*/
+			/*
+			 * New line detected. Lets assume, that all characters
+			 * till the end of the line were equal to the last
+			 * character in this line.
+			 */
 			if (odev->buf_offs % odev->width != 0)
 				ret = append_values(odev, odev->last_val,
 						    odev->width -
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/bcm/Bcmchar.c linux-libre-3.11-rc7-gnu/drivers/staging/bcm/Bcmchar.c
--- linux-libre-3.10-gnu/drivers/staging/bcm/Bcmchar.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/bcm/Bcmchar.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 * Returns	  - Zero(Success)
 ****************************************************************/
 
-static int bcm_char_open(struct inode *inode, struct file * filp)
+static int bcm_char_open(struct inode *inode, struct file *filp)
 {
 	struct bcm_mini_adapter *Adapter = NULL;
 	struct bcm_tarang_data *pTarang = NULL;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/bcm/InterfaceIdleMode.c linux-libre-3.11-rc7-gnu/drivers/staging/bcm/InterfaceIdleMode.c
--- linux-libre-3.10-gnu/drivers/staging/bcm/InterfaceIdleMode.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/bcm/InterfaceIdleMode.c	2013-08-25 20:43:22.000000000 -0400
@@ -42,107 +42,95 @@ send to f/w with in 200 ms after the Idl
 */
 
 
-int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int* puiBuffer)
+int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int *puiBuffer)
 {
 	int	status = STATUS_SUCCESS;
 	unsigned int	uiRegRead = 0;
 	int bytes;
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"SubType of Message :0x%X", ntohl(*puiBuffer));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "SubType of Message :0x%X", ntohl(*puiBuffer));
 
-	if(ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL," Got GO_TO_IDLE_MODE_PAYLOAD(210) Msg Subtype");
-		if(ntohl(*(puiBuffer+1)) == 0 )
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Got IDLE MODE WAKE UP Response From F/W");
+	if (ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, " Got GO_TO_IDLE_MODE_PAYLOAD(210) Msg Subtype");
+		if (ntohl(*(puiBuffer+1)) == 0 ) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Got IDLE MODE WAKE UP Response From F/W");
 
-			status = wrmalt (Adapter,SW_ABORT_IDLEMODE_LOC, &uiRegRead, sizeof(uiRegRead));
-			if(status)
-			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg");
+			status = wrmalt (Adapter, SW_ABORT_IDLEMODE_LOC, &uiRegRead, sizeof(uiRegRead));
+			if (status) {
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg");
 				return status;
 			}
 
-			if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
-			{
+			if (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) {
 				uiRegRead = 0x00000000 ;
-				status = wrmalt (Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegRead, sizeof(uiRegRead));
-				if(status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode	Reg");
+				status = wrmalt (Adapter, DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegRead, sizeof(uiRegRead));
+				if (status) {
+					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode	Reg");
 					return status;
 				}
 			}
-			//Below Register should not br read in case of Manual and Protocol Idle mode.
-			else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
-			{
-				//clear on read Register
+			/* Below Register should not br read in case of Manual and Protocol Idle mode */
+			else if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) {
+				/* clear on read Register */
 				bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegRead, sizeof(uiRegRead));
 				if (bytes < 0) {
 					status = bytes;
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg0");
+					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg0");
 					return status;
 				}
-				//clear on read Register
+				/* clear on read Register */
 				bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegRead, sizeof(uiRegRead));
 				if (bytes < 0) {
 					status = bytes;
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort	Reg1");
+					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort	Reg1");
 					return status;
 				}
 			}
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Device Up from Idle Mode");
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Device Up from Idle Mode");
 
-			// Set Idle Mode Flag to False and Clear IdleMode reg.
+			/* Set Idle Mode Flag to False and Clear IdleMode reg. */
 			Adapter->IdleMode = FALSE;
 			Adapter->bTriedToWakeUpFromlowPowerMode = FALSE;
 
 			wake_up(&Adapter->lowpower_mode_wait_queue);
 
-		}
-		else
-		{
-			if(TRUE == Adapter->IdleMode)
+		} else {
+			if (TRUE == Adapter->IdleMode)
 			{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Device is already in Idle mode....");
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Device is already in Idle mode....");
 				return status ;
 			}
 
 			uiRegRead = 0;
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Got Req from F/W to go in IDLE mode \n");
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Got Req from F/W to go in IDLE mode \n");
 
-			if (Adapter->chip_id== BCS220_2 ||
+			if (Adapter->chip_id == BCS220_2 ||
 				Adapter->chip_id == BCS220_2BC ||
-					Adapter->chip_id== BCS250_BC ||
-					Adapter->chip_id== BCS220_3)
-			{
+					Adapter->chip_id == BCS250_BC ||
+					Adapter->chip_id == BCS220_3) {
 
 				bytes = rdmalt(Adapter, HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead));
 				if (bytes < 0) {
 					status = bytes;
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "rdm failed while Reading HPM_CONFIG_LDO145 Reg 0\n");
+					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "rdm failed while Reading HPM_CONFIG_LDO145 Reg 0\n");
 					return status;
 				}
 
 
 				uiRegRead |= (1<<17);
 
-				status = wrmalt (Adapter,HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead));
-				if(status)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg\n");
+				status = wrmalt (Adapter, HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead));
+				if (status) {
+					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg\n");
 					return status;
 				}
 
 			}
 			SendIdleModeResponse(Adapter);
 		}
-	}
-	else if(ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "OverRiding Service Flow Params");
-		OverrideServiceFlowParams(Adapter,puiBuffer);
+	} else if (ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "OverRiding Service Flow Params");
+		OverrideServiceFlowParams(Adapter, puiBuffer);
 	}
 	return status;
 }
@@ -152,46 +140,40 @@ static int InterfaceAbortIdlemode(struct
 	int 	status = STATUS_SUCCESS;
 	unsigned int value;
 	unsigned int chip_id ;
-	unsigned long timeout = 0 ,itr = 0;
+	unsigned long timeout = 0, itr = 0;
 
 	int 	lenwritten = 0;
-	unsigned char aucAbortPattern[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+	unsigned char aucAbortPattern[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 	struct bcm_interface_adapter *psInterfaceAdapter = Adapter->pvInterfaceAdapter;
 
-	//Abort Bus suspend if its already suspended
-	if((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend))
-	{
+	/* Abort Bus suspend if its already suspended */
+	if ((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend)) {
 		status = usb_autopm_get_interface(psInterfaceAdapter->interface);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Bus got wakeup..Aborting Idle mode... status:%d \n",status);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Bus got wakeup..Aborting Idle mode... status:%d \n", status);
 
 	}
 
-	if((Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
+	if ((Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
 									||
-	   (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE))
-	{
-		//write the SW abort pattern.
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing pattern<%d> to SW_ABORT_IDLEMODE_LOC\n", Pattern);
-		status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(Pattern));
-		if(status)
-		{
-				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
+	   (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) {
+		/* write the SW abort pattern. */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing pattern<%d> to SW_ABORT_IDLEMODE_LOC\n", Pattern);
+		status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(Pattern));
+		if (status) {
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
 				return status;
 		}
 	}
 
-	if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
-	{
+	if (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) {
 		value = 0x80000000;
-		status = wrmalt(Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &value, sizeof(value));
-		if(status)
+		status = wrmalt(Adapter, DEBUG_INTERRUPT_GENERATOR_REGISTOR, &value, sizeof(value));
+		if (status)
 		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Register failed");
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Register failed");
 			return status;
 		}
-	}
-	else if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)
-	{
+	} else if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) {
 		/*
 		 * Get a Interrupt Out URB and send 8 Bytes Down
 		 * To be Done in Thread Context.
@@ -204,43 +186,32 @@ static int InterfaceAbortIdlemode(struct
 			8,
 			&lenwritten,
 			5000);
-		if(status)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Sending Abort pattern down fails with status:%d..\n",status);
+		if (status) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Sending Abort pattern down fails with status:%d..\n", status);
 			return status;
-		}
-		else
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "NOB Sent down :%d", lenwritten);
+		} else {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "NOB Sent down :%d", lenwritten);
 		}
 
-		//mdelay(25);
+		/* mdelay(25); */
 
-		timeout= jiffies +  msecs_to_jiffies(50) ;
-		while( timeout > jiffies )
-		{
+		timeout = jiffies +  msecs_to_jiffies(50) ;
+		while ( timeout > jiffies ) {
 			itr++ ;
 			rdmalt(Adapter, CHIP_ID_REG, &chip_id, sizeof(UINT));
-			if(0xbece3200==(chip_id&~(0xF0)))
-			{
+			if (0xbece3200 == (chip_id&~(0xF0)))
 				chip_id = chip_id&~(0xF0);
-			}
-			if(chip_id == Adapter->chip_id)
+			if (chip_id == Adapter->chip_id)
 				break;
 		}
-		if(timeout < jiffies )
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Not able to read chip-id even after 25 msec");
-		}
+		if (timeout < jiffies )
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Not able to read chip-id even after 25 msec");
 		else
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Number of completed iteration to read chip-id :%lu", itr);
-		}
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Number of completed iteration to read chip-id :%lu", itr);
 
-		status = wrmalt(Adapter,SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(status));
-		if(status)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
+		status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(status));
+		if (status) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to Register SW_ABORT_IDLEMODE_LOC failed..");
 			return status;
 		}
 	}
@@ -249,13 +220,10 @@ static int InterfaceAbortIdlemode(struct
 int InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter)
 {
 	ULONG	Status = 0;
-	if(Adapter->bTriedToWakeUpFromlowPowerMode)
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Wake up already attempted.. ignoring\n");
-	}
-	else
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"Writing Low Power Mode Abort pattern to the Device\n");
+	if (Adapter->bTriedToWakeUpFromlowPowerMode) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Wake up already attempted.. ignoring\n");
+	} else {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing Low Power Mode Abort pattern to the Device\n");
 		Adapter->bTriedToWakeUpFromlowPowerMode = TRUE;
 		InterfaceAbortIdlemode(Adapter, Adapter->usIdleModePattern);
 
@@ -269,33 +237,30 @@ void InterfaceHandleShutdownModeWakeup(s
 	INT Status = 0;
 	int bytes;
 
-	if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING)
-	{
-		// clear idlemode interrupt.
+	if (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) {
+		/* clear idlemode interrupt. */
 		uiRegVal = 0;
-		Status =wrmalt(Adapter,DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegVal, sizeof(uiRegVal));
-		if(Status)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Failed with err :%d", Status);
+		Status = wrmalt(Adapter, DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegVal, sizeof(uiRegVal));
+		if (Status) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Failed with err :%d", Status);
 			return;
 		}
 	}
 
-    else
-	{
+    else {
 
-        //clear Interrupt EP registers.
-		bytes = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG0, &uiRegVal, sizeof(uiRegVal));
+        /* clear Interrupt EP registers. */
+		bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegVal, sizeof(uiRegVal));
 		if (bytes < 0) {
 			Status = bytes;
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG0 failed with Err :%d", Status);
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM of DEVICE_INT_OUT_EP_REG0 failed with Err :%d", Status);
 			return;
 		}
 
-		bytes = rdmalt(Adapter,DEVICE_INT_OUT_EP_REG1, &uiRegVal, sizeof(uiRegVal));
+		bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegVal, sizeof(uiRegVal));
 		if (bytes < 0) {
 			Status = bytes;
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM of DEVICE_INT_OUT_EP_REG1 failed with Err :%d", Status);
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM of DEVICE_INT_OUT_EP_REG1 failed with Err :%d", Status);
 			return;
 		}
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/bcm/vendorspecificextn.c linux-libre-3.11-rc7-gnu/drivers/staging/bcm/vendorspecificextn.c
--- linux-libre-3.10-gnu/drivers/staging/bcm/vendorspecificextn.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/bcm/vendorspecificextn.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,70 +1,70 @@
 #include "headers.h"
-//-----------------------------------------------------------------------------
-// Procedure:	vendorextnGetSectionInfo
-//
-// Description: Finds the type of NVM used.
-//
-// Arguments:
-//		Adapter    - ptr to Adapter object instance
-//		pNVMType   - ptr to NVM type.
-// Returns:
-//		STATUS_SUCCESS/STATUS_FAILURE
-//
-//-----------------------------------------------------------------------------
+/*
+ * Procedure:	vendorextnGetSectionInfo
+ *
+ * Description: Finds the type of NVM used.
+ *
+ * Arguments:
+ *		Adapter    - ptr to Adapter object instance
+ *		pNVMType   - ptr to NVM type.
+ * Returns:
+ *		STATUS_SUCCESS/STATUS_FAILURE
+ *
+ */
 INT vendorextnGetSectionInfo(PVOID  pContext, struct bcm_flash2x_vendor_info *pVendorInfo)
 {
 	return STATUS_FAILURE;
 }
 
-//-----------------------------------------------------------------------------
-// Procedure:   vendorextnInit
-//
-// Description: Initializing the vendor extension NVM interface
-//
-// Arguments:
-//              Adapter   - Pointer to MINI Adapter Structure.
-
-// Returns:
-//              STATUS_SUCCESS/STATUS_FAILURE
-//
-//-----------------------------------------------------------------------------
+/*
+ * Procedure:   vendorextnInit
+ *
+ * Description: Initializing the vendor extension NVM interface
+ *
+ * Arguments:
+ *              Adapter   - Pointer to MINI Adapter Structure
+ * Returns:
+ *             STATUS_SUCCESS/STATUS_FAILURE
+ *
+ *
+ */
 INT vendorextnInit(struct bcm_mini_adapter *Adapter)
 {
 	return STATUS_SUCCESS;
 }
 
-//-----------------------------------------------------------------------------
-// Procedure:   vendorextnExit
-//
-// Description: Free the resource associated with vendor extension NVM interface
-//
-// Arguments:
-//              Adapter   - Pointer to MINI Adapter Structure.
-
-// Returns:
-//              STATUS_SUCCESS/STATUS_FAILURE
-//
-//-----------------------------------------------------------------------------
+/*
+ * Procedure:   vendorextnExit
+ *
+ * Description: Free the resource associated with vendor extension NVM interface
+ *
+ * Arguments:
+ *
+ * Returns:
+ *              STATUS_SUCCESS/STATUS_FAILURE
+ *
+ *
+ */
 INT vendorextnExit(struct bcm_mini_adapter *Adapter)
 {
 	return STATUS_SUCCESS;
 }
 
-//------------------------------------------------------------------------
-// Procedure:	vendorextnIoctl
-//
-// Description: 	execute the vendor extension specific ioctl
-//
-//Arguments:
-//		Adapter -Beceem private Adapter Structure
-//		cmd 	-vendor extension specific Ioctl commad
-//		arg		-input parameter sent by vendor
-//
-// Returns:
-//		CONTINUE_COMMON_PATH in case it is not meant to be processed by vendor ioctls
-//		STATUS_SUCCESS/STATUS_FAILURE as per the IOCTL return value
-//
-//--------------------------------------------------------------------------
+/*
+ * Procedure:	vendorextnIoctl
+ *
+ * Description: execute the vendor extension specific ioctl
+ *
+ * Arguments:
+ *		Adapter -Beceem private Adapter Structure
+ *		cmd	-vendor extension specific Ioctl commad
+ *		arg	-input parameter sent by vendor
+ *
+ * Returns:
+ *		CONTINUE_COMMON_PATH in case it is not meant to be processed by vendor ioctls
+ *		STATUS_SUCCESS/STATUS_FAILURE as per the IOCTL return value
+ */
+
 INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg)
 {
 	return CONTINUE_COMMON_PATH;
@@ -72,22 +72,21 @@ INT vendorextnIoctl(struct bcm_mini_adap
 
 
 
-//------------------------------------------------------------------
-// Procedure:	vendorextnReadSection
-//
-// Description: Reads from a section of NVM
-//
-// Arguments:
-//		pContext - ptr to Adapter object instance
-//		pBuffer - Read the data from Vendor Area to this buffer
-//		SectionVal   - Value of type of Section
-//		Offset - Read from the Offset of the Vendor Section.
-//		numOfBytes - Read numOfBytes from the Vendor section to Buffer
-//
-// Returns:
-//		STATUS_SUCCESS/STATUS_FAILURE
-//
-//------------------------------------------------------------------
+/*
+ * Procedure:	vendorextnReadSection
+ *
+ * Description: Reads from a section of NVM
+ *
+ * Arguments:
+ *		pContext - ptr to Adapter object instance
+ *		pBuffer - Read the data from Vendor Area to this buffer
+ *		SectionVal   - Value of type of Section
+ *		Offset - Read from the Offset of the Vendor Section.
+ *		numOfBytes - Read numOfBytes from the Vendor section to Buffer
+ *
+ * Returns:
+ *		STATUS_SUCCESS/STATUS_FAILURE
+ */
 
 INT vendorextnReadSection(PVOID  pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
 			UINT offset, UINT numOfBytes)
@@ -97,23 +96,22 @@ INT vendorextnReadSection(PVOID  pContex
 
 
 
-//------------------------------------------------------------------
-// Procedure:	vendorextnWriteSection
-//
-// Description: Write to a Section of NVM
-//
-// Arguments:
-//		pContext - ptr to Adapter object instance
-//		pBuffer - Write the data provided in the buffer
-//		SectionVal   - Value of type of Section
-//		Offset - Writes to the Offset of the Vendor Section.
-//		numOfBytes - Write num Bytes after reading from pBuffer.
-//		bVerify - the Buffer Written should be verified.
-//
-// Returns:
-//		STATUS_SUCCESS/STATUS_FAILURE
-//
-//------------------------------------------------------------------
+/*
+ * Procedure:	vendorextnWriteSection
+ *
+ * Description: Write to a Section of NVM
+ *
+ * Arguments:
+ *		pContext - ptr to Adapter object instance
+ *		pBuffer - Write the data provided in the buffer
+ *		SectionVal   - Value of type of Section
+ *		Offset - Writes to the Offset of the Vendor Section.
+ *		numOfBytes - Write num Bytes after reading from pBuffer.
+ *		bVerify - the Buffer Written should be verified.
+ *
+ * Returns:
+ *		STATUS_SUCCESS/STATUS_FAILURE
+ */
 INT vendorextnWriteSection(PVOID  pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
 			UINT offset, UINT numOfBytes, BOOLEAN bVerify)
 {
@@ -122,25 +120,23 @@ INT vendorextnWriteSection(PVOID  pConte
 
 
 
-//------------------------------------------------------------------
-// Procedure:	vendorextnWriteSectionWithoutErase
-//
-// Description: Write to a Section of NVM without erasing the sector
-//
-// Arguments:
-//		pContext - ptr to Adapter object instance
-//		pBuffer - Write the data provided in the buffer
-//		SectionVal   - Value of type of Section
-//		Offset - Writes to the Offset of the Vendor Section.
-//		numOfBytes - Write num Bytes after reading from pBuffer.
-//
-// Returns:
-//		STATUS_SUCCESS/STATUS_FAILURE
-//
-//------------------------------------------------------------------
+/*
+ * Procedure:	vendorextnWriteSectionWithoutErase
+ *
+ * Description: Write to a Section of NVM without erasing the sector
+ *
+ * Arguments:
+ *		pContext - ptr to Adapter object instance
+ *		pBuffer - Write the data provided in the buffer
+ *		SectionVal   - Value of type of Section
+ *		Offset - Writes to the Offset of the Vendor Section.
+ *		numOfBytes - Write num Bytes after reading from pBuffer.
+ *
+ * Returns:
+ *		STATUS_SUCCESS/STATUS_FAILURE
+ */
 INT vendorextnWriteSectionWithoutErase(PVOID  pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal,
 			UINT offset, UINT numOfBytes)
 {
 	return STATUS_FAILURE;
 }
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/bcm/Version.h linux-libre-3.11-rc7-gnu/drivers/staging/bcm/Version.h
--- linux-libre-3.10-gnu/drivers/staging/bcm/Version.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/bcm/Version.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,3 @@
-
 /*Copyright (c) 2005 Beceem Communications Inc.
 
 Module Name:
@@ -17,7 +16,6 @@ Abstract:
 #define VER_FILETYPE                VFT_DRV
 #define VER_FILESUBTYPE             VFT2_DRV_NETWORK
 
-
 #define VER_FILEVERSION             5.2.45
 #define VER_FILEVERSION_STR         "5.2.45"
 
@@ -28,8 +26,4 @@ Abstract:
 #define VER_PRODUCTVERSION_STR      VER_FILEVERSION_STR
 
 
-
-
-//#include "common.ver"
-
-#endif 	//VERSION_H
+#endif /* VERSION_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/btmtk_usb/btmtk_usb.c linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/btmtk_usb.c
--- linux-libre-3.10-gnu/drivers/staging/btmtk_usb/btmtk_usb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/btmtk_usb.c	2013-08-31 18:01:11.000000000 -0400
@@ -0,0 +1,1783 @@
+/*
+ *  MediaTek Bluetooth USB Driver
+ *
+ *  Copyright (C) 2013, MediaTek co.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  or on the worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <linux/completion.h>
+#include <linux/firmware.h>
+#include <linux/usb.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "btmtk_usb.h"
+
+#define VERSION "1.0.4"
+#define MT7650_FIRMWARE	"/*(DEBLOBBED)*/"
+#define MT7662_FIRMWARE	"/*(DEBLOBBED)*/"
+
+static struct usb_driver btmtk_usb_driver;
+
+
+static int btmtk_usb_load_rom_patch(struct btmtk_usb_data *);
+static int btmtk_usb_load_fw(struct btmtk_usb_data *);
+
+static void hex_dump(char *str, u8 *src_buf, u32 src_buf_len)
+{
+	unsigned char *pt;
+	int x;
+
+	pt = src_buf;
+
+	BT_DBG("%s: %p, len = %d\n", str, src_buf, src_buf_len);
+
+	for (x = 0; x < src_buf_len; x++) {
+		if (x % 16 == 0)
+			BT_DBG("0x%04x : ", x);
+		BT_DBG("%02x ", ((unsigned char)pt[x]));
+		if (x % 16 == 15)
+			BT_DBG("\n");
+	}
+
+	BT_DBG("\n");
+}
+
+static int btmtk_usb_reset(struct usb_device *udev)
+{
+	int ret;
+
+	BT_DBG("%s\n", __func__);
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, DEVICE_VENDOR_REQUEST_OUT,
+						  0x01, 0x00, NULL, 0x00, CONTROL_TIMEOUT_JIFFIES);
+
+	if (ret < 0) {
+		BT_ERR("%s error(%d)\n", __func__, ret);
+		return ret;
+	}
+
+	if (ret > 0)
+		ret = 0;
+
+	return ret;
+}
+
+static int btmtk_usb_io_read32(struct btmtk_usb_data *data, u32 reg, u32 *val)
+{
+	u8 request = data->r_request;
+	struct usb_device *udev = data->udev;
+	int ret;
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), request, DEVICE_VENDOR_REQUEST_IN,
+						  0x0, reg, data->io_buf, 4,
+						  CONTROL_TIMEOUT_JIFFIES);
+
+	if (ret < 0) {
+		*val = 0xffffffff;
+		BT_ERR("%s error(%d), reg=%x, value=%x\n", __func__, ret, reg, *val);
+		return ret;
+	}
+
+	memmove(val, data->io_buf, 4);
+
+	*val = le32_to_cpu(*val);
+
+	if (ret > 0)
+		ret = 0;
+
+	return ret;
+}
+
+static int btmtk_usb_io_write32(struct btmtk_usb_data *data, u32 reg, u32 val)
+{
+	u16 value, index;
+	u8 request = data->w_request;
+	struct usb_device *udev = data->udev;
+	int ret;
+
+	index = (u16)reg;
+	value = val & 0x0000ffff;
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, DEVICE_VENDOR_REQUEST_OUT,
+						  value, index, NULL, 0,
+						  CONTROL_TIMEOUT_JIFFIES);
+
+	if (ret < 0) {
+		BT_ERR("%s error(%d), reg=%x, value=%x\n", __func__, ret, reg, val);
+		return ret;
+	}
+
+	index = (u16)(reg + 2);
+	value = (val & 0xffff0000) >> 16;
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+				request, DEVICE_VENDOR_REQUEST_OUT,
+				value, index, NULL, 0, CONTROL_TIMEOUT_JIFFIES);
+
+	if (ret < 0) {
+		BT_ERR("%s error(%d), reg=%x, value=%x\n", __func__, ret, reg, val);
+		return ret;
+	}
+
+	if (ret > 0)
+		ret = 0;
+
+	return ret;
+}
+
+static int btmtk_usb_switch_iobase(struct btmtk_usb_data *data, int base)
+{
+	int ret = 0;
+
+	switch (base) {
+	case SYSCTL:
+		data->w_request = 0x42;
+		data->r_request = 0x47;
+		break;
+	case WLAN:
+		data->w_request = 0x02;
+		data->r_request = 0x07;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static void btmtk_usb_cap_init(struct btmtk_usb_data *data)
+{
+	const struct firmware	*firmware;
+	struct usb_device   *udev = data->udev;
+	int ret;
+
+	btmtk_usb_io_read32(data, 0x00, &data->chip_id);
+
+	BT_DBG("chip id = %x\n", data->chip_id);
+
+	if (is_mt7630(data) || is_mt7650(data)) {
+		data->need_load_fw = 1;
+		data->need_load_rom_patch = 0;
+		ret = reject_firmware(&firmware, MT7650_FIRMWARE, &udev->dev);
+		if (ret < 0) {
+			if (ret == -ENOENT) {
+				BT_ERR("Firmware file \"%s\" not found \n", MT7650_FIRMWARE);
+			} else {
+				BT_ERR("Firmware file \"%s\" request failed (err=%d) \n",
+					MT7650_FIRMWARE, ret);
+			}
+		} else {
+			BT_DBG("Firmware file \"%s\" Found \n", MT7650_FIRMWARE);
+			/* load firmware here */
+			data->firmware = firmware;
+			btmtk_usb_load_fw(data);
+		}
+		release_firmware(firmware);
+	} else if (is_mt7632(data) || is_mt7662(data)) {
+		data->need_load_fw = 0;
+		data->need_load_rom_patch = 1;
+		data->rom_patch_offset = 0x90000;
+		ret = reject_firmware(&firmware, MT7662_FIRMWARE, &udev->dev);
+		if (ret < 0) {
+			if (ret == -ENOENT) {
+				BT_ERR("Firmware file \"%s\" not found\n", MT7662_FIRMWARE);
+			} else {
+				BT_ERR("Firmware file \"%s\" request failed (err=%d)\n",
+					MT7662_FIRMWARE, ret);
+			}
+		} else {
+		    BT_DBG("Firmware file \"%s\" Found\n", MT7662_FIRMWARE);
+		    /* load rom patch here */
+		    data->firmware = firmware;
+		    data->rom_patch_len = firmware->size;
+		    btmtk_usb_load_rom_patch(data);
+		}
+		release_firmware(firmware);
+	} else {
+		BT_ERR("unknow chip(%x)\n", data->chip_id);
+	}
+}
+
+static u16 checksume16(u8 *pData, int len)
+{
+	int sum = 0;
+
+	while (len > 1) {
+		sum += *((u16 *)pData);
+
+		pData = pData + 2;
+
+		if (sum & 0x80000000)
+			sum = (sum & 0xFFFF) + (sum >> 16);
+
+		len -= 2;
+	}
+
+	if (len)
+		sum += *((u8 *)pData);
+
+	while (sum >> 16) {
+		sum = (sum & 0xFFFF) + (sum >> 16);
+	}
+
+	return ~sum;
+}
+
+static int btmtk_usb_chk_crc(struct btmtk_usb_data *data, u32 checksum_len)
+{
+	int ret = 0;
+	struct usb_device *udev = data->udev;
+
+	BT_DBG("%s\n", __func__);
+
+	memmove(data->io_buf, &data->rom_patch_offset, 4);
+	memmove(&data->io_buf[4], &checksum_len, 4);
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x1, DEVICE_VENDOR_REQUEST_IN,
+						  0x20, 0x00, data->io_buf, 8,
+						  CONTROL_TIMEOUT_JIFFIES);
+
+	if (ret < 0) {
+		BT_ERR("%s error(%d)\n", __func__, ret);
+	}
+
+	return ret;
+}
+
+static u16 btmtk_usb_get_crc(struct btmtk_usb_data *data)
+{
+	int ret = 0;
+	struct usb_device *udev = data->udev;
+	u16 crc, count = 0;
+
+	BT_DBG("%s\n", __func__);
+
+	while (1) {
+		ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+					0x01, DEVICE_VENDOR_REQUEST_IN,
+					0x21, 0x00, data->io_buf, 2,
+					CONTROL_TIMEOUT_JIFFIES);
+
+		if (ret < 0) {
+			crc = 0xFFFF;
+			BT_ERR("%s error(%d)\n", __func__, ret);
+		}
+
+		memmove(&crc, data->io_buf, 2);
+
+		crc = le16_to_cpu(crc);
+
+		if (crc != 0xFFFF)
+			break;
+
+		mdelay(100);
+
+		if (count++ > 100) {
+			BT_ERR("Query CRC over %d times\n", count);
+			break;
+		}
+	}
+
+	return crc;
+}
+
+static int btmtk_usb_reset_wmt(struct btmtk_usb_data *data)
+{
+	int ret = 0;
+
+	/* reset command */
+	u8 cmd[8] = {0x6F, 0xFC, 0x05, 0x01, 0x07, 0x01, 0x00, 0x04};
+
+	memmove(data->io_buf, cmd, 8);
+
+	BT_DBG("%s\n", __func__);
+
+	ret = usb_control_msg(data->udev, usb_sndctrlpipe(data->udev, 0), 0x01,
+				DEVICE_CLASS_REQUEST_OUT, 0x12, 0x00, data->io_buf,
+				8, CONTROL_TIMEOUT_JIFFIES);
+
+	if (ret)
+		BT_ERR("%s:(%d)\n", __func__, ret);
+
+	return ret;
+}
+
+static void load_rom_patch_complete(struct urb *urb)
+{
+
+	struct completion *sent_to_mcu_done = (struct completion *)urb->context;
+
+	complete(sent_to_mcu_done);
+}
+
+static int btmtk_usb_load_rom_patch(struct btmtk_usb_data *data)
+{
+	u32 loop = 0;
+	u32 value;
+	s32 sent_len;
+	int ret = 0, total_checksum = 0;
+	struct urb *urb;
+	u32 patch_len = 0;
+	u32 cur_len = 0;
+	dma_addr_t data_dma;
+	struct completion sent_to_mcu_done;
+	int first_block = 1;
+	unsigned char phase;
+	void *buf;
+	char *pos;
+	unsigned int pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
+
+	if (!data->firmware) {
+		BT_ERR("%s:please assign a rom patch\n", __func__);
+		return -1;
+	}
+
+load_patch_protect:
+	btmtk_usb_switch_iobase(data, WLAN);
+	btmtk_usb_io_read32(data, SEMAPHORE_03, &value);
+	loop++;
+
+	if (((value & 0x01) == 0x00) && (loop < 600)) {
+		mdelay(1);
+		goto load_patch_protect;
+	}
+
+	btmtk_usb_io_write32(data, 0x1004, 0x2c);
+
+	btmtk_usb_switch_iobase(data, SYSCTL);
+
+	btmtk_usb_io_write32(data, 0x1c, 0x30);
+
+	/* Enable USB_DMA_CFG */
+	btmtk_usb_io_write32(data, 0x9018, 0x00c00020);
+
+	btmtk_usb_switch_iobase(data, WLAN);
+
+	/* check ROM patch if upgrade */
+	btmtk_usb_io_read32(data, COM_REG0, &value);
+
+	if ((value & 0x02) == 0x02)
+		goto error0;
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+	if (!urb) {
+		ret = -ENOMEM;
+		goto error0;
+	}
+
+	buf = usb_alloc_coherent(data->udev, UPLOAD_PATCH_UNIT, GFP_ATOMIC, &data_dma);
+
+	if (!buf) {
+		ret = -ENOMEM;
+		goto error1;
+	}
+
+	pos = buf;
+	BT_DBG("loading rom patch");
+
+	init_completion(&sent_to_mcu_done);
+
+	cur_len = 0x00;
+	patch_len = data->rom_patch_len - PATCH_INFO_SIZE;
+
+	/* loading rom patch */
+	while (1) {
+		s32 sent_len_max = UPLOAD_PATCH_UNIT - PATCH_HEADER_SIZE;
+		sent_len = (patch_len - cur_len) >= sent_len_max ? sent_len_max : (patch_len - cur_len);
+
+		BT_DBG("patch_len = %d\n", patch_len);
+		BT_DBG("cur_len = %d\n", cur_len);
+		BT_DBG("sent_len = %d\n", sent_len);
+
+		if (sent_len > 0) {
+			if (first_block == 1) {
+				if (sent_len < sent_len_max)
+					phase = PATCH_PHASE3;
+				else
+					phase = PATCH_PHASE1;
+				first_block = 0;
+			} else if (sent_len == sent_len_max) {
+				phase = PATCH_PHASE2;
+			} else {
+				phase = PATCH_PHASE3;
+			}
+
+			/* prepare HCI header */
+			pos[0] = 0x6F;
+			pos[1] = 0xFC;
+			pos[2] = (sent_len + 5) & 0xFF;
+			pos[3] = ((sent_len + 5) >> 8) & 0xFF;
+
+			/* prepare WMT header */
+			pos[4] = 0x01;
+			pos[5] = 0x01;
+			pos[6] = (sent_len + 1) & 0xFF;
+			pos[7] = ((sent_len + 1) >> 8) & 0xFF;
+
+			pos[8] = phase;
+
+			memcpy(&pos[9], data->firmware->data + PATCH_INFO_SIZE + cur_len, sent_len);
+
+			BT_DBG("sent_len + PATCH_HEADER_SIZE = %d, phase = %d\n",
+					sent_len + PATCH_HEADER_SIZE, phase);
+
+			usb_fill_bulk_urb(urb,
+					data->udev,
+					pipe,
+					buf,
+					sent_len + PATCH_HEADER_SIZE,
+					load_rom_patch_complete,
+					&sent_to_mcu_done);
+
+			urb->transfer_dma = data_dma;
+			urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+			ret = usb_submit_urb(urb, GFP_ATOMIC);
+
+			if (ret)
+				goto error2;
+
+			if (!wait_for_completion_timeout(&sent_to_mcu_done, msecs_to_jiffies(1000))) {
+				usb_kill_urb(urb);
+				BT_ERR("upload rom_patch timeout\n");
+				goto error2;
+			}
+
+			BT_DBG(".");
+
+			mdelay(200);
+
+			cur_len += sent_len;
+
+		} else {
+			break;
+		}
+	}
+
+	total_checksum = checksume16((u8 *)data->firmware->data + PATCH_INFO_SIZE, patch_len);
+
+	BT_DBG("Send checksum req..\n");
+
+	btmtk_usb_chk_crc(data, patch_len);
+
+	mdelay(20);
+
+	if (total_checksum != btmtk_usb_get_crc(data)) {
+		BT_ERR("checksum fail!, local(0x%x) <> fw(0x%x)\n",
+				total_checksum, btmtk_usb_get_crc(data));
+		ret = -1;
+		goto error2;
+	}
+
+	mdelay(20);
+
+	ret = btmtk_usb_reset_wmt(data);
+
+	mdelay(20);
+
+error2:
+	usb_free_coherent(data->udev, UPLOAD_PATCH_UNIT, buf, data_dma);
+error1:
+	usb_free_urb(urb);
+error0:
+	btmtk_usb_io_write32(data, SEMAPHORE_03, 0x1);
+	return ret;
+}
+
+
+static int load_fw_iv(struct btmtk_usb_data *data)
+{
+	int ret;
+	struct usb_device *udev = data->udev;
+	char *buf = kmalloc(64, GFP_ATOMIC);
+
+	memmove(buf, data->firmware->data + 32, 64);
+
+	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
+						  DEVICE_VENDOR_REQUEST_OUT, 0x12, 0x0, buf, 64,
+						  CONTROL_TIMEOUT_JIFFIES);
+
+	if (ret < 0) {
+		BT_ERR("%s error(%d) step4\n", __func__, ret);
+		kfree(buf);
+		return ret;
+	}
+
+	if (ret > 0)
+		ret = 0;
+
+	kfree(buf);
+
+	return ret;
+}
+
+static void load_fw_complete(struct urb *urb)
+{
+
+	struct completion *sent_to_mcu_done = (struct completion *)urb->context;
+
+	complete(sent_to_mcu_done);
+}
+
+static int btmtk_usb_load_fw(struct btmtk_usb_data *data)
+{
+	struct usb_device *udev = data->udev;
+	struct urb *urb;
+	void *buf;
+	u32 cur_len = 0;
+	u32 packet_header = 0;
+	u32 value;
+	u32 ilm_len = 0, dlm_len = 0;
+	u16 fw_ver, build_ver;
+	u32 loop = 0;
+	dma_addr_t data_dma;
+	int ret = 0, sent_len;
+	struct completion sent_to_mcu_done;
+	unsigned int pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
+
+	if (!data->firmware) {
+		BT_ERR("%s:please assign a fw\n", __func__);
+		return -1;
+	}
+
+	BT_DBG("bulk_tx_ep = %x\n", data->bulk_tx_ep->bEndpointAddress);
+
+loadfw_protect:
+	btmtk_usb_switch_iobase(data, WLAN);
+	btmtk_usb_io_read32(data, SEMAPHORE_00, &value);
+	loop++;
+
+	if (((value & 0x1) == 0) && (loop < 10000))
+		goto loadfw_protect;
+
+	/* check MCU if ready */
+	btmtk_usb_io_read32(data, COM_REG0, &value);
+
+	if ((value & 0x01) == 0x01)
+		goto error0;
+
+	/* Enable MPDMA TX and EP2 load FW mode */
+	btmtk_usb_io_write32(data, 0x238, 0x1c000000);
+
+	btmtk_usb_reset(udev);
+	mdelay(100);
+
+	ilm_len = (*(data->firmware->data + 3) << 24)
+			| (*(data->firmware->data + 2) << 16)
+			| (*(data->firmware->data + 1) << 8)
+			| (*data->firmware->data);
+
+	dlm_len = (*(data->firmware->data + 7) << 24)
+			| (*(data->firmware->data + 6) << 16)
+			| (*(data->firmware->data + 5) << 8)
+			| (*(data->firmware->data + 4));
+
+	fw_ver = (*(data->firmware->data + 11) << 8) | (*(data->firmware->data + 10));
+
+	build_ver = (*(data->firmware->data + 9) << 8) | (*(data->firmware->data + 8));
+
+	BT_DBG("fw version:%d.%d.%02d ",
+			(fw_ver & 0xf000) >> 8,
+			(fw_ver & 0x0f00) >> 8,
+			(fw_ver & 0x00ff));
+
+	BT_DBG("build:%x\n", build_ver);
+
+	BT_DBG("build Time =");
+
+	for (loop = 0; loop < 16; loop++)
+		BT_DBG("%c", *(data->firmware->data + 16 + loop));
+
+	BT_DBG("\n");
+
+	BT_DBG("ILM length = %d(bytes)\n", ilm_len);
+	BT_DBG("DLM length = %d(bytes)\n", dlm_len);
+
+	btmtk_usb_switch_iobase(data, SYSCTL);
+
+	/* U2M_PDMA rx_ring_base_ptr */
+	btmtk_usb_io_write32(data, 0x790, 0x400230);
+
+	/* U2M_PDMA rx_ring_max_cnt */
+	btmtk_usb_io_write32(data, 0x794, 0x1);
+
+	/* U2M_PDMA cpu_idx */
+	btmtk_usb_io_write32(data, 0x798, 0x1);
+
+	/* U2M_PDMA enable */
+	btmtk_usb_io_write32(data, 0x704, 0x44);
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+	if (!urb) {
+		ret = -ENOMEM;
+		goto error1;
+	}
+
+	buf = usb_alloc_coherent(udev, 14592, GFP_ATOMIC, &data_dma);
+
+	if (!buf) {
+		ret = -ENOMEM;
+		goto error2;
+	}
+
+	BT_DBG("loading fw");
+
+	init_completion(&sent_to_mcu_done);
+
+	btmtk_usb_switch_iobase(data, SYSCTL);
+
+	cur_len = 0x40;
+
+	/* Loading ILM */
+	while (1) {
+		sent_len = (ilm_len - cur_len) >= 14336 ? 14336 : (ilm_len - cur_len);
+
+		if (sent_len > 0) {
+			packet_header &= ~(0xffffffff);
+			packet_header |= (sent_len << 16);
+			packet_header = cpu_to_le32(packet_header);
+
+			memmove(buf, &packet_header, 4);
+			memmove(buf + 4, data->firmware->data + 32 + cur_len, sent_len);
+
+			/* U2M_PDMA descriptor */
+			btmtk_usb_io_write32(data, 0x230, cur_len);
+
+			while ((sent_len % 4) != 0) {
+				sent_len++;
+			}
+
+			/* U2M_PDMA length */
+			btmtk_usb_io_write32(data, 0x234, sent_len << 16);
+
+			usb_fill_bulk_urb(urb,
+					udev,
+					pipe,
+					buf,
+					sent_len + 4,
+					load_fw_complete,
+					&sent_to_mcu_done);
+
+			urb->transfer_dma = data_dma;
+			urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+			ret = usb_submit_urb(urb, GFP_ATOMIC);
+
+			if (ret)
+				goto error3;
+
+			if (!wait_for_completion_timeout(&sent_to_mcu_done, msecs_to_jiffies(1000))) {
+				usb_kill_urb(urb);
+				BT_ERR("upload ilm fw timeout\n");
+				goto error3;
+			}
+
+			BT_DBG(".");
+
+			mdelay(200);
+
+			cur_len += sent_len;
+		} else {
+			break;
+		}
+	}
+
+	init_completion(&sent_to_mcu_done);
+	cur_len = 0x00;
+
+	/* Loading DLM */
+	while (1) {
+		sent_len = (dlm_len - cur_len) >= 14336 ? 14336 : (dlm_len - cur_len);
+
+		if (sent_len > 0) {
+			packet_header &= ~(0xffffffff);
+			packet_header |= (sent_len << 16);
+			packet_header = cpu_to_le32(packet_header);
+
+			memmove(buf, &packet_header, 4);
+			memmove(buf + 4, data->firmware->data + 32 + ilm_len + cur_len, sent_len);
+
+			/* U2M_PDMA descriptor */
+			btmtk_usb_io_write32(data, 0x230, 0x80000 + cur_len);
+
+			while ((sent_len % 4) != 0) {
+				BT_DBG("sent_len is not divided by 4\n");
+				sent_len++;
+			}
+
+			/* U2M_PDMA length */
+			btmtk_usb_io_write32(data, 0x234, sent_len << 16);
+
+			usb_fill_bulk_urb(urb,
+					udev,
+					pipe,
+					buf,
+					sent_len + 4,
+					load_fw_complete,
+					&sent_to_mcu_done);
+
+			urb->transfer_dma = data_dma;
+			urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+			ret = usb_submit_urb(urb, GFP_ATOMIC);
+
+			if (ret)
+				goto error3;
+
+			if (!wait_for_completion_timeout(&sent_to_mcu_done, msecs_to_jiffies(1000))) {
+				usb_kill_urb(urb);
+				BT_ERR("upload dlm fw timeout\n");
+				goto error3;
+			}
+
+			BT_DBG(".");
+
+			mdelay(500);
+
+			cur_len += sent_len;
+
+		} else {
+			break;
+		}
+	}
+
+	/* upload 64bytes interrupt vector */
+	ret = load_fw_iv(data);
+	mdelay(100);
+
+	btmtk_usb_switch_iobase(data, WLAN);
+
+	/* check MCU if ready */
+	loop = 0;
+
+	do {
+		btmtk_usb_io_read32(data, COM_REG0, &value);
+
+		if (value == 0x01)
+			break;
+
+		mdelay(10);
+		loop++;
+	} while (loop <= 100);
+
+	if (loop > 1000) {
+		BT_ERR("wait for 100 times\n");
+		ret = -ENODEV;
+	}
+
+error3:
+	usb_free_coherent(udev, 14592, buf, data_dma);
+error2:
+	usb_free_urb(urb);
+error1:
+	/* Disbale load fw mode */
+	btmtk_usb_io_read32(data, 0x238, &value);
+	value = value & ~(0x10000000);
+	btmtk_usb_io_write32(data,  0x238, value);
+error0:
+	btmtk_usb_io_write32(data, SEMAPHORE_00, 0x1);
+	return ret;
+}
+
+static int inc_tx(struct btmtk_usb_data *data)
+{
+	unsigned long flags;
+	int rv;
+
+	spin_lock_irqsave(&data->txlock, flags);
+	rv = test_bit(BTUSB_SUSPENDING, &data->flags);
+	if (!rv)
+		data->tx_in_flight++;
+	spin_unlock_irqrestore(&data->txlock, flags);
+
+	return rv;
+}
+
+static void btmtk_usb_intr_complete(struct urb *urb)
+{
+	struct hci_dev *hdev = urb->context;
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	int err;
+
+	BT_DBG("%s: %s urb %p status %d count %d\n", __func__, hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return;
+
+	if (urb->status == 0) {
+		hdev->stat.byte_rx += urb->actual_length;
+
+		hex_dump("hci event", urb->transfer_buffer, urb->actual_length);
+
+		if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
+						urb->transfer_buffer,
+						urb->actual_length) < 0) {
+			BT_ERR("%s corrupted event packet", hdev->name);
+			hdev->stat.err_rx++;
+		}
+	}
+
+	if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
+		return;
+
+	usb_mark_last_busy(data->udev);
+	usb_anchor_urb(urb, &data->intr_anchor);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+
+	if (err < 0) {
+		/* -EPERM: urb is being killed;
+		 * -ENODEV: device got disconnected */
+		if (err != -EPERM && err != -ENODEV)
+			BT_ERR("%s urb %p failed to resubmit (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+}
+
+static int btmtk_usb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
+{
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	struct urb *urb;
+	unsigned char *buf;
+	unsigned int pipe;
+	int err, size;
+
+	BT_DBG("%s\n", __func__);
+
+	if (!data->intr_ep)
+		return -ENODEV;
+
+	urb = usb_alloc_urb(0, mem_flags);
+	if (!urb)
+		return -ENOMEM;
+
+	size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
+
+	buf = kmalloc(size, mem_flags);
+	if (!buf) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress);
+
+	usb_fill_int_urb(urb, data->udev, pipe, buf, size,
+						btmtk_usb_intr_complete, hdev,
+						data->intr_ep->bInterval);
+
+	urb->transfer_flags |= URB_FREE_BUFFER;
+
+	usb_anchor_urb(urb, &data->intr_anchor);
+
+	err = usb_submit_urb(urb, mem_flags);
+	if (err < 0) {
+		if (err != -EPERM && err != -ENODEV)
+			BT_ERR("%s urb %p submission failed (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+
+	usb_free_urb(urb);
+
+	return err;
+
+}
+
+static void btmtk_usb_bulk_in_complete(struct urb *urb)
+{
+	struct hci_dev *hdev = urb->context;
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	int err;
+
+	BT_DBG("%s:%s urb %p status %d count %d", __func__, hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
+		return;
+	}
+
+	if (urb->status == 0) {
+		hdev->stat.byte_rx += urb->actual_length;
+
+		if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
+						urb->transfer_buffer,
+						urb->actual_length) < 0) {
+			BT_ERR("%s corrupted ACL packet", hdev->name);
+			hdev->stat.err_rx++;
+		}
+	}
+
+	if (!test_bit(BTUSB_BULK_RUNNING, &data->flags))
+		return;
+
+	usb_anchor_urb(urb, &data->bulk_anchor);
+	usb_mark_last_busy(data->udev);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		/* -EPERM: urb is being killed;
+		 * -ENODEV: device got disconnected */
+		if (err != -EPERM && err != -ENODEV)
+			BT_ERR("%s urb %p failed to resubmit (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+}
+
+static int btmtk_usb_submit_bulk_in_urb(struct hci_dev *hdev, gfp_t mem_flags)
+{
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	struct urb *urb;
+	unsigned char *buf;
+	unsigned int pipe;
+	int err, size = HCI_MAX_FRAME_SIZE;
+
+	BT_DBG("%s:%s\n", __func__, hdev->name);
+
+	if (!data->bulk_rx_ep)
+		return -ENODEV;
+
+	urb = usb_alloc_urb(0, mem_flags);
+	if (!urb)
+		return -ENOMEM;
+
+	buf = kmalloc(size, mem_flags);
+	if (!buf) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
+
+	usb_fill_bulk_urb(urb, data->udev, pipe,
+					buf, size, btmtk_usb_bulk_in_complete, hdev);
+
+	urb->transfer_flags |= URB_FREE_BUFFER;
+
+	usb_mark_last_busy(data->udev);
+	usb_anchor_urb(urb, &data->bulk_anchor);
+
+	err = usb_submit_urb(urb, mem_flags);
+	if (err < 0) {
+		if (err != -EPERM && err != -ENODEV)
+			BT_ERR("%s urb %p submission failed (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+
+	usb_free_urb(urb);
+
+	return err;
+}
+
+static void btmtk_usb_isoc_in_complete(struct urb *urb)
+
+{
+	struct hci_dev *hdev = urb->context;
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	int i, err;
+
+	BT_DBG("%s: %s urb %p status %d count %d", __func__, hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return;
+
+	if (urb->status == 0) {
+		for (i = 0; i < urb->number_of_packets; i++) {
+			unsigned int offset = urb->iso_frame_desc[i].offset;
+			unsigned int length = urb->iso_frame_desc[i].actual_length;
+
+			if (urb->iso_frame_desc[i].status)
+				continue;
+
+			hdev->stat.byte_rx += length;
+
+			if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
+						urb->transfer_buffer + offset,
+								length) < 0) {
+				BT_ERR("%s corrupted SCO packet", hdev->name);
+				hdev->stat.err_rx++;
+			}
+		}
+	}
+
+	if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
+		return;
+
+	usb_anchor_urb(urb, &data->isoc_anchor);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		/* -EPERM: urb is being killed;
+		 * -ENODEV: device got disconnected */
+		if (err != -EPERM && err != -ENODEV)
+			BT_ERR("%s urb %p failed to resubmit (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+}
+
+static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
+{
+	int i, offset = 0;
+
+	BT_DBG("len %d mtu %d", len, mtu);
+
+	for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu;
+					i++, offset += mtu, len -= mtu) {
+		urb->iso_frame_desc[i].offset = offset;
+		urb->iso_frame_desc[i].length = mtu;
+	}
+
+	if (len && i < BTUSB_MAX_ISOC_FRAMES) {
+		urb->iso_frame_desc[i].offset = offset;
+		urb->iso_frame_desc[i].length = len;
+		i++;
+	}
+
+	urb->number_of_packets = i;
+}
+
+static int btmtk_usb_submit_isoc_in_urb(struct hci_dev *hdev, gfp_t mem_flags)
+{
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	struct urb *urb;
+	unsigned char *buf;
+	unsigned int pipe;
+	int err, size;
+
+	BT_DBG("%s\n", __func__);
+
+	if (!data->isoc_rx_ep)
+		return -ENODEV;
+
+	urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags);
+	if (!urb)
+		return -ENOMEM;
+
+	size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
+						BTUSB_MAX_ISOC_FRAMES;
+
+	buf = kmalloc(size, mem_flags);
+	if (!buf) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
+
+	usb_fill_int_urb(urb, data->udev, pipe, buf, size, btmtk_usb_isoc_in_complete,
+				hdev, data->isoc_rx_ep->bInterval);
+
+	urb->transfer_flags  = URB_FREE_BUFFER | URB_ISO_ASAP;
+
+	__fill_isoc_descriptor(urb, size,
+			le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
+
+	usb_anchor_urb(urb, &data->isoc_anchor);
+
+	err = usb_submit_urb(urb, mem_flags);
+	if (err < 0) {
+		if (err != -EPERM && err != -ENODEV)
+			BT_ERR("%s urb %p submission failed (%d)",
+						hdev->name, urb, -err);
+		usb_unanchor_urb(urb);
+	}
+
+	usb_free_urb(urb);
+
+	return err;
+}
+
+static int btmtk_usb_open(struct hci_dev *hdev)
+{
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	int err;
+
+	BT_DBG("%s\n", __func__);
+
+	err = usb_autopm_get_interface(data->intf);
+	if (err < 0)
+		return err;
+
+	data->intf->needs_remote_wakeup = 1;
+
+	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
+		goto done;
+
+	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
+		goto done;
+
+	err = btmtk_usb_submit_intr_urb(hdev, GFP_KERNEL);
+	if (err < 0)
+		goto failed;
+
+	err = btmtk_usb_submit_bulk_in_urb(hdev, GFP_KERNEL);
+	if (err < 0) {
+		usb_kill_anchored_urbs(&data->intr_anchor);
+		goto failed;
+	}
+
+	set_bit(BTUSB_BULK_RUNNING, &data->flags);
+	btmtk_usb_submit_bulk_in_urb(hdev, GFP_KERNEL);
+
+done:
+	usb_autopm_put_interface(data->intf);
+	return 0;
+
+failed:
+	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+	clear_bit(HCI_RUNNING, &hdev->flags);
+	usb_autopm_put_interface(data->intf);
+	return err;
+}
+
+static void btmtk_usb_stop_traffic(struct btmtk_usb_data *data)
+{
+	BT_DBG("%s\n", __func__);
+
+	usb_kill_anchored_urbs(&data->intr_anchor);
+	usb_kill_anchored_urbs(&data->bulk_anchor);
+	usb_kill_anchored_urbs(&data->isoc_anchor);
+}
+
+static int btmtk_usb_close(struct hci_dev *hdev)
+{
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	int err;
+
+	BT_DBG("%s\n", __func__);
+
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	cancel_work_sync(&data->work);
+	cancel_work_sync(&data->waker);
+
+	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+
+	btmtk_usb_stop_traffic(data);
+
+	err = usb_autopm_get_interface(data->intf);
+	if (err < 0)
+		goto failed;
+
+	data->intf->needs_remote_wakeup = 0;
+	usb_autopm_put_interface(data->intf);
+
+failed:
+	usb_scuttle_anchored_urbs(&data->deferred);
+	return 0;
+}
+
+static int btmtk_usb_flush(struct hci_dev *hdev)
+{
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+
+	BT_DBG("%s\n", __func__);
+
+	usb_kill_anchored_urbs(&data->tx_anchor);
+
+	return 0;
+}
+
+static void btmtk_usb_tx_complete(struct urb *urb)
+{
+	struct sk_buff *skb = urb->context;
+	struct hci_dev *hdev = (struct hci_dev *)skb->dev;
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+
+	BT_DBG("%s: %s urb %p status %d count %d\n", __func__, hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		goto done;
+
+	if (!urb->status)
+		hdev->stat.byte_tx += urb->transfer_buffer_length;
+	else
+		hdev->stat.err_tx++;
+
+done:
+	spin_lock(&data->txlock);
+	data->tx_in_flight--;
+	spin_unlock(&data->txlock);
+
+	kfree(urb->setup_packet);
+
+	kfree_skb(skb);
+}
+
+static void btmtk_usb_isoc_tx_complete(struct urb *urb)
+{
+	struct sk_buff *skb = urb->context;
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+
+	BT_DBG("%s: %s urb %p status %d count %d", __func__, hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		goto done;
+
+	if (!urb->status)
+		hdev->stat.byte_tx += urb->transfer_buffer_length;
+	else
+		hdev->stat.err_tx++;
+
+done:
+	kfree(urb->setup_packet);
+
+	kfree_skb(skb);
+}
+
+static int btmtk_usb_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev *hdev = (struct hci_dev *)skb->dev;
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	struct usb_ctrlrequest *dr;
+	struct urb *urb;
+	unsigned int pipe;
+	int err;
+
+	BT_DBG("%s\n", __func__);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		return -EBUSY;
+
+	switch (bt_cb(skb)->pkt_type) {
+	case HCI_COMMAND_PKT:
+		urb = usb_alloc_urb(0, GFP_ATOMIC);
+		if (!urb)
+			return -ENOMEM;
+
+		dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
+		if (!dr) {
+			usb_free_urb(urb);
+			return -ENOMEM;
+		}
+
+		dr->bRequestType = data->cmdreq_type;
+		dr->bRequest     = 0;
+		dr->wIndex       = 0;
+		dr->wValue       = 0;
+		dr->wLength      = __cpu_to_le16(skb->len);
+
+		pipe = usb_sndctrlpipe(data->udev, 0x00);
+
+		if (test_bit(HCI_RUNNING, &hdev->flags)) {
+			u16 op_code;
+			memcpy(&op_code, skb->data, 2);
+			BT_DBG("ogf = %x\n", (op_code & 0xfc00) >> 10);
+			BT_DBG("ocf = %x\n", op_code & 0x03ff);
+			hex_dump("hci command", skb->data, skb->len);
+
+		}
+
+		usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
+				skb->data, skb->len, btmtk_usb_tx_complete, skb);
+
+		hdev->stat.cmd_tx++;
+		break;
+
+	case HCI_ACLDATA_PKT:
+		if (!data->bulk_tx_ep)
+			return -ENODEV;
+
+		urb = usb_alloc_urb(0, GFP_ATOMIC);
+		if (!urb)
+			return -ENOMEM;
+
+		pipe = usb_sndbulkpipe(data->udev,
+					data->bulk_tx_ep->bEndpointAddress);
+
+		usb_fill_bulk_urb(urb, data->udev, pipe,
+				skb->data, skb->len, btmtk_usb_tx_complete, skb);
+
+		hdev->stat.acl_tx++;
+		BT_DBG("HCI_ACLDATA_PKT:\n");
+		break;
+
+	case HCI_SCODATA_PKT:
+		if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
+			return -ENODEV;
+
+		urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
+		if (!urb)
+			return -ENOMEM;
+
+		pipe = usb_sndisocpipe(data->udev,
+					data->isoc_tx_ep->bEndpointAddress);
+
+		usb_fill_int_urb(urb, data->udev, pipe,
+				skb->data, skb->len, btmtk_usb_isoc_tx_complete,
+				skb, data->isoc_tx_ep->bInterval);
+
+		urb->transfer_flags  = URB_ISO_ASAP;
+
+		__fill_isoc_descriptor(urb, skb->len,
+				le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
+
+		hdev->stat.sco_tx++;
+		BT_DBG("HCI_SCODATA_PKT:\n");
+		goto skip_waking;
+
+	default:
+		return -EILSEQ;
+	}
+
+	err = inc_tx(data);
+
+	if (err) {
+		usb_anchor_urb(urb, &data->deferred);
+		schedule_work(&data->waker);
+		err = 0;
+		goto done;
+	}
+
+skip_waking:
+	usb_anchor_urb(urb, &data->tx_anchor);
+
+	err = usb_submit_urb(urb, GFP_ATOMIC);
+	if (err < 0) {
+		if (err != -EPERM && err != -ENODEV)
+			BT_ERR("%s urb %p submission failed (%d)",
+						hdev->name, urb, -err);
+		kfree(urb->setup_packet);
+		usb_unanchor_urb(urb);
+	} else {
+		usb_mark_last_busy(data->udev);
+	}
+
+done:
+	usb_free_urb(urb);
+	return err;
+}
+
+static void btmtk_usb_notify(struct hci_dev *hdev, unsigned int evt)
+{
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+
+	BT_DBG("%s evt %d", hdev->name, evt);
+
+	if (hdev->conn_hash.sco_num != data->sco_num) {
+		data->sco_num = hdev->conn_hash.sco_num;
+		schedule_work(&data->work);
+	}
+}
+
+static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
+{
+	struct btmtk_usb_data *data = hci_get_drvdata(hdev);
+	struct usb_interface *intf = data->isoc;
+	struct usb_endpoint_descriptor *ep_desc;
+	int i, err;
+
+	if (!data->isoc)
+		return -ENODEV;
+
+	err = usb_set_interface(data->udev, 1, altsetting);
+	if (err < 0) {
+		BT_ERR("%s setting interface failed (%d)", hdev->name, -err);
+		return err;
+	}
+
+	data->isoc_altsetting = altsetting;
+
+	data->isoc_tx_ep = NULL;
+	data->isoc_rx_ep = NULL;
+
+	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+		ep_desc = &intf->cur_altsetting->endpoint[i].desc;
+
+		if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) {
+			data->isoc_tx_ep = ep_desc;
+			continue;
+		}
+
+		if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) {
+			data->isoc_rx_ep = ep_desc;
+			continue;
+		}
+	}
+
+	if (!data->isoc_tx_ep || !data->isoc_rx_ep) {
+		BT_ERR("%s invalid SCO descriptors", hdev->name);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void btmtk_usb_work(struct work_struct *work)
+{
+	struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, work);
+	struct hci_dev *hdev = data->hdev;
+	int new_alts;
+	int err;
+
+	BT_DBG("%s\n", __func__);
+
+	if (hdev->conn_hash.sco_num > 0) {
+		if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
+			err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
+			if (err < 0) {
+				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+				usb_kill_anchored_urbs(&data->isoc_anchor);
+				return;
+			}
+
+			set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
+		}
+
+		if (hdev->voice_setting & 0x0020) {
+			static const int alts[3] = { 2, 4, 5 };
+			new_alts = alts[hdev->conn_hash.sco_num - 1];
+		} else {
+			new_alts = hdev->conn_hash.sco_num;
+		}
+
+		if (data->isoc_altsetting != new_alts) {
+			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+			usb_kill_anchored_urbs(&data->isoc_anchor);
+
+			if (__set_isoc_interface(hdev, new_alts) < 0)
+				return;
+		}
+
+		if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
+			if (btmtk_usb_submit_isoc_in_urb(hdev, GFP_KERNEL) < 0)
+				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+			else
+				btmtk_usb_submit_isoc_in_urb(hdev, GFP_KERNEL);
+		}
+	} else {
+		clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+		usb_kill_anchored_urbs(&data->isoc_anchor);
+
+		__set_isoc_interface(hdev, 0);
+
+		if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
+			 usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
+	}
+}
+
+static void btmtk_usb_waker(struct work_struct *work)
+{
+	struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, waker);
+	int err;
+
+	err = usb_autopm_get_interface(data->intf);
+
+	if (err < 0)
+		return;
+
+	usb_autopm_put_interface(data->intf);
+}
+
+static int btmtk_usb_probe(struct usb_interface *intf,
+					const struct usb_device_id *id)
+{
+	struct btmtk_usb_data *data;
+	struct usb_endpoint_descriptor *ep_desc;
+	int i, err;
+	struct hci_dev *hdev;
+
+	/* interface numbers are hardcoded in the spec */
+	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+		return -ENODEV;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+
+	if (!data)
+		return -ENOMEM;
+
+	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+		ep_desc = &intf->cur_altsetting->endpoint[i].desc;
+
+		if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
+			data->intr_ep = ep_desc;
+			continue;
+		}
+
+		if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
+			data->bulk_tx_ep = ep_desc;
+			continue;
+		}
+
+		if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
+			data->bulk_rx_ep = ep_desc;
+			continue;
+		}
+	}
+
+	if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
+		kfree(data);
+		return -ENODEV;
+	}
+
+	data->cmdreq_type = USB_TYPE_CLASS;
+
+	data->udev = interface_to_usbdev(intf);
+	data->intf = intf;
+
+	spin_lock_init(&data->lock);
+	INIT_WORK(&data->work, btmtk_usb_work);
+	INIT_WORK(&data->waker, btmtk_usb_waker);
+	spin_lock_init(&data->txlock);
+
+	init_usb_anchor(&data->tx_anchor);
+	init_usb_anchor(&data->intr_anchor);
+	init_usb_anchor(&data->bulk_anchor);
+	init_usb_anchor(&data->isoc_anchor);
+	init_usb_anchor(&data->deferred);
+
+	hdev = hci_alloc_dev();
+	if (!hdev) {
+		kfree(data);
+		return -ENOMEM;
+	}
+
+	hdev->bus = HCI_USB;
+
+	hci_set_drvdata(hdev, data);
+
+	data->hdev = hdev;
+
+	SET_HCIDEV_DEV(hdev, &intf->dev);
+
+	hdev->open     = btmtk_usb_open;
+	hdev->close    = btmtk_usb_close;
+	hdev->flush    = btmtk_usb_flush;
+	hdev->send     = btmtk_usb_send_frame;
+	hdev->notify   = btmtk_usb_notify;
+
+	/* Interface numbers are hardcoded in the specification */
+	data->isoc = usb_ifnum_to_if(data->udev, 1);
+
+	if (data->isoc) {
+		err = usb_driver_claim_interface(&btmtk_usb_driver,
+							data->isoc, data);
+		if (err < 0) {
+			hci_free_dev(hdev);
+			kfree(data);
+			return err;
+		}
+	}
+
+	data->io_buf = kmalloc(256, GFP_KERNEL);
+	if (!data->io_buf) {
+		hci_free_dev(hdev);
+		kfree(data);
+		return -ENOMEM;
+	}
+
+	btmtk_usb_switch_iobase(data, WLAN);
+
+	btmtk_usb_cap_init(data);
+
+	err = hci_register_dev(hdev);
+	if (err < 0) {
+		hci_free_dev(hdev);
+		kfree(data);
+		return err;
+	}
+
+	usb_set_intfdata(intf, data);
+
+	return 0;
+}
+
+static void btmtk_usb_disconnect(struct usb_interface *intf)
+{
+	struct btmtk_usb_data *data = usb_get_intfdata(intf);
+	struct hci_dev *hdev;
+
+	BT_DBG("%s\n", __func__);
+
+	if (!data)
+		return;
+
+	hdev = data->hdev;
+	usb_set_intfdata(data->intf, NULL);
+
+	if (data->isoc)
+		usb_set_intfdata(data->isoc, NULL);
+
+	hci_unregister_dev(hdev);
+
+	if (intf == data->isoc)
+		usb_driver_release_interface(&btmtk_usb_driver, data->intf);
+	else if (data->isoc)
+		usb_driver_release_interface(&btmtk_usb_driver, data->isoc);
+
+	hci_free_dev(hdev);
+
+	kfree(data->io_buf);
+
+	kfree(data);
+}
+
+#ifdef CONFIG_PM
+static int btmtk_usb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct btmtk_usb_data *data = usb_get_intfdata(intf);
+
+	BT_DBG("%s\n", __func__);
+
+	if (data->suspend_count++)
+		return 0;
+
+	spin_lock_irq(&data->txlock);
+	if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) {
+		set_bit(BTUSB_SUSPENDING, &data->flags);
+		spin_unlock_irq(&data->txlock);
+	} else {
+		spin_unlock_irq(&data->txlock);
+		data->suspend_count--;
+		return -EBUSY;
+	}
+
+	cancel_work_sync(&data->work);
+
+	btmtk_usb_stop_traffic(data);
+	usb_kill_anchored_urbs(&data->tx_anchor);
+
+	return 0;
+}
+
+static void play_deferred(struct btmtk_usb_data *data)
+{
+	struct urb *urb;
+	int err;
+
+	while ((urb = usb_get_from_anchor(&data->deferred))) {
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err < 0)
+			break;
+
+		data->tx_in_flight++;
+	}
+
+	usb_scuttle_anchored_urbs(&data->deferred);
+}
+
+static int btmtk_usb_resume(struct usb_interface *intf)
+{
+	struct btmtk_usb_data *data = usb_get_intfdata(intf);
+	struct hci_dev *hdev = data->hdev;
+	int err = 0;
+
+	BT_DBG("%s\n", __func__);
+
+	if (--data->suspend_count)
+		return 0;
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		goto done;
+
+	if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
+		err = btmtk_usb_submit_intr_urb(hdev, GFP_NOIO);
+		if (err < 0) {
+			clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+			goto failed;
+		}
+	}
+
+	if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
+		err = btmtk_usb_submit_bulk_in_urb(hdev, GFP_NOIO);
+		if (err < 0) {
+			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+			goto failed;
+		}
+
+		btmtk_usb_submit_bulk_in_urb(hdev, GFP_NOIO);
+	}
+
+	if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
+		if (btmtk_usb_submit_isoc_in_urb(hdev, GFP_NOIO) < 0)
+			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+		else
+			btmtk_usb_submit_isoc_in_urb(hdev, GFP_NOIO);
+	}
+
+	spin_lock_irq(&data->txlock);
+	play_deferred(data);
+	clear_bit(BTUSB_SUSPENDING, &data->flags);
+	spin_unlock_irq(&data->txlock);
+	schedule_work(&data->work);
+
+	return 0;
+
+failed:
+	usb_scuttle_anchored_urbs(&data->deferred);
+done:
+	spin_lock_irq(&data->txlock);
+	clear_bit(BTUSB_SUSPENDING, &data->flags);
+	spin_unlock_irq(&data->txlock);
+
+	return err;
+}
+#endif
+
+static struct usb_device_id btmtk_usb_table[] = {
+	/* Mediatek MT7650 */
+	{ USB_DEVICE(0x0e8d, 0x7650) },
+	{ USB_DEVICE(0x0e8d, 0x7630) },
+	{ USB_DEVICE(0x0e8d, 0x763e) },
+	/* Mediatek MT662 */
+	{ USB_DEVICE(0x0e8d, 0x7662) },
+	{ USB_DEVICE(0x0e8d, 0x7632) },
+	{ }	/* Terminating entry */
+};
+
+static struct usb_driver btmtk_usb_driver = {
+	.name		= "btmtk_usb",
+	.probe		= btmtk_usb_probe,
+	.disconnect	= btmtk_usb_disconnect,
+#ifdef CONFIG_PM
+	.suspend	= btmtk_usb_suspend,
+	.resume		= btmtk_usb_resume,
+#endif
+	.id_table	= btmtk_usb_table,
+	.supports_autosuspend = 1,
+	.disable_hub_initiated_lpm = 1,
+};
+
+module_usb_driver(btmtk_usb_driver);
+
+MODULE_DESCRIPTION("Mediatek Bluetooth USB driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
+/*(DEBLOBBED)*/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/btmtk_usb/btmtk_usb.h linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/btmtk_usb.h
--- linux-libre-3.10-gnu/drivers/staging/btmtk_usb/btmtk_usb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/btmtk_usb.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,138 @@
+/*
+ *  MediaTek Bluetooth USB Driver
+ *
+ *  Copyright (C) 2013, MediaTek co.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  or on the worldwide web at
+ *  http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ */
+
+#ifndef __BTMTK_USB_H__
+#define __BTMTK_USB_H_
+
+/* Memory map for MTK BT */
+
+/* SYS Control */
+#define SYSCTL	0x400000
+
+/* WLAN */
+#define WLAN		0x410000
+
+/* MCUCTL */
+#define INT_LEVEL		0x0718
+#define COM_REG0		0x0730
+#define SEMAPHORE_00	0x07B0
+#define SEMAPHORE_01	0x07B4
+#define SEMAPHORE_02	0x07B8
+#define SEMAPHORE_03	0x07BC
+
+/* Chip definition */
+
+#define CONTROL_TIMEOUT_JIFFIES ((300 * HZ) / 100)
+#define DEVICE_VENDOR_REQUEST_OUT	0x40
+#define DEVICE_VENDOR_REQUEST_IN	0xc0
+#define DEVICE_CLASS_REQUEST_OUT	0x20
+
+#define BTUSB_MAX_ISOC_FRAMES	10
+#define BTUSB_INTR_RUNNING	0
+#define BTUSB_BULK_RUNNING	1
+#define BTUSB_ISOC_RUNNING	2
+#define BTUSB_SUSPENDING	3
+#define BTUSB_DID_ISO_RESUME	4
+
+/* ROM Patch */
+#define PATCH_HCI_HEADER_SIZE 4
+#define PATCH_WMT_HEADER_SIZE 5
+#define PATCH_HEADER_SIZE (PATCH_HCI_HEADER_SIZE + PATCH_WMT_HEADER_SIZE)
+#define UPLOAD_PATCH_UNIT 2048
+#define PATCH_INFO_SIZE 30
+#define PATCH_PHASE1 1
+#define PATCH_PHASE2 2
+#define PATCH_PHASE3 3
+
+struct btmtk_usb_data {
+	struct hci_dev *hdev;
+	struct usb_device    *udev;
+	struct usb_interface *intf;
+	struct usb_interface *isoc;
+
+	spinlock_t lock;
+
+	unsigned long flags;
+	struct work_struct work;
+	struct work_struct waker;
+
+	struct usb_anchor tx_anchor;
+	struct usb_anchor intr_anchor;
+	struct usb_anchor bulk_anchor;
+	struct usb_anchor isoc_anchor;
+	struct usb_anchor deferred;
+	int tx_in_flight;
+	spinlock_t txlock;
+
+	struct usb_endpoint_descriptor *intr_ep;
+	struct usb_endpoint_descriptor *bulk_tx_ep;
+	struct usb_endpoint_descriptor *bulk_rx_ep;
+	struct usb_endpoint_descriptor *isoc_tx_ep;
+	struct usb_endpoint_descriptor *isoc_rx_ep;
+
+	__u8 cmdreq_type;
+
+	unsigned int sco_num;
+	int isoc_altsetting;
+	int suspend_count;
+
+	/* request for different io operation */
+	u8 w_request;
+	u8 r_request;
+
+	/* io buffer for usb control transfer */
+	char *io_buf;
+
+	struct semaphore fw_upload_sem;
+
+	/* unsigned char *fw_image; */
+	/* unsigned char *rom_patch; */
+	const struct firmware *firmware;
+	u32 chip_id;
+	u8 need_load_fw;
+	u8 need_load_rom_patch;
+	u32 rom_patch_offset;
+	u32 rom_patch_len;
+};
+
+static inline int is_mt7630(struct btmtk_usb_data *data)
+{
+	return ((data->chip_id & 0xffff0000) == 0x76300000);
+}
+
+static inline int is_mt7650(struct btmtk_usb_data *data)
+{
+	return ((data->chip_id & 0xffff0000) == 0x76500000);
+}
+
+static inline int is_mt7632(struct btmtk_usb_data *data)
+{
+	return ((data->chip_id & 0xffff0000) == 0x76320000);
+}
+
+static inline int is_mt7662(struct btmtk_usb_data *data)
+{
+	return ((data->chip_id & 0xffff0000) == 0x76620000);
+}
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/btmtk_usb/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/btmtk_usb/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,11 @@
+config USB_BTMTK
+	tristate "Mediatek Bluetooth support"
+	depends on USB && BT && m
+	---help---
+	  Say Y here if you wish to control a MTK USB Bluetooth.
+
+	  This option depends on 'USB' support being enabled
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called btmtk_usb.
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/btmtk_usb/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/Makefile
--- linux-libre-3.10-gnu/drivers/staging/btmtk_usb/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_BTMTK)	+= btmtk_usb.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/btmtk_usb/README linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/README
--- linux-libre-3.10-gnu/drivers/staging/btmtk_usb/README	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/README	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,14 @@
+-build driver modules
+	make
+
+-install driver modules
+	make install
+
+-remove driver modules
+	make clean
+
+-dynamic debug message
+	turn on CONFIG_DYNAMIC_DEBUG compiler flag for current kernel
+	mount -t debugfs none /sys/kernel/debug/
+	echo "module module_name +p" > /sys/kernel/debug/dynamic_debug/control(turn on debug messages, module name such as btmtk_usb)
+	echo "module module_name -p" > /sys/kernel/debug/dynamic_debug/control(turn off debug messages, module name such as btmtk_usb)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/btmtk_usb/TODO linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/TODO
--- linux-libre-3.10-gnu/drivers/staging/btmtk_usb/TODO	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/btmtk_usb/TODO	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,10 @@
+TODO:
+        - checkpatch.pl clean
+	- determine if the driver should not be using a duplicate
+          version of the usb-bluetooth interface code, but should
+          be merged into the drivers/bluetooth/ directory and
+          infrastructure instead.
+	- review by the bluetooth developer community
+
+Please send any patches for this driver to Yu-Chen, Cho <acho@suse.com> and
+jay.hung@mediatek.com
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ced1401/ced_ioc.c linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/ced_ioc.c
--- linux-libre-3.10-gnu/drivers/staging/ced1401/ced_ioc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/ced_ioc.c	2013-08-25 20:43:22.000000000 -0400
@@ -37,13 +37,14 @@
 **
 ** Empties the Output buffer and sets int lines. Used from user level only
 ****************************************************************************/
-void FlushOutBuff(DEVICE_EXTENSION * pdx)
+static void FlushOutBuff(DEVICE_EXTENSION *pdx)
 {
 	dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__,
 		pdx->sCurrentState);
 	if (pdx->sCurrentState == U14ERR_TIME)	/* Do nothing if hardware in trouble */
 		return;
-//    CharSend_Cancel(pdx);                   /* Kill off any pending I/O */
+	/* Kill off any pending I/O */
+	/* CharSend_Cancel(pdx);  */
 	spin_lock_irq(&pdx->charOutLock);
 	pdx->dwNumOutput = 0;
 	pdx->dwOutBuffGet = 0;
@@ -57,13 +58,14 @@ void FlushOutBuff(DEVICE_EXTENSION * pdx
 **
 ** Empties the input buffer and sets int lines
 ****************************************************************************/
-void FlushInBuff(DEVICE_EXTENSION * pdx)
+static void FlushInBuff(DEVICE_EXTENSION *pdx)
 {
 	dev_dbg(&pdx->interface->dev, "%s currentState=%d", __func__,
 		pdx->sCurrentState);
 	if (pdx->sCurrentState == U14ERR_TIME)	/* Do nothing if hardware in trouble */
 		return;
-//    CharRead_Cancel(pDevObject);            /* Kill off any pending I/O */
+	/* Kill off any pending I/O */
+	/*     CharRead_Cancel(pDevObject);  */
 	spin_lock_irq(&pdx->charInLock);
 	pdx->dwNumInput = 0;
 	pdx->dwInBuffGet = 0;
@@ -77,11 +79,11 @@ void FlushInBuff(DEVICE_EXTENSION * pdx)
 ** Utility routine to copy chars into the output buffer and fire them off.
 ** called from user mode, holds charOutLock.
 ****************************************************************************/
-static int PutChars(DEVICE_EXTENSION * pdx, const char *pCh,
+static int PutChars(DEVICE_EXTENSION *pdx, const char *pCh,
 		    unsigned int uCount)
 {
 	int iReturn;
-	spin_lock_irq(&pdx->charOutLock);	// get the output spin lock
+	spin_lock_irq(&pdx->charOutLock);	/*  get the output spin lock */
 	if ((OUTBUF_SZ - pdx->dwNumOutput) >= uCount) {
 		unsigned int u;
 		for (u = 0; u < uCount; u++) {
@@ -91,9 +93,9 @@ static int PutChars(DEVICE_EXTENSION * p
 		}
 		pdx->dwNumOutput += uCount;
 		spin_unlock_irq(&pdx->charOutLock);
-		iReturn = SendChars(pdx);	// ...give a chance to transmit data
+		iReturn = SendChars(pdx);	/*  ...give a chance to transmit data */
 	} else {
-		iReturn = U14ERR_NOOUT;	// no room at the out (ha-ha)
+		iReturn = U14ERR_NOOUT;	/*  no room at the out (ha-ha) */
 		spin_unlock_irq(&pdx->charOutLock);
 	}
 	return iReturn;
@@ -104,26 +106,25 @@ static int PutChars(DEVICE_EXTENSION * p
 ** trigger an output transfer if this is appropriate. User mode.
 ** Holds the io_mutex
 *****************************************************************************/
-int SendString(DEVICE_EXTENSION * pdx, const char __user * pData,
+int SendString(DEVICE_EXTENSION *pdx, const char __user *pData,
 	       unsigned int n)
 {
-	int iReturn = U14ERR_NOERROR;	// assume all will be well
-	char buffer[OUTBUF_SZ + 1];	// space in our address space for characters
-	if (n > OUTBUF_SZ)	// check space in local buffer...
-		return U14ERR_NOOUT;	// ...too many characters
+	int iReturn = U14ERR_NOERROR;	/*  assume all will be well */
+	char buffer[OUTBUF_SZ + 1];	/*  space in our address space for characters */
+	if (n > OUTBUF_SZ)	/*  check space in local buffer... */
+		return U14ERR_NOOUT;	/*  ...too many characters */
 	if (copy_from_user(buffer, pData, n))
 		return -EFAULT;
-	buffer[n] = 0;		// terminate for debug purposes
+	buffer[n] = 0;		/*  terminate for debug purposes */
 
-	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
-	if (n > 0)		// do nothing if nowt to do!
-	{
+	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
+	if (n > 0) {		/*  do nothing if nowt to do! */
 		dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__, n,
 			buffer);
 		iReturn = PutChars(pdx, buffer, n);
 	}
 
-	Allowi(pdx);		// make sure we have input int
+	Allowi(pdx);		/*  make sure we have input int */
 	mutex_unlock(&pdx->io_mutex);
 
 	return iReturn;
@@ -134,13 +135,13 @@ int SendString(DEVICE_EXTENSION * pdx, c
 **
 ** Sends a single character to the 1401. User mode, holds io_mutex.
 ****************************************************************************/
-int SendChar(DEVICE_EXTENSION * pdx, char c)
+int SendChar(DEVICE_EXTENSION *pdx, char c)
 {
 	int iReturn;
-	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
+	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
 	iReturn = PutChars(pdx, &c, 1);
 	dev_dbg(&pdx->interface->dev, "SendChar >%c< (0x%02x)", c, c);
-	Allowi(pdx);	// Make sure char reads are running
+	Allowi(pdx);	/*  Make sure char reads are running */
 	mutex_unlock(&pdx->io_mutex);
 	return iReturn;
 }
@@ -171,20 +172,20 @@ int SendChar(DEVICE_EXTENSION * pdx, cha
 **
 ** return error code (U14ERR_NOERROR for OK)
 */
-int Get1401State(DEVICE_EXTENSION * pdx, __u32 * state, __u32 * error)
+int Get1401State(DEVICE_EXTENSION *pdx, __u32 *state, __u32 *error)
 {
 	int nGot;
 	dev_dbg(&pdx->interface->dev, "Get1401State() entry");
 
-	*state = 0xFFFFFFFF;	// Start off with invalid state
+	*state = 0xFFFFFFFF;	/*  Start off with invalid state */
 	nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
 			       GET_STATUS, (D_TO_H | VENDOR | DEVREQ), 0, 0,
 			       pdx->statBuf, sizeof(pdx->statBuf), HZ);
 	if (nGot != sizeof(pdx->statBuf)) {
 		dev_err(&pdx->interface->dev,
 			"Get1401State() FAILED, return code %d", nGot);
-		pdx->sCurrentState = U14ERR_TIME;	// Indicate that things are very wrong indeed
-		*state = 0;	// Force status values to a known state
+		pdx->sCurrentState = U14ERR_TIME;	/*  Indicate that things are very wrong indeed */
+		*state = 0;	/*  Force status values to a known state */
 		*error = 0;
 	} else {
 		int nDevice;
@@ -192,17 +193,16 @@ int Get1401State(DEVICE_EXTENSION * pdx,
 			"Get1401State() Success, state: 0x%x, 0x%x",
 			pdx->statBuf[0], pdx->statBuf[1]);
 
-		*state = pdx->statBuf[0];	// Return the state values to the calling code
+		*state = pdx->statBuf[0];	/*  Return the state values to the calling code */
 		*error = pdx->statBuf[1];
 
-		nDevice = pdx->udev->descriptor.bcdDevice >> 8;	// 1401 type code value
-		switch (nDevice)	// so we can clean up current state
-		{
+		nDevice = pdx->udev->descriptor.bcdDevice >> 8;	/*  1401 type code value */
+		switch (nDevice) {	/*  so we can clean up current state */
 		case 0:
 			pdx->sCurrentState = U14ERR_U1401;
 			break;
 
-		default:	// allow lots of device codes for future 1401s
+		default:	/*  allow lots of device codes for future 1401s */
 			if ((nDevice >= 1) && (nDevice <= 23))
 				pdx->sCurrentState = (short)(nDevice + 6);
 			else
@@ -219,7 +219,7 @@ int Get1401State(DEVICE_EXTENSION * pdx,
 **
 ** Kills off staged read\write request from the USB if one is pending.
 ****************************************************************************/
-int ReadWrite_Cancel(DEVICE_EXTENSION * pdx)
+int ReadWrite_Cancel(DEVICE_EXTENSION *pdx)
 {
 	dev_dbg(&pdx->interface->dev, "ReadWrite_Cancel entry %d",
 		pdx->bStagedUrbPending);
@@ -227,24 +227,23 @@ int ReadWrite_Cancel(DEVICE_EXTENSION *
 	int ntStatus = STATUS_SUCCESS;
 	bool bResult = false;
 	unsigned int i;
-	// We can fill this in when we know how we will implement the staged transfer stuff
+	/*  We can fill this in when we know how we will implement the staged transfer stuff */
 	spin_lock_irq(&pdx->stagedLock);
 
-	if (pdx->bStagedUrbPending)	// anything to be cancelled? May need more...
-	{
+	if (pdx->bStagedUrbPending) {	/*  anything to be cancelled? May need more... */
 		dev_info(&pdx->interface - dev,
 			 "ReadWrite_Cancel about to cancel Urb");
-
-		//       KeClearEvent(&pdx->StagingDoneEvent);   // Clear the staging done flag
+		/* Clear the staging done flag */
+		/* KeClearEvent(&pdx->StagingDoneEvent); */
 		USB_ASSERT(pdx->pStagedIrp != NULL);
 
-		// Release the spinlock first otherwise the completion routine may hang
-		//  on the spinlock while this function hands waiting for the event.
+		/*  Release the spinlock first otherwise the completion routine may hang */
+		/*   on the spinlock while this function hands waiting for the event. */
 		spin_unlock_irq(&pdx->stagedLock);
-		bResult = IoCancelIrp(pdx->pStagedIrp);	// Actually do the cancel
+		bResult = IoCancelIrp(pdx->pStagedIrp);	/*  Actually do the cancel */
 		if (bResult) {
 			LARGE_INTEGER timeout;
-			timeout.QuadPart = -10000000;	// Use a timeout of 1 second
+			timeout.QuadPart = -10000000;	/*  Use a timeout of 1 second */
 			dev_info(&pdx->interface - dev,
 				 "ReadWrite_Cancel about to wait till done");
 			ntStatus =
@@ -274,14 +273,14 @@ int ReadWrite_Cancel(DEVICE_EXTENSION *
 ** InSelfTest - utility to check in self test. Return 1 for ST, 0 for not or
 ** a -ve error code if we failed for some reason.
 ***************************************************************************/
-static int InSelfTest(DEVICE_EXTENSION * pdx, unsigned int *pState)
+static int InSelfTest(DEVICE_EXTENSION *pdx, unsigned int *pState)
 {
 	unsigned int state, error;
-	int iReturn = Get1401State(pdx, &state, &error);	// see if in self-test
-	if (iReturn == U14ERR_NOERROR)	// if all still OK
-		iReturn = (state == (unsigned int)-1) ||	// TX problem or...
-		    ((state & 0xff) == 0x80);	// ...self test
-	*pState = state;	// return actual state
+	int iReturn = Get1401State(pdx, &state, &error);	/*  see if in self-test */
+	if (iReturn == U14ERR_NOERROR)	/*  if all still OK */
+		iReturn = (state == (unsigned int)-1) ||	/*  TX problem or... */
+		    ((state & 0xff) == 0x80);	/*  ...self test */
+	*pState = state;	/*  return actual state */
 	return iReturn;
 }
 
@@ -303,48 +302,45 @@ static int InSelfTest(DEVICE_EXTENSION *
 **
 **  Returns TRUE if a 1401 detected and OK, else FALSE
 ****************************************************************************/
-bool Is1401(DEVICE_EXTENSION * pdx)
+bool Is1401(DEVICE_EXTENSION *pdx)
 {
 	int iReturn;
 	dev_dbg(&pdx->interface->dev, "%s", __func__);
 
-	ced_draw_down(pdx);	// wait for, then kill outstanding Urbs
-	FlushInBuff(pdx);	// Clear out input buffer & pipe
-	FlushOutBuff(pdx);	// Clear output buffer & pipe
+	ced_draw_down(pdx);	/*  wait for, then kill outstanding Urbs */
+	FlushInBuff(pdx);	/*  Clear out input buffer & pipe */
+	FlushOutBuff(pdx);	/*  Clear output buffer & pipe */
 
-	// The next call returns 0 if OK, but has returned 1 in the past, meaning that
-	// usb_unlock_device() is needed... now it always is
+	/*  The next call returns 0 if OK, but has returned 1 in the past, meaning that */
+	/*  usb_unlock_device() is needed... now it always is */
 	iReturn = usb_lock_device_for_reset(pdx->udev, pdx->interface);
 
-	// release the io_mutex because if we don't, we will deadlock due to system
-	// calls back into the driver.
-	mutex_unlock(&pdx->io_mutex);	// locked, so we will not get system calls
-	if (iReturn >= 0)	// if we failed
-	{
-		iReturn = usb_reset_device(pdx->udev);	// try to do the reset
-		usb_unlock_device(pdx->udev);	// undo the lock
+	/*  release the io_mutex because if we don't, we will deadlock due to system */
+	/*  calls back into the driver. */
+	mutex_unlock(&pdx->io_mutex);	/*  locked, so we will not get system calls */
+	if (iReturn >= 0) {	/*  if we failed */
+		iReturn = usb_reset_device(pdx->udev);	/*  try to do the reset */
+		usb_unlock_device(pdx->udev);	/*  undo the lock */
 	}
 
-	mutex_lock(&pdx->io_mutex);	// hold stuff off while we wait
-	pdx->dwDMAFlag = MODE_CHAR;	// Clear DMA mode flag regardless!
-	if (iReturn == 0)	// if all is OK still
-	{
+	mutex_lock(&pdx->io_mutex);	/*  hold stuff off while we wait */
+	pdx->dwDMAFlag = MODE_CHAR;	/*  Clear DMA mode flag regardless! */
+	if (iReturn == 0) {	/*  if all is OK still */
 		unsigned int state;
-		iReturn = InSelfTest(pdx, &state);	// see if likely in self test
-		if (iReturn > 0)	// do we need to wait for self-test?
-		{
-			unsigned long ulTimeOut = jiffies + 30 * HZ;	// when to give up
+		iReturn = InSelfTest(pdx, &state);	/*  see if likely in self test */
+		if (iReturn > 0) {	/*  do we need to wait for self-test? */
+			unsigned long ulTimeOut = jiffies + 30 * HZ;	/*  when to give up */
 			while ((iReturn > 0) && time_before(jiffies, ulTimeOut)) {
-				schedule();	// let other stuff run
-				iReturn = InSelfTest(pdx, &state);	// see if done yet
+				schedule();	/*  let other stuff run */
+				iReturn = InSelfTest(pdx, &state);	/*  see if done yet */
 			}
 		}
 
-		if (iReturn == 0)	// if all is OK...
-			iReturn = state == 0;	// then success is that the state is 0
+		if (iReturn == 0)	/*  if all is OK... */
+			iReturn = state == 0;	/*  then success is that the state is 0 */
 	} else
-		iReturn = 0;	// we failed
-	pdx->bForceReset = false;	// Clear forced reset flag now
+		iReturn = 0;	/*  we failed */
+	pdx->bForceReset = false;	/*  Clear forced reset flag now */
 
 	return iReturn > 0;
 }
@@ -363,45 +359,42 @@ bool Is1401(DEVICE_EXTENSION * pdx)
 **
 ** The return value is TRUE if a useable 1401 is found, FALSE if not
 */
-bool QuickCheck(DEVICE_EXTENSION * pdx, bool bTestBuff, bool bCanReset)
+bool QuickCheck(DEVICE_EXTENSION *pdx, bool bTestBuff, bool bCanReset)
 {
-	bool bRet = false;	// assume it will fail and we will reset
+	bool bRet = false;	/*  assume it will fail and we will reset */
 	bool bShortTest;
 
-	bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) &&	// no DMA running
-		      (!pdx->bForceReset) &&	// Not had a real reset forced
-		      (pdx->sCurrentState >= U14ERR_STD));	// No 1401 errors stored
+	bShortTest = ((pdx->dwDMAFlag == MODE_CHAR) &&	/*  no DMA running */
+		      (!pdx->bForceReset) &&	/*  Not had a real reset forced */
+		      (pdx->sCurrentState >= U14ERR_STD));	/*  No 1401 errors stored */
 
 	dev_dbg(&pdx->interface->dev,
 		"%s DMAFlag:%d, state:%d, force:%d, testBuff:%d, short:%d",
 		__func__, pdx->dwDMAFlag, pdx->sCurrentState, pdx->bForceReset,
 		bTestBuff, bShortTest);
 
-	if ((bTestBuff) &&	// Buffer check requested, and...
-	    (pdx->dwNumInput || pdx->dwNumOutput))	// ...characters were in the buffer?
-	{
-		bShortTest = false;	// Then do the full test
+	if ((bTestBuff) &&	/*  Buffer check requested, and... */
+	    (pdx->dwNumInput || pdx->dwNumOutput)) {	/*  ...characters were in the buffer? */
+		bShortTest = false;	/*  Then do the full test */
 		dev_dbg(&pdx->interface->dev,
 			"%s will reset as buffers not empty", __func__);
 	}
 
-	if (bShortTest || !bCanReset)	// Still OK to try the short test?
-	{			// Always test if no reset - we want state update
+	if (bShortTest || !bCanReset) {	/*  Still OK to try the short test? */
+				/*  Always test if no reset - we want state update */
 		unsigned int state, error;
 		dev_dbg(&pdx->interface->dev, "%s->Get1401State", __func__);
-		if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR)	// Check on the 1401 state
-		{
-			if ((state & 0xFF) == 0)	// If call worked, check the status value
-				bRet = true;	// If that was zero, all is OK, no reset needed
+		if (Get1401State(pdx, &state, &error) == U14ERR_NOERROR) {	/*  Check on the 1401 state */
+			if ((state & 0xFF) == 0)	/*  If call worked, check the status value */
+				bRet = true;	/*  If that was zero, all is OK, no reset needed */
 		}
 	}
 
-	if (!bRet && bCanReset)	// If all not OK, then
-	{
+	if (!bRet && bCanReset)	{ /*  If all not OK, then */
 		dev_info(&pdx->interface->dev, "%s->Is1401 %d %d %d %d",
 			 __func__, bShortTest, pdx->sCurrentState, bTestBuff,
 			 pdx->bForceReset);
-		bRet = Is1401(pdx);	//  do full test
+		bRet = Is1401(pdx);	/*   do full test */
 	}
 
 	return bRet;
@@ -412,11 +405,11 @@ bool QuickCheck(DEVICE_EXTENSION * pdx,
 **
 ** Resets the 1401 and empties the i/o buffers
 *****************************************************************************/
-int Reset1401(DEVICE_EXTENSION * pdx)
+int Reset1401(DEVICE_EXTENSION *pdx)
 {
-	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
+	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
 	dev_dbg(&pdx->interface->dev, "ABout to call QuickCheck");
-	QuickCheck(pdx, true, true);	// Check 1401, reset if not OK
+	QuickCheck(pdx, true, true);	/*  Check 1401, reset if not OK */
 	mutex_unlock(&pdx->io_mutex);
 	return U14ERR_NOERROR;
 }
@@ -426,30 +419,29 @@ int Reset1401(DEVICE_EXTENSION * pdx)
 **
 ** Gets a single character from the 1401
 ****************************************************************************/
-int GetChar(DEVICE_EXTENSION * pdx)
+int GetChar(DEVICE_EXTENSION *pdx)
 {
-	int iReturn = U14ERR_NOIN;	// assume we will get  nothing
-	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
+	int iReturn = U14ERR_NOIN;	/*  assume we will get  nothing */
+	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
 
 	dev_dbg(&pdx->interface->dev, "GetChar");
 
-	Allowi(pdx);	// Make sure char reads are running
-	SendChars(pdx);	// and send any buffered chars
+	Allowi(pdx);	/*  Make sure char reads are running */
+	SendChars(pdx);	/*  and send any buffered chars */
 
 	spin_lock_irq(&pdx->charInLock);
-	if (pdx->dwNumInput > 0)	// worth looking
-	{
+	if (pdx->dwNumInput > 0) {	/*  worth looking */
 		iReturn = pdx->inputBuffer[pdx->dwInBuffGet++];
 		if (pdx->dwInBuffGet >= INBUF_SZ)
 			pdx->dwInBuffGet = 0;
 		pdx->dwNumInput--;
 	} else
-		iReturn = U14ERR_NOIN;	// no input data to read
+		iReturn = U14ERR_NOIN;	/*  no input data to read */
 	spin_unlock_irq(&pdx->charInLock);
 
-	Allowi(pdx);	// Make sure char reads are running
+	Allowi(pdx);	/*  Make sure char reads are running */
 
-	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o
+	mutex_unlock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
 	return iReturn;
 }
 
@@ -464,46 +456,43 @@ int GetChar(DEVICE_EXTENSION * pdx)
 ** returns the count of characters (including the terminator, or 0 if none
 ** or a negative error code.
 ****************************************************************************/
-int GetString(DEVICE_EXTENSION * pdx, char __user * pUser, int n)
+int GetString(DEVICE_EXTENSION *pdx, char __user *pUser, int n)
 {
-	int nAvailable;		// character in the buffer
+	int nAvailable;		/*  character in the buffer */
 	int iReturn = U14ERR_NOIN;
 	if (n <= 0)
 		return -ENOMEM;
 
-	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
-	Allowi(pdx);	// Make sure char reads are running
-	SendChars(pdx);		// and send any buffered chars
+	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
+	Allowi(pdx);	/*  Make sure char reads are running */
+	SendChars(pdx);		/*  and send any buffered chars */
 
 	spin_lock_irq(&pdx->charInLock);
-	nAvailable = pdx->dwNumInput;	// characters available now
-	if (nAvailable > n)	// read max of space in pUser...
-		nAvailable = n;	// ...or input characters
+	nAvailable = pdx->dwNumInput;	/*  characters available now */
+	if (nAvailable > n)	/*  read max of space in pUser... */
+		nAvailable = n;	/*  ...or input characters */
 
-	if (nAvailable > 0)	// worth looking?
-	{
-		char buffer[INBUF_SZ + 1];	// space for a linear copy of data
+	if (nAvailable > 0) {	/*  worth looking? */
+		char buffer[INBUF_SZ + 1];	/*  space for a linear copy of data */
 		int nGot = 0;
-		int nCopyToUser;	// number to copy to user
+		int nCopyToUser;	/*  number to copy to user */
 		char cData;
 		do {
 			cData = pdx->inputBuffer[pdx->dwInBuffGet++];
-			if (cData == CR_CHAR)	// replace CR with zero
+			if (cData == CR_CHAR)	/*  replace CR with zero */
 				cData = (char)0;
 
 			if (pdx->dwInBuffGet >= INBUF_SZ)
-				pdx->dwInBuffGet = 0;	// wrap buffer pointer
+				pdx->dwInBuffGet = 0;	/*  wrap buffer pointer */
 
-			buffer[nGot++] = cData;	// save the output
-		}
-		while ((nGot < nAvailable) && cData);
+			buffer[nGot++] = cData;	/*  save the output */
+		} while ((nGot < nAvailable) && cData);
 
-		nCopyToUser = nGot;	// what to copy...
-		if (cData)	// do we need null
-		{
-			buffer[nGot] = (char)0;	// make it tidy
-			if (nGot < n)	// if space in user buffer...
-				++nCopyToUser;	// ...copy the 0 as well.
+		nCopyToUser = nGot;	/*  what to copy... */
+		if (cData) {	/*  do we need null */
+			buffer[nGot] = (char)0;	/*  make it tidy */
+			if (nGot < n)	/*  if space in user buffer... */
+				++nCopyToUser;	/*  ...copy the 0 as well. */
 		}
 
 		pdx->dwNumInput -= nGot;
@@ -514,12 +503,12 @@ int GetString(DEVICE_EXTENSION * pdx, ch
 		if (copy_to_user(pUser, buffer, nCopyToUser))
 			iReturn = -EFAULT;
 		else
-			iReturn = nGot;		// report characters read
+			iReturn = nGot;		/*  report characters read */
 	} else
 		spin_unlock_irq(&pdx->charInLock);
 
-	Allowi(pdx);	// Make sure char reads are running
-	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o
+	Allowi(pdx);	/*  Make sure char reads are running */
+	mutex_unlock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
 
 	return iReturn;
 }
@@ -527,14 +516,14 @@ int GetString(DEVICE_EXTENSION * pdx, ch
 /*******************************************************************************
 ** Get count of characters in the inout buffer.
 *******************************************************************************/
-int Stat1401(DEVICE_EXTENSION * pdx)
+int Stat1401(DEVICE_EXTENSION *pdx)
 {
 	int iReturn;
-	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
-	Allowi(pdx);		// make sure we allow pending chars
-	SendChars(pdx);		// in both directions
-	iReturn = pdx->dwNumInput;	// no lock as single read
-	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o
+	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
+	Allowi(pdx);		/*  make sure we allow pending chars */
+	SendChars(pdx);		/*  in both directions */
+	iReturn = pdx->dwNumInput;	/*  no lock as single read */
+	mutex_unlock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
 	return iReturn;
 }
 
@@ -545,32 +534,30 @@ int Stat1401(DEVICE_EXTENSION * pdx)
 ** any fancy interlocks as we only read the interrupt routine data, and the
 ** system is arranged so nothing can be destroyed.
 ****************************************************************************/
-int LineCount(DEVICE_EXTENSION * pdx)
+int LineCount(DEVICE_EXTENSION *pdx)
 {
-	int iReturn = 0;	// will be count of line ends
+	int iReturn = 0;	/*  will be count of line ends */
 
-	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
-	Allowi(pdx);		// Make sure char reads are running
-	SendChars(pdx);		// and send any buffered chars
-	spin_lock_irq(&pdx->charInLock);	// Get protection
+	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
+	Allowi(pdx);		/*  Make sure char reads are running */
+	SendChars(pdx);		/*  and send any buffered chars */
+	spin_lock_irq(&pdx->charInLock);	/*  Get protection */
 
-	if (pdx->dwNumInput > 0)	// worth looking?
-	{
-		unsigned int dwIndex = pdx->dwInBuffGet;	// start at first available
-		unsigned int dwEnd = pdx->dwInBuffPut;	// Position for search end
+	if (pdx->dwNumInput > 0) {	/*  worth looking? */
+		unsigned int dwIndex = pdx->dwInBuffGet;	/*  start at first available */
+		unsigned int dwEnd = pdx->dwInBuffPut;	/*  Position for search end */
 		do {
 			if (pdx->inputBuffer[dwIndex++] == CR_CHAR)
-				++iReturn;	// inc count if CR
+				++iReturn;	/*  inc count if CR */
 
-			if (dwIndex >= INBUF_SZ)	// see if we fall off buff
+			if (dwIndex >= INBUF_SZ)	/*  see if we fall off buff */
 				dwIndex = 0;
-		}
-		while (dwIndex != dwEnd);	// go to last available
+		} while (dwIndex != dwEnd);	/*  go to last available */
 	}
 
 	spin_unlock_irq(&pdx->charInLock);
 	dev_dbg(&pdx->interface->dev, "LineCount returned %d", iReturn);
-	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o
+	mutex_unlock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
 	return iReturn;
 }
 
@@ -579,14 +566,14 @@ int LineCount(DEVICE_EXTENSION * pdx)
 **
 ** Gets the space in the output buffer. Called from user code.
 *****************************************************************************/
-int GetOutBufSpace(DEVICE_EXTENSION * pdx)
+int GetOutBufSpace(DEVICE_EXTENSION *pdx)
 {
 	int iReturn;
-	mutex_lock(&pdx->io_mutex);	// Protect disconnect from new i/o
-	SendChars(pdx);		// send any buffered chars
-	iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput);	// no lock needed for single read
+	mutex_lock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
+	SendChars(pdx);		/*  send any buffered chars */
+	iReturn = (int)(OUTBUF_SZ - pdx->dwNumOutput);	/*  no lock needed for single read */
 	dev_dbg(&pdx->interface->dev, "OutBufSpace %d", iReturn);
-	mutex_unlock(&pdx->io_mutex);	// Protect disconnect from new i/o
+	mutex_unlock(&pdx->io_mutex);	/*  Protect disconnect from new i/o */
 	return iReturn;
 }
 
@@ -597,7 +584,7 @@ int GetOutBufSpace(DEVICE_EXTENSION * pd
 ** Clears up a transfer area. This is always called in the context of a user
 ** request, never from a call-back.
 ****************************************************************************/
-int ClearArea(DEVICE_EXTENSION * pdx, int nArea)
+int ClearArea(DEVICE_EXTENSION *pdx, int nArea)
 {
 	int iReturn = U14ERR_NOERROR;
 
@@ -606,14 +593,14 @@ int ClearArea(DEVICE_EXTENSION * pdx, in
 		dev_err(&pdx->interface->dev, "%s Attempt to clear area %d",
 			__func__, nArea);
 	} else {
-		TRANSAREA *pTA = &pdx->rTransDef[nArea];	// to save typing
-		if (!pTA->bUsed)	// if not used...
-			iReturn = U14ERR_NOTSET;	// ...nothing to be done
+		TRANSAREA *pTA = &pdx->rTransDef[nArea];	/*  to save typing */
+		if (!pTA->bUsed)	/*  if not used... */
+			iReturn = U14ERR_NOTSET;	/*  ...nothing to be done */
 		else {
-			// We must save the memory we return as we shouldn't mess with memory while
-			// holding a spin lock.
-			struct page **pPages = 0;	// save page address list
-			int nPages = 0;	// and number of pages
+			/*  We must save the memory we return as we shouldn't mess with memory while */
+			/*  holding a spin lock. */
+			struct page **pPages = NULL; /*save page address list*/
+			int nPages = 0;	/*  and number of pages */
 			int np;
 
 			dev_dbg(&pdx->interface->dev, "%s area %d", __func__,
@@ -621,33 +608,32 @@ int ClearArea(DEVICE_EXTENSION * pdx, in
 			spin_lock_irq(&pdx->stagedLock);
 			if ((pdx->StagedId == nArea)
 			    && (pdx->dwDMAFlag > MODE_CHAR)) {
-				iReturn = U14ERR_UNLOCKFAIL;	// cannot delete as in use
+				iReturn = U14ERR_UNLOCKFAIL;	/*  cannot delete as in use */
 				dev_err(&pdx->interface->dev,
 					"%s call on area %d while active",
 					__func__, nArea);
 			} else {
-				pPages = pTA->pPages;	// save page address list
-				nPages = pTA->nPages;	// and page count
-				if (pTA->dwEventSz)	// if events flagging in use
-					wake_up_interruptible(&pTA->wqEvent);	// release anything that was waiting
+				pPages = pTA->pPages;	/*  save page address list */
+				nPages = pTA->nPages;	/*  and page count */
+				if (pTA->dwEventSz)	/*  if events flagging in use */
+					wake_up_interruptible(&pTA->wqEvent);	/*  release anything that was waiting */
 
 				if (pdx->bXFerWaiting
 				    && (pdx->rDMAInfo.wIdent == nArea))
-					pdx->bXFerWaiting = false;	// Cannot have pending xfer if area cleared
+					pdx->bXFerWaiting = false;	/*  Cannot have pending xfer if area cleared */
 
-				// Clean out the TRANSAREA except for the wait queue, which is at the end
-				// This sets bUsed to false and dwEventSz to 0 to say area not used and no events.
+				/*  Clean out the TRANSAREA except for the wait queue, which is at the end */
+				/*  This sets bUsed to false and dwEventSz to 0 to say area not used and no events. */
 				memset(pTA, 0,
 				       sizeof(TRANSAREA) -
 				       sizeof(wait_queue_head_t));
 			}
 			spin_unlock_irq(&pdx->stagedLock);
 
-			if (pPages)	// if we decided to release the memory
-			{
-				// Now we must undo the pinning down of the pages. We will assume the worst and mark
-				// all the pages as dirty. Don't be tempted to move this up above as you must not be
-				// holding a spin lock to do this stuff as it is not atomic.
+			if (pPages) { 	/*  if we decided to release the memory */
+				/*  Now we must undo the pinning down of the pages. We will assume the worst and mark */
+				/*  all the pages as dirty. Don't be tempted to move this up above as you must not be */
+				/*  holding a spin lock to do this stuff as it is not atomic. */
 				dev_dbg(&pdx->interface->dev, "%s nPages=%d",
 					__func__, nPages);
 
@@ -674,29 +660,29 @@ int ClearArea(DEVICE_EXTENSION * pdx, in
 ** Sets up a transfer area - the functional part. Called by both
 ** SetTransfer and SetCircular.
 ****************************************************************************/
-static int SetArea(DEVICE_EXTENSION * pdx, int nArea, char __user * puBuf,
+static int SetArea(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
 		   unsigned int dwLength, bool bCircular, bool bCircToHost)
 {
-	// Start by working out the page aligned start of the area and the size
-	// of the area in pages, allowing for the start not being aligned and the
-	// end needing to be rounded up to a page boundary.
+	/*  Start by working out the page aligned start of the area and the size */
+	/*  of the area in pages, allowing for the start not being aligned and the */
+	/*  end needing to be rounded up to a page boundary. */
 	unsigned long ulStart = ((unsigned long)puBuf) & PAGE_MASK;
 	unsigned int ulOffset = ((unsigned long)puBuf) & (PAGE_SIZE - 1);
 	int len = (dwLength + ulOffset + PAGE_SIZE - 1) >> PAGE_SHIFT;
 
-	TRANSAREA *pTA = &pdx->rTransDef[nArea];	// to save typing
-	struct page **pPages = 0;	// space for page tables
-	int nPages = 0;		// and number of pages
+	TRANSAREA *pTA = &pdx->rTransDef[nArea];	/*  to save typing */
+	struct page **pPages = NULL;	/*  space for page tables */
+	int nPages = 0;		/*  and number of pages */
 
-	int iReturn = ClearArea(pdx, nArea);	// see if OK to use this area
-	if ((iReturn != U14ERR_NOTSET) &&	// if not area unused and...
-	    (iReturn != U14ERR_NOERROR))	// ...not all OK, then...
-		return iReturn;	// ...we cannot use this area
+	int iReturn = ClearArea(pdx, nArea);	/*  see if OK to use this area */
+	if ((iReturn != U14ERR_NOTSET) &&	/*  if not area unused and... */
+	    (iReturn != U14ERR_NOERROR))	/*  ...not all OK, then... */
+		return iReturn;	/*  ...we cannot use this area */
 
-	if (!access_ok(VERIFY_WRITE, puBuf, dwLength))	// if we cannot access the memory...
-		return -EFAULT;	// ...then we are done
+	if (!access_ok(VERIFY_WRITE, puBuf, dwLength))	/*  if we cannot access the memory... */
+		return -EFAULT;	/*  ...then we are done */
 
-	// Now allocate space to hold the page pointer and virtual address pointer tables
+	/*  Now allocate space to hold the page pointer and virtual address pointer tables */
 	pPages = kmalloc(len * sizeof(struct page *), GFP_KERNEL);
 	if (!pPages) {
 		iReturn = U14ERR_NOMEMORY;
@@ -705,24 +691,23 @@ static int SetArea(DEVICE_EXTENSION * pd
 	dev_dbg(&pdx->interface->dev, "%s %p, length=%06x, circular %d",
 		__func__, puBuf, dwLength, bCircular);
 
-	// To pin down user pages we must first acquire the mapping semaphore.
-	down_read(&current->mm->mmap_sem);	// get memory map semaphore
-	nPages =
-	    get_user_pages(current, current->mm, ulStart, len, 1, 0, pPages, 0);
-	up_read(&current->mm->mmap_sem);	// release the semaphore
+	/*  To pin down user pages we must first acquire the mapping semaphore. */
+	down_read(&current->mm->mmap_sem);	/*  get memory map semaphore */
+	nPages = get_user_pages(current, current->mm, ulStart, len, 1, 0,
+				pPages, NULL);
+	up_read(&current->mm->mmap_sem);	/*  release the semaphore */
 	dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages);
 
-	if (nPages > 0)		// if we succeeded
-	{
-		// If you are tempted to use page_address (form LDD3), forget it. You MUST use
-		// kmap() or kmap_atomic() to get a virtual address. page_address will give you
-		// (null) or at least it does in this context with an x86 machine.
+	if (nPages > 0) {		/*  if we succeeded */
+		/*  If you are tempted to use page_address (form LDD3), forget it. You MUST use */
+		/*  kmap() or kmap_atomic() to get a virtual address. page_address will give you */
+		/*  (null) or at least it does in this context with an x86 machine. */
 		spin_lock_irq(&pdx->stagedLock);
-		pTA->lpvBuff = puBuf;	// keep start of region (user address)
-		pTA->dwBaseOffset = ulOffset;	// save offset in first page to start of xfer
-		pTA->dwLength = dwLength;	// Size if the region in bytes
-		pTA->pPages = pPages;	// list of pages that are used by buffer
-		pTA->nPages = nPages;	// number of pages
+		pTA->lpvBuff = puBuf;	/*  keep start of region (user address) */
+		pTA->dwBaseOffset = ulOffset;	/*  save offset in first page to start of xfer */
+		pTA->dwLength = dwLength;	/*  Size if the region in bytes */
+		pTA->pPages = pPages;	/*  list of pages that are used by buffer */
+		pTA->nPages = nPages;	/*  number of pages */
 
 		pTA->bCircular = bCircular;
 		pTA->bCircToHost = bCircToHost;
@@ -731,10 +716,10 @@ static int SetArea(DEVICE_EXTENSION * pd
 		pTA->aBlocks[0].dwSize = 0;
 		pTA->aBlocks[1].dwOffset = 0;
 		pTA->aBlocks[1].dwSize = 0;
-		pTA->bUsed = true;	// This is now a used block
+		pTA->bUsed = true;	/*  This is now a used block */
 
 		spin_unlock_irq(&pdx->stagedLock);
-		iReturn = U14ERR_NOERROR;	// say all was well
+		iReturn = U14ERR_NOERROR;	/*  say all was well */
 	} else {
 		iReturn = U14ERR_LOCKFAIL;
 		goto error;
@@ -754,7 +739,7 @@ error:
 ** unset it. Unsetting will fail if the area is booked, and a transfer to that
 ** area is in progress. Otherwise, we will release the area and re-assign it.
 ****************************************************************************/
-int SetTransfer(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD)
+int SetTransfer(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD)
 {
 	int iReturn;
 	TRANSFERDESC td;
@@ -765,9 +750,9 @@ int SetTransfer(DEVICE_EXTENSION * pdx,
 	mutex_lock(&pdx->io_mutex);
 	dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__,
 		td.wAreaNum, td.dwLength);
-	// The strange cast is done so that we don't get warnings in 32-bit linux about the size of the
-	// pointer. The pointer is always passed as a 64-bit object so that we don't have problems using
-	// a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system.
+	/*  The strange cast is done so that we don't get warnings in 32-bit linux about the size of the */
+	/*  pointer. The pointer is always passed as a 64-bit object so that we don't have problems using */
+	/*  a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. */
 	iReturn =
 	    SetArea(pdx, td.wAreaNum,
 		    (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
@@ -780,7 +765,7 @@ int SetTransfer(DEVICE_EXTENSION * pdx,
 ** UnSetTransfer
 ** Erases a transfer area record
 ****************************************************************************/
-int UnsetTransfer(DEVICE_EXTENSION * pdx, int nArea)
+int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea)
 {
 	int iReturn;
 	mutex_lock(&pdx->io_mutex);
@@ -797,27 +782,26 @@ int UnsetTransfer(DEVICE_EXTENSION * pdx
 ** pretend that whatever the user asked for was achieved, so we return 1 if
 ** try to create one, and 0 if they ask to remove (assuming all else was OK).
 ****************************************************************************/
-int SetEvent(DEVICE_EXTENSION * pdx, TRANSFEREVENT __user * pTE)
+int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user *pTE)
 {
 	int iReturn = U14ERR_NOERROR;
 	TRANSFEREVENT te;
 
-	// get a local copy of the data
+	/*  get a local copy of the data */
 	if (copy_from_user(&te, pTE, sizeof(te)))
 		return -EFAULT;
 
-	if (te.wAreaNum >= MAX_TRANSAREAS)	// the area must exist
+	if (te.wAreaNum >= MAX_TRANSAREAS)	/*  the area must exist */
 		return U14ERR_BADAREA;
 	else {
 		TRANSAREA *pTA = &pdx->rTransDef[te.wAreaNum];
-		mutex_lock(&pdx->io_mutex);	// make sure we have no competitor
+		mutex_lock(&pdx->io_mutex);	/*  make sure we have no competitor */
 		spin_lock_irq(&pdx->stagedLock);
-		if (pTA->bUsed)	// area must be in use
-		{
-			pTA->dwEventSt = te.dwStart;	// set area regions
-			pTA->dwEventSz = te.dwLength;	// set size (0 cancels it)
-			pTA->bEventToHost = te.wFlags & 1;	// set the direction
-			pTA->iWakeUp = 0;	// zero the wake up count
+		if (pTA->bUsed) {	/*  area must be in use */
+			pTA->dwEventSt = te.dwStart;	/*  set area regions */
+			pTA->dwEventSz = te.dwLength;	/*  set size (0 cancels it) */
+			pTA->bEventToHost = te.wFlags & 1;	/*  set the direction */
+			pTA->iWakeUp = 0;	/*  zero the wake up count */
 		} else
 			iReturn = U14ERR_NOTSET;
 		spin_unlock_irq(&pdx->stagedLock);
@@ -833,7 +817,7 @@ int SetEvent(DEVICE_EXTENSION * pdx, TRA
 ** of times that a block met the event condition since we last cleared it or
 ** 0 if timed out, or -ve error (bad area or not set, or signal).
 ****************************************************************************/
-int WaitEvent(DEVICE_EXTENSION * pdx, int nArea, int msTimeOut)
+int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut)
 {
 	int iReturn;
 	if ((unsigned)nArea >= MAX_TRANSAREAS)
@@ -841,15 +825,15 @@ int WaitEvent(DEVICE_EXTENSION * pdx, in
 	else {
 		int iWait;
 		TRANSAREA *pTA = &pdx->rTransDef[nArea];
-		msTimeOut = (msTimeOut * HZ + 999) / 1000;	// convert timeout to jiffies
+		msTimeOut = (msTimeOut * HZ + 999) / 1000;	/*  convert timeout to jiffies */
 
-		// We cannot wait holding the mutex, but we check the flags while holding
-		// it. This may well be pointless as another thread could get in between
-		// releasing it and the wait call. However, this would have to clear the
-		// iWakeUp flag. However, the !pTA-bUsed may help us in this case.
-		mutex_lock(&pdx->io_mutex);	// make sure we have no competitor
-		if (!pTA->bUsed || !pTA->dwEventSz)	// check something to wait for...
-			return U14ERR_NOTSET;	// ...else we do nothing
+		/*  We cannot wait holding the mutex, but we check the flags while holding */
+		/*  it. This may well be pointless as another thread could get in between */
+		/*  releasing it and the wait call. However, this would have to clear the */
+		/*  iWakeUp flag. However, the !pTA-bUsed may help us in this case. */
+		mutex_lock(&pdx->io_mutex);	/*  make sure we have no competitor */
+		if (!pTA->bUsed || !pTA->dwEventSz)	/*  check something to wait for... */
+			return U14ERR_NOTSET;	/*  ...else we do nothing */
 		mutex_unlock(&pdx->io_mutex);
 
 		if (msTimeOut)
@@ -863,12 +847,12 @@ int WaitEvent(DEVICE_EXTENSION * pdx, in
 			    wait_event_interruptible(pTA->wqEvent, pTA->iWakeUp
 						     || !pTA->bUsed);
 		if (iWait)
-			iReturn = -ERESTARTSYS;	// oops - we have had a SIGNAL
+			iReturn = -ERESTARTSYS;	/*  oops - we have had a SIGNAL */
 		else
-			iReturn = pTA->iWakeUp;	// else the wakeup count
+			iReturn = pTA->iWakeUp;	/*  else the wakeup count */
 
 		spin_lock_irq(&pdx->stagedLock);
-		pTA->iWakeUp = 0;	// clear the flag
+		pTA->iWakeUp = 0;	/*  clear the flag */
 		spin_unlock_irq(&pdx->stagedLock);
 	}
 	return iReturn;
@@ -880,17 +864,17 @@ int WaitEvent(DEVICE_EXTENSION * pdx, in
 ** number of times a block completed since the last call, or 0 if none or a
 ** negative error.
 ****************************************************************************/
-int TestEvent(DEVICE_EXTENSION * pdx, int nArea)
+int TestEvent(DEVICE_EXTENSION *pdx, int nArea)
 {
 	int iReturn;
 	if ((unsigned)nArea >= MAX_TRANSAREAS)
 		iReturn = U14ERR_BADAREA;
 	else {
 		TRANSAREA *pTA = &pdx->rTransDef[nArea];
-		mutex_lock(&pdx->io_mutex);	// make sure we have no competitor
+		mutex_lock(&pdx->io_mutex);	/*  make sure we have no competitor */
 		spin_lock_irq(&pdx->stagedLock);
-		iReturn = pTA->iWakeUp;	// get wakeup count since last call
-		pTA->iWakeUp = 0;	// clear the count
+		iReturn = pTA->iWakeUp;	/*  get wakeup count since last call */
+		pTA->iWakeUp = 0;	/*  clear the count */
 		spin_unlock_irq(&pdx->stagedLock);
 		mutex_unlock(&pdx->io_mutex);
 	}
@@ -901,17 +885,17 @@ int TestEvent(DEVICE_EXTENSION * pdx, in
 ** GetTransferInfo
 ** Puts the current state of the 1401 in a TGET_TX_BLOCK.
 *****************************************************************************/
-int GetTransfer(DEVICE_EXTENSION * pdx, TGET_TX_BLOCK __user * pTX)
+int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pTX)
 {
 	int iReturn = U14ERR_NOERROR;
 	unsigned int dwIdent;
 
 	mutex_lock(&pdx->io_mutex);
-	dwIdent = pdx->StagedId;	// area ident for last xfer
+	dwIdent = pdx->StagedId;	/*  area ident for last xfer */
 	if (dwIdent >= MAX_TRANSAREAS)
 		iReturn = U14ERR_BADAREA;
 	else {
-		// Return the best information we have - we don't have physical addresses
+		/*  Return the best information we have - we don't have physical addresses */
 		TGET_TX_BLOCK *tx;
 
 		tx = kzalloc(sizeof(*tx), GFP_KERNEL);
@@ -921,8 +905,8 @@ int GetTransfer(DEVICE_EXTENSION * pdx,
 		}
 		tx->size = pdx->rTransDef[dwIdent].dwLength;
 		tx->linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff);
-		tx->avail = GET_TX_MAXENTRIES;	// how many blocks we could return
-		tx->used = 1;	// number we actually return
+		tx->avail = GET_TX_MAXENTRIES;	/*  how many blocks we could return */
+		tx->used = 1;	/*  number we actually return */
 		tx->entries[0].physical =
 		    (long long)(tx->linear + pdx->StagedOffset);
 		tx->entries[0].size = tx->size;
@@ -940,7 +924,7 @@ int GetTransfer(DEVICE_EXTENSION * pdx,
 **
 ** Empties the host i/o buffers
 ****************************************************************************/
-int KillIO1401(DEVICE_EXTENSION * pdx)
+int KillIO1401(DEVICE_EXTENSION *pdx)
 {
 	dev_dbg(&pdx->interface->dev, "%s", __func__);
 	mutex_lock(&pdx->io_mutex);
@@ -955,7 +939,7 @@ int KillIO1401(DEVICE_EXTENSION * pdx)
 ** Returns a 0 or a 1 for whether DMA is happening. No point holding a mutex
 ** for this as it only does one read.
 *****************************************************************************/
-int BlkTransState(DEVICE_EXTENSION * pdx)
+int BlkTransState(DEVICE_EXTENSION *pdx)
 {
 	int iReturn = pdx->dwDMAFlag != MODE_CHAR;
 	dev_dbg(&pdx->interface->dev, "%s = %d", __func__, iReturn);
@@ -967,12 +951,12 @@ int BlkTransState(DEVICE_EXTENSION * pdx
 **
 ** Puts the current state of the 1401 in the Irp return buffer.
 *****************************************************************************/
-int StateOf1401(DEVICE_EXTENSION * pdx)
+int StateOf1401(DEVICE_EXTENSION *pdx)
 {
 	int iReturn;
 	mutex_lock(&pdx->io_mutex);
 
-	QuickCheck(pdx, false, false);	// get state up to date, no reset
+	QuickCheck(pdx, false, false);	/*  get state up to date, no reset */
 	iReturn = pdx->sCurrentState;
 
 	mutex_unlock(&pdx->io_mutex);
@@ -987,20 +971,23 @@ int StateOf1401(DEVICE_EXTENSION * pdx)
 ** Initiates a self-test cycle. The assumption is that we have no interrupts
 ** active, so we should make sure that this is the case.
 *****************************************************************************/
-int StartSelfTest(DEVICE_EXTENSION * pdx)
+int StartSelfTest(DEVICE_EXTENSION *pdx)
 {
 	int nGot;
 	mutex_lock(&pdx->io_mutex);
 	dev_dbg(&pdx->interface->dev, "%s", __func__);
 
-	ced_draw_down(pdx);	// wait for, then kill outstanding Urbs
-	FlushInBuff(pdx);	// Clear out input buffer & pipe
-	FlushOutBuff(pdx);	// Clear output buffer & pipe
-//    ReadWrite_Cancel(pDeviceObject);        /* so things stay tidy */
+	ced_draw_down(pdx);	/*  wait for, then kill outstanding Urbs */
+	FlushInBuff(pdx);	/*  Clear out input buffer & pipe */
+	FlushOutBuff(pdx);	/*  Clear output buffer & pipe */
+	/* so things stay tidy */
+	/* ReadWrite_Cancel(pDeviceObject); */
 	pdx->dwDMAFlag = MODE_CHAR;	/* Clear DMA mode flags here */
 
-	nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0), DB_SELFTEST, (H_TO_D | VENDOR | DEVREQ), 0, 0, 0, 0, HZ);	// allow 1 second timeout
-	pdx->ulSelfTestTime = jiffies + HZ * 30;	// 30 seconds into the future
+	nGot = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
+			       DB_SELFTEST, (H_TO_D | VENDOR | DEVREQ),
+			       0, 0, NULL, 0, HZ); /* allow 1 second timeout */
+	pdx->ulSelfTestTime = jiffies + HZ * 30;	/*  30 seconds into the future */
 
 	mutex_unlock(&pdx->io_mutex);
 	if (nGot < 0)
@@ -1013,53 +1000,49 @@ int StartSelfTest(DEVICE_EXTENSION * pdx
 **
 ** Check progress of a self-test cycle
 ****************************************************************************/
-int CheckSelfTest(DEVICE_EXTENSION * pdx, TGET_SELFTEST __user * pGST)
+int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST)
 {
 	unsigned int state, error;
 	int iReturn;
-	TGET_SELFTEST gst;	// local work space
-	memset(&gst, 0, sizeof(gst));	// clear out the space (sets code 0)
+	TGET_SELFTEST gst;	/*  local work space */
+	memset(&gst, 0, sizeof(gst));	/*  clear out the space (sets code 0) */
 
 	mutex_lock(&pdx->io_mutex);
 
 	dev_dbg(&pdx->interface->dev, "%s", __func__);
 	iReturn = Get1401State(pdx, &state, &error);
-	if (iReturn == U14ERR_NOERROR)	// Only accept zero if it happens twice
+	if (iReturn == U14ERR_NOERROR)	/*  Only accept zero if it happens twice */
 		iReturn = Get1401State(pdx, &state, &error);
 
-	if (iReturn != U14ERR_NOERROR)	// Self-test can cause comms errors
-	{			// so we assume still testing
+	if (iReturn != U14ERR_NOERROR) {	/*  Self-test can cause comms errors */
+				/*  so we assume still testing */
 		dev_err(&pdx->interface->dev,
 			"%s Get1401State=%d, assuming still testing", __func__,
 			iReturn);
-		state = 0x80;	// Force still-testing, no error
+		state = 0x80;	/*  Force still-testing, no error */
 		error = 0;
 		iReturn = U14ERR_NOERROR;
 	}
 
-	if ((state == -1) && (error == -1))	// If Get1401State had problems
-	{
+	if ((state == -1) && (error == -1)) {	/*  If Get1401State had problems */
 		dev_err(&pdx->interface->dev,
 			"%s Get1401State failed, assuming still testing",
 			__func__);
-		state = 0x80;	// Force still-testing, no error
+		state = 0x80;	/*  Force still-testing, no error */
 		error = 0;
 	}
 
-	if ((state & 0xFF) == 0x80)	// If we are still in self-test
-	{
-		if (state & 0x00FF0000)	// Have we got an error?
-		{
-			gst.code = (state & 0x00FF0000) >> 16;	// read the error code
-			gst.x = error & 0x0000FFFF;	// Error data X
-			gst.y = (error & 0xFFFF0000) >> 16;	// and data Y
+	if ((state & 0xFF) == 0x80) {	/*  If we are still in self-test */
+		if (state & 0x00FF0000)	{ /*  Have we got an error? */
+			gst.code = (state & 0x00FF0000) >> 16;	/*  read the error code */
+			gst.x = error & 0x0000FFFF;	/*  Error data X */
+			gst.y = (error & 0xFFFF0000) >> 16;	/*  and data Y */
 			dev_dbg(&pdx->interface->dev, "Self-test error code %d",
 				gst.code);
-		} else		// No error, check for timeout
-		{
-			unsigned long ulNow = jiffies;	// get current time
+		} else {		/*  No error, check for timeout */
+			unsigned long ulNow = jiffies;	/*  get current time */
 			if (time_after(ulNow, pdx->ulSelfTestTime)) {
-				gst.code = -2;	// Flag the timeout
+				gst.code = -2;	/*  Flag the timeout */
 				dev_dbg(&pdx->interface->dev,
 					"Self-test timed-out");
 			} else
@@ -1067,16 +1050,16 @@ int CheckSelfTest(DEVICE_EXTENSION * pdx
 					"Self-test on-going");
 		}
 	} else {
-		gst.code = -1;	// Flag the test is done
+		gst.code = -1;	/*  Flag the test is done */
 		dev_dbg(&pdx->interface->dev, "Self-test done");
 	}
 
-	if (gst.code < 0)	// If we have a problem or finished
-	{			// If using the 2890 we should reset properly
+	if (gst.code < 0) {	/*  If we have a problem or finished */
+				/*  If using the 2890 we should reset properly */
 		if ((pdx->nPipes == 4) && (pdx->s1401Type <= TYPEPOWER))
-			Is1401(pdx);	// Get 1401 reset and OK
+			Is1401(pdx);	/*  Get 1401 reset and OK */
 		else
-			QuickCheck(pdx, true, true);	// Otherwise check without reset unless problems
+			QuickCheck(pdx, true, true);	/*  Otherwise check without reset unless problems */
 	}
 	mutex_unlock(&pdx->io_mutex);
 
@@ -1091,7 +1074,7 @@ int CheckSelfTest(DEVICE_EXTENSION * pdx
 **
 ** Returns code for standard, plus, micro1401, power1401 or none
 ****************************************************************************/
-int TypeOf1401(DEVICE_EXTENSION * pdx)
+int TypeOf1401(DEVICE_EXTENSION *pdx)
 {
 	int iReturn = TYPEUNKNOWN;
 	mutex_lock(&pdx->io_mutex);
@@ -1100,7 +1083,7 @@ int TypeOf1401(DEVICE_EXTENSION * pdx)
 	switch (pdx->s1401Type) {
 	case TYPE1401:
 		iReturn = U14ERR_STD;
-		break;		// Handle these types directly
+		break;		/*  Handle these types directly */
 	case TYPEPLUS:
 		iReturn = U14ERR_PLUS;
 		break;
@@ -1109,9 +1092,9 @@ int TypeOf1401(DEVICE_EXTENSION * pdx)
 		break;
 	default:
 		if ((pdx->s1401Type >= TYPEPOWER) && (pdx->s1401Type <= 25))
-			iReturn = pdx->s1401Type + 4;	// We can calculate types
-		else		//  for up-coming 1401 designs
-			iReturn = TYPEUNKNOWN;	// Don't know or not there
+			iReturn = pdx->s1401Type + 4;	/*  We can calculate types */
+		else		/*   for up-coming 1401 designs */
+			iReturn = TYPEUNKNOWN;	/*  Don't know or not there */
 	}
 	dev_dbg(&pdx->interface->dev, "%s %d", __func__, iReturn);
 	mutex_unlock(&pdx->io_mutex);
@@ -1124,13 +1107,13 @@ int TypeOf1401(DEVICE_EXTENSION * pdx)
 **
 ** Returns flags on block transfer abilities
 ****************************************************************************/
-int TransferFlags(DEVICE_EXTENSION * pdx)
+int TransferFlags(DEVICE_EXTENSION *pdx)
 {
-	int iReturn = U14TF_MULTIA | U14TF_DIAG |	// we always have multiple DMA area
-	    U14TF_NOTIFY | U14TF_CIRCTH;	// diagnostics, notify and circular
+	int iReturn = U14TF_MULTIA | U14TF_DIAG |	/*  we always have multiple DMA area */
+	    U14TF_NOTIFY | U14TF_CIRCTH;	/*  diagnostics, notify and circular */
 	dev_dbg(&pdx->interface->dev, "%s", __func__);
 	mutex_lock(&pdx->io_mutex);
-	if (pdx->bIsUSB2)	// Set flag for USB2 if appropriate
+	if (pdx->bIsUSB2)	/*  Set flag for USB2 if appropriate */
 		iReturn |= U14TF_USB2;
 	mutex_unlock(&pdx->io_mutex);
 
@@ -1142,12 +1125,16 @@ int TransferFlags(DEVICE_EXTENSION * pdx
 ** Issues a debug\diagnostic command to the 1401 along with a 32-bit datum
 ** This is a utility command used for dbg operations.
 */
-static int DbgCmd1401(DEVICE_EXTENSION * pdx, unsigned char cmd,
+static int DbgCmd1401(DEVICE_EXTENSION *pdx, unsigned char cmd,
 		      unsigned int data)
 {
 	int iReturn;
 	dev_dbg(&pdx->interface->dev, "%s entry", __func__);
-	iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), cmd, (H_TO_D | VENDOR | DEVREQ), (unsigned short)data, (unsigned short)(data >> 16), 0, 0, HZ);	// allow 1 second timeout
+	iReturn = usb_control_msg(pdx->udev, usb_sndctrlpipe(pdx->udev, 0), cmd,
+				  (H_TO_D | VENDOR | DEVREQ),
+				  (unsigned short)data,
+				  (unsigned short)(data >> 16), NULL, 0, HZ);
+						/* allow 1 second timeout */
 	if (iReturn < 0)
 		dev_err(&pdx->interface->dev, "%s fail code=%d", __func__,
 			iReturn);
@@ -1160,7 +1147,7 @@ static int DbgCmd1401(DEVICE_EXTENSION *
 **
 ** Execute the diagnostic peek operation. Uses address, width and repeats.
 ****************************************************************************/
-int DbgPeek(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
+int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
 {
 	int iReturn;
 	TDBGBLOCK db;
@@ -1189,7 +1176,7 @@ int DbgPeek(DEVICE_EXTENSION * pdx, TDBG
 ** Execute the diagnostic poke operation. Parameters are in the CSBLOCK struct
 ** in order address, size, repeats and value to poke.
 ****************************************************************************/
-int DbgPoke(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
+int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
 {
 	int iReturn;
 	TDBGBLOCK db;
@@ -1218,7 +1205,7 @@ int DbgPoke(DEVICE_EXTENSION * pdx, TDBG
 ** Execute the diagnostic ramp data operation. Parameters are in the CSBLOCK struct
 ** in order address, default, enable mask, size and repeats.
 ****************************************************************************/
-int DbgRampData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
+int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
 {
 	int iReturn;
 	TDBGBLOCK db;
@@ -1250,7 +1237,7 @@ int DbgRampData(DEVICE_EXTENSION * pdx,
 **
 ** Execute the diagnostic ramp address operation
 ****************************************************************************/
-int DbgRampAddr(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
+int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
 {
 	int iReturn;
 	TDBGBLOCK db;
@@ -1280,16 +1267,16 @@ int DbgRampAddr(DEVICE_EXTENSION * pdx,
 **
 ** Retrieve the data resulting from the last debug Peek operation
 ****************************************************************************/
-int DbgGetData(DEVICE_EXTENSION * pdx, TDBGBLOCK __user * pDB)
+int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB)
 {
 	int iReturn;
 	TDBGBLOCK db;
-	memset(&db, 0, sizeof(db));	// fill returned block with 0s
+	memset(&db, 0, sizeof(db));	/*  fill returned block with 0s */
 
 	mutex_lock(&pdx->io_mutex);
 	dev_dbg(&pdx->interface->dev, "%s", __func__);
 
-	// Read back the last peeked value from the 1401.
+	/*  Read back the last peeked value from the 1401. */
 	iReturn = usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
 				  DB_DATA, (D_TO_H | VENDOR | DEVREQ), 0, 0,
 				  &db.iData, sizeof(db.iData), HZ);
@@ -1313,7 +1300,7 @@ int DbgGetData(DEVICE_EXTENSION * pdx, T
 ** Stop any never-ending debug loop, we just call Get1401State for USB
 **
 ****************************************************************************/
-int DbgStopLoop(DEVICE_EXTENSION * pdx)
+int DbgStopLoop(DEVICE_EXTENSION *pdx)
 {
 	int iReturn;
 	unsigned int uState, uErr;
@@ -1334,7 +1321,7 @@ int DbgStopLoop(DEVICE_EXTENSION * pdx)
 ** booked and a transfer to that area is in progress. Otherwise, we will
 ** release the area and re-assign it.
 ****************************************************************************/
-int SetCircular(DEVICE_EXTENSION * pdx, TRANSFERDESC __user * pTD)
+int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD)
 {
 	int iReturn;
 	bool bToHost;
@@ -1346,11 +1333,11 @@ int SetCircular(DEVICE_EXTENSION * pdx,
 	mutex_lock(&pdx->io_mutex);
 	dev_dbg(&pdx->interface->dev, "%s area:%d, size:%08x", __func__,
 		td.wAreaNum, td.dwLength);
-	bToHost = td.eSize != 0;	// this is used as the tohost flag
+	bToHost = td.eSize != 0;	/*  this is used as the tohost flag */
 
-	// The strange cast is done so that we don't get warnings in 32-bit linux about the size of the
-	// pointer. The pointer is always passed as a 64-bit object so that we don't have problems using
-	// a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system.
+	/*  The strange cast is done so that we don't get warnings in 32-bit linux about the size of the */
+	/*  pointer. The pointer is always passed as a 64-bit object so that we don't have problems using */
+	/*  a 32-bit program on a 64-bit system. unsigned long is 64-bits on a 64-bit system. */
 	iReturn =
 	    SetArea(pdx, td.wAreaNum,
 		    (char __user *)((unsigned long)td.lpvBuff), td.dwLength,
@@ -1364,7 +1351,7 @@ int SetCircular(DEVICE_EXTENSION * pdx,
 **
 ** Return the next available block of circularly-transferred data.
 ****************************************************************************/
-int GetCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB)
+int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
 {
 	int iReturn = U14ERR_NOERROR;
 	unsigned int nArea;
@@ -1377,20 +1364,17 @@ int GetCircBlock(DEVICE_EXTENSION * pdx,
 
 	mutex_lock(&pdx->io_mutex);
 
-	nArea = cb.nArea;	// Retrieve parameters first
-	cb.dwOffset = 0;	// set default result (nothing)
+	nArea = cb.nArea;	/*  Retrieve parameters first */
+	cb.dwOffset = 0;	/*  set default result (nothing) */
 	cb.dwSize = 0;
 
-	if (nArea < MAX_TRANSAREAS)	// The area number must be OK
-	{
-		TRANSAREA *pArea = &pdx->rTransDef[nArea];	// Pointer to relevant info
-		spin_lock_irq(&pdx->stagedLock);	// Lock others out
+	if (nArea < MAX_TRANSAREAS) {	/*  The area number must be OK */
+		TRANSAREA *pArea = &pdx->rTransDef[nArea];	/*  Pointer to relevant info */
+		spin_lock_irq(&pdx->stagedLock);	/*  Lock others out */
 
-		if ((pArea->bUsed) && (pArea->bCircular) &&	// Must be circular area
-		    (pArea->bCircToHost))	// For now at least must be to host
-		{
-			if (pArea->aBlocks[0].dwSize > 0)	// Got anything?
-			{
+		if ((pArea->bUsed) && (pArea->bCircular) &&	/*  Must be circular area */
+		    (pArea->bCircToHost)) {	/*  For now at least must be to host */
+			if (pArea->aBlocks[0].dwSize > 0) {	/*  Got anything? */
 				cb.dwOffset = pArea->aBlocks[0].dwOffset;
 				cb.dwSize = pArea->aBlocks[0].dwSize;
 				dev_dbg(&pdx->interface->dev,
@@ -1416,7 +1400,7 @@ int GetCircBlock(DEVICE_EXTENSION * pdx,
 **
 ** Frees a block of circularly-transferred data and returns the next one.
 ****************************************************************************/
-int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB)
+int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB)
 {
 	int iReturn = U14ERR_NOERROR;
 	unsigned int nArea, uStart, uSize;
@@ -1429,33 +1413,28 @@ int FreeCircBlock(DEVICE_EXTENSION * pdx
 
 	mutex_lock(&pdx->io_mutex);
 
-	nArea = cb.nArea;	// Retrieve parameters first
+	nArea = cb.nArea;	/*  Retrieve parameters first */
 	uStart = cb.dwOffset;
 	uSize = cb.dwSize;
-	cb.dwOffset = 0;	// then set default result (nothing)
+	cb.dwOffset = 0;	/*  then set default result (nothing) */
 	cb.dwSize = 0;
 
-	if (nArea < MAX_TRANSAREAS)	// The area number must be OK
-	{
-		TRANSAREA *pArea = &pdx->rTransDef[nArea];	// Pointer to relevant info
-		spin_lock_irq(&pdx->stagedLock);	// Lock others out
+	if (nArea < MAX_TRANSAREAS) {	/*  The area number must be OK */
+		TRANSAREA *pArea = &pdx->rTransDef[nArea];	/*  Pointer to relevant info */
+		spin_lock_irq(&pdx->stagedLock);	/*  Lock others out */
 
-		if ((pArea->bUsed) && (pArea->bCircular) &&	// Must be circular area
-		    (pArea->bCircToHost))	// For now at least must be to host
-		{
+		if ((pArea->bUsed) && (pArea->bCircular) &&	/*  Must be circular area */
+		    (pArea->bCircToHost)) {	/*  For now at least must be to host */
 			bool bWaiting = false;
 
-			if ((pArea->aBlocks[0].dwSize >= uSize) &&	// Got anything?
-			    (pArea->aBlocks[0].dwOffset == uStart))	// Must be legal data
-			{
+			if ((pArea->aBlocks[0].dwSize >= uSize) &&	/*  Got anything? */
+			    (pArea->aBlocks[0].dwOffset == uStart)) {	/*  Must be legal data */
 				pArea->aBlocks[0].dwSize -= uSize;
 				pArea->aBlocks[0].dwOffset += uSize;
-				if (pArea->aBlocks[0].dwSize == 0)	// Have we emptied this block?
-				{
-					if (pArea->aBlocks[1].dwSize)	// Is there a second block?
-					{
-						pArea->aBlocks[0] = pArea->aBlocks[1];	// Copy down block 2 data
-						pArea->aBlocks[1].dwSize = 0;	// and mark the second block as unused
+				if (pArea->aBlocks[0].dwSize == 0) {	/*  Have we emptied this block? */
+					if (pArea->aBlocks[1].dwSize) {	/*  Is there a second block? */
+						pArea->aBlocks[0] = pArea->aBlocks[1];	/*  Copy down block 2 data */
+						pArea->aBlocks[1].dwSize = 0;	/*  and mark the second block as unused */
 						pArea->aBlocks[1].dwOffset = 0;
 					} else
 						pArea->aBlocks[0].dwOffset = 0;
@@ -1468,9 +1447,8 @@ int FreeCircBlock(DEVICE_EXTENSION * pdx
 					pArea->aBlocks[0].dwOffset,
 					pdx->bXFerWaiting);
 
-				// Return the next available block of memory as well
-				if (pArea->aBlocks[0].dwSize > 0)	// Got anything?
-				{
+				/*  Return the next available block of memory as well */
+				if (pArea->aBlocks[0].dwSize > 0) {	/*  Got anything? */
 					cb.dwOffset =
 					    pArea->aBlocks[0].dwOffset;
 					cb.dwSize = pArea->aBlocks[0].dwSize;
@@ -1492,9 +1470,8 @@ int FreeCircBlock(DEVICE_EXTENSION * pdx
 				iReturn = U14ERR_NOMEMORY;
 			}
 
-			// If we have one, kick off pending transfer
-			if (bWaiting)	// Got a block xfer waiting?
-			{
+			/*  If we have one, kick off pending transfer */
+			if (bWaiting) {	/*  Got a block xfer waiting? */
 				int RWMStat =
 				    ReadWriteMem(pdx, !pdx->rDMAInfo.bOutWard,
 						 pdx->rDMAInfo.wIdent,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ced1401/ced_ioctl.h linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/ced_ioctl.h
--- linux-libre-3.10-gnu/drivers/staging/ced1401/ced_ioctl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/ced_ioctl.h	2013-08-25 20:43:22.000000000 -0400
@@ -35,7 +35,7 @@ typedef struct TransferDesc {
 	short eSize;		/* element size - is tohost flag for circular */
 } TRANSFERDESC;
 
-typedef TRANSFERDESC * LPTRANSFERDESC;
+typedef TRANSFERDESC *LPTRANSFERDESC;
 
 typedef struct TransferEvent {
 	unsigned int dwStart;		/* offset into the area */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ced1401/machine.h linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/machine.h
--- linux-libre-3.10-gnu/drivers/staging/ced1401/machine.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/machine.h	2013-08-25 20:43:22.000000000 -0400
@@ -77,20 +77,13 @@
 #endif
 
 #if defined(LINUX) || defined(MAXOSX)
-    #define FAR
+	#define FAR
 
-    typedef int BOOL;       // To match Windows
-    typedef char * LPSTR;
-    typedef const char * LPCSTR;
-    typedef unsigned short WORD;
-    typedef unsigned int  DWORD;
-    typedef unsigned char  BYTE;
-    typedef BYTE  BOOLEAN;
-    typedef unsigned char UCHAR;
-    #define __packed __attribute__((packed))
-    typedef BYTE * LPBYTE;
-    #define HIWORD(x) (WORD)(((x)>>16) & 0xffff)
-    #define LOWORD(x) (WORD)((x) & 0xffff)
+	typedef int BOOL;       /*  To match Windows */
+	typedef unsigned char  BYTE;
+	#define __packed __attribute__((packed))
+	#define HIWORD(x) (unsigned short)(((x)>>16) & 0xffff)
+	#define LOWORD(x) (unsigned short)((x) & 0xffff)
 #endif
 
 #ifdef _IS_WINDOWS_
@@ -104,21 +97,20 @@
 ** a synonym.
 */
 #ifdef GNUC
-    #define DllExport __attribute__((dllexport))
-    #define DllImport __attribute__((dllimport))
+	#define DllExport __attribute__((dllexport))
+	#define DllImport __attribute__((dllimport))
 #endif
 
 #ifndef DllExport
 #ifdef _IS_WINDOWS_
-    #define DllExport __declspec(dllexport)
-    #define DllImport __declspec(dllimport)
+	#define DllExport __declspec(dllexport)
+	#define DllImport __declspec(dllimport)
 #else
-    #define DllExport
-    #define DllImport
+	#define DllExport
+	#define DllImport
 #endif
 #endif /* _IS_WINDOWS_ */
 
-    
 #ifndef TRUE
    #define TRUE 1
    #define FALSE 0
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ced1401/usb1401.c linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/usb1401.c
--- linux-libre-3.10-gnu/drivers/staging/ced1401/usb1401.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/usb1401.c	2013-08-25 20:43:22.000000000 -0400
@@ -126,18 +126,18 @@ static void ced_delete(struct kref *kref
 {
 	DEVICE_EXTENSION *pdx = to_DEVICE_EXTENSION(kref);
 
-	// Free up the output buffer, then free the output urb. Note that the interface member
-	// of pdx will probably be NULL, so cannot be used to get to dev.
+	/*  Free up the output buffer, then free the output urb. Note that the interface member */
+	/*  of pdx will probably be NULL, so cannot be used to get to dev. */
 	usb_free_coherent(pdx->udev, OUTBUF_SZ, pdx->pCoherCharOut,
 			  pdx->pUrbCharOut->transfer_dma);
 	usb_free_urb(pdx->pUrbCharOut);
 
-	// Do the same for chan input
+	/*  Do the same for chan input */
 	usb_free_coherent(pdx->udev, INBUF_SZ, pdx->pCoherCharIn,
 			  pdx->pUrbCharIn->transfer_dma);
 	usb_free_urb(pdx->pUrbCharIn);
 
-	// Do the same for the block transfers
+	/*  Do the same for the block transfers */
 	usb_free_coherent(pdx->udev, STAGED_SZ, pdx->pCoherStagedIO,
 			  pdx->pStagedUrb->transfer_dma);
 	usb_free_urb(pdx->pStagedUrb);
@@ -146,7 +146,7 @@ static void ced_delete(struct kref *kref
 	kfree(pdx);
 }
 
-// This is the driver end of the open() call from user space.
+/*  This is the driver end of the open() call from user space. */
 static int ced_open(struct inode *inode, struct file *file)
 {
 	DEVICE_EXTENSION *pdx;
@@ -184,7 +184,7 @@ static int ced_open(struct inode *inode,
 			kref_put(&pdx->kref, ced_delete);
 			goto exit;
 		}
-	} else {		//uncomment this block if you want exclusive open
+	} else {		/* uncomment this block if you want exclusive open */
 		dev_err(&interface->dev, "%s fail: already open", __func__);
 		retval = -EBUSY;
 		pdx->open_count--;
@@ -210,11 +210,11 @@ static int ced_release(struct inode *ino
 
 	dev_dbg(&pdx->interface->dev, "%s called", __func__);
 	mutex_lock(&pdx->io_mutex);
-	if (!--pdx->open_count && pdx->interface)	// Allow autosuspend
+	if (!--pdx->open_count && pdx->interface)	/*  Allow autosuspend */
 		usb_autopm_put_interface(pdx->interface);
 	mutex_unlock(&pdx->io_mutex);
 
-	kref_put(&pdx->kref, ced_delete);	// decrement the count on our device
+	kref_put(&pdx->kref, ced_delete);	/*  decrement the count on our device */
 	return 0;
 }
 
@@ -252,9 +252,9 @@ static int ced_flush(struct file *file,
 ** not help with a device extension held by a file.
 ** return true if can accept new io requests, else false
 */
-static bool CanAcceptIoRequests(DEVICE_EXTENSION * pdx)
+static bool CanAcceptIoRequests(DEVICE_EXTENSION *pdx)
 {
-	return pdx && pdx->interface;	// Can we accept IO requests
+	return pdx && pdx->interface;	/*  Can we accept IO requests */
 }
 
 /****************************************************************************
@@ -264,9 +264,9 @@ static bool CanAcceptIoRequests(DEVICE_E
 static void ced_writechar_callback(struct urb *pUrb)
 {
 	DEVICE_EXTENSION *pdx = pUrb->context;
-	int nGot = pUrb->actual_length;	// what we transferred
+	int nGot = pUrb->actual_length;	/*  what we transferred */
 
-	if (pUrb->status) {	// sync/async unlink faults aren't errors
+	if (pUrb->status) {	/*  sync/async unlink faults aren't errors */
 		if (!
 		    (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
 		     || pUrb->status == -ESHUTDOWN)) {
@@ -278,36 +278,35 @@ static void ced_writechar_callback(struc
 		spin_lock(&pdx->err_lock);
 		pdx->errors = pUrb->status;
 		spin_unlock(&pdx->err_lock);
-		nGot = 0;	//  and tidy up again if so
+		nGot = 0;	/*   and tidy up again if so */
 
-		spin_lock(&pdx->charOutLock);	// already at irq level
-		pdx->dwOutBuffGet = 0;	// Reset the output buffer
+		spin_lock(&pdx->charOutLock);	/*  already at irq level */
+		pdx->dwOutBuffGet = 0;	/*  Reset the output buffer */
 		pdx->dwOutBuffPut = 0;
-		pdx->dwNumOutput = 0;	// Clear the char count
-		pdx->bPipeError[0] = 1;	// Flag an error for later
-		pdx->bSendCharsPending = false;	// Allow other threads again
-		spin_unlock(&pdx->charOutLock);	// already at irq level
+		pdx->dwNumOutput = 0;	/*  Clear the char count */
+		pdx->bPipeError[0] = 1;	/*  Flag an error for later */
+		pdx->bSendCharsPending = false;	/*  Allow other threads again */
+		spin_unlock(&pdx->charOutLock);	/*  already at irq level */
 		dev_dbg(&pdx->interface->dev,
 			"%s - char out done, 0 chars sent", __func__);
 	} else {
 		dev_dbg(&pdx->interface->dev,
 			"%s - char out done, %d chars sent", __func__, nGot);
-		spin_lock(&pdx->charOutLock);	// already at irq level
-		pdx->dwNumOutput -= nGot;	// Now adjust the char send buffer
-		pdx->dwOutBuffGet += nGot;	// to match what we did
-		if (pdx->dwOutBuffGet >= OUTBUF_SZ)	// Can't do this any earlier as data could be overwritten
+		spin_lock(&pdx->charOutLock);	/*  already at irq level */
+		pdx->dwNumOutput -= nGot;	/*  Now adjust the char send buffer */
+		pdx->dwOutBuffGet += nGot;	/*  to match what we did */
+		if (pdx->dwOutBuffGet >= OUTBUF_SZ)	/*  Can't do this any earlier as data could be overwritten */
 			pdx->dwOutBuffGet = 0;
 
-		if (pdx->dwNumOutput > 0)	// if more to be done...
-		{
-			int nPipe = 0;	// The pipe number to use
+		if (pdx->dwNumOutput > 0) {	/*  if more to be done... */
+			int nPipe = 0;	/*  The pipe number to use */
 			int iReturn;
 			char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet];
-			unsigned int dwCount = pdx->dwNumOutput;	// maximum to send
-			if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ)	// does it cross buffer end?
+			unsigned int dwCount = pdx->dwNumOutput;	/*  maximum to send */
+			if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ)	/*  does it cross buffer end? */
 				dwCount = OUTBUF_SZ - pdx->dwOutBuffGet;
-			spin_unlock(&pdx->charOutLock);	// we are done with stuff that changes
-			memcpy(pdx->pCoherCharOut, pDat, dwCount);	// copy output data to the buffer
+			spin_unlock(&pdx->charOutLock);	/*  we are done with stuff that changes */
+			memcpy(pdx->pCoherCharOut, pDat, dwCount);	/*  copy output data to the buffer */
 			usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev,
 					  usb_sndbulkpipe(pdx->udev,
 							  pdx->epAddr[0]),
@@ -315,22 +314,22 @@ static void ced_writechar_callback(struc
 					  ced_writechar_callback, pdx);
 			pdx->pUrbCharOut->transfer_flags |=
 			    URB_NO_TRANSFER_DMA_MAP;
-			usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted);	// in case we need to kill it
+			usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted);	/*  in case we need to kill it */
 			iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_ATOMIC);
 			dev_dbg(&pdx->interface->dev, "%s n=%d>%s<", __func__,
 				dwCount, pDat);
-			spin_lock(&pdx->charOutLock);	// grab lock for errors
+			spin_lock(&pdx->charOutLock);	/*  grab lock for errors */
 			if (iReturn) {
-				pdx->bPipeError[nPipe] = 1;	// Flag an error to be handled later
-				pdx->bSendCharsPending = false;	// Allow other threads again
+				pdx->bPipeError[nPipe] = 1;	/*  Flag an error to be handled later */
+				pdx->bSendCharsPending = false;	/*  Allow other threads again */
 				usb_unanchor_urb(pdx->pUrbCharOut);
 				dev_err(&pdx->interface->dev,
 					"%s usb_submit_urb() returned %d",
 					__func__, iReturn);
 			}
 		} else
-			pdx->bSendCharsPending = false;	// Allow other threads again
-		spin_unlock(&pdx->charOutLock);	// already at irq level
+			pdx->bSendCharsPending = false;	/*  Allow other threads again */
+		spin_unlock(&pdx->charOutLock);	/*  already at irq level */
 	}
 }
 
@@ -339,44 +338,43 @@ static void ced_writechar_callback(struc
 ** Transmit the characters in the output buffer to the 1401. This may need
 ** breaking down into multiple transfers.
 ****************************************************************************/
-int SendChars(DEVICE_EXTENSION * pdx)
+int SendChars(DEVICE_EXTENSION *pdx)
 {
 	int iReturn = U14ERR_NOERROR;
 
-	spin_lock_irq(&pdx->charOutLock);	// Protect ourselves
+	spin_lock_irq(&pdx->charOutLock);	/*  Protect ourselves */
 
-	if ((!pdx->bSendCharsPending) &&	// Not currently sending
-	    (pdx->dwNumOutput > 0) &&	//  has characters to output
-	    (CanAcceptIoRequests(pdx)))	//  and current activity is OK
-	{
-		unsigned int dwCount = pdx->dwNumOutput;	// Get a copy of the character count
-		pdx->bSendCharsPending = true;	// Set flag to lock out other threads
+	if ((!pdx->bSendCharsPending) &&	/*  Not currently sending */
+	    (pdx->dwNumOutput > 0) &&	/*   has characters to output */
+	    (CanAcceptIoRequests(pdx)))	{ /*   and current activity is OK */
+		unsigned int dwCount = pdx->dwNumOutput;	/*  Get a copy of the character count */
+		pdx->bSendCharsPending = true;	/*  Set flag to lock out other threads */
 
 		dev_dbg(&pdx->interface->dev,
 			"Send %d chars to 1401, EP0 flag %d\n", dwCount,
 			pdx->nPipes == 3);
-		// If we have only 3 end points we must send the characters to the 1401 using EP0.
+		/*  If we have only 3 end points we must send the characters to the 1401 using EP0. */
 		if (pdx->nPipes == 3) {
-			// For EP0 character transmissions to the 1401, we have to hang about until they
-			// are gone, as otherwise without more character IO activity they will never go.
-			unsigned int count = dwCount;	// Local char counter
-			unsigned int index = 0;	// The index into the char buffer
+			/*  For EP0 character transmissions to the 1401, we have to hang about until they */
+			/*  are gone, as otherwise without more character IO activity they will never go. */
+			unsigned int count = dwCount;	/*  Local char counter */
+			unsigned int index = 0;	/*  The index into the char buffer */
 
-			spin_unlock_irq(&pdx->charOutLock);	// Free spinlock as we call USBD
+			spin_unlock_irq(&pdx->charOutLock);	/*  Free spinlock as we call USBD */
 
 			while ((count > 0) && (iReturn == U14ERR_NOERROR)) {
-				// We have to break the transfer up into 64-byte chunks because of a 2270 problem
-				int n = count > 64 ? 64 : count;	// Chars for this xfer, max of 64
+				/*  We have to break the transfer up into 64-byte chunks because of a 2270 problem */
+				int n = count > 64 ? 64 : count;	/*  Chars for this xfer, max of 64 */
 				int nSent = usb_control_msg(pdx->udev,
-							    usb_sndctrlpipe(pdx->udev, 0),	// use end point 0
-							    DB_CHARS,	// bRequest
-							    (H_TO_D | VENDOR | DEVREQ),	// to the device, vendor request to the device
-							    0, 0,	// value and index are both 0
-							    &pdx->outputBuffer[index],	// where to send from
-							    n,	// how much to send
-							    1000);	// timeout in jiffies
+							    usb_sndctrlpipe(pdx->udev, 0),	/*  use end point 0 */
+							    DB_CHARS,	/*  bRequest */
+							    (H_TO_D | VENDOR | DEVREQ),	/*  to the device, vendor request to the device */
+							    0, 0,	/*  value and index are both 0 */
+							    &pdx->outputBuffer[index],	/*  where to send from */
+							    n,	/*  how much to send */
+							    1000);	/*  timeout in jiffies */
 				if (nSent <= 0) {
-					iReturn = nSent ? nSent : -ETIMEDOUT;	// if 0 chars says we timed out
+					iReturn = nSent ? nSent : -ETIMEDOUT;	/*  if 0 chars says we timed out */
 					dev_err(&pdx->interface->dev,
 						"Send %d chars by EP0 failed: %d",
 						n, iReturn);
@@ -388,19 +386,19 @@ int SendChars(DEVICE_EXTENSION * pdx)
 				}
 			}
 
-			spin_lock_irq(&pdx->charOutLock);	// Protect pdx changes, released by general code
-			pdx->dwOutBuffGet = 0;	// so reset the output buffer
+			spin_lock_irq(&pdx->charOutLock);	/*  Protect pdx changes, released by general code */
+			pdx->dwOutBuffGet = 0;	/*  so reset the output buffer */
 			pdx->dwOutBuffPut = 0;
-			pdx->dwNumOutput = 0;	// and clear the buffer count
-			pdx->bSendCharsPending = false;	// Allow other threads again
-		} else {	// Here for sending chars normally - we hold the spin lock
-			int nPipe = 0;	// The pipe number to use
+			pdx->dwNumOutput = 0;	/*  and clear the buffer count */
+			pdx->bSendCharsPending = false;	/*  Allow other threads again */
+		} else {	/*  Here for sending chars normally - we hold the spin lock */
+			int nPipe = 0;	/*  The pipe number to use */
 			char *pDat = &pdx->outputBuffer[pdx->dwOutBuffGet];
 
-			if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ)	// does it cross buffer end?
+			if ((pdx->dwOutBuffGet + dwCount) > OUTBUF_SZ)	/*  does it cross buffer end? */
 				dwCount = OUTBUF_SZ - pdx->dwOutBuffGet;
-			spin_unlock_irq(&pdx->charOutLock);	// we are done with stuff that changes
-			memcpy(pdx->pCoherCharOut, pDat, dwCount);	// copy output data to the buffer
+			spin_unlock_irq(&pdx->charOutLock);	/*  we are done with stuff that changes */
+			memcpy(pdx->pCoherCharOut, pDat, dwCount);	/*  copy output data to the buffer */
 			usb_fill_bulk_urb(pdx->pUrbCharOut, pdx->udev,
 					  usb_sndbulkpipe(pdx->udev,
 							  pdx->epAddr[0]),
@@ -410,11 +408,11 @@ int SendChars(DEVICE_EXTENSION * pdx)
 			    URB_NO_TRANSFER_DMA_MAP;
 			usb_anchor_urb(pdx->pUrbCharOut, &pdx->submitted);
 			iReturn = usb_submit_urb(pdx->pUrbCharOut, GFP_KERNEL);
-			spin_lock_irq(&pdx->charOutLock);	// grab lock for errors
+			spin_lock_irq(&pdx->charOutLock);	/*  grab lock for errors */
 			if (iReturn) {
-				pdx->bPipeError[nPipe] = 1;	// Flag an error to be handled later
-				pdx->bSendCharsPending = false;	// Allow other threads again
-				usb_unanchor_urb(pdx->pUrbCharOut);	// remove from list of active urbs
+				pdx->bPipeError[nPipe] = 1;	/*  Flag an error to be handled later */
+				pdx->bSendCharsPending = false;	/*  Allow other threads again */
+				usb_unanchor_urb(pdx->pUrbCharOut);	/*  remove from list of active urbs */
 			}
 		}
 	} else if (pdx->bSendCharsPending && (pdx->dwNumOutput > 0))
@@ -422,7 +420,7 @@ int SendChars(DEVICE_EXTENSION * pdx)
 			"SendChars bSendCharsPending:true");
 
 	dev_dbg(&pdx->interface->dev, "SendChars exit code: %d", iReturn);
-	spin_unlock_irq(&pdx->charOutLock);	// Now let go of the spinlock
+	spin_unlock_irq(&pdx->charOutLock);	/*  Now let go of the spinlock */
 	return iReturn;
 }
 
@@ -440,14 +438,14 @@ int SendChars(DEVICE_EXTENSION * pdx)
 ** pdx  Is our device extension which holds all we know about the transfer.
 ** n    The number of bytes to move one way or the other.
 ***************************************************************************/
-static void CopyUserSpace(DEVICE_EXTENSION * pdx, int n)
+static void CopyUserSpace(DEVICE_EXTENSION *pdx, int n)
 {
 	unsigned int nArea = pdx->StagedId;
 	if (nArea < MAX_TRANSAREAS) {
-		TRANSAREA *pArea = &pdx->rTransDef[nArea];	// area to be used
+		TRANSAREA *pArea = &pdx->rTransDef[nArea];	/*  area to be used */
 		unsigned int dwOffset =
 		    pdx->StagedDone + pdx->StagedOffset + pArea->dwBaseOffset;
-		char *pCoherBuf = pdx->pCoherStagedIO;	// coherent buffer
+		char *pCoherBuf = pdx->pCoherStagedIO;	/*  coherent buffer */
 		if (!pArea->bUsed) {
 			dev_err(&pdx->interface->dev, "%s area %d unused",
 				__func__, nArea);
@@ -455,15 +453,15 @@ static void CopyUserSpace(DEVICE_EXTENSI
 		}
 
 		while (n) {
-			int nPage = dwOffset >> PAGE_SHIFT;	// page number in table
+			int nPage = dwOffset >> PAGE_SHIFT;	/*  page number in table */
 			if (nPage < pArea->nPages) {
 				char *pvAddress =
 				    (char *)kmap_atomic(pArea->pPages[nPage]);
 				if (pvAddress) {
-					unsigned int uiPageOff = dwOffset & (PAGE_SIZE - 1);	// offset into the page
-					size_t uiXfer = PAGE_SIZE - uiPageOff;	// max to transfer on this page
-					if (uiXfer > n)	// limit byte count if too much
-						uiXfer = n;	// for the page
+					unsigned int uiPageOff = dwOffset & (PAGE_SIZE - 1);	/*  offset into the page */
+					size_t uiXfer = PAGE_SIZE - uiPageOff;	/*  max to transfer on this page */
+					if (uiXfer > n)	/*  limit byte count if too much */
+						uiXfer = n;	/*  for the page */
 					if (pdx->StagedRead)
 						memcpy(pvAddress + uiPageOff,
 						       pCoherBuf, uiXfer);
@@ -494,8 +492,8 @@ static void CopyUserSpace(DEVICE_EXTENSI
 			nArea);
 }
 
-// Forward declarations for stuff used circularly
-static int StageChunk(DEVICE_EXTENSION * pdx);
+/*  Forward declarations for stuff used circularly */
+static int StageChunk(DEVICE_EXTENSION *pdx);
 /***************************************************************************
 ** ReadWrite_Complete
 **
@@ -504,14 +502,14 @@ static int StageChunk(DEVICE_EXTENSION *
 static void staged_callback(struct urb *pUrb)
 {
 	DEVICE_EXTENSION *pdx = pUrb->context;
-	unsigned int nGot = pUrb->actual_length;	// what we transferred
+	unsigned int nGot = pUrb->actual_length;	/*  what we transferred */
 	bool bCancel = false;
-	bool bRestartCharInput;	// used at the end
+	bool bRestartCharInput;	/*  used at the end */
 
-	spin_lock(&pdx->stagedLock);	// stop ReadWriteMem() action while this routine is running
-	pdx->bStagedUrbPending = false;	// clear the flag for staged IRP pending
+	spin_lock(&pdx->stagedLock);	/*  stop ReadWriteMem() action while this routine is running */
+	pdx->bStagedUrbPending = false;	/*  clear the flag for staged IRP pending */
 
-	if (pUrb->status) {	// sync/async unlink faults aren't errors
+	if (pUrb->status) {	/*  sync/async unlink faults aren't errors */
 		if (!
 		    (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
 		     || pUrb->status == -ESHUTDOWN)) {
@@ -525,40 +523,37 @@ static void staged_callback(struct urb *
 		spin_lock(&pdx->err_lock);
 		pdx->errors = pUrb->status;
 		spin_unlock(&pdx->err_lock);
-		nGot = 0;	//  and tidy up again if so
+		nGot = 0;	/*   and tidy up again if so */
 		bCancel = true;
 	} else {
 		dev_dbg(&pdx->interface->dev, "%s %d chars xferred", __func__,
 			nGot);
-		if (pdx->StagedRead)	// if reading, save to user space
-			CopyUserSpace(pdx, nGot);	// copy from buffer to user
+		if (pdx->StagedRead)	/*  if reading, save to user space */
+			CopyUserSpace(pdx, nGot);	/*  copy from buffer to user */
 		if (nGot == 0)
 			dev_dbg(&pdx->interface->dev, "%s ZLP", __func__);
 	}
 
-	// Update the transfer length based on the TransferBufferLength value in the URB
+	/*  Update the transfer length based on the TransferBufferLength value in the URB */
 	pdx->StagedDone += nGot;
 
 	dev_dbg(&pdx->interface->dev, "%s, done %d bytes of %d", __func__,
 		pdx->StagedDone, pdx->StagedLength);
 
-	if ((pdx->StagedDone == pdx->StagedLength) ||	// If no more to do
-	    (bCancel))		// or this IRP was cancelled
-	{
-		TRANSAREA *pArea = &pdx->rTransDef[pdx->StagedId];	// Transfer area info
+	if ((pdx->StagedDone == pdx->StagedLength) ||	/*  If no more to do */
+	    (bCancel)) {		/*  or this IRP was cancelled */
+		TRANSAREA *pArea = &pdx->rTransDef[pdx->StagedId];	/*  Transfer area info */
 		dev_dbg(&pdx->interface->dev,
 			"%s transfer done, bytes %d, cancel %d", __func__,
 			pdx->StagedDone, bCancel);
 
-		// Here is where we sort out what to do with this transfer if using a circular buffer. We have
-		//  a completed transfer that can be assumed to fit into the transfer area. We should be able to
-		//  add this to the end of a growing block or to use it to start a new block unless the code
-		//  that calculates the offset to use (in ReadWriteMem) is totally duff.
-		if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) &&	// Time to sort out circular buffer info?
-		    (pdx->StagedRead))	// Only for tohost transfers for now
-		{
-			if (pArea->aBlocks[1].dwSize > 0)	// If block 1 is in use we must append to it
-			{
+		/*  Here is where we sort out what to do with this transfer if using a circular buffer. We have */
+		/*   a completed transfer that can be assumed to fit into the transfer area. We should be able to */
+		/*   add this to the end of a growing block or to use it to start a new block unless the code */
+		/*   that calculates the offset to use (in ReadWriteMem) is totally duff. */
+		if ((pArea->bCircular) && (pArea->bCircToHost) && (!bCancel) &&	/*  Time to sort out circular buffer info? */
+		    (pdx->StagedRead)) {	/*  Only for tohost transfers for now */
+			if (pArea->aBlocks[1].dwSize > 0) {	/*  If block 1 is in use we must append to it */
 				if (pdx->StagedOffset ==
 				    (pArea->aBlocks[1].dwOffset +
 				     pArea->aBlocks[1].dwSize)) {
@@ -569,7 +564,7 @@ static void staged_callback(struct urb *
 						pArea->aBlocks[1].dwSize,
 						pArea->aBlocks[1].dwOffset);
 				} else {
-					// Here things have gone very, very, wrong, but I cannot see how this can actually be achieved
+					/*  Here things have gone very, very, wrong, but I cannot see how this can actually be achieved */
 					pArea->aBlocks[1].dwOffset =
 					    pdx->StagedOffset;
 					pArea->aBlocks[1].dwSize =
@@ -580,22 +575,20 @@ static void staged_callback(struct urb *
 						pArea->aBlocks[1].dwSize,
 						pArea->aBlocks[1].dwOffset);
 				}
-			} else	// If block 1 is not used, we try to add to block 0
-			{
-				if (pArea->aBlocks[0].dwSize > 0)	// Got stored block 0 information?
-				{	// Must append onto the existing block 0
+			} else {	/*  If block 1 is not used, we try to add to block 0 */
+				if (pArea->aBlocks[0].dwSize > 0) {	/*  Got stored block 0 information? */
+					/*  Must append onto the existing block 0 */
 					if (pdx->StagedOffset ==
 					    (pArea->aBlocks[0].dwOffset +
 					     pArea->aBlocks[0].dwSize)) {
-						pArea->aBlocks[0].dwSize += pdx->StagedLength;	// Just add this transfer in
+						pArea->aBlocks[0].dwSize += pdx->StagedLength;	/*  Just add this transfer in */
 						dev_dbg(&pdx->interface->dev,
 							"RWM_Complete, circ block 0 now %d bytes at %d",
 							pArea->aBlocks[0].
 							dwSize,
 							pArea->aBlocks[0].
 							dwOffset);
-					} else	// If it doesn't append, put into new block 1
-					{
+					} else {	/*  If it doesn't append, put into new block 1 */
 						pArea->aBlocks[1].dwOffset =
 						    pdx->StagedOffset;
 						pArea->aBlocks[1].dwSize =
@@ -607,8 +600,7 @@ static void staged_callback(struct urb *
 							pArea->aBlocks[1].
 							dwOffset);
 					}
-				} else	// No info stored yet, just save in block 0
-				{
+				} else	{ /*  No info stored yet, just save in block 0 */
 					pArea->aBlocks[0].dwOffset =
 					    pdx->StagedOffset;
 					pArea->aBlocks[0].dwSize =
@@ -621,21 +613,19 @@ static void staged_callback(struct urb *
 			}
 		}
 
-		if (!bCancel)	// Don't generate an event if cancelled
-		{
+		if (!bCancel) { /*  Don't generate an event if cancelled */
 			dev_dbg(&pdx->interface->dev,
 				"RWM_Complete,  bCircular %d, bToHost %d, eStart %d, eSize %d",
 				pArea->bCircular, pArea->bEventToHost,
 				pArea->dwEventSt, pArea->dwEventSz);
-			if ((pArea->dwEventSz) &&	// Set a user-mode event...
-			    (pdx->StagedRead == pArea->bEventToHost))	// ...on transfers in this direction?
-			{
-				int iWakeUp = 0;	// assume
-				// If we have completed the right sort of DMA transfer then set the event to notify
-				//   the user code to wake up anyone that is waiting.
-				if ((pArea->bCircular) &&	// Circular areas use a simpler test
-				    (pArea->bCircToHost))	// only in supported direction
-				{	// Is total data waiting up to size limit?
+			if ((pArea->dwEventSz) &&	/*  Set a user-mode event... */
+			    (pdx->StagedRead == pArea->bEventToHost)) {	/*  ...on transfers in this direction? */
+				int iWakeUp = 0;	/*  assume */
+				/*  If we have completed the right sort of DMA transfer then set the event to notify */
+				/*    the user code to wake up anyone that is waiting. */
+				if ((pArea->bCircular) &&	/*  Circular areas use a simpler test */
+				    (pArea->bCircToHost)) {	/*  only in supported direction */
+					/*  Is total data waiting up to size limit? */
 					unsigned int dwTotal =
 					    pArea->aBlocks[0].dwSize +
 					    pArea->aBlocks[1].dwSize;
@@ -653,19 +643,17 @@ static void staged_callback(struct urb *
 				if (iWakeUp) {
 					dev_dbg(&pdx->interface->dev,
 						"About to set event to notify app");
-					wake_up_interruptible(&pArea->wqEvent);	// wake up waiting processes
-					++pArea->iWakeUp;	// increment wakeup count
+					wake_up_interruptible(&pArea->wqEvent);	/*  wake up waiting processes */
+					++pArea->iWakeUp;	/*  increment wakeup count */
 				}
 			}
 		}
 
-		pdx->dwDMAFlag = MODE_CHAR;	// Switch back to char mode before ReadWriteMem call
+		pdx->dwDMAFlag = MODE_CHAR;	/*  Switch back to char mode before ReadWriteMem call */
 
-		if (!bCancel)	// Don't look for waiting transfer if cancelled
-		{
-			// If we have a transfer waiting, kick it off
-			if (pdx->bXFerWaiting)	// Got a block xfer waiting?
-			{
+		if (!bCancel) {	/*  Don't look for waiting transfer if cancelled */
+			/*  If we have a transfer waiting, kick it off */
+			if (pdx->bXFerWaiting) {	/*  Got a block xfer waiting? */
 				int iReturn;
 				dev_info(&pdx->interface->dev,
 					 "*** RWM_Complete *** pending transfer will now be set up!!!");
@@ -682,22 +670,22 @@ static void staged_callback(struct urb *
 			}
 		}
 
-	} else			// Here for more to do
-		StageChunk(pdx);	// fire off the next bit
+	} else			/*  Here for more to do */
+		StageChunk(pdx);	/*  fire off the next bit */
 
-	// While we hold the stagedLock, see if we should reallow character input ints
-	// Don't allow if cancelled, or if a new block has started or if there is a waiting block.
-	// This feels wrong as we should ask which spin lock protects dwDMAFlag.
+	/*  While we hold the stagedLock, see if we should reallow character input ints */
+	/*  Don't allow if cancelled, or if a new block has started or if there is a waiting block. */
+	/*  This feels wrong as we should ask which spin lock protects dwDMAFlag. */
 	bRestartCharInput = !bCancel && (pdx->dwDMAFlag == MODE_CHAR)
 	    && !pdx->bXFerWaiting;
 
-	spin_unlock(&pdx->stagedLock);	// Finally release the lock again
+	spin_unlock(&pdx->stagedLock);	/*  Finally release the lock again */
 
-	// This is not correct as dwDMAFlag is protected by the staged lock, but it is treated
-	// in Allowi as if it were protected by the char lock. In any case, most systems will
-	// not be upset by char input during DMA... sigh. Needs sorting out.
-	if (bRestartCharInput)	// may be out of date, but...
-		Allowi(pdx);	// ...Allowi tests a lock too.
+	/*  This is not correct as dwDMAFlag is protected by the staged lock, but it is treated */
+	/*  in Allowi as if it were protected by the char lock. In any case, most systems will */
+	/*  not be upset by char input during DMA... sigh. Needs sorting out. */
+	if (bRestartCharInput)	/*  may be out of date, but... */
+		Allowi(pdx);	/*  ...Allowi tests a lock too. */
 	dev_dbg(&pdx->interface->dev, "%s done", __func__);
 }
 
@@ -709,29 +697,28 @@ static void staged_callback(struct urb *
 ** The calling code must have acquired the staging spinlock before calling
 **  this function, and is responsible for releasing it. We are at callback level.
 ****************************************************************************/
-static int StageChunk(DEVICE_EXTENSION * pdx)
+static int StageChunk(DEVICE_EXTENSION *pdx)
 {
 	int iReturn = U14ERR_NOERROR;
 	unsigned int ChunkSize;
-	int nPipe = pdx->StagedRead ? 3 : 2;	// The pipe number to use for reads or writes
+	int nPipe = pdx->StagedRead ? 3 : 2;	/*  The pipe number to use for reads or writes */
 	if (pdx->nPipes == 3)
-		nPipe--;	// Adjust for the 3-pipe case
-	if (nPipe < 0)		// and trap case that should never happen
+		nPipe--;	/*  Adjust for the 3-pipe case */
+	if (nPipe < 0)		/*  and trap case that should never happen */
 		return U14ERR_FAIL;
 
-	if (!CanAcceptIoRequests(pdx))	// got sudden remove?
-	{
+	if (!CanAcceptIoRequests(pdx)) {	/*  got sudden remove? */
 		dev_info(&pdx->interface->dev, "%s sudden remove, giving up",
 			 __func__);
-		return U14ERR_FAIL;	// could do with a better error
+		return U14ERR_FAIL;	/*  could do with a better error */
 	}
 
-	ChunkSize = (pdx->StagedLength - pdx->StagedDone);	// transfer length remaining
-	if (ChunkSize > STAGED_SZ)	// make sure to keep legal
-		ChunkSize = STAGED_SZ;	//  limit to max allowed
+	ChunkSize = (pdx->StagedLength - pdx->StagedDone);	/*  transfer length remaining */
+	if (ChunkSize > STAGED_SZ)	/*  make sure to keep legal */
+		ChunkSize = STAGED_SZ;	/*   limit to max allowed */
 
-	if (!pdx->StagedRead)	// if writing...
-		CopyUserSpace(pdx, ChunkSize);	// ...copy data into the buffer
+	if (!pdx->StagedRead)	/*  if writing... */
+		CopyUserSpace(pdx, ChunkSize);	/*  ...copy data into the buffer */
 
 	usb_fill_bulk_urb(pdx->pStagedUrb, pdx->udev,
 			  pdx->StagedRead ? usb_rcvbulkpipe(pdx->udev,
@@ -740,15 +727,15 @@ static int StageChunk(DEVICE_EXTENSION *
 			  usb_sndbulkpipe(pdx->udev, pdx->epAddr[nPipe]),
 			  pdx->pCoherStagedIO, ChunkSize, staged_callback, pdx);
 	pdx->pStagedUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-	usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted);	// in case we need to kill it
+	usb_anchor_urb(pdx->pStagedUrb, &pdx->submitted);	/*  in case we need to kill it */
 	iReturn = usb_submit_urb(pdx->pStagedUrb, GFP_ATOMIC);
 	if (iReturn) {
-		usb_unanchor_urb(pdx->pStagedUrb);	// kill it
-		pdx->bPipeError[nPipe] = 1;	// Flag an error to be handled later
+		usb_unanchor_urb(pdx->pStagedUrb);	/*  kill it */
+		pdx->bPipeError[nPipe] = 1;	/*  Flag an error to be handled later */
 		dev_err(&pdx->interface->dev, "%s submit urb failed, code %d",
 			__func__, iReturn);
 	} else
-		pdx->bStagedUrbPending = true;	// Set the flag for staged URB pending
+		pdx->bStagedUrbPending = true;	/*  Set the flag for staged URB pending */
 	dev_dbg(&pdx->interface->dev, "%s done so far:%d, this size:%d",
 		__func__, pdx->StagedDone, ChunkSize);
 
@@ -772,13 +759,12 @@ static int StageChunk(DEVICE_EXTENSION *
 **             transfer.
 **    dwLen - the number of bytes to transfer.
 */
-int ReadWriteMem(DEVICE_EXTENSION * pdx, bool Read, unsigned short wIdent,
+int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
 		 unsigned int dwOffs, unsigned int dwLen)
 {
-	TRANSAREA *pArea = &pdx->rTransDef[wIdent];	// Transfer area info
+	TRANSAREA *pArea = &pdx->rTransDef[wIdent];	/*  Transfer area info */
 
-	if (!CanAcceptIoRequests(pdx))	// Are we in a state to accept new requests?
-	{
+	if (!CanAcceptIoRequests(pdx)) {	/*  Are we in a state to accept new requests? */
 		dev_err(&pdx->interface->dev, "%s can't accept requests",
 			__func__);
 		return U14ERR_FAIL;
@@ -788,56 +774,51 @@ int ReadWriteMem(DEVICE_EXTENSION * pdx,
 		"%s xfer %d bytes to %s, offset %d, area %d", __func__, dwLen,
 		Read ? "host" : "1401", dwOffs, wIdent);
 
-	// Amazingly, we can get an escape sequence back before the current staged Urb is done, so we
-	//  have to check for this situation and, if so, wait until all is OK.
+	/*  Amazingly, we can get an escape sequence back before the current staged Urb is done, so we */
+	/*   have to check for this situation and, if so, wait until all is OK. */
 	if (pdx->bStagedUrbPending) {
-		pdx->bXFerWaiting = true;	// Flag we are waiting
+		pdx->bXFerWaiting = true;	/*  Flag we are waiting */
 		dev_info(&pdx->interface->dev,
 			 "%s xfer is waiting, as previous staged pending",
 			 __func__);
 		return U14ERR_NOERROR;
 	}
 
-	if (dwLen == 0)		// allow 0-len read or write; just return success
-	{
+	if (dwLen == 0) {		/*  allow 0-len read or write; just return success */
 		dev_dbg(&pdx->interface->dev,
 			"%s OK; zero-len read/write request", __func__);
 		return U14ERR_NOERROR;
 	}
 
-	if ((pArea->bCircular) &&	// Circular transfer?
-	    (pArea->bCircToHost) && (Read))	// In a supported direction
-	{			// If so, we sort out offset ourself
-		bool bWait = false;	// Flag for transfer having to wait
+	if ((pArea->bCircular) &&	/*  Circular transfer? */
+	    (pArea->bCircToHost) && (Read)) {	/*  In a supported direction */
+				/*  If so, we sort out offset ourself */
+		bool bWait = false;	/*  Flag for transfer having to wait */
 
 		dev_dbg(&pdx->interface->dev,
 			"Circular buffers are %d at %d and %d at %d",
 			pArea->aBlocks[0].dwSize, pArea->aBlocks[0].dwOffset,
 			pArea->aBlocks[1].dwSize, pArea->aBlocks[1].dwOffset);
-		if (pArea->aBlocks[1].dwSize > 0)	// Using the second block already?
-		{
-			dwOffs = pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize;	// take offset from that
-			bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset;	// Wait if will overwrite block 0?
-			bWait |= (dwOffs + dwLen) > pArea->dwLength;	// or if it overflows the buffer
-		} else		// Area 1 not in use, try to use area 0
-		{
-			if (pArea->aBlocks[0].dwSize == 0)	// Reset block 0 if not in use
+		if (pArea->aBlocks[1].dwSize > 0) {	/*  Using the second block already? */
+			dwOffs = pArea->aBlocks[1].dwOffset + pArea->aBlocks[1].dwSize;	/*  take offset from that */
+			bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset;	/*  Wait if will overwrite block 0? */
+			bWait |= (dwOffs + dwLen) > pArea->dwLength;	/*  or if it overflows the buffer */
+		} else {		/*  Area 1 not in use, try to use area 0 */
+			if (pArea->aBlocks[0].dwSize == 0)	/*  Reset block 0 if not in use */
 				pArea->aBlocks[0].dwOffset = 0;
 			dwOffs =
 			    pArea->aBlocks[0].dwOffset +
 			    pArea->aBlocks[0].dwSize;
-			if ((dwOffs + dwLen) > pArea->dwLength)	// Off the end of the buffer?
-			{
-				pArea->aBlocks[1].dwOffset = 0;	// Set up to use second block
+			if ((dwOffs + dwLen) > pArea->dwLength) {	/*  Off the end of the buffer? */
+				pArea->aBlocks[1].dwOffset = 0;	/*  Set up to use second block */
 				dwOffs = 0;
-				bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset;	// Wait if will overwrite block 0?
-				bWait |= (dwOffs + dwLen) > pArea->dwLength;	// or if it overflows the buffer
+				bWait = (dwOffs + dwLen) > pArea->aBlocks[0].dwOffset;	/*  Wait if will overwrite block 0? */
+				bWait |= (dwOffs + dwLen) > pArea->dwLength;	/*  or if it overflows the buffer */
 			}
 		}
 
-		if (bWait)	// This transfer will have to wait?
-		{
-			pdx->bXFerWaiting = true;	// Flag we are waiting
+		if (bWait) {	/*  This transfer will have to wait? */
+			pdx->bXFerWaiting = true;	/*  Flag we are waiting */
 			dev_dbg(&pdx->interface->dev,
 				"%s xfer waiting for circular buffer space",
 				__func__);
@@ -848,17 +829,17 @@ int ReadWriteMem(DEVICE_EXTENSION * pdx,
 			"%s circular xfer, %d bytes starting at %d", __func__,
 			dwLen, dwOffs);
 	}
-	// Save the parameters for the read\write transfer
-	pdx->StagedRead = Read;	// Save the parameters for this read
-	pdx->StagedId = wIdent;	// ID allows us to get transfer area info
-	pdx->StagedOffset = dwOffs;	// The area within the transfer area
+	/*  Save the parameters for the read\write transfer */
+	pdx->StagedRead = Read;	/*  Save the parameters for this read */
+	pdx->StagedId = wIdent;	/*  ID allows us to get transfer area info */
+	pdx->StagedOffset = dwOffs;	/*  The area within the transfer area */
 	pdx->StagedLength = dwLen;
-	pdx->StagedDone = 0;	// Initialise the byte count
-	pdx->dwDMAFlag = MODE_LINEAR;	// Set DMA mode flag at this point
-	pdx->bXFerWaiting = false;	// Clearly not a transfer waiting now
+	pdx->StagedDone = 0;	/*  Initialise the byte count */
+	pdx->dwDMAFlag = MODE_LINEAR;	/*  Set DMA mode flag at this point */
+	pdx->bXFerWaiting = false;	/*  Clearly not a transfer waiting now */
 
-//    KeClearEvent(&pdx->StagingDoneEvent);           // Clear the transfer done event
-	StageChunk(pdx);	// fire off the first chunk
+/*     KeClearEvent(&pdx->StagingDoneEvent);           // Clear the transfer done event */
+	StageChunk(pdx);	/*  fire off the first chunk */
 
 	return U14ERR_NOERROR;
 }
@@ -877,12 +858,11 @@ static bool ReadChar(unsigned char *pCha
 	bool bRead = false;
 	unsigned int dDone = *pdDone;
 
-	if (dDone < dGot)	// If there is more data
-	{
-		*pChar = (unsigned char)pBuf[dDone];	// Extract the next char
-		dDone++;	// Increment the done count
+	if (dDone < dGot) {	/*  If there is more data */
+		*pChar = (unsigned char)pBuf[dDone];	/*  Extract the next char */
+		dDone++;	/*  Increment the done count */
 		*pdDone = dDone;
-		bRead = true;	// and flag success
+		bRead = true;	/*  and flag success */
 	}
 
 	return bRead;
@@ -962,32 +942,32 @@ static bool ReadHuff(volatile unsigned i
 **  we start handling the data at offset zero.
 **
 *****************************************************************************/
-static bool ReadDMAInfo(volatile DMADESC * pDmaDesc, DEVICE_EXTENSION * pdx,
+static bool ReadDMAInfo(volatile DMADESC *pDmaDesc, DEVICE_EXTENSION *pdx,
 			char *pBuf, unsigned int dwCount)
 {
-	bool bResult = false;	// assume we won't succeed
+	bool bResult = false;	/*  assume we won't succeed */
 	unsigned char ucData;
-	unsigned int dDone = 0;	// We haven't parsed anything so far
+	unsigned int dDone = 0;	/*  We haven't parsed anything so far */
 
 	dev_dbg(&pdx->interface->dev, "%s", __func__);
 
 	if (ReadChar(&ucData, pBuf, &dDone, dwCount)) {
-		unsigned char ucTransCode = (ucData & 0x0F);	// get code for transfer type
-		unsigned short wIdent = ((ucData >> 4) & 0x07);	// and area identifier
+		unsigned char ucTransCode = (ucData & 0x0F);	/*  get code for transfer type */
+		unsigned short wIdent = ((ucData >> 4) & 0x07);	/*  and area identifier */
 
-		// fill in the structure we were given
-		pDmaDesc->wTransType = ucTransCode;	// type of transfer
-		pDmaDesc->wIdent = wIdent;	// area to use
-		pDmaDesc->dwSize = 0;	// initialise other bits
+		/*  fill in the structure we were given */
+		pDmaDesc->wTransType = ucTransCode;	/*  type of transfer */
+		pDmaDesc->wIdent = wIdent;	/*  area to use */
+		pDmaDesc->dwSize = 0;	/*  initialise other bits */
 		pDmaDesc->dwOffset = 0;
 
 		dev_dbg(&pdx->interface->dev, "%s type: %d ident: %d", __func__,
 			pDmaDesc->wTransType, pDmaDesc->wIdent);
 
-		pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST);	// set transfer direction
+		pDmaDesc->bOutWard = (ucTransCode != TM_EXTTOHOST);	/*  set transfer direction */
 
 		switch (ucTransCode) {
-		case TM_EXTTOHOST:	// Extended linear transfer modes (the only ones!)
+		case TM_EXTTOHOST:	/*  Extended linear transfer modes (the only ones!) */
 		case TM_EXTTO1401:
 			{
 				bResult =
@@ -1001,14 +981,14 @@ static bool ReadDMAInfo(volatile DMADESC
 						__func__, pDmaDesc->dwOffset,
 						pDmaDesc->dwSize);
 
-					if ((wIdent >= MAX_TRANSAREAS) ||	// Illegal area number, or...
-					    (!pdx->rTransDef[wIdent].bUsed) ||	// area not set up, or...
-					    (pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) ||	// range/size
+					if ((wIdent >= MAX_TRANSAREAS) ||	/*  Illegal area number, or... */
+					    (!pdx->rTransDef[wIdent].bUsed) ||	/*  area not set up, or... */
+					    (pDmaDesc->dwOffset > pdx->rTransDef[wIdent].dwLength) ||	/*  range/size */
 					    ((pDmaDesc->dwOffset +
 					      pDmaDesc->dwSize) >
 					     (pdx->rTransDef[wIdent].
 					      dwLength))) {
-						bResult = false;	// bad parameter(s)
+						bResult = false;	/*  bad parameter(s) */
 						dev_dbg(&pdx->interface->dev,
 							"%s bad param - id %d, bUsed %d, offset %d, size %d, area length %d",
 							__func__, wIdent,
@@ -1028,7 +1008,7 @@ static bool ReadDMAInfo(volatile DMADESC
 	} else
 		bResult = false;
 
-	if (!bResult)		// now check parameters for validity
+	if (!bResult)		/*  now check parameters for validity */
 		dev_err(&pdx->interface->dev, "%s error reading Esc sequence",
 			__func__);
 
@@ -1049,30 +1029,29 @@ static bool ReadDMAInfo(volatile DMADESC
 **           this is known to be at least 2 or we will not be called.
 **
 ****************************************************************************/
-static int Handle1401Esc(DEVICE_EXTENSION * pdx, char *pCh,
+static int Handle1401Esc(DEVICE_EXTENSION *pdx, char *pCh,
 			 unsigned int dwCount)
 {
 	int iReturn = U14ERR_FAIL;
 
-	// I have no idea what this next test is about. '?' is 0x3f, which is area 3, code
-	// 15. At the moment, this is not used, so it does no harm, but unless someone can
-	// tell me what this is for, it should be removed from this and the Windows driver.
-	if (pCh[0] == '?')	// Is this an information response
-	{			// Parse and save the information
+	/*  I have no idea what this next test is about. '?' is 0x3f, which is area 3, code */
+	/*  15. At the moment, this is not used, so it does no harm, but unless someone can */
+	/*  tell me what this is for, it should be removed from this and the Windows driver. */
+	if (pCh[0] == '?') {	/*  Is this an information response */
+				/*  Parse and save the information */
 	} else {
-		spin_lock(&pdx->stagedLock);	// Lock others out
+		spin_lock(&pdx->stagedLock);	/*  Lock others out */
 
-		if (ReadDMAInfo(&pdx->rDMAInfo, pdx, pCh, dwCount))	// Get DMA parameters
-		{
-			unsigned short wTransType = pdx->rDMAInfo.wTransType;	// check transfer type
+		if (ReadDMAInfo(&pdx->rDMAInfo, pdx, pCh, dwCount)) {	/*  Get DMA parameters */
+			unsigned short wTransType = pdx->rDMAInfo.wTransType;	/*  check transfer type */
 
 			dev_dbg(&pdx->interface->dev,
 				"%s xfer to %s, offset %d, length %d", __func__,
 				pdx->rDMAInfo.bOutWard ? "1401" : "host",
 				pdx->rDMAInfo.dwOffset, pdx->rDMAInfo.dwSize);
 
-			if (pdx->bXFerWaiting)	// Check here for badly out of kilter...
-			{	// This can never happen, really
+			if (pdx->bXFerWaiting) { /*  Check here for badly out of kilter... */
+				/*  This can never happen, really */
 				dev_err(&pdx->interface->dev,
 					"ERROR: DMA setup while transfer still waiting");
 				spin_unlock(&pdx->stagedLock);
@@ -1090,16 +1069,16 @@ static int Handle1401Esc(DEVICE_EXTENSIO
 						dev_err(&pdx->interface->dev,
 							"%s ReadWriteMem() failed %d",
 							__func__, iReturn);
-				} else	// This covers non-linear transfer setup
+				} else	/*  This covers non-linear transfer setup */
 					dev_err(&pdx->interface->dev,
 						"%s Unknown block xfer type %d",
 						__func__, wTransType);
 			}
-		} else		// Failed to read parameters
+		} else		/*  Failed to read parameters */
 			dev_err(&pdx->interface->dev, "%s ReadDMAInfo() fail",
 				__func__);
 
-		spin_unlock(&pdx->stagedLock);	// OK here
+		spin_unlock(&pdx->stagedLock);	/*  OK here */
 	}
 
 	dev_dbg(&pdx->interface->dev, "%s returns %d", __func__, iReturn);
@@ -1113,12 +1092,11 @@ static int Handle1401Esc(DEVICE_EXTENSIO
 static void ced_readchar_callback(struct urb *pUrb)
 {
 	DEVICE_EXTENSION *pdx = pUrb->context;
-	int nGot = pUrb->actual_length;	// what we transferred
+	int nGot = pUrb->actual_length;	/*  what we transferred */
 
-	if (pUrb->status)	// Do we have a problem to handle?
-	{
-		int nPipe = pdx->nPipes == 4 ? 1 : 0;	// The pipe number to use for error
-		// sync/async unlink faults aren't errors... just saying device removed or stopped
+	if (pUrb->status) {	/*  Do we have a problem to handle? */
+		int nPipe = pdx->nPipes == 4 ? 1 : 0;	/*  The pipe number to use for error */
+		/*  sync/async unlink faults aren't errors... just saying device removed or stopped */
 		if (!
 		    (pUrb->status == -ENOENT || pUrb->status == -ECONNRESET
 		     || pUrb->status == -ESHUTDOWN)) {
@@ -1133,27 +1111,26 @@ static void ced_readchar_callback(struct
 		spin_lock(&pdx->err_lock);
 		pdx->errors = pUrb->status;
 		spin_unlock(&pdx->err_lock);
-		nGot = 0;	//  and tidy up again if so
+		nGot = 0;	/*   and tidy up again if so */
 
-		spin_lock(&pdx->charInLock);	// already at irq level
-		pdx->bPipeError[nPipe] = 1;	// Flag an error for later
+		spin_lock(&pdx->charInLock);	/*  already at irq level */
+		pdx->bPipeError[nPipe] = 1;	/*  Flag an error for later */
 	} else {
-		if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b))	// Esc sequence?
-		{
-			Handle1401Esc(pdx, &pdx->pCoherCharIn[1], nGot - 1);	// handle it
-			spin_lock(&pdx->charInLock);	// already at irq level
+		if ((nGot > 1) && ((pdx->pCoherCharIn[0] & 0x7f) == 0x1b)) {	/*  Esc sequence? */
+			Handle1401Esc(pdx, &pdx->pCoherCharIn[1], nGot - 1);	/*  handle it */
+			spin_lock(&pdx->charInLock);	/*  already at irq level */
 		} else {
-			spin_lock(&pdx->charInLock);	// already at irq level
+			spin_lock(&pdx->charInLock);	/*  already at irq level */
 			if (nGot > 0) {
 				unsigned int i;
 				if (nGot < INBUF_SZ) {
-					pdx->pCoherCharIn[nGot] = 0;	// tidy the string
+					pdx->pCoherCharIn[nGot] = 0;	/*  tidy the string */
 					dev_dbg(&pdx->interface->dev,
 						"%s got %d chars >%s<",
 						__func__, nGot,
 						pdx->pCoherCharIn);
 				}
-				// We know that whatever we read must fit in the input buffer
+				/*  We know that whatever we read must fit in the input buffer */
 				for (i = 0; i < nGot; i++) {
 					pdx->inputBuffer[pdx->dwInBuffPut++] =
 					    pdx->pCoherCharIn[i] & 0x7F;
@@ -1162,17 +1139,17 @@ static void ced_readchar_callback(struct
 				}
 
 				if ((pdx->dwNumInput + nGot) <= INBUF_SZ)
-					pdx->dwNumInput += nGot;	// Adjust the buffer count accordingly
+					pdx->dwNumInput += nGot;	/*  Adjust the buffer count accordingly */
 			} else
 				dev_dbg(&pdx->interface->dev, "%s read ZLP",
 					__func__);
 		}
 	}
 
-	pdx->bReadCharsPending = false;	// No longer have a pending read
-	spin_unlock(&pdx->charInLock);	// already at irq level
+	pdx->bReadCharsPending = false;	/*  No longer have a pending read */
+	spin_unlock(&pdx->charInLock);	/*  already at irq level */
 
-	Allowi(pdx);	// see if we can do the next one
+	Allowi(pdx);	/*  see if we can do the next one */
 }
 
 /****************************************************************************
@@ -1182,25 +1159,25 @@ static void ced_readchar_callback(struct
 ** we can pick up any inward transfers. This can be called in multiple contexts
 ** so we use the irqsave version of the spinlock.
 ****************************************************************************/
-int Allowi(DEVICE_EXTENSION * pdx)
+int Allowi(DEVICE_EXTENSION *pdx)
 {
 	int iReturn = U14ERR_NOERROR;
 	unsigned long flags;
-	spin_lock_irqsave(&pdx->charInLock, flags);	// can be called in multiple contexts
+	spin_lock_irqsave(&pdx->charInLock, flags);	/*  can be called in multiple contexts */
 
-	// We don't want char input running while DMA is in progress as we know that this
-	//  can cause sequencing problems for the 2270. So don't. It will also allow the
-	//  ERR response to get back to the host code too early on some PCs, even if there
-	//  is no actual driver failure, so we don't allow this at all.
-	if (!pdx->bInDrawDown &&	// stop input if
-	    !pdx->bReadCharsPending &&	// If no read request outstanding
-	    (pdx->dwNumInput < (INBUF_SZ / 2)) &&	//  and there is some space
-	    (pdx->dwDMAFlag == MODE_CHAR) &&	//  not doing any DMA
-	    (!pdx->bXFerWaiting) &&	//  no xfer waiting to start
-	    (CanAcceptIoRequests(pdx)))	//  and activity is generally OK
-	{			//  then off we go
-		unsigned int nMax = INBUF_SZ - pdx->dwNumInput;	// max we could read
-		int nPipe = pdx->nPipes == 4 ? 1 : 0;	// The pipe number to use
+	/*  We don't want char input running while DMA is in progress as we know that this */
+	/*   can cause sequencing problems for the 2270. So don't. It will also allow the */
+	/*   ERR response to get back to the host code too early on some PCs, even if there */
+	/*   is no actual driver failure, so we don't allow this at all. */
+	if (!pdx->bInDrawDown &&	/*  stop input if */
+	    !pdx->bReadCharsPending &&	/*  If no read request outstanding */
+	    (pdx->dwNumInput < (INBUF_SZ / 2)) &&	/*   and there is some space */
+	    (pdx->dwDMAFlag == MODE_CHAR) &&	/*   not doing any DMA */
+	    (!pdx->bXFerWaiting) &&	/*   no xfer waiting to start */
+	    (CanAcceptIoRequests(pdx)))	{ /*   and activity is generally OK */
+				/*   then off we go */
+		unsigned int nMax = INBUF_SZ - pdx->dwNumInput;	/*  max we could read */
+		int nPipe = pdx->nPipes == 4 ? 1 : 0;	/*  The pipe number to use */
 
 		dev_dbg(&pdx->interface->dev, "%s %d chars in input buffer",
 			__func__, pdx->dwNumInput);
@@ -1209,16 +1186,16 @@ int Allowi(DEVICE_EXTENSION * pdx)
 				 usb_rcvintpipe(pdx->udev, pdx->epAddr[nPipe]),
 				 pdx->pCoherCharIn, nMax, ced_readchar_callback,
 				 pdx, pdx->bInterval);
-		pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;	// short xfers are OK by default
-		usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted);	// in case we need to kill it
+		pdx->pUrbCharIn->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;	/*  short xfers are OK by default */
+		usb_anchor_urb(pdx->pUrbCharIn, &pdx->submitted);	/*  in case we need to kill it */
 		iReturn = usb_submit_urb(pdx->pUrbCharIn, GFP_ATOMIC);
 		if (iReturn) {
-			usb_unanchor_urb(pdx->pUrbCharIn);	// remove from list of active Urbs
-			pdx->bPipeError[nPipe] = 1;	// Flag an error to be handled later
+			usb_unanchor_urb(pdx->pUrbCharIn);	/*  remove from list of active Urbs */
+			pdx->bPipeError[nPipe] = 1;	/*  Flag an error to be handled later */
 			dev_err(&pdx->interface->dev,
 				"%s submit urb failed: %d", __func__, iReturn);
 		} else
-			pdx->bReadCharsPending = true;	// Flag that we are active here
+			pdx->bReadCharsPending = true;	/*  Flag that we are active here */
 	}
 
 	spin_unlock_irqrestore(&pdx->charInLock, flags);
@@ -1238,15 +1215,15 @@ static long ced_ioctl(struct file *file,
 {
 	int err = 0;
 	DEVICE_EXTENSION *pdx = file->private_data;
-	if (!CanAcceptIoRequests(pdx))	// check we still exist
+	if (!CanAcceptIoRequests(pdx))	/*  check we still exist */
 		return -ENODEV;
 
-	// Check that access is allowed, where is is needed. Anything that would have an indeterminate
-	// size will be checked by the specific command.
-	if (_IOC_DIR(cmd) & _IOC_READ)	// read from point of view of user...
-		err = !access_ok(VERIFY_WRITE, (void __user *)ulArg, _IOC_SIZE(cmd));	// is kernel write
-	else if (_IOC_DIR(cmd) & _IOC_WRITE)	// and write from point of view of user...
-		err = !access_ok(VERIFY_READ, (void __user *)ulArg, _IOC_SIZE(cmd));	// is kernel read
+	/*  Check that access is allowed, where is is needed. Anything that would have an indeterminate */
+	/*  size will be checked by the specific command. */
+	if (_IOC_DIR(cmd) & _IOC_READ)	/*  read from point of view of user... */
+		err = !access_ok(VERIFY_WRITE, (void __user *)ulArg, _IOC_SIZE(cmd));	/*  is kernel write */
+	else if (_IOC_DIR(cmd) & _IOC_WRITE)	/*  and write from point of view of user... */
+		err = !access_ok(VERIFY_READ, (void __user *)ulArg, _IOC_SIZE(cmd));	/*  is kernel read */
 	if (err)
 		return -EFAULT;
 
@@ -1289,7 +1266,7 @@ static long ced_ioctl(struct file *file,
 		return -1;
 
 	case _IOC_NR(IOCTL_CED_GETDRIVERREVISION):
-		return (2 << 24) | (DRIVERMAJREV << 16) | DRIVERMINREV;	// USB | MAJOR | MINOR
+		return (2 << 24) | (DRIVERMAJREV << 16) | DRIVERMINREV;	/*  USB | MAJOR | MINOR */
 
 	case _IOC_NR(IOCTL_CED_GETTRANSFER):
 		return GetTransfer(pdx, (TGET_TX_BLOCK __user *) ulArg);
@@ -1335,7 +1312,7 @@ static long ced_ioctl(struct file *file,
 		return DbgStopLoop(pdx);
 
 	case _IOC_NR(IOCTL_CED_FULLRESET):
-		pdx->bForceReset = true;	// Set a flag for a full reset
+		pdx->bForceReset = true;	/*  Set a flag for a full reset */
 		break;
 
 	case _IOC_NR(IOCTL_CED_SETCIRCULAR):
@@ -1378,8 +1355,8 @@ static struct usb_class_driver ced_class
 	.minor_base = USB_CED_MINOR_BASE,
 };
 
-// Check that the device that matches a 1401 vendor and product ID is OK to use and
-// initialise our DEVICE_EXTENSION.
+/*  Check that the device that matches a 1401 vendor and product ID is OK to use and */
+/*  initialise our DEVICE_EXTENSION. */
 static int ced_probe(struct usb_interface *interface,
 		     const struct usb_device_id *id)
 {
@@ -1389,23 +1366,22 @@ static int ced_probe(struct usb_interfac
 	int i, bcdDevice;
 	int retval = -ENOMEM;
 
-	// allocate memory for our device extension and initialize it
+	/*  allocate memory for our device extension and initialize it */
 	pdx = kzalloc(sizeof(*pdx), GFP_KERNEL);
 	if (!pdx)
 		goto error;
 
-	for (i = 0; i < MAX_TRANSAREAS; ++i)	// Initialise the wait queues
-	{
+	for (i = 0; i < MAX_TRANSAREAS; ++i) {	/*  Initialise the wait queues */
 		init_waitqueue_head(&pdx->rTransDef[i].wqEvent);
 	}
 
-	// Put initialises for our stuff here. Note that all of *pdx is zero, so
-	// no need to explicitly zero it.
+	/*  Put initialises for our stuff here. Note that all of *pdx is zero, so */
+	/*  no need to explicitly zero it. */
 	spin_lock_init(&pdx->charOutLock);
 	spin_lock_init(&pdx->charInLock);
 	spin_lock_init(&pdx->stagedLock);
 
-	// Initialises from the skeleton stuff
+	/*  Initialises from the skeleton stuff */
 	kref_init(&pdx->kref);
 	mutex_init(&pdx->io_mutex);
 	spin_lock_init(&pdx->err_lock);
@@ -1414,7 +1390,7 @@ static int ced_probe(struct usb_interfac
 	pdx->udev = usb_get_dev(interface_to_usbdev(interface));
 	pdx->interface = interface;
 
-	// Attempt to identify the device
+	/*  Attempt to identify the device */
 	bcdDevice = pdx->udev->descriptor.bcdDevice;
 	i = (bcdDevice >> 8);
 	if (i == 0)
@@ -1426,8 +1402,8 @@ static int ced_probe(struct usb_interfac
 			__func__, bcdDevice);
 		goto error;
 	}
-	// set up the endpoint information. We only care about the number of EP as
-	// we know that we are dealing with a 1401 device.
+	/*  set up the endpoint information. We only care about the number of EP as */
+	/*  we know that we are dealing with a 1401 device. */
 	iface_desc = interface->cur_altsetting;
 	pdx->nPipes = iface_desc->desc.bNumEndpoints;
 	dev_info(&interface->dev, "1401Type=%d with %d End Points",
@@ -1435,10 +1411,10 @@ static int ced_probe(struct usb_interfac
 	if ((pdx->nPipes < 3) || (pdx->nPipes > 4))
 		goto error;
 
-	// Allocate the URBs we hold for performing transfers
-	pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL);	// character output URB
-	pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL);	// character input URB
-	pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL);	// block transfer URB
+	/*  Allocate the URBs we hold for performing transfers */
+	pdx->pUrbCharOut = usb_alloc_urb(0, GFP_KERNEL);	/*  character output URB */
+	pdx->pUrbCharIn = usb_alloc_urb(0, GFP_KERNEL);	/*  character input URB */
+	pdx->pStagedUrb = usb_alloc_urb(0, GFP_KERNEL);	/*  block transfer URB */
 	if (!pdx->pUrbCharOut || !pdx->pUrbCharIn || !pdx->pStagedUrb) {
 		dev_err(&interface->dev, "%s URB alloc failed", __func__);
 		goto error;
@@ -1464,15 +1440,14 @@ static int ced_probe(struct usb_interfac
 		pdx->epAddr[i] = endpoint->bEndpointAddress;
 		dev_info(&interface->dev, "Pipe %d, ep address %02x", i,
 			 pdx->epAddr[i]);
-		if (((pdx->nPipes == 3) && (i == 0)) ||	// if char input end point
+		if (((pdx->nPipes == 3) && (i == 0)) ||	/*  if char input end point */
 		    ((pdx->nPipes == 4) && (i == 1))) {
-			pdx->bInterval = endpoint->bInterval;	// save the endpoint interrupt interval
+			pdx->bInterval = endpoint->bInterval;	/*  save the endpoint interrupt interval */
 			dev_info(&interface->dev, "Pipe %d, bInterval = %d", i,
 				 pdx->bInterval);
 		}
-		// Detect USB2 by checking last ep size (64 if USB1)
-		if (i == pdx->nPipes - 1)	// if this is the last ep (bulk)
-		{
+		/*  Detect USB2 by checking last ep size (64 if USB1) */
+		if (i == pdx->nPipes - 1) {	/*  if this is the last ep (bulk) */
 			pdx->bIsUSB2 =
 			    le16_to_cpu(endpoint->wMaxPacketSize) > 64;
 			dev_info(&pdx->interface->dev, "USB%d",
@@ -1501,7 +1476,7 @@ static int ced_probe(struct usb_interfac
 
 error:
 	if (pdx)
-		kref_put(&pdx->kref, ced_delete);	// frees allocated memory
+		kref_put(&pdx->kref, ced_delete);	/*  frees allocated memory */
 	return retval;
 }
 
@@ -1511,39 +1486,39 @@ static void ced_disconnect(struct usb_in
 	int minor = interface->minor;
 	int i;
 
-	usb_set_intfdata(interface, NULL);	// remove the pdx from the interface
-	usb_deregister_dev(interface, &ced_class);	// give back our minor device number
+	usb_set_intfdata(interface, NULL);	/*  remove the pdx from the interface */
+	usb_deregister_dev(interface, &ced_class);	/*  give back our minor device number */
 
-	mutex_lock(&pdx->io_mutex);	// stop more I/O starting while...
-	ced_draw_down(pdx);	// ...wait for then kill any io
+	mutex_lock(&pdx->io_mutex);	/*  stop more I/O starting while... */
+	ced_draw_down(pdx);	/*  ...wait for then kill any io */
 	for (i = 0; i < MAX_TRANSAREAS; ++i) {
-		int iErr = ClearArea(pdx, i);	// ...release any used memory
+		int iErr = ClearArea(pdx, i);	/*  ...release any used memory */
 		if (iErr == U14ERR_UNLOCKFAIL)
 			dev_err(&pdx->interface->dev, "%s Area %d was in used",
 				__func__, i);
 	}
-	pdx->interface = NULL;	// ...we kill off link to interface
+	pdx->interface = NULL;	/*  ...we kill off link to interface */
 	mutex_unlock(&pdx->io_mutex);
 
 	usb_kill_anchored_urbs(&pdx->submitted);
 
-	kref_put(&pdx->kref, ced_delete);	// decrement our usage count
+	kref_put(&pdx->kref, ced_delete);	/*  decrement our usage count */
 
 	dev_info(&interface->dev, "USB cedusb #%d now disconnected", minor);
 }
 
-// Wait for all the urbs we know of to be done with, then kill off any that
-// are left. NBNB we will need to have a mechanism to stop circular xfers
-// from trying to fire off more urbs. We will wait up to 3 seconds for Urbs
-// to be done.
-void ced_draw_down(DEVICE_EXTENSION * pdx)
+/*  Wait for all the urbs we know of to be done with, then kill off any that */
+/*  are left. NBNB we will need to have a mechanism to stop circular xfers */
+/*  from trying to fire off more urbs. We will wait up to 3 seconds for Urbs */
+/*  to be done. */
+void ced_draw_down(DEVICE_EXTENSION *pdx)
 {
 	int time;
 	dev_dbg(&pdx->interface->dev, "%s called", __func__);
 
 	pdx->bInDrawDown = true;
 	time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000);
-	if (!time) {		// if we timed out we kill the urbs
+	if (!time) {		/*  if we timed out we kill the urbs */
 		usb_kill_anchored_urbs(&pdx->submitted);
 		dev_err(&pdx->interface->dev, "%s timed out", __func__);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ced1401/usb1401.h linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/usb1401.h
--- linux-libre-3.10-gnu/drivers/staging/ced1401/usb1401.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/usb1401.h	2013-08-25 20:43:22.000000000 -0400
@@ -26,31 +26,32 @@
 #define UINT unsigned int
 #endif
 
-/// Device type codes, but these don't need to be extended - a succession is assumed
-/// These are set for usb from the bcdDevice field (suitably mangled). Future devices
-/// will be added in order of device creation to the list, so the names here are just
-/// to help use remember which device is which. The U14ERR_... values follow the same
-/// pattern for modern devices.
-#define TYPEUNKNOWN        -1             // dont know
-#define TYPE1401           0              // standard 1401
-#define TYPEPLUS           1              // 1401 plus
-#define TYPEU1401          2              // u1401
-#define TYPEPOWER          3              // Power1401
-#define TYPEU14012         4              // u1401 mkII
-#define TYPEPOWER2         5              // Power1401 mk II
-#define TYPEMICRO3         6              // Micro1401-3
-#define TYPEPOWER3         7              // Power1401-3
+/** Device type codes, but these don't need to be extended - a succession is assumed
+** These are set for usb from the bcdDevice field (suitably mangled). Future devices
+** will be added in order of device creation to the list, so the names here are just
+** to help use remember which device is which. The U14ERR_... values follow the same
+** pattern for modern devices.a
+**/
+#define TYPEUNKNOWN        -1             /*  dont know */
+#define TYPE1401           0              /*  standard 1401 */
+#define TYPEPLUS           1              /*  1401 plus */
+#define TYPEU1401          2              /*  u1401 */
+#define TYPEPOWER          3              /*  Power1401 */
+#define TYPEU14012         4              /*  u1401 mkII */
+#define TYPEPOWER2         5              /*  Power1401 mk II */
+#define TYPEMICRO3         6              /*  Micro1401-3 */
+#define TYPEPOWER3         7              /*  Power1401-3 */
 
-/// Some useful defines of constants. DONT FORGET to change the version in the
-/// resources whenever you change it here!.
-#define DRIVERMAJREV      2             // driver revision level major (match windows)
-#define DRIVERMINREV      0             // driver revision level minor
+/*  Some useful defines of constants. DONT FORGET to change the version in the */
+/*  resources whenever you change it here!. */
+#define DRIVERMAJREV      2             /*  driver revision level major (match windows) */
+#define DRIVERMINREV      0             /*  driver revision level minor */
 
-/// Definitions of the various block transfer command codes
-#define TM_EXTTOHOST    8               // extended tohost
-#define TM_EXTTO1401    9               // extended to1401
+/*  Definitions of the various block transfer command codes */
+#define TM_EXTTOHOST    8               /*  extended tohost */
+#define TM_EXTTO1401    9               /*  extended to1401 */
 
-/// Definitions of values in usbReqtype. Used in sorting out setup actions
+/*  Definitions of values in usbReqtype. Used in sorting out setup actions */
 #define H_TO_D 0x00
 #define D_TO_H 0x80
 #define VENDOR 0x40
@@ -58,7 +59,7 @@
 #define INTREQ 0x01
 #define ENDREQ 0x02
 
-/// Definition of values in usbRequest, again used to sort out setup
+/*  Definition of values in usbRequest, again used to sort out setup */
 #define GET_STATUS      0x00
 #define CLEAR_FEATURE   0x01
 #define SET_FEATURE     0x03
@@ -71,8 +72,8 @@
 #define SET_INTERFACE   0x0b
 #define SYNCH_FRAME     0x0c
 
-/// Definitions of the various debug command codes understood by the 1401. These
-/// are used in various vendor-specific commands to achieve the desired effect
+/*  Definitions of the various debug command codes understood by the 1401. These */
+/*  are used in various vendor-specific commands to achieve the desired effect */
 #define DB_GRAB         0x50            /* Grab is a NOP for USB */
 #define DB_FREE         0x51            /* Free is a NOP for the USB */
 #define DB_SETADD       0x52            /* Set debug address (double) */
@@ -91,139 +92,135 @@
 #define CR_CHAR          0x0D           /* The carriage return character */
 #define CR_CHAR_80       0x8d           /*  and with bit 7 set */
 
-/// A structure holding information about a block of memory for use in circular transfers
-typedef struct circBlk
-{
-    volatile UINT dwOffset;             /* Offset within area of block start */
-    volatile UINT dwSize;               /* Size of the block, in bytes (0 = unused) */
+/*  A structure holding information about a block of memory for use in circular transfers */
+typedef struct circBlk {
+	volatile UINT dwOffset;             /* Offset within area of block start */
+	volatile UINT dwSize;               /* Size of the block, in bytes (0 = unused) */
 } CIRCBLK;
 
-/// A structure holding all of the information about a transfer area - an area of
-///  memory set up for use either as a source or destination in DMA transfers.
-typedef struct transarea
-{
-    void*       lpvBuff;                // User address of xfer area saved for completeness
-    UINT        dwBaseOffset;           // offset to start of xfer area in first page
-    UINT        dwLength;               // Length of xfer area, in bytes
-    struct page **pPages;               // Points at array of locked down pages
-    int         nPages;                 // number of pages that are locked down
-    bool        bUsed;                  // Is this structure in use?
-    bool        bCircular;              // Is this area for circular transfers?
-    bool        bCircToHost;            // Flag for direction of circular transfer
-    bool        bEventToHost;           // Set event on transfer to host?
-    int         iWakeUp;                // Set 1 on event, cleared by TestEvent()
-    UINT        dwEventSt;              // Defines section within xfer area for...
-    UINT        dwEventSz;              // ...notification by the event SZ is 0 if unset
-    CIRCBLK     aBlocks[2];             // Info on a pair of circular blocks
-    wait_queue_head_t wqEvent;          // The wait queue for events in this area MUST BE LAST
+/*  A structure holding all of the information about a transfer area - an area of */
+/*   memory set up for use either as a source or destination in DMA transfers. */
+typedef struct transarea {
+	void	*lpvBuff;                /*  User address of xfer area saved for completeness */
+	UINT        dwBaseOffset;           /*  offset to start of xfer area in first page */
+	UINT        dwLength;               /*  Length of xfer area, in bytes */
+	struct page **pPages;               /*  Points at array of locked down pages */
+	int         nPages;                 /*  number of pages that are locked down */
+	bool        bUsed;                  /*  Is this structure in use? */
+	bool        bCircular;              /*  Is this area for circular transfers? */
+	bool        bCircToHost;            /*  Flag for direction of circular transfer */
+	bool        bEventToHost;           /*  Set event on transfer to host? */
+	int         iWakeUp;                /*  Set 1 on event, cleared by TestEvent() */
+	UINT        dwEventSt;              /*  Defines section within xfer area for... */
+	UINT        dwEventSz;              /*  ...notification by the event SZ is 0 if unset */
+	CIRCBLK     aBlocks[2];             /*  Info on a pair of circular blocks */
+	wait_queue_head_t wqEvent;          /*  The wait queue for events in this area MUST BE LAST */
 } TRANSAREA;
 
-/// The DMADESC structure is used to hold information on the transfer in progress. It
-/// is set up by ReadDMAInfo, using information sent by the 1401 in an escape sequence.
-typedef struct dmadesc
-{
-    unsigned short wTransType;          /* transfer type as TM_xxx above        */
-    unsigned short wIdent;              /* identifier word                      */
-    unsigned int   dwSize;              /* bytes to transfer                    */
-    unsigned int   dwOffset;            /* offset into transfer area for trans  */
-    bool           bOutWard;            /* true when data is going TO 1401      */
+/*  The DMADESC structure is used to hold information on the transfer in progress. It */
+/*  is set up by ReadDMAInfo, using information sent by the 1401 in an escape sequence. */
+typedef struct dmadesc {
+	unsigned short wTransType;          /* transfer type as TM_xxx above        */
+	unsigned short wIdent;              /* identifier word                      */
+	unsigned int   dwSize;              /* bytes to transfer                    */
+	unsigned int   dwOffset;            /* offset into transfer area for trans  */
+	bool           bOutWard;            /* true when data is going TO 1401      */
 } DMADESC;
 
 #define INBUF_SZ         256            /* input buffer size */
 #define OUTBUF_SZ        256            /* output buffer size */
-#define STAGED_SZ 0x10000               // size of coherent buffer for staged transfers
+#define STAGED_SZ 0x10000               /*  size of coherent buffer for staged transfers */
 
-/// Structure to hold all of our device specific stuff. We are making this as similar as we
-/// can to the Windows driver to help in our understanding of what is going on.
-typedef struct _DEVICE_EXTENSION
-{
-    char inputBuffer[INBUF_SZ];         /* The two buffers */
-    char outputBuffer[OUTBUF_SZ];       /* accessed by the host functions */
-    volatile unsigned int dwNumInput;   /* num of chars in input buffer   */
-    volatile unsigned int dwInBuffGet;  /* where to get from input buffer */
-    volatile unsigned int dwInBuffPut;  /* where to put into input buffer */
-    volatile unsigned int dwNumOutput;  /* num of chars in output buffer  */
-    volatile unsigned int dwOutBuffGet; /* where to get from output buffer*/
-    volatile unsigned int dwOutBuffPut; /* where to put into output buffer*/
+/*  Structure to hold all of our device specific stuff. We are making this as similar as we */
+/*  can to the Windows driver to help in our understanding of what is going on. */
+typedef struct _DEVICE_EXTENSION {
+	char inputBuffer[INBUF_SZ];         /* The two buffers */
+	char outputBuffer[OUTBUF_SZ];       /* accessed by the host functions */
+	volatile unsigned int dwNumInput;   /* num of chars in input buffer   */
+	volatile unsigned int dwInBuffGet;  /* where to get from input buffer */
+	volatile unsigned int dwInBuffPut;  /* where to put into input buffer */
+	volatile unsigned int dwNumOutput;  /* num of chars in output buffer  */
+	volatile unsigned int dwOutBuffGet; /* where to get from output buffer*/
+	volatile unsigned int dwOutBuffPut; /* where to put into output buffer*/
 
-    volatile bool bSendCharsPending;    /* Flag to indicate sendchar active */
-    volatile bool bReadCharsPending;    /* Flag to indicate a read is primed */
-    char* pCoherCharOut;                /* special aligned buffer for chars to 1401 */
-    struct urb* pUrbCharOut;            /* urb used for chars to 1401 */
-    char* pCoherCharIn;                 /* special aligned buffer for chars to host */
-    struct urb* pUrbCharIn;             /* urb used for chars to host */
+	volatile bool bSendCharsPending;    /* Flag to indicate sendchar active */
+	volatile bool bReadCharsPending;    /* Flag to indicate a read is primed */
+	char *pCoherCharOut;                /* special aligned buffer for chars to 1401 */
+	struct urb *pUrbCharOut;            /* urb used for chars to 1401 */
+	char *pCoherCharIn;                 /* special aligned buffer for chars to host */
+	struct urb *pUrbCharIn;             /* urb used for chars to host */
 
-    spinlock_t charOutLock;             /* to protect the outputBuffer and outputting */
-    spinlock_t charInLock;              /* to protect the inputBuffer and char reads */
-    __u8 bInterval;                     /* Interrupt end point interval */
+	spinlock_t charOutLock;             /* to protect the outputBuffer and outputting */
+	spinlock_t charInLock;              /* to protect the inputBuffer and char reads */
+	__u8 bInterval;                     /* Interrupt end point interval */
 
-    volatile unsigned int dwDMAFlag;    /* state of DMA */
-    TRANSAREA rTransDef[MAX_TRANSAREAS];/* transfer area info */
-    volatile DMADESC rDMAInfo;          // info on current DMA transfer
-    volatile bool bXFerWaiting;         // Flag set if DMA transfer stalled
-    volatile bool bInDrawDown;          // Flag that we want to halt transfers
+	volatile unsigned int dwDMAFlag;    /* state of DMA */
+	TRANSAREA rTransDef[MAX_TRANSAREAS];/* transfer area info */
+	volatile DMADESC rDMAInfo;          /*  info on current DMA transfer */
+	volatile bool bXFerWaiting;         /*  Flag set if DMA transfer stalled */
+	volatile bool bInDrawDown;          /*  Flag that we want to halt transfers */
 
-    // Parameters relating to a block read\write that is in progress. Some of these values
-    //  are equivalent to values in rDMAInfo. The values here are those in use, while those
-    //  in rDMAInfo are those received from the 1401 via an escape sequence. If another
-    //  escape sequence arrives before the previous xfer ends, rDMAInfo values are updated while these
-    //  are used to finish off the current transfer.
-    volatile short StagedId;            // The transfer area id for this transfer
-    volatile bool StagedRead;           // Flag TRUE for read from 1401, FALSE for write
-    volatile unsigned int StagedLength; // Total length of this transfer
-    volatile unsigned int StagedOffset; // Offset within memory area for transfer start
-    volatile unsigned int StagedDone;   // Bytes transferred so far
-    volatile bool bStagedUrbPending;    // Flag to indicate active
-    char* pCoherStagedIO;               // buffer used for block transfers
-    struct urb* pStagedUrb;             // The URB to use
-    spinlock_t stagedLock;              // protects ReadWriteMem() and circular buffer stuff
+	/*  Parameters relating to a block read\write that is in progress. Some of these values */
+	/*   are equivalent to values in rDMAInfo. The values here are those in use, while those */
+	/*   in rDMAInfo are those received from the 1401 via an escape sequence. If another */
+	/*   escape sequence arrives before the previous xfer ends, rDMAInfo values are updated while these */
+	/*   are used to finish off the current transfer. */
+	volatile short StagedId;            /*  The transfer area id for this transfer */
+	volatile bool StagedRead;           /*  Flag TRUE for read from 1401, FALSE for write */
+	volatile unsigned int StagedLength; /*  Total length of this transfer */
+	volatile unsigned int StagedOffset; /*  Offset within memory area for transfer start */
+	volatile unsigned int StagedDone;   /*  Bytes transferred so far */
+	volatile bool bStagedUrbPending;    /*  Flag to indicate active */
+	char *pCoherStagedIO;               /*  buffer used for block transfers */
+	struct urb *pStagedUrb;             /*  The URB to use */
+	spinlock_t stagedLock;              /*  protects ReadWriteMem() and circular buffer stuff */
 
-    short s1401Type;                    // type of 1401 attached
-    short sCurrentState;                // current error state
-    bool bIsUSB2;                       // type of the interface we connect to
-    bool bForceReset;                   // Flag to make sure we get a real reset
-    __u32 statBuf[2];                   // buffer for 1401 state info
+	short s1401Type;                    /*  type of 1401 attached */
+	short sCurrentState;                /*  current error state */
+	bool bIsUSB2;                       /*  type of the interface we connect to */
+	bool bForceReset;                   /*  Flag to make sure we get a real reset */
+	__u32 statBuf[2];                   /*  buffer for 1401 state info */
 
-    unsigned long ulSelfTestTime;       // used to timeout self test
+	unsigned long ulSelfTestTime;       /*  used to timeout self test */
 
-    int nPipes;                         // Should be 3 or 4 depending on 1401 usb chip
-    int bPipeError[4];                  // set non-zero if an error on one of the pipe
-    __u8 epAddr[4];                     // addresses of the 3/4 end points
+	int nPipes;                         /*  Should be 3 or 4 depending on 1401 usb chip */
+	int bPipeError[4];                  /*  set non-zero if an error on one of the pipe */
+	__u8 epAddr[4];                     /*  addresses of the 3/4 end points */
 
-    struct usb_device *udev;            // the usb device for this device
-    struct usb_interface *interface;    // the interface for this device, NULL if removed
-    struct usb_anchor submitted;        // in case we need to retract our submissions
-    struct mutex io_mutex;              // synchronize I/O with disconnect, one user-mode caller at a time
+	struct usb_device *udev;            /*  the usb device for this device */
+	struct usb_interface *interface;    /*  the interface for this device, NULL if removed */
+	struct usb_anchor submitted;        /*  in case we need to retract our submissions */
+	struct mutex io_mutex;              /*  synchronize I/O with disconnect, one user-mode caller at a time */
 
-    int    errors;                      // the last request tanked
-    int    open_count;                  // count the number of openers
-    spinlock_t err_lock;                // lock for errors
-    struct kref kref;
-}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
+	int    errors;                      /*  the last request tanked */
+	int    open_count;                  /*  count the number of openers */
+	spinlock_t err_lock;                /*  lock for errors */
+	struct kref kref;
+} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
 #define to_DEVICE_EXTENSION(d) container_of(d, DEVICE_EXTENSION, kref)
 
-/// Definitions of routimes used between compilation object files
-// in usb1401.c
-extern int Allowi(DEVICE_EXTENSION* pdx);
-extern int SendChars(DEVICE_EXTENSION* pdx);
+/*  Definitions of routimes used between compilation object files */
+/*  in usb1401.c */
+extern int Allowi(DEVICE_EXTENSION *pdx);
+extern int SendChars(DEVICE_EXTENSION *pdx);
 extern void ced_draw_down(DEVICE_EXTENSION *pdx);
 extern int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent,
-                      unsigned int dwOffs, unsigned int dwLen);
+				unsigned int dwOffs, unsigned int dwLen);
 
-// in ced_ioc.c
+/*  in ced_ioc.c */
 extern int ClearArea(DEVICE_EXTENSION *pdx, int nArea);
-extern int SendString(DEVICE_EXTENSION* pdx, const char __user* pData, unsigned int n);
+extern int SendString(DEVICE_EXTENSION *pdx, const char __user *pData, unsigned int n);
 extern int SendChar(DEVICE_EXTENSION *pdx, char c);
-extern int Get1401State(DEVICE_EXTENSION* pdx, __u32* state, __u32* error);
+extern int Get1401State(DEVICE_EXTENSION *pdx, __u32 *state, __u32 *error);
 extern int ReadWrite_Cancel(DEVICE_EXTENSION *pdx);
-extern bool Is1401(DEVICE_EXTENSION* pdx);
-extern bool QuickCheck(DEVICE_EXTENSION* pdx, bool bTestBuff, bool bCanReset);
+extern bool Is1401(DEVICE_EXTENSION *pdx);
+extern bool QuickCheck(DEVICE_EXTENSION *pdx, bool bTestBuff, bool bCanReset);
 extern int Reset1401(DEVICE_EXTENSION *pdx);
 extern int GetChar(DEVICE_EXTENSION *pdx);
-extern int GetString(DEVICE_EXTENSION *pdx, char __user* pUser, int n);
+extern int GetString(DEVICE_EXTENSION *pdx, char __user *pUser, int n);
 extern int SetTransfer(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD);
 extern int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea);
-extern int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user*pTE);
+extern int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user *pTE);
 extern int Stat1401(DEVICE_EXTENSION *pdx);
 extern int LineCount(DEVICE_EXTENSION *pdx);
 extern int GetOutBufSpace(DEVICE_EXTENSION *pdx);
@@ -235,15 +232,15 @@ extern int StartSelfTest(DEVICE_EXTENSIO
 extern int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST);
 extern int TypeOf1401(DEVICE_EXTENSION *pdx);
 extern int TransferFlags(DEVICE_EXTENSION *pdx);
-extern int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user* pDB);
+extern int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
 extern int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
 extern int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
 extern int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
 extern int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB);
 extern int DbgStopLoop(DEVICE_EXTENSION *pdx);
 extern int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD);
-extern int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB);
-extern int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB);
+extern int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB);
+extern int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user *pCB);
 extern int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut);
 extern int TestEvent(DEVICE_EXTENSION *pdx, int nArea);
 #endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ced1401/use1401.h linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/use1401.h
--- linux-libre-3.10-gnu/drivers/staging/ced1401/use1401.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/use1401.h	2013-08-25 20:43:22.000000000 -0400
@@ -11,16 +11,16 @@
 #define __USE1401_H__
 #include "machine.h"
 
-// Some definitions to make things compatible. If you want to use Use1401 directly
-//  from a Windows program you should define U14_NOT_DLL, in which case you also
-//  MUST make sure that your application startup code calls U14InitLib().
-// DLL_USE1401 is defined when you are building the Use1401 dll, not otherwise.
+/*  Some definitions to make things compatible. If you want to use Use1401 directly */
+/*   from a Windows program you should define U14_NOT_DLL, in which case you also */
+/*   MUST make sure that your application startup code calls U14InitLib(). */
+/*  DLL_USE1401 is defined when you are building the Use1401 dll, not otherwise. */
 #ifdef _IS_WINDOWS_
 #ifndef U14_NOT_DLL
 #ifdef DLL_USE1401
-#define U14API(retType) retType DllExport __stdcall
+#define U14API(retType) (retType DllExport __stdcall)
 #else
-#define U14API(retType) retType DllImport __stdcall
+#define U14API(retType) (retType DllImport __stdcall)
 #endif
 #endif
 
@@ -36,7 +36,7 @@
 #ifdef _QT
 #ifndef U14_NOT_DLL
 #undef U14API
-#define U14API(retType) retType __declspec(dllimport) __stdcall
+#define U14API(retType) (retType __declspec(dllimport) __stdcall)
 #endif
 #undef U14LONG
 #define U14LONG int
@@ -50,20 +50,20 @@
 #define U14LONG long
 #endif
 
-/// Error codes: We need them here as user space can see them.
-#define U14ERR_NOERROR        0             // no problems
+/* Error codes: We need them here as user space can see them. */
+#define U14ERR_NOERROR        0             /*  no problems */
 
-/// Device error codes, but these don't need to be extended - a succession is assumed
-#define U14ERR_STD            4              // standard 1401 connected
-#define U14ERR_U1401          5              // u1401 connected
-#define U14ERR_PLUS           6              // 1401 plus connected
-#define U14ERR_POWER          7              // Power1401 connected
-#define U14ERR_U14012         8              // u1401 mkII connected
+/* Device error codes, but these don't need to be extended - a succession is assumed */
+#define U14ERR_STD            4              /*  standard 1401 connected */
+#define U14ERR_U1401          5              /*  u1401 connected */
+#define U14ERR_PLUS           6              /*  1401 plus connected */
+#define U14ERR_POWER          7              /*  Power1401 connected */
+#define U14ERR_U14012         8              /*  u1401 mkII connected */
 #define U14ERR_POWER2         9
 #define U14ERR_U14013        10
 #define U14ERR_POWER3        11
 
-/// NBNB Error numbers need shifting as some linux error codes start at 512
+/* NBNB Error numbers need shifting as some linux error codes start at 512 */
 #define U14ERR(n)             (n+U14ERRBASE)
 #define U14ERR_OFF            U14ERR(0)      /* 1401 there but switched off    */
 #define U14ERR_NC             U14ERR(-1)     /* 1401 not connected             */
@@ -113,7 +113,7 @@
 #define U14ERR_DRIVCOMMS      U14ERR(-110)   /* failed talking to driver       */
 #define U14ERR_OUTOFMEMORY    U14ERR(-111)   /* needed memory and couldnt get it*/
 
-/// 1401 type codes.
+/* / 1401 type codes. */
 #define U14TYPE1401           0           /* standard 1401                  */
 #define U14TYPEPLUS           1           /* 1401 plus                      */
 #define U14TYPEU1401          2           /* u1401                          */
@@ -124,9 +124,9 @@
 #define U14TYPEPOWER3         7           /* power1401-3                    */
 #define U14TYPEUNKNOWN        -1          /* dont know                      */
 
-/// Transfer flags to allow driver capabilities to be interrogated
+/* Transfer flags to allow driver capabilities to be interrogated */
 
-/// Constants for transfer flags
+/* Constants for transfer flags */
 #define U14TF_USEDMA          1           /* Transfer flag for use DMA      */
 #define U14TF_MULTIA          2           /* Transfer flag for multi areas  */
 #define U14TF_FIFO            4           /* for FIFO interface card        */
@@ -138,18 +138,18 @@
 #define U14TF_DIAG            256         /* Diagnostics/debug functions    */
 #define U14TF_CIRC14          512         /* Circular-mode to 1401          */
 
-/// Definitions of element sizes for DMA transfers - to allow byte-swapping
+/* Definitions of element sizes for DMA transfers - to allow byte-swapping */
 #define ESZBYTES              0           /* BYTE element size value        */
-#define ESZWORDS              1           /* WORD element size value        */
+#define ESZWORDS              1           /* unsigned short element size value        */
 #define ESZLONGS              2           /* long element size value        */
 #define ESZUNKNOWN            0           /* unknown element size value     */
 
-/// These define required access types for the debug/diagnostics function
+/* These define required access types for the debug/diagnostics function */
 #define BYTE_SIZE             1           /* 8-bit access                   */
 #define WORD_SIZE             2           /* 16-bit access                  */
 #define LONG_SIZE             3           /* 32-bit access                  */
 
-/// Stuff used by U14_GetTransfer
+/* Stuff used by U14_GetTransfer */
 #define GET_TX_MAXENTRIES  257          /* (max length / page size + 1) */
 
 #ifdef _IS_WINDOWS_
@@ -157,19 +157,19 @@
 
 typedef struct                          /* used for U14_GetTransfer results */
 {                                          /* Info on a single mapped block */
-   U14LONG physical;
-   U14LONG size;
+	U14LONG physical;
+	U14LONG size;
 } TXENTRY;
 
 typedef struct TGetTxBlock              /* used for U14_GetTransfer results */
 {                                               /* matches structure in VXD */
-   U14LONG size;
-   U14LONG linear;
-   short   seg;
-   short   reserved;
-   short   avail;                      /* number of available entries */
-   short   used;                       /* number of used entries */
-   TXENTRY entries[GET_TX_MAXENTRIES];       /* Array of mapped block info */
+	U14LONG size;
+	U14LONG linear;
+	short   seg;
+	short   reserved;
+	short   avail;                      /* number of available entries */
+	short   used;                       /* number of used entries */
+	TXENTRY entries[GET_TX_MAXENTRIES];       /* Array of mapped block info */
 } TGET_TX_BLOCK;
 
 typedef TGET_TX_BLOCK *LPGET_TX_BLOCK;
@@ -180,19 +180,19 @@ typedef TGET_TX_BLOCK *LPGET_TX_BLOCK;
 #ifdef LINUX
 typedef struct                          /* used for U14_GetTransfer results */
 {                                       /* Info on a single mapped block */
-   long long physical;
-   long     size;
+	long long physical;
+	long     size;
 } TXENTRY;
 
 typedef struct TGetTxBlock              /* used for U14_GetTransfer results */
 {                                       /* matches structure in VXD */
-   long long linear;                    /* linear address */
-   long     size;                       /* total size of the mapped area, holds id when called */
-   short    seg;                        /* segment of the address for Win16 */
-   short    reserved;
-   short    avail;                      /* number of available entries */
-   short    used;                       /* number of used entries */
-   TXENTRY  entries[GET_TX_MAXENTRIES]; /* Array of mapped block info */
+	long long linear;                    /* linear address */
+	long     size;                       /* total size of the mapped area, holds id when called */
+	short    seg;                        /* segment of the address for Win16 */
+	short    reserved;
+	short    avail;                      /* number of available entries */
+	short    used;                       /* number of used entries */
+	TXENTRY  entries[GET_TX_MAXENTRIES]; /* Array of mapped block info */
 } TGET_TX_BLOCK;
 #endif
 
@@ -200,84 +200,84 @@ typedef struct TGetTxBlock
 extern "C" {
 #endif
 
-U14API(int)   U14WhenToTimeOut(short hand);         // when to timeout in ms
-U14API(short) U14PassedTime(int iTime);             // non-zero if iTime passed
+U14API(int)   U14WhenToTimeOut(short hand);         /*  when to timeout in ms */
+U14API(short)	U14PassedTime(int iTime);             /*  non-zero if iTime passed */
 
-U14API(short) U14LastErrCode(short hand);
+U14API(short)	U14LastErrCode(short hand);
 
-U14API(short) U14Open1401(short n1401);
-U14API(short) U14Close1401(short hand);
-U14API(short) U14Reset1401(short hand);
-U14API(short) U14ForceReset(short hand);
-U14API(short) U14TypeOf1401(short hand);
-U14API(short) U14NameOf1401(short hand, char* pBuf, WORD wMax);
+U14API(short)	U14Open1401(short n1401);
+U14API(short)	U14Close1401(short hand);
+U14API(short)	U14Reset1401(short hand);
+U14API(short)	U14ForceReset(short hand);
+U14API(short)	U14TypeOf1401(short hand);
+U14API(short)	U14NameOf1401(short hand, char *pBuf, unsigned short wMax);
 
-U14API(short) U14Stat1401(short hand);
-U14API(short) U14CharCount(short hand);
-U14API(short) U14LineCount(short hand);
+U14API(short)	U14Stat1401(short hand);
+U14API(short)	U14CharCount(short hand);
+U14API(short)	U14LineCount(short hand);
 
-U14API(short) U14SendString(short hand, const char* pString);
-U14API(short) U14GetString(short hand, char* pBuffer, WORD wMaxLen);
-U14API(short) U14SendChar(short hand, char cChar);
-U14API(short) U14GetChar(short hand, char* pcChar);
+U14API(short)	U14SendString(short hand, const char *pString);
+U14API(short)	U14GetString(short hand, char *pBuffer, unsigned short wMaxLen);
+U14API(short)	U14SendChar(short hand, char cChar);
+U14API(short)	U14GetChar(short hand, char *pcChar);
 
-U14API(short) U14LdCmd(short hand, const char* command);
-U14API(DWORD) U14Ld(short hand, const char* vl, const char* str);
+U14API(short)	U14LdCmd(short hand, const char *command);
+U14API(unsigned int) U14Ld(short hand, const char *vl, const char *str);
 
-U14API(short) U14SetTransArea(short hand, WORD wArea, void *pvBuff,
-                                            DWORD dwLength, short eSz);
-U14API(short) U14UnSetTransfer(short hand, WORD wArea);
-U14API(short) U14SetTransferEvent(short hand, WORD wArea, BOOL bEvent,
-                                  BOOL bToHost, DWORD dwStart, DWORD dwLength);
-U14API(int)   U14TestTransferEvent(short hand, WORD wArea);
-U14API(int)   U14WaitTransferEvent(short hand, WORD wArea, int msTimeOut);
-U14API(short) U14GetTransfer(short hand, TGET_TX_BLOCK *pTransBlock);
+U14API(short)	U14SetTransArea(short hand, unsigned short wArea, void *pvBuff,
+					unsigned int dwLength, short eSz);
+U14API(short)	U14UnSetTransfer(short hand, unsigned short wArea);
+U14API(short)	U14SetTransferEvent(short hand, unsigned short wArea, BOOL bEvent,
+					BOOL bToHost, unsigned int dwStart, unsigned int dwLength);
+U14API(int)   U14TestTransferEvent(short hand, unsigned short wArea);
+U14API(int)   U14WaitTransferEvent(short hand, unsigned short wArea, int msTimeOut);
+U14API(short)	U14GetTransfer(short hand, TGET_TX_BLOCK *pTransBlock);
 
-U14API(short) U14ToHost(short hand, char* pAddrHost,DWORD dwSize,DWORD dw1401,
-                                                            short eSz);
-U14API(short) U14To1401(short hand, const char* pAddrHost,DWORD dwSize,DWORD dw1401,
-                                                            short eSz);
+U14API(short)	U14ToHost(short hand, char *pAddrHost, unsigned int dwSize, unsigned int dw1401,
+								short eSz);
+U14API(short)	U14To1401(short hand, const char *pAddrHost, unsigned int dwSize, unsigned int dw1401,
+								short eSz);
 
-U14API(short) U14SetCircular(short hand, WORD wArea, BOOL bToHost, void *pvBuff,
-                                         DWORD dwLength);
+U14API(short)	U14SetCircular(short hand, unsigned short wArea, BOOL bToHost, void *pvBuff,
+							unsigned int dwLength);
 
-U14API(int)   U14GetCircBlk(short hand, WORD wArea, DWORD *pdwOffs);
-U14API(int)   U14FreeCircBlk(short hand, WORD wArea, DWORD dwOffs, DWORD dwSize,
-                                         DWORD *pdwOffs);
+U14API(int)   U14GetCircBlk(short hand, unsigned short wArea, unsigned int *pdwOffs);
+U14API(int)   U14FreeCircBlk(short hand, unsigned short wArea, unsigned int dwOffs, unsigned int dwSize,
+							unsigned int *pdwOffs);
 
-U14API(short) U14StrToLongs(const char* pszBuff, U14LONG *palNums, short sMaxLongs);
-U14API(short) U14LongsFrom1401(short hand, U14LONG *palBuff, short sMaxLongs);
+U14API(short)	U14StrToLongs(const char *pszBuff, U14LONG *palNums, short sMaxLongs);
+U14API(short)	U14LongsFrom1401(short hand, U14LONG *palBuff, short sMaxLongs);
 
 U14API(void)  U14SetTimeout(short hand, int lTimeout);
 U14API(int)   U14GetTimeout(short hand);
-U14API(short) U14OutBufSpace(short hand);
+U14API(short)	U14OutBufSpace(short hand);
 U14API(int)   U14BaseAddr1401(short hand);
 U14API(int)   U14DriverVersion(short hand);
 U14API(int)   U14DriverType(short hand);
-U14API(short) U14DriverName(short hand, char* pBuf, WORD wMax);
-U14API(short) U14GetUserMemorySize(short hand, DWORD *pMemorySize);
-U14API(short) U14KillIO1401(short hand);
+U14API(short)	U14DriverName(short hand, char *pBuf, unsigned short wMax);
+U14API(short)	U14GetUserMemorySize(short hand, unsigned int *pMemorySize);
+U14API(short)	U14KillIO1401(short hand);
 
-U14API(short) U14BlkTransState(short hand);
-U14API(short) U14StateOf1401(short hand);
+U14API(short)	U14BlkTransState(short hand);
+U14API(short)	U14StateOf1401(short hand);
 
-U14API(short) U14Grab1401(short hand);
-U14API(short) U14Free1401(short hand);
-U14API(short) U14Peek1401(short hand, DWORD dwAddr, int nSize, int nRepeats);
-U14API(short) U14Poke1401(short hand, DWORD dwAddr, DWORD dwValue, int nSize, int nRepeats);
-U14API(short) U14Ramp1401(short hand, DWORD dwAddr, DWORD dwDef, DWORD dwEnable, int nSize, int nRepeats);
-U14API(short) U14RampAddr(short hand, DWORD dwDef, DWORD dwEnable, int nSize, int nRepeats);
-U14API(short) U14StopDebugLoop(short hand);
-U14API(short) U14GetDebugData(short hand, U14LONG *plValue);
+U14API(short)	U14Grab1401(short hand);
+U14API(short)	U14Free1401(short hand);
+U14API(short)	U14Peek1401(short hand, unsigned int dwAddr, int nSize, int nRepeats);
+U14API(short)	U14Poke1401(short hand, unsigned int dwAddr, unsigned int dwValue, int nSize, int nRepeats);
+U14API(short)	U14Ramp1401(short hand, unsigned int dwAddr, unsigned int dwDef, unsigned int dwEnable, int nSize, int nRepeats);
+U14API(short)	U14RampAddr(short hand, unsigned int dwDef, unsigned int dwEnable, int nSize, int nRepeats);
+U14API(short)	U14StopDebugLoop(short hand);
+U14API(short)	U14GetDebugData(short hand, U14LONG *plValue);
 
-U14API(short) U14StartSelfTest(short hand);
-U14API(short) U14CheckSelfTest(short hand, U14LONG *pData);
-U14API(short) U14TransferFlags(short hand);
-U14API(void)  U14GetErrorString(short nErr, char* pStr, WORD wMax);
+U14API(short)	U14StartSelfTest(short hand);
+U14API(short)	U14CheckSelfTest(short hand, U14LONG *pData);
+U14API(short)	U14TransferFlags(short hand);
+U14API(void)  U14GetErrorString(short nErr, char *pStr, unsigned short wMax);
 U14API(int)   U14MonitorRev(short hand);
 U14API(void)  U14CloseAll(void);
 
-U14API(short) U14WorkingSet(DWORD dwMinKb, DWORD dwMaxKb);
+U14API(short)	U14WorkingSet(unsigned int dwMinKb, unsigned int dwMaxKb);
 U14API(int)   U14InitLib(void);
 
 #ifdef __cplusplus
@@ -285,3 +285,4 @@ U14API(int)   U14InitLib(void);
 #endif
 
 #endif /* End of ifndef __USE1401_H__ */
+
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ced1401/use14_ioc.h linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/use14_ioc.h
--- linux-libre-3.10-gnu/drivers/staging/ced1401/use14_ioc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/use14_ioc.h	2013-08-25 20:43:22.000000000 -0400
@@ -19,283 +19,282 @@
 ** The IOCTL function codes from 0x80 to 0xFF are for developer use.
 */
 #define  FILE_DEVICE_CED1401    0x8001
-#define  FNNUMBASE              0x800
+						FNNUMBASE              0x800
 
-#define  U14_OPEN1401            CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE,               \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_OPEN1401            CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE,               \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_CLOSE1401           CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+1,             \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_CLOSE1401           CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+1,             \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_SENDSTRING          CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+2,             \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_SENDSTRING          CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+2,             \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_RESET1401           CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+3,             \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_RESET1401           CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+3,             \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_GETCHAR             CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+4,             \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_GETCHAR             CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+4,             \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_SENDCHAR            CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+5,             \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_SENDCHAR            CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+5,             \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_STAT1401            CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+6,             \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_STAT1401            CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+6,             \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_LINECOUNT           CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+7,             \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_LINECOUNT           CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+7,             \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_GETSTRING           CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+8,             \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_GETSTRING           CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+8,             \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_REGCALLBACK         CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+9,             \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_REGCALLBACK         CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+9,             \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_GETMONITORBUF       CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+10,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_GETMONITORBUF       CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+10,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_SETTRANSFER         CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+11,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_SETTRANSFER         CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+11,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_UNSETTRANSFER       CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+12,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_UNSETTRANSFER       CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+12,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_SETTRANSEVENT       CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+13,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_SETTRANSEVENT       CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+13,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_GETOUTBUFSPACE      CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+14,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_GETOUTBUFSPACE      CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+14,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_GETBASEADDRESS      CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+15,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_GETBASEADDRESS      CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+15,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_GETDRIVERREVISION   CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+16,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_GETDRIVERREVISION   CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+16,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_GETTRANSFER         CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+17,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_GETTRANSFER         CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+17,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_KILLIO1401          CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+18,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_KILLIO1401          CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+18,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_BLKTRANSSTATE       CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+19,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_BLKTRANSSTATE       CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+19,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_BYTECOUNT           CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+20,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_BYTECOUNT           CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+20,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_ZEROBLOCKCOUNT      CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+21,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_ZEROBLOCKCOUNT      CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+21,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_STOPCIRCULAR        CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+22,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_STOPCIRCULAR        CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+22,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_STATEOF1401         CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+23,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_STATEOF1401         CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+23,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_REGISTERS1401       CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+24,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_REGISTERS1401       CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+24,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_GRAB1401            CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+25,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_GRAB1401            CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+25,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_FREE1401            CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+26,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_FREE1401            CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+26,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_STEP1401            CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+27,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_STEP1401            CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+27,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_SET1401REGISTERS    CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+28,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_SET1401REGISTERS    CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+28,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_STEPTILL1401        CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+29,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_STEPTILL1401        CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+29,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_SETORIN             CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+30,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_SETORIN             CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+30,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_STARTSELFTEST       CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+31,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_STARTSELFTEST       CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+31,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_CHECKSELFTEST       CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+32,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_CHECKSELFTEST       CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+32,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_TYPEOF1401          CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+33,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_TYPEOF1401          CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+33,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_TRANSFERFLAGS       CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+34,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_TRANSFERFLAGS       CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+34,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_DBGPEEK             CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+35,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_DBGPEEK             CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+35,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_DBGPOKE             CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+36,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_DBGPOKE             CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+36,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_DBGRAMPDATA         CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+37,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_DBGRAMPDATA         CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+37,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_DBGRAMPADDR         CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+38,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_DBGRAMPADDR         CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+38,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_DBGGETDATA          CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+39,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_DBGGETDATA          CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+39,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_DBGSTOPLOOP         CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+40,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_DBGSTOPLOOP         CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+40,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_FULLRESET           CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+41,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_FULLRESET           CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+41,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_SETCIRCULAR         CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+42,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_SETCIRCULAR         CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+42,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_GETCIRCBLK          CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+43,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_GETCIRCBLK          CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+43,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-#define  U14_FREECIRCBLK         CTL_CODE( FILE_DEVICE_CED1401,     \
-                                           FNNUMBASE+44,            \
-                                           METHOD_BUFFERED,         \
-                                           FILE_ANY_ACCESS)
+#define  U14_FREECIRCBLK         CTL_CODE(FILE_DEVICE_CED1401,     \
+						FNNUMBASE+44,            \
+						METHOD_BUFFERED,         \
+						FILE_ANY_ACCESS)
 
-//--------------- Structures that are shared with the driver -------------
+/*--------------- Structures that are shared with the driver ------------- */
 #pragma pack(1)
 
 typedef struct                  /* used for get/set standard 1401 registers */
 {
-   short   sPC;
-   char    A;
-   char    X;
-   char    Y;
-   char    stat;
-   char    rubbish;
+	short   sPC;
+	char    A;
+	char    X;
+	char    Y;
+	char    stat;
+	char    rubbish;
 } T1401REGISTERS;
 
 typedef union     /* to communicate with 1401 driver status & control funcs */
 {
-   char           chrs[22];
-   short          ints[11];
-   long           longs[5];
-   T1401REGISTERS registers;
+	char           chrs[22];
+	short          ints[11];
+	long           longs[5];
+	T1401REGISTERS registers;
 } TCSBLOCK;
 
 typedef TCSBLOCK*  LPTCSBLOCK;
 
-typedef struct paramBlk
-{
-    short       sState;
-    TCSBLOCK    csBlock;
+typedef struct paramBlk {
+	 short       sState;
+	 TCSBLOCK    csBlock;
 } PARAMBLK;
 
 typedef PARAMBLK*   PPARAMBLK;
 
 typedef struct TransferDesc          /* Structure and type for SetTransArea */
 {
-   WORD        wArea;            /* number of transfer area to set up       */
-   void FAR *  lpvBuff;          /* address of transfer area                */
-   DWORD       dwLength;         /* length of area to set up                */
-   short       eSize;            /* size to move (for swapping on MAC)      */
+	unsigned short        wArea;            /* number of transfer area to set up       */
+	void FAR *lpvBuff;          /* address of transfer area                */
+	unsigned int       dwLength;         /* length of area to set up                */
+	short       eSize;            /* size to move (for swapping on MAC)      */
 } TRANSFERDESC;
 
-typedef TRANSFERDESC FAR *    LPTRANSFERDESC;
+typedef TRANSFERDESC FAR *LPTRANSFERDESC;
 
 /* This is the structure used to set up a transfer area */
 typedef struct VXTransferDesc    /* use1401.c and use1432x.x use only       */
 {
-   WORD        wArea;            /* number of transfer area to set up       */
-   WORD        wAddrSel;         /* 16 bit selector for area                */
-   DWORD       dwAddrOfs;        /* 32 bit offset for area start            */
-   DWORD       dwLength;         /* length of area to set up                */
+	unsigned short        wArea;            /* number of transfer area to set up       */
+	unsigned short        wAddrSel;         /* 16 bit selector for area                */
+	unsigned int       dwAddrOfs;        /* 32 bit offset for area start            */
+	unsigned int       dwLength;         /* length of area to set up                */
 } VXTRANSFERDESC;
 
 #pragma pack()
 
-#endif
\ No newline at end of file
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ced1401/userspace/use1401.c linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/userspace/use1401.c
--- linux-libre-3.10-gnu/drivers/staging/ced1401/userspace/use1401.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ced1401/userspace/use1401.c	2013-08-25 20:43:22.000000000 -0400
@@ -36,7 +36,7 @@
 ** Under Windows 9x and NT, Use1401 uses DeviceIoControl to get access to
 ** the 1401 driver. This has parameters for the device handle, the function
 ** code, an input pointer and byte count, an output pointer and byte count
-** and a pointer to a DWORD to hold the output byte count. Note that input
+** and a pointer to a unsigned int to hold the output byte count. Note that input
 ** and output are from the point-of-view of the driver, so the output stuff
 ** is used to read values from the 1401, not send to the 1401. The use of
 ** these parameters varies with the function in use and the operating
@@ -250,7 +250,7 @@ static int iAttached = 0;
 static HANDLE aHand1401[MAX1401] = {0};         // handles for 1401s
 static HANDLE aXferEvent[MAX1401] = {0};        // transfer events for the 1401s
 static LPVOID apAreas[MAX1401][MAX_TRANSAREAS]; // Locked areas
-static DWORD  auAreas[MAX1401][MAX_TRANSAREAS]; // Size of locked areas
+static unsigned int  auAreas[MAX1401][MAX_TRANSAREAS]; // Size of locked areas
 static BOOL   bWindows9x = FALSE;               // if we are Windows 95 or better
 #ifdef _WIN64
 #define USE_NT_DIOC(ind) TRUE
@@ -276,8 +276,8 @@ static int aHand1401[MAX1401] = {0};
 typedef struct CmdHead          // defines header block on command
 {                               // for PC commands
    char   acBasic[5];           // BASIC information - needed to align things
-   WORD   wBasicSz;             // size as seen by BASIC
-   WORD   wCmdSize;             // size of the following info
+   unsigned short   wBasicSz;             // size as seen by BASIC
+   unsigned short   wCmdSize;             // size of the following info
 } __packed CMDHEAD;
 #pragma pack()                  // back to normal
 
@@ -311,7 +311,7 @@ static short CheckHandle(short h)
 ****************************************************************************/
 static short U14Status1401(short sHand, LONG lCode, TCSBLOCK* pBlk)
 {
-    DWORD dwBytes = 0;
+    unsigned int dwBytes = 0;
 
     if ((sHand < 0) || (sHand >= MAX1401))  /* Check parameters */
         return U14ERR_BADHAND;
@@ -345,7 +345,7 @@ static short U14Status1401(short sHand,
 ****************************************************************************/
 static short U14Control1401(short sHand, LONG lCode, TCSBLOCK* pBlk)
 {
-    DWORD dwBytes = 0;
+    unsigned int dwBytes = 0;
 
     if ((sHand < 0) || (sHand >= MAX1401))              /* Check parameters */
         return U14ERR_BADHAND;
@@ -455,7 +455,7 @@ static void TranslateString(char* pStr)
 ****************************************************************************/
 U14API(short) U14StrToLongs(const char* pszBuff, U14LONG *palNums, short sMaxLongs)
 {
-    WORD wChInd = 0;                // index into source
+    unsigned short wChInd = 0;                // index into source
     short sLgInd = 0;               // index into result longs
 
     while (pszBuff[wChInd] &&       // until we get to end of string...
@@ -681,7 +681,7 @@ U14API(int) U14DriverType(short hand)
 ** U14DriverName
 ** Returns the driver type as 3 character (ISA, PCI, USB or HSS))
 ****************************************************************************/
-U14API(short) U14DriverName(short hand, char* pBuf, WORD wMax)
+U14API(short) U14DriverName(short hand, char* pBuf, unsigned short wMax)
 {
     char* pName;
     *pBuf = 0;                             // Start off with a blank string
@@ -779,7 +779,7 @@ U14API(short)  U14Free1401(short hand)
 ** is called. After the peek is done, use U14GetDebugData to retrieve
 ** the results of the peek.
 ****************************************************************************/
-U14API(short) U14Peek1401(short hand, DWORD dwAddr, int nSize, int nRepeats)
+U14API(short) U14Peek1401(short hand, unsigned int dwAddr, int nSize, int nRepeats)
 {
     short sErr = CheckHandle(hand);
     if (sErr == U14ERR_NOERROR)
@@ -813,7 +813,7 @@ U14API(short) U14Peek1401(short hand, DW
 ** If lRepeats is zero, the loop will continue until U14StopDebugLoop
 ** is called.
 ****************************************************************************/
-U14API(short) U14Poke1401(short hand, DWORD dwAddr, DWORD dwValue,
+U14API(short) U14Poke1401(short hand, unsigned int dwAddr, unsigned int dwValue,
                                       int nSize, int nRepeats)
 {
     short sErr = CheckHandle(hand);
@@ -849,7 +849,7 @@ U14API(short) U14Poke1401(short hand, DW
 ** DESCRIPTION  Cause the 1401 to loop, writing a ramp to a location.
 ** If lRepeats is zero, the loop will continue until U14StopDebugLoop.
 ****************************************************************************/
-U14API(short) U14Ramp1401(short hand, DWORD dwAddr, DWORD dwDef, DWORD dwEnable,
+U14API(short) U14Ramp1401(short hand, unsigned int dwAddr, unsigned int dwDef, unsigned int dwEnable,
                                       int nSize, int nRepeats)
 {
     short sErr = CheckHandle(hand);
@@ -887,7 +887,7 @@ U14API(short) U14Ramp1401(short hand, DW
 ** DESCRIPTION  Cause the 1401 to loop, reading from a ramping location.
 ** If lRepeats is zero, the loop will continue until U14StopDebugLoop
 ****************************************************************************/
-U14API(short) U14RampAddr(short hand, DWORD dwDef, DWORD dwEnable,
+U14API(short) U14RampAddr(short hand, unsigned int dwDef, unsigned int dwEnable,
                                       int nSize, int nRepeats)
 {
     short sErr = CheckHandle(hand);
@@ -1024,7 +1024,7 @@ U14API(short) U14CheckSelfTest(short han
 /****************************************************************************
 ** U14GetUserMemorySize
 ****************************************************************************/
-U14API(short) U14GetUserMemorySize(short hand, DWORD *pMemorySize)
+U14API(short) U14GetUserMemorySize(short hand, unsigned int *pMemorySize)
 {
     // The original 1401 used a different command for getting the size
     short sErr = U14SendString(hand, (asType1401[hand] == U14TYPE1401) ? "MEMTOP;" : "MEMTOP,?;");
@@ -1061,7 +1061,7 @@ U14API(short) U14TypeOf1401(short hand)
 ** U14NameOf1401
 ** Returns the type of the 1401 as a string, blank if unknown
 ****************************************************************************/
-U14API(short) U14NameOf1401(short hand, char* pBuf, WORD wMax)
+U14API(short) U14NameOf1401(short hand, char* pBuf, unsigned short wMax)
 {
     short sErr = CheckHandle(hand);
     if (sErr == U14ERR_NOERROR)
@@ -1207,7 +1207,7 @@ static short U14TryToOpen(int n1401, lon
 {
     short sErr = U14ERR_NOERROR;
     HANDLE hDevice = INVALID_HANDLE_VALUE;
-    DWORD dwErr = 0;
+    unsigned int dwErr = 0;
     int nFirst, nLast, nDev = 0;        /* Used for the search for a 1401 */
     BOOL bOldName = FALSE;               /* start by looking for a modern driver */
 
@@ -1262,7 +1262,7 @@ static short U14TryToOpen(int n1401, lon
             }
             else
             {
-                DWORD dwe = GetLastError();     /* Get error code otherwise */
+                unsigned int dwe = GetLastError();     /* Get error code otherwise */
                 if ((dwe != ERROR_FILE_NOT_FOUND) || (dwErr == 0))
                     dwErr = dwe;                /* Ignore repeats of 'not found' */
             }
@@ -1454,7 +1454,7 @@ U14API(short) U14Close1401(short hand)
         U14Reset1401(hand);                     // in case an active transfer running
         for (j = 0; j < MAX_TRANSAREAS; ++j)    // Locate locked areas
             if (iAreaMask & (1 << j))           // And kill off any transfers
-                U14UnSetTransfer(hand, (WORD)j);
+                U14UnSetTransfer(hand, (unsigned short)j);
     }
 
 #ifdef _IS_WINDOWS_
@@ -1581,7 +1581,7 @@ U14API(short) U14SendString(short hand,
         if (bSpaceToSend)
         {
             PARAMBLK    rData;
-            DWORD       dwBytes;
+            unsigned int       dwBytes;
             char        tstr[MAXSTRLEN+5];          /* Buffer for chars */
 
             if ((hand < 0) || (hand >= MAX1401))
@@ -1592,18 +1592,18 @@ U14API(short) U14SendString(short hand,
 #ifndef _WIN64
                 if (!USE_NT_DIOC(hand))             /* Using WIN 95 driver access? */
                 {
-                    int iOK = DeviceIoControl(aHand1401[hand], (DWORD)U14_SENDSTRING,
+                    int iOK = DeviceIoControl(aHand1401[hand], (unsigned int)U14_SENDSTRING,
                                     NULL, 0, tstr, nChars,
                                     &dwBytes, NULL);
                     if (iOK)
-                        sErr = (dwBytes >= (DWORD)nChars) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS;
+                        sErr = (dwBytes >= (unsigned int)nChars) ? U14ERR_NOERROR : U14ERR_DRIVCOMMS;
                     else
                         sErr = (short)GetLastError();
                 }
                 else
 #endif
                 {
-                    int iOK = DeviceIoControl(aHand1401[hand],(DWORD)U14_SENDSTRING,
+                    int iOK = DeviceIoControl(aHand1401[hand],(unsigned int)U14_SENDSTRING,
                                     tstr, nChars,
                                     &rData,sizeof(PARAMBLK),&dwBytes,NULL);
                     if (iOK && (dwBytes >= sizeof(PARAMBLK)))
@@ -1697,7 +1697,7 @@ U14API(short) U14SendChar(short hand, ch
 **          error code. Any error from the device causes us to set up for
 **          a full reset.
 ****************************************************************************/
-U14API(short) U14GetString(short hand, char* pBuffer, WORD wMaxLen)
+U14API(short) U14GetString(short hand, char* pBuffer, unsigned short wMaxLen)
 {
     short sErr = CheckHandle(hand);
     if (sErr != U14ERR_NOERROR)             // If an error...
@@ -1726,8 +1726,8 @@ U14API(short) U14GetString(short hand, c
         {
             if (asLastRetCode[hand] == U14ERR_NOERROR)     /* all ok so far */
             {
-                DWORD       dwBytes = 0;
-                *((WORD *)pBuffer) = wMaxLen;       /* set up length */
+                unsigned int       dwBytes = 0;
+                *((unsigned short *)pBuffer) = wMaxLen;       /* set up length */
 #ifndef _WIN64
                 if (!USE_NT_DIOC(hand))             /* Win 95 DIOC here ? */
                 {
@@ -1737,9 +1737,9 @@ U14API(short) U14GetString(short hand, c
                     if (wMaxLen > MAXSTRLEN)        /* Truncate length */
                         wMaxLen = MAXSTRLEN;    
 
-                    *((WORD *)tstr) = wMaxLen;      /* set len */
+                    *((unsigned short *)tstr) = wMaxLen;      /* set len */
 
-                    iOK = DeviceIoControl(aHand1401[hand],(DWORD)U14_GETSTRING,
+                    iOK = DeviceIoControl(aHand1401[hand],(unsigned int)U14_GETSTRING,
                                     NULL, 0, tstr, wMaxLen+sizeof(short),
                                     &dwBytes, NULL);
                     if (iOK)                        /* Device IO control OK ? */
@@ -1768,7 +1768,7 @@ U14API(short) U14GetString(short hand, c
                         char* pMem = (char*)GlobalLock(hMem);
                         if (pMem)
                         {
-                            int iOK = DeviceIoControl(aHand1401[hand],(DWORD)U14_GETSTRING,
+                            int iOK = DeviceIoControl(aHand1401[hand],(unsigned int)U14_GETSTRING,
                                             NULL, 0, pMem, wMaxLen+sizeof(short),
                                             &dwBytes, NULL);
                             if (iOK)                /* Device IO control OK ? */
@@ -1946,7 +1946,7 @@ U14API(short) U14LineCount(short hand)
 **       other functions after getting an error and before using
 **       this function.
 ****************************************************************************/
-U14API(void)  U14GetErrorString(short nErr, char* pStr, WORD wMax)
+U14API(void)  U14GetErrorString(short nErr, char* pStr, unsigned short wMax)
 {
     char    wstr[150];
 
@@ -2105,7 +2105,7 @@ U14API(void)  U14GetErrorString(short nE
         break;
 
     }
-    if ((WORD)strlen(wstr) >= wMax-1)  /* Check for string being too long */
+    if ((unsigned short)strlen(wstr) >= wMax-1)  /* Check for string being too long */
         wstr[wMax-1] = 0;                          /* and truncate it if so */
     strcpy(pStr, wstr);                       /* Return the error string */
 }
@@ -2120,8 +2120,8 @@ U14API(short) U14GetTransfer(short hand,
 #ifdef _IS_WINDOWS_
     if (sErr == U14ERR_NOERROR)
     { 
-        DWORD dwBytes = 0;
-        BOOL bOK = DeviceIoControl(aHand1401[hand], (DWORD)U14_GETTRANSFER, NULL, 0, pTransBlock,
+        unsigned int dwBytes = 0;
+        BOOL bOK = DeviceIoControl(aHand1401[hand], (unsigned int)U14_GETTRANSFER, NULL, 0, pTransBlock,
                               sizeof(TGET_TX_BLOCK), &dwBytes, NULL);
     
         if (bOK && (dwBytes >= sizeof(TGET_TX_BLOCK)))
@@ -2145,12 +2145,12 @@ U14API(short) U14GetTransfer(short hand,
 //     1 unable to access process (insufficient rights?)
 //     2 unable to read process working set
 //     3 unable to set process working set - bad parameters?
-U14API(short) U14WorkingSet(DWORD dwMinKb, DWORD dwMaxKb)
+U14API(short) U14WorkingSet(unsigned int dwMinKb, unsigned int dwMaxKb)
 {
 #ifdef _IS_WINDOWS_
     short sRetVal = 0;                      // 0 means all is OK
     HANDLE hProcess;
-    DWORD dwVer = GetVersion();
+    unsigned int dwVer = GetVersion();
 	if (dwVer & 0x80000000)                 // is this not NT?
         return 0;                           // then give up right now
 
@@ -2164,8 +2164,8 @@ U14API(short) U14WorkingSet(DWORD dwMinK
         SIZE_T dwMinSize,dwMaxSize;
         if (GetProcessWorkingSetSize(hProcess, &dwMinSize, &dwMaxSize))
         {
-            DWORD dwMin = dwMinKb << 10;    // convert from kb to bytes
-            DWORD dwMax = dwMaxKb << 10;
+            unsigned int dwMin = dwMinKb << 10;    // convert from kb to bytes
+            unsigned int dwMax = dwMaxKb << 10;
 
             // if we get here, we have managed to read the current size
             if (dwMin > dwMinSize)          // need to change sizes?
@@ -2200,7 +2200,7 @@ U14API(short) U14WorkingSet(DWORD dwMinK
 ** U14UnSetTransfer  Cancels a transfer area
 ** wArea    The index of a block previously used in by SetTransfer
 *****************************************************************************/
-U14API(short) U14UnSetTransfer(short hand, WORD wArea)
+U14API(short) U14UnSetTransfer(short hand, unsigned short wArea)
 {
     short sErr = CheckHandle(hand);
 #ifdef _IS_WINDOWS_
@@ -2223,13 +2223,13 @@ U14API(short) U14UnSetTransfer(short han
 
 /****************************************************************************
 ** U14SetTransArea      Sets an area up to be used for transfers
-** WORD  wArea     The area number to set up
+** unsigned short  wArea     The area number to set up
 ** void *pvBuff    The address of the buffer for the data.
-** DWORD dwLength  The length of the buffer for the data
+** unsigned int dwLength  The length of the buffer for the data
 ** short eSz       The element size (used for byte swapping on the Mac)
 ****************************************************************************/
-U14API(short) U14SetTransArea(short hand, WORD wArea, void *pvBuff,
-                                          DWORD dwLength, short eSz)
+U14API(short) U14SetTransArea(short hand, unsigned short wArea, void *pvBuff,
+                                          unsigned int dwLength, short eSz)
 {
     TRANSFERDESC td;
     short sErr = CheckHandle(hand);
@@ -2254,7 +2254,7 @@ U14API(short) U14SetTransArea(short hand
 #ifndef _WIN64
     if (!USE_NT_DIOC(hand))                         /* Use Win 9x DIOC? */
     {
-        DWORD dwBytes;
+        unsigned int dwBytes;
         VXTRANSFERDESC vxDesc;                      /* Structure to pass to VXD */
         vxDesc.wArea = wArea;                       /* Copy across simple params */
         vxDesc.dwLength = dwLength;
@@ -2264,10 +2264,10 @@ U14API(short) U14SetTransArea(short hand
             sErr = U14ERR_DRIVTOOOLD;
         else
         {
-            vxDesc.dwAddrOfs = (DWORD)pvBuff;       /* 32 bit offset */
+            vxDesc.dwAddrOfs = (unsigned int)pvBuff;       /* 32 bit offset */
             vxDesc.wAddrSel  = 0;
 
-            if (DeviceIoControl(aHand1401[hand], (DWORD)U14_SETTRANSFER,
+            if (DeviceIoControl(aHand1401[hand], (unsigned int)U14_SETTRANSFER,
                                 pvBuff,dwLength,    /* Will translate pointer */
                                 &vxDesc,sizeof(VXTRANSFERDESC),
                                 &dwBytes,NULL))
@@ -2285,13 +2285,13 @@ U14API(short) U14SetTransArea(short hand
 #endif
     {
         PARAMBLK rWork;
-        DWORD dwBytes;
+        unsigned int dwBytes;
         td.wArea = wArea;     /* Pure NT - put data into struct */
         td.lpvBuff = pvBuff;
         td.dwLength = dwLength;
         td.eSize = 0;                // Dummy element size
 
-        if (DeviceIoControl(aHand1401[hand],(DWORD)U14_SETTRANSFER,
+        if (DeviceIoControl(aHand1401[hand],(unsigned int)U14_SETTRANSFER,
                             &td,sizeof(TRANSFERDESC),
                             &rWork,sizeof(PARAMBLK),&dwBytes,NULL))
         {
@@ -2344,8 +2344,8 @@ U14API(short) U14SetTransArea(short hand
 ** Returns 1 if an event handle exists, 0 if all OK and no event handle or
 ** a negative code for an error.
 ****************************************************************************/
-U14API(short) U14SetTransferEvent(short hand, WORD wArea, BOOL bEvent,
-                                  BOOL bToHost, DWORD dwStart, DWORD dwLength)
+U14API(short) U14SetTransferEvent(short hand, unsigned short wArea, BOOL bEvent,
+                                  BOOL bToHost, unsigned int dwStart, unsigned int dwLength)
 {
 #ifdef _IS_WINDOWS_
     TCSBLOCK csBlock;
@@ -2416,7 +2416,7 @@ U14API(short) U14SetTransferEvent(short
 ** Would a U14WaitTransferEvent() call return immediately? return 1 if so,
 ** 0 if not or a negative code if a problem.
 ****************************************************************************/
-U14API(int) U14TestTransferEvent(short hand, WORD wArea)
+U14API(int) U14TestTransferEvent(short hand, unsigned short wArea)
 {
 #ifdef _IS_WINDOWS_
     int iErr = CheckHandle(hand);
@@ -2441,7 +2441,7 @@ U14API(int) U14TestTransferEvent(short h
 ** Returns   If no event handle then return immediately. Else return 1 if
 **           timed out or 0=event, and a negative code if a problem.
 ****************************************************************************/
-U14API(int) U14WaitTransferEvent(short hand, WORD wArea, int msTimeOut)
+U14API(int) U14WaitTransferEvent(short hand, unsigned short wArea, int msTimeOut)
 {
 #ifdef _IS_WINDOWS_
     int iErr = CheckHandle(hand);
@@ -2466,13 +2466,13 @@ U14API(int) U14WaitTransferEvent(short h
 
 /****************************************************************************
 ** U14SetCircular    Sets an area up for circular DMA transfers
-** WORD  wArea          The area number to set up
+** unsigned short  wArea          The area number to set up
 ** BOOL  bToHost        Sets the direction of data transfer
 ** void *pvBuff        The address of the buffer for the data
-** DWORD dwLength       The length of the buffer for the data
+** unsigned int dwLength       The length of the buffer for the data
 ****************************************************************************/
-U14API(short) U14SetCircular(short hand, WORD wArea, BOOL bToHost,
-									void *pvBuff, DWORD dwLength)
+U14API(short) U14SetCircular(short hand, unsigned short wArea, BOOL bToHost,
+									void *pvBuff, unsigned int dwLength)
 {
     short sErr = CheckHandle(hand);
     if (sErr != U14ERR_NOERROR)
@@ -2495,14 +2495,14 @@ U14API(short) U14SetCircular(short hand,
     else
     {
         PARAMBLK rWork;
-        DWORD dwBytes;
+        unsigned int dwBytes;
         TRANSFERDESC txDesc;
         txDesc.wArea = wArea;             /* Pure NT - put data into struct */
         txDesc.lpvBuff = pvBuff;
         txDesc.dwLength = dwLength;
         txDesc.eSize = (short)bToHost;       /* Use this for direction flag */
    
-        if (DeviceIoControl(aHand1401[hand],(DWORD)U14_SETCIRCULAR,
+        if (DeviceIoControl(aHand1401[hand],(unsigned int)U14_SETCIRCULAR,
                            &txDesc, sizeof(TRANSFERDESC),
                            &rWork, sizeof(PARAMBLK),&dwBytes,NULL))
         {
@@ -2542,7 +2542,7 @@ U14API(short) U14SetCircular(short hand,
 ** Function  GetCircBlk returns the size (& start offset) of the next
 **           available block of circular data.
 ****************************************************************************/
-U14API(int) U14GetCircBlk(short hand, WORD wArea, DWORD *pdwOffs)
+U14API(int) U14GetCircBlk(short hand, unsigned short wArea, unsigned int *pdwOffs)
 {
     int lErr = CheckHandle(hand);
     if (lErr != U14ERR_NOERROR)
@@ -2555,10 +2555,10 @@ U14API(int) U14GetCircBlk(short hand, WO
 #ifdef _IS_WINDOWS_
         PARAMBLK rWork;
         TCSBLOCK csBlock;
-        DWORD dwBytes;
+        unsigned int dwBytes;
         csBlock.longs[0] = wArea;               // Area number into control block
         rWork.sState = U14ERR_DRIVCOMMS;
-        if (DeviceIoControl(aHand1401[hand], (DWORD)U14_GETCIRCBLK, &csBlock, sizeof(TCSBLOCK), &rWork, sizeof(PARAMBLK), &dwBytes, NULL) &&
+        if (DeviceIoControl(aHand1401[hand], (unsigned int)U14_GETCIRCBLK, &csBlock, sizeof(TCSBLOCK), &rWork, sizeof(PARAMBLK), &dwBytes, NULL) &&
            (dwBytes >= sizeof(PARAMBLK)))
             lErr = rWork.sState;
         else
@@ -2591,8 +2591,8 @@ U14API(int) U14GetCircBlk(short hand, WO
 **           resuse for circular transfers and returns the size (& start
 **           offset) of the next available block of circular data.
 ****************************************************************************/
-U14API(int) U14FreeCircBlk(short hand, WORD wArea, DWORD dwOffs, DWORD dwSize,
-                                        DWORD *pdwOffs)
+U14API(int) U14FreeCircBlk(short hand, unsigned short wArea, unsigned int dwOffs, unsigned int dwSize,
+                                        unsigned int *pdwOffs)
 {
     int lErr = CheckHandle(hand);
     if (lErr != U14ERR_NOERROR)
@@ -2603,12 +2603,12 @@ U14API(int) U14FreeCircBlk(short hand, W
 #ifdef _IS_WINDOWS_
         PARAMBLK rWork;
         TCSBLOCK csBlock;
-        DWORD dwBytes;
+        unsigned int dwBytes;
         csBlock.longs[0] = wArea;               // Area number into control block
         csBlock.longs[1] = dwOffs;
         csBlock.longs[2] = dwSize;
         rWork.sState = U14ERR_DRIVCOMMS;
-        if (DeviceIoControl(aHand1401[hand], (DWORD)U14_FREECIRCBLK, &csBlock, sizeof(TCSBLOCK),
+        if (DeviceIoControl(aHand1401[hand], (unsigned int)U14_FREECIRCBLK, &csBlock, sizeof(TCSBLOCK),
                            &rWork, sizeof(PARAMBLK), &dwBytes, NULL) &&
            (dwBytes >= sizeof(PARAMBLK)))
            lErr = rWork.sState;
@@ -2647,7 +2647,7 @@ U14API(int) U14FreeCircBlk(short hand, W
 ** which it should be to get a pointer
 *****************************************************************************/
 static short Transfer(short hand, BOOL bTo1401, char* pData,
-                       DWORD dwSize, DWORD dw1401, short eSz)
+                       unsigned int dwSize, unsigned int dw1401, short eSz)
 {
     char strcopy[MAXSTRLEN+1];          // to hold copy of work string
     short sResult = U14SetTransArea(hand, 0, (void *)pData, dwSize, eSz);
@@ -2670,8 +2670,8 @@ static short Transfer(short hand, BOOL b
 /****************************************************************************
 ** Function  ToHost transfers data into the host from the 1401
 ****************************************************************************/
-U14API(short) U14ToHost(short hand, char* pAddrHost, DWORD dwSize,
-                                            DWORD dw1401, short eSz)
+U14API(short) U14ToHost(short hand, char* pAddrHost, unsigned int dwSize,
+                                            unsigned int dw1401, short eSz)
 {
     short sErr = CheckHandle(hand);
     if ((sErr == U14ERR_NOERROR) && dwSize) // TOHOST is a constant
@@ -2682,8 +2682,8 @@ U14API(short) U14ToHost(short hand, char
 /****************************************************************************
 ** Function  To1401 transfers data into the 1401 from the host
 ****************************************************************************/
-U14API(short) U14To1401(short hand, const char* pAddrHost,DWORD dwSize,
-                                    DWORD dw1401, short eSz)
+U14API(short) U14To1401(short hand, const char* pAddrHost,unsigned int dwSize,
+                                    unsigned int dw1401, short eSz)
 {
     short sErr = CheckHandle(hand);
     if ((sErr == U14ERR_NOERROR) && dwSize) // TO1401 is a constant
@@ -2707,7 +2707,7 @@ U14API(short) U14To1401(short hand, cons
 #define file_close(h)   close(h)
 #define file_seek(h, pos) lseek(h, pos, SEEK_SET) 
 #define file_read(h, buffer, size) (read(h, buffer, size) == (ssize_t)size)
-static DWORD GetModuleFileName(void* dummy, char* buffer, int max)
+static unsigned int GetModuleFileName(void* dummy, char* buffer, int max)
 {
     // The following works for Linux systems with a /proc file system.
     char szProcPath[32];
@@ -2766,7 +2766,7 @@ U14API(short) U14LdCmd(short hand, const
     // application was run from.
     if (!bGotIt)                            // Still not got it?
     {
-        DWORD dwLen = GetModuleFileName(NULL, filnam, FNSZ); // Get app path
+        unsigned int dwLen = GetModuleFileName(NULL, filnam, FNSZ); // Get app path
         if (dwLen > 0)                      // and use it as path if found
         {
             char* pStr = strrchr(filnam, PATHSEP);    // Point to last separator
@@ -2821,7 +2821,7 @@ U14API(short) U14LdCmd(short hand, const
                 file_seek(iFHandle, sizeof(CMDHEAD));
                 if (file_read(iFHandle, pMem, (UINT)nComSize))
                 {
-                    sErr = U14SetTransArea(hand, 0, (void *)pMem, (DWORD)nComSize, ESZBYTES);
+                    sErr = U14SetTransArea(hand, 0, (void *)pMem, (unsigned int)nComSize, ESZBYTES);
                     if (sErr == U14ERR_NOERROR)
                     {
                         sprintf(strcopy, "CLOAD,0,$%X;", (int)nComSize);
@@ -2858,9 +2858,9 @@ U14API(short) U14LdCmd(short hand, const
 ** Returns NOERROR code or a long with error in lo word and index of
 ** command that failed in high word
 ****************************************************************************/
-U14API(DWORD) U14Ld(short hand, const char* vl, const char* str)
+U14API(unsigned int) U14Ld(short hand, const char* vl, const char* str)
 {
-    DWORD dwIndex = 0;              // index to current command
+    unsigned int dwIndex = 0;              // index to current command
     long lErr = U14ERR_NOERROR;     // what the error was that went wrong
     char strcopy[MAXSTRLEN+1];      // stores unmodified str parameter
     char szFExt[8];                 // The command file extension
@@ -2939,7 +2939,7 @@ U14API(DWORD) U14Ld(short hand, const ch
         return lErr;
     }
     else
-        return ((dwIndex<<16) | ((DWORD)lErr & 0x0000FFFF));
+        return ((dwIndex<<16) | ((unsigned int)lErr & 0x0000FFFF));
 }
 
 // Initialise the library (if not initialised) and return the library version
@@ -2951,7 +2951,7 @@ U14API(int) U14InitLib(void)
         int i;
 #ifdef _IS_WINDOWS_
         int j;
-        DWORD   dwVersion = GetVersion();
+        unsigned int   dwVersion = GetVersion();
         bWindows9x = FALSE;                  // Assume not Win9x
 
         if (dwVersion & 0x80000000)                 // if not windows NT
@@ -2993,12 +2993,12 @@ U14API(int) U14InitLib(void)
 #ifdef _IS_WINDOWS_
 #ifndef U14_NOT_DLL
 /****************************************************************************
-** FUNCTION: DllMain(HANDLE, DWORD, LPVOID)
+** FUNCTION: DllMain(HANDLE, unsigned int, LPVOID)
 ** LibMain is called by Windows when the DLL is initialized, Thread Attached,
 ** and other times. Refer to SDK documentation, as to the different ways this
 ** may be called.
 ****************************************************************************/
-INT APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReserved)
+INT APIENTRY DllMain(HANDLE hInst, unsigned int ul_reason_being_called, LPVOID lpReserved)
 {
     int iRetVal = 1;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedi_buf.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_buf.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedi_buf.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_buf.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,10 +13,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "comedidev.h"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedi_compat32.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_compat32.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedi_compat32.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_compat32.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #include <linux/uaccess.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedi_compat32.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_compat32.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedi_compat32.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_compat32.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _COMEDI_COMPAT32_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedidev.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedidev.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedidev.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedidev.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _COMEDIDEV_H
@@ -270,11 +265,14 @@ enum subdevice_runflags {
 	/* indicates an COMEDI_CB_ERROR event has occurred since the last
 	 * command was started */
 	SRF_ERROR = 0x00000004,
-	SRF_RUNNING = 0x08000000
+	SRF_RUNNING = 0x08000000,
+	SRF_FREE_SPRIV = 0x80000000,	/* free s->private on detach */
 };
 
 bool comedi_is_subdevice_running(struct comedi_subdevice *s);
 
+void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size);
+
 int comedi_check_chanlist(struct comedi_subdevice *s,
 			  int n,
 			  unsigned int *chanlist);
@@ -312,6 +310,18 @@ struct comedi_lrange {
 	struct comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
 };
 
+static inline bool comedi_range_is_bipolar(struct comedi_subdevice *s,
+					   unsigned int range)
+{
+	return s->range_table->range[range].min < 0;
+}
+
+static inline bool comedi_range_is_unipolar(struct comedi_subdevice *s,
+					    unsigned int range)
+{
+	return s->range_table->range[range].min >= 0;
+}
+
 /* some silly little inline functions */
 
 static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
@@ -349,7 +359,12 @@ void comedi_buf_memcpy_from(struct comed
 
 int comedi_alloc_subdevices(struct comedi_device *, int);
 
-void comedi_spriv_free(struct comedi_device *, int subdev_num);
+int comedi_load_firmware(struct comedi_device *, struct device *,
+			 const char *name,
+			 int (*cb)(struct comedi_device *,
+				   const u8 *data, size_t size,
+				   unsigned long context),
+			 unsigned long context);
 
 int __comedi_request_region(struct comedi_device *,
 			    unsigned long start, unsigned long len);
@@ -489,6 +504,7 @@ struct usb_driver;
 struct usb_interface;
 
 struct usb_interface *comedi_to_usb_interface(struct comedi_device *);
+struct usb_device *comedi_to_usb_dev(struct comedi_device *);
 
 int comedi_usb_auto_config(struct usb_interface *, struct comedi_driver *,
 			   unsigned long context);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedi_fops.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_fops.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedi_fops.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_fops.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #undef DEBUG
@@ -536,6 +531,23 @@ static bool comedi_is_subdevice_idle(str
 	return (runflags & (SRF_ERROR | SRF_RUNNING)) ? false : true;
 }
 
+/**
+ * comedi_alloc_spriv() - Allocate memory for the subdevice private data.
+ * @s: comedi_subdevice struct
+ * @size: size of the memory to allocate
+ *
+ * This also sets the subdevice runflags to allow the core to automatically
+ * free the private data during the detach.
+ */
+void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size)
+{
+	s->private = kzalloc(size, GFP_KERNEL);
+	if (s->private)
+		comedi_set_subdevice_runflags(s, ~0, SRF_FREE_SPRIV);
+	return s->private;
+}
+EXPORT_SYMBOL_GPL(comedi_alloc_spriv);
+
 /*
    This function restores a subdevice to an idle state.
  */
@@ -665,7 +677,7 @@ static int do_bufconfig_ioctl(struct com
 	if (copy_from_user(&bc, arg, sizeof(bc)))
 		return -EFAULT;
 
-	if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0)
+	if (bc.subdevice >= dev->n_subdevices)
 		return -EINVAL;
 
 	s = &dev->subdevices[bc.subdevice];
@@ -918,7 +930,7 @@ static int do_bufinfo_ioctl(struct comed
 	if (copy_from_user(&bi, arg, sizeof(bi)))
 		return -EFAULT;
 
-	if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0)
+	if (bi.subdevice >= dev->n_subdevices)
 		return -EINVAL;
 
 	s = &dev->subdevices[bi.subdevice];
@@ -1401,22 +1413,19 @@ static int do_cmd_ioctl(struct comedi_de
 		DPRINTK("subdevice busy\n");
 		return -EBUSY;
 	}
-	s->busy = file;
 
 	/* make sure channel/gain list isn't too long */
 	if (cmd.chanlist_len > s->len_chanlist) {
 		DPRINTK("channel/gain list too long %u > %d\n",
 			cmd.chanlist_len, s->len_chanlist);
-		ret = -EINVAL;
-		goto cleanup;
+		return -EINVAL;
 	}
 
 	/* make sure channel/gain list isn't too short */
 	if (cmd.chanlist_len < 1) {
 		DPRINTK("channel/gain list too short %u < 1\n",
 			cmd.chanlist_len);
-		ret = -EINVAL;
-		goto cleanup;
+		return -EINVAL;
 	}
 
 	async->cmd = cmd;
@@ -1426,8 +1435,7 @@ static int do_cmd_ioctl(struct comedi_de
 	    kmalloc(async->cmd.chanlist_len * sizeof(int), GFP_KERNEL);
 	if (!async->cmd.chanlist) {
 		DPRINTK("allocation failed\n");
-		ret = -ENOMEM;
-		goto cleanup;
+		return -ENOMEM;
 	}
 
 	if (copy_from_user(async->cmd.chanlist, user_chanlist,
@@ -1479,6 +1487,9 @@ static int do_cmd_ioctl(struct comedi_de
 
 	comedi_set_subdevice_runflags(s, ~0, SRF_USER | SRF_RUNNING);
 
+	/* set s->busy _after_ setting SRF_RUNNING flag to avoid race with
+	 * comedi_read() or comedi_write() */
+	s->busy = file;
 	ret = s->do_cmd(dev, s);
 	if (ret == 0)
 		return 0;
@@ -1693,6 +1704,7 @@ static int do_cancel_ioctl(struct comedi
 			   void *file)
 {
 	struct comedi_subdevice *s;
+	int ret;
 
 	if (arg >= dev->n_subdevices)
 		return -EINVAL;
@@ -1709,7 +1721,11 @@ static int do_cancel_ioctl(struct comedi
 	if (s->busy != file)
 		return -EBUSY;
 
-	return do_cancel(dev, s);
+	ret = do_cancel(dev, s);
+	if (comedi_get_subdevice_runflags(s) & SRF_USER)
+		wake_up_interruptible(&s->async->wait_head);
+
+	return ret;
 }
 
 /*
@@ -2041,11 +2057,13 @@ static ssize_t comedi_write(struct file
 
 		if (!comedi_is_subdevice_running(s)) {
 			if (count == 0) {
+				mutex_lock(&dev->mutex);
 				if (comedi_is_subdevice_in_error(s))
 					retval = -EPIPE;
 				else
 					retval = 0;
 				do_become_nonbusy(dev, s);
+				mutex_unlock(&dev->mutex);
 			}
 			break;
 		}
@@ -2144,11 +2162,13 @@ static ssize_t comedi_read(struct file *
 
 		if (n == 0) {
 			if (!comedi_is_subdevice_running(s)) {
+				mutex_lock(&dev->mutex);
 				do_become_nonbusy(dev, s);
 				if (comedi_is_subdevice_in_error(s))
 					retval = -EPIPE;
 				else
 					retval = 0;
+				mutex_unlock(&dev->mutex);
 				break;
 			}
 			if (file->f_flags & O_NONBLOCK) {
@@ -2186,9 +2206,11 @@ static ssize_t comedi_read(struct file *
 		buf += n;
 		break;		/* makes device work like a pipe */
 	}
-	if (comedi_is_subdevice_idle(s) &&
-	    async->buf_read_count - async->buf_write_count == 0) {
-		do_become_nonbusy(dev, s);
+	if (comedi_is_subdevice_idle(s)) {
+		mutex_lock(&dev->mutex);
+		if (async->buf_read_count - async->buf_write_count == 0)
+			do_become_nonbusy(dev, s);
+		mutex_unlock(&dev->mutex);
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&async->wait_head, &wait);
@@ -2317,9 +2339,6 @@ static int comedi_close(struct inode *in
 
 	mutex_unlock(&dev->mutex);
 
-	if (file->f_flags & FASYNC)
-		comedi_fasync(-1, file, 0);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedi.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _COMEDI_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedilib.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedilib.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedilib.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedilib.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _LINUX_COMEDILIB_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedi_pci.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_pci.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedi_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/pci.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedi_pcmcia.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_pcmcia.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedi_pcmcia.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_pcmcia.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/kernel.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/comedi_usb.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_usb.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/comedi_usb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/comedi_usb.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/usb.h>
@@ -35,6 +31,18 @@ struct usb_interface *comedi_to_usb_inte
 EXPORT_SYMBOL_GPL(comedi_to_usb_interface);
 
 /**
+ * comedi_to_usb_dev() - comedi_device pointer to usb_device pointer.
+ * @dev: comedi_device struct
+ */
+struct usb_device *comedi_to_usb_dev(struct comedi_device *dev)
+{
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
+
+	return intf ? interface_to_usbdev(intf) : NULL;
+}
+EXPORT_SYMBOL_GPL(comedi_to_usb_dev);
+
+/**
  * comedi_usb_auto_config() - Configure/probe a comedi USB driver.
  * @intf: usb_interface struct
  * @driver: comedi_driver struct
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/8253.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/8253.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/8253.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/8253.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _8253_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/8255.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/8255.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/8255.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/8255.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: 8255
@@ -81,7 +76,6 @@ I/O port base address can be found in th
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
-#include <linux/slab.h>
 
 #include "comedi_fc.h"
 #include "8255.h"
@@ -290,15 +284,13 @@ int subdev_8255_init(struct comedi_devic
 {
 	struct subdev_8255_private *spriv;
 
-	spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
+	spriv = comedi_alloc_spriv(s, sizeof(*spriv));
 	if (!spriv)
 		return -ENOMEM;
 
 	spriv->iobase	= iobase;
 	spriv->io	= io ? io : subdev_8255_io;
 
-	s->private	= spriv;
-
 	s->type		= COMEDI_SUBD_DIO;
 	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
 	s->n_chan	= 24;
@@ -391,7 +383,6 @@ static void dev_8255_detach(struct comed
 			spriv = s->private;
 			release_region(spriv->iobase, _8255_SIZE);
 		}
-		comedi_spriv_free(dev, i);
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/8255.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/8255.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/8255.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/8255.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _8255_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/8255_pci.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/8255_pci.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/8255_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/8255_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,10 +19,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -242,10 +238,7 @@ static int pci_8255_auto_attach(struct c
 static void pci_8255_detach(struct comedi_device *dev)
 {
 	struct pci_8255_private *devpriv = dev->private;
-	int i;
 
-	for (i = 0; i < dev->n_subdevices; i++)
-		comedi_spriv_free(dev, i);
 	if (devpriv && devpriv->mmio_base)
 		iounmap(devpriv->mmio_base);
 	comedi_pci_disable(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/acl7225b.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/acl7225b.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/acl7225b.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/acl7225b.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,136 +0,0 @@
-/*
- * comedi/drivers/acl7225b.c
- * Driver for Adlink NuDAQ ACL-7225b and clones
- * José Luis Sánchez
- */
-/*
-Driver: acl7225b
-Description: Adlink NuDAQ ACL-7225b & compatibles
-Author: José Luis Sánchez (jsanchezv@teleline.es)
-Status: testing
-Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio)
-*/
-
-#include "../comedidev.h"
-
-#include <linux/ioport.h>
-
-#define ACL7225_RIO_LO 0	/* Relays input/output low byte (R0-R7) */
-#define ACL7225_RIO_HI 1	/* Relays input/output high byte (R8-R15) */
-#define ACL7225_DI_LO  2	/* Digital input low byte (DI0-DI7) */
-#define ACL7225_DI_HI  3	/* Digital input high byte (DI8-DI15) */
-
-struct acl7225b_boardinfo {
-	const char *name;
-	int io_range;
-};
-
-static const struct acl7225b_boardinfo acl7225b_boards[] = {
-	{
-		.name		= "acl7225b",
-		.io_range	= 8,		/* only 4 are used */
-	}, {
-		.name		= "p16r16dio",
-		.io_range	= 4,
-	},
-};
-
-static int acl7225b_do_insn_bits(struct comedi_device *dev,
-				 struct comedi_subdevice *s,
-				 struct comedi_insn *insn,
-				 unsigned int *data)
-{
-	unsigned long reg = (unsigned long)s->private;
-	unsigned int mask = data[0];
-	unsigned int bits = data[1];
-
-	if (mask) {
-		s->state &= ~mask;
-		s->state |= (bits & mask);
-
-		if (mask & 0x00ff)
-			outb(s->state & 0xff, dev->iobase + reg);
-		if (mask & 0xff00)
-			outb((s->state >> 8), dev->iobase + reg + 1);
-	}
-
-	data[1] = s->state;
-
-	return insn->n;
-}
-
-static int acl7225b_di_insn_bits(struct comedi_device *dev,
-				 struct comedi_subdevice *s,
-				 struct comedi_insn *insn,
-				 unsigned int *data)
-{
-	unsigned long reg = (unsigned long)s->private;
-
-	data[1] = inb(dev->iobase + reg) |
-		  (inb(dev->iobase + reg + 1) << 8);
-
-	return insn->n;
-}
-
-static int acl7225b_attach(struct comedi_device *dev,
-			   struct comedi_devconfig *it)
-{
-	const struct acl7225b_boardinfo *board = comedi_board(dev);
-	struct comedi_subdevice *s;
-	int ret;
-
-	ret = comedi_request_region(dev, it->options[0], board->io_range);
-	if (ret)
-		return ret;
-
-	ret = comedi_alloc_subdevices(dev, 3);
-	if (ret)
-		return ret;
-
-	s = &dev->subdevices[0];
-	/* Relays outputs */
-	s->type		= COMEDI_SUBD_DO;
-	s->subdev_flags	= SDF_WRITABLE;
-	s->maxdata	= 1;
-	s->n_chan	= 16;
-	s->insn_bits	= acl7225b_do_insn_bits;
-	s->range_table	= &range_digital;
-	s->private	= (void *)ACL7225_RIO_LO;
-
-	s = &dev->subdevices[1];
-	/* Relays status */
-	s->type		= COMEDI_SUBD_DI;
-	s->subdev_flags	= SDF_READABLE;
-	s->maxdata	= 1;
-	s->n_chan	= 16;
-	s->insn_bits	= acl7225b_di_insn_bits;
-	s->range_table	= &range_digital;
-	s->private	= (void *)ACL7225_RIO_LO;
-
-	s = &dev->subdevices[2];
-	/* Isolated digital inputs */
-	s->type		= COMEDI_SUBD_DI;
-	s->subdev_flags	= SDF_READABLE;
-	s->maxdata	= 1;
-	s->n_chan	= 16;
-	s->insn_bits	= acl7225b_di_insn_bits;
-	s->range_table	= &range_digital;
-	s->private	= (void *)ACL7225_DI_LO;
-
-	return 0;
-}
-
-static struct comedi_driver acl7225b_driver = {
-	.driver_name	= "acl7225b",
-	.module		= THIS_MODULE,
-	.attach		= acl7225b_attach,
-	.detach		= comedi_legacy_detach,
-	.board_name	= &acl7225b_boards[0].name,
-	.num_names	= ARRAY_SIZE(acl7225b_boards),
-	.offset		= sizeof(struct acl7225b_boardinfo),
-};
-module_comedi_driver(acl7225b_driver);
-
-MODULE_DESCRIPTION("Comedi: NuDAQ ACL-7225B, 16 Relay & 16 Isolated DI Card");
-MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_1032.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_1032.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_1032.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_1032.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,13 +20,6 @@
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * You should also find the complete GPL in the COPYING file accompanying this
- * source code.
  */
 
 #include <linux/pci.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_1516.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_1516.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_1516.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_1516.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,13 +20,6 @@
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * You should also find the complete GPL in the COPYING file accompanying
- * this source code.
  */
 
 #include <linux/pci.h>
@@ -203,7 +196,6 @@ static void apci1516_detach(struct comed
 {
 	if (dev->iobase)
 		apci1516_reset(dev);
-	comedi_spriv_free(dev, 2);
 	comedi_pci_disable(dev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_16xx.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_16xx.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_16xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_16xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,13 +20,6 @@
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * You should also find the complete GPL in the COPYING file accompanying
- * this source code.
  */
 
 #include <linux/pci.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_2032.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_2032.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_2032.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_2032.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,13 +20,6 @@
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * You should also find the complete GPL in the COPYING file accompanying
- * this source code.
  */
 
 #include <linux/pci.h>
@@ -354,7 +347,6 @@ static void apci2032_detach(struct comed
 		free_irq(dev->irq, dev);
 	if (dev->read_subdev)
 		kfree(dev->read_subdev->private);
-	comedi_spriv_free(dev, 1);
 	comedi_pci_disable(dev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_2200.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_2200.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_2200.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_2200.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,13 +20,6 @@
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * You should also find the complete GPL in the COPYING file accompanying
- * this source code.
  */
 
 #include <linux/pci.h>
@@ -130,7 +123,6 @@ static void apci2200_detach(struct comed
 {
 	if (dev->iobase)
 		apci2200_reset(dev);
-	comedi_spriv_free(dev, 2);
 	comedi_pci_disable(dev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_3120.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_3120.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_3120.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_3120.c	2013-08-25 20:43:22.000000000 -0400
@@ -103,8 +103,6 @@ static int apci3120_auto_attach(struct c
 		if (devpriv->ul_DmaBufferVirtual[i]) {
 			devpriv->ui_DmaBufferPages[i] = pages;
 			devpriv->ui_DmaBufferSize[i] = PAGE_SIZE * pages;
-			devpriv->ui_DmaBufferSamples[i] =
-				devpriv->ui_DmaBufferSize[i] >> 1;
 			devpriv->ul_DmaBufferHw[i] =
 				virt_to_bus((void *)devpriv->
 				ul_DmaBufferVirtual[i]);
@@ -138,9 +136,6 @@ static int apci3120_auto_attach(struct c
 	s->len_chanlist = this_board->i_AiChannelList;
 	s->range_table = &range_apci3120_ai;
 
-	/* Set the initialisation flag */
-	devpriv->b_AiInitialisation = 1;
-
 	s->insn_config = i_APCI3120_InsnConfigAnalogInput;
 	s->insn_read = i_APCI3120_InsnReadAnalogInput;
 	s->do_cmdtest = i_APCI3120_CommandTestAnalogInput;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_3501.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_3501.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_3501.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_3501.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,13 +20,6 @@
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * You should also find the complete GPL in the COPYING file accompanying
- * this source code.
  */
 
 #include <linux/pci.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_3xxx.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_3xxx.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_apci_3xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_apci_3xxx.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,14 +1,57 @@
+/*
+ * addi_apci_3xxx.c
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ * Project manager: S. Weber
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data.com
+ *	info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
 #include <linux/pci.h>
+#include <linux/interrupt.h>
 
 #include "../comedidev.h"
+
 #include "comedi_fc.h"
-#include "amcc_s5933.h"
 
-#include "addi-data/addi_common.h"
+#define CONV_UNIT_NS		(1 << 0)
+#define CONV_UNIT_US		(1 << 1)
+#define CONV_UNIT_MS		(1 << 2)
 
-#include "addi-data/addi_eeprom.c"
-#include "addi-data/hwdrv_apci3xxx.c"
-#include "addi-data/addi_common.c"
+static const struct comedi_lrange apci3xxx_ai_range = {
+	8, {
+		BIP_RANGE(10),
+		BIP_RANGE(5),
+		BIP_RANGE(2),
+		BIP_RANGE(1),
+		UNI_RANGE(10),
+		UNI_RANGE(5),
+		UNI_RANGE(2),
+		UNI_RANGE(1)
+	}
+};
+
+static const struct comedi_lrange apci3xxx_ao_range = {
+	2, {
+		BIP_RANGE(10),
+		UNI_RANGE(10)
+	}
+};
 
 enum apci3xxx_boardid {
 	BOARD_APCI3000_16,
@@ -38,651 +81,853 @@ enum apci3xxx_boardid {
 	BOARD_APCI3500,
 };
 
-static const struct addi_board apci3xxx_boardtypes[] = {
+struct apci3xxx_boardinfo {
+	const char *name;
+	int ai_subdev_flags;
+	int ai_n_chan;
+	unsigned int ai_maxdata;
+	unsigned char ai_conv_units;
+	unsigned int ai_min_acq_ns;
+	unsigned int has_ao:1;
+	unsigned int has_dig_in:1;
+	unsigned int has_dig_out:1;
+	unsigned int has_ttl_io:1;
+};
+
+static const struct apci3xxx_boardinfo apci3xxx_boardtypes[] = {
 	[BOARD_APCI3000_16] = {
-		.pc_DriverName		= "apci3000-16",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 16,
-		.i_NbrAiChannelDiff	= 8,
-		.i_AiChannelList	= 16,
-		.i_AiMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3000-16",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 16,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3000_8] = {
-		.pc_DriverName		= "apci3000-8",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 8,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 8,
-		.i_AiMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3000-8",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 8,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3000_4] = {
-		.pc_DriverName		= "apci3000-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 4,
-		.i_NbrAiChannelDiff	= 2,
-		.i_AiChannelList	= 4,
-		.i_AiMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3000-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 4,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3006_16] = {
-		.pc_DriverName		= "apci3006-16",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 16,
-		.i_NbrAiChannelDiff	= 8,
-		.i_AiChannelList	= 16,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3006-16",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 16,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3006_8] = {
-		.pc_DriverName		= "apci3006-8",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 8,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 8,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3006-8",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 8,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3006_4] = {
-		.pc_DriverName		= "apci3006-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 4,
-		.i_NbrAiChannelDiff	= 2,
-		.i_AiChannelList	= 4,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3006-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 4,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3010_16] = {
-		.pc_DriverName		= "apci3010-16",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 16,
-		.i_NbrAiChannelDiff	= 8,
-		.i_AiChannelList	= 16,
-		.i_AiMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3010-16",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 16,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3010_8] = {
-		.pc_DriverName		= "apci3010-8",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 8,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 8,
-		.i_AiMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3010-8",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 8,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3010_4] = {
-		.pc_DriverName		= "apci3010-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 4,
-		.i_NbrAiChannelDiff	= 2,
-		.i_AiChannelList	= 4,
-		.i_AiMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3010-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 4,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3016_16] = {
-		.pc_DriverName		= "apci3016-16",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 16,
-		.i_NbrAiChannelDiff	= 8,
-		.i_AiChannelList	= 16,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3016-16",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 16,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3016_8] = {
-		.pc_DriverName		= "apci3016-8",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 8,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 8,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3016-8",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 8,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3016_4] = {
-		.pc_DriverName		= "apci3016-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 4,
-		.i_NbrAiChannelDiff	= 2,
-		.i_AiChannelList	= 4,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3016-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 4,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3100_16_4] = {
-		.pc_DriverName		= "apci3100-16-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 16,
-		.i_NbrAiChannelDiff	= 8,
-		.i_AiChannelList	= 16,
-		.i_NbrAoChannel		= 4,
-		.i_AiMaxdata		= 4095,
-		.i_AoMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.pr_AoRangelist		= &range_apci3XXX_ao,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3100-16-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 16,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ao			= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3100_8_4] = {
-		.pc_DriverName		= "apci3100-8-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 8,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 8,
-		.i_NbrAoChannel		= 4,
-		.i_AiMaxdata		= 4095,
-		.i_AoMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.pr_AoRangelist		= &range_apci3XXX_ao,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3100-8-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 8,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ao			= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3106_16_4] = {
-		.pc_DriverName		= "apci3106-16-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 16,
-		.i_NbrAiChannelDiff	= 8,
-		.i_AiChannelList	= 16,
-		.i_NbrAoChannel		= 4,
-		.i_AiMaxdata		= 65535,
-		.i_AoMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.pr_AoRangelist		= &range_apci3XXX_ao,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3106-16-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 16,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ao			= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3106_8_4] = {
-		.pc_DriverName		= "apci3106-8-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 8,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 8,
-		.i_NbrAoChannel		= 4,
-		.i_AiMaxdata		= 65535,
-		.i_AoMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.pr_AoRangelist		= &range_apci3XXX_ao,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 10000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3106-8-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 8,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 10000,
+		.has_ao			= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3110_16_4] = {
-		.pc_DriverName		= "apci3110-16-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 16,
-		.i_NbrAiChannelDiff	= 8,
-		.i_AiChannelList	= 16,
-		.i_NbrAoChannel		= 4,
-		.i_AiMaxdata		= 4095,
-		.i_AoMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.pr_AoRangelist		= &range_apci3XXX_ao,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3110-16-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 16,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_ao			= 1,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3110_8_4] = {
-		.pc_DriverName		= "apci3110-8-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 8,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 8,
-		.i_NbrAoChannel		= 4,
-		.i_AiMaxdata		= 4095,
-		.i_AoMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.pr_AoRangelist		= &range_apci3XXX_ao,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3110-8-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 8,
+		.ai_maxdata		= 0x0fff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_ao			= 1,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3116_16_4] = {
-		.pc_DriverName		= "apci3116-16-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 16,
-		.i_NbrAiChannelDiff	= 8,
-		.i_AiChannelList	= 16,
-		.i_NbrAoChannel		= 4,
-		.i_AiMaxdata		= 65535,
-		.i_AoMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.pr_AoRangelist		= &range_apci3XXX_ao,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3116-16-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 16,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_ao			= 1,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3116_8_4] = {
-		.pc_DriverName		= "apci3116-8-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannel		= 8,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 8,
-		.i_NbrAoChannel		= 4,
-		.i_AiMaxdata		= 65535,
-		.i_AoMaxdata		= 4095,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.pr_AoRangelist		= &range_apci3XXX_ao,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.i_NbrTTLChannel	= 24,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3116-8-4",
+		.ai_subdev_flags	= SDF_COMMON | SDF_GROUND | SDF_DIFF,
+		.ai_n_chan		= 8,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_ao			= 1,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
+		.has_ttl_io		= 1,
 	},
 	[BOARD_APCI3003] = {
-		.pc_DriverName		= "apci3003",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 4,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.b_AvailableConvertUnit	= 7,
-		.ui_MinAcquisitiontimeNs = 2500,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
+		.name			= "apci3003",
+		.ai_subdev_flags	= SDF_DIFF,
+		.ai_n_chan		= 4,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US |
+					  CONV_UNIT_NS,
+		.ai_min_acq_ns		= 2500,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
 	},
 	[BOARD_APCI3002_16] = {
-		.pc_DriverName		= "apci3002-16",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannelDiff	= 16,
-		.i_AiChannelList	= 16,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
+		.name			= "apci3002-16",
+		.ai_subdev_flags	= SDF_DIFF,
+		.ai_n_chan		= 16,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
 	},
 	[BOARD_APCI3002_8] = {
-		.pc_DriverName		= "apci3002-8",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannelDiff	= 8,
-		.i_AiChannelList	= 8,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
+		.name			= "apci3002-8",
+		.ai_subdev_flags	= SDF_DIFF,
+		.ai_n_chan		= 8,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
 	},
 	[BOARD_APCI3002_4] = {
-		.pc_DriverName		= "apci3002-4",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAiChannelDiff	= 4,
-		.i_AiChannelList	= 4,
-		.i_AiMaxdata		= 65535,
-		.pr_AiRangelist		= &range_apci3XXX_ai,
-		.i_NbrDiChannel		= 4,
-		.i_NbrDoChannel		= 4,
-		.i_DoMaxdata		= 1,
-		.b_AvailableConvertUnit	= 6,
-		.ui_MinAcquisitiontimeNs = 5000,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
-		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
-		.di_bits		= apci3xxx_di_insn_bits,
-		.do_bits		= apci3xxx_do_insn_bits,
+		.name			= "apci3002-4",
+		.ai_subdev_flags	= SDF_DIFF,
+		.ai_n_chan		= 4,
+		.ai_maxdata		= 0xffff,
+		.ai_conv_units		= CONV_UNIT_MS | CONV_UNIT_US,
+		.ai_min_acq_ns		= 5000,
+		.has_dig_in		= 1,
+		.has_dig_out		= 1,
 	},
 	[BOARD_APCI3500] = {
-		.pc_DriverName		= "apci3500",
-		.i_IorangeBase1		= 256,
-		.i_PCIEeprom		= ADDIDATA_NO_EEPROM,
-		.pc_EepromChip		= ADDIDATA_9054,
-		.i_NbrAoChannel		= 4,
-		.i_AoMaxdata		= 4095,
-		.pr_AoRangelist		= &range_apci3XXX_ao,
-		.i_NbrTTLChannel	= 24,
-		.interrupt		= v_APCI3XXX_Interrupt,
-		.reset			= i_APCI3XXX_Reset,
-		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
-		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
-		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
-		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
-		.ttl_write		= i_APCI3XXX_InsnWriteTTLIO,
+		.name			= "apci3500",
+		.has_ao			= 1,
+		.has_ttl_io		= 1,
 	},
 };
 
+struct apci3xxx_private {
+	void __iomem *mmio;
+	unsigned int ai_timer;
+	unsigned char ai_time_base;
+};
+
+static irqreturn_t apci3xxx_irq_handler(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct apci3xxx_private *devpriv = dev->private;
+	struct comedi_subdevice *s = dev->read_subdev;
+	unsigned int status;
+	unsigned int val;
+
+	/* Test if interrupt occur */
+	status = readl(devpriv->mmio + 16);
+	if ((status & 0x2) == 0x2) {
+		/* Reset the interrupt */
+		writel(status, devpriv->mmio + 16);
+
+		val = readl(devpriv->mmio + 28);
+		comedi_buf_put(s->async, val);
+
+		s->async->events |= COMEDI_CB_EOA;
+		comedi_event(dev, s);
+
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+
+static int apci3xxx_ai_started(struct comedi_device *dev)
+{
+	struct apci3xxx_private *devpriv = dev->private;
+
+	if ((readl(devpriv->mmio + 8) & 0x80000) == 0x80000)
+		return 1;
+	else
+		return 0;
+
+}
+
+static int apci3xxx_ai_setup(struct comedi_device *dev, unsigned int chanspec)
+{
+	struct apci3xxx_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(chanspec);
+	unsigned int range = CR_RANGE(chanspec);
+	unsigned int aref = CR_AREF(chanspec);
+	unsigned int delay_mode;
+	unsigned int val;
+
+	if (apci3xxx_ai_started(dev))
+		return -EBUSY;
+
+	/* Clear the FIFO */
+	writel(0x10000, devpriv->mmio + 12);
+
+	/* Get and save the delay mode */
+	delay_mode = readl(devpriv->mmio + 4);
+	delay_mode &= 0xfffffef0;
+
+	/* Channel configuration selection */
+	writel(delay_mode, devpriv->mmio + 4);
+
+	/* Make the configuration */
+	val = (range & 3) | ((range >> 2) << 6) |
+	      ((aref == AREF_DIFF) << 7);
+	writel(val, devpriv->mmio + 0);
+
+	/* Channel selection */
+	writel(delay_mode | 0x100, devpriv->mmio + 4);
+	writel(chan, devpriv->mmio + 0);
+
+	/* Restore delay mode */
+	writel(delay_mode, devpriv->mmio + 4);
+
+	/* Set the number of sequence to 1 */
+	writel(1, devpriv->mmio + 48);
+
+	return 0;
+}
+
+static int apci3xxx_ai_insn_read(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn,
+				 unsigned int *data)
+{
+	struct apci3xxx_private *devpriv = dev->private;
+	unsigned int val;
+	int ret;
+	int i;
+
+	ret = apci3xxx_ai_setup(dev, insn->chanspec);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < insn->n; i++) {
+		/* Start the conversion */
+		writel(0x80000, devpriv->mmio + 8);
+
+		/* Wait the EOS */
+		do {
+			val = readl(devpriv->mmio + 20);
+			val &= 0x1;
+		} while (!val);
+
+		/* Read the analog value */
+		data[i] = readl(devpriv->mmio + 28);
+	}
+
+	return insn->n;
+}
+
+static int apci3xxx_ai_ns_to_timer(struct comedi_device *dev,
+				   unsigned int *ns, int round_mode)
+{
+	const struct apci3xxx_boardinfo *board = comedi_board(dev);
+	struct apci3xxx_private *devpriv = dev->private;
+	unsigned int base;
+	unsigned int timer;
+	int time_base;
+
+	/* time_base: 0 = ns, 1 = us, 2 = ms */
+	for (time_base = 0; time_base < 3; time_base++) {
+		/* skip unsupported time bases */
+		if (!(board->ai_conv_units & (1 << time_base)))
+			continue;
+
+		switch (time_base) {
+		case 0:
+			base = 1;
+			break;
+		case 1:
+			base = 1000;
+			break;
+		case 2:
+			base = 1000000;
+			break;
+		}
+
+		switch (round_mode) {
+		case TRIG_ROUND_NEAREST:
+		default:
+			timer = (*ns + base / 2) / base;
+			break;
+		case TRIG_ROUND_DOWN:
+			timer = *ns / base;
+			break;
+		case TRIG_ROUND_UP:
+			timer = (*ns + base - 1) / base;
+			break;
+		}
+
+		if (timer < 0x10000) {
+			devpriv->ai_time_base = time_base;
+			devpriv->ai_timer = timer;
+			*ns = timer * time_base;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static int apci3xxx_ai_cmdtest(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_cmd *cmd)
+{
+	const struct apci3xxx_boardinfo *board = comedi_board(dev);
+	int err = 0;
+	unsigned int tmp;
+
+	/* Step 1 : check if triggers are trivially valid */
+
+	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+	err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
+	err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
+	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
+
+	if (err)
+		return 1;
+
+	/* Step 2a : make sure trigger sources are unique */
+
+	err |= cfc_check_trigger_is_unique(cmd->stop_src);
+
+	/* Step 2b : and mutually compatible */
+
+	if (err)
+		return 2;
+
+	/* Step 3: check if arguments are trivially valid */
+
+	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+	err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+	err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+					 board->ai_min_acq_ns);
+	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+	if (cmd->stop_src == TRIG_COUNT)
+		err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
+	else	/* TRIG_NONE */
+		err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	/*
+	 * FIXME: The hardware supports multiple scan modes but the original
+	 * addi-data driver only supported reading a single channel with
+	 * interrupts. Need a proper datasheet to fix this.
+	 *
+	 * The following scan modes are supported by the hardware:
+	 * 1) Single software scan
+	 * 2) Single hardware triggered scan
+	 * 3) Continuous software scan
+	 * 4) Continuous software scan with timer delay
+	 * 5) Continuous hardware triggered scan
+	 * 6) Continuous hardware triggered scan with timer delay
+	 *
+	 * For now, limit the chanlist to a single channel.
+	 */
+	if (cmd->chanlist_len > 1) {
+		cmd->chanlist_len = 1;
+		err |= -EINVAL;
+	}
+
+	tmp = cmd->convert_arg;
+	err |= apci3xxx_ai_ns_to_timer(dev, &cmd->convert_arg,
+				       cmd->flags & TRIG_ROUND_MASK);
+	if (tmp != cmd->convert_arg)
+		err |= -EINVAL;
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int apci3xxx_ai_cmd(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
+{
+	struct apci3xxx_private *devpriv = dev->private;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int ret;
+
+	ret = apci3xxx_ai_setup(dev, cmd->chanlist[0]);
+	if (ret)
+		return ret;
+
+	/* Set the convert timing unit */
+	writel(devpriv->ai_time_base, devpriv->mmio + 36);
+
+	/* Set the convert timing */
+	writel(devpriv->ai_timer, devpriv->mmio + 32);
+
+	/* Start the conversion */
+	writel(0x180000, devpriv->mmio + 8);
+
+	return 0;
+}
+
+static int apci3xxx_ai_cancel(struct comedi_device *dev,
+			      struct comedi_subdevice *s)
+{
+	return 0;
+}
+
+static int apci3xxx_ao_insn_write(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn,
+				  unsigned int *data)
+{
+	struct apci3xxx_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int range = CR_RANGE(insn->chanspec);
+	unsigned int status;
+	int i;
+
+	for (i = 0; i < insn->n; i++) {
+		/* Set the range selection */
+		writel(range, devpriv->mmio + 96);
+
+		/* Write the analog value to the selected channel */
+		writel((data[i] << 8) | chan, devpriv->mmio + 100);
+
+		/* Wait the end of transfer */
+		do {
+			status = readl(devpriv->mmio + 96);
+		} while ((status & 0x100) != 0x100);
+	}
+
+	return insn->n;
+}
+
+static int apci3xxx_di_insn_bits(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn,
+				 unsigned int *data)
+{
+	data[1] = inl(dev->iobase + 32) & 0xf;
+
+	return insn->n;
+}
+
+static int apci3xxx_do_insn_bits(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn,
+				 unsigned int *data)
+{
+	unsigned int mask = data[0];
+	unsigned int bits = data[1];
+
+	s->state = inl(dev->iobase + 48) & 0xf;
+	if (mask) {
+		s->state &= ~mask;
+		s->state |= (bits & mask);
+
+		outl(s->state, dev->iobase + 48);
+	}
+
+	data[1] = s->state;
+
+	return insn->n;
+}
+
+static int apci3xxx_dio_insn_config(struct comedi_device *dev,
+				    struct comedi_subdevice *s,
+				    struct comedi_insn *insn,
+				    unsigned int *data)
+{
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int mask = 1 << chan;
+	unsigned int bits;
+
+	/*
+	 * Port 0 (channels 0-7) are always inputs
+	 * Port 1 (channels 8-15) are always outputs
+	 * Port 2 (channels 16-23) are programmable i/o
+	 *
+	 * Changing any channel in port 2 changes the entire port.
+	 */
+	if (mask & 0xff0000)
+		bits = 0xff0000;
+	else
+		bits = 0;
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~bits;
+		break;
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= bits;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+	default:
+		return -EINVAL;
+	}
+
+	/* update port 2 configuration */
+	if (bits)
+		outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
+
+	return insn->n;
+}
+
+static int apci3xxx_dio_insn_bits(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn,
+				  unsigned int *data)
+{
+	unsigned int mask = data[0];
+	unsigned int bits = data[1];
+	unsigned int val;
+
+	/* only update output channels */
+	mask &= s->io_bits;
+	if (mask) {
+		s->state &= ~mask;
+		s->state |= (bits & mask);
+
+		if (mask & 0xff)
+			outl(s->state & 0xff, dev->iobase + 80);
+		if (mask & 0xff0000)
+			outl((s->state >> 16) & 0xff, dev->iobase + 112);
+	}
+
+	val = inl(dev->iobase + 80);
+	val |= (inl(dev->iobase + 64) << 8);
+	if (s->io_bits & 0xff0000)
+		val |= (inl(dev->iobase + 112) << 16);
+	else
+		val |= (inl(dev->iobase + 96) << 16);
+
+	data[1] = val;
+
+	return insn->n;
+}
+
+static int apci3xxx_reset(struct comedi_device *dev)
+{
+	struct apci3xxx_private *devpriv = dev->private;
+	unsigned int val;
+	int i;
+
+	/* Disable the interrupt */
+	disable_irq(dev->irq);
+
+	/* Clear the start command */
+	writel(0, devpriv->mmio + 8);
+
+	/* Reset the interrupt flags */
+	val = readl(devpriv->mmio + 16);
+	writel(val, devpriv->mmio + 16);
+
+	/* clear the EOS */
+	readl(devpriv->mmio + 20);
+
+	/* Clear the FIFO */
+	for (i = 0; i < 16; i++)
+		val = readl(devpriv->mmio + 28);
+
+	/* Enable the interrupt */
+	enable_irq(dev->irq);
+
+	return 0;
+}
+
 static int apci3xxx_auto_attach(struct comedi_device *dev,
 				unsigned long context)
 {
-	const struct addi_board *board = NULL;
+	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+	const struct apci3xxx_boardinfo *board = NULL;
+	struct apci3xxx_private *devpriv;
+	struct comedi_subdevice *s;
+	int n_subdevices;
+	int subdev;
+	int ret;
 
 	if (context < ARRAY_SIZE(apci3xxx_boardtypes))
 		board = &apci3xxx_boardtypes[context];
 	if (!board)
 		return -ENODEV;
 	dev->board_ptr = board;
+	dev->board_name = board->name;
 
-	return addi_auto_attach(dev, context);
+	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+	if (!devpriv)
+		return -ENOMEM;
+	dev->private = devpriv;
+
+	ret = comedi_pci_enable(dev);
+	if (ret)
+		return ret;
+
+	dev->iobase = pci_resource_start(pcidev, 2);
+	devpriv->mmio = pci_ioremap_bar(pcidev, 3);
+
+	if (pcidev->irq > 0) {
+		ret = request_irq(pcidev->irq, apci3xxx_irq_handler,
+				  IRQF_SHARED, dev->board_name, dev);
+		if (ret == 0)
+			dev->irq = pcidev->irq;
+	}
+
+	n_subdevices = (board->ai_n_chan ? 0 : 1) + board->has_ao +
+		       board->has_dig_in + board->has_dig_out +
+		       board->has_ttl_io;
+	ret = comedi_alloc_subdevices(dev, n_subdevices);
+	if (ret)
+		return ret;
+
+	subdev = 0;
+
+	/* Analog Input subdevice */
+	if (board->ai_n_chan) {
+		s = &dev->subdevices[subdev];
+		s->type		= COMEDI_SUBD_AI;
+		s->subdev_flags	= SDF_READABLE | board->ai_subdev_flags;
+		s->n_chan	= board->ai_n_chan;
+		s->maxdata	= board->ai_maxdata;
+		s->len_chanlist	= s->n_chan;
+		s->range_table	= &apci3xxx_ai_range;
+		s->insn_read	= apci3xxx_ai_insn_read;
+		if (dev->irq) {
+			dev->read_subdev = s;
+			s->subdev_flags	|= SDF_CMD_READ;
+			s->do_cmdtest	= apci3xxx_ai_cmdtest;
+			s->do_cmd	= apci3xxx_ai_cmd;
+			s->cancel	= apci3xxx_ai_cancel;
+		}
+
+		subdev++;
+	}
+
+	/* Analog Output subdevice */
+	if (board->has_ao) {
+		s = &dev->subdevices[subdev];
+		s->type		= COMEDI_SUBD_AO;
+		s->subdev_flags	= SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+		s->n_chan	= 4;
+		s->maxdata	= 0x0fff;
+		s->range_table	= &apci3xxx_ao_range;
+		s->insn_write	= apci3xxx_ao_insn_write;
+
+		subdev++;
+	}
+
+	/* Digital Input subdevice */
+	if (board->has_dig_in) {
+		s = &dev->subdevices[subdev];
+		s->type		= COMEDI_SUBD_DI;
+		s->subdev_flags	= SDF_READABLE;
+		s->n_chan	= 4;
+		s->maxdata	= 1;
+		s->range_table	= &range_digital;
+		s->insn_bits	= apci3xxx_di_insn_bits;
+
+		subdev++;
+	}
+
+	/* Digital Output subdevice */
+	if (board->has_dig_out) {
+		s = &dev->subdevices[subdev];
+		s->type		= COMEDI_SUBD_DO;
+		s->subdev_flags	= SDF_WRITEABLE;
+		s->n_chan	= 4;
+		s->maxdata	= 1;
+		s->range_table	= &range_digital;
+		s->insn_bits	= apci3xxx_do_insn_bits;
+
+		subdev++;
+	}
+
+	/* TTL Digital I/O subdevice */
+	if (board->has_ttl_io) {
+		s = &dev->subdevices[subdev];
+		s->type		= COMEDI_SUBD_DIO;
+		s->subdev_flags	= SDF_READABLE | SDF_WRITEABLE;
+		s->n_chan	= 24;
+		s->maxdata	= 1;
+		s->io_bits	= 0xff;	/* channels 0-7 are always outputs */
+		s->range_table	= &range_digital;
+		s->insn_config	= apci3xxx_dio_insn_config;
+		s->insn_bits	= apci3xxx_dio_insn_bits;
+
+		subdev++;
+	}
+
+	apci3xxx_reset(dev);
+	return 0;
+}
+
+static void apci3xxx_detach(struct comedi_device *dev)
+{
+	struct apci3xxx_private *devpriv = dev->private;
+
+	if (devpriv) {
+		if (dev->iobase)
+			apci3xxx_reset(dev);
+		if (dev->irq)
+			free_irq(dev->irq, dev);
+		if (devpriv->mmio)
+			iounmap(devpriv->mmio);
+	}
+	comedi_pci_disable(dev);
 }
 
 static struct comedi_driver apci3xxx_driver = {
 	.driver_name	= "addi_apci_3xxx",
 	.module		= THIS_MODULE,
 	.auto_attach	= apci3xxx_auto_attach,
-	.detach		= i_ADDI_Detach,
+	.detach		= apci3xxx_detach,
 };
 
 static int apci3xxx_pci_probe(struct pci_dev *dev,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/addi_common.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/addi_common.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/addi_common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/addi_common.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,13 +20,6 @@ This program is distributed in the hope
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this
-source code.
-
 @endverbatim
 */
 /*
@@ -46,10 +39,6 @@ source code.
   +-----------------------------------------------------------------------+
 */
 
-#ifndef COMEDI_SUBD_TTLIO
-#define COMEDI_SUBD_TTLIO   11	/* Digital Input Output But TTL */
-#endif
-
 static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,
 				     struct comedi_subdevice *s,
 				     struct comedi_insn *insn,
@@ -105,23 +94,14 @@ static int addi_auto_attach(struct comed
 	if (ret)
 		return ret;
 
-	if (!this_board->pc_EepromChip ||
-	    strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) {
-		/* board does not have an eeprom or is not ADDIDATA_9054 */
-		if (this_board->i_IorangeBase1)
-			dev->iobase = pci_resource_start(pcidev, 1);
-		else
-			dev->iobase = pci_resource_start(pcidev, 0);
+	if (this_board->i_IorangeBase1)
+		dev->iobase = pci_resource_start(pcidev, 1);
+	else
+		dev->iobase = pci_resource_start(pcidev, 0);
 
-		devpriv->iobase = dev->iobase;
-		devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
-		devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
-	} else {
-		/* board has an ADDIDATA_9054 eeprom */
-		dev->iobase = pci_resource_start(pcidev, 2);
-		devpriv->iobase = pci_resource_start(pcidev, 2);
-		devpriv->dw_AiBase = pci_ioremap_bar(pcidev, 3);
-	}
+	devpriv->iobase = dev->iobase;
+	devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
+	devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
 	devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
 
 	/* Initialize parameters that can be overridden in EEPROM */
@@ -132,7 +112,6 @@ static int addi_auto_attach(struct comed
 	devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel;
 	devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel;
 	devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata;
-	devpriv->s_EeParameters.i_Dma = this_board->i_Dma;
 	devpriv->s_EeParameters.i_Timer = this_board->i_Timer;
 	devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
 		this_board->ui_MinAcquisitiontimeNs;
@@ -191,9 +170,6 @@ static int addi_auto_attach(struct comed
 		s->len_chanlist = this_board->i_AiChannelList;
 		s->range_table = this_board->pr_AiRangelist;
 
-		/* Set the initialisation flag */
-		devpriv->b_AiInitialisation = 1;
-
 		s->insn_config = this_board->ai_config;
 		s->insn_read = this_board->ai_read;
 		s->insn_write = this_board->ai_write;
@@ -215,8 +191,6 @@ static int addi_auto_attach(struct comed
 		s->maxdata = devpriv->s_EeParameters.i_AoMaxdata;
 		s->len_chanlist =
 			devpriv->s_EeParameters.i_NbrAoChannel;
-		s->range_table = this_board->pr_AoRangelist;
-		s->insn_config = this_board->ao_config;
 		s->insn_write = this_board->ao_write;
 	} else {
 		s->type = COMEDI_SUBD_UNUSED;
@@ -281,22 +255,7 @@ static int addi_auto_attach(struct comed
 
 	/*  Allocate and Initialise TTL */
 	s = &dev->subdevices[5];
-	if (this_board->i_NbrTTLChannel) {
-		s->type = COMEDI_SUBD_TTLIO;
-		s->subdev_flags =
-			SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
-		s->n_chan = this_board->i_NbrTTLChannel;
-		s->maxdata = 1;
-		s->io_bits = 0;	/* all bits input */
-		s->len_chanlist = this_board->i_NbrTTLChannel;
-		s->range_table = &range_digital;
-		s->insn_config = this_board->ttl_config;
-		s->insn_bits = this_board->ttl_bits;
-		s->insn_read = this_board->ttl_read;
-		s->insn_write = this_board->ttl_write;
-	} else {
-		s->type = COMEDI_SUBD_UNUSED;
-	}
+	s->type = COMEDI_SUBD_UNUSED;
 
 	/* EEPROM */
 	s = &dev->subdevices[6];
@@ -323,8 +282,6 @@ static void i_ADDI_Detach(struct comedi_
 			i_ADDI_Reset(dev);
 		if (dev->irq)
 			free_irq(dev->irq, dev);
-		if (devpriv->dw_AiBase)
-			iounmap(devpriv->dw_AiBase);
 	}
 	comedi_pci_disable(dev);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/addi_common.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/addi_common.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/addi_common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/addi_common.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,12 +18,8 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
-#define LOBYTE(W)	(unsigned char)((W) & 0xFF)
-#define HIBYTE(W)	(unsigned char)(((W) >> 8) & 0xFF)
-#define MAKEWORD(H, L)	(unsigned short)((L) | ((H) << 8))
 #define LOWORD(W)	(unsigned short)((W) & 0xFFFF)
 #define HIWORD(W)	(unsigned short)(((W) >> 16) & 0xFFFF)
-#define MAKEDWORD(H, L)	(unsigned int)((L) | ((H) << 16))
 
 #define ADDI_ENABLE		1
 #define ADDI_DISABLE		0
@@ -33,8 +29,6 @@
 #define ADDIDATA_NO_EEPROM	0
 #define ADDIDATA_93C76		"93C76"
 #define ADDIDATA_S5920		"S5920"
-#define ADDIDATA_S5933		"S5933"
-#define ADDIDATA_9054		"9054"
 
 /* ADDIDATA Enable Disable */
 #define ADDIDATA_ENABLE		1
@@ -55,17 +49,12 @@ struct addi_board {
 	int i_AiMaxdata;	/*  resolution of A/D */
 	int i_AoMaxdata;	/*  resolution of D/A */
 	const struct comedi_lrange *pr_AiRangelist;	/* rangelist for A/D */
-	const struct comedi_lrange *pr_AoRangelist;	/* rangelist for D/A */
 
 	int i_NbrDiChannel;	/*  Number of DI channels */
 	int i_NbrDoChannel;	/*  Number of DO channels */
 	int i_DoMaxdata;	/*  data to set all channels high */
 
-	int i_NbrTTLChannel;	/*  Number of TTL channels */
-
-	int i_Dma;		/*  dma present or not */
 	int i_Timer;		/*    timer subdevice present or not */
-	unsigned char b_AvailableConvertUnit;
 	unsigned int ui_MinAcquisitiontimeNs;	/*  Minimum Acquisition in Nano secs */
 	unsigned int ui_MinDelaytimeNs;	/*  Minimum Delay in Nano secs */
 
@@ -90,12 +79,8 @@ struct addi_board {
 	int (*ai_cancel)(struct comedi_device *, struct comedi_subdevice *);
 
 	/* Analog Output */
-	int (*ao_config)(struct comedi_device *, struct comedi_subdevice *,
-			 struct comedi_insn *, unsigned int *);
 	int (*ao_write)(struct comedi_device *, struct comedi_subdevice *,
 			struct comedi_insn *, unsigned int *);
-	int (*ao_bits)(struct comedi_device *, struct comedi_subdevice *,
-		       struct comedi_insn *, unsigned int *);
 
 	/* Digital Input */
 	int (*di_config)(struct comedi_device *, struct comedi_subdevice *,
@@ -126,16 +111,6 @@ struct addi_board {
 			  struct comedi_insn *, unsigned int *);
 	int (*timer_bits)(struct comedi_device *, struct comedi_subdevice *,
 			  struct comedi_insn *, unsigned int *);
-
-	/* TTL IO */
-	int (*ttl_config)(struct comedi_device *, struct comedi_subdevice *,
-			  struct comedi_insn *, unsigned int *);
-	int (*ttl_bits)(struct comedi_device *, struct comedi_subdevice *,
-			struct comedi_insn *, unsigned int *);
-	int (*ttl_read)(struct comedi_device *, struct comedi_subdevice *,
-			struct comedi_insn *, unsigned int *);
-	int (*ttl_write)(struct comedi_device *, struct comedi_subdevice *,
-			 struct comedi_insn *, unsigned int *);
 };
 
 /* MODULE INFO STRUCTURE */
@@ -283,58 +258,41 @@ union str_ModuleInfo {
 
 /* Private structure for the addi_apci3120 driver */
 struct addi_private {
-
 	int iobase;
 	int i_IobaseAmcc;	/*  base+size for AMCC chip */
 	int i_IobaseAddon;	/* addon base address */
 	int i_IobaseReserved;
-	void __iomem *dw_AiBase;
 	unsigned char b_AiContinuous;	/*  we do unlimited AI */
-	unsigned char b_AiInitialisation;
 	unsigned int ui_AiActualScan;	/* how many scans we finished */
-	unsigned int ui_AiBufferPtr;	/*  data buffer ptr in samples */
 	unsigned int ui_AiNbrofChannels;	/*  how many channels is measured */
 	unsigned int ui_AiScanLength;	/*  Length of actual scanlist */
-	unsigned int ui_AiActualScanPosition;	/*  position in actual scan */
 	unsigned int *pui_AiChannelList;	/*  actual chanlist */
 	unsigned int ui_AiChannelList[32];	/*  actual chanlist */
-	unsigned char b_AiChannelConfiguration[32];	/*  actual chanlist */
 	unsigned int ui_AiReadData[32];
-	unsigned int dw_AiInitialised;
 	unsigned int ui_AiTimer0;	/* Timer Constant for Timer0 */
 	unsigned int ui_AiTimer1;	/* Timer constant for Timer1 */
 	unsigned int ui_AiFlags;
 	unsigned int ui_AiDataLength;
-	short *AiData;	/*  Pointer to sample data */
 	unsigned int ui_AiNbrofScans;	/*  number of scans to do */
 	unsigned short us_UseDma;	/*  To use Dma or not */
 	unsigned char b_DmaDoubleBuffer;	/*  we can use double buffering */
 	unsigned int ui_DmaActualBuffer;	/*  which buffer is used now */
-	/* UPDATE-0.7.57->0.7.68 */
-	/* unsigned int               ul_DmaBufferVirtual[2]; pointers to begin of DMA buffer */
 	short *ul_DmaBufferVirtual[2];	/*  pointers to begin of DMA buffer */
 	unsigned int ul_DmaBufferHw[2];	/*  hw address of DMA buff */
 	unsigned int ui_DmaBufferSize[2];	/*  size of dma buffer in bytes */
 	unsigned int ui_DmaBufferUsesize[2];	/*  which size we may now used for transfer */
-	unsigned int ui_DmaBufferSamples[2];	/*  size in samples */
 	unsigned int ui_DmaBufferPages[2];	/*  number of pages in buffer */
 	unsigned char b_DigitalOutputRegister;	/*  Digital Output Register */
 	unsigned char b_OutputMemoryStatus;
-	unsigned char b_AnalogInputChannelNbr;	/*  Analog input channel Nbr */
-	unsigned char b_AnalogOutputChannelNbr;	/*  Analog input Output  Nbr */
 	unsigned char b_TimerSelectMode;	/*  Contain data written at iobase + 0C */
 	unsigned char b_ModeSelectRegister;	/*  Contain data written at iobase + 0E */
 	unsigned short us_OutputRegister;	/*  Contain data written at iobase + 0 */
-	unsigned char b_InterruptState;
-	unsigned char b_TimerInit;	/*  Specify if InitTimerWatchdog was load */
-	unsigned char b_TimerStarted;	/*  Specify if timer 2 is running or not */
 	unsigned char b_Timer2Mode;	/*  Specify the timer 2 mode */
 	unsigned char b_Timer2Interrupt;	/* Timer2  interrupt enable or disable */
 	unsigned char b_AiCyclicAcquisition;	/*  indicate cyclic acquisition */
 	unsigned char b_InterruptMode;	/*  eoc eos or dma */
 	unsigned char b_EocEosInterrupt;	/*  Enable disable eoc eos interrupt */
 	unsigned int ui_EocEosConversionTime;
-	unsigned char b_EocEosConversionTimeBase;
 	unsigned char b_SingelDiff;
 	unsigned char b_ExttrigEnable;	/* To enable or disable external trigger */
 
@@ -365,7 +323,6 @@ struct addi_private {
 	} s_InterruptParameters;
 
 	union str_ModuleInfo s_ModuleInfo[4];
-	unsigned int ul_TTLPortConfiguration[10];
 
 	/* Parameters read from EEPROM overriding static board info */
 	struct {
@@ -376,7 +333,6 @@ struct addi_private {
 		int i_NbrDiChannel;	/*  Number of DI channels */
 		int i_NbrDoChannel;	/*  Number of DO channels */
 		int i_DoMaxdata;	/*  data to set all channels high */
-		int i_Dma;		/*  dma present or not */
 		int i_Timer;		/*  timer subdevice present or not */
 		unsigned int ui_MinAcquisitiontimeNs;
 					/*  Minimum Acquisition in Nano secs */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,13 +20,6 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * You should also find the complete GPL in the COPYING file accompanying
- * this source code.
  */
 
 #define NVRAM_USER_DATA_START	0x100
@@ -302,7 +295,7 @@ static void addi_eeprom_read_ai_info(str
 	devpriv->s_EeParameters.ui_MinDelaytimeNs = tmp * 1000;
 
 	tmp = addi_eeprom_readw(iobase, type, addr + 20);
-	devpriv->s_EeParameters.i_Dma = (tmp >> 13) & 0x01;
+	/* dma = (tmp >> 13) & 0x01; */
 
 	tmp = addi_eeprom_readw(iobase, type, addr + 72) & 0xff;
 	if (tmp) {		/* > 0 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
@@ -724,9 +720,7 @@ static int i_APCI3120_StopCyclicAcquisit
 	inb(dev->iobase + APCI3120_RESET_FIFO);
 	inw(dev->iobase + APCI3120_RD_STATUS);
 	devpriv->ui_AiActualScan = 0;
-	devpriv->ui_AiActualScanPosition = 0;
 	s->async->cur_chan = 0;
-	devpriv->ui_AiBufferPtr = 0;
 	devpriv->b_AiContinuous = 0;
 	devpriv->ui_DmaActualBuffer = 0;
 
@@ -895,9 +889,7 @@ static int i_APCI3120_CyclicAnalogInput(
 	/* END JK 07.05.04: Comparison between WIN32 and Linux driver */
 
 	devpriv->ui_AiActualScan = 0;
-	devpriv->ui_AiActualScanPosition = 0;
 	s->async->cur_chan = 0;
-	devpriv->ui_AiBufferPtr = 0;
 	devpriv->ui_DmaActualBuffer = 0;
 
 	/*  value for timer2  minus -2 has to be done .....dunno y?? */
@@ -1351,8 +1343,6 @@ static int i_APCI3120_CommandAnalogInput
 	devpriv->ui_AiScanLength = cmd->scan_end_arg;
 	devpriv->pui_AiChannelList = cmd->chanlist;
 
-	/* UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data; */
-	devpriv->AiData = s->async->prealloc_buf;
 	/* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */
 	devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@ This program is free software; you can r
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
 @endverbatim
 */
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1376 +0,0 @@
-/**
-@verbatim
-
-Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
-
-	ADDI-DATA GmbH
-	Dieselstrasse 3
-	D-77833 Ottersweier
-	Tel: +19(0)7223/9493-0
-	Fax: +49(0)7223/9493-92
-	http://www.addi-data.com
-	info@addi-data.com
-
-This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
-@endverbatim
-*/
-/*
-  +-----------------------------------------------------------------------+
-  | (C) ADDI-DATA GmbH          Dieselstrasse 3      D-77833 Ottersweier  |
-  +-----------------------------------------------------------------------+
-  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
-  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
-  +-----------------------------------------------------------------------+
-  | Project     : APCI-3XXX       | Compiler   : GCC                      |
-  | Module name : hwdrv_apci3xxx.c| Version    : 2.96                     |
-  +-------------------------------+---------------------------------------+
-  | Project manager: S. Weber     | Date       :  15/09/2005              |
-  +-----------------------------------------------------------------------+
-  | Description :APCI3XXX Module.  Hardware abstraction Layer for APCI3XXX|
-  +-----------------------------------------------------------------------+
-  |                             UPDATE'S                                  |
-  +-----------------------------------------------------------------------+
-  |   Date   |   Author  |          Description of updates                |
-  +----------+-----------+------------------------------------------------+
-  |          | 		 | 						  |
-  |          |           |						  |
-  +----------+-----------+------------------------------------------------+
-*/
-
-#ifndef COMEDI_SUBD_TTLIO
-#define COMEDI_SUBD_TTLIO	11	/* Digital Input Output But TTL */
-#endif
-
-#define APCI3XXX_SINGLE				0
-#define APCI3XXX_DIFF				1
-#define APCI3XXX_CONFIGURATION			0
-
-#define APCI3XXX_TTL_INIT_DIRECTION_PORT2	0
-
-static const struct comedi_lrange range_apci3XXX_ai = {
-	8, {
-		BIP_RANGE(10),
-		BIP_RANGE(5),
-		BIP_RANGE(2),
-		BIP_RANGE(1),
-		UNI_RANGE(10),
-		UNI_RANGE(5),
-		UNI_RANGE(2),
-		UNI_RANGE(1)
-	}
-};
-
-static const struct comedi_lrange range_apci3XXX_ao = {
-	2, {
-		BIP_RANGE(10),
-		UNI_RANGE(10)
-	}
-};
-
-/*
-+----------------------------------------------------------------------------+
-|                         ANALOG INPUT FUNCTIONS                             |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_TestConversionStarted                 |
-|                          (struct comedi_device    *dev)                           |
-+----------------------------------------------------------------------------+
-| Task                Test if any conversion started                         |
-+----------------------------------------------------------------------------+
-| Input Parameters  : -                                                      |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      : 0 : Conversion not started                             |
-|                     1 : Conversion started                                 |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev)
-{
-	struct addi_private *devpriv = dev->private;
-
-	if ((readl(devpriv->dw_AiBase + 8) & 0x80000UL) == 0x80000UL)
-		return 1;
-	else
-		return 0;
-
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_AnalogInputConfigOperatingMode        |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task           Converting mode and convert time selection                  |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_SingleDiff  = (unsigned char)  data[1];                       |
-|                     b_TimeBase    = (unsigned char)  data[2]; (0: ns, 1:micros 2:ms)|
-|                    dw_ReloadValue = (unsigned int) data[3];                       |
-|                     ........                                               |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0 : No error                                           |
-|                    -1 : Single/Diff selection error                        |
-|                    -2 : Convert time base unity selection error            |
-|                    -3 : Convert time value selection error                 |
-|                    -10: Any conversion started                             |
-|                    ....                                                    |
-|                    -100 : Config command error                             |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev,
-						     struct comedi_subdevice *s,
-						     struct comedi_insn *insn,
-						     unsigned int *data)
-{
-	const struct addi_board *this_board = comedi_board(dev);
-	struct addi_private *devpriv = dev->private;
-	int i_ReturnValue = insn->n;
-	unsigned char b_TimeBase = 0;
-	unsigned char b_SingleDiff = 0;
-	unsigned int dw_ReloadValue = 0;
-	unsigned int dw_TestReloadValue = 0;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
-
-	if (insn->n == 4) {
-	   /****************************/
-		/* Get the Singel/Diff flag */
-	   /****************************/
-
-		b_SingleDiff = (unsigned char) data[1];
-
-	   /****************************/
-		/* Get the time base unitiy */
-	   /****************************/
-
-		b_TimeBase = (unsigned char) data[2];
-
-	   /*************************************/
-		/* Get the convert time reload value */
-	   /*************************************/
-
-		dw_ReloadValue = (unsigned int) data[3];
-
-	   /**********************/
-		/* Test the time base */
-	   /**********************/
-
-		if ((this_board->b_AvailableConvertUnit & (1 << b_TimeBase)) !=
-			0) {
-	      /*******************************/
-			/* Test the convert time value */
-	      /*******************************/
-
-			if (dw_ReloadValue <= 65535) {
-				dw_TestReloadValue = dw_ReloadValue;
-
-				if (b_TimeBase == 1) {
-					dw_TestReloadValue =
-						dw_TestReloadValue * 1000UL;
-				}
-				if (b_TimeBase == 2) {
-					dw_TestReloadValue =
-						dw_TestReloadValue * 1000000UL;
-				}
-
-		 /*******************************/
-				/* Test the convert time value */
-		 /*******************************/
-
-				if (dw_TestReloadValue >=
-					devpriv->s_EeParameters.
-					ui_MinAcquisitiontimeNs) {
-					if ((b_SingleDiff == APCI3XXX_SINGLE)
-						|| (b_SingleDiff ==
-							APCI3XXX_DIFF)) {
-						if (((b_SingleDiff == APCI3XXX_SINGLE)
-						        && (devpriv->s_EeParameters.i_NbrAiChannel == 0))
-						    || ((b_SingleDiff == APCI3XXX_DIFF)
-							&& (this_board->i_NbrAiChannelDiff == 0))
-						    ) {
-			   /*******************************/
-							/* Single/Diff selection error */
-			   /*******************************/
-
-							printk("Single/Diff selection error\n");
-							i_ReturnValue = -1;
-						} else {
-			   /**********************************/
-							/* Test if conversion not started */
-			   /**********************************/
-
-							if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
-								devpriv->
-									ui_EocEosConversionTime
-									=
-									(unsigned int)
-									dw_ReloadValue;
-								devpriv->
-									b_EocEosConversionTimeBase
-									=
-									b_TimeBase;
-								devpriv->
-									b_SingelDiff
-									=
-									b_SingleDiff;
-								devpriv->
-									b_AiInitialisation
-									= 1;
-
-			      /*******************************/
-								/* Set the convert timing unit */
-			      /*******************************/
-
-								writel((unsigned int)b_TimeBase,
-									devpriv->dw_AiBase + 36);
-
-			      /**************************/
-								/* Set the convert timing */
-			      /*************************/
-
-								writel(dw_ReloadValue, devpriv->dw_AiBase + 32);
-							} else {
-			      /**************************/
-								/* Any conversion started */
-			      /**************************/
-
-								printk("Any conversion started\n");
-								i_ReturnValue =
-									-10;
-							}
-						}
-					} else {
-		       /*******************************/
-						/* Single/Diff selection error */
-		       /*******************************/
-
-						printk("Single/Diff selection error\n");
-						i_ReturnValue = -1;
-					}
-				} else {
-		    /************************/
-					/* Time selection error */
-		    /************************/
-
-					printk("Convert time value selection error\n");
-					i_ReturnValue = -3;
-				}
-			} else {
-		 /************************/
-				/* Time selection error */
-		 /************************/
-
-				printk("Convert time value selection error\n");
-				i_ReturnValue = -3;
-			}
-		} else {
-	      /*****************************/
-			/* Time base selection error */
-	      /*****************************/
-
-			printk("Convert time base unity selection error\n");
-			i_ReturnValue = -2;
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
-	}
-
-	return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_InsnConfigAnalogInput                 |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task           Converting mode and convert time selection                  |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_ConvertMode = (unsigned char)  data[0];                       |
-|                     b_TimeBase    = (unsigned char)  data[1]; (0: ns, 1:micros 2:ms)|
-|                    dw_ReloadValue = (unsigned int) data[2];                       |
-|                     ........                                               |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0: No error                                            |
-|                    ....                                                    |
-|                    -100 : Config command error                             |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev,
-					    struct comedi_subdevice *s,
-					    struct comedi_insn *insn,
-					    unsigned int *data)
-{
-	int i_ReturnValue = insn->n;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
-
-	if (insn->n >= 1) {
-		switch ((unsigned char) data[0]) {
-		case APCI3XXX_CONFIGURATION:
-			i_ReturnValue =
-				i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
-				s, insn, data);
-			break;
-
-		default:
-			i_ReturnValue = -100;
-			printk("Config command error %d\n", data[0]);
-			break;
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
-	}
-
-	return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_InsnReadAnalogInput                   |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task                Read 1 analog input                                    |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Range             = CR_RANGE(insn->chanspec);        |
-|                     b_Channel           = CR_CHAN(insn->chanspec);         |
-|                     dw_NbrOfAcquisition = insn->n;                         |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0: No error                                            |
-|                    -3 : Channel selection error                            |
-|                    -4 : Configuration selelection error                    |
-|                    -10: Any conversion started                             |
-|                    ....                                                    |
-|                    -100 : Config command error                             |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
-					  struct comedi_subdevice *s,
-					  struct comedi_insn *insn,
-					  unsigned int *data)
-{
-	const struct addi_board *this_board = comedi_board(dev);
-	struct addi_private *devpriv = dev->private;
-	int i_ReturnValue = insn->n;
-	unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec);
-	unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
-	unsigned int dw_Temp = 0;
-	unsigned int dw_Configuration = 0;
-	unsigned int dw_AcquisitionCpt = 0;
-	unsigned char b_Interrupt = 0;
-
-	/*************************************/
-	/* Test if operating mode configured */
-	/*************************************/
-
-	if (devpriv->b_AiInitialisation) {
-	   /***************************/
-		/* Test the channel number */
-	   /***************************/
-
-		if (((b_Channel < devpriv->s_EeParameters.i_NbrAiChannel)
-				&& (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
-			|| ((b_Channel < this_board->i_NbrAiChannelDiff)
-				&& (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
-	      /**********************************/
-			/* Test the channel configuration */
-	      /**********************************/
-
-			if (b_Configuration > 7) {
-		 /***************************/
-				/* Channel not initialised */
-		 /***************************/
-
-				i_ReturnValue = -4;
-				printk("Channel %d range %d selection error\n",
-					b_Channel, b_Configuration);
-			}
-		} else {
-	      /***************************/
-			/* Channel selection error */
-	      /***************************/
-
-			i_ReturnValue = -3;
-			printk("Channel %d selection error\n", b_Channel);
-		}
-
-	   /**************************/
-		/* Test if no error occur */
-	   /**************************/
-
-		if (i_ReturnValue >= 0) {
-	      /************************/
-			/* Test the buffer size */
-	      /************************/
-
-			if ((b_Interrupt != 0) || ((b_Interrupt == 0)
-					&& (insn->n >= 1))) {
-		 /**********************************/
-				/* Test if conversion not started */
-		 /**********************************/
-
-				if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
-		    /******************/
-					/* Clear the FIFO */
-		    /******************/
-
-					writel(0x10000UL, devpriv->dw_AiBase + 12);
-
-		    /*******************************/
-					/* Get and save the delay mode */
-		    /*******************************/
-
-					dw_Temp = readl(devpriv->dw_AiBase + 4);
-					dw_Temp = dw_Temp & 0xFFFFFEF0UL;
-
-		    /***********************************/
-					/* Channel configuration selection */
-		    /***********************************/
-
-					writel(dw_Temp, devpriv->dw_AiBase + 4);
-
-		    /**************************/
-					/* Make the configuration */
-		    /**************************/
-
-					dw_Configuration =
-						(b_Configuration & 3) |
-						((unsigned int) (b_Configuration >> 2)
-						<< 6) | ((unsigned int) devpriv->
-						b_SingelDiff << 7);
-
-		    /***************************/
-					/* Write the configuration */
-		    /***************************/
-
-					writel(dw_Configuration,
-					       devpriv->dw_AiBase + 0);
-
-		    /*********************/
-					/* Channel selection */
-		    /*********************/
-
-					writel(dw_Temp | 0x100UL,
-					       devpriv->dw_AiBase + 4);
-					writel((unsigned int) b_Channel,
-					       devpriv->dw_AiBase + 0);
-
-		    /***********************/
-					/* Restaure delay mode */
-		    /***********************/
-
-					writel(dw_Temp, devpriv->dw_AiBase + 4);
-
-		    /***********************************/
-					/* Set the number of sequence to 1 */
-		    /***********************************/
-
-					writel(1, devpriv->dw_AiBase + 48);
-
-		    /***************************/
-					/* Save the interrupt flag */
-		    /***************************/
-
-					devpriv->b_EocEosInterrupt =
-						b_Interrupt;
-
-		    /*******************************/
-					/* Save the number of channels */
-		    /*******************************/
-
-					devpriv->ui_AiNbrofChannels = 1;
-
-		    /******************************/
-					/* Test if interrupt not used */
-		    /******************************/
-
-					if (b_Interrupt == 0) {
-						for (dw_AcquisitionCpt = 0;
-							dw_AcquisitionCpt <
-							insn->n;
-							dw_AcquisitionCpt++) {
-			  /************************/
-							/* Start the conversion */
-			  /************************/
-
-							writel(0x80000UL, devpriv->dw_AiBase + 8);
-
-			  /****************/
-							/* Wait the EOS */
-			  /****************/
-
-							do {
-								dw_Temp = readl(devpriv->dw_AiBase + 20);
-								dw_Temp = dw_Temp & 1;
-							} while (dw_Temp != 1);
-
-			  /*************************/
-							/* Read the analog value */
-			  /*************************/
-
-							data[dw_AcquisitionCpt] = (unsigned int)readl(devpriv->dw_AiBase + 28);
-						}
-					} else {
-		       /************************/
-						/* Start the conversion */
-		       /************************/
-
-						writel(0x180000UL, devpriv->dw_AiBase + 8);
-					}
-				} else {
-		    /**************************/
-					/* Any conversion started */
-		    /**************************/
-
-					printk("Any conversion started\n");
-					i_ReturnValue = -10;
-				}
-			} else {
-		 /*******************/
-				/* Data size error */
-		 /*******************/
-
-				printk("Buffer size error\n");
-				i_ReturnValue = -101;
-			}
-		}
-	} else {
-	   /***************************/
-		/* Channel selection error */
-	   /***************************/
-
-		printk("Operating mode not configured\n");
-		i_ReturnValue = -1;
-	}
-	return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name     : void v_APCI3XXX_Interrupt (int            irq,         |
-|                                                void           *d)       |
-+----------------------------------------------------------------------------+
-| Task              :Interrupt handler for APCI3XXX                          |
-|                    When interrupt occurs this gets called.                 |
-|                    First it finds which interrupt has been generated and   |
-|                    handles  corresponding interrupt                        |
-+----------------------------------------------------------------------------+
-| Input Parameters  : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      : -                                                      |
-+----------------------------------------------------------------------------+
-*/
-
-static void v_APCI3XXX_Interrupt(int irq, void *d)
-{
-	struct comedi_device *dev = d;
-	struct addi_private *devpriv = dev->private;
-	unsigned char b_CopyCpt = 0;
-	unsigned int dw_Status = 0;
-
-	/***************************/
-	/* Test if interrupt occur */
-	/***************************/
-
-	dw_Status = readl(devpriv->dw_AiBase + 16);
-	if ( (dw_Status & 0x2UL) == 0x2UL) {
-	   /***********************/
-		/* Reset the interrupt */
-	   /***********************/
-
-		writel(dw_Status, devpriv->dw_AiBase + 16);
-
-	   /*****************************/
-		/* Test if interrupt enabled */
-	   /*****************************/
-
-		if (devpriv->b_EocEosInterrupt == 1) {
-	      /********************************/
-			/* Read all analog inputs value */
-	      /********************************/
-
-			for (b_CopyCpt = 0;
-				b_CopyCpt < devpriv->ui_AiNbrofChannels;
-				b_CopyCpt++) {
-				devpriv->ui_AiReadData[b_CopyCpt] =
-					(unsigned int)readl(devpriv->dw_AiBase + 28);
-			}
-
-	      /**************************/
-			/* Set the interrupt flag */
-	      /**************************/
-
-			devpriv->b_EocEosInterrupt = 2;
-
-	      /**********************************************/
-			/* Send a signal to from kernel to user space */
-	      /**********************************************/
-
-			send_sig(SIGIO, devpriv->tsk_Current, 0);
-		}
-	}
-}
-
-/*
-+----------------------------------------------------------------------------+
-|                            ANALOG OUTPUT SUBDEVICE                         |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_InsnWriteAnalogOutput                 |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task                Read 1 analog input                                    |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Range    = CR_RANGE(insn->chanspec);                 |
-|                     b_Channel  = CR_CHAN(insn->chanspec);                  |
-|                     data[0]    = analog value;                             |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0: No error                                            |
-|                    -3 : Channel selection error                            |
-|                    -4 : Configuration selelection error                    |
-|                    ....                                                    |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
-					    struct comedi_subdevice *s,
-					    struct comedi_insn *insn,
-					    unsigned int *data)
-{
-	struct addi_private *devpriv = dev->private;
-	unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec);
-	unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
-	unsigned int dw_Status = 0;
-	int i_ReturnValue = insn->n;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
-
-	if (insn->n >= 1) {
-	   /***************************/
-		/* Test the channel number */
-	   /***************************/
-
-		if (b_Channel < devpriv->s_EeParameters.i_NbrAoChannel) {
-	      /**********************************/
-			/* Test the channel configuration */
-	      /**********************************/
-
-			if (b_Range < 2) {
-		 /***************************/
-				/* Set the range selection */
-		 /***************************/
-
-				writel(b_Range, devpriv->dw_AiBase + 96);
-
-		 /**************************************************/
-				/* Write the analog value to the selected channel */
-		 /**************************************************/
-
-				writel((data[0] << 8) | b_Channel,
-					devpriv->dw_AiBase + 100);
-
-		 /****************************/
-				/* Wait the end of transfer */
-		 /****************************/
-
-				do {
-					dw_Status = readl(devpriv->dw_AiBase + 96);
-				} while ((dw_Status & 0x100) != 0x100);
-			} else {
-		 /***************************/
-				/* Channel not initialised */
-		 /***************************/
-
-				i_ReturnValue = -4;
-				printk("Channel %d range %d selection error\n",
-					b_Channel, b_Range);
-			}
-		} else {
-	      /***************************/
-			/* Channel selection error */
-	      /***************************/
-
-			i_ReturnValue = -3;
-			printk("Channel %d selection error\n", b_Channel);
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
-	}
-
-	return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-|                              TTL FUNCTIONS                                 |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_InsnConfigInitTTLIO                   |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task           You must calling this function be                           |
-|                for you call any other function witch access of TTL.        |
-|                APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_InitType    = (unsigned char) data[0];                        |
-|                     b_Port2Mode   = (unsigned char) data[1];                        |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0: No error                                            |
-|                    -1: Port 2 mode selection is wrong                      |
-|                    ....                                                    |
-|                    -100 : Config command error                             |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev,
-					  struct comedi_subdevice *s,
-					  struct comedi_insn *insn,
-					  unsigned int *data)
-{
-	struct addi_private *devpriv = dev->private;
-	int i_ReturnValue = insn->n;
-	unsigned char b_Command = 0;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
-
-	if (insn->n >= 1) {
-	   /*******************/
-		/* Get the command */
-		/* **************** */
-
-		b_Command = (unsigned char) data[0];
-
-	   /********************/
-		/* Test the command */
-	   /********************/
-
-		if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
-	      /***************************************/
-			/* Test the initialisation buffer size */
-	      /***************************************/
-
-			if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
-				&& (insn->n != 2)) {
-		 /*******************/
-				/* Data size error */
-		 /*******************/
-
-				printk("Buffer size error\n");
-				i_ReturnValue = -101;
-			}
-		} else {
-	      /************************/
-			/* Config command error */
-	      /************************/
-
-			printk("Command selection error\n");
-			i_ReturnValue = -100;
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
-	}
-
-	/*********************************************************************************/
-	/* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
-	/*********************************************************************************/
-
-	if ((i_ReturnValue >= 0)
-		&& (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
-	   /**********************/
-		/* Test the direction */
-	   /**********************/
-
-		if ((data[1] == 0) || (data[1] == 0xFF)) {
-	      /**************************/
-			/* Save the configuration */
-	      /**************************/
-
-			devpriv->ul_TTLPortConfiguration[0] =
-				devpriv->ul_TTLPortConfiguration[0] | data[1];
-		} else {
-	      /************************/
-			/* Port direction error */
-	      /************************/
-
-			printk("Port 2 direction selection error\n");
-			i_ReturnValue = -1;
-		}
-	}
-
-	/**************************/
-	/* Test if no error occur */
-	/**************************/
-
-	if (i_ReturnValue >= 0) {
-	   /***********************************/
-		/* Test if TTL port initilaisation */
-	   /***********************************/
-
-		if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
-	      /*************************/
-			/* Set the configuration */
-	      /*************************/
-
-			outl(data[1], devpriv->iobase + 224);
-		}
-	}
-
-	return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-|                        TTL INPUT FUNCTIONS                                 |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int     i_APCI3XXX_InsnBitsTTLIO                       |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task              : Write the selected output mask and read the status from|
-|                     all TTL channles                                       |
-+----------------------------------------------------------------------------+
-| Input Parameters  : dw_ChannelMask = data [0];                             |
-|                     dw_BitMask     = data [1];                             |
-+----------------------------------------------------------------------------+
-| Output Parameters : data[1] : All TTL channles states                      |
-+----------------------------------------------------------------------------+
-| Return Value      : >0  : No error                                         |
-|                    -4   : Channel mask error                               |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev,
-				    struct comedi_subdevice *s,
-				    struct comedi_insn *insn,
-				    unsigned int *data)
-{
-	struct addi_private *devpriv = dev->private;
-	int i_ReturnValue = insn->n;
-	unsigned char b_ChannelCpt = 0;
-	unsigned int dw_ChannelMask = 0;
-	unsigned int dw_BitMask = 0;
-	unsigned int dw_Status = 0;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
-
-	if (insn->n >= 2) {
-	   /*******************************/
-		/* Get the channe and bit mask */
-	   /*******************************/
-
-		dw_ChannelMask = data[0];
-		dw_BitMask = data[1];
-
-	   /*************************/
-		/* Test the channel mask */
-	   /*************************/
-
-		if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
-			(((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
-				|| (((devpriv->ul_TTLPortConfiguration[0] &
-							0xFF) == 0)
-					&& ((dw_ChannelMask & 0XFF0000) ==
-						0)))) {
-	      /*********************************/
-			/* Test if set/reset any channel */
-	      /*********************************/
-
-			if (dw_ChannelMask) {
-		 /****************************************/
-				/* Test if set/rest any port 0 channels */
-		 /****************************************/
-
-				if (dw_ChannelMask & 0xFF) {
-		    /*******************************************/
-					/* Read port 0 (first digital output port) */
-		    /*******************************************/
-
-					dw_Status = inl(devpriv->iobase + 80);
-
-					for (b_ChannelCpt = 0; b_ChannelCpt < 8;
-						b_ChannelCpt++) {
-						if ((dw_ChannelMask >>
-								b_ChannelCpt) &
-							1) {
-							dw_Status =
-								(dw_Status &
-								(0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
-						}
-					}
-
-					outl(dw_Status, devpriv->iobase + 80);
-				}
-
-		 /****************************************/
-				/* Test if set/rest any port 2 channels */
-		 /****************************************/
-
-				if (dw_ChannelMask & 0xFF0000) {
-					dw_BitMask = dw_BitMask >> 16;
-					dw_ChannelMask = dw_ChannelMask >> 16;
-
-		    /********************************************/
-					/* Read port 2 (second digital output port) */
-		    /********************************************/
-
-					dw_Status = inl(devpriv->iobase + 112);
-
-					for (b_ChannelCpt = 0; b_ChannelCpt < 8;
-						b_ChannelCpt++) {
-						if ((dw_ChannelMask >>
-								b_ChannelCpt) &
-							1) {
-							dw_Status =
-								(dw_Status &
-								(0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
-						}
-					}
-
-					outl(dw_Status, devpriv->iobase + 112);
-				}
-			}
-
-	      /*******************************************/
-			/* Read port 0 (first digital output port) */
-	      /*******************************************/
-
-			data[1] = inl(devpriv->iobase + 80);
-
-	      /******************************************/
-			/* Read port 1 (first digital input port) */
-	      /******************************************/
-
-			data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
-
-	      /************************/
-			/* Test if port 2 input */
-	      /************************/
-
-			if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
-				data[1] =
-					data[1] | (inl(devpriv->iobase +
-						96) << 16);
-			} else {
-				data[1] =
-					data[1] | (inl(devpriv->iobase +
-						112) << 16);
-			}
-		} else {
-	      /************************/
-			/* Config command error */
-	      /************************/
-
-			printk("Channel mask error\n");
-			i_ReturnValue = -4;
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
-	}
-
-	return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int i_APCI3XXX_InsnReadTTLIO                           |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task              : Read the status from selected channel                  |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
-+----------------------------------------------------------------------------+
-| Output Parameters : data[0] : Selected TTL channel state                   |
-+----------------------------------------------------------------------------+
-| Return Value      : 0   : No error                                         |
-|                    -3   : Channel selection error                          |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev,
-				    struct comedi_subdevice *s,
-				    struct comedi_insn *insn,
-				    unsigned int *data)
-{
-	struct addi_private *devpriv = dev->private;
-	unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
-	int i_ReturnValue = insn->n;
-	unsigned int *pls_ReadData = data;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
-
-	if (insn->n >= 1) {
-	   /***********************/
-		/* Test if read port 0 */
-	   /***********************/
-
-		if (b_Channel < 8) {
-	      /*******************************************/
-			/* Read port 0 (first digital output port) */
-	      /*******************************************/
-
-			pls_ReadData[0] = inl(devpriv->iobase + 80);
-			pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
-		} else {
-	      /***********************/
-			/* Test if read port 1 */
-	      /***********************/
-
-			if ((b_Channel > 7) && (b_Channel < 16)) {
-		 /******************************************/
-				/* Read port 1 (first digital input port) */
-		 /******************************************/
-
-				pls_ReadData[0] = inl(devpriv->iobase + 64);
-				pls_ReadData[0] =
-					(pls_ReadData[0] >> (b_Channel -
-						8)) & 1;
-			} else {
-		 /***********************/
-				/* Test if read port 2 */
-		 /***********************/
-
-				if ((b_Channel > 15) && (b_Channel < 24)) {
-		    /************************/
-					/* Test if port 2 input */
-		    /************************/
-
-					if ((devpriv->ul_TTLPortConfiguration[0]
-							& 0xFF) == 0) {
-						pls_ReadData[0] =
-							inl(devpriv->iobase +
-							96);
-						pls_ReadData[0] =
-							(pls_ReadData[0] >>
-							(b_Channel - 16)) & 1;
-					} else {
-						pls_ReadData[0] =
-							inl(devpriv->iobase +
-							112);
-						pls_ReadData[0] =
-							(pls_ReadData[0] >>
-							(b_Channel - 16)) & 1;
-					}
-				} else {
-		    /***************************/
-					/* Channel selection error */
-		    /***************************/
-
-					i_ReturnValue = -3;
-					printk("Channel %d selection error\n",
-						b_Channel);
-				}
-			}
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
-	}
-
-	return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-|                        TTL OUTPUT FUNCTIONS                                |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int     i_APCI3XXX_InsnWriteTTLIO                      |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task              : Set the state from TTL output channel                  |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
-|                     b_State   = data [0]                                   |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      : 0   : No error                                         |
-|                    -3   : Channel selection error                          |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
-				     struct comedi_subdevice *s,
-				     struct comedi_insn *insn,
-				     unsigned int *data)
-{
-	struct addi_private *devpriv = dev->private;
-	int i_ReturnValue = insn->n;
-	unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
-	unsigned char b_State = 0;
-	unsigned int dw_Status = 0;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
-
-	if (insn->n >= 1) {
-		b_State = (unsigned char) data[0];
-
-	   /***********************/
-		/* Test if read port 0 */
-	   /***********************/
-
-		if (b_Channel < 8) {
-	      /*****************************************************************************/
-			/* Read port 0 (first digital output port) and set/reset the selected channel */
-	      /*****************************************************************************/
-
-			dw_Status = inl(devpriv->iobase + 80);
-			dw_Status =
-				(dw_Status & (0xFF -
-					(1 << b_Channel))) | ((b_State & 1) <<
-				b_Channel);
-			outl(dw_Status, devpriv->iobase + 80);
-		} else {
-	      /***********************/
-			/* Test if read port 2 */
-	      /***********************/
-
-			if ((b_Channel > 15) && (b_Channel < 24)) {
-		 /*************************/
-				/* Test if port 2 output */
-		 /*************************/
-
-				if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
-					== 0xFF) {
-		    /*****************************************************************************/
-					/* Read port 2 (first digital output port) and set/reset the selected channel */
-		    /*****************************************************************************/
-
-					dw_Status = inl(devpriv->iobase + 112);
-					dw_Status =
-						(dw_Status & (0xFF -
-							(1 << (b_Channel -
-									16)))) |
-						((b_State & 1) << (b_Channel -
-							16));
-					outl(dw_Status, devpriv->iobase + 112);
-				} else {
-		    /***************************/
-					/* Channel selection error */
-		    /***************************/
-
-					i_ReturnValue = -3;
-					printk("Channel %d selection error\n",
-						b_Channel);
-				}
-			} else {
-		 /***************************/
-				/* Channel selection error */
-		 /***************************/
-
-				i_ReturnValue = -3;
-				printk("Channel %d selection error\n",
-					b_Channel);
-			}
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
-	}
-
-	return i_ReturnValue;
-}
-
-static int apci3xxx_di_insn_bits(struct comedi_device *dev,
-				 struct comedi_subdevice *s,
-				 struct comedi_insn *insn,
-				 unsigned int *data)
-{
-	struct addi_private *devpriv = dev->private;
-
-	data[1] = inl(devpriv->iobase + 32) & 0xf;
-
-	return insn->n;
-}
-
-static int apci3xxx_do_insn_bits(struct comedi_device *dev,
-				 struct comedi_subdevice *s,
-				 struct comedi_insn *insn,
-				 unsigned int *data)
-{
-	struct addi_private *devpriv = dev->private;
-	unsigned int mask = data[0];
-	unsigned int bits = data[1];
-
-	s->state = inl(devpriv->iobase + 48) & 0xf;
-	if (mask) {
-		s->state &= ~mask;
-		s->state |= (bits & mask);
-
-		outl(s->state, devpriv->iobase + 48);
-	}
-
-	data[1] = s->state;
-
-	return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function   Name   : int i_APCI3XXX_Reset(struct comedi_device *dev)               |                                                         +----------------------------------------------------------------------------+
-| Task              :resets all the registers                                |
-+----------------------------------------------------------------------------+
-| Input Parameters  : struct comedi_device *dev                                     |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      : -                                                      |
-+----------------------------------------------------------------------------+
-*/
-
-static int i_APCI3XXX_Reset(struct comedi_device *dev)
-{
-	struct addi_private *devpriv = dev->private;
-	unsigned char b_Cpt = 0;
-
-	/*************************/
-	/* Disable the interrupt */
-	/*************************/
-
-	disable_irq(dev->irq);
-
-	/****************************/
-	/* Reset the interrupt flag */
-	/****************************/
-
-	devpriv->b_EocEosInterrupt = 0;
-
-	/***************************/
-	/* Clear the start command */
-	/***************************/
-
-	writel(0, devpriv->dw_AiBase + 8);
-
-	/*****************************/
-	/* Reset the interrupt flags */
-	/*****************************/
-
-	writel(readl(devpriv->dw_AiBase + 16), devpriv->dw_AiBase + 16);
-
-	/*****************/
-	/* clear the EOS */
-	/*****************/
-
-	readl(devpriv->dw_AiBase + 20);
-
-	/******************/
-	/* Clear the FIFO */
-	/******************/
-
-	for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
-		readl(devpriv->dw_AiBase + 28);
-	}
-
-	/************************/
-	/* Enable the interrupt */
-	/************************/
-
-	enable_irq(dev->irq);
-
-	return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_watchdog.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_watchdog.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/addi_watchdog.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/addi_watchdog.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,10 +16,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include "../comedidev.h"
@@ -130,14 +126,12 @@ int addi_watchdog_init(struct comedi_sub
 {
 	struct addi_watchdog_private *spriv;
 
-	spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
+	spriv = comedi_alloc_spriv(s, sizeof(*spriv));
 	if (!spriv)
 		return -ENOMEM;
 
 	spriv->iobase = iobase;
 
-	s->private	= spriv;
-
 	s->type		= COMEDI_SUBD_TIMER;
 	s->subdev_flags	= SDF_WRITEABLE;
 	s->n_chan	= 1;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adl_pci6208.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adl_pci6208.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adl_pci6208.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adl_pci6208.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,10 +20,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 /*
 Driver: adl_pci6208
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adl_pci7x3x.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adl_pci7x3x.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adl_pci7x3x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adl_pci7x3x.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,10 +19,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adl_pci8164.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adl_pci8164.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adl_pci8164.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adl_pci8164.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,10 +13,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adl_pci9111.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adl_pci9111.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adl_pci9111.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adl_pci9111.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,10 +17,6 @@ This program is distributed in the hope
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adq12b.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adq12b.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adq12b.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adq12b.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: adq12b
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adv_pci1723.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adv_pci1723.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adv_pci1723.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adv_pci1723.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*
    comedi/drivers/pci1723.c
 
    COMEDI - Linux Control and Measurement Device Interface
@@ -13,12 +13,7 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*******************************************************************************/
+*/
 /*
 Driver: adv_pci1723
 Description: Advantech PCI-1723
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adv_pci1724.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adv_pci1724.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adv_pci1724.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adv_pci1724.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,12 +17,7 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************/
+*/
 
 /*
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adv_pci_dio.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adv_pci_dio.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/adv_pci_dio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/adv_pci_dio.c	2013-08-25 20:43:22.000000000 -0400
@@ -1173,19 +1173,11 @@ static int pci_dio_auto_attach(struct co
 static void pci_dio_detach(struct comedi_device *dev)
 {
 	struct pci_dio_private *devpriv = dev->private;
-	struct comedi_subdevice *s;
-	int i;
 
 	if (devpriv) {
 		if (devpriv->valid)
 			pci_dio_reset(dev);
 	}
-	for (i = 0; i < dev->n_subdevices; i++) {
-		s = &dev->subdevices[i];
-		if (s->type == COMEDI_SUBD_DIO)
-			comedi_spriv_free(dev, i);
-		s->private = NULL; /* some private data is static */
-	}
 	comedi_pci_disable(dev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/aio_aio12_8.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/aio_aio12_8.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/aio_aio12_8.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/aio_aio12_8.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
@@ -259,17 +255,11 @@ static int aio_aio12_8_attach(struct com
 	return 0;
 }
 
-static void aio_aio12_8_detach(struct comedi_device *dev)
-{
-	comedi_spriv_free(dev, 2);
-	comedi_legacy_detach(dev);
-}
-
 static struct comedi_driver aio_aio12_8_driver = {
 	.driver_name	= "aio_aio12_8",
 	.module		= THIS_MODULE,
 	.attach		= aio_aio12_8_attach,
-	.detach		= aio_aio12_8_detach,
+	.detach		= comedi_legacy_detach,
 	.board_name	= &board_types[0].name,
 	.num_names	= ARRAY_SIZE(board_types),
 	.offset		= sizeof(struct aio12_8_boardtype),
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/aio_iiro_16.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/aio_iiro_16.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/aio_iiro_16.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/aio_iiro_16.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_dio200.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_dio200.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_dio200.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_dio200.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
  * Driver: amplc_dio200
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_dio200_common.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_dio200_common.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_dio200_common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_dio200_common.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #include <linux/interrupt.h>
@@ -561,7 +556,7 @@ dio200_subdev_intr_init(struct comedi_de
 	const struct dio200_layout *layout = dio200_dev_layout(dev);
 	struct dio200_subdev_intr *subpriv;
 
-	subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+	subpriv = comedi_alloc_spriv(s, sizeof(*subpriv));
 	if (!subpriv)
 		return -ENOMEM;
 
@@ -573,7 +568,6 @@ dio200_subdev_intr_init(struct comedi_de
 		/* Disable interrupt sources. */
 		dio200_write8(dev, subpriv->ofs, 0);
 
-	s->private = subpriv;
 	s->type = COMEDI_SUBD_DI;
 	s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
 	if (layout->has_int_sce) {
@@ -888,11 +882,10 @@ dio200_subdev_8254_init(struct comedi_de
 	struct dio200_subdev_8254 *subpriv;
 	unsigned int chan;
 
-	subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+	subpriv = comedi_alloc_spriv(s, sizeof(*subpriv));
 	if (!subpriv)
 		return -ENOMEM;
 
-	s->private = subpriv;
 	s->type = COMEDI_SUBD_COUNTER;
 	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
 	s->n_chan = 3;
@@ -1024,11 +1017,12 @@ static int dio200_subdev_8255_init(struc
 {
 	struct dio200_subdev_8255 *subpriv;
 
-	subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+	subpriv = comedi_alloc_spriv(s, sizeof(*subpriv));
 	if (!subpriv)
 		return -ENOMEM;
+
 	subpriv->ofs = offset;
-	s->private = subpriv;
+
 	s->type = COMEDI_SUBD_DIO;
 	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
 	s->n_chan = 24;
@@ -1230,28 +1224,11 @@ void amplc_dio200_common_detach(struct c
 {
 	const struct dio200_board *thisboard = comedi_board(dev);
 	struct dio200_private *devpriv = dev->private;
-	const struct dio200_layout *layout;
-	unsigned n;
 
 	if (!thisboard || !devpriv)
 		return;
 	if (dev->irq)
 		free_irq(dev->irq, dev);
-	if (dev->subdevices) {
-		layout = dio200_board_layout(thisboard);
-		for (n = 0; n < dev->n_subdevices; n++) {
-			switch (layout->sdtype[n]) {
-			case sd_8254:
-			case sd_8255:
-			case sd_intr:
-				comedi_spriv_free(dev, n);
-				break;
-			case sd_timer:
-			default:
-				break;
-			}
-		}
-	}
 }
 EXPORT_SYMBOL_GPL(amplc_dio200_common_detach);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_dio200.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_dio200.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_dio200.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_dio200.h	2013-08-25 20:43:22.000000000 -0400
@@ -18,11 +18,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef AMPLC_DIO200_H_INCLUDED
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_dio200_pci.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_dio200_pci.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_dio200_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_dio200_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
  * Driver: amplc_dio200_pci
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pc236.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pc236.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pc236.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pc236.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: amplc_pc236
@@ -543,7 +538,6 @@ static void pc236_detach(struct comedi_d
 		return;
 	if (dev->iobase)
 		pc236_intr_disable(dev);
-	comedi_spriv_free(dev, 0);
 	if (is_isa_board(thisboard)) {
 		comedi_legacy_detach(dev);
 	} else if (is_pci_board(thisboard)) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pc263.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pc263.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pc263.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pc263.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: amplc_pc263
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pci224.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pci224.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pci224.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pci224.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: amplc_pci224
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pci230.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pci230.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pci230.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pci230.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,10 +16,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   */
 /*
 Driver: amplc_pci230
@@ -2834,7 +2830,6 @@ static void pci230_detach(struct comedi_
 {
 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 
-	comedi_spriv_free(dev, 2);
 	if (dev->irq)
 		free_irq(dev->irq, dev);
 	comedi_pci_disable(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pci263.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pci263.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/amplc_pci263.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/amplc_pci263.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: amplc_pci263
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/c6xdigio.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/c6xdigio.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/c6xdigio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/c6xdigio.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: c6xdigio
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_das16_cs.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_das16_cs.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_das16_cs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_das16_cs.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,10 +15,6 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
     PCMCIA support code for this driver is adapted from the dummy_cs.c
     driver of the Linux PCMCIA Card Services package.
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcidas64.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcidas64.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcidas64.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcidas64.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,12 +28,7 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************/
+*/
 
 /*
  * Driver: cb_pcidas64
@@ -4163,7 +4158,6 @@ static void detach(struct comedi_device
 					devpriv->ao_dma_desc_bus_addr);
 		}
 	}
-	comedi_spriv_free(dev, 4);
 	comedi_pci_disable(dev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcidas.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcidas.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcidas.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcidas.c	2013-08-25 20:43:22.000000000 -0400
@@ -19,12 +19,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************
 */
 /*
 Driver: cb_pcidas
@@ -1608,7 +1602,6 @@ static void cb_pcidas_detach(struct come
 	}
 	if (dev->irq)
 		free_irq(dev->irq, dev);
-	comedi_spriv_free(dev, 2);
 	comedi_pci_disable(dev);
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcidda.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcidda.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcidda.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcidda.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,10 +17,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -397,18 +393,11 @@ static int cb_pcidda_auto_attach(struct
 	return 0;
 }
 
-static void cb_pcidda_detach(struct comedi_device *dev)
-{
-	comedi_spriv_free(dev, 1);
-	comedi_spriv_free(dev, 2);
-	comedi_pci_disable(dev);
-}
-
 static struct comedi_driver cb_pcidda_driver = {
 	.driver_name	= "cb_pcidda",
 	.module		= THIS_MODULE,
 	.auto_attach	= cb_pcidda_auto_attach,
-	.detach		= cb_pcidda_detach,
+	.detach		= comedi_pci_disable,
 };
 
 static int cb_pcidda_pci_probe(struct pci_dev *dev,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcimdas.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcimdas.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcimdas.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcimdas.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: cb_pcimdas
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcimdda.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcimdda.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/cb_pcimdda.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/cb_pcimdda.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,11 +15,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: cb_pcimdda
@@ -197,17 +192,11 @@ static int cb_pcimdda_auto_attach(struct
 	return 1;
 }
 
-static void cb_pcimdda_detach(struct comedi_device *dev)
-{
-	comedi_spriv_free(dev, 1);
-	comedi_pci_disable(dev);
-}
-
 static struct comedi_driver cb_pcimdda_driver = {
 	.driver_name	= "cb_pcimdda",
 	.module		= THIS_MODULE,
 	.auto_attach	= cb_pcimdda_auto_attach,
-	.detach		= cb_pcimdda_detach,
+	.detach		= comedi_pci_disable,
 };
 
 static int cb_pcimdda_pci_probe(struct pci_dev *dev,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_bond.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_bond.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_bond.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_bond.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,11 +15,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: comedi_bond
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_fc.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_fc.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_fc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_fc.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,12 +17,7 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************/
+*/
 
 #include "../comedidev.h"
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_fc.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_fc.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_fc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_fc.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,12 +17,7 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************/
+*/
 
 #ifndef _COMEDI_FC_H
 #define _COMEDI_FC_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_parport.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_parport.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_parport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_parport.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: comedi_parport
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_test.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_test.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/comedi_test.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/comedi_test.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,12 +21,7 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************/
+*/
 /*
 Driver: comedi_test
 Description: generates fake waveforms
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/contec_pci_dio.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/contec_pci_dio.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/contec_pci_dio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/contec_pci_dio.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,11 +13,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: contec_pci_dio
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/daqboard2000.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/daqboard2000.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/daqboard2000.c	2013-07-01 10:42:02.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/daqboard2000.c	2013-08-31 18:01:50.000000000 -0400
@@ -14,11 +14,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: daqboard2000
@@ -110,7 +105,6 @@ Configuration options: not applicable, u
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/firmware.h>
 
 #include "../comedidev.h"
 
@@ -524,7 +518,8 @@ static int daqboard2000_writeCPLD(struct
 }
 
 static int initialize_daqboard2000(struct comedi_device *dev,
-				   const u8 *cpld_array, size_t len)
+				   const u8 *cpld_array, size_t len,
+				   unsigned long context)
 {
 	struct daqboard2000_private *devpriv = dev->private;
 	int result = -EIO;
@@ -565,22 +560,6 @@ static int initialize_daqboard2000(struc
 	return result;
 }
 
-static int daqboard2000_upload_firmware(struct comedi_device *dev)
-{
-	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-	const struct firmware *fw;
-	int ret;
-
-	ret = reject_firmware(&fw, DAQBOARD2000_FIRMWARE, &pcidev->dev);
-	if (ret)
-		return ret;
-
-	ret = initialize_daqboard2000(dev, fw->data, fw->size);
-	release_firmware(fw);
-
-	return ret;
-}
-
 static void daqboard2000_adcStopDmaTransfer(struct comedi_device *dev)
 {
 }
@@ -724,7 +703,9 @@ static int daqboard2000_auto_attach(stru
 
 	readl(devpriv->plx + 0x6c);
 
-	result = daqboard2000_upload_firmware(dev);
+	result = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
+				      DAQBOARD2000_FIRMWARE,
+				      initialize_daqboard2000, 0);
 	if (result < 0)
 		return result;
 
@@ -766,7 +747,6 @@ static void daqboard2000_detach(struct c
 {
 	struct daqboard2000_private *devpriv = dev->private;
 
-	comedi_spriv_free(dev, 2);
 	if (dev->irq)
 		free_irq(dev->irq, dev);
 	if (devpriv) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,12 +16,6 @@
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *****************************************************************
  */
 
 /*
@@ -566,12 +560,6 @@ int das08_common_attach(struct comedi_de
 }
 EXPORT_SYMBOL_GPL(das08_common_attach);
 
-void das08_common_detach(struct comedi_device *dev)
-{
-	comedi_spriv_free(dev, 4);
-}
-EXPORT_SYMBOL_GPL(das08_common_detach);
-
 static int __init das08_init(void)
 {
 	return 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08_cs.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08_cs.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08_cs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08_cs.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,19 +16,12 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
     PCMCIA support code for this driver is adapted from the dummy_cs.c
     driver of the Linux PCMCIA Card Services package.
 
     The initial developer of the original code is David A. Hinds
     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-*****************************************************************
-
 */
 /*
 Driver: das08_cs
@@ -93,17 +86,11 @@ static int das08_cs_auto_attach(struct c
 	return das08_common_attach(dev, iobase);
 }
 
-static void das08_cs_detach(struct comedi_device *dev)
-{
-	das08_common_detach(dev);
-	comedi_pcmcia_disable(dev);
-}
-
 static struct comedi_driver driver_das08_cs = {
 	.driver_name	= "das08_cs",
 	.module		= THIS_MODULE,
 	.auto_attach	= das08_cs_auto_attach,
-	.detach		= das08_cs_detach,
+	.detach		= comedi_pcmcia_disable,
 };
 
 static int das08_pcmcia_attach(struct pcmcia_device *link)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _DAS08_H
@@ -52,6 +47,5 @@ struct das08_private_struct {
 };
 
 int das08_common_attach(struct comedi_device *dev, unsigned long iobase);
-void das08_common_detach(struct comedi_device *dev);
 
 #endif /* _DAS08_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08_isa.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08_isa.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08_isa.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08_isa.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,10 +16,6 @@
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -193,17 +189,11 @@ static int das08_isa_attach(struct comed
 	return das08_common_attach(dev, dev->iobase);
 }
 
-static void das08_isa_detach(struct comedi_device *dev)
-{
-	das08_common_detach(dev);
-	comedi_legacy_detach(dev);
-}
-
 static struct comedi_driver das08_isa_driver = {
 	.driver_name	= "isa-das08",
 	.module		= THIS_MODULE,
 	.attach		= das08_isa_attach,
-	.detach		= das08_isa_detach,
+	.detach		= comedi_legacy_detach,
 	.board_name	= &das08_isa_boards[0].name,
 	.num_names	= ARRAY_SIZE(das08_isa_boards),
 	.offset		= sizeof(das08_isa_boards[0]),
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08_pci.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08_pci.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das08_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das08_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,10 +16,6 @@
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -79,17 +75,11 @@ static int das08_pci_auto_attach(struct
 	return das08_common_attach(dev, dev->iobase);
 }
 
-static void das08_pci_detach(struct comedi_device *dev)
-{
-	das08_common_detach(dev);
-	comedi_pci_disable(dev);
-}
-
 static struct comedi_driver das08_pci_comedi_driver = {
 	.driver_name	= "pci-das08",
 	.module		= THIS_MODULE,
 	.auto_attach	= das08_pci_auto_attach,
-	.detach		= das08_pci_detach,
+	.detach		= comedi_pci_disable,
 };
 
 static int das08_pci_probe(struct pci_dev *dev,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das16.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das16.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das16.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das16.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,12 +16,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************
 */
 /*
 Driver: das16
@@ -1339,7 +1333,6 @@ static void das16_detach(struct comedi_d
 	struct das16_private_struct *devpriv = dev->private;
 
 	das16_reset(dev);
-	comedi_spriv_free(dev, 4);
 	if (devpriv) {
 		int i;
 		for (i = 0; i < 2; i++) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das16m1.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das16m1.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das16m1.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das16m1.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,12 +17,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************
 */
 /*
 Driver: das16m1
@@ -672,7 +666,6 @@ static void das16m1_detach(struct comedi
 {
 	struct das16m1_private_struct *devpriv = dev->private;
 
-	comedi_spriv_free(dev, 3);
 	if (devpriv && devpriv->extra_iobase)
 		release_region(devpriv->extra_iobase, DAS16M1_SIZE2);
 	comedi_legacy_detach(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das1800.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das1800.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das1800.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das1800.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,12 +15,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************
 */
 /*
 Driver: das1800
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das6402.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das6402.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das6402.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das6402.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,11 +22,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: das6402
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das800.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das800.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/das800.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/das800.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,12 +15,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************
 */
 /*
 Driver: das800
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dmm32at.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dmm32at.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dmm32at.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dmm32at.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: dmm32at
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt2811.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt2811.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt2811.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt2811.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,10 +18,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 /*
 Driver: dt2811
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt2814.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt2814.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt2814.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt2814.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: dt2814
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt2815.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt2815.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt2815.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt2815.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: dt2815
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt2817.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt2817.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt2817.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt2817.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: dt2817
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt282x.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt282x.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt282x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt282x.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: dt282x
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt3000.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt3000.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt3000.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt3000.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: dt3000
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt9812.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt9812.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dt9812.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dt9812.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,11 +15,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 /*
@@ -43,14 +38,11 @@ for my needs.
  *      says P1).
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/kref.h>
 #include <linux/uaccess.h>
 #include <linux/usb.h>
 
@@ -60,6 +52,9 @@ for my needs.
 #define DT9812_MAX_WRITE_CMD_PIPE_SIZE	32
 #define DT9812_MAX_READ_CMD_PIPE_SIZE	32
 
+/* usb_bulk_msg() timout in milliseconds */
+#define DT9812_USB_TIMEOUT		1000
+
 /*
  * See Silican Laboratories C8051F020/1/2/3 manual
  */
@@ -242,87 +237,25 @@ struct dt9812_usb_cmd {
 		struct dt9812_write_multi write_multi_info;
 		struct dt9812_rmw_multi rmw_multi_info;
 	} u;
-#if 0
-	WRITE_BYTE_INFO WriteByteInfo;
-	READ_BYTE_INFO ReadByteInfo;
-	WRITE_MULTI_INFO WriteMultiInfo;
-	READ_MULTI_INFO ReadMultiInfo;
-	RMW_BYTE_INFO RMWByteInfo;
-	RMW_MULTI_INFO RMWMultiInfo;
-	DAC_THRESHOLD_INFO DacThresholdInfo;
-	INT_ON_CHANGE_MASK_INFO IntOnChangeMaskInfo;
-	CGL_INFO CglInfo;
-	SUBSYSTEM_INFO SubsystemInfo;
-	CAL_POT_CMD CalPotCmd;
-	WRITE_DEV_BYTE_INFO WriteDevByteInfo;
-	READ_DEV_BYTE_INFO ReadDevByteInfo;
-	WRITE_DEV_MULTI_INFO WriteDevMultiInfo;
-	READ_DEV_MULTI_INFO ReadDevMultiInfo;
-	READ_SINGLE_VALUE_INFO ReadSingleValueInfo;
-	WRITE_SINGLE_VALUE_INFO WriteSingleValueInfo;
-#endif
-};
-
-#define DT9812_NUM_SLOTS	16
-
-static DEFINE_SEMAPHORE(dt9812_mutex);
-
-static const struct usb_device_id dt9812_table[] = {
-	{USB_DEVICE(0x0867, 0x9812)},
-	{}			/* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE(usb, dt9812_table);
-
-struct usb_dt9812 {
-	struct slot_dt9812 *slot;
-	struct usb_device *udev;
-	struct usb_interface *interface;
-	u16 vendor;
-	u16 product;
-	u16 device;
-	u32 serial;
+struct dt9812_private {
+	struct semaphore sem;
 	struct {
 		__u8 addr;
 		size_t size;
-	} message_pipe, command_write, command_read, write_stream, read_stream;
-	struct kref kref;
-	u16 analog_out_shadow[2];
-	u8 digital_out_shadow;
-};
-
-struct comedi_dt9812 {
-	struct slot_dt9812 *slot;
-	u32 serial;
-};
-
-struct slot_dt9812 {
-	struct semaphore mutex;
-	u32 serial;
-	struct usb_dt9812 *usb;
-	struct comedi_dt9812 *comedi;
+	} cmd_wr, cmd_rd;
+	u16 device;
+	u16 ao_shadow[2];
 };
 
-static struct slot_dt9812 dt9812[DT9812_NUM_SLOTS];
-
-static inline struct usb_dt9812 *to_dt9812_dev(struct kref *d)
-{
-	return container_of(d, struct usb_dt9812, kref);
-}
-
-static void dt9812_delete(struct kref *kref)
-{
-	struct usb_dt9812 *dev = to_dt9812_dev(kref);
-
-	usb_put_dev(dev->udev);
-	kfree(dev);
-}
-
-static int dt9812_read_info(struct usb_dt9812 *dev, int offset, void *buf,
-			    size_t buf_size)
+static int dt9812_read_info(struct comedi_device *dev,
+			    int offset, void *buf, size_t buf_size)
 {
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct dt9812_private *devpriv = dev->private;
 	struct dt9812_usb_cmd cmd;
-	int count, retval;
+	int count, ret;
 
 	cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
 	cmd.u.flash_data_info.address =
@@ -330,25 +263,23 @@ static int dt9812_read_info(struct usb_d
 	cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size);
 
 	/* DT9812 only responds to 32 byte writes!! */
-	count = 32;
-	retval = usb_bulk_msg(dev->udev,
-			      usb_sndbulkpipe(dev->udev,
-					      dev->command_write.addr),
-			      &cmd, 32, &count, HZ * 1);
-	if (retval)
-		return retval;
-	retval = usb_bulk_msg(dev->udev,
-			      usb_rcvbulkpipe(dev->udev,
-					      dev->command_read.addr),
-			      buf, buf_size, &count, HZ * 1);
-	return retval;
+	ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
+			   &cmd, 32, &count, DT9812_USB_TIMEOUT);
+	if (ret)
+		return ret;
+
+	return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
+			    buf, buf_size, &count, DT9812_USB_TIMEOUT);
 }
 
-static int dt9812_read_multiple_registers(struct usb_dt9812 *dev, int reg_count,
-					  u8 *address, u8 *value)
+static int dt9812_read_multiple_registers(struct comedi_device *dev,
+					  int reg_count, u8 *address,
+					  u8 *value)
 {
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct dt9812_private *devpriv = dev->private;
 	struct dt9812_usb_cmd cmd;
-	int i, count, retval;
+	int i, count, ret;
 
 	cmd.cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG);
 	cmd.u.read_multi_info.count = reg_count;
@@ -356,26 +287,23 @@ static int dt9812_read_multiple_register
 		cmd.u.read_multi_info.address[i] = address[i];
 
 	/* DT9812 only responds to 32 byte writes!! */
-	count = 32;
-	retval = usb_bulk_msg(dev->udev,
-			      usb_sndbulkpipe(dev->udev,
-					      dev->command_write.addr),
-			      &cmd, 32, &count, HZ * 1);
-	if (retval)
-		return retval;
-	retval = usb_bulk_msg(dev->udev,
-			      usb_rcvbulkpipe(dev->udev,
-					      dev->command_read.addr),
-			      value, reg_count, &count, HZ * 1);
-	return retval;
+	ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
+			   &cmd, 32, &count, DT9812_USB_TIMEOUT);
+	if (ret)
+		return ret;
+
+	return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr),
+			    value, reg_count, &count, DT9812_USB_TIMEOUT);
 }
 
-static int dt9812_write_multiple_registers(struct usb_dt9812 *dev,
+static int dt9812_write_multiple_registers(struct comedi_device *dev,
 					   int reg_count, u8 *address,
 					   u8 *value)
 {
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct dt9812_private *devpriv = dev->private;
 	struct dt9812_usb_cmd cmd;
-	int i, count, retval;
+	int i, count;
 
 	cmd.cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG);
 	cmd.u.read_multi_info.count = reg_count;
@@ -383,19 +311,20 @@ static int dt9812_write_multiple_registe
 		cmd.u.write_multi_info.write[i].address = address[i];
 		cmd.u.write_multi_info.write[i].value = value[i];
 	}
+
 	/* DT9812 only responds to 32 byte writes!! */
-	retval = usb_bulk_msg(dev->udev,
-			      usb_sndbulkpipe(dev->udev,
-					      dev->command_write.addr),
-			      &cmd, 32, &count, HZ * 1);
-	return retval;
+	return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
+			    &cmd, 32, &count, DT9812_USB_TIMEOUT);
 }
 
-static int dt9812_rmw_multiple_registers(struct usb_dt9812 *dev, int reg_count,
+static int dt9812_rmw_multiple_registers(struct comedi_device *dev,
+					 int reg_count,
 					 struct dt9812_rmw_byte *rmw)
 {
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct dt9812_private *devpriv = dev->private;
 	struct dt9812_usb_cmd cmd;
-	int i, count, retval;
+	int i, count;
 
 	cmd.cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG);
 	cmd.u.rmw_multi_info.count = reg_count;
@@ -403,76 +332,52 @@ static int dt9812_rmw_multiple_registers
 		cmd.u.rmw_multi_info.rmw[i] = rmw[i];
 
 	/* DT9812 only responds to 32 byte writes!! */
-	retval = usb_bulk_msg(dev->udev,
-			      usb_sndbulkpipe(dev->udev,
-					      dev->command_write.addr),
-			      &cmd, 32, &count, HZ * 1);
-	return retval;
+	return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
+			    &cmd, 32, &count, DT9812_USB_TIMEOUT);
 }
 
-static int dt9812_digital_in(struct slot_dt9812 *slot, u8 *bits)
+static int dt9812_digital_in(struct comedi_device *dev, u8 *bits)
 {
-	int result = -ENODEV;
-
-	down(&slot->mutex);
-	if (slot->usb) {
-		u8 reg[2] = { F020_SFR_P3, F020_SFR_P1 };
-		u8 value[2];
+	struct dt9812_private *devpriv = dev->private;
+	u8 reg[2] = { F020_SFR_P3, F020_SFR_P1 };
+	u8 value[2];
+	int ret;
 
-		result = dt9812_read_multiple_registers(slot->usb, 2, reg,
-							value);
-		if (result == 0) {
-			/*
-			 * bits 0-6 in F020_SFR_P3 are bits 0-6 in the digital
-			 * input port bit 3 in F020_SFR_P1 is bit 7 in the
-			 * digital input port
-			 */
-			*bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4);
-			/* printk("%2.2x, %2.2x -> %2.2x\n",
-			   value[0], value[1], *bits); */
-		}
+	down(&devpriv->sem);
+	ret = dt9812_read_multiple_registers(dev, 2, reg, value);
+	if (ret == 0) {
+		/*
+		 * bits 0-6 in F020_SFR_P3 are bits 0-6 in the digital
+		 * input port bit 3 in F020_SFR_P1 is bit 7 in the
+		 * digital input port
+		 */
+		*bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4);
 	}
-	up(&slot->mutex);
+	up(&devpriv->sem);
 
-	return result;
+	return ret;
 }
 
-static int dt9812_digital_out(struct slot_dt9812 *slot, u8 bits)
+static int dt9812_digital_out(struct comedi_device *dev, u8 bits)
 {
-	int result = -ENODEV;
-
-	down(&slot->mutex);
-	if (slot->usb) {
-		u8 reg[1];
-		u8 value[1];
-
-		reg[0] = F020_SFR_P2;
-		value[0] = bits;
-		result = dt9812_write_multiple_registers(slot->usb, 1, reg,
-							 value);
-		slot->usb->digital_out_shadow = bits;
-	}
-	up(&slot->mutex);
-	return result;
-}
+	struct dt9812_private *devpriv = dev->private;
+	u8 reg[1] = { F020_SFR_P2 };
+	u8 value[1] = { bits };
+	int ret;
 
-static int dt9812_digital_out_shadow(struct slot_dt9812 *slot, u8 *bits)
-{
-	int result = -ENODEV;
+	down(&devpriv->sem);
+	ret = dt9812_write_multiple_registers(dev, 1, reg, value);
+	up(&devpriv->sem);
 
-	down(&slot->mutex);
-	if (slot->usb) {
-		*bits = slot->usb->digital_out_shadow;
-		result = 0;
-	}
-	up(&slot->mutex);
-	return result;
+	return ret;
 }
 
-static void dt9812_configure_mux(struct usb_dt9812 *dev,
+static void dt9812_configure_mux(struct comedi_device *dev,
 				 struct dt9812_rmw_byte *rmw, int channel)
 {
-	if (dev->device == DT9812_DEVID_DT9812_10) {
+	struct dt9812_private *devpriv = dev->private;
+
+	if (devpriv->device == DT9812_DEVID_DT9812_10) {
 		/* In the DT9812/10V MUX is selected by P1.5-7 */
 		rmw->address = F020_SFR_P1;
 		rmw->and_mask = 0xe0;
@@ -485,18 +390,21 @@ static void dt9812_configure_mux(struct
 	}
 }
 
-static void dt9812_configure_gain(struct usb_dt9812 *dev,
+static void dt9812_configure_gain(struct comedi_device *dev,
 				  struct dt9812_rmw_byte *rmw,
 				  enum dt9812_gain gain)
 {
-	if (dev->device == DT9812_DEVID_DT9812_10) {
-		/* In the DT9812/10V, there is an external gain of 0.5 */
+	struct dt9812_private *devpriv = dev->private;
+
+	/* In the DT9812/10V, there is an external gain of 0.5 */
+	if (devpriv->device == DT9812_DEVID_DT9812_10)
 		gain <<= 1;
-	}
 
 	rmw->address = F020_SFR_ADC0CF;
 	rmw->and_mask = F020_MASK_ADC0CF_AMP0GN2 |
-	    F020_MASK_ADC0CF_AMP0GN1 | F020_MASK_ADC0CF_AMP0GN0;
+			F020_MASK_ADC0CF_AMP0GN1 |
+			F020_MASK_ADC0CF_AMP0GN0;
+
 	switch (gain) {
 		/*
 		 * 000 -> Gain =  1
@@ -508,8 +416,10 @@ static void dt9812_configure_gain(struct
 		 */
 	case DT9812_GAIN_0PT5:
 		rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 |
-		    F020_MASK_ADC0CF_AMP0GN1;
+				F020_MASK_ADC0CF_AMP0GN1;
 		break;
+	default:
+		/* this should never happen, just use a gain of 1 */
 	case DT9812_GAIN_1:
 		rmw->or_value = 0x00;
 		break;
@@ -521,20 +431,18 @@ static void dt9812_configure_gain(struct
 		break;
 	case DT9812_GAIN_8:
 		rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 |
-		    F020_MASK_ADC0CF_AMP0GN0;
+				F020_MASK_ADC0CF_AMP0GN0;
 		break;
 	case DT9812_GAIN_16:
 		rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
 		break;
-	default:
-		dev_err(&dev->interface->dev, "Illegal gain %d\n", gain);
-
 	}
 }
 
-static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 *value,
-			    enum dt9812_gain gain)
+static int dt9812_analog_in(struct comedi_device *dev,
+			    int channel, u16 *value, enum dt9812_gain gain)
 {
+	struct dt9812_private *devpriv = dev->private;
 	struct dt9812_rmw_byte rmw[3];
 	u8 reg[3] = {
 		F020_SFR_ADC0CN,
@@ -542,31 +450,30 @@ static int dt9812_analog_in(struct slot_
 		F020_SFR_ADC0L
 	};
 	u8 val[3];
-	int result = -ENODEV;
+	int ret;
 
-	down(&slot->mutex);
-	if (!slot->usb)
-		goto exit;
+	down(&devpriv->sem);
 
 	/* 1 select the gain */
-	dt9812_configure_gain(slot->usb, &rmw[0], gain);
+	dt9812_configure_gain(dev, &rmw[0], gain);
 
 	/* 2 set the MUX to select the channel */
-	dt9812_configure_mux(slot->usb, &rmw[1], channel);
+	dt9812_configure_mux(dev, &rmw[1], channel);
 
 	/* 3 start conversion */
 	rmw[2].address = F020_SFR_ADC0CN;
 	rmw[2].and_mask = 0xff;
 	rmw[2].or_value = F020_MASK_ADC0CN_AD0EN | F020_MASK_ADC0CN_AD0BUSY;
 
-	result = dt9812_rmw_multiple_registers(slot->usb, 3, rmw);
-	if (result)
+	ret = dt9812_rmw_multiple_registers(dev, 3, rmw);
+	if (ret)
 		goto exit;
 
 	/* read the status and ADC */
-	result = dt9812_read_multiple_registers(slot->usb, 3, reg, val);
-	if (result)
+	ret = dt9812_read_multiple_registers(dev, 3, reg, val);
+	if (ret)
 		goto exit;
+
 	/*
 	 * An ADC conversion takes 16 SAR clocks cycles, i.e. about 9us.
 	 * Therefore, between the instant that AD0BUSY was set via
@@ -578,7 +485,7 @@ static int dt9812_analog_in(struct slot_
 	 */
 	if ((val[0] & (F020_MASK_ADC0CN_AD0INT | F020_MASK_ADC0CN_AD0BUSY)) ==
 	    F020_MASK_ADC0CN_AD0INT) {
-		switch (slot->usb->device) {
+		switch (devpriv->device) {
 		case DT9812_DEVID_DT9812_10:
 			/*
 			 * For DT9812-10V the personality module set the
@@ -594,422 +501,284 @@ static int dt9812_analog_in(struct slot_
 	}
 
 exit:
-	up(&slot->mutex);
-	return result;
+	up(&devpriv->sem);
+
+	return ret;
 }
 
-static int dt9812_analog_out_shadow(struct slot_dt9812 *slot, int channel,
-				    u16 *value)
+static int dt9812_analog_out(struct comedi_device *dev, int channel, u16 value)
 {
-	int result = -ENODEV;
+	struct dt9812_private *devpriv = dev->private;
+	struct dt9812_rmw_byte rmw[3];
+	int ret;
 
-	down(&slot->mutex);
-	if (slot->usb) {
-		*value = slot->usb->analog_out_shadow[channel];
-		result = 0;
+	down(&devpriv->sem);
+
+	switch (channel) {
+	case 0:
+		/* 1. Set DAC mode */
+		rmw[0].address = F020_SFR_DAC0CN;
+		rmw[0].and_mask = 0xff;
+		rmw[0].or_value = F020_MASK_DACxCN_DACxEN;
+
+		/* 2 load low byte of DAC value first */
+		rmw[1].address = F020_SFR_DAC0L;
+		rmw[1].and_mask = 0xff;
+		rmw[1].or_value = value & 0xff;
+
+		/* 3 load high byte of DAC value next to latch the
+			12-bit value */
+		rmw[2].address = F020_SFR_DAC0H;
+		rmw[2].and_mask = 0xff;
+		rmw[2].or_value = (value >> 8) & 0xf;
+		break;
+
+	case 1:
+		/* 1. Set DAC mode */
+		rmw[0].address = F020_SFR_DAC1CN;
+		rmw[0].and_mask = 0xff;
+		rmw[0].or_value = F020_MASK_DACxCN_DACxEN;
+
+		/* 2 load low byte of DAC value first */
+		rmw[1].address = F020_SFR_DAC1L;
+		rmw[1].and_mask = 0xff;
+		rmw[1].or_value = value & 0xff;
+
+		/* 3 load high byte of DAC value next to latch the
+			12-bit value */
+		rmw[2].address = F020_SFR_DAC1H;
+		rmw[2].and_mask = 0xff;
+		rmw[2].or_value = (value >> 8) & 0xf;
+		break;
 	}
-	up(&slot->mutex);
+	ret = dt9812_rmw_multiple_registers(dev, 3, rmw);
+	devpriv->ao_shadow[channel] = value;
 
-	return result;
+	up(&devpriv->sem);
+
+	return ret;
 }
 
-static int dt9812_analog_out(struct slot_dt9812 *slot, int channel, u16 value)
+static int dt9812_di_insn_bits(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn,
+			       unsigned int *data)
 {
-	int result = -ENODEV;
-
-	down(&slot->mutex);
-	if (slot->usb) {
-		struct dt9812_rmw_byte rmw[3];
+	u8 bits = 0;
+	int ret;
 
-		switch (channel) {
-		case 0:
-			/* 1. Set DAC mode */
-			rmw[0].address = F020_SFR_DAC0CN;
-			rmw[0].and_mask = 0xff;
-			rmw[0].or_value = F020_MASK_DACxCN_DACxEN;
+	ret = dt9812_digital_in(dev, &bits);
+	if (ret)
+		return ret;
 
-			/* 2 load low byte of DAC value first */
-			rmw[1].address = F020_SFR_DAC0L;
-			rmw[1].and_mask = 0xff;
-			rmw[1].or_value = value & 0xff;
+	data[1] = bits;
 
-			/* 3 load high byte of DAC value next to latch the
-			   12-bit value */
-			rmw[2].address = F020_SFR_DAC0H;
-			rmw[2].and_mask = 0xff;
-			rmw[2].or_value = (value >> 8) & 0xf;
-			break;
+	return insn->n;
+}
 
-		case 1:
-			/* 1. Set DAC mode */
-			rmw[0].address = F020_SFR_DAC1CN;
-			rmw[0].and_mask = 0xff;
-			rmw[0].or_value = F020_MASK_DACxCN_DACxEN;
+static int dt9812_do_insn_bits(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn,
+			       unsigned int *data)
+{
+	unsigned int mask = data[0];
+	unsigned int bits = data[1];
 
-			/* 2 load low byte of DAC value first */
-			rmw[1].address = F020_SFR_DAC1L;
-			rmw[1].and_mask = 0xff;
-			rmw[1].or_value = value & 0xff;
+	if (mask) {
+		s->state &= ~mask;
+		s->state |= (bits & mask);
 
-			/* 3 load high byte of DAC value next to latch the
-			   12-bit value */
-			rmw[2].address = F020_SFR_DAC1H;
-			rmw[2].and_mask = 0xff;
-			rmw[2].or_value = (value >> 8) & 0xf;
-			break;
-		}
-		result = dt9812_rmw_multiple_registers(slot->usb, 3, rmw);
-		slot->usb->analog_out_shadow[channel] = value;
+		dt9812_digital_out(dev, s->state);
 	}
-	up(&slot->mutex);
 
-	return result;
+	data[1] = s->state;
+
+	return insn->n;
 }
 
-/*
- * USB framework functions
- */
+static int dt9812_ai_insn_read(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn,
+			       unsigned int *data)
+{
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	u16 val = 0;
+	int ret;
+	int i;
 
-static int dt9812_probe(struct usb_interface *interface,
-			const struct usb_device_id *id)
+	for (i = 0; i < insn->n; i++) {
+		ret = dt9812_analog_in(dev, chan, &val, DT9812_GAIN_1);
+		if (ret)
+			return ret;
+		data[i] = val;
+	}
+
+	return insn->n;
+}
+
+static int dt9812_ao_insn_read(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn,
+			       unsigned int *data)
 {
-	int retval = -ENOMEM;
-	struct usb_dt9812 *dev = NULL;
-	struct usb_host_interface *iface_desc;
-	struct usb_endpoint_descriptor *endpoint;
+	struct dt9812_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
 	int i;
-	u8 fw;
 
-	/* allocate memory for our device state and initialize it */
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (dev == NULL)
-		goto error;
+	down(&devpriv->sem);
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_shadow[chan];
+	up(&devpriv->sem);
 
-	kref_init(&dev->kref);
+	return insn->n;
+}
 
-	dev->udev = usb_get_dev(interface_to_usbdev(interface));
-	dev->interface = interface;
+static int dt9812_ao_insn_write(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn,
+				unsigned int *data)
+{
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	int ret;
+	int i;
 
-	/* Check endpoints */
-	iface_desc = interface->cur_altsetting;
+	for (i = 0; i < insn->n; i++) {
+		ret = dt9812_analog_out(dev, chan, data[i]);
+		if (ret)
+			return ret;
+	}
 
-	if (iface_desc->desc.bNumEndpoints != 5) {
-		dev_err(&interface->dev, "Wrong number of endpoints.\n");
-		retval = -ENODEV;
-		goto error;
+	return insn->n;
+}
+
+static int dt9812_find_endpoints(struct comedi_device *dev)
+{
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
+	struct usb_host_interface *host = intf->cur_altsetting;
+	struct dt9812_private *devpriv = dev->private;
+	struct usb_endpoint_descriptor *ep;
+	int i;
+
+	if (host->desc.bNumEndpoints != 5) {
+		dev_err(dev->class_dev, "Wrong number of endpoints\n");
+		return -ENODEV;
 	}
 
-	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
-		int direction = -1;
-		endpoint = &iface_desc->endpoint[i].desc;
+	for (i = 0; i < host->desc.bNumEndpoints; ++i) {
+		int dir = -1;
+		ep = &host->endpoint[i].desc;
 		switch (i) {
 		case 0:
-			direction = USB_DIR_IN;
-			dev->message_pipe.addr = endpoint->bEndpointAddress;
-			dev->message_pipe.size =
-			    le16_to_cpu(endpoint->wMaxPacketSize);
-
+			/* unused message pipe */
+			dir = USB_DIR_IN;
 			break;
 		case 1:
-			direction = USB_DIR_OUT;
-			dev->command_write.addr = endpoint->bEndpointAddress;
-			dev->command_write.size =
-			    le16_to_cpu(endpoint->wMaxPacketSize);
+			dir = USB_DIR_OUT;
+			devpriv->cmd_wr.addr = ep->bEndpointAddress;
+			devpriv->cmd_wr.size = le16_to_cpu(ep->wMaxPacketSize);
 			break;
 		case 2:
-			direction = USB_DIR_IN;
-			dev->command_read.addr = endpoint->bEndpointAddress;
-			dev->command_read.size =
-			    le16_to_cpu(endpoint->wMaxPacketSize);
+			dir = USB_DIR_IN;
+			devpriv->cmd_rd.addr = ep->bEndpointAddress;
+			devpriv->cmd_rd.size = le16_to_cpu(ep->wMaxPacketSize);
 			break;
 		case 3:
-			direction = USB_DIR_OUT;
-			dev->write_stream.addr = endpoint->bEndpointAddress;
-			dev->write_stream.size =
-			    le16_to_cpu(endpoint->wMaxPacketSize);
+			/* unused write stream */
+			dir = USB_DIR_OUT;
 			break;
 		case 4:
-			direction = USB_DIR_IN;
-			dev->read_stream.addr = endpoint->bEndpointAddress;
-			dev->read_stream.size =
-			    le16_to_cpu(endpoint->wMaxPacketSize);
+			/* unused read stream */
+			dir = USB_DIR_IN;
 			break;
 		}
-		if ((endpoint->bEndpointAddress & USB_DIR_IN) != direction) {
-			dev_err(&interface->dev,
-				"Endpoint has wrong direction.\n");
-			retval = -ENODEV;
-			goto error;
+		if ((ep->bEndpointAddress & USB_DIR_IN) != dir) {
+			dev_err(dev->class_dev,
+				"Endpoint has wrong direction\n");
+			return -ENODEV;
 		}
 	}
-	if (dt9812_read_info(dev, 0, &fw, sizeof(fw)) != 0) {
+	return 0;
+}
+
+static int dt9812_reset_device(struct comedi_device *dev)
+{
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct dt9812_private *devpriv = dev->private;
+	u32 serial;
+	u16 vendor;
+	u16 product;
+	u16 tmp16;
+	u8 tmp8;
+	int ret;
+	int i;
+
+	ret = dt9812_read_info(dev, 0, &tmp8, sizeof(tmp8));
+	if (ret) {
 		/*
 		 * Seems like a configuration reset is necessary if driver is
 		 * reloaded while device is attached
 		 */
-		usb_reset_configuration(dev->udev);
+		usb_reset_configuration(usb);
 		for (i = 0; i < 10; i++) {
-			retval = dt9812_read_info(dev, 1, &fw, sizeof(fw));
-			if (retval == 0) {
-				dev_info(&interface->dev,
-					 "usb_reset_configuration succeeded "
-					 "after %d iterations\n", i);
+			ret = dt9812_read_info(dev, 1, &tmp8, sizeof(tmp8));
+			if (ret == 0)
 				break;
-			}
-		}
-	}
-
-	if (dt9812_read_info(dev, 1, &dev->vendor, sizeof(dev->vendor)) != 0) {
-		dev_err(&interface->dev, "Failed to read vendor.\n");
-		retval = -ENODEV;
-		goto error;
-	}
-	if (dt9812_read_info(dev, 3, &dev->product, sizeof(dev->product)) != 0) {
-		dev_err(&interface->dev, "Failed to read product.\n");
-		retval = -ENODEV;
-		goto error;
-	}
-	if (dt9812_read_info(dev, 5, &dev->device, sizeof(dev->device)) != 0) {
-		dev_err(&interface->dev, "Failed to read device.\n");
-		retval = -ENODEV;
-		goto error;
-	}
-	if (dt9812_read_info(dev, 7, &dev->serial, sizeof(dev->serial)) != 0) {
-		dev_err(&interface->dev, "Failed to read serial.\n");
-		retval = -ENODEV;
-		goto error;
-	}
-
-	dev->vendor = le16_to_cpu(dev->vendor);
-	dev->product = le16_to_cpu(dev->product);
-	dev->device = le16_to_cpu(dev->device);
-	dev->serial = le32_to_cpu(dev->serial);
-	switch (dev->device) {
-	case DT9812_DEVID_DT9812_10:
-		dev->analog_out_shadow[0] = 0x0800;
-		dev->analog_out_shadow[1] = 0x800;
-		break;
-	case DT9812_DEVID_DT9812_2PT5:
-		dev->analog_out_shadow[0] = 0x0000;
-		dev->analog_out_shadow[1] = 0x0000;
-		break;
-	}
-	dev->digital_out_shadow = 0;
-
-	/* save our data pointer in this interface device */
-	usb_set_intfdata(interface, dev);
-
-	/* let the user know what node this device is now attached to */
-	dev_info(&interface->dev, "USB DT9812 (%4.4x.%4.4x.%4.4x) #0x%8.8x\n",
-		 dev->vendor, dev->product, dev->device, dev->serial);
-
-	down(&dt9812_mutex);
-	{
-		/* Find a slot for the USB device */
-		struct slot_dt9812 *first = NULL;
-		struct slot_dt9812 *best = NULL;
-
-		for (i = 0; i < DT9812_NUM_SLOTS; i++) {
-			if (!first && !dt9812[i].usb && dt9812[i].serial == 0)
-				first = &dt9812[i];
-			if (!best && dt9812[i].serial == dev->serial)
-				best = &dt9812[i];
 		}
-
-		if (!best)
-			best = first;
-
-		if (best) {
-			down(&best->mutex);
-			best->usb = dev;
-			dev->slot = best;
-			up(&best->mutex);
+		if (ret) {
+			dev_err(dev->class_dev,
+				"unable to reset configuration\n");
+			return ret;
 		}
 	}
-	up(&dt9812_mutex);
-
-	return 0;
-
-error:
-	if (dev)
-		kref_put(&dev->kref, dt9812_delete);
-	return retval;
-}
-
-static void dt9812_disconnect(struct usb_interface *interface)
-{
-	struct usb_dt9812 *dev;
-	int minor = interface->minor;
 
-	down(&dt9812_mutex);
-	dev = usb_get_intfdata(interface);
-	if (dev->slot) {
-		down(&dev->slot->mutex);
-		dev->slot->usb = NULL;
-		up(&dev->slot->mutex);
-		dev->slot = NULL;
+	ret = dt9812_read_info(dev, 1, &vendor, sizeof(vendor));
+	if (ret) {
+		dev_err(dev->class_dev, "failed to read vendor id\n");
+		return ret;
 	}
-	usb_set_intfdata(interface, NULL);
-	up(&dt9812_mutex);
-
-	/* queue final destruction */
-	kref_put(&dev->kref, dt9812_delete);
-
-	dev_info(&interface->dev, "USB Dt9812 #%d now disconnected\n", minor);
-}
-
-static struct usb_driver dt9812_usb_driver = {
-	.name = "dt9812",
-	.probe = dt9812_probe,
-	.disconnect = dt9812_disconnect,
-	.id_table = dt9812_table,
-};
-
-/*
- * Comedi functions
- */
-
-static int dt9812_comedi_open(struct comedi_device *dev)
-{
-	struct comedi_dt9812 *devpriv = dev->private;
-	int result = -ENODEV;
-
-	down(&devpriv->slot->mutex);
-	if (devpriv->slot->usb) {
-		/* We have an attached device, fill in current range info */
-		struct comedi_subdevice *s;
-
-		s = &dev->subdevices[0];
-		s->n_chan = 8;
-		s->maxdata = 1;
-
-		s = &dev->subdevices[1];
-		s->n_chan = 8;
-		s->maxdata = 1;
-
-		s = &dev->subdevices[2];
-		s->n_chan = 8;
-		switch (devpriv->slot->usb->device) {
-		case 0:{
-				s->maxdata = 4095;
-				s->range_table = &range_bipolar10;
-			}
-			break;
-		case 1:{
-				s->maxdata = 4095;
-				s->range_table = &range_unipolar2_5;
-			}
-			break;
-		}
+	vendor = le16_to_cpu(vendor);
 
-		s = &dev->subdevices[3];
-		s->n_chan = 2;
-		switch (devpriv->slot->usb->device) {
-		case 0:{
-				s->maxdata = 4095;
-				s->range_table = &range_bipolar10;
-			}
-			break;
-		case 1:{
-				s->maxdata = 4095;
-				s->range_table = &range_unipolar2_5;
-			}
-			break;
-		}
-		result = 0;
+	ret = dt9812_read_info(dev, 3, &product, sizeof(product));
+	if (ret) {
+		dev_err(dev->class_dev, "failed to read product id\n");
+		return ret;
 	}
-	up(&devpriv->slot->mutex);
-	return result;
-}
-
-static int dt9812_di_rinsn(struct comedi_device *dev,
-			   struct comedi_subdevice *s, struct comedi_insn *insn,
-			   unsigned int *data)
-{
-	struct comedi_dt9812 *devpriv = dev->private;
-	unsigned int channel = CR_CHAN(insn->chanspec);
-	int n;
-	u8 bits = 0;
-
-	dt9812_digital_in(devpriv->slot, &bits);
-	for (n = 0; n < insn->n; n++)
-		data[n] = ((1 << channel) & bits) != 0;
-	return n;
-}
-
-static int dt9812_do_winsn(struct comedi_device *dev,
-			   struct comedi_subdevice *s, struct comedi_insn *insn,
-			   unsigned int *data)
-{
-	struct comedi_dt9812 *devpriv = dev->private;
-	unsigned int channel = CR_CHAN(insn->chanspec);
-	int n;
-	u8 bits = 0;
-
-	dt9812_digital_out_shadow(devpriv->slot, &bits);
-	for (n = 0; n < insn->n; n++) {
-		u8 mask = 1 << channel;
+	product = le16_to_cpu(product);
 
-		bits &= ~mask;
-		if (data[n])
-			bits |= mask;
+	ret = dt9812_read_info(dev, 5, &tmp16, sizeof(tmp16));
+	if (ret) {
+		dev_err(dev->class_dev, "failed to read device id\n");
+		return ret;
 	}
-	dt9812_digital_out(devpriv->slot, bits);
-	return n;
-}
-
-static int dt9812_ai_rinsn(struct comedi_device *dev,
-			   struct comedi_subdevice *s, struct comedi_insn *insn,
-			   unsigned int *data)
-{
-	struct comedi_dt9812 *devpriv = dev->private;
-	unsigned int channel = CR_CHAN(insn->chanspec);
-	int n;
-
-	for (n = 0; n < insn->n; n++) {
-		u16 value = 0;
+	devpriv->device = le16_to_cpu(tmp16);
 
-		dt9812_analog_in(devpriv->slot, channel, &value, DT9812_GAIN_1);
-		data[n] = value;
+	ret = dt9812_read_info(dev, 7, &serial, sizeof(serial));
+	if (ret) {
+		dev_err(dev->class_dev, "failed to read serial number\n");
+		return ret;
 	}
-	return n;
-}
+	serial = le32_to_cpu(serial);
 
-static int dt9812_ao_rinsn(struct comedi_device *dev,
-			   struct comedi_subdevice *s, struct comedi_insn *insn,
-			   unsigned int *data)
-{
-	struct comedi_dt9812 *devpriv = dev->private;
-	unsigned int channel = CR_CHAN(insn->chanspec);
-	int n;
-	u16 value;
+	/* let the user know what node this device is now attached to */
+	dev_info(dev->class_dev, "USB DT9812 (%4.4x.%4.4x.%4.4x) #0x%8.8x\n",
+		 vendor, product, devpriv->device, serial);
 
-	for (n = 0; n < insn->n; n++) {
-		value = 0;
-		dt9812_analog_out_shadow(devpriv->slot, channel, &value);
-		data[n] = value;
+	if (devpriv->device != DT9812_DEVID_DT9812_10 &&
+	    devpriv->device != DT9812_DEVID_DT9812_2PT5) {
+		dev_err(dev->class_dev, "Unsupported device!\n");
+		return -EINVAL;
 	}
-	return n;
-}
-
-static int dt9812_ao_winsn(struct comedi_device *dev,
-			   struct comedi_subdevice *s, struct comedi_insn *insn,
-			   unsigned int *data)
-{
-	struct comedi_dt9812 *devpriv = dev->private;
-	unsigned int channel = CR_CHAN(insn->chanspec);
-	int n;
 
-	for (n = 0; n < insn->n; n++)
-		dt9812_analog_out(devpriv->slot, channel, data[n]);
-	return n;
+	return 0;
 }
 
-static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int dt9812_auto_attach(struct comedi_device *dev,
+			      unsigned long context)
 {
-	struct comedi_dt9812 *devpriv;
-	int i;
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
+	struct dt9812_private *devpriv;
 	struct comedi_subdevice *s;
+	bool is_unipolar;
 	int ret;
 
 	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
@@ -1017,125 +786,107 @@ static int dt9812_attach(struct comedi_d
 		return -ENOMEM;
 	dev->private = devpriv;
 
-	/*
-	 * Special open routine, since USB unit may be unattached at
-	 * comedi_config time, hence range can not be determined
-	 */
-	dev->open = dt9812_comedi_open;
+	sema_init(&devpriv->sem, 1);
+	usb_set_intfdata(intf, devpriv);
 
-	devpriv->serial = it->options[0];
+	ret = dt9812_find_endpoints(dev);
+	if (ret)
+		return ret;
+
+	ret = dt9812_reset_device(dev);
+	if (ret)
+		return ret;
+
+	is_unipolar = (devpriv->device == DT9812_DEVID_DT9812_2PT5);
 
 	ret = comedi_alloc_subdevices(dev, 4);
 	if (ret)
 		return ret;
 
-	/* digital input subdevice */
+	/* Digital Input subdevice */
 	s = &dev->subdevices[0];
-	s->type = COMEDI_SUBD_DI;
-	s->subdev_flags = SDF_READABLE;
-	s->n_chan = 0;
-	s->maxdata = 1;
-	s->range_table = &range_digital;
-	s->insn_read = &dt9812_di_rinsn;
+	s->type		= COMEDI_SUBD_DI;
+	s->subdev_flags	= SDF_READABLE;
+	s->n_chan	= 8;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= dt9812_di_insn_bits;
 
-	/* digital output subdevice */
+	/* Digital Output subdevice */
 	s = &dev->subdevices[1];
-	s->type = COMEDI_SUBD_DO;
-	s->subdev_flags = SDF_WRITEABLE;
-	s->n_chan = 0;
-	s->maxdata = 1;
-	s->range_table = &range_digital;
-	s->insn_write = &dt9812_do_winsn;
+	s->type		= COMEDI_SUBD_DO;
+	s->subdev_flags	= SDF_WRITEABLE;
+	s->n_chan	= 8;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= dt9812_do_insn_bits;
 
-	/* analog input subdevice */
+	/* Analog Input subdevice */
 	s = &dev->subdevices[2];
-	s->type = COMEDI_SUBD_AI;
-	s->subdev_flags = SDF_READABLE | SDF_GROUND;
-	s->n_chan = 0;
-	s->maxdata = 1;
-	s->range_table = NULL;
-	s->insn_read = &dt9812_ai_rinsn;
+	s->type		= COMEDI_SUBD_AI;
+	s->subdev_flags	= SDF_READABLE | SDF_GROUND;
+	s->n_chan	= 8;
+	s->maxdata	= 0x0fff;
+	s->range_table	= is_unipolar ? &range_unipolar2_5 : &range_bipolar10;
+	s->insn_read	= dt9812_ai_insn_read;
 
-	/* analog output subdevice */
+	/* Analog Output subdevice */
 	s = &dev->subdevices[3];
-	s->type = COMEDI_SUBD_AO;
-	s->subdev_flags = SDF_WRITEABLE;
-	s->n_chan = 0;
-	s->maxdata = 1;
-	s->range_table = NULL;
-	s->insn_write = &dt9812_ao_winsn;
-	s->insn_read = &dt9812_ao_rinsn;
-
-	dev_info(dev->class_dev, "successfully attached to dt9812.\n");
+	s->type		= COMEDI_SUBD_AO;
+	s->subdev_flags	= SDF_WRITEABLE;
+	s->n_chan	= 2;
+	s->maxdata	= 0x0fff;
+	s->range_table	= is_unipolar ? &range_unipolar2_5 : &range_bipolar10;
+	s->insn_write	= dt9812_ao_insn_write;
+	s->insn_read	= dt9812_ao_insn_read;
 
-	down(&dt9812_mutex);
-	/* Find a slot for the comedi device */
-	{
-		struct slot_dt9812 *first = NULL;
-		struct slot_dt9812 *best = NULL;
-		for (i = 0; i < DT9812_NUM_SLOTS; i++) {
-			if (!first && !dt9812[i].comedi) {
-				/* First free slot from comedi side */
-				first = &dt9812[i];
-			}
-			if (!best &&
-			    dt9812[i].usb &&
-			    dt9812[i].usb->serial == devpriv->serial) {
-				/* We have an attaced device with matching ID */
-				best = &dt9812[i];
-			}
-		}
-		if (!best)
-			best = first;
-		if (best) {
-			down(&best->mutex);
-			best->comedi = devpriv;
-			best->serial = devpriv->serial;
-			devpriv->slot = best;
-			up(&best->mutex);
-		}
-	}
-	up(&dt9812_mutex);
+	devpriv->ao_shadow[0] = is_unipolar ? 0x0000 : 0x0800;
+	devpriv->ao_shadow[1] = is_unipolar ? 0x0000 : 0x0800;
 
 	return 0;
 }
 
 static void dt9812_detach(struct comedi_device *dev)
 {
-	/* Nothing to cleanup */
-}
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
+	struct dt9812_private *devpriv = dev->private;
 
-static struct comedi_driver dt9812_comedi_driver = {
-	.module = THIS_MODULE,
-	.driver_name = "dt9812",
-	.attach = dt9812_attach,
-	.detach = dt9812_detach,
-};
+	if (!devpriv)
+		return;
 
-static int __init usb_dt9812_init(void)
-{
-	int i;
+	down(&devpriv->sem);
 
-	/* Initialize all driver slots */
-	for (i = 0; i < DT9812_NUM_SLOTS; i++) {
-		sema_init(&dt9812[i].mutex, 1);
-		dt9812[i].serial = 0;
-		dt9812[i].usb = NULL;
-		dt9812[i].comedi = NULL;
-	}
-	dt9812[12].serial = 0x0;
+	usb_set_intfdata(intf, NULL);
 
-	return comedi_usb_driver_register(&dt9812_comedi_driver,
-						&dt9812_usb_driver);
+	up(&devpriv->sem);
 }
 
-static void __exit usb_dt9812_exit(void)
+static struct comedi_driver dt9812_driver = {
+	.driver_name	= "dt9812",
+	.module		= THIS_MODULE,
+	.auto_attach	= dt9812_auto_attach,
+	.detach		= dt9812_detach,
+};
+
+static int dt9812_usb_probe(struct usb_interface *intf,
+			    const struct usb_device_id *id)
 {
-	comedi_usb_driver_unregister(&dt9812_comedi_driver, &dt9812_usb_driver);
+	return comedi_usb_auto_config(intf, &dt9812_driver, id->driver_info);
 }
 
-module_init(usb_dt9812_init);
-module_exit(usb_dt9812_exit);
+static const struct usb_device_id dt9812_usb_table[] = {
+	{ USB_DEVICE(0x0867, 0x9812) },
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, dt9812_usb_table);
+
+static struct usb_driver dt9812_usb_driver = {
+	.name		= "dt9812",
+	.id_table	= dt9812_usb_table,
+	.probe		= dt9812_usb_probe,
+	.disconnect	= comedi_usb_auto_unconfig,
+};
+module_comedi_usb_driver(dt9812_driver, dt9812_usb_driver);
 
 MODULE_AUTHOR("Anders Blomdell <anders.blomdell@control.lth.se>");
 MODULE_DESCRIPTION("Comedi DT9812 driver");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dyna_pci10xx.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dyna_pci10xx.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/dyna_pci10xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/dyna_pci10xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,10 +11,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/gsc_hpdi.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/gsc_hpdi.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/gsc_hpdi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/gsc_hpdi.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,12 +18,7 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************/
+*/
 
 /*
  * Driver: gsc_hpdi
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/icp_multi.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/icp_multi.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/icp_multi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/icp_multi.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,11 +13,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/jr3_pci.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/jr3_pci.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/jr3_pci.c	2013-07-01 10:42:04.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/jr3_pci.c	2013-08-31 18:01:52.000000000 -0400
@@ -14,11 +14,6 @@
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
  * Driver: jr3_pci
@@ -45,7 +40,6 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/ctype.h>
-#include <linux/firmware.h>
 #include <linux/jiffies.h>
 #include <linux/slab.h>
 #include <linux/timer.h>
@@ -96,37 +90,6 @@ struct jr3_pci_subdev_private {
 	int retries;
 };
 
-/* Hotplug firmware loading stuff */
-static int comedi_load_firmware(struct comedi_device *dev, const char *name,
-				int (*cb)(struct comedi_device *dev,
-					const u8 *data, size_t size))
-{
-	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-	int result = 0;
-	const struct firmware *fw;
-	char *firmware_path;
-	static const char *prefix = "comedi/";
-
-	firmware_path = kmalloc(strlen(prefix) + strlen(name) + 1, GFP_KERNEL);
-	if (!firmware_path) {
-		result = -ENOMEM;
-	} else {
-		firmware_path[0] = '\0';
-		strcat(firmware_path, prefix);
-		strcat(firmware_path, name);
-		result = reject_firmware(&fw, firmware_path, &pcidev->dev);
-		if (result == 0) {
-			if (!cb)
-				result = -EINVAL;
-			else
-				result = cb(dev, fw->data, fw->size);
-			release_firmware(fw);
-		}
-		kfree(firmware_path);
-	}
-	return result;
-}
-
 static struct poll_delay_t poll_delay_min_max(int min, int max)
 {
 	struct poll_delay_t result;
@@ -361,8 +324,9 @@ static int read_idm_word(const u8 *data,
 	return result;
 }
 
-static int jr3_download_firmware(struct comedi_device *dev, const u8 *data,
-				 size_t size)
+static int jr3_download_firmware(struct comedi_device *dev,
+				 const u8 *data, size_t size,
+				 unsigned long context)
 {
 	/*
 	 * IDM file format is:
@@ -767,7 +731,9 @@ static int jr3_pci_auto_attach(struct co
 	/*  Reset DSP card */
 	writel(0, &devpriv->iobase->channel[0].reset);
 
-	result = comedi_load_firmware(dev, "/*(DEBLOBBED)*/", jr3_download_firmware);
+	result = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
+				      "/*(DEBLOBBED)*/",
+				      jr3_download_firmware, 0);
 	dev_dbg(dev->class_dev, "Firmare load %d\n", result);
 
 	if (result < 0)
@@ -777,8 +743,9 @@ static int jr3_pci_auto_attach(struct co
 	 * format:
 	 *     model serial Fx Fy Fz Mx My Mz\n
 	 *
-	 *     comedi_load_firmware(dev, "jr3_offsets_table",
-	 *                          jr3_download_firmware);
+	 *     comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
+	 *                          "comedi/jr3_offsets_table",
+	 *                          jr3_download_firmware, 1);
 	 */
 
 	/*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ke_counter.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ke_counter.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ke_counter.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ke_counter.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: ke_counter
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/Makefile
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -11,19 +11,16 @@ obj-$(CONFIG_COMEDI_SERIAL2002)		+= seri
 obj-$(CONFIG_COMEDI_SKEL)		+= skel.o
 
 # Comedi ISA drivers
-obj-$(CONFIG_COMEDI_ACL7225B)		+= acl7225b.o
 obj-$(CONFIG_COMEDI_AMPLC_DIO200_ISA)	+= amplc_dio200.o
 obj-$(CONFIG_COMEDI_AMPLC_PC263_ISA)	+= amplc_pc263.o
 obj-$(CONFIG_COMEDI_PCL711)		+= pcl711.o
 obj-$(CONFIG_COMEDI_PCL724)		+= pcl724.o
-obj-$(CONFIG_COMEDI_PCL725)		+= pcl725.o
 obj-$(CONFIG_COMEDI_PCL726)		+= pcl726.o
 obj-$(CONFIG_COMEDI_PCL730)		+= pcl730.o
 obj-$(CONFIG_COMEDI_PCL812)		+= pcl812.o
 obj-$(CONFIG_COMEDI_PCL816)		+= pcl816.o
 obj-$(CONFIG_COMEDI_PCL818)		+= pcl818.o
 obj-$(CONFIG_COMEDI_PCM3724)		+= pcm3724.o
-obj-$(CONFIG_COMEDI_PCM3730)		+= pcm3730.o
 obj-$(CONFIG_COMEDI_RTI800)		+= rti800.o
 obj-$(CONFIG_COMEDI_RTI802)		+= rti802.o
 obj-$(CONFIG_COMEDI_DAS16M1)		+= das16m1.o
@@ -55,6 +52,7 @@ obj-$(CONFIG_COMEDI_PCMMIO)		+= pcmmio.o
 obj-$(CONFIG_COMEDI_PCMUIO)		+= pcmuio.o
 obj-$(CONFIG_COMEDI_MULTIQ3)		+= multiq3.o
 obj-$(CONFIG_COMEDI_POC)		+= poc.o
+obj-$(CONFIG_COMEDI_S526)		+= s526.o
 
 # Comedi PCI drivers
 obj-$(CONFIG_COMEDI_8255_PCI)		+= 8255_pci.o
@@ -110,7 +108,6 @@ obj-$(CONFIG_COMEDI_NI_LABPC_PCI)	+= ni_
 obj-$(CONFIG_COMEDI_NI_PCIDIO)		+= ni_pcidio.o
 obj-$(CONFIG_COMEDI_NI_PCIMIO)		+= ni_pcimio.o
 obj-$(CONFIG_COMEDI_RTD520)		+= rtd520.o
-obj-$(CONFIG_COMEDI_S526)		+= s526.o
 obj-$(CONFIG_COMEDI_S626)		+= s626.o
 obj-$(CONFIG_COMEDI_SSV_DNP)		+= ssv_dnp.o
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/me4000.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/me4000.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/me4000.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/me4000.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: me4000
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/me_daq.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/me_daq.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/me_daq.c	2013-07-01 10:42:07.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/me_daq.c	2013-08-31 18:01:54.000000000 -0400
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -37,7 +33,6 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
-#include <linux/firmware.h>
 
 #include "../comedidev.h"
 
@@ -391,7 +386,8 @@ static int me_ao_insn_read(struct comedi
 }
 
 static int me2600_xilinx_download(struct comedi_device *dev,
-				  const u8 *data, size_t size)
+				  const u8 *data, size_t size,
+				  unsigned long context)
 {
 	struct me_private_data *dev_private = dev->private;
 	unsigned int value;
@@ -460,22 +456,6 @@ static int me2600_xilinx_download(struct
 	return 0;
 }
 
-static int me2600_upload_firmware(struct comedi_device *dev)
-{
-	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-	const struct firmware *fw;
-	int ret;
-
-	ret = reject_firmware(&fw, ME2600_FIRMWARE, &pcidev->dev);
-	if (ret)
-		return ret;
-
-	ret = me2600_xilinx_download(dev, fw->data, fw->size);
-	release_firmware(fw);
-
-	return ret;
-}
-
 static int me_reset(struct comedi_device *dev)
 {
 	struct me_private_data *dev_private = dev->private;
@@ -529,7 +509,9 @@ static int me_auto_attach(struct comedi_
 
 	/* Download firmware and reset card */
 	if (board->needs_firmware) {
-		ret = me2600_upload_firmware(dev);
+		ret = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
+					   ME2600_FIRMWARE,
+					   me2600_xilinx_download, 0);
 		if (ret < 0)
 			return ret;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/mite.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/mite.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/mite.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/mite.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/mite.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/mite.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/mite.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/mite.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _MITE_H_
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/mpc624.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/mpc624.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/mpc624.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/mpc624.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: mpc624
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/multiq3.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/multiq3.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/multiq3.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/multiq3.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: multiq3
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_6527.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_6527.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_6527.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_6527.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: ni_6527
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_65xx.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_65xx.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_65xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_65xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: ni_65xx
@@ -286,15 +281,6 @@ static inline struct ni_65xx_subdevice_p
 	return subdev->private;
 }
 
-static struct ni_65xx_subdevice_private *ni_65xx_alloc_subdevice_private(void)
-{
-	struct ni_65xx_subdevice_private *subdev_private =
-	    kzalloc(sizeof(struct ni_65xx_subdevice_private), GFP_KERNEL);
-	if (subdev_private == NULL)
-		return NULL;
-	return subdev_private;
-}
-
 static int ni_65xx_config_filter(struct comedi_device *dev,
 				 struct comedi_subdevice *s,
 				 struct comedi_insn *insn, unsigned int *data)
@@ -589,6 +575,7 @@ static int ni_65xx_auto_attach(struct co
 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 	const struct ni_65xx_board *board = NULL;
 	struct ni_65xx_private *devpriv;
+	struct ni_65xx_subdevice_private *spriv;
 	struct comedi_subdevice *s;
 	unsigned i;
 	int ret;
@@ -637,10 +624,10 @@ static int ni_65xx_auto_attach(struct co
 		s->maxdata = 1;
 		s->insn_config = ni_65xx_dio_insn_config;
 		s->insn_bits = ni_65xx_dio_insn_bits;
-		s->private = ni_65xx_alloc_subdevice_private();
-		if (s->private == NULL)
+		spriv = comedi_alloc_spriv(s, sizeof(*spriv));
+		if (!spriv)
 			return -ENOMEM;
-		sprivate(s)->base_port = 0;
+		spriv->base_port = 0;
 	} else {
 		s->type = COMEDI_SUBD_UNUSED;
 	}
@@ -654,10 +641,10 @@ static int ni_65xx_auto_attach(struct co
 		s->range_table = &range_digital;
 		s->maxdata = 1;
 		s->insn_bits = ni_65xx_dio_insn_bits;
-		s->private = ni_65xx_alloc_subdevice_private();
-		if (s->private == NULL)
+		spriv = comedi_alloc_spriv(s, sizeof(*spriv));
+		if (!spriv)
 			return -ENOMEM;
-		sprivate(s)->base_port = board->num_di_ports;
+		spriv->base_port = board->num_di_ports;
 	} else {
 		s->type = COMEDI_SUBD_UNUSED;
 	}
@@ -672,10 +659,10 @@ static int ni_65xx_auto_attach(struct co
 		s->maxdata = 1;
 		s->insn_config = ni_65xx_dio_insn_config;
 		s->insn_bits = ni_65xx_dio_insn_bits;
-		s->private = ni_65xx_alloc_subdevice_private();
-		if (s->private == NULL)
+		spriv = comedi_alloc_spriv(s, sizeof(*spriv));
+		if (!spriv)
 			return -ENOMEM;
-		sprivate(s)->base_port = 0;
+		spriv->base_port = 0;
 		for (i = 0; i < board->num_dio_ports; ++i) {
 			/*  configure all ports for input */
 			writeb(0x1,
@@ -730,7 +717,6 @@ static int ni_65xx_auto_attach(struct co
 static void ni_65xx_detach(struct comedi_device *dev)
 {
 	struct ni_65xx_private *devpriv = dev->private;
-	int i;
 
 	if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
 		writeb(0x00,
@@ -739,8 +725,6 @@ static void ni_65xx_detach(struct comedi
 	}
 	if (dev->irq)
 		free_irq(dev->irq, dev);
-	for (i = 0; i < dev->n_subdevices; ++i)
-		comedi_spriv_free(dev, i);
 	if (devpriv) {
 		if (devpriv->mite) {
 			mite_unsetup(devpriv->mite);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_660x.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_660x.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_660x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_660x.c	2013-08-25 20:43:22.000000000 -0400
@@ -11,10 +11,6 @@
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_670x.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_670x.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_670x.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_670x.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: ni_670x
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_at_a2150.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_at_a2150.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_at_a2150.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_at_a2150.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,12 +15,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************
 */
 /*
 Driver: ni_at_a2150
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_at_ao.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_at_ao.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_at_ao.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_at_ao.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: ni_at_ao
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_atmio16d.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_atmio16d.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_atmio16d.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_atmio16d.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,11 +12,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: ni_atmio16d
@@ -767,7 +762,6 @@ static int atmio16d_attach(struct comedi
 
 static void atmio16d_detach(struct comedi_device *dev)
 {
-	comedi_spriv_free(dev, 3);
 	reset_atmio16d(dev);
 	comedi_legacy_detach(dev);
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_atmio.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_atmio.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_atmio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_atmio.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 /*
 Driver: ni_atmio
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_daq_700.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_daq_700.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_daq_700.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_daq_700.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,11 +15,6 @@
  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 /*
@@ -40,7 +35,7 @@ port, bit 0; channel 8 corresponds to th
 Digital direction configuration: channels 0-7 output, 8-15 input (8225 device
 emu as port A output, port B input, port C N/A).
 
-Analog: The input  range is 0 to 4095 for -10 to +10 volts 
+Analog: The input  range is 0 to 4095 for -10 to +10 volts
 IRQ is assigned but not used.
 
 Version 0.1	Original DIO only driver
@@ -183,7 +178,7 @@ static int daq700_ai_rinsn(struct comedi
  */
 static void daq700_ai_config(struct comedi_device *dev,
 			     struct comedi_subdevice *s)
-{			
+{
 	unsigned long iobase = dev->iobase;
 
 	outb(0x80, iobase + CMD_R1);	/* disable scanning, ADC to chan 0 */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_daq_dio24.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_daq_dio24.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_daq_dio24.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_daq_dio24.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,12 +18,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************
 */
 /*
 Driver: ni_daq_dio24
@@ -71,17 +65,11 @@ static int dio24_auto_attach(struct come
 	return 0;
 }
 
-static void dio24_detach(struct comedi_device *dev)
-{
-	comedi_spriv_free(dev, 0);
-	comedi_pcmcia_disable(dev);
-}
-
 static struct comedi_driver driver_dio24 = {
 	.driver_name	= "ni_daq_dio24",
 	.module		= THIS_MODULE,
 	.auto_attach	= dio24_auto_attach,
-	.detach		= dio24_detach,
+	.detach		= comedi_pcmcia_disable,
 };
 
 static int dio24_cs_attach(struct pcmcia_device *link)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_labpc.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_labpc.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_labpc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_labpc.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,10 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -88,7 +84,7 @@
 #define CMD1_REG		0x00	/* W: Command 1 reg */
 #define CMD1_MA(x)		(((x) & 0x7) << 0)
 #define CMD1_TWOSCMP		(1 << 3)
-#define CMD1_GAIN_MASK		(7 << 4)
+#define CMD1_GAIN(x)		(((x) & 0x7) << 4)
 #define CMD1_SCANEN		(1 << 7)
 #define CMD2_REG		0x01	/* W: Command 2 reg */
 #define CMD2_PRETRIG		(1 << 0)
@@ -153,11 +149,6 @@ enum scan_mode {
 	MODE_MULT_CHAN_DOWN,
 };
 
-static const int labpc_plus_ai_gain_bits[] = {
-	0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
-	0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
-};
-
 static const struct comedi_lrange range_labpc_plus_ai = {
 	16, {
 		BIP_RANGE(5),
@@ -179,13 +170,7 @@ static const struct comedi_lrange range_
 	}
 };
 
-const int labpc_1200_ai_gain_bits[] = {
-	0x00, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
-	0x00, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
-};
-EXPORT_SYMBOL_GPL(labpc_1200_ai_gain_bits);
-
-const struct comedi_lrange range_labpc_1200_ai = {
+static const struct comedi_lrange range_labpc_1200_ai = {
 	14, {
 		BIP_RANGE(5),
 		BIP_RANGE(2.5),
@@ -203,7 +188,6 @@ const struct comedi_lrange range_labpc_1
 		UNI_RANGE(0.1)
 	}
 };
-EXPORT_SYMBOL_GPL(range_labpc_1200_ai);
 
 static const struct comedi_lrange range_labpc_ao = {
 	2, {
@@ -239,25 +223,18 @@ static const struct labpc_boardinfo labp
 	{
 		.name			= "lab-pc-1200",
 		.ai_speed		= 10000,
-		.register_layout	= labpc_1200_layout,
-		.has_ao			= 1,
-		.ai_range_table		= &range_labpc_1200_ai,
-		.ai_range_code		= labpc_1200_ai_gain_bits,
 		.ai_scan_up		= 1,
+		.has_ao			= 1,
+		.is_labpc1200		= 1,
 	}, {
 		.name			= "lab-pc-1200ai",
 		.ai_speed		= 10000,
-		.register_layout	= labpc_1200_layout,
-		.ai_range_table		= &range_labpc_1200_ai,
-		.ai_range_code		= labpc_1200_ai_gain_bits,
 		.ai_scan_up		= 1,
+		.is_labpc1200		= 1,
 	}, {
 		.name			= "lab-pc+",
 		.ai_speed		= 12000,
-		.register_layout	= labpc_plus_layout,
 		.has_ao			= 1,
-		.ai_range_table		= &range_labpc_plus_ai,
-		.ai_range_code		= labpc_plus_ai_gain_bits,
 	},
 };
 #endif
@@ -326,12 +303,21 @@ static void labpc_ai_set_chan_and_gain(s
 	const struct labpc_boardinfo *board = comedi_board(dev);
 	struct labpc_private *devpriv = dev->private;
 
+	if (board->is_labpc1200) {
+		/*
+		 * The LabPC-1200 boards do not have a gain
+		 * of '0x10'. Skip the range values that would
+		 * result in this gain.
+		 */
+		range += (range > 0) + (range > 7);
+	}
+
 	/* munge channel bits for differential/scan disabled mode */
 	if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) &&
 	    aref == AREF_DIFF)
 		chan *= 2;
 	devpriv->cmd1 = CMD1_MA(chan);
-	devpriv->cmd1 |= board->ai_range_code[range];
+	devpriv->cmd1 |= CMD1_GAIN(range);
 
 	devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
 }
@@ -347,7 +333,7 @@ static void labpc_setup_cmd6_reg(struct
 	const struct labpc_boardinfo *board = comedi_board(dev);
 	struct labpc_private *devpriv = dev->private;
 
-	if (board->register_layout != labpc_1200_layout)
+	if (!board->is_labpc1200)
 		return;
 
 	/* reference inputs to ground or common? */
@@ -759,7 +745,7 @@ static int labpc_ai_cmdtest(struct comed
 	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 
 	stop_mask = TRIG_COUNT | TRIG_NONE;
-	if (board->register_layout == labpc_1200_layout)
+	if (board->is_labpc1200)
 		stop_mask |= TRIG_EXT;
 	err |= cfc_check_trigger_src(&cmd->stop_src, stop_mask);
 
@@ -895,7 +881,7 @@ static int labpc_ai_cmd(struct comedi_de
 		/* pc-plus has no fifo-half full interrupt */
 	} else
 #endif
-	if (board->register_layout == labpc_1200_layout &&
+	if (board->is_labpc1200 &&
 		   /*  wake-end-of-scan should interrupt on fifo not empty */
 		   (cmd->flags & TRIG_WAKE_EOS) == 0 &&
 		   /*  make sure we are taking more than just a few points */
@@ -1175,7 +1161,7 @@ static irqreturn_t labpc_interrupt(int i
 
 	/* read board status */
 	devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
-	if (board->register_layout == labpc_1200_layout)
+	if (board->is_labpc1200)
 		devpriv->stat2 = devpriv->read_byte(dev->iobase + STAT2_REG);
 
 	if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
@@ -1201,8 +1187,7 @@ static irqreturn_t labpc_interrupt(int i
 		 * has occurred
 		 */
 		if (devpriv->stat1 & STAT1_GATA0 ||
-		    (board->register_layout == labpc_1200_layout
-		     && devpriv->stat2 & STAT2_OUTA1)) {
+		    (board->is_labpc1200 && devpriv->stat2 & STAT2_OUTA1)) {
 			handle_isa_dma(dev);
 		}
 	} else
@@ -1266,7 +1251,7 @@ static int labpc_ao_insn_write(struct co
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
 	/* set range */
-	if (board->register_layout == labpc_1200_layout) {
+	if (board->is_labpc1200) {
 		range = CR_RANGE(insn->chanspec);
 		if (labpc_range_is_unipolar(s, range))
 			devpriv->cmd6 |= CMD6_DACUNI(channel);
@@ -1603,7 +1588,7 @@ int labpc_common_attach(struct comedi_de
 	devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
 	devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
 	devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
-	if (board->register_layout == labpc_1200_layout) {
+	if (board->is_labpc1200) {
 		devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
 		devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
 	}
@@ -1626,7 +1611,8 @@ int labpc_common_attach(struct comedi_de
 	s->n_chan	= 8;
 	s->len_chanlist	= 8;
 	s->maxdata	= 0x0fff;
-	s->range_table	= board->ai_range_table;
+	s->range_table	= board->is_labpc1200
+				? &range_labpc_1200_ai : &range_labpc_plus_ai;
 	s->insn_read	= labpc_ai_insn_read;
 	if (dev->irq) {
 		dev->read_subdev = s;
@@ -1671,7 +1657,7 @@ int labpc_common_attach(struct comedi_de
 
 	/*  calibration subdevices for boards that have one */
 	s = &dev->subdevices[3];
-	if (board->register_layout == labpc_1200_layout) {
+	if (board->is_labpc1200) {
 		s->type		= COMEDI_SUBD_CALIB;
 		s->subdev_flags	= SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
 		s->n_chan	= 16;
@@ -1686,7 +1672,7 @@ int labpc_common_attach(struct comedi_de
 
 	/* EEPROM */
 	s = &dev->subdevices[4];
-	if (board->register_layout == labpc_1200_layout) {
+	if (board->is_labpc1200) {
 		s->type		= COMEDI_SUBD_MEMORY;
 		s->subdev_flags	= SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
 		s->n_chan	= EEPROM_SIZE;
@@ -1703,12 +1689,6 @@ int labpc_common_attach(struct comedi_de
 }
 EXPORT_SYMBOL_GPL(labpc_common_attach);
 
-void labpc_common_detach(struct comedi_device *dev)
-{
-	comedi_spriv_free(dev, 2);
-}
-EXPORT_SYMBOL_GPL(labpc_common_detach);
-
 #if IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISA)
 static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
@@ -1761,8 +1741,6 @@ static void labpc_detach(struct comedi_d
 {
 	struct labpc_private *devpriv = dev->private;
 
-	labpc_common_detach(dev);
-
 	if (devpriv) {
 		kfree(devpriv->dma_buffer);
 		if (devpriv->dma_chan)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_labpc_cs.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_labpc_cs.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_labpc_cs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_labpc_cs.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,12 +18,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-************************************************************************
 */
 /*
 Driver: ni_labpc_cs
@@ -76,12 +70,9 @@ NI manuals:
 static const struct labpc_boardinfo labpc_cs_boards[] = {
 	{
 		.name			= "daqcard-1200",
-		.device_id		= 0x103,
 		.ai_speed		= 10000,
-		.register_layout	= labpc_1200_layout,
 		.has_ao			= 1,
-		.ai_range_table		= &range_labpc_1200_ai,
-		.ai_range_code		= labpc_1200_ai_gain_bits,
+		.is_labpc1200		= 1,
 	},
 };
 
@@ -113,17 +104,11 @@ static int labpc_auto_attach(struct come
 	return labpc_common_attach(dev, link->irq, IRQF_SHARED);
 }
 
-static void labpc_detach(struct comedi_device *dev)
-{
-	labpc_common_detach(dev);
-	comedi_pcmcia_disable(dev);
-}
-
 static struct comedi_driver driver_labpc_cs = {
 	.driver_name	= "ni_labpc_cs",
 	.module		= THIS_MODULE,
 	.auto_attach	= labpc_auto_attach,
-	.detach		= labpc_detach,
+	.detach		= comedi_pcmcia_disable,
 };
 
 static int labpc_cs_attach(struct pcmcia_device *link)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_labpc.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_labpc.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_labpc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_labpc.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _NI_LABPC_H
@@ -27,27 +22,17 @@
 #define EEPROM_SIZE	256	/*  256 byte eeprom */
 #define NUM_AO_CHAN	2	/*  boards have two analog output channels */
 
-enum labpc_register_layout { labpc_plus_layout, labpc_1200_layout };
 enum transfer_type { fifo_not_empty_transfer, fifo_half_full_transfer,
 	isa_dma_transfer
 };
 
 struct labpc_boardinfo {
 	const char *name;
-	int device_id;		/*  device id for pci and pcmcia boards */
-	int ai_speed;		/*  maximum input speed in nanoseconds */
-
-	/*  1200 has extra registers compared to pc+ */
-	enum labpc_register_layout register_layout;
-	int has_ao;		/*  has analog output true/false */
-	const struct comedi_lrange *ai_range_table;
-	const int *ai_range_code;
-
-	/*  board can auto scan up in ai channels, not just down */
-	unsigned ai_scan_up:1;
-
-	/* uses memory mapped io instead of ioports */
-	unsigned has_mmio:1;
+	int ai_speed;			/* maximum input speed in ns */
+	unsigned ai_scan_up:1;		/* can auto scan up in ai channels */
+	unsigned has_ao:1;		/* has analog outputs */
+	unsigned is_labpc1200:1;	/* has extra regs compared to pc+ */
+	unsigned has_mmio:1;		/* uses memory mapped io */
 };
 
 struct labpc_private {
@@ -101,9 +86,5 @@ struct labpc_private {
 
 int labpc_common_attach(struct comedi_device *dev,
 			unsigned int irq, unsigned long isr_flags);
-void labpc_common_detach(struct comedi_device *dev);
-
-extern const int labpc_1200_ai_gain_bits[];
-extern const struct comedi_lrange range_labpc_1200_ai;
 
 #endif /* _NI_LABPC_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_labpc_pci.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_labpc_pci.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_labpc_pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_labpc_pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -12,10 +12,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -50,11 +46,9 @@ static const struct labpc_boardinfo labp
 	[BOARD_NI_PCI1200] = {
 		.name			= "ni_pci-1200",
 		.ai_speed		= 10000,
-		.register_layout	= labpc_1200_layout,
-		.has_ao			= 1,
-		.ai_range_table		= &range_labpc_1200_ai,
-		.ai_range_code		= labpc_1200_ai_gain_bits,
 		.ai_scan_up		= 1,
+		.has_ao			= 1,
+		.is_labpc1200		= 1,
 		.has_mmio		= 1,
 	},
 };
@@ -98,8 +92,6 @@ static void labpc_pci_detach(struct come
 {
 	struct labpc_private *devpriv = dev->private;
 
-	labpc_common_detach(dev);
-
 	if (devpriv && devpriv->mite) {
 		mite_unsetup(devpriv->mite);
 		mite_free(devpriv->mite);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_mio_common.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_mio_common.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_mio_common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_mio_common.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,11 +15,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 /*
@@ -4077,7 +4072,6 @@ static void mio_common_detach(struct com
 			ni_gpct_device_destroy(devpriv->counter_dev);
 		}
 	}
-	comedi_spriv_free(dev, NI_8255_DIO_SUBDEV);
 }
 
 static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_mio_cs.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_mio_cs.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_mio_cs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_mio_cs.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: ni_mio_cs
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_pcidio.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_pcidio.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_pcidio.c	2013-07-01 10:42:09.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_pcidio.c	2013-08-31 18:01:57.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: ni_pcidio
@@ -58,7 +53,6 @@ comedi_nonfree_firmware tarball availabl
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
-#include <linux/firmware.h>
 
 #include "../comedidev.h"
 
@@ -969,11 +963,13 @@ static int ni_pcidio_change(struct comed
 	return 0;
 }
 
-static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
-			      const u8 *data, size_t data_len)
+static int pci_6534_load_fpga(struct comedi_device *dev,
+			      const u8 *data, size_t data_len,
+			      unsigned long context)
 {
 	struct nidio96_private *devpriv = dev->private;
 	static const int timeout = 1000;
+	int fpga_index = context;
 	int i;
 	size_t j;
 
@@ -1031,7 +1027,7 @@ static int pci_6534_load_fpga(struct com
 
 static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
 {
-	return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
+	return pci_6534_load_fpga(dev, NULL, 0, fpga_index);
 }
 
 static int pci_6534_reset_fpgas(struct comedi_device *dev)
@@ -1065,13 +1061,12 @@ static void pci_6534_init_main_fpga(stru
 static int pci_6534_upload_firmware(struct comedi_device *dev)
 {
 	struct nidio96_private *devpriv = dev->private;
-	int ret;
-	const struct firmware *fw;
 	static const char *const fw_file[3] = {
 		FW_PCI_6534_SCARAB_DI,	/* loaded into scarab A for DI */
 		FW_PCI_6534_SCARAB_DO,	/* loaded into scarab B for DO */
 		FW_PCI_6534_MAIN,	/* loaded into main FPGA */
 	};
+	int ret;
 	int n;
 
 	ret = pci_6534_reset_fpgas(dev);
@@ -1079,14 +1074,11 @@ static int pci_6534_upload_firmware(stru
 		return ret;
 	/* load main FPGA first, then the two scarabs */
 	for (n = 2; n >= 0; n--) {
-		ret = reject_firmware(&fw, fw_file[n],
-				       &devpriv->mite->pcidev->dev);
-		if (ret == 0) {
-			ret = pci_6534_load_fpga(dev, n, fw->data, fw->size);
-			if (ret == 0 && n == 2)
-				pci_6534_init_main_fpga(dev);
-			release_firmware(fw);
-		}
+		ret = comedi_load_firmware(dev, &devpriv->mite->pcidev->dev,
+					   fw_file[n],
+					   pci_6534_load_fpga, n);
+		if (ret == 0 && n == 2)
+			pci_6534_init_main_fpga(dev);
 		if (ret < 0)
 			break;
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_pcimio.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_pcimio.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_pcimio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_pcimio.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 /*
 Driver: ni_pcimio
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_stc.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_stc.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_stc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_stc.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_tio.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_tio.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_tio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_tio.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,10 +13,6 @@
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_tiocmd.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_tiocmd.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_tiocmd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_tiocmd.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,10 +13,6 @@
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_tio.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_tio.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_tio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_tio.h	2013-08-25 20:43:22.000000000 -0400
@@ -13,11 +13,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _COMEDI_NI_TIO_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_tio_internal.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_tio_internal.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ni_tio_internal.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ni_tio_internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _COMEDI_NI_TIO_INTERNAL_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl711.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl711.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl711.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl711.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: pcl711
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl724.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl724.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl724.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl724.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,42 +1,28 @@
 /*
-    comedi/drivers/pcl724.c
-
-    Michal Dobes <dobes@tesnet.cz>
-
-    hardware driver for Advantech cards:
-     card:   PCL-724, PCL-722, PCL-731
-     driver: pcl724,  pcl722,  pcl731
-    and ADLink cards:
-     card:   ACL-7122, ACL-7124, PET-48DIO
-     driver: acl7122,  acl7124,  pet48dio
-
-    Options for PCL-724, PCL-731, ACL-7124 and PET-48DIO:
-     [0] - IO Base
-
-    Options for PCL-722 and ACL-7122:
-     [0] - IO Base
-     [1] - IRQ (0=disable IRQ) IRQ isn't supported at this time!
-     [2] -number of DIO:
-	      0, 144: 144 DIO configuration
-	      1,  96:  96 DIO configuration
-*/
-/*
-Driver: pcl724
-Description: Advantech PCL-724, PCL-722, PCL-731 ADLink ACL-7122, ACL-7124,
-  PET-48DIO
-Author: Michal Dobes <dobes@tesnet.cz>
-Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
-  [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio)
-Status: untested
+ * pcl724.c
+ * Comedi driver for 8255 based ISA DIO boards
+ *
+ * Michal Dobes <dobes@tesnet.cz>
+ */
 
-This is driver for digital I/O boards PCL-722/724/731 with 144/24/48 DIO
-and for digital I/O boards ACL-7122/7124/PET-48DIO with 144/24/48 DIO.
-It need 8255.o for operations and only immediate mode is supported.
-See the source for configuration details.
-*/
 /*
- * check_driver overrides:
- *   struct comedi_insn
+ * Driver: pcl724
+ * Description: Comedi driver for 8255 based ISA DIO boards
+ * Devices: (Advantech) PCL-724 [pcl724]
+ *	    (Advantech) PCL-722 [pcl722]
+ *	    (Advantech) PCL-731 [pcl731]
+ *	    (ADLink) ACL-7122 [acl7122]
+ *	    (ADLink) ACL-7124 [acl7124]
+ *	    (ADLink) PET-48DIO [pet48dio]
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ * Status: untested
+ *
+ * Configuration options:
+ *   [0] - IO Base
+ *   [1] - IRQ (not supported)
+ *   [2] - number of DIO (pcl722 and acl7122 boards)
+ *	   0, 144: 144 DIO configuration
+ *	   1,  96:  96 DIO configuration
  */
 
 #include "../comedidev.h"
@@ -46,40 +32,48 @@ See the source for configuration details
 
 #include "8255.h"
 
-#define PCL722_SIZE    32
-#define PCL722_96_SIZE 16
-#define PCL724_SIZE     4
-#define PCL731_SIZE     8
-#define PET48_SIZE      2
-
 #define SIZE_8255	4
 
-/* #define PCL724_IRQ   1  no IRQ support now */
-
 struct pcl724_board {
-
-	const char *name;	/*  board name */
-	int dio;		/*  num of DIO */
-	int numofports;		/*  num of 8255 subdevices */
-	unsigned int IRQbits;	/*  allowed interrupts */
-	unsigned int io_range;	/*  len of IO space */
-	char can_have96;
-	char is_pet48;
+	const char *name;
+	unsigned int io_range;
+	unsigned int can_have96:1;
+	unsigned int is_pet48:1;
+	int numofports;
 };
 
-static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
-{
-	unsigned long iobase = arg;
-
-	if (dir) {
-		outb(data, iobase + port);
-		return 0;
-	} else {
-		return inb(iobase + port);
-	}
-}
+static const struct pcl724_board boardtypes[] = {
+	{
+		.name		= "pcl724",
+		.io_range	= 0x04,
+		.numofports	= 1,	/* 24 DIO channels */
+	}, {
+		.name		= "pcl722",
+		.io_range	= 0x20,
+		.can_have96	= 1,
+		.numofports	= 6,	/* 144 (or 96) DIO channels */
+	}, {
+		.name		= "pcl731",
+		.io_range	= 0x08,
+		.numofports	= 2,	/* 48 DIO channels */
+	}, {
+		.name		= "acl7122",
+		.io_range	= 0x20,
+		.can_have96	= 1,
+		.numofports	= 6,	/* 144 (or 96) DIO channels */
+	}, {
+		.name		= "acl7124",
+		.io_range	= 0x04,
+		.numofports	= 1,	/* 24 DIO channels */
+	}, {
+		.name		= "pet48dio",
+		.io_range	= 0x02,
+		.is_pet48	= 1,
+		.numofports	= 2,	/* 48 DIO channels */
+	},
+};
 
-static int subdev_8255mapped_cb(int dir, int port, int data,
+static int pcl724_8255mapped_io(int dir, int port, int data,
 				unsigned long iobase)
 {
 	int movport = SIZE_8255 * (iobase >> 12);
@@ -96,57 +90,30 @@ static int subdev_8255mapped_cb(int dir,
 	}
 }
 
-static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pcl724_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it)
 {
 	const struct pcl724_board *board = comedi_board(dev);
 	struct comedi_subdevice *s;
+	unsigned long iobase;
 	unsigned int iorange;
-	int ret, i, n_subdevices;
-#ifdef PCL724_IRQ
-	unsigned int irq;
-#endif
+	int n_subdevices;
+	int ret;
+	int i;
 
 	iorange = board->io_range;
-	if ((board->can_have96) &&
-	    ((it->options[1] == 1) || (it->options[1] == 96)))
-		iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */
-	ret = comedi_request_region(dev, it->options[0], iorange);
-	if (ret)
-		return ret;
+	n_subdevices = board->numofports;
 
-#ifdef PCL724_IRQ
-	irq = 0;
-	if (board->IRQbits != 0) {	/* board support IRQ */
-		irq = it->options[1];
-		if (irq) {	/* we want to use IRQ */
-			if (((1 << irq) & board->IRQbits) == 0) {
-				printk(KERN_WARNING
-				       ", IRQ %u is out of allowed range, "
-				       "DISABLING IT", irq);
-				irq = 0;	/* Bad IRQ */
-			} else {
-				if (request_irq(irq, interrupt_pcl724, 0,
-					        dev->board_name, dev)) {
-					printk(KERN_WARNING
-					       ", unable to allocate IRQ %u, "
-					       "DISABLING IT", irq);
-					irq = 0;	/* Can't use IRQ */
-				} else {
-					printk(", irq=%u", irq);
-				}
-			}
-		}
+	/* Handle PCL-724 in 96 DIO configuration */
+	if (board->can_have96 &&
+	    (it->options[2] == 1 || it->options[2] == 96)) {
+		iorange = 0x10;
+		n_subdevices = 4;
 	}
 
-	dev->irq = irq;
-#endif
-
-	printk("\n");
-
-	n_subdevices = board->numofports;
-	if ((board->can_have96) && ((it->options[1] == 1)
-					 || (it->options[1] == 96)))
-		n_subdevices = 4;	/*  PCL-724 in 96 DIO configuration */
+	ret = comedi_request_region(dev, it->options[0], iorange);
+	if (ret)
+		return ret;
 
 	ret = comedi_alloc_subdevices(dev, n_subdevices);
 	if (ret)
@@ -155,41 +122,25 @@ static int pcl724_attach(struct comedi_d
 	for (i = 0; i < dev->n_subdevices; i++) {
 		s = &dev->subdevices[i];
 		if (board->is_pet48) {
-			subdev_8255_init(dev, s, subdev_8255mapped_cb,
-					 (unsigned long)(dev->iobase +
-							 i * 0x1000));
-		} else
-			subdev_8255_init(dev, s, subdev_8255_cb,
-					 (unsigned long)(dev->iobase +
-							 SIZE_8255 * i));
+			iobase = dev->iobase + (i * 0x1000);
+			ret = subdev_8255_init(dev, s, pcl724_8255mapped_io,
+					       iobase);
+		} else {
+			iobase = dev->iobase + (i * SIZE_8255);
+			ret = subdev_8255_init(dev, s, NULL, iobase);
+		}
+		if (ret)
+			return ret;
 	}
 
 	return 0;
 }
 
-static void pcl724_detach(struct comedi_device *dev)
-{
-	int i;
-
-	for (i = 0; i < dev->n_subdevices; i++)
-		comedi_spriv_free(dev, i);
-	comedi_legacy_detach(dev);
-}
-
-static const struct pcl724_board boardtypes[] = {
-	{ "pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, },
-	{ "pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0, },
-	{ "pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0, },
-	{ "acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0, },
-	{ "acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, },
-	{ "pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1, },
-};
-
 static struct comedi_driver pcl724_driver = {
 	.driver_name	= "pcl724",
 	.module		= THIS_MODULE,
 	.attach		= pcl724_attach,
-	.detach		= pcl724_detach,
+	.detach		= comedi_legacy_detach,
 	.board_name	= &boardtypes[0].name,
 	.num_names	= ARRAY_SIZE(boardtypes),
 	.offset		= sizeof(struct pcl724_board),
@@ -197,5 +148,5 @@ static struct comedi_driver pcl724_drive
 module_comedi_driver(pcl724_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for 8255 based ISA DIO boards");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl725.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl725.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl725.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl725.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,91 +0,0 @@
-/*
- * comedi/drivers/pcl725.c
- * Driver for PCL725 and clones
- * David A. Schleef
- */
-/*
-Driver: pcl725
-Description: Advantech PCL-725 (& compatibles)
-Author: ds
-Status: unknown
-Devices: [Advantech] PCL-725 (pcl725)
-*/
-
-#include "../comedidev.h"
-
-#include <linux/ioport.h>
-
-#define PCL725_SIZE 2
-
-#define PCL725_DO 0
-#define PCL725_DI 1
-
-static int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-			  struct comedi_insn *insn, unsigned int *data)
-{
-	if (data[0]) {
-		s->state &= ~data[0];
-		s->state |= (data[0] & data[1]);
-		outb(s->state, dev->iobase + PCL725_DO);
-	}
-
-	data[1] = s->state;
-
-	return insn->n;
-}
-
-static int pcl725_di_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-			  struct comedi_insn *insn, unsigned int *data)
-{
-	data[1] = inb(dev->iobase + PCL725_DI);
-
-	return insn->n;
-}
-
-static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
-	struct comedi_subdevice *s;
-	int ret;
-
-	ret = comedi_request_region(dev, it->options[0], PCL725_SIZE);
-	if (ret)
-		return ret;
-
-	ret = comedi_alloc_subdevices(dev, 2);
-	if (ret)
-		return ret;
-
-	s = &dev->subdevices[0];
-	/* do */
-	s->type = COMEDI_SUBD_DO;
-	s->subdev_flags = SDF_WRITABLE;
-	s->maxdata = 1;
-	s->n_chan = 8;
-	s->insn_bits = pcl725_do_insn;
-	s->range_table = &range_digital;
-
-	s = &dev->subdevices[1];
-	/* di */
-	s->type = COMEDI_SUBD_DI;
-	s->subdev_flags = SDF_READABLE;
-	s->maxdata = 1;
-	s->n_chan = 8;
-	s->insn_bits = pcl725_di_insn;
-	s->range_table = &range_digital;
-
-	printk(KERN_INFO "\n");
-
-	return 0;
-}
-
-static struct comedi_driver pcl725_driver = {
-	.driver_name	= "pcl725",
-	.module		= THIS_MODULE,
-	.attach		= pcl725_attach,
-	.detach		= comedi_legacy_detach,
-};
-module_comedi_driver(pcl725_driver);
-
-MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl726.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl726.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl726.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl726.c	2013-08-25 20:43:22.000000000 -0400
@@ -20,11 +20,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: pcl726
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl730.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl730.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcl730.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcl730.c	2013-08-25 20:43:22.000000000 -0400
@@ -3,135 +3,299 @@
  * Driver for Advantech PCL-730 and clones
  * José Luis Sánchez
  */
-/*
-Driver: pcl730
-Description: Advantech PCL-730 (& compatibles)
-Author: José Luis Sánchez (jsanchezv@teleline.es)
-Status: untested
-Devices: [Advantech] PCL-730 (pcl730), [ICP] ISO-730 (iso730),
-		 [Adlink] ACL-7130 (acl7130)
 
-Interrupts are not supported.
-The ACL-7130 card have an 8254 timer/counter not supported by this driver.
-*/
+/*
+ * Driver: pcl730
+ * Description: Advantech PCL-730 (& compatibles)
+ * Devices: (Advantech) PCL-730 [pcl730]
+ *	    (ICP) ISO-730 [iso730]
+ *	    (Adlink) ACL-7130 [acl7130]
+ *	    (Advantech) PCM-3730 [pcm3730]
+ *	    (Advantech) PCL-725 [pcl725]
+ *	    (ICP) P8R8-DIO [p16r16dio]
+ *	    (Adlink) ACL-7225b [acl7225b]
+ *	    (ICP) P16R16-DIO [p16r16dio]
+ *	    (Advantech) PCL-733 [pcl733]
+ *	    (Advantech) PCL-734 [pcl734]
+ * Author: José Luis Sánchez (jsanchezv@teleline.es)
+ * Status: untested
+ *
+ * Configuration options:
+ *   [0] - I/O port base
+ *
+ * Interrupts are not supported.
+ * The ACL-7130 card has an 8254 timer/counter not supported by this driver.
+ */
 
 #include "../comedidev.h"
 
 #include <linux/ioport.h>
 
-#define PCL730_SIZE		4
-#define ACL7130_SIZE	8
-#define PCL730_IDIO_LO	0	/* Isolated Digital I/O low byte (ID0-ID7) */
-#define PCL730_IDIO_HI	1	/* Isolated Digital I/O high byte (ID8-ID15) */
-#define PCL730_DIO_LO	2	/* TTL Digital I/O low byte (D0-D7) */
-#define PCL730_DIO_HI	3	/* TTL Digital I/O high byte (D8-D15) */
+/*
+ * Register map
+ *
+ * The register map varies slightly depending on the board type but
+ * all registers are 8-bit.
+ *
+ * The boardinfo 'io_range' is used to allow comedi to request the
+ * proper range required by the board.
+ *
+ * The comedi_subdevice 'private' data is used to pass the register
+ * offset to the (*insn_bits) functions to read/write the correct
+ * registers.
+ *
+ * The basic register mapping looks like this:
+ *
+ *     BASE+0  Isolated outputs 0-7 (write) / inputs 0-7 (read)
+ *     BASE+1  Isolated outputs 8-15 (write) / inputs 8-15 (read)
+ *     BASE+2  TTL outputs 0-7 (write) / inputs 0-7 (read)
+ *     BASE+3  TTL outputs 8-15 (write) / inputs 8-15 (read)
+ *
+ * The pcm3730 board does not have register BASE+1.
+ *
+ * The pcl725 and p8r8dio only have registers BASE+0 and BASE+1:
+ *
+ *     BASE+0  Isolated outputs 0-7 (write) (read back on p8r8dio)
+ *     BASE+1  Isolated inputs 0-7 (read)
+ *
+ * The acl7225b and p16r16dio boards have this register mapping:
+ *
+ *     BASE+0  Isolated outputs 0-7 (write) (read back)
+ *     BASE+1  Isolated outputs 8-15 (write) (read back)
+ *     BASE+2  Isolated inputs 0-7 (read)
+ *     BASE+3  Isolated inputs 8-15 (read)
+ *
+ * The pcl733 and pcl733 boards have this register mapping:
+ *
+ *     BASE+0  Isolated outputs 0-7 (write) or inputs 0-7 (read)
+ *     BASE+1  Isolated outputs 8-15 (write) or inputs 8-15 (read)
+ *     BASE+2  Isolated outputs 16-23 (write) or inputs 16-23 (read)
+ *     BASE+3  Isolated outputs 24-31 (write) or inputs 24-31 (read)
+ */
 
 struct pcl730_board {
+	const char *name;
+	unsigned int io_range;
+	unsigned is_pcl725:1;
+	unsigned is_acl7225b:1;
+	unsigned has_readback:1;
+	unsigned has_ttl_io:1;
+	int n_subdevs;
+	int n_iso_out_chan;
+	int n_iso_in_chan;
+	int n_ttl_chan;
+};
 
-	const char *name;	/*  board name */
-	unsigned int io_range;	/*  len of I/O space */
+static const struct pcl730_board pcl730_boards[] = {
+	{
+		.name		= "pcl730",
+		.io_range	= 0x04,
+		.has_ttl_io	= 1,
+		.n_subdevs	= 4,
+		.n_iso_out_chan	= 16,
+		.n_iso_in_chan	= 16,
+		.n_ttl_chan	= 16,
+	}, {
+		.name		= "iso730",
+		.io_range	= 0x04,
+		.n_subdevs	= 4,
+		.n_iso_out_chan	= 16,
+		.n_iso_in_chan	= 16,
+		.n_ttl_chan	= 16,
+	}, {
+		.name		= "acl7130",
+		.io_range	= 0x08,
+		.has_ttl_io	= 1,
+		.n_subdevs	= 4,
+		.n_iso_out_chan	= 16,
+		.n_iso_in_chan	= 16,
+		.n_ttl_chan	= 16,
+	}, {
+		.name		= "pcm3730",
+		.io_range	= 0x04,
+		.has_ttl_io	= 1,
+		.n_subdevs	= 4,
+		.n_iso_out_chan	= 8,
+		.n_iso_in_chan	= 8,
+		.n_ttl_chan	= 16,
+	}, {
+		.name		= "pcl725",
+		.io_range	= 0x02,
+		.is_pcl725	= 1,
+		.n_subdevs	= 2,
+		.n_iso_out_chan	= 8,
+		.n_iso_in_chan	= 8,
+	}, {
+		.name		= "p8r8dio",
+		.io_range	= 0x02,
+		.is_pcl725	= 1,
+		.has_readback	= 1,
+		.n_subdevs	= 2,
+		.n_iso_out_chan	= 8,
+		.n_iso_in_chan	= 8,
+	}, {
+		.name		= "acl7225b",
+		.io_range	= 0x08,		/* only 4 are used */
+		.is_acl7225b	= 1,
+		.has_readback	= 1,
+		.n_subdevs	= 2,
+		.n_iso_out_chan	= 16,
+		.n_iso_in_chan	= 16,
+	}, {
+		.name		= "p16r16dio",
+		.io_range	= 0x04,
+		.is_acl7225b	= 1,
+		.has_readback	= 1,
+		.n_subdevs	= 2,
+		.n_iso_out_chan	= 16,
+		.n_iso_in_chan	= 16,
+	}, {
+		.name		= "pcl733",
+		.io_range	= 0x04,
+		.n_subdevs	= 1,
+		.n_iso_in_chan	= 32,
+	}, {
+		.name		= "pcl734",
+		.io_range	= 0x04,
+		.n_subdevs	= 1,
+		.n_iso_out_chan	= 32,
+	},
 };
 
-static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-			  struct comedi_insn *insn, unsigned int *data)
+static int pcl730_do_insn_bits(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn,
+			       unsigned int *data)
 {
-	if (data[0]) {
-		s->state &= ~data[0];
-		s->state |= (data[0] & data[1]);
+	unsigned long reg = (unsigned long)s->private;
+	unsigned int mask = data[0];
+	unsigned int bits = data[1];
+
+	if (mask) {
+		s->state &= ~mask;
+		s->state |= (bits & mask);
+
+		if (mask & 0x00ff)
+			outb(s->state & 0xff, dev->iobase + reg);
+		if ((mask & 0xff00) && (s->n_chan > 8))
+			outb((s->state >> 8) & 0xff, dev->iobase + reg + 1);
+		if ((mask & 0xff0000) && (s->n_chan > 16))
+			outb((s->state >> 16) & 0xff, dev->iobase + reg + 2);
+		if ((mask & 0xff000000) && (s->n_chan > 24))
+			outb((s->state >> 24) & 0xff, dev->iobase + reg + 3);
 	}
-	if (data[0] & 0x00ff)
-		outb(s->state & 0xff,
-		     dev->iobase + ((unsigned long)s->private));
-	if (data[0] & 0xff00)
-		outb((s->state >> 8),
-		     dev->iobase + ((unsigned long)s->private) + 1);
 
 	data[1] = s->state;
 
 	return insn->n;
 }
 
-static int pcl730_di_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-			  struct comedi_insn *insn, unsigned int *data)
+static unsigned int pcl730_get_bits(struct comedi_device *dev,
+				    struct comedi_subdevice *s)
 {
-	data[1] = inb(dev->iobase + ((unsigned long)s->private)) |
-	    (inb(dev->iobase + ((unsigned long)s->private) + 1) << 8);
+	unsigned long reg = (unsigned long)s->private;
+	unsigned int val;
+
+	val = inb(dev->iobase + reg);
+	if (s->n_chan > 8)
+		val |= (inb(dev->iobase + reg + 1) << 8);
+	if (s->n_chan > 16)
+		val |= (inb(dev->iobase + reg + 2) << 16);
+	if (s->n_chan > 24)
+		val |= (inb(dev->iobase + reg + 3) << 24);
+
+	return val;
+}
+
+static int pcl730_di_insn_bits(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn,
+			       unsigned int *data)
+{
+	data[1] = pcl730_get_bits(dev, s);
 
 	return insn->n;
 }
 
-static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pcl730_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it)
 {
 	const struct pcl730_board *board = comedi_board(dev);
 	struct comedi_subdevice *s;
+	int subdev;
 	int ret;
 
 	ret = comedi_request_region(dev, it->options[0], board->io_range);
 	if (ret)
 		return ret;
 
-	ret = comedi_alloc_subdevices(dev, 4);
+	ret = comedi_alloc_subdevices(dev, board->n_subdevs);
 	if (ret)
 		return ret;
 
-	s = &dev->subdevices[0];
-	/* Isolated do */
-	s->type = COMEDI_SUBD_DO;
-	s->subdev_flags = SDF_WRITABLE;
-	s->maxdata = 1;
-	s->n_chan = 16;
-	s->insn_bits = pcl730_do_insn;
-	s->range_table = &range_digital;
-	s->private = (void *)PCL730_IDIO_LO;
+	subdev = 0;
 
-	s = &dev->subdevices[1];
-	/* Isolated di */
-	s->type = COMEDI_SUBD_DI;
-	s->subdev_flags = SDF_READABLE;
-	s->maxdata = 1;
-	s->n_chan = 16;
-	s->insn_bits = pcl730_di_insn;
-	s->range_table = &range_digital;
-	s->private = (void *)PCL730_IDIO_LO;
+	if (board->n_iso_out_chan) {
+		/* Isolated Digital Outputs */
+		s = &dev->subdevices[subdev++];
+		s->type		= COMEDI_SUBD_DO;
+		s->subdev_flags	= SDF_WRITABLE;
+		s->n_chan	= board->n_iso_out_chan;
+		s->maxdata	= 1;
+		s->range_table	= &range_digital;
+		s->insn_bits	= pcl730_do_insn_bits;
+		s->private	= (void *)0;
 
-	s = &dev->subdevices[2];
-	/* TTL do */
-	s->type = COMEDI_SUBD_DO;
-	s->subdev_flags = SDF_WRITABLE;
-	s->maxdata = 1;
-	s->n_chan = 16;
-	s->insn_bits = pcl730_do_insn;
-	s->range_table = &range_digital;
-	s->private = (void *)PCL730_DIO_LO;
+		/* get the initial state if supported */
+		if (board->has_readback)
+			s->state = pcl730_get_bits(dev, s);
+	}
 
-	s = &dev->subdevices[3];
-	/* TTL di */
-	s->type = COMEDI_SUBD_DI;
-	s->subdev_flags = SDF_READABLE;
-	s->maxdata = 1;
-	s->n_chan = 16;
-	s->insn_bits = pcl730_di_insn;
-	s->range_table = &range_digital;
-	s->private = (void *)PCL730_DIO_LO;
+	if (board->n_iso_in_chan) {
+		/* Isolated Digital Inputs */
+		s = &dev->subdevices[subdev++];
+		s->type		= COMEDI_SUBD_DI;
+		s->subdev_flags	= SDF_READABLE;
+		s->n_chan	= board->n_iso_in_chan;
+		s->maxdata	= 1;
+		s->range_table	= &range_digital;
+		s->insn_bits	= pcl730_di_insn_bits;
+		s->private	= board->is_acl7225b ? (void *)2 :
+				  board->is_pcl725 ? (void *)1 : (void *)0;
+	}
 
-	printk(KERN_INFO "\n");
+	if (board->has_ttl_io) {
+		/* TTL Digital Outputs */
+		s = &dev->subdevices[subdev++];
+		s->type		= COMEDI_SUBD_DO;
+		s->subdev_flags	= SDF_WRITABLE;
+		s->n_chan	= board->n_ttl_chan;
+		s->maxdata	= 1;
+		s->range_table	= &range_digital;
+		s->insn_bits	= pcl730_do_insn_bits;
+		s->private	= (void *)2;
+
+		/* TTL Digital Inputs */
+		s = &dev->subdevices[subdev++];
+		s->type		= COMEDI_SUBD_DI;
+		s->subdev_flags	= SDF_READABLE;
+		s->n_chan	= board->n_ttl_chan;
+		s->maxdata	= 1;
+		s->range_table	= &range_digital;
+		s->insn_bits	= pcl730_di_insn_bits;
+		s->private	= (void *)2;
+	}
 
 	return 0;
 }
 
-static const struct pcl730_board boardtypes[] = {
-	{ "pcl730", PCL730_SIZE, },
-	{ "iso730", PCL730_SIZE, },
-	{ "acl7130", ACL7130_SIZE, },
-};
-
 static struct comedi_driver pcl730_driver = {
 	.driver_name	= "pcl730",
 	.module		= THIS_MODULE,
 	.attach		= pcl730_attach,
 	.detach		= comedi_legacy_detach,
-	.board_name	= &boardtypes[0].name,
-	.num_names	= ARRAY_SIZE(boardtypes),
+	.board_name	= &pcl730_boards[0].name,
+	.num_names	= ARRAY_SIZE(pcl730_boards),
 	.offset		= sizeof(struct pcl730_board),
 };
 module_comedi_driver(pcl730_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcm3724.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcm3724.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcm3724.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcm3724.c	2013-08-25 20:43:22.000000000 -0400
@@ -250,20 +250,11 @@ static int pcm3724_attach(struct comedi_
 	return 0;
 }
 
-static void pcm3724_detach(struct comedi_device *dev)
-{
-	int i;
-
-	for (i = 0; i < dev->n_subdevices; i++)
-		comedi_spriv_free(dev, i);
-	comedi_legacy_detach(dev);
-}
-
 static struct comedi_driver pcm3724_driver = {
 	.driver_name	= "pcm3724",
 	.module		= THIS_MODULE,
 	.attach		= pcm3724_attach,
-	.detach		= pcm3724_detach,
+	.detach		= comedi_legacy_detach,
 };
 module_comedi_driver(pcm3724_driver);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcm3730.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcm3730.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcm3730.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcm3730.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,136 +0,0 @@
-/*
- * comedi/drivers/pcm3730.c
- * Driver for PCM3730 and clones
- * Blaine Lee
- * from pcl725 by David S.
- */
-/*
-Driver: pcm3730
-Description: PCM3730
-Author: Blaine Lee
-Devices: [Advantech] PCM-3730 (pcm3730)
-Status: unknown
-
-Configuration options:
-  [0] - I/O port base
-*/
-
-#include "../comedidev.h"
-
-#include <linux/ioport.h>
-
-#define PCM3730_SIZE 4		/*  consecutive io port addresses */
-
-#define PCM3730_DOA 0		/*  offsets for each port */
-#define PCM3730_DOB 2
-#define PCM3730_DOC 3
-#define PCM3730_DIA 0
-#define PCM3730_DIB 2
-#define PCM3730_DIC 3
-
-static int pcm3730_do_insn_bits(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				struct comedi_insn *insn, unsigned int *data)
-{
-	if (data[0]) {
-		s->state &= ~data[0];
-		s->state |= (data[0] & data[1]);
-		outb(s->state, dev->iobase + (unsigned long)(s->private));
-	}
-	data[1] = s->state;
-
-	return insn->n;
-}
-
-static int pcm3730_di_insn_bits(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				struct comedi_insn *insn, unsigned int *data)
-{
-	data[1] = inb(dev->iobase + (unsigned long)(s->private));
-	return insn->n;
-}
-
-static int pcm3730_attach(struct comedi_device *dev,
-			  struct comedi_devconfig *it)
-{
-	struct comedi_subdevice *s;
-	int ret;
-
-	ret = comedi_request_region(dev, it->options[0], PCM3730_SIZE);
-	if (ret)
-		return ret;
-
-	ret = comedi_alloc_subdevices(dev, 6);
-	if (ret)
-		return ret;
-
-	s = &dev->subdevices[0];
-	s->type = COMEDI_SUBD_DO;
-	s->subdev_flags = SDF_WRITABLE;
-	s->maxdata = 1;
-	s->n_chan = 8;
-	s->insn_bits = pcm3730_do_insn_bits;
-	s->range_table = &range_digital;
-	s->private = (void *)PCM3730_DOA;
-
-	s = &dev->subdevices[1];
-	s->type = COMEDI_SUBD_DO;
-	s->subdev_flags = SDF_WRITABLE;
-	s->maxdata = 1;
-	s->n_chan = 8;
-	s->insn_bits = pcm3730_do_insn_bits;
-	s->range_table = &range_digital;
-	s->private = (void *)PCM3730_DOB;
-
-	s = &dev->subdevices[2];
-	s->type = COMEDI_SUBD_DO;
-	s->subdev_flags = SDF_WRITABLE;
-	s->maxdata = 1;
-	s->n_chan = 8;
-	s->insn_bits = pcm3730_do_insn_bits;
-	s->range_table = &range_digital;
-	s->private = (void *)PCM3730_DOC;
-
-	s = &dev->subdevices[3];
-	s->type = COMEDI_SUBD_DI;
-	s->subdev_flags = SDF_READABLE;
-	s->maxdata = 1;
-	s->n_chan = 8;
-	s->insn_bits = pcm3730_di_insn_bits;
-	s->range_table = &range_digital;
-	s->private = (void *)PCM3730_DIA;
-
-	s = &dev->subdevices[4];
-	s->type = COMEDI_SUBD_DI;
-	s->subdev_flags = SDF_READABLE;
-	s->maxdata = 1;
-	s->n_chan = 8;
-	s->insn_bits = pcm3730_di_insn_bits;
-	s->range_table = &range_digital;
-	s->private = (void *)PCM3730_DIB;
-
-	s = &dev->subdevices[5];
-	s->type = COMEDI_SUBD_DI;
-	s->subdev_flags = SDF_READABLE;
-	s->maxdata = 1;
-	s->n_chan = 8;
-	s->insn_bits = pcm3730_di_insn_bits;
-	s->range_table = &range_digital;
-	s->private = (void *)PCM3730_DIC;
-
-	printk(KERN_INFO "\n");
-
-	return 0;
-}
-
-static struct comedi_driver pcm3730_driver = {
-	.driver_name	= "pcm3730",
-	.module		= THIS_MODULE,
-	.attach		= pcm3730_attach,
-	.detach		= comedi_legacy_detach,
-};
-module_comedi_driver(pcm3730_driver);
-
-MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
-MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcmad.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcmad.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcmad.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcmad.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,53 +1,45 @@
 /*
-    comedi/drivers/pcmad.c
-    Hardware driver for Winsystems PCM-A/D12 and PCM-A/D16
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * pcmad.c
+ * Hardware driver for Winsystems PCM-A/D12 and PCM-A/D16
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
-*/
 /*
-Driver: pcmad
-Description: Winsystems PCM-A/D12, PCM-A/D16
-Author: ds
-Devices: [Winsystems] PCM-A/D12 (pcmad12), PCM-A/D16 (pcmad16)
-Status: untested
-
-This driver was written on a bet that I couldn't write a driver
-in less than 2 hours.  I won the bet, but never got paid.  =(
-
-Configuration options:
-  [0] - I/O port base
-  [1] - unused
-  [2] - Analog input reference
-	0 = single ended
-	1 = differential
-  [3] - Analog input encoding (must match jumpers)
-	0 = straight binary
-	1 = two's complement
-*/
+ * Driver: pcmad
+ * Description: Winsystems PCM-A/D12, PCM-A/D16
+ * Devices: (Winsystems) PCM-A/D12 [pcmad12]
+ *	    (Winsystems) PCM-A/D16 [pcmad16]
+ * Author: ds
+ * Status: untested
+ *
+ * This driver was written on a bet that I couldn't write a driver
+ * in less than 2 hours.  I won the bet, but never got paid.  =(
+ *
+ * Configuration options:
+ *   [0] - I/O port base
+ *   [1] - IRQ (unused)
+ *   [2] - Analog input reference (must match jumpers)
+ *	   0 = single-ended (16 channels)
+ *	   1 = differential (8 channels)
+ *   [3] - Analog input encoding (must match jumpers)
+ *	   0 = straight binary (0-5V input range)
+ *	   1 = two's complement (+-10V input range)
+ */
 
-#include <linux/interrupt.h>
 #include "../comedidev.h"
 
-#include <linux/ioport.h>
-
-#define PCMAD_SIZE		4
-
 #define PCMAD_STATUS		0
 #define PCMAD_LSB		1
 #define PCMAD_MSB		2
@@ -55,60 +47,82 @@ Configuration options:
 
 struct pcmad_board_struct {
 	const char *name;
-	int n_ai_bits;
+	unsigned int ai_maxdata;
 };
 
-struct pcmad_priv_struct {
-	int differential;
-	int twos_comp;
+static const struct pcmad_board_struct pcmad_boards[] = {
+	{
+		.name		= "pcmad12",
+		.ai_maxdata	= 0x0fff,
+	}, {
+		.name		= "pcmad16",
+		.ai_maxdata	= 0xffff,
+	},
 };
 
 #define TIMEOUT	100
 
+static int pcmad_ai_wait_for_eoc(struct comedi_device *dev,
+				 int timeout)
+{
+	int i;
+
+	for (i = 0; i < timeout; i++) {
+		if ((inb(dev->iobase + PCMAD_STATUS) & 0x3) == 0x3)
+			return 0;
+	}
+	return -ETIME;
+}
+
+static bool pcmad_range_is_bipolar(struct comedi_subdevice *s,
+				   unsigned int range)
+{
+	return s->range_table->range[range].min < 0;
+}
+
 static int pcmad_ai_insn_read(struct comedi_device *dev,
 			      struct comedi_subdevice *s,
-			      struct comedi_insn *insn, unsigned int *data)
+			      struct comedi_insn *insn,
+			      unsigned int *data)
 {
-	const struct pcmad_board_struct *board = comedi_board(dev);
-	struct pcmad_priv_struct *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int range = CR_RANGE(insn->chanspec);
+	unsigned int val;
+	int ret;
 	int i;
-	int chan;
-	int n;
 
-	chan = CR_CHAN(insn->chanspec);
-
-	for (n = 0; n < insn->n; n++) {
+	for (i = 0; i < insn->n; i++) {
 		outb(chan, dev->iobase + PCMAD_CONVERT);
 
-		for (i = 0; i < TIMEOUT; i++) {
-			if ((inb(dev->iobase + PCMAD_STATUS) & 0x3) == 0x3)
-				break;
+		ret = pcmad_ai_wait_for_eoc(dev, TIMEOUT);
+		if (ret)
+			return ret;
+
+		val = inb(dev->iobase + PCMAD_LSB) |
+		      (inb(dev->iobase + PCMAD_MSB) << 8);
+
+		/* data is shifted on the pcmad12, fix it */
+		if (s->maxdata == 0x0fff)
+			val >>= 4;
+
+		if (pcmad_range_is_bipolar(s, range)) {
+			/* munge the two's complement value */
+			val ^= ((s->maxdata + 1) >> 1);
 		}
-		data[n] = inb(dev->iobase + PCMAD_LSB);
-		data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8);
 
-		if (devpriv->twos_comp)
-			data[n] ^= (1 << (board->n_ai_bits - 1));
+		data[i] = val;
 	}
 
-	return n;
+	return insn->n;
 }
 
-/*
- * options:
- * 0	i/o base
- * 1	unused
- * 2	0=single ended 1=differential
- * 3	0=straight binary 1=two's comp
- */
 static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	const struct pcmad_board_struct *board = comedi_board(dev);
-	struct pcmad_priv_struct *devpriv;
 	struct comedi_subdevice *s;
 	int ret;
 
-	ret = comedi_request_region(dev, it->options[0], PCMAD_SIZE);
+	ret = comedi_request_region(dev, it->options[0], 0x04);
 	if (ret)
 		return ret;
 
@@ -116,32 +130,25 @@ static int pcmad_attach(struct comedi_de
 	if (ret)
 		return ret;
 
-	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
-	if (!devpriv)
-		return -ENOMEM;
-	dev->private = devpriv;
-
 	s = &dev->subdevices[0];
-	s->type = COMEDI_SUBD_AI;
-	s->subdev_flags = SDF_READABLE | AREF_GROUND;
-	s->n_chan = 16;		/* XXX */
-	s->len_chanlist = 1;
-	s->insn_read = pcmad_ai_insn_read;
-	s->maxdata = (1 << board->n_ai_bits) - 1;
-	s->range_table = &range_unknown;
+	s->type		= COMEDI_SUBD_AI;
+	if (it->options[1]) {
+		/* 8 differential channels */
+		s->subdev_flags	= SDF_READABLE | AREF_DIFF;
+		s->n_chan	= 8;
+	} else {
+		/* 16 single-ended channels */
+		s->subdev_flags	= SDF_READABLE | AREF_GROUND;
+		s->n_chan	= 16;
+	}
+	s->len_chanlist	= 1;
+	s->maxdata	= board->ai_maxdata;
+	s->range_table	= it->options[2] ? &range_bipolar10 : &range_unipolar5;
+	s->insn_read	= pcmad_ai_insn_read;
 
 	return 0;
 }
 
-static const struct pcmad_board_struct pcmad_boards[] = {
-	{
-		.name		= "pcmad12",
-		.n_ai_bits	= 12,
-	}, {
-		.name		= "pcmad16",
-		.n_ai_bits	= 16,
-	},
-};
 static struct comedi_driver pcmad_driver = {
 	.driver_name	= "pcmad",
 	.module		= THIS_MODULE,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcmda12.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcmda12.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcmda12.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcmda12.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,152 +1,130 @@
 /*
-    comedi/drivers/pcmda12.c
-    Driver for Winsystems PC-104 based PCM-D/A-12 8-channel AO board.
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
+ * pcmda12.c
+ * Driver for Winsystems PC-104 based PCM-D/A-12 8-channel AO board.
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
 /*
-Driver: pcmda12
-Description: A driver for the Winsystems PCM-D/A-12
-Devices: [Winsystems] PCM-D/A-12 (pcmda12)
-Author: Calin Culianu <calin@ajvar.org>
-Updated: Fri, 13 Jan 2006 12:01:01 -0500
-Status: works
-
-A driver for the relatively straightforward-to-program PCM-D/A-12.
-This board doesn't support commands, and the only way to set its
-analog output range is to jumper the board.  As such,
-comedi_data_write() ignores the range value specified.
-
-The board uses 16 consecutive I/O addresses starting at the I/O port
-base address.  Each address corresponds to the LSB then MSB of a
-particular channel from 0-7.
-
-Note that the board is not ISA-PNP capable and thus
-needs the I/O port comedi_config parameter.
-
-Note that passing a nonzero value as the second config option will
-enable "simultaneous xfer" mode for this board, in which AO writes
-will not take effect until a subsequent read of any AO channel.  This
-is so that one can speed up programming by preloading all AO registers
-with values before simultaneously setting them to take effect with one
-read command.
-
-Configuration Options:
-  [0] - I/O port base address
-  [1] - Do Simultaneous Xfer (see description)
-*/
+ * Driver: pcmda12
+ * Description: A driver for the Winsystems PCM-D/A-12
+ * Devices: (Winsystems) PCM-D/A-12 [pcmda12]
+ * Author: Calin Culianu <calin@ajvar.org>
+ * Updated: Fri, 13 Jan 2006 12:01:01 -0500
+ * Status: works
+ *
+ * A driver for the relatively straightforward-to-program PCM-D/A-12.
+ * This board doesn't support commands, and the only way to set its
+ * analog output range is to jumper the board. As such,
+ * comedi_data_write() ignores the range value specified.
+ *
+ * The board uses 16 consecutive I/O addresses starting at the I/O port
+ * base address. Each address corresponds to the LSB then MSB of a
+ * particular channel from 0-7.
+ *
+ * Note that the board is not ISA-PNP capable and thus needs the I/O
+ * port comedi_config parameter.
+ *
+ * Note that passing a nonzero value as the second config option will
+ * enable "simultaneous xfer" mode for this board, in which AO writes
+ * will not take effect until a subsequent read of any AO channel. This
+ * is so that one can speed up programming by preloading all AO registers
+ * with values before simultaneously setting them to take effect with one
+ * read command.
+ *
+ * Configuration Options:
+ *   [0] - I/O port base address
+ *   [1] - Do Simultaneous Xfer (see description)
+ */
 
 #include "../comedidev.h"
 
-#define CHANS 8
-#define IOSIZE 16
-#define LSB(x) ((unsigned char)((x) & 0xff))
-#define MSB(x) ((unsigned char)((((unsigned short)(x))>>8) & 0xff))
-#define LSB_PORT(chan) (dev->iobase + (chan)*2)
-#define MSB_PORT(chan) (LSB_PORT(chan)+1)
-#define BITS 12
-
-/* note these have no effect and are merely here for reference..
-   these are configured by jumpering the board! */
+/* AI range is not configurable, it's set by jumpers on the board */
 static const struct comedi_lrange pcmda12_ranges = {
-	3,
-	{
-	 UNI_RANGE(5), UNI_RANGE(10), BIP_RANGE(5)
-	 }
+	3, {
+		UNI_RANGE(5),
+		UNI_RANGE(10),
+		BIP_RANGE(5)
+	}
 };
 
 struct pcmda12_private {
-
-	unsigned int ao_readback[CHANS];
+	unsigned int ao_readback[8];
 	int simultaneous_xfer_mode;
 };
 
-static void zero_chans(struct comedi_device *dev)
-{				/* sets up an
-				   ASIC chip to defaults */
-	int i;
-	for (i = 0; i < CHANS; ++i) {
-/*      /\* do this as one instruction?? *\/ */
-/*      outw(0, LSB_PORT(chan)); */
-		outb(0, LSB_PORT(i));
-		outb(0, MSB_PORT(i));
-	}
-	inb(LSB_PORT(0));	/* update chans. */
-}
-
-static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-		    struct comedi_insn *insn, unsigned int *data)
+static int pcmda12_ao_insn_write(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn,
+				 unsigned int *data)
 {
 	struct pcmda12_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int val = devpriv->ao_readback[chan];
+	unsigned long ioreg = dev->iobase + (chan * 2);
 	int i;
-	int chan = CR_CHAN(insn->chanspec);
 
-	/* Writing a list of values to an AO channel is probably not
-	 * very useful, but that's how the interface is defined. */
 	for (i = 0; i < insn->n; ++i) {
+		val = data[i];
+		outb(val & 0xff, ioreg);
+		outb((val >> 8) & 0xff, ioreg + 1);
 
-/*      /\* do this as one instruction?? *\/ */
-/*      outw(data[i], LSB_PORT(chan)); */
-
-		/* Need to do this as two instructions due to 8-bit bus?? */
-		/*  first, load the low byte */
-		outb(LSB(data[i]), LSB_PORT(chan));
-		/*  next, write the high byte */
-		outb(MSB(data[i]), MSB_PORT(chan));
-
-		/* save shadow register */
-		devpriv->ao_readback[chan] = data[i];
-
+		/*
+		 * Initiate transfer if not in simultaneaous xfer
+		 * mode by reading one of the AO registers.
+		 */
 		if (!devpriv->simultaneous_xfer_mode)
-			inb(LSB_PORT(chan));
+			inb(ioreg);
 	}
+	devpriv->ao_readback[chan] = val;
 
-	/* return the number of samples written */
-	return i;
+	return insn->n;
 }
 
-/* AO subdevices should have a read insn as well as a write insn.
-
-   Usually this means copying a value stored in devpriv->ao_readback.
-   However, since this driver supports simultaneous xfer then sometimes
-   this function actually accomplishes work.
-
-   Simultaneaous xfer mode is accomplished by loading ALL the values
-   you want for AO in all the channels, then READing off one of the AO
-   registers to initiate the instantaneous simultaneous update of all
-   DAC outputs, which makes all AO channels update simultaneously.
-   This is useful for some control applications, I would imagine.
-*/
-static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-		    struct comedi_insn *insn, unsigned int *data)
+static int pcmda12_ao_insn_read(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn,
+				unsigned int *data)
 {
 	struct pcmda12_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
 	int i;
-	int chan = CR_CHAN(insn->chanspec);
 
-	for (i = 0; i < insn->n; i++) {
-		if (devpriv->simultaneous_xfer_mode)
-			inb(LSB_PORT(chan));
-		/* read back shadow register */
+	/*
+	 * Initiate simultaneaous xfer mode by reading one of the
+	 * AO registers. All analog outputs will then be updated.
+	 */
+	if (devpriv->simultaneous_xfer_mode)
+		inb(dev->iobase);
+
+	for (i = 0; i < insn->n; i++)
 		data[i] = devpriv->ao_readback[chan];
-	}
 
-	return i;
+	return insn->n;
+}
+
+static void pcmda12_ao_reset(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
+{
+	int i;
+
+	for (i = 0; i < s->n_chan; ++i) {
+		outb(0, dev->iobase + (i * 2));
+		outb(0, dev->iobase + (i * 2) + 1);
+	}
+	/* Initiate transfer by reading one of the AO registers. */
+	inb(dev->iobase);
 }
 
 static int pcmda12_attach(struct comedi_device *dev,
@@ -156,7 +134,7 @@ static int pcmda12_attach(struct comedi_
 	struct comedi_subdevice *s;
 	int ret;
 
-	ret = comedi_request_region(dev, it->options[0], IOSIZE);
+	ret = comedi_request_region(dev, it->options[0], 0x10);
 	if (ret)
 		return ret;
 
@@ -172,18 +150,17 @@ static int pcmda12_attach(struct comedi_
 		return ret;
 
 	s = &dev->subdevices[0];
-	s->private = NULL;
-	s->maxdata = (0x1 << BITS) - 1;
-	s->range_table = &pcmda12_ranges;
-	s->type = COMEDI_SUBD_AO;
-	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-	s->n_chan = CHANS;
-	s->insn_write = &ao_winsn;
-	s->insn_read = &ao_rinsn;
+	s->type		= COMEDI_SUBD_AO;
+	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
+	s->n_chan	= 8;
+	s->maxdata	= 0x0fff;
+	s->range_table	= &pcmda12_ranges;
+	s->insn_write	= pcmda12_ao_insn_write;
+	s->insn_read	= pcmda12_ao_insn_read;
 
-	zero_chans(dev);	/* clear out all the registers, basically */
+	pcmda12_ao_reset(dev, s);
 
-	return 1;
+	return 0;
 }
 
 static struct comedi_driver pcmda12_driver = {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcmmio.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcmmio.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcmmio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcmmio.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 /*
 Driver: pcmmio
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcmuio.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcmuio.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/pcmuio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/pcmuio.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,79 +1,77 @@
 /*
-    comedi/drivers/pcmuio.c
-    Driver for Winsystems PC-104 based 48-channel and 96-channel DIO boards.
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
+ * pcmuio.c
+ * Comedi driver for Winsystems PC-104 based 48/96-channel DIO boards.
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
 /*
-Driver: pcmuio
-Description: A driver for the PCM-UIO48A and PCM-UIO96A boards from Winsystems.
-Devices: [Winsystems] PCM-UIO48A (pcmuio48), PCM-UIO96A (pcmuio96)
-Author: Calin Culianu <calin@ajvar.org>
-Updated: Fri, 13 Jan 2006 12:01:01 -0500
-Status: works
-
-A driver for the relatively straightforward-to-program PCM-UIO48A and
-PCM-UIO96A boards from Winsystems.  These boards use either one or two
-(in the 96-DIO version) WS16C48 ASIC HighDensity I/O Chips (HDIO).
-This chip is interesting in that each I/O line is individually
-programmable for INPUT or OUTPUT (thus comedi_dio_config can be done
-on a per-channel basis).  Also, each chip supports edge-triggered
-interrupts for the first 24 I/O lines.  Of course, since the
-96-channel version of the board has two ASICs, it can detect polarity
-changes on up to 48 I/O lines.  Since this is essentially an (non-PnP)
-ISA board, I/O Address and IRQ selection are done through jumpers on
-the board.  You need to pass that information to this driver as the
-first and second comedi_config option, respectively.  Note that the
-48-channel version uses 16 bytes of IO memory and the 96-channel
-version uses 32-bytes (in case you are worried about conflicts).  The
-48-channel board is split into two 24-channel comedi subdevices.
-The 96-channel board is split into 4 24-channel DIO subdevices.
-
-Note that IRQ support has been added, but it is untested.
-
-To use edge-detection IRQ support, pass the IRQs of both ASICS
-(for the 96 channel version) or just 1 ASIC (for 48-channel version).
-Then, use use comedi_commands with TRIG_NOW.
-Your callback will be called each time an edge is triggered, and the data
-values will be two sample_t's, which should be concatenated to form one
-32-bit unsigned int.  This value is the mask of channels that had
-edges detected from your channel list.  Note that the bits positions
-in the mask correspond to positions in your chanlist when you specified
-the command and *not* channel id's!
-
-To set the polarity of the edge-detection interrupts pass a nonzero value for
-either CR_RANGE or CR_AREF for edge-up polarity, or a zero value for both
-CR_RANGE and CR_AREF if you want edge-down polarity.
-
-In the 48-channel version:
-
-On subdev 0, the first 24 channels channels are edge-detect channels.
-
-In the 96-channel board you have the collowing channels that can do edge detection:
-
-subdev 0, channels 0-24  (first 24 channels of 1st ASIC)
-subdev 2, channels 0-24  (first 24 channels of 2nd ASIC)
-
-Configuration Options:
-  [0] - I/O port base address
-  [1] - IRQ (for first ASIC, or first 24 channels)
-  [2] - IRQ for second ASIC (pcmuio96 only - IRQ for chans 48-72 .. can be the same as first irq!)
-*/
+ * Driver: pcmuio
+ * Description: Winsystems PC-104 based 48/96-channel DIO boards.
+ * Devices: (Winsystems) PCM-UIO48A [pcmuio48]
+ *	    (Winsystems) PCM-UIO96A [pcmuio96]
+ * Author: Calin Culianu <calin@ajvar.org>
+ * Updated: Fri, 13 Jan 2006 12:01:01 -0500
+ * Status: works
+ *
+ * A driver for the relatively straightforward-to-program PCM-UIO48A and
+ * PCM-UIO96A boards from Winsystems. These boards use either one or two
+ * (in the 96-DIO version) WS16C48 ASIC HighDensity I/O Chips (HDIO). This
+ * chip is interesting in that each I/O line is individually programmable
+ * for INPUT or OUTPUT (thus comedi_dio_config can be done on a per-channel
+ * basis). Also, each chip supports edge-triggered interrupts for the first
+ * 24 I/O lines. Of course, since the 96-channel version of the board has
+ * two ASICs, it can detect polarity changes on up to 48 I/O lines. Since
+ * this is essentially an (non-PnP) ISA board, I/O Address and IRQ selection
+ * are done through jumpers on the board. You need to pass that information
+ * to this driver as the first and second comedi_config option, respectively.
+ * Note that the 48-channel version uses 16 bytes of IO memory and the 96-
+ * channel version uses 32-bytes (in case you are worried about conflicts).
+ * The 48-channel board is split into two 24-channel comedi subdevices. The
+ * 96-channel board is split into 4 24-channel DIO subdevices.
+ *
+ * Note that IRQ support has been added, but it is untested.
+ *
+ * To use edge-detection IRQ support, pass the IRQs of both ASICS (for the
+ * 96 channel version) or just 1 ASIC (for 48-channel version). Then, use
+ * comedi_commands with TRIG_NOW. Your callback will be called each time an
+ * edge is triggered, and the data values will be two sample_t's, which
+ * should be concatenated to form one 32-bit unsigned int.  This value is
+ * the mask of channels that had edges detected from your channel list. Note
+ * that the bits positions in the mask correspond to positions in your
+ * chanlist when you specified the command and *not* channel id's!
+ *
+ * To set the polarity of the edge-detection interrupts pass a nonzero value
+ * for either CR_RANGE or CR_AREF for edge-up polarity, or a zero value for
+ * both CR_RANGE and CR_AREF if you want edge-down polarity.
+ *
+ * In the 48-channel version:
+ *
+ * On subdev 0, the first 24 channels channels are edge-detect channels.
+ *
+ * In the 96-channel board you have the following channels that can do edge
+ * detection:
+ *
+ * subdev 0, channels 0-24  (first 24 channels of 1st ASIC)
+ * subdev 2, channels 0-24  (first 24 channels of 2nd ASIC)
+ *
+ * Configuration Options:
+ *  [0] - I/O port base address
+ *  [1] - IRQ (for first ASIC, or first 24 channels)
+ *  [2] - IRQ (for second ASIC, pcmuio96 only - IRQ for chans 48-72
+ *             can be the same as first irq!)
+ */
 
 #include <linux/interrupt.h>
 #include <linux/slab.h>
@@ -82,94 +80,62 @@ Configuration Options:
 
 #include "comedi_fc.h"
 
-#define CHANS_PER_PORT   8
-#define PORTS_PER_ASIC   6
-#define INTR_PORTS_PER_ASIC   3
-#define MAX_CHANS_PER_SUBDEV 24	/* number of channels per comedi subdevice */
-#define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV/CHANS_PER_PORT)
-#define CHANS_PER_ASIC (CHANS_PER_PORT*PORTS_PER_ASIC)
-#define INTR_CHANS_PER_ASIC 24
-#define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT)
-#define MAX_DIO_CHANS   (PORTS_PER_ASIC*2*CHANS_PER_PORT)
-#define MAX_ASICS       (MAX_DIO_CHANS/CHANS_PER_ASIC)
-#define CALC_N_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) /*+ (nchans > INTR_CHANS_PER_ASIC ? 2 : 1)*/)
-/* IO Memory sizes */
-#define ASIC_IOSIZE (0x10)
-#define PCMUIO48_IOSIZE ASIC_IOSIZE
-#define PCMUIO96_IOSIZE (ASIC_IOSIZE*2)
-
-/* Some offsets - these are all in the 16byte IO memory offset from
-   the base address.  Note that there is a paging scheme to swap out
-   offsets 0x8-0xA using the PAGELOCK register.  See the table below.
-
-  Register(s)       Pages        R/W?        Description
-  --------------------------------------------------------------
-  REG_PORTx         All          R/W         Read/Write/Configure IO
-  REG_INT_PENDING   All          ReadOnly    Quickly see which INT_IDx has int.
-  REG_PAGELOCK      All          WriteOnly   Select a page
-  REG_POLx          Pg. 1 only   WriteOnly   Select edge-detection polarity
-  REG_ENABx         Pg. 2 only   WriteOnly   Enable/Disable edge-detect. int.
-  REG_INT_IDx       Pg. 3 only   R/W         See which ports/bits have ints.
+/*
+ * Register I/O map
+ *
+ * Offset    Page 0       Page 1       Page 2       Page 3
+ * ------  -----------  -----------  -----------  -----------
+ *  0x00   Port 0 I/O   Port 0 I/O   Port 0 I/O   Port 0 I/O
+ *  0x01   Port 1 I/O   Port 1 I/O   Port 1 I/O   Port 1 I/O
+ *  0x02   Port 2 I/O   Port 2 I/O   Port 2 I/O   Port 2 I/O
+ *  0x03   Port 3 I/O   Port 3 I/O   Port 3 I/O   Port 3 I/O
+ *  0x04   Port 4 I/O   Port 4 I/O   Port 4 I/O   Port 4 I/O
+ *  0x05   Port 5 I/O   Port 5 I/O   Port 5 I/O   Port 5 I/O
+ *  0x06   INT_PENDING  INT_PENDING  INT_PENDING  INT_PENDING
+ *  0x07    Page/Lock    Page/Lock    Page/Lock    Page/Lock
+ *  0x08       N/A         POL_0       ENAB_0       INT_ID0
+ *  0x09       N/A         POL_1       ENAB_1       INT_ID1
+ *  0x0a       N/A         POL_2       ENAB_2       INT_ID2
  */
-#define REG_PORT0 0x0
-#define REG_PORT1 0x1
-#define REG_PORT2 0x2
-#define REG_PORT3 0x3
-#define REG_PORT4 0x4
-#define REG_PORT5 0x5
-#define REG_INT_PENDING 0x6
-#define REG_PAGELOCK 0x7	/* page selector register, upper 2 bits select a page
-				   and bits 0-5 are used to 'lock down' a particular
-				   port above to make it readonly.  */
-#define REG_POL0 0x8
-#define REG_POL1 0x9
-#define REG_POL2 0xA
-#define REG_ENAB0 0x8
-#define REG_ENAB1 0x9
-#define REG_ENAB2 0xA
-#define REG_INT_ID0 0x8
-#define REG_INT_ID1 0x9
-#define REG_INT_ID2 0xA
+#define PCMUIO_PORT_REG(x)		(0x00 + (x))
+#define PCMUIO_INT_PENDING_REG		0x06
+#define PCMUIO_PAGE_LOCK_REG		0x07
+#define PCMUIO_LOCK_PORT(x)		((1 << (x)) & 0x3f)
+#define PCMUIO_PAGE(x)			(((x) & 0x3) << 6)
+#define PCMUIO_PAGE_MASK		PCMUIO_PAGE(3)
+#define PCMUIO_PAGE_POL			1
+#define PCMUIO_PAGE_ENAB		2
+#define PCMUIO_PAGE_INT_ID		3
+#define PCMUIO_PAGE_REG(x)		(0x08 + (x))
 
-#define NUM_PAGED_REGS 3
-#define NUM_PAGES 4
-#define FIRST_PAGED_REG 0x8
-#define REG_PAGE_BITOFFSET 6
-#define REG_LOCK_BITOFFSET 0
-#define REG_PAGE_MASK (~((0x1<<REG_PAGE_BITOFFSET)-1))
-#define REG_LOCK_MASK ~(REG_PAGE_MASK)
-#define PAGE_POL 1
-#define PAGE_ENAB 2
-#define PAGE_INT_ID 3
+#define PCMUIO_ASIC_IOSIZE		0x10
+#define PCMUIO_MAX_ASICS		2
 
-/*
- * Board descriptions for two imaginary boards.  Describing the
- * boards in this way is optional, and completely driver-dependent.
- * Some drivers use arrays such as this, other do not.
- */
 struct pcmuio_board {
 	const char *name;
 	const int num_asics;
-	const int num_channels_per_port;
-	const int num_ports;
 };
 
-/* this structure is for data unique to this subdevice.  */
-struct pcmuio_subdev_private {
-	/* mapping of halfwords (bytes) in port/chanarray to iobase */
-	unsigned long iobases[PORTS_PER_SUBDEV];
+static const struct pcmuio_board pcmuio_boards[] = {
+	{
+		.name		= "pcmuio48",
+		.num_asics	= 1,
+	}, {
+		.name		= "pcmuio96",
+		.num_asics	= 2,
+	},
+};
 
+struct pcmuio_subdev_private {
 	/* The below is only used for intr subdevices */
 	struct {
-		int asic;	/* if non-negative, this subdev has an interrupt asic */
-		int first_chan;	/* if nonnegative, the first channel id for
-				   interrupts. */
-		int num_asic_chans;	/* the number of asic channels in this subdev
-					   that have interrutps */
-		int asic_chan;	/* if nonnegative, the first channel id with
-				   respect to the asic that has interrupts */
-		int enabled_mask;	/* subdev-relative channel mask for channels
-					   we are interested in */
+		/* if non-negative, this subdev has an interrupt asic */
+		int asic;
+		/*
+		 * subdev-relative channel mask for channels
+		 * we are interested in
+		 */
+		int enabled_mask;
 		int active;
 		int stop_count;
 		int continuous;
@@ -177,160 +143,112 @@ struct pcmuio_subdev_private {
 	} intr;
 };
 
-/* this structure is for data unique to this hardware driver.  If
-   several hardware drivers keep similar information in this structure,
-   feel free to suggest moving the variable to the struct comedi_device struct.  */
 struct pcmuio_private {
 	struct {
-		unsigned char pagelock;	/* current page and lock */
-		unsigned char pol[NUM_PAGED_REGS];	/* shadow of POLx registers */
-		unsigned char enab[NUM_PAGED_REGS];	/* shadow of ENABx registers */
-		int num;
-		unsigned long iobase;
 		unsigned int irq;
 		spinlock_t spinlock;
-	} asics[MAX_ASICS];
+	} asics[PCMUIO_MAX_ASICS];
 	struct pcmuio_subdev_private *sprivs;
 };
 
-#define subpriv ((struct pcmuio_subdev_private *)s->private)
-
-/* DIO devices are slightly special.  Although it is possible to
- * implement the insn_read/insn_write interface, it is much more
- * useful to applications if you implement the insn_bits interface.
- * This allows packed reading/writing of the DIO channels.  The
- * comedi core can convert between insn_bits and insn_read/write */
-static int pcmuio_dio_insn_bits(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				struct comedi_insn *insn, unsigned int *data)
+static void pcmuio_write(struct comedi_device *dev, unsigned int val,
+			 int asic, int page, int port)
 {
-	int byte_no;
+	unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE);
 
-	/* NOTE:
-	   reading a 0 means this channel was high
-	   writine a 0 sets the channel high
-	   reading a 1 means this channel was low
-	   writing a 1 means set this channel low
+	if (page == 0) {
+		/* Port registers are valid for any page */
+		outb(val & 0xff, iobase + PCMUIO_PORT_REG(port + 0));
+		outb((val >> 8) & 0xff, iobase + PCMUIO_PORT_REG(port + 1));
+		outb((val >> 16) & 0xff, iobase + PCMUIO_PORT_REG(port + 2));
+	} else {
+		outb(PCMUIO_PAGE(page), iobase + PCMUIO_PAGE_LOCK_REG);
+		outb(val & 0xff, iobase + PCMUIO_PAGE_REG(0));
+		outb((val >> 8) & 0xff, iobase + PCMUIO_PAGE_REG(1));
+		outb((val >> 16) & 0xff, iobase + PCMUIO_PAGE_REG(2));
+	}
+}
 
-	   Therefore everything is always inverted. */
+static unsigned int pcmuio_read(struct comedi_device *dev,
+				int asic, int page, int port)
+{
+	unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE);
+	unsigned int val;
 
-	/* The insn data is a mask in data[0] and the new data
-	 * in data[1], each channel cooresponding to a bit. */
+	if (page == 0) {
+		/* Port registers are valid for any page */
+		val = inb(iobase + PCMUIO_PORT_REG(port + 0));
+		val |= (inb(iobase + PCMUIO_PORT_REG(port + 1)) << 8);
+		val |= (inb(iobase + PCMUIO_PORT_REG(port + 2)) << 16);
+	} else {
+		outb(PCMUIO_PAGE(page), iobase + PCMUIO_PAGE_LOCK_REG);
+		val = inb(iobase + PCMUIO_PAGE_REG(0));
+		val |= (inb(iobase + PCMUIO_PAGE_REG(1)) << 8);
+		val |= (inb(iobase + PCMUIO_PAGE_REG(2)) << 16);
+	}
 
-#ifdef DAMMIT_ITS_BROKEN
-	/* DEBUG */
-	dev_dbg(dev->class_dev, "write mask: %08x  data: %08x\n", data[0],
-		data[1]);
-#endif
+	return val;
+}
 
-	s->state = 0;
+/*
+ * Each channel can be individually programmed for input or output.
+ * Writing a '0' to a channel causes the corresponding output pin
+ * to go to a high-z state (pulled high by an external 10K resistor).
+ * This allows it to be used as an input. When used in the input mode,
+ * a read reflects the inverted state of the I/O pin, such that a
+ * high on the pin will read as a '0' in the register. Writing a '1'
+ * to a bit position causes the pin to sink current (up to 12mA),
+ * effectively pulling it low.
+ */
+static int pcmuio_dio_insn_bits(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
+{
+	unsigned int mask = data[0] & s->io_bits;	/* outputs only */
+	unsigned int bits = data[1];
+	int asic = s->index / 2;
+	int port = (s->index % 2) ? 3 : 0;
+	unsigned int val;
 
-	for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) {
-		/* address of 8-bit port */
-		unsigned long ioaddr = subpriv->iobases[byte_no],
-		    /* bit offset of port in 32-bit doubleword */
-		    offset = byte_no * 8;
-		/* this 8-bit port's data */
-		unsigned char byte = 0,
-		    /* The write mask for this port (if any) */
-		    write_mask_byte = (data[0] >> offset) & 0xff,
-		    /* The data byte for this port */
-		    data_byte = (data[1] >> offset) & 0xff;
+	/* get inverted state of the channels from the port */
+	val = pcmuio_read(dev, asic, 0, port);
 
-		byte = inb(ioaddr);	/* read all 8-bits for this port */
+	/* get the true state of the channels */
+	s->state = val ^ ((0x1 << s->n_chan) - 1);
 
-#ifdef DAMMIT_ITS_BROKEN
-		/* DEBUG */
-		printk
-		    ("byte %d wmb %02x db %02x offset %02d io %04x, data_in %02x ",
-		     byte_no, (unsigned)write_mask_byte, (unsigned)data_byte,
-		     offset, ioaddr, (unsigned)byte);
-#endif
+	if (mask) {
+		s->state &= ~mask;
+		s->state |= (mask & bits);
 
-		if (write_mask_byte) {
-			/* this byte has some write_bits -- so set the output lines */
-			byte &= ~write_mask_byte;	/* clear bits for write mask */
-			byte |= ~data_byte & write_mask_byte;	/* set to inverted data_byte */
-			/* Write out the new digital output state */
-			outb(byte, ioaddr);
-		}
-#ifdef DAMMIT_ITS_BROKEN
-		/* DEBUG */
-		dev_dbg(dev->class_dev, "data_out_byte %02x\n", (unsigned)byte);
-#endif
-		/* save the digital input lines for this byte.. */
-		s->state |= ((unsigned int)byte) << offset;
+		/* invert the state and update the channels */
+		val = s->state ^ ((0x1 << s->n_chan) - 1);
+		pcmuio_write(dev, val, asic, 0, port);
 	}
 
-	/* now return the DIO lines to data[1] - note they came inverted! */
-	data[1] = ~s->state;
-
-#ifdef DAMMIT_ITS_BROKEN
-	/* DEBUG */
-	dev_dbg(dev->class_dev, "s->state %08x data_out %08x\n", s->state,
-		data[1]);
-#endif
+	data[1] = s->state;
 
 	return insn->n;
 }
 
-/* The input or output configuration of each digital line is
- * configured by a special insn_config instruction.  chanspec
- * contains the channel to be changed, and data[0] contains the
- * value COMEDI_INPUT or COMEDI_OUTPUT. */
 static int pcmuio_dio_insn_config(struct comedi_device *dev,
 				  struct comedi_subdevice *s,
 				  struct comedi_insn *insn, unsigned int *data)
 {
-	int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
-	    chan % 8;
-	unsigned long ioaddr;
-	unsigned char byte;
-
-	/* Compute ioaddr for this channel */
-	ioaddr = subpriv->iobases[byte_no];
-
-	/* NOTE:
-	   writing a 0 an IO channel's bit sets the channel to INPUT
-	   and pulls the line high as well
-
-	   writing a 1 to an IO channel's  bit pulls the line low
-
-	   All channels are implicitly always in OUTPUT mode -- but when
-	   they are high they can be considered to be in INPUT mode..
-
-	   Thus, we only force channels low if the config request was INPUT,
-	   otherwise we do nothing to the hardware.    */
+	unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
+	int asic = s->index / 2;
+	int port = (s->index % 2) ? 3 : 0;
 
 	switch (data[0]) {
 	case INSN_CONFIG_DIO_OUTPUT:
-		/* save to io_bits -- don't actually do anything since
-		   all input channels are also output channels... */
-		s->io_bits |= 1 << chan;
+		s->io_bits |= chan_mask;
 		break;
 	case INSN_CONFIG_DIO_INPUT:
-		/* write a 0 to the actual register representing the channel
-		   to set it to 'input'.  0 means "float high". */
-		byte = inb(ioaddr);
-		byte &= ~(1 << bit_no);
-				/**< set input channel to '0' */
-
-		/* write out byte -- this is the only time we actually affect the
-		   hardware as all channels are implicitly output -- but input
-		   channels are set to float-high */
-		outb(byte, ioaddr);
-
-		/* save to io_bits */
-		s->io_bits &= ~(1 << chan);
+		s->io_bits &= ~chan_mask;
+		pcmuio_write(dev, s->io_bits, asic, 0, port);
 		break;
-
 	case INSN_CONFIG_DIO_QUERY:
-		/* retrieve from shadow register */
-		data[1] =
-		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
-		return insn->n;
+		data[1] = (s->io_bits & chan_mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		break;
-
 	default:
 		return -EINVAL;
 		break;
@@ -339,100 +257,28 @@ static int pcmuio_dio_insn_config(struct
 	return insn->n;
 }
 
-static void switch_page(struct comedi_device *dev, int asic, int page)
+static void pcmuio_reset(struct comedi_device *dev)
 {
 	const struct pcmuio_board *board = comedi_board(dev);
-	struct pcmuio_private *devpriv = dev->private;
-
-	if (asic < 0 || asic >= board->num_asics)
-		return;		/* paranoia */
-	if (page < 0 || page >= NUM_PAGES)
-		return;		/* more paranoia */
-
-	devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK;
-	devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET;
-
-	/* now write out the shadow register */
-	outb(devpriv->asics[asic].pagelock,
-	     dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
-}
-
-static void init_asics(struct comedi_device *dev)
-{				/* sets up an
-				   ASIC chip to defaults */
-	const struct pcmuio_board *board = comedi_board(dev);
 	int asic;
 
 	for (asic = 0; asic < board->num_asics; ++asic) {
-		int port, page;
-		unsigned long baseaddr = dev->iobase + asic * ASIC_IOSIZE;
-
-		switch_page(dev, asic, 0);	/* switch back to page 0 */
-
 		/* first, clear all the DIO port bits */
-		for (port = 0; port < PORTS_PER_ASIC; ++port)
-			outb(0, baseaddr + REG_PORT0 + port);
+		pcmuio_write(dev, 0, asic, 0, 0);
+		pcmuio_write(dev, 0, asic, 0, 3);
 
 		/* Next, clear all the paged registers for each page */
-		for (page = 1; page < NUM_PAGES; ++page) {
-			int reg;
-			/* now clear all the paged registers */
-			switch_page(dev, asic, page);
-			for (reg = FIRST_PAGED_REG;
-			     reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
-				outb(0, baseaddr + reg);
-		}
-
-		/* DEBUG  set rising edge interrupts on port0 of both asics */
-		/*switch_page(dev, asic, PAGE_POL);
-		   outb(0xff, baseaddr + REG_POL0);
-		   switch_page(dev, asic, PAGE_ENAB);
-		   outb(0xff, baseaddr + REG_ENAB0); */
-		/* END DEBUG */
-
-		switch_page(dev, asic, 0);	/* switch back to default page 0 */
-
+		pcmuio_write(dev, 0, asic, PCMUIO_PAGE_POL, 0);
+		pcmuio_write(dev, 0, asic, PCMUIO_PAGE_ENAB, 0);
+		pcmuio_write(dev, 0, asic, PCMUIO_PAGE_INT_ID, 0);
 	}
 }
 
-#ifdef notused
-static void lock_port(struct comedi_device *dev, int asic, int port)
-{
-	const struct pcmuio_board *board = comedi_board(dev);
-	struct pcmuio_private *devpriv = dev->private;
-
-	if (asic < 0 || asic >= board->num_asics)
-		return;		/* paranoia */
-	if (port < 0 || port >= PORTS_PER_ASIC)
-		return;		/* more paranoia */
-
-	devpriv->asics[asic].pagelock |= 0x1 << port;
-	/* now write out the shadow register */
-	outb(devpriv->asics[asic].pagelock,
-	     dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
-}
-
-static void unlock_port(struct comedi_device *dev, int asic, int port)
-{
-	const struct pcmuio_board *board = comedi_board(dev);
-	struct pcmuio_private *devpriv = dev->private;
-
-	if (asic < 0 || asic >= board->num_asics)
-		return;		/* paranoia */
-	if (port < 0 || port >= PORTS_PER_ASIC)
-		return;		/* more paranoia */
-	devpriv->asics[asic].pagelock &= ~(0x1 << port) | REG_LOCK_MASK;
-	/* now write out the shadow register */
-	outb(devpriv->asics[asic].pagelock,
-	     dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
-}
-#endif /* notused */
-
 static void pcmuio_stop_intr(struct comedi_device *dev,
 			     struct comedi_subdevice *s)
 {
-	int nports, firstport, asic, port;
-	struct pcmuio_private *devpriv = dev->private;
+	struct pcmuio_subdev_private *subpriv = s->private;
+	int asic;
 
 	asic = subpriv->intr.asic;
 	if (asic < 0)
@@ -441,161 +287,124 @@ static void pcmuio_stop_intr(struct come
 	subpriv->intr.enabled_mask = 0;
 	subpriv->intr.active = 0;
 	s->async->inttrig = NULL;
-	nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT;
-	firstport = subpriv->intr.asic_chan / CHANS_PER_PORT;
-	switch_page(dev, asic, PAGE_ENAB);
-	for (port = firstport; port < firstport + nports; ++port) {
-		/* disable all intrs for this subdev.. */
-		outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port);
-	}
+
+	/* disable all intrs for this subdev.. */
+	pcmuio_write(dev, 0, asic, PCMUIO_PAGE_ENAB, 0);
 }
 
-static irqreturn_t interrupt_pcmuio(int irq, void *d)
+static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      unsigned triggered)
 {
-	int asic, got1 = 0;
-	struct comedi_device *dev = (struct comedi_device *)d;
-	struct pcmuio_private *devpriv = dev->private;
-	int i;
+	struct pcmuio_subdev_private *subpriv = s->private;
+	unsigned int len = s->async->cmd.chanlist_len;
+	unsigned oldevents = s->async->events;
+	unsigned int val = 0;
+	unsigned long flags;
+	unsigned mytrig;
+	unsigned int i;
 
-	for (asic = 0; asic < MAX_ASICS; ++asic) {
-		if (irq == devpriv->asics[asic].irq) {
-			unsigned long flags;
-			unsigned triggered = 0;
-			unsigned long iobase = devpriv->asics[asic].iobase;
-			/* it is an interrupt for ASIC #asic */
-			unsigned char int_pend;
+	spin_lock_irqsave(&subpriv->intr.spinlock, flags);
 
-			spin_lock_irqsave(&devpriv->asics[asic].spinlock,
-					  flags);
+	if (!subpriv->intr.active)
+		goto done;
 
-			int_pend = inb(iobase + REG_INT_PENDING) & 0x07;
+	mytrig = triggered;
+	mytrig &= ((0x1 << s->n_chan) - 1);
 
-			if (int_pend) {
-				int port;
-				for (port = 0; port < INTR_PORTS_PER_ASIC;
-				     ++port) {
-					if (int_pend & (0x1 << port)) {
-						unsigned char
-						    io_lines_with_edges = 0;
-						switch_page(dev, asic,
-							    PAGE_INT_ID);
-						io_lines_with_edges =
-						    inb(iobase +
-							REG_INT_ID0 + port);
+	if (!(mytrig & subpriv->intr.enabled_mask))
+		goto done;
 
-						if (io_lines_with_edges)
-							/* clear pending interrupt */
-							outb(0, iobase +
-							     REG_INT_ID0 +
-							     port);
+	for (i = 0; i < len; i++) {
+		unsigned int chan = CR_CHAN(s->async->cmd.chanlist[i]);
+		if (mytrig & (1U << chan))
+			val |= (1U << i);
+	}
 
-						triggered |=
-						    io_lines_with_edges <<
-						    port * 8;
-					}
-				}
+	/* Write the scan to the buffer. */
+	if (comedi_buf_put(s->async, ((short *)&val)[0]) &&
+	    comedi_buf_put(s->async, ((short *)&val)[1])) {
+		s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+	} else {
+		/* Overflow! Stop acquisition!! */
+		/* TODO: STOP_ACQUISITION_CALL_HERE!! */
+		pcmuio_stop_intr(dev, s);
+	}
 
-				++got1;
+	/* Check for end of acquisition. */
+	if (!subpriv->intr.continuous) {
+		/* stop_src == TRIG_COUNT */
+		if (subpriv->intr.stop_count > 0) {
+			subpriv->intr.stop_count--;
+			if (subpriv->intr.stop_count == 0) {
+				s->async->events |= COMEDI_CB_EOA;
+				/* TODO: STOP_ACQUISITION_CALL_HERE!! */
+				pcmuio_stop_intr(dev, s);
 			}
+		}
+	}
 
-			spin_unlock_irqrestore(&devpriv->asics[asic].spinlock,
-					       flags);
-
-			if (triggered) {
-				struct comedi_subdevice *s;
-				/* TODO here: dispatch io lines to subdevs with commands.. */
-				printk
-				    ("PCMUIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n",
-				     irq, asic, triggered);
-				for (i = 0; i < dev->n_subdevices; i++) {
-					s = &dev->subdevices[i];
-					if (subpriv->intr.asic == asic) {	/* this is an interrupt subdev, and it matches this asic! */
-						unsigned long flags;
-						unsigned oldevents;
-
-						spin_lock_irqsave(&subpriv->
-								  intr.spinlock,
-								  flags);
-
-						oldevents = s->async->events;
+done:
+	spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
 
-						if (subpriv->intr.active) {
-							unsigned mytrig =
-							    ((triggered >>
-							      subpriv->intr.asic_chan)
-							     &
-							     ((0x1 << subpriv->
-							       intr.
-							       num_asic_chans) -
-							      1)) << subpriv->
-							    intr.first_chan;
-							if (mytrig &
-							    subpriv->intr.enabled_mask)
-							{
-								unsigned int val
-								    = 0;
-								unsigned int n,
-								    ch, len;
+	if (oldevents != s->async->events)
+		comedi_event(dev, s);
+}
 
-								len =
-								    s->
-								    async->cmd.chanlist_len;
-								for (n = 0;
-								     n < len;
-								     n++) {
-									ch = CR_CHAN(s->async->cmd.chanlist[n]);
-									if (mytrig & (1U << ch)) {
-										val |= (1U << n);
-									}
-								}
-								/* Write the scan to the buffer. */
-								if (comedi_buf_put(s->async, ((short *)&val)[0])
-								    &&
-								    comedi_buf_put
-								    (s->async,
-								     ((short *)
-								      &val)[1]))
-								{
-									s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
-								} else {
-									/* Overflow! Stop acquisition!! */
-									/* TODO: STOP_ACQUISITION_CALL_HERE!! */
-									pcmuio_stop_intr
-									    (dev,
-									     s);
-								}
+static int pcmuio_handle_asic_interrupt(struct comedi_device *dev, int asic)
+{
+	struct pcmuio_private *devpriv = dev->private;
+	struct pcmuio_subdev_private *subpriv;
+	unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE);
+	unsigned int triggered = 0;
+	int got1 = 0;
+	unsigned long flags;
+	unsigned char int_pend;
+	int i;
 
-								/* Check for end of acquisition. */
-								if (!subpriv->intr.continuous) {
-									/* stop_src == TRIG_COUNT */
-									if (subpriv->intr.stop_count > 0) {
-										subpriv->intr.stop_count--;
-										if (subpriv->intr.stop_count == 0) {
-											s->async->events |= COMEDI_CB_EOA;
-											/* TODO: STOP_ACQUISITION_CALL_HERE!! */
-											pcmuio_stop_intr
-											    (dev,
-											     s);
-										}
-									}
-								}
-							}
-						}
+	spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags);
 
-						spin_unlock_irqrestore
-						    (&subpriv->intr.spinlock,
-						     flags);
+	int_pend = inb(iobase + PCMUIO_INT_PENDING_REG) & 0x07;
+	if (int_pend) {
+		triggered = pcmuio_read(dev, asic, PCMUIO_PAGE_INT_ID, 0);
+		pcmuio_write(dev, 0, asic, PCMUIO_PAGE_INT_ID, 0);
 
-						if (oldevents !=
-						    s->async->events) {
-							comedi_event(dev, s);
-						}
+		++got1;
+	}
 
-					}
+	spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags);
 
-				}
+	if (triggered) {
+		struct comedi_subdevice *s;
+		/* TODO here: dispatch io lines to subdevs with commands.. */
+		for (i = 0; i < dev->n_subdevices; i++) {
+			s = &dev->subdevices[i];
+			subpriv = s->private;
+			if (subpriv->intr.asic == asic) {
+				/*
+				 * This is an interrupt subdev, and it
+				 * matches this asic!
+				 */
+				pcmuio_handle_intr_subdev(dev, s,
+							  triggered);
 			}
+		}
+	}
+	return got1;
+}
 
+static irqreturn_t pcmuio_interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct pcmuio_private *devpriv = dev->private;
+	int got1 = 0;
+	int asic;
+
+	for (asic = 0; asic < PCMUIO_MAX_ASICS; ++asic) {
+		if (irq == devpriv->asics[asic].irq) {
+			/* it is an interrupt for ASIC #asic */
+			if (pcmuio_handle_asic_interrupt(dev, asic))
+				got1++;
 		}
 	}
 	if (!got1)
@@ -606,7 +415,7 @@ static irqreturn_t interrupt_pcmuio(int
 static int pcmuio_start_intr(struct comedi_device *dev,
 			     struct comedi_subdevice *s)
 {
-	struct pcmuio_private *devpriv = dev->private;
+	struct pcmuio_subdev_private *subpriv = s->private;
 
 	if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) {
 		/* An empty acquisition! */
@@ -615,7 +424,7 @@ static int pcmuio_start_intr(struct come
 		return 1;
 	} else {
 		unsigned bits = 0, pol_bits = 0, n;
-		int nports, firstport, asic, port;
+		int asic;
 		struct comedi_cmd *cmd = &s->async->cmd;
 
 		asic = subpriv->intr.asic;
@@ -624,8 +433,6 @@ static int pcmuio_start_intr(struct come
 					   subdev */
 		subpriv->intr.enabled_mask = 0;
 		subpriv->intr.active = 1;
-		nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT;
-		firstport = subpriv->intr.asic_chan / CHANS_PER_PORT;
 		if (cmd->chanlist) {
 			for (n = 0; n < cmd->chanlist_len; n++) {
 				bits |= (1U << CR_CHAN(cmd->chanlist[n]));
@@ -635,31 +442,19 @@ static int pcmuio_start_intr(struct come
 				    << CR_CHAN(cmd->chanlist[n]);
 			}
 		}
-		bits &= ((0x1 << subpriv->intr.num_asic_chans) -
-			 1) << subpriv->intr.first_chan;
+		bits &= ((0x1 << s->n_chan) - 1);
 		subpriv->intr.enabled_mask = bits;
 
-		switch_page(dev, asic, PAGE_ENAB);
-		for (port = firstport; port < firstport + nports; ++port) {
-			unsigned enab =
-			    bits >> (subpriv->intr.first_chan + (port -
-								 firstport) *
-				     8) & 0xff, pol =
-			    pol_bits >> (subpriv->intr.first_chan +
-					 (port - firstport) * 8) & 0xff;
-			/* set enab intrs for this subdev.. */
-			outb(enab,
-			     devpriv->asics[asic].iobase + REG_ENAB0 + port);
-			switch_page(dev, asic, PAGE_POL);
-			outb(pol,
-			     devpriv->asics[asic].iobase + REG_ENAB0 + port);
-		}
+		/* set pol and enab intrs for this subdev.. */
+		pcmuio_write(dev, pol_bits, asic, PCMUIO_PAGE_POL, 0);
+		pcmuio_write(dev, bits, asic, PCMUIO_PAGE_ENAB, 0);
 	}
 	return 0;
 }
 
 static int pcmuio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
+	struct pcmuio_subdev_private *subpriv = s->private;
 	unsigned long flags;
 
 	spin_lock_irqsave(&subpriv->intr.spinlock, flags);
@@ -677,6 +472,7 @@ static int
 pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
 			  unsigned int trignum)
 {
+	struct pcmuio_subdev_private *subpriv = s->private;
 	unsigned long flags;
 	int event = 0;
 
@@ -701,6 +497,7 @@ pcmuio_inttrig_start_intr(struct comedi_
  */
 static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
+	struct pcmuio_subdev_private *subpriv = s->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned long flags;
 	int event = 0;
@@ -797,17 +594,18 @@ static int pcmuio_cmdtest(struct comedi_
 static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	const struct pcmuio_board *board = comedi_board(dev);
-	struct pcmuio_private *devpriv;
 	struct comedi_subdevice *s;
-	int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0;
-	unsigned int irq[MAX_ASICS];
+	struct pcmuio_private *devpriv;
+	struct pcmuio_subdev_private *subpriv;
+	int sdev_no, n_subdevs, asic;
+	unsigned int irq[PCMUIO_MAX_ASICS];
 	int ret;
 
 	irq[0] = it->options[1];
 	irq[1] = it->options[2];
 
 	ret = comedi_request_region(dev, it->options[0],
-				    board->num_asics * ASIC_IOSIZE);
+				    board->num_asics * PCMUIO_ASIC_IOSIZE);
 	if (ret)
 		return ret;
 
@@ -816,20 +614,11 @@ static int pcmuio_attach(struct comedi_d
 		return -ENOMEM;
 	dev->private = devpriv;
 
-	for (asic = 0; asic < MAX_ASICS; ++asic) {
-		devpriv->asics[asic].num = asic;
-		devpriv->asics[asic].iobase = dev->iobase + asic * ASIC_IOSIZE;
-		devpriv->asics[asic].irq = 0;	/* this gets actually set at the end of
-						   this function when we
-						   request_irqs */
+	for (asic = 0; asic < PCMUIO_MAX_ASICS; ++asic)
 		spin_lock_init(&devpriv->asics[asic].spinlock);
-	}
 
-	chans_left = CHANS_PER_ASIC * board->num_asics;
-	n_subdevs = CALC_N_SUBDEVS(chans_left);
-	devpriv->sprivs = kcalloc(n_subdevs,
-				  sizeof(struct pcmuio_subdev_private),
-				  GFP_KERNEL);
+	n_subdevs = board->num_asics * 2;
+	devpriv->sprivs = kcalloc(n_subdevs, sizeof(*subpriv), GFP_KERNEL);
 	if (!devpriv->sprivs)
 		return -ENOMEM;
 
@@ -837,74 +626,40 @@ static int pcmuio_attach(struct comedi_d
 	if (ret)
 		return ret;
 
-	port = 0;
-	asic = 0;
 	for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) {
-		int byte_no;
-
 		s = &dev->subdevices[sdev_no];
-		s->private = &devpriv->sprivs[sdev_no];
+		subpriv = &devpriv->sprivs[sdev_no];
+		s->private = subpriv;
 		s->maxdata = 1;
 		s->range_table = &range_digital;
 		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
 		s->type = COMEDI_SUBD_DIO;
 		s->insn_bits = pcmuio_dio_insn_bits;
 		s->insn_config = pcmuio_dio_insn_config;
-		s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV);
-		subpriv->intr.asic = -1;
-		subpriv->intr.first_chan = -1;
-		subpriv->intr.asic_chan = -1;
-		subpriv->intr.num_asic_chans = -1;
-		subpriv->intr.active = 0;
-		s->len_chanlist = 1;
-
-		/* save the ioport address for each 'port' of 8 channels in the
-		   subdevice */
-		for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) {
-			if (port >= PORTS_PER_ASIC) {
-				port = 0;
-				++asic;
-				thisasic_chanct = 0;
-			}
-			subpriv->iobases[byte_no] =
-			    devpriv->asics[asic].iobase + port;
+		s->n_chan = 24;
 
-			if (thisasic_chanct <
-			    CHANS_PER_PORT * INTR_PORTS_PER_ASIC
-			    && subpriv->intr.asic < 0) {
-				/* this is an interrupt subdevice, so setup the struct */
-				subpriv->intr.asic = asic;
-				subpriv->intr.active = 0;
-				subpriv->intr.stop_count = 0;
-				subpriv->intr.first_chan = byte_no * 8;
-				subpriv->intr.asic_chan = thisasic_chanct;
-				subpriv->intr.num_asic_chans =
-				    s->n_chan - subpriv->intr.first_chan;
-				dev->read_subdev = s;
-				s->subdev_flags |= SDF_CMD_READ;
-				s->cancel = pcmuio_cancel;
-				s->do_cmd = pcmuio_cmd;
-				s->do_cmdtest = pcmuio_cmdtest;
-				s->len_chanlist = subpriv->intr.num_asic_chans;
-			}
-			thisasic_chanct += CHANS_PER_PORT;
+		/* subdevices 0 and 2 suppport interrupts */
+		if ((sdev_no % 2) == 0) {
+			/* setup the interrupt subdevice */
+			subpriv->intr.asic = sdev_no / 2;
+			dev->read_subdev = s;
+			s->subdev_flags |= SDF_CMD_READ;
+			s->cancel = pcmuio_cancel;
+			s->do_cmd = pcmuio_cmd;
+			s->do_cmdtest = pcmuio_cmdtest;
+			s->len_chanlist = s->n_chan;
+		} else {
+			subpriv->intr.asic = -1;
+			s->len_chanlist = 1;
 		}
 		spin_lock_init(&subpriv->intr.spinlock);
-
-		chans_left -= s->n_chan;
-
-		if (!chans_left) {
-			asic = 0;	/* reset the asic to our first asic, to do intr subdevs */
-			port = 0;
-		}
-
 	}
 
-	init_asics(dev);	/* clear out all the registers, basically */
+	pcmuio_reset(dev);
 
-	for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
+	for (asic = 0; irq[0] && asic < PCMUIO_MAX_ASICS; ++asic) {
 		if (irq[asic]
-		    && request_irq(irq[asic], interrupt_pcmuio,
+		    && request_irq(irq[asic], pcmuio_interrupt,
 				   IRQF_SHARED, board->name, dev)) {
 			int i;
 			/* unroll the allocated irqs.. */
@@ -917,17 +672,7 @@ static int pcmuio_attach(struct comedi_d
 		devpriv->asics[asic].irq = irq[asic];
 	}
 
-	if (irq[0]) {
-		dev_dbg(dev->class_dev, "irq: %u\n", irq[0]);
-		if (irq[1] && board->num_asics == 2)
-			dev_dbg(dev->class_dev, "second ASIC irq: %u\n",
-				irq[1]);
-	} else {
-		dev_dbg(dev->class_dev, "(IRQ mode disabled)\n");
-	}
-
-
-	return 1;
+	return 0;
 }
 
 static void pcmuio_detach(struct comedi_device *dev)
@@ -935,7 +680,7 @@ static void pcmuio_detach(struct comedi_
 	struct pcmuio_private *devpriv = dev->private;
 	int i;
 
-	for (i = 0; i < MAX_ASICS; ++i) {
+	for (i = 0; i < PCMUIO_MAX_ASICS; ++i) {
 		if (devpriv->asics[i].irq)
 			free_irq(devpriv->asics[i].irq, dev);
 	}
@@ -944,18 +689,6 @@ static void pcmuio_detach(struct comedi_
 	comedi_legacy_detach(dev);
 }
 
-static const struct pcmuio_board pcmuio_boards[] = {
-	{
-		.name		= "pcmuio48",
-		.num_asics	= 1,
-		.num_ports	= 6,
-	}, {
-		.name		= "pcmuio96",
-		.num_asics	= 2,
-		.num_ports	= 12,
-	},
-};
-
 static struct comedi_driver pcmuio_driver = {
 	.driver_name	= "pcmuio",
 	.module		= THIS_MODULE,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/plx9052.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/plx9052.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/plx9052.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/plx9052.h	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #ifndef _PLX9052_H_
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/poc.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/poc.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/poc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/poc.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,25 +13,18 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 /*
 Driver: poc
 Description: Generic driver for very simple devices
 Author: ds
-Devices: [Keithley Metrabyte] DAC-02 (dac02), [Advantech] PCL-733 (pcl733),
-  PCL-734 (pcl734)
+Devices: [Keithley Metrabyte] DAC-02 (dac02)
 Updated: Sat, 16 Mar 2002 17:34:48 -0800
 Status: unknown
 
 This driver is indended to support very simple ISA-based devices,
 including:
   dac02 - Keithley DAC-02 analog output board
-  pcl733 - Advantech PCL-733
-  pcl734 - Advantech PCL-734
 
 Configuration options:
   [0] - I/O port base
@@ -101,39 +94,6 @@ static int dac02_ao_winsn(struct comedi_
 	return 1;
 }
 
-static int pcl733_insn_bits(struct comedi_device *dev,
-			    struct comedi_subdevice *s,
-			    struct comedi_insn *insn, unsigned int *data)
-{
-	data[1] = inb(dev->iobase + 0);
-	data[1] |= (inb(dev->iobase + 1) << 8);
-	data[1] |= (inb(dev->iobase + 2) << 16);
-	data[1] |= (inb(dev->iobase + 3) << 24);
-
-	return insn->n;
-}
-
-static int pcl734_insn_bits(struct comedi_device *dev,
-			    struct comedi_subdevice *s,
-			    struct comedi_insn *insn, unsigned int *data)
-{
-	if (data[0]) {
-		s->state &= ~data[0];
-		s->state |= (data[0] & data[1]);
-		if ((data[0] >> 0) & 0xff)
-			outb((s->state >> 0) & 0xff, dev->iobase + 0);
-		if ((data[0] >> 8) & 0xff)
-			outb((s->state >> 8) & 0xff, dev->iobase + 1);
-		if ((data[0] >> 16) & 0xff)
-			outb((s->state >> 16) & 0xff, dev->iobase + 2);
-		if ((data[0] >> 24) & 0xff)
-			outb((s->state >> 24) & 0xff, dev->iobase + 3);
-	}
-	data[1] = s->state;
-
-	return insn->n;
-}
-
 static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	const struct boarddef_struct *board = comedi_board(dev);
@@ -180,22 +140,6 @@ static const struct boarddef_struct boar
 		.winsn		= dac02_ao_winsn,
 		.rinsn		= readback_insn,
 		.range		= &range_unknown,
-	}, {
-		.name		= "pcl733",
-		.iosize		= 4,
-		.type		= COMEDI_SUBD_DI,
-		.n_chan		= 32,
-		.n_bits		= 1,
-		.insnbits	= pcl733_insn_bits,
-		.range		= &range_digital,
-	}, {
-		.name		= "pcl734",
-		.iosize		= 4,
-		.type		= COMEDI_SUBD_DO,
-		.n_chan		= 32,
-		.n_bits		= 1,
-		.insnbits	= pcl734_insn_bits,
-		.range		= &range_digital,
 	},
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/rtd520.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/rtd520.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/rtd520.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/rtd520.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/rti800.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/rti800.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/rti800.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/rti800.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,10 +14,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/rti802.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/rti802.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/rti802.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/rti802.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: rti802
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/s526.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/s526.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/s526.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/s526.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: s526
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/s626.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/s626.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/s626.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/s626.c	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,6 @@
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/s626.h linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/s626.h
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/s626.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/s626.h	2013-08-25 20:43:22.000000000 -0400
@@ -17,11 +17,6 @@
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/serial2002.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/serial2002.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/serial2002.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/serial2002.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/skel.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/skel.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/skel.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/skel.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: skel
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ssv_dnp.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ssv_dnp.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/ssv_dnp.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/ssv_dnp.c	2013-08-25 20:43:22.000000000 -0400
@@ -15,11 +15,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: ssv_dnp
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/unioxx5.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/unioxx5.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/unioxx5.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/unioxx5.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,10 +18,6 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
  *  GNU General Public License for more details.                           *
  *                                                                         *
- *  You should have received a copy of the GNU General Public License      *
- *  along with this program; if not, write to the Free Software            *
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              *
- *                                                                         *
  ***************************************************************************/
 /*
 
@@ -375,15 +371,13 @@ static int __unioxx5_subdev_init(struct
 	int i, to, ndef_flag = 0;
 	int ret;
 
-	usp = kzalloc(sizeof(*usp), GFP_KERNEL);
-	if (usp == NULL)
+	usp = comedi_alloc_spriv(s, sizeof(*usp));
+	if (!usp)
 		return -ENOMEM;
 
 	ret = __comedi_request_region(dev, iobase, UNIOXX5_SIZE);
-	if (ret) {
-		kfree(usp);
+	if (ret)
 		return ret;
-	}
 	usp->usp_iobase = iobase;
 
 	/* defining modules types */
@@ -417,7 +411,6 @@ static int __unioxx5_subdev_init(struct
 
 	/* initial subdevice for digital or analog i/o */
 	s->type = COMEDI_SUBD_DIO;
-	s->private = usp;
 	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
 	s->n_chan = UNIOXX5_NUM_OF_CHANS;
 	s->maxdata = 0xFFF;
@@ -478,15 +471,15 @@ static int unioxx5_attach(struct comedi_
 
 static void unioxx5_detach(struct comedi_device *dev)
 {
+	struct comedi_subdevice *s;
+	struct unioxx5_subd_priv *spriv;
 	int i;
-	struct comedi_subdevice *subdev;
-	struct unioxx5_subd_priv *usp;
 
 	for (i = 0; i < dev->n_subdevices; i++) {
-		subdev = &dev->subdevices[i];
-		usp = subdev->private;
-		release_region(usp->usp_iobase, UNIOXX5_SIZE);
-		kfree(subdev->private);
+		s = &dev->subdevices[i];
+		spriv = s->private;
+		if (spriv && spriv->usp_iobase)
+			release_region(spriv->usp_iobase, UNIOXX5_SIZE);
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/usbdux.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/usbdux.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/usbdux.c	2013-07-01 10:42:12.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/usbdux.c	2013-08-31 18:01:59.000000000 -0400
@@ -11,11 +11,6 @@
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
  */
 /*
 Driver: usbdux
@@ -94,7 +89,6 @@ sampling rate. If you sample two channel
 #include <linux/usb.h>
 #include <linux/fcntl.h>
 #include <linux/compiler.h>
-#include <linux/firmware.h>
 
 #include "../comedidev.h"
 
@@ -727,154 +721,82 @@ static void usbduxsub_ao_isoc_irq(struct
 	}
 }
 
-static int usbduxsub_start(struct usbduxsub *usbduxsub)
-{
-	int errcode = 0;
-	uint8_t *local_transfer_buffer;
-
-	local_transfer_buffer = kmalloc(1, GFP_KERNEL);
-	if (!local_transfer_buffer)
-		return -ENOMEM;
-
-	/* 7f92 to zero */
-	*local_transfer_buffer = 0;
-	errcode = usb_control_msg(usbduxsub->usbdev,
-				  /* create a pipe for a control transfer */
-				  usb_sndctrlpipe(usbduxsub->usbdev, 0),
-				  /* bRequest, "Firmware" */
-				  USBDUXSUB_FIRMWARE,
-				  /* bmRequestType */
-				  VENDOR_DIR_OUT,
-				  /* Value */
-				  USBDUXSUB_CPUCS,
-				  /* Index */
-				  0x0000,
-				  /* address of the transfer buffer */
-				  local_transfer_buffer,
-				  /* Length */
-				  1,
-				  /* Timeout */
-				  BULK_TIMEOUT);
-	if (errcode < 0)
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: control msg failed (start)\n");
-
-	kfree(local_transfer_buffer);
-	return errcode;
-}
-
-static int usbduxsub_stop(struct usbduxsub *usbduxsub)
-{
-	int errcode = 0;
-	uint8_t *local_transfer_buffer;
-
-	local_transfer_buffer = kmalloc(1, GFP_KERNEL);
-	if (!local_transfer_buffer)
-		return -ENOMEM;
-
-	/* 7f92 to one */
-	*local_transfer_buffer = 1;
-	errcode = usb_control_msg(usbduxsub->usbdev,
-				  usb_sndctrlpipe(usbduxsub->usbdev, 0),
-				  /* bRequest, "Firmware" */
-				  USBDUXSUB_FIRMWARE,
-				  /* bmRequestType */
-				  VENDOR_DIR_OUT,
-				  /* Value */
-				  USBDUXSUB_CPUCS,
-				  /* Index */
-				  0x0000, local_transfer_buffer,
-				  /* Length */
-				  1,
-				  /* Timeout */
-				  BULK_TIMEOUT);
-	if (errcode < 0)
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: control msg failed (stop)\n");
-
-	kfree(local_transfer_buffer);
-	return errcode;
-}
-
-static int usbduxsub_upload(struct usbduxsub *usbduxsub,
-			    uint8_t *local_transfer_buffer,
-			    unsigned int start_addr, unsigned int len)
-{
-	int errcode;
-
-	errcode = usb_control_msg(usbduxsub->usbdev,
-				  usb_sndctrlpipe(usbduxsub->usbdev, 0),
-				  /* brequest, firmware */
-				  USBDUXSUB_FIRMWARE,
-				  /* bmRequestType */
-				  VENDOR_DIR_OUT,
-				  /* value */
-				  start_addr,
-				  /* index */
-				  0x0000,
-				  /* our local safe buffer */
-				  local_transfer_buffer,
-				  /* length */
-				  len,
-				  /* timeout */
-				  BULK_TIMEOUT);
-	dev_dbg(&usbduxsub->interface->dev, "comedi_: result=%d\n", errcode);
-	if (errcode < 0) {
-		dev_err(&usbduxsub->interface->dev, "comedi_: upload failed\n");
-		return errcode;
-	}
-	return 0;
-}
-
 #define FIRMWARE_MAX_LEN 0x2000
 
-static int firmware_upload(struct usbduxsub *usbduxsub,
-			  const u8 *firmware_binary, int size_firmware)
+static int usbdux_firmware_upload(struct comedi_device *dev,
+				  const u8 *data, size_t size,
+				  unsigned long context)
 {
+	struct usbduxsub *usbduxsub = dev->private;
+	struct usb_device *usb = usbduxsub->usbdev;
+	uint8_t *buf;
+	uint8_t *tmp;
 	int ret;
-	uint8_t *fw_buf;
 
-	if (!firmware_binary)
+	if (!data)
 		return 0;
 
-	if (size_firmware > FIRMWARE_MAX_LEN) {
+	if (size > FIRMWARE_MAX_LEN) {
 		dev_err(&usbduxsub->interface->dev,
 			"usbdux firmware binary it too large for FX2.\n");
 		return -ENOMEM;
 	}
 
 	/* we generate a local buffer for the firmware */
-	fw_buf = kmemdup(firmware_binary, size_firmware, GFP_KERNEL);
-	if (!fw_buf) {
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: mem alloc for firmware failed\n");
+	buf = kmemdup(data, size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	/* we need a malloc'ed buffer for usb_control_msg() */
+	tmp = kmalloc(1, GFP_KERNEL);
+	if (!tmp) {
+		kfree(buf);
 		return -ENOMEM;
 	}
 
-	ret = usbduxsub_stop(usbduxsub);
+	/* stop the current firmware on the device */
+	*tmp = 1;	/* 7f92 to one */
+	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
+			      USBDUXSUB_FIRMWARE,
+			      VENDOR_DIR_OUT,
+			      USBDUXSUB_CPUCS, 0x0000,
+			      tmp, 1,
+			      BULK_TIMEOUT);
 	if (ret < 0) {
 		dev_err(&usbduxsub->interface->dev,
 			"comedi_: can not stop firmware\n");
-		kfree(fw_buf);
-		return ret;
+		goto done;
 	}
 
-	ret = usbduxsub_upload(usbduxsub, fw_buf, 0, size_firmware);
+	/* upload the new firmware to the device */
+	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
+			      USBDUXSUB_FIRMWARE,
+			      VENDOR_DIR_OUT,
+			      0, 0x0000,
+			      buf, size,
+			      BULK_TIMEOUT);
 	if (ret < 0) {
 		dev_err(&usbduxsub->interface->dev,
 			"comedi_: firmware upload failed\n");
-		kfree(fw_buf);
-		return ret;
+		goto done;
 	}
-	ret = usbduxsub_start(usbduxsub);
-	if (ret < 0) {
+
+	/* start the new firmware on the device */
+	*tmp = 0;	/* 7f92 to zero */
+	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
+			      USBDUXSUB_FIRMWARE,
+			      VENDOR_DIR_OUT,
+			      USBDUXSUB_CPUCS, 0x0000,
+			      tmp, 1,
+			      BULK_TIMEOUT);
+	if (ret < 0)
 		dev_err(&usbduxsub->interface->dev,
 			"comedi_: can not start firmware\n");
-		kfree(fw_buf);
-		return ret;
-	}
-	kfree(fw_buf);
-	return 0;
+
+done:
+	kfree(tmp);
+	kfree(buf);
+	return ret;
 }
 
 static int usbduxsub_submit_inurbs(struct usbduxsub *usbduxsub)
@@ -2328,13 +2250,21 @@ static int usbdux_auto_attach(struct com
 			      unsigned long context_unused)
 {
 	struct usb_interface *uinterf = comedi_to_usb_interface(dev);
+	struct usbduxsub *this_usbduxsub = usb_get_intfdata(uinterf);
+	struct usb_device *usb = usbduxsub->usbdev;
 	int ret;
-	struct usbduxsub *this_usbduxsub;
+
+	dev->private = this_usbduxsub;	/* This is temporary... */
+	ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
+				   usbdux_firmware_upload, 0);
+	if (ret < 0) {
+		dev->private = NULL;
+		return ret;
+	}
 
 	dev->private = NULL;
 
 	down(&start_stop_sem);
-	this_usbduxsub = usb_get_intfdata(uinterf);
 	if (!this_usbduxsub || !this_usbduxsub->probed) {
 		dev_err(dev->class_dev,
 			"usbdux: error: auto_attach failed, not connected\n");
@@ -2369,35 +2299,6 @@ static struct comedi_driver usbdux_drive
 	.detach		= usbdux_detach,
 };
 
-static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
-						     void *context)
-{
-	struct usbduxsub *usbduxsub_tmp = context;
-	struct usb_interface *uinterf = usbduxsub_tmp->interface;
-	int ret;
-
-	if (fw == NULL) {
-		dev_err(&uinterf->dev,
-			"Firmware complete handler without firmware!\n");
-		return;
-	}
-
-	/*
-	 * we need to upload the firmware here because fw will be
-	 * freed once we've left this function
-	 */
-	ret = firmware_upload(usbduxsub_tmp, fw->data, fw->size);
-
-	if (ret) {
-		dev_err(&uinterf->dev,
-			"Could not upload firmware (err=%d)\n", ret);
-		goto out;
-	}
-	comedi_usb_auto_config(uinterf, &usbdux_driver, 0);
- out:
-	release_firmware(fw);
-}
-
 static int usbdux_usb_probe(struct usb_interface *uinterf,
 			    const struct usb_device_id *id)
 {
@@ -2405,7 +2306,6 @@ static int usbdux_usb_probe(struct usb_i
 	struct device *dev = &uinterf->dev;
 	int i;
 	int index;
-	int ret;
 
 	dev_dbg(dev, "comedi_: usbdux_: "
 		"finding a free structure for the usb-device\n");
@@ -2622,23 +2522,7 @@ static int usbdux_usb_probe(struct usb_i
 	usbduxsub[index].probed = 1;
 	up(&start_stop_sem);
 
-	ret = reject_firmware_nowait(THIS_MODULE,
-				      FW_ACTION_HOTPLUG,
-				      FIRMWARE,
-				      &udev->dev,
-				      GFP_KERNEL,
-				      usbduxsub + index,
-				      usbdux_firmware_request_complete_handler);
-
-	if (ret) {
-		dev_err(dev, "Could not load firmware (err=%d)\n", ret);
-		return ret;
-	}
-
-	dev_info(dev, "comedi_: usbdux%d "
-		 "has been successfully initialised.\n", index);
-	/* success */
-	return 0;
+	return comedi_usb_auto_config(uinterf, &usbdux_driver, 0);
 }
 
 static void usbdux_usb_disconnect(struct usb_interface *intf)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/usbduxfast.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/usbduxfast.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/usbduxfast.c	2013-07-01 10:42:14.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/usbduxfast.c	2013-08-31 18:02:02.000000000 -0400
@@ -10,10 +10,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 /*
@@ -40,7 +36,6 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
-#include <linux/firmware.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -60,6 +55,7 @@
  * constants for "firmware" upload and download
  */
 #define FIRMWARE		"/*(DEBLOBBED)*/"
+#define FIRMWARE_MAX_LEN	0x2000
 #define USBDUXFASTSUB_FIRMWARE	0xA0
 #define VENDOR_DIR_IN		0xC0
 #define VENDOR_DIR_OUT		0x40
@@ -112,7 +108,7 @@
 /*
  * size of the buffer for the dux commands in bytes
  */
-#define SIZEOFDUXBUFFER	256
+#define SIZEOFDUXBUF	256
 
 /*
  * number of in-URBs which receive the data: min=5
@@ -120,16 +116,6 @@
 #define NUMOFINBUFFERSHIGH	10
 
 /*
- * total number of usbduxfast devices
- */
-#define NUMUSBDUXFAST	16
-
-/*
- * analogue in subdevice
- */
-#define SUBDEV_AD	0
-
-/*
  * min delay steps for more than one channel
  * basically when the mux gives up ;-)
  *
@@ -161,143 +147,83 @@ static const struct comedi_lrange range_
  * this is the structure which holds all the data of this driver
  * one sub device just now: A/D
  */
-struct usbduxfastsub_s {
-	int attached;		/* is attached? */
-	int probed;		/* is it associated with a subdevice? */
-	struct usb_device *usbdev;	/* pointer to the usb-device */
-	struct urb *urbIn;	/* BULK-transfer handling: urb */
-	int8_t *transfer_buffer;
-	int16_t *insnBuffer;	/* input buffer for single insn */
-	int ifnum;		/* interface number */
-	struct usb_interface *interface;	/* interface structure */
-	/* comedi device for the interrupt context */
-	struct comedi_device *comedidev;
+struct usbduxfast_private {
+	struct urb *urb;	/* BULK-transfer handling: urb */
+	uint8_t *duxbuf;
+	int8_t *inbuf;
 	short int ai_cmd_running;	/* asynchronous command is running */
 	short int ai_continous;	/* continous acquisition */
 	long int ai_sample_count;	/* number of samples to acquire */
-	uint8_t *dux_commands;	/* commands */
 	int ignore;		/* counter which ignores the first
 				   buffers */
 	struct semaphore sem;
 };
 
 /*
- * The pointer to the private usb-data of the driver
- * is also the private data for the comedi-device.
- * This has to be global as the usb subsystem needs
- * global variables. The other reason is that this
- * structure must be there _before_ any comedi
- * command is issued. The usb subsystem must be
- * initialised before comedi can access it.
- */
-static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST];
-
-static DEFINE_SEMAPHORE(start_stop_sem);
-
-/*
  * bulk transfers to usbduxfast
  */
 #define SENDADCOMMANDS            0
 #define SENDINITEP6               1
 
-static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type)
+static int usbduxfast_send_cmd(struct comedi_device *dev, int cmd_type)
 {
-	int tmp, nsent;
-
-	udfs->dux_commands[0] = cmd_type;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxfast_private *devpriv = dev->private;
+	int nsent;
+	int ret;
 
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi%d: usbduxfast: dux_commands: ",
-	       udfs->comedidev->minor);
-	for (tmp = 0; tmp < SIZEOFDUXBUFFER; tmp++)
-		printk(" %02x", udfs->dux_commands[tmp]);
-	printk("\n");
-#endif
+	devpriv->duxbuf[0] = cmd_type;
 
-	tmp = usb_bulk_msg(udfs->usbdev,
-			   usb_sndbulkpipe(udfs->usbdev, CHANNELLISTEP),
-			   udfs->dux_commands, SIZEOFDUXBUFFER, &nsent, 10000);
-	if (tmp < 0)
-		dev_err(&udfs->interface->dev,
-			"could not transmit dux_commands to the usb-device, err=%d\n",
-			tmp);
-	return tmp;
+	ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, CHANNELLISTEP),
+			   devpriv->duxbuf, SIZEOFDUXBUF,
+			   &nsent, 10000);
+	if (ret < 0)
+		dev_err(dev->class_dev,
+			"could not transmit command to the usb-device, err=%d\n",
+			ret);
+	return ret;
 }
 
-/*
- * Stops the data acquision.
- * It should be safe to call this function from any context.
- */
-static int usbduxfastsub_unlink_InURBs(struct usbduxfastsub_s *udfs)
+static void usbduxfast_cmd_data(struct comedi_device *dev, int index,
+				uint8_t len, uint8_t op, uint8_t out,
+				uint8_t log)
 {
-	int j = 0;
-	int err = 0;
+	struct usbduxfast_private *devpriv = dev->private;
 
-	if (udfs && udfs->urbIn) {
-		udfs->ai_cmd_running = 0;
-		/* waits until a running transfer is over */
-		usb_kill_urb(udfs->urbIn);
-		j = 0;
-	}
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi: usbduxfast: unlinked InURB: res=%d\n", j);
-#endif
-	return err;
+	/* Set the GPIF bytes, the first byte is the command byte */
+	devpriv->duxbuf[1 + 0x00 + index] = len;
+	devpriv->duxbuf[1 + 0x08 + index] = op;
+	devpriv->duxbuf[1 + 0x10 + index] = out;
+	devpriv->duxbuf[1 + 0x18 + index] = log;
 }
 
-/*
- * This will stop a running acquisition operation.
- * Is called from within this driver from both the
- * interrupt context and from comedi.
- */
-static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs, int do_unlink)
+static int usbduxfast_ai_stop(struct comedi_device *dev, int do_unlink)
 {
-	int ret = 0;
-
-	if (!udfs) {
-		pr_err("%s: udfs=NULL!\n", __func__);
-		return -EFAULT;
-	}
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi: usbduxfast_ai_stop\n");
-#endif
+	struct usbduxfast_private *devpriv = dev->private;
 
-	udfs->ai_cmd_running = 0;
+	/* stop aquistion */
+	devpriv->ai_cmd_running = 0;
 
-	if (do_unlink)
-		/* stop aquistion */
-		ret = usbduxfastsub_unlink_InURBs(udfs);
+	if (do_unlink && devpriv->urb) {
+		/* kill the running transfer */
+		usb_kill_urb(devpriv->urb);
+	}
 
-	return ret;
+	return 0;
 }
 
-/*
- * This will cancel a running acquisition operation.
- * This is called by comedi but never from inside the driver.
- */
 static int usbduxfast_ai_cancel(struct comedi_device *dev,
 				struct comedi_subdevice *s)
 {
-	struct usbduxfastsub_s *udfs;
+	struct usbduxfast_private *devpriv = dev->private;
 	int ret;
 
-	/* force unlink of all urbs */
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi: usbduxfast_ai_cancel\n");
-#endif
-	udfs = dev->private;
-	if (!udfs) {
-		dev_err(dev->class_dev, "%s: udfs=NULL\n", __func__);
+	if (!devpriv)
 		return -EFAULT;
-	}
-	down(&udfs->sem);
-	if (!udfs->probed) {
-		up(&udfs->sem);
-		return -ENODEV;
-	}
-	/* unlink */
-	ret = usbduxfast_ai_stop(udfs, 1);
-	up(&udfs->sem);
+
+	down(&devpriv->sem);
+	ret = usbduxfast_ai_stop(dev, 1);
+	up(&devpriv->sem);
 
 	return ret;
 }
@@ -306,32 +232,17 @@ static int usbduxfast_ai_cancel(struct c
  * analogue IN
  * interrupt service routine
  */
-static void usbduxfastsub_ai_Irq(struct urb *urb)
+static void usbduxfast_ai_interrupt(struct urb *urb)
 {
+	struct comedi_device *dev = urb->context;
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async = s->async;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxfast_private *devpriv = dev->private;
 	int n, err;
-	struct usbduxfastsub_s *udfs;
-	struct comedi_device *this_comedidev;
-	struct comedi_subdevice *s;
 
-	/* sanity checks - is the urb there? */
-	if (!urb) {
-		pr_err("ao int-handler called with urb=NULL!\n");
-		return;
-	}
-	/* the context variable points to the subdevice */
-	this_comedidev = urb->context;
-	if (!this_comedidev) {
-		pr_err("urb context is a NULL pointer!\n");
-		return;
-	}
-	/* the private structure of the subdevice is usbduxfastsub_s */
-	udfs = this_comedidev->private;
-	if (!udfs) {
-		pr_err("private of comedi subdev is a NULL pointer!\n");
-		return;
-	}
 	/* are we running a command? */
-	if (unlikely(!udfs->ai_cmd_running)) {
+	if (unlikely(!devpriv->ai_cmd_running)) {
 		/*
 		 * not running a command
 		 * do not continue execution if no asynchronous command
@@ -340,13 +251,6 @@ static void usbduxfastsub_ai_Irq(struct
 		return;
 	}
 
-	if (unlikely(!udfs->attached)) {
-		/* no comedi device there */
-		return;
-	}
-	/* subdevice which is the AD converter */
-	s = &this_comedidev->subdevices[SUBDEV_AD];
-
 	/* first we test if something unusual has just happened */
 	switch (urb->status) {
 	case 0:
@@ -361,189 +265,93 @@ static void usbduxfastsub_ai_Irq(struct
 	case -ESHUTDOWN:
 	case -ECONNABORTED:
 		/* tell this comedi */
-		s->async->events |= COMEDI_CB_EOA;
-		s->async->events |= COMEDI_CB_ERROR;
-		comedi_event(udfs->comedidev, s);
+		async->events |= COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
+		comedi_event(dev, s);
 		/* stop the transfer w/o unlink */
-		usbduxfast_ai_stop(udfs, 0);
+		usbduxfast_ai_stop(dev, 0);
 		return;
 
 	default:
 		pr_err("non-zero urb status received in ai intr context: %d\n",
 		       urb->status);
-		s->async->events |= COMEDI_CB_EOA;
-		s->async->events |= COMEDI_CB_ERROR;
-		comedi_event(udfs->comedidev, s);
-		usbduxfast_ai_stop(udfs, 0);
+		async->events |= COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		usbduxfast_ai_stop(dev, 0);
 		return;
 	}
 
-	if (!udfs->ignore) {
-		if (!udfs->ai_continous) {
+	if (!devpriv->ignore) {
+		if (!devpriv->ai_continous) {
 			/* not continuous, fixed number of samples */
 			n = urb->actual_length / sizeof(uint16_t);
-			if (unlikely(udfs->ai_sample_count < n)) {
-				/*
-				 * we have send only a fraction of the bytes
-				 * received
-				 */
+			if (unlikely(devpriv->ai_sample_count < n)) {
+				unsigned int num_bytes;
+
+				/* partial sample received */
+				num_bytes = devpriv->ai_sample_count *
+					    sizeof(uint16_t);
 				cfc_write_array_to_buffer(s,
 							  urb->transfer_buffer,
-							  udfs->ai_sample_count
-							  * sizeof(uint16_t));
-				usbduxfast_ai_stop(udfs, 0);
+							  num_bytes);
+				usbduxfast_ai_stop(dev, 0);
 				/* tell comedi that the acquistion is over */
-				s->async->events |= COMEDI_CB_EOA;
-				comedi_event(udfs->comedidev, s);
+				async->events |= COMEDI_CB_EOA;
+				comedi_event(dev, s);
 				return;
 			}
-			udfs->ai_sample_count -= n;
+			devpriv->ai_sample_count -= n;
 		}
 		/* write the full buffer to comedi */
 		err = cfc_write_array_to_buffer(s, urb->transfer_buffer,
 						urb->actual_length);
 		if (unlikely(err == 0)) {
 			/* buffer overflow */
-			usbduxfast_ai_stop(udfs, 0);
+			usbduxfast_ai_stop(dev, 0);
 			return;
 		}
 
 		/* tell comedi that data is there */
-		comedi_event(udfs->comedidev, s);
-
+		comedi_event(dev, s);
 	} else {
 		/* ignore this packet */
-		udfs->ignore--;
+		devpriv->ignore--;
 	}
 
 	/*
 	 * command is still running
 	 * resubmit urb for BULK transfer
 	 */
-	urb->dev = udfs->usbdev;
+	urb->dev = usb;
 	urb->status = 0;
 	err = usb_submit_urb(urb, GFP_ATOMIC);
 	if (err < 0) {
-		dev_err(&urb->dev->dev,
+		dev_err(dev->class_dev,
 			"urb resubm failed: %d", err);
-		s->async->events |= COMEDI_CB_EOA;
-		s->async->events |= COMEDI_CB_ERROR;
-		comedi_event(udfs->comedidev, s);
-		usbduxfast_ai_stop(udfs, 0);
-	}
-}
-
-static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
-{
-	int ret;
-	unsigned char *local_transfer_buffer;
-
-	local_transfer_buffer = kmalloc(1, GFP_KERNEL);
-	if (!local_transfer_buffer)
-		return -ENOMEM;
-
-	/* 7f92 to zero */
-	*local_transfer_buffer = 0;
-	/* bRequest, "Firmware" */
-	ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
-			      USBDUXFASTSUB_FIRMWARE,
-			      VENDOR_DIR_OUT,	  /* bmRequestType */
-			      USBDUXFASTSUB_CPUCS,    /* Value */
-			      0x0000,	/* Index */
-			      /* address of the transfer buffer */
-			      local_transfer_buffer,
-			      1,      /* Length */
-			      EZTIMEOUT);    /* Timeout */
-	if (ret < 0)
-		dev_err(&udfs->interface->dev,
-			"control msg failed (start)\n");
-
-	kfree(local_transfer_buffer);
-	return ret;
-}
-
-static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
-{
-	int ret;
-	unsigned char *local_transfer_buffer;
-
-	local_transfer_buffer = kmalloc(1, GFP_KERNEL);
-	if (!local_transfer_buffer)
-		return -ENOMEM;
-
-	/* 7f92 to one */
-	*local_transfer_buffer = 1;
-	/* bRequest, "Firmware" */
-	ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
-			      USBDUXFASTSUB_FIRMWARE,
-			      VENDOR_DIR_OUT,	/* bmRequestType */
-			      USBDUXFASTSUB_CPUCS,	/* Value */
-			      0x0000,	/* Index */
-			      local_transfer_buffer, 1,	/* Length */
-			      EZTIMEOUT);	/* Timeout */
-	if (ret < 0)
-		dev_err(&udfs->interface->dev,
-			"control msg failed (stop)\n");
-
-	kfree(local_transfer_buffer);
-	return ret;
-}
-
-static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
-				unsigned char *local_transfer_buffer,
-				unsigned int startAddr, unsigned int len)
-{
-	int ret;
-
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi: usbduxfast: uploading %d bytes", len);
-	printk(KERN_DEBUG " to addr %d, first byte=%d.\n",
-	       startAddr, local_transfer_buffer[0]);
-#endif
-	/* brequest, firmware */
-	ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
-			      USBDUXFASTSUB_FIRMWARE,
-			      VENDOR_DIR_OUT,	/* bmRequestType */
-			      startAddr,	/* value */
-			      0x0000,	 /* index */
-			      /* our local safe buffer */
-			      local_transfer_buffer,
-			      len,	/* length */
-			      EZTIMEOUT);      /* timeout */
-
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret);
-#endif
-
-	if (ret < 0) {
-		dev_err(&udfs->interface->dev, "uppload failed\n");
-		return ret;
+		async->events |= COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		usbduxfast_ai_stop(dev, 0);
 	}
-
-	return 0;
 }
 
-static int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
+static int usbduxfast_submit_urb(struct comedi_device *dev)
 {
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxfast_private *devpriv = dev->private;
 	int ret;
 
-	if (!udfs)
+	if (!devpriv)
 		return -EFAULT;
 
-	usb_fill_bulk_urb(udfs->urbIn, udfs->usbdev,
-			  usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
-			  udfs->transfer_buffer,
-			  SIZEINBUF, usbduxfastsub_ai_Irq, udfs->comedidev);
+	usb_fill_bulk_urb(devpriv->urb, usb, usb_rcvbulkpipe(usb, BULKINEP),
+			  devpriv->inbuf, SIZEINBUF,
+			  usbduxfast_ai_interrupt, dev);
 
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
-	       "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
-	       udfs->urbIn->dev);
-#endif
-	ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC);
+	ret = usb_submit_urb(devpriv->urb, GFP_ATOMIC);
 	if (ret) {
-		dev_err(&udfs->interface->dev,
-			"ai: usb_submit_urb error %d\n", ret);
+		dev_err(dev->class_dev, "usb_submit_urb error %d\n", ret);
 		return ret;
 	}
 	return 0;
@@ -553,13 +361,9 @@ static int usbduxfast_ai_cmdtest(struct
 				 struct comedi_subdevice *s,
 				 struct comedi_cmd *cmd)
 {
-	struct usbduxfastsub_s *udfs = dev->private;
 	int err = 0;
 	long int steps, tmp;
-	int minSamplPer;
-
-	if (!udfs->probed)
-		return -ENODEV;
+	int min_sample_period;
 
 	/* Step 1 : check if triggers are trivially valid */
 
@@ -601,14 +405,14 @@ static int usbduxfast_ai_cmdtest(struct
 	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
 
 	if (cmd->chanlist_len == 1)
-		minSamplPer = 1;
+		min_sample_period = 1;
 	else
-		minSamplPer = MIN_SAMPLING_PERIOD;
+		min_sample_period = MIN_SAMPLING_PERIOD;
 
 	if (cmd->convert_src == TRIG_TIMER) {
 		steps = cmd->convert_arg * 30;
-		if (steps < (minSamplPer * 1000))
-			steps = minSamplPer * 1000;
+		if (steps < (min_sample_period * 1000))
+			steps = min_sample_period * 1000;
 
 		if (steps > (MAX_SAMPLING_PERIOD * 1000))
 			steps = MAX_SAMPLING_PERIOD * 1000;
@@ -650,80 +454,53 @@ static int usbduxfast_ai_inttrig(struct
 				 struct comedi_subdevice *s,
 				 unsigned int trignum)
 {
+	struct usbduxfast_private *devpriv = dev->private;
 	int ret;
-	struct usbduxfastsub_s *udfs = dev->private;
 
-	if (!udfs)
+	if (!devpriv)
 		return -EFAULT;
 
-	down(&udfs->sem);
-	if (!udfs->probed) {
-		up(&udfs->sem);
-		return -ENODEV;
-	}
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi%d: usbduxfast_ai_inttrig\n", dev->minor);
-#endif
+	down(&devpriv->sem);
 
 	if (trignum != 0) {
-		dev_err(dev->class_dev, "%s: invalid trignum\n", __func__);
-		up(&udfs->sem);
+		dev_err(dev->class_dev, "invalid trignum\n");
+		up(&devpriv->sem);
 		return -EINVAL;
 	}
-	if (!udfs->ai_cmd_running) {
-		udfs->ai_cmd_running = 1;
-		ret = usbduxfastsub_submit_InURBs(udfs);
+	if (!devpriv->ai_cmd_running) {
+		devpriv->ai_cmd_running = 1;
+		ret = usbduxfast_submit_urb(dev);
 		if (ret < 0) {
-			dev_err(dev->class_dev,
-				"%s: urbSubmit: err=%d\n", __func__, ret);
-			udfs->ai_cmd_running = 0;
-			up(&udfs->sem);
+			dev_err(dev->class_dev, "urbSubmit: err=%d\n", ret);
+			devpriv->ai_cmd_running = 0;
+			up(&devpriv->sem);
 			return ret;
 		}
 		s->async->inttrig = NULL;
 	} else {
-		dev_err(dev->class_dev,
-			"ai_inttrig but acqu is already running\n");
+		dev_err(dev->class_dev, "ai is already running\n");
 	}
-	up(&udfs->sem);
+	up(&devpriv->sem);
 	return 1;
 }
 
-/*
- * offsets for the GPIF bytes
- * the first byte is the command byte
- */
-#define LENBASE	(1+0x00)
-#define OPBASE	(1+0x08)
-#define OUTBASE	(1+0x10)
-#define LOGBASE	(1+0x18)
-
 static int usbduxfast_ai_cmd(struct comedi_device *dev,
 			     struct comedi_subdevice *s)
 {
+	struct usbduxfast_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int chan, gain, rngmask = 0xff;
 	int i, j, ret;
-	struct usbduxfastsub_s *udfs;
 	int result;
 	long steps, steps_tmp;
 
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmd\n", dev->minor);
-#endif
-	udfs = dev->private;
-	if (!udfs)
+	if (!devpriv)
 		return -EFAULT;
 
-	down(&udfs->sem);
-	if (!udfs->probed) {
-		up(&udfs->sem);
-		return -ENODEV;
-	}
-	if (udfs->ai_cmd_running) {
-		dev_err(dev->class_dev,
-			"ai_cmd not possible. Another ai_cmd is running.\n");
-		up(&udfs->sem);
+	down(&devpriv->sem);
+	if (devpriv->ai_cmd_running) {
+		dev_err(dev->class_dev, "ai_cmd not possible\n");
+		up(&devpriv->sem);
 		return -EBUSY;
 	}
 	/* set current channel of the running acquisition to zero */
@@ -733,7 +510,7 @@ static int usbduxfast_ai_cmd(struct come
 	 * ignore the first buffers from the device if there
 	 * is an error condition
 	 */
-	udfs->ignore = PACKETS_TO_IGNORE;
+	devpriv->ignore = PACKETS_TO_IGNORE;
 
 	if (cmd->chanlist_len > 0) {
 		gain = CR_RANGE(cmd->chanlist[0]);
@@ -741,20 +518,19 @@ static int usbduxfast_ai_cmd(struct come
 			chan = CR_CHAN(cmd->chanlist[i]);
 			if (chan != i) {
 				dev_err(dev->class_dev,
-					"cmd is accepting only consecutive channels.\n");
-				up(&udfs->sem);
+					"channels are not consecutive\n");
+				up(&devpriv->sem);
 				return -EINVAL;
 			}
 			if ((gain != CR_RANGE(cmd->chanlist[i]))
 			    && (cmd->chanlist_len > 3)) {
 				dev_err(dev->class_dev,
-					"the gain must be the same for all channels.\n");
-				up(&udfs->sem);
+					"gain must be the same for all channels\n");
+				up(&devpriv->sem);
 				return -EINVAL;
 			}
 			if (i >= NUMCHANNELS) {
-				dev_err(dev->class_dev,
-					"channel list too long\n");
+				dev_err(dev->class_dev, "chanlist too long\n");
 				break;
 			}
 		}
@@ -762,8 +538,8 @@ static int usbduxfast_ai_cmd(struct come
 	steps = 0;
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		dev_err(dev->class_dev,
-			"scan_begin_src==TRIG_TIMER not valid.\n");
-		up(&udfs->sem);
+			"scan_begin_src==TRIG_TIMER not valid\n");
+		up(&devpriv->sem);
 		return -EINVAL;
 	}
 	if (cmd->convert_src == TRIG_TIMER)
@@ -771,27 +547,23 @@ static int usbduxfast_ai_cmd(struct come
 
 	if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
 		dev_err(dev->class_dev,
-			"ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
+			"steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n",
 			steps, cmd->scan_begin_arg);
-		up(&udfs->sem);
+		up(&devpriv->sem);
 		return -EINVAL;
 	}
 	if (steps > MAX_SAMPLING_PERIOD) {
-		dev_err(dev->class_dev, "ai_cmd: sampling rate too low.\n");
-		up(&udfs->sem);
+		dev_err(dev->class_dev, "sampling rate too low\n");
+		up(&devpriv->sem);
 		return -EINVAL;
 	}
 	if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
 	    && (cmd->chanlist_len != 16)) {
 		dev_err(dev->class_dev,
-			"ai_cmd: TRIG_EXT only with 1 or 16 channels possible.\n");
-		up(&udfs->sem);
+			"TRIG_EXT only with 1 or 16 channels possible\n");
+		up(&devpriv->sem);
 		return -EINVAL;
 	}
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi%d: usbduxfast: steps=%ld, convert_arg=%u\n",
-	       dev->minor, steps, cmd->convert_arg);
-#endif
 
 	switch (cmd->chanlist_len) {
 	case 1:
@@ -812,17 +584,11 @@ static int usbduxfast_ai_cmd(struct come
 		/* we loop here until ready has been set */
 		if (cmd->start_src == TRIG_EXT) {
 			/* branch back to state 0 */
-			udfs->dux_commands[LENBASE + 0] = 0x01;
 			/* deceision state w/o data */
-			udfs->dux_commands[OPBASE + 0] = 0x01;
-			udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
 			/* RDY0 = 0 */
-			udfs->dux_commands[LOGBASE + 0] = 0x00;
+			usbduxfast_cmd_data(dev, 0, 0x01, 0x01, rngmask, 0x00);
 		} else {	/* we just proceed to state 1 */
-			udfs->dux_commands[LENBASE + 0] = 1;
-			udfs->dux_commands[OPBASE + 0] = 0;
-			udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
-			udfs->dux_commands[LOGBASE + 0] = 0;
+			usbduxfast_cmd_data(dev, 0, 0x01, 0x00, rngmask, 0x00);
 		}
 
 		if (steps < MIN_SAMPLING_PERIOD) {
@@ -835,33 +601,25 @@ static int usbduxfast_ai_cmd(struct come
 				 */
 
 				/* branch back to state 1 */
-				udfs->dux_commands[LENBASE + 1] = 0x89;
 				/* deceision state with data */
-				udfs->dux_commands[OPBASE + 1] = 0x03;
-				udfs->dux_commands[OUTBASE + 1] =
-				    0xFF & rngmask;
 				/* doesn't matter */
-				udfs->dux_commands[LOGBASE + 1] = 0xFF;
+				usbduxfast_cmd_data(dev, 1,
+						    0x89, 0x03, rngmask, 0xff);
 			} else {
 				/*
 				 * we loop through two states: data and delay
 				 * max rate is 15MHz
 				 */
-				udfs->dux_commands[LENBASE + 1] = steps - 1;
 				/* data */
-				udfs->dux_commands[OPBASE + 1] = 0x02;
-				udfs->dux_commands[OUTBASE + 1] =
-				    0xFF & rngmask;
 				/* doesn't matter */
-				udfs->dux_commands[LOGBASE + 1] = 0;
+				usbduxfast_cmd_data(dev, 1, steps - 1,
+						    0x02, rngmask, 0x00);
+
 				/* branch back to state 1 */
-				udfs->dux_commands[LENBASE + 2] = 0x09;
 				/* deceision state w/o data */
-				udfs->dux_commands[OPBASE + 2] = 0x01;
-				udfs->dux_commands[OUTBASE + 2] =
-				    0xFF & rngmask;
 				/* doesn't matter */
-				udfs->dux_commands[LOGBASE + 2] = 0xFF;
+				usbduxfast_cmd_data(dev, 2,
+						    0x09, 0x01, rngmask, 0xff);
 			}
 		} else {
 			/*
@@ -873,26 +631,20 @@ static int usbduxfast_ai_cmd(struct come
 			steps = steps - 1;
 
 			/* do the first part of the delay */
-			udfs->dux_commands[LENBASE + 1] = steps / 2;
-			udfs->dux_commands[OPBASE + 1] = 0;
-			udfs->dux_commands[OUTBASE + 1] = 0xFF & rngmask;
-			udfs->dux_commands[LOGBASE + 1] = 0;
+			usbduxfast_cmd_data(dev, 1,
+					    steps / 2, 0x00, rngmask, 0x00);
 
 			/* and the second part */
-			udfs->dux_commands[LENBASE + 2] = steps - steps / 2;
-			udfs->dux_commands[OPBASE + 2] = 0;
-			udfs->dux_commands[OUTBASE + 2] = 0xFF & rngmask;
-			udfs->dux_commands[LOGBASE + 2] = 0;
+			usbduxfast_cmd_data(dev, 2, steps - steps / 2,
+					    0x00, rngmask, 0x00);
 
 			/* get the data and branch back */
 
 			/* branch back to state 1 */
-			udfs->dux_commands[LENBASE + 3] = 0x09;
 			/* deceision state w data */
-			udfs->dux_commands[OPBASE + 3] = 0x03;
-			udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
 			/* doesn't matter */
-			udfs->dux_commands[LOGBASE + 3] = 0xFF;
+			usbduxfast_cmd_data(dev, 3,
+					    0x09, 0x03, rngmask, 0xff);
 		}
 		break;
 
@@ -907,11 +659,8 @@ static int usbduxfast_ai_cmd(struct come
 		else
 			rngmask = 0xff;
 
-		udfs->dux_commands[LENBASE + 0] = 1;
 		/* data */
-		udfs->dux_commands[OPBASE + 0] = 0x02;
-		udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
-		udfs->dux_commands[LOGBASE + 0] = 0;
+		usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
 
 		/* we have 1 state with duration 1: state 0 */
 		steps_tmp = steps - 1;
@@ -922,23 +671,16 @@ static int usbduxfast_ai_cmd(struct come
 			rngmask = 0xff;
 
 		/* do the first part of the delay */
-		udfs->dux_commands[LENBASE + 1] = steps_tmp / 2;
-		udfs->dux_commands[OPBASE + 1] = 0;
 		/* count */
-		udfs->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
-		udfs->dux_commands[LOGBASE + 1] = 0;
+		usbduxfast_cmd_data(dev, 1, steps_tmp / 2,
+				    0x00, 0xfe & rngmask, 0x00);
 
 		/* and the second part */
-		udfs->dux_commands[LENBASE + 2] = steps_tmp - steps_tmp / 2;
-		udfs->dux_commands[OPBASE + 2] = 0;
-		udfs->dux_commands[OUTBASE + 2] = 0xFF & rngmask;
-		udfs->dux_commands[LOGBASE + 2] = 0;
+		usbduxfast_cmd_data(dev, 2, steps_tmp  - steps_tmp / 2,
+				    0x00, rngmask, 0x00);
 
-		udfs->dux_commands[LENBASE + 3] = 1;
 		/* data */
-		udfs->dux_commands[OPBASE + 3] = 0x02;
-		udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
-		udfs->dux_commands[LOGBASE + 3] = 0;
+		usbduxfast_cmd_data(dev, 3, 0x01, 0x02, rngmask, 0x00);
 
 		/*
 		 * we have 2 states with duration 1: step 6 and
@@ -952,22 +694,15 @@ static int usbduxfast_ai_cmd(struct come
 			rngmask = 0xff;
 
 		/* do the first part of the delay */
-		udfs->dux_commands[LENBASE + 4] = steps_tmp / 2;
-		udfs->dux_commands[OPBASE + 4] = 0;
 		/* reset */
-		udfs->dux_commands[OUTBASE + 4] = (0xFF - 0x02) & rngmask;
-		udfs->dux_commands[LOGBASE + 4] = 0;
+		usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
+				    0x00, (0xff - 0x02) & rngmask, 0x00);
 
 		/* and the second part */
-		udfs->dux_commands[LENBASE + 5] = steps_tmp - steps_tmp / 2;
-		udfs->dux_commands[OPBASE + 5] = 0;
-		udfs->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
-		udfs->dux_commands[LOGBASE + 5] = 0;
+		usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
+				    0x00, rngmask, 0x00);
 
-		udfs->dux_commands[LENBASE + 6] = 1;
-		udfs->dux_commands[OPBASE + 6] = 0;
-		udfs->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
-		udfs->dux_commands[LOGBASE + 6] = 0;
+		usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
 		break;
 
 	case 3:
@@ -975,6 +710,8 @@ static int usbduxfast_ai_cmd(struct come
 		 * three channels
 		 */
 		for (j = 0; j < 1; j++) {
+			int index = j * 2;
+
 			if (CR_RANGE(cmd->chanlist[j]) > 0)
 				rngmask = 0xff - 0x04;
 			else
@@ -983,12 +720,10 @@ static int usbduxfast_ai_cmd(struct come
 			 * commit data to the FIFO and do the first part
 			 * of the delay
 			 */
-			udfs->dux_commands[LENBASE + j * 2] = steps / 2;
 			/* data */
-			udfs->dux_commands[OPBASE + j * 2] = 0x02;
 			/* no change */
-			udfs->dux_commands[OUTBASE + j * 2] = 0xFF & rngmask;
-			udfs->dux_commands[LOGBASE + j * 2] = 0;
+			usbduxfast_cmd_data(dev, index, steps / 2,
+					    0x02, rngmask, 0x00);
 
 			if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
 				rngmask = 0xff - 0x04;
@@ -996,25 +731,19 @@ static int usbduxfast_ai_cmd(struct come
 				rngmask = 0xff;
 
 			/* do the second part of the delay */
-			udfs->dux_commands[LENBASE + j * 2 + 1] =
-			    steps - steps / 2;
 			/* no data */
-			udfs->dux_commands[OPBASE + j * 2 + 1] = 0;
 			/* count */
-			udfs->dux_commands[OUTBASE + j * 2 + 1] =
-			    0xFE & rngmask;
-			udfs->dux_commands[LOGBASE + j * 2 + 1] = 0;
+			usbduxfast_cmd_data(dev, index + 1, steps - steps / 2,
+					    0x00, 0xfe & rngmask, 0x00);
 		}
 
 		/* 2 steps with duration 1: the idele step and step 6: */
 		steps_tmp = steps - 2;
 
 		/* commit data to the FIFO and do the first part of the delay */
-		udfs->dux_commands[LENBASE + 4] = steps_tmp / 2;
 		/* data */
-		udfs->dux_commands[OPBASE + 4] = 0x02;
-		udfs->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
-		udfs->dux_commands[LOGBASE + 4] = 0;
+		usbduxfast_cmd_data(dev, 4, steps_tmp / 2,
+				    0x02, rngmask, 0x00);
 
 		if (CR_RANGE(cmd->chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
@@ -1022,17 +751,12 @@ static int usbduxfast_ai_cmd(struct come
 			rngmask = 0xff;
 
 		/* do the second part of the delay */
-		udfs->dux_commands[LENBASE + 5] = steps_tmp - steps_tmp / 2;
 		/* no data */
-		udfs->dux_commands[OPBASE + 5] = 0;
 		/* reset */
-		udfs->dux_commands[OUTBASE + 5] = (0xFF - 0x02) & rngmask;
-		udfs->dux_commands[LOGBASE + 5] = 0;
+		usbduxfast_cmd_data(dev, 5, steps_tmp - steps_tmp / 2,
+				    0x00, (0xff - 0x02) & rngmask, 0x00);
 
-		udfs->dux_commands[LENBASE + 6] = 1;
-		udfs->dux_commands[OPBASE + 6] = 0;
-		udfs->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
-		udfs->dux_commands[LOGBASE + 6] = 0;
+		usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
 
 	case 16:
 		if (CR_RANGE(cmd->chanlist[0]) > 0)
@@ -1046,101 +770,79 @@ static int usbduxfast_ai_cmd(struct come
 			 */
 
 			/* branch back to state 0 */
-			udfs->dux_commands[LENBASE + 0] = 0x01;
 			/* deceision state w/o data */
-			udfs->dux_commands[OPBASE + 0] = 0x01;
 			/* reset */
-			udfs->dux_commands[OUTBASE + 0] =
-			    (0xFF - 0x02) & rngmask;
 			/* RDY0 = 0 */
-			udfs->dux_commands[LOGBASE + 0] = 0x00;
+			usbduxfast_cmd_data(dev, 0, 0x01, 0x01,
+					    (0xff - 0x02) & rngmask, 0x00);
 		} else {
 			/*
 			 * we just proceed to state 1
 			 */
 
 			/* 30us reset pulse */
-			udfs->dux_commands[LENBASE + 0] = 255;
-			udfs->dux_commands[OPBASE + 0] = 0;
 			/* reset */
-			udfs->dux_commands[OUTBASE + 0] =
-			    (0xFF - 0x02) & rngmask;
-			udfs->dux_commands[LOGBASE + 0] = 0;
+			usbduxfast_cmd_data(dev, 0, 0xff, 0x00,
+					    (0xff - 0x02) & rngmask, 0x00);
 		}
 
 		/* commit data to the FIFO */
-		udfs->dux_commands[LENBASE + 1] = 1;
 		/* data */
-		udfs->dux_commands[OPBASE + 1] = 0x02;
-		udfs->dux_commands[OUTBASE + 1] = 0xFF & rngmask;
-		udfs->dux_commands[LOGBASE + 1] = 0;
+		usbduxfast_cmd_data(dev, 1, 0x01, 0x02, rngmask, 0x00);
 
 		/* we have 2 states with duration 1 */
 		steps = steps - 2;
 
 		/* do the first part of the delay */
-		udfs->dux_commands[LENBASE + 2] = steps / 2;
-		udfs->dux_commands[OPBASE + 2] = 0;
-		udfs->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
-		udfs->dux_commands[LOGBASE + 2] = 0;
+		usbduxfast_cmd_data(dev, 2, steps / 2,
+				    0x00, 0xfe & rngmask, 0x00);
 
 		/* and the second part */
-		udfs->dux_commands[LENBASE + 3] = steps - steps / 2;
-		udfs->dux_commands[OPBASE + 3] = 0;
-		udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
-		udfs->dux_commands[LOGBASE + 3] = 0;
+		usbduxfast_cmd_data(dev, 3, steps - steps / 2,
+				    0x00, rngmask, 0x00);
 
 		/* branch back to state 1 */
-		udfs->dux_commands[LENBASE + 4] = 0x09;
 		/* deceision state w/o data */
-		udfs->dux_commands[OPBASE + 4] = 0x01;
-		udfs->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
 		/* doesn't matter */
-		udfs->dux_commands[LOGBASE + 4] = 0xFF;
+		usbduxfast_cmd_data(dev, 4, 0x09, 0x01, rngmask, 0xff);
 
 		break;
 
 	default:
 		dev_err(dev->class_dev, "unsupported combination of channels\n");
-		up(&udfs->sem);
+		up(&devpriv->sem);
 		return -EFAULT;
 	}
 
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
-	       dev->minor);
-#endif
 	/* 0 means that the AD commands are sent */
-	result = send_dux_commands(udfs, SENDADCOMMANDS);
+	result = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
 	if (result < 0) {
-		dev_err(dev->class_dev,
-			"adc command could not be submitted. Aborting...\n");
-		up(&udfs->sem);
+		up(&devpriv->sem);
 		return result;
 	}
 	if (cmd->stop_src == TRIG_COUNT) {
-		udfs->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
-		if (udfs->ai_sample_count < 1) {
+		devpriv->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
+		if (devpriv->ai_sample_count < 1) {
 			dev_err(dev->class_dev,
-				"(cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting.\n");
-			up(&udfs->sem);
+				"(cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting\n");
+			up(&devpriv->sem);
 			return -EFAULT;
 		}
-		udfs->ai_continous = 0;
+		devpriv->ai_continous = 0;
 	} else {
 		/* continous acquisition */
-		udfs->ai_continous = 1;
-		udfs->ai_sample_count = 0;
+		devpriv->ai_continous = 1;
+		devpriv->ai_sample_count = 0;
 	}
 
 	if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
 		/* enable this acquisition operation */
-		udfs->ai_cmd_running = 1;
-		ret = usbduxfastsub_submit_InURBs(udfs);
+		devpriv->ai_cmd_running = 1;
+		ret = usbduxfast_submit_urb(dev);
 		if (ret < 0) {
-			udfs->ai_cmd_running = 0;
+			devpriv->ai_cmd_running = 0;
 			/* fixme: unlink here?? */
-			up(&udfs->sem);
+			up(&devpriv->sem);
 			return ret;
 		}
 		s->async->inttrig = NULL;
@@ -1152,7 +854,7 @@ static int usbduxfast_ai_cmd(struct come
 		 */
 		s->async->inttrig = usbduxfast_ai_inttrig;
 	}
-	up(&udfs->sem);
+	up(&devpriv->sem);
 
 	return 0;
 }
@@ -1162,490 +864,283 @@ static int usbduxfast_ai_cmd(struct come
  */
 static int usbduxfast_ai_insn_read(struct comedi_device *dev,
 				   struct comedi_subdevice *s,
-				   struct comedi_insn *insn, unsigned int *data)
+				   struct comedi_insn *insn,
+				   unsigned int *data)
 {
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxfast_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int range = CR_RANGE(insn->chanspec);
+	uint8_t rngmask = range ? (0xff - 0x04) : 0xff;
 	int i, j, n, actual_length;
-	int chan, range, rngmask;
-	int err;
-	struct usbduxfastsub_s *udfs;
+	int ret;
 
-	udfs = dev->private;
-	if (!udfs) {
-		dev_err(dev->class_dev, "%s: no usb dev.\n", __func__);
-		return -ENODEV;
-	}
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi%d: ai_insn_read, insn->n=%d, "
-	       "insn->subdev=%d\n", dev->minor, insn->n, insn->subdev);
-#endif
-	down(&udfs->sem);
-	if (!udfs->probed) {
-		up(&udfs->sem);
-		return -ENODEV;
-	}
-	if (udfs->ai_cmd_running) {
+	down(&devpriv->sem);
+
+	if (devpriv->ai_cmd_running) {
 		dev_err(dev->class_dev,
-			"ai_insn_read not possible. Async Command is running.\n");
-		up(&udfs->sem);
+			"ai_insn_read not possible, async cmd is running\n");
+		up(&devpriv->sem);
 		return -EBUSY;
 	}
-	/* sample one channel */
-	chan = CR_CHAN(insn->chanspec);
-	range = CR_RANGE(insn->chanspec);
-	/* set command for the first channel */
 
-	if (range > 0)
-		rngmask = 0xff - 0x04;
-	else
-		rngmask = 0xff;
+	/* set command for the first channel */
 
 	/* commit data to the FIFO */
-	udfs->dux_commands[LENBASE + 0] = 1;
 	/* data */
-	udfs->dux_commands[OPBASE + 0] = 0x02;
-	udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
-	udfs->dux_commands[LOGBASE + 0] = 0;
+	usbduxfast_cmd_data(dev, 0, 0x01, 0x02, rngmask, 0x00);
 
 	/* do the first part of the delay */
-	udfs->dux_commands[LENBASE + 1] = 12;
-	udfs->dux_commands[OPBASE + 1] = 0;
-	udfs->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
-	udfs->dux_commands[LOGBASE + 1] = 0;
-
-	udfs->dux_commands[LENBASE + 2] = 1;
-	udfs->dux_commands[OPBASE + 2] = 0;
-	udfs->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
-	udfs->dux_commands[LOGBASE + 2] = 0;
-
-	udfs->dux_commands[LENBASE + 3] = 1;
-	udfs->dux_commands[OPBASE + 3] = 0;
-	udfs->dux_commands[OUTBASE + 3] = 0xFE & rngmask;
-	udfs->dux_commands[LOGBASE + 3] = 0;
-
-	udfs->dux_commands[LENBASE + 4] = 1;
-	udfs->dux_commands[OPBASE + 4] = 0;
-	udfs->dux_commands[OUTBASE + 4] = 0xFE & rngmask;
-	udfs->dux_commands[LOGBASE + 4] = 0;
+	usbduxfast_cmd_data(dev, 1, 0x0c, 0x00, 0xfe & rngmask, 0x00);
+	usbduxfast_cmd_data(dev, 2, 0x01, 0x00, 0xfe & rngmask, 0x00);
+	usbduxfast_cmd_data(dev, 3, 0x01, 0x00, 0xfe & rngmask, 0x00);
+	usbduxfast_cmd_data(dev, 4, 0x01, 0x00, 0xfe & rngmask, 0x00);
 
 	/* second part */
-	udfs->dux_commands[LENBASE + 5] = 12;
-	udfs->dux_commands[OPBASE + 5] = 0;
-	udfs->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
-	udfs->dux_commands[LOGBASE + 5] = 0;
-
-	udfs->dux_commands[LENBASE + 6] = 1;
-	udfs->dux_commands[OPBASE + 6] = 0;
-	udfs->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
-	udfs->dux_commands[LOGBASE + 0] = 0;
+	usbduxfast_cmd_data(dev, 5, 0x0c, 0x00, rngmask, 0x00);
+	usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
 
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
-	       dev->minor);
-#endif
-	/* 0 means that the AD commands are sent */
-	err = send_dux_commands(udfs, SENDADCOMMANDS);
-	if (err < 0) {
-		dev_err(dev->class_dev,
-			"adc command could not be submitted. Aborting...\n");
-		up(&udfs->sem);
-		return err;
+	ret = usbduxfast_send_cmd(dev, SENDADCOMMANDS);
+	if (ret < 0) {
+		up(&devpriv->sem);
+		return ret;
 	}
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
-	       "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
-	       udfs->urbIn->dev);
-#endif
+
 	for (i = 0; i < PACKETS_TO_IGNORE; i++) {
-		err = usb_bulk_msg(udfs->usbdev,
-				   usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
-				   udfs->transfer_buffer, SIZEINBUF,
+		ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
+				   devpriv->inbuf, SIZEINBUF,
 				   &actual_length, 10000);
-		if (err < 0) {
-			dev_err(dev->class_dev, "insn timeout. No data.\n");
-			up(&udfs->sem);
-			return err;
+		if (ret < 0) {
+			dev_err(dev->class_dev, "insn timeout, no data\n");
+			up(&devpriv->sem);
+			return ret;
 		}
 	}
-	/* data points */
+
 	for (i = 0; i < insn->n;) {
-		err = usb_bulk_msg(udfs->usbdev,
-				   usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
-				   udfs->transfer_buffer, SIZEINBUF,
+		ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, BULKINEP),
+				   devpriv->inbuf, SIZEINBUF,
 				   &actual_length, 10000);
-		if (err < 0) {
-			dev_err(dev->class_dev, "insn data error: %d\n", err);
-			up(&udfs->sem);
-			return err;
+		if (ret < 0) {
+			dev_err(dev->class_dev, "insn data error: %d\n", ret);
+			up(&devpriv->sem);
+			return ret;
 		}
 		n = actual_length / sizeof(uint16_t);
 		if ((n % 16) != 0) {
-			dev_err(dev->class_dev, "insn data packet corrupted.\n");
-			up(&udfs->sem);
+			dev_err(dev->class_dev, "insn data packet corrupted\n");
+			up(&devpriv->sem);
 			return -EINVAL;
 		}
 		for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
-			data[i] = ((uint16_t *) (udfs->transfer_buffer))[j];
+			data[i] = ((uint16_t *) (devpriv->inbuf))[j];
 			i++;
 		}
 	}
-	up(&udfs->sem);
-	return i;
-}
-
-#define FIRMWARE_MAX_LEN 0x2000
-
-static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub,
-			  const u8 *firmwareBinary, int sizeFirmware)
-{
-	int ret;
-	uint8_t *fwBuf;
-
-	if (!firmwareBinary)
-		return 0;
-
-	if (sizeFirmware > FIRMWARE_MAX_LEN) {
-		dev_err(&usbduxfastsub->interface->dev,
-			"comedi_: usbduxfast firmware binary it too large for FX2.\n");
-		return -ENOMEM;
-	}
-
-	/* we generate a local buffer for the firmware */
-	fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL);
-	if (!fwBuf) {
-		dev_err(&usbduxfastsub->interface->dev,
-			"comedi_: mem alloc for firmware failed\n");
-		return -ENOMEM;
-	}
-
-	ret = usbduxfastsub_stop(usbduxfastsub);
-	if (ret < 0) {
-		dev_err(&usbduxfastsub->interface->dev,
-			"comedi_: can not stop firmware\n");
-		kfree(fwBuf);
-		return ret;
-	}
-
-	ret = usbduxfastsub_upload(usbduxfastsub, fwBuf, 0, sizeFirmware);
-	if (ret < 0) {
-		dev_err(&usbduxfastsub->interface->dev,
-			"comedi_: firmware upload failed\n");
-		kfree(fwBuf);
-		return ret;
-	}
-	ret = usbduxfastsub_start(usbduxfastsub);
-	if (ret < 0) {
-		dev_err(&usbduxfastsub->interface->dev,
-			"comedi_: can not start firmware\n");
-		kfree(fwBuf);
-		return ret;
-	}
-	kfree(fwBuf);
-	return 0;
-}
 
-static void tidy_up(struct usbduxfastsub_s *udfs)
-{
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi_: usbduxfast: tiding up\n");
-#endif
-
-	if (!udfs)
-		return;
-
-	/* shows the usb subsystem that the driver is down */
-	if (udfs->interface)
-		usb_set_intfdata(udfs->interface, NULL);
-
-	udfs->probed = 0;
-
-	if (udfs->urbIn) {
-		/* waits until a running transfer is over */
-		usb_kill_urb(udfs->urbIn);
-
-		kfree(udfs->transfer_buffer);
-		udfs->transfer_buffer = NULL;
-
-		usb_free_urb(udfs->urbIn);
-		udfs->urbIn = NULL;
-	}
-
-	kfree(udfs->insnBuffer);
-	udfs->insnBuffer = NULL;
-
-	kfree(udfs->dux_commands);
-	udfs->dux_commands = NULL;
+	up(&devpriv->sem);
 
-	udfs->ai_cmd_running = 0;
+	return insn->n;
 }
 
-static int usbduxfast_attach_common(struct comedi_device *dev,
-				    struct usbduxfastsub_s *udfs)
+static int usbduxfast_attach_common(struct comedi_device *dev)
 {
-	int ret;
+	struct usbduxfast_private *devpriv = dev->private;
 	struct comedi_subdevice *s;
+	int ret;
 
-	down(&udfs->sem);
-	/* pointer back to the corresponding comedi device */
-	udfs->comedidev = dev;
+	down(&devpriv->sem);
 
 	ret = comedi_alloc_subdevices(dev, 1);
 	if (ret) {
-		up(&udfs->sem);
+		up(&devpriv->sem);
 		return ret;
 	}
-	/* private structure is also simply the usb-structure */
-	dev->private = udfs;
-	/* the first subdevice is the A/D converter */
-	s = &dev->subdevices[SUBDEV_AD];
-	/*
-	 * the URBs get the comedi subdevice which is responsible for reading
-	 * this is the subdevice which reads data
-	 */
+
+	/* Analog Input subdevice */
+	s = &dev->subdevices[0];
 	dev->read_subdev = s;
-	/* the subdevice receives as private structure the usb-structure */
-	s->private = NULL;
-	/* analog input */
-	s->type = COMEDI_SUBD_AI;
-	/* readable and ref is to ground */
-	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
-	/* 16 channels */
-	s->n_chan = 16;
-	/* length of the channellist */
-	s->len_chanlist = 16;
-	/* callback functions */
-	s->insn_read = usbduxfast_ai_insn_read;
-	s->do_cmdtest = usbduxfast_ai_cmdtest;
-	s->do_cmd = usbduxfast_ai_cmd;
-	s->cancel = usbduxfast_ai_cancel;
-	/* max value from the A/D converter (12bit+1 bit for overflow) */
-	s->maxdata = 0x1000;
-	/* range table to convert to physical units */
-	s->range_table = &range_usbduxfast_ai_range;
-	/* finally decide that it's attached */
-	udfs->attached = 1;
-	up(&udfs->sem);
-	dev_info(dev->class_dev, "successfully attached to usbduxfast.\n");
+	s->type		= COMEDI_SUBD_AI;
+	s->subdev_flags	= SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+	s->n_chan	= 16;
+	s->len_chanlist	= 16;
+	s->insn_read	= usbduxfast_ai_insn_read;
+	s->do_cmdtest	= usbduxfast_ai_cmdtest;
+	s->do_cmd	= usbduxfast_ai_cmd;
+	s->cancel	= usbduxfast_ai_cancel;
+	s->maxdata	= 0x1000;
+	s->range_table	= &range_usbduxfast_ai_range;
+
+	up(&devpriv->sem);
+
 	return 0;
 }
 
-static int usbduxfast_auto_attach(struct comedi_device *dev,
-				  unsigned long context_unused)
+static int usbduxfast_upload_firmware(struct comedi_device *dev,
+				      const u8 *data, size_t size,
+				      unsigned long context)
 {
-	struct usb_interface *uinterf = comedi_to_usb_interface(dev);
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	uint8_t *buf;
+	unsigned char *tmp;
 	int ret;
-	struct usbduxfastsub_s *udfs;
-
-	dev->private = NULL;
-	down(&start_stop_sem);
-	udfs = usb_get_intfdata(uinterf);
-	if (!udfs || !udfs->probed) {
-		dev_err(dev->class_dev,
-			"usbduxfast: error: auto_attach failed, not connected\n");
-		ret = -ENODEV;
-	} else if (udfs->attached) {
-		dev_err(dev->class_dev,
-		       "usbduxfast: error: auto_attach failed, already attached\n");
-		ret = -ENODEV;
-	} else
-		ret = usbduxfast_attach_common(dev, udfs);
-	up(&start_stop_sem);
-	return ret;
-}
 
-static void usbduxfast_detach(struct comedi_device *dev)
-{
-	struct usbduxfastsub_s *usb = dev->private;
+	if (!data)
+		return 0;
 
-	if (usb) {
-		down(&usb->sem);
-		down(&start_stop_sem);
-		dev->private = NULL;
-		usb->attached = 0;
-		usb->comedidev = NULL;
-		up(&start_stop_sem);
-		up(&usb->sem);
+	if (size > FIRMWARE_MAX_LEN) {
+		dev_err(dev->class_dev, "firmware binary too large for FX2\n");
+		return -ENOMEM;
 	}
-}
-
-static struct comedi_driver usbduxfast_driver = {
-	.driver_name	= "usbduxfast",
-	.module		= THIS_MODULE,
-	.auto_attach	= usbduxfast_auto_attach,
-	.detach		= usbduxfast_detach,
-};
 
-static void usbduxfast_firmware_request_complete_handler(const struct firmware
-							 *fw, void *context)
-{
-	struct usbduxfastsub_s *usbduxfastsub_tmp = context;
-	struct usb_interface *uinterf = usbduxfastsub_tmp->interface;
-	int ret;
+	/* we generate a local buffer for the firmware */
+	buf = kmemdup(data, size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
-	if (fw == NULL)
-		return;
+	/* we need a malloc'ed buffer for usb_control_msg() */
+	tmp = kmalloc(1, GFP_KERNEL);
+	if (!tmp) {
+		kfree(buf);
+		return -ENOMEM;
+	}
 
-	/*
-	 * we need to upload the firmware here because fw will be
-	 * freed once we've left this function
-	 */
-	ret = firmwareUpload(usbduxfastsub_tmp, fw->data, fw->size);
+	/* stop the current firmware on the device */
+	*tmp = 1;	/* 7f92 to one */
+	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
+			      USBDUXFASTSUB_FIRMWARE,
+			      VENDOR_DIR_OUT,
+			      USBDUXFASTSUB_CPUCS, 0x0000,
+			      tmp, 1,
+			      EZTIMEOUT);
+	if (ret < 0) {
+		dev_err(dev->class_dev, "can not stop firmware\n");
+		goto done;
+	}
 
-	if (ret) {
-		dev_err(&uinterf->dev,
-			"Could not upload firmware (err=%d)\n", ret);
-		goto out;
+	/* upload the new firmware to the device */
+	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
+			      USBDUXFASTSUB_FIRMWARE,
+			      VENDOR_DIR_OUT,
+			      0, 0x0000,
+			      buf, size,
+			      EZTIMEOUT);
+	if (ret < 0) {
+		dev_err(dev->class_dev, "firmware upload failed\n");
+		goto done;
 	}
 
-	comedi_usb_auto_config(uinterf, &usbduxfast_driver, 0);
- out:
-	release_firmware(fw);
+	/* start the new firmware on the device */
+	*tmp = 0;	/* 7f92 to zero */
+	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
+			      USBDUXFASTSUB_FIRMWARE,
+			      VENDOR_DIR_OUT,
+			      USBDUXFASTSUB_CPUCS, 0x0000,
+			      tmp, 1,
+			      EZTIMEOUT);
+	if (ret < 0)
+		dev_err(dev->class_dev, "can not start firmware\n");
+
+done:
+	kfree(tmp);
+	kfree(buf);
+	return ret;
 }
 
-static int usbduxfast_usb_probe(struct usb_interface *uinterf,
-				const struct usb_device_id *id)
+static int usbduxfast_auto_attach(struct comedi_device *dev,
+				  unsigned long context_unused)
 {
-	struct usb_device *udev = interface_to_usbdev(uinterf);
-	int i;
-	int index;
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxfast_private *devpriv;
 	int ret;
 
-	if (udev->speed != USB_SPEED_HIGH) {
-		dev_err(&uinterf->dev,
+	if (usb->speed != USB_SPEED_HIGH) {
+		dev_err(dev->class_dev,
 			"This driver needs USB 2.0 to operate. Aborting...\n");
 		return -ENODEV;
 	}
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi_: usbduxfast_: finding a free structure for "
-	       "the usb-device\n");
-#endif
-	down(&start_stop_sem);
-	/* look for a free place in the usbduxfast array */
-	index = -1;
-	for (i = 0; i < NUMUSBDUXFAST; i++) {
-		if (!usbduxfastsub[i].probed) {
-			index = i;
-			break;
-		}
-	}
 
-	/* no more space */
-	if (index == -1) {
-		dev_err(&uinterf->dev,
-			"Too many usbduxfast-devices connected.\n");
-		up(&start_stop_sem);
-		return -EMFILE;
-	}
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi_: usbduxfast: usbduxfastsub[%d] is ready to "
-	       "connect to comedi.\n", index);
-#endif
-
-	sema_init(&(usbduxfastsub[index].sem), 1);
-	/* save a pointer to the usb device */
-	usbduxfastsub[index].usbdev = udev;
+	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+	if (!devpriv)
+		return -ENOMEM;
+	dev->private = devpriv;
 
-	/* save the interface itself */
-	usbduxfastsub[index].interface = uinterf;
-	/* get the interface number from the interface */
-	usbduxfastsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
-	/*
-	 * hand the private data over to the usb subsystem
-	 * will be needed for disconnect
-	 */
-	usb_set_intfdata(uinterf, &(usbduxfastsub[index]));
+	sema_init(&devpriv->sem, 1);
+	usb_set_intfdata(intf, devpriv);
 
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi_: usbduxfast: ifnum=%d\n",
-	       usbduxfastsub[index].ifnum);
-#endif
-	/* create space for the commands going to the usb device */
-	usbduxfastsub[index].dux_commands = kmalloc(SIZEOFDUXBUFFER,
-						    GFP_KERNEL);
-	if (!usbduxfastsub[index].dux_commands) {
-		tidy_up(&(usbduxfastsub[index]));
-		up(&start_stop_sem);
-		return -ENOMEM;
-	}
-	/* create space of the instruction buffer */
-	usbduxfastsub[index].insnBuffer = kmalloc(SIZEINSNBUF, GFP_KERNEL);
-	if (!usbduxfastsub[index].insnBuffer) {
-		tidy_up(&(usbduxfastsub[index]));
-		up(&start_stop_sem);
+	devpriv->duxbuf = kmalloc(SIZEOFDUXBUF, GFP_KERNEL);
+	if (!devpriv->duxbuf)
 		return -ENOMEM;
-	}
-	/* setting to alternate setting 1: enabling bulk ep */
-	i = usb_set_interface(usbduxfastsub[index].usbdev,
-			      usbduxfastsub[index].ifnum, 1);
-	if (i < 0) {
-		dev_err(&uinterf->dev,
-			"usbduxfast%d: could not switch to alternate setting 1.\n",
-			index);
-		tidy_up(&(usbduxfastsub[index]));
-		up(&start_stop_sem);
+
+	ret = usb_set_interface(usb,
+				intf->altsetting->desc.bInterfaceNumber, 1);
+	if (ret < 0) {
+		dev_err(dev->class_dev,
+			"could not switch to alternate setting 1\n");
 		return -ENODEV;
 	}
-	usbduxfastsub[index].urbIn = usb_alloc_urb(0, GFP_KERNEL);
-	if (!usbduxfastsub[index].urbIn) {
-		dev_err(&uinterf->dev,
-			"usbduxfast%d: Could not alloc. urb\n", index);
-		tidy_up(&(usbduxfastsub[index]));
-		up(&start_stop_sem);
-		return -ENOMEM;
-	}
-	usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL);
-	if (!usbduxfastsub[index].transfer_buffer) {
-		tidy_up(&(usbduxfastsub[index]));
-		up(&start_stop_sem);
+
+	devpriv->urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!devpriv->urb) {
+		dev_err(dev->class_dev, "Could not alloc. urb\n");
 		return -ENOMEM;
 	}
-	/* we've reached the bottom of the function */
-	usbduxfastsub[index].probed = 1;
-	up(&start_stop_sem);
 
-	ret = reject_firmware_nowait(THIS_MODULE,
-				      FW_ACTION_HOTPLUG,
-				      FIRMWARE,
-				      &udev->dev,
-				      GFP_KERNEL,
-				      usbduxfastsub + index,
-				      usbduxfast_firmware_request_complete_handler);
+	devpriv->inbuf = kmalloc(SIZEINBUF, GFP_KERNEL);
+	if (!devpriv->inbuf)
+		return -ENOMEM;
 
-	if (ret) {
-		dev_err(&uinterf->dev, "could not load firmware (err=%d)\n", ret);
+	ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
+				   usbduxfast_upload_firmware, 0);
+	if (ret)
 		return ret;
-	}
 
-	dev_info(&uinterf->dev,
-		 "usbduxfast%d has been successfully initialized.\n", index);
-	/* success */
-	return 0;
+	return usbduxfast_attach_common(dev);
 }
 
-static void usbduxfast_usb_disconnect(struct usb_interface *intf)
+static void usbduxfast_detach(struct comedi_device *dev)
 {
-	struct usbduxfastsub_s *udfs = usb_get_intfdata(intf);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
+	struct usbduxfast_private *devpriv = dev->private;
 
-	if (!udfs) {
-		dev_err(&intf->dev, "disconnect called with null pointer.\n");
-		return;
-	}
-	if (udfs->usbdev != udev) {
-		dev_err(&intf->dev, "BUG! called with wrong ptr!!!\n");
+	if (!devpriv)
 		return;
+
+	down(&devpriv->sem);
+
+	usb_set_intfdata(intf, NULL);
+
+	if (devpriv->urb) {
+		/* waits until a running transfer is over */
+		usb_kill_urb(devpriv->urb);
+
+		kfree(devpriv->inbuf);
+		devpriv->inbuf = NULL;
+
+		usb_free_urb(devpriv->urb);
+		devpriv->urb = NULL;
 	}
 
-	comedi_usb_auto_unconfig(intf);
+	kfree(devpriv->duxbuf);
+	devpriv->duxbuf = NULL;
 
-	down(&start_stop_sem);
-	down(&udfs->sem);
-	tidy_up(udfs);
-	up(&udfs->sem);
-	up(&start_stop_sem);
+	devpriv->ai_cmd_running = 0;
 
-#ifdef CONFIG_COMEDI_DEBUG
-	printk(KERN_DEBUG "comedi_: usbduxfast: disconnected from the usb\n");
-#endif
+	up(&devpriv->sem);
+}
+
+static struct comedi_driver usbduxfast_driver = {
+	.driver_name	= "usbduxfast",
+	.module		= THIS_MODULE,
+	.auto_attach	= usbduxfast_auto_attach,
+	.detach		= usbduxfast_detach,
+};
+
+static int usbduxfast_usb_probe(struct usb_interface *intf,
+				const struct usb_device_id *id)
+{
+	return comedi_usb_auto_config(intf, &usbduxfast_driver, 0);
 }
 
 static const struct usb_device_id usbduxfast_usb_table[] = {
@@ -1657,12 +1152,9 @@ static const struct usb_device_id usbdux
 MODULE_DEVICE_TABLE(usb, usbduxfast_usb_table);
 
 static struct usb_driver usbduxfast_usb_driver = {
-#ifdef COMEDI_HAVE_USB_DRIVER_OWNER
-	.owner		= THIS_MODULE,
-#endif
 	.name		= "usbduxfast",
 	.probe		= usbduxfast_usb_probe,
-	.disconnect	= usbduxfast_usb_disconnect,
+	.disconnect	= comedi_usb_auto_unconfig,
 	.id_table	= usbduxfast_usb_table,
 };
 module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/usbduxsigma.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/usbduxsigma.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/usbduxsigma.c	2013-07-01 10:42:17.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/usbduxsigma.c	2013-08-31 18:02:04.000000000 -0400
@@ -1,30 +1,27 @@
 /*
-   comedi/drivers/usbdux.c
-   Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
+ * usbduxsigma.c
+ * Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
+
 /*
-Driver: usbduxsigma
-Description: University of Stirling USB DAQ & INCITE Technology Limited
-Devices: [ITL] USB-DUX (usbduxsigma.o)
-Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 8 Nov 2011
-Status: testing
-*/
+ * Driver: usbduxsigma
+ * Description: University of Stirling USB DAQ & INCITE Technology Limited
+ * Devices: (ITL) USB-DUX [usbduxsigma]
+ * Author: Bernd Porr <BerndPorr@f2s.com>
+ * Updated: 8 Nov 2011
+ * Status: testing
+ */
+
 /*
  * I must give credit here to Chris Baugher who
  * wrote the driver for AT-MIO-16d. I used some parts of this
@@ -44,9 +41,6 @@ Status: testing
  *   0.6: corrected wrong input range
  */
 
-/* generates loads of debug info */
-/* #define NOISY_DUX_DEBUGBUG */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -55,7 +49,7 @@ Status: testing
 #include <linux/usb.h>
 #include <linux/fcntl.h>
 #include <linux/compiler.h>
-#include <linux/firmware.h>
+
 #include "comedi_fc.h"
 #include "../comedidev.h"
 
@@ -63,38 +57,21 @@ Status: testing
 #define BULK_TIMEOUT 1000
 
 /* constants for "firmware" upload and download */
-#define FIRMWARE "/*(DEBLOBBED)*/"
-#define USBDUXSUB_FIRMWARE 0xA0
-#define VENDOR_DIR_IN  0xC0
-#define VENDOR_DIR_OUT 0x40
+#define FIRMWARE		"/*(DEBLOBBED)*/"
+#define FIRMWARE_MAX_LEN	0x4000
+#define USBDUXSUB_FIRMWARE	0xa0
+#define VENDOR_DIR_IN		0xc0
+#define VENDOR_DIR_OUT		0x40
 
 /* internal addresses of the 8051 processor */
 #define USBDUXSUB_CPUCS 0xE600
 
-/*
- * the minor device number, major is 180 only for debugging purposes and to
- * upload special firmware (programming the eeprom etc) which is not
- * compatible with the comedi framwork
- */
-#define USBDUXSUB_MINOR 32
-
-/* max lenghth of the transfer-buffer for software upload */
-#define TB_LEN 0x2000
-
-/* Input endpoint number: ISO/IRQ */
-#define ISOINEP           6
-
-/* Output endpoint number: ISO/IRQ */
-#define ISOOUTEP          2
-
-/* This EP sends DUX commands to USBDUX */
-#define COMMAND_OUT_EP     1
-
-/* This EP receives the DUX commands from USBDUX */
-#define COMMAND_IN_EP        8
-
-/* Output endpoint for PWM */
-#define PWM_EP         4
+/* USB endpoints */
+#define USBDUXSIGMA_CMD_OUT_EP		1	/* command output */
+#define USBDUXSIGMA_ISO_OUT_EP		2	/* analog output ISO/IRQ */
+#define USBDUXSIGMA_PWM_OUT_EP		4	/* pwm output */
+#define USBDUXSIGMA_ISO_IN_EP		6	/* analog input ISO/IRQ */
+#define USBDUXSIGMA_CMD_IN_EP		8	/* command input */
 
 /* 300Hz max frequ under PWM */
 #define MIN_PWM_PERIOD  ((long)(1E9/300))
@@ -105,6 +82,8 @@ Status: testing
 /* Number of channels (16 AD and offset)*/
 #define NUMCHANNELS 16
 
+#define USBDUXSIGMA_NUM_AO_CHAN		4
+
 /* Size of one A/D value */
 #define SIZEADIN          ((sizeof(int32_t)))
 
@@ -150,84 +129,54 @@ Status: testing
 /* must have more buffers due to buggy USB ctr */
 #define NUMOFOUTBUFFERSHIGH    10
 
-/* Total number of usbdux devices */
-#define NUMUSBDUX             16
-
-/* Analogue in subdevice */
-#define SUBDEV_AD             0
-
-/* Analogue out subdevice */
-#define SUBDEV_DA             1
-
-/* Digital I/O */
-#define SUBDEV_DIO            2
-
-/* timer aka pwm output */
-#define SUBDEV_PWM            3
-
 /* number of retries to get the right dux command */
 #define RETRIES 10
 
-/**************************************************/
-/* comedi constants */
-static const struct comedi_lrange range_usbdux_ai_range = { 1, {
-								BIP_RANGE
-								(2.65/2.0)
-								}
-};
+/* bulk transfer commands to usbduxsigma */
+#define USBBUXSIGMA_AD_CMD		0
+#define USBDUXSIGMA_DA_CMD		1
+#define USBDUXSIGMA_DIO_CFG_CMD		2
+#define USBDUXSIGMA_DIO_BITS_CMD	3
+#define USBDUXSIGMA_SINGLE_AD_CMD	4
+#define USBDUXSIGMA_PWM_ON_CMD		7
+#define USBDUXSIGMA_PWM_OFF_CMD		8
 
-/*
- * private structure of one subdevice
- */
+static const struct comedi_lrange usbduxsigma_ai_range = {
+	1, {
+		BIP_RANGE(2.65 / 2.0)
+	}
+};
 
-/*
- * This is the structure which holds all the data of
- * this driver one sub device just now: A/D
- */
-struct usbduxsub {
-	/* attached? */
-	int attached;
-	/* is it associated with a subdevice? */
-	int probed;
-	/* pointer to the usb-device */
-	struct usb_device *usbdev;
+struct usbduxsigma_private {
 	/* actual number of in-buffers */
-	int numOfInBuffers;
+	int n_ai_urbs;
 	/* actual number of out-buffers */
-	int numOfOutBuffers;
+	int n_ao_urbs;
 	/* ISO-transfer handling: buffers */
-	struct urb **urbIn;
-	struct urb **urbOut;
+	struct urb **ai_urbs;
+	struct urb **ao_urbs;
 	/* pwm-transfer handling */
-	struct urb *urbPwm;
+	struct urb *pwm_urb;
 	/* PWM period */
-	unsigned int pwmPeriod;
+	unsigned int pwm_period;
 	/* PWM internal delay for the GPIF in the FX2 */
-	uint8_t pwmDelay;
+	uint8_t pwm_delay;
 	/* size of the PWM buffer which holds the bit pattern */
-	int sizePwmBuf;
+	int pwm_buf_sz;
 	/* input buffer for the ISO-transfer */
-	int32_t *inBuffer;
+	int32_t *in_buf;
 	/* input buffer for single insn */
-	int8_t *insnBuffer;
-	/* output buffer for single DA outputs */
-	int16_t *outBuffer;
-	/* interface number */
-	int ifnum;
-	/* interface structure in 2.6 */
-	struct usb_interface *interface;
-	/* comedi device for the interrupt context */
-	struct comedi_device *comedidev;
-	/* is it USB_SPEED_HIGH or not? */
-	short int high_speed;
-	/* asynchronous command is running */
-	short int ai_cmd_running;
-	short int ao_cmd_running;
-	/* pwm is running */
-	short int pwm_cmd_running;
-	/* continuous acquisition */
-	short int ai_continuous;
-	short int ao_continuous;
+	int8_t *insn_buf;
+
+	unsigned int ao_readback[USBDUXSIGMA_NUM_AO_CHAN];
+
+	unsigned high_speed:1;
+	unsigned ai_cmd_running:1;
+	unsigned ai_continuous:1;
+	unsigned ao_cmd_running:1;
+	unsigned ao_continuous:1;
+	unsigned pwm_cmd_running:1;
+
 	/* number of samples to acquire */
 	int ai_sample_count;
 	int ao_sample_count;
@@ -246,126 +195,58 @@ struct usbduxsub {
 	struct semaphore sem;
 };
 
-/*
- * The pointer to the private usb-data of the driver is also the private data
- * for the comedi-device.  This has to be global as the usb subsystem needs
- * global variables. The other reason is that this structure must be there
- * _before_ any comedi command is issued. The usb subsystem must be initialised
- * before comedi can access it.
- */
-static struct usbduxsub usbduxsub[NUMUSBDUX];
-
-static DEFINE_SEMAPHORE(start_stop_sem);
-
-/*
- * Stops the data acquision
- * It should be safe to call this function from any context
- */
-static int usbduxsub_unlink_InURBs(struct usbduxsub *usbduxsub_tmp)
-{
-	int i = 0;
-	int err = 0;
-
-	if (usbduxsub_tmp && usbduxsub_tmp->urbIn) {
-		for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
-			if (usbduxsub_tmp->urbIn[i]) {
-				/* We wait here until all transfers have been
-				 * cancelled. */
-				usb_kill_urb(usbduxsub_tmp->urbIn[i]);
-			}
-			dev_dbg(&usbduxsub_tmp->interface->dev,
-				"comedi: usbdux: unlinked InURB %d, err=%d\n",
-				i, err);
-		}
-	}
-	return err;
-}
-
-/*
- * This will stop a running acquisition operation
- * Is called from within this driver from both the
- * interrupt context and from comedi
- */
-static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
+static void usbduxsigma_ai_stop(struct comedi_device *dev, int do_unlink)
 {
-	int ret = 0;
-
-	if (!this_usbduxsub) {
-		pr_err("comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n");
-		return -EFAULT;
-	}
-	dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n");
+	struct usbduxsigma_private *devpriv = dev->private;
 
 	if (do_unlink) {
-		/* stop aquistion */
-		ret = usbduxsub_unlink_InURBs(this_usbduxsub);
-	}
+		int i;
 
-	this_usbduxsub->ai_cmd_running = 0;
+		for (i = 0; i < devpriv->n_ai_urbs; i++) {
+			if (devpriv->ai_urbs[i])
+				usb_kill_urb(devpriv->ai_urbs[i]);
+		}
+	}
 
-	return ret;
+	devpriv->ai_cmd_running = 0;
 }
 
-/*
- * This will cancel a running acquisition operation.
- * This is called by comedi but never from inside the driver.
- */
-static int usbdux_ai_cancel(struct comedi_device *dev,
-			    struct comedi_subdevice *s)
+static int usbduxsigma_ai_cancel(struct comedi_device *dev,
+				 struct comedi_subdevice *s)
 {
-	struct usbduxsub *this_usbduxsub;
-	int res = 0;
-
-	/* force unlink of all urbs */
-	this_usbduxsub = dev->private;
-	if (!this_usbduxsub)
-		return -EFAULT;
+	struct usbduxsigma_private *devpriv = dev->private;
 
-	dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_cancel\n");
+	down(&devpriv->sem);
+	/* unlink only if it is really running */
+	usbduxsigma_ai_stop(dev, devpriv->ai_cmd_running);
+	up(&devpriv->sem);
 
-	/* prevent other CPUs from submitting new commands just now */
-	down(&this_usbduxsub->sem);
-	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
-	}
-	/* unlink only if the urb really has been submitted */
-	res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->ai_cmd_running);
-	up(&this_usbduxsub->sem);
-	return res;
+	return 0;
 }
 
-/* analogue IN - interrupt service routine */
-static void usbduxsub_ai_IsocIrq(struct urb *urb)
+static void usbduxsigma_ai_urb_complete(struct urb *urb)
 {
-	int i, err, n;
-	struct usbduxsub *this_usbduxsub;
-	struct comedi_device *this_comedidev;
-	struct comedi_subdevice *s;
-	int32_t v;
+	struct comedi_device *dev = urb->context;
+	struct usbduxsigma_private *devpriv = dev->private;
+	struct comedi_subdevice *s = dev->read_subdev;
 	unsigned int dio_state;
-
-	/* the context variable points to the comedi device */
-	this_comedidev = urb->context;
-	/* the private structure of the subdevice is struct usbduxsub */
-	this_usbduxsub = this_comedidev->private;
-	/* subdevice which is the AD converter */
-	s = &this_comedidev->subdevices[SUBDEV_AD];
+	int32_t val;
+	int ret;
+	int i;
 
 	/* first we test if something unusual has just happened */
 	switch (urb->status) {
 	case 0:
 		/* copy the result in the transfer buffer */
-		memcpy(this_usbduxsub->inBuffer,
-		       urb->transfer_buffer, SIZEINBUF);
+		memcpy(devpriv->in_buf, urb->transfer_buffer, SIZEINBUF);
 		break;
 	case -EILSEQ:
-		/* error in the ISOchronous data */
-		/* we don't copy the data into the transfer buffer */
-		/* and recycle the last data byte */
-		dev_dbg(&urb->dev->dev,
-			"comedi%d: usbdux: CRC error in ISO IN stream.\n",
-			this_usbduxsub->comedidev->minor);
+		/*
+		 * error in the ISOchronous data
+		 * we don't copy the data into the transfer buffer
+		 * and recycle the last data byte
+		 */
+		dev_dbg(dev->class_dev, "CRC error in ISO IN stream\n");
 
 		break;
 
@@ -374,185 +255,127 @@ static void usbduxsub_ai_IsocIrq(struct
 	case -ESHUTDOWN:
 	case -ECONNABORTED:
 		/* happens after an unlink command */
-		if (this_usbduxsub->ai_cmd_running) {
-			/* we are still running a command */
-			/* tell this comedi */
-			s->async->events |= COMEDI_CB_EOA;
-			s->async->events |= COMEDI_CB_ERROR;
-			comedi_event(this_usbduxsub->comedidev, s);
-			/* stop the transfer w/o unlink */
-			usbdux_ai_stop(this_usbduxsub, 0);
+		if (devpriv->ai_cmd_running) {
+			usbduxsigma_ai_stop(dev, 0);	/* w/o unlink */
+			/* we are still running a command, tell comedi */
+			s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
+			comedi_event(dev, s);
 		}
 		return;
 
 	default:
-		/* a real error on the bus */
-		/* pass error to comedi if we are really running a command */
-		if (this_usbduxsub->ai_cmd_running) {
-			dev_err(&urb->dev->dev,
-				"Non-zero urb status received in ai intr "
-				"context: %d\n", urb->status);
-			s->async->events |= COMEDI_CB_EOA;
-			s->async->events |= COMEDI_CB_ERROR;
-			comedi_event(this_usbduxsub->comedidev, s);
-			/* don't do an unlink here */
-			usbdux_ai_stop(this_usbduxsub, 0);
+		/*
+		 * a real error on the bus
+		 * pass error to comedi if we are really running a command
+		 */
+		if (devpriv->ai_cmd_running) {
+			dev_err(dev->class_dev,
+				"%s: non-zero urb status (%d)\n",
+				__func__, urb->status);
+			usbduxsigma_ai_stop(dev, 0);	/* w/o unlink */
+			s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
+			comedi_event(dev, s);
 		}
 		return;
 	}
 
-	/*
-	 * at this point we are reasonably sure that nothing dodgy has happened
-	 * are we running a command?
-	 */
-	if (unlikely((!(this_usbduxsub->ai_cmd_running)))) {
-		/*
-		 * not running a command, do not continue execution if no
-		 * asynchronous command is running in particular not resubmit
-		 */
+	if (unlikely(!devpriv->ai_cmd_running))
 		return;
-	}
 
-	urb->dev = this_usbduxsub->usbdev;
+	urb->dev = comedi_to_usb_dev(dev);
 
-	/* resubmit the urb */
-	err = usb_submit_urb(urb, GFP_ATOMIC);
-	if (unlikely(err < 0)) {
-		dev_err(&urb->dev->dev,
-			"comedi_: urb resubmit failed in int-context!"
-			"err=%d\n",
-			err);
-		if (err == -EL2NSYNC)
-			dev_err(&urb->dev->dev,
-				"buggy USB host controller or bug in IRQ "
-				"handler!\n");
-		s->async->events |= COMEDI_CB_EOA;
-		s->async->events |= COMEDI_CB_ERROR;
-		comedi_event(this_usbduxsub->comedidev, s);
-		/* don't do an unlink here */
-		usbdux_ai_stop(this_usbduxsub, 0);
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (unlikely(ret < 0)) {
+		dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
+			__func__, ret);
+		if (ret == -EL2NSYNC)
+			dev_err(dev->class_dev,
+				"buggy USB host controller or bug in IRQ handler\n");
+		usbduxsigma_ai_stop(dev, 0);	/* w/o unlink */
+		s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
+		comedi_event(dev, s);
 		return;
 	}
 
 	/* get the state of the dio pins to allow external trigger */
-	dio_state = be32_to_cpu(this_usbduxsub->inBuffer[0]);
+	dio_state = be32_to_cpu(devpriv->in_buf[0]);
 
-	this_usbduxsub->ai_counter--;
-	if (likely(this_usbduxsub->ai_counter > 0))
+	devpriv->ai_counter--;
+	if (likely(devpriv->ai_counter > 0))
 		return;
 
 	/* timer zero, transfer measurements to comedi */
-	this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
+	devpriv->ai_counter = devpriv->ai_timer;
 
-	/* test, if we transmit only a fixed number of samples */
-	if (!(this_usbduxsub->ai_continuous)) {
+	if (!devpriv->ai_continuous) {
 		/* not continuous, fixed number of samples */
-		this_usbduxsub->ai_sample_count--;
-		/* all samples received? */
-		if (this_usbduxsub->ai_sample_count < 0) {
-			/* prevent a resubmit next time */
-			usbdux_ai_stop(this_usbduxsub, 0);
-			/* say comedi that the acquistion is over */
+		devpriv->ai_sample_count--;
+		if (devpriv->ai_sample_count < 0) {
+			usbduxsigma_ai_stop(dev, 0);	/* w/o unlink */
+			/* acquistion is over, tell comedi */
 			s->async->events |= COMEDI_CB_EOA;
-			comedi_event(this_usbduxsub->comedidev, s);
+			comedi_event(dev, s);
 			return;
 		}
 	}
+
 	/* get the data from the USB bus and hand it over to comedi */
-	n = s->async->cmd.chanlist_len;
-	for (i = 0; i < n; i++) {
+	for (i = 0; i < s->async->cmd.chanlist_len; i++) {
 		/* transfer data, note first byte is the DIO state */
-		v = be32_to_cpu(this_usbduxsub->inBuffer[i+1]);
-		/* strip status byte */
-		v = v & 0x00ffffff;
-		/* convert to unsigned */
-		v = v ^ 0x00800000;
-		/* write the byte to the buffer */
-		err = cfc_write_array_to_buffer(s, &v, sizeof(uint32_t));
-		if (unlikely(err == 0)) {
+		val = be32_to_cpu(devpriv->in_buf[i+1]);
+		val &= 0x00ffffff;	/* strip status byte */
+		val ^= 0x00800000;	/* convert to unsigned */
+
+		ret = cfc_write_array_to_buffer(s, &val, sizeof(uint32_t));
+		if (unlikely(ret == 0)) {
 			/* buffer overflow */
-			usbdux_ai_stop(this_usbduxsub, 0);
+			usbduxsigma_ai_stop(dev, 0);	/* w/o unlink */
 			return;
 		}
 	}
 	/* tell comedi that data is there */
-	s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
-	comedi_event(this_usbduxsub->comedidev, s);
+	s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+	comedi_event(dev, s);
 }
 
-static int usbduxsub_unlink_OutURBs(struct usbduxsub *usbduxsub_tmp)
+static void usbduxsigma_ao_stop(struct comedi_device *dev, int do_unlink)
 {
-	int i = 0;
-	int err = 0;
+	struct usbduxsigma_private *devpriv = dev->private;
 
-	if (usbduxsub_tmp && usbduxsub_tmp->urbOut) {
-		for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
-			if (usbduxsub_tmp->urbOut[i])
-				usb_kill_urb(usbduxsub_tmp->urbOut[i]);
+	if (do_unlink) {
+		int i;
 
-			dev_dbg(&usbduxsub_tmp->interface->dev,
-				"comedi: usbdux: unlinked OutURB %d: res=%d\n",
-				i, err);
+		for (i = 0; i < devpriv->n_ao_urbs; i++) {
+			if (devpriv->ao_urbs[i])
+				usb_kill_urb(devpriv->ao_urbs[i]);
 		}
 	}
-	return err;
-}
 
-/* This will cancel a running acquisition operation
- * in any context.
- */
-static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
-{
-	int ret = 0;
-
-	if (!this_usbduxsub)
-		return -EFAULT;
-	dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ao_cancel\n");
-
-	if (do_unlink)
-		ret = usbduxsub_unlink_OutURBs(this_usbduxsub);
-
-	this_usbduxsub->ao_cmd_running = 0;
-
-	return ret;
+	devpriv->ao_cmd_running = 0;
 }
 
-/* force unlink, is called by comedi */
-static int usbdux_ao_cancel(struct comedi_device *dev,
-			    struct comedi_subdevice *s)
+static int usbduxsigma_ao_cancel(struct comedi_device *dev,
+				 struct comedi_subdevice *s)
 {
-	struct usbduxsub *this_usbduxsub = dev->private;
-	int res = 0;
-
-	if (!this_usbduxsub)
-		return -EFAULT;
+	struct usbduxsigma_private *devpriv = dev->private;
 
-	/* prevent other CPUs from submitting a command just now */
-	down(&this_usbduxsub->sem);
-	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
-	}
+	down(&devpriv->sem);
 	/* unlink only if it is really running */
-	res = usbdux_ao_stop(this_usbduxsub, this_usbduxsub->ao_cmd_running);
-	up(&this_usbduxsub->sem);
-	return res;
+	usbduxsigma_ao_stop(dev, devpriv->ao_cmd_running);
+	up(&devpriv->sem);
+
+	return 0;
 }
 
-static void usbduxsub_ao_IsocIrq(struct urb *urb)
+static void usbduxsigma_ao_urb_complete(struct urb *urb)
 {
-	int i, ret;
+	struct comedi_device *dev = urb->context;
+	struct usbduxsigma_private *devpriv = dev->private;
+	struct comedi_subdevice *s = dev->write_subdev;
 	uint8_t *datap;
-	struct usbduxsub *this_usbduxsub;
-	struct comedi_device *this_comedidev;
-	struct comedi_subdevice *s;
-
-	/* the context variable points to the subdevice */
-	this_comedidev = urb->context;
-	/* the private structure of the subdevice is struct usbduxsub */
-	this_usbduxsub = this_comedidev->private;
-
-	s = &this_comedidev->subdevices[SUBDEV_DA];
+	int len;
+	int ret;
+	int i;
 
 	switch (urb->status) {
 	case 0:
@@ -563,347 +386,141 @@ static void usbduxsub_ao_IsocIrq(struct
 	case -ENOENT:
 	case -ESHUTDOWN:
 	case -ECONNABORTED:
-		/* after an unlink command, unplug, ... etc */
-		/* no unlink needed here. Already shutting down. */
-		if (this_usbduxsub->ao_cmd_running) {
+		/* happens after an unlink command */
+		if (devpriv->ao_cmd_running) {
+			usbduxsigma_ao_stop(dev, 0);	/* w/o unlink */
 			s->async->events |= COMEDI_CB_EOA;
-			comedi_event(this_usbduxsub->comedidev, s);
-			usbdux_ao_stop(this_usbduxsub, 0);
+			comedi_event(dev, s);
 		}
 		return;
 
 	default:
 		/* a real error */
-		if (this_usbduxsub->ao_cmd_running) {
-			dev_err(&urb->dev->dev,
-				"comedi_: Non-zero urb status received in ao "
-				"intr context: %d\n", urb->status);
-			s->async->events |= COMEDI_CB_ERROR;
-			s->async->events |= COMEDI_CB_EOA;
-			comedi_event(this_usbduxsub->comedidev, s);
-			/* we do an unlink if we are in the high speed mode */
-			usbdux_ao_stop(this_usbduxsub, 0);
+		if (devpriv->ao_cmd_running) {
+			dev_err(dev->class_dev,
+				"%s: non-zero urb status (%d)\n",
+				__func__, urb->status);
+			usbduxsigma_ao_stop(dev, 0);	/* w/o unlink */
+			s->async->events |= (COMEDI_CB_ERROR | COMEDI_CB_EOA);
+			comedi_event(dev, s);
 		}
 		return;
 	}
 
-	/* are we actually running? */
-	if (!(this_usbduxsub->ao_cmd_running))
+	if (!devpriv->ao_cmd_running)
 		return;
 
-	/* normal operation: executing a command in this subdevice */
-	this_usbduxsub->ao_counter--;
-	if ((int)this_usbduxsub->ao_counter <= 0) {
-		/* timer zero */
-		this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
+	devpriv->ao_counter--;
+	if ((int)devpriv->ao_counter <= 0) {
+		/* timer zero, transfer from comedi */
+		devpriv->ao_counter = devpriv->ao_timer;
 
-		/* handle non continuous acquisition */
-		if (!(this_usbduxsub->ao_continuous)) {
-			/* fixed number of samples */
-			this_usbduxsub->ao_sample_count--;
-			if (this_usbduxsub->ao_sample_count < 0) {
-				/* all samples transmitted */
-				usbdux_ao_stop(this_usbduxsub, 0);
+		if (!devpriv->ao_continuous) {
+			/* not continuous, fixed number of samples */
+			devpriv->ao_sample_count--;
+			if (devpriv->ao_sample_count < 0) {
+				usbduxsigma_ao_stop(dev, 0);	/* w/o unlink */
+				/* acquistion is over, tell comedi */
 				s->async->events |= COMEDI_CB_EOA;
-				comedi_event(this_usbduxsub->comedidev, s);
-				/* no resubmit of the urb */
+				comedi_event(dev, s);
 				return;
 			}
 		}
+
 		/* transmit data to the USB bus */
-		((uint8_t *) (urb->transfer_buffer))[0] =
-		    s->async->cmd.chanlist_len;
-		for (i = 0; i < s->async->cmd.chanlist_len; i++) {
-			short temp;
-			if (i >= NUMOUTCHANNELS)
-				break;
+		datap = urb->transfer_buffer;
+		len = s->async->cmd.chanlist_len;
+		*datap++ = len;
+		for (i = 0; i < len; i++) {
+			unsigned int chan = devpriv->dac_commands[i];
+			short val;
 
-			/* pointer to the DA */
-			datap =
-			    (&(((uint8_t *) urb->transfer_buffer)[i * 2 + 1]));
-			/* get the data from comedi */
-			ret = comedi_buf_get(s->async, &temp);
-			datap[0] = temp;
-			datap[1] = this_usbduxsub->dac_commands[i];
-			/* printk("data[0]=%x, data[1]=%x, data[2]=%x\n", */
-			/* datap[0],datap[1],datap[2]); */
+			ret = comedi_buf_get(s->async, &val);
 			if (ret < 0) {
-				dev_err(&urb->dev->dev,
-					"comedi: buffer underflow\n");
-				s->async->events |= COMEDI_CB_EOA;
-				s->async->events |= COMEDI_CB_OVERFLOW;
+				dev_err(dev->class_dev, "buffer underflow\n");
+				s->async->events |= (COMEDI_CB_EOA |
+						     COMEDI_CB_OVERFLOW);
 			}
-			/* transmit data to comedi */
+			*datap++ = val;
+			*datap++ = chan;
+			devpriv->ao_readback[chan] = val;
+
 			s->async->events |= COMEDI_CB_BLOCK;
-			comedi_event(this_usbduxsub->comedidev, s);
+			comedi_event(dev, s);
 		}
 	}
+
 	urb->transfer_buffer_length = SIZEOUTBUF;
-	urb->dev = this_usbduxsub->usbdev;
+	urb->dev = comedi_to_usb_dev(dev);
 	urb->status = 0;
-	if (this_usbduxsub->ao_cmd_running) {
-		if (this_usbduxsub->high_speed) {
-			/* uframes */
-			urb->interval = 8;
-		} else {
-			/* frames */
-			urb->interval = 1;
-		}
-		urb->number_of_packets = 1;
-		urb->iso_frame_desc[0].offset = 0;
-		urb->iso_frame_desc[0].length = SIZEOUTBUF;
-		urb->iso_frame_desc[0].status = 0;
-		ret = usb_submit_urb(urb, GFP_ATOMIC);
-		if (ret < 0) {
-			dev_err(&urb->dev->dev,
-				"comedi_: ao urb resubm failed in int-cont. "
-				"ret=%d", ret);
-			if (ret == EL2NSYNC)
-				dev_err(&urb->dev->dev,
-					"buggy USB host controller or bug in "
-					"IRQ handling!\n");
-
-			s->async->events |= COMEDI_CB_EOA;
-			s->async->events |= COMEDI_CB_ERROR;
-			comedi_event(this_usbduxsub->comedidev, s);
-			/* don't do an unlink here */
-			usbdux_ao_stop(this_usbduxsub, 0);
-		}
-	}
-}
-
-static int usbduxsub_start(struct usbduxsub *usbduxsub)
-{
-	int errcode = 0;
-	uint8_t *local_transfer_buffer;
-
-	local_transfer_buffer = kmalloc(16, GFP_KERNEL);
-	if (!local_transfer_buffer)
-		return -ENOMEM;
-
-	/* 7f92 to zero */
-	local_transfer_buffer[0] = 0;
-	errcode = usb_control_msg(usbduxsub->usbdev,
-				  /* create a pipe for a control transfer */
-				  usb_sndctrlpipe(usbduxsub->usbdev, 0),
-				  /* bRequest, "Firmware" */
-				  USBDUXSUB_FIRMWARE,
-				  /* bmRequestType */
-				  VENDOR_DIR_OUT,
-				  /* Value */
-				  USBDUXSUB_CPUCS,
-				  /* Index */
-				  0x0000,
-				  /* address of the transfer buffer */
-				  local_transfer_buffer,
-				  /* Length */
-				  1,
-				  /* Timeout */
-				  BULK_TIMEOUT);
-	if (errcode < 0)
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: control msg failed (start)\n");
-
-	kfree(local_transfer_buffer);
-	return errcode;
-}
-
-static int usbduxsub_stop(struct usbduxsub *usbduxsub)
-{
-	int errcode = 0;
-	uint8_t *local_transfer_buffer;
-
-	local_transfer_buffer = kmalloc(16, GFP_KERNEL);
-	if (!local_transfer_buffer)
-		return -ENOMEM;
-
-	/* 7f92 to one */
-	local_transfer_buffer[0] = 1;
-	errcode = usb_control_msg(usbduxsub->usbdev,
-				  usb_sndctrlpipe(usbduxsub->usbdev, 0),
-				  /* bRequest, "Firmware" */
-				  USBDUXSUB_FIRMWARE,
-				  /* bmRequestType */
-				  VENDOR_DIR_OUT,
-				  /* Value */
-				  USBDUXSUB_CPUCS,
-				  /* Index */
-				  0x0000, local_transfer_buffer,
-				  /* Length */
-				  1,
-				  /* Timeout */
-				  BULK_TIMEOUT);
-	if (errcode < 0)
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: control msg failed (stop)\n");
-
-	kfree(local_transfer_buffer);
-	return errcode;
-}
-
-static int usbduxsub_upload(struct usbduxsub *usbduxsub,
-			    uint8_t *local_transfer_buffer,
-			    unsigned int startAddr, unsigned int len)
-{
-	int errcode;
-
-	errcode = usb_control_msg(usbduxsub->usbdev,
-				  usb_sndctrlpipe(usbduxsub->usbdev, 0),
-				  /* brequest, firmware */
-				  USBDUXSUB_FIRMWARE,
-				  /* bmRequestType */
-				  VENDOR_DIR_OUT,
-				  /* value */
-				  startAddr,
-				  /* index */
-				  0x0000,
-				  /* our local safe buffer */
-				  local_transfer_buffer,
-				  /* length */
-				  len,
-				  /* timeout */
-				  BULK_TIMEOUT);
-	dev_dbg(&usbduxsub->interface->dev, "comedi_: result=%d\n", errcode);
-	if (errcode < 0) {
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: upload failed\n");
-		return errcode;
-	}
-	return 0;
-}
-
-/* the FX2LP has twice as much as the standard FX2 */
-#define FIRMWARE_MAX_LEN 0x4000
-
-static int firmwareUpload(struct usbduxsub *usbduxsub,
-			  const u8 *firmwareBinary, int sizeFirmware)
-{
-	int ret;
-	uint8_t *fwBuf;
-
-	if (!firmwareBinary)
-		return 0;
-
-	if (sizeFirmware > FIRMWARE_MAX_LEN) {
-		dev_err(&usbduxsub->interface->dev,
-			"usbduxsigma firmware binary it too large for FX2.\n");
-		return -ENOMEM;
-	}
-
-	/* we generate a local buffer for the firmware */
-	fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL);
-	if (!fwBuf) {
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: mem alloc for firmware failed\n");
-		return -ENOMEM;
-	}
-
-	ret = usbduxsub_stop(usbduxsub);
-	if (ret < 0) {
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: can not stop firmware\n");
-		kfree(fwBuf);
-		return ret;
-	}
-
-	ret = usbduxsub_upload(usbduxsub, fwBuf, 0, sizeFirmware);
-	if (ret < 0) {
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: firmware upload failed\n");
-		kfree(fwBuf);
-		return ret;
-	}
-	ret = usbduxsub_start(usbduxsub);
+	if (devpriv->high_speed)
+		urb->interval = 8;	/* uframes */
+	else
+		urb->interval = 1;	/* frames */
+	urb->number_of_packets = 1;
+	urb->iso_frame_desc[0].offset = 0;
+	urb->iso_frame_desc[0].length = SIZEOUTBUF;
+	urb->iso_frame_desc[0].status = 0;
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
 	if (ret < 0) {
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: can not start firmware\n");
-		kfree(fwBuf);
-		return ret;
+		dev_err(dev->class_dev,
+			"%s: urb resubmit failed (%d)\n",
+			__func__, ret);
+		if (ret == EL2NSYNC)
+			dev_err(dev->class_dev,
+				"buggy USB host controller or bug in IRQ handler\n");
+		usbduxsigma_ao_stop(dev, 0);	/* w/o unlink */
+		s->async->events |= (COMEDI_CB_EOA | COMEDI_CB_ERROR);
+		comedi_event(dev, s);
 	}
-	kfree(fwBuf);
-	return 0;
 }
 
-static int usbduxsub_submit_InURBs(struct usbduxsub *usbduxsub)
+static int usbduxsigma_submit_urbs(struct comedi_device *dev,
+				   struct urb **urbs, int num_urbs,
+				   int input_urb)
 {
-	int i, errFlag;
-
-	if (!usbduxsub)
-		return -EFAULT;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxsigma_private *devpriv = dev->private;
+	struct urb *urb;
+	int ret;
+	int i;
 
 	/* Submit all URBs and start the transfer on the bus */
-	for (i = 0; i < usbduxsub->numOfInBuffers; i++) {
-		/* in case of a resubmission after an unlink... */
-		usbduxsub->urbIn[i]->interval = usbduxsub->ai_interval;
-		usbduxsub->urbIn[i]->context = usbduxsub->comedidev;
-		usbduxsub->urbIn[i]->dev = usbduxsub->usbdev;
-		usbduxsub->urbIn[i]->status = 0;
-		usbduxsub->urbIn[i]->transfer_flags = URB_ISO_ASAP;
-		dev_dbg(&usbduxsub->interface->dev,
-			"comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n",
-			usbduxsub->comedidev->minor, i,
-			(usbduxsub->urbIn[i]->context),
-			(usbduxsub->urbIn[i]->dev),
-			(usbduxsub->urbIn[i]->interval));
-		errFlag = usb_submit_urb(usbduxsub->urbIn[i], GFP_ATOMIC);
-		if (errFlag) {
-			dev_err(&usbduxsub->interface->dev,
-				"comedi_: ai: usb_submit_urb(%d) error %d\n",
-				i, errFlag);
-			return errFlag;
-		}
-	}
-	return 0;
-}
-
-static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub)
-{
-	int i, errFlag;
-
-	if (!usbduxsub)
-		return -EFAULT;
+	for (i = 0; i < num_urbs; i++) {
+		urb = urbs[i];
 
-	for (i = 0; i < usbduxsub->numOfOutBuffers; i++) {
-		dev_dbg(&usbduxsub->interface->dev,
-			"comedi_: submitting out-urb[%d]\n", i);
 		/* in case of a resubmission after an unlink... */
-		usbduxsub->urbOut[i]->context = usbduxsub->comedidev;
-		usbduxsub->urbOut[i]->dev = usbduxsub->usbdev;
-		usbduxsub->urbOut[i]->status = 0;
-		usbduxsub->urbOut[i]->transfer_flags = URB_ISO_ASAP;
-		errFlag = usb_submit_urb(usbduxsub->urbOut[i], GFP_ATOMIC);
-		if (errFlag) {
-			dev_err(&usbduxsub->interface->dev,
-				"comedi_: ao: usb_submit_urb(%d) error %d\n",
-				i, errFlag);
-			return errFlag;
-		}
+		if (input_urb)
+			urb->interval = devpriv->ai_interval;
+		urb->context = dev;
+		urb->dev = usb;
+		urb->status = 0;
+		urb->transfer_flags = URB_ISO_ASAP;
+
+		ret = usb_submit_urb(urb, GFP_ATOMIC);
+		if (ret)
+			return ret;
 	}
 	return 0;
 }
 
-static int chanToInterval(int nChannels)
+static int usbduxsigma_chans_to_interval(int num_chan)
 {
-	if (nChannels <= 2)
-		/* 4kHz */
-		return 2;
-	if (nChannels <= 8)
-		/* 2kHz */
-		return 4;
-	/* 1kHz */
-	return 8;
+	if (num_chan <= 2)
+		return 2;	/* 4kHz */
+	if (num_chan <= 8)
+		return 4;	/* 2kHz */
+	return 8;		/* 1kHz */
 }
 
-static int usbdux_ai_cmdtest(struct comedi_device *dev,
-			     struct comedi_subdevice *s,
-			     struct comedi_cmd *cmd)
+static int usbduxsigma_ai_cmdtest(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  struct comedi_cmd *cmd)
 {
-	struct usbduxsub *this_usbduxsub = dev->private;
-	int err = 0, i;
-	unsigned int tmpTimer;
-
-	if (!(this_usbduxsub->probed))
-		return -ENODEV;
+	struct usbduxsigma_private *devpriv = dev->private;
+	int high_speed = devpriv->high_speed;
+	int interval = usbduxsigma_chans_to_interval(cmd->chanlist_len);
+	int err = 0;
 
 	/* Step 1 : check if triggers are trivially valid */
 
@@ -934,34 +551,28 @@ static int usbdux_ai_cmdtest(struct come
 		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
 
 	if (cmd->scan_begin_src == TRIG_TIMER) {
-		if (this_usbduxsub->high_speed) {
+		unsigned int tmp;
+
+		if (high_speed) {
 			/*
 			 * In high speed mode microframes are possible.
 			 * However, during one microframe we can roughly
 			 * sample two channels. Thus, the more channels
 			 * are in the channel list the more time we need.
 			 */
-			i = chanToInterval(cmd->chanlist_len);
 			err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
-							 (1000000 / 8 * i));
-			/* now calc the real sampling rate with all the
-			 * rounding errors */
-			tmpTimer =
-			    ((unsigned int)(cmd->scan_begin_arg / 125000)) *
-			    125000;
+						(1000000 / 8 * interval));
+
+			tmp = (cmd->scan_begin_arg / 125000) * 125000;
 		} else {
 			/* full speed */
 			/* 1kHz scans every USB frame */
 			err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
 							 1000000);
-			/*
-			 * calc the real sampling rate with the rounding errors
-			 */
-			tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
-						   1000000)) * 1000000;
+
+			tmp = (cmd->scan_begin_arg / 1000000) * 1000000;
 		}
-		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
-						tmpTimer);
+		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
 	}
 
 	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
@@ -976,6 +587,37 @@ static int usbdux_ai_cmdtest(struct come
 	if (err)
 		return 3;
 
+	/* Step 4: fix up any arguments */
+
+	if (high_speed) {
+		/*
+		 * every 2 channels get a time window of 125us. Thus, if we
+		 * sample all 16 channels we need 1ms. If we sample only one
+		 * channel we need only 125us
+		 */
+		devpriv->ai_interval = interval;
+		devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval);
+	} else {
+		/* interval always 1ms */
+		devpriv->ai_interval = 1;
+		devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
+	}
+	if (devpriv->ai_timer < 1)
+		err |= -EINVAL;
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		/* data arrives as one packet */
+		devpriv->ai_sample_count = cmd->stop_arg;
+		devpriv->ai_continuous = 0;
+	} else {
+		/* continuous acquisition */
+		devpriv->ai_continuous = 1;
+		devpriv->ai_sample_count = 0;
+	}
+
+	if (err)
+		return 4;
+
 	return 0;
 }
 
@@ -993,536 +635,278 @@ static void create_adc_command(unsigned
 		(*muxsg1) = (*muxsg1) | (1 << (chan-8));
 }
 
-
-/* bulk transfers to usbdux */
-
-#define SENDADCOMMANDS            0
-#define SENDDACOMMANDS            1
-#define SENDDIOCONFIGCOMMAND      2
-#define SENDDIOBITSCOMMAND        3
-#define SENDSINGLEAD              4
-#define SENDPWMON                 7
-#define SENDPWMOFF                8
-
-static int send_dux_commands(struct usbduxsub *this_usbduxsub, int cmd_type)
+static int usbbuxsigma_send_cmd(struct comedi_device *dev, int cmd_type)
 {
-	int result, nsent;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxsigma_private *devpriv = dev->private;
+	int nsent;
 
-	this_usbduxsub->dux_commands[0] = cmd_type;
-#ifdef NOISY_DUX_DEBUGBUG
-	printk(KERN_DEBUG "comedi%d: usbdux: dux_commands: ",
-	       this_usbduxsub->comedidev->minor);
-	for (result = 0; result < SIZEOFDUXBUFFER; result++)
-		printk(" %02x", this_usbduxsub->dux_commands[result]);
-	printk("\n");
-#endif
-	result = usb_bulk_msg(this_usbduxsub->usbdev,
-			      usb_sndbulkpipe(this_usbduxsub->usbdev,
-					      COMMAND_OUT_EP),
-			      this_usbduxsub->dux_commands, SIZEOFDUXBUFFER,
-			      &nsent, BULK_TIMEOUT);
-	if (result < 0)
-		dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
-			"could not transmit dux_command to the usb-device, "
-			"err=%d\n", this_usbduxsub->comedidev->minor, result);
+	devpriv->dux_commands[0] = cmd_type;
 
-	return result;
+	return usb_bulk_msg(usb, usb_sndbulkpipe(usb, USBDUXSIGMA_CMD_OUT_EP),
+			    devpriv->dux_commands, SIZEOFDUXBUFFER,
+			    &nsent, BULK_TIMEOUT);
 }
 
-static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
+static int usbduxsigma_receive_cmd(struct comedi_device *dev, int command)
 {
-	int result = (-EFAULT);
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxsigma_private *devpriv = dev->private;
 	int nrec;
+	int ret;
 	int i;
 
 	for (i = 0; i < RETRIES; i++) {
-		result = usb_bulk_msg(this_usbduxsub->usbdev,
-				      usb_rcvbulkpipe(this_usbduxsub->usbdev,
-						      COMMAND_IN_EP),
-				      this_usbduxsub->insnBuffer, SIZEINSNBUF,
-				      &nrec, BULK_TIMEOUT);
-		if (result < 0) {
-			dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
-				"insn: USB error %d "
-				"while receiving DUX command"
-				"\n", this_usbduxsub->comedidev->minor,
-				result);
-			return result;
-		}
-		if (this_usbduxsub->insnBuffer[0] == command)
-			return result;
+		ret = usb_bulk_msg(usb,
+				   usb_rcvbulkpipe(usb, USBDUXSIGMA_CMD_IN_EP),
+				   devpriv->insn_buf, SIZEINSNBUF,
+				   &nrec, BULK_TIMEOUT);
+		if (ret < 0)
+			return ret;
+
+		if (devpriv->insn_buf[0] == command)
+			return 0;
 	}
-	/* this is only reached if the data has been requested a couple of
-	 * times */
-	dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: "
-		"wrong data returned from firmware: want %d, got %d.\n",
-		this_usbduxsub->comedidev->minor, command,
-		this_usbduxsub->insnBuffer[0]);
+	/*
+	 * This is only reached if the data has been requested a
+	 * couple of times and the command was not received.
+	 */
 	return -EFAULT;
 }
 
-static int usbdux_ai_inttrig(struct comedi_device *dev,
-			     struct comedi_subdevice *s, unsigned int trignum)
+static int usbduxsigma_ai_inttrig(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  unsigned int trignum)
 {
+	struct usbduxsigma_private *devpriv = dev->private;
 	int ret;
-	struct usbduxsub *this_usbduxsub = dev->private;
-	if (!this_usbduxsub)
-		return -EFAULT;
 
-	down(&this_usbduxsub->sem);
-	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
-	}
-	dev_dbg(&this_usbduxsub->interface->dev,
-		"comedi%d: usbdux_ai_inttrig\n", dev->minor);
-
-	if (trignum != 0) {
-		dev_err(&this_usbduxsub->interface->dev,
-			"comedi%d: usbdux_ai_inttrig: invalid trignum\n",
-			dev->minor);
-		up(&this_usbduxsub->sem);
+	if (trignum != 0)
 		return -EINVAL;
-	}
-	if (!(this_usbduxsub->ai_cmd_running)) {
-		this_usbduxsub->ai_cmd_running = 1;
-		ret = usbduxsub_submit_InURBs(this_usbduxsub);
+
+	down(&devpriv->sem);
+	if (!devpriv->ai_cmd_running) {
+		ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
+					      devpriv->n_ai_urbs, 1);
 		if (ret < 0) {
-			dev_err(&this_usbduxsub->interface->dev,
-				"comedi%d: usbdux_ai_inttrig: "
-				"urbSubmit: err=%d\n", dev->minor, ret);
-			this_usbduxsub->ai_cmd_running = 0;
-			up(&this_usbduxsub->sem);
+			up(&devpriv->sem);
 			return ret;
 		}
+		devpriv->ai_cmd_running = 1;
 		s->async->inttrig = NULL;
-	} else {
-		dev_err(&this_usbduxsub->interface->dev,
-			"comedi%d: ai_inttrig but acqu is already running\n",
-			dev->minor);
 	}
-	up(&this_usbduxsub->sem);
+	up(&devpriv->sem);
+
 	return 1;
 }
 
-static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+static int usbduxsigma_ai_cmd(struct comedi_device *dev,
+			      struct comedi_subdevice *s)
 {
+	struct usbduxsigma_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned int chan;
-	int i, ret;
-	struct usbduxsub *this_usbduxsub = dev->private;
-	int result;
+	unsigned int len = cmd->chanlist_len;
 	uint8_t muxsg0 = 0;
 	uint8_t muxsg1 = 0;
 	uint8_t sysred = 0;
+	int ret;
+	int i;
 
-	if (!this_usbduxsub)
-		return -EFAULT;
-
-	dev_dbg(&this_usbduxsub->interface->dev,
-		"comedi%d: usbdux_ai_cmd\n", dev->minor);
-
-	/* block other CPUs from starting an ai_cmd */
-	down(&this_usbduxsub->sem);
+	down(&devpriv->sem);
 
-	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
-	}
-	if (this_usbduxsub->ai_cmd_running) {
-		dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
-			"ai_cmd not possible. Another ai_cmd is running.\n",
-			dev->minor);
-		up(&this_usbduxsub->sem);
-		return -EBUSY;
-	}
 	/* set current channel of the running acquisition to zero */
 	s->async->cur_chan = 0;
+	for (i = 0; i < len; i++) {
+		unsigned int chan  = CR_CHAN(cmd->chanlist[i]);
 
-	/* first the number of channels per time step */
-	this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
-
-	/* CONFIG0 */
-	this_usbduxsub->dux_commands[2] = 0x12;
-
-	/* CONFIG1: 23kHz sampling rate, delay = 0us,  */
-	this_usbduxsub->dux_commands[3] = 0x03;
-
-	/* CONFIG3: differential channels off */
-	this_usbduxsub->dux_commands[4] = 0x00;
-
-	for (i = 0; i < cmd->chanlist_len; i++) {
-		chan = CR_CHAN(cmd->chanlist[i]);
 		create_adc_command(chan, &muxsg0, &muxsg1);
-		if (i >= NUMCHANNELS) {
-			dev_err(&this_usbduxsub->interface->dev,
-				"comedi%d: channel list too long\n",
-				dev->minor);
-			break;
-		}
 	}
-	this_usbduxsub->dux_commands[5] = muxsg0;
-	this_usbduxsub->dux_commands[6] = muxsg1;
-	this_usbduxsub->dux_commands[7] = sysred;
 
-	dev_dbg(&this_usbduxsub->interface->dev,
-		"comedi %d: sending commands to the usb device: size=%u\n",
-		dev->minor, NUMCHANNELS);
-
-	result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS);
-	if (result < 0) {
-		up(&this_usbduxsub->sem);
-		return result;
-	}
+	devpriv->dux_commands[1] = len;  /* num channels per time step */
+	devpriv->dux_commands[2] = 0x12; /* CONFIG0 */
+	devpriv->dux_commands[3] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
+	devpriv->dux_commands[4] = 0x00; /* CONFIG3: diff. channels off */
+	devpriv->dux_commands[5] = muxsg0;
+	devpriv->dux_commands[6] = muxsg1;
+	devpriv->dux_commands[7] = sysred;
 
-	if (this_usbduxsub->high_speed) {
-		/*
-		 * every 2 channels get a time window of 125us. Thus, if we
-		 * sample all 16 channels we need 1ms. If we sample only one
-		 * channel we need only 125us
-		 */
-		this_usbduxsub->ai_interval =
-			chanToInterval(cmd->chanlist_len);
-		this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
-							  (this_usbduxsub->
-							   ai_interval));
-	} else {
-		/* interval always 1ms */
-		this_usbduxsub->ai_interval = 1;
-		this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
-	}
-	if (this_usbduxsub->ai_timer < 1) {
-		dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: "
-			"timer=%d, scan_begin_arg=%d. "
-			"Not properly tested by cmdtest?\n", dev->minor,
-			this_usbduxsub->ai_timer, cmd->scan_begin_arg);
-		up(&this_usbduxsub->sem);
-		return -EINVAL;
+	ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD);
+	if (ret < 0) {
+		up(&devpriv->sem);
+		return ret;
 	}
-	this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
 
-	if (cmd->stop_src == TRIG_COUNT) {
-		/* data arrives as one packet */
-		this_usbduxsub->ai_sample_count = cmd->stop_arg;
-		this_usbduxsub->ai_continuous = 0;
-	} else {
-		/* continuous acquisition */
-		this_usbduxsub->ai_continuous = 1;
-		this_usbduxsub->ai_sample_count = 0;
-	}
+	devpriv->ai_counter = devpriv->ai_timer;
 
 	if (cmd->start_src == TRIG_NOW) {
 		/* enable this acquisition operation */
-		this_usbduxsub->ai_cmd_running = 1;
-		ret = usbduxsub_submit_InURBs(this_usbduxsub);
+		ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
+					      devpriv->n_ai_urbs, 1);
 		if (ret < 0) {
-			this_usbduxsub->ai_cmd_running = 0;
-			/* fixme: unlink here?? */
-			up(&this_usbduxsub->sem);
+			up(&devpriv->sem);
 			return ret;
 		}
 		s->async->inttrig = NULL;
-	} else {
-		/* TRIG_INT */
-		/* don't enable the acquision operation */
-		/* wait for an internal signal */
-		s->async->inttrig = usbdux_ai_inttrig;
+		devpriv->ai_cmd_running = 1;
+	} else {	/* TRIG_INT */
+		/* wait for an internal signal and submit the urbs later */
+		s->async->inttrig = usbduxsigma_ai_inttrig;
 	}
-	up(&this_usbduxsub->sem);
+
+	up(&devpriv->sem);
+
 	return 0;
 }
 
-/* Mode 0 is used to get a single conversion on demand */
-static int usbdux_ai_insn_read(struct comedi_device *dev,
-			       struct comedi_subdevice *s,
-			       struct comedi_insn *insn, unsigned int *data)
+static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
+				    struct comedi_subdevice *s,
+				    struct comedi_insn *insn,
+				    unsigned int *data)
 {
-	int i;
-	int32_t one = 0;
-	int chan;
-	int err;
-	struct usbduxsub *this_usbduxsub = dev->private;
+	struct usbduxsigma_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
 	uint8_t muxsg0 = 0;
 	uint8_t muxsg1 = 0;
 	uint8_t sysred = 0;
+	int ret;
+	int i;
 
-	if (!this_usbduxsub)
-		return 0;
-
-	dev_dbg(&this_usbduxsub->interface->dev,
-		"comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
-		dev->minor, insn->n, insn->subdev);
-
-	down(&this_usbduxsub->sem);
-	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
-	}
-	if (this_usbduxsub->ai_cmd_running) {
-		dev_err(&this_usbduxsub->interface->dev,
-			"comedi%d: ai_insn_read not possible. "
-			"Async Command is running.\n", dev->minor);
-		up(&this_usbduxsub->sem);
-		return 0;
+	down(&devpriv->sem);
+	if (devpriv->ai_cmd_running) {
+		up(&devpriv->sem);
+		return -EBUSY;
 	}
 
-	/* sample one channel */
-	/* CONFIG0: chopper on */
-	this_usbduxsub->dux_commands[1] = 0x16;
-
-	/* CONFIG1: 2kHz sampling rate */
-	this_usbduxsub->dux_commands[2] = 0x80;
-
-	/* CONFIG3: differential channels off */
-	this_usbduxsub->dux_commands[3] = 0x00;
-
-	chan = CR_CHAN(insn->chanspec);
 	create_adc_command(chan, &muxsg0, &muxsg1);
 
-	this_usbduxsub->dux_commands[4] = muxsg0;
-	this_usbduxsub->dux_commands[5] = muxsg1;
-	this_usbduxsub->dux_commands[6] = sysred;
+	/* Mode 0 is used to get a single conversion on demand */
+	devpriv->dux_commands[1] = 0x16; /* CONFIG0: chopper on */
+	devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
+	devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
+	devpriv->dux_commands[4] = muxsg0;
+	devpriv->dux_commands[5] = muxsg1;
+	devpriv->dux_commands[6] = sysred;
 
 	/* adc commands */
-	err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
-	if (err < 0) {
-		up(&this_usbduxsub->sem);
-		return err;
+	ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
+	if (ret < 0) {
+		up(&devpriv->sem);
+		return ret;
 	}
 
 	for (i = 0; i < insn->n; i++) {
-		err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
-		if (err < 0) {
-			up(&this_usbduxsub->sem);
-			return 0;
-		}
-		/* 32 bits big endian from the A/D converter */
-		one = be32_to_cpu(*((int32_t *)
-				    ((this_usbduxsub->insnBuffer)+1)));
-		/* mask out the status byte */
-		one = one & 0x00ffffff;
-		/* turn it into an unsigned integer */
-		one = one ^ 0x00800000;
-		data[i] = one;
-	}
-	up(&this_usbduxsub->sem);
-	return i;
-}
-
-
-
-
-static int usbdux_getstatusinfo(struct comedi_device *dev, int chan)
-{
-	struct usbduxsub *this_usbduxsub = dev->private;
-	uint8_t sysred = 0;
-	uint32_t one;
-	int err;
-
-	if (!this_usbduxsub)
-		return 0;
-
-	if (this_usbduxsub->ai_cmd_running) {
-		dev_err(&this_usbduxsub->interface->dev,
-			"comedi%d: status read not possible. "
-			"Async Command is running.\n", dev->minor);
-		return 0;
-	}
-
-	/* CONFIG0 */
-	this_usbduxsub->dux_commands[1] = 0x12;
+		int32_t val;
 
-	/* CONFIG1: 2kHz sampling rate */
-	this_usbduxsub->dux_commands[2] = 0x80;
+		ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
+		if (ret < 0) {
+			up(&devpriv->sem);
+			return ret;
+		}
 
-	/* CONFIG3: differential channels off */
-	this_usbduxsub->dux_commands[3] = 0x00;
+		/* 32 bits big endian from the A/D converter */
+		val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf) + 1)));
+		val &= 0x00ffffff;	/* strip status byte */
+		val ^= 0x00800000;	/* convert to unsigned */
 
-	if (chan == 1) {
-		/* ADC offset */
-		sysred = sysred | 1;
-	} else if (chan == 2) {
-		/* VCC */
-		sysred = sysred | 4;
-	} else if (chan == 3) {
-		/* temperature */
-		sysred = sysred | 8;
-	} else if (chan == 4) {
-		/* gain */
-		sysred = sysred | 16;
-	} else if (chan == 5) {
-		/* ref */
-		sysred = sysred | 32;
+		data[i] = val;
 	}
+	up(&devpriv->sem);
 
-	this_usbduxsub->dux_commands[4] = 0;
-	this_usbduxsub->dux_commands[5] = 0;
-	this_usbduxsub->dux_commands[6] = sysred;
-
-	/* adc commands */
-	err = send_dux_commands(this_usbduxsub, SENDSINGLEAD);
-	if (err < 0)
-		return err;
-
-	err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD);
-	if (err < 0)
-		return err;
-
-	/* 32 bits big endian from the A/D converter */
-	one = be32_to_cpu(*((int32_t *)((this_usbduxsub->insnBuffer)+1)));
-	/* mask out the status byte */
-	one = one & 0x00ffffff;
-	one = one ^ 0x00800000;
-
-	return (int)one;
+	return insn->n;
 }
 
-
-
-
-
-
-/************************************/
-/* analog out */
-
-static int usbdux_ao_insn_read(struct comedi_device *dev,
-			       struct comedi_subdevice *s,
-			       struct comedi_insn *insn, unsigned int *data)
+static int usbduxsigma_ao_insn_read(struct comedi_device *dev,
+				    struct comedi_subdevice *s,
+				    struct comedi_insn *insn,
+				    unsigned int *data)
 {
+	struct usbduxsigma_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
 	int i;
-	int chan = CR_CHAN(insn->chanspec);
-	struct usbduxsub *this_usbduxsub = dev->private;
-
-	if (!this_usbduxsub)
-		return -EFAULT;
 
-	down(&this_usbduxsub->sem);
-	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
-	}
+	down(&devpriv->sem);
 	for (i = 0; i < insn->n; i++)
-		data[i] = this_usbduxsub->outBuffer[chan];
+		data[i] = devpriv->ao_readback[chan];
+	up(&devpriv->sem);
 
-	up(&this_usbduxsub->sem);
-	return i;
+	return insn->n;
 }
 
-static int usbdux_ao_insn_write(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				struct comedi_insn *insn, unsigned int *data)
+static int usbduxsigma_ao_insn_write(struct comedi_device *dev,
+				     struct comedi_subdevice *s,
+				     struct comedi_insn *insn,
+				     unsigned int *data)
 {
-	int i, err;
-	int chan = CR_CHAN(insn->chanspec);
-	struct usbduxsub *this_usbduxsub = dev->private;
-
-	if (!this_usbduxsub)
-		return -EFAULT;
-
-	dev_dbg(&this_usbduxsub->interface->dev,
-		"comedi%d: ao_insn_write\n", dev->minor);
+	struct usbduxsigma_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	int ret;
+	int i;
 
-	down(&this_usbduxsub->sem);
-	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
-	}
-	if (this_usbduxsub->ao_cmd_running) {
-		dev_err(&this_usbduxsub->interface->dev,
-			"comedi%d: ao_insn_write: "
-			"ERROR: asynchronous ao_cmd is running\n", dev->minor);
-		up(&this_usbduxsub->sem);
-		return 0;
+	down(&devpriv->sem);
+	if (devpriv->ao_cmd_running) {
+		up(&devpriv->sem);
+		return -EBUSY;
 	}
 
 	for (i = 0; i < insn->n; i++) {
-		dev_dbg(&this_usbduxsub->interface->dev,
-			"comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",
-			dev->minor, chan, i, data[i]);
-
-		/* number of channels: 1 */
-		this_usbduxsub->dux_commands[1] = 1;
-		/* channel number */
-		this_usbduxsub->dux_commands[2] = data[i];
-		this_usbduxsub->outBuffer[chan] = data[i];
-		this_usbduxsub->dux_commands[3] = chan;
-		err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS);
-		if (err < 0) {
-			up(&this_usbduxsub->sem);
-			return err;
+		devpriv->dux_commands[1] = 1;		/* num channels */
+		devpriv->dux_commands[2] = data[i];	/* value */
+		devpriv->dux_commands[3] = chan;	/* channel number */
+		ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DA_CMD);
+		if (ret < 0) {
+			up(&devpriv->sem);
+			return ret;
 		}
+		devpriv->ao_readback[chan] = data[i];
 	}
-	up(&this_usbduxsub->sem);
+	up(&devpriv->sem);
 
-	return i;
+	return insn->n;
 }
 
-static int usbdux_ao_inttrig(struct comedi_device *dev,
-			     struct comedi_subdevice *s, unsigned int trignum)
+static int usbduxsigma_ao_inttrig(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  unsigned int trignum)
 {
+	struct usbduxsigma_private *devpriv = dev->private;
 	int ret;
-	struct usbduxsub *this_usbduxsub = dev->private;
 
-	if (!this_usbduxsub)
-		return -EFAULT;
-
-	down(&this_usbduxsub->sem);
+	if (trignum != 0)
+		return -EINVAL;
 
-	if (!(this_usbduxsub->probed)) {
-		ret = -ENODEV;
-		goto out;
-	}
-	if (trignum != 0) {
-		dev_err(&this_usbduxsub->interface->dev,
-			"comedi%d: usbdux_ao_inttrig: invalid trignum\n",
-			dev->minor);
-		ret = -EINVAL;
-		goto out;
-	}
-	if (!(this_usbduxsub->ao_cmd_running)) {
-		this_usbduxsub->ao_cmd_running = 1;
-		ret = usbduxsub_submit_OutURBs(this_usbduxsub);
+	down(&devpriv->sem);
+	if (!devpriv->ao_cmd_running) {
+		ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
+					      devpriv->n_ao_urbs, 0);
 		if (ret < 0) {
-			dev_err(&this_usbduxsub->interface->dev,
-				"comedi%d: usbdux_ao_inttrig: submitURB: "
-				"err=%d\n", dev->minor, ret);
-			this_usbduxsub->ao_cmd_running = 0;
-			goto out;
+			up(&devpriv->sem);
+			return ret;
 		}
+		devpriv->ao_cmd_running = 1;
 		s->async->inttrig = NULL;
-	} else {
-		dev_err(&this_usbduxsub->interface->dev,
-			"comedi%d: ao_inttrig but acqu is already running.\n",
-			dev->minor);
 	}
-	ret = 1;
-out:
-	up(&this_usbduxsub->sem);
-	return ret;
+	up(&devpriv->sem);
+
+	return 1;
 }
 
-static int usbdux_ao_cmdtest(struct comedi_device *dev,
-			     struct comedi_subdevice *s,
-			     struct comedi_cmd *cmd)
+static int usbduxsigma_ao_cmdtest(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  struct comedi_cmd *cmd)
 {
-	struct usbduxsub *this_usbduxsub = dev->private;
+	struct usbduxsigma_private *devpriv = dev->private;
 	int err = 0;
+	int high_speed;
 	unsigned int flags;
 
-	if (!this_usbduxsub)
-		return -EFAULT;
-
-	if (!(this_usbduxsub->probed))
-		return -ENODEV;
-
-	dev_dbg(&this_usbduxsub->interface->dev,
-		"comedi%d: usbdux_ao_cmdtest\n", dev->minor);
+	/* high speed conversions are not used yet */
+	high_speed = 0;		/* (devpriv->high_speed) */
 
 	/* Step 1 : check if triggers are trivially valid */
 
 	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
 
-	if (0) {		/* (this_usbduxsub->high_speed) */
+	if (high_speed) {
 		/*
 		 * start immediately a new scan
 		 * the sampling rate is set by the coversion rate
@@ -1538,8 +922,10 @@ static int usbdux_ao_cmdtest(struct come
 	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 
-	if (err)
+	if (err) {
+		up(&devpriv->sem);
 		return 1;
+	}
 
 	/* Step 2a : make sure trigger sources are unique */
 
@@ -1578,272 +964,186 @@ static int usbdux_ao_cmdtest(struct come
 	if (err)
 		return 3;
 
-	return 0;
-}
-
-static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
-	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned int chan, gain;
-	int i, ret;
-	struct usbduxsub *this_usbduxsub = dev->private;
-
-	if (!this_usbduxsub)
-		return -EFAULT;
-
-	down(&this_usbduxsub->sem);
-	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
-	}
-	dev_dbg(&this_usbduxsub->interface->dev,
-		"comedi%d: %s\n", dev->minor, __func__);
-
-	/* set current channel of the running acquisition to zero */
-	s->async->cur_chan = 0;
-	for (i = 0; i < cmd->chanlist_len; ++i) {
-		chan = CR_CHAN(cmd->chanlist[i]);
-		gain = CR_RANGE(cmd->chanlist[i]);
-		if (i >= NUMOUTCHANNELS) {
-			dev_err(&this_usbduxsub->interface->dev,
-				"comedi%d: %s: channel list too long\n",
-				dev->minor, __func__);
-			break;
-		}
-		this_usbduxsub->dac_commands[i] = chan;
-		dev_dbg(&this_usbduxsub->interface->dev,
-			"comedi%d: dac command for ch %d is %x\n",
-			dev->minor, i, this_usbduxsub->dac_commands[i]);
-	}
+	/* Step 4: fix up any arguments */
 
-	/* we count in steps of 1ms (125us) */
-	/* 125us mode not used yet */
-	if (0) {		/* (this_usbduxsub->high_speed) */
-		/* 125us */
+	/* we count in timer steps */
+	if (high_speed) {
 		/* timing of the conversion itself: every 125 us */
-		this_usbduxsub->ao_timer = cmd->convert_arg / 125000;
+		devpriv->ao_timer = cmd->convert_arg / 125000;
 	} else {
-		/* 1ms */
-		/* timing of the scan: we get all channels at once */
-		this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000;
-		dev_dbg(&this_usbduxsub->interface->dev,
-			"comedi%d: scan_begin_src=%d, scan_begin_arg=%d, "
-			"convert_src=%d, convert_arg=%d\n", dev->minor,
-			cmd->scan_begin_src, cmd->scan_begin_arg,
-			cmd->convert_src, cmd->convert_arg);
-		dev_dbg(&this_usbduxsub->interface->dev,
-			"comedi%d: ao_timer=%d (ms)\n",
-			dev->minor, this_usbduxsub->ao_timer);
-		if (this_usbduxsub->ao_timer < 1) {
-			dev_err(&this_usbduxsub->interface->dev,
-				"comedi%d: usbdux: ao_timer=%d, "
-				"scan_begin_arg=%d. "
-				"Not properly tested by cmdtest?\n",
-				dev->minor, this_usbduxsub->ao_timer,
-				cmd->scan_begin_arg);
-			up(&this_usbduxsub->sem);
-			return -EINVAL;
-		}
+		/*
+		 * timing of the scan: every 1ms
+		 * we get all channels at once
+		 */
+		devpriv->ao_timer = cmd->scan_begin_arg / 1000000;
 	}
-	this_usbduxsub->ao_counter = this_usbduxsub->ao_timer;
+	if (devpriv->ao_timer < 1)
+		err |= -EINVAL;
 
 	if (cmd->stop_src == TRIG_COUNT) {
-		/* not continuous */
-		/* counter */
-		/* high speed also scans everything at once */
-		if (0) {	/* (this_usbduxsub->high_speed) */
-			this_usbduxsub->ao_sample_count =
-			    (cmd->stop_arg) * (cmd->scan_end_arg);
+		/* not continuous, use counter */
+		if (high_speed) {
+			/* high speed also scans everything at once */
+			devpriv->ao_sample_count = cmd->stop_arg *
+						   cmd->scan_end_arg;
 		} else {
-			/* there's no scan as the scan has been */
-			/* perf inside the FX2 */
-			/* data arrives as one packet */
-			this_usbduxsub->ao_sample_count = cmd->stop_arg;
+			/*
+			 * There's no scan as the scan has been
+			 * handled inside the FX2. Data arrives as
+			 * one packet.
+			 */
+			devpriv->ao_sample_count = cmd->stop_arg;
 		}
-		this_usbduxsub->ao_continuous = 0;
+		devpriv->ao_continuous = 0;
 	} else {
 		/* continuous acquisition */
-		this_usbduxsub->ao_continuous = 1;
-		this_usbduxsub->ao_sample_count = 0;
+		devpriv->ao_continuous = 1;
+		devpriv->ao_sample_count = 0;
 	}
 
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int usbduxsigma_ao_cmd(struct comedi_device *dev,
+			      struct comedi_subdevice *s)
+{
+	struct usbduxsigma_private *devpriv = dev->private;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int ret;
+	int i;
+
+	down(&devpriv->sem);
+
+	/* set current channel of the running acquisition to zero */
+	s->async->cur_chan = 0;
+	for (i = 0; i < cmd->chanlist_len; ++i)
+		devpriv->dac_commands[i] = CR_CHAN(cmd->chanlist[i]);
+
+	devpriv->ao_counter = devpriv->ao_timer;
+
 	if (cmd->start_src == TRIG_NOW) {
 		/* enable this acquisition operation */
-		this_usbduxsub->ao_cmd_running = 1;
-		ret = usbduxsub_submit_OutURBs(this_usbduxsub);
+		ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
+					      devpriv->n_ao_urbs, 0);
 		if (ret < 0) {
-			this_usbduxsub->ao_cmd_running = 0;
-			/* fixme: unlink here?? */
-			up(&this_usbduxsub->sem);
+			up(&devpriv->sem);
 			return ret;
 		}
 		s->async->inttrig = NULL;
-	} else {
-		/* TRIG_INT */
-		/* submit the urbs later */
-		/* wait for an internal signal */
-		s->async->inttrig = usbdux_ao_inttrig;
+		devpriv->ao_cmd_running = 1;
+	} else {	/* TRIG_INT */
+		/* wait for an internal signal and submit the urbs later */
+		s->async->inttrig = usbduxsigma_ao_inttrig;
 	}
 
-	up(&this_usbduxsub->sem);
+	up(&devpriv->sem);
+
 	return 0;
 }
 
-static int usbdux_dio_insn_config(struct comedi_device *dev,
-				  struct comedi_subdevice *s,
-				  struct comedi_insn *insn, unsigned int *data)
+static int usbduxsigma_dio_insn_config(struct comedi_device *dev,
+				       struct comedi_subdevice *s,
+				       struct comedi_insn *insn,
+				       unsigned int *data)
 {
-	int chan = CR_CHAN(insn->chanspec);
-
-	/* The input or output configuration of each digital line is
-	 * configured by a special insn_config instruction.  chanspec
-	 * contains the channel to be changed, and data[0] contains the
-	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int mask = 1 << chan;
 
 	switch (data[0]) {
 	case INSN_CONFIG_DIO_OUTPUT:
-		s->io_bits |= 1 << chan;	/* 1 means Out */
+		s->io_bits |= mask;
 		break;
 	case INSN_CONFIG_DIO_INPUT:
-		s->io_bits &= ~(1 << chan);
+		s->io_bits &= ~mask;
 		break;
 	case INSN_CONFIG_DIO_QUERY:
-		data[1] =
-		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		break;
 	default:
 		return -EINVAL;
 		break;
 	}
-	/* we don't tell the firmware here as it would take 8 frames */
-	/* to submit the information. We do it in the insn_bits. */
+
+	/*
+	 * We don't tell the firmware here as it would take 8 frames
+	 * to submit the information. We do it in the (*insn_bits).
+	 */
 	return insn->n;
 }
 
-static int usbdux_dio_insn_bits(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				struct comedi_insn *insn,
-				unsigned int *data)
+static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
+				     struct comedi_subdevice *s,
+				     struct comedi_insn *insn,
+				     unsigned int *data)
 {
+	struct usbduxsigma_private *devpriv = dev->private;
+	unsigned int mask = data[0];
+	unsigned int bits = data[1];
+	int ret;
 
-	struct usbduxsub *this_usbduxsub = dev->private;
-	int err;
-
-	if (!this_usbduxsub)
-		return -EFAULT;
+	down(&devpriv->sem);
 
-	down(&this_usbduxsub->sem);
+	s->state &= ~mask;
+	s->state |= (bits & mask);
 
-	if (!(this_usbduxsub->probed)) {
-		up(&this_usbduxsub->sem);
-		return -ENODEV;
-	}
+	devpriv->dux_commands[1] = s->io_bits & 0xff;
+	devpriv->dux_commands[4] = s->state & 0xff;
+	devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
+	devpriv->dux_commands[5] = (s->state >> 8) & 0xff;
+	devpriv->dux_commands[3] = (s->io_bits >> 16) & 0xff;
+	devpriv->dux_commands[6] = (s->state >> 16) & 0xff;
 
-	/* The insn data is a mask in data[0] and the new data
-	 * in data[1], each channel cooresponding to a bit. */
-	s->state &= ~data[0];
-	s->state |= data[0] & data[1];
-	/* The commands are 8 bits wide */
-	this_usbduxsub->dux_commands[1] = (s->io_bits) & 0x000000FF;
-	this_usbduxsub->dux_commands[4] = (s->state) & 0x000000FF;
-	this_usbduxsub->dux_commands[2] = ((s->io_bits) & 0x0000FF00) >> 8;
-	this_usbduxsub->dux_commands[5] = ((s->state) & 0x0000FF00) >> 8;
-	this_usbduxsub->dux_commands[3] = ((s->io_bits) & 0x00FF0000) >> 16;
-	this_usbduxsub->dux_commands[6] = ((s->state) & 0x00FF0000) >> 16;
+	ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
+	if (ret < 0)
+		goto done;
+	ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
+	if (ret < 0)
+		goto done;
 
-	/* This command also tells the firmware to return */
-	/* the digital input lines */
-	err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
-	if (err < 0) {
-		up(&this_usbduxsub->sem);
-		return err;
-	}
-	err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND);
-	if (err < 0) {
-		up(&this_usbduxsub->sem);
-		return err;
-	}
+	s->state = devpriv->insn_buf[1] |
+		   (devpriv->insn_buf[2] << 8) |
+		   (devpriv->insn_buf[3] << 16);
 
-	data[1] = (((unsigned int)(this_usbduxsub->insnBuffer[1]))&0xff) |
-		((((unsigned int)(this_usbduxsub->insnBuffer[2]))&0xff) << 8) |
-		((((unsigned int)(this_usbduxsub->insnBuffer[3]))&0xff) << 16);
+	data[1] = s->state;
+	ret = insn->n;
 
-	s->state = data[1];
+done:
+	up(&devpriv->sem);
 
-	up(&this_usbduxsub->sem);
-	return insn->n;
+	return ret;
 }
 
-/***********************************/
-/* PWM */
-
-static int usbduxsub_unlink_PwmURBs(struct usbduxsub *usbduxsub_tmp)
+static void usbduxsigma_pwm_stop(struct comedi_device *dev, int do_unlink)
 {
-	int err = 0;
+	struct usbduxsigma_private *devpriv = dev->private;
 
-	if (usbduxsub_tmp && usbduxsub_tmp->urbPwm) {
-		if (usbduxsub_tmp->urbPwm)
-			usb_kill_urb(usbduxsub_tmp->urbPwm);
-		dev_dbg(&usbduxsub_tmp->interface->dev,
-			"comedi: unlinked PwmURB: res=%d\n", err);
+	if (do_unlink) {
+		if (devpriv->pwm_urb)
+			usb_kill_urb(devpriv->pwm_urb);
 	}
-	return err;
-}
-
-/* This cancels a running acquisition operation
- * in any context.
- */
-static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
-{
-	int ret = 0;
 
-	if (!this_usbduxsub)
-		return -EFAULT;
-
-	dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__);
-	if (do_unlink)
-		ret = usbduxsub_unlink_PwmURBs(this_usbduxsub);
-
-	this_usbduxsub->pwm_cmd_running = 0;
-
-	return ret;
+	devpriv->pwm_cmd_running = 0;
 }
 
-/* force unlink - is called by comedi */
-static int usbdux_pwm_cancel(struct comedi_device *dev,
-			     struct comedi_subdevice *s)
+static int usbduxsigma_pwm_cancel(struct comedi_device *dev,
+				  struct comedi_subdevice *s)
 {
-	struct usbduxsub *this_usbduxsub = dev->private;
-	int res = 0;
+	struct usbduxsigma_private *devpriv = dev->private;
 
 	/* unlink only if it is really running */
-	res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->pwm_cmd_running);
-
-	dev_dbg(&this_usbduxsub->interface->dev,
-		"comedi %d: sending pwm off command to the usb device.\n",
-		dev->minor);
-	res = send_dux_commands(this_usbduxsub, SENDPWMOFF);
-	if (res < 0)
-		return res;
+	usbduxsigma_pwm_stop(dev, devpriv->pwm_cmd_running);
 
-	return res;
+	return usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_OFF_CMD);
 }
 
-static void usbduxsub_pwm_irq(struct urb *urb)
+static void usbduxsigma_pwm_urb_complete(struct urb *urb)
 {
+	struct comedi_device *dev = urb->context;
+	struct usbduxsigma_private *devpriv = dev->private;
 	int ret;
-	struct usbduxsub *this_usbduxsub;
-	struct comedi_device *this_comedidev;
-	struct comedi_subdevice *s;
-
-	/* printk(KERN_DEBUG "PWM: IRQ\n"); */
-
-	/* the context variable points to the subdevice */
-	this_comedidev = urb->context;
-	/* the private structure of the subdevice is struct usbduxsub */
-	this_usbduxsub = this_comedidev->private;
-
-	s = &this_comedidev->subdevices[SUBDEV_DA];
 
 	switch (urb->status) {
 	case 0:
@@ -1854,260 +1154,180 @@ static void usbduxsub_pwm_irq(struct urb
 	case -ENOENT:
 	case -ESHUTDOWN:
 	case -ECONNABORTED:
-		/*
-		 * after an unlink command, unplug, ... etc
-		 * no unlink needed here. Already shutting down.
-		 */
-		if (this_usbduxsub->pwm_cmd_running)
-			usbdux_pwm_stop(this_usbduxsub, 0);
-
+		/* happens after an unlink command */
+		if (devpriv->pwm_cmd_running)
+			usbduxsigma_pwm_stop(dev, 0);	/* w/o unlink */
 		return;
 
 	default:
 		/* a real error */
-		if (this_usbduxsub->pwm_cmd_running) {
-			dev_err(&this_usbduxsub->interface->dev,
-				"comedi_: Non-zero urb status received in "
-				"pwm intr context: %d\n", urb->status);
-			usbdux_pwm_stop(this_usbduxsub, 0);
+		if (devpriv->pwm_cmd_running) {
+			dev_err(dev->class_dev,
+				"%s: non-zero urb status (%d)\n",
+				__func__, urb->status);
+			usbduxsigma_pwm_stop(dev, 0);	/* w/o unlink */
 		}
 		return;
 	}
 
-	/* are we actually running? */
-	if (!(this_usbduxsub->pwm_cmd_running))
+	if (!devpriv->pwm_cmd_running)
 		return;
 
-	urb->transfer_buffer_length = this_usbduxsub->sizePwmBuf;
-	urb->dev = this_usbduxsub->usbdev;
+	urb->transfer_buffer_length = devpriv->pwm_buf_sz;
+	urb->dev = comedi_to_usb_dev(dev);
 	urb->status = 0;
-	if (this_usbduxsub->pwm_cmd_running) {
-		ret = usb_submit_urb(urb, GFP_ATOMIC);
-		if (ret < 0) {
-			dev_err(&this_usbduxsub->interface->dev,
-				"comedi_: pwm urb resubm failed in int-cont. "
-				"ret=%d", ret);
-			if (ret == EL2NSYNC)
-				dev_err(&this_usbduxsub->interface->dev,
-					"buggy USB host controller or bug in "
-					"IRQ handling!\n");
-
-			/* don't do an unlink here */
-			usbdux_pwm_stop(this_usbduxsub, 0);
-		}
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret < 0) {
+		dev_err(dev->class_dev, "%s: urb resubmit failed (%d)\n",
+			__func__, ret);
+		if (ret == EL2NSYNC)
+			dev_err(dev->class_dev,
+				"buggy USB host controller or bug in IRQ handler\n");
+		usbduxsigma_pwm_stop(dev, 0);	/* w/o unlink */
 	}
 }
 
-static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
+static int usbduxsigma_submit_pwm_urb(struct comedi_device *dev)
 {
-	int errFlag;
-
-	if (!usbduxsub)
-		return -EFAULT;
-
-	dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxsigma_private *devpriv = dev->private;
+	struct urb *urb = devpriv->pwm_urb;
 
 	/* in case of a resubmission after an unlink... */
-	usb_fill_bulk_urb(usbduxsub->urbPwm,
-			  usbduxsub->usbdev,
-			  usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
-			  usbduxsub->urbPwm->transfer_buffer,
-			  usbduxsub->sizePwmBuf, usbduxsub_pwm_irq,
-			  usbduxsub->comedidev);
+	usb_fill_bulk_urb(urb,
+			  usb, usb_sndbulkpipe(usb, USBDUXSIGMA_PWM_OUT_EP),
+			  urb->transfer_buffer, devpriv->pwm_buf_sz,
+			  usbduxsigma_pwm_urb_complete, dev);
 
-	errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC);
-	if (errFlag) {
-		dev_err(&usbduxsub->interface->dev,
-			"comedi_: usbduxsigma: pwm: usb_submit_urb error %d\n",
-			errFlag);
-		return errFlag;
-	}
-	return 0;
+	return usb_submit_urb(urb, GFP_ATOMIC);
 }
 
-static int usbdux_pwm_period(struct comedi_device *dev,
-			     struct comedi_subdevice *s, unsigned int period)
+static int usbduxsigma_pwm_period(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  unsigned int period)
 {
-	struct usbduxsub *this_usbduxsub = dev->private;
+	struct usbduxsigma_private *devpriv = dev->private;
 	int fx2delay = 255;
 
 	if (period < MIN_PWM_PERIOD) {
-		dev_err(&this_usbduxsub->interface->dev,
-			"comedi%d: illegal period setting for pwm.\n",
-			dev->minor);
 		return -EAGAIN;
 	} else {
-		fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
-		if (fx2delay > 255) {
-			dev_err(&this_usbduxsub->interface->dev,
-				"comedi%d: period %d for pwm is too low.\n",
-				dev->minor, period);
+		fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
+		if (fx2delay > 255)
 			return -EAGAIN;
-		}
 	}
-	this_usbduxsub->pwmDelay = fx2delay;
-	this_usbduxsub->pwmPeriod = period;
-	dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
-		__func__, period, fx2delay);
+	devpriv->pwm_delay = fx2delay;
+	devpriv->pwm_period = period;
 	return 0;
 }
 
-/* is called from insn so there's no need to do all the sanity checks */
-static int usbdux_pwm_start(struct comedi_device *dev,
-			    struct comedi_subdevice *s)
+static int usbduxsigma_pwm_start(struct comedi_device *dev,
+				 struct comedi_subdevice *s)
 {
-	int ret, i;
-	struct usbduxsub *this_usbduxsub = dev->private;
-
-	dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n",
-		dev->minor, __func__);
+	struct usbduxsigma_private *devpriv = dev->private;
+	int ret;
 
-	if (this_usbduxsub->pwm_cmd_running) {
-		/* already running */
+	if (devpriv->pwm_cmd_running)
 		return 0;
-	}
 
-	this_usbduxsub->dux_commands[1] = ((uint8_t) this_usbduxsub->pwmDelay);
-	ret = send_dux_commands(this_usbduxsub, SENDPWMON);
+	devpriv->dux_commands[1] = devpriv->pwm_delay;
+	ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_ON_CMD);
 	if (ret < 0)
 		return ret;
 
-	/* initialise the buffer */
-	for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
-		((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
+	memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);
 
-	this_usbduxsub->pwm_cmd_running = 1;
-	ret = usbduxsub_submit_PwmURBs(this_usbduxsub);
-	if (ret < 0) {
-		this_usbduxsub->pwm_cmd_running = 0;
+	ret = usbduxsigma_submit_pwm_urb(dev);
+	if (ret < 0)
 		return ret;
-	}
+	devpriv->pwm_cmd_running = 1;
+
 	return 0;
 }
 
-/* generates the bit pattern for PWM with the optional sign bit */
-static int usbdux_pwm_pattern(struct comedi_device *dev,
-			      struct comedi_subdevice *s, int channel,
-			      unsigned int value, unsigned int sign)
+static int usbduxsigma_pwm_pattern(struct comedi_device *dev,
+				   struct comedi_subdevice *s,
+				   unsigned int chan,
+				   unsigned int value,
+				   unsigned int sign)
 {
-	struct usbduxsub *this_usbduxsub = dev->private;
-	int i, szbuf;
-	char *pBuf;
-	char pwm_mask;
-	char sgn_mask;
-	char c;
-
-	if (!this_usbduxsub)
-		return -EFAULT;
+	struct usbduxsigma_private *devpriv = dev->private;
+	char pwm_mask = (1 << chan);	/* DIO bit for the PWM data */
+	char sgn_mask = (16 << chan);	/* DIO bit for the sign */
+	char *buf = (char *)(devpriv->pwm_urb->transfer_buffer);
+	int szbuf = devpriv->pwm_buf_sz;
+	int i;
 
-	/* this is the DIO bit which carries the PWM data */
-	pwm_mask = (1 << channel);
-	/* this is the DIO bit which carries the optional direction bit */
-	sgn_mask = (16 << channel);
-	/* this is the buffer which will be filled with the with bit */
-	/* pattern for one period */
-	szbuf = this_usbduxsub->sizePwmBuf;
-	pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
 	for (i = 0; i < szbuf; i++) {
-		c = *pBuf;
-		/* reset bits */
-		c = c & (~pwm_mask);
-		/* set the bit as long as the index is lower than the value */
+		char c = *buf;
+
+		c &= ~pwm_mask;
 		if (i < value)
-			c = c | pwm_mask;
-		/* set the optional sign bit for a relay */
-		if (!sign) {
-			/* positive value */
-			c = c & (~sgn_mask);
-		} else {
-			/* negative value */
-			c = c | sgn_mask;
-		}
-		*(pBuf++) = c;
+			c |= pwm_mask;
+		if (!sign)
+			c &= ~sgn_mask;
+		else
+			c |= sgn_mask;
+		*buf++ = c;
 	}
 	return 1;
 }
 
-static int usbdux_pwm_write(struct comedi_device *dev,
-			    struct comedi_subdevice *s,
-			    struct comedi_insn *insn, unsigned int *data)
+static int usbduxsigma_pwm_write(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn,
+				 unsigned int *data)
 {
-	struct usbduxsub *this_usbduxsub = dev->private;
-
-	if (!this_usbduxsub)
-		return -EFAULT;
+	unsigned int chan = CR_CHAN(insn->chanspec);
 
-	if ((insn->n) != 1) {
-		/*
-		 * doesn't make sense to have more than one value here because
-		 * it would just overwrite the PWM buffer a couple of times
-		 */
+	/*
+	 * It doesn't make sense to support more than one value here
+	 * because it would just overwrite the PWM buffer.
+	 */
+	if (insn->n != 1)
 		return -EINVAL;
-	}
 
 	/*
-	 * the sign is set via a special INSN only, this gives us 8 bits for
-	 * normal operation
-	 * relay sign 0 by default
+	 * The sign is set via a special INSN only, this gives us 8 bits
+	 * for normal operation, sign is 0 by default.
 	 */
-	return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
+	return usbduxsigma_pwm_pattern(dev, s, chan, data[0], 0);
 }
 
-static int usbdux_pwm_read(struct comedi_device *x1,
-			   struct comedi_subdevice *x2, struct comedi_insn *x3,
-			   unsigned int *x4)
+static int usbduxsigma_pwm_config(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn,
+				  unsigned int *data)
 {
-	/* not needed */
-	return -EINVAL;
-};
+	struct usbduxsigma_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
 
-/* switches on/off PWM */
-static int usbdux_pwm_config(struct comedi_device *dev,
-			     struct comedi_subdevice *s,
-			     struct comedi_insn *insn, unsigned int *data)
-{
-	struct usbduxsub *this_usbduxsub = dev->private;
 	switch (data[0]) {
 	case INSN_CONFIG_ARM:
-		/* switch it on */
-		dev_dbg(&this_usbduxsub->interface->dev,
-			"comedi%d: %s: pwm on\n", dev->minor, __func__);
 		/*
 		 * if not zero the PWM is limited to a certain time which is
 		 * not supported here
 		 */
 		if (data[1] != 0)
 			return -EINVAL;
-		return usbdux_pwm_start(dev, s);
+		return usbduxsigma_pwm_start(dev, s);
 	case INSN_CONFIG_DISARM:
-		dev_dbg(&this_usbduxsub->interface->dev,
-			"comedi%d: %s: pwm off\n", dev->minor, __func__);
-		return usbdux_pwm_cancel(dev, s);
+		return usbduxsigma_pwm_cancel(dev, s);
 	case INSN_CONFIG_GET_PWM_STATUS:
-		/*
-		 * to check if the USB transmission has failed or in case PWM
-		 * was limited to n cycles to check if it has terminated
-		 */
-		data[1] = this_usbduxsub->pwm_cmd_running;
+		data[1] = devpriv->pwm_cmd_running;
 		return 0;
 	case INSN_CONFIG_PWM_SET_PERIOD:
-		dev_dbg(&this_usbduxsub->interface->dev,
-			"comedi%d: %s: setting period\n", dev->minor,
-			__func__);
-		return usbdux_pwm_period(dev, s, data[1]);
+		return usbduxsigma_pwm_period(dev, s, data[1]);
 	case INSN_CONFIG_PWM_GET_PERIOD:
-		data[1] = this_usbduxsub->pwmPeriod;
+		data[1] = devpriv->pwm_period;
 		return 0;
 	case INSN_CONFIG_PWM_SET_H_BRIDGE:
-		/* value in the first byte and the sign in the second for a
-		   relay */
-		return usbdux_pwm_pattern(dev, s,
-					  /* the channel number */
-					  CR_CHAN(insn->chanspec),
-					  /* actual PWM data */
-					  data[1],
-					  /* just a sign */
-					  (data[2] != 0));
+		/*
+		 * data[1] = value
+		 * data[2] = sign (for a relay)
+		 */
+		return usbduxsigma_pwm_pattern(dev, s, chan,
+					       data[1], (data[2] != 0));
 	case INSN_CONFIG_PWM_GET_H_BRIDGE:
 		/* values are not kept in this driver, nothing to return */
 		return -EINVAL;
@@ -2115,542 +1335,412 @@ static int usbdux_pwm_config(struct come
 	return -EINVAL;
 }
 
-/* end of PWM */
-/*****************************************************************/
-
-static void tidy_up(struct usbduxsub *usbduxsub_tmp)
+static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
 {
-	int i;
+	struct usbduxsigma_private *devpriv = dev->private;
+	uint8_t sysred;
+	uint32_t val;
+	int ret;
 
-	if (!usbduxsub_tmp)
-		return;
-	dev_dbg(&usbduxsub_tmp->interface->dev, "comedi_: tiding up\n");
+	switch (chan) {
+	default:
+	case 0:
+		sysred = 0;		/* ADC zero */
+		break;
+	case 1:
+		sysred = 1;		/* ADC offset */
+		break;
+	case 2:
+		sysred = 4;		/* VCC */
+		break;
+	case 3:
+		sysred = 8;		/* temperature */
+		break;
+	case 4:
+		sysred = 16;		/* gain */
+		break;
+	case 5:
+		sysred =  32;		/* ref */
+		break;
+	}
 
-	/* shows the usb subsystem that the driver is down */
-	if (usbduxsub_tmp->interface)
-		usb_set_intfdata(usbduxsub_tmp->interface, NULL);
+	devpriv->dux_commands[1] = 0x12; /* CONFIG0 */
+	devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
+	devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
+	devpriv->dux_commands[4] = 0;
+	devpriv->dux_commands[5] = 0;
+	devpriv->dux_commands[6] = sysred;
+	ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
+	if (ret < 0)
+		return ret;
 
-	usbduxsub_tmp->probed = 0;
+	ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
+	if (ret < 0)
+		return ret;
 
-	if (usbduxsub_tmp->urbIn) {
-		if (usbduxsub_tmp->ai_cmd_running) {
-			usbduxsub_tmp->ai_cmd_running = 0;
-			usbduxsub_unlink_InURBs(usbduxsub_tmp);
-		}
-		for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
-			kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
-			usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
-			usb_kill_urb(usbduxsub_tmp->urbIn[i]);
-			usb_free_urb(usbduxsub_tmp->urbIn[i]);
-			usbduxsub_tmp->urbIn[i] = NULL;
-		}
-		kfree(usbduxsub_tmp->urbIn);
-		usbduxsub_tmp->urbIn = NULL;
-	}
-	if (usbduxsub_tmp->urbOut) {
-		if (usbduxsub_tmp->ao_cmd_running) {
-			usbduxsub_tmp->ao_cmd_running = 0;
-			usbduxsub_unlink_OutURBs(usbduxsub_tmp);
-		}
-		for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
-			if (usbduxsub_tmp->urbOut[i]->transfer_buffer) {
-				kfree(usbduxsub_tmp->
-				      urbOut[i]->transfer_buffer);
-				usbduxsub_tmp->urbOut[i]->transfer_buffer =
-				    NULL;
-			}
-			if (usbduxsub_tmp->urbOut[i]) {
-				usb_kill_urb(usbduxsub_tmp->urbOut[i]);
-				usb_free_urb(usbduxsub_tmp->urbOut[i]);
-				usbduxsub_tmp->urbOut[i] = NULL;
-			}
-		}
-		kfree(usbduxsub_tmp->urbOut);
-		usbduxsub_tmp->urbOut = NULL;
-	}
-	if (usbduxsub_tmp->urbPwm) {
-		if (usbduxsub_tmp->pwm_cmd_running) {
-			usbduxsub_tmp->pwm_cmd_running = 0;
-			usbduxsub_unlink_PwmURBs(usbduxsub_tmp);
-		}
-		kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
-		usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
-		usb_kill_urb(usbduxsub_tmp->urbPwm);
-		usb_free_urb(usbduxsub_tmp->urbPwm);
-		usbduxsub_tmp->urbPwm = NULL;
-	}
-	kfree(usbduxsub_tmp->inBuffer);
-	usbduxsub_tmp->inBuffer = NULL;
-	kfree(usbduxsub_tmp->insnBuffer);
-	usbduxsub_tmp->insnBuffer = NULL;
-	kfree(usbduxsub_tmp->outBuffer);
-	usbduxsub_tmp->outBuffer = NULL;
-	kfree(usbduxsub_tmp->dac_commands);
-	usbduxsub_tmp->dac_commands = NULL;
-	kfree(usbduxsub_tmp->dux_commands);
-	usbduxsub_tmp->dux_commands = NULL;
-	usbduxsub_tmp->ai_cmd_running = 0;
-	usbduxsub_tmp->ao_cmd_running = 0;
-	usbduxsub_tmp->pwm_cmd_running = 0;
+	/* 32 bits big endian from the A/D converter */
+	val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf)+1)));
+	val &= 0x00ffffff;	/* strip status byte */
+	val ^= 0x00800000;	/* convert to unsigned */
+
+	return (int)val;
 }
 
-static int usbduxsigma_attach_common(struct comedi_device *dev,
-				     struct usbduxsub *uds)
+static int usbduxsigma_attach_common(struct comedi_device *dev)
 {
-	int ret;
+	struct usbduxsigma_private *devpriv = dev->private;
 	struct comedi_subdevice *s;
 	int n_subdevs;
 	int offset;
+	int ret;
 
-	down(&uds->sem);
-	/* pointer back to the corresponding comedi device */
-	uds->comedidev = dev;
+	down(&devpriv->sem);
 
-	/* set number of subdevices */
-	if (uds->high_speed)
+	if (devpriv->high_speed)
 		n_subdevs = 4;	/* with pwm */
 	else
 		n_subdevs = 3;	/* without pwm */
 	ret = comedi_alloc_subdevices(dev, n_subdevs);
 	if (ret) {
-		up(&uds->sem);
+		up(&devpriv->sem);
 		return ret;
 	}
-	/* private structure is also simply the usb-structure */
-	dev->private = uds;
-	/* the first subdevice is the A/D converter */
-	s = &dev->subdevices[SUBDEV_AD];
-	/* the URBs get the comedi subdevice */
-	/* which is responsible for reading */
-	/* this is the subdevice which reads data */
+
+	/* Analog Input subdevice */
+	s = &dev->subdevices[0];
 	dev->read_subdev = s;
-	/* the subdevice receives as private structure the */
-	/* usb-structure */
-	s->private = NULL;
-	/* analog input */
-	s->type = COMEDI_SUBD_AI;
-	/* readable and ref is to ground, 32 bit wide data! */
-	s->subdev_flags = SDF_READABLE | SDF_GROUND |
-		SDF_CMD_READ | SDF_LSAMPL;
-	/* 16 A/D channels */
-	s->n_chan = NUMCHANNELS;
-	/* length of the channellist */
-	s->len_chanlist = NUMCHANNELS;
-	/* callback functions */
-	s->insn_read = usbdux_ai_insn_read;
-	s->do_cmdtest = usbdux_ai_cmdtest;
-	s->do_cmd = usbdux_ai_cmd;
-	s->cancel = usbdux_ai_cancel;
-	/* max value from the A/D converter (24bit) */
-	s->maxdata = 0x00FFFFFF;
-	/* range table to convert to physical units */
-	s->range_table = (&range_usbdux_ai_range);
-	/* analog output subdevice */
-	s = &dev->subdevices[SUBDEV_DA];
-	/* analog out */
-	s->type = COMEDI_SUBD_AO;
-	/* backward pointer */
+	s->type		= COMEDI_SUBD_AI;
+	s->subdev_flags	= SDF_READABLE | SDF_GROUND | SDF_CMD_READ | SDF_LSAMPL;
+	s->n_chan	= NUMCHANNELS;
+	s->len_chanlist	= NUMCHANNELS;
+	s->maxdata	= 0x00ffffff;
+	s->range_table	= &usbduxsigma_ai_range;
+	s->insn_read	= usbduxsigma_ai_insn_read;
+	s->do_cmdtest	= usbduxsigma_ai_cmdtest;
+	s->do_cmd	= usbduxsigma_ai_cmd;
+	s->cancel	= usbduxsigma_ai_cancel;
+
+	/* Analog Output subdevice */
+	s = &dev->subdevices[1];
 	dev->write_subdev = s;
-	/* the subdevice receives as private structure the */
-	/* usb-structure */
-	s->private = NULL;
-	/* are writable */
-	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
-	/* 4 channels */
-	s->n_chan = 4;
-	/* length of the channellist */
-	s->len_chanlist = 4;
-	/* 8 bit resolution */
-	s->maxdata = 0x00ff;
-	/* unipolar range */
-	s->range_table = &range_unipolar2_5;
-	/* callback */
-	s->do_cmdtest = usbdux_ao_cmdtest;
-	s->do_cmd = usbdux_ao_cmd;
-	s->cancel = usbdux_ao_cancel;
-	s->insn_read = usbdux_ao_insn_read;
-	s->insn_write = usbdux_ao_insn_write;
-	/* digital I/O subdevice */
-	s = &dev->subdevices[SUBDEV_DIO];
-	s->type = COMEDI_SUBD_DIO;
-	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-	/* 8 external and 16 internal channels */
-	s->n_chan = 24;
-	s->maxdata = 1;
-	s->range_table = (&range_digital);
-	s->insn_bits = usbdux_dio_insn_bits;
-	s->insn_config = usbdux_dio_insn_config;
-	/* we don't use it */
-	s->private = NULL;
-	if (uds->high_speed) {
-		/* timer / pwm subdevice */
-		s = &dev->subdevices[SUBDEV_PWM];
-		s->type = COMEDI_SUBD_PWM;
-		s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
-		s->n_chan = 8;
-		/* this defines the max duty cycle resolution */
-		s->maxdata = uds->sizePwmBuf;
-		s->insn_write = usbdux_pwm_write;
-		s->insn_read = usbdux_pwm_read;
-		s->insn_config = usbdux_pwm_config;
-		usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
+	s->type		= COMEDI_SUBD_AO;
+	s->subdev_flags	= SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
+	s->n_chan	= USBDUXSIGMA_NUM_AO_CHAN;
+	s->len_chanlist	= s->n_chan;
+	s->maxdata	= 0x00ff;
+	s->range_table	= &range_unipolar2_5;
+	s->insn_write	= usbduxsigma_ao_insn_write;
+	s->insn_read	= usbduxsigma_ao_insn_read;
+	s->do_cmdtest	= usbduxsigma_ao_cmdtest;
+	s->do_cmd	= usbduxsigma_ao_cmd;
+	s->cancel	= usbduxsigma_ao_cancel;
+
+	/* Digital I/O subdevice */
+	s = &dev->subdevices[2];
+	s->type		= COMEDI_SUBD_DIO;
+	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
+	s->n_chan	= 24;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= usbduxsigma_dio_insn_bits;
+	s->insn_config	= usbduxsigma_dio_insn_config;
+
+	if (devpriv->high_speed) {
+		/* Timer / pwm subdevice */
+		s = &dev->subdevices[3];
+		s->type		= COMEDI_SUBD_PWM;
+		s->subdev_flags	= SDF_WRITABLE | SDF_PWM_HBRIDGE;
+		s->n_chan	= 8;
+		s->maxdata	= devpriv->pwm_buf_sz;
+		s->insn_write	= usbduxsigma_pwm_write;
+		s->insn_config	= usbduxsigma_pwm_config;
+
+		usbduxsigma_pwm_period(dev, s, PWM_DEFAULT_PERIOD);
 	}
-	/* finally decide that it's attached */
-	uds->attached = 1;
-	up(&uds->sem);
-	offset = usbdux_getstatusinfo(dev, 0);
-	if (offset < 0)
-		dev_err(&uds->interface->dev,
-			"Communication to USBDUXSIGMA failed! Check firmware and cabling.");
-	dev_info(&uds->interface->dev,
-		 "comedi%d: attached, ADC_zero = %x\n", dev->minor, offset);
-	return 0;
-}
 
-static int usbduxsigma_auto_attach(struct comedi_device *dev,
-				   unsigned long context_unused)
-{
-	struct usb_interface *uinterf = comedi_to_usb_interface(dev);
-	int ret;
-	struct usbduxsub *uds;
+	up(&devpriv->sem);
 
-	dev->private = NULL;
-	down(&start_stop_sem);
-	uds = usb_get_intfdata(uinterf);
-	if (!uds || !uds->probed) {
-		dev_err(dev->class_dev,
-			"usbduxsigma: error: auto_attach failed, not connected\n");
-		ret = -ENODEV;
-	} else if (uds->attached) {
+	offset = usbduxsigma_getstatusinfo(dev, 0);
+	if (offset < 0)
 		dev_err(dev->class_dev,
-		       "usbduxsigma: error: auto_attach failed, already attached\n");
-		ret = -ENODEV;
-	} else
-		ret = usbduxsigma_attach_common(dev, uds);
-	up(&start_stop_sem);
-	return ret;
-}
+			"Communication to USBDUXSIGMA failed! Check firmware and cabling\n");
 
-static void usbduxsigma_detach(struct comedi_device *dev)
-{
-	struct usbduxsub *usb = dev->private;
+	dev_info(dev->class_dev, "attached, ADC_zero = %x\n", offset);
 
-	if (usb) {
-		down(&usb->sem);
-		dev->private = NULL;
-		usb->attached = 0;
-		usb->comedidev = NULL;
-		up(&usb->sem);
-	}
+	return 0;
 }
 
-static struct comedi_driver usbduxsigma_driver = {
-	.driver_name	= "usbduxsigma",
-	.module		= THIS_MODULE,
-	.auto_attach	= usbduxsigma_auto_attach,
-	.detach		= usbduxsigma_detach,
-};
-
-static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
-						     void *context)
+static int usbduxsigma_firmware_upload(struct comedi_device *dev,
+				       const u8 *data, size_t size,
+				       unsigned long context)
 {
-	struct usbduxsub *usbduxsub_tmp = context;
-	struct usb_interface *uinterf = usbduxsub_tmp->interface;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	uint8_t *buf;
+	uint8_t *tmp;
 	int ret;
 
-	if (fw == NULL) {
-		dev_err(&uinterf->dev,
-			"Firmware complete handler without firmware!\n");
-		return;
-	}
-
-	/*
-	 * we need to upload the firmware here because fw will be
-	 * freed once we've left this function
-	 */
-	ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size);
+	if (!data)
+		return 0;
 
-	if (ret) {
-		dev_err(&uinterf->dev,
-			"Could not upload firmware (err=%d)\n", ret);
-		goto out;
+	if (size > FIRMWARE_MAX_LEN) {
+		dev_err(dev->class_dev, "firmware binary too large for FX2\n");
+		return -ENOMEM;
 	}
-	comedi_usb_auto_config(uinterf, &usbduxsigma_driver, 0);
-out:
-	release_firmware(fw);
-}
 
-static int usbduxsigma_usb_probe(struct usb_interface *uinterf,
-				 const struct usb_device_id *id)
-{
-	struct usb_device *udev = interface_to_usbdev(uinterf);
-	struct device *dev = &uinterf->dev;
-	int i;
-	int index;
-	int ret;
-
-	dev_dbg(dev, "comedi_: usbdux_: "
-		"finding a free structure for the usb-device\n");
+	/* we generate a local buffer for the firmware */
+	buf = kmemdup(data, size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
-	down(&start_stop_sem);
-	/* look for a free place in the usbdux array */
-	index = -1;
-	for (i = 0; i < NUMUSBDUX; i++) {
-		if (!(usbduxsub[i].probed)) {
-			index = i;
-			break;
-		}
+	/* we need a malloc'ed buffer for usb_control_msg() */
+	tmp = kmalloc(1, GFP_KERNEL);
+	if (!tmp) {
+		kfree(buf);
+		return -ENOMEM;
 	}
 
-	/* no more space */
-	if (index == -1) {
-		dev_err(dev, "Too many usbduxsigma-devices connected.\n");
-		up(&start_stop_sem);
-		return -EMFILE;
+	/* stop the current firmware on the device */
+	*tmp = 1;	/* 7f92 to one */
+	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
+			      USBDUXSUB_FIRMWARE,
+			      VENDOR_DIR_OUT,
+			      USBDUXSUB_CPUCS, 0x0000,
+			      tmp, 1,
+			      BULK_TIMEOUT);
+	if (ret < 0) {
+		dev_err(dev->class_dev, "can not stop firmware\n");
+		goto done;
 	}
-	dev_dbg(dev, "comedi_: usbdux: "
-		"usbduxsub[%d] is ready to connect to comedi.\n", index);
 
-	sema_init(&(usbduxsub[index].sem), 1);
-	/* save a pointer to the usb device */
-	usbduxsub[index].usbdev = udev;
+	/* upload the new firmware to the device */
+	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
+			      USBDUXSUB_FIRMWARE,
+			      VENDOR_DIR_OUT,
+			      0, 0x0000,
+			      buf, size,
+			      BULK_TIMEOUT);
+	if (ret < 0) {
+		dev_err(dev->class_dev, "firmware upload failed\n");
+		goto done;
+	}
 
-	/* save the interface itself */
-	usbduxsub[index].interface = uinterf;
-	/* get the interface number from the interface */
-	usbduxsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
-	/* hand the private data over to the usb subsystem */
-	/* will be needed for disconnect */
-	usb_set_intfdata(uinterf, &(usbduxsub[index]));
+	/* start the new firmware on the device */
+	*tmp = 0;	/* 7f92 to zero */
+	ret = usb_control_msg(usb, usb_sndctrlpipe(usb, 0),
+			      USBDUXSUB_FIRMWARE,
+			      VENDOR_DIR_OUT,
+			      USBDUXSUB_CPUCS, 0x0000,
+			      tmp, 1,
+			      BULK_TIMEOUT);
+	if (ret < 0)
+		dev_err(dev->class_dev, "can not start firmware\n");
 
-	dev_dbg(dev, "comedi_: usbdux: ifnum=%d\n", usbduxsub[index].ifnum);
+done:
+	kfree(tmp);
+	kfree(buf);
+	return ret;
+}
 
-	/* test if it is high speed (USB 2.0) */
-	usbduxsub[index].high_speed =
-	    (usbduxsub[index].usbdev->speed == USB_SPEED_HIGH);
+static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev)
+{
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxsigma_private *devpriv = dev->private;
+	struct urb *urb;
+	int i;
 
-	/* create space for the commands of the DA converter */
-	usbduxsub[index].dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
-	if (!usbduxsub[index].dac_commands) {
-		tidy_up(&(usbduxsub[index]));
-		up(&start_stop_sem);
-		return -ENOMEM;
-	}
-	/* create space for the commands going to the usb device */
-	usbduxsub[index].dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
-	if (!usbduxsub[index].dux_commands) {
-		tidy_up(&(usbduxsub[index]));
-		up(&start_stop_sem);
-		return -ENOMEM;
-	}
-	/* create space for the in buffer and set it to zero */
-	usbduxsub[index].inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
-	if (!(usbduxsub[index].inBuffer)) {
-		tidy_up(&(usbduxsub[index]));
-		up(&start_stop_sem);
-		return -ENOMEM;
-	}
-	/* create space of the instruction buffer */
-	usbduxsub[index].insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
-	if (!(usbduxsub[index].insnBuffer)) {
-		tidy_up(&(usbduxsub[index]));
-		up(&start_stop_sem);
-		return -ENOMEM;
-	}
-	/* create space for the outbuffer */
-	usbduxsub[index].outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
-	if (!(usbduxsub[index].outBuffer)) {
-		tidy_up(&(usbduxsub[index]));
-		up(&start_stop_sem);
+	devpriv->dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
+	devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL);
+	devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL);
+	devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL);
+	devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(*urb),
+				   GFP_KERNEL);
+	devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(*urb),
+				   GFP_KERNEL);
+	if (!devpriv->dac_commands || !devpriv->dux_commands ||
+	    !devpriv->in_buf || !devpriv->insn_buf ||
+	    !devpriv->ai_urbs || !devpriv->ao_urbs)
 		return -ENOMEM;
-	}
-	/* setting to alternate setting 3: enabling iso ep and bulk ep. */
-	i = usb_set_interface(usbduxsub[index].usbdev,
-			      usbduxsub[index].ifnum, 3);
-	if (i < 0) {
-		dev_err(dev, "comedi_: usbduxsigma%d: "
-			"could not set alternate setting 3 in high speed.\n",
-			index);
-		tidy_up(&(usbduxsub[index]));
-		up(&start_stop_sem);
-		return -ENODEV;
-	}
-	if (usbduxsub[index].high_speed)
-		usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSHIGH;
-	else
-		usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSFULL;
 
-	usbduxsub[index].urbIn = kcalloc(usbduxsub[index].numOfInBuffers,
-					 sizeof(struct urb *),
-					 GFP_KERNEL);
-	if (!(usbduxsub[index].urbIn)) {
-		tidy_up(&(usbduxsub[index]));
-		up(&start_stop_sem);
-		return -ENOMEM;
-	}
-	for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) {
+	for (i = 0; i < devpriv->n_ai_urbs; i++) {
 		/* one frame: 1ms */
-		usbduxsub[index].urbIn[i] = usb_alloc_urb(1, GFP_KERNEL);
-		if (usbduxsub[index].urbIn[i] == NULL) {
-			dev_err(dev, "comedi_: usbduxsigma%d: "
-				"Could not alloc. urb(%d)\n", index, i);
-			tidy_up(&(usbduxsub[index]));
-			up(&start_stop_sem);
+		urb = usb_alloc_urb(1, GFP_KERNEL);
+		if (!urb)
 			return -ENOMEM;
-		}
-		usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev;
+		devpriv->ai_urbs[i] = urb;
+		urb->dev = usb;
 		/* will be filled later with a pointer to the comedi-device */
 		/* and ONLY then the urb should be submitted */
-		usbduxsub[index].urbIn[i]->context = NULL;
-		usbduxsub[index].urbIn[i]->pipe =
-		    usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
-		usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP;
-		usbduxsub[index].urbIn[i]->transfer_buffer =
-		    kzalloc(SIZEINBUF, GFP_KERNEL);
-		if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) {
-			tidy_up(&(usbduxsub[index]));
-			up(&start_stop_sem);
+		urb->context = NULL;
+		urb->pipe = usb_rcvisocpipe(usb, USBDUXSIGMA_ISO_IN_EP);
+		urb->transfer_flags = URB_ISO_ASAP;
+		urb->transfer_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
+		if (!urb->transfer_buffer)
 			return -ENOMEM;
-		}
-		usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq;
-		usbduxsub[index].urbIn[i]->number_of_packets = 1;
-		usbduxsub[index].urbIn[i]->transfer_buffer_length = SIZEINBUF;
-		usbduxsub[index].urbIn[i]->iso_frame_desc[0].offset = 0;
-		usbduxsub[index].urbIn[i]->iso_frame_desc[0].length =
-			SIZEINBUF;
+		urb->complete = usbduxsigma_ai_urb_complete;
+		urb->number_of_packets = 1;
+		urb->transfer_buffer_length = SIZEINBUF;
+		urb->iso_frame_desc[0].offset = 0;
+		urb->iso_frame_desc[0].length = SIZEINBUF;
 	}
 
-	/* out */
-	if (usbduxsub[index].high_speed)
-		usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
-	else
-		usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSFULL;
-
-	usbduxsub[index].urbOut = kcalloc(usbduxsub[index].numOfOutBuffers,
-					  sizeof(struct urb *), GFP_KERNEL);
-	if (!(usbduxsub[index].urbOut)) {
-		tidy_up(&(usbduxsub[index]));
-		up(&start_stop_sem);
-		return -ENOMEM;
-	}
-	for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) {
+	for (i = 0; i < devpriv->n_ao_urbs; i++) {
 		/* one frame: 1ms */
-		usbduxsub[index].urbOut[i] = usb_alloc_urb(1, GFP_KERNEL);
-		if (usbduxsub[index].urbOut[i] == NULL) {
-			dev_err(dev, "comedi_: usbduxsigma%d: "
-				"Could not alloc. urb(%d)\n", index, i);
-			tidy_up(&(usbduxsub[index]));
-			up(&start_stop_sem);
+		urb = usb_alloc_urb(1, GFP_KERNEL);
+		if (!urb)
 			return -ENOMEM;
-		}
-		usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev;
+		devpriv->ao_urbs[i] = urb;
+		urb->dev = usb;
 		/* will be filled later with a pointer to the comedi-device */
 		/* and ONLY then the urb should be submitted */
-		usbduxsub[index].urbOut[i]->context = NULL;
-		usbduxsub[index].urbOut[i]->pipe =
-		    usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
-		usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP;
-		usbduxsub[index].urbOut[i]->transfer_buffer =
-		    kzalloc(SIZEOUTBUF, GFP_KERNEL);
-		if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) {
-			tidy_up(&(usbduxsub[index]));
-			up(&start_stop_sem);
+		urb->context = NULL;
+		urb->pipe = usb_sndisocpipe(usb, USBDUXSIGMA_ISO_OUT_EP);
+		urb->transfer_flags = URB_ISO_ASAP;
+		urb->transfer_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
+		if (!urb->transfer_buffer)
 			return -ENOMEM;
-		}
-		usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq;
-		usbduxsub[index].urbOut[i]->number_of_packets = 1;
-		usbduxsub[index].urbOut[i]->transfer_buffer_length =
-			SIZEOUTBUF;
-		usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0;
-		usbduxsub[index].urbOut[i]->iso_frame_desc[0].length =
-		    SIZEOUTBUF;
-		if (usbduxsub[index].high_speed) {
-			/* uframes */
-			usbduxsub[index].urbOut[i]->interval = 8;
-		} else {
-			/* frames */
-			usbduxsub[index].urbOut[i]->interval = 1;
-		}
+		urb->complete = usbduxsigma_ao_urb_complete;
+		urb->number_of_packets = 1;
+		urb->transfer_buffer_length = SIZEOUTBUF;
+		urb->iso_frame_desc[0].offset = 0;
+		urb->iso_frame_desc[0].length = SIZEOUTBUF;
+		if (devpriv->high_speed)
+			urb->interval = 8;	/* uframes */
+		else
+			urb->interval = 1;	/* frames */
 	}
 
-	/* pwm */
-	if (usbduxsub[index].high_speed) {
+	if (devpriv->high_speed) {
 		/* max bulk ep size in high speed */
-		usbduxsub[index].sizePwmBuf = 512;
-		usbduxsub[index].urbPwm = usb_alloc_urb(0, GFP_KERNEL);
-		if (usbduxsub[index].urbPwm == NULL) {
-			dev_err(dev, "comedi_: usbduxsigma%d: "
-				"Could not alloc. pwm urb\n", index);
-			tidy_up(&(usbduxsub[index]));
-			up(&start_stop_sem);
+		devpriv->pwm_buf_sz = 512;
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!urb)
 			return -ENOMEM;
-		}
-		usbduxsub[index].urbPwm->transfer_buffer =
-		    kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL);
-		if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
-			tidy_up(&(usbduxsub[index]));
-			up(&start_stop_sem);
+		devpriv->pwm_urb = urb;
+		urb->transfer_buffer = kzalloc(devpriv->pwm_buf_sz, GFP_KERNEL);
+		if (!urb->transfer_buffer)
 			return -ENOMEM;
-		}
 	} else {
-		usbduxsub[index].urbPwm = NULL;
-		usbduxsub[index].sizePwmBuf = 0;
+		devpriv->pwm_urb = NULL;
+		devpriv->pwm_buf_sz = 0;
 	}
 
-	usbduxsub[index].ai_cmd_running = 0;
-	usbduxsub[index].ao_cmd_running = 0;
-	usbduxsub[index].pwm_cmd_running = 0;
+	return 0;
+}
 
-	/* we've reached the bottom of the function */
-	usbduxsub[index].probed = 1;
-	up(&start_stop_sem);
+static void usbduxsigma_free_usb_buffers(struct comedi_device *dev)
+{
+	struct usbduxsigma_private *devpriv = dev->private;
+	struct urb *urb;
+	int i;
 
-	ret = reject_firmware_nowait(THIS_MODULE,
-				      FW_ACTION_HOTPLUG,
-				      FIRMWARE,
-				      &udev->dev,
-				      GFP_KERNEL,
-				      usbduxsub + index,
-				      usbdux_firmware_request_complete_handler
-				      );
+	/* force unlink all urbs */
+	usbduxsigma_ai_stop(dev, 1);
+	usbduxsigma_ao_stop(dev, 1);
+	usbduxsigma_pwm_stop(dev, 1);
 
-	if (ret) {
-		dev_err(dev, "Could not load firmware (err=%d)\n", ret);
-		return ret;
+	urb = devpriv->pwm_urb;
+	if (urb) {
+		kfree(urb->transfer_buffer);
+		usb_free_urb(urb);
 	}
-
-	dev_info(dev, "comedi_: successfully initialised.\n");
-	/* success */
-	return 0;
+	if (devpriv->ao_urbs) {
+		for (i = 0; i < devpriv->n_ao_urbs; i++) {
+			urb = devpriv->ao_urbs[i];
+			if (urb) {
+				kfree(urb->transfer_buffer);
+				usb_free_urb(urb);
+			}
+		}
+		kfree(devpriv->ao_urbs);
+	}
+	if (devpriv->ai_urbs) {
+		for (i = 0; i < devpriv->n_ai_urbs; i++) {
+			urb = devpriv->ai_urbs[i];
+			if (urb) {
+				kfree(urb->transfer_buffer);
+				usb_free_urb(urb);
+			}
+		}
+		kfree(devpriv->ai_urbs);
+	}
+	kfree(devpriv->insn_buf);
+	kfree(devpriv->in_buf);
+	kfree(devpriv->dux_commands);
+	kfree(devpriv->dac_commands);
 }
 
-static void usbduxsigma_usb_disconnect(struct usb_interface *intf)
+static int usbduxsigma_auto_attach(struct comedi_device *dev,
+				   unsigned long context_unused)
 {
-	struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf);
-	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
+	struct usb_device *usb = comedi_to_usb_dev(dev);
+	struct usbduxsigma_private *devpriv;
+	int ret;
 
-	if (!usbduxsub_tmp) {
-		dev_err(&intf->dev,
-			"comedi_: disconnect called with null pointer.\n");
-		return;
+	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+	if (!devpriv)
+		return -ENOMEM;
+	dev->private = devpriv;
+
+	sema_init(&devpriv->sem, 1);
+	usb_set_intfdata(intf, devpriv);
+
+	ret = usb_set_interface(usb,
+				intf->altsetting->desc.bInterfaceNumber, 3);
+	if (ret < 0) {
+		dev_err(dev->class_dev,
+			"could not set alternate setting 3 in high speed\n");
+		return -ENODEV;
 	}
-	if (usbduxsub_tmp->usbdev != udev) {
-		dev_err(&intf->dev, "comedi_: BUG! wrong ptr!\n");
-		return;
+
+	/* test if it is high speed (USB 2.0) */
+	devpriv->high_speed = (usb->speed == USB_SPEED_HIGH);
+	if (devpriv->high_speed) {
+		devpriv->n_ai_urbs = NUMOFINBUFFERSHIGH;
+		devpriv->n_ao_urbs = NUMOFOUTBUFFERSHIGH;
+	} else {
+		devpriv->n_ai_urbs = NUMOFINBUFFERSFULL;
+		devpriv->n_ao_urbs = NUMOFOUTBUFFERSFULL;
 	}
-	if (usbduxsub_tmp->ai_cmd_running)
-		/* we are still running a command */
-		usbdux_ai_stop(usbduxsub_tmp, 1);
-	if (usbduxsub_tmp->ao_cmd_running)
-		/* we are still running a command */
-		usbdux_ao_stop(usbduxsub_tmp, 1);
-	comedi_usb_auto_unconfig(intf);
-	down(&start_stop_sem);
-	down(&usbduxsub_tmp->sem);
-	tidy_up(usbduxsub_tmp);
-	up(&usbduxsub_tmp->sem);
-	up(&start_stop_sem);
-	dev_info(&intf->dev, "comedi_: disconnected from the usb\n");
+
+	ret = usbduxsigma_alloc_usb_buffers(dev);
+	if (ret)
+		return ret;
+
+	ret = comedi_load_firmware(dev, &usb->dev, FIRMWARE,
+				   usbduxsigma_firmware_upload, 0);
+	if (ret)
+		return ret;
+
+	return usbduxsigma_attach_common(dev);
+}
+
+static void usbduxsigma_detach(struct comedi_device *dev)
+{
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
+	struct usbduxsigma_private *devpriv = dev->private;
+
+	if (!devpriv)
+		return;
+
+	usb_set_intfdata(intf, NULL);
+
+	down(&devpriv->sem);
+	usbduxsigma_free_usb_buffers(dev);
+	up(&devpriv->sem);
+}
+
+static struct comedi_driver usbduxsigma_driver = {
+	.driver_name	= "usbduxsigma",
+	.module		= THIS_MODULE,
+	.auto_attach	= usbduxsigma_auto_attach,
+	.detach		= usbduxsigma_detach,
+};
+
+static int usbduxsigma_usb_probe(struct usb_interface *intf,
+				 const struct usb_device_id *id)
+{
+	return comedi_usb_auto_config(intf, &usbduxsigma_driver, 0);
 }
 
 static const struct usb_device_id usbduxsigma_usb_table[] = {
@@ -2664,7 +1754,7 @@ MODULE_DEVICE_TABLE(usb, usbduxsigma_usb
 static struct usb_driver usbduxsigma_usb_driver = {
 	.name		= "usbduxsigma",
 	.probe		= usbduxsigma_usb_probe,
-	.disconnect	= usbduxsigma_usb_disconnect,
+	.disconnect	= comedi_usb_auto_unconfig,
 	.id_table	= usbduxsigma_usb_table,
 };
 module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers/vmk80xx.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/vmk80xx.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers/vmk80xx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers/vmk80xx.c	2013-08-25 20:43:22.000000000 -0400
@@ -16,11 +16,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 /*
 Driver: vmk80xx
@@ -159,8 +154,6 @@ static const struct vmk80xx_board vmk80x
 };
 
 struct vmk80xx_private {
-	struct usb_device *usb;
-	struct usb_interface *intf;
 	struct usb_endpoint_descriptor *ep_rx;
 	struct usb_endpoint_descriptor *ep_tx;
 	struct firmware_version fw;
@@ -170,9 +163,10 @@ struct vmk80xx_private {
 	enum vmk80xx_model model;
 };
 
-static int vmk80xx_check_data_link(struct vmk80xx_private *devpriv)
+static int vmk80xx_check_data_link(struct comedi_device *dev)
 {
-	struct usb_device *usb = devpriv->usb;
+	struct vmk80xx_private *devpriv = dev->private;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
 	unsigned int tx_pipe;
 	unsigned int rx_pipe;
 	unsigned char tx[1];
@@ -194,9 +188,10 @@ static int vmk80xx_check_data_link(struc
 	return (int)rx[1];
 }
 
-static void vmk80xx_read_eeprom(struct vmk80xx_private *devpriv, int flag)
+static void vmk80xx_read_eeprom(struct comedi_device *dev, int flag)
 {
-	struct usb_device *usb = devpriv->usb;
+	struct vmk80xx_private *devpriv = dev->private;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
 	unsigned int tx_pipe;
 	unsigned int rx_pipe;
 	unsigned char tx[1];
@@ -223,9 +218,10 @@ static void vmk80xx_read_eeprom(struct v
 		strncpy(devpriv->fw.ic6_vers, rx + 25, 24);
 }
 
-static void vmk80xx_do_bulk_msg(struct vmk80xx_private *devpriv)
+static void vmk80xx_do_bulk_msg(struct comedi_device *dev)
 {
-	struct usb_device *usb = devpriv->usb;
+	struct vmk80xx_private *devpriv = dev->private;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
 	__u8 tx_addr;
 	__u8 rx_addr;
 	unsigned int tx_pipe;
@@ -248,21 +244,18 @@ static void vmk80xx_do_bulk_msg(struct v
 	usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, size, NULL, HZ * 10);
 }
 
-static int vmk80xx_read_packet(struct vmk80xx_private *devpriv)
+static int vmk80xx_read_packet(struct comedi_device *dev)
 {
-	struct usb_device *usb;
+	struct vmk80xx_private *devpriv = dev->private;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
 	struct usb_endpoint_descriptor *ep;
 	unsigned int pipe;
 
-	if (!devpriv->intf)
-		return -ENODEV;
-
 	if (devpriv->model == VMK8061_MODEL) {
-		vmk80xx_do_bulk_msg(devpriv);
+		vmk80xx_do_bulk_msg(dev);
 		return 0;
 	}
 
-	usb = devpriv->usb;
 	ep = devpriv->ep_rx;
 	pipe = usb_rcvintpipe(usb, ep->bEndpointAddress);
 	return usb_interrupt_msg(usb, pipe, devpriv->usb_rx_buf,
@@ -270,23 +263,20 @@ static int vmk80xx_read_packet(struct vm
 				 HZ * 10);
 }
 
-static int vmk80xx_write_packet(struct vmk80xx_private *devpriv, int cmd)
+static int vmk80xx_write_packet(struct comedi_device *dev, int cmd)
 {
-	struct usb_device *usb;
+	struct vmk80xx_private *devpriv = dev->private;
+	struct usb_device *usb = comedi_to_usb_dev(dev);
 	struct usb_endpoint_descriptor *ep;
 	unsigned int pipe;
 
-	if (!devpriv->intf)
-		return -ENODEV;
-
 	devpriv->usb_tx_buf[0] = cmd;
 
 	if (devpriv->model == VMK8061_MODEL) {
-		vmk80xx_do_bulk_msg(devpriv);
+		vmk80xx_do_bulk_msg(dev);
 		return 0;
 	}
 
-	usb = devpriv->usb;
 	ep = devpriv->ep_tx;
 	pipe = usb_sndintpipe(usb, ep->bEndpointAddress);
 	return usb_interrupt_msg(usb, pipe, devpriv->usb_tx_buf,
@@ -294,18 +284,19 @@ static int vmk80xx_write_packet(struct v
 				 HZ * 10);
 }
 
-static int vmk80xx_reset_device(struct vmk80xx_private *devpriv)
+static int vmk80xx_reset_device(struct comedi_device *dev)
 {
+	struct vmk80xx_private *devpriv = dev->private;
 	size_t size;
 	int retval;
 
 	size = le16_to_cpu(devpriv->ep_tx->wMaxPacketSize);
 	memset(devpriv->usb_tx_buf, 0, size);
-	retval = vmk80xx_write_packet(devpriv, VMK8055_CMD_RST);
+	retval = vmk80xx_write_packet(dev, VMK8055_CMD_RST);
 	if (retval)
 		return retval;
 	/* set outputs to known state as we cannot read them */
-	return vmk80xx_write_packet(devpriv, VMK8055_CMD_WRT_AD);
+	return vmk80xx_write_packet(dev, VMK8055_CMD_WRT_AD);
 }
 
 static int vmk80xx_ai_insn_read(struct comedi_device *dev,
@@ -338,7 +329,7 @@ static int vmk80xx_ai_insn_read(struct c
 	}
 
 	for (n = 0; n < insn->n; n++) {
-		if (vmk80xx_read_packet(devpriv))
+		if (vmk80xx_read_packet(dev))
 			break;
 
 		if (devpriv->model == VMK8055_MODEL) {
@@ -388,7 +379,7 @@ static int vmk80xx_ao_insn_write(struct
 	for (n = 0; n < insn->n; n++) {
 		devpriv->usb_tx_buf[reg] = data[n];
 
-		if (vmk80xx_write_packet(devpriv, cmd))
+		if (vmk80xx_write_packet(dev, cmd))
 			break;
 	}
 
@@ -415,7 +406,7 @@ static int vmk80xx_ao_insn_read(struct c
 	devpriv->usb_tx_buf[0] = VMK8061_CMD_RD_AO;
 
 	for (n = 0; n < insn->n; n++) {
-		if (vmk80xx_read_packet(devpriv))
+		if (vmk80xx_read_packet(dev))
 			break;
 
 		data[n] = devpriv->usb_rx_buf[reg + chan];
@@ -447,7 +438,7 @@ static int vmk80xx_di_insn_bits(struct c
 		reg = VMK8055_DI_REG;
 	}
 
-	retval = vmk80xx_read_packet(devpriv);
+	retval = vmk80xx_read_packet(dev);
 
 	if (!retval) {
 		if (devpriv->model == VMK8055_MODEL)
@@ -492,7 +483,7 @@ static int vmk80xx_do_insn_bits(struct c
 		tx_buf[reg] &= ~data[0];
 		tx_buf[reg] |= (data[0] & data[1]);
 
-		retval = vmk80xx_write_packet(devpriv, cmd);
+		retval = vmk80xx_write_packet(dev, cmd);
 
 		if (retval)
 			goto out;
@@ -501,7 +492,7 @@ static int vmk80xx_do_insn_bits(struct c
 	if (devpriv->model == VMK8061_MODEL) {
 		tx_buf[0] = VMK8061_CMD_RD_DO;
 
-		retval = vmk80xx_read_packet(devpriv);
+		retval = vmk80xx_read_packet(dev);
 
 		if (!retval) {
 			data[1] = rx_buf[reg];
@@ -547,7 +538,7 @@ static int vmk80xx_cnt_insn_read(struct
 	}
 
 	for (n = 0; n < insn->n; n++) {
-		if (vmk80xx_read_packet(devpriv))
+		if (vmk80xx_read_packet(dev))
 			break;
 
 		if (devpriv->model == VMK8055_MODEL)
@@ -597,7 +588,7 @@ static int vmk80xx_cnt_insn_config(struc
 	}
 
 	for (n = 0; n < insn->n; n++)
-		if (vmk80xx_write_packet(devpriv, cmd))
+		if (vmk80xx_write_packet(dev, cmd))
 			break;
 
 	up(&devpriv->limit_sem);
@@ -640,7 +631,7 @@ static int vmk80xx_cnt_insn_write(struct
 
 		devpriv->usb_tx_buf[6 + chan] = val;
 
-		if (vmk80xx_write_packet(devpriv, cmd))
+		if (vmk80xx_write_packet(dev, cmd))
 			break;
 	}
 
@@ -671,7 +662,7 @@ static int vmk80xx_pwm_insn_read(struct
 	tx_buf[0] = VMK8061_CMD_RD_PWM;
 
 	for (n = 0; n < insn->n; n++) {
-		if (vmk80xx_read_packet(devpriv))
+		if (vmk80xx_read_packet(dev))
 			break;
 
 		data[n] = rx_buf[reg[0]] + 4 * rx_buf[reg[1]];
@@ -719,7 +710,7 @@ static int vmk80xx_pwm_insn_write(struct
 		tx_buf[reg[0]] = (unsigned char)(data[n] & 0x03);
 		tx_buf[reg[1]] = (unsigned char)(data[n] >> 2) & 0xff;
 
-		if (vmk80xx_write_packet(devpriv, cmd))
+		if (vmk80xx_write_packet(dev, cmd))
 			break;
 	}
 
@@ -731,7 +722,7 @@ static int vmk80xx_pwm_insn_write(struct
 static int vmk80xx_find_usb_endpoints(struct comedi_device *dev)
 {
 	struct vmk80xx_private *devpriv = dev->private;
-	struct usb_interface *intf = devpriv->intf;
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
 	struct usb_host_interface *iface_desc = intf->cur_altsetting;
 	struct usb_endpoint_descriptor *ep_desc;
 	int i;
@@ -889,8 +880,6 @@ static int vmk80xx_auto_attach(struct co
 		return -ENOMEM;
 	dev->private = devpriv;
 
-	devpriv->usb = interface_to_usbdev(intf);
-	devpriv->intf = intf;
 	devpriv->model = boardinfo->model;
 
 	ret = vmk80xx_find_usb_endpoints(dev);
@@ -906,23 +895,24 @@ static int vmk80xx_auto_attach(struct co
 	usb_set_intfdata(intf, devpriv);
 
 	if (devpriv->model == VMK8061_MODEL) {
-		vmk80xx_read_eeprom(devpriv, IC3_VERSION);
+		vmk80xx_read_eeprom(dev, IC3_VERSION);
 		dev_info(&intf->dev, "%s\n", devpriv->fw.ic3_vers);
 
-		if (vmk80xx_check_data_link(devpriv)) {
-			vmk80xx_read_eeprom(devpriv, IC6_VERSION);
+		if (vmk80xx_check_data_link(dev)) {
+			vmk80xx_read_eeprom(dev, IC6_VERSION);
 			dev_info(&intf->dev, "%s\n", devpriv->fw.ic6_vers);
 		}
 	}
 
 	if (devpriv->model == VMK8055_MODEL)
-		vmk80xx_reset_device(devpriv);
+		vmk80xx_reset_device(dev);
 
 	return vmk80xx_init_subdevices(dev);
 }
 
 static void vmk80xx_detach(struct comedi_device *dev)
 {
+	struct usb_interface *intf = comedi_to_usb_interface(dev);
 	struct vmk80xx_private *devpriv = dev->private;
 
 	if (!devpriv)
@@ -930,7 +920,7 @@ static void vmk80xx_detach(struct comedi
 
 	down(&devpriv->limit_sem);
 
-	usb_set_intfdata(devpriv->intf, NULL);
+	usb_set_intfdata(intf, NULL);
 
 	kfree(devpriv->usb_rx_buf);
 	kfree(devpriv->usb_tx_buf);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/drivers.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/drivers.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/drivers.c	2013-08-31 18:01:48.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #include <linux/device.h>
@@ -38,6 +33,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
+#include <linux/firmware.h>
 
 #include "comedidev.h"
 #include "comedi_internal.h"
@@ -87,18 +83,6 @@ int comedi_alloc_subdevices(struct comed
 }
 EXPORT_SYMBOL_GPL(comedi_alloc_subdevices);
 
-void comedi_spriv_free(struct comedi_device *dev, int subdev_num)
-{
-	struct comedi_subdevice *s;
-
-	if (dev->subdevices && subdev_num < dev->n_subdevices) {
-		s = &dev->subdevices[subdev_num];
-		kfree(s->private);
-		s->private = NULL;
-	}
-}
-EXPORT_SYMBOL_GPL(comedi_spriv_free);
-
 static void cleanup_device(struct comedi_device *dev)
 {
 	int i;
@@ -107,6 +91,8 @@ static void cleanup_device(struct comedi
 	if (dev->subdevices) {
 		for (i = 0; i < dev->n_subdevices; i++) {
 			s = &dev->subdevices[i];
+			if (s->runflags & SRF_FREE_SPRIV)
+				kfree(s->private);
 			comedi_free_subdevice_minor(s);
 			if (s->async) {
 				comedi_buf_alloc(dev, s, 0);
@@ -352,6 +338,38 @@ static void comedi_report_boards(struct
 }
 
 /**
+ * comedi_load_firmware() - Request and load firmware for a device.
+ * @dev: comedi_device struct
+ * @hw_device: device struct for the comedi_device
+ * @name: the name of the firmware image
+ * @cb: callback to the upload the firmware image
+ * @context: private context from the driver
+ */
+int comedi_load_firmware(struct comedi_device *dev,
+			 struct device *device,
+			 const char *name,
+			 int (*cb)(struct comedi_device *dev,
+				   const u8 *data, size_t size,
+				   unsigned long context),
+			 unsigned long context)
+{
+	const struct firmware *fw;
+	int ret;
+
+	if (!cb)
+		return -EINVAL;
+
+	ret = reject_firmware(&fw, name, device);
+	if (ret == 0) {
+		ret = cb(dev, fw->data, fw->size, context);
+		release_firmware(fw);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(comedi_load_firmware);
+
+/**
  * __comedi_request_region() - Request an I/O reqion for a legacy driver.
  * @dev: comedi_device struct
  * @start: base address of the I/O reqion
@@ -464,7 +482,7 @@ int comedi_device_attach(struct comedi_d
 		ret = comedi_device_postconfig(dev);
 	if (ret < 0) {
 		comedi_device_detach(dev);
-		module_put(dev->driver->module);
+		module_put(driv->module);
 	}
 	/* On success, the driver module count has been incremented. */
 	return ret;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/kcomedilib/kcomedilib_main.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/kcomedilib/kcomedilib_main.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/kcomedilib/kcomedilib_main.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #include <linux/module.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/comedi/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/comedi/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -110,15 +110,6 @@ menuconfig COMEDI_ISA_DRIVERS
 
 if COMEDI_ISA_DRIVERS
 
-config COMEDI_ACL7225B
-	tristate "ADlink NuDAQ ACL-7225b and compatibles support"
-	---help---
-	  Enable support for ADlink NuDAQ ACL-7225b and compatibles,
-	  ADlink ACL-7225b (acl7225b), ICP P16R16DIO (p16r16dio)
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called acl7225b.
-
 config COMEDI_PCL711
 	tristate "Advantech PCL-711/711b and ADlink ACL-8112 ISA card support"
 	---help---
@@ -137,14 +128,6 @@ config COMEDI_PCL724
 	  To compile this driver as a module, choose M here: the module will be
 	  called pcl724.
 
-config COMEDI_PCL725
-	tristate "Advantech PCL-725 and compatible ISA card support"
-	---help---
-	  Enable support for Advantech PCL-725 and compatible ISA cards.
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called pcl725.
-
 config COMEDI_PCL726
 	tristate "Advantech PCL-726 and compatible ISA card support"
 	---help---
@@ -154,10 +137,21 @@ config COMEDI_PCL726
 	  called pcl726.
 
 config COMEDI_PCL730
-	tristate "Advantech PCL-730 and ADlink ACL-7130 ISA card support"
+	tristate "Simple Digital I/O board support (8-bit ports)"
 	---help---
-	  Enable support for Advantech PCL-730, ICP ISO-730 and ADlink
-	  ACL-7130 ISA cards
+	  Enable support for various simple ISA or PC/104 Digital I/O boards.
+	  These boards all use 8-bit I/O ports.
+
+	  Advantech PCL-730   isolated - 16 in/16 out  ttl - 16 in/16 out
+	  ICP ISO-730         isolated - 16 in/16 out  ttl - 16 in/16 out
+	  ADlink ACL-7130     isolated - 16 in/16 out  ttl - 16 in/16 out
+	  Advantech PCM-3730  isolated - 8 in/8 out    ttl - 16 in/16 out
+	  Advantech PCL-725   isolated - 8 in/8 out
+	  ICP P8R8-DIO        isolated - 8 in/8 out
+	  ADlink ACL-7225b    isolated - 16 in/16 out
+	  ICP P16R16-DIO      isolated - 16 in/16 out
+	  Advantech PCL-733   isolated - 32 in
+	  Advantech PCL-734   isolated - 32 out
 
 	  To compile this driver as a module, choose M here: the module will be
 	  called pcl730.
@@ -201,14 +195,6 @@ config COMEDI_PCM3724
 	  To compile this driver as a module, choose M here: the module will be
 	  called pcm3724.
 
-config COMEDI_PCM3730
-	tristate "Advantech PCM-3730 and clone PC/104 board support"
-	---help---
-	  Enable support for Advantech PCM-3730 and clone PC/104 boards
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called pcm3730.
-
 config COMEDI_AMPLC_DIO200_ISA
 	tristate "Amplicon PC212E/PC214E/PC215E/PC218E/PC272E"
 	select COMEDI_AMPLC_DIO200
@@ -543,12 +529,19 @@ config COMEDI_POC
 	tristate "Generic driver for very simple devices"
 	---help---
 	  Enable generic support for very simple / POC (Piece of Crap) boards,
-	  Keithley Metrabyte DAC-02 (dac02), Advantech PCL-733 (pcl733) and
-	  PCL-734 (pcl734)
+	  Keithley Metrabyte DAC-02 (dac02).
 
 	  To compile this driver as a module, choose M here: the module will be
 	  called poc.
 
+config COMEDI_S526
+	tristate "Sensoray s526 support"
+	---help---
+	  Enable support for Sensoray s526
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called s526.
+
 endif # COMEDI_ISA_DRIVERS
 
 menuconfig COMEDI_PCI_DRIVERS
@@ -1076,14 +1069,6 @@ config COMEDI_RTD520
 	  To compile this driver as a module, choose M here: the module will be
 	  called rtd520.
 
-config COMEDI_S526
-	tristate "Sensoray s526 support"
-	---help---
-	  Enable support for Sensoray s526
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called s526.
-
 config COMEDI_S626
 	tristate "Sensoray 626 support"
 	select COMEDI_FC
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/proc.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/proc.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/proc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/proc.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/range.c linux-libre-3.11-rc7-gnu/drivers/staging/comedi/range.c
--- linux-libre-3.10-gnu/drivers/staging/comedi/range.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/range.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,11 +14,6 @@
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
 */
 
 #include <linux/uaccess.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/comedi/TODO linux-libre-3.11-rc7-gnu/drivers/staging/comedi/TODO
--- linux-libre-3.10-gnu/drivers/staging/comedi/TODO	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/comedi/TODO	2013-08-25 20:43:22.000000000 -0400
@@ -9,4 +9,4 @@ TODO:
 Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
 copy:
 	Ian Abbott <abbotti@mev.co.uk>
-	Frank Mori Hess <fmhess@users.sourceforge.net>
+	H Hartley Sweeten <hsweeten@visionengravers.com>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cptm1217/clearpad_tm1217.c linux-libre-3.11-rc7-gnu/drivers/staging/cptm1217/clearpad_tm1217.c
--- linux-libre-3.10-gnu/drivers/staging/cptm1217/clearpad_tm1217.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cptm1217/clearpad_tm1217.c	2013-08-25 20:43:22.000000000 -0400
@@ -547,10 +547,8 @@ fail_gpio:
 fail:
 	/* Clean up before returning failure */
 	for (i = 0; i < TOUCH_SUPPORTED; i++) {
-		if (ts->cp_input_info[i].input) {
+		if (ts->cp_input_info[i].input)
 			input_unregister_device(ts->cp_input_info[i].input);
-			input_free_device(ts->cp_input_info[i].input);
-		}
 	}
 	kfree(ts);
 	return retval;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/bc_dts_glob_lnx.h linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/bc_dts_glob_lnx.h
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/bc_dts_glob_lnx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/bc_dts_glob_lnx.h	2013-08-25 20:43:22.000000000 -0400
@@ -58,11 +58,11 @@
  * between the driver and the application.
  */
 enum BC_DTS_GLOBALS {
-	BC_MAX_FW_CMD_BUFF_SZ	= 0x40,		/* FW passthrough cmd/rsp buffer size */
+	BC_MAX_FW_CMD_BUFF_SZ = 0x40, /* FW passthrough cmd/rsp buffer size */
 	PCI_CFG_SIZE		= 256,		/* PCI config size buffer */
 	BC_IOCTL_DATA_POOL_SIZE	= 8,		/* BC_IOCTL_DATA Pool size */
-	BC_LINK_MAX_OPENS	= 3,		/* Maximum simultaneous opens*/
-	BC_LINK_MAX_SGLS	= 1024,		/* Maximum SG elements 4M/4K */
+	BC_LINK_MAX_OPENS	= 3,	/* Maximum simultaneous opens*/
+	BC_LINK_MAX_SGLS	= 1024,	/* Maximum SG elements 4M/4K */
 	BC_TX_LIST_CNT		= 2,		/* Max Tx DMA Rings */
 	BC_RX_LIST_CNT		= 8,		/* Max Rx DMA Rings*/
 	BC_PROC_OUTPUT_TIMEOUT	= 3000,		/* Milliseconds */
@@ -240,11 +240,14 @@ enum BC_DRV_CMD {
 	DRV_CMD_ADD_RXBUFFS,	/* Add Rx side buffers to driver pool */
 	DRV_CMD_FETCH_RXBUFF,	/* Get Rx DMAed buffer */
 	DRV_CMD_START_RX_CAP,	/* Start Rx Buffer Capture */
-	DRV_CMD_FLUSH_RX_CAP,	/* Stop the capture for now...we will enhance this later*/
+	DRV_CMD_FLUSH_RX_CAP,	/* Stop the capture for now...
+			we will enhance this later*/
 	DRV_CMD_GET_DRV_STAT,	/* Get Driver Internal Statistics */
 	DRV_CMD_RST_DRV_STAT,	/* Reset Driver Internal Statistics */
-	DRV_CMD_NOTIFY_MODE,	/* Notify the Mode to driver in which the application is Operating*/
-	DRV_CMD_CHANGE_CLOCK,	/* Change the core clock to either save power or improve performance */
+	DRV_CMD_NOTIFY_MODE,	/* Notify the Mode to driver
+			in which the application is Operating*/
+	DRV_CMD_CHANGE_CLOCK,	/* Change the core clock to either save power
+			or improve performance */
 
 	/* MUST be the last one.. */
 	DRV_CMD_END,			/* End of the List.. */
@@ -283,8 +286,8 @@ struct crystalhd_ioctl_data {
 	struct BC_IOCTL_DATA	udata;		/* IOCTL from App..*/
 	uint32_t		u_id;		/* Driver specific user ID */
 	uint32_t		cmd;		/* Cmd ID for driver's use. */
-	void			*add_cdata;	/* Additional command specific data..*/
-	uint32_t		add_cdata_sz;	/* Additional command specific data size */
+	void	 *add_cdata;	/* Additional command specific data..*/
+	uint32_t add_cdata_sz;	/* Additional command specific data size */
 	struct crystalhd_ioctl_data *next;	/* List/Fifo management */
 };
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_cmds.c linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_cmds.c
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_cmds.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_cmds.c	2013-08-25 20:43:22.000000000 -0400
@@ -472,8 +472,8 @@ static enum BC_STATUS bc_cproc_hw_txdma(
 }
 
 /* Helper function to check on user buffers */
-static enum BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz,
-					uint32_t uv_off, bool en_422)
+static enum BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff,
+				 uint32_t ub_sz, uint32_t uv_off, bool en_422)
 {
 	if (!ubuff || !ub_sz) {
 		BCMLOG_ERR("%s->Invalid Arg %p %x\n",
@@ -483,8 +483,9 @@ static enum BC_STATUS bc_cproc_check_inb
 
 	/* Check for alignment */
 	if (((uintptr_t)ubuff) & 0x03) {
-		BCMLOG_ERR("%s-->Un-aligned address not implemented yet.. %p\n",
-				((pin) ? "TX" : "RX"), ubuff);
+		BCMLOG_ERR(
+			"%s-->Un-aligned address not implemented yet.. %p\n",
+			 ((pin) ? "TX" : "RX"), ubuff);
 		return BC_STS_NOT_IMPL;
 	}
 	if (pin)
@@ -572,7 +573,8 @@ static enum BC_STATUS bc_cproc_add_cap_b
 	if (!dio_hnd)
 		return BC_STS_ERROR;
 
-	sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio_hnd, (ctx->state == BC_LINK_READY));
+	sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio_hnd,
+					 (ctx->state == BC_LINK_READY));
 	if ((sts != BC_STS_SUCCESS) && (sts != BC_STS_BUSY)) {
 		crystalhd_unmap_dio(ctx->adp, dio_hnd);
 		return sts;
@@ -618,7 +620,8 @@ static enum BC_STATUS bc_cproc_fetch_fra
 
 	sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
 	if (sts != BC_STS_SUCCESS)
-		return (ctx->state & BC_LINK_SUSPEND) ? BC_STS_IO_USER_ABORT : sts;
+		return (ctx->state & BC_LINK_SUSPEND) ?
+					 BC_STS_IO_USER_ABORT : sts;
 
 	frame->Flags = dio->uinfo.comp_flags;
 
@@ -673,7 +676,8 @@ static enum BC_STATUS bc_cproc_flush_cap
 	frame = &idata->udata.u.DecOutData;
 	for (count = 0; count < BC_RX_LIST_CNT; count++) {
 
-		sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
+		sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx,
+					 &frame->PibInfo, &dio);
 		if (sts != BC_STS_SUCCESS)
 			break;
 
@@ -916,7 +920,8 @@ enum BC_STATUS crystalhd_user_open(struc
  * Closer application handle and release app specific
  * resources.
  */
-enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc)
+enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx,
+					 struct crystalhd_user *uc)
 {
 	uint32_t mode = uc->mode;
 
@@ -1008,8 +1013,8 @@ enum BC_STATUS crystalhd_delete_cmd_cont
  * mode of operation and returns the function pointer
  * from the cproc table.
  */
-crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd,
-				      struct crystalhd_user *uc)
+crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx,
+				 uint32_t cmd, struct crystalhd_user *uc)
 {
 	crystalhd_cmd_proc cproc = NULL;
 	unsigned int i, tbl_sz;
@@ -1024,7 +1029,8 @@ crystalhd_cmd_proc crystalhd_get_cmd_pro
 		return NULL;
 	}
 
-	tbl_sz = sizeof(g_crystalhd_cproc_tbl) / sizeof(struct crystalhd_cmd_tbl);
+	tbl_sz = sizeof(g_crystalhd_cproc_tbl) /
+				 sizeof(struct crystalhd_cmd_tbl);
 	for (i = 0; i < tbl_sz; i++) {
 		if (g_crystalhd_cproc_tbl[i].cmd_id == cmd) {
 			if ((uc->mode == DTS_MONITOR_MODE) &&
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_cmds.h linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_cmds.h
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_cmds.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_cmds.h	2013-08-25 20:43:22.000000000 -0400
@@ -66,7 +66,8 @@ struct crystalhd_cmd {
 	struct crystalhd_hw	hw_ctx;
 };
 
-typedef enum BC_STATUS(*crystalhd_cmd_proc)(struct crystalhd_cmd *, struct crystalhd_ioctl_data *);
+typedef enum BC_STATUS(*crystalhd_cmd_proc)(struct crystalhd_cmd *,
+					 struct crystalhd_ioctl_data *);
 
 struct crystalhd_cmd_tbl {
 	uint32_t		cmd_id;
@@ -74,13 +75,17 @@ struct crystalhd_cmd_tbl {
 	uint32_t		block_mon;
 };
 
-enum BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, struct crystalhd_ioctl_data *idata);
+enum BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx,
+				 struct crystalhd_ioctl_data *idata);
 enum BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx);
-crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd,
-				      struct crystalhd_user *uc);
-enum BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, struct crystalhd_user **user_ctx);
-enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc);
-enum BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, struct crystalhd_adp *adp);
+crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx,
+				 uint32_t cmd, struct crystalhd_user *uc);
+enum BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx,
+				 struct crystalhd_user **user_ctx);
+enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx,
+				 struct crystalhd_user *uc);
+enum BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
+				 struct crystalhd_adp *adp);
 enum BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx);
 bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_fw_if.h linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_fw_if.h
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_fw_if.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_fw_if.h	2013-08-25 20:43:22.000000000 -0400
@@ -106,7 +106,8 @@ struct ppb_vc1 {
 
 struct fgt_sei {
 	struct fgt_sei *next;
-	unsigned char model_values[3][MAX_FGT_VALUE_INTERVAL][MAX_FGT_MODEL_VALUE];
+	unsigned char
+		 model_values[3][MAX_FGT_VALUE_INTERVAL][MAX_FGT_MODEL_VALUE];
 	unsigned char upper_bound[3][MAX_FGT_VALUE_INTERVAL];
 	unsigned char lower_bound[3][MAX_FGT_VALUE_INTERVAL];
 
@@ -125,10 +126,12 @@ struct fgt_sei {
 
 	unsigned char blending_mode_id;	/* Blending mode. */
 	unsigned char log2_scale_factor;	/* Log2 scale factor (2-7). */
-	unsigned char comp_flag[3];		/* Components [0,2] parameters present flag. */
-	unsigned char num_intervals_minus1[3]; /* Number of intensity level intervals. */
+	unsigned char comp_flag[3];	/* Components [0,2]
+					 parameters present flag. */
+	unsigned char num_intervals_minus1[3]; /* Number of
+					 intensity level intervals. */
 	unsigned char num_model_values[3];	/* Number of model values. */
-	uint16_t      repetition_period;	/* Repetition period (0-16384) */
+	uint16_t      repetition_period; /* Repetition period (0-16384) */
 
 };
 
@@ -266,40 +269,40 @@ enum  c011_ts_cmd {
 
 	/* Decoding commands */
 	eCMD_C011_DEC_CHAN_OPEN			= eCMD_C011_CMD_BASE + 0x100,
-	eCMD_C011_DEC_CHAN_CLOSE			= eCMD_C011_CMD_BASE + 0x101,
-	eCMD_C011_DEC_CHAN_ACTIVATE			= eCMD_C011_CMD_BASE + 0x102,
-	eCMD_C011_DEC_CHAN_STATUS			= eCMD_C011_CMD_BASE + 0x103,
-	eCMD_C011_DEC_CHAN_FLUSH			= eCMD_C011_CMD_BASE + 0x104,
+	eCMD_C011_DEC_CHAN_CLOSE		= eCMD_C011_CMD_BASE + 0x101,
+	eCMD_C011_DEC_CHAN_ACTIVATE		= eCMD_C011_CMD_BASE + 0x102,
+	eCMD_C011_DEC_CHAN_STATUS		= eCMD_C011_CMD_BASE + 0x103,
+	eCMD_C011_DEC_CHAN_FLUSH		= eCMD_C011_CMD_BASE + 0x104,
 	eCMD_C011_DEC_CHAN_TRICK_PLAY		= eCMD_C011_CMD_BASE + 0x105,
-	eCMD_C011_DEC_CHAN_TS_PIDS			= eCMD_C011_CMD_BASE + 0x106,
+	eCMD_C011_DEC_CHAN_TS_PIDS		= eCMD_C011_CMD_BASE + 0x106,
 	eCMD_C011_DEC_CHAN_PS_STREAM_ID		= eCMD_C011_CMD_BASE + 0x107,
 	eCMD_C011_DEC_CHAN_INPUT_PARAMS		= eCMD_C011_CMD_BASE + 0x108,
 	eCMD_C011_DEC_CHAN_VIDEO_OUTPUT		= eCMD_C011_CMD_BASE + 0x109,
-	eCMD_C011_DEC_CHAN_OUTPUT_FORMAT		= eCMD_C011_CMD_BASE + 0x10A,
-	eCMD_C011_DEC_CHAN_SCALING_FILTERS		= eCMD_C011_CMD_BASE + 0x10B,
-	eCMD_C011_DEC_CHAN_OSD_MODE			= eCMD_C011_CMD_BASE + 0x10D,
+	eCMD_C011_DEC_CHAN_OUTPUT_FORMAT	= eCMD_C011_CMD_BASE + 0x10A,
+	eCMD_C011_DEC_CHAN_SCALING_FILTERS	= eCMD_C011_CMD_BASE + 0x10B,
+	eCMD_C011_DEC_CHAN_OSD_MODE		= eCMD_C011_CMD_BASE + 0x10D,
 	eCMD_C011_DEC_CHAN_DROP			= eCMD_C011_CMD_BASE + 0x10E,
-	eCMD_C011_DEC_CHAN_RELEASE			= eCMD_C011_CMD_BASE + 0x10F,
-	eCMD_C011_DEC_CHAN_STREAM_SETTINGS		= eCMD_C011_CMD_BASE + 0x110,
+	eCMD_C011_DEC_CHAN_RELEASE		= eCMD_C011_CMD_BASE + 0x10F,
+	eCMD_C011_DEC_CHAN_STREAM_SETTINGS	= eCMD_C011_CMD_BASE + 0x110,
 	eCMD_C011_DEC_CHAN_PAUSE_OUTPUT		= eCMD_C011_CMD_BASE + 0x111,
-	eCMD_C011_DEC_CHAN_CHANGE			= eCMD_C011_CMD_BASE + 0x112,
-	eCMD_C011_DEC_CHAN_SET_STC			= eCMD_C011_CMD_BASE + 0x113,
-	eCMD_C011_DEC_CHAN_SET_PTS			= eCMD_C011_CMD_BASE + 0x114,
-	eCMD_C011_DEC_CHAN_CC_MODE			= eCMD_C011_CMD_BASE + 0x115,
-	eCMD_C011_DEC_CREATE_AUDIO_CONTEXT		= eCMD_C011_CMD_BASE + 0x116,
-	eCMD_C011_DEC_COPY_AUDIO_CONTEXT		= eCMD_C011_CMD_BASE + 0x117,
-	eCMD_C011_DEC_DELETE_AUDIO_CONTEXT		= eCMD_C011_CMD_BASE + 0x118,
-	eCMD_C011_DEC_CHAN_SET_DECYPTION		= eCMD_C011_CMD_BASE + 0x119,
+	eCMD_C011_DEC_CHAN_CHANGE		= eCMD_C011_CMD_BASE + 0x112,
+	eCMD_C011_DEC_CHAN_SET_STC		= eCMD_C011_CMD_BASE + 0x113,
+	eCMD_C011_DEC_CHAN_SET_PTS		= eCMD_C011_CMD_BASE + 0x114,
+	eCMD_C011_DEC_CHAN_CC_MODE		= eCMD_C011_CMD_BASE + 0x115,
+	eCMD_C011_DEC_CREATE_AUDIO_CONTEXT	= eCMD_C011_CMD_BASE + 0x116,
+	eCMD_C011_DEC_COPY_AUDIO_CONTEXT	= eCMD_C011_CMD_BASE + 0x117,
+	eCMD_C011_DEC_DELETE_AUDIO_CONTEXT	= eCMD_C011_CMD_BASE + 0x118,
+	eCMD_C011_DEC_CHAN_SET_DECYPTION	= eCMD_C011_CMD_BASE + 0x119,
 	eCMD_C011_DEC_CHAN_START_VIDEO		= eCMD_C011_CMD_BASE + 0x11A,
 	eCMD_C011_DEC_CHAN_STOP_VIDEO		= eCMD_C011_CMD_BASE + 0x11B,
 	eCMD_C011_DEC_CHAN_PIC_CAPTURE		= eCMD_C011_CMD_BASE + 0x11C,
-	eCMD_C011_DEC_CHAN_PAUSE			= eCMD_C011_CMD_BASE + 0x11D,
+	eCMD_C011_DEC_CHAN_PAUSE		= eCMD_C011_CMD_BASE + 0x11D,
 	eCMD_C011_DEC_CHAN_PAUSE_STATE		= eCMD_C011_CMD_BASE + 0x11E,
-	eCMD_C011_DEC_CHAN_SET_SLOWM_RATE		= eCMD_C011_CMD_BASE + 0x11F,
-	eCMD_C011_DEC_CHAN_GET_SLOWM_RATE		= eCMD_C011_CMD_BASE + 0x120,
+	eCMD_C011_DEC_CHAN_SET_SLOWM_RATE	= eCMD_C011_CMD_BASE + 0x11F,
+	eCMD_C011_DEC_CHAN_GET_SLOWM_RATE	= eCMD_C011_CMD_BASE + 0x120,
 	eCMD_C011_DEC_CHAN_SET_FF_RATE		= eCMD_C011_CMD_BASE + 0x121,
 	eCMD_C011_DEC_CHAN_GET_FF_RATE		= eCMD_C011_CMD_BASE + 0x122,
-	eCMD_C011_DEC_CHAN_FRAME_ADVANCE		= eCMD_C011_CMD_BASE + 0x123,
+	eCMD_C011_DEC_CHAN_FRAME_ADVANCE	= eCMD_C011_CMD_BASE + 0x123,
 	eCMD_C011_DEC_CHAN_SET_SKIP_PIC_MODE	= eCMD_C011_CMD_BASE + 0x124,
 	eCMD_C011_DEC_CHAN_GET_SKIP_PIC_MODE	= eCMD_C011_CMD_BASE + 0x125,
 	eCMD_C011_DEC_CHAN_FILL_PIC_BUF		= eCMD_C011_CMD_BASE + 0x126,
@@ -308,15 +311,16 @@ enum  c011_ts_cmd {
 	eCMD_C011_DEC_CHAN_SET_BRCM_TRICK_MODE	= eCMD_C011_CMD_BASE + 0x129,
 	eCMD_C011_DEC_CHAN_GET_BRCM_TRICK_MODE	= eCMD_C011_CMD_BASE + 0x12A,
 	eCMD_C011_DEC_CHAN_REVERSE_FIELD_STATUS	= eCMD_C011_CMD_BASE + 0x12B,
-	eCMD_C011_DEC_CHAN_I_PICTURE_FOUND		= eCMD_C011_CMD_BASE + 0x12C,
-	eCMD_C011_DEC_CHAN_SET_PARAMETER		= eCMD_C011_CMD_BASE + 0x12D,
+	eCMD_C011_DEC_CHAN_I_PICTURE_FOUND	= eCMD_C011_CMD_BASE + 0x12C,
+	eCMD_C011_DEC_CHAN_SET_PARAMETER	= eCMD_C011_CMD_BASE + 0x12D,
 	eCMD_C011_DEC_CHAN_SET_USER_DATA_MODE	= eCMD_C011_CMD_BASE + 0x12E,
-	eCMD_C011_DEC_CHAN_SET_PAUSE_DISPLAY_MODE	= eCMD_C011_CMD_BASE + 0x12F,
-	eCMD_C011_DEC_CHAN_SET_SLOW_DISPLAY_MODE	= eCMD_C011_CMD_BASE + 0x130,
+	eCMD_C011_DEC_CHAN_SET_PAUSE_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x12F,
+	eCMD_C011_DEC_CHAN_SET_SLOW_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x130,
 	eCMD_C011_DEC_CHAN_SET_FF_DISPLAY_MODE	= eCMD_C011_CMD_BASE + 0x131,
-	eCMD_C011_DEC_CHAN_SET_DISPLAY_TIMING_MODE	= eCMD_C011_CMD_BASE + 0x132,
-	eCMD_C011_DEC_CHAN_SET_DISPLAY_MODE		= eCMD_C011_CMD_BASE + 0x133,
-	eCMD_C011_DEC_CHAN_GET_DISPLAY_MODE		= eCMD_C011_CMD_BASE + 0x134,
+	eCMD_C011_DEC_CHAN_SET_DISPLAY_TIMING_MODE = eCMD_C011_CMD_BASE +
+								 0x132,
+	eCMD_C011_DEC_CHAN_SET_DISPLAY_MODE	= eCMD_C011_CMD_BASE + 0x133,
+	eCMD_C011_DEC_CHAN_GET_DISPLAY_MODE	= eCMD_C011_CMD_BASE + 0x134,
 	eCMD_C011_DEC_CHAN_SET_REVERSE_FIELD	= eCMD_C011_CMD_BASE + 0x135,
 	eCMD_C011_DEC_CHAN_STREAM_OPEN		= eCMD_C011_CMD_BASE + 0x136,
 	eCMD_C011_DEC_CHAN_SET_PCR_PID		= eCMD_C011_CMD_BASE + 0x137,
@@ -328,19 +332,22 @@ enum  c011_ts_cmd {
 	eCMD_C011_DEC_CHAN_GET_DISPLAY_ORDER	= eCMD_C011_CMD_BASE + 0x143,
 	eCMD_C011_DEC_CHAN_SET_HOST_TRICK_MODE	= eCMD_C011_CMD_BASE + 0x144,
 	eCMD_C011_DEC_CHAN_SET_OPERATION_MODE	= eCMD_C011_CMD_BASE + 0x145,
-	eCMD_C011_DEC_CHAN_DISPLAY_PAUSE_UNTO_PTS	= eCMD_C011_CMD_BASE + 0x146,
-	eCMD_C011_DEC_CHAN_SET_PTS_STC_DIFF_THRESHOLD = eCMD_C011_CMD_BASE + 0x147,
+	eCMD_C011_DEC_CHAN_DISPLAY_PAUSE_UNTO_PTS = eCMD_C011_CMD_BASE + 0x146,
+	eCMD_C011_DEC_CHAN_SET_PTS_STC_DIFF_THRESHOLD = eCMD_C011_CMD_BASE +
+								 0x147,
 	eCMD_C011_DEC_CHAN_SEND_COMPRESSED_BUF	= eCMD_C011_CMD_BASE + 0x148,
 	eCMD_C011_DEC_CHAN_SET_CLIPPING		= eCMD_C011_CMD_BASE + 0x149,
 	eCMD_C011_DEC_CHAN_SET_PARAMETERS_FOR_HARD_RESET_INTERRUPT_TO_HOST
 		= eCMD_C011_CMD_BASE + 0x150,
 
 	/* Decoder RevD commands */
-	eCMD_C011_DEC_CHAN_SET_CSC	= eCMD_C011_CMD_BASE + 0x180, /* color space conversion */
+	eCMD_C011_DEC_CHAN_SET_CSC	= eCMD_C011_CMD_BASE + 0x180, /* color
+							 space conversion */
 	eCMD_C011_DEC_CHAN_SET_RANGE_REMAP	= eCMD_C011_CMD_BASE + 0x181,
 	eCMD_C011_DEC_CHAN_SET_FGT		= eCMD_C011_CMD_BASE + 0x182,
 	/* Note: 0x183 not implemented yet in Rev D main */
-	eCMD_C011_DEC_CHAN_SET_LASTPICTURE_PADDING = eCMD_C011_CMD_BASE + 0x183,
+	eCMD_C011_DEC_CHAN_SET_LASTPICTURE_PADDING = eCMD_C011_CMD_BASE +
+								 0x183,
 
 	/* Decoder 7412 commands (7412-only) */
 	eCMD_C011_DEC_CHAN_SET_CONTENT_KEY	= eCMD_C011_CMD_BASE + 0x190,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_hw.c linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_hw.c
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_hw.c	2013-08-25 20:43:22.000000000 -0400
@@ -94,15 +94,19 @@ static bool crystalhd_bring_out_of_rst(s
 	 * Enable clocks while 7412 reset is asserted, delay
 	 * De-assert 7412 reset
 	 */
-	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
+	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp,
+					 MISC_PERST_DECODER_CTRL);
 	rst_deco_cntrl.stop_bcm_7412_clk = 0;
 	rst_deco_cntrl.bcm7412_rst = 1;
-	crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
+	crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL,
+					 rst_deco_cntrl.whole_reg);
 	msleep_interruptible(10);
 
-	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
+	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp,
+					 MISC_PERST_DECODER_CTRL);
 	rst_deco_cntrl.bcm7412_rst = 0;
-	crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
+	crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL,
+					 rst_deco_cntrl.whole_reg);
 	msleep_interruptible(50);
 
 	/* Disable OTP_CONTENT_MISC to 0 to disable all secure modes */
@@ -132,9 +136,11 @@ static bool crystalhd_put_in_reset(struc
 	 * Assert 7412 reset, delay
 	 * Assert 7412 stop clock
 	 */
-	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
+	rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp,
+					 MISC_PERST_DECODER_CTRL);
 	rst_deco_cntrl.stop_bcm_7412_clk = 1;
-	crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
+	crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL,
+					 rst_deco_cntrl.whole_reg);
 	msleep_interruptible(50);
 
 	/* Bus Arbiter Timeout: GISB_ARBITER_TIMER
@@ -213,7 +219,8 @@ static void crystalhd_clear_errors(struc
 {
 	uint32_t reg;
 
-	/* FIXME: jarod: wouldn't we want to write a 0 to the reg? Or does the write clear the bits specified? */
+	/* FIXME: jarod: wouldn't we want to write a 0 to the reg?
+	 Or does the write clear the bits specified? */
 	reg = crystalhd_reg_rd(adp, MISC1_Y_RX_ERROR_STATUS);
 	if (reg)
 		crystalhd_reg_wr(adp, MISC1_Y_RX_ERROR_STATUS, reg);
@@ -263,10 +270,12 @@ static bool crystalhd_load_firmware_conf
 	crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (BC_DRAM_FW_CFG_ADDR >> 19));
 
 	crystalhd_reg_wr(adp, AES_CMD, 0);
-	crystalhd_reg_wr(adp, AES_CONFIG_INFO, (BC_DRAM_FW_CFG_ADDR & 0x7FFFF));
+	crystalhd_reg_wr(adp, AES_CONFIG_INFO,
+		 (BC_DRAM_FW_CFG_ADDR & 0x7FFFF));
 	crystalhd_reg_wr(adp, AES_CMD, 0x1);
 
-	/* FIXME: jarod: I've seen this fail, and introducing extra delays helps... */
+	/* FIXME: jarod: I've seen this fail,
+	 and introducing extra delays helps... */
 	for (i = 0; i < 100; ++i) {
 		reg = crystalhd_reg_rd(adp, AES_STATUS);
 		if (reg & 0x1)
@@ -349,7 +358,8 @@ static bool crystalhd_stop_device(struct
 	return true;
 }
 
-static struct crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(struct crystalhd_hw *hw)
+static struct crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(
+					struct crystalhd_hw *hw)
 {
 	unsigned long flags = 0;
 	struct crystalhd_rx_dma_pkt *temp = NULL;
@@ -484,8 +494,8 @@ hw_create_ioq_err:
 }
 
 
-static bool crystalhd_code_in_full(struct crystalhd_adp *adp, uint32_t needed_sz,
-				 bool b_188_byte_pkts,  uint8_t flags)
+static bool crystalhd_code_in_full(struct crystalhd_adp *adp,
+		 uint32_t needed_sz, bool b_188_byte_pkts,  uint8_t flags)
 {
 	uint32_t base, end, writep, readp;
 	uint32_t cpbSize, cpbFullness, fifoSize;
@@ -525,7 +535,7 @@ static bool crystalhd_code_in_full(struc
 }
 
 static enum BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw,
-					    uint32_t list_id, enum BC_STATUS cs)
+					 uint32_t list_id, enum BC_STATUS cs)
 {
 	struct tx_dma_pkt *tx_req;
 
@@ -536,7 +546,8 @@ static enum BC_STATUS crystalhd_hw_tx_re
 
 	hw->pwr_lock--;
 
-	tx_req = (struct tx_dma_pkt *)crystalhd_dioq_find_and_fetch(hw->tx_actq, list_id);
+	tx_req = (struct tx_dma_pkt *)crystalhd_dioq_find_and_fetch(
+					hw->tx_actq, list_id);
 	if (!tx_req) {
 		if (cs != BC_STS_IO_USER_ABORT)
 			BCMLOG_ERR("Find and Fetch Did not find req\n");
@@ -559,7 +570,8 @@ static enum BC_STATUS crystalhd_hw_tx_re
 	return crystalhd_dioq_add(hw->tx_freeq, tx_req, false, 0);
 }
 
-static bool crystalhd_tx_list0_handler(struct crystalhd_hw *hw, uint32_t err_sts)
+static bool crystalhd_tx_list0_handler(struct crystalhd_hw *hw,
+					 uint32_t err_sts)
 {
 	uint32_t err_mask, tmp;
 	unsigned long flags = 0;
@@ -591,7 +603,8 @@ static bool crystalhd_tx_list0_handler(s
 	return true;
 }
 
-static bool crystalhd_tx_list1_handler(struct crystalhd_hw *hw, uint32_t err_sts)
+static bool crystalhd_tx_list1_handler(struct crystalhd_hw *hw,
+					 uint32_t err_sts)
 {
 	uint32_t err_mask, tmp;
 	unsigned long flags = 0;
@@ -663,14 +676,15 @@ static void crystalhd_hw_dump_desc(struc
 	if (!p_dma_desc || !cnt)
 		return;
 
-	/* FIXME: jarod: perhaps a modparam desc_debug to enable this, rather than
-	 * setting ll (log level, I presume) to non-zero? */
+	/* FIXME: jarod: perhaps a modparam desc_debug to enable this,
+	 rather than setting ll (log level, I presume) to non-zero? */
 	if (!ll)
 		return;
 
 	for (ix = ul_desc_index; ix < (ul_desc_index + cnt); ix++) {
-		BCMLOG(ll, "%s[%d] Buff[%x:%x] Next:[%x:%x] XferSz:%x Intr:%x,Last:%x\n",
-		       ((p_dma_desc[ul_desc_index].dma_dir) ? "TDesc" : "RDesc"),
+		BCMLOG(ll,
+		 "%s[%d] Buff[%x:%x] Next:[%x:%x] XferSz:%x Intr:%x,Last:%x\n",
+		 ((p_dma_desc[ul_desc_index].dma_dir) ? "TDesc" : "RDesc"),
 		       ul_desc_index,
 		       p_dma_desc[ul_desc_index].buff_addr_high,
 		       p_dma_desc[ul_desc_index].buff_addr_low,
@@ -707,7 +721,8 @@ static enum BC_STATUS crystalhd_hw_fill_
 		/* Get SGLE length */
 		len = crystalhd_get_sgle_len(ioreq, sg_ix);
 		if (len % 4) {
-			BCMLOG_ERR(" len in sg %d %d %d\n", len, sg_ix, sg_cnt);
+			BCMLOG_ERR(" len in sg %d %d %d\n", len, sg_ix,
+				 sg_cnt);
 			return BC_STS_NOT_IMPL;
 		}
 		/* Setup DMA desc with Phy addr & Length at current index. */
@@ -722,7 +737,8 @@ static enum BC_STATUS crystalhd_hw_fill_
 		desc[ix].dma_dir        = ioreq->uinfo.dir_tx;
 
 		/* Chain DMA descriptor.  */
-		addr_temp.full_addr = desc_phy_addr + sizeof(struct dma_descriptor);
+		addr_temp.full_addr = desc_phy_addr +
+					 sizeof(struct dma_descriptor);
 		desc[ix].next_desc_addr_low = addr_temp.low_part;
 		desc[ix].next_desc_addr_high = addr_temp.high_part;
 
@@ -731,8 +747,9 @@ static enum BC_STATUS crystalhd_hw_fill_
 
 		/* Debug.. */
 		if ((!len) || (len > crystalhd_get_sgle_len(ioreq, sg_ix))) {
-			BCMLOG_ERR("inv-len(%x) Ix(%d) count:%x xfr_sz:%x sg_cnt:%d\n",
-				   len, ix, count, xfr_sz, sg_cnt);
+			BCMLOG_ERR(
+			 "inv-len(%x) Ix(%d) count:%x xfr_sz:%x sg_cnt:%d\n",
+			 len, ix, count, xfr_sz, sg_cnt);
 			return BC_STS_ERROR;
 		}
 		/* Length expects Multiple of 4 */
@@ -774,7 +791,8 @@ static enum BC_STATUS crystalhd_hw_fill_
 	return BC_STS_SUCCESS;
 }
 
-static enum BC_STATUS crystalhd_xlat_sgl_to_dma_desc(struct crystalhd_dio_req *ioreq,
+static enum BC_STATUS crystalhd_xlat_sgl_to_dma_desc(
+					      struct crystalhd_dio_req *ioreq,
 					      struct dma_desc_mem *pdesc_mem,
 					      uint32_t *uv_desc_index)
 {
@@ -887,12 +905,14 @@ static enum BC_STATUS crystalhd_stop_tx_
 	while ((l1 || l2) && cnt) {
 
 		if (l1) {
-			l1 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST0);
+			l1 = crystalhd_reg_rd(hw->adp,
+				 MISC1_TX_FIRST_DESC_L_ADDR_LIST0);
 			l1 &= DMA_START_BIT;
 		}
 
 		if (l2) {
-			l2 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST1);
+			l2 = crystalhd_reg_rd(hw->adp,
+				 MISC1_TX_FIRST_DESC_L_ADDR_LIST1);
 			l2 &= DMA_START_BIT;
 		}
 
@@ -986,7 +1006,8 @@ static uint32_t crystalhd_get_addr_from_
 	return addr_entry;
 }
 
-static bool crystalhd_rel_addr_to_pib_Q(struct crystalhd_hw *hw, uint32_t addr_to_rel)
+static bool crystalhd_rel_addr_to_pib_Q(struct crystalhd_hw *hw,
+					 uint32_t addr_to_rel)
 {
 	uint32_t Q_addr;
 	uint32_t r_offset, w_offset, n_offset;
@@ -1021,7 +1042,8 @@ static bool crystalhd_rel_addr_to_pib_Q(
 	return true;
 }
 
-static void cpy_pib_to_app(struct c011_pib *src_pib, struct BC_PIC_INFO_BLOCK *dst_pib)
+static void cpy_pib_to_app(struct c011_pib *src_pib,
+					 struct BC_PIC_INFO_BLOCK *dst_pib)
 {
 	if (!src_pib || !dst_pib) {
 		BCMLOG_ERR("Invalid Arguments\n");
@@ -1063,11 +1085,13 @@ static void crystalhd_hw_proc_pib(struct
 			       (uint32_t *)&src_pib);
 
 		if (src_pib.bFormatChange) {
-			rx_pkt = (struct crystalhd_rx_dma_pkt *)crystalhd_dioq_fetch(hw->rx_freeq);
+			rx_pkt = (struct crystalhd_rx_dma_pkt *)
+					crystalhd_dioq_fetch(hw->rx_freeq);
 			if (!rx_pkt)
 				return;
 			rx_pkt->flags = 0;
-			rx_pkt->flags |= COMP_FLAG_PIB_VALID | COMP_FLAG_FMT_CHANGE;
+			rx_pkt->flags |= COMP_FLAG_PIB_VALID |
+					 COMP_FLAG_FMT_CHANGE;
 			AppPib = &rx_pkt->pib;
 			cpy_pib_to_app(&src_pib, AppPib);
 
@@ -1084,7 +1108,8 @@ static void crystalhd_hw_proc_pib(struct
 			       rx_pkt->pib.pulldown,
 			       rx_pkt->pib.ycom);
 
-			crystalhd_dioq_add(hw->rx_rdyq, (void *)rx_pkt, true, rx_pkt->pkt_tag);
+			crystalhd_dioq_add(hw->rx_rdyq, (void *)rx_pkt, true,
+					 rx_pkt->pkt_tag);
 
 		}
 
@@ -1096,16 +1121,20 @@ static void crystalhd_start_rx_dma_engin
 {
 	uint32_t        dma_cntrl;
 
-	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
+	dma_cntrl = crystalhd_reg_rd(hw->adp,
+			 MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
 	if (!(dma_cntrl & DMA_START_BIT)) {
 		dma_cntrl |= DMA_START_BIT;
-		crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+		crystalhd_reg_wr(hw->adp,
+			 MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
 	}
 
-	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
+	dma_cntrl = crystalhd_reg_rd(hw->adp,
+			 MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
 	if (!(dma_cntrl & DMA_START_BIT)) {
 		dma_cntrl |= DMA_START_BIT;
-		crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+		crystalhd_reg_wr(hw->adp,
+			 MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
 	}
 
 	return;
@@ -1116,44 +1145,52 @@ static void crystalhd_stop_rx_dma_engine
 	uint32_t dma_cntrl = 0, count = 30;
 	uint32_t l0y = 1, l0uv = 1, l1y = 1, l1uv = 1;
 
-	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
+	dma_cntrl = crystalhd_reg_rd(hw->adp,
+			 MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
 	if ((dma_cntrl & DMA_START_BIT)) {
 		dma_cntrl &= ~DMA_START_BIT;
-		crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+		crystalhd_reg_wr(hw->adp,
+			 MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
 	}
 
-	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
+	dma_cntrl = crystalhd_reg_rd(hw->adp,
+			 MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
 	if ((dma_cntrl & DMA_START_BIT)) {
 		dma_cntrl &= ~DMA_START_BIT;
-		crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+		crystalhd_reg_wr(hw->adp,
+			 MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
 	}
 
 	/* Poll for 3seconds (30 * 100ms) on both the lists..*/
 	while ((l0y || l0uv || l1y || l1uv) && count) {
 
 		if (l0y) {
-			l0y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0);
+			l0y = crystalhd_reg_rd(hw->adp,
+				 MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0);
 			l0y &= DMA_START_BIT;
 			if (!l0y)
 				hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
 		}
 
 		if (l1y) {
-			l1y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1);
+			l1y = crystalhd_reg_rd(hw->adp,
+				 MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1);
 			l1y &= DMA_START_BIT;
 			if (!l1y)
 				hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
 		}
 
 		if (l0uv) {
-			l0uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0);
+			l0uv = crystalhd_reg_rd(hw->adp,
+				 MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0);
 			l0uv &= DMA_START_BIT;
 			if (!l0uv)
 				hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
 		}
 
 		if (l1uv) {
-			l1uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1);
+			l1uv = crystalhd_reg_rd(hw->adp,
+				 MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1);
 			l1uv &= DMA_START_BIT;
 			if (!l1uv)
 				hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
@@ -1168,7 +1205,8 @@ static void crystalhd_stop_rx_dma_engine
 	       count, hw->rx_list_sts[0], hw->rx_list_sts[1]);
 }
 
-static enum BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw, struct crystalhd_rx_dma_pkt *rx_pkt)
+static enum BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw,
+					 struct crystalhd_rx_dma_pkt *rx_pkt)
 {
 	uint32_t y_low_addr_reg, y_high_addr_reg;
 	uint32_t uv_low_addr_reg, uv_high_addr_reg;
@@ -1186,7 +1224,8 @@ static enum BC_STATUS crystalhd_hw_prog_
 	}
 
 	spin_lock_irqsave(&hw->rx_lock, flags);
-	/* FIXME: jarod: sts_free is an enum for 0, in crystalhd_hw.h... yuk... */
+	/* FIXME: jarod: sts_free is an enum for 0,
+	 in crystalhd_hw.h... yuk... */
 	if (sts_free != hw->rx_list_sts[hw->rx_list_post_index]) {
 		spin_unlock_irqrestore(&hw->rx_lock, flags);
 		return BC_STS_BUSY;
@@ -1210,7 +1249,8 @@ static enum BC_STATUS crystalhd_hw_prog_
 	hw->rx_list_post_index = (hw->rx_list_post_index + 1) % DMA_ENGINE_CNT;
 	spin_unlock_irqrestore(&hw->rx_lock, flags);
 
-	crystalhd_dioq_add(hw->rx_actq, (void *)rx_pkt, false, rx_pkt->pkt_tag);
+	crystalhd_dioq_add(hw->rx_actq, (void *)rx_pkt, false,
+			 rx_pkt->pkt_tag);
 
 	crystalhd_start_rx_dma_engine(hw);
 	/* Program the Y descriptor */
@@ -1221,8 +1261,10 @@ static enum BC_STATUS crystalhd_hw_prog_
 	if (rx_pkt->uv_phy_addr) {
 		/* Program the UV descriptor */
 		desc_addr.full_addr = rx_pkt->uv_phy_addr;
-		crystalhd_reg_wr(hw->adp, uv_high_addr_reg, desc_addr.high_part);
-		crystalhd_reg_wr(hw->adp, uv_low_addr_reg, desc_addr.low_part | 0x01);
+		crystalhd_reg_wr(hw->adp, uv_high_addr_reg,
+			 desc_addr.high_part);
+		crystalhd_reg_wr(hw->adp, uv_low_addr_reg,
+			 desc_addr.low_part | 0x01);
 	}
 
 	return BC_STS_SUCCESS;
@@ -1268,16 +1310,20 @@ static void crystalhd_hw_finalize_pause(
 
 	hw->stop_pending = 0;
 
-	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
+	dma_cntrl = crystalhd_reg_rd(hw->adp,
+			 MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
 	if (dma_cntrl & DMA_START_BIT) {
 		dma_cntrl &= ~DMA_START_BIT;
-		crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+		crystalhd_reg_wr(hw->adp,
+			 MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
 	}
 
-	dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
+	dma_cntrl = crystalhd_reg_rd(hw->adp,
+			 MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
 	if (dma_cntrl & DMA_START_BIT) {
 		dma_cntrl &= ~DMA_START_BIT;
-		crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
+		crystalhd_reg_wr(hw->adp,
+			 MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
 	}
 	hw->rx_list_post_index = 0;
 
@@ -1287,8 +1333,8 @@ static void crystalhd_hw_finalize_pause(
 	crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm);
 }
 
-static enum BC_STATUS crystalhd_rx_pkt_done(struct crystalhd_hw *hw, uint32_t list_index,
-				     enum BC_STATUS comp_sts)
+static enum BC_STATUS crystalhd_rx_pkt_done(struct crystalhd_hw *hw,
+			 uint32_t list_index, enum BC_STATUS comp_sts)
 {
 	struct crystalhd_rx_dma_pkt *rx_pkt = NULL;
 	uint32_t y_dw_dnsz, uv_dw_dnsz;
@@ -1302,7 +1348,8 @@ static enum BC_STATUS crystalhd_rx_pkt_d
 	rx_pkt = crystalhd_dioq_find_and_fetch(hw->rx_actq,
 					     hw->rx_pkt_tag_seed + list_index);
 	if (!rx_pkt) {
-		BCMLOG_ERR("Act-Q:PostIx:%x L0Sts:%x L1Sts:%x current L:%x tag:%x comp:%x\n",
+		BCMLOG_ERR(
+		"Act-Q:PostIx:%x L0Sts:%x L1Sts:%x current L:%x tag:%x comp:%x\n",
 			   hw->rx_list_post_index, hw->rx_list_sts[0],
 			   hw->rx_list_sts[1], list_index,
 			   hw->rx_pkt_tag_seed + list_index, comp_sts);
@@ -1324,8 +1371,8 @@ static enum BC_STATUS crystalhd_rx_pkt_d
 	return crystalhd_hw_post_cap_buff(hw, rx_pkt);
 }
 
-static bool crystalhd_rx_list0_handler(struct crystalhd_hw *hw, uint32_t int_sts,
-				     uint32_t y_err_sts, uint32_t uv_err_sts)
+static bool crystalhd_rx_list0_handler(struct crystalhd_hw *hw,
+		 uint32_t int_sts, uint32_t y_err_sts, uint32_t uv_err_sts)
 {
 	uint32_t tmp;
 	enum list_sts tmp_lsts;
@@ -1367,7 +1414,8 @@ static bool crystalhd_rx_list0_handler(s
 		tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK;
 	}
 
-	if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
+	if (uv_err_sts &
+	 MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
 		hw->rx_list_sts[0] &= ~rx_uv_mask;
 		hw->rx_list_sts[0] |= rx_uv_error;
 		tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK;
@@ -1392,8 +1440,8 @@ static bool crystalhd_rx_list0_handler(s
 	return (tmp_lsts != hw->rx_list_sts[0]);
 }
 
-static bool crystalhd_rx_list1_handler(struct crystalhd_hw *hw, uint32_t int_sts,
-				     uint32_t y_err_sts, uint32_t uv_err_sts)
+static bool crystalhd_rx_list1_handler(struct crystalhd_hw *hw,
+		 uint32_t int_sts, uint32_t y_err_sts, uint32_t uv_err_sts)
 {
 	uint32_t tmp;
 	enum list_sts tmp_lsts;
@@ -1486,9 +1534,11 @@ static void crystalhd_rx_isr(struct crys
 		/* Update States..*/
 		spin_lock_irqsave(&hw->rx_lock, flags);
 		if (i == 0)
-			ret = crystalhd_rx_list0_handler(hw, intr_sts, y_err_sts, uv_err_sts);
+			ret = crystalhd_rx_list0_handler(hw, intr_sts,
+					 y_err_sts, uv_err_sts);
 		else
-			ret = crystalhd_rx_list1_handler(hw, intr_sts, y_err_sts, uv_err_sts);
+			ret = crystalhd_rx_list1_handler(hw, intr_sts,
+					 y_err_sts, uv_err_sts);
 		if (ret) {
 			switch (hw->rx_list_sts[i]) {
 			case sts_free:
@@ -1501,11 +1551,13 @@ static void crystalhd_rx_isr(struct crys
 				/* We got error on both or Y or uv. */
 				hw->stats.rx_errors++;
 				crystalhd_get_dnsz(hw, i, &y_dn_sz, &uv_dn_sz);
-				/* FIXME: jarod: this is where my mini pci-e card is tripping up */
+				/* FIXME: jarod: this is where
+				 my mini pci-e card is tripping up */
 				BCMLOG(BCMLOG_DBG, "list_index:%x rx[%d] Y:%x "
 				       "UV:%x Int:%x YDnSz:%x UVDnSz:%x\n",
 				       i, hw->stats.rx_errors, y_err_sts,
-				       uv_err_sts, intr_sts, y_dn_sz, uv_dn_sz);
+				       uv_err_sts, intr_sts, y_dn_sz,
+				       		 uv_dn_sz);
 				hw->rx_list_sts[i] = sts_free;
 				comp_sts = BC_STS_ERROR;
 				break;
@@ -1567,14 +1619,17 @@ static enum BC_STATUS crystalhd_put_ddr2
 	union link_misc_perst_decoder_ctrl rst_cntrl_reg;
 
 	/* Pulse reset pin of 7412 (MISC_PERST_DECODER_CTRL) */
-	rst_cntrl_reg.whole_reg = crystalhd_reg_rd(hw->adp, MISC_PERST_DECODER_CTRL);
+	rst_cntrl_reg.whole_reg = crystalhd_reg_rd(hw->adp,
+					 MISC_PERST_DECODER_CTRL);
 
 	rst_cntrl_reg.bcm_7412_rst = 1;
-	crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg);
+	crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL,
+					 rst_cntrl_reg.whole_reg);
 	msleep_interruptible(50);
 
 	rst_cntrl_reg.bcm_7412_rst = 0;
-	crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg);
+	crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL,
+					 rst_cntrl_reg.whole_reg);
 
 	/* Close all banks, put DDR in idle */
 	bc_dec_reg_wr(hw->adp, SDRAM_PRECHARGE, 0);
@@ -1622,7 +1677,8 @@ static enum BC_STATUS crystalhd_put_ddr2
 **
 *************************************************/
 
-enum BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, uint32_t sz)
+enum BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer,
+					 uint32_t sz)
 {
 	uint32_t reg_data, cnt, *temp_buff;
 	uint32_t fw_sig_len = 36;
@@ -1828,7 +1884,8 @@ bool crystalhd_hw_interrupt(struct cryst
 			crystalhd_hw_proc_pib(hw);
 
 		bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, deco_intr);
-		/* FIXME: jarod: No udelay? might this be the real reason mini pci-e cards were stalling out? */
+		/* FIXME: jarod: No udelay? might this be
+		 the real reason mini pci-e cards were stalling out? */
 		bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, 0);
 		rc = 1;
 	}
@@ -1852,7 +1909,8 @@ bool crystalhd_hw_interrupt(struct cryst
 	return rc;
 }
 
-enum BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp)
+enum BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw,
+			 struct crystalhd_adp *adp)
 {
 	if (!hw || !adp) {
 		BCMLOG_ERR("Invalid Arguments\n");
@@ -1967,7 +2025,8 @@ enum BC_STATUS crystalhd_hw_setup_dma_ri
 		}
 		rpkt->desc_mem.pdma_desc_start = mem;
 		rpkt->desc_mem.phy_addr = phy_addr;
-		rpkt->desc_mem.sz  = BC_LINK_MAX_SGLS * sizeof(struct dma_descriptor);
+		rpkt->desc_mem.sz  = BC_LINK_MAX_SGLS *
+					 sizeof(struct dma_descriptor);
 		rpkt->pkt_tag = hw->rx_pkt_tag_seed + i;
 		crystalhd_hw_free_rx_pkt(hw, rpkt);
 	}
@@ -2013,7 +2072,8 @@ enum BC_STATUS crystalhd_hw_free_dma_rin
 	return BC_STS_SUCCESS;
 }
 
-enum BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, struct crystalhd_dio_req *ioreq,
+enum BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw,
+			     struct crystalhd_dio_req *ioreq,
 			     hw_comp_callback call_back,
 			     wait_queue_head_t *cb_event, uint32_t *list_id,
 			     uint8_t data_flags)
@@ -2047,7 +2107,8 @@ enum BC_STATUS crystalhd_hw_post_tx(stru
 	}
 
 	/* Get a list from TxFreeQ */
-	tx_dma_packet = (struct tx_dma_pkt *)crystalhd_dioq_fetch(hw->tx_freeq);
+	tx_dma_packet = (struct tx_dma_pkt *)crystalhd_dioq_fetch(
+						hw->tx_freeq);
 	if (!tx_dma_packet) {
 		BCMLOG_ERR("No empty elements..\n");
 		return BC_STS_ERR_USAGE;
@@ -2105,7 +2166,8 @@ enum BC_STATUS crystalhd_hw_post_tx(stru
 	crystalhd_start_tx_dma_engine(hw);
 	crystalhd_reg_wr(hw->adp, first_desc_u_addr, desc_addr.high_part);
 
-	crystalhd_reg_wr(hw->adp, first_desc_l_addr, desc_addr.low_part | 0x01);
+	crystalhd_reg_wr(hw->adp, first_desc_l_addr, desc_addr.low_part |
+					 0x01);
 					/* Be sure we set the valid bit ^^^^ */
 
 	return BC_STS_SUCCESS;
@@ -2120,7 +2182,8 @@ enum BC_STATUS crystalhd_hw_post_tx(stru
  *
  * FIX_ME: Not Tested the actual condition..
  */
-enum BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id)
+enum BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw,
+					 uint32_t list_id)
 {
 	if (!hw || !list_id) {
 		BCMLOG_ERR("Invalid Arguments\n");
@@ -2134,7 +2197,7 @@ enum BC_STATUS crystalhd_hw_cancel_tx(st
 }
 
 enum BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
-				    struct crystalhd_dio_req *ioreq, bool en_post)
+				 struct crystalhd_dio_req *ioreq, bool en_post)
 {
 	struct crystalhd_rx_dma_pkt *rpkt;
 	uint32_t tag, uv_desc_ix = 0;
@@ -2154,7 +2217,8 @@ enum BC_STATUS crystalhd_hw_add_cap_buff
 	rpkt->dio_req = ioreq;
 	tag = rpkt->pkt_tag;
 
-	sts = crystalhd_xlat_sgl_to_dma_desc(ioreq, &rpkt->desc_mem, &uv_desc_ix);
+	sts = crystalhd_xlat_sgl_to_dma_desc(ioreq, &rpkt->desc_mem,
+					 &uv_desc_ix);
 	if (sts != BC_STS_SUCCESS)
 		return sts;
 
@@ -2163,7 +2227,7 @@ enum BC_STATUS crystalhd_hw_add_cap_buff
 	/* Store the address of UV in the rx packet for post*/
 	if (uv_desc_ix)
 		rpkt->uv_phy_addr = rpkt->desc_mem.phy_addr +
-				    (sizeof(struct dma_descriptor) * (uv_desc_ix + 1));
+			 (sizeof(struct dma_descriptor) * (uv_desc_ix + 1));
 
 	if (en_post)
 		sts = crystalhd_hw_post_cap_buff(hw, rpkt);
@@ -2190,7 +2254,8 @@ enum BC_STATUS crystalhd_hw_get_cap_buff
 	rpkt = crystalhd_dioq_fetch_wait(hw->rx_rdyq, timeout, &sig_pending);
 	if (!rpkt) {
 		if (sig_pending) {
-			BCMLOG(BCMLOG_INFO, "wait on frame time out %d\n", sig_pending);
+			BCMLOG(BCMLOG_INFO, "wait on frame time out %d\n",
+					 sig_pending);
 			return BC_STS_IO_USER_ABORT;
 		} else {
 			return BC_STS_TIMEOUT;
@@ -2305,7 +2370,8 @@ enum BC_STATUS crystalhd_hw_suspend(stru
 	return BC_STS_SUCCESS;
 }
 
-void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats)
+void crystalhd_hw_stats(struct crystalhd_hw *hw,
+		 struct crystalhd_hw_stats *stats)
 {
 	if (!hw) {
 		BCMLOG_ERR("Invalid Arguments\n");
@@ -2378,7 +2444,8 @@ enum BC_STATUS crystalhd_hw_set_core_clo
 
 		if (reg & 0x00020000) {
 			hw->prev_n = n;
-			/* FIXME: jarod: outputting a random "C" is... confusing... */
+			/* FIXME: jarod: outputting
+			 a random "C" is... confusing... */
 			BCMLOG(BCMLOG_INFO, "C");
 			return BC_STS_SUCCESS;
 		} else {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_hw.h linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_hw.h
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_hw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_hw.h	2013-08-25 20:43:22.000000000 -0400
@@ -46,7 +46,7 @@
 #define Cpu2HstMbx1		0x00100F04
 #define MbxStat1		0x00100F08
 #define Stream2Host_Intr_Sts	0x00100F24
-#define C011_RET_SUCCESS	0x0	/* Reutrn status of firmware command. */
+#define C011_RET_SUCCESS	0x0 /* Reutrn status of firmware command. */
 
 /* TS input status register */
 #define TS_StreamAFIFOStatus	0x0010044C
@@ -103,7 +103,7 @@
 #define BC_FWIMG_ST_ADDR	0x00000000
 /* FIXME: jarod: there's a kernel function that'll do this for us... */
 #define rotr32_1(x, n)		(((x) >> n) | ((x) << (32 - n)))
-#define bswap_32_1(x)		((rotr32_1((x), 24) & 0x00ff00ff) | (rotr32_1((x), 8) & 0xff00ff00))
+#define bswap_32_1(x) ((rotr32_1((x), 24) & 0x00ff00ff) | (rotr32_1((x), 8) & 0xff00ff00))
 
 #define DecHt_HostSwReset	0x340000
 #define BC_DRAM_FW_CFG_ADDR	0x001c2000
@@ -136,9 +136,11 @@ union intr_mask_reg {
 
 union link_misc_perst_deco_ctrl {
 	struct {
-		uint32_t	bcm7412_rst:1;		/* 1 -> BCM7412 is held in reset. Reset value 1.*/
+		uint32_t	bcm7412_rst:1;	/* 1 -> BCM7412 is held
+						in reset. Reset value 1.*/
 		uint32_t	reserved0:3;		/* Reserved.No Effect*/
-		uint32_t	stop_bcm_7412_clk:1;	/* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
+		uint32_t	stop_bcm_7412_clk:1;	/* 1 ->Stops branch of
+						27MHz clk used to clk BCM7412*/
 		uint32_t	reserved1:27;		/* Reseved. No Effect*/
 	};
 
@@ -148,13 +150,18 @@ union link_misc_perst_deco_ctrl {
 
 union link_misc_perst_clk_ctrl {
 	struct {
-		uint32_t	sel_alt_clk:1;	  /* When set, selects a 6.75MHz clock as the source of core_clk */
-		uint32_t	stop_core_clk:1;  /* When set, stops the branch of core_clk that is not needed for low power operation */
-		uint32_t	pll_pwr_dn:1;	  /* When set, powers down the main PLL. The alternate clock bit should be set
-						     to select an alternate clock before setting this bit.*/
+		uint32_t	sel_alt_clk:1;	  /* When set, selects a
+				 6.75MHz clock as the source of core_clk */
+		uint32_t	stop_core_clk:1;  /* When set, stops the branch
+		 of core_clk that is not needed for low power operation */
+		uint32_t	pll_pwr_dn:1;	  /* When set, powers down the
+			 main PLL. The alternate clock bit should be set to
+			 select an alternate clock before setting this bit.*/
 		uint32_t	reserved0:5;	  /* Reserved */
-		uint32_t	pll_mult:8;	  /* This setting controls the multiplier for the PLL. */
-		uint32_t	pll_div:4;	  /* This setting controls the divider for the PLL. */
+		uint32_t	pll_mult:8;	  /* This setting controls
+						 the multiplier for the PLL. */
+		uint32_t	pll_div:4;	  /* This setting controls
+						 the divider for the PLL. */
 		uint32_t	reserved1:12;	  /* Reserved */
 	};
 
@@ -164,9 +171,11 @@ union link_misc_perst_clk_ctrl {
 
 union link_misc_perst_decoder_ctrl {
 	struct {
-		uint32_t	bcm_7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/
+		uint32_t	bcm_7412_rst:1; /* 1 -> BCM7412 is held
+						 in reset. Reset value 1.*/
 		uint32_t	res0:3; /* Reserved.No Effect*/
-		uint32_t	stop_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
+		uint32_t	stop_7412_clk:1; /* 1 ->Stops branch of 27MHz
+						 clk used to clk BCM7412*/
 		uint32_t	res1:27; /* Reseved. No Effect */
 	};
 
@@ -225,10 +234,12 @@ struct dma_descriptor {	/* 8 32-bit valu
  * The  virtual address will determine what should be freed.
  */
 struct dma_desc_mem {
-	struct dma_descriptor	*pdma_desc_start; /* 32-bytes for dma descriptor. should be first element */
-	dma_addr_t		phy_addr;	/* physical address of each DMA desc */
+	struct dma_descriptor	*pdma_desc_start; /* 32-bytes for dma
+				 descriptor. should be first element */
+	dma_addr_t		phy_addr;	/* physical address
+						 of each DMA desc */
 	uint32_t		sz;
-	struct _dma_desc_mem_	*Next;		/* points to Next Descriptor in chain */
+	struct _dma_desc_mem_	*Next; /* points to Next Descriptor in chain */
 
 };
 
@@ -323,50 +334,54 @@ struct crystalhd_hw {
 #define CLOCK_PRESET 175
 
 /* DMA engine register BIT mask wrappers.. */
-#define DMA_START_BIT		MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK
+#define DMA_START_BIT	MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK
 
-#define GET_RX_INTR_MASK (INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK |		\
-			  INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK |	\
-			  INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK |		\
-			  INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK |		\
-			  INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK |		\
-			  INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK |	\
-			  INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK |		\
-			  INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
+#define GET_RX_INTR_MASK (INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK |	\
+	INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK |	\
+	INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK |		\
+	INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK |		\
+	INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK |		\
+	INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK |	\
+	INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK |		\
+	INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
 
-#define GET_Y0_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK |		\
-			MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK |		\
-			MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK |	\
-			MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
+#define GET_Y0_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
+	MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK |		\
+	MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK |	\
+	MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
 
-#define GET_UV0_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK |		\
-			 MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK |		\
-			 MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK |	\
-			 MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
+#define GET_UV0_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
+	MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK |		\
+	MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK |	\
+	MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
 
-#define GET_Y1_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK |		\
-			MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK |		\
-			MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK |	\
-			MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
+#define GET_Y1_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
+	MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK |		\
+	MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK |	\
+	MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
 
-#define GET_UV1_ERR_MSK	(MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK |		\
-			 MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK |		\
-			 MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK |	\
-			 MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
+#define GET_UV1_ERR_MSK	(MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
+	MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK |		\
+	MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK |	\
+	MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
 
 
 /**** API Exposed to the other layers ****/
 enum BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp,
 			      void *buffer, uint32_t sz);
-enum BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, struct BC_FW_CMD *fw_cmd);
-bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw);
-enum BC_STATUS crystalhd_hw_open(struct crystalhd_hw *, struct crystalhd_adp *);
+enum BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw,
+				 struct BC_FW_CMD *fw_cmd);
+bool crystalhd_hw_interrupt(struct crystalhd_adp *adp,
+				 struct crystalhd_hw *hw);
+enum BC_STATUS crystalhd_hw_open(struct crystalhd_hw *,
+				 struct crystalhd_adp *);
 enum BC_STATUS crystalhd_hw_close(struct crystalhd_hw *);
 enum BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *);
 enum BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *);
 
 
-enum BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, struct crystalhd_dio_req *ioreq,
+enum BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw,
+			     struct crystalhd_dio_req *ioreq,
 			     hw_comp_callback call_back,
 			     wait_queue_head_t *cb_event,
 			     uint32_t *list_id, uint8_t data_flags);
@@ -374,15 +389,17 @@ enum BC_STATUS crystalhd_hw_post_tx(stru
 enum BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw);
 enum BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw);
 enum BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw);
-enum BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id);
+enum BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw,
+				 uint32_t list_id);
 enum BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
-				    struct crystalhd_dio_req *ioreq, bool en_post);
+			 struct crystalhd_dio_req *ioreq, bool en_post);
 enum BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
 				    struct BC_PIC_INFO_BLOCK *pib,
 				    struct crystalhd_dio_req **ioreq);
 enum BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw);
 enum BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw);
-void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats);
+void crystalhd_hw_stats(struct crystalhd_hw *hw,
+			 struct crystalhd_hw_stats *stats);
 
 /* API to program the core clock on the decoder */
 enum BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_lnx.c linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_lnx.c
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_lnx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_lnx.c	2013-08-25 20:43:22.000000000 -0400
@@ -75,7 +75,8 @@ static int chd_dec_disable_int(struct cr
 	return 0;
 }
 
-struct crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr)
+struct crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp,
+					 bool isr)
 {
 	unsigned long flags = 0;
 	struct crystalhd_ioctl_data *temp;
@@ -95,8 +96,8 @@ struct crystalhd_ioctl_data *chd_dec_all
 	return temp;
 }
 
-void chd_dec_free_iodata(struct crystalhd_adp *adp, struct crystalhd_ioctl_data *iodata,
-			 bool isr)
+void chd_dec_free_iodata(struct crystalhd_adp *adp,
+			 struct crystalhd_ioctl_data *iodata, bool isr)
 {
 	unsigned long flags = 0;
 
@@ -109,7 +110,8 @@ void chd_dec_free_iodata(struct crystalh
 	spin_unlock_irqrestore(&adp->lock, flags);
 }
 
-static inline int crystalhd_user_data(unsigned long ud, void *dr, int size, int set)
+static inline int crystalhd_user_data(unsigned long ud, void *dr,
+			 int size, int set)
 {
 	int rc;
 
@@ -131,8 +133,8 @@ static inline int crystalhd_user_data(un
 	return rc;
 }
 
-static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, struct crystalhd_ioctl_data *io,
-			       uint32_t m_sz, unsigned long ua)
+static int chd_dec_fetch_cdata(struct crystalhd_adp *adp,
+	 struct crystalhd_ioctl_data *io, uint32_t m_sz, unsigned long ua)
 {
 	unsigned long ua_off;
 	int rc = 0;
@@ -163,7 +165,7 @@ static int chd_dec_fetch_cdata(struct cr
 }
 
 static int chd_dec_release_cdata(struct crystalhd_adp *adp,
-				 struct crystalhd_ioctl_data *io, unsigned long ua)
+			 struct crystalhd_ioctl_data *io, unsigned long ua)
 {
 	unsigned long ua_off;
 	int rc;
@@ -178,8 +180,9 @@ static int chd_dec_release_cdata(struct
 		rc = crystalhd_user_data(ua_off, io->add_cdata,
 					io->add_cdata_sz, 1);
 		if (rc) {
-			BCMLOG_ERR("failed to push add_cdata sz:%x ua_off:%x\n",
-				   io->add_cdata_sz, (unsigned int)ua_off);
+			BCMLOG_ERR(
+				"failed to push add_cdata sz:%x ua_off:%x\n",
+				 io->add_cdata_sz, (unsigned int)ua_off);
 			return -ENODATA;
 		}
 	}
@@ -252,10 +255,7 @@ static int chd_dec_api_cmd(struct crysta
 		rc = chd_dec_proc_user_data(adp, temp, ua, 1);
 	}
 
-	if (temp) {
-		chd_dec_free_iodata(adp, temp, 0);
-		temp = NULL;
-	}
+	chd_dec_free_iodata(adp, temp, 0);
 
 	return rc;
 }
@@ -378,8 +378,8 @@ static int chd_dec_init_chdev(struct cry
 		goto class_create_fail;
 	}
 
-	dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0),
-			    NULL, "crystalhd");
+	dev = device_create(crystalhd_class, NULL,
+			 MKDEV(adp->chd_dec_major, 0), NULL, "crystalhd");
 	if (IS_ERR(dev)) {
 		rc = PTR_ERR(dev);
 		BCMLOG_ERR("failed to create device\n");
@@ -394,7 +394,8 @@ static int chd_dec_init_chdev(struct cry
 
 	/* Allocate general purpose ioctl pool. */
 	for (i = 0; i < CHD_IODATA_POOL_SZ; i++) {
-		temp = kzalloc(sizeof(struct crystalhd_ioctl_data), GFP_KERNEL);
+		temp = kzalloc(sizeof(struct crystalhd_ioctl_data),
+					 GFP_KERNEL);
 		if (!temp) {
 			BCMLOG_ERR("ioctl data pool kzalloc failed\n");
 			rc = -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_lnx.h linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_lnx.h
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_lnx.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_lnx.h	2013-08-25 20:43:22.000000000 -0400
@@ -77,8 +77,8 @@ struct crystalhd_adp {
 	int		chd_dec_major;
 	unsigned int		cfg_users;
 
-	struct crystalhd_ioctl_data	*idata_free_head;	/* ioctl data pool */
-	struct crystalhd_elem		*elem_pool_head;	/* Queue element pool */
+	struct crystalhd_ioctl_data	*idata_free_head; /* ioctl data pool */
+	struct crystalhd_elem	*elem_pool_head; /* Queue element pool */
 
 	struct crystalhd_cmd	cmds;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_misc.c linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_misc.c
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_misc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_misc.c	2013-08-25 20:43:22.000000000 -0400
@@ -30,19 +30,22 @@
 
 uint32_t g_linklog_level;
 
-static inline uint32_t crystalhd_dram_rd(struct crystalhd_adp *adp, uint32_t mem_off)
+static inline uint32_t crystalhd_dram_rd(struct crystalhd_adp *adp,
+					 uint32_t mem_off)
 {
 	crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
 	return bc_dec_reg_rd(adp, (0x00380000 | (mem_off & 0x0007FFFF)));
 }
 
-static inline void crystalhd_dram_wr(struct crystalhd_adp *adp, uint32_t mem_off, uint32_t val)
+static inline void crystalhd_dram_wr(struct crystalhd_adp *adp,
+					 uint32_t mem_off, uint32_t val)
 {
 	crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
 	bc_dec_reg_wr(adp, (0x00380000 | (mem_off & 0x0007FFFF)), val);
 }
 
-static inline enum BC_STATUS bc_chk_dram_range(struct crystalhd_adp *adp, uint32_t start_off, uint32_t cnt)
+static inline enum BC_STATUS bc_chk_dram_range(struct crystalhd_adp *adp,
+					 uint32_t start_off, uint32_t cnt)
 {
 	return BC_STS_SUCCESS;
 }
@@ -66,7 +69,8 @@ static struct crystalhd_dio_req *crystal
 	return temp;
 }
 
-static void crystalhd_free_dio(struct crystalhd_adp *adp, struct crystalhd_dio_req *dio)
+static void crystalhd_free_dio(struct crystalhd_adp *adp,
+					 struct crystalhd_dio_req *dio)
 {
 	unsigned long flags = 0;
 
@@ -99,7 +103,8 @@ static struct crystalhd_elem *crystalhd_
 
 	return temp;
 }
-static void crystalhd_free_elem(struct crystalhd_adp *adp, struct crystalhd_elem *elem)
+static void crystalhd_free_elem(struct crystalhd_adp *adp,
+					 struct crystalhd_elem *elem)
 {
 	unsigned long flags = 0;
 
@@ -120,7 +125,8 @@ static inline void crystalhd_set_sg(stru
 #endif
 }
 
-static inline void crystalhd_init_sg(struct scatterlist *sg, unsigned int entries)
+static inline void crystalhd_init_sg(struct scatterlist *sg,
+					 unsigned int entries)
 {
 	/* http://lkml.org/lkml/2007/11/27/68 */
 	sg_init_table(sg, entries);
@@ -208,7 +214,8 @@ uint32_t crystalhd_reg_rd(struct crystal
  * configuration space.
  *
  */
-void crystalhd_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val)
+void crystalhd_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off,
+					 uint32_t val)
 {
 	if (!adp || (reg_off > adp->pci_i2o_len)) {
 		BCMLOG_ERR("link_wr_reg_off outof range: 0x%08x\n", reg_off);
@@ -469,7 +476,8 @@ enum BC_STATUS crystalhd_create_dioq(str
  * by calling the call back provided during creation.
  *
  */
-void crystalhd_delete_dioq(struct crystalhd_adp *adp, struct crystalhd_dioq *dioq)
+void crystalhd_delete_dioq(struct crystalhd_adp *adp,
+			 struct crystalhd_dioq *dioq)
 {
 	void *temp;
 
@@ -639,7 +647,8 @@ void *crystalhd_dioq_fetch_wait(struct c
 	while ((ioq->count == 0) && count) {
 		spin_unlock_irqrestore(&ioq->lock, flags);
 
-		crystalhd_wait_on_event(&ioq->event, (ioq->count > 0), 1000, rc, 0);
+		crystalhd_wait_on_event(&ioq->event,
+				 (ioq->count > 0), 1000, rc, 0);
 		if (rc == 0) {
 			goto out;
 		} else if (rc == -EINTR) {
@@ -678,7 +687,8 @@ enum BC_STATUS crystalhd_map_dio(struct
 			  struct crystalhd_dio_req **dio_hnd)
 {
 	struct crystalhd_dio_req	*dio;
-	/* FIXME: jarod: should some of these unsigned longs be uint32_t or uintptr_t? */
+	/* FIXME: jarod: should some of these
+	 unsigned longs be uint32_t or uintptr_t? */
 	unsigned long start = 0, end = 0, uaddr = 0, count = 0;
 	unsigned long spsz = 0, uv_start = 0;
 	int i = 0, rw = 0, res = 0, nr_pages = 0, skip_fb_sg = 0;
@@ -723,7 +733,8 @@ enum BC_STATUS crystalhd_map_dio(struct
 	if (uv_offset) {
 		uv_start = (uaddr + (unsigned long)uv_offset)  >> PAGE_SHIFT;
 		dio->uinfo.uv_sg_ix = uv_start - start;
-		dio->uinfo.uv_sg_off = ((uaddr + (unsigned long)uv_offset) & ~PAGE_MASK);
+		dio->uinfo.uv_sg_off = ((uaddr + (unsigned long)uv_offset) &
+					 ~PAGE_MASK);
 	}
 
 	dio->fb_size = ubuff_sz & 0x03;
@@ -819,7 +830,8 @@ enum BC_STATUS crystalhd_map_dio(struct
  *
  * This routine is to unmap the user buffer pages.
  */
-enum BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp, struct crystalhd_dio_req *dio)
+enum BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp,
+				 struct crystalhd_dio_req *dio)
 {
 	struct page *page = NULL;
 	int j = 0;
@@ -841,7 +853,8 @@ enum BC_STATUS crystalhd_unmap_dio(struc
 		}
 	}
 	if (dio->sig == crystalhd_dio_sg_mapped)
-		pci_unmap_sg(adp->pdev, dio->sg, dio->page_cnt, dio->direction);
+		pci_unmap_sg(adp->pdev, dio->sg, dio->page_cnt,
+			 dio->direction);
 
 	crystalhd_free_dio(adp, dio);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_misc.h linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_misc.h
--- linux-libre-3.10-gnu/drivers/staging/crystalhd/crystalhd_misc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/crystalhd/crystalhd_misc.h	2013-08-25 20:43:22.000000000 -0400
@@ -127,12 +127,16 @@ uint32_t crystalhd_reg_rd(struct crystal
 void crystalhd_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t);
 
 /*========= Decoder (7412) memory access routines..=================*/
-enum BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
-enum BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
+enum BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *,
+			 uint32_t, uint32_t, uint32_t *);
+enum BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *,
+			 uint32_t, uint32_t, uint32_t *);
 
 /*==========Link (70012) PCIe Config access routines.================*/
-enum BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
-enum BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t);
+enum BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *,
+			 uint32_t, uint32_t, uint32_t *);
+enum BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *,
+			 uint32_t, uint32_t, uint32_t);
 
 /*========= Linux Kernel Interface routines. ======================= */
 void *bc_kern_dma_alloc(struct crystalhd_adp *, uint32_t, dma_addr_t *);
@@ -168,20 +172,26 @@ do {									\
 /*================ Direct IO mapping routines ==================*/
 extern int crystalhd_create_dio_pool(struct crystalhd_adp *, uint32_t);
 extern void crystalhd_destroy_dio_pool(struct crystalhd_adp *);
-extern enum BC_STATUS crystalhd_map_dio(struct crystalhd_adp *, void *, uint32_t,
-				   uint32_t, bool, bool, struct crystalhd_dio_req**);
+extern enum BC_STATUS crystalhd_map_dio(struct crystalhd_adp *, void *,
+		 uint32_t, uint32_t, bool, bool, struct crystalhd_dio_req**);
 
-extern enum BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *, struct crystalhd_dio_req*);
+extern enum BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *,
+					 struct crystalhd_dio_req*);
 #define crystalhd_get_sgle_paddr(_dio, _ix) (cpu_to_le64(sg_dma_address(&_dio->sg[_ix])))
 #define crystalhd_get_sgle_len(_dio, _ix) (cpu_to_le32(sg_dma_len(&_dio->sg[_ix])))
 
 /*================ General Purpose Queues ==================*/
-extern enum BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *, struct crystalhd_dioq **, crystalhd_data_free_cb , void *);
-extern void crystalhd_delete_dioq(struct crystalhd_adp *, struct crystalhd_dioq *);
-extern enum BC_STATUS crystalhd_dioq_add(struct crystalhd_dioq *ioq, void *data, bool wake, uint32_t tag);
+extern enum BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *,
+		 struct crystalhd_dioq **, crystalhd_data_free_cb , void *);
+extern void crystalhd_delete_dioq(struct crystalhd_adp *,
+		 struct crystalhd_dioq *);
+extern enum BC_STATUS crystalhd_dioq_add(struct crystalhd_dioq *ioq,
+		 void *data, bool wake, uint32_t tag);
 extern void *crystalhd_dioq_fetch(struct crystalhd_dioq *ioq);
-extern void *crystalhd_dioq_find_and_fetch(struct crystalhd_dioq *ioq, uint32_t tag);
-extern void *crystalhd_dioq_fetch_wait(struct crystalhd_dioq *ioq, uint32_t to_secs, uint32_t *sig_pend);
+extern void *crystalhd_dioq_find_and_fetch(struct crystalhd_dioq *ioq,
+		 uint32_t tag);
+extern void *crystalhd_dioq_fetch_wait(struct crystalhd_dioq *ioq,
+		 uint32_t to_secs, uint32_t *sig_pend);
 
 #define crystalhd_dioq_count(_ioq)	((_ioq) ? _ioq->count : 0)
 
@@ -190,7 +200,8 @@ extern void crystalhd_delete_elem_pool(s
 
 
 /*================ Debug routines/macros .. ================================*/
-extern void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount);
+extern void crystalhd_show_buffer(uint32_t off, uint8_t *buff,
+		 uint32_t dwcount);
 
 enum _chd_log_levels {
 	BCMLOG_ERROR		= 0x80000000,	/* Don't disable this option */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/bh.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/bh.c
--- linux-libre-3.10-gnu/drivers/staging/csr/bh.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/bh.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,397 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     bh.c
- *
- * PURPOSE:
- *      Provides an implementation for the driver bottom-half.
- *      It is part of the porting exercise in Linux.
- *
- * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include "csr_wifi_hip_unifi.h"
-#include "unifi_priv.h"
-#include <linux/sched/rt.h>
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_start_thread
- *
- *      Helper function to start a new thread.
- *
- *  Arguments:
- *      priv            Pointer to OS driver structure for the device.
- *      thread          Pointer to the thread object
- *      func            The thread function
- *
- *  Returns:
- *      0 on success or else a Linux error code.
- * ---------------------------------------------------------------------------
- */
-int uf_start_thread(unifi_priv_t *priv,
-		    struct uf_thread *thread, int (*func)(void *))
-{
-	if (thread->thread_task != NULL) {
-		unifi_error(priv, "%s thread already started\n", thread->name);
-		return 0;
-	}
-
-	/* Start the kernel thread that handles all h/w accesses. */
-	thread->thread_task = kthread_run(func, priv, "%s", thread->name);
-	if (IS_ERR(thread->thread_task))
-		return PTR_ERR(thread->thread_task);
-
-	/* Module parameter overides the thread priority */
-	if (bh_priority != -1) {
-		if (bh_priority >= 0 && bh_priority <= MAX_RT_PRIO) {
-			struct sched_param param;
-			priv->bh_thread.prio = bh_priority;
-			unifi_trace(priv, UDBG1,
-				"%s thread (RT) priority = %d\n",
-				thread->name, bh_priority);
-			param.sched_priority = bh_priority;
-			sched_setscheduler(thread->thread_task,
-					   SCHED_FIFO, &param);
-		} else if (bh_priority > MAX_RT_PRIO &&
-			   bh_priority <= MAX_PRIO) {
-			priv->bh_thread.prio = bh_priority;
-			unifi_trace(priv, UDBG1, "%s thread priority = %d\n",
-					thread->name,
-					PRIO_TO_NICE(bh_priority));
-			set_user_nice(thread->thread_task,
-				      PRIO_TO_NICE(bh_priority));
-		} else {
-			priv->bh_thread.prio = DEFAULT_PRIO;
-			unifi_warning(priv,
-				      "%s thread unsupported (%d) priority\n",
-				      thread->name, bh_priority);
-		}
-	} else
-		priv->bh_thread.prio = DEFAULT_PRIO;
-	unifi_trace(priv, UDBG2, "Started %s thread\n", thread->name);
-
-	return 0;
-} /* uf_start_thread() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_stop_thread
- *
- *      Helper function to stop a thread.
- *
- *  Arguments:
- *      priv            Pointer to OS driver structure for the device.
- *      thread          Pointer to the thread object
- *
- *  Returns:
- *
- * ---------------------------------------------------------------------------
- */
-void uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread)
-{
-	if (!thread->thread_task) {
-		unifi_notice(priv, "%s thread is already stopped\n",
-							thread->name);
-		return;
-	}
-
-	unifi_trace(priv, UDBG2, "Stopping %s thread\n", thread->name);
-
-	kthread_stop(thread->thread_task);
-	thread->thread_task = NULL;
-
-} /* uf_stop_thread() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_wait_for_thread_to_stop
- *
- *      Helper function to wait until a thread is stopped.
- *
- *  Arguments:
- *      priv    Pointer to OS driver structure for the device.
- *
- *  Returns:
- *
- * ---------------------------------------------------------------------------
- */
-void
-uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread)
-{
-	/*
-	 * kthread_stop() cannot handle the thread exiting while
-	 * kthread_should_stop() is false, so sleep until kthread_stop()
-	 * wakes us up
-	 */
-	unifi_trace(priv, UDBG2, "%s waiting for the stop signal.\n",
-							thread->name);
-	set_current_state(TASK_INTERRUPTIBLE);
-	if (!kthread_should_stop()) {
-		unifi_trace(priv, UDBG2, "%s schedule....\n", thread->name);
-		schedule();
-	}
-
-	thread->thread_task = NULL;
-	unifi_trace(priv, UDBG2, "%s exiting....\n", thread->name);
-} /* uf_wait_for_thread_to_stop() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  handle_bh_error
- *
- *      This function reports an error returned from the HIP core bottom-half.
- *      Normally, implemented during the porting exercise, passing the error
- *      to the SME using unifi_sys_wifi_off_ind().
- *      The SME will try to reset the device and go through
- *      the initialisation of the UniFi.
- *
- *  Arguments:
- *      priv            Pointer to OS driver structure for the device.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void
-handle_bh_error(unifi_priv_t *priv)
-{
-	netInterface_priv_t *interfacePriv;
-	u8 conf_param = CONFIG_IND_ERROR;
-	u8 interfaceTag;
-
-
-	/* Block unifi_run_bh() until the error has been handled. */
-	priv->bh_thread.block_thread = 1;
-
-	/* Consider UniFi to be uninitialised */
-	priv->init_progress = UNIFI_INIT_NONE;
-
-	/* Stop the network traffic */
-	for (interfaceTag = 0;
-	     interfaceTag < CSR_WIFI_NUM_INTERFACES; interfaceTag++) {
-		interfacePriv = priv->interfacePriv[interfaceTag];
-		if (interfacePriv->netdev_registered)
-			netif_carrier_off(priv->netdev[interfaceTag]);
-	}
-
-#ifdef CSR_NATIVE_LINUX
-	/* Force any client waiting on an mlme_wait_for_reply() to abort. */
-	uf_abort_mlme(priv);
-
-	/* Cancel any pending workqueue tasks */
-	flush_workqueue(priv->unifi_workqueue);
-
-#endif /* CSR_NATIVE_LINUX */
-
-	unifi_error(priv,
-		"handle_bh_error: fatal error is reported to the SME.\n");
-	/* Notify the clients (SME or unifi_manager) for the error. */
-	ul_log_config_ind(priv, &conf_param, sizeof(u8));
-
-} /* handle_bh_error() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  bh_thread_function
- *
- *      All hardware access happens in this thread.
- *      This means there is no need for locks on the hardware and we don't need
- *      to worry about reentrancy with the SDIO library.
- *      Provides and example implementation on how to call unifi_bh(), which
- *      is part of the HIP core API.
- *
- *      It processes the events generated by unifi_run_bh() to serialise calls
- *      to unifi_bh(). It also demonstrates how the timeout parameter passed in
- *      and returned from unifi_bh() needs to be handled.
- *
- *  Arguments:
- *      arg             Pointer to OS driver structure for the device.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      When the bottom half of the driver needs to process signals, events,
- *      or simply the host status (i.e sleep mode), it invokes unifi_run_bh().
- *      Since we need all SDIO transaction to be in a single thread, the
- *      unifi_run_bh() will wake up this thread to process it.
- *
- * ---------------------------------------------------------------------------
- */
-static int bh_thread_function(void *arg)
-{
-	unifi_priv_t *priv = (unifi_priv_t *)arg;
-	CsrResult csrResult;
-	long ret;
-	u32 timeout, t;
-	struct uf_thread *this_thread;
-
-	unifi_trace(priv, UDBG2, "bh_thread_function starting\n");
-
-	this_thread = &priv->bh_thread;
-
-	t = timeout = 0;
-    while (!kthread_should_stop()) {
-        /* wait until an error occurs, or we need to process something. */
-        unifi_trace(priv, UDBG3, "bh_thread goes to sleep.\n");
-
-        if (timeout > 0) {
-            /* Convert t in ms to jiffies */
-            t = msecs_to_jiffies(timeout);
-            ret = wait_event_interruptible_timeout(this_thread->wakeup_q,
-                    (this_thread->wakeup_flag && !this_thread->block_thread) ||
-                    kthread_should_stop(),
-                    t);
-            timeout = (ret > 0) ? jiffies_to_msecs(ret) : 0;
-        } else {
-            ret = wait_event_interruptible(this_thread->wakeup_q,
-                    (this_thread->wakeup_flag && !this_thread->block_thread) ||
-                    kthread_should_stop());
-        }
-
-        if (kthread_should_stop()) {
-            unifi_trace(priv, UDBG2, "bh_thread: signalled to exit\n");
-            break;
-        }
-
-        if (ret < 0) {
-            unifi_notice(priv,
-                    "bh_thread: wait_event returned %d, thread will exit\n",
-                    ret);
-            uf_wait_for_thread_to_stop(priv, this_thread);
-            break;
-        }
-
-        this_thread->wakeup_flag = 0;
-
-        unifi_trace(priv, UDBG3, "bh_thread calls unifi_bh().\n");
-
-        CsrSdioClaim(priv->sdio);
-        csrResult = unifi_bh(priv->card, &timeout);
-        if(csrResult != CSR_RESULT_SUCCESS) {
-            if (csrResult == CSR_WIFI_HIP_RESULT_NO_DEVICE) {
-                CsrSdioRelease(priv->sdio);
-                uf_wait_for_thread_to_stop(priv, this_thread);
-                break;
-            }
-            /* Errors must be delivered to the error task */
-            handle_bh_error(priv);
-        }
-        CsrSdioRelease(priv->sdio);
-    }
-
-    /*
-     * I would normally try to call csr_sdio_remove_irq() here to make sure
-     * that we do not get any interrupts while this thread is not running.
-     * However, the MMC/SDIO driver tries to kill its' interrupt thread.
-     * The kernel threads implementation does not allow to kill threads
-     * from a signalled to stop thread.
-     * So, instead call csr_sdio_linux_remove_irq() always after calling
-     * uf_stop_thread() to kill this thread.
-     */
-
-    unifi_trace(priv, UDBG2, "bh_thread exiting....\n");
-    return 0;
-} /* bh_thread_function() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_init_bh
- *
- *      Helper function to start the bottom half of the driver.
- *      All we need to do here is start the I/O bh thread.
- *
- *  Arguments:
- *      priv            Pointer to OS driver structure for the device.
- *
- *  Returns:
- *      0 on success or else a Linux error code.
- * ---------------------------------------------------------------------------
- */
-    int
-uf_init_bh(unifi_priv_t *priv)
-{
-    int r;
-
-    /* Enable mlme interface. */
-    priv->io_aborted = 0;
-
-
-    /* Start the BH thread */
-    r = uf_start_thread(priv, &priv->bh_thread, bh_thread_function);
-    if (r) {
-        unifi_error(priv,
-                "uf_init_bh: failed to start the BH thread.\n");
-        return r;
-    }
-
-    /* Allow interrupts */
-    r = csr_sdio_linux_install_irq(priv->sdio);
-    if (r) {
-        unifi_error(priv,
-                "uf_init_bh: failed to install the IRQ.\n");
-
-        uf_stop_thread(priv, &priv->bh_thread);
-    }
-
-    return r;
-} /* uf_init_bh() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_run_bh
- *
- *      Part of the HIP core lib API, implemented in the porting exercise.
- *      The bottom half of the driver calls this function when
- *      it wants to process anything that requires access to unifi.
- *      We need to call unifi_bh() which in this implementation is done
- *      by waking up the I/O thread.
- *
- *  Arguments:
- *      ospriv          Pointer to OS driver structure for the device.
- *
- *  Returns:
- *      0 on success or else a Linux error code.
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_run_bh(void *ospriv)
-{
-    unifi_priv_t *priv = ospriv;
-
-    /*
-     * If an error has occurred, we discard silently all messages from the bh
-     * until the error has been processed and the unifi has been reinitialised.
-     */
-    if (priv->bh_thread.block_thread == 1) {
-        unifi_trace(priv, UDBG3, "unifi_run_bh: discard message.\n");
-        /*
-         * Do not try to acknowledge a pending interrupt here.
-         * This function is called by unifi_send_signal() which in turn can be
-         * running in an atomic or 'disabled irq' level if a signal is sent
-         * from a workqueue task (i.e multicass addresses set).
-         * We can not hold the SDIO lock because it might sleep.
-         */
-        return CSR_RESULT_FAILURE;
-    }
-
-    priv->bh_thread.wakeup_flag = 1;
-    /* wake up I/O thread */
-    wake_up_interruptible(&priv->bh_thread.wakeup_q);
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_run_bh() */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_framework_ext.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_framework_ext.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_framework_ext.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_framework_ext.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/kthread.h>
-#include <linux/module.h>
-#include <linux/freezer.h>
-#include <linux/semaphore.h>
-#include <linux/slab.h>
-#include <linux/bitops.h>
-
-#include "csr_framework_ext.h"
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrThreadSleep
- *
- *  DESCRIPTION
- *      Sleep for a given period.
- *
- *  RETURNS
- *      void
- *
- *----------------------------------------------------------------------------*/
-void CsrThreadSleep(u16 sleepTimeInMs)
-{
-    unsigned long t;
-
-    /* Convert t in ms to jiffies and round up */
-    t = ((sleepTimeInMs * HZ) + 999) / 1000;
-    schedule_timeout_uninterruptible(t);
-}
-EXPORT_SYMBOL_GPL(CsrThreadSleep);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_framework_ext.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_framework_ext.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_framework_ext.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_framework_ext.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-#ifndef CSR_FRAMEWORK_EXT_H__
-#define CSR_FRAMEWORK_EXT_H__
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include "csr_result.h"
-#include "csr_framework_ext_types.h"
-
-/* Result codes */
-#define CSR_FE_RESULT_NO_MORE_EVENTS    ((CsrResult) 0x0001)
-#define CSR_FE_RESULT_INVALID_POINTER   ((CsrResult) 0x0002)
-#define CSR_FE_RESULT_INVALID_HANDLE    ((CsrResult) 0x0003)
-#define CSR_FE_RESULT_NO_MORE_MUTEXES   ((CsrResult) 0x0004)
-#define CSR_FE_RESULT_TIMEOUT           ((CsrResult) 0x0005)
-#define CSR_FE_RESULT_NO_MORE_THREADS   ((CsrResult) 0x0006)
-
-/* Thread priorities */
-#define CSR_THREAD_PRIORITY_HIGHEST     ((u16) 0)
-#define CSR_THREAD_PRIORITY_HIGH        ((u16) 1)
-#define CSR_THREAD_PRIORITY_NORMAL      ((u16) 2)
-#define CSR_THREAD_PRIORITY_LOW         ((u16) 3)
-#define CSR_THREAD_PRIORITY_LOWEST      ((u16) 4)
-
-#define CSR_EVENT_WAIT_INFINITE         ((u16) 0xFFFF)
-
-void CsrThreadSleep(u16 sleepTimeInMs);
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_framework_ext_types.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_framework_ext_types.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_framework_ext_types.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_framework_ext_types.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-#ifndef CSR_FRAMEWORK_EXT_TYPES_H__
-#define CSR_FRAMEWORK_EXT_TYPES_H__
-/*****************************************************************************
-
-	(c) Cambridge Silicon Radio Limited 2010
-	All rights reserved and confidential information of CSR
-
-	Refer to LICENSE.txt included with this source for details
-	on the license terms.
-
-*****************************************************************************/
-
-#ifdef __KERNEL__
-#include <linux/kthread.h>
-#include <linux/semaphore.h>
-#else
-#include <pthread.h>
-#endif
-
-#ifdef __KERNEL__
-
-typedef struct semaphore CsrMutexHandle;
-
-#else /* __KERNEL __ */
-
-typedef pthread_mutex_t CsrMutexHandle;
-
-#endif /* __KERNEL__ */
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_log_configure.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_log_configure.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_log_configure.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_log_configure.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-#ifndef CSR_LOG_CONFIGURE_H__
-#define CSR_LOG_CONFIGURE_H__
-/*****************************************************************************
-
-  (c) Cambridge Silicon Radio Limited 2010
-  All rights reserved and confidential information of CSR
-
-  Refer to LICENSE.txt included with this source for details
-  on the license terms.
-
- *****************************************************************************/
-
-#include "csr_log.h"
-
-/*--------------------------------------------*/
-/*  Filtering on log text warning levels      */
-/*--------------------------------------------*/
-typedef u32 CsrLogLevelText;
-#define CSR_LOG_LEVEL_TEXT_OFF       ((CsrLogLevelText) 0x0000)
-
-#define CSR_LOG_LEVEL_TEXT_CRITICAL  ((CsrLogLevelText) 0x0001)
-#define CSR_LOG_LEVEL_TEXT_ERROR     ((CsrLogLevelText) 0x0002)
-#define CSR_LOG_LEVEL_TEXT_WARNING   ((CsrLogLevelText) 0x0004)
-#define CSR_LOG_LEVEL_TEXT_INFO      ((CsrLogLevelText) 0x0008)
-#define CSR_LOG_LEVEL_TEXT_DEBUG     ((CsrLogLevelText) 0x0010)
-
-#define CSR_LOG_LEVEL_TEXT_ALL       ((CsrLogLevelText) 0xFFFF)
-
-/* The log text interface is used by both scheduler tasks and components outside the scheduler context.
- * Therefore a CsrLogTextTaskId is introduced. It is effectively considered as two u16's. The lower
- * 16 bits corresponds one2one with the scheduler queueId's (CsrSchedQid) and as such these bits can not be used
- * by components outside scheduler tasks. The upper 16 bits are allocated for use of components outside the
- * scheduler like drivers etc. Components in this range is defined independently by each technology. To avoid
- * clashes the technologies are only allowed to assign values within the same restrictive range as allies to
- * primitive identifiers. eg. for the framework components outside the scheduler is only allowed to assign
- * taskId's in the range 0x0600xxxx to 0x06FFxxxx. And so on for other technologies. */
-typedef u32 CsrLogTextTaskId;
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_log.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_log.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_log.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_log.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,223 +0,0 @@
-#ifndef CSR_LOG_H__
-#define CSR_LOG_H__
-/*****************************************************************************
-
-	(c) Cambridge Silicon Radio Limited 2010
-	All rights reserved and confidential information of CSR
-
-	Refer to LICENSE.txt included with this source for details
-	on the license terms.
-
-*****************************************************************************/
-
-#include "csr_sched.h"
-#include "csr_prim_defs.h"
-#include "csr_msgconv.h"
-
-/*
- * Log filtering
- */
-
-/*----------------------------------------------------*/
-/*  Filtering on environment specific log levels      */
-/*----------------------------------------------------*/
-typedef u32 CsrLogLevelEnvironment;
-#define CSR_LOG_LEVEL_ENVIRONMENT_OFF          ((CsrLogLevelEnvironment) 0x00000000) /* No environment data/events are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_BCI_ACL      ((CsrLogLevelEnvironment) 0x00000001) /* BlueCore Channel Interface HCI Acl data are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_BCI_HCI      ((CsrLogLevelEnvironment) 0x00000002) /* BlueCore Channel Interface HCI Cmd/Evt data are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_BCI_SCO      ((CsrLogLevelEnvironment) 0x00000004) /* BlueCore Channel Interface HCI Sco data are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_BCI_VENDOR   ((CsrLogLevelEnvironment) 0x00000008) /* BlueCore Channel Interface HCI Vendor specific data are logged (This includes BCCMD, HQ, VM etc) */
-#define CSR_LOG_LEVEL_ENVIRONMENT_TRANSPORTS   ((CsrLogLevelEnvironment) 0x00000010) /* Transport protocol data is logged (This includes transport protocols like BCSP, H4 etc.) */
-#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_REG    ((CsrLogLevelEnvironment) 0x00000020) /* Background Interrupt registration events are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_UNREG  ((CsrLogLevelEnvironment) 0x00000040) /* Background Interrupt unregistration events are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_SET    ((CsrLogLevelEnvironment) 0x00000080) /* Background Interrupt set events are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_START  ((CsrLogLevelEnvironment) 0x00000100) /* Background Interrupt start events are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_BGINT_DONE   ((CsrLogLevelEnvironment) 0x00000200) /* Background Interrupt done events are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_PROTO        ((CsrLogLevelEnvironment) 0x00000400) /* Transport protocol events are logged */
-#define CSR_LOG_LEVEL_ENVIRONMENT_PROTO_LOC    ((CsrLogLevelEnvironment) 0x00000800) /* The Location where the transport protocol event occurred are logged NB: This is a supplement to CSR_LOG_LEVEL_ENVIRONMENT_PROTO, it has no effect without it */
-/* The bit masks between here are reserved for future usage */
-#define CSR_LOG_LEVEL_ENVIRONMENT_ALL          ((CsrLogLevelEnvironment) 0xFFFFFFFF) /* All possible environment data/events are logged WARNING: By using this define the application also accepts future possible environment data/events in the logs */
-
-/*----------------------------------------------------*/
-/*  Filtering on task specific log levels             */
-/*----------------------------------------------------*/
-typedef u32 CsrLogLevelTask;
-#define CSR_LOG_LEVEL_TASK_OFF                 ((CsrLogLevelTask) 0x00000000) /* No events are logged for this task */
-#define CSR_LOG_LEVEL_TASK_TEXT                ((CsrLogLevelTask) 0x00000001) /* Text strings printed by a task are logged NB: This bit does not affect the CSR_LOG_TEXT_LEVEL interface. This has to be configured separately */
-#define CSR_LOG_LEVEL_TASK_TEXT_LOC            ((CsrLogLevelTask) 0x00000002) /* The locaction where the text string call occurred are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_TEXT, it has no effect without it */
-#define CSR_LOG_LEVEL_TASK_STATE               ((CsrLogLevelTask) 0x00000004) /* FSM state transitions in a task are logged */
-#define CSR_LOG_LEVEL_TASK_STATE_NAME          ((CsrLogLevelTask) 0x00000008) /* The name of each state in a FSM state transition are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_STATE, it has no effect without it */
-#define CSR_LOG_LEVEL_TASK_STATE_LOC           ((CsrLogLevelTask) 0x00000010) /* The location where the FSM state transition occurred are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_STATE, it has no effect without it */
-#define CSR_LOG_LEVEL_TASK_TASK_SWITCH         ((CsrLogLevelTask) 0x00000020) /* Activation and deactiation of a task are logged */
-#define CSR_LOG_LEVEL_TASK_MESSAGE_PUT         ((CsrLogLevelTask) 0x00000080) /* Message put operations are logged */
-#define CSR_LOG_LEVEL_TASK_MESSAGE_PUT_LOC     ((CsrLogLevelTask) 0x00000100) /* The location where a message was sent are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_MESSAGE_PUT, it has no effect without it */
-#define CSR_LOG_LEVEL_TASK_MESSAGE_GET         ((CsrLogLevelTask) 0x00000200) /* Message get operations are logged */
-#define CSR_LOG_LEVEL_TASK_MESSAGE_QUEUE_PUSH  ((CsrLogLevelTask) 0x00000400) /* Message push operations are logged */
-#define CSR_LOG_LEVEL_TASK_MESSAGE_QUEUE_POP   ((CsrLogLevelTask) 0x00000800) /* Message pop operations are logged */
-#define CSR_LOG_LEVEL_TASK_PRIM_ONLY_TYPE      ((CsrLogLevelTask) 0x00001000) /* Only the type of primitives in messages are logged. By default the entire primitive is serialized and logged */
-#define CSR_LOG_LEVEL_TASK_PRIM_APPLY_LIMIT    ((CsrLogLevelTask) 0x00002000) /* An upper limit (defined by CSR_LOG_PRIM_SIZE_UPPER_LIMIT) is applied to how much of a primitive in a message are logged. NB: This limit is only applied if CSR_LOG_LEVEL_TASK_PRIM_ONLY_TYPE is _not_ defined */
-#define CSR_LOG_LEVEL_TASK_TIMER_IN            ((CsrLogLevelTask) 0x00004000) /* TimedEventIn events are logged */
-#define CSR_LOG_LEVEL_TASK_TIMER_IN_LOC        ((CsrLogLevelTask) 0x00008000) /* The location where a timer was started are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_TIMER_IN, it has no effect without it */
-#define CSR_LOG_LEVEL_TASK_TIMER_CANCEL        ((CsrLogLevelTask) 0x00010000) /* TimedEventCancel events are logged */
-#define CSR_LOG_LEVEL_TASK_TIMER_CANCEL_LOC    ((CsrLogLevelTask) 0x00020000) /* The location where a timer was cancelled are logged. NB: This is a supplement to CSR_LOG_LEVEL_TASK_TIMER_CANCEL, it has no effect without it */
-#define CSR_LOG_LEVEL_TASK_TIMER_FIRE          ((CsrLogLevelTask) 0x00040000) /* TimedEventFire events are logged */
-#define CSR_LOG_LEVEL_TASK_TIMER_DONE          ((CsrLogLevelTask) 0x00080000) /* TimedEventDone events are logged */
-/* The bit masks between here are reserved for future usage */
-#define CSR_LOG_LEVEL_TASK_ALL                 ((CsrLogLevelTask) 0xFFFFFFFF & ~(CSR_LOG_LEVEL_TASK_PRIM_ONLY_TYPE | CSR_LOG_LEVEL_TASK_PRIM_APPLY_LIMIT)) /* All info possible to log for a task are logged. WARNING: By using this define the application also accepts future possible task data/events in the logs */
-
-u8 CsrLogEnvironmentIsFiltered(CsrLogLevelEnvironment level);
-CsrLogLevelTask CsrLogTaskFilterGet(CsrSchedQid taskId);
-u8 CsrLogTaskIsFiltered(CsrSchedQid taskId, CsrLogLevelTask level);
-
-/*
- * Logging stuff
- */
-#define CSR_LOG_STRINGIFY_REAL(a) (#a)
-#define CSR_LOG_STRINGIFY(a) CSR_LOG_STRINGIFY_REAL(a)
-
-typedef struct {
-	u16            primitiveType;
-	const char *primitiveName;
-	CsrMsgConvMsgEntry  *messageConv; /* Private - do not use */
-} CsrLogPrimitiveInformation;
-
-typedef struct {
-	const char        *techVer;
-	u32                   primitiveInfoCount;
-	CsrLogPrimitiveInformation *primitiveInfo;
-} CsrLogTechInformation;
-
-/*---------------------------------*/
-/*  Tech logging */
-/*---------------------------------*/
-typedef u8 bitmask8_t;
-typedef u16 bitmask16_t;
-typedef u32 bitmask32_t;
-
-#ifdef CSR_LOG_ENABLE
-#ifdef CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER
-/* DEPRECATED - replaced by csr_log_text.h */
-#define CSR_LOG_TEXT(text) \
-	do { \
-		if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) { \
-			CsrLogTaskText(text, __LINE__, __FILE__); \
-		} \
-	} while (0)
-#else
-/* DEPRECATED - replaced by csr_log_text.h */
-#define CSR_LOG_TEXT(text) \
-	do { \
-		if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) { \
-			CsrLogTaskText(text, 0, NULL); \
-		} \
-	} while (0)
-#endif
-#else
-#define CSR_LOG_TEXT(text)
-#endif
-
-/* DEPRECATED - replaced by csr_log_text.h */
-void CsrLogTaskText(const char *text,
-	u32 line,
-	const char *file);
-
-#define CSR_LOG_STATE_TRANSITION_MASK_FSM_NAME          (0x001)
-#define CSR_LOG_STATE_TRANSITION_MASK_NEXT_STATE        (0x002)
-#define CSR_LOG_STATE_TRANSITION_MASK_NEXT_STATE_STR    (0x004)
-#define CSR_LOG_STATE_TRANSITION_MASK_PREV_STATE        (0x008)
-#define CSR_LOG_STATE_TRANSITION_MASK_PREV_STATE_STR    (0x010)
-#define CSR_LOG_STATE_TRANSITION_MASK_EVENT             (0x020)
-#define CSR_LOG_STATE_TRANSITION_MASK_EVENT_STR         (0x040)
-
-/* DEPRECATED - replaced by csr_log_text.h */
-void CsrLogStateTransition(bitmask16_t mask,
-	u32 identifier,
-	const char *fsm_name,
-	u32 prev_state,
-	const char *prev_state_str,
-	u32 in_event,
-	const char *in_event_str,
-	u32 next_state,
-	const char *next_state_str,
-	u32 line,
-	const char *file);
-
-/*---------------------------------*/
-/*  BSP logging */
-/*---------------------------------*/
-void CsrLogSchedInit(u8 thread_id);
-void CsrLogSchedDeinit(u8 thread_id);
-
-void CsrLogSchedStart(u8 thread_id);
-void CsrLogSchedStop(u8 thread_id);
-
-void CsrLogInitTask(u8 thread_id, CsrSchedQid tskid, const char *tskName);
-void CsrLogDeinitTask(u16 task_id);
-
-void CsrLogActivate(CsrSchedQid tskid);
-void CsrLogDeactivate(CsrSchedQid tskid);
-
-#define SYNERGY_SERIALIZER_TYPE_DUMP    (0x000)
-#define SYNERGY_SERIALIZER_TYPE_SER     (0x001)
-
-void CsrLogMessagePut(u32 line,
-	const char *file,
-	CsrSchedQid src_task_id,
-	CsrSchedQid dst_taskid,
-	CsrSchedMsgId msg_id,
-	u16 prim_type,
-	const void *msg);
-
-void CsrLogMessageGet(CsrSchedQid src_task_id,
-	CsrSchedQid dst_taskid,
-	u8 get_res,
-	CsrSchedMsgId msg_id,
-	u16 prim_type,
-	const void *msg);
-
-void CsrLogTimedEventIn(u32 line,
-	const char *file,
-	CsrSchedQid task_id,
-	CsrSchedTid tid,
-	u32 requested_delay,
-	u16 fniarg,
-	const void *fnvarg);
-
-void CsrLogTimedEventFire(CsrSchedQid task_id,
-	CsrSchedTid tid);
-
-void CsrLogTimedEventDone(CsrSchedQid task_id,
-	CsrSchedTid tid);
-
-void CsrLogTimedEventCancel(u32 line,
-	const char *file,
-	CsrSchedQid task_id,
-	CsrSchedTid tid,
-	u8 cancel_res);
-
-void CsrLogBgintRegister(u8 thread_id,
-	CsrSchedBgint irq,
-	const char *callback,
-	const void *ptr);
-void CsrLogBgintUnregister(CsrSchedBgint irq);
-void CsrLogBgintSet(CsrSchedBgint irq);
-void CsrLogBgintServiceStart(CsrSchedBgint irq);
-void CsrLogBgintServiceDone(CsrSchedBgint irq);
-
-void CsrLogExceptionStateEvent(u16 prim_type,
-	CsrPrim msg_type,
-	u16 state,
-	u32 line,
-	const char *file);
-void CsrLogExceptionGeneral(u16 prim_type,
-	u16 state,
-	const char *text,
-	u32 line,
-	const char *file);
-void CsrLogExceptionWarning(u16 prim_type,
-	u16 state,
-	const char *text,
-	u32 line,
-	const char *file);
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_log_text.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_log_text.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_log_text.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_log_text.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,124 +0,0 @@
-#ifndef CSR_LOG_TEXT_H__
-#define CSR_LOG_TEXT_H__
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include "csr_log_configure.h"
-
-typedef struct CsrLogSubOrigin
-{
-    u16            subOriginNumber;  /* Id of the given SubOrigin */
-    const char *subOriginName;    /* Prefix Text for this SubOrigin */
-} CsrLogSubOrigin;
-
-/* Register a task which is going to use the CSR_LOG_TEXT_XXX interface */
-#ifdef CSR_LOG_ENABLE
-void CsrLogTextRegister(CsrLogTextTaskId taskId, const char *taskName, u16 subOriginsLength, const CsrLogSubOrigin *subOrigins);
-#else
-#define CsrLogTextRegister(taskId, taskName, subOriginsLength, subOrigins)
-#endif
-
-/* CRITICAL: Conditions that are threatening to the integrity/stability of the
-   system as a whole. */
-#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_CRITICAL_DISABLE)
-void CsrLogTextCritical(CsrLogTextTaskId taskId, u16 subOrigin, const char *formatString, ...);
-void CsrLogTextBufferCritical(CsrLogTextTaskId taskId, u16 subOrigin, size_t bufferLength, const void *buffer, const char *formatString, ...);
-#define CSR_LOG_TEXT_CRITICAL(taskId_subOrigin_formatString_varargs) CsrLogTextCritical taskId_subOrigin_formatString_varargs
-#define CSR_LOG_TEXT_CONDITIONAL_CRITICAL(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_CRITICAL(logtextargs);}}
-#define CSR_LOG_TEXT_BUFFER_CRITICAL(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferCritical taskId_subOrigin_length_buffer_formatString_varargs
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_CRITICAL(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_CRITICAL(logtextbufferargs);}}
-#else
-#define CSR_LOG_TEXT_CRITICAL(taskId_subOrigin_formatString_varargs)
-#define CSR_LOG_TEXT_CONDITIONAL_CRITICAL(condition, logtextargs)
-#define CSR_LOG_TEXT_BUFFER_CRITICAL(taskId_subOrigin_length_buffer_formatString_varargs)
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_CRITICAL(condition, logtextbufferargs)
-#endif
-
-/* ERROR: Malfunction of a component rendering it unable to operate correctly,
-   causing lack of functionality but not loss of system integrity/stability. */
-#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_ERROR_DISABLE)
-void CsrLogTextError(CsrLogTextTaskId taskId, u16 subOrigin, const char *formatString, ...);
-void CsrLogTextBufferError(CsrLogTextTaskId taskId, u16 subOrigin, size_t bufferLength, const void *buffer, const char *formatString, ...);
-#define CSR_LOG_TEXT_ERROR(taskId_subOrigin_formatString_varargs) CsrLogTextError taskId_subOrigin_formatString_varargs
-#define CSR_LOG_TEXT_CONDITIONAL_ERROR(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_ERROR(logtextargs);}}
-#define CSR_LOG_TEXT_BUFFER_ERROR(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferError taskId_subOrigin_length_buffer_formatString_varargs
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_ERROR(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_ERROR(logtextbufferargs);}}
-#else
-#define CSR_LOG_TEXT_ERROR(taskId_subOrigin_formatString_varargs)
-#define CSR_LOG_TEXT_CONDITIONAL_ERROR(condition, logtextargs)
-#define CSR_LOG_TEXT_BUFFER_ERROR(taskId_subOrigin_length_buffer_formatString_varargs)
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_ERROR(condition, logtextbufferargs)
-#endif
-
-/* WARNING: Conditions that are unexpected and indicative of possible problems
-   or violations of specifications, where the result of such deviations does not
-   lead to malfunction of the component. */
-#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_WARNING_DISABLE)
-void CsrLogTextWarning(CsrLogTextTaskId taskId, u16 subOrigin, const char *formatString, ...);
-void CsrLogTextBufferWarning(CsrLogTextTaskId taskId, u16 subOrigin, size_t bufferLength, const void *buffer, const char *formatString, ...);
-#define CSR_LOG_TEXT_WARNING(taskId_subOrigin_formatString_varargs) CsrLogTextWarning taskId_subOrigin_formatString_varargs
-#define CSR_LOG_TEXT_CONDITIONAL_WARNING(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_WARNING(logtextargs);}}
-#define CSR_LOG_TEXT_BUFFER_WARNING(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferWarning taskId_subOrigin_length_buffer_formatString_varargs
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_WARNING(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_WARNING(logtextbufferargs);}}
-#else
-#define CSR_LOG_TEXT_WARNING(taskId_subOrigin_formatString_varargs)
-#define CSR_LOG_TEXT_CONDITIONAL_WARNING(condition, logtextargs)
-#define CSR_LOG_TEXT_BUFFER_WARNING(taskId_subOrigin_length_buffer_formatString_varargs)
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_WARNING(condition, logtextbufferargs)
-#endif
-
-/* INFO: Important events that may aid in determining the conditions under which
-   the more severe conditions are encountered. */
-#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_INFO_DISABLE)
-void CsrLogTextInfo(CsrLogTextTaskId taskId, u16 subOrigin, const char *formatString, ...);
-void CsrLogTextBufferInfo(CsrLogTextTaskId taskId, u16 subOrigin, size_t bufferLength, const void *buffer, const char *formatString, ...);
-#define CSR_LOG_TEXT_INFO(taskId_subOrigin_formatString_varargs) CsrLogTextInfo taskId_subOrigin_formatString_varargs
-#define CSR_LOG_TEXT_CONDITIONAL_INFO(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_INFO(logtextargs);}}
-#define CSR_LOG_TEXT_BUFFER_INFO(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferInfo taskId_subOrigin_length_buffer_formatString_varargs
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_INFO(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_INFO(logtextbufferargs);}}
-#else
-#define CSR_LOG_TEXT_INFO(taskId_subOrigin_formatString_varargs)
-#define CSR_LOG_TEXT_CONDITIONAL_INFO(condition, logtextargs)
-#define CSR_LOG_TEXT_BUFFER_INFO(taskId_subOrigin_length_buffer_formatString_varargs)
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_INFO(condition, logtextbufferargs)
-#endif
-
-/* DEBUG: Similar to INFO, but dedicated to events that occur more frequently. */
-#if defined(CSR_LOG_ENABLE) && !defined(CSR_LOG_LEVEL_TEXT_DEBUG_DISABLE)
-void CsrLogTextDebug(CsrLogTextTaskId taskId, u16 subOrigin, const char *formatString, ...);
-void CsrLogTextBufferDebug(CsrLogTextTaskId taskId, u16 subOrigin, size_t bufferLength, const void *buffer, const char *formatString, ...);
-#define CSR_LOG_TEXT_DEBUG(taskId_subOrigin_formatString_varargs) CsrLogTextDebug taskId_subOrigin_formatString_varargs
-#define CSR_LOG_TEXT_CONDITIONAL_DEBUG(condition, logtextargs) {if (condition) {CSR_LOG_TEXT_DEBUG(logtextargs);}}
-#define CSR_LOG_TEXT_BUFFER_DEBUG(taskId_subOrigin_length_buffer_formatString_varargs) CsrLogTextBufferDebug taskId_subOrigin_length_buffer_formatString_varargs
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_DEBUG(condition, logtextbufferargs) {if (condition) {CSR_LOG_TEXT_BUFFER_DEBUG(logtextbufferargs);}}
-#else
-#define CSR_LOG_TEXT_DEBUG(taskId_subOrigin_formatString_varargs)
-#define CSR_LOG_TEXT_CONDITIONAL_DEBUG(condition, logtextargs)
-#define CSR_LOG_TEXT_BUFFER_DEBUG(taskId_subOrigin_length_buffer_formatString_varargs)
-#define CSR_LOG_TEXT_BUFFER_CONDITIONAL_DEBUG(condition, logtextbufferargs)
-#endif
-
-/* CSR_LOG_TEXT_ASSERT (CRITICAL) */
-#ifdef CSR_LOG_ENABLE
-#define CSR_LOG_TEXT_ASSERT(origin, suborigin, condition) \
-    {if (!(condition)) {CSR_LOG_TEXT_CRITICAL((origin, suborigin, "Assertion \"%s\" failed at %s:%u", #condition, __FILE__, __LINE__));}}
-#else
-#define CSR_LOG_TEXT_ASSERT(origin, suborigin, condition)
-#endif
-
-/* CSR_LOG_TEXT_UNHANDLED_PRIM (CRITICAL) */
-#ifdef CSR_LOG_ENABLE
-#define CSR_LOG_TEXT_UNHANDLED_PRIMITIVE(origin, suborigin, primClass, primType) \
-    CSR_LOG_TEXT_CRITICAL((origin, suborigin, "Unhandled primitive 0x%04X:0x%04X at %s:%u", primClass, primType, __FILE__, __LINE__))
-#else
-#define CSR_LOG_TEXT_UNHANDLED_PRIMITIVE(origin, suborigin, primClass, primType)
-#endif
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_macro.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_macro.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_macro.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_macro.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-#ifndef CSR_MACRO_H__
-#define CSR_MACRO_H__
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include <linux/types.h>
-
-#define FALSE	(0)
-#define TRUE	(1)
-
-/*------------------------------------------------------------------*/
-/* Endian conversion */
-/*------------------------------------------------------------------*/
-#define CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr)        (((u16) ((u8 *) (ptr))[0]) | ((u16) ((u8 *) (ptr))[1]) << 8)
-#define CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr)        (((u32) ((u8 *) (ptr))[0]) | ((u32) ((u8 *) (ptr))[1]) << 8 | \
-                                                       ((u32) ((u8 *) (ptr))[2]) << 16 | ((u32) ((u8 *) (ptr))[3]) << 24)
-#define CSR_COPY_UINT16_TO_LITTLE_ENDIAN(uint, ptr)    ((u8 *) (ptr))[0] = ((u8) ((uint) & 0x00FF)); \
-    ((u8 *) (ptr))[1] = ((u8) ((uint) >> 8))
-#define CSR_COPY_UINT32_TO_LITTLE_ENDIAN(uint, ptr)    ((u8 *) (ptr))[0] = ((u8) ((uint) & 0x000000FF)); \
-    ((u8 *) (ptr))[1] = ((u8) (((uint) >> 8) & 0x000000FF)); \
-    ((u8 *) (ptr))[2] = ((u8) (((uint) >> 16) & 0x000000FF)); \
-    ((u8 *) (ptr))[3] = ((u8) (((uint) >> 24) & 0x000000FF))
-
-/*------------------------------------------------------------------*/
-/* Misc */
-/*------------------------------------------------------------------*/
-/* Use this macro on unused local variables that cannot be removed (such as
-   unused function parameters). This will quell warnings from certain compilers
-   and static code analysis tools like Lint and Valgrind. */
-#define CSR_UNUSED(x) ((void) (x))
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_msgconv.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_msgconv.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_msgconv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_msgconv.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,291 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include "csr_sched.h"
-#include "csr_msgconv.h"
-#include "csr_macro.h"
-
-static CsrMsgConvEntry *converter;
-
-CsrMsgConvPrimEntry *CsrMsgConvFind(u16 primType)
-{
-    CsrMsgConvPrimEntry *ptr = NULL;
-
-    if (converter)
-    {
-        ptr = converter->profile_converters;
-        while (ptr)
-        {
-            if (ptr->primType == primType)
-            {
-                break;
-            }
-            else
-            {
-                ptr = ptr->next;
-            }
-        }
-    }
-
-    return ptr;
-}
-
-static const CsrMsgConvMsgEntry *find_msg_converter(CsrMsgConvPrimEntry *ptr, u16 msgType)
-{
-    const CsrMsgConvMsgEntry *cv = ptr->conv;
-    if (ptr->lookupFunc)
-    {
-        return (const CsrMsgConvMsgEntry *) ptr->lookupFunc((CsrMsgConvMsgEntry *) cv, msgType);
-    }
-
-    while (cv)
-    {
-        if (cv->serFunc == NULL)
-        {
-            /* We've reached the end of the chain */
-            cv = NULL;
-            break;
-        }
-
-        if (cv->msgType == msgType)
-        {
-            break;
-        }
-        else
-        {
-            cv++;
-        }
-    }
-
-    return cv;
-}
-
-static void *deserialize_data(u16 primType,
-    size_t length,
-    u8 *data)
-{
-    CsrMsgConvPrimEntry *ptr;
-    u8 *ret;
-
-    ptr = CsrMsgConvFind(primType);
-
-    if (ptr)
-    {
-        const CsrMsgConvMsgEntry *cv;
-        u16 msgId = 0;
-        size_t offset = 0;
-        CsrUint16Des(&msgId, data, &offset);
-
-        cv = find_msg_converter(ptr, msgId);
-        if (cv)
-        {
-            ret = cv->deserFunc(data, length);
-        }
-        else
-        {
-            ret = NULL;
-        }
-    }
-    else
-    {
-        ret = NULL;
-    }
-
-    return ret;
-}
-
-static size_t sizeof_message(u16 primType, void *msg)
-{
-    CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
-    size_t ret;
-
-    if (ptr)
-    {
-        const CsrMsgConvMsgEntry *cv;
-        u16 msgId = *(u16 *) msg;
-
-        cv = find_msg_converter(ptr, msgId);
-        if (cv)
-        {
-            ret = cv->sizeofFunc(msg);
-        }
-        else
-        {
-            ret = 0;
-        }
-    }
-    else
-    {
-        ret = 0;
-    }
-
-    return ret;
-}
-
-static u8 free_message(u16 primType, u8 *data)
-{
-    CsrMsgConvPrimEntry *ptr;
-    u8 ret;
-
-    ptr = CsrMsgConvFind(primType);
-
-    if (ptr)
-    {
-        const CsrMsgConvMsgEntry *cv;
-        u16 msgId = *(u16 *) data;
-
-        cv = find_msg_converter(ptr, msgId);
-        if (cv)
-        {
-            cv->freeFunc(data);
-            ret = TRUE;
-        }
-        else
-        {
-            ret = FALSE;
-        }
-    }
-    else
-    {
-        ret = FALSE;
-    }
-
-    return ret;
-}
-
-static u8 *serialize_message(u16 primType,
-    void *msg,
-    size_t *length,
-    u8 *buffer)
-{
-    CsrMsgConvPrimEntry *ptr;
-    u8 *ret;
-
-    ptr = CsrMsgConvFind(primType);
-
-    *length = 0;
-
-    if (ptr)
-    {
-        const CsrMsgConvMsgEntry *cv;
-
-        cv = find_msg_converter(ptr, *(u16 *) msg);
-        if (cv)
-        {
-            ret = cv->serFunc(buffer, length, msg);
-        }
-        else
-        {
-            ret = NULL;
-        }
-    }
-    else
-    {
-        ret = NULL;
-    }
-
-    return ret;
-}
-
-size_t CsrMsgConvSizeof(u16 primType, void *msg)
-{
-    return sizeof_message(primType, msg);
-}
-
-u8 *CsrMsgConvSerialize(u8 *buffer, size_t maxBufferOffset, size_t *offset, u16 primType, void *msg)
-{
-    if (converter)
-    {
-        size_t serializedLength;
-        u8 *bufSerialized;
-        u8 *bufOffset = &buffer[*offset];
-        bufSerialized = converter->serialize_message(primType, msg, &serializedLength, bufOffset);
-        *offset += serializedLength;
-        return bufSerialized;
-    }
-    else
-    {
-        return NULL;
-    }
-}
-
-/* Insert profile converter at head of converter list. */
-void CsrMsgConvInsert(u16 primType, const CsrMsgConvMsgEntry *ce)
-{
-    CsrMsgConvPrimEntry *pc;
-    pc = CsrMsgConvFind(primType);
-
-    if (pc)
-    {
-        /* Already registered. Do nothing */
-    }
-    else
-    {
-        pc = kmalloc(sizeof(*pc), GFP_KERNEL);
-        pc->primType = primType;
-        pc->conv = ce;
-        pc->lookupFunc = NULL;
-        pc->next = converter->profile_converters;
-        converter->profile_converters = pc;
-    }
-}
-EXPORT_SYMBOL_GPL(CsrMsgConvInsert);
-
-CsrMsgConvMsgEntry *CsrMsgConvFindEntry(u16 primType, u16 msgType)
-{
-    CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
-    if (ptr)
-    {
-        return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType);
-    }
-    return NULL;
-}
-EXPORT_SYMBOL_GPL(CsrMsgConvFindEntry);
-
-CsrMsgConvMsgEntry *CsrMsgConvFindEntryByMsg(u16 primType, const void *msg)
-{
-    CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
-    if (ptr && msg)
-    {
-        u16 msgType = *((u16 *) msg);
-        return (CsrMsgConvMsgEntry *) find_msg_converter(ptr, msgType);
-    }
-    return NULL;
-}
-
-void CsrMsgConvCustomLookupRegister(u16 primType, CsrMsgCustomLookupFunc *lookupFunc)
-{
-    CsrMsgConvPrimEntry *ptr = CsrMsgConvFind(primType);
-    if (ptr)
-    {
-        ptr->lookupFunc = lookupFunc;
-    }
-}
-EXPORT_SYMBOL_GPL(CsrMsgConvCustomLookupRegister);
-
-CsrMsgConvEntry *CsrMsgConvInit(void)
-{
-    if (!converter)
-    {
-        converter = kmalloc(sizeof(CsrMsgConvEntry), GFP_KERNEL);
-
-        converter->profile_converters = NULL;
-        converter->free_message = free_message;
-        converter->sizeof_message = sizeof_message;
-        converter->serialize_message = serialize_message;
-        converter->deserialize_data = deserialize_data;
-    }
-
-    return converter;
-}
-EXPORT_SYMBOL_GPL(CsrMsgConvInit);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_msgconv.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_msgconv.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_msgconv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_msgconv.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,78 +0,0 @@
-#ifndef CSR_MSGCONV_H__
-#define CSR_MSGCONV_H__
-
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include <linux/types.h>
-#include "csr_prim_defs.h"
-#include "csr_sched.h"
-
-typedef size_t (CsrMsgSizeofFunc)(void *msg);
-typedef u8 *(CsrMsgSerializeFunc)(u8 *buffer, size_t *length, void *msg);
-typedef void (CsrMsgFreeFunc)(void *msg);
-typedef void *(CsrMsgDeserializeFunc)(u8 *buffer, size_t length);
-
-/* Converter entry for one message type */
-typedef struct CsrMsgConvMsgEntry
-{
-    u16              msgType;
-    CsrMsgSizeofFunc      *sizeofFunc;
-    CsrMsgSerializeFunc   *serFunc;
-    CsrMsgDeserializeFunc *deserFunc;
-    CsrMsgFreeFunc        *freeFunc;
-} CsrMsgConvMsgEntry;
-
-/* Optional lookup function */
-typedef CsrMsgConvMsgEntry *(CsrMsgCustomLookupFunc)(CsrMsgConvMsgEntry *ce, u16 msgType);
-
-/* All converter entries for one specific primitive */
-typedef struct CsrMsgConvPrimEntry
-{
-    u16                   primType;
-    const CsrMsgConvMsgEntry   *conv;
-    CsrMsgCustomLookupFunc     *lookupFunc;
-    struct CsrMsgConvPrimEntry *next;
-} CsrMsgConvPrimEntry;
-
-typedef struct
-{
-    CsrMsgConvPrimEntry *profile_converters;
-    void *(*deserialize_data)(u16 primType, size_t length, u8 * data);
-    u8 (*free_message)(u16 primType, u8 *data);
-    size_t (*sizeof_message)(u16 primType, void *msg);
-    u8 *(*serialize_message)(u16 primType, void *msg,
-                                   size_t * length,
-                                   u8 * buffer);
-} CsrMsgConvEntry;
-
-size_t CsrMsgConvSizeof(u16 primType, void *msg);
-u8 *CsrMsgConvSerialize(u8 *buffer, size_t maxBufferOffset, size_t *offset, u16 primType, void *msg);
-void CsrMsgConvCustomLookupRegister(u16 primType, CsrMsgCustomLookupFunc *lookupFunc);
-void CsrMsgConvInsert(u16 primType, const CsrMsgConvMsgEntry *ce);
-CsrMsgConvPrimEntry *CsrMsgConvFind(u16 primType);
-CsrMsgConvMsgEntry *CsrMsgConvFindEntry(u16 primType, u16 msgType);
-CsrMsgConvMsgEntry *CsrMsgConvFindEntryByMsg(u16 primType, const void *msg);
-CsrMsgConvEntry *CsrMsgConvInit(void);
-
-/* Prototypes for primitive type serializers */
-void CsrUint8Ser(u8 *buffer, size_t *offset, u8 value);
-void CsrUint16Ser(u8 *buffer, size_t *offset, u16 value);
-void CsrUint32Ser(u8 *buffer, size_t *offset, u32 value);
-void CsrMemCpySer(u8 *buffer, size_t *offset, const void *value, size_t length);
-void CsrCharStringSer(u8 *buffer, size_t *offset, const char *value);
-
-void CsrUint8Des(u8 *value, u8 *buffer, size_t *offset);
-void CsrUint16Des(u16 *value, u8 *buffer, size_t *offset);
-void CsrUint32Des(u32 *value, u8 *buffer, size_t *offset);
-void CsrMemCpyDes(void *value, u8 *buffer, size_t *offset, size_t length);
-void CsrCharStringDes(char **value, u8 *buffer, size_t *offset);
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_msg_transport.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_msg_transport.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_msg_transport.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_msg_transport.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-#ifndef CSR_MSG_TRANSPORT_H__
-#define CSR_MSG_TRANSPORT_H__
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CsrMsgTransport
-#define CsrMsgTransport CsrSchedMessagePut
-#endif
-
-#endif /* CSR_MSG_TRANSPORT */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_prim_defs.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_prim_defs.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_prim_defs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_prim_defs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-#ifndef CSR_PRIM_DEFS_H__
-#define CSR_PRIM_DEFS_H__
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/************************************************************************************
- * Segmentation of primitives in upstream and downstream segment
- ************************************************************************************/
-typedef u16 CsrPrim;
-#define CSR_PRIM_UPSTREAM                   ((CsrPrim) (0x8000))
-
-/************************************************************************************
- * Primitive definitions for Synergy framework
- ************************************************************************************/
-#define CSR_SYNERGY_EVENT_CLASS_BASE        ((u16) (0x0600))
-
-#define CSR_HCI_PRIM                        ((u16) (0x0000 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_BCCMD_PRIM                      ((u16) (0x0001 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_HQ_PRIM                         ((u16) (0x0002 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_VM_PRIM                         ((u16) (0x0003 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_TM_BLUECORE_PRIM                ((u16) (0x0004 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_FP_PRIM                         ((u16) (0x0005 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_IP_SOCKET_PRIM                  ((u16) (0x0006 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_IP_ETHER_PRIM                   ((u16) (0x0007 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_IP_IFCONFIG_PRIM                ((u16) (0x0008 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_IP_INTERNAL_PRIM                ((u16) (0x0009 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_FSAL_PRIM                       ((u16) (0x000A | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_DATA_STORE_PRIM                 ((u16) (0x000B | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_AM_PRIM                         ((u16) (0x000C | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_TLS_PRIM                        ((u16) (0x000D | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_DHCP_SERVER_PRIM                ((u16) (0x000E | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_TFTP_PRIM                       ((u16) (0x000F | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_DSPM_PRIM                       ((u16) (0x0010 | CSR_SYNERGY_EVENT_CLASS_BASE))
-#define CSR_TLS_INTERNAL_PRIM               ((u16) (0x0011 | CSR_SYNERGY_EVENT_CLASS_BASE))
-
-#define NUMBER_OF_CSR_FW_EVENTS             (CSR_DSPM_PRIM - CSR_SYNERGY_EVENT_CLASS_BASE + 1)
-
-#define CSR_SYNERGY_EVENT_CLASS_MISC_BASE   ((u16) (0x06A0))
-
-#define CSR_UI_PRIM                         ((u16) (0x0000 | CSR_SYNERGY_EVENT_CLASS_MISC_BASE))
-#define CSR_APP_PRIM                        ((u16) (0x0001 | CSR_SYNERGY_EVENT_CLASS_MISC_BASE))
-#define CSR_SDIO_PROBE_PRIM                 ((u16) (0x0002 | CSR_SYNERGY_EVENT_CLASS_MISC_BASE))
-
-#define NUMBER_OF_CSR_FW_MISC_EVENTS        (CSR_SDIO_PROBE_PRIM - CSR_SYNERGY_EVENT_CLASS_MISC_BASE + 1)
-
-#define CSR_ENV_PRIM                        ((u16) (0x00FF | CSR_SYNERGY_EVENT_CLASS_MISC_BASE))
-
-#endif /* CSR_PRIM_DEFS_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_result.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_result.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_result.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_result.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-#ifndef CSR_RESULT_H__
-#define CSR_RESULT_H__
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-typedef u16 CsrResult;
-#define CSR_RESULT_SUCCESS  ((CsrResult) 0x0000)
-#define CSR_RESULT_FAILURE  ((CsrResult) 0xFFFF)
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_sched.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_sched.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_sched.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_sched.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-#ifndef CSR_SCHED_H__
-#define CSR_SCHED_H__
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-#include <linux/types.h>
-#include "csr_time.h"
-
-/* An identifier issued by the scheduler. */
-typedef u32 CsrSchedIdentifier;
-
-/* A task identifier */
-typedef u16 CsrSchedTaskId;
-
-/* A queue identifier */
-typedef u16 CsrSchedQid;
-
-/* A message identifier */
-typedef CsrSchedIdentifier CsrSchedMsgId;
-
-/* A timer event identifier */
-typedef CsrSchedIdentifier CsrSchedTid;
-#define CSR_SCHED_TID_INVALID     ((CsrSchedTid) 0)
-
-/* Time constants. */
-#define CSR_SCHED_TIME_MAX                (0xFFFFFFFF)
-#define CSR_SCHED_MILLISECOND             (1000)
-#define CSR_SCHED_SECOND                  (1000 * CSR_SCHED_MILLISECOND)
-#define CSR_SCHED_MINUTE                  (60 * CSR_SCHED_SECOND)
-
-/* Queue and primitive that identifies the environment */
-#define CSR_SCHED_TASK_ID        0xFFFF
-#define CSR_SCHED_PRIM                   (CSR_SCHED_TASK_ID)
-#define CSR_SCHED_EXCLUDED_MODULE_QUEUE      0xFFFF
-
-/*
- * Background interrupt definitions
- */
-typedef u16 CsrSchedBgint;
-#define CSR_SCHED_BGINT_INVALID ((CsrSchedBgint) 0xFFFF)
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSchedMessagePut
- *
- *  DESCRIPTION
- *      Sends a message consisting of the integer "mi" and the void * pointer
- *      "mv" to the message queue "q".
- *
- *      "mi" and "mv" are neither inspected nor changed by the scheduler - the
- *      task that owns "q" is expected to make sense of the values. "mv" may
- *      be null.
- *
- *  NOTE
- *      If "mv" is not null then it will typically be a chunk of kmalloc()ed
- *      memory, though there is no need for it to be so. Tasks should normally
- *      obey the convention that when a message built with kmalloc()ed memory
- *      is given to CsrSchedMessagePut() then ownership of the memory is ceded to the
- *      scheduler - and eventually to the recipient task. I.e., the receiver of
- *      the message will be expected to kfree() the message storage.
- *
- *  RETURNS
- *      void.
- *
- *----------------------------------------------------------------------------*/
-#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER)
-void CsrSchedMessagePutStringLog(CsrSchedQid q,
-    u16 mi,
-    void *mv,
-    u32 line,
-    const char *file);
-#define CsrSchedMessagePut(q, mi, mv) CsrSchedMessagePutStringLog((q), (mi), (mv), __LINE__, __FILE__)
-#else
-void CsrSchedMessagePut(CsrSchedQid q,
-    u16 mi,
-    void *mv);
-#endif
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_sdio.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_sdio.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_sdio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_sdio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,723 +0,0 @@
-#ifndef CSR_SDIO_H__
-#define CSR_SDIO_H__
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include "csr_result.h"
-
-/* Result Codes */
-#define CSR_SDIO_RESULT_INVALID_VALUE   ((CsrResult) 1) /* Invalid argument value */
-#define CSR_SDIO_RESULT_NO_DEVICE       ((CsrResult) 2) /* The specified device is no longer present */
-#define CSR_SDIO_RESULT_CRC_ERROR       ((CsrResult) 3) /* The transmitted/received data or command response contained a CRC error */
-#define CSR_SDIO_RESULT_TIMEOUT         ((CsrResult) 4) /* No command response or data received from device, or function enable/disable did not succeed within timeout period */
-#define CSR_SDIO_RESULT_NOT_RESET       ((CsrResult) 5) /* The device was not reset */
-
-/* Features (for use in features member of CsrSdioFunction) */
-#define CSR_SDIO_FEATURE_BYTE_MODE                   0x00000001 /* Transfer sizes do not have to be a multiple of block size */
-#define CSR_SDIO_FEATURE_DMA_CAPABLE_MEM_REQUIRED    0x00000002 /* Bulk operations require DMA friendly memory */
-
-/* CsrSdioFunctionId wildcards (for use in CsrSdioFunctionId members) */
-#define CSR_SDIO_ANY_MANF_ID        0xFFFF
-#define CSR_SDIO_ANY_CARD_ID        0xFFFF
-#define CSR_SDIO_ANY_SDIO_FUNCTION  0xFF
-#define CSR_SDIO_ANY_SDIO_INTERFACE 0xFF
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioFunctionId
- *
- *  DESCRIPTION
- *      This structure describes one or more functions of a device, based on
- *      four qualitative measures. The CsrSdioFunctionId wildcard defines can be
- *      used for making the CsrSdioFunctionId match more than one function.
- *
- *  MEMBERS
- *      manfId - Vendor ID (or CSR_SDIO_ANY_MANF_ID).
- *      cardId - Device ID (or CSR_SDIO_ANY_CARD_ID).
- *      sdioFunction - SDIO Function number (or CSR_SDIO_ANY_SDIO_FUNCTION).
- *      sdioInterface - SDIO Standard Interface Code (or CSR_SDIO_ANY_SDIO_INTERFACE)
- *
- *----------------------------------------------------------------------------*/
-typedef struct
-{
-    u16 manfId;       /* Vendor ID to match or CSR_SDIO_ANY_MANF_ID */
-    u16 cardId;       /* Device ID to match or CSR_SDIO_ANY_CARD_ID */
-    u8  sdioFunction; /* SDIO Function number to match or CSR_SDIO_ANY_SDIO_FUNCTION */
-    u8  sdioInterface; /* SDIO Standard Interface Code to match or CSR_SDIO_ANY_SDIO_INTERFACE */
-} CsrSdioFunctionId;
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioFunction
- *
- *  DESCRIPTION
- *      This structure represents a single function on a device.
- *
- *  MEMBERS
- *      sdioId - A CsrSdioFunctionId describing this particular function. The
- *               subfield shall not contain any CsrSdioFunctionId wildcards. The
- *               subfields shall describe the specific single function
- *               represented by this structure.
- *      blockSize - Actual configured block size, or 0 if unconfigured.
- *      features - Bit mask with any of CSR_SDIO_FEATURE_* set.
- *      device - Handle of device containing the function. If two functions have
- *               the same device handle, they reside on the same device.
- *      driverData - For use by the Function Driver. The SDIO Driver shall not
- *                   attempt to dereference the pointer.
- *      priv - For use by the SDIO Driver. The Function Driver shall not attempt
- *             to dereference the pointer.
- *
- *
- *----------------------------------------------------------------------------*/
-typedef struct
-{
-    CsrSdioFunctionId sdioId;
-    u16         blockSize; /* Actual configured block size, or 0 if unconfigured */
-    u32         features; /* Bit mask with any of CSR_SDIO_FEATURE_* set */
-    void             *device; /* Handle of device containing the function */
-    void             *driverData; /* For use by the Function Driver */
-    void             *priv; /* For use by the SDIO Driver */
-} CsrSdioFunction;
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioInsertedCallback, CsrSdioRemovedCallback
- *
- *  DESCRIPTION
- *      CsrSdioInsertedCallback is called when a function becomes available to
- *      a registered Function Driver that supports the function.
- *      CsrSdioRemovedCallback is called when a function is no longer available
- *      to a Function Driver, either because the device has been removed, or the
- *      Function Driver has been unregistered.
- *
- *      NOTE: These functions are implemented by the Function Driver, and are
- *            passed as function pointers in the CsrSdioFunctionDriver struct.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *
- *----------------------------------------------------------------------------*/
-typedef void (*CsrSdioInsertedCallback)(CsrSdioFunction *function);
-typedef void (*CsrSdioRemovedCallback)(CsrSdioFunction *function);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioInterruptDsrCallback, CsrSdioInterruptCallback
- *
- *  DESCRIPTION
- *      CsrSdioInterruptCallback is called when an interrupt occurs on the
- *      the device associated with the specified function.
- *
- *      NOTE: These functions are implemented by the Function Driver, and are
- *            passed as function pointers in the CsrSdioFunctionDriver struct.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *
- *  RETURNS (only CsrSdioInterruptCallback)
- *      A pointer to a CsrSdioInterruptDsrCallback function.
- *
- *----------------------------------------------------------------------------*/
-typedef void (*CsrSdioInterruptDsrCallback)(CsrSdioFunction *function);
-typedef CsrSdioInterruptDsrCallback (*CsrSdioInterruptCallback)(CsrSdioFunction *function);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioSuspendCallback, CsrSdioResumeCallback
- *
- *  DESCRIPTION
- *      CsrSdioSuspendCallback is called when the system is preparing to go
- *      into a suspended state. CsrSdioResumeCallback is called when the system
- *      has entered an active state again.
- *
- *      NOTE: These functions are implemented by the Function Driver, and are
- *            passed as function pointers in the CsrSdioFunctionDriver struct.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *
- *----------------------------------------------------------------------------*/
-typedef void (*CsrSdioSuspendCallback)(CsrSdioFunction *function);
-typedef void (*CsrSdioResumeCallback)(CsrSdioFunction *function);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioAsyncCallback, CsrSdioAsyncDsrCallback
- *
- *  DESCRIPTION
- *      CsrSdioAsyncCallback is called when an asynchronous operation completes.
- *
- *      NOTE: These functions are implemented by the Function Driver, and are
- *            passed as function pointers in the function calls that initiate
- *            the operation.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *      result - The result of the operation that completed. See the description
- *               of the initiating function for possible result values.
- *
- *  RETURNS (only CsrSdioAsyncCallback)
- *      A pointer to a CsrSdioAsyncDsrCallback function.
- *
- *----------------------------------------------------------------------------*/
-typedef void (*CsrSdioAsyncDsrCallback)(CsrSdioFunction *function, CsrResult result);
-typedef CsrSdioAsyncDsrCallback (*CsrSdioAsyncCallback)(CsrSdioFunction *function, CsrResult result);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioFunctionDriver
- *
- *  DESCRIPTION
- *      Structure representing a Function Driver.
- *
- *  MEMBERS
- *      inserted - Callback, see description of CsrSdioInsertedCallback.
- *      removed - Callback, see description of CsrSdioRemovedCallback.
- *      intr - Callback, see description of CsrSdioInterruptCallback.
- *      suspend - Callback, see description of CsrSdioSuspendCallback.
- *      resume - Callback, see description of CsrSdioResumeCallback.
- *      ids - Array of CsrSdioFunctionId describing one or more functions that
- *            are supported by the Function Driver.
- *      idsCount - Length of the ids array.
- *      priv - For use by the SDIO Driver. The Function Driver may initialise
- *             it to NULL, but shall otherwise not access the pointer or attempt
- *             to dereference it.
- *
- *----------------------------------------------------------------------------*/
-typedef struct
-{
-    CsrSdioInsertedCallback  inserted;
-    CsrSdioRemovedCallback   removed;
-    CsrSdioInterruptCallback intr;
-    CsrSdioSuspendCallback   suspend;
-    CsrSdioResumeCallback    resume;
-    CsrSdioFunctionId       *ids;
-    u8                 idsCount;
-    void                    *priv;          /* For use by the SDIO Driver */
-} CsrSdioFunctionDriver;
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioFunctionDriverRegister
- *
- *  DESCRIPTION
- *      Register a Function Driver.
- *
- *  PARAMETERS
- *      functionDriver - Pointer to struct describing the Function Driver.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - The Function Driver was successfully
- *                           registered.
- *      CSR_RESULT_FAILURE - Unable to register the function driver,
- *                                because of an unspecified/unknown error. The
- *                                Function Driver has not been registered.
- *      CSR_SDIO_RESULT_INVALID_VALUE - The specified Function Driver pointer
- *                                      does not point at a valid Function
- *                                      Driver structure, or some of the members
- *                                      contain invalid entries.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *functionDriver);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioFunctionDriverUnregister
- *
- *  DESCRIPTION
- *      Unregister a previously registered Function Driver.
- *
- *  PARAMETERS
- *      functionDriver - pointer to struct describing the Function Driver.
- *
- *----------------------------------------------------------------------------*/
-void CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *functionDriver);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioFunctionEnable, CsrSdioFunctionDisable
- *
- *  DESCRIPTION
- *      Enable/disable the specified function by setting/clearing the
- *      corresponding bit in the I/O Enable register in function 0, and then
- *      periodically reading the related bit in the I/O Ready register until it
- *      is set/clear, limited by an implementation defined timeout.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - The specified function was enabled/disabled.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *      CSR_SDIO_RESULT_CRC_ERROR - A CRC error occurred. The state of the
- *                                  related bit in the I/O Enable register is
- *                                  undefined.
- *      CSR_SDIO_RESULT_TIMEOUT - No response from the device, or the related
- *                                bit in the I/O ready register was not
- *                                set/cleared within the timeout period.
- *
- *      NOTE: If the SDIO R5 response is available, and either of the
- *            FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
- *            is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
- *            CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
- *            COM_CRC_ERROR bits shall be ignored.
- *
- *            If the CSPI response is available, and any of the
- *            FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE will be returned.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioFunctionEnable(CsrSdioFunction *function);
-CsrResult CsrSdioFunctionDisable(CsrSdioFunction *function);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioInterruptEnable, CsrSdioInterruptDisable
- *
- *  DESCRIPTION
- *      Enable/disable the interrupt for the specified function by
- *      setting/clearing the corresponding bit in the INT Enable register in
- *      function 0.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - The specified function was enabled/disabled.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *      CSR_SDIO_RESULT_CRC_ERROR - A CRC error occurred. The state of the
- *                                  related bit in the INT Enable register is
- *                                  unchanged.
- *      CSR_SDIO_RESULT_INVALID_VALUE - The specified function cannot be
- *                                      enabled/disabled, because it either
- *                                      does not exist or it is not possible to
- *                                      individually enable/disable functions.
- *      CSR_SDIO_RESULT_TIMEOUT - No response from the device.
- *
- *      NOTE: If the SDIO R5 response is available, and either of the
- *            FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
- *            is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
- *            CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
- *            COM_CRC_ERROR bits shall be ignored.
- *
- *            If the CSPI response is available, and any of the
- *            FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE will be returned.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioInterruptEnable(CsrSdioFunction *function);
-CsrResult CsrSdioInterruptDisable(CsrSdioFunction *function);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioInterruptAcknowledge
- *
- *  DESCRIPTION
- *      Acknowledge that a signalled interrupt has been handled. Shall only
- *      be called once, and exactly once for each signalled interrupt to the
- *      corresponding function.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function to which the
- *                 event was signalled.
- *
- *----------------------------------------------------------------------------*/
-void CsrSdioInterruptAcknowledge(CsrSdioFunction *function);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioInsertedAcknowledge, CsrSdioRemovedAcknowledge
- *
- *  DESCRIPTION
- *      Acknowledge that a signalled inserted/removed event has been handled.
- *      Shall only be called once, and exactly once for each signalled event to
- *      the corresponding function.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function to which the
- *                 inserted was signalled.
- *      result (CsrSdioInsertedAcknowledge only)
- *          CSR_RESULT_SUCCESS - The Function Driver has accepted the
- *                                    function, and the function is attached to
- *                                    the Function Driver until the
- *                                    CsrSdioRemovedCallback is called and
- *                                    acknowledged.
- *          CSR_RESULT_FAILURE - Unable to accept the function. The
- *                                    function is not attached to the Function
- *                                    Driver, and it may be passed to another
- *                                    Function Driver which supports the
- *                                    function.
- *
- *----------------------------------------------------------------------------*/
-void CsrSdioInsertedAcknowledge(CsrSdioFunction *function, CsrResult result);
-void CsrSdioRemovedAcknowledge(CsrSdioFunction *function);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioSuspendAcknowledge, CsrSdioResumeAcknowledge
- *
- *  DESCRIPTION
- *      Acknowledge that a signalled suspend event has been handled. Shall only
- *      be called once, and exactly once for each signalled event to the
- *      corresponding function.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function to which the
- *                 event was signalled.
- *      result
- *          CSR_RESULT_SUCCESS - Successfully suspended/resumed.
- *          CSR_RESULT_FAILURE - Unspecified/unknown error.
- *
- *----------------------------------------------------------------------------*/
-void CsrSdioSuspendAcknowledge(CsrSdioFunction *function, CsrResult result);
-void CsrSdioResumeAcknowledge(CsrSdioFunction *function, CsrResult result);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioBlockSizeSet
- *
- *  DESCRIPTION
- *      Set the block size to use for the function. The actual configured block
- *      size shall be the minimum of:
- *          1) Maximum block size supported by the function.
- *          2) Maximum block size supported by the host controller.
- *          3) The block size specified by the blockSize argument.
- *
- *      When this function returns, the actual configured block size is
- *      available in the blockSize member of the function struct.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *      blockSize - Block size to use for the function. Valid range is 1 to
- *                  2048.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - The block size register on the chip
- *                                was updated.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *      CSR_SDIO_RESULT_CRC_ERROR - A CRC error occurred. The configured block
- *                                  size is undefined.
- *      CSR_SDIO_RESULT_TIMEOUT - No response from the device.
- *
- *      NOTE: If the SDIO R5 response is available, and the FUNCTION_NUMBER
- *            bits is set, CSR_SDIO_RESULT_INVALID_VALUE shall be returned.
- *            If the ERROR bit is set (but not FUNCTION_NUMBER),
- *            CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
- *            COM_CRC_ERROR bits shall be ignored.
- *
- *            If the CSPI response is available, and any of the
- *            FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE will be returned.
- *
- *      NOTE: Setting the block size requires two individual operations. The
- *            implementation shall ignore the OUT_OF_RANGE bit of the SDIO R5
- *            response for the first operation, as the partially configured
- *            block size may be out of range, even if the final block size
- *            (after the second operation) is in the valid range.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioBlockSizeSet(CsrSdioFunction *function, u16 blockSize);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioMaxBusClockFrequencySet
- *
- *  DESCRIPTION
- *      Set the maximum clock frequency to use for the device associated with
- *      the specified function. The actual configured clock frequency for the
- *      device shall be the minimum of:
- *          1) Maximum clock frequency supported by the device.
- *          2) Maximum clock frequency supported by the host controller.
- *          3) Maximum clock frequency specified for any function on the same
- *             device.
- *
- *      If the clock frequency exceeds 25MHz, it is the responsibility of the
- *      SDIO driver to enable high speed mode on the device, using the standard
- *      defined procedure, before increasing the frequency beyond the limit.
- *
- *      Note that the clock frequency configured affects all functions on the
- *      same device.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *      maxFrequency - The maximum clock frequency for the function in Hertz.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - The maximum clock frequency was successfully
- *                                set for the function.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *
- *      NOTE: If the SDIO R5 response is available, and the FUNCTION_NUMBER
- *            bits is set, CSR_SDIO_RESULT_INVALID_VALUE shall be returned.
- *            If the ERROR bit is set (but not FUNCTION_NUMBER),
- *            CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
- *            COM_CRC_ERROR bits shall be ignored.
- *
- *            If the CSPI response is available, and any of the
- *            FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE will be returned.
- *
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, u32 maxFrequency);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioRead8, CsrSdioWrite8, CsrSdioRead8Async, CsrSdioWrite8Async
- *
- *  DESCRIPTION
- *      Read/write an 8bit value from/to the specified register address.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *      address - Register address within the function.
- *      data - The data to read/write.
- *      callback - The function to call on operation completion.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - The data was successfully read/written.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *      CSR_SDIO_RESULT_CRC_ERROR - A CRC error occurred. No data read/written.
- *      CSR_SDIO_RESULT_TIMEOUT - No response from the device.
- *
- *      NOTE: If the SDIO R5 response is available, and either of the
- *            FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
- *            is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
- *            CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
- *            COM_CRC_ERROR bits shall be ignored.
- *
- *            If the CSPI response is available, and any of the
- *            FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE will be returned.
- *
- *      NOTE: The CsrSdioRead8Async and CsrSdioWrite8Async functions return
- *            immediately, and the supplied callback function is called when the
- *            operation is complete. The result value is given as an argument to
- *            the callback function.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioRead8(CsrSdioFunction *function, u32 address, u8 *data);
-CsrResult CsrSdioWrite8(CsrSdioFunction *function, u32 address, u8 data);
-void CsrSdioRead8Async(CsrSdioFunction *function, u32 address, u8 *data, CsrSdioAsyncCallback callback);
-void CsrSdioWrite8Async(CsrSdioFunction *function, u32 address, u8 data, CsrSdioAsyncCallback callback);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioRead16, CsrSdioWrite16, CsrSdioRead16Async, CsrSdioWrite16Async
- *
- *  DESCRIPTION
- *      Read/write a 16bit value from/to the specified register address.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *      address - Register address within the function.
- *      data - The data to read/write.
- *      callback - The function to call on operation completion.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - The data was successfully read/written.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *      CSR_SDIO_RESULT_CRC_ERROR - A CRC error occurred. Data may have been
- *                                  partially read/written.
- *      CSR_SDIO_RESULT_TIMEOUT - No response from the device.
- *
- *      NOTE: If the SDIO R5 response is available, and either of the
- *            FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
- *            is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
- *            CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
- *            COM_CRC_ERROR bits shall be ignored.
- *
- *            If the CSPI response is available, and any of the
- *            FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE will be returned.
- *
- *      NOTE: The CsrSdioRead16Async and CsrSdioWrite16Async functions return
- *            immediately, and the supplied callback function is called when the
- *            operation is complete. The result value is given as an argument to
- *            the callback function.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioRead16(CsrSdioFunction *function, u32 address, u16 *data);
-CsrResult CsrSdioWrite16(CsrSdioFunction *function, u32 address, u16 data);
-void CsrSdioRead16Async(CsrSdioFunction *function, u32 address, u16 *data, CsrSdioAsyncCallback callback);
-void CsrSdioWrite16Async(CsrSdioFunction *function, u32 address, u16 data, CsrSdioAsyncCallback callback);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioF0Read8, CsrSdioF0Write8, CsrSdioF0Read8Async,
- *      CsrSdioF0Write8Async
- *
- *  DESCRIPTION
- *      Read/write an 8bit value from/to the specified register address in
- *      function 0.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *      address - Register address within the function.
- *      data - The data to read/write.
- *      callback - The function to call on operation completion.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - The data was successfully read/written.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *      CSR_SDIO_RESULT_CRC_ERROR - A CRC error occurred. No data read/written.
- *      CSR_SDIO_RESULT_TIMEOUT - No response from the device.
- *
- *      NOTE: If the SDIO R5 response is available, and either of the
- *            FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
- *            is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
- *            CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
- *            COM_CRC_ERROR bits shall be ignored.
- *
- *            If the CSPI response is available, and any of the
- *            FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE will be returned.
- *
- *      NOTE: The CsrSdioF0Read8Async and CsrSdioF0Write8Async functions return
- *            immediately, and the supplied callback function is called when the
- *            operation is complete. The result value is given as an argument to
- *            the callback function.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioF0Read8(CsrSdioFunction *function, u32 address, u8 *data);
-CsrResult CsrSdioF0Write8(CsrSdioFunction *function, u32 address, u8 data);
-void CsrSdioF0Read8Async(CsrSdioFunction *function, u32 address, u8 *data, CsrSdioAsyncCallback callback);
-void CsrSdioF0Write8Async(CsrSdioFunction *function, u32 address, u8 data, CsrSdioAsyncCallback callback);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioRead, CsrSdioWrite, CsrSdioReadAsync, CsrSdioWriteAsync
- *
- *  DESCRIPTION
- *      Read/write a specified number of bytes from/to the specified register
- *      address.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *      address - Register address within the function.
- *      data - The data to read/write.
- *      length - Number of byte to read/write.
- *      callback - The function to call on operation completion.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - The data was successfully read/written.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_INVALID_VALUE - One or more arguments were invalid.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *      CSR_SDIO_RESULT_CRC_ERROR - A CRC error occurred. Data may have been
- *                                  partially read/written.
- *      CSR_SDIO_RESULT_TIMEOUT - No response from the device.
- *
- *      NOTE: If the SDIO R5 response is available, and either of the
- *            FUNCTION_NUMBER or OUT_OF_RANGE bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE shall be returned. If the ERROR bit
- *            is set (but none of FUNCTION_NUMBER or OUT_OF_RANGE),
- *            CSR_RESULT_FAILURE shall be returned. The ILLEGAL_COMMAND and
- *            COM_CRC_ERROR bits shall be ignored.
- *
- *            If the CSPI response is available, and any of the
- *            FUNCTION_DISABLED or CLOCK_DISABLED bits are set,
- *            CSR_SDIO_RESULT_INVALID_VALUE will be returned.
- *
- *      NOTE: The CsrSdioF0Read8Async and CsrSdioF0Write8Async functions return
- *            immediately, and the supplied callback function is called when the
- *            operation is complete. The result value is given as an argument to
- *            the callback function.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioRead(CsrSdioFunction *function, u32 address, void *data, u32 length);
-CsrResult CsrSdioWrite(CsrSdioFunction *function, u32 address, const void *data, u32 length);
-void CsrSdioReadAsync(CsrSdioFunction *function, u32 address, void *data, u32 length, CsrSdioAsyncCallback callback);
-void CsrSdioWriteAsync(CsrSdioFunction *function, u32 address, const void *data, u32 length, CsrSdioAsyncCallback callback);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioPowerOn, CsrSdioPowerOff
- *
- *  DESCRIPTION
- *      Power on/off the device.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function that resides on
- *                 the device to power on/off.
- *
- *  RETURNS (only CsrSdioPowerOn)
- *      CSR_RESULT_SUCCESS - Power was successfully reapplied and the device
- *                                has been reinitialised.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *      CSR_SDIO_RESULT_CRC_ERROR - A CRC error occurred during reinitialisation.
- *      CSR_SDIO_RESULT_TIMEOUT - No response from the device during
- *                                reinitialisation.
- *      CSR_SDIO_RESULT_NOT_RESET - The power was not removed by the
- *                                  CsrSdioPowerOff call. The state of the
- *                                  device is unchanged.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioPowerOn(CsrSdioFunction *function);
-void CsrSdioPowerOff(CsrSdioFunction *function);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioHardReset
- *
- *  DESCRIPTION
- *      Perform a hardware reset of the device.
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function that resides on
- *                 the device to hard reset.
- *
- *  RETURNS
- *      CSR_RESULT_SUCCESS - Reset was successfully performed and the device
- *                                has been reinitialised.
- *      CSR_RESULT_FAILURE - Unspecified/unknown error.
- *      CSR_SDIO_RESULT_NO_DEVICE - The device does not exist anymore.
- *      CSR_SDIO_RESULT_CRC_ERROR - A CRC error occurred during reinitialisation.
- *      CSR_SDIO_RESULT_TIMEOUT - No response from the device during
- *                                reinitialisation.
- *      CSR_SDIO_RESULT_NOT_RESET - The reset was not applied because it is not
- *                                  supported. The state of the device is
- *                                  unchanged.
- *
- *----------------------------------------------------------------------------*/
-CsrResult CsrSdioHardReset(CsrSdioFunction *function);
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrSdioFunctionActive, CsrSdioFunctionIdle
- *
- *  DESCRIPTION
- *
- *  PARAMETERS
- *      function - Pointer to struct representing the function.
- *
- *----------------------------------------------------------------------------*/
-void CsrSdioFunctionActive(CsrSdioFunction *function);
-void CsrSdioFunctionIdle(CsrSdioFunction *function);
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_serialize_primitive_types.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_serialize_primitive_types.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_serialize_primitive_types.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_serialize_primitive_types.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,100 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include "csr_prim_defs.h"
-#include "csr_msgconv.h"
-#include "csr_macro.h"
-
-void CsrUint8Des(u8 *value, u8 *buffer, size_t *offset)
-{
-    *value = buffer[*offset];
-    *offset += sizeof(*value);
-}
-EXPORT_SYMBOL_GPL(CsrUint8Des);
-
-void CsrUint16Des(u16 *value, u8 *buffer, size_t *offset)
-{
-    *value = (buffer[*offset + 0] << 0) |
-             (buffer[*offset + 1] << 8);
-    *offset += sizeof(*value);
-}
-EXPORT_SYMBOL_GPL(CsrUint16Des);
-
-void CsrUint32Des(u32 *value, u8 *buffer, size_t *offset)
-{
-    *value = (buffer[*offset + 0] << 0) |
-             (buffer[*offset + 1] << 8) |
-             (buffer[*offset + 2] << 16) |
-             (buffer[*offset + 3] << 24);
-    *offset += sizeof(*value);
-}
-EXPORT_SYMBOL_GPL(CsrUint32Des);
-
-void CsrMemCpyDes(void *value, u8 *buffer, size_t *offset, size_t length)
-{
-    memcpy(value, &buffer[*offset], length);
-    *offset += length;
-}
-EXPORT_SYMBOL_GPL(CsrMemCpyDes);
-
-void CsrCharStringDes(char **value, u8 *buffer, size_t *offset)
-{
-    *value = kstrdup((char *) &buffer[*offset], GFP_KERNEL);
-    *offset += strlen(*value) + 1;
-}
-EXPORT_SYMBOL_GPL(CsrCharStringDes);
-
-void CsrUint8Ser(u8 *buffer, size_t *offset, u8 value)
-{
-    buffer[*offset] = value;
-    *offset += sizeof(value);
-}
-EXPORT_SYMBOL_GPL(CsrUint8Ser);
-
-void CsrUint16Ser(u8 *buffer, size_t *offset, u16 value)
-{
-    buffer[*offset + 0] = (u8) ((value >> 0) & 0xFF);
-    buffer[*offset + 1] = (u8) ((value >> 8) & 0xFF);
-    *offset += sizeof(value);
-}
-EXPORT_SYMBOL_GPL(CsrUint16Ser);
-
-void CsrUint32Ser(u8 *buffer, size_t *offset, u32 value)
-{
-    buffer[*offset + 0] = (u8) ((value >> 0) & 0xFF);
-    buffer[*offset + 1] = (u8) ((value >> 8) & 0xFF);
-    buffer[*offset + 2] = (u8) ((value >> 16) & 0xFF);
-    buffer[*offset + 3] = (u8) ((value >> 24) & 0xFF);
-    *offset += sizeof(value);
-}
-EXPORT_SYMBOL_GPL(CsrUint32Ser);
-
-void CsrMemCpySer(u8 *buffer, size_t *offset, const void *value, size_t length)
-{
-    memcpy(&buffer[*offset], value, length);
-    *offset += length;
-}
-EXPORT_SYMBOL_GPL(CsrMemCpySer);
-
-void CsrCharStringSer(u8 *buffer, size_t *offset, const char *value)
-{
-    if (value)
-    {
-        strcpy(((char *) &buffer[*offset]), value);
-        *offset += strlen(value) + 1;
-    }
-    else
-    {
-        CsrUint8Ser(buffer, offset, 0);
-    }
-}
-EXPORT_SYMBOL_GPL(CsrCharStringSer);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_time.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_time.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_time.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_time.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/*****************************************************************************
-
-	(c) Cambridge Silicon Radio Limited 2010
-	All rights reserved and confidential information of CSR
-
-	Refer to LICENSE.txt included with this source for details
-	on the license terms.
-
-*****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/module.h>
-
-#include "csr_time.h"
-
-u32 CsrTimeGet(u32 *high)
-{
-	struct timespec ts;
-	u64 time;
-	u32 low;
-
-	ts = current_kernel_time();
-	time = (u64) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
-
-	if (high != NULL)
-		*high = (u32) ((time >> 32) & 0xFFFFFFFF);
-
-	low = (u32) (time & 0xFFFFFFFF);
-
-	return low;
-}
-EXPORT_SYMBOL_GPL(CsrTimeGet);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_time.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_time.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_time.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_time.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,76 +0,0 @@
-#ifndef CSR_TIME_H__
-#define CSR_TIME_H__
-/*****************************************************************************
-
-(c) Cambridge Silicon Radio Limited 2010
-All rights reserved and confidential information of CSR
-
-Refer to LICENSE.txt included with this source for details
-on the license terms.
-
-*****************************************************************************/
-
-#include <linux/types.h>
-
-/*******************************************************************************
-
-NAME
-	CsrTimeGet
-
-DESCRIPTION
-	Returns the current system time in a low and a high part. The low part
-	is expressed in microseconds. The high part is incremented when the low
-	part wraps to provide an extended range.
-
-	The caller may provide a NULL pointer as the high parameter.
-	In this case the function just returns the low part and ignores the
-	high parameter.
-
-	Although the time is expressed in microseconds the actual resolution is
-	platform dependent and can be less. It is recommended that the
-	resolution is at least 10 milliseconds.
-
-PARAMETERS
-	high - Pointer to variable that will receive the high part of the
-	       current system time. Passing NULL is valid.
-
-RETURNS
-	Low part of current system time in microseconds.
-
-*******************************************************************************/
-u32 CsrTimeGet(u32 *high);
-
-
-/*------------------------------------------------------------------*/
-/* CsrTime Macros */
-/*------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrTimeAdd
- *
- *  DESCRIPTION
- *      Add two time values. Adding the numbers can overflow the range of a
- *      CsrTime, so the user must be cautious.
- *
- *  RETURNS
- *      CsrTime - the sum of "t1" and "t2".
- *
- *----------------------------------------------------------------------------*/
-#define CsrTimeAdd(t1, t2) ((t1) + (t2))
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrTimeSub
- *
- *  DESCRIPTION
- *      Subtract two time values. Subtracting the numbers can provoke an
- *      underflow, so the user must be cautious.
- *
- *  RETURNS
- *      CsrTime - "t1" - "t2".
- *
- *----------------------------------------------------------------------------*/
-#define CsrTimeSub(t1, t2)    ((s32) (t1) - (s32) (t2))
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_util.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_util.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_util.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_util.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,15 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2010
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include <linux/module.h>
-
-MODULE_DESCRIPTION("CSR Operating System Kernel Abstraction");
-MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
-MODULE_LICENSE("GPL and additional rights");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_common.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_common.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_common.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,101 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_COMMON_H__
-#define CSR_WIFI_COMMON_H__
-
-#include <linux/types.h>
-#include "csr_result.h"
-
-/* MAC address */
-typedef struct
-{
-    u8 a[6];
-} CsrWifiMacAddress;
-
-/* IPv4 address */
-typedef struct
-{
-    u8 a[4];
-} CsrWifiIp4Address;
-
-/* IPv6 address */
-typedef struct
-{
-    u8 a[16];
-} CsrWifiIp6Address;
-
-typedef struct
-{
-    u8 ssid[32];
-    u8 length;
-} CsrWifiSsid;
-
-/*******************************************************************************
-
-  DESCRIPTION
-    Result values used on the Wifi Interfaces
-
- VALUES
-    CSR_RESULT_SUCCESS
-                   - The request/procedure succeeded
-    CSR_RESULT_FAILURE
-                   - The request/procedure did not succeed because of an error
-    CSR_WIFI_RESULT_NOT_FOUND
-                   - The request did not succeed because some resource was not
-                     found.
-    CSR_WIFI_RESULT_TIMED_OUT
-                   - The request/procedure did not succeed because of a time out
-    CSR_WIFI_RESULT_CANCELLED
-                   - The request was canceled due to another conflicting
-                     request that was issued before this one was completed
-    CSR_WIFI_RESULT_INVALID_PARAMETER
-                   - The request/procedure did not succeed because it had an
-                     invalid parameter
-    CSR_WIFI_RESULT_NO_ROOM
-                   - The request did not succeed due to a lack of resources,
-                     e.g. out of memory problem.
-    CSR_WIFI_RESULT_UNSUPPORTED
-                   - The request/procedure did not succeed because the feature
-                     is not supported yet
-    CSR_WIFI_RESULT_UNAVAILABLE
-                   - The request cannot be processed at this time
-    CSR_WIFI_RESULT_WIFI_OFF
-                   - The requested action is not available because Wi-Fi is
-                     currently off
-    CSR_WIFI_RESULT_SECURITY_ERROR
-                   - The request/procedure did not succeed because of a security
-                     error
-    CSR_WIFI_RESULT_MIB_SET_FAILURE
-                   - MIB Set Failure: either the MIB OID to be written to does
-                     not exist or the MIB Value is invalid.
-    CSR_WIFI_RESULT_INVALID_INTERFACE_TAG
-                   - The supplied Interface Tag is not valid.
-    CSR_WIFI_RESULT_P2P_NOA_CONFIG_CONFLICT
-                   - The new NOA configuration conflicts with the existing NOA configuration
-                     hence not accepted"
-*******************************************************************************/
-#define CSR_WIFI_RESULT_NOT_FOUND                 ((CsrResult) 0x0001)
-#define CSR_WIFI_RESULT_TIMED_OUT                 ((CsrResult) 0x0002)
-#define CSR_WIFI_RESULT_CANCELLED                 ((CsrResult) 0x0003)
-#define CSR_WIFI_RESULT_INVALID_PARAMETER         ((CsrResult) 0x0004)
-#define CSR_WIFI_RESULT_NO_ROOM                   ((CsrResult) 0x0005)
-#define CSR_WIFI_RESULT_UNSUPPORTED               ((CsrResult) 0x0006)
-#define CSR_WIFI_RESULT_UNAVAILABLE               ((CsrResult) 0x0007)
-#define CSR_WIFI_RESULT_WIFI_OFF                  ((CsrResult) 0x0008)
-#define CSR_WIFI_RESULT_SECURITY_ERROR            ((CsrResult) 0x0009)
-#define CSR_WIFI_RESULT_MIB_SET_FAILURE           ((CsrResult) 0x000A)
-#define CSR_WIFI_RESULT_INVALID_INTERFACE_TAG     ((CsrResult) 0x000B)
-#define CSR_WIFI_RESULT_P2P_NOA_CONFIG_CONFLICT   ((CsrResult) 0x000C)
-
-#define CSR_WIFI_VERSION	"5.1.0.0"
-
-#endif
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_fsm_event.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_fsm_event.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_fsm_event.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_fsm_event.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,42 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_FSM_EVENT_H
-#define CSR_WIFI_FSM_EVENT_H
-
-#include "csr_prim_defs.h"
-#include "csr_sched.h"
-
-/**
- * @brief
- *   FSM event header.
- *
- * @par Description
- *   All events MUST have this struct as the FIRST member.
- *   The next member is used internally for linked lists
- */
-typedef struct CsrWifiFsmEvent
-{
-    CsrPrim     type;
-    u16   primtype;
-    CsrSchedQid destination;
-    CsrSchedQid source;
-
-    /* Private pointer to allow an optimal Event list */
-    /* NOTE: Ignore this pointer.
-     *       Do not waste code initializing OR freeing it.
-     *       The pointer is used internally in the CsrWifiFsm code
-     *       to avoid a second malloc when queuing events.
-     */
-    struct CsrWifiFsmEvent *next;
-} CsrWifiFsmEvent;
-
-#endif /* CSR_WIFI_FSM_EVENT_H */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_fsm.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_fsm.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_fsm.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_fsm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,240 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_FSM_H
-#define CSR_WIFI_FSM_H
-
-#include "csr_prim_defs.h"
-#include "csr_log_text.h"
-#include "csr_wifi_fsm_event.h"
-
-/* including this file for CsrWifiInterfaceMode*/
-#include "csr_wifi_common.h"
-
-#define CSR_WIFI_FSM_ENV       (0xFFFF)
-
-/**
- * @brief
- *   Toplevel FSM context data
- *
- * @par Description
- *   Holds ALL FSM static and dynamic data for a FSM
- */
-typedef struct CsrWifiFsmContext CsrWifiFsmContext;
-
-/**
- * @brief
- *   FSM External Wakeup CallbackFunction Pointer
- *
- * @par Description
- *   Defines the external wakeup function for the FSM
- *   to call when an external event is injected into the systen
- *
- * @param[in]    context : External context
- *
- * @return
- *   void
- */
-typedef void (*CsrWifiFsmExternalWakupCallbackPtr)(void *context);
-
-/**
- * @brief
- *   Initialises a top level FSM context
- *
- * @par Description
- *   Initialises the FSM Context to an initial state and allocates
- *   space for "maxProcesses" number of instances
- *
- * @param[in]    osaContext         : OSA context
- * @param[in]    applicationContext : Internal fsm application context
- * @param[in]    externalContext    : External context
- * @param[in]    maxProcesses       : Max processes to allocate room for
- *
- * @return
- *   CsrWifiFsmContext* fsm context
- */
-extern CsrWifiFsmContext* CsrWifiFsmInit(void *applicationContext, void *externalContext, u16 maxProcesses, CsrLogTextTaskId loggingTaskId);
-
-/**
- * @brief
- *   Resets the FSM's back to first conditions
- *
- * @par Description
- *   This function is used to free any dynamic resources allocated for the
- *   given context by CsrWifiFsmInit().
- *   The FSM's reset function is called to cleanup any fsm specific memory
- *   The reset function does NOT need to free the fsm data pointer as
- *   CsrWifiFsmShutdown() will do it.
- *   the FSM's init function is call again to reinitialise the FSM context.
- *   CsrWifiFsmReset() should NEVER be called when CsrWifiFsmExecute() is running.
- *
- * @param[in]    context    : FSM context
- *
- * @return
- *   void
- */
-extern void CsrWifiFsmReset(CsrWifiFsmContext *context);
-
-/**
- * @brief
- *   Frees resources allocated by CsrWifiFsmInit
- *
- * @par Description
- *   This function is used to free any dynamic resources allocated for the
- *   given context by CsrWifiFsmInit(), prior to complete termination of
- *   the program.
- *   The FSM's reset function is called to cleanup any fsm specific memory.
- *   The reset function does NOT need to free the fsm data pointer as
- *   CsrWifiFsmShutdown() will do it.
- *   CsrWifiFsmShutdown() should NEVER be called when CsrWifiFsmExecute() is running.
- *
- * @param[in]    context       : FSM context
- *
- * @return
- *   void
- */
-extern void CsrWifiFsmShutdown(CsrWifiFsmContext *context);
-
-/**
- * @brief
- *   Executes the fsm context
- *
- * @par Description
- *   Executes the FSM context and runs until ALL events in the context are processed.
- *   When no more events are left to process then CsrWifiFsmExecute() returns to a time
- *   specifying when to next call the CsrWifiFsmExecute()
- *   Scheduling, threading, blocking and external event notification are outside
- *   the scope of the FSM and CsrWifiFsmExecute().
- *
- * @param[in]    context  : FSM context
- *
- * @return
- *   u32    Time in ms until next timeout or 0xFFFFFFFF for no timer set
- */
-extern u32 CsrWifiFsmExecute(CsrWifiFsmContext *context);
-
-/**
- * @brief
- *   Adds an event to the FSM context's external event queue for processing
- *
- * @par Description
- *   Adds an event to the contexts external queue
- *   This is thread safe and adds an event to the fsm's external event queue.
- *
- * @param[in]    context      : FSM context
- * @param[in]    event        : event to add to the event queue
- * @param[in]    source       : source of the event (this can be a synergy task queue or an fsm instance id)
- * @param[in]    destination  : destination of the event (This can be a fsm instance id or CSR_WIFI_FSM_ENV)
- * @param[in]    id           : event id
- *
- * @return
- *   void
- */
-extern void CsrWifiFsmSendEventExternal(CsrWifiFsmContext *context, CsrWifiFsmEvent *event, u16 source, u16 destination, CsrPrim primtype, u16 id);
-
-/**
- * @brief
- *   Adds an Alien event to the FSM context's external event queue for processing
- *
- * @par Description
- *   Adds an event to the contexts external queue
- *   This is thread safe and adds an event to the fsm's external event queue.
- *
- * @param[in]    context      : FSM context
- * @param[in]    event        : event to add to the event queue
- * @param[in]    source       : source of the event (this can be a synergy task queue or an fsm instance id)
- * @param[in]    destination  : destination of the event (This can be a fsm instance id or CSR_WIFI_FSM_ENV)
- * @param[in]    id           : event id
- */
-#define CsrWifiFsmSendAlienEventExternal(_context, _alienEvent, _source, _destination, _primtype, _id) \
-    { \
-        CsrWifiFsmAlienEvent *_evt = kmalloc(sizeof(CsrWifiFsmAlienEvent), GFP_KERNEL); \
-        _evt->alienEvent = _alienEvent; \
-        CsrWifiFsmSendEventExternal(_context, (CsrWifiFsmEvent *)_evt, _source, _destination, _primtype, _id); \
-    }
-
-
-/**
- * @brief
- *   Current time of day in ms
- *
- * @param[in]    context   : FSM context
- *
- * @return
- *   u32 32 bit ms tick
- */
-extern u32 CsrWifiFsmGetTimeOfDayMs(CsrWifiFsmContext *context);
-
-/**
- * @brief
- *   Gets the time until the next FSM timer expiry
- *
- * @par Description
- *   Returns the next timeout time or 0 if no timers are set.
- *
- * @param[in]    context    : FSM context
- *
- * @return
- *   u32    Time in ms until next timeout or 0xFFFFFFFF for no timer set
- */
-extern u32 CsrWifiFsmGetNextTimeout(CsrWifiFsmContext *context);
-
-/**
- * @brief
- *   Fast forwards the fsm timers by ms Milliseconds
- *
- * @param[in]  context : FSM context
- * @param[in]  ms      : Milliseconds to fast forward by
- *
- * @return
- *   void
- */
-extern void CsrWifiFsmFastForward(CsrWifiFsmContext *context, u16 ms);
-
-/**
- * @brief
- *   shift the current time of day by ms amount
- *
- * @par Description
- *   useful to speed up tests where time needs to pass
- *
- * @param[in]    context  : FSM context
- * @param[in]    ms       : ms to adjust time by
- *
- * @return
- *   void
- */
-extern void CsrWifiFsmTestAdvanceTime(CsrWifiFsmContext *context, u32 ms);
-
-/**
- * @brief
- *    Check if the fsm has events to process
- *
- * @param[in]    context    : FSM context
- *
- * @return
- *   u8 returns TRUE if there are events for the FSM to process
- */
-extern u8 CsrWifiFsmHasEvents(CsrWifiFsmContext *context);
-
-/**
- * @brief
- *   function that installs the contexts wakeup function
- *
- * @param[in]    context    : FSM context
- * @param[in]    callback   : Callback function pointer
- *
- * @return
- *   void
- */
-extern void CsrWifiFsmInstallWakeupCallback(CsrWifiFsmContext *context, CsrWifiFsmExternalWakupCallbackPtr callback);
-
-#endif /* CSR_WIFI_FSM_H */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_fsm_types.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_fsm_types.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_fsm_types.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_fsm_types.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,430 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_FSM_TYPES_H
-#define CSR_WIFI_FSM_TYPES_H
-
-#include <linux/types.h>
-#include "csr_macro.h"
-#include "csr_sched.h"
-
-#ifdef CSR_WIFI_FSM_MUTEX_ENABLE
-#include "csr_framework_ext.h"
-#endif
-
-#include "csr_wifi_fsm.h"
-
-#define CSR_WIFI_FSM_MAX_TRANSITION_HISTORY 10
-
-/**
- * @brief
- *   FSM event list header.
- *
- * @par Description
- *   Singly linked list of events.
- */
-typedef struct CsrWifiFsmEventList
-{
-    CsrWifiFsmEvent *first;
-    CsrWifiFsmEvent *last;
-} CsrWifiFsmEventList;
-
-
-/**
- * @brief
- *   FSM timer id.
- *
- * @par Description
- *   Composite Id made up of the type, dest and a unique id so
- *   CsrWifiFsmRemoveTimer knows where to look when removing the timer
- */
-typedef struct CsrWifiFsmTimerId
-{
-    CsrPrim     type;
-    u16   primtype;
-    CsrSchedQid destination;
-    u16   uniqueid;
-} CsrWifiFsmTimerId;
-
-/**
- * @brief
- *   FSM timer header.
- *
- * @par Description
- *   All timer MUST have this struct as the FIRST member.
- *   The first members of the structure MUST remain compatable
- *   with the CsrWifiFsmEvent so that timers are just specialised events
- */
-typedef struct CsrWifiFsmTimer
-{
-    CsrPrim     type;
-    u16   primtype;
-    CsrSchedQid destination;
-    CsrSchedQid source;
-
-    /* Private pointer to allow an optimal Event list */
-    struct CsrWifiFsmTimer *next;
-
-    CsrWifiFsmTimerId timerid;
-    u32         timeoutTimeMs;
-} CsrWifiFsmTimer;
-
-
-/**
- * @brief
- *   Fsm Alien Event
- *
- * @par Description
- *   Allows the wrapping of alien events that do not use CsrWifiFsmEvent
- *   as the first member of the Event struct
- */
-typedef struct
-{
-    CsrWifiFsmEvent event;
-    void           *alienEvent;
-} CsrWifiFsmAlienEvent;
-
-
-/**
- * @brief
- *   FSM timer list header.
- *
- * @par Description
- *   Singly linked list of timers.
- */
-typedef struct CsrWifiFsmTimerList
-{
-    CsrWifiFsmTimer *first;
-    CsrWifiFsmTimer *last;
-    u16        nexttimerid;
-} CsrWifiFsmTimerList;
-
-/**
- * @brief
- *   Process Entry Function Pointer
- *
- * @par Description
- *   Defines the entry function for a processes.
- *   Called at process initialisation.
- *
- * @param[in]    context : FSM context
- *
- * @return
- *   void
- */
-typedef void (*CsrWifiFsmProcEntryFnPtr)(CsrWifiFsmContext *context);
-
-/**
- * @brief
- *   Process Transition Function Pointer
- *
- * @par Description
- *   Defines a transition function for a processes.
- *   Called when an event causes a transition on a process
- *
- * @param[in]    CsrWifiFsmContext* : FSM context
- * @param[in]    void* : FSM data (can be NULL)
- * @param[in]    const CsrWifiFsmEvent*  : event to process
- *
- * @return
- *   void
- */
-typedef void (*CsrWifiFsmTransitionFnPtr)(CsrWifiFsmContext *context, void *fsmData, const CsrWifiFsmEvent *event);
-
-/**
- * @brief
- *   Process reset/shutdown Function Pointer
- *
- * @par Description
- *   Defines the reset/shutdown function for a processes.
- *   Called to reset or shutdown an fsm.
- *
- * @param[in]    context      : FSM context
- *
- * @return
- *   void
- */
-typedef void (*CsrWifiFsmProcResetFnPtr)(CsrWifiFsmContext *context);
-
-/**
- * @brief
- *   FSM Default Destination CallbackFunction Pointer
- *
- * @par Description
- *   Defines the default destination function for the FSM
- *   to call when an event does not have a valid destination.
- *   This
- *
- * @param[in]    context : External context
- *
- * @return
- *   u16 a valid destination OR CSR_WIFI_FSM_ENV
- */
-typedef u16 (*CsrWifiFsmDestLookupCallbackPtr)(void *context, const CsrWifiFsmEvent *event);
-
-
-#ifdef CSR_WIFI_FSM_DUMP_ENABLE
-/**
- * @brief
- *   Trace Dump Function Pointer
- *
- * @par Description
- *   Called when we want to trace the FSM
- *
- * @param[in]    context : FSM context
- * @param[in]    id      : fsm id
- *
- * @return
- *   void
- */
-typedef void (*CsrWifiFsmDumpFnPtr)(CsrWifiFsmContext *context, void *fsmData);
-#endif
-
-/**
- * @brief
- *   Event ID to transition function entry
- *
- * @par Description
- *   Event ID to Transition Entry in a state table.
- */
-typedef struct
-{
-    u32                 eventid;
-    CsrWifiFsmTransitionFnPtr transition;
-#ifdef CSR_LOG_ENABLE
-    const char *transitionName;
-#endif
-} CsrWifiFsmEventEntry;
-
-/**
- * @brief
- *   Single State's Transition Table
- *
- * @par Description
- *   Stores Data for a single State's event to
- *   transition functions mapping
- */
-typedef struct
-{
-    const u8              numEntries;
-    const u8               saveAll;
-    const CsrWifiFsmEventEntry *eventEntryArray; /* array of transition function pointers for state */
-#ifdef CSR_LOG_ENABLE
-    u16            stateNumber;
-    const char *stateName;
-#endif
-} CsrWifiFsmTableEntry;
-
-/**
- * @brief
- *   Process State Transtion table
- *
- * @par Description
- *   Stores Data for a processes State to transition table
- */
-typedef struct
-{
-    u16                   numStates;         /* number of states    */
-    const CsrWifiFsmTableEntry *aStateEventMatrix; /* state event matrix  */
-} CsrWifiFsmTransitionFunctionTable;
-
-/**
- * @brief
- *   Const Process definition
- *
- * @par Description
- *   Constant process specification.
- *   This is ALL the non dynamic data that defines
- *   a process.
- */
-typedef struct
-{
-    const char                    *processName;
-    const u32                         processId;
-    const CsrWifiFsmTransitionFunctionTable transitionTable;
-    const CsrWifiFsmTableEntry              unhandledTransitions;
-    const CsrWifiFsmTableEntry              ignoreFunctions;
-    const CsrWifiFsmProcEntryFnPtr          entryFn;
-    const CsrWifiFsmProcResetFnPtr          resetFn;
-#ifdef CSR_WIFI_FSM_DUMP_ENABLE
-    const CsrWifiFsmDumpFnPtr dumpFn;               /* Called to dump fsm specific trace if not NULL */
-#endif
-} CsrWifiFsmProcessStateMachine;
-
-#ifdef CSR_WIFI_FSM_DUMP_ENABLE
-/**
- * @brief
- *   Storage for state transition info
- */
-typedef struct
-{
-    u16                 transitionNumber;
-    CsrWifiFsmEvent           event;
-    u16                 fromState;
-    u16                 toState;
-    CsrWifiFsmTransitionFnPtr transitionFn;
-    u16                 transitionCount; /* number consecutive of times this transition was seen */
-#ifdef CSR_LOG_ENABLE
-    const char *transitionName;
-#endif
-} CsrWifiFsmTransitionRecord;
-
-/**
- * @brief
- *   Storage for the last state X transitions
- */
-typedef struct
-{
-    u16                  numTransitions;
-    CsrWifiFsmTransitionRecord records[CSR_WIFI_FSM_MAX_TRANSITION_HISTORY];
-} CsrWifiFsmTransitionRecords;
-#endif
-
-/**
- * @brief
- *   Dynamic Process data
- *
- * @par Description
- *   Dynamic process data that is used to keep track of the
- *   state and data for a process instance
- */
-typedef struct
-{
-    const CsrWifiFsmProcessStateMachine *fsmInfo;         /* state machine info that is constant regardless of context */
-    u16                            instanceId;      /* Runtime process id */
-    u16                            state;           /* Current state */
-    void                                *params;          /* Instance user data */
-    CsrWifiFsmEventList                  savedEventQueue; /* The saved event queue */
-    struct CsrWifiFsmInstanceEntry      *subFsm;          /* Sub Fsm instance data */
-    struct CsrWifiFsmInstanceEntry      *subFsmCaller;    /* The Fsm instance that created the SubFsm and should be used for callbacks*/
-#ifdef CSR_WIFI_FSM_DUMP_ENABLE
-    CsrWifiFsmTransitionRecords transitionRecords;        /* Last X transitions in the FSM */
-#endif
-} CsrWifiFsmInstanceEntry;
-
-/**
- * @brief
- *   OnCreate Callback Function Pointer
- *
- * @par Description
- *   Called when an fsm is created.
- *
- * @param[in]    extContext : External context
- * @param[in]    instance : FSM instance
- *
- * @return
- *   void
- */
-typedef void (*CsrWifiFsmOnCreateFnPtr)(void *extContext, const CsrWifiFsmInstanceEntry *instance);
-
-/**
- * @brief
- *   OnTransition Callback Function Pointer
- *
- * @par Description
- *   Called when an event is processed by a fsm
- *
- * @param[in]    extContext : External context
- * @param[in]    eventEntryArray : Entry data
- * @param[in]    event : Event
- *
- * @return
- *   void
- */
-typedef void (*CsrWifiFsmOnTransitionFnPtr)(void *extContext, const CsrWifiFsmEventEntry *eventEntryArray, const CsrWifiFsmEvent *event);
-
-/**
- * @brief
- *   OnStateChange Callback Function Pointer
- *
- * @par Description
- *   Called when CsrWifiFsmNextState is called
- *
- * @param[in]    extContext : External context
- *
- * @return
- *   void
- */
-typedef void (*CsrWifiFsmOnStateChangeFnPtr)(void *extContext, u16 nextstate);
-
-/**
- * @brief
- *   OnIgnore,OnError or OnInvalid Callback Function Pointer
- *
- * @par Description
- *   Called when an event is processed by a fsm
- *
- * @param[in]    extContext : External context
- * @param[in]    event : Event
- *
- * @return
- *   void
- */
-typedef void (*CsrWifiFsmOnEventFnPtr)(void *extContext, const CsrWifiFsmEvent *event);
-
-/**
- * @brief
- *   Toplevel FSM context data
- *
- * @par Description
- *   Holds ALL FSM static and dynamic data for a FSM
- */
-struct CsrWifiFsmContext
-{
-    CsrWifiFsmEventList eventQueue;                           /* The internal event queue                     */
-    CsrWifiFsmEventList externalEventQueue;                   /* The external event queue                     */
-#ifdef CSR_WIFI_FSM_MUTEX_ENABLE
-    CsrMutexHandle externalEventQueueLock;                    /* The external event queue mutex               */
-#endif
-    u32                          timeOffset;            /* Amount to adjust the TimeOfDayMs by          */
-    CsrWifiFsmTimerList                timerQueue;            /* The internal timer queue                     */
-    u8                            useTempSaveList;       /* Should the temp save list be used            */
-    CsrWifiFsmEventList                tempSaveList;          /* The temp save event queue                    */
-    CsrWifiFsmEvent                   *eventForwardedOrSaved; /* The event that was forwarded or Saved        */
-    u16                          maxProcesses;          /* Size of instanceArray                        */
-    u16                          numProcesses;          /* Current number allocated in instanceArray    */
-    CsrWifiFsmInstanceEntry           *instanceArray;         /* Array of processes for this component        */
-    CsrWifiFsmInstanceEntry           *ownerInstance;         /* The Process that owns currentInstance (SubFsm support) */
-    CsrWifiFsmInstanceEntry           *currentInstance;       /* Current Process that is executing            */
-    CsrWifiFsmExternalWakupCallbackPtr externalEventFn;       /* External event Callback                      */
-    CsrWifiFsmOnEventFnPtr             appIgnoreCallback;     /* Application Ignore event Callback            */
-    CsrWifiFsmDestLookupCallbackPtr    appEvtDstCallback;     /* Application Lookup event Destination Function*/
-
-    void            *applicationContext;                      /* Internal fsm application context             */
-    void            *externalContext;                         /* External context (set by the user of the fsm)*/
-    CsrLogTextTaskId loggingTaskId;                           /* Task Id to use in any logging output         */
-
-#ifndef CSR_WIFI_FSM_SCHEDULER_DISABLED
-    CsrSchedTid schedTimerId;                                 /* Scheduler TimerId for use in Scheduler Tasks */
-    u32   schedTimerNexttimeoutMs;                      /* Next timeout time for the current timer      */
-#endif
-
-#ifdef CSR_WIFI_FSM_MUTEX_ENABLE
-#ifdef CSR_WIFI_FSM_TRANSITION_LOCK
-    CsrMutexHandle transitionLock;                     /* Lock when calling transition functions        */
-#endif
-#endif
-
-#ifdef CSR_LOG_ENABLE
-    CsrWifiFsmOnCreateFnPtr      onCreate;             /* Debug Transition Callback                    */
-    CsrWifiFsmOnTransitionFnPtr  onTransition;         /* Debug Transition Callback                    */
-    CsrWifiFsmOnTransitionFnPtr  onUnhandedCallback;   /* Unhanded event Callback                      */
-    CsrWifiFsmOnStateChangeFnPtr onStateChange;        /* Debug State Change Callback                  */
-    CsrWifiFsmOnEventFnPtr       onIgnoreCallback;     /* Ignore event Callback                        */
-    CsrWifiFsmOnEventFnPtr       onSaveCallback;       /* Save event Callback                          */
-    CsrWifiFsmOnEventFnPtr       onErrorCallback;      /* Error event Callback                         */
-    CsrWifiFsmOnEventFnPtr       onInvalidCallback;    /* Invalid event Callback                       */
-#endif
-#ifdef CSR_WIFI_FSM_DUMP_ENABLE
-    u16 masterTransitionNumber;                  /* Increments on every transition              */
-#endif
-};
-
-#endif /* CSR_WIFI_FSM_TYPES_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,114 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- ******************************************************************************
- * FILE : csr_wifi_hip_card.h
- *
- * PURPOSE : Defines abstract interface for hardware specific functions.
- *           Note, this is a different file from one of the same name in the
- *           Windows driver.
- *
- *****************************************************************************
- */
-#ifndef __CARD_H__
-#define __CARD_H__
-
-#include "csr_wifi_hip_card_sdio.h"
-#include "csr_wifi_hip_signals.h"
-#include "csr_wifi_hip_unifi_udi.h"
-
-
-/*****************************************************************************
- * CardEnableInt -
- */
-CsrResult CardEnableInt(card_t *card);
-
-/*****************************************************************************
- * CardGenInt -
- */
-CsrResult CardGenInt(card_t *card);
-
-/*****************************************************************************
- * CardPendingInt -
- */
-CsrResult CardPendingInt(card_t *card, u8 *pintr);
-
-/*****************************************************************************
- * CardDisableInt -
- */
-CsrResult CardDisableInt(card_t *card);
-
-/*****************************************************************************
- * CardClearInt -
- */
-CsrResult CardClearInt(card_t *card);
-
-/*****************************************************************************
- * CardDisable -
- */
-void CardDisable(card_t *card);
-
-/*****************************************************************************
- * CardIntEnabled -
- */
-CsrResult CardIntEnabled(card_t *card, u8 *enabled);
-
-/*****************************************************************************
- * CardGetDataSlotSize
- */
-u16 CardGetDataSlotSize(card_t *card);
-
-/*****************************************************************************
- * CardWriteBulkData -
- */
-CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQueue queue);
-
-
-/*****************************************************************************
- * CardClearFromHostDataSlot -
- */
-void CardClearFromHostDataSlot(card_t *card, const s16 aSlotNum);
-
-#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
-/*****************************************************************************
- * CardClearFromHostDataSlotWithoutFreeingBulkData - Clear the data stot
- * without freeing the bulk data
- */
-
-void CardClearFromHostDataSlotWithoutFreeingBulkData(card_t *card, const s16 aSlotNum);
-#endif
-
-/*****************************************************************************
- * CardGetFreeFromHostDataSlots -
- */
-u16 CardGetFreeFromHostDataSlots(card_t *card);
-
-u16 CardAreAllFromHostDataSlotsEmpty(card_t *card);
-
-CsrResult card_start_processor(card_t *card, enum unifi_dbg_processors_select which);
-
-CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr);
-
-CsrResult unifi_dl_firmware(card_t *card, void *arg);
-CsrResult unifi_dl_patch(card_t *card, void *arg, u32 boot_ctrl);
-CsrResult unifi_do_loader_op(card_t *card, u32 op_addr, u8 opcode);
-void* unifi_dl_fw_read_start(card_t *card, s8 is_fw);
-
-CsrResult unifi_coredump_handle_request(card_t *card);
-
-CsrResult ConvertCsrSdioToCsrHipResult(card_t *card, CsrResult csrResult);
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-void unifi_debug_log_to_buf(const char *fmt, ...);
-void unifi_debug_string_to_buf(const char *str);
-void unifi_debug_hex_to_buf(const char *buff, u16 length);
-#endif
-
-#endif /* __CARD_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,4001 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- * FILE: csr_wifi_hip_card_sdio.c
- *
- * PURPOSE: Implementation of the Card API for SDIO.
- *
- * NOTES:
- *      CardInit() is called from the SDIO probe callback when a card is
- *      inserted. This performs the basic SDIO initialisation, enabling i/o
- *      etc.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/slab.h>
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-#include "csr_wifi_hip_unifiversion.h"
-#include "csr_wifi_hip_card.h"
-#include "csr_wifi_hip_card_sdio.h"
-#include "csr_wifi_hip_chiphelper.h"
-
-
-/* Time to wait between attempts to read MAILBOX0 */
-#define MAILBOX1_TIMEOUT                10  /* in millisecs */
-#define MAILBOX1_ATTEMPTS               200 /* 2 seconds */
-
-#define MAILBOX2_TIMEOUT                5   /* in millisecs */
-#define MAILBOX2_ATTEMPTS               10  /* 50ms */
-
-#define RESET_SETTLE_DELAY              25  /* in millisecs */
-
-static CsrResult card_init_slots(card_t *card);
-static CsrResult card_hw_init(card_t *card);
-static CsrResult firmware_present_in_flash(card_t *card);
-static void bootstrap_chip_hw(card_t *card);
-static CsrResult unifi_reset_hardware(card_t *card);
-static CsrResult unifi_hip_init(card_t *card);
-static CsrResult card_access_panic(card_t *card);
-static CsrResult unifi_read_chip_version(card_t *card);
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_alloc_card
- *
- *      Allocate and initialise the card context structure.
- *
- *  Arguments:
- *      sdio            Pointer to SDIO context pointer to pass to low
- *                      level i/o functions.
- *      ospriv          Pointer to O/S private struct to pass when calling
- *                      callbacks to the higher level system.
- *
- *  Returns:
- *      Pointer to card struct, which represents the driver context or
- *      NULL if the allocation failed.
- * ---------------------------------------------------------------------------
- */
-card_t* unifi_alloc_card(CsrSdioFunction *sdio, void *ospriv)
-{
-    card_t *card;
-    u32 i;
-
-
-    card = kzalloc(sizeof(card_t), GFP_KERNEL);
-    if (card == NULL)
-    {
-        return NULL;
-    }
-
-    card->sdio_if = sdio;
-    card->ospriv  = ospriv;
-
-    card->unifi_interrupt_seq = 1;
-
-    /* Make these invalid. */
-    card->proc_select = (u32)(-1);
-    card->dmem_page = (u32)(-1);
-    card->pmem_page = (u32)(-1);
-
-    card->bh_reason_host = 0;
-    card->bh_reason_unifi = 0;
-
-    for (i = 0; i < sizeof(card->tx_q_paused_flag) / sizeof(card->tx_q_paused_flag[0]); i++)
-    {
-        card->tx_q_paused_flag[i] = 0;
-    }
-    card->memory_resources_allocated = 0;
-
-    card->low_power_mode = UNIFI_LOW_POWER_DISABLED;
-    card->periodic_wake_mode = UNIFI_PERIODIC_WAKE_HOST_DISABLED;
-
-    card->host_state = UNIFI_HOST_STATE_AWAKE;
-    card->intmode = CSR_WIFI_INTMODE_DEFAULT;
-
-    /*
-     * Memory resources for buffers are allocated when the chip is initialised
-     * because we need configuration information from the firmware.
-     */
-
-    /*
-     * Initialise wait queues and lists
-     */
-    card->fh_command_queue.q_body = card->fh_command_q_body;
-    card->fh_command_queue.q_length = UNIFI_SOFT_COMMAND_Q_LENGTH;
-
-    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-    {
-        card->fh_traffic_queue[i].q_body = card->fh_traffic_q_body[i];
-        card->fh_traffic_queue[i].q_length = UNIFI_SOFT_TRAFFIC_Q_LENGTH;
-    }
-
-
-    /* Initialise mini-coredump pointers in case no coredump buffers
-     * are requested by the OS layer.
-     */
-    card->request_coredump_on_reset = 0;
-    card->dump_next_write = NULL;
-    card->dump_cur_read = NULL;
-    card->dump_buf = NULL;
-
-#ifdef UNIFI_DEBUG
-    /* Determine offset of LSB in pointer for later alignment sanity check.
-     * Synergy integer types have specific widths, which cause compiler
-     * warnings when casting pointer types, e.g. on 64-bit systems.
-     */
-    {
-        u32 val = 0x01234567;
-
-        if (*((u8 *)&val) == 0x01)
-        {
-            card->lsb = sizeof(void *) - 1;     /* BE */
-        }
-        else
-        {
-            card->lsb = 0;                      /* LE */
-        }
-    }
-#endif
-    return card;
-} /* unifi_alloc_card() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_init_card
- *
- *      Reset the hardware and perform HIP initialization
- *
- *  Arguments:
- *      card        Pointer to card struct
- *
- *  Returns:
- *      CsrResult code
- *      CSR_RESULT_SUCCESS if successful
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_init_card(card_t *card, s32 led_mask)
-{
-    CsrResult r;
-
-
-    if (card == NULL)
-    {
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    r = unifi_init(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    r = unifi_hip_init(card);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to start host protocol.\n");
-        return r;
-    }
-
-    return CSR_RESULT_SUCCESS;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_init
- *
- *      Init the hardware.
- *
- *  Arguments:
- *      card        Pointer to card struct
- *
- *  Returns:
- *      CsrResult code
- *      CSR_RESULT_SUCCESS if successful
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_init(card_t *card)
-{
-    CsrResult r;
-    CsrResult csrResult;
-
-    if (card == NULL)
-    {
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    /*
-     * Disable the SDIO interrupts while initialising UniFi.
-     * Re-enable them when f/w is running.
-     */
-    csrResult = CsrSdioInterruptDisable(card->sdio_if);
-    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-    {
-        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-    }
-
-    /*
-     * UniFi's PLL may start with a slow clock (~ 1 MHz) so initially
-     * set the SDIO bus clock to a similar value or SDIO accesses may
-     * fail.
-     */
-    csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_SAFE_HZ);
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-        return r;
-    }
-    card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ;
-
-    /*
-     * Reset UniFi. Note, this only resets the WLAN function part of the chip,
-     * the SDIO interface is not reset.
-     */
-    unifi_trace(card->ospriv, UDBG1, "Resetting UniFi\n");
-    r = unifi_reset_hardware(card);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to reset UniFi\n");
-        return r;
-    }
-
-    /* Reset the power save mode, to be active until the MLME-reset is complete */
-    r = unifi_configure_low_power_mode(card,
-                                       UNIFI_LOW_POWER_DISABLED, UNIFI_PERIODIC_WAKE_HOST_DISABLED);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to set power save mode\n");
-        return r;
-    }
-
-    /*
-     * Set initial value of page registers.
-     * The page registers will be maintained by unifi_read...() and
-     * unifi_write...().
-     */
-    card->proc_select = (u32)(-1);
-    card->dmem_page = (u32)(-1);
-    card->pmem_page = (u32)(-1);
-    r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, 0);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n");
-        return r;
-    }
-    r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, 0);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write PROG_MEM2_PAGE\n");
-        return r;
-    }
-
-    /*
-     * If the driver has reset UniFi due to previous SDIO failure, this may
-     * have been due to a chip watchdog reset. In this case, the driver may
-     * have requested a mini-coredump which needs to be captured now the
-     * SDIO interface is alive.
-     */
-    (void)unifi_coredump_handle_request(card);
-
-    /*
-     * Probe to see if the UniFi has ROM/flash to boot from. CSR6xxx should do.
-     */
-    r = firmware_present_in_flash(card);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r == CSR_WIFI_HIP_RESULT_NOT_FOUND)
-    {
-        unifi_error(card->ospriv, "No firmware found\n");
-    }
-    else if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Probe for Flash failed\n");
-    }
-
-    return r;
-} /* unifi_init() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_download
- *
- *      Load the firmware.
- *
- *  Arguments:
- *      card        Pointer to card struct
- *      led_mask    Loader LED mask
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success
- *      CsrResult error code on failure.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_download(card_t *card, s32 led_mask)
-{
-    CsrResult r;
-    void *dlpriv;
-
-    if (card == NULL)
-    {
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    /* Set the loader led mask */
-    card->loader_led_mask = led_mask;
-
-    /* Get the firmware file information */
-    unifi_trace(card->ospriv, UDBG1, "downloading firmware...\n");
-
-    dlpriv = unifi_dl_fw_read_start(card, UNIFI_FW_STA);
-    if (dlpriv == NULL)
-    {
-        return CSR_WIFI_HIP_RESULT_NOT_FOUND;
-    }
-
-    /* Download the firmware. */
-    r = unifi_dl_firmware(card, dlpriv);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to download firmware\n");
-        return r;
-    }
-
-    /* Free the firmware file information. */
-    unifi_fw_read_stop(card->ospriv, dlpriv);
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_download() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_hip_init
- *
- *      This function performs the f/w initialisation sequence as described
- *      in the Unifi Host Interface Protocol Specification.
- *      It allocates memory for host-side slot data and signal queues.
- *
- *  Arguments:
- *      card        Pointer to card struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success or else a CSR error code
- *
- *  Notes:
- *      The firmware must have been downloaded.
- * ---------------------------------------------------------------------------
- */
-static CsrResult unifi_hip_init(card_t *card)
-{
-    CsrResult r;
-    CsrResult csrResult;
-
-    r = card_hw_init(card);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to establish communication with UniFi\n");
-        return r;
-    }
-#ifdef CSR_PRE_ALLOC_NET_DATA
-    /* if there is any preallocated netdata left from the prev session free it now */
-    prealloc_netdata_free(card);
-#endif
-    /*
-     * Allocate memory for host-side slot data and signal queues.
-     * We need the config info read from the firmware to know how much
-     * memory to allocate.
-     */
-    r = card_init_slots(card);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Init slots failed: %d\n", r);
-        return r;
-    }
-
-    unifi_trace(card->ospriv, UDBG2, "Sending first UniFi interrupt\n");
-
-    r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    /* Enable the SDIO interrupts now that the f/w is running. */
-    csrResult = CsrSdioInterruptEnable(card->sdio_if);
-    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-    {
-        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-    }
-
-    /* Signal the UniFi to start handling messages */
-    r = CardGenInt(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_hip_init() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  _build_sdio_config_data
- *
- *      Unpack the SDIO configuration information from a buffer read from
- *      UniFi into a host structure.
- *      The data is byte-swapped for a big-endian host if necessary by the
- *      UNPACK... macros.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      cfg_data        Destination structure to unpack into.
- *      cfg_data_buf    Source buffer to read from. This should be the raw
- *                      data read from UniFi.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void _build_sdio_config_data(sdio_config_data_t *cfg_data,
-                                    const u8     *cfg_data_buf)
-{
-    s16 offset = 0;
-
-    cfg_data->version = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->sdio_ctrl_offset = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->fromhost_sigbuf_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->tohost_sigbuf_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->num_fromhost_sig_frags = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->num_tohost_sig_frags = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->num_fromhost_data_slots = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->num_tohost_data_slots = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->data_slot_size = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->initialised = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->overlay_size = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT32;
-
-    cfg_data->data_slot_round = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->sig_frag_size = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-    offset += SIZEOF_UINT16;
-
-    cfg_data->tohost_signal_padding = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
-} /* _build_sdio_config_data() */
-
-
-/*
- * - Function ----------------------------------------------------------------
- * card_hw_init()
- *
- *      Perform the initialisation procedure described in the UniFi Host
- *      Interface Protocol document (section 3.3.8) and read the run-time
- *      configuration information from the UniFi. This is stuff like number
- *      of bulk data slots etc.
- *
- *      The card enumeration and SD initialisation has already been done by
- *      the SDIO library, see card_sdio_init().
- *
- *      The initialisation is done when firmware is ready, i.e. this may need
- *      to be called after a f/w download operation.
- *
- *      The initialisation procedure goes like this:
- *       - Wait for UniFi to start-up by polling SHARED_MAILBOX1
- *       - Find the symbol table and look up SLT_SDIO_SLOT_CONFIG
- *       - Read the config structure
- *       - Check the "SDIO initialised" flag, if not zero do a h/w reset and
- *         start again
- *       - Decide the number of bulk data slots to allocate, allocate them and
- *         set "SDIO initialised" flag (and generate an interrupt) to say so.
- *
- * Arguments:
- *      card        Pointer to card struct
- *
- * Returns:
- *      CSR_RESULT_SUCEESS on success,
- *      a CSR error code on failure
- *
- * Notes:
- *      All data in the f/w is stored in a little endian format, without any
- *      padding bytes. Every read from this memory has to be transformed in
- *      host (cpu specific) format, before it is stored in driver's parameters
- *      or/and structures. Athough unifi_card_read16() and unifi_read32() do perform
- *      the conversion internally, unifi_readn() does not.
- * ---------------------------------------------------------------------------
- */
-static CsrResult card_hw_init(card_t *card)
-{
-    u32 slut_address;
-    u16 initialised;
-    u16 finger_print;
-    symbol_t slut;
-    sdio_config_data_t *cfg_data;
-    u8 cfg_data_buf[SDIO_CONFIG_DATA_SIZE];
-    CsrResult r;
-    void *dlpriv;
-    s16 major, minor;
-    s16 search_4slut_again;
-    CsrResult csrResult;
-
-    /*
-     * The device revision from the TPLMID_MANF and TPLMID_CARD fields
-     * of the CIS are available as
-     *   card->sdio_if->pDevice->ManfID
-     *   card->sdio_if->pDevice->AppID
-     */
-
-    /*
-     * Run in a loop so we can patch.
-     */
-    do
-    {
-        /* Reset these each time around the loop. */
-        search_4slut_again = 0;
-        cfg_data = NULL;
-
-        r = card_wait_for_firmware_to_start(card, &slut_address);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Firmware hasn't started\n");
-            return r;
-        }
-        unifi_trace(card->ospriv, UDBG4, "SLUT addr 0x%lX\n", slut_address);
-
-        /*
-         * Firmware has started, but doesn't know full clock configuration yet
-         * as some of the information may be in the MIB. Therefore we set an
-         * initial SDIO clock speed, faster than UNIFI_SDIO_CLOCK_SAFE_HZ, for
-         * the patch download and subsequent firmware initialisation, and
-         * full speed UNIFI_SDIO_CLOCK_MAX_HZ will be set once the f/w tells us
-         * that it is ready.
-         */
-        csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ);
-        if (csrResult != CSR_RESULT_SUCCESS)
-        {
-            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-            return r;
-        }
-        card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;
-
-        /*
-         * Check the SLUT fingerprint.
-         * The slut_address is a generic pointer so we must use unifi_card_read16().
-         */
-        unifi_trace(card->ospriv, UDBG4, "Looking for SLUT finger print\n");
-        finger_print = 0;
-        r = unifi_card_read16(card, slut_address, &finger_print);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to read SLUT finger print\n");
-            return r;
-        }
-
-        if (finger_print != SLUT_FINGERPRINT)
-        {
-            unifi_error(card->ospriv, "Failed to find Symbol lookup table fingerprint\n");
-            return CSR_RESULT_FAILURE;
-        }
-
-        /* Symbol table starts imedately after the fingerprint */
-        slut_address += 2;
-
-        /* Search the table until either the end marker is found, or the
-         * loading of patch firmware invalidates the current table.
-         */
-        while (!search_4slut_again)
-        {
-            u16 s;
-            u32 l;
-
-            r = unifi_card_read16(card, slut_address, &s);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            slut_address += 2;
-
-            if (s == CSR_SLT_END)
-            {
-                unifi_trace(card->ospriv, UDBG3, "  found CSR_SLT_END\n");
-                break;
-            }
-
-            r = unifi_read32(card, slut_address, &l);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            slut_address += 4;
-
-            slut.id = s;
-            slut.obj = l;
-
-            unifi_trace(card->ospriv, UDBG3, "  found SLUT id %02d.%08lx\n", slut.id, slut.obj);
-            switch (slut.id)
-            {
-                case CSR_SLT_SDIO_SLOT_CONFIG:
-                    cfg_data = &card->config_data;
-                    /*
-                     * unifi_card_readn reads n bytes from the card, where data is stored
-                     * in a little endian format, without any padding bytes. So, we
-                     * can not just pass the cfg_data pointer or use the
-                     * sizeof(sdio_config_data_t) since the structure in the host can
-                     * be big endian formatted or have padding bytes for alignment.
-                     * We use a char buffer to read the data from the card.
-                     */
-                    r = unifi_card_readn(card, slut.obj, cfg_data_buf, SDIO_CONFIG_DATA_SIZE);
-                    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-                    {
-                        return r;
-                    }
-                    if (r != CSR_RESULT_SUCCESS)
-                    {
-                        unifi_error(card->ospriv, "Failed to read config data\n");
-                        return r;
-                    }
-                    /* .. and then we copy the data to the host structure */
-                    _build_sdio_config_data(cfg_data, cfg_data_buf);
-
-                    /* Make sure the from host data slots are what we expect
-                        we reserve 2 for commands and there should be at least
-                        1 left for each access category */
-                    if ((cfg_data->num_fromhost_data_slots < UNIFI_RESERVED_COMMAND_SLOTS)
-                        || (cfg_data->num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS) / UNIFI_NO_OF_TX_QS == 0)
-                    {
-                        unifi_error(card->ospriv, "From host data slots %d\n", cfg_data->num_fromhost_data_slots);
-                        unifi_error(card->ospriv, "need to be (queues * x + 2) (UNIFI_RESERVED_COMMAND_SLOTS for commands)\n");
-                        return CSR_RESULT_FAILURE;
-                    }
-
-                    /* Configure SDIO to-block-size padding */
-                    if (card->sdio_io_block_pad)
-                    {
-                    /*
-                     * Firmware limits the maximum padding size via data_slot_round.
-                     * Therefore when padding to whole block sizes, the block size
-                     * must be configured correctly by adjusting CSR_WIFI_HIP_SDIO_BLOCK_SIZE.
-                     */
-                        if (cfg_data->data_slot_round < card->sdio_io_block_size)
-                        {
-                            unifi_error(card->ospriv,
-                                        "Configuration error: Block size of %d exceeds f/w data_slot_round of %d\n",
-                                        card->sdio_io_block_size, cfg_data->data_slot_round);
-                            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-                        }
-
-                        /*
-                         * To force the To-Host signals to be rounded up to the SDIO block
-                         * size, we need to write the To-Host Signal Padding Fragments
-                         * field of the SDIO configuration in UniFi.
-                         */
-                        if ((card->sdio_io_block_size % cfg_data->sig_frag_size) != 0)
-                        {
-                            unifi_error(card->ospriv, "Configuration error: Can not pad to-host signals.\n");
-                            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-                        }
-                        cfg_data->tohost_signal_padding = (u16) (card->sdio_io_block_size / cfg_data->sig_frag_size);
-                        unifi_info(card->ospriv, "SDIO block size %d requires %d padding chunks\n",
-                                   card->sdio_io_block_size, cfg_data->tohost_signal_padding);
-                        r = unifi_card_write16(card, slut.obj + SDIO_TO_HOST_SIG_PADDING_OFFSET, cfg_data->tohost_signal_padding);
-                        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-                        {
-                            return r;
-                        }
-                        if (r != CSR_RESULT_SUCCESS)
-                        {
-                            unifi_error(card->ospriv, "Failed to write To-Host Signal Padding Fragments\n");
-                            return r;
-                        }
-                    }
-
-                    /* Reconstruct the Generic Pointer address of the
-                     * SDIO Control Data Struct.
-                     */
-                    card->sdio_ctrl_addr = cfg_data->sdio_ctrl_offset | (UNIFI_SH_DMEM << 24);
-                    card->init_flag_addr = slut.obj + SDIO_INIT_FLAG_OFFSET;
-                    break;
-
-                case CSR_SLT_BUILD_ID_NUMBER:
-                {
-                    u32 n;
-                    r = unifi_read32(card, slut.obj, &n);
-                    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-                    {
-                        return r;
-                    }
-                    if (r != CSR_RESULT_SUCCESS)
-                    {
-                        unifi_error(card->ospriv, "Failed to read build id\n");
-                        return r;
-                    }
-                    card->build_id = n;
-                }
-                break;
-
-                case CSR_SLT_BUILD_ID_STRING:
-                    r = unifi_readnz(card, slut.obj, card->build_id_string,
-                                     sizeof(card->build_id_string));
-                    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-                    {
-                        return r;
-                    }
-                    if (r != CSR_RESULT_SUCCESS)
-                    {
-                        unifi_error(card->ospriv, "Failed to read build string\n");
-                        return r;
-                    }
-                    break;
-
-                case CSR_SLT_PERSISTENT_STORE_DB:
-                    break;
-
-                case CSR_SLT_BOOT_LOADER_CONTROL:
-
-                    /* This command copies most of the station firmware
-                     * image from ROM into program RAM.  It also clears
-                     * out the zerod data and sets up the initialised
-                     * data. */
-                    r = unifi_do_loader_op(card, slut.obj + 6, UNIFI_BOOT_LOADER_LOAD_STA);
-                    if (r != CSR_RESULT_SUCCESS)
-                    {
-                        unifi_error(card->ospriv, "Failed to write loader load image command\n");
-                        return r;
-                    }
-
-                    dlpriv = unifi_dl_fw_read_start(card, UNIFI_FW_STA);
-
-                    /* dlpriv might be NULL, we still need to do the do_loader_op step. */
-                    if (dlpriv != NULL)
-                    {
-                    /* Download the firmware. */
-                        r = unifi_dl_patch(card, dlpriv, slut.obj);
-
-                    /* Free the firmware file information. */
-                        unifi_fw_read_stop(card->ospriv, dlpriv);
-
-                        if (r != CSR_RESULT_SUCCESS)
-                        {
-                            unifi_error(card->ospriv, "Failed to patch firmware\n");
-                            return r;
-                        }
-                    }
-
-                    /* This command starts the firmware image that we want (the
-                    * station by default) with any patches required applied. */
-                    r = unifi_do_loader_op(card, slut.obj + 6, UNIFI_BOOT_LOADER_RESTART);
-                    if (r != CSR_RESULT_SUCCESS)
-                    {
-                        unifi_error(card->ospriv, "Failed to write loader restart command\n");
-                        return r;
-                    }
-
-                    /* The now running patch f/w defines a new SLUT data structure -
-                     * the current one is no longer valid. We must drop out of the
-                     * processing loop and enumerate the new SLUT (which may appear
-                     * at a different offset).
-                     */
-                    search_4slut_again = 1;
-                    break;
-
-                case CSR_SLT_PANIC_DATA_PHY:
-                    card->panic_data_phy_addr = slut.obj;
-                    break;
-
-                case CSR_SLT_PANIC_DATA_MAC:
-                    card->panic_data_mac_addr = slut.obj;
-                    break;
-
-                default:
-                    /* do nothing */
-                    break;
-            }
-        } /* while */
-    } while (search_4slut_again);
-
-    /* Did we find the Config Data ? */
-    if (cfg_data == NULL)
-    {
-        unifi_error(card->ospriv, "Failed to find SDIO_SLOT_CONFIG Symbol\n");
-        return CSR_RESULT_FAILURE;
-    }
-
-    /*
-     * Has ths card already been initialised?
-     * If so, return an error so we do a h/w reset and start again.
-     */
-    r = unifi_card_read16(card, card->init_flag_addr, &initialised);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to read init flag at %08lx\n",
-                    card->init_flag_addr);
-        return r;
-    }
-    if (initialised != 0)
-    {
-        return CSR_RESULT_FAILURE;
-    }
-
-
-    /*
-     * Now check the UniFi firmware version
-     */
-    major = (cfg_data->version >> 8) & 0xFF;
-    minor = cfg_data->version & 0xFF;
-    unifi_info(card->ospriv, "UniFi f/w protocol version %d.%d (driver %d.%d)\n",
-               major, minor,
-               UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
-
-    unifi_info(card->ospriv, "Firmware build %u: %s\n",
-               card->build_id, card->build_id_string);
-
-    if (major != UNIFI_HIP_MAJOR_VERSION)
-    {
-        unifi_error(card->ospriv, "UniFi f/w protocol major version (%d) is different from driver (v%d.%d)\n",
-                    major, UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
-#ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK
-        return CSR_RESULT_FAILURE;
-#endif
-    }
-    if (minor < UNIFI_HIP_MINOR_VERSION)
-    {
-        unifi_error(card->ospriv, "UniFi f/w protocol version (v%d.%d) is older than minimum required by driver (v%d.%d).\n",
-                    major, minor,
-                    UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
-#ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK
-        return CSR_RESULT_FAILURE;
-#endif
-    }
-
-    /* Read panic codes from a previous firmware panic. If the firmware has
-     * not panicked since power was applied (e.g. power-off hard reset)
-     * the stored panic codes will not be updated.
-     */
-    unifi_read_panic(card);
-
-    return CSR_RESULT_SUCCESS;
-} /* card_hw_init() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_wait_for_unifi_to_reset
- *
- *      Waits for a reset to complete by polling the WLAN function enable
- *      bit (which is cleared on reset).
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code on failure.
- * ---------------------------------------------------------------------------
- */
-static CsrResult card_wait_for_unifi_to_reset(card_t *card)
-{
-    s16 i;
-    CsrResult r;
-    u8 io_enable;
-    CsrResult csrResult;
-
-    r = CSR_RESULT_SUCCESS;
-    for (i = 0; i < MAILBOX2_ATTEMPTS; i++)
-    {
-        unifi_trace(card->ospriv, UDBG1, "waiting for reset to complete, attempt %d\n", i);
-        if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
-        {
-            /* It's quite likely that this read will timeout for the
-             * first few tries - especially if we have reset via
-             * DBG_RESET.
-             */
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-            unifi_debug_log_to_buf("m0@%02X=", SDIO_IO_READY);
-#endif
-            csrResult = CsrSdioF0Read8(card->sdio_if, SDIO_IO_READY, &io_enable);
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-            if (csrResult != CSR_RESULT_SUCCESS)
-            {
-                unifi_debug_log_to_buf("error=%X\n", csrResult);
-            }
-            else
-            {
-                unifi_debug_log_to_buf("%X\n", io_enable);
-            }
-#endif
-            if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-            {
-                return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-            }
-            r = CSR_RESULT_SUCCESS;
-            if (csrResult != CSR_RESULT_SUCCESS)
-            {
-                r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-            }
-        }
-        else
-        {
-            r = sdio_read_f0(card, SDIO_IO_ENABLE, &io_enable);
-        }
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r == CSR_RESULT_SUCCESS)
-        {
-            u16 mbox2;
-            s16 enabled = io_enable & (1 << card->function);
-
-            if (!enabled)
-            {
-                unifi_trace(card->ospriv, UDBG1,
-                            "Reset complete (function %d is disabled) in ~ %u msecs\n",
-                            card->function, i * MAILBOX2_TIMEOUT);
-
-                /* Enable WLAN function and verify MAILBOX2 is zero'd */
-                csrResult = CsrSdioFunctionEnable(card->sdio_if);
-                if (csrResult != CSR_RESULT_SUCCESS)
-                {
-                    r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-                    unifi_error(card->ospriv, "CsrSdioFunctionEnable failed %d\n", r);
-                    break;
-                }
-            }
-
-            r = unifi_read_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, &mbox2);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "read HIP_HANDSHAKE failed %d\n", r);
-                break;
-            }
-            if (mbox2 != 0)
-            {
-                unifi_error(card->ospriv, "MAILBOX2 non-zero after reset (mbox2 = %04x)\n", mbox2);
-                r = CSR_RESULT_FAILURE;
-            }
-            break;
-        }
-        else
-        {
-            if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
-            {
-                /* We ignore read failures for the first few reads,
-                 * they are probably benign. */
-                if (i > MAILBOX2_ATTEMPTS / 4)
-                {
-                    unifi_trace(card->ospriv, UDBG1, "Failed to read CCCR IO Ready register while polling for reset\n");
-                }
-            }
-            else
-            {
-                unifi_trace(card->ospriv, UDBG1, "Failed to read CCCR IO Enable register while polling for reset\n");
-            }
-        }
-        CsrThreadSleep(MAILBOX2_TIMEOUT);
-    }
-
-    if (r == CSR_RESULT_SUCCESS && i == MAILBOX2_ATTEMPTS)
-    {
-        unifi_trace(card->ospriv, UDBG1, "Timeout waiting for UniFi to complete reset\n");
-        r = CSR_RESULT_FAILURE;
-    }
-
-    return r;
-} /* card_wait_for_unifi_to_reset() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_wait_for_unifi_to_disable
- *
- *      Waits for the function to become disabled by polling the
- *      IO_READY bit.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code on failure.
- *
- *  Notes: This function can only be used with
- *         card->chip_id > SDIO_CARD_ID_UNIFI_2
- * ---------------------------------------------------------------------------
- */
-static CsrResult card_wait_for_unifi_to_disable(card_t *card)
-{
-    s16 i;
-    CsrResult r;
-    u8 io_enable;
-    CsrResult csrResult;
-
-    if (card->chip_id <= SDIO_CARD_ID_UNIFI_2)
-    {
-        unifi_error(card->ospriv,
-                    "Function reset method not supported for chip_id=%d\n",
-                    card->chip_id);
-        return CSR_RESULT_FAILURE;
-    }
-
-    r = CSR_RESULT_SUCCESS;
-    for (i = 0; i < MAILBOX2_ATTEMPTS; i++)
-    {
-        unifi_trace(card->ospriv, UDBG1, "waiting for disable to complete, attempt %d\n", i);
-
-        /*
-         * It's quite likely that this read will timeout for the
-         * first few tries - especially if we have reset via
-         * DBG_RESET.
-         */
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        unifi_debug_log_to_buf("r0@%02X=", SDIO_IO_READY);
-#endif
-        csrResult = CsrSdioF0Read8(card->sdio_if, SDIO_IO_READY, &io_enable);
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        if (csrResult != CSR_RESULT_SUCCESS)
-        {
-            unifi_debug_log_to_buf("error=%X\n", csrResult);
-        }
-        else
-        {
-            unifi_debug_log_to_buf("%X\n", io_enable);
-        }
-#endif
-        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-        {
-            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-        }
-        if (csrResult == CSR_RESULT_SUCCESS)
-        {
-            s16 enabled = io_enable & (1 << card->function);
-            r = CSR_RESULT_SUCCESS;
-            if (!enabled)
-            {
-                unifi_trace(card->ospriv, UDBG1,
-                            "Disable complete (function %d is disabled) in ~ %u msecs\n",
-                            card->function, i * MAILBOX2_TIMEOUT);
-
-                break;
-            }
-        }
-        else
-        {
-            /*
-             * We ignore read failures for the first few reads,
-             * they are probably benign.
-             */
-            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-            if (i > (MAILBOX2_ATTEMPTS / 4))
-            {
-                unifi_trace(card->ospriv, UDBG1,
-                            "Failed to read CCCR IO Ready register while polling for disable\n");
-            }
-        }
-        CsrThreadSleep(MAILBOX2_TIMEOUT);
-    }
-
-    if ((r == CSR_RESULT_SUCCESS) && (i == MAILBOX2_ATTEMPTS))
-    {
-        unifi_trace(card->ospriv, UDBG1, "Timeout waiting for UniFi to complete disable\n");
-        r = CSR_RESULT_FAILURE;
-    }
-
-    return r;
-} /* card_wait_for_unifi_to_reset() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_wait_for_firmware_to_start
- *
- *      Polls the MAILBOX1 register for a non-zero value.
- *      Then reads MAILBOX0 and forms the two values into a 32-bit address
- *      which is returned to the caller.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      paddr           Pointer to receive the UniFi address formed
- *                      by concatenating MAILBOX1 and MAILBOX0.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code on failure.
- * ---------------------------------------------------------------------------
- */
-CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr)
-{
-    s32 i;
-    u16 mbox0, mbox1;
-    CsrResult r;
-
-    /*
-     * Wait for UniFi to initialise its data structures by polling
-     * the SHARED_MAILBOX1 register.
-     * Experience shows this is typically 120ms.
-     */
-    CsrThreadSleep(MAILBOX1_TIMEOUT);
-
-    mbox1 = 0;
-    unifi_trace(card->ospriv, UDBG1, "waiting for MAILBOX1 to be non-zero...\n");
-    for (i = 0; i < MAILBOX1_ATTEMPTS; i++)
-    {
-        r = unifi_read_direct16(card, ChipHelper_MAILBOX1(card->helper) * 2, &mbox1);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            /* These reads can fail if UniFi isn't up yet, so try again */
-            unifi_warning(card->ospriv, "Failed to read UniFi Mailbox1 register\n");
-        }
-
-        if ((r == CSR_RESULT_SUCCESS) && (mbox1 != 0))
-        {
-            unifi_trace(card->ospriv, UDBG1, "MAILBOX1 ready (0x%04X) in %u millisecs\n",
-                        mbox1, i * MAILBOX1_TIMEOUT);
-
-            /* Read the MAILBOX1 again in case we caught the value as it
-             * changed. */
-            r = unifi_read_direct16(card, ChipHelper_MAILBOX1(card->helper) * 2, &mbox1);
-            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-            {
-                return r;
-            }
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "Failed to read UniFi Mailbox1 register for second time\n");
-                return r;
-            }
-            unifi_trace(card->ospriv, UDBG1, "MAILBOX1 value=0x%04X\n", mbox1);
-
-            break;
-        }
-
-        CsrThreadSleep(MAILBOX1_TIMEOUT);
-        if ((i % 100) == 99)
-        {
-            unifi_trace(card->ospriv, UDBG2, "MAILBOX1 not ready (0x%X), still trying...\n", mbox1);
-        }
-    }
-
-    if ((r == CSR_RESULT_SUCCESS) && (mbox1 == 0))
-    {
-        unifi_trace(card->ospriv, UDBG1, "Timeout waiting for firmware to start, Mailbox1 still 0 after %d ms\n",
-                    MAILBOX1_ATTEMPTS * MAILBOX1_TIMEOUT);
-        return CSR_RESULT_FAILURE;
-    }
-
-
-    /*
-     * Complete the reset handshake by setting MAILBOX2 to 0xFFFF
-     */
-    r = unifi_write_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, 0xFFFF);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write f/w startup handshake to MAILBOX2\n");
-        return r;
-    }
-
-
-    /*
-     * Read the Symbol Look Up Table (SLUT) offset.
-     * Top 16 bits are in mbox1, read the lower 16 bits from mbox0.
-     */
-    mbox0 = 0;
-    r = unifi_read_direct16(card, ChipHelper_MAILBOX0(card->helper) * 2, &mbox0);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to read UniFi Mailbox0 register\n");
-        return r;
-    }
-
-    *paddr = (((u32)mbox1 << 16) | mbox0);
-
-    return CSR_RESULT_SUCCESS;
-} /* card_wait_for_firmware_to_start() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_capture_panic
- *
- *      Attempt to capture panic codes from the firmware. This may involve
- *      warm reset of the chip to regain access following a watchdog reset.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS if panic codes were captured, or none available
- *      CSR_RESULT_FAILURE if the driver could not access function 1
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_capture_panic(card_t *card)
-{
-
-    /* The firmware must have previously initialised to read the panic addresses
-     * from the SLUT
-     */
-    if (!card->panic_data_phy_addr || !card->panic_data_mac_addr)
-    {
-        return CSR_RESULT_SUCCESS;
-    }
-
-    /* Ensure we can access function 1 following a panic/watchdog reset */
-    if (card_access_panic(card) == CSR_RESULT_SUCCESS)
-    {
-        /* Read the panic codes */
-        unifi_read_panic(card);
-    }
-    else
-    {
-        unifi_info(card->ospriv, "Unable to read panic codes");
-    }
-
-    return CSR_RESULT_SUCCESS;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_access_panic
- *      Attempt to read the WLAN SDIO function in order to read panic codes
- *      and perform various reset steps to regain access if the read fails.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS if panic codes can be read
- *      CSR error code if panic codes can not be read
- * ---------------------------------------------------------------------------
- */
-static CsrResult card_access_panic(card_t *card)
-{
-    u16 data_u16 = 0;
-    s32 i;
-    CsrResult r, sr;
-
-    /* A chip version of zero means that the version never got successfully read
-     * during reset. In this case give up because it will not be possible to
-     * verify the chip version.
-     */
-    if (!card->chip_version)
-    {
-        unifi_info(card->ospriv, "Unknown chip version\n");
-        return CSR_RESULT_FAILURE;
-    }
-
-    /* Ensure chip is awake or access to function 1 will fail */
-    r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "unifi_set_host_state() failed %d\n", r);
-        return CSR_RESULT_FAILURE; /* Card is probably unpowered */
-    }
-    CsrThreadSleep(20);
-
-    for (i = 0; i < 3; i++)
-    {
-        sr = CsrSdioRead16(card->sdio_if, CHIP_HELPER_UNIFI_GBL_CHIP_VERSION * 2, &data_u16);
-        if (sr != CSR_RESULT_SUCCESS || data_u16 != card->chip_version)
-        {
-            unifi_info(card->ospriv, "Failed to read valid chip version sr=%d (0x%04x want 0x%04x) try %d\n",
-                       sr, data_u16, card->chip_version, i);
-
-            /* Set clock speed low */
-            sr = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_SAFE_HZ);
-            if (sr != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "CsrSdioMaxBusClockFrequencySet() failed1 %d\n", sr);
-                r = ConvertCsrSdioToCsrHipResult(card, sr);
-            }
-            card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ;
-
-            /* First try re-enabling function in case a f/w watchdog reset disabled it */
-            if (i == 0)
-            {
-                unifi_info(card->ospriv, "Try function enable\n");
-                sr = CsrSdioFunctionEnable(card->sdio_if);
-                if (sr != CSR_RESULT_SUCCESS)
-                {
-                    r = ConvertCsrSdioToCsrHipResult(card, sr);
-                    unifi_error(card->ospriv, "CsrSdioFunctionEnable failed %d (HIP %d)\n", sr, r);
-                }
-                continue;
-            }
-
-            /* Second try, set awake */
-            unifi_info(card->ospriv, "Try set awake\n");
-
-            /* Ensure chip is awake */
-            r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
-            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-            {
-                return r;
-            }
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "unifi_set_host_state() failed2 %d\n", r);
-            }
-
-            /* Set clock speed low in case setting the host state raised it, which
-             * would only happen if host state was previously TORPID
-             */
-            sr = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_SAFE_HZ);
-            if (sr != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "CsrSdioMaxBusClockFrequencySet() failed2 %d\n", sr);
-            }
-            card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ;
-
-            if (i == 1)
-            {
-                continue;
-            }
-
-            /* Perform a s/w reset to preserve as much as the card state as possible,
-             * (mainly the preserve RAM). The context will be lost for coredump - but as we
-             * were unable to access the WLAN function for panic, the coredump would have
-             * also failed without a reset.
-             */
-            unifi_info(card->ospriv, "Try s/w reset\n");
-
-            r = unifi_card_hard_reset(card);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "unifi_card_hard_reset() failed %d\n", r);
-            }
-        }
-        else
-        {
-            if (i > 0)
-            {
-                unifi_info(card->ospriv, "Read chip version 0x%x after %d retries\n", data_u16, i);
-            }
-            break;
-        }
-    }
-
-    r = ConvertCsrSdioToCsrHipResult(card, sr);
-    return r;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_read_panic
- *      Reads, saves and prints panic codes stored by the firmware in UniFi's
- *      preserve RAM by the last panic that occurred since chip was powered.
- *      Nothing is saved if the panic codes are read as zero.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- * ---------------------------------------------------------------------------
- */
-void unifi_read_panic(card_t *card)
-{
-    CsrResult r;
-    u16 p_code, p_arg;
-
-    /* The firmware must have previously initialised to read the panic addresses
-     * from the SLUT
-     */
-    if (!card->panic_data_phy_addr || !card->panic_data_mac_addr)
-    {
-        return;
-    }
-
-    /* Get the panic data from PHY */
-    r = unifi_card_read16(card, card->panic_data_phy_addr, &p_code);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_phy_addr, r);
-        p_code = 0;
-    }
-    if (p_code)
-    {
-        r = unifi_card_read16(card, card->panic_data_phy_addr + 2, &p_arg);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_phy_addr + 2, r);
-        }
-        unifi_error(card->ospriv, "Last UniFi PHY PANIC %04x arg %04x\n", p_code, p_arg);
-        card->last_phy_panic_code = p_code;
-        card->last_phy_panic_arg = p_arg;
-    }
-
-    /* Get the panic data from MAC */
-    r = unifi_card_read16(card, card->panic_data_mac_addr, &p_code);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_mac_addr, r);
-        p_code = 0;
-    }
-    if (p_code)
-    {
-        r = unifi_card_read16(card, card->panic_data_mac_addr + 2, &p_arg);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_mac_addr + 2, r);
-        }
-        unifi_error(card->ospriv, "Last UniFi MAC PANIC %04x arg %04x\n", p_code, p_arg);
-        card->last_mac_panic_code = p_code;
-        card->last_mac_panic_arg = p_arg;
-    }
-
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_allocate_memory_resources
- *
- *      Allocates memory for the from-host, to-host bulk data slots,
- *      soft queue buffers and bulk data buffers.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code on failure.
- * ---------------------------------------------------------------------------
- */
-static CsrResult card_allocate_memory_resources(card_t *card)
-{
-    s16 n, i, k, r;
-    sdio_config_data_t *cfg_data;
-
-    /* Reset any state carried forward from a previous life */
-    card->fh_command_queue.q_rd_ptr = 0;
-    card->fh_command_queue.q_wr_ptr = 0;
-    (void)scnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
-                      "fh_cmd_q");
-    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-    {
-        card->fh_traffic_queue[i].q_rd_ptr = 0;
-        card->fh_traffic_queue[i].q_wr_ptr = 0;
-        (void)scnprintf(card->fh_traffic_queue[i].name,
-                          UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
-    }
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-    unifi_ta_sampling_init(card);
-#endif
-    /* Convenience short-cut */
-    cfg_data = &card->config_data;
-
-    /*
-     * Allocate memory for the from-host and to-host signal buffers.
-     */
-    card->fh_buffer.buf = kmalloc(UNIFI_FH_BUF_SIZE, GFP_KERNEL);
-    if (card->fh_buffer.buf == NULL)
-    {
-        unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n");
-        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-    }
-    card->fh_buffer.bufsize = UNIFI_FH_BUF_SIZE;
-    card->fh_buffer.ptr = card->fh_buffer.buf;
-    card->fh_buffer.count = 0;
-
-    card->th_buffer.buf = kmalloc(UNIFI_FH_BUF_SIZE, GFP_KERNEL);
-    if (card->th_buffer.buf == NULL)
-    {
-        unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n");
-        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-    }
-    card->th_buffer.bufsize = UNIFI_FH_BUF_SIZE;
-    card->th_buffer.ptr = card->th_buffer.buf;
-    card->th_buffer.count = 0;
-
-
-    /*
-     * Allocate memory for the from-host and to-host bulk data slots.
-     * This is done as separate kmallocs because lots of smaller
-     * allocations are more likely to succeed than one huge one.
-     */
-
-    /* Allocate memory for the array of pointers */
-    n = cfg_data->num_fromhost_data_slots;
-
-    unifi_trace(card->ospriv, UDBG3, "Alloc from-host resources, %d slots.\n", n);
-    card->from_host_data = kmalloc(n * sizeof(slot_desc_t), GFP_KERNEL);
-    if (card->from_host_data == NULL)
-    {
-        unifi_error(card->ospriv, "Failed to allocate memory for F-H bulk data array\n");
-        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-    }
-
-    /* Initialise from-host bulk data slots */
-    for (i = 0; i < n; i++)
-    {
-        UNIFI_INIT_BULK_DATA(&card->from_host_data[i].bd);
-    }
-
-    /* Allocate memory for the array used for slot host tag mapping */
-    card->fh_slot_host_tag_record = kmalloc(n * sizeof(u32), GFP_KERNEL);
-
-    if (card->fh_slot_host_tag_record == NULL)
-    {
-        unifi_error(card->ospriv, "Failed to allocate memory for F-H slot host tag mapping array\n");
-        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-    }
-
-    /* Initialise host tag entries for from-host bulk data slots */
-    for (i = 0; i < n; i++)
-    {
-        card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
-    }
-
-
-    /* Allocate memory for the array of pointers */
-    n = cfg_data->num_tohost_data_slots;
-
-    unifi_trace(card->ospriv, UDBG3, "Alloc to-host resources, %d slots.\n", n);
-    card->to_host_data = kmalloc(n * sizeof(bulk_data_desc_t), GFP_KERNEL);
-    if (card->to_host_data == NULL)
-    {
-        unifi_error(card->ospriv, "Failed to allocate memory for T-H bulk data array\n");
-        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-    }
-
-    /* Initialise to-host bulk data slots */
-    for (i = 0; i < n; i++)
-    {
-        UNIFI_INIT_BULK_DATA(&card->to_host_data[i]);
-    }
-
-    /*
-     * Initialise buffers for soft Q
-     */
-    for (i = 0; i < UNIFI_SOFT_COMMAND_Q_LENGTH; i++)
-    {
-        for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++)
-        {
-            UNIFI_INIT_BULK_DATA(&card->fh_command_q_body[i].bulkdata[r]);
-        }
-    }
-
-    for (k = 0; k < UNIFI_NO_OF_TX_QS; k++)
-    {
-        for (i = 0; i < UNIFI_SOFT_TRAFFIC_Q_LENGTH; i++)
-        {
-            for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++)
-            {
-                UNIFI_INIT_BULK_DATA(&card->fh_traffic_q_body[k][i].bulkdata[r]);
-            }
-        }
-    }
-
-    card->memory_resources_allocated = 1;
-
-    return CSR_RESULT_SUCCESS;
-} /* card_allocate_memory_resources() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_free_bulk_data
- *
- *      Free the data associated to a bulk data structure.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      bulk_data_slot  Pointer to bulk data structure
- *
- *  Returns:
- *      None.
- *
- * ---------------------------------------------------------------------------
- */
-static void unifi_free_bulk_data(card_t *card, bulk_data_desc_t *bulk_data_slot)
-{
-    if (bulk_data_slot->data_length != 0)
-    {
-        unifi_net_data_free(card->ospriv, bulk_data_slot);
-    }
-} /* unifi_free_bulk_data() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_free_memory_resources
- *
- *      Frees memory allocated for the from-host, to-host bulk data slots,
- *      soft queue buffers and bulk data buffers.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void card_free_memory_resources(card_t *card)
-{
-
-    unifi_trace(card->ospriv, UDBG1, "Freeing card memory resources.\n");
-
-    /* Clear our internal queues */
-    unifi_cancel_pending_signals(card);
-
-
-    kfree(card->to_host_data);
-    card->to_host_data = NULL;
-
-    kfree(card->from_host_data);
-    card->from_host_data = NULL;
-
-    /* free the memory for slot host tag mapping array */
-    kfree(card->fh_slot_host_tag_record);
-    card->fh_slot_host_tag_record = NULL;
-
-    kfree(card->fh_buffer.buf);
-    card->fh_buffer.ptr = card->fh_buffer.buf = NULL;
-    card->fh_buffer.bufsize = 0;
-    card->fh_buffer.count = 0;
-
-    kfree(card->th_buffer.buf);
-    card->th_buffer.ptr = card->th_buffer.buf = NULL;
-    card->th_buffer.bufsize = 0;
-    card->th_buffer.count = 0;
-
-
-    card->memory_resources_allocated = 0;
-
-} /* card_free_memory_resources() */
-
-
-static void card_init_soft_queues(card_t *card)
-{
-    s16 i;
-
-    unifi_trace(card->ospriv, UDBG1, "Initialising internal signal queues.\n");
-    /* Reset any state carried forward from a previous life */
-    card->fh_command_queue.q_rd_ptr = 0;
-    card->fh_command_queue.q_wr_ptr = 0;
-    (void)scnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
-                      "fh_cmd_q");
-    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-    {
-        card->fh_traffic_queue[i].q_rd_ptr = 0;
-        card->fh_traffic_queue[i].q_wr_ptr = 0;
-        (void)scnprintf(card->fh_traffic_queue[i].name,
-                          UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
-    }
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-    unifi_ta_sampling_init(card);
-#endif
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_cancel_pending_signals
- *
- *      Free the signals and associated bulk data, pending in the core.
- *
- *  Arguments:
- *      card        Pointer to card struct
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void unifi_cancel_pending_signals(card_t *card)
-{
-    s16 i, n, r;
-
-    unifi_trace(card->ospriv, UDBG1, "Canceling pending signals.\n");
-
-    if (card->to_host_data)
-    {
-        /*
-         * Free any bulk data buffers allocated for the t-h slots
-         * This will clear all buffers that did not make it to
-         * unifi_receive_event() before cancel was request.
-         */
-        n = card->config_data.num_tohost_data_slots;
-        unifi_trace(card->ospriv, UDBG3, "Freeing to-host resources, %d slots.\n", n);
-        for (i = 0; i < n; i++)
-        {
-            unifi_free_bulk_data(card, &card->to_host_data[i]);
-        }
-    }
-
-    /*
-     * If any of the from-host bulk data has reached the card->from_host_data
-     * but not UniFi, we need to free the buffers here.
-     */
-    if (card->from_host_data)
-    {
-        /* Free any bulk data buffers allocated for the f-h slots */
-        n = card->config_data.num_fromhost_data_slots;
-        unifi_trace(card->ospriv, UDBG3, "Freeing from-host resources, %d slots.\n", n);
-        for (i = 0; i < n; i++)
-        {
-            unifi_free_bulk_data(card, &card->from_host_data[i].bd);
-        }
-
-        for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-        {
-            card->dynamic_slot_data.from_host_used_slots[i] = 0;
-            card->dynamic_slot_data.from_host_max_slots[i] = 0;
-            card->dynamic_slot_data.from_host_reserved_slots[i] = 0;
-        }
-    }
-
-    /*
-     * Free any bulk data buffers allocated in the soft queues.
-     * This covers the case where a bulk data pointer has reached the soft queue
-     * but not the card->from_host_data.
-     */
-    unifi_trace(card->ospriv, UDBG3, "Freeing cmd q resources.\n");
-    for (i = 0; i < UNIFI_SOFT_COMMAND_Q_LENGTH; i++)
-    {
-        for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++)
-        {
-            unifi_free_bulk_data(card, &card->fh_command_q_body[i].bulkdata[r]);
-        }
-    }
-
-    unifi_trace(card->ospriv, UDBG3, "Freeing traffic q resources.\n");
-    for (n = 0; n < UNIFI_NO_OF_TX_QS; n++)
-    {
-        for (i = 0; i < UNIFI_SOFT_TRAFFIC_Q_LENGTH; i++)
-        {
-            for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++)
-            {
-                unifi_free_bulk_data(card, &card->fh_traffic_q_body[n][i].bulkdata[r]);
-            }
-        }
-    }
-
-    card_init_soft_queues(card);
-
-} /* unifi_cancel_pending_signals() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_free_card
- *
- *      Free the memory allocated for the card structure and buffers.
- *
- *  Notes:
- *      The porting layer is responsible for freeing any mini-coredump buffers
- *      allocated when it called unifi_coredump_init(), by calling
- *      unifi_coredump_free() before calling this function.
- *
- *  Arguments:
- *      card        Pointer to card struct
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void unifi_free_card(card_t *card)
-{
-#ifdef CSR_PRE_ALLOC_NET_DATA
-    prealloc_netdata_free(card);
-#endif
-    /* Free any memory allocated. */
-    card_free_memory_resources(card);
-
-    /* Warn if caller didn't free coredump buffers */
-    if (card->dump_buf)
-    {
-        unifi_error(card->ospriv, "Caller should call unifi_coredump_free()\n");
-        unifi_coredump_free(card); /* free anyway to prevent memory leak */
-    }
-
-    kfree(card);
-
-} /* unifi_free_card() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_init_slots
- *
- *      Allocate memory for host-side slot data and signal queues.
- *
- * Arguments:
- *      card            Pointer to card object
- *
- * Returns:
- *      CSR error code.
- * ---------------------------------------------------------------------------
- */
-static CsrResult card_init_slots(card_t *card)
-{
-    CsrResult r;
-    u8 i;
-
-    /* Allocate the buffers we need, only once. */
-    if (card->memory_resources_allocated == 1)
-    {
-        card_free_memory_resources(card);
-    }
-    else
-    {
-        /* Initialise our internal command and traffic queues */
-        card_init_soft_queues(card);
-    }
-
-    r = card_allocate_memory_resources(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to allocate card memory resources.\n");
-        card_free_memory_resources(card);
-        return r;
-    }
-
-    if (card->sdio_ctrl_addr == 0)
-    {
-        unifi_error(card->ospriv, "Failed to find config struct!\n");
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    /*
-     * Set initial counts.
-     */
-
-    card->from_host_data_head = 0;
-
-    /* Get initial signal counts from UniFi, in case it has not been reset. */
-    {
-        u16 s;
-
-        /* Get the from-host-signals-written count */
-        r = unifi_card_read16(card, card->sdio_ctrl_addr + 0, &s);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to read from-host sig written count\n");
-            return r;
-        }
-        card->from_host_signals_w = (s16)s;
-
-        /* Get the to-host-signals-written count */
-        r = unifi_card_read16(card, card->sdio_ctrl_addr + 6, &s);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to read to-host sig read count\n");
-            return r;
-        }
-        card->to_host_signals_r = (s16)s;
-    }
-
-    /* Set Initialised flag. */
-    r = unifi_card_write16(card, card->init_flag_addr, 0x0001);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write initialised flag\n");
-        return r;
-    }
-
-    /* Dynamic queue reservation */
-    memset(&card->dynamic_slot_data, 0, sizeof(card_dynamic_slot_t));
-
-    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-    {
-        card->dynamic_slot_data.from_host_max_slots[i] = card->config_data.num_fromhost_data_slots -
-                                                         UNIFI_RESERVED_COMMAND_SLOTS;
-        card->dynamic_slot_data.queue_stable[i] = FALSE;
-    }
-
-    card->dynamic_slot_data.packets_interval = UNIFI_PACKETS_INTERVAL;
-
-    return CSR_RESULT_SUCCESS;
-} /* card_init_slots() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_set_udi_hook
- *
- *      Registers the udi hook that reports the sent signals to the core.
- *
- *  Arguments:
- *      card            Pointer to the card context struct
- *      udi_fn          Pointer to the callback function.
- *
- *  Returns:
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE if the card pointer is invalid,
- *      CSR_RESULT_SUCCESS on success.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_set_udi_hook(card_t *card, udi_func_t udi_fn)
-{
-    if (card == NULL)
-    {
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    if (card->udi_hook == NULL)
-    {
-        card->udi_hook = udi_fn;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_set_udi_hook() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_remove_udi_hook
- *
- *      Removes the udi hook that reports the sent signals from the core.
- *
- *  Arguments:
- *      card            Pointer to the card context struct
- *      udi_fn          Pointer to the callback function.
- *
- *  Returns:
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE if the card pointer is invalid,
- *      CSR_RESULT_SUCCESS on success.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_remove_udi_hook(card_t *card, udi_func_t udi_fn)
-{
-    if (card == NULL)
-    {
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    if (card->udi_hook == udi_fn)
-    {
-        card->udi_hook = NULL;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_remove_udi_hook() */
-
-
-static void CardReassignDynamicReservation(card_t *card)
-{
-    u8 i;
-
-    unifi_trace(card->ospriv, UDBG5, "Packets Txed %d %d %d %d\n",
-                card->dynamic_slot_data.packets_txed[0],
-                card->dynamic_slot_data.packets_txed[1],
-                card->dynamic_slot_data.packets_txed[2],
-                card->dynamic_slot_data.packets_txed[3]);
-
-    /* Clear reservation and recalculate max slots */
-    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-    {
-        card->dynamic_slot_data.queue_stable[i] = FALSE;
-        card->dynamic_slot_data.from_host_reserved_slots[i] = 0;
-        card->dynamic_slot_data.from_host_max_slots[i] = card->config_data.num_fromhost_data_slots -
-                                                         UNIFI_RESERVED_COMMAND_SLOTS;
-        card->dynamic_slot_data.packets_txed[i] = 0;
-
-        unifi_trace(card->ospriv, UDBG5, "CardReassignDynamicReservation: queue %d reserved %d Max %d\n", i,
-                    card->dynamic_slot_data.from_host_reserved_slots[i],
-                    card->dynamic_slot_data.from_host_max_slots[i]);
-    }
-
-    card->dynamic_slot_data.total_packets_txed = 0;
-}
-
-
-/* Algorithm to dynamically reserve slots. The logic is based mainly on the outstanding queue
- * length. Slots are reserved for particular queues during an interval and cleared after the interval.
- * Each queue has three associated variables.. a) used slots - the number of slots currently occupied
- * by the queue b) reserved slots - number of slots reserved specifically for the queue c) max slots - total
- * slots that this queue can actually use (may be higher than reserved slots and is dependent on reserved slots
- * for other queues).
- * This function is called when there are no slots available for a queue. It checks to see if there are enough
- * unreserved slots sufficient for this request. If available these slots are reserved for the queue.
- * If there are not enough unreserved slots, a fair share for each queue is calculated based on the total slots
- * and the number of active queues (any queue with existing reservation is considered active). Queues needing
- * less than their fair share are allowed to have the previously reserved slots. The remaining slots are
- * distributed evenly among queues that need more than the fair share
- *
- * A better scheme would take current bandwidth per AC into consideration when reserving slots. An
- * implementation scheme could consider the relative time/service period for slots in an AC. If the firmware
- * services other ACs faster than a particular AC (packets wait in the slots longer) then it is fair to reserve
- * less slots for the AC
- */
-static void CardCheckDynamicReservation(card_t *card, unifi_TrafficQueue queue)
-{
-    u16 q_len, active_queues = 0, excess_queue_slots, div_extra_slots,
-              queue_fair_share, reserved_slots = 0, q, excess_need_queues = 0, unmovable_slots = 0;
-    s32 i;
-    q_t *sigq;
-    u16 num_data_slots = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS;
-
-    /* Calculate the pending queue length */
-    sigq = &card->fh_traffic_queue[queue];
-    q_len = CSR_WIFI_HIP_Q_SLOTS_USED(sigq);
-
-    if (q_len <= card->dynamic_slot_data.from_host_reserved_slots[queue])
-    {
-        unifi_trace(card->ospriv, UDBG5, "queue %d q_len %d already has that many reserved slots, exiting\n", queue, q_len);
-        return;
-    }
-
-    /* Upper limit */
-    if (q_len > num_data_slots)
-    {
-        q_len = num_data_slots;
-    }
-
-    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-    {
-        if (i != (s32)queue)
-        {
-            reserved_slots += card->dynamic_slot_data.from_host_reserved_slots[i];
-        }
-        if ((i == (s32)queue) || (card->dynamic_slot_data.from_host_reserved_slots[i] > 0))
-        {
-            active_queues++;
-        }
-    }
-
-    unifi_trace(card->ospriv, UDBG5, "CardCheckDynamicReservation: queue %d q_len %d\n", queue, q_len);
-    unifi_trace(card->ospriv, UDBG5, "Active queues %d reserved slots on other queues %d\n",
-                active_queues, reserved_slots);
-
-    if (reserved_slots + q_len <= num_data_slots)
-    {
-        card->dynamic_slot_data.from_host_reserved_slots[queue] = q_len;
-        if (q_len == num_data_slots)
-        {
-            /* This is the common case when just 1 stream is going */
-            card->dynamic_slot_data.queue_stable[queue] = TRUE;
-        }
-    }
-    else
-    {
-        queue_fair_share = num_data_slots / active_queues;
-        unifi_trace(card->ospriv, UDBG5, "queue fair share %d\n", queue_fair_share);
-
-        /* Evenly distribute slots among active queues */
-        /* Find out the queues that need excess of fair share. Also find slots allocated
-         * to queues less than their fair share, these slots cannot be reallocated (unmovable slots) */
-
-        card->dynamic_slot_data.from_host_reserved_slots[queue] = q_len;
-
-        for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-        {
-            if (card->dynamic_slot_data.from_host_reserved_slots[i] > queue_fair_share)
-            {
-                excess_need_queues++;
-            }
-            else
-            {
-                unmovable_slots += card->dynamic_slot_data.from_host_reserved_slots[i];
-            }
-        }
-
-        unifi_trace(card->ospriv, UDBG5, "Excess need queues %d\n", excess_need_queues);
-
-        /* Now find the slots per excess demand queue */
-        excess_queue_slots = (num_data_slots - unmovable_slots) / excess_need_queues;
-        div_extra_slots = (num_data_slots - unmovable_slots) - excess_queue_slots * excess_need_queues;
-        for (i = UNIFI_NO_OF_TX_QS - 1; i >= 0; i--)
-        {
-            if (card->dynamic_slot_data.from_host_reserved_slots[i] > excess_queue_slots)
-            {
-                card->dynamic_slot_data.from_host_reserved_slots[i] = excess_queue_slots;
-                if (div_extra_slots > 0)
-                {
-                    card->dynamic_slot_data.from_host_reserved_slots[i]++;
-                    div_extra_slots--;
-                }
-                /* No more slots will be allocated to this queue during the current interval */
-                card->dynamic_slot_data.queue_stable[i] = TRUE;
-                unifi_trace(card->ospriv, UDBG5, "queue stable %d\n", i);
-            }
-        }
-    }
-
-    /* Redistribute max slots */
-    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-    {
-        reserved_slots = 0;
-        for (q = 0; q < UNIFI_NO_OF_TX_QS; q++)
-        {
-            if (i != q)
-            {
-                reserved_slots += card->dynamic_slot_data.from_host_reserved_slots[q];
-            }
-        }
-
-        card->dynamic_slot_data.from_host_max_slots[i] = num_data_slots - reserved_slots;
-        unifi_trace(card->ospriv, UDBG5, "queue %d reserved %d Max %d\n", i,
-                    card->dynamic_slot_data.from_host_reserved_slots[i],
-                    card->dynamic_slot_data.from_host_max_slots[i]);
-    }
-
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CardClearFromHostDataSlot
- *
- *      Clear a the given data slot, making it available again.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *      slot            Index of the signal slot to clear.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void CardClearFromHostDataSlot(card_t *card, const s16 slot)
-{
-    u8 queue = card->from_host_data[slot].queue;
-    const void *os_data_ptr = card->from_host_data[slot].bd.os_data_ptr;
-
-    if (card->from_host_data[slot].bd.data_length == 0)
-    {
-        unifi_warning(card->ospriv,
-                      "Surprise: request to clear an already free FH data slot: %d\n",
-                      slot);
-        return;
-    }
-
-    if (os_data_ptr == NULL)
-    {
-        unifi_warning(card->ospriv,
-                      "Clearing FH data slot %d: has null payload, len=%d\n",
-                      slot, card->from_host_data[slot].bd.data_length);
-    }
-
-    /* Free card->from_host_data[slot].bd.os_net_ptr here. */
-    /* Mark slot as free by setting length to 0. */
-    unifi_free_bulk_data(card, &card->from_host_data[slot].bd);
-    if (queue < UNIFI_NO_OF_TX_QS)
-    {
-        if (card->dynamic_slot_data.from_host_used_slots[queue] == 0)
-        {
-            unifi_error(card->ospriv, "Goofed up used slots q = %d used slots = %d\n",
-                        queue,
-                        card->dynamic_slot_data.from_host_used_slots[queue]);
-        }
-        else
-        {
-            card->dynamic_slot_data.from_host_used_slots[queue]--;
-        }
-        card->dynamic_slot_data.packets_txed[queue]++;
-        card->dynamic_slot_data.total_packets_txed++;
-        if (card->dynamic_slot_data.total_packets_txed >= card->dynamic_slot_data.packets_interval)
-        {
-            CardReassignDynamicReservation(card);
-        }
-    }
-
-    unifi_trace(card->ospriv, UDBG4, "CardClearFromHostDataSlot: slot %d recycled %p\n", slot, os_data_ptr);
-
-} /* CardClearFromHostDataSlot() */
-
-
-#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
-/*
- * ---------------------------------------------------------------------------
- *  CardClearFromHostDataSlotWithoutFreeingBulkData
- *
- *      Clear the given data slot with out freeing the bulk data.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *      slot            Index of the signal slot to clear.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void CardClearFromHostDataSlotWithoutFreeingBulkData(card_t *card, const s16 slot)
-{
-    u8 queue = card->from_host_data[slot].queue;
-
-    /* Initialise the from_host data slot so it can be re-used,
-     * Set length field in from_host_data array to 0.
-     */
-    UNIFI_INIT_BULK_DATA(&card->from_host_data[slot].bd);
-
-    queue = card->from_host_data[slot].queue;
-
-    if (queue < UNIFI_NO_OF_TX_QS)
-    {
-        if (card->dynamic_slot_data.from_host_used_slots[queue] == 0)
-        {
-            unifi_error(card->ospriv, "Goofed up used slots q = %d used slots = %d\n",
-                        queue,
-                        card->dynamic_slot_data.from_host_used_slots[queue]);
-        }
-        else
-        {
-            card->dynamic_slot_data.from_host_used_slots[queue]--;
-        }
-        card->dynamic_slot_data.packets_txed[queue]++;
-        card->dynamic_slot_data.total_packets_txed++;
-        if (card->dynamic_slot_data.total_packets_txed >=
-            card->dynamic_slot_data.packets_interval)
-        {
-            CardReassignDynamicReservation(card);
-        }
-    }
-} /* CardClearFromHostDataSlotWithoutFreeingBulkData() */
-
-
-#endif
-
-u16 CardGetDataSlotSize(card_t *card)
-{
-    return card->config_data.data_slot_size;
-} /* CardGetDataSlotSize() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CardGetFreeFromHostDataSlots
- *
- *      Retrieve the number of from-host bulk data slots available.
- *
- *  Arguments:
- *      card            Pointer to the card context struct
- *
- *  Returns:
- *      Number of free from-host bulk data slots.
- * ---------------------------------------------------------------------------
- */
-u16 CardGetFreeFromHostDataSlots(card_t *card)
-{
-    u16 i, n = 0;
-
-    /* First two slots reserved for MLME */
-    for (i = 0; i < card->config_data.num_fromhost_data_slots; i++)
-    {
-        if (card->from_host_data[i].bd.data_length == 0)
-        {
-            /* Free slot */
-            n++;
-        }
-    }
-
-    return n;
-} /* CardGetFreeFromHostDataSlots() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CardAreAllFromHostDataSlotsEmpty
- *
- *      Returns the state of from-host bulk data slots.
- *
- *  Arguments:
- *      card            Pointer to the card context struct
- *
- *  Returns:
- *      1       The from-host bulk data slots are all empty (available).
- *      0       Some or all the from-host bulk data slots are in use.
- * ---------------------------------------------------------------------------
- */
-u16 CardAreAllFromHostDataSlotsEmpty(card_t *card)
-{
-    u16 i;
-
-    for (i = 0; i < card->config_data.num_fromhost_data_slots; i++)
-    {
-        if (card->from_host_data[i].bd.data_length != 0)
-        {
-            return 0;
-        }
-    }
-
-    return 1;
-} /* CardGetFreeFromHostDataSlots() */
-
-
-static CsrResult unifi_identify_hw(card_t *card)
-{
-
-    card->chip_id = card->sdio_if->sdioId.cardId;
-    card->function = card->sdio_if->sdioId.sdioFunction;
-    card->sdio_io_block_size = card->sdio_if->blockSize;
-
-    /* If SDIO controller doesn't support byte mode CMD53, pad transfers to block sizes */
-    card->sdio_io_block_pad = (card->sdio_if->features & CSR_SDIO_FEATURE_BYTE_MODE)?FALSE : TRUE;
-
-    /*
-     * Setup the chip helper so that we can access the registers (and
-     * also tell what sub-type of HIP we should use).
-     */
-    card->helper = ChipHelper_GetVersionSdio((u8)card->chip_id);
-    if (!card->helper)
-    {
-        unifi_error(card->ospriv, "Null ChipHelper\n");
-    }
-
-    unifi_info(card->ospriv, "Chip ID 0x%02X  Function %u  Block Size %u  Name %s(%s)\n",
-               card->chip_id, card->function, card->sdio_io_block_size,
-               ChipHelper_MarketingName(card->helper),
-               ChipHelper_FriendlyName(card->helper));
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_identify_hw() */
-
-
-static CsrResult unifi_prepare_hw(card_t *card)
-{
-    CsrResult r;
-    CsrResult csrResult;
-    enum unifi_host_state old_state = card->host_state;
-
-    r = unifi_identify_hw(card);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to identify hw\n");
-        return r;
-    }
-
-    unifi_trace(card->ospriv, UDBG1,
-                "%s mode SDIO\n", card->sdio_io_block_pad?"Block" : "Byte");
-    /*
-     * Chip must be a awake or blocks that are asleep may not get
-     * reset.  We can only do this after we have read the chip_id.
-     */
-    r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-
-    if (old_state == UNIFI_HOST_STATE_TORPID)
-    {
-        /* Ensure the initial clock rate is set; if a reset occurred when the chip was
-         * TORPID, unifi_set_host_state() may have raised it to MAX.
-         */
-        csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ);
-        if (csrResult != CSR_RESULT_SUCCESS)
-        {
-            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-            return r;
-        }
-        card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;
-    }
-
-    /*
-     * The WLAN function must be enabled to access MAILBOX2 and DEBUG_RST
-     * registers.
-     */
-    csrResult = CsrSdioFunctionEnable(card->sdio_if);
-    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-    {
-        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-    }
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-        /* Can't enable WLAN function. Try resetting the SDIO block. */
-        unifi_error(card->ospriv, "Failed to re-enable function %d.\n", card->function);
-        return r;
-    }
-
-    /*
-     * Poke some registers to make sure the PLL has started,
-     * otherwise memory accesses are likely to fail.
-     */
-    bootstrap_chip_hw(card);
-
-    /* Try to read the chip version from register. */
-    r = unifi_read_chip_version(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_prepare_hw() */
-
-
-static CsrResult unifi_read_chip_version(card_t *card)
-{
-    u32 gbl_chip_version;
-    CsrResult r;
-    u16 ver;
-
-    gbl_chip_version = ChipHelper_GBL_CHIP_VERSION(card->helper);
-
-    /* Try to read the chip version from register. */
-    if (gbl_chip_version != 0)
-    {
-        r = unifi_read_direct16(card, gbl_chip_version * 2, &ver);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to read GBL_CHIP_VERSION\n");
-            return r;
-        }
-        card->chip_version = ver;
-    }
-    else
-    {
-        unifi_info(card->ospriv, "Unknown Chip ID, cannot locate GBL_CHIP_VERSION\n");
-        r = CSR_RESULT_FAILURE;
-    }
-
-    unifi_info(card->ospriv, "Chip Version 0x%04X\n", card->chip_version);
-
-    return r;
-} /* unifi_read_chip_version() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_reset_hardware
- *
- *      Execute the UniFi reset sequence.
- *
- *      Note: This may fail if the chip is going TORPID so retry at
- *      least once.
- *
- *  Arguments:
- *      card - pointer to card context structure
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error otherwise.
- *
- *  Notes:
- *      Some platforms (e.g. Windows Vista) do not allow access to registers
- *      that are necessary for a software soft reset.
- * ---------------------------------------------------------------------------
- */
-static CsrResult unifi_reset_hardware(card_t *card)
-{
-    CsrResult r;
-    u16 new_block_size = UNIFI_IO_BLOCK_SIZE;
-    CsrResult csrResult;
-
-    /* Errors returned by unifi_prepare_hw() are not critical at this point */
-    r = unifi_prepare_hw(card);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-
-    /* First try SDIO controller reset, which may power cycle the UniFi, assert
-     * its reset line, or not be implemented depending on the platform.
-     */
-    unifi_info(card->ospriv, "Calling CsrSdioHardReset\n");
-    csrResult = CsrSdioHardReset(card->sdio_if);
-    if (csrResult == CSR_RESULT_SUCCESS)
-    {
-        unifi_info(card->ospriv, "CsrSdioHardReset succeeded on resetting UniFi\n");
-        r = unifi_prepare_hw(card);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "unifi_prepare_hw failed after hard reset\n");
-            return r;
-        }
-    }
-    else if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-    {
-        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-    }
-    else
-    {
-        /* Falling back to software hard reset methods */
-        unifi_info(card->ospriv, "Falling back to software hard reset\n");
-        r = unifi_card_hard_reset(card);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "software hard reset failed\n");
-            return r;
-        }
-
-        /* If we fell back to unifi_card_hard_reset() methods, chip version may
-         * not have been read. (Note in the unlikely event that it is zero,
-         * it will be harmlessly read again)
-         */
-        if (card->chip_version == 0)
-        {
-            r = unifi_read_chip_version(card);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-        }
-    }
-
-#ifdef CSR_WIFI_HIP_SDIO_BLOCK_SIZE
-    new_block_size = CSR_WIFI_HIP_SDIO_BLOCK_SIZE;
-#endif
-
-    /* After hard reset, we need to restore the SDIO block size */
-    csrResult = CsrSdioBlockSizeSet(card->sdio_if, new_block_size);
-    r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-
-    /* Warn if a different block size was achieved by the transport */
-    if (card->sdio_if->blockSize != new_block_size)
-    {
-        unifi_info(card->ospriv,
-                   "Actually got block size %d\n", card->sdio_if->blockSize);
-    }
-
-    /* sdio_io_block_size always needs be updated from the achieved block size,
-     * as it is used by the OS layer to allocate memory in unifi_net_malloc().
-     * Controllers which don't support block mode (e.g. CSPI) will report a
-     * block size of zero.
-     */
-    if (card->sdio_if->blockSize == 0)
-    {
-        unifi_info(card->ospriv, "Block size 0, block mode not available\n");
-
-        /* Set sdio_io_block_size to 1 so that unifi_net_data_malloc() has a
-         * sensible rounding value. Elsewhere padding will already be
-         * disabled because the controller supports byte mode.
-         */
-        card->sdio_io_block_size = 1;
-
-        /* Controller features must declare support for byte mode */
-        if (!(card->sdio_if->features & CSR_SDIO_FEATURE_BYTE_MODE))
-        {
-            unifi_error(card->ospriv, "Requires byte mode\n");
-            r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-        }
-    }
-    else
-    {
-        /* Padding will be enabled if CSR_SDIO_FEATURE_BYTE_MODE isn't set */
-        card->sdio_io_block_size = card->sdio_if->blockSize;
-    }
-
-
-    return r;
-} /* unifi_reset_hardware() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_reset_method_io_enable
- *
- *      Issue a hard reset to the hw writing the IO_ENABLE.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *
- *  Returns:
- *      0 on success,
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE   if the card was ejected
- *      CSR_RESULT_FAILURE         if an SDIO error occurred or if a response
- *                                 was not seen in the expected time
- * ---------------------------------------------------------------------------
- */
-static CsrResult card_reset_method_io_enable(card_t *card)
-{
-    CsrResult r;
-    CsrResult csrResult;
-
-    /*
-     * This resets only function 1, so should be used in
-     * preference to the method below (CSR_FUNC_EN)
-     */
-    unifi_trace(card->ospriv, UDBG1, "Hard reset (IO_ENABLE)\n");
-
-    csrResult = CsrSdioFunctionDisable(card->sdio_if);
-    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-    {
-        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-    }
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-        unifi_warning(card->ospriv, "SDIO error writing IO_ENABLE: %d\n", r);
-    }
-    else
-    {
-        /* Delay here to let the reset take affect. */
-        CsrThreadSleep(RESET_SETTLE_DELAY);
-
-        r = card_wait_for_unifi_to_disable(card);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-
-        if (r == CSR_RESULT_SUCCESS)
-        {
-            r = card_wait_for_unifi_to_reset(card);
-            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-            {
-                return r;
-            }
-        }
-    }
-
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_trace(card->ospriv, UDBG1, "Hard reset (CSR_FUNC_EN)\n");
-
-        r = sdio_write_f0(card, SDIO_CSR_FUNC_EN, 0);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_warning(card->ospriv, "SDIO error writing SDIO_CSR_FUNC_EN: %d\n", r);
-            return r;
-        }
-        else
-        {
-            /* Delay here to let the reset take affect. */
-            CsrThreadSleep(RESET_SETTLE_DELAY);
-
-            r = card_wait_for_unifi_to_reset(card);
-            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-            {
-                return r;
-            }
-        }
-    }
-
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_warning(card->ospriv, "card_reset_method_io_enable failed to reset UniFi\n");
-    }
-
-    return r;
-} /* card_reset_method_io_enable() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_reset_method_dbg_reset
- *
- *      Issue a hard reset to the hw writing the DBG_RESET.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS         on success,
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE   if the card was ejected
- *      CSR_RESULT_FAILURE         if an SDIO error occurred or if a response
- *                                 was not seen in the expected time
- * ---------------------------------------------------------------------------
- */
-static CsrResult card_reset_method_dbg_reset(card_t *card)
-{
-    CsrResult r;
-
-    /*
-     * Prepare UniFi for h/w reset
-     */
-    if (card->host_state == UNIFI_HOST_STATE_TORPID)
-    {
-        r = unifi_set_host_state(card, UNIFI_HOST_STATE_DROWSY);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to set UNIFI_HOST_STATE_DROWSY\n");
-            return r;
-        }
-        CsrThreadSleep(5);
-    }
-
-    r = unifi_card_stop_processor(card, UNIFI_PROC_BOTH);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Can't stop processors\n");
-        return r;
-    }
-
-    unifi_trace(card->ospriv, UDBG1, "Hard reset (DBG_RESET)\n");
-
-    /*
-     * This register write may fail. The debug reset resets
-     * parts of the Function 0 sections of the chip, and
-     * therefore the response cannot be sent back to the host.
-     */
-    r = unifi_write_direct_8_or_16(card, ChipHelper_DBG_RESET(card->helper) * 2, 1);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_warning(card->ospriv, "SDIO error writing DBG_RESET: %d\n", r);
-        return r;
-    }
-
-    /* Delay here to let the reset take affect. */
-    CsrThreadSleep(RESET_SETTLE_DELAY);
-
-    r = card_wait_for_unifi_to_reset(card);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_warning(card->ospriv, "card_reset_method_dbg_reset failed to reset UniFi\n");
-    }
-
-    return r;
-} /* card_reset_method_dbg_reset() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_card_hard_reset
- *
- *      Issue reset to hardware, by writing to registers on the card.
- *      Power to the card is preserved.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS         on success,
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE   if the card was ejected
- *      CSR_RESULT_FAILURE         if an SDIO error occurred or if a response
- *                                 was not seen in the expected time
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_card_hard_reset(card_t *card)
-{
-    CsrResult r;
-    const struct chip_helper_reset_values *init_data;
-    u32 chunks;
-
-    /* Clear cache of page registers */
-    card->proc_select = (u32)(-1);
-    card->dmem_page = (u32)(-1);
-    card->pmem_page = (u32)(-1);
-
-    /*
-     * We need to have a valid card->helper before we use software hard reset.
-     * If unifi_identify_hw() fails to get the card ID, it probably means
-     * that there is no way to talk to the h/w.
-     */
-    r = unifi_identify_hw(card);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "unifi_card_hard_reset failed to identify h/w\n");
-        return r;
-    }
-
-    /* Search for some reset code. */
-    chunks = ChipHelper_HostResetSequence(card->helper, &init_data);
-    if (chunks != 0)
-    {
-        unifi_error(card->ospriv,
-                    "Hard reset (Code download) is unsupported\n");
-
-        return CSR_RESULT_FAILURE;
-    }
-
-    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
-    {
-        /* The HIP spec considers this a bus-specific reset.
-         * This resets only function 1, so should be used in
-         * preference to the method below (CSR_FUNC_EN)
-         * If this method fails, it means that the f/w is probably
-         * not running. In this case, try the DBG_RESET method.
-         */
-        r = card_reset_method_io_enable(card);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r == CSR_RESULT_SUCCESS)
-        {
-            return r;
-        }
-    }
-
-    /* Software hard reset */
-    r = card_reset_method_dbg_reset(card);
-
-    return r;
-} /* unifi_card_hard_reset() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *
- *  CardGenInt
- *
- *      Prod the card.
- *      This function causes an internal interrupt to be raised in the
- *      UniFi chip. It is used to signal the firmware that some action has
- *      been completed.
- *      The UniFi Host Interface asks that the value used increments for
- *      debugging purposes.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS         on success,
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE   if the card was ejected
- *      CSR_RESULT_FAILURE         if an SDIO error occurred or if a response
- *                                 was not seen in the expected time
- * ---------------------------------------------------------------------------
- */
-CsrResult CardGenInt(card_t *card)
-{
-    CsrResult r;
-
-    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
-    {
-        r = sdio_write_f0(card, SDIO_CSR_FROM_HOST_SCRATCH0,
-                          (u8)card->unifi_interrupt_seq);
-    }
-    else
-    {
-        r = unifi_write_direct_8_or_16(card,
-                                       ChipHelper_SHARED_IO_INTERRUPT(card->helper) * 2,
-                                       (u8)card->unifi_interrupt_seq);
-    }
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "SDIO error writing UNIFI_SHARED_IO_INTERRUPT: %d\n", r);
-        return r;
-    }
-
-    card->unifi_interrupt_seq++;
-
-    return CSR_RESULT_SUCCESS;
-} /* CardGenInt() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CardEnableInt
- *
- *      Enable the outgoing SDIO interrupt from UniFi to the host.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS            on success,
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
- *      CSR_RESULT_FAILURE            if an SDIO error occurred,
- * ---------------------------------------------------------------------------
- */
-CsrResult CardEnableInt(card_t *card)
-{
-    CsrResult r;
-    u8 int_enable;
-
-    r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n");
-        return r;
-    }
-
-    int_enable |= (1 << card->function) | UNIFI_SD_INT_ENABLE_IENM;
-
-    r = sdio_write_f0(card, SDIO_INT_ENABLE, int_enable);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "SDIO error writing SDIO_INT_ENABLE\n");
-        return r;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* CardEnableInt() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CardDisableInt
- *
- *      Disable the outgoing SDIO interrupt from UniFi to the host.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS            on success,
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
- *      CSR_RESULT_FAILURE            if an SDIO error occurred,
- * ---------------------------------------------------------------------------
- */
-CsrResult CardDisableInt(card_t *card)
-{
-    CsrResult r;
-    u8 int_enable;
-
-    r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n");
-        return r;
-    }
-
-    int_enable &= ~(1 << card->function);
-
-    r = sdio_write_f0(card, SDIO_INT_ENABLE, int_enable);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "SDIO error writing SDIO_INT_ENABLE\n");
-        return r;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* CardDisableInt() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CardPendingInt
- *
- *      Determine whether UniFi is currently asserting the SDIO interrupt
- *      request.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *      pintr           Pointer to location to write interrupt status,
- *                          TRUE if interrupt pending,
- *                          FALSE if no interrupt pending.
- *  Returns:
- *      CSR_RESULT_SUCCESS            interrupt status read successfully
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
- *      CSR_RESULT_FAILURE            if an SDIO error occurred,
- * ---------------------------------------------------------------------------
- */
-CsrResult CardPendingInt(card_t *card, u8 *pintr)
-{
-    CsrResult r;
-    u8 pending;
-
-    *pintr = FALSE;
-
-    r = sdio_read_f0(card, SDIO_INT_PENDING, &pending);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "SDIO error reading SDIO_INT_PENDING\n");
-        return r;
-    }
-
-    *pintr = (pending & (1 << card->function))?TRUE : FALSE;
-
-    return CSR_RESULT_SUCCESS;
-} /* CardPendingInt() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CardClearInt
- *
- *      Clear the UniFi SDIO interrupt request.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS          if pending interrupt was cleared, or no pending interrupt.
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE    if the card was ejected
- *      CSR_RESULT_FAILURE          if an SDIO error occurred,
- * ---------------------------------------------------------------------------
- */
-CsrResult CardClearInt(card_t *card)
-{
-    CsrResult r;
-    u8 intr;
-
-    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
-    {
-        /* CardPendingInt() sets intr, if there is a pending interrupt */
-        r = CardPendingInt(card, &intr);
-        if (intr == FALSE)
-        {
-            return r;
-        }
-
-        r = sdio_write_f0(card, SDIO_CSR_HOST_INT_CLEAR, 1);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "SDIO error writing SDIO_CSR_HOST_INT_CLEAR\n");
-        }
-    }
-    else
-    {
-        r = unifi_write_direct_8_or_16(card,
-                                       ChipHelper_SDIO_HOST_INT(card->helper) * 2,
-                                       0);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "SDIO error writing UNIFI_SDIO_HOST_INT\n");
-        }
-    }
-
-    return r;
-} /* CardClearInt() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CardIntEnabled
- *
- *      Determine whether UniFi is currently asserting the SDIO interrupt
- *      request.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *      enabled         Pointer to location to write interrupt enable status,
- *                          TRUE if interrupts enabled,
- *                          FALSE if interupts disabled.
- *
- *  Returns:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
- *      CSR_RESULT_FAILURE            if an SDIO error occurred,
- * ---------------------------------------------------------------------------
- */
-CsrResult CardIntEnabled(card_t *card, u8 *enabled)
-{
-    CsrResult r;
-    u8 int_enable;
-
-    r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n");
-        return r;
-    }
-
-    *enabled = (int_enable & (1 << card->function))?TRUE : FALSE;
-
-    return CSR_RESULT_SUCCESS;
-} /* CardIntEnabled() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CardWriteBulkData
- *      Allocate slot in the pending bulkdata arrays and assign it to a signal's
- *      bulkdata reference. The slot is then ready for UniFi's bulkdata commands
- *      to transfer the data to/from the host.
- *
- *  Arguments:
- *      card            Pointer to Card object
- *      csptr           Pending signal pointer, including bulkdata ref
- *      queue           Traffic queue that this signal is using
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS if a free slot was assigned
- *      CSR_RESULT_FAILURE if no slot was available
- * ---------------------------------------------------------------------------
- */
-CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQueue queue)
-{
-    u16 i, slots[UNIFI_MAX_DATA_REFERENCES], j = 0;
-    u8 *packed_sigptr, num_slots_required = 0;
-    bulk_data_desc_t *bulkdata = csptr->bulkdata;
-    s16 h, nslots;
-
-    /* Count the number of slots required */
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
-    {
-        if (bulkdata[i].data_length != 0)
-        {
-            num_slots_required++;
-        }
-    }
-
-    /* Get the slot numbers */
-    if (num_slots_required != 0)
-    {
-        /* Last 2 slots for MLME */
-        if (queue == UNIFI_TRAFFIC_Q_MLME)
-        {
-            h = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS;
-            for (i = 0; i < card->config_data.num_fromhost_data_slots; i++)
-            {
-                if (card->from_host_data[h].bd.data_length == 0)
-                {
-                    /* Free data slot, claim it */
-                    slots[j++] = h;
-                    if (j == num_slots_required)
-                    {
-                        break;
-                    }
-                }
-
-                if (++h >= card->config_data.num_fromhost_data_slots)
-                {
-                    h = 0;
-                }
-            }
-        }
-        else
-        {
-            if (card->dynamic_slot_data.from_host_used_slots[queue]
-                < card->dynamic_slot_data.from_host_max_slots[queue])
-            {
-                /* Data commands get a free slot only after a few checks */
-                nslots = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS;
-
-                h = card->from_host_data_head;
-
-                for (i = 0; i < nslots; i++)
-                {
-                    if (card->from_host_data[h].bd.data_length == 0)
-                    {
-                        /* Free data slot, claim it */
-                        slots[j++] = h;
-                        if (j == num_slots_required)
-                        {
-                            break;
-                        }
-                    }
-
-                    if (++h >= nslots)
-                    {
-                        h = 0;
-                    }
-                }
-                card->from_host_data_head = h;
-            }
-        }
-
-        /* Required number of slots are not available, bail out */
-        if (j != num_slots_required)
-        {
-            unifi_trace(card->ospriv, UDBG5, "CardWriteBulkData: didn't find free slot/s\n");
-
-            /* If we haven't already reached the stable state we can ask for reservation */
-            if ((queue != UNIFI_TRAFFIC_Q_MLME) && (card->dynamic_slot_data.queue_stable[queue] == FALSE))
-            {
-                CardCheckDynamicReservation(card, queue);
-            }
-
-            for (i = 0; i < card->config_data.num_fromhost_data_slots; i++)
-            {
-                unifi_trace(card->ospriv, UDBG5, "fh data slot %d: %d\n", i, card->from_host_data[i].bd.data_length);
-            }
-            return CSR_RESULT_FAILURE;
-        }
-    }
-
-    packed_sigptr = csptr->sigbuf;
-
-    /* Fill in the slots with data */
-    j = 0;
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
-    {
-        if (bulkdata[i].data_length == 0)
-        {
-            /* Zero-out the DATAREF in the signal */
-            SET_PACKED_DATAREF_SLOT(packed_sigptr, i, 0);
-            SET_PACKED_DATAREF_LEN(packed_sigptr, i, 0);
-        }
-        else
-        {
-            /*
-             * Fill in the slot number in the SIGNAL structure but
-             * preserve the offset already in there
-             */
-            SET_PACKED_DATAREF_SLOT(packed_sigptr, i, slots[j] | (((u16)packed_sigptr[SIZEOF_SIGNAL_HEADER + (i * SIZEOF_DATAREF) + 1]) << 8));
-            SET_PACKED_DATAREF_LEN(packed_sigptr, i, bulkdata[i].data_length);
-
-            /* Do not copy the data, just store the information to them */
-            card->from_host_data[slots[j]].bd.os_data_ptr = bulkdata[i].os_data_ptr;
-            card->from_host_data[slots[j]].bd.os_net_buf_ptr = bulkdata[i].os_net_buf_ptr;
-            card->from_host_data[slots[j]].bd.data_length = bulkdata[i].data_length;
-            card->from_host_data[slots[j]].bd.net_buf_length = bulkdata[i].net_buf_length;
-            card->from_host_data[slots[j]].queue = queue;
-
-            unifi_trace(card->ospriv, UDBG4, "CardWriteBulkData sig=0x%x, fh slot %d = %p\n",
-                        GET_SIGNAL_ID(packed_sigptr), i, bulkdata[i].os_data_ptr);
-
-            /* Sanity-check that the bulk data desc being assigned to the slot
-             * actually has a payload.
-             */
-            if (!bulkdata[i].os_data_ptr)
-            {
-                unifi_error(card->ospriv, "Assign null os_data_ptr (len=%d) fh slot %d, i=%d, q=%d, sig=0x%x",
-                            bulkdata[i].data_length, slots[j], i, queue, GET_SIGNAL_ID(packed_sigptr));
-            }
-
-            j++;
-            if (queue < UNIFI_NO_OF_TX_QS)
-            {
-                card->dynamic_slot_data.from_host_used_slots[queue]++;
-            }
-        }
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /*  CardWriteBulkData() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_find_data_slot
- *
- *      Dereference references to bulk data slots into pointers to real data.
- *
- *  Arguments:
- *      card            Pointer to the card struct.
- *      slot            Slot number from a signal structure
- *
- *  Returns:
- *      Pointer to entry in bulk_data_slot array.
- * ---------------------------------------------------------------------------
- */
-bulk_data_desc_t* card_find_data_slot(card_t *card, s16 slot)
-{
-    s16 sn;
-    bulk_data_desc_t *bd;
-
-    sn = slot & 0x7FFF;
-
-    /* ?? check sanity of slot number ?? */
-
-    if (slot & SLOT_DIR_TO_HOST)
-    {
-        bd = &card->to_host_data[sn];
-    }
-    else
-    {
-        bd = &card->from_host_data[sn].bd;
-    }
-
-    return bd;
-} /* card_find_data_slot() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  firmware_present_in_flash
- *
- *      Probe for external Flash that looks like it might contain firmware.
- *
- *      If Flash is not present, reads always return 0x0008.
- *      If Flash is present, but empty, reads return 0xFFFF.
- *      Anything else is considered to be firmware.
- *
- *  Arguments:
- *      card        Pointer to card struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS                 firmware is present in ROM or flash
- *      CSR_WIFI_HIP_RESULT_NOT_FOUND      firmware is not present in ROM or flash
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
- *      CSR_RESULT_FAILURE                 if an SDIO error occurred
- * ---------------------------------------------------------------------------
- */
-static CsrResult firmware_present_in_flash(card_t *card)
-{
-    CsrResult r;
-    u16 m1, m5;
-
-    if (ChipHelper_HasRom(card->helper))
-    {
-        return CSR_RESULT_SUCCESS;
-    }
-    if (!ChipHelper_HasFlash(card->helper))
-    {
-        return CSR_WIFI_HIP_RESULT_NOT_FOUND;
-    }
-
-    /*
-     * Examine the Flash locations that are the power-on default reset
-     * vectors of the XAP processors.
-     * These are words 1 and 5 in Flash.
-     */
-    r = unifi_card_read16(card, UNIFI_MAKE_GP(EXT_FLASH, 2), &m1);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    r = unifi_card_read16(card, UNIFI_MAKE_GP(EXT_FLASH, 10), &m5);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    /* Check for uninitialised/missing flash */
-    if ((m1 == 0x0008) || (m1 == 0xFFFF) ||
-        (m1 == 0x0004) || (m5 == 0x0004) ||
-        (m5 == 0x0008) || (m5 == 0xFFFF))
-    {
-        return CSR_WIFI_HIP_RESULT_NOT_FOUND;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* firmware_present_in_flash() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  bootstrap_chip_hw
- *
- *      Perform chip specific magic to "Get It Working" TM.  This will
- *      increase speed of PLLs in analogue and maybe enable some
- *      on-chip regulators.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void bootstrap_chip_hw(card_t *card)
-{
-    const struct chip_helper_init_values *vals;
-    u32 i, len;
-    void *sdio = card->sdio_if;
-    CsrResult csrResult;
-
-    len = ChipHelper_ClockStartupSequence(card->helper, &vals);
-    if (len != 0)
-    {
-        for (i = 0; i < len; i++)
-        {
-            csrResult = CsrSdioWrite16(sdio, vals[i].addr * 2, vals[i].value);
-            if (csrResult != CSR_RESULT_SUCCESS)
-            {
-                unifi_warning(card->ospriv, "Failed to write bootstrap value %d\n", i);
-                /* Might not be fatal */
-            }
-
-            CsrThreadSleep(1);
-        }
-    }
-} /* bootstrap_chip_hw() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_card_stop_processor
- *
- *      Stop the UniFi XAP processors.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      which           One of UNIFI_PROC_MAC, UNIFI_PROC_PHY, UNIFI_PROC_BOTH
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS if successful, or CSR error code
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_card_stop_processor(card_t *card, enum unifi_dbg_processors_select which)
-{
-    CsrResult r = CSR_RESULT_SUCCESS;
-    u8 status;
-    s16 retry = 100;
-
-    while (retry--)
-    {
-        /* Select both XAPs */
-        r = unifi_set_proc_select(card, which);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            break;
-        }
-
-        /* Stop processors */
-        r = unifi_write_direct16(card, ChipHelper_DBG_EMU_CMD(card->helper) * 2, 2);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            break;
-        }
-
-        /* Read status */
-        r = unifi_read_direct_8_or_16(card,
-                                      ChipHelper_DBG_HOST_STOP_STATUS(card->helper) * 2,
-                                      &status);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            break;
-        }
-
-        if ((status & 1) == 1)
-        {
-            /* Success! */
-            return CSR_RESULT_SUCCESS;
-        }
-
-        /* Processors didn't stop, try again */
-    }
-
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        /* An SDIO error occurred */
-        unifi_error(card->ospriv, "Failed to stop processors: SDIO error\n");
-    }
-    else
-    {
-        /* If we reach here, we didn't the status in time. */
-        unifi_error(card->ospriv, "Failed to stop processors: timeout waiting for stopped status\n");
-        r = CSR_RESULT_FAILURE;
-    }
-
-    return r;
-} /* unifi_card_stop_processor() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  card_start_processor
- *
- *      Start the UniFi XAP processors.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      which           One of UNIFI_PROC_MAC, UNIFI_PROC_PHY, UNIFI_PROC_BOTH
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS or CSR error code
- * ---------------------------------------------------------------------------
- */
-CsrResult card_start_processor(card_t *card, enum unifi_dbg_processors_select which)
-{
-    CsrResult r;
-
-    /* Select both XAPs */
-    r = unifi_set_proc_select(card, which);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "unifi_set_proc_select failed: %d.\n", r);
-        return r;
-    }
-
-
-    r = unifi_write_direct_8_or_16(card,
-                                   ChipHelper_DBG_EMU_CMD(card->helper) * 2, 8);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    r = unifi_write_direct_8_or_16(card,
-                                   ChipHelper_DBG_EMU_CMD(card->helper) * 2, 0);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* card_start_processor() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_set_interrupt_mode
- *
- *      Configure the interrupt processing mode used by the HIP
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      mode            Interrupt mode to apply
- *
- *  Returns:
- *      None
- * ---------------------------------------------------------------------------
- */
-void unifi_set_interrupt_mode(card_t *card, u32 mode)
-{
-    if (mode == CSR_WIFI_INTMODE_RUN_BH_ONCE)
-    {
-        unifi_info(card->ospriv, "Scheduled interrupt mode");
-    }
-    card->intmode = mode;
-} /* unifi_set_interrupt_mode() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_start_processors
- *
- *      Start all UniFi XAP processors.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code on error
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_start_processors(card_t *card)
-{
-    return card_start_processor(card, UNIFI_PROC_BOTH);
-} /* unifi_start_processors() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_request_max_sdio_clock
- *
- *      Requests that the maximum SDIO clock rate is set at the next suitable
- *      opportunity (e.g. when the BH next runs, so as not to interfere with
- *      any current operation).
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      None
- * ---------------------------------------------------------------------------
- */
-void unifi_request_max_sdio_clock(card_t *card)
-{
-    card->request_max_clock = 1;
-} /* unifi_request_max_sdio_clock() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_set_host_state
- *
- *      Set the host deep-sleep state.
- *
- *      If transitioning to TORPID, the SDIO driver will be notified
- *      that the SD bus will be unused (idle) and conversely, when
- *      transitioning from TORPID that the bus will be used (active).
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      state           New deep-sleep state.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS            on success
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
- *      CSR_RESULT_FAILURE            if an SDIO error occurred
- *
- *  Notes:
- *      We need to reduce the SDIO clock speed before trying to wake up the
- *      chip. Actually, in the implementation below we reduce the clock speed
- *      not just before we try to wake up the chip, but when we put the chip to
- *      deep sleep. This means that if the f/w wakes up on its' own, we waste
- *      a reduce/increace cycle. However, trying to eliminate this overhead is
- *      proved difficult, as the current state machine in the HIP lib does at
- *      least a CMD52 to disable the interrupts before we configure the host
- *      state.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_set_host_state(card_t *card, enum unifi_host_state state)
-{
-    CsrResult r = CSR_RESULT_SUCCESS;
-    CsrResult csrResult;
-    static const char *const states[] = {
-        "AWAKE", "DROWSY", "TORPID"
-    };
-    static const u8 state_csr_host_wakeup[] = {
-        1, 3, 0
-    };
-    static const u8 state_io_abort[] = {
-        0, 2, 3
-    };
-
-    unifi_trace(card->ospriv, UDBG4, "State %s to %s\n",
-                states[card->host_state], states[state]);
-
-    if (card->host_state == UNIFI_HOST_STATE_TORPID)
-    {
-        CsrSdioFunctionActive(card->sdio_if);
-    }
-
-    /* Write the new state to UniFi. */
-    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
-    {
-        r = sdio_write_f0(card, SDIO_CSR_HOST_WAKEUP,
-                          (u8)((card->function << 4) | state_csr_host_wakeup[state]));
-    }
-    else
-    {
-        r = sdio_write_f0(card, SDIO_IO_ABORT, state_io_abort[state]);
-    }
-
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write UniFi deep sleep state\n");
-    }
-    else
-    {
-        /*
-         * If the chip was in state TORPID then we can now increase
-         * the maximum bus clock speed.
-         */
-        if (card->host_state == UNIFI_HOST_STATE_TORPID)
-        {
-            csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if,
-                                                       UNIFI_SDIO_CLOCK_MAX_HZ);
-            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-            /* Non-fatal error */
-            if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE)
-            {
-                unifi_warning(card->ospriv,
-                              "Failed to increase the SDIO clock speed\n");
-            }
-            else
-            {
-                card->sdio_clock_speed = UNIFI_SDIO_CLOCK_MAX_HZ;
-            }
-        }
-
-        /*
-         * Cache the current state in the card structure to avoid
-         * unnecessary SDIO reads.
-         */
-        card->host_state = state;
-
-        if (state == UNIFI_HOST_STATE_TORPID)
-        {
-            /*
-             * If the chip is now in state TORPID then we must now decrease
-             * the maximum bus clock speed.
-             */
-            csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if,
-                                                       UNIFI_SDIO_CLOCK_SAFE_HZ);
-            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-            if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE)
-            {
-                unifi_warning(card->ospriv,
-                              "Failed to decrease the SDIO clock speed\n");
-            }
-            else
-            {
-                card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ;
-            }
-            CsrSdioFunctionIdle(card->sdio_if);
-        }
-    }
-
-    return r;
-} /* unifi_set_host_state() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_card_info
- *
- *      Update the card information data structure
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      card_info       Pointer to info structure to update
- *
- *  Returns:
- *      None
- * ---------------------------------------------------------------------------
- */
-void unifi_card_info(card_t *card, card_info_t *card_info)
-{
-    card_info->chip_id = card->chip_id;
-    card_info->chip_version = card->chip_version;
-    card_info->fw_build = card->build_id;
-    card_info->fw_hip_version = card->config_data.version;
-    card_info->sdio_block_size = card->sdio_io_block_size;
-} /* unifi_card_info() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_check_io_status
- *
- *      Check UniFi for spontaneous reset and pending interrupt.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      status          Pointer to location to write chip status:
- *                        0 if UniFi is running, and no interrupt pending
- *                        1 if UniFi has spontaneously reset
- *                        2 if there is a pending interrupt
- *  Returns:
- *      CSR_RESULT_SUCCESS if OK, or CSR error
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_check_io_status(card_t *card, s32 *status)
-{
-    u8 io_en;
-    CsrResult r;
-    u8 pending;
-
-    *status = 0;
-
-    r = sdio_read_f0(card, SDIO_IO_ENABLE, &io_en);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to read SDIO_IO_ENABLE to check for spontaneous reset\n");
-        return r;
-    }
-
-    if ((io_en & (1 << card->function)) == 0)
-    {
-        s32 fw_count;
-        *status = 1;
-        unifi_error(card->ospriv, "UniFi has spontaneously reset.\n");
-
-        /*
-         * These reads are very likely to fail. We want to know if the function is really
-         * disabled or the SDIO driver just returns rubbish.
-         */
-        fw_count = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4);
-        if (fw_count < 0)
-        {
-            unifi_error(card->ospriv, "Failed to read to-host sig written count\n");
-        }
-        else
-        {
-            unifi_error(card->ospriv, "thsw: %u (driver thinks is %u)\n",
-                        fw_count, card->to_host_signals_w);
-        }
-        fw_count = unifi_read_shared_count(card, card->sdio_ctrl_addr + 2);
-        if (fw_count < 0)
-        {
-            unifi_error(card->ospriv, "Failed to read from-host sig read count\n");
-        }
-        else
-        {
-            unifi_error(card->ospriv, "fhsr: %u (driver thinks is %u)\n",
-                        fw_count, card->from_host_signals_r);
-        }
-
-        return r;
-    }
-
-    unifi_info(card->ospriv, "UniFi function %d is enabled.\n", card->function);
-
-    /* See if we missed an SDIO interrupt */
-    r = CardPendingInt(card, &pending);
-    if (pending)
-    {
-        unifi_error(card->ospriv, "There is an unhandled pending interrupt.\n");
-        *status = 2;
-        return r;
-    }
-
-    return r;
-} /* unifi_check_io_status() */
-
-
-void unifi_get_hip_qos_info(card_t *card, unifi_HipQosInfo *hipqosinfo)
-{
-    s32 count_fhr;
-    s16 t;
-    u32 occupied_fh;
-
-    q_t *sigq;
-    u16 nslots, i;
-
-    memset(hipqosinfo, 0, sizeof(unifi_HipQosInfo));
-
-    nslots = card->config_data.num_fromhost_data_slots;
-
-    for (i = 0; i < nslots; i++)
-    {
-        if (card->from_host_data[i].bd.data_length == 0)
-        {
-            hipqosinfo->free_fh_bulkdata_slots++;
-        }
-    }
-
-    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-    {
-        sigq = &card->fh_traffic_queue[i];
-        t = sigq->q_wr_ptr - sigq->q_rd_ptr;
-        if (t < 0)
-        {
-            t += sigq->q_length;
-        }
-        hipqosinfo->free_fh_sig_queue_slots[i] = (sigq->q_length - t) - 1;
-    }
-
-    count_fhr = unifi_read_shared_count(card, card->sdio_ctrl_addr + 2);
-    if (count_fhr < 0)
-    {
-        unifi_error(card->ospriv, "Failed to read from-host sig read count - %d\n", count_fhr);
-        hipqosinfo->free_fh_fw_slots = 0xfa;
-        return;
-    }
-
-    occupied_fh = (card->from_host_signals_w - count_fhr) % 128;
-
-    hipqosinfo->free_fh_fw_slots = (u16)(card->config_data.num_fromhost_sig_frags - occupied_fh);
-}
-
-
-
-CsrResult ConvertCsrSdioToCsrHipResult(card_t *card, CsrResult csrResult)
-{
-    CsrResult r = CSR_RESULT_FAILURE;
-
-    switch (csrResult)
-    {
-        case CSR_RESULT_SUCCESS:
-            r = CSR_RESULT_SUCCESS;
-            break;
-        /* Timeout errors */
-        case CSR_SDIO_RESULT_TIMEOUT:
-        /* Integrity errors */
-        case CSR_SDIO_RESULT_CRC_ERROR:
-            r = CSR_RESULT_FAILURE;
-            break;
-        case CSR_SDIO_RESULT_NO_DEVICE:
-            r = CSR_WIFI_HIP_RESULT_NO_DEVICE;
-            break;
-        case CSR_SDIO_RESULT_INVALID_VALUE:
-            r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            break;
-        case CSR_RESULT_FAILURE:
-            r = CSR_RESULT_FAILURE;
-            break;
-        default:
-            unifi_warning(card->ospriv, "Unrecognised csrResult error code: %d\n", csrResult);
-            break;
-    }
-
-    return r;
-} /* ConvertCsrSdioToCsrHipResult() */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,694 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *
- *  FILE:     csr_wifi_hip_card_sdio.h
- *
- *  PURPOSE:
- *      Internal header for Card API for SDIO.
- * ---------------------------------------------------------------------------
- */
-#ifndef __CARD_SDIO_H__
-#define __CARD_SDIO_H__
-
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_unifi_udi.h"
-#include "csr_wifi_hip_unifihw.h"
-#include "csr_wifi_hip_unifiversion.h"
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-#include "csr_wifi_hip_ta_sampling.h"
-#endif
-#include "csr_wifi_hip_xbv.h"
-#include "csr_wifi_hip_chiphelper.h"
-
-
-/*
- *
- * Configuration items.
- * Which of these should go in a platform unifi_config.h file?
- *
- */
-
-/*
- * When the traffic queues contain more signals than there is space for on
- * UniFi, a limiting algorithm comes into play.
- * If a traffic queue has enough slots free to buffer more traffic from the
- * network stack, then the following check is applied. The number of free
- * slots is RESUME_XMIT_THRESHOLD.
- */
-#define RESUME_XMIT_THRESHOLD           4
-
-
-/*
- * When reading signals from UniFi, the host processes pending all signals
- * and then acknowledges them together in a single write to update the
- * to-host-chunks-read location.
- * When there is more than one bulk data transfer (e.g. one received data
- * packet and a request for the payload data of a transmitted packet), the
- * update can be delayed significantly. This ties up resources on chip.
- *
- * To remedy this problem, to-host-chunks-read is updated after processing
- * a signal if TO_HOST_FLUSH_THRESHOLD bytes of bulk data have been
- * transferred since the last update.
- */
-#define TO_HOST_FLUSH_THRESHOLD (500 * 5)
-
-
-/* SDIO Card Common Control Registers */
-#define SDIO_CCCR_SDIO_REVISION     (0x00)
-#define SDIO_SD_SPEC_REVISION       (0x01)
-#define SDIO_IO_ENABLE              (0x02)
-#define SDIO_IO_READY               (0x03)
-#define SDIO_INT_ENABLE             (0x04)
-#define SDIO_INT_PENDING            (0x05)
-#define SDIO_IO_ABORT               (0x06)
-#define SDIO_BUS_IFACE_CONTROL      (0x07)
-#define SDIO_CARD_CAPABILOTY        (0x08)
-#define SDIO_COMMON_CIS_POINTER     (0x09)
-#define SDIO_BUS_SUSPEND            (0x0C)
-#define SDIO_FUNCTION_SELECT        (0x0D)
-#define SDIO_EXEC_FLAGS             (0x0E)
-#define SDIO_READY_FLAGS            (0x0F)
-#define SDIO_FN0_BLOCK_SIZE         (0x10)
-#define SDIO_POWER_CONTROL          (0x12)
-#define SDIO_VENDOR_START           (0xF0)
-
-#define SDIO_CSR_HOST_WAKEUP        (0xf0)
-#define SDIO_CSR_HOST_INT_CLEAR     (0xf1)
-#define SDIO_CSR_FROM_HOST_SCRATCH0 (0xf2)
-#define SDIO_CSR_FROM_HOST_SCRATCH1 (0xf3)
-#define SDIO_CSR_TO_HOST_SCRATCH0   (0xf4)
-#define SDIO_CSR_TO_HOST_SCRATCH1   (0xf5)
-#define SDIO_CSR_FUNC_EN            (0xf6)
-#define SDIO_CSR_CSPI_MODE          (0xf7)
-#define SDIO_CSR_CSPI_STATUS        (0xf8)
-#define SDIO_CSR_CSPI_PADDING       (0xf9)
-
-
-#define UNIFI_SD_INT_ENABLE_IENM 0x0001    /* Master INT Enable */
-
-#ifdef CSR_PRE_ALLOC_NET_DATA
-#define BULK_DATA_PRE_ALLOC_NUM 16
-#endif
-
-/*
- * Structure to hold configuration information read from UniFi.
- */
-typedef struct
-{
-    /*
-     * The version of the SDIO signal queues and bulk data pools
-     * configuration structure. The MSB is the major version number, used to
-     * indicate incompatible changes. The LSB gives the minor revision number,
-     * used to indicate changes that maintain backwards compatibility.
-     */
-    u16 version;
-
-    /*
-     * offset from the start of the shared data memory to the SD IO
-     * control structure.
-     */
-    u16 sdio_ctrl_offset;
-
-    /* Buffer handle of the from-host signal queue */
-    u16 fromhost_sigbuf_handle;
-
-    /* Buffer handle of the to-host signal queue */
-    u16 tohost_sigbuf_handle;
-
-    /*
-     * Maximum number of signal primitive or bulk data command fragments that may be
-     * pending in the to-hw signal queue.
-     */
-    u16 num_fromhost_sig_frags;
-
-    /*
-     * Number of signal primitive or bulk data command fragments that must be pending
-     * in the to-host signal queue before the host will generate an interrupt
-     * to indicate that it has read a signal. This will usually be the total
-     * capacity of the to-host signal buffer less the size of the largest signal
-     * primitive divided by the signal primitive fragment size, but may be set
-     * to 1 to request interrupts every time that the host read a signal.
-     * Note that the hw may place more signals in the to-host signal queue
-     * than indicated by this field.
-     */
-    u16 num_tohost_sig_frags;
-
-    /*
-     * Number of to-hw bulk data slots. Slots are numbered from 0 (zero) to
-     * one less than the value in this field
-     */
-    u16 num_fromhost_data_slots;
-
-    /*
-     * Number of frm-hw bulk data slots. Slots are numbered from 0 (zero) to
-     * one less than the value in this field
-     */
-    u16 num_tohost_data_slots;
-
-    /*
-     * Size of the bulk data slots (2 octets)
-     * The size of the bulk data slots in octets. This will usually be
-     * the size of the largest MSDU. The value should always be even.
-     */
-    u16 data_slot_size;
-
-    /*
-     * Indicates that the host has finished the initialisation sequence.
-     * Initialised to 0x0000 by the firmware, and set to 0x0001 by us.
-     */
-    u16 initialised;
-
-    /* Added by protocol version 0x0001 */
-    u32 overlay_size;
-
-    /* Added by protocol version 0x0300 */
-    u16 data_slot_round;
-    u16 sig_frag_size;
-
-    /* Added by protocol version 0x0500 */
-    u16 tohost_signal_padding;
-} sdio_config_data_t;
-
-/*
- * These values may change with versions of the Host Interface Protocol.
- */
-/*
- * Size of config info block pointed to by the CSR_SLT_SDIO_SLOT_CONFIG
- * entry in the f/w symbol table
- */
-#define SDIO_CONFIG_DATA_SIZE 30
-
-/* Offset of the INIT flag in the config info block. */
-#define SDIO_INIT_FLAG_OFFSET 0x12
-#define SDIO_TO_HOST_SIG_PADDING_OFFSET 0x1C
-
-
-/* Structure for a bulk data transfer command */
-typedef struct
-{
-    u16 cmd_and_len;   /* bits 12-15 cmd, bits 0-11 len */
-    u16 data_slot;     /* slot number, perhaps OR'd with SLOT_DIR_TO_HOST */
-    u16 offset;
-    u16 buffer_handle;
-} bulk_data_cmd_t;
-
-
-/* Bulk Data signal command values */
-#define SDIO_CMD_SIGNAL                 0x00
-#define SDIO_CMD_TO_HOST_TRANSFER       0x01
-#define SDIO_CMD_TO_HOST_TRANSFER_ACK   0x02 /*deprecated*/
-#define SDIO_CMD_FROM_HOST_TRANSFER     0x03
-#define SDIO_CMD_FROM_HOST_TRANSFER_ACK 0x04 /*deprecated*/
-#define SDIO_CMD_CLEAR_SLOT             0x05
-#define SDIO_CMD_OVERLAY_TRANSFER       0x06
-#define SDIO_CMD_OVERLAY_TRANSFER_ACK   0x07 /*deprecated*/
-#define SDIO_CMD_FROM_HOST_AND_CLEAR    0x08
-#define SDIO_CMD_PADDING                0x0f
-
-#define SLOT_DIR_TO_HOST 0x8000
-
-
-/* Initialise bulkdata slot
- *  params:
- *      bulk_data_desc_t *bulk_data_slot
- */
-#define UNIFI_INIT_BULK_DATA(bulk_data_slot)        \
-    {                                               \
-        (bulk_data_slot)->os_data_ptr = NULL;       \
-        (bulk_data_slot)->data_length = 0;          \
-        (bulk_data_slot)->os_net_buf_ptr = NULL;    \
-        (bulk_data_slot)->net_buf_length = 0;       \
-    }
-
-/*
- * Structure to contain a SIGNAL datagram.
- * This is used to build signal queues between the main driver and the
- * i/o thread.
- * The fields are:
- *      sigbuf          Contains the HIP signal is wire-format (i.e. packed,
- *                      little-endian)
- *      bulkdata        Contains a copy of any associated bulk data
- *      signal_length   The size of the signal in the sigbuf
- */
-typedef struct card_signal
-{
-    u8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE];
-
-    /* Length of the SIGNAL inside sigbuf */
-    u16 signal_length;
-
-    bulk_data_desc_t bulkdata[UNIFI_MAX_DATA_REFERENCES];
-} card_signal_t;
-
-
-/*
- * Control structure for a generic ring buffer.
- */
-#define UNIFI_QUEUE_NAME_MAX_LENGTH     16
-typedef struct
-{
-    card_signal_t *q_body;
-
-    /* Num elements in queue (capacity is one less than this!) */
-    u16 q_length;
-
-    u16 q_wr_ptr;
-    u16 q_rd_ptr;
-
-    char name[UNIFI_QUEUE_NAME_MAX_LENGTH];
-} q_t;
-
-
-#define UNIFI_RESERVED_COMMAND_SLOTS   2
-
-/* Considering approx 500 us per packet giving 0.5 secs */
-#define UNIFI_PACKETS_INTERVAL         1000
-
-/*
- * Dynamic slot reservation for QoS
- */
-typedef struct
-{
-    u16 from_host_used_slots[UNIFI_NO_OF_TX_QS];
-    u16 from_host_max_slots[UNIFI_NO_OF_TX_QS];
-    u16 from_host_reserved_slots[UNIFI_NO_OF_TX_QS];
-
-    /* Parameters to determine if a queue was active.
-       If number of packets sent is greater than the threshold
-       for the queue, the queue is considered active and no
-       re reservation is done, it is important not to keep this
-       value too low */
-    /* Packets sent during this interval */
-    u16 packets_txed[UNIFI_NO_OF_TX_QS];
-    u16 total_packets_txed;
-
-    /* Number of packets to see if slots need to be reassigned */
-    u16 packets_interval;
-
-    /* Once a queue reaches a stable state, avoid processing */
-    u8 queue_stable[UNIFI_NO_OF_TX_QS];
-} card_dynamic_slot_t;
-
-
-/* These are type-safe and don't write incorrect values to the
- * structure. */
-
-/* Return queue slots used count
- *  params:
- *      const q_t *q
- *  returns:
- *      u16
- */
-#define CSR_WIFI_HIP_Q_SLOTS_USED(q)     \
-    (((q)->q_wr_ptr - (q)->q_rd_ptr < 0)? \
-     ((q)->q_wr_ptr - (q)->q_rd_ptr + (q)->q_length) : ((q)->q_wr_ptr - (q)->q_rd_ptr))
-
-/* Return queue slots free count
- *  params:
- *      const q_t *q
- *  returns:
- *      u16
- */
-#define CSR_WIFI_HIP_Q_SLOTS_FREE(q)     \
-    ((q)->q_length - CSR_WIFI_HIP_Q_SLOTS_USED((q)) - 1)
-
-/* Return slot signal data pointer
- *  params:
- *      const q_t *q
- *      u16 slot
- *  returns:
- *      card_signal_t *
- */
-#define CSR_WIFI_HIP_Q_SLOT_DATA(q, slot)    \
-    ((q)->q_body + slot)
-
-/* Return queue next read slot
- *  params:
- *      const q_t *q
- *  returns:
- *      u16 slot offset
- */
-#define CSR_WIFI_HIP_Q_NEXT_R_SLOT(q)    \
-    ((q)->q_rd_ptr)
-
-/* Return queue next write slot
- *  params:
- *      const q_t *q
- *  returns:
- *      u16 slot offset
- */
-#define CSR_WIFI_HIP_Q_NEXT_W_SLOT(q)    \
-    ((q)->q_wr_ptr)
-
-/* Return updated queue pointer wrapped around its length
- *  params:
- *      const q_t *q
- *      u16 x     amount to add to queue pointer
- *  returns:
- *      u16 wrapped queue pointer
- */
-#define CSR_WIFI_HIP_Q_WRAP(q, x)    \
-    ((((x) >= (q)->q_length)?((x) % (q)->q_length) : (x)))
-
-/* Advance queue read pointer
- *  params:
- *      const q_t *q
- */
-#define CSR_WIFI_HIP_Q_INC_R(q)  \
-    ((q)->q_rd_ptr = CSR_WIFI_HIP_Q_WRAP((q), (q)->q_rd_ptr + 1))
-
-/* Advance queue write pointer
- *  params:
- *      const q_t *q
- */
-#define CSR_WIFI_HIP_Q_INC_W(q)  \
-    ((q)->q_wr_ptr = CSR_WIFI_HIP_Q_WRAP((q), (q)->q_wr_ptr + 1))
-
-enum unifi_host_state
-{
-    UNIFI_HOST_STATE_AWAKE   = 0,
-    UNIFI_HOST_STATE_DROWSY  = 1,
-    UNIFI_HOST_STATE_TORPID  = 2
-};
-
-typedef struct
-{
-    bulk_data_desc_t   bd;
-    unifi_TrafficQueue queue; /* Used for dynamic slot reservation */
-} slot_desc_t;
-
-/*
- * Structure describing a UniFi SDIO card.
- */
-struct card
-{
-    /*
-     * Back pointer for the higher level OS code. This is passed as
-     * an argument to callbacks (e.g. for received data and indications).
-     */
-    void *ospriv;
-
-    /*
-     * mapping of HIP slot to MA-PACKET.req host tag, the
-     * array is indexed by slot numbers and each index stores
-     * information of the last host tag it was used for
-     */
-    u32 *fh_slot_host_tag_record;
-
-
-    /* Info read from Symbol Table during probe */
-    u32     build_id;
-    char build_id_string[128];
-
-    /* Retrieve from SDIO driver. */
-    u16 chip_id;
-
-    /* Read from GBL_CHIP_VERSION. */
-    u16 chip_version;
-
-    /* From the SDIO driver (probably 1) */
-    u8 function;
-
-    /* This is sused to get the register addresses and things. */
-    ChipDescript *helper;
-
-    /*
-     * Bit mask of PIOs for the loader to waggle during download.
-     * We assume these are connected to LEDs. The main firmware gets
-     * the mask from a MIB entry.
-     */
-    s32 loader_led_mask;
-
-    /*
-     * Support for flow control. When the from-host queue of signals
-     * is full, we ask the host upper layer to stop sending packets. When
-     * the queue drains we tell it that it can send packets again.
-     * We use this flag to remember the current state.
-     */
-#define card_is_tx_q_paused(card, q)   (card->tx_q_paused_flag[q])
-#define card_tx_q_unpause(card, q)   (card->tx_q_paused_flag[q] = 0)
-#define card_tx_q_pause(card, q)   (card->tx_q_paused_flag[q] = 1)
-
-    u16 tx_q_paused_flag[UNIFI_TRAFFIC_Q_MAX + 1 + UNIFI_NO_OF_TX_QS]; /* defensive more than big enough */
-
-    /* UDI callback for logging UniFi interactions */
-    udi_func_t udi_hook;
-
-    u8 bh_reason_host;
-    u8 bh_reason_unifi;
-
-    /* SDIO clock speed request from OS layer */
-    u8 request_max_clock;
-
-    /* Last SDIO clock frequency set */
-    u32 sdio_clock_speed;
-
-    /*
-     * Current host state (copy of value in IOABORT register and
-     * spinlock to protect it.
-     */
-    enum unifi_host_state host_state;
-
-    enum unifi_low_power_mode     low_power_mode;
-    enum unifi_periodic_wake_mode periodic_wake_mode;
-
-    /*
-     * Ring buffer of signal structs for a queue of data packets from
-     * the host.
-     * The queue is empty when fh_data_q_num_rd == fh_data_q_num_wr.
-     * To add a packet to the queue, copy it to index given by
-     * (fh_data_q_num_wr%UNIFI_SOFT_Q_LENGTH) and advance fh_data_q_num_wr.
-     * To take a packet from the queue, copy data from index given by
-     * (fh_data_q_num_rd%UNIFI_SOFT_Q_LENGTH) and advance fh_data_q_num_rd.
-     * fh_data_q_num_rd and fh_data_q_num_rd are both modulo 256.
-     */
-    card_signal_t fh_command_q_body[UNIFI_SOFT_COMMAND_Q_LENGTH];
-    q_t           fh_command_queue;
-
-    card_signal_t fh_traffic_q_body[UNIFI_NO_OF_TX_QS][UNIFI_SOFT_TRAFFIC_Q_LENGTH];
-    q_t           fh_traffic_queue[UNIFI_NO_OF_TX_QS];
-
-    /*
-     * Signal counts from UniFi SDIO Control Data Structure.
-     * These are cached and synchronised with the UniFi before and after
-     * a batch of operations.
-     *
-     * These are the modulo-256 count of signals written to or read from UniFi
-     * The value is incremented for every signal.
-     */
-    s32 from_host_signals_w;
-    s32 from_host_signals_r;
-    s32 to_host_signals_r;
-    s32 to_host_signals_w;
-
-
-    /* Should specify buffer size as a number of signals */
-    /*
-     * Enough for 10 th and 10 fh data slots:
-     *   1 * 10 * 8 =  80
-     *   2 * 10 * 8 = 160
-     */
-#define UNIFI_FH_BUF_SIZE 1024
-    struct sigbuf
-    {
-        u8 *buf;     /* buffer area */
-        u8 *ptr;     /* current pos */
-        u16 count;   /* signal count */
-        u16 bufsize;
-    } fh_buffer;
-    struct sigbuf th_buffer;
-
-
-    /*
-     * Field to use for the incrementing value to write to the UniFi
-     * SHARED_IO_INTERRUPT register.
-     * Flag to say we need to generate an interrupt at end of processing.
-     */
-    u32 unifi_interrupt_seq;
-    u8  generate_interrupt;
-
-
-    /* Pointers to the bulk data slots */
-    slot_desc_t      *from_host_data;
-    bulk_data_desc_t *to_host_data;
-
-
-    /*
-     * Index of the next (hopefully) free data slot.
-     * This is an optimisation that starts searching at a more likely point
-     * than the beginning.
-     */
-    s16 from_host_data_head;
-
-    /* Dynamic slot allocation for queues */
-    card_dynamic_slot_t dynamic_slot_data;
-
-    /*
-     * SDIO specific fields
-     */
-
-    /* Interface pointer for the SDIO library */
-    CsrSdioFunction *sdio_if;
-
-    /* Copy of config_data struct from the card */
-    sdio_config_data_t config_data;
-
-    /* SDIO address of the Initialised flag and Control Data struct */
-    u32 init_flag_addr;
-    u32 sdio_ctrl_addr;
-
-    /* The last value written to the Shared Data Memory Page register */
-    u32 proc_select;
-    u32 dmem_page;
-    u32 pmem_page;
-
-    /* SDIO traffic counters limited to 32 bits for Synergy compatibility */
-    u32 sdio_bytes_read;
-    u32 sdio_bytes_written;
-
-    u8 memory_resources_allocated;
-
-    /* UniFi SDIO I/O Block size. */
-    u16 sdio_io_block_size;
-
-    /* Pad transfer sizes to SDIO block boundaries */
-    u8 sdio_io_block_pad;
-
-    /* Read from the XBV */
-    struct FWOV fwov;
-
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-    /* TA sampling */
-    ta_data_t ta_sampling;
-#endif
-
-    /* Auto-coredump */
-    s16             request_coredump_on_reset; /* request coredump on next reset */
-    struct coredump_buf *dump_buf;                  /* root node */
-    struct coredump_buf *dump_next_write;           /* node to fill at next dump */
-    struct coredump_buf *dump_cur_read;             /* valid node to read, or NULL */
-
-#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
-    struct cmd_profile
-    {
-        u32 cmd52_count;
-        u32 cmd53_count;
-        u32 tx_count;
-        u32 tx_cfm_count;
-        u32 rx_count;
-        u32 bh_count;
-        u32 process_count;
-        u32 protocol_count;
-
-        u32 cmd52_f0_r_count;
-        u32 cmd52_f0_w_count;
-        u32 cmd52_r8or16_count;
-        u32 cmd52_w8or16_count;
-        u32 cmd52_r16_count;
-        u32 cmd52_w16_count;
-        u32 cmd52_r32_count;
-
-        u32 sdio_cmd_signal;
-        u32 sdio_cmd_clear_slot;
-        u32 sdio_cmd_to_host;
-        u32 sdio_cmd_from_host;
-        u32 sdio_cmd_from_host_and_clear;
-    } hip_prof;
-    struct cmd_profile cmd_prof;
-#endif
-
-    /* Interrupt processing mode flags */
-    u32 intmode;
-
-#ifdef UNIFI_DEBUG
-    u8 lsb;
-#endif
-
-    /* Historic firmware panic codes */
-    u32 panic_data_phy_addr;
-    u32 panic_data_mac_addr;
-    u16 last_phy_panic_code;
-    u16 last_phy_panic_arg;
-    u16 last_mac_panic_code;
-    u16 last_mac_panic_arg;
-#ifdef CSR_PRE_ALLOC_NET_DATA
-    bulk_data_desc_t bulk_data_desc_list[BULK_DATA_PRE_ALLOC_NUM];
-    u16        prealloc_netdata_r;
-    u16        prealloc_netdata_w;
-#endif
-}; /* struct card */
-
-
-/* Reset types */
-enum unifi_reset_type
-{
-    UNIFI_COLD_RESET = 1,
-    UNIFI_WARM_RESET = 2
-};
-
-/*
- * unifi_set_host_state() implements signalling for waking UniFi from
- * deep sleep. The host indicates to UniFi that it is in one of three states:
- *   Torpid - host has nothing to send, UniFi can go to sleep.
- *   Drowsy - host has data to send to UniFi. UniFi will respond with an
- *            SDIO interrupt. When hosts responds it moves to Awake.
- *   Awake  - host has data to transfer, UniFi must stay awake.
- *            When host has finished, it moves to Torpid.
- */
-CsrResult unifi_set_host_state(card_t *card, enum unifi_host_state state);
-
-
-CsrResult unifi_set_proc_select(card_t *card, enum unifi_dbg_processors_select select);
-s32 card_read_signal_counts(card_t *card);
-bulk_data_desc_t* card_find_data_slot(card_t *card, s16 slot);
-
-
-CsrResult unifi_read32(card_t *card, u32 unifi_addr, u32 *pdata);
-CsrResult unifi_readnz(card_t *card, u32 unifi_addr,
-                       void *pdata, u16 len);
-s32 unifi_read_shared_count(card_t *card, u32 addr);
-
-CsrResult unifi_writen(card_t *card, u32 unifi_addr, void *pdata, u16 len);
-
-CsrResult unifi_bulk_rw(card_t *card, u32 handle,
-                        void *pdata, u32 len, s16 direction);
-CsrResult unifi_bulk_rw_noretry(card_t *card, u32 handle,
-                                void *pdata, u32 len, s16 direction);
-#define UNIFI_SDIO_READ       0
-#define UNIFI_SDIO_WRITE      1
-
-CsrResult unifi_read_8_or_16(card_t *card, u32 unifi_addr, u8 *pdata);
-CsrResult unifi_write_8_or_16(card_t *card, u32 unifi_addr, u8 data);
-CsrResult unifi_read_direct_8_or_16(card_t *card, u32 addr, u8 *pdata);
-CsrResult unifi_write_direct_8_or_16(card_t *card, u32 addr, u8 data);
-
-CsrResult unifi_read_direct16(card_t *card, u32 addr, u16 *pdata);
-CsrResult unifi_read_direct32(card_t *card, u32 addr, u32 *pdata);
-CsrResult unifi_read_directn(card_t *card, u32 addr, void *pdata, u16 len);
-
-CsrResult unifi_write_direct16(card_t *card, u32 addr, u16 data);
-CsrResult unifi_write_directn(card_t *card, u32 addr, void *pdata, u16 len);
-
-CsrResult sdio_read_f0(card_t *card, u32 addr, u8 *pdata);
-CsrResult sdio_write_f0(card_t *card, u32 addr, u8 data);
-
-void unifi_read_panic(card_t *card);
-#ifdef CSR_PRE_ALLOC_NET_DATA
-void prealloc_netdata_free(card_t *card);
-CsrResult prealloc_netdata_alloc(card_t *card);
-#endif
-/* For diagnostic use */
-void dump(void *mem, u16 len);
-void dump16(void *mem, u16 len);
-
-#endif /* __CARD_SDIO_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2595 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     csr_wifi_hip_card_sdio_intr.c
- *
- *  PURPOSE:
- *      Interrupt processing for the UniFi SDIO driver.
- *
- *      We may need another signal queue of responses to UniFi to hold
- *      bulk data commands generated by read_to_host_signals().
- *
- * ---------------------------------------------------------------------------
- */
-#undef CSR_WIFI_HIP_NOISY
-
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-#include "csr_wifi_hip_card.h"
-#include "csr_wifi_hip_xbv.h"
-
-
-/*
- * If the SDIO link is idle for this time (in milliseconds),
- * signal UniFi to go into Deep Sleep.
- * Valid return value of unifi_bh().
- */
-#define UNIFI_DEFAULT_HOST_IDLE_TIMEOUT 5
-/*
- * If the UniFi has not woken up for this time (in milliseconds),
- * signal the bottom half to take action.
- * Valid return value of unifi_bh().
- */
-#define UNIFI_DEFAULT_WAKE_TIMEOUT      1000
-
-
-static CsrResult process_bh(card_t *card);
-static CsrResult handle_host_protocol(card_t *card, u8 *processed_something);
-
-static CsrResult flush_fh_buffer(card_t *card);
-
-static CsrResult check_fh_sig_slots(card_t *card, u16 needed, s32 *space);
-
-static CsrResult read_to_host_signals(card_t *card, s32 *processed);
-static CsrResult process_to_host_signals(card_t *card, s32 *processed);
-
-static CsrResult process_bulk_data_command(card_t *card,
-                                           const u8 *cmdptr,
-                                           s16 cmd, u16 len);
-static CsrResult process_clear_slot_command(card_t         *card,
-                                            const u8 *cmdptr);
-static CsrResult process_fh_cmd_queue(card_t *card, s32 *processed);
-static CsrResult process_fh_traffic_queue(card_t *card, s32 *processed);
-static void restart_packet_flow(card_t *card);
-static CsrResult process_clock_request(card_t *card);
-
-#ifdef CSR_WIFI_HIP_NOISY
-s16 dump_fh_buf = 0;
-#endif /* CSR_WIFI_HIP_NOISY */
-
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-
-/*
- * The unifi_debug_output buffer can be used to debug the HIP behaviour offline
- * i.e. without using the tracing functions that change the timing.
- *
- * Call unifi_debug_log_to_buf() with printf arguments to store a string into
- * unifi_debug_output. When unifi_debug_buf_dump() is called, the contents of the
- * buffer are dumped with dump_str() which has to be implemented in the
- * OS layer, during the porting exercise. The offset printed, holds the
- * offset where the last character is (always a zero).
- *
- */
-
-#define UNIFI_DEBUG_GBUFFER_SIZE       8192
-static char unifi_debug_output[UNIFI_DEBUG_GBUFFER_SIZE];
-static char *unifi_dbgbuf_ptr = unifi_debug_output;
-static char *unifi_dbgbuf_start = unifi_debug_output;
-
-static void append_char(char c)
-{
-    /* write char and advance pointer */
-    *unifi_dbgbuf_ptr++ = c;
-    /* wrap pointer at end of buffer */
-    if ((unifi_dbgbuf_ptr - unifi_debug_output) >= UNIFI_DEBUG_GBUFFER_SIZE)
-    {
-        unifi_dbgbuf_ptr = unifi_debug_output;
-    }
-} /* append_char() */
-
-
-void unifi_debug_string_to_buf(const char *str)
-{
-    const char *p = str;
-    while (*p)
-    {
-        append_char(*p);
-        p++;
-    }
-    /* Update start-of-buffer pointer */
-    unifi_dbgbuf_start = unifi_dbgbuf_ptr + 1;
-    if ((unifi_dbgbuf_start - unifi_debug_output) >= UNIFI_DEBUG_GBUFFER_SIZE)
-    {
-        unifi_dbgbuf_start = unifi_debug_output;
-    }
-}
-
-
-void unifi_debug_log_to_buf(const char *fmt, ...)
-{
-#define DEBUG_BUFFER_SIZE       80
-    static char s[DEBUG_BUFFER_SIZE];
-    va_list args;
-
-    va_start(args, fmt);
-    vsnprintf(s, DEBUG_BUFFER_SIZE, fmt, args);
-    va_end(args);
-
-    unifi_debug_string_to_buf(s);
-} /* unifi_debug_log_to_buf() */
-
-
-/* Convert signed 32 bit (or less) integer to string */
-static void CsrUInt16ToHex(u16 number, char *str)
-{
-    u16 index;
-    u16 currentValue;
-
-    for (index = 0; index < 4; index++)
-    {
-        currentValue = (u16) (number & 0x000F);
-        number >>= 4;
-        str[3 - index] = (char) (currentValue > 9 ? currentValue + 55 : currentValue + '0');
-    }
-    str[4] = '\0';
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_debug_hex_to_buf
- *
- *  puts the contents of the passed buffer into the debug buffer as a hex string
- *
- *  Arguments:
- *      buff         buffer to print as hex
- *      length       number of chars to print
- *
- *  Returns:
- *      None.
- *
- * ---------------------------------------------------------------------------
- */
-void unifi_debug_hex_to_buf(const char *buff, u16 length)
-{
-    char s[5];
-    u16 i;
-
-    for (i = 0; i < length; i = i + 2)
-    {
-        CsrUInt16ToHex(*((u16 *)(buff + i)), s);
-        unifi_debug_string_to_buf(s);
-    }
-}
-
-
-void unifi_debug_buf_dump(void)
-{
-    s32 offset = unifi_dbgbuf_ptr - unifi_debug_output;
-
-    unifi_error(NULL, "HIP debug buffer offset=%d\n", offset);
-    dump_str(unifi_debug_output + offset, UNIFI_DEBUG_GBUFFER_SIZE - offset);
-    dump_str(unifi_debug_output, offset);
-} /* unifi_debug_buf_dump() */
-
-
-#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */
-
-#ifdef CSR_PRE_ALLOC_NET_DATA
-#define NETDATA_PRE_ALLOC_BUF_SIZE 8000
-
-void prealloc_netdata_free(card_t *card)
-{
-    unifi_warning(card->ospriv, "prealloc_netdata_free: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
-
-    while (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length != 0)
-    {
-        unifi_warning(card->ospriv, "prealloc_netdata_free: r=%d\n", card->prealloc_netdata_r);
-
-        unifi_net_data_free(card->ospriv, &card->bulk_data_desc_list[card->prealloc_netdata_r]);
-        card->prealloc_netdata_r++;
-        card->prealloc_netdata_r %= BULK_DATA_PRE_ALLOC_NUM;
-    }
-    card->prealloc_netdata_r = card->prealloc_netdata_w = 0;
-
-    unifi_warning(card->ospriv, "prealloc_netdata_free: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
-}
-
-
-CsrResult prealloc_netdata_alloc(card_t *card)
-{
-    CsrResult r;
-
-    unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_alloc: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
-
-    while (card->bulk_data_desc_list[card->prealloc_netdata_w].data_length == 0)
-    {
-        r = unifi_net_data_malloc(card->ospriv, &card->bulk_data_desc_list[card->prealloc_netdata_w], NETDATA_PRE_ALLOC_BUF_SIZE);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "prealloc_netdata_alloc: Failed to allocate t-h bulk data\n");
-            return CSR_RESULT_FAILURE;
-        }
-        card->prealloc_netdata_w++;
-        card->prealloc_netdata_w %= BULK_DATA_PRE_ALLOC_NUM;
-    }
-    unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_alloc: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
-
-    return CSR_RESULT_SUCCESS;
-}
-
-
-static CsrResult prealloc_netdata_get(card_t *card, bulk_data_desc_t *bulk_data_slot, u32 size)
-{
-    CsrResult r;
-
-    unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_get: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
-
-    if (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length == 0)
-    {
-        unifi_error(card->ospriv, "prealloc_netdata_get: data_length = 0\n");
-    }
-
-    if ((size > NETDATA_PRE_ALLOC_BUF_SIZE) || (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length == 0))
-    {
-        unifi_warning(card->ospriv, "prealloc_netdata_get: Calling net_data_malloc\n");
-
-        r = unifi_net_data_malloc(card->ospriv, bulk_data_slot, size);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "prealloc_netdata_get: Failed to allocate t-h bulk data\n");
-            return CSR_RESULT_FAILURE;
-        }
-        return CSR_RESULT_SUCCESS;
-    }
-
-    *bulk_data_slot = card->bulk_data_desc_list[card->prealloc_netdata_r];
-    card->bulk_data_desc_list[card->prealloc_netdata_r].os_data_ptr = NULL;
-    card->bulk_data_desc_list[card->prealloc_netdata_r].os_net_buf_ptr = NULL;
-    card->bulk_data_desc_list[card->prealloc_netdata_r].net_buf_length = 0;
-    card->bulk_data_desc_list[card->prealloc_netdata_r].data_length = 0;
-
-    card->prealloc_netdata_r++;
-    card->prealloc_netdata_r %= BULK_DATA_PRE_ALLOC_NUM;
-
-    unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_get: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
-
-    return CSR_RESULT_SUCCESS;
-}
-
-
-#endif
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_sdio_interrupt_handler
- *
- *      This function should be called by the OS-dependent code to handle
- *      an SDIO interrupt from the UniFi.
- *
- *  Arguments:
- *      card            Pointer to card context structure.
- *
- *  Returns:
- *      None.
- *
- *  Notes: This function may be called in DRS context. In this case,
- *         tracing with the unifi_trace(), etc, is not allowed.
- * ---------------------------------------------------------------------------
- */
-void unifi_sdio_interrupt_handler(card_t *card)
-{
-    /*
-     * Set the flag to say reason for waking was SDIO interrupt.
-     * Then ask the OS layer to run the unifi_bh to give attention to the UniFi.
-     */
-    card->bh_reason_unifi = 1;
-    (void)unifi_run_bh(card->ospriv);
-} /*  sdio_interrupt_handler() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_configure_low_power_mode
- *
- *      This function should be called by the OS-dependent when
- *      the deep sleep signaling needs to be enabled or disabled.
- *
- *  Arguments:
- *      card            Pointer to card context structure.
- *      low_power_mode  Disable/Enable the deep sleep signaling
- *      periodic_wake_mode UniFi wakes host periodically.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success or a CSR error code.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_configure_low_power_mode(card_t                       *card,
-                                         enum unifi_low_power_mode     low_power_mode,
-                                         enum unifi_periodic_wake_mode periodic_wake_mode)
-{
-    card->low_power_mode = low_power_mode;
-    card->periodic_wake_mode = periodic_wake_mode;
-
-    unifi_trace(card->ospriv, UDBG1,
-                "unifi_configure_low_power_mode: new mode = %s, wake_host = %s\n",
-                (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled",
-                (periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_DISABLED)?"FALSE" : "TRUE");
-
-    (void)unifi_run_bh(card->ospriv);
-    return CSR_RESULT_SUCCESS;
-} /* unifi_configure_low_power_mode() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_force_low_power_mode
- *
- *      This function should be called by the OS-dependent when
- *      UniFi needs to be set to the low power mode (e.g. on suspend)
- *
- *  Arguments:
- *      card            Pointer to card context structure.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success or a CSR error code.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_force_low_power_mode(card_t *card)
-{
-    if (card->low_power_mode == UNIFI_LOW_POWER_DISABLED)
-    {
-        unifi_error(card->ospriv, "Attempt to set mode to TORPID when lower power mode is disabled\n");
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    return unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID);
-} /* unifi_force_low_power_mode() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_bh
- *
- *      This function should be called by the OS-dependent code when
- *      host and/or UniFi has requested an exchange of messages.
- *
- *  Arguments:
- *      card            Pointer to card context structure.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success or a CSR error code.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_bh(card_t *card, u32 *remaining)
-{
-    CsrResult r;
-    CsrResult csrResult;
-    u8 pending;
-    s32 iostate, j;
-    const enum unifi_low_power_mode low_power_mode = card->low_power_mode;
-    u16 data_slots_used = 0;
-
-
-    /* Process request to raise the maximum SDIO clock */
-    r = process_clock_request(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Error setting maximum SDIO clock\n");
-        goto exit;
-    }
-
-    /*
-     * Why was the BH thread woken?
-     * If it was an SDIO interrupt, UniFi is awake and we need to process it.
-     * If it was a host process queueing data, then we need to awaken UniFi.
-     *
-     * Priority of flags is top down.
-     *
-     * ----------------------------------------------------------+
-     *    \state|   AWAKE      |    DROWSY      |    TORPID      |
-     * flag\    |              |                |                |
-     * ---------+--------------+----------------+----------------|
-     *          | do the host  | go to AWAKE and| go to AWAKE and|
-     *   unifi  | protocol     | do the host    | do the host    |
-     *          |              | protocol       | protocol       |
-     * ---------+--------------+----------------+----------------|
-     *          | do the host  |                |                |
-     *   host   | protocol     |  do nothing    | go to DROWSY   |
-     *          |              |                |                |
-     * ---------+--------------+----------------+----------------|
-     *          |              |                | should not     |
-     *  timeout | go to TORPID | error, unifi   | occur          |
-     *          |              | didn't wake up | do nothing     |
-     * ----------------------------------------------------------+
-     *
-     * Note that if we end up in the AWAKE state we always do the host protocol.
-     */
-
-    do
-    {
-        /*
-         * When the host state is set to DROWSY, then we can not disable the
-         * interrupts as UniFi can generate an interrupt even when the INT_ENABLE
-         * register has the interrupts disabled. This interrupt will be lost.
-         */
-        if (card->host_state == UNIFI_HOST_STATE_DROWSY || card->host_state == UNIFI_HOST_STATE_TORPID)
-        {
-            u8 reason_unifi;
-
-            /*
-             * An interrupt may occur while or after we cache the reason.
-             * This interrupt will cause the unifi_bh() to be scheduled again.
-             * Any interrupt that has happened before the register is read
-             * and is considered spurious has to acknowledged.
-             */
-            reason_unifi = card->bh_reason_unifi;
-
-            /*
-             * If an interrupt is received, check if it was a real one,
-             * set the host state to AWAKE and run the BH.
-             */
-            r = CardPendingInt(card, &pending);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                goto exit;
-            }
-
-            if (pending)
-            {
-                unifi_trace(card->ospriv, UDBG5,
-                            "UNIFI_HOST_STATE_%s: Set state to AWAKE.\n",
-                            (card->host_state == UNIFI_HOST_STATE_TORPID)?"TORPID" : "DROWSY");
-
-                r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
-                if (r == CSR_RESULT_SUCCESS)
-                {
-                    (*remaining) = 0;
-                    break;
-                }
-            }
-            else if (reason_unifi)
-            {
-                CsrSdioInterruptAcknowledge(card->sdio_if);
-            }
-
-            /*
-             * If an chip is in TORPID, and the host wants to wake it up,
-             * set the host state to DROWSY and wait for the wake-up interrupt.
-             */
-            if ((card->host_state == UNIFI_HOST_STATE_TORPID) && card->bh_reason_host)
-            {
-                r = unifi_set_host_state(card, UNIFI_HOST_STATE_DROWSY);
-                if (r == CSR_RESULT_SUCCESS)
-                {
-                    /*
-                     * set the timeout value to UNIFI_DEFAULT_WAKE_TIMEOUT
-                     * to capture a wake error.
-                     */
-                    card->bh_reason_host = 0;
-                    (*remaining) = UNIFI_DEFAULT_WAKE_TIMEOUT;
-                    return CSR_RESULT_SUCCESS;
-                }
-
-                goto exit;
-            }
-
-            /*
-             * If the chip is in DROWSY, and the timeout expires,
-             * we need to reset the chip. This should never occur.
-             * (If it does, check that the calling thread set "remaining"
-             * according to the time remaining when unifi_bh() was called).
-             */
-            if ((card->host_state == UNIFI_HOST_STATE_DROWSY) && ((*remaining) == 0))
-            {
-                unifi_error(card->ospriv, "UniFi did not wake up on time...\n");
-
-                /*
-                 * Check if Function1 has gone away or
-                 * if we missed an SDIO interrupt.
-                 */
-                r = unifi_check_io_status(card, &iostate);
-                if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-                {
-                    goto exit;
-                }
-                /* Need to reset and reboot */
-                return CSR_RESULT_FAILURE;
-            }
-        }
-        else
-        {
-            if (card->bh_reason_unifi || card->bh_reason_host)
-            {
-                break;
-            }
-
-            if (((*remaining) == 0) && (low_power_mode == UNIFI_LOW_POWER_ENABLED))
-            {
-                r = unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID);
-                if (r == CSR_RESULT_SUCCESS)
-                {
-                    (*remaining) = 0;
-                    return CSR_RESULT_SUCCESS;
-                }
-
-                goto exit;
-            }
-        }
-
-        /* No need to run the host protocol */
-        return CSR_RESULT_SUCCESS;
-    } while (0);
-
-
-    /* Disable the SDIO interrupts while doing SDIO ops */
-    csrResult = CsrSdioInterruptDisable(card->sdio_if);
-    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-    {
-        r = CSR_WIFI_HIP_RESULT_NO_DEVICE;
-        goto exit;
-    }
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-        unifi_error(card->ospriv, "Failed to disable SDIO interrupts. unifi_bh queues error.\n");
-        goto exit;
-    }
-
-    /* Now that the interrupts are disabled, ack the interrupt */
-    CsrSdioInterruptAcknowledge(card->sdio_if);
-
-    /* Run the HIP */
-    r = process_bh(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        goto exit;
-    }
-
-    /*
-     * If host is now idle, schedule a timer for the delay before we
-     * let UniFi go into deep sleep.
-     * If the timer goes off, we will move to TORPID state.
-     * If UniFi raises an interrupt in the meantime, we will cancel
-     * the timer and start a new one when we become idle.
-     */
-    for (j = 0; j < UNIFI_NO_OF_TX_QS; j++)
-    {
-        data_slots_used += CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[j]);
-    }
-
-    if ((low_power_mode == UNIFI_LOW_POWER_ENABLED) && (data_slots_used == 0))
-    {
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-        if (card->ta_sampling.traffic_type != CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_PERIODIC)
-        {
-#endif
-        /* return the UNIFI_DEFAULT_HOST_IDLE_TIMEOUT, so we can go to sleep. */
-        unifi_trace(card->ospriv, UDBG5,
-                    "Traffic is not periodic, set timer for TORPID.\n");
-        (*remaining) = UNIFI_DEFAULT_HOST_IDLE_TIMEOUT;
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-    }
-    else
-    {
-        unifi_trace(card->ospriv, UDBG5,
-                    "Traffic is periodic, set unifi to TORPID immediately.\n");
-        if (CardAreAllFromHostDataSlotsEmpty(card) == 1)
-        {
-            r = unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                goto exit;
-            }
-        }
-    }
-#endif
-    }
-
-    csrResult = CsrSdioInterruptEnable(card->sdio_if);
-    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-    {
-        r = CSR_WIFI_HIP_RESULT_NO_DEVICE;
-    }
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-        unifi_error(card->ospriv, "Failed to enable SDIO interrupt\n");
-    }
-
-exit:
-
-    unifi_trace(card->ospriv, UDBG4, "New state=%d\n", card->host_state);
-
-    if (r != CSR_RESULT_SUCCESS)
-    {
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        unifi_debug_buf_dump();
-#endif
-        /* If an interrupt has been raised, ack it here */
-        if (card->bh_reason_unifi)
-        {
-            CsrSdioInterruptAcknowledge(card->sdio_if);
-        }
-
-        unifi_error(card->ospriv,
-                    "unifi_bh: state=%d %c, clock=%dkHz, interrupt=%d host=%d, power_save=%s\n",
-                    card->host_state,
-                    (card->host_state == UNIFI_HOST_STATE_AWAKE)?'A' : (card->host_state == UNIFI_HOST_STATE_DROWSY)?'D' : 'T',
-                    card->sdio_clock_speed / 1000,
-                    card->bh_reason_unifi, card->bh_reason_host,
-                    (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled");
-
-        /* Try to capture firmware panic codes */
-        (void)unifi_capture_panic(card);
-
-        /* Ask for a mini-coredump when the driver has reset UniFi */
-        (void)unifi_coredump_request_at_next_reset(card, 1);
-    }
-
-    return r;
-} /* unifi_bh() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  process_clock_request
- *
- *      Handle request from the OS layer to increase the SDIO clock speed.
- *      The fast clock is limited until the firmware has indicated that it has
- *      completed initialisation to the OS layer.
- *
- *  Arguments:
- *      card            Pointer to card context structure.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success or CSR error code.
- * ---------------------------------------------------------------------------
- */
-static CsrResult process_clock_request(card_t *card)
-{
-    CsrResult r = CSR_RESULT_SUCCESS;
-    CsrResult csrResult;
-
-    if (!card->request_max_clock)
-    {
-        return CSR_RESULT_SUCCESS;   /* No pending request */
-    }
-
-    /*
-     * The SDIO clock speed request from the OS layer is only acted upon if
-     * the UniFi is awake. If it was in any other state, the clock speed will
-     * transition through SAFE to MAX while the host wakes it up, and the
-     * final speed reached will be UNIFI_SDIO_CLOCK_MAX_HZ.
-     * This assumes that the SME never requests low power mode while the f/w
-     * initialisation takes place.
-     */
-    if (card->host_state == UNIFI_HOST_STATE_AWAKE)
-    {
-        unifi_trace(card->ospriv, UDBG1, "Set SDIO max clock\n");
-        csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_MAX_HZ);
-        if (csrResult != CSR_RESULT_SUCCESS)
-        {
-            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-        }
-        else
-        {
-            card->sdio_clock_speed = UNIFI_SDIO_CLOCK_MAX_HZ;  /* log the new freq */
-        }
-    }
-    else
-    {
-        unifi_trace(card->ospriv, UDBG1, "Will set SDIO max clock after wakeup\n");
-    }
-
-    /* Cancel the request now that it has been acted upon, or is about to be
-     * by the wakeup mechanism
-     */
-    card->request_max_clock = 0;
-
-    return r;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  process_bh
- *
- *      Exchange messages with UniFi
- *
- *  Arguments:
- *      card            Pointer to card context structure.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success or CSR error code.
- * ---------------------------------------------------------------------------
- */
-static CsrResult process_bh(card_t *card)
-{
-    CsrResult r;
-    u8 more;
-    more = FALSE;
-
-    /* Process the reasons (interrupt, signals) */
-    do
-    {
-        /*
-         * Run in a while loop, to save clearing the interrupts
-         * every time around the outside loop.
-         */
-        do
-        {
-            /* If configured to run the HIP just once, skip first loop */
-            if (card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE)
-            {
-                break;
-            }
-
-            r = handle_host_protocol(card, &more);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-            unifi_debug_log_to_buf("c52=%d c53=%d tx=%d txc=%d rx=%d s=%d t=%d fc=%d\n",
-                                   card->cmd_prof.cmd52_count,
-                                   card->cmd_prof.cmd53_count,
-                                   card->cmd_prof.tx_count,
-                                   card->cmd_prof.tx_cfm_count,
-                                   card->cmd_prof.rx_count,
-                                   card->cmd_prof.sdio_cmd_signal,
-                                   card->cmd_prof.sdio_cmd_to_host,
-                                   card->cmd_prof.sdio_cmd_from_host_and_clear
-                                   );
-
-            card->cmd_prof.cmd52_count = card->cmd_prof.cmd53_count = 0;
-            card->cmd_prof.tx_count = card->cmd_prof.tx_cfm_count = card->cmd_prof.rx_count = 0;
-
-            card->cmd_prof.cmd52_f0_r_count = 0;
-            card->cmd_prof.cmd52_f0_w_count = 0;
-            card->cmd_prof.cmd52_r8or16_count = 0;
-            card->cmd_prof.cmd52_w8or16_count = 0;
-            card->cmd_prof.cmd52_r16_count = 0;
-            card->cmd_prof.cmd52_w16_count = 0;
-            card->cmd_prof.cmd52_r32_count = 0;
-
-            card->cmd_prof.sdio_cmd_signal = 0;
-            card->cmd_prof.sdio_cmd_clear_slot = 0;
-            card->cmd_prof.sdio_cmd_to_host = 0;
-            card->cmd_prof.sdio_cmd_from_host = 0;
-            card->cmd_prof.sdio_cmd_from_host_and_clear = 0;
-#endif
-
-
-        } while (more || card->bh_reason_unifi || card->bh_reason_host);
-
-        /* Acknowledge the h/w interrupt */
-        r = CardClearInt(card);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to acknowledge interrupt.\n");
-            return r;
-        }
-
-        /*
-         * UniFi may have tried to generate an interrupt during the
-         * CardClearInt() was running. So, we need to run the host
-         * protocol again, to check if there are any pending requests.
-         */
-        r = handle_host_protocol(card, &more);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            return r;
-        }
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-        unifi_debug_log_to_buf("c52=%d c53=%d tx=%d txc=%d rx=%d s=%d t=%d fc=%d\n",
-                               card->cmd_prof.cmd52_count,
-                               card->cmd_prof.cmd53_count,
-                               card->cmd_prof.tx_count,
-                               card->cmd_prof.tx_cfm_count,
-                               card->cmd_prof.rx_count,
-                               card->cmd_prof.sdio_cmd_signal,
-                               card->cmd_prof.sdio_cmd_to_host,
-                               card->cmd_prof.sdio_cmd_from_host_and_clear
-                               );
-
-        card->cmd_prof.cmd52_count = card->cmd_prof.cmd53_count = 0;
-        card->cmd_prof.tx_count = card->cmd_prof.tx_cfm_count = card->cmd_prof.rx_count = 0;
-
-        card->cmd_prof.cmd52_f0_r_count = 0;
-        card->cmd_prof.cmd52_f0_w_count = 0;
-        card->cmd_prof.cmd52_r8or16_count = 0;
-        card->cmd_prof.cmd52_w8or16_count = 0;
-        card->cmd_prof.cmd52_r16_count = 0;
-        card->cmd_prof.cmd52_w16_count = 0;
-        card->cmd_prof.cmd52_r32_count = 0;
-
-        card->cmd_prof.sdio_cmd_signal = 0;
-        card->cmd_prof.sdio_cmd_clear_slot = 0;
-        card->cmd_prof.sdio_cmd_to_host = 0;
-        card->cmd_prof.sdio_cmd_from_host = 0;
-        card->cmd_prof.sdio_cmd_from_host_and_clear = 0;
-#endif
-        /* If configured to run the HIP just once, work is now done */
-        if (card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE)
-        {
-            break;
-        }
-
-    } while (more || card->bh_reason_unifi || card->bh_reason_host);
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-    if ((card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE) == 0)
-    {
-        unifi_debug_log_to_buf("proc=%d\n",
-                               card->cmd_prof.process_count);
-    }
-#endif
-
-    return CSR_RESULT_SUCCESS;
-} /* process_bh() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  handle_host_protocol
- *
- *      This function implements the Host Interface Protocol (HIP) as
- *      described in the Host Interface Protocol Specification.
- *
- *  Arguments:
- *      card                 Pointer to card context structure.
- *      processed_something  Pointer to location to update processing status:
- *                              TRUE when data was transferred
- *                              FALSE when no data was transferred (queues empty)
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success or CSR error code.
- * ---------------------------------------------------------------------------
- */
-static CsrResult handle_host_protocol(card_t *card, u8 *processed_something)
-{
-    CsrResult r;
-    s32 done;
-
-    *processed_something = FALSE;
-
-#ifdef CSR_WIFI_HIP_NOISY
-    unifi_error(card->ospriv, "   ========================     \n");
-#endif /* CSR_WIFI_HIP_NOISY */
-
-#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
-    card->cmd_prof.process_count++;
-#endif
-
-    card->bh_reason_unifi = card->bh_reason_host = 0;
-    card->generate_interrupt = 0;
-
-
-    /*
-     * (Re)fill the T-H signal buffer
-     */
-    r = read_to_host_signals(card, &done);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Error occurred reading to-host signals\n");
-        return r;
-    }
-    if (done > 0)
-    {
-        *processed_something = TRUE;
-    }
-
-    /*
-     * Process any to-host signals.
-     * Perform any requested CMD53 transfers here, but just queue any
-     * bulk data command responses.
-     */
-    r = process_to_host_signals(card, &done);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Error occurred processing to-host signals\n");
-        return r;
-    }
-
-    /* Now send any signals in the F-H queues */
-    /* Give precedence to the command queue */
-    r = process_fh_cmd_queue(card, &done);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Error occurred processing from-host signals\n");
-        return r;
-    }
-    if (done > 0)
-    {
-        *processed_something = TRUE;
-    }
-
-    r = process_fh_traffic_queue(card, &done);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Error occurred processing from-host data signals\n");
-        return r;
-    }
-    if (done > 0)
-    {
-        *processed_something = TRUE;
-    }
-
-    /* Flush out the batch of signals to the UniFi. */
-    r = flush_fh_buffer(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to copy from-host signals to UniFi\n");
-        return r;
-    }
-
-
-    /*
-     * Send the host interrupt to say the queues have been modified.
-     */
-    if (card->generate_interrupt)
-    {
-        r = CardGenInt(card);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to notify UniFi that queues have been modified.\n");
-            return r;
-        }
-    }
-
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-#ifdef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
-    unifi_rx_queue_flush(card->ospriv);
-#endif
-#endif
-
-    /* See if we can re-enable transmission now */
-    restart_packet_flow(card);
-
-#ifdef CSR_PRE_ALLOC_NET_DATA
-    r = prealloc_netdata_alloc(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "prealloc_netdata failed\n");
-        return r;
-    }
-#endif
-
-    /*
-     * Don't put the thread sleep if we just interacted with the chip,
-     * there might be more to do if we look again.
-     */
-    return r;
-} /* handle_host_protocol() */
-
-
-/*
- *      Rounds the given signal length in bytes to a whole number
- *      of sig_frag_size.
- */
-#define GET_CHUNKS_FOR(SIG_FRAG_SIZE, LENGTH) (((LENGTH) + ((SIG_FRAG_SIZE)-1)) / (SIG_FRAG_SIZE))
-
-
-/*
- * ---------------------------------------------------------------------------
- *  read_to_host_signals
- *
- *      Read everything pending in the UniFi TH signal buffer.
- *      Only do it if the local buffer is empty.
- *
- *  Arguments:
- *      card        Pointer to card context struct
- *      processed   Number of signals read:
- *                      0 if there were no signals pending,
- *                      1 if we read at least one signal
- *  Returns:
- *      CSR error code if an error occurred.
- * ---------------------------------------------------------------------------
- */
-static CsrResult read_to_host_signals(card_t *card, s32 *processed)
-{
-    s32 count_thw, count_thr;
-    s32 unread_chunks, unread_bytes;
-    CsrResult r;
-
-    *processed = 0;
-
-    /* Read any pending signals or bulk data commands */
-    count_thw = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4);
-    if (count_thw < 0)
-    {
-        unifi_error(card->ospriv, "Failed to read to-host sig written count\n");
-        return CSR_RESULT_FAILURE;
-    }
-    card->to_host_signals_w = count_thw; /* diag */
-
-    count_thr = card->to_host_signals_r;
-
-    if (count_thw == count_thr)
-    {
-        return CSR_RESULT_SUCCESS;
-    }
-
-    unread_chunks =
-        (((count_thw - count_thr) + 128) % 128) - card->th_buffer.count;
-
-    if (unread_chunks == 0)
-    {
-        return CSR_RESULT_SUCCESS;
-    }
-
-    unread_bytes = card->config_data.sig_frag_size * unread_chunks;
-
-
-    r = unifi_bulk_rw(card,
-                      card->config_data.tohost_sigbuf_handle,
-                      card->th_buffer.ptr,
-                      unread_bytes,
-                      UNIFI_SDIO_READ);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to read ToHost signal\n");
-        return r;
-    }
-
-    card->th_buffer.ptr += unread_bytes;
-    card->th_buffer.count += (u16)unread_chunks;
-
-    *processed = 1;
-
-    return CSR_RESULT_SUCCESS;
-} /* read_to_host_signals() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  update_to_host_signals_r
- *
- *      Advance the shared-memory count of chunks read from the to-host
- *      signal buffer.
- *      Raise a UniFi internal interrupt to tell the firmware that the
- *      count has changed.
- *
- *  Arguments:
- *      card            Pointer to card context struct
- *      pending         Number of chunks remaining
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success or CSR error code
- * ---------------------------------------------------------------------------
- */
-static CsrResult update_to_host_signals_r(card_t *card, s16 pending)
-{
-    CsrResult r;
-
-    card->to_host_signals_r =
-        (card->to_host_signals_r + (card->th_buffer.count - pending)) % 128;
-    card->th_buffer.count = pending;
-
-    /* Update the count of signals read */
-    r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 6,
-                            (u8)card->to_host_signals_r);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to update to-host signals read\n");
-        return r;
-    }
-
-    r = CardGenInt(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to notify UniFi that we processed to-host signals.\n");
-        return r;
-    }
-
-    card->generate_interrupt = 0;
-
-    return CSR_RESULT_SUCCESS;
-} /* update_to_host_signals_r() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  read_unpack_cmd
- *
- *      Converts a wire-formatted command to the host bulk_data_cmd_t structure.
- *
- *  Arguments:
- *      ptr             Pointer to the command
- *      bulk_data_cmd   Pointer to the host structure
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void read_unpack_cmd(const u8 *ptr, bulk_data_cmd_t *bulk_data_cmd)
-{
-    s16 index = 0;
-    bulk_data_cmd->cmd_and_len = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-    index += SIZEOF_UINT16;
-    bulk_data_cmd->data_slot = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-    index += SIZEOF_UINT16;
-    bulk_data_cmd->offset = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-    index += SIZEOF_UINT16;
-    bulk_data_cmd->buffer_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-    index += SIZEOF_UINT16;
-} /* read_unpack_cmd */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  process_to_host_signals
- *
- *      Read and dispatch signals from the UniFi
- *
- *  Arguments:
- *      card        Pointer to card context struct
- *      processed   Pointer to location to write processing result:
- *                      0 if there were no signals pending,
- *                      1 if we read at least one signal
- *
- *  Returns:
- *      CSR error code if there was an error
- *
- *  Notes:
- *      Since bulk data transfers can take a long time, if we wait until
- *      all are done before we acknowledge the signals, the UniFi runs out
- *      of buffer space. Therefore we keep a count of the bytes transferred
- *      in bulk data commands, and update the to-host-signals-read count
- *      if we've done a large transfer.
- *
- *      All data in the f/w is stored in a little endian format, without any
- *      padding bytes. Every read from the memory has to be transformed in
- *      host (cpu specific) format, before we can process it. Therefore we
- *      use read_unpack_cmd() and read_unpack_signal() to convert the raw data
- *      contained in the card->th_buffer.buf to host structures.
- *      Important: UDI clients use wire-formatted structures, so we need to
- *      indicate all data, as we have read it from the device.
- * ---------------------------------------------------------------------------
- */
-static CsrResult process_to_host_signals(card_t *card, s32 *processed)
-{
-    s16 pending;
-    s16 remaining;
-    u8 *bufptr;
-    bulk_data_param_t data_ptrs;
-    s16 cmd;
-    u16 sig_len;
-    s16 i;
-    u16 chunks_in_buf;
-    u16 bytes_transferred = 0;
-    CsrResult r = CSR_RESULT_SUCCESS;
-
-    *processed = 0;
-
-    pending = card->th_buffer.count;
-
-    /* Are there new to-host signals? */
-    unifi_trace(card->ospriv, UDBG4, "handling %d to-host chunks\n", pending);
-
-    if (!pending)
-    {
-        return CSR_RESULT_SUCCESS;
-    }
-
-    /*
-     * This is a pointer to the raw data we have read from the f/w.
-     * Can be a signal or a command. Note that we need to convert
-     * it to a host structure before we process it.
-     */
-    bufptr = card->th_buffer.buf;
-
-    while (pending > 0)
-    {
-        s16 f_flush_count = 0;
-
-        /*
-         * Command and length are common to signal and bulk data msgs.
-         * If command == 0 (i.e. a signal), len is number of bytes
-         * *following* the 2-byte header.
-         */
-        cmd = bufptr[1] >> 4;
-        sig_len = bufptr[0] + ((bufptr[1] & 0x0F) << 8);
-
-#ifdef CSR_WIFI_HIP_NOISY
-        unifi_error(card->ospriv, "Received UniFi msg cmd=%d, len=%d\n",
-                    cmd, sig_len);
-#endif  /* CSR_WIFI_HIP_NOISY */
-
-        if ((sig_len == 0) &&
-            ((cmd != SDIO_CMD_CLEAR_SLOT) && (cmd != SDIO_CMD_PADDING)))
-        {
-            unifi_error(card->ospriv, "incomplete signal or command: has size zero\n");
-            return CSR_RESULT_FAILURE;
-        }
-        /*
-         * Make sure the buffer contains a complete message.
-         * Signals may occupy multiple chunks, bulk-data commands occupy
-         * one chunk.
-         */
-        if (cmd == SDIO_CMD_SIGNAL)
-        {
-            chunks_in_buf = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(sig_len + 2));
-        }
-        else
-        {
-            chunks_in_buf = 1;
-        }
-
-        if (chunks_in_buf > (u16)pending)
-        {
-            unifi_error(card->ospriv, "incomplete signal (0x%x?): need %d chunks, got %d\n",
-                        GET_SIGNAL_ID(bufptr + 2),
-                        chunks_in_buf, pending);
-            unifi_error(card->ospriv, " thsw=%d, thsr=%d\n",
-                        card->to_host_signals_w,
-                        card->to_host_signals_r);
-            return CSR_RESULT_FAILURE;
-        }
-
-
-        switch (cmd)
-        {
-            case SDIO_CMD_SIGNAL:
-                /* This is a signal. Read the rest of it and then handle it. */
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-                card->cmd_prof.sdio_cmd_signal++;
-#endif
-
-                for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
-                {
-                    /* Retrieve dataRefs[i].DataLength */
-                    u16 data_len = GET_PACKED_DATAREF_LEN(bufptr + 2, i);
-
-                    /*
-                     * The bulk data length in the signal can not be greater than
-                     * the maximun length allowed by the SDIO config structure.
-                     */
-                    if (data_len > card->config_data.data_slot_size)
-                    {
-                        unifi_error(card->ospriv,
-                                    "Bulk Data length (%d) exceeds Maximum Bulk Data length (%d)\n",
-                                    data_len, card->config_data.data_slot_size);
-                        return CSR_RESULT_FAILURE;
-                    }
-
-                    /*
-                     * Len here might not be the same as the length in the
-                     * bulk data slot.  The slot length will always be even,
-                     * but len could be odd.
-                     */
-                    if (data_len != 0)
-                    {
-                    /* Retrieve dataRefs[i].SlotNumber */
-                        s16 slot = GET_PACKED_DATAREF_SLOT(bufptr + 2, i);
-
-                        if (slot >= card->config_data.num_tohost_data_slots)
-                        {
-                            unifi_error(card->ospriv, "!!!bad slot number in to-host signal: %d, sig 0x%X\n",
-                                        slot, cmd);
-                            return CSR_RESULT_FAILURE;
-                        }
-
-                        data_ptrs.d[i].os_data_ptr = card->to_host_data[slot].os_data_ptr;
-                        data_ptrs.d[i].os_net_buf_ptr = card->to_host_data[slot].os_net_buf_ptr;
-                        data_ptrs.d[i].net_buf_length = card->to_host_data[slot].net_buf_length;
-                        data_ptrs.d[i].data_length = data_len;
-                    }
-                    else
-                    {
-                        UNIFI_INIT_BULK_DATA(&data_ptrs.d[i]);
-                    }
-                }
-
-            /*
-             * Log the signal to the UDI, before call unifi_receive_event() as
-             * it can modify the bulk data.
-             */
-                if (card->udi_hook)
-                {
-                    (*card->udi_hook)(card->ospriv, bufptr + 2, sig_len,
-                                      &data_ptrs, UDI_LOG_TO_HOST);
-                }
-
-#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
-                if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_CONFIRM_ID)
-                {
-                    card->cmd_prof.tx_cfm_count++;
-                }
-                else if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_INDICATION_ID)
-                {
-                    if (data_ptrs.d[0].os_data_ptr)
-                    {
-                        if ((*data_ptrs.d[0].os_data_ptr) & 0x08)
-                        {
-                            card->cmd_prof.rx_count++;
-                        }
-                    }
-                }
-#endif
-                /*
-                 * Check if the signal is MA-PACKET.cfm and if so check the status.
-                 * If the status is failure, search through the slot records to find
-                 * if any slots are occupied for this host tag. This can happen if
-                 * f/w has not downloaded the bulkdata and before that itself it has
-                 * signalled the confirm with failure. If it finds a slot with that
-                 * host tag then, it clears the corresponding slot
-                 */
-
-                if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_CONFIRM_ID)
-                {
-                    /* Get host tag and transmission status */
-                    u32 host_tag = GET_PACKED_MA_PACKET_CONFIRM_HOST_TAG(bufptr + 2);
-                    u16 status = GET_PACKED_MA_PACKET_CONFIRM_TRANSMISSION_STATUS(bufptr + 2);
-
-                    unifi_trace(card->ospriv, UDBG4, "process_to_host_signals signal ID=%x host Tag=%x status=%x\n",
-                                GET_SIGNAL_ID(bufptr + 2), host_tag, status);
-
-                    /* If transmission status is failure then search through the slot records
-                     * and if for any slot records the clear slot is not done then do it now
-                     */
-
-                    if (status && (card->fh_slot_host_tag_record))
-                    {
-                        u16 num_fh_slots = card->config_data.num_fromhost_data_slots;
-
-                        /* search through the list of slot records and match with host tag
-                         * If a slot is not yet cleared then clear the slot from here
-                         */
-                        for (i = 0; i < num_fh_slots; i++)
-                        {
-                            if (card->fh_slot_host_tag_record[i] == host_tag)
-                            {
-#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
-                                /* Invoke the HAL module function to requeue it back to HAL Queues */
-                                r = unifi_reque_ma_packet_request(card->ospriv, host_tag, status, &card->from_host_data[i].bd);
-                                card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
-                                if (CSR_RESULT_SUCCESS != r)
-                                {
-                                    unifi_trace(card->ospriv, UDBG5, "process_to_host_signals: Failed to requeue Packet(hTag:%x) back to HAL \n", host_tag);
-                                    CardClearFromHostDataSlot(card, i);
-                                }
-                                else
-                                {
-                                    CardClearFromHostDataSlotWithoutFreeingBulkData(card, i);
-                                }
-
-#else
-                                unifi_trace(card->ospriv, UDBG4, "process_to_host_signals Clear slot=%x host tag=%x\n", i, host_tag);
-                                card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
-
-                                /* Set length field in from_host_data array to 0 */
-                                CardClearFromHostDataSlot(card, i);
-#endif
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                /* Pass event to OS layer */
-                unifi_receive_event(card->ospriv, bufptr + 2, sig_len, &data_ptrs);
-
-                /* Initialise the to_host data, so it can be re-used. */
-                for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
-                {
-                /* The slot is only valid if the length is non-zero. */
-                    if (GET_PACKED_DATAREF_LEN(bufptr + 2, i) != 0)
-                    {
-                        s16 slot = GET_PACKED_DATAREF_SLOT(bufptr + 2, i);
-                        if (slot < card->config_data.num_tohost_data_slots)
-                        {
-                            UNIFI_INIT_BULK_DATA(&card->to_host_data[slot]);
-                        }
-                    }
-                }
-
-#ifndef CSR_WIFI_DEFER_TH_FLUSH
-                /*
-                 * If we have previously transferred a lot of data, ack
-                 * the signals read so far, so f/w can reclaim the buffer
-                 * memory sooner.
-                 */
-                if (bytes_transferred >= TO_HOST_FLUSH_THRESHOLD)
-                {
-                    f_flush_count = 1;
-                }
-#endif
-                break;
-
-
-            case SDIO_CMD_CLEAR_SLOT:
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-                card->cmd_prof.sdio_cmd_clear_slot++;
-#endif
-                /* This is a clear slot command. */
-                if (sig_len != 0)
-                {
-                    unifi_error(card->ospriv, "process_to_host_signals: clear slot, bad data len: 0x%X at offset %d\n",
-                                sig_len, bufptr - card->th_buffer.buf);
-                    return CSR_RESULT_FAILURE;
-                }
-
-                r = process_clear_slot_command(card, bufptr);
-                if (r != CSR_RESULT_SUCCESS)
-                {
-                    unifi_error(card->ospriv, "Failed to process clear slot\n");
-                    return r;
-                }
-                break;
-
-            case SDIO_CMD_TO_HOST_TRANSFER:
-            case SDIO_CMD_FROM_HOST_TRANSFER:
-            case SDIO_CMD_FROM_HOST_AND_CLEAR:
-            case SDIO_CMD_OVERLAY_TRANSFER:
-                /* This is a bulk data command. */
-                if (sig_len & 1)
-                {
-                    unifi_error(card->ospriv, "process_to_host_signals: bulk data, bad data len: 0x%X at offset %d\n",
-                                sig_len, bufptr - card->th_buffer.buf);
-                    return CSR_RESULT_FAILURE;
-                }
-
-                r = process_bulk_data_command(card, bufptr, cmd, sig_len);
-                if (r != CSR_RESULT_SUCCESS)
-                {
-                    unifi_error(card->ospriv, "Failed to process bulk cmd\n");
-                    return r;
-                }
-                /* Count the bytes transferred */
-                bytes_transferred += sig_len;
-
-                if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR)
-                {
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-                    card->cmd_prof.sdio_cmd_from_host_and_clear++;
-#endif
-#ifndef CSR_WIFI_DEFER_TH_FLUSH
-                    f_flush_count = 1;
-#endif
-                }
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-                else if (cmd == SDIO_CMD_FROM_HOST_TRANSFER)
-                {
-                    card->cmd_prof.sdio_cmd_from_host++;
-                }
-                else if (cmd == SDIO_CMD_TO_HOST_TRANSFER)
-                {
-                    card->cmd_prof.sdio_cmd_to_host++;
-                }
-#endif
-                break;
-
-            case SDIO_CMD_PADDING:
-                break;
-
-            default:
-                unifi_error(card->ospriv, "Unrecognised to-host command: %d\n", cmd);
-                break;
-        }
-
-        bufptr += chunks_in_buf * card->config_data.sig_frag_size;
-        pending -= chunks_in_buf;
-
-        /*
-         * Write out the host signal count when a significant
-         * number of bytes of bulk data have been transferred or
-         * when we have performed a CopyFromHostAndClear.
-         */
-        if (f_flush_count)
-        {
-            r = update_to_host_signals_r(card, pending);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            bytes_transferred = 0;
-        }
-    }
-
-    if (pending)
-    {
-        unifi_warning(card->ospriv, "proc_th_sigs: %d unprocessed\n", pending);
-    }
-
-    /* If we processed any signals, write the updated count to UniFi */
-    if (card->th_buffer.count != pending)
-    {
-        r = update_to_host_signals_r(card, pending);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            return r;
-        }
-    }
-
-    /*
-     * Reset the buffer pointer, copying down any un-processed signals.
-     * This can happen if we enable the optimisation in read_to_host_signals()
-     * that limits the length to whole blocks.
-     */
-    remaining = card->th_buffer.ptr - bufptr;
-    if (remaining < 0)
-    {
-        unifi_error(card->ospriv, "Processing TH signals overran the buffer\n");
-        return CSR_RESULT_FAILURE;
-    }
-    if (remaining > 0)
-    {
-        /* Use a safe copy because source and destination may overlap */
-        u8 *d = card->th_buffer.buf;
-        u8 *s = bufptr;
-        s32 n = remaining;
-        while (n--)
-        {
-            *d++ = *s++;
-        }
-    }
-    card->th_buffer.ptr = card->th_buffer.buf + remaining;
-
-
-    /* If we reach here then we processed something */
-    *processed = 1;
-    return CSR_RESULT_SUCCESS;
-} /* process_to_host_signals() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  process_clear_slot_command
- *
- *      Process a clear slot command fom the UniFi.
- *
- *  Arguments:
- *   card       Pointer to card context struct
- *   bdcmd      Pointer to bulk-data command msg from UniFi
- *
- *  Returns:
- *      0 on success, CSR error code on error
- * ---------------------------------------------------------------------------
- */
-static CsrResult process_clear_slot_command(card_t *card, const u8 *cmdptr)
-{
-    u16 data_slot;
-    s16 slot;
-
-    data_slot = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cmdptr + SIZEOF_UINT16);
-
-    unifi_trace(card->ospriv, UDBG4, "Processing clear slot cmd, slot=0x%X\n",
-                data_slot);
-
-    slot = data_slot & 0x7FFF;
-
-#ifdef CSR_WIFI_HIP_NOISY
-    unifi_error(card->ospriv, "CMD clear data slot 0x%04x\n", data_slot);
-#endif /* CSR_WIFI_HIP_NOISY */
-
-    if (data_slot & SLOT_DIR_TO_HOST)
-    {
-        if (slot >= card->config_data.num_tohost_data_slots)
-        {
-            unifi_error(card->ospriv,
-                        "Invalid to-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n",
-                        slot);
-            return CSR_RESULT_FAILURE;
-        }
-        /* clear to-host data slot */
-        unifi_warning(card->ospriv, "Unexpected clear to-host data slot cmd: 0x%04x\n",
-                      data_slot);
-    }
-    else
-    {
-        if (slot >= card->config_data.num_fromhost_data_slots)
-        {
-            unifi_error(card->ospriv,
-                        "Invalid from-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n",
-                        slot);
-            return CSR_RESULT_FAILURE;
-        }
-
-        /*
-         * The driver is the owner to clear all slots now
-         * Ref - comment in process_fh_traffic_queue
-         * so it will just ignore the clear slot command from firmware
-         * and return success
-         */
-        return CSR_RESULT_SUCCESS;
-
-        /* Set length field in from_host_data array to 0 */
-        /* CardClearFromHostDataSlot(card, slot); */
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* process_clear_slot_command() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  process_bulk_data_command
- *
- *      Process a bulk data request from the UniFi.
- *
- *  Arguments:
- *   card       Pointer to card context struct
- *   bdcmd      Pointer to bulk-data command msg from UniFi
- *   cmd, len   Decoded values of command and length from the msg header
- *              Cmd will only be one of:
- *                      SDIO_CMD_TO_HOST_TRANSFER
- *                      SDIO_CMD_FROM_HOST_TRANSFER
- *                      SDIO_CMD_FROM_HOST_AND_CLEAR
- *                      SDIO_CMD_OVERLAY_TRANSFER
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code on error
- * ---------------------------------------------------------------------------
- */
-static CsrResult process_bulk_data_command(card_t *card, const u8 *cmdptr,
-                                           s16 cmd, u16 len)
-{
-    bulk_data_desc_t *bdslot;
-#ifdef CSR_WIFI_ALIGNMENT_WORKAROUND
-    u8 *host_bulk_data_slot;
-#endif
-    bulk_data_cmd_t bdcmd;
-    s16 offset;
-    s16 slot;
-    s16 dir;
-    CsrResult r;
-
-    read_unpack_cmd(cmdptr, &bdcmd);
-
-    unifi_trace(card->ospriv, UDBG4, "Processing bulk data cmd %d %s, len=%d, slot=0x%X\n",
-                cmd, lookup_bulkcmd_name(cmd), len, bdcmd.data_slot);
-
-    /*
-     * Round up the transfer length if required.
-     * This is useful to force all transfers to be a multiple of the SDIO block
-     * size, so the SDIO driver won't try to use a byte-mode CMD53. These are
-     * broken on some hardware platforms.
-     */
-    if (card->sdio_io_block_pad)
-    {
-        len = (len + card->sdio_io_block_size - 1) & ~(card->sdio_io_block_size - 1);
-        unifi_trace(card->ospriv, UDBG4, "Rounded bulk data length up to %d\n", len);
-    }
-
-    slot = bdcmd.data_slot & 0x7FFF;
-
-    if (cmd == SDIO_CMD_OVERLAY_TRANSFER)
-    {
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;     /* Not used on CSR6xxx */
-    }
-    else
-    {
-        if (bdcmd.data_slot & SLOT_DIR_TO_HOST)
-        {
-            /* Request is for to-host bulk data */
-
-            /* Check sanity of slot number */
-            if (slot >= card->config_data.num_tohost_data_slots)
-            {
-                unifi_error(card->ospriv,
-                            "Invalid to-host data slot in SDIO bulk xfr req: %d\n",
-                            slot);
-                return CSR_RESULT_FAILURE;
-            }
-
-            /* Allocate memory for card->to_host_data[slot] bulk data here. */
-#ifdef CSR_PRE_ALLOC_NET_DATA
-            r = prealloc_netdata_get(card, &card->to_host_data[slot], len);
-#else
-            r = unifi_net_data_malloc(card->ospriv, &card->to_host_data[slot], len);
-#endif
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "Failed to allocate t-h bulk data\n");
-                return CSR_RESULT_FAILURE;
-            }
-
-            bdslot = &card->to_host_data[slot];
-
-            /* Make sure that the buffer is 4-bytes aligned */
-            r = unifi_net_dma_align(card->ospriv, bdslot);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "Failed to align t-h bulk data buffer for DMA\n");
-                return CSR_RESULT_FAILURE;
-            }
-        }
-        else
-        {
-            /* Request is for from-host bulk data */
-
-            if (slot >= card->config_data.num_fromhost_data_slots)
-            {
-                unifi_error(card->ospriv,
-                            "Invalid from-host data slot in SDIO bulk xfr req: %d\n",
-                            slot);
-                return CSR_RESULT_FAILURE;
-            }
-            bdslot = &card->from_host_data[slot].bd;
-        }
-        offset = bdcmd.offset;
-    }
-    /* Do the transfer */
-    dir = (cmd == SDIO_CMD_TO_HOST_TRANSFER)?
-          UNIFI_SDIO_READ : UNIFI_SDIO_WRITE;
-
-    unifi_trace(card->ospriv, UDBG4,
-                "Bulk %c %s len=%d, handle %d - slot=%d %p+(%d)\n",
-                (dir == UNIFI_SDIO_READ)?'R' : 'W',
-                lookup_bulkcmd_name(cmd),
-                len,
-                bdcmd.buffer_handle,
-                slot, bdslot->os_data_ptr, offset);
-#ifdef CSR_WIFI_HIP_NOISY
-    unifi_error(card->ospriv, "Bulk %s len=%d, handle %d - slot=%d %p+(%d)\n",
-                lookup_bulkcmd_name(cmd),
-                len,
-                bdcmd.buffer_handle,
-                slot, bdslot->os_data_ptr, offset);
-#endif /* CSR_WIFI_HIP_NOISY */
-
-
-    if (bdslot->os_data_ptr == NULL)
-    {
-        unifi_error(card->ospriv, "Null os_data_ptr - Bulk %s handle %d - slot=%d o=(%d)\n",
-                    lookup_bulkcmd_name(cmd),
-                    bdcmd.buffer_handle,
-                    slot,
-                    offset);
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-#ifdef CSR_WIFI_ALIGNMENT_WORKAROUND
-    /* if os_data_ptr is not 4-byte aligned, then allocate a new buffer and copy data
-    to new buffer to ensure the address passed to unifi_bulk_rw is 4-byte aligned */
-
-    if (len != 0 && (dir == UNIFI_SDIO_WRITE) && (((ptrdiff_t)bdslot->os_data_ptr + offset) & 3))
-    {
-        host_bulk_data_slot = kmalloc(len, GFP_KERNEL);
-
-        if (!host_bulk_data_slot)
-        {
-            unifi_error(card->ospriv, " failed to allocate request_data before unifi_bulk_rw\n");
-            return -1;
-        }
-
-        memcpy((void *)host_bulk_data_slot,
-                  (void *)(bdslot->os_data_ptr + offset), len);
-
-        r = unifi_bulk_rw(card,
-                          bdcmd.buffer_handle,
-                          (void *)host_bulk_data_slot,
-                          len,
-                          dir);
-    }
-    else
-#endif
-    {
-        r = unifi_bulk_rw(card,
-                          bdcmd.buffer_handle,
-                          (void *)(bdslot->os_data_ptr + offset),
-                          len,
-                          dir);
-    }
-
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv,
-                    "Failed: %s hlen=%d, slen=%d, handle %d - slot=%d %p+0x%X\n",
-                    lookup_bulkcmd_name(cmd),
-                    len,                    /* Header length */
-                    bdslot->data_length,    /* Length stored in slot */
-                    bdcmd.buffer_handle,
-                    slot, bdslot->os_data_ptr, offset);
-        return r;
-    }
-
-    bdslot->data_length = len;
-
-    if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR)
-    {
-        if (slot >= card->config_data.num_fromhost_data_slots)
-        {
-            unifi_error(card->ospriv,
-                        "Invalid from-host data slot in SDIO_CMD_FROM_HOST_AND_CLEAR: %d\n",
-                        slot);
-            return CSR_RESULT_FAILURE;
-        }
-
-#ifdef CSR_WIFI_ALIGNMENT_WORKAROUND
-        /* moving this check before we clear host data slot */
-        if ((len != 0) && (dir == UNIFI_SDIO_WRITE) && (((ptrdiff_t)bdslot->os_data_ptr + offset) & 3))
-        {
-            kfree(host_bulk_data_slot);
-        }
-#endif
-
-        if (card->fh_slot_host_tag_record)
-        {
-            unifi_trace(card->ospriv, UDBG5, "CopyFromHostAndClearSlot Reset entry for slot=%d\n", slot);
-
-            /* reset the host tag entry for the corresponding slot */
-            card->fh_slot_host_tag_record[slot] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
-        }
-
-
-        /* Set length field in from_host_data array to 0 */
-        CardClearFromHostDataSlot(card, slot);
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* process_bulk_data_command() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  check_fh_sig_slots
- *
- *      Check whether there are <n> free signal slots available on UniFi.
- *      This takes into account the signals already batched since the
- *      from_host_signal counts were last read.
- *      If the from_host_signal counts indicate not enough space, we read
- *      the latest count from UniFi to see if some more have been freed.
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS, otherwise CSR error code on error.
- * ---------------------------------------------------------------------------
- */
-static CsrResult check_fh_sig_slots(card_t *card, u16 needed, s32 *space_fh)
-{
-    u32 count_fhw;
-    u32 occupied_fh, slots_fh;
-    s32 count_fhr;
-
-    count_fhw = card->from_host_signals_w;
-    count_fhr = card->from_host_signals_r;
-    slots_fh = card->config_data.num_fromhost_sig_frags;
-
-    /* Only read the space in from-host queue if necessary */
-    occupied_fh = (count_fhw - count_fhr) % 128;
-
-    if (slots_fh < occupied_fh)
-    {
-        *space_fh = 0;
-    }
-    else
-    {
-        *space_fh = slots_fh - occupied_fh;
-    }
-
-    if ((occupied_fh != 0) && (*space_fh < needed))
-    {
-        count_fhr = unifi_read_shared_count(card, card->sdio_ctrl_addr + 2);
-        if (count_fhr < 0)
-        {
-            unifi_error(card->ospriv, "Failed to read from-host sig read count\n");
-            return CSR_RESULT_FAILURE;
-        }
-        card->from_host_signals_r = count_fhr; /* diag */
-
-        occupied_fh = (count_fhw - count_fhr) % 128;
-        *space_fh = slots_fh - occupied_fh;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* check_fh_sig_slots() */
-
-
-/*
-* If we are padding the From-Host signals to the SDIO block size,
-* we need to round up the needed_chunks to the SDIO block size.
-*/
-#define ROUND_UP_NEEDED_CHUNKS(_card, _needed_chunks) \
-    { \
-        u16 _chunks_per_block; \
-        u16 _chunks_in_last_block; \
- \
-        if (_card->sdio_io_block_pad) \
-        { \
-            _chunks_per_block = _card->sdio_io_block_size / _card->config_data.sig_frag_size; \
-            _chunks_in_last_block = _needed_chunks % _chunks_per_block; \
-            if (_chunks_in_last_block != 0) \
-            { \
-                _needed_chunks = _needed_chunks + (_chunks_per_block - _chunks_in_last_block); \
-            } \
-        } \
-    }
-
-
-#define ROUND_UP_SPACE_CHUNKS(_card, _space_chunks) \
-    { \
-        u16 _chunks_per_block; \
- \
-        if (_card->sdio_io_block_pad) \
-        { \
-            _chunks_per_block = _card->sdio_io_block_size / _card->config_data.sig_frag_size; \
-            _space_chunks = ((_space_chunks / _chunks_per_block) * _chunks_per_block); \
-        } \
-    }
-
-
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  process_fh_cmd_queue
- *
- *      Take one signal off the from-host queue and copy it to the UniFi.
- *      Does nothing if the UniFi has no slots free.
- *
- *  Arguments:
- *      card       Pointer to card context struct
- *      processed  Location to write:
- *                      0 if there is nothing on the queue to process
- *                      1 if a signal was successfully processed
- *
- *  Returns:
- *      CSR error code if an error occurred.
- *
- *  Notes:
- *      The from-host queue contains signal requests from the network driver
- *      and any UDI clients interspersed. UDI clients' requests have been stored
- *      in the from-host queue using the wire-format structures, as they arrive.
- *      All other requests are stored in the from-host queue using the host
- *      (cpu specific) structures. We use the is_packed member of the card_signal_t
- *      structure that describes the queue to make the distinction.
- * ---------------------------------------------------------------------------
- */
-static CsrResult process_fh_cmd_queue(card_t *card, s32 *processed)
-{
-    q_t *sigq = &card->fh_command_queue;
-
-    CsrResult r;
-    u16 pending_sigs;
-    u16 pending_chunks;
-    u16 needed_chunks;
-    s32 space_chunks;
-    u16 q_index;
-
-    *processed = 0;
-
-    /* Get the number of pending signals. */
-    pending_sigs = CSR_WIFI_HIP_Q_SLOTS_USED(sigq);
-    unifi_trace(card->ospriv, UDBG5, "proc_fh: %d pending\n", pending_sigs);
-    if (pending_sigs == 0)
-    {
-        /* Nothing to do */
-        return CSR_RESULT_SUCCESS;
-    }
-
-    /* Work out how many chunks we have waiting to send */
-    for (pending_chunks = 0, q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(sigq);
-         q_index != CSR_WIFI_HIP_Q_NEXT_W_SLOT(sigq);
-         q_index = CSR_WIFI_HIP_Q_WRAP(sigq, q_index + 1))
-    {
-        card_signal_t *csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, q_index);
-
-        /*
-         * Note that GET_CHUNKS_FOR() needs the size of the packed
-         * (wire-formatted) structure
-         */
-        pending_chunks += GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(csptr->signal_length + 2));
-    }
-
-    /*
-     * Check whether UniFi has space for all the buffered bulk-data
-     * commands and signals as well.
-     */
-    needed_chunks = pending_chunks + card->fh_buffer.count;
-
-    /* Round up to the block size if necessary */
-    ROUND_UP_NEEDED_CHUNKS(card, needed_chunks);
-
-    r = check_fh_sig_slots(card, needed_chunks, &space_chunks);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        /* Error */
-        unifi_error(card->ospriv, "Failed to read fh sig count\n");
-        return r;
-    }
-
-#ifdef CSR_WIFI_HIP_NOISY
-    unifi_error(card->ospriv, "proc_fh: %d chunks free, need %d\n",
-                space_chunks, needed_chunks);
-#endif /* CSR_WIFI_HIP_NOISY */
-
-
-    /*
-     * Coalesce as many from-host signals as possible
-     * into a single block and write using a single CMD53
-     */
-    if (needed_chunks > (u16)space_chunks)
-    {
-        /* Round up to the block size if necessary */
-        ROUND_UP_SPACE_CHUNKS(card, space_chunks);
-
-        /*
-         * If the f/w has less free chunks than those already pending
-         * return immediately.
-         */
-        if ((u16)space_chunks <= card->fh_buffer.count)
-        {
-            /*
-             * No room in UniFi for any signals after the buffered bulk
-             * data commands have been sent.
-             */
-            unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n",
-                        card->fh_buffer.count, space_chunks);
-            card->generate_interrupt = 1;
-            return CSR_RESULT_SUCCESS;
-        }
-        pending_chunks = (u16)(space_chunks - card->fh_buffer.count);
-    }
-
-    while (pending_sigs-- && pending_chunks > 0)
-    {
-        card_signal_t *csptr;
-        s16 i;
-        u16 sig_chunks, total_length, free_chunks_in_fh_buffer;
-        bulk_data_param_t bulkdata;
-        u8 *packed_sigptr;
-        u16 signal_length = 0;
-
-        /* Retrieve the entry at the head of the queue */
-        q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(sigq);
-
-        /* Get a pointer to the containing card_signal_t struct */
-        csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, q_index);
-
-        /* Get the new length of the packed signal */
-        signal_length = csptr->signal_length;
-
-        if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE))
-        {
-            unifi_error(card->ospriv, "process_fh_queue: Bad len: %d\n", signal_length);
-            return CSR_RESULT_FAILURE;
-        }
-
-        /* Need space for 2-byte SDIO protocol header + signal */
-        sig_chunks = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(signal_length + 2));
-
-        free_chunks_in_fh_buffer = GET_CHUNKS_FOR(card->config_data.sig_frag_size,
-                                                  (u16)((card->fh_buffer.buf + UNIFI_FH_BUF_SIZE) - card->fh_buffer.ptr));
-        if (free_chunks_in_fh_buffer < sig_chunks)
-        {
-            /* No more room */
-            unifi_notice(card->ospriv, "proc_fh_cmd_q: no room in fh buffer for 0x%.4X, deferring\n",
-                         (u16)(GET_SIGNAL_ID(csptr->sigbuf)));
-            break;
-        }
-
-        packed_sigptr = csptr->sigbuf;
-
-        /* Claim and set up a from-host data slot */
-        if (CSR_RESULT_FAILURE == CardWriteBulkData(card, csptr, UNIFI_TRAFFIC_Q_MLME))
-        {
-            unifi_notice(card->ospriv, "proc_fh_cmd_q: no fh data slots for 0x%.4X, deferring\n",
-                         (u16)(GET_SIGNAL_ID(csptr->sigbuf)));
-            break;
-        }
-
-        for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
-        {
-            if (csptr->bulkdata[i].data_length == 0)
-            {
-                UNIFI_INIT_BULK_DATA(&bulkdata.d[i]);
-            }
-            else
-            {
-                bulkdata.d[i].os_data_ptr = csptr->bulkdata[i].os_data_ptr;
-                bulkdata.d[i].data_length = csptr->bulkdata[i].data_length;
-            }
-
-            /* Pass the free responsibility to the lower layer. */
-            UNIFI_INIT_BULK_DATA(&csptr->bulkdata[i]);
-        }
-
-        unifi_trace(card->ospriv, UDBG2, "Sending signal 0x%.4X\n",
-                    GET_SIGNAL_ID(packed_sigptr));
-#ifdef CSR_WIFI_HIP_NOISY
-        unifi_error(card->ospriv, "Sending signal 0x%.4X\n",
-                    GET_SIGNAL_ID(packed_sigptr));
-#endif  /* CSR_WIFI_HIP_NOISY */
-
-
-        /* Append packed signal to F-H buffer */
-        total_length = sig_chunks * card->config_data.sig_frag_size;
-
-        card->fh_buffer.ptr[0] = (u8)(signal_length & 0xff);
-        card->fh_buffer.ptr[1] =
-            (u8)(((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4));
-
-        memcpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length);
-        memset(card->fh_buffer.ptr + 2 + signal_length, 0,
-                  total_length - (2 + signal_length));
-
-#ifdef CSR_WIFI_HIP_NOISY
-        unifi_error(card->ospriv, "proc_fh: fh_buffer %d bytes \n",
-                    signal_length + 2);
-        dump(card->fh_buffer.ptr, signal_length + 2);
-        unifi_trace(card->ospriv, UDBG1, " \n");
-#endif  /* CSR_WIFI_HIP_NOISY */
-
-        card->fh_buffer.ptr += total_length;
-        card->fh_buffer.count += sig_chunks;
-
-#ifdef CSR_WIFI_HIP_NOISY
-        unifi_error(card->ospriv, "Added %d to fh buf, len now %d, count %d\n",
-                    signal_length,
-                    card->fh_buffer.ptr - card->fh_buffer.buf,
-                    card->fh_buffer.count);
-#endif  /* CSR_WIFI_HIP_NOISY */
-
-        (*processed)++;
-        pending_chunks -= sig_chunks;
-
-        /* Log the signal to the UDI. */
-        /* UDI will get the packed structure */
-        /* Can not log the unpacked signal, unless we reconstruct it! */
-        if (card->udi_hook)
-        {
-            (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length,
-                              &bulkdata, UDI_LOG_FROM_HOST);
-        }
-
-        /* Remove entry from q */
-        csptr->signal_length = 0;
-        CSR_WIFI_HIP_Q_INC_R(sigq);
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* process_fh_cmd_queue() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  process_fh_traffic_queue
- *
- *      Take signals off the from-host queue and copy them to the UniFi.
- *      Does nothing if the UniFi has no slots free.
- *
- *  Arguments:
- *      card       Pointer to card context struct
- *      sigq       Pointer to the traffic queue
- *      processed  Pointer to location to write:
- *                      0 if there is nothing on the queue to process
- *                      1 if a signal was successfully processed
- *
- *  Returns:
- *      CSR error code if an error occurred.
- *
- *  Notes:
- *      The from-host queue contains signal requests from the network driver
- *      and any UDI clients interspersed.
- * ---------------------------------------------------------------------------
- */
-static CsrResult process_fh_traffic_queue(card_t *card, s32 *processed)
-{
-    q_t *sigq = card->fh_traffic_queue;
-
-    CsrResult r;
-    s16 n = 0;
-    s32 q_no;
-    u16 pending_sigs = 0;
-    u16 pending_chunks = 0;
-    u16 needed_chunks;
-    s32 space_chunks;
-    u16 q_index;
-    u32 host_tag = 0;
-    u16 slot_num = 0;
-
-    *processed = 0;
-
-    /* calculate how many signals are in queues and how many chunks are needed. */
-    for (n = UNIFI_NO_OF_TX_QS - 1; n >= 0; n--)
-    {
-        /* Get the number of pending signals. */
-        pending_sigs += CSR_WIFI_HIP_Q_SLOTS_USED(&sigq[n]);
-        unifi_trace(card->ospriv, UDBG5, "proc_fh%d: %d pending\n", n, pending_sigs);
-
-        /* Work out how many chunks we have waiting to send */
-        for (q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(&sigq[n]);
-             q_index != CSR_WIFI_HIP_Q_NEXT_W_SLOT(&sigq[n]);
-             q_index = CSR_WIFI_HIP_Q_WRAP(&sigq[n], q_index + 1))
-        {
-            card_signal_t *csptr = CSR_WIFI_HIP_Q_SLOT_DATA(&sigq[n], q_index);
-
-            /*
-             * Note that GET_CHUNKS_FOR() needs the size of the packed
-             * (wire-formatted) structure
-             */
-            pending_chunks += GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(csptr->signal_length + 2));
-        }
-    }
-
-    /* If there are no pending signals, just return */
-    if (pending_sigs == 0)
-    {
-        /* Nothing to do */
-        return CSR_RESULT_SUCCESS;
-    }
-
-    /*
-     * Check whether UniFi has space for all the buffered bulk-data
-     * commands and signals as well.
-     */
-    needed_chunks = pending_chunks + card->fh_buffer.count;
-
-    /* Round up to the block size if necessary */
-    ROUND_UP_NEEDED_CHUNKS(card, needed_chunks);
-
-    r = check_fh_sig_slots(card, needed_chunks, &space_chunks);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        /* Error */
-        unifi_error(card->ospriv, "Failed to read fh sig count\n");
-        return r;
-    }
-
-#ifdef CSR_WIFI_HIP_NOISY
-    unifi_error(card->ospriv,
-                "process_fh_traffic_queue: %d chunks free, need %d\n",
-                space_chunks, needed_chunks);
-    read_fhsr(card);            /* debugging only */
-#endif /* CSR_WIFI_HIP_NOISY */
-
-    /* Coalesce as many from-host signals as possible
-       into a single block and write using a single CMD53 */
-    if (needed_chunks > (u16)space_chunks)
-    {
-        /* Round up to the block size if necessary */
-        ROUND_UP_SPACE_CHUNKS(card, space_chunks);
-
-        if ((u16)space_chunks <= card->fh_buffer.count)
-        {
-            /*
-             * No room in UniFi for any signals after the buffered bulk
-             * data commands have been sent.
-             */
-            unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n",
-                        card->fh_buffer.count, space_chunks);
-            card->generate_interrupt = 1;
-            return 0;
-        }
-
-        pending_chunks = (u16)space_chunks - card->fh_buffer.count;
-    }
-
-    q_no = UNIFI_NO_OF_TX_QS - 1;
-
-    /*
-     * pending_sigs will be exhausted if there are is no restriction to the pending
-     * signals per queue. pending_chunks may be exhausted if there is a restriction.
-     * q_no check will be exhausted if there is a restriction and our round-robin
-     * algorith fails to fill all chunks.
-     */
-    do
-    {
-        card_signal_t *csptr;
-        u16 sig_chunks, total_length, free_chunks_in_fh_buffer;
-        bulk_data_param_t bulkdata;
-        u8 *packed_sigptr;
-        u16 signal_length = 0;
-
-        /* if this queue is empty go to next one. */
-        if (CSR_WIFI_HIP_Q_SLOTS_USED(&sigq[q_no]) == 0)
-        {
-            q_no--;
-            continue;
-        }
-
-        /* Retrieve the entry at the head of the queue */
-        q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(&sigq[q_no]);
-
-        /* Get a pointer to the containing card_signal_t struct */
-        csptr = CSR_WIFI_HIP_Q_SLOT_DATA(&sigq[q_no], q_index);
-
-        /* Get the new length of the packed signal */
-        signal_length = csptr->signal_length;
-
-        if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE))
-        {
-            unifi_error(card->ospriv, "process_fh_traffic_queue: Bad len: %d\n", signal_length);
-            return CSR_RESULT_FAILURE;
-        }
-
-        /* Need space for 2-byte SDIO protocol header + signal */
-        sig_chunks = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(signal_length + 2));
-        free_chunks_in_fh_buffer = GET_CHUNKS_FOR(card->config_data.sig_frag_size,
-                                                  (u16)((card->fh_buffer.buf + UNIFI_FH_BUF_SIZE) - card->fh_buffer.ptr));
-        if (free_chunks_in_fh_buffer < sig_chunks)
-        {
-            /* No more room */
-            unifi_notice(card->ospriv, "process_fh_traffic_queue: no more chunks.\n");
-            break;
-        }
-
-        packed_sigptr = csptr->sigbuf;
-        /* Claim and set up a from-host data slot */
-        if (CSR_RESULT_FAILURE == CardWriteBulkData(card, csptr, (unifi_TrafficQueue)q_no))
-        {
-            q_no--;
-            continue;
-        }
-
-        /* Sanity check: MA-PACKET.req must have a valid bulk data */
-        if ((csptr->bulkdata[0].data_length == 0) || (csptr->bulkdata[0].os_data_ptr == NULL))
-        {
-            unifi_error(card->ospriv, "MA-PACKET.req with empty bulk data (%d bytes in %p)\n",
-                        csptr->bulkdata[0].data_length, csptr->bulkdata[0].os_data_ptr);
-            dump(packed_sigptr, signal_length);
-            return CSR_RESULT_FAILURE;
-        }
-
-        bulkdata.d[0].os_data_ptr = csptr->bulkdata[0].os_data_ptr;
-        bulkdata.d[0].data_length = csptr->bulkdata[0].data_length;
-        bulkdata.d[0].os_net_buf_ptr = csptr->bulkdata[0].os_net_buf_ptr;
-        bulkdata.d[0].net_buf_length = csptr->bulkdata[0].net_buf_length;
-
-        /* The driver owns clearing of HIP slots for following scenario
-         * - driver has requested a MA-PACKET.req signal
-         * - The f/w after receiving the signal decides it can't send it out due to various reasons
-         * - So the f/w without downloading the bulk data decides to just send a confirmation with fail
-         * - and then sends a clear slot signal to HIP
-         *
-         * But in some cases the clear slot signal never comes and the slot remains --NOT-- freed for ever
-         *
-         * To handle this, HIP will keep the record of host tag for each occupied slot
-         * and then based on status of that Host tag and slot the driver will decide if the slot is
-         * cleared by f/w signal or the slot has to be freed by driver
-         */
-
-        if (card->fh_slot_host_tag_record)
-        {
-            /* Update the f-h slot record for the corresponding host tag */
-            host_tag = GET_PACKED_MA_PACKET_REQUEST_HOST_TAG(packed_sigptr);
-            slot_num = GET_PACKED_DATAREF_SLOT(packed_sigptr, 0) & 0x00FF;
-
-            unifi_trace(card->ospriv, UDBG5,
-                        "process_fh_traffic_queue signal ID =%x fh slot=%x Host tag =%x\n",
-                        GET_SIGNAL_ID(packed_sigptr), slot_num, host_tag);
-            card->fh_slot_host_tag_record[slot_num] = host_tag;
-        }
-        UNIFI_INIT_BULK_DATA(&bulkdata.d[1]);
-        UNIFI_INIT_BULK_DATA(&csptr->bulkdata[0]);
-        UNIFI_INIT_BULK_DATA(&csptr->bulkdata[1]);
-
-#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
-        if (bulkdata.d[0].os_data_ptr)
-        {
-            if ((*bulkdata.d[0].os_data_ptr) & 0x08)
-            {
-                card->cmd_prof.tx_count++;
-            }
-        }
-#endif
-        unifi_trace(card->ospriv, UDBG3, "Sending signal 0x%.4X\n",
-                    GET_SIGNAL_ID(packed_sigptr));
-#ifdef CSR_WIFI_HIP_NOISY
-        unifi_error(card->ospriv, "Sending signal 0x%.4X\n",
-                    GET_SIGNAL_ID(packed_sigptr));
-#endif  /* CSR_WIFI_HIP_NOISY */
-
-        /* Append packed signal to F-H buffer */
-        total_length = sig_chunks * card->config_data.sig_frag_size;
-
-        card->fh_buffer.ptr[0] = (u8)(signal_length & 0xff);
-        card->fh_buffer.ptr[1] =
-            (u8)(((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4));
-
-        memcpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length);
-        memset(card->fh_buffer.ptr + 2 + signal_length, 0,
-                  total_length - (2 + signal_length));
-
-#ifdef CSR_WIFI_HIP_NOISY
-        unifi_error(card->ospriv, "proc_fh: fh_buffer %d bytes \n",
-                    signal_length + 2);
-        dump(card->fh_buffer.ptr, signal_length + 2);
-        unifi_trace(card->ospriv, UDBG1, " \n");
-#endif  /* CSR_WIFI_HIP_NOISY */
-
-        card->fh_buffer.ptr += total_length;
-        card->fh_buffer.count += sig_chunks;
-
-#ifdef CSR_WIFI_HIP_NOISY
-        unifi_error(card->ospriv, "Added %d to fh buf, len now %d, count %d\n",
-                    signal_length,
-                    card->fh_buffer.ptr - card->fh_buffer.buf,
-                    card->fh_buffer.count);
-#endif  /* CSR_WIFI_HIP_NOISY */
-
-        (*processed)++;
-        pending_sigs--;
-        pending_chunks -= sig_chunks;
-
-        /* Log the signal to the UDI. */
-        /* UDI will get the packed structure */
-        /* Can not log the unpacked signal, unless we reconstruct it! */
-        if (card->udi_hook)
-        {
-            (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length,
-                              &bulkdata, UDI_LOG_FROM_HOST);
-        }
-
-        /* Remove entry from q */
-        csptr->signal_length = 0;
-        /* Note that the traffic queue has only one valid bulk data buffer. */
-        csptr->bulkdata[0].data_length = 0;
-
-        CSR_WIFI_HIP_Q_INC_R(&sigq[q_no]);
-    } while ((pending_sigs > 0) && (pending_chunks > 0) && (q_no >= 0));
-
-    return CSR_RESULT_SUCCESS;
-} /* process_fh_traffic_queue() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  flush_fh_buffer
- *
- *      Write out the cache from-hosts signals to the UniFi.
- *
- *  Arguments:
- *      card       Pointer to card context struct
- *
- *  Returns:
- *      CSR error code if an SDIO error occurred.
- * ---------------------------------------------------------------------------
- */
-static CsrResult flush_fh_buffer(card_t *card)
-{
-    CsrResult r;
-    u16 len;
-    u16 sig_units;
-    u16 data_round;
-    u16 chunks_in_last_block;
-    u16 padding_chunks;
-    u16 i;
-
-    len = card->fh_buffer.ptr - card->fh_buffer.buf;
-
-#ifdef CSR_WIFI_HIP_NOISY
-    unifi_error(card->ospriv, "fh_buffer is at %p, ptr= %p\n",
-                card->fh_buffer.buf, card->fh_buffer.ptr);
-#endif /* CSR_WIFI_HIP_NOISY */
-
-    if (len == 0)
-    {
-        return CSR_RESULT_SUCCESS;
-    }
-
-#ifdef CSR_WIFI_HIP_NOISY
-    if (dump_fh_buf)
-    {
-        dump(card->fh_buffer.buf, len);
-        dump_fh_buf = 0;
-    }
-#endif /* CSR_WIFI_HIP_NOISY */
-
-    if (card->sdio_io_block_pad)
-    {
-        /* Both of these are powers of 2 */
-        sig_units = card->config_data.sig_frag_size;
-        data_round = card->sdio_io_block_size;
-
-        if (data_round > sig_units)
-        {
-            chunks_in_last_block = (len % data_round) / sig_units;
-
-            if (chunks_in_last_block != 0)
-            {
-                padding_chunks = (data_round / sig_units) - chunks_in_last_block;
-
-                memset(card->fh_buffer.ptr, 0, padding_chunks * sig_units);
-                for (i = 0; i < padding_chunks; i++)
-                {
-                    card->fh_buffer.ptr[1] = SDIO_CMD_PADDING << 4;
-                    card->fh_buffer.ptr += sig_units;
-                }
-
-                card->fh_buffer.count += padding_chunks;
-                len += padding_chunks * sig_units;
-            }
-        }
-    }
-
-    r = unifi_bulk_rw(card,
-                      card->config_data.fromhost_sigbuf_handle,
-                      card->fh_buffer.buf,
-                      len, UNIFI_SDIO_WRITE);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write fh signals: %u bytes, error %d\n", len, r);
-        return r;
-    }
-
-    /* Update from-host-signals-written signal count */
-    card->from_host_signals_w =
-        (card->from_host_signals_w + card->fh_buffer.count) % 128u;
-    r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 0,
-                            (u8)card->from_host_signals_w);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write fh signal count %u with error %d\n",
-                    card->from_host_signals_w, r);
-        return r;
-    }
-    card->generate_interrupt = 1;
-
-    /* Reset the fh buffer pointer */
-    card->fh_buffer.ptr = card->fh_buffer.buf;
-    card->fh_buffer.count = 0;
-
-#ifdef CSR_WIFI_HIP_NOISY
-    unifi_error(card->ospriv, "END flush: fh len %d, count %d\n",
-                card->fh_buffer.ptr - card->fh_buffer.buf,
-                card->fh_buffer.count);
-#endif /* CSR_WIFI_HIP_NOISY */
-
-    return CSR_RESULT_SUCCESS;
-} /* flush_fh_buffer() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  restart_packet_flow
- *
- *      This function is called before the bottom-half thread sleeps.
- *      It checks whether both data and signal resources are available and
- *      then calls the OS-layer function to re-enable packet transmission.
- *
- *  Arguments:
- *      card       Pointer to card context struct
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void restart_packet_flow(card_t *card)
-{
-    u8 q;
-
-    /*
-     * We only look at the fh_traffic_queue, because that is where packets from
-     * the network stack are placed.
-     */
-    for (q = 0; q <= UNIFI_TRAFFIC_Q_VO; q++)
-    {
-        if (card_is_tx_q_paused(card, q) &&
-            CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[q]) >= RESUME_XMIT_THRESHOLD)
-        {
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-            unifi_debug_log_to_buf("U");
-#endif
-            card_tx_q_unpause(card, q);
-            unifi_restart_xmit(card->ospriv, (unifi_TrafficQueue)q);
-        }
-    }
-} /* restart_packet_flow() */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1713 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- * FILE: csr_wifi_hip_card_sdio_mem.c
- *
- * PURPOSE: Implementation of the Card API for SDIO.
- *
- * ---------------------------------------------------------------------------
- */
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_card.h"
-
-#define SDIO_RETRIES    3
-#define CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH 16
-
-
-#define retryable_sdio_error(_csrResult) (((_csrResult) == CSR_SDIO_RESULT_CRC_ERROR) || ((_csrResult) == CSR_SDIO_RESULT_TIMEOUT))
-
-
-/*
- * ---------------------------------------------------------------------------
- *  retrying_read8
- *  retrying_write8
- *
- *      These functions provide the first level of retry for SDIO operations.
- *      If an SDIO command fails for reason of a response timeout or CRC
- *      error, it is retried immediately. If three attempts fail we report a
- *      failure.
- *      If the command failed for any other reason, the failure is reported
- *      immediately.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      funcnum         The SDIO function to access.
- *                      Function 0 is the Card Configuration Register space,
- *                      function 1/2 is the UniFi register space.
- *      addr            Address to access
- *      pdata           Pointer in which to return the value read.
- *      data            Value to write.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS  on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- * ---------------------------------------------------------------------------
- */
-static CsrResult retrying_read8(card_t *card, s16 funcnum, u32 addr, u8 *pdata)
-{
-    CsrSdioFunction *sdio = card->sdio_if;
-    CsrResult r = CSR_RESULT_SUCCESS;
-    s16 retries;
-    CsrResult csrResult = CSR_RESULT_SUCCESS;
-
-    retries = 0;
-    while (retries++ < SDIO_RETRIES)
-    {
-        if (funcnum == 0)
-        {
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-            unifi_debug_log_to_buf("r0@%02X", addr);
-#endif
-            csrResult = CsrSdioF0Read8(sdio, addr, pdata);
-        }
-        else
-        {
-#ifdef CSR_WIFI_TRANSPORT_CSPI
-            unifi_error(card->ospriv,
-                        "retrying_read_f0_8: F1 8-bit reads are not allowed.\n");
-            return CSR_RESULT_FAILURE;
-#else
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-            unifi_debug_log_to_buf("r@%02X", addr);
-#endif
-            csrResult = CsrSdioRead8(sdio, addr, pdata);
-#endif
-        }
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        if (csrResult != CSR_RESULT_SUCCESS)
-        {
-            unifi_debug_log_to_buf("error=%X\n", csrResult);
-        }
-        else
-        {
-            unifi_debug_log_to_buf("=%X\n", *pdata);
-        }
-#endif
-        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-        {
-            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-        }
-        /*
-         * Try again for retryable (CRC or TIMEOUT) errors,
-         * break on success or fatal error
-         */
-        if (!retryable_sdio_error(csrResult))
-        {
-#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
-            card->cmd_prof.cmd52_count++;
-#endif
-            break;
-        }
-        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr);
-    }
-
-    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
-    {
-        unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries);
-    }
-
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
-                    addr, retries - 1);
-        /* Report any SDIO error as a general i/o error */
-        r = CSR_RESULT_FAILURE;
-    }
-
-    return r;
-} /* retrying_read8() */
-
-
-static CsrResult retrying_write8(card_t *card, s16 funcnum, u32 addr, u8 data)
-{
-    CsrSdioFunction *sdio = card->sdio_if;
-    CsrResult r = CSR_RESULT_SUCCESS;
-    s16 retries;
-    CsrResult csrResult = CSR_RESULT_SUCCESS;
-
-    retries = 0;
-    while (retries++ < SDIO_RETRIES)
-    {
-        if (funcnum == 0)
-        {
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-            unifi_debug_log_to_buf("w0@%02X=%X", addr, data);
-#endif
-            csrResult = CsrSdioF0Write8(sdio, addr, data);
-        }
-        else
-        {
-#ifdef CSR_WIFI_TRANSPORT_CSPI
-            unifi_error(card->ospriv,
-                        "retrying_write_f0_8: F1 8-bit writes are not allowed.\n");
-            return CSR_RESULT_FAILURE;
-#else
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-            unifi_debug_log_to_buf("w@%02X=%X", addr, data);
-#endif
-            csrResult = CsrSdioWrite8(sdio, addr, data);
-#endif
-        }
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        if (csrResult != CSR_RESULT_SUCCESS)
-        {
-            unifi_debug_log_to_buf(",error=%X", csrResult);
-        }
-        unifi_debug_string_to_buf("\n");
-#endif
-        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-        {
-            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-        }
-        /*
-         * Try again for retryable (CRC or TIMEOUT) errors,
-         * break on success or fatal error
-         */
-        if (!retryable_sdio_error(csrResult))
-        {
-#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
-            card->cmd_prof.cmd52_count++;
-#endif
-            break;
-        }
-        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n",
-                    data, funcnum, addr);
-    }
-
-    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
-    {
-        unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries);
-    }
-
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
-                    addr, retries - 1);
-        /* Report any SDIO error as a general i/o error */
-        r = CSR_RESULT_FAILURE;
-    }
-
-    return r;
-} /* retrying_write8() */
-
-
-static CsrResult retrying_read16(card_t *card, s16 funcnum,
-                                 u32 addr, u16 *pdata)
-{
-    CsrSdioFunction *sdio = card->sdio_if;
-    CsrResult r = CSR_RESULT_SUCCESS;
-    s16 retries;
-    CsrResult csrResult = CSR_RESULT_SUCCESS;
-
-    retries = 0;
-    while (retries++ < SDIO_RETRIES)
-    {
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        unifi_debug_log_to_buf("r@%02X", addr);
-#endif
-        csrResult = CsrSdioRead16(sdio, addr, pdata);
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        if (csrResult != CSR_RESULT_SUCCESS)
-        {
-            unifi_debug_log_to_buf("error=%X\n", csrResult);
-        }
-        else
-        {
-            unifi_debug_log_to_buf("=%X\n", *pdata);
-        }
-#endif
-        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-        {
-            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-        }
-
-        /*
-         * Try again for retryable (CRC or TIMEOUT) errors,
-         * break on success or fatal error
-         */
-        if (!retryable_sdio_error(csrResult))
-        {
-#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
-            card->cmd_prof.cmd52_count++;
-#endif
-            break;
-        }
-        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr);
-    }
-
-    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
-    {
-        unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries);
-    }
-
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
-                    addr, retries - 1);
-        /* Report any SDIO error as a general i/o error */
-        r = CSR_RESULT_FAILURE;
-    }
-
-    return r;
-} /* retrying_read16() */
-
-
-static CsrResult retrying_write16(card_t *card, s16 funcnum,
-                                  u32 addr, u16 data)
-{
-    CsrSdioFunction *sdio = card->sdio_if;
-    CsrResult r = CSR_RESULT_SUCCESS;
-    s16 retries;
-    CsrResult csrResult = CSR_RESULT_SUCCESS;
-
-    retries = 0;
-    while (retries++ < SDIO_RETRIES)
-    {
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        unifi_debug_log_to_buf("w@%02X=%X", addr, data);
-#endif
-        csrResult = CsrSdioWrite16(sdio, addr, data);
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        if (csrResult != CSR_RESULT_SUCCESS)
-        {
-            unifi_debug_log_to_buf(",error=%X", csrResult);
-        }
-        unifi_debug_string_to_buf("\n");
-#endif
-        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-        {
-            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-        }
-
-        /*
-         * Try again for retryable (CRC or TIMEOUT) errors,
-         * break on success or fatal error
-         */
-        if (!retryable_sdio_error(csrResult))
-        {
-#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
-            card->cmd_prof.cmd52_count++;
-#endif
-            break;
-        }
-        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n",
-                    data, funcnum, addr);
-    }
-
-    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
-    {
-        unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries);
-    }
-
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
-                    addr, retries - 1);
-        /* Report any SDIO error as a general i/o error */
-        r = CSR_RESULT_FAILURE;
-    }
-
-    return r;
-} /* retrying_write16() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  sdio_read_f0
- *
- *      Reads a byte value from the CCCR (func 0) area of UniFi.
- *
- *  Arguments:
- *      card    Pointer to card structure.
- *      addr    Address to read from
- *      pdata   Pointer in which to store the read value.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- * ---------------------------------------------------------------------------
- */
-CsrResult sdio_read_f0(card_t *card, u32 addr, u8 *pdata)
-{
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-    card->cmd_prof.cmd52_f0_r_count++;
-#endif
-    return retrying_read8(card, 0, addr, pdata);
-} /* sdio_read_f0() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  sdio_write_f0
- *
- *      Writes a byte value to the CCCR (func 0) area of UniFi.
- *
- *  Arguments:
- *      card    Pointer to card structure.
- *      addr    Address to read from
- *      data    Data value to write.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- * ---------------------------------------------------------------------------
- */
-CsrResult sdio_write_f0(card_t *card, u32 addr, u8 data)
-{
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-    card->cmd_prof.cmd52_f0_w_count++;
-#endif
-    return retrying_write8(card, 0, addr, data);
-} /* sdio_write_f0() */
-
-
-/*
- * ---------------------------------------------------------------------------
- * unifi_read_direct_8_or_16
- *
- *      Read a 8-bit value from the UniFi SDIO interface.
- *
- *  Arguments:
- *      card    Pointer to card structure.
- *      addr    Address to read from
- *      pdata   Pointer in which to return data.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_read_direct_8_or_16(card_t *card, u32 addr, u8 *pdata)
-{
-#ifdef CSR_WIFI_TRANSPORT_CSPI
-    u16 w;
-    CsrResult r;
-
-    r = retrying_read16(card, card->function, addr, &w);
-    *pdata = (u8)(w & 0xFF);
-    return r;
-#else
-    return retrying_read8(card, card->function, addr, pdata);
-#endif
-} /* unifi_read_direct_8_or_16() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_write_direct_8_or_16
- *
- *      Write a byte value to the UniFi SDIO interface.
- *
- *  Arguments:
- *      card    Pointer to card structure.
- *      addr    Address to write to
- *      data    Value to write.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error
- *
- *  Notes:
- *      If 8-bit write is used, the even address *must* be written second.
- *      This is because writes to odd bytes are cached and not committed
- *      to memory until the preceding even address is written.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_write_direct_8_or_16(card_t *card, u32 addr, u8 data)
-{
-    if (addr & 1)
-    {
-        unifi_warning(card->ospriv,
-                      "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
-                      addr);
-    }
-
-#ifdef CSR_WIFI_TRANSPORT_CSPI
-    return retrying_write16(card, card->function, addr, (u16)data);
-#else
-    return retrying_write8(card, card->function, addr, data);
-#endif
-} /* unifi_write_direct_8_or_16() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_read_direct16
- *
- *      Read a 16-bit value from the UniFi SDIO interface.
- *
- *  Arguments:
- *      card    Pointer to card structure.
- *      addr    Address to read from
- *      pdata   Pointer in which to return data.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *
- *  Notes:
- *      The even address *must* be read first. This is because reads from
- *      odd bytes are cached and read from memory when the preceding
- *      even address is read.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_read_direct16(card_t *card, u32 addr, u16 *pdata)
-{
-    return retrying_read16(card, card->function, addr, pdata);
-} /* unifi_read_direct16() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_write_direct16
- *
- *      Write a 16-bit value to the UniFi SDIO interface.
- *
- *  Arguments:
- *      card    Pointer to card structure.
- *      addr    Address to write to
- *      data    Value to write.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *
- *  Notes:
- *      The even address *must* be written second. This is because writes to
- *      odd bytes are cached and not committed to memory until the preceding
- *      even address is written.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_write_direct16(card_t *card, u32 addr, u16 data)
-{
-    return retrying_write16(card, card->function, addr, data);
-} /* unifi_write_direct16() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_read_direct32
- *
- *      Read a 32-bit value from the UniFi SDIO interface.
- *
- *  Arguments:
- *      card    Pointer to card structure.
- *      addr    Address to read from
- *      pdata   Pointer in which to return data.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_read_direct32(card_t *card, u32 addr, u32 *pdata)
-{
-    CsrResult r;
-    u16 w0, w1;
-
-    r = retrying_read16(card, card->function, addr, &w0);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    r = retrying_read16(card, card->function, addr + 2, &w1);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    *pdata = ((u32)w1 << 16) | (u32)w0;
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_read_direct32() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_read_directn_match
- *
- *      Read multiple 8-bit values from the UniFi SDIO interface,
- *      stopping when either we have read 'len' bytes or we have read
- *      a octet equal to 'match'.  If 'match' is not a valid octet
- *      then this function is the same as 'unifi_read_directn'.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      addr            Start address to read from.
- *      pdata           Pointer to which to write data.
- *      len             Maximum umber of bytes to read
- *      match           The value to stop reading at.
- *      num             Pointer to buffer to write number of bytes read
- *
- *  Returns:
- *      number of octets read on success, negative error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *
- *  Notes:
- *      The even address *must* be read first. This is because reads from
- *      odd bytes are cached and read from memory when the preceding
- *      even address is read.
- * ---------------------------------------------------------------------------
- */
-static CsrResult unifi_read_directn_match(card_t *card, u32 addr, void *pdata, u16 len, s8 m, u32 *num)
-{
-    CsrResult r;
-    u32 i;
-    u8 *cptr;
-    u16 w;
-
-    *num = 0;
-
-    cptr = (u8 *)pdata;
-    for (i = 0; i < len; i += 2)
-    {
-        r = retrying_read16(card, card->function, addr, &w);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            return r;
-        }
-
-        *cptr++ = ((u8)w & 0xFF);
-        if ((m >= 0) && (((s8)w & 0xFF) == m))
-        {
-            break;
-        }
-
-        if (i + 1 == len)
-        {
-            /* The len is odd. Ignore the last high byte */
-            break;
-        }
-
-        *cptr++ = ((u8)(w >> 8) & 0xFF);
-        if ((m >= 0) && (((s8)(w >> 8) & 0xFF) == m))
-        {
-            break;
-        }
-
-        addr += 2;
-    }
-
-    *num = (s32)(cptr - (u8 *)pdata);
-    return CSR_RESULT_SUCCESS;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_read_directn
- *
- *      Read multiple 8-bit values from the UniFi SDIO interface.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      addr            Start address to read from.
- *      pdata           Pointer to which to write data.
- *      len             Number of bytes to read
- *
- *  Returns:
- *      0 on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *
- *  Notes:
- *      The even address *must* be read first. This is because reads from
- *      odd bytes are cached and read from memory when the preceding
- *      even address is read.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_read_directn(card_t *card, u32 addr, void *pdata, u16 len)
-{
-    u32 num;
-
-    return unifi_read_directn_match(card, addr, pdata, len, -1, &num);
-} /* unifi_read_directn() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_write_directn
- *
- *      Write multiple 8-bit values to the UniFi SDIO interface.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      addr            Start address to write to.
- *      pdata           Source data pointer.
- *      len             Number of bytes to write, must be even.
- *
- *  Returns:
- *      0 on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *
- *  Notes:
- *      The UniFi has a peculiar 16-bit bus architecture. Writes are only
- *      committed to memory when an even address is accessed. Writes to
- *      odd addresses are cached and only committed if the next write is
- *      to the preceding address.
- *      This means we must write data as pairs of bytes in reverse order.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_write_directn(card_t *card, u32 addr, void *pdata, u16 len)
-{
-    CsrResult r;
-    u8 *cptr;
-    s16 signed_len;
-
-    cptr = (u8 *)pdata;
-    signed_len = (s16)len;
-    while (signed_len > 0)
-    {
-        /* This is UniFi-1 specific code. CSPI not supported so 8-bit write allowed */
-        r = retrying_write16(card, card->function, addr, *cptr);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            return r;
-        }
-
-        cptr += 2;
-        addr += 2;
-        signed_len -= 2;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_write_directn() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  set_dmem_page
- *  set_pmem_page
- *
- *      Set up the page register for the shared data memory window or program
- *      memory window.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      dmem_addr       UniFi shared-data-memory address to access.
- *      pmem_addr       UniFi program memory address to access. This includes
- *                        External FLASH memory at    0x000000
- *                        Processor program memory at 0x200000
- *                        External SRAM at memory     0x400000
- *      paddr           Location to write an SDIO address (24-bit) for
- *                       use in a unifi_read_direct or unifi_write_direct call.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
- *      CSR_RESULT_FAILURE an SDIO error occurred
- * ---------------------------------------------------------------------------
- */
-static CsrResult set_dmem_page(card_t *card, u32 dmem_addr, u32 *paddr)
-{
-    u16 page, addr;
-    u32 len;
-    CsrResult r;
-
-    *paddr = 0;
-
-    if (!ChipHelper_DecodeWindow(card->helper,
-                                 CHIP_HELPER_WINDOW_3,
-                                 CHIP_HELPER_WT_SHARED,
-                                 dmem_addr / 2,
-                                 &page, &addr, &len))
-    {
-        unifi_error(card->ospriv, "Failed to decode SHARED_DMEM_PAGE %08lx\n", dmem_addr);
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    if (page != card->dmem_page)
-    {
-        unifi_trace(card->ospriv, UDBG6, "setting dmem page=0x%X, addr=0x%lX\n", page, addr);
-
-        /* change page register */
-        r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, page);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n");
-            return r;
-        }
-
-        card->dmem_page = page;
-    }
-
-    *paddr = ((s32)addr * 2) + (dmem_addr & 1);
-
-    return CSR_RESULT_SUCCESS;
-} /* set_dmem_page() */
-
-
-static CsrResult set_pmem_page(card_t *card, u32 pmem_addr,
-                               enum chip_helper_window_type mem_type, u32 *paddr)
-{
-    u16 page, addr;
-    u32 len;
-    CsrResult r;
-
-    *paddr = 0;
-
-    if (!ChipHelper_DecodeWindow(card->helper,
-                                 CHIP_HELPER_WINDOW_2,
-                                 mem_type,
-                                 pmem_addr / 2,
-                                 &page, &addr, &len))
-    {
-        unifi_error(card->ospriv, "Failed to decode PROG MEM PAGE %08lx %d\n", pmem_addr, mem_type);
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    if (page != card->pmem_page)
-    {
-        unifi_trace(card->ospriv, UDBG6, "setting pmem page=0x%X, addr=0x%lX\n", page, addr);
-
-        /* change page register */
-        r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, page);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to write PROG MEM PAGE\n");
-            return r;
-        }
-
-        card->pmem_page = page;
-    }
-
-    *paddr = ((s32)addr * 2) + (pmem_addr & 1);
-
-    return CSR_RESULT_SUCCESS;
-} /* set_pmem_page() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  set_page
- *
- *      Sets up the appropriate page register to access the given address.
- *      Returns the sdio address at which the unifi address can be accessed.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      generic_addr    UniFi internal address to access, in Generic Pointer
- *                      format, i.e. top byte is space indicator.
- *      paddr           Location to write page address
- *                          SDIO address (24-bit) for use in a unifi_read_direct or
- *                          unifi_write_direct call
- *
- *  Returns:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  the address is invalid
- * ---------------------------------------------------------------------------
- */
-static CsrResult set_page(card_t *card, u32 generic_addr, u32 *paddr)
-{
-    s32 space;
-    u32 addr;
-    CsrResult r = CSR_RESULT_SUCCESS;
-
-    if (!paddr)
-    {
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-    *paddr = 0;
-    space = UNIFI_GP_SPACE(generic_addr);
-    addr = UNIFI_GP_OFFSET(generic_addr);
-    switch (space)
-    {
-        case UNIFI_SH_DMEM:
-            /* Shared Data Memory is accessed via the Shared Data Memory window */
-            r = set_dmem_page(card, addr, paddr);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            break;
-
-        case UNIFI_EXT_FLASH:
-            if (!ChipHelper_HasFlash(card->helper))
-            {
-                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
-                            generic_addr, card->helper);
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            /* External FLASH is accessed via the Program Memory window */
-            r = set_pmem_page(card, addr, CHIP_HELPER_WT_FLASH, paddr);
-            break;
-
-        case UNIFI_EXT_SRAM:
-            if (!ChipHelper_HasExtSram(card->helper))
-            {
-                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08l (helper=0x%x)\n",
-                            generic_addr, card->helper);
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            /* External SRAM is accessed via the Program Memory window */
-            r = set_pmem_page(card, addr, CHIP_HELPER_WT_EXT_SRAM, paddr);
-            break;
-
-        case UNIFI_REGISTERS:
-            /* Registers are accessed directly */
-            *paddr = addr;
-            break;
-
-        case UNIFI_PHY_DMEM:
-            r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
-            break;
-
-        case UNIFI_MAC_DMEM:
-            r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
-            break;
-
-        case UNIFI_BT_DMEM:
-            if (!ChipHelper_HasBt(card->helper))
-            {
-                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
-                            generic_addr, card->helper);
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            r = unifi_set_proc_select(card, UNIFI_PROC_BT);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
-            break;
-
-        case UNIFI_PHY_PMEM:
-            r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
-            break;
-
-        case UNIFI_MAC_PMEM:
-            r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
-            break;
-
-        case UNIFI_BT_PMEM:
-            if (!ChipHelper_HasBt(card->helper))
-            {
-                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
-                            generic_addr, card->helper);
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            r = unifi_set_proc_select(card, UNIFI_PROC_BT);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
-            break;
-
-        case UNIFI_PHY_ROM:
-            if (!ChipHelper_HasRom(card->helper))
-            {
-                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
-                            generic_addr, card->helper);
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
-            break;
-
-        case UNIFI_MAC_ROM:
-            if (!ChipHelper_HasRom(card->helper))
-            {
-                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
-                            generic_addr, card->helper);
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
-            break;
-
-        case UNIFI_BT_ROM:
-            if (!ChipHelper_HasRom(card->helper) || !ChipHelper_HasBt(card->helper))
-            {
-                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
-                            generic_addr, card->helper);
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            r = unifi_set_proc_select(card, UNIFI_PROC_BT);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                return r;
-            }
-            r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
-            break;
-
-        default:
-            unifi_error(card->ospriv, "Bad address space %d in generic pointer 0x%08lX (helper=0x%x)\n",
-                        space, generic_addr, card->helper);
-            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    return r;
-} /* set_page() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_set_proc_select
- *
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      select          Which XAP core to select
- *
- *  Returns:
- *      0 on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_set_proc_select(card_t *card, enum unifi_dbg_processors_select select)
-{
-    CsrResult r;
-
-    /* Verify the the select value is allowed. */
-    switch (select)
-    {
-        case UNIFI_PROC_MAC:
-        case UNIFI_PROC_PHY:
-        case UNIFI_PROC_BOTH:
-            break;
-
-
-        default:
-            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    if (card->proc_select != (u32)select)
-    {
-        r = unifi_write_direct16(card,
-                                 ChipHelper_DBG_HOST_PROC_SELECT(card->helper) * 2,
-                                 (u8)select);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to write to Proc Select register\n");
-            return r;
-        }
-
-        card->proc_select = (u32)select;
-    }
-
-    return CSR_RESULT_SUCCESS;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- * unifi_read_8_or_16
- *
- * Performs a byte read of the given address in shared data memory.
- * Set up the shared data memory page register as required.
- *
- * Arguments:
- * card Pointer to card structure.
- * unifi_addr UniFi shared-data-memory address to access.
- * pdata Pointer to a byte variable for the value read.
- *
- * Returns:
- * CSR_RESULT_SUCCESS on success, non-zero error code on error:
- * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
- * CSR_RESULT_FAILURE an SDIO error occurred
- * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_read_8_or_16(card_t *card, u32 unifi_addr, u8 *pdata)
-{
-    u32 sdio_addr;
-    CsrResult r;
-#ifdef CSR_WIFI_TRANSPORT_CSPI
-    u16 w;
-#endif
-
-    r = set_page(card, unifi_addr, &sdio_addr);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-    card->cmd_prof.cmd52_r8or16_count++;
-#endif
-#ifdef CSR_WIFI_TRANSPORT_CSPI
-    r = retrying_read16(card, card->function, sdio_addr, &w);
-    *pdata = (u8)(w & 0xFF);
-    return r;
-#else
-    return retrying_read8(card, card->function, sdio_addr, pdata);
-#endif
-} /* unifi_read_8_or_16() */
-
-
-/*
- * ---------------------------------------------------------------------------
- * unifi_write_8_or_16
- *
- * Performs a byte write of the given address in shared data memory.
- * Set up the shared data memory page register as required.
- *
- * Arguments:
- * card Pointer to card context struct.
- * unifi_addr UniFi shared-data-memory address to access.
- * data Value to write.
- *
- * Returns:
- * CSR_RESULT_SUCCESS on success, non-zero error code on error:
- * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
- * CSR_RESULT_FAILURE an SDIO error occurred
- * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
- *
- * Notes:
- * Beware using unifi_write8() because byte writes are not safe on UniFi.
- * Writes to odd bytes are cached, writes to even bytes perform a 16-bit
- * write with the previously cached odd byte.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_write_8_or_16(card_t *card, u32 unifi_addr, u8 data)
-{
-    u32 sdio_addr;
-    CsrResult r;
-#ifdef CSR_WIFI_TRANSPORT_CSPI
-    u16 w;
-#endif
-
-    r = set_page(card, unifi_addr, &sdio_addr);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    if (sdio_addr & 1)
-    {
-        unifi_warning(card->ospriv,
-                      "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
-                      sdio_addr);
-    }
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-    card->cmd_prof.cmd52_w8or16_count++;
-#endif
-#ifdef CSR_WIFI_TRANSPORT_CSPI
-    w = data;
-    return retrying_write16(card, card->function, sdio_addr, w);
-#else
-    return retrying_write8(card, card->function, sdio_addr, data);
-#endif
-} /* unifi_write_8_or_16() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_card_read16
- *
- *      Performs a 16-bit read of the given address in shared data memory.
- *      Set up the shared data memory page register as required.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      unifi_addr      UniFi shared-data-memory address to access.
- *      pdata           Pointer to a 16-bit int variable for the value read.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_card_read16(card_t *card, u32 unifi_addr, u16 *pdata)
-{
-    u32 sdio_addr;
-    CsrResult r;
-
-    r = set_page(card, unifi_addr, &sdio_addr);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-    card->cmd_prof.cmd52_r16_count++;
-#endif
-    return unifi_read_direct16(card, sdio_addr, pdata);
-} /* unifi_card_read16() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_card_write16
- *
- *      Performs a 16-bit write of the given address in shared data memory.
- *      Set up the shared data memory page register as required.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      unifi_addr      UniFi shared-data-memory address to access.
- *      pdata           Pointer to a byte variable for the value write.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_card_write16(card_t *card, u32 unifi_addr, u16 data)
-{
-    u32 sdio_addr;
-    CsrResult r;
-
-    r = set_page(card, unifi_addr, &sdio_addr);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-    card->cmd_prof.cmd52_w16_count++;
-#endif
-    return unifi_write_direct16(card, sdio_addr, data);
-} /* unifi_card_write16() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_read32
- *
- *      Performs a 32-bit read of the given address in shared data memory.
- *      Set up the shared data memory page register as required.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      unifi_addr      UniFi shared-data-memory address to access.
- *      pdata           Pointer to a int variable for the value read.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_read32(card_t *card, u32 unifi_addr, u32 *pdata)
-{
-    u32 sdio_addr;
-    CsrResult r;
-
-    r = set_page(card, unifi_addr, &sdio_addr);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-    card->cmd_prof.cmd52_r32_count++;
-#endif
-    return unifi_read_direct32(card, sdio_addr, pdata);
-} /* unifi_read32() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_card_readn
- *  unifi_readnz
- *
- *      Read multiple 8-bit values from the UniFi SDIO interface.
- *      This function interprets the address as a GenericPointer as
- *      defined in the UniFi Host Interface Protocol Specification.
- *      The readnz version of this function will stop when it reads a
- *      zero octet.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      unifi_addr      UniFi shared-data-memory address to access.
- *      pdata           Pointer to which to write data.
- *      len             Number of bytes to read
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_readn_match(card_t *card, u32 unifi_addr, void *pdata, u16 len, s8 match)
-{
-    u32 sdio_addr;
-    CsrResult r;
-    u32 num;
-
-    r = set_page(card, unifi_addr, &sdio_addr);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    r = unifi_read_directn_match(card, sdio_addr, pdata, len, match, &num);
-    return r;
-} /* unifi_readn_match() */
-
-
-CsrResult unifi_card_readn(card_t *card, u32 unifi_addr, void *pdata, u16 len)
-{
-    return unifi_readn_match(card, unifi_addr, pdata, len, -1);
-} /* unifi_card_readn() */
-
-
-CsrResult unifi_readnz(card_t *card, u32 unifi_addr, void *pdata, u16 len)
-{
-    return unifi_readn_match(card, unifi_addr, pdata, len, 0);
-} /* unifi_readnz() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_read_shared_count
- *
- *      Read signal count locations, checking for an SDIO error.  The
- *      signal count locations only contain a valid number if the
- *      highest bit isn't set.
- *
- *  Arguments:
- *      card            Pointer to card context structure.
- *      addr            Shared-memory address to read.
- *
- *  Returns:
- *      Value read from memory (0-127) or -1 on error
- * ---------------------------------------------------------------------------
- */
-s32 unifi_read_shared_count(card_t *card, u32 addr)
-{
-    u8 b;
-    /* I've increased this count, because I have seen cases where
-     * there were three reads in a row with the top bit set.  I'm not
-     * sure why this might have happened, but I can't see a problem
-     * with increasing this limit.  It's better to take a while to
-     * recover than to fail. */
-#define SHARED_READ_RETRY_LIMIT 10
-    s32 i;
-
-    /*
-     * Get the to-host-signals-written count.
-     * The top-bit will be set if the firmware was in the process of
-     * changing the value, in which case we read again.
-     */
-    /* Limit the number of repeats so we don't freeze */
-    for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++)
-    {
-        CsrResult r;
-        r = unifi_read_8_or_16(card, addr, &b);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            return -1;
-        }
-        if (!(b & 0x80))
-        {
-            /* There is a chance that the MSB may have contained invalid data
-             * (overflow) at the time it was read. Therefore mask off the MSB.
-             * This avoids a race between driver read and firmware write of the
-             * word, the value we need is in the lower 8 bits anway.
-             */
-            return (s32)(b & 0xff);
-        }
-    }
-
-    return -1;                  /* this function has changed in WMM mods */
-} /* unifi_read_shared_count() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_writen
- *
- *      Write multiple 8-bit values to the UniFi SDIO interface using CMD52
- *      This function interprets the address as a GenericPointer as
- *      defined in the UniFi Host Interface Protocol Specification.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      unifi_addr      UniFi shared-data-memory address to access.
- *      pdata           Pointer to which to write data.
- *      len             Number of bytes to write
- *
- *  Returns:
- *      0 on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE    an odd length or length too big.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_writen(card_t *card, u32 unifi_addr, void *pdata, u16 len)
-{
-    u32 sdio_addr;
-    CsrResult r;
-
-    r = set_page(card, unifi_addr, &sdio_addr);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    return unifi_write_directn(card, sdio_addr, pdata, len);
-} /* unifi_writen() */
-
-
-static CsrResult csr_sdio_block_rw(card_t *card, s16 funcnum,
-                                   u32 addr, u8 *pdata,
-                                   u16 count, s16 dir_is_write)
-{
-    CsrResult csrResult;
-
-    if (dir_is_write == UNIFI_SDIO_READ)
-    {
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        unifi_debug_log_to_buf("r@%02X#%X=", addr, count);
-#endif
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-        unifi_debug_log_to_buf("R");
-#endif
-        csrResult = CsrSdioRead(card->sdio_if, addr, pdata, count);
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-        unifi_debug_log_to_buf("<");
-#endif
-    }
-    else
-    {
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-        unifi_debug_log_to_buf("w@%02X#%X=", addr, count);
-        unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count);
-#endif
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-        unifi_debug_log_to_buf("W");
-#endif
-        csrResult = CsrSdioWrite(card->sdio_if, addr, pdata, count);
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-        unifi_debug_log_to_buf(">");
-#endif
-    }
-#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
-    card->cmd_prof.cmd53_count++;
-#endif
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        unifi_debug_log_to_buf("error=%X", csrResult);
-    }
-    else if (dir_is_write == UNIFI_SDIO_READ)
-    {
-        unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count);
-    }
-    unifi_debug_string_to_buf("\n");
-#endif
-    return csrResult;  /* CSR SDIO (not HIP) error code */
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_bulk_rw
- *
- *      Transfer bulk data to or from the UniFi SDIO interface.
- *      This function is used to read or write signals and bulk data.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      handle          Value to put in the Register Address field of the CMD53 req.
- *      data            Pointer to data to write.
- *      direction       One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *
- *  Notes:
- *      This function uses SDIO CMD53, which is the block transfer mode.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_bulk_rw(card_t *card, u32 handle, void *pdata,
-                        u32 len, s16 direction)
-{
-#define CMD53_RETRIES 3
-    /*
-     * Ideally instead of sleeping, we want to busy wait.
-     * Currently there is no framework API to do this. When it becomes available,
-     * we can use it to busy wait using usecs
-     */
-#define REWIND_RETRIES          15    /* when REWIND_DELAY==1msec, or 250 when REWIND_DELAY==50usecs */
-#define REWIND_POLLING_RETRIES  5
-#define REWIND_DELAY            1     /* msec or 50usecs */
-    CsrResult csrResult;              /* SDIO error code */
-    CsrResult r = CSR_RESULT_SUCCESS; /* HIP error code */
-    s16 retries = CMD53_RETRIES;
-    s16 stat_retries;
-    u8 stat;
-    s16 dump_read;
-#ifdef UNIFI_DEBUG
-    u8 *pdata_lsb = ((u8 *)&pdata) + card->lsb;
-#endif
-#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
-    static s16 fake_error;
-#endif
-
-    dump_read = 0;
-#ifdef UNIFI_DEBUG
-    if (*pdata_lsb & 1)
-    {
-        unifi_notice(card->ospriv, "CD53 request on a unaligned buffer (addr: 0x%X) dir %s-Host\n",
-                     pdata, (direction == UNIFI_SDIO_READ)?"To" : "From");
-        if (direction == UNIFI_SDIO_WRITE)
-        {
-            dump(pdata, (u16)len);
-        }
-        else
-        {
-            dump_read = 1;
-        }
-    }
-#endif
-
-    /* Defensive checks */
-    if (!pdata)
-    {
-        unifi_error(card->ospriv, "Null pdata for unifi_bulk_rw() len: %d\n", len);
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-    if ((len & 1) || (len > 0xffff))
-    {
-        unifi_error(card->ospriv, "Impossible CMD53 length requested: %d\n", len);
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    while (1)
-    {
-        csrResult = csr_sdio_block_rw(card, card->function, handle,
-                                      (u8 *)pdata, (u16)len,
-                                      direction);
-        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
-        {
-            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
-        }
-#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
-        if (++fake_error > 100)
-        {
-            fake_error = 90;
-            unifi_warning(card->ospriv, "Faking a CMD53 error,\n");
-            if (csrResult == CSR_RESULT_SUCCESS)
-            {
-                csrResult = CSR_RESULT_FAILURE;
-            }
-        }
-#endif
-        if (csrResult == CSR_RESULT_SUCCESS)
-        {
-            if (dump_read)
-            {
-                dump(pdata, (u16)len);
-            }
-            break;
-        }
-
-        /*
-         * At this point the SDIO driver should have written the I/O Abort
-         * register to notify UniFi that the command has failed.
-         * UniFi-1 and UniFi-2 (not UF6xxx) use the same register to store the
-         * Deep Sleep State. This means we have to restore the Deep Sleep
-         * State (AWAKE in any case since we can not perform a CD53 in any other
-         * state) by rewriting the I/O Abort register to its previous value.
-         */
-        if (card->chip_id <= SDIO_CARD_ID_UNIFI_2)
-        {
-            (void)unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
-        }
-
-        /* If csr_sdio_block_rw() failed in a non-retryable way, or retries exhausted
-         * then stop retrying
-         */
-        if (!retryable_sdio_error(csrResult))
-        {
-            unifi_error(card->ospriv, "Fatal error in a CMD53 transfer\n");
-            break;
-        }
-
-        /*
-         * These happen from time to time, try again
-         */
-        if (--retries == 0)
-        {
-            break;
-        }
-
-        unifi_trace(card->ospriv, UDBG4,
-                    "Error in a CMD53 transfer, retrying (h:%d,l:%u)...\n",
-                    (s16)handle & 0xff, len);
-
-        /* The transfer failed, rewind and try again */
-        r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 8,
-                                (u8)(handle & 0xff));
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            /*
-             * If we can't even do CMD52 (register read/write) then
-             * stop here.
-             */
-            unifi_error(card->ospriv, "Failed to write REWIND cmd\n");
-            return r;
-        }
-
-        /* Signal the UniFi to look for the rewind request. */
-        r = CardGenInt(card);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            return r;
-        }
-
-        /* Wait for UniFi to acknowledge the rewind */
-        stat_retries = REWIND_RETRIES;
-        while (1)
-        {
-            r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 8, &stat);
-            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-            {
-                return r;
-            }
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "Failed to read REWIND status\n");
-                return CSR_RESULT_FAILURE;
-            }
-
-            if (stat == 0)
-            {
-                break;
-            }
-            if (--stat_retries == 0)
-            {
-                unifi_error(card->ospriv, "Timeout waiting for REWIND ready\n");
-                return CSR_RESULT_FAILURE;
-            }
-
-            /* Poll for the ack a few times */
-            if (stat_retries < REWIND_RETRIES - REWIND_POLLING_RETRIES)
-            {
-                CsrThreadSleep(REWIND_DELAY);
-            }
-        }
-    }
-
-    /* The call to csr_sdio_block_rw() still failed after retrying */
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Block %s failed after %d retries\n",
-                    (direction == UNIFI_SDIO_READ)?"read" : "write",
-                    CMD53_RETRIES - retries);
-        /* Report any SDIO error as a general i/o error */
-        return CSR_RESULT_FAILURE;
-    }
-
-    /* Collect some stats */
-    if (direction == UNIFI_SDIO_READ)
-    {
-        card->sdio_bytes_read += len;
-    }
-    else
-    {
-        card->sdio_bytes_written += len;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_bulk_rw() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_bulk_rw_noretry
- *
- *      Transfer bulk data to or from the UniFi SDIO interface.
- *      This function is used to read or write signals and bulk data.
- *
- *  Arguments:
- *      card            Pointer to card structure.
- *      handle          Value to put in the Register Address field of
- *                      the CMD53 req.
- *      data            Pointer to data to write.
- *      direction       One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
- *
- *  Returns:
- *      0 on success, non-zero error code on error:
- *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
- *      CSR_RESULT_FAILURE     an SDIO error occurred
- *
- *  Notes:
- *      This function uses SDIO CMD53, which is the block transfer mode.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_bulk_rw_noretry(card_t *card, u32 handle, void *pdata,
-                                u32 len, s16 direction)
-{
-    CsrResult csrResult;
-
-    csrResult = csr_sdio_block_rw(card, card->function, handle,
-                                  (u8 *)pdata, (u16)len, direction);
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Block %s failed\n",
-                    (direction == UNIFI_SDIO_READ)?"read" : "write");
-        return csrResult;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_bulk_rw_noretry() */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,793 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include "csr_macro.h"
-#include "csr_wifi_hip_chiphelper_private.h"
-
-#ifndef nelem
-#define nelem(a) (sizeof(a) / sizeof(a[0]))
-#endif
-
-#define counted(foo) { nelem(foo), foo }
-#define null_counted()  { 0, NULL }
-
-/* The init values are a set of register writes that we must
-   perform when we first connect to the chip to get it working.
-   They swicth on the correct clocks and possibly set the host
-   interface as a wkaeup source.  They should not be used if
-   proper HIP opperation is required, but are useful before we
-   do a code download. */
-static const struct chip_helper_init_values init_vals_v1[] = {
-    { 0xFDBB, 0xFFFF },
-    { 0xFDB6, 0x03FF },
-    { 0xFDB1, 0x01E3 },
-    { 0xFDB3, 0x0FFF },
-    { 0xFEE3, 0x08F0 },
-    { 0xFEE7, 0x3C3F },
-    { 0xFEE6, 0x0050 },
-    { 0xFDBA, 0x0000 }
-};
-
-static const struct chip_helper_init_values init_vals_v2[] = {
-    { 0xFDB6, 0x0FFF },
-    { 0xF023, 0x3F3F },
-    { 0xFDB1, 0x01E3 },
-    { 0xFDB3, 0x0FFF },
-    { 0xF003, 0x08F0 },
-    { 0xF007, 0x3C3F },
-    { 0xF006, 0x0050 }
-};
-
-
-static const struct chip_helper_init_values init_vals_v22_v23[] = {
-    { 0xF81C, 0x00FF },
-    /*{ 0x????, 0x???? }, */
-    { 0xF80C, 0x1FFF },
-    { 0xFA25, 0x001F },
-    { 0xF804, 0x00FF },
-    { 0xF802, 0x0FFF },
-    /*{ 0x????, 0x???? },
-      { 0x????, 0x???? },
-      { 0x????, 0x???? }*/
-};
-
-static const u16 reset_program_a_v1_or_v2[] = {
-    0x0000
-};
-static const u16 reset_program_b_v1_or_v2[] = {
-    0x0010, 0xFE00, 0xA021, 0xFF00, 0x8111, 0x0009, 0x0CA4, 0x0114,
-    0x0280, 0x04F8, 0xFE00, 0x6F25, 0x06E0, 0x0010, 0xFC00, 0x0121,
-    0xFC00, 0x0225, 0xFE00, 0x7125, 0xFE00, 0x6D11, 0x03F0, 0xFE00,
-    0x6E25, 0x0008, 0x00E0
-};
-
-static const struct chip_helper_reset_values reset_program_v1_or_v2[] =
-{
-    {
-        MAKE_GP(REGISTERS, 0x000C),
-        nelem(reset_program_a_v1_or_v2),
-        reset_program_a_v1_or_v2
-    },
-    {
-        MAKE_GP(MAC_PMEM, 0x000000),
-        nelem(reset_program_b_v1_or_v2),
-        reset_program_b_v1_or_v2
-    }
-};
-
-static const struct chip_map_address_t unifi_map_address_v1_v2[] =
-{
-    { 0xFE9F, 0xFE7B },     /* PM1_BANK_SELECT */
-    { 0xFE9E, 0xFE78 },     /* PM2_BANK_SELECT */
-    { 0xFE9D, 0xFE7E },     /* SHARED_DMEM_PAGE */
-    { 0xFE91, 0xFE90 },     /* PROC_SELECT */
-    { 0xFE8D, 0xFE8C },     /* STOP_STATUS */
-};
-
-static const struct chip_map_address_t unifi_map_address_v22_v23[] =
-{
-    { 0xF8F9, 0xF8AC },     /* GW1_CONFIG */
-    { 0xF8FA, 0xF8AD },     /* GW2_CONFIG */
-    { 0xF8FB, 0xF8AE },     /* GW3_CONFIG */
-    { 0xF830, 0xF81E },     /* PROC_SELECT */
-    { 0xF831, 0xF81F },     /* STOP_STATUS */
-    { 0xF8FC, 0xF8AF },     /* IO_LOG_ADDRESS */
-};
-
-static const struct chip_device_regs_t unifi_device_regs_null =
-{
-    0xFE81,                     /* GBL_CHIP_VERSION */
-    0x0000,                     /* GBL_MISC_ENABLES */
-    0x0000,                     /* DBG_EMU_CMD */
-    {
-        0x0000,                 /* HOST.DBG_PROC_SELECT */
-        0x0000,                 /* HOST.DBG_STOP_STATUS */
-        0x0000,                 /* HOST.WINDOW1_PAGE */
-        0x0000,                 /* HOST.WINDOW2_PAGE */
-        0x0000,                 /* HOST.WINDOW3_PAGE */
-        0x0000                  /* HOST.IO_LOG_ADDR */
-    },
-    {
-        0x0000,                 /* SPI.DBG_PROC_SELECT */
-        0x0000,                 /* SPI.DBG_STOP_STATUS */
-        0x0000,                 /* SPI.WINDOW1_PAGE */
-        0x0000,                 /* SPI.WINDOW2_PAGE */
-        0x0000,                 /* SPI.WINDOW3_PAGE */
-        0x0000                  /* SPI.IO_LOG_ADDR */
-    },
-    0x0000,                     /* DBG_RESET */
-    0x0000,                     /* > DBG_RESET_VALUE */
-    0x0000,                     /* DBG_RESET_WARN */
-    0x0000,                     /* DBG_RESET_WARN_VALUE */
-    0x0000,                     /* DBG_RESET_RESULT */
-    0xFFE9,                     /* XAP_PCH */
-    0xFFEA,                     /* XAP_PCL */
-    0x0000,                     /* PROC_PC_SNOOP */
-    0x0000,                     /* WATCHDOG_DISABLE */
-    0x0000,                     /* MAILBOX0 */
-    0x0000,                     /* MAILBOX1 */
-    0x0000,                     /* MAILBOX2 */
-    0x0000,                     /* MAILBOX3 */
-    0x0000,                     /* SDIO_HOST_INT */
-    0x0000,                     /* SHARED_IO_INTERRUPT */
-    0x0000,                     /* SDIO HIP HANDSHAKE */
-    0x0000                      /* COEX_STATUS */
-};
-
-/* UF105x */
-static const struct chip_device_regs_t unifi_device_regs_v1 =
-{
-    0xFE81,                     /* GBL_CHIP_VERSION */
-    0xFE87,                     /* GBL_MISC_ENABLES */
-    0xFE9C,                     /* DBG_EMU_CMD */
-    {
-        0xFE90,                 /* HOST.DBG_PROC_SELECT */
-        0xFE8C,                 /* HOST.DBG_STOP_STATUS */
-        0xFE7B,                 /* HOST.WINDOW1_PAGE */
-        0xFE78,                 /* HOST.WINDOW2_PAGE */
-        0xFE7E,                 /* HOST.WINDOW3_PAGE */
-        0x0000                  /* HOST.IO_LOG_ADDR */
-    },
-    {
-        0xFE91,                 /* SPI.DBG_PROC_SELECT */
-        0xFE8D,                 /* SPI.DBG_STOP_STATUS */
-        0xFE9F,                 /* SPI.WINDOW1_PAGE */
-        0xFE9E,                 /* SPI.WINDOW2_PAGE */
-        0xFE9D,                 /* SPI.WINDOW3_PAGE */
-        0x0000                  /* SPI.IO_LOG_ADDR */
-    },
-    0xFE92,                     /* DBG_RESET */
-    0x0001,                     /* > DBG_RESET_VALUE */
-    0xFDA0,                     /* DBG_RESET_WARN (HOST_SELECT) */
-    0x0000,                     /* DBG_RESET_WARN_VALUE */
-    0xFE92,                     /* DBG_RESET_RESULT */
-    0xFFE9,                     /* XAP_PCH */
-    0xFFEA,                     /* XAP_PCL */
-    0x0051,                     /* PROC_PC_SNOOP */
-    0xFE70,                     /* WATCHDOG_DISABLE */
-    0xFE6B,                     /* MAILBOX0 */
-    0xFE6A,                     /* MAILBOX1 */
-    0xFE69,                     /* MAILBOX2 */
-    0xFE68,                     /* MAILBOX3 */
-    0xFE67,                     /* SDIO_HOST_INT */
-    0xFE65,                     /* SHARED_IO_INTERRUPT */
-    0xFDE9,                     /* SDIO HIP HANDSHAKE */
-    0x0000                      /* COEX_STATUS */
-};
-
-/* UF2... */
-static const struct chip_device_regs_t unifi_device_regs_v2 =
-{
-    0xFE81,                     /* GBL_CHIP_VERSION */
-    0xFE87,                     /* GBL_MISC_ENABLES */
-    0xFE9C,                     /* DBG_EMU_CMD */
-    {
-        0xFE90,                 /* HOST.DBG_PROC_SELECT */
-        0xFE8C,                 /* HOST.DBG_STOP_STATUS */
-        0xFE7B,                 /* HOST.WINDOW1_PAGE */
-        0xFE78,                 /* HOST.WINDOW2_PAGE */
-        0xFE7E,                 /* HOST.WINDOW3_PAGE */
-        0x0000                  /* HOST.IO_LOG_ADDR */
-    },
-    {
-        0xFE91,                 /* SPI.DBG_PROC_SELECT */
-        0xFE8D,                 /* SPI.DBG_STOP_STATUS */
-        0xFE9F,                 /* SPI.WINDOW1_PAGE */
-        0xFE9E,                 /* SPI.WINDOW2_PAGE */
-        0xFE9D,                 /* SPI.WINDOW3_PAGE */
-        0x0000                  /* SPI.IO_LOG_ADDR */
-    },
-    0xFE92,                     /* DBG_RESET */
-    0x0000,                     /* > DBG_RESET_VALUE */
-    0xFDE9,                     /* DBG_RESET_WARN (TEST_FLASH_DATA - SHARED_MAILBOX2B) */
-    0xFFFF,                     /* DBG_RESET_WARN_VALUE */
-    0xFDE9,                     /* DBG_RESET_RESULT (TEST_FLASH_DATA) */
-    0xFFE9,                     /* XAP_PCH */
-    0xFFEA,                     /* XAP_PCL */
-    0x0051,                     /* PROC_PC_SNOOP */
-    0xFE70,                     /* WATCHDOG_DISABLE */
-    0xFE6B,                     /* MAILBOX0 */
-    0xFE6A,                     /* MAILBOX1 */
-    0xFE69,                     /* MAILBOX2 */
-    0xFE68,                     /* MAILBOX3 */
-    0xFE67,                     /* SDIO_HOST_INT */
-    0xFE65,                     /* SHARED_IO_INTERRUPT */
-    0xFE69,                     /* SDIO HIP HANDSHAKE */
-    0x0000                      /* COEX_STATUS */
-};
-
-/* UF60xx */
-static const struct chip_device_regs_t unifi_device_regs_v22_v23 =
-{
-    0xFE81,                     /* GBL_CHIP_VERSION */
-    0xF84F,                     /* GBL_MISC_ENABLES */
-    0xF81D,                     /* DBG_EMU_CMD */
-    {
-        0xF81E,                 /* HOST.DBG_PROC_SELECT */
-        0xF81F,                 /* HOST.DBG_STOP_STATUS */
-        0xF8AC,                 /* HOST.WINDOW1_PAGE */
-        0xF8AD,                 /* HOST.WINDOW2_PAGE */
-        0xF8AE,                 /* HOST.WINDOW3_PAGE */
-        0xF8AF                  /* HOST.IO_LOG_ADDR */
-    },
-    {
-        0xF830,                 /* SPI.DBG_PROC_SELECT */
-        0xF831,                 /* SPI.DBG_STOP_STATUS */
-        0xF8F9,                 /* SPI.WINDOW1_PAGE */
-        0xF8FA,                 /* SPI.WINDOW2_PAGE */
-        0xF8FB,                 /* SPI.WINDOW3_PAGE */
-        0xF8FC                  /* SPI.IO_LOG_ADDR */
-    },
-    0xF82F,                     /* DBG_RESET */
-    0x0001,                     /* > DBG_RESET_VALUE */
-    0x0000,                     /* DBG_RESET_WARN */
-    0x0000,                     /* DBG_RESET_WARN_VALUE */
-    0xF82F,                     /* DBG_RESET_RESULT */
-    0xFFE9,                     /* XAP_PCH */
-    0xFFEA,                     /* XAP_PCL */
-    0x001B,                     /* PROC_PC_SNOOP */
-    0x0055,                     /* WATCHDOG_DISABLE */
-    0xF84B,                     /* MAILBOX0 */
-    0xF84C,                     /* MAILBOX1 */
-    0xF84D,                     /* MAILBOX2 */
-    0xF84E,                     /* MAILBOX3 */
-    0xF92F,                     /* SDIO_HOST_INT */
-    0xF92B,                     /* SDIO_FROMHOST_SCRTACH0 / SHARED_IO_INTERRUPT */
-    0xF84D,                     /* SDIO HIP HANDSHAKE (MAILBOX2) */
-    0xF9FB                      /* COEX_STATUS */
-};
-
-/* Program memory window on UF105x. */
-static const struct window_shift_info_t prog_window_array_unifi_v1_v2[CHIP_HELPER_WT_COUNT] =
-{
-    { TRUE, 11, 0x0200 }, /* CODE RAM */
-    { TRUE, 11, 0x0000 }, /* FLASH */
-    { TRUE, 11, 0x0400 }, /* External SRAM */
-    { FALSE, 0, 0 },      /* ROM */
-    { FALSE, 0, 0 }       /* SHARED */
-};
-
-/* Shared memory window on UF105x. */
-static const struct window_shift_info_t shared_window_array_unifi_v1_v2[CHIP_HELPER_WT_COUNT] =
-{
-    { FALSE, 0, 0 },      /* CODE RAM */
-    { FALSE, 0, 0 },      /* FLASH */
-    { FALSE, 0, 0 },      /* External SRAM */
-    { FALSE, 0, 0 },      /* ROM */
-    { TRUE, 11, 0x0000 }  /* SHARED */
-};
-
-/* One of the Generic Windows on UF60xx and later. */
-static const struct window_shift_info_t generic_window_array_unifi_v22_v23[CHIP_HELPER_WT_COUNT] =
-{
-    { TRUE, 11, 0x3800 }, /* CODE RAM */
-    { FALSE, 0, 0 },      /* FLASH */
-    { FALSE, 0, 0 },      /* External SRAM */
-    { TRUE, 11, 0x2000 }, /* ROM */
-    { TRUE, 11, 0x0000 }  /* SHARED */
-};
-
-/* The three windows on UF105x. */
-static const struct window_info_t prog1_window_unifi_v1_v2  = { 0x0000, 0x2000, 0x0080, prog_window_array_unifi_v1_v2 };
-static const struct window_info_t prog2_window_unifi_v1_v2  = { 0x2000, 0x2000, 0x0000, prog_window_array_unifi_v1_v2 };
-static const struct window_info_t shared_window_unifi_v1_v2 = { 0x4000, 0x2000, 0x0000, shared_window_array_unifi_v1_v2 };
-
-/* The three windows on UF60xx and later. */
-static const struct window_info_t generic1_window_unifi_v22_v23 = { 0x0000, 0x2000, 0x0080, generic_window_array_unifi_v22_v23 };
-static const struct window_info_t generic2_window_unifi_v22_v23 = { 0x2000, 0x2000, 0x0000, generic_window_array_unifi_v22_v23 };
-static const struct window_info_t generic3_window_unifi_v22_v23 = { 0x4000, 0x2000, 0x0000, generic_window_array_unifi_v22_v23 };
-
-static const struct chip_device_desc_t chip_device_desc_null =
-{
-    { FALSE, 0x0000, 0x0000, 0x00 },
-    "",
-    "",
-    null_counted(),                         /* init */
-    null_counted(),                         /* reset_prog */
-    &unifi_device_regs_null,                /* regs */
-    {
-        FALSE,                              /* has_flash */
-        FALSE,                              /* has_ext_sram */
-        FALSE,                              /* has_rom */
-        FALSE,                              /* has_bt */
-        FALSE,                              /* has_wlan */
-    },
-    null_counted(),
-    /* prog_offset */
-    {
-        0x00000000,
-        0x00000000,
-        0x00000000,
-        0x00000000
-    },
-    /* data_offset */
-    {
-        0x0000                              /* ram */
-    },
-    /* windows */
-    {
-        NULL,
-        NULL,
-        NULL
-    }
-};
-
-static const struct chip_device_desc_t unifi_device_desc_v1 =
-{
-    { FALSE, 0xf0ff, 0x1001, 0x01 },        /* UF105x R01 */
-    "UF105x",
-    "UniFi-1",
-    counted(init_vals_v1),                  /* init */
-    counted(reset_program_v1_or_v2),        /* reset_prog */
-    &unifi_device_regs_v1,                  /* regs */
-    {
-        TRUE,                               /* has_flash    */
-        TRUE,                               /* has_ext_sram */
-        FALSE,                              /* has_rom      */
-        FALSE,                              /* has_bt       */
-        TRUE,                               /* has_wlan */
-    },
-    counted(unifi_map_address_v1_v2),       /* map */
-    /* prog_offset */
-    {
-        0x00100000,                         /* ram */
-        0x00000000,                         /* rom (invalid) */
-        0x00000000,                         /* flash */
-        0x00200000,                         /* ext_ram */
-    },
-    /* data_offset */
-    {
-        0x8000                              /* ram */
-    },
-    /* windows */
-    {
-        &prog1_window_unifi_v1_v2,
-        &prog2_window_unifi_v1_v2,
-        &shared_window_unifi_v1_v2
-    }
-};
-
-static const struct chip_device_desc_t unifi_device_desc_v2 =
-{
-    { FALSE, 0xf0ff, 0x2001, 0x02 },        /* UF2... R02 */
-    "UF2...",
-    "UniFi-2",
-    counted(init_vals_v2),                  /* init */
-    counted(reset_program_v1_or_v2),        /* reset_prog */
-    &unifi_device_regs_v2,                  /* regs */
-    {
-        TRUE,                               /* has_flash    */
-        TRUE,                               /* has_ext_sram */
-        FALSE,                              /* has_rom      */
-        FALSE,                              /* has_bt      */
-        TRUE,                               /* has_wlan */
-    },
-    counted(unifi_map_address_v1_v2),       /* map */
-    /* prog_offset */
-    {
-        0x00100000,                         /* ram */
-        0x00000000,                         /* rom (invalid) */
-        0x00000000,                         /* flash */
-        0x00200000,                         /* ext_ram */
-    },
-    /* data_offset */
-    {
-        0x8000                              /* ram */
-    },
-    /* windows */
-    {
-        &prog1_window_unifi_v1_v2,
-        &prog2_window_unifi_v1_v2,
-        &shared_window_unifi_v1_v2
-    }
-};
-
-static const struct chip_device_desc_t unifi_device_desc_v3 =
-{
-    { FALSE, 0xf0ff, 0x3001, 0x02 },        /* UF2... R03 */
-    "UF2...",
-    "UniFi-3",
-    counted(init_vals_v2),                  /* init */
-    counted(reset_program_v1_or_v2),        /* reset_prog */
-    &unifi_device_regs_v2,                  /* regs */
-    {
-        TRUE,                               /* has_flash    */
-        TRUE,                               /* has_ext_sram */
-        FALSE,                              /* has_rom      */
-        FALSE,                              /* has_bt      */
-        TRUE,                               /* has_wlan */
-    },
-    counted(unifi_map_address_v1_v2),       /* map */
-    /* prog_offset */
-    {
-        0x00100000,                         /* ram */
-        0x00000000,                         /* rom (invalid) */
-        0x00000000,                         /* flash */
-        0x00200000,                         /* ext_ram */
-    },
-    /* data_offset */
-    {
-        0x8000                              /* ram */
-    },
-    /* windows */
-    {
-        &prog1_window_unifi_v1_v2,
-        &prog2_window_unifi_v1_v2,
-        &shared_window_unifi_v1_v2
-    }
-};
-
-static const struct chip_device_desc_t unifi_device_desc_v22 =
-{
-    { FALSE, 0x00ff, 0x0022, 0x07 },        /* UF60xx */
-    "UF60xx",
-    "UniFi-4",
-    counted(init_vals_v22_v23),             /* init */
-    null_counted(),                         /* reset_prog */
-    &unifi_device_regs_v22_v23,             /* regs */
-    {
-        FALSE,                              /* has_flash    */
-        FALSE,                              /* has_ext_sram */
-        TRUE,                               /* has_rom      */
-        FALSE,                              /* has_bt       */
-        TRUE,                               /* has_wlan */
-    },
-    counted(unifi_map_address_v22_v23),     /* map */
-    /* prog_offset */
-    {
-        0x00C00000,                         /* ram */
-        0x00000000,                         /* rom */
-        0x00000000,                         /* flash (invalid) */
-        0x00000000,                         /* ext_ram (invalid) */
-    },
-    /* data_offset */
-    {
-        0x8000                              /* ram */
-    },
-    /* windows */
-    {
-        &generic1_window_unifi_v22_v23,
-        &generic2_window_unifi_v22_v23,
-        &generic3_window_unifi_v22_v23
-    }
-};
-
-static const struct chip_device_desc_t unifi_device_desc_v23 =
-{
-    { FALSE, 0x00ff, 0x0023, 0x08 },        /* UF.... */
-    "UF....",
-    "UF.... (5)",
-    counted(init_vals_v22_v23),             /* init */
-    null_counted(),                         /* reset_prog */
-    &unifi_device_regs_v22_v23,             /* regs */
-    {
-        FALSE,                              /* has_flash    */
-        FALSE,                              /* has_ext_sram */
-        TRUE,                               /* has_rom      */
-        TRUE,                               /* has_bt       */
-        TRUE,                               /* has_wlan */
-    },
-    counted(unifi_map_address_v22_v23),
-    /* prog_offset */
-    {
-        0x00C00000,                         /* ram */
-        0x00000000,                         /* rom */
-        0x00000000,                         /* flash (invalid) */
-        0x00000000,                         /* ext_sram (invalid) */
-    },
-    /* data_offset */
-    {
-        0x8000                              /* ram */
-    },
-    /* windows */
-    {
-        &generic1_window_unifi_v22_v23,
-        &generic2_window_unifi_v22_v23,
-        &generic3_window_unifi_v22_v23
-    }
-};
-
-static const struct chip_device_desc_t hyd_wlan_subsys_desc_v1 =
-{
-    { FALSE, 0x00ff, 0x0044, 0x00 },        /* UF.... */
-    "HYD...",
-    "HYD...    ",
-    counted(init_vals_v22_v23),             /* init */
-    null_counted(),                         /* reset_prog */
-    &unifi_device_regs_v22_v23,             /* regs */
-    {
-        FALSE,                              /* has_flash    */
-        FALSE,                              /* has_ext_sram */
-        TRUE,                               /* has_rom      */
-        FALSE,                              /* has_bt       */
-        TRUE,                               /* has_wlan */
-    },
-    counted(unifi_map_address_v22_v23),
-    /* prog_offset */
-    {
-        0x00C00000,                         /* ram */
-        0x00000000,                         /* rom */
-        0x00000000,                         /* flash (invalid) */
-        0x00000000,                         /* ext_sram (invalid) */
-    },
-    /* data_offset */
-    {
-        0x8000                              /* ram */
-    },
-    /* windows */
-    {
-        &generic1_window_unifi_v22_v23,
-        &generic2_window_unifi_v22_v23,
-        &generic3_window_unifi_v22_v23
-    }
-};
-
-
-/* This is the list of all chips that we know about.  I'm
-   assuming that the order here will be important - we
-   might have multiple entries witrh the same SDIO id for
-   instance.  The first one in this list will be the one
-   that is returned if a search is done on only that id.
-   The client will then have to call GetVersionXXX again
-   but with more detailed info.
-
-   I don't know if we need to signal this up to the client
-   in some way?
-
-   (We get the SDIO id before we know anything else about
-   the chip.  We might not be able to read any of the other
-   registers at first, but we still need to know about the
-   chip). */
-static const struct chip_device_desc_t *chip_ver_to_desc[] =
-{
-    &unifi_device_desc_v1,      /* UF105x R01 */
-    &unifi_device_desc_v2,      /* UF2... R02 */
-    &unifi_device_desc_v3,      /* UF2... R03 */
-    &unifi_device_desc_v22,     /* UF60xx */
-    &unifi_device_desc_v23,     /* UF.... */
-    &hyd_wlan_subsys_desc_v1
-};
-
-ChipDescript* ChipHelper_GetVersionSdio(u8 sdio_ver)
-{
-    u32 i;
-
-    for (i = 0; i < nelem(chip_ver_to_desc); i++)
-    {
-        if (chip_ver_to_desc[i]->chip_version.sdio == sdio_ver)
-        {
-            return chip_ver_to_desc[i];
-        }
-    }
-
-    return &chip_device_desc_null;
-}
-
-
-ChipDescript* ChipHelper_GetVersionAny(u16 from_FF9A, u16 from_FE81)
-{
-    u32 i;
-
-    if ((from_FF9A & 0xFF00) != 0)
-    {
-        for (i = 0; i < nelem(chip_ver_to_desc); i++)
-        {
-            if (chip_ver_to_desc[i]->chip_version.pre_bc7 &&
-                ((from_FF9A & chip_ver_to_desc[i]->chip_version.mask) ==
-                 chip_ver_to_desc[i]->chip_version.result))
-            {
-                return chip_ver_to_desc[i];
-            }
-        }
-    }
-    else
-    {
-        for (i = 0; i < nelem(chip_ver_to_desc); i++)
-        {
-            if (!chip_ver_to_desc[i]->chip_version.pre_bc7 &&
-                ((from_FE81 & chip_ver_to_desc[i]->chip_version.mask) ==
-                 chip_ver_to_desc[i]->chip_version.result))
-            {
-                return chip_ver_to_desc[i];
-            }
-        }
-    }
-
-    return &chip_device_desc_null;
-}
-
-
-ChipDescript* ChipHelper_GetVersionUniFi(u16 ver)
-{
-    return ChipHelper_GetVersionAny(0x0000, ver);
-}
-
-
-ChipDescript *ChipHelper_Null(void)
-{
-    return &chip_device_desc_null;
-}
-
-
-ChipDescript* ChipHelper_GetVersionBlueCore(enum chip_helper_bluecore_age bc_age, u16 version)
-{
-    if (bc_age == chip_helper_bluecore_pre_bc7)
-    {
-        return ChipHelper_GetVersionAny(version, 0x0000);
-    }
-    else
-    {
-        return ChipHelper_GetVersionAny(0x0000, version);
-    }
-}
-
-
-/* Expand the DEF0 functions into simple code to return the
-   correct thing.  The DEF1 functions expand to nothing in
-   this X macro expansion. */
-#define CHIP_HELPER_DEF0_C_DEF(ret_type, name, info)            \
-    ret_type ChipHelper_ ## name(ChipDescript * chip_help)           \
-    {                                                               \
-        return chip_help->info;                                     \
-    }
-#define CHIP_HELPER_DEF1_C_DEF(ret_type, name, type1, name1)
-
-CHIP_HELPER_LIST(C_DEF)
-
-/*
- * Map register addresses between HOST and SPI access.
- */
-u16 ChipHelper_MapAddress_SPI2HOST(ChipDescript *chip_help, u16 addr)
-{
-    u32 i;
-    for (i = 0; i < chip_help->map.len; i++)
-    {
-        if (chip_help->map.vals[i].spi == addr)
-        {
-            return chip_help->map.vals[i].host;
-        }
-    }
-    return addr;
-}
-
-
-u16 ChipHelper_MapAddress_HOST2SPI(ChipDescript *chip_help, u16 addr)
-{
-    u32 i;
-    for (i = 0; i < chip_help->map.len; i++)
-    {
-        if (chip_help->map.vals[i].host == addr)
-        {
-            return chip_help->map.vals[i].spi;
-        }
-    }
-    return addr;
-}
-
-
-/* The address returned by this function is the start of the
-   window in the address space, that is where we can start
-   accessing data from.  If a section of the window at the
-   start is unusable because something else is cluttering up
-   the address map then that is taken into account and this
-   function returns that address justt past that. */
-u16 ChipHelper_WINDOW_ADDRESS(ChipDescript                 *chip_help,
-                                    enum chip_helper_window_index window)
-{
-    if (window < CHIP_HELPER_WINDOW_COUNT &&
-        chip_help->windows[window] != NULL)
-    {
-        return chip_help->windows[window]->address + chip_help->windows[window]->blocked;
-    }
-    return 0;
-}
-
-
-/* This returns the size of the window minus any blocked section */
-u16 ChipHelper_WINDOW_SIZE(ChipDescript                 *chip_help,
-                                 enum chip_helper_window_index window)
-{
-    if (window < CHIP_HELPER_WINDOW_COUNT &&
-        chip_help->windows[window] != NULL)
-    {
-        return chip_help->windows[window]->size - chip_help->windows[window]->blocked;
-    }
-    return 0;
-}
-
-
-/* Get the register writes we should do to make sure that
-   the chip is running with most clocks on. */
-u32 ChipHelper_ClockStartupSequence(ChipDescript                          *chip_help,
-                                          const struct chip_helper_init_values **val)
-{
-    *val = chip_help->init.vals;
-    return chip_help->init.len;
-}
-
-
-/* Get the set of values tat we should write to the chip to perform a reset. */
-u32 ChipHelper_HostResetSequence(ChipDescript                           *chip_help,
-                                       const struct chip_helper_reset_values **val)
-{
-    *val = chip_help->reset_prog.vals;
-    return chip_help->reset_prog.len;
-}
-
-
-/* Decode a windowed access to the chip. */
-s32 ChipHelper_DecodeWindow(ChipDescript *chip_help,
-                                 enum chip_helper_window_index window,
-                                 enum chip_helper_window_type type,
-                                 u32 offset,
-                                 u16 *page, u16 *addr, u32 *len)
-{
-    const struct window_info_t *win;
-    const struct window_shift_info_t *mode;
-    u16 of, pg;
-
-    if (window >= CHIP_HELPER_WINDOW_COUNT)
-    {
-        return FALSE;
-    }
-    if ((win = chip_help->windows[window]) == NULL)
-    {
-        return FALSE;
-    }
-    if (type >= CHIP_HELPER_WT_COUNT)
-    {
-        return FALSE;
-    }
-    if ((mode = &win->mode[type]) == NULL)
-    {
-        return FALSE;
-    }
-    if (!mode->allowed)
-    {
-        return FALSE;
-    }
-
-    pg = (u16)(offset >> mode->page_shift) + mode->page_offset;
-    of = (u16)(offset & ((1 << mode->page_shift) - 1));
-    /* If 'blocked' is zero this does nothing, else decrease
-       the page register and increase the offset until we aren't
-       in the blocked region of the window. */
-    while (of < win->blocked)
-    {
-        of += 1 << mode->page_shift;
-        pg--;
-    }
-    *page = pg;
-    *addr = win->address + of;
-    *len = win->size - of;
-    return TRUE;
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,407 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_HIP_CHIPHELPER_H__
-#define CSR_WIFI_HIP_CHIPHELPER_H__
-
-
-#include <linux/types.h>
-
-/* The age of the BlueCore chip.  This is probably not useful, if
-   you know the age then you can probably work out the version directly. */
-enum chip_helper_bluecore_age
-{
-    chip_helper_bluecore_pre_bc7,
-    chip_helper_bluecore_bc7_or_later
-};
-
-/* We support up to three windowed regions at the moment.
-   Don't reorder these - they're used to index into an array. */
-enum chip_helper_window_index
-{
-    CHIP_HELPER_WINDOW_1        = 0,
-    CHIP_HELPER_WINDOW_2        = 1,
-    CHIP_HELPER_WINDOW_3        = 2,
-    CHIP_HELPER_WINDOW_COUNT    = 3
-};
-
-/* These are the things that we can access through a window.
-   Don't reorder these - they're used to index into an array. */
-enum chip_helper_window_type
-{
-    CHIP_HELPER_WT_CODE_RAM = 0,
-    CHIP_HELPER_WT_FLASH    = 1,
-    CHIP_HELPER_WT_EXT_SRAM = 2,
-    CHIP_HELPER_WT_ROM      = 3,
-    CHIP_HELPER_WT_SHARED   = 4,
-    CHIP_HELPER_WT_COUNT    = 5
-};
-
-/* Commands to stop and start the XAP */
-enum chip_helper_dbg_emu_cmd_enum
-{
-    CHIP_HELPER_DBG_EMU_CMD_XAP_STEP_MASK   = 0x0001,
-    CHIP_HELPER_DBG_EMU_CMD_XAP_RUN_B_MASK  = 0x0002,
-    CHIP_HELPER_DBG_EMU_CMD_XAP_BRK_MASK    = 0x0004,
-    CHIP_HELPER_DBG_EMU_CMD_XAP_WAKEUP_MASK = 0x0008
-};
-
-/* Bitmasks for Stop and sleep status: DBG_SPI_STOP_STATUS & DBG_HOST_STOP_STATUS */
-enum chip_helper_dbg_stop_status_enum
-{
-    CHIP_HELPER_DBG_STOP_STATUS_NONE_MASK               = 0x0000,
-    CHIP_HELPER_DBG_STOP_STATUS_P0_MASK                 = 0x0001,
-    CHIP_HELPER_DBG_STOP_STATUS_P1_MASK                 = 0x0002,
-    CHIP_HELPER_DBG_STOP_STATUS_P2_MASK                 = 0x0004,
-    CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P0_MASK    = 0x0008,
-    CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P1_MASK    = 0x0010,
-    CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_P2_MASK    = 0x0020,
-    /* Legacy names/alias */
-    CHIP_HELPER_DBG_STOP_STATUS_MAC_MASK                = 0x0001,
-    CHIP_HELPER_DBG_STOP_STATUS_PHY_MASK                = 0x0002,
-    CHIP_HELPER_DBG_STOP_STATUS_BT_MASK                 = 0x0004,
-    CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_MAC_MASK   = 0x0008,
-    CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_PHY_MASK   = 0x0010,
-    CHIP_HELPER_DBG_STOP_STATUS_SLEEP_STATUS_BT_MASK    = 0x0020
-};
-
-/* Codes to disable the watchdog */
-enum chip_helper_watchdog_disable_enum
-{
-    CHIP_HELPER_WATCHDOG_DISABLE_CODE1 = 0x6734,
-    CHIP_HELPER_WATCHDOG_DISABLE_CODE2 = 0xD6BF,
-    CHIP_HELPER_WATCHDOG_DISABLE_CODE3 = 0xC31E
-};
-
-/* Other bits have changed between versions */
-enum chip_helper_gbl_misc_enum
-{
-    CHIP_HELPER_GBL_MISC_SPI_STOP_OUT_EN_MASK  = 0x0001,
-    CHIP_HELPER_GBL_MISC_MMU_INIT_DONE_MASK    = 0x0004
-};
-
-/* Coex status register, contains interrupt status and reset pullup status.
- * CHIP_HELPER_COEX_STATUS_RST_PULLS_MSB_MASK can be used to check
- * for WAPI on R03 chips and later. */
-enum chip_helper_coex_status_mask_enum
-{
-    CHIP_HELPER_COEX_STATUS_RST_PULLS_LSB_MASK   = 0x0001,
-    CHIP_HELPER_COEX_STATUS_RST_PULLS_MSB_MASK   = 0x0008,
-    CHIP_HELPER_COEX_STATUS_WL_FEC_PINS_LSB_MASK = 0x0010,
-    CHIP_HELPER_COEX_STATUS_WL_FEC_PINS_MSB_MASK = 0x0080,
-    CHIP_HELPER_COEX_STATUS_INT_UART_MASK        = 0x0100,
-    CHIP_HELPER_COEX_STATUS_INT_BT_LEG_MASK      = 0x0200
-};
-
-/* How to select the different CPUs */
-enum chip_helper_dbg_proc_sel_enum
-{
-    CHIP_HELPER_DBG_PROC_SEL_MAC  = 0,
-    CHIP_HELPER_DBG_PROC_SEL_PHY  = 1,
-    CHIP_HELPER_DBG_PROC_SEL_BT   = 2,
-    CHIP_HELPER_DBG_PROC_SEL_NONE = 2,
-    CHIP_HELPER_DBG_PROC_SEL_BOTH = 3
-};
-
-/* These are the only registers that we have to know the
-   address of before we know the chip version. */
-enum chip_helper_fixed_registers
-{
-    /* This is the address of GBL_CHIP_VERISON on BC7,
-       UF105x, UF60xx and
-       anything later than that. */
-    CHIP_HELPER_UNIFI_GBL_CHIP_VERSION  = 0xFE81,
-
-    CHIP_HELPER_OLD_BLUECORE_GBL_CHIP_VERSION = 0xFF9A
-
-                                                /* This isn't used at the moment (but might be needed
-                                                to distinguish the BlueCore sub version?) */
-                                                /* CHIP_HELPER_OLD_BLUECORE_ANA_VERSION_ID = 0xFF7D */
-};
-
-/* Address-value pairs for defining initialisation values */
-struct chip_helper_init_values
-{
-    u16 addr;
-    u16 value;
-};
-
-/* A block of data that should be written to the device */
-struct chip_helper_reset_values
-{
-    u32        gp_address;
-    u32        len;
-    const u16 *data;
-};
-
-/*
- * This is the C API.
- */
-
-/* opaque type */
-typedef const struct chip_device_desc_t ChipDescript;
-
-/* Return a NULL descriptor */
-ChipDescript* ChipHelper_Null(void);
-
-/* This should get the correct version for any CSR chip.
-   The two parameters are what is read from addresses
-   0xFF9A and 0xFE81 (OLD_BLUECORE_GBL_CHIP_VERSION and
-   UNIFI_GBL_CHIP_VERSION).  These should give a unique identity
-   for most (all?) chips.
-
-   FF9A is the old GBL_CHIP_VERSION register.  If the high
-   eight bits are zero then the chip is a new (BC7 +) one
-   and FE81 is the _new_ GBL_CHIP_VERSION register. */
-ChipDescript* ChipHelper_GetVersionAny(u16 from_FF9A, u16 from_FE81);
-
-/* The chip is a UniFi, but we don't know which type
-   The parameter is the value of UNIFI_GBL_CHIP_VERSION (0xFE81) */
-ChipDescript* ChipHelper_GetVersionUniFi(u16 version);
-
-/* This gets the version from the SDIO device id.  This only
-   gives quite a coarse grained version, so we should update once
-   we hav access to the function N registers. */
-ChipDescript* ChipHelper_GetVersionSdio(u8 sdio_version);
-
-/* The chip is some sort of BlueCore.  If "age" is "pre_bc7" then
-   "version" is what was read from FF9A.  If "age" is bc7_or_later
-   then "version" is read from FE81.  If we don't know if we're pre
-   or post BC7 then we should use "GetVersionAny". */
-ChipDescript* ChipHelper_GetVersionBlueCore(enum chip_helper_bluecore_age age,
-                                            u16                     version);
-
-/* The main functions of this class are built with an X macro.  This
-   means we can generate the C and C++ versions from the same source
-   without the two diverging.
-
-   The DEF0 functions are simple and take no parameters.  The first
-   parameter to the macro is the return type.  The second parameter
-   is the function name and the third parameter is where to get the
-   info from (this is hidden from the user).
-
-   The DEF1 functions take one parameter. This time the third macro
-   parameter is the type of this parameter, and the fourth macro
-   parameter is the name of the parameter. The bodies of these
-   functions are hand written. */
-#define CHIP_HELPER_LIST(m)                                             \
-    CHIP_HELPER_DEF0(m, (const char *, FriendlyName, friendly_name))     \
-    CHIP_HELPER_DEF0(m, (const char *, MarketingName, marketing_name))  \
-    CHIP_HELPER_DEF0(m, (u16, DBG_EMU_CMD, regs->dbg_emu_cmd))       \
-    CHIP_HELPER_DEF0(m, (u16, DBG_HOST_PROC_SELECT, regs->host.dbg_proc_select)) \
-    CHIP_HELPER_DEF0(m, (u16, DBG_HOST_STOP_STATUS, regs->host.dbg_stop_status)) \
-    CHIP_HELPER_DEF0(m, (u16, HOST_WINDOW1_PAGE, regs->host.window1_page)) \
-    CHIP_HELPER_DEF0(m, (u16, HOST_WINDOW2_PAGE, regs->host.window2_page)) \
-    CHIP_HELPER_DEF0(m, (u16, HOST_WINDOW3_PAGE, regs->host.window3_page)) \
-    CHIP_HELPER_DEF0(m, (u16, HOST_IO_LOG_ADDR, regs->host.io_log_addr)) \
-    CHIP_HELPER_DEF0(m, (u16, DBG_SPI_PROC_SELECT, regs->spi.dbg_proc_select)) \
-    CHIP_HELPER_DEF0(m, (u16, DBG_SPI_STOP_STATUS, regs->spi.dbg_stop_status)) \
-    CHIP_HELPER_DEF0(m, (u16, SPI_WINDOW1_PAGE, regs->spi.window1_page)) \
-    CHIP_HELPER_DEF0(m, (u16, SPI_WINDOW2_PAGE, regs->spi.window2_page)) \
-    CHIP_HELPER_DEF0(m, (u16, SPI_WINDOW3_PAGE, regs->spi.window3_page)) \
-    CHIP_HELPER_DEF0(m, (u16, SPI_IO_LOG_ADDR, regs->spi.io_log_addr)) \
-    CHIP_HELPER_DEF0(m, (u16, DBG_RESET, regs->dbg_reset))           \
-    CHIP_HELPER_DEF0(m, (u16, DBG_RESET_VALUE, regs->dbg_reset_value)) \
-    CHIP_HELPER_DEF0(m, (u16, DBG_RESET_WARN, regs->dbg_reset_warn)) \
-    CHIP_HELPER_DEF0(m, (u16, DBG_RESET_WARN_VALUE, regs->dbg_reset_warn_value)) \
-    CHIP_HELPER_DEF0(m, (u16, DBG_RESET_RESULT, regs->dbg_reset_result)) \
-    CHIP_HELPER_DEF0(m, (u16, WATCHDOG_DISABLE, regs->watchdog_disable)) \
-    CHIP_HELPER_DEF0(m, (u16, PROC_PC_SNOOP, regs->proc_pc_snoop))   \
-    CHIP_HELPER_DEF0(m, (u16, GBL_CHIP_VERSION, regs->gbl_chip_version)) \
-    CHIP_HELPER_DEF0(m, (u16, GBL_MISC_ENABLES, regs->gbl_misc_enables)) \
-    CHIP_HELPER_DEF0(m, (u16, XAP_PCH, regs->xap_pch))               \
-    CHIP_HELPER_DEF0(m, (u16, XAP_PCL, regs->xap_pcl))               \
-    CHIP_HELPER_DEF0(m, (u16, MAILBOX0, regs->mailbox0))             \
-    CHIP_HELPER_DEF0(m, (u16, MAILBOX1, regs->mailbox1))             \
-    CHIP_HELPER_DEF0(m, (u16, MAILBOX2, regs->mailbox2))             \
-    CHIP_HELPER_DEF0(m, (u16, MAILBOX3, regs->mailbox3))             \
-    CHIP_HELPER_DEF0(m, (u16, SDIO_HIP_HANDSHAKE, regs->sdio_hip_handshake))   \
-    CHIP_HELPER_DEF0(m, (u16, SDIO_HOST_INT, regs->sdio_host_int))   \
-    CHIP_HELPER_DEF0(m, (u16, COEX_STATUS, regs->coex_status))       \
-    CHIP_HELPER_DEF0(m, (u16, SHARED_IO_INTERRUPT, regs->shared_io_interrupt)) \
-    CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_RAM_OFFSET, prog_offset.ram)) \
-    CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_ROM_OFFSET, prog_offset.rom)) \
-    CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_FLASH_OFFSET, prog_offset.flash)) \
-    CHIP_HELPER_DEF0(m, (u32, PROGRAM_MEMORY_EXT_SRAM_OFFSET, prog_offset.ext_sram)) \
-    CHIP_HELPER_DEF0(m, (u16, DATA_MEMORY_RAM_OFFSET, data_offset.ram)) \
-    CHIP_HELPER_DEF0(m, (s32, HasFlash, bools.has_flash))              \
-    CHIP_HELPER_DEF0(m, (s32, HasExtSram, bools.has_ext_sram))         \
-    CHIP_HELPER_DEF0(m, (s32, HasRom, bools.has_rom))                  \
-    CHIP_HELPER_DEF0(m, (s32, HasBt, bools.has_bt))                    \
-    CHIP_HELPER_DEF0(m, (s32, HasWLan, bools.has_wlan))                \
-    CHIP_HELPER_DEF1(m, (u16, WINDOW_ADDRESS, enum chip_helper_window_index, window)) \
-    CHIP_HELPER_DEF1(m, (u16, WINDOW_SIZE, enum chip_helper_window_index, window)) \
-    CHIP_HELPER_DEF1(m, (u16, MapAddress_SPI2HOST, u16, addr))          \
-    CHIP_HELPER_DEF1(m, (u16, MapAddress_HOST2SPI, u16, addr))          \
-    CHIP_HELPER_DEF1(m, (u32, ClockStartupSequence, const struct chip_helper_init_values **, val)) \
-    CHIP_HELPER_DEF1(m, (u32, HostResetSequence, const struct chip_helper_reset_values **, val))
-
-/* Some magic to help the expansion */
-#define CHIP_HELPER_DEF0(a, b) \
-    CHIP_HELPER_DEF0_ ## a b
-#define CHIP_HELPER_DEF1(a, b) \
-    CHIP_HELPER_DEF1_ ## a b
-
-/* Macros so that when we expand the list we get "C" function prototypes. */
-#define CHIP_HELPER_DEF0_C_DEC(ret_type, name, info)    \
-    ret_type ChipHelper_ ## name(ChipDescript * chip_help);
-#define CHIP_HELPER_DEF1_C_DEC(ret_type, name, type1, name1)   \
-    ret_type ChipHelper_ ## name(ChipDescript * chip_help, type1 name1);
-
-CHIP_HELPER_LIST(C_DEC)
-
-/* FriendlyName
-   MarketingName
-
-   These two functions return human readable strings that describe
-   the chip.  FriendlyName returns something that a software engineer
-   at CSR might understand.  MarketingName returns something more like
-   an external name for a CSR chip.
-*/
-/* DBG_EMU_CMD
-   WATCHDOG_DISABLE
-   PROC_PC_SNOOP
-   GBL_CHIP_VERSION
-   XAP_PCH
-   XAP_PCL
-
-   These registers are used to control the XAPs.
-*/
-/* DBG_HOST_PROC_SELECT  DBG_HOST_STOP_STATUS
-   HOST_WINDOW1_PAGE HOST_WINDOW2_PAGE HOST_WINDOW3_PAGE
-   HOST_IO_LOG_ADDR
-   DBG_SPI_PROC_SELECT  DBG_SPI_STOP_STATUS
-   SPI_WINDOW1_PAGE SPI_WINDOW2_PAGE SPI_WINDOW3_PAGE
-   SPI_IO_LOG_ADDR
-
-   These register are used to control the XAPs and the memory
-   windows, normally while debugging the code on chip.  There
-   are two versons of these registers, one for access via SPI
-   and another for access via the host interface.
-*/
-/*  DBG_RESET
-    DBG_RESET_VALUE
-    DBG_RESET_WARN
-    DBG_RESET_WARN_VALUE
-    DBG_RESET_RESULT
-
-    These registers are used to reset the XAP.  This can be
-    quite complex for some chips.  If DBG_RESET_WARN is non
-    zero the DBG_RESET_WARN_VALUE should be written to address
-    DBG_RESET_WARN before the reset is perfeormed.  DBG_RESET_VALUE
-    should then be written to DBG_RESET to make the reset happen.
-    The DBG_RESET_RESULT register should contain 0 if the reset
-    was successful.
-*/
-/*  GBL_MISC_ENABLES
-
-    This register controls some special chip features.  It
-    should be used with care is it changes quite a lot between
-    chip versions.
-*/
-/*  MAILBOX0
-    MAILBOX1
-    MAILBOX2
-    MAILBOX3
-
-    The mailbox registers are for communication between the host
-    and the firmware.  There use is described in part by the host
-    interface protcol specifcation.
-*/
-/*  SDIO_HIP_HANDSHAKE
-
-    This is one of the more important SDIO HIP registers.  On some
-    chips it has the same value as one of the mailbox registers
-    and on other chips it is different.
-*/
-/*  SDIO_HOST_INT
-    SHARED_IO_INTERRUPT
-
-    These registers are used by some versions of the host interface
-    protocol specification.  Their names should probably be changed
-    to hide the registers and to expose the functions more.
-*/
-/*  COEX_STATUS
-
-    Coex status register, contains interrupt status and reset
-    pullup status.  The latter is used to detect WAPI.
-*/
-/*  PROGRAM_MEMORY_RAM_OFFSET
-    PROGRAM_MEMORY_ROM_OFFSET
-    PROGRAM_MEMORY_FLASH_OFFSET
-    PROGRAM_MEMORY_EXT_SRAM_OFFSET
-    DATA_MEMORY_RAM_OFFSET
-
-    These are constants that describe the offset of the different
-    memory types in the two different address spaces.
-*/
-/*  HasFlash HasExtSram HasRom
-    HasBt HasWLan
-
-    These are a set of bools describing the chip.
-*/
-/*  WINDOW_ADDRESS WINDOW_SIZE
-
-    These two functions return the size and address of the windows.
-    The address is the address of the lowest value in the address
-    map that is part of the window and the size is the number of
-    visible words.
-
-    Some of the windows have their lowest portion covered by
-    registers.  For these windows address is the first address
-    after the registers and size is the siave excluding the part
-    covered by registers.
-*/
-/*  MapAddress_SPI2HOST
-    MapAddress_HOST2SPI
-
-    The debugging interface is duplicated on UniFi and later chips
-    so that there are two versions - one over the SPI interaface and
-    the other over the SDIO interface.  These functions map the
-    registers between these two interfaces.
-*/
-/*  ClockStartupSequence
-
-    This function returns the list of register value pairs that
-    should be forced into UniFi to enable SPI communication.  This
-    set of registers is not needed if the firmware is running, but
-    will be needed if the device is being booted from cold.  These
-    register writes enable the clocks and setup the PLL to a basic
-    working state.  SPI access might be unreliable until these writes
-    have occurred (And they may take mulitple goes).
-*/
-/*  HostResetSequence
-
-    This returns a number of chunks of data and generic pointers.
-    All of the XAPs should be stopped.  The data should be written
-    to the generic pointers.  The instruction pointer for the MAC
-    should then be set to the start of program memory and then the
-    MAC should be "go"d.  This will reset the chip in a reliable
-    and orderly manner without resetting the SDIO interface.  It
-    is therefore not needed if the chip is being accessed by the
-    SPI interface (the DBG_RESET_ mechanism can be used instead).
-*/
-
-/* The Decode Window function is more complex.  For the window
-   'window' it tries to return the address and page register
-   value needed to see offset 'offset' of memory type 'type'.
-
-   It return 1 on success and 0 on failure.  'page' is what
-   should be written to the page register.  'addr' is the
-   address in the XAPs 16 address map to read from.  'len'
-   is the length that we can read without having to change
-   the page registers. */
-s32 ChipHelper_DecodeWindow(ChipDescript *chip_help,
-                                 enum chip_helper_window_index window,
-                                 enum chip_helper_window_type type,
-                                 u32 offset,
-                                 u16 *page, u16 *addr, u32 *len);
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,200 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_HIP_CHIPHELPER_PRIVATE_H__
-#define CSR_WIFI_HIP_CHIPHELPER_PRIVATE_H__
-
-
-#include "csr_wifi_hip_chiphelper.h"
-
-/* This GP stuff should be somewhere else? */
-
-/* Memory spaces encoded in top byte of Generic Pointer type */
-#define UNIFI_SH_DMEM   0x01    /* Shared Data Memory */
-#define UNIFI_EXT_FLASH 0x02    /* External FLASH */
-#define UNIFI_EXT_SRAM  0x03    /* External SRAM */
-#define UNIFI_REGISTERS 0x04    /* Registers */
-#define UNIFI_PHY_DMEM  0x10    /* PHY Data Memory */
-#define UNIFI_PHY_PMEM  0x11    /* PHY Program Memory */
-#define UNIFI_PHY_ROM   0x12    /* PHY ROM */
-#define UNIFI_MAC_DMEM  0x20    /* MAC Data Memory */
-#define UNIFI_MAC_PMEM  0x21    /* MAC Program Memory */
-#define UNIFI_MAC_ROM   0x22    /* MAC ROM */
-#define UNIFI_BT_DMEM   0x30    /* BT Data Memory */
-#define UNIFI_BT_PMEM   0x31    /* BT Program Memory */
-#define UNIFI_BT_ROM    0x32    /* BT ROM */
-
-#define MAKE_GP(R, O)  (((UNIFI_ ## R) << 24) | (O))
-#define GP_OFFSET(GP)  ((GP) & 0xFFFFFF)
-#define GP_SPACE(GP)   (((GP) >> 24) & 0xFF)
-
-
-/* Address value pairs */
-struct val_array_t
-{
-    u32                             len;
-    const struct chip_helper_init_values *vals;
-};
-
-/* Just a (counted) u16 array */
-struct data_array_t
-{
-    u32        len;
-    const u16 *vals;
-};
-
-struct reset_prog_t
-{
-    u32                              len;
-    const struct chip_helper_reset_values *vals;
-};
-
-/* The addresses of registers that are equivalent but on
-   different host transports. */
-struct chip_map_address_t
-{
-    u16 spi, host;
-};
-
-struct map_array_t
-{
-    u32                        len;
-    const struct chip_map_address_t *vals;
-};
-
-struct chip_device_regs_per_transport_t
-{
-    u16 dbg_proc_select;
-    u16 dbg_stop_status;
-    u16 window1_page;    /* PROG_PMEM1 or GW1 */
-    u16 window2_page;    /* PROG_PMEM2 or GW2 */
-    u16 window3_page;    /* SHARED or GW3 */
-    u16 io_log_addr;
-};
-
-struct chip_device_regs_t
-{
-    u16                               gbl_chip_version;
-    u16                               gbl_misc_enables;
-    u16                               dbg_emu_cmd;
-    struct chip_device_regs_per_transport_t host;
-    struct chip_device_regs_per_transport_t spi;
-    u16                               dbg_reset;
-    u16                               dbg_reset_value;
-    u16                               dbg_reset_warn;
-    u16                               dbg_reset_warn_value;
-    u16                               dbg_reset_result;
-    u16                               xap_pch;
-    u16                               xap_pcl;
-    u16                               proc_pc_snoop;
-    u16                               watchdog_disable;
-    u16                               mailbox0;
-    u16                               mailbox1;
-    u16                               mailbox2;
-    u16                               mailbox3;
-    u16                               sdio_host_int;
-    u16                               shared_io_interrupt;
-    u16                               sdio_hip_handshake;
-    u16                               coex_status; /* Allows WAPI detection */
-};
-
-/* If allowed is false then this window does not provide this
-   type of access.
-   This describes how addresses should be shifted to make the
-   "page" address.  The address is shifted left by 'page_shift'
-   and then has 'page_offset' added.  This value should then be
-   written to the page register. */
-struct window_shift_info_t
-{
-    s32  allowed;
-    u32 page_shift;
-    u16 page_offset;
-};
-
-/* Each window has an address and size.  These are obvious.  It then
-   has a description for each type of memory that might be accessed
-   through it.  There might also be a start to the offset of the window.
-   This means that that number of addresses at the start of the window
-   are unusable. */
-struct window_info_t
-{
-    u16                         address;
-    u16                         size;
-    u16                         blocked;
-    const struct window_shift_info_t *mode;
-};
-
-/* If GBL_CHIP_VERSION and'ed with 'mask' and is equal to 'result'
-   then this is the correct set of info.  If pre_bc7 is true then the
-   address of GBL_CHIP_VERSION is FF9A, else its FE81. */
-struct chip_version_t
-{
-    s32  pre_bc7;
-    u16 mask;
-    u16 result;
-    u8  sdio;
-};
-
-struct chip_device_desc_t
-{
-    struct chip_version_t chip_version;
-
-    /* This is a text string that a human might find useful (BC02, UF105x) */
-    const char *friendly_name;
-    /* This is what we show to customers */
-    const char *marketing_name;
-
-    /* Initialisation values to write following a reset */
-    struct val_array_t init;
-
-    /* Binary sequence for hard reset */
-    struct reset_prog_t reset_prog;
-
-    /* The register map */
-    const struct chip_device_regs_t *regs;
-
-    /* Some misc. info on the chip */
-    struct
-    {
-        u32 has_flash     : 1;
-        u32 has_ext_sram  : 1;
-        u32 has_rom       : 1;
-        u32 has_bt        : 1;
-        u32 has_wlan      : 1;
-    } bools;
-
-    /* This table is used to remap register addresses depending on what
-       host interface is used.  On the BC7 and later chips there are
-       multiple sets of memory window registers, on for each host
-       interafce (SDIO / SPI).  The correct one is needed. */
-    struct map_array_t map;
-
-    /* The offsets into the program address space of the different types of memory.
-       The RAM offset is probably the most useful. */
-    struct
-    {
-        u32 ram;
-        u32 rom;
-        u32 flash;
-        u32 ext_sram;
-    } prog_offset;
-
-    /* The offsets into the data address space of interesting things. */
-    struct
-    {
-        u16 ram;
-        /* maybe add shared / page tables? */
-    } data_offset;
-
-    /* Information on the different windows */
-    const struct window_info_t *windows[CHIP_HELPER_WINDOW_COUNT];
-};
-
-#endif /* CSR_WIFI_HIP_CHIPHELPER_PRIVATE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_conversions.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_conversions.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_conversions.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_conversions.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *
- * FILE: csr_wifi_hip_conversions.h
- *
- * PURPOSE:
- *      This header file provides the macros for converting to and from
- *      wire format.
- *      These macros *MUST* work for little-endian AND big-endian hosts.
- *
- * ---------------------------------------------------------------------------
- */
-#ifndef __CSR_WIFI_HIP_CONVERSIONS_H__
-#define __CSR_WIFI_HIP_CONVERSIONS_H__
-
-#define SIZEOF_UINT16           2
-#define SIZEOF_UINT32           4
-#define SIZEOF_UINT64           8
-
-#define SIZEOF_SIGNAL_HEADER    6
-#define SIZEOF_DATAREF          4
-
-
-/*
- * Macro to retrieve the signal ID from a wire-format signal.
- */
-#define GET_SIGNAL_ID(_buf)     CSR_GET_UINT16_FROM_LITTLE_ENDIAN((_buf))
-
-/*
- * Macros to retrieve and set the DATAREF fields in a packed (i.e. wire-format)
- * HIP signal.
- */
-#define GET_PACKED_DATAREF_SLOT(_buf, _ref)                             \
-    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref) * SIZEOF_DATAREF) + 0))
-
-#define GET_PACKED_DATAREF_LEN(_buf, _ref)                              \
-    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref) * SIZEOF_DATAREF) + 2))
-
-#define SET_PACKED_DATAREF_SLOT(_buf, _ref, _slot)                      \
-    CSR_COPY_UINT16_TO_LITTLE_ENDIAN((_slot), ((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref) * SIZEOF_DATAREF) + 0))
-
-#define SET_PACKED_DATAREF_LEN(_buf, _ref, _len)                        \
-    CSR_COPY_UINT16_TO_LITTLE_ENDIAN((_len), ((_buf) + SIZEOF_SIGNAL_HEADER + ((_ref) * SIZEOF_DATAREF) + 2))
-
-#define GET_PACKED_MA_PACKET_REQUEST_FRAME_PRIORITY(_buf)              \
-    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES * SIZEOF_DATAREF + 8))
-
-#define GET_PACKED_MA_PACKET_REQUEST_HOST_TAG(_buf)                     \
-    CSR_GET_UINT32_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES * SIZEOF_DATAREF + 4))
-
-#define GET_PACKED_MA_PACKET_CONFIRM_HOST_TAG(_buf)                     \
-    CSR_GET_UINT32_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES * SIZEOF_DATAREF + 8))
-
-#define GET_PACKED_MA_PACKET_CONFIRM_TRANSMISSION_STATUS(_buf)                     \
-    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(((_buf) + SIZEOF_SIGNAL_HEADER + UNIFI_MAX_DATA_REFERENCES * SIZEOF_DATAREF + 2))
-
-
-s32 get_packed_struct_size(const u8 *buf);
-CsrResult read_unpack_signal(const u8 *ptr, CSR_SIGNAL *sig);
-CsrResult write_pack(const CSR_SIGNAL *sig, u8 *ptr, u16 *sig_len);
-
-#endif /* __CSR_WIFI_HIP_CONVERSIONS_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_download.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_download.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_download.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_download.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,819 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- * FILE: csr_wifi_hip_download.c
- *
- * PURPOSE:
- *      Routines for downloading firmware to UniFi.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/slab.h>
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_unifiversion.h"
-#include "csr_wifi_hip_card.h"
-#include "csr_wifi_hip_xbv.h"
-
-#undef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH
-
-static CsrResult do_patch_download(card_t *card, void *dlpriv,
-                                   xbv1_t *pfwinfo, u32 boot_ctrl_addr);
-
-static CsrResult do_patch_convert_download(card_t *card,
-                                           void *dlpriv, xbv1_t *pfwinfo);
-
-/*
- * ---------------------------------------------------------------------------
- *  _find_in_slut
- *
- *      Find the offset of the appropriate object in the SLUT of a card
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      psym            Pointer to symbol object.
- *                         id set up by caller
- *                         obj will be set up by this function
- *      pslut           Pointer to SLUT address, if 0xffffffff then it must be
- *                         read from the chip.
- *  Returns:
- *      CSR_RESULT_SUCCESS on success
- *      Non-zero on error,
- *      CSR_WIFI_HIP_RESULT_NOT_FOUND if not found
- * ---------------------------------------------------------------------------
- */
-static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut)
-{
-    u32 slut_address;
-    u16 finger_print;
-    CsrResult r;
-    CsrResult csrResult;
-
-    /* Get SLUT address */
-    if (*pslut == 0xffffffff)
-    {
-        r = card_wait_for_firmware_to_start(card, &slut_address);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Firmware hasn't started\n");
-            return r;
-        }
-        *pslut = slut_address;
-
-        /*
-         * Firmware has started so set the SDIO bus clock to the initial speed,
-         * faster than UNIFI_SDIO_CLOCK_SAFE_HZ, to speed up the f/w download.
-         */
-        csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ);
-        if (csrResult != CSR_RESULT_SUCCESS)
-        {
-            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
-            return r;
-        }
-        card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;
-    }
-    else
-    {
-        slut_address = *pslut;  /* Use previously discovered address */
-    }
-    unifi_trace(card->ospriv, UDBG4, "SLUT addr: 0x%lX\n", slut_address);
-
-    /*
-     * Check the SLUT fingerprint.
-     * The slut_address is a generic pointer so we must use unifi_card_read16().
-     */
-    unifi_trace(card->ospriv, UDBG4, "Looking for SLUT finger print\n");
-    finger_print = 0;
-    r = unifi_card_read16(card, slut_address, &finger_print);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        return r;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to read SLUT finger print\n");
-        return r;
-    }
-
-    if (finger_print != SLUT_FINGERPRINT)
-    {
-        unifi_error(card->ospriv, "Failed to find SLUT fingerprint\n");
-        return CSR_RESULT_FAILURE;
-    }
-
-    /* Symbol table starts imedately after the fingerprint */
-    slut_address += 2;
-
-    while (1)
-    {
-        u16 id;
-        u32 obj;
-
-        r = unifi_card_read16(card, slut_address, &id);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            return r;
-        }
-        slut_address += 2;
-
-        if (id == CSR_SLT_END)
-        {
-            /* End of table reached: not found */
-            r = CSR_WIFI_HIP_RESULT_RANGE;
-            break;
-        }
-
-        r = unifi_read32(card, slut_address, &obj);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            return r;
-        }
-        slut_address += 4;
-
-        unifi_trace(card->ospriv, UDBG3, "  found SLUT id %02d.%08lx\n", id, obj);
-
-        r = CSR_WIFI_HIP_RESULT_NOT_FOUND;
-        /* Found search term? */
-        if (id == psym->id)
-        {
-            unifi_trace(card->ospriv, UDBG1, " matched SLUT id %02d.%08lx\n", id, obj);
-            psym->obj = obj;
-            r = CSR_RESULT_SUCCESS;
-            break;
-        }
-    }
-
-    return r;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  do_patch_convert_download
- *
- *      Download the given firmware image to the UniFi, converting from FWDL
- *      to PTDL XBV format.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      dlpriv          Pointer to source firmware image
- *      fwinfo          Pointer to source firmware info struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code on error
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *pfwinfo)
-{
-    CsrResult r;
-    u32 slut_base = 0xffffffff;
-    void *pfw;
-    u32 psize;
-    symbol_t sym;
-
-    /* Reset the chip to guarantee that the ROM loader is running */
-    r = unifi_init(card);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv,
-                    "do_patch_convert_download: failed to re-init UniFi\n");
-        return r;
-    }
-
-    /* If no unifi_helper is running, the firmware version must be read */
-    if (card->build_id == 0)
-    {
-        u32 ver = 0;
-        sym.id = CSR_SLT_BUILD_ID_NUMBER;
-        sym.obj = 0; /* To be updated by _find_in_slut() */
-
-        unifi_trace(card->ospriv, UDBG1, "Need f/w version\n");
-
-        /* Find chip build id entry in SLUT */
-        r = _find_in_slut(card, &sym, &slut_base);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to find CSR_SLT_BUILD_ID_NUMBER\n");
-            return CSR_RESULT_FAILURE;
-        }
-
-        /* Read running f/w version */
-        r = unifi_read32(card, sym.obj, &ver);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to read f/w id\n");
-            return CSR_RESULT_FAILURE;
-        }
-        card->build_id = ver;
-    }
-
-    /* Convert the ptest firmware to a patch against the running firmware */
-    pfw = xbv_to_patch(card, unifi_fw_read, dlpriv, pfwinfo, &psize);
-    if (!pfw)
-    {
-        unifi_error(card->ospriv, "Failed to convert f/w to patch");
-        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-    }
-    else
-    {
-        void *desc;
-        sym.id = CSR_SLT_BOOT_LOADER_CONTROL;
-        sym.obj = 0; /* To be updated by _find_in_slut() */
-
-        /* Find boot loader control entry in SLUT */
-        r = _find_in_slut(card, &sym, &slut_base);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to find BOOT_LOADER_CONTROL\n");
-            kfree(pfw);
-            return CSR_RESULT_FAILURE;
-        }
-
-        r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to wake UniFi\n");
-        }
-
-        /* Get a dlpriv for the patch buffer so that unifi_fw_read() can
-         * access it.
-         */
-        desc = unifi_fw_open_buffer(card->ospriv, pfw, psize);
-        if (!desc)
-        {
-            kfree(pfw);
-            return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-        }
-
-        /* Download the patch */
-        unifi_info(card->ospriv, "Downloading converted f/w as patch\n");
-        r = unifi_dl_patch(card, desc, sym.obj);
-        kfree(pfw);
-        unifi_fw_close_buffer(card->ospriv, desc);
-
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Converted patch download failed\n");
-            return r;
-        }
-        else
-        {
-            unifi_trace(card->ospriv, UDBG1, "Converted patch downloaded\n");
-        }
-
-        /* This command starts the firmware */
-        r = unifi_do_loader_op(card, sym.obj + 6, UNIFI_BOOT_LOADER_RESTART);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to write loader restart cmd\n");
-        }
-
-        return r;
-    }
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_dl_firmware
- *
- *      Download the given firmware image to the UniFi.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      dlpriv          A context pointer from the calling function to be
- *                      passed when calling unifi_fw_read().
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success,
- *      CSR_WIFI_HIP_RESULT_NO_MEMORY         memory allocation failed
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         error in XBV file
- *      CSR_RESULT_FAILURE            SDIO error
- *
- *  Notes:
- *      Stops and resets the chip, does the download and runs the new
- *      firmware.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_dl_firmware(card_t *card, void *dlpriv)
-{
-    xbv1_t *fwinfo;
-    CsrResult r;
-
-    fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL);
-    if (fwinfo == NULL)
-    {
-        unifi_error(card->ospriv, "Failed to allocate memory for firmware\n");
-        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-    }
-
-    /*
-     * Scan the firmware file to find the TLVs we are interested in.
-     * These are:
-     *   - check we support the file format version in VERF
-     *   - SLTP Symbol Lookup Table Pointer
-     *   - FWDL firmware download segments
-     *   - FWOV firmware overlay segment
-     *   - VMEQ Register probe tests to verify matching h/w
-     */
-    r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo);
-    if (r != CSR_RESULT_SUCCESS || fwinfo->mode != xbv_firmware)
-    {
-        unifi_error(card->ospriv, "File type is %s, expected firmware.\n",
-                    fwinfo->mode == xbv_patch?"patch" : "unknown");
-        kfree(fwinfo);
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    /* UF6xxx doesn't accept firmware, only patches. Therefore we convert
-     * the file to patch format with version numbers matching the current
-     * running firmware, and then download via the patch mechanism.
-     * The sole purpose of this is to support production test firmware across
-     * different ROM releases, the test firmware being provided in non-patch
-     * format.
-     */
-    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
-    {
-        unifi_info(card->ospriv, "Must convert f/w to patch format\n");
-        r = do_patch_convert_download(card, dlpriv, fwinfo);
-    }
-    else
-    {
-        /* Older UniFi chips allowed firmware to be directly loaded onto the
-         * chip, which is no longer supported.
-         */
-        unifi_error(card->ospriv, "Only patch downloading supported\n");
-        r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    kfree(fwinfo);
-    return r;
-} /* unifi_dl_firmware() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_dl_patch
- *
- *      Load the given patch set into UniFi.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      dlpriv          The os specific handle to the firmware file.
- *      boot_ctrl       The address of the boot loader control structure.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success,
- *      CSR_WIFI_HIP_RESULT_NO_MEMORY         memory allocation failed
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         error in XBV file
- *      CSR_RESULT_FAILURE            SDIO error
- *
- *  Notes:
- *      This ends up telling UniFi to restart.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl)
-{
-    xbv1_t *fwinfo;
-    CsrResult r;
-
-    unifi_info(card->ospriv, "unifi_dl_patch %p %08x\n", dlpriv, boot_ctrl);
-
-    fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL);
-    if (fwinfo == NULL)
-    {
-        unifi_error(card->ospriv, "Failed to allocate memory for patches\n");
-        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-    }
-
-    /*
-     * Scan the firmware file to find the TLVs we are interested in.
-     * These are:
-     *   - check we support the file format version in VERF
-     *   - FWID The build ID of the ROM that we can patch
-     *   - PTDL patch download segments
-     */
-    r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo);
-    if (r != CSR_RESULT_SUCCESS || fwinfo->mode != xbv_patch)
-    {
-        kfree(fwinfo);
-        unifi_error(card->ospriv, "Failed to read in patch file\n");
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    /*
-     * We have to check the build id read from the SLUT against that
-     * for the patch file.  They have to match exactly.
-     *    "card->build_id" == XBV1.PTCH.FWID
-     */
-    if (card->build_id != fwinfo->build_id)
-    {
-        unifi_error(card->ospriv, "Wrong patch file for chip (chip = %lu, file = %lu)\n",
-                    card->build_id, fwinfo->build_id);
-        kfree(fwinfo);
-#ifndef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-#else
-        fwinfo = NULL;
-        dlpriv = NULL;
-        return CSR_RESULT_SUCCESS;
-#endif
-    }
-
-    r = do_patch_download(card, dlpriv, fwinfo, boot_ctrl);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to patch image\n");
-    }
-
-    kfree(fwinfo);
-
-    return r;
-} /* unifi_dl_patch() */
-
-
-void* unifi_dl_fw_read_start(card_t *card, s8 is_fw)
-{
-    card_info_t card_info;
-
-    unifi_card_info(card, &card_info);
-    unifi_trace(card->ospriv, UDBG5,
-                "id=%d, ver=0x%x, fw_build=%u, fw_hip=0x%x, block_size=%d\n",
-                card_info.chip_id, card_info.chip_version,
-                card_info.fw_build, card_info.fw_hip_version,
-                card_info.sdio_block_size);
-
-    return unifi_fw_read_start(card->ospriv, is_fw, &card_info);
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  safe_read_shared_location
- *
- *      Read a shared memory location repeatedly until we get two readings
- *      the same.
- *
- *  Arguments:
- *      card            Pointer to card context struct.
- *      unifi_addr      UniFi shared-data-memory address to access.
- *      pdata           Pointer to a byte variable for the value read.
- *
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code on failure
- * ---------------------------------------------------------------------------
- */
-static CsrResult safe_read_shared_location(card_t *card, u32 address, u8 *pdata)
-{
-    CsrResult r;
-    u16 limit = 1000;
-    u8 b, b2;
-
-    *pdata = 0;
-
-    r = unifi_read_8_or_16(card, address, &b);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        return r;
-    }
-
-    while (limit--)
-    {
-        r = unifi_read_8_or_16(card, address, &b2);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            return r;
-        }
-
-        /* When we have a stable value, return it */
-        if (b == b2)
-        {
-            *pdata = b;
-            return CSR_RESULT_SUCCESS;
-        }
-
-        b = b2;
-    }
-
-    return CSR_RESULT_FAILURE;
-} /* safe_read_shared_location() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_do_loader_op
- *
- *      Send a loader / boot_loader command to the UniFi and wait for
- *      it to complete.
- *
- *  Arguments:
- *      card            Pointer to card context struct.
- *      op_addr         The address of the loader operation control word.
- *      opcode          The operation to perform.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS    on success
- *      CSR_RESULT_FAILURE    SDIO error or SDIO/XAP timeout
- * ---------------------------------------------------------------------------
- */
-
-/*
- * Ideally instead of sleeping, we want to busy wait.
- * Currently there is no framework API to do this. When it becomes available,
- * we can use it to busy wait using usecs
- */
-#define OPERATION_TIMEOUT_LOOPS (100)  /* when OPERATION_TIMEOUT_DELAY==1, (500) otherwise */
-#define OPERATION_TIMEOUT_DELAY 1      /* msec, or 200usecs */
-
-CsrResult unifi_do_loader_op(card_t *card, u32 op_addr, u8 opcode)
-{
-    CsrResult r;
-    s16 op_retries;
-
-    unifi_trace(card->ospriv, UDBG4, "Loader cmd 0x%0x -> 0x%08x\n", opcode, op_addr);
-
-    /* Set the Operation command byte to the opcode */
-    r = unifi_write_8_or_16(card, op_addr, opcode);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to write loader copy command\n");
-        return r;
-    }
-
-    /* Wait for Operation command byte to be Idle */
-    /* Typically takes ~100us */
-    op_retries = 0;
-    r = CSR_RESULT_SUCCESS;
-    while (1)
-    {
-        u8 op;
-
-        /*
-         * Read the memory location until two successive reads give
-         * the same value.
-         * Then handle it.
-         */
-        r = safe_read_shared_location(card, op_addr, &op);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Failed to read loader status\n");
-            break;
-        }
-
-        if (op == UNIFI_LOADER_IDLE)
-        {
-            /* Success */
-            break;
-        }
-
-        if (op != opcode)
-        {
-            unifi_error(card->ospriv, "Error reported by loader: 0x%X\n", op);
-            r = CSR_RESULT_FAILURE;
-            break;
-        }
-
-        /* Allow 500us timeout */
-        if (++op_retries >= OPERATION_TIMEOUT_LOOPS)
-        {
-            unifi_error(card->ospriv, "Timeout waiting for loader to ack transfer\n");
-            /* Stop XAPs to aid post-mortem */
-            r = unifi_card_stop_processor(card, UNIFI_PROC_BOTH);
-            if (r != CSR_RESULT_SUCCESS)
-            {
-                unifi_error(card->ospriv, "Failed to stop UniFi processors\n");
-            }
-            else
-            {
-                r = CSR_RESULT_FAILURE;
-            }
-            break;
-        }
-        CsrThreadSleep(OPERATION_TIMEOUT_DELAY);
-    } /* Loop exits with r != CSR_RESULT_SUCCESS on error */
-
-    return r;
-}     /* unifi_do_loader_op() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  send_ptdl_to_unifi
- *
- *      Copy a patch block from userland to the UniFi.
- *      This function reads data, 2K at a time, from userland and writes
- *      it to the UniFi.
- *
- *  Arguments:
- *      card            A pointer to the card structure
- *      dlpriv          The os specific handle for the firmware file
- *      ptdl            A pointer ot the PTDL block
- *      handle          The buffer handle to use for the xfer
- *      op_addr         The address of the loader operation control word
- *
- *  Returns:
- *      Number of bytes sent (Positive) or negative value indicating
- *      error code:
- *      CSR_WIFI_HIP_RESULT_NO_MEMORY         memory allocation failed
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         error in XBV file
- *      CSR_RESULT_FAILURE            SDIO error
- * ---------------------------------------------------------------------------
- */
-static CsrResult send_ptdl_to_unifi(card_t *card, void *dlpriv,
-                                    const struct PTDL *ptdl, u32 handle,
-                                    u32 op_addr)
-{
-    u32 offset;
-    u8 *buf;
-    s32 data_len;
-    u32 write_len;
-    CsrResult r;
-    const u16 buf_size = 2 * 1024;
-
-    offset = ptdl->dl_offset;
-    data_len = ptdl->dl_size;
-
-    if (data_len > buf_size)
-    {
-        unifi_error(card->ospriv, "PTDL block is too large (%u)\n",
-                    ptdl->dl_size);
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    buf = kmalloc(buf_size, GFP_KERNEL);
-    if (buf == NULL)
-    {
-        unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n");
-        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-    }
-
-    r = CSR_RESULT_SUCCESS;
-
-    if (unifi_fw_read(card->ospriv, dlpriv, offset, buf, data_len) != data_len)
-    {
-        unifi_error(card->ospriv, "Failed to read from file\n");
-    }
-    else
-    {
-        /* We can always round these if the host wants to */
-        if (card->sdio_io_block_pad)
-        {
-            write_len = (data_len + (card->sdio_io_block_size - 1)) &
-                        ~(card->sdio_io_block_size - 1);
-
-            /* Zero out the rest of the buffer (This isn't needed, but it
-             * makes debugging things later much easier). */
-            memset(buf + data_len, 0, write_len - data_len);
-        }
-        else
-        {
-            write_len = data_len;
-        }
-
-        r = unifi_bulk_rw_noretry(card, handle, buf, write_len, UNIFI_SDIO_WRITE);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "CMD53 failed writing %d bytes to handle %ld\n",
-                        data_len, handle);
-        }
-        else
-        {
-            /*
-             * Can change the order of things to overlap read from file
-             * with copy to unifi
-             */
-            r = unifi_do_loader_op(card, op_addr, UNIFI_BOOT_LOADER_PATCH);
-        }
-    }
-
-    kfree(buf);
-
-    if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        unifi_error(card->ospriv, "Failed to copy block of %u bytes to UniFi\n",
-                    ptdl->dl_size);
-    }
-
-    return r;
-} /* send_ptdl_to_unifi() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  do_patch_download
- *
- *      This function downloads a set of patches to UniFi and then
- *      causes it to restart.
- *
- *  Arguments:
- *      card            Pointer to card struct.
- *      dlpriv          A context pointer from the calling function to be
- *                      used when reading the XBV file.  This can be NULL
- *                      in which case not patches are applied.
- *      pfwinfo         Pointer to a fwinfo struct describing the f/w
- *                      XBV file.
- *      boot_ctrl_addr  The address of the boot loader control structure.
- *
- *  Returns:
- *      0 on success, or an error code
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE for a bad laoader version number
- * ---------------------------------------------------------------------------
- */
-static CsrResult do_patch_download(card_t *card, void *dlpriv, xbv1_t *pfwinfo, u32 boot_ctrl_addr)
-{
-    CsrResult r;
-    s32 i;
-    u16 loader_version;
-    u16 handle;
-    u32 total_bytes;
-
-    /*
-     * Read info from the SDIO Loader Control Data Structure
-     */
-    /* Check the loader version */
-    r = unifi_card_read16(card, boot_ctrl_addr, &loader_version);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Patch download: Failed to read loader version\n");
-        return r;
-    }
-    unifi_trace(card->ospriv, UDBG2, "Patch download: boot loader version 0x%04X\n", loader_version);
-    switch (loader_version)
-    {
-        case 0x0000:
-            break;
-
-        default:
-            unifi_error(card->ospriv, "Patch loader version (0x%04X) is not supported by this driver\n",
-                        loader_version);
-            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    /* Retrieve the handle to use with CMD53 */
-    r = unifi_card_read16(card, boot_ctrl_addr + 4, &handle);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Patch download: Failed to read loader handle\n");
-        return r;
-    }
-
-    /* Set the mask of LEDs to flash */
-    if (card->loader_led_mask)
-    {
-        r = unifi_card_write16(card, boot_ctrl_addr + 2,
-                               (u16)card->loader_led_mask);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Patch download: Failed to write LED mask\n");
-            return r;
-        }
-    }
-
-    total_bytes = 0;
-
-    /* Copy download data to UniFi memory */
-    for (i = 0; i < pfwinfo->num_ptdl; i++)
-    {
-        unifi_trace(card->ospriv, UDBG3, "Patch download: %d Downloading for %d from offset %d\n",
-                    i,
-                    pfwinfo->ptdl[i].dl_size,
-                    pfwinfo->ptdl[i].dl_offset);
-
-        r = send_ptdl_to_unifi(card, dlpriv, &pfwinfo->ptdl[i],
-                               handle, boot_ctrl_addr + 6);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            return r;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Patch failed after %u bytes\n",
-                        total_bytes);
-            return r;
-        }
-        total_bytes += pfwinfo->ptdl[i].dl_size;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* do_patch_download() */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_dump.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_dump.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_dump.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_dump.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,837 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- * FILE: csr_wifi_hip_dump.c
- *
- * PURPOSE:
- *      Routines for retrieving and buffering core status from the UniFi
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/slab.h>
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_unifiversion.h"
-#include "csr_wifi_hip_card.h"
-
-/* Locations to capture in dump (XAP words) */
-#define HIP_CDUMP_FIRST_CPUREG      (0xFFE0) /* First CPU register */
-#define HIP_CDUMP_FIRST_LO          (0)      /* Start of low address range */
-#define HIP_CDUMP_FIRST_HI_MAC      (0x3C00) /* Start of MAC high area */
-#define HIP_CDUMP_FIRST_HI_PHY      (0x1C00) /* Start of PHY high area */
-#define HIP_CDUMP_FIRST_SH          (0)      /* Start of shared memory area */
-
-#define HIP_CDUMP_NCPUREGS    (10)           /* No. of 16-bit XAP registers */
-#define HIP_CDUMP_NWORDS_LO   (0x0100)       /* Low area size in 16-bit words */
-#define HIP_CDUMP_NWORDS_HI   (0x0400)       /* High area size in 16-bit words */
-#define HIP_CDUMP_NWORDS_SH   (0x0500)       /* Shared memory area size, 16-bit words */
-
-#define HIP_CDUMP_NUM_ZONES 7                /* Number of UniFi memory areas to capture */
-
-/* Mini-coredump state */
-typedef struct coredump_buf
-{
-    u16  count;                       /* serial number of dump */
-    u32  timestamp;                   /* host's system time at capture */
-    s16   requestor;                   /* request: 0=auto dump, 1=manual */
-    u16  chip_ver;
-    u32  fw_ver;
-    u16 *zone[HIP_CDUMP_NUM_ZONES];
-
-    struct coredump_buf *next;              /* circular list */
-    struct coredump_buf *prev;              /* circular list */
-} coredump_buffer;
-
-/* Structure used to describe a zone of chip memory captured by mini-coredump */
-struct coredump_zone
-{
-    unifi_coredump_space_t           space;  /* XAP memory space this zone covers */
-    enum unifi_dbg_processors_select cpu;    /* XAP CPU core selector */
-    u32                        gp;     /* Generic Pointer to memory zone on XAP */
-    u16                        offset; /* 16-bit XAP word offset of zone in memory space */
-    u16                        length; /* Length of zone in XAP words */
-};
-
-static CsrResult unifi_coredump_from_sdio(card_t *card, coredump_buffer *dump_buf);
-static CsrResult unifi_coredump_read_zones(card_t *card, coredump_buffer *dump_buf);
-static CsrResult unifi_coredump_read_zone(card_t *card, u16 *zone,
-                                          const struct coredump_zone *def);
-static s32 get_value_from_coredump(const coredump_buffer *dump,
-                                        const unifi_coredump_space_t space, const u16 offset);
-
-/* Table of chip memory zones we capture on mini-coredump */
-static const struct coredump_zone zonedef_table[HIP_CDUMP_NUM_ZONES] = {
-    { UNIFI_COREDUMP_MAC_REG,  UNIFI_PROC_MAC, UNIFI_MAKE_GP(REGISTERS, HIP_CDUMP_FIRST_CPUREG * 2), HIP_CDUMP_FIRST_CPUREG, HIP_CDUMP_NCPUREGS },
-    { UNIFI_COREDUMP_PHY_REG,  UNIFI_PROC_PHY, UNIFI_MAKE_GP(REGISTERS, HIP_CDUMP_FIRST_CPUREG * 2), HIP_CDUMP_FIRST_CPUREG, HIP_CDUMP_NCPUREGS },
-    { UNIFI_COREDUMP_SH_DMEM,  UNIFI_PROC_INVALID, UNIFI_MAKE_GP(SH_DMEM, HIP_CDUMP_FIRST_SH * 2),   HIP_CDUMP_FIRST_SH,     HIP_CDUMP_NWORDS_SH },
-    { UNIFI_COREDUMP_MAC_DMEM, UNIFI_PROC_MAC, UNIFI_MAKE_GP(MAC_DMEM, HIP_CDUMP_FIRST_LO * 2),      HIP_CDUMP_FIRST_LO,     HIP_CDUMP_NWORDS_LO },
-    { UNIFI_COREDUMP_MAC_DMEM, UNIFI_PROC_MAC, UNIFI_MAKE_GP(MAC_DMEM, HIP_CDUMP_FIRST_HI_MAC * 2),  HIP_CDUMP_FIRST_HI_MAC, HIP_CDUMP_NWORDS_HI },
-    { UNIFI_COREDUMP_PHY_DMEM, UNIFI_PROC_PHY, UNIFI_MAKE_GP(PHY_DMEM, HIP_CDUMP_FIRST_LO * 2),      HIP_CDUMP_FIRST_LO,     HIP_CDUMP_NWORDS_LO },
-    { UNIFI_COREDUMP_PHY_DMEM, UNIFI_PROC_PHY, UNIFI_MAKE_GP(PHY_DMEM, HIP_CDUMP_FIRST_HI_PHY * 2),  HIP_CDUMP_FIRST_HI_PHY, HIP_CDUMP_NWORDS_HI },
-};
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_coredump_request_at_next_reset
- *
- *      Request that a mini-coredump is performed when the driver has
- *      completed resetting the UniFi device.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      enable          If non-zero, sets the request.
- *                      If zero, cancels any pending request.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS or CSR HIP error code
- *
- *  Notes:
- *      This function is typically called once the driver has detected that
- *      the UniFi device has become unresponsive due to crash, or internal
- *      watchdog reset. The driver must reset it to regain communication and,
- *      immediately after that, the mini-coredump can be captured.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_coredump_request_at_next_reset(card_t *card, s8 enable)
-{
-    CsrResult r;
-
-    if (enable)
-    {
-        unifi_trace(card->ospriv, UDBG2, "Mini-coredump requested after reset\n");
-    }
-
-    if (card == NULL)
-    {
-        r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-    else
-    {
-        card->request_coredump_on_reset = enable?1 : 0;
-        r = CSR_RESULT_SUCCESS;
-    }
-
-    return r;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_coredump_handle_request
- *
- *      Performs a coredump now, if one was requested, and clears the request.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS or CSR HIP error code
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_coredump_handle_request(card_t *card)
-{
-    CsrResult r = CSR_RESULT_SUCCESS;
-
-    if (card == NULL)
-    {
-        r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-    else
-    {
-        if (card->request_coredump_on_reset == 1)
-        {
-            card->request_coredump_on_reset = 0;
-            r = unifi_coredump_capture(card, NULL);
-        }
-    }
-
-    return r;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_coredump_capture
- *
- *      Capture the current status of the UniFi device.
- *      Various registers are buffered for future offline inspection.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      req             Pointer to request struct, or NULL:
- *                          A coredump requested manually by the user app
- *                          will have a request struct pointer, an automatic
- *                          coredump will have a NULL pointer.
- *  Returns:
- *      CSR_RESULT_SUCCESS  on success,
- *      CSR_RESULT_FAILURE  SDIO error
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  Initialisation not complete
- *
- *  Notes:
- *      The result is a filled entry in the circular buffer of core dumps,
- *      values from which can be extracted to userland via an ioctl.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_coredump_capture(card_t *card, struct unifi_coredump_req *req)
-{
-    CsrResult r = CSR_RESULT_SUCCESS;
-    static u16 dump_seq_no = 1;
-    u32 time_of_capture;
-
-    if (card->dump_next_write == NULL)
-    {
-        r = CSR_RESULT_SUCCESS;
-        goto done;
-    }
-
-    /* Reject forced capture before initialisation has happened */
-    if (card->helper == NULL)
-    {
-        r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-        goto done;
-    }
-
-
-    /*
-     * Force a mini-coredump capture right now
-     */
-    time_of_capture = CsrTimeGet(NULL);
-    unifi_info(card->ospriv, "Mini-coredump capture at t=%u\n", time_of_capture);
-
-    /* Wake up the processors so we can talk to them */
-    r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to wake UniFi\n");
-        goto done;
-    }
-    CsrThreadSleep(20);
-
-    /* Stop both XAPs */
-    unifi_trace(card->ospriv, UDBG4, "Stopping XAPs for coredump capture\n");
-    r = unifi_card_stop_processor(card, UNIFI_PROC_BOTH);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to stop UniFi XAPs\n");
-        goto done;
-    }
-
-    /* Dump core into the next available slot in the circular list */
-    r = unifi_coredump_from_sdio(card, card->dump_next_write);
-    if (r == CSR_RESULT_SUCCESS)
-    {
-        /* Record whether the dump was manual or automatic */
-        card->dump_next_write->requestor = (req?1 : 0);
-        card->dump_next_write->timestamp = time_of_capture;
-        /* Advance to the next buffer */
-        card->dump_next_write->count = dump_seq_no++;
-        card->dump_cur_read = card->dump_next_write;
-        card->dump_next_write = card->dump_next_write->next;
-
-        /* Sequence no. of zero indicates slot not in use, so handle wrap */
-        if (dump_seq_no == 0)
-        {
-            dump_seq_no = 1;
-        }
-
-        unifi_trace(card->ospriv, UDBG3,
-                    "Coredump (%p), SeqNo=%d, cur_read=%p, next_write=%p\n",
-                    req,
-                    card->dump_cur_read->count,
-                    card->dump_cur_read, card->dump_next_write);
-    }
-
-    /* Start both XAPs */
-    unifi_trace(card->ospriv, UDBG4, "Restart XAPs after coredump\n");
-    r = card_start_processor(card, UNIFI_PROC_BOTH);
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Failed to start UniFi XAPs\n");
-        goto done;
-    }
-
-done:
-    return r;
-} /* unifi_coredump_capture() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  get_value_from_coredump
- *
- *
- *
- *  Arguments:
- *      dump                Pointer to buffered coredump data
- *      offset_in_space     XAP memory space to retrieve from the buffer (there
- *                          may be more than one zone covering the same memory
- *                          space, but starting from different offsets).
- *      offset              Offset within the XAP memory space to be retrieved
- *
- *  Returns:
- *      >=0                  Register value on success
- *      <0                   Register out of range of any captured zones
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-static s32 get_value_from_coredump(const coredump_buffer       *coreDump,
-                                        const unifi_coredump_space_t space,
-                                        const u16              offset_in_space)
-{
-    s32 r = -1;
-    u16 offset_in_zone;
-    u32 zone_end_offset;
-    s32 i;
-    const struct coredump_zone *def = &zonedef_table[0];
-
-    /* Search zone def table for a match with the requested memory space */
-    for (i = 0; i < HIP_CDUMP_NUM_ZONES; i++, def++)
-    {
-        if (space == def->space)
-        {
-            zone_end_offset = def->offset + def->length;
-
-            /* Is the space offset contained in this zone? */
-            if (offset_in_space < zone_end_offset &&
-                offset_in_space >= def->offset)
-            {
-                /* Calculate the offset of data within the zone buffer */
-                offset_in_zone = offset_in_space - def->offset;
-                r = (s32) * (coreDump->zone[i] + offset_in_zone);
-
-                unifi_trace(NULL, UDBG6,
-                            "sp %d, offs 0x%04x = 0x%04x (in z%d 0x%04x->0x%04x)\n",
-                            space, offset_in_space, r,
-                            i, def->offset, zone_end_offset - 1);
-                break;
-            }
-        }
-    }
-    return r;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_coredump_get_value
- *
- *      Retrieve the value of a register buffered from a previous core dump,
- *      so that it may be reported back to application code.
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      req_reg         Pointer to request parameter partially filled. This
- *                      function puts in the values retrieved from the dump.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, or:
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         Null parameter error
- *      CSR_WIFI_HIP_RESULT_RANGE                 Register out of range
- *      CSR_WIFI_HIP_RESULT_NOT_FOUND             Dump index not (yet) captured
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_coredump_get_value(card_t *card, struct unifi_coredump_req *req)
-{
-    CsrResult r;
-    s32 i = 0;
-    coredump_buffer *find_dump = NULL;
-
-    if (req == NULL || card == NULL)
-    {
-        r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-        goto done;
-    }
-    req->value = -1;
-    if (card->dump_buf == NULL)
-    {
-        unifi_trace(card->ospriv, UDBG2, "No coredump buffers\n");
-        r = CSR_WIFI_HIP_RESULT_NOT_FOUND;     /* Coredumping disabled */
-        goto done;
-    }
-    if (card->dump_cur_read == NULL)
-    {
-        unifi_trace(card->ospriv, UDBG4, "No coredumps captured\n");
-        r = CSR_WIFI_HIP_RESULT_NOT_FOUND;     /* No coredump yet captured */
-        goto done;
-    }
-
-    /* Find the requested dump buffer */
-    switch (req->index)
-    {
-        case 0:     /* Newest */
-            find_dump = card->dump_cur_read;
-            break;
-        case -1:    /* Oldest: The next used slot forward */
-            for (find_dump = card->dump_cur_read->next;
-                 (find_dump->count == 0) && (find_dump != card->dump_cur_read);
-                 find_dump = card->dump_cur_read->next)
-            {
-            }
-            break;
-        default:    /* Number of steps back from current read position */
-            for (i = 0, find_dump = card->dump_cur_read;
-                 i < req->index;
-                 i++, find_dump = find_dump->prev)
-            {
-                /* Walk the list for the index'th entry, but
-                 * stop when about to wrap. */
-                unifi_trace(card->ospriv, UDBG6,
-                            "%d: %d, @%p, p=%p, n=%p, cr=%p, h=%p\n",
-                            i, find_dump->count, find_dump, find_dump->prev,
-                            find_dump->next, card->dump_cur_read, card->dump_buf);
-                if (find_dump->prev == card->dump_cur_read)
-                {
-                    /* Wrapped but still not found, index out of range */
-                    if (i != req->index)
-                    {
-                        unifi_trace(card->ospriv, UDBG6,
-                                    "Dump index %d not found %d\n", req->index, i);
-                        r = CSR_WIFI_HIP_RESULT_NOT_FOUND;
-                        goto done;
-                    }
-                    break;
-                }
-            }
-            break;
-    }
-
-    /* Check if the slot is actually filled with a core dump */
-    if (find_dump->count == 0)
-    {
-        unifi_trace(card->ospriv, UDBG4, "Not captured %d\n", req->index);
-        r = CSR_WIFI_HIP_RESULT_NOT_FOUND;
-        goto done;
-    }
-
-    unifi_trace(card->ospriv, UDBG6, "Req index %d, found seq %d at step %d\n",
-                req->index, find_dump->count, i);
-
-    /* Find the appropriate entry in the buffer */
-    req->value = get_value_from_coredump(find_dump, req->space, (u16)req->offset);
-    if (req->value < 0)
-    {
-        r = CSR_WIFI_HIP_RESULT_RANGE;     /* Un-captured register */
-        unifi_trace(card->ospriv, UDBG4,
-                    "Can't read space %d, reg 0x%x from coredump buffer %d\n",
-                    req->space, req->offset, req->index);
-    }
-    else
-    {
-        r = CSR_RESULT_SUCCESS;
-    }
-
-    /* Update the private request structure with the found values */
-    req->chip_ver = find_dump->chip_ver;
-    req->fw_ver = find_dump->fw_ver;
-    req->timestamp = find_dump->timestamp;
-    req->requestor = find_dump->requestor;
-    req->serial = find_dump->count;
-
-done:
-    return r;
-} /* unifi_coredump_get_value() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_coredump_read_zone
- *
- *      Captures a UniFi memory zone into a buffer on the host
- *
- *  Arguments:
- *      card          Pointer to card struct
- *      zonebuf       Pointer to on-host buffer to dump the memory zone into
- *      def           Pointer to description of the memory zone to read from UniFi.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS                   on success, or:
- *      CSR_RESULT_FAILURE                   SDIO error
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         Parameter error
- *
- *  Notes:
- *      It is assumed that the caller has already stopped the XAPs
- * ---------------------------------------------------------------------------
- */
-static CsrResult unifi_coredump_read_zone(card_t *card, u16 *zonebuf, const struct coredump_zone *def)
-{
-    CsrResult r;
-
-    if (zonebuf == NULL || def == NULL)
-    {
-        r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-        goto done;
-    }
-
-    /* Select XAP CPU if necessary */
-    if (def->cpu != UNIFI_PROC_INVALID)
-    {
-        if (def->cpu != UNIFI_PROC_MAC && def->cpu != UNIFI_PROC_PHY)
-        {
-            r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            goto done;
-        }
-        r = unifi_set_proc_select(card, def->cpu);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            goto done;
-        }
-    }
-
-    unifi_trace(card->ospriv, UDBG4,
-                "Dump sp %d, offs 0x%04x, 0x%04x words @GP=%08x CPU %d\n",
-                def->space, def->offset, def->length, def->gp, def->cpu);
-
-    /* Read on-chip RAM (byte-wise) */
-    r = unifi_card_readn(card, def->gp, zonebuf, (u16)(def->length * 2));
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        goto done;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Can't read UniFi shared data area\n");
-        goto done;
-    }
-
-done:
-    return r;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_coredump_read_zones
- *
- *      Walks through the table of on-chip memory zones defined in zonedef_table,
- *      and reads each of them from the UniFi chip
- *
- *  Arguments:
- *      card          Pointer to card struct
- *      dump_buf      Buffer into which register values will be dumped
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS                   on success, or:
- *      CSR_RESULT_FAILURE                   SDIO error
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         Parameter error
- *
- *  Notes:
- *      It is assumed that the caller has already stopped the XAPs
- * ---------------------------------------------------------------------------
- */
-static CsrResult unifi_coredump_read_zones(card_t *card, coredump_buffer *dump_buf)
-{
-    CsrResult r = CSR_RESULT_SUCCESS;
-    s32 i;
-
-    /* Walk the table of coredump zone definitions and read them from the chip */
-    for (i = 0;
-         (i < HIP_CDUMP_NUM_ZONES) && (r == 0);
-         i++)
-    {
-        r = unifi_coredump_read_zone(card, dump_buf->zone[i], &zonedef_table[i]);
-    }
-
-    return r;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_coredump_from_sdio
- *
- *      Capture the status of the UniFi processors, over SDIO
- *
- *  Arguments:
- *      card            Pointer to card struct
- *      reg_buffer      Buffer into which register values will be dumped
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS                   on success, or:
- *      CSR_RESULT_FAILURE                   SDIO error
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         Parameter error
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-static CsrResult unifi_coredump_from_sdio(card_t *card, coredump_buffer *dump_buf)
-{
-    u16 val;
-    CsrResult r;
-    u32 sdio_addr;
-
-    if (dump_buf == NULL)
-    {
-        r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-        goto done;
-    }
-
-
-    /* Chip and firmware version */
-    unifi_trace(card->ospriv, UDBG4, "Get chip version\n");
-    sdio_addr = 2 * ChipHelper_GBL_CHIP_VERSION(card->helper);
-    if (sdio_addr != 0)
-    {
-        r = unifi_read_direct16(card, sdio_addr, &val);
-        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-        {
-            goto done;
-        }
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "Can't read GBL_CHIP_VERSION\n");
-            goto done;
-        }
-    }
-    dump_buf->chip_ver = val;
-    dump_buf->fw_ver = card->build_id;
-
-    unifi_trace(card->ospriv, UDBG4, "chip_ver 0x%04x, fw_ver %u\n",
-                dump_buf->chip_ver, dump_buf->fw_ver);
-
-    /* Capture the memory zones required from UniFi */
-    r = unifi_coredump_read_zones(card, dump_buf);
-    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
-    {
-        goto done;
-    }
-    if (r != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(card->ospriv, "Can't read UniFi memory areas\n");
-        goto done;
-    }
-
-done:
-    return r;
-} /* unifi_coredump_from_sdio() */
-
-
-#ifndef UNIFI_DISABLE_COREDUMP
-/*
- * ---------------------------------------------------------------------------
- *  new_coredump_node
- *
- *      Allocates a coredump linked-list node, and links it to the previous.
- *
- *  Arguments:
- *      ospriv          OS context
- *      prevnode        Previous node to link into
- *
- *  Returns:
- *      Pointer to valid coredump_buffer on success
- *      NULL on memory allocation failure
- *
- *  Notes:
- *      Allocates "all or nothing"
- * ---------------------------------------------------------------------------
- */
-static
-coredump_buffer* new_coredump_node(void *ospriv, coredump_buffer *prevnode)
-{
-    coredump_buffer *newnode = NULL;
-    u16 *newzone = NULL;
-    s32 i;
-    u32 zone_size;
-
-    /* Allocate node header */
-    newnode = kzalloc(sizeof(coredump_buffer), GFP_KERNEL);
-    if (newnode == NULL)
-    {
-        return NULL;
-    }
-
-    /* Allocate chip memory zone capture buffers */
-    for (i = 0; i < HIP_CDUMP_NUM_ZONES; i++)
-    {
-        zone_size = sizeof(u16) * zonedef_table[i].length;
-        newzone = kzalloc(zone_size, GFP_KERNEL);
-        newnode->zone[i] = newzone;
-        if (newzone == NULL)
-        {
-            unifi_error(ospriv, "Out of memory on coredump zone %d (%d words)\n",
-                        i, zonedef_table[i].length);
-            break;
-        }
-    }
-
-    /* Clean up if any zone alloc failed */
-    if (newzone == NULL)
-    {
-        for (i = 0; newnode->zone[i] != NULL; i++)
-        {
-            kfree(newnode->zone[i]);
-            newnode->zone[i] = NULL;
-        }
-    }
-
-    /* Link to previous node */
-    newnode->prev = prevnode;
-    if (prevnode)
-    {
-        prevnode->next = newnode;
-    }
-    newnode->next = NULL;
-
-    return newnode;
-}
-
-
-#endif /* UNIFI_DISABLE_COREDUMP */
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_coredump_init
- *
- *      Allocates buffers for the automatic SDIO core dump
- *
- *  Arguments:
- *      card                Pointer to card struct
- *      num_dump_buffers    Number of buffers to reserve for coredumps
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS               on success, or:
- *      CSR_WIFI_HIP_RESULT_NO_MEMORY         memory allocation failed
- *
- *  Notes:
- *      Allocates space in advance, to be used for the last n coredump buffers
- *      the intention being that the size is sufficient for at least one dump,
- *      probably several.
- *      It's probably advisable to have at least 2 coredump buffers to allow
- *      one to be enquired with the unifi_coredump tool, while leaving another
- *      free for capturing.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_coredump_init(card_t *card, u16 num_dump_buffers)
-{
-#ifndef UNIFI_DISABLE_COREDUMP
-    void *ospriv = card->ospriv;
-    coredump_buffer *prev = NULL;
-    coredump_buffer *newnode = NULL;
-    u32 i = 0;
-#endif
-
-    card->request_coredump_on_reset = 0;
-    card->dump_next_write = NULL;
-    card->dump_cur_read = NULL;
-    card->dump_buf = NULL;
-
-#ifndef UNIFI_DISABLE_COREDUMP
-    unifi_trace(ospriv, UDBG1,
-                "Allocate buffers for %d core dumps\n", num_dump_buffers);
-    if (num_dump_buffers == 0)
-    {
-        goto done;
-    }
-
-    /* Root node */
-    card->dump_buf = new_coredump_node(ospriv, NULL);
-    if (card->dump_buf == NULL)
-    {
-        goto fail;
-    }
-    prev = card->dump_buf;
-    newnode = card->dump_buf;
-
-    /* Add each subsequent node at tail */
-    for (i = 1; i < num_dump_buffers; i++)
-    {
-        newnode = new_coredump_node(ospriv, prev);
-        if (newnode == NULL)
-        {
-            goto fail;
-        }
-        prev = newnode;
-    }
-
-    /* Link the first and last nodes to make the list circular */
-    card->dump_buf->prev = newnode;
-    newnode->next = card->dump_buf;
-
-    /* Set initial r/w access pointers */
-    card->dump_next_write = card->dump_buf;
-    card->dump_cur_read = NULL;
-
-    unifi_trace(ospriv, UDBG2, "Core dump configured (%d dumps max)\n", i);
-
-done:
-#endif
-    return CSR_RESULT_SUCCESS;
-
-#ifndef UNIFI_DISABLE_COREDUMP
-fail:
-    /* Unwind what we allocated so far */
-    unifi_error(ospriv, "Out of memory allocating core dump node %d\n", i);
-    unifi_coredump_free(card);
-    return CSR_WIFI_HIP_RESULT_NO_MEMORY;
-#endif
-} /* unifi_coreump_init() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_coredump_free
- *
- *      Free all memory dynamically allocated for core dump
- *
- *  Arguments:
- *      card            Pointer to card struct
- *
- *  Returns:
- *      None
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-void unifi_coredump_free(card_t *card)
-{
-    void *ospriv = card->ospriv;
-    coredump_buffer *node, *del_node;
-    s16 i = 0;
-    s16 j;
-
-    unifi_trace(ospriv, UDBG2, "Core dump de-configured\n");
-
-    if (card->dump_buf == NULL)
-    {
-        return;
-    }
-
-    node = card->dump_buf;
-    do
-    {
-        /* Free payload zones */
-        for (j = 0; j < HIP_CDUMP_NUM_ZONES; j++)
-        {
-            kfree(node->zone[j]);
-            node->zone[j] = NULL;
-        }
-
-        /* Detach */
-        del_node = node;
-        node = node->next;
-
-        /* Free header */
-        kfree(del_node);
-        i++;
-    } while ((node != NULL) && (node != card->dump_buf));
-
-    unifi_trace(ospriv, UDBG3, "Freed %d coredump buffers\n", i);
-
-    card->dump_buf = NULL;
-    card->dump_next_write = NULL;
-    card->dump_cur_read = NULL;
-} /* unifi_coredump_free() */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_packing.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_packing.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_packing.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_packing.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,4804 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#include "csr_wifi_hip_signals.h"
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-
-
-/*
- * ---------------------------------------------------------------------------
- *  get_packed_struct_size
- *
- *      Examine a buffer containing a UniFi signal in wire-format.
- *      The first two bytes contain the signal ID, decode the signal ID and
- *      return the size, in  bytes, of the signal, not including any bulk
- *      data.
- *
- *      WARNING: This function is auto-generated, DO NOT EDIT!
- *
- *  Arguments:
- *      buf     Pointer to buffer to decode.
- *
- *  Returns:
- *      0 if the signal ID is not recognised (i.e. zero length),
- *      otherwise the number of bytes occupied by the signal in the buffer.
- *      This is useful for stepping past the signal to the object in the buffer.
- * ---------------------------------------------------------------------------
- */
-s32 get_packed_struct_size(const u8 *buf)
-{
-    s32 size = 0;
-    u16 sig_id;
-
-    sig_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(buf);
-
-    size += SIZEOF_UINT16;
-    size += SIZEOF_UINT16;
-    size += SIZEOF_UINT16;
-    switch (sig_id)
-    {
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_DEBUG_WORD16_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-        case CSR_DEBUG_GENERIC_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-        case CSR_MA_PACKET_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT64;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-        case CSR_MLME_SET_TIM_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECTED_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT32;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            break;
-#endif
-        case CSR_DEBUG_GENERIC_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT32;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MLME_SET_TIM_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_DEBUG_GENERIC_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-        case CSR_MA_PACKET_CANCEL_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT32;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_PACKET_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT32;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_VIF_AVAILABILITY_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            break;
-#endif
-        case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT32;
-            size += SIZEOF_UINT32;
-            size += SIZEOF_UINT32;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT32;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 32 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_PACKET_ERROR_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT32;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT32;
-            size += SIZEOF_UINT32;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_DEBUG_STRING_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += 48 / 8;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_PACKET_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT32;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_REQUEST_ID:
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            size += SIZEOF_UINT16;
-            break;
-#endif
-        default:
-            size = 0;
-    }
-    return size;
-} /* get_packed_struct_size() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  read_unpack_signal
- *
- *      Unpack a wire-format signal into a host-native structure.
- *      This function handles any necessary conversions for endianness and
- *      places no restrictions on packing or alignment for the structure
- *      definition.
- *
- *      WARNING: This function is auto-generated, DO NOT EDIT!
- *
- *  Arguments:
- *      ptr             Signal buffer to unpack.
- *      sig             Pointer to destination structure to populate.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success,
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE if the ID of signal was not recognised.
- * ---------------------------------------------------------------------------
- */
-CsrResult read_unpack_signal(const u8 *ptr, CSR_SIGNAL *sig)
-{
-    s32 index = 0;
-
-    sig->SignalPrimitiveHeader.SignalId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-    index += SIZEOF_UINT16;
-
-    sig->SignalPrimitiveHeader.ReceiverProcessId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-    index += SIZEOF_UINT16;
-
-    sig->SignalPrimitiveHeader.SenderProcessId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-    index += SIZEOF_UINT16;
-
-    switch (sig->SignalPrimitiveHeader.SignalId)
-    {
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID:
-            sig->u.MlmeSetPacketFilterConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_CONFIRM_ID:
-            sig->u.MlmeSetkeysConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID:
-            sig->u.MlmeConfigQueueConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
-            sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanConfirm.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID:
-            sig->u.MlmeAddBlackoutConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutConfirm.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_REQUEST_ID:
-            sig->u.MlmeDelBlackoutRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutRequest.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID:
-            sig->u.MlmeGetKeySequenceConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_CONFIRM_ID:
-            sig->u.MlmeSmStartConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID:
-            sig->u.MlmeStopAggregationConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeStopAggregationConfirm.PeerQstaAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeStopAggregationConfirm.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationConfirm.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_REQUEST_ID:
-            sig->u.MlmeDelTspecRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecRequest.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_DEBUG_WORD16_INDICATION_ID:
-            sig->u.DebugWord16Indication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[8] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[9] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[10] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[11] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[12] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[13] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[14] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugWord16Indication.DebugWords[15] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-        case CSR_DEBUG_GENERIC_CONFIRM_ID:
-            sig->u.DebugGenericConfirm.DebugVariable.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.DebugVariable.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.DebugWords[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.DebugWords[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.DebugWords[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.DebugWords[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.DebugWords[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.DebugWords[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.DebugWords[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericConfirm.DebugWords[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-        case CSR_MA_PACKET_INDICATION_ID:
-            sig->u.MaPacketIndication.Data.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketIndication.Data.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MaPacketIndication.LocalTime.x, &ptr[index], 64 / 8);
-            index += 64 / 8;
-            sig->u.MaPacketIndication.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketIndication.Channel = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketIndication.ReceptionStatus = (CSR_RECEPTION_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketIndication.Rssi = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketIndication.Snr = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketIndication.ReceivedRate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-        case CSR_MLME_SET_TIM_REQUEST_ID:
-            sig->u.MlmeSetTimRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimRequest.AssociationId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimRequest.TimValue = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECTED_INDICATION_ID:
-            sig->u.MlmeConnectedIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectedIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectedIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectedIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectedIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectedIndication.ConnectionStatus = (CSR_CONNECTION_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeConnectedIndication.PeerMacAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID:
-            sig->u.MlmeDelRxTriggerRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerRequest.TriggerId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
-            sig->u.MlmeTriggeredGetIndication.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeTriggeredGetIndication.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeTriggeredGetIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeTriggeredGetIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeTriggeredGetIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeTriggeredGetIndication.Status = (CSR_MIB_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeTriggeredGetIndication.ErrorIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeTriggeredGetIndication.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_REQUEST_ID:
-            sig->u.MlmeScanRequest.ChannelList.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanRequest.ChannelList.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanRequest.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanRequest.ScanType = (CSR_SCAN_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanRequest.ProbeDelay = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            sig->u.MlmeScanRequest.MinChannelTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanRequest.MaxChannelTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_CONFIRM_ID:
-            sig->u.MlmeDeletekeysConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_REQUEST_ID:
-            sig->u.MlmeGetNextRequest.MibAttribute.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetNextRequest.MibAttribute.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetNextRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetNextRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_CONFIRM_ID:
-            sig->u.MlmeSetChannelConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_REQUEST_ID:
-            sig->u.MlmeStartAggregationRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeStartAggregationRequest.PeerQstaAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeStartAggregationRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationRequest.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationRequest.StartingSequenceNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationRequest.BufferSize = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationRequest.BlockAckTimeout = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_REQUEST_ID:
-            sig->u.MlmeHlSyncRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeHlSyncRequest.GroupAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-        case CSR_DEBUG_GENERIC_REQUEST_ID:
-            sig->u.DebugGenericRequest.DebugVariable.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.DebugVariable.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.DebugWords[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.DebugWords[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.DebugWords[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.DebugWords[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.DebugWords[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.DebugWords[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.DebugWords[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericRequest.DebugWords[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_CONFIRM_ID:
-            sig->u.MlmeLeaveConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeLeaveConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeLeaveConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeLeaveConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeLeaveConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeLeaveConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
-            sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetRequest.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID:
-            sig->u.MlmeAddMulticastAddressRequest.Data.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressRequest.Data.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressRequest.NumberOfMulticastGroupAddresses = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_REQUEST_ID:
-            sig->u.MlmeResetRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeResetRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeResetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeResetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeResetRequest.StaAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeResetRequest.SetDefaultMib = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
-            sig->u.MlmeScanCancelRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanCancelRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanCancelRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanCancelRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanCancelRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
-            sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetConfirm.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID:
-            sig->u.MlmeSetPacketFilterRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterRequest.PacketFilterMode = (CSR_PACKET_FILTER_MODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetPacketFilterRequest.ArpFilterAddress = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID:
-            sig->u.MlmeDelRxTriggerConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerConfirm.TriggerId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelRxTriggerConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_REQUEST_ID:
-            sig->u.MlmeConnectStatusRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusRequest.ConnectionStatus = (CSR_CONNECTION_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeConnectStatusRequest.StaAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeConnectStatusRequest.AssociationId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusRequest.AssociationCapabilityInformation = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_REQUEST_ID:
-            sig->u.MlmeLeaveRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeLeaveRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeLeaveRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeLeaveRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeLeaveRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_REQUEST_ID:
-            sig->u.MlmeConfigQueueRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueRequest.QueueIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueRequest.Aifs = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueRequest.Cwmin = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueRequest.Cwmax = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConfigQueueRequest.TxopLimit = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_CONFIRM_ID:
-            sig->u.MlmeDelTspecConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecConfirm.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTspecConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MLME_SET_TIM_CONFIRM_ID:
-            sig->u.MlmeSetTimConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetTimConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_INDICATION_ID:
-            sig->u.MlmeMeasureIndication.MeasurementReportSet.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureIndication.MeasurementReportSet.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureIndication.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID:
-            sig->u.MlmeDelBlackoutConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutConfirm.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelBlackoutConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
-            sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelTriggeredGetConfirm.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_DEBUG_GENERIC_INDICATION_ID:
-            sig->u.DebugGenericIndication.DebugVariable.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.DebugVariable.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.DebugWords[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.DebugWords[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.DebugWords[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.DebugWords[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.DebugWords[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.DebugWords[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.DebugWords[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugGenericIndication.DebugWords[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-        case CSR_MA_PACKET_CANCEL_REQUEST_ID:
-            sig->u.MaPacketCancelRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketCancelRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketCancelRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketCancelRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketCancelRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketCancelRequest.HostTag = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID:
-            sig->u.MlmeModifyBssParameterConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
-            sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanConfirm.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_PACKET_REQUEST_ID:
-            sig->u.MaPacketRequest.Data.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketRequest.Data.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketRequest.TransmitRate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketRequest.HostTag = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            sig->u.MaPacketRequest.Priority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MaPacketRequest.Ra.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MaPacketRequest.TransmissionControl = (CSR_TRANSMISSION_CONTROL) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID:
-            sig->u.MlmeModifyBssParameterRequest.Data.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterRequest.Data.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterRequest.BeaconPeriod = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterRequest.DtimPeriod = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeModifyBssParameterRequest.CapabilityInformation = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeModifyBssParameterRequest.Bssid.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeModifyBssParameterRequest.RtsThreshold = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID:
-            sig->u.MlmeAddRxTriggerRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerRequest.TriggerId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerRequest.Priority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_VIF_AVAILABILITY_INDICATION_ID:
-            sig->u.MaVifAvailabilityIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityIndication.Multicast = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
-            sig->u.MlmeHlSyncCancelRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncCancelRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncCancelRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncCancelRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeHlSyncCancelRequest.GroupAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
-            sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanRequest.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID:
-            sig->u.MlmeBlackoutEndedIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlackoutEndedIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlackoutEndedIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlackoutEndedIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlackoutEndedIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlackoutEndedIndication.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
-            sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanDoneIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanDoneIndication.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanDoneIndication.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID:
-            sig->u.MlmeGetKeySequenceRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceRequest.KeyId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetKeySequenceRequest.KeyType = (CSR_KEY_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeGetKeySequenceRequest.Address.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_REQUEST_ID:
-            sig->u.MlmeSetChannelRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelRequest.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelRequest.Channel = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeSetChannelRequest.Address.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeSetChannelRequest.AvailabilityDuration = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetChannelRequest.AvailabilityInterval = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_CONFIRM_ID:
-            sig->u.MlmeMeasureConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureConfirm.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
-            sig->u.MlmeAddTriggeredGetRequest.MibAttribute.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetRequest.MibAttribute.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTriggeredGetRequest.TriggeredId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID:
-            sig->u.MlmeAutonomousScanLossIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanLossIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanLossIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanLossIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAutonomousScanLossIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeAutonomousScanLossIndication.Bssid.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-        case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID:
-            sig->u.MaVifAvailabilityResponse.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityResponse.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityResponse.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityResponse.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityResponse.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaVifAvailabilityResponse.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_REQUEST_ID:
-            sig->u.MlmeAddTemplateRequest.Data1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateRequest.Data1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateRequest.Data2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateRequest.Data2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateRequest.FrameType = (CSR_FRAME_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateRequest.MinTransmitRate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_CONFIRM_ID:
-            sig->u.MlmePowermgtConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
-            sig->u.MlmeAddPeriodicConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicConfirm.PeriodicId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_CONFIRM_ID:
-            sig->u.MlmeGetConfirm.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetConfirm.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetConfirm.Status = (CSR_MIB_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetConfirm.ErrorIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_CONFIRM_ID:
-            sig->u.MlmeGetNextConfirm.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetNextConfirm.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetNextConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetNextConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetNextConfirm.Status = (CSR_MIB_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetNextConfirm.ErrorIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_REQUEST_ID:
-            sig->u.MlmeStopAggregationRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeStopAggregationRequest.PeerQstaAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeStopAggregationRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopAggregationRequest.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID:
-            sig->u.MlmeAddRxTriggerConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerConfirm.TriggerId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddRxTriggerConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_REQUEST_ID:
-            sig->u.MlmeAddBlackoutRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutRequest.BlackoutId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutRequest.BlackoutType = (CSR_BLACKOUT_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutRequest.BlackoutSource = (CSR_BLACKOUT_SOURCE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddBlackoutRequest.BlackoutStartReference = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            sig->u.MlmeAddBlackoutRequest.BlackoutPeriod = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            sig->u.MlmeAddBlackoutRequest.BlackoutDuration = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            memcpy(sig->u.MlmeAddBlackoutRequest.PeerStaAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeAddBlackoutRequest.BlackoutCount = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_REQUEST_ID:
-            sig->u.MlmeDeletekeysRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysRequest.KeyId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDeletekeysRequest.KeyType = (CSR_KEY_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeDeletekeysRequest.Address.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_CONFIRM_ID:
-            sig->u.MlmeResetConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeResetConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeResetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeResetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeResetConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CONFIRM_ID:
-            sig->u.MlmeHlSyncConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeHlSyncConfirm.GroupAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeHlSyncConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
-            sig->u.MlmeAddAutonomousScanRequest.ChannelList.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.ChannelList.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.InformationElements.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.InformationElements.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.ChannelStartingFactor = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.ScanType = (CSR_SCAN_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.ProbeDelay = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            sig->u.MlmeAddAutonomousScanRequest.MinChannelTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddAutonomousScanRequest.MaxChannelTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_REQUEST_ID:
-            sig->u.MlmeSetRequest.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetRequest.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_REQUEST_ID:
-            sig->u.MlmeSmStartRequest.Beacon.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartRequest.Beacon.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartRequest.BssParameters.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartRequest.BssParameters.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartRequest.Ifindex = (CSR_IFINTERFACE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartRequest.Channel = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeSmStartRequest.InterfaceAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            memcpy(sig->u.MlmeSmStartRequest.Bssid.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeSmStartRequest.BeaconPeriod = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartRequest.DtimPeriod = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSmStartRequest.CapabilityInformation = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_CONFIRM_ID:
-            sig->u.MlmeConnectStatusConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeConnectStatusConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
-            sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelAutonomousScanConfirm.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
-            sig->u.MlmeDelPeriodicRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicRequest.PeriodicId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_REQUEST_ID:
-            sig->u.MlmeSetkeysRequest.Key.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.Key.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.Length = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.KeyId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.KeyType = (CSR_KEY_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeSetkeysRequest.Address.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeSetkeysRequest.SequenceNumber[0] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.SequenceNumber[1] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.SequenceNumber[2] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.SequenceNumber[3] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.SequenceNumber[4] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.SequenceNumber[5] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.SequenceNumber[6] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetkeysRequest.SequenceNumber[7] = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(&sig->u.MlmeSetkeysRequest.CipherSuiteSelector, &ptr[index], 32 / 8);
-            index += 32 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
-            sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanRequest.AutonomousScanId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePauseAutonomousScanRequest.Pause = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_REQUEST_ID:
-            sig->u.MlmeGetRequest.MibAttribute.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetRequest.MibAttribute.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeGetRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_REQUEST_ID:
-            sig->u.MlmePowermgtRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtRequest.PowerManagementMode = (CSR_POWER_MANAGEMENT_MODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtRequest.ReceiveDtims = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtRequest.ListenInterval = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmePowermgtRequest.TrafficWindow = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_PACKET_ERROR_INDICATION_ID:
-            sig->u.MaPacketErrorIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketErrorIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketErrorIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketErrorIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketErrorIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MaPacketErrorIndication.PeerQstaAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MaPacketErrorIndication.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketErrorIndication.SequenceNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
-            sig->u.MlmeAddPeriodicRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicRequest.PeriodicId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicRequest.MaximumLatency = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            sig->u.MlmeAddPeriodicRequest.PeriodicSchedulingMode = (CSR_PERIODIC_SCHEDULING_MODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicRequest.WakeHost = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddPeriodicRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_REQUEST_ID:
-            sig->u.MlmeAddTspecRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecRequest.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecRequest.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecRequest.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecRequest.PsScheme = (CSR_PS_SCHEME) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecRequest.MediumTime = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecRequest.ServiceStartTime = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            sig->u.MlmeAddTspecRequest.ServiceInterval = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            sig->u.MlmeAddTspecRequest.MinimumDataRate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID:
-            sig->u.MlmeAddMulticastAddressConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddMulticastAddressConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_CONFIRM_ID:
-            sig->u.MlmeAddTspecConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecConfirm.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTspecConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
-            sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeHlSyncCancelConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CONFIRM_ID:
-            sig->u.MlmeScanConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeScanConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_DEBUG_STRING_INDICATION_ID:
-            sig->u.DebugStringIndication.DebugMessage.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugStringIndication.DebugMessage.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugStringIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.DebugStringIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID:
-            sig->u.MlmeAddTemplateConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateConfirm.FrameType = (CSR_FRAME_TYPE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeAddTemplateConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID:
-            sig->u.MlmeBlockackErrorIndication.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlockackErrorIndication.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlockackErrorIndication.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlockackErrorIndication.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlockackErrorIndication.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeBlockackErrorIndication.ResultCode = (CSR_REASON_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeBlockackErrorIndication.PeerQstaAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CONFIRM_ID:
-            sig->u.MlmeSetConfirm.MibAttributeValue.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetConfirm.MibAttributeValue.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetConfirm.Status = (CSR_MIB_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeSetConfirm.ErrorIndex = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_REQUEST_ID:
-            sig->u.MlmeMeasureRequest.MeasurementRequestSet.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureRequest.MeasurementRequestSet.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeMeasureRequest.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_CONFIRM_ID:
-            sig->u.MlmeStartAggregationConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(sig->u.MlmeStartAggregationConfirm.PeerQstaAddress.x, &ptr[index], 48 / 8);
-            index += 48 / 8;
-            sig->u.MlmeStartAggregationConfirm.UserPriority = (CSR_PRIORITY) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationConfirm.Direction = (CSR_DIRECTION) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStartAggregationConfirm.SequenceNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_CONFIRM_ID:
-            sig->u.MlmeStopMeasureConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopMeasureConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopMeasureConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopMeasureConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopMeasureConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopMeasureConfirm.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_PACKET_CONFIRM_ID:
-            sig->u.MaPacketConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketConfirm.TransmissionStatus = (CSR_TRANSMISSION_STATUS) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketConfirm.RetryCount = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketConfirm.Rate = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MaPacketConfirm.HostTag = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT32;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
-            sig->u.MlmeDelPeriodicConfirm.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicConfirm.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicConfirm.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicConfirm.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicConfirm.VirtualInterfaceIdentifier = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicConfirm.PeriodicId = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeDelPeriodicConfirm.ResultCode = (CSR_RESULT_CODE) CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_REQUEST_ID:
-            sig->u.MlmeStopMeasureRequest.Dummydataref1.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopMeasureRequest.Dummydataref1.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopMeasureRequest.Dummydataref2.SlotNumber = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopMeasureRequest.Dummydataref2.DataLength = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            sig->u.MlmeStopMeasureRequest.DialogToken = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-
-        default:
-            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-    return CSR_RESULT_SUCCESS;
-} /* read_unpack_signal() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  write_pack
- *
- *      Convert a signal structure, in host-native format, to the
- *      little-endian wire format specified in the UniFi Host Interface
- *      Protocol Specification.
- *
- *      WARNING: This function is auto-generated, DO NOT EDIT!
- *
- *  Arguments:
- *      sig             Pointer to signal structure to pack.
- *      ptr             Destination buffer to pack into.
- *      sig_len         Returns the length of the packed signal, i.e. the
- *                      number of bytes written to ptr.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success,
- *      CSR_WIFI_HIP_RESULT_INVALID_VALUE if the ID of signal was not recognised.
- * ---------------------------------------------------------------------------
- */
-CsrResult write_pack(const CSR_SIGNAL *sig, u8 *ptr, u16 *sig_len)
-{
-    s16 index = 0;
-
-    CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->SignalPrimitiveHeader.SignalId, ptr + index);
-    index += SIZEOF_UINT16;
-
-    CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->SignalPrimitiveHeader.ReceiverProcessId, ptr + index);
-    index += SIZEOF_UINT16;
-
-    CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->SignalPrimitiveHeader.SenderProcessId, ptr + index);
-    index += SIZEOF_UINT16;
-
-    switch (sig->SignalPrimitiveHeader.SignalId)
-    {
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanConfirm.AutonomousScanId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.BlackoutId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutRequest.BlackoutId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[0], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[1], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[2], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[3], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[4], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[5], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[6], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceConfirm.SequenceNumber[7], ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeStopAggregationConfirm.PeerQstaAddress.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.Direction, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecRequest.Direction, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_DEBUG_WORD16_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[0], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[1], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[2], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[3], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[4], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[5], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[6], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[7], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[8], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[9], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[10], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[11], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[12], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[13], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[14], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugWord16Indication.DebugWords[15], ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-        case CSR_DEBUG_GENERIC_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugVariable.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugVariable.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[0], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[1], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[2], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[3], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[4], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[5], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[6], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericConfirm.DebugWords[7], ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-        case CSR_MA_PACKET_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Data.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Data.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MaPacketIndication.LocalTime.x, 64 / 8);
-            index += 64 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Ifindex, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Channel, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.ReceptionStatus, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Rssi, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.Snr, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketIndication.ReceivedRate, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-        case CSR_MLME_SET_TIM_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.AssociationId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimRequest.TimValue, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECTED_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectedIndication.ConnectionStatus, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeConnectedIndication.PeerMacAddress.x, 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerRequest.TriggerId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.MibAttributeValue.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.MibAttributeValue.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.Status, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.ErrorIndex, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeTriggeredGetIndication.TriggeredId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.ChannelList.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.ChannelList.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.InformationElements.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.InformationElements.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.Ifindex, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.ScanType, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.ProbeDelay, ptr + index);
-            index += SIZEOF_UINT32;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.MinChannelTime, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanRequest.MaxChannelTime, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextRequest.MibAttribute.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextRequest.MibAttribute.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeStartAggregationRequest.PeerQstaAddress.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.Direction, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.StartingSequenceNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.BufferSize, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationRequest.BlockAckTimeout, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeHlSyncRequest.GroupAddress.x, 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-        case CSR_DEBUG_GENERIC_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugVariable.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugVariable.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[0], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[1], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[2], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[3], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[4], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[5], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[6], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericRequest.DebugWords[7], ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetRequest.TriggeredId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.Data.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.Data.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressRequest.NumberOfMulticastGroupAddresses, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeResetRequest.StaAddress.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetRequest.SetDefaultMib, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanCancelRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetConfirm.TriggeredId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.InformationElements.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.InformationElements.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.PacketFilterMode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeSetPacketFilterRequest.ArpFilterAddress, ptr + index);
-            index += SIZEOF_UINT32;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.TriggerId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelRxTriggerConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.InformationElements.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.InformationElements.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.ConnectionStatus, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeConnectStatusRequest.StaAddress.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.AssociationId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusRequest.AssociationCapabilityInformation, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeLeaveRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.QueueIndex, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Aifs, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Cwmin, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.Cwmax, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConfigQueueRequest.TxopLimit, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTspecConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MLME_SET_TIM_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetTimConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.MeasurementReportSet.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.MeasurementReportSet.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureIndication.DialogToken, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.BlackoutId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelBlackoutConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelTriggeredGetConfirm.TriggeredId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_DEBUG_GENERIC_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugVariable.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugVariable.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[0], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[1], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[2], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[3], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[4], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[5], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[6], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugGenericIndication.DebugWords[7], ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-        case CSR_MA_PACKET_CANCEL_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MaPacketCancelRequest.HostTag, ptr + index);
-            index += SIZEOF_UINT32;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanConfirm.AutonomousScanId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_PACKET_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Data.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Data.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.TransmitRate, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.HostTag, ptr + index);
-            index += SIZEOF_UINT32;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.Priority, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MaPacketRequest.Ra.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketRequest.TransmissionControl, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.Data.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.Data.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.BeaconPeriod, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.DtimPeriod, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.CapabilityInformation, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeModifyBssParameterRequest.Bssid.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeModifyBssParameterRequest.RtsThreshold, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.InformationElements.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.InformationElements.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.TriggerId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerRequest.Priority, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_VIF_AVAILABILITY_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityIndication.Multicast, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeHlSyncCancelRequest.GroupAddress.x, 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanRequest.AutonomousScanId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlackoutEndedIndication.BlackoutId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanDoneIndication.AutonomousScanId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.KeyId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetKeySequenceRequest.KeyType, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeGetKeySequenceRequest.Address.x, 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Ifindex, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.Channel, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeSetChannelRequest.Address.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.AvailabilityDuration, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetChannelRequest.AvailabilityInterval, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureConfirm.DialogToken, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.MibAttribute.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.MibAttribute.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTriggeredGetRequest.TriggeredId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAutonomousScanLossIndication.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeAutonomousScanLossIndication.Bssid.x, 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-        case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaVifAvailabilityResponse.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.Data1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.Data1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.Data2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.Data2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.FrameType, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateRequest.MinTransmitRate, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.PeriodicId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.MibAttributeValue.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.MibAttributeValue.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.Status, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetConfirm.ErrorIndex, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.MibAttributeValue.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.MibAttributeValue.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.Status, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetNextConfirm.ErrorIndex, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeStopAggregationRequest.PeerQstaAddress.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopAggregationRequest.Direction, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.TriggerId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddRxTriggerConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutType, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutSource, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutStartReference, ptr + index);
-            index += SIZEOF_UINT32;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutPeriod, ptr + index);
-            index += SIZEOF_UINT32;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutDuration, ptr + index);
-            index += SIZEOF_UINT32;
-            memcpy(ptr + index, sig->u.MlmeAddBlackoutRequest.PeerStaAddress.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddBlackoutRequest.BlackoutCount, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.KeyId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDeletekeysRequest.KeyType, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeDeletekeysRequest.Address.x, 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeResetConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeHlSyncConfirm.GroupAddress.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ChannelList.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ChannelList.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.InformationElements.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.InformationElements.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.AutonomousScanId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.Ifindex, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ChannelStartingFactor, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ScanType, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.ProbeDelay, ptr + index);
-            index += SIZEOF_UINT32;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.MinChannelTime, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddAutonomousScanRequest.MaxChannelTime, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetRequest.MibAttributeValue.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetRequest.MibAttributeValue.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.Beacon.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.Beacon.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.BssParameters.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.BssParameters.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.Ifindex, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.Channel, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeSmStartRequest.InterfaceAddress.x, 48 / 8);
-            index += 48 / 8;
-            memcpy(ptr + index, sig->u.MlmeSmStartRequest.Bssid.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.BeaconPeriod, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.DtimPeriod, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSmStartRequest.CapabilityInformation, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeConnectStatusConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelAutonomousScanConfirm.AutonomousScanId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicRequest.PeriodicId, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Key.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Key.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.Length, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.KeyId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.KeyType, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeSetkeysRequest.Address.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[0], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[1], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[2], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[3], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[4], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[5], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[6], ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetkeysRequest.SequenceNumber[7], ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, &sig->u.MlmeSetkeysRequest.CipherSuiteSelector, 32 / 8);
-            index += 32 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.AutonomousScanId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePauseAutonomousScanRequest.Pause, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetRequest.MibAttribute.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetRequest.MibAttribute.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeGetRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.PowerManagementMode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.ReceiveDtims, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.ListenInterval, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmePowermgtRequest.TrafficWindow, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_PACKET_ERROR_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MaPacketErrorIndication.PeerQstaAddress.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketErrorIndication.SequenceNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.PeriodicId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.MaximumLatency, ptr + index);
-            index += SIZEOF_UINT32;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.PeriodicSchedulingMode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.WakeHost, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddPeriodicRequest.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.Direction, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.PsScheme, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.MediumTime, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.ServiceStartTime, ptr + index);
-            index += SIZEOF_UINT32;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.ServiceInterval, ptr + index);
-            index += SIZEOF_UINT32;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecRequest.MinimumDataRate, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddMulticastAddressConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTspecConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeHlSyncCancelConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeScanConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_DEBUG_STRING_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugStringIndication.DebugMessage.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugStringIndication.DebugMessage.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugStringIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.DebugStringIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.FrameType, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeAddTemplateConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeBlockackErrorIndication.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeBlockackErrorIndication.PeerQstaAddress.x, 48 / 8);
-            index += 48 / 8;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.MibAttributeValue.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.MibAttributeValue.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.Status, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeSetConfirm.ErrorIndex, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.MeasurementRequestSet.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.MeasurementRequestSet.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeMeasureRequest.DialogToken, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            memcpy(ptr + index, sig->u.MlmeStartAggregationConfirm.PeerQstaAddress.x, 48 / 8);
-            index += 48 / 8;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.UserPriority, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.Direction, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStartAggregationConfirm.SequenceNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureConfirm.DialogToken, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-        case CSR_MA_PACKET_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.TransmissionStatus, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.RetryCount, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.Rate, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT32_TO_LITTLE_ENDIAN(sig->u.MaPacketConfirm.HostTag, ptr + index);
-            index += SIZEOF_UINT32;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.VirtualInterfaceIdentifier, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.PeriodicId, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeDelPeriodicConfirm.ResultCode, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_REQUEST_ID:
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.Dummydataref1.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.Dummydataref1.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.Dummydataref2.SlotNumber, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.Dummydataref2.DataLength, ptr + index);
-            index += SIZEOF_UINT16;
-            CSR_COPY_UINT16_TO_LITTLE_ENDIAN(sig->u.MlmeStopMeasureRequest.DialogToken, ptr + index);
-            index += SIZEOF_UINT16;
-            break;
-#endif
-
-        default:
-            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    *sig_len = index;
-
-    return CSR_RESULT_SUCCESS;
-} /* write_pack() */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_send.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_send.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_send.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_send.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,415 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ***************************************************************************
- *
- *  FILE:     csr_wifi_hip_send.c
- *
- *  PURPOSE:
- *      Code for adding a signal request to the from-host queue.
- *      When the driver bottom-half is run, it will take requests from the
- *      queue and pass them to the UniFi.
- *
- * ***************************************************************************
- */
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-#include "csr_wifi_hip_sigs.h"
-#include "csr_wifi_hip_card.h"
-
-unifi_TrafficQueue unifi_frame_priority_to_queue(CSR_PRIORITY priority)
-{
-    switch (priority)
-    {
-        case CSR_QOS_UP0:
-        case CSR_QOS_UP3:
-            return UNIFI_TRAFFIC_Q_BE;
-        case CSR_QOS_UP1:
-        case CSR_QOS_UP2:
-            return UNIFI_TRAFFIC_Q_BK;
-        case CSR_QOS_UP4:
-        case CSR_QOS_UP5:
-            return UNIFI_TRAFFIC_Q_VI;
-        case CSR_QOS_UP6:
-        case CSR_QOS_UP7:
-        case CSR_MANAGEMENT:
-            return UNIFI_TRAFFIC_Q_VO;
-        default:
-            return UNIFI_TRAFFIC_Q_BE;
-    }
-}
-
-
-CSR_PRIORITY unifi_get_default_downgrade_priority(unifi_TrafficQueue queue)
-{
-    switch (queue)
-    {
-        case UNIFI_TRAFFIC_Q_BE:
-            return CSR_QOS_UP0;
-        case UNIFI_TRAFFIC_Q_BK:
-            return CSR_QOS_UP1;
-        case UNIFI_TRAFFIC_Q_VI:
-            return CSR_QOS_UP5;
-        case UNIFI_TRAFFIC_Q_VO:
-            return CSR_QOS_UP6;
-        default:
-            return CSR_QOS_UP0;
-    }
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  send_signal
- *
- *      This function queues a signal for sending to UniFi.  It first checks
- *      that there is space on the fh_signal_queue for another entry, then
- *      claims any bulk data slots required and copies data into them. Then
- *      increments the fh_signal_queue write count.
- *
- *      The fh_signal_queue is later processed by the driver bottom half
- *      (in unifi_bh()).
- *
- *      This function call unifi_pause_xmit() to pause the flow of data plane
- *      packets when:
- *        - the fh_signal_queue ring buffer is full
- *        - there are less than UNIFI_MAX_DATA_REFERENCES (2) bulk data
- *          slots available.
- *
- *  Arguments:
- *      card            Pointer to card context structure
- *      sigptr          Pointer to the signal to write to UniFi.
- *      siglen          Number of bytes pointer to by sigptr.
- *      bulkdata        Array of pointers to an associated bulk data.
- *      sigq            To which from-host queue to add the signal.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success
- *      CSR_WIFI_HIP_RESULT_NO_SPACE if there were insufficient data slots or
- *                              no free signal queue entry
- *
- * Notes:
- *      Calls unifi_pause_xmit() when the last slots are used.
- * ---------------------------------------------------------------------------
- */
-static CsrResult send_signal(card_t *card, const u8 *sigptr, u32 siglen,
-                             const bulk_data_param_t *bulkdata,
-                             q_t *sigq, u32 priority_q, u32 run_bh)
-{
-    u16 i, data_slot_size;
-    card_signal_t *csptr;
-    s16 qe;
-    CsrResult r;
-    s16 debug_print = 0;
-
-    data_slot_size = CardGetDataSlotSize(card);
-
-    /* Check that the fh_data_queue has a free slot */
-    if (!CSR_WIFI_HIP_Q_SLOTS_FREE(sigq))
-    {
-        unifi_trace(card->ospriv, UDBG3, "send_signal: %s full\n", sigq->name);
-
-        return CSR_WIFI_HIP_RESULT_NO_SPACE;
-    }
-
-    /*
-     * Now add the signal to the From Host signal queue
-     */
-    /* Get next slot on queue */
-    qe = CSR_WIFI_HIP_Q_NEXT_W_SLOT(sigq);
-    csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, qe);
-
-    /* Make up the card_signal struct */
-    csptr->signal_length = (u16)siglen;
-    memcpy((void *)csptr->sigbuf, (void *)sigptr, siglen);
-
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i)
-    {
-        if ((bulkdata != NULL) && (bulkdata->d[i].data_length != 0))
-        {
-            u32 datalen = bulkdata->d[i].data_length;
-
-            /* Make sure data will fit in a bulk data slot */
-            if (bulkdata->d[i].os_data_ptr == NULL)
-            {
-                unifi_error(card->ospriv, "send_signal - NULL bulkdata[%d]\n", i);
-                debug_print++;
-                csptr->bulkdata[i].data_length = 0;
-            }
-            else
-            {
-                if (datalen > data_slot_size)
-                {
-                    unifi_error(card->ospriv,
-                                "send_signal - Invalid data length %u (@%p), "
-                                "truncating\n",
-                                datalen, bulkdata->d[i].os_data_ptr);
-                    datalen = data_slot_size;
-                    debug_print++;
-                }
-                /* Store the bulk data info in the soft queue. */
-                csptr->bulkdata[i].os_data_ptr = (u8 *)bulkdata->d[i].os_data_ptr;
-                csptr->bulkdata[i].os_net_buf_ptr = (u8 *)bulkdata->d[i].os_net_buf_ptr;
-                csptr->bulkdata[i].net_buf_length = bulkdata->d[i].net_buf_length;
-                csptr->bulkdata[i].data_length = datalen;
-            }
-        }
-        else
-        {
-            UNIFI_INIT_BULK_DATA(&csptr->bulkdata[i]);
-        }
-    }
-
-    if (debug_print)
-    {
-        const u8 *sig = sigptr;
-
-		unifi_error(card->ospriv, "Signal(%d): %*ph\n", siglen,
-					  16, sig);
-        unifi_error(card->ospriv, "Bulkdata pointer %p(%d), %p(%d)\n",
-                    bulkdata != NULL?bulkdata->d[0].os_data_ptr : NULL,
-                    bulkdata != NULL?bulkdata->d[0].data_length : 0,
-                    bulkdata != NULL?bulkdata->d[1].os_data_ptr : NULL,
-                    bulkdata != NULL?bulkdata->d[1].data_length : 0);
-    }
-
-    /* Advance the written count to say there is a new entry */
-    CSR_WIFI_HIP_Q_INC_W(sigq);
-
-    /*
-     * Set the flag to say reason for waking was a host request.
-     * Then ask the OS layer to run the unifi_bh.
-     */
-    if (run_bh == 1)
-    {
-        card->bh_reason_host = 1;
-        r = unifi_run_bh(card->ospriv);
-        if (r != CSR_RESULT_SUCCESS)
-        {
-            unifi_error(card->ospriv, "failed to run bh.\n");
-            card->bh_reason_host = 0;
-
-            /*
-             * The bulk data buffer will be freed by the caller.
-             * We need to invalidate the description of the bulk data in our
-             * soft queue, to prevent the core freeing the bulk data again later.
-             */
-            for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i)
-            {
-                if (csptr->bulkdata[i].data_length != 0)
-                {
-                    csptr->bulkdata[i].os_data_ptr = csptr->bulkdata[i].os_net_buf_ptr = NULL;
-                    csptr->bulkdata[i].net_buf_length = csptr->bulkdata[i].data_length = 0;
-                }
-            }
-            return r;
-        }
-    }
-    else
-    {
-        unifi_error(card->ospriv, "run_bh=%d, bh not called.\n", run_bh);
-    }
-
-    /*
-     * Have we used up all the fh signal list entries?
-     */
-    if (CSR_WIFI_HIP_Q_SLOTS_FREE(sigq) == 0)
-    {
-        /* We have filled the queue, so stop the upper layer. The command queue
-         * is an exception, as suspending due to that being full could delay
-         * resume/retry until new commands or data are received.
-         */
-        if (sigq != &card->fh_command_queue)
-        {
-            /*
-             * Must call unifi_pause_xmit() *before* setting the paused flag.
-             * (the unifi_pause_xmit call should not be after setting the flag because of the possibility of being interrupted
-             * by the bh thread between our setting the flag and the call to unifi_pause_xmit()
-             * If bh thread then cleared the flag, we would end up paused, but without the flag set)
-             * Instead, setting it afterwards means that if this thread is interrupted by the bh thread
-             * the pause flag is still guaranteed to end up set
-             * However the potential deadlock now is that if bh thread emptied the queue and cleared the flag before this thread's
-             * call to unifi_pause_xmit(), then bh thread may not run again because it will be waiting for
-             * a packet to appear in the queue but nothing ever will because xmit is paused.
-             * So we will end up with the queue paused, and the flag set to say it is paused, but bh never runs to unpause it.
-             * (Note even this bad situation would not persist long in practice, because something else (eg rx, or tx in different queue)
-             * is likely to wake bh thread quite soon)
-             * But to avoid this deadlock completely, after setting the flag we check that there is something left in the queue.
-             * If there is, we know that bh thread has not emptied the queue yet.
-             * Since bh thread checks to unpause the queue *after* taking packets from the queue, we know that it is still going to make at
-             * least one more check to see whether it needs to unpause the queue.  So all is well.
-             * If there are no packets in the queue, then the deadlock described above might happen.  To make sure it does not, we
-             * unpause the queue here. A possible side effect is that unifi_restart_xmit() may (rarely) be called for second time
-             *  unnecessarily, which is harmless
-             */
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-            unifi_debug_log_to_buf("P");
-#endif
-            unifi_pause_xmit(card->ospriv, (unifi_TrafficQueue)priority_q);
-            card_tx_q_pause(card, priority_q);
-            if (CSR_WIFI_HIP_Q_SLOTS_USED(sigq) == 0)
-            {
-                card_tx_q_unpause(card, priority_q);
-                unifi_restart_xmit(card->ospriv, (unifi_TrafficQueue) priority_q);
-            }
-        }
-        else
-        {
-            unifi_warning(card->ospriv,
-                          "send_signal: fh_cmd_q full, not pausing (run_bh=%d)\n",
-                          run_bh);
-        }
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /*  send_signal() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_send_signal
- *
- *    Invokes send_signal() to queue a signal in the command or traffic queue
- *    If sigptr pointer is NULL, it pokes the bh to check if UniFi is responsive.
- *
- *  Arguments:
- *      card        Pointer to card context struct
- *      sigptr      Pointer to signal from card.
- *      siglen      Size of the signal
- *      bulkdata    Pointer to the bulk data of the signal
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success
- *      CSR_WIFI_HIP_RESULT_NO_SPACE if there were insufficient data slots or no free signal queue entry
- *
- *  Notes:
- *      unifi_send_signal() is used to queue signals, created by the driver,
- *      to the device. Signals are constructed using the UniFi packed structures.
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_send_signal(card_t *card, const u8 *sigptr, u32 siglen,
-                            const bulk_data_param_t *bulkdata)
-{
-    q_t *sig_soft_q;
-    u16 signal_id;
-    CsrResult r;
-    u32 run_bh;
-    u32 priority_q;
-
-    /* A NULL signal pointer is a request to check if UniFi is responsive */
-    if (sigptr == NULL)
-    {
-        card->bh_reason_host = 1;
-        return unifi_run_bh(card->ospriv);
-    }
-
-    priority_q = 0;
-    run_bh = 1;
-    signal_id = GET_SIGNAL_ID(sigptr);
-    /*
-     * If the signal is a CSR_MA_PACKET_REQUEST ,
-     * we send it using the traffic soft queue. Else we use the command soft queue.
-     */
-    if (signal_id == CSR_MA_PACKET_REQUEST_ID)
-    {
-        u16 frame_priority;
-
-        if (card->periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_ENABLED)
-        {
-            run_bh = 0;
-        }
-
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
-        unifi_debug_log_to_buf("D");
-#endif
-        /* Sanity check: MA-PACKET.req must have a valid bulk data */
-        if ((bulkdata->d[0].data_length == 0) || (bulkdata->d[0].os_data_ptr == NULL))
-        {
-            unifi_error(card->ospriv, "MA-PACKET.req with empty bulk data (%d bytes in %p)\n",
-                        bulkdata->d[0].data_length, bulkdata->d[0].os_data_ptr);
-            dump((void *)sigptr, siglen);
-            return CSR_RESULT_FAILURE;
-        }
-
-        /* Map the frame priority to a traffic queue index. */
-        frame_priority = GET_PACKED_MA_PACKET_REQUEST_FRAME_PRIORITY(sigptr);
-        priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY)frame_priority);
-
-        sig_soft_q = &card->fh_traffic_queue[priority_q];
-    }
-    else
-    {
-        sig_soft_q = &card->fh_command_queue;
-    }
-
-    r = send_signal(card, sigptr, siglen, bulkdata, sig_soft_q, priority_q, run_bh);
-    /* On error, the caller must free or requeue bulkdata buffers */
-
-    return r;
-} /* unifi_send_signal() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_send_resources_available
- *
- *      Examines whether there is available space to queue
- *      a signal in the command or traffic queue
- *
- *  Arguments:
- *      card        Pointer to card context struct
- *      sigptr      Pointer to signal.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS if resources available
- *      CSR_WIFI_HIP_RESULT_NO_SPACE if there was no free signal queue entry
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_send_resources_available(card_t *card, const u8 *sigptr)
-{
-    q_t *sig_soft_q;
-    u16 signal_id = GET_SIGNAL_ID(sigptr);
-
-    /*
-     * If the signal is a CSR_MA_PACKET_REQUEST ,
-     * we send it using the traffic soft queue. Else we use the command soft queue.
-     */
-    if (signal_id == CSR_MA_PACKET_REQUEST_ID)
-    {
-        u16 frame_priority;
-        u32 priority_q;
-
-        /* Map the frame priority to a traffic queue index. */
-        frame_priority = GET_PACKED_MA_PACKET_REQUEST_FRAME_PRIORITY(sigptr);
-        priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY)frame_priority);
-
-        sig_soft_q = &card->fh_traffic_queue[priority_q];
-    }
-    else
-    {
-        sig_soft_q = &card->fh_command_queue;
-    }
-
-    /* Check that the fh_data_queue has a free slot */
-    if (!CSR_WIFI_HIP_Q_SLOTS_FREE(sig_soft_q))
-    {
-        unifi_notice(card->ospriv, "unifi_send_resources_available: %s full\n",
-                     sig_soft_q->name);
-        return CSR_WIFI_HIP_RESULT_NO_SPACE;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_send_resources_available() */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_signals.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_signals.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_signals.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_signals.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1313 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-
-/* Generated by hip_dd_l_c_gen.pl */
-
-#include "csr_wifi_hip_signals.h"
-
-#include "csr_wifi_hip_unifi.h"
-
-s32 SigGetSize(const CSR_SIGNAL *aSignal)
-{
-    switch (aSignal->SignalPrimitiveHeader.SignalId)
-    {
-        case CSR_MA_PACKET_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_REQUEST);
-        case CSR_MA_PACKET_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_CONFIRM);
-        case CSR_MA_PACKET_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_INDICATION);
-        case CSR_MA_PACKET_CANCEL_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_CANCEL_REQUEST);
-        case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_VIF_AVAILABILITY_RESPONSE);
-        case CSR_MA_VIF_AVAILABILITY_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_VIF_AVAILABILITY_INDICATION);
-        case CSR_MA_PACKET_ERROR_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MA_PACKET_ERROR_INDICATION);
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESET_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_RESET_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_NEXT_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_NEXT_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_POWERMGT_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_POWERMGT_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MEASURE_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MEASURE_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MEASURE_INDICATION);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SETKEYS_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SETKEYS_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELETEKEYS_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DELETEKEYS_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECTED_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONNECTED_INDICATION);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SCAN_CANCEL_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_CANCEL_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_HL_SYNC_CANCEL_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_PERIODIC_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_PERIODIC_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_PERIODIC_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_PERIODIC_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_PACKET_FILTER_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_PACKET_FILTER_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_STOP_MEASURE_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_STOP_MEASURE_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TRIGGERED_GET_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TRIGGERED_GET_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TRIGGERED_GET_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TRIGGERED_GET_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_TRIGGERED_GET_INDICATION);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_BLACKOUT_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_BLACKOUT_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_BLACKOUT_ENDED_INDICATION);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_BLACKOUT_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_BLACKOUT_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_RX_TRIGGER_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_RX_TRIGGER_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_RX_TRIGGER_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_RX_TRIGGER_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONNECT_STATUS_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONNECT_STATUS_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TEMPLATE_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TEMPLATE_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONFIG_QUEUE_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_CONFIG_QUEUE_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TSPEC_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_TSPEC_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TSPEC_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_DEL_TSPEC_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_START_AGGREGATION_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_START_AGGREGATION_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_BLOCKACK_ERROR_INDICATION);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_STOP_AGGREGATION_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_STOP_AGGREGATION_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SM_START_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SM_START_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_LEAVE_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_LEAVE_CONFIRM);
-#endif
-        case CSR_MLME_SET_TIM_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_TIM_REQUEST);
-        case CSR_MLME_SET_TIM_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_TIM_CONFIRM);
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_KEY_SEQUENCE_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_GET_KEY_SEQUENCE_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_CHANNEL_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_SET_CHANNEL_CONFIRM);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST);
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM);
-#endif
-        case CSR_DEBUG_STRING_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_STRING_INDICATION);
-        case CSR_DEBUG_WORD16_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_WORD16_INDICATION);
-        case CSR_DEBUG_GENERIC_REQUEST_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_GENERIC_REQUEST);
-        case CSR_DEBUG_GENERIC_CONFIRM_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_GENERIC_CONFIRM);
-        case CSR_DEBUG_GENERIC_INDICATION_ID:
-            return offsetof(struct CSR_SIGNAL_PRIMITIVE, u) + sizeof(CSR_DEBUG_GENERIC_INDICATION);
-        default:
-            return 0;
-    }
-}
-
-
-s32 SigGetDataRefs(CSR_SIGNAL *aSignal, CSR_DATAREF **aDataRef)
-{
-    s32 numRefs = 0;
-
-    switch (aSignal->SignalPrimitiveHeader.SignalId)
-    {
-        case CSR_MA_PACKET_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MaPacketRequest.Data;
-            aDataRef[numRefs++] = &aSignal->u.MaPacketRequest.Dummydataref2;
-            break;
-        case CSR_MA_PACKET_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MaPacketConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MaPacketConfirm.Dummydataref2;
-            break;
-        case CSR_MA_PACKET_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MaPacketIndication.Data;
-            aDataRef[numRefs++] = &aSignal->u.MaPacketIndication.Dummydataref2;
-            break;
-        case CSR_MA_PACKET_CANCEL_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MaPacketCancelRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MaPacketCancelRequest.Dummydataref2;
-            break;
-        case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID:
-            aDataRef[numRefs++] = &aSignal->u.MaVifAvailabilityResponse.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MaVifAvailabilityResponse.Dummydataref2;
-            break;
-        case CSR_MA_VIF_AVAILABILITY_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MaVifAvailabilityIndication.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MaVifAvailabilityIndication.Dummydataref2;
-            break;
-        case CSR_MA_PACKET_ERROR_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MaPacketErrorIndication.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MaPacketErrorIndication.Dummydataref2;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeResetRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeResetRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeResetConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeResetConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetRequest.MibAttribute;
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetConfirm.MibAttributeValue;
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetRequest.MibAttributeValue;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetConfirm.MibAttributeValue;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetNextRequest.MibAttribute;
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetNextRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetNextConfirm.MibAttributeValue;
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetNextConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmePowermgtRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmePowermgtRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmePowermgtConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmePowermgtConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeScanRequest.ChannelList;
-            aDataRef[numRefs++] = &aSignal->u.MlmeScanRequest.InformationElements;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeScanConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeScanConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeMeasureRequest.MeasurementRequestSet;
-            aDataRef[numRefs++] = &aSignal->u.MlmeMeasureRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeMeasureConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeMeasureConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeMeasureIndication.MeasurementReportSet;
-            aDataRef[numRefs++] = &aSignal->u.MlmeMeasureIndication.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysRequest.Key;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetkeysConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDeletekeysConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanLossIndication.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanLossIndication.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECTED_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeConnectedIndication.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeConnectedIndication.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeScanCancelRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeScanCancelRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeHlSyncCancelConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddPeriodicConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelPeriodicConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanRequest.ChannelList;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanRequest.InformationElements;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddAutonomousScanConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelAutonomousScanConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetPacketFilterRequest.InformationElements;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetPacketFilterRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetPacketFilterConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetPacketFilterConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeStopMeasureRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeStopMeasureRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeStopMeasureConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeStopMeasureConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmePauseAutonomousScanConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanDoneIndication.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAutonomousScanDoneIndication.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetRequest.MibAttribute;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTriggeredGetConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelTriggeredGetConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeTriggeredGetIndication.MibAttributeValue;
-            aDataRef[numRefs++] = &aSignal->u.MlmeTriggeredGetIndication.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddBlackoutRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddBlackoutRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddBlackoutConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddBlackoutConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeBlackoutEndedIndication.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeBlackoutEndedIndication.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelBlackoutRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelBlackoutRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelBlackoutConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelBlackoutConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddRxTriggerRequest.InformationElements;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddRxTriggerRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddRxTriggerConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddRxTriggerConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelRxTriggerRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelRxTriggerRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelRxTriggerConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelRxTriggerConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeConnectStatusRequest.InformationElements;
-            aDataRef[numRefs++] = &aSignal->u.MlmeConnectStatusRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeConnectStatusConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeConnectStatusConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeModifyBssParameterRequest.Data;
-            aDataRef[numRefs++] = &aSignal->u.MlmeModifyBssParameterRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeModifyBssParameterConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeModifyBssParameterConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTemplateRequest.Data1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTemplateRequest.Data2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTemplateConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTemplateConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeConfigQueueRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeConfigQueueRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeConfigQueueConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeConfigQueueConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTspecRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTspecRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTspecConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddTspecConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelTspecRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelTspecRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelTspecConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeDelTspecConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeStartAggregationRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeStartAggregationRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeStartAggregationConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeStartAggregationConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeBlockackErrorIndication.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeBlockackErrorIndication.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeStopAggregationRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeStopAggregationRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeStopAggregationConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeStopAggregationConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSmStartRequest.Beacon;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSmStartRequest.BssParameters;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSmStartConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSmStartConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeLeaveRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeLeaveRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeLeaveConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeLeaveConfirm.Dummydataref2;
-            break;
-#endif
-        case CSR_MLME_SET_TIM_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetTimRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetTimRequest.Dummydataref2;
-            break;
-        case CSR_MLME_SET_TIM_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetTimConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetTimConfirm.Dummydataref2;
-            break;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetKeySequenceRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetKeySequenceRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetKeySequenceConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeGetKeySequenceConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetChannelRequest.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetChannelRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetChannelConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeSetChannelConfirm.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddMulticastAddressRequest.Data;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddMulticastAddressRequest.Dummydataref2;
-            break;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddMulticastAddressConfirm.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.MlmeAddMulticastAddressConfirm.Dummydataref2;
-            break;
-#endif
-        case CSR_DEBUG_STRING_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.DebugStringIndication.DebugMessage;
-            aDataRef[numRefs++] = &aSignal->u.DebugStringIndication.Dummydataref2;
-            break;
-        case CSR_DEBUG_WORD16_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.DebugWord16Indication.Dummydataref1;
-            aDataRef[numRefs++] = &aSignal->u.DebugWord16Indication.Dummydataref2;
-            break;
-        case CSR_DEBUG_GENERIC_REQUEST_ID:
-            aDataRef[numRefs++] = &aSignal->u.DebugGenericRequest.DebugVariable;
-            aDataRef[numRefs++] = &aSignal->u.DebugGenericRequest.Dummydataref2;
-            break;
-        case CSR_DEBUG_GENERIC_CONFIRM_ID:
-            aDataRef[numRefs++] = &aSignal->u.DebugGenericConfirm.DebugVariable;
-            aDataRef[numRefs++] = &aSignal->u.DebugGenericConfirm.Dummydataref2;
-            break;
-        case CSR_DEBUG_GENERIC_INDICATION_ID:
-            aDataRef[numRefs++] = &aSignal->u.DebugGenericIndication.DebugVariable;
-            aDataRef[numRefs++] = &aSignal->u.DebugGenericIndication.Dummydataref2;
-            break;
-        default:
-            return 0;
-    }
-    return numRefs;
-}
-
-
-u32 SigGetFilterPos(u16 aSigID)
-{
-    switch (aSigID)
-    {
-        case CSR_MA_PACKET_REQUEST_ID:
-            return 0x00000001;
-        case CSR_MA_PACKET_CONFIRM_ID:
-            return 0x00000002;
-        case CSR_MA_PACKET_INDICATION_ID:
-            return 0x00000004;
-        case CSR_MA_PACKET_CANCEL_REQUEST_ID:
-            return 0x00000008;
-        case CSR_MA_VIF_AVAILABILITY_RESPONSE_ID:
-            return 0x00000010;
-        case CSR_MA_VIF_AVAILABILITY_INDICATION_ID:
-            return 0x00000020;
-        case CSR_MA_PACKET_ERROR_INDICATION_ID:
-            return 0x00000040;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_REQUEST_ID:
-            return 0x00000080;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_RESET_CONFIRM_ID:
-            return 0x00000100;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_REQUEST_ID:
-            return 0x00000200;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_CONFIRM_ID:
-            return 0x00000400;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_REQUEST_ID:
-            return 0x00000800;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CONFIRM_ID:
-            return 0x00001000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_REQUEST_ID:
-            return 0x00002000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_NEXT_CONFIRM_ID:
-            return 0x00004000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_REQUEST_ID:
-            return 0x00008000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_POWERMGT_CONFIRM_ID:
-            return 0x00010001;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_REQUEST_ID:
-            return 0x00010002;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CONFIRM_ID:
-            return 0x00010004;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_REQUEST_ID:
-            return 0x00010008;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CONFIRM_ID:
-            return 0x00010010;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_REQUEST_ID:
-            return 0x00010020;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_CONFIRM_ID:
-            return 0x00010040;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MEASURE_INDICATION_ID:
-            return 0x00010080;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_REQUEST_ID:
-            return 0x00010100;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SETKEYS_CONFIRM_ID:
-            return 0x00010200;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_REQUEST_ID:
-            return 0x00010400;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DELETEKEYS_CONFIRM_ID:
-            return 0x00010800;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID:
-            return 0x00011000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECTED_INDICATION_ID:
-            return 0x00012000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SCAN_CANCEL_REQUEST_ID:
-            return 0x00014000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID:
-            return 0x00018000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
-            return 0x00020001;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_REQUEST_ID:
-            return 0x00020002;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
-            return 0x00020004;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_REQUEST_ID:
-            return 0x00020008;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
-            return 0x00020010;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID:
-            return 0x00020020;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
-            return 0x00020040;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID:
-            return 0x00020080;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
-            return 0x00020100;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_REQUEST_ID:
-            return 0x00020200;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID:
-            return 0x00020400;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_REQUEST_ID:
-            return 0x00020800;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_MEASURE_CONFIRM_ID:
-            return 0x00021000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID:
-            return 0x00022000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
-            return 0x00024000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID:
-            return 0x00028000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID:
-            return 0x00030001;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
-            return 0x00030002;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID:
-            return 0x00030004;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
-            return 0x00030008;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_TRIGGERED_GET_INDICATION_ID:
-            return 0x00030010;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_REQUEST_ID:
-            return 0x00030020;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID:
-            return 0x00030040;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLACKOUT_ENDED_INDICATION_ID:
-            return 0x00030080;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_REQUEST_ID:
-            return 0x00030100;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID:
-            return 0x00030200;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID:
-            return 0x00030400;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID:
-            return 0x00030800;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID:
-            return 0x00031000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID:
-            return 0x00032000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_REQUEST_ID:
-            return 0x00034000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONNECT_STATUS_CONFIRM_ID:
-            return 0x00038000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID:
-            return 0x00040001;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID:
-            return 0x00040002;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_REQUEST_ID:
-            return 0x00040004;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID:
-            return 0x00040008;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_REQUEST_ID:
-            return 0x00040010;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID:
-            return 0x00040020;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_REQUEST_ID:
-            return 0x00040040;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_TSPEC_CONFIRM_ID:
-            return 0x00040080;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_REQUEST_ID:
-            return 0x00040100;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_DEL_TSPEC_CONFIRM_ID:
-            return 0x00040200;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_REQUEST_ID:
-            return 0x00040400;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_START_AGGREGATION_CONFIRM_ID:
-            return 0x00040800;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_BLOCKACK_ERROR_INDICATION_ID:
-            return 0x00041000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_REQUEST_ID:
-            return 0x00042000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID:
-            return 0x00044000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_REQUEST_ID:
-            return 0x00048000;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SM_START_CONFIRM_ID:
-            return 0x00050001;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_REQUEST_ID:
-            return 0x00050002;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_LEAVE_CONFIRM_ID:
-            return 0x00050004;
-#endif
-        case CSR_MLME_SET_TIM_REQUEST_ID:
-            return 0x00050008;
-        case CSR_MLME_SET_TIM_CONFIRM_ID:
-            return 0x00050010;
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID:
-            return 0x00050020;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID:
-            return 0x00050040;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_REQUEST_ID:
-            return 0x00050080;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_SET_CHANNEL_CONFIRM_ID:
-            return 0x00050100;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID:
-            return 0x00050200;
-#endif
-#ifdef CSR_WIFI_HIP_FULL_SIGNAL_SET
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID:
-            return 0x00050400;
-#endif
-        case CSR_DEBUG_STRING_INDICATION_ID:
-            return 0x00050800;
-        case CSR_DEBUG_WORD16_INDICATION_ID:
-            return 0x00051000;
-        case CSR_DEBUG_GENERIC_REQUEST_ID:
-            return 0x00052000;
-        case CSR_DEBUG_GENERIC_CONFIRM_ID:
-            return 0x00054000;
-        case CSR_DEBUG_GENERIC_INDICATION_ID:
-            return 0x00058000;
-        default:
-            break;
-    }
-    return 0xffffffff;
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_signals.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_signals.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_signals.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_signals.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,128 +0,0 @@
-/*****************************************************************************
-
-	(c) Cambridge Silicon Radio Limited 2011
-	All rights reserved and confidential information of CSR
-
-	Refer to LICENSE.txt included with this source for details
-	on the license terms.
-
-*****************************************************************************/
-
-/*
- *****************************************************************************
- *
- * FILE: csr_wifi_hip_signals.h
- *
- * PURPOSE:
- *      Header file wrapping the auto-generated code in csr_wifi_hip_sigs.h
- *      and csr_wifi_hip_signals.c -
- *      csr_wifi_hip_sigs.h provides structures defining UniFi signals and
- *      csr_wifi_hip_signals.c provides SigGetSize() and SigGetDataRefs().
- *
- *****************************************************************************
- */
-#ifndef __CSR_WIFI_HIP_SIGNALS_H__
-#define __CSR_WIFI_HIP_SIGNALS_H__
-
-#include <linux/types.h>
-#include "csr_wifi_hip_sigs.h"
-
-
-/****************************************************************************/
-/* INFORMATION ELEMENTS */
-/****************************************************************************/
-
-/* Information Element ID's - shouldn't be in here, but nowhere better yet */
-#define IE_SSID_ID                       0
-#define IE_SUPPORTED_RATES_ID            1
-#define IE_FH_PARAM_SET_ID               2
-#define IE_DS_PARAM_SET_ID               3
-#define IE_CF_PARAM_SET_ID               4
-#define IE_TIM_ID                        5
-#define IE_IBSS_PARAM_SET_ID             6
-#define IE_COUNTRY_ID                    7
-#define IE_HOPPING_PATTERN_PARAMS_ID     8
-#define IE_HOPPING_PATTERN_TABLE_ID      9
-#define IE_REQUEST_ID                    10
-#define IE_QBSS_LOAD_ID                  11
-#define IE_EDCA_PARAM_SET_ID             12
-#define IE_TRAFFIC_SPEC_ID               13
-#define IE_TRAFFIC_CLASS_ID              14
-#define IE_SCHEDULE_ID                   15
-#define IE_CHALLENGE_TEXT_ID             16
-#define IE_POWER_CONSTRAINT_ID           32
-#define IE_POWER_CAPABILITY_ID           33
-#define IE_TPC_REQUEST_ID                34
-#define IE_TPC_REPORT_ID                 35
-#define IE_SUPPORTED_CHANNELS_ID         36
-#define IE_CHANNEL_SWITCH_ANNOUNCE_ID    37
-#define IE_MEASUREMENT_REQUEST_ID        38
-#define IE_MEASUREMENT_REPORT_ID         39
-#define IE_QUIET_ID                      40
-#define IE_IBSS_DFS_ID                   41
-#define IE_ERP_INFO_ID                   42
-#define IE_TS_DELAY_ID                   43
-#define IE_TCLAS_PROCESSING_ID           44
-#define IE_QOS_CAPABILITY_ID             46
-#define IE_RSN_ID                        48
-#define IE_EXTENDED_SUPPORTED_RATES_ID   50
-#define IE_AP_CHANNEL_REPORT_ID          52
-#define IE_RCPI_ID                       53
-#define IE_WPA_ID                       221
-
-
-/* The maximum number of data references in a signal structure */
-#define UNIFI_MAX_DATA_REFERENCES 2
-
-/* The space to allow for a wire-format signal structure */
-#define UNIFI_PACKED_SIGBUF_SIZE   64
-
-
-/******************************************************************************/
-/* SIGNAL PARAMETER VALUES */
-/******************************************************************************/
-
-/* ifIndex */
-#define UNIFI_IF_2G4 1
-#define UNIFI_IF_5G  2
-
-/* SendProcessId */
-#define HOST_PROC_ID 0xc000
-
-#define SIG_CAP_ESS             0x0001
-#define SIG_CAP_IBSS            0x0002
-#define SIG_CAP_CF_POLLABLE     0x0004
-#define SIG_CAP_CF_POLL_REQUEST 0x0008
-#define SIG_CAP_PRIVACY         0x0010
-#define SIG_CAP_SHORT_PREAMBLE  0x0020
-#define SIG_CAP_DSSSOFDM        0x2000
-
-/******************************************************************************/
-/* FUNCTION DECLARATIONS */
-/******************************************************************************/
-
-/******************************************************************************
- * SigGetNumDataRefs - Retrieve pointers to data-refs from a signal.
- *
- * PARAMETERS:
- *   aSignal  - Pointer to signal to retrieve the data refs of.
- *   aDataRef - Address of a pointer to the structure that the data refs
- *              pointers will be stored.
- *
- * RETURNS:
- *   The number of data-refs in the signal.
- */
-s32 SigGetDataRefs(CSR_SIGNAL *aSignal, CSR_DATAREF **aDataRef);
-
-/******************************************************************************
- * SigGetSize - Retrieve the size (in bytes) of a given signal.
- *
- * PARAMETERS:
- *   aSignal  - Pointer to signal to retrieve size of.
- *
- * RETURNS:
- *   The size (in bytes) of the given signal.
- */
-s32 SigGetSize(const CSR_SIGNAL *aSignal);
-
-#endif /* __CSR_WIFI_HIP_SIGNALS_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_sigs.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_sigs.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_sigs.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_sigs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1417 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-
-/* Generated by hip_dd_l_h_gen.pl */
-
-#ifndef CSR_WIFI_HIP_SIGS_H
-#define CSR_WIFI_HIP_SIGS_H
-
-typedef s16 csr_place_holding_type;
-
-typedef u16 CSR_ASSOCIATION_ID;
-
-typedef u16 CSR_AUTONOMOUS_SCAN_ID;
-
-typedef u16 CSR_BEACON_PERIODS;
-
-typedef u16 CSR_BLACKOUT_ID;
-
-typedef enum CSR_BLACKOUT_SOURCE
-{
-    CSR_DOT11_LOCAL                               = 0x0000,
-    CSR_DOT11_REMOTE                              = 0x0001,
-    CSR_OTHER_RADIO                               = 0x0002,
-    CSR_NOT_LINKED                                = 0x0004
-} CSR_BLACKOUT_SOURCE;
-
-typedef enum CSR_BLACKOUT_TYPE
-{
-    CSR_LOCAL_DEVICE_ONLY                         = 0x0001,
-    CSR_SPECIFIED_PEER                            = 0x0002,
-    CSR_CURRENT_CHANNEL                           = 0x0004,
-    CSR_P2P                                       = 0x0008
-} CSR_BLACKOUT_TYPE;
-
-typedef enum CSR_BOOT_LOADER_OPERATION
-{
-    CSR_BOOT_LOADER_IDLE                          = 0x00,
-    CSR_BOOT_LOADER_RESTART                       = 0x01,
-    CSR_BOOT_LOADER_PATCH                         = 0x02,
-    CSR_BOOT_LOADER_IMAGE_0                       = 0x10,
-    CSR_BOOT_LOADER_IMAGE_1                       = 0x11,
-    CSR_BOOT_LOADER_IMAGE_2                       = 0x12,
-    CSR_BOOT_LOADER_IMAGE_3                       = 0x13
-} CSR_BOOT_LOADER_OPERATION;
-
-typedef u16 CSR_CAPABILITY_INFORMATION;
-
-typedef u16 CSR_CHANNEL_STARTING_FACTOR;
-
-typedef u32 CSR_CIPHER_SUITE_SELECTOR;
-
-typedef u32 CSR_CLIENT_TAG;
-
-typedef enum CSR_CONNECTION_STATUS
-{
-    CSR_DISCONNECTED                              = 0x0000,
-    CSR_CONNECTED_AWAKE                           = 0x0001
-} CSR_CONNECTION_STATUS;
-
-typedef s16 CSR_DECIBELS;
-
-typedef enum CSR_DIRECTION
-{
-    CSR_TRANSMIT                                  = 0x0000,
-    CSR_RECEIVE                                   = 0x0001,
-    CSR_BIDIRECTIONAL                             = 0x0003
-} CSR_DIRECTION;
-
-typedef enum CSR_FRAME_TYPE
-{
-    CSR_RESERVED                                  = 0x0000,
-    CSR_BEACON                                    = 0x0001,
-    CSR_PROBE_RESPONSE                            = 0x0002,
-    CSR_BEACON_AND_PROBE_RESPONSE                 = 0x0003,
-    CSR_PROBE_REQUEST                             = 0x0004
-} CSR_FRAME_TYPE;
-
-typedef u32 CSR_IPV4_ADDRESS;
-
-typedef enum CSR_IFINTERFACE
-{
-    CSR_INDEX_2G4                                 = 0x0001,
-    CSR_INDEX_5G                                  = 0x0002
-} CSR_IFINTERFACE;
-
-typedef enum CSR_KEY_TYPE
-{
-    CSR_GROUP                                     = 0x0000,
-    CSR_PAIRWISE                                  = 0x0001,
-    CSR_PEER_KEY                                  = 0x0002,
-    CSR_IGTK                                      = 0x0003
-} CSR_KEY_TYPE;
-
-typedef enum CSR_LOADER_OPERATION
-{
-    CSR_LOADER_IDLE                               = 0x0000,
-    CSR_LOADER_COPY                               = 0x0001
-} CSR_LOADER_OPERATION;
-
-typedef struct CSR_MAC_ADDRESS
-{
-    u8 x[6];
-} CSR_MACADDRESS;
-
-typedef enum CSR_MIB_STATUS
-{
-    CSR_MIB_SUCCESSFUL                            = 0x0000,
-    CSR_MIB_INVALID_PARAMETERS                    = 0x0001,
-    CSR_MIB_WRITE_ONLY                            = 0x0002,
-    CSR_MIB_READ_ONLY                             = 0x0003
-} CSR_MIB_STATUS;
-
-typedef enum CSR_MEMORY_SPACE
-{
-    CSR_NONE                                      = 0x00,
-    CSR_SHARED_DATA_MEMORY                        = 0x01,
-    CSR_EXTERNAL_FLASH_MEMORY                     = 0x02,
-    CSR_EXTERNAL_SRAM                             = 0x03,
-    CSR_REGISTERS                                 = 0x04,
-    CSR_PHY_PROCESSOR_DATA_MEMORY                 = 0x10,
-    CSR_PHY_PROCESSOR_PROGRAM_MEMORY              = 0x11,
-    CSR_PHY_PROCESSOR_ROM                         = 0x12,
-    CSR_MAC_PROCESSOR_DATA_MEMORY                 = 0x20,
-    CSR_MAC_PROCESSOR_PROGRAM_MEMORY              = 0x21,
-    CSR_MAC_PROCESSOR_ROM                         = 0x22,
-    CSR_BT_PROCESSOR_DATA_MEMORY                  = 0x30,
-    CSR_BT_PROCESSOR_PROGRAM_MEMORY               = 0x31,
-    CSR_BT_PROCESSOR_ROM                          = 0x32
-} CSR_MEMORY_SPACE;
-
-typedef u16 CSR_MICROSECONDS16;
-
-typedef u32 CSR_MICROSECONDS32;
-
-typedef u16 CSR_NATURAL16;
-
-typedef enum CSR_PS_SCHEME
-{
-    CSR_LEGACY_PS                                 = 0x0001,
-    CSR_U_APSD                                    = 0x0002,
-    CSR_S_APSD                                    = 0x0004
-} CSR_PS_SCHEME;
-
-typedef enum CSR_PACKET_FILTER_MODE
-{
-    CSR_PFM_OPT_OUT                               = 0x0000,
-    CSR_PFM_OPT_IN                                = 0x0003
-} CSR_PACKET_FILTER_MODE;
-
-typedef u16 CSR_PERIODIC_ID;
-
-typedef enum CSR_PERIODIC_SCHEDULING_MODE
-{
-    CSR_PSM_PERIODIC_SCHEDULE_PS_POLL             = 0x0001,
-    CSR_PSM_PERIODIC_SCHEDULE_PM_BIT              = 0x0002,
-    CSR_PSM_PERIODIC_SCHEDULE_UAPSD               = 0x0004,
-    CSR_PSM_PERIODIC_SCHEDULE_SAPSD               = 0x0008
-} CSR_PERIODIC_SCHEDULING_MODE;
-
-typedef enum CSR_POWER_MANAGEMENT_MODE
-{
-    CSR_PMM_ACTIVE_MODE                           = 0x0000,
-    CSR_PMM_POWER_SAVE                            = 0x0001,
-    CSR_PMM_FAST_POWER_SAVE                       = 0x0002
-} CSR_POWER_MANAGEMENT_MODE;
-
-typedef enum CSR_PRIORITY
-{
-    CSR_QOS_UP0                                   = 0x0000,
-    CSR_QOS_UP1                                   = 0x0001,
-    CSR_QOS_UP2                                   = 0x0002,
-    CSR_QOS_UP3                                   = 0x0003,
-    CSR_QOS_UP4                                   = 0x0004,
-    CSR_QOS_UP5                                   = 0x0005,
-    CSR_QOS_UP6                                   = 0x0006,
-    CSR_QOS_UP7                                   = 0x0007,
-    CSR_CONTENTION                                = 0x8000,
-    CSR_MANAGEMENT                                = 0x8010
-} CSR_PRIORITY;
-
-typedef enum CSR_REASON_CODE
-{
-    CSR_UNSPECIFIED_REASON                        = 0x0001,
-    CSR_INVALID_INFORMATION_ELEMENT               = 0x000d,
-    CSR_QOS_UNSPECIFIED_REASON                    = 0x0020,
-    CSR_QOS_EXCESSIVE_NOT_ACK                     = 0x0022,
-    CSR_QOS_TXOP_LIMIT_EXCEEDED                   = 0x0023,
-    CSR_QSTA_LEAVING                              = 0x0024,
-    CSR_UNKNOWN_BA                                = 0x0026,
-    CSR_UNKNOWN_TS                                = 0x0026,
-    CSR_TIMEOUT                                   = 0x0027
-} CSR_REASON_CODE;
-
-typedef enum CSR_RECEPTION_STATUS
-{
-    CSR_RX_SUCCESS                                = 0x0000,
-    CSR_RX_FAILURE_UNSPECIFIED                    = 0x0001,
-    CSR_MICHAEL_MIC_ERROR                         = 0x0002,
-    CSR_DECRYPTION_ERROR                          = 0x0003,
-    CSR_NO_TEMPORAL_KEY_AVAILABLE                 = 0x0004,
-    CSR_UNSUPPORTED_MODULATION                    = 0x0011,
-    CSR_BAD_FCS                                   = 0x0012,
-    CSR_BAD_SIGNAL                                = 0x0013
-} CSR_RECEPTION_STATUS;
-
-typedef enum CSR_RESULT_CODE
-{
-    CSR_RC_SUCCESS                                = 0x0000,
-    CSR_RC_UNSPECIFIED_FAILURE                    = 0x0001,
-    CSR_RC_REFUSED                                = 0x0003,
-    CSR_RC_INVALID_PARAMETERS                     = 0x0026,
-    CSR_RC_REJECTED_INVALID_IE                    = 0x0028,
-    CSR_RC_REJECTED_INVALID_GROUP_CIPHER          = 0x0029,
-    CSR_RC_REJECTED_INVALID_PAIRWISE_CIPHER       = 0x002a,
-    CSR_RC_TIMEOUT                                = 0x8000,
-    CSR_RC_TOO_MANY_SIMULTANEOUS_REQUESTS         = 0x8001,
-    CSR_RC_BSS_ALREADY_STARTED_OR_JOINED          = 0x8002,
-    CSR_RC_NOT_SUPPORTED                          = 0x8003,
-    CSR_RC_TRANSMISSION_FAILURE                   = 0x8004,
-    CSR_RC_RESET_REQUIRED_BEFORE_START            = 0x8006,
-    CSR_RC_INSUFFICIENT_RESOURCE                  = 0x8007,
-    CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES = 0x8008,
-    CSR_RC_INVALID_UNICAST_CIPHER                 = 0xf02f,
-    CSR_RC_INVALID_MULTICAST_CIPHER               = 0xf030
-} CSR_RESULT_CODE;
-
-typedef enum CSR_SCAN_TYPE
-{
-    CSR_SC_ACTIVE_SCAN                            = 0x0000,
-    CSR_SC_PASSIVE_SCAN                           = 0x0001
-} CSR_SCAN_TYPE;
-
-typedef enum CSR_SIGNAL_ID
-{
-    CSR_MA_PACKET_REQUEST_ID                      = 0x0110,
-    CSR_MA_PACKET_CONFIRM_ID                      = 0x0111,
-    CSR_MA_PACKET_INDICATION_ID                   = 0x0113,
-    CSR_MA_PACKET_CANCEL_REQUEST_ID               = 0x0114,
-    CSR_MA_VIF_AVAILABILITY_RESPONSE_ID           = 0x0116,
-    CSR_MA_VIF_AVAILABILITY_INDICATION_ID         = 0x0117,
-    CSR_MA_PACKET_ERROR_INDICATION_ID             = 0x011b,
-    CSR_MLME_RESET_REQUEST_ID                     = 0x0200,
-    CSR_MLME_RESET_CONFIRM_ID                     = 0x0201,
-    CSR_MLME_GET_REQUEST_ID                       = 0x0204,
-    CSR_MLME_GET_CONFIRM_ID                       = 0x0205,
-    CSR_MLME_SET_REQUEST_ID                       = 0x0208,
-    CSR_MLME_SET_CONFIRM_ID                       = 0x0209,
-    CSR_MLME_GET_NEXT_REQUEST_ID                  = 0x020c,
-    CSR_MLME_GET_NEXT_CONFIRM_ID                  = 0x020d,
-    CSR_MLME_POWERMGT_REQUEST_ID                  = 0x0210,
-    CSR_MLME_POWERMGT_CONFIRM_ID                  = 0x0211,
-    CSR_MLME_SCAN_REQUEST_ID                      = 0x0214,
-    CSR_MLME_SCAN_CONFIRM_ID                      = 0x0215,
-    CSR_MLME_HL_SYNC_REQUEST_ID                   = 0x0244,
-    CSR_MLME_HL_SYNC_CONFIRM_ID                   = 0x0245,
-    CSR_MLME_MEASURE_REQUEST_ID                   = 0x0258,
-    CSR_MLME_MEASURE_CONFIRM_ID                   = 0x0259,
-    CSR_MLME_MEASURE_INDICATION_ID                = 0x025b,
-    CSR_MLME_SETKEYS_REQUEST_ID                   = 0x0268,
-    CSR_MLME_SETKEYS_CONFIRM_ID                   = 0x0269,
-    CSR_MLME_DELETEKEYS_REQUEST_ID                = 0x026c,
-    CSR_MLME_DELETEKEYS_CONFIRM_ID                = 0x026d,
-    CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION_ID   = 0x0287,
-    CSR_MLME_CONNECTED_INDICATION_ID              = 0x028b,
-    CSR_MLME_SCAN_CANCEL_REQUEST_ID               = 0x028c,
-    CSR_MLME_HL_SYNC_CANCEL_REQUEST_ID            = 0x0298,
-    CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID            = 0x0299,
-    CSR_MLME_ADD_PERIODIC_REQUEST_ID              = 0x02a0,
-    CSR_MLME_ADD_PERIODIC_CONFIRM_ID              = 0x02a1,
-    CSR_MLME_DEL_PERIODIC_REQUEST_ID              = 0x02a4,
-    CSR_MLME_DEL_PERIODIC_CONFIRM_ID              = 0x02a5,
-    CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST_ID       = 0x02a8,
-    CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID       = 0x02a9,
-    CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST_ID       = 0x02ac,
-    CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID       = 0x02ad,
-    CSR_MLME_SET_PACKET_FILTER_REQUEST_ID         = 0x02b8,
-    CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID         = 0x02b9,
-    CSR_MLME_STOP_MEASURE_REQUEST_ID              = 0x02bc,
-    CSR_MLME_STOP_MEASURE_CONFIRM_ID              = 0x02bd,
-    CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST_ID     = 0x02cc,
-    CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID     = 0x02cd,
-    CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION_ID   = 0x02db,
-    CSR_MLME_ADD_TRIGGERED_GET_REQUEST_ID         = 0x02dc,
-    CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID         = 0x02dd,
-    CSR_MLME_DEL_TRIGGERED_GET_REQUEST_ID         = 0x02e0,
-    CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID         = 0x02e1,
-    CSR_MLME_TRIGGERED_GET_INDICATION_ID          = 0x02e7,
-    CSR_MLME_ADD_BLACKOUT_REQUEST_ID              = 0x02f8,
-    CSR_MLME_ADD_BLACKOUT_CONFIRM_ID              = 0x02f9,
-    CSR_MLME_BLACKOUT_ENDED_INDICATION_ID         = 0x02fb,
-    CSR_MLME_DEL_BLACKOUT_REQUEST_ID              = 0x02fc,
-    CSR_MLME_DEL_BLACKOUT_CONFIRM_ID              = 0x02fd,
-    CSR_MLME_ADD_RX_TRIGGER_REQUEST_ID            = 0x0304,
-    CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID            = 0x0305,
-    CSR_MLME_DEL_RX_TRIGGER_REQUEST_ID            = 0x0308,
-    CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID            = 0x0309,
-    CSR_MLME_CONNECT_STATUS_REQUEST_ID            = 0x0310,
-    CSR_MLME_CONNECT_STATUS_CONFIRM_ID            = 0x0311,
-    CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST_ID      = 0x0314,
-    CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID      = 0x0315,
-    CSR_MLME_ADD_TEMPLATE_REQUEST_ID              = 0x0318,
-    CSR_MLME_ADD_TEMPLATE_CONFIRM_ID              = 0x0319,
-    CSR_MLME_CONFIG_QUEUE_REQUEST_ID              = 0x031c,
-    CSR_MLME_CONFIG_QUEUE_CONFIRM_ID              = 0x031d,
-    CSR_MLME_ADD_TSPEC_REQUEST_ID                 = 0x0320,
-    CSR_MLME_ADD_TSPEC_CONFIRM_ID                 = 0x0321,
-    CSR_MLME_DEL_TSPEC_REQUEST_ID                 = 0x0324,
-    CSR_MLME_DEL_TSPEC_CONFIRM_ID                 = 0x0325,
-    CSR_MLME_START_AGGREGATION_REQUEST_ID         = 0x0328,
-    CSR_MLME_START_AGGREGATION_CONFIRM_ID         = 0x0329,
-    CSR_MLME_BLOCKACK_ERROR_INDICATION_ID         = 0x032b,
-    CSR_MLME_STOP_AGGREGATION_REQUEST_ID          = 0x032c,
-    CSR_MLME_STOP_AGGREGATION_CONFIRM_ID          = 0x032d,
-    CSR_MLME_SM_START_REQUEST_ID                  = 0x0334,
-    CSR_MLME_SM_START_CONFIRM_ID                  = 0x0335,
-    CSR_MLME_LEAVE_REQUEST_ID                     = 0x0338,
-    CSR_MLME_LEAVE_CONFIRM_ID                     = 0x0339,
-    CSR_MLME_SET_TIM_REQUEST_ID                   = 0x033c,
-    CSR_MLME_SET_TIM_CONFIRM_ID                   = 0x033d,
-    CSR_MLME_GET_KEY_SEQUENCE_REQUEST_ID          = 0x0340,
-    CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID          = 0x0341,
-    CSR_MLME_SET_CHANNEL_REQUEST_ID               = 0x034c,
-    CSR_MLME_SET_CHANNEL_CONFIRM_ID               = 0x034d,
-    CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST_ID     = 0x040c,
-    CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID     = 0x040d,
-    CSR_DEBUG_STRING_INDICATION_ID                = 0x0803,
-    CSR_DEBUG_WORD16_INDICATION_ID                = 0x0807,
-    CSR_DEBUG_GENERIC_REQUEST_ID                  = 0x0808,
-    CSR_DEBUG_GENERIC_CONFIRM_ID                  = 0x0809,
-    CSR_DEBUG_GENERIC_INDICATION_ID               = 0x080b
-} CSR_SIGNAL_ID;
-
-typedef u16 CSR_SIMPLE_POINTER;
-
-typedef u16 CSR_STARTING_SEQUENCE_NUMBER;
-
-typedef enum CSR_SYMBOL_ID
-{
-    CSR_SLT_END                                   = 0x0000,
-    CSR_SLT_PCI_SLOT_CONFIG                       = 0x0001,
-    CSR_SLT_SDIO_SLOT_CONFIG                      = 0x0002,
-    CSR_SLT_BUILD_ID_NUMBER                       = 0x0003,
-    CSR_SLT_BUILD_ID_STRING                       = 0x0004,
-    CSR_SLT_PERSISTENT_STORE_DB                   = 0x0005,
-    CSR_SLT_RESET_VECTOR_PHY                      = 0x0006,
-    CSR_SLT_RESET_VECTOR_MAC                      = 0x0007,
-    CSR_SLT_SDIO_LOADER_CONTROL                   = 0x0008,
-    CSR_SLT_TEST_CMD                              = 0x0009,
-    CSR_SLT_TEST_ALIVE_COUNTER                    = 0x000a,
-    CSR_SLT_TEST_PARAMETERS                       = 0x000b,
-    CSR_SLT_TEST_RESULTS                          = 0x000c,
-    CSR_SLT_TEST_VERSION                          = 0x000d,
-    CSR_SLT_MIB_PSID_RANGES                       = 0x000e,
-    CSR_SLT_KIP_TABLE                             = 0x000f,
-    CSR_SLT_PANIC_DATA_PHY                        = 0x0010,
-    CSR_SLT_PANIC_DATA_MAC                        = 0x0011,
-    CSR_SLT_BOOT_LOADER_CONTROL                   = 0x0012,
-    CSR_SLT_SOFT_MAC                              = 0x0013
-} CSR_SYMBOL_ID;
-
-typedef struct CSR_TSF_TIME
-{
-    u8 x[8];
-} CSR_TSF_TIME;
-
-typedef u16 CSR_TIME_UNITS;
-
-typedef enum CSR_TRANSMISSION_CONTROL
-{
-    CSR_TRIGGERED                                 = 0x0001,
-    CSR_END_OF_SERVICE                            = 0x0002,
-    CSR_NO_CONFIRM_REQUIRED                       = 0x0004,
-    CSR_ALLOW_BA                                  = 0x0008
-} CSR_TRANSMISSION_CONTROL;
-
-typedef enum CSR_TRANSMISSION_STATUS
-{
-    CSR_TX_SUCCESSFUL                             = 0x0000,
-    CSR_TX_RETRY_LIMIT                            = 0x0001,
-    CSR_TX_LIFETIME                               = 0x0002,
-    CSR_TX_NO_BSS                                 = 0x0003,
-    CSR_TX_EXCESSIVE_DATA_LENGTH                  = 0x0004,
-    CSR_TX_UNSUPPORTED_PRIORITY                   = 0x0006,
-    CSR_TX_UNAVAILABLE_PRIORITY                   = 0x0007,
-    CSR_TX_UNAVAILABLE_KEY_MAPPING                = 0x000a,
-    CSR_TX_EDCA_TIMEOUT                           = 0x000b,
-    CSR_TX_BLOCK_ACK_TIMEOUT                      = 0x000c,
-    CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED      = 0x000d,
-    CSR_TX_REJECTED_PEER_STATION_SLEEPING         = 0x000e,
-    CSR_TX_REJECTED_DTIM_ENDED                    = 0x000f,
-    CSR_TX_REJECTED_DTIM_STARTED                  = 0x0010
-} CSR_TRANSMISSION_STATUS;
-
-typedef u16 CSR_TRIGGER_ID;
-
-typedef u16 CSR_TRIGGERED_ID;
-
-typedef enum CSR_HIP_VERSIONS
-{
-    CSR_HIP_ENG_VERSION                           = 0x0001,
-    CSR_HIP_VERSION                               = 0x0900
-} CSR_HIP_VERSIONS;
-
-typedef u16 CSR_BUFFER_HANDLE;
-
-typedef u16 CSR_CHANNEL_NUMBER;
-
-typedef struct CSR_DATA_REFERENCE
-{
-    u16 SlotNumber;
-    u16 DataLength;
-} CSR_DATAREF;
-
-typedef u16 CSR_DIALOG_TOKEN;
-
-typedef struct CSR_GENERIC_POINTER
-{
-    u32        MemoryOffset;
-    CSR_MEMORY_SPACE MemorySpace;
-} CSR_GENERIC_POINTER;
-
-typedef struct CSR_MLME_CONFIG_QUEUE_CONFIRM
-{
-    CSR_DATAREF     Dummydataref1;
-    CSR_DATAREF     Dummydataref2;
-    CSR_RESULT_CODE ResultCode;
-} CSR_MLME_CONFIG_QUEUE_CONFIRM;
-
-typedef struct CSR_MLME_CONFIG_QUEUE_REQUEST
-{
-    CSR_DATAREF   Dummydataref1;
-    CSR_DATAREF   Dummydataref2;
-    CSR_NATURAL16 QueueIndex;
-    CSR_NATURAL16 Aifs;
-    CSR_NATURAL16 Cwmin;
-    CSR_NATURAL16 Cwmax;
-    CSR_NATURAL16 TxopLimit;
-} CSR_MLME_CONFIG_QUEUE_REQUEST;
-
-typedef struct CSR_MLME_GET_CONFIRM
-{
-    CSR_DATAREF    MibAttributeValue;
-    CSR_DATAREF    Dummydataref2;
-    CSR_MIB_STATUS Status;
-    CSR_NATURAL16  ErrorIndex;
-} CSR_MLME_GET_CONFIRM;
-
-typedef struct CSR_MLME_GET_REQUEST
-{
-    CSR_DATAREF MibAttribute;
-    CSR_DATAREF Dummydataref2;
-} CSR_MLME_GET_REQUEST;
-
-typedef struct CSR_MLME_GET_NEXT_CONFIRM
-{
-    CSR_DATAREF    MibAttributeValue;
-    CSR_DATAREF    Dummydataref2;
-    CSR_MIB_STATUS Status;
-    CSR_NATURAL16  ErrorIndex;
-} CSR_MLME_GET_NEXT_CONFIRM;
-
-typedef struct CSR_MLME_GET_NEXT_REQUEST
-{
-    CSR_DATAREF MibAttribute;
-    CSR_DATAREF Dummydataref2;
-} CSR_MLME_GET_NEXT_REQUEST;
-
-typedef struct CSR_MLME_HL_SYNC_CONFIRM
-{
-    CSR_DATAREF     Dummydataref1;
-    CSR_DATAREF     Dummydataref2;
-    CSR_MACADDRESS  GroupAddress;
-    CSR_RESULT_CODE ResultCode;
-} CSR_MLME_HL_SYNC_CONFIRM;
-
-typedef struct CSR_MLME_HL_SYNC_REQUEST
-{
-    CSR_DATAREF    Dummydataref1;
-    CSR_DATAREF    Dummydataref2;
-    CSR_MACADDRESS GroupAddress;
-} CSR_MLME_HL_SYNC_REQUEST;
-
-typedef struct CSR_MLME_HL_SYNC_CANCEL_CONFIRM
-{
-    CSR_DATAREF     Dummydataref1;
-    CSR_DATAREF     Dummydataref2;
-    CSR_RESULT_CODE ResultCode;
-} CSR_MLME_HL_SYNC_CANCEL_CONFIRM;
-
-typedef struct CSR_MLME_HL_SYNC_CANCEL_REQUEST
-{
-    CSR_DATAREF    Dummydataref1;
-    CSR_DATAREF    Dummydataref2;
-    CSR_MACADDRESS GroupAddress;
-} CSR_MLME_HL_SYNC_CANCEL_REQUEST;
-
-typedef struct CSR_MLME_MEASURE_CONFIRM
-{
-    CSR_DATAREF      Dummydataref1;
-    CSR_DATAREF      Dummydataref2;
-    CSR_RESULT_CODE  ResultCode;
-    CSR_DIALOG_TOKEN DialogToken;
-} CSR_MLME_MEASURE_CONFIRM;
-
-typedef struct CSR_MLME_MEASURE_INDICATION
-{
-    CSR_DATAREF      MeasurementReportSet;
-    CSR_DATAREF      Dummydataref2;
-    CSR_DIALOG_TOKEN DialogToken;
-} CSR_MLME_MEASURE_INDICATION;
-
-typedef struct CSR_MLME_MEASURE_REQUEST
-{
-    CSR_DATAREF      MeasurementRequestSet;
-    CSR_DATAREF      Dummydataref2;
-    CSR_DIALOG_TOKEN DialogToken;
-} CSR_MLME_MEASURE_REQUEST;
-
-typedef struct CSR_MLME_RESET_CONFIRM
-{
-    CSR_DATAREF     Dummydataref1;
-    CSR_DATAREF     Dummydataref2;
-    CSR_RESULT_CODE ResultCode;
-} CSR_MLME_RESET_CONFIRM;
-
-typedef struct CSR_MLME_RESET_REQUEST
-{
-    CSR_DATAREF    Dummydataref1;
-    CSR_DATAREF    Dummydataref2;
-    CSR_MACADDRESS StaAddress;
-    s16       SetDefaultMib;
-} CSR_MLME_RESET_REQUEST;
-
-typedef struct CSR_MLME_SET_CONFIRM
-{
-    CSR_DATAREF    MibAttributeValue;
-    CSR_DATAREF    Dummydataref2;
-    CSR_MIB_STATUS Status;
-    CSR_NATURAL16  ErrorIndex;
-} CSR_MLME_SET_CONFIRM;
-
-typedef struct CSR_MLME_SET_REQUEST
-{
-    CSR_DATAREF MibAttributeValue;
-    CSR_DATAREF Dummydataref2;
-} CSR_MLME_SET_REQUEST;
-
-typedef struct CSR_MLME_STOP_MEASURE_CONFIRM
-{
-    CSR_DATAREF      Dummydataref1;
-    CSR_DATAREF      Dummydataref2;
-    CSR_RESULT_CODE  ResultCode;
-    CSR_DIALOG_TOKEN DialogToken;
-} CSR_MLME_STOP_MEASURE_CONFIRM;
-
-typedef struct CSR_MLME_STOP_MEASURE_REQUEST
-{
-    CSR_DATAREF      Dummydataref1;
-    CSR_DATAREF      Dummydataref2;
-    CSR_DIALOG_TOKEN DialogToken;
-} CSR_MLME_STOP_MEASURE_REQUEST;
-
-typedef u16 CSR_PROCESS_ID;
-
-typedef u16 CSR_RATE;
-
-typedef u16 CSR_SEQUENCE_NUMBER;
-
-typedef struct CSR_SIGNAL_PRIMITIVE_HEADER
-{
-    s16       SignalId;
-    CSR_PROCESS_ID ReceiverProcessId;
-    CSR_PROCESS_ID SenderProcessId;
-} CSR_SIGNAL_PRIMITIVE_HEADER;
-
-typedef u16 CSR_TRAFFIC_WINDOW;
-
-typedef u16 CSR_VIF_IDENTIFIER;
-
-typedef struct CSR_DEBUG_GENERIC_CONFIRM
-{
-    CSR_DATAREF   DebugVariable;
-    CSR_DATAREF   Dummydataref2;
-    CSR_NATURAL16 DebugWords[8];
-} CSR_DEBUG_GENERIC_CONFIRM;
-
-typedef struct CSR_DEBUG_GENERIC_INDICATION
-{
-    CSR_DATAREF   DebugVariable;
-    CSR_DATAREF   Dummydataref2;
-    CSR_NATURAL16 DebugWords[8];
-} CSR_DEBUG_GENERIC_INDICATION;
-
-typedef struct CSR_DEBUG_GENERIC_REQUEST
-{
-    CSR_DATAREF   DebugVariable;
-    CSR_DATAREF   Dummydataref2;
-    CSR_NATURAL16 DebugWords[8];
-} CSR_DEBUG_GENERIC_REQUEST;
-
-typedef struct CSR_DEBUG_STRING_INDICATION
-{
-    CSR_DATAREF DebugMessage;
-    CSR_DATAREF Dummydataref2;
-} CSR_DEBUG_STRING_INDICATION;
-
-typedef struct CSR_DEBUG_WORD16_INDICATION
-{
-    CSR_DATAREF   Dummydataref1;
-    CSR_DATAREF   Dummydataref2;
-    CSR_NATURAL16 DebugWords[16];
-} CSR_DEBUG_WORD16_INDICATION;
-
-typedef struct CSR_MA_PACKET_CONFIRM
-{
-    CSR_DATAREF             Dummydataref1;
-    CSR_DATAREF             Dummydataref2;
-    CSR_VIF_IDENTIFIER      VirtualInterfaceIdentifier;
-    CSR_TRANSMISSION_STATUS TransmissionStatus;
-    CSR_NATURAL16           RetryCount;
-    CSR_RATE                Rate;
-    CSR_CLIENT_TAG          HostTag;
-} CSR_MA_PACKET_CONFIRM;
-
-typedef struct CSR_MA_PACKET_INDICATION
-{
-    CSR_DATAREF          Data;
-    CSR_DATAREF          Dummydataref2;
-    CSR_VIF_IDENTIFIER   VirtualInterfaceIdentifier;
-    CSR_TSF_TIME         LocalTime;
-    CSR_IFINTERFACE      Ifindex;
-    CSR_CHANNEL_NUMBER   Channel;
-    CSR_RECEPTION_STATUS ReceptionStatus;
-    CSR_DECIBELS         Rssi;
-    CSR_DECIBELS         Snr;
-    CSR_RATE             ReceivedRate;
-} CSR_MA_PACKET_INDICATION;
-
-typedef struct CSR_MA_PACKET_REQUEST
-{
-    CSR_DATAREF              Data;
-    CSR_DATAREF              Dummydataref2;
-    CSR_VIF_IDENTIFIER       VirtualInterfaceIdentifier;
-    CSR_RATE                 TransmitRate;
-    CSR_CLIENT_TAG           HostTag;
-    CSR_PRIORITY             Priority;
-    CSR_MACADDRESS           Ra;
-    CSR_TRANSMISSION_CONTROL TransmissionControl;
-} CSR_MA_PACKET_REQUEST;
-
-typedef struct CSR_MA_PACKET_CANCEL_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_CLIENT_TAG     HostTag;
-} CSR_MA_PACKET_CANCEL_REQUEST;
-
-typedef struct CSR_MA_PACKET_ERROR_INDICATION
-{
-    CSR_DATAREF         Dummydataref1;
-    CSR_DATAREF         Dummydataref2;
-    CSR_VIF_IDENTIFIER  VirtualInterfaceIdentifier;
-    CSR_MACADDRESS      PeerQstaAddress;
-    CSR_PRIORITY        UserPriority;
-    CSR_SEQUENCE_NUMBER SequenceNumber;
-} CSR_MA_PACKET_ERROR_INDICATION;
-
-typedef struct CSR_MA_VIF_AVAILABILITY_INDICATION
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    s16           Multicast;
-} CSR_MA_VIF_AVAILABILITY_INDICATION;
-
-typedef struct CSR_MA_VIF_AVAILABILITY_RESPONSE
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MA_VIF_AVAILABILITY_RESPONSE;
-
-typedef struct CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM
-{
-    CSR_DATAREF            Dummydataref1;
-    CSR_DATAREF            Dummydataref2;
-    CSR_VIF_IDENTIFIER     VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE        ResultCode;
-    CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
-} CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM;
-
-typedef struct CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST
-{
-    CSR_DATAREF                 ChannelList;
-    CSR_DATAREF                 InformationElements;
-    CSR_VIF_IDENTIFIER          VirtualInterfaceIdentifier;
-    CSR_AUTONOMOUS_SCAN_ID      AutonomousScanId;
-    CSR_IFINTERFACE             Ifindex;
-    CSR_CHANNEL_STARTING_FACTOR ChannelStartingFactor;
-    CSR_SCAN_TYPE               ScanType;
-    CSR_MICROSECONDS32          ProbeDelay;
-    CSR_TIME_UNITS              MinChannelTime;
-    CSR_TIME_UNITS              MaxChannelTime;
-} CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST;
-
-typedef struct CSR_MLME_ADD_BLACKOUT_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_BLACKOUT_ID    BlackoutId;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_ADD_BLACKOUT_CONFIRM;
-
-typedef struct CSR_MLME_ADD_BLACKOUT_REQUEST
-{
-    CSR_DATAREF         Dummydataref1;
-    CSR_DATAREF         Dummydataref2;
-    CSR_VIF_IDENTIFIER  VirtualInterfaceIdentifier;
-    CSR_BLACKOUT_ID     BlackoutId;
-    CSR_BLACKOUT_TYPE   BlackoutType;
-    CSR_BLACKOUT_SOURCE BlackoutSource;
-    CSR_MICROSECONDS32  BlackoutStartReference;
-    CSR_MICROSECONDS32  BlackoutPeriod;
-    CSR_MICROSECONDS32  BlackoutDuration;
-    CSR_MACADDRESS      PeerStaAddress;
-    CSR_NATURAL16       BlackoutCount;
-} CSR_MLME_ADD_BLACKOUT_REQUEST;
-
-typedef struct CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM;
-
-typedef struct CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST
-{
-    CSR_DATAREF        Data;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_NATURAL16      NumberOfMulticastGroupAddresses;
-} CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST;
-
-typedef struct CSR_MLME_ADD_PERIODIC_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_PERIODIC_ID    PeriodicId;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_ADD_PERIODIC_CONFIRM;
-
-typedef struct CSR_MLME_ADD_PERIODIC_REQUEST
-{
-    CSR_DATAREF                  Dummydataref1;
-    CSR_DATAREF                  Dummydataref2;
-    CSR_VIF_IDENTIFIER           VirtualInterfaceIdentifier;
-    CSR_PERIODIC_ID              PeriodicId;
-    CSR_MICROSECONDS32           MaximumLatency;
-    CSR_PERIODIC_SCHEDULING_MODE PeriodicSchedulingMode;
-    s16                     WakeHost;
-    CSR_PRIORITY                 UserPriority;
-} CSR_MLME_ADD_PERIODIC_REQUEST;
-
-typedef struct CSR_MLME_ADD_RX_TRIGGER_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_TRIGGER_ID     TriggerId;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_ADD_RX_TRIGGER_CONFIRM;
-
-typedef struct CSR_MLME_ADD_RX_TRIGGER_REQUEST
-{
-    CSR_DATAREF        InformationElements;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_TRIGGER_ID     TriggerId;
-    CSR_PRIORITY       Priority;
-} CSR_MLME_ADD_RX_TRIGGER_REQUEST;
-
-typedef struct CSR_MLME_ADD_TEMPLATE_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_FRAME_TYPE     FrameType;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_ADD_TEMPLATE_CONFIRM;
-
-typedef struct CSR_MLME_ADD_TEMPLATE_REQUEST
-{
-    CSR_DATAREF        Data1;
-    CSR_DATAREF        Data2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_FRAME_TYPE     FrameType;
-    CSR_RATE           MinTransmitRate;
-} CSR_MLME_ADD_TEMPLATE_REQUEST;
-
-typedef struct CSR_MLME_ADD_TRIGGERED_GET_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-    CSR_TRIGGERED_ID   TriggeredId;
-} CSR_MLME_ADD_TRIGGERED_GET_CONFIRM;
-
-typedef struct CSR_MLME_ADD_TRIGGERED_GET_REQUEST
-{
-    CSR_DATAREF        MibAttribute;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_TRIGGERED_ID   TriggeredId;
-} CSR_MLME_ADD_TRIGGERED_GET_REQUEST;
-
-typedef struct CSR_MLME_ADD_TSPEC_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_PRIORITY       UserPriority;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_ADD_TSPEC_CONFIRM;
-
-typedef struct CSR_MLME_ADD_TSPEC_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_PRIORITY       UserPriority;
-    CSR_DIRECTION      Direction;
-    CSR_PS_SCHEME      PsScheme;
-    CSR_NATURAL16      MediumTime;
-    CSR_MICROSECONDS32 ServiceStartTime;
-    CSR_MICROSECONDS32 ServiceInterval;
-    CSR_RATE           MinimumDataRate;
-} CSR_MLME_ADD_TSPEC_REQUEST;
-
-typedef struct CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION
-{
-    CSR_DATAREF            Dummydataref1;
-    CSR_DATAREF            Dummydataref2;
-    CSR_VIF_IDENTIFIER     VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE        ResultCode;
-    CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
-} CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION;
-
-typedef struct CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_MACADDRESS     Bssid;
-} CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION;
-
-typedef struct CSR_MLME_BLACKOUT_ENDED_INDICATION
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_BLACKOUT_ID    BlackoutId;
-} CSR_MLME_BLACKOUT_ENDED_INDICATION;
-
-typedef struct CSR_MLME_BLOCKACK_ERROR_INDICATION
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_REASON_CODE    ResultCode;
-    CSR_MACADDRESS     PeerQstaAddress;
-} CSR_MLME_BLOCKACK_ERROR_INDICATION;
-
-typedef struct CSR_MLME_CONNECTED_INDICATION
-{
-    CSR_DATAREF           Dummydataref1;
-    CSR_DATAREF           Dummydataref2;
-    CSR_VIF_IDENTIFIER    VirtualInterfaceIdentifier;
-    CSR_CONNECTION_STATUS ConnectionStatus;
-    CSR_MACADDRESS        PeerMacAddress;
-} CSR_MLME_CONNECTED_INDICATION;
-
-typedef struct CSR_MLME_CONNECT_STATUS_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_CONNECT_STATUS_CONFIRM;
-
-typedef struct CSR_MLME_CONNECT_STATUS_REQUEST
-{
-    CSR_DATAREF                InformationElements;
-    CSR_DATAREF                Dummydataref2;
-    CSR_VIF_IDENTIFIER         VirtualInterfaceIdentifier;
-    CSR_CONNECTION_STATUS      ConnectionStatus;
-    CSR_MACADDRESS             StaAddress;
-    CSR_ASSOCIATION_ID         AssociationId;
-    CSR_CAPABILITY_INFORMATION AssociationCapabilityInformation;
-} CSR_MLME_CONNECT_STATUS_REQUEST;
-
-typedef struct CSR_MLME_DELETEKEYS_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_DELETEKEYS_CONFIRM;
-
-typedef struct CSR_MLME_DELETEKEYS_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_NATURAL16      KeyId;
-    CSR_KEY_TYPE       KeyType;
-    CSR_MACADDRESS     Address;
-} CSR_MLME_DELETEKEYS_REQUEST;
-
-typedef struct CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM
-{
-    CSR_DATAREF            Dummydataref1;
-    CSR_DATAREF            Dummydataref2;
-    CSR_VIF_IDENTIFIER     VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE        ResultCode;
-    CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
-} CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM;
-
-typedef struct CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST
-{
-    CSR_DATAREF            Dummydataref1;
-    CSR_DATAREF            Dummydataref2;
-    CSR_VIF_IDENTIFIER     VirtualInterfaceIdentifier;
-    CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
-} CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST;
-
-typedef struct CSR_MLME_DEL_BLACKOUT_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_BLACKOUT_ID    BlackoutId;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_DEL_BLACKOUT_CONFIRM;
-
-typedef struct CSR_MLME_DEL_BLACKOUT_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_BLACKOUT_ID    BlackoutId;
-} CSR_MLME_DEL_BLACKOUT_REQUEST;
-
-typedef struct CSR_MLME_DEL_PERIODIC_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_PERIODIC_ID    PeriodicId;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_DEL_PERIODIC_CONFIRM;
-
-typedef struct CSR_MLME_DEL_PERIODIC_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_PERIODIC_ID    PeriodicId;
-} CSR_MLME_DEL_PERIODIC_REQUEST;
-
-typedef struct CSR_MLME_DEL_RX_TRIGGER_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_TRIGGER_ID     TriggerId;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_DEL_RX_TRIGGER_CONFIRM;
-
-typedef struct CSR_MLME_DEL_RX_TRIGGER_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_TRIGGER_ID     TriggerId;
-} CSR_MLME_DEL_RX_TRIGGER_REQUEST;
-
-typedef struct CSR_MLME_DEL_TRIGGERED_GET_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-    CSR_TRIGGERED_ID   TriggeredId;
-} CSR_MLME_DEL_TRIGGERED_GET_CONFIRM;
-
-typedef struct CSR_MLME_DEL_TRIGGERED_GET_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_TRIGGERED_ID   TriggeredId;
-} CSR_MLME_DEL_TRIGGERED_GET_REQUEST;
-
-typedef struct CSR_MLME_DEL_TSPEC_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_PRIORITY       UserPriority;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_DEL_TSPEC_CONFIRM;
-
-typedef struct CSR_MLME_DEL_TSPEC_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_PRIORITY       UserPriority;
-    CSR_DIRECTION      Direction;
-} CSR_MLME_DEL_TSPEC_REQUEST;
-
-typedef struct CSR_MLME_GET_KEY_SEQUENCE_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-    CSR_NATURAL16      SequenceNumber[8];
-} CSR_MLME_GET_KEY_SEQUENCE_CONFIRM;
-
-typedef struct CSR_MLME_GET_KEY_SEQUENCE_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_NATURAL16      KeyId;
-    CSR_KEY_TYPE       KeyType;
-    CSR_MACADDRESS     Address;
-} CSR_MLME_GET_KEY_SEQUENCE_REQUEST;
-
-typedef struct CSR_MLME_LEAVE_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_LEAVE_CONFIRM;
-
-typedef struct CSR_MLME_LEAVE_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-} CSR_MLME_LEAVE_REQUEST;
-
-typedef struct CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM;
-
-typedef struct CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST
-{
-    CSR_DATAREF                Data;
-    CSR_DATAREF                Dummydataref2;
-    CSR_VIF_IDENTIFIER         VirtualInterfaceIdentifier;
-    CSR_TIME_UNITS             BeaconPeriod;
-    CSR_BEACON_PERIODS         DtimPeriod;
-    CSR_CAPABILITY_INFORMATION CapabilityInformation;
-    CSR_MACADDRESS             Bssid;
-    CSR_NATURAL16              RtsThreshold;
-} CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST;
-
-typedef struct CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM
-{
-    CSR_DATAREF            Dummydataref1;
-    CSR_DATAREF            Dummydataref2;
-    CSR_VIF_IDENTIFIER     VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE        ResultCode;
-    CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
-} CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM;
-
-typedef struct CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST
-{
-    CSR_DATAREF            Dummydataref1;
-    CSR_DATAREF            Dummydataref2;
-    CSR_VIF_IDENTIFIER     VirtualInterfaceIdentifier;
-    CSR_AUTONOMOUS_SCAN_ID AutonomousScanId;
-    s16               Pause;
-} CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST;
-
-typedef struct CSR_MLME_POWERMGT_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_POWERMGT_CONFIRM;
-
-typedef struct CSR_MLME_POWERMGT_REQUEST
-{
-    CSR_DATAREF               Dummydataref1;
-    CSR_DATAREF               Dummydataref2;
-    CSR_VIF_IDENTIFIER        VirtualInterfaceIdentifier;
-    CSR_POWER_MANAGEMENT_MODE PowerManagementMode;
-    s16                  ReceiveDtims;
-    CSR_BEACON_PERIODS        ListenInterval;
-    CSR_TRAFFIC_WINDOW        TrafficWindow;
-} CSR_MLME_POWERMGT_REQUEST;
-
-typedef struct CSR_MLME_SCAN_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_SCAN_CONFIRM;
-
-typedef struct CSR_MLME_SCAN_REQUEST
-{
-    CSR_DATAREF        ChannelList;
-    CSR_DATAREF        InformationElements;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_IFINTERFACE    Ifindex;
-    CSR_SCAN_TYPE      ScanType;
-    CSR_MICROSECONDS32 ProbeDelay;
-    CSR_TIME_UNITS     MinChannelTime;
-    CSR_TIME_UNITS     MaxChannelTime;
-} CSR_MLME_SCAN_REQUEST;
-
-typedef struct CSR_MLME_SCAN_CANCEL_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-} CSR_MLME_SCAN_CANCEL_REQUEST;
-
-typedef struct CSR_MLME_SETKEYS_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_SETKEYS_CONFIRM;
-
-typedef struct CSR_MLME_SETKEYS_REQUEST
-{
-    CSR_DATAREF               Key;
-    CSR_DATAREF               Dummydataref2;
-    CSR_VIF_IDENTIFIER        VirtualInterfaceIdentifier;
-    CSR_NATURAL16             Length;
-    CSR_NATURAL16             KeyId;
-    CSR_KEY_TYPE              KeyType;
-    CSR_MACADDRESS            Address;
-    CSR_NATURAL16             SequenceNumber[8];
-    CSR_CIPHER_SUITE_SELECTOR CipherSuiteSelector;
-} CSR_MLME_SETKEYS_REQUEST;
-
-typedef struct CSR_MLME_SET_CHANNEL_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_SET_CHANNEL_CONFIRM;
-
-typedef struct CSR_MLME_SET_CHANNEL_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_IFINTERFACE    Ifindex;
-    CSR_CHANNEL_NUMBER Channel;
-    CSR_MACADDRESS     Address;
-    CSR_TIME_UNITS     AvailabilityDuration;
-    CSR_TIME_UNITS     AvailabilityInterval;
-} CSR_MLME_SET_CHANNEL_REQUEST;
-
-typedef struct CSR_MLME_SET_PACKET_FILTER_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_SET_PACKET_FILTER_CONFIRM;
-
-typedef struct CSR_MLME_SET_PACKET_FILTER_REQUEST
-{
-    CSR_DATAREF            InformationElements;
-    CSR_DATAREF            Dummydataref2;
-    CSR_VIF_IDENTIFIER     VirtualInterfaceIdentifier;
-    CSR_PACKET_FILTER_MODE PacketFilterMode;
-    CSR_IPV4_ADDRESS       ArpFilterAddress;
-} CSR_MLME_SET_PACKET_FILTER_REQUEST;
-
-typedef struct CSR_MLME_SET_TIM_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_SET_TIM_CONFIRM;
-
-typedef struct CSR_MLME_SET_TIM_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_ASSOCIATION_ID AssociationId;
-    s16           TimValue;
-} CSR_MLME_SET_TIM_REQUEST;
-
-typedef struct CSR_MLME_SM_START_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_SM_START_CONFIRM;
-
-typedef struct CSR_MLME_SM_START_REQUEST
-{
-    CSR_DATAREF                Beacon;
-    CSR_DATAREF                BssParameters;
-    CSR_VIF_IDENTIFIER         VirtualInterfaceIdentifier;
-    CSR_IFINTERFACE            Ifindex;
-    CSR_CHANNEL_NUMBER         Channel;
-    CSR_MACADDRESS             InterfaceAddress;
-    CSR_MACADDRESS             Bssid;
-    CSR_TIME_UNITS             BeaconPeriod;
-    CSR_BEACON_PERIODS         DtimPeriod;
-    CSR_CAPABILITY_INFORMATION CapabilityInformation;
-} CSR_MLME_SM_START_REQUEST;
-
-typedef struct CSR_MLME_START_AGGREGATION_CONFIRM
-{
-    CSR_DATAREF         Dummydataref1;
-    CSR_DATAREF         Dummydataref2;
-    CSR_VIF_IDENTIFIER  VirtualInterfaceIdentifier;
-    CSR_MACADDRESS      PeerQstaAddress;
-    CSR_PRIORITY        UserPriority;
-    CSR_DIRECTION       Direction;
-    CSR_RESULT_CODE     ResultCode;
-    CSR_SEQUENCE_NUMBER SequenceNumber;
-} CSR_MLME_START_AGGREGATION_CONFIRM;
-
-typedef struct CSR_MLME_START_AGGREGATION_REQUEST
-{
-    CSR_DATAREF                  Dummydataref1;
-    CSR_DATAREF                  Dummydataref2;
-    CSR_VIF_IDENTIFIER           VirtualInterfaceIdentifier;
-    CSR_MACADDRESS               PeerQstaAddress;
-    CSR_PRIORITY                 UserPriority;
-    CSR_DIRECTION                Direction;
-    CSR_STARTING_SEQUENCE_NUMBER StartingSequenceNumber;
-    CSR_NATURAL16                BufferSize;
-    CSR_TIME_UNITS               BlockAckTimeout;
-} CSR_MLME_START_AGGREGATION_REQUEST;
-
-typedef struct CSR_MLME_STOP_AGGREGATION_CONFIRM
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_MACADDRESS     PeerQstaAddress;
-    CSR_PRIORITY       UserPriority;
-    CSR_DIRECTION      Direction;
-    CSR_RESULT_CODE    ResultCode;
-} CSR_MLME_STOP_AGGREGATION_CONFIRM;
-
-typedef struct CSR_MLME_STOP_AGGREGATION_REQUEST
-{
-    CSR_DATAREF        Dummydataref1;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_MACADDRESS     PeerQstaAddress;
-    CSR_PRIORITY       UserPriority;
-    CSR_DIRECTION      Direction;
-} CSR_MLME_STOP_AGGREGATION_REQUEST;
-
-typedef struct CSR_MLME_TRIGGERED_GET_INDICATION
-{
-    CSR_DATAREF        MibAttributeValue;
-    CSR_DATAREF        Dummydataref2;
-    CSR_VIF_IDENTIFIER VirtualInterfaceIdentifier;
-    CSR_MIB_STATUS     Status;
-    CSR_NATURAL16      ErrorIndex;
-    CSR_TRIGGERED_ID   TriggeredId;
-} CSR_MLME_TRIGGERED_GET_INDICATION;
-
-typedef struct CSR_SIGNAL_PRIMITIVE
-{
-    CSR_SIGNAL_PRIMITIVE_HEADER SignalPrimitiveHeader;
-    union
-    {
-        CSR_MA_PACKET_REQUEST                    MaPacketRequest;
-        CSR_MA_PACKET_CONFIRM                    MaPacketConfirm;
-        CSR_MA_PACKET_INDICATION                 MaPacketIndication;
-        CSR_MA_PACKET_CANCEL_REQUEST             MaPacketCancelRequest;
-        CSR_MA_VIF_AVAILABILITY_RESPONSE         MaVifAvailabilityResponse;
-        CSR_MA_VIF_AVAILABILITY_INDICATION       MaVifAvailabilityIndication;
-        CSR_MA_PACKET_ERROR_INDICATION           MaPacketErrorIndication;
-        CSR_MLME_RESET_REQUEST                   MlmeResetRequest;
-        CSR_MLME_RESET_CONFIRM                   MlmeResetConfirm;
-        CSR_MLME_GET_REQUEST                     MlmeGetRequest;
-        CSR_MLME_GET_CONFIRM                     MlmeGetConfirm;
-        CSR_MLME_SET_REQUEST                     MlmeSetRequest;
-        CSR_MLME_SET_CONFIRM                     MlmeSetConfirm;
-        CSR_MLME_GET_NEXT_REQUEST                MlmeGetNextRequest;
-        CSR_MLME_GET_NEXT_CONFIRM                MlmeGetNextConfirm;
-        CSR_MLME_POWERMGT_REQUEST                MlmePowermgtRequest;
-        CSR_MLME_POWERMGT_CONFIRM                MlmePowermgtConfirm;
-        CSR_MLME_SCAN_REQUEST                    MlmeScanRequest;
-        CSR_MLME_SCAN_CONFIRM                    MlmeScanConfirm;
-        CSR_MLME_HL_SYNC_REQUEST                 MlmeHlSyncRequest;
-        CSR_MLME_HL_SYNC_CONFIRM                 MlmeHlSyncConfirm;
-        CSR_MLME_MEASURE_REQUEST                 MlmeMeasureRequest;
-        CSR_MLME_MEASURE_CONFIRM                 MlmeMeasureConfirm;
-        CSR_MLME_MEASURE_INDICATION              MlmeMeasureIndication;
-        CSR_MLME_SETKEYS_REQUEST                 MlmeSetkeysRequest;
-        CSR_MLME_SETKEYS_CONFIRM                 MlmeSetkeysConfirm;
-        CSR_MLME_DELETEKEYS_REQUEST              MlmeDeletekeysRequest;
-        CSR_MLME_DELETEKEYS_CONFIRM              MlmeDeletekeysConfirm;
-        CSR_MLME_AUTONOMOUS_SCAN_LOSS_INDICATION MlmeAutonomousScanLossIndication;
-        CSR_MLME_CONNECTED_INDICATION            MlmeConnectedIndication;
-        CSR_MLME_SCAN_CANCEL_REQUEST             MlmeScanCancelRequest;
-        CSR_MLME_HL_SYNC_CANCEL_REQUEST          MlmeHlSyncCancelRequest;
-        CSR_MLME_HL_SYNC_CANCEL_CONFIRM          MlmeHlSyncCancelConfirm;
-        CSR_MLME_ADD_PERIODIC_REQUEST            MlmeAddPeriodicRequest;
-        CSR_MLME_ADD_PERIODIC_CONFIRM            MlmeAddPeriodicConfirm;
-        CSR_MLME_DEL_PERIODIC_REQUEST            MlmeDelPeriodicRequest;
-        CSR_MLME_DEL_PERIODIC_CONFIRM            MlmeDelPeriodicConfirm;
-        CSR_MLME_ADD_AUTONOMOUS_SCAN_REQUEST     MlmeAddAutonomousScanRequest;
-        CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM     MlmeAddAutonomousScanConfirm;
-        CSR_MLME_DEL_AUTONOMOUS_SCAN_REQUEST     MlmeDelAutonomousScanRequest;
-        CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM     MlmeDelAutonomousScanConfirm;
-        CSR_MLME_SET_PACKET_FILTER_REQUEST       MlmeSetPacketFilterRequest;
-        CSR_MLME_SET_PACKET_FILTER_CONFIRM       MlmeSetPacketFilterConfirm;
-        CSR_MLME_STOP_MEASURE_REQUEST            MlmeStopMeasureRequest;
-        CSR_MLME_STOP_MEASURE_CONFIRM            MlmeStopMeasureConfirm;
-        CSR_MLME_PAUSE_AUTONOMOUS_SCAN_REQUEST   MlmePauseAutonomousScanRequest;
-        CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM   MlmePauseAutonomousScanConfirm;
-        CSR_MLME_AUTONOMOUS_SCAN_DONE_INDICATION MlmeAutonomousScanDoneIndication;
-        CSR_MLME_ADD_TRIGGERED_GET_REQUEST       MlmeAddTriggeredGetRequest;
-        CSR_MLME_ADD_TRIGGERED_GET_CONFIRM       MlmeAddTriggeredGetConfirm;
-        CSR_MLME_DEL_TRIGGERED_GET_REQUEST       MlmeDelTriggeredGetRequest;
-        CSR_MLME_DEL_TRIGGERED_GET_CONFIRM       MlmeDelTriggeredGetConfirm;
-        CSR_MLME_TRIGGERED_GET_INDICATION        MlmeTriggeredGetIndication;
-        CSR_MLME_ADD_BLACKOUT_REQUEST            MlmeAddBlackoutRequest;
-        CSR_MLME_ADD_BLACKOUT_CONFIRM            MlmeAddBlackoutConfirm;
-        CSR_MLME_BLACKOUT_ENDED_INDICATION       MlmeBlackoutEndedIndication;
-        CSR_MLME_DEL_BLACKOUT_REQUEST            MlmeDelBlackoutRequest;
-        CSR_MLME_DEL_BLACKOUT_CONFIRM            MlmeDelBlackoutConfirm;
-        CSR_MLME_ADD_RX_TRIGGER_REQUEST          MlmeAddRxTriggerRequest;
-        CSR_MLME_ADD_RX_TRIGGER_CONFIRM          MlmeAddRxTriggerConfirm;
-        CSR_MLME_DEL_RX_TRIGGER_REQUEST          MlmeDelRxTriggerRequest;
-        CSR_MLME_DEL_RX_TRIGGER_CONFIRM          MlmeDelRxTriggerConfirm;
-        CSR_MLME_CONNECT_STATUS_REQUEST          MlmeConnectStatusRequest;
-        CSR_MLME_CONNECT_STATUS_CONFIRM          MlmeConnectStatusConfirm;
-        CSR_MLME_MODIFY_BSS_PARAMETER_REQUEST    MlmeModifyBssParameterRequest;
-        CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM    MlmeModifyBssParameterConfirm;
-        CSR_MLME_ADD_TEMPLATE_REQUEST            MlmeAddTemplateRequest;
-        CSR_MLME_ADD_TEMPLATE_CONFIRM            MlmeAddTemplateConfirm;
-        CSR_MLME_CONFIG_QUEUE_REQUEST            MlmeConfigQueueRequest;
-        CSR_MLME_CONFIG_QUEUE_CONFIRM            MlmeConfigQueueConfirm;
-        CSR_MLME_ADD_TSPEC_REQUEST               MlmeAddTspecRequest;
-        CSR_MLME_ADD_TSPEC_CONFIRM               MlmeAddTspecConfirm;
-        CSR_MLME_DEL_TSPEC_REQUEST               MlmeDelTspecRequest;
-        CSR_MLME_DEL_TSPEC_CONFIRM               MlmeDelTspecConfirm;
-        CSR_MLME_START_AGGREGATION_REQUEST       MlmeStartAggregationRequest;
-        CSR_MLME_START_AGGREGATION_CONFIRM       MlmeStartAggregationConfirm;
-        CSR_MLME_BLOCKACK_ERROR_INDICATION       MlmeBlockackErrorIndication;
-        CSR_MLME_STOP_AGGREGATION_REQUEST        MlmeStopAggregationRequest;
-        CSR_MLME_STOP_AGGREGATION_CONFIRM        MlmeStopAggregationConfirm;
-        CSR_MLME_SM_START_REQUEST                MlmeSmStartRequest;
-        CSR_MLME_SM_START_CONFIRM                MlmeSmStartConfirm;
-        CSR_MLME_LEAVE_REQUEST                   MlmeLeaveRequest;
-        CSR_MLME_LEAVE_CONFIRM                   MlmeLeaveConfirm;
-        CSR_MLME_SET_TIM_REQUEST                 MlmeSetTimRequest;
-        CSR_MLME_SET_TIM_CONFIRM                 MlmeSetTimConfirm;
-        CSR_MLME_GET_KEY_SEQUENCE_REQUEST        MlmeGetKeySequenceRequest;
-        CSR_MLME_GET_KEY_SEQUENCE_CONFIRM        MlmeGetKeySequenceConfirm;
-        CSR_MLME_SET_CHANNEL_REQUEST             MlmeSetChannelRequest;
-        CSR_MLME_SET_CHANNEL_CONFIRM             MlmeSetChannelConfirm;
-        CSR_MLME_ADD_MULTICAST_ADDRESS_REQUEST   MlmeAddMulticastAddressRequest;
-        CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM   MlmeAddMulticastAddressConfirm;
-        CSR_DEBUG_STRING_INDICATION              DebugStringIndication;
-        CSR_DEBUG_WORD16_INDICATION              DebugWord16Indication;
-        CSR_DEBUG_GENERIC_REQUEST                DebugGenericRequest;
-        CSR_DEBUG_GENERIC_CONFIRM                DebugGenericConfirm;
-        CSR_DEBUG_GENERIC_INDICATION             DebugGenericIndication;
-    } u;
-} CSR_SIGNAL;
-
-#define SIG_FILTER_SIZE 6
-
-u32 SigGetFilterPos(u16 aSigID);
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_ta_sampling.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_ta_sampling.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_ta_sampling.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_ta_sampling.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,541 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     csr_wifi_hip_ta_sampling.c
- *
- *  PURPOSE:
- *      The traffic analysis sampling module.
- *      This gathers data which is sent to the SME and used to analyse
- *      the traffic behaviour.
- *
- * Provides:
- *      unifi_ta_sampling_init - Initialise the internal state
- *      unifi_ta_sample        - Sampling function, call this for every data packet
- *
- * Calls these external functions which must be provided:
- *      unifi_ta_indicate_sampling - Pass sample data to the SME.
- *      unifi_ta_indicate_protocol - Report certain data packet types to the SME.
- * ---------------------------------------------------------------------------
- */
-
-#include "csr_wifi_hip_card_sdio.h"
-
-/* Maximum number of Tx frames we store each CYCLE_1, for detecting period */
-#define TA_MAX_INTERVALS_IN_C1          100
-
-/* Number of intervals in CYCLE_1 (one second), for detecting periodic */
-/* Must match size of unifi_TrafficStats.intervals - 1 */
-#define TA_INTERVALS_NUM               10
-
-/* Step (in msecs) between intervals, for detecting periodic */
-/* We are only interested in periods up to 100ms, i.e. between beacons */
-/* This is correct for TA_INTERVALS_NUM=10 */
-#define TA_INTERVALS_STEP               10
-
-
-enum ta_frame_identity
-{
-    TA_FRAME_UNKNOWN,
-    TA_FRAME_ETHERNET_UNINTERESTING,
-    TA_FRAME_ETHERNET_INTERESTING
-};
-
-
-#define TA_ETHERNET_TYPE_OFFSET     6
-#define TA_LLC_HEADER_SIZE          8
-#define TA_IP_TYPE_OFFSET           17
-#define TA_UDP_SOURCE_PORT_OFFSET   28
-#define TA_UDP_DEST_PORT_OFFSET     (TA_UDP_SOURCE_PORT_OFFSET + 2)
-#define TA_BOOTP_CLIENT_MAC_ADDR_OFFSET 64
-#define TA_DHCP_MESSAGE_TYPE_OFFSET 278
-#define TA_DHCP_MESSAGE_TYPE_ACK    0x05
-#define TA_PROTO_TYPE_IP            0x0800
-#define TA_PROTO_TYPE_EAP           0x888E
-#define TA_PROTO_TYPE_WAI           0x8864
-#define TA_PROTO_TYPE_ARP           0x0806
-#define TA_IP_TYPE_TCP              0x06
-#define TA_IP_TYPE_UDP              0x11
-#define TA_UDP_PORT_BOOTPC          0x0044
-#define TA_UDP_PORT_BOOTPS          0x0043
-#define TA_EAPOL_TYPE_OFFSET        9
-#define TA_EAPOL_TYPE_START         0x01
-
-#define snap_802_2                  0xAAAA0300
-#define oui_rfc1042                 0x00000000
-#define oui_8021h                   0x0000f800
-static const u8 aironet_snap[5] = { 0x00, 0x40, 0x96, 0x00, 0x00 };
-
-
-/*
- * ---------------------------------------------------------------------------
- *  ta_detect_protocol
- *
- *      Internal only.
- *      Detects a specific protocol in a frame and indicates a TA event.
- *
- *  Arguments:
- *      ta              The pointer to the TA module.
- *      direction       The direction of the frame (tx or rx).
- *      data            Pointer to the structure that contains the data.
- *
- *  Returns:
- *      None
- * ---------------------------------------------------------------------------
- */
-static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrlProtocolDirection direction,
-                                                 const bulk_data_desc_t *data,
-                                                 const u8 *saddr,
-                                                 const u8 *sta_macaddr)
-{
-    ta_data_t *tad = &card->ta_sampling;
-    u16 proto;
-    u16 source_port, dest_port;
-    CsrWifiMacAddress srcAddress;
-    u32 snap_hdr, oui_hdr;
-
-    if (data->data_length < TA_LLC_HEADER_SIZE)
-    {
-        return TA_FRAME_UNKNOWN;
-    }
-
-    snap_hdr = (((u32)data->os_data_ptr[0]) << 24) |
-               (((u32)data->os_data_ptr[1]) << 16) |
-               (((u32)data->os_data_ptr[2]) << 8);
-    if (snap_hdr != snap_802_2)
-    {
-        return TA_FRAME_UNKNOWN;
-    }
-
-    if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM)
-    {
-        /*
-         * Here we would use the custom filter to detect interesting frames.
-         */
-    }
-
-    oui_hdr = (((u32)data->os_data_ptr[3]) << 24) |
-              (((u32)data->os_data_ptr[4]) << 16) |
-              (((u32)data->os_data_ptr[5]) << 8);
-    if ((oui_hdr == oui_rfc1042) || (oui_hdr == oui_8021h))
-    {
-        proto = (data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET] * 256) +
-                data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET + 1];
-
-        /* The only interesting IP frames are the DHCP */
-        if (proto == TA_PROTO_TYPE_IP)
-        {
-            if (data->data_length > TA_IP_TYPE_OFFSET)
-            {
-                if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM)
-                {
-                    ta_l4stats_t *ta_l4stats = &tad->ta_l4stats;
-                    u8 l4proto = data->os_data_ptr[TA_IP_TYPE_OFFSET];
-
-                    if (l4proto == TA_IP_TYPE_TCP)
-                    {
-                        if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX)
-                        {
-                            ta_l4stats->txTcpBytesCount += data->data_length;
-                        }
-                        else
-                        {
-                            ta_l4stats->rxTcpBytesCount += data->data_length;
-                        }
-                    }
-                    else if (l4proto == TA_IP_TYPE_UDP)
-                    {
-                        if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX)
-                        {
-                            ta_l4stats->txUdpBytesCount += data->data_length;
-                        }
-                        else
-                        {
-                            ta_l4stats->rxUdpBytesCount += data->data_length;
-                        }
-                    }
-                }
-
-                /* detect DHCP frames */
-                if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP)
-                {
-                    /* DHCP frames are UDP frames with BOOTP ports */
-                    if (data->os_data_ptr[TA_IP_TYPE_OFFSET] == TA_IP_TYPE_UDP)
-                    {
-                        if (data->data_length > TA_UDP_DEST_PORT_OFFSET)
-                        {
-                            source_port = (data->os_data_ptr[TA_UDP_SOURCE_PORT_OFFSET] * 256) +
-                                          data->os_data_ptr[TA_UDP_SOURCE_PORT_OFFSET + 1];
-                            dest_port = (data->os_data_ptr[TA_UDP_DEST_PORT_OFFSET] * 256) +
-                                        data->os_data_ptr[TA_UDP_DEST_PORT_OFFSET + 1];
-
-                            if (((source_port == TA_UDP_PORT_BOOTPC) && (dest_port == TA_UDP_PORT_BOOTPS)) ||
-                                ((source_port == TA_UDP_PORT_BOOTPS) && (dest_port == TA_UDP_PORT_BOOTPC)))
-                            {
-                                /* The DHCP should have at least a message type (request, ack, nack, etc) */
-                                if (data->data_length > TA_DHCP_MESSAGE_TYPE_OFFSET + 6)
-                                {
-                                    UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
-
-                                    if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX)
-                                    {
-                                        unifi_ta_indicate_protocol(card->ospriv,
-                                                                   CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP,
-                                                                   direction,
-                                                                   &srcAddress);
-                                        return TA_FRAME_ETHERNET_UNINTERESTING;
-                                    }
-
-                                    /* DHCPACK is a special indication */
-                                    if (UNIFI_MAC_ADDRESS_CMP(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr) == TRUE)
-                                    {
-                                        if (data->os_data_ptr[TA_DHCP_MESSAGE_TYPE_OFFSET] == TA_DHCP_MESSAGE_TYPE_ACK)
-                                        {
-                                            unifi_ta_indicate_protocol(card->ospriv,
-                                                                       CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP_ACK,
-                                                                       direction,
-                                                                       &srcAddress);
-                                        }
-                                        else
-                                        {
-                                            unifi_ta_indicate_protocol(card->ospriv,
-                                                                       CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP,
-                                                                       direction,
-                                                                       &srcAddress);
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            return TA_FRAME_ETHERNET_INTERESTING;
-        }
-
-        /* detect protocol type EAPOL or WAI (treated as equivalent here) */
-        if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL)
-        {
-            if (TA_PROTO_TYPE_EAP == proto || TA_PROTO_TYPE_WAI == proto)
-            {
-                if ((TA_PROTO_TYPE_WAI == proto) || (direction != CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) ||
-                    (data->os_data_ptr[TA_EAPOL_TYPE_OFFSET] == TA_EAPOL_TYPE_START))
-                {
-                    UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
-                    unifi_ta_indicate_protocol(card->ospriv,
-                                               CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL,
-                                               direction, &srcAddress);
-                }
-                return TA_FRAME_ETHERNET_UNINTERESTING;
-            }
-        }
-
-        /* detect protocol type 0x0806 (ARP) */
-        if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP)
-        {
-            if (proto == TA_PROTO_TYPE_ARP)
-            {
-                UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
-                unifi_ta_indicate_protocol(card->ospriv,
-                                           CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP,
-                                           direction, &srcAddress);
-                return TA_FRAME_ETHERNET_UNINTERESTING;
-            }
-        }
-
-        return TA_FRAME_ETHERNET_INTERESTING;
-    }
-    else if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET)
-    {
-        /* detect Aironet frames */
-        if (!memcmp(data->os_data_ptr + 3, aironet_snap, 5))
-        {
-            UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
-            unifi_ta_indicate_protocol(card->ospriv, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET,
-                                       direction, &srcAddress);
-        }
-    }
-
-    return TA_FRAME_ETHERNET_UNINTERESTING;
-} /* ta_detect_protocol() */
-
-
-static void tas_reset_data(ta_data_t *tad)
-{
-    s16 i;
-
-    for (i = 0; i < (TA_INTERVALS_NUM + 1); i++)
-    {
-        tad->stats.intervals[i] = 0;
-    }
-
-    tad->stats.rxFramesNum = 0;
-    tad->stats.txFramesNum = 0;
-    tad->stats.rxBytesCount = 0;
-    tad->stats.txBytesCount = 0;
-    tad->stats.rxMeanRate = 0;
-
-    tad->rx_sum_rate = 0;
-
-    tad->ta_l4stats.rxTcpBytesCount = 0;
-    tad->ta_l4stats.txTcpBytesCount = 0;
-    tad->ta_l4stats.rxUdpBytesCount = 0;
-    tad->ta_l4stats.txUdpBytesCount = 0;
-} /* tas_reset_data() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  API.
- *  unifi_ta_sampling_init
- *
- *      (Re)Initialise the Traffic Analysis sampling module.
- *      Resets the counters and timestamps.
- *
- *  Arguments:
- *      tad             Pointer to a ta_data_t structure containing the
- *                      context for this device instance.
- *      drv_priv        An opaque pointer that the TA sampling module will
- *                      pass in call-outs.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void unifi_ta_sampling_init(card_t *card)
-{
-    (void)unifi_ta_configure(card, CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET, NULL);
-
-    card->ta_sampling.packet_filter = CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE;
-    card->ta_sampling.traffic_type = CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_OCCASIONAL;
-} /* unifi_ta_sampling_init() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  API.
- *  unifi_ta_sample
- *
- *      Sample a data frame for the TA module.
- *      This function stores all the useful information it can extract from
- *      the frame and detects any specific protocols.
- *
- *  Arguments:
- *      tad             The pointer to the TA sampling context struct.
- *      direction       The direction of the frame (rx, tx)
- *      data            Pointer to the frame data
- *      saddr           Source MAC address of frame.
- *      timestamp       Time (in msecs) that the frame was received.
- *      rate            Reported data rate for the rx frame (0 for tx frames)
- *
- *  Returns:
- *      None
- * ---------------------------------------------------------------------------
- */
-void unifi_ta_sample(card_t                            *card,
-                     CsrWifiRouterCtrlProtocolDirection direction,
-                     const bulk_data_desc_t            *data,
-                     const u8                    *saddr,
-                     const u8                    *sta_macaddr,
-                     u32                          timestamp,
-                     u16                          rate)
-{
-    ta_data_t *tad = &card->ta_sampling;
-    enum ta_frame_identity identity;
-    u32 time_delta;
-
-
-
-    /* Step1: Check for specific frames */
-    if (tad->packet_filter != CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE)
-    {
-        identity = ta_detect_protocol(card, direction, data, saddr, sta_macaddr);
-    }
-    else
-    {
-        identity = TA_FRAME_ETHERNET_INTERESTING;
-    }
-
-
-    /* Step2: Update the information in the current record */
-    if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX)
-    {
-        /* Update the Rx packet count and the throughput count */
-        tad->stats.rxFramesNum++;
-        tad->stats.rxBytesCount += data->data_length;
-
-        /* Accumulate packet Rx rates for later averaging */
-        tad->rx_sum_rate += rate;
-    }
-    else
-    {
-        if (identity == TA_FRAME_ETHERNET_INTERESTING)
-        {
-            /*
-             * Store the period between the last and the current frame.
-             * There is not point storing more than TA_MAX_INTERVALS_IN_C1 periods,
-             * the traffic will be bursty or continuous.
-             */
-            if (tad->stats.txFramesNum < TA_MAX_INTERVALS_IN_C1)
-            {
-                u32 interval;
-                u32 index_in_intervals;
-
-                interval = timestamp - tad->tx_last_ts;
-                tad->tx_last_ts = timestamp;
-                index_in_intervals = (interval + TA_INTERVALS_STEP / 2 - 1) / TA_INTERVALS_STEP;
-
-                /* If the interval is interesting, update the t1_intervals count */
-                if (index_in_intervals <= TA_INTERVALS_NUM)
-                {
-                    unifi_trace(card->ospriv, UDBG5,
-                                "unifi_ta_sample: TX interval=%d index=%d\n",
-                                interval, index_in_intervals);
-                    tad->stats.intervals[index_in_intervals]++;
-                }
-            }
-        }
-
-        /* Update the Tx packet count... */
-        tad->stats.txFramesNum++;
-        /* ... and the number of bytes for throughput. */
-        tad->stats.txBytesCount += data->data_length;
-    }
-
-    /*
-     * If more than one second has elapsed since the last report, send
-     * another one.
-     */
-    /* Unsigned subtraction handles wrap-around from 0xFFFFFFFF to 0 */
-    time_delta = timestamp - tad->last_indication_time;
-    if (time_delta >= 1000)
-    {
-        /*
-         * rxFramesNum can be flashed in tas_reset_data() by another thread.
-         * Use a temp to avoid division by zero.
-         */
-        u32 temp_rxFramesNum;
-        temp_rxFramesNum = tad->stats.rxFramesNum;
-
-        /* Calculate this interval's mean frame Rx rate from the sum */
-        if (temp_rxFramesNum)
-        {
-            tad->stats.rxMeanRate = tad->rx_sum_rate / temp_rxFramesNum;
-        }
-        unifi_trace(card->ospriv, UDBG5,
-                    "unifi_ta_sample: RX fr=%lu, r=%u, sum=%lu, av=%lu\n",
-                    tad->stats.rxFramesNum, rate,
-                    tad->rx_sum_rate, tad->stats.rxMeanRate);
-
-        /*
-         * Send the information collected in the stats struct
-         * to the SME and reset the counters.
-         */
-        if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM)
-        {
-            u32 rxTcpThroughput = tad->ta_l4stats.rxTcpBytesCount / time_delta;
-            u32 txTcpThroughput = tad->ta_l4stats.txTcpBytesCount / time_delta;
-            u32 rxUdpThroughput = tad->ta_l4stats.rxUdpBytesCount / time_delta;
-            u32 txUdpThroughput = tad->ta_l4stats.txUdpBytesCount / time_delta;
-
-            unifi_ta_indicate_l4stats(card->ospriv,
-                                      rxTcpThroughput,
-                                      txTcpThroughput,
-                                      rxUdpThroughput,
-                                      txUdpThroughput
-                                      );
-        }
-        unifi_ta_indicate_sampling(card->ospriv, &tad->stats);
-        tas_reset_data(tad);
-        tad->last_indication_time = timestamp;
-    }
-} /* unifi_ta_sample() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  External API.
- *  unifi_ta_configure
- *
- *      Configures the TA module parameters.
- *
- *  Arguments:
- *      ta              The pointer to the TA module.
- *      config_type     The type of the configuration request
- *      config          Pointer to the configuration parameters.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code otherwise
- * ---------------------------------------------------------------------------
- */
-CsrResult unifi_ta_configure(card_t                               *card,
-                             CsrWifiRouterCtrlTrafficConfigType    config_type,
-                             const CsrWifiRouterCtrlTrafficConfig *config)
-{
-    ta_data_t *tad = &card->ta_sampling;
-
-    /* Reinitialise our data when we are reset */
-    if (config_type == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET)
-    {
-        /* Reset the stats to zero */
-        tas_reset_data(tad);
-
-        /* Reset the timer variables */
-        tad->tx_last_ts = 0;
-        tad->last_indication_time = 0;
-
-        return CSR_RESULT_SUCCESS;
-    }
-
-    if (config_type == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER)
-    {
-        tad->packet_filter = config->packetFilter;
-
-        if (tad->packet_filter & CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM)
-        {
-            tad->custom_filter = config->customFilter;
-        }
-
-        return CSR_RESULT_SUCCESS;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_ta_configure() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  External API.
- *  unifi_ta_classification
- *
- *      Configures the current TA classification.
- *
- *  Arguments:
- *      ta              The pointer to the TA module.
- *      traffic_type    The classification type
- *      period          The traffic period if the type is periodic
- *
- *  Returns:
- *      None
- * ---------------------------------------------------------------------------
- */
-void unifi_ta_classification(card_t                      *card,
-                             CsrWifiRouterCtrlTrafficType traffic_type,
-                             u16                    period)
-{
-    unifi_trace(card->ospriv, UDBG3,
-                "Changed current ta classification to: %d\n", traffic_type);
-
-    card->ta_sampling.traffic_type = traffic_type;
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_ta_sampling.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_ta_sampling.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_ta_sampling.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_ta_sampling.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,66 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     csr_wifi_hip_ta_sampling.h
- *
- *  PURPOSE:
- *      This file contains Traffic Analysis definitions common to the
- *      sampling and analysis modules.
- *
- * ---------------------------------------------------------------------------
- */
-#ifndef __TA_SAMPLING_H__
-#define __TA_SAMPLING_H__
-
-#include "csr_wifi_hip_unifi.h"
-
-typedef struct ta_l4stats
-{
-    u32 rxTcpBytesCount;
-    u32 txTcpBytesCount;
-    u32 rxUdpBytesCount;
-    u32 txUdpBytesCount;
-} ta_l4stats_t;
-
-/*
- * Context structure to preserve state between calls.
- */
-
-typedef struct ta_data
-{
-    /* Current packet filter configuration */
-    u16 packet_filter;
-
-    /* Current packet custom filter configuration */
-    CsrWifiRouterCtrlTrafficFilter custom_filter;
-
-    /* The timestamp of the last tx packet processed. */
-    u32 tx_last_ts;
-
-    /* The timestamp of the last packet processed. */
-    u32 last_indication_time;
-
-    /* Statistics */
-    CsrWifiRouterCtrlTrafficStats stats;
-
-    /* Current traffic classification */
-    CsrWifiRouterCtrlTrafficType traffic_type;
-
-    /* Sum of packet rx rates for this interval used to calculate mean */
-    u32    rx_sum_rate;
-    ta_l4stats_t ta_l4stats;
-} ta_data_t;
-
-
-void unifi_ta_sampling_init(card_t *card);
-
-#endif /* __TA_SAMPLING_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_udi.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_udi.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_udi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_udi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,173 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     csr_wifi_hip_card_udi.c
- *
- *  PURPOSE:
- *      Maintain a list of callbacks to log UniFi exchanges to one or more
- *      debug/monitoring client applications.
- *
- * NOTES:
- *      Just call the UDI driver log fn directly for now.
- *      When done properly, each open() on the UDI device will install
- *      a log function. We will call all log fns whenever a signal is written
- *      to or read form the UniFi.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/seq_file.h>
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_card.h"
-
-
-static void unifi_print_unsafe_sdio_status(card_t *card, struct seq_file *m)
-{
-#ifdef CSR_UNSAFE_SDIO_ACCESS
-	s32 iostate;
-	CsrResult r;
-	static const char *const states[] = {
-		"AWAKE", "DROWSY", "TORPID"
-	};
-#define SHARED_READ_RETRY_LIMIT 10
-	u8 b;
-
-	seq_printf(m, "Host State: %s\n", states[card->host_state]);
-
-	r = unifi_check_io_status(card, &iostate);
-	if (iostate == 1) {
-		seq_puts(m, remaining, "I/O Check: F1 disabled\n");
-        } else {
-		if (iostate == 1) {
-			seq_puts(m, "I/O Check: pending interrupt\n");
-
-		seq_printf(m, "BH reason interrupt = %d\n", card->bh_reason_unifi);
-		seq_printf(m, "BH reason host      = %d\n", card->bh_reason_host);
-
-		for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++) {
-			r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 2, &b);
-			if (r == CSR_RESULT_SUCCESS && !(b & 0x80)) {
-				seq_printf(m, "fhsr: %u (driver thinks is %u)\n",
-					   b, card->from_host_signals_r);
-				break;
-			}
-		}
-
-		iostate = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4);
-		seq_printf(m, "thsw: %u (driver thinks is %u)\n",
-			   iostate, card->to_host_signals_w);
-        }
-#endif
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_print_status
- *
- *      Print status info to given character buffer.
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-s32 unifi_print_status(card_t *card, struct seq_file *m)
-{
-	sdio_config_data_t *cfg;
-	u16 i, n;
-
-	i = n = 0;
-	seq_printf(m, "Chip ID %u\n", card->chip_id);
-	seq_printf(m, "Chip Version %04X\n", card->chip_version);
-	seq_printf(m, "HIP v%u.%u\n",
-		   (card->config_data.version >> 8) & 0xFF,
-		   card->config_data.version & 0xFF);
-	seq_printf(m, "Build %u: %s\n", card->build_id, card->build_id_string);
-
-	cfg = &card->config_data;
-
-	seq_printf(m, "sdio ctrl offset          %u\n", cfg->sdio_ctrl_offset);
-	seq_printf(m, "fromhost sigbuf handle    %u\n", cfg->fromhost_sigbuf_handle);
-	seq_printf(m, "tohost_sigbuf_handle      %u\n", cfg->tohost_sigbuf_handle);
-	seq_printf(m, "num_fromhost_sig_frags    %u\n", cfg->num_fromhost_sig_frags);
-	seq_printf(m, "num_tohost_sig_frags      %u\n", cfg->num_tohost_sig_frags);
-	seq_printf(m, "num_fromhost_data_slots   %u\n", cfg->num_fromhost_data_slots);
-	seq_printf(m, "num_tohost_data_slots     %u\n", cfg->num_tohost_data_slots);
-	seq_printf(m, "data_slot_size            %u\n", cfg->data_slot_size);
-
-	/* Added by protocol version 0x0001 */
-	seq_printf(m, "overlay_size              %u\n", cfg->overlay_size);
-
-	/* Added by protocol version 0x0300 */
-	seq_printf(m, "data_slot_round           %u\n", cfg->data_slot_round);
-	seq_printf(m, "sig_frag_size             %u\n", cfg->sig_frag_size);
-
-	/* Added by protocol version 0x0300 */
-	seq_printf(m, "tohost_sig_pad            %u\n", cfg->tohost_signal_padding);
-
-	seq_puts(m, "\nInternal state:\n");
-
-	seq_printf(m, "Last PHY PANIC: %04x:%04x\n",
-		   card->last_phy_panic_code, card->last_phy_panic_arg);
-	seq_printf(m, "Last MAC PANIC: %04x:%04x\n",
-		   card->last_mac_panic_code, card->last_mac_panic_arg);
-
-	seq_printf(m, "fhsr: %hu\n", (u16)card->from_host_signals_r);
-	seq_printf(m, "fhsw: %hu\n", (u16)card->from_host_signals_w);
-	seq_printf(m, "thsr: %hu\n", (u16)card->to_host_signals_r);
-	seq_printf(m, "thsw: %hu\n", (u16)card->to_host_signals_w);
-	seq_printf(m, "fh buffer contains: %d signals, %td bytes\n",
-		   card->fh_buffer.count,
-		   card->fh_buffer.ptr - card->fh_buffer.buf);
-
-	seq_puts(m, "paused: ");
-	for (i = 0; i < ARRAY_SIZE(card->tx_q_paused_flag); i++)
-		seq_printf(m, card->tx_q_paused_flag[i] ? "1" : "0");
-	seq_putc(m, '\n');
-
-	seq_printf(m, "fh command q: %u waiting, %u free of %u:\n",
-		   CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_command_queue),
-		   CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_command_queue),
-		   UNIFI_SOFT_COMMAND_Q_LENGTH);
-
-	for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
-		seq_printf(m, "fh traffic q[%u]: %u waiting, %u free of %u:\n",
-			   i,
-			   CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[i]),
-			   CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[i]),
-			   UNIFI_SOFT_TRAFFIC_Q_LENGTH);
-
-	seq_printf(m, "fh data slots free: %u\n",
-		   card->from_host_data ? CardGetFreeFromHostDataSlots(card) : 0);
-
-	seq_puts(m, "From host data slots:");
-	n = card->config_data.num_fromhost_data_slots;
-	for (i = 0; i < n && card->from_host_data; i++)
-		seq_printf(m, " %hu", (u16)card->from_host_data[i].bd.data_length);
-	seq_putc(m, '\n');
-
-	seq_puts(m, "To host data slots:");
-	n = card->config_data.num_tohost_data_slots;
-	for (i = 0; i < n && card->to_host_data; i++)
-		seq_printf(m, " %hu", (u16)card->to_host_data[i].data_length);
-	seq_putc(m, '\n');
-
-	unifi_print_unsafe_sdio_status(card, m);
-
-	seq_puts(m, "\nStats:\n");
-	seq_printf(m, "Total SDIO bytes: R=%u W=%u\n",
-		   card->sdio_bytes_read, card->sdio_bytes_written);
-
-	seq_printf(m, "Interrupts generated on card: %u\n", card->unifi_interrupt_seq);
-	return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifi.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifi.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,871 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *
- * FILE : csr_wifi_hip_unifi.h
- *
- * PURPOSE : Public API for the UniFi HIP core library.
- *
- * ---------------------------------------------------------------------------
- */
-#ifndef __CSR_WIFI_HIP_UNIFI_H__
-#define __CSR_WIFI_HIP_UNIFI_H__ 1
-
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-#include "csr_wifi_router_ctrl_prim.h"
-#include "csr_wifi_router_prim.h"
-#else
-#include "csr_time.h"
-#endif
-
-/* SDIO chip ID numbers */
-
-/* Manufacturer id */
-#define SDIO_MANF_ID_CSR              0x032a
-
-/* Device id */
-#define SDIO_CARD_ID_UNIFI_1          0x0001
-#define SDIO_CARD_ID_UNIFI_2          0x0002
-#define SDIO_CARD_ID_UNIFI_3          0x0007
-#define SDIO_CARD_ID_UNIFI_4          0x0008
-
-/* Function number for WLAN */
-#define SDIO_WLAN_FUNC_ID_UNIFI_1          0x0001
-#define SDIO_WLAN_FUNC_ID_UNIFI_2          0x0001
-#define SDIO_WLAN_FUNC_ID_UNIFI_3          0x0001
-#define SDIO_WLAN_FUNC_ID_UNIFI_4          0x0002
-
-/* Maximum SDIO bus clock supported. */
-#define UNIFI_SDIO_CLOCK_MAX_HZ    50000000  /* Hz */
-
-/*
- * Initialisation SDIO bus clock.
- *
- * The initialisation clock speed should be used from when the chip has been
- * reset until the first MLME-reset has been received (i.e. during firmware
- * initialisation), unless UNIFI_SDIO_CLOCK_SAFE_HZ applies.
- */
-#define UNIFI_SDIO_CLOCK_INIT_HZ    12500000 /* Hz */
-
-/*
- * Safe SDIO bus clock.
- *
- * The safe speed should be used when the chip is in deep sleep or
- * it's state is unknown (just after reset / power on).
- */
-#define UNIFI_SDIO_CLOCK_SAFE_HZ    1000000  /* Hz */
-
-/* I/O default block size to use for UniFi. */
-#define UNIFI_IO_BLOCK_SIZE     64
-
-#define UNIFI_WOL_OFF   0
-#define UNIFI_WOL_SDIO  1
-#define UNIFI_WOL_PIO   2
-
-/* The number of Tx traffic queues */
-#define UNIFI_NO_OF_TX_QS              4
-
-#define CSR_WIFI_HIP_RESERVED_HOST_TAG 0xFFFFFFFF
-
-/*
- * The number of slots in the from-host queues.
- *
- * UNIFI_SOFT_TRAFFIC_Q_LENGTH is the number of slots in the traffic queues
- * and there will be UNIFI_NO_OF_TX_QS of them.
- * Traffic queues are used for data packets.
- *
- * UNIFI_SOFT_COMMAND_Q_LENGTH is the number of slots in the command queue.
- * The command queue is used for MLME management requests.
- *
- * Queues are ring buffers and so must always have 1 unused slot.
- */
-#define UNIFI_SOFT_TRAFFIC_Q_LENGTH (20 + 1)
-#define UNIFI_SOFT_COMMAND_Q_LENGTH (16 + 1)
-
-#include "csr_framework_ext.h"  /* from the synergy porting folder */
-#include "csr_sdio.h"           /* from the synergy porting folder */
-#include "csr_macro.h"          /* from the synergy porting folder */
-#include "csr_wifi_result.h"
-
-/* Utility MACROS. Note that UNIFI_MAC_ADDRESS_CMP returns TRUE on success */
-#define UNIFI_MAC_ADDRESS_COPY(dst, src) \
-    do { (dst)[0] = (src)[0]; (dst)[1] = (src)[1]; \
-         (dst)[2] = (src)[2]; (dst)[3] = (src)[3]; \
-         (dst)[4] = (src)[4]; (dst)[5] = (src)[5]; \
-    } while (0)
-
-#define UNIFI_MAC_ADDRESS_CMP(addr1, addr2) \
-    (((addr1)[0] == (addr2)[0]) && ((addr1)[1] == (addr2)[1]) && \
-     ((addr1)[2] == (addr2)[2]) && ((addr1)[3] == (addr2)[3]) && \
-     ((addr1)[4] == (addr2)[4]) && ((addr1)[5] == (addr2)[5]))
-
-/* Traffic queue ordered according to priority
- * EAPOL/Uncontrolled port Queue should be the last
- */
-typedef enum
-{
-    UNIFI_TRAFFIC_Q_BK = 0,
-    UNIFI_TRAFFIC_Q_BE,
-    UNIFI_TRAFFIC_Q_VI,
-    UNIFI_TRAFFIC_Q_VO,
-    UNIFI_TRAFFIC_Q_EAPOL,    /* Non existent in HIP */
-    UNIFI_TRAFFIC_Q_MAX,      /* Non existent */
-    UNIFI_TRAFFIC_Q_MLME      /* Non existent */
-} unifi_TrafficQueue;
-
-/*
- * Structure describing a bulk data slot.
- * This structure is shared between the HIP core library and the OS
- * layer. See the definition of unifi_net_data_malloc() for more details.
- *
- * The data_length field is used to indicate empty/occupied state.
- * Needs to be defined before #include "unifi_os.h".
- */
-typedef struct _bulk_data_desc
-{
-    const u8 *os_data_ptr;
-    u32       data_length;
-    const void     *os_net_buf_ptr;
-    u32       net_buf_length;
-} bulk_data_desc_t;
-
-/* Structure of an entry in the Symbol Look Up Table (SLUT). */
-typedef struct _symbol
-{
-    u16 id;
-    u32 obj;
-} symbol_t;
-
-/*
- * Header files need to be included from the current directory,
- * the SME library, the synergy framework and the OS layer.
- * A thin OS layer needs to be implemented in the porting exercise.
- *
- * Note that unifi_os.h should be included only in unifi.h
- */
-
-#include "unifi_os.h"
-
-/*
- * Contains the HIP core definitions selected in the porting exercise, such as
- * UNIFI_PAD_BULK_DATA_TO_BLOCK_SIZE and UNIFI_PAD_SIGNALS_TO_BLOCK_SIZE.
- * Implemented in the OS layer, as part of the porting exersice.
- */
-#include "unifi_config.h"
-
-#include "csr_wifi_hip_signals.h" /* from this dir */
-
-/*
- * The card structure is an opaque pointer that is used to pass context
- * to the upper-edge API functions.
- */
-typedef struct card card_t;
-
-
-/*
- * This structure describes all of the bulk data that 'might' be
- * associated with a signal.
- */
-typedef struct _bulk_data_param
-{
-    bulk_data_desc_t d[UNIFI_MAX_DATA_REFERENCES];
-} bulk_data_param_t;
-
-
-/*
- * This structure describes the chip and HIP core lib
- * information that exposed to the OS layer.
- */
-typedef struct _card_info
-{
-    u16 chip_id;
-    u16 chip_version;
-    u32 fw_build;
-    u16 fw_hip_version;
-    u32 sdio_block_size;
-} card_info_t;
-
-
-/*
- * Mini-coredump definitions
- */
-/* Definition of XAP memory ranges used by the mini-coredump system.
- * Note that, these values are NOT the same as UNIFI_REGISTERS, etc
- * in unifihw.h which don't allow selection of register areas for each XAP.
- */
-typedef enum unifi_coredump_space
-{
-    UNIFI_COREDUMP_MAC_REG,
-    UNIFI_COREDUMP_PHY_REG,
-    UNIFI_COREDUMP_SH_DMEM,
-    UNIFI_COREDUMP_MAC_DMEM,
-    UNIFI_COREDUMP_PHY_DMEM,
-    UNIFI_COREDUMP_TRIGGER_MAGIC = 0xFEED
-} unifi_coredump_space_t;
-
-/* Structure used to request a register value from a mini-coredump buffer */
-typedef struct unifi_coredump_req
-{
-    /* From user */
-    s32               index;       /* 0=newest, -1=oldest */
-    unifi_coredump_space_t space;       /* memory space */
-    u32              offset;      /* register offset in space */
-    /* From driver */
-    u32 drv_build;                /* Driver build id */
-    u32 chip_ver;                 /* Chip version */
-    u32 fw_ver;                   /* Firmware version */
-    s32  requestor;                /* Requestor: 0=auto dump, 1=manual */
-    u32 timestamp;                /* time of capture by driver */
-    u32 serial;                   /* capture serial number */
-    s32  value;                    /* register value */
-} unifi_coredump_req_t;                 /* mini-coredumped reg value request */
-
-
-/**
- * @defgroup upperedge Upper edge API
- *
- * The following functions are implemented in the HIP core lib.
- */
-
-/**
- *
- * Initialise the HIP core lib.
- * Note that the OS layer must initialise the SDIO glue layer and obtain
- * an SDIO function context, prior to this call.
- *
- * @param sdiopriv the SDIO function context.
- *
- * @param ospriv the OS layer context.
- *
- * @return \p card_t the HIP core lib API context.
- *
- * @ingroup upperedge
- */
-card_t* unifi_alloc_card(CsrSdioFunction *sdiopriv, void *ospriv);
-
-
-/**
- *
- * Initialise the UniFi chip.
- *
- * @param card the HIP core lib API context.
- *
- * @param led_mask the led mask to apply to UniFi.
- *
- * @return \b 0 if UniFi is initialized.
- *
- * @return \b -CSR_EIO if an I/O error occurred while initializing UniFi
- *
- * @return \b -CSR_ENODEV if the card is no longer present.
- *
- * @ingroup upperedge
- */
-CsrResult unifi_init_card(card_t *card, s32 led_mask);
-
-/**
- *
- * De-Initialise the HIP core lib.
- *
- * @param card the HIP core lib API context.
- *
- * @ingroup upperedge
- */
-void unifi_free_card(card_t *card);
-
-/**
- *
- * Cancel all the signals pending in the HIP core lib.
- * Normally used during a system suspend when the power is retained on UniFi.
- *
- * @param card the HIP core lib API context.
- *
- * @ingroup upperedge
- */
-void unifi_cancel_pending_signals(card_t *card);
-
-/**
- *
- * Send a signal to UniFi.
- * Normally it is called from unifi_sys_hip_req() and the OS layer
- * Tx data plane.
- *
- * Note that the bulkdata buffers ownership is passed to the HIP core lib.
- * These buffers must be allocated using unifi_net_data_malloc().
- *
- * @param card the HIP core lib API context.
- *
- * @param sigptr pointer to the signal.
- *
- * @param siglen size of the signal.
- *
- * @param bulkdata pointer to the bulk data associated with the signal.
- *
- * @return \b 0 signal is sent.
- *
- * @return \b -CSR_EIO if an error occurred while sending the signal
- *
- * @return \b -CSR_ENODEV if the card is no longer present.
- *
- * @ingroup upperedge
- */
-CsrResult unifi_send_signal(card_t *card, const u8 *sigptr,
-                            u32 siglen,
-                            const bulk_data_param_t *bulkdata);
-
-/**
- *
- * Check if the HIP core lib has resources to send a signal.
- * Normally there no need to use this function.
- *
- * @param card the HIP core lib API context.
- *
- * @param sigptr pointer to the signal.
- *
- * @return \b 0 if there are resources for the signal.
- *
- * @return \b -CSR_ENOSPC if there are not enough resources
- *
- * @ingroup upperedge
- */
-CsrResult unifi_send_resources_available(card_t *card, const u8 *sigptr);
-
-/**
- *
- * Read the UniFi chip and the HIP core lib information.
- *
- * @param card the HIP core lib API context.
- *
- * @param card_info pointer to save the information.
- *
- * @ingroup upperedge
- */
-void unifi_card_info(card_t *card, card_info_t *card_info);
-
-/**
- *
- * Print the UniFi I/O and Interrupt status.
- * Normally it is used for debug purposes only.
- *
- * @param card the HIP core lib API context.
-
- * @param status buffer for the chip status
- *
- * @return \b 0 if the check was performed.
- *
- * @return \b -CSR_EIO if an error occurred while checking the status.
- *
- * @return \b -CSR_ENODEV if the card is no longer present.
- *
- * @ingroup upperedge
- */
-CsrResult unifi_check_io_status(card_t *card, s32 *status);
-
-
-/**
- *
- * Run the HIP core lib Botton-Half.
- * Whenever the HIP core lib want this function to be called
- * by the OS layer, it calls unifi_run_bh().
- *
- * @param card the HIP core lib API context.
- *
- * @param remaining pointer to return the time (in msecs) that this function
- * should be re-scheduled. A return value of 0 means that no re-scheduling
- * is required. If unifi_bh() is called before the timeout expires,
- * the caller must pass in the remaining time.
- *
- * @return \b 0 if no error occurred.
- *
- * @return \b -CSR_ENODEV if the card is no longer present.
- *
- * @return \b -CSR_E* if an error occurred while running the bottom half.
- *
- * @ingroup upperedge
- */
-CsrResult unifi_bh(card_t *card, u32 *remaining);
-
-
-/**
- * UniFi Low Power Mode (Deep Sleep Signaling)
- *
- * unifi_low_power_mode defines the UniFi Deep Sleep Signaling status.
- * Use with unifi_configure_low_power_mode() to enable/disable
- * the Deep Sleep Signaling.
- */
-enum unifi_low_power_mode
-{
-    UNIFI_LOW_POWER_DISABLED,
-    UNIFI_LOW_POWER_ENABLED
-};
-
-/**
- * Periodic Wake Host Mode
- *
- * unifi_periodic_wake_mode defines the Periodic Wake Host Mode.
- * It can only be set to UNIFI_PERIODIC_WAKE_HOST_ENABLED if
- * low_power_mode == UNIFI_LOW_POWER_ENABLED.
- */
-enum unifi_periodic_wake_mode
-{
-    UNIFI_PERIODIC_WAKE_HOST_DISABLED,
-    UNIFI_PERIODIC_WAKE_HOST_ENABLED
-};
-
-/**
- *
- * Run the HIP core lib Botton-Half.
- * Whenever the HIP core lib want this function to be called
- * by the OS layer, it calls unifi_run_bh().
- *
- * Typically, the SME is responsible for configuring these parameters,
- * so unifi_sys_configure_power_mode_req() is usually implemented
- * as a direct call to unifi_configure_low_power_mode().
- *
- * Note: When polling mode is used instead of interrupts,
- * low_power_mode must never be set to UNIFI_LOW_POWER_ENABLED.
- *
- * @param card the HIP core lib API context.
- *
- * @param low_power_mode the Low Power Mode.
- *
- * @param periodic_wake_mode the Periodic Wake Mode.
- *
- * @return \b 0 if no error occurred.
- *
- * @return \b -CSR_E* if the request failed.
- *
- * @ingroup upperedge
- */
-CsrResult unifi_configure_low_power_mode(card_t                       *card,
-                                         enum unifi_low_power_mode     low_power_mode,
-                                         enum unifi_periodic_wake_mode periodic_wake_mode);
-
-/**
- *
- * Forces the UniFi chip to enter a Deep Sleep state.
- * This is normally called by the OS layer when the platform suspends.
- *
- * Note that if the UniFi Low Power Mode is disabled this call fails.
- *
- * @param card the HIP core lib API context.
- *
- * @return \b 0 if no error occurred.
- *
- * @return \b -CSR_ENODEV if the card is no longer present.
- *
- * @return \b -CSR_E* if the request failed.
- *
- * @ingroup upperedge
- */
-CsrResult unifi_force_low_power_mode(card_t *card);
-
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-/**
- * Configure the Traffic Analysis sampling
- *
- * Enable or disable statistics gathering.
- * Enable or disable particular packet detection.
- *
- * @param card the HIP core context
- * @param config_type the item to configure
- * @param config pointer to struct containing config info
- *
- * @return \b 0 if configuration was successful
- *
- * @return \b -CSR_EINVAL if a parameter had an invalid value
- *
- * @ingroup upperedge
- */
-CsrResult unifi_ta_configure(card_t                               *card,
-                             CsrWifiRouterCtrlTrafficConfigType    config_type,
-                             const CsrWifiRouterCtrlTrafficConfig *config);
-
-/**
- * Pass a packet for Traffic Analysis sampling
- *
- * @param card the HIP core context
- * @param direction the direction (Rx or Tx) of the frame.
- * @param data pointer to bulkdata struct containing the packet
- * @param saddr the source address of the packet
- * @param sta_macaddr the MAC address of the UniFi chip
- * @param timestamp the current time in msecs
- *
- * @ingroup upperedge
- */
-void unifi_ta_sample(card_t                            *card,
-                     CsrWifiRouterCtrlProtocolDirection direction,
-                     const bulk_data_desc_t            *data,
-                     const u8                    *saddr,
-                     const u8                    *sta_macaddr,
-                     u32                          timestamp,
-                     u16                          rate);
-
-/**
- * Notify the HIP core lib for a detected Traffic Classification.
- * Typically, the SME is responsible for configuring these parameters,
- * so unifi_sys_traffic_classification_req() is usually implemented
- * as a direct call to unifi_ta_classification().
- *
- * @param card the HIP core context.
- * @param traffic_type the detected traffic type.
- * @param period The detected period of the traffic.
- *
- * @ingroup upperedge
- */
-void unifi_ta_classification(card_t                      *card,
-                             CsrWifiRouterCtrlTrafficType traffic_type,
-                             u16                    period);
-
-#endif
-/**
- * Use software to hard reset the chip.
- * This is a subset of the unifi_init_card() functionality and should
- * only be used only to reset a paniced chip before a coredump is taken.
- *
- * @param card the HIP core context.
- *
- * @ingroup upperedge
- */
-CsrResult unifi_card_hard_reset(card_t *card);
-
-
-CsrResult unifi_card_readn(card_t *card, u32 unifi_addr, void *pdata, u16 len);
-CsrResult unifi_card_read16(card_t *card, u32 unifi_addr, u16 *pdata);
-CsrResult unifi_card_write16(card_t *card, u32 unifi_addr, u16 data);
-
-
-enum unifi_dbg_processors_select
-{
-    UNIFI_PROC_MAC,
-    UNIFI_PROC_PHY,
-    UNIFI_PROC_BT,
-    UNIFI_PROC_BOTH,
-    UNIFI_PROC_INVALID
-};
-
-CsrResult unifi_card_stop_processor(card_t *card, enum unifi_dbg_processors_select which);
-
-/**
- * Call-outs from the HIP core lib to the OS layer.
- * The following functions need to be implemented during the porting exercise.
- */
-
-/**
- * Selects appropriate queue according to priority
- * Helps maintain uniformity in queue selection between the HIP
- * and the OS layers.
- *
- * @param priority priority of the packet
- *
- * @return \b Traffic queue to which a packet of this priority belongs
- *
- * @ingroup upperedge
- */
-unifi_TrafficQueue
-unifi_frame_priority_to_queue(CSR_PRIORITY priority);
-
-/**
- * Returns the priority corresponding to a particular Queue when that is used
- * when downgrading a packet to a lower AC.
- * Helps maintain uniformity in queue - priority mapping between the HIP
- * and the OS layers.
- *
- * @param queue
- *
- * @return \b Highest priority corresponding to this queue
- *
- * @ingroup upperedge
- */
-CSR_PRIORITY unifi_get_default_downgrade_priority(unifi_TrafficQueue queue);
-
-/**
- *
- * Flow control callbacks.
- * unifi_pause_xmit() is called when the HIP core lib does not have any
- * resources to store data packets. The OS layer needs to pause
- * the Tx data plane until unifi_restart_xmit() is called.
- *
- * @param ospriv the OS layer context.
- *
- * @ingroup upperedge
- */
-void unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue);
-void unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue);
-
-/**
- *
- * Request to run the Bottom-Half.
- * The HIP core lib calls this function to request that unifi_bh()
- * needs to be run by the OS layer. It can be called anytime, i.e.
- * when the unifi_bh() is running.
- * Since unifi_bh() is not re-entrant, usually unifi_run_bh() sets
- * an event to a thread that schedules a call to unifi_bh().
- *
- * @param ospriv the OS layer context.
- *
- * @ingroup upperedge
- */
-CsrResult unifi_run_bh(void *ospriv);
-
-/**
- *
- * Delivers a signal received from UniFi to the OS layer.
- * Normally, the data signals should be delivered to the data plane
- * and all the rest to the SME (unifi_sys_hip_ind()).
- *
- * Note that the OS layer is responsible for freeing the bulkdata
- * buffers, using unifi_net_data_free().
- *
- * @param ospriv the OS layer context.
- *
- * @param sigptr pointer to the signal.
- *
- * @param siglen size of the signal.
- *
- * @param bulkdata pointer to the bulk data associated with the signal.
- *
- * @ingroup upperedge
- */
-void unifi_receive_event(void *ospriv,
-                         u8 *sigdata, u32 siglen,
-                         const bulk_data_param_t *bulkdata);
-
-#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
-/**
- *
- * Used to reque the failed ma packet request back to hal queues
- *
- * @param ospriv the OS layer context.
- *
- * @param host_tag host tag for the packet to requeue.
- *
- * @param bulkDataDesc pointer to the bulk data.
- *
- * @ingroup upperedge
- */
-CsrResult unifi_reque_ma_packet_request(void *ospriv, u32 host_tag,
-                                        u16 status,
-                                        bulk_data_desc_t *bulkDataDesc);
-
-#endif
-typedef struct
-{
-    u16 free_fh_sig_queue_slots[UNIFI_NO_OF_TX_QS];
-    u16 free_fh_bulkdata_slots;
-    u16 free_fh_fw_slots;
-} unifi_HipQosInfo;
-
-void unifi_get_hip_qos_info(card_t *card, unifi_HipQosInfo *hipqosinfo);
-
-
-/**
- * Functions that read a portion of a firmware file.
- *
- * Note: If the UniFi chip runs the f/w from ROM, the HIP core may never
- * call these functions. Also, the HIP core may call these functions even if
- * a f/w file is not available. In this case, it is safe to fail the request.
- */
-#define UNIFI_FW_STA    1   /* Identify STA firmware file */
-
-/**
- *
- * Ask the OS layer to initialise a read from a f/w file.
- *
- * @param ospriv the OS layer context.
- *
- * @param is_fw if 0 the request if for the loader file, if 1 the request
- * is for a f/w file.
- *
- * @param info a card_info_t structure containing versions information.
- * Note that some members of the structure may not be initialised.
- *
- * @return \p NULL if the file is not available, or a pointer which contains
- * OS specific information for the file (typically the contents of the file)
- * that the HIP core uses when calling unifi_fw_read() and unifi_fw_read_stop()
- *
- * @ingroup upperedge
- */
-void* unifi_fw_read_start(void *ospriv, s8 is_fw, const card_info_t *info);
-
-/**
- *
- * Ask the OS layer to return a portion from a f/w file.
- *
- * @param ospriv the OS layer context.
- *
- * @param arg the OS pointer returned by unifi_fw_read_start().
- *
- * @param offset the offset in the f/w file to read the read from.
- *
- * @param buf the buffer to store the returned data.
- *
- * @param len the size in bytes of the requested read.
- *
- * @ingroup upperedge
- */
-s32 unifi_fw_read(void *ospriv, void *arg, u32 offset, void *buf, u32 len);
-
-/**
- *
- * Ask the OS layer to finish reading from a f/w file.
- *
- * @param ospriv the OS layer context.
- *
- * @param dlpriv the OS pointer returned by unifi_fw_read_start().
- *
- * @ingroup upperedge
- */
-void unifi_fw_read_stop(void *ospriv, void *dlpriv);
-
-/**
- *
- * Ask OS layer for a handle to a dynamically allocated firmware buffer
- * (primarily intended for production test images which may need conversion)
- *
- * @param ospriv the OS layer context.
- *
- * @param fwbuf pointer to dynamically allocated buffer
- *
- * @param len length of provided buffer in bytes
- *
- * @ingroup upperedge
- */
-void* unifi_fw_open_buffer(void *ospriv, void *fwbuf, u32 len);
-
-/**
- *
- * Release a handle to a dynamically allocated firmware buffer
- * (primarily intended for production test images which may need conversion)
- *
- * @param ospriv the OS layer context.
- *
- * @param fwbuf pointer to dynamically allocated buffer
- *
- * @ingroup upperedge
- */
-void unifi_fw_close_buffer(void *ospriv, void *fwbuf);
-
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-/*
- * Driver must provide these.
- *
- * A simple implementation will just call
- * unifi_sys_traffic_protocol_ind() or unifi_sys_traffic_classification_ind()
- * respectively. See sme_csr_userspace/sme_userspace.c.
- */
-/**
- *
- * Indicates a detected packet of type packet_type.
- * Typically, this information is processed by the SME so
- * unifi_ta_indicate_protocol() needs to schedule a call to
- * unifi_sys_traffic_protocol_ind().
- *
- * @param ospriv the OS layer context.
- *
- * @param packet_type the detected packet type.
- *
- * @param direction the direction of the packet (Rx, Tx).
- *
- * @param src_addr the source address of the packet.
- *
- * @ingroup upperedge
- */
-void unifi_ta_indicate_protocol(void                              *ospriv,
-                                CsrWifiRouterCtrlTrafficPacketType packet_type,
-                                CsrWifiRouterCtrlProtocolDirection direction,
-                                const CsrWifiMacAddress           *src_addr);
-
-/**
- *
- * Indicates statistics for the sample data over a period.
- * Typically, this information is processed by the SME so
- * unifi_ta_indicate_sampling() needs to schedule a call to
- * unifi_sys_traffic_sample_ind().
- *
- * @param ospriv the OS layer context.
- *
- * @param stats the pointer to the structure that contains the statistics.
- *
- * @ingroup upperedge
- */
-void unifi_ta_indicate_sampling(void *ospriv, CsrWifiRouterCtrlTrafficStats *stats);
-void unifi_ta_indicate_l4stats(void     *ospriv,
-                               u32 rxTcpThroughput,
-                               u32 txTcpThroughput,
-                               u32 rxUdpThroughput,
-                               u32 txUdpThroughput);
-#endif
-
-void unifi_rx_queue_flush(void *ospriv);
-
-/**
- * Call-out from the SDIO glue layer.
- *
- * The glue layer needs to call unifi_sdio_interrupt_handler() every time
- * an interrupts occurs.
- *
- * @param card the HIP core context.
- *
- * @ingroup bottomedge
- */
-void unifi_sdio_interrupt_handler(card_t *card);
-
-
-/* HELPER FUNCTIONS */
-
-/*
- * unifi_init() and unifi_download() implement a subset of unifi_init_card functionality
- * that excludes HIP initialization.
- */
-CsrResult unifi_init(card_t *card);
-CsrResult unifi_download(card_t *card, s32 led_mask);
-
-/*
- * unifi_start_processors() ensures both on-chip processors are running
- */
-CsrResult unifi_start_processors(card_t *card);
-
-CsrResult unifi_capture_panic(card_t *card);
-
-/*
- * Configure HIP interrupt processing mode
- */
-#define CSR_WIFI_INTMODE_DEFAULT        0
-#define CSR_WIFI_INTMODE_RUN_BH_ONCE    1       /* Run BH once per interrupt */
-
-void unifi_set_interrupt_mode(card_t *card, u32 mode);
-
-/*
- * unifi_request_max_clock() requests that max SDIO clock speed is set at the
- * next suitable opportunity.
- */
-void unifi_request_max_sdio_clock(card_t *card);
-
-
-/* Functions to lookup bulk data command names. */
-const char* lookup_bulkcmd_name(u16 id);
-
-/* Function to log HIP's global debug buffer */
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-void unifi_debug_buf_dump(void);
-void unifi_debug_log_to_buf(const char *fmt, ...);
-void unifi_debug_hex_to_buf(const char *buff, u16 length);
-#endif
-
-/* Mini-coredump utility functions */
-CsrResult unifi_coredump_get_value(card_t *card, struct unifi_coredump_req *req);
-CsrResult unifi_coredump_capture(card_t *card, struct unifi_coredump_req *req);
-CsrResult unifi_coredump_request_at_next_reset(card_t *card, s8 enable);
-CsrResult unifi_coredump_init(card_t *card, u16 num_dump_buffers);
-void unifi_coredump_free(card_t *card);
-
-#endif /* __CSR_WIFI_HIP_UNIFI_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifihw.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifihw.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifihw.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifihw.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,59 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *
- * File: csr_wifi_hip_unifihw.h
- *
- *      Definitions of various chip registers, addresses, values etc.
- *
- * ---------------------------------------------------------------------------
- */
-#ifndef __UNIFIHW_H__
-#define __UNIFIHW_H__ 1
-
-/* Symbol Look Up Table fingerprint. IDs are in sigs.h */
-#define SLUT_FINGERPRINT        0xD397
-
-
-/* Values of LoaderOperation */
-#define UNIFI_LOADER_IDLE       0x00
-#define UNIFI_LOADER_COPY       0x01
-#define UNIFI_LOADER_ERROR_MASK 0xF0
-
-/* Values of BootLoaderOperation */
-#define UNIFI_BOOT_LOADER_IDLE       0x00
-#define UNIFI_BOOT_LOADER_RESTART    0x01
-#define UNIFI_BOOT_LOADER_PATCH      0x02
-#define UNIFI_BOOT_LOADER_LOAD_STA   0x10
-#define UNIFI_BOOT_LOADER_LOAD_PTEST 0x11
-
-
-/* Memory spaces encoded in top byte of Generic Pointer type */
-#define UNIFI_SH_DMEM   0x01    /* Shared Data Memory */
-#define UNIFI_EXT_FLASH 0x02    /* External FLASH */
-#define UNIFI_EXT_SRAM  0x03    /* External SRAM */
-#define UNIFI_REGISTERS 0x04    /* Registers */
-#define UNIFI_PHY_DMEM  0x10    /* PHY Data Memory */
-#define UNIFI_PHY_PMEM  0x11    /* PHY Program Memory */
-#define UNIFI_PHY_ROM   0x12    /* PHY ROM */
-#define UNIFI_MAC_DMEM  0x20    /* MAC Data Memory */
-#define UNIFI_MAC_PMEM  0x21    /* MAC Program Memory */
-#define UNIFI_MAC_ROM   0x22    /* MAC ROM */
-#define UNIFI_BT_DMEM   0x30    /* BT Data Memory */
-#define UNIFI_BT_PMEM   0x31    /* BT Program Memory */
-#define UNIFI_BT_ROM    0x32    /* BT ROM */
-
-#define UNIFI_MAKE_GP(R, O)  (((UNIFI_ ## R) << 24) | (O))
-#define UNIFI_GP_OFFSET(GP)  ((GP) & 0xFFFFFF)
-#define UNIFI_GP_SPACE(GP)   (((GP) >> 24) & 0xFF)
-
-#endif /* __UNIFIHW_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include "csr_wifi_hip_unifi.h"
-
-struct sig_name {
-	s16 id;
-	const char *name;
-};
-
-static const struct sig_name Unifi_bulkcmd_names[] = {
-	{ 0, "SignalCmd" },
-	{ 1, "CopyToHost" },
-	{ 2, "CopyToHostAck" },
-	{ 3, "CopyFromHost" },
-	{ 4, "CopyFromHostAck" },
-	{ 5, "ClearSlot" },
-	{ 6, "CopyOverlay" },
-	{ 7, "CopyOverlayAck" },
-	{ 8, "CopyFromHostAndClearSlot" },
-	{ 15, "Padding" }
-};
-
-const char *lookup_bulkcmd_name(u16 id)
-{
-	if (id < 9)
-		return Unifi_bulkcmd_names[id].name;
-	if (id == 15)
-		return "Padding";
-
-	return "UNKNOWN";
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifi_udi.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifi_udi.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifi_udi.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifi_udi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     csr_wifi_hip_unifi_udi.h
- *
- *  PURPOSE:
- *      Declarations and definitions for the UniFi Debug Interface.
- *
- * ---------------------------------------------------------------------------
- */
-#ifndef __CSR_WIFI_HIP_UNIFI_UDI_H__
-#define __CSR_WIFI_HIP_UNIFI_UDI_H__
-
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_signals.h"
-
-
-/*
- * Support for tracing the wire protocol.
- */
-enum udi_log_direction
-{
-    UDI_LOG_FROM_HOST   = 0x0000,
-    UDI_LOG_TO_HOST     = 0x0001
-};
-
-typedef void (*udi_func_t)(void *ospriv, u8 *sigdata,
-                           u32 signal_len,
-                           const bulk_data_param_t *bulkdata,
-                           enum udi_log_direction dir);
-
-CsrResult unifi_set_udi_hook(card_t *card, udi_func_t udi_fn);
-CsrResult unifi_remove_udi_hook(card_t *card, udi_func_t udi_fn);
-
-
-/*
- * Function to print current status info to a string.
- * This is used in the linux /proc interface and might be useful
- * in other systems.
- */
-s32 unifi_print_status(card_t *card, struct seq_file *m);
-
-#endif /* __CSR_WIFI_HIP_UNIFI_UDI_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifiversion.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifiversion.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_unifiversion.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_unifiversion.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     unifiversion.h
- *
- *  PURPOSE:
- *      Version information for the portable UniFi driver.
- *
- * ---------------------------------------------------------------------------
- */
-
-#ifndef __UNIFIVERSION_H__
-#define __UNIFIVERSION_H__
-
-/*
- * The minimum version of Host Interface Protocol required by the driver.
- */
-#define UNIFI_HIP_MAJOR_VERSION 9
-#define UNIFI_HIP_MINOR_VERSION 1
-
-#endif /* __UNIFIVERSION_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_xbv.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_xbv.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_xbv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_xbv.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1076 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- * FILE: csr_wifi_hip_xbv.c
- *
- * PURPOSE:
- *      Routines for downloading firmware to UniFi.
- *
- *      UniFi firmware files use a nested TLV (Tag-Length-Value) format.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/slab.h>
-
-#ifdef CSR_WIFI_XBV_TEST
-/* Standalone test harness */
-#include "unifi_xbv.h"
-#include "csr_wifi_hip_unifihw.h"
-#else
-/* Normal driver build */
-#include "csr_wifi_hip_unifiversion.h"
-#include "csr_wifi_hip_card.h"
-#define DBG_TAG(t)
-#endif
-
-#include "csr_wifi_hip_xbv.h"
-
-#define STREAM_CHECKSUM 0x6d34        /* Sum of uint16s in each patch stream */
-
-/* XBV sizes used in patch conversion
- */
-#define PTDL_MAX_SIZE 2048            /* Max bytes allowed per PTDL */
-#define PTDL_HDR_SIZE (4 + 2 + 6 + 2) /* sizeof(fw_id, sec_len, patch_cmd, csum) */
-
-/* Struct to represent a buffer for reading firmware file */
-
-typedef struct
-{
-    void      *dlpriv;
-    s32   ioffset;
-    fwreadfn_t iread;
-} ct_t;
-
-/* Struct to represent a TLV field */
-typedef struct
-{
-    char t_name[4];
-    u32     t_len;
-} tag_t;
-
-
-#define TAG_EQ(i, v)    (((i)[0] == (v)[0]) &&  \
-                         ((i)[1] == (v)[1]) &&  \
-                         ((i)[2] == (v)[2]) &&  \
-                         ((i)[3] == (v)[3]))
-
-/* We create a small stack on the stack that contains an enum
- * indicating the containing list segments, and the offset at which
- * those lists end.  This enables a lot more error checking. */
-typedef enum
-{
-    xbv_xbv1,
-    /*xbv_info,*/
-    xbv_fw,
-    xbv_vers,
-    xbv_vand,
-    xbv_ptch,
-    xbv_other
-} xbv_container;
-
-#define XBV_STACK_SIZE 6
-#define XBV_MAX_OFFS   0x7fffffff
-
-typedef struct
-{
-    struct
-    {
-        xbv_container container;
-        s32      ioffset_end;
-    } s[XBV_STACK_SIZE];
-    u32 ptr;
-} xbv_stack_t;
-
-static s32 read_tag(card_t *card, ct_t *ct, tag_t *tag);
-static s32 read_bytes(card_t *card, ct_t *ct, void *buf, u32 len);
-static s32 read_uint(card_t *card, ct_t *ct, u32 *u, u32 len);
-static s32 xbv_check(xbv1_t *fwinfo, const xbv_stack_t *stack,
-                          xbv_mode new_mode, xbv_container old_cont);
-static s32 xbv_push(xbv1_t *fwinfo, xbv_stack_t *stack,
-                         xbv_mode new_mode, xbv_container old_cont,
-                         xbv_container new_cont, u32 ioff);
-
-static u32 write_uint16(void *buf, const u32 offset,
-                              const u16 val);
-static u32 write_uint32(void *buf, const u32 offset,
-                              const u32 val);
-static u32 write_bytes(void *buf, const u32 offset,
-                             const u8 *data, const u32 len);
-static u32 write_tag(void *buf, const u32 offset,
-                           const char *tag_str);
-static u32 write_chunk(void *buf, const u32 offset,
-                             const char *tag_str,
-                             const u32 payload_len);
-static u16 calc_checksum(void *buf, const u32 offset,
-                               const u32 bytes_len);
-static u32 calc_patch_size(const xbv1_t *fwinfo);
-
-static u32 write_xbv_header(void *buf, const u32 offset,
-                                  const u32 file_payload_length);
-static u32 write_ptch_header(void *buf, const u32 offset,
-                                   const u32 fw_id);
-static u32 write_patchcmd(void *buf, const u32 offset,
-                                const u32 dst_genaddr, const u16 len);
-static u32 write_reset_ptdl(void *buf, const u32 offset,
-                                  const xbv1_t *fwinfo, u32 fw_id);
-static u32 write_fwdl_to_ptdl(void *buf, const u32 offset,
-                                    fwreadfn_t readfn, const struct FWDL *fwdl,
-                                    const void *fw_buf, const u32 fw_id,
-                                    void *rdbuf);
-
-/*
- * ---------------------------------------------------------------------------
- *  parse_xbv1
- *
- *      Scan the firmware file to find the TLVs we are interested in.
- *      Actions performed:
- *        - check we support the file format version in VERF
- *      Store these TLVs if we have a firmware image:
- *        - SLTP Symbol Lookup Table Pointer
- *        - FWDL firmware download segments
- *        - FWOL firmware overlay segment
- *        - VMEQ Register probe tests to verify matching h/w
- *      Store these TLVs if we have a patch file:
- *        - FWID the firmware build ID that this file patches
- *        - PTDL The actual patches
- *
- *      The structure pointed to by fwinfo is cleared and
- *      'fwinfo->mode' is set to 'unknown'.  The 'fwinfo->mode'
- *      variable is set to 'firmware' or 'patch' once we know which
- *      sort of XBV file we have.
- *
- *  Arguments:
- *      readfn          Pointer to function to call to read from the file.
- *      dlpriv          Opaque pointer arg to pass to readfn.
- *      fwinfo          Pointer to fwinfo struct to fill in.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR error code on failure
- * ---------------------------------------------------------------------------
- */
-CsrResult xbv1_parse(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo)
-{
-    ct_t ct;
-    tag_t tag;
-    xbv_stack_t stack;
-
-    ct.dlpriv = dlpriv;
-    ct.ioffset = 0;
-    ct.iread = readfn;
-
-    memset(fwinfo, 0, sizeof(xbv1_t));
-    fwinfo->mode = xbv_unknown;
-
-    /* File must start with XBV1 triplet */
-    if (read_tag(card, &ct, &tag) <= 0)
-    {
-        unifi_error(NULL, "File is not UniFi firmware\n");
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    DBG_TAG(tag.t_name);
-
-    if (!TAG_EQ(tag.t_name, "XBV1"))
-    {
-        unifi_error(NULL, "File is not UniFi firmware (%s)\n", tag.t_name);
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    stack.ptr = 0;
-    stack.s[stack.ptr].container = xbv_xbv1;
-    stack.s[stack.ptr].ioffset_end = XBV_MAX_OFFS;
-
-    /* Now scan the file */
-    while (1)
-    {
-        s32 n;
-
-        n = read_tag(card, &ct, &tag);
-        if (n < 0)
-        {
-            unifi_error(NULL, "No tag\n");
-            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-        }
-        if (n == 0)
-        {
-            /* End of file */
-            break;
-        }
-
-        DBG_TAG(tag.t_name);
-
-        /* File format version */
-        if (TAG_EQ(tag.t_name, "VERF"))
-        {
-            u32 version;
-
-            if (xbv_check(fwinfo, &stack, xbv_unknown, xbv_xbv1) ||
-                (tag.t_len != 2) ||
-                read_uint(card, &ct, &version, 2))
-            {
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            if (version != 0)
-            {
-                unifi_error(NULL, "Unsupported firmware file version: %d.%d\n",
-                            version >> 8, version & 0xFF);
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-        }
-        else if (TAG_EQ(tag.t_name, "LIST"))
-        {
-            char name[4];
-            u32 list_end;
-
-            list_end = ct.ioffset + tag.t_len;
-
-            if (read_bytes(card, &ct, name, 4))
-            {
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-
-            DBG_TAG(name);
-            if (TAG_EQ(name, "FW  "))
-            {
-                if (xbv_push(fwinfo, &stack, xbv_firmware, xbv_xbv1, xbv_fw, list_end))
-                {
-                    return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-                }
-            }
-            else if (TAG_EQ(name, "VERS"))
-            {
-                if (xbv_push(fwinfo, &stack, xbv_firmware, xbv_fw, xbv_vers, list_end) ||
-                    (fwinfo->vers.num_vand != 0))
-                {
-                    return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-                }
-            }
-            else if (TAG_EQ(name, "VAND"))
-            {
-                struct VAND *vand;
-
-                if (xbv_push(fwinfo, &stack, xbv_firmware, xbv_vers, xbv_vand, list_end) ||
-                    (fwinfo->vers.num_vand >= MAX_VAND))
-                {
-                    return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-                }
-
-                /* Get a new VAND */
-                vand = fwinfo->vand + fwinfo->vers.num_vand++;
-
-                /* Fill it in */
-                vand->first = fwinfo->num_vmeq;
-                vand->count = 0;
-            }
-            else if (TAG_EQ(name, "PTCH"))
-            {
-                if (xbv_push(fwinfo, &stack, xbv_patch, xbv_xbv1, xbv_ptch, list_end))
-                {
-                    return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-                }
-            }
-            else
-            {
-                /* Skip over any other lists.  We dont bother to push
-                 * the new list type now as we would only pop it at
-                 * the end of the outer loop. */
-                ct.ioffset += tag.t_len - 4;
-            }
-        }
-        else if (TAG_EQ(tag.t_name, "SLTP"))
-        {
-            u32 addr;
-
-            if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_fw) ||
-                (tag.t_len != 4) ||
-                (fwinfo->slut_addr != 0) ||
-                read_uint(card, &ct, &addr, 4))
-            {
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-
-            fwinfo->slut_addr = addr;
-        }
-        else if (TAG_EQ(tag.t_name, "FWDL"))
-        {
-            u32 addr;
-            struct FWDL *fwdl;
-
-            if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_fw) ||
-                (fwinfo->num_fwdl >= MAX_FWDL) ||
-                (read_uint(card, &ct, &addr, 4)))
-            {
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-
-            fwdl = fwinfo->fwdl + fwinfo->num_fwdl++;
-
-            fwdl->dl_size = tag.t_len - 4;
-            fwdl->dl_addr = addr;
-            fwdl->dl_offset = ct.ioffset;
-
-            ct.ioffset += tag.t_len - 4;
-        }
-        else if (TAG_EQ(tag.t_name, "FWOV"))
-        {
-            if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_fw) ||
-                (fwinfo->fwov.dl_size != 0) ||
-                (fwinfo->fwov.dl_offset != 0))
-            {
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-
-            fwinfo->fwov.dl_size = tag.t_len;
-            fwinfo->fwov.dl_offset = ct.ioffset;
-
-            ct.ioffset += tag.t_len;
-        }
-        else if (TAG_EQ(tag.t_name, "VMEQ"))
-        {
-            u32 temp[3];
-            struct VAND *vand;
-            struct VMEQ *vmeq;
-
-            if (xbv_check(fwinfo, &stack, xbv_firmware, xbv_vand) ||
-                (fwinfo->num_vmeq >= MAX_VMEQ) ||
-                (fwinfo->vers.num_vand == 0) ||
-                (tag.t_len != 8) ||
-                read_uint(card, &ct, &temp[0], 4) ||
-                read_uint(card, &ct, &temp[1], 2) ||
-                read_uint(card, &ct, &temp[2], 2))
-            {
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-
-            /* Get the last VAND */
-            vand = fwinfo->vand + (fwinfo->vers.num_vand - 1);
-
-            /* Get a new VMEQ */
-            vmeq = fwinfo->vmeq + fwinfo->num_vmeq++;
-
-            /* Note that this VAND contains another VMEQ */
-            vand->count++;
-
-            /* Fill in the VMEQ */
-            vmeq->addr = temp[0];
-            vmeq->mask = (u16)temp[1];
-            vmeq->value = (u16)temp[2];
-        }
-        else if (TAG_EQ(tag.t_name, "FWID"))
-        {
-            u32 build_id;
-
-            if (xbv_check(fwinfo, &stack, xbv_patch, xbv_ptch) ||
-                (tag.t_len != 4) ||
-                (fwinfo->build_id != 0) ||
-                read_uint(card, &ct, &build_id, 4))
-            {
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-
-            fwinfo->build_id = build_id;
-        }
-        else if (TAG_EQ(tag.t_name, "PTDL"))
-        {
-            struct PTDL *ptdl;
-
-            if (xbv_check(fwinfo, &stack, xbv_patch, xbv_ptch) ||
-                (fwinfo->num_ptdl >= MAX_PTDL))
-            {
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-
-            /* Allocate a new PTDL */
-            ptdl = fwinfo->ptdl + fwinfo->num_ptdl++;
-
-            ptdl->dl_size = tag.t_len;
-            ptdl->dl_offset = ct.ioffset;
-
-            ct.ioffset += tag.t_len;
-        }
-        else
-        {
-            /*
-             * If we get here it is a tag we are not interested in,
-             * just skip over it.
-             */
-            ct.ioffset += tag.t_len;
-        }
-
-        /* Check to see if we are at the end of the currently stacked
-         * segment.  We could finish more than one list at a time. */
-        while (ct.ioffset >= stack.s[stack.ptr].ioffset_end)
-        {
-            if (ct.ioffset > stack.s[stack.ptr].ioffset_end)
-            {
-                unifi_error(NULL,
-                            "XBV file has overrun stack'd segment %d (%d > %d)\n",
-                            stack.ptr, ct.ioffset, stack.s[stack.ptr].ioffset_end);
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            if (stack.ptr <= 0)
-            {
-                unifi_error(NULL, "XBV file has underrun stack pointer\n");
-                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-            }
-            stack.ptr--;
-        }
-    }
-
-    if (stack.ptr != 0)
-    {
-        unifi_error(NULL, "Last list of XBV is not complete.\n");
-        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* xbv1_parse() */
-
-
-/* Check the the XBV file is of a consistant sort (either firmware or
- * patch) and that we are in the correct containing list type. */
-static s32 xbv_check(xbv1_t *fwinfo, const xbv_stack_t *stack,
-                          xbv_mode new_mode, xbv_container old_cont)
-{
-    /* If the new file mode is unknown the current packet could be in
-     * either (any) type of XBV file, and we cant make a decission at
-     * this time. */
-    if (new_mode != xbv_unknown)
-    {
-        if (fwinfo->mode == xbv_unknown)
-        {
-            fwinfo->mode = new_mode;
-        }
-        else if (fwinfo->mode != new_mode)
-        {
-            return -1;
-        }
-    }
-    /* If the current stack top doesn't match what we expect then the
-     * file is corrupt. */
-    if (stack->s[stack->ptr].container != old_cont)
-    {
-        return -1;
-    }
-    return 0;
-}
-
-
-/* Make checks as above and then enter a new list */
-static s32 xbv_push(xbv1_t *fwinfo, xbv_stack_t *stack,
-                         xbv_mode new_mode, xbv_container old_cont,
-                         xbv_container new_cont, u32 new_ioff)
-{
-    if (xbv_check(fwinfo, stack, new_mode, old_cont))
-    {
-        return -1;
-    }
-
-    /* Check that our stack won't overflow. */
-    if (stack->ptr >= (XBV_STACK_SIZE - 1))
-    {
-        return -1;
-    }
-
-    /* Add the new list element to the top of the stack. */
-    stack->ptr++;
-    stack->s[stack->ptr].container = new_cont;
-    stack->s[stack->ptr].ioffset_end = new_ioff;
-
-    return 0;
-}
-
-
-static u32 xbv2uint(u8 *ptr, s32 len)
-{
-    u32 u = 0;
-    s16 i;
-
-    for (i = 0; i < len; i++)
-    {
-        u32 b;
-        b = ptr[i];
-        u += b << (i * 8);
-    }
-    return u;
-}
-
-
-static s32 read_tag(card_t *card, ct_t *ct, tag_t *tag)
-{
-    u8 buf[8];
-    s32 n;
-
-    n = (*ct->iread)(card->ospriv, ct->dlpriv, ct->ioffset, buf, 8);
-    if (n <= 0)
-    {
-        return n;
-    }
-
-    /* read the tag and length */
-    if (n != 8)
-    {
-        return -1;
-    }
-
-    /* get section tag */
-    memcpy(tag->t_name, buf, 4);
-
-    /* get section length */
-    tag->t_len = xbv2uint(buf + 4, 4);
-
-    ct->ioffset += 8;
-
-    return 8;
-} /* read_tag() */
-
-
-static s32 read_bytes(card_t *card, ct_t *ct, void *buf, u32 len)
-{
-    /* read the tag value */
-    if ((*ct->iread)(card->ospriv, ct->dlpriv, ct->ioffset, buf, len) != (s32)len)
-    {
-        return -1;
-    }
-
-    ct->ioffset += len;
-
-    return 0;
-} /* read_bytes() */
-
-
-static s32 read_uint(card_t *card, ct_t *ct, u32 *u, u32 len)
-{
-    u8 buf[4];
-
-    /* Integer cannot be more than 4 bytes */
-    if (len > 4)
-    {
-        return -1;
-    }
-
-    if (read_bytes(card, ct, buf, len))
-    {
-        return -1;
-    }
-
-    *u = xbv2uint(buf, len);
-
-    return 0;
-} /* read_uint() */
-
-
-static u32 write_uint16(void *buf, const u32 offset, const u16 val)
-{
-    u8 *dst = (u8 *)buf + offset;
-    *dst++ = (u8)(val & 0xff); /* LSB first */
-    *dst = (u8)(val >> 8);
-    return sizeof(u16);
-}
-
-
-static u32 write_uint32(void *buf, const u32 offset, const u32 val)
-{
-    (void)write_uint16(buf, offset + 0, (u16)(val & 0xffff));
-    (void)write_uint16(buf, offset + 2, (u16)(val >> 16));
-    return sizeof(u32);
-}
-
-
-static u32 write_bytes(void *buf, const u32 offset, const u8 *data, const u32 len)
-{
-    u32 i;
-    u8 *dst = (u8 *)buf + offset;
-
-    for (i = 0; i < len; i++)
-    {
-        *dst++ = *((u8 *)data + i);
-    }
-    return len;
-}
-
-
-static u32 write_tag(void *buf, const u32 offset, const char *tag_str)
-{
-    u8 *dst = (u8 *)buf + offset;
-    memcpy(dst, tag_str, 4);
-    return 4;
-}
-
-
-static u32 write_chunk(void *buf, const u32 offset, const char *tag_str, const u32 payload_len)
-{
-    u32 written = 0;
-    written += write_tag(buf, offset, tag_str);
-    written += write_uint32(buf, written + offset, (u32)payload_len);
-
-    return written;
-}
-
-
-static u16 calc_checksum(void *buf, const u32 offset, const u32 bytes_len)
-{
-    u32 i;
-    u8 *src = (u8 *)buf + offset;
-    u16 sum = 0;
-    u16 val;
-
-    for (i = 0; i < bytes_len / 2; i++)
-    {
-        /* Contents copied to file is LE, host might not be */
-        val = (u16) * src++;         /* LSB */
-        val += (u16)(*src++) << 8;   /* MSB */
-        sum += val;
-    }
-
-    /* Total of uint16s in the stream plus the stored check value
-     * should equal STREAM_CHECKSUM when decoded.
-     */
-    return (STREAM_CHECKSUM - sum);
-}
-
-
-#define PTDL_RESET_DATA_SIZE  20  /* Size of reset vectors PTDL */
-
-static u32 calc_patch_size(const xbv1_t *fwinfo)
-{
-    s16 i;
-    u32 size = 0;
-
-    /*
-     * Work out how big an equivalent patch format file must be for this image.
-     * This only needs to be approximate, so long as it's large enough.
-     */
-    if (fwinfo->mode != xbv_firmware)
-    {
-        return 0;
-    }
-
-    /* Payload (which will get put into a series of PTDLs) */
-    for (i = 0; i < fwinfo->num_fwdl; i++)
-    {
-        size += fwinfo->fwdl[i].dl_size;
-    }
-
-    /* Another PTDL at the end containing reset vectors */
-    size += PTDL_RESET_DATA_SIZE;
-
-    /* PTDL headers. Add one for remainder, one for reset vectors */
-    size += ((fwinfo->num_fwdl / PTDL_MAX_SIZE) + 2) * PTDL_HDR_SIZE;
-
-    /* Another 1K sufficient to cover miscellaneous headers */
-    size += 1024;
-
-    return size;
-}
-
-
-static u32 write_xbv_header(void *buf, const u32 offset, const u32 file_payload_length)
-{
-    u32 written = 0;
-
-    /* The length value given to the XBV chunk is the length of all subsequent
-     * contents of the file, excluding the 8 byte size of the XBV1 header itself
-     * (The added 6 bytes thus accounts for the size of the VERF)
-     */
-    written += write_chunk(buf, offset + written, (char *)"XBV1", file_payload_length + 6);
-
-    written += write_chunk(buf, offset + written, (char *)"VERF", 2);
-    written += write_uint16(buf,  offset + written, 0);      /* File version */
-
-    return written;
-}
-
-
-static u32 write_ptch_header(void *buf, const u32 offset, const u32 fw_id)
-{
-    u32 written = 0;
-
-    /* LIST is written with a zero length, to be updated later */
-    written += write_chunk(buf, offset + written, (char *)"LIST", 0);
-    written += write_tag(buf, offset + written, (char *)"PTCH");        /* List type */
-
-    written += write_chunk(buf, offset + written, (char *)"FWID", 4);
-    written += write_uint32(buf, offset + written, fw_id);
-
-
-    return written;
-}
-
-
-#define UF_REGION_PHY  1
-#define UF_REGION_MAC  2
-#define UF_MEMPUT_MAC  0x0000
-#define UF_MEMPUT_PHY  0x1000
-
-static u32 write_patchcmd(void *buf, const u32 offset, const u32 dst_genaddr, const u16 len)
-{
-    u32 written = 0;
-    u32 region = (dst_genaddr >> 28);
-    u16 cmd_and_len = UF_MEMPUT_MAC;
-
-    if (region == UF_REGION_PHY)
-    {
-        cmd_and_len = UF_MEMPUT_PHY;
-    }
-    else if (region != UF_REGION_MAC)
-    {
-        return 0; /* invalid */
-    }
-
-    /* Write the command and data length */
-    cmd_and_len |= len;
-    written += write_uint16(buf, offset + written, cmd_and_len);
-
-    /* Write the destination generic address */
-    written += write_uint16(buf, offset + written, (u16)(dst_genaddr >> 16));
-    written += write_uint16(buf, offset + written, (u16)(dst_genaddr & 0xffff));
-
-    /* The data payload should be appended to the command */
-    return written;
-}
-
-
-static u32 write_fwdl_to_ptdl(void *buf, const u32 offset, fwreadfn_t readfn,
-                                    const struct FWDL *fwdl, const void *dlpriv,
-                                    const u32 fw_id, void *fw_buf)
-{
-    u32 written = 0;
-    s16 chunks = 0;
-    u32 left = fwdl->dl_size;      /* Bytes left in this fwdl */
-    u32 dl_addr = fwdl->dl_addr;   /* Target address of fwdl image on XAP */
-    u32 dl_offs = fwdl->dl_offset; /* Offset of fwdl image data in source */
-    u16 csum;
-    u32 csum_start_offs;           /* first offset to include in checksum */
-    u32 sec_data_len;              /* section data byte count */
-    u32 sec_len;                   /* section data + header byte count */
-
-    /* FWDL maps to one or more PTDLs, as max size for a PTDL is 1K words */
-    while (left)
-    {
-        /* Calculate amount to be transferred */
-        sec_data_len = min_t(u32, left, PTDL_MAX_SIZE - PTDL_HDR_SIZE);
-        sec_len = sec_data_len + PTDL_HDR_SIZE;
-
-        /* Write PTDL header + entire PTDL size */
-        written += write_chunk(buf, offset + written, (char *)"PTDL", sec_len);
-        /* bug digest implies 4 bytes of padding here, but that seems wrong */
-
-        /* Checksum starts here */
-        csum_start_offs = offset + written;
-
-        /* Patch-chunk header: fw_id. Note that this is in XAP word order */
-        written += write_uint16(buf, offset + written, (u16)(fw_id >> 16));
-        written += write_uint16(buf, offset + written, (u16)(fw_id & 0xffff));
-
-        /* Patch-chunk header: section length in uint16s */
-        written += write_uint16(buf, offset + written, (u16)(sec_len / 2));
-
-
-        /* Write the appropriate patch command for the data's destination ptr */
-        written += write_patchcmd(buf, offset + written, dl_addr, (u16)(sec_data_len / 2));
-
-        /* Write the data itself (limited to the max chunk length) */
-        if (readfn(NULL, (void *)dlpriv, dl_offs, fw_buf, sec_data_len) < 0)
-        {
-            return 0;
-        }
-
-        written += write_bytes(buf,
-                               offset + written,
-                               fw_buf,
-                               sec_data_len);
-
-        /* u16 checksum calculated over data written */
-        csum = calc_checksum(buf, csum_start_offs, written - (csum_start_offs - offset));
-        written += write_uint16(buf, offset + written, csum);
-
-        left -= sec_data_len;
-        dl_addr += sec_data_len;
-        dl_offs += sec_data_len;
-        chunks++;
-    }
-
-    return written;
-}
-
-
-#define SEC_CMD_LEN         ((4 + 2) * 2) /* sizeof(cmd, vector) per XAP */
-#define PTDL_VEC_HDR_SIZE   (4 + 2 + 2)   /* sizeof(fw_id, sec_len, csum) */
-#define UF_MAC_START_VEC    0x00c00000    /* Start address of image on MAC */
-#define UF_PHY_START_VEC    0x00c00000    /* Start address of image on PHY */
-#define UF_MAC_START_CMD    0x6000        /* MAC "Set start address" command */
-#define UF_PHY_START_CMD    0x7000        /* PHY "Set start address" command */
-
-static u32 write_reset_ptdl(void *buf, const u32 offset, const xbv1_t *fwinfo, u32 fw_id)
-{
-    u32 written = 0;
-    u16 csum;
-    u32 csum_start_offs;                 /* first offset to include in checksum */
-    u32 sec_len;                         /* section data + header byte count */
-
-    sec_len = SEC_CMD_LEN + PTDL_VEC_HDR_SIZE; /* Total section byte length */
-
-    /* Write PTDL header + entire PTDL size */
-    written += write_chunk(buf, offset + written, (char *)"PTDL", sec_len);
-
-    /* Checksum starts here */
-    csum_start_offs = offset + written;
-
-    /* Patch-chunk header: fw_id. Note that this is in XAP word order */
-    written += write_uint16(buf, offset + written, (u16)(fw_id >> 16));
-    written += write_uint16(buf, offset + written, (u16)(fw_id & 0xffff));
-
-    /* Patch-chunk header: section length in uint16s */
-    written += write_uint16(buf, offset + written, (u16)(sec_len / 2));
-
-    /*
-     * Restart addresses to be executed on subsequent loader restart command.
-     */
-
-    /* Setup the MAC start address, note word ordering */
-    written += write_uint16(buf, offset + written, UF_MAC_START_CMD);
-    written += write_uint16(buf, offset + written, (UF_MAC_START_VEC >> 16));
-    written += write_uint16(buf, offset + written, (UF_MAC_START_VEC & 0xffff));
-
-    /* Setup the PHY start address, note word ordering */
-    written += write_uint16(buf, offset + written, UF_PHY_START_CMD);
-    written += write_uint16(buf, offset + written, (UF_PHY_START_VEC >> 16));
-    written += write_uint16(buf, offset + written, (UF_PHY_START_VEC & 0xffff));
-
-    /* u16 checksum calculated over data written */
-    csum = calc_checksum(buf, csum_start_offs, written - (csum_start_offs - offset));
-    written += write_uint16(buf, offset + written, csum);
-
-    return written;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  read_slut
- *
- *      desc
- *
- *  Arguments:
- *      readfn          Pointer to function to call to read from the file.
- *      dlpriv          Opaque pointer arg to pass to readfn.
- *      addr            Offset into firmware image of SLUT.
- *      fwinfo          Pointer to fwinfo struct to fill in.
- *
- *  Returns:
- *      Number of SLUT entries in the f/w, or -1 if the image was corrupt.
- * ---------------------------------------------------------------------------
- */
-s32 xbv1_read_slut(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo,
-                        symbol_t *slut, u32 slut_len)
-{
-    s16 i;
-    s32 offset;
-    u32 magic;
-    u32 count = 0;
-    ct_t ct;
-
-    if (fwinfo->mode != xbv_firmware)
-    {
-        return -1;
-    }
-
-    /* Find the d/l segment containing the SLUT */
-    /* This relies on the SLUT being entirely contained in one segment */
-    offset = -1;
-    for (i = 0; i < fwinfo->num_fwdl; i++)
-    {
-        if ((fwinfo->slut_addr >= fwinfo->fwdl[i].dl_addr) &&
-            (fwinfo->slut_addr < (fwinfo->fwdl[i].dl_addr + fwinfo->fwdl[i].dl_size)))
-        {
-            offset = fwinfo->fwdl[i].dl_offset +
-                     (fwinfo->slut_addr - fwinfo->fwdl[i].dl_addr);
-        }
-    }
-    if (offset < 0)
-    {
-        return -1;
-    }
-
-    ct.dlpriv = dlpriv;
-    ct.ioffset = offset;
-    ct.iread = readfn;
-
-    if (read_uint(card, &ct, &magic, 2))
-    {
-        return -1;
-    }
-    if (magic != SLUT_FINGERPRINT)
-    {
-        return -1;
-    }
-
-    while (count < slut_len)
-    {
-        u32 id, obj;
-
-        /* Read Symbol Id */
-        if (read_uint(card, &ct, &id, 2))
-        {
-            return -1;
-        }
-
-        /* Check for end of table marker */
-        if (id == CSR_SLT_END)
-        {
-            break;
-        }
-
-        /* Read Symbol Value */
-        if (read_uint(card, &ct, &obj, 4))
-        {
-            return -1;
-        }
-
-        slut[count].id  = (u16)id;
-        slut[count].obj = obj;
-        count++;
-    }
-
-    return count;
-} /* read_slut() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  xbv_to_patch
- *
- *      Convert (the relevant parts of) a firmware xbv file into a patch xbv
- *
- *  Arguments:
- *      card
- *      fw_buf - pointer to xbv firmware image
- *      fwinfo - structure describing the firmware image
- *      size   - pointer to location into which size of f/w is written.
- *
- *  Returns:
- *      Pointer to firmware image, or NULL on error. Caller must free this
- *      buffer via kfree() once it's finished with.
- *
- *  Notes:
- *      The input fw_buf should have been checked via xbv1_parse prior to
- *      calling this function, so the input image is assumed valid.
- * ---------------------------------------------------------------------------
- */
-#define PTCH_LIST_SIZE 16         /* sizeof PTCH+FWID chunk in LIST header */
-
-void* xbv_to_patch(card_t *card, fwreadfn_t readfn,
-                   const void *fw_buf, const xbv1_t *fwinfo, u32 *size)
-{
-    void *patch_buf = NULL;
-    u32 patch_buf_size;
-    u32 payload_offs = 0;           /* Start of XBV payload */
-    s16 i;
-    u32 patch_offs = 0;
-    u32 list_len_offs = 0;          /* Offset of PTDL LIST length parameter */
-    u32 ptdl_start_offs = 0;        /* Offset of first PTDL chunk */
-    u32 fw_id;
-    void *rdbuf;
-
-    if (!fw_buf || !fwinfo || !card)
-    {
-        return NULL;
-    }
-
-    if (fwinfo->mode != xbv_firmware)
-    {
-        unifi_error(NULL, "Not a firmware file\n");
-        return NULL;
-    }
-
-    /* Pre-allocate read buffer for chunk conversion */
-    rdbuf = kmalloc(PTDL_MAX_SIZE, GFP_KERNEL);
-    if (!rdbuf)
-    {
-        unifi_error(card, "Couldn't alloc conversion buffer\n");
-        return NULL;
-    }
-
-    /* Loader requires patch file's build ID to match the running firmware's */
-    fw_id = card->build_id;
-
-    /* Firmware XBV1 contains VERF, optional INFO, SLUT(s), FWDL(s)          */
-    /* Other chunks should get skipped.                                      */
-    /* VERF should be sanity-checked against chip version                    */
-
-    /* Patch    XBV1 contains VERF, optional INFO, PTCH                      */
-    /*          PTCH contains FWID, optional INFO, PTDL(s), PTDL(start_vec)  */
-    /* Each FWDL is split into PTDLs (each is 1024 XAP words max)            */
-    /* Each PTDL contains running ROM f/w version, and checksum              */
-    /* MAC/PHY reset addresses (known) are added into a final PTDL           */
-
-    /* The input image has already been parsed, and loaded into fwinfo, so we
-     * can use that to build the output image
-     */
-    patch_buf_size = calc_patch_size(fwinfo);
-
-    patch_buf = kmalloc(patch_buf_size, GFP_KERNEL);
-    if (!patch_buf)
-    {
-        kfree(rdbuf);
-        unifi_error(NULL, "Can't malloc buffer for patch conversion\n");
-        return NULL;
-    }
-
-    memset(patch_buf, 0xdd, patch_buf_size);
-
-    /* Write XBV + VERF headers */
-    patch_offs += write_xbv_header(patch_buf, patch_offs, 0);
-    payload_offs = patch_offs;
-
-    /* Write patch (LIST) header */
-    list_len_offs = patch_offs + 4;    /* Save LIST.length offset for later update */
-    patch_offs += write_ptch_header(patch_buf, patch_offs, fw_id);
-
-    /* Save start offset of the PTDL chunks */
-    ptdl_start_offs = patch_offs;
-
-    /* Write LIST of firmware PTDL blocks */
-    for (i = 0; i < fwinfo->num_fwdl; i++)
-    {
-        patch_offs += write_fwdl_to_ptdl(patch_buf,
-                                         patch_offs,
-                                         readfn,
-                                         &fwinfo->fwdl[i],
-                                         fw_buf,
-                                         fw_id,
-                                         rdbuf);
-    }
-
-    /* Write restart-vector PTDL last */
-    patch_offs += write_reset_ptdl(patch_buf, patch_offs, fwinfo, fw_id);
-
-    /* Now the length is known, update the LIST.length */
-    (void)write_uint32(patch_buf, list_len_offs,
-                       (patch_offs - ptdl_start_offs) + PTCH_LIST_SIZE);
-
-    /* Re write XBV headers just to fill in the correct file size */
-    (void)write_xbv_header(patch_buf, 0, (patch_offs - payload_offs));
-
-    unifi_trace(card->ospriv, UDBG1, "XBV:PTCH size %u, fw_id %u\n",
-                patch_offs, fw_id);
-    if (size)
-    {
-        *size = patch_offs;
-    }
-    kfree(rdbuf);
-
-    return patch_buf;
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_xbv.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_xbv.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hip_xbv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hip_xbv.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,119 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/*
- * ---------------------------------------------------------------------------
- * FILE: csr_wifi_hip_xbv.h
- *
- * PURPOSE:
- *      Definitions and declarations for code to read XBV files - the UniFi
- *      firmware download file format.
- *
- * ---------------------------------------------------------------------------
- */
-#ifndef __XBV_H__
-#define __XBV_H__
-
-#ifndef CSR_WIFI_XBV_TEST
-/* Driver includes */
-#include "csr_wifi_hip_unifi.h"
-#endif
-
-
-struct VMEQ
-{
-    u32 addr;
-    u16 mask;
-    u16 value;
-};
-
-struct VAND
-{
-    u32 first;
-    u32 count;
-};
-
-struct VERS
-{
-    u32 num_vand;
-};
-
-struct FWDL
-{
-    u32 dl_addr;
-    u32 dl_size;
-    u32 dl_offset;
-};
-
-struct FWOV
-{
-    u32 dl_size;
-    u32 dl_offset;
-};
-
-struct PTDL
-{
-    u32 dl_size;
-    u32 dl_offset;
-};
-
-#define MAX_VMEQ 64
-#define MAX_VAND 64
-#define MAX_FWDL 256
-#define MAX_PTDL 256
-
-/* An XBV1 file can either contain firmware or patches (at the
- * moment).  The 'mode' member of the xbv1_t structure tells us which
- * one is the case. */
-typedef enum
-{
-    xbv_unknown,
-    xbv_firmware,
-    xbv_patch
-} xbv_mode;
-
-typedef struct
-{
-    xbv_mode mode;
-
-    /* Parts of a Firmware XBV1 */
-
-    struct VMEQ vmeq[MAX_VMEQ];
-    u32   num_vmeq;
-    struct VAND vand[MAX_VAND];
-    struct VERS vers;
-
-    u32 slut_addr;
-
-    /* F/W download image, possibly more than one part */
-    struct FWDL fwdl[MAX_FWDL];
-    s16    num_fwdl;
-
-    /* F/W overlay image, add r not used */
-    struct FWOV fwov;
-
-    /* Parts of a Patch XBV1 */
-
-    u32 build_id;
-
-    struct PTDL ptdl[MAX_PTDL];
-    s16    num_ptdl;
-}  xbv1_t;
-
-
-typedef s32 (*fwreadfn_t)(void *ospriv, void *dlpriv, u32 offset, void *buf, u32 len);
-
-CsrResult xbv1_parse(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo);
-s32 xbv1_read_slut(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo,
-                        symbol_t *slut, u32 slut_len);
-void* xbv_to_patch(card_t *card, fwreadfn_t readfn, const void *fw_buf, const xbv1_t *fwinfo,
-                   u32 *size);
-
-#endif /* __XBV_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hostio_prim.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hostio_prim.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_hostio_prim.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_hostio_prim.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-
-#ifndef CSR_WIFI_HOSTIO_H
-#define CSR_WIFI_HOSTIO_H
-
-#define CSR_WIFI_HOSTIO_PRIM 0x0453
-
-#endif /* CSR_WIFI_HOSTIO_H */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_lib.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_lib.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_lib.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_lib.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,103 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-#ifndef CSR_WIFI_LIB_H__
-#define CSR_WIFI_LIB_H__
-
-#include "csr_wifi_fsm_event.h"
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiFsmEventInit
- *
- *  DESCRIPTION
- *      Macro to initialise the members of a CsrWifiFsmEvent.
- *----------------------------------------------------------------------------*/
-#define CsrWifiFsmEventInit(evt, p_primtype, p_msgtype, p_dst, p_src) \
-    (evt)->primtype = p_primtype; \
-    (evt)->type = p_msgtype; \
-    (evt)->destination = p_dst; \
-    (evt)->source = p_src
-
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiEvent_struct
- *
- *  DESCRIPTION
- *      Generic message creator.
- *      Allocates and fills in a message with the signature CsrWifiEvent
- *
- *----------------------------------------------------------------------------*/
-CsrWifiFsmEvent* CsrWifiEvent_struct(u16 primtype, u16 msgtype, CsrSchedQid dst, CsrSchedQid src);
-
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u8        value;
-} CsrWifiEventCsrUint8;
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiEventCsrUint8_struct
- *
- *  DESCRIPTION
- *      Generic message creator.
- *      Allocates and fills in a message with the signature CsrWifiEventCsrUint8
- *
- *----------------------------------------------------------------------------*/
-CsrWifiEventCsrUint8* CsrWifiEventCsrUint8_struct(u16 primtype, u16 msgtype, CsrSchedQid dst, CsrSchedQid src, u8 value);
-
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       value;
-} CsrWifiEventCsrUint16;
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiEventCsrUint16_struct
- *
- *  DESCRIPTION
- *      Generic message creator.
- *      Allocates and fills in a message with the signature CsrWifiEventCsrUint16
- *
- *----------------------------------------------------------------------------*/
-CsrWifiEventCsrUint16* CsrWifiEventCsrUint16_struct(u16 primtype, u16 msgtype, CsrSchedQid dst, CsrSchedQid src, u16 value);
-
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u32       value;
-} CsrWifiEventCsrUint32;
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiEventCsrUint32_struct
- *
- *  DESCRIPTION
- *      Generic message creator.
- *      Allocates and fills in a message with the signature CsrWifiEventCsrUint32
- *
- *----------------------------------------------------------------------------*/
-CsrWifiEventCsrUint32* CsrWifiEventCsrUint32_struct(u16 primtype, u16 msgtype, CsrSchedQid dst, CsrSchedQid src, u32 value);
-
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       value16;
-    u8        value8;
-} CsrWifiEventCsrUint16CsrUint8;
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiEventCsrUint16CsrUint8_struct
- *
- *  DESCRIPTION
- *      Generic message creator.
- *      Allocates and fills in a message with the signature CsrWifiEventCsrUint16CsrUint8
- *
- *----------------------------------------------------------------------------*/
-CsrWifiEventCsrUint16CsrUint8* CsrWifiEventCsrUint16CsrUint8_struct(u16 primtype, u16 msgtype, CsrSchedQid dst, CsrSchedQid src, u16 value16, u8 value8);
-
-#endif /* CSR_WIFI_LIB_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_msgconv.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_msgconv.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_msgconv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_msgconv.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_MSGCONV_H__
-#define CSR_WIFI_MSGCONV_H__
-
-#include "csr_prim_defs.h"
-#include "csr_sched.h"
-
-void CsrUint16SerBigEndian(u8 *ptr, size_t *len, u16 v);
-void CsrUint24SerBigEndian(u8 *ptr, size_t *len, u32 v);
-void CsrUint32SerBigEndian(u8 *ptr, size_t *len, u32 v);
-
-void CsrUint16DesBigEndian(u16 *v, u8 *buffer, size_t *offset);
-void CsrUint24DesBigEndian(u32 *v, u8 *buffer, size_t *offset);
-void CsrUint32DesBigEndian(u32 *v, u8 *buffer, size_t *offset);
-
-void CsrUint24Ser(u8 *ptr, size_t *len, u32 v);
-void CsrUint24Des(u32 *v, u8 *buffer, size_t *offset);
-
-
-size_t CsrWifiEventSizeof(void *msg);
-u8* CsrWifiEventSer(u8 *ptr, size_t *len, void *msg);
-void* CsrWifiEventDes(u8 *buffer, size_t length);
-
-size_t CsrWifiEventCsrUint8Sizeof(void *msg);
-u8* CsrWifiEventCsrUint8Ser(u8 *ptr, size_t *len, void *msg);
-void* CsrWifiEventCsrUint8Des(u8 *buffer, size_t length);
-
-size_t CsrWifiEventCsrUint16Sizeof(void *msg);
-u8* CsrWifiEventCsrUint16Ser(u8 *ptr, size_t *len, void *msg);
-void* CsrWifiEventCsrUint16Des(u8 *buffer, size_t length);
-
-size_t CsrWifiEventCsrUint32Sizeof(void *msg);
-u8* CsrWifiEventCsrUint32Ser(u8 *ptr, size_t *len, void *msg);
-void* CsrWifiEventCsrUint32Des(u8 *buffer, size_t length);
-
-size_t CsrWifiEventCsrUint16CsrUint8Sizeof(void *msg);
-u8* CsrWifiEventCsrUint16CsrUint8Ser(u8 *ptr, size_t *len, void *msg);
-void* CsrWifiEventCsrUint16CsrUint8Des(u8 *buffer, size_t length);
-
-#endif /* CSR_WIFI_MSGCONV_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_converter_init.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_converter_init.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_converter_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_converter_init.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,90 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#include "csr_msgconv.h"
-#include "csr_macro.h"
-
-#ifdef CSR_WIFI_NME_ENABLE
-#ifdef CSR_WIFI_AP_ENABLE
-
-#ifdef CSR_LOG_ENABLE
-#include "csr_log.h"
-#endif
-
-#ifndef EXCLUDE_CSR_WIFI_NME_AP_MODULE
-#include "csr_wifi_nme_ap_serialize.h"
-#include "csr_wifi_nme_ap_prim.h"
-
-static CsrMsgConvMsgEntry csrwifinmeap_conv_lut[] = {
-    { CSR_WIFI_NME_AP_CONFIG_SET_REQ, CsrWifiNmeApConfigSetReqSizeof, CsrWifiNmeApConfigSetReqSer, CsrWifiNmeApConfigSetReqDes, CsrWifiNmeApConfigSetReqSerFree },
-    { CSR_WIFI_NME_AP_WPS_REGISTER_REQ, CsrWifiNmeApWpsRegisterReqSizeof, CsrWifiNmeApWpsRegisterReqSer, CsrWifiNmeApWpsRegisterReqDes, CsrWifiNmeApWpsRegisterReqSerFree },
-    { CSR_WIFI_NME_AP_START_REQ, CsrWifiNmeApStartReqSizeof, CsrWifiNmeApStartReqSer, CsrWifiNmeApStartReqDes, CsrWifiNmeApStartReqSerFree },
-    { CSR_WIFI_NME_AP_STOP_REQ, CsrWifiNmeApStopReqSizeof, CsrWifiNmeApStopReqSer, CsrWifiNmeApStopReqDes, CsrWifiNmeApStopReqSerFree },
-    { CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_REQ, CsrWifiNmeApWmmParamUpdateReqSizeof, CsrWifiNmeApWmmParamUpdateReqSer, CsrWifiNmeApWmmParamUpdateReqDes, CsrWifiNmeApWmmParamUpdateReqSerFree },
-    { CSR_WIFI_NME_AP_STA_REMOVE_REQ, CsrWifiNmeApStaRemoveReqSizeof, CsrWifiNmeApStaRemoveReqSer, CsrWifiNmeApStaRemoveReqDes, CsrWifiNmeApStaRemoveReqSerFree },
-    { CSR_WIFI_NME_AP_CONFIG_SET_CFM, CsrWifiNmeApConfigSetCfmSizeof, CsrWifiNmeApConfigSetCfmSer, CsrWifiNmeApConfigSetCfmDes, CsrWifiNmeApConfigSetCfmSerFree },
-    { CSR_WIFI_NME_AP_WPS_REGISTER_CFM, CsrWifiNmeApWpsRegisterCfmSizeof, CsrWifiNmeApWpsRegisterCfmSer, CsrWifiNmeApWpsRegisterCfmDes, CsrWifiNmeApWpsRegisterCfmSerFree },
-    { CSR_WIFI_NME_AP_START_CFM, CsrWifiNmeApStartCfmSizeof, CsrWifiNmeApStartCfmSer, CsrWifiNmeApStartCfmDes, CsrWifiNmeApStartCfmSerFree },
-    { CSR_WIFI_NME_AP_STOP_CFM, CsrWifiNmeApStopCfmSizeof, CsrWifiNmeApStopCfmSer, CsrWifiNmeApStopCfmDes, CsrWifiNmeApStopCfmSerFree },
-    { CSR_WIFI_NME_AP_STOP_IND, CsrWifiNmeApStopIndSizeof, CsrWifiNmeApStopIndSer, CsrWifiNmeApStopIndDes, CsrWifiNmeApStopIndSerFree },
-    { CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_CFM, CsrWifiNmeApWmmParamUpdateCfmSizeof, CsrWifiNmeApWmmParamUpdateCfmSer, CsrWifiNmeApWmmParamUpdateCfmDes, CsrWifiNmeApWmmParamUpdateCfmSerFree },
-    { CSR_WIFI_NME_AP_STATION_IND, CsrWifiNmeApStationIndSizeof, CsrWifiNmeApStationIndSer, CsrWifiNmeApStationIndDes, CsrWifiNmeApStationIndSerFree },
-
-    { 0, NULL, NULL, NULL, NULL },
-};
-
-CsrMsgConvMsgEntry* CsrWifiNmeApConverterLookup(CsrMsgConvMsgEntry *ce, u16 msgType)
-{
-    if (msgType & CSR_PRIM_UPSTREAM)
-    {
-        u16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT;
-        if (idx < (CSR_WIFI_NME_AP_PRIM_UPSTREAM_COUNT + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT) &&
-            csrwifinmeap_conv_lut[idx].msgType == msgType)
-        {
-            return &csrwifinmeap_conv_lut[idx];
-        }
-    }
-    else
-    {
-        if (msgType < CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT &&
-            csrwifinmeap_conv_lut[msgType].msgType == msgType)
-        {
-            return &csrwifinmeap_conv_lut[msgType];
-        }
-    }
-    return NULL;
-}
-
-
-void CsrWifiNmeApConverterInit(void)
-{
-    CsrMsgConvInsert(CSR_WIFI_NME_AP_PRIM, csrwifinmeap_conv_lut);
-    CsrMsgConvCustomLookupRegister(CSR_WIFI_NME_AP_PRIM, CsrWifiNmeApConverterLookup);
-}
-
-
-#ifdef CSR_LOG_ENABLE
-static const CsrLogPrimitiveInformation csrwifinmeap_conv_info = {
-    CSR_WIFI_NME_AP_PRIM,
-    (char *)"CSR_WIFI_NME_AP_PRIM",
-    csrwifinmeap_conv_lut
-};
-const CsrLogPrimitiveInformation* CsrWifiNmeApTechInfoGet(void)
-{
-    return &csrwifinmeap_conv_info;
-}
-
-
-#endif /* CSR_LOG_ENABLE */
-#endif /* EXCLUDE_CSR_WIFI_NME_AP_MODULE */
-#endif /* CSR_WIFI_NME_ENABLE */
-#endif /* CSR_WIFI_AP_ENABLE */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,41 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_NME_AP_CONVERTER_INIT_H__
-#define CSR_WIFI_NME_AP_CONVERTER_INIT_H__
-
-#ifndef CSR_WIFI_NME_ENABLE
-#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_converter_init.h
-#endif
-#ifndef CSR_WIFI_AP_ENABLE
-#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_converter_init.h
-#endif
-
-#ifndef EXCLUDE_CSR_WIFI_NME_AP_MODULE
-
-#include "csr_msgconv.h"
-
-#ifdef CSR_LOG_ENABLE
-#include "csr_log.h"
-
-extern const CsrLogPrimitiveInformation* CsrWifiNmeApTechInfoGet(void);
-#endif /* CSR_LOG_ENABLE */
-
-extern void CsrWifiNmeApConverterInit(void);
-
-#else /* EXCLUDE_CSR_WIFI_NME_AP_MODULE */
-
-#define CsrWifiNmeApConverterInit()
-
-#endif /* EXCLUDE_CSR_WIFI_NME_AP_MODULE */
-
-#endif /* CSR_WIFI_NME_AP_CONVERTER_INIT_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_free_downstream_contents.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_free_downstream_contents.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_free_downstream_contents.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_free_downstream_contents.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,84 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/slab.h>
-#include "csr_wifi_nme_ap_prim.h"
-#include "csr_wifi_nme_ap_lib.h"
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrWifiNmeApFreeDownstreamMessageContents
- *
- *  DESCRIPTION
- *
- *
- *  PARAMETERS
- *      eventClass: only the value CSR_WIFI_NME_AP_PRIM will be handled
- *      message:    the message to free
- *----------------------------------------------------------------------------*/
-void CsrWifiNmeApFreeDownstreamMessageContents(u16 eventClass, void *message)
-{
-    if (eventClass != CSR_WIFI_NME_AP_PRIM)
-    {
-        return;
-    }
-    if (NULL == message)
-    {
-        return;
-    }
-
-    switch (*((CsrWifiNmeApPrim *) message))
-    {
-        case CSR_WIFI_NME_AP_CONFIG_SET_REQ:
-        {
-            CsrWifiNmeApConfigSetReq *p = (CsrWifiNmeApConfigSetReq *)message;
-            kfree(p->apMacConfig.macAddressList);
-            p->apMacConfig.macAddressList = NULL;
-            break;
-        }
-        case CSR_WIFI_NME_AP_START_REQ:
-        {
-            CsrWifiNmeApStartReq *p = (CsrWifiNmeApStartReq *)message;
-            switch (p->apCredentials.authType)
-            {
-                case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL:
-                    switch (p->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase)
-                    {
-                        case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE:
-                            kfree(p->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase);
-                            p->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase = NULL;
-                            break;
-                        default:
-                            break;
-                    }
-                    break;
-                default:
-                    break;
-            }
-            {
-                u16 i3;
-                for (i3 = 0; i3 < p->p2pGoParam.operatingChanList.channelEntryListCount; i3++)
-                {
-                    kfree(p->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel);
-                    p->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel = NULL;
-                }
-            }
-            kfree(p->p2pGoParam.operatingChanList.channelEntryList);
-            p->p2pGoParam.operatingChanList.channelEntryList = NULL;
-            break;
-        }
-
-        default:
-            break;
-    }
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_free_upstream_contents.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_free_upstream_contents.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_free_upstream_contents.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_free_upstream_contents.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#include "csr_wifi_nme_ap_prim.h"
-#include "csr_wifi_nme_ap_lib.h"
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrWifiNmeApFreeUpstreamMessageContents
- *
- *  DESCRIPTION
- *
- *
- *  PARAMETERS
- *      eventClass: only the value CSR_WIFI_NME_AP_PRIM will be handled
- *      message:    the message to free
- *----------------------------------------------------------------------------*/
-void CsrWifiNmeApFreeUpstreamMessageContents(u16 eventClass, void *message)
-{
-    if (eventClass != CSR_WIFI_NME_AP_PRIM)
-    {
-        return;
-    }
-    if (NULL == message)
-    {
-        return;
-    }
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_lib.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_lib.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_lib.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_lib.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,495 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_NME_AP_LIB_H__
-#define CSR_WIFI_NME_AP_LIB_H__
-
-#include "csr_sched.h"
-#include "csr_macro.h"
-#include "csr_msg_transport.h"
-
-#include "csr_wifi_lib.h"
-
-#include "csr_wifi_nme_ap_prim.h"
-#include "csr_wifi_nme_task.h"
-
-#ifndef CSR_WIFI_NME_ENABLE
-#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_lib.h
-#endif
-#ifndef CSR_WIFI_AP_ENABLE
-#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_lib.h
-#endif
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiNmeApFreeUpstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_NME_AP upstream message. Does not
- *      free the message itself, and can only be used for upstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_NME_AP upstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiNmeApFreeUpstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiNmeApFreeDownstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_NME_AP downstream message. Does not
- *      free the message itself, and can only be used for downstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_NME_AP downstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiNmeApFreeDownstreamMessageContents(u16 eventClass, void *message);
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApConfigSetReqSend
-
-  DESCRIPTION
-    This primitive passes AP configuration info for NME. This can be sent at
-    any time but will be acted upon when the AP is started again. This
-    information is common to both P2P GO and AP
-
-  PARAMETERS
-    queue       - Message Source Task Queue (Cfm's will be sent to this Queue)
-    apConfig    - AP configuration for the NME.
-    apMacConfig - MAC configuration to be acted on when
-                  CSR_WIFI_NME_AP_START.request is sent.
-
-*******************************************************************************/
-#define CsrWifiNmeApConfigSetReqCreate(msg__, dst__, src__, apConfig__, apMacConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_CONFIG_SET_REQ, dst__, src__); \
-    msg__->apConfig = (apConfig__); \
-    msg__->apMacConfig = (apMacConfig__);
-
-#define CsrWifiNmeApConfigSetReqSendTo(dst__, src__, apConfig__, apMacConfig__) \
-    { \
-        CsrWifiNmeApConfigSetReq *msg__; \
-        CsrWifiNmeApConfigSetReqCreate(msg__, dst__, src__, apConfig__, apMacConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApConfigSetReqSend(src__, apConfig__, apMacConfig__) \
-    CsrWifiNmeApConfigSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, apConfig__, apMacConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Status of the request.
-
-*******************************************************************************/
-#define CsrWifiNmeApConfigSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_CONFIG_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeApConfigSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiNmeApConfigSetCfm *msg__; \
-        CsrWifiNmeApConfigSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApConfigSetCfmSend(dst__, status__) \
-    CsrWifiNmeApConfigSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStaRemoveReqSend
-
-  DESCRIPTION
-    This primitive disconnects a connected station. If keepBlocking is set to
-    TRUE, the station with the specified MAC address is not allowed to
-    connect. If the requested station is not already connected,it may be
-    blocked based on keepBlocking parameter.
-
-  PARAMETERS
-    queue         - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    staMacAddress - Mac Address of the station to be disconnected or blocked
-    keepBlocking  - If TRUE, the station is blocked. If FALSE and the station is
-                    connected, disconnect the station. If FALSE and the station
-                    is not connected, no action is taken.
-
-*******************************************************************************/
-#define CsrWifiNmeApStaRemoveReqCreate(msg__, dst__, src__, interfaceTag__, staMacAddress__, keepBlocking__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApStaRemoveReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STA_REMOVE_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->staMacAddress = (staMacAddress__); \
-    msg__->keepBlocking = (keepBlocking__);
-
-#define CsrWifiNmeApStaRemoveReqSendTo(dst__, src__, interfaceTag__, staMacAddress__, keepBlocking__) \
-    { \
-        CsrWifiNmeApStaRemoveReq *msg__; \
-        CsrWifiNmeApStaRemoveReqCreate(msg__, dst__, src__, interfaceTag__, staMacAddress__, keepBlocking__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApStaRemoveReqSend(src__, interfaceTag__, staMacAddress__, keepBlocking__) \
-    CsrWifiNmeApStaRemoveReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, staMacAddress__, keepBlocking__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStartReqSend
-
-  DESCRIPTION
-    This primitive requests NME to started the AP operation.
-
-  PARAMETERS
-    queue          - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag   - Interface identifier; unique identifier of an interface
-    apType         - AP Type specifies the Legacy AP or P2P GO operation
-    cloakSsid      - Indicates whether the SSID should be cloaked (hidden and
-                     not broadcast in beacon) or not
-    ssid           - Service Set Identifier
-    ifIndex        - Radio interface
-    channel        - Channel number of the channel to use
-    apCredentials  - Security credential configuration.
-    maxConnections - Maximum number of stations/P2P clients allowed
-    p2pGoParam     - P2P specific GO parameters.
-    wpsEnabled     - Indicates whether WPS should be enabled or not
-
-*******************************************************************************/
-#define CsrWifiNmeApStartReqCreate(msg__, dst__, src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApStartReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_START_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->apType = (apType__); \
-    msg__->cloakSsid = (cloakSsid__); \
-    msg__->ssid = (ssid__); \
-    msg__->ifIndex = (ifIndex__); \
-    msg__->channel = (channel__); \
-    msg__->apCredentials = (apCredentials__); \
-    msg__->maxConnections = (maxConnections__); \
-    msg__->p2pGoParam = (p2pGoParam__); \
-    msg__->wpsEnabled = (wpsEnabled__);
-
-#define CsrWifiNmeApStartReqSendTo(dst__, src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__) \
-    { \
-        CsrWifiNmeApStartReq *msg__; \
-        CsrWifiNmeApStartReqCreate(msg__, dst__, src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApStartReqSend(src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__) \
-    CsrWifiNmeApStartReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, apCredentials__, maxConnections__, p2pGoParam__, wpsEnabled__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStartCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of CSR_WIFI_NME_AP_START.request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface identifier; unique identifier of an interface
-    status       - Status of the request.
-    ssid         - Service Set Identifier
-
-*******************************************************************************/
-#define CsrWifiNmeApStartCfmCreate(msg__, dst__, src__, interfaceTag__, status__, ssid__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApStartCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_START_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->ssid = (ssid__);
-
-#define CsrWifiNmeApStartCfmSendTo(dst__, src__, interfaceTag__, status__, ssid__) \
-    { \
-        CsrWifiNmeApStartCfm *msg__; \
-        CsrWifiNmeApStartCfmCreate(msg__, dst__, src__, interfaceTag__, status__, ssid__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApStartCfmSend(dst__, interfaceTag__, status__, ssid__) \
-    CsrWifiNmeApStartCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__, ssid__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStationIndSend
-
-  DESCRIPTION
-    This primitive indicates that a station has joined or a previously joined
-    station has left the BSS/group
-
-  PARAMETERS
-    queue             - Destination Task Queue
-    interfaceTag      - Interface Identifier; unique identifier of an interface
-    mediaStatus       - Indicates whether the station is connected or
-                        disconnected
-    peerMacAddress    - MAC address of the station
-    peerDeviceAddress - P2P Device Address
-
-*******************************************************************************/
-#define CsrWifiNmeApStationIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApStationInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STATION_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->mediaStatus = (mediaStatus__); \
-    msg__->peerMacAddress = (peerMacAddress__); \
-    msg__->peerDeviceAddress = (peerDeviceAddress__);
-
-#define CsrWifiNmeApStationIndSendTo(dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__) \
-    { \
-        CsrWifiNmeApStationInd *msg__; \
-        CsrWifiNmeApStationIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApStationIndSend(dst__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__) \
-    CsrWifiNmeApStationIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStopReqSend
-
-  DESCRIPTION
-    This primitive requests NME to stop the AP operation.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiNmeApStopReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApStopReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STOP_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiNmeApStopReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiNmeApStopReq *msg__; \
-        CsrWifiNmeApStopReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApStopReqSend(src__, interfaceTag__) \
-    CsrWifiNmeApStopReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStopIndSend
-
-  DESCRIPTION
-    Indicates that AP operation had stopped because of some unrecoverable
-    error after AP operation was started successfully. NME sends this signal
-    after failing to restart the AP operation internally following an error
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    apType       - Reports AP Type (P2PGO or AP)
-    status       - Error Status
-
-*******************************************************************************/
-#define CsrWifiNmeApStopIndCreate(msg__, dst__, src__, interfaceTag__, apType__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApStopInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STOP_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->apType = (apType__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeApStopIndSendTo(dst__, src__, interfaceTag__, apType__, status__) \
-    { \
-        CsrWifiNmeApStopInd *msg__; \
-        CsrWifiNmeApStopIndCreate(msg__, dst__, src__, interfaceTag__, apType__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApStopIndSend(dst__, interfaceTag__, apType__, status__) \
-    CsrWifiNmeApStopIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, apType__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStopCfmSend
-
-  DESCRIPTION
-    This primitive confirms that the AP operation is stopped. NME shall send
-    this primitive in response to the request even if AP operation has
-    already been stopped
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface identifier; unique identifier of an interface
-    status       - Status of the request.
-
-*******************************************************************************/
-#define CsrWifiNmeApStopCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApStopCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_STOP_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeApStopCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiNmeApStopCfm *msg__; \
-        CsrWifiNmeApStopCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApStopCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiNmeApStopCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApWmmParamUpdateReqSend
-
-  DESCRIPTION
-    Application uses this primitive to update the WMM parameters
-
-  PARAMETERS
-    queue         - Message Source Task Queue (Cfm's will be sent to this Queue)
-    wmmApParams   - WMM Access point parameters per access category. The array
-                    index corresponds to the ACI
-    wmmApBcParams - WMM station parameters per access category to be advertised
-                    in the beacons and probe response The array index
-                    corresponds to the ACI
-
-*******************************************************************************/
-#define CsrWifiNmeApWmmParamUpdateReqCreate(msg__, dst__, src__, wmmApParams__, wmmApBcParams__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApWmmParamUpdateReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_REQ, dst__, src__); \
-    memcpy(msg__->wmmApParams, (wmmApParams__), sizeof(CsrWifiSmeWmmAcParams) * 4); \
-    memcpy(msg__->wmmApBcParams, (wmmApBcParams__), sizeof(CsrWifiSmeWmmAcParams) * 4);
-
-#define CsrWifiNmeApWmmParamUpdateReqSendTo(dst__, src__, wmmApParams__, wmmApBcParams__) \
-    { \
-        CsrWifiNmeApWmmParamUpdateReq *msg__; \
-        CsrWifiNmeApWmmParamUpdateReqCreate(msg__, dst__, src__, wmmApParams__, wmmApBcParams__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApWmmParamUpdateReqSend(src__, wmmApParams__, wmmApBcParams__) \
-    CsrWifiNmeApWmmParamUpdateReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, wmmApParams__, wmmApBcParams__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApWmmParamUpdateCfmSend
-
-  DESCRIPTION
-    A confirm for for the WMM parameters update
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Status of the request.
-
-*******************************************************************************/
-#define CsrWifiNmeApWmmParamUpdateCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApWmmParamUpdateCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeApWmmParamUpdateCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiNmeApWmmParamUpdateCfm *msg__; \
-        CsrWifiNmeApWmmParamUpdateCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApWmmParamUpdateCfmSend(dst__, status__) \
-    CsrWifiNmeApWmmParamUpdateCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApWpsRegisterReqSend
-
-  DESCRIPTION
-    This primitive allows the NME to accept the WPS registration from an
-    enrollee. Such registration procedure can be cancelled by sending
-    CSR_WIFI_NME_WPS_CANCEL.request.
-
-  PARAMETERS
-    queue                    - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag             - Interface Identifier; unique identifier of an
-                               interface
-    selectedDevicePasswordId - Selected password type
-    selectedConfigMethod     - Selected WPS configuration method type
-    pin                      - PIN value.
-                               Relevant if selected device password ID is PIN.4
-                               digit pin is passed by sending the pin digits in
-                               pin[0]..pin[3] and rest of the contents filled
-                               with '-'.
-
-*******************************************************************************/
-#define CsrWifiNmeApWpsRegisterReqCreate(msg__, dst__, src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApWpsRegisterReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_WPS_REGISTER_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->selectedDevicePasswordId = (selectedDevicePasswordId__); \
-    msg__->selectedConfigMethod = (selectedConfigMethod__); \
-    memcpy(msg__->pin, (pin__), sizeof(u8) * 8);
-
-#define CsrWifiNmeApWpsRegisterReqSendTo(dst__, src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__) \
-    { \
-        CsrWifiNmeApWpsRegisterReq *msg__; \
-        CsrWifiNmeApWpsRegisterReqCreate(msg__, dst__, src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApWpsRegisterReqSend(src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__) \
-    CsrWifiNmeApWpsRegisterReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, selectedDevicePasswordId__, selectedConfigMethod__, pin__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApWpsRegisterCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of WPS procedure.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface identifier; unique identifier of an interface
-    status       - Status of the request.
-
-*******************************************************************************/
-#define CsrWifiNmeApWpsRegisterCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeApWpsRegisterCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_AP_PRIM, CSR_WIFI_NME_AP_WPS_REGISTER_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeApWpsRegisterCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiNmeApWpsRegisterCfm *msg__; \
-        CsrWifiNmeApWpsRegisterCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeApWpsRegisterCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiNmeApWpsRegisterCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__)
-
-#endif /* CSR_WIFI_NME_AP_LIB_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_prim.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_prim.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_prim.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_prim.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,494 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_NME_AP_PRIM_H__
-#define CSR_WIFI_NME_AP_PRIM_H__
-
-#include <linux/types.h>
-#include "csr_prim_defs.h"
-#include "csr_sched.h"
-#include "csr_wifi_common.h"
-#include "csr_result.h"
-#include "csr_wifi_fsm_event.h"
-#include "csr_wifi_sme_ap_prim.h"
-#include "csr_wifi_nme_prim.h"
-
-#ifndef CSR_WIFI_NME_ENABLE
-#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_prim.h
-#endif
-#ifndef CSR_WIFI_AP_ENABLE
-#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_prim.h
-#endif
-
-#define CSR_WIFI_NME_AP_PRIM                                            (0x0426)
-
-typedef CsrPrim CsrWifiNmeApPrim;
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApPersCredentialType
-
-  DESCRIPTION
-    NME Credential Types
-
- VALUES
-    CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK
-                   - Use PSK as credential.
-    CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE
-                   - Use the specified passphrase as credential
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeApPersCredentialType;
-#define CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK          ((CsrWifiNmeApPersCredentialType) 0x00)
-#define CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE   ((CsrWifiNmeApPersCredentialType) 0x01)
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApConfig
-
-  DESCRIPTION
-    Structure holding AP config data.
-
-  MEMBERS
-    apGroupkeyTimeout - Access point group key timeout.
-    apStrictGtkRekey  - Access point strict GTK rekey flag. If set TRUE, the AP
-                        shall rekey GTK every time a connected STA leaves BSS.
-    apGmkTimeout      - Access point GMK timeout
-    apResponseTimeout - Response timeout
-    apRetransLimit    - Max allowed retransmissions
-
-*******************************************************************************/
-typedef struct
-{
-    u16 apGroupkeyTimeout;
-    u8   apStrictGtkRekey;
-    u16 apGmkTimeout;
-    u16 apResponseTimeout;
-    u8  apRetransLimit;
-} CsrWifiNmeApConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApAuthPers
-
-  DESCRIPTION
-
-  MEMBERS
-    authSupport                     - Credential type value (as defined in the
-                                      enumeration type).
-    rsnCapabilities                 - RSN capabilities mask
-    wapiCapabilities                - WAPI capabilities mask
-    pskOrPassphrase                 - Credential type value (as defined in the
-                                      enumeration type).
-    authPers_credentials            - Union containing credentials which depends
-                                      on credentialType parameter.
-    authPers_credentialspsk         -
-    authPers_credentialspassphrase  -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeApAuthSupportMask      authSupport;
-    CsrWifiSmeApRsnCapabilitiesMask  rsnCapabilities;
-    CsrWifiSmeApWapiCapabilitiesMask wapiCapabilities;
-    CsrWifiNmeApPersCredentialType   pskOrPassphrase;
-    union {
-        CsrWifiNmePsk        psk;
-        CsrWifiNmePassphrase passphrase;
-    } authPers_credentials;
-} CsrWifiNmeApAuthPers;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApCredentials
-
-  DESCRIPTION
-    Structure containing the Credentials data.
-
-  MEMBERS
-    authType                     - Authentication type
-    nmeAuthType                  - Authentication parameters
-    nmeAuthTypeopenSystemEmpty   -
-    nmeAuthTypeauthwep           -
-    nmeAuthTypeauthTypePersonal  -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeApAuthType authType;
-    union {
-        CsrWifiSmeEmpty      openSystemEmpty;
-        CsrWifiSmeWepAuth    authwep;
-        CsrWifiNmeApAuthPers authTypePersonal;
-    } nmeAuthType;
-} CsrWifiNmeApCredentials;
-
-
-/* Downstream */
-#define CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST            (0x0000)
-
-#define CSR_WIFI_NME_AP_CONFIG_SET_REQ                    ((CsrWifiNmeApPrim) (0x0000 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_WPS_REGISTER_REQ                  ((CsrWifiNmeApPrim) (0x0001 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_START_REQ                         ((CsrWifiNmeApPrim) (0x0002 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_STOP_REQ                          ((CsrWifiNmeApPrim) (0x0003 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_REQ              ((CsrWifiNmeApPrim) (0x0004 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_STA_REMOVE_REQ                    ((CsrWifiNmeApPrim) (0x0005 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST))
-
-
-#define CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_HIGHEST           (0x0005 + CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST)
-
-/* Upstream */
-#define CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST              (0x0000 + CSR_PRIM_UPSTREAM)
-
-#define CSR_WIFI_NME_AP_CONFIG_SET_CFM                    ((CsrWifiNmeApPrim)(0x0000 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_WPS_REGISTER_CFM                  ((CsrWifiNmeApPrim)(0x0001 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_START_CFM                         ((CsrWifiNmeApPrim)(0x0002 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_STOP_CFM                          ((CsrWifiNmeApPrim)(0x0003 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_STOP_IND                          ((CsrWifiNmeApPrim)(0x0004 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_WMM_PARAM_UPDATE_CFM              ((CsrWifiNmeApPrim)(0x0005 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_AP_STATION_IND                       ((CsrWifiNmeApPrim)(0x0006 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST))
-
-#define CSR_WIFI_NME_AP_PRIM_UPSTREAM_HIGHEST             (0x0006 + CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST)
-
-#define CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT             (CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_LOWEST)
-#define CSR_WIFI_NME_AP_PRIM_UPSTREAM_COUNT               (CSR_WIFI_NME_AP_PRIM_UPSTREAM_HIGHEST   + 1 - CSR_WIFI_NME_AP_PRIM_UPSTREAM_LOWEST)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApConfigSetReq
-
-  DESCRIPTION
-    This primitive passes AP configuration info for NME. This can be sent at
-    any time but will be acted upon when the AP is started again. This
-    information is common to both P2P GO and AP
-
-  MEMBERS
-    common      - Common header for use with the CsrWifiFsm Module
-    apConfig    - AP configuration for the NME.
-    apMacConfig - MAC configuration to be acted on when
-                  CSR_WIFI_NME_AP_START.request is sent.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    CsrWifiNmeApConfig    apConfig;
-    CsrWifiSmeApMacConfig apMacConfig;
-} CsrWifiNmeApConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApWpsRegisterReq
-
-  DESCRIPTION
-    This primitive allows the NME to accept the WPS registration from an
-    enrollee. Such registration procedure can be cancelled by sending
-    CSR_WIFI_NME_WPS_CANCEL.request.
-
-  MEMBERS
-    common                   - Common header for use with the CsrWifiFsm Module
-    interfaceTag             - Interface Identifier; unique identifier of an
-                               interface
-    selectedDevicePasswordId - Selected password type
-    selectedConfigMethod     - Selected WPS configuration method type
-    pin                      - PIN value.
-                               Relevant if selected device password ID is PIN.4
-                               digit pin is passed by sending the pin digits in
-                               pin[0]..pin[3] and rest of the contents filled
-                               with '-'.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent         common;
-    u16               interfaceTag;
-    CsrWifiSmeWpsDpid       selectedDevicePasswordId;
-    CsrWifiSmeWpsConfigType selectedConfigMethod;
-    u8                pin[8];
-} CsrWifiNmeApWpsRegisterReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStartReq
-
-  DESCRIPTION
-    This primitive requests NME to started the AP operation.
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   - Interface identifier; unique identifier of an interface
-    apType         - AP Type specifies the Legacy AP or P2P GO operation
-    cloakSsid      - Indicates whether the SSID should be cloaked (hidden and
-                     not broadcast in beacon) or not
-    ssid           - Service Set Identifier
-    ifIndex        - Radio interface
-    channel        - Channel number of the channel to use
-    apCredentials  - Security credential configuration.
-    maxConnections - Maximum number of stations/P2P clients allowed
-    p2pGoParam     - P2P specific GO parameters.
-    wpsEnabled     - Indicates whether WPS should be enabled or not
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent         common;
-    u16               interfaceTag;
-    CsrWifiSmeApType        apType;
-    u8                 cloakSsid;
-    CsrWifiSsid             ssid;
-    CsrWifiSmeRadioIF       ifIndex;
-    u8                channel;
-    CsrWifiNmeApCredentials apCredentials;
-    u8                maxConnections;
-    CsrWifiSmeApP2pGoConfig p2pGoParam;
-    u8                 wpsEnabled;
-} CsrWifiNmeApStartReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStopReq
-
-  DESCRIPTION
-    This primitive requests NME to stop the AP operation.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiNmeApStopReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApWmmParamUpdateReq
-
-  DESCRIPTION
-    Application uses this primitive to update the WMM parameters
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    wmmApParams   - WMM Access point parameters per access category. The array
-                    index corresponds to the ACI
-    wmmApBcParams - WMM station parameters per access category to be advertised
-                    in the beacons and probe response The array index
-                    corresponds to the ACI
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    CsrWifiSmeWmmAcParams wmmApParams[4];
-    CsrWifiSmeWmmAcParams wmmApBcParams[4];
-} CsrWifiNmeApWmmParamUpdateReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStaRemoveReq
-
-  DESCRIPTION
-    This primitive disconnects a connected station. If keepBlocking is set to
-    TRUE, the station with the specified MAC address is not allowed to
-    connect. If the requested station is not already connected,it may be
-    blocked based on keepBlocking parameter.
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    staMacAddress - Mac Address of the station to be disconnected or blocked
-    keepBlocking  - If TRUE, the station is blocked. If FALSE and the station is
-                    connected, disconnect the station. If FALSE and the station
-                    is not connected, no action is taken.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    u16         interfaceTag;
-    CsrWifiMacAddress staMacAddress;
-    u8           keepBlocking;
-} CsrWifiNmeApStaRemoveReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApConfigSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Status of the request.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiNmeApConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApWpsRegisterCfm
-
-  DESCRIPTION
-    This primitive reports the result of WPS procedure.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface identifier; unique identifier of an interface
-    status       - Status of the request.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiNmeApWpsRegisterCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStartCfm
-
-  DESCRIPTION
-    This primitive reports the result of CSR_WIFI_NME_AP_START.request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface identifier; unique identifier of an interface
-    status       - Status of the request.
-    ssid         - Service Set Identifier
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-    CsrWifiSsid     ssid;
-} CsrWifiNmeApStartCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStopCfm
-
-  DESCRIPTION
-    This primitive confirms that the AP operation is stopped. NME shall send
-    this primitive in response to the request even if AP operation has
-    already been stopped
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface identifier; unique identifier of an interface
-    status       - Status of the request.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiNmeApStopCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStopInd
-
-  DESCRIPTION
-    Indicates that AP operation had stopped because of some unrecoverable
-    error after AP operation was started successfully. NME sends this signal
-    after failing to restart the AP operation internally following an error
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    apType       - Reports AP Type (P2PGO or AP)
-    status       - Error Status
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent  common;
-    u16        interfaceTag;
-    CsrWifiSmeApType apType;
-    CsrResult        status;
-} CsrWifiNmeApStopInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApWmmParamUpdateCfm
-
-  DESCRIPTION
-    A confirm for for the WMM parameters update
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Status of the request.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiNmeApWmmParamUpdateCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeApStationInd
-
-  DESCRIPTION
-    This primitive indicates that a station has joined or a previously joined
-    station has left the BSS/group
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    interfaceTag      - Interface Identifier; unique identifier of an interface
-    mediaStatus       - Indicates whether the station is connected or
-                        disconnected
-    peerMacAddress    - MAC address of the station
-    peerDeviceAddress - P2P Device Address
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    u16             interfaceTag;
-    CsrWifiSmeMediaStatus mediaStatus;
-    CsrWifiMacAddress     peerMacAddress;
-    CsrWifiMacAddress     peerDeviceAddress;
-} CsrWifiNmeApStationInd;
-
-#endif /* CSR_WIFI_NME_AP_PRIM_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_sef.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_sef.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_sef.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_sef.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/*****************************************************************************
-
-  FILE: csr_wifi_nme_sef.c
-
-  (c) Cambridge Silicon Radio Limited 2010
-
-  Refer to LICENSE.txt included with this source for details
-  on the license terms.
-
- *****************************************************************************/
-#include "csr_wifi_nme_ap_sef.h"
-#include "unifi_priv.h"
-
-void CsrWifiNmeApUpstreamStateHandlers(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    switch(msg->type) {
-        case CSR_WIFI_NME_AP_START_CFM:
-            CsrWifiNmeApStartCfmHandler(drvpriv, msg);
-            break;
-        case CSR_WIFI_NME_AP_STOP_CFM:
-            CsrWifiNmeApStopCfmHandler(drvpriv, msg);
-            break;
-        case CSR_WIFI_NME_AP_CONFIG_SET_CFM:
-            CsrWifiNmeApConfigSetCfmHandler(drvpriv,msg);
-            break;
-        default:
-	    unifi_error(drvpriv, "CsrWifiNmeApUpstreamStateHandlers: unhandled NME_AP message type 0x%.4X\n",msg->type);
-            break;
-    }
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_sef.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_sef.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_sef.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_sef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-/*****************************************************************************
-    FILE: csr_wifi_nme_sef.h
-    (c) Cambridge Silicon Radio Limited 2010
-
-    Refer to LICENSE.txt included with this source for details
-    on the license terms.
-
-*****************************************************************************/
-#ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_NME_H__
-#define CSR_WIFI_ROUTER_SEF_CSR_WIFI_NME_H__
-
-#include "csr_wifi_nme_prim.h"
-
-void CsrWifiNmeApUpstreamStateHandlers(void* drvpriv, CsrWifiFsmEvent* msg);
-
-
-extern void CsrWifiNmeApConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiNmeApStartCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-extern void CsrWifiNmeApStopCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-
-#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_NME_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_serialize.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_serialize.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_serialize.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_serialize.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,909 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "csr_msgconv.h"
-
-#ifdef CSR_WIFI_NME_ENABLE
-#ifdef CSR_WIFI_AP_ENABLE
-
-#include "csr_wifi_nme_ap_prim.h"
-#include "csr_wifi_nme_ap_serialize.h"
-
-void CsrWifiNmeApPfree(void *ptr)
-{
-    kfree(ptr);
-}
-
-
-size_t CsrWifiNmeApConfigSetReqSizeof(void *msg)
-{
-    CsrWifiNmeApConfigSetReq *primitive = (CsrWifiNmeApConfigSetReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 104) */
-    bufferSize += 2;  /* u16 primitive->apConfig.apGroupkeyTimeout */
-    bufferSize += 1;  /* u8 primitive->apConfig.apStrictGtkRekey */
-    bufferSize += 2;  /* u16 primitive->apConfig.apGmkTimeout */
-    bufferSize += 2;  /* u16 primitive->apConfig.apResponseTimeout */
-    bufferSize += 1;  /* u8 primitive->apConfig.apRetransLimit */
-    bufferSize += 1;  /* CsrWifiSmeApPhySupportMask primitive->apMacConfig.phySupportedBitmap */
-    bufferSize += 2;  /* u16 primitive->apMacConfig.beaconInterval */
-    bufferSize += 1;  /* u8 primitive->apMacConfig.dtimPeriod */
-    bufferSize += 2;  /* u16 primitive->apMacConfig.maxListenInterval */
-    bufferSize += 1;  /* u8 primitive->apMacConfig.supportedRatesCount */
-    bufferSize += 20; /* u8 primitive->apMacConfig.supportedRates[20] */
-    bufferSize += 1;  /* CsrWifiSmePreambleType primitive->apMacConfig.preamble */
-    bufferSize += 1;  /* u8 primitive->apMacConfig.shortSlotTimeEnabled */
-    bufferSize += 1;  /* CsrWifiSmeCtsProtectionType primitive->apMacConfig.ctsProtectionType */
-    bufferSize += 1;  /* u8 primitive->apMacConfig.wmmEnabled */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            bufferSize += 1; /* u8 primitive->apMacConfig.wmmApParams[i2].cwMin */
-            bufferSize += 1; /* u8 primitive->apMacConfig.wmmApParams[i2].cwMax */
-            bufferSize += 1; /* u8 primitive->apMacConfig.wmmApParams[i2].aifs */
-            bufferSize += 2; /* u16 primitive->apMacConfig.wmmApParams[i2].txopLimit */
-            bufferSize += 1; /* u8 primitive->apMacConfig.wmmApParams[i2].admissionControlMandatory */
-        }
-    }
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            bufferSize += 1; /* u8 primitive->apMacConfig.wmmApBcParams[i2].cwMin */
-            bufferSize += 1; /* u8 primitive->apMacConfig.wmmApBcParams[i2].cwMax */
-            bufferSize += 1; /* u8 primitive->apMacConfig.wmmApBcParams[i2].aifs */
-            bufferSize += 2; /* u16 primitive->apMacConfig.wmmApBcParams[i2].txopLimit */
-            bufferSize += 1; /* u8 primitive->apMacConfig.wmmApBcParams[i2].admissionControlMandatory */
-        }
-    }
-    bufferSize += 1;         /* CsrWifiSmeApAccessType primitive->apMacConfig.accessType */
-    bufferSize += 1;         /* u8 primitive->apMacConfig.macAddressListCount */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->apMacConfig.macAddressListCount; i2++)
-        {
-            bufferSize += 6; /* u8 primitive->apMacConfig.macAddressList[i2].a[6] */
-        }
-    }
-    bufferSize += 1;         /* u8 primitive->apMacConfig.apHtParams.greenfieldSupported */
-    bufferSize += 1;         /* u8 primitive->apMacConfig.apHtParams.shortGi20MHz */
-    bufferSize += 1;         /* u8 primitive->apMacConfig.apHtParams.rxStbc */
-    bufferSize += 1;         /* u8 primitive->apMacConfig.apHtParams.rifsModeAllowed */
-    bufferSize += 1;         /* u8 primitive->apMacConfig.apHtParams.htProtection */
-    bufferSize += 1;         /* u8 primitive->apMacConfig.apHtParams.dualCtsProtection */
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApConfigSetReq *primitive = (CsrWifiNmeApConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->apConfig.apGroupkeyTimeout);
-    CsrUint8Ser(ptr, len, (u8) primitive->apConfig.apStrictGtkRekey);
-    CsrUint16Ser(ptr, len, (u16) primitive->apConfig.apGmkTimeout);
-    CsrUint16Ser(ptr, len, (u16) primitive->apConfig.apResponseTimeout);
-    CsrUint8Ser(ptr, len, (u8) primitive->apConfig.apRetransLimit);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.phySupportedBitmap);
-    CsrUint16Ser(ptr, len, (u16) primitive->apMacConfig.beaconInterval);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.dtimPeriod);
-    CsrUint16Ser(ptr, len, (u16) primitive->apMacConfig.maxListenInterval);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.supportedRatesCount);
-    CsrMemCpySer(ptr, len, (const void *) primitive->apMacConfig.supportedRates, ((u16) (20)));
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.preamble);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.shortSlotTimeEnabled);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.ctsProtectionType);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.wmmEnabled);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.wmmApParams[i2].cwMin);
-            CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.wmmApParams[i2].cwMax);
-            CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.wmmApParams[i2].aifs);
-            CsrUint16Ser(ptr, len, (u16) primitive->apMacConfig.wmmApParams[i2].txopLimit);
-            CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.wmmApParams[i2].admissionControlMandatory);
-        }
-    }
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.wmmApBcParams[i2].cwMin);
-            CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.wmmApBcParams[i2].cwMax);
-            CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.wmmApBcParams[i2].aifs);
-            CsrUint16Ser(ptr, len, (u16) primitive->apMacConfig.wmmApBcParams[i2].txopLimit);
-            CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.wmmApBcParams[i2].admissionControlMandatory);
-        }
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.accessType);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.macAddressListCount);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->apMacConfig.macAddressListCount; i2++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->apMacConfig.macAddressList[i2].a, ((u16) (6)));
-        }
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.apHtParams.greenfieldSupported);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.apHtParams.shortGi20MHz);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.apHtParams.rxStbc);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.apHtParams.rifsModeAllowed);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.apHtParams.htProtection);
-    CsrUint8Ser(ptr, len, (u8) primitive->apMacConfig.apHtParams.dualCtsProtection);
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApConfigSetReq *primitive = kmalloc(sizeof(CsrWifiNmeApConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->apConfig.apGroupkeyTimeout, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apConfig.apStrictGtkRekey, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->apConfig.apGmkTimeout, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->apConfig.apResponseTimeout, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apConfig.apRetransLimit, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.phySupportedBitmap, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->apMacConfig.beaconInterval, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.dtimPeriod, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->apMacConfig.maxListenInterval, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.supportedRatesCount, buffer, &offset);
-    CsrMemCpyDes(primitive->apMacConfig.supportedRates, buffer, &offset, ((u16) (20)));
-    CsrUint8Des((u8 *) &primitive->apMacConfig.preamble, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.shortSlotTimeEnabled, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.ctsProtectionType, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.wmmEnabled, buffer, &offset);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            CsrUint8Des((u8 *) &primitive->apMacConfig.wmmApParams[i2].cwMin, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->apMacConfig.wmmApParams[i2].cwMax, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->apMacConfig.wmmApParams[i2].aifs, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->apMacConfig.wmmApParams[i2].txopLimit, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->apMacConfig.wmmApParams[i2].admissionControlMandatory, buffer, &offset);
-        }
-    }
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            CsrUint8Des((u8 *) &primitive->apMacConfig.wmmApBcParams[i2].cwMin, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->apMacConfig.wmmApBcParams[i2].cwMax, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->apMacConfig.wmmApBcParams[i2].aifs, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->apMacConfig.wmmApBcParams[i2].txopLimit, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->apMacConfig.wmmApBcParams[i2].admissionControlMandatory, buffer, &offset);
-        }
-    }
-    CsrUint8Des((u8 *) &primitive->apMacConfig.accessType, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.macAddressListCount, buffer, &offset);
-    primitive->apMacConfig.macAddressList = NULL;
-    if (primitive->apMacConfig.macAddressListCount)
-    {
-        primitive->apMacConfig.macAddressList = kmalloc(sizeof(CsrWifiMacAddress) * primitive->apMacConfig.macAddressListCount, GFP_KERNEL);
-    }
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->apMacConfig.macAddressListCount; i2++)
-        {
-            CsrMemCpyDes(primitive->apMacConfig.macAddressList[i2].a, buffer, &offset, ((u16) (6)));
-        }
-    }
-    CsrUint8Des((u8 *) &primitive->apMacConfig.apHtParams.greenfieldSupported, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.apHtParams.shortGi20MHz, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.apHtParams.rxStbc, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.apHtParams.rifsModeAllowed, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.apHtParams.htProtection, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apMacConfig.apHtParams.dualCtsProtection, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiNmeApConfigSetReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiNmeApConfigSetReq *primitive = (CsrWifiNmeApConfigSetReq *) voidPrimitivePointer;
-    kfree(primitive->apMacConfig.macAddressList);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiNmeApWpsRegisterReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiSmeWpsDpid primitive->selectedDevicePasswordId */
-    bufferSize += 2; /* CsrWifiSmeWpsConfigType primitive->selectedConfigMethod */
-    bufferSize += 8; /* u8 primitive->pin[8] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApWpsRegisterReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApWpsRegisterReq *primitive = (CsrWifiNmeApWpsRegisterReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->selectedDevicePasswordId);
-    CsrUint16Ser(ptr, len, (u16) primitive->selectedConfigMethod);
-    CsrMemCpySer(ptr, len, (const void *) primitive->pin, ((u16) (8)));
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApWpsRegisterReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApWpsRegisterReq *primitive = kmalloc(sizeof(CsrWifiNmeApWpsRegisterReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->selectedDevicePasswordId, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->selectedConfigMethod, buffer, &offset);
-    CsrMemCpyDes(primitive->pin, buffer, &offset, ((u16) (8)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiNmeApStartReqSizeof(void *msg)
-{
-    CsrWifiNmeApStartReq *primitive = (CsrWifiNmeApStartReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 112) */
-    bufferSize += 2;  /* u16 primitive->interfaceTag */
-    bufferSize += 1;  /* CsrWifiSmeApType primitive->apType */
-    bufferSize += 1;  /* u8 primitive->cloakSsid */
-    bufferSize += 32; /* u8 primitive->ssid.ssid[32] */
-    bufferSize += 1;  /* u8 primitive->ssid.length */
-    bufferSize += 1;  /* CsrWifiSmeRadioIF primitive->ifIndex */
-    bufferSize += 1;  /* u8 primitive->channel */
-    bufferSize += 1;  /* CsrWifiSmeApAuthType primitive->apCredentials.authType */
-    switch (primitive->apCredentials.authType)
-    {
-        case CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM:
-            bufferSize += 1; /* u8 primitive->apCredentials.nmeAuthType.openSystemEmpty.empty */
-            break;
-        case CSR_WIFI_SME_AP_AUTH_TYPE_WEP:
-            bufferSize += 1; /* CsrWifiSmeWepCredentialType primitive->apCredentials.nmeAuthType.authwep.wepKeyType */
-            switch (primitive->apCredentials.nmeAuthType.authwep.wepKeyType)
-            {
-                case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128:
-                    bufferSize += 1;  /* CsrWifiSmeWepAuthMode primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.wepAuthType */
-                    bufferSize += 1;  /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.selectedWepKey */
-                    bufferSize += 13; /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key1[13] */
-                    bufferSize += 13; /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key2[13] */
-                    bufferSize += 13; /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key3[13] */
-                    bufferSize += 13; /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key4[13] */
-                    break;
-                case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64:
-                    bufferSize += 1;  /* CsrWifiSmeWepAuthMode primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.wepAuthType */
-                    bufferSize += 1;  /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.selectedWepKey */
-                    bufferSize += 5;  /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key1[5] */
-                    bufferSize += 5;  /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key2[5] */
-                    bufferSize += 5;  /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key3[5] */
-                    bufferSize += 5;  /* u8 primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key4[5] */
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL:
-            bufferSize += 1; /* CsrWifiSmeApAuthSupportMask primitive->apCredentials.nmeAuthType.authTypePersonal.authSupport */
-            bufferSize += 2; /* CsrWifiSmeApRsnCapabilitiesMask primitive->apCredentials.nmeAuthType.authTypePersonal.rsnCapabilities */
-            bufferSize += 2; /* CsrWifiSmeApWapiCapabilitiesMask primitive->apCredentials.nmeAuthType.authTypePersonal.wapiCapabilities */
-            bufferSize += 1; /* CsrWifiNmeApPersCredentialType primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase */
-            switch (primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase)
-            {
-                case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK:
-                    bufferSize += 2;                                                                                                                                                                                                                      /* u16 primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.encryptionMode */
-                    bufferSize += 32;                                                                                                                                                                                                                     /* u8 primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.psk[32] */
-                    break;
-                case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE:
-                    bufferSize += 2;                                                                                                                                                                                                                      /* u16 primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.encryptionMode */
-                    bufferSize += (primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase ? strlen(primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase) : 0) + 1; /* char* primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase (0 byte len + 1 for NULL Term) */
-                    break;
-                default:
-                    break;
-            }
-            break;
-        default:
-            break;
-    }
-    bufferSize += 1; /* u8 primitive->maxConnections */
-    bufferSize += 1; /* CsrWifiSmeP2pGroupCapabilityMask primitive->p2pGoParam.groupCapability */
-    bufferSize += 3; /* u8 primitive->p2pGoParam.operatingChanList.country[3] */
-    bufferSize += 1; /* u8 primitive->p2pGoParam.operatingChanList.channelEntryListCount */
-    {
-        u16 i3;
-        for (i3 = 0; i3 < primitive->p2pGoParam.operatingChanList.channelEntryListCount; i3++)
-        {
-            bufferSize += 1;                                                                                  /* u8 primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingClass */
-            bufferSize += 1;                                                                                  /* u8 primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount */
-            bufferSize += primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount; /* u8 primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel */
-        }
-    }
-    bufferSize += 1;                                                                                          /* u8 primitive->p2pGoParam.opPsEnabled */
-    bufferSize += 1;                                                                                          /* u8 primitive->p2pGoParam.ctWindow */
-    bufferSize += 1;                                                                                          /* CsrWifiSmeP2pNoaConfigMethod primitive->p2pGoParam.noaConfigMethod */
-    bufferSize += 1;                                                                                          /* u8 primitive->p2pGoParam.allowNoaWithNonP2pDevices */
-    bufferSize += 1;                                                                                          /* u8 primitive->wpsEnabled */
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApStartReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApStartReq *primitive = (CsrWifiNmeApStartReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->apType);
-    CsrUint8Ser(ptr, len, (u8) primitive->cloakSsid);
-    CsrMemCpySer(ptr, len, (const void *) primitive->ssid.ssid, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->ssid.length);
-    CsrUint8Ser(ptr, len, (u8) primitive->ifIndex);
-    CsrUint8Ser(ptr, len, (u8) primitive->channel);
-    CsrUint8Ser(ptr, len, (u8) primitive->apCredentials.authType);
-    switch (primitive->apCredentials.authType)
-    {
-        case CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM:
-            CsrUint8Ser(ptr, len, (u8) primitive->apCredentials.nmeAuthType.openSystemEmpty.empty);
-            break;
-        case CSR_WIFI_SME_AP_AUTH_TYPE_WEP:
-            CsrUint8Ser(ptr, len, (u8) primitive->apCredentials.nmeAuthType.authwep.wepKeyType);
-            switch (primitive->apCredentials.nmeAuthType.authwep.wepKeyType)
-            {
-                case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128:
-                    CsrUint8Ser(ptr, len, (u8) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.wepAuthType);
-                    CsrUint8Ser(ptr, len, (u8) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.selectedWepKey);
-                    CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key1, ((u16) (13)));
-                    CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key2, ((u16) (13)));
-                    CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key3, ((u16) (13)));
-                    CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key4, ((u16) (13)));
-                    break;
-                case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64:
-                    CsrUint8Ser(ptr, len, (u8) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.wepAuthType);
-                    CsrUint8Ser(ptr, len, (u8) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.selectedWepKey);
-                    CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key1, ((u16) (5)));
-                    CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key2, ((u16) (5)));
-                    CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key3, ((u16) (5)));
-                    CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key4, ((u16) (5)));
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL:
-            CsrUint8Ser(ptr, len, (u8) primitive->apCredentials.nmeAuthType.authTypePersonal.authSupport);
-            CsrUint16Ser(ptr, len, (u16) primitive->apCredentials.nmeAuthType.authTypePersonal.rsnCapabilities);
-            CsrUint16Ser(ptr, len, (u16) primitive->apCredentials.nmeAuthType.authTypePersonal.wapiCapabilities);
-            CsrUint8Ser(ptr, len, (u8) primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase);
-            switch (primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase)
-            {
-                case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK:
-                    CsrUint16Ser(ptr, len, (u16) primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.encryptionMode);
-                    CsrMemCpySer(ptr, len, (const void *) primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.psk, ((u16) (32)));
-                    break;
-                case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE:
-                    CsrUint16Ser(ptr, len, (u16) primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.encryptionMode);
-                    CsrCharStringSer(ptr, len, primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase);
-                    break;
-                default:
-                    break;
-            }
-            break;
-        default:
-            break;
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->maxConnections);
-    CsrUint8Ser(ptr, len, (u8) primitive->p2pGoParam.groupCapability);
-    CsrMemCpySer(ptr, len, (const void *) primitive->p2pGoParam.operatingChanList.country, ((u16) (3)));
-    CsrUint8Ser(ptr, len, (u8) primitive->p2pGoParam.operatingChanList.channelEntryListCount);
-    {
-        u16 i3;
-        for (i3 = 0; i3 < primitive->p2pGoParam.operatingChanList.channelEntryListCount; i3++)
-        {
-            CsrUint8Ser(ptr, len, (u8) primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingClass);
-            CsrUint8Ser(ptr, len, (u8) primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount);
-            if (primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount)
-            {
-                CsrMemCpySer(ptr, len, (const void *) primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel, ((u16) (primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount)));
-            }
-        }
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->p2pGoParam.opPsEnabled);
-    CsrUint8Ser(ptr, len, (u8) primitive->p2pGoParam.ctWindow);
-    CsrUint8Ser(ptr, len, (u8) primitive->p2pGoParam.noaConfigMethod);
-    CsrUint8Ser(ptr, len, (u8) primitive->p2pGoParam.allowNoaWithNonP2pDevices);
-    CsrUint8Ser(ptr, len, (u8) primitive->wpsEnabled);
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApStartReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApStartReq *primitive = kmalloc(sizeof(CsrWifiNmeApStartReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apType, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->cloakSsid, buffer, &offset);
-    CsrMemCpyDes(primitive->ssid.ssid, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->ssid.length, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ifIndex, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->channel, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apCredentials.authType, buffer, &offset);
-    switch (primitive->apCredentials.authType)
-    {
-        case CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM:
-            CsrUint8Des((u8 *) &primitive->apCredentials.nmeAuthType.openSystemEmpty.empty, buffer, &offset);
-            break;
-        case CSR_WIFI_SME_AP_AUTH_TYPE_WEP:
-            CsrUint8Des((u8 *) &primitive->apCredentials.nmeAuthType.authwep.wepKeyType, buffer, &offset);
-            switch (primitive->apCredentials.nmeAuthType.authwep.wepKeyType)
-            {
-                case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128:
-                    CsrUint8Des((u8 *) &primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.wepAuthType, buffer, &offset);
-                    CsrUint8Des((u8 *) &primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.selectedWepKey, buffer, &offset);
-                    CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key1, buffer, &offset, ((u16) (13)));
-                    CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key2, buffer, &offset, ((u16) (13)));
-                    CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key3, buffer, &offset, ((u16) (13)));
-                    CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep128Key.key4, buffer, &offset, ((u16) (13)));
-                    break;
-                case CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64:
-                    CsrUint8Des((u8 *) &primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.wepAuthType, buffer, &offset);
-                    CsrUint8Des((u8 *) &primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.selectedWepKey, buffer, &offset);
-                    CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key1, buffer, &offset, ((u16) (5)));
-                    CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key2, buffer, &offset, ((u16) (5)));
-                    CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key3, buffer, &offset, ((u16) (5)));
-                    CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authwep.wepCredentials.wep64Key.key4, buffer, &offset, ((u16) (5)));
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL:
-            CsrUint8Des((u8 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.authSupport, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.rsnCapabilities, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.wapiCapabilities, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase, buffer, &offset);
-            switch (primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase)
-            {
-                case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK:
-                    CsrUint16Des((u16 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.encryptionMode, buffer, &offset);
-                    CsrMemCpyDes(primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.psk.psk, buffer, &offset, ((u16) (32)));
-                    break;
-                case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE:
-                    CsrUint16Des((u16 *) &primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.encryptionMode, buffer, &offset);
-                    CsrCharStringDes(&primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase, buffer, &offset);
-                    break;
-                default:
-                    break;
-            }
-            break;
-        default:
-            break;
-    }
-    CsrUint8Des((u8 *) &primitive->maxConnections, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->p2pGoParam.groupCapability, buffer, &offset);
-    CsrMemCpyDes(primitive->p2pGoParam.operatingChanList.country, buffer, &offset, ((u16) (3)));
-    CsrUint8Des((u8 *) &primitive->p2pGoParam.operatingChanList.channelEntryListCount, buffer, &offset);
-    primitive->p2pGoParam.operatingChanList.channelEntryList = NULL;
-    if (primitive->p2pGoParam.operatingChanList.channelEntryListCount)
-    {
-        primitive->p2pGoParam.operatingChanList.channelEntryList = kmalloc(sizeof(CsrWifiSmeApP2pOperatingChanEntry) * primitive->p2pGoParam.operatingChanList.channelEntryListCount, GFP_KERNEL);
-    }
-    {
-        u16 i3;
-        for (i3 = 0; i3 < primitive->p2pGoParam.operatingChanList.channelEntryListCount; i3++)
-        {
-            CsrUint8Des((u8 *) &primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingClass, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount, buffer, &offset);
-            if (primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount)
-            {
-                primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel = kmalloc(primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount, GFP_KERNEL);
-                CsrMemCpyDes(primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel, buffer, &offset, ((u16) (primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannelCount)));
-            }
-            else
-            {
-                primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel = NULL;
-            }
-        }
-    }
-    CsrUint8Des((u8 *) &primitive->p2pGoParam.opPsEnabled, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->p2pGoParam.ctWindow, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->p2pGoParam.noaConfigMethod, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->p2pGoParam.allowNoaWithNonP2pDevices, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->wpsEnabled, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiNmeApStartReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiNmeApStartReq *primitive = (CsrWifiNmeApStartReq *) voidPrimitivePointer;
-    switch (primitive->apCredentials.authType)
-    {
-        case CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL:
-            switch (primitive->apCredentials.nmeAuthType.authTypePersonal.pskOrPassphrase)
-            {
-                case CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PASSPHRASE:
-                    kfree(primitive->apCredentials.nmeAuthType.authTypePersonal.authPers_credentials.passphrase.passphrase);
-                    break;
-                default:
-                    break;
-            }
-            break;
-        default:
-            break;
-    }
-    {
-        u16 i3;
-        for (i3 = 0; i3 < primitive->p2pGoParam.operatingChanList.channelEntryListCount; i3++)
-        {
-            kfree(primitive->p2pGoParam.operatingChanList.channelEntryList[i3].operatingChannel);
-        }
-    }
-    kfree(primitive->p2pGoParam.operatingChanList.channelEntryList);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiNmeApWmmParamUpdateReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 51) */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 4; i1++)
-        {
-            bufferSize += 1; /* u8 primitive->wmmApParams[i1].cwMin */
-            bufferSize += 1; /* u8 primitive->wmmApParams[i1].cwMax */
-            bufferSize += 1; /* u8 primitive->wmmApParams[i1].aifs */
-            bufferSize += 2; /* u16 primitive->wmmApParams[i1].txopLimit */
-            bufferSize += 1; /* u8 primitive->wmmApParams[i1].admissionControlMandatory */
-        }
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 4; i1++)
-        {
-            bufferSize += 1; /* u8 primitive->wmmApBcParams[i1].cwMin */
-            bufferSize += 1; /* u8 primitive->wmmApBcParams[i1].cwMax */
-            bufferSize += 1; /* u8 primitive->wmmApBcParams[i1].aifs */
-            bufferSize += 2; /* u16 primitive->wmmApBcParams[i1].txopLimit */
-            bufferSize += 1; /* u8 primitive->wmmApBcParams[i1].admissionControlMandatory */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApWmmParamUpdateReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApWmmParamUpdateReq *primitive = (CsrWifiNmeApWmmParamUpdateReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 4; i1++)
-        {
-            CsrUint8Ser(ptr, len, (u8) primitive->wmmApParams[i1].cwMin);
-            CsrUint8Ser(ptr, len, (u8) primitive->wmmApParams[i1].cwMax);
-            CsrUint8Ser(ptr, len, (u8) primitive->wmmApParams[i1].aifs);
-            CsrUint16Ser(ptr, len, (u16) primitive->wmmApParams[i1].txopLimit);
-            CsrUint8Ser(ptr, len, (u8) primitive->wmmApParams[i1].admissionControlMandatory);
-        }
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 4; i1++)
-        {
-            CsrUint8Ser(ptr, len, (u8) primitive->wmmApBcParams[i1].cwMin);
-            CsrUint8Ser(ptr, len, (u8) primitive->wmmApBcParams[i1].cwMax);
-            CsrUint8Ser(ptr, len, (u8) primitive->wmmApBcParams[i1].aifs);
-            CsrUint16Ser(ptr, len, (u16) primitive->wmmApBcParams[i1].txopLimit);
-            CsrUint8Ser(ptr, len, (u8) primitive->wmmApBcParams[i1].admissionControlMandatory);
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApWmmParamUpdateReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApWmmParamUpdateReq *primitive = kmalloc(sizeof(CsrWifiNmeApWmmParamUpdateReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 4; i1++)
-        {
-            CsrUint8Des((u8 *) &primitive->wmmApParams[i1].cwMin, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->wmmApParams[i1].cwMax, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->wmmApParams[i1].aifs, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->wmmApParams[i1].txopLimit, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->wmmApParams[i1].admissionControlMandatory, buffer, &offset);
-        }
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 4; i1++)
-        {
-            CsrUint8Des((u8 *) &primitive->wmmApBcParams[i1].cwMin, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->wmmApBcParams[i1].cwMax, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->wmmApBcParams[i1].aifs, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->wmmApBcParams[i1].txopLimit, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->wmmApBcParams[i1].admissionControlMandatory, buffer, &offset);
-        }
-    }
-
-    return primitive;
-}
-
-
-size_t CsrWifiNmeApStaRemoveReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 12) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 6; /* u8 primitive->staMacAddress.a[6] */
-    bufferSize += 1; /* u8 primitive->keepBlocking */
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApStaRemoveReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApStaRemoveReq *primitive = (CsrWifiNmeApStaRemoveReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->staMacAddress.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->keepBlocking);
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApStaRemoveReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApStaRemoveReq *primitive = kmalloc(sizeof(CsrWifiNmeApStaRemoveReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->staMacAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->keepBlocking, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiNmeApWpsRegisterCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApWpsRegisterCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApWpsRegisterCfm *primitive = (CsrWifiNmeApWpsRegisterCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApWpsRegisterCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApWpsRegisterCfm *primitive = kmalloc(sizeof(CsrWifiNmeApWpsRegisterCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiNmeApStartCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 40) */
-    bufferSize += 2;  /* u16 primitive->interfaceTag */
-    bufferSize += 2;  /* CsrResult primitive->status */
-    bufferSize += 32; /* u8 primitive->ssid.ssid[32] */
-    bufferSize += 1;  /* u8 primitive->ssid.length */
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApStartCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApStartCfm *primitive = (CsrWifiNmeApStartCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrMemCpySer(ptr, len, (const void *) primitive->ssid.ssid, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->ssid.length);
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApStartCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApStartCfm *primitive = kmalloc(sizeof(CsrWifiNmeApStartCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrMemCpyDes(primitive->ssid.ssid, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->ssid.length, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiNmeApStopCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApStopCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApStopCfm *primitive = (CsrWifiNmeApStopCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApStopCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApStopCfm *primitive = kmalloc(sizeof(CsrWifiNmeApStopCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiNmeApStopIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiSmeApType primitive->apType */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApStopIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApStopInd *primitive = (CsrWifiNmeApStopInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->apType);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApStopIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApStopInd *primitive = kmalloc(sizeof(CsrWifiNmeApStopInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->apType, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiNmeApStationIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 18) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiSmeMediaStatus primitive->mediaStatus */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    bufferSize += 6; /* u8 primitive->peerDeviceAddress.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiNmeApStationIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiNmeApStationInd *primitive = (CsrWifiNmeApStationInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->mediaStatus);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerDeviceAddress.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiNmeApStationIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiNmeApStationInd *primitive = kmalloc(sizeof(CsrWifiNmeApStationInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->mediaStatus, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-    CsrMemCpyDes(primitive->peerDeviceAddress.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-#endif /* CSR_WIFI_NME_ENABLE */
-#endif /* CSR_WIFI_AP_ENABLE */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_serialize.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_serialize.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_ap_serialize.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_ap_serialize.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,94 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_NME_AP_SERIALIZE_H__
-#define CSR_WIFI_NME_AP_SERIALIZE_H__
-
-#include "csr_wifi_msgconv.h"
-
-#include "csr_wifi_nme_ap_prim.h"
-
-#ifndef CSR_WIFI_NME_ENABLE
-#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_serialize.h
-#endif
-#ifndef CSR_WIFI_AP_ENABLE
-#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_serialize.h
-#endif
-
-extern void CsrWifiNmeApPfree(void *ptr);
-
-extern u8* CsrWifiNmeApConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApConfigSetReqSizeof(void *msg);
-extern void CsrWifiNmeApConfigSetReqSerFree(void *msg);
-
-extern u8* CsrWifiNmeApWpsRegisterReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApWpsRegisterReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApWpsRegisterReqSizeof(void *msg);
-#define CsrWifiNmeApWpsRegisterReqSerFree CsrWifiNmeApPfree
-
-extern u8* CsrWifiNmeApStartReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApStartReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApStartReqSizeof(void *msg);
-extern void CsrWifiNmeApStartReqSerFree(void *msg);
-
-#define CsrWifiNmeApStopReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeApStopReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeApStopReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeApStopReqSerFree CsrWifiNmeApPfree
-
-extern u8* CsrWifiNmeApWmmParamUpdateReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApWmmParamUpdateReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApWmmParamUpdateReqSizeof(void *msg);
-#define CsrWifiNmeApWmmParamUpdateReqSerFree CsrWifiNmeApPfree
-
-extern u8* CsrWifiNmeApStaRemoveReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApStaRemoveReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApStaRemoveReqSizeof(void *msg);
-#define CsrWifiNmeApStaRemoveReqSerFree CsrWifiNmeApPfree
-
-#define CsrWifiNmeApConfigSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeApConfigSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeApConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeApConfigSetCfmSerFree CsrWifiNmeApPfree
-
-extern u8* CsrWifiNmeApWpsRegisterCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApWpsRegisterCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApWpsRegisterCfmSizeof(void *msg);
-#define CsrWifiNmeApWpsRegisterCfmSerFree CsrWifiNmeApPfree
-
-extern u8* CsrWifiNmeApStartCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApStartCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApStartCfmSizeof(void *msg);
-#define CsrWifiNmeApStartCfmSerFree CsrWifiNmeApPfree
-
-extern u8* CsrWifiNmeApStopCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApStopCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApStopCfmSizeof(void *msg);
-#define CsrWifiNmeApStopCfmSerFree CsrWifiNmeApPfree
-
-extern u8* CsrWifiNmeApStopIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApStopIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApStopIndSizeof(void *msg);
-#define CsrWifiNmeApStopIndSerFree CsrWifiNmeApPfree
-
-#define CsrWifiNmeApWmmParamUpdateCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeApWmmParamUpdateCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeApWmmParamUpdateCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeApWmmParamUpdateCfmSerFree CsrWifiNmeApPfree
-
-extern u8* CsrWifiNmeApStationIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeApStationIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeApStationIndSizeof(void *msg);
-#define CsrWifiNmeApStationIndSerFree CsrWifiNmeApPfree
-
-#endif /* CSR_WIFI_NME_AP_SERIALIZE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_converter_init.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_converter_init.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_converter_init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_converter_init.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,38 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_NME_CONVERTER_INIT_H__
-#define CSR_WIFI_NME_CONVERTER_INIT_H__
-
-#ifndef CSR_WIFI_NME_ENABLE
-#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_converter_init.h
-#endif
-
-#ifndef EXCLUDE_CSR_WIFI_NME_MODULE
-
-#include "csr_msgconv.h"
-
-#ifdef CSR_LOG_ENABLE
-#include "csr_log.h"
-
-extern const CsrLogPrimitiveInformation* CsrWifiNmeTechInfoGet(void);
-#endif /* CSR_LOG_ENABLE */
-
-extern void CsrWifiNmeConverterInit(void);
-
-#else /* EXCLUDE_CSR_WIFI_NME_MODULE */
-
-#define CsrWifiNmeConverterInit()
-
-#endif /* EXCLUDE_CSR_WIFI_NME_MODULE */
-
-#endif /* CSR_WIFI_NME_CONVERTER_INIT_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_lib.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_lib.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_lib.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_lib.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,991 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_NME_LIB_H__
-#define CSR_WIFI_NME_LIB_H__
-
-#include "csr_sched.h"
-#include "csr_macro.h"
-#include "csr_msg_transport.h"
-
-#include "csr_wifi_lib.h"
-
-#include "csr_wifi_nme_prim.h"
-#include "csr_wifi_nme_task.h"
-
-
-#ifndef CSR_WIFI_NME_ENABLE
-#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_lib.h
-#endif
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeConnectionStatusGetReqSend
-
-  DESCRIPTION
-    Requests the current connection status of the NME.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiNmeConnectionStatusGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeConnectionStatusGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_CONNECTION_STATUS_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiNmeConnectionStatusGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiNmeConnectionStatusGetReq *msg__; \
-        CsrWifiNmeConnectionStatusGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeConnectionStatusGetReqSend(src__, interfaceTag__) \
-    CsrWifiNmeConnectionStatusGetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeConnectionStatusGetCfmSend
-
-  DESCRIPTION
-    Reports the connection status of the NME.
-
-  PARAMETERS
-    queue            - Destination Task Queue
-    interfaceTag     - Interface Identifier; unique identifier of an interface
-    status           - Indicates the success or otherwise of the requested
-                       operation.
-    connectionStatus - NME current connection status
-
-*******************************************************************************/
-#define CsrWifiNmeConnectionStatusGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionStatus__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeConnectionStatusGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_CONNECTION_STATUS_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->connectionStatus = (connectionStatus__);
-
-#define CsrWifiNmeConnectionStatusGetCfmSendTo(dst__, src__, interfaceTag__, status__, connectionStatus__) \
-    { \
-        CsrWifiNmeConnectionStatusGetCfm *msg__; \
-        CsrWifiNmeConnectionStatusGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionStatus__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeConnectionStatusGetCfmSend(dst__, interfaceTag__, status__, connectionStatus__) \
-    CsrWifiNmeConnectionStatusGetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__, connectionStatus__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEventMaskSetReqSend
-
-  DESCRIPTION
-    The wireless manager application may register with the NME to receive
-    notification of interesting events. Indications will be sent only if the
-    wireless manager explicitly registers to be notified of that event.
-    indMask is a bit mask of values defined in CsrWifiNmeIndicationsMask.
-
-  PARAMETERS
-    queue   - Message Source Task Queue (Cfm's will be sent to this Queue)
-    indMask - Set mask with values from CsrWifiNmeIndications
-
-*******************************************************************************/
-#define CsrWifiNmeEventMaskSetReqCreate(msg__, dst__, src__, indMask__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeEventMaskSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_EVENT_MASK_SET_REQ, dst__, src__); \
-    msg__->indMask = (indMask__);
-
-#define CsrWifiNmeEventMaskSetReqSendTo(dst__, src__, indMask__) \
-    { \
-        CsrWifiNmeEventMaskSetReq *msg__; \
-        CsrWifiNmeEventMaskSetReqCreate(msg__, dst__, src__, indMask__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeEventMaskSetReqSend(src__, indMask__) \
-    CsrWifiNmeEventMaskSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, indMask__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEventMaskSetCfmSend
-
-  DESCRIPTION
-    The NME calls the primitive to report the result of the request
-    primitive.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiNmeEventMaskSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeEventMaskSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_EVENT_MASK_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeEventMaskSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiNmeEventMaskSetCfm *msg__; \
-        CsrWifiNmeEventMaskSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeEventMaskSetCfmSend(dst__, status__) \
-    CsrWifiNmeEventMaskSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileConnectReqSend
-
-  DESCRIPTION
-    Requests the NME to attempt to connect to the specified profile.
-    Overrides any current connection attempt.
-
-  PARAMETERS
-    queue           - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    profileIdentity - Identity (BSSID, SSID) of profile to be connected to.
-                      It must match an existing profile in the NME.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileConnectReqCreate(msg__, dst__, src__, interfaceTag__, profileIdentity__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileConnectReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_CONNECT_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->profileIdentity = (profileIdentity__);
-
-#define CsrWifiNmeProfileConnectReqSendTo(dst__, src__, interfaceTag__, profileIdentity__) \
-    { \
-        CsrWifiNmeProfileConnectReq *msg__; \
-        CsrWifiNmeProfileConnectReqCreate(msg__, dst__, src__, interfaceTag__, profileIdentity__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileConnectReqSend(src__, interfaceTag__, profileIdentity__) \
-    CsrWifiNmeProfileConnectReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, profileIdentity__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileConnectCfmSend
-
-  DESCRIPTION
-    Reports the status of the NME PROFILE CONNECT REQ. If unsuccessful the
-    connectAttempt parameters contain details of the APs that the NME
-    attempted to connect to before reporting the failure of the request.
-
-  PARAMETERS
-    queue                - Destination Task Queue
-    interfaceTag         - Interface Identifier; unique identifier of an
-                           interface
-    status               - Indicates the success or otherwise of the requested
-                           operation.
-    connectAttemptsCount - This parameter is relevant only if
-                           status!=CSR_WIFI_NME_STATUS_SUCCESS.
-                           Number of connection attempt elements provided with
-                           this primitive
-    connectAttempts      - This parameter is relevant only if
-                           status!=CSR_WIFI_NME_STATUS_SUCCESS.
-                           Points to the list of connection attempt elements
-                           provided with this primitive
-                           Each element of the list provides information about
-                           an AP on which the connection attempt was made and
-                           the error that occurred during the attempt.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileConnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileConnectCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_CONNECT_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->connectAttemptsCount = (connectAttemptsCount__); \
-    msg__->connectAttempts = (connectAttempts__);
-
-#define CsrWifiNmeProfileConnectCfmSendTo(dst__, src__, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__) \
-    { \
-        CsrWifiNmeProfileConnectCfm *msg__; \
-        CsrWifiNmeProfileConnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileConnectCfmSend(dst__, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__) \
-    CsrWifiNmeProfileConnectCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__, connectAttemptsCount__, connectAttempts__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDeleteAllReqSend
-
-  DESCRIPTION
-    Deletes all profiles present in the NME, but does NOT modify the
-    preferred profile list.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiNmeProfileDeleteAllReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileDeleteAllReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DELETE_ALL_REQ, dst__, src__);
-
-#define CsrWifiNmeProfileDeleteAllReqSendTo(dst__, src__) \
-    { \
-        CsrWifiNmeProfileDeleteAllReq *msg__; \
-        CsrWifiNmeProfileDeleteAllReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileDeleteAllReqSend(src__) \
-    CsrWifiNmeProfileDeleteAllReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDeleteAllCfmSend
-
-  DESCRIPTION
-    Reports the status of the CSR_WIFI_NME_PROFILE_DELETE_ALL_REQ.
-    Returns always CSR_WIFI_NME_STATUS_SUCCESS.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Indicates the success or otherwise of the requested operation, but
-             in this case it always set to success.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileDeleteAllCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileDeleteAllCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DELETE_ALL_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeProfileDeleteAllCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiNmeProfileDeleteAllCfm *msg__; \
-        CsrWifiNmeProfileDeleteAllCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileDeleteAllCfmSend(dst__, status__) \
-    CsrWifiNmeProfileDeleteAllCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDeleteReqSend
-
-  DESCRIPTION
-    Will delete the profile with a matching identity, but does NOT modify the
-    preferred profile list.
-
-  PARAMETERS
-    queue           - Message Source Task Queue (Cfm's will be sent to this Queue)
-    profileIdentity - Identity (BSSID, SSID) of profile to be deleted.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileDeleteReqCreate(msg__, dst__, src__, profileIdentity__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileDeleteReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DELETE_REQ, dst__, src__); \
-    msg__->profileIdentity = (profileIdentity__);
-
-#define CsrWifiNmeProfileDeleteReqSendTo(dst__, src__, profileIdentity__) \
-    { \
-        CsrWifiNmeProfileDeleteReq *msg__; \
-        CsrWifiNmeProfileDeleteReqCreate(msg__, dst__, src__, profileIdentity__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileDeleteReqSend(src__, profileIdentity__) \
-    CsrWifiNmeProfileDeleteReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, profileIdentity__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDeleteCfmSend
-
-  DESCRIPTION
-    Reports the status of the CSR_WIFI_NME_PROFILE_DELETE_REQ.
-    Returns CSR_WIFI_NME_STATUS_NOT_FOUND if there is no matching profile.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Indicates the success or otherwise of the requested operation.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileDeleteCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileDeleteCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DELETE_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeProfileDeleteCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiNmeProfileDeleteCfm *msg__; \
-        CsrWifiNmeProfileDeleteCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileDeleteCfmSend(dst__, status__) \
-    CsrWifiNmeProfileDeleteCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDisconnectIndSend
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that informs that application that the current profile
-    connection has disconnected. The indication will contain information
-    about APs that it attempted to maintain the connection via i.e. in the
-    case of failed roaming.
-
-  PARAMETERS
-    queue                - Destination Task Queue
-    interfaceTag         - Interface Identifier; unique identifier of an
-                           interface
-    connectAttemptsCount - Number of connection attempt elements provided with
-                           this primitive
-    connectAttempts      - Points to the list of connection attempt elements
-                           provided with this primitive
-                           Each element of the list provides information about
-                           an AP on which the connection attempt was made and
-                           the error occurred during the attempt.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileDisconnectIndCreate(msg__, dst__, src__, interfaceTag__, connectAttemptsCount__, connectAttempts__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileDisconnectInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_DISCONNECT_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->connectAttemptsCount = (connectAttemptsCount__); \
-    msg__->connectAttempts = (connectAttempts__);
-
-#define CsrWifiNmeProfileDisconnectIndSendTo(dst__, src__, interfaceTag__, connectAttemptsCount__, connectAttempts__) \
-    { \
-        CsrWifiNmeProfileDisconnectInd *msg__; \
-        CsrWifiNmeProfileDisconnectIndCreate(msg__, dst__, src__, interfaceTag__, connectAttemptsCount__, connectAttempts__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileDisconnectIndSend(dst__, interfaceTag__, connectAttemptsCount__, connectAttempts__) \
-    CsrWifiNmeProfileDisconnectIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, connectAttemptsCount__, connectAttempts__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileOrderSetReqSend
-
-  DESCRIPTION
-    Defines the preferred order that profiles present in the NME should be
-    used during the NME auto-connect behaviour.
-    If profileIdentitysCount == 0, it removes any existing preferred profile
-    list already present in the NME, effectively disabling the auto-connect
-    behaviour.
-    NOTE: Profile identities that do not match any profile stored in the NME
-    are ignored during the auto-connect procedure.
-    NOTE: during auto-connect the NME will only attempt to join an existing
-    adhoc network and it will never attempt to host an adhoc network; for
-    hosting and adhoc network, use CSR_WIFI_NME_PROFILE_CONNECT_REQ
-
-  PARAMETERS
-    queue                 - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag          - Interface Identifier; unique identifier of an
-                            interface
-    profileIdentitysCount - The number of profiles identities in the list.
-    profileIdentitys      - Points to the list of profile identities.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileOrderSetReqCreate(msg__, dst__, src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileOrderSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_ORDER_SET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->profileIdentitysCount = (profileIdentitysCount__); \
-    msg__->profileIdentitys = (profileIdentitys__);
-
-#define CsrWifiNmeProfileOrderSetReqSendTo(dst__, src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__) \
-    { \
-        CsrWifiNmeProfileOrderSetReq *msg__; \
-        CsrWifiNmeProfileOrderSetReqCreate(msg__, dst__, src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileOrderSetReqSend(src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__) \
-    CsrWifiNmeProfileOrderSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, profileIdentitysCount__, profileIdentitys__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileOrderSetCfmSend
-
-  DESCRIPTION
-    Confirmation to UNIFI_NME_PROFILE_ORDER_SET.request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Indicates the success or otherwise of the requested
-                   operation.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileOrderSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileOrderSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_ORDER_SET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeProfileOrderSetCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiNmeProfileOrderSetCfm *msg__; \
-        CsrWifiNmeProfileOrderSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileOrderSetCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiNmeProfileOrderSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileSetReqSend
-
-  DESCRIPTION
-    Creates or updates an existing profile in the NME that matches the unique
-    identity of the profile. Each profile is identified by the combination of
-    BSSID and SSID. The profile contains all the required credentials for
-    attempting to connect to the network. Creating or updating a profile via
-    the NME PROFILE SET REQ does NOT add the profile to the preferred profile
-    list within the NME used for the NME auto-connect behaviour.
-
-  PARAMETERS
-    queue   - Message Source Task Queue (Cfm's will be sent to this Queue)
-    profile - Specifies the identity and credentials of the network.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileSetReqCreate(msg__, dst__, src__, profile__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_SET_REQ, dst__, src__); \
-    msg__->profile = (profile__);
-
-#define CsrWifiNmeProfileSetReqSendTo(dst__, src__, profile__) \
-    { \
-        CsrWifiNmeProfileSetReq *msg__; \
-        CsrWifiNmeProfileSetReqCreate(msg__, dst__, src__, profile__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileSetReqSend(src__, profile__) \
-    CsrWifiNmeProfileSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, profile__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileSetCfmSend
-
-  DESCRIPTION
-    Reports the status of the NME PROFILE SET REQ; the request will only fail
-    if the details specified in the profile contains an invalid combination
-    of parameters for example specifying the profile as cloaked but not
-    specifying the SSID. The NME doesn't limit the number of profiles that
-    may be created. The NME assumes that the entity configuring it is aware
-    of the appropriate limits.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Indicates the success or otherwise of the requested operation.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeProfileSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiNmeProfileSetCfm *msg__; \
-        CsrWifiNmeProfileSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileSetCfmSend(dst__, status__) \
-    CsrWifiNmeProfileSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileUpdateIndSend
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that informs that application that the contained profile has
-    changed.
-    For example, either the credentials EAP-FAST PAC file or the session data
-    within the profile has changed.
-    It is up to the application whether it stores this updated profile or
-    not.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    profile      - The identity and credentials of the network.
-
-*******************************************************************************/
-#define CsrWifiNmeProfileUpdateIndCreate(msg__, dst__, src__, interfaceTag__, profile__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeProfileUpdateInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_PROFILE_UPDATE_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->profile = (profile__);
-
-#define CsrWifiNmeProfileUpdateIndSendTo(dst__, src__, interfaceTag__, profile__) \
-    { \
-        CsrWifiNmeProfileUpdateInd *msg__; \
-        CsrWifiNmeProfileUpdateIndCreate(msg__, dst__, src__, interfaceTag__, profile__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeProfileUpdateIndSend(dst__, interfaceTag__, profile__) \
-    CsrWifiNmeProfileUpdateIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, profile__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimGsmAuthIndSend
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that requests the UICC Manager to perform a GSM
-    authentication on behalf of the NME. This indication is generated when
-    the NME is attempting to connect to a profile configured for EAP-SIM. An
-    application MUST register to receive this indication for the NME to
-    support the EAP-SIM credential types. Otherwise the NME has no route to
-    obtain the information from the UICC. EAP-SIM authentication requires 2
-    or 3 GSM authentication rounds and therefore 2 or 3 RANDS (GSM Random
-    Challenges) are included.
-
-  PARAMETERS
-    queue       - Destination Task Queue
-    randsLength - GSM RAND is 16 bytes long hence valid values are 32 (2 RANDS)
-                  or 48 (3 RANDs).
-    rands       - 2 or 3 RANDs values.
-
-*******************************************************************************/
-#define CsrWifiNmeSimGsmAuthIndCreate(msg__, dst__, src__, randsLength__, rands__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeSimGsmAuthInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_GSM_AUTH_IND, dst__, src__); \
-    msg__->randsLength = (randsLength__); \
-    msg__->rands = (rands__);
-
-#define CsrWifiNmeSimGsmAuthIndSendTo(dst__, src__, randsLength__, rands__) \
-    { \
-        CsrWifiNmeSimGsmAuthInd *msg__; \
-        CsrWifiNmeSimGsmAuthIndCreate(msg__, dst__, src__, randsLength__, rands__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeSimGsmAuthIndSend(dst__, randsLength__, rands__) \
-    CsrWifiNmeSimGsmAuthIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, randsLength__, rands__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimGsmAuthResSend
-
-  DESCRIPTION
-    Response from the application that received the NME SIM GSM AUTH IND. For
-    each GSM authentication round a GSM Ciphering key (Kc) and a signed
-    response (SRES) are produced. Since 2 or 3 GSM authentication rounds are
-    used the 2 or 3 Kc's obtained respectively are combined into one buffer
-    and similarly the 2 or 3 SRES's obtained are combined into another
-    buffer. The order of Kc values (SRES values respectively) in their buffer
-    is the same as that of their corresponding RAND values in the incoming
-    indication.
-
-  PARAMETERS
-    status     - Indicates the outcome of the requested operation:
-                 STATUS_SUCCESS or STATUS_ERROR
-    kcsLength  - Length in Bytes of Kc buffer. Legal values are: 16 or 24.
-    kcs        - Kc buffer holding 2 or 3 Kc values.
-    sresLength - Length in Bytes of SRES buffer. Legal values are: 8 or 12.
-    sres       - SRES buffer holding 2 or 3 SRES values.
-
-*******************************************************************************/
-#define CsrWifiNmeSimGsmAuthResCreate(msg__, dst__, src__, status__, kcsLength__, kcs__, sresLength__, sres__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeSimGsmAuthRes), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_GSM_AUTH_RES, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->kcsLength = (kcsLength__); \
-    msg__->kcs = (kcs__); \
-    msg__->sresLength = (sresLength__); \
-    msg__->sres = (sres__);
-
-#define CsrWifiNmeSimGsmAuthResSendTo(dst__, src__, status__, kcsLength__, kcs__, sresLength__, sres__) \
-    { \
-        CsrWifiNmeSimGsmAuthRes *msg__; \
-        CsrWifiNmeSimGsmAuthResCreate(msg__, dst__, src__, status__, kcsLength__, kcs__, sresLength__, sres__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeSimGsmAuthResSend(src__, status__, kcsLength__, kcs__, sresLength__, sres__) \
-    CsrWifiNmeSimGsmAuthResSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, status__, kcsLength__, kcs__, sresLength__, sres__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimImsiGetIndSend
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that requests the IMSI and UICC type from the UICC Manager.
-    This indication is generated when the NME is attempting to connect to a
-    profile configured for EAP-SIM/AKA. An application MUST register to
-    receive this indication for the NME to support the EAP-SIM/AKA credential
-    types. Otherwise the NME has no route to obtain the information from the
-    UICC.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-
-*******************************************************************************/
-#define CsrWifiNmeSimImsiGetIndCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeSimImsiGetInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_IMSI_GET_IND, dst__, src__);
-
-#define CsrWifiNmeSimImsiGetIndSendTo(dst__, src__) \
-    { \
-        CsrWifiNmeSimImsiGetInd *msg__; \
-        CsrWifiNmeSimImsiGetIndCreate(msg__, dst__, src__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeSimImsiGetIndSend(dst__) \
-    CsrWifiNmeSimImsiGetIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimImsiGetResSend
-
-  DESCRIPTION
-    Response from the application that received the NME SIM IMSI GET IND.
-
-  PARAMETERS
-    status   - Indicates the outcome of the requested operation: STATUS_SUCCESS
-               or STATUS_ERROR.
-    imsi     - The value of the IMSI obtained from the UICC.
-    cardType - The UICC type (GSM only (SIM), UMTS only (USIM), Both).
-
-*******************************************************************************/
-#define CsrWifiNmeSimImsiGetResCreate(msg__, dst__, src__, status__, imsi__, cardType__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeSimImsiGetRes), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_IMSI_GET_RES, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->imsi = (imsi__); \
-    msg__->cardType = (cardType__);
-
-#define CsrWifiNmeSimImsiGetResSendTo(dst__, src__, status__, imsi__, cardType__) \
-    { \
-        CsrWifiNmeSimImsiGetRes *msg__; \
-        CsrWifiNmeSimImsiGetResCreate(msg__, dst__, src__, status__, imsi__, cardType__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeSimImsiGetResSend(src__, status__, imsi__, cardType__) \
-    CsrWifiNmeSimImsiGetResSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, status__, imsi__, cardType__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimUmtsAuthIndSend
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that requests the UICC Manager to perform a UMTS
-    authentication on behalf of the NME. This indication is generated when
-    the NME is attempting to connect to a profile configured for EAP-AKA. An
-    application MUST register to receive this indication for the NME to
-    support the EAP-AKA credential types. Otherwise the NME has no route to
-    obtain the information from the USIM. EAP-AKA requires one UMTS
-    authentication round and therefore only one RAND and one AUTN values are
-    included.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    rand   - UMTS RAND value.
-    autn   - UMTS AUTN value.
-
-*******************************************************************************/
-#define CsrWifiNmeSimUmtsAuthIndCreate(msg__, dst__, src__, rand__, autn__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeSimUmtsAuthInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_UMTS_AUTH_IND, dst__, src__); \
-    memcpy(msg__->rand, (rand__), sizeof(u8) * 16); \
-    memcpy(msg__->autn, (autn__), sizeof(u8) * 16);
-
-#define CsrWifiNmeSimUmtsAuthIndSendTo(dst__, src__, rand__, autn__) \
-    { \
-        CsrWifiNmeSimUmtsAuthInd *msg__; \
-        CsrWifiNmeSimUmtsAuthIndCreate(msg__, dst__, src__, rand__, autn__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeSimUmtsAuthIndSend(dst__, rand__, autn__) \
-    CsrWifiNmeSimUmtsAuthIndSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, rand__, autn__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimUmtsAuthResSend
-
-  DESCRIPTION
-    Response from the application that received the NME SIM UMTS AUTH IND.
-    The values of umtsCipherKey, umtsIntegrityKey, resParameterLength and
-    resParameter are only meanigful when result = UMTS_AUTH_RESULT_SUCCESS.
-    The value of auts is only meaningful when
-    result=UMTS_AUTH_RESULT_SYNC_FAIL.
-
-  PARAMETERS
-    status             - Indicates the outcome of the requested operation:
-                         STATUS_SUCCESS or STATUS_ERROR.
-    result             - The result of UMTS authentication as performed by the
-                         UICC which could be: Success, Authentication Reject or
-                         Synchronisation Failure. For all these 3 outcomes the
-                         value of status is success.
-    umtsCipherKey      - The UMTS Cipher Key as calculated and returned by the
-                         UICC.
-    umtsIntegrityKey   - The UMTS Integrity Key as calculated and returned by
-                         the UICC.
-    resParameterLength - The length (in bytes) of the RES parameter (min=4; max
-                         = 16).
-    resParameter       - The RES parameter as calculated and returned by the
-                         UICC.
-    auts               - The AUTS parameter as calculated and returned by the
-                         UICC.
-
-*******************************************************************************/
-#define CsrWifiNmeSimUmtsAuthResCreate(msg__, dst__, src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeSimUmtsAuthRes), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_SIM_UMTS_AUTH_RES, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->result = (result__); \
-    memcpy(msg__->umtsCipherKey, (umtsCipherKey__), sizeof(u8) * 16); \
-    memcpy(msg__->umtsIntegrityKey, (umtsIntegrityKey__), sizeof(u8) * 16); \
-    msg__->resParameterLength = (resParameterLength__); \
-    msg__->resParameter = (resParameter__); \
-    memcpy(msg__->auts, (auts__), sizeof(u8) * 14);
-
-#define CsrWifiNmeSimUmtsAuthResSendTo(dst__, src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__) \
-    { \
-        CsrWifiNmeSimUmtsAuthRes *msg__; \
-        CsrWifiNmeSimUmtsAuthResCreate(msg__, dst__, src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeSimUmtsAuthResSend(src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__) \
-    CsrWifiNmeSimUmtsAuthResSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, status__, result__, umtsCipherKey__, umtsIntegrityKey__, resParameterLength__, resParameter__, auts__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsCancelReqSend
-
-  DESCRIPTION
-    Requests the NME to cancel any WPS procedure that it is currently
-    performing. This includes WPS registrar activities started because of
-    CSR_WIFI_NME_AP_REGISTER.request
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiNmeWpsCancelReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeWpsCancelReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CANCEL_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiNmeWpsCancelReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiNmeWpsCancelReq *msg__; \
-        CsrWifiNmeWpsCancelReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeWpsCancelReqSend(src__, interfaceTag__) \
-    CsrWifiNmeWpsCancelReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsCancelCfmSend
-
-  DESCRIPTION
-    Reports the status of the NME WPS REQ, the request is always SUCCESSFUL.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Only returns CSR_WIFI_NME_STATUS_SUCCESS
-
-*******************************************************************************/
-#define CsrWifiNmeWpsCancelCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeWpsCancelCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CANCEL_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeWpsCancelCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiNmeWpsCancelCfm *msg__; \
-        CsrWifiNmeWpsCancelCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeWpsCancelCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiNmeWpsCancelCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsCfmSend
-
-  DESCRIPTION
-    Reports the status of the NME WPS REQ.
-    If CSR_WIFI_NME_STATUS_SUCCESS, the profile parameter contains the
-    identity and credentials of the AP.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Indicates the success or otherwise of the requested
-                   operation.
-    profile      - This parameter is relevant only if
-                   status==CSR_WIFI_NME_STATUS_SUCCESS.
-                   The identity and credentials of the network.
-
-*******************************************************************************/
-#define CsrWifiNmeWpsCfmCreate(msg__, dst__, src__, interfaceTag__, status__, profile__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeWpsCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->profile = (profile__);
-
-#define CsrWifiNmeWpsCfmSendTo(dst__, src__, interfaceTag__, status__, profile__) \
-    { \
-        CsrWifiNmeWpsCfm *msg__; \
-        CsrWifiNmeWpsCfmCreate(msg__, dst__, src__, interfaceTag__, status__, profile__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeWpsCfmSend(dst__, interfaceTag__, status__, profile__) \
-    CsrWifiNmeWpsCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__, profile__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsConfigSetReqSend
-
-  DESCRIPTION
-    This primitive passes the WPS information for the device to NME. This may
-    be accepted only if no interface is active.
-
-  PARAMETERS
-    queue     - Message Source Task Queue (Cfm's will be sent to this Queue)
-    wpsConfig - WPS config.
-
-*******************************************************************************/
-#define CsrWifiNmeWpsConfigSetReqCreate(msg__, dst__, src__, wpsConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeWpsConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CONFIG_SET_REQ, dst__, src__); \
-    msg__->wpsConfig = (wpsConfig__);
-
-#define CsrWifiNmeWpsConfigSetReqSendTo(dst__, src__, wpsConfig__) \
-    { \
-        CsrWifiNmeWpsConfigSetReq *msg__; \
-        CsrWifiNmeWpsConfigSetReqCreate(msg__, dst__, src__, wpsConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeWpsConfigSetReqSend(src__, wpsConfig__) \
-    CsrWifiNmeWpsConfigSetReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, wpsConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsConfigSetCfmSend
-
-  DESCRIPTION
-    Confirm.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Status of the request.
-
-*******************************************************************************/
-#define CsrWifiNmeWpsConfigSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeWpsConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_CONFIG_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiNmeWpsConfigSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiNmeWpsConfigSetCfm *msg__; \
-        CsrWifiNmeWpsConfigSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeWpsConfigSetCfmSend(dst__, status__) \
-    CsrWifiNmeWpsConfigSetCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsReqSend
-
-  DESCRIPTION
-    Requests the NME to look for WPS enabled APs and attempt to perform WPS
-    to determine the appropriate security credentials to connect to the AP.
-    If the PIN == '00000000' then 'push button mode' is indicated, otherwise
-    the PIN has to match that of the AP. 4 digit pin is passed by sending the
-    pin digits in pin[0]..pin[3] and rest of the contents filled with '-'.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    pin          - PIN value.
-    ssid         - Service Set identifier
-    bssid        - ID of Basic Service Set for which a WPS connection attempt is
-                   being made.
-
-*******************************************************************************/
-#define CsrWifiNmeWpsReqCreate(msg__, dst__, src__, interfaceTag__, pin__, ssid__, bssid__) \
-    msg__ = kmalloc(sizeof(CsrWifiNmeWpsReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_NME_PRIM, CSR_WIFI_NME_WPS_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    memcpy(msg__->pin, (pin__), sizeof(u8) * 8); \
-    msg__->ssid = (ssid__); \
-    msg__->bssid = (bssid__);
-
-#define CsrWifiNmeWpsReqSendTo(dst__, src__, interfaceTag__, pin__, ssid__, bssid__) \
-    { \
-        CsrWifiNmeWpsReq *msg__; \
-        CsrWifiNmeWpsReqCreate(msg__, dst__, src__, interfaceTag__, pin__, ssid__, bssid__); \
-        CsrMsgTransport(dst__, CSR_WIFI_NME_PRIM, msg__); \
-    }
-
-#define CsrWifiNmeWpsReqSend(src__, interfaceTag__, pin__, ssid__, bssid__) \
-    CsrWifiNmeWpsReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, pin__, ssid__, bssid__)
-
-#endif /* CSR_WIFI_NME_LIB_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_prim.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_prim.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_prim.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_prim.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1657 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_NME_PRIM_H__
-#define CSR_WIFI_NME_PRIM_H__
-
-#include <linux/types.h>
-#include "csr_prim_defs.h"
-#include "csr_sched.h"
-#include "csr_wifi_common.h"
-#include "csr_result.h"
-#include "csr_wifi_fsm_event.h"
-#include "csr_wifi_sme_prim.h"
-
-#ifndef CSR_WIFI_NME_ENABLE
-#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_prim.h
-#endif
-
-#define CSR_WIFI_NME_PRIM                                               (0x0424)
-
-typedef CsrPrim CsrWifiNmePrim;
-
-typedef void (*CsrWifiNmeFrameFreeFunction)(void *frame);
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeAuthMode
-
-  DESCRIPTION
-    WiFi Authentication Mode
-
- VALUES
-    CSR_WIFI_NME_AUTH_MODE_80211_OPEN
-                   - Connects to an open system network (i.e. no authentication,
-                     no encryption) or to a WEP enabled network.
-    CSR_WIFI_NME_AUTH_MODE_80211_SHARED
-                   - Connect to a WEP enabled network.
-    CSR_WIFI_NME_AUTH_MODE_8021X_WPA
-                   - Connects to a WPA Enterprise enabled network.
-    CSR_WIFI_NME_AUTH_MODE_8021X_WPAPSK
-                   - Connects to a WPA with Pre-Shared Key enabled network.
-    CSR_WIFI_NME_AUTH_MODE_8021X_WPA2
-                   - Connects to a WPA2 Enterprise enabled network.
-    CSR_WIFI_NME_AUTH_MODE_8021X_WPA2PSK
-                   - Connects to a WPA2 with Pre-Shared Key enabled network.
-    CSR_WIFI_NME_AUTH_MODE_8021X_CCKM
-                   - Connects to a CCKM enabled network.
-    CSR_WIFI_NME_AUTH_MODE_WAPI_WAI
-                   - Connects to a WAPI Enterprise enabled network.
-    CSR_WIFI_NME_AUTH_MODE_WAPI_WAIPSK
-                   - Connects to a WAPI with Pre-Shared Key enabled network.
-    CSR_WIFI_NME_AUTH_MODE_8021X_OTHER1X
-                   - For future use.
-
-*******************************************************************************/
-typedef u16 CsrWifiNmeAuthMode;
-#define CSR_WIFI_NME_AUTH_MODE_80211_OPEN      ((CsrWifiNmeAuthMode) 0x0001)
-#define CSR_WIFI_NME_AUTH_MODE_80211_SHARED    ((CsrWifiNmeAuthMode) 0x0002)
-#define CSR_WIFI_NME_AUTH_MODE_8021X_WPA       ((CsrWifiNmeAuthMode) 0x0004)
-#define CSR_WIFI_NME_AUTH_MODE_8021X_WPAPSK    ((CsrWifiNmeAuthMode) 0x0008)
-#define CSR_WIFI_NME_AUTH_MODE_8021X_WPA2      ((CsrWifiNmeAuthMode) 0x0010)
-#define CSR_WIFI_NME_AUTH_MODE_8021X_WPA2PSK   ((CsrWifiNmeAuthMode) 0x0020)
-#define CSR_WIFI_NME_AUTH_MODE_8021X_CCKM      ((CsrWifiNmeAuthMode) 0x0040)
-#define CSR_WIFI_NME_AUTH_MODE_WAPI_WAI        ((CsrWifiNmeAuthMode) 0x0080)
-#define CSR_WIFI_NME_AUTH_MODE_WAPI_WAIPSK     ((CsrWifiNmeAuthMode) 0x0100)
-#define CSR_WIFI_NME_AUTH_MODE_8021X_OTHER1X   ((CsrWifiNmeAuthMode) 0x0200)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeBssType
-
-  DESCRIPTION
-    Type of BSS
-
- VALUES
-    CSR_WIFI_NME_BSS_TYPE_INFRASTRUCTURE
-                   - Infrastructure BSS type where access to the network is via
-                     one or several Access Points.
-    CSR_WIFI_NME_BSS_TYPE_ADHOC
-                   - Adhoc or Independent BSS Type where one Station acts as a
-                     host and future stations can join the adhoc network without
-                     needing an access point.
-    CSR_WIFI_NME_BSS_TYPE_RESERVED
-                   - To be in sync with SME.This is not used.
-    CSR_WIFI_NME_BSS_TYPE_P2P
-                   - P2P mode of operation.
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeBssType;
-#define CSR_WIFI_NME_BSS_TYPE_INFRASTRUCTURE   ((CsrWifiNmeBssType) 0x00)
-#define CSR_WIFI_NME_BSS_TYPE_ADHOC            ((CsrWifiNmeBssType) 0x01)
-#define CSR_WIFI_NME_BSS_TYPE_RESERVED         ((CsrWifiNmeBssType) 0x02)
-#define CSR_WIFI_NME_BSS_TYPE_P2P              ((CsrWifiNmeBssType) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeCcxOptionsMask
-
-  DESCRIPTION
-    Enumeration type defining possible mask values for setting CCX options.
-
- VALUES
-    CSR_WIFI_NME_CCX_OPTION_NONE - No CCX option is set.
-    CSR_WIFI_NME_CCX_OPTION_CCKM - CCX option cckm is set.
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeCcxOptionsMask;
-#define CSR_WIFI_NME_CCX_OPTION_NONE   ((CsrWifiNmeCcxOptionsMask) 0x00)
-#define CSR_WIFI_NME_CCX_OPTION_CCKM   ((CsrWifiNmeCcxOptionsMask) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeConfigAction
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_PIN_ENTRY_PUSH_BUTTON -
-    CSR_WIFI_PIN_ENTRY_DISPLAY_PIN -
-    CSR_WIFI_PIN_ENTRY_ENTER_PIN   -
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeConfigAction;
-#define CSR_WIFI_PIN_ENTRY_PUSH_BUTTON   ((CsrWifiNmeConfigAction) 0x00)
-#define CSR_WIFI_PIN_ENTRY_DISPLAY_PIN   ((CsrWifiNmeConfigAction) 0x01)
-#define CSR_WIFI_PIN_ENTRY_ENTER_PIN     ((CsrWifiNmeConfigAction) 0x02)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeConnectionStatus
-
-  DESCRIPTION
-    Indicate the NME Connection Status when connecting or when disconnecting
-
- VALUES
-    CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_DISCONNECTED
-                   - NME is disconnected.
-    CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_CONNECTING
-                   - NME is in the process of connecting.
-    CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_AUTHENTICATING
-                   - NME is in the authentication stage of a connection attempt.
-    CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_CONNECTED
-                   - NME is connected.
-    CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_DISCONNECTING
-                   - NME is in the process of disconnecting.
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeConnectionStatus;
-#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_DISCONNECTED     ((CsrWifiNmeConnectionStatus) 0x00)
-#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_CONNECTING       ((CsrWifiNmeConnectionStatus) 0x01)
-#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_AUTHENTICATING   ((CsrWifiNmeConnectionStatus) 0x02)
-#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_CONNECTED        ((CsrWifiNmeConnectionStatus) 0x03)
-#define CSR_WIFI_NME_CONNECTION_STATUS_CONNECTION_STATUS_DISCONNECTING    ((CsrWifiNmeConnectionStatus) 0x04)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeCredentialType
-
-  DESCRIPTION
-    NME Credential Types
-
- VALUES
-    CSR_WIFI_NME_CREDENTIAL_TYPE_OPEN_SYSTEM
-                   - Credential Type Open System.
-    CSR_WIFI_NME_CREDENTIAL_TYPE_WEP64
-                   - Credential Type WEP-64
-    CSR_WIFI_NME_CREDENTIAL_TYPE_WEP128
-                   - Credential Type WEP-128
-    CSR_WIFI_NME_CREDENTIAL_TYPE_WPA_PSK
-                   - Credential Type WPA Pre-Shared Key
-    CSR_WIFI_NME_CREDENTIAL_TYPE_WPA_PASSPHRASE
-                   - Credential Type WPA pass phrase
-    CSR_WIFI_NME_CREDENTIAL_TYPE_WPA2_PSK
-                   - Credential Type WPA2 Pre-Shared Key.
-    CSR_WIFI_NME_CREDENTIAL_TYPE_WPA2_PASSPHRASE
-                   - Credential Type WPA2 pass phrase
-    CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI_PSK
-                   - Credential Type WAPI Pre-Shared Key.
-    CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI_PASSPHRASE
-                   - Credential Type WAPI pass phrase
-    CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI
-                   - Credential Type WAPI certificates
-    CSR_WIFI_NME_CREDENTIAL_TYPE_8021X
-                   - Credential Type 802.1X: the associated type supports
-                     FAST/LEAP/TLS/TTLS/PEAP/etc.
-
-*******************************************************************************/
-typedef u16 CsrWifiNmeCredentialType;
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_OPEN_SYSTEM       ((CsrWifiNmeCredentialType) 0x0000)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_WEP64             ((CsrWifiNmeCredentialType) 0x0001)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_WEP128            ((CsrWifiNmeCredentialType) 0x0002)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_WPA_PSK           ((CsrWifiNmeCredentialType) 0x0003)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_WPA_PASSPHRASE    ((CsrWifiNmeCredentialType) 0x0004)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_WPA2_PSK          ((CsrWifiNmeCredentialType) 0x0005)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_WPA2_PASSPHRASE   ((CsrWifiNmeCredentialType) 0x0006)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI_PSK          ((CsrWifiNmeCredentialType) 0x0007)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI_PASSPHRASE   ((CsrWifiNmeCredentialType) 0x0008)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_WAPI              ((CsrWifiNmeCredentialType) 0x0009)
-#define CSR_WIFI_NME_CREDENTIAL_TYPE_8021X             ((CsrWifiNmeCredentialType) 0x000A)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEapMethod
-
-  DESCRIPTION
-    Outer EAP method with possibly inner method.
-
- VALUES
-    CSR_WIFI_NME_EAP_METHOD_TLS
-                   - EAP-TLS Method.
-    CSR_WIFI_NME_EAP_METHOD_TTLS_MSCHAPV2
-                   - EAP-TTLS Method with MSCHAPV2.
-    CSR_WIFI_NME_EAP_METHOD_PEAP_GTC
-                   - EAP-PEAP Method with GTC.
-    CSR_WIFI_NME_EAP_METHOD_PEAP_MSCHAPV2
-                   - EAP-PEAP Method with MSCHAPV2.
-    CSR_WIFI_NME_EAP_METHOD_SIM
-                   - EAP-SIM Method.
-    CSR_WIFI_NME_EAP_METHOD_AKA
-                   - EAP-AKA Method.
-    CSR_WIFI_NME_EAP_METHOD_FAST_GTC
-                   - EAP-FAST Method with GTC.
-    CSR_WIFI_NME_EAP_METHOD_FAST_MSCHAPV2
-                   - EAP-FAST Method with MSCHAPV2.
-    CSR_WIFI_NME_EAP_METHOD_LEAP
-                   - EAP-LEAP Method.
-
-*******************************************************************************/
-typedef u16 CsrWifiNmeEapMethod;
-#define CSR_WIFI_NME_EAP_METHOD_TLS             ((CsrWifiNmeEapMethod) 0x0001)
-#define CSR_WIFI_NME_EAP_METHOD_TTLS_MSCHAPV2   ((CsrWifiNmeEapMethod) 0x0002)
-#define CSR_WIFI_NME_EAP_METHOD_PEAP_GTC        ((CsrWifiNmeEapMethod) 0x0004)
-#define CSR_WIFI_NME_EAP_METHOD_PEAP_MSCHAPV2   ((CsrWifiNmeEapMethod) 0x0008)
-#define CSR_WIFI_NME_EAP_METHOD_SIM             ((CsrWifiNmeEapMethod) 0x0010)
-#define CSR_WIFI_NME_EAP_METHOD_AKA             ((CsrWifiNmeEapMethod) 0x0020)
-#define CSR_WIFI_NME_EAP_METHOD_FAST_GTC        ((CsrWifiNmeEapMethod) 0x0040)
-#define CSR_WIFI_NME_EAP_METHOD_FAST_MSCHAPV2   ((CsrWifiNmeEapMethod) 0x0080)
-#define CSR_WIFI_NME_EAP_METHOD_LEAP            ((CsrWifiNmeEapMethod) 0x0100)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEncryption
-
-  DESCRIPTION
-    WiFi Encryption method
-
- VALUES
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_NONE
-                   - No encryprion set.
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_WEP40
-                   - 40 bytes WEP key for peer to peer communication.
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_WEP104
-                   - 104 bytes WEP key for peer to peer communication.
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_TKIP
-                   - TKIP key for peer to peer communication.
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_CCMP
-                   - CCMP key for peer to peer communication.
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_SMS4
-                   - SMS4 key for peer to peer communication.
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_WEP40
-                   - 40 bytes WEP key for broadcast messages.
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_WEP104
-                   - 104 bytes WEP key for broadcast messages.
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_TKIP
-                   - TKIP key for broadcast messages.
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_CCMP
-                   - CCMP key for broadcast messages
-    CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_SMS4
-                   - SMS4 key for broadcast messages.
-
-*******************************************************************************/
-typedef u16 CsrWifiNmeEncryption;
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_NONE              ((CsrWifiNmeEncryption) 0x0000)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_WEP40    ((CsrWifiNmeEncryption) 0x0001)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_WEP104   ((CsrWifiNmeEncryption) 0x0002)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_TKIP     ((CsrWifiNmeEncryption) 0x0004)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_CCMP     ((CsrWifiNmeEncryption) 0x0008)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_SMS4     ((CsrWifiNmeEncryption) 0x0010)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_WEP40       ((CsrWifiNmeEncryption) 0x0020)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_WEP104      ((CsrWifiNmeEncryption) 0x0040)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_TKIP        ((CsrWifiNmeEncryption) 0x0080)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_CCMP        ((CsrWifiNmeEncryption) 0x0100)
-#define CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_SMS4        ((CsrWifiNmeEncryption) 0x0200)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeIndications
-
-  DESCRIPTION
-    NME indications
-
- VALUES
-    CSR_WIFI_NME_INDICATIONS_IND_AP_STATION
-                   - NME AP Station Indication.
-    CSR_WIFI_NME_INDICATIONS_IND_AP_STOP
-                   - NME AP Stop Indication.
-    CSR_WIFI_NME_INDICATIONS_IND_SIM_UMTS_AUTH
-                   - NME UMTS Authentication Indication.
-    CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_START
-                   - NME P2P Group Start Indication.
-    CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_STATUS
-                   - NME P2P Group Status Indication.
-    CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_ROLE
-                   - NME P2P Group Role Indication.
-    CSR_WIFI_NME_INDICATIONS_IND_PROFILE_DISCONNECT
-                   - NME Profile Disconnect Indication.
-    CSR_WIFI_NME_INDICATIONS_IND_PROFILE_UPDATE
-                   - NME Profile Update Indication.
-    CSR_WIFI_NME_INDICATIONS_IND_SIM_IMSI_GET
-                   - NME GET IMSI Indication.
-    CSR_WIFI_NME_INDICATIONS_IND_SIM_GSM_AUTH
-                   - NME GSM Authentication Indication.
-    CSR_WIFI_NME_INDICATIONS_ALL
-                   - Used to register for all available indications
-
-*******************************************************************************/
-typedef u32 CsrWifiNmeIndications;
-#define CSR_WIFI_NME_INDICATIONS_IND_AP_STATION           ((CsrWifiNmeIndications) 0x00100000)
-#define CSR_WIFI_NME_INDICATIONS_IND_AP_STOP              ((CsrWifiNmeIndications) 0x00200000)
-#define CSR_WIFI_NME_INDICATIONS_IND_SIM_UMTS_AUTH        ((CsrWifiNmeIndications) 0x01000000)
-#define CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_START      ((CsrWifiNmeIndications) 0x02000000)
-#define CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_STATUS     ((CsrWifiNmeIndications) 0x04000000)
-#define CSR_WIFI_NME_INDICATIONS_IND_P2P_GROUP_ROLE       ((CsrWifiNmeIndications) 0x08000000)
-#define CSR_WIFI_NME_INDICATIONS_IND_PROFILE_DISCONNECT   ((CsrWifiNmeIndications) 0x10000000)
-#define CSR_WIFI_NME_INDICATIONS_IND_PROFILE_UPDATE       ((CsrWifiNmeIndications) 0x20000000)
-#define CSR_WIFI_NME_INDICATIONS_IND_SIM_IMSI_GET         ((CsrWifiNmeIndications) 0x40000000)
-#define CSR_WIFI_NME_INDICATIONS_IND_SIM_GSM_AUTH         ((CsrWifiNmeIndications) 0x80000000)
-#define CSR_WIFI_NME_INDICATIONS_ALL                      ((CsrWifiNmeIndications) 0xFFFFFFFF)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSecError
-
-  DESCRIPTION
-    NME Security Errors
-    place holder for the security library abort reason
-
- VALUES
-    CSR_WIFI_NME_SEC_ERROR_SEC_ERROR_UNKNOWN
-                   - Unknown Security Error.
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeSecError;
-#define CSR_WIFI_NME_SEC_ERROR_SEC_ERROR_UNKNOWN   ((CsrWifiNmeSecError) 0x00)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimCardType
-
-  DESCRIPTION
-    (U)SIM Card (or UICC) types
-
- VALUES
-    CSR_WIFI_NME_SIM_CARD_TYPE_2G   - 2G SIM card, capable of performing GSM
-                                      authentication only.
-    CSR_WIFI_NME_SIM_CARD_TYPE_3G   - UICC supporting USIM application, capable
-                                      of performing UMTS authentication only.
-    CSR_WIFI_NME_SIM_CARD_TYPE_2G3G - UICC supporting both USIM and SIM
-                                      applications, capable of performing both
-                                      UMTS and GSM authentications.
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeSimCardType;
-#define CSR_WIFI_NME_SIM_CARD_TYPE_2G     ((CsrWifiNmeSimCardType) 0x01)
-#define CSR_WIFI_NME_SIM_CARD_TYPE_3G     ((CsrWifiNmeSimCardType) 0x02)
-#define CSR_WIFI_NME_SIM_CARD_TYPE_2G3G   ((CsrWifiNmeSimCardType) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeUmtsAuthResult
-
-  DESCRIPTION
-    Only relevant for UMTS Authentication. It indicates if the UICC has
-    successfully authenticated the network or otherwise.
-
- VALUES
-    CSR_WIFI_NME_UMTS_AUTH_RESULT_SUCCESS
-                   - Successful outcome from USIM indicating that the card has
-                     successfully authenticated the network.
-    CSR_WIFI_NME_UMTS_AUTH_RESULT_SYNC_FAIL
-                   - Unsuccessful outcome from USIM indicating that the card is
-                     requesting the network to synchronise and re-try again. If
-                     no further request is received an NME timer will expire and
-                     the authentication is aborted.
-    CSR_WIFI_NME_UMTS_AUTH_RESULT_REJECT
-                   - Unsuccessful outcome from USIM indicating that the card has
-                     rejected the network and that the authentication is
-                     aborted.
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeUmtsAuthResult;
-#define CSR_WIFI_NME_UMTS_AUTH_RESULT_SUCCESS     ((CsrWifiNmeUmtsAuthResult) 0x00)
-#define CSR_WIFI_NME_UMTS_AUTH_RESULT_SYNC_FAIL   ((CsrWifiNmeUmtsAuthResult) 0x01)
-#define CSR_WIFI_NME_UMTS_AUTH_RESULT_REJECT      ((CsrWifiNmeUmtsAuthResult) 0x02)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWmmQosInfo
-
-  DESCRIPTION
-    Defines bits for the QoS Info octect as defined in the WMM specification.
-    The values of this type are used across the NME/SME/Router API's and they
-    must be kept consistent with the corresponding types in the .xml of the
-    other interfaces
-
- VALUES
-    CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_ALL
-                   - WMM AP may deliver all buffered frames.
-    CSR_WIFI_NME_WMM_QOS_INFO_AC_VO
-                   - To enable the triggering and delivery of QoS Voice.
-    CSR_WIFI_NME_WMM_QOS_INFO_AC_VI
-                   - To enable the triggering and delivery of QoS Video.
-    CSR_WIFI_NME_WMM_QOS_INFO_AC_BK
-                   - To enable the triggering and delivery of QoS Background.
-    CSR_WIFI_NME_WMM_QOS_INFO_AC_BE
-                   - To enable the triggering and delivery of QoS Best Effort.
-    CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_TWO
-                   - WMM AP may deliver a maximum of 2 buffered frames per
-                     Unscheduled Service Period (USP).
-    CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_FOUR
-                   - WMM AP may deliver a maximum of 4 buffered frames per USP.
-    CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_SIX
-                   - WMM AP may deliver a maximum of 6 buffered frames per USP.
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeWmmQosInfo;
-#define CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_ALL    ((CsrWifiNmeWmmQosInfo) 0x00)
-#define CSR_WIFI_NME_WMM_QOS_INFO_AC_VO            ((CsrWifiNmeWmmQosInfo) 0x01)
-#define CSR_WIFI_NME_WMM_QOS_INFO_AC_VI            ((CsrWifiNmeWmmQosInfo) 0x02)
-#define CSR_WIFI_NME_WMM_QOS_INFO_AC_BK            ((CsrWifiNmeWmmQosInfo) 0x04)
-#define CSR_WIFI_NME_WMM_QOS_INFO_AC_BE            ((CsrWifiNmeWmmQosInfo) 0x08)
-#define CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_TWO    ((CsrWifiNmeWmmQosInfo) 0x20)
-#define CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_FOUR   ((CsrWifiNmeWmmQosInfo) 0x40)
-#define CSR_WIFI_NME_WMM_QOS_INFO_AC_MAX_SP_SIX    ((CsrWifiNmeWmmQosInfo) 0x60)
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEapMethodMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiNmeEapMethod.
-
-*******************************************************************************/
-typedef u16 CsrWifiNmeEapMethodMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEncryptionMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiNmeEncryption
-
-*******************************************************************************/
-typedef u16 CsrWifiNmeEncryptionMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeIndicationsMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiNmeIndications
-
-*******************************************************************************/
-typedef u32 CsrWifiNmeIndicationsMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeNmeIndicationsMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiNmeNmeIndications.
-    Used to overlap the unused portion of the unifi_IndicationsMask For NME
-    specific indications
-
-*******************************************************************************/
-typedef u32 CsrWifiNmeNmeIndicationsMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWmmQosInfoMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiNmeWmmQosInfo
-
-*******************************************************************************/
-typedef u8 CsrWifiNmeWmmQosInfoMask;
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEmpty
-
-  DESCRIPTION
-    Empty Structure to indicate that no credentials are available.
-
-  MEMBERS
-    empty  - Only element of the empty structure (always set to 0).
-
-*******************************************************************************/
-typedef struct
-{
-    u8 empty;
-} CsrWifiNmeEmpty;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmePassphrase
-
-  DESCRIPTION
-    Structure holding the ASCII Pass Phrase data.
-
-  MEMBERS
-    encryptionMode - Encryption type as defined in CsrWifiSmeEncryption.
-    passphrase     - Pass phrase ASCII value.
-
-*******************************************************************************/
-typedef struct
-{
-    u16      encryptionMode;
-    char *passphrase;
-} CsrWifiNmePassphrase;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmePsk
-
-  DESCRIPTION
-    Structure holding the Pre-Shared Key data.
-
-  MEMBERS
-    encryptionMode - Encryption type as defined in CsrWifiSmeEncryption.
-    psk            - Pre-Shared Key value.
-
-*******************************************************************************/
-typedef struct
-{
-    u16 encryptionMode;
-    u8  psk[32];
-} CsrWifiNmePsk;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWapiCredentials
-
-  DESCRIPTION
-    Structure holding WAPI credentials data.
-
-  MEMBERS
-    certificateLength   - Length in bytes of the following client certificate.
-    certificate         - The actual client certificate data (if present).
-                          DER/PEM format supported.
-    privateKeyLength    - Length in bytes of the following private key.
-    privateKey          - The actual private key. DER/PEM format.
-    caCertificateLength - Length in bytes of the following certificate authority
-                          certificate.
-    caCertificate       - The actual certificate authority certificate data. If
-                          not supplied the received certificate authority
-                          certificate is assumed to be validate, if present the
-                          received certificate is validated against it. DER/PEM
-                          format supported.
-
-*******************************************************************************/
-typedef struct
-{
-    u32 certificateLength;
-    u8 *certificate;
-    u16 privateKeyLength;
-    u8 *privateKey;
-    u32 caCertificateLength;
-    u8 *caCertificate;
-} CsrWifiNmeWapiCredentials;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeConnectAttempt
-
-  DESCRIPTION
-    Structure holding Connection attempt data.
-
-  MEMBERS
-    bssid         - Id of Basic Service Set connections attempt have been made
-                    to.
-    status        - Status returned to indicate the success or otherwise of the
-                    connection attempt.
-    securityError - Security error status indicating the nature of the failure
-                    to connect.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiMacAddress  bssid;
-    CsrResult          status;
-    CsrWifiNmeSecError securityError;
-} CsrWifiNmeConnectAttempt;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEapCredentials
-
-  DESCRIPTION
-    Supports the use of multiple EAP methods via a single structure. The
-    methods required are indicated by the value set in the eapMethodMask
-
-  MEMBERS
-    eapMethodMask
-                   - Bit mask of supported EAP methods
-                     Currently only supports the setting of one bit.
-                     Required for all the EAP methods.
-    authMode
-                   - Bit mask representing the authentication types that may be
-                     supported by a suitable AP. An AP must support at least one
-                     of the authentication types specified to be considered for
-                     connection. Required for all EAP methods.
-    encryptionMode
-                   - Bit mask representing the encryption types that may be
-                     supported by a suitable AP. An AP must support a suitable
-                     mix of the pairwise and group encryption types requested to
-                     be considered for connection. Required for all EAP methods.
-    userName
-                   - User name. Required for all EAP methods except: SIM or AKA.
-    userPassword
-                   - User Password. Required for all EAP methods except: TLS,
-                     SIM or AKA.
-    authServerUserIdentity
-                   - Authentication server user Identity. Required for all EAP
-                     methods except: TLS, SIM, AKA or FAST.
-    clientCertificateLength
-                   - Length in bytes of the following client certificate (if
-                     present). Only required for TLS.
-    clientCertificate
-                   - The actual client certificate data (if present). Only
-                     required for TLS. DER/PEM format supported.
-    certificateAuthorityCertificateLength
-                   - Length in bytes of the following certificate authority
-                     certificate (if present). Optional for TLS, TTLS, PEAP.
-    certificateAuthorityCertificate
-                   - The actual certificate authority certificate data (if
-                     present). If not supplied the received certificate
-                     authority certificate is assumed to be valid, if present
-                     the received certificate is validated against it. Optional
-                     for TLS, TTLS, PEAP. DER/PEM format supported.
-    privateKeyLength
-                   - Length in bytes of the following private key (if present).
-                     Only required for TLS.
-    privateKey
-                   - The actual private key (if present). Only required for TLS.
-                     DER/PEM format, maybe password protected.
-    privateKeyPassword
-                   - Optional password to protect the private key.
-    sessionLength
-                   - Length in bytes of the following session field Supported
-                     for all EAP methods except: SIM or AKA.
-    session
-                   - Session information to support faster re-authentication.
-                     Supported for all EAP methods except: SIM or AKA.
-    allowPacProvisioning
-                   - If TRUE: PAC provisioning is allowed 'over-the_air';
-                     If FALSE: a PAC must be supplied.
-                     Only required for FAST.
-    pacLength
-                   - Length the following PAC field. If allowPacProvisioning is
-                     FALSE then the PAC MUST be supplied (i.e. non-zero). Only
-                     required for FAST.
-    pac
-                   - The actual PAC data. If allowPacProvisioning is FALSE then
-                     the PAC MUST be supplied. Only required for FAST.
-    pacPassword
-                   - Optional password to protect the PAC. Only required for
-                     FAST.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiNmeEapMethodMask  eapMethodMask;
-    CsrWifiSmeAuthModeMask   authMode;
-    CsrWifiNmeEncryptionMask encryptionMode;
-    char           *userName;
-    char           *userPassword;
-    char           *authServerUserIdentity;
-    u32                clientCertificateLength;
-    u8                *clientCertificate;
-    u32                certificateAuthorityCertificateLength;
-    u8                *certificateAuthorityCertificate;
-    u16                privateKeyLength;
-    u8                *privateKey;
-    char           *privateKeyPassword;
-    u32                sessionLength;
-    u8                *session;
-    u8                  allowPacProvisioning;
-    u32                pacLength;
-    u8                *pac;
-    char           *pacPassword;
-} CsrWifiNmeEapCredentials;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmePeerConfig
-
-  DESCRIPTION
-    Structure holding Peer Config data.
-
-  MEMBERS
-    p2pDeviceId         -
-    groupCapabilityMask -
-    groupOwnerIntent    -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiMacAddress                p2pDeviceId;
-    CsrWifiSmeP2pGroupCapabilityMask groupCapabilityMask;
-    u8                         groupOwnerIntent;
-} CsrWifiNmePeerConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileIdentity
-
-  DESCRIPTION
-    The identity of a profile is defined as the unique combination the BSSID
-    and SSID.
-
-  MEMBERS
-    bssid  - ID of Basic Service Set for or the P2pDevice address of the GO for
-             which a connection attempt was made.
-    ssid   - Service Set Id.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiMacAddress bssid;
-    CsrWifiSsid       ssid;
-} CsrWifiNmeProfileIdentity;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWep128Keys
-
-  DESCRIPTION
-    Structure holding WEP Authentication Type and WEP keys that can be used
-    when using WEP128.
-
-  MEMBERS
-    wepAuthType    - Mask to select the WEP authentication type (Open or Shared)
-    selectedWepKey - Index to one of the four keys below indicating the
-                     currently used WEP key.
-    key1           - Value for key number 1.
-    key2           - Value for key number 2.
-    key3           - Value for key number 3.
-    key4           - Value for key number 4.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeAuthModeMask wepAuthType;
-    u8               selectedWepKey;
-    u8               key1[13];
-    u8               key2[13];
-    u8               key3[13];
-    u8               key4[13];
-} CsrWifiNmeWep128Keys;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWep64Keys
-
-  DESCRIPTION
-    Structure for holding WEP Authentication Type and WEP keys that can be
-    used when using WEP64.
-
-  MEMBERS
-    wepAuthType    - Mask to select the WEP authentication type (Open or Shared)
-    selectedWepKey - Index to one of the four keys below indicating the
-                     currently used WEP key.
-    key1           - Value for key number 1.
-    key2           - Value for key number 2.
-    key3           - Value for key number 3.
-    key4           - Value for key number 4.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeAuthModeMask wepAuthType;
-    u8               selectedWepKey;
-    u8               key1[5];
-    u8               key2[5];
-    u8               key3[5];
-    u8               key4[5];
-} CsrWifiNmeWep64Keys;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeCredentials
-
-  DESCRIPTION
-    Structure containing the Credentials data.
-
-  MEMBERS
-    credentialType            - Credential type value (as defined in the
-                                enumeration type).
-    credential                - Union containing credentials which depends on
-                                credentialType parameter.
-    credentialeap             -
-    credentialwapiPassphrase  -
-    credentialwpa2Passphrase  -
-    credentialwpa2Psk         -
-    credentialwapiPsk         -
-    credentialwpaPassphrase   -
-    credentialwapi            -
-    credentialwep128Key       -
-    credentialwpaPsk          -
-    credentialopenSystem      -
-    credentialwep64Key        -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiNmeCredentialType credentialType;
-    union {
-        CsrWifiNmeEapCredentials  eap;
-        CsrWifiNmePassphrase      wapiPassphrase;
-        CsrWifiNmePassphrase      wpa2Passphrase;
-        CsrWifiNmePsk             wpa2Psk;
-        CsrWifiNmePsk             wapiPsk;
-        CsrWifiNmePassphrase      wpaPassphrase;
-        CsrWifiNmeWapiCredentials wapi;
-        CsrWifiNmeWep128Keys      wep128Key;
-        CsrWifiNmePsk             wpaPsk;
-        CsrWifiNmeEmpty           openSystem;
-        CsrWifiNmeWep64Keys       wep64Key;
-    } credential;
-} CsrWifiNmeCredentials;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfile
-
-  DESCRIPTION
-    Structure containing the Profile data.
-
-  MEMBERS
-    profileIdentity - Profile Identity.
-    wmmQosInfoMask  - Mask for WMM QoS information.
-    bssType         - Type of BSS (Infrastructure or Adhoc).
-    channelNo       - Channel Number.
-    ccxOptionsMask  - Options mask for Cisco Compatible Extentions.
-    cloakedSsid     - Flag to decide whether the SSID is cloaked (not
-                      transmitted) or not.
-    credentials     - Credentials data.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiNmeProfileIdentity profileIdentity;
-    CsrWifiNmeWmmQosInfoMask  wmmQosInfoMask;
-    CsrWifiNmeBssType         bssType;
-    u8                  channelNo;
-    u8                  ccxOptionsMask;
-    u8                   cloakedSsid;
-    CsrWifiNmeCredentials     credentials;
-} CsrWifiNmeProfile;
-
-
-/* Downstream */
-#define CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST            (0x0000)
-
-#define CSR_WIFI_NME_PROFILE_SET_REQ                      ((CsrWifiNmePrim) (0x0000 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_DELETE_REQ                   ((CsrWifiNmePrim) (0x0001 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_DELETE_ALL_REQ               ((CsrWifiNmePrim) (0x0002 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_ORDER_SET_REQ                ((CsrWifiNmePrim) (0x0003 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_CONNECT_REQ                  ((CsrWifiNmePrim) (0x0004 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_WPS_REQ                              ((CsrWifiNmePrim) (0x0005 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_WPS_CANCEL_REQ                       ((CsrWifiNmePrim) (0x0006 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_CONNECTION_STATUS_GET_REQ            ((CsrWifiNmePrim) (0x0007 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_SIM_IMSI_GET_RES                     ((CsrWifiNmePrim) (0x0008 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_SIM_GSM_AUTH_RES                     ((CsrWifiNmePrim) (0x0009 + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_SIM_UMTS_AUTH_RES                    ((CsrWifiNmePrim) (0x000A + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_WPS_CONFIG_SET_REQ                   ((CsrWifiNmePrim) (0x000B + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_NME_EVENT_MASK_SET_REQ                   ((CsrWifiNmePrim) (0x000C + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST))
-
-
-#define CSR_WIFI_NME_PRIM_DOWNSTREAM_HIGHEST           (0x000C + CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)
-
-/* Upstream */
-#define CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST              (0x0000 + CSR_PRIM_UPSTREAM)
-
-#define CSR_WIFI_NME_PROFILE_SET_CFM                      ((CsrWifiNmePrim)(0x0000 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_DELETE_CFM                   ((CsrWifiNmePrim)(0x0001 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_DELETE_ALL_CFM               ((CsrWifiNmePrim)(0x0002 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_ORDER_SET_CFM                ((CsrWifiNmePrim)(0x0003 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_CONNECT_CFM                  ((CsrWifiNmePrim)(0x0004 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_WPS_CFM                              ((CsrWifiNmePrim)(0x0005 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_WPS_CANCEL_CFM                       ((CsrWifiNmePrim)(0x0006 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_CONNECTION_STATUS_GET_CFM            ((CsrWifiNmePrim)(0x0007 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_UPDATE_IND                   ((CsrWifiNmePrim)(0x0008 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_PROFILE_DISCONNECT_IND               ((CsrWifiNmePrim)(0x0009 + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_SIM_IMSI_GET_IND                     ((CsrWifiNmePrim)(0x000A + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_SIM_GSM_AUTH_IND                     ((CsrWifiNmePrim)(0x000B + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_SIM_UMTS_AUTH_IND                    ((CsrWifiNmePrim)(0x000C + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_WPS_CONFIG_SET_CFM                   ((CsrWifiNmePrim)(0x000D + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_NME_EVENT_MASK_SET_CFM                   ((CsrWifiNmePrim)(0x000E + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST))
-
-#define CSR_WIFI_NME_PRIM_UPSTREAM_HIGHEST             (0x000E + CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)
-
-#define CSR_WIFI_NME_PRIM_DOWNSTREAM_COUNT             (CSR_WIFI_NME_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_NME_PRIM_DOWNSTREAM_LOWEST)
-#define CSR_WIFI_NME_PRIM_UPSTREAM_COUNT               (CSR_WIFI_NME_PRIM_UPSTREAM_HIGHEST   + 1 - CSR_WIFI_NME_PRIM_UPSTREAM_LOWEST)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileSetReq
-
-  DESCRIPTION
-    Creates or updates an existing profile in the NME that matches the unique
-    identity of the profile. Each profile is identified by the combination of
-    BSSID and SSID. The profile contains all the required credentials for
-    attempting to connect to the network. Creating or updating a profile via
-    the NME PROFILE SET REQ does NOT add the profile to the preferred profile
-    list within the NME used for the NME auto-connect behaviour.
-
-  MEMBERS
-    common  - Common header for use with the CsrWifiFsm Module
-    profile - Specifies the identity and credentials of the network.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    CsrWifiNmeProfile profile;
-} CsrWifiNmeProfileSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDeleteReq
-
-  DESCRIPTION
-    Will delete the profile with a matching identity, but does NOT modify the
-    preferred profile list.
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    profileIdentity - Identity (BSSID, SSID) of profile to be deleted.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    CsrWifiNmeProfileIdentity profileIdentity;
-} CsrWifiNmeProfileDeleteReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDeleteAllReq
-
-  DESCRIPTION
-    Deletes all profiles present in the NME, but does NOT modify the
-    preferred profile list.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiNmeProfileDeleteAllReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileOrderSetReq
-
-  DESCRIPTION
-    Defines the preferred order that profiles present in the NME should be
-    used during the NME auto-connect behaviour.
-    If profileIdentitysCount == 0, it removes any existing preferred profile
-    list already present in the NME, effectively disabling the auto-connect
-    behaviour.
-    NOTE: Profile identities that do not match any profile stored in the NME
-    are ignored during the auto-connect procedure.
-    NOTE: during auto-connect the NME will only attempt to join an existing
-    adhoc network and it will never attempt to host an adhoc network; for
-    hosting and adhoc network, use CSR_WIFI_NME_PROFILE_CONNECT_REQ
-
-  MEMBERS
-    common                - Common header for use with the CsrWifiFsm Module
-    interfaceTag          - Interface Identifier; unique identifier of an
-                            interface
-    profileIdentitysCount - The number of profiles identities in the list.
-    profileIdentitys      - Points to the list of profile identities.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent            common;
-    u16                  interfaceTag;
-    u8                   profileIdentitysCount;
-    CsrWifiNmeProfileIdentity *profileIdentitys;
-} CsrWifiNmeProfileOrderSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileConnectReq
-
-  DESCRIPTION
-    Requests the NME to attempt to connect to the specified profile.
-    Overrides any current connection attempt.
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    profileIdentity - Identity (BSSID, SSID) of profile to be connected to.
-                      It must match an existing profile in the NME.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrWifiNmeProfileIdentity profileIdentity;
-} CsrWifiNmeProfileConnectReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsReq
-
-  DESCRIPTION
-    Requests the NME to look for WPS enabled APs and attempt to perform WPS
-    to determine the appropriate security credentials to connect to the AP.
-    If the PIN == '00000000' then 'push button mode' is indicated, otherwise
-    the PIN has to match that of the AP. 4 digit pin is passed by sending the
-    pin digits in pin[0]..pin[3] and rest of the contents filled with '-'.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    pin          - PIN value.
-    ssid         - Service Set identifier
-    bssid        - ID of Basic Service Set for which a WPS connection attempt is
-                   being made.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    u16         interfaceTag;
-    u8          pin[8];
-    CsrWifiSsid       ssid;
-    CsrWifiMacAddress bssid;
-} CsrWifiNmeWpsReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsCancelReq
-
-  DESCRIPTION
-    Requests the NME to cancel any WPS procedure that it is currently
-    performing. This includes WPS registrar activities started because of
-    CSR_WIFI_NME_AP_REGISTER.request
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiNmeWpsCancelReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeConnectionStatusGetReq
-
-  DESCRIPTION
-    Requests the current connection status of the NME.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiNmeConnectionStatusGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimImsiGetRes
-
-  DESCRIPTION
-    Response from the application that received the NME SIM IMSI GET IND.
-
-  MEMBERS
-    common   - Common header for use with the CsrWifiFsm Module
-    status   - Indicates the outcome of the requested operation: STATUS_SUCCESS
-               or STATUS_ERROR.
-    imsi     - The value of the IMSI obtained from the UICC.
-    cardType - The UICC type (GSM only (SIM), UMTS only (USIM), Both).
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    CsrResult             status;
-    char        *imsi;
-    CsrWifiNmeSimCardType cardType;
-} CsrWifiNmeSimImsiGetRes;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimGsmAuthRes
-
-  DESCRIPTION
-    Response from the application that received the NME SIM GSM AUTH IND. For
-    each GSM authentication round a GSM Ciphering key (Kc) and a signed
-    response (SRES) are produced. Since 2 or 3 GSM authentication rounds are
-    used the 2 or 3 Kc's obtained respectively are combined into one buffer
-    and similarly the 2 or 3 SRES's obtained are combined into another
-    buffer. The order of Kc values (SRES values respectively) in their buffer
-    is the same as that of their corresponding RAND values in the incoming
-    indication.
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    status     - Indicates the outcome of the requested operation:
-                 STATUS_SUCCESS or STATUS_ERROR
-    kcsLength  - Length in Bytes of Kc buffer. Legal values are: 16 or 24.
-    kcs        - Kc buffer holding 2 or 3 Kc values.
-    sresLength - Length in Bytes of SRES buffer. Legal values are: 8 or 12.
-    sres       - SRES buffer holding 2 or 3 SRES values.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-    u8        kcsLength;
-    u8       *kcs;
-    u8        sresLength;
-    u8       *sres;
-} CsrWifiNmeSimGsmAuthRes;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimUmtsAuthRes
-
-  DESCRIPTION
-    Response from the application that received the NME SIM UMTS AUTH IND.
-    The values of umtsCipherKey, umtsIntegrityKey, resParameterLength and
-    resParameter are only meanigful when result = UMTS_AUTH_RESULT_SUCCESS.
-    The value of auts is only meaningful when
-    result=UMTS_AUTH_RESULT_SYNC_FAIL.
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    status             - Indicates the outcome of the requested operation:
-                         STATUS_SUCCESS or STATUS_ERROR.
-    result             - The result of UMTS authentication as performed by the
-                         UICC which could be: Success, Authentication Reject or
-                         Synchronisation Failure. For all these 3 outcomes the
-                         value of status is success.
-    umtsCipherKey      - The UMTS Cipher Key as calculated and returned by the
-                         UICC.
-    umtsIntegrityKey   - The UMTS Integrity Key as calculated and returned by
-                         the UICC.
-    resParameterLength - The length (in bytes) of the RES parameter (min=4; max
-                         = 16).
-    resParameter       - The RES parameter as calculated and returned by the
-                         UICC.
-    auts               - The AUTS parameter as calculated and returned by the
-                         UICC.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent          common;
-    CsrResult                status;
-    CsrWifiNmeUmtsAuthResult result;
-    u8                 umtsCipherKey[16];
-    u8                 umtsIntegrityKey[16];
-    u8                 resParameterLength;
-    u8                *resParameter;
-    u8                 auts[14];
-} CsrWifiNmeSimUmtsAuthRes;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsConfigSetReq
-
-  DESCRIPTION
-    This primitive passes the WPS information for the device to NME. This may
-    be accepted only if no interface is active.
-
-  MEMBERS
-    common    - Common header for use with the CsrWifiFsm Module
-    wpsConfig - WPS config.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    CsrWifiSmeWpsConfig wpsConfig;
-} CsrWifiNmeWpsConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEventMaskSetReq
-
-  DESCRIPTION
-    The wireless manager application may register with the NME to receive
-    notification of interesting events. Indications will be sent only if the
-    wireless manager explicitly registers to be notified of that event.
-    indMask is a bit mask of values defined in CsrWifiNmeIndicationsMask.
-
-  MEMBERS
-    common  - Common header for use with the CsrWifiFsm Module
-    indMask - Set mask with values from CsrWifiNmeIndications
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    CsrWifiNmeIndicationsMask indMask;
-} CsrWifiNmeEventMaskSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileSetCfm
-
-  DESCRIPTION
-    Reports the status of the NME PROFILE SET REQ; the request will only fail
-    if the details specified in the profile contains an invalid combination
-    of parameters for example specifying the profile as cloaked but not
-    specifying the SSID. The NME doesn't limit the number of profiles that
-    may be created. The NME assumes that the entity configuring it is aware
-    of the appropriate limits.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Indicates the success or otherwise of the requested operation.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiNmeProfileSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDeleteCfm
-
-  DESCRIPTION
-    Reports the status of the CSR_WIFI_NME_PROFILE_DELETE_REQ.
-    Returns CSR_WIFI_NME_STATUS_NOT_FOUND if there is no matching profile.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Indicates the success or otherwise of the requested operation.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiNmeProfileDeleteCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDeleteAllCfm
-
-  DESCRIPTION
-    Reports the status of the CSR_WIFI_NME_PROFILE_DELETE_ALL_REQ.
-    Returns always CSR_WIFI_NME_STATUS_SUCCESS.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Indicates the success or otherwise of the requested operation, but
-             in this case it always set to success.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiNmeProfileDeleteAllCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileOrderSetCfm
-
-  DESCRIPTION
-    Confirmation to UNIFI_NME_PROFILE_ORDER_SET.request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Indicates the success or otherwise of the requested
-                   operation.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiNmeProfileOrderSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileConnectCfm
-
-  DESCRIPTION
-    Reports the status of the NME PROFILE CONNECT REQ. If unsuccessful the
-    connectAttempt parameters contain details of the APs that the NME
-    attempted to connect to before reporting the failure of the request.
-
-  MEMBERS
-    common               - Common header for use with the CsrWifiFsm Module
-    interfaceTag         - Interface Identifier; unique identifier of an
-                           interface
-    status               - Indicates the success or otherwise of the requested
-                           operation.
-    connectAttemptsCount - This parameter is relevant only if
-                           status!=CSR_WIFI_NME_STATUS_SUCCESS.
-                           Number of connection attempt elements provided with
-                           this primitive
-    connectAttempts      - This parameter is relevant only if
-                           status!=CSR_WIFI_NME_STATUS_SUCCESS.
-                           Points to the list of connection attempt elements
-                           provided with this primitive
-                           Each element of the list provides information about
-                           an AP on which the connection attempt was made and
-                           the error that occurred during the attempt.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrResult                 status;
-    u8                  connectAttemptsCount;
-    CsrWifiNmeConnectAttempt *connectAttempts;
-} CsrWifiNmeProfileConnectCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsCfm
-
-  DESCRIPTION
-    Reports the status of the NME WPS REQ.
-    If CSR_WIFI_NME_STATUS_SUCCESS, the profile parameter contains the
-    identity and credentials of the AP.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Indicates the success or otherwise of the requested
-                   operation.
-    profile      - This parameter is relevant only if
-                   status==CSR_WIFI_NME_STATUS_SUCCESS.
-                   The identity and credentials of the network.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    u16         interfaceTag;
-    CsrResult         status;
-    CsrWifiNmeProfile profile;
-} CsrWifiNmeWpsCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsCancelCfm
-
-  DESCRIPTION
-    Reports the status of the NME WPS REQ, the request is always SUCCESSFUL.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Only returns CSR_WIFI_NME_STATUS_SUCCESS
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiNmeWpsCancelCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeConnectionStatusGetCfm
-
-  DESCRIPTION
-    Reports the connection status of the NME.
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    interfaceTag     - Interface Identifier; unique identifier of an interface
-    status           - Indicates the success or otherwise of the requested
-                       operation.
-    connectionStatus - NME current connection status
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent            common;
-    u16                  interfaceTag;
-    CsrResult                  status;
-    CsrWifiNmeConnectionStatus connectionStatus;
-} CsrWifiNmeConnectionStatusGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileUpdateInd
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that informs that application that the contained profile has
-    changed.
-    For example, either the credentials EAP-FAST PAC file or the session data
-    within the profile has changed.
-    It is up to the application whether it stores this updated profile or
-    not.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    profile      - The identity and credentials of the network.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    u16         interfaceTag;
-    CsrWifiNmeProfile profile;
-} CsrWifiNmeProfileUpdateInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeProfileDisconnectInd
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that informs that application that the current profile
-    connection has disconnected. The indication will contain information
-    about APs that it attempted to maintain the connection via i.e. in the
-    case of failed roaming.
-
-  MEMBERS
-    common               - Common header for use with the CsrWifiFsm Module
-    interfaceTag         - Interface Identifier; unique identifier of an
-                           interface
-    connectAttemptsCount - Number of connection attempt elements provided with
-                           this primitive
-    connectAttempts      - Points to the list of connection attempt elements
-                           provided with this primitive
-                           Each element of the list provides information about
-                           an AP on which the connection attempt was made and
-                           the error occurred during the attempt.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    u8                  connectAttemptsCount;
-    CsrWifiNmeConnectAttempt *connectAttempts;
-} CsrWifiNmeProfileDisconnectInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimImsiGetInd
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that requests the IMSI and UICC type from the UICC Manager.
-    This indication is generated when the NME is attempting to connect to a
-    profile configured for EAP-SIM/AKA. An application MUST register to
-    receive this indication for the NME to support the EAP-SIM/AKA credential
-    types. Otherwise the NME has no route to obtain the information from the
-    UICC.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiNmeSimImsiGetInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimGsmAuthInd
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that requests the UICC Manager to perform a GSM
-    authentication on behalf of the NME. This indication is generated when
-    the NME is attempting to connect to a profile configured for EAP-SIM. An
-    application MUST register to receive this indication for the NME to
-    support the EAP-SIM credential types. Otherwise the NME has no route to
-    obtain the information from the UICC. EAP-SIM authentication requires 2
-    or 3 GSM authentication rounds and therefore 2 or 3 RANDS (GSM Random
-    Challenges) are included.
-
-  MEMBERS
-    common      - Common header for use with the CsrWifiFsm Module
-    randsLength - GSM RAND is 16 bytes long hence valid values are 32 (2 RANDS)
-                  or 48 (3 RANDs).
-    rands       - 2 or 3 RANDs values.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u8        randsLength;
-    u8       *rands;
-} CsrWifiNmeSimGsmAuthInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeSimUmtsAuthInd
-
-  DESCRIPTION
-    Indication generated from the NME (if an application subscribes to
-    receive it) that requests the UICC Manager to perform a UMTS
-    authentication on behalf of the NME. This indication is generated when
-    the NME is attempting to connect to a profile configured for EAP-AKA. An
-    application MUST register to receive this indication for the NME to
-    support the EAP-AKA credential types. Otherwise the NME has no route to
-    obtain the information from the USIM. EAP-AKA requires one UMTS
-    authentication round and therefore only one RAND and one AUTN values are
-    included.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    rand   - UMTS RAND value.
-    autn   - UMTS AUTN value.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u8        rand[16];
-    u8        autn[16];
-} CsrWifiNmeSimUmtsAuthInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeWpsConfigSetCfm
-
-  DESCRIPTION
-    Confirm.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Status of the request.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiNmeWpsConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiNmeEventMaskSetCfm
-
-  DESCRIPTION
-    The NME calls the primitive to report the result of the request
-    primitive.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiNmeEventMaskSetCfm;
-
-#endif /* CSR_WIFI_NME_PRIM_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_serialize.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_serialize.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_serialize.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_serialize.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,166 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_NME_SERIALIZE_H__
-#define CSR_WIFI_NME_SERIALIZE_H__
-
-#include "csr_wifi_msgconv.h"
-#include "csr_wifi_nme_prim.h"
-
-#ifndef CSR_WIFI_NME_ENABLE
-#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_serialize.h
-#endif
-
-extern void CsrWifiNmePfree(void *ptr);
-
-extern u8* CsrWifiNmeProfileSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeProfileSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeProfileSetReqSizeof(void *msg);
-extern void CsrWifiNmeProfileSetReqSerFree(void *msg);
-
-extern u8* CsrWifiNmeProfileDeleteReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeProfileDeleteReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeProfileDeleteReqSizeof(void *msg);
-#define CsrWifiNmeProfileDeleteReqSerFree CsrWifiNmePfree
-
-#define CsrWifiNmeProfileDeleteAllReqSer CsrWifiEventSer
-#define CsrWifiNmeProfileDeleteAllReqDes CsrWifiEventDes
-#define CsrWifiNmeProfileDeleteAllReqSizeof CsrWifiEventSizeof
-#define CsrWifiNmeProfileDeleteAllReqSerFree CsrWifiNmePfree
-
-extern u8* CsrWifiNmeProfileOrderSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeProfileOrderSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeProfileOrderSetReqSizeof(void *msg);
-extern void CsrWifiNmeProfileOrderSetReqSerFree(void *msg);
-
-extern u8* CsrWifiNmeProfileConnectReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeProfileConnectReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeProfileConnectReqSizeof(void *msg);
-#define CsrWifiNmeProfileConnectReqSerFree CsrWifiNmePfree
-
-extern u8* CsrWifiNmeWpsReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeWpsReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeWpsReqSizeof(void *msg);
-#define CsrWifiNmeWpsReqSerFree CsrWifiNmePfree
-
-#define CsrWifiNmeWpsCancelReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeWpsCancelReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeWpsCancelReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeWpsCancelReqSerFree CsrWifiNmePfree
-
-#define CsrWifiNmeConnectionStatusGetReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeConnectionStatusGetReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeConnectionStatusGetReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeConnectionStatusGetReqSerFree CsrWifiNmePfree
-
-extern u8* CsrWifiNmeSimImsiGetResSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeSimImsiGetResDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeSimImsiGetResSizeof(void *msg);
-extern void CsrWifiNmeSimImsiGetResSerFree(void *msg);
-
-extern u8* CsrWifiNmeSimGsmAuthResSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeSimGsmAuthResDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeSimGsmAuthResSizeof(void *msg);
-extern void CsrWifiNmeSimGsmAuthResSerFree(void *msg);
-
-extern u8* CsrWifiNmeSimUmtsAuthResSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeSimUmtsAuthResDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeSimUmtsAuthResSizeof(void *msg);
-extern void CsrWifiNmeSimUmtsAuthResSerFree(void *msg);
-
-extern u8* CsrWifiNmeWpsConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeWpsConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeWpsConfigSetReqSizeof(void *msg);
-extern void CsrWifiNmeWpsConfigSetReqSerFree(void *msg);
-
-#define CsrWifiNmeEventMaskSetReqSer CsrWifiEventCsrUint32Ser
-#define CsrWifiNmeEventMaskSetReqDes CsrWifiEventCsrUint32Des
-#define CsrWifiNmeEventMaskSetReqSizeof CsrWifiEventCsrUint32Sizeof
-#define CsrWifiNmeEventMaskSetReqSerFree CsrWifiNmePfree
-
-#define CsrWifiNmeProfileSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeProfileSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeProfileSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeProfileSetCfmSerFree CsrWifiNmePfree
-
-#define CsrWifiNmeProfileDeleteCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeProfileDeleteCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeProfileDeleteCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeProfileDeleteCfmSerFree CsrWifiNmePfree
-
-#define CsrWifiNmeProfileDeleteAllCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeProfileDeleteAllCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeProfileDeleteAllCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeProfileDeleteAllCfmSerFree CsrWifiNmePfree
-
-extern u8* CsrWifiNmeProfileOrderSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeProfileOrderSetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeProfileOrderSetCfmSizeof(void *msg);
-#define CsrWifiNmeProfileOrderSetCfmSerFree CsrWifiNmePfree
-
-extern u8* CsrWifiNmeProfileConnectCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeProfileConnectCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeProfileConnectCfmSizeof(void *msg);
-extern void CsrWifiNmeProfileConnectCfmSerFree(void *msg);
-
-extern u8* CsrWifiNmeWpsCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeWpsCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeWpsCfmSizeof(void *msg);
-extern void CsrWifiNmeWpsCfmSerFree(void *msg);
-
-extern u8* CsrWifiNmeWpsCancelCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeWpsCancelCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeWpsCancelCfmSizeof(void *msg);
-#define CsrWifiNmeWpsCancelCfmSerFree CsrWifiNmePfree
-
-extern u8* CsrWifiNmeConnectionStatusGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeConnectionStatusGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeConnectionStatusGetCfmSizeof(void *msg);
-#define CsrWifiNmeConnectionStatusGetCfmSerFree CsrWifiNmePfree
-
-extern u8* CsrWifiNmeProfileUpdateIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeProfileUpdateIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeProfileUpdateIndSizeof(void *msg);
-extern void CsrWifiNmeProfileUpdateIndSerFree(void *msg);
-
-extern u8* CsrWifiNmeProfileDisconnectIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeProfileDisconnectIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeProfileDisconnectIndSizeof(void *msg);
-extern void CsrWifiNmeProfileDisconnectIndSerFree(void *msg);
-
-#define CsrWifiNmeSimImsiGetIndSer CsrWifiEventSer
-#define CsrWifiNmeSimImsiGetIndDes CsrWifiEventDes
-#define CsrWifiNmeSimImsiGetIndSizeof CsrWifiEventSizeof
-#define CsrWifiNmeSimImsiGetIndSerFree CsrWifiNmePfree
-
-extern u8* CsrWifiNmeSimGsmAuthIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeSimGsmAuthIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeSimGsmAuthIndSizeof(void *msg);
-extern void CsrWifiNmeSimGsmAuthIndSerFree(void *msg);
-
-extern u8* CsrWifiNmeSimUmtsAuthIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiNmeSimUmtsAuthIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiNmeSimUmtsAuthIndSizeof(void *msg);
-#define CsrWifiNmeSimUmtsAuthIndSerFree CsrWifiNmePfree
-
-#define CsrWifiNmeWpsConfigSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeWpsConfigSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeWpsConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeWpsConfigSetCfmSerFree CsrWifiNmePfree
-
-#define CsrWifiNmeEventMaskSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiNmeEventMaskSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiNmeEventMaskSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiNmeEventMaskSetCfmSerFree CsrWifiNmePfree
-
-#endif /* CSR_WIFI_NME_SERIALIZE_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_task.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_task.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_nme_task.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_nme_task.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_NME_TASK_H__
-#define CSR_WIFI_NME_TASK_H__
-
-#include <linux/types.h>
-#include "csr_sched.h"
-
-#ifndef CSR_WIFI_NME_ENABLE
-#error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_task.h
-#endif
-
-#define CSR_WIFI_NME_LOG_ID 0x1203FFFF
-extern CsrSchedQid CSR_WIFI_NME_IFACEQUEUE;
-
-#endif /* CSR_WIFI_NME_TASK_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_private_common.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_private_common.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_private_common.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_private_common.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,81 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_PRIVATE_COMMON_H__
-#define CSR_WIFI_PRIVATE_COMMON_H__
-
-/**
- * @brief maximum number of STAs allowed to be connected
- *
- * @par Description
- *   min & max Beacon Interval
- */
-#define CSR_WIFI_AP_MAX_ASSOC_STA   8
-
-/** Number of only b rates */
-#define CSR_WIFI_SME_AP_MAX_ONLY_B_RATES        4
-
-
-/** Number of mandatory b rates */
-#define CSR_WIFI_SME_AP_MAX_MANDATORY_B_RATES   2
-
-
-/** Number of mandatory bg rates */
-#define CSR_WIFI_SME_AP_MAX_MANDATORY_BG_RATES  4
-
-
-/** Number of bg rates */
-#define CSR_WIFI_SME_AP_MAX_BG_RATES            12
-
-
-/** Number of no b only g rates */
-#define CSR_WIFI_SME_AP_MAX_NO_B_ONLY_G_RATES   8
-
-
-/** Number of mandatory g rates */
-#define CSR_WIFI_SME_AP_MAX_MANDATORY_G_RATES   7
-
-
-/* Number of g mandatory rates */
-#define CSR_WIFI_SME_AP_G_MANDATORY_RATES_NUM   7
-
-
-/* Number of b mandatory rates */
-#define CSR_WIFI_SME_AP_B_MANDATORY_RATES_NUM   2
-
-
-/* Number of b/g mandatory rates */
-#define CSR_WIFI_SME_AP_BG_MANDATORY_RATES_NUM   4
-
-
-/* The maximum allowed length of SSID */
-#define CSR_WIFI_SME_AP_SSID_MAX_LENGTH         32
-
-/* Refer 8.4.2.27 RSN element - we support TKIP, WPA2, WAPI and PSK only, no pmkid, group cipher suite */
-#define CSR_WIFI_SME_RSN_PACKED_SIZE (1 + 1 + 2 + 4 + 2 + 4 * 2 + 2 + 4 * 1 + 2 + 24)
-
-/* Refer 7.3.2.9 (ISO/IEC 8802-11:2006) WAPI element - we support WAPI PSK only, no bkid, group cipher suite */
-#define CSR_WIFI_SME_WAPI_PACKED_SIZE (1 + 1 + 2 + 2 + 4 * 1 + 2 + 4 * 1 + 4 + 2 + 24)
-
-
-/* Common structure for NME and SME to maintain Interface mode*/
-typedef u8 CsrWifiInterfaceMode;
-#define  CSR_WIFI_MODE_NONE                             ((CsrWifiInterfaceMode) 0xFF)
-#define  CSR_WIFI_MODE_STA                              ((CsrWifiInterfaceMode) 0x00)
-#define  CSR_WIFI_MODE_AP                               ((CsrWifiInterfaceMode) 0x01)
-#define  CSR_WIFI_MODE_P2P_DEVICE                       ((CsrWifiInterfaceMode) 0x02)
-#define  CSR_WIFI_MODE_P2P_CLI                          ((CsrWifiInterfaceMode) 0x03)
-#define  CSR_WIFI_MODE_P2P_GO                           ((CsrWifiInterfaceMode) 0x04)
-#define  CSR_WIFI_MODE_AMP                              ((CsrWifiInterfaceMode) 0x05)
-#define  CSR_WIFI_MODE_WPS_ENROLLEE                     ((CsrWifiInterfaceMode) 0x06)
-#define  CSR_WIFI_MODE_IBSS                             ((CsrWifiInterfaceMode) 0x07)
-
-#endif
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_result.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_result.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_result.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_result.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_RESULT_H__
-#define CSR_WIFI_RESULT_H__
-
-#include "csr_result.h"
-
-/* THIS FILE SHOULD CONTAIN ONLY RESULT CODES */
-
-/* Result Codes */
-#define CSR_WIFI_HIP_RESULT_INVALID_VALUE    ((CsrResult) 1) /* Invalid argument value */
-#define CSR_WIFI_HIP_RESULT_NO_DEVICE        ((CsrResult) 2) /* The specified device is no longer present */
-#define CSR_WIFI_HIP_RESULT_NO_SPACE         ((CsrResult) 3) /* A queue or buffer is full */
-#define CSR_WIFI_HIP_RESULT_NO_MEMORY        ((CsrResult) 4) /* Fatal error, no memory */
-#define CSR_WIFI_HIP_RESULT_RANGE            ((CsrResult) 5) /* Request exceeds the range of a file or a buffer */
-#define CSR_WIFI_HIP_RESULT_NOT_FOUND        ((CsrResult) 6) /* A file (typically a f/w patch) is not found */
-
-#endif /* CSR_WIFI_RESULT_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_converter_init.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_converter_init.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_converter_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_converter_init.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,82 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#include "csr_msgconv.h"
-#include "csr_macro.h"
-
-
-#ifdef CSR_LOG_ENABLE
-#include "csr_log.h"
-#endif
-
-#ifndef EXCLUDE_CSR_WIFI_ROUTER_MODULE
-#include "csr_wifi_router_serialize.h"
-#include "csr_wifi_router_prim.h"
-
-static CsrMsgConvMsgEntry csrwifirouter_conv_lut[] = {
-    { CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_REQ, CsrWifiRouterMaPacketSubscribeReqSizeof, CsrWifiRouterMaPacketSubscribeReqSer, CsrWifiRouterMaPacketSubscribeReqDes, CsrWifiRouterMaPacketSubscribeReqSerFree },
-    { CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_REQ, CsrWifiRouterMaPacketUnsubscribeReqSizeof, CsrWifiRouterMaPacketUnsubscribeReqSer, CsrWifiRouterMaPacketUnsubscribeReqDes, CsrWifiRouterMaPacketUnsubscribeReqSerFree },
-    { CSR_WIFI_ROUTER_MA_PACKET_REQ, CsrWifiRouterMaPacketReqSizeof, CsrWifiRouterMaPacketReqSer, CsrWifiRouterMaPacketReqDes, CsrWifiRouterMaPacketReqSerFree },
-    { CSR_WIFI_ROUTER_MA_PACKET_RES, CsrWifiRouterMaPacketResSizeof, CsrWifiRouterMaPacketResSer, CsrWifiRouterMaPacketResDes, CsrWifiRouterMaPacketResSerFree },
-    { CSR_WIFI_ROUTER_MA_PACKET_CANCEL_REQ, CsrWifiRouterMaPacketCancelReqSizeof, CsrWifiRouterMaPacketCancelReqSer, CsrWifiRouterMaPacketCancelReqDes, CsrWifiRouterMaPacketCancelReqSerFree },
-    { CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_CFM, CsrWifiRouterMaPacketSubscribeCfmSizeof, CsrWifiRouterMaPacketSubscribeCfmSer, CsrWifiRouterMaPacketSubscribeCfmDes, CsrWifiRouterMaPacketSubscribeCfmSerFree },
-    { CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_CFM, CsrWifiRouterMaPacketUnsubscribeCfmSizeof, CsrWifiRouterMaPacketUnsubscribeCfmSer, CsrWifiRouterMaPacketUnsubscribeCfmDes, CsrWifiRouterMaPacketUnsubscribeCfmSerFree },
-    { CSR_WIFI_ROUTER_MA_PACKET_CFM, CsrWifiRouterMaPacketCfmSizeof, CsrWifiRouterMaPacketCfmSer, CsrWifiRouterMaPacketCfmDes, CsrWifiRouterMaPacketCfmSerFree },
-    { CSR_WIFI_ROUTER_MA_PACKET_IND, CsrWifiRouterMaPacketIndSizeof, CsrWifiRouterMaPacketIndSer, CsrWifiRouterMaPacketIndDes, CsrWifiRouterMaPacketIndSerFree },
-
-    { 0, NULL, NULL, NULL, NULL },
-};
-
-CsrMsgConvMsgEntry* CsrWifiRouterConverterLookup(CsrMsgConvMsgEntry *ce, u16 msgType)
-{
-    if (msgType & CSR_PRIM_UPSTREAM)
-    {
-        u16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT;
-        if (idx < (CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT) &&
-            csrwifirouter_conv_lut[idx].msgType == msgType)
-        {
-            return &csrwifirouter_conv_lut[idx];
-        }
-    }
-    else
-    {
-        if (msgType < CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT &&
-            csrwifirouter_conv_lut[msgType].msgType == msgType)
-        {
-            return &csrwifirouter_conv_lut[msgType];
-        }
-    }
-    return NULL;
-}
-
-
-void CsrWifiRouterConverterInit(void)
-{
-    CsrMsgConvInsert(CSR_WIFI_ROUTER_PRIM, csrwifirouter_conv_lut);
-    CsrMsgConvCustomLookupRegister(CSR_WIFI_ROUTER_PRIM, CsrWifiRouterConverterLookup);
-}
-
-
-#ifdef CSR_LOG_ENABLE
-static const CsrLogPrimitiveInformation csrwifirouter_conv_info = {
-    CSR_WIFI_ROUTER_PRIM,
-    (char *)"CSR_WIFI_ROUTER_PRIM",
-    csrwifirouter_conv_lut
-};
-const CsrLogPrimitiveInformation* CsrWifiRouterTechInfoGet(void)
-{
-    return &csrwifirouter_conv_info;
-}
-
-
-#endif /* CSR_LOG_ENABLE */
-#endif /* EXCLUDE_CSR_WIFI_ROUTER_MODULE */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_converter_init.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_converter_init.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_converter_init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_converter_init.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_ROUTER_CONVERTER_INIT_H__
-#define CSR_WIFI_ROUTER_CONVERTER_INIT_H__
-
-#ifndef EXCLUDE_CSR_WIFI_ROUTER_MODULE
-
-#include "csr_msgconv.h"
-
-#ifdef CSR_LOG_ENABLE
-#include "csr_log.h"
-
-extern const CsrLogPrimitiveInformation* CsrWifiRouterTechInfoGet(void);
-#endif /* CSR_LOG_ENABLE */
-
-extern void CsrWifiRouterConverterInit(void);
-
-#else /* EXCLUDE_CSR_WIFI_ROUTER_MODULE */
-
-#define CsrWifiRouterConverterInit()
-
-#endif /* EXCLUDE_CSR_WIFI_ROUTER_MODULE */
-
-#endif /* CSR_WIFI_ROUTER_CONVERTER_INIT_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,134 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#include "csr_msgconv.h"
-#include "csr_macro.h"
-
-#ifdef CSR_LOG_ENABLE
-#include "csr_log.h"
-#endif
-
-#ifndef EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE
-#include "csr_wifi_router_ctrl_serialize.h"
-#include "csr_wifi_router_ctrl_prim.h"
-
-static CsrMsgConvMsgEntry csrwifirouterctrl_conv_lut[] = {
-    { CSR_WIFI_ROUTER_CTRL_CONFIGURE_POWER_MODE_REQ, CsrWifiRouterCtrlConfigurePowerModeReqSizeof, CsrWifiRouterCtrlConfigurePowerModeReqSer, CsrWifiRouterCtrlConfigurePowerModeReqDes, CsrWifiRouterCtrlConfigurePowerModeReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_HIP_REQ, CsrWifiRouterCtrlHipReqSizeof, CsrWifiRouterCtrlHipReqSer, CsrWifiRouterCtrlHipReqDes, CsrWifiRouterCtrlHipReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_REQ, CsrWifiRouterCtrlMediaStatusReqSizeof, CsrWifiRouterCtrlMediaStatusReqSer, CsrWifiRouterCtrlMediaStatusReqDes, CsrWifiRouterCtrlMediaStatusReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_RES, CsrWifiRouterCtrlMulticastAddressResSizeof, CsrWifiRouterCtrlMulticastAddressResSer, CsrWifiRouterCtrlMulticastAddressResDes, CsrWifiRouterCtrlMulticastAddressResSerFree },
-    { CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_REQ, CsrWifiRouterCtrlPortConfigureReqSizeof, CsrWifiRouterCtrlPortConfigureReqSer, CsrWifiRouterCtrlPortConfigureReqDes, CsrWifiRouterCtrlPortConfigureReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_REQ, CsrWifiRouterCtrlQosControlReqSizeof, CsrWifiRouterCtrlQosControlReqSer, CsrWifiRouterCtrlQosControlReqDes, CsrWifiRouterCtrlQosControlReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_SUSPEND_RES, CsrWifiRouterCtrlSuspendResSizeof, CsrWifiRouterCtrlSuspendResSer, CsrWifiRouterCtrlSuspendResDes, CsrWifiRouterCtrlSuspendResSerFree },
-    { CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_REQ, CsrWifiRouterCtrlTclasAddReqSizeof, CsrWifiRouterCtrlTclasAddReqSer, CsrWifiRouterCtrlTclasAddReqDes, CsrWifiRouterCtrlTclasAddReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_RESUME_RES, CsrWifiRouterCtrlResumeResSizeof, CsrWifiRouterCtrlResumeResSer, CsrWifiRouterCtrlResumeResDes, CsrWifiRouterCtrlResumeResSerFree },
-    { CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_REQ, CsrWifiRouterCtrlRawSdioDeinitialiseReqSizeof, CsrWifiRouterCtrlRawSdioDeinitialiseReqSer, CsrWifiRouterCtrlRawSdioDeinitialiseReqDes, CsrWifiRouterCtrlRawSdioDeinitialiseReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_REQ, CsrWifiRouterCtrlRawSdioInitialiseReqSizeof, CsrWifiRouterCtrlRawSdioInitialiseReqSer, CsrWifiRouterCtrlRawSdioInitialiseReqDes, CsrWifiRouterCtrlRawSdioInitialiseReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_REQ, CsrWifiRouterCtrlTclasDelReqSizeof, CsrWifiRouterCtrlTclasDelReqSer, CsrWifiRouterCtrlTclasDelReqDes, CsrWifiRouterCtrlTclasDelReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_TRAFFIC_CLASSIFICATION_REQ, CsrWifiRouterCtrlTrafficClassificationReqSizeof, CsrWifiRouterCtrlTrafficClassificationReqSer, CsrWifiRouterCtrlTrafficClassificationReqDes, CsrWifiRouterCtrlTrafficClassificationReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_REQ, CsrWifiRouterCtrlTrafficConfigReqSizeof, CsrWifiRouterCtrlTrafficConfigReqSer, CsrWifiRouterCtrlTrafficConfigReqDes, CsrWifiRouterCtrlTrafficConfigReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WIFI_OFF_REQ, CsrWifiRouterCtrlWifiOffReqSizeof, CsrWifiRouterCtrlWifiOffReqSer, CsrWifiRouterCtrlWifiOffReqDes, CsrWifiRouterCtrlWifiOffReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WIFI_OFF_RES, CsrWifiRouterCtrlWifiOffResSizeof, CsrWifiRouterCtrlWifiOffResSer, CsrWifiRouterCtrlWifiOffResDes, CsrWifiRouterCtrlWifiOffResSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ, CsrWifiRouterCtrlWifiOnReqSizeof, CsrWifiRouterCtrlWifiOnReqSer, CsrWifiRouterCtrlWifiOnReqDes, CsrWifiRouterCtrlWifiOnReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES, CsrWifiRouterCtrlWifiOnResSizeof, CsrWifiRouterCtrlWifiOnResSer, CsrWifiRouterCtrlWifiOnResDes, CsrWifiRouterCtrlWifiOnResSerFree },
-    { CSR_WIFI_ROUTER_CTRL_M4_TRANSMIT_REQ, CsrWifiRouterCtrlM4TransmitReqSizeof, CsrWifiRouterCtrlM4TransmitReqSer, CsrWifiRouterCtrlM4TransmitReqDes, CsrWifiRouterCtrlM4TransmitReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_MODE_SET_REQ, CsrWifiRouterCtrlModeSetReqSizeof, CsrWifiRouterCtrlModeSetReqSer, CsrWifiRouterCtrlModeSetReqDes, CsrWifiRouterCtrlModeSetReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_PEER_ADD_REQ, CsrWifiRouterCtrlPeerAddReqSizeof, CsrWifiRouterCtrlPeerAddReqSer, CsrWifiRouterCtrlPeerAddReqDes, CsrWifiRouterCtrlPeerAddReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_PEER_DEL_REQ, CsrWifiRouterCtrlPeerDelReqSizeof, CsrWifiRouterCtrlPeerDelReqSer, CsrWifiRouterCtrlPeerDelReqDes, CsrWifiRouterCtrlPeerDelReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_REQ, CsrWifiRouterCtrlPeerUpdateReqSizeof, CsrWifiRouterCtrlPeerUpdateReqSer, CsrWifiRouterCtrlPeerUpdateReqDes, CsrWifiRouterCtrlPeerUpdateReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ, CsrWifiRouterCtrlCapabilitiesReqSizeof, CsrWifiRouterCtrlCapabilitiesReqSer, CsrWifiRouterCtrlCapabilitiesReqDes, CsrWifiRouterCtrlCapabilitiesReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ, CsrWifiRouterCtrlBlockAckEnableReqSizeof, CsrWifiRouterCtrlBlockAckEnableReqSer, CsrWifiRouterCtrlBlockAckEnableReqDes, CsrWifiRouterCtrlBlockAckEnableReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ, CsrWifiRouterCtrlBlockAckDisableReqSizeof, CsrWifiRouterCtrlBlockAckDisableReqSer, CsrWifiRouterCtrlBlockAckDisableReqDes, CsrWifiRouterCtrlBlockAckDisableReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ, CsrWifiRouterCtrlWapiRxPktReqSizeof, CsrWifiRouterCtrlWapiRxPktReqSer, CsrWifiRouterCtrlWapiRxPktReqDes, CsrWifiRouterCtrlWapiRxPktReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, CsrWifiRouterCtrlWapiMulticastFilterReqSizeof, CsrWifiRouterCtrlWapiMulticastFilterReqSer, CsrWifiRouterCtrlWapiMulticastFilterReqDes, CsrWifiRouterCtrlWapiMulticastFilterReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, CsrWifiRouterCtrlWapiUnicastFilterReqSizeof, CsrWifiRouterCtrlWapiUnicastFilterReqSer, CsrWifiRouterCtrlWapiUnicastFilterReqDes, CsrWifiRouterCtrlWapiUnicastFilterReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ, CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof, CsrWifiRouterCtrlWapiUnicastTxPktReqSer, CsrWifiRouterCtrlWapiUnicastTxPktReqDes, CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ, CsrWifiRouterCtrlWapiFilterReqSizeof, CsrWifiRouterCtrlWapiFilterReqSer, CsrWifiRouterCtrlWapiFilterReqDes, CsrWifiRouterCtrlWapiFilterReqSerFree },
-    { CSR_WIFI_ROUTER_CTRL_HIP_IND, CsrWifiRouterCtrlHipIndSizeof, CsrWifiRouterCtrlHipIndSer, CsrWifiRouterCtrlHipIndDes, CsrWifiRouterCtrlHipIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND, CsrWifiRouterCtrlMulticastAddressIndSizeof, CsrWifiRouterCtrlMulticastAddressIndSer, CsrWifiRouterCtrlMulticastAddressIndDes, CsrWifiRouterCtrlMulticastAddressIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM, CsrWifiRouterCtrlPortConfigureCfmSizeof, CsrWifiRouterCtrlPortConfigureCfmSer, CsrWifiRouterCtrlPortConfigureCfmDes, CsrWifiRouterCtrlPortConfigureCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_RESUME_IND, CsrWifiRouterCtrlResumeIndSizeof, CsrWifiRouterCtrlResumeIndSer, CsrWifiRouterCtrlResumeIndDes, CsrWifiRouterCtrlResumeIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_SUSPEND_IND, CsrWifiRouterCtrlSuspendIndSizeof, CsrWifiRouterCtrlSuspendIndSer, CsrWifiRouterCtrlSuspendIndDes, CsrWifiRouterCtrlSuspendIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_CFM, CsrWifiRouterCtrlTclasAddCfmSizeof, CsrWifiRouterCtrlTclasAddCfmSer, CsrWifiRouterCtrlTclasAddCfmDes, CsrWifiRouterCtrlTclasAddCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_CFM, CsrWifiRouterCtrlRawSdioDeinitialiseCfmSizeof, CsrWifiRouterCtrlRawSdioDeinitialiseCfmSer, CsrWifiRouterCtrlRawSdioDeinitialiseCfmDes, CsrWifiRouterCtrlRawSdioDeinitialiseCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_CFM, CsrWifiRouterCtrlRawSdioInitialiseCfmSizeof, CsrWifiRouterCtrlRawSdioInitialiseCfmSer, CsrWifiRouterCtrlRawSdioInitialiseCfmDes, CsrWifiRouterCtrlRawSdioInitialiseCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_CFM, CsrWifiRouterCtrlTclasDelCfmSizeof, CsrWifiRouterCtrlTclasDelCfmSer, CsrWifiRouterCtrlTclasDelCfmDes, CsrWifiRouterCtrlTclasDelCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_TRAFFIC_PROTOCOL_IND, CsrWifiRouterCtrlTrafficProtocolIndSizeof, CsrWifiRouterCtrlTrafficProtocolIndSer, CsrWifiRouterCtrlTrafficProtocolIndDes, CsrWifiRouterCtrlTrafficProtocolIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_TRAFFIC_SAMPLE_IND, CsrWifiRouterCtrlTrafficSampleIndSizeof, CsrWifiRouterCtrlTrafficSampleIndSer, CsrWifiRouterCtrlTrafficSampleIndDes, CsrWifiRouterCtrlTrafficSampleIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WIFI_OFF_IND, CsrWifiRouterCtrlWifiOffIndSizeof, CsrWifiRouterCtrlWifiOffIndSer, CsrWifiRouterCtrlWifiOffIndDes, CsrWifiRouterCtrlWifiOffIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WIFI_OFF_CFM, CsrWifiRouterCtrlWifiOffCfmSizeof, CsrWifiRouterCtrlWifiOffCfmSer, CsrWifiRouterCtrlWifiOffCfmDes, CsrWifiRouterCtrlWifiOffCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WIFI_ON_IND, CsrWifiRouterCtrlWifiOnIndSizeof, CsrWifiRouterCtrlWifiOnIndSer, CsrWifiRouterCtrlWifiOnIndDes, CsrWifiRouterCtrlWifiOnIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WIFI_ON_CFM, CsrWifiRouterCtrlWifiOnCfmSizeof, CsrWifiRouterCtrlWifiOnCfmSer, CsrWifiRouterCtrlWifiOnCfmDes, CsrWifiRouterCtrlWifiOnCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_M4_READY_TO_SEND_IND, CsrWifiRouterCtrlM4ReadyToSendIndSizeof, CsrWifiRouterCtrlM4ReadyToSendIndSer, CsrWifiRouterCtrlM4ReadyToSendIndDes, CsrWifiRouterCtrlM4ReadyToSendIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_M4_TRANSMITTED_IND, CsrWifiRouterCtrlM4TransmittedIndSizeof, CsrWifiRouterCtrlM4TransmittedIndSer, CsrWifiRouterCtrlM4TransmittedIndDes, CsrWifiRouterCtrlM4TransmittedIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_MIC_FAILURE_IND, CsrWifiRouterCtrlMicFailureIndSizeof, CsrWifiRouterCtrlMicFailureIndSer, CsrWifiRouterCtrlMicFailureIndDes, CsrWifiRouterCtrlMicFailureIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_CONNECTED_IND, CsrWifiRouterCtrlConnectedIndSizeof, CsrWifiRouterCtrlConnectedIndSer, CsrWifiRouterCtrlConnectedIndDes, CsrWifiRouterCtrlConnectedIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_PEER_ADD_CFM, CsrWifiRouterCtrlPeerAddCfmSizeof, CsrWifiRouterCtrlPeerAddCfmSer, CsrWifiRouterCtrlPeerAddCfmDes, CsrWifiRouterCtrlPeerAddCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_PEER_DEL_CFM, CsrWifiRouterCtrlPeerDelCfmSizeof, CsrWifiRouterCtrlPeerDelCfmSer, CsrWifiRouterCtrlPeerDelCfmDes, CsrWifiRouterCtrlPeerDelCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_UNEXPECTED_FRAME_IND, CsrWifiRouterCtrlUnexpectedFrameIndSizeof, CsrWifiRouterCtrlUnexpectedFrameIndSer, CsrWifiRouterCtrlUnexpectedFrameIndDes, CsrWifiRouterCtrlUnexpectedFrameIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_CFM, CsrWifiRouterCtrlPeerUpdateCfmSizeof, CsrWifiRouterCtrlPeerUpdateCfmSer, CsrWifiRouterCtrlPeerUpdateCfmDes, CsrWifiRouterCtrlPeerUpdateCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_CAPABILITIES_CFM, CsrWifiRouterCtrlCapabilitiesCfmSizeof, CsrWifiRouterCtrlCapabilitiesCfmSer, CsrWifiRouterCtrlCapabilitiesCfmDes, CsrWifiRouterCtrlCapabilitiesCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_CFM, CsrWifiRouterCtrlBlockAckEnableCfmSizeof, CsrWifiRouterCtrlBlockAckEnableCfmSer, CsrWifiRouterCtrlBlockAckEnableCfmDes, CsrWifiRouterCtrlBlockAckEnableCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM, CsrWifiRouterCtrlBlockAckDisableCfmSizeof, CsrWifiRouterCtrlBlockAckDisableCfmSer, CsrWifiRouterCtrlBlockAckDisableCfmDes, CsrWifiRouterCtrlBlockAckDisableCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND, CsrWifiRouterCtrlBlockAckErrorIndSizeof, CsrWifiRouterCtrlBlockAckErrorIndSer, CsrWifiRouterCtrlBlockAckErrorIndDes, CsrWifiRouterCtrlBlockAckErrorIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND, CsrWifiRouterCtrlStaInactiveIndSizeof, CsrWifiRouterCtrlStaInactiveIndSer, CsrWifiRouterCtrlStaInactiveIndDes, CsrWifiRouterCtrlStaInactiveIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND, CsrWifiRouterCtrlWapiRxMicCheckIndSizeof, CsrWifiRouterCtrlWapiRxMicCheckIndSer, CsrWifiRouterCtrlWapiRxMicCheckIndDes, CsrWifiRouterCtrlWapiRxMicCheckIndSerFree },
-    { CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM, CsrWifiRouterCtrlModeSetCfmSizeof, CsrWifiRouterCtrlModeSetCfmSer, CsrWifiRouterCtrlModeSetCfmDes, CsrWifiRouterCtrlModeSetCfmSerFree },
-    { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer, CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree },
-
-    { 0, NULL, NULL, NULL, NULL },
-};
-
-CsrMsgConvMsgEntry* CsrWifiRouterCtrlConverterLookup(CsrMsgConvMsgEntry *ce, u16 msgType)
-{
-    if (msgType & CSR_PRIM_UPSTREAM)
-    {
-        u16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT;
-        if (idx < (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT) &&
-            csrwifirouterctrl_conv_lut[idx].msgType == msgType)
-        {
-            return &csrwifirouterctrl_conv_lut[idx];
-        }
-    }
-    else
-    {
-        if (msgType < CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT &&
-            csrwifirouterctrl_conv_lut[msgType].msgType == msgType)
-        {
-            return &csrwifirouterctrl_conv_lut[msgType];
-        }
-    }
-    return NULL;
-}
-
-
-void CsrWifiRouterCtrlConverterInit(void)
-{
-    CsrMsgConvInsert(CSR_WIFI_ROUTER_CTRL_PRIM, csrwifirouterctrl_conv_lut);
-    CsrMsgConvCustomLookupRegister(CSR_WIFI_ROUTER_CTRL_PRIM, CsrWifiRouterCtrlConverterLookup);
-}
-
-
-#ifdef CSR_LOG_ENABLE
-static const CsrLogPrimitiveInformation csrwifirouterctrl_conv_info = {
-    CSR_WIFI_ROUTER_CTRL_PRIM,
-    (char *)"CSR_WIFI_ROUTER_CTRL_PRIM",
-    csrwifirouterctrl_conv_lut
-};
-const CsrLogPrimitiveInformation* CsrWifiRouterCtrlTechInfoGet(void)
-{
-    return &csrwifirouterctrl_conv_info;
-}
-
-
-#endif /* CSR_LOG_ENABLE */
-#endif /* EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__
-#define CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__
-
-#ifndef EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE
-
-#include "csr_msgconv.h"
-
-#ifdef CSR_LOG_ENABLE
-#include "csr_log.h"
-
-extern const CsrLogPrimitiveInformation* CsrWifiRouterCtrlTechInfoGet(void);
-#endif /* CSR_LOG_ENABLE */
-
-extern void CsrWifiRouterCtrlConverterInit(void);
-
-#else /* EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE */
-
-#define CsrWifiRouterCtrlConverterInit()
-
-#endif /* EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE */
-
-#endif /* CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,108 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/slab.h>
-#include "csr_wifi_router_ctrl_prim.h"
-#include "csr_wifi_router_ctrl_lib.h"
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrWifiRouterCtrlFreeDownstreamMessageContents
- *
- *  DESCRIPTION
- *
- *
- *  PARAMETERS
- *      eventClass: only the value CSR_WIFI_ROUTER_CTRL_PRIM will be handled
- *      message:    the message to free
- *----------------------------------------------------------------------------*/
-void CsrWifiRouterCtrlFreeDownstreamMessageContents(u16 eventClass, void *message)
-{
-    if (eventClass != CSR_WIFI_ROUTER_CTRL_PRIM)
-    {
-        return;
-    }
-    if (NULL == message)
-    {
-        return;
-    }
-
-    switch (*((CsrWifiRouterCtrlPrim *) message))
-    {
-        case CSR_WIFI_ROUTER_CTRL_HIP_REQ:
-        {
-            CsrWifiRouterCtrlHipReq *p = (CsrWifiRouterCtrlHipReq *)message;
-            kfree(p->mlmeCommand);
-            p->mlmeCommand = NULL;
-            kfree(p->dataRef1);
-            p->dataRef1 = NULL;
-            kfree(p->dataRef2);
-            p->dataRef2 = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_RES:
-        {
-            CsrWifiRouterCtrlMulticastAddressRes *p = (CsrWifiRouterCtrlMulticastAddressRes *)message;
-            kfree(p->getAddresses);
-            p->getAddresses = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_REQ:
-        {
-            CsrWifiRouterCtrlTclasAddReq *p = (CsrWifiRouterCtrlTclasAddReq *)message;
-            kfree(p->tclas);
-            p->tclas = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_REQ:
-        {
-            CsrWifiRouterCtrlTclasDelReq *p = (CsrWifiRouterCtrlTclasDelReq *)message;
-            kfree(p->tclas);
-            p->tclas = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ:
-        {
-            CsrWifiRouterCtrlWifiOnReq *p = (CsrWifiRouterCtrlWifiOnReq *)message;
-            kfree(p->data);
-            p->data = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES:
-        {
-            CsrWifiRouterCtrlWifiOnRes *p = (CsrWifiRouterCtrlWifiOnRes *)message;
-            kfree(p->smeVersions.smeBuild);
-            p->smeVersions.smeBuild = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ:
-        {
-            CsrWifiRouterCtrlWapiRxPktReq *p = (CsrWifiRouterCtrlWapiRxPktReq *)message;
-            kfree(p->signal);
-            p->signal = NULL;
-            kfree(p->data);
-            p->data = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ:
-        {
-            CsrWifiRouterCtrlWapiUnicastTxPktReq *p = (CsrWifiRouterCtrlWapiUnicastTxPktReq *)message;
-            kfree(p->data);
-            p->data = NULL;
-            break;
-        }
-
-        default:
-            break;
-    }
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,87 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/slab.h>
-#include "csr_wifi_router_ctrl_prim.h"
-#include "csr_wifi_router_ctrl_lib.h"
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrWifiRouterCtrlFreeUpstreamMessageContents
- *
- *  DESCRIPTION
- *
- *
- *  PARAMETERS
- *      eventClass: only the value CSR_WIFI_ROUTER_CTRL_PRIM will be handled
- *      message:    the message to free
- *----------------------------------------------------------------------------*/
-void CsrWifiRouterCtrlFreeUpstreamMessageContents(u16 eventClass, void *message)
-{
-    if (eventClass != CSR_WIFI_ROUTER_CTRL_PRIM)
-    {
-        return;
-    }
-    if (NULL == message)
-    {
-        return;
-    }
-
-    switch (*((CsrWifiRouterCtrlPrim *) message))
-    {
-        case CSR_WIFI_ROUTER_CTRL_HIP_IND:
-        {
-            CsrWifiRouterCtrlHipInd *p = (CsrWifiRouterCtrlHipInd *)message;
-            kfree(p->mlmeCommand);
-            p->mlmeCommand = NULL;
-            kfree(p->dataRef1);
-            p->dataRef1 = NULL;
-            kfree(p->dataRef2);
-            p->dataRef2 = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND:
-        {
-            CsrWifiRouterCtrlMulticastAddressInd *p = (CsrWifiRouterCtrlMulticastAddressInd *)message;
-            kfree(p->setAddresses);
-            p->setAddresses = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_WIFI_ON_IND:
-        {
-            CsrWifiRouterCtrlWifiOnInd *p = (CsrWifiRouterCtrlWifiOnInd *)message;
-            kfree(p->versions.routerBuild);
-            p->versions.routerBuild = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND:
-        {
-            CsrWifiRouterCtrlWapiRxMicCheckInd *p = (CsrWifiRouterCtrlWapiRxMicCheckInd *)message;
-            kfree(p->signal);
-            p->signal = NULL;
-            kfree(p->data);
-            p->data = NULL;
-            break;
-        }
-        case CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND:
-        {
-            CsrWifiRouterCtrlWapiUnicastTxEncryptInd *p = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *)message;
-            kfree(p->data);
-            p->data = NULL;
-            break;
-        }
-
-        default:
-            break;
-    }
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_lib.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_lib.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_lib.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_lib.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,2082 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_ROUTER_CTRL_LIB_H__
-#define CSR_WIFI_ROUTER_CTRL_LIB_H__
-
-#include "csr_sched.h"
-#include "csr_macro.h"
-#include "csr_msg_transport.h"
-
-#include "csr_wifi_lib.h"
-
-#include "csr_wifi_router_ctrl_prim.h"
-#include "csr_wifi_router_task.h"
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiRouterCtrlFreeUpstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_ROUTER_CTRL upstream message. Does not
- *      free the message itself, and can only be used for upstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_ROUTER_CTRL upstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiRouterCtrlFreeUpstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiRouterCtrlFreeDownstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_ROUTER_CTRL downstream message. Does not
- *      free the message itself, and can only be used for downstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_ROUTER_CTRL downstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiRouterCtrlFreeDownstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- * Enum to string functions
- *----------------------------------------------------------------------------*/
-const char* CsrWifiRouterCtrlBlockAckRoleToString(CsrWifiRouterCtrlBlockAckRole value);
-const char* CsrWifiRouterCtrlControlIndicationToString(CsrWifiRouterCtrlControlIndication value);
-const char* CsrWifiRouterCtrlListActionToString(CsrWifiRouterCtrlListAction value);
-const char* CsrWifiRouterCtrlLowPowerModeToString(CsrWifiRouterCtrlLowPowerMode value);
-const char* CsrWifiRouterCtrlMediaStatusToString(CsrWifiRouterCtrlMediaStatus value);
-const char* CsrWifiRouterCtrlModeToString(CsrWifiRouterCtrlMode value);
-const char* CsrWifiRouterCtrlPeerStatusToString(CsrWifiRouterCtrlPeerStatus value);
-const char* CsrWifiRouterCtrlPortActionToString(CsrWifiRouterCtrlPortAction value);
-const char* CsrWifiRouterCtrlPowersaveTypeToString(CsrWifiRouterCtrlPowersaveType value);
-const char* CsrWifiRouterCtrlProtocolDirectionToString(CsrWifiRouterCtrlProtocolDirection value);
-const char* CsrWifiRouterCtrlQoSControlToString(CsrWifiRouterCtrlQoSControl value);
-const char* CsrWifiRouterCtrlQueueConfigToString(CsrWifiRouterCtrlQueueConfig value);
-const char* CsrWifiRouterCtrlTrafficConfigTypeToString(CsrWifiRouterCtrlTrafficConfigType value);
-const char* CsrWifiRouterCtrlTrafficPacketTypeToString(CsrWifiRouterCtrlTrafficPacketType value);
-const char* CsrWifiRouterCtrlTrafficTypeToString(CsrWifiRouterCtrlTrafficType value);
-
-
-/*----------------------------------------------------------------------------*
- * CsrPrim Type toString function.
- * Converts a message type to the String name of the Message
- *----------------------------------------------------------------------------*/
-const char* CsrWifiRouterCtrlPrimTypeToString(CsrPrim msgType);
-
-/*----------------------------------------------------------------------------*
- * Lookup arrays for PrimType name Strings
- *----------------------------------------------------------------------------*/
-extern const char *CsrWifiRouterCtrlUpstreamPrimNames[CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT];
-extern const char *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT];
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckDisableReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue           - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag    -
-    clientData      -
-    macAddress      -
-    trafficStreamID -
-    role            -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlBlockAckDisableReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckDisableReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->macAddress = (macAddress__); \
-    msg__->trafficStreamID = (trafficStreamID__); \
-    msg__->role = (role__);
-
-#define CsrWifiRouterCtrlBlockAckDisableReqSendTo(dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__) \
-    { \
-        CsrWifiRouterCtrlBlockAckDisableReq *msg__; \
-        CsrWifiRouterCtrlBlockAckDisableReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlBlockAckDisableReqSend(src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__) \
-    CsrWifiRouterCtrlBlockAckDisableReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckDisableCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlBlockAckDisableCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckDisableCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlBlockAckDisableCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \
-    { \
-        CsrWifiRouterCtrlBlockAckDisableCfm *msg__; \
-        CsrWifiRouterCtrlBlockAckDisableCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlBlockAckDisableCfmSend(dst__, clientData__, interfaceTag__, status__) \
-    CsrWifiRouterCtrlBlockAckDisableCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckEnableReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue           - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag    -
-    clientData      -
-    macAddress      -
-    trafficStreamID -
-    role            -
-    bufferSize      -
-    timeout         -
-    ssn             -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlBlockAckEnableReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckEnableReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->macAddress = (macAddress__); \
-    msg__->trafficStreamID = (trafficStreamID__); \
-    msg__->role = (role__); \
-    msg__->bufferSize = (bufferSize__); \
-    msg__->timeout = (timeout__); \
-    msg__->ssn = (ssn__);
-
-#define CsrWifiRouterCtrlBlockAckEnableReqSendTo(dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__) \
-    { \
-        CsrWifiRouterCtrlBlockAckEnableReq *msg__; \
-        CsrWifiRouterCtrlBlockAckEnableReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlBlockAckEnableReqSend(src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__) \
-    CsrWifiRouterCtrlBlockAckEnableReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, macAddress__, trafficStreamID__, role__, bufferSize__, timeout__, ssn__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckEnableCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlBlockAckEnableCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckEnableCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlBlockAckEnableCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \
-    { \
-        CsrWifiRouterCtrlBlockAckEnableCfm *msg__; \
-        CsrWifiRouterCtrlBlockAckEnableCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlBlockAckEnableCfmSend(dst__, clientData__, interfaceTag__, status__) \
-    CsrWifiRouterCtrlBlockAckEnableCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckErrorIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue           - Destination Task Queue
-    clientData      -
-    interfaceTag    -
-    trafficStreamID -
-    peerMacAddress  -
-    status          -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlBlockAckErrorIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckErrorInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->trafficStreamID = (trafficStreamID__); \
-    msg__->peerMacAddress = (peerMacAddress__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlBlockAckErrorIndSendTo(dst__, src__, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__) \
-    { \
-        CsrWifiRouterCtrlBlockAckErrorInd *msg__; \
-        CsrWifiRouterCtrlBlockAckErrorIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlBlockAckErrorIndSend(dst__, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__) \
-    CsrWifiRouterCtrlBlockAckErrorIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, trafficStreamID__, peerMacAddress__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlCapabilitiesReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Message Source Task Queue (Cfm's will be sent to this Queue)
-    clientData -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlCapabilitiesReqCreate(msg__, dst__, src__, clientData__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlCapabilitiesReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ, dst__, src__); \
-    msg__->clientData = (clientData__);
-
-#define CsrWifiRouterCtrlCapabilitiesReqSendTo(dst__, src__, clientData__) \
-    { \
-        CsrWifiRouterCtrlCapabilitiesReq *msg__; \
-        CsrWifiRouterCtrlCapabilitiesReqCreate(msg__, dst__, src__, clientData__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlCapabilitiesReqSend(src__, clientData__) \
-    CsrWifiRouterCtrlCapabilitiesReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlCapabilitiesCfmSend
-
-  DESCRIPTION
-    The router sends this primitive to confirm the size of the queues of the
-    HIP.
-
-  PARAMETERS
-    queue            - Destination Task Queue
-    clientData       -
-    commandQueueSize - Size of command queue
-    trafficQueueSize - Size of traffic queue (per AC)
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlCapabilitiesCfmCreate(msg__, dst__, src__, clientData__, commandQueueSize__, trafficQueueSize__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlCapabilitiesCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_CAPABILITIES_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->commandQueueSize = (commandQueueSize__); \
-    msg__->trafficQueueSize = (trafficQueueSize__);
-
-#define CsrWifiRouterCtrlCapabilitiesCfmSendTo(dst__, src__, clientData__, commandQueueSize__, trafficQueueSize__) \
-    { \
-        CsrWifiRouterCtrlCapabilitiesCfm *msg__; \
-        CsrWifiRouterCtrlCapabilitiesCfmCreate(msg__, dst__, src__, clientData__, commandQueueSize__, trafficQueueSize__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlCapabilitiesCfmSend(dst__, clientData__, commandQueueSize__, trafficQueueSize__) \
-    CsrWifiRouterCtrlCapabilitiesCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, commandQueueSize__, trafficQueueSize__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlConfigurePowerModeReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Message Source Task Queue (Cfm's will be sent to this Queue)
-    clientData -
-    mode       -
-    wakeHost   -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlConfigurePowerModeReqCreate(msg__, dst__, src__, clientData__, mode__, wakeHost__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlConfigurePowerModeReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_CONFIGURE_POWER_MODE_REQ, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->mode = (mode__); \
-    msg__->wakeHost = (wakeHost__);
-
-#define CsrWifiRouterCtrlConfigurePowerModeReqSendTo(dst__, src__, clientData__, mode__, wakeHost__) \
-    { \
-        CsrWifiRouterCtrlConfigurePowerModeReq *msg__; \
-        CsrWifiRouterCtrlConfigurePowerModeReqCreate(msg__, dst__, src__, clientData__, mode__, wakeHost__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlConfigurePowerModeReqSend(src__, clientData__, mode__, wakeHost__) \
-    CsrWifiRouterCtrlConfigurePowerModeReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, mode__, wakeHost__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlConnectedIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-    peerStatus     -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlConnectedIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerStatus__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlConnectedInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_CONNECTED_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->peerMacAddress = (peerMacAddress__); \
-    msg__->peerStatus = (peerStatus__);
-
-#define CsrWifiRouterCtrlConnectedIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerStatus__) \
-    { \
-        CsrWifiRouterCtrlConnectedInd *msg__; \
-        CsrWifiRouterCtrlConnectedIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerStatus__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlConnectedIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__, peerStatus__) \
-    CsrWifiRouterCtrlConnectedIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__, peerStatus__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlHipReqSend
-
-  DESCRIPTION
-    This primitive is used for transferring MLME messages to the HIP.
-
-  PARAMETERS
-    queue             - Message Source Task Queue (Cfm's will be sent to this Queue)
-    mlmeCommandLength - Length of the MLME signal
-    mlmeCommand       - Pointer to the MLME signal
-    dataRef1Length    - Length of the dataRef1 bulk data
-    dataRef1          - Pointer to the bulk data 1
-    dataRef2Length    - Length of the dataRef2 bulk data
-    dataRef2          - Pointer to the bulk data 2
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlHipReqCreate(msg__, dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlHipReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_HIP_REQ, dst__, src__); \
-    msg__->mlmeCommandLength = (mlmeCommandLength__); \
-    msg__->mlmeCommand = (mlmeCommand__); \
-    msg__->dataRef1Length = (dataRef1Length__); \
-    msg__->dataRef1 = (dataRef1__); \
-    msg__->dataRef2Length = (dataRef2Length__); \
-    msg__->dataRef2 = (dataRef2__);
-
-#define CsrWifiRouterCtrlHipReqSendTo(dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \
-    { \
-        CsrWifiRouterCtrlHipReq *msg__; \
-        CsrWifiRouterCtrlHipReqCreate(msg__, dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlHipReqSend(src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \
-    CsrWifiRouterCtrlHipReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlHipIndSend
-
-  DESCRIPTION
-    This primitive is used for transferring MLME messages from the HIP.
-
-  PARAMETERS
-    queue             - Destination Task Queue
-    mlmeCommandLength - Length of the MLME signal
-    mlmeCommand       - Pointer to the MLME signal
-    dataRef1Length    - Length of the dataRef1 bulk data
-    dataRef1          - Pointer to the bulk data 1
-    dataRef2Length    - Length of the dataRef2 bulk data
-    dataRef2          - Pointer to the bulk data 2
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlHipIndCreate(msg__, dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlHipInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_HIP_IND, dst__, src__); \
-    msg__->mlmeCommandLength = (mlmeCommandLength__); \
-    msg__->mlmeCommand = (mlmeCommand__); \
-    msg__->dataRef1Length = (dataRef1Length__); \
-    msg__->dataRef1 = (dataRef1__); \
-    msg__->dataRef2Length = (dataRef2Length__); \
-    msg__->dataRef2 = (dataRef2__);
-
-#define CsrWifiRouterCtrlHipIndSendTo(dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \
-    { \
-        CsrWifiRouterCtrlHipInd *msg__; \
-        CsrWifiRouterCtrlHipIndCreate(msg__, dst__, src__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlHipIndSend(dst__, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__) \
-    CsrWifiRouterCtrlHipIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, mlmeCommandLength__, mlmeCommand__, dataRef1Length__, dataRef1__, dataRef2Length__, dataRef2__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlM4ReadyToSendIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlM4ReadyToSendIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlM4ReadyToSendInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_M4_READY_TO_SEND_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->peerMacAddress = (peerMacAddress__);
-
-#define CsrWifiRouterCtrlM4ReadyToSendIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__) \
-    { \
-        CsrWifiRouterCtrlM4ReadyToSendInd *msg__; \
-        CsrWifiRouterCtrlM4ReadyToSendIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlM4ReadyToSendIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__) \
-    CsrWifiRouterCtrlM4ReadyToSendIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlM4TransmitReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    clientData   -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlM4TransmitReqCreate(msg__, dst__, src__, interfaceTag__, clientData__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlM4TransmitReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_M4_TRANSMIT_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__);
-
-#define CsrWifiRouterCtrlM4TransmitReqSendTo(dst__, src__, interfaceTag__, clientData__) \
-    { \
-        CsrWifiRouterCtrlM4TransmitReq *msg__; \
-        CsrWifiRouterCtrlM4TransmitReqCreate(msg__, dst__, src__, interfaceTag__, clientData__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlM4TransmitReqSend(src__, interfaceTag__, clientData__) \
-    CsrWifiRouterCtrlM4TransmitReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlM4TransmittedIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-    status         -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlM4TransmittedIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlM4TransmittedInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_M4_TRANSMITTED_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->peerMacAddress = (peerMacAddress__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlM4TransmittedIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__, status__) \
-    { \
-        CsrWifiRouterCtrlM4TransmittedInd *msg__; \
-        CsrWifiRouterCtrlM4TransmittedIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlM4TransmittedIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__, status__) \
-    CsrWifiRouterCtrlM4TransmittedIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMediaStatusReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    clientData   -
-    mediaStatus  -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlMediaStatusReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, mediaStatus__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlMediaStatusReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->mediaStatus = (mediaStatus__);
-
-#define CsrWifiRouterCtrlMediaStatusReqSendTo(dst__, src__, interfaceTag__, clientData__, mediaStatus__) \
-    { \
-        CsrWifiRouterCtrlMediaStatusReq *msg__; \
-        CsrWifiRouterCtrlMediaStatusReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, mediaStatus__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlMediaStatusReqSend(src__, interfaceTag__, clientData__, mediaStatus__) \
-    CsrWifiRouterCtrlMediaStatusReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, mediaStatus__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMicFailureIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-    unicastPdu     -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlMicFailureIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlMicFailureInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MIC_FAILURE_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->peerMacAddress = (peerMacAddress__); \
-    msg__->unicastPdu = (unicastPdu__);
-
-#define CsrWifiRouterCtrlMicFailureIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__) \
-    { \
-        CsrWifiRouterCtrlMicFailureInd *msg__; \
-        CsrWifiRouterCtrlMicFailureIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlMicFailureIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__) \
-    CsrWifiRouterCtrlMicFailureIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__, unicastPdu__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlModeSetReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue               - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag        -
-    clientData          -
-    mode                -
-    bssid               - BSSID of the network the device is going to be a part
-                          of
-    protection          - Set to TRUE if encryption is enabled for the
-                          connection/broadcast frames
-    intraBssDistEnabled - If set to TRUE, intra BSS destribution will be
-                          enabled. If set to FALSE, any unicast PDU which does
-                          not have the RA as the the local MAC address, shall be
-                          ignored. This field is interpreted by the receive if
-                          mode is set to CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlModeSetReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlModeSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MODE_SET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->mode = (mode__); \
-    msg__->bssid = (bssid__); \
-    msg__->protection = (protection__); \
-    msg__->intraBssDistEnabled = (intraBssDistEnabled__);
-
-#define CsrWifiRouterCtrlModeSetReqSendTo(dst__, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) \
-    { \
-        CsrWifiRouterCtrlModeSetReq *msg__; \
-        CsrWifiRouterCtrlModeSetReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlModeSetReqSend(src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) \
-    CsrWifiRouterCtrlModeSetReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlModeSetCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    mode         -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlModeSetCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, mode__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlModeSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->mode = (mode__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlModeSetCfmSendTo(dst__, src__, clientData__, interfaceTag__, mode__, status__) \
-    { \
-        CsrWifiRouterCtrlModeSetCfm *msg__; \
-        CsrWifiRouterCtrlModeSetCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, mode__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlModeSetCfmSend(dst__, clientData__, interfaceTag__, mode__, status__) \
-    CsrWifiRouterCtrlModeSetCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, mode__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMulticastAddressIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue             - Destination Task Queue
-    clientData        -
-    interfaceTag      -
-    action            -
-    setAddressesCount -
-    setAddresses      -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlMulticastAddressIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlMulticastAddressInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->action = (action__); \
-    msg__->setAddressesCount = (setAddressesCount__); \
-    msg__->setAddresses = (setAddresses__);
-
-#define CsrWifiRouterCtrlMulticastAddressIndSendTo(dst__, src__, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \
-    { \
-        CsrWifiRouterCtrlMulticastAddressInd *msg__; \
-        CsrWifiRouterCtrlMulticastAddressIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlMulticastAddressIndSend(dst__, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \
-    CsrWifiRouterCtrlMulticastAddressIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, action__, setAddressesCount__, setAddresses__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMulticastAddressResSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    interfaceTag      -
-    clientData        -
-    status            -
-    action            -
-    getAddressesCount -
-    getAddresses      -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlMulticastAddressResCreate(msg__, dst__, src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlMulticastAddressRes), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_RES, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->status = (status__); \
-    msg__->action = (action__); \
-    msg__->getAddressesCount = (getAddressesCount__); \
-    msg__->getAddresses = (getAddresses__);
-
-#define CsrWifiRouterCtrlMulticastAddressResSendTo(dst__, src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__) \
-    { \
-        CsrWifiRouterCtrlMulticastAddressRes *msg__; \
-        CsrWifiRouterCtrlMulticastAddressResCreate(msg__, dst__, src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlMulticastAddressResSend(src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__) \
-    CsrWifiRouterCtrlMulticastAddressResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, status__, action__, getAddressesCount__, getAddresses__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerAddReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue          - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag   -
-    clientData     -
-    peerMacAddress -
-    associationId  -
-    staInfo        -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlPeerAddReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlPeerAddReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_ADD_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->peerMacAddress = (peerMacAddress__); \
-    msg__->associationId = (associationId__); \
-    msg__->staInfo = (staInfo__);
-
-#define CsrWifiRouterCtrlPeerAddReqSendTo(dst__, src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__) \
-    { \
-        CsrWifiRouterCtrlPeerAddReq *msg__; \
-        CsrWifiRouterCtrlPeerAddReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlPeerAddReqSend(src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__) \
-    CsrWifiRouterCtrlPeerAddReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, peerMacAddress__, associationId__, staInfo__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerAddCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue            - Destination Task Queue
-    clientData       -
-    interfaceTag     -
-    peerMacAddress   -
-    peerRecordHandle -
-    status           -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlPeerAddCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlPeerAddCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_ADD_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->peerMacAddress = (peerMacAddress__); \
-    msg__->peerRecordHandle = (peerRecordHandle__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlPeerAddCfmSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__) \
-    { \
-        CsrWifiRouterCtrlPeerAddCfm *msg__; \
-        CsrWifiRouterCtrlPeerAddCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlPeerAddCfmSend(dst__, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__) \
-    CsrWifiRouterCtrlPeerAddCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__, peerRecordHandle__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerDelReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue            - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag     -
-    clientData       -
-    peerRecordHandle -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlPeerDelReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerRecordHandle__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlPeerDelReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_DEL_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->peerRecordHandle = (peerRecordHandle__);
-
-#define CsrWifiRouterCtrlPeerDelReqSendTo(dst__, src__, interfaceTag__, clientData__, peerRecordHandle__) \
-    { \
-        CsrWifiRouterCtrlPeerDelReq *msg__; \
-        CsrWifiRouterCtrlPeerDelReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerRecordHandle__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlPeerDelReqSend(src__, interfaceTag__, clientData__, peerRecordHandle__) \
-    CsrWifiRouterCtrlPeerDelReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, peerRecordHandle__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerDelCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlPeerDelCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlPeerDelCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_DEL_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlPeerDelCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \
-    { \
-        CsrWifiRouterCtrlPeerDelCfm *msg__; \
-        CsrWifiRouterCtrlPeerDelCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlPeerDelCfmSend(dst__, clientData__, interfaceTag__, status__) \
-    CsrWifiRouterCtrlPeerDelCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerUpdateReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue            - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag     -
-    clientData       -
-    peerRecordHandle -
-    powersaveMode    -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlPeerUpdateReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlPeerUpdateReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->peerRecordHandle = (peerRecordHandle__); \
-    msg__->powersaveMode = (powersaveMode__);
-
-#define CsrWifiRouterCtrlPeerUpdateReqSendTo(dst__, src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__) \
-    { \
-        CsrWifiRouterCtrlPeerUpdateReq *msg__; \
-        CsrWifiRouterCtrlPeerUpdateReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlPeerUpdateReqSend(src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__) \
-    CsrWifiRouterCtrlPeerUpdateReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, peerRecordHandle__, powersaveMode__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerUpdateCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlPeerUpdateCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlPeerUpdateCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlPeerUpdateCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \
-    { \
-        CsrWifiRouterCtrlPeerUpdateCfm *msg__; \
-        CsrWifiRouterCtrlPeerUpdateCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlPeerUpdateCfmSend(dst__, clientData__, interfaceTag__, status__) \
-    CsrWifiRouterCtrlPeerUpdateCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPortConfigureReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue                  - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag           -
-    clientData             -
-    uncontrolledPortAction -
-    controlledPortAction   -
-    macAddress             -
-    setProtection          -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlPortConfigureReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlPortConfigureReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->uncontrolledPortAction = (uncontrolledPortAction__); \
-    msg__->controlledPortAction = (controlledPortAction__); \
-    msg__->macAddress = (macAddress__); \
-    msg__->setProtection = (setProtection__);
-
-#define CsrWifiRouterCtrlPortConfigureReqSendTo(dst__, src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__) \
-    { \
-        CsrWifiRouterCtrlPortConfigureReq *msg__; \
-        CsrWifiRouterCtrlPortConfigureReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlPortConfigureReqSend(src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__) \
-    CsrWifiRouterCtrlPortConfigureReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, uncontrolledPortAction__, controlledPortAction__, macAddress__, setProtection__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPortConfigureCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    status       -
-    macAddress   -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlPortConfigureCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__, macAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlPortConfigureCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->macAddress = (macAddress__);
-
-#define CsrWifiRouterCtrlPortConfigureCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__, macAddress__) \
-    { \
-        CsrWifiRouterCtrlPortConfigureCfm *msg__; \
-        CsrWifiRouterCtrlPortConfigureCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__, macAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlPortConfigureCfmSend(dst__, clientData__, interfaceTag__, status__, macAddress__) \
-    CsrWifiRouterCtrlPortConfigureCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__, macAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlQosControlReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    clientData   -
-    control      -
-    queueConfig  -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlQosControlReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, control__, queueConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlQosControlReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->control = (control__); \
-    msg__->queueConfig = (queueConfig__);
-
-#define CsrWifiRouterCtrlQosControlReqSendTo(dst__, src__, interfaceTag__, clientData__, control__, queueConfig__) \
-    { \
-        CsrWifiRouterCtrlQosControlReq *msg__; \
-        CsrWifiRouterCtrlQosControlReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, control__, queueConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlQosControlReqSend(src__, interfaceTag__, clientData__, control__, queueConfig__) \
-    CsrWifiRouterCtrlQosControlReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, control__, queueConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlRawSdioDeinitialiseReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Message Source Task Queue (Cfm's will be sent to this Queue)
-    clientData -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlRawSdioDeinitialiseReqCreate(msg__, dst__, src__, clientData__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlRawSdioDeinitialiseReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_REQ, dst__, src__); \
-    msg__->clientData = (clientData__);
-
-#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSendTo(dst__, src__, clientData__) \
-    { \
-        CsrWifiRouterCtrlRawSdioDeinitialiseReq *msg__; \
-        CsrWifiRouterCtrlRawSdioDeinitialiseReqCreate(msg__, dst__, src__, clientData__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSend(src__, clientData__) \
-    CsrWifiRouterCtrlRawSdioDeinitialiseReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlRawSdioDeinitialiseCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Destination Task Queue
-    clientData -
-    result     -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlRawSdioDeinitialiseCfmCreate(msg__, dst__, src__, clientData__, result__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlRawSdioDeinitialiseCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->result = (result__);
-
-#define CsrWifiRouterCtrlRawSdioDeinitialiseCfmSendTo(dst__, src__, clientData__, result__) \
-    { \
-        CsrWifiRouterCtrlRawSdioDeinitialiseCfm *msg__; \
-        CsrWifiRouterCtrlRawSdioDeinitialiseCfmCreate(msg__, dst__, src__, clientData__, result__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlRawSdioDeinitialiseCfmSend(dst__, clientData__, result__) \
-    CsrWifiRouterCtrlRawSdioDeinitialiseCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, result__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlRawSdioInitialiseReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Message Source Task Queue (Cfm's will be sent to this Queue)
-    clientData -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlRawSdioInitialiseReqCreate(msg__, dst__, src__, clientData__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlRawSdioInitialiseReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_REQ, dst__, src__); \
-    msg__->clientData = (clientData__);
-
-#define CsrWifiRouterCtrlRawSdioInitialiseReqSendTo(dst__, src__, clientData__) \
-    { \
-        CsrWifiRouterCtrlRawSdioInitialiseReq *msg__; \
-        CsrWifiRouterCtrlRawSdioInitialiseReqCreate(msg__, dst__, src__, clientData__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlRawSdioInitialiseReqSend(src__, clientData__) \
-    CsrWifiRouterCtrlRawSdioInitialiseReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlRawSdioInitialiseCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue            - Destination Task Queue
-    clientData       -
-    result           -
-    byteRead         -
-    byteWrite        -
-    firmwareDownload -
-    reset            -
-    coreDumpPrepare  -
-    byteBlockRead    -
-    gpRead16         -
-    gpWrite16        -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlRawSdioInitialiseCfmCreate(msg__, dst__, src__, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlRawSdioInitialiseCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->result = (result__); \
-    msg__->byteRead = (byteRead__); \
-    msg__->byteWrite = (byteWrite__); \
-    msg__->firmwareDownload = (firmwareDownload__); \
-    msg__->reset = (reset__); \
-    msg__->coreDumpPrepare = (coreDumpPrepare__); \
-    msg__->byteBlockRead = (byteBlockRead__); \
-    msg__->gpRead16 = (gpRead16__); \
-    msg__->gpWrite16 = (gpWrite16__);
-
-#define CsrWifiRouterCtrlRawSdioInitialiseCfmSendTo(dst__, src__, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__) \
-    { \
-        CsrWifiRouterCtrlRawSdioInitialiseCfm *msg__; \
-        CsrWifiRouterCtrlRawSdioInitialiseCfmCreate(msg__, dst__, src__, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlRawSdioInitialiseCfmSend(dst__, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__) \
-    CsrWifiRouterCtrlRawSdioInitialiseCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, result__, byteRead__, byteWrite__, firmwareDownload__, reset__, coreDumpPrepare__, byteBlockRead__, gpRead16__, gpWrite16__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlResumeIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue           - Destination Task Queue
-    clientData      -
-    powerMaintained -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlResumeIndCreate(msg__, dst__, src__, clientData__, powerMaintained__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlResumeInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RESUME_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->powerMaintained = (powerMaintained__);
-
-#define CsrWifiRouterCtrlResumeIndSendTo(dst__, src__, clientData__, powerMaintained__) \
-    { \
-        CsrWifiRouterCtrlResumeInd *msg__; \
-        CsrWifiRouterCtrlResumeIndCreate(msg__, dst__, src__, clientData__, powerMaintained__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlResumeIndSend(dst__, clientData__, powerMaintained__) \
-    CsrWifiRouterCtrlResumeIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, powerMaintained__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlResumeResSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    clientData -
-    status     -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlResumeResCreate(msg__, dst__, src__, clientData__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlResumeRes), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_RESUME_RES, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlResumeResSendTo(dst__, src__, clientData__, status__) \
-    { \
-        CsrWifiRouterCtrlResumeRes *msg__; \
-        CsrWifiRouterCtrlResumeResCreate(msg__, dst__, src__, clientData__, status__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlResumeResSend(src__, clientData__, status__) \
-    CsrWifiRouterCtrlResumeResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlStaInactiveIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    staAddress   -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlStaInactiveIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, staAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlStaInactiveInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->staAddress = (staAddress__);
-
-#define CsrWifiRouterCtrlStaInactiveIndSendTo(dst__, src__, clientData__, interfaceTag__, staAddress__) \
-    { \
-        CsrWifiRouterCtrlStaInactiveInd *msg__; \
-        CsrWifiRouterCtrlStaInactiveIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, staAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlStaInactiveIndSend(dst__, clientData__, interfaceTag__, staAddress__) \
-    CsrWifiRouterCtrlStaInactiveIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, staAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlSuspendIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue       - Destination Task Queue
-    clientData  -
-    hardSuspend -
-    d3Suspend   -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlSuspendIndCreate(msg__, dst__, src__, clientData__, hardSuspend__, d3Suspend__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlSuspendInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_SUSPEND_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->hardSuspend = (hardSuspend__); \
-    msg__->d3Suspend = (d3Suspend__);
-
-#define CsrWifiRouterCtrlSuspendIndSendTo(dst__, src__, clientData__, hardSuspend__, d3Suspend__) \
-    { \
-        CsrWifiRouterCtrlSuspendInd *msg__; \
-        CsrWifiRouterCtrlSuspendIndCreate(msg__, dst__, src__, clientData__, hardSuspend__, d3Suspend__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlSuspendIndSend(dst__, clientData__, hardSuspend__, d3Suspend__) \
-    CsrWifiRouterCtrlSuspendIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, hardSuspend__, d3Suspend__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlSuspendResSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    clientData -
-    status     -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlSuspendResCreate(msg__, dst__, src__, clientData__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlSuspendRes), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_SUSPEND_RES, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlSuspendResSendTo(dst__, src__, clientData__, status__) \
-    { \
-        CsrWifiRouterCtrlSuspendRes *msg__; \
-        CsrWifiRouterCtrlSuspendResCreate(msg__, dst__, src__, clientData__, status__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlSuspendResSend(src__, clientData__, status__) \
-    CsrWifiRouterCtrlSuspendResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTclasAddReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    clientData   -
-    tclasLength  -
-    tclas        -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlTclasAddReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlTclasAddReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->tclasLength = (tclasLength__); \
-    msg__->tclas = (tclas__);
-
-#define CsrWifiRouterCtrlTclasAddReqSendTo(dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__) \
-    { \
-        CsrWifiRouterCtrlTclasAddReq *msg__; \
-        CsrWifiRouterCtrlTclasAddReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlTclasAddReqSend(src__, interfaceTag__, clientData__, tclasLength__, tclas__) \
-    CsrWifiRouterCtrlTclasAddReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, tclasLength__, tclas__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTclasAddCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlTclasAddCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlTclasAddCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlTclasAddCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \
-    { \
-        CsrWifiRouterCtrlTclasAddCfm *msg__; \
-        CsrWifiRouterCtrlTclasAddCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlTclasAddCfmSend(dst__, clientData__, interfaceTag__, status__) \
-    CsrWifiRouterCtrlTclasAddCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTclasDelReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    clientData   -
-    tclasLength  -
-    tclas        -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlTclasDelReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlTclasDelReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->tclasLength = (tclasLength__); \
-    msg__->tclas = (tclas__);
-
-#define CsrWifiRouterCtrlTclasDelReqSendTo(dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__) \
-    { \
-        CsrWifiRouterCtrlTclasDelReq *msg__; \
-        CsrWifiRouterCtrlTclasDelReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, tclasLength__, tclas__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlTclasDelReqSend(src__, interfaceTag__, clientData__, tclasLength__, tclas__) \
-    CsrWifiRouterCtrlTclasDelReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, tclasLength__, tclas__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTclasDelCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlTclasDelCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlTclasDelCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlTclasDelCfmSendTo(dst__, src__, clientData__, interfaceTag__, status__) \
-    { \
-        CsrWifiRouterCtrlTclasDelCfm *msg__; \
-        CsrWifiRouterCtrlTclasDelCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlTclasDelCfmSend(dst__, clientData__, interfaceTag__, status__) \
-    CsrWifiRouterCtrlTclasDelCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficClassificationReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    clientData   -
-    trafficType  -
-    period       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlTrafficClassificationReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, trafficType__, period__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlTrafficClassificationReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TRAFFIC_CLASSIFICATION_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->trafficType = (trafficType__); \
-    msg__->period = (period__);
-
-#define CsrWifiRouterCtrlTrafficClassificationReqSendTo(dst__, src__, interfaceTag__, clientData__, trafficType__, period__) \
-    { \
-        CsrWifiRouterCtrlTrafficClassificationReq *msg__; \
-        CsrWifiRouterCtrlTrafficClassificationReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, trafficType__, period__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlTrafficClassificationReqSend(src__, interfaceTag__, clientData__, trafficType__, period__) \
-    CsrWifiRouterCtrlTrafficClassificationReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, trafficType__, period__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficConfigReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue             - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag      -
-    clientData        -
-    trafficConfigType -
-    config            -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlTrafficConfigReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, trafficConfigType__, config__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlTrafficConfigReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->clientData = (clientData__); \
-    msg__->trafficConfigType = (trafficConfigType__); \
-    msg__->config = (config__);
-
-#define CsrWifiRouterCtrlTrafficConfigReqSendTo(dst__, src__, interfaceTag__, clientData__, trafficConfigType__, config__) \
-    { \
-        CsrWifiRouterCtrlTrafficConfigReq *msg__; \
-        CsrWifiRouterCtrlTrafficConfigReqCreate(msg__, dst__, src__, interfaceTag__, clientData__, trafficConfigType__, config__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlTrafficConfigReqSend(src__, interfaceTag__, clientData__, trafficConfigType__, config__) \
-    CsrWifiRouterCtrlTrafficConfigReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, trafficConfigType__, config__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficProtocolIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    packetType   -
-    direction    -
-    srcAddress   -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlTrafficProtocolIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, packetType__, direction__, srcAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlTrafficProtocolInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PROTOCOL_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->packetType = (packetType__); \
-    msg__->direction = (direction__); \
-    msg__->srcAddress = (srcAddress__);
-
-#define CsrWifiRouterCtrlTrafficProtocolIndSendTo(dst__, src__, clientData__, interfaceTag__, packetType__, direction__, srcAddress__) \
-    { \
-        CsrWifiRouterCtrlTrafficProtocolInd *msg__; \
-        CsrWifiRouterCtrlTrafficProtocolIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, packetType__, direction__, srcAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlTrafficProtocolIndSend(dst__, clientData__, interfaceTag__, packetType__, direction__, srcAddress__) \
-    CsrWifiRouterCtrlTrafficProtocolIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, packetType__, direction__, srcAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficSampleIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    stats        -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlTrafficSampleIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, stats__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlTrafficSampleInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_TRAFFIC_SAMPLE_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->stats = (stats__);
-
-#define CsrWifiRouterCtrlTrafficSampleIndSendTo(dst__, src__, clientData__, interfaceTag__, stats__) \
-    { \
-        CsrWifiRouterCtrlTrafficSampleInd *msg__; \
-        CsrWifiRouterCtrlTrafficSampleIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, stats__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlTrafficSampleIndSend(dst__, clientData__, interfaceTag__, stats__) \
-    CsrWifiRouterCtrlTrafficSampleIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, stats__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlUnexpectedFrameIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlUnexpectedFrameIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlUnexpectedFrameInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_UNEXPECTED_FRAME_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->peerMacAddress = (peerMacAddress__);
-
-#define CsrWifiRouterCtrlUnexpectedFrameIndSendTo(dst__, src__, clientData__, interfaceTag__, peerMacAddress__) \
-    { \
-        CsrWifiRouterCtrlUnexpectedFrameInd *msg__; \
-        CsrWifiRouterCtrlUnexpectedFrameIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, peerMacAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlUnexpectedFrameIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__) \
-    CsrWifiRouterCtrlUnexpectedFrameIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiFilterReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue           - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag    -
-    isWapiConnected -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWapiFilterReqCreate(msg__, dst__, src__, interfaceTag__, isWapiConnected__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWapiFilterReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->isWapiConnected = (isWapiConnected__);
-
-#define CsrWifiRouterCtrlWapiFilterReqSendTo(dst__, src__, interfaceTag__, isWapiConnected__) \
-    { \
-        CsrWifiRouterCtrlWapiFilterReq *msg__; \
-        CsrWifiRouterCtrlWapiFilterReqCreate(msg__, dst__, src__, interfaceTag__, isWapiConnected__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWapiFilterReqSend(src__, interfaceTag__, isWapiConnected__) \
-    CsrWifiRouterCtrlWapiFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, isWapiConnected__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiMulticastFilterReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWapiMulticastFilterReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiRouterCtrlWapiMulticastFilterReq *msg__; \
-        CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWapiMulticastFilterReqSend(src__, interfaceTag__, status__) \
-    CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiRxMicCheckIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    signalLength -
-    signal       -
-    dataLength   -
-    data         -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWapiRxMicCheckIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWapiRxMicCheckInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->signalLength = (signalLength__); \
-    msg__->signal = (signal__); \
-    msg__->dataLength = (dataLength__); \
-    msg__->data = (data__);
-
-#define CsrWifiRouterCtrlWapiRxMicCheckIndSendTo(dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
-    { \
-        CsrWifiRouterCtrlWapiRxMicCheckInd *msg__; \
-        CsrWifiRouterCtrlWapiRxMicCheckIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWapiRxMicCheckIndSend(dst__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
-    CsrWifiRouterCtrlWapiRxMicCheckIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiRxPktReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    signalLength -
-    signal       -
-    dataLength   -
-    data         -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWapiRxPktReqCreate(msg__, dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWapiRxPktReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->signalLength = (signalLength__); \
-    msg__->signal = (signal__); \
-    msg__->dataLength = (dataLength__); \
-    msg__->data = (data__);
-
-#define CsrWifiRouterCtrlWapiRxPktReqSendTo(dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
-    { \
-        CsrWifiRouterCtrlWapiRxPktReq *msg__; \
-        CsrWifiRouterCtrlWapiRxPktReqCreate(msg__, dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWapiRxPktReqSend(src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
-    CsrWifiRouterCtrlWapiRxPktReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiUnicastFilterReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWapiUnicastFilterReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiRouterCtrlWapiUnicastFilterReq *msg__; \
-        CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWapiUnicastFilterReqSend(src__, interfaceTag__, status__) \
-    CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    clientData   -
-    interfaceTag -
-    dataLength   -
-    data         -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, dataLength__, data__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxEncryptInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->dataLength = (dataLength__); \
-    msg__->data = (data__);
-
-#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndSendTo(dst__, src__, clientData__, interfaceTag__, dataLength__, data__) \
-    { \
-        CsrWifiRouterCtrlWapiUnicastTxEncryptInd *msg__; \
-        CsrWifiRouterCtrlWapiUnicastTxEncryptIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, dataLength__, data__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(dst__, clientData__, interfaceTag__, dataLength__, data__) \
-    CsrWifiRouterCtrlWapiUnicastTxEncryptIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, dataLength__, data__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiUnicastTxPktReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    dataLength   -
-    data         -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWapiUnicastTxPktReqCreate(msg__, dst__, src__, interfaceTag__, dataLength__, data__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxPktReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->dataLength = (dataLength__); \
-    msg__->data = (data__);
-
-#define CsrWifiRouterCtrlWapiUnicastTxPktReqSendTo(dst__, src__, interfaceTag__, dataLength__, data__) \
-    { \
-        CsrWifiRouterCtrlWapiUnicastTxPktReq *msg__; \
-        CsrWifiRouterCtrlWapiUnicastTxPktReqCreate(msg__, dst__, src__, interfaceTag__, dataLength__, data__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWapiUnicastTxPktReqSend(src__, interfaceTag__, dataLength__, data__) \
-    CsrWifiRouterCtrlWapiUnicastTxPktReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, dataLength__, data__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOffReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Message Source Task Queue (Cfm's will be sent to this Queue)
-    clientData -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWifiOffReqCreate(msg__, dst__, src__, clientData__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWifiOffReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_OFF_REQ, dst__, src__); \
-    msg__->clientData = (clientData__);
-
-#define CsrWifiRouterCtrlWifiOffReqSendTo(dst__, src__, clientData__) \
-    { \
-        CsrWifiRouterCtrlWifiOffReq *msg__; \
-        CsrWifiRouterCtrlWifiOffReqCreate(msg__, dst__, src__, clientData__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWifiOffReqSend(src__, clientData__) \
-    CsrWifiRouterCtrlWifiOffReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOffIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue             - Destination Task Queue
-    clientData        -
-    controlIndication -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWifiOffIndCreate(msg__, dst__, src__, clientData__, controlIndication__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWifiOffInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_OFF_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->controlIndication = (controlIndication__);
-
-#define CsrWifiRouterCtrlWifiOffIndSendTo(dst__, src__, clientData__, controlIndication__) \
-    { \
-        CsrWifiRouterCtrlWifiOffInd *msg__; \
-        CsrWifiRouterCtrlWifiOffIndCreate(msg__, dst__, src__, clientData__, controlIndication__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWifiOffIndSend(dst__, clientData__, controlIndication__) \
-    CsrWifiRouterCtrlWifiOffIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, controlIndication__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOffResSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    clientData -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWifiOffResCreate(msg__, dst__, src__, clientData__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWifiOffRes), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_OFF_RES, dst__, src__); \
-    msg__->clientData = (clientData__);
-
-#define CsrWifiRouterCtrlWifiOffResSendTo(dst__, src__, clientData__) \
-    { \
-        CsrWifiRouterCtrlWifiOffRes *msg__; \
-        CsrWifiRouterCtrlWifiOffResCreate(msg__, dst__, src__, clientData__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWifiOffResSend(src__, clientData__) \
-    CsrWifiRouterCtrlWifiOffResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOffCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Destination Task Queue
-    clientData -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWifiOffCfmCreate(msg__, dst__, src__, clientData__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWifiOffCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_OFF_CFM, dst__, src__); \
-    msg__->clientData = (clientData__);
-
-#define CsrWifiRouterCtrlWifiOffCfmSendTo(dst__, src__, clientData__) \
-    { \
-        CsrWifiRouterCtrlWifiOffCfm *msg__; \
-        CsrWifiRouterCtrlWifiOffCfmCreate(msg__, dst__, src__, clientData__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWifiOffCfmSend(dst__, clientData__) \
-    CsrWifiRouterCtrlWifiOffCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOnReqSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Message Source Task Queue (Cfm's will be sent to this Queue)
-    clientData -
-    dataLength - Number of bytes in the buffer pointed to by 'data'
-    data       - Pointer to the buffer containing 'dataLength' bytes
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__, dataLength__, data__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWifiOnReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->dataLength = (dataLength__); \
-    msg__->data = (data__);
-
-#define CsrWifiRouterCtrlWifiOnReqSendTo(dst__, src__, clientData__, dataLength__, data__) \
-    { \
-        CsrWifiRouterCtrlWifiOnReq *msg__; \
-        CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__, dataLength__, data__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWifiOnReqSend(src__, clientData__, dataLength__, data__) \
-    CsrWifiRouterCtrlWifiOnReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, dataLength__, data__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOnIndSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Destination Task Queue
-    clientData -
-    status     -
-    versions   -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWifiOnIndCreate(msg__, dst__, src__, clientData__, status__, versions__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWifiOnInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_IND, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->status = (status__); \
-    msg__->versions = (versions__);
-
-#define CsrWifiRouterCtrlWifiOnIndSendTo(dst__, src__, clientData__, status__, versions__) \
-    { \
-        CsrWifiRouterCtrlWifiOnInd *msg__; \
-        CsrWifiRouterCtrlWifiOnIndCreate(msg__, dst__, src__, clientData__, status__, versions__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWifiOnIndSend(dst__, clientData__, status__, versions__) \
-    CsrWifiRouterCtrlWifiOnIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, status__, versions__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOnResSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    clientData          -
-    status              -
-    numInterfaceAddress -
-    stationMacAddress   - array size 1 MUST match CSR_WIFI_NUM_INTERFACES
-    smeVersions         -
-    scheduledInterrupt  -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWifiOnResCreate(msg__, dst__, src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWifiOnRes), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->status = (status__); \
-    msg__->numInterfaceAddress = (numInterfaceAddress__); \
-    memcpy(msg__->stationMacAddress, (stationMacAddress__), sizeof(CsrWifiMacAddress) * 2); \
-    msg__->smeVersions = (smeVersions__); \
-    msg__->scheduledInterrupt = (scheduledInterrupt__);
-
-#define CsrWifiRouterCtrlWifiOnResSendTo(dst__, src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__) \
-    { \
-        CsrWifiRouterCtrlWifiOnRes *msg__; \
-        CsrWifiRouterCtrlWifiOnResCreate(msg__, dst__, src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWifiOnResSend(src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__) \
-    CsrWifiRouterCtrlWifiOnResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, status__, numInterfaceAddress__, stationMacAddress__, smeVersions__, scheduledInterrupt__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOnCfmSend
-
-  DESCRIPTION
-
-  PARAMETERS
-    queue      - Destination Task Queue
-    clientData -
-    status     -
-
-*******************************************************************************/
-#define CsrWifiRouterCtrlWifiOnCfmCreate(msg__, dst__, src__, clientData__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterCtrlWifiOnCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_CFM, dst__, src__); \
-    msg__->clientData = (clientData__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterCtrlWifiOnCfmSendTo(dst__, src__, clientData__, status__) \
-    { \
-        CsrWifiRouterCtrlWifiOnCfm *msg__; \
-        CsrWifiRouterCtrlWifiOnCfmCreate(msg__, dst__, src__, clientData__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterCtrlWifiOnCfmSend(dst__, clientData__, status__) \
-    CsrWifiRouterCtrlWifiOnCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, status__)
-
-#endif /* CSR_WIFI_ROUTER_CTRL_LIB_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_prim.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_prim.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_prim.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_prim.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,2113 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_ROUTER_CTRL_PRIM_H__
-#define CSR_WIFI_ROUTER_CTRL_PRIM_H__
-
-#include <linux/types.h>
-#include "csr_prim_defs.h"
-#include "csr_sched.h"
-#include "csr_wifi_common.h"
-#include "csr_result.h"
-#include "csr_wifi_fsm_event.h"
-
-#define CSR_WIFI_ROUTER_CTRL_PRIM                                       (0x0401)
-
-typedef CsrPrim CsrWifiRouterCtrlPrim;
-
-typedef CsrResult (*CsrWifiRouterCtrlRawSdioByteWrite)(u8 func, u32 address, u8 data);
-typedef CsrResult (*CsrWifiRouterCtrlRawSdioByteRead)(u8 func, u32 address, u8 *pdata);
-typedef CsrResult (*CsrWifiRouterCtrlRawSdioFirmwareDownload)(u32 length, const u8 *pdata);
-typedef CsrResult (*CsrWifiRouterCtrlRawSdioReset)(void);
-typedef CsrResult (*CsrWifiRouterCtrlRawSdioCoreDumpPrepare)(u8 suspendSme);
-typedef CsrResult (*CsrWifiRouterCtrlRawSdioByteBlockRead)(u8 func, u32 address, u8 *pdata, u32 length);
-typedef CsrResult (*CsrWifiRouterCtrlRawSdioGpRead16)(u8 func, u32 address, u16 *pdata);
-typedef CsrResult (*CsrWifiRouterCtrlRawSdioGpWrite16)(u8 func, u32 address, u16 data);
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckRole
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR
-                   -
-    CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT
-                   -
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlBlockAckRole;
-#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR   ((CsrWifiRouterCtrlBlockAckRole) 0x00)
-#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT    ((CsrWifiRouterCtrlBlockAckRole) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlControlIndication
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_ERROR
-                   -
-    CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_EXIT
-                   -
-    CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_USER_REQUESTED
-                   -
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlControlIndication;
-#define CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_ERROR            ((CsrWifiRouterCtrlControlIndication) 0x01)
-#define CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_EXIT             ((CsrWifiRouterCtrlControlIndication) 0x02)
-#define CSR_WIFI_ROUTER_CTRL_CONTROL_INDICATION_USER_REQUESTED   ((CsrWifiRouterCtrlControlIndication) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlListAction
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_LIST_ACTION_GET
-                   -
-    CSR_WIFI_ROUTER_CTRL_LIST_ACTION_ADD
-                   -
-    CSR_WIFI_ROUTER_CTRL_LIST_ACTION_REMOVE
-                   -
-    CSR_WIFI_ROUTER_CTRL_LIST_ACTION_FLUSH
-                   -
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlListAction;
-#define CSR_WIFI_ROUTER_CTRL_LIST_ACTION_GET      ((CsrWifiRouterCtrlListAction) 0x00)
-#define CSR_WIFI_ROUTER_CTRL_LIST_ACTION_ADD      ((CsrWifiRouterCtrlListAction) 0x01)
-#define CSR_WIFI_ROUTER_CTRL_LIST_ACTION_REMOVE   ((CsrWifiRouterCtrlListAction) 0x02)
-#define CSR_WIFI_ROUTER_CTRL_LIST_ACTION_FLUSH    ((CsrWifiRouterCtrlListAction) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlLowPowerMode
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED
-                   -
-    CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_ENABLED
-                   -
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterCtrlLowPowerMode;
-#define CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED   ((CsrWifiRouterCtrlLowPowerMode) 0x0000)
-#define CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_ENABLED    ((CsrWifiRouterCtrlLowPowerMode) 0x0001)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMediaStatus
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_CONNECTED
-                   -
-    CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_DISCONNECTED
-                   -
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlMediaStatus;
-#define CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_CONNECTED      ((CsrWifiRouterCtrlMediaStatus) 0x00)
-#define CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_DISCONNECTED   ((CsrWifiRouterCtrlMediaStatus) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMode
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_MODE_NONE    -
-    CSR_WIFI_ROUTER_CTRL_MODE_IBSS    -
-    CSR_WIFI_ROUTER_CTRL_MODE_STA     -
-    CSR_WIFI_ROUTER_CTRL_MODE_AP      -
-    CSR_WIFI_ROUTER_CTRL_MODE_MONITOR -
-    CSR_WIFI_ROUTER_CTRL_MODE_AMP     -
-    CSR_WIFI_ROUTER_CTRL_MODE_P2P     -
-    CSR_WIFI_ROUTER_CTRL_MODE_P2PGO   -
-    CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI  -
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlMode;
-#define CSR_WIFI_ROUTER_CTRL_MODE_NONE      ((CsrWifiRouterCtrlMode) 0x00)
-#define CSR_WIFI_ROUTER_CTRL_MODE_IBSS      ((CsrWifiRouterCtrlMode) 0x01)
-#define CSR_WIFI_ROUTER_CTRL_MODE_STA       ((CsrWifiRouterCtrlMode) 0x02)
-#define CSR_WIFI_ROUTER_CTRL_MODE_AP        ((CsrWifiRouterCtrlMode) 0x03)
-#define CSR_WIFI_ROUTER_CTRL_MODE_MONITOR   ((CsrWifiRouterCtrlMode) 0x04)
-#define CSR_WIFI_ROUTER_CTRL_MODE_AMP       ((CsrWifiRouterCtrlMode) 0x05)
-#define CSR_WIFI_ROUTER_CTRL_MODE_P2P       ((CsrWifiRouterCtrlMode) 0x06)
-#define CSR_WIFI_ROUTER_CTRL_MODE_P2PGO     ((CsrWifiRouterCtrlMode) 0x07)
-#define CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI    ((CsrWifiRouterCtrlMode) 0x08)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerStatus
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE
-                   -
-    CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE
-                   -
-    CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED
-                   -
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlPeerStatus;
-#define CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE       ((CsrWifiRouterCtrlPeerStatus) 0x00)
-#define CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE   ((CsrWifiRouterCtrlPeerStatus) 0x01)
-#define CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED           ((CsrWifiRouterCtrlPeerStatus) 0x02)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPortAction
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN
-                   -
-    CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD
-                   -
-    CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK
-                   -
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterCtrlPortAction;
-#define CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN             ((CsrWifiRouterCtrlPortAction) 0x0000)
-#define CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD   ((CsrWifiRouterCtrlPortAction) 0x0001)
-#define CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK     ((CsrWifiRouterCtrlPortAction) 0x0002)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPowersaveType
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_AC_BK_PS_INFO_PRESENT
-                   - If set, AC BK PS info is present in b4 and b5
-    CSR_WIFI_ROUTER_CTRL_AC_BE_PS_INFO_PRESENT
-                   - If set, AC BE PS info is present in b6 and b7
-    CSR_WIFI_ROUTER_CTRL_AC_VI_PS_INFO_PRESENT
-                   - If set, AC VI PS info is present in b8 and b9
-    CSR_WIFI_ROUTER_CTRL_AC_VO_PS_INFO_PRESENT
-                   - If set, AC VO PS info is present in b10 and b11
-    CSR_WIFI_ROUTER_CTRL_AC_BK_TRIGGER_ENABLED
-                   -
-    CSR_WIFI_ROUTER_CTRL_AC_BK_DELIVERY_ENABLED
-                   -
-    CSR_WIFI_ROUTER_CTRL_AC_BE_TRIGGER_ENABLED
-                   -
-    CSR_WIFI_ROUTER_CTRL_AC_BE_DELIVERY_ENABLED
-                   -
-    CSR_WIFI_ROUTER_CTRL_AC_VI_TRIGGER_ENABLED
-                   -
-    CSR_WIFI_ROUTER_CTRL_AC_VI_DELIVERY_ENABLED
-                   -
-    CSR_WIFI_ROUTER_CTRL_AC_VO_TRIGGER_ENABLED
-                   -
-    CSR_WIFI_ROUTER_CTRL_AC_VO_DELIVERY_ENABLED
-                   -
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterCtrlPowersaveType;
-#define CSR_WIFI_ROUTER_CTRL_AC_BK_PS_INFO_PRESENT    ((CsrWifiRouterCtrlPowersaveType) 0x0001)
-#define CSR_WIFI_ROUTER_CTRL_AC_BE_PS_INFO_PRESENT    ((CsrWifiRouterCtrlPowersaveType) 0x0002)
-#define CSR_WIFI_ROUTER_CTRL_AC_VI_PS_INFO_PRESENT    ((CsrWifiRouterCtrlPowersaveType) 0x0004)
-#define CSR_WIFI_ROUTER_CTRL_AC_VO_PS_INFO_PRESENT    ((CsrWifiRouterCtrlPowersaveType) 0x0008)
-#define CSR_WIFI_ROUTER_CTRL_AC_BK_TRIGGER_ENABLED    ((CsrWifiRouterCtrlPowersaveType) 0x0010)
-#define CSR_WIFI_ROUTER_CTRL_AC_BK_DELIVERY_ENABLED   ((CsrWifiRouterCtrlPowersaveType) 0x0020)
-#define CSR_WIFI_ROUTER_CTRL_AC_BE_TRIGGER_ENABLED    ((CsrWifiRouterCtrlPowersaveType) 0x0040)
-#define CSR_WIFI_ROUTER_CTRL_AC_BE_DELIVERY_ENABLED   ((CsrWifiRouterCtrlPowersaveType) 0x0080)
-#define CSR_WIFI_ROUTER_CTRL_AC_VI_TRIGGER_ENABLED    ((CsrWifiRouterCtrlPowersaveType) 0x0100)
-#define CSR_WIFI_ROUTER_CTRL_AC_VI_DELIVERY_ENABLED   ((CsrWifiRouterCtrlPowersaveType) 0x0200)
-#define CSR_WIFI_ROUTER_CTRL_AC_VO_TRIGGER_ENABLED    ((CsrWifiRouterCtrlPowersaveType) 0x0400)
-#define CSR_WIFI_ROUTER_CTRL_AC_VO_DELIVERY_ENABLED   ((CsrWifiRouterCtrlPowersaveType) 0x0800)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlProtocolDirection
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX
-                   -
-    CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX
-                   -
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterCtrlProtocolDirection;
-#define CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX   ((CsrWifiRouterCtrlProtocolDirection) 0x0000)
-#define CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX   ((CsrWifiRouterCtrlProtocolDirection) 0x0001)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlQoSControl
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_OFF
-                   -
-    CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON
-                   -
-    CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_80211_ON
-                   -
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterCtrlQoSControl;
-#define CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_OFF        ((CsrWifiRouterCtrlQoSControl) 0x0000)
-#define CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON     ((CsrWifiRouterCtrlQoSControl) 0x0001)
-#define CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_80211_ON   ((CsrWifiRouterCtrlQoSControl) 0x0002)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlQueueConfig
-
-  DESCRIPTION
-    Defines which Queues are enabled for use.
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE
-                   -
-    CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE
-                   -
-    CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE
-                   -
-    CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE
-                   -
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlQueueConfig;
-#define CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE   ((CsrWifiRouterCtrlQueueConfig) 0x01)
-#define CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE   ((CsrWifiRouterCtrlQueueConfig) 0x02)
-#define CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE   ((CsrWifiRouterCtrlQueueConfig) 0x04)
-#define CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE   ((CsrWifiRouterCtrlQueueConfig) 0x08)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficConfigType
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_CLS
-                   -
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterCtrlTrafficConfigType;
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_RESET    ((CsrWifiRouterCtrlTrafficConfigType) 0x0000)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER   ((CsrWifiRouterCtrlTrafficConfigType) 0x0001)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_CLS      ((CsrWifiRouterCtrlTrafficConfigType) 0x0002)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficPacketType
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP_ACK
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ALL
-                   -
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterCtrlTrafficPacketType;
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_NONE       ((CsrWifiRouterCtrlTrafficPacketType) 0x0000)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL      ((CsrWifiRouterCtrlTrafficPacketType) 0x0001)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP       ((CsrWifiRouterCtrlTrafficPacketType) 0x0002)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_DHCP_ACK   ((CsrWifiRouterCtrlTrafficPacketType) 0x0004)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP        ((CsrWifiRouterCtrlTrafficPacketType) 0x0008)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET    ((CsrWifiRouterCtrlTrafficPacketType) 0x0010)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM     ((CsrWifiRouterCtrlTrafficPacketType) 0x0020)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ALL        ((CsrWifiRouterCtrlTrafficPacketType) 0x00FF)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficType
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_OCCASIONAL
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_BURSTY
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_PERIODIC
-                   -
-    CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_CONTINUOUS
-                   -
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlTrafficType;
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_OCCASIONAL   ((CsrWifiRouterCtrlTrafficType) 0x00)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_BURSTY       ((CsrWifiRouterCtrlTrafficType) 0x01)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_PERIODIC     ((CsrWifiRouterCtrlTrafficType) 0x02)
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_CONTINUOUS   ((CsrWifiRouterCtrlTrafficType) 0x03)
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerRecordHandle
-
-  DESCRIPTION
-
-*******************************************************************************/
-typedef u32 CsrWifiRouterCtrlPeerRecordHandle;
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPowersaveTypeMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by
-    CsrWifiRouterCtrlPowersaveType
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterCtrlPowersaveTypeMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlQueueConfigMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiRouterCtrlQueueConfig
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlQueueConfigMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlRequestorInfo
-
-  DESCRIPTION
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterCtrlRequestorInfo;
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficStreamId
-
-  DESCRIPTION
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterCtrlTrafficStreamId;
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlSmeVersions
-
-  DESCRIPTION
-
-  MEMBERS
-    firmwarePatch -
-    smeBuild      -
-    smeHip        -
-
-*******************************************************************************/
-typedef struct
-{
-    u32      firmwarePatch;
-    char *smeBuild;
-    u32      smeHip;
-} CsrWifiRouterCtrlSmeVersions;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlStaInfo
-
-  DESCRIPTION
-
-  MEMBERS
-    wmmOrQosEnabled     -
-    powersaveMode       -
-    maxSpLength         -
-    listenIntervalInTus -
-
-*******************************************************************************/
-typedef struct
-{
-    u8                            wmmOrQosEnabled;
-    CsrWifiRouterCtrlPowersaveTypeMask powersaveMode;
-    u8                           maxSpLength;
-    u16                          listenIntervalInTus;
-} CsrWifiRouterCtrlStaInfo;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficFilter
-
-  DESCRIPTION
-
-  MEMBERS
-    etherType     -
-    ipType        -
-    udpSourcePort -
-    udpDestPort   -
-
-*******************************************************************************/
-typedef struct
-{
-    u32 etherType;
-    u8  ipType;
-    u32 udpSourcePort;
-    u32 udpDestPort;
-} CsrWifiRouterCtrlTrafficFilter;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficStats
-
-  DESCRIPTION
-
-  MEMBERS
-    rxMeanRate   - Mean rx data rate over the interval
-    rxFramesNum  - Keep number of Rx frames per second, for CYCLE_3.
-    txFramesNum  - Keep number of Tx frames per second, for CYCLE_3.
-    rxBytesCount - Keep calculated Rx throughput per second, for CYCLE_2.
-    txBytesCount - Keep calculated Tx throughput per second, for CYCLE_2.
-    intervals    - array size 11 MUST match TA_INTERVALS_NUM
-
-*******************************************************************************/
-typedef struct
-{
-    u32 rxMeanRate;
-    u32 rxFramesNum;
-    u32 txFramesNum;
-    u32 rxBytesCount;
-    u32 txBytesCount;
-    u8  intervals[11];
-} CsrWifiRouterCtrlTrafficStats;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlVersions
-
-  DESCRIPTION
-
-  MEMBERS
-    chipId        -
-    chipVersion   -
-    firmwareBuild -
-    firmwareHip   -
-    routerBuild   -
-    routerHip     -
-
-*******************************************************************************/
-typedef struct
-{
-    u32      chipId;
-    u32      chipVersion;
-    u32      firmwareBuild;
-    u32      firmwareHip;
-    char *routerBuild;
-    u32      routerHip;
-} CsrWifiRouterCtrlVersions;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficConfig
-
-  DESCRIPTION
-
-  MEMBERS
-    packetFilter -
-    customFilter -
-
-*******************************************************************************/
-typedef struct
-{
-    u16                      packetFilter;
-    CsrWifiRouterCtrlTrafficFilter customFilter;
-} CsrWifiRouterCtrlTrafficConfig;
-
-
-/* Downstream */
-#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST            (0x0000)
-
-#define CSR_WIFI_ROUTER_CTRL_CONFIGURE_POWER_MODE_REQ     ((CsrWifiRouterCtrlPrim) (0x0000 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_HIP_REQ                      ((CsrWifiRouterCtrlPrim) (0x0001 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_MEDIA_STATUS_REQ             ((CsrWifiRouterCtrlPrim) (0x0002 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_RES        ((CsrWifiRouterCtrlPrim) (0x0003 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_REQ           ((CsrWifiRouterCtrlPrim) (0x0004 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_REQ              ((CsrWifiRouterCtrlPrim) (0x0005 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_SUSPEND_RES                  ((CsrWifiRouterCtrlPrim) (0x0006 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_REQ                ((CsrWifiRouterCtrlPrim) (0x0007 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_RESUME_RES                   ((CsrWifiRouterCtrlPrim) (0x0008 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_REQ    ((CsrWifiRouterCtrlPrim) (0x0009 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_REQ      ((CsrWifiRouterCtrlPrim) (0x000A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_REQ                ((CsrWifiRouterCtrlPrim) (0x000B + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CLASSIFICATION_REQ   ((CsrWifiRouterCtrlPrim) (0x000C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_REQ           ((CsrWifiRouterCtrlPrim) (0x000D + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WIFI_OFF_REQ                 ((CsrWifiRouterCtrlPrim) (0x000E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WIFI_OFF_RES                 ((CsrWifiRouterCtrlPrim) (0x000F + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ                  ((CsrWifiRouterCtrlPrim) (0x0010 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES                  ((CsrWifiRouterCtrlPrim) (0x0011 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_M4_TRANSMIT_REQ              ((CsrWifiRouterCtrlPrim) (0x0012 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_MODE_SET_REQ                 ((CsrWifiRouterCtrlPrim) (0x0013 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PEER_ADD_REQ                 ((CsrWifiRouterCtrlPrim) (0x0014 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PEER_DEL_REQ                 ((CsrWifiRouterCtrlPrim) (0x0015 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_REQ              ((CsrWifiRouterCtrlPrim) (0x0016 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ             ((CsrWifiRouterCtrlPrim) (0x0017 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ         ((CsrWifiRouterCtrlPrim) (0x0018 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ        ((CsrWifiRouterCtrlPrim) (0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ              ((CsrWifiRouterCtrlPrim) (0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ    ((CsrWifiRouterCtrlPrim) (0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ      ((CsrWifiRouterCtrlPrim) (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ      ((CsrWifiRouterCtrlPrim) (0x001D + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ              ((CsrWifiRouterCtrlPrim) (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-
-
-#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST           (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)
-
-/* Upstream */
-#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST              (0x0000 + CSR_PRIM_UPSTREAM)
-
-#define CSR_WIFI_ROUTER_CTRL_HIP_IND                      ((CsrWifiRouterCtrlPrim)(0x0000 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND        ((CsrWifiRouterCtrlPrim)(0x0001 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM           ((CsrWifiRouterCtrlPrim)(0x0002 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_RESUME_IND                   ((CsrWifiRouterCtrlPrim)(0x0003 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_SUSPEND_IND                  ((CsrWifiRouterCtrlPrim)(0x0004 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_TCLAS_ADD_CFM                ((CsrWifiRouterCtrlPrim)(0x0005 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_RAW_SDIO_DEINITIALISE_CFM    ((CsrWifiRouterCtrlPrim)(0x0006 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_RAW_SDIO_INITIALISE_CFM      ((CsrWifiRouterCtrlPrim)(0x0007 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_TCLAS_DEL_CFM                ((CsrWifiRouterCtrlPrim)(0x0008 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_PROTOCOL_IND         ((CsrWifiRouterCtrlPrim)(0x0009 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_TRAFFIC_SAMPLE_IND           ((CsrWifiRouterCtrlPrim)(0x000A + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WIFI_OFF_IND                 ((CsrWifiRouterCtrlPrim)(0x000B + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WIFI_OFF_CFM                 ((CsrWifiRouterCtrlPrim)(0x000C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WIFI_ON_IND                  ((CsrWifiRouterCtrlPrim)(0x000D + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WIFI_ON_CFM                  ((CsrWifiRouterCtrlPrim)(0x000E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_M4_READY_TO_SEND_IND         ((CsrWifiRouterCtrlPrim)(0x000F + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_M4_TRANSMITTED_IND           ((CsrWifiRouterCtrlPrim)(0x0010 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_MIC_FAILURE_IND              ((CsrWifiRouterCtrlPrim)(0x0011 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_CONNECTED_IND                ((CsrWifiRouterCtrlPrim)(0x0012 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PEER_ADD_CFM                 ((CsrWifiRouterCtrlPrim)(0x0013 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PEER_DEL_CFM                 ((CsrWifiRouterCtrlPrim)(0x0014 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_UNEXPECTED_FRAME_IND         ((CsrWifiRouterCtrlPrim)(0x0015 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PEER_UPDATE_CFM              ((CsrWifiRouterCtrlPrim)(0x0016 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_CAPABILITIES_CFM             ((CsrWifiRouterCtrlPrim)(0x0017 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_CFM         ((CsrWifiRouterCtrlPrim)(0x0018 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM        ((CsrWifiRouterCtrlPrim)(0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND          ((CsrWifiRouterCtrlPrim)(0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND             ((CsrWifiRouterCtrlPrim)(0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND        ((CsrWifiRouterCtrlPrim)(0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM                 ((CsrWifiRouterCtrlPrim)(0x001D + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND  ((CsrWifiRouterCtrlPrim)(0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-
-#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST             (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)
-
-#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT             (CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)
-#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT               (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST   + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlConfigurePowerModeReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-    mode       -
-    wakeHost   -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrWifiRouterCtrlLowPowerMode  mode;
-    u8                        wakeHost;
-} CsrWifiRouterCtrlConfigurePowerModeReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlHipReq
-
-  DESCRIPTION
-    This primitive is used for transferring MLME messages to the HIP.
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    mlmeCommandLength - Length of the MLME signal
-    mlmeCommand       - Pointer to the MLME signal
-    dataRef1Length    - Length of the dataRef1 bulk data
-    dataRef1          - Pointer to the bulk data 1
-    dataRef2Length    - Length of the dataRef2 bulk data
-    dataRef2          - Pointer to the bulk data 2
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       mlmeCommandLength;
-    u8       *mlmeCommand;
-    u16       dataRef1Length;
-    u8       *dataRef1;
-    u16       dataRef2Length;
-    u8       *dataRef2;
-} CsrWifiRouterCtrlHipReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMediaStatusReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    clientData   -
-    mediaStatus  -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrWifiRouterCtrlMediaStatus   mediaStatus;
-} CsrWifiRouterCtrlMediaStatusReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMulticastAddressRes
-
-  DESCRIPTION
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    interfaceTag      -
-    clientData        -
-    status            -
-    action            -
-    getAddressesCount -
-    getAddresses      -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrResult                      status;
-    CsrWifiRouterCtrlListAction    action;
-    u8                       getAddressesCount;
-    CsrWifiMacAddress             *getAddresses;
-} CsrWifiRouterCtrlMulticastAddressRes;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPortConfigureReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common                 - Common header for use with the CsrWifiFsm Module
-    interfaceTag           -
-    clientData             -
-    uncontrolledPortAction -
-    controlledPortAction   -
-    macAddress             -
-    setProtection          -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrWifiRouterCtrlPortAction    uncontrolledPortAction;
-    CsrWifiRouterCtrlPortAction    controlledPortAction;
-    CsrWifiMacAddress              macAddress;
-    u8                        setProtection;
-} CsrWifiRouterCtrlPortConfigureReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlQosControlReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    clientData   -
-    control      -
-    queueConfig  -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                  common;
-    u16                        interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo   clientData;
-    CsrWifiRouterCtrlQoSControl      control;
-    CsrWifiRouterCtrlQueueConfigMask queueConfig;
-} CsrWifiRouterCtrlQosControlReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlSuspendRes
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-    status     -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrResult                      status;
-} CsrWifiRouterCtrlSuspendRes;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTclasAddReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    clientData   -
-    tclasLength  -
-    tclas        -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      tclasLength;
-    u8                      *tclas;
-} CsrWifiRouterCtrlTclasAddReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlResumeRes
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-    status     -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrResult                      status;
-} CsrWifiRouterCtrlResumeRes;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlRawSdioDeinitialiseReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-} CsrWifiRouterCtrlRawSdioDeinitialiseReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlRawSdioInitialiseReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-} CsrWifiRouterCtrlRawSdioInitialiseReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTclasDelReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    clientData   -
-    tclasLength  -
-    tclas        -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      tclasLength;
-    u8                      *tclas;
-} CsrWifiRouterCtrlTclasDelReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficClassificationReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    clientData   -
-    trafficType  -
-    period       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrWifiRouterCtrlTrafficType   trafficType;
-    u16                      period;
-} CsrWifiRouterCtrlTrafficClassificationReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficConfigReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    interfaceTag      -
-    clientData        -
-    trafficConfigType -
-    config            -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                    common;
-    u16                          interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo     clientData;
-    CsrWifiRouterCtrlTrafficConfigType trafficConfigType;
-    CsrWifiRouterCtrlTrafficConfig     config;
-} CsrWifiRouterCtrlTrafficConfigReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOffReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-} CsrWifiRouterCtrlWifiOffReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOffRes
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-} CsrWifiRouterCtrlWifiOffRes;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOnReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-    dataLength - Number of bytes in the buffer pointed to by 'data'
-    data       - Pointer to the buffer containing 'dataLength' bytes
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u32                      dataLength;
-    u8                      *data;
-} CsrWifiRouterCtrlWifiOnReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOnRes
-
-  DESCRIPTION
-
-  MEMBERS
-    common              - Common header for use with the CsrWifiFsm Module
-    clientData          -
-    status              -
-    numInterfaceAddress -
-    stationMacAddress   - array size 1 MUST match CSR_WIFI_NUM_INTERFACES
-    smeVersions         -
-    scheduledInterrupt  -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrResult                      status;
-    u16                      numInterfaceAddress;
-    CsrWifiMacAddress              stationMacAddress[2];
-    CsrWifiRouterCtrlSmeVersions   smeVersions;
-    u8                        scheduledInterrupt;
-} CsrWifiRouterCtrlWifiOnRes;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlM4TransmitReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    clientData   -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-} CsrWifiRouterCtrlM4TransmitReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlModeSetReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common              - Common header for use with the CsrWifiFsm Module
-    interfaceTag        -
-    clientData          -
-    mode                -
-    bssid               - BSSID of the network the device is going to be a part
-                          of
-    protection          - Set to TRUE if encryption is enabled for the
-                          connection/broadcast frames
-    intraBssDistEnabled - If set to TRUE, intra BSS destribution will be
-                          enabled. If set to FALSE, any unicast PDU which does
-                          not have the RA as the the local MAC address, shall be
-                          ignored. This field is interpreted by the receive if
-                          mode is set to CSR_WIFI_ROUTER_CTRL_MODE_P2PGO
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrWifiRouterCtrlMode          mode;
-    CsrWifiMacAddress              bssid;
-    u8                        protection;
-    u8                        intraBssDistEnabled;
-} CsrWifiRouterCtrlModeSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerAddReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   -
-    clientData     -
-    peerMacAddress -
-    associationId  -
-    staInfo        -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrWifiMacAddress              peerMacAddress;
-    u16                      associationId;
-    CsrWifiRouterCtrlStaInfo       staInfo;
-} CsrWifiRouterCtrlPeerAddReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerDelReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    interfaceTag     -
-    clientData       -
-    peerRecordHandle -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                   common;
-    u16                         interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo    clientData;
-    CsrWifiRouterCtrlPeerRecordHandle peerRecordHandle;
-} CsrWifiRouterCtrlPeerDelReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerUpdateReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    interfaceTag     -
-    clientData       -
-    peerRecordHandle -
-    powersaveMode    -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                    common;
-    u16                          interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo     clientData;
-    CsrWifiRouterCtrlPeerRecordHandle  peerRecordHandle;
-    CsrWifiRouterCtrlPowersaveTypeMask powersaveMode;
-} CsrWifiRouterCtrlPeerUpdateReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlCapabilitiesReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-} CsrWifiRouterCtrlCapabilitiesReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckEnableReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    -
-    clientData      -
-    macAddress      -
-    trafficStreamID -
-    role            -
-    bufferSize      -
-    timeout         -
-    ssn             -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                  common;
-    u16                        interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo   clientData;
-    CsrWifiMacAddress                macAddress;
-    CsrWifiRouterCtrlTrafficStreamId trafficStreamID;
-    CsrWifiRouterCtrlBlockAckRole    role;
-    u16                        bufferSize;
-    u16                        timeout;
-    u16                        ssn;
-} CsrWifiRouterCtrlBlockAckEnableReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckDisableReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    -
-    clientData      -
-    macAddress      -
-    trafficStreamID -
-    role            -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                  common;
-    u16                        interfaceTag;
-    CsrWifiRouterCtrlRequestorInfo   clientData;
-    CsrWifiMacAddress                macAddress;
-    CsrWifiRouterCtrlTrafficStreamId trafficStreamID;
-    CsrWifiRouterCtrlBlockAckRole    role;
-} CsrWifiRouterCtrlBlockAckDisableReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiRxPktReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    signalLength -
-    signal       -
-    dataLength   -
-    data         -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    u16       signalLength;
-    u8       *signal;
-    u16       dataLength;
-    u8       *data;
-} CsrWifiRouterCtrlWapiRxPktReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiMulticastFilterReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    u8        status;
-} CsrWifiRouterCtrlWapiMulticastFilterReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiUnicastFilterReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    u8        status;
-} CsrWifiRouterCtrlWapiUnicastFilterReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiUnicastTxPktReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    dataLength   -
-    data         -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    u16       dataLength;
-    u8       *data;
-} CsrWifiRouterCtrlWapiUnicastTxPktReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiFilterReq
-
-  DESCRIPTION
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    -
-    isWapiConnected -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    u8         isWapiConnected;
-} CsrWifiRouterCtrlWapiFilterReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlHipInd
-
-  DESCRIPTION
-    This primitive is used for transferring MLME messages from the HIP.
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    mlmeCommandLength - Length of the MLME signal
-    mlmeCommand       - Pointer to the MLME signal
-    dataRef1Length    - Length of the dataRef1 bulk data
-    dataRef1          - Pointer to the bulk data 1
-    dataRef2Length    - Length of the dataRef2 bulk data
-    dataRef2          - Pointer to the bulk data 2
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       mlmeCommandLength;
-    u8       *mlmeCommand;
-    u16       dataRef1Length;
-    u8       *dataRef1;
-    u16       dataRef2Length;
-    u8       *dataRef2;
-} CsrWifiRouterCtrlHipInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMulticastAddressInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    clientData        -
-    interfaceTag      -
-    action            -
-    setAddressesCount -
-    setAddresses      -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlListAction    action;
-    u8                       setAddressesCount;
-    CsrWifiMacAddress             *setAddresses;
-} CsrWifiRouterCtrlMulticastAddressInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPortConfigureCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    status       -
-    macAddress   -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrResult                      status;
-    CsrWifiMacAddress              macAddress;
-} CsrWifiRouterCtrlPortConfigureCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlResumeInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    clientData      -
-    powerMaintained -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u8                        powerMaintained;
-} CsrWifiRouterCtrlResumeInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlSuspendInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common      - Common header for use with the CsrWifiFsm Module
-    clientData  -
-    hardSuspend -
-    d3Suspend   -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u8                        hardSuspend;
-    u8                        d3Suspend;
-} CsrWifiRouterCtrlSuspendInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTclasAddCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrResult                      status;
-} CsrWifiRouterCtrlTclasAddCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlRawSdioDeinitialiseCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-    result     -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrResult                      result;
-} CsrWifiRouterCtrlRawSdioDeinitialiseCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlRawSdioInitialiseCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    clientData       -
-    result           -
-    byteRead         -
-    byteWrite        -
-    firmwareDownload -
-    reset            -
-    coreDumpPrepare  -
-    byteBlockRead    -
-    gpRead16         -
-    gpWrite16        -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                          common;
-    CsrWifiRouterCtrlRequestorInfo           clientData;
-    CsrResult                                result;
-    CsrWifiRouterCtrlRawSdioByteRead         byteRead;
-    CsrWifiRouterCtrlRawSdioByteWrite        byteWrite;
-    CsrWifiRouterCtrlRawSdioFirmwareDownload firmwareDownload;
-    CsrWifiRouterCtrlRawSdioReset            reset;
-    CsrWifiRouterCtrlRawSdioCoreDumpPrepare  coreDumpPrepare;
-    CsrWifiRouterCtrlRawSdioByteBlockRead    byteBlockRead;
-    CsrWifiRouterCtrlRawSdioGpRead16         gpRead16;
-    CsrWifiRouterCtrlRawSdioGpWrite16        gpWrite16;
-} CsrWifiRouterCtrlRawSdioInitialiseCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTclasDelCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrResult                      status;
-} CsrWifiRouterCtrlTclasDelCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficProtocolInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    packetType   -
-    direction    -
-    srcAddress   -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                    common;
-    CsrWifiRouterCtrlRequestorInfo     clientData;
-    u16                          interfaceTag;
-    CsrWifiRouterCtrlTrafficPacketType packetType;
-    CsrWifiRouterCtrlProtocolDirection direction;
-    CsrWifiMacAddress                  srcAddress;
-} CsrWifiRouterCtrlTrafficProtocolInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlTrafficSampleInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    stats        -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlTrafficStats  stats;
-} CsrWifiRouterCtrlTrafficSampleInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOffInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    clientData        -
-    controlIndication -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                    common;
-    CsrWifiRouterCtrlRequestorInfo     clientData;
-    CsrWifiRouterCtrlControlIndication controlIndication;
-} CsrWifiRouterCtrlWifiOffInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOffCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-} CsrWifiRouterCtrlWifiOffCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOnInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-    status     -
-    versions   -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrResult                      status;
-    CsrWifiRouterCtrlVersions      versions;
-} CsrWifiRouterCtrlWifiOnInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWifiOnCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    clientData -
-    status     -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    CsrResult                      status;
-} CsrWifiRouterCtrlWifiOnCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlM4ReadyToSendInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrWifiMacAddress              peerMacAddress;
-} CsrWifiRouterCtrlM4ReadyToSendInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlM4TransmittedInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-    status         -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrWifiMacAddress              peerMacAddress;
-    CsrResult                      status;
-} CsrWifiRouterCtrlM4TransmittedInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlMicFailureInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-    unicastPdu     -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrWifiMacAddress              peerMacAddress;
-    u8                        unicastPdu;
-} CsrWifiRouterCtrlMicFailureInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlConnectedInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-    peerStatus     -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrWifiMacAddress              peerMacAddress;
-    CsrWifiRouterCtrlPeerStatus    peerStatus;
-} CsrWifiRouterCtrlConnectedInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerAddCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    clientData       -
-    interfaceTag     -
-    peerMacAddress   -
-    peerRecordHandle -
-    status           -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                   common;
-    CsrWifiRouterCtrlRequestorInfo    clientData;
-    u16                         interfaceTag;
-    CsrWifiMacAddress                 peerMacAddress;
-    CsrWifiRouterCtrlPeerRecordHandle peerRecordHandle;
-    CsrResult                         status;
-} CsrWifiRouterCtrlPeerAddCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerDelCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrResult                      status;
-} CsrWifiRouterCtrlPeerDelCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlUnexpectedFrameInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    clientData     -
-    interfaceTag   -
-    peerMacAddress -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrWifiMacAddress              peerMacAddress;
-} CsrWifiRouterCtrlUnexpectedFrameInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlPeerUpdateCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrResult                      status;
-} CsrWifiRouterCtrlPeerUpdateCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlCapabilitiesCfm
-
-  DESCRIPTION
-    The router sends this primitive to confirm the size of the queues of the
-    HIP.
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    clientData       -
-    commandQueueSize - Size of command queue
-    trafficQueueSize - Size of traffic queue (per AC)
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      commandQueueSize;
-    u16                      trafficQueueSize;
-} CsrWifiRouterCtrlCapabilitiesCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckEnableCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrResult                      status;
-} CsrWifiRouterCtrlBlockAckEnableCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckDisableCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrResult                      status;
-} CsrWifiRouterCtrlBlockAckDisableCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlBlockAckErrorInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    clientData      -
-    interfaceTag    -
-    trafficStreamID -
-    peerMacAddress  -
-    status          -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                  common;
-    CsrWifiRouterCtrlRequestorInfo   clientData;
-    u16                        interfaceTag;
-    CsrWifiRouterCtrlTrafficStreamId trafficStreamID;
-    CsrWifiMacAddress                peerMacAddress;
-    CsrResult                        status;
-} CsrWifiRouterCtrlBlockAckErrorInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlStaInactiveInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    staAddress   -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrWifiMacAddress              staAddress;
-} CsrWifiRouterCtrlStaInactiveInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiRxMicCheckInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    signalLength -
-    signal       -
-    dataLength   -
-    data         -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    u16                      signalLength;
-    u8                      *signal;
-    u16                      dataLength;
-    u8                      *data;
-} CsrWifiRouterCtrlWapiRxMicCheckInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlModeSetCfm
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    mode         -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    CsrWifiRouterCtrlMode          mode;
-    CsrResult                      status;
-} CsrWifiRouterCtrlModeSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterCtrlWapiUnicastTxEncryptInd
-
-  DESCRIPTION
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    clientData   -
-    interfaceTag -
-    dataLength   -
-    data         -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrWifiRouterCtrlRequestorInfo clientData;
-    u16                      interfaceTag;
-    u16                      dataLength;
-    u8                      *data;
-} CsrWifiRouterCtrlWapiUnicastTxEncryptInd;
-
-#endif /* CSR_WIFI_ROUTER_CTRL_PRIM_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_sef.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_sef.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_sef.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_sef.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,46 +0,0 @@
-/*****************************************************************************
-
-  (c) Cambridge Silicon Radio Limited 2010
-  Confidential information of CSR
-
-  Refer to LICENSE.txt included with this source for details
-  on the license terms.
-
- *****************************************************************************/
-#include "csr_wifi_router_ctrl_sef.h"
-
-const CsrWifiRouterCtrlStateHandlerType
-	CsrWifiRouterCtrlDownstreamStateHandlers
-	[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT] = {
-		/* 0x0000 */ CsrWifiRouterCtrlConfigurePowerModeReqHandler,
-		/* 0x0001 */ CsrWifiRouterCtrlHipReqHandler,
-		/* 0x0002 */ CsrWifiRouterCtrlMediaStatusReqHandler,
-		/* 0x0003 */ CsrWifiRouterCtrlMulticastAddressResHandler,
-		/* 0x0004 */ CsrWifiRouterCtrlPortConfigureReqHandler,
-		/* 0x0005 */ CsrWifiRouterCtrlQosControlReqHandler,
-		/* 0x0006 */ CsrWifiRouterCtrlSuspendResHandler,
-		/* 0x0007 */ CsrWifiRouterCtrlTclasAddReqHandler,
-		/* 0x0008 */ CsrWifiRouterCtrlResumeResHandler,
-		/* 0x0009 */ CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler,
-		/* 0x000A */ CsrWifiRouterCtrlRawSdioInitialiseReqHandler,
-		/* 0x000B */ CsrWifiRouterCtrlTclasDelReqHandler,
-		/* 0x000C */ CsrWifiRouterCtrlTrafficClassificationReqHandler,
-		/* 0x000D */ CsrWifiRouterCtrlTrafficConfigReqHandler,
-		/* 0x000E */ CsrWifiRouterCtrlWifiOffReqHandler,
-		/* 0x000F */ CsrWifiRouterCtrlWifiOffResHandler,
-		/* 0x0010 */ CsrWifiRouterCtrlWifiOnReqHandler,
-		/* 0x0011 */ CsrWifiRouterCtrlWifiOnResHandler,
-		/* 0x0012 */ CsrWifiRouterCtrlM4TransmitReqHandler,
-		/* 0x0013 */ CsrWifiRouterCtrlModeSetReqHandler,
-		/* 0x0014 */ CsrWifiRouterCtrlPeerAddReqHandler,
-		/* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler,
-		/* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler,
-		/* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler,
-		/* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler,
-		/* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler,
-		/* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler,
-		/* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler,
-		/* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler,
-		/* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler,
-		/* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler,
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_sef.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_sef.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_sef.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_sef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-/*****************************************************************************
-
-  (c) Cambridge Silicon Radio Limited 2010
-  Confidential information of CSR
-
-  Refer to LICENSE.txt included with this source for details
-  on the license terms.
-
- *****************************************************************************/
-#ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_CTRL_H__
-#define CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_CTRL_H__
-
-#include "csr_wifi_router_ctrl_prim.h"
-
-    typedef void (*CsrWifiRouterCtrlStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg);
-
-    extern const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT];
-
-    extern void CsrWifiRouterCtrlConfigurePowerModeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlHipReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlMediaStatusReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlMulticastAddressResHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlPortConfigureReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlQosControlReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlSuspendResHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlTclasAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlRawSdioInitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlTclasDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlTrafficClassificationReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlTrafficConfigReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlWifiOffResHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlM4TransmitReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlPeerAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlPeerDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlPeerUpdateReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlCapabilitiesReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-
-#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_CTRL_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2591 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "csr_msgconv.h"
-#include "csr_wifi_router_ctrl_prim.h"
-#include "csr_wifi_router_ctrl_serialize.h"
-
-void CsrWifiRouterCtrlPfree(void *ptr)
-{
-    kfree(ptr);
-}
-
-
-size_t CsrWifiRouterCtrlConfigurePowerModeReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrWifiRouterCtrlLowPowerMode primitive->mode */
-    bufferSize += 1; /* u8 primitive->wakeHost */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlConfigurePowerModeReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlConfigurePowerModeReq *primitive = (CsrWifiRouterCtrlConfigurePowerModeReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->mode);
-    CsrUint8Ser(ptr, len, (u8) primitive->wakeHost);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlConfigurePowerModeReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlConfigurePowerModeReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlConfigurePowerModeReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mode, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->wakeHost, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlHipReqSizeof(void *msg)
-{
-    CsrWifiRouterCtrlHipReq *primitive = (CsrWifiRouterCtrlHipReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 12) */
-    bufferSize += 2;                            /* u16 primitive->mlmeCommandLength */
-    bufferSize += primitive->mlmeCommandLength; /* u8 primitive->mlmeCommand */
-    bufferSize += 2;                            /* u16 primitive->dataRef1Length */
-    bufferSize += primitive->dataRef1Length;    /* u8 primitive->dataRef1 */
-    bufferSize += 2;                            /* u16 primitive->dataRef2Length */
-    bufferSize += primitive->dataRef2Length;    /* u8 primitive->dataRef2 */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlHipReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlHipReq *primitive = (CsrWifiRouterCtrlHipReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->mlmeCommandLength);
-    if (primitive->mlmeCommandLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->mlmeCommand, ((u16) (primitive->mlmeCommandLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->dataRef1Length);
-    if (primitive->dataRef1Length)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->dataRef1, ((u16) (primitive->dataRef1Length)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->dataRef2Length);
-    if (primitive->dataRef2Length)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->dataRef2, ((u16) (primitive->dataRef2Length)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlHipReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlHipReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlHipReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mlmeCommandLength, buffer, &offset);
-    if (primitive->mlmeCommandLength)
-    {
-        primitive->mlmeCommand = kmalloc(primitive->mlmeCommandLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->mlmeCommand, buffer, &offset, ((u16) (primitive->mlmeCommandLength)));
-    }
-    else
-    {
-        primitive->mlmeCommand = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->dataRef1Length, buffer, &offset);
-    if (primitive->dataRef1Length)
-    {
-        primitive->dataRef1 = kmalloc(primitive->dataRef1Length, GFP_KERNEL);
-        CsrMemCpyDes(primitive->dataRef1, buffer, &offset, ((u16) (primitive->dataRef1Length)));
-    }
-    else
-    {
-        primitive->dataRef1 = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->dataRef2Length, buffer, &offset);
-    if (primitive->dataRef2Length)
-    {
-        primitive->dataRef2 = kmalloc(primitive->dataRef2Length, GFP_KERNEL);
-        CsrMemCpyDes(primitive->dataRef2, buffer, &offset, ((u16) (primitive->dataRef2Length)));
-    }
-    else
-    {
-        primitive->dataRef2 = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlHipReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlHipReq *primitive = (CsrWifiRouterCtrlHipReq *) voidPrimitivePointer;
-    kfree(primitive->mlmeCommand);
-    kfree(primitive->dataRef1);
-    kfree(primitive->dataRef2);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlMediaStatusReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 1; /* CsrWifiRouterCtrlMediaStatus primitive->mediaStatus */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlMediaStatusReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlMediaStatusReq *primitive = (CsrWifiRouterCtrlMediaStatusReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint8Ser(ptr, len, (u8) primitive->mediaStatus);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlMediaStatusReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlMediaStatusReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlMediaStatusReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->mediaStatus, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlMulticastAddressResSizeof(void *msg)
-{
-    CsrWifiRouterCtrlMulticastAddressRes *primitive = (CsrWifiRouterCtrlMulticastAddressRes *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* CsrWifiRouterCtrlListAction primitive->action */
-    bufferSize += 1; /* u8 primitive->getAddressesCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getAddressesCount; i1++)
-        {
-            bufferSize += 6; /* u8 primitive->getAddresses[i1].a[6] */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlMulticastAddressResSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlMulticastAddressRes *primitive = (CsrWifiRouterCtrlMulticastAddressRes *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->getAddressesCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getAddressesCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->getAddresses[i1].a, ((u16) (6)));
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlMulticastAddressResDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlMulticastAddressRes *primitive = kmalloc(sizeof(CsrWifiRouterCtrlMulticastAddressRes), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->getAddressesCount, buffer, &offset);
-    primitive->getAddresses = NULL;
-    if (primitive->getAddressesCount)
-    {
-        primitive->getAddresses = kmalloc(sizeof(CsrWifiMacAddress) * primitive->getAddressesCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getAddressesCount; i1++)
-        {
-            CsrMemCpyDes(primitive->getAddresses[i1].a, buffer, &offset, ((u16) (6)));
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlMulticastAddressResSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlMulticastAddressRes *primitive = (CsrWifiRouterCtrlMulticastAddressRes *) voidPrimitivePointer;
-    kfree(primitive->getAddresses);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlPortConfigureReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 18) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrWifiRouterCtrlPortAction primitive->uncontrolledPortAction */
-    bufferSize += 2; /* CsrWifiRouterCtrlPortAction primitive->controlledPortAction */
-    bufferSize += 6; /* u8 primitive->macAddress.a[6] */
-    bufferSize += 1; /* u8 primitive->setProtection */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlPortConfigureReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlPortConfigureReq *primitive = (CsrWifiRouterCtrlPortConfigureReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->uncontrolledPortAction);
-    CsrUint16Ser(ptr, len, (u16) primitive->controlledPortAction);
-    CsrMemCpySer(ptr, len, (const void *) primitive->macAddress.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->setProtection);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlPortConfigureReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlPortConfigureReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlPortConfigureReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->uncontrolledPortAction, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->controlledPortAction, buffer, &offset);
-    CsrMemCpyDes(primitive->macAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->setProtection, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlQosControlReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrWifiRouterCtrlQoSControl primitive->control */
-    bufferSize += 1; /* CsrWifiRouterCtrlQueueConfigMask primitive->queueConfig */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlQosControlReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlQosControlReq *primitive = (CsrWifiRouterCtrlQosControlReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->control);
-    CsrUint8Ser(ptr, len, (u8) primitive->queueConfig);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlQosControlReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlQosControlReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlQosControlReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->control, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->queueConfig, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlSuspendResSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlSuspendResSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlSuspendRes *primitive = (CsrWifiRouterCtrlSuspendRes *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlSuspendResDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlSuspendRes *primitive = kmalloc(sizeof(CsrWifiRouterCtrlSuspendRes), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlTclasAddReqSizeof(void *msg)
-{
-    CsrWifiRouterCtrlTclasAddReq *primitive = (CsrWifiRouterCtrlTclasAddReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2;                      /* u16 primitive->interfaceTag */
-    bufferSize += 2;                      /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2;                      /* u16 primitive->tclasLength */
-    bufferSize += primitive->tclasLength; /* u8 primitive->tclas */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlTclasAddReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlTclasAddReq *primitive = (CsrWifiRouterCtrlTclasAddReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->tclasLength);
-    if (primitive->tclasLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->tclas, ((u16) (primitive->tclasLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlTclasAddReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlTclasAddReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlTclasAddReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->tclasLength, buffer, &offset);
-    if (primitive->tclasLength)
-    {
-        primitive->tclas = kmalloc(primitive->tclasLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->tclas, buffer, &offset, ((u16) (primitive->tclasLength)));
-    }
-    else
-    {
-        primitive->tclas = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlTclasAddReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlTclasAddReq *primitive = (CsrWifiRouterCtrlTclasAddReq *) voidPrimitivePointer;
-    kfree(primitive->tclas);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlResumeResSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlResumeResSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlResumeRes *primitive = (CsrWifiRouterCtrlResumeRes *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlResumeResDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlResumeRes *primitive = kmalloc(sizeof(CsrWifiRouterCtrlResumeRes), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlTclasDelReqSizeof(void *msg)
-{
-    CsrWifiRouterCtrlTclasDelReq *primitive = (CsrWifiRouterCtrlTclasDelReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2;                      /* u16 primitive->interfaceTag */
-    bufferSize += 2;                      /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2;                      /* u16 primitive->tclasLength */
-    bufferSize += primitive->tclasLength; /* u8 primitive->tclas */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlTclasDelReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlTclasDelReq *primitive = (CsrWifiRouterCtrlTclasDelReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->tclasLength);
-    if (primitive->tclasLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->tclas, ((u16) (primitive->tclasLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlTclasDelReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlTclasDelReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlTclasDelReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->tclasLength, buffer, &offset);
-    if (primitive->tclasLength)
-    {
-        primitive->tclas = kmalloc(primitive->tclasLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->tclas, buffer, &offset, ((u16) (primitive->tclasLength)));
-    }
-    else
-    {
-        primitive->tclas = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlTclasDelReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlTclasDelReq *primitive = (CsrWifiRouterCtrlTclasDelReq *) voidPrimitivePointer;
-    kfree(primitive->tclas);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlTrafficClassificationReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 1; /* CsrWifiRouterCtrlTrafficType primitive->trafficType */
-    bufferSize += 2; /* u16 primitive->period */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlTrafficClassificationReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlTrafficClassificationReq *primitive = (CsrWifiRouterCtrlTrafficClassificationReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint8Ser(ptr, len, (u8) primitive->trafficType);
-    CsrUint16Ser(ptr, len, (u16) primitive->period);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlTrafficClassificationReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlTrafficClassificationReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlTrafficClassificationReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->trafficType, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->period, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlTrafficConfigReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 24) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrWifiRouterCtrlTrafficConfigType primitive->trafficConfigType */
-    bufferSize += 2; /* u16 primitive->config.packetFilter */
-    bufferSize += 4; /* u32 primitive->config.customFilter.etherType */
-    bufferSize += 1; /* u8 primitive->config.customFilter.ipType */
-    bufferSize += 4; /* u32 primitive->config.customFilter.udpSourcePort */
-    bufferSize += 4; /* u32 primitive->config.customFilter.udpDestPort */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlTrafficConfigReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlTrafficConfigReq *primitive = (CsrWifiRouterCtrlTrafficConfigReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->trafficConfigType);
-    CsrUint16Ser(ptr, len, (u16) primitive->config.packetFilter);
-    CsrUint32Ser(ptr, len, (u32) primitive->config.customFilter.etherType);
-    CsrUint8Ser(ptr, len, (u8) primitive->config.customFilter.ipType);
-    CsrUint32Ser(ptr, len, (u32) primitive->config.customFilter.udpSourcePort);
-    CsrUint32Ser(ptr, len, (u32) primitive->config.customFilter.udpDestPort);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlTrafficConfigReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlTrafficConfigReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlTrafficConfigReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->trafficConfigType, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->config.packetFilter, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->config.customFilter.etherType, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->config.customFilter.ipType, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->config.customFilter.udpSourcePort, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->config.customFilter.udpDestPort, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlWifiOnReqSizeof(void *msg)
-{
-    CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2;                     /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 4;                     /* u32 primitive->dataLength */
-    bufferSize += primitive->dataLength; /* u8 primitive->data */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlWifiOnReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint32Ser(ptr, len, (u32) primitive->dataLength);
-    if (primitive->dataLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->data, ((u16) (primitive->dataLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlWifiOnReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlWifiOnReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlWifiOnReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->dataLength, buffer, &offset);
-    if (primitive->dataLength)
-    {
-        primitive->data = kmalloc(primitive->dataLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->data, buffer, &offset, ((u16) (primitive->dataLength)));
-    }
-    else
-    {
-        primitive->data = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlWifiOnReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) voidPrimitivePointer;
-    kfree(primitive->data);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlWifiOnResSizeof(void *msg)
-{
-    CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 30) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 2; /* u16 primitive->numInterfaceAddress */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 2; i1++)
-        {
-            bufferSize += 6;                                                                            /* u8 primitive->stationMacAddress[i1].a[6] */
-        }
-    }
-    bufferSize += 4;                                                                                    /* u32 primitive->smeVersions.firmwarePatch */
-    bufferSize += (primitive->smeVersions.smeBuild ? strlen(primitive->smeVersions.smeBuild) : 0) + 1;  /* char* primitive->smeVersions.smeBuild (0 byte len + 1 for NULL Term) */
-    bufferSize += 4;                                                                                    /* u32 primitive->smeVersions.smeHip */
-    bufferSize += 1;                                                                                    /* u8 primitive->scheduledInterrupt */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlWifiOnResSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint16Ser(ptr, len, (u16) primitive->numInterfaceAddress);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 2; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->stationMacAddress[i1].a, ((u16) (6)));
-        }
-    }
-    CsrUint32Ser(ptr, len, (u32) primitive->smeVersions.firmwarePatch);
-    CsrCharStringSer(ptr, len, primitive->smeVersions.smeBuild);
-    CsrUint32Ser(ptr, len, (u32) primitive->smeVersions.smeHip);
-    CsrUint8Ser(ptr, len, (u8) primitive->scheduledInterrupt);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlWifiOnResDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlWifiOnRes *primitive = kmalloc(sizeof(CsrWifiRouterCtrlWifiOnRes), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->numInterfaceAddress, buffer, &offset);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 2; i1++)
-        {
-            CsrMemCpyDes(primitive->stationMacAddress[i1].a, buffer, &offset, ((u16) (6)));
-        }
-    }
-    CsrUint32Des((u32 *) &primitive->smeVersions.firmwarePatch, buffer, &offset);
-    CsrCharStringDes(&primitive->smeVersions.smeBuild, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->smeVersions.smeHip, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scheduledInterrupt, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlWifiOnResSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *) voidPrimitivePointer;
-    kfree(primitive->smeVersions.smeBuild);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlM4TransmitReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlM4TransmitReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlM4TransmitReq *primitive = (CsrWifiRouterCtrlM4TransmitReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlM4TransmitReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlM4TransmitReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlM4TransmitReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlModeSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 16) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 1; /* CsrWifiRouterCtrlMode primitive->mode */
-    bufferSize += 6; /* u8 primitive->bssid.a[6] */
-    bufferSize += 1; /* u8 primitive->protection */
-    bufferSize += 1; /* u8 primitive->intraBssDistEnabled */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlModeSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlModeSetReq *primitive = (CsrWifiRouterCtrlModeSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint8Ser(ptr, len, (u8) primitive->mode);
-    CsrMemCpySer(ptr, len, (const void *) primitive->bssid.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->protection);
-    CsrUint8Ser(ptr, len, (u8) primitive->intraBssDistEnabled);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlModeSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlModeSetReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlModeSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->mode, buffer, &offset);
-    CsrMemCpyDes(primitive->bssid.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->protection, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->intraBssDistEnabled, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlPeerAddReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 21) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    bufferSize += 2; /* u16 primitive->associationId */
-    bufferSize += 1; /* u8 primitive->staInfo.wmmOrQosEnabled */
-    bufferSize += 2; /* CsrWifiRouterCtrlPowersaveTypeMask primitive->staInfo.powersaveMode */
-    bufferSize += 1; /* u8 primitive->staInfo.maxSpLength */
-    bufferSize += 2; /* u16 primitive->staInfo.listenIntervalInTus */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlPeerAddReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlPeerAddReq *primitive = (CsrWifiRouterCtrlPeerAddReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    CsrUint16Ser(ptr, len, (u16) primitive->associationId);
-    CsrUint8Ser(ptr, len, (u8) primitive->staInfo.wmmOrQosEnabled);
-    CsrUint16Ser(ptr, len, (u16) primitive->staInfo.powersaveMode);
-    CsrUint8Ser(ptr, len, (u8) primitive->staInfo.maxSpLength);
-    CsrUint16Ser(ptr, len, (u16) primitive->staInfo.listenIntervalInTus);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlPeerAddReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlPeerAddReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlPeerAddReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint16Des((u16 *) &primitive->associationId, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->staInfo.wmmOrQosEnabled, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->staInfo.powersaveMode, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->staInfo.maxSpLength, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->staInfo.listenIntervalInTus, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlPeerDelReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 4; /* CsrWifiRouterCtrlPeerRecordHandle primitive->peerRecordHandle */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlPeerDelReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlPeerDelReq *primitive = (CsrWifiRouterCtrlPeerDelReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint32Ser(ptr, len, (u32) primitive->peerRecordHandle);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlPeerDelReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlPeerDelReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlPeerDelReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->peerRecordHandle, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlPeerUpdateReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 4; /* CsrWifiRouterCtrlPeerRecordHandle primitive->peerRecordHandle */
-    bufferSize += 2; /* CsrWifiRouterCtrlPowersaveTypeMask primitive->powersaveMode */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlPeerUpdateReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlPeerUpdateReq *primitive = (CsrWifiRouterCtrlPeerUpdateReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint32Ser(ptr, len, (u32) primitive->peerRecordHandle);
-    CsrUint16Ser(ptr, len, (u16) primitive->powersaveMode);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlPeerUpdateReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlPeerUpdateReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlPeerUpdateReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->peerRecordHandle, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->powersaveMode, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlBlockAckEnableReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 21) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 6; /* u8 primitive->macAddress.a[6] */
-    bufferSize += 1; /* CsrWifiRouterCtrlTrafficStreamId primitive->trafficStreamID */
-    bufferSize += 1; /* CsrWifiRouterCtrlBlockAckRole primitive->role */
-    bufferSize += 2; /* u16 primitive->bufferSize */
-    bufferSize += 2; /* u16 primitive->timeout */
-    bufferSize += 2; /* u16 primitive->ssn */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlBlockAckEnableReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlBlockAckEnableReq *primitive = (CsrWifiRouterCtrlBlockAckEnableReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrMemCpySer(ptr, len, (const void *) primitive->macAddress.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->trafficStreamID);
-    CsrUint8Ser(ptr, len, (u8) primitive->role);
-    CsrUint16Ser(ptr, len, (u16) primitive->bufferSize);
-    CsrUint16Ser(ptr, len, (u16) primitive->timeout);
-    CsrUint16Ser(ptr, len, (u16) primitive->ssn);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlBlockAckEnableReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlBlockAckEnableReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckEnableReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrMemCpyDes(primitive->macAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->trafficStreamID, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->role, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->bufferSize, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->timeout, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->ssn, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlBlockAckDisableReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 6; /* u8 primitive->macAddress.a[6] */
-    bufferSize += 1; /* CsrWifiRouterCtrlTrafficStreamId primitive->trafficStreamID */
-    bufferSize += 1; /* CsrWifiRouterCtrlBlockAckRole primitive->role */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlBlockAckDisableReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlBlockAckDisableReq *primitive = (CsrWifiRouterCtrlBlockAckDisableReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrMemCpySer(ptr, len, (const void *) primitive->macAddress.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->trafficStreamID);
-    CsrUint8Ser(ptr, len, (u8) primitive->role);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlBlockAckDisableReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlBlockAckDisableReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckDisableReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrMemCpyDes(primitive->macAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->trafficStreamID, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->role, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlWapiRxPktReqSizeof(void *msg)
-{
-    CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
-    bufferSize += 2;                       /* u16 primitive->interfaceTag */
-    bufferSize += 2;                       /* u16 primitive->signalLength */
-    bufferSize += primitive->signalLength; /* u8 primitive->signal */
-    bufferSize += 2;                       /* u16 primitive->dataLength */
-    bufferSize += primitive->dataLength;   /* u8 primitive->data */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlWapiRxPktReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->signalLength);
-    if (primitive->signalLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->signal, ((u16) (primitive->signalLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->dataLength);
-    if (primitive->dataLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->data, ((u16) (primitive->dataLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlWapiRxPktReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlWapiRxPktReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlWapiRxPktReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->signalLength, buffer, &offset);
-    if (primitive->signalLength)
-    {
-        primitive->signal = kmalloc(primitive->signalLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->signal, buffer, &offset, ((u16) (primitive->signalLength)));
-    }
-    else
-    {
-        primitive->signal = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->dataLength, buffer, &offset);
-    if (primitive->dataLength)
-    {
-        primitive->data = kmalloc(primitive->dataLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->data, buffer, &offset, ((u16) (primitive->dataLength)));
-    }
-    else
-    {
-        primitive->data = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlWapiRxPktReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) voidPrimitivePointer;
-    kfree(primitive->signal);
-    kfree(primitive->data);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof(void *msg)
-{
-    CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2;                     /* u16 primitive->interfaceTag */
-    bufferSize += 2;                     /* u16 primitive->dataLength */
-    bufferSize += primitive->dataLength; /* u8 primitive->data */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlWapiUnicastTxPktReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->dataLength);
-    if (primitive->dataLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->data, ((u16) (primitive->dataLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlWapiUnicastTxPktReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = kmalloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxPktReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->dataLength, buffer, &offset);
-    if (primitive->dataLength)
-    {
-        primitive->data = kmalloc(primitive->dataLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->data, buffer, &offset, ((u16) (primitive->dataLength)));
-    }
-    else
-    {
-        primitive->data = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) voidPrimitivePointer;
-    kfree(primitive->data);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlHipIndSizeof(void *msg)
-{
-    CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 12) */
-    bufferSize += 2;                            /* u16 primitive->mlmeCommandLength */
-    bufferSize += primitive->mlmeCommandLength; /* u8 primitive->mlmeCommand */
-    bufferSize += 2;                            /* u16 primitive->dataRef1Length */
-    bufferSize += primitive->dataRef1Length;    /* u8 primitive->dataRef1 */
-    bufferSize += 2;                            /* u16 primitive->dataRef2Length */
-    bufferSize += primitive->dataRef2Length;    /* u8 primitive->dataRef2 */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlHipIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->mlmeCommandLength);
-    if (primitive->mlmeCommandLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->mlmeCommand, ((u16) (primitive->mlmeCommandLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->dataRef1Length);
-    if (primitive->dataRef1Length)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->dataRef1, ((u16) (primitive->dataRef1Length)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->dataRef2Length);
-    if (primitive->dataRef2Length)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->dataRef2, ((u16) (primitive->dataRef2Length)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlHipIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlHipInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlHipInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mlmeCommandLength, buffer, &offset);
-    if (primitive->mlmeCommandLength)
-    {
-        primitive->mlmeCommand = kmalloc(primitive->mlmeCommandLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->mlmeCommand, buffer, &offset, ((u16) (primitive->mlmeCommandLength)));
-    }
-    else
-    {
-        primitive->mlmeCommand = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->dataRef1Length, buffer, &offset);
-    if (primitive->dataRef1Length)
-    {
-        primitive->dataRef1 = kmalloc(primitive->dataRef1Length, GFP_KERNEL);
-        CsrMemCpyDes(primitive->dataRef1, buffer, &offset, ((u16) (primitive->dataRef1Length)));
-    }
-    else
-    {
-        primitive->dataRef1 = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->dataRef2Length, buffer, &offset);
-    if (primitive->dataRef2Length)
-    {
-        primitive->dataRef2 = kmalloc(primitive->dataRef2Length, GFP_KERNEL);
-        CsrMemCpyDes(primitive->dataRef2, buffer, &offset, ((u16) (primitive->dataRef2Length)));
-    }
-    else
-    {
-        primitive->dataRef2 = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlHipIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *) voidPrimitivePointer;
-    kfree(primitive->mlmeCommand);
-    kfree(primitive->dataRef1);
-    kfree(primitive->dataRef2);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlMulticastAddressIndSizeof(void *msg)
-{
-    CsrWifiRouterCtrlMulticastAddressInd *primitive = (CsrWifiRouterCtrlMulticastAddressInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiRouterCtrlListAction primitive->action */
-    bufferSize += 1; /* u8 primitive->setAddressesCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setAddressesCount; i1++)
-        {
-            bufferSize += 6; /* u8 primitive->setAddresses[i1].a[6] */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlMulticastAddressIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlMulticastAddressInd *primitive = (CsrWifiRouterCtrlMulticastAddressInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->setAddressesCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setAddressesCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->setAddresses[i1].a, ((u16) (6)));
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlMulticastAddressIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlMulticastAddressInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlMulticastAddressInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->setAddressesCount, buffer, &offset);
-    primitive->setAddresses = NULL;
-    if (primitive->setAddressesCount)
-    {
-        primitive->setAddresses = kmalloc(sizeof(CsrWifiMacAddress) * primitive->setAddressesCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setAddressesCount; i1++)
-        {
-            CsrMemCpyDes(primitive->setAddresses[i1].a, buffer, &offset, ((u16) (6)));
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlMulticastAddressIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlMulticastAddressInd *primitive = (CsrWifiRouterCtrlMulticastAddressInd *) voidPrimitivePointer;
-    kfree(primitive->setAddresses);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlPortConfigureCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 6; /* u8 primitive->macAddress.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlPortConfigureCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlPortConfigureCfm *primitive = (CsrWifiRouterCtrlPortConfigureCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrMemCpySer(ptr, len, (const void *) primitive->macAddress.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlPortConfigureCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlPortConfigureCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlPortConfigureCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrMemCpyDes(primitive->macAddress.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlSuspendIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 1; /* u8 primitive->hardSuspend */
-    bufferSize += 1; /* u8 primitive->d3Suspend */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlSuspendIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlSuspendInd *primitive = (CsrWifiRouterCtrlSuspendInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint8Ser(ptr, len, (u8) primitive->hardSuspend);
-    CsrUint8Ser(ptr, len, (u8) primitive->d3Suspend);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlSuspendIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlSuspendInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlSuspendInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->hardSuspend, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->d3Suspend, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlTclasAddCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlTclasAddCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlTclasAddCfm *primitive = (CsrWifiRouterCtrlTclasAddCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlTclasAddCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlTclasAddCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlTclasAddCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlRawSdioDeinitialiseCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrResult primitive->result */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlRawSdioDeinitialiseCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlRawSdioDeinitialiseCfm *primitive = (CsrWifiRouterCtrlRawSdioDeinitialiseCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->result);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlRawSdioDeinitialiseCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlRawSdioDeinitialiseCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlRawSdioDeinitialiseCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->result, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlRawSdioInitialiseCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 39) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrResult primitive->result */
-    bufferSize += 4; /* CsrWifiRouterCtrlRawSdioByteRead primitive->byteRead */
-    bufferSize += 4; /* CsrWifiRouterCtrlRawSdioByteWrite primitive->byteWrite */
-    bufferSize += 4; /* CsrWifiRouterCtrlRawSdioFirmwareDownload primitive->firmwareDownload */
-    bufferSize += 4; /* CsrWifiRouterCtrlRawSdioReset primitive->reset */
-    bufferSize += 4; /* CsrWifiRouterCtrlRawSdioCoreDumpPrepare primitive->coreDumpPrepare */
-    bufferSize += 4; /* CsrWifiRouterCtrlRawSdioByteBlockRead primitive->byteBlockRead */
-    bufferSize += 4; /* CsrWifiRouterCtrlRawSdioGpRead16 primitive->gpRead16 */
-    bufferSize += 4; /* CsrWifiRouterCtrlRawSdioGpWrite16 primitive->gpWrite16 */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlRawSdioInitialiseCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlRawSdioInitialiseCfm *primitive = (CsrWifiRouterCtrlRawSdioInitialiseCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->result);
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->byteRead */
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->byteWrite */
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->firmwareDownload */
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->reset */
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->coreDumpPrepare */
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->byteBlockRead */
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->gpRead16 */
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->gpWrite16 */
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlRawSdioInitialiseCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlRawSdioInitialiseCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlRawSdioInitialiseCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->result, buffer, &offset);
-    primitive->byteRead = NULL;         /* Special for Function Pointers... */
-    offset += 4;
-    primitive->byteWrite = NULL;        /* Special for Function Pointers... */
-    offset += 4;
-    primitive->firmwareDownload = NULL; /* Special for Function Pointers... */
-    offset += 4;
-    primitive->reset = NULL;            /* Special for Function Pointers... */
-    offset += 4;
-    primitive->coreDumpPrepare = NULL;  /* Special for Function Pointers... */
-    offset += 4;
-    primitive->byteBlockRead = NULL;    /* Special for Function Pointers... */
-    offset += 4;
-    primitive->gpRead16 = NULL;         /* Special for Function Pointers... */
-    offset += 4;
-    primitive->gpWrite16 = NULL;        /* Special for Function Pointers... */
-    offset += 4;
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlTclasDelCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlTclasDelCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlTclasDelCfm *primitive = (CsrWifiRouterCtrlTclasDelCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlTclasDelCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlTclasDelCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlTclasDelCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlTrafficProtocolIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrWifiRouterCtrlTrafficPacketType primitive->packetType */
-    bufferSize += 2; /* CsrWifiRouterCtrlProtocolDirection primitive->direction */
-    bufferSize += 6; /* u8 primitive->srcAddress.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlTrafficProtocolIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlTrafficProtocolInd *primitive = (CsrWifiRouterCtrlTrafficProtocolInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->packetType);
-    CsrUint16Ser(ptr, len, (u16) primitive->direction);
-    CsrMemCpySer(ptr, len, (const void *) primitive->srcAddress.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlTrafficProtocolIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlTrafficProtocolInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlTrafficProtocolInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->packetType, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->direction, buffer, &offset);
-    CsrMemCpyDes(primitive->srcAddress.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlTrafficSampleIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 38) */
-    bufferSize += 2;  /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2;  /* u16 primitive->interfaceTag */
-    bufferSize += 4;  /* u32 primitive->stats.rxMeanRate */
-    bufferSize += 4;  /* u32 primitive->stats.rxFramesNum */
-    bufferSize += 4;  /* u32 primitive->stats.txFramesNum */
-    bufferSize += 4;  /* u32 primitive->stats.rxBytesCount */
-    bufferSize += 4;  /* u32 primitive->stats.txBytesCount */
-    bufferSize += 11; /* u8 primitive->stats.intervals[11] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlTrafficSampleIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlTrafficSampleInd *primitive = (CsrWifiRouterCtrlTrafficSampleInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint32Ser(ptr, len, (u32) primitive->stats.rxMeanRate);
-    CsrUint32Ser(ptr, len, (u32) primitive->stats.rxFramesNum);
-    CsrUint32Ser(ptr, len, (u32) primitive->stats.txFramesNum);
-    CsrUint32Ser(ptr, len, (u32) primitive->stats.rxBytesCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->stats.txBytesCount);
-    CsrMemCpySer(ptr, len, (const void *) primitive->stats.intervals, ((u16) (11)));
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlTrafficSampleIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlTrafficSampleInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlTrafficSampleInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->stats.rxMeanRate, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->stats.rxFramesNum, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->stats.txFramesNum, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->stats.rxBytesCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->stats.txBytesCount, buffer, &offset);
-    CsrMemCpyDes(primitive->stats.intervals, buffer, &offset, ((u16) (11)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlWifiOnIndSizeof(void *msg)
-{
-    CsrWifiRouterCtrlWifiOnInd *primitive = (CsrWifiRouterCtrlWifiOnInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 27) */
-    bufferSize += 2;                                                                                    /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2;                                                                                    /* CsrResult primitive->status */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.chipId */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.chipVersion */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.firmwareBuild */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.firmwareHip */
-    bufferSize += (primitive->versions.routerBuild ? strlen(primitive->versions.routerBuild) : 0) + 1;  /* char* primitive->versions.routerBuild (0 byte len + 1 for NULL Term) */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.routerHip */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlWifiOnIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlWifiOnInd *primitive = (CsrWifiRouterCtrlWifiOnInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.chipId);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.chipVersion);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.firmwareBuild);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.firmwareHip);
-    CsrCharStringSer(ptr, len, primitive->versions.routerBuild);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.routerHip);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlWifiOnIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlWifiOnInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlWifiOnInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.chipId, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.chipVersion, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.firmwareBuild, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.firmwareHip, buffer, &offset);
-    CsrCharStringDes(&primitive->versions.routerBuild, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.routerHip, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlWifiOnIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlWifiOnInd *primitive = (CsrWifiRouterCtrlWifiOnInd *) voidPrimitivePointer;
-    kfree(primitive->versions.routerBuild);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlWifiOnCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlWifiOnCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlWifiOnCfm *primitive = (CsrWifiRouterCtrlWifiOnCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlWifiOnCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlWifiOnCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlWifiOnCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlM4ReadyToSendIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlM4ReadyToSendIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlM4ReadyToSendInd *primitive = (CsrWifiRouterCtrlM4ReadyToSendInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlM4ReadyToSendIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlM4ReadyToSendInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlM4ReadyToSendInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlM4TransmittedIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlM4TransmittedIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlM4TransmittedInd *primitive = (CsrWifiRouterCtrlM4TransmittedInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlM4TransmittedIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlM4TransmittedInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlM4TransmittedInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlMicFailureIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 14) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    bufferSize += 1; /* u8 primitive->unicastPdu */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlMicFailureIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlMicFailureInd *primitive = (CsrWifiRouterCtrlMicFailureInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->unicastPdu);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlMicFailureIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlMicFailureInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlMicFailureInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->unicastPdu, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlConnectedIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 14) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    bufferSize += 1; /* CsrWifiRouterCtrlPeerStatus primitive->peerStatus */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlConnectedIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlConnectedInd *primitive = (CsrWifiRouterCtrlConnectedInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->peerStatus);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlConnectedIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlConnectedInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlConnectedInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->peerStatus, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlPeerAddCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 19) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    bufferSize += 4; /* CsrWifiRouterCtrlPeerRecordHandle primitive->peerRecordHandle */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlPeerAddCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlPeerAddCfm *primitive = (CsrWifiRouterCtrlPeerAddCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    CsrUint32Ser(ptr, len, (u32) primitive->peerRecordHandle);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlPeerAddCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlPeerAddCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlPeerAddCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint32Des((u32 *) &primitive->peerRecordHandle, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlPeerDelCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlPeerDelCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlPeerDelCfm *primitive = (CsrWifiRouterCtrlPeerDelCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlPeerDelCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlPeerDelCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlPeerDelCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlUnexpectedFrameIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlUnexpectedFrameIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlUnexpectedFrameInd *primitive = (CsrWifiRouterCtrlUnexpectedFrameInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlUnexpectedFrameIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlUnexpectedFrameInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlUnexpectedFrameInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlPeerUpdateCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlPeerUpdateCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlPeerUpdateCfm *primitive = (CsrWifiRouterCtrlPeerUpdateCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlPeerUpdateCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlPeerUpdateCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlPeerUpdateCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlCapabilitiesCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->commandQueueSize */
-    bufferSize += 2; /* u16 primitive->trafficQueueSize */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlCapabilitiesCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlCapabilitiesCfm *primitive = (CsrWifiRouterCtrlCapabilitiesCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->commandQueueSize);
-    CsrUint16Ser(ptr, len, (u16) primitive->trafficQueueSize);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlCapabilitiesCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlCapabilitiesCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlCapabilitiesCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->commandQueueSize, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->trafficQueueSize, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlBlockAckEnableCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlBlockAckEnableCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlBlockAckEnableCfm *primitive = (CsrWifiRouterCtrlBlockAckEnableCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlBlockAckEnableCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlBlockAckEnableCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckEnableCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlBlockAckDisableCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlBlockAckDisableCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlBlockAckDisableCfm *primitive = (CsrWifiRouterCtrlBlockAckDisableCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlBlockAckDisableCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlBlockAckDisableCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckDisableCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlBlockAckErrorIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 16) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiRouterCtrlTrafficStreamId primitive->trafficStreamID */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlBlockAckErrorIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlBlockAckErrorInd *primitive = (CsrWifiRouterCtrlBlockAckErrorInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->trafficStreamID);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlBlockAckErrorIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlBlockAckErrorInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlBlockAckErrorInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->trafficStreamID, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlStaInactiveIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 6; /* u8 primitive->staAddress.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlStaInactiveIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlStaInactiveInd *primitive = (CsrWifiRouterCtrlStaInactiveInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->staAddress.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlStaInactiveIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlStaInactiveInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlStaInactiveInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->staAddress.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlWapiRxMicCheckIndSizeof(void *msg)
-{
-    CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2;                       /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2;                       /* u16 primitive->interfaceTag */
-    bufferSize += 2;                       /* u16 primitive->signalLength */
-    bufferSize += primitive->signalLength; /* u8 primitive->signal */
-    bufferSize += 2;                       /* u16 primitive->dataLength */
-    bufferSize += primitive->dataLength;   /* u8 primitive->data */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlWapiRxMicCheckIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->signalLength);
-    if (primitive->signalLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->signal, ((u16) (primitive->signalLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->dataLength);
-    if (primitive->dataLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->data, ((u16) (primitive->dataLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlWapiRxMicCheckIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlWapiRxMicCheckInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->signalLength, buffer, &offset);
-    if (primitive->signalLength)
-    {
-        primitive->signal = kmalloc(primitive->signalLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->signal, buffer, &offset, ((u16) (primitive->signalLength)));
-    }
-    else
-    {
-        primitive->signal = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->dataLength, buffer, &offset);
-    if (primitive->dataLength)
-    {
-        primitive->data = kmalloc(primitive->dataLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->data, buffer, &offset, ((u16) (primitive->dataLength)));
-    }
-    else
-    {
-        primitive->data = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlWapiRxMicCheckIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) voidPrimitivePointer;
-    kfree(primitive->signal);
-    kfree(primitive->data);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterCtrlModeSetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiRouterCtrlMode primitive->mode */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlModeSetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlModeSetCfm *primitive = (CsrWifiRouterCtrlModeSetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->mode);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlModeSetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlModeSetCfm *primitive = kmalloc(sizeof(CsrWifiRouterCtrlModeSetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->mode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg)
-{
-    CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2;                     /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
-    bufferSize += 2;                     /* u16 primitive->interfaceTag */
-    bufferSize += 2;                     /* u16 primitive->dataLength */
-    bufferSize += primitive->dataLength; /* u8 primitive->data */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->clientData);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->dataLength);
-    if (primitive->dataLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->data, ((u16) (primitive->dataLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = kmalloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxEncryptInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->clientData, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->dataLength, buffer, &offset);
-    if (primitive->dataLength)
-    {
-        primitive->data = kmalloc(primitive->dataLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->data, buffer, &offset, ((u16) (primitive->dataLength)));
-    }
-    else
-    {
-        primitive->data = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) voidPrimitivePointer;
-    kfree(primitive->data);
-    kfree(primitive);
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,333 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_ROUTER_CTRL_SERIALIZE_H__
-#define CSR_WIFI_ROUTER_CTRL_SERIALIZE_H__
-
-#include "csr_wifi_msgconv.h"
-
-#include "csr_wifi_router_ctrl_prim.h"
-
-extern void CsrWifiRouterCtrlPfree(void *ptr);
-
-extern u8* CsrWifiRouterCtrlConfigurePowerModeReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlConfigurePowerModeReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlConfigurePowerModeReqSizeof(void *msg);
-#define CsrWifiRouterCtrlConfigurePowerModeReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlHipReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlHipReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlHipReqSizeof(void *msg);
-extern void CsrWifiRouterCtrlHipReqSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlMediaStatusReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlMediaStatusReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlMediaStatusReqSizeof(void *msg);
-#define CsrWifiRouterCtrlMediaStatusReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlMulticastAddressResSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlMulticastAddressResDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlMulticastAddressResSizeof(void *msg);
-extern void CsrWifiRouterCtrlMulticastAddressResSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlPortConfigureReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlPortConfigureReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlPortConfigureReqSizeof(void *msg);
-#define CsrWifiRouterCtrlPortConfigureReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlQosControlReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlQosControlReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlQosControlReqSizeof(void *msg);
-#define CsrWifiRouterCtrlQosControlReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlSuspendResSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlSuspendResDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlSuspendResSizeof(void *msg);
-#define CsrWifiRouterCtrlSuspendResSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlTclasAddReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlTclasAddReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlTclasAddReqSizeof(void *msg);
-extern void CsrWifiRouterCtrlTclasAddReqSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlResumeResSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlResumeResDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlResumeResSizeof(void *msg);
-#define CsrWifiRouterCtrlResumeResSerFree CsrWifiRouterCtrlPfree
-
-#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiRouterCtrlRawSdioDeinitialiseReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiRouterCtrlRawSdioDeinitialiseReqSerFree CsrWifiRouterCtrlPfree
-
-#define CsrWifiRouterCtrlRawSdioInitialiseReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiRouterCtrlRawSdioInitialiseReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiRouterCtrlRawSdioInitialiseReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiRouterCtrlRawSdioInitialiseReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlTclasDelReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlTclasDelReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlTclasDelReqSizeof(void *msg);
-extern void CsrWifiRouterCtrlTclasDelReqSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlTrafficClassificationReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlTrafficClassificationReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlTrafficClassificationReqSizeof(void *msg);
-#define CsrWifiRouterCtrlTrafficClassificationReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlTrafficConfigReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlTrafficConfigReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlTrafficConfigReqSizeof(void *msg);
-#define CsrWifiRouterCtrlTrafficConfigReqSerFree CsrWifiRouterCtrlPfree
-
-#define CsrWifiRouterCtrlWifiOffReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiRouterCtrlWifiOffReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiRouterCtrlWifiOffReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiRouterCtrlWifiOffReqSerFree CsrWifiRouterCtrlPfree
-
-#define CsrWifiRouterCtrlWifiOffResSer CsrWifiEventCsrUint16Ser
-#define CsrWifiRouterCtrlWifiOffResDes CsrWifiEventCsrUint16Des
-#define CsrWifiRouterCtrlWifiOffResSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiRouterCtrlWifiOffResSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlWifiOnReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlWifiOnReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlWifiOnReqSizeof(void *msg);
-extern void CsrWifiRouterCtrlWifiOnReqSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlWifiOnResSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlWifiOnResDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlWifiOnResSizeof(void *msg);
-extern void CsrWifiRouterCtrlWifiOnResSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlM4TransmitReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlM4TransmitReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlM4TransmitReqSizeof(void *msg);
-#define CsrWifiRouterCtrlM4TransmitReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlModeSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlModeSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlModeSetReqSizeof(void *msg);
-#define CsrWifiRouterCtrlModeSetReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlPeerAddReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlPeerAddReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlPeerAddReqSizeof(void *msg);
-#define CsrWifiRouterCtrlPeerAddReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlPeerDelReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlPeerDelReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlPeerDelReqSizeof(void *msg);
-#define CsrWifiRouterCtrlPeerDelReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlPeerUpdateReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlPeerUpdateReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlPeerUpdateReqSizeof(void *msg);
-#define CsrWifiRouterCtrlPeerUpdateReqSerFree CsrWifiRouterCtrlPfree
-
-#define CsrWifiRouterCtrlCapabilitiesReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiRouterCtrlCapabilitiesReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiRouterCtrlCapabilitiesReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiRouterCtrlCapabilitiesReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlBlockAckEnableReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlBlockAckEnableReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlBlockAckEnableReqSizeof(void *msg);
-#define CsrWifiRouterCtrlBlockAckEnableReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlBlockAckDisableReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlBlockAckDisableReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlBlockAckDisableReqSizeof(void *msg);
-#define CsrWifiRouterCtrlBlockAckDisableReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlWapiRxPktReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlWapiRxPktReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlWapiRxPktReqSizeof(void *msg);
-extern void CsrWifiRouterCtrlWapiRxPktReqSerFree(void *msg);
-
-#define CsrWifiRouterCtrlWapiMulticastFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser
-#define CsrWifiRouterCtrlWapiMulticastFilterReqDes CsrWifiEventCsrUint16CsrUint8Des
-#define CsrWifiRouterCtrlWapiMulticastFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
-#define CsrWifiRouterCtrlWapiMulticastFilterReqSerFree CsrWifiRouterCtrlPfree
-
-#define CsrWifiRouterCtrlWapiUnicastFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser
-#define CsrWifiRouterCtrlWapiUnicastFilterReqDes CsrWifiEventCsrUint16CsrUint8Des
-#define CsrWifiRouterCtrlWapiUnicastFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
-#define CsrWifiRouterCtrlWapiUnicastFilterReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlWapiUnicastTxPktReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlWapiUnicastTxPktReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof(void *msg);
-extern void CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree(void *msg);
-
-#define CsrWifiRouterCtrlWapiFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser
-#define CsrWifiRouterCtrlWapiFilterReqDes CsrWifiEventCsrUint16CsrUint8Des
-#define CsrWifiRouterCtrlWapiFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
-#define CsrWifiRouterCtrlWapiFilterReqSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlHipIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlHipIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlHipIndSizeof(void *msg);
-extern void CsrWifiRouterCtrlHipIndSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlMulticastAddressIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlMulticastAddressIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlMulticastAddressIndSizeof(void *msg);
-extern void CsrWifiRouterCtrlMulticastAddressIndSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlPortConfigureCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlPortConfigureCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlPortConfigureCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlPortConfigureCfmSerFree CsrWifiRouterCtrlPfree
-
-#define CsrWifiRouterCtrlResumeIndSer CsrWifiEventCsrUint16CsrUint8Ser
-#define CsrWifiRouterCtrlResumeIndDes CsrWifiEventCsrUint16CsrUint8Des
-#define CsrWifiRouterCtrlResumeIndSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
-#define CsrWifiRouterCtrlResumeIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlSuspendIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlSuspendIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlSuspendIndSizeof(void *msg);
-#define CsrWifiRouterCtrlSuspendIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlTclasAddCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlTclasAddCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlTclasAddCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlTclasAddCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlRawSdioDeinitialiseCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlRawSdioDeinitialiseCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlRawSdioDeinitialiseCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlRawSdioDeinitialiseCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlRawSdioInitialiseCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlRawSdioInitialiseCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlRawSdioInitialiseCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlRawSdioInitialiseCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlTclasDelCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlTclasDelCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlTclasDelCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlTclasDelCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlTrafficProtocolIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlTrafficProtocolIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlTrafficProtocolIndSizeof(void *msg);
-#define CsrWifiRouterCtrlTrafficProtocolIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlTrafficSampleIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlTrafficSampleIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlTrafficSampleIndSizeof(void *msg);
-#define CsrWifiRouterCtrlTrafficSampleIndSerFree CsrWifiRouterCtrlPfree
-
-#define CsrWifiRouterCtrlWifiOffIndSer CsrWifiEventCsrUint16CsrUint8Ser
-#define CsrWifiRouterCtrlWifiOffIndDes CsrWifiEventCsrUint16CsrUint8Des
-#define CsrWifiRouterCtrlWifiOffIndSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
-#define CsrWifiRouterCtrlWifiOffIndSerFree CsrWifiRouterCtrlPfree
-
-#define CsrWifiRouterCtrlWifiOffCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiRouterCtrlWifiOffCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiRouterCtrlWifiOffCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiRouterCtrlWifiOffCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlWifiOnIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlWifiOnIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlWifiOnIndSizeof(void *msg);
-extern void CsrWifiRouterCtrlWifiOnIndSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlWifiOnCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlWifiOnCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlWifiOnCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlWifiOnCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlM4ReadyToSendIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlM4ReadyToSendIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlM4ReadyToSendIndSizeof(void *msg);
-#define CsrWifiRouterCtrlM4ReadyToSendIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlM4TransmittedIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlM4TransmittedIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlM4TransmittedIndSizeof(void *msg);
-#define CsrWifiRouterCtrlM4TransmittedIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlMicFailureIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlMicFailureIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlMicFailureIndSizeof(void *msg);
-#define CsrWifiRouterCtrlMicFailureIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlConnectedIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlConnectedIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlConnectedIndSizeof(void *msg);
-#define CsrWifiRouterCtrlConnectedIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlPeerAddCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlPeerAddCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlPeerAddCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlPeerAddCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlPeerDelCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlPeerDelCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlPeerDelCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlPeerDelCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlUnexpectedFrameIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlUnexpectedFrameIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlUnexpectedFrameIndSizeof(void *msg);
-#define CsrWifiRouterCtrlUnexpectedFrameIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlPeerUpdateCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlPeerUpdateCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlPeerUpdateCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlPeerUpdateCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlCapabilitiesCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlCapabilitiesCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlCapabilitiesCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlCapabilitiesCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlBlockAckEnableCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlBlockAckEnableCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlBlockAckEnableCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlBlockAckEnableCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlBlockAckDisableCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlBlockAckDisableCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlBlockAckDisableCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlBlockAckDisableCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlBlockAckErrorIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlBlockAckErrorIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlBlockAckErrorIndSizeof(void *msg);
-#define CsrWifiRouterCtrlBlockAckErrorIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlStaInactiveIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlStaInactiveIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlStaInactiveIndSizeof(void *msg);
-#define CsrWifiRouterCtrlStaInactiveIndSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlWapiRxMicCheckIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlWapiRxMicCheckIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlWapiRxMicCheckIndSizeof(void *msg);
-extern void CsrWifiRouterCtrlWapiRxMicCheckIndSerFree(void *msg);
-
-extern u8* CsrWifiRouterCtrlModeSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlModeSetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlModeSetCfmSizeof(void *msg);
-#define CsrWifiRouterCtrlModeSetCfmSerFree CsrWifiRouterCtrlPfree
-
-extern u8* CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg);
-extern void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *msg);
-
-#endif /* CSR_WIFI_ROUTER_CTRL_SERIALIZE_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_free_downstream_contents.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_free_downstream_contents.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_free_downstream_contents.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_free_downstream_contents.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,53 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/slab.h>
-#include "csr_wifi_router_prim.h"
-#include "csr_wifi_router_lib.h"
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrWifiRouterFreeDownstreamMessageContents
- *
- *  DESCRIPTION
- *
- *
- *  PARAMETERS
- *      eventClass: only the value CSR_WIFI_ROUTER_PRIM will be handled
- *      message:    the message to free
- *----------------------------------------------------------------------------*/
-void CsrWifiRouterFreeDownstreamMessageContents(u16 eventClass, void *message)
-{
-    if (eventClass != CSR_WIFI_ROUTER_PRIM)
-    {
-        return;
-    }
-    if (NULL == message)
-    {
-        return;
-    }
-
-    switch (*((CsrWifiRouterPrim *) message))
-    {
-        case CSR_WIFI_ROUTER_MA_PACKET_REQ:
-        {
-            CsrWifiRouterMaPacketReq *p = (CsrWifiRouterMaPacketReq *)message;
-            kfree(p->frame);
-            p->frame = NULL;
-            break;
-        }
-
-        default:
-            break;
-    }
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,47 +0,0 @@
-/*****************************************************************************
-
-	(c) Cambridge Silicon Radio Limited 2011
-	All rights reserved and confidential information of CSR
-
-	Refer to LICENSE.txt included with this source for details
-	on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/slab.h>
-#include "csr_wifi_router_prim.h"
-#include "csr_wifi_router_lib.h"
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrWifiRouterFreeUpstreamMessageContents
- *
- *  DESCRIPTION
- *
- *
- *  PARAMETERS
- *      eventClass: only the value CSR_WIFI_ROUTER_PRIM will be handled
- *      message:    the message to free
- *----------------------------------------------------------------------------*/
-void CsrWifiRouterFreeUpstreamMessageContents(u16 eventClass, void *message)
-{
-	if (eventClass != CSR_WIFI_ROUTER_PRIM)
-		return;
-	if (NULL == message)
-		return;
-	switch (*((CsrWifiRouterPrim *) message)) {
-	case CSR_WIFI_ROUTER_MA_PACKET_IND:
-	{
-		CsrWifiRouterMaPacketInd *p =
-			(CsrWifiRouterMaPacketInd *) message;
-		kfree(p->frame);
-		p->frame = NULL;
-		break;
-	}
-	default:
-		break;
-	}
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_lib.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_lib.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_lib.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_lib.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,417 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_ROUTER_LIB_H__
-#define CSR_WIFI_ROUTER_LIB_H__
-
-#include "csr_sched.h"
-#include "csr_macro.h"
-#include "csr_msg_transport.h"
-
-#include "csr_wifi_lib.h"
-
-#include "csr_wifi_router_prim.h"
-#include "csr_wifi_router_task.h"
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiRouterFreeUpstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_ROUTER upstream message. Does not
- *      free the message itself, and can only be used for upstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_ROUTER upstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiRouterFreeUpstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiRouterFreeDownstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_ROUTER downstream message. Does not
- *      free the message itself, and can only be used for downstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_ROUTER downstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiRouterFreeDownstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- * Enum to string functions
- *----------------------------------------------------------------------------*/
-const char* CsrWifiRouterAppTypeToString(CsrWifiRouterAppType value);
-const char* CsrWifiRouterEncapsulationToString(CsrWifiRouterEncapsulation value);
-const char* CsrWifiRouterOuiToString(CsrWifiRouterOui value);
-const char* CsrWifiRouterPriorityToString(CsrWifiRouterPriority value);
-
-
-/*----------------------------------------------------------------------------*
- * CsrPrim Type toString function.
- * Converts a message type to the String name of the Message
- *----------------------------------------------------------------------------*/
-const char* CsrWifiRouterPrimTypeToString(CsrPrim msgType);
-
-/*----------------------------------------------------------------------------*
- * Lookup arrays for PrimType name Strings
- *----------------------------------------------------------------------------*/
-extern const char *CsrWifiRouterUpstreamPrimNames[CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT];
-extern const char *CsrWifiRouterDownstreamPrimNames[CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT];
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketCancelReqSend
-
-  DESCRIPTION
-    This primitive is used to request cancellation of a previously send
-    CsrWifiRouterMaPacketReq.
-    The frame may already have been transmitted so there is no guarantees
-    that the CsrWifiRouterMaPacketCancelReq actually cancels the transmission
-    of the frame in question.
-    If the cancellation fails, the Router will send, if required,
-    CsrWifiRouterMaPacketCfm.
-    If the cancellation succeeds, the Router will not send
-    CsrWifiRouterMaPacketCfm.
-
-  PARAMETERS
-    queue          - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    hostTag        - The hostTag for the frame, which should be cancelled.
-    priority       - Priority of the frame, which should be cancelled
-    peerMacAddress - Destination MAC address of the frame, which should be
-                     cancelled
-
-*******************************************************************************/
-#define CsrWifiRouterMaPacketCancelReqCreate(msg__, dst__, src__, interfaceTag__, hostTag__, priority__, peerMacAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterMaPacketCancelReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_CANCEL_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->hostTag = (hostTag__); \
-    msg__->priority = (priority__); \
-    msg__->peerMacAddress = (peerMacAddress__);
-
-#define CsrWifiRouterMaPacketCancelReqSendTo(dst__, src__, interfaceTag__, hostTag__, priority__, peerMacAddress__) \
-    { \
-        CsrWifiRouterMaPacketCancelReq *msg__; \
-        CsrWifiRouterMaPacketCancelReqCreate(msg__, dst__, src__, interfaceTag__, hostTag__, priority__, peerMacAddress__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterMaPacketCancelReqSend(src__, interfaceTag__, hostTag__, priority__, peerMacAddress__) \
-    CsrWifiRouterMaPacketCancelReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, hostTag__, priority__, peerMacAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketReqSend
-
-  DESCRIPTION
-    A task sends this primitive to transmit a frame.
-
-  PARAMETERS
-    queue              - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - The handle of the subscription
-    frameLength        - Length of the frame to be sent in bytes
-    frame              - Pointer to the frame to be sent
-    freeFunction       - Pointer to function to be used to free the frame
-    priority           - Priority of the frame, which should be sent
-    hostTag            - An application shall set the bits b31..b28 using one of
-                         the CSR_WIFI_ROUTER_APP_TYPE_* masks. Bits b0..b27 can
-                         be used by the requestor without any restrictions, but
-                         the hostTag shall be unique so the hostTag for
-                         CSR_WIFI_ROUTER_APP _TYPE_OTHER should be constructured
-                         in the following way [ CSR_WIFI_ROUTER_APP_TYPE_OTHER
-                         (4 bits) | SubscriptionHandle (8 bits) | Sequence no.
-                         (20 bits) ]. If the hostTag is not unique, the
-                         behaviour of the system is unpredicatable with respect
-                         to data/management frame transfer.
-    cfmRequested       - Indicates if the requestor needs a confirm for packet
-                         requests sent under this subscription. If set to TRUE,
-                         the router will send a confirm, else it will not send
-                         any confirm
-
-*******************************************************************************/
-#define CsrWifiRouterMaPacketReqCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterMaPacketReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->subscriptionHandle = (subscriptionHandle__); \
-    msg__->frameLength = (frameLength__); \
-    msg__->frame = (frame__); \
-    msg__->freeFunction = (freeFunction__); \
-    msg__->priority = (priority__); \
-    msg__->hostTag = (hostTag__); \
-    msg__->cfmRequested = (cfmRequested__);
-
-#define CsrWifiRouterMaPacketReqSendTo(dst__, src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__) \
-    { \
-        CsrWifiRouterMaPacketReq *msg__; \
-        CsrWifiRouterMaPacketReqCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterMaPacketReqSend(src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__) \
-    CsrWifiRouterMaPacketReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, subscriptionHandle__, frameLength__, frame__, freeFunction__, priority__, hostTag__, cfmRequested__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketIndSend
-
-  DESCRIPTION
-    The router sends the primitive to a subscribed task when it receives a
-    frame matching the subscription.
-
-  PARAMETERS
-    queue              - Destination Task Queue
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - The handle of the subscription
-    result             - Status of the operation
-    frameLength        - Length of the received frame in bytes
-    frame              - Pointer to the received frame
-    freeFunction       - Pointer to function to be used to free the frame
-    rssi               - Received signal strength indication in dBm
-    snr                - Signal to Noise Ratio
-    rate               - Transmission/Reception rate
-
-*******************************************************************************/
-#define CsrWifiRouterMaPacketIndCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterMaPacketInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->subscriptionHandle = (subscriptionHandle__); \
-    msg__->result = (result__); \
-    msg__->frameLength = (frameLength__); \
-    msg__->frame = (frame__); \
-    msg__->freeFunction = (freeFunction__); \
-    msg__->rssi = (rssi__); \
-    msg__->snr = (snr__); \
-    msg__->rate = (rate__);
-
-#define CsrWifiRouterMaPacketIndSendTo(dst__, src__, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__) \
-    { \
-        CsrWifiRouterMaPacketInd *msg__; \
-        CsrWifiRouterMaPacketIndCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterMaPacketIndSend(dst__, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__) \
-    CsrWifiRouterMaPacketIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, subscriptionHandle__, result__, frameLength__, frame__, freeFunction__, rssi__, snr__, rate__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketResSend
-
-  DESCRIPTION
-    A task send this primitive to confirm the reception of the received
-    frame.
-
-  PARAMETERS
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - The handle of the subscription
-    result             - Status of the operation
-
-*******************************************************************************/
-#define CsrWifiRouterMaPacketResCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, result__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterMaPacketRes), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_RES, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->subscriptionHandle = (subscriptionHandle__); \
-    msg__->result = (result__);
-
-#define CsrWifiRouterMaPacketResSendTo(dst__, src__, interfaceTag__, subscriptionHandle__, result__) \
-    { \
-        CsrWifiRouterMaPacketRes *msg__; \
-        CsrWifiRouterMaPacketResCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, result__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterMaPacketResSend(src__, interfaceTag__, subscriptionHandle__, result__) \
-    CsrWifiRouterMaPacketResSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, subscriptionHandle__, result__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketCfmSend
-
-  DESCRIPTION
-    The router sends the primitive to confirm the result of the transmission
-    of the packet of the corresponding CSR_WIFI_ROUTER MA_PACKET_REQ request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    result       - Status of the operation
-    hostTag      - The hostTrag will match the hostTag sent in the request.
-    rate         - Transmission/Reception rate
-
-*******************************************************************************/
-#define CsrWifiRouterMaPacketCfmCreate(msg__, dst__, src__, interfaceTag__, result__, hostTag__, rate__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterMaPacketCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->result = (result__); \
-    msg__->hostTag = (hostTag__); \
-    msg__->rate = (rate__);
-
-#define CsrWifiRouterMaPacketCfmSendTo(dst__, src__, interfaceTag__, result__, hostTag__, rate__) \
-    { \
-        CsrWifiRouterMaPacketCfm *msg__; \
-        CsrWifiRouterMaPacketCfmCreate(msg__, dst__, src__, interfaceTag__, result__, hostTag__, rate__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterMaPacketCfmSend(dst__, interfaceTag__, result__, hostTag__, rate__) \
-    CsrWifiRouterMaPacketCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, result__, hostTag__, rate__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketSubscribeReqSend
-
-  DESCRIPTION
-    A task can use this primitive to subscribe for a particular OUI/protocol
-    and transmit and receive frames matching the subscription.
-    NOTE: Multiple subscriptions for a given protocol and OUI will result in
-    the first subscription receiving the data and not the subsequent
-    subscriptions.
-
-  PARAMETERS
-    queue         - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    encapsulation - Specifies the encapsulation type, which will be used for the
-                    subscription
-    protocol      - Together with the OUI, specifies the protocol, which a task
-                    wants to subscribe to
-    oui           - Specifies the OUI for the protocol, which a task wants to
-                    subscribe to
-
-*******************************************************************************/
-#define CsrWifiRouterMaPacketSubscribeReqCreate(msg__, dst__, src__, interfaceTag__, encapsulation__, protocol__, oui__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterMaPacketSubscribeReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->encapsulation = (encapsulation__); \
-    msg__->protocol = (protocol__); \
-    msg__->oui = (oui__);
-
-#define CsrWifiRouterMaPacketSubscribeReqSendTo(dst__, src__, interfaceTag__, encapsulation__, protocol__, oui__) \
-    { \
-        CsrWifiRouterMaPacketSubscribeReq *msg__; \
-        CsrWifiRouterMaPacketSubscribeReqCreate(msg__, dst__, src__, interfaceTag__, encapsulation__, protocol__, oui__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterMaPacketSubscribeReqSend(src__, interfaceTag__, encapsulation__, protocol__, oui__) \
-    CsrWifiRouterMaPacketSubscribeReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, encapsulation__, protocol__, oui__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketSubscribeCfmSend
-
-  DESCRIPTION
-    The router sends this primitive to confirm the result of the
-    subscription.
-
-  PARAMETERS
-    queue              - Destination Task Queue
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - Handle to the subscription
-                         This handle must be used in all subsequent requests
-    status             - Status of the operation
-    allocOffset        - Size of the offset for the frames of the subscription
-
-*******************************************************************************/
-#define CsrWifiRouterMaPacketSubscribeCfmCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, status__, allocOffset__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterMaPacketSubscribeCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->subscriptionHandle = (subscriptionHandle__); \
-    msg__->status = (status__); \
-    msg__->allocOffset = (allocOffset__);
-
-#define CsrWifiRouterMaPacketSubscribeCfmSendTo(dst__, src__, interfaceTag__, subscriptionHandle__, status__, allocOffset__) \
-    { \
-        CsrWifiRouterMaPacketSubscribeCfm *msg__; \
-        CsrWifiRouterMaPacketSubscribeCfmCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__, status__, allocOffset__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterMaPacketSubscribeCfmSend(dst__, interfaceTag__, subscriptionHandle__, status__, allocOffset__) \
-    CsrWifiRouterMaPacketSubscribeCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, subscriptionHandle__, status__, allocOffset__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketUnsubscribeReqSend
-
-  DESCRIPTION
-    A task sends this primitive to unsubscribe a subscription
-
-  PARAMETERS
-    queue              - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - The handle of the subscription
-
-*******************************************************************************/
-#define CsrWifiRouterMaPacketUnsubscribeReqCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterMaPacketUnsubscribeReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->subscriptionHandle = (subscriptionHandle__);
-
-#define CsrWifiRouterMaPacketUnsubscribeReqSendTo(dst__, src__, interfaceTag__, subscriptionHandle__) \
-    { \
-        CsrWifiRouterMaPacketUnsubscribeReq *msg__; \
-        CsrWifiRouterMaPacketUnsubscribeReqCreate(msg__, dst__, src__, interfaceTag__, subscriptionHandle__); \
-        CsrMsgTransport(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterMaPacketUnsubscribeReqSend(src__, interfaceTag__, subscriptionHandle__) \
-    CsrWifiRouterMaPacketUnsubscribeReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, subscriptionHandle__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketUnsubscribeCfmSend
-
-  DESCRIPTION
-    The router sends this primitive to confirm the result of the
-    unsubscription.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Status of the operation
-
-*******************************************************************************/
-#define CsrWifiRouterMaPacketUnsubscribeCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiRouterMaPacketUnsubscribeCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_PRIM, CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiRouterMaPacketUnsubscribeCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiRouterMaPacketUnsubscribeCfm *msg__; \
-        CsrWifiRouterMaPacketUnsubscribeCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_PRIM, msg__); \
-    }
-
-#define CsrWifiRouterMaPacketUnsubscribeCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiRouterMaPacketUnsubscribeCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, status__)
-
-#endif /* CSR_WIFI_ROUTER_LIB_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_prim.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_prim.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_prim.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_prim.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,421 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_ROUTER_PRIM_H__
-#define CSR_WIFI_ROUTER_PRIM_H__
-
-#include <linux/types.h>
-#include "csr_prim_defs.h"
-#include "csr_sched.h"
-#include "csr_wifi_common.h"
-#include "csr_result.h"
-#include "csr_wifi_fsm_event.h"
-
-#define CSR_WIFI_ROUTER_PRIM                                            (0x0400)
-
-typedef CsrPrim CsrWifiRouterPrim;
-
-typedef void (*CsrWifiRouterFrameFreeFunction)(void *frame);
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterAppType
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_APP_TYPE_SME   -
-    CSR_WIFI_ROUTER_APP_TYPE_PAL   -
-    CSR_WIFI_ROUTER_APP_TYPE_NME   -
-    CSR_WIFI_ROUTER_APP_TYPE_OTHER -
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterAppType;
-#define CSR_WIFI_ROUTER_APP_TYPE_SME     ((CsrWifiRouterAppType) 0x0)
-#define CSR_WIFI_ROUTER_APP_TYPE_PAL     ((CsrWifiRouterAppType) 0x1)
-#define CSR_WIFI_ROUTER_APP_TYPE_NME     ((CsrWifiRouterAppType) 0x2)
-#define CSR_WIFI_ROUTER_APP_TYPE_OTHER   ((CsrWifiRouterAppType) 0x3)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterEncapsulation
-
-  DESCRIPTION
-    Indicates the type of encapsulation used for the subscription
-
- VALUES
-    CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET
-                   - Ethernet encapsulation
-    CSR_WIFI_ROUTER_ENCAPSULATION_LLC_SNAP
-                   - LLC/SNAP encapsulation
-
-*******************************************************************************/
-typedef u8 CsrWifiRouterEncapsulation;
-#define CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET   ((CsrWifiRouterEncapsulation) 0x00)
-#define CSR_WIFI_ROUTER_ENCAPSULATION_LLC_SNAP   ((CsrWifiRouterEncapsulation) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterOui
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_ROUTER_OUI_RFC_1042 -
-    CSR_WIFI_ROUTER_OUI_BT       -
-
-*******************************************************************************/
-typedef u32 CsrWifiRouterOui;
-#define CSR_WIFI_ROUTER_OUI_RFC_1042   ((CsrWifiRouterOui) 0x000000)
-#define CSR_WIFI_ROUTER_OUI_BT         ((CsrWifiRouterOui) 0x001958)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterPriority
-
-  DESCRIPTION
-    As defined in the IEEE 802.11 standards
-
- VALUES
-    CSR_WIFI_ROUTER_PRIORITY_QOS_UP0
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_ROUTER_PRIORITY_QOS_UP1
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_ROUTER_PRIORITY_QOS_UP2
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_ROUTER_PRIORITY_QOS_UP3
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_ROUTER_PRIORITY_QOS_UP4
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_ROUTER_PRIORITY_QOS_UP5
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_ROUTER_PRIORITY_QOS_UP6
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_ROUTER_PRIORITY_QOS_UP7
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_ROUTER_PRIORITY_CONTENTION
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_ROUTER_PRIORITY_MANAGEMENT
-                   - See IEEE 802.11 Standard
-
-*******************************************************************************/
-typedef u16 CsrWifiRouterPriority;
-#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP0      ((CsrWifiRouterPriority) 0x0000)
-#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP1      ((CsrWifiRouterPriority) 0x0001)
-#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP2      ((CsrWifiRouterPriority) 0x0002)
-#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP3      ((CsrWifiRouterPriority) 0x0003)
-#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP4      ((CsrWifiRouterPriority) 0x0004)
-#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP5      ((CsrWifiRouterPriority) 0x0005)
-#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP6      ((CsrWifiRouterPriority) 0x0006)
-#define CSR_WIFI_ROUTER_PRIORITY_QOS_UP7      ((CsrWifiRouterPriority) 0x0007)
-#define CSR_WIFI_ROUTER_PRIORITY_CONTENTION   ((CsrWifiRouterPriority) 0x8000)
-#define CSR_WIFI_ROUTER_PRIORITY_MANAGEMENT   ((CsrWifiRouterPriority) 0x8010)
-
-
-/* Downstream */
-#define CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST            (0x0000)
-
-#define CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_REQ           ((CsrWifiRouterPrim) (0x0000 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_REQ         ((CsrWifiRouterPrim) (0x0001 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_MA_PACKET_REQ                     ((CsrWifiRouterPrim) (0x0002 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_MA_PACKET_RES                     ((CsrWifiRouterPrim) (0x0003 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_MA_PACKET_CANCEL_REQ              ((CsrWifiRouterPrim) (0x0004 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST))
-
-
-#define CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_HIGHEST           (0x0004 + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST)
-
-/* Upstream */
-#define CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST              (0x0000 + CSR_PRIM_UPSTREAM)
-
-#define CSR_WIFI_ROUTER_MA_PACKET_SUBSCRIBE_CFM           ((CsrWifiRouterPrim)(0x0000 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_MA_PACKET_UNSUBSCRIBE_CFM         ((CsrWifiRouterPrim)(0x0001 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_MA_PACKET_CFM                     ((CsrWifiRouterPrim)(0x0002 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_MA_PACKET_IND                     ((CsrWifiRouterPrim)(0x0003 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST))
-
-#define CSR_WIFI_ROUTER_PRIM_UPSTREAM_HIGHEST             (0x0003 + CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST)
-
-#define CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT             (CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST)
-#define CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT               (CSR_WIFI_ROUTER_PRIM_UPSTREAM_HIGHEST   + 1 - CSR_WIFI_ROUTER_PRIM_UPSTREAM_LOWEST)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketSubscribeReq
-
-  DESCRIPTION
-    A task can use this primitive to subscribe for a particular OUI/protocol
-    and transmit and receive frames matching the subscription.
-    NOTE: Multiple subscriptions for a given protocol and OUI will result in
-    the first subscription receiving the data and not the subsequent
-    subscriptions.
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    encapsulation - Specifies the encapsulation type, which will be used for the
-                    subscription
-    protocol      - Together with the OUI, specifies the protocol, which a task
-                    wants to subscribe to
-    oui           - Specifies the OUI for the protocol, which a task wants to
-                    subscribe to
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent            common;
-    u16                  interfaceTag;
-    CsrWifiRouterEncapsulation encapsulation;
-    u16                  protocol;
-    u32                  oui;
-} CsrWifiRouterMaPacketSubscribeReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketUnsubscribeReq
-
-  DESCRIPTION
-    A task sends this primitive to unsubscribe a subscription
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - The handle of the subscription
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    u8        subscriptionHandle;
-} CsrWifiRouterMaPacketUnsubscribeReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketReq
-
-  DESCRIPTION
-    A task sends this primitive to transmit a frame.
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - The handle of the subscription
-    frameLength        - Length of the frame to be sent in bytes
-    frame              - Pointer to the frame to be sent
-    freeFunction       - Pointer to function to be used to free the frame
-    priority           - Priority of the frame, which should be sent
-    hostTag            - An application shall set the bits b31..b28 using one of
-                         the CSR_WIFI_ROUTER_APP_TYPE_* masks. Bits b0..b27 can
-                         be used by the requestor without any restrictions, but
-                         the hostTag shall be unique so the hostTag for
-                         CSR_WIFI_ROUTER_APP _TYPE_OTHER should be constructured
-                         in the following way [ CSR_WIFI_ROUTER_APP_TYPE_OTHER
-                         (4 bits) | SubscriptionHandle (8 bits) | Sequence no.
-                         (20 bits) ]. If the hostTag is not unique, the
-                         behaviour of the system is unpredicatable with respect
-                         to data/management frame transfer.
-    cfmRequested       - Indicates if the requestor needs a confirm for packet
-                         requests sent under this subscription. If set to TRUE,
-                         the router will send a confirm, else it will not send
-                         any confirm
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    u8                       subscriptionHandle;
-    u16                      frameLength;
-    u8                      *frame;
-    CsrWifiRouterFrameFreeFunction freeFunction;
-    CsrWifiRouterPriority          priority;
-    u32                      hostTag;
-    u8                        cfmRequested;
-} CsrWifiRouterMaPacketReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketRes
-
-  DESCRIPTION
-    A task send this primitive to confirm the reception of the received
-    frame.
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - The handle of the subscription
-    result             - Status of the operation
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    u8        subscriptionHandle;
-    CsrResult       result;
-} CsrWifiRouterMaPacketRes;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketCancelReq
-
-  DESCRIPTION
-    This primitive is used to request cancellation of a previously send
-    CsrWifiRouterMaPacketReq.
-    The frame may already have been transmitted so there is no guarantees
-    that the CsrWifiRouterMaPacketCancelReq actually cancels the transmission
-    of the frame in question.
-    If the cancellation fails, the Router will send, if required,
-    CsrWifiRouterMaPacketCfm.
-    If the cancellation succeeds, the Router will not send
-    CsrWifiRouterMaPacketCfm.
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    hostTag        - The hostTag for the frame, which should be cancelled.
-    priority       - Priority of the frame, which should be cancelled
-    peerMacAddress - Destination MAC address of the frame, which should be
-                     cancelled
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    u16             interfaceTag;
-    u32             hostTag;
-    CsrWifiRouterPriority priority;
-    CsrWifiMacAddress     peerMacAddress;
-} CsrWifiRouterMaPacketCancelReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketSubscribeCfm
-
-  DESCRIPTION
-    The router sends this primitive to confirm the result of the
-    subscription.
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - Handle to the subscription
-                         This handle must be used in all subsequent requests
-    status             - Status of the operation
-    allocOffset        - Size of the offset for the frames of the subscription
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    u8        subscriptionHandle;
-    CsrResult       status;
-    u16       allocOffset;
-} CsrWifiRouterMaPacketSubscribeCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketUnsubscribeCfm
-
-  DESCRIPTION
-    The router sends this primitive to confirm the result of the
-    unsubscription.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Status of the operation
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiRouterMaPacketUnsubscribeCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketCfm
-
-  DESCRIPTION
-    The router sends the primitive to confirm the result of the transmission
-    of the packet of the corresponding CSR_WIFI_ROUTER MA_PACKET_REQ request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    result       - Status of the operation
-    hostTag      - The hostTrag will match the hostTag sent in the request.
-    rate         - Transmission/Reception rate
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       result;
-    u32       hostTag;
-    u16       rate;
-} CsrWifiRouterMaPacketCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiRouterMaPacketInd
-
-  DESCRIPTION
-    The router sends the primitive to a subscribed task when it receives a
-    frame matching the subscription.
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    interfaceTag       - Interface Identifier; unique identifier of an interface
-    subscriptionHandle - The handle of the subscription
-    result             - Status of the operation
-    frameLength        - Length of the received frame in bytes
-    frame              - Pointer to the received frame
-    freeFunction       - Pointer to function to be used to free the frame
-    rssi               - Received signal strength indication in dBm
-    snr                - Signal to Noise Ratio
-    rate               - Transmission/Reception rate
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    u16                      interfaceTag;
-    u8                       subscriptionHandle;
-    CsrResult                      result;
-    u16                      frameLength;
-    u8                      *frame;
-    CsrWifiRouterFrameFreeFunction freeFunction;
-    s16                       rssi;
-    s16                       snr;
-    u16                      rate;
-} CsrWifiRouterMaPacketInd;
-
-#endif /* CSR_WIFI_ROUTER_PRIM_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_sef.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_sef.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_sef.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_sef.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-/*****************************************************************************
-
-  (c) Cambridge Silicon Radio Limited 2010
-  Confidential information of CSR
-
-  Refer to LICENSE.txt included with this source for details
-  on the license terms.
-
- *****************************************************************************/
-#include "csr_wifi_router_sef.h"
-
-const CsrWifiRouterStateHandlerType CsrWifiRouterDownstreamStateHandlers[CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT] =
-{
-    /* 0x0000 */ CsrWifiRouterMaPacketSubscribeReqHandler,
-    /* 0x0001 */ CsrWifiRouterMaPacketUnsubscribeReqHandler,
-    /* 0x0002 */ CsrWifiRouterMaPacketReqHandler,
-    /* 0x0003 */ CsrWifiRouterMaPacketResHandler,
-    /* 0x0004 */ CsrWifiRouterMaPacketCancelReqHandler,
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_sef.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_sef.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_sef.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_sef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/*****************************************************************************
-
-  (c) Cambridge Silicon Radio Limited 2010
-  Confidential information of CSR
-
-  Refer to LICENSE.txt included with this source for details
-  on the license terms.
-
- *****************************************************************************/
-#ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_H__
-#define CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_H__
-
-#include "csr_wifi_router_prim.h"
-
-    typedef void (*CsrWifiRouterStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg);
-
-    extern const CsrWifiRouterStateHandlerType CsrWifiRouterDownstreamStateHandlers[CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT];
-
-    extern void CsrWifiRouterMaPacketSubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterMaPacketUnsubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterMaPacketReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-    extern void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
-
-#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_serialize.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_serialize.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_serialize.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_serialize.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,418 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/slab.h>
-#include "csr_msgconv.h"
-#include "csr_wifi_router_prim.h"
-#include "csr_wifi_router_serialize.h"
-
-void CsrWifiRouterPfree(void *ptr)
-{
-    kfree(ptr);
-}
-
-
-size_t CsrWifiRouterMaPacketSubscribeReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 12) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiRouterEncapsulation primitive->encapsulation */
-    bufferSize += 2; /* u16 primitive->protocol */
-    bufferSize += 4; /* u32 primitive->oui */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterMaPacketSubscribeReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterMaPacketSubscribeReq *primitive = (CsrWifiRouterMaPacketSubscribeReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->encapsulation);
-    CsrUint16Ser(ptr, len, (u16) primitive->protocol);
-    CsrUint32Ser(ptr, len, (u32) primitive->oui);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterMaPacketSubscribeReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterMaPacketSubscribeReq *primitive = kmalloc(sizeof(CsrWifiRouterMaPacketSubscribeReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->encapsulation, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->protocol, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->oui, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterMaPacketReqSizeof(void *msg)
-{
-    CsrWifiRouterMaPacketReq *primitive = (CsrWifiRouterMaPacketReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 20) */
-    bufferSize += 2;                      /* u16 primitive->interfaceTag */
-    bufferSize += 1;                      /* u8 primitive->subscriptionHandle */
-    bufferSize += 2;                      /* u16 primitive->frameLength */
-    bufferSize += primitive->frameLength; /* u8 primitive->frame */
-    bufferSize += 4;                      /* CsrWifiRouterFrameFreeFunction primitive->freeFunction */
-    bufferSize += 2;                      /* CsrWifiRouterPriority primitive->priority */
-    bufferSize += 4;                      /* u32 primitive->hostTag */
-    bufferSize += 1;                      /* u8 primitive->cfmRequested */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterMaPacketReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterMaPacketReq *primitive = (CsrWifiRouterMaPacketReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->subscriptionHandle);
-    CsrUint16Ser(ptr, len, (u16) primitive->frameLength);
-    if (primitive->frameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->frame, ((u16) (primitive->frameLength)));
-    }
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->freeFunction */
-    CsrUint16Ser(ptr, len, (u16) primitive->priority);
-    CsrUint32Ser(ptr, len, (u32) primitive->hostTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->cfmRequested);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterMaPacketReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterMaPacketReq *primitive = kmalloc(sizeof(CsrWifiRouterMaPacketReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->subscriptionHandle, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->frameLength, buffer, &offset);
-    if (primitive->frameLength)
-    {
-        primitive->frame = kmalloc(primitive->frameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->frame, buffer, &offset, ((u16) (primitive->frameLength)));
-    }
-    else
-    {
-        primitive->frame = NULL;
-    }
-    primitive->freeFunction = NULL; /* Special for Function Pointers... */
-    offset += 4;
-    CsrUint16Des((u16 *) &primitive->priority, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->hostTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->cfmRequested, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiRouterMaPacketReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterMaPacketReq *primitive = (CsrWifiRouterMaPacketReq *) voidPrimitivePointer;
-    kfree(primitive->frame);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiRouterMaPacketResSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* u8 primitive->subscriptionHandle */
-    bufferSize += 2; /* CsrResult primitive->result */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterMaPacketResSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterMaPacketRes *primitive = (CsrWifiRouterMaPacketRes *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->subscriptionHandle);
-    CsrUint16Ser(ptr, len, (u16) primitive->result);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterMaPacketResDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterMaPacketRes *primitive = kmalloc(sizeof(CsrWifiRouterMaPacketRes), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->subscriptionHandle, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->result, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterMaPacketCancelReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 4; /* u32 primitive->hostTag */
-    bufferSize += 2; /* CsrWifiRouterPriority primitive->priority */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterMaPacketCancelReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterMaPacketCancelReq *primitive = (CsrWifiRouterMaPacketCancelReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint32Ser(ptr, len, (u32) primitive->hostTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->priority);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiRouterMaPacketCancelReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterMaPacketCancelReq *primitive = kmalloc(sizeof(CsrWifiRouterMaPacketCancelReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->hostTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->priority, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterMaPacketSubscribeCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* u8 primitive->subscriptionHandle */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 2; /* u16 primitive->allocOffset */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterMaPacketSubscribeCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterMaPacketSubscribeCfm *primitive = (CsrWifiRouterMaPacketSubscribeCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->subscriptionHandle);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint16Ser(ptr, len, (u16) primitive->allocOffset);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterMaPacketSubscribeCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterMaPacketSubscribeCfm *primitive = kmalloc(sizeof(CsrWifiRouterMaPacketSubscribeCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->subscriptionHandle, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->allocOffset, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterMaPacketUnsubscribeCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterMaPacketUnsubscribeCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterMaPacketUnsubscribeCfm *primitive = (CsrWifiRouterMaPacketUnsubscribeCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterMaPacketUnsubscribeCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterMaPacketUnsubscribeCfm *primitive = kmalloc(sizeof(CsrWifiRouterMaPacketUnsubscribeCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterMaPacketCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->result */
-    bufferSize += 4; /* u32 primitive->hostTag */
-    bufferSize += 2; /* u16 primitive->rate */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterMaPacketCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterMaPacketCfm *primitive = (CsrWifiRouterMaPacketCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->result);
-    CsrUint32Ser(ptr, len, (u32) primitive->hostTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->rate);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterMaPacketCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterMaPacketCfm *primitive = kmalloc(sizeof(CsrWifiRouterMaPacketCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->result, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->hostTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->rate, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiRouterMaPacketIndSizeof(void *msg)
-{
-    CsrWifiRouterMaPacketInd *primitive = (CsrWifiRouterMaPacketInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 21) */
-    bufferSize += 2;                      /* u16 primitive->interfaceTag */
-    bufferSize += 1;                      /* u8 primitive->subscriptionHandle */
-    bufferSize += 2;                      /* CsrResult primitive->result */
-    bufferSize += 2;                      /* u16 primitive->frameLength */
-    bufferSize += primitive->frameLength; /* u8 primitive->frame */
-    bufferSize += 4;                      /* CsrWifiRouterFrameFreeFunction primitive->freeFunction */
-    bufferSize += 2;                      /* s16 primitive->rssi */
-    bufferSize += 2;                      /* s16 primitive->snr */
-    bufferSize += 2;                      /* u16 primitive->rate */
-    return bufferSize;
-}
-
-
-u8* CsrWifiRouterMaPacketIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiRouterMaPacketInd *primitive = (CsrWifiRouterMaPacketInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->subscriptionHandle);
-    CsrUint16Ser(ptr, len, (u16) primitive->result);
-    CsrUint16Ser(ptr, len, (u16) primitive->frameLength);
-    if (primitive->frameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->frame, ((u16) (primitive->frameLength)));
-    }
-    CsrUint32Ser(ptr, len, 0); /* Special for Function Pointers... primitive->freeFunction */
-    CsrUint16Ser(ptr, len, (u16) primitive->rssi);
-    CsrUint16Ser(ptr, len, (u16) primitive->snr);
-    CsrUint16Ser(ptr, len, (u16) primitive->rate);
-    return(ptr);
-}
-
-
-void* CsrWifiRouterMaPacketIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiRouterMaPacketInd *primitive = kmalloc(sizeof(CsrWifiRouterMaPacketInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->subscriptionHandle, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->result, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->frameLength, buffer, &offset);
-    if (primitive->frameLength)
-    {
-        primitive->frame = kmalloc(primitive->frameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->frame, buffer, &offset, ((u16) (primitive->frameLength)));
-    }
-    else
-    {
-        primitive->frame = NULL;
-    }
-    primitive->freeFunction = NULL; /* Special for Function Pointers... */
-    offset += 4;
-    CsrUint16Des((u16 *) &primitive->rssi, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->snr, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->rate, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiRouterMaPacketIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiRouterMaPacketInd *primitive = (CsrWifiRouterMaPacketInd *) voidPrimitivePointer;
-    kfree(primitive->frame);
-    kfree(primitive);
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_serialize.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_serialize.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_serialize.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_serialize.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,67 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_ROUTER_SERIALIZE_H__
-#define CSR_WIFI_ROUTER_SERIALIZE_H__
-
-#include "csr_wifi_msgconv.h"
-#include "csr_wifi_router_prim.h"
-
-extern void CsrWifiRouterPfree(void *ptr);
-
-extern u8* CsrWifiRouterMaPacketSubscribeReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterMaPacketSubscribeReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterMaPacketSubscribeReqSizeof(void *msg);
-#define CsrWifiRouterMaPacketSubscribeReqSerFree CsrWifiRouterPfree
-
-#define CsrWifiRouterMaPacketUnsubscribeReqSer CsrWifiEventCsrUint16CsrUint8Ser
-#define CsrWifiRouterMaPacketUnsubscribeReqDes CsrWifiEventCsrUint16CsrUint8Des
-#define CsrWifiRouterMaPacketUnsubscribeReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
-#define CsrWifiRouterMaPacketUnsubscribeReqSerFree CsrWifiRouterPfree
-
-extern u8* CsrWifiRouterMaPacketReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterMaPacketReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterMaPacketReqSizeof(void *msg);
-extern void CsrWifiRouterMaPacketReqSerFree(void *msg);
-
-extern u8* CsrWifiRouterMaPacketResSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterMaPacketResDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterMaPacketResSizeof(void *msg);
-#define CsrWifiRouterMaPacketResSerFree CsrWifiRouterPfree
-
-extern u8* CsrWifiRouterMaPacketCancelReqSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterMaPacketCancelReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterMaPacketCancelReqSizeof(void *msg);
-#define CsrWifiRouterMaPacketCancelReqSerFree CsrWifiRouterPfree
-
-extern u8* CsrWifiRouterMaPacketSubscribeCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterMaPacketSubscribeCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterMaPacketSubscribeCfmSizeof(void *msg);
-#define CsrWifiRouterMaPacketSubscribeCfmSerFree CsrWifiRouterPfree
-
-extern u8* CsrWifiRouterMaPacketUnsubscribeCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterMaPacketUnsubscribeCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterMaPacketUnsubscribeCfmSizeof(void *msg);
-#define CsrWifiRouterMaPacketUnsubscribeCfmSerFree CsrWifiRouterPfree
-
-extern u8* CsrWifiRouterMaPacketCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterMaPacketCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterMaPacketCfmSizeof(void *msg);
-#define CsrWifiRouterMaPacketCfmSerFree CsrWifiRouterPfree
-
-extern u8* CsrWifiRouterMaPacketIndSer(u8 *ptr, size_t *len, void *msg);
-extern void* CsrWifiRouterMaPacketIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiRouterMaPacketIndSizeof(void *msg);
-extern void CsrWifiRouterMaPacketIndSerFree(void *msg);
-
-#endif /* CSR_WIFI_ROUTER_SERIALIZE_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_task.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_task.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_task.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_task.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_ROUTER_TASK_H__
-#define CSR_WIFI_ROUTER_TASK_H__
-
-#include "csr_sched.h"
-
-#define CSR_WIFI_ROUTER_LOG_ID 0x1201FFFF
-extern CsrSchedQid CSR_WIFI_ROUTER_IFACEQUEUE;
-void CsrWifiRouterInit(void **gash);
-void CsrWifiRouterDeinit(void **gash);
-void CsrWifiRouterHandler(void **gash);
-
-#endif /* CSR_WIFI_ROUTER_TASK_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_transport.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_transport.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_router_transport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_router_transport.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,199 +0,0 @@
-/** @file router_transport.c
- *
- *
- * Copyright (C) Cambridge Silicon Radio Ltd 2006-2010. All rights reserved.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- ****************************************************************************/
-
-#include "unifi_priv.h"
-
-#include "csr_sched.h"
-#include "csr_msgconv.h"
-
-#include "sme_userspace.h"
-
-#include "csr_wifi_hostio_prim.h"
-#include "csr_wifi_router_lib.h"
-#include "csr_wifi_router_sef.h"
-#include "csr_wifi_router_converter_init.h"
-#include "csr_wifi_router_ctrl_lib.h"
-#include "csr_wifi_router_ctrl_sef.h"
-#include "csr_wifi_router_ctrl_converter_init.h"
-#include "csr_wifi_sme_prim.h"
-#include "csr_wifi_sme_sef.h"
-#include "csr_wifi_sme_converter_init.h"
-#ifdef CSR_SUPPORT_WEXT
-#ifdef CSR_SUPPORT_WEXT_AP
-#include "csr_wifi_nme_ap_prim.h"
-#include "csr_wifi_nme_ap_sef.h"
-#include "csr_wifi_nme_ap_converter_init.h"
-#endif
-#endif
-
-static unifi_priv_t *drvpriv = NULL;
-void CsrWifiRouterTransportInit(unifi_priv_t *priv)
-{
-    unifi_trace(priv, UDBG1, "CsrWifiRouterTransportInit: \n");
-
-    drvpriv = priv;
-    (void)CsrMsgConvInit();
-    CsrWifiRouterConverterInit();
-    CsrWifiRouterCtrlConverterInit();
-    CsrWifiSmeConverterInit();
-#ifdef CSR_SUPPORT_WEXT
-#ifdef CSR_SUPPORT_WEXT_AP
-    CsrWifiNmeApConverterInit();
-#endif
-#endif
-}
-
-void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8* buffer, size_t bufferLength)
-{
-    CsrMsgConvMsgEntry* msgEntry;
-    u16 primType;
-    CsrSchedQid src;
-    CsrSchedQid dest;
-    u16 msgType;
-    size_t offset = 0;
-    CsrWifiFsmEvent* msg;
-
-    /* Decode the prim and message type */
-    CsrUint16Des(&primType, buffer, &offset);
-    CsrUint16Des(&src, buffer, &offset);
-    CsrUint16Des(&dest, buffer, &offset);
-    CsrUint16Des(&msgType, buffer, &offset);
-    offset -= 2; /* Adjust as the Deserialise Function will read this as well */
-
-    unifi_trace(priv, UDBG4, "CsrWifiRouterTransportRecv: primType=0x%.4X, msgType=0x%.4X, bufferLength=%d\n",
-                primType, msgType, bufferLength);
-
-    /* Special handling for HOSTIO messages.... */
-    if (primType == CSR_WIFI_HOSTIO_PRIM)
-    {
-        CsrWifiRouterCtrlHipReq req = {{CSR_WIFI_ROUTER_CTRL_HIP_REQ, CSR_WIFI_ROUTER_CTRL_PRIM, dest, src, NULL}, 0, NULL, 0, NULL, 0, NULL};
-
-        req.mlmeCommandLength = bufferLength;
-        req.mlmeCommand = buffer;
-
-        offset += 8;/* Skip the id, src, dest and slot number */
-        CsrUint16Des(&req.dataRef1Length, buffer, &offset);
-        offset += 2; /* Skip the slot number */
-        CsrUint16Des(&req.dataRef2Length, buffer, &offset);
-
-        if (req.dataRef1Length)
-        {
-            u16 dr1Offset = (bufferLength - req.dataRef2Length) - req.dataRef1Length;
-            req.dataRef1 = &buffer[dr1Offset];
-        }
-
-        if (req.dataRef2Length)
-        {
-            u16 dr2Offset = bufferLength - req.dataRef2Length;
-            req.dataRef2 = &buffer[dr2Offset];
-        }
-
-        /* Copy the hip data but strip off the prim type */
-        req.mlmeCommandLength -= (req.dataRef1Length + req.dataRef2Length + 6);
-        req.mlmeCommand = &buffer[6];
-
-        CsrWifiRouterCtrlHipReqHandler(priv, &req.common);
-        return;
-    }
-
-    msgEntry = CsrMsgConvFindEntry(primType, msgType);
-    if (!msgEntry)
-    {
-        unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n",
-                    primType, msgType);
-        dump(buffer, bufferLength);
-        return;
-    }
-
-    msg = (CsrWifiFsmEvent*)(msgEntry->deserFunc)(&buffer[offset], bufferLength - offset);
-
-    msg->primtype = primType;
-    msg->type = msgType;
-    msg->source = src;
-    msg->destination = dest;
-
-    switch(primType)
-    {
-    case CSR_WIFI_ROUTER_CTRL_PRIM:
-        CsrWifiRouterCtrlDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST](priv, msg);
-        CsrWifiRouterCtrlFreeDownstreamMessageContents(CSR_WIFI_ROUTER_CTRL_PRIM, msg);
-        break;
-    case CSR_WIFI_ROUTER_PRIM:
-        CsrWifiRouterDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST](priv, msg);
-        CsrWifiRouterFreeDownstreamMessageContents(CSR_WIFI_ROUTER_PRIM, msg);
-        break;
-        case CSR_WIFI_SME_PRIM:
-            CsrWifiSmeUpstreamStateHandlers[msg->type - CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST](priv, msg);
-            CsrWifiSmeFreeUpstreamMessageContents(CSR_WIFI_SME_PRIM, msg);
-            break;
-#ifdef CSR_SUPPORT_WEXT
-#ifdef CSR_SUPPORT_WEXT_AP
-        case CSR_WIFI_NME_AP_PRIM:
-            CsrWifiNmeApUpstreamStateHandlers(priv, msg);
-            CsrWifiNmeApFreeUpstreamMessageContents(CSR_WIFI_NME_AP_PRIM, msg);
-            break;
-#endif
-#endif
-        default:
-            unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend unhandled prim type 0x%.4X\n", primType);
-            break;
-    }
-    kfree(msg);
-}
-
-static void CsrWifiRouterTransportSerialiseAndSend(u16 primType, void* msg)
-{
-    CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)msg;
-    CsrMsgConvMsgEntry* msgEntry;
-    size_t msgSize;
-    size_t encodeBufferLen = 0;
-    size_t offset = 0;
-    u8* encodeBuffer;
-
-    unifi_trace(drvpriv, UDBG4, "CsrWifiRouterTransportSerialiseAndSend: primType=0x%.4X, msgType=0x%.4X\n",
-                primType, evt->type);
-
-    msgEntry = CsrMsgConvFindEntry(primType, evt->type);
-    if (!msgEntry)
-    {
-        unifi_error(drvpriv, "CsrWifiRouterTransportSerialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n",
-                    primType, evt->type);
-        return;
-    }
-
-    msgSize = 6 + (msgEntry->sizeofFunc)((void*)msg);
-
-    encodeBuffer = kmalloc(msgSize, GFP_KERNEL);
-
-    /* Encode PrimType */
-    CsrUint16Ser(encodeBuffer, &encodeBufferLen, primType);
-    CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->source);
-    CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->destination);
-
-    (void)(msgEntry->serFunc)(&encodeBuffer[encodeBufferLen], &offset, msg);
-    encodeBufferLen += offset;
-
-    uf_sme_queue_message(drvpriv, encodeBuffer, encodeBufferLen);
-
-    /* Do not use msgEntry->freeFunc because the memory is owned by the driver */
-    kfree(msg);
-}
-
-#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER)
-void CsrSchedMessagePutStringLog(CsrSchedQid q, u16 mi, void *mv, u32 line, char *file)
-#else
-void CsrSchedMessagePut(CsrSchedQid q, u16 mi, void *mv)
-#endif
-{
-    CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)mv;
-    evt->destination = q;
-    CsrWifiRouterTransportSerialiseAndSend(mi, mv);
-}
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_serialize_primitive_types.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_serialize_primitive_types.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_serialize_primitive_types.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_serialize_primitive_types.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,256 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include "csr_macro.h"
-#include "csr_msgconv.h"
-#include "csr_wifi_msgconv.h"
-#include "csr_wifi_lib.h"
-
-void CsrUint24Des(u32 *v, u8 *buffer, size_t *offset)
-{
-    u32 val;
-
-    val = ((buffer[(*offset) + 2] << 16) |
-           (buffer[(*offset) + 1] << 8) |
-           (buffer[(*offset)]));
-
-    *offset += 3;
-    *v = val;
-}
-
-
-/* Big endian :e.g WSC, TCLAS */
-void CsrUint16DesBigEndian(u16 *v, u8 *buffer, size_t *offset)
-{
-    u16 val;
-
-    val = (buffer[(*offset)] << 8) | (buffer[(*offset) + 1]);
-    *offset += 2;
-
-    *v = val;
-}
-
-
-void CsrUint24DesBigEndian(u32 *v, u8 *buffer, size_t *offset)
-{
-    u32 val;
-
-    val = ((buffer[(*offset)] << 16) |
-           (buffer[(*offset) + 1] << 8) |
-           (buffer[(*offset) + 2]));
-
-    *offset += 3;
-    *v = val;
-}
-
-
-void CsrUint32DesBigEndian(u32 *v, u8 *buffer, size_t *offset)
-{
-    u32 val;
-
-    val = ((buffer[(*offset)] << 24) |
-           (buffer[(*offset) + 1] << 16) |
-           (buffer[(*offset) + 2] << 8) |
-           (buffer[(*offset) + 3]));
-
-    *offset += 4;
-    *v = val;
-}
-
-
-void CsrUint24Ser(u8 *ptr, size_t *len, u32 v)
-{
-    ptr[(*len) + 2] = (u8)((v & 0x00ff0000) >> 16);
-    ptr[(*len) + 1] = (u8)((v & 0x0000ff00) >> 8);
-    ptr[(*len)]     = (u8)((v & 0x000000ff));
-
-    *len += 3;
-}
-
-
-/* Big endian :e.g WSC, TCLAS */
-void CsrUint16SerBigEndian(u8 *ptr, size_t *len, u16 v)
-{
-    ptr[(*len)] = (u8)((v & 0xff00) >> 8);
-    ptr[(*len) + 1] = (u8)((v & 0x00ff));
-
-    *len += 2;
-}
-
-
-void CsrUint32SerBigEndian(u8 *ptr, size_t *len, u32 v)
-{
-    ptr[(*len)] = (u8)((v & 0xff000000) >> 24);
-    ptr[(*len) + 1] = (u8)((v & 0x00ff0000) >> 16);
-    ptr[(*len) + 2] = (u8)((v & 0x0000ff00) >> 8);
-    ptr[(*len) + 3] = (u8)((v & 0x000000ff));
-
-    *len += 4;
-}
-
-
-void CsrUint24SerBigEndian(u8 *ptr, size_t *len, u32 v)
-{
-    ptr[(*len)] = (u8)((v & 0x00ff0000) >> 16);
-    ptr[(*len) + 1] = (u8)((v & 0x0000ff00) >> 8);
-    ptr[(*len) + 2] = (u8)((v & 0x000000ff));
-
-    *len += 3;
-}
-
-
-size_t CsrWifiEventSizeof(void *msg)
-{
-    return 2;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventSizeof);
-
-u8* CsrWifiEventSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiFsmEvent *primitive = (CsrWifiFsmEvent *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->type);
-    return(ptr);
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventSer);
-
-void* CsrWifiEventDes(u8 *buffer, size_t length)
-{
-    CsrWifiFsmEvent *primitive = kmalloc(sizeof(CsrWifiFsmEvent), GFP_KERNEL);
-    size_t offset = 0;
-    CsrUint16Des(&primitive->type, buffer, &offset);
-
-    return primitive;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventDes);
-
-size_t CsrWifiEventCsrUint8Sizeof(void *msg)
-{
-    return 3;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint8Sizeof);
-
-u8* CsrWifiEventCsrUint8Ser(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiEventCsrUint8 *primitive = (CsrWifiEventCsrUint8 *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint8Ser(ptr, len, primitive->value);
-    return(ptr);
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint8Ser);
-
-
-void* CsrWifiEventCsrUint8Des(u8 *buffer, size_t length)
-{
-    CsrWifiEventCsrUint8 *primitive = kmalloc(sizeof(CsrWifiEventCsrUint8), GFP_KERNEL);
-
-    size_t offset = 0;
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint8Des(&primitive->value, buffer, &offset);
-
-    return primitive;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint8Des);
-
-
-size_t CsrWifiEventCsrUint16Sizeof(void *msg)
-{
-    return 4;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16Sizeof);
-
-
-u8* CsrWifiEventCsrUint16Ser(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiEventCsrUint16 *primitive = (CsrWifiEventCsrUint16 *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, primitive->value);
-    return(ptr);
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16Ser);
-
-void* CsrWifiEventCsrUint16Des(u8 *buffer, size_t length)
-{
-    CsrWifiEventCsrUint16 *primitive = kmalloc(sizeof(CsrWifiEventCsrUint16), GFP_KERNEL);
-
-    size_t offset = 0;
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des(&primitive->value, buffer, &offset);
-
-    return primitive;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16Des);
-
-
-size_t CsrWifiEventCsrUint32Sizeof(void *msg)
-{
-    return 6;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint32Sizeof);
-
-u8* CsrWifiEventCsrUint32Ser(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiEventCsrUint32 *primitive = (CsrWifiEventCsrUint32 *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint32Ser(ptr, len, primitive->value);
-    return(ptr);
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint32Ser);
-
-
-void* CsrWifiEventCsrUint32Des(u8 *buffer, size_t length)
-{
-    CsrWifiEventCsrUint32 *primitive = kmalloc(sizeof(CsrWifiEventCsrUint32), GFP_KERNEL);
-
-    size_t offset = 0;
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint32Des(&primitive->value, buffer, &offset);
-
-    return primitive;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint32Des);
-
-size_t CsrWifiEventCsrUint16CsrUint8Sizeof(void *msg)
-{
-    return 5;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16CsrUint8Sizeof);
-
-u8* CsrWifiEventCsrUint16CsrUint8Ser(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiEventCsrUint16CsrUint8 *primitive = (CsrWifiEventCsrUint16CsrUint8 *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, primitive->value16);
-    CsrUint8Ser(ptr, len, primitive->value8);
-    return(ptr);
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16CsrUint8Ser);
-
-
-void* CsrWifiEventCsrUint16CsrUint8Des(u8 *buffer, size_t length)
-{
-    CsrWifiEventCsrUint16CsrUint8 *primitive = kmalloc(sizeof(CsrWifiEventCsrUint16CsrUint8), GFP_KERNEL);
-
-    size_t offset = 0;
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des(&primitive->value16, buffer, &offset);
-    CsrUint8Des(&primitive->value8, buffer, &offset);
-
-    return primitive;
-}
-EXPORT_SYMBOL_GPL(CsrWifiEventCsrUint16CsrUint8Des);
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_ap_lib.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_ap_lib.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_ap_lib.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_ap_lib.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,774 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_SME_AP_LIB_H__
-#define CSR_WIFI_SME_AP_LIB_H__
-
-#include "csr_sched.h"
-#include "csr_macro.h"
-#include "csr_msg_transport.h"
-
-#include "csr_wifi_lib.h"
-
-#include "csr_wifi_sme_ap_prim.h"
-#include "csr_wifi_sme_task.h"
-
-#ifndef CSR_WIFI_AP_ENABLE
-#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_sme_ap_lib.h
-#endif
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiSmeApFreeUpstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_SME_AP upstream message. Does not
- *      free the message itself, and can only be used for upstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_SME_AP upstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiSmeApFreeUpstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiSmeApFreeDownstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_SME_AP downstream message. Does not
- *      free the message itself, and can only be used for downstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_SME_AP downstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiSmeApFreeDownstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- * Enum to string functions
- *----------------------------------------------------------------------------*/
-const char* CsrWifiSmeApAccessTypeToString(CsrWifiSmeApAccessType value);
-const char* CsrWifiSmeApAuthSupportToString(CsrWifiSmeApAuthSupport value);
-const char* CsrWifiSmeApAuthTypeToString(CsrWifiSmeApAuthType value);
-const char* CsrWifiSmeApDirectionToString(CsrWifiSmeApDirection value);
-const char* CsrWifiSmeApPhySupportToString(CsrWifiSmeApPhySupport value);
-const char* CsrWifiSmeApTypeToString(CsrWifiSmeApType value);
-
-
-/*----------------------------------------------------------------------------*
- * CsrPrim Type toString function.
- * Converts a message type to the String name of the Message
- *----------------------------------------------------------------------------*/
-const char* CsrWifiSmeApPrimTypeToString(CsrPrim msgType);
-
-/*----------------------------------------------------------------------------*
- * Lookup arrays for PrimType name Strings
- *----------------------------------------------------------------------------*/
-extern const char *CsrWifiSmeApUpstreamPrimNames[CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT];
-extern const char *CsrWifiSmeApDownstreamPrimNames[CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT];
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApActiveBaGetReqSend
-
-  DESCRIPTION
-    This primitive used to retrieve information related to the active block
-    ack sessions
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-
-*******************************************************************************/
-#define CsrWifiSmeApActiveBaGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApActiveBaGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ACTIVE_BA_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeApActiveBaGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeApActiveBaGetReq *msg__; \
-        CsrWifiSmeApActiveBaGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApActiveBaGetReqSend(src__, interfaceTag__) \
-    CsrWifiSmeApActiveBaGetReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApActiveBaGetCfmSend
-
-  DESCRIPTION
-    This primitive carries the information related to the active ba sessions
-
-  PARAMETERS
-    queue            - Destination Task Queue
-    interfaceTag     -
-    status           - Reports the result of the request
-    activeBaCount    - Number of active block ack session
-    activeBaSessions - Points to a buffer containing an array of
-                       CsrWifiSmeApBaSession structures.
-
-*******************************************************************************/
-#define CsrWifiSmeApActiveBaGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApActiveBaGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ACTIVE_BA_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->activeBaCount = (activeBaCount__); \
-    msg__->activeBaSessions = (activeBaSessions__);
-
-#define CsrWifiSmeApActiveBaGetCfmSendTo(dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \
-    { \
-        CsrWifiSmeApActiveBaGetCfm *msg__; \
-        CsrWifiSmeApActiveBaGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApActiveBaGetCfmSend(dst__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \
-    CsrWifiSmeApActiveBaGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, activeBaCount__, activeBaSessions__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBaDeleteReqSend
-
-  DESCRIPTION
-    This primitive is used to delete an active block ack session
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-    reason       -
-    baSession    - BA session to be deleted
-
-*******************************************************************************/
-#define CsrWifiSmeApBaDeleteReqCreate(msg__, dst__, src__, interfaceTag__, reason__, baSession__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApBaDeleteReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BA_DELETE_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->reason = (reason__); \
-    msg__->baSession = (baSession__);
-
-#define CsrWifiSmeApBaDeleteReqSendTo(dst__, src__, interfaceTag__, reason__, baSession__) \
-    { \
-        CsrWifiSmeApBaDeleteReq *msg__; \
-        CsrWifiSmeApBaDeleteReqCreate(msg__, dst__, src__, interfaceTag__, reason__, baSession__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApBaDeleteReqSend(src__, interfaceTag__, reason__, baSession__) \
-    CsrWifiSmeApBaDeleteReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, reason__, baSession__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBaDeleteCfmSend
-
-  DESCRIPTION
-    This primitive confirms the BA is deleted
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag -
-    status       - Reports the result of the request
-    baSession    - deleted BA session
-
-*******************************************************************************/
-#define CsrWifiSmeApBaDeleteCfmCreate(msg__, dst__, src__, interfaceTag__, status__, baSession__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApBaDeleteCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BA_DELETE_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->baSession = (baSession__);
-
-#define CsrWifiSmeApBaDeleteCfmSendTo(dst__, src__, interfaceTag__, status__, baSession__) \
-    { \
-        CsrWifiSmeApBaDeleteCfm *msg__; \
-        CsrWifiSmeApBaDeleteCfmCreate(msg__, dst__, src__, interfaceTag__, status__, baSession__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApBaDeleteCfmSend(dst__, interfaceTag__, status__, baSession__) \
-    CsrWifiSmeApBaDeleteCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, baSession__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBeaconingStartReqSend
-
-  DESCRIPTION
-    This primitive requests the SME to start AP or GO functionality
-
-  PARAMETERS
-    queue           - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag    -
-    initialPresence - Set to 0, if Not in a group fomration phase, set to 1 ,
-                      during group formation phase
-    apType          - apType : Legacy AP or P2PGO
-    cloakSsid       - cloakSsid flag.
-    ssid            - ssid.
-    ifIndex         - Radio Interface
-    channel         - channel.
-    maxConnections  - Maximum Stations + P2PClients allowed
-    apCredentials   - AP security credeitals used to advertise in beacon /probe
-                      response
-    smeApConfig     - AP configuration
-    p2pGoParam      - P2P specific GO parameters. Ignored if it is a leagacy AP
-
-*******************************************************************************/
-#define CsrWifiSmeApBeaconingStartReqCreate(msg__, dst__, src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApBeaconingStartReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BEACONING_START_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->initialPresence = (initialPresence__); \
-    msg__->apType = (apType__); \
-    msg__->cloakSsid = (cloakSsid__); \
-    msg__->ssid = (ssid__); \
-    msg__->ifIndex = (ifIndex__); \
-    msg__->channel = (channel__); \
-    msg__->maxConnections = (maxConnections__); \
-    msg__->apCredentials = (apCredentials__); \
-    msg__->smeApConfig = (smeApConfig__); \
-    msg__->p2pGoParam = (p2pGoParam__);
-
-#define CsrWifiSmeApBeaconingStartReqSendTo(dst__, src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__) \
-    { \
-        CsrWifiSmeApBeaconingStartReq *msg__; \
-        CsrWifiSmeApBeaconingStartReqCreate(msg__, dst__, src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApBeaconingStartReqSend(src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__) \
-    CsrWifiSmeApBeaconingStartReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, initialPresence__, apType__, cloakSsid__, ssid__, ifIndex__, channel__, maxConnections__, apCredentials__, smeApConfig__, p2pGoParam__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBeaconingStartCfmSend
-
-  DESCRIPTION
-    This primitive confirms the completion of the request along with the
-    status
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag -
-    status       -
-    secIeLength  -
-    secIe        -
-
-*******************************************************************************/
-#define CsrWifiSmeApBeaconingStartCfmCreate(msg__, dst__, src__, interfaceTag__, status__, secIeLength__, secIe__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApBeaconingStartCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BEACONING_START_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->secIeLength = (secIeLength__); \
-    msg__->secIe = (secIe__);
-
-#define CsrWifiSmeApBeaconingStartCfmSendTo(dst__, src__, interfaceTag__, status__, secIeLength__, secIe__) \
-    { \
-        CsrWifiSmeApBeaconingStartCfm *msg__; \
-        CsrWifiSmeApBeaconingStartCfmCreate(msg__, dst__, src__, interfaceTag__, status__, secIeLength__, secIe__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApBeaconingStartCfmSend(dst__, interfaceTag__, status__, secIeLength__, secIe__) \
-    CsrWifiSmeApBeaconingStartCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, secIeLength__, secIe__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBeaconingStopReqSend
-
-  DESCRIPTION
-    This primitive requests the SME to STOP AP or P2PGO operation
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-
-*******************************************************************************/
-#define CsrWifiSmeApBeaconingStopReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApBeaconingStopReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BEACONING_STOP_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeApBeaconingStopReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeApBeaconingStopReq *msg__; \
-        CsrWifiSmeApBeaconingStopReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApBeaconingStopReqSend(src__, interfaceTag__) \
-    CsrWifiSmeApBeaconingStopReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBeaconingStopCfmSend
-
-  DESCRIPTION
-    This primitive confirms AP or P2PGO operation is terminated
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiSmeApBeaconingStopCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApBeaconingStopCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BEACONING_STOP_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeApBeaconingStopCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeApBeaconingStopCfm *msg__; \
-        CsrWifiSmeApBeaconingStopCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApBeaconingStopCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeApBeaconingStopCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApErrorIndSend
-
-  DESCRIPTION
-    This primitve is sent by SME to indicate some error in AP operationi
-    after AP operations were started successfully and continuing the AP
-    operation may lead to undesired behaviour. It is the responsibility of
-    the upper layers to stop AP operation if needed
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Range 0-1
-    apType       -
-    status       - Contains the error status
-
-*******************************************************************************/
-#define CsrWifiSmeApErrorIndCreate(msg__, dst__, src__, interfaceTag__, apType__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApErrorInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ERROR_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->apType = (apType__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeApErrorIndSendTo(dst__, src__, interfaceTag__, apType__, status__) \
-    { \
-        CsrWifiSmeApErrorInd *msg__; \
-        CsrWifiSmeApErrorIndCreate(msg__, dst__, src__, interfaceTag__, apType__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApErrorIndSend(dst__, interfaceTag__, apType__, status__) \
-    CsrWifiSmeApErrorIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, apType__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApStaConnectStartIndSend
-
-  DESCRIPTION
-    This primitive indicates that a stations request to join the group/BSS is
-    accepted
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    interfaceTag   -
-    peerMacAddress -
-
-*******************************************************************************/
-#define CsrWifiSmeApStaConnectStartIndCreate(msg__, dst__, src__, interfaceTag__, peerMacAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApStaConnectStartInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_STA_CONNECT_START_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->peerMacAddress = (peerMacAddress__);
-
-#define CsrWifiSmeApStaConnectStartIndSendTo(dst__, src__, interfaceTag__, peerMacAddress__) \
-    { \
-        CsrWifiSmeApStaConnectStartInd *msg__; \
-        CsrWifiSmeApStaConnectStartIndCreate(msg__, dst__, src__, interfaceTag__, peerMacAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApStaConnectStartIndSend(dst__, interfaceTag__, peerMacAddress__) \
-    CsrWifiSmeApStaConnectStartIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, peerMacAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApStaDisconnectReqSend
-
-  DESCRIPTION
-    This primitive tells SME to deauth ot disassociate a particular station
-    within BSS
-
-  PARAMETERS
-    queue          - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag   -
-    deauthReason   -
-    disassocReason -
-    peerMacaddress -
-    keepBlocking   - If TRUE, the station is blocked. If FALSE and the station
-                     is connected, disconnect the station. If FALSE and the
-                     station is not connected, no action is taken.
-
-*******************************************************************************/
-#define CsrWifiSmeApStaDisconnectReqCreate(msg__, dst__, src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApStaDisconnectReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_STA_DISCONNECT_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->deauthReason = (deauthReason__); \
-    msg__->disassocReason = (disassocReason__); \
-    msg__->peerMacaddress = (peerMacaddress__); \
-    msg__->keepBlocking = (keepBlocking__);
-
-#define CsrWifiSmeApStaDisconnectReqSendTo(dst__, src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__) \
-    { \
-        CsrWifiSmeApStaDisconnectReq *msg__; \
-        CsrWifiSmeApStaDisconnectReqCreate(msg__, dst__, src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApStaDisconnectReqSend(src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__) \
-    CsrWifiSmeApStaDisconnectReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, deauthReason__, disassocReason__, peerMacaddress__, keepBlocking__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApStaDisconnectCfmSend
-
-  DESCRIPTION
-    This primitive confirms the station is disconnected
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    interfaceTag   -
-    status         -
-    peerMacaddress -
-
-*******************************************************************************/
-#define CsrWifiSmeApStaDisconnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__, peerMacaddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApStaDisconnectCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_STA_DISCONNECT_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->peerMacaddress = (peerMacaddress__);
-
-#define CsrWifiSmeApStaDisconnectCfmSendTo(dst__, src__, interfaceTag__, status__, peerMacaddress__) \
-    { \
-        CsrWifiSmeApStaDisconnectCfm *msg__; \
-        CsrWifiSmeApStaDisconnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__, peerMacaddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApStaDisconnectCfmSend(dst__, interfaceTag__, status__, peerMacaddress__) \
-    CsrWifiSmeApStaDisconnectCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, peerMacaddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApStaNotifyIndSend
-
-  DESCRIPTION
-    This primitive indicates that a station has joined or a previously joined
-    station has left the BSS/group
-
-  PARAMETERS
-    queue             - Destination Task Queue
-    interfaceTag      -
-    mediaStatus       -
-    peerMacAddress    -
-    peerDeviceAddress -
-    disassocReason    -
-    deauthReason      -
-    WpsRegistration   -
-    secIeLength       -
-    secIe             -
-    groupKeyId        -
-    seqNumber         -
-
-*******************************************************************************/
-#define CsrWifiSmeApStaNotifyIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApStaNotifyInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_STA_NOTIFY_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->mediaStatus = (mediaStatus__); \
-    msg__->peerMacAddress = (peerMacAddress__); \
-    msg__->peerDeviceAddress = (peerDeviceAddress__); \
-    msg__->disassocReason = (disassocReason__); \
-    msg__->deauthReason = (deauthReason__); \
-    msg__->WpsRegistration = (WpsRegistration__); \
-    msg__->secIeLength = (secIeLength__); \
-    msg__->secIe = (secIe__); \
-    msg__->groupKeyId = (groupKeyId__); \
-    memcpy(msg__->seqNumber, (seqNumber__), sizeof(u16) * 8);
-
-#define CsrWifiSmeApStaNotifyIndSendTo(dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__) \
-    { \
-        CsrWifiSmeApStaNotifyInd *msg__; \
-        CsrWifiSmeApStaNotifyIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApStaNotifyIndSend(dst__, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__) \
-    CsrWifiSmeApStaNotifyIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, mediaStatus__, peerMacAddress__, peerDeviceAddress__, disassocReason__, deauthReason__, WpsRegistration__, secIeLength__, secIe__, groupKeyId__, seqNumber__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWmmParamUpdateReqSend
-
-  DESCRIPTION
-    Application uses this primitive to update the WMM parameters on the fly
-
-  PARAMETERS
-    queue         - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag  -
-    wmmApParams   - WMM parameters to be used for local firmware queue
-                    configuration
-    wmmApBcParams - WMM parameters to be advertised in beacon/probe response
-
-*******************************************************************************/
-#define CsrWifiSmeApWmmParamUpdateReqCreate(msg__, dst__, src__, interfaceTag__, wmmApParams__, wmmApBcParams__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApWmmParamUpdateReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    memcpy(msg__->wmmApParams, (wmmApParams__), sizeof(CsrWifiSmeWmmAcParams) * 4); \
-    memcpy(msg__->wmmApBcParams, (wmmApBcParams__), sizeof(CsrWifiSmeWmmAcParams) * 4);
-
-#define CsrWifiSmeApWmmParamUpdateReqSendTo(dst__, src__, interfaceTag__, wmmApParams__, wmmApBcParams__) \
-    { \
-        CsrWifiSmeApWmmParamUpdateReq *msg__; \
-        CsrWifiSmeApWmmParamUpdateReqCreate(msg__, dst__, src__, interfaceTag__, wmmApParams__, wmmApBcParams__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApWmmParamUpdateReqSend(src__, interfaceTag__, wmmApParams__, wmmApBcParams__) \
-    CsrWifiSmeApWmmParamUpdateReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, wmmApParams__, wmmApBcParams__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWmmParamUpdateCfmSend
-
-  DESCRIPTION
-    A confirm for CSR_WIFI_SME_AP_WMM_PARAM_UPDATE.request
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiSmeApWmmParamUpdateCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApWmmParamUpdateCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeApWmmParamUpdateCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeApWmmParamUpdateCfm *msg__; \
-        CsrWifiSmeApWmmParamUpdateCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApWmmParamUpdateCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeApWmmParamUpdateCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsConfigurationReqSend
-
-  DESCRIPTION
-    This primitive passes the WPS information for the device to SME. This may
-    be accepted only if no interface is active.
-
-  PARAMETERS
-    queue     - Message Source Task Queue (Cfm's will be sent to this Queue)
-    wpsConfig - WPS config.
-
-*******************************************************************************/
-#define CsrWifiSmeApWpsConfigurationReqCreate(msg__, dst__, src__, wpsConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApWpsConfigurationReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_CONFIGURATION_REQ, dst__, src__); \
-    msg__->wpsConfig = (wpsConfig__);
-
-#define CsrWifiSmeApWpsConfigurationReqSendTo(dst__, src__, wpsConfig__) \
-    { \
-        CsrWifiSmeApWpsConfigurationReq *msg__; \
-        CsrWifiSmeApWpsConfigurationReqCreate(msg__, dst__, src__, wpsConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApWpsConfigurationReqSend(src__, wpsConfig__) \
-    CsrWifiSmeApWpsConfigurationReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, wpsConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsConfigurationCfmSend
-
-  DESCRIPTION
-    Confirm.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Status of the request.
-
-*******************************************************************************/
-#define CsrWifiSmeApWpsConfigurationCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApWpsConfigurationCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_CONFIGURATION_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeApWpsConfigurationCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeApWpsConfigurationCfm *msg__; \
-        CsrWifiSmeApWpsConfigurationCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApWpsConfigurationCfmSend(dst__, status__) \
-    CsrWifiSmeApWpsConfigurationCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsRegistrationFinishedReqSend
-
-  DESCRIPTION
-    This primitive tells SME that WPS registration procedure has finished
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag -
-
-*******************************************************************************/
-#define CsrWifiSmeApWpsRegistrationFinishedReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApWpsRegistrationFinishedReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_REGISTRATION_FINISHED_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeApWpsRegistrationFinishedReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeApWpsRegistrationFinishedReq *msg__; \
-        CsrWifiSmeApWpsRegistrationFinishedReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApWpsRegistrationFinishedReqSend(src__, interfaceTag__) \
-    CsrWifiSmeApWpsRegistrationFinishedReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsRegistrationFinishedCfmSend
-
-  DESCRIPTION
-    A confirm for UNIFI_MGT_AP_WPS_REGISTRATION_FINISHED.request
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiSmeApWpsRegistrationFinishedCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApWpsRegistrationFinishedCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_REGISTRATION_FINISHED_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeApWpsRegistrationFinishedCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeApWpsRegistrationFinishedCfm *msg__; \
-        CsrWifiSmeApWpsRegistrationFinishedCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApWpsRegistrationFinishedCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeApWpsRegistrationFinishedCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsRegistrationStartedReqSend
-
-  DESCRIPTION
-    This primitive tells SME that WPS registration procedure has started
-
-  PARAMETERS
-    queue                    - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag             -
-    SelectedDevicePasswordId -
-    SelectedconfigMethod     -
-
-*******************************************************************************/
-#define CsrWifiSmeApWpsRegistrationStartedReqCreate(msg__, dst__, src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApWpsRegistrationStartedReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_REGISTRATION_STARTED_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->SelectedDevicePasswordId = (SelectedDevicePasswordId__); \
-    msg__->SelectedconfigMethod = (SelectedconfigMethod__);
-
-#define CsrWifiSmeApWpsRegistrationStartedReqSendTo(dst__, src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__) \
-    { \
-        CsrWifiSmeApWpsRegistrationStartedReq *msg__; \
-        CsrWifiSmeApWpsRegistrationStartedReqCreate(msg__, dst__, src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApWpsRegistrationStartedReqSend(src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__) \
-    CsrWifiSmeApWpsRegistrationStartedReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, SelectedDevicePasswordId__, SelectedconfigMethod__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsRegistrationStartedCfmSend
-
-  DESCRIPTION
-    A confirm for UNIFI_MGT_AP_WPS_REGISTRATION_STARTED.request
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-#define CsrWifiSmeApWpsRegistrationStartedCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeApWpsRegistrationStartedCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_WPS_REGISTRATION_STARTED_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeApWpsRegistrationStartedCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeApWpsRegistrationStartedCfm *msg__; \
-        CsrWifiSmeApWpsRegistrationStartedCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeApWpsRegistrationStartedCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeApWpsRegistrationStartedCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-
-#endif /* CSR_WIFI_SME_AP_LIB_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_ap_prim.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_ap_prim.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_ap_prim.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_ap_prim.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1030 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_SME_AP_PRIM_H__
-#define CSR_WIFI_SME_AP_PRIM_H__
-
-#include "csr_prim_defs.h"
-#include "csr_sched.h"
-#include "csr_wifi_common.h"
-#include "csr_result.h"
-#include "csr_wifi_fsm_event.h"
-#include "csr_wifi_sme_prim.h"
-
-#ifndef CSR_WIFI_AP_ENABLE
-#error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_sme_ap_prim.h
-#endif
-
-#define CSR_WIFI_SME_AP_PRIM                                            (0x0407)
-
-typedef CsrPrim CsrWifiSmeApPrim;
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApAccessType
-
-  DESCRIPTION
-    Allow or deny STAs based on MAC address
-
- VALUES
-    CSR_WIFI_AP_ACCESS_TYPE_NONE  - None
-    CSR_WIFI_AP_ACCESS_TYPE_ALLOW - Allow only if MAC address is from the list
-    CSR_WIFI_AP_ACCESS_TYPE_DENY  - Disallow if MAC address is from the list
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeApAccessType;
-#define CSR_WIFI_AP_ACCESS_TYPE_NONE    ((CsrWifiSmeApAccessType) 0x00)
-#define CSR_WIFI_AP_ACCESS_TYPE_ALLOW   ((CsrWifiSmeApAccessType) 0x01)
-#define CSR_WIFI_AP_ACCESS_TYPE_DENY    ((CsrWifiSmeApAccessType) 0x02)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApAuthSupport
-
-  DESCRIPTION
-    Define bits for AP authentication support
-
- VALUES
-    CSR_WIFI_SME_RSN_AUTH_WPAPSK  - RSN WPA-PSK Support
-    CSR_WIFI_SME_RSN_AUTH_WPA2PSK - RSN WPA2-PSK Support
-    CSR_WIFI_SME_AUTH_WAPIPSK     - WAPI-PSK Support
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeApAuthSupport;
-#define CSR_WIFI_SME_RSN_AUTH_WPAPSK    ((CsrWifiSmeApAuthSupport) 0x01)
-#define CSR_WIFI_SME_RSN_AUTH_WPA2PSK   ((CsrWifiSmeApAuthSupport) 0x02)
-#define CSR_WIFI_SME_AUTH_WAPIPSK       ((CsrWifiSmeApAuthSupport) 0x04)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApAuthType
-
-  DESCRIPTION
-    Definition of the SME AP Authentication Options
-
- VALUES
-    CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM
-                   - Open  authentication
-    CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL
-                   - Personal authentication using a passphrase or a pre-shared
-                     key.
-    CSR_WIFI_SME_AP_AUTH_TYPE_WEP
-                   - WEP authentication. This can be either open or shared key
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeApAuthType;
-#define CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM   ((CsrWifiSmeApAuthType) 0x00)
-#define CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL      ((CsrWifiSmeApAuthType) 0x01)
-#define CSR_WIFI_SME_AP_AUTH_TYPE_WEP           ((CsrWifiSmeApAuthType) 0x02)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApDirection
-
-  DESCRIPTION
-    Definition of Direction
-
- VALUES
-    CSR_WIFI_AP_DIRECTION_RECEIPIENT - Receipient
-    CSR_WIFI_AP_DIRECTION_ORIGINATOR - Originator
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeApDirection;
-#define CSR_WIFI_AP_DIRECTION_RECEIPIENT   ((CsrWifiSmeApDirection) 0x00)
-#define CSR_WIFI_AP_DIRECTION_ORIGINATOR   ((CsrWifiSmeApDirection) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApPhySupport
-
-  DESCRIPTION
-    Define bits for CsrWifiSmeApPhySupportMask
-
- VALUES
-    CSR_WIFI_SME_AP_PHY_SUPPORT_A - 802.11a. It is not supported in the current
-                                    release.
-    CSR_WIFI_SME_AP_PHY_SUPPORT_B - 802.11b
-    CSR_WIFI_SME_AP_PHY_SUPPORT_G - 802.11g
-    CSR_WIFI_SME_AP_PHY_SUPPORT_N - 802.11n
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeApPhySupport;
-#define CSR_WIFI_SME_AP_PHY_SUPPORT_A   ((CsrWifiSmeApPhySupport) 0x01)
-#define CSR_WIFI_SME_AP_PHY_SUPPORT_B   ((CsrWifiSmeApPhySupport) 0x02)
-#define CSR_WIFI_SME_AP_PHY_SUPPORT_G   ((CsrWifiSmeApPhySupport) 0x04)
-#define CSR_WIFI_SME_AP_PHY_SUPPORT_N   ((CsrWifiSmeApPhySupport) 0x08)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApType
-
-  DESCRIPTION
-    Definition of AP types
-
- VALUES
-    CSR_WIFI_AP_TYPE_LEGACY - Legacy AP
-    CSR_WIFI_AP_TYPE_P2P    - P2P Group Owner(GO)
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeApType;
-#define CSR_WIFI_AP_TYPE_LEGACY   ((CsrWifiSmeApType) 0x00)
-#define CSR_WIFI_AP_TYPE_P2P      ((CsrWifiSmeApType) 0x01)
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApAuthSupportMask
-
-  DESCRIPTION
-    See CsrWifiSmeApAuthSupport for bit definitions
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeApAuthSupportMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApPhySupportMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeApPhySupport
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeApPhySupportMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApRsnCapabilities
-
-  DESCRIPTION
-    Set to 0 for the current release
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeApRsnCapabilities;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApRsnCapabilitiesMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeApRsnCapabilities
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeApRsnCapabilitiesMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWapiCapabilities
-
-  DESCRIPTION
-    Ignored by the stack as WAPI is not supported for AP operations in the
-    current release
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeApWapiCapabilities;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWapiCapabilitiesMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeApWapiCapabilities
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeApWapiCapabilitiesMask;
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApHtParams
-
-  DESCRIPTION
-    Structure holding HT parameters
-
-  MEMBERS
-    greenfieldSupported - Indicates if the AP supports Htgreenfield operation
-                          subject to the chip capability. If the chip does not
-                          support Htgreenfield operation, this parameter will be
-                          ignored.
-                          NOTE: if shortGi20MHz is set to TRUE and the chip
-                          supports short GI operation for 20MHz this field will
-                          be be ignored and the AP will not support Htgreenfield
-                          operation.
-                          NOTE: This field is ignored by the Wi-Fi stack for the
-                          current release. It implies that AP does not support
-                          greenfield operation.
-    shortGi20MHz        - Indicates if the AP support short GI operation for
-                          20MHz subject to the chip capability.If the chip does
-                          not support short GI for 20MHz, this parameter is
-                          ignored
-    rxStbc              - Support for STBC for receive. 0 => No support for STBC
-                          , 1=> Use STBC for Rx
-    rifsModeAllowed     - RIFS Mode is allowed to protect overlapping non-HT BSS
-    htProtection        - Deprecated
-    dualCtsProtection   - Dual CTS Protection enabled
-
-*******************************************************************************/
-typedef struct
-{
-    u8  greenfieldSupported;
-    u8  shortGi20MHz;
-    u8 rxStbc;
-    u8  rifsModeAllowed;
-    u8 htProtection;
-    u8  dualCtsProtection;
-} CsrWifiSmeApHtParams;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApP2pOperatingChanEntry
-
-  DESCRIPTION
-
-  MEMBERS
-    operatingClass        - Channel operating class
-    operatingChannelCount - Number of channels in this entry
-    operatingChannel      - List of channels
-
-*******************************************************************************/
-typedef struct
-{
-    u8  operatingClass;
-    u8  operatingChannelCount;
-    u8 *operatingChannel;
-} CsrWifiSmeApP2pOperatingChanEntry;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApP2pOperatingChanList
-
-  DESCRIPTION
-    This structure contains the lists of P2P operating channels
-
-  MEMBERS
-    country               - Country
-    channelEntryListCount - Number of entries
-    channelEntryList      - List of entries
-
-*******************************************************************************/
-typedef struct
-{
-    u8                           country[3];
-    u8                           channelEntryListCount;
-    CsrWifiSmeApP2pOperatingChanEntry *channelEntryList;
-} CsrWifiSmeApP2pOperatingChanList;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApAuthPers
-
-  DESCRIPTION
-
-  MEMBERS
-    authSupport        -
-    encryptionModeMask -
-    rsnCapabilities    -
-    wapiCapabilities   -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeApAuthSupportMask      authSupport;
-    CsrWifiSmeEncryptionMask         encryptionModeMask;
-    CsrWifiSmeApRsnCapabilitiesMask  rsnCapabilities;
-    CsrWifiSmeApWapiCapabilitiesMask wapiCapabilities;
-} CsrWifiSmeApAuthPers;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBaSession
-
-  DESCRIPTION
-
-  MEMBERS
-    peerMacAddress - Indicates MAC address of the peer station
-    tid            - Specifies the TID of the MSDUs for which this Block Ack has
-                     been set up. Range: 0-15
-    direction      - Specifies if the AP is the originator or the recipient of
-                     the data stream that uses the Block Ack.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiMacAddress     peerMacAddress;
-    u8              tid;
-    CsrWifiSmeApDirection direction;
-} CsrWifiSmeApBaSession;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApMacConfig
-
-  DESCRIPTION
-    Structure holding AP MAC configuration.
-
-  MEMBERS
-    phySupportedBitmap   - Indicates supported physical layers
-    beaconInterval       - Beacon interval in terms of TUs
-    dtimPeriod           - DTIM period in terms of number of beacon intervals
-    maxListenInterval    - Maximum allowed listen interval as number of beacon
-                           intervals
-    supportedRatesCount  - Number of supported rates. Range : 0  to 20
-    supportedRates       - List of supportedRates. A rate is specied in the
-                           units of 500kbps. An entry for a basic rate shall
-                           have the MSB set to 1.
-    preamble             - Preamble to be advertised in beacons and probe
-                           responses
-    shortSlotTimeEnabled - TRUE indicates the AP shall use short slot time if
-                           all the stations use short slot operation.
-    ctsProtectionType    - CTS protection to be used
-    wmmEnabled           - Indicate whether WMM is enabled or not. If set to
-                           FALSE,the WMM parameters shall be ignored by the
-                           receiver.
-    wmmApParams          - WMM parameters to be used for local firmware queue
-                           configuration. Array index corresponds to the ACI.
-    wmmApBcParams        - WMM parameters to be advertised in beacon/probe
-                           response. Array index corresponds to the ACI
-    accessType           - Specifies whether the MAC addresses from the list
-                           should be allowed or denied
-    macAddressListCount  - Number of MAC addresses
-    macAddressList       - List of MAC addresses
-    apHtParams           - AP HT parameters. The stack shall use these
-                           parameters only if phySupportedBitmap indicates
-                           support for IEEE 802.11n
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeApPhySupportMask  phySupportedBitmap;
-    u16                   beaconInterval;
-    u8                    dtimPeriod;
-    u16                   maxListenInterval;
-    u8                    supportedRatesCount;
-    u8                    supportedRates[20];
-    CsrWifiSmePreambleType      preamble;
-    u8                     shortSlotTimeEnabled;
-    CsrWifiSmeCtsProtectionType ctsProtectionType;
-    u8                     wmmEnabled;
-    CsrWifiSmeWmmAcParams       wmmApParams[4];
-    CsrWifiSmeWmmAcParams       wmmApBcParams[4];
-    CsrWifiSmeApAccessType      accessType;
-    u8                    macAddressListCount;
-    CsrWifiMacAddress          *macAddressList;
-    CsrWifiSmeApHtParams        apHtParams;
-} CsrWifiSmeApMacConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApP2pGoConfig
-
-  DESCRIPTION
-
-  MEMBERS
-    groupCapability           - Indicates the P2P group capabilities
-    operatingChanList         - List of operating channels in the order of
-                                decreasing priority. It may contain channel
-                                entry/entries not supported by the wifi stack.
-                                These shall be filtered out by the wifi stack
-    opPsEnabled               - Indicates whether opportunistic power save can
-                                be used.
-                                Note: This parameter is ignored by the WiFi
-                                stack for the current release
-    ctWindow                  - Define Client Traffic window to be used in terms
-                                of number of TUs. Range: 0 to 127.
-                                Note: This parameter is ignored by the WiFi
-                                stack for the current release.
-    noaConfigMethod           - Notice of Absence configuration method.
-                                Note: This parameter is ignored by the WiFi
-                                stack for the current release.
-    allowNoaWithNonP2pDevices - Indicates if NOA should be allowed if non P2P
-                                devices are connected. If allowed the non P2P
-                                devices may suffer in throughput.
-                                Note: This parameter is ignored by the WiFi
-                                stack for the current release.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeP2pGroupCapabilityMask groupCapability;
-    CsrWifiSmeApP2pOperatingChanList operatingChanList;
-    u8                          opPsEnabled;
-    u8                         ctWindow;
-    CsrWifiSmeP2pNoaConfigMethod     noaConfigMethod;
-    u8                          allowNoaWithNonP2pDevices;
-} CsrWifiSmeApP2pGoConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApCredentials
-
-  DESCRIPTION
-
-  MEMBERS
-    authType                    -
-    smeAuthType                 -
-    smeAuthTypeopenSystemEmpty  -
-    smeAuthTypeauthwep          -
-    smeAuthTypeauthPers         -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeApAuthType authType;
-    union {
-        CsrWifiSmeEmpty      openSystemEmpty;
-        CsrWifiSmeWepAuth    authwep;
-        CsrWifiSmeApAuthPers authPers;
-    } smeAuthType;
-} CsrWifiSmeApCredentials;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApSecConfig
-
-  DESCRIPTION
-
-  MEMBERS
-    apCredentials -
-    wpsEnabled    -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeApCredentials apCredentials;
-    u8                 wpsEnabled;
-} CsrWifiSmeApSecConfig;
-
-
-/* Downstream */
-#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST            (0x0000)
-
-#define CSR_WIFI_SME_AP_BEACONING_START_REQ               ((CsrWifiSmeApPrim) (0x0000 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_BEACONING_STOP_REQ                ((CsrWifiSmeApPrim) (0x0001 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_WPS_REGISTRATION_STARTED_REQ      ((CsrWifiSmeApPrim) (0x0002 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_WPS_REGISTRATION_FINISHED_REQ     ((CsrWifiSmeApPrim) (0x0003 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_REQ              ((CsrWifiSmeApPrim) (0x0004 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_STA_DISCONNECT_REQ                ((CsrWifiSmeApPrim) (0x0005 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_REQ             ((CsrWifiSmeApPrim) (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_ACTIVE_BA_GET_REQ                 ((CsrWifiSmeApPrim) (0x0007 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_BA_DELETE_REQ                     ((CsrWifiSmeApPrim) (0x0008 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-
-
-#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST           (0x0008 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)
-
-/* Upstream */
-#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST              (0x0000 + CSR_PRIM_UPSTREAM)
-
-#define CSR_WIFI_SME_AP_BEACONING_START_CFM               ((CsrWifiSmeApPrim)(0x0000 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_BEACONING_STOP_CFM                ((CsrWifiSmeApPrim)(0x0001 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_STA_NOTIFY_IND                    ((CsrWifiSmeApPrim)(0x0002 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_STA_CONNECT_START_IND             ((CsrWifiSmeApPrim)(0x0003 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_WPS_REGISTRATION_STARTED_CFM      ((CsrWifiSmeApPrim)(0x0004 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_WPS_REGISTRATION_FINISHED_CFM     ((CsrWifiSmeApPrim)(0x0005 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_CFM              ((CsrWifiSmeApPrim)(0x0006 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_STA_DISCONNECT_CFM                ((CsrWifiSmeApPrim)(0x0007 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_CFM             ((CsrWifiSmeApPrim)(0x0008 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_ERROR_IND                         ((CsrWifiSmeApPrim)(0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_ACTIVE_BA_GET_CFM                 ((CsrWifiSmeApPrim)(0x000A + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_BA_DELETE_CFM                     ((CsrWifiSmeApPrim)(0x000B + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-
-#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST             (0x000B + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)
-
-#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT             (CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)
-#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT               (CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST   + 1 - CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBeaconingStartReq
-
-  DESCRIPTION
-    This primitive requests the SME to start AP or GO functionality
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    -
-    initialPresence - Set to 0, if Not in a group fomration phase, set to 1 ,
-                      during group formation phase
-    apType          - apType : Legacy AP or P2PGO
-    cloakSsid       - cloakSsid flag.
-    ssid            - ssid.
-    ifIndex         - Radio Interface
-    channel         - channel.
-    maxConnections  - Maximum Stations + P2PClients allowed
-    apCredentials   - AP security credeitals used to advertise in beacon /probe
-                      response
-    smeApConfig     - AP configuration
-    p2pGoParam      - P2P specific GO parameters. Ignored if it is a leagacy AP
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent         common;
-    u16               interfaceTag;
-    u8                initialPresence;
-    CsrWifiSmeApType        apType;
-    u8                 cloakSsid;
-    CsrWifiSsid             ssid;
-    CsrWifiSmeRadioIF       ifIndex;
-    u8                channel;
-    u8                maxConnections;
-    CsrWifiSmeApSecConfig   apCredentials;
-    CsrWifiSmeApMacConfig   smeApConfig;
-    CsrWifiSmeApP2pGoConfig p2pGoParam;
-} CsrWifiSmeApBeaconingStartReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBeaconingStopReq
-
-  DESCRIPTION
-    This primitive requests the SME to STOP AP or P2PGO operation
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeApBeaconingStopReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsRegistrationStartedReq
-
-  DESCRIPTION
-    This primitive tells SME that WPS registration procedure has started
-
-  MEMBERS
-    common                   - Common header for use with the CsrWifiFsm Module
-    interfaceTag             -
-    SelectedDevicePasswordId -
-    SelectedconfigMethod     -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent         common;
-    u16               interfaceTag;
-    CsrWifiSmeWpsDpid       SelectedDevicePasswordId;
-    CsrWifiSmeWpsConfigType SelectedconfigMethod;
-} CsrWifiSmeApWpsRegistrationStartedReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsRegistrationFinishedReq
-
-  DESCRIPTION
-    This primitive tells SME that WPS registration procedure has finished
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeApWpsRegistrationFinishedReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWmmParamUpdateReq
-
-  DESCRIPTION
-    Application uses this primitive to update the WMM parameters on the fly
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    interfaceTag  -
-    wmmApParams   - WMM parameters to be used for local firmware queue
-                    configuration
-    wmmApBcParams - WMM parameters to be advertised in beacon/probe response
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    u16             interfaceTag;
-    CsrWifiSmeWmmAcParams wmmApParams[4];
-    CsrWifiSmeWmmAcParams wmmApBcParams[4];
-} CsrWifiSmeApWmmParamUpdateReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApStaDisconnectReq
-
-  DESCRIPTION
-    This primitive tells SME to deauth ot disassociate a particular station
-    within BSS
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   -
-    deauthReason   -
-    disassocReason -
-    peerMacaddress -
-    keepBlocking   - If TRUE, the station is blocked. If FALSE and the station
-                     is connected, disconnect the station. If FALSE and the
-                     station is not connected, no action is taken.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrWifiSmeIEEE80211Reason deauthReason;
-    CsrWifiSmeIEEE80211Reason disassocReason;
-    CsrWifiMacAddress         peerMacaddress;
-    u8                   keepBlocking;
-} CsrWifiSmeApStaDisconnectReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsConfigurationReq
-
-  DESCRIPTION
-    This primitive passes the WPS information for the device to SME. This may
-    be accepted only if no interface is active.
-
-  MEMBERS
-    common    - Common header for use with the CsrWifiFsm Module
-    wpsConfig - WPS config.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    CsrWifiSmeWpsConfig wpsConfig;
-} CsrWifiSmeApWpsConfigurationReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApActiveBaGetReq
-
-  DESCRIPTION
-    This primitive used to retrieve information related to the active block
-    ack sessions
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeApActiveBaGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBaDeleteReq
-
-  DESCRIPTION
-    This primitive is used to delete an active block ack session
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    reason       -
-    baSession    - BA session to be deleted
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrWifiSmeIEEE80211Reason reason;
-    CsrWifiSmeApBaSession     baSession;
-} CsrWifiSmeApBaDeleteReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBeaconingStartCfm
-
-  DESCRIPTION
-    This primitive confirms the completion of the request along with the
-    status
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    status       -
-    secIeLength  -
-    secIe        -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-    u16       secIeLength;
-    u8       *secIe;
-} CsrWifiSmeApBeaconingStartCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBeaconingStopCfm
-
-  DESCRIPTION
-    This primitive confirms AP or P2PGO operation is terminated
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeApBeaconingStopCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApStaNotifyInd
-
-  DESCRIPTION
-    This primitive indicates that a station has joined or a previously joined
-    station has left the BSS/group
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    interfaceTag      -
-    mediaStatus       -
-    peerMacAddress    -
-    peerDeviceAddress -
-    disassocReason    -
-    deauthReason      -
-    WpsRegistration   -
-    secIeLength       -
-    secIe             -
-    groupKeyId        -
-    seqNumber         -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrWifiSmeMediaStatus     mediaStatus;
-    CsrWifiMacAddress         peerMacAddress;
-    CsrWifiMacAddress         peerDeviceAddress;
-    CsrWifiSmeIEEE80211Reason disassocReason;
-    CsrWifiSmeIEEE80211Reason deauthReason;
-    CsrWifiSmeWpsRegistration WpsRegistration;
-    u8                  secIeLength;
-    u8                 *secIe;
-    u8                  groupKeyId;
-    u16                 seqNumber[8];
-} CsrWifiSmeApStaNotifyInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApStaConnectStartInd
-
-  DESCRIPTION
-    This primitive indicates that a stations request to join the group/BSS is
-    accepted
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   -
-    peerMacAddress -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    u16         interfaceTag;
-    CsrWifiMacAddress peerMacAddress;
-} CsrWifiSmeApStaConnectStartInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsRegistrationStartedCfm
-
-  DESCRIPTION
-    A confirm for UNIFI_MGT_AP_WPS_REGISTRATION_STARTED.request
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeApWpsRegistrationStartedCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsRegistrationFinishedCfm
-
-  DESCRIPTION
-    A confirm for UNIFI_MGT_AP_WPS_REGISTRATION_FINISHED.request
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeApWpsRegistrationFinishedCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWmmParamUpdateCfm
-
-  DESCRIPTION
-    A confirm for CSR_WIFI_SME_AP_WMM_PARAM_UPDATE.request
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    status       -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeApWmmParamUpdateCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApStaDisconnectCfm
-
-  DESCRIPTION
-    This primitive confirms the station is disconnected
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   -
-    status         -
-    peerMacaddress -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    u16         interfaceTag;
-    CsrResult         status;
-    CsrWifiMacAddress peerMacaddress;
-} CsrWifiSmeApStaDisconnectCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApWpsConfigurationCfm
-
-  DESCRIPTION
-    Confirm.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Status of the request.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeApWpsConfigurationCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApErrorInd
-
-  DESCRIPTION
-    This primitve is sent by SME to indicate some error in AP operationi
-    after AP operations were started successfully and continuing the AP
-    operation may lead to undesired behaviour. It is the responsibility of
-    the upper layers to stop AP operation if needed
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Range 0-1
-    apType       -
-    status       - Contains the error status
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent  common;
-    u16        interfaceTag;
-    CsrWifiSmeApType apType;
-    CsrResult        status;
-} CsrWifiSmeApErrorInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApActiveBaGetCfm
-
-  DESCRIPTION
-    This primitive carries the information related to the active ba sessions
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    interfaceTag     -
-    status           - Reports the result of the request
-    activeBaCount    - Number of active block ack session
-    activeBaSessions - Points to a buffer containing an array of
-                       CsrWifiSmeApBaSession structures.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent        common;
-    u16              interfaceTag;
-    CsrResult              status;
-    u16              activeBaCount;
-    CsrWifiSmeApBaSession *activeBaSessions;
-} CsrWifiSmeApActiveBaGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeApBaDeleteCfm
-
-  DESCRIPTION
-    This primitive confirms the BA is deleted
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag -
-    status       - Reports the result of the request
-    baSession    - deleted BA session
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    u16             interfaceTag;
-    CsrResult             status;
-    CsrWifiSmeApBaSession baSession;
-} CsrWifiSmeApBaDeleteCfm;
-
-
-#endif /* CSR_WIFI_SME_AP_PRIM_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_converter_init.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_converter_init.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_converter_init.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_converter_init.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,201 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#include "csr_msgconv.h"
-#include "csr_macro.h"
-
-
-#ifdef CSR_LOG_ENABLE
-#include "csr_log.h"
-#endif
-
-#ifndef EXCLUDE_CSR_WIFI_SME_MODULE
-#include "csr_wifi_sme_serialize.h"
-#include "csr_wifi_sme_prim.h"
-
-static CsrMsgConvMsgEntry csrwifisme_conv_lut[] = {
-    { CSR_WIFI_SME_ACTIVATE_REQ, CsrWifiSmeActivateReqSizeof, CsrWifiSmeActivateReqSer, CsrWifiSmeActivateReqDes, CsrWifiSmeActivateReqSerFree },
-    { CSR_WIFI_SME_ADHOC_CONFIG_GET_REQ, CsrWifiSmeAdhocConfigGetReqSizeof, CsrWifiSmeAdhocConfigGetReqSer, CsrWifiSmeAdhocConfigGetReqDes, CsrWifiSmeAdhocConfigGetReqSerFree },
-    { CSR_WIFI_SME_ADHOC_CONFIG_SET_REQ, CsrWifiSmeAdhocConfigSetReqSizeof, CsrWifiSmeAdhocConfigSetReqSer, CsrWifiSmeAdhocConfigSetReqDes, CsrWifiSmeAdhocConfigSetReqSerFree },
-    { CSR_WIFI_SME_BLACKLIST_REQ, CsrWifiSmeBlacklistReqSizeof, CsrWifiSmeBlacklistReqSer, CsrWifiSmeBlacklistReqDes, CsrWifiSmeBlacklistReqSerFree },
-    { CSR_WIFI_SME_CALIBRATION_DATA_GET_REQ, CsrWifiSmeCalibrationDataGetReqSizeof, CsrWifiSmeCalibrationDataGetReqSer, CsrWifiSmeCalibrationDataGetReqDes, CsrWifiSmeCalibrationDataGetReqSerFree },
-    { CSR_WIFI_SME_CALIBRATION_DATA_SET_REQ, CsrWifiSmeCalibrationDataSetReqSizeof, CsrWifiSmeCalibrationDataSetReqSer, CsrWifiSmeCalibrationDataSetReqDes, CsrWifiSmeCalibrationDataSetReqSerFree },
-    { CSR_WIFI_SME_CCX_CONFIG_GET_REQ, CsrWifiSmeCcxConfigGetReqSizeof, CsrWifiSmeCcxConfigGetReqSer, CsrWifiSmeCcxConfigGetReqDes, CsrWifiSmeCcxConfigGetReqSerFree },
-    { CSR_WIFI_SME_CCX_CONFIG_SET_REQ, CsrWifiSmeCcxConfigSetReqSizeof, CsrWifiSmeCcxConfigSetReqSer, CsrWifiSmeCcxConfigSetReqDes, CsrWifiSmeCcxConfigSetReqSerFree },
-    { CSR_WIFI_SME_COEX_CONFIG_GET_REQ, CsrWifiSmeCoexConfigGetReqSizeof, CsrWifiSmeCoexConfigGetReqSer, CsrWifiSmeCoexConfigGetReqDes, CsrWifiSmeCoexConfigGetReqSerFree },
-    { CSR_WIFI_SME_COEX_CONFIG_SET_REQ, CsrWifiSmeCoexConfigSetReqSizeof, CsrWifiSmeCoexConfigSetReqSer, CsrWifiSmeCoexConfigSetReqDes, CsrWifiSmeCoexConfigSetReqSerFree },
-    { CSR_WIFI_SME_COEX_INFO_GET_REQ, CsrWifiSmeCoexInfoGetReqSizeof, CsrWifiSmeCoexInfoGetReqSer, CsrWifiSmeCoexInfoGetReqDes, CsrWifiSmeCoexInfoGetReqSerFree },
-    { CSR_WIFI_SME_CONNECT_REQ, CsrWifiSmeConnectReqSizeof, CsrWifiSmeConnectReqSer, CsrWifiSmeConnectReqDes, CsrWifiSmeConnectReqSerFree },
-    { CSR_WIFI_SME_CONNECTION_CONFIG_GET_REQ, CsrWifiSmeConnectionConfigGetReqSizeof, CsrWifiSmeConnectionConfigGetReqSer, CsrWifiSmeConnectionConfigGetReqDes, CsrWifiSmeConnectionConfigGetReqSerFree },
-    { CSR_WIFI_SME_CONNECTION_INFO_GET_REQ, CsrWifiSmeConnectionInfoGetReqSizeof, CsrWifiSmeConnectionInfoGetReqSer, CsrWifiSmeConnectionInfoGetReqDes, CsrWifiSmeConnectionInfoGetReqSerFree },
-    { CSR_WIFI_SME_CONNECTION_STATS_GET_REQ, CsrWifiSmeConnectionStatsGetReqSizeof, CsrWifiSmeConnectionStatsGetReqSer, CsrWifiSmeConnectionStatsGetReqDes, CsrWifiSmeConnectionStatsGetReqSerFree },
-    { CSR_WIFI_SME_DEACTIVATE_REQ, CsrWifiSmeDeactivateReqSizeof, CsrWifiSmeDeactivateReqSer, CsrWifiSmeDeactivateReqDes, CsrWifiSmeDeactivateReqSerFree },
-    { CSR_WIFI_SME_DISCONNECT_REQ, CsrWifiSmeDisconnectReqSizeof, CsrWifiSmeDisconnectReqSer, CsrWifiSmeDisconnectReqDes, CsrWifiSmeDisconnectReqSerFree },
-    { CSR_WIFI_SME_EVENT_MASK_SET_REQ, CsrWifiSmeEventMaskSetReqSizeof, CsrWifiSmeEventMaskSetReqSer, CsrWifiSmeEventMaskSetReqDes, CsrWifiSmeEventMaskSetReqSerFree },
-    { CSR_WIFI_SME_HOST_CONFIG_GET_REQ, CsrWifiSmeHostConfigGetReqSizeof, CsrWifiSmeHostConfigGetReqSer, CsrWifiSmeHostConfigGetReqDes, CsrWifiSmeHostConfigGetReqSerFree },
-    { CSR_WIFI_SME_HOST_CONFIG_SET_REQ, CsrWifiSmeHostConfigSetReqSizeof, CsrWifiSmeHostConfigSetReqSer, CsrWifiSmeHostConfigSetReqDes, CsrWifiSmeHostConfigSetReqSerFree },
-    { CSR_WIFI_SME_KEY_REQ, CsrWifiSmeKeyReqSizeof, CsrWifiSmeKeyReqSer, CsrWifiSmeKeyReqDes, CsrWifiSmeKeyReqSerFree },
-    { CSR_WIFI_SME_LINK_QUALITY_GET_REQ, CsrWifiSmeLinkQualityGetReqSizeof, CsrWifiSmeLinkQualityGetReqSer, CsrWifiSmeLinkQualityGetReqDes, CsrWifiSmeLinkQualityGetReqSerFree },
-    { CSR_WIFI_SME_MIB_CONFIG_GET_REQ, CsrWifiSmeMibConfigGetReqSizeof, CsrWifiSmeMibConfigGetReqSer, CsrWifiSmeMibConfigGetReqDes, CsrWifiSmeMibConfigGetReqSerFree },
-    { CSR_WIFI_SME_MIB_CONFIG_SET_REQ, CsrWifiSmeMibConfigSetReqSizeof, CsrWifiSmeMibConfigSetReqSer, CsrWifiSmeMibConfigSetReqDes, CsrWifiSmeMibConfigSetReqSerFree },
-    { CSR_WIFI_SME_MIB_GET_NEXT_REQ, CsrWifiSmeMibGetNextReqSizeof, CsrWifiSmeMibGetNextReqSer, CsrWifiSmeMibGetNextReqDes, CsrWifiSmeMibGetNextReqSerFree },
-    { CSR_WIFI_SME_MIB_GET_REQ, CsrWifiSmeMibGetReqSizeof, CsrWifiSmeMibGetReqSer, CsrWifiSmeMibGetReqDes, CsrWifiSmeMibGetReqSerFree },
-    { CSR_WIFI_SME_MIB_SET_REQ, CsrWifiSmeMibSetReqSizeof, CsrWifiSmeMibSetReqSer, CsrWifiSmeMibSetReqDes, CsrWifiSmeMibSetReqSerFree },
-    { CSR_WIFI_SME_MULTICAST_ADDRESS_REQ, CsrWifiSmeMulticastAddressReqSizeof, CsrWifiSmeMulticastAddressReqSer, CsrWifiSmeMulticastAddressReqDes, CsrWifiSmeMulticastAddressReqSerFree },
-    { CSR_WIFI_SME_PACKET_FILTER_SET_REQ, CsrWifiSmePacketFilterSetReqSizeof, CsrWifiSmePacketFilterSetReqSer, CsrWifiSmePacketFilterSetReqDes, CsrWifiSmePacketFilterSetReqSerFree },
-    { CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_REQ, CsrWifiSmePermanentMacAddressGetReqSizeof, CsrWifiSmePermanentMacAddressGetReqSer, CsrWifiSmePermanentMacAddressGetReqDes, CsrWifiSmePermanentMacAddressGetReqSerFree },
-    { CSR_WIFI_SME_PMKID_REQ, CsrWifiSmePmkidReqSizeof, CsrWifiSmePmkidReqSer, CsrWifiSmePmkidReqDes, CsrWifiSmePmkidReqSerFree },
-    { CSR_WIFI_SME_POWER_CONFIG_GET_REQ, CsrWifiSmePowerConfigGetReqSizeof, CsrWifiSmePowerConfigGetReqSer, CsrWifiSmePowerConfigGetReqDes, CsrWifiSmePowerConfigGetReqSerFree },
-    { CSR_WIFI_SME_POWER_CONFIG_SET_REQ, CsrWifiSmePowerConfigSetReqSizeof, CsrWifiSmePowerConfigSetReqSer, CsrWifiSmePowerConfigSetReqDes, CsrWifiSmePowerConfigSetReqSerFree },
-    { CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_REQ, CsrWifiSmeRegulatoryDomainInfoGetReqSizeof, CsrWifiSmeRegulatoryDomainInfoGetReqSer, CsrWifiSmeRegulatoryDomainInfoGetReqDes, CsrWifiSmeRegulatoryDomainInfoGetReqSerFree },
-    { CSR_WIFI_SME_ROAMING_CONFIG_GET_REQ, CsrWifiSmeRoamingConfigGetReqSizeof, CsrWifiSmeRoamingConfigGetReqSer, CsrWifiSmeRoamingConfigGetReqDes, CsrWifiSmeRoamingConfigGetReqSerFree },
-    { CSR_WIFI_SME_ROAMING_CONFIG_SET_REQ, CsrWifiSmeRoamingConfigSetReqSizeof, CsrWifiSmeRoamingConfigSetReqSer, CsrWifiSmeRoamingConfigSetReqDes, CsrWifiSmeRoamingConfigSetReqSerFree },
-    { CSR_WIFI_SME_SCAN_CONFIG_GET_REQ, CsrWifiSmeScanConfigGetReqSizeof, CsrWifiSmeScanConfigGetReqSer, CsrWifiSmeScanConfigGetReqDes, CsrWifiSmeScanConfigGetReqSerFree },
-    { CSR_WIFI_SME_SCAN_CONFIG_SET_REQ, CsrWifiSmeScanConfigSetReqSizeof, CsrWifiSmeScanConfigSetReqSer, CsrWifiSmeScanConfigSetReqDes, CsrWifiSmeScanConfigSetReqSerFree },
-    { CSR_WIFI_SME_SCAN_FULL_REQ, CsrWifiSmeScanFullReqSizeof, CsrWifiSmeScanFullReqSer, CsrWifiSmeScanFullReqDes, CsrWifiSmeScanFullReqSerFree },
-    { CSR_WIFI_SME_SCAN_RESULTS_FLUSH_REQ, CsrWifiSmeScanResultsFlushReqSizeof, CsrWifiSmeScanResultsFlushReqSer, CsrWifiSmeScanResultsFlushReqDes, CsrWifiSmeScanResultsFlushReqSerFree },
-    { CSR_WIFI_SME_SCAN_RESULTS_GET_REQ, CsrWifiSmeScanResultsGetReqSizeof, CsrWifiSmeScanResultsGetReqSer, CsrWifiSmeScanResultsGetReqDes, CsrWifiSmeScanResultsGetReqSerFree },
-    { CSR_WIFI_SME_SME_STA_CONFIG_GET_REQ, CsrWifiSmeSmeStaConfigGetReqSizeof, CsrWifiSmeSmeStaConfigGetReqSer, CsrWifiSmeSmeStaConfigGetReqDes, CsrWifiSmeSmeStaConfigGetReqSerFree },
-    { CSR_WIFI_SME_SME_STA_CONFIG_SET_REQ, CsrWifiSmeSmeStaConfigSetReqSizeof, CsrWifiSmeSmeStaConfigSetReqSer, CsrWifiSmeSmeStaConfigSetReqDes, CsrWifiSmeSmeStaConfigSetReqSerFree },
-    { CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_REQ, CsrWifiSmeStationMacAddressGetReqSizeof, CsrWifiSmeStationMacAddressGetReqSer, CsrWifiSmeStationMacAddressGetReqDes, CsrWifiSmeStationMacAddressGetReqSerFree },
-    { CSR_WIFI_SME_TSPEC_REQ, CsrWifiSmeTspecReqSizeof, CsrWifiSmeTspecReqSer, CsrWifiSmeTspecReqDes, CsrWifiSmeTspecReqSerFree },
-    { CSR_WIFI_SME_VERSIONS_GET_REQ, CsrWifiSmeVersionsGetReqSizeof, CsrWifiSmeVersionsGetReqSer, CsrWifiSmeVersionsGetReqDes, CsrWifiSmeVersionsGetReqSerFree },
-    { CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ, CsrWifiSmeWifiFlightmodeReqSizeof, CsrWifiSmeWifiFlightmodeReqSer, CsrWifiSmeWifiFlightmodeReqDes, CsrWifiSmeWifiFlightmodeReqSerFree },
-    { CSR_WIFI_SME_WIFI_OFF_REQ, CsrWifiSmeWifiOffReqSizeof, CsrWifiSmeWifiOffReqSer, CsrWifiSmeWifiOffReqDes, CsrWifiSmeWifiOffReqSerFree },
-    { CSR_WIFI_SME_WIFI_ON_REQ, CsrWifiSmeWifiOnReqSizeof, CsrWifiSmeWifiOnReqSer, CsrWifiSmeWifiOnReqDes, CsrWifiSmeWifiOnReqSerFree },
-    { CSR_WIFI_SME_CLOAKED_SSIDS_SET_REQ, CsrWifiSmeCloakedSsidsSetReqSizeof, CsrWifiSmeCloakedSsidsSetReqSer, CsrWifiSmeCloakedSsidsSetReqDes, CsrWifiSmeCloakedSsidsSetReqSerFree },
-    { CSR_WIFI_SME_CLOAKED_SSIDS_GET_REQ, CsrWifiSmeCloakedSsidsGetReqSizeof, CsrWifiSmeCloakedSsidsGetReqSer, CsrWifiSmeCloakedSsidsGetReqDes, CsrWifiSmeCloakedSsidsGetReqSerFree },
-    { CSR_WIFI_SME_SME_COMMON_CONFIG_GET_REQ, CsrWifiSmeSmeCommonConfigGetReqSizeof, CsrWifiSmeSmeCommonConfigGetReqSer, CsrWifiSmeSmeCommonConfigGetReqDes, CsrWifiSmeSmeCommonConfigGetReqSerFree },
-    { CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ, CsrWifiSmeSmeCommonConfigSetReqSizeof, CsrWifiSmeSmeCommonConfigSetReqSer, CsrWifiSmeSmeCommonConfigSetReqDes, CsrWifiSmeSmeCommonConfigSetReqSerFree },
-    { CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ, CsrWifiSmeInterfaceCapabilityGetReqSizeof, CsrWifiSmeInterfaceCapabilityGetReqSer, CsrWifiSmeInterfaceCapabilityGetReqDes, CsrWifiSmeInterfaceCapabilityGetReqSerFree },
-    { CSR_WIFI_SME_WPS_CONFIGURATION_REQ, CsrWifiSmeWpsConfigurationReqSizeof, CsrWifiSmeWpsConfigurationReqSer, CsrWifiSmeWpsConfigurationReqDes, CsrWifiSmeWpsConfigurationReqSerFree },
-    { CSR_WIFI_SME_SET_REQ, CsrWifiSmeSetReqSizeof, CsrWifiSmeSetReqSer, CsrWifiSmeSetReqDes, CsrWifiSmeSetReqSerFree },
-    { CSR_WIFI_SME_ACTIVATE_CFM, CsrWifiSmeActivateCfmSizeof, CsrWifiSmeActivateCfmSer, CsrWifiSmeActivateCfmDes, CsrWifiSmeActivateCfmSerFree },
-    { CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM, CsrWifiSmeAdhocConfigGetCfmSizeof, CsrWifiSmeAdhocConfigGetCfmSer, CsrWifiSmeAdhocConfigGetCfmDes, CsrWifiSmeAdhocConfigGetCfmSerFree },
-    { CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM, CsrWifiSmeAdhocConfigSetCfmSizeof, CsrWifiSmeAdhocConfigSetCfmSer, CsrWifiSmeAdhocConfigSetCfmDes, CsrWifiSmeAdhocConfigSetCfmSerFree },
-    { CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND, CsrWifiSmeAssociationCompleteIndSizeof, CsrWifiSmeAssociationCompleteIndSer, CsrWifiSmeAssociationCompleteIndDes, CsrWifiSmeAssociationCompleteIndSerFree },
-    { CSR_WIFI_SME_ASSOCIATION_START_IND, CsrWifiSmeAssociationStartIndSizeof, CsrWifiSmeAssociationStartIndSer, CsrWifiSmeAssociationStartIndDes, CsrWifiSmeAssociationStartIndSerFree },
-    { CSR_WIFI_SME_BLACKLIST_CFM, CsrWifiSmeBlacklistCfmSizeof, CsrWifiSmeBlacklistCfmSer, CsrWifiSmeBlacklistCfmDes, CsrWifiSmeBlacklistCfmSerFree },
-    { CSR_WIFI_SME_CALIBRATION_DATA_GET_CFM, CsrWifiSmeCalibrationDataGetCfmSizeof, CsrWifiSmeCalibrationDataGetCfmSer, CsrWifiSmeCalibrationDataGetCfmDes, CsrWifiSmeCalibrationDataGetCfmSerFree },
-    { CSR_WIFI_SME_CALIBRATION_DATA_SET_CFM, CsrWifiSmeCalibrationDataSetCfmSizeof, CsrWifiSmeCalibrationDataSetCfmSer, CsrWifiSmeCalibrationDataSetCfmDes, CsrWifiSmeCalibrationDataSetCfmSerFree },
-    { CSR_WIFI_SME_CCX_CONFIG_GET_CFM, CsrWifiSmeCcxConfigGetCfmSizeof, CsrWifiSmeCcxConfigGetCfmSer, CsrWifiSmeCcxConfigGetCfmDes, CsrWifiSmeCcxConfigGetCfmSerFree },
-    { CSR_WIFI_SME_CCX_CONFIG_SET_CFM, CsrWifiSmeCcxConfigSetCfmSizeof, CsrWifiSmeCcxConfigSetCfmSer, CsrWifiSmeCcxConfigSetCfmDes, CsrWifiSmeCcxConfigSetCfmSerFree },
-    { CSR_WIFI_SME_COEX_CONFIG_GET_CFM, CsrWifiSmeCoexConfigGetCfmSizeof, CsrWifiSmeCoexConfigGetCfmSer, CsrWifiSmeCoexConfigGetCfmDes, CsrWifiSmeCoexConfigGetCfmSerFree },
-    { CSR_WIFI_SME_COEX_CONFIG_SET_CFM, CsrWifiSmeCoexConfigSetCfmSizeof, CsrWifiSmeCoexConfigSetCfmSer, CsrWifiSmeCoexConfigSetCfmDes, CsrWifiSmeCoexConfigSetCfmSerFree },
-    { CSR_WIFI_SME_COEX_INFO_GET_CFM, CsrWifiSmeCoexInfoGetCfmSizeof, CsrWifiSmeCoexInfoGetCfmSer, CsrWifiSmeCoexInfoGetCfmDes, CsrWifiSmeCoexInfoGetCfmSerFree },
-    { CSR_WIFI_SME_CONNECT_CFM, CsrWifiSmeConnectCfmSizeof, CsrWifiSmeConnectCfmSer, CsrWifiSmeConnectCfmDes, CsrWifiSmeConnectCfmSerFree },
-    { CSR_WIFI_SME_CONNECTION_CONFIG_GET_CFM, CsrWifiSmeConnectionConfigGetCfmSizeof, CsrWifiSmeConnectionConfigGetCfmSer, CsrWifiSmeConnectionConfigGetCfmDes, CsrWifiSmeConnectionConfigGetCfmSerFree },
-    { CSR_WIFI_SME_CONNECTION_INFO_GET_CFM, CsrWifiSmeConnectionInfoGetCfmSizeof, CsrWifiSmeConnectionInfoGetCfmSer, CsrWifiSmeConnectionInfoGetCfmDes, CsrWifiSmeConnectionInfoGetCfmSerFree },
-    { CSR_WIFI_SME_CONNECTION_QUALITY_IND, CsrWifiSmeConnectionQualityIndSizeof, CsrWifiSmeConnectionQualityIndSer, CsrWifiSmeConnectionQualityIndDes, CsrWifiSmeConnectionQualityIndSerFree },
-    { CSR_WIFI_SME_CONNECTION_STATS_GET_CFM, CsrWifiSmeConnectionStatsGetCfmSizeof, CsrWifiSmeConnectionStatsGetCfmSer, CsrWifiSmeConnectionStatsGetCfmDes, CsrWifiSmeConnectionStatsGetCfmSerFree },
-    { CSR_WIFI_SME_DEACTIVATE_CFM, CsrWifiSmeDeactivateCfmSizeof, CsrWifiSmeDeactivateCfmSer, CsrWifiSmeDeactivateCfmDes, CsrWifiSmeDeactivateCfmSerFree },
-    { CSR_WIFI_SME_DISCONNECT_CFM, CsrWifiSmeDisconnectCfmSizeof, CsrWifiSmeDisconnectCfmSer, CsrWifiSmeDisconnectCfmDes, CsrWifiSmeDisconnectCfmSerFree },
-    { CSR_WIFI_SME_EVENT_MASK_SET_CFM, CsrWifiSmeEventMaskSetCfmSizeof, CsrWifiSmeEventMaskSetCfmSer, CsrWifiSmeEventMaskSetCfmDes, CsrWifiSmeEventMaskSetCfmSerFree },
-    { CSR_WIFI_SME_HOST_CONFIG_GET_CFM, CsrWifiSmeHostConfigGetCfmSizeof, CsrWifiSmeHostConfigGetCfmSer, CsrWifiSmeHostConfigGetCfmDes, CsrWifiSmeHostConfigGetCfmSerFree },
-    { CSR_WIFI_SME_HOST_CONFIG_SET_CFM, CsrWifiSmeHostConfigSetCfmSizeof, CsrWifiSmeHostConfigSetCfmSer, CsrWifiSmeHostConfigSetCfmDes, CsrWifiSmeHostConfigSetCfmSerFree },
-    { CSR_WIFI_SME_IBSS_STATION_IND, CsrWifiSmeIbssStationIndSizeof, CsrWifiSmeIbssStationIndSer, CsrWifiSmeIbssStationIndDes, CsrWifiSmeIbssStationIndSerFree },
-    { CSR_WIFI_SME_KEY_CFM, CsrWifiSmeKeyCfmSizeof, CsrWifiSmeKeyCfmSer, CsrWifiSmeKeyCfmDes, CsrWifiSmeKeyCfmSerFree },
-    { CSR_WIFI_SME_LINK_QUALITY_GET_CFM, CsrWifiSmeLinkQualityGetCfmSizeof, CsrWifiSmeLinkQualityGetCfmSer, CsrWifiSmeLinkQualityGetCfmDes, CsrWifiSmeLinkQualityGetCfmSerFree },
-    { CSR_WIFI_SME_MEDIA_STATUS_IND, CsrWifiSmeMediaStatusIndSizeof, CsrWifiSmeMediaStatusIndSer, CsrWifiSmeMediaStatusIndDes, CsrWifiSmeMediaStatusIndSerFree },
-    { CSR_WIFI_SME_MIB_CONFIG_GET_CFM, CsrWifiSmeMibConfigGetCfmSizeof, CsrWifiSmeMibConfigGetCfmSer, CsrWifiSmeMibConfigGetCfmDes, CsrWifiSmeMibConfigGetCfmSerFree },
-    { CSR_WIFI_SME_MIB_CONFIG_SET_CFM, CsrWifiSmeMibConfigSetCfmSizeof, CsrWifiSmeMibConfigSetCfmSer, CsrWifiSmeMibConfigSetCfmDes, CsrWifiSmeMibConfigSetCfmSerFree },
-    { CSR_WIFI_SME_MIB_GET_CFM, CsrWifiSmeMibGetCfmSizeof, CsrWifiSmeMibGetCfmSer, CsrWifiSmeMibGetCfmDes, CsrWifiSmeMibGetCfmSerFree },
-    { CSR_WIFI_SME_MIB_GET_NEXT_CFM, CsrWifiSmeMibGetNextCfmSizeof, CsrWifiSmeMibGetNextCfmSer, CsrWifiSmeMibGetNextCfmDes, CsrWifiSmeMibGetNextCfmSerFree },
-    { CSR_WIFI_SME_MIB_SET_CFM, CsrWifiSmeMibSetCfmSizeof, CsrWifiSmeMibSetCfmSer, CsrWifiSmeMibSetCfmDes, CsrWifiSmeMibSetCfmSerFree },
-    { CSR_WIFI_SME_MIC_FAILURE_IND, CsrWifiSmeMicFailureIndSizeof, CsrWifiSmeMicFailureIndSer, CsrWifiSmeMicFailureIndDes, CsrWifiSmeMicFailureIndSerFree },
-    { CSR_WIFI_SME_MULTICAST_ADDRESS_CFM, CsrWifiSmeMulticastAddressCfmSizeof, CsrWifiSmeMulticastAddressCfmSer, CsrWifiSmeMulticastAddressCfmDes, CsrWifiSmeMulticastAddressCfmSerFree },
-    { CSR_WIFI_SME_PACKET_FILTER_SET_CFM, CsrWifiSmePacketFilterSetCfmSizeof, CsrWifiSmePacketFilterSetCfmSer, CsrWifiSmePacketFilterSetCfmDes, CsrWifiSmePacketFilterSetCfmSerFree },
-    { CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_CFM, CsrWifiSmePermanentMacAddressGetCfmSizeof, CsrWifiSmePermanentMacAddressGetCfmSer, CsrWifiSmePermanentMacAddressGetCfmDes, CsrWifiSmePermanentMacAddressGetCfmSerFree },
-    { CSR_WIFI_SME_PMKID_CANDIDATE_LIST_IND, CsrWifiSmePmkidCandidateListIndSizeof, CsrWifiSmePmkidCandidateListIndSer, CsrWifiSmePmkidCandidateListIndDes, CsrWifiSmePmkidCandidateListIndSerFree },
-    { CSR_WIFI_SME_PMKID_CFM, CsrWifiSmePmkidCfmSizeof, CsrWifiSmePmkidCfmSer, CsrWifiSmePmkidCfmDes, CsrWifiSmePmkidCfmSerFree },
-    { CSR_WIFI_SME_POWER_CONFIG_GET_CFM, CsrWifiSmePowerConfigGetCfmSizeof, CsrWifiSmePowerConfigGetCfmSer, CsrWifiSmePowerConfigGetCfmDes, CsrWifiSmePowerConfigGetCfmSerFree },
-    { CSR_WIFI_SME_POWER_CONFIG_SET_CFM, CsrWifiSmePowerConfigSetCfmSizeof, CsrWifiSmePowerConfigSetCfmSer, CsrWifiSmePowerConfigSetCfmDes, CsrWifiSmePowerConfigSetCfmSerFree },
-    { CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_CFM, CsrWifiSmeRegulatoryDomainInfoGetCfmSizeof, CsrWifiSmeRegulatoryDomainInfoGetCfmSer, CsrWifiSmeRegulatoryDomainInfoGetCfmDes, CsrWifiSmeRegulatoryDomainInfoGetCfmSerFree },
-    { CSR_WIFI_SME_ROAM_COMPLETE_IND, CsrWifiSmeRoamCompleteIndSizeof, CsrWifiSmeRoamCompleteIndSer, CsrWifiSmeRoamCompleteIndDes, CsrWifiSmeRoamCompleteIndSerFree },
-    { CSR_WIFI_SME_ROAM_START_IND, CsrWifiSmeRoamStartIndSizeof, CsrWifiSmeRoamStartIndSer, CsrWifiSmeRoamStartIndDes, CsrWifiSmeRoamStartIndSerFree },
-    { CSR_WIFI_SME_ROAMING_CONFIG_GET_CFM, CsrWifiSmeRoamingConfigGetCfmSizeof, CsrWifiSmeRoamingConfigGetCfmSer, CsrWifiSmeRoamingConfigGetCfmDes, CsrWifiSmeRoamingConfigGetCfmSerFree },
-    { CSR_WIFI_SME_ROAMING_CONFIG_SET_CFM, CsrWifiSmeRoamingConfigSetCfmSizeof, CsrWifiSmeRoamingConfigSetCfmSer, CsrWifiSmeRoamingConfigSetCfmDes, CsrWifiSmeRoamingConfigSetCfmSerFree },
-    { CSR_WIFI_SME_SCAN_CONFIG_GET_CFM, CsrWifiSmeScanConfigGetCfmSizeof, CsrWifiSmeScanConfigGetCfmSer, CsrWifiSmeScanConfigGetCfmDes, CsrWifiSmeScanConfigGetCfmSerFree },
-    { CSR_WIFI_SME_SCAN_CONFIG_SET_CFM, CsrWifiSmeScanConfigSetCfmSizeof, CsrWifiSmeScanConfigSetCfmSer, CsrWifiSmeScanConfigSetCfmDes, CsrWifiSmeScanConfigSetCfmSerFree },
-    { CSR_WIFI_SME_SCAN_FULL_CFM, CsrWifiSmeScanFullCfmSizeof, CsrWifiSmeScanFullCfmSer, CsrWifiSmeScanFullCfmDes, CsrWifiSmeScanFullCfmSerFree },
-    { CSR_WIFI_SME_SCAN_RESULT_IND, CsrWifiSmeScanResultIndSizeof, CsrWifiSmeScanResultIndSer, CsrWifiSmeScanResultIndDes, CsrWifiSmeScanResultIndSerFree },
-    { CSR_WIFI_SME_SCAN_RESULTS_FLUSH_CFM, CsrWifiSmeScanResultsFlushCfmSizeof, CsrWifiSmeScanResultsFlushCfmSer, CsrWifiSmeScanResultsFlushCfmDes, CsrWifiSmeScanResultsFlushCfmSerFree },
-    { CSR_WIFI_SME_SCAN_RESULTS_GET_CFM, CsrWifiSmeScanResultsGetCfmSizeof, CsrWifiSmeScanResultsGetCfmSer, CsrWifiSmeScanResultsGetCfmDes, CsrWifiSmeScanResultsGetCfmSerFree },
-    { CSR_WIFI_SME_SME_STA_CONFIG_GET_CFM, CsrWifiSmeSmeStaConfigGetCfmSizeof, CsrWifiSmeSmeStaConfigGetCfmSer, CsrWifiSmeSmeStaConfigGetCfmDes, CsrWifiSmeSmeStaConfigGetCfmSerFree },
-    { CSR_WIFI_SME_SME_STA_CONFIG_SET_CFM, CsrWifiSmeSmeStaConfigSetCfmSizeof, CsrWifiSmeSmeStaConfigSetCfmSer, CsrWifiSmeSmeStaConfigSetCfmDes, CsrWifiSmeSmeStaConfigSetCfmSerFree },
-    { CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_CFM, CsrWifiSmeStationMacAddressGetCfmSizeof, CsrWifiSmeStationMacAddressGetCfmSer, CsrWifiSmeStationMacAddressGetCfmDes, CsrWifiSmeStationMacAddressGetCfmSerFree },
-    { CSR_WIFI_SME_TSPEC_IND, CsrWifiSmeTspecIndSizeof, CsrWifiSmeTspecIndSer, CsrWifiSmeTspecIndDes, CsrWifiSmeTspecIndSerFree },
-    { CSR_WIFI_SME_TSPEC_CFM, CsrWifiSmeTspecCfmSizeof, CsrWifiSmeTspecCfmSer, CsrWifiSmeTspecCfmDes, CsrWifiSmeTspecCfmSerFree },
-    { CSR_WIFI_SME_VERSIONS_GET_CFM, CsrWifiSmeVersionsGetCfmSizeof, CsrWifiSmeVersionsGetCfmSer, CsrWifiSmeVersionsGetCfmDes, CsrWifiSmeVersionsGetCfmSerFree },
-    { CSR_WIFI_SME_WIFI_FLIGHTMODE_CFM, CsrWifiSmeWifiFlightmodeCfmSizeof, CsrWifiSmeWifiFlightmodeCfmSer, CsrWifiSmeWifiFlightmodeCfmDes, CsrWifiSmeWifiFlightmodeCfmSerFree },
-    { CSR_WIFI_SME_WIFI_OFF_IND, CsrWifiSmeWifiOffIndSizeof, CsrWifiSmeWifiOffIndSer, CsrWifiSmeWifiOffIndDes, CsrWifiSmeWifiOffIndSerFree },
-    { CSR_WIFI_SME_WIFI_OFF_CFM, CsrWifiSmeWifiOffCfmSizeof, CsrWifiSmeWifiOffCfmSer, CsrWifiSmeWifiOffCfmDes, CsrWifiSmeWifiOffCfmSerFree },
-    { CSR_WIFI_SME_WIFI_ON_CFM, CsrWifiSmeWifiOnCfmSizeof, CsrWifiSmeWifiOnCfmSer, CsrWifiSmeWifiOnCfmDes, CsrWifiSmeWifiOnCfmSerFree },
-    { CSR_WIFI_SME_CLOAKED_SSIDS_SET_CFM, CsrWifiSmeCloakedSsidsSetCfmSizeof, CsrWifiSmeCloakedSsidsSetCfmSer, CsrWifiSmeCloakedSsidsSetCfmDes, CsrWifiSmeCloakedSsidsSetCfmSerFree },
-    { CSR_WIFI_SME_CLOAKED_SSIDS_GET_CFM, CsrWifiSmeCloakedSsidsGetCfmSizeof, CsrWifiSmeCloakedSsidsGetCfmSer, CsrWifiSmeCloakedSsidsGetCfmDes, CsrWifiSmeCloakedSsidsGetCfmSerFree },
-    { CSR_WIFI_SME_WIFI_ON_IND, CsrWifiSmeWifiOnIndSizeof, CsrWifiSmeWifiOnIndSer, CsrWifiSmeWifiOnIndDes, CsrWifiSmeWifiOnIndSerFree },
-    { CSR_WIFI_SME_SME_COMMON_CONFIG_GET_CFM, CsrWifiSmeSmeCommonConfigGetCfmSizeof, CsrWifiSmeSmeCommonConfigGetCfmSer, CsrWifiSmeSmeCommonConfigGetCfmDes, CsrWifiSmeSmeCommonConfigGetCfmSerFree },
-    { CSR_WIFI_SME_SME_COMMON_CONFIG_SET_CFM, CsrWifiSmeSmeCommonConfigSetCfmSizeof, CsrWifiSmeSmeCommonConfigSetCfmSer, CsrWifiSmeSmeCommonConfigSetCfmDes, CsrWifiSmeSmeCommonConfigSetCfmSerFree },
-    { CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_CFM, CsrWifiSmeInterfaceCapabilityGetCfmSizeof, CsrWifiSmeInterfaceCapabilityGetCfmSer, CsrWifiSmeInterfaceCapabilityGetCfmDes, CsrWifiSmeInterfaceCapabilityGetCfmSerFree },
-    { CSR_WIFI_SME_ERROR_IND, CsrWifiSmeErrorIndSizeof, CsrWifiSmeErrorIndSer, CsrWifiSmeErrorIndDes, CsrWifiSmeErrorIndSerFree },
-    { CSR_WIFI_SME_INFO_IND, CsrWifiSmeInfoIndSizeof, CsrWifiSmeInfoIndSer, CsrWifiSmeInfoIndDes, CsrWifiSmeInfoIndSerFree },
-    { CSR_WIFI_SME_CORE_DUMP_IND, CsrWifiSmeCoreDumpIndSizeof, CsrWifiSmeCoreDumpIndSer, CsrWifiSmeCoreDumpIndDes, CsrWifiSmeCoreDumpIndSerFree },
-    { CSR_WIFI_SME_AMP_STATUS_CHANGE_IND, CsrWifiSmeAmpStatusChangeIndSizeof, CsrWifiSmeAmpStatusChangeIndSer, CsrWifiSmeAmpStatusChangeIndDes, CsrWifiSmeAmpStatusChangeIndSerFree },
-    { CSR_WIFI_SME_WPS_CONFIGURATION_CFM, CsrWifiSmeWpsConfigurationCfmSizeof, CsrWifiSmeWpsConfigurationCfmSer, CsrWifiSmeWpsConfigurationCfmDes, CsrWifiSmeWpsConfigurationCfmSerFree },
-
-    { 0, NULL, NULL, NULL, NULL },
-};
-
-CsrMsgConvMsgEntry* CsrWifiSmeConverterLookup(CsrMsgConvMsgEntry *ce, u16 msgType)
-{
-    if (msgType & CSR_PRIM_UPSTREAM)
-    {
-        u16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT;
-        if (idx < (CSR_WIFI_SME_PRIM_UPSTREAM_COUNT + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT) &&
-            csrwifisme_conv_lut[idx].msgType == msgType)
-        {
-            return &csrwifisme_conv_lut[idx];
-        }
-    }
-    else
-    {
-        if (msgType < CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT &&
-            csrwifisme_conv_lut[msgType].msgType == msgType)
-        {
-            return &csrwifisme_conv_lut[msgType];
-        }
-    }
-    return NULL;
-}
-
-
-void CsrWifiSmeConverterInit(void)
-{
-    CsrMsgConvInsert(CSR_WIFI_SME_PRIM, csrwifisme_conv_lut);
-    CsrMsgConvCustomLookupRegister(CSR_WIFI_SME_PRIM, CsrWifiSmeConverterLookup);
-}
-
-
-#ifdef CSR_LOG_ENABLE
-static const CsrLogPrimitiveInformation csrwifisme_conv_info = {
-    CSR_WIFI_SME_PRIM,
-    (char *)"CSR_WIFI_SME_PRIM",
-    csrwifisme_conv_lut
-};
-const CsrLogPrimitiveInformation* CsrWifiSmeTechInfoGet(void)
-{
-    return &csrwifisme_conv_info;
-}
-
-
-#endif /* CSR_LOG_ENABLE */
-#endif /* EXCLUDE_CSR_WIFI_SME_MODULE */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_converter_init.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_converter_init.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_converter_init.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_converter_init.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_SME_CONVERTER_INIT_H__
-#define CSR_WIFI_SME_CONVERTER_INIT_H__
-
-#ifndef EXCLUDE_CSR_WIFI_SME_MODULE
-
-#include "csr_msgconv.h"
-
-#ifdef CSR_LOG_ENABLE
-#include "csr_log.h"
-
-extern const CsrLogPrimitiveInformation* CsrWifiSmeTechInfoGet(void);
-#endif /* CSR_LOG_ENABLE */
-
-extern void CsrWifiSmeConverterInit(void);
-
-#else /* EXCLUDE_CSR_WIFI_SME_MODULE */
-
-#define CsrWifiSmeConverterInit()
-
-#endif /* EXCLUDE_CSR_WIFI_SME_MODULE */
-
-#endif /* CSR_WIFI_SME_CONVERTER_INIT_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,187 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/slab.h>
-#include "csr_wifi_sme_prim.h"
-#include "csr_wifi_sme_lib.h"
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrWifiSmeFreeDownstreamMessageContents
- *
- *  DESCRIPTION
- *
- *
- *  PARAMETERS
- *      eventClass: only the value CSR_WIFI_SME_PRIM will be handled
- *      message:    the message to free
- *----------------------------------------------------------------------------*/
-void CsrWifiSmeFreeDownstreamMessageContents(u16 eventClass, void *message)
-{
-    if (eventClass != CSR_WIFI_SME_PRIM)
-    {
-        return;
-    }
-    if (NULL == message)
-    {
-        return;
-    }
-
-    switch (*((CsrWifiSmePrim *) message))
-    {
-        case CSR_WIFI_SME_BLACKLIST_REQ:
-        {
-            CsrWifiSmeBlacklistReq *p = (CsrWifiSmeBlacklistReq *)message;
-            kfree(p->setAddresses);
-            p->setAddresses = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_CALIBRATION_DATA_SET_REQ:
-        {
-            CsrWifiSmeCalibrationDataSetReq *p = (CsrWifiSmeCalibrationDataSetReq *)message;
-            kfree(p->calibrationData);
-            p->calibrationData = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_CONNECT_REQ:
-        {
-            CsrWifiSmeConnectReq *p = (CsrWifiSmeConnectReq *)message;
-            kfree(p->connectionConfig.mlmeAssociateReqInformationElements);
-            p->connectionConfig.mlmeAssociateReqInformationElements = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_MIB_GET_NEXT_REQ:
-        {
-            CsrWifiSmeMibGetNextReq *p = (CsrWifiSmeMibGetNextReq *)message;
-            kfree(p->mibAttribute);
-            p->mibAttribute = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_MIB_GET_REQ:
-        {
-            CsrWifiSmeMibGetReq *p = (CsrWifiSmeMibGetReq *)message;
-            kfree(p->mibAttribute);
-            p->mibAttribute = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_MIB_SET_REQ:
-        {
-            CsrWifiSmeMibSetReq *p = (CsrWifiSmeMibSetReq *)message;
-            kfree(p->mibAttribute);
-            p->mibAttribute = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_MULTICAST_ADDRESS_REQ:
-        {
-            CsrWifiSmeMulticastAddressReq *p = (CsrWifiSmeMulticastAddressReq *)message;
-            kfree(p->setAddresses);
-            p->setAddresses = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_PACKET_FILTER_SET_REQ:
-        {
-            CsrWifiSmePacketFilterSetReq *p = (CsrWifiSmePacketFilterSetReq *)message;
-            kfree(p->filter);
-            p->filter = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_PMKID_REQ:
-        {
-            CsrWifiSmePmkidReq *p = (CsrWifiSmePmkidReq *)message;
-            kfree(p->setPmkids);
-            p->setPmkids = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_SCAN_CONFIG_SET_REQ:
-        {
-            CsrWifiSmeScanConfigSetReq *p = (CsrWifiSmeScanConfigSetReq *)message;
-            kfree(p->scanConfig.passiveChannelList);
-            p->scanConfig.passiveChannelList = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_SCAN_FULL_REQ:
-        {
-            CsrWifiSmeScanFullReq *p = (CsrWifiSmeScanFullReq *)message;
-            kfree(p->ssid);
-            p->ssid = NULL;
-            kfree(p->channelList);
-            p->channelList = NULL;
-            kfree(p->probeIe);
-            p->probeIe = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_TSPEC_REQ:
-        {
-            CsrWifiSmeTspecReq *p = (CsrWifiSmeTspecReq *)message;
-            kfree(p->tspec);
-            p->tspec = NULL;
-            kfree(p->tclas);
-            p->tclas = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ:
-        {
-            CsrWifiSmeWifiFlightmodeReq *p = (CsrWifiSmeWifiFlightmodeReq *)message;
-            {
-                u16 i1;
-                for (i1 = 0; i1 < p->mibFilesCount; i1++)
-                {
-                    kfree(p->mibFiles[i1].data);
-                    p->mibFiles[i1].data = NULL;
-                }
-            }
-            kfree(p->mibFiles);
-            p->mibFiles = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_WIFI_ON_REQ:
-        {
-            CsrWifiSmeWifiOnReq *p = (CsrWifiSmeWifiOnReq *)message;
-            {
-                u16 i1;
-                for (i1 = 0; i1 < p->mibFilesCount; i1++)
-                {
-                    kfree(p->mibFiles[i1].data);
-                    p->mibFiles[i1].data = NULL;
-                }
-            }
-            kfree(p->mibFiles);
-            p->mibFiles = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_CLOAKED_SSIDS_SET_REQ:
-        {
-            CsrWifiSmeCloakedSsidsSetReq *p = (CsrWifiSmeCloakedSsidsSetReq *)message;
-            kfree(p->cloakedSsids.cloakedSsids);
-            p->cloakedSsids.cloakedSsids = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_WPS_CONFIGURATION_REQ:
-        {
-            CsrWifiSmeWpsConfigurationReq *p = (CsrWifiSmeWpsConfigurationReq *)message;
-            kfree(p->wpsConfig.secondaryDeviceType);
-            p->wpsConfig.secondaryDeviceType = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_SET_REQ:
-        {
-            CsrWifiSmeSetReq *p = (CsrWifiSmeSetReq *)message;
-            kfree(p->data);
-            p->data = NULL;
-            break;
-        }
-
-        default:
-            break;
-    }
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_free_upstream_contents.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_free_upstream_contents.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_free_upstream_contents.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_free_upstream_contents.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,275 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/slab.h>
-#include "csr_wifi_sme_prim.h"
-#include "csr_wifi_sme_lib.h"
-
-/*----------------------------------------------------------------------------*
- *  NAME
- *      CsrWifiSmeFreeUpstreamMessageContents
- *
- *  DESCRIPTION
- *
- *
- *  PARAMETERS
- *      eventClass: only the value CSR_WIFI_SME_PRIM will be handled
- *      message:    the message to free
- *----------------------------------------------------------------------------*/
-void CsrWifiSmeFreeUpstreamMessageContents(u16 eventClass, void *message)
-{
-    if (eventClass != CSR_WIFI_SME_PRIM)
-    {
-        return;
-    }
-    if (NULL == message)
-    {
-        return;
-    }
-
-    switch (*((CsrWifiSmePrim *) message))
-    {
-        case CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND:
-        {
-            CsrWifiSmeAssociationCompleteInd *p = (CsrWifiSmeAssociationCompleteInd *)message;
-            kfree(p->connectionInfo.beaconFrame);
-            p->connectionInfo.beaconFrame = NULL;
-            kfree(p->connectionInfo.associationReqFrame);
-            p->connectionInfo.associationReqFrame = NULL;
-            kfree(p->connectionInfo.associationRspFrame);
-            p->connectionInfo.associationRspFrame = NULL;
-            kfree(p->connectionInfo.assocScanInfoElements);
-            p->connectionInfo.assocScanInfoElements = NULL;
-            kfree(p->connectionInfo.assocReqInfoElements);
-            p->connectionInfo.assocReqInfoElements = NULL;
-            kfree(p->connectionInfo.assocRspInfoElements);
-            p->connectionInfo.assocRspInfoElements = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_BLACKLIST_CFM:
-        {
-            CsrWifiSmeBlacklistCfm *p = (CsrWifiSmeBlacklistCfm *)message;
-            kfree(p->getAddresses);
-            p->getAddresses = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_CALIBRATION_DATA_GET_CFM:
-        {
-            CsrWifiSmeCalibrationDataGetCfm *p = (CsrWifiSmeCalibrationDataGetCfm *)message;
-            kfree(p->calibrationData);
-            p->calibrationData = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_CONNECTION_CONFIG_GET_CFM:
-        {
-            CsrWifiSmeConnectionConfigGetCfm *p = (CsrWifiSmeConnectionConfigGetCfm *)message;
-            kfree(p->connectionConfig.mlmeAssociateReqInformationElements);
-            p->connectionConfig.mlmeAssociateReqInformationElements = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_CONNECTION_INFO_GET_CFM:
-        {
-            CsrWifiSmeConnectionInfoGetCfm *p = (CsrWifiSmeConnectionInfoGetCfm *)message;
-            kfree(p->connectionInfo.beaconFrame);
-            p->connectionInfo.beaconFrame = NULL;
-            kfree(p->connectionInfo.associationReqFrame);
-            p->connectionInfo.associationReqFrame = NULL;
-            kfree(p->connectionInfo.associationRspFrame);
-            p->connectionInfo.associationRspFrame = NULL;
-            kfree(p->connectionInfo.assocScanInfoElements);
-            p->connectionInfo.assocScanInfoElements = NULL;
-            kfree(p->connectionInfo.assocReqInfoElements);
-            p->connectionInfo.assocReqInfoElements = NULL;
-            kfree(p->connectionInfo.assocRspInfoElements);
-            p->connectionInfo.assocRspInfoElements = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_MEDIA_STATUS_IND:
-        {
-            CsrWifiSmeMediaStatusInd *p = (CsrWifiSmeMediaStatusInd *)message;
-            kfree(p->connectionInfo.beaconFrame);
-            p->connectionInfo.beaconFrame = NULL;
-            kfree(p->connectionInfo.associationReqFrame);
-            p->connectionInfo.associationReqFrame = NULL;
-            kfree(p->connectionInfo.associationRspFrame);
-            p->connectionInfo.associationRspFrame = NULL;
-            kfree(p->connectionInfo.assocScanInfoElements);
-            p->connectionInfo.assocScanInfoElements = NULL;
-            kfree(p->connectionInfo.assocReqInfoElements);
-            p->connectionInfo.assocReqInfoElements = NULL;
-            kfree(p->connectionInfo.assocRspInfoElements);
-            p->connectionInfo.assocRspInfoElements = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_MIB_GET_CFM:
-        {
-            CsrWifiSmeMibGetCfm *p = (CsrWifiSmeMibGetCfm *)message;
-            kfree(p->mibAttribute);
-            p->mibAttribute = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_MIB_GET_NEXT_CFM:
-        {
-            CsrWifiSmeMibGetNextCfm *p = (CsrWifiSmeMibGetNextCfm *)message;
-            kfree(p->mibAttribute);
-            p->mibAttribute = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_MULTICAST_ADDRESS_CFM:
-        {
-            CsrWifiSmeMulticastAddressCfm *p = (CsrWifiSmeMulticastAddressCfm *)message;
-            kfree(p->getAddresses);
-            p->getAddresses = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_PMKID_CANDIDATE_LIST_IND:
-        {
-            CsrWifiSmePmkidCandidateListInd *p = (CsrWifiSmePmkidCandidateListInd *)message;
-            kfree(p->pmkidCandidates);
-            p->pmkidCandidates = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_PMKID_CFM:
-        {
-            CsrWifiSmePmkidCfm *p = (CsrWifiSmePmkidCfm *)message;
-            kfree(p->getPmkids);
-            p->getPmkids = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_SCAN_CONFIG_GET_CFM:
-        {
-            CsrWifiSmeScanConfigGetCfm *p = (CsrWifiSmeScanConfigGetCfm *)message;
-            kfree(p->scanConfig.passiveChannelList);
-            p->scanConfig.passiveChannelList = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_SCAN_RESULT_IND:
-        {
-            CsrWifiSmeScanResultInd *p = (CsrWifiSmeScanResultInd *)message;
-            kfree(p->result.informationElements);
-            p->result.informationElements = NULL;
-            switch (p->result.p2pDeviceRole)
-            {
-                case CSR_WIFI_SME_P2P_ROLE_GO:
-                {
-                    u16 i4;
-                    for (i4 = 0; i4 < p->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-                    {
-                        kfree(p->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType);
-                        p->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = NULL;
-                    }
-                }
-                    kfree(p->result.deviceInfo.groupInfo.p2PClientInfo);
-                    p->result.deviceInfo.groupInfo.p2PClientInfo = NULL;
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-                    kfree(p->result.deviceInfo.standalonedevInfo.secDeviceType);
-                    p->result.deviceInfo.standalonedevInfo.secDeviceType = NULL;
-                    break;
-                default:
-                    break;
-            }
-            break;
-        }
-        case CSR_WIFI_SME_SCAN_RESULTS_GET_CFM:
-        {
-            CsrWifiSmeScanResultsGetCfm *p = (CsrWifiSmeScanResultsGetCfm *)message;
-            {
-                u16 i1;
-                for (i1 = 0; i1 < p->scanResultsCount; i1++)
-                {
-                    kfree(p->scanResults[i1].informationElements);
-                    p->scanResults[i1].informationElements = NULL;
-                    switch (p->scanResults[i1].p2pDeviceRole)
-                    {
-                        case CSR_WIFI_SME_P2P_ROLE_GO:
-                        {
-                            u16 i4;
-                            for (i4 = 0; i4 < p->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-                            {
-                                kfree(p->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType);
-                                p->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = NULL;
-                            }
-                        }
-                            kfree(p->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo);
-                            p->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo = NULL;
-                            break;
-                        case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-                            kfree(p->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType);
-                            p->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType = NULL;
-                            break;
-                        default:
-                            break;
-                    }
-                }
-            }
-            kfree(p->scanResults);
-            p->scanResults = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_TSPEC_IND:
-        {
-            CsrWifiSmeTspecInd *p = (CsrWifiSmeTspecInd *)message;
-            kfree(p->tspec);
-            p->tspec = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_TSPEC_CFM:
-        {
-            CsrWifiSmeTspecCfm *p = (CsrWifiSmeTspecCfm *)message;
-            kfree(p->tspec);
-            p->tspec = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_VERSIONS_GET_CFM:
-        {
-            CsrWifiSmeVersionsGetCfm *p = (CsrWifiSmeVersionsGetCfm *)message;
-            kfree(p->versions.routerBuild);
-            p->versions.routerBuild = NULL;
-            kfree(p->versions.smeBuild);
-            p->versions.smeBuild = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_CLOAKED_SSIDS_GET_CFM:
-        {
-            CsrWifiSmeCloakedSsidsGetCfm *p = (CsrWifiSmeCloakedSsidsGetCfm *)message;
-            kfree(p->cloakedSsids.cloakedSsids);
-            p->cloakedSsids.cloakedSsids = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_ERROR_IND:
-        {
-            CsrWifiSmeErrorInd *p = (CsrWifiSmeErrorInd *)message;
-            kfree(p->errorMessage);
-            p->errorMessage = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_INFO_IND:
-        {
-            CsrWifiSmeInfoInd *p = (CsrWifiSmeInfoInd *)message;
-            kfree(p->infoMessage);
-            p->infoMessage = NULL;
-            break;
-        }
-        case CSR_WIFI_SME_CORE_DUMP_IND:
-        {
-            CsrWifiSmeCoreDumpInd *p = (CsrWifiSmeCoreDumpInd *)message;
-            kfree(p->data);
-            p->data = NULL;
-            break;
-        }
-
-        default:
-            break;
-    }
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_lib.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_lib.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_lib.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_lib.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,4303 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_SME_LIB_H__
-#define CSR_WIFI_SME_LIB_H__
-
-#include "csr_sched.h"
-#include "csr_macro.h"
-#include "csr_msg_transport.h"
-
-#include "csr_wifi_lib.h"
-
-#include "csr_wifi_sme_prim.h"
-#include "csr_wifi_sme_task.h"
-
-
-#ifndef CSR_WIFI_SME_LIB_DESTINATION_QUEUE
-# ifdef CSR_WIFI_NME_ENABLE
-# include "csr_wifi_nme_task.h"
-# define CSR_WIFI_SME_LIB_DESTINATION_QUEUE CSR_WIFI_NME_IFACEQUEUE
-# else
-# define CSR_WIFI_SME_LIB_DESTINATION_QUEUE CSR_WIFI_SME_IFACEQUEUE
-# endif
-#endif
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiSmeFreeUpstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_SME upstream message. Does not
- *      free the message itself, and can only be used for upstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_SME upstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiSmeFreeUpstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- *  CsrWifiSmeFreeDownstreamMessageContents
- *
- *  DESCRIPTION
- *      Free the allocated memory in a CSR_WIFI_SME downstream message. Does not
- *      free the message itself, and can only be used for downstream messages.
- *
- *  PARAMETERS
- *      Deallocates the resources in a CSR_WIFI_SME downstream message
- *----------------------------------------------------------------------------*/
-void CsrWifiSmeFreeDownstreamMessageContents(u16 eventClass, void *message);
-
-/*----------------------------------------------------------------------------*
- * Enum to string functions
- *----------------------------------------------------------------------------*/
-const char* CsrWifiSme80211NetworkTypeToString(CsrWifiSme80211NetworkType value);
-const char* CsrWifiSme80211PrivacyModeToString(CsrWifiSme80211PrivacyMode value);
-const char* CsrWifiSme80211dTrustLevelToString(CsrWifiSme80211dTrustLevel value);
-const char* CsrWifiSmeAmpStatusToString(CsrWifiSmeAmpStatus value);
-const char* CsrWifiSmeAuthModeToString(CsrWifiSmeAuthMode value);
-const char* CsrWifiSmeBasicUsabilityToString(CsrWifiSmeBasicUsability value);
-const char* CsrWifiSmeBssTypeToString(CsrWifiSmeBssType value);
-const char* CsrWifiSmeCoexSchemeToString(CsrWifiSmeCoexScheme value);
-const char* CsrWifiSmeControlIndicationToString(CsrWifiSmeControlIndication value);
-const char* CsrWifiSmeCtsProtectionTypeToString(CsrWifiSmeCtsProtectionType value);
-const char* CsrWifiSmeD3AutoScanModeToString(CsrWifiSmeD3AutoScanMode value);
-const char* CsrWifiSmeEncryptionToString(CsrWifiSmeEncryption value);
-const char* CsrWifiSmeFirmwareDriverInterfaceToString(CsrWifiSmeFirmwareDriverInterface value);
-const char* CsrWifiSmeHostPowerModeToString(CsrWifiSmeHostPowerMode value);
-const char* CsrWifiSmeIEEE80211ReasonToString(CsrWifiSmeIEEE80211Reason value);
-const char* CsrWifiSmeIEEE80211ResultToString(CsrWifiSmeIEEE80211Result value);
-const char* CsrWifiSmeIndicationsToString(CsrWifiSmeIndications value);
-const char* CsrWifiSmeKeyTypeToString(CsrWifiSmeKeyType value);
-const char* CsrWifiSmeListActionToString(CsrWifiSmeListAction value);
-const char* CsrWifiSmeMediaStatusToString(CsrWifiSmeMediaStatus value);
-const char* CsrWifiSmeP2pCapabilityToString(CsrWifiSmeP2pCapability value);
-const char* CsrWifiSmeP2pGroupCapabilityToString(CsrWifiSmeP2pGroupCapability value);
-const char* CsrWifiSmeP2pNoaConfigMethodToString(CsrWifiSmeP2pNoaConfigMethod value);
-const char* CsrWifiSmeP2pRoleToString(CsrWifiSmeP2pRole value);
-const char* CsrWifiSmeP2pStatusToString(CsrWifiSmeP2pStatus value);
-const char* CsrWifiSmePacketFilterModeToString(CsrWifiSmePacketFilterMode value);
-const char* CsrWifiSmePowerSaveLevelToString(CsrWifiSmePowerSaveLevel value);
-const char* CsrWifiSmePreambleTypeToString(CsrWifiSmePreambleType value);
-const char* CsrWifiSmeRadioIFToString(CsrWifiSmeRadioIF value);
-const char* CsrWifiSmeRegulatoryDomainToString(CsrWifiSmeRegulatoryDomain value);
-const char* CsrWifiSmeRoamReasonToString(CsrWifiSmeRoamReason value);
-const char* CsrWifiSmeScanTypeToString(CsrWifiSmeScanType value);
-const char* CsrWifiSmeTrafficTypeToString(CsrWifiSmeTrafficType value);
-const char* CsrWifiSmeTspecCtrlToString(CsrWifiSmeTspecCtrl value);
-const char* CsrWifiSmeTspecResultCodeToString(CsrWifiSmeTspecResultCode value);
-const char* CsrWifiSmeWepAuthModeToString(CsrWifiSmeWepAuthMode value);
-const char* CsrWifiSmeWepCredentialTypeToString(CsrWifiSmeWepCredentialType value);
-const char* CsrWifiSmeWmmModeToString(CsrWifiSmeWmmMode value);
-const char* CsrWifiSmeWmmQosInfoToString(CsrWifiSmeWmmQosInfo value);
-const char* CsrWifiSmeWpsConfigTypeToString(CsrWifiSmeWpsConfigType value);
-const char* CsrWifiSmeWpsDeviceCategoryToString(CsrWifiSmeWpsDeviceCategory value);
-const char* CsrWifiSmeWpsDeviceSubCategoryToString(CsrWifiSmeWpsDeviceSubCategory value);
-const char* CsrWifiSmeWpsDpidToString(CsrWifiSmeWpsDpid value);
-const char* CsrWifiSmeWpsRegistrationToString(CsrWifiSmeWpsRegistration value);
-
-
-/*----------------------------------------------------------------------------*
- * CsrPrim Type toString function.
- * Converts a message type to the String name of the Message
- *----------------------------------------------------------------------------*/
-const char* CsrWifiSmePrimTypeToString(CsrPrim msgType);
-
-/*----------------------------------------------------------------------------*
- * Lookup arrays for PrimType name Strings
- *----------------------------------------------------------------------------*/
-extern const char *CsrWifiSmeUpstreamPrimNames[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT];
-extern const char *CsrWifiSmeDownstreamPrimNames[CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT];
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeActivateReqSend
-
-  DESCRIPTION
-    The WMA sends this primitive to activate the SME.
-    The WMA must activate the SME before it can send any other primitive.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeActivateReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeActivateReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ACTIVATE_REQ, dst__, src__);
-
-#define CsrWifiSmeActivateReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeActivateReq *msg__; \
-        CsrWifiSmeActivateReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeActivateReqSend(src__) \
-    CsrWifiSmeActivateReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeActivateCfmSend
-
-  DESCRIPTION
-    The SME sends this primitive when the activation is complete.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeActivateCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeActivateCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ACTIVATE_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeActivateCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeActivateCfm *msg__; \
-        CsrWifiSmeActivateCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeActivateCfmSend(dst__, status__) \
-    CsrWifiSmeActivateCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAdhocConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the adHocConfig parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeAdhocConfigGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeAdhocConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ADHOC_CONFIG_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeAdhocConfigGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeAdhocConfigGetReq *msg__; \
-        CsrWifiSmeAdhocConfigGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeAdhocConfigGetReqSend(src__) \
-    CsrWifiSmeAdhocConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAdhocConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue       - Destination Task Queue
-    status      - Reports the result of the request
-    adHocConfig - Contains the values used when starting an Ad-hoc (IBSS)
-                  connection.
-
-*******************************************************************************/
-#define CsrWifiSmeAdhocConfigGetCfmCreate(msg__, dst__, src__, status__, adHocConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeAdhocConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->adHocConfig = (adHocConfig__);
-
-#define CsrWifiSmeAdhocConfigGetCfmSendTo(dst__, src__, status__, adHocConfig__) \
-    { \
-        CsrWifiSmeAdhocConfigGetCfm *msg__; \
-        CsrWifiSmeAdhocConfigGetCfmCreate(msg__, dst__, src__, status__, adHocConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeAdhocConfigGetCfmSend(dst__, status__, adHocConfig__) \
-    CsrWifiSmeAdhocConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, adHocConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAdhocConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the adHocConfig parameter.
-
-  PARAMETERS
-    queue       - Message Source Task Queue (Cfm's will be sent to this Queue)
-    adHocConfig - Sets the values to use when starting an ad hoc network.
-
-*******************************************************************************/
-#define CsrWifiSmeAdhocConfigSetReqCreate(msg__, dst__, src__, adHocConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeAdhocConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ADHOC_CONFIG_SET_REQ, dst__, src__); \
-    msg__->adHocConfig = (adHocConfig__);
-
-#define CsrWifiSmeAdhocConfigSetReqSendTo(dst__, src__, adHocConfig__) \
-    { \
-        CsrWifiSmeAdhocConfigSetReq *msg__; \
-        CsrWifiSmeAdhocConfigSetReqCreate(msg__, dst__, src__, adHocConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeAdhocConfigSetReqSend(src__, adHocConfig__) \
-    CsrWifiSmeAdhocConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, adHocConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAdhocConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeAdhocConfigSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeAdhocConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeAdhocConfigSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeAdhocConfigSetCfm *msg__; \
-        CsrWifiSmeAdhocConfigSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeAdhocConfigSetCfmSend(dst__, status__) \
-    CsrWifiSmeAdhocConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAmpStatusChangeIndSend
-
-  DESCRIPTION
-    Indication of change to AMP activity.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface on which the AMP activity changed.
-    ampStatus    - The new status of AMP activity.Range: {AMP_ACTIVE,
-                   AMP_INACTIVE}.
-
-*******************************************************************************/
-#define CsrWifiSmeAmpStatusChangeIndCreate(msg__, dst__, src__, interfaceTag__, ampStatus__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeAmpStatusChangeInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_AMP_STATUS_CHANGE_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->ampStatus = (ampStatus__);
-
-#define CsrWifiSmeAmpStatusChangeIndSendTo(dst__, src__, interfaceTag__, ampStatus__) \
-    { \
-        CsrWifiSmeAmpStatusChangeInd *msg__; \
-        CsrWifiSmeAmpStatusChangeIndCreate(msg__, dst__, src__, interfaceTag__, ampStatus__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeAmpStatusChangeIndSend(dst__, interfaceTag__, ampStatus__) \
-    CsrWifiSmeAmpStatusChangeIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, ampStatus__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAssociationCompleteIndSend
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it whenever it completes an attempt to associate with an AP. If
-    the association was successful, status will be set to
-    CSR_WIFI_SME_STATUS_SUCCESS, otherwise status and deauthReason shall be
-    set to appropriate error codes.
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    status         - Reports the result of the association procedure
-    connectionInfo - This parameter is relevant only if result is
-                     CSR_WIFI_SME_STATUS_SUCCESS:
-                     it points to the connection information for the new network
-    deauthReason   - This parameter is relevant only if result is not
-                     CSR_WIFI_SME_STATUS_SUCCESS:
-                     if the AP deauthorised the station, it gives the reason of
-                     the deauthorization
-
-*******************************************************************************/
-#define CsrWifiSmeAssociationCompleteIndCreate(msg__, dst__, src__, interfaceTag__, status__, connectionInfo__, deauthReason__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeAssociationCompleteInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->connectionInfo = (connectionInfo__); \
-    msg__->deauthReason = (deauthReason__);
-
-#define CsrWifiSmeAssociationCompleteIndSendTo(dst__, src__, interfaceTag__, status__, connectionInfo__, deauthReason__) \
-    { \
-        CsrWifiSmeAssociationCompleteInd *msg__; \
-        CsrWifiSmeAssociationCompleteIndCreate(msg__, dst__, src__, interfaceTag__, status__, connectionInfo__, deauthReason__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeAssociationCompleteIndSend(dst__, interfaceTag__, status__, connectionInfo__, deauthReason__) \
-    CsrWifiSmeAssociationCompleteIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, connectionInfo__, deauthReason__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAssociationStartIndSend
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it whenever it begins an attempt to associate with an AP.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    address      - BSSID of the associating network
-    ssid         - Service Set identifier of the associating network
-
-*******************************************************************************/
-#define CsrWifiSmeAssociationStartIndCreate(msg__, dst__, src__, interfaceTag__, address__, ssid__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeAssociationStartInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ASSOCIATION_START_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->address = (address__); \
-    msg__->ssid = (ssid__);
-
-#define CsrWifiSmeAssociationStartIndSendTo(dst__, src__, interfaceTag__, address__, ssid__) \
-    { \
-        CsrWifiSmeAssociationStartInd *msg__; \
-        CsrWifiSmeAssociationStartIndCreate(msg__, dst__, src__, interfaceTag__, address__, ssid__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeAssociationStartIndSend(dst__, interfaceTag__, address__, ssid__) \
-    CsrWifiSmeAssociationStartIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, address__, ssid__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeBlacklistReqSend
-
-  DESCRIPTION
-    The wireless manager application should call this primitive to notify the
-    driver of any networks that should not be connected to. The interface
-    allows the wireless manager application to query, add, remove, and flush
-    the BSSIDs that the driver may not connect or roam to.
-    When this primitive adds to the black list the BSSID to which the SME is
-    currently connected, the SME will try to roam, if applicable, to another
-    BSSID in the same ESS; if the roaming procedure fails, the SME will
-    disconnect.
-
-  PARAMETERS
-    queue           - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    action          - The value of the CsrWifiSmeListAction parameter instructs
-                      the driver to modify or provide the list of blacklisted
-                      networks.
-    setAddressCount - Number of BSSIDs sent with this primitive
-    setAddresses    - Pointer to the list of BBSIDs sent with the primitive, set
-                      to NULL if none is sent.
-
-*******************************************************************************/
-#define CsrWifiSmeBlacklistReqCreate(msg__, dst__, src__, interfaceTag__, action__, setAddressCount__, setAddresses__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeBlacklistReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_BLACKLIST_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->action = (action__); \
-    msg__->setAddressCount = (setAddressCount__); \
-    msg__->setAddresses = (setAddresses__);
-
-#define CsrWifiSmeBlacklistReqSendTo(dst__, src__, interfaceTag__, action__, setAddressCount__, setAddresses__) \
-    { \
-        CsrWifiSmeBlacklistReq *msg__; \
-        CsrWifiSmeBlacklistReqCreate(msg__, dst__, src__, interfaceTag__, action__, setAddressCount__, setAddresses__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeBlacklistReqSend(src__, interfaceTag__, action__, setAddressCount__, setAddresses__) \
-    CsrWifiSmeBlacklistReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, setAddressCount__, setAddresses__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeBlacklistCfmSend
-
-  DESCRIPTION
-    The SME will call this primitive when the action on the blacklist has
-    completed. For a GET action, this primitive also reports the list of
-    BBSIDs in the blacklist.
-
-  PARAMETERS
-    queue           - Destination Task Queue
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    status          - Reports the result of the request
-    action          - Action in the request
-    getAddressCount - This parameter is only relevant if action is
-                      CSR_WIFI_SME_LIST_ACTION_GET:
-                      number of BSSIDs sent with this primitive
-    getAddresses    - Pointer to the list of BBSIDs sent with the primitive, set
-                      to NULL if none is sent.
-
-*******************************************************************************/
-#define CsrWifiSmeBlacklistCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getAddressCount__, getAddresses__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeBlacklistCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_BLACKLIST_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->action = (action__); \
-    msg__->getAddressCount = (getAddressCount__); \
-    msg__->getAddresses = (getAddresses__);
-
-#define CsrWifiSmeBlacklistCfmSendTo(dst__, src__, interfaceTag__, status__, action__, getAddressCount__, getAddresses__) \
-    { \
-        CsrWifiSmeBlacklistCfm *msg__; \
-        CsrWifiSmeBlacklistCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getAddressCount__, getAddresses__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeBlacklistCfmSend(dst__, interfaceTag__, status__, action__, getAddressCount__, getAddresses__) \
-    CsrWifiSmeBlacklistCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, action__, getAddressCount__, getAddresses__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCalibrationDataGetReqSend
-
-  DESCRIPTION
-    This primitive retrieves the Wi-Fi radio calibration data.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeCalibrationDataGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCalibrationDataGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CALIBRATION_DATA_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeCalibrationDataGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeCalibrationDataGetReq *msg__; \
-        CsrWifiSmeCalibrationDataGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCalibrationDataGetReqSend(src__) \
-    CsrWifiSmeCalibrationDataGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCalibrationDataGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue                 - Destination Task Queue
-    status                - Reports the result of the request
-    calibrationDataLength - Number of bytes in the buffer pointed by
-                            calibrationData
-    calibrationData       - Pointer to a buffer of length calibrationDataLength
-                            containing the calibration data
-
-*******************************************************************************/
-#define CsrWifiSmeCalibrationDataGetCfmCreate(msg__, dst__, src__, status__, calibrationDataLength__, calibrationData__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCalibrationDataGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CALIBRATION_DATA_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->calibrationDataLength = (calibrationDataLength__); \
-    msg__->calibrationData = (calibrationData__);
-
-#define CsrWifiSmeCalibrationDataGetCfmSendTo(dst__, src__, status__, calibrationDataLength__, calibrationData__) \
-    { \
-        CsrWifiSmeCalibrationDataGetCfm *msg__; \
-        CsrWifiSmeCalibrationDataGetCfmCreate(msg__, dst__, src__, status__, calibrationDataLength__, calibrationData__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCalibrationDataGetCfmSend(dst__, status__, calibrationDataLength__, calibrationData__) \
-    CsrWifiSmeCalibrationDataGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, calibrationDataLength__, calibrationData__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCalibrationDataSetReqSend
-
-  DESCRIPTION
-    This primitive sets the Wi-Fi radio calibration data.
-    The usage of the primitive with proper calibration data will avoid
-    time-consuming configuration after power-up.
-
-  PARAMETERS
-    queue                 - Message Source Task Queue (Cfm's will be sent to this Queue)
-    calibrationDataLength - Number of bytes in the buffer pointed by
-                            calibrationData
-    calibrationData       - Pointer to a buffer of length calibrationDataLength
-                            containing the calibration data
-
-*******************************************************************************/
-#define CsrWifiSmeCalibrationDataSetReqCreate(msg__, dst__, src__, calibrationDataLength__, calibrationData__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCalibrationDataSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CALIBRATION_DATA_SET_REQ, dst__, src__); \
-    msg__->calibrationDataLength = (calibrationDataLength__); \
-    msg__->calibrationData = (calibrationData__);
-
-#define CsrWifiSmeCalibrationDataSetReqSendTo(dst__, src__, calibrationDataLength__, calibrationData__) \
-    { \
-        CsrWifiSmeCalibrationDataSetReq *msg__; \
-        CsrWifiSmeCalibrationDataSetReqCreate(msg__, dst__, src__, calibrationDataLength__, calibrationData__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCalibrationDataSetReqSend(src__, calibrationDataLength__, calibrationData__) \
-    CsrWifiSmeCalibrationDataSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, calibrationDataLength__, calibrationData__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCalibrationDataSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeCalibrationDataSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCalibrationDataSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CALIBRATION_DATA_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeCalibrationDataSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeCalibrationDataSetCfm *msg__; \
-        CsrWifiSmeCalibrationDataSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCalibrationDataSetCfmSend(dst__, status__) \
-    CsrWifiSmeCalibrationDataSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCcxConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the CcxConfig parameter.
-    CURRENTLY NOT SUPPORTED.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiSmeCcxConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCcxConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CCX_CONFIG_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeCcxConfigGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeCcxConfigGetReq *msg__; \
-        CsrWifiSmeCcxConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCcxConfigGetReqSend(src__, interfaceTag__) \
-    CsrWifiSmeCcxConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCcxConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-    ccxConfig    - Currently not supported
-
-*******************************************************************************/
-#define CsrWifiSmeCcxConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, ccxConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCcxConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CCX_CONFIG_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->ccxConfig = (ccxConfig__);
-
-#define CsrWifiSmeCcxConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, ccxConfig__) \
-    { \
-        CsrWifiSmeCcxConfigGetCfm *msg__; \
-        CsrWifiSmeCcxConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, ccxConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCcxConfigGetCfmSend(dst__, interfaceTag__, status__, ccxConfig__) \
-    CsrWifiSmeCcxConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, ccxConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCcxConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the CcxConfig parameter.
-    CURRENTLY NOT SUPPORTED.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    ccxConfig    - Currently not supported
-
-*******************************************************************************/
-#define CsrWifiSmeCcxConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, ccxConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCcxConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CCX_CONFIG_SET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->ccxConfig = (ccxConfig__);
-
-#define CsrWifiSmeCcxConfigSetReqSendTo(dst__, src__, interfaceTag__, ccxConfig__) \
-    { \
-        CsrWifiSmeCcxConfigSetReq *msg__; \
-        CsrWifiSmeCcxConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, ccxConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCcxConfigSetReqSend(src__, interfaceTag__, ccxConfig__) \
-    CsrWifiSmeCcxConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, ccxConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCcxConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeCcxConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCcxConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CCX_CONFIG_SET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeCcxConfigSetCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeCcxConfigSetCfm *msg__; \
-        CsrWifiSmeCcxConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCcxConfigSetCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeCcxConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCloakedSsidsGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the CloakedSsids parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeCloakedSsidsGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCloakedSsidsGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CLOAKED_SSIDS_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeCloakedSsidsGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeCloakedSsidsGetReq *msg__; \
-        CsrWifiSmeCloakedSsidsGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCloakedSsidsGetReqSend(src__) \
-    CsrWifiSmeCloakedSsidsGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCloakedSsidsGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    status       - Reports the result of the request
-    cloakedSsids - Reports list of cloaked SSIDs that are explicitly scanned for
-                   by the driver
-
-*******************************************************************************/
-#define CsrWifiSmeCloakedSsidsGetCfmCreate(msg__, dst__, src__, status__, cloakedSsids__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCloakedSsidsGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CLOAKED_SSIDS_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->cloakedSsids = (cloakedSsids__);
-
-#define CsrWifiSmeCloakedSsidsGetCfmSendTo(dst__, src__, status__, cloakedSsids__) \
-    { \
-        CsrWifiSmeCloakedSsidsGetCfm *msg__; \
-        CsrWifiSmeCloakedSsidsGetCfmCreate(msg__, dst__, src__, status__, cloakedSsids__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCloakedSsidsGetCfmSend(dst__, status__, cloakedSsids__) \
-    CsrWifiSmeCloakedSsidsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, cloakedSsids__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCloakedSsidsSetReqSend
-
-  DESCRIPTION
-    This primitive sets the list of cloaked SSIDs for which the WMA possesses
-    profiles.
-    When the driver detects a cloaked AP, the SME will explicitly scan for it
-    using the list of cloaked SSIDs provided it, and, if the scan succeeds,
-    it will report the AP to the WMA either via CSR_WIFI_SME_SCAN_RESULT_IND
-    (if registered) or via CSR_WIFI_SCAN_RESULT_GET_CFM.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    cloakedSsids - Sets the list of cloaked SSIDs
-
-*******************************************************************************/
-#define CsrWifiSmeCloakedSsidsSetReqCreate(msg__, dst__, src__, cloakedSsids__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCloakedSsidsSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CLOAKED_SSIDS_SET_REQ, dst__, src__); \
-    msg__->cloakedSsids = (cloakedSsids__);
-
-#define CsrWifiSmeCloakedSsidsSetReqSendTo(dst__, src__, cloakedSsids__) \
-    { \
-        CsrWifiSmeCloakedSsidsSetReq *msg__; \
-        CsrWifiSmeCloakedSsidsSetReqCreate(msg__, dst__, src__, cloakedSsids__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCloakedSsidsSetReqSend(src__, cloakedSsids__) \
-    CsrWifiSmeCloakedSsidsSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, cloakedSsids__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCloakedSsidsSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeCloakedSsidsSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCloakedSsidsSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CLOAKED_SSIDS_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeCloakedSsidsSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeCloakedSsidsSetCfm *msg__; \
-        CsrWifiSmeCloakedSsidsSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCloakedSsidsSetCfmSend(dst__, status__) \
-    CsrWifiSmeCloakedSsidsSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the CoexConfig parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeCoexConfigGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCoexConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_CONFIG_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeCoexConfigGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeCoexConfigGetReq *msg__; \
-        CsrWifiSmeCoexConfigGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCoexConfigGetReqSend(src__) \
-    CsrWifiSmeCoexConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue      - Destination Task Queue
-    status     - Reports the result of the request
-    coexConfig - Reports the parameters used to configure the coexistence
-                 behaviour
-
-*******************************************************************************/
-#define CsrWifiSmeCoexConfigGetCfmCreate(msg__, dst__, src__, status__, coexConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCoexConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_CONFIG_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->coexConfig = (coexConfig__);
-
-#define CsrWifiSmeCoexConfigGetCfmSendTo(dst__, src__, status__, coexConfig__) \
-    { \
-        CsrWifiSmeCoexConfigGetCfm *msg__; \
-        CsrWifiSmeCoexConfigGetCfmCreate(msg__, dst__, src__, status__, coexConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCoexConfigGetCfmSend(dst__, status__, coexConfig__) \
-    CsrWifiSmeCoexConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, coexConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the CoexConfig parameter.
-
-  PARAMETERS
-    queue      - Message Source Task Queue (Cfm's will be sent to this Queue)
-    coexConfig - Configures the coexistence behaviour
-
-*******************************************************************************/
-#define CsrWifiSmeCoexConfigSetReqCreate(msg__, dst__, src__, coexConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCoexConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_CONFIG_SET_REQ, dst__, src__); \
-    msg__->coexConfig = (coexConfig__);
-
-#define CsrWifiSmeCoexConfigSetReqSendTo(dst__, src__, coexConfig__) \
-    { \
-        CsrWifiSmeCoexConfigSetReq *msg__; \
-        CsrWifiSmeCoexConfigSetReqCreate(msg__, dst__, src__, coexConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCoexConfigSetReqSend(src__, coexConfig__) \
-    CsrWifiSmeCoexConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, coexConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeCoexConfigSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCoexConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_CONFIG_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeCoexConfigSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeCoexConfigSetCfm *msg__; \
-        CsrWifiSmeCoexConfigSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCoexConfigSetCfmSend(dst__, status__) \
-    CsrWifiSmeCoexConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexInfoGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the CoexInfo parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeCoexInfoGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCoexInfoGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_INFO_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeCoexInfoGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeCoexInfoGetReq *msg__; \
-        CsrWifiSmeCoexInfoGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCoexInfoGetReqSend(src__) \
-    CsrWifiSmeCoexInfoGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexInfoGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue    - Destination Task Queue
-    status   - Reports the result of the request
-    coexInfo - Reports information and state related to coexistence.
-
-*******************************************************************************/
-#define CsrWifiSmeCoexInfoGetCfmCreate(msg__, dst__, src__, status__, coexInfo__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCoexInfoGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_COEX_INFO_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->coexInfo = (coexInfo__);
-
-#define CsrWifiSmeCoexInfoGetCfmSendTo(dst__, src__, status__, coexInfo__) \
-    { \
-        CsrWifiSmeCoexInfoGetCfm *msg__; \
-        CsrWifiSmeCoexInfoGetCfmCreate(msg__, dst__, src__, status__, coexInfo__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCoexInfoGetCfmSend(dst__, status__, coexInfo__) \
-    CsrWifiSmeCoexInfoGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, coexInfo__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectReqSend
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to start the
-    process of joining an 802.11 wireless network or to start an ad hoc
-    network.
-    The structure pointed by connectionConfig contains parameters describing
-    the network to join or, in case of an ad hoc network, to host or join.
-    The SME will select a network, perform the IEEE 802.11 Join, Authenticate
-    and Associate exchanges.
-    The SME selects the networks from the current scan list that match both
-    the SSID and BSSID, however either or both of these may be the wildcard
-    value. Using this rule, the following operations are possible:
-      * To connect to a network by name, specify the SSID and set the BSSID to
-        0xFF 0xFF 0xFF 0xFF 0xFF 0xFF. If there are two or more networks visible,
-        the SME will select the one with the strongest signal.
-      * To connect to a specific network, specify the BSSID. The SSID is
-        optional, but if given it must match the SSID of the network. An empty
-        SSID may be specified by setting the SSID length to zero. Please note
-        that if the BSSID is specified (i.e. not equal to 0xFF 0xFF 0xFF 0xFF
-        0xFF 0xFF), the SME will not attempt to roam if signal conditions become
-        poor, even if there is an alternative AP with an SSID that matches the
-        current network SSID.
-      * To connect to any network matching the other parameters (i.e. security,
-        etc), set the SSID length to zero and set the BSSID to 0xFF 0xFF 0xFF
-        0xFF 0xFF 0xFF. In this case, the SME will order all available networks
-        by their signal strengths and will iterate through this list until it
-        successfully connects.
-    NOTE: Specifying the BSSID will restrict the selection to one specific
-    network. If SSID and BSSID are given, they must both match the network
-    for it to be selected. To select a network based on the SSID only, the
-    wireless manager application must set the BSSID to 0xFF 0xFF 0xFF 0xFF
-    0xFF 0xFF.
-    The SME will try to connect to each network that matches the provided
-    parameters, one by one, until it succeeds or has tried unsuccessfully
-    with all the matching networks.
-    If there is no network that matches the parameters and the request allows
-    to host an ad hoc network, the SME will advertise a new ad hoc network
-    instead.
-    If the SME cannot connect, it will notify the failure in the confirm.
-
-  PARAMETERS
-    queue            - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag     - Interface Identifier; unique identifier of an interface
-    connectionConfig - Describes the candidate network to join or to host.
-
-*******************************************************************************/
-#define CsrWifiSmeConnectReqCreate(msg__, dst__, src__, interfaceTag__, connectionConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeConnectReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECT_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->connectionConfig = (connectionConfig__);
-
-#define CsrWifiSmeConnectReqSendTo(dst__, src__, interfaceTag__, connectionConfig__) \
-    { \
-        CsrWifiSmeConnectReq *msg__; \
-        CsrWifiSmeConnectReqCreate(msg__, dst__, src__, interfaceTag__, connectionConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeConnectReqSend(src__, interfaceTag__, connectionConfig__) \
-    CsrWifiSmeConnectReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, connectionConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectCfmSend
-
-  DESCRIPTION
-    The SME calls this primitive when the connection exchange is complete or
-    all connection attempts fail.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request.
-                   CSR_WIFI_SME_STATUS_NOT_FOUND: all attempts by the SME to
-                   locate the requested AP failed
-
-*******************************************************************************/
-#define CsrWifiSmeConnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeConnectCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECT_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeConnectCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeConnectCfm *msg__; \
-        CsrWifiSmeConnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeConnectCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeConnectCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the ConnectionConfig parameter.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiSmeConnectionConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeConnectionConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_CONFIG_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeConnectionConfigGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeConnectionConfigGetReq *msg__; \
-        CsrWifiSmeConnectionConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeConnectionConfigGetReqSend(src__, interfaceTag__) \
-    CsrWifiSmeConnectionConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue            - Destination Task Queue
-    interfaceTag     - Interface Identifier; unique identifier of an interface
-    status           - Reports the result of the request
-    connectionConfig - Parameters used by the SME for selecting a network
-
-*******************************************************************************/
-#define CsrWifiSmeConnectionConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeConnectionConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_CONFIG_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->connectionConfig = (connectionConfig__);
-
-#define CsrWifiSmeConnectionConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, connectionConfig__) \
-    { \
-        CsrWifiSmeConnectionConfigGetCfm *msg__; \
-        CsrWifiSmeConnectionConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeConnectionConfigGetCfmSend(dst__, interfaceTag__, status__, connectionConfig__) \
-    CsrWifiSmeConnectionConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, connectionConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionInfoGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the ConnectionInfo parameter.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiSmeConnectionInfoGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeConnectionInfoGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_INFO_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeConnectionInfoGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeConnectionInfoGetReq *msg__; \
-        CsrWifiSmeConnectionInfoGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeConnectionInfoGetReqSend(src__, interfaceTag__) \
-    CsrWifiSmeConnectionInfoGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionInfoGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    status         - Reports the result of the request
-    connectionInfo - Information about the current connection
-
-*******************************************************************************/
-#define CsrWifiSmeConnectionInfoGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionInfo__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeConnectionInfoGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_INFO_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->connectionInfo = (connectionInfo__);
-
-#define CsrWifiSmeConnectionInfoGetCfmSendTo(dst__, src__, interfaceTag__, status__, connectionInfo__) \
-    { \
-        CsrWifiSmeConnectionInfoGetCfm *msg__; \
-        CsrWifiSmeConnectionInfoGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionInfo__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeConnectionInfoGetCfmSend(dst__, interfaceTag__, status__, connectionInfo__) \
-    CsrWifiSmeConnectionInfoGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, connectionInfo__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionQualityIndSend
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it whenever the value of the current connection quality
-    parameters change by more than a certain configurable amount.
-    The wireless manager application may configure the trigger thresholds for
-    this indication using the field in smeConfig parameter of
-    CSR_WIFI_SME_SME_CONFIG_SET_REQ.
-    Connection quality messages can be suppressed by setting both thresholds
-    to zero.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    linkQuality  - Indicates the quality of the link
-
-*******************************************************************************/
-#define CsrWifiSmeConnectionQualityIndCreate(msg__, dst__, src__, interfaceTag__, linkQuality__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeConnectionQualityInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_QUALITY_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->linkQuality = (linkQuality__);
-
-#define CsrWifiSmeConnectionQualityIndSendTo(dst__, src__, interfaceTag__, linkQuality__) \
-    { \
-        CsrWifiSmeConnectionQualityInd *msg__; \
-        CsrWifiSmeConnectionQualityIndCreate(msg__, dst__, src__, interfaceTag__, linkQuality__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeConnectionQualityIndSend(dst__, interfaceTag__, linkQuality__) \
-    CsrWifiSmeConnectionQualityIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, linkQuality__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionStatsGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the ConnectionStats parameter.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiSmeConnectionStatsGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeConnectionStatsGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_STATS_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeConnectionStatsGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeConnectionStatsGetReq *msg__; \
-        CsrWifiSmeConnectionStatsGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeConnectionStatsGetReqSend(src__, interfaceTag__) \
-    CsrWifiSmeConnectionStatsGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionStatsGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue           - Destination Task Queue
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    status          - Reports the result of the request
-    connectionStats - Statistics for current connection.
-
-*******************************************************************************/
-#define CsrWifiSmeConnectionStatsGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionStats__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeConnectionStatsGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CONNECTION_STATS_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->connectionStats = (connectionStats__);
-
-#define CsrWifiSmeConnectionStatsGetCfmSendTo(dst__, src__, interfaceTag__, status__, connectionStats__) \
-    { \
-        CsrWifiSmeConnectionStatsGetCfm *msg__; \
-        CsrWifiSmeConnectionStatsGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, connectionStats__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeConnectionStatsGetCfmSend(dst__, interfaceTag__, status__, connectionStats__) \
-    CsrWifiSmeConnectionStatsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, connectionStats__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoreDumpIndSend
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive Wi-Fi Chip core dump data.
-    The core dump data may be fragmented and sent using more than one
-    indication.
-    To indicate that all the data has been sent, the last indication contains
-    a 'length' of 0 and 'data' of NULL.
-
-  PARAMETERS
-    queue      - Destination Task Queue
-    dataLength - Number of bytes in the buffer pointed to by 'data'
-    data       - Pointer to the buffer containing 'dataLength' bytes of core
-                 dump data
-
-*******************************************************************************/
-#define CsrWifiSmeCoreDumpIndCreate(msg__, dst__, src__, dataLength__, data__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeCoreDumpInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_CORE_DUMP_IND, dst__, src__); \
-    msg__->dataLength = (dataLength__); \
-    msg__->data = (data__);
-
-#define CsrWifiSmeCoreDumpIndSendTo(dst__, src__, dataLength__, data__) \
-    { \
-        CsrWifiSmeCoreDumpInd *msg__; \
-        CsrWifiSmeCoreDumpIndCreate(msg__, dst__, src__, dataLength__, data__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeCoreDumpIndSend(dst__, dataLength__, data__) \
-    CsrWifiSmeCoreDumpIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, dataLength__, data__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDeactivateReqSend
-
-  DESCRIPTION
-    The WMA sends this primitive to deactivate the SME.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeDeactivateReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeDeactivateReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_DEACTIVATE_REQ, dst__, src__);
-
-#define CsrWifiSmeDeactivateReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeDeactivateReq *msg__; \
-        CsrWifiSmeDeactivateReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeDeactivateReqSend(src__) \
-    CsrWifiSmeDeactivateReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDeactivateCfmSend
-
-  DESCRIPTION
-    The SME sends this primitive when the deactivation is complete.
-    The WMA cannot send any more primitives until it actives the SME again
-    sending another CSR_WIFI_SME_ACTIVATE_REQ.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeDeactivateCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeDeactivateCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_DEACTIVATE_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeDeactivateCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeDeactivateCfm *msg__; \
-        CsrWifiSmeDeactivateCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeDeactivateCfmSend(dst__, status__) \
-    CsrWifiSmeDeactivateCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDisconnectReqSend
-
-  DESCRIPTION
-    The wireless manager application may disconnect from the current network
-    by calling this primitive
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiSmeDisconnectReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeDisconnectReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_DISCONNECT_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeDisconnectReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeDisconnectReq *msg__; \
-        CsrWifiSmeDisconnectReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeDisconnectReqSend(src__, interfaceTag__) \
-    CsrWifiSmeDisconnectReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDisconnectCfmSend
-
-  DESCRIPTION
-    On reception of CSR_WIFI_SME_DISCONNECT_REQ the SME will perform a
-    disconnect operation, sending a CsrWifiSmeMediaStatusInd with
-    CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED and then call this primitive when
-    disconnection is complete.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeDisconnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeDisconnectCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_DISCONNECT_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeDisconnectCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeDisconnectCfm *msg__; \
-        CsrWifiSmeDisconnectCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeDisconnectCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeDisconnectCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeErrorIndSend
-
-  DESCRIPTION
-    Important error message indicating a error of some importance
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    errorMessage - Contains the error message.
-
-*******************************************************************************/
-#define CsrWifiSmeErrorIndCreate(msg__, dst__, src__, errorMessage__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeErrorInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ERROR_IND, dst__, src__); \
-    msg__->errorMessage = (errorMessage__);
-
-#define CsrWifiSmeErrorIndSendTo(dst__, src__, errorMessage__) \
-    { \
-        CsrWifiSmeErrorInd *msg__; \
-        CsrWifiSmeErrorIndCreate(msg__, dst__, src__, errorMessage__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeErrorIndSend(dst__, errorMessage__) \
-    CsrWifiSmeErrorIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, errorMessage__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeEventMaskSetReqSend
-
-  DESCRIPTION
-    The wireless manager application may register with the SME to receive
-    notification of interesting events. Indications will be sent only if the
-    wireless manager explicitly registers to be notified of that event.
-    indMask is a bit mask of values defined in CsrWifiSmeIndicationsMask.
-
-  PARAMETERS
-    queue   - Message Source Task Queue (Cfm's will be sent to this Queue)
-    indMask - Set mask with values from CsrWifiSmeIndications
-
-*******************************************************************************/
-#define CsrWifiSmeEventMaskSetReqCreate(msg__, dst__, src__, indMask__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeEventMaskSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_EVENT_MASK_SET_REQ, dst__, src__); \
-    msg__->indMask = (indMask__);
-
-#define CsrWifiSmeEventMaskSetReqSendTo(dst__, src__, indMask__) \
-    { \
-        CsrWifiSmeEventMaskSetReq *msg__; \
-        CsrWifiSmeEventMaskSetReqCreate(msg__, dst__, src__, indMask__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeEventMaskSetReqSend(src__, indMask__) \
-    CsrWifiSmeEventMaskSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, indMask__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeEventMaskSetCfmSend
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the request
-    primitive.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeEventMaskSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeEventMaskSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_EVENT_MASK_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeEventMaskSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeEventMaskSetCfm *msg__; \
-        CsrWifiSmeEventMaskSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeEventMaskSetCfmSend(dst__, status__) \
-    CsrWifiSmeEventMaskSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the hostConfig parameter.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiSmeHostConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeHostConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_HOST_CONFIG_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeHostConfigGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeHostConfigGetReq *msg__; \
-        CsrWifiSmeHostConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeHostConfigGetReqSend(src__, interfaceTag__) \
-    CsrWifiSmeHostConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-    hostConfig   - Current host power state.
-
-*******************************************************************************/
-#define CsrWifiSmeHostConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, hostConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeHostConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_HOST_CONFIG_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->hostConfig = (hostConfig__);
-
-#define CsrWifiSmeHostConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, hostConfig__) \
-    { \
-        CsrWifiSmeHostConfigGetCfm *msg__; \
-        CsrWifiSmeHostConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, hostConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeHostConfigGetCfmSend(dst__, interfaceTag__, status__, hostConfig__) \
-    CsrWifiSmeHostConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, hostConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the hostConfig parameter.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    hostConfig   - Communicates a change of host power state (for example, on
-                   mains power, on battery power etc) and of the periodicity of
-                   traffic data
-
-*******************************************************************************/
-#define CsrWifiSmeHostConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, hostConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeHostConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_HOST_CONFIG_SET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->hostConfig = (hostConfig__);
-
-#define CsrWifiSmeHostConfigSetReqSendTo(dst__, src__, interfaceTag__, hostConfig__) \
-    { \
-        CsrWifiSmeHostConfigSetReq *msg__; \
-        CsrWifiSmeHostConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, hostConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeHostConfigSetReqSend(src__, interfaceTag__, hostConfig__) \
-    CsrWifiSmeHostConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, hostConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeHostConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeHostConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_HOST_CONFIG_SET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeHostConfigSetCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeHostConfigSetCfm *msg__; \
-        CsrWifiSmeHostConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeHostConfigSetCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeHostConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeIbssStationIndSend
-
-  DESCRIPTION
-    The SME will send this primitive to indicate that a station has joined or
-    left the ad-hoc network.
-
-  PARAMETERS
-    queue       - Destination Task Queue
-    address     - MAC address of the station that has joined or left
-    isconnected - TRUE if the station joined, FALSE if the station left
-
-*******************************************************************************/
-#define CsrWifiSmeIbssStationIndCreate(msg__, dst__, src__, address__, isconnected__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeIbssStationInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_IBSS_STATION_IND, dst__, src__); \
-    msg__->address = (address__); \
-    msg__->isconnected = (isconnected__);
-
-#define CsrWifiSmeIbssStationIndSendTo(dst__, src__, address__, isconnected__) \
-    { \
-        CsrWifiSmeIbssStationInd *msg__; \
-        CsrWifiSmeIbssStationIndCreate(msg__, dst__, src__, address__, isconnected__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeIbssStationIndSend(dst__, address__, isconnected__) \
-    CsrWifiSmeIbssStationIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, address__, isconnected__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeInfoIndSend
-
-  DESCRIPTION
-    Message indicating a some info about current activity. Mostly of interest
-    in testing but may be useful in the field.
-
-  PARAMETERS
-    queue       - Destination Task Queue
-    infoMessage - Contains the message.
-
-*******************************************************************************/
-#define CsrWifiSmeInfoIndCreate(msg__, dst__, src__, infoMessage__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeInfoInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_INFO_IND, dst__, src__); \
-    msg__->infoMessage = (infoMessage__);
-
-#define CsrWifiSmeInfoIndSendTo(dst__, src__, infoMessage__) \
-    { \
-        CsrWifiSmeInfoInd *msg__; \
-        CsrWifiSmeInfoIndCreate(msg__, dst__, src__, infoMessage__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeInfoIndSend(dst__, infoMessage__) \
-    CsrWifiSmeInfoIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, infoMessage__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeInterfaceCapabilityGetReqSend
-
-  DESCRIPTION
-    The Wireless Manager calls this primitive to ask the SME for the
-    capabilities of the supported interfaces
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeInterfaceCapabilityGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeInterfaceCapabilityGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeInterfaceCapabilityGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeInterfaceCapabilityGetReq *msg__; \
-        CsrWifiSmeInterfaceCapabilityGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeInterfaceCapabilityGetReqSend(src__) \
-    CsrWifiSmeInterfaceCapabilityGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeInterfaceCapabilityGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue         - Destination Task Queue
-    status        - Result of the request
-    numInterfaces - Number of the interfaces supported
-    capBitmap     - Points to the list of capabilities bitmaps provided for each
-                    interface.
-                    The bits represent the following capabilities:
-                    -bits 7 to 4-Reserved
-                    -bit 3-AMP
-                    -bit 2-P2P
-                    -bit 1-AP
-                    -bit 0-STA
-
-*******************************************************************************/
-#define CsrWifiSmeInterfaceCapabilityGetCfmCreate(msg__, dst__, src__, status__, numInterfaces__, capBitmap__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeInterfaceCapabilityGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->numInterfaces = (numInterfaces__); \
-    memcpy(msg__->capBitmap, (capBitmap__), sizeof(u8) * 2);
-
-#define CsrWifiSmeInterfaceCapabilityGetCfmSendTo(dst__, src__, status__, numInterfaces__, capBitmap__) \
-    { \
-        CsrWifiSmeInterfaceCapabilityGetCfm *msg__; \
-        CsrWifiSmeInterfaceCapabilityGetCfmCreate(msg__, dst__, src__, status__, numInterfaces__, capBitmap__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeInterfaceCapabilityGetCfmSend(dst__, status__, numInterfaces__, capBitmap__) \
-    CsrWifiSmeInterfaceCapabilityGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, numInterfaces__, capBitmap__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeKeyReqSend
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to add or remove
-    keys that the chip should use for encryption of data.
-    The interface allows the wireless manager application to add and remove
-    keys according to the specified action.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    action       - The value of the CsrWifiSmeListAction parameter instructs the
-                   driver to modify or provide the list of keys.
-                   CSR_WIFI_SME_LIST_ACTION_GET is not supported here.
-    key          - Key to be added or removed
-
-*******************************************************************************/
-#define CsrWifiSmeKeyReqCreate(msg__, dst__, src__, interfaceTag__, action__, key__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeKeyReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_KEY_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->action = (action__); \
-    msg__->key = (key__);
-
-#define CsrWifiSmeKeyReqSendTo(dst__, src__, interfaceTag__, action__, key__) \
-    { \
-        CsrWifiSmeKeyReq *msg__; \
-        CsrWifiSmeKeyReqCreate(msg__, dst__, src__, interfaceTag__, action__, key__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeKeyReqSend(src__, interfaceTag__, action__, key__) \
-    CsrWifiSmeKeyReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, key__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeKeyCfmSend
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the request
-    primitive.
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    status         - Reports the result of the request
-    action         - Action in the request
-    keyType        - Type of the key added/deleted
-    peerMacAddress - Peer MAC Address of the key added/deleted
-
-*******************************************************************************/
-#define CsrWifiSmeKeyCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, keyType__, peerMacAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeKeyCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_KEY_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->action = (action__); \
-    msg__->keyType = (keyType__); \
-    msg__->peerMacAddress = (peerMacAddress__);
-
-#define CsrWifiSmeKeyCfmSendTo(dst__, src__, interfaceTag__, status__, action__, keyType__, peerMacAddress__) \
-    { \
-        CsrWifiSmeKeyCfm *msg__; \
-        CsrWifiSmeKeyCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, keyType__, peerMacAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeKeyCfmSend(dst__, interfaceTag__, status__, action__, keyType__, peerMacAddress__) \
-    CsrWifiSmeKeyCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, action__, keyType__, peerMacAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeLinkQualityGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the LinkQuality parameter.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiSmeLinkQualityGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeLinkQualityGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_LINK_QUALITY_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeLinkQualityGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeLinkQualityGetReq *msg__; \
-        CsrWifiSmeLinkQualityGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeLinkQualityGetReqSend(src__, interfaceTag__) \
-    CsrWifiSmeLinkQualityGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeLinkQualityGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-    linkQuality  - Indicates the quality of the link
-
-*******************************************************************************/
-#define CsrWifiSmeLinkQualityGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, linkQuality__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeLinkQualityGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_LINK_QUALITY_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->linkQuality = (linkQuality__);
-
-#define CsrWifiSmeLinkQualityGetCfmSendTo(dst__, src__, interfaceTag__, status__, linkQuality__) \
-    { \
-        CsrWifiSmeLinkQualityGetCfm *msg__; \
-        CsrWifiSmeLinkQualityGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, linkQuality__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeLinkQualityGetCfmSend(dst__, interfaceTag__, status__, linkQuality__) \
-    CsrWifiSmeLinkQualityGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, linkQuality__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMediaStatusIndSend
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it when a network connection is established, lost or has moved to
-    another AP.
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    mediaStatus    - Indicates the media status
-    connectionInfo - This parameter is relevant only if the mediaStatus is
-                     CSR_WIFI_SME_MEDIA_STATUS_CONNECTED:
-                     it points to the connection information for the new network
-    disassocReason - This parameter is relevant only if the mediaStatus is
-                     CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED:
-                     if a disassociation has occurred it gives the reason of the
-                     disassociation
-    deauthReason   - This parameter is relevant only if the mediaStatus is
-                     CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED:
-                     if a deauthentication has occurred it gives the reason of
-                     the deauthentication
-
-*******************************************************************************/
-#define CsrWifiSmeMediaStatusIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMediaStatusInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MEDIA_STATUS_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->mediaStatus = (mediaStatus__); \
-    msg__->connectionInfo = (connectionInfo__); \
-    msg__->disassocReason = (disassocReason__); \
-    msg__->deauthReason = (deauthReason__);
-
-#define CsrWifiSmeMediaStatusIndSendTo(dst__, src__, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__) \
-    { \
-        CsrWifiSmeMediaStatusInd *msg__; \
-        CsrWifiSmeMediaStatusIndCreate(msg__, dst__, src__, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMediaStatusIndSend(dst__, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__) \
-    CsrWifiSmeMediaStatusIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, mediaStatus__, connectionInfo__, disassocReason__, deauthReason__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the MibConfig parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeMibConfigGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_CONFIG_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeMibConfigGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeMibConfigGetReq *msg__; \
-        CsrWifiSmeMibConfigGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibConfigGetReqSend(src__) \
-    CsrWifiSmeMibConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue     - Destination Task Queue
-    status    - Reports the result of the request
-    mibConfig - Reports various IEEE 802.11 attributes as currently configured
-
-*******************************************************************************/
-#define CsrWifiSmeMibConfigGetCfmCreate(msg__, dst__, src__, status__, mibConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_CONFIG_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->mibConfig = (mibConfig__);
-
-#define CsrWifiSmeMibConfigGetCfmSendTo(dst__, src__, status__, mibConfig__) \
-    { \
-        CsrWifiSmeMibConfigGetCfm *msg__; \
-        CsrWifiSmeMibConfigGetCfmCreate(msg__, dst__, src__, status__, mibConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibConfigGetCfmSend(dst__, status__, mibConfig__) \
-    CsrWifiSmeMibConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, mibConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the MibConfig parameter.
-
-  PARAMETERS
-    queue     - Message Source Task Queue (Cfm's will be sent to this Queue)
-    mibConfig - Conveys the desired value of various IEEE 802.11 attributes as
-                currently configured
-
-*******************************************************************************/
-#define CsrWifiSmeMibConfigSetReqCreate(msg__, dst__, src__, mibConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_CONFIG_SET_REQ, dst__, src__); \
-    msg__->mibConfig = (mibConfig__);
-
-#define CsrWifiSmeMibConfigSetReqSendTo(dst__, src__, mibConfig__) \
-    { \
-        CsrWifiSmeMibConfigSetReq *msg__; \
-        CsrWifiSmeMibConfigSetReqCreate(msg__, dst__, src__, mibConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibConfigSetReqSend(src__, mibConfig__) \
-    CsrWifiSmeMibConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, mibConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeMibConfigSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_CONFIG_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeMibConfigSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeMibConfigSetCfm *msg__; \
-        CsrWifiSmeMibConfigSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibConfigSetCfmSend(dst__, status__) \
-    CsrWifiSmeMibConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibGetCfmSend
-
-  DESCRIPTION
-    The SME calls this primitive to return the requested MIB variable values.
-
-  PARAMETERS
-    queue              - Destination Task Queue
-    status             - Reports the result of the request
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to the VarBind or VarBindList containing the
-                         names and values of the MIB variables requested
-
-*******************************************************************************/
-#define CsrWifiSmeMibGetCfmCreate(msg__, dst__, src__, status__, mibAttributeLength__, mibAttribute__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->mibAttributeLength = (mibAttributeLength__); \
-    msg__->mibAttribute = (mibAttribute__);
-
-#define CsrWifiSmeMibGetCfmSendTo(dst__, src__, status__, mibAttributeLength__, mibAttribute__) \
-    { \
-        CsrWifiSmeMibGetCfm *msg__; \
-        CsrWifiSmeMibGetCfmCreate(msg__, dst__, src__, status__, mibAttributeLength__, mibAttribute__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibGetCfmSend(dst__, status__, mibAttributeLength__, mibAttribute__) \
-    CsrWifiSmeMibGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, mibAttributeLength__, mibAttribute__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibGetNextReqSend
-
-  DESCRIPTION
-    To read a sequence of MIB parameters, for example a table, call this
-    primitive to find the name of the next MIB variable
-
-  PARAMETERS
-    queue              - Message Source Task Queue (Cfm's will be sent to this Queue)
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to a VarBind or VarBindList containing the
-                         name(s) of the MIB variable(s) to search from.
-
-*******************************************************************************/
-#define CsrWifiSmeMibGetNextReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibGetNextReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_GET_NEXT_REQ, dst__, src__); \
-    msg__->mibAttributeLength = (mibAttributeLength__); \
-    msg__->mibAttribute = (mibAttribute__);
-
-#define CsrWifiSmeMibGetNextReqSendTo(dst__, src__, mibAttributeLength__, mibAttribute__) \
-    { \
-        CsrWifiSmeMibGetNextReq *msg__; \
-        CsrWifiSmeMibGetNextReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibGetNextReqSend(src__, mibAttributeLength__, mibAttribute__) \
-    CsrWifiSmeMibGetNextReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, mibAttributeLength__, mibAttribute__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibGetNextCfmSend
-
-  DESCRIPTION
-    The SME calls this primitive to return the requested MIB name(s).
-    The wireless manager application can then read the value of the MIB
-    variable using CSR_WIFI_SME_MIB_GET_REQ, using the names provided.
-
-  PARAMETERS
-    queue              - Destination Task Queue
-    status             - Reports the result of the request
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to a VarBind or VarBindList containing the
-                         name(s) of the MIB variable(s) lexicographically
-                         following the name(s) given in the request
-
-*******************************************************************************/
-#define CsrWifiSmeMibGetNextCfmCreate(msg__, dst__, src__, status__, mibAttributeLength__, mibAttribute__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibGetNextCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_GET_NEXT_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->mibAttributeLength = (mibAttributeLength__); \
-    msg__->mibAttribute = (mibAttribute__);
-
-#define CsrWifiSmeMibGetNextCfmSendTo(dst__, src__, status__, mibAttributeLength__, mibAttribute__) \
-    { \
-        CsrWifiSmeMibGetNextCfm *msg__; \
-        CsrWifiSmeMibGetNextCfmCreate(msg__, dst__, src__, status__, mibAttributeLength__, mibAttribute__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibGetNextCfmSend(dst__, status__, mibAttributeLength__, mibAttribute__) \
-    CsrWifiSmeMibGetNextCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, mibAttributeLength__, mibAttribute__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibGetReqSend
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to retrieve one or
-    more MIB variables.
-
-  PARAMETERS
-    queue              - Message Source Task Queue (Cfm's will be sent to this Queue)
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to the VarBind or VarBindList containing the
-                         names of the MIB variables to be retrieved
-
-*******************************************************************************/
-#define CsrWifiSmeMibGetReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_GET_REQ, dst__, src__); \
-    msg__->mibAttributeLength = (mibAttributeLength__); \
-    msg__->mibAttribute = (mibAttribute__);
-
-#define CsrWifiSmeMibGetReqSendTo(dst__, src__, mibAttributeLength__, mibAttribute__) \
-    { \
-        CsrWifiSmeMibGetReq *msg__; \
-        CsrWifiSmeMibGetReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibGetReqSend(src__, mibAttributeLength__, mibAttribute__) \
-    CsrWifiSmeMibGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, mibAttributeLength__, mibAttribute__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibSetReqSend
-
-  DESCRIPTION
-    The SME provides raw access to the MIB on the chip, which may be used by
-    some configuration or diagnostic utilities, but is not normally needed by
-    the wireless manager application.
-    The MIB access functions use BER encoded names (OID) of the MIB
-    parameters and BER encoded values, as described in the chip Host
-    Interface Protocol Specification.
-    The MIB parameters are described in 'Wi-Fi 5.0.0 Management Information
-    Base Reference Guide'.
-    The wireless manager application calls this primitive to set one or more
-    MIB variables
-
-  PARAMETERS
-    queue              - Message Source Task Queue (Cfm's will be sent to this Queue)
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to the VarBind or VarBindList containing the
-                         names and values of the MIB variables to set
-
-*******************************************************************************/
-#define CsrWifiSmeMibSetReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_SET_REQ, dst__, src__); \
-    msg__->mibAttributeLength = (mibAttributeLength__); \
-    msg__->mibAttribute = (mibAttribute__);
-
-#define CsrWifiSmeMibSetReqSendTo(dst__, src__, mibAttributeLength__, mibAttribute__) \
-    { \
-        CsrWifiSmeMibSetReq *msg__; \
-        CsrWifiSmeMibSetReqCreate(msg__, dst__, src__, mibAttributeLength__, mibAttribute__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibSetReqSend(src__, mibAttributeLength__, mibAttribute__) \
-    CsrWifiSmeMibSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, mibAttributeLength__, mibAttribute__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibSetCfmSend
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the set primitive.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeMibSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMibSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIB_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeMibSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeMibSetCfm *msg__; \
-        CsrWifiSmeMibSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMibSetCfmSend(dst__, status__) \
-    CsrWifiSmeMibSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMicFailureIndSend
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it whenever the chip firmware reports a MIC failure.
-
-  PARAMETERS
-    queue         - Destination Task Queue
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    secondFailure - TRUE if this indication is for a second failure in 60
-                    seconds
-    count         - The number of MIC failure events since the connection was
-                    established
-    address       - MAC address of the transmitter that caused the MIC failure
-    keyType       - Type of key for which the failure occurred
-
-*******************************************************************************/
-#define CsrWifiSmeMicFailureIndCreate(msg__, dst__, src__, interfaceTag__, secondFailure__, count__, address__, keyType__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMicFailureInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MIC_FAILURE_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->secondFailure = (secondFailure__); \
-    msg__->count = (count__); \
-    msg__->address = (address__); \
-    msg__->keyType = (keyType__);
-
-#define CsrWifiSmeMicFailureIndSendTo(dst__, src__, interfaceTag__, secondFailure__, count__, address__, keyType__) \
-    { \
-        CsrWifiSmeMicFailureInd *msg__; \
-        CsrWifiSmeMicFailureIndCreate(msg__, dst__, src__, interfaceTag__, secondFailure__, count__, address__, keyType__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMicFailureIndSend(dst__, interfaceTag__, secondFailure__, count__, address__, keyType__) \
-    CsrWifiSmeMicFailureIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, secondFailure__, count__, address__, keyType__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMulticastAddressReqSend
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to specify the
-    multicast addresses which the chip should recognise. The interface allows
-    the wireless manager application to query, add, remove and flush the
-    multicast addresses for the network interface according to the specified
-    action.
-
-  PARAMETERS
-    queue             - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag      - Interface Identifier; unique identifier of an interface
-    action            - The value of the CsrWifiSmeListAction parameter
-                        instructs the driver to modify or provide the list of
-                        MAC addresses.
-    setAddressesCount - Number of MAC addresses sent with the primitive
-    setAddresses      - Pointer to the list of MAC Addresses sent with the
-                        primitive, set to NULL if none is sent.
-
-*******************************************************************************/
-#define CsrWifiSmeMulticastAddressReqCreate(msg__, dst__, src__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMulticastAddressReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MULTICAST_ADDRESS_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->action = (action__); \
-    msg__->setAddressesCount = (setAddressesCount__); \
-    msg__->setAddresses = (setAddresses__);
-
-#define CsrWifiSmeMulticastAddressReqSendTo(dst__, src__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \
-    { \
-        CsrWifiSmeMulticastAddressReq *msg__; \
-        CsrWifiSmeMulticastAddressReqCreate(msg__, dst__, src__, interfaceTag__, action__, setAddressesCount__, setAddresses__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMulticastAddressReqSend(src__, interfaceTag__, action__, setAddressesCount__, setAddresses__) \
-    CsrWifiSmeMulticastAddressReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, setAddressesCount__, setAddresses__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMulticastAddressCfmSend
-
-  DESCRIPTION
-    The SME will call this primitive when the operation is complete. For a
-    GET action, this primitive reports the current list of MAC addresses.
-
-  PARAMETERS
-    queue             - Destination Task Queue
-    interfaceTag      - Interface Identifier; unique identifier of an interface
-    status            - Reports the result of the request
-    action            - Action in the request
-    getAddressesCount - This parameter is only relevant if action is
-                        CSR_WIFI_SME_LIST_ACTION_GET:
-                        number of MAC addresses sent with the primitive
-    getAddresses      - Pointer to the list of MAC Addresses sent with the
-                        primitive, set to NULL if none is sent.
-
-*******************************************************************************/
-#define CsrWifiSmeMulticastAddressCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeMulticastAddressCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_MULTICAST_ADDRESS_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->action = (action__); \
-    msg__->getAddressesCount = (getAddressesCount__); \
-    msg__->getAddresses = (getAddresses__);
-
-#define CsrWifiSmeMulticastAddressCfmSendTo(dst__, src__, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__) \
-    { \
-        CsrWifiSmeMulticastAddressCfm *msg__; \
-        CsrWifiSmeMulticastAddressCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeMulticastAddressCfmSend(dst__, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__) \
-    CsrWifiSmeMulticastAddressCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, action__, getAddressesCount__, getAddresses__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePacketFilterSetReqSend
-
-  DESCRIPTION
-    The wireless manager application should call this primitive to enable or
-    disable filtering of broadcast packets: uninteresting broadcast packets
-    will be dropped by the Wi-Fi chip, instead of passing them up to the
-    host.
-    This has the advantage of saving power in the host application processor
-    as it removes the need to process unwanted packets.
-    All broadcast packets are filtered according to the filter and the filter
-    mode provided, except ARP packets, which are filtered using
-    arpFilterAddress.
-    Filters are not cumulative: only the parameters specified in the most
-    recent successful request are significant.
-    For more information, see 'UniFi Firmware API Specification'.
-
-  PARAMETERS
-    queue            - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag     - Interface Identifier; unique identifier of an interface
-    filterLength     - Length of the filter in bytes.
-                       filterLength=0 disables the filter previously set
-    filter           - Points to the first byte of the filter provided, if any.
-                       This shall include zero or more instance of the
-                       information elements of one of these types
-                         * Traffic Classification (TCLAS) elements
-                         * WMM-SA TCLAS elements
-    mode             - Specifies whether the filter selects or excludes packets
-                       matching the filter
-    arpFilterAddress - IPv4 address to be used for filtering the ARP packets.
-                         * If the specified address is the IPv4 broadcast address
-                           (255.255.255.255), all ARP packets are reported to the
-                           host,
-                         * If the specified address is NOT the IPv4 broadcast
-                           address, only ARP packets with the specified address in
-                           the Source or Target Protocol Address fields are reported
-                           to the host
-
-*******************************************************************************/
-#define CsrWifiSmePacketFilterSetReqCreate(msg__, dst__, src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePacketFilterSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PACKET_FILTER_SET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->filterLength = (filterLength__); \
-    msg__->filter = (filter__); \
-    msg__->mode = (mode__); \
-    msg__->arpFilterAddress = (arpFilterAddress__);
-
-#define CsrWifiSmePacketFilterSetReqSendTo(dst__, src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__) \
-    { \
-        CsrWifiSmePacketFilterSetReq *msg__; \
-        CsrWifiSmePacketFilterSetReqCreate(msg__, dst__, src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePacketFilterSetReqSend(src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__) \
-    CsrWifiSmePacketFilterSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, filterLength__, filter__, mode__, arpFilterAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePacketFilterSetCfmSend
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the set primitive.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmePacketFilterSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePacketFilterSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PACKET_FILTER_SET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmePacketFilterSetCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmePacketFilterSetCfm *msg__; \
-        CsrWifiSmePacketFilterSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePacketFilterSetCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmePacketFilterSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePermanentMacAddressGetReqSend
-
-  DESCRIPTION
-    This primitive retrieves the MAC address stored in EEPROM
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmePermanentMacAddressGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePermanentMacAddressGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_REQ, dst__, src__);
-
-#define CsrWifiSmePermanentMacAddressGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmePermanentMacAddressGetReq *msg__; \
-        CsrWifiSmePermanentMacAddressGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePermanentMacAddressGetReqSend(src__) \
-    CsrWifiSmePermanentMacAddressGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePermanentMacAddressGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue               - Destination Task Queue
-    status              - Reports the result of the request
-    permanentMacAddress - MAC address stored in the EEPROM
-
-*******************************************************************************/
-#define CsrWifiSmePermanentMacAddressGetCfmCreate(msg__, dst__, src__, status__, permanentMacAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePermanentMacAddressGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->permanentMacAddress = (permanentMacAddress__);
-
-#define CsrWifiSmePermanentMacAddressGetCfmSendTo(dst__, src__, status__, permanentMacAddress__) \
-    { \
-        CsrWifiSmePermanentMacAddressGetCfm *msg__; \
-        CsrWifiSmePermanentMacAddressGetCfmCreate(msg__, dst__, src__, status__, permanentMacAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePermanentMacAddressGetCfmSend(dst__, status__, permanentMacAddress__) \
-    CsrWifiSmePermanentMacAddressGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, permanentMacAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePmkidCandidateListIndSend
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it when a new network supporting preauthentication and/or PMK
-    caching is seen.
-
-  PARAMETERS
-    queue                - Destination Task Queue
-    interfaceTag         - Interface Identifier; unique identifier of an
-                           interface
-    pmkidCandidatesCount - Number of PMKID candidates provided
-    pmkidCandidates      - Points to the first PMKID candidate
-
-*******************************************************************************/
-#define CsrWifiSmePmkidCandidateListIndCreate(msg__, dst__, src__, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePmkidCandidateListInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PMKID_CANDIDATE_LIST_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->pmkidCandidatesCount = (pmkidCandidatesCount__); \
-    msg__->pmkidCandidates = (pmkidCandidates__);
-
-#define CsrWifiSmePmkidCandidateListIndSendTo(dst__, src__, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__) \
-    { \
-        CsrWifiSmePmkidCandidateListInd *msg__; \
-        CsrWifiSmePmkidCandidateListIndCreate(msg__, dst__, src__, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePmkidCandidateListIndSend(dst__, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__) \
-    CsrWifiSmePmkidCandidateListIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, pmkidCandidatesCount__, pmkidCandidates__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePmkidReqSend
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to request an
-    operation on the SME PMKID list.
-    The action argument specifies the operation to perform.
-    When the connection is complete, the wireless manager application may
-    then send and receive EAPOL packets to complete WPA or WPA2
-    authentication if appropriate.
-    The wireless manager application can then pass the resulting encryption
-    keys using this primitive.
-
-  PARAMETERS
-    queue          - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    action         - The value of the CsrWifiSmeListAction parameter instructs
-                     the driver to modify or provide the list of PMKIDs.
-    setPmkidsCount - Number of PMKIDs sent with the primitive
-    setPmkids      - Pointer to the list of PMKIDs sent with the primitive, set
-                     to NULL if none is sent.
-
-*******************************************************************************/
-#define CsrWifiSmePmkidReqCreate(msg__, dst__, src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePmkidReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PMKID_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->action = (action__); \
-    msg__->setPmkidsCount = (setPmkidsCount__); \
-    msg__->setPmkids = (setPmkids__);
-
-#define CsrWifiSmePmkidReqSendTo(dst__, src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__) \
-    { \
-        CsrWifiSmePmkidReq *msg__; \
-        CsrWifiSmePmkidReqCreate(msg__, dst__, src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePmkidReqSend(src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__) \
-    CsrWifiSmePmkidReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, setPmkidsCount__, setPmkids__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePmkidCfmSend
-
-  DESCRIPTION
-    The SME will call this primitive when the operation is complete. For a
-    GET action, this primitive reports the current list of PMKIDs
-
-  PARAMETERS
-    queue          - Destination Task Queue
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    status         - Reports the result of the request
-    action         - Action in the request
-    getPmkidsCount - This parameter is only relevant if action is
-                     CSR_WIFI_SME_LIST_ACTION_GET:
-                     number of PMKIDs sent with the primitive
-    getPmkids      - Pointer to the list of PMKIDs sent with the primitive, set
-                     to NULL if none is sent.
-
-*******************************************************************************/
-#define CsrWifiSmePmkidCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePmkidCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_PMKID_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->action = (action__); \
-    msg__->getPmkidsCount = (getPmkidsCount__); \
-    msg__->getPmkids = (getPmkids__);
-
-#define CsrWifiSmePmkidCfmSendTo(dst__, src__, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__) \
-    { \
-        CsrWifiSmePmkidCfm *msg__; \
-        CsrWifiSmePmkidCfmCreate(msg__, dst__, src__, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePmkidCfmSend(dst__, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__) \
-    CsrWifiSmePmkidCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, action__, getPmkidsCount__, getPmkids__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the PowerConfig parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmePowerConfigGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePowerConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_POWER_CONFIG_GET_REQ, dst__, src__);
-
-#define CsrWifiSmePowerConfigGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmePowerConfigGetReq *msg__; \
-        CsrWifiSmePowerConfigGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePowerConfigGetReqSend(src__) \
-    CsrWifiSmePowerConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue       - Destination Task Queue
-    status      - Reports the result of the request
-    powerConfig - Returns the current parameters for the power configuration of
-                  the firmware
-
-*******************************************************************************/
-#define CsrWifiSmePowerConfigGetCfmCreate(msg__, dst__, src__, status__, powerConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePowerConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_POWER_CONFIG_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->powerConfig = (powerConfig__);
-
-#define CsrWifiSmePowerConfigGetCfmSendTo(dst__, src__, status__, powerConfig__) \
-    { \
-        CsrWifiSmePowerConfigGetCfm *msg__; \
-        CsrWifiSmePowerConfigGetCfmCreate(msg__, dst__, src__, status__, powerConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePowerConfigGetCfmSend(dst__, status__, powerConfig__) \
-    CsrWifiSmePowerConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, powerConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the PowerConfig parameter.
-
-  PARAMETERS
-    queue       - Message Source Task Queue (Cfm's will be sent to this Queue)
-    powerConfig - Power saving configuration
-
-*******************************************************************************/
-#define CsrWifiSmePowerConfigSetReqCreate(msg__, dst__, src__, powerConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePowerConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_POWER_CONFIG_SET_REQ, dst__, src__); \
-    msg__->powerConfig = (powerConfig__);
-
-#define CsrWifiSmePowerConfigSetReqSendTo(dst__, src__, powerConfig__) \
-    { \
-        CsrWifiSmePowerConfigSetReq *msg__; \
-        CsrWifiSmePowerConfigSetReqCreate(msg__, dst__, src__, powerConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePowerConfigSetReqSend(src__, powerConfig__) \
-    CsrWifiSmePowerConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, powerConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmePowerConfigSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmePowerConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_POWER_CONFIG_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmePowerConfigSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmePowerConfigSetCfm *msg__; \
-        CsrWifiSmePowerConfigSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmePowerConfigSetCfmSend(dst__, status__) \
-    CsrWifiSmePowerConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRegulatoryDomainInfoGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the RegulatoryDomainInfo parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeRegulatoryDomainInfoGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeRegulatoryDomainInfoGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeRegulatoryDomainInfoGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeRegulatoryDomainInfoGetReq *msg__; \
-        CsrWifiSmeRegulatoryDomainInfoGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeRegulatoryDomainInfoGetReqSend(src__) \
-    CsrWifiSmeRegulatoryDomainInfoGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRegulatoryDomainInfoGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue      - Destination Task Queue
-    status     - Reports the result of the request
-    regDomInfo - Reports information and state related to regulatory domain
-                 operation.
-
-*******************************************************************************/
-#define CsrWifiSmeRegulatoryDomainInfoGetCfmCreate(msg__, dst__, src__, status__, regDomInfo__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeRegulatoryDomainInfoGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->regDomInfo = (regDomInfo__);
-
-#define CsrWifiSmeRegulatoryDomainInfoGetCfmSendTo(dst__, src__, status__, regDomInfo__) \
-    { \
-        CsrWifiSmeRegulatoryDomainInfoGetCfm *msg__; \
-        CsrWifiSmeRegulatoryDomainInfoGetCfmCreate(msg__, dst__, src__, status__, regDomInfo__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeRegulatoryDomainInfoGetCfmSend(dst__, status__, regDomInfo__) \
-    CsrWifiSmeRegulatoryDomainInfoGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, regDomInfo__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamCompleteIndSend
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it whenever it completes an attempt to roam to an AP. If the roam
-    attempt was successful, status will be set to CSR_WIFI_SME_SUCCESS,
-    otherwise it shall be set to the appropriate error code.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the roaming procedure
-
-*******************************************************************************/
-#define CsrWifiSmeRoamCompleteIndCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeRoamCompleteInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAM_COMPLETE_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeRoamCompleteIndSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeRoamCompleteInd *msg__; \
-        CsrWifiSmeRoamCompleteIndCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeRoamCompleteIndSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeRoamCompleteIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamStartIndSend
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it whenever it begins an attempt to roam to an AP.
-    If the wireless manager application connect request specified the SSID
-    and the BSSID was set to the broadcast address (0xFF 0xFF 0xFF 0xFF 0xFF
-    0xFF), the SME monitors the signal quality and maintains a list of
-    candidates to roam to. When the signal quality of the current connection
-    falls below a threshold, and there is a candidate with better quality,
-    the SME will attempt to the candidate AP.
-    If the roaming procedure succeeds, the SME will also issue a Media
-    Connect indication to inform the wireless manager application of the
-    change.
-    NOTE: to prevent the SME from initiating roaming the WMA must specify the
-    BSSID in the connection request; this forces the SME to connect only to
-    that AP.
-    The wireless manager application can obtain statistics for roaming
-    purposes using CSR_WIFI_SME_CONNECTION_QUALITY_IND and
-    CSR_WIFI_SME_CONNECTION_STATS_GET_REQ.
-    When the wireless manager application wishes to roam to another AP, it
-    must issue a connection request specifying the BSSID of the desired AP.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    roamReason   - Indicates the reason for starting the roaming procedure
-    reason80211  - Indicates the reason for deauthentication or disassociation
-
-*******************************************************************************/
-#define CsrWifiSmeRoamStartIndCreate(msg__, dst__, src__, interfaceTag__, roamReason__, reason80211__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeRoamStartInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAM_START_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->roamReason = (roamReason__); \
-    msg__->reason80211 = (reason80211__);
-
-#define CsrWifiSmeRoamStartIndSendTo(dst__, src__, interfaceTag__, roamReason__, reason80211__) \
-    { \
-        CsrWifiSmeRoamStartInd *msg__; \
-        CsrWifiSmeRoamStartIndCreate(msg__, dst__, src__, interfaceTag__, roamReason__, reason80211__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeRoamStartIndSend(dst__, interfaceTag__, roamReason__, reason80211__) \
-    CsrWifiSmeRoamStartIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, roamReason__, reason80211__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the RoamingConfig parameter.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiSmeRoamingConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeRoamingConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAMING_CONFIG_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeRoamingConfigGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeRoamingConfigGetReq *msg__; \
-        CsrWifiSmeRoamingConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeRoamingConfigGetReqSend(src__, interfaceTag__) \
-    CsrWifiSmeRoamingConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue         - Destination Task Queue
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    status        - Reports the result of the request
-    roamingConfig - Reports the roaming behaviour of the driver and firmware
-
-*******************************************************************************/
-#define CsrWifiSmeRoamingConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, roamingConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeRoamingConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAMING_CONFIG_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->roamingConfig = (roamingConfig__);
-
-#define CsrWifiSmeRoamingConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, roamingConfig__) \
-    { \
-        CsrWifiSmeRoamingConfigGetCfm *msg__; \
-        CsrWifiSmeRoamingConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, roamingConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeRoamingConfigGetCfmSend(dst__, interfaceTag__, status__, roamingConfig__) \
-    CsrWifiSmeRoamingConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, roamingConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the RoamingConfig parameter.
-
-  PARAMETERS
-    queue         - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    roamingConfig - Desired roaming behaviour values
-
-*******************************************************************************/
-#define CsrWifiSmeRoamingConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, roamingConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeRoamingConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAMING_CONFIG_SET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->roamingConfig = (roamingConfig__);
-
-#define CsrWifiSmeRoamingConfigSetReqSendTo(dst__, src__, interfaceTag__, roamingConfig__) \
-    { \
-        CsrWifiSmeRoamingConfigSetReq *msg__; \
-        CsrWifiSmeRoamingConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, roamingConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeRoamingConfigSetReqSend(src__, interfaceTag__, roamingConfig__) \
-    CsrWifiSmeRoamingConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, roamingConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive sets the value of the RoamingConfig parameter.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeRoamingConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeRoamingConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_ROAMING_CONFIG_SET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeRoamingConfigSetCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeRoamingConfigSetCfm *msg__; \
-        CsrWifiSmeRoamingConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeRoamingConfigSetCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeRoamingConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the ScanConfig parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeScanConfigGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_CONFIG_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeScanConfigGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeScanConfigGetReq *msg__; \
-        CsrWifiSmeScanConfigGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanConfigGetReqSend(src__) \
-    CsrWifiSmeScanConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue      - Destination Task Queue
-    status     - Reports the result of the request
-    scanConfig - Returns the current parameters for the autonomous scanning
-                 behaviour of the firmware
-
-*******************************************************************************/
-#define CsrWifiSmeScanConfigGetCfmCreate(msg__, dst__, src__, status__, scanConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_CONFIG_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->scanConfig = (scanConfig__);
-
-#define CsrWifiSmeScanConfigGetCfmSendTo(dst__, src__, status__, scanConfig__) \
-    { \
-        CsrWifiSmeScanConfigGetCfm *msg__; \
-        CsrWifiSmeScanConfigGetCfmCreate(msg__, dst__, src__, status__, scanConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanConfigGetCfmSend(dst__, status__, scanConfig__) \
-    CsrWifiSmeScanConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, scanConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the ScanConfig parameter.
-    The SME normally configures the firmware to perform autonomous scanning
-    without involving the host.
-    The firmware passes beacon / probe response or indicates loss of beacon
-    on certain changes of state, for example:
-      * A new AP is seen for the first time
-      * An AP is no longer visible
-      * The signal strength of an AP changes by more than a certain amount, as
-        configured by the thresholds in the scanConfig parameter
-    In addition to the autonomous scan, the wireless manager application may
-    request a scan at any time using CSR_WIFI_SME_SCAN_FULL_REQ.
-
-  PARAMETERS
-    queue      - Message Source Task Queue (Cfm's will be sent to this Queue)
-    scanConfig - Reports the configuration for the autonomous scanning behaviour
-                 of the firmware
-
-*******************************************************************************/
-#define CsrWifiSmeScanConfigSetReqCreate(msg__, dst__, src__, scanConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_CONFIG_SET_REQ, dst__, src__); \
-    msg__->scanConfig = (scanConfig__);
-
-#define CsrWifiSmeScanConfigSetReqSendTo(dst__, src__, scanConfig__) \
-    { \
-        CsrWifiSmeScanConfigSetReq *msg__; \
-        CsrWifiSmeScanConfigSetReqCreate(msg__, dst__, src__, scanConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanConfigSetReqSend(src__, scanConfig__) \
-    CsrWifiSmeScanConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, scanConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeScanConfigSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_CONFIG_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeScanConfigSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeScanConfigSetCfm *msg__; \
-        CsrWifiSmeScanConfigSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanConfigSetCfmSend(dst__, status__) \
-    CsrWifiSmeScanConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanFullReqSend
-
-  DESCRIPTION
-    The wireless manager application should call this primitive to request a
-    full scan.
-    Channels are scanned actively or passively according to the requirement
-    set by regulatory domain.
-    If the SME receives this primitive while a full scan is going on, the new
-    request is buffered and it will be served after the current full scan is
-    completed.
-
-  PARAMETERS
-    queue            - Message Source Task Queue (Cfm's will be sent to this Queue)
-    ssidCount        - Number of SSIDs provided.
-                       If it is 0, the SME will attempt to detect any network
-    ssid             - Points to the first SSID provided, if any.
-    bssid            - BSS identifier.
-                       If it is equal to FF-FF-FF-FF-FF, the SME will listen for
-                       messages from any BSS.
-                       If it is different from FF-FF-FF-FF-FF and any SSID is
-                       provided, one SSID must match the network of the BSS.
-    forceScan        - Forces the scan even if the SME is in a state which would
-                       normally prevent it (e.g. autonomous scan is running).
-    bssType          - Type of BSS to scan for
-    scanType         - Type of scan to perform
-    channelListCount - Number of channels provided.
-                       If it is 0, the SME will initiate a scan of all the
-                       supported channels that are permitted by the current
-                       regulatory domain.
-    channelList      - Points to the first channel , or NULL if channelListCount
-                       is zero.
-    probeIeLength    - Length of the information element in bytes to be sent
-                       with the probe message.
-    probeIe          - Points to the first byte of the information element to be
-                       sent with the probe message.
-
-*******************************************************************************/
-#define CsrWifiSmeScanFullReqCreate(msg__, dst__, src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanFullReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_FULL_REQ, dst__, src__); \
-    msg__->ssidCount = (ssidCount__); \
-    msg__->ssid = (ssid__); \
-    msg__->bssid = (bssid__); \
-    msg__->forceScan = (forceScan__); \
-    msg__->bssType = (bssType__); \
-    msg__->scanType = (scanType__); \
-    msg__->channelListCount = (channelListCount__); \
-    msg__->channelList = (channelList__); \
-    msg__->probeIeLength = (probeIeLength__); \
-    msg__->probeIe = (probeIe__);
-
-#define CsrWifiSmeScanFullReqSendTo(dst__, src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__) \
-    { \
-        CsrWifiSmeScanFullReq *msg__; \
-        CsrWifiSmeScanFullReqCreate(msg__, dst__, src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanFullReqSend(src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__) \
-    CsrWifiSmeScanFullReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, ssidCount__, ssid__, bssid__, forceScan__, bssType__, scanType__, channelListCount__, channelList__, probeIeLength__, probeIe__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanFullCfmSend
-
-  DESCRIPTION
-    The SME calls this primitive when the results from the scan are
-    available.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeScanFullCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanFullCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_FULL_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeScanFullCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeScanFullCfm *msg__; \
-        CsrWifiSmeScanFullCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanFullCfmSend(dst__, status__) \
-    CsrWifiSmeScanFullCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultIndSend
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it whenever a scan indication is received from the firmware.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    result - Points to a buffer containing a scan result.
-
-*******************************************************************************/
-#define CsrWifiSmeScanResultIndCreate(msg__, dst__, src__, result__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanResultInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULT_IND, dst__, src__); \
-    msg__->result = (result__);
-
-#define CsrWifiSmeScanResultIndSendTo(dst__, src__, result__) \
-    { \
-        CsrWifiSmeScanResultInd *msg__; \
-        CsrWifiSmeScanResultIndCreate(msg__, dst__, src__, result__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanResultIndSend(dst__, result__) \
-    CsrWifiSmeScanResultIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, result__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultsFlushReqSend
-
-  DESCRIPTION
-    The Wireless Manager calls this primitive to ask the SME to delete all
-    scan results from its cache, except for the scan result of any currently
-    connected network.
-    As scan results are received by the SME from the firmware, they are
-    cached in the SME memory.
-    Any time the Wireless Manager requests scan results, they are returned
-    from the SME internal cache.
-    For some applications it may be desirable to clear this cache prior to
-    requesting that a scan be performed; this will ensure that the cache then
-    only contains the networks detected in the most recent scan.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeScanResultsFlushReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanResultsFlushReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULTS_FLUSH_REQ, dst__, src__);
-
-#define CsrWifiSmeScanResultsFlushReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeScanResultsFlushReq *msg__; \
-        CsrWifiSmeScanResultsFlushReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanResultsFlushReqSend(src__) \
-    CsrWifiSmeScanResultsFlushReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultsFlushCfmSend
-
-  DESCRIPTION
-    The SME will call this primitive when the cache has been cleared.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeScanResultsFlushCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanResultsFlushCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULTS_FLUSH_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeScanResultsFlushCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeScanResultsFlushCfm *msg__; \
-        CsrWifiSmeScanResultsFlushCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanResultsFlushCfmSend(dst__, status__) \
-    CsrWifiSmeScanResultsFlushCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultsGetReqSend
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to retrieve the
-    current set of scan results, either after receiving a successful
-    CSR_WIFI_SME_SCAN_FULL_CFM, or to get autonomous scan results.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeScanResultsGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanResultsGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULTS_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeScanResultsGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeScanResultsGetReq *msg__; \
-        CsrWifiSmeScanResultsGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanResultsGetReqSend(src__) \
-    CsrWifiSmeScanResultsGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultsGetCfmSend
-
-  DESCRIPTION
-    The SME sends this primitive to provide the current set of scan results.
-
-  PARAMETERS
-    queue            - Destination Task Queue
-    status           - Reports the result of the request
-    scanResultsCount - Number of scan results
-    scanResults      - Points to a buffer containing an array of
-                       CsrWifiSmeScanResult structures.
-
-*******************************************************************************/
-#define CsrWifiSmeScanResultsGetCfmCreate(msg__, dst__, src__, status__, scanResultsCount__, scanResults__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeScanResultsGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SCAN_RESULTS_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->scanResultsCount = (scanResultsCount__); \
-    msg__->scanResults = (scanResults__);
-
-#define CsrWifiSmeScanResultsGetCfmSendTo(dst__, src__, status__, scanResultsCount__, scanResults__) \
-    { \
-        CsrWifiSmeScanResultsGetCfm *msg__; \
-        CsrWifiSmeScanResultsGetCfmCreate(msg__, dst__, src__, status__, scanResultsCount__, scanResults__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeScanResultsGetCfmSend(dst__, status__, scanResultsCount__, scanResults__) \
-    CsrWifiSmeScanResultsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, scanResultsCount__, scanResults__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSetReqSend
-
-  DESCRIPTION
-    Used to pass custom data to the SME. Format is the same as 802.11 Info
-    Elements => | Id | Length | Data
-    1) Cmanr Test Mode "Id:0 Length:1 Data:0x00 = OFF 0x01 = ON" "0x00 0x01
-    (0x00|0x01)"
-
-  PARAMETERS
-    queue      - Message Source Task Queue (Cfm's will be sent to this Queue)
-    dataLength - Number of bytes in the buffer pointed to by 'data'
-    data       - Pointer to the buffer containing 'dataLength' bytes
-
-*******************************************************************************/
-#define CsrWifiSmeSetReqCreate(msg__, dst__, src__, dataLength__, data__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SET_REQ, dst__, src__); \
-    msg__->dataLength = (dataLength__); \
-    msg__->data = (data__);
-
-#define CsrWifiSmeSetReqSendTo(dst__, src__, dataLength__, data__) \
-    { \
-        CsrWifiSmeSetReq *msg__; \
-        CsrWifiSmeSetReqCreate(msg__, dst__, src__, dataLength__, data__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeSetReqSend(src__, dataLength__, data__) \
-    CsrWifiSmeSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, dataLength__, data__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeCommonConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the Sme common parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeSmeCommonConfigGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeSmeCommonConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_COMMON_CONFIG_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeSmeCommonConfigGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeSmeCommonConfigGetReq *msg__; \
-        CsrWifiSmeSmeCommonConfigGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeSmeCommonConfigGetReqSend(src__) \
-    CsrWifiSmeSmeCommonConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeCommonConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    status       - Reports the result of the request
-    deviceConfig - Configuration options in the SME
-
-*******************************************************************************/
-#define CsrWifiSmeSmeCommonConfigGetCfmCreate(msg__, dst__, src__, status__, deviceConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeSmeCommonConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_COMMON_CONFIG_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->deviceConfig = (deviceConfig__);
-
-#define CsrWifiSmeSmeCommonConfigGetCfmSendTo(dst__, src__, status__, deviceConfig__) \
-    { \
-        CsrWifiSmeSmeCommonConfigGetCfm *msg__; \
-        CsrWifiSmeSmeCommonConfigGetCfmCreate(msg__, dst__, src__, status__, deviceConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeSmeCommonConfigGetCfmSend(dst__, status__, deviceConfig__) \
-    CsrWifiSmeSmeCommonConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, deviceConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeCommonConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the Sme common.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    deviceConfig - Configuration options in the SME
-
-*******************************************************************************/
-#define CsrWifiSmeSmeCommonConfigSetReqCreate(msg__, dst__, src__, deviceConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeSmeCommonConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ, dst__, src__); \
-    msg__->deviceConfig = (deviceConfig__);
-
-#define CsrWifiSmeSmeCommonConfigSetReqSendTo(dst__, src__, deviceConfig__) \
-    { \
-        CsrWifiSmeSmeCommonConfigSetReq *msg__; \
-        CsrWifiSmeSmeCommonConfigSetReqCreate(msg__, dst__, src__, deviceConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeSmeCommonConfigSetReqSend(src__, deviceConfig__) \
-    CsrWifiSmeSmeCommonConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, deviceConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeCommonConfigSetCfmSend
-
-  DESCRIPTION
-    Reports the result of the request
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeSmeCommonConfigSetCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeSmeCommonConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_COMMON_CONFIG_SET_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeSmeCommonConfigSetCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeSmeCommonConfigSetCfm *msg__; \
-        CsrWifiSmeSmeCommonConfigSetCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeSmeCommonConfigSetCfmSend(dst__, status__) \
-    CsrWifiSmeSmeCommonConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeStaConfigGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the SmeStaConfig parameter.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-#define CsrWifiSmeSmeStaConfigGetReqCreate(msg__, dst__, src__, interfaceTag__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeSmeStaConfigGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_STA_CONFIG_GET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__);
-
-#define CsrWifiSmeSmeStaConfigGetReqSendTo(dst__, src__, interfaceTag__) \
-    { \
-        CsrWifiSmeSmeStaConfigGetReq *msg__; \
-        CsrWifiSmeSmeStaConfigGetReqCreate(msg__, dst__, src__, interfaceTag__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeSmeStaConfigGetReqSend(src__, interfaceTag__) \
-    CsrWifiSmeSmeStaConfigGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeStaConfigGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-    smeConfig    - Current SME Station Parameters
-
-*******************************************************************************/
-#define CsrWifiSmeSmeStaConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, smeConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeSmeStaConfigGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_STA_CONFIG_GET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->smeConfig = (smeConfig__);
-
-#define CsrWifiSmeSmeStaConfigGetCfmSendTo(dst__, src__, interfaceTag__, status__, smeConfig__) \
-    { \
-        CsrWifiSmeSmeStaConfigGetCfm *msg__; \
-        CsrWifiSmeSmeStaConfigGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, smeConfig__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeSmeStaConfigGetCfmSend(dst__, interfaceTag__, status__, smeConfig__) \
-    CsrWifiSmeSmeStaConfigGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, smeConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeStaConfigSetReqSend
-
-  DESCRIPTION
-    This primitive sets the value of the SmeConfig parameter.
-
-  PARAMETERS
-    queue        - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    smeConfig    - SME Station Parameters to be set
-
-*******************************************************************************/
-#define CsrWifiSmeSmeStaConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, smeConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeSmeStaConfigSetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_STA_CONFIG_SET_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->smeConfig = (smeConfig__);
-
-#define CsrWifiSmeSmeStaConfigSetReqSendTo(dst__, src__, interfaceTag__, smeConfig__) \
-    { \
-        CsrWifiSmeSmeStaConfigSetReq *msg__; \
-        CsrWifiSmeSmeStaConfigSetReqCreate(msg__, dst__, src__, interfaceTag__, smeConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeSmeStaConfigSetReqSend(src__, interfaceTag__, smeConfig__) \
-    CsrWifiSmeSmeStaConfigSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, smeConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeStaConfigSetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue        - Destination Task Queue
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeSmeStaConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeSmeStaConfigSetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SME_STA_CONFIG_SET_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeSmeStaConfigSetCfmSendTo(dst__, src__, interfaceTag__, status__) \
-    { \
-        CsrWifiSmeSmeStaConfigSetCfm *msg__; \
-        CsrWifiSmeSmeStaConfigSetCfmCreate(msg__, dst__, src__, interfaceTag__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeSmeStaConfigSetCfmSend(dst__, interfaceTag__, status__) \
-    CsrWifiSmeSmeStaConfigSetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeStationMacAddressGetReqSend
-
-  DESCRIPTION
-    This primitives is used to retrieve the current MAC address used by the
-    station.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeStationMacAddressGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeStationMacAddressGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeStationMacAddressGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeStationMacAddressGetReq *msg__; \
-        CsrWifiSmeStationMacAddressGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeStationMacAddressGetReqSend(src__) \
-    CsrWifiSmeStationMacAddressGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeStationMacAddressGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue             - Destination Task Queue
-    status            - Reports the result of the request
-    stationMacAddress - Current MAC address of the station.
-
-*******************************************************************************/
-#define CsrWifiSmeStationMacAddressGetCfmCreate(msg__, dst__, src__, status__, stationMacAddress__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeStationMacAddressGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    memcpy(msg__->stationMacAddress, (stationMacAddress__), sizeof(CsrWifiMacAddress) * 2);
-
-#define CsrWifiSmeStationMacAddressGetCfmSendTo(dst__, src__, status__, stationMacAddress__) \
-    { \
-        CsrWifiSmeStationMacAddressGetCfm *msg__; \
-        CsrWifiSmeStationMacAddressGetCfmCreate(msg__, dst__, src__, status__, stationMacAddress__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeStationMacAddressGetCfmSend(dst__, status__, stationMacAddress__) \
-    CsrWifiSmeStationMacAddressGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, stationMacAddress__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTspecReqSend
-
-  DESCRIPTION
-    The wireless manager application should call this primitive to use the
-    TSPEC feature.
-    The chip supports the use of TSPECs and TCLAS for the use of IEEE
-    802.11/WMM Quality of Service features.
-    The API allows the wireless manager application to supply a correctly
-    formatted TSPEC and TCLAS pair to the driver.
-    After performing basic validation, the driver negotiates the installation
-    of the TSPEC with the AP as defined by the 802.11 specification.
-    The driver retains all TSPEC and TCLAS pairs until they are specifically
-    removed.
-    It is not compulsory for a TSPEC to have a TCLAS (NULL is used to
-    indicate that no TCLAS is supplied), while a TCLASS always require a
-    TSPEC.
-    The format of the TSPEC element is specified in 'WMM (including WMM Power
-    Save) Specification - Version 1.1' and 'ANSI/IEEE Std 802.11-REVmb/D3.0'.
-    For more information, see 'UniFi Configuring WMM and WMM-PS'.
-
-  PARAMETERS
-    queue         - Message Source Task Queue (Cfm's will be sent to this Queue)
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    action        - Specifies the action to be carried out on the list of TSPECs.
-                    CSR_WIFI_SME_LIST_ACTION_FLUSH is not applicable here.
-    transactionId - Unique Transaction ID for the TSPEC, as assigned by the
-                    driver
-    strict        - If it set to false, allows the SME to perform automatic
-                    TSPEC negotiation
-    ctrlMask      - Additional TSPEC configuration for CCX.
-                    Set mask with values from CsrWifiSmeTspecCtrl.
-                    CURRENTLY NOT SUPPORTED
-    tspecLength   - Length of the TSPEC.
-    tspec         - Points to the first byte of the TSPEC
-    tclasLength   - Length of the TCLAS.
-                    If it is equal to 0, no TCLASS is provided for the TSPEC
-    tclas         - Points to the first byte of the TCLAS, if any.
-
-*******************************************************************************/
-#define CsrWifiSmeTspecReqCreate(msg__, dst__, src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeTspecReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_TSPEC_REQ, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->action = (action__); \
-    msg__->transactionId = (transactionId__); \
-    msg__->strict = (strict__); \
-    msg__->ctrlMask = (ctrlMask__); \
-    msg__->tspecLength = (tspecLength__); \
-    msg__->tspec = (tspec__); \
-    msg__->tclasLength = (tclasLength__); \
-    msg__->tclas = (tclas__);
-
-#define CsrWifiSmeTspecReqSendTo(dst__, src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__) \
-    { \
-        CsrWifiSmeTspecReq *msg__; \
-        CsrWifiSmeTspecReqCreate(msg__, dst__, src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeTspecReqSend(src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__) \
-    CsrWifiSmeTspecReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, interfaceTag__, action__, transactionId__, strict__, ctrlMask__, tspecLength__, tspec__, tclasLength__, tclas__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTspecIndSend
-
-  DESCRIPTION
-    The SME will send this primitive to all the task that have registered to
-    receive it when a status change in the TSPEC occurs.
-
-  PARAMETERS
-    queue           - Destination Task Queue
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    transactionId   - Unique Transaction ID for the TSPEC, as assigned by the
-                      driver
-    tspecResultCode - Specifies the TSPEC operation requested by the peer
-                      station
-    tspecLength     - Length of the TSPEC.
-    tspec           - Points to the first byte of the TSPEC
-
-*******************************************************************************/
-#define CsrWifiSmeTspecIndCreate(msg__, dst__, src__, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeTspecInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_TSPEC_IND, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->transactionId = (transactionId__); \
-    msg__->tspecResultCode = (tspecResultCode__); \
-    msg__->tspecLength = (tspecLength__); \
-    msg__->tspec = (tspec__);
-
-#define CsrWifiSmeTspecIndSendTo(dst__, src__, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \
-    { \
-        CsrWifiSmeTspecInd *msg__; \
-        CsrWifiSmeTspecIndCreate(msg__, dst__, src__, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeTspecIndSend(dst__, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \
-    CsrWifiSmeTspecIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, transactionId__, tspecResultCode__, tspecLength__, tspec__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTspecCfmSend
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the TSpec primitive
-    request.
-
-  PARAMETERS
-    queue           - Destination Task Queue
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    status          - Reports the result of the request
-    transactionId   - Unique Transaction ID for the TSPEC, as assigned by the
-                      driver
-    tspecResultCode - Specifies the result of the negotiated TSPEC operation
-    tspecLength     - Length of the TSPEC.
-    tspec           - Points to the first byte of the TSPEC
-
-*******************************************************************************/
-#define CsrWifiSmeTspecCfmCreate(msg__, dst__, src__, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeTspecCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_TSPEC_CFM, dst__, src__); \
-    msg__->interfaceTag = (interfaceTag__); \
-    msg__->status = (status__); \
-    msg__->transactionId = (transactionId__); \
-    msg__->tspecResultCode = (tspecResultCode__); \
-    msg__->tspecLength = (tspecLength__); \
-    msg__->tspec = (tspec__);
-
-#define CsrWifiSmeTspecCfmSendTo(dst__, src__, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \
-    { \
-        CsrWifiSmeTspecCfm *msg__; \
-        CsrWifiSmeTspecCfmCreate(msg__, dst__, src__, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeTspecCfmSend(dst__, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__) \
-    CsrWifiSmeTspecCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, transactionId__, tspecResultCode__, tspecLength__, tspec__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeVersionsGetReqSend
-
-  DESCRIPTION
-    This primitive gets the value of the Versions parameter.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeVersionsGetReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeVersionsGetReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_VERSIONS_GET_REQ, dst__, src__);
-
-#define CsrWifiSmeVersionsGetReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeVersionsGetReq *msg__; \
-        CsrWifiSmeVersionsGetReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeVersionsGetReqSend(src__) \
-    CsrWifiSmeVersionsGetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeVersionsGetCfmSend
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  PARAMETERS
-    queue    - Destination Task Queue
-    status   - Reports the result of the request
-    versions - Version IDs of the product
-
-*******************************************************************************/
-#define CsrWifiSmeVersionsGetCfmCreate(msg__, dst__, src__, status__, versions__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeVersionsGetCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_VERSIONS_GET_CFM, dst__, src__); \
-    msg__->status = (status__); \
-    msg__->versions = (versions__);
-
-#define CsrWifiSmeVersionsGetCfmSendTo(dst__, src__, status__, versions__) \
-    { \
-        CsrWifiSmeVersionsGetCfm *msg__; \
-        CsrWifiSmeVersionsGetCfmCreate(msg__, dst__, src__, status__, versions__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeVersionsGetCfmSend(dst__, status__, versions__) \
-    CsrWifiSmeVersionsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, versions__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiFlightmodeReqSend
-
-  DESCRIPTION
-    The wireless manager application may call this primitive on boot-up of
-    the platform to ensure that the chip is placed in a mode that prevents
-    any emission of RF energy.
-    This primitive is an alternative to CSR_WIFI_SME_WIFI_ON_REQ.
-    As in CSR_WIFI_SME_WIFI_ON_REQ, it causes the download of the patch file
-    (if any) and the programming of the initial MIB settings (if supplied by
-    the WMA), but it also ensures that the chip is left in its lowest
-    possible power-mode with the radio subsystems disabled.
-    This feature is useful on platforms where power cannot be removed from
-    the chip (leaving the chip not initialised will cause it to consume more
-    power so calling this function ensures that the chip is initialised into
-    a low power mode but without entering a state where it could emit any RF
-    energy).
-    NOTE: this primitive does not cause the Wi-Fi to change state: Wi-Fi
-    stays conceptually off. Configuration primitives can be sent after
-    CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ and the configuration will be maintained.
-    Requests that require the state of the Wi-Fi to be ON will return
-    CSR_WIFI_SME_STATUS_WIFI_OFF in their confirms.
-
-  PARAMETERS
-    queue         - Message Source Task Queue (Cfm's will be sent to this Queue)
-    address       - Optionally specifies a station MAC address.
-                    In normal use, the manager should set the address to 0xFF
-                    0xFF 0xFF 0xFF 0xFF 0xFF, which will cause the chip to use
-                    the MAC address in the MIB.
-    mibFilesCount - Number of provided data blocks with initial MIB values
-    mibFiles      - Points to the first data block with initial MIB values.
-                    These data blocks are typically the contents of the provided
-                    files ufmib.dat and localmib.dat, available from the host
-                    file system, if they exist.
-                    These files typically contain radio tuning and calibration
-                    values.
-                    More values can be created using the Host Tools.
-
-*******************************************************************************/
-#define CsrWifiSmeWifiFlightmodeReqCreate(msg__, dst__, src__, address__, mibFilesCount__, mibFiles__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWifiFlightmodeReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ, dst__, src__); \
-    msg__->address = (address__); \
-    msg__->mibFilesCount = (mibFilesCount__); \
-    msg__->mibFiles = (mibFiles__);
-
-#define CsrWifiSmeWifiFlightmodeReqSendTo(dst__, src__, address__, mibFilesCount__, mibFiles__) \
-    { \
-        CsrWifiSmeWifiFlightmodeReq *msg__; \
-        CsrWifiSmeWifiFlightmodeReqCreate(msg__, dst__, src__, address__, mibFilesCount__, mibFiles__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWifiFlightmodeReqSend(src__, address__, mibFilesCount__, mibFiles__) \
-    CsrWifiSmeWifiFlightmodeReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, address__, mibFilesCount__, mibFiles__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiFlightmodeCfmSend
-
-  DESCRIPTION
-    The SME calls this primitive when the chip is initialised for low power
-    mode and with the radio subsystem disabled. To leave flight mode, and
-    enable Wi-Fi, the wireless manager application should call
-    CSR_WIFI_SME_WIFI_ON_REQ.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeWifiFlightmodeCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWifiFlightmodeCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_FLIGHTMODE_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeWifiFlightmodeCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeWifiFlightmodeCfm *msg__; \
-        CsrWifiSmeWifiFlightmodeCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWifiFlightmodeCfmSend(dst__, status__) \
-    CsrWifiSmeWifiFlightmodeCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOffReqSend
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to turn off the
-    chip, thus saving power when Wi-Fi is not in use.
-
-  PARAMETERS
-    queue  - Message Source Task Queue (Cfm's will be sent to this Queue)
-
-*******************************************************************************/
-#define CsrWifiSmeWifiOffReqCreate(msg__, dst__, src__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWifiOffReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_OFF_REQ, dst__, src__);
-
-#define CsrWifiSmeWifiOffReqSendTo(dst__, src__) \
-    { \
-        CsrWifiSmeWifiOffReq *msg__; \
-        CsrWifiSmeWifiOffReqCreate(msg__, dst__, src__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWifiOffReqSend(src__) \
-    CsrWifiSmeWifiOffReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOffIndSend
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it to report that the chip has been turned off.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    reason - Indicates the reason why the Wi-Fi has been switched off.
-
-*******************************************************************************/
-#define CsrWifiSmeWifiOffIndCreate(msg__, dst__, src__, reason__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWifiOffInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_OFF_IND, dst__, src__); \
-    msg__->reason = (reason__);
-
-#define CsrWifiSmeWifiOffIndSendTo(dst__, src__, reason__) \
-    { \
-        CsrWifiSmeWifiOffInd *msg__; \
-        CsrWifiSmeWifiOffIndCreate(msg__, dst__, src__, reason__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWifiOffIndSend(dst__, reason__) \
-    CsrWifiSmeWifiOffIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, reason__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOffCfmSend
-
-  DESCRIPTION
-    After receiving CSR_WIFI_SME_WIFI_OFF_REQ, if the chip is connected to a
-    network, the SME will perform a disconnect operation, will send a
-    CSR_WIFI_SME_MEDIA_STATUS_IND with
-    CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED, and then will call
-    CSR_WIFI_SME_WIFI_OFF_CFM when the chip is off.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeWifiOffCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWifiOffCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_OFF_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeWifiOffCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeWifiOffCfm *msg__; \
-        CsrWifiSmeWifiOffCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWifiOffCfmSend(dst__, status__) \
-    CsrWifiSmeWifiOffCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOnReqSend
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to turn on the
-    Wi-Fi chip.
-    If the Wi-Fi chip is currently off, the SME turns the Wi-Fi chip on,
-    downloads the patch file (if any), and programs the initial MIB settings
-    (if supplied by the WMA).
-    The patch file is not provided with the SME API; its downloading is
-    automatic and handled internally by the system.
-    The MIB settings, when provided, override the default values that the
-    firmware loads from EEPROM.
-    If the Wi-Fi chip is already on, the SME takes no action and returns a
-    successful status in the confirm.
-
-  PARAMETERS
-    queue         - Message Source Task Queue (Cfm's will be sent to this Queue)
-    address       - Optionally specifies a station MAC address.
-                    In normal use, the manager should set the address to 0xFF
-                    0xFF 0xFF 0xFF 0xFF 0xFF, which will cause the chip to use
-                    the MAC address in the MIB
-    mibFilesCount - Number of provided data blocks with initial MIB values
-    mibFiles      - Points to the first data block with initial MIB values.
-                    These data blocks are typically the contents of the provided
-                    files ufmib.dat and localmib.dat, available from the host
-                    file system, if they exist.
-                    These files typically contain radio tuning and calibration
-                    values.
-                    More values can be created using the Host Tools.
-
-*******************************************************************************/
-#define CsrWifiSmeWifiOnReqCreate(msg__, dst__, src__, address__, mibFilesCount__, mibFiles__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWifiOnReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_ON_REQ, dst__, src__); \
-    msg__->address = (address__); \
-    msg__->mibFilesCount = (mibFilesCount__); \
-    msg__->mibFiles = (mibFiles__);
-
-#define CsrWifiSmeWifiOnReqSendTo(dst__, src__, address__, mibFilesCount__, mibFiles__) \
-    { \
-        CsrWifiSmeWifiOnReq *msg__; \
-        CsrWifiSmeWifiOnReqCreate(msg__, dst__, src__, address__, mibFilesCount__, mibFiles__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWifiOnReqSend(src__, address__, mibFilesCount__, mibFiles__) \
-    CsrWifiSmeWifiOnReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, address__, mibFilesCount__, mibFiles__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOnIndSend
-
-  DESCRIPTION
-    The SME sends this primitive to all tasks that have registered to receive
-    it once the chip becomes available and ready to use.
-
-  PARAMETERS
-    queue   - Destination Task Queue
-    address - Current MAC address
-
-*******************************************************************************/
-#define CsrWifiSmeWifiOnIndCreate(msg__, dst__, src__, address__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWifiOnInd), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_ON_IND, dst__, src__); \
-    msg__->address = (address__);
-
-#define CsrWifiSmeWifiOnIndSendTo(dst__, src__, address__) \
-    { \
-        CsrWifiSmeWifiOnInd *msg__; \
-        CsrWifiSmeWifiOnIndCreate(msg__, dst__, src__, address__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWifiOnIndSend(dst__, address__) \
-    CsrWifiSmeWifiOnIndSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, address__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOnCfmSend
-
-  DESCRIPTION
-    The SME sends this primitive to the task that has sent the request once
-    the chip has been initialised and is available for use.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Reports the result of the request
-
-*******************************************************************************/
-#define CsrWifiSmeWifiOnCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWifiOnCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WIFI_ON_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeWifiOnCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeWifiOnCfm *msg__; \
-        CsrWifiSmeWifiOnCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWifiOnCfmSend(dst__, status__) \
-    CsrWifiSmeWifiOnCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsConfigurationReqSend
-
-  DESCRIPTION
-    This primitive passes the WPS information for the device to SME. This may
-    be accepted only if no interface is active.
-
-  PARAMETERS
-    queue     - Message Source Task Queue (Cfm's will be sent to this Queue)
-    wpsConfig - WPS config.
-
-*******************************************************************************/
-#define CsrWifiSmeWpsConfigurationReqCreate(msg__, dst__, src__, wpsConfig__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWpsConfigurationReq), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WPS_CONFIGURATION_REQ, dst__, src__); \
-    msg__->wpsConfig = (wpsConfig__);
-
-#define CsrWifiSmeWpsConfigurationReqSendTo(dst__, src__, wpsConfig__) \
-    { \
-        CsrWifiSmeWpsConfigurationReq *msg__; \
-        CsrWifiSmeWpsConfigurationReqCreate(msg__, dst__, src__, wpsConfig__); \
-        CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWpsConfigurationReqSend(src__, wpsConfig__) \
-    CsrWifiSmeWpsConfigurationReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, wpsConfig__)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsConfigurationCfmSend
-
-  DESCRIPTION
-    Confirm.
-
-  PARAMETERS
-    queue  - Destination Task Queue
-    status - Status of the request.
-
-*******************************************************************************/
-#define CsrWifiSmeWpsConfigurationCfmCreate(msg__, dst__, src__, status__) \
-    msg__ = kmalloc(sizeof(CsrWifiSmeWpsConfigurationCfm), GFP_KERNEL); \
-    CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_WPS_CONFIGURATION_CFM, dst__, src__); \
-    msg__->status = (status__);
-
-#define CsrWifiSmeWpsConfigurationCfmSendTo(dst__, src__, status__) \
-    { \
-        CsrWifiSmeWpsConfigurationCfm *msg__; \
-        CsrWifiSmeWpsConfigurationCfmCreate(msg__, dst__, src__, status__); \
-        CsrSchedMessagePut(dst__, CSR_WIFI_SME_PRIM, msg__); \
-    }
-
-#define CsrWifiSmeWpsConfigurationCfmSend(dst__, status__) \
-    CsrWifiSmeWpsConfigurationCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__)
-
-#endif /* CSR_WIFI_SME_LIB_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_prim.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_prim.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_prim.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_prim.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6510 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_SME_PRIM_H__
-#define CSR_WIFI_SME_PRIM_H__
-
-#include <linux/types.h>
-#include "csr_prim_defs.h"
-#include "csr_sched.h"
-#include "csr_wifi_common.h"
-#include "csr_result.h"
-#include "csr_wifi_fsm_event.h"
-
-#define CSR_WIFI_SME_PRIM                                               (0x0404)
-
-typedef CsrPrim CsrWifiSmePrim;
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSme80211NetworkType
-
-  DESCRIPTION
-    Indicates the physical layer of the network
-
- VALUES
-    CSR_WIFI_SME_80211_NETWORK_TYPE_DS
-                   - Direct-sequence spread spectrum
-    CSR_WIFI_SME_80211_NETWORK_TYPE_OFDM24
-                   - Orthogonal Frequency Division Multiplexing at 2.4 GHz
-    CSR_WIFI_SME_80211_NETWORK_TYPE_OFDM5
-                   - Orthogonal Frequency Division Multiplexing at 5 GHz
-    CSR_WIFI_SME_80211_NETWORK_TYPE_AUTO
-                   - Automatic
-
-*******************************************************************************/
-typedef u8 CsrWifiSme80211NetworkType;
-#define CSR_WIFI_SME_80211_NETWORK_TYPE_DS       ((CsrWifiSme80211NetworkType) 0x00)
-#define CSR_WIFI_SME_80211_NETWORK_TYPE_OFDM24   ((CsrWifiSme80211NetworkType) 0x01)
-#define CSR_WIFI_SME_80211_NETWORK_TYPE_OFDM5    ((CsrWifiSme80211NetworkType) 0x02)
-#define CSR_WIFI_SME_80211_NETWORK_TYPE_AUTO     ((CsrWifiSme80211NetworkType) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSme80211PrivacyMode
-
-  DESCRIPTION
-    Bits to enable or disable the privacy mode
-
- VALUES
-    CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED
-                   - Privacy mode is enabled: use of WEP for confidentiality is
-                     required.
-    CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED
-                   - Privacy mode is disabled
-
-*******************************************************************************/
-typedef u8 CsrWifiSme80211PrivacyMode;
-#define CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED   ((CsrWifiSme80211PrivacyMode) 0x00)
-#define CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED    ((CsrWifiSme80211PrivacyMode) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSme80211dTrustLevel
-
-  DESCRIPTION
-    Level of trust for the information coming from the network
-
- VALUES
-    CSR_WIFI_SME_80211D_TRUST_LEVEL_STRICT
-                   - Start with passive scanning and only accept country IE for
-                     updating channel lists
-    CSR_WIFI_SME_80211D_TRUST_LEVEL_ADJUNCT
-                   - As above plus accept adjunct technology location
-                     information
-    CSR_WIFI_SME_80211D_TRUST_LEVEL_BSS
-                   - As above accept plus receiving channel from infrastructure
-                     networks
-    CSR_WIFI_SME_80211D_TRUST_LEVEL_IBSS
-                   - As above accept plus receiving channel from the ad hoc
-                     networks
-    CSR_WIFI_SME_80211D_TRUST_LEVEL_MIB
-                   - Start with active scanning with list of active channels
-                     from the MIB and accept as above
-    CSR_WIFI_SME_80211D_TRUST_LEVEL_DISABLED
-                   - Start with active scanning with list of active channels
-                     from the MIB and ignore any channel information from the
-                     network
-
-*******************************************************************************/
-typedef u8 CsrWifiSme80211dTrustLevel;
-#define CSR_WIFI_SME_80211D_TRUST_LEVEL_STRICT     ((CsrWifiSme80211dTrustLevel) 0x01)
-#define CSR_WIFI_SME_80211D_TRUST_LEVEL_ADJUNCT    ((CsrWifiSme80211dTrustLevel) 0x02)
-#define CSR_WIFI_SME_80211D_TRUST_LEVEL_BSS        ((CsrWifiSme80211dTrustLevel) 0x03)
-#define CSR_WIFI_SME_80211D_TRUST_LEVEL_IBSS       ((CsrWifiSme80211dTrustLevel) 0x04)
-#define CSR_WIFI_SME_80211D_TRUST_LEVEL_MIB        ((CsrWifiSme80211dTrustLevel) 0x05)
-#define CSR_WIFI_SME_80211D_TRUST_LEVEL_DISABLED   ((CsrWifiSme80211dTrustLevel) 0x06)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAmpStatus
-
-  DESCRIPTION
-    AMP Current Status
-
- VALUES
-    CSR_WIFI_SME_AMP_ACTIVE   - AMP ACTIVE.
-    CSR_WIFI_SME_AMP_INACTIVE - AMP INACTIVE
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeAmpStatus;
-#define CSR_WIFI_SME_AMP_ACTIVE     ((CsrWifiSmeAmpStatus) 0x00)
-#define CSR_WIFI_SME_AMP_INACTIVE   ((CsrWifiSmeAmpStatus) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAuthMode
-
-  DESCRIPTION
-    Define bits for CsrWifiSmeAuthMode
-
- VALUES
-    CSR_WIFI_SME_AUTH_MODE_80211_OPEN
-                   - Connects to an open system network (i.e. no authentication,
-                     no encryption) or to a WEP enabled network.
-    CSR_WIFI_SME_AUTH_MODE_80211_SHARED
-                   - Connect to a WEP enabled network.
-    CSR_WIFI_SME_AUTH_MODE_8021X_WPA
-                   - Connects to a WPA Enterprise enabled network.
-    CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK
-                   - Connects to a WPA with Pre-Shared Key enabled network.
-    CSR_WIFI_SME_AUTH_MODE_8021X_WPA2
-                   - Connects to a WPA2 Enterprise enabled network.
-    CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK
-                   - Connects to a WPA2 with Pre-Shared Key enabled network.
-    CSR_WIFI_SME_AUTH_MODE_8021X_CCKM
-                   - Connects to a CCKM enabled network.
-    CSR_WIFI_SME_AUTH_MODE_WAPI_WAI
-                   - Connects to a WAPI Enterprise enabled network.
-    CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK
-                   - Connects to a WAPI with Pre-Shared Key enabled network.
-    CSR_WIFI_SME_AUTH_MODE_8021X_OTHER1X
-                   - For future use.
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeAuthMode;
-#define CSR_WIFI_SME_AUTH_MODE_80211_OPEN      ((CsrWifiSmeAuthMode) 0x0001)
-#define CSR_WIFI_SME_AUTH_MODE_80211_SHARED    ((CsrWifiSmeAuthMode) 0x0002)
-#define CSR_WIFI_SME_AUTH_MODE_8021X_WPA       ((CsrWifiSmeAuthMode) 0x0004)
-#define CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK    ((CsrWifiSmeAuthMode) 0x0008)
-#define CSR_WIFI_SME_AUTH_MODE_8021X_WPA2      ((CsrWifiSmeAuthMode) 0x0010)
-#define CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK   ((CsrWifiSmeAuthMode) 0x0020)
-#define CSR_WIFI_SME_AUTH_MODE_8021X_CCKM      ((CsrWifiSmeAuthMode) 0x0040)
-#define CSR_WIFI_SME_AUTH_MODE_WAPI_WAI        ((CsrWifiSmeAuthMode) 0x0080)
-#define CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK     ((CsrWifiSmeAuthMode) 0x0100)
-#define CSR_WIFI_SME_AUTH_MODE_8021X_OTHER1X   ((CsrWifiSmeAuthMode) 0x0200)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeBasicUsability
-
-  DESCRIPTION
-    Indicates the usability level of a channel
-
- VALUES
-    CSR_WIFI_SME_BASIC_USABILITY_UNUSABLE
-                   - Not usable; connection not recommended
-    CSR_WIFI_SME_BASIC_USABILITY_POOR
-                   - Poor quality; connect only if nothing better is available
-    CSR_WIFI_SME_BASIC_USABILITY_SATISFACTORY
-                   - Quality is satisfactory
-    CSR_WIFI_SME_BASIC_USABILITY_NOT_CONNECTED
-                   - Not connected
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeBasicUsability;
-#define CSR_WIFI_SME_BASIC_USABILITY_UNUSABLE        ((CsrWifiSmeBasicUsability) 0x00)
-#define CSR_WIFI_SME_BASIC_USABILITY_POOR            ((CsrWifiSmeBasicUsability) 0x01)
-#define CSR_WIFI_SME_BASIC_USABILITY_SATISFACTORY    ((CsrWifiSmeBasicUsability) 0x02)
-#define CSR_WIFI_SME_BASIC_USABILITY_NOT_CONNECTED   ((CsrWifiSmeBasicUsability) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeBssType
-
-  DESCRIPTION
-    Indicates the BSS type
-
- VALUES
-    CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE
-                   - Infrastructure BSS.
-    CSR_WIFI_SME_BSS_TYPE_ADHOC
-                   - Ad hoc or Independent BSS.
-    CSR_WIFI_SME_BSS_TYPE_ANY_BSS
-                   - Specifies any type of BSS
-    CSR_WIFI_SME_BSS_TYPE_P2P
-                   - Specifies P2P
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeBssType;
-#define CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE   ((CsrWifiSmeBssType) 0x00)
-#define CSR_WIFI_SME_BSS_TYPE_ADHOC            ((CsrWifiSmeBssType) 0x01)
-#define CSR_WIFI_SME_BSS_TYPE_ANY_BSS          ((CsrWifiSmeBssType) 0x02)
-#define CSR_WIFI_SME_BSS_TYPE_P2P              ((CsrWifiSmeBssType) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexScheme
-
-  DESCRIPTION
-    Options for the coexistence signalling
-    Same as MibValues
-
- VALUES
-    CSR_WIFI_SME_COEX_SCHEME_DISABLED
-                   - The coexistence signalling is disabled
-    CSR_WIFI_SME_COEX_SCHEME_CSR
-                   - Basic CSR coexistence signalling
-    CSR_WIFI_SME_COEX_SCHEME_CSR_CHANNEL
-                   - Full CSR coexistence signalling
-    CSR_WIFI_SME_COEX_SCHEME_PTA
-                   - Packet Traffic Arbitrator coexistence signalling
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeCoexScheme;
-#define CSR_WIFI_SME_COEX_SCHEME_DISABLED      ((CsrWifiSmeCoexScheme) 0x00)
-#define CSR_WIFI_SME_COEX_SCHEME_CSR           ((CsrWifiSmeCoexScheme) 0x01)
-#define CSR_WIFI_SME_COEX_SCHEME_CSR_CHANNEL   ((CsrWifiSmeCoexScheme) 0x02)
-#define CSR_WIFI_SME_COEX_SCHEME_PTA           ((CsrWifiSmeCoexScheme) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeControlIndication
-
-  DESCRIPTION
-    Indicates the reason why the Wi-Fi has been switched off.
-    The values of this type are used across the NME/SME/Router API's and they
-    must be kept consistent with the corresponding types in the .xml of the
-    ottherinterfaces
-
- VALUES
-    CSR_WIFI_SME_CONTROL_INDICATION_ERROR
-                   - An unrecoverable error (for example, an unrecoverable SDIO
-                     error) has occurred.
-                     The wireless manager application should reinitialise the
-                     chip by calling CSR_WIFI_SME_WIFI_ON_REQ.
-    CSR_WIFI_SME_CONTROL_INDICATION_EXIT
-                   - The chip became unavailable due to an external action, for
-                     example, when a plug-in card is ejected or the driver is
-                     unloaded.
-    CSR_WIFI_SME_CONTROL_INDICATION_USER_REQUESTED
-                   - The Wi-Fi has been switched off as the wireless manager
-                     application has sent CSR_WIFI_SME_WIFI_OFF_REQ
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeControlIndication;
-#define CSR_WIFI_SME_CONTROL_INDICATION_ERROR            ((CsrWifiSmeControlIndication) 0x01)
-#define CSR_WIFI_SME_CONTROL_INDICATION_EXIT             ((CsrWifiSmeControlIndication) 0x02)
-#define CSR_WIFI_SME_CONTROL_INDICATION_USER_REQUESTED   ((CsrWifiSmeControlIndication) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCtsProtectionType
-
-  DESCRIPTION
-    SME CTS Protection Types
-
- VALUES
-    CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC
-                   - AP CTS Protection automatic based on non-ERP station in own
-                     BSS or neighbouring BSS on the same channel based on OLBC.
-                     This requires monitoring of beacons from other APs.
-    CSR_WIFI_SME_CTS_PROTECTION_FORCE_ENABLED
-                   - AP CTS Protection Force enabled
-    CSR_WIFI_SME_CTS_PROTECTION_FORCE_DISABLED
-                   - AP CTS Protection Force disabled.
-    CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC_NO_OLBC
-                   - AP CTS Protection automatic without considering OLBC but
-                     considering non-ERP station in the own BSS Valid only if AP
-                     is configured to work in 802.11bg or 802.11g mode otherwise
-                     this option specifies the same behaviour as AUTOMATIC
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeCtsProtectionType;
-#define CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC           ((CsrWifiSmeCtsProtectionType) 0x00)
-#define CSR_WIFI_SME_CTS_PROTECTION_FORCE_ENABLED       ((CsrWifiSmeCtsProtectionType) 0x01)
-#define CSR_WIFI_SME_CTS_PROTECTION_FORCE_DISABLED      ((CsrWifiSmeCtsProtectionType) 0x02)
-#define CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC_NO_OLBC   ((CsrWifiSmeCtsProtectionType) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeD3AutoScanMode
-
-  DESCRIPTION
-    Autonomous scan status while in D3 suspended period
-
- VALUES
-    CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSON
-                   - Autonomous scan stays on
-    CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSOFF
-                   - Autonomous scan is switched off
-    CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSAUTO
-                   - Automatically select autoscanning behaviour.
-                     CURRENTLY NOT SUPPORTED
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeD3AutoScanMode;
-#define CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSON     ((CsrWifiSmeD3AutoScanMode) 0x00)
-#define CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSOFF    ((CsrWifiSmeD3AutoScanMode) 0x01)
-#define CSR_WIFI_SME_D3AUTO_SCAN_MODE_PSAUTO   ((CsrWifiSmeD3AutoScanMode) 0x02)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeEncryption
-
-  DESCRIPTION
-    Defines bits for CsrWifiSmeEncryption
-    For a WEP enabled network, the caller must specify the correct
-    combination of flags in the encryptionModeMask.
-
- VALUES
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE
-                   - No encryption set
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40
-                   - Selects 40 byte key WEP for unicast communication
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104
-                   - Selects 104 byte key WEP for unicast communication
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_TKIP
-                   - Selects TKIP for unicast communication
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_CCMP
-                   - Selects CCMP for unicast communication
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4
-                   - Selects SMS4 for unicast communication
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40
-                   - Selects 40 byte key WEP for broadcast messages
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104
-                   - Selects 104 byte key WEP for broadcast messages
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP
-                   - Selects a TKIP for broadcast messages
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP
-                   - Selects CCMP for broadcast messages
-    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4
-                   - Selects SMS4 for broadcast messages
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeEncryption;
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE              ((CsrWifiSmeEncryption) 0x0000)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40    ((CsrWifiSmeEncryption) 0x0001)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104   ((CsrWifiSmeEncryption) 0x0002)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_TKIP     ((CsrWifiSmeEncryption) 0x0004)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_CCMP     ((CsrWifiSmeEncryption) 0x0008)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4     ((CsrWifiSmeEncryption) 0x0010)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40       ((CsrWifiSmeEncryption) 0x0020)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104      ((CsrWifiSmeEncryption) 0x0040)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP        ((CsrWifiSmeEncryption) 0x0080)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP        ((CsrWifiSmeEncryption) 0x0100)
-#define CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4        ((CsrWifiSmeEncryption) 0x0200)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeFirmwareDriverInterface
-
-  DESCRIPTION
-    Type of communication between Host and Firmware
-
- VALUES
-    CSR_WIFI_SME_FIRMWARE_DRIVER_INTERFACE_UNIT_DATA_INTERFACE
-                   - No preformated header. NOT SUPPORTED in the current release
-    CSR_WIFI_SME_FIRMWARE_DRIVER_INTERFACE_PACKET_INTERFACE
-                   - Preformated IEEE 802.11 header for user plane
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeFirmwareDriverInterface;
-#define CSR_WIFI_SME_FIRMWARE_DRIVER_INTERFACE_UNIT_DATA_INTERFACE   ((CsrWifiSmeFirmwareDriverInterface) 0x00)
-#define CSR_WIFI_SME_FIRMWARE_DRIVER_INTERFACE_PACKET_INTERFACE      ((CsrWifiSmeFirmwareDriverInterface) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostPowerMode
-
-  DESCRIPTION
-    Defines the power mode
-
- VALUES
-    CSR_WIFI_SME_HOST_POWER_MODE_ACTIVE
-                   - Host device is running on external power.
-    CSR_WIFI_SME_HOST_POWER_MODE_POWER_SAVE
-                   - Host device is running on (internal) battery power.
-    CSR_WIFI_SME_HOST_POWER_MODE_FULL_POWER_SAVE
-                   - For future use.
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeHostPowerMode;
-#define CSR_WIFI_SME_HOST_POWER_MODE_ACTIVE            ((CsrWifiSmeHostPowerMode) 0x00)
-#define CSR_WIFI_SME_HOST_POWER_MODE_POWER_SAVE        ((CsrWifiSmeHostPowerMode) 0x01)
-#define CSR_WIFI_SME_HOST_POWER_MODE_FULL_POWER_SAVE   ((CsrWifiSmeHostPowerMode) 0x02)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeIEEE80211Reason
-
-  DESCRIPTION
-    As definined in the IEEE 802.11 standards
-
- VALUES
-    CSR_WIFI_SME_IEEE80211_REASON_SUCCESS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_UNSPECIFIED_REASON
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_AUTHENTICATION_NOT_VALID
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_DEAUTHENTICATED_LEAVE_BSS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_INACTIVITY
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_AP_OVERLOAD
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_CLASS_2FRAME_ERROR
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_CLASS_3FRAME_ERROR
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_LEAVE_BSS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_ASSOCIATION_NOT_AUTHENTICATED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_POWER_CAPABILITY
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_SUPPORTED_CHANNELS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_INVALID_INFORMATION_ELEMENT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_MICHAEL_MIC_FAILURE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_FOURWAY_HANDSHAKE_TIMEOUT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_GROUP_KEY_UPDATE_TIMEOUT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_HANDSHAKE_ELEMENT_DIFFERENT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_INVALID_GROUP_CIPHER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_INVALID_PAIRWISE_CIPHER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_INVALID_AKMP
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_UNSUPPORTED_RSN_IEVERSION
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_INVALID_RSN_IECAPABILITIES
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_DOT1X_AUTH_FAILED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_CIPHER_REJECTED_BY_POLICY
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_SERVICE_CHANGE_PRECLUDES_TS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_QOS_UNSPECIFIED_REASON
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_QOS_INSUFFICIENT_BANDWIDTH
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_QOS_EXCESSIVE_NOT_ACK
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_QOS_TXOPLIMIT_EXCEEDED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_QSTA_LEAVING
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_END_TS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_END_DLS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_END_BA
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_TS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_BA
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_DLS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_TIMEOUT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_STAKEY_MISMATCH
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_UNICAST_KEY_NEGOTIATION_TIMEOUT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_MULTICAST_KEY_ANNOUNCEMENT_TIMEOUT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_INCOMPATIBLE_UNICAST_KEY_NEGOTIATION_IE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_INVALID_MULTICAST_CIPHER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_INVALID_UNICAST_CIPHER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_UNSUPPORTED_WAPI_IE_VERSION
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_INVALID_WAPI_CAPABILITY_IE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_REASON_WAI_CERTIFICATE_AUTHENTICATION_FAILED
-                   - See IEEE 802.11 Standard
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeIEEE80211Reason;
-#define CSR_WIFI_SME_IEEE80211_REASON_SUCCESS                                   ((CsrWifiSmeIEEE80211Reason) 0x0000)
-#define CSR_WIFI_SME_IEEE80211_REASON_UNSPECIFIED_REASON                        ((CsrWifiSmeIEEE80211Reason) 0x0001)
-#define CSR_WIFI_SME_IEEE80211_REASON_AUTHENTICATION_NOT_VALID                  ((CsrWifiSmeIEEE80211Reason) 0x0002)
-#define CSR_WIFI_SME_IEEE80211_REASON_DEAUTHENTICATED_LEAVE_BSS                 ((CsrWifiSmeIEEE80211Reason) 0x0003)
-#define CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_INACTIVITY                  ((CsrWifiSmeIEEE80211Reason) 0x0004)
-#define CSR_WIFI_SME_IEEE80211_REASON_AP_OVERLOAD                               ((CsrWifiSmeIEEE80211Reason) 0x0005)
-#define CSR_WIFI_SME_IEEE80211_REASON_CLASS_2FRAME_ERROR                        ((CsrWifiSmeIEEE80211Reason) 0x0006)
-#define CSR_WIFI_SME_IEEE80211_REASON_CLASS_3FRAME_ERROR                        ((CsrWifiSmeIEEE80211Reason) 0x0007)
-#define CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_LEAVE_BSS                   ((CsrWifiSmeIEEE80211Reason) 0x0008)
-#define CSR_WIFI_SME_IEEE80211_REASON_ASSOCIATION_NOT_AUTHENTICATED             ((CsrWifiSmeIEEE80211Reason) 0x0009)
-#define CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_POWER_CAPABILITY            ((CsrWifiSmeIEEE80211Reason) 0x000a)
-#define CSR_WIFI_SME_IEEE80211_REASON_DISASSOCIATED_SUPPORTED_CHANNELS          ((CsrWifiSmeIEEE80211Reason) 0x000b)
-#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_INFORMATION_ELEMENT               ((CsrWifiSmeIEEE80211Reason) 0x000d)
-#define CSR_WIFI_SME_IEEE80211_REASON_MICHAEL_MIC_FAILURE                       ((CsrWifiSmeIEEE80211Reason) 0x000e)
-#define CSR_WIFI_SME_IEEE80211_REASON_FOURWAY_HANDSHAKE_TIMEOUT                 ((CsrWifiSmeIEEE80211Reason) 0x000f)
-#define CSR_WIFI_SME_IEEE80211_REASON_GROUP_KEY_UPDATE_TIMEOUT                  ((CsrWifiSmeIEEE80211Reason) 0x0010)
-#define CSR_WIFI_SME_IEEE80211_REASON_HANDSHAKE_ELEMENT_DIFFERENT               ((CsrWifiSmeIEEE80211Reason) 0x0011)
-#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_GROUP_CIPHER                      ((CsrWifiSmeIEEE80211Reason) 0x0012)
-#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_PAIRWISE_CIPHER                   ((CsrWifiSmeIEEE80211Reason) 0x0013)
-#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_AKMP                              ((CsrWifiSmeIEEE80211Reason) 0x0014)
-#define CSR_WIFI_SME_IEEE80211_REASON_UNSUPPORTED_RSN_IEVERSION                 ((CsrWifiSmeIEEE80211Reason) 0x0015)
-#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_RSN_IECAPABILITIES                ((CsrWifiSmeIEEE80211Reason) 0x0016)
-#define CSR_WIFI_SME_IEEE80211_REASON_DOT1X_AUTH_FAILED                         ((CsrWifiSmeIEEE80211Reason) 0x0017)
-#define CSR_WIFI_SME_IEEE80211_REASON_CIPHER_REJECTED_BY_POLICY                 ((CsrWifiSmeIEEE80211Reason) 0x0018)
-#define CSR_WIFI_SME_IEEE80211_REASON_SERVICE_CHANGE_PRECLUDES_TS               ((CsrWifiSmeIEEE80211Reason) 0x001F)
-#define CSR_WIFI_SME_IEEE80211_REASON_QOS_UNSPECIFIED_REASON                    ((CsrWifiSmeIEEE80211Reason) 0x0020)
-#define CSR_WIFI_SME_IEEE80211_REASON_QOS_INSUFFICIENT_BANDWIDTH                ((CsrWifiSmeIEEE80211Reason) 0x0021)
-#define CSR_WIFI_SME_IEEE80211_REASON_QOS_EXCESSIVE_NOT_ACK                     ((CsrWifiSmeIEEE80211Reason) 0x0022)
-#define CSR_WIFI_SME_IEEE80211_REASON_QOS_TXOPLIMIT_EXCEEDED                    ((CsrWifiSmeIEEE80211Reason) 0x0023)
-#define CSR_WIFI_SME_IEEE80211_REASON_QSTA_LEAVING                              ((CsrWifiSmeIEEE80211Reason) 0x0024)
-#define CSR_WIFI_SME_IEEE80211_REASON_END_TS                                    ((CsrWifiSmeIEEE80211Reason) 0x0025)
-#define CSR_WIFI_SME_IEEE80211_REASON_END_DLS                                   ((CsrWifiSmeIEEE80211Reason) 0x0025)
-#define CSR_WIFI_SME_IEEE80211_REASON_END_BA                                    ((CsrWifiSmeIEEE80211Reason) 0x0025)
-#define CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_TS                                ((CsrWifiSmeIEEE80211Reason) 0x0026)
-#define CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_BA                                ((CsrWifiSmeIEEE80211Reason) 0x0026)
-#define CSR_WIFI_SME_IEEE80211_REASON_UNKNOWN_DLS                               ((CsrWifiSmeIEEE80211Reason) 0x0026)
-#define CSR_WIFI_SME_IEEE80211_REASON_TIMEOUT                                   ((CsrWifiSmeIEEE80211Reason) 0x0027)
-#define CSR_WIFI_SME_IEEE80211_REASON_STAKEY_MISMATCH                           ((CsrWifiSmeIEEE80211Reason) 0x002d)
-#define CSR_WIFI_SME_IEEE80211_REASON_UNICAST_KEY_NEGOTIATION_TIMEOUT           ((CsrWifiSmeIEEE80211Reason) 0xf019)
-#define CSR_WIFI_SME_IEEE80211_REASON_MULTICAST_KEY_ANNOUNCEMENT_TIMEOUT        ((CsrWifiSmeIEEE80211Reason) 0xf01a)
-#define CSR_WIFI_SME_IEEE80211_REASON_INCOMPATIBLE_UNICAST_KEY_NEGOTIATION_IE   ((CsrWifiSmeIEEE80211Reason) 0xf01b)
-#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_MULTICAST_CIPHER                  ((CsrWifiSmeIEEE80211Reason) 0xf01c)
-#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_UNICAST_CIPHER                    ((CsrWifiSmeIEEE80211Reason) 0xf01d)
-#define CSR_WIFI_SME_IEEE80211_REASON_UNSUPPORTED_WAPI_IE_VERSION               ((CsrWifiSmeIEEE80211Reason) 0xf01e)
-#define CSR_WIFI_SME_IEEE80211_REASON_INVALID_WAPI_CAPABILITY_IE                ((CsrWifiSmeIEEE80211Reason) 0xf01f)
-#define CSR_WIFI_SME_IEEE80211_REASON_WAI_CERTIFICATE_AUTHENTICATION_FAILED     ((CsrWifiSmeIEEE80211Reason) 0xf020)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeIEEE80211Result
-
-  DESCRIPTION
-    As definined in the IEEE 802.11 standards
-
- VALUES
-    CSR_WIFI_SME_IEEE80211_RESULT_SUCCESS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_UNSPECIFIED_FAILURE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CAPABILITIES_MISMATCH
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REASSOCIATION_DENIED_NO_ASSOCIATION
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_EXTERNAL_REASON
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AUTHENTICATION_MISMATCH
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_INVALID_AUTHENTICATION_SEQUENCE_NUMBER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CHALLENGE_FAILURE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AUTHENTICATION_TIMEOUT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AP_OUT_OF_MEMORY
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_BASIC_RATES_MISMATCH
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SHORT_PREAMBLE_REQUIRED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_PBCC_MODULATION_REQUIRED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CHANNEL_AGILITY_REQUIRED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SPECTRUM_MANAGEMENT_REQUIRED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_POWER_CAPABILITY_UNACCEPTABLE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SUPPORTED_CHANNELS_UNACCEPTABLE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SHORT_SLOT_REQUIRED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_DSSS_OFDMREQUIRED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_NO_HT_SUPPORT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_R0KH_UNREACHABLE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_PCO_TRANSITION_SUPPORT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_ASSOCIATION_REQUEST_REJECTED_TEMPORARILY
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_ROBUST_MANAGEMENT_FRAME_POLICY_VIOLATION
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_FAILURE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AP_BANDWIDTH_INSUFFICIENT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_POOR_OPERATING_CHANNEL
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_QOS_REQUIRED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_REASON_UNSPECIFIED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INVALID_PARAMETERS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_WITH_SUGGESTED_TSPEC_CHANGES
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_IE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_GROUP_CIPHER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_PAIRWISE_CIPHER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_AKMP
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_UNSUPPORTED_RSN_VERSION
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_RSN_CAPABILITY
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_SECURITY_POLICY
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_FOR_DELAY_PERIOD
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_NOT_ALLOWED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_NOT_PRESENT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_NOT_QSTA
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_LISTEN_INTERVAL_TOO_LARGE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INVALID_FT_ACTION_FRAME_COUNT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INVALID_PMKID
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INVALID_MDIE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INVALID_FTIE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_UNSPECIFIED_QOS_FAILURE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_WRONG_POLICY
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INSUFFICIENT_BANDWIDTH
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INVALID_TSPEC_PARAMETERS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_TIMEOUT
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_TOO_MANY_SIMULTANEOUS_REQUESTS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_BSS_ALREADY_STARTED_OR_JOINED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_NOT_SUPPORTED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_TRANSMISSION_FAILURE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_NOT_AUTHENTICATED
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_RESET_REQUIRED_BEFORE_START
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_LM_INFO_UNAVAILABLE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INVALID_UNICAST_CIPHER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INVALID_MULTICAST_CIPHER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_UNSUPPORTED_WAPI_IE_VERSION
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_IEEE80211_RESULT_INVALID_WAPI_CAPABILITY_IE
-                   - See IEEE 802.11 Standard
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeIEEE80211Result;
-#define CSR_WIFI_SME_IEEE80211_RESULT_SUCCESS                                          ((CsrWifiSmeIEEE80211Result) 0x0000)
-#define CSR_WIFI_SME_IEEE80211_RESULT_UNSPECIFIED_FAILURE                              ((CsrWifiSmeIEEE80211Result) 0x0001)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CAPABILITIES_MISMATCH                    ((CsrWifiSmeIEEE80211Result) 0x000a)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REASSOCIATION_DENIED_NO_ASSOCIATION              ((CsrWifiSmeIEEE80211Result) 0x000b)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_EXTERNAL_REASON                          ((CsrWifiSmeIEEE80211Result) 0x000c)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AUTHENTICATION_MISMATCH                  ((CsrWifiSmeIEEE80211Result) 0x000d)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_INVALID_AUTHENTICATION_SEQUENCE_NUMBER   ((CsrWifiSmeIEEE80211Result) 0x000e)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CHALLENGE_FAILURE                        ((CsrWifiSmeIEEE80211Result) 0x000f)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AUTHENTICATION_TIMEOUT                   ((CsrWifiSmeIEEE80211Result) 0x0010)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AP_OUT_OF_MEMORY                         ((CsrWifiSmeIEEE80211Result) 0x0011)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_BASIC_RATES_MISMATCH                     ((CsrWifiSmeIEEE80211Result) 0x0012)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SHORT_PREAMBLE_REQUIRED                  ((CsrWifiSmeIEEE80211Result) 0x0013)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_PBCC_MODULATION_REQUIRED                 ((CsrWifiSmeIEEE80211Result) 0x0014)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_CHANNEL_AGILITY_REQUIRED                 ((CsrWifiSmeIEEE80211Result) 0x0015)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SPECTRUM_MANAGEMENT_REQUIRED             ((CsrWifiSmeIEEE80211Result) 0x0016)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_POWER_CAPABILITY_UNACCEPTABLE            ((CsrWifiSmeIEEE80211Result) 0x0017)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SUPPORTED_CHANNELS_UNACCEPTABLE          ((CsrWifiSmeIEEE80211Result) 0x0018)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_SHORT_SLOT_REQUIRED                      ((CsrWifiSmeIEEE80211Result) 0x0019)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_DSSS_OFDMREQUIRED                        ((CsrWifiSmeIEEE80211Result) 0x001a)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_NO_HT_SUPPORT                            ((CsrWifiSmeIEEE80211Result) 0x001b)
-#define CSR_WIFI_SME_IEEE80211_RESULT_R0KH_UNREACHABLE                                 ((CsrWifiSmeIEEE80211Result) 0x001c)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_PCO_TRANSITION_SUPPORT                   ((CsrWifiSmeIEEE80211Result) 0x001d)
-#define CSR_WIFI_SME_IEEE80211_RESULT_ASSOCIATION_REQUEST_REJECTED_TEMPORARILY         ((CsrWifiSmeIEEE80211Result) 0x001e)
-#define CSR_WIFI_SME_IEEE80211_RESULT_ROBUST_MANAGEMENT_FRAME_POLICY_VIOLATION         ((CsrWifiSmeIEEE80211Result) 0x001f)
-#define CSR_WIFI_SME_IEEE80211_RESULT_FAILURE                                          ((CsrWifiSmeIEEE80211Result) 0x0020)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_AP_BANDWIDTH_INSUFFICIENT                ((CsrWifiSmeIEEE80211Result) 0x0021)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_POOR_OPERATING_CHANNEL                   ((CsrWifiSmeIEEE80211Result) 0x0022)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_QOS_REQUIRED                             ((CsrWifiSmeIEEE80211Result) 0x0023)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_REASON_UNSPECIFIED                       ((CsrWifiSmeIEEE80211Result) 0x0025)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED                                          ((CsrWifiSmeIEEE80211Result) 0x0025)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_PARAMETERS                               ((CsrWifiSmeIEEE80211Result) 0x0026)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_WITH_SUGGESTED_TSPEC_CHANGES            ((CsrWifiSmeIEEE80211Result) 0x0027)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_IE                              ((CsrWifiSmeIEEE80211Result) 0x0028)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_GROUP_CIPHER                    ((CsrWifiSmeIEEE80211Result) 0x0029)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_PAIRWISE_CIPHER                 ((CsrWifiSmeIEEE80211Result) 0x002a)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_AKMP                            ((CsrWifiSmeIEEE80211Result) 0x002b)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_UNSUPPORTED_RSN_VERSION                 ((CsrWifiSmeIEEE80211Result) 0x002c)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_INVALID_RSN_CAPABILITY                  ((CsrWifiSmeIEEE80211Result) 0x002d)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_SECURITY_POLICY                         ((CsrWifiSmeIEEE80211Result) 0x002e)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_FOR_DELAY_PERIOD                        ((CsrWifiSmeIEEE80211Result) 0x002f)
-#define CSR_WIFI_SME_IEEE80211_RESULT_NOT_ALLOWED                                      ((CsrWifiSmeIEEE80211Result) 0x0030)
-#define CSR_WIFI_SME_IEEE80211_RESULT_NOT_PRESENT                                      ((CsrWifiSmeIEEE80211Result) 0x0031)
-#define CSR_WIFI_SME_IEEE80211_RESULT_NOT_QSTA                                         ((CsrWifiSmeIEEE80211Result) 0x0032)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REJECTED_LISTEN_INTERVAL_TOO_LARGE               ((CsrWifiSmeIEEE80211Result) 0x0033)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_FT_ACTION_FRAME_COUNT                    ((CsrWifiSmeIEEE80211Result) 0x0034)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_PMKID                                    ((CsrWifiSmeIEEE80211Result) 0x0035)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_MDIE                                     ((CsrWifiSmeIEEE80211Result) 0x0036)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_FTIE                                     ((CsrWifiSmeIEEE80211Result) 0x0037)
-#define CSR_WIFI_SME_IEEE80211_RESULT_UNSPECIFIED_QOS_FAILURE                          ((CsrWifiSmeIEEE80211Result) 0x00c8)
-#define CSR_WIFI_SME_IEEE80211_RESULT_WRONG_POLICY                                     ((CsrWifiSmeIEEE80211Result) 0x00c9)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INSUFFICIENT_BANDWIDTH                           ((CsrWifiSmeIEEE80211Result) 0x00ca)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_TSPEC_PARAMETERS                         ((CsrWifiSmeIEEE80211Result) 0x00cb)
-#define CSR_WIFI_SME_IEEE80211_RESULT_TIMEOUT                                          ((CsrWifiSmeIEEE80211Result) 0x8000)
-#define CSR_WIFI_SME_IEEE80211_RESULT_TOO_MANY_SIMULTANEOUS_REQUESTS                   ((CsrWifiSmeIEEE80211Result) 0x8001)
-#define CSR_WIFI_SME_IEEE80211_RESULT_BSS_ALREADY_STARTED_OR_JOINED                    ((CsrWifiSmeIEEE80211Result) 0x8002)
-#define CSR_WIFI_SME_IEEE80211_RESULT_NOT_SUPPORTED                                    ((CsrWifiSmeIEEE80211Result) 0x8003)
-#define CSR_WIFI_SME_IEEE80211_RESULT_TRANSMISSION_FAILURE                             ((CsrWifiSmeIEEE80211Result) 0x8004)
-#define CSR_WIFI_SME_IEEE80211_RESULT_REFUSED_NOT_AUTHENTICATED                        ((CsrWifiSmeIEEE80211Result) 0x8005)
-#define CSR_WIFI_SME_IEEE80211_RESULT_RESET_REQUIRED_BEFORE_START                      ((CsrWifiSmeIEEE80211Result) 0x8006)
-#define CSR_WIFI_SME_IEEE80211_RESULT_LM_INFO_UNAVAILABLE                              ((CsrWifiSmeIEEE80211Result) 0x8007)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_UNICAST_CIPHER                           ((CsrWifiSmeIEEE80211Result) 0xf02f)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_MULTICAST_CIPHER                         ((CsrWifiSmeIEEE80211Result) 0xf030)
-#define CSR_WIFI_SME_IEEE80211_RESULT_UNSUPPORTED_WAPI_IE_VERSION                      ((CsrWifiSmeIEEE80211Result) 0xf031)
-#define CSR_WIFI_SME_IEEE80211_RESULT_INVALID_WAPI_CAPABILITY_IE                       ((CsrWifiSmeIEEE80211Result) 0xf032)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeIndications
-
-  DESCRIPTION
-    Defines bits for CsrWifiSmeIndicationsMask
-
- VALUES
-    CSR_WIFI_SME_INDICATIONS_NONE
-                   - Used to cancel the registrations for receiving indications
-    CSR_WIFI_SME_INDICATIONS_WIFIOFF
-                   - Used to register for CSR_WIFI_SME_WIFI_OFF_IND events
-    CSR_WIFI_SME_INDICATIONS_SCANRESULT
-                   - Used to register for CSR_WIFI_SME_SCAN_RESULT_IND events
-    CSR_WIFI_SME_INDICATIONS_CONNECTIONQUALITY
-                   - Used to register for CSR_WIFI_SME_CONNECTION_QUALITY_IND
-                     events
-    CSR_WIFI_SME_INDICATIONS_MEDIASTATUS
-                   - Used to register for CSR_WIFI_SME_MEDIA_STATUS_IND events
-    CSR_WIFI_SME_INDICATIONS_MICFAILURE
-                   - Used to register for CSR_WIFI_SME_MICFAILURE_IND events
-    CSR_WIFI_SME_INDICATIONS_PMKIDCANDIDATELIST
-                   - Used to register for CSR_WIFI_SME_PMKIDCANDIDATE_LIST_IND
-                     events
-    CSR_WIFI_SME_INDICATIONS_TSPEC
-                   - Used to register for CSR_WIFI_SME_TSPEC_IND events
-    CSR_WIFI_SME_INDICATIONS_ROAMSTART
-                   - Used to register for CSR_WIFI_SME_ROAM_START_IND events
-    CSR_WIFI_SME_INDICATIONS_ROAMCOMPLETE
-                   - Used to register for CSR_WIFI_SME_ROAM_COMPLETE_IND events
-    CSR_WIFI_SME_INDICATIONS_ASSOCIATIONSTART
-                   - Used to register for CSR_WIFI_SME_ASSOCIATION_START_IND
-                     events
-    CSR_WIFI_SME_INDICATIONS_ASSOCIATIONCOMPLETE
-                   - Used to register for CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND
-                     events
-    CSR_WIFI_SME_INDICATIONS_IBSSSTATION
-                   - Used to register for CSR_WIFI_SME_IBSS_STATION_IND events
-    CSR_WIFI_SME_INDICATIONS_WIFION
-                   - Used to register for CSR_WIFI_SME_WIFI_ON_IND events
-    CSR_WIFI_SME_INDICATIONS_ERROR
-                   - Used to register for CSR_WIFI_SME_ERROR_IND events
-    CSR_WIFI_SME_INDICATIONS_INFO
-                   - Used to register for CSR_WIFI_SME_INFO_IND events
-    CSR_WIFI_SME_INDICATIONS_COREDUMP
-                   - Used to register for CSR_WIFI_SME_CORE_DUMP_IND events
-    CSR_WIFI_SME_INDICATIONS_ALL
-                   - Used to register for all available indications
-
-*******************************************************************************/
-typedef u32 CsrWifiSmeIndications;
-#define CSR_WIFI_SME_INDICATIONS_NONE                  ((CsrWifiSmeIndications) 0x00000000)
-#define CSR_WIFI_SME_INDICATIONS_WIFIOFF               ((CsrWifiSmeIndications) 0x00000001)
-#define CSR_WIFI_SME_INDICATIONS_SCANRESULT            ((CsrWifiSmeIndications) 0x00000002)
-#define CSR_WIFI_SME_INDICATIONS_CONNECTIONQUALITY     ((CsrWifiSmeIndications) 0x00000004)
-#define CSR_WIFI_SME_INDICATIONS_MEDIASTATUS           ((CsrWifiSmeIndications) 0x00000008)
-#define CSR_WIFI_SME_INDICATIONS_MICFAILURE            ((CsrWifiSmeIndications) 0x00000010)
-#define CSR_WIFI_SME_INDICATIONS_PMKIDCANDIDATELIST    ((CsrWifiSmeIndications) 0x00000020)
-#define CSR_WIFI_SME_INDICATIONS_TSPEC                 ((CsrWifiSmeIndications) 0x00000040)
-#define CSR_WIFI_SME_INDICATIONS_ROAMSTART             ((CsrWifiSmeIndications) 0x00000080)
-#define CSR_WIFI_SME_INDICATIONS_ROAMCOMPLETE          ((CsrWifiSmeIndications) 0x00000100)
-#define CSR_WIFI_SME_INDICATIONS_ASSOCIATIONSTART      ((CsrWifiSmeIndications) 0x00000200)
-#define CSR_WIFI_SME_INDICATIONS_ASSOCIATIONCOMPLETE   ((CsrWifiSmeIndications) 0x00000400)
-#define CSR_WIFI_SME_INDICATIONS_IBSSSTATION           ((CsrWifiSmeIndications) 0x00000800)
-#define CSR_WIFI_SME_INDICATIONS_WIFION                ((CsrWifiSmeIndications) 0x00001000)
-#define CSR_WIFI_SME_INDICATIONS_ERROR                 ((CsrWifiSmeIndications) 0x00002000)
-#define CSR_WIFI_SME_INDICATIONS_INFO                  ((CsrWifiSmeIndications) 0x00004000)
-#define CSR_WIFI_SME_INDICATIONS_COREDUMP              ((CsrWifiSmeIndications) 0x00008000)
-#define CSR_WIFI_SME_INDICATIONS_ALL                   ((CsrWifiSmeIndications) 0xFFFFFFFF)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeKeyType
-
-  DESCRIPTION
-    Indicates the type of the key
-
- VALUES
-    CSR_WIFI_SME_KEY_TYPE_GROUP    - Key for broadcast communication
-    CSR_WIFI_SME_KEY_TYPE_PAIRWISE - Key for unicast communication
-    CSR_WIFI_SME_KEY_TYPE_STAKEY   - Key for direct link communication to
-                                     another station in infrastructure networks
-    CSR_WIFI_SME_KEY_TYPE_IGTK     - Integrity Group Temporal Key
-    CSR_WIFI_SME_KEY_TYPE_CCKM     - Key for Cisco Centralized Key Management
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeKeyType;
-#define CSR_WIFI_SME_KEY_TYPE_GROUP      ((CsrWifiSmeKeyType) 0x00)
-#define CSR_WIFI_SME_KEY_TYPE_PAIRWISE   ((CsrWifiSmeKeyType) 0x01)
-#define CSR_WIFI_SME_KEY_TYPE_STAKEY     ((CsrWifiSmeKeyType) 0x02)
-#define CSR_WIFI_SME_KEY_TYPE_IGTK       ((CsrWifiSmeKeyType) 0x03)
-#define CSR_WIFI_SME_KEY_TYPE_CCKM       ((CsrWifiSmeKeyType) 0x04)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeListAction
-
-  DESCRIPTION
-    Identifies the type of action to be performed on a list of items
-    The values of this type are used across the NME/SME/Router API's and they
-    must be kept consistent with the corresponding types in the .xml of the
-    ottherinterfaces
-
- VALUES
-    CSR_WIFI_SME_LIST_ACTION_GET    - Retrieve the current list of items
-    CSR_WIFI_SME_LIST_ACTION_ADD    - Add one or more items
-    CSR_WIFI_SME_LIST_ACTION_REMOVE - Remove one or more items
-    CSR_WIFI_SME_LIST_ACTION_FLUSH  - Remove all items
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeListAction;
-#define CSR_WIFI_SME_LIST_ACTION_GET      ((CsrWifiSmeListAction) 0x00)
-#define CSR_WIFI_SME_LIST_ACTION_ADD      ((CsrWifiSmeListAction) 0x01)
-#define CSR_WIFI_SME_LIST_ACTION_REMOVE   ((CsrWifiSmeListAction) 0x02)
-#define CSR_WIFI_SME_LIST_ACTION_FLUSH    ((CsrWifiSmeListAction) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMediaStatus
-
-  DESCRIPTION
-    Indicates the connection status
-    The values of this type are used across the NME/SME/Router API's and they
-    must be kept consistent with the corresponding types in the .xml of the
-    ottherinterfaces
-
- VALUES
-    CSR_WIFI_SME_MEDIA_STATUS_CONNECTED
-                   - Value CSR_WIFI_SME_MEDIA_STATUS_CONNECTED can happen in two
-                     situations:
-                       * A network connection is established. Specifically, this is
-                         when the MLME_ASSOCIATION completes or the first peer
-                         relationship is established in an IBSS. In a WPA/WPA2
-                         network, this indicates that the stack is ready to perform
-                         the 4-way handshake or 802.1x authentication if CSR NME
-                         security library is not used. If CSR NME security library
-                         is used this indicates, completion of 4way handshake or
-                         802.1x authentication
-                       * The SME roams to another AP on the same ESS
-                     During the AP operation, it indicates that the peer station
-                     is connected to the AP and is ready for data transfer.
-    CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED
-                   - Value CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED can happen in
-                     two situations:
-                       * when the connection to a network is lost and there is no
-                         alternative on the same ESS to roam to
-                       * when a CSR_WIFI_SME_DISCONNECT_REQ request is issued
-                     During AP or P2PGO operation, it indicates that the peer
-                     station has disconnected from the AP
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeMediaStatus;
-#define CSR_WIFI_SME_MEDIA_STATUS_CONNECTED      ((CsrWifiSmeMediaStatus) 0x00)
-#define CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED   ((CsrWifiSmeMediaStatus) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pCapability
-
-  DESCRIPTION
-    Defines P2P Device Capabilities
-
- VALUES
-    CSR_WIFI_SME_P2P_SERVICE_DISCOVERY_CAPABILITY
-                   - This field is set to 1 if the P2P Device supports Service
-                     Discovery, and to 0 otherwise
-    CSR_WIFI_SME_P2P_CLIENT_DISCOVERABILITY_CAPABILITY
-                   - This field is set to 1 when the P2P Device supports P2P
-                     Client Discoverability, and to 0 otherwise.
-    CSR_WIFI_SME_P2P_CONCURRENT_OPERATION_CAPABILITY
-                   - This field is set to 1 when the P2P Device supports
-                     Concurrent Operation with WLAN, and to 0 otherwise.
-    CSR_WIFI_SME_P2P_MANAGED_DEVICE_CAPABILITY
-                   - This field is set to 1 when the P2P interface of the P2P
-                     Device is capable of being managed by the WLAN
-                     (infrastructure network) based on P2P coexistence
-                     parameters, and to 0 otherwise
-    CSR_WIFI_SME_P2P_INVITAION_CAPABILITY
-                   - This field is set to 1 if the P2P Device is capable of
-                     processing P2P Invitation Procedure signaling, and to 0
-                     otherwise.
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeP2pCapability;
-#define CSR_WIFI_SME_P2P_SERVICE_DISCOVERY_CAPABILITY        ((CsrWifiSmeP2pCapability) 0x01)
-#define CSR_WIFI_SME_P2P_CLIENT_DISCOVERABILITY_CAPABILITY   ((CsrWifiSmeP2pCapability) 0x02)
-#define CSR_WIFI_SME_P2P_CONCURRENT_OPERATION_CAPABILITY     ((CsrWifiSmeP2pCapability) 0x04)
-#define CSR_WIFI_SME_P2P_MANAGED_DEVICE_CAPABILITY           ((CsrWifiSmeP2pCapability) 0x08)
-#define CSR_WIFI_SME_P2P_INVITAION_CAPABILITY                ((CsrWifiSmeP2pCapability) 0x20)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pGroupCapability
-
-  DESCRIPTION
-    Define bits for P2P Group Capability
-
- VALUES
-    CSR_WIFI_P2P_GRP_CAP_GO
-                   - Indicates if the local device has become a GO after GO
-                     negotiation
-    CSR_WIFI_P2P_GRP_CAP_PERSISTENT
-                   - Persistent group
-    CSR_WIFI_P2P_GRP_CAP_INTRABSS_DIST
-                   - Intra-BSS data distribution support
-    CSR_WIFI_P2P_GRP_CAP_CROSS_CONN
-                   - Support of cross connection
-    CSR_WIFI_P2P_GRP_CAP_PERSISTENT_RECONNECT
-                   - Support of persistent reconnect
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeP2pGroupCapability;
-#define CSR_WIFI_P2P_GRP_CAP_GO                     ((CsrWifiSmeP2pGroupCapability) 0x01)
-#define CSR_WIFI_P2P_GRP_CAP_PERSISTENT             ((CsrWifiSmeP2pGroupCapability) 0x02)
-#define CSR_WIFI_P2P_GRP_CAP_INTRABSS_DIST          ((CsrWifiSmeP2pGroupCapability) 0x08)
-#define CSR_WIFI_P2P_GRP_CAP_CROSS_CONN             ((CsrWifiSmeP2pGroupCapability) 0x10)
-#define CSR_WIFI_P2P_GRP_CAP_PERSISTENT_RECONNECT   ((CsrWifiSmeP2pGroupCapability) 0x20)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pNoaConfigMethod
-
-  DESCRIPTION
-    Notice of Absece Configuration
-
- VALUES
-    CSR_WIFI_P2P_NOA_NONE         - Do not use NOA
-    CSR_WIFI_P2P_NOA_AUTONOMOUS   - NOA based on the traffic analysis
-    CSR_WIFI_P2P_NOA_USER_DEFINED - NOA as specified by the user
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeP2pNoaConfigMethod;
-#define CSR_WIFI_P2P_NOA_NONE           ((CsrWifiSmeP2pNoaConfigMethod) 0x00)
-#define CSR_WIFI_P2P_NOA_AUTONOMOUS     ((CsrWifiSmeP2pNoaConfigMethod) 0x01)
-#define CSR_WIFI_P2P_NOA_USER_DEFINED   ((CsrWifiSmeP2pNoaConfigMethod) 0x02)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pRole
-
-  DESCRIPTION
-    Definition of roles for a P2P Device
-
- VALUES
-    CSR_WIFI_SME_P2P_ROLE_NONE       - A non-P2PDevice device
-    CSR_WIFI_SME_P2P_ROLE_STANDALONE - A Standalone P2P device
-    CSR_WIFI_SME_P2P_ROLE_GO         - Role Assumed is that of a Group Owner
-                                       within a P2P Group
-    CSR_WIFI_SME_P2P_ROLE_CLI        - Role Assumed is that of a P2P Client
-                                       within a P2P Group
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeP2pRole;
-#define CSR_WIFI_SME_P2P_ROLE_NONE         ((CsrWifiSmeP2pRole) 0x00)
-#define CSR_WIFI_SME_P2P_ROLE_STANDALONE   ((CsrWifiSmeP2pRole) 0x01)
-#define CSR_WIFI_SME_P2P_ROLE_GO           ((CsrWifiSmeP2pRole) 0x02)
-#define CSR_WIFI_SME_P2P_ROLE_CLI          ((CsrWifiSmeP2pRole) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pStatus
-
-  DESCRIPTION
-    This data type enumerates the outcome of P2P procedure
-
- VALUES
-    CSR_WIFI_SME_P2P_STATUS_SUCCESS
-                   - Success
-    CSR_WIFI_SME_P2P_STATUS_FAIL_INFO_UNAVAILABLE
-                   - Fail; information is currently unavailable
-    CSR_WIFI_SME_P2P_STATUS_FAIL_INCOMPATIBLE_PARAM
-                   - Fail; incompatible parameters
-    CSR_WIFI_SME_P2P_STATUS_FAIL_LIMIT_REACHED
-                   - Fail; limit reached
-    CSR_WIFI_SME_P2P_STATUS_FAIL_INVALID_PARAM
-                   - Fail; invalid parameters
-    CSR_WIFI_SME_P2P_STATUS_FAIL_ACCOMODATE
-                   - Fail; unable to accommodate request
-    CSR_WIFI_SME_P2P_STATUS_FAIL_PREV_ERROR
-                   - Fail; previous protocol error, or disruptive behavior
-    CSR_WIFI_SME_P2P_STATUS_FAIL_COMMON_CHANNELS
-                   - Fail; no common channels
-    CSR_WIFI_SME_P2P_STATUS_FAIL_UNKNOWN_GROUP
-                   - Fail; unknown P2P Group
-    CSR_WIFI_SME_P2P_STATUS_FAIL_GO_INTENT
-                   - Fail: both P2P Devices indicated an Intent of 15 in Group
-                     Owner Negotiation
-    CSR_WIFI_SME_P2P_STATUS_FAIL_PROVISION_METHOD_INCOMPATIBLE
-                   - Fail; incompatible provisioning method
-    CSR_WIFI_SME_P2P_STATUS_FAIL_REJECT
-                   - Fail: rejected by user
-    CSR_WIFI_SME_P2P_STATUS_FAIL_RESERVED
-                   - Fail; Status Reserved
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeP2pStatus;
-#define CSR_WIFI_SME_P2P_STATUS_SUCCESS                              ((CsrWifiSmeP2pStatus) 0x00)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_INFO_UNAVAILABLE                ((CsrWifiSmeP2pStatus) 0x01)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_INCOMPATIBLE_PARAM              ((CsrWifiSmeP2pStatus) 0x02)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_LIMIT_REACHED                   ((CsrWifiSmeP2pStatus) 0x03)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_INVALID_PARAM                   ((CsrWifiSmeP2pStatus) 0x04)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_ACCOMODATE                      ((CsrWifiSmeP2pStatus) 0x05)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_PREV_ERROR                      ((CsrWifiSmeP2pStatus) 0x06)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_COMMON_CHANNELS                 ((CsrWifiSmeP2pStatus) 0x07)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_UNKNOWN_GROUP                   ((CsrWifiSmeP2pStatus) 0x08)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_GO_INTENT                       ((CsrWifiSmeP2pStatus) 0x09)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_PROVISION_METHOD_INCOMPATIBLE   ((CsrWifiSmeP2pStatus) 0x0A)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_REJECT                          ((CsrWifiSmeP2pStatus) 0x0B)
-#define CSR_WIFI_SME_P2P_STATUS_FAIL_RESERVED                        ((CsrWifiSmeP2pStatus) 0xFF)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePacketFilterMode
-
-  DESCRIPTION
-    Options for the filter mode parameter.
-    The Values here match the HIP interface
-
- VALUES
-    CSR_WIFI_SME_PACKET_FILTER_MODE_OPT_OUT
-                   - Broadcast packets are always reported to the host unless
-                     they match at least one of the specified TCLAS IEs.
-    CSR_WIFI_SME_PACKET_FILTER_MODE_OPT_IN
-                   - Broadcast packets are reported to the host only if they
-                     match at least one of the specified TCLAS IEs.
-
-*******************************************************************************/
-typedef u8 CsrWifiSmePacketFilterMode;
-#define CSR_WIFI_SME_PACKET_FILTER_MODE_OPT_OUT   ((CsrWifiSmePacketFilterMode) 0x00)
-#define CSR_WIFI_SME_PACKET_FILTER_MODE_OPT_IN    ((CsrWifiSmePacketFilterMode) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerSaveLevel
-
-  DESCRIPTION
-    Power Save Level options as defined in the IEEE 802.11 standards
-    First 3 values are set to match the mlme PowerManagementMode
-
- VALUES
-    CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW  - No power save: the driver will remain
-                                         active at all times
-    CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH - Enter power save after all packets in
-                                         the queues are transmitted and received
-    CSR_WIFI_SME_POWER_SAVE_LEVEL_MED  - Enter power save after all packets in
-                                         the queues are transmitted and received
-                                         and a further configurable delay
-                                         (default 1s) has elapsed
-    CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO - The SME will decide when to enter power
-                                         save mode according to the traffic
-                                         analysis
-
-*******************************************************************************/
-typedef u8 CsrWifiSmePowerSaveLevel;
-#define CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW    ((CsrWifiSmePowerSaveLevel) 0x00)
-#define CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH   ((CsrWifiSmePowerSaveLevel) 0x01)
-#define CSR_WIFI_SME_POWER_SAVE_LEVEL_MED    ((CsrWifiSmePowerSaveLevel) 0x02)
-#define CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO   ((CsrWifiSmePowerSaveLevel) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePreambleType
-
-  DESCRIPTION
-    SME Preamble Types
-
- VALUES
-    CSR_WIFI_SME_USE_LONG_PREAMBLE  - Use legacy (long) preamble
-    CSR_WIFI_SME_USE_SHORT_PREAMBLE - Use short PPDU format
-
-*******************************************************************************/
-typedef u8 CsrWifiSmePreambleType;
-#define CSR_WIFI_SME_USE_LONG_PREAMBLE    ((CsrWifiSmePreambleType) 0x00)
-#define CSR_WIFI_SME_USE_SHORT_PREAMBLE   ((CsrWifiSmePreambleType) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRadioIF
-
-  DESCRIPTION
-    Indicates the frequency
-
- VALUES
-    CSR_WIFI_SME_RADIO_IF_GHZ_2_4 - Indicates the 2.4 GHZ frequency
-    CSR_WIFI_SME_RADIO_IF_GHZ_5_0 - Future use: currently not supported
-    CSR_WIFI_SME_RADIO_IF_BOTH    - Future use: currently not supported
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeRadioIF;
-#define CSR_WIFI_SME_RADIO_IF_GHZ_2_4   ((CsrWifiSmeRadioIF) 0x01)
-#define CSR_WIFI_SME_RADIO_IF_GHZ_5_0   ((CsrWifiSmeRadioIF) 0x02)
-#define CSR_WIFI_SME_RADIO_IF_BOTH      ((CsrWifiSmeRadioIF) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRegulatoryDomain
-
-  DESCRIPTION
-    Indicates the regulatory domain as defined in IEEE 802.11 standards
-
- VALUES
-    CSR_WIFI_SME_REGULATORY_DOMAIN_OTHER
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_FCC
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_IC
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_ETSI
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_SPAIN
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_FRANCE
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_JAPAN
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_JAPANBIS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_CHINA
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_CHINABIS
-                   - See IEEE 802.11 Standard
-    CSR_WIFI_SME_REGULATORY_DOMAIN_NONE
-                   - See IEEE 802.11 Standard
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeRegulatoryDomain;
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_OTHER      ((CsrWifiSmeRegulatoryDomain) 0x00)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_FCC        ((CsrWifiSmeRegulatoryDomain) 0x10)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_IC         ((CsrWifiSmeRegulatoryDomain) 0x20)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_ETSI       ((CsrWifiSmeRegulatoryDomain) 0x30)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_SPAIN      ((CsrWifiSmeRegulatoryDomain) 0x31)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_FRANCE     ((CsrWifiSmeRegulatoryDomain) 0x32)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_JAPAN      ((CsrWifiSmeRegulatoryDomain) 0x40)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_JAPANBIS   ((CsrWifiSmeRegulatoryDomain) 0x41)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_CHINA      ((CsrWifiSmeRegulatoryDomain) 0x50)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_CHINABIS   ((CsrWifiSmeRegulatoryDomain) 0x51)
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_NONE       ((CsrWifiSmeRegulatoryDomain) 0xFF)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamReason
-
-  DESCRIPTION
-    Indicates the reason for roaming
-
- VALUES
-    CSR_WIFI_SME_ROAM_REASON_BEACONLOST
-                   - The station cannot receive the beacon signal any more
-    CSR_WIFI_SME_ROAM_REASON_DISASSOCIATED
-                   - The station has been disassociated
-    CSR_WIFI_SME_ROAM_REASON_DEAUTHENTICATED
-                   - The station has been deauthenticated
-    CSR_WIFI_SME_ROAM_REASON_BETTERAPFOUND
-                   - A better AP has been found
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeRoamReason;
-#define CSR_WIFI_SME_ROAM_REASON_BEACONLOST        ((CsrWifiSmeRoamReason) 0x00)
-#define CSR_WIFI_SME_ROAM_REASON_DISASSOCIATED     ((CsrWifiSmeRoamReason) 0x01)
-#define CSR_WIFI_SME_ROAM_REASON_DEAUTHENTICATED   ((CsrWifiSmeRoamReason) 0x02)
-#define CSR_WIFI_SME_ROAM_REASON_BETTERAPFOUND     ((CsrWifiSmeRoamReason) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanType
-
-  DESCRIPTION
-    Identifies the type of scan to be performed
-
- VALUES
-    CSR_WIFI_SME_SCAN_TYPE_ALL     - Scan actively or passively according to the
-                                     regulatory domain restrictions
-    CSR_WIFI_SME_SCAN_TYPE_ACTIVE  - Scan actively only: send probes and listen
-                                     for answers
-    CSR_WIFI_SME_SCAN_TYPE_PASSIVE - Scan passively only: listen for beacon
-                                     messages
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeScanType;
-#define CSR_WIFI_SME_SCAN_TYPE_ALL       ((CsrWifiSmeScanType) 0x00)
-#define CSR_WIFI_SME_SCAN_TYPE_ACTIVE    ((CsrWifiSmeScanType) 0x01)
-#define CSR_WIFI_SME_SCAN_TYPE_PASSIVE   ((CsrWifiSmeScanType) 0x02)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTrafficType
-
-  DESCRIPTION
-    Identifies the type of traffic going on on the connection.
-    The values of this type are used across the NME/SME/Router API's and they
-    must be kept consistent with the corresponding types in the .xml of the
-    ottherinterfaces
-
- VALUES
-    CSR_WIFI_SME_TRAFFIC_TYPE_OCCASIONAL
-                   - During the last 30 seconds there were fewer than 20 packets
-                     per seconds in each second in both directions
-    CSR_WIFI_SME_TRAFFIC_TYPE_BURSTY
-                   - During the last 30 seconds there was at least one second
-                     during which more than 20 packets were received in either
-                     direction
-    CSR_WIFI_SME_TRAFFIC_TYPE_PERIODIC
-                   - During the last 5 seconds there were at least 10 packets
-                     received each second and a defined period for the traffic
-                     can be recognized
-    CSR_WIFI_SME_TRAFFIC_TYPE_CONTINUOUS
-                   - During the last 5 seconds there were at least 20 packets
-                     received each second in either direction
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeTrafficType;
-#define CSR_WIFI_SME_TRAFFIC_TYPE_OCCASIONAL   ((CsrWifiSmeTrafficType) 0x00)
-#define CSR_WIFI_SME_TRAFFIC_TYPE_BURSTY       ((CsrWifiSmeTrafficType) 0x01)
-#define CSR_WIFI_SME_TRAFFIC_TYPE_PERIODIC     ((CsrWifiSmeTrafficType) 0x02)
-#define CSR_WIFI_SME_TRAFFIC_TYPE_CONTINUOUS   ((CsrWifiSmeTrafficType) 0x03)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTspecCtrl
-
-  DESCRIPTION
-    Defines bits for CsrWifiSmeTspecCtrlMask for additional CCX configuration.
-    CURRENTLY NOT SUPPORTED.
-
- VALUES
-    CSR_WIFI_SME_TSPEC_CTRL_STRICT
-                   - No automatic negotiation
-    CSR_WIFI_SME_TSPEC_CTRL_CCX_SIGNALLING
-                   - Signalling TSPEC
-    CSR_WIFI_SME_TSPEC_CTRL_CCX_VOICE
-                   - Voice traffic TSPEC
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeTspecCtrl;
-#define CSR_WIFI_SME_TSPEC_CTRL_STRICT           ((CsrWifiSmeTspecCtrl) 0x01)
-#define CSR_WIFI_SME_TSPEC_CTRL_CCX_SIGNALLING   ((CsrWifiSmeTspecCtrl) 0x02)
-#define CSR_WIFI_SME_TSPEC_CTRL_CCX_VOICE        ((CsrWifiSmeTspecCtrl) 0x04)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTspecResultCode
-
-  DESCRIPTION
-    Defines the result of the TSPEC exchanges with the AP
-
- VALUES
-    CSR_WIFI_SME_TSPEC_RESULT_SUCCESS
-                   - TSPEC command has been processed correctly
-    CSR_WIFI_SME_TSPEC_RESULT_UNSPECIFIED_QOS_FAILURE
-                   - The Access Point reported a failure
-    CSR_WIFI_SME_TSPEC_RESULT_FAILURE
-                   - Internal failure in the SME
-    CSR_WIFI_SME_TSPEC_RESULT_INVALID_TSPEC_PARAMETERS
-                   - The TSPEC parameters are invalid
-    CSR_WIFI_SME_TSPEC_RESULT_INVALID_TCLAS_PARAMETERS
-                   - The TCLASS parameters are invalid
-    CSR_WIFI_SME_TSPEC_RESULT_INSUFFICIENT_BANDWIDTH
-                   - As specified by the WMM Spec
-    CSR_WIFI_SME_TSPEC_RESULT_WRONG_POLICY
-                   - As specified by the WMM Spec
-    CSR_WIFI_SME_TSPEC_RESULT_REJECTED_WITH_SUGGESTED_CHANGES
-                   - As specified by the WMM Spec
-    CSR_WIFI_SME_TSPEC_RESULT_TIMEOUT
-                   - The TSPEC negotiation timed out
-    CSR_WIFI_SME_TSPEC_RESULT_NOT_SUPPORTED
-                   - The Access Point does not support the TSPEC
-    CSR_WIFI_SME_TSPEC_RESULT_IE_LENGTH_INCORRECT
-                   - The length of the TSPEC is not correct
-    CSR_WIFI_SME_TSPEC_RESULT_INVALID_TRANSACTION_ID
-                   - The TSPEC transaction id is not in the list
-    CSR_WIFI_SME_TSPEC_RESULT_INSTALLED
-                   - The TSPEC has been installed and it is now active.
-    CSR_WIFI_SME_TSPEC_RESULT_TID_ALREADY_INSTALLED
-                   - The Traffic ID has already been installed
-    CSR_WIFI_SME_TSPEC_RESULT_TSPEC_REMOTELY_DELETED
-                   - The AP has deleted the TSPEC
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeTspecResultCode;
-#define CSR_WIFI_SME_TSPEC_RESULT_SUCCESS                           ((CsrWifiSmeTspecResultCode) 0x00)
-#define CSR_WIFI_SME_TSPEC_RESULT_UNSPECIFIED_QOS_FAILURE           ((CsrWifiSmeTspecResultCode) 0x01)
-#define CSR_WIFI_SME_TSPEC_RESULT_FAILURE                           ((CsrWifiSmeTspecResultCode) 0x02)
-#define CSR_WIFI_SME_TSPEC_RESULT_INVALID_TSPEC_PARAMETERS          ((CsrWifiSmeTspecResultCode) 0x05)
-#define CSR_WIFI_SME_TSPEC_RESULT_INVALID_TCLAS_PARAMETERS          ((CsrWifiSmeTspecResultCode) 0x06)
-#define CSR_WIFI_SME_TSPEC_RESULT_INSUFFICIENT_BANDWIDTH            ((CsrWifiSmeTspecResultCode) 0x07)
-#define CSR_WIFI_SME_TSPEC_RESULT_WRONG_POLICY                      ((CsrWifiSmeTspecResultCode) 0x08)
-#define CSR_WIFI_SME_TSPEC_RESULT_REJECTED_WITH_SUGGESTED_CHANGES   ((CsrWifiSmeTspecResultCode) 0x09)
-#define CSR_WIFI_SME_TSPEC_RESULT_TIMEOUT                           ((CsrWifiSmeTspecResultCode) 0x0D)
-#define CSR_WIFI_SME_TSPEC_RESULT_NOT_SUPPORTED                     ((CsrWifiSmeTspecResultCode) 0x0E)
-#define CSR_WIFI_SME_TSPEC_RESULT_IE_LENGTH_INCORRECT               ((CsrWifiSmeTspecResultCode) 0x10)
-#define CSR_WIFI_SME_TSPEC_RESULT_INVALID_TRANSACTION_ID            ((CsrWifiSmeTspecResultCode) 0x11)
-#define CSR_WIFI_SME_TSPEC_RESULT_INSTALLED                         ((CsrWifiSmeTspecResultCode) 0x12)
-#define CSR_WIFI_SME_TSPEC_RESULT_TID_ALREADY_INSTALLED             ((CsrWifiSmeTspecResultCode) 0x13)
-#define CSR_WIFI_SME_TSPEC_RESULT_TSPEC_REMOTELY_DELETED            ((CsrWifiSmeTspecResultCode) 0x14)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWepAuthMode
-
-  DESCRIPTION
-    Define bits for CsrWifiSmeWepAuthMode
-
- VALUES
-    CSR_WIFI_SME_WEP_AUTH_MODE_OPEN   - Open-WEP enabled network
-    CSR_WIFI_SME_WEP_AUTH_MODE_SHARED - Shared-key WEP enabled network.
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeWepAuthMode;
-#define CSR_WIFI_SME_WEP_AUTH_MODE_OPEN     ((CsrWifiSmeWepAuthMode) 0x00)
-#define CSR_WIFI_SME_WEP_AUTH_MODE_SHARED   ((CsrWifiSmeWepAuthMode) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWepCredentialType
-
-  DESCRIPTION
-    Definition of types of WEP Credentials
-
- VALUES
-    CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64
-                   - WEP 64 credential
-    CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128
-                   - WEP 128 credential
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeWepCredentialType;
-#define CSR_WIFI_SME_CREDENTIAL_TYPE_WEP64    ((CsrWifiSmeWepCredentialType) 0x00)
-#define CSR_WIFI_SME_CREDENTIAL_TYPE_WEP128   ((CsrWifiSmeWepCredentialType) 0x01)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWmmMode
-
-  DESCRIPTION
-    Defines bits for CsrWifiSmeWmmModeMask: enable/disable WMM features.
-
- VALUES
-    CSR_WIFI_SME_WMM_MODE_DISABLED   - Disables the WMM features.
-    CSR_WIFI_SME_WMM_MODE_AC_ENABLED - Enables support for WMM-AC.
-    CSR_WIFI_SME_WMM_MODE_PS_ENABLED - Enables support for WMM Power Save.
-    CSR_WIFI_SME_WMM_MODE_SA_ENABLED - Currently not supported
-    CSR_WIFI_SME_WMM_MODE_ENABLED    - Enables support for all currently
-                                       available WMM features.
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeWmmMode;
-#define CSR_WIFI_SME_WMM_MODE_DISABLED     ((CsrWifiSmeWmmMode) 0x00)
-#define CSR_WIFI_SME_WMM_MODE_AC_ENABLED   ((CsrWifiSmeWmmMode) 0x01)
-#define CSR_WIFI_SME_WMM_MODE_PS_ENABLED   ((CsrWifiSmeWmmMode) 0x02)
-#define CSR_WIFI_SME_WMM_MODE_SA_ENABLED   ((CsrWifiSmeWmmMode) 0x04)
-#define CSR_WIFI_SME_WMM_MODE_ENABLED      ((CsrWifiSmeWmmMode) 0xFF)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWmmQosInfo
-
-  DESCRIPTION
-    Defines bits for the QoS Info Octect as defined in the WMM specification.
-    The first four values define one bit each that can be set or cleared.
-    Each of the last four values define all the remaining 4 bits and only one
-    of them at the time shall be used.
-    For more information, see 'WMM (including WMM Power Save) Specification -
-    Version 1.1' and 'UniFi Configuring WMM and WMM-PS, Application Note'.
-
- VALUES
-    CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_ALL
-                   - WMM AP may deliver all buffered frames
-    CSR_WIFI_SME_WMM_QOS_INFO_AC_VO
-                   - Enable UAPSD(both trigger and delivery) for Voice Access
-                     Category
-    CSR_WIFI_SME_WMM_QOS_INFO_AC_VI
-                   - Enable UAPSD(both trigger and delivery) for  Video Access
-                     Category
-    CSR_WIFI_SME_WMM_QOS_INFO_AC_BK
-                   - Enable UAPSD(both trigger and delivery) for  Background
-                     Access Category
-    CSR_WIFI_SME_WMM_QOS_INFO_AC_BE
-                   - Enable UAPSD(both trigger and delivery) for  Best Effort
-                     Access Category
-    CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_TWO
-                   - WMM AP may deliver a maximum of 2 buffered frames (MSDUs
-                     and MMPDUs) per USP
-    CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_FOUR
-                   - WMM AP may deliver a maximum of 4 buffered frames (MSDUs
-                     and MMPDUs) per USP
-    CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_SIX
-                   - WMM AP may deliver a maximum of 6 buffered frames (MSDUs
-                     and MMPDUs) per USP
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeWmmQosInfo;
-#define CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_ALL    ((CsrWifiSmeWmmQosInfo) 0x00)
-#define CSR_WIFI_SME_WMM_QOS_INFO_AC_VO            ((CsrWifiSmeWmmQosInfo) 0x01)
-#define CSR_WIFI_SME_WMM_QOS_INFO_AC_VI            ((CsrWifiSmeWmmQosInfo) 0x02)
-#define CSR_WIFI_SME_WMM_QOS_INFO_AC_BK            ((CsrWifiSmeWmmQosInfo) 0x04)
-#define CSR_WIFI_SME_WMM_QOS_INFO_AC_BE            ((CsrWifiSmeWmmQosInfo) 0x08)
-#define CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_TWO    ((CsrWifiSmeWmmQosInfo) 0x20)
-#define CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_FOUR   ((CsrWifiSmeWmmQosInfo) 0x40)
-#define CSR_WIFI_SME_WMM_QOS_INFO_AC_MAX_SP_SIX    ((CsrWifiSmeWmmQosInfo) 0x60)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsConfigType
-
-  DESCRIPTION
-    WPS config methods supported/used by a device
-
- VALUES
-    CSR_WIFI_WPS_CONFIG_LABEL
-                   - Label
-    CSR_WIFI_WPS_CONFIG_DISPLAY
-                   - Display
-    CSR_WIFI_WPS_CONFIG_EXT_NFC
-                   - External NFC : Not supported in this release
-    CSR_WIFI_WPS_CONFIG_INT_NFC
-                   - Internal NFC : Not supported in this release
-    CSR_WIFI_WPS_CONFIG_NFC_IFACE
-                   - NFC interface : Not supported in this release
-    CSR_WIFI_WPS_CONFIG_PBC
-                   - PBC
-    CSR_WIFI_WPS_CONFIG_KEYPAD
-                   - KeyPad
-    CSR_WIFI_WPS_CONFIG_VIRTUAL_PBC
-                   - PBC through software user interface
-    CSR_WIFI_WPS_CONFIG_PHYSICAL_PBC
-                   - Physical PBC
-    CSR_WIFI_WPS_CONFIG_VIRTUAL_DISPLAY
-                   - Virtual Display : via html config page etc
-    CSR_WIFI_WPS_CONFIG_PHYSICAL_DISPLAY
-                   - Physical Display : Attached to the device
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeWpsConfigType;
-#define CSR_WIFI_WPS_CONFIG_LABEL              ((CsrWifiSmeWpsConfigType) 0x0004)
-#define CSR_WIFI_WPS_CONFIG_DISPLAY            ((CsrWifiSmeWpsConfigType) 0x0008)
-#define CSR_WIFI_WPS_CONFIG_EXT_NFC            ((CsrWifiSmeWpsConfigType) 0x0010)
-#define CSR_WIFI_WPS_CONFIG_INT_NFC            ((CsrWifiSmeWpsConfigType) 0x0020)
-#define CSR_WIFI_WPS_CONFIG_NFC_IFACE          ((CsrWifiSmeWpsConfigType) 0x0040)
-#define CSR_WIFI_WPS_CONFIG_PBC                ((CsrWifiSmeWpsConfigType) 0x0080)
-#define CSR_WIFI_WPS_CONFIG_KEYPAD             ((CsrWifiSmeWpsConfigType) 0x0100)
-#define CSR_WIFI_WPS_CONFIG_VIRTUAL_PBC        ((CsrWifiSmeWpsConfigType) 0x0280)
-#define CSR_WIFI_WPS_CONFIG_PHYSICAL_PBC       ((CsrWifiSmeWpsConfigType) 0x0480)
-#define CSR_WIFI_WPS_CONFIG_VIRTUAL_DISPLAY    ((CsrWifiSmeWpsConfigType) 0x2008)
-#define CSR_WIFI_WPS_CONFIG_PHYSICAL_DISPLAY   ((CsrWifiSmeWpsConfigType) 0x4008)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsDeviceCategory
-
-  DESCRIPTION
-    Wps Primary Device Types
-
- VALUES
-    CSR_WIFI_SME_WPS_CATEGORY_UNSPECIFIED
-                   - Unspecified.
-    CSR_WIFI_SME_WPS_CATEGORY_COMPUTER
-                   - Computer.
-    CSR_WIFI_SME_WPS_CATEGORY_INPUT_DEV
-                   - Input device
-    CSR_WIFI_SME_WPS_CATEGORY_PRT_SCAN_FX_CP
-                   - Printer Scanner Fax Copier etc
-    CSR_WIFI_SME_WPS_CATEGORY_CAMERA
-                   - Camera
-    CSR_WIFI_SME_WPS_CATEGORY_STORAGE
-                   - Storage
-    CSR_WIFI_SME_WPS_CATEGORY_NET_INFRA
-                   - Net Infra
-    CSR_WIFI_SME_WPS_CATEGORY_DISPLAY
-                   - Display
-    CSR_WIFI_SME_WPS_CATEGORY_MULTIMEDIA
-                   - Multimedia
-    CSR_WIFI_SME_WPS_CATEGORY_GAMING
-                   - Gaming.
-    CSR_WIFI_SME_WPS_CATEGORY_TELEPHONE
-                   - Telephone.
-    CSR_WIFI_SME_WPS_CATEGORY_AUDIO
-                   - Audio
-    CSR_WIFI_SME_WPS_CATEOARY_OTHERS
-                   - Others.
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeWpsDeviceCategory;
-#define CSR_WIFI_SME_WPS_CATEGORY_UNSPECIFIED      ((CsrWifiSmeWpsDeviceCategory) 0x00)
-#define CSR_WIFI_SME_WPS_CATEGORY_COMPUTER         ((CsrWifiSmeWpsDeviceCategory) 0x01)
-#define CSR_WIFI_SME_WPS_CATEGORY_INPUT_DEV        ((CsrWifiSmeWpsDeviceCategory) 0x02)
-#define CSR_WIFI_SME_WPS_CATEGORY_PRT_SCAN_FX_CP   ((CsrWifiSmeWpsDeviceCategory) 0x03)
-#define CSR_WIFI_SME_WPS_CATEGORY_CAMERA           ((CsrWifiSmeWpsDeviceCategory) 0x04)
-#define CSR_WIFI_SME_WPS_CATEGORY_STORAGE          ((CsrWifiSmeWpsDeviceCategory) 0x05)
-#define CSR_WIFI_SME_WPS_CATEGORY_NET_INFRA        ((CsrWifiSmeWpsDeviceCategory) 0x06)
-#define CSR_WIFI_SME_WPS_CATEGORY_DISPLAY          ((CsrWifiSmeWpsDeviceCategory) 0x07)
-#define CSR_WIFI_SME_WPS_CATEGORY_MULTIMEDIA       ((CsrWifiSmeWpsDeviceCategory) 0x08)
-#define CSR_WIFI_SME_WPS_CATEGORY_GAMING           ((CsrWifiSmeWpsDeviceCategory) 0x09)
-#define CSR_WIFI_SME_WPS_CATEGORY_TELEPHONE        ((CsrWifiSmeWpsDeviceCategory) 0x0A)
-#define CSR_WIFI_SME_WPS_CATEGORY_AUDIO            ((CsrWifiSmeWpsDeviceCategory) 0x0B)
-#define CSR_WIFI_SME_WPS_CATEOARY_OTHERS           ((CsrWifiSmeWpsDeviceCategory) 0xFF)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsDeviceSubCategory
-
-  DESCRIPTION
-    Wps Secondary Device Types
-
- VALUES
-    CSR_WIFI_SME_WPS_SUB_CATEGORY_UNSPECIFIED
-                   - Unspecied
-    CSR_WIFI_SME_WPS_STORAGE_SUB_CATEGORY_NAS
-                   - Network Associated Storage
-    CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_PRNTR
-                   - Printer or print server
-    CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_WM
-                   - Windows mobile
-    CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_TUNER
-                   - Audio tuner/receiver
-    CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_DIG_STL
-                   - Digital still camera
-    CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_AP
-                   - Access Point
-    CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_TV
-                   - TV.
-    CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_DAR
-                   - DAR.
-    CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_KEYBD
-                   - Keyboard.
-    CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_PC
-                   - PC.
-    CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_XBOX
-                   - Xbox.
-    CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_SCNR
-                   - Scanner
-    CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_SERVER
-                   - Server
-    CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_ROUTER
-                   - Router
-    CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_PVR
-                   - PVR
-    CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_SPEAKER
-                   - Speaker
-    CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_FP_SM
-                   - Feature phone - Single mode
-    CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_VIDEO
-                   - Video camera
-    CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_PIC_FRM
-                   - Picture frame
-    CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_XBOX_360
-                   - Xbox360
-    CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_MOUSE
-                   - Mouse
-    CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_SWITCH
-                   - Switch
-    CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_PMP
-                   - Portable music player
-    CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_JOYSTK
-                   - Joy stick
-    CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_PLAY_STN
-                   - Play-station
-    CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_MED_CENT
-                   - Media Center
-    CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_MCX
-                   - MCX
-    CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_FP_DM
-                   - Feature phone - Dual mode
-    CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_WEB
-                   - Web camera
-    CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_FAX
-                   - Fax
-    CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_PROJECTOR
-                   - Projector
-    CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_TRKBL
-                   - Track Ball
-    CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_ST_BOX
-                   - Set-Top-Box
-    CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_GATEWAY
-                   - GateWay.
-    CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_SECURITY
-                   - Security camera
-    CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_ULTRA_MOB_PC
-                   - Ultra mobile PC.
-    CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_CONSOLE
-                   - Game console/Game console adapter
-    CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_CPR
-                   - Copier
-    CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_HEADSET
-                   - Headset(headphones + microphone)
-    CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_SP_SM
-                   - Smart phone - Single mode
-    CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_MONITOR
-                   - Monitor.
-    CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_GAME_CTRL
-                   - Game control.
-    CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_ALL
-                   - All-in-One
-    CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_MEDIA
-                   - Media Server/Media Adapter/Media Extender
-    CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_SP_DM
-                   - Smart phone - Dual mode
-    CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_PORT_DEV
-                   - Portable gaming device
-    CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_HEADPHONE
-                   - Headphone.
-    CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_NOTEBOOK
-                   - Notebook.
-    CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_REMOTE
-                   - Remote control
-    CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_MIC
-                   - Microphone
-    CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_DESKTOP
-                   - Desktop.
-    CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_VP
-                   - Portable video player
-    CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_MID
-                   - Mobile internet device
-    CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_TOUCH_SCRN
-                   - Touch screen
-    CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_BIOMET_RDR
-                   - Biometric reader
-    CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_NETBOOK
-                   - Netbook
-    CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_BRCD_RDR
-                   - Bar code reader.
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeWpsDeviceSubCategory;
-#define CSR_WIFI_SME_WPS_SUB_CATEGORY_UNSPECIFIED             ((CsrWifiSmeWpsDeviceSubCategory) 0x00)
-#define CSR_WIFI_SME_WPS_STORAGE_SUB_CATEGORY_NAS             ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_PRNTR              ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_WM            ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_TUNER             ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_DIG_STL          ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_AP            ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_TV              ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_DAR                  ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_KEYBD         ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_PC             ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_XBOX             ((CsrWifiSmeWpsDeviceSubCategory) 0x01)
-#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_SCNR               ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_SERVER         ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_ROUTER        ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_PVR                  ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_SPEAKER           ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_FP_SM         ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_VIDEO            ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_PIC_FRM         ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_XBOX_360         ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_MOUSE         ((CsrWifiSmeWpsDeviceSubCategory) 0x02)
-#define CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_SWITCH        ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_PMP               ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_JOYSTK        ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_PLAY_STN         ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_MED_CENT       ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_MCX                  ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_FP_DM         ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_WEB              ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_FAX                ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_PROJECTOR       ((CsrWifiSmeWpsDeviceSubCategory) 0x03)
-#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_TRKBL         ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_ST_BOX               ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_NET_INFRA_SUB_CATEGORY_GATEWAY       ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_CAMERA_SUB_CATEGORY_SECURITY         ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_ULTRA_MOB_PC   ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_CONSOLE          ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_CPR                ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_HEADSET           ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_SP_SM         ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_DISPLAY_SUB_CATEGORY_MONITOR         ((CsrWifiSmeWpsDeviceSubCategory) 0x04)
-#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_GAME_CTRL     ((CsrWifiSmeWpsDeviceSubCategory) 0x05)
-#define CSR_WIFI_SME_WPS_PSFC_SUB_CATEGORY_ALL                ((CsrWifiSmeWpsDeviceSubCategory) 0x05)
-#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_MEDIA                ((CsrWifiSmeWpsDeviceSubCategory) 0x05)
-#define CSR_WIFI_SME_WPS_TELEPHONE_SUB_CATEGORY_SP_DM         ((CsrWifiSmeWpsDeviceSubCategory) 0x05)
-#define CSR_WIFI_SME_WPS_GAMING_SUB_CATEGORY_PORT_DEV         ((CsrWifiSmeWpsDeviceSubCategory) 0x05)
-#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_HEADPHONE         ((CsrWifiSmeWpsDeviceSubCategory) 0x05)
-#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_NOTEBOOK       ((CsrWifiSmeWpsDeviceSubCategory) 0x05)
-#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_REMOTE        ((CsrWifiSmeWpsDeviceSubCategory) 0x06)
-#define CSR_WIFI_SME_WPS_AUDIO_SUB_CATEGORY_MIC               ((CsrWifiSmeWpsDeviceSubCategory) 0x06)
-#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_DESKTOP        ((CsrWifiSmeWpsDeviceSubCategory) 0x06)
-#define CSR_WIFI_SME_WPS_MM_SUB_CATEGORY_VP                   ((CsrWifiSmeWpsDeviceSubCategory) 0x06)
-#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_MID            ((CsrWifiSmeWpsDeviceSubCategory) 0x07)
-#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_TOUCH_SCRN    ((CsrWifiSmeWpsDeviceSubCategory) 0x07)
-#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_BIOMET_RDR    ((CsrWifiSmeWpsDeviceSubCategory) 0x08)
-#define CSR_WIFI_SME_WPS_COMPUTER_SUB_CATEGORY_NETBOOK        ((CsrWifiSmeWpsDeviceSubCategory) 0x08)
-#define CSR_WIFI_SME_WPS_INPUT_DEV_SUB_CATEGORY_BRCD_RDR      ((CsrWifiSmeWpsDeviceSubCategory) 0x09)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsDpid
-
-  DESCRIPTION
-    Device Password ID for the chosen config method
-
- VALUES
-    CSR_WIFI_SME_WPS_DPID_PIN       - PIN
-    CSR_WIFI_SME_WPS_DPID_USER      - User specified : Used only during P2P GO
-                                      negotiation procedure
-    CSR_WIFI_SME_WPS_DPID_MACHINE   - Machine specified i: Not used in this
-                                      release
-    CSR_WIFI_SME_WPS_DPID_REKEY     - Rekey : Not used in this release
-    CSR_WIFI_SME_WPS_DPID_PBC       - PBC
-    CSR_WIFI_SME_WPS_DPID_REGISTRAR - Registrar specified : Used only in P2P Go
-                                      negotiation procedure
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeWpsDpid;
-#define CSR_WIFI_SME_WPS_DPID_PIN         ((CsrWifiSmeWpsDpid) 0x0000)
-#define CSR_WIFI_SME_WPS_DPID_USER        ((CsrWifiSmeWpsDpid) 0x0001)
-#define CSR_WIFI_SME_WPS_DPID_MACHINE     ((CsrWifiSmeWpsDpid) 0x0002)
-#define CSR_WIFI_SME_WPS_DPID_REKEY       ((CsrWifiSmeWpsDpid) 0x0003)
-#define CSR_WIFI_SME_WPS_DPID_PBC         ((CsrWifiSmeWpsDpid) 0x0004)
-#define CSR_WIFI_SME_WPS_DPID_REGISTRAR   ((CsrWifiSmeWpsDpid) 0x0005)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsRegistration
-
-  DESCRIPTION
-
- VALUES
-    CSR_WIFI_SME_WPS_REG_NOT_REQUIRED - No encryption set
-    CSR_WIFI_SME_WPS_REG_REQUIRED     - No encryption set
-    CSR_WIFI_SME_WPS_REG_UNKNOWN      - No encryption set
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeWpsRegistration;
-#define CSR_WIFI_SME_WPS_REG_NOT_REQUIRED   ((CsrWifiSmeWpsRegistration) 0x00)
-#define CSR_WIFI_SME_WPS_REG_REQUIRED       ((CsrWifiSmeWpsRegistration) 0x01)
-#define CSR_WIFI_SME_WPS_REG_UNKNOWN        ((CsrWifiSmeWpsRegistration) 0x02)
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAuthModeMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeAuthMode
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeAuthModeMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeEncryptionMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeEncryption
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeEncryptionMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeIndicationsMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeIndications
-
-*******************************************************************************/
-typedef u32 CsrWifiSmeIndicationsMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pCapabilityMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeP2pCapability
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeP2pCapabilityMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pGroupCapabilityMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeP2pGroupCapability
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeP2pGroupCapabilityMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTspecCtrlMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeTspecCtrl
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeTspecCtrlMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWmmModeMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeWmmMode
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeWmmModeMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWmmQosInfoMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeWmmQosInfo
-
-*******************************************************************************/
-typedef u8 CsrWifiSmeWmmQosInfoMask;
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsConfigTypeMask
-
-  DESCRIPTION
-    Mask type for use with the values defined by CsrWifiSmeWpsConfigType
-
-*******************************************************************************/
-typedef u16 CsrWifiSmeWpsConfigTypeMask;
-
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAdHocConfig
-
-  DESCRIPTION
-    Defines values to use when starting an Ad-hoc (IBSS) network.
-
-  MEMBERS
-    atimWindowTu          - ATIM window specified for IBSS
-    beaconPeriodTu        - Interval between beacon packets
-    joinOnlyAttempts      - Maximum number of attempts to join an ad-hoc network.
-                            The default value is 1.
-                            Set to 0 for infinite attempts.
-    joinAttemptIntervalMs - Time between scans for joining the requested IBSS.
-
-*******************************************************************************/
-typedef struct
-{
-    u16 atimWindowTu;
-    u16 beaconPeriodTu;
-    u16 joinOnlyAttempts;
-    u16 joinAttemptIntervalMs;
-} CsrWifiSmeAdHocConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAvailabilityConfig
-
-  DESCRIPTION
-
-  MEMBERS
-    listenChannel        -
-    availabilityDuration -
-    avalabilityPeriod    -
-
-*******************************************************************************/
-typedef struct
-{
-    u8  listenChannel;
-    u16 availabilityDuration;
-    u16 avalabilityPeriod;
-} CsrWifiSmeAvailabilityConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCcxConfig
-
-  DESCRIPTION
-    This type is reserved for future use and should not be used.
-
-  MEMBERS
-    keepAliveTimeMs    - NOT USED
-    apRoamingEnabled   - NOT USED
-    measurementsMask   - NOT USED
-    ccxRadioMgtEnabled - NOT USED
-
-*******************************************************************************/
-typedef struct
-{
-    u8 keepAliveTimeMs;
-    u8  apRoamingEnabled;
-    u8 measurementsMask;
-    u8  ccxRadioMgtEnabled;
-} CsrWifiSmeCcxConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexConfig
-
-  DESCRIPTION
-    Parameters for the coexistence behaviour.
-
-  MEMBERS
-    coexEnableSchemeManagement     - Enables the Coexistence Management Scheme
-    coexPeriodicWakeHost           - If TRUE the firmware wakes up the host
-                                     periodically according to the traffic
-                                     period and latency parameters; the host
-                                     will then send the data to transmit only
-                                     when woken up.
-                                     If FALSE, the firmware does not wake up the
-                                     host and the host will send the data to
-                                     transmit to the firmware whenever there is
-                                     data to transmit
-    coexTrafficBurstyLatencyMs     - Period of awakening for the firmware used
-                                     when bursty traffic is detected
-    coexTrafficContinuousLatencyMs - Period of awakening for the firmware used
-                                     when continuous traffic is detected
-    coexObexBlackoutDurationMs     - Blackout Duration when a Obex Connection is
-                                     used
-    coexObexBlackoutPeriodMs       - Blackout Period when a Obex Connection is
-                                     used
-    coexA2dpBrBlackoutDurationMs   - Blackout Duration when a Basic Rate A2DP
-                                     Connection streaming data
-    coexA2dpBrBlackoutPeriodMs     - Blackout Period when a Basic Rate A2DP
-                                     Connection streaming data
-    coexA2dpEdrBlackoutDurationMs  - Blackout Duration when an Enhanced Data
-                                     Rate A2DP Connection streaming data
-    coexA2dpEdrBlackoutPeriodMs    - Blackout Period when an Enhanced Data Rate
-                                     A2DP Connection streaming data
-    coexPagingBlackoutDurationMs   - Blackout Duration when a BT page is active
-    coexPagingBlackoutPeriodMs     - Blackout Period when a BT page is active
-    coexInquiryBlackoutDurationMs  - Blackout Duration when a BT inquiry is
-                                     active
-    coexInquiryBlackoutPeriodMs    - Blackout Period when a BT inquiry is active
-
-*******************************************************************************/
-typedef struct
-{
-    u8   coexEnableSchemeManagement;
-    u8   coexPeriodicWakeHost;
-    u16 coexTrafficBurstyLatencyMs;
-    u16 coexTrafficContinuousLatencyMs;
-    u16 coexObexBlackoutDurationMs;
-    u16 coexObexBlackoutPeriodMs;
-    u16 coexA2dpBrBlackoutDurationMs;
-    u16 coexA2dpBrBlackoutPeriodMs;
-    u16 coexA2dpEdrBlackoutDurationMs;
-    u16 coexA2dpEdrBlackoutPeriodMs;
-    u16 coexPagingBlackoutDurationMs;
-    u16 coexPagingBlackoutPeriodMs;
-    u16 coexInquiryBlackoutDurationMs;
-    u16 coexInquiryBlackoutPeriodMs;
-} CsrWifiSmeCoexConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionStats
-
-  DESCRIPTION
-    Indicates the statistics of the connection.
-    The dot11 fields are defined in the Annex D of the IEEE 802.11 standard.
-
-  MEMBERS
-    unifiTxDataRate
-                   - The bit rate currently in use for transmissions of unicast
-                     data frames; a data rate in units of 500kbit/s.
-                     On an infrastructure BSS, this is the data rate used in
-                     communicating with the associated access point; if there is
-                     none, an error is returned.
-                     On an IBSS, this is the data rate used for the last
-                     transmission of a unicast data frame to any station in the
-                     IBSS. If no such transmission has been made, an error is
-                     returned.
-    unifiRxDataRate
-                   - As above for receiving data
-    dot11RetryCount
-                   - See IEEE 802.11 Standard
-    dot11MultipleRetryCount
-                   - See IEEE 802.11 Standard
-    dot11AckFailureCount
-                   - See IEEE 802.11 Standard
-    dot11FrameDuplicateCount
-                   - See IEEE 802.11 Standard
-    dot11FcsErrorCount
-                   - See IEEE 802.11 Standard
-    dot11RtsSuccessCount
-                   - See IEEE 802.11 Standard
-    dot11RtsFailureCount
-                   - See IEEE 802.11 Standard
-    dot11FailedCount
-                   - See IEEE 802.11 Standard
-    dot11TransmittedFragmentCount
-                   - See IEEE 802.11 Standard
-    dot11TransmittedFrameCount
-                   - See IEEE 802.11 Standard
-    dot11WepExcludedCount
-                   - See IEEE 802.11 Standard
-    dot11WepIcvErrorCount
-                   - See IEEE 802.11 Standard
-    dot11WepUndecryptableCount
-                   - See IEEE 802.11 Standard
-    dot11MulticastReceivedFrameCount
-                   - See IEEE 802.11 Standard
-    dot11MulticastTransmittedFrameCount
-                   - See IEEE 802.11 Standard
-    dot11ReceivedFragmentCount
-                   - See IEEE 802.11 Standard
-    dot11Rsna4WayHandshakeFailures
-                   - See IEEE 802.11 Standard
-    dot11RsnaTkipCounterMeasuresInvoked
-                   - See IEEE 802.11 Standard
-    dot11RsnaStatsTkipLocalMicFailures
-                   - See IEEE 802.11 Standard
-    dot11RsnaStatsTkipReplays
-                   - See IEEE 802.11 Standard
-    dot11RsnaStatsTkipIcvErrors
-                   - See IEEE 802.11 Standard
-    dot11RsnaStatsCcmpReplays
-                   - See IEEE 802.11 Standard
-    dot11RsnaStatsCcmpDecryptErrors
-                   - See IEEE 802.11 Standard
-
-*******************************************************************************/
-typedef struct
-{
-    u8  unifiTxDataRate;
-    u8  unifiRxDataRate;
-    u32 dot11RetryCount;
-    u32 dot11MultipleRetryCount;
-    u32 dot11AckFailureCount;
-    u32 dot11FrameDuplicateCount;
-    u32 dot11FcsErrorCount;
-    u32 dot11RtsSuccessCount;
-    u32 dot11RtsFailureCount;
-    u32 dot11FailedCount;
-    u32 dot11TransmittedFragmentCount;
-    u32 dot11TransmittedFrameCount;
-    u32 dot11WepExcludedCount;
-    u32 dot11WepIcvErrorCount;
-    u32 dot11WepUndecryptableCount;
-    u32 dot11MulticastReceivedFrameCount;
-    u32 dot11MulticastTransmittedFrameCount;
-    u32 dot11ReceivedFragmentCount;
-    u32 dot11Rsna4WayHandshakeFailures;
-    u32 dot11RsnaTkipCounterMeasuresInvoked;
-    u32 dot11RsnaStatsTkipLocalMicFailures;
-    u32 dot11RsnaStatsTkipReplays;
-    u32 dot11RsnaStatsTkipIcvErrors;
-    u32 dot11RsnaStatsCcmpReplays;
-    u32 dot11RsnaStatsCcmpDecryptErrors;
-} CsrWifiSmeConnectionStats;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDataBlock
-
-  DESCRIPTION
-    Holds a generic data block to be passed through the interface
-
-  MEMBERS
-    length - Length of the data block
-    data   - Points to the first byte of the data block
-
-*******************************************************************************/
-typedef struct
-{
-    u16 length;
-    u8 *data;
-} CsrWifiSmeDataBlock;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeEmpty
-
-  DESCRIPTION
-    Empty Structure to indicate that no parameters are available.
-
-  MEMBERS
-    empty  - Only element of the empty structure (always set to 0).
-
-*******************************************************************************/
-typedef struct
-{
-    u8 empty;
-} CsrWifiSmeEmpty;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeLinkQuality
-
-  DESCRIPTION
-    Indicates the quality of the link
-
-  MEMBERS
-    unifiRssi - Indicates the received signal strength indication of the link in
-                dBm
-    unifiSnr  - Indicates the signal to noise ratio of the link in dB
-
-*******************************************************************************/
-typedef struct
-{
-    s16 unifiRssi;
-    s16 unifiSnr;
-} CsrWifiSmeLinkQuality;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibConfig
-
-  DESCRIPTION
-    Allows low level configuration in the chip.
-
-  MEMBERS
-    unifiFixMaxTxDataRate       - This attribute is used in combination with
-                                  unifiFixTxDataRate. If it is FALSE, then
-                                  unifiFixTxDataRate specifies a specific data
-                                  rate to use. If it is TRUE, unifiFixTxDataRate
-                                  instead specifies a maximum data rate.
-    unifiFixTxDataRate          - Transmit rate for unicast data.
-                                  See MIB description for more details
-    dot11RtsThreshold           - See IEEE 802.11 Standard
-    dot11FragmentationThreshold - See IEEE 802.11 Standard
-    dot11CurrentTxPowerLevel    - See IEEE 802.11 Standard
-
-*******************************************************************************/
-typedef struct
-{
-    u8   unifiFixMaxTxDataRate;
-    u8  unifiFixTxDataRate;
-    u16 dot11RtsThreshold;
-    u16 dot11FragmentationThreshold;
-    u16 dot11CurrentTxPowerLevel;
-} CsrWifiSmeMibConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pProfileIdentity
-
-  DESCRIPTION
-    Details to be filled in
-
-  MEMBERS
-    listenChannel        -
-    availabilityDuration -
-    avalabilityPeriod    -
-
-*******************************************************************************/
-typedef struct
-{
-    u8  listenChannel;
-    u16 availabilityDuration;
-    u16 avalabilityPeriod;
-} CsrWifiSmeP2pProfileIdentity;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePmkid
-
-  DESCRIPTION
-    Defines a PMKID association with BSS
-
-  MEMBERS
-    bssid  - BSS identifier
-    pmkid  - PMKID
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiMacAddress bssid;
-    u8          pmkid[16];
-} CsrWifiSmePmkid;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePmkidCandidate
-
-  DESCRIPTION
-    Information for a PMKID candidate
-
-  MEMBERS
-    bssid          - BSS identifier
-    preAuthAllowed - Indicates whether preauthentication is allowed
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiMacAddress bssid;
-    u8           preAuthAllowed;
-} CsrWifiSmePmkidCandidate;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePmkidList
-
-  DESCRIPTION
-    NOT USED
-    Used in the Sync access API
-
-  MEMBERS
-    pmkidsCount - Number of PMKIDs in the list
-    pmkids      - Points to the first PMKID in the list
-
-*******************************************************************************/
-typedef struct
-{
-    u8         pmkidsCount;
-    CsrWifiSmePmkid *pmkids;
-} CsrWifiSmePmkidList;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRegulatoryDomainInfo
-
-  DESCRIPTION
-    Regulatory domain options.
-
-  MEMBERS
-    dot11MultiDomainCapabilityImplemented
-                   - TRUE is the multi domain capability is implemented
-    dot11MultiDomainCapabilityEnabled
-                   - TRUE is the multi domain capability is enabled
-    currentRegulatoryDomain
-                   - Current regulatory domain
-    currentCountryCode
-                   - Current country code as defined by the IEEE 802.11
-                     standards
-
-*******************************************************************************/
-typedef struct
-{
-    u8                    dot11MultiDomainCapabilityImplemented;
-    u8                    dot11MultiDomainCapabilityEnabled;
-    CsrWifiSmeRegulatoryDomain currentRegulatoryDomain;
-    u8                   currentCountryCode[2];
-} CsrWifiSmeRegulatoryDomainInfo;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingBandData
-
-  DESCRIPTION
-    Thresholds to define one usability level category for the received signal
-
-  MEMBERS
-    rssiHighThreshold - Received Signal Strength Indication upper bound in dBm
-                        for the usability level
-    rssiLowThreshold  - Received Signal Strength Indication lower bound in dBm
-                        for the usability level
-    snrHighThreshold  - Signal to Noise Ratio upper bound in dB for the
-                        usability level
-    snrLowThreshold   - Signal to Noise Ratio lower bound in dB for the
-                        usability level
-
-*******************************************************************************/
-typedef struct
-{
-    s16 rssiHighThreshold;
-    s16 rssiLowThreshold;
-    s16 snrHighThreshold;
-    s16 snrLowThreshold;
-} CsrWifiSmeRoamingBandData;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfigData
-
-  DESCRIPTION
-    Configures the scanning behaviour of the driver and firmware
-
-  MEMBERS
-    intervalSeconds         - All the channels will be scanned once in this time
-                              interval.
-                              If connected, the channel scans are spread across
-                              the interval.
-                              If disconnected, all the channels will be scanned
-                              together
-    validitySeconds         - How long the scan result are cached
-    minActiveChannelTimeTu  - Minimum time of listening on a channel being
-                              actively scanned before leaving if no probe
-                              responses or beacon frames have been received
-    maxActiveChannelTimeTu  - Maximum time of listening on a channel being
-                              actively scanned
-    minPassiveChannelTimeTu - Minimum time of listening on a channel being
-                              passive scanned before leaving if no beacon frames
-                              have been received
-    maxPassiveChannelTimeTu - Maximum time of listening on a channel being
-                              passively scanned
-
-*******************************************************************************/
-typedef struct
-{
-    u16 intervalSeconds;
-    u16 validitySeconds;
-    u16 minActiveChannelTimeTu;
-    u16 maxActiveChannelTimeTu;
-    u16 minPassiveChannelTimeTu;
-    u16 maxPassiveChannelTimeTu;
-} CsrWifiSmeScanConfigData;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTsfTime
-
-  DESCRIPTION
-    Time stamp representation
-
-  MEMBERS
-    data   - TSF Bytes
-
-*******************************************************************************/
-typedef struct
-{
-    u8 data[8];
-} CsrWifiSmeTsfTime;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeVersions
-
-  DESCRIPTION
-    Reports version information for the chip, the firmware and the driver and
-    the SME.
-
-  MEMBERS
-    chipId        - Chip ID
-    chipVersion   - Chip version ID
-    firmwareBuild - Firmware Rom build number
-    firmwarePatch - Firmware Patch build number (if applicable)
-    firmwareHip   - Firmware HIP protocol version number
-    routerBuild   - Router build number
-    routerHip     - Router HIP protocol version number
-    smeBuild      - SME build number
-    smeHip        - SME HIP protocol version number
-
-*******************************************************************************/
-typedef struct
-{
-    u32      chipId;
-    u32      chipVersion;
-    u32      firmwareBuild;
-    u32      firmwarePatch;
-    u32      firmwareHip;
-    char *routerBuild;
-    u32      routerHip;
-    char *smeBuild;
-    u32      smeHip;
-} CsrWifiSmeVersions;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWmmAcParams
-
-  DESCRIPTION
-    Structure holding WMM AC params data.
-
-  MEMBERS
-    cwMin                     - Exponent for the calculation of CWmin. Range: 0
-                                to 15
-    cwMax                     - Exponent for the calculation of CWmax. Range: 0
-                                to15
-    aifs                      - Arbitration Inter Frame Spacing in terms of
-                                number of timeslots. Range 2 to 15
-    txopLimit                 - TXOP Limit in the units of 32 microseconds
-    admissionControlMandatory - Indicates whether the admission control is
-                                mandatory or not. Current release does not
-                                support admission control , hence shall be set
-                                to FALSE.
-
-*******************************************************************************/
-typedef struct
-{
-    u8  cwMin;
-    u8  cwMax;
-    u8  aifs;
-    u16 txopLimit;
-    u8   admissionControlMandatory;
-} CsrWifiSmeWmmAcParams;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsDeviceType
-
-  DESCRIPTION
-    Structure holding AP WPS device type data.
-
-  MEMBERS
-    deviceDetails - category , sub category etc
-
-*******************************************************************************/
-typedef struct
-{
-    u8 deviceDetails[8];
-} CsrWifiSmeWpsDeviceType;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsDeviceTypeCommon
-
-  DESCRIPTION
-
-  MEMBERS
-    spportWps  -
-    deviceType -
-
-*******************************************************************************/
-typedef struct
-{
-    u8  spportWps;
-    u8 deviceType;
-} CsrWifiSmeWpsDeviceTypeCommon;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsInfo
-
-  DESCRIPTION
-
-  MEMBERS
-    version         -
-    configMethods   -
-    devicePassworId -
-
-*******************************************************************************/
-typedef struct
-{
-    u16 version;
-    u16 configMethods;
-    u16 devicePassworId;
-} CsrWifiSmeWpsInfo;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCloakedSsidConfig
-
-  DESCRIPTION
-    List of cloaked SSIDs .
-
-  MEMBERS
-    cloakedSsidsCount - Number of cloaked SSID
-    cloakedSsids      - Points to the first byte of the first SSID provided
-
-*******************************************************************************/
-typedef struct
-{
-    u8     cloakedSsidsCount;
-    CsrWifiSsid *cloakedSsids;
-} CsrWifiSmeCloakedSsidConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexInfo
-
-  DESCRIPTION
-    Information and state related to coexistence.
-
-  MEMBERS
-    hasTrafficData            - TRUE if any Wi-Fi traffic is detected
-    currentTrafficType        - Current type of traffic
-    currentPeriodMs           - Period of the traffic as detected by the traffic
-                                analysis.
-                                If the traffic is not periodic, it is set to 0.
-    currentPowerSave          - Current power save level
-    currentCoexPeriodMs       - Period of awakening for the firmware used when
-                                periodic traffic is detected.
-                                If the traffic is not periodic, it is set to 0.
-    currentCoexLatencyMs      - Period of awakening for the firmware used when
-                                non-periodic traffic is detected
-    hasBtDevice               - TRUE if there is a Bluetooth device connected
-    currentBlackoutDurationUs - Current blackout duration for protecting
-                                Bluetooth
-    currentBlackoutPeriodUs   - Current blackout period
-    currentCoexScheme         - Defines the scheme for the coexistence
-                                signalling
-
-*******************************************************************************/
-typedef struct
-{
-    u8                  hasTrafficData;
-    CsrWifiSmeTrafficType    currentTrafficType;
-    u16                currentPeriodMs;
-    CsrWifiSmePowerSaveLevel currentPowerSave;
-    u16                currentCoexPeriodMs;
-    u16                currentCoexLatencyMs;
-    u8                  hasBtDevice;
-    u32                currentBlackoutDurationUs;
-    u32                currentBlackoutPeriodUs;
-    CsrWifiSmeCoexScheme     currentCoexScheme;
-} CsrWifiSmeCoexInfo;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionConfig
-
-  DESCRIPTION
-    Specifies the parameters that the SME should use in selecting a network.
-
-  MEMBERS
-    ssid
-                   - Service Set identifier
-    bssid
-                   - BSS identifier
-    bssType
-                   - Indicates the type of BSS
-    ifIndex
-                   - Indicates the radio interface
-    privacyMode
-                   - Specifies whether the privacy mode is enabled or disabled.
-    authModeMask
-                   - Sets the authentication options that the SME can use while
-                     associating to the AP
-                     Set mask with values from CsrWifiSmeAuthMode
-    encryptionModeMask
-                   - Sets the encryption options that the SME can use while
-                     associating to the AP
-                     Set mask with values from CsrWifiSmeEncryption
-    mlmeAssociateReqInformationElementsLength
-                   - Length in bytes of information elements to be sent in the
-                     Association Request.
-    mlmeAssociateReqInformationElements
-                   - Points to the first byte of the information elements, if
-                     any.
-    wmmQosInfo
-                   - This parameter allows the driver's WMM behaviour to be
-                     configured.
-                     To enable support for WMM, use
-                     CSR_WIFI_SME_SME_CONFIG_SET_REQ with the
-                     CSR_WIFI_SME_WMM_MODE_AC_ENABLED bit set in wmmModeMask
-                     field in smeConfig parameter.
-                     Set mask with values from CsrWifiSmeWmmQosInfo
-    adhocJoinOnly
-                   - This parameter is relevant only if bssType is NOT set to
-                     CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE:
-                     if TRUE the SME will only try to join an ad-hoc network if
-                     there is one already established;
-                     if FALSE the SME will try to join an ad-hoc network if
-                     there is one already established or it will try to
-                     establish a new one
-    adhocChannel
-                   - This parameter is relevant only if bssType is NOT set to
-                     CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE:
-                     it indicates the channel to use joining an ad hoc network.
-                     Setting this to 0 causes the SME to select a channel from
-                     those permitted in the regulatory domain.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSsid                ssid;
-    CsrWifiMacAddress          bssid;
-    CsrWifiSmeBssType          bssType;
-    CsrWifiSmeRadioIF          ifIndex;
-    CsrWifiSme80211PrivacyMode privacyMode;
-    CsrWifiSmeAuthModeMask     authModeMask;
-    CsrWifiSmeEncryptionMask   encryptionModeMask;
-    u16                  mlmeAssociateReqInformationElementsLength;
-    u8                  *mlmeAssociateReqInformationElements;
-    CsrWifiSmeWmmQosInfoMask   wmmQosInfo;
-    u8                    adhocJoinOnly;
-    u8                   adhocChannel;
-} CsrWifiSmeConnectionConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionInfo
-
-  DESCRIPTION
-    Parameters that the SME should use in selecting a network
-
-  MEMBERS
-    ssid                        - Service set identifier
-    bssid                       - BSS identifier
-    networkType80211            - Physical layer used for the connection
-    channelNumber               - Channel number
-    channelFrequency            - Channel frequency
-    authMode                    - Authentication mode used for the connection
-    pairwiseCipher              - Encryption type for peer to peer communication
-    groupCipher                 - Encryption type for broadcast and multicast
-                                  communication
-    ifIndex                     - Indicates the radio interface
-    atimWindowTu                - ATIM window specified for IBSS
-    beaconPeriodTu              - Interval between beacon packets
-    reassociation               - Indicates whether a reassociation occurred
-    beaconFrameLength           - Indicates the number of bytes of the beacon
-                                  frame
-    beaconFrame                 - Points at the first byte of the beacon frame
-    associationReqFrameLength   - Indicates the number of bytes of the
-                                  association request frame
-    associationReqFrame         - Points at the first byte of the association
-                                  request frame
-    associationRspFrameLength   - Indicates the number of bytes of the
-                                  association response frame
-    associationRspFrame         - Points at the first byte of the association
-                                  response frame
-    assocScanInfoElementsLength - Indicates the number of bytes in the buffer
-                                  pointed by assocScanInfoElements
-    assocScanInfoElements       - Pointer to the buffer containing the
-                                  information elements of the probe response
-                                  received after the probe requests sent before
-                                  attempting to authenticate to the network
-    assocReqCapabilities        - Reports the content of the Capability
-                                  information element as specified in the
-                                  association request.
-    assocReqListenIntervalTu    - Listen Interval specified in the association
-                                  request
-    assocReqApAddress           - AP address to which the association requests
-                                  has been sent
-    assocReqInfoElementsLength  - Indicates the number of bytes of the
-                                  association request information elements
-    assocReqInfoElements        - Points at the first byte of the association
-                                  request information elements
-    assocRspResult              - Result reported in the association response
-    assocRspCapabilityInfo      - Reports the content of the Capability
-                                  information element as received in the
-                                  association response.
-    assocRspAssociationId       - Reports the association ID received in the
-                                  association response.
-    assocRspInfoElementsLength  - Indicates the number of bytes of the
-                                  association response information elements
-    assocRspInfoElements        - Points at the first byte of the association
-                                  response information elements
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSsid                ssid;
-    CsrWifiMacAddress          bssid;
-    CsrWifiSme80211NetworkType networkType80211;
-    u8                   channelNumber;
-    u16                  channelFrequency;
-    CsrWifiSmeAuthMode         authMode;
-    CsrWifiSmeEncryption       pairwiseCipher;
-    CsrWifiSmeEncryption       groupCipher;
-    CsrWifiSmeRadioIF          ifIndex;
-    u16                  atimWindowTu;
-    u16                  beaconPeriodTu;
-    u8                    reassociation;
-    u16                  beaconFrameLength;
-    u8                  *beaconFrame;
-    u16                  associationReqFrameLength;
-    u8                  *associationReqFrame;
-    u16                  associationRspFrameLength;
-    u8                  *associationRspFrame;
-    u16                  assocScanInfoElementsLength;
-    u8                  *assocScanInfoElements;
-    u16                  assocReqCapabilities;
-    u16                  assocReqListenIntervalTu;
-    CsrWifiMacAddress          assocReqApAddress;
-    u16                  assocReqInfoElementsLength;
-    u8                  *assocReqInfoElements;
-    CsrWifiSmeIEEE80211Result  assocRspResult;
-    u16                  assocRspCapabilityInfo;
-    u16                  assocRspAssociationId;
-    u16                  assocRspInfoElementsLength;
-    u8                  *assocRspInfoElements;
-} CsrWifiSmeConnectionInfo;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDeviceConfig
-
-  DESCRIPTION
-    General configuration options in the SME
-
-  MEMBERS
-    trustLevel              - Level of trust of the information coming from the
-                              network
-    countryCode             - Country code as specified by IEEE 802.11 standard
-    firmwareDriverInterface - Specifies the type of communication between Host
-                              and Firmware
-    enableStrictDraftN      - If TRUE TKIP is disallowed when connecting to
-                              802.11n enabled access points
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSme80211dTrustLevel        trustLevel;
-    u8                          countryCode[2];
-    CsrWifiSmeFirmwareDriverInterface firmwareDriverInterface;
-    u8                           enableStrictDraftN;
-} CsrWifiSmeDeviceConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDeviceInfo
-
-  DESCRIPTION
-    P2P Information for a P2P Device
-
-  MEMBERS
-    deviceAddress            - Device Address of the P2P device
-    configMethods            - Supported WPS configuration methods.
-    p2PDeviceCap             - P2P device capabilities
-    primDeviceType           - Primary WPS device type
-    secondaryDeviceTypeCount - Number of secondary device types
-    secDeviceType            - list of secondary WPS device types
-    deviceName               - Device name without up to 32 characters'\0'.
-    deviceNameLength         - Number of characters of the device name
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiMacAddress           deviceAddress;
-    CsrWifiSmeWpsConfigTypeMask configMethods;
-    CsrWifiSmeP2pCapabilityMask p2PDeviceCap;
-    CsrWifiSmeWpsDeviceType     primDeviceType;
-    u8                    secondaryDeviceTypeCount;
-    CsrWifiSmeWpsDeviceType    *secDeviceType;
-    u8                    deviceName[32];
-    u8                    deviceNameLength;
-} CsrWifiSmeDeviceInfo;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDeviceInfoCommon
-
-  DESCRIPTION
-    Structure holding device information.
-
-  MEMBERS
-    p2pDeviceAddress          -
-    primaryDeviceType         -
-    secondaryDeviceTypesCount -
-    secondaryDeviceTypes      -
-    deviceNameLength          -
-    deviceName                -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiMacAddress             p2pDeviceAddress;
-    CsrWifiSmeWpsDeviceTypeCommon primaryDeviceType;
-    u8                      secondaryDeviceTypesCount;
-    u8                      secondaryDeviceTypes[10];
-    u8                      deviceNameLength;
-    u8                      deviceName[32];
-} CsrWifiSmeDeviceInfoCommon;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostConfig
-
-  DESCRIPTION
-    Defines the host power state (for example, on mains power, on battery
-    power etc) and the periodicity of the traffic data.
-
-  MEMBERS
-    powerMode               - The wireless manager application should use the
-                              powerMode parameter to inform the SME of the host
-                              power state.
-    applicationDataPeriodMs - The applicationDataPeriodMs parameter allows a
-                              wireless manager application to inform the SME
-                              that an application is running that generates
-                              periodic network traffic and the period of the
-                              traffic.
-                              An example of such an application is a VoIP client.
-                              The wireless manager application should set
-                              applicationDataPeriodMs to the period in
-                              milliseconds between data packets or zero if no
-                              periodic application is running.
-                              Voip etc 0 = No Periodic Data
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeHostPowerMode powerMode;
-    u16               applicationDataPeriodMs;
-} CsrWifiSmeHostConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeKey
-
-  DESCRIPTION
-    Information for a key to be used for encryption
-
-  MEMBERS
-    keyType       - Specifies whether the key is a pairwise or group key; it
-                    should be set to CSR_WIFI_SME_GROUP_KEY or
-                    CSR_WIFI_SME_PAIRWISE_KEY, as required.
-    keyIndex      - Specifies which WEP key (0-3) to set; it should be set to 0
-                    for a WPA/WPA2 pairwise key and non-zero for a WPA/WPA2
-                    group key.
-    wepTxKey      - If wepTxKey is TRUE, and the key is a WEP key, the key will
-                    be selected for encrypting transmitted packets.
-                    To select a previously defined key as the transmit
-                    encryption key, set keyIndex to the required key, wepTxKey
-                    to TRUE and the keyLength to 0.
-    keyRsc        - Key Receive Sequence Counter
-    authenticator - If TRUE the WMA will act as authenticator.
-                    CURRENTLY NOT SUPPORTED
-    address       - BSS identifier of the AP
-    keyLength     - Length of the key in bytes
-    key           - Points to the first byte of the key
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeKeyType keyType;
-    u8          keyIndex;
-    u8           wepTxKey;
-    u16         keyRsc[8];
-    u8           authenticator;
-    CsrWifiMacAddress address;
-    u8          keyLength;
-    u8          key[32];
-} CsrWifiSmeKey;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pClientInfoType
-
-  DESCRIPTION
-    P2P Information for a P2P Client
-
-  MEMBERS
-    p2PClientInterfaceAddress - MAC address of the P2P Client
-    clientDeviceInfo          - Device Information
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiMacAddress    p2PClientInterfaceAddress;
-    CsrWifiSmeDeviceInfo clientDeviceInfo;
-} CsrWifiSmeP2pClientInfoType;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeP2pGroupInfo
-
-  DESCRIPTION
-    P2P Information for a P2P Group
-
-  MEMBERS
-    groupCapability    - P2P group capabilities
-    p2pDeviceAddress   - Device Address of the GO
-    p2pClientInfoCount - Number of P2P Clients that belong to the group.
-    p2PClientInfo      - Pointer to the list containing client information for
-                         each client in the group
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeP2pGroupCapabilityMask groupCapability;
-    CsrWifiMacAddress                p2pDeviceAddress;
-    u8                         p2pClientInfoCount;
-    CsrWifiSmeP2pClientInfoType     *p2PClientInfo;
-} CsrWifiSmeP2pGroupInfo;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerConfig
-
-  DESCRIPTION
-    Configures the power-save behaviour of the driver and firmware.
-
-  MEMBERS
-    powerSaveLevel         - Power Save Level option
-    listenIntervalTu       - Interval for waking to receive beacon frames
-    rxDtims                - If TRUE, wake for DTIM every beacon period, to
-                             allow the reception broadcast packets
-    d3AutoScanMode         - Defines whether the autonomous scanning will be
-                             turned off or will stay on during a D3 suspended
-                             period
-    clientTrafficWindow    - Deprecated
-    opportunisticPowerSave - Deprecated
-    noticeOfAbsence        - Deprecated
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmePowerSaveLevel powerSaveLevel;
-    u16                listenIntervalTu;
-    u8                  rxDtims;
-    CsrWifiSmeD3AutoScanMode d3AutoScanMode;
-    u8                 clientTrafficWindow;
-    u8                  opportunisticPowerSave;
-    u8                  noticeOfAbsence;
-} CsrWifiSmePowerConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingConfig
-
-  DESCRIPTION
-    Configures the roaming behaviour of the driver and firmware
-
-  MEMBERS
-    roamingBands             - Defines the thresholds to determine the usability
-                               level of the current connection.
-                               roamingBands is indexed by the first 3 entries of
-                               the CsrWifiSmeBasicUsability enum
-    disableSmoothRoaming     - Disable the RSSI/SNR triggers from the Firmware
-                               that the SME uses to detect the quality of the
-                               connection.
-                               This implicitly disables disableRoamScans
-    disableRoamScans         - Disables the scanning for the roaming operation
-    reconnectLimit           - Maximum number of times SME may reconnect in the
-                               given interval
-    reconnectLimitIntervalMs - Interval for maximum number of times SME may
-                               reconnect to the same Access Point
-    roamScanCfg              - Scanning behaviour for the specifically aimed at
-                               improving roaming performance.
-                               roamScanCfg is indexed by the first 3 entries of
-                               the CsrWifiSmeBasicUsability enum
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeRoamingBandData roamingBands[3];
-    u8                   disableSmoothRoaming;
-    u8                   disableRoamScans;
-    u8                  reconnectLimit;
-    u16                 reconnectLimitIntervalMs;
-    CsrWifiSmeScanConfigData  roamScanCfg[3];
-} CsrWifiSmeRoamingConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfig
-
-  DESCRIPTION
-    Parameters for the autonomous scanning behaviour of the system
-
-  MEMBERS
-    scanCfg                 - Scan configuration data.
-                              Indexed by the CsrWifiSmeBasicUsability enum
-    disableAutonomousScans  - Enables or disables the autonomous scan
-    maxResults              - Maximum number of results to be cached in the SME
-    highRssiThreshold       - High received signal strength indication threshold
-                              in dBm for an AP above which the system will
-                              report scan indications
-    lowRssiThreshold        - Low received signal strength indication threshold
-                              in dBm for an AP below which the system will
-                              report scan indications
-    deltaRssiThreshold      - Minimum difference for received signal strength
-                              indication in dBm for an AP which trigger a scan
-                              indication to be sent.
-    highSnrThreshold        - High Signal to Noise Ratio threshold in dB for an
-                              AP above which the system will report scan
-                              indications
-    lowSnrThreshold         - Low Signal to Noise Ratio threshold in dB for an
-                              AP below which the system will report scan
-                              indications
-    deltaSnrThreshold       - Minimum difference for Signal to Noise Ratio in dB
-                              for an AP which trigger a scan indication to be
-                              sent.
-    passiveChannelListCount - Number of channels to be scanned passively.
-    passiveChannelList      - Points to the first channel to be scanned
-                              passively , if any.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeScanConfigData scanCfg[4];
-    u8                  disableAutonomousScans;
-    u16                maxResults;
-    s8                  highRssiThreshold;
-    s8                  lowRssiThreshold;
-    s8                  deltaRssiThreshold;
-    s8                  highSnrThreshold;
-    s8                  lowSnrThreshold;
-    s8                  deltaSnrThreshold;
-    u16                passiveChannelListCount;
-    u8                *passiveChannelList;
-} CsrWifiSmeScanConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResult
-
-  DESCRIPTION
-    This structure defines the scan result for each BSS found
-
-  MEMBERS
-    ssid                         - Service set identifier
-    bssid                        - BSS identifier
-    rssi                         - Received signal strength indication in dBm
-    snr                          - Signal to noise ratio in dB
-    ifIndex                      - Indicates the radio interface
-    beaconPeriodTu               - Interval between beacon frames
-    timeStamp                    - Timestamp in the BSS
-    localTime                    - Timestamp in the Access Point
-    channelFrequency             - Channel frequency
-    capabilityInformation        - Capabilities of the BSS.
-    channelNumber                - Channel number
-    usability                    - Indicates the usability level.
-    bssType                      - Type of BSS.
-    informationElementsLength    - Number of bytes of the information elements
-                                   received as part of the beacon or probe
-                                   response.
-    informationElements          - Points to the first byte of the IEs received
-                                   as part of the beacon or probe response.
-                                   The format of the IEs is as specified in the
-                                   IEEE 802.11 specification.
-    p2pDeviceRole                - Role of the P2P device.
-                                   Relevant only if bssType is
-                                   CSR_WIFI_SME_BSS_TYPE_P2P
-    deviceInfo                   - Union containing P2P device info which
-                                   depends on p2pDeviceRole parameter.
-    deviceInforeservedCli        -
-    deviceInfogroupInfo          -
-    deviceInforeservedNone       -
-    deviceInfostandalonedevInfo  -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSsid              ssid;
-    CsrWifiMacAddress        bssid;
-    s16                 rssi;
-    s16                 snr;
-    CsrWifiSmeRadioIF        ifIndex;
-    u16                beaconPeriodTu;
-    CsrWifiSmeTsfTime        timeStamp;
-    CsrWifiSmeTsfTime        localTime;
-    u16                channelFrequency;
-    u16                capabilityInformation;
-    u8                 channelNumber;
-    CsrWifiSmeBasicUsability usability;
-    CsrWifiSmeBssType        bssType;
-    u16                informationElementsLength;
-    u8                *informationElements;
-    CsrWifiSmeP2pRole        p2pDeviceRole;
-    union {
-        CsrWifiSmeEmpty        reservedCli;
-        CsrWifiSmeP2pGroupInfo groupInfo;
-        CsrWifiSmeEmpty        reservedNone;
-        CsrWifiSmeDeviceInfo   standalonedevInfo;
-    } deviceInfo;
-} CsrWifiSmeScanResult;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeStaConfig
-
-  DESCRIPTION
-    Station configuration options in the SME
-
-  MEMBERS
-    connectionQualityRssiChangeTrigger - Sets the difference of RSSI
-                                         measurements which triggers reports
-                                         from the Firmware
-    connectionQualitySnrChangeTrigger  - Sets the difference of SNR measurements
-                                         which triggers reports from the
-                                         Firmware
-    wmmModeMask                        - Mask containing one or more values from
-                                         CsrWifiSmeWmmMode
-    ifIndex                            - Indicates the band of frequencies used
-    allowUnicastUseGroupCipher         - If TRUE, it allows to use groupwise
-                                         keys if no pairwise key is specified
-    enableOpportunisticKeyCaching      - If TRUE, enables the Opportunistic Key
-                                         Caching feature
-
-*******************************************************************************/
-typedef struct
-{
-    u8              connectionQualityRssiChangeTrigger;
-    u8              connectionQualitySnrChangeTrigger;
-    CsrWifiSmeWmmModeMask wmmModeMask;
-    CsrWifiSmeRadioIF     ifIndex;
-    u8               allowUnicastUseGroupCipher;
-    u8               enableOpportunisticKeyCaching;
-} CsrWifiSmeStaConfig;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWep128Keys
-
-  DESCRIPTION
-    Structure holding WEP Authentication Type and WEP keys that can be used
-    when using WEP128.
-
-  MEMBERS
-    wepAuthType    - Mask to select the WEP authentication type (Open or Shared)
-    selectedWepKey - Index to one of the four keys below indicating the
-                     currently used WEP key. Mapping From SME/User -> firmware.
-                     Key 1 -> Index 0. Key 2 -> Index 1. key 3 -> Index 2. Key
-                     4-> Index 3.
-    key1           - Value for key number 1.
-    key2           - Value for key number 2.
-    key3           - Value for key number 3.
-    key4           - Value for key number 4.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeWepAuthMode wepAuthType;
-    u8              selectedWepKey;
-    u8              key1[13];
-    u8              key2[13];
-    u8              key3[13];
-    u8              key4[13];
-} CsrWifiSmeWep128Keys;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWep64Keys
-
-  DESCRIPTION
-    Structure holding WEP Authentication Type and WEP keys that can be used
-    when using WEP64.
-
-  MEMBERS
-    wepAuthType    - Mask to select the WEP authentication type (Open or Shared)
-    selectedWepKey - Index to one of the four keys below indicating the
-                     currently used WEP key. Mapping From SME/User -> firmware.
-                     Key 1 -> Index 0. Key 2 -> Index 1. key 3 -> Index 2. Key
-                     4-> Index 3.
-    key1           - Value for key number 1.
-    key2           - Value for key number 2.
-    key3           - Value for key number 3.
-    key4           - Value for key number 4.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeWepAuthMode wepAuthType;
-    u8              selectedWepKey;
-    u8              key1[5];
-    u8              key2[5];
-    u8              key3[5];
-    u8              key4[5];
-} CsrWifiSmeWep64Keys;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWepAuth
-
-  DESCRIPTION
-    WEP authentication parameter structure
-
-  MEMBERS
-    wepKeyType               - WEP key try (128 bit or 64 bit)
-    wepCredentials           - Union containing credentials which depends on
-                               wepKeyType parameter.
-    wepCredentialswep128Key  -
-    wepCredentialswep64Key   -
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiSmeWepCredentialType wepKeyType;
-    union {
-        CsrWifiSmeWep128Keys wep128Key;
-        CsrWifiSmeWep64Keys  wep64Key;
-    } wepCredentials;
-} CsrWifiSmeWepAuth;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsConfig
-
-  DESCRIPTION
-    Structure holding AP WPS Config data.
-
-  MEMBERS
-    wpsVersion               - wpsVersion should be 0x10 for WPS1.0h or 0x20 for
-                               WSC2.0
-    uuid                     - uuid.
-    deviceName               - Device name upto 32 characters without '\0'.
-    deviceNameLength         - deviceNameLen.
-    manufacturer             - manufacturer: CSR
-    manufacturerLength       - manufacturerLen.
-    modelName                - modelName Unifi
-    modelNameLength          - modelNameLen.
-    modelNumber              - modelNumber
-    modelNumberLength        - modelNumberLen.
-    serialNumber             - serialNumber
-    primDeviceType           - Primary WPS device type
-    secondaryDeviceTypeCount - Number of secondary device types
-    secondaryDeviceType      - list of secondary WPS device types
-    configMethods            - Supported WPS config methods
-    rfBands                  - RfBands.
-    osVersion                - Os version on which the device is running
-
-*******************************************************************************/
-typedef struct
-{
-    u8                    wpsVersion;
-    u8                    uuid[16];
-    u8                    deviceName[32];
-    u8                    deviceNameLength;
-    u8                    manufacturer[64];
-    u8                    manufacturerLength;
-    u8                    modelName[32];
-    u8                    modelNameLength;
-    u8                    modelNumber[32];
-    u8                    modelNumberLength;
-    u8                    serialNumber[32];
-    CsrWifiSmeWpsDeviceType     primDeviceType;
-    u8                    secondaryDeviceTypeCount;
-    CsrWifiSmeWpsDeviceType    *secondaryDeviceType;
-    CsrWifiSmeWpsConfigTypeMask configMethods;
-    u8                    rfBands;
-    u8                    osVersion[4];
-} CsrWifiSmeWpsConfig;
-
-
-/* Downstream */
-#define CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST            (0x0000)
-
-#define CSR_WIFI_SME_ACTIVATE_REQ                         ((CsrWifiSmePrim) (0x0000 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_ADHOC_CONFIG_GET_REQ                 ((CsrWifiSmePrim) (0x0001 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_ADHOC_CONFIG_SET_REQ                 ((CsrWifiSmePrim) (0x0002 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_BLACKLIST_REQ                        ((CsrWifiSmePrim) (0x0003 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CALIBRATION_DATA_GET_REQ             ((CsrWifiSmePrim) (0x0004 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CALIBRATION_DATA_SET_REQ             ((CsrWifiSmePrim) (0x0005 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CCX_CONFIG_GET_REQ                   ((CsrWifiSmePrim) (0x0006 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CCX_CONFIG_SET_REQ                   ((CsrWifiSmePrim) (0x0007 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_COEX_CONFIG_GET_REQ                  ((CsrWifiSmePrim) (0x0008 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_COEX_CONFIG_SET_REQ                  ((CsrWifiSmePrim) (0x0009 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_COEX_INFO_GET_REQ                    ((CsrWifiSmePrim) (0x000A + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CONNECT_REQ                          ((CsrWifiSmePrim) (0x000B + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CONNECTION_CONFIG_GET_REQ            ((CsrWifiSmePrim) (0x000C + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CONNECTION_INFO_GET_REQ              ((CsrWifiSmePrim) (0x000D + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CONNECTION_STATS_GET_REQ             ((CsrWifiSmePrim) (0x000E + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_DEACTIVATE_REQ                       ((CsrWifiSmePrim) (0x000F + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_DISCONNECT_REQ                       ((CsrWifiSmePrim) (0x0010 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_EVENT_MASK_SET_REQ                   ((CsrWifiSmePrim) (0x0011 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_HOST_CONFIG_GET_REQ                  ((CsrWifiSmePrim) (0x0012 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_HOST_CONFIG_SET_REQ                  ((CsrWifiSmePrim) (0x0013 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_KEY_REQ                              ((CsrWifiSmePrim) (0x0014 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_LINK_QUALITY_GET_REQ                 ((CsrWifiSmePrim) (0x0015 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_CONFIG_GET_REQ                   ((CsrWifiSmePrim) (0x0016 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_CONFIG_SET_REQ                   ((CsrWifiSmePrim) (0x0017 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_GET_NEXT_REQ                     ((CsrWifiSmePrim) (0x0018 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_GET_REQ                          ((CsrWifiSmePrim) (0x0019 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_SET_REQ                          ((CsrWifiSmePrim) (0x001A + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_MULTICAST_ADDRESS_REQ                ((CsrWifiSmePrim) (0x001B + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_PACKET_FILTER_SET_REQ                ((CsrWifiSmePrim) (0x001C + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_REQ        ((CsrWifiSmePrim) (0x001D + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_PMKID_REQ                            ((CsrWifiSmePrim) (0x001E + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_POWER_CONFIG_GET_REQ                 ((CsrWifiSmePrim) (0x001F + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_POWER_CONFIG_SET_REQ                 ((CsrWifiSmePrim) (0x0020 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_REQ       ((CsrWifiSmePrim) (0x0021 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_ROAMING_CONFIG_GET_REQ               ((CsrWifiSmePrim) (0x0022 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_ROAMING_CONFIG_SET_REQ               ((CsrWifiSmePrim) (0x0023 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_CONFIG_GET_REQ                  ((CsrWifiSmePrim) (0x0024 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_CONFIG_SET_REQ                  ((CsrWifiSmePrim) (0x0025 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_FULL_REQ                        ((CsrWifiSmePrim) (0x0026 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_RESULTS_FLUSH_REQ               ((CsrWifiSmePrim) (0x0027 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_RESULTS_GET_REQ                 ((CsrWifiSmePrim) (0x0028 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SME_STA_CONFIG_GET_REQ               ((CsrWifiSmePrim) (0x0029 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SME_STA_CONFIG_SET_REQ               ((CsrWifiSmePrim) (0x002A + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_REQ          ((CsrWifiSmePrim) (0x002B + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_TSPEC_REQ                            ((CsrWifiSmePrim) (0x002C + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_VERSIONS_GET_REQ                     ((CsrWifiSmePrim) (0x002D + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ                  ((CsrWifiSmePrim) (0x002E + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_WIFI_OFF_REQ                         ((CsrWifiSmePrim) (0x002F + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_WIFI_ON_REQ                          ((CsrWifiSmePrim) (0x0030 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CLOAKED_SSIDS_SET_REQ                ((CsrWifiSmePrim) (0x0031 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_CLOAKED_SSIDS_GET_REQ                ((CsrWifiSmePrim) (0x0032 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SME_COMMON_CONFIG_GET_REQ            ((CsrWifiSmePrim) (0x0033 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ            ((CsrWifiSmePrim) (0x0034 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ         ((CsrWifiSmePrim) (0x0035 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_WPS_CONFIGURATION_REQ                ((CsrWifiSmePrim) (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_SET_REQ                              ((CsrWifiSmePrim) (0x0037 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-
-
-#define CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST           (0x0037 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)
-
-/* Upstream */
-#define CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST              (0x0000 + CSR_PRIM_UPSTREAM)
-
-#define CSR_WIFI_SME_ACTIVATE_CFM                         ((CsrWifiSmePrim)(0x0000 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM                 ((CsrWifiSmePrim)(0x0001 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM                 ((CsrWifiSmePrim)(0x0002 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_ASSOCIATION_COMPLETE_IND             ((CsrWifiSmePrim)(0x0003 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_ASSOCIATION_START_IND                ((CsrWifiSmePrim)(0x0004 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_BLACKLIST_CFM                        ((CsrWifiSmePrim)(0x0005 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CALIBRATION_DATA_GET_CFM             ((CsrWifiSmePrim)(0x0006 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CALIBRATION_DATA_SET_CFM             ((CsrWifiSmePrim)(0x0007 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CCX_CONFIG_GET_CFM                   ((CsrWifiSmePrim)(0x0008 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CCX_CONFIG_SET_CFM                   ((CsrWifiSmePrim)(0x0009 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_COEX_CONFIG_GET_CFM                  ((CsrWifiSmePrim)(0x000A + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_COEX_CONFIG_SET_CFM                  ((CsrWifiSmePrim)(0x000B + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_COEX_INFO_GET_CFM                    ((CsrWifiSmePrim)(0x000C + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CONNECT_CFM                          ((CsrWifiSmePrim)(0x000D + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CONNECTION_CONFIG_GET_CFM            ((CsrWifiSmePrim)(0x000E + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CONNECTION_INFO_GET_CFM              ((CsrWifiSmePrim)(0x000F + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CONNECTION_QUALITY_IND               ((CsrWifiSmePrim)(0x0010 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CONNECTION_STATS_GET_CFM             ((CsrWifiSmePrim)(0x0011 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_DEACTIVATE_CFM                       ((CsrWifiSmePrim)(0x0012 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_DISCONNECT_CFM                       ((CsrWifiSmePrim)(0x0013 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_EVENT_MASK_SET_CFM                   ((CsrWifiSmePrim)(0x0014 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_HOST_CONFIG_GET_CFM                  ((CsrWifiSmePrim)(0x0015 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_HOST_CONFIG_SET_CFM                  ((CsrWifiSmePrim)(0x0016 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_IBSS_STATION_IND                     ((CsrWifiSmePrim)(0x0017 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_KEY_CFM                              ((CsrWifiSmePrim)(0x0018 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_LINK_QUALITY_GET_CFM                 ((CsrWifiSmePrim)(0x0019 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_MEDIA_STATUS_IND                     ((CsrWifiSmePrim)(0x001A + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_CONFIG_GET_CFM                   ((CsrWifiSmePrim)(0x001B + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_CONFIG_SET_CFM                   ((CsrWifiSmePrim)(0x001C + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_GET_CFM                          ((CsrWifiSmePrim)(0x001D + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_GET_NEXT_CFM                     ((CsrWifiSmePrim)(0x001E + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIB_SET_CFM                          ((CsrWifiSmePrim)(0x001F + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_MIC_FAILURE_IND                      ((CsrWifiSmePrim)(0x0020 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_MULTICAST_ADDRESS_CFM                ((CsrWifiSmePrim)(0x0021 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_PACKET_FILTER_SET_CFM                ((CsrWifiSmePrim)(0x0022 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_PERMANENT_MAC_ADDRESS_GET_CFM        ((CsrWifiSmePrim)(0x0023 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_PMKID_CANDIDATE_LIST_IND             ((CsrWifiSmePrim)(0x0024 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_PMKID_CFM                            ((CsrWifiSmePrim)(0x0025 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_POWER_CONFIG_GET_CFM                 ((CsrWifiSmePrim)(0x0026 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_POWER_CONFIG_SET_CFM                 ((CsrWifiSmePrim)(0x0027 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_REGULATORY_DOMAIN_INFO_GET_CFM       ((CsrWifiSmePrim)(0x0028 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_ROAM_COMPLETE_IND                    ((CsrWifiSmePrim)(0x0029 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_ROAM_START_IND                       ((CsrWifiSmePrim)(0x002A + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_ROAMING_CONFIG_GET_CFM               ((CsrWifiSmePrim)(0x002B + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_ROAMING_CONFIG_SET_CFM               ((CsrWifiSmePrim)(0x002C + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_CONFIG_GET_CFM                  ((CsrWifiSmePrim)(0x002D + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_CONFIG_SET_CFM                  ((CsrWifiSmePrim)(0x002E + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_FULL_CFM                        ((CsrWifiSmePrim)(0x002F + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_RESULT_IND                      ((CsrWifiSmePrim)(0x0030 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_RESULTS_FLUSH_CFM               ((CsrWifiSmePrim)(0x0031 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SCAN_RESULTS_GET_CFM                 ((CsrWifiSmePrim)(0x0032 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SME_STA_CONFIG_GET_CFM               ((CsrWifiSmePrim)(0x0033 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SME_STA_CONFIG_SET_CFM               ((CsrWifiSmePrim)(0x0034 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_STATION_MAC_ADDRESS_GET_CFM          ((CsrWifiSmePrim)(0x0035 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_TSPEC_IND                            ((CsrWifiSmePrim)(0x0036 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_TSPEC_CFM                            ((CsrWifiSmePrim)(0x0037 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_VERSIONS_GET_CFM                     ((CsrWifiSmePrim)(0x0038 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_WIFI_FLIGHTMODE_CFM                  ((CsrWifiSmePrim)(0x0039 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_WIFI_OFF_IND                         ((CsrWifiSmePrim)(0x003A + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_WIFI_OFF_CFM                         ((CsrWifiSmePrim)(0x003B + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_WIFI_ON_CFM                          ((CsrWifiSmePrim)(0x003C + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CLOAKED_SSIDS_SET_CFM                ((CsrWifiSmePrim)(0x003D + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CLOAKED_SSIDS_GET_CFM                ((CsrWifiSmePrim)(0x003E + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_WIFI_ON_IND                          ((CsrWifiSmePrim)(0x003F + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SME_COMMON_CONFIG_GET_CFM            ((CsrWifiSmePrim)(0x0040 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_SME_COMMON_CONFIG_SET_CFM            ((CsrWifiSmePrim)(0x0041 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_CFM         ((CsrWifiSmePrim)(0x0042 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_ERROR_IND                            ((CsrWifiSmePrim)(0x0043 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_INFO_IND                             ((CsrWifiSmePrim)(0x0044 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_CORE_DUMP_IND                        ((CsrWifiSmePrim)(0x0045 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AMP_STATUS_CHANGE_IND                ((CsrWifiSmePrim)(0x0046 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_WPS_CONFIGURATION_CFM                ((CsrWifiSmePrim)(0x0047 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST))
-
-#define CSR_WIFI_SME_PRIM_UPSTREAM_HIGHEST             (0x0047 + CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)
-
-#define CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT             (CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)
-#define CSR_WIFI_SME_PRIM_UPSTREAM_COUNT               (CSR_WIFI_SME_PRIM_UPSTREAM_HIGHEST   + 1 - CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST)
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeActivateReq
-
-  DESCRIPTION
-    The WMA sends this primitive to activate the SME.
-    The WMA must activate the SME before it can send any other primitive.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeActivateReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAdhocConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the adHocConfig parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeAdhocConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAdhocConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the adHocConfig parameter.
-
-  MEMBERS
-    common      - Common header for use with the CsrWifiFsm Module
-    adHocConfig - Sets the values to use when starting an ad hoc network.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    CsrWifiSmeAdHocConfig adHocConfig;
-} CsrWifiSmeAdhocConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeBlacklistReq
-
-  DESCRIPTION
-    The wireless manager application should call this primitive to notify the
-    driver of any networks that should not be connected to. The interface
-    allows the wireless manager application to query, add, remove, and flush
-    the BSSIDs that the driver may not connect or roam to.
-    When this primitive adds to the black list the BSSID to which the SME is
-    currently connected, the SME will try to roam, if applicable, to another
-    BSSID in the same ESS; if the roaming procedure fails, the SME will
-    disconnect.
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    action          - The value of the CsrWifiSmeListAction parameter instructs
-                      the driver to modify or provide the list of blacklisted
-                      networks.
-    setAddressCount - Number of BSSIDs sent with this primitive
-    setAddresses    - Pointer to the list of BBSIDs sent with the primitive, set
-                      to NULL if none is sent.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrWifiSmeListAction action;
-    u8             setAddressCount;
-    CsrWifiMacAddress   *setAddresses;
-} CsrWifiSmeBlacklistReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCalibrationDataGetReq
-
-  DESCRIPTION
-    This primitive retrieves the Wi-Fi radio calibration data.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeCalibrationDataGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCalibrationDataSetReq
-
-  DESCRIPTION
-    This primitive sets the Wi-Fi radio calibration data.
-    The usage of the primitive with proper calibration data will avoid
-    time-consuming configuration after power-up.
-
-  MEMBERS
-    common                - Common header for use with the CsrWifiFsm Module
-    calibrationDataLength - Number of bytes in the buffer pointed by
-                            calibrationData
-    calibrationData       - Pointer to a buffer of length calibrationDataLength
-                            containing the calibration data
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       calibrationDataLength;
-    u8       *calibrationData;
-} CsrWifiSmeCalibrationDataSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCcxConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the CcxConfig parameter.
-    CURRENTLY NOT SUPPORTED.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeCcxConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCcxConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the CcxConfig parameter.
-    CURRENTLY NOT SUPPORTED.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    ccxConfig    - Currently not supported
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    u16           interfaceTag;
-    CsrWifiSmeCcxConfig ccxConfig;
-} CsrWifiSmeCcxConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the CoexConfig parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeCoexConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the CoexConfig parameter.
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    coexConfig - Configures the coexistence behaviour
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    CsrWifiSmeCoexConfig coexConfig;
-} CsrWifiSmeCoexConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexInfoGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the CoexInfo parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeCoexInfoGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectReq
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to start the
-    process of joining an 802.11 wireless network or to start an ad hoc
-    network.
-    The structure pointed by connectionConfig contains parameters describing
-    the network to join or, in case of an ad hoc network, to host or join.
-    The SME will select a network, perform the IEEE 802.11 Join, Authenticate
-    and Associate exchanges.
-    The SME selects the networks from the current scan list that match both
-    the SSID and BSSID, however either or both of these may be the wildcard
-    value. Using this rule, the following operations are possible:
-      * To connect to a network by name, specify the SSID and set the BSSID to
-        0xFF 0xFF 0xFF 0xFF 0xFF 0xFF. If there are two or more networks visible,
-        the SME will select the one with the strongest signal.
-      * To connect to a specific network, specify the BSSID. The SSID is
-        optional, but if given it must match the SSID of the network. An empty
-        SSID may be specified by setting the SSID length to zero. Please note
-        that if the BSSID is specified (i.e. not equal to 0xFF 0xFF 0xFF 0xFF
-        0xFF 0xFF), the SME will not attempt to roam if signal conditions become
-        poor, even if there is an alternative AP with an SSID that matches the
-        current network SSID.
-      * To connect to any network matching the other parameters (i.e. security,
-        etc), set the SSID length to zero and set the BSSID to 0xFF 0xFF 0xFF
-        0xFF 0xFF 0xFF. In this case, the SME will order all available networks
-        by their signal strengths and will iterate through this list until it
-        successfully connects.
-    NOTE: Specifying the BSSID will restrict the selection to one specific
-    network. If SSID and BSSID are given, they must both match the network
-    for it to be selected. To select a network based on the SSID only, the
-    wireless manager application must set the BSSID to 0xFF 0xFF 0xFF 0xFF
-    0xFF 0xFF.
-    The SME will try to connect to each network that matches the provided
-    parameters, one by one, until it succeeds or has tried unsuccessfully
-    with all the matching networks.
-    If there is no network that matches the parameters and the request allows
-    to host an ad hoc network, the SME will advertise a new ad hoc network
-    instead.
-    If the SME cannot connect, it will notify the failure in the confirm.
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    interfaceTag     - Interface Identifier; unique identifier of an interface
-    connectionConfig - Describes the candidate network to join or to host.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent            common;
-    u16                  interfaceTag;
-    CsrWifiSmeConnectionConfig connectionConfig;
-} CsrWifiSmeConnectReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the ConnectionConfig parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeConnectionConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionInfoGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the ConnectionInfo parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeConnectionInfoGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionStatsGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the ConnectionStats parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeConnectionStatsGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDeactivateReq
-
-  DESCRIPTION
-    The WMA sends this primitive to deactivate the SME.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeDeactivateReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDisconnectReq
-
-  DESCRIPTION
-    The wireless manager application may disconnect from the current network
-    by calling this primitive
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeDisconnectReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeEventMaskSetReq
-
-  DESCRIPTION
-    The wireless manager application may register with the SME to receive
-    notification of interesting events. Indications will be sent only if the
-    wireless manager explicitly registers to be notified of that event.
-    indMask is a bit mask of values defined in CsrWifiSmeIndicationsMask.
-
-  MEMBERS
-    common  - Common header for use with the CsrWifiFsm Module
-    indMask - Set mask with values from CsrWifiSmeIndications
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    CsrWifiSmeIndicationsMask indMask;
-} CsrWifiSmeEventMaskSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the hostConfig parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeHostConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the hostConfig parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    hostConfig   - Communicates a change of host power state (for example, on
-                   mains power, on battery power etc) and of the periodicity of
-                   traffic data
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrWifiSmeHostConfig hostConfig;
-} CsrWifiSmeHostConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeKeyReq
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to add or remove
-    keys that the chip should use for encryption of data.
-    The interface allows the wireless manager application to add and remove
-    keys according to the specified action.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    action       - The value of the CsrWifiSmeListAction parameter instructs the
-                   driver to modify or provide the list of keys.
-                   CSR_WIFI_SME_LIST_ACTION_GET is not supported here.
-    key          - Key to be added or removed
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrWifiSmeListAction action;
-    CsrWifiSmeKey        key;
-} CsrWifiSmeKeyReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeLinkQualityGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the LinkQuality parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeLinkQualityGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the MibConfig parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeMibConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the MibConfig parameter.
-
-  MEMBERS
-    common    - Common header for use with the CsrWifiFsm Module
-    mibConfig - Conveys the desired value of various IEEE 802.11 attributes as
-                currently configured
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    CsrWifiSmeMibConfig mibConfig;
-} CsrWifiSmeMibConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibGetNextReq
-
-  DESCRIPTION
-    To read a sequence of MIB parameters, for example a table, call this
-    primitive to find the name of the next MIB variable
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to a VarBind or VarBindList containing the
-                         name(s) of the MIB variable(s) to search from.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       mibAttributeLength;
-    u8       *mibAttribute;
-} CsrWifiSmeMibGetNextReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibGetReq
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to retrieve one or
-    more MIB variables.
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to the VarBind or VarBindList containing the
-                         names of the MIB variables to be retrieved
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       mibAttributeLength;
-    u8       *mibAttribute;
-} CsrWifiSmeMibGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibSetReq
-
-  DESCRIPTION
-    The SME provides raw access to the MIB on the chip, which may be used by
-    some configuration or diagnostic utilities, but is not normally needed by
-    the wireless manager application.
-    The MIB access functions use BER encoded names (OID) of the MIB
-    parameters and BER encoded values, as described in the chip Host
-    Interface Protocol Specification.
-    The MIB parameters are described in 'Wi-Fi 5.0.0 Management Information
-    Base Reference Guide'.
-    The wireless manager application calls this primitive to set one or more
-    MIB variables
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to the VarBind or VarBindList containing the
-                         names and values of the MIB variables to set
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       mibAttributeLength;
-    u8       *mibAttribute;
-} CsrWifiSmeMibSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMulticastAddressReq
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to specify the
-    multicast addresses which the chip should recognise. The interface allows
-    the wireless manager application to query, add, remove and flush the
-    multicast addresses for the network interface according to the specified
-    action.
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    interfaceTag      - Interface Identifier; unique identifier of an interface
-    action            - The value of the CsrWifiSmeListAction parameter
-                        instructs the driver to modify or provide the list of
-                        MAC addresses.
-    setAddressesCount - Number of MAC addresses sent with the primitive
-    setAddresses      - Pointer to the list of MAC Addresses sent with the
-                        primitive, set to NULL if none is sent.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrWifiSmeListAction action;
-    u8             setAddressesCount;
-    CsrWifiMacAddress   *setAddresses;
-} CsrWifiSmeMulticastAddressReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePacketFilterSetReq
-
-  DESCRIPTION
-    The wireless manager application should call this primitive to enable or
-    disable filtering of broadcast packets: uninteresting broadcast packets
-    will be dropped by the Wi-Fi chip, instead of passing them up to the
-    host.
-    This has the advantage of saving power in the host application processor
-    as it removes the need to process unwanted packets.
-    All broadcast packets are filtered according to the filter and the filter
-    mode provided, except ARP packets, which are filtered using
-    arpFilterAddress.
-    Filters are not cumulative: only the parameters specified in the most
-    recent successful request are significant.
-    For more information, see 'UniFi Firmware API Specification'.
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    interfaceTag     - Interface Identifier; unique identifier of an interface
-    filterLength     - Length of the filter in bytes.
-                       filterLength=0 disables the filter previously set
-    filter           - Points to the first byte of the filter provided, if any.
-                       This shall include zero or more instance of the
-                       information elements of one of these types
-                         * Traffic Classification (TCLAS) elements
-                         * WMM-SA TCLAS elements
-    mode             - Specifies whether the filter selects or excludes packets
-                       matching the filter
-    arpFilterAddress - IPv4 address to be used for filtering the ARP packets.
-                         * If the specified address is the IPv4 broadcast address
-                           (255.255.255.255), all ARP packets are reported to the
-                           host,
-                         * If the specified address is NOT the IPv4 broadcast
-                           address, only ARP packets with the specified address in
-                           the Source or Target Protocol Address fields are reported
-                           to the host
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent            common;
-    u16                  interfaceTag;
-    u16                  filterLength;
-    u8                  *filter;
-    CsrWifiSmePacketFilterMode mode;
-    CsrWifiIp4Address          arpFilterAddress;
-} CsrWifiSmePacketFilterSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePermanentMacAddressGetReq
-
-  DESCRIPTION
-    This primitive retrieves the MAC address stored in EEPROM
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmePermanentMacAddressGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePmkidReq
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to request an
-    operation on the SME PMKID list.
-    The action argument specifies the operation to perform.
-    When the connection is complete, the wireless manager application may
-    then send and receive EAPOL packets to complete WPA or WPA2
-    authentication if appropriate.
-    The wireless manager application can then pass the resulting encryption
-    keys using this primitive.
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    action         - The value of the CsrWifiSmeListAction parameter instructs
-                     the driver to modify or provide the list of PMKIDs.
-    setPmkidsCount - Number of PMKIDs sent with the primitive
-    setPmkids      - Pointer to the list of PMKIDs sent with the primitive, set
-                     to NULL if none is sent.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrWifiSmeListAction action;
-    u8             setPmkidsCount;
-    CsrWifiSmePmkid     *setPmkids;
-} CsrWifiSmePmkidReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the PowerConfig parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmePowerConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the PowerConfig parameter.
-
-  MEMBERS
-    common      - Common header for use with the CsrWifiFsm Module
-    powerConfig - Power saving configuration
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    CsrWifiSmePowerConfig powerConfig;
-} CsrWifiSmePowerConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRegulatoryDomainInfoGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the RegulatoryDomainInfo parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeRegulatoryDomainInfoGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the RoamingConfig parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeRoamingConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the RoamingConfig parameter.
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    roamingConfig - Desired roaming behaviour values
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent         common;
-    u16               interfaceTag;
-    CsrWifiSmeRoamingConfig roamingConfig;
-} CsrWifiSmeRoamingConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the ScanConfig parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeScanConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the ScanConfig parameter.
-    The SME normally configures the firmware to perform autonomous scanning
-    without involving the host.
-    The firmware passes beacon / probe response or indicates loss of beacon
-    on certain changes of state, for example:
-      * A new AP is seen for the first time
-      * An AP is no longer visible
-      * The signal strength of an AP changes by more than a certain amount, as
-        configured by the thresholds in the scanConfig parameter
-    In addition to the autonomous scan, the wireless manager application may
-    request a scan at any time using CSR_WIFI_SME_SCAN_FULL_REQ.
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    scanConfig - Reports the configuration for the autonomous scanning behaviour
-                 of the firmware
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    CsrWifiSmeScanConfig scanConfig;
-} CsrWifiSmeScanConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanFullReq
-
-  DESCRIPTION
-    The wireless manager application should call this primitive to request a
-    full scan.
-    Channels are scanned actively or passively according to the requirement
-    set by regulatory domain.
-    If the SME receives this primitive while a full scan is going on, the new
-    request is buffered and it will be served after the current full scan is
-    completed.
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    ssidCount        - Number of SSIDs provided.
-                       If it is 0, the SME will attempt to detect any network
-    ssid             - Points to the first SSID provided, if any.
-    bssid            - BSS identifier.
-                       If it is equal to FF-FF-FF-FF-FF, the SME will listen for
-                       messages from any BSS.
-                       If it is different from FF-FF-FF-FF-FF and any SSID is
-                       provided, one SSID must match the network of the BSS.
-    forceScan        - Forces the scan even if the SME is in a state which would
-                       normally prevent it (e.g. autonomous scan is running).
-    bssType          - Type of BSS to scan for
-    scanType         - Type of scan to perform
-    channelListCount - Number of channels provided.
-                       If it is 0, the SME will initiate a scan of all the
-                       supported channels that are permitted by the current
-                       regulatory domain.
-    channelList      - Points to the first channel , or NULL if channelListCount
-                       is zero.
-    probeIeLength    - Length of the information element in bytes to be sent
-                       with the probe message.
-    probeIe          - Points to the first byte of the information element to be
-                       sent with the probe message.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent    common;
-    u8           ssidCount;
-    CsrWifiSsid       *ssid;
-    CsrWifiMacAddress  bssid;
-    u8            forceScan;
-    CsrWifiSmeBssType  bssType;
-    CsrWifiSmeScanType scanType;
-    u16          channelListCount;
-    u8          *channelList;
-    u16          probeIeLength;
-    u8          *probeIe;
-} CsrWifiSmeScanFullReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultsFlushReq
-
-  DESCRIPTION
-    The Wireless Manager calls this primitive to ask the SME to delete all
-    scan results from its cache, except for the scan result of any currently
-    connected network.
-    As scan results are received by the SME from the firmware, they are
-    cached in the SME memory.
-    Any time the Wireless Manager requests scan results, they are returned
-    from the SME internal cache.
-    For some applications it may be desirable to clear this cache prior to
-    requesting that a scan be performed; this will ensure that the cache then
-    only contains the networks detected in the most recent scan.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeScanResultsFlushReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultsGetReq
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to retrieve the
-    current set of scan results, either after receiving a successful
-    CSR_WIFI_SME_SCAN_FULL_CFM, or to get autonomous scan results.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeScanResultsGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeStaConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the SmeStaConfig parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-} CsrWifiSmeSmeStaConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeStaConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the SmeConfig parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    smeConfig    - SME Station Parameters to be set
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    u16           interfaceTag;
-    CsrWifiSmeStaConfig smeConfig;
-} CsrWifiSmeSmeStaConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeStationMacAddressGetReq
-
-  DESCRIPTION
-    This primitives is used to retrieve the current MAC address used by the
-    station.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeStationMacAddressGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTspecReq
-
-  DESCRIPTION
-    The wireless manager application should call this primitive to use the
-    TSPEC feature.
-    The chip supports the use of TSPECs and TCLAS for the use of IEEE
-    802.11/WMM Quality of Service features.
-    The API allows the wireless manager application to supply a correctly
-    formatted TSPEC and TCLAS pair to the driver.
-    After performing basic validation, the driver negotiates the installation
-    of the TSPEC with the AP as defined by the 802.11 specification.
-    The driver retains all TSPEC and TCLAS pairs until they are specifically
-    removed.
-    It is not compulsory for a TSPEC to have a TCLAS (NULL is used to
-    indicate that no TCLAS is supplied), while a TCLASS always require a
-    TSPEC.
-    The format of the TSPEC element is specified in 'WMM (including WMM Power
-    Save) Specification - Version 1.1' and 'ANSI/IEEE Std 802.11-REVmb/D3.0'.
-    For more information, see 'UniFi Configuring WMM and WMM-PS'.
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    action        - Specifies the action to be carried out on the list of TSPECs.
-                    CSR_WIFI_SME_LIST_ACTION_FLUSH is not applicable here.
-    transactionId - Unique Transaction ID for the TSPEC, as assigned by the
-                    driver
-    strict        - If it set to false, allows the SME to perform automatic
-                    TSPEC negotiation
-    ctrlMask      - Additional TSPEC configuration for CCX.
-                    Set mask with values from CsrWifiSmeTspecCtrl.
-                    CURRENTLY NOT SUPPORTED
-    tspecLength   - Length of the TSPEC.
-    tspec         - Points to the first byte of the TSPEC
-    tclasLength   - Length of the TCLAS.
-                    If it is equal to 0, no TCLASS is provided for the TSPEC
-    tclas         - Points to the first byte of the TCLAS, if any.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent         common;
-    u16               interfaceTag;
-    CsrWifiSmeListAction    action;
-    u32               transactionId;
-    u8                 strict;
-    CsrWifiSmeTspecCtrlMask ctrlMask;
-    u16               tspecLength;
-    u8               *tspec;
-    u16               tclasLength;
-    u8               *tclas;
-} CsrWifiSmeTspecReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeVersionsGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the Versions parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeVersionsGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiFlightmodeReq
-
-  DESCRIPTION
-    The wireless manager application may call this primitive on boot-up of
-    the platform to ensure that the chip is placed in a mode that prevents
-    any emission of RF energy.
-    This primitive is an alternative to CSR_WIFI_SME_WIFI_ON_REQ.
-    As in CSR_WIFI_SME_WIFI_ON_REQ, it causes the download of the patch file
-    (if any) and the programming of the initial MIB settings (if supplied by
-    the WMA), but it also ensures that the chip is left in its lowest
-    possible power-mode with the radio subsystems disabled.
-    This feature is useful on platforms where power cannot be removed from
-    the chip (leaving the chip not initialised will cause it to consume more
-    power so calling this function ensures that the chip is initialised into
-    a low power mode but without entering a state where it could emit any RF
-    energy).
-    NOTE: this primitive does not cause the Wi-Fi to change state: Wi-Fi
-    stays conceptually off. Configuration primitives can be sent after
-    CSR_WIFI_SME_WIFI_FLIGHTMODE_REQ and the configuration will be maintained.
-    Requests that require the state of the Wi-Fi to be ON will return
-    CSR_WIFI_SME_STATUS_WIFI_OFF in their confirms.
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    address       - Optionally specifies a station MAC address.
-                    In normal use, the manager should set the address to 0xFF
-                    0xFF 0xFF 0xFF 0xFF 0xFF, which will cause the chip to use
-                    the MAC address in the MIB.
-    mibFilesCount - Number of provided data blocks with initial MIB values
-    mibFiles      - Points to the first data block with initial MIB values.
-                    These data blocks are typically the contents of the provided
-                    files ufmib.dat and localmib.dat, available from the host
-                    file system, if they exist.
-                    These files typically contain radio tuning and calibration
-                    values.
-                    More values can be created using the Host Tools.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    CsrWifiMacAddress    address;
-    u16            mibFilesCount;
-    CsrWifiSmeDataBlock *mibFiles;
-} CsrWifiSmeWifiFlightmodeReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOffReq
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to turn off the
-    chip, thus saving power when Wi-Fi is not in use.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeWifiOffReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOnReq
-
-  DESCRIPTION
-    The wireless manager application calls this primitive to turn on the
-    Wi-Fi chip.
-    If the Wi-Fi chip is currently off, the SME turns the Wi-Fi chip on,
-    downloads the patch file (if any), and programs the initial MIB settings
-    (if supplied by the WMA).
-    The patch file is not provided with the SME API; its downloading is
-    automatic and handled internally by the system.
-    The MIB settings, when provided, override the default values that the
-    firmware loads from EEPROM.
-    If the Wi-Fi chip is already on, the SME takes no action and returns a
-    successful status in the confirm.
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    address       - Optionally specifies a station MAC address.
-                    In normal use, the manager should set the address to 0xFF
-                    0xFF 0xFF 0xFF 0xFF 0xFF, which will cause the chip to use
-                    the MAC address in the MIB
-    mibFilesCount - Number of provided data blocks with initial MIB values
-    mibFiles      - Points to the first data block with initial MIB values.
-                    These data blocks are typically the contents of the provided
-                    files ufmib.dat and localmib.dat, available from the host
-                    file system, if they exist.
-                    These files typically contain radio tuning and calibration
-                    values.
-                    More values can be created using the Host Tools.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    CsrWifiMacAddress    address;
-    u16            mibFilesCount;
-    CsrWifiSmeDataBlock *mibFiles;
-} CsrWifiSmeWifiOnReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCloakedSsidsSetReq
-
-  DESCRIPTION
-    This primitive sets the list of cloaked SSIDs for which the WMA possesses
-    profiles.
-    When the driver detects a cloaked AP, the SME will explicitly scan for it
-    using the list of cloaked SSIDs provided it, and, if the scan succeeds,
-    it will report the AP to the WMA either via CSR_WIFI_SME_SCAN_RESULT_IND
-    (if registered) or via CSR_WIFI_SCAN_RESULT_GET_CFM.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    cloakedSsids - Sets the list of cloaked SSIDs
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent             common;
-    CsrWifiSmeCloakedSsidConfig cloakedSsids;
-} CsrWifiSmeCloakedSsidsSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCloakedSsidsGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the CloakedSsids parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeCloakedSsidsGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeCommonConfigGetReq
-
-  DESCRIPTION
-    This primitive gets the value of the Sme common parameter.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeSmeCommonConfigGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeCommonConfigSetReq
-
-  DESCRIPTION
-    This primitive sets the value of the Sme common.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    deviceConfig - Configuration options in the SME
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent        common;
-    CsrWifiSmeDeviceConfig deviceConfig;
-} CsrWifiSmeSmeCommonConfigSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeInterfaceCapabilityGetReq
-
-  DESCRIPTION
-    The Wireless Manager calls this primitive to ask the SME for the
-    capabilities of the supported interfaces
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-} CsrWifiSmeInterfaceCapabilityGetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsConfigurationReq
-
-  DESCRIPTION
-    This primitive passes the WPS information for the device to SME. This may
-    be accepted only if no interface is active.
-
-  MEMBERS
-    common    - Common header for use with the CsrWifiFsm Module
-    wpsConfig - WPS config.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    CsrWifiSmeWpsConfig wpsConfig;
-} CsrWifiSmeWpsConfigurationReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSetReq
-
-  DESCRIPTION
-    Used to pass custom data to the SME. Format is the same as 802.11 Info
-    Elements => | Id | Length | Data
-    1) Cmanr Test Mode "Id:0 Length:1 Data:0x00 = OFF 0x01 = ON" "0x00 0x01
-    (0x00|0x01)"
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    dataLength - Number of bytes in the buffer pointed to by 'data'
-    data       - Pointer to the buffer containing 'dataLength' bytes
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u32       dataLength;
-    u8       *data;
-} CsrWifiSmeSetReq;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeActivateCfm
-
-  DESCRIPTION
-    The SME sends this primitive when the activation is complete.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeActivateCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAdhocConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common      - Common header for use with the CsrWifiFsm Module
-    status      - Reports the result of the request
-    adHocConfig - Contains the values used when starting an Ad-hoc (IBSS)
-                  connection.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    CsrResult             status;
-    CsrWifiSmeAdHocConfig adHocConfig;
-} CsrWifiSmeAdhocConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAdhocConfigSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeAdhocConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAssociationCompleteInd
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it whenever it completes an attempt to associate with an AP. If
-    the association was successful, status will be set to
-    CSR_WIFI_SME_STATUS_SUCCESS, otherwise status and deauthReason shall be
-    set to appropriate error codes.
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    status         - Reports the result of the association procedure
-    connectionInfo - This parameter is relevant only if result is
-                     CSR_WIFI_SME_STATUS_SUCCESS:
-                     it points to the connection information for the new network
-    deauthReason   - This parameter is relevant only if result is not
-                     CSR_WIFI_SME_STATUS_SUCCESS:
-                     if the AP deauthorised the station, it gives the reason of
-                     the deauthorization
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrResult                 status;
-    CsrWifiSmeConnectionInfo  connectionInfo;
-    CsrWifiSmeIEEE80211Reason deauthReason;
-} CsrWifiSmeAssociationCompleteInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAssociationStartInd
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it whenever it begins an attempt to associate with an AP.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    address      - BSSID of the associating network
-    ssid         - Service Set identifier of the associating network
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    u16         interfaceTag;
-    CsrWifiMacAddress address;
-    CsrWifiSsid       ssid;
-} CsrWifiSmeAssociationStartInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeBlacklistCfm
-
-  DESCRIPTION
-    The SME will call this primitive when the action on the blacklist has
-    completed. For a GET action, this primitive also reports the list of
-    BBSIDs in the blacklist.
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    status          - Reports the result of the request
-    action          - Action in the request
-    getAddressCount - This parameter is only relevant if action is
-                      CSR_WIFI_SME_LIST_ACTION_GET:
-                      number of BSSIDs sent with this primitive
-    getAddresses    - Pointer to the list of BBSIDs sent with the primitive, set
-                      to NULL if none is sent.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrResult            status;
-    CsrWifiSmeListAction action;
-    u8             getAddressCount;
-    CsrWifiMacAddress   *getAddresses;
-} CsrWifiSmeBlacklistCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCalibrationDataGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common                - Common header for use with the CsrWifiFsm Module
-    status                - Reports the result of the request
-    calibrationDataLength - Number of bytes in the buffer pointed by
-                            calibrationData
-    calibrationData       - Pointer to a buffer of length calibrationDataLength
-                            containing the calibration data
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-    u16       calibrationDataLength;
-    u8       *calibrationData;
-} CsrWifiSmeCalibrationDataGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCalibrationDataSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeCalibrationDataSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCcxConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-    ccxConfig    - Currently not supported
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    u16           interfaceTag;
-    CsrResult           status;
-    CsrWifiSmeCcxConfig ccxConfig;
-} CsrWifiSmeCcxConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCcxConfigSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeCcxConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    status     - Reports the result of the request
-    coexConfig - Reports the parameters used to configure the coexistence
-                 behaviour
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    CsrResult            status;
-    CsrWifiSmeCoexConfig coexConfig;
-} CsrWifiSmeCoexConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexConfigSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeCoexConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoexInfoGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common   - Common header for use with the CsrWifiFsm Module
-    status   - Reports the result of the request
-    coexInfo - Reports information and state related to coexistence.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent    common;
-    CsrResult          status;
-    CsrWifiSmeCoexInfo coexInfo;
-} CsrWifiSmeCoexInfoGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectCfm
-
-  DESCRIPTION
-    The SME calls this primitive when the connection exchange is complete or
-    all connection attempts fail.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request.
-                   CSR_WIFI_SME_STATUS_NOT_FOUND: all attempts by the SME to
-                   locate the requested AP failed
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeConnectCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    interfaceTag     - Interface Identifier; unique identifier of an interface
-    status           - Reports the result of the request
-    connectionConfig - Parameters used by the SME for selecting a network
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent            common;
-    u16                  interfaceTag;
-    CsrResult                  status;
-    CsrWifiSmeConnectionConfig connectionConfig;
-} CsrWifiSmeConnectionConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionInfoGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    status         - Reports the result of the request
-    connectionInfo - Information about the current connection
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent          common;
-    u16                interfaceTag;
-    CsrResult                status;
-    CsrWifiSmeConnectionInfo connectionInfo;
-} CsrWifiSmeConnectionInfoGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionQualityInd
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it whenever the value of the current connection quality
-    parameters change by more than a certain configurable amount.
-    The wireless manager application may configure the trigger thresholds for
-    this indication using the field in smeConfig parameter of
-    CSR_WIFI_SME_SME_CONFIG_SET_REQ.
-    Connection quality messages can be suppressed by setting both thresholds
-    to zero.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    linkQuality  - Indicates the quality of the link
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    u16             interfaceTag;
-    CsrWifiSmeLinkQuality linkQuality;
-} CsrWifiSmeConnectionQualityInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeConnectionStatsGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    status          - Reports the result of the request
-    connectionStats - Statistics for current connection.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrResult                 status;
-    CsrWifiSmeConnectionStats connectionStats;
-} CsrWifiSmeConnectionStatsGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDeactivateCfm
-
-  DESCRIPTION
-    The SME sends this primitive when the deactivation is complete.
-    The WMA cannot send any more primitives until it actives the SME again
-    sending another CSR_WIFI_SME_ACTIVATE_REQ.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeDeactivateCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeDisconnectCfm
-
-  DESCRIPTION
-    On reception of CSR_WIFI_SME_DISCONNECT_REQ the SME will perform a
-    disconnect operation, sending a CsrWifiSmeMediaStatusInd with
-    CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED and then call this primitive when
-    disconnection is complete.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeDisconnectCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeEventMaskSetCfm
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the request
-    primitive.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeEventMaskSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-    hostConfig   - Current host power state.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrResult            status;
-    CsrWifiSmeHostConfig hostConfig;
-} CsrWifiSmeHostConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeHostConfigSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeHostConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeIbssStationInd
-
-  DESCRIPTION
-    The SME will send this primitive to indicate that a station has joined or
-    left the ad-hoc network.
-
-  MEMBERS
-    common      - Common header for use with the CsrWifiFsm Module
-    address     - MAC address of the station that has joined or left
-    isconnected - TRUE if the station joined, FALSE if the station left
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    CsrWifiMacAddress address;
-    u8           isconnected;
-} CsrWifiSmeIbssStationInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeKeyCfm
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the request
-    primitive.
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    status         - Reports the result of the request
-    action         - Action in the request
-    keyType        - Type of the key added/deleted
-    peerMacAddress - Peer MAC Address of the key added/deleted
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrResult            status;
-    CsrWifiSmeListAction action;
-    CsrWifiSmeKeyType    keyType;
-    CsrWifiMacAddress    peerMacAddress;
-} CsrWifiSmeKeyCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeLinkQualityGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-    linkQuality  - Indicates the quality of the link
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    u16             interfaceTag;
-    CsrResult             status;
-    CsrWifiSmeLinkQuality linkQuality;
-} CsrWifiSmeLinkQualityGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMediaStatusInd
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it when a network connection is established, lost or has moved to
-    another AP.
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    mediaStatus    - Indicates the media status
-    connectionInfo - This parameter is relevant only if the mediaStatus is
-                     CSR_WIFI_SME_MEDIA_STATUS_CONNECTED:
-                     it points to the connection information for the new network
-    disassocReason - This parameter is relevant only if the mediaStatus is
-                     CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED:
-                     if a disassociation has occurred it gives the reason of the
-                     disassociation
-    deauthReason   - This parameter is relevant only if the mediaStatus is
-                     CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED:
-                     if a deauthentication has occurred it gives the reason of
-                     the deauthentication
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrWifiSmeMediaStatus     mediaStatus;
-    CsrWifiSmeConnectionInfo  connectionInfo;
-    CsrWifiSmeIEEE80211Reason disassocReason;
-    CsrWifiSmeIEEE80211Reason deauthReason;
-} CsrWifiSmeMediaStatusInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common    - Common header for use with the CsrWifiFsm Module
-    status    - Reports the result of the request
-    mibConfig - Reports various IEEE 802.11 attributes as currently configured
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    CsrResult           status;
-    CsrWifiSmeMibConfig mibConfig;
-} CsrWifiSmeMibConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibConfigSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeMibConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibGetCfm
-
-  DESCRIPTION
-    The SME calls this primitive to return the requested MIB variable values.
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    status             - Reports the result of the request
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to the VarBind or VarBindList containing the
-                         names and values of the MIB variables requested
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-    u16       mibAttributeLength;
-    u8       *mibAttribute;
-} CsrWifiSmeMibGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibGetNextCfm
-
-  DESCRIPTION
-    The SME calls this primitive to return the requested MIB name(s).
-    The wireless manager application can then read the value of the MIB
-    variable using CSR_WIFI_SME_MIB_GET_REQ, using the names provided.
-
-  MEMBERS
-    common             - Common header for use with the CsrWifiFsm Module
-    status             - Reports the result of the request
-    mibAttributeLength - Length of mibAttribute
-    mibAttribute       - Points to a VarBind or VarBindList containing the
-                         name(s) of the MIB variable(s) lexicographically
-                         following the name(s) given in the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-    u16       mibAttributeLength;
-    u8       *mibAttribute;
-} CsrWifiSmeMibGetNextCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMibSetCfm
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the set primitive.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeMibSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMicFailureInd
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it whenever the chip firmware reports a MIC failure.
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    secondFailure - TRUE if this indication is for a second failure in 60
-                    seconds
-    count         - The number of MIC failure events since the connection was
-                    established
-    address       - MAC address of the transmitter that caused the MIC failure
-    keyType       - Type of key for which the failure occurred
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    u16         interfaceTag;
-    u8           secondFailure;
-    u16         count;
-    CsrWifiMacAddress address;
-    CsrWifiSmeKeyType keyType;
-} CsrWifiSmeMicFailureInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeMulticastAddressCfm
-
-  DESCRIPTION
-    The SME will call this primitive when the operation is complete. For a
-    GET action, this primitive reports the current list of MAC addresses.
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    interfaceTag      - Interface Identifier; unique identifier of an interface
-    status            - Reports the result of the request
-    action            - Action in the request
-    getAddressesCount - This parameter is only relevant if action is
-                        CSR_WIFI_SME_LIST_ACTION_GET:
-                        number of MAC addresses sent with the primitive
-    getAddresses      - Pointer to the list of MAC Addresses sent with the
-                        primitive, set to NULL if none is sent.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrResult            status;
-    CsrWifiSmeListAction action;
-    u8             getAddressesCount;
-    CsrWifiMacAddress   *getAddresses;
-} CsrWifiSmeMulticastAddressCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePacketFilterSetCfm
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the set primitive.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmePacketFilterSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePermanentMacAddressGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common              - Common header for use with the CsrWifiFsm Module
-    status              - Reports the result of the request
-    permanentMacAddress - MAC address stored in the EEPROM
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    CsrResult         status;
-    CsrWifiMacAddress permanentMacAddress;
-} CsrWifiSmePermanentMacAddressGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePmkidCandidateListInd
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it when a new network supporting preauthentication and/or PMK
-    caching is seen.
-
-  MEMBERS
-    common               - Common header for use with the CsrWifiFsm Module
-    interfaceTag         - Interface Identifier; unique identifier of an
-                           interface
-    pmkidCandidatesCount - Number of PMKID candidates provided
-    pmkidCandidates      - Points to the first PMKID candidate
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    u8                  pmkidCandidatesCount;
-    CsrWifiSmePmkidCandidate *pmkidCandidates;
-} CsrWifiSmePmkidCandidateListInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePmkidCfm
-
-  DESCRIPTION
-    The SME will call this primitive when the operation is complete. For a
-    GET action, this primitive reports the current list of PMKIDs
-
-  MEMBERS
-    common         - Common header for use with the CsrWifiFsm Module
-    interfaceTag   - Interface Identifier; unique identifier of an interface
-    status         - Reports the result of the request
-    action         - Action in the request
-    getPmkidsCount - This parameter is only relevant if action is
-                     CSR_WIFI_SME_LIST_ACTION_GET:
-                     number of PMKIDs sent with the primitive
-    getPmkids      - Pointer to the list of PMKIDs sent with the primitive, set
-                     to NULL if none is sent.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    u16            interfaceTag;
-    CsrResult            status;
-    CsrWifiSmeListAction action;
-    u8             getPmkidsCount;
-    CsrWifiSmePmkid     *getPmkids;
-} CsrWifiSmePmkidCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common      - Common header for use with the CsrWifiFsm Module
-    status      - Reports the result of the request
-    powerConfig - Returns the current parameters for the power configuration of
-                  the firmware
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    CsrResult             status;
-    CsrWifiSmePowerConfig powerConfig;
-} CsrWifiSmePowerConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmePowerConfigSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmePowerConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRegulatoryDomainInfoGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    status     - Reports the result of the request
-    regDomInfo - Reports information and state related to regulatory domain
-                 operation.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent                common;
-    CsrResult                      status;
-    CsrWifiSmeRegulatoryDomainInfo regDomInfo;
-} CsrWifiSmeRegulatoryDomainInfoGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamCompleteInd
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it whenever it completes an attempt to roam to an AP. If the roam
-    attempt was successful, status will be set to CSR_WIFI_SME_SUCCESS,
-    otherwise it shall be set to the appropriate error code.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the roaming procedure
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeRoamCompleteInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamStartInd
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive it whenever it begins an attempt to roam to an AP.
-    If the wireless manager application connect request specified the SSID
-    and the BSSID was set to the broadcast address (0xFF 0xFF 0xFF 0xFF 0xFF
-    0xFF), the SME monitors the signal quality and maintains a list of
-    candidates to roam to. When the signal quality of the current connection
-    falls below a threshold, and there is a candidate with better quality,
-    the SME will attempt to the candidate AP.
-    If the roaming procedure succeeds, the SME will also issue a Media
-    Connect indication to inform the wireless manager application of the
-    change.
-    NOTE: to prevent the SME from initiating roaming the WMA must specify the
-    BSSID in the connection request; this forces the SME to connect only to
-    that AP.
-    The wireless manager application can obtain statistics for roaming
-    purposes using CSR_WIFI_SME_CONNECTION_QUALITY_IND and
-    CSR_WIFI_SME_CONNECTION_STATS_GET_REQ.
-    When the wireless manager application wishes to roam to another AP, it
-    must issue a connection request specifying the BSSID of the desired AP.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    roamReason   - Indicates the reason for starting the roaming procedure
-    reason80211  - Indicates the reason for deauthentication or disassociation
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrWifiSmeRoamReason      roamReason;
-    CsrWifiSmeIEEE80211Reason reason80211;
-} CsrWifiSmeRoamStartInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    interfaceTag  - Interface Identifier; unique identifier of an interface
-    status        - Reports the result of the request
-    roamingConfig - Reports the roaming behaviour of the driver and firmware
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent         common;
-    u16               interfaceTag;
-    CsrResult               status;
-    CsrWifiSmeRoamingConfig roamingConfig;
-} CsrWifiSmeRoamingConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeRoamingConfigSetCfm
-
-  DESCRIPTION
-    This primitive sets the value of the RoamingConfig parameter.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeRoamingConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    status     - Reports the result of the request
-    scanConfig - Returns the current parameters for the autonomous scanning
-                 behaviour of the firmware
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    CsrResult            status;
-    CsrWifiSmeScanConfig scanConfig;
-} CsrWifiSmeScanConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanConfigSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeScanConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanFullCfm
-
-  DESCRIPTION
-    The SME calls this primitive when the results from the scan are
-    available.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeScanFullCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultInd
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it whenever a scan indication is received from the firmware.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    result - Points to a buffer containing a scan result.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent      common;
-    CsrWifiSmeScanResult result;
-} CsrWifiSmeScanResultInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultsFlushCfm
-
-  DESCRIPTION
-    The SME will call this primitive when the cache has been cleared.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeScanResultsFlushCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeScanResultsGetCfm
-
-  DESCRIPTION
-    The SME sends this primitive to provide the current set of scan results.
-
-  MEMBERS
-    common           - Common header for use with the CsrWifiFsm Module
-    status           - Reports the result of the request
-    scanResultsCount - Number of scan results
-    scanResults      - Points to a buffer containing an array of
-                       CsrWifiSmeScanResult structures.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent       common;
-    CsrResult             status;
-    u16             scanResultsCount;
-    CsrWifiSmeScanResult *scanResults;
-} CsrWifiSmeScanResultsGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeStaConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-    smeConfig    - Current SME Station Parameters
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    u16           interfaceTag;
-    CsrResult           status;
-    CsrWifiSmeStaConfig smeConfig;
-} CsrWifiSmeSmeStaConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeStaConfigSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface Identifier; unique identifier of an interface
-    status       - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u16       interfaceTag;
-    CsrResult       status;
-} CsrWifiSmeSmeStaConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeStationMacAddressGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common            - Common header for use with the CsrWifiFsm Module
-    status            - Reports the result of the request
-    stationMacAddress - Current MAC address of the station.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    CsrResult         status;
-    CsrWifiMacAddress stationMacAddress[2];
-} CsrWifiSmeStationMacAddressGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTspecInd
-
-  DESCRIPTION
-    The SME will send this primitive to all the task that have registered to
-    receive it when a status change in the TSPEC occurs.
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    transactionId   - Unique Transaction ID for the TSPEC, as assigned by the
-                      driver
-    tspecResultCode - Specifies the TSPEC operation requested by the peer
-                      station
-    tspecLength     - Length of the TSPEC.
-    tspec           - Points to the first byte of the TSPEC
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    u32                 transactionId;
-    CsrWifiSmeTspecResultCode tspecResultCode;
-    u16                 tspecLength;
-    u8                 *tspec;
-} CsrWifiSmeTspecInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeTspecCfm
-
-  DESCRIPTION
-    The SME calls the primitive to report the result of the TSpec primitive
-    request.
-
-  MEMBERS
-    common          - Common header for use with the CsrWifiFsm Module
-    interfaceTag    - Interface Identifier; unique identifier of an interface
-    status          - Reports the result of the request
-    transactionId   - Unique Transaction ID for the TSPEC, as assigned by the
-                      driver
-    tspecResultCode - Specifies the result of the negotiated TSPEC operation
-    tspecLength     - Length of the TSPEC.
-    tspec           - Points to the first byte of the TSPEC
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent           common;
-    u16                 interfaceTag;
-    CsrResult                 status;
-    u32                 transactionId;
-    CsrWifiSmeTspecResultCode tspecResultCode;
-    u16                 tspecLength;
-    u8                 *tspec;
-} CsrWifiSmeTspecCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeVersionsGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common   - Common header for use with the CsrWifiFsm Module
-    status   - Reports the result of the request
-    versions - Version IDs of the product
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent    common;
-    CsrResult          status;
-    CsrWifiSmeVersions versions;
-} CsrWifiSmeVersionsGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiFlightmodeCfm
-
-  DESCRIPTION
-    The SME calls this primitive when the chip is initialised for low power
-    mode and with the radio subsystem disabled. To leave flight mode, and
-    enable Wi-Fi, the wireless manager application should call
-    CSR_WIFI_SME_WIFI_ON_REQ.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeWifiFlightmodeCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOffInd
-
-  DESCRIPTION
-    The SME sends this primitive to all the tasks that have registered to
-    receive it to report that the chip has been turned off.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    reason - Indicates the reason why the Wi-Fi has been switched off.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent             common;
-    CsrWifiSmeControlIndication reason;
-} CsrWifiSmeWifiOffInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOffCfm
-
-  DESCRIPTION
-    After receiving CSR_WIFI_SME_WIFI_OFF_REQ, if the chip is connected to a
-    network, the SME will perform a disconnect operation, will send a
-    CSR_WIFI_SME_MEDIA_STATUS_IND with
-    CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED, and then will call
-    CSR_WIFI_SME_WIFI_OFF_CFM when the chip is off.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeWifiOffCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOnCfm
-
-  DESCRIPTION
-    The SME sends this primitive to the task that has sent the request once
-    the chip has been initialised and is available for use.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeWifiOnCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCloakedSsidsSetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeCloakedSsidsSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCloakedSsidsGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    status       - Reports the result of the request
-    cloakedSsids - Reports list of cloaked SSIDs that are explicitly scanned for
-                   by the driver
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent             common;
-    CsrResult                   status;
-    CsrWifiSmeCloakedSsidConfig cloakedSsids;
-} CsrWifiSmeCloakedSsidsGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWifiOnInd
-
-  DESCRIPTION
-    The SME sends this primitive to all tasks that have registered to receive
-    it once the chip becomes available and ready to use.
-
-  MEMBERS
-    common  - Common header for use with the CsrWifiFsm Module
-    address - Current MAC address
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent   common;
-    CsrWifiMacAddress address;
-} CsrWifiSmeWifiOnInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeCommonConfigGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    status       - Reports the result of the request
-    deviceConfig - Configuration options in the SME
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent        common;
-    CsrResult              status;
-    CsrWifiSmeDeviceConfig deviceConfig;
-} CsrWifiSmeSmeCommonConfigGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeSmeCommonConfigSetCfm
-
-  DESCRIPTION
-    Reports the result of the request
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Reports the result of the request
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeSmeCommonConfigSetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeInterfaceCapabilityGetCfm
-
-  DESCRIPTION
-    This primitive reports the result of the request.
-
-  MEMBERS
-    common        - Common header for use with the CsrWifiFsm Module
-    status        - Result of the request
-    numInterfaces - Number of the interfaces supported
-    capBitmap     - Points to the list of capabilities bitmaps provided for each
-                    interface.
-                    The bits represent the following capabilities:
-                    -bits 7 to 4-Reserved
-                    -bit 3-AMP
-                    -bit 2-P2P
-                    -bit 1-AP
-                    -bit 0-STA
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-    u16       numInterfaces;
-    u8        capBitmap[2];
-} CsrWifiSmeInterfaceCapabilityGetCfm;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeErrorInd
-
-  DESCRIPTION
-    Important error message indicating a error of some importance
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    errorMessage - Contains the error message.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    char  *errorMessage;
-} CsrWifiSmeErrorInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeInfoInd
-
-  DESCRIPTION
-    Message indicating a some info about current activity. Mostly of interest
-    in testing but may be useful in the field.
-
-  MEMBERS
-    common      - Common header for use with the CsrWifiFsm Module
-    infoMessage - Contains the message.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    char  *infoMessage;
-} CsrWifiSmeInfoInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeCoreDumpInd
-
-  DESCRIPTION
-    The SME will send this primitive to all the tasks that have registered to
-    receive Wi-Fi Chip core dump data.
-    The core dump data may be fragmented and sent using more than one
-    indication.
-    To indicate that all the data has been sent, the last indication contains
-    a 'length' of 0 and 'data' of NULL.
-
-  MEMBERS
-    common     - Common header for use with the CsrWifiFsm Module
-    dataLength - Number of bytes in the buffer pointed to by 'data'
-    data       - Pointer to the buffer containing 'dataLength' bytes of core
-                 dump data
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    u32       dataLength;
-    u8       *data;
-} CsrWifiSmeCoreDumpInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeAmpStatusChangeInd
-
-  DESCRIPTION
-    Indication of change to AMP activity.
-
-  MEMBERS
-    common       - Common header for use with the CsrWifiFsm Module
-    interfaceTag - Interface on which the AMP activity changed.
-    ampStatus    - The new status of AMP activity.Range: {AMP_ACTIVE,
-                   AMP_INACTIVE}.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent     common;
-    u16           interfaceTag;
-    CsrWifiSmeAmpStatus ampStatus;
-} CsrWifiSmeAmpStatusChangeInd;
-
-/*******************************************************************************
-
-  NAME
-    CsrWifiSmeWpsConfigurationCfm
-
-  DESCRIPTION
-    Confirm.
-
-  MEMBERS
-    common - Common header for use with the CsrWifiFsm Module
-    status - Status of the request.
-
-*******************************************************************************/
-typedef struct
-{
-    CsrWifiFsmEvent common;
-    CsrResult       status;
-} CsrWifiSmeWpsConfigurationCfm;
-
-#endif /* CSR_WIFI_SME_PRIM_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_sef.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_sef.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_sef.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_sef.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*****************************************************************************
-
-  (c) Cambridge Silicon Radio Limited 2010
-  Confidential information of CSR
-
-  Refer to LICENSE.txt included with this source for details
-  on the license terms.
-
- *****************************************************************************/
-#include "csr_wifi_sme_sef.h"
-
-const CsrWifiSmeStateHandlerType CsrWifiSmeUpstreamStateHandlers[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT] =
-{
-    /* 0x8000 */ CsrWifiSmeActivateCfmHandler,
-    /* 0x8001 */ CsrWifiSmeAdhocConfigGetCfmHandler,
-    /* 0x8002 */ CsrWifiSmeAdhocConfigSetCfmHandler,
-    /* 0x8003 */ CsrWifiSmeAssociationCompleteIndHandler,
-    /* 0x8004 */ CsrWifiSmeAssociationStartIndHandler,
-    /* 0x8005 */ CsrWifiSmeBlacklistCfmHandler,
-    /* 0x8006 */ CsrWifiSmeCalibrationDataGetCfmHandler,
-    /* 0x8007 */ CsrWifiSmeCalibrationDataSetCfmHandler,
-    /* 0x8008 */ CsrWifiSmeCcxConfigGetCfmHandler,
-    /* 0x8009 */ CsrWifiSmeCcxConfigSetCfmHandler,
-    /* 0x800A */ CsrWifiSmeCoexConfigGetCfmHandler,
-    /* 0x800B */ CsrWifiSmeCoexConfigSetCfmHandler,
-    /* 0x800C */ CsrWifiSmeCoexInfoGetCfmHandler,
-    /* 0x800D */ CsrWifiSmeConnectCfmHandler,
-    /* 0x800E */ CsrWifiSmeConnectionConfigGetCfmHandler,
-    /* 0x800F */ CsrWifiSmeConnectionInfoGetCfmHandler,
-    /* 0x8010 */ CsrWifiSmeConnectionQualityIndHandler,
-    /* 0x8011 */ CsrWifiSmeConnectionStatsGetCfmHandler,
-    /* 0x8012 */ CsrWifiSmeDeactivateCfmHandler,
-    /* 0x8013 */ CsrWifiSmeDisconnectCfmHandler,
-    /* 0x8014 */ CsrWifiSmeEventMaskSetCfmHandler,
-    /* 0x8015 */ CsrWifiSmeHostConfigGetCfmHandler,
-    /* 0x8016 */ CsrWifiSmeHostConfigSetCfmHandler,
-    /* 0x8017 */ CsrWifiSmeIbssStationIndHandler,
-    /* 0x8018 */ CsrWifiSmeKeyCfmHandler,
-    /* 0x8019 */ CsrWifiSmeLinkQualityGetCfmHandler,
-    /* 0x801A */ CsrWifiSmeMediaStatusIndHandler,
-    /* 0x801B */ CsrWifiSmeMibConfigGetCfmHandler,
-    /* 0x801C */ CsrWifiSmeMibConfigSetCfmHandler,
-    /* 0x801D */ CsrWifiSmeMibGetCfmHandler,
-    /* 0x801E */ CsrWifiSmeMibGetNextCfmHandler,
-    /* 0x801F */ CsrWifiSmeMibSetCfmHandler,
-    /* 0x8020 */ CsrWifiSmeMicFailureIndHandler,
-    /* 0x8021 */ CsrWifiSmeMulticastAddressCfmHandler,
-    /* 0x8022 */ CsrWifiSmePacketFilterSetCfmHandler,
-    /* 0x8023 */ CsrWifiSmePermanentMacAddressGetCfmHandler,
-    /* 0x8024 */ CsrWifiSmePmkidCandidateListIndHandler,
-    /* 0x8025 */ CsrWifiSmePmkidCfmHandler,
-    /* 0x8026 */ CsrWifiSmePowerConfigGetCfmHandler,
-    /* 0x8027 */ CsrWifiSmePowerConfigSetCfmHandler,
-    /* 0x8028 */ CsrWifiSmeRegulatoryDomainInfoGetCfmHandler,
-    /* 0x8029 */ CsrWifiSmeRoamCompleteIndHandler,
-    /* 0x802A */ CsrWifiSmeRoamStartIndHandler,
-    /* 0x802B */ CsrWifiSmeRoamingConfigGetCfmHandler,
-    /* 0x802C */ CsrWifiSmeRoamingConfigSetCfmHandler,
-    /* 0x802D */ CsrWifiSmeScanConfigGetCfmHandler,
-    /* 0x802E */ CsrWifiSmeScanConfigSetCfmHandler,
-    /* 0x802F */ CsrWifiSmeScanFullCfmHandler,
-    /* 0x8030 */ CsrWifiSmeScanResultIndHandler,
-    /* 0x8031 */ CsrWifiSmeScanResultsFlushCfmHandler,
-    /* 0x8032 */ CsrWifiSmeScanResultsGetCfmHandler,
-    /* 0x8033 */ CsrWifiSmeSmeStaConfigGetCfmHandler,
-    /* 0x8034 */ CsrWifiSmeSmeStaConfigSetCfmHandler,
-    /* 0x8035 */ CsrWifiSmeStationMacAddressGetCfmHandler,
-    /* 0x8036 */ CsrWifiSmeTspecIndHandler,
-    /* 0x8037 */ CsrWifiSmeTspecCfmHandler,
-    /* 0x8038 */ CsrWifiSmeVersionsGetCfmHandler,
-    /* 0x8039 */ CsrWifiSmeWifiFlightmodeCfmHandler,
-    /* 0x803A */ CsrWifiSmeWifiOffIndHandler,
-    /* 0x803B */ CsrWifiSmeWifiOffCfmHandler,
-    /* 0x803C */ CsrWifiSmeWifiOnCfmHandler,
-    /* 0x803D */ CsrWifiSmeCloakedSsidsSetCfmHandler,
-    /* 0x803E */ CsrWifiSmeCloakedSsidsGetCfmHandler,
-    /* 0x803F */ CsrWifiSmeWifiOnIndHandler,
-    /* 0x8040 */ CsrWifiSmeSmeCommonConfigGetCfmHandler,
-    /* 0x8041 */ CsrWifiSmeSmeCommonConfigSetCfmHandler,
-    /* 0x8042 */ CsrWifiSmeGetInterfaceCapabilityCfmHandler,
-    /* 0x8043 */ CsrWifiSmeErrorIndHandler,
-    /* 0x8044 */ CsrWifiSmeInfoIndHandler,
-    /* 0x8045 */ CsrWifiSmeCoreDumpIndHandler,
-    /* 0x8046 */ CsrWifiSmeAmpStatusChangeIndHandler,
-};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_sef.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_sef.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_sef.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_sef.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,142 +0,0 @@
-/*****************************************************************************
-
-	(c) Cambridge Silicon Radio Limited 2010
-	Confidential information of CSR
-
-	Refer to LICENSE.txt included with this source for details
-	on the license terms.
-
-*****************************************************************************/
-#ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__
-#define CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__
-
-#include "csr_wifi_sme_prim.h"
-
-typedef void (*CsrWifiSmeStateHandlerType)(void *drvpriv, CsrWifiFsmEvent *msg);
-
-extern const CsrWifiSmeStateHandlerType
-	CsrWifiSmeUpstreamStateHandlers[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT];
-
-
-extern void CsrWifiSmeActivateCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeAdhocConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeAdhocConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeAssociationCompleteIndHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeAssociationStartIndHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeBlacklistCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCalibrationDataGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCalibrationDataSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCcxConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCcxConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCoexConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCoexConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCoexInfoGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeConnectCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeConnectionConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeConnectionInfoGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeConnectionQualityIndHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeConnectionStatsGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeDeactivateCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeDisconnectCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeEventMaskSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeHostConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeHostConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeIbssStationIndHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeKeyCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeLinkQualityGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeMediaStatusIndHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeMibConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeMibConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeMibGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeMibGetNextCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeMibSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeMicFailureIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeMulticastAddressCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmePacketFilterSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmePermanentMacAddressGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmePmkidCandidateListIndHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmePmkidCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmePowerConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmePowerConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeRoamCompleteIndHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeRoamStartIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeRoamingConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeRoamingConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeScanConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeScanConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeScanFullCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeScanResultIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeScanResultsFlushCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeScanResultsGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeSmeStaConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeSmeStaConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeStationMacAddressGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeTspecIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeTspecCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeVersionsGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeWifiFlightmodeCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeWifiOffIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeWifiOffCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeWifiOnCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCloakedSsidsSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCloakedSsidsGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeWifiOnIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeSmeCommonConfigGetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeSmeCommonConfigSetCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeErrorIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeInfoIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeCoreDumpIndHandler(void *drvpriv, CsrWifiFsmEvent *msg);
-extern void CsrWifiSmeAmpStatusChangeIndHandler(void *drvpriv,
-	CsrWifiFsmEvent *msg);
-
-#endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_serialize.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_serialize.c
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_serialize.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_serialize.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,5809 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2012
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-#include <linux/string.h>
-#include <linux/slab.h>
-#include "csr_msgconv.h"
-#include "csr_wifi_sme_prim.h"
-#include "csr_wifi_sme_serialize.h"
-
-void CsrWifiSmePfree(void *ptr)
-{
-    kfree(ptr);
-}
-
-
-size_t CsrWifiSmeAdhocConfigSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
-    bufferSize += 2; /* u16 primitive->adHocConfig.atimWindowTu */
-    bufferSize += 2; /* u16 primitive->adHocConfig.beaconPeriodTu */
-    bufferSize += 2; /* u16 primitive->adHocConfig.joinOnlyAttempts */
-    bufferSize += 2; /* u16 primitive->adHocConfig.joinAttemptIntervalMs */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeAdhocConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeAdhocConfigSetReq *primitive = (CsrWifiSmeAdhocConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->adHocConfig.atimWindowTu);
-    CsrUint16Ser(ptr, len, (u16) primitive->adHocConfig.beaconPeriodTu);
-    CsrUint16Ser(ptr, len, (u16) primitive->adHocConfig.joinOnlyAttempts);
-    CsrUint16Ser(ptr, len, (u16) primitive->adHocConfig.joinAttemptIntervalMs);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeAdhocConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeAdhocConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmeAdhocConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->adHocConfig.atimWindowTu, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->adHocConfig.beaconPeriodTu, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->adHocConfig.joinOnlyAttempts, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->adHocConfig.joinAttemptIntervalMs, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeBlacklistReqSizeof(void *msg)
-{
-    CsrWifiSmeBlacklistReq *primitive = (CsrWifiSmeBlacklistReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiSmeListAction primitive->action */
-    bufferSize += 1; /* u8 primitive->setAddressCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setAddressCount; i1++)
-        {
-            bufferSize += 6; /* u8 primitive->setAddresses[i1].a[6] */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeBlacklistReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeBlacklistReq *primitive = (CsrWifiSmeBlacklistReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->setAddressCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setAddressCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->setAddresses[i1].a, ((u16) (6)));
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeBlacklistReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeBlacklistReq *primitive = kmalloc(sizeof(CsrWifiSmeBlacklistReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->setAddressCount, buffer, &offset);
-    primitive->setAddresses = NULL;
-    if (primitive->setAddressCount)
-    {
-        primitive->setAddresses = kmalloc(sizeof(CsrWifiMacAddress) * primitive->setAddressCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setAddressCount; i1++)
-        {
-            CsrMemCpyDes(primitive->setAddresses[i1].a, buffer, &offset, ((u16) (6)));
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeBlacklistReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeBlacklistReq *primitive = (CsrWifiSmeBlacklistReq *) voidPrimitivePointer;
-    kfree(primitive->setAddresses);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeCalibrationDataSetReqSizeof(void *msg)
-{
-    CsrWifiSmeCalibrationDataSetReq *primitive = (CsrWifiSmeCalibrationDataSetReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 6) */
-    bufferSize += 2;                                /* u16 primitive->calibrationDataLength */
-    bufferSize += primitive->calibrationDataLength; /* u8 primitive->calibrationData */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCalibrationDataSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCalibrationDataSetReq *primitive = (CsrWifiSmeCalibrationDataSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->calibrationDataLength);
-    if (primitive->calibrationDataLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->calibrationData, ((u16) (primitive->calibrationDataLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCalibrationDataSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCalibrationDataSetReq *primitive = kmalloc(sizeof(CsrWifiSmeCalibrationDataSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->calibrationDataLength, buffer, &offset);
-    if (primitive->calibrationDataLength)
-    {
-        primitive->calibrationData = kmalloc(primitive->calibrationDataLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->calibrationData, buffer, &offset, ((u16) (primitive->calibrationDataLength)));
-    }
-    else
-    {
-        primitive->calibrationData = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeCalibrationDataSetReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeCalibrationDataSetReq *primitive = (CsrWifiSmeCalibrationDataSetReq *) voidPrimitivePointer;
-    kfree(primitive->calibrationData);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeCcxConfigSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* u8 primitive->ccxConfig.keepAliveTimeMs */
-    bufferSize += 1; /* u8 primitive->ccxConfig.apRoamingEnabled */
-    bufferSize += 1; /* u8 primitive->ccxConfig.measurementsMask */
-    bufferSize += 1; /* u8 primitive->ccxConfig.ccxRadioMgtEnabled */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCcxConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCcxConfigSetReq *primitive = (CsrWifiSmeCcxConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->ccxConfig.keepAliveTimeMs);
-    CsrUint8Ser(ptr, len, (u8) primitive->ccxConfig.apRoamingEnabled);
-    CsrUint8Ser(ptr, len, (u8) primitive->ccxConfig.measurementsMask);
-    CsrUint8Ser(ptr, len, (u8) primitive->ccxConfig.ccxRadioMgtEnabled);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCcxConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCcxConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmeCcxConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ccxConfig.keepAliveTimeMs, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ccxConfig.apRoamingEnabled, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ccxConfig.measurementsMask, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ccxConfig.ccxRadioMgtEnabled, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeCoexConfigSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 29) */
-    bufferSize += 1; /* u8 primitive->coexConfig.coexEnableSchemeManagement */
-    bufferSize += 1; /* u8 primitive->coexConfig.coexPeriodicWakeHost */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexTrafficBurstyLatencyMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexTrafficContinuousLatencyMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexObexBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexObexBlackoutPeriodMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexA2dpBrBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexA2dpBrBlackoutPeriodMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexA2dpEdrBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexPagingBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexPagingBlackoutPeriodMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexInquiryBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexInquiryBlackoutPeriodMs */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCoexConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCoexConfigSetReq *primitive = (CsrWifiSmeCoexConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint8Ser(ptr, len, (u8) primitive->coexConfig.coexEnableSchemeManagement);
-    CsrUint8Ser(ptr, len, (u8) primitive->coexConfig.coexPeriodicWakeHost);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexTrafficBurstyLatencyMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexTrafficContinuousLatencyMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexObexBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexObexBlackoutPeriodMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexA2dpBrBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexA2dpBrBlackoutPeriodMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexA2dpEdrBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexPagingBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexPagingBlackoutPeriodMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexInquiryBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexInquiryBlackoutPeriodMs);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCoexConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCoexConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmeCoexConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->coexConfig.coexEnableSchemeManagement, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->coexConfig.coexPeriodicWakeHost, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexTrafficBurstyLatencyMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexTrafficContinuousLatencyMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexObexBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexObexBlackoutPeriodMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexA2dpBrBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexA2dpBrBlackoutPeriodMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexA2dpEdrBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexPagingBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexPagingBlackoutPeriodMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexInquiryBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexInquiryBlackoutPeriodMs, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeConnectReqSizeof(void *msg)
-{
-    CsrWifiSmeConnectReq *primitive = (CsrWifiSmeConnectReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 57) */
-    bufferSize += 2;                                                                     /* u16 primitive->interfaceTag */
-    bufferSize += 32;                                                                    /* u8 primitive->connectionConfig.ssid.ssid[32] */
-    bufferSize += 1;                                                                     /* u8 primitive->connectionConfig.ssid.length */
-    bufferSize += 6;                                                                     /* u8 primitive->connectionConfig.bssid.a[6] */
-    bufferSize += 1;                                                                     /* CsrWifiSmeBssType primitive->connectionConfig.bssType */
-    bufferSize += 1;                                                                     /* CsrWifiSmeRadioIF primitive->connectionConfig.ifIndex */
-    bufferSize += 1;                                                                     /* CsrWifiSme80211PrivacyMode primitive->connectionConfig.privacyMode */
-    bufferSize += 2;                                                                     /* CsrWifiSmeAuthModeMask primitive->connectionConfig.authModeMask */
-    bufferSize += 2;                                                                     /* CsrWifiSmeEncryptionMask primitive->connectionConfig.encryptionModeMask */
-    bufferSize += 2;                                                                     /* u16 primitive->connectionConfig.mlmeAssociateReqInformationElementsLength */
-    bufferSize += primitive->connectionConfig.mlmeAssociateReqInformationElementsLength; /* u8 primitive->connectionConfig.mlmeAssociateReqInformationElements */
-    bufferSize += 1;                                                                     /* CsrWifiSmeWmmQosInfoMask primitive->connectionConfig.wmmQosInfo */
-    bufferSize += 1;                                                                     /* u8 primitive->connectionConfig.adhocJoinOnly */
-    bufferSize += 1;                                                                     /* u8 primitive->connectionConfig.adhocChannel */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeConnectReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeConnectReq *primitive = (CsrWifiSmeConnectReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.ssid.ssid, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.ssid.length);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.bssid.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.bssType);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.ifIndex);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.privacyMode);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionConfig.authModeMask);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionConfig.encryptionModeMask);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionConfig.mlmeAssociateReqInformationElementsLength);
-    if (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.mlmeAssociateReqInformationElements, ((u16) (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength)));
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.wmmQosInfo);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.adhocJoinOnly);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.adhocChannel);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeConnectReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeConnectReq *primitive = kmalloc(sizeof(CsrWifiSmeConnectReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionConfig.ssid.ssid, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->connectionConfig.ssid.length, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionConfig.bssid.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->connectionConfig.bssType, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionConfig.ifIndex, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionConfig.privacyMode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionConfig.authModeMask, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionConfig.encryptionModeMask, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionConfig.mlmeAssociateReqInformationElementsLength, buffer, &offset);
-    if (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength)
-    {
-        primitive->connectionConfig.mlmeAssociateReqInformationElements = kmalloc(primitive->connectionConfig.mlmeAssociateReqInformationElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionConfig.mlmeAssociateReqInformationElements, buffer, &offset, ((u16) (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength)));
-    }
-    else
-    {
-        primitive->connectionConfig.mlmeAssociateReqInformationElements = NULL;
-    }
-    CsrUint8Des((u8 *) &primitive->connectionConfig.wmmQosInfo, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionConfig.adhocJoinOnly, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionConfig.adhocChannel, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiSmeConnectReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeConnectReq *primitive = (CsrWifiSmeConnectReq *) voidPrimitivePointer;
-    kfree(primitive->connectionConfig.mlmeAssociateReqInformationElements);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeHostConfigSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiSmeHostPowerMode primitive->hostConfig.powerMode */
-    bufferSize += 2; /* u16 primitive->hostConfig.applicationDataPeriodMs */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeHostConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeHostConfigSetReq *primitive = (CsrWifiSmeHostConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->hostConfig.powerMode);
-    CsrUint16Ser(ptr, len, (u16) primitive->hostConfig.applicationDataPeriodMs);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeHostConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeHostConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmeHostConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->hostConfig.powerMode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->hostConfig.applicationDataPeriodMs, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeKeyReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 65) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiSmeListAction primitive->action */
-    bufferSize += 1; /* CsrWifiSmeKeyType primitive->key.keyType */
-    bufferSize += 1; /* u8 primitive->key.keyIndex */
-    bufferSize += 1; /* u8 primitive->key.wepTxKey */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 8; i2++)
-        {
-            bufferSize += 2; /* u16 primitive->key.keyRsc[8] */
-        }
-    }
-    bufferSize += 1;         /* u8 primitive->key.authenticator */
-    bufferSize += 6;         /* u8 primitive->key.address.a[6] */
-    bufferSize += 1;         /* u8 primitive->key.keyLength */
-    bufferSize += 32;        /* u8 primitive->key.key[32] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeKeyReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeKeyReq *primitive = (CsrWifiSmeKeyReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->key.keyType);
-    CsrUint8Ser(ptr, len, (u8) primitive->key.keyIndex);
-    CsrUint8Ser(ptr, len, (u8) primitive->key.wepTxKey);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 8; i2++)
-        {
-            CsrUint16Ser(ptr, len, (u16) primitive->key.keyRsc[i2]);
-        }
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->key.authenticator);
-    CsrMemCpySer(ptr, len, (const void *) primitive->key.address.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->key.keyLength);
-    CsrMemCpySer(ptr, len, (const void *) primitive->key.key, ((u16) (32)));
-    return(ptr);
-}
-
-
-void* CsrWifiSmeKeyReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeKeyReq *primitive = kmalloc(sizeof(CsrWifiSmeKeyReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->key.keyType, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->key.keyIndex, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->key.wepTxKey, buffer, &offset);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 8; i2++)
-        {
-            CsrUint16Des((u16 *) &primitive->key.keyRsc[i2], buffer, &offset);
-        }
-    }
-    CsrUint8Des((u8 *) &primitive->key.authenticator, buffer, &offset);
-    CsrMemCpyDes(primitive->key.address.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->key.keyLength, buffer, &offset);
-    CsrMemCpyDes(primitive->key.key, buffer, &offset, ((u16) (32)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeMibConfigSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
-    bufferSize += 1; /* u8 primitive->mibConfig.unifiFixMaxTxDataRate */
-    bufferSize += 1; /* u8 primitive->mibConfig.unifiFixTxDataRate */
-    bufferSize += 2; /* u16 primitive->mibConfig.dot11RtsThreshold */
-    bufferSize += 2; /* u16 primitive->mibConfig.dot11FragmentationThreshold */
-    bufferSize += 2; /* u16 primitive->mibConfig.dot11CurrentTxPowerLevel */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMibConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMibConfigSetReq *primitive = (CsrWifiSmeMibConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint8Ser(ptr, len, (u8) primitive->mibConfig.unifiFixMaxTxDataRate);
-    CsrUint8Ser(ptr, len, (u8) primitive->mibConfig.unifiFixTxDataRate);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibConfig.dot11RtsThreshold);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibConfig.dot11FragmentationThreshold);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibConfig.dot11CurrentTxPowerLevel);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMibConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMibConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmeMibConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->mibConfig.unifiFixMaxTxDataRate, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->mibConfig.unifiFixTxDataRate, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibConfig.dot11RtsThreshold, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibConfig.dot11FragmentationThreshold, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibConfig.dot11CurrentTxPowerLevel, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeMibGetNextReqSizeof(void *msg)
-{
-    CsrWifiSmeMibGetNextReq *primitive = (CsrWifiSmeMibGetNextReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 6) */
-    bufferSize += 2;                             /* u16 primitive->mibAttributeLength */
-    bufferSize += primitive->mibAttributeLength; /* u8 primitive->mibAttribute */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMibGetNextReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMibGetNextReq *primitive = (CsrWifiSmeMibGetNextReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibAttributeLength);
-    if (primitive->mibAttributeLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((u16) (primitive->mibAttributeLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMibGetNextReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMibGetNextReq *primitive = kmalloc(sizeof(CsrWifiSmeMibGetNextReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibAttributeLength, buffer, &offset);
-    if (primitive->mibAttributeLength)
-    {
-        primitive->mibAttribute = kmalloc(primitive->mibAttributeLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((u16) (primitive->mibAttributeLength)));
-    }
-    else
-    {
-        primitive->mibAttribute = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeMibGetNextReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeMibGetNextReq *primitive = (CsrWifiSmeMibGetNextReq *) voidPrimitivePointer;
-    kfree(primitive->mibAttribute);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeMibGetReqSizeof(void *msg)
-{
-    CsrWifiSmeMibGetReq *primitive = (CsrWifiSmeMibGetReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 6) */
-    bufferSize += 2;                             /* u16 primitive->mibAttributeLength */
-    bufferSize += primitive->mibAttributeLength; /* u8 primitive->mibAttribute */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMibGetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMibGetReq *primitive = (CsrWifiSmeMibGetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibAttributeLength);
-    if (primitive->mibAttributeLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((u16) (primitive->mibAttributeLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMibGetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMibGetReq *primitive = kmalloc(sizeof(CsrWifiSmeMibGetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibAttributeLength, buffer, &offset);
-    if (primitive->mibAttributeLength)
-    {
-        primitive->mibAttribute = kmalloc(primitive->mibAttributeLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((u16) (primitive->mibAttributeLength)));
-    }
-    else
-    {
-        primitive->mibAttribute = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeMibGetReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeMibGetReq *primitive = (CsrWifiSmeMibGetReq *) voidPrimitivePointer;
-    kfree(primitive->mibAttribute);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeMibSetReqSizeof(void *msg)
-{
-    CsrWifiSmeMibSetReq *primitive = (CsrWifiSmeMibSetReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 6) */
-    bufferSize += 2;                             /* u16 primitive->mibAttributeLength */
-    bufferSize += primitive->mibAttributeLength; /* u8 primitive->mibAttribute */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMibSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMibSetReq *primitive = (CsrWifiSmeMibSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibAttributeLength);
-    if (primitive->mibAttributeLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((u16) (primitive->mibAttributeLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMibSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMibSetReq *primitive = kmalloc(sizeof(CsrWifiSmeMibSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibAttributeLength, buffer, &offset);
-    if (primitive->mibAttributeLength)
-    {
-        primitive->mibAttribute = kmalloc(primitive->mibAttributeLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((u16) (primitive->mibAttributeLength)));
-    }
-    else
-    {
-        primitive->mibAttribute = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeMibSetReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeMibSetReq *primitive = (CsrWifiSmeMibSetReq *) voidPrimitivePointer;
-    kfree(primitive->mibAttribute);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeMulticastAddressReqSizeof(void *msg)
-{
-    CsrWifiSmeMulticastAddressReq *primitive = (CsrWifiSmeMulticastAddressReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiSmeListAction primitive->action */
-    bufferSize += 1; /* u8 primitive->setAddressesCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setAddressesCount; i1++)
-        {
-            bufferSize += 6; /* u8 primitive->setAddresses[i1].a[6] */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMulticastAddressReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMulticastAddressReq *primitive = (CsrWifiSmeMulticastAddressReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->setAddressesCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setAddressesCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->setAddresses[i1].a, ((u16) (6)));
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMulticastAddressReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMulticastAddressReq *primitive = kmalloc(sizeof(CsrWifiSmeMulticastAddressReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->setAddressesCount, buffer, &offset);
-    primitive->setAddresses = NULL;
-    if (primitive->setAddressesCount)
-    {
-        primitive->setAddresses = kmalloc(sizeof(CsrWifiMacAddress) * primitive->setAddressesCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setAddressesCount; i1++)
-        {
-            CsrMemCpyDes(primitive->setAddresses[i1].a, buffer, &offset, ((u16) (6)));
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeMulticastAddressReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeMulticastAddressReq *primitive = (CsrWifiSmeMulticastAddressReq *) voidPrimitivePointer;
-    kfree(primitive->setAddresses);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmePacketFilterSetReqSizeof(void *msg)
-{
-    CsrWifiSmePacketFilterSetReq *primitive = (CsrWifiSmePacketFilterSetReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2;                       /* u16 primitive->interfaceTag */
-    bufferSize += 2;                       /* u16 primitive->filterLength */
-    bufferSize += primitive->filterLength; /* u8 primitive->filter */
-    bufferSize += 1;                       /* CsrWifiSmePacketFilterMode primitive->mode */
-    bufferSize += 4;                       /* u8 primitive->arpFilterAddress.a[4] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmePacketFilterSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmePacketFilterSetReq *primitive = (CsrWifiSmePacketFilterSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->filterLength);
-    if (primitive->filterLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->filter, ((u16) (primitive->filterLength)));
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->mode);
-    CsrMemCpySer(ptr, len, (const void *) primitive->arpFilterAddress.a, ((u16) (4)));
-    return(ptr);
-}
-
-
-void* CsrWifiSmePacketFilterSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmePacketFilterSetReq *primitive = kmalloc(sizeof(CsrWifiSmePacketFilterSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->filterLength, buffer, &offset);
-    if (primitive->filterLength)
-    {
-        primitive->filter = kmalloc(primitive->filterLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->filter, buffer, &offset, ((u16) (primitive->filterLength)));
-    }
-    else
-    {
-        primitive->filter = NULL;
-    }
-    CsrUint8Des((u8 *) &primitive->mode, buffer, &offset);
-    CsrMemCpyDes(primitive->arpFilterAddress.a, buffer, &offset, ((u16) (4)));
-
-    return primitive;
-}
-
-
-void CsrWifiSmePacketFilterSetReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmePacketFilterSetReq *primitive = (CsrWifiSmePacketFilterSetReq *) voidPrimitivePointer;
-    kfree(primitive->filter);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmePmkidReqSizeof(void *msg)
-{
-    CsrWifiSmePmkidReq *primitive = (CsrWifiSmePmkidReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 29) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiSmeListAction primitive->action */
-    bufferSize += 1; /* u8 primitive->setPmkidsCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setPmkidsCount; i1++)
-        {
-            bufferSize += 6;  /* u8 primitive->setPmkids[i1].bssid.a[6] */
-            bufferSize += 16; /* u8 primitive->setPmkids[i1].pmkid[16] */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmePmkidReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmePmkidReq *primitive = (CsrWifiSmePmkidReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->setPmkidsCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setPmkidsCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->setPmkids[i1].bssid.a, ((u16) (6)));
-            CsrMemCpySer(ptr, len, (const void *) primitive->setPmkids[i1].pmkid, ((u16) (16)));
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmePmkidReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmePmkidReq *primitive = kmalloc(sizeof(CsrWifiSmePmkidReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->setPmkidsCount, buffer, &offset);
-    primitive->setPmkids = NULL;
-    if (primitive->setPmkidsCount)
-    {
-        primitive->setPmkids = kmalloc(sizeof(CsrWifiSmePmkid) * primitive->setPmkidsCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->setPmkidsCount; i1++)
-        {
-            CsrMemCpyDes(primitive->setPmkids[i1].bssid.a, buffer, &offset, ((u16) (6)));
-            CsrMemCpyDes(primitive->setPmkids[i1].pmkid, buffer, &offset, ((u16) (16)));
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmePmkidReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmePmkidReq *primitive = (CsrWifiSmePmkidReq *) voidPrimitivePointer;
-    kfree(primitive->setPmkids);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmePowerConfigSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
-    bufferSize += 1; /* CsrWifiSmePowerSaveLevel primitive->powerConfig.powerSaveLevel */
-    bufferSize += 2; /* u16 primitive->powerConfig.listenIntervalTu */
-    bufferSize += 1; /* u8 primitive->powerConfig.rxDtims */
-    bufferSize += 1; /* CsrWifiSmeD3AutoScanMode primitive->powerConfig.d3AutoScanMode */
-    bufferSize += 1; /* u8 primitive->powerConfig.clientTrafficWindow */
-    bufferSize += 1; /* u8 primitive->powerConfig.opportunisticPowerSave */
-    bufferSize += 1; /* u8 primitive->powerConfig.noticeOfAbsence */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmePowerConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmePowerConfigSetReq *primitive = (CsrWifiSmePowerConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.powerSaveLevel);
-    CsrUint16Ser(ptr, len, (u16) primitive->powerConfig.listenIntervalTu);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.rxDtims);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.d3AutoScanMode);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.clientTrafficWindow);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.opportunisticPowerSave);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.noticeOfAbsence);
-    return(ptr);
-}
-
-
-void* CsrWifiSmePowerConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmePowerConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmePowerConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.powerSaveLevel, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->powerConfig.listenIntervalTu, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.rxDtims, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.d3AutoScanMode, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.clientTrafficWindow, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.opportunisticPowerSave, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.noticeOfAbsence, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeRoamingConfigSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 70) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            bufferSize += 2; /* s16 primitive->roamingConfig.roamingBands[i2].rssiHighThreshold */
-            bufferSize += 2; /* s16 primitive->roamingConfig.roamingBands[i2].rssiLowThreshold */
-            bufferSize += 2; /* s16 primitive->roamingConfig.roamingBands[i2].snrHighThreshold */
-            bufferSize += 2; /* s16 primitive->roamingConfig.roamingBands[i2].snrLowThreshold */
-        }
-    }
-    bufferSize += 1;         /* u8 primitive->roamingConfig.disableSmoothRoaming */
-    bufferSize += 1;         /* u8 primitive->roamingConfig.disableRoamScans */
-    bufferSize += 1;         /* u8 primitive->roamingConfig.reconnectLimit */
-    bufferSize += 2;         /* u16 primitive->roamingConfig.reconnectLimitIntervalMs */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].intervalSeconds */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].validitySeconds */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeRoamingConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeRoamingConfigSetReq *primitive = (CsrWifiSmeRoamingConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamingBands[i2].rssiHighThreshold);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamingBands[i2].rssiLowThreshold);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamingBands[i2].snrHighThreshold);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamingBands[i2].snrLowThreshold);
-        }
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->roamingConfig.disableSmoothRoaming);
-    CsrUint8Ser(ptr, len, (u8) primitive->roamingConfig.disableRoamScans);
-    CsrUint8Ser(ptr, len, (u8) primitive->roamingConfig.reconnectLimit);
-    CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.reconnectLimitIntervalMs);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].intervalSeconds);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].validitySeconds);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu);
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeRoamingConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeRoamingConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmeRoamingConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamingBands[i2].rssiHighThreshold, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamingBands[i2].rssiLowThreshold, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamingBands[i2].snrHighThreshold, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamingBands[i2].snrLowThreshold, buffer, &offset);
-        }
-    }
-    CsrUint8Des((u8 *) &primitive->roamingConfig.disableSmoothRoaming, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->roamingConfig.disableRoamScans, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->roamingConfig.reconnectLimit, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->roamingConfig.reconnectLimitIntervalMs, buffer, &offset);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].intervalSeconds, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].validitySeconds, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu, buffer, &offset);
-        }
-    }
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeScanConfigSetReqSizeof(void *msg)
-{
-    CsrWifiSmeScanConfigSetReq *primitive = (CsrWifiSmeScanConfigSetReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 63) */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].intervalSeconds */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].validitySeconds */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu */
-        }
-    }
-    bufferSize += 1;                                             /* u8 primitive->scanConfig.disableAutonomousScans */
-    bufferSize += 2;                                             /* u16 primitive->scanConfig.maxResults */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.highRssiThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.lowRssiThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.deltaRssiThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.highSnrThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.lowSnrThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.deltaSnrThreshold */
-    bufferSize += 2;                                             /* u16 primitive->scanConfig.passiveChannelListCount */
-    bufferSize += primitive->scanConfig.passiveChannelListCount; /* u8 primitive->scanConfig.passiveChannelList */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeScanConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeScanConfigSetReq *primitive = (CsrWifiSmeScanConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].intervalSeconds);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].validitySeconds);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu);
-        }
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.disableAutonomousScans);
-    CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.maxResults);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.highRssiThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.lowRssiThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.deltaRssiThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.highSnrThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.lowSnrThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.deltaSnrThreshold);
-    CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.passiveChannelListCount);
-    if (primitive->scanConfig.passiveChannelListCount)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->scanConfig.passiveChannelList, ((u16) (primitive->scanConfig.passiveChannelListCount)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeScanConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeScanConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmeScanConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].intervalSeconds, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].validitySeconds, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu, buffer, &offset);
-        }
-    }
-    CsrUint8Des((u8 *) &primitive->scanConfig.disableAutonomousScans, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->scanConfig.maxResults, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.highRssiThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.lowRssiThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.deltaRssiThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.highSnrThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.lowSnrThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.deltaSnrThreshold, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->scanConfig.passiveChannelListCount, buffer, &offset);
-    if (primitive->scanConfig.passiveChannelListCount)
-    {
-        primitive->scanConfig.passiveChannelList = kmalloc(primitive->scanConfig.passiveChannelListCount, GFP_KERNEL);
-        CsrMemCpyDes(primitive->scanConfig.passiveChannelList, buffer, &offset, ((u16) (primitive->scanConfig.passiveChannelListCount)));
-    }
-    else
-    {
-        primitive->scanConfig.passiveChannelList = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeScanConfigSetReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeScanConfigSetReq *primitive = (CsrWifiSmeScanConfigSetReq *) voidPrimitivePointer;
-    kfree(primitive->scanConfig.passiveChannelList);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeScanFullReqSizeof(void *msg)
-{
-    CsrWifiSmeScanFullReq *primitive = (CsrWifiSmeScanFullReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 52) */
-    bufferSize += 1; /* u8 primitive->ssidCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->ssidCount; i1++)
-        {
-            bufferSize += 32;                  /* u8 primitive->ssid[i1].ssid[32] */
-            bufferSize += 1;                   /* u8 primitive->ssid[i1].length */
-        }
-    }
-    bufferSize += 6;                           /* u8 primitive->bssid.a[6] */
-    bufferSize += 1;                           /* u8 primitive->forceScan */
-    bufferSize += 1;                           /* CsrWifiSmeBssType primitive->bssType */
-    bufferSize += 1;                           /* CsrWifiSmeScanType primitive->scanType */
-    bufferSize += 2;                           /* u16 primitive->channelListCount */
-    bufferSize += primitive->channelListCount; /* u8 primitive->channelList */
-    bufferSize += 2;                           /* u16 primitive->probeIeLength */
-    bufferSize += primitive->probeIeLength;    /* u8 primitive->probeIe */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeScanFullReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeScanFullReq *primitive = (CsrWifiSmeScanFullReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint8Ser(ptr, len, (u8) primitive->ssidCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->ssidCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->ssid[i1].ssid, ((u16) (32)));
-            CsrUint8Ser(ptr, len, (u8) primitive->ssid[i1].length);
-        }
-    }
-    CsrMemCpySer(ptr, len, (const void *) primitive->bssid.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->forceScan);
-    CsrUint8Ser(ptr, len, (u8) primitive->bssType);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanType);
-    CsrUint16Ser(ptr, len, (u16) primitive->channelListCount);
-    if (primitive->channelListCount)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->channelList, ((u16) (primitive->channelListCount)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->probeIeLength);
-    if (primitive->probeIeLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->probeIe, ((u16) (primitive->probeIeLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeScanFullReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeScanFullReq *primitive = kmalloc(sizeof(CsrWifiSmeScanFullReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ssidCount, buffer, &offset);
-    primitive->ssid = NULL;
-    if (primitive->ssidCount)
-    {
-        primitive->ssid = kmalloc(sizeof(CsrWifiSsid) * primitive->ssidCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->ssidCount; i1++)
-        {
-            CsrMemCpyDes(primitive->ssid[i1].ssid, buffer, &offset, ((u16) (32)));
-            CsrUint8Des((u8 *) &primitive->ssid[i1].length, buffer, &offset);
-        }
-    }
-    CsrMemCpyDes(primitive->bssid.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->forceScan, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->bssType, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanType, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->channelListCount, buffer, &offset);
-    if (primitive->channelListCount)
-    {
-        primitive->channelList = kmalloc(primitive->channelListCount, GFP_KERNEL);
-        CsrMemCpyDes(primitive->channelList, buffer, &offset, ((u16) (primitive->channelListCount)));
-    }
-    else
-    {
-        primitive->channelList = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->probeIeLength, buffer, &offset);
-    if (primitive->probeIeLength)
-    {
-        primitive->probeIe = kmalloc(primitive->probeIeLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->probeIe, buffer, &offset, ((u16) (primitive->probeIeLength)));
-    }
-    else
-    {
-        primitive->probeIe = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeScanFullReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeScanFullReq *primitive = (CsrWifiSmeScanFullReq *) voidPrimitivePointer;
-    kfree(primitive->ssid);
-    kfree(primitive->channelList);
-    kfree(primitive->probeIe);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* u8 primitive->smeConfig.connectionQualityRssiChangeTrigger */
-    bufferSize += 1; /* u8 primitive->smeConfig.connectionQualitySnrChangeTrigger */
-    bufferSize += 1; /* CsrWifiSmeWmmModeMask primitive->smeConfig.wmmModeMask */
-    bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */
-    bufferSize += 1; /* u8 primitive->smeConfig.allowUnicastUseGroupCipher */
-    bufferSize += 1; /* u8 primitive->smeConfig.enableOpportunisticKeyCaching */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeSmeStaConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeSmeStaConfigSetReq *primitive = (CsrWifiSmeSmeStaConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.connectionQualityRssiChangeTrigger);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.connectionQualitySnrChangeTrigger);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.wmmModeMask);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.ifIndex);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.allowUnicastUseGroupCipher);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.enableOpportunisticKeyCaching);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeSmeStaConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeSmeStaConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmeSmeStaConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.connectionQualityRssiChangeTrigger, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.connectionQualitySnrChangeTrigger, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.wmmModeMask, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.ifIndex, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.allowUnicastUseGroupCipher, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.enableOpportunisticKeyCaching, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeTspecReqSizeof(void *msg)
-{
-    CsrWifiSmeTspecReq *primitive = (CsrWifiSmeTspecReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 18) */
-    bufferSize += 2;                      /* u16 primitive->interfaceTag */
-    bufferSize += 1;                      /* CsrWifiSmeListAction primitive->action */
-    bufferSize += 4;                      /* u32 primitive->transactionId */
-    bufferSize += 1;                      /* u8 primitive->strict */
-    bufferSize += 1;                      /* CsrWifiSmeTspecCtrlMask primitive->ctrlMask */
-    bufferSize += 2;                      /* u16 primitive->tspecLength */
-    bufferSize += primitive->tspecLength; /* u8 primitive->tspec */
-    bufferSize += 2;                      /* u16 primitive->tclasLength */
-    bufferSize += primitive->tclasLength; /* u8 primitive->tclas */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeTspecReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeTspecReq *primitive = (CsrWifiSmeTspecReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint32Ser(ptr, len, (u32) primitive->transactionId);
-    CsrUint8Ser(ptr, len, (u8) primitive->strict);
-    CsrUint8Ser(ptr, len, (u8) primitive->ctrlMask);
-    CsrUint16Ser(ptr, len, (u16) primitive->tspecLength);
-    if (primitive->tspecLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->tspec, ((u16) (primitive->tspecLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->tclasLength);
-    if (primitive->tclasLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->tclas, ((u16) (primitive->tclasLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeTspecReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeTspecReq *primitive = kmalloc(sizeof(CsrWifiSmeTspecReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->transactionId, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->strict, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ctrlMask, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->tspecLength, buffer, &offset);
-    if (primitive->tspecLength)
-    {
-        primitive->tspec = kmalloc(primitive->tspecLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->tspec, buffer, &offset, ((u16) (primitive->tspecLength)));
-    }
-    else
-    {
-        primitive->tspec = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->tclasLength, buffer, &offset);
-    if (primitive->tclasLength)
-    {
-        primitive->tclas = kmalloc(primitive->tclasLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->tclas, buffer, &offset, ((u16) (primitive->tclasLength)));
-    }
-    else
-    {
-        primitive->tclas = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeTspecReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeTspecReq *primitive = (CsrWifiSmeTspecReq *) voidPrimitivePointer;
-    kfree(primitive->tspec);
-    kfree(primitive->tclas);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeWifiFlightmodeReqSizeof(void *msg)
-{
-    CsrWifiSmeWifiFlightmodeReq *primitive = (CsrWifiSmeWifiFlightmodeReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 14) */
-    bufferSize += 6; /* u8 primitive->address.a[6] */
-    bufferSize += 2; /* u16 primitive->mibFilesCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->mibFilesCount; i1++)
-        {
-            bufferSize += 2;                              /* u16 primitive->mibFiles[i1].length */
-            bufferSize += primitive->mibFiles[i1].length; /* u8 primitive->mibFiles[i1].data */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeWifiFlightmodeReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeWifiFlightmodeReq *primitive = (CsrWifiSmeWifiFlightmodeReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((u16) (6)));
-    CsrUint16Ser(ptr, len, (u16) primitive->mibFilesCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->mibFilesCount; i1++)
-        {
-            CsrUint16Ser(ptr, len, (u16) primitive->mibFiles[i1].length);
-            if (primitive->mibFiles[i1].length)
-            {
-                CsrMemCpySer(ptr, len, (const void *) primitive->mibFiles[i1].data, ((u16) (primitive->mibFiles[i1].length)));
-            }
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeWifiFlightmodeReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeWifiFlightmodeReq *primitive = kmalloc(sizeof(CsrWifiSmeWifiFlightmodeReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrMemCpyDes(primitive->address.a, buffer, &offset, ((u16) (6)));
-    CsrUint16Des((u16 *) &primitive->mibFilesCount, buffer, &offset);
-    primitive->mibFiles = NULL;
-    if (primitive->mibFilesCount)
-    {
-        primitive->mibFiles = kmalloc(sizeof(CsrWifiSmeDataBlock) * primitive->mibFilesCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->mibFilesCount; i1++)
-        {
-            CsrUint16Des((u16 *) &primitive->mibFiles[i1].length, buffer, &offset);
-            if (primitive->mibFiles[i1].length)
-            {
-                primitive->mibFiles[i1].data = kmalloc(primitive->mibFiles[i1].length, GFP_KERNEL);
-                CsrMemCpyDes(primitive->mibFiles[i1].data, buffer, &offset, ((u16) (primitive->mibFiles[i1].length)));
-            }
-            else
-            {
-                primitive->mibFiles[i1].data = NULL;
-            }
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeWifiFlightmodeReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeWifiFlightmodeReq *primitive = (CsrWifiSmeWifiFlightmodeReq *) voidPrimitivePointer;
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->mibFilesCount; i1++)
-        {
-            kfree(primitive->mibFiles[i1].data);
-        }
-    }
-    kfree(primitive->mibFiles);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeWifiOnReqSizeof(void *msg)
-{
-    CsrWifiSmeWifiOnReq *primitive = (CsrWifiSmeWifiOnReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 14) */
-    bufferSize += 6; /* u8 primitive->address.a[6] */
-    bufferSize += 2; /* u16 primitive->mibFilesCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->mibFilesCount; i1++)
-        {
-            bufferSize += 2;                              /* u16 primitive->mibFiles[i1].length */
-            bufferSize += primitive->mibFiles[i1].length; /* u8 primitive->mibFiles[i1].data */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeWifiOnReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeWifiOnReq *primitive = (CsrWifiSmeWifiOnReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((u16) (6)));
-    CsrUint16Ser(ptr, len, (u16) primitive->mibFilesCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->mibFilesCount; i1++)
-        {
-            CsrUint16Ser(ptr, len, (u16) primitive->mibFiles[i1].length);
-            if (primitive->mibFiles[i1].length)
-            {
-                CsrMemCpySer(ptr, len, (const void *) primitive->mibFiles[i1].data, ((u16) (primitive->mibFiles[i1].length)));
-            }
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeWifiOnReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeWifiOnReq *primitive = kmalloc(sizeof(CsrWifiSmeWifiOnReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrMemCpyDes(primitive->address.a, buffer, &offset, ((u16) (6)));
-    CsrUint16Des((u16 *) &primitive->mibFilesCount, buffer, &offset);
-    primitive->mibFiles = NULL;
-    if (primitive->mibFilesCount)
-    {
-        primitive->mibFiles = kmalloc(sizeof(CsrWifiSmeDataBlock) * primitive->mibFilesCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->mibFilesCount; i1++)
-        {
-            CsrUint16Des((u16 *) &primitive->mibFiles[i1].length, buffer, &offset);
-            if (primitive->mibFiles[i1].length)
-            {
-                primitive->mibFiles[i1].data = kmalloc(primitive->mibFiles[i1].length, GFP_KERNEL);
-                CsrMemCpyDes(primitive->mibFiles[i1].data, buffer, &offset, ((u16) (primitive->mibFiles[i1].length)));
-            }
-            else
-            {
-                primitive->mibFiles[i1].data = NULL;
-            }
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeWifiOnReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeWifiOnReq *primitive = (CsrWifiSmeWifiOnReq *) voidPrimitivePointer;
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->mibFilesCount; i1++)
-        {
-            kfree(primitive->mibFiles[i1].data);
-        }
-    }
-    kfree(primitive->mibFiles);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeCloakedSsidsSetReqSizeof(void *msg)
-{
-    CsrWifiSmeCloakedSsidsSetReq *primitive = (CsrWifiSmeCloakedSsidsSetReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 37) */
-    bufferSize += 1; /* u8 primitive->cloakedSsids.cloakedSsidsCount */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++)
-        {
-            bufferSize += 32; /* u8 primitive->cloakedSsids.cloakedSsids[i2].ssid[32] */
-            bufferSize += 1;  /* u8 primitive->cloakedSsids.cloakedSsids[i2].length */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCloakedSsidsSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCloakedSsidsSetReq *primitive = (CsrWifiSmeCloakedSsidsSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint8Ser(ptr, len, (u8) primitive->cloakedSsids.cloakedSsidsCount);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->cloakedSsids.cloakedSsids[i2].ssid, ((u16) (32)));
-            CsrUint8Ser(ptr, len, (u8) primitive->cloakedSsids.cloakedSsids[i2].length);
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCloakedSsidsSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCloakedSsidsSetReq *primitive = kmalloc(sizeof(CsrWifiSmeCloakedSsidsSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->cloakedSsids.cloakedSsidsCount, buffer, &offset);
-    primitive->cloakedSsids.cloakedSsids = NULL;
-    if (primitive->cloakedSsids.cloakedSsidsCount)
-    {
-        primitive->cloakedSsids.cloakedSsids = kmalloc(sizeof(CsrWifiSsid) * primitive->cloakedSsids.cloakedSsidsCount, GFP_KERNEL);
-    }
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++)
-        {
-            CsrMemCpyDes(primitive->cloakedSsids.cloakedSsids[i2].ssid, buffer, &offset, ((u16) (32)));
-            CsrUint8Des((u8 *) &primitive->cloakedSsids.cloakedSsids[i2].length, buffer, &offset);
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeCloakedSsidsSetReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeCloakedSsidsSetReq *primitive = (CsrWifiSmeCloakedSsidsSetReq *) voidPrimitivePointer;
-    kfree(primitive->cloakedSsids.cloakedSsids);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeSmeCommonConfigSetReqSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 1; /* CsrWifiSme80211dTrustLevel primitive->deviceConfig.trustLevel */
-    bufferSize += 2; /* u8 primitive->deviceConfig.countryCode[2] */
-    bufferSize += 1; /* CsrWifiSmeFirmwareDriverInterface primitive->deviceConfig.firmwareDriverInterface */
-    bufferSize += 1; /* u8 primitive->deviceConfig.enableStrictDraftN */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeSmeCommonConfigSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeSmeCommonConfigSetReq *primitive = (CsrWifiSmeSmeCommonConfigSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint8Ser(ptr, len, (u8) primitive->deviceConfig.trustLevel);
-    CsrMemCpySer(ptr, len, (const void *) primitive->deviceConfig.countryCode, ((u16) (2)));
-    CsrUint8Ser(ptr, len, (u8) primitive->deviceConfig.firmwareDriverInterface);
-    CsrUint8Ser(ptr, len, (u8) primitive->deviceConfig.enableStrictDraftN);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeSmeCommonConfigSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeSmeCommonConfigSetReq *primitive = kmalloc(sizeof(CsrWifiSmeSmeCommonConfigSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->deviceConfig.trustLevel, buffer, &offset);
-    CsrMemCpyDes(primitive->deviceConfig.countryCode, buffer, &offset, ((u16) (2)));
-    CsrUint8Des((u8 *) &primitive->deviceConfig.firmwareDriverInterface, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->deviceConfig.enableStrictDraftN, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeWpsConfigurationReqSizeof(void *msg)
-{
-    CsrWifiSmeWpsConfigurationReq *primitive = (CsrWifiSmeWpsConfigurationReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 240) */
-    bufferSize += 1;  /* u8 primitive->wpsConfig.wpsVersion */
-    bufferSize += 16; /* u8 primitive->wpsConfig.uuid[16] */
-    bufferSize += 32; /* u8 primitive->wpsConfig.deviceName[32] */
-    bufferSize += 1;  /* u8 primitive->wpsConfig.deviceNameLength */
-    bufferSize += 64; /* u8 primitive->wpsConfig.manufacturer[64] */
-    bufferSize += 1;  /* u8 primitive->wpsConfig.manufacturerLength */
-    bufferSize += 32; /* u8 primitive->wpsConfig.modelName[32] */
-    bufferSize += 1;  /* u8 primitive->wpsConfig.modelNameLength */
-    bufferSize += 32; /* u8 primitive->wpsConfig.modelNumber[32] */
-    bufferSize += 1;  /* u8 primitive->wpsConfig.modelNumberLength */
-    bufferSize += 32; /* u8 primitive->wpsConfig.serialNumber[32] */
-    bufferSize += 8;  /* u8 primitive->wpsConfig.primDeviceType.deviceDetails[8] */
-    bufferSize += 1;  /* u8 primitive->wpsConfig.secondaryDeviceTypeCount */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->wpsConfig.secondaryDeviceTypeCount; i2++)
-        {
-            bufferSize += 8; /* u8 primitive->wpsConfig.secondaryDeviceType[i2].deviceDetails[8] */
-        }
-    }
-    bufferSize += 2;         /* CsrWifiSmeWpsConfigTypeMask primitive->wpsConfig.configMethods */
-    bufferSize += 1;         /* u8 primitive->wpsConfig.rfBands */
-    bufferSize += 4;         /* u8 primitive->wpsConfig.osVersion[4] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeWpsConfigurationReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeWpsConfigurationReq *primitive = (CsrWifiSmeWpsConfigurationReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint8Ser(ptr, len, (u8) primitive->wpsConfig.wpsVersion);
-    CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.uuid, ((u16) (16)));
-    CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.deviceName, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->wpsConfig.deviceNameLength);
-    CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.manufacturer, ((u16) (64)));
-    CsrUint8Ser(ptr, len, (u8) primitive->wpsConfig.manufacturerLength);
-    CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.modelName, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->wpsConfig.modelNameLength);
-    CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.modelNumber, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->wpsConfig.modelNumberLength);
-    CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.serialNumber, ((u16) (32)));
-    CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.primDeviceType.deviceDetails, ((u16) (8)));
-    CsrUint8Ser(ptr, len, (u8) primitive->wpsConfig.secondaryDeviceTypeCount);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->wpsConfig.secondaryDeviceTypeCount; i2++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.secondaryDeviceType[i2].deviceDetails, ((u16) (8)));
-        }
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->wpsConfig.configMethods);
-    CsrUint8Ser(ptr, len, (u8) primitive->wpsConfig.rfBands);
-    CsrMemCpySer(ptr, len, (const void *) primitive->wpsConfig.osVersion, ((u16) (4)));
-    return(ptr);
-}
-
-
-void* CsrWifiSmeWpsConfigurationReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeWpsConfigurationReq *primitive = kmalloc(sizeof(CsrWifiSmeWpsConfigurationReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->wpsConfig.wpsVersion, buffer, &offset);
-    CsrMemCpyDes(primitive->wpsConfig.uuid, buffer, &offset, ((u16) (16)));
-    CsrMemCpyDes(primitive->wpsConfig.deviceName, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->wpsConfig.deviceNameLength, buffer, &offset);
-    CsrMemCpyDes(primitive->wpsConfig.manufacturer, buffer, &offset, ((u16) (64)));
-    CsrUint8Des((u8 *) &primitive->wpsConfig.manufacturerLength, buffer, &offset);
-    CsrMemCpyDes(primitive->wpsConfig.modelName, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->wpsConfig.modelNameLength, buffer, &offset);
-    CsrMemCpyDes(primitive->wpsConfig.modelNumber, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->wpsConfig.modelNumberLength, buffer, &offset);
-    CsrMemCpyDes(primitive->wpsConfig.serialNumber, buffer, &offset, ((u16) (32)));
-    CsrMemCpyDes(primitive->wpsConfig.primDeviceType.deviceDetails, buffer, &offset, ((u16) (8)));
-    CsrUint8Des((u8 *) &primitive->wpsConfig.secondaryDeviceTypeCount, buffer, &offset);
-    primitive->wpsConfig.secondaryDeviceType = NULL;
-    if (primitive->wpsConfig.secondaryDeviceTypeCount)
-    {
-        primitive->wpsConfig.secondaryDeviceType = kmalloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->wpsConfig.secondaryDeviceTypeCount, GFP_KERNEL);
-    }
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->wpsConfig.secondaryDeviceTypeCount; i2++)
-        {
-            CsrMemCpyDes(primitive->wpsConfig.secondaryDeviceType[i2].deviceDetails, buffer, &offset, ((u16) (8)));
-        }
-    }
-    CsrUint16Des((u16 *) &primitive->wpsConfig.configMethods, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->wpsConfig.rfBands, buffer, &offset);
-    CsrMemCpyDes(primitive->wpsConfig.osVersion, buffer, &offset, ((u16) (4)));
-
-    return primitive;
-}
-
-
-void CsrWifiSmeWpsConfigurationReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeWpsConfigurationReq *primitive = (CsrWifiSmeWpsConfigurationReq *) voidPrimitivePointer;
-    kfree(primitive->wpsConfig.secondaryDeviceType);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeSetReqSizeof(void *msg)
-{
-    CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 4;                     /* u32 primitive->dataLength */
-    bufferSize += primitive->dataLength; /* u8 primitive->data */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeSetReqSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint32Ser(ptr, len, (u32) primitive->dataLength);
-    if (primitive->dataLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->data, ((u16) (primitive->dataLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeSetReqDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeSetReq *primitive = kmalloc(sizeof(CsrWifiSmeSetReq), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->dataLength, buffer, &offset);
-    if (primitive->dataLength)
-    {
-        primitive->data = kmalloc(primitive->dataLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->data, buffer, &offset, ((u16) (primitive->dataLength)));
-    }
-    else
-    {
-        primitive->data = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeSetReqSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) voidPrimitivePointer;
-    kfree(primitive->data);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 2; /* u16 primitive->adHocConfig.atimWindowTu */
-    bufferSize += 2; /* u16 primitive->adHocConfig.beaconPeriodTu */
-    bufferSize += 2; /* u16 primitive->adHocConfig.joinOnlyAttempts */
-    bufferSize += 2; /* u16 primitive->adHocConfig.joinAttemptIntervalMs */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeAdhocConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeAdhocConfigGetCfm *primitive = (CsrWifiSmeAdhocConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint16Ser(ptr, len, (u16) primitive->adHocConfig.atimWindowTu);
-    CsrUint16Ser(ptr, len, (u16) primitive->adHocConfig.beaconPeriodTu);
-    CsrUint16Ser(ptr, len, (u16) primitive->adHocConfig.joinOnlyAttempts);
-    CsrUint16Ser(ptr, len, (u16) primitive->adHocConfig.joinAttemptIntervalMs);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeAdhocConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeAdhocConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeAdhocConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->adHocConfig.atimWindowTu, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->adHocConfig.beaconPeriodTu, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->adHocConfig.joinOnlyAttempts, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->adHocConfig.joinAttemptIntervalMs, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeAssociationCompleteIndSizeof(void *msg)
-{
-    CsrWifiSmeAssociationCompleteInd *primitive = (CsrWifiSmeAssociationCompleteInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 98) */
-    bufferSize += 2;                                                     /* u16 primitive->interfaceTag */
-    bufferSize += 2;                                                     /* CsrResult primitive->status */
-    bufferSize += 32;                                                    /* u8 primitive->connectionInfo.ssid.ssid[32] */
-    bufferSize += 1;                                                     /* u8 primitive->connectionInfo.ssid.length */
-    bufferSize += 6;                                                     /* u8 primitive->connectionInfo.bssid.a[6] */
-    bufferSize += 1;                                                     /* CsrWifiSme80211NetworkType primitive->connectionInfo.networkType80211 */
-    bufferSize += 1;                                                     /* u8 primitive->connectionInfo.channelNumber */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.channelFrequency */
-    bufferSize += 2;                                                     /* CsrWifiSmeAuthMode primitive->connectionInfo.authMode */
-    bufferSize += 2;                                                     /* CsrWifiSmeEncryption primitive->connectionInfo.pairwiseCipher */
-    bufferSize += 2;                                                     /* CsrWifiSmeEncryption primitive->connectionInfo.groupCipher */
-    bufferSize += 1;                                                     /* CsrWifiSmeRadioIF primitive->connectionInfo.ifIndex */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.atimWindowTu */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.beaconPeriodTu */
-    bufferSize += 1;                                                     /* u8 primitive->connectionInfo.reassociation */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.beaconFrameLength */
-    bufferSize += primitive->connectionInfo.beaconFrameLength;           /* u8 primitive->connectionInfo.beaconFrame */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.associationReqFrameLength */
-    bufferSize += primitive->connectionInfo.associationReqFrameLength;   /* u8 primitive->connectionInfo.associationReqFrame */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.associationRspFrameLength */
-    bufferSize += primitive->connectionInfo.associationRspFrameLength;   /* u8 primitive->connectionInfo.associationRspFrame */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocScanInfoElementsLength */
-    bufferSize += primitive->connectionInfo.assocScanInfoElementsLength; /* u8 primitive->connectionInfo.assocScanInfoElements */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocReqCapabilities */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocReqListenIntervalTu */
-    bufferSize += 6;                                                     /* u8 primitive->connectionInfo.assocReqApAddress.a[6] */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocReqInfoElementsLength */
-    bufferSize += primitive->connectionInfo.assocReqInfoElementsLength;  /* u8 primitive->connectionInfo.assocReqInfoElements */
-    bufferSize += 2;                                                     /* CsrWifiSmeIEEE80211Result primitive->connectionInfo.assocRspResult */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocRspCapabilityInfo */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocRspAssociationId */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocRspInfoElementsLength */
-    bufferSize += primitive->connectionInfo.assocRspInfoElementsLength;  /* u8 primitive->connectionInfo.assocRspInfoElements */
-    bufferSize += 2;                                                     /* CsrWifiSmeIEEE80211Reason primitive->deauthReason */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeAssociationCompleteIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeAssociationCompleteInd *primitive = (CsrWifiSmeAssociationCompleteInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.ssid.ssid, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.ssid.length);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.bssid.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.networkType80211);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.channelNumber);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.channelFrequency);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.authMode);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.pairwiseCipher);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.groupCipher);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.ifIndex);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.atimWindowTu);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.beaconPeriodTu);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.reassociation);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.beaconFrameLength);
-    if (primitive->connectionInfo.beaconFrameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.beaconFrame, ((u16) (primitive->connectionInfo.beaconFrameLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.associationReqFrameLength);
-    if (primitive->connectionInfo.associationReqFrameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationReqFrame, ((u16) (primitive->connectionInfo.associationReqFrameLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.associationRspFrameLength);
-    if (primitive->connectionInfo.associationRspFrameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationRspFrame, ((u16) (primitive->connectionInfo.associationRspFrameLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocScanInfoElementsLength);
-    if (primitive->connectionInfo.assocScanInfoElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocScanInfoElements, ((u16) (primitive->connectionInfo.assocScanInfoElementsLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocReqCapabilities);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocReqListenIntervalTu);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqApAddress.a, ((u16) (6)));
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocReqInfoElementsLength);
-    if (primitive->connectionInfo.assocReqInfoElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqInfoElements, ((u16) (primitive->connectionInfo.assocReqInfoElementsLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspResult);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspCapabilityInfo);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspAssociationId);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspInfoElementsLength);
-    if (primitive->connectionInfo.assocRspInfoElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocRspInfoElements, ((u16) (primitive->connectionInfo.assocRspInfoElementsLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->deauthReason);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeAssociationCompleteIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeAssociationCompleteInd *primitive = kmalloc(sizeof(CsrWifiSmeAssociationCompleteInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionInfo.ssid.ssid, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->connectionInfo.ssid.length, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionInfo.bssid.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->connectionInfo.networkType80211, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionInfo.channelNumber, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.channelFrequency, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.authMode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.pairwiseCipher, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.groupCipher, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionInfo.ifIndex, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.atimWindowTu, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.beaconPeriodTu, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionInfo.reassociation, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.beaconFrameLength, buffer, &offset);
-    if (primitive->connectionInfo.beaconFrameLength)
-    {
-        primitive->connectionInfo.beaconFrame = kmalloc(primitive->connectionInfo.beaconFrameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.beaconFrame, buffer, &offset, ((u16) (primitive->connectionInfo.beaconFrameLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.beaconFrame = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.associationReqFrameLength, buffer, &offset);
-    if (primitive->connectionInfo.associationReqFrameLength)
-    {
-        primitive->connectionInfo.associationReqFrame = kmalloc(primitive->connectionInfo.associationReqFrameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.associationReqFrame, buffer, &offset, ((u16) (primitive->connectionInfo.associationReqFrameLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.associationReqFrame = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.associationRspFrameLength, buffer, &offset);
-    if (primitive->connectionInfo.associationRspFrameLength)
-    {
-        primitive->connectionInfo.associationRspFrame = kmalloc(primitive->connectionInfo.associationRspFrameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.associationRspFrame, buffer, &offset, ((u16) (primitive->connectionInfo.associationRspFrameLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.associationRspFrame = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocScanInfoElementsLength, buffer, &offset);
-    if (primitive->connectionInfo.assocScanInfoElementsLength)
-    {
-        primitive->connectionInfo.assocScanInfoElements = kmalloc(primitive->connectionInfo.assocScanInfoElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.assocScanInfoElements, buffer, &offset, ((u16) (primitive->connectionInfo.assocScanInfoElementsLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.assocScanInfoElements = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocReqCapabilities, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocReqListenIntervalTu, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionInfo.assocReqApAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocReqInfoElementsLength, buffer, &offset);
-    if (primitive->connectionInfo.assocReqInfoElementsLength)
-    {
-        primitive->connectionInfo.assocReqInfoElements = kmalloc(primitive->connectionInfo.assocReqInfoElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.assocReqInfoElements, buffer, &offset, ((u16) (primitive->connectionInfo.assocReqInfoElementsLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.assocReqInfoElements = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspResult, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspCapabilityInfo, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspAssociationId, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspInfoElementsLength, buffer, &offset);
-    if (primitive->connectionInfo.assocRspInfoElementsLength)
-    {
-        primitive->connectionInfo.assocRspInfoElements = kmalloc(primitive->connectionInfo.assocRspInfoElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.assocRspInfoElements, buffer, &offset, ((u16) (primitive->connectionInfo.assocRspInfoElementsLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.assocRspInfoElements = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->deauthReason, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiSmeAssociationCompleteIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeAssociationCompleteInd *primitive = (CsrWifiSmeAssociationCompleteInd *) voidPrimitivePointer;
-    kfree(primitive->connectionInfo.beaconFrame);
-    kfree(primitive->connectionInfo.associationReqFrame);
-    kfree(primitive->connectionInfo.associationRspFrame);
-    kfree(primitive->connectionInfo.assocScanInfoElements);
-    kfree(primitive->connectionInfo.assocReqInfoElements);
-    kfree(primitive->connectionInfo.assocRspInfoElements);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeAssociationStartIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 44) */
-    bufferSize += 2;  /* u16 primitive->interfaceTag */
-    bufferSize += 6;  /* u8 primitive->address.a[6] */
-    bufferSize += 32; /* u8 primitive->ssid.ssid[32] */
-    bufferSize += 1;  /* u8 primitive->ssid.length */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeAssociationStartIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeAssociationStartInd *primitive = (CsrWifiSmeAssociationStartInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((u16) (6)));
-    CsrMemCpySer(ptr, len, (const void *) primitive->ssid.ssid, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->ssid.length);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeAssociationStartIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeAssociationStartInd *primitive = kmalloc(sizeof(CsrWifiSmeAssociationStartInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrMemCpyDes(primitive->address.a, buffer, &offset, ((u16) (6)));
-    CsrMemCpyDes(primitive->ssid.ssid, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->ssid.length, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeBlacklistCfmSizeof(void *msg)
-{
-    CsrWifiSmeBlacklistCfm *primitive = (CsrWifiSmeBlacklistCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* CsrWifiSmeListAction primitive->action */
-    bufferSize += 1; /* u8 primitive->getAddressCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getAddressCount; i1++)
-        {
-            bufferSize += 6; /* u8 primitive->getAddresses[i1].a[6] */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeBlacklistCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeBlacklistCfm *primitive = (CsrWifiSmeBlacklistCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->getAddressCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getAddressCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->getAddresses[i1].a, ((u16) (6)));
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeBlacklistCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeBlacklistCfm *primitive = kmalloc(sizeof(CsrWifiSmeBlacklistCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->getAddressCount, buffer, &offset);
-    primitive->getAddresses = NULL;
-    if (primitive->getAddressCount)
-    {
-        primitive->getAddresses = kmalloc(sizeof(CsrWifiMacAddress) * primitive->getAddressCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getAddressCount; i1++)
-        {
-            CsrMemCpyDes(primitive->getAddresses[i1].a, buffer, &offset, ((u16) (6)));
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeBlacklistCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeBlacklistCfm *primitive = (CsrWifiSmeBlacklistCfm *) voidPrimitivePointer;
-    kfree(primitive->getAddresses);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeCalibrationDataGetCfmSizeof(void *msg)
-{
-    CsrWifiSmeCalibrationDataGetCfm *primitive = (CsrWifiSmeCalibrationDataGetCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2;                                /* CsrResult primitive->status */
-    bufferSize += 2;                                /* u16 primitive->calibrationDataLength */
-    bufferSize += primitive->calibrationDataLength; /* u8 primitive->calibrationData */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCalibrationDataGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCalibrationDataGetCfm *primitive = (CsrWifiSmeCalibrationDataGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint16Ser(ptr, len, (u16) primitive->calibrationDataLength);
-    if (primitive->calibrationDataLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->calibrationData, ((u16) (primitive->calibrationDataLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCalibrationDataGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCalibrationDataGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeCalibrationDataGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->calibrationDataLength, buffer, &offset);
-    if (primitive->calibrationDataLength)
-    {
-        primitive->calibrationData = kmalloc(primitive->calibrationDataLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->calibrationData, buffer, &offset, ((u16) (primitive->calibrationDataLength)));
-    }
-    else
-    {
-        primitive->calibrationData = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeCalibrationDataGetCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeCalibrationDataGetCfm *primitive = (CsrWifiSmeCalibrationDataGetCfm *) voidPrimitivePointer;
-    kfree(primitive->calibrationData);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeCcxConfigGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* u8 primitive->ccxConfig.keepAliveTimeMs */
-    bufferSize += 1; /* u8 primitive->ccxConfig.apRoamingEnabled */
-    bufferSize += 1; /* u8 primitive->ccxConfig.measurementsMask */
-    bufferSize += 1; /* u8 primitive->ccxConfig.ccxRadioMgtEnabled */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCcxConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCcxConfigGetCfm *primitive = (CsrWifiSmeCcxConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->ccxConfig.keepAliveTimeMs);
-    CsrUint8Ser(ptr, len, (u8) primitive->ccxConfig.apRoamingEnabled);
-    CsrUint8Ser(ptr, len, (u8) primitive->ccxConfig.measurementsMask);
-    CsrUint8Ser(ptr, len, (u8) primitive->ccxConfig.ccxRadioMgtEnabled);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCcxConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCcxConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeCcxConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ccxConfig.keepAliveTimeMs, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ccxConfig.apRoamingEnabled, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ccxConfig.measurementsMask, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->ccxConfig.ccxRadioMgtEnabled, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeCcxConfigSetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCcxConfigSetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCcxConfigSetCfm *primitive = (CsrWifiSmeCcxConfigSetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCcxConfigSetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCcxConfigSetCfm *primitive = kmalloc(sizeof(CsrWifiSmeCcxConfigSetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeCoexConfigGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 31) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* u8 primitive->coexConfig.coexEnableSchemeManagement */
-    bufferSize += 1; /* u8 primitive->coexConfig.coexPeriodicWakeHost */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexTrafficBurstyLatencyMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexTrafficContinuousLatencyMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexObexBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexObexBlackoutPeriodMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexA2dpBrBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexA2dpBrBlackoutPeriodMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexA2dpEdrBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexPagingBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexPagingBlackoutPeriodMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexInquiryBlackoutDurationMs */
-    bufferSize += 2; /* u16 primitive->coexConfig.coexInquiryBlackoutPeriodMs */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCoexConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCoexConfigGetCfm *primitive = (CsrWifiSmeCoexConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->coexConfig.coexEnableSchemeManagement);
-    CsrUint8Ser(ptr, len, (u8) primitive->coexConfig.coexPeriodicWakeHost);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexTrafficBurstyLatencyMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexTrafficContinuousLatencyMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexObexBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexObexBlackoutPeriodMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexA2dpBrBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexA2dpBrBlackoutPeriodMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexA2dpEdrBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexPagingBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexPagingBlackoutPeriodMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexInquiryBlackoutDurationMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexConfig.coexInquiryBlackoutPeriodMs);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCoexConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCoexConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeCoexConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->coexConfig.coexEnableSchemeManagement, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->coexConfig.coexPeriodicWakeHost, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexTrafficBurstyLatencyMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexTrafficContinuousLatencyMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexObexBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexObexBlackoutPeriodMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexA2dpBrBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexA2dpBrBlackoutPeriodMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexA2dpEdrBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexA2dpEdrBlackoutPeriodMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexPagingBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexPagingBlackoutPeriodMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexInquiryBlackoutDurationMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexConfig.coexInquiryBlackoutPeriodMs, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeCoexInfoGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 24) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* u8 primitive->coexInfo.hasTrafficData */
-    bufferSize += 1; /* CsrWifiSmeTrafficType primitive->coexInfo.currentTrafficType */
-    bufferSize += 2; /* u16 primitive->coexInfo.currentPeriodMs */
-    bufferSize += 1; /* CsrWifiSmePowerSaveLevel primitive->coexInfo.currentPowerSave */
-    bufferSize += 2; /* u16 primitive->coexInfo.currentCoexPeriodMs */
-    bufferSize += 2; /* u16 primitive->coexInfo.currentCoexLatencyMs */
-    bufferSize += 1; /* u8 primitive->coexInfo.hasBtDevice */
-    bufferSize += 4; /* u32 primitive->coexInfo.currentBlackoutDurationUs */
-    bufferSize += 4; /* u32 primitive->coexInfo.currentBlackoutPeriodUs */
-    bufferSize += 1; /* CsrWifiSmeCoexScheme primitive->coexInfo.currentCoexScheme */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCoexInfoGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCoexInfoGetCfm *primitive = (CsrWifiSmeCoexInfoGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->coexInfo.hasTrafficData);
-    CsrUint8Ser(ptr, len, (u8) primitive->coexInfo.currentTrafficType);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexInfo.currentPeriodMs);
-    CsrUint8Ser(ptr, len, (u8) primitive->coexInfo.currentPowerSave);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexInfo.currentCoexPeriodMs);
-    CsrUint16Ser(ptr, len, (u16) primitive->coexInfo.currentCoexLatencyMs);
-    CsrUint8Ser(ptr, len, (u8) primitive->coexInfo.hasBtDevice);
-    CsrUint32Ser(ptr, len, (u32) primitive->coexInfo.currentBlackoutDurationUs);
-    CsrUint32Ser(ptr, len, (u32) primitive->coexInfo.currentBlackoutPeriodUs);
-    CsrUint8Ser(ptr, len, (u8) primitive->coexInfo.currentCoexScheme);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCoexInfoGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCoexInfoGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeCoexInfoGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->coexInfo.hasTrafficData, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->coexInfo.currentTrafficType, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexInfo.currentPeriodMs, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->coexInfo.currentPowerSave, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexInfo.currentCoexPeriodMs, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->coexInfo.currentCoexLatencyMs, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->coexInfo.hasBtDevice, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->coexInfo.currentBlackoutDurationUs, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->coexInfo.currentBlackoutPeriodUs, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->coexInfo.currentCoexScheme, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeConnectCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeConnectCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeConnectCfm *primitive = (CsrWifiSmeConnectCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeConnectCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeConnectCfm *primitive = kmalloc(sizeof(CsrWifiSmeConnectCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeConnectionConfigGetCfmSizeof(void *msg)
-{
-    CsrWifiSmeConnectionConfigGetCfm *primitive = (CsrWifiSmeConnectionConfigGetCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 59) */
-    bufferSize += 2;                                                                     /* u16 primitive->interfaceTag */
-    bufferSize += 2;                                                                     /* CsrResult primitive->status */
-    bufferSize += 32;                                                                    /* u8 primitive->connectionConfig.ssid.ssid[32] */
-    bufferSize += 1;                                                                     /* u8 primitive->connectionConfig.ssid.length */
-    bufferSize += 6;                                                                     /* u8 primitive->connectionConfig.bssid.a[6] */
-    bufferSize += 1;                                                                     /* CsrWifiSmeBssType primitive->connectionConfig.bssType */
-    bufferSize += 1;                                                                     /* CsrWifiSmeRadioIF primitive->connectionConfig.ifIndex */
-    bufferSize += 1;                                                                     /* CsrWifiSme80211PrivacyMode primitive->connectionConfig.privacyMode */
-    bufferSize += 2;                                                                     /* CsrWifiSmeAuthModeMask primitive->connectionConfig.authModeMask */
-    bufferSize += 2;                                                                     /* CsrWifiSmeEncryptionMask primitive->connectionConfig.encryptionModeMask */
-    bufferSize += 2;                                                                     /* u16 primitive->connectionConfig.mlmeAssociateReqInformationElementsLength */
-    bufferSize += primitive->connectionConfig.mlmeAssociateReqInformationElementsLength; /* u8 primitive->connectionConfig.mlmeAssociateReqInformationElements */
-    bufferSize += 1;                                                                     /* CsrWifiSmeWmmQosInfoMask primitive->connectionConfig.wmmQosInfo */
-    bufferSize += 1;                                                                     /* u8 primitive->connectionConfig.adhocJoinOnly */
-    bufferSize += 1;                                                                     /* u8 primitive->connectionConfig.adhocChannel */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeConnectionConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeConnectionConfigGetCfm *primitive = (CsrWifiSmeConnectionConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.ssid.ssid, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.ssid.length);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.bssid.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.bssType);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.ifIndex);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.privacyMode);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionConfig.authModeMask);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionConfig.encryptionModeMask);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionConfig.mlmeAssociateReqInformationElementsLength);
-    if (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionConfig.mlmeAssociateReqInformationElements, ((u16) (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength)));
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.wmmQosInfo);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.adhocJoinOnly);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionConfig.adhocChannel);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeConnectionConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeConnectionConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeConnectionConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionConfig.ssid.ssid, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->connectionConfig.ssid.length, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionConfig.bssid.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->connectionConfig.bssType, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionConfig.ifIndex, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionConfig.privacyMode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionConfig.authModeMask, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionConfig.encryptionModeMask, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionConfig.mlmeAssociateReqInformationElementsLength, buffer, &offset);
-    if (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength)
-    {
-        primitive->connectionConfig.mlmeAssociateReqInformationElements = kmalloc(primitive->connectionConfig.mlmeAssociateReqInformationElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionConfig.mlmeAssociateReqInformationElements, buffer, &offset, ((u16) (primitive->connectionConfig.mlmeAssociateReqInformationElementsLength)));
-    }
-    else
-    {
-        primitive->connectionConfig.mlmeAssociateReqInformationElements = NULL;
-    }
-    CsrUint8Des((u8 *) &primitive->connectionConfig.wmmQosInfo, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionConfig.adhocJoinOnly, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionConfig.adhocChannel, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiSmeConnectionConfigGetCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeConnectionConfigGetCfm *primitive = (CsrWifiSmeConnectionConfigGetCfm *) voidPrimitivePointer;
-    kfree(primitive->connectionConfig.mlmeAssociateReqInformationElements);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeConnectionInfoGetCfmSizeof(void *msg)
-{
-    CsrWifiSmeConnectionInfoGetCfm *primitive = (CsrWifiSmeConnectionInfoGetCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 96) */
-    bufferSize += 2;                                                     /* u16 primitive->interfaceTag */
-    bufferSize += 2;                                                     /* CsrResult primitive->status */
-    bufferSize += 32;                                                    /* u8 primitive->connectionInfo.ssid.ssid[32] */
-    bufferSize += 1;                                                     /* u8 primitive->connectionInfo.ssid.length */
-    bufferSize += 6;                                                     /* u8 primitive->connectionInfo.bssid.a[6] */
-    bufferSize += 1;                                                     /* CsrWifiSme80211NetworkType primitive->connectionInfo.networkType80211 */
-    bufferSize += 1;                                                     /* u8 primitive->connectionInfo.channelNumber */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.channelFrequency */
-    bufferSize += 2;                                                     /* CsrWifiSmeAuthMode primitive->connectionInfo.authMode */
-    bufferSize += 2;                                                     /* CsrWifiSmeEncryption primitive->connectionInfo.pairwiseCipher */
-    bufferSize += 2;                                                     /* CsrWifiSmeEncryption primitive->connectionInfo.groupCipher */
-    bufferSize += 1;                                                     /* CsrWifiSmeRadioIF primitive->connectionInfo.ifIndex */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.atimWindowTu */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.beaconPeriodTu */
-    bufferSize += 1;                                                     /* u8 primitive->connectionInfo.reassociation */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.beaconFrameLength */
-    bufferSize += primitive->connectionInfo.beaconFrameLength;           /* u8 primitive->connectionInfo.beaconFrame */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.associationReqFrameLength */
-    bufferSize += primitive->connectionInfo.associationReqFrameLength;   /* u8 primitive->connectionInfo.associationReqFrame */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.associationRspFrameLength */
-    bufferSize += primitive->connectionInfo.associationRspFrameLength;   /* u8 primitive->connectionInfo.associationRspFrame */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocScanInfoElementsLength */
-    bufferSize += primitive->connectionInfo.assocScanInfoElementsLength; /* u8 primitive->connectionInfo.assocScanInfoElements */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocReqCapabilities */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocReqListenIntervalTu */
-    bufferSize += 6;                                                     /* u8 primitive->connectionInfo.assocReqApAddress.a[6] */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocReqInfoElementsLength */
-    bufferSize += primitive->connectionInfo.assocReqInfoElementsLength;  /* u8 primitive->connectionInfo.assocReqInfoElements */
-    bufferSize += 2;                                                     /* CsrWifiSmeIEEE80211Result primitive->connectionInfo.assocRspResult */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocRspCapabilityInfo */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocRspAssociationId */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocRspInfoElementsLength */
-    bufferSize += primitive->connectionInfo.assocRspInfoElementsLength;  /* u8 primitive->connectionInfo.assocRspInfoElements */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeConnectionInfoGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeConnectionInfoGetCfm *primitive = (CsrWifiSmeConnectionInfoGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.ssid.ssid, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.ssid.length);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.bssid.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.networkType80211);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.channelNumber);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.channelFrequency);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.authMode);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.pairwiseCipher);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.groupCipher);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.ifIndex);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.atimWindowTu);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.beaconPeriodTu);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.reassociation);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.beaconFrameLength);
-    if (primitive->connectionInfo.beaconFrameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.beaconFrame, ((u16) (primitive->connectionInfo.beaconFrameLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.associationReqFrameLength);
-    if (primitive->connectionInfo.associationReqFrameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationReqFrame, ((u16) (primitive->connectionInfo.associationReqFrameLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.associationRspFrameLength);
-    if (primitive->connectionInfo.associationRspFrameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationRspFrame, ((u16) (primitive->connectionInfo.associationRspFrameLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocScanInfoElementsLength);
-    if (primitive->connectionInfo.assocScanInfoElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocScanInfoElements, ((u16) (primitive->connectionInfo.assocScanInfoElementsLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocReqCapabilities);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocReqListenIntervalTu);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqApAddress.a, ((u16) (6)));
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocReqInfoElementsLength);
-    if (primitive->connectionInfo.assocReqInfoElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqInfoElements, ((u16) (primitive->connectionInfo.assocReqInfoElementsLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspResult);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspCapabilityInfo);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspAssociationId);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspInfoElementsLength);
-    if (primitive->connectionInfo.assocRspInfoElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocRspInfoElements, ((u16) (primitive->connectionInfo.assocRspInfoElementsLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeConnectionInfoGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeConnectionInfoGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeConnectionInfoGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionInfo.ssid.ssid, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->connectionInfo.ssid.length, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionInfo.bssid.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->connectionInfo.networkType80211, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionInfo.channelNumber, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.channelFrequency, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.authMode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.pairwiseCipher, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.groupCipher, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionInfo.ifIndex, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.atimWindowTu, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.beaconPeriodTu, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionInfo.reassociation, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.beaconFrameLength, buffer, &offset);
-    if (primitive->connectionInfo.beaconFrameLength)
-    {
-        primitive->connectionInfo.beaconFrame = kmalloc(primitive->connectionInfo.beaconFrameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.beaconFrame, buffer, &offset, ((u16) (primitive->connectionInfo.beaconFrameLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.beaconFrame = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.associationReqFrameLength, buffer, &offset);
-    if (primitive->connectionInfo.associationReqFrameLength)
-    {
-        primitive->connectionInfo.associationReqFrame = kmalloc(primitive->connectionInfo.associationReqFrameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.associationReqFrame, buffer, &offset, ((u16) (primitive->connectionInfo.associationReqFrameLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.associationReqFrame = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.associationRspFrameLength, buffer, &offset);
-    if (primitive->connectionInfo.associationRspFrameLength)
-    {
-        primitive->connectionInfo.associationRspFrame = kmalloc(primitive->connectionInfo.associationRspFrameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.associationRspFrame, buffer, &offset, ((u16) (primitive->connectionInfo.associationRspFrameLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.associationRspFrame = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocScanInfoElementsLength, buffer, &offset);
-    if (primitive->connectionInfo.assocScanInfoElementsLength)
-    {
-        primitive->connectionInfo.assocScanInfoElements = kmalloc(primitive->connectionInfo.assocScanInfoElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.assocScanInfoElements, buffer, &offset, ((u16) (primitive->connectionInfo.assocScanInfoElementsLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.assocScanInfoElements = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocReqCapabilities, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocReqListenIntervalTu, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionInfo.assocReqApAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocReqInfoElementsLength, buffer, &offset);
-    if (primitive->connectionInfo.assocReqInfoElementsLength)
-    {
-        primitive->connectionInfo.assocReqInfoElements = kmalloc(primitive->connectionInfo.assocReqInfoElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.assocReqInfoElements, buffer, &offset, ((u16) (primitive->connectionInfo.assocReqInfoElementsLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.assocReqInfoElements = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspResult, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspCapabilityInfo, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspAssociationId, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspInfoElementsLength, buffer, &offset);
-    if (primitive->connectionInfo.assocRspInfoElementsLength)
-    {
-        primitive->connectionInfo.assocRspInfoElements = kmalloc(primitive->connectionInfo.assocRspInfoElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.assocRspInfoElements, buffer, &offset, ((u16) (primitive->connectionInfo.assocRspInfoElementsLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.assocRspInfoElements = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeConnectionInfoGetCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeConnectionInfoGetCfm *primitive = (CsrWifiSmeConnectionInfoGetCfm *) voidPrimitivePointer;
-    kfree(primitive->connectionInfo.beaconFrame);
-    kfree(primitive->connectionInfo.associationReqFrame);
-    kfree(primitive->connectionInfo.associationRspFrame);
-    kfree(primitive->connectionInfo.assocScanInfoElements);
-    kfree(primitive->connectionInfo.assocReqInfoElements);
-    kfree(primitive->connectionInfo.assocRspInfoElements);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeConnectionQualityIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* s16 primitive->linkQuality.unifiRssi */
-    bufferSize += 2; /* s16 primitive->linkQuality.unifiSnr */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeConnectionQualityIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeConnectionQualityInd *primitive = (CsrWifiSmeConnectionQualityInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->linkQuality.unifiRssi);
-    CsrUint16Ser(ptr, len, (u16) primitive->linkQuality.unifiSnr);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeConnectionQualityIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeConnectionQualityInd *primitive = kmalloc(sizeof(CsrWifiSmeConnectionQualityInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->linkQuality.unifiRssi, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->linkQuality.unifiSnr, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeConnectionStatsGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 101) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* u8 primitive->connectionStats.unifiTxDataRate */
-    bufferSize += 1; /* u8 primitive->connectionStats.unifiRxDataRate */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11RetryCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11MultipleRetryCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11AckFailureCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11FrameDuplicateCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11FcsErrorCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11RtsSuccessCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11RtsFailureCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11FailedCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11TransmittedFragmentCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11TransmittedFrameCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11WepExcludedCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11WepIcvErrorCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11WepUndecryptableCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11MulticastReceivedFrameCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11MulticastTransmittedFrameCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11ReceivedFragmentCount */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11Rsna4WayHandshakeFailures */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11RsnaTkipCounterMeasuresInvoked */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11RsnaStatsTkipLocalMicFailures */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11RsnaStatsTkipReplays */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11RsnaStatsTkipIcvErrors */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11RsnaStatsCcmpReplays */
-    bufferSize += 4; /* u32 primitive->connectionStats.dot11RsnaStatsCcmpDecryptErrors */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeConnectionStatsGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeConnectionStatsGetCfm *primitive = (CsrWifiSmeConnectionStatsGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionStats.unifiTxDataRate);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionStats.unifiRxDataRate);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11RetryCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11MultipleRetryCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11AckFailureCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11FrameDuplicateCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11FcsErrorCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11RtsSuccessCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11RtsFailureCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11FailedCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11TransmittedFragmentCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11TransmittedFrameCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11WepExcludedCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11WepIcvErrorCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11WepUndecryptableCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11MulticastReceivedFrameCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11MulticastTransmittedFrameCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11ReceivedFragmentCount);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11Rsna4WayHandshakeFailures);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11RsnaTkipCounterMeasuresInvoked);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11RsnaStatsTkipLocalMicFailures);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11RsnaStatsTkipReplays);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11RsnaStatsTkipIcvErrors);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11RsnaStatsCcmpReplays);
-    CsrUint32Ser(ptr, len, (u32) primitive->connectionStats.dot11RsnaStatsCcmpDecryptErrors);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeConnectionStatsGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeConnectionStatsGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeConnectionStatsGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionStats.unifiTxDataRate, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionStats.unifiRxDataRate, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11RetryCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11MultipleRetryCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11AckFailureCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11FrameDuplicateCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11FcsErrorCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11RtsSuccessCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11RtsFailureCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11FailedCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11TransmittedFragmentCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11TransmittedFrameCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11WepExcludedCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11WepIcvErrorCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11WepUndecryptableCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11MulticastReceivedFrameCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11MulticastTransmittedFrameCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11ReceivedFragmentCount, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11Rsna4WayHandshakeFailures, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11RsnaTkipCounterMeasuresInvoked, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11RsnaStatsTkipLocalMicFailures, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11RsnaStatsTkipReplays, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11RsnaStatsTkipIcvErrors, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11RsnaStatsCcmpReplays, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->connectionStats.dot11RsnaStatsCcmpDecryptErrors, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeDisconnectCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeDisconnectCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeDisconnectCfm *primitive = (CsrWifiSmeDisconnectCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeDisconnectCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeDisconnectCfm *primitive = kmalloc(sizeof(CsrWifiSmeDisconnectCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeHostConfigGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* CsrWifiSmeHostPowerMode primitive->hostConfig.powerMode */
-    bufferSize += 2; /* u16 primitive->hostConfig.applicationDataPeriodMs */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeHostConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeHostConfigGetCfm *primitive = (CsrWifiSmeHostConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->hostConfig.powerMode);
-    CsrUint16Ser(ptr, len, (u16) primitive->hostConfig.applicationDataPeriodMs);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeHostConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeHostConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeHostConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->hostConfig.powerMode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->hostConfig.applicationDataPeriodMs, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeHostConfigSetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeHostConfigSetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeHostConfigSetCfm *primitive = (CsrWifiSmeHostConfigSetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeHostConfigSetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeHostConfigSetCfm *primitive = kmalloc(sizeof(CsrWifiSmeHostConfigSetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeIbssStationIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 6; /* u8 primitive->address.a[6] */
-    bufferSize += 1; /* u8 primitive->isconnected */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeIbssStationIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeIbssStationInd *primitive = (CsrWifiSmeIbssStationInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->isconnected);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeIbssStationIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeIbssStationInd *primitive = kmalloc(sizeof(CsrWifiSmeIbssStationInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrMemCpyDes(primitive->address.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->isconnected, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeKeyCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* CsrWifiSmeListAction primitive->action */
-    bufferSize += 1; /* CsrWifiSmeKeyType primitive->keyType */
-    bufferSize += 6; /* u8 primitive->peerMacAddress.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeKeyCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeKeyCfm *primitive = (CsrWifiSmeKeyCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->keyType);
-    CsrMemCpySer(ptr, len, (const void *) primitive->peerMacAddress.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiSmeKeyCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeKeyCfm *primitive = kmalloc(sizeof(CsrWifiSmeKeyCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->keyType, buffer, &offset);
-    CsrMemCpyDes(primitive->peerMacAddress.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeLinkQualityGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 2; /* s16 primitive->linkQuality.unifiRssi */
-    bufferSize += 2; /* s16 primitive->linkQuality.unifiSnr */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeLinkQualityGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeLinkQualityGetCfm *primitive = (CsrWifiSmeLinkQualityGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint16Ser(ptr, len, (u16) primitive->linkQuality.unifiRssi);
-    CsrUint16Ser(ptr, len, (u16) primitive->linkQuality.unifiSnr);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeLinkQualityGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeLinkQualityGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeLinkQualityGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->linkQuality.unifiRssi, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->linkQuality.unifiSnr, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeMediaStatusIndSizeof(void *msg)
-{
-    CsrWifiSmeMediaStatusInd *primitive = (CsrWifiSmeMediaStatusInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 99) */
-    bufferSize += 2;                                                     /* u16 primitive->interfaceTag */
-    bufferSize += 1;                                                     /* CsrWifiSmeMediaStatus primitive->mediaStatus */
-    bufferSize += 32;                                                    /* u8 primitive->connectionInfo.ssid.ssid[32] */
-    bufferSize += 1;                                                     /* u8 primitive->connectionInfo.ssid.length */
-    bufferSize += 6;                                                     /* u8 primitive->connectionInfo.bssid.a[6] */
-    bufferSize += 1;                                                     /* CsrWifiSme80211NetworkType primitive->connectionInfo.networkType80211 */
-    bufferSize += 1;                                                     /* u8 primitive->connectionInfo.channelNumber */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.channelFrequency */
-    bufferSize += 2;                                                     /* CsrWifiSmeAuthMode primitive->connectionInfo.authMode */
-    bufferSize += 2;                                                     /* CsrWifiSmeEncryption primitive->connectionInfo.pairwiseCipher */
-    bufferSize += 2;                                                     /* CsrWifiSmeEncryption primitive->connectionInfo.groupCipher */
-    bufferSize += 1;                                                     /* CsrWifiSmeRadioIF primitive->connectionInfo.ifIndex */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.atimWindowTu */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.beaconPeriodTu */
-    bufferSize += 1;                                                     /* u8 primitive->connectionInfo.reassociation */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.beaconFrameLength */
-    bufferSize += primitive->connectionInfo.beaconFrameLength;           /* u8 primitive->connectionInfo.beaconFrame */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.associationReqFrameLength */
-    bufferSize += primitive->connectionInfo.associationReqFrameLength;   /* u8 primitive->connectionInfo.associationReqFrame */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.associationRspFrameLength */
-    bufferSize += primitive->connectionInfo.associationRspFrameLength;   /* u8 primitive->connectionInfo.associationRspFrame */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocScanInfoElementsLength */
-    bufferSize += primitive->connectionInfo.assocScanInfoElementsLength; /* u8 primitive->connectionInfo.assocScanInfoElements */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocReqCapabilities */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocReqListenIntervalTu */
-    bufferSize += 6;                                                     /* u8 primitive->connectionInfo.assocReqApAddress.a[6] */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocReqInfoElementsLength */
-    bufferSize += primitive->connectionInfo.assocReqInfoElementsLength;  /* u8 primitive->connectionInfo.assocReqInfoElements */
-    bufferSize += 2;                                                     /* CsrWifiSmeIEEE80211Result primitive->connectionInfo.assocRspResult */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocRspCapabilityInfo */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocRspAssociationId */
-    bufferSize += 2;                                                     /* u16 primitive->connectionInfo.assocRspInfoElementsLength */
-    bufferSize += primitive->connectionInfo.assocRspInfoElementsLength;  /* u8 primitive->connectionInfo.assocRspInfoElements */
-    bufferSize += 2;                                                     /* CsrWifiSmeIEEE80211Reason primitive->disassocReason */
-    bufferSize += 2;                                                     /* CsrWifiSmeIEEE80211Reason primitive->deauthReason */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMediaStatusIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMediaStatusInd *primitive = (CsrWifiSmeMediaStatusInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->mediaStatus);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.ssid.ssid, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.ssid.length);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.bssid.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.networkType80211);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.channelNumber);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.channelFrequency);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.authMode);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.pairwiseCipher);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.groupCipher);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.ifIndex);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.atimWindowTu);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.beaconPeriodTu);
-    CsrUint8Ser(ptr, len, (u8) primitive->connectionInfo.reassociation);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.beaconFrameLength);
-    if (primitive->connectionInfo.beaconFrameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.beaconFrame, ((u16) (primitive->connectionInfo.beaconFrameLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.associationReqFrameLength);
-    if (primitive->connectionInfo.associationReqFrameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationReqFrame, ((u16) (primitive->connectionInfo.associationReqFrameLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.associationRspFrameLength);
-    if (primitive->connectionInfo.associationRspFrameLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.associationRspFrame, ((u16) (primitive->connectionInfo.associationRspFrameLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocScanInfoElementsLength);
-    if (primitive->connectionInfo.assocScanInfoElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocScanInfoElements, ((u16) (primitive->connectionInfo.assocScanInfoElementsLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocReqCapabilities);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocReqListenIntervalTu);
-    CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqApAddress.a, ((u16) (6)));
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocReqInfoElementsLength);
-    if (primitive->connectionInfo.assocReqInfoElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocReqInfoElements, ((u16) (primitive->connectionInfo.assocReqInfoElementsLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspResult);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspCapabilityInfo);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspAssociationId);
-    CsrUint16Ser(ptr, len, (u16) primitive->connectionInfo.assocRspInfoElementsLength);
-    if (primitive->connectionInfo.assocRspInfoElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->connectionInfo.assocRspInfoElements, ((u16) (primitive->connectionInfo.assocRspInfoElementsLength)));
-    }
-    CsrUint16Ser(ptr, len, (u16) primitive->disassocReason);
-    CsrUint16Ser(ptr, len, (u16) primitive->deauthReason);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMediaStatusIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMediaStatusInd *primitive = kmalloc(sizeof(CsrWifiSmeMediaStatusInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->mediaStatus, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionInfo.ssid.ssid, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->connectionInfo.ssid.length, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionInfo.bssid.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->connectionInfo.networkType80211, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionInfo.channelNumber, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.channelFrequency, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.authMode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.pairwiseCipher, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.groupCipher, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionInfo.ifIndex, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.atimWindowTu, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.beaconPeriodTu, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->connectionInfo.reassociation, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.beaconFrameLength, buffer, &offset);
-    if (primitive->connectionInfo.beaconFrameLength)
-    {
-        primitive->connectionInfo.beaconFrame = kmalloc(primitive->connectionInfo.beaconFrameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.beaconFrame, buffer, &offset, ((u16) (primitive->connectionInfo.beaconFrameLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.beaconFrame = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.associationReqFrameLength, buffer, &offset);
-    if (primitive->connectionInfo.associationReqFrameLength)
-    {
-        primitive->connectionInfo.associationReqFrame = kmalloc(primitive->connectionInfo.associationReqFrameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.associationReqFrame, buffer, &offset, ((u16) (primitive->connectionInfo.associationReqFrameLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.associationReqFrame = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.associationRspFrameLength, buffer, &offset);
-    if (primitive->connectionInfo.associationRspFrameLength)
-    {
-        primitive->connectionInfo.associationRspFrame = kmalloc(primitive->connectionInfo.associationRspFrameLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.associationRspFrame, buffer, &offset, ((u16) (primitive->connectionInfo.associationRspFrameLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.associationRspFrame = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocScanInfoElementsLength, buffer, &offset);
-    if (primitive->connectionInfo.assocScanInfoElementsLength)
-    {
-        primitive->connectionInfo.assocScanInfoElements = kmalloc(primitive->connectionInfo.assocScanInfoElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.assocScanInfoElements, buffer, &offset, ((u16) (primitive->connectionInfo.assocScanInfoElementsLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.assocScanInfoElements = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocReqCapabilities, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocReqListenIntervalTu, buffer, &offset);
-    CsrMemCpyDes(primitive->connectionInfo.assocReqApAddress.a, buffer, &offset, ((u16) (6)));
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocReqInfoElementsLength, buffer, &offset);
-    if (primitive->connectionInfo.assocReqInfoElementsLength)
-    {
-        primitive->connectionInfo.assocReqInfoElements = kmalloc(primitive->connectionInfo.assocReqInfoElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.assocReqInfoElements, buffer, &offset, ((u16) (primitive->connectionInfo.assocReqInfoElementsLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.assocReqInfoElements = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspResult, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspCapabilityInfo, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspAssociationId, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->connectionInfo.assocRspInfoElementsLength, buffer, &offset);
-    if (primitive->connectionInfo.assocRspInfoElementsLength)
-    {
-        primitive->connectionInfo.assocRspInfoElements = kmalloc(primitive->connectionInfo.assocRspInfoElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->connectionInfo.assocRspInfoElements, buffer, &offset, ((u16) (primitive->connectionInfo.assocRspInfoElementsLength)));
-    }
-    else
-    {
-        primitive->connectionInfo.assocRspInfoElements = NULL;
-    }
-    CsrUint16Des((u16 *) &primitive->disassocReason, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->deauthReason, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiSmeMediaStatusIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeMediaStatusInd *primitive = (CsrWifiSmeMediaStatusInd *) voidPrimitivePointer;
-    kfree(primitive->connectionInfo.beaconFrame);
-    kfree(primitive->connectionInfo.associationReqFrame);
-    kfree(primitive->connectionInfo.associationRspFrame);
-    kfree(primitive->connectionInfo.assocScanInfoElements);
-    kfree(primitive->connectionInfo.assocReqInfoElements);
-    kfree(primitive->connectionInfo.assocRspInfoElements);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeMibConfigGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* u8 primitive->mibConfig.unifiFixMaxTxDataRate */
-    bufferSize += 1; /* u8 primitive->mibConfig.unifiFixTxDataRate */
-    bufferSize += 2; /* u16 primitive->mibConfig.dot11RtsThreshold */
-    bufferSize += 2; /* u16 primitive->mibConfig.dot11FragmentationThreshold */
-    bufferSize += 2; /* u16 primitive->mibConfig.dot11CurrentTxPowerLevel */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMibConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMibConfigGetCfm *primitive = (CsrWifiSmeMibConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->mibConfig.unifiFixMaxTxDataRate);
-    CsrUint8Ser(ptr, len, (u8) primitive->mibConfig.unifiFixTxDataRate);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibConfig.dot11RtsThreshold);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibConfig.dot11FragmentationThreshold);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibConfig.dot11CurrentTxPowerLevel);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMibConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMibConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeMibConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->mibConfig.unifiFixMaxTxDataRate, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->mibConfig.unifiFixTxDataRate, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibConfig.dot11RtsThreshold, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibConfig.dot11FragmentationThreshold, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibConfig.dot11CurrentTxPowerLevel, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeMibGetCfmSizeof(void *msg)
-{
-    CsrWifiSmeMibGetCfm *primitive = (CsrWifiSmeMibGetCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2;                             /* CsrResult primitive->status */
-    bufferSize += 2;                             /* u16 primitive->mibAttributeLength */
-    bufferSize += primitive->mibAttributeLength; /* u8 primitive->mibAttribute */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMibGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMibGetCfm *primitive = (CsrWifiSmeMibGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibAttributeLength);
-    if (primitive->mibAttributeLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((u16) (primitive->mibAttributeLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMibGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMibGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeMibGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibAttributeLength, buffer, &offset);
-    if (primitive->mibAttributeLength)
-    {
-        primitive->mibAttribute = kmalloc(primitive->mibAttributeLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((u16) (primitive->mibAttributeLength)));
-    }
-    else
-    {
-        primitive->mibAttribute = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeMibGetCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeMibGetCfm *primitive = (CsrWifiSmeMibGetCfm *) voidPrimitivePointer;
-    kfree(primitive->mibAttribute);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeMibGetNextCfmSizeof(void *msg)
-{
-    CsrWifiSmeMibGetNextCfm *primitive = (CsrWifiSmeMibGetNextCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2;                             /* CsrResult primitive->status */
-    bufferSize += 2;                             /* u16 primitive->mibAttributeLength */
-    bufferSize += primitive->mibAttributeLength; /* u8 primitive->mibAttribute */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMibGetNextCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMibGetNextCfm *primitive = (CsrWifiSmeMibGetNextCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint16Ser(ptr, len, (u16) primitive->mibAttributeLength);
-    if (primitive->mibAttributeLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->mibAttribute, ((u16) (primitive->mibAttributeLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMibGetNextCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMibGetNextCfm *primitive = kmalloc(sizeof(CsrWifiSmeMibGetNextCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->mibAttributeLength, buffer, &offset);
-    if (primitive->mibAttributeLength)
-    {
-        primitive->mibAttribute = kmalloc(primitive->mibAttributeLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->mibAttribute, buffer, &offset, ((u16) (primitive->mibAttributeLength)));
-    }
-    else
-    {
-        primitive->mibAttribute = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeMibGetNextCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeMibGetNextCfm *primitive = (CsrWifiSmeMibGetNextCfm *) voidPrimitivePointer;
-    kfree(primitive->mibAttribute);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeMicFailureIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* u8 primitive->secondFailure */
-    bufferSize += 2; /* u16 primitive->count */
-    bufferSize += 6; /* u8 primitive->address.a[6] */
-    bufferSize += 1; /* CsrWifiSmeKeyType primitive->keyType */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMicFailureIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMicFailureInd *primitive = (CsrWifiSmeMicFailureInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->secondFailure);
-    CsrUint16Ser(ptr, len, (u16) primitive->count);
-    CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((u16) (6)));
-    CsrUint8Ser(ptr, len, (u8) primitive->keyType);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMicFailureIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMicFailureInd *primitive = kmalloc(sizeof(CsrWifiSmeMicFailureInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->secondFailure, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->count, buffer, &offset);
-    CsrMemCpyDes(primitive->address.a, buffer, &offset, ((u16) (6)));
-    CsrUint8Des((u8 *) &primitive->keyType, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeMulticastAddressCfmSizeof(void *msg)
-{
-    CsrWifiSmeMulticastAddressCfm *primitive = (CsrWifiSmeMulticastAddressCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* CsrWifiSmeListAction primitive->action */
-    bufferSize += 1; /* u8 primitive->getAddressesCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getAddressesCount; i1++)
-        {
-            bufferSize += 6; /* u8 primitive->getAddresses[i1].a[6] */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeMulticastAddressCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeMulticastAddressCfm *primitive = (CsrWifiSmeMulticastAddressCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->getAddressesCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getAddressesCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->getAddresses[i1].a, ((u16) (6)));
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeMulticastAddressCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeMulticastAddressCfm *primitive = kmalloc(sizeof(CsrWifiSmeMulticastAddressCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->getAddressesCount, buffer, &offset);
-    primitive->getAddresses = NULL;
-    if (primitive->getAddressesCount)
-    {
-        primitive->getAddresses = kmalloc(sizeof(CsrWifiMacAddress) * primitive->getAddressesCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getAddressesCount; i1++)
-        {
-            CsrMemCpyDes(primitive->getAddresses[i1].a, buffer, &offset, ((u16) (6)));
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeMulticastAddressCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeMulticastAddressCfm *primitive = (CsrWifiSmeMulticastAddressCfm *) voidPrimitivePointer;
-    kfree(primitive->getAddresses);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmePacketFilterSetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmePacketFilterSetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmePacketFilterSetCfm *primitive = (CsrWifiSmePacketFilterSetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiSmePacketFilterSetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmePacketFilterSetCfm *primitive = kmalloc(sizeof(CsrWifiSmePacketFilterSetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmePermanentMacAddressGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 6; /* u8 primitive->permanentMacAddress.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmePermanentMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmePermanentMacAddressGetCfm *primitive = (CsrWifiSmePermanentMacAddressGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrMemCpySer(ptr, len, (const void *) primitive->permanentMacAddress.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiSmePermanentMacAddressGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmePermanentMacAddressGetCfm *primitive = kmalloc(sizeof(CsrWifiSmePermanentMacAddressGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrMemCpyDes(primitive->permanentMacAddress.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmePmkidCandidateListIndSizeof(void *msg)
-{
-    CsrWifiSmePmkidCandidateListInd *primitive = (CsrWifiSmePmkidCandidateListInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* u8 primitive->pmkidCandidatesCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->pmkidCandidatesCount; i1++)
-        {
-            bufferSize += 6; /* u8 primitive->pmkidCandidates[i1].bssid.a[6] */
-            bufferSize += 1; /* u8 primitive->pmkidCandidates[i1].preAuthAllowed */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmePmkidCandidateListIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmePmkidCandidateListInd *primitive = (CsrWifiSmePmkidCandidateListInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->pmkidCandidatesCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->pmkidCandidatesCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->pmkidCandidates[i1].bssid.a, ((u16) (6)));
-            CsrUint8Ser(ptr, len, (u8) primitive->pmkidCandidates[i1].preAuthAllowed);
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmePmkidCandidateListIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmePmkidCandidateListInd *primitive = kmalloc(sizeof(CsrWifiSmePmkidCandidateListInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->pmkidCandidatesCount, buffer, &offset);
-    primitive->pmkidCandidates = NULL;
-    if (primitive->pmkidCandidatesCount)
-    {
-        primitive->pmkidCandidates = kmalloc(sizeof(CsrWifiSmePmkidCandidate) * primitive->pmkidCandidatesCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->pmkidCandidatesCount; i1++)
-        {
-            CsrMemCpyDes(primitive->pmkidCandidates[i1].bssid.a, buffer, &offset, ((u16) (6)));
-            CsrUint8Des((u8 *) &primitive->pmkidCandidates[i1].preAuthAllowed, buffer, &offset);
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmePmkidCandidateListIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmePmkidCandidateListInd *primitive = (CsrWifiSmePmkidCandidateListInd *) voidPrimitivePointer;
-    kfree(primitive->pmkidCandidates);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmePmkidCfmSizeof(void *msg)
-{
-    CsrWifiSmePmkidCfm *primitive = (CsrWifiSmePmkidCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 31) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* CsrWifiSmeListAction primitive->action */
-    bufferSize += 1; /* u8 primitive->getPmkidsCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getPmkidsCount; i1++)
-        {
-            bufferSize += 6;  /* u8 primitive->getPmkids[i1].bssid.a[6] */
-            bufferSize += 16; /* u8 primitive->getPmkids[i1].pmkid[16] */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmePmkidCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmePmkidCfm *primitive = (CsrWifiSmePmkidCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->action);
-    CsrUint8Ser(ptr, len, (u8) primitive->getPmkidsCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getPmkidsCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->getPmkids[i1].bssid.a, ((u16) (6)));
-            CsrMemCpySer(ptr, len, (const void *) primitive->getPmkids[i1].pmkid, ((u16) (16)));
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmePmkidCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmePmkidCfm *primitive = kmalloc(sizeof(CsrWifiSmePmkidCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->action, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->getPmkidsCount, buffer, &offset);
-    primitive->getPmkids = NULL;
-    if (primitive->getPmkidsCount)
-    {
-        primitive->getPmkids = kmalloc(sizeof(CsrWifiSmePmkid) * primitive->getPmkidsCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->getPmkidsCount; i1++)
-        {
-            CsrMemCpyDes(primitive->getPmkids[i1].bssid.a, buffer, &offset, ((u16) (6)));
-            CsrMemCpyDes(primitive->getPmkids[i1].pmkid, buffer, &offset, ((u16) (16)));
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmePmkidCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmePmkidCfm *primitive = (CsrWifiSmePmkidCfm *) voidPrimitivePointer;
-    kfree(primitive->getPmkids);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmePowerConfigGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* CsrWifiSmePowerSaveLevel primitive->powerConfig.powerSaveLevel */
-    bufferSize += 2; /* u16 primitive->powerConfig.listenIntervalTu */
-    bufferSize += 1; /* u8 primitive->powerConfig.rxDtims */
-    bufferSize += 1; /* CsrWifiSmeD3AutoScanMode primitive->powerConfig.d3AutoScanMode */
-    bufferSize += 1; /* u8 primitive->powerConfig.clientTrafficWindow */
-    bufferSize += 1; /* u8 primitive->powerConfig.opportunisticPowerSave */
-    bufferSize += 1; /* u8 primitive->powerConfig.noticeOfAbsence */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmePowerConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmePowerConfigGetCfm *primitive = (CsrWifiSmePowerConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.powerSaveLevel);
-    CsrUint16Ser(ptr, len, (u16) primitive->powerConfig.listenIntervalTu);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.rxDtims);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.d3AutoScanMode);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.clientTrafficWindow);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.opportunisticPowerSave);
-    CsrUint8Ser(ptr, len, (u8) primitive->powerConfig.noticeOfAbsence);
-    return(ptr);
-}
-
-
-void* CsrWifiSmePowerConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmePowerConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmePowerConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.powerSaveLevel, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->powerConfig.listenIntervalTu, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.rxDtims, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.d3AutoScanMode, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.clientTrafficWindow, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.opportunisticPowerSave, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->powerConfig.noticeOfAbsence, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeRegulatoryDomainInfoGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* u8 primitive->regDomInfo.dot11MultiDomainCapabilityImplemented */
-    bufferSize += 1; /* u8 primitive->regDomInfo.dot11MultiDomainCapabilityEnabled */
-    bufferSize += 1; /* CsrWifiSmeRegulatoryDomain primitive->regDomInfo.currentRegulatoryDomain */
-    bufferSize += 2; /* u8 primitive->regDomInfo.currentCountryCode[2] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeRegulatoryDomainInfoGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeRegulatoryDomainInfoGetCfm *primitive = (CsrWifiSmeRegulatoryDomainInfoGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->regDomInfo.dot11MultiDomainCapabilityImplemented);
-    CsrUint8Ser(ptr, len, (u8) primitive->regDomInfo.dot11MultiDomainCapabilityEnabled);
-    CsrUint8Ser(ptr, len, (u8) primitive->regDomInfo.currentRegulatoryDomain);
-    CsrMemCpySer(ptr, len, (const void *) primitive->regDomInfo.currentCountryCode, ((u16) (2)));
-    return(ptr);
-}
-
-
-void* CsrWifiSmeRegulatoryDomainInfoGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeRegulatoryDomainInfoGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeRegulatoryDomainInfoGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->regDomInfo.dot11MultiDomainCapabilityImplemented, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->regDomInfo.dot11MultiDomainCapabilityEnabled, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->regDomInfo.currentRegulatoryDomain, buffer, &offset);
-    CsrMemCpyDes(primitive->regDomInfo.currentCountryCode, buffer, &offset, ((u16) (2)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeRoamCompleteIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeRoamCompleteIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeRoamCompleteInd *primitive = (CsrWifiSmeRoamCompleteInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeRoamCompleteIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeRoamCompleteInd *primitive = kmalloc(sizeof(CsrWifiSmeRoamCompleteInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeRoamStartIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 1; /* CsrWifiSmeRoamReason primitive->roamReason */
-    bufferSize += 2; /* CsrWifiSmeIEEE80211Reason primitive->reason80211 */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeRoamStartIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeRoamStartInd *primitive = (CsrWifiSmeRoamStartInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint8Ser(ptr, len, (u8) primitive->roamReason);
-    CsrUint16Ser(ptr, len, (u16) primitive->reason80211);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeRoamStartIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeRoamStartInd *primitive = kmalloc(sizeof(CsrWifiSmeRoamStartInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->roamReason, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->reason80211, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeRoamingConfigGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 72) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            bufferSize += 2; /* s16 primitive->roamingConfig.roamingBands[i2].rssiHighThreshold */
-            bufferSize += 2; /* s16 primitive->roamingConfig.roamingBands[i2].rssiLowThreshold */
-            bufferSize += 2; /* s16 primitive->roamingConfig.roamingBands[i2].snrHighThreshold */
-            bufferSize += 2; /* s16 primitive->roamingConfig.roamingBands[i2].snrLowThreshold */
-        }
-    }
-    bufferSize += 1;         /* u8 primitive->roamingConfig.disableSmoothRoaming */
-    bufferSize += 1;         /* u8 primitive->roamingConfig.disableRoamScans */
-    bufferSize += 1;         /* u8 primitive->roamingConfig.reconnectLimit */
-    bufferSize += 2;         /* u16 primitive->roamingConfig.reconnectLimitIntervalMs */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].intervalSeconds */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].validitySeconds */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu */
-            bufferSize += 2; /* u16 primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeRoamingConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeRoamingConfigGetCfm *primitive = (CsrWifiSmeRoamingConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamingBands[i2].rssiHighThreshold);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamingBands[i2].rssiLowThreshold);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamingBands[i2].snrHighThreshold);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamingBands[i2].snrLowThreshold);
-        }
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->roamingConfig.disableSmoothRoaming);
-    CsrUint8Ser(ptr, len, (u8) primitive->roamingConfig.disableRoamScans);
-    CsrUint8Ser(ptr, len, (u8) primitive->roamingConfig.reconnectLimit);
-    CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.reconnectLimitIntervalMs);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].intervalSeconds);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].validitySeconds);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu);
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeRoamingConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeRoamingConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeRoamingConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamingBands[i2].rssiHighThreshold, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamingBands[i2].rssiLowThreshold, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamingBands[i2].snrHighThreshold, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamingBands[i2].snrLowThreshold, buffer, &offset);
-        }
-    }
-    CsrUint8Des((u8 *) &primitive->roamingConfig.disableSmoothRoaming, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->roamingConfig.disableRoamScans, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->roamingConfig.reconnectLimit, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->roamingConfig.reconnectLimitIntervalMs, buffer, &offset);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 3; i2++)
-        {
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].intervalSeconds, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].validitySeconds, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].minActiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].maxActiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].minPassiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->roamingConfig.roamScanCfg[i2].maxPassiveChannelTimeTu, buffer, &offset);
-        }
-    }
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeRoamingConfigSetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeRoamingConfigSetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeRoamingConfigSetCfm *primitive = (CsrWifiSmeRoamingConfigSetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeRoamingConfigSetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeRoamingConfigSetCfm *primitive = kmalloc(sizeof(CsrWifiSmeRoamingConfigSetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeScanConfigGetCfmSizeof(void *msg)
-{
-    CsrWifiSmeScanConfigGetCfm *primitive = (CsrWifiSmeScanConfigGetCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 65) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].intervalSeconds */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].validitySeconds */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu */
-            bufferSize += 2;                                     /* u16 primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu */
-        }
-    }
-    bufferSize += 1;                                             /* u8 primitive->scanConfig.disableAutonomousScans */
-    bufferSize += 2;                                             /* u16 primitive->scanConfig.maxResults */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.highRssiThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.lowRssiThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.deltaRssiThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.highSnrThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.lowSnrThreshold */
-    bufferSize += 1;                                             /* s8 primitive->scanConfig.deltaSnrThreshold */
-    bufferSize += 2;                                             /* u16 primitive->scanConfig.passiveChannelListCount */
-    bufferSize += primitive->scanConfig.passiveChannelListCount; /* u8 primitive->scanConfig.passiveChannelList */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeScanConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeScanConfigGetCfm *primitive = (CsrWifiSmeScanConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].intervalSeconds);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].validitySeconds);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu);
-        }
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.disableAutonomousScans);
-    CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.maxResults);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.highRssiThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.lowRssiThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.deltaRssiThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.highSnrThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.lowSnrThreshold);
-    CsrUint8Ser(ptr, len, (u8) primitive->scanConfig.deltaSnrThreshold);
-    CsrUint16Ser(ptr, len, (u16) primitive->scanConfig.passiveChannelListCount);
-    if (primitive->scanConfig.passiveChannelListCount)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->scanConfig.passiveChannelList, ((u16) (primitive->scanConfig.passiveChannelListCount)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeScanConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeScanConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeScanConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < 4; i2++)
-        {
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].intervalSeconds, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].validitySeconds, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].minActiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].maxActiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].minPassiveChannelTimeTu, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanConfig.scanCfg[i2].maxPassiveChannelTimeTu, buffer, &offset);
-        }
-    }
-    CsrUint8Des((u8 *) &primitive->scanConfig.disableAutonomousScans, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->scanConfig.maxResults, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.highRssiThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.lowRssiThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.deltaRssiThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.highSnrThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.lowSnrThreshold, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->scanConfig.deltaSnrThreshold, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->scanConfig.passiveChannelListCount, buffer, &offset);
-    if (primitive->scanConfig.passiveChannelListCount)
-    {
-        primitive->scanConfig.passiveChannelList = kmalloc(primitive->scanConfig.passiveChannelListCount, GFP_KERNEL);
-        CsrMemCpyDes(primitive->scanConfig.passiveChannelList, buffer, &offset, ((u16) (primitive->scanConfig.passiveChannelListCount)));
-    }
-    else
-    {
-        primitive->scanConfig.passiveChannelList = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeScanConfigGetCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeScanConfigGetCfm *primitive = (CsrWifiSmeScanConfigGetCfm *) voidPrimitivePointer;
-    kfree(primitive->scanConfig.passiveChannelList);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeScanResultIndSizeof(void *msg)
-{
-    CsrWifiSmeScanResultInd *primitive = (CsrWifiSmeScanResultInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 149) */
-    bufferSize += 32;                                          /* u8 primitive->result.ssid.ssid[32] */
-    bufferSize += 1;                                           /* u8 primitive->result.ssid.length */
-    bufferSize += 6;                                           /* u8 primitive->result.bssid.a[6] */
-    bufferSize += 2;                                           /* s16 primitive->result.rssi */
-    bufferSize += 2;                                           /* s16 primitive->result.snr */
-    bufferSize += 1;                                           /* CsrWifiSmeRadioIF primitive->result.ifIndex */
-    bufferSize += 2;                                           /* u16 primitive->result.beaconPeriodTu */
-    bufferSize += 8;                                           /* u8 primitive->result.timeStamp.data[8] */
-    bufferSize += 8;                                           /* u8 primitive->result.localTime.data[8] */
-    bufferSize += 2;                                           /* u16 primitive->result.channelFrequency */
-    bufferSize += 2;                                           /* u16 primitive->result.capabilityInformation */
-    bufferSize += 1;                                           /* u8 primitive->result.channelNumber */
-    bufferSize += 1;                                           /* CsrWifiSmeBasicUsability primitive->result.usability */
-    bufferSize += 1;                                           /* CsrWifiSmeBssType primitive->result.bssType */
-    bufferSize += 2;                                           /* u16 primitive->result.informationElementsLength */
-    bufferSize += primitive->result.informationElementsLength; /* u8 primitive->result.informationElements */
-    bufferSize += 1;                                           /* CsrWifiSmeP2pRole primitive->result.p2pDeviceRole */
-    switch (primitive->result.p2pDeviceRole)
-    {
-        case CSR_WIFI_SME_P2P_ROLE_CLI:
-            bufferSize += 1; /* u8 primitive->result.deviceInfo.reservedCli.empty */
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_GO:
-            bufferSize += 1; /* CsrWifiSmeP2pGroupCapabilityMask primitive->result.deviceInfo.groupInfo.groupCapability */
-            bufferSize += 6; /* u8 primitive->result.deviceInfo.groupInfo.p2pDeviceAddress.a[6] */
-            bufferSize += 1; /* u8 primitive->result.deviceInfo.groupInfo.p2pClientInfoCount */
-            {
-                u16 i4;
-                for (i4 = 0; i4 < primitive->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-                {
-                    bufferSize += 6; /* u8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a[6] */
-                    bufferSize += 6; /* u8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a[6] */
-                    bufferSize += 2; /* CsrWifiSmeWpsConfigTypeMask primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods */
-                    bufferSize += 1; /* CsrWifiSmeP2pCapabilityMask primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap */
-                    bufferSize += 8; /* u8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails[8] */
-                    bufferSize += 1; /* u8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount */
-                    {
-                        u16 i6;
-                        for (i6 = 0; i6 < primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++)
-                        {
-                            bufferSize += 8; /* u8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails[8] */
-                        }
-                    }
-                    bufferSize += 32;        /* u8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName[32] */
-                    bufferSize += 1;         /* u8 primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength */
-                }
-            }
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_NONE:
-            bufferSize += 1; /* u8 primitive->result.deviceInfo.reservedNone.empty */
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-            bufferSize += 6; /* u8 primitive->result.deviceInfo.standalonedevInfo.deviceAddress.a[6] */
-            bufferSize += 2; /* CsrWifiSmeWpsConfigTypeMask primitive->result.deviceInfo.standalonedevInfo.configMethods */
-            bufferSize += 1; /* CsrWifiSmeP2pCapabilityMask primitive->result.deviceInfo.standalonedevInfo.p2PDeviceCap */
-            bufferSize += 8; /* u8 primitive->result.deviceInfo.standalonedevInfo.primDeviceType.deviceDetails[8] */
-            bufferSize += 1; /* u8 primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount */
-            {
-                u16 i4;
-                for (i4 = 0; i4 < primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++)
-                {
-                    bufferSize += 8; /* u8 primitive->result.deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails[8] */
-                }
-            }
-            bufferSize += 32;        /* u8 primitive->result.deviceInfo.standalonedevInfo.deviceName[32] */
-            bufferSize += 1;         /* u8 primitive->result.deviceInfo.standalonedevInfo.deviceNameLength */
-            break;
-        default:
-            break;
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeScanResultIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeScanResultInd *primitive = (CsrWifiSmeScanResultInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrMemCpySer(ptr, len, (const void *) primitive->result.ssid.ssid, ((u16) (32)));
-    CsrUint8Ser(ptr, len, (u8) primitive->result.ssid.length);
-    CsrMemCpySer(ptr, len, (const void *) primitive->result.bssid.a, ((u16) (6)));
-    CsrUint16Ser(ptr, len, (u16) primitive->result.rssi);
-    CsrUint16Ser(ptr, len, (u16) primitive->result.snr);
-    CsrUint8Ser(ptr, len, (u8) primitive->result.ifIndex);
-    CsrUint16Ser(ptr, len, (u16) primitive->result.beaconPeriodTu);
-    CsrMemCpySer(ptr, len, (const void *) primitive->result.timeStamp.data, ((u16) (8)));
-    CsrMemCpySer(ptr, len, (const void *) primitive->result.localTime.data, ((u16) (8)));
-    CsrUint16Ser(ptr, len, (u16) primitive->result.channelFrequency);
-    CsrUint16Ser(ptr, len, (u16) primitive->result.capabilityInformation);
-    CsrUint8Ser(ptr, len, (u8) primitive->result.channelNumber);
-    CsrUint8Ser(ptr, len, (u8) primitive->result.usability);
-    CsrUint8Ser(ptr, len, (u8) primitive->result.bssType);
-    CsrUint16Ser(ptr, len, (u16) primitive->result.informationElementsLength);
-    if (primitive->result.informationElementsLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->result.informationElements, ((u16) (primitive->result.informationElementsLength)));
-    }
-    CsrUint8Ser(ptr, len, (u8) primitive->result.p2pDeviceRole);
-    switch (primitive->result.p2pDeviceRole)
-    {
-        case CSR_WIFI_SME_P2P_ROLE_CLI:
-            CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.reservedCli.empty);
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_GO:
-            CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.groupInfo.groupCapability);
-            CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2pDeviceAddress.a, ((u16) (6)));
-            CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.groupInfo.p2pClientInfoCount);
-            {
-                u16 i4;
-                for (i4 = 0; i4 < primitive->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-                {
-                    CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a, ((u16) (6)));
-                    CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a, ((u16) (6)));
-                    CsrUint16Ser(ptr, len, (u16) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods);
-                    CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap);
-                    CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails, ((u16) (8)));
-                    CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount);
-                    {
-                        u16 i6;
-                        for (i6 = 0; i6 < primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++)
-                        {
-                            CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails, ((u16) (8)));
-                        }
-                    }
-                    CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName, ((u16) (32)));
-                    CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength);
-                }
-            }
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_NONE:
-            CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.reservedNone.empty);
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-            CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.standalonedevInfo.deviceAddress.a, ((u16) (6)));
-            CsrUint16Ser(ptr, len, (u16) primitive->result.deviceInfo.standalonedevInfo.configMethods);
-            CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.standalonedevInfo.p2PDeviceCap);
-            CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.standalonedevInfo.primDeviceType.deviceDetails, ((u16) (8)));
-            CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount);
-            {
-                u16 i4;
-                for (i4 = 0; i4 < primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++)
-                {
-                    CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails, ((u16) (8)));
-                }
-            }
-            CsrMemCpySer(ptr, len, (const void *) primitive->result.deviceInfo.standalonedevInfo.deviceName, ((u16) (32)));
-            CsrUint8Ser(ptr, len, (u8) primitive->result.deviceInfo.standalonedevInfo.deviceNameLength);
-            break;
-        default:
-            break;
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeScanResultIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeScanResultInd *primitive = kmalloc(sizeof(CsrWifiSmeScanResultInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrMemCpyDes(primitive->result.ssid.ssid, buffer, &offset, ((u16) (32)));
-    CsrUint8Des((u8 *) &primitive->result.ssid.length, buffer, &offset);
-    CsrMemCpyDes(primitive->result.bssid.a, buffer, &offset, ((u16) (6)));
-    CsrUint16Des((u16 *) &primitive->result.rssi, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->result.snr, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->result.ifIndex, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->result.beaconPeriodTu, buffer, &offset);
-    CsrMemCpyDes(primitive->result.timeStamp.data, buffer, &offset, ((u16) (8)));
-    CsrMemCpyDes(primitive->result.localTime.data, buffer, &offset, ((u16) (8)));
-    CsrUint16Des((u16 *) &primitive->result.channelFrequency, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->result.capabilityInformation, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->result.channelNumber, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->result.usability, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->result.bssType, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->result.informationElementsLength, buffer, &offset);
-    if (primitive->result.informationElementsLength)
-    {
-        primitive->result.informationElements = kmalloc(primitive->result.informationElementsLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->result.informationElements, buffer, &offset, ((u16) (primitive->result.informationElementsLength)));
-    }
-    else
-    {
-        primitive->result.informationElements = NULL;
-    }
-    CsrUint8Des((u8 *) &primitive->result.p2pDeviceRole, buffer, &offset);
-    switch (primitive->result.p2pDeviceRole)
-    {
-        case CSR_WIFI_SME_P2P_ROLE_CLI:
-            CsrUint8Des((u8 *) &primitive->result.deviceInfo.reservedCli.empty, buffer, &offset);
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_GO:
-            CsrUint8Des((u8 *) &primitive->result.deviceInfo.groupInfo.groupCapability, buffer, &offset);
-            CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2pDeviceAddress.a, buffer, &offset, ((u16) (6)));
-            CsrUint8Des((u8 *) &primitive->result.deviceInfo.groupInfo.p2pClientInfoCount, buffer, &offset);
-            primitive->result.deviceInfo.groupInfo.p2PClientInfo = NULL;
-            if (primitive->result.deviceInfo.groupInfo.p2pClientInfoCount)
-            {
-                primitive->result.deviceInfo.groupInfo.p2PClientInfo = kmalloc(sizeof(CsrWifiSmeP2pClientInfoType) * primitive->result.deviceInfo.groupInfo.p2pClientInfoCount, GFP_KERNEL);
-            }
-            {
-                u16 i4;
-                for (i4 = 0; i4 < primitive->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-                {
-                    CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a, buffer, &offset, ((u16) (6)));
-                    CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a, buffer, &offset, ((u16) (6)));
-                    CsrUint16Des((u16 *) &primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods, buffer, &offset);
-                    CsrUint8Des((u8 *) &primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap, buffer, &offset);
-                    CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails, buffer, &offset, ((u16) (8)));
-                    CsrUint8Des((u8 *) &primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount, buffer, &offset);
-                    primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = NULL;
-                    if (primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount)
-                    {
-                        primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = kmalloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount, GFP_KERNEL);
-                    }
-                    {
-                        u16 i6;
-                        for (i6 = 0; i6 < primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++)
-                        {
-                            CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails, buffer, &offset, ((u16) (8)));
-                        }
-                    }
-                    CsrMemCpyDes(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName, buffer, &offset, ((u16) (32)));
-                    CsrUint8Des((u8 *) &primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength, buffer, &offset);
-                }
-            }
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_NONE:
-            CsrUint8Des((u8 *) &primitive->result.deviceInfo.reservedNone.empty, buffer, &offset);
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-            CsrMemCpyDes(primitive->result.deviceInfo.standalonedevInfo.deviceAddress.a, buffer, &offset, ((u16) (6)));
-            CsrUint16Des((u16 *) &primitive->result.deviceInfo.standalonedevInfo.configMethods, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->result.deviceInfo.standalonedevInfo.p2PDeviceCap, buffer, &offset);
-            CsrMemCpyDes(primitive->result.deviceInfo.standalonedevInfo.primDeviceType.deviceDetails, buffer, &offset, ((u16) (8)));
-            CsrUint8Des((u8 *) &primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount, buffer, &offset);
-            primitive->result.deviceInfo.standalonedevInfo.secDeviceType = NULL;
-            if (primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount)
-            {
-                primitive->result.deviceInfo.standalonedevInfo.secDeviceType = kmalloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount, GFP_KERNEL);
-            }
-            {
-                u16 i4;
-                for (i4 = 0; i4 < primitive->result.deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++)
-                {
-                    CsrMemCpyDes(primitive->result.deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails, buffer, &offset, ((u16) (8)));
-                }
-            }
-            CsrMemCpyDes(primitive->result.deviceInfo.standalonedevInfo.deviceName, buffer, &offset, ((u16) (32)));
-            CsrUint8Des((u8 *) &primitive->result.deviceInfo.standalonedevInfo.deviceNameLength, buffer, &offset);
-            break;
-        default:
-            break;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeScanResultIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeScanResultInd *primitive = (CsrWifiSmeScanResultInd *) voidPrimitivePointer;
-    kfree(primitive->result.informationElements);
-    switch (primitive->result.p2pDeviceRole)
-    {
-        case CSR_WIFI_SME_P2P_ROLE_GO:
-        {
-            u16 i4;
-            for (i4 = 0; i4 < primitive->result.deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-            {
-                kfree(primitive->result.deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType);
-            }
-        }
-            kfree(primitive->result.deviceInfo.groupInfo.p2PClientInfo);
-            break;
-        case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-            kfree(primitive->result.deviceInfo.standalonedevInfo.secDeviceType);
-            break;
-        default:
-            break;
-    }
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeScanResultsGetCfmSizeof(void *msg)
-{
-    CsrWifiSmeScanResultsGetCfm *primitive = (CsrWifiSmeScanResultsGetCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 153) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 2; /* u16 primitive->scanResultsCount */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->scanResultsCount; i1++)
-        {
-            bufferSize += 32;                                                   /* u8 primitive->scanResults[i1].ssid.ssid[32] */
-            bufferSize += 1;                                                    /* u8 primitive->scanResults[i1].ssid.length */
-            bufferSize += 6;                                                    /* u8 primitive->scanResults[i1].bssid.a[6] */
-            bufferSize += 2;                                                    /* s16 primitive->scanResults[i1].rssi */
-            bufferSize += 2;                                                    /* s16 primitive->scanResults[i1].snr */
-            bufferSize += 1;                                                    /* CsrWifiSmeRadioIF primitive->scanResults[i1].ifIndex */
-            bufferSize += 2;                                                    /* u16 primitive->scanResults[i1].beaconPeriodTu */
-            bufferSize += 8;                                                    /* u8 primitive->scanResults[i1].timeStamp.data[8] */
-            bufferSize += 8;                                                    /* u8 primitive->scanResults[i1].localTime.data[8] */
-            bufferSize += 2;                                                    /* u16 primitive->scanResults[i1].channelFrequency */
-            bufferSize += 2;                                                    /* u16 primitive->scanResults[i1].capabilityInformation */
-            bufferSize += 1;                                                    /* u8 primitive->scanResults[i1].channelNumber */
-            bufferSize += 1;                                                    /* CsrWifiSmeBasicUsability primitive->scanResults[i1].usability */
-            bufferSize += 1;                                                    /* CsrWifiSmeBssType primitive->scanResults[i1].bssType */
-            bufferSize += 2;                                                    /* u16 primitive->scanResults[i1].informationElementsLength */
-            bufferSize += primitive->scanResults[i1].informationElementsLength; /* u8 primitive->scanResults[i1].informationElements */
-            bufferSize += 1;                                                    /* CsrWifiSmeP2pRole primitive->scanResults[i1].p2pDeviceRole */
-            switch (primitive->scanResults[i1].p2pDeviceRole)
-            {
-                case CSR_WIFI_SME_P2P_ROLE_CLI:
-                    bufferSize += 1; /* u8 primitive->scanResults[i1].deviceInfo.reservedCli.empty */
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_GO:
-                    bufferSize += 1; /* CsrWifiSmeP2pGroupCapabilityMask primitive->scanResults[i1].deviceInfo.groupInfo.groupCapability */
-                    bufferSize += 6; /* u8 primitive->scanResults[i1].deviceInfo.groupInfo.p2pDeviceAddress.a[6] */
-                    bufferSize += 1; /* u8 primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount */
-                    {
-                        u16 i4;
-                        for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-                        {
-                            bufferSize += 6; /* u8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a[6] */
-                            bufferSize += 6; /* u8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a[6] */
-                            bufferSize += 2; /* CsrWifiSmeWpsConfigTypeMask primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods */
-                            bufferSize += 1; /* CsrWifiSmeP2pCapabilityMask primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap */
-                            bufferSize += 8; /* u8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails[8] */
-                            bufferSize += 1; /* u8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount */
-                            {
-                                u16 i6;
-                                for (i6 = 0; i6 < primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++)
-                                {
-                                    bufferSize += 8; /* u8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails[8] */
-                                }
-                            }
-                            bufferSize += 32;        /* u8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName[32] */
-                            bufferSize += 1;         /* u8 primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength */
-                        }
-                    }
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_NONE:
-                    bufferSize += 1; /* u8 primitive->scanResults[i1].deviceInfo.reservedNone.empty */
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-                    bufferSize += 6; /* u8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceAddress.a[6] */
-                    bufferSize += 2; /* CsrWifiSmeWpsConfigTypeMask primitive->scanResults[i1].deviceInfo.standalonedevInfo.configMethods */
-                    bufferSize += 1; /* CsrWifiSmeP2pCapabilityMask primitive->scanResults[i1].deviceInfo.standalonedevInfo.p2PDeviceCap */
-                    bufferSize += 8; /* u8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.primDeviceType.deviceDetails[8] */
-                    bufferSize += 1; /* u8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount */
-                    {
-                        u16 i4;
-                        for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++)
-                        {
-                            bufferSize += 8; /* u8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails[8] */
-                        }
-                    }
-                    bufferSize += 32;        /* u8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceName[32] */
-                    bufferSize += 1;         /* u8 primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceNameLength */
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeScanResultsGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeScanResultsGetCfm *primitive = (CsrWifiSmeScanResultsGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint16Ser(ptr, len, (u16) primitive->scanResultsCount);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->scanResultsCount; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].ssid.ssid, ((u16) (32)));
-            CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].ssid.length);
-            CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].bssid.a, ((u16) (6)));
-            CsrUint16Ser(ptr, len, (u16) primitive->scanResults[i1].rssi);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanResults[i1].snr);
-            CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].ifIndex);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanResults[i1].beaconPeriodTu);
-            CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].timeStamp.data, ((u16) (8)));
-            CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].localTime.data, ((u16) (8)));
-            CsrUint16Ser(ptr, len, (u16) primitive->scanResults[i1].channelFrequency);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanResults[i1].capabilityInformation);
-            CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].channelNumber);
-            CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].usability);
-            CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].bssType);
-            CsrUint16Ser(ptr, len, (u16) primitive->scanResults[i1].informationElementsLength);
-            if (primitive->scanResults[i1].informationElementsLength)
-            {
-                CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].informationElements, ((u16) (primitive->scanResults[i1].informationElementsLength)));
-            }
-            CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].p2pDeviceRole);
-            switch (primitive->scanResults[i1].p2pDeviceRole)
-            {
-                case CSR_WIFI_SME_P2P_ROLE_CLI:
-                    CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.reservedCli.empty);
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_GO:
-                    CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.groupInfo.groupCapability);
-                    CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2pDeviceAddress.a, ((u16) (6)));
-                    CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount);
-                    {
-                        u16 i4;
-                        for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-                        {
-                            CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a, ((u16) (6)));
-                            CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a, ((u16) (6)));
-                            CsrUint16Ser(ptr, len, (u16) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods);
-                            CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap);
-                            CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails, ((u16) (8)));
-                            CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount);
-                            {
-                                u16 i6;
-                                for (i6 = 0; i6 < primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++)
-                                {
-                                    CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails, ((u16) (8)));
-                                }
-                            }
-                            CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName, ((u16) (32)));
-                            CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength);
-                        }
-                    }
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_NONE:
-                    CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.reservedNone.empty);
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-                    CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceAddress.a, ((u16) (6)));
-                    CsrUint16Ser(ptr, len, (u16) primitive->scanResults[i1].deviceInfo.standalonedevInfo.configMethods);
-                    CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.standalonedevInfo.p2PDeviceCap);
-                    CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.standalonedevInfo.primDeviceType.deviceDetails, ((u16) (8)));
-                    CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount);
-                    {
-                        u16 i4;
-                        for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++)
-                        {
-                            CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails, ((u16) (8)));
-                        }
-                    }
-                    CsrMemCpySer(ptr, len, (const void *) primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceName, ((u16) (32)));
-                    CsrUint8Ser(ptr, len, (u8) primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceNameLength);
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeScanResultsGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeScanResultsGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeScanResultsGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->scanResultsCount, buffer, &offset);
-    primitive->scanResults = NULL;
-    if (primitive->scanResultsCount)
-    {
-        primitive->scanResults = kmalloc(sizeof(CsrWifiSmeScanResult) * primitive->scanResultsCount, GFP_KERNEL);
-    }
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->scanResultsCount; i1++)
-        {
-            CsrMemCpyDes(primitive->scanResults[i1].ssid.ssid, buffer, &offset, ((u16) (32)));
-            CsrUint8Des((u8 *) &primitive->scanResults[i1].ssid.length, buffer, &offset);
-            CsrMemCpyDes(primitive->scanResults[i1].bssid.a, buffer, &offset, ((u16) (6)));
-            CsrUint16Des((u16 *) &primitive->scanResults[i1].rssi, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanResults[i1].snr, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->scanResults[i1].ifIndex, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanResults[i1].beaconPeriodTu, buffer, &offset);
-            CsrMemCpyDes(primitive->scanResults[i1].timeStamp.data, buffer, &offset, ((u16) (8)));
-            CsrMemCpyDes(primitive->scanResults[i1].localTime.data, buffer, &offset, ((u16) (8)));
-            CsrUint16Des((u16 *) &primitive->scanResults[i1].channelFrequency, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanResults[i1].capabilityInformation, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->scanResults[i1].channelNumber, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->scanResults[i1].usability, buffer, &offset);
-            CsrUint8Des((u8 *) &primitive->scanResults[i1].bssType, buffer, &offset);
-            CsrUint16Des((u16 *) &primitive->scanResults[i1].informationElementsLength, buffer, &offset);
-            if (primitive->scanResults[i1].informationElementsLength)
-            {
-                primitive->scanResults[i1].informationElements = kmalloc(primitive->scanResults[i1].informationElementsLength, GFP_KERNEL);
-                CsrMemCpyDes(primitive->scanResults[i1].informationElements, buffer, &offset, ((u16) (primitive->scanResults[i1].informationElementsLength)));
-            }
-            else
-            {
-                primitive->scanResults[i1].informationElements = NULL;
-            }
-            CsrUint8Des((u8 *) &primitive->scanResults[i1].p2pDeviceRole, buffer, &offset);
-            switch (primitive->scanResults[i1].p2pDeviceRole)
-            {
-                case CSR_WIFI_SME_P2P_ROLE_CLI:
-                    CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.reservedCli.empty, buffer, &offset);
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_GO:
-                    CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.groupCapability, buffer, &offset);
-                    CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2pDeviceAddress.a, buffer, &offset, ((u16) (6)));
-                    CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount, buffer, &offset);
-                    primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo = NULL;
-                    if (primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount)
-                    {
-                        primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo = kmalloc(sizeof(CsrWifiSmeP2pClientInfoType) * primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount, GFP_KERNEL);
-                    }
-                    {
-                        u16 i4;
-                        for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-                        {
-                            CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].p2PClientInterfaceAddress.a, buffer, &offset, ((u16) (6)));
-                            CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceAddress.a, buffer, &offset, ((u16) (6)));
-                            CsrUint16Des((u16 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.configMethods, buffer, &offset);
-                            CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.p2PDeviceCap, buffer, &offset);
-                            CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.primDeviceType.deviceDetails, buffer, &offset, ((u16) (8)));
-                            CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount, buffer, &offset);
-                            primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = NULL;
-                            if (primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount)
-                            {
-                                primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType = kmalloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount, GFP_KERNEL);
-                            }
-                            {
-                                u16 i6;
-                                for (i6 = 0; i6 < primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secondaryDeviceTypeCount; i6++)
-                                {
-                                    CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType[i6].deviceDetails, buffer, &offset, ((u16) (8)));
-                                }
-                            }
-                            CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceName, buffer, &offset, ((u16) (32)));
-                            CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.deviceNameLength, buffer, &offset);
-                        }
-                    }
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_NONE:
-                    CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.reservedNone.empty, buffer, &offset);
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-                    CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceAddress.a, buffer, &offset, ((u16) (6)));
-                    CsrUint16Des((u16 *) &primitive->scanResults[i1].deviceInfo.standalonedevInfo.configMethods, buffer, &offset);
-                    CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.standalonedevInfo.p2PDeviceCap, buffer, &offset);
-                    CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.standalonedevInfo.primDeviceType.deviceDetails, buffer, &offset, ((u16) (8)));
-                    CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount, buffer, &offset);
-                    primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType = NULL;
-                    if (primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount)
-                    {
-                        primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType = kmalloc(sizeof(CsrWifiSmeWpsDeviceType) * primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount, GFP_KERNEL);
-                    }
-                    {
-                        u16 i4;
-                        for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.standalonedevInfo.secondaryDeviceTypeCount; i4++)
-                        {
-                            CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType[i4].deviceDetails, buffer, &offset, ((u16) (8)));
-                        }
-                    }
-                    CsrMemCpyDes(primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceName, buffer, &offset, ((u16) (32)));
-                    CsrUint8Des((u8 *) &primitive->scanResults[i1].deviceInfo.standalonedevInfo.deviceNameLength, buffer, &offset);
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeScanResultsGetCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeScanResultsGetCfm *primitive = (CsrWifiSmeScanResultsGetCfm *) voidPrimitivePointer;
-    {
-        u16 i1;
-        for (i1 = 0; i1 < primitive->scanResultsCount; i1++)
-        {
-            kfree(primitive->scanResults[i1].informationElements);
-            switch (primitive->scanResults[i1].p2pDeviceRole)
-            {
-                case CSR_WIFI_SME_P2P_ROLE_GO:
-                {
-                    u16 i4;
-                    for (i4 = 0; i4 < primitive->scanResults[i1].deviceInfo.groupInfo.p2pClientInfoCount; i4++)
-                    {
-                        kfree(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo[i4].clientDeviceInfo.secDeviceType);
-                    }
-                }
-                    kfree(primitive->scanResults[i1].deviceInfo.groupInfo.p2PClientInfo);
-                    break;
-                case CSR_WIFI_SME_P2P_ROLE_STANDALONE:
-                    kfree(primitive->scanResults[i1].deviceInfo.standalonedevInfo.secDeviceType);
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-    kfree(primitive->scanResults);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeSmeStaConfigGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* u8 primitive->smeConfig.connectionQualityRssiChangeTrigger */
-    bufferSize += 1; /* u8 primitive->smeConfig.connectionQualitySnrChangeTrigger */
-    bufferSize += 1; /* CsrWifiSmeWmmModeMask primitive->smeConfig.wmmModeMask */
-    bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */
-    bufferSize += 1; /* u8 primitive->smeConfig.allowUnicastUseGroupCipher */
-    bufferSize += 1; /* u8 primitive->smeConfig.enableOpportunisticKeyCaching */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeSmeStaConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeSmeStaConfigGetCfm *primitive = (CsrWifiSmeSmeStaConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.connectionQualityRssiChangeTrigger);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.connectionQualitySnrChangeTrigger);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.wmmModeMask);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.ifIndex);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.allowUnicastUseGroupCipher);
-    CsrUint8Ser(ptr, len, (u8) primitive->smeConfig.enableOpportunisticKeyCaching);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeSmeStaConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeSmeStaConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeSmeStaConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.connectionQualityRssiChangeTrigger, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.connectionQualitySnrChangeTrigger, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.wmmModeMask, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.ifIndex, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.allowUnicastUseGroupCipher, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->smeConfig.enableOpportunisticKeyCaching, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeSmeStaConfigSetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 7) */
-    bufferSize += 2; /* u16 primitive->interfaceTag */
-    bufferSize += 2; /* CsrResult primitive->status */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeSmeStaConfigSetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeSmeStaConfigSetCfm *primitive = (CsrWifiSmeSmeStaConfigSetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeSmeStaConfigSetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeSmeStaConfigSetCfm *primitive = kmalloc(sizeof(CsrWifiSmeSmeStaConfigSetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeStationMacAddressGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 17) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 2; i1++)
-        {
-            bufferSize += 6; /* u8 primitive->stationMacAddress[i1].a[6] */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeStationMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeStationMacAddressGetCfm *primitive = (CsrWifiSmeStationMacAddressGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 2; i1++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->stationMacAddress[i1].a, ((u16) (6)));
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeStationMacAddressGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeStationMacAddressGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeStationMacAddressGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    {
-        u16 i1;
-        for (i1 = 0; i1 < 2; i1++)
-        {
-            CsrMemCpyDes(primitive->stationMacAddress[i1].a, buffer, &offset, ((u16) (6)));
-        }
-    }
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeTspecIndSizeof(void *msg)
-{
-    CsrWifiSmeTspecInd *primitive = (CsrWifiSmeTspecInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
-    bufferSize += 2;                      /* u16 primitive->interfaceTag */
-    bufferSize += 4;                      /* u32 primitive->transactionId */
-    bufferSize += 1;                      /* CsrWifiSmeTspecResultCode primitive->tspecResultCode */
-    bufferSize += 2;                      /* u16 primitive->tspecLength */
-    bufferSize += primitive->tspecLength; /* u8 primitive->tspec */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeTspecIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeTspecInd *primitive = (CsrWifiSmeTspecInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint32Ser(ptr, len, (u32) primitive->transactionId);
-    CsrUint8Ser(ptr, len, (u8) primitive->tspecResultCode);
-    CsrUint16Ser(ptr, len, (u16) primitive->tspecLength);
-    if (primitive->tspecLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->tspec, ((u16) (primitive->tspecLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeTspecIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeTspecInd *primitive = kmalloc(sizeof(CsrWifiSmeTspecInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->transactionId, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->tspecResultCode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->tspecLength, buffer, &offset);
-    if (primitive->tspecLength)
-    {
-        primitive->tspec = kmalloc(primitive->tspecLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->tspec, buffer, &offset, ((u16) (primitive->tspecLength)));
-    }
-    else
-    {
-        primitive->tspec = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeTspecIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeTspecInd *primitive = (CsrWifiSmeTspecInd *) voidPrimitivePointer;
-    kfree(primitive->tspec);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeTspecCfmSizeof(void *msg)
-{
-    CsrWifiSmeTspecCfm *primitive = (CsrWifiSmeTspecCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 15) */
-    bufferSize += 2;                      /* u16 primitive->interfaceTag */
-    bufferSize += 2;                      /* CsrResult primitive->status */
-    bufferSize += 4;                      /* u32 primitive->transactionId */
-    bufferSize += 1;                      /* CsrWifiSmeTspecResultCode primitive->tspecResultCode */
-    bufferSize += 2;                      /* u16 primitive->tspecLength */
-    bufferSize += primitive->tspecLength; /* u8 primitive->tspec */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeTspecCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeTspecCfm *primitive = (CsrWifiSmeTspecCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->interfaceTag);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint32Ser(ptr, len, (u32) primitive->transactionId);
-    CsrUint8Ser(ptr, len, (u8) primitive->tspecResultCode);
-    CsrUint16Ser(ptr, len, (u16) primitive->tspecLength);
-    if (primitive->tspecLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->tspec, ((u16) (primitive->tspecLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeTspecCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeTspecCfm *primitive = kmalloc(sizeof(CsrWifiSmeTspecCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->interfaceTag, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->transactionId, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->tspecResultCode, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->tspecLength, buffer, &offset);
-    if (primitive->tspecLength)
-    {
-        primitive->tspec = kmalloc(primitive->tspecLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->tspec, buffer, &offset, ((u16) (primitive->tspecLength)));
-    }
-    else
-    {
-        primitive->tspec = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeTspecCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeTspecCfm *primitive = (CsrWifiSmeTspecCfm *) voidPrimitivePointer;
-    kfree(primitive->tspec);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeVersionsGetCfmSizeof(void *msg)
-{
-    CsrWifiSmeVersionsGetCfm *primitive = (CsrWifiSmeVersionsGetCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 33) */
-    bufferSize += 2;                                                                                    /* CsrResult primitive->status */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.chipId */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.chipVersion */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.firmwareBuild */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.firmwarePatch */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.firmwareHip */
-    bufferSize += (primitive->versions.routerBuild ? strlen(primitive->versions.routerBuild) : 0) + 1;  /* char* primitive->versions.routerBuild (0 byte len + 1 for NULL Term) */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.routerHip */
-    bufferSize += (primitive->versions.smeBuild ? strlen(primitive->versions.smeBuild) : 0) + 1;        /* char* primitive->versions.smeBuild (0 byte len + 1 for NULL Term) */
-    bufferSize += 4;                                                                                    /* u32 primitive->versions.smeHip */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeVersionsGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeVersionsGetCfm *primitive = (CsrWifiSmeVersionsGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.chipId);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.chipVersion);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.firmwareBuild);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.firmwarePatch);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.firmwareHip);
-    CsrCharStringSer(ptr, len, primitive->versions.routerBuild);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.routerHip);
-    CsrCharStringSer(ptr, len, primitive->versions.smeBuild);
-    CsrUint32Ser(ptr, len, (u32) primitive->versions.smeHip);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeVersionsGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeVersionsGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeVersionsGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.chipId, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.chipVersion, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.firmwareBuild, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.firmwarePatch, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.firmwareHip, buffer, &offset);
-    CsrCharStringDes(&primitive->versions.routerBuild, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.routerHip, buffer, &offset);
-    CsrCharStringDes(&primitive->versions.smeBuild, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->versions.smeHip, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiSmeVersionsGetCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeVersionsGetCfm *primitive = (CsrWifiSmeVersionsGetCfm *) voidPrimitivePointer;
-    kfree(primitive->versions.routerBuild);
-    kfree(primitive->versions.smeBuild);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeCloakedSsidsGetCfmSizeof(void *msg)
-{
-    CsrWifiSmeCloakedSsidsGetCfm *primitive = (CsrWifiSmeCloakedSsidsGetCfm *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 39) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* u8 primitive->cloakedSsids.cloakedSsidsCount */
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++)
-        {
-            bufferSize += 32; /* u8 primitive->cloakedSsids.cloakedSsids[i2].ssid[32] */
-            bufferSize += 1;  /* u8 primitive->cloakedSsids.cloakedSsids[i2].length */
-        }
-    }
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCloakedSsidsGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCloakedSsidsGetCfm *primitive = (CsrWifiSmeCloakedSsidsGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->cloakedSsids.cloakedSsidsCount);
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++)
-        {
-            CsrMemCpySer(ptr, len, (const void *) primitive->cloakedSsids.cloakedSsids[i2].ssid, ((u16) (32)));
-            CsrUint8Ser(ptr, len, (u8) primitive->cloakedSsids.cloakedSsids[i2].length);
-        }
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCloakedSsidsGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCloakedSsidsGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeCloakedSsidsGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->cloakedSsids.cloakedSsidsCount, buffer, &offset);
-    primitive->cloakedSsids.cloakedSsids = NULL;
-    if (primitive->cloakedSsids.cloakedSsidsCount)
-    {
-        primitive->cloakedSsids.cloakedSsids = kmalloc(sizeof(CsrWifiSsid) * primitive->cloakedSsids.cloakedSsidsCount, GFP_KERNEL);
-    }
-    {
-        u16 i2;
-        for (i2 = 0; i2 < primitive->cloakedSsids.cloakedSsidsCount; i2++)
-        {
-            CsrMemCpyDes(primitive->cloakedSsids.cloakedSsids[i2].ssid, buffer, &offset, ((u16) (32)));
-            CsrUint8Des((u8 *) &primitive->cloakedSsids.cloakedSsids[i2].length, buffer, &offset);
-        }
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeCloakedSsidsGetCfmSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeCloakedSsidsGetCfm *primitive = (CsrWifiSmeCloakedSsidsGetCfm *) voidPrimitivePointer;
-    kfree(primitive->cloakedSsids.cloakedSsids);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeWifiOnIndSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 6; /* u8 primitive->address.a[6] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeWifiOnIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeWifiOnInd *primitive = (CsrWifiSmeWifiOnInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrMemCpySer(ptr, len, (const void *) primitive->address.a, ((u16) (6)));
-    return(ptr);
-}
-
-
-void* CsrWifiSmeWifiOnIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeWifiOnInd *primitive = kmalloc(sizeof(CsrWifiSmeWifiOnInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrMemCpyDes(primitive->address.a, buffer, &offset, ((u16) (6)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeSmeCommonConfigGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 1; /* CsrWifiSme80211dTrustLevel primitive->deviceConfig.trustLevel */
-    bufferSize += 2; /* u8 primitive->deviceConfig.countryCode[2] */
-    bufferSize += 1; /* CsrWifiSmeFirmwareDriverInterface primitive->deviceConfig.firmwareDriverInterface */
-    bufferSize += 1; /* u8 primitive->deviceConfig.enableStrictDraftN */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeSmeCommonConfigGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeSmeCommonConfigGetCfm *primitive = (CsrWifiSmeSmeCommonConfigGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint8Ser(ptr, len, (u8) primitive->deviceConfig.trustLevel);
-    CsrMemCpySer(ptr, len, (const void *) primitive->deviceConfig.countryCode, ((u16) (2)));
-    CsrUint8Ser(ptr, len, (u8) primitive->deviceConfig.firmwareDriverInterface);
-    CsrUint8Ser(ptr, len, (u8) primitive->deviceConfig.enableStrictDraftN);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeSmeCommonConfigGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeSmeCommonConfigGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeSmeCommonConfigGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->deviceConfig.trustLevel, buffer, &offset);
-    CsrMemCpyDes(primitive->deviceConfig.countryCode, buffer, &offset, ((u16) (2)));
-    CsrUint8Des((u8 *) &primitive->deviceConfig.firmwareDriverInterface, buffer, &offset);
-    CsrUint8Des((u8 *) &primitive->deviceConfig.enableStrictDraftN, buffer, &offset);
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeInterfaceCapabilityGetCfmSizeof(void *msg)
-{
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
-    bufferSize += 2; /* CsrResult primitive->status */
-    bufferSize += 2; /* u16 primitive->numInterfaces */
-    bufferSize += 2; /* u8 primitive->capBitmap[2] */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeInterfaceCapabilityGetCfmSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeInterfaceCapabilityGetCfm *primitive = (CsrWifiSmeInterfaceCapabilityGetCfm *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint16Ser(ptr, len, (u16) primitive->status);
-    CsrUint16Ser(ptr, len, (u16) primitive->numInterfaces);
-    CsrMemCpySer(ptr, len, (const void *) primitive->capBitmap, ((u16) (2)));
-    return(ptr);
-}
-
-
-void* CsrWifiSmeInterfaceCapabilityGetCfmDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeInterfaceCapabilityGetCfm *primitive = kmalloc(sizeof(CsrWifiSmeInterfaceCapabilityGetCfm), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->status, buffer, &offset);
-    CsrUint16Des((u16 *) &primitive->numInterfaces, buffer, &offset);
-    CsrMemCpyDes(primitive->capBitmap, buffer, &offset, ((u16) (2)));
-
-    return primitive;
-}
-
-
-size_t CsrWifiSmeErrorIndSizeof(void *msg)
-{
-    CsrWifiSmeErrorInd *primitive = (CsrWifiSmeErrorInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 3) */
-    bufferSize += (primitive->errorMessage ? strlen(primitive->errorMessage) : 0) + 1; /* char* primitive->errorMessage (0 byte len + 1 for NULL Term) */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeErrorIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeErrorInd *primitive = (CsrWifiSmeErrorInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrCharStringSer(ptr, len, primitive->errorMessage);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeErrorIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeErrorInd *primitive = kmalloc(sizeof(CsrWifiSmeErrorInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrCharStringDes(&primitive->errorMessage, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiSmeErrorIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeErrorInd *primitive = (CsrWifiSmeErrorInd *) voidPrimitivePointer;
-    kfree(primitive->errorMessage);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeInfoIndSizeof(void *msg)
-{
-    CsrWifiSmeInfoInd *primitive = (CsrWifiSmeInfoInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 3) */
-    bufferSize += (primitive->infoMessage ? strlen(primitive->infoMessage) : 0) + 1; /* char* primitive->infoMessage (0 byte len + 1 for NULL Term) */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeInfoIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeInfoInd *primitive = (CsrWifiSmeInfoInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrCharStringSer(ptr, len, primitive->infoMessage);
-    return(ptr);
-}
-
-
-void* CsrWifiSmeInfoIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeInfoInd *primitive = kmalloc(sizeof(CsrWifiSmeInfoInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrCharStringDes(&primitive->infoMessage, buffer, &offset);
-
-    return primitive;
-}
-
-
-void CsrWifiSmeInfoIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeInfoInd *primitive = (CsrWifiSmeInfoInd *) voidPrimitivePointer;
-    kfree(primitive->infoMessage);
-    kfree(primitive);
-}
-
-
-size_t CsrWifiSmeCoreDumpIndSizeof(void *msg)
-{
-    CsrWifiSmeCoreDumpInd *primitive = (CsrWifiSmeCoreDumpInd *) msg;
-    size_t bufferSize = 2;
-
-    /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
-    bufferSize += 4;                     /* u32 primitive->dataLength */
-    bufferSize += primitive->dataLength; /* u8 primitive->data */
-    return bufferSize;
-}
-
-
-u8* CsrWifiSmeCoreDumpIndSer(u8 *ptr, size_t *len, void *msg)
-{
-    CsrWifiSmeCoreDumpInd *primitive = (CsrWifiSmeCoreDumpInd *)msg;
-    *len = 0;
-    CsrUint16Ser(ptr, len, primitive->common.type);
-    CsrUint32Ser(ptr, len, (u32) primitive->dataLength);
-    if (primitive->dataLength)
-    {
-        CsrMemCpySer(ptr, len, (const void *) primitive->data, ((u16) (primitive->dataLength)));
-    }
-    return(ptr);
-}
-
-
-void* CsrWifiSmeCoreDumpIndDes(u8 *buffer, size_t length)
-{
-    CsrWifiSmeCoreDumpInd *primitive = kmalloc(sizeof(CsrWifiSmeCoreDumpInd), GFP_KERNEL);
-    size_t offset;
-    offset = 0;
-
-    CsrUint16Des(&primitive->common.type, buffer, &offset);
-    CsrUint32Des((u32 *) &primitive->dataLength, buffer, &offset);
-    if (primitive->dataLength)
-    {
-        primitive->data = kmalloc(primitive->dataLength, GFP_KERNEL);
-        CsrMemCpyDes(primitive->data, buffer, &offset, ((u16) (primitive->dataLength)));
-    }
-    else
-    {
-        primitive->data = NULL;
-    }
-
-    return primitive;
-}
-
-
-void CsrWifiSmeCoreDumpIndSerFree(void *voidPrimitivePointer)
-{
-    CsrWifiSmeCoreDumpInd *primitive = (CsrWifiSmeCoreDumpInd *) voidPrimitivePointer;
-    kfree(primitive->data);
-    kfree(primitive);
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_serialize.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_serialize.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_serialize.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_serialize.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,666 +0,0 @@
-/*****************************************************************************
-
-	(c) Cambridge Silicon Radio Limited 2012
-	All rights reserved and confidential information of CSR
-
-	Refer to LICENSE.txt included with this source for details
-	on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_SME_SERIALIZE_H__
-#define CSR_WIFI_SME_SERIALIZE_H__
-
-#include "csr_wifi_msgconv.h"
-#include "csr_wifi_sme_prim.h"
-
-extern void CsrWifiSmePfree(void *ptr);
-
-#define CsrWifiSmeActivateReqSer CsrWifiEventSer
-#define CsrWifiSmeActivateReqDes CsrWifiEventDes
-#define CsrWifiSmeActivateReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeActivateReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeAdhocConfigGetReqSer CsrWifiEventSer
-#define CsrWifiSmeAdhocConfigGetReqDes CsrWifiEventDes
-#define CsrWifiSmeAdhocConfigGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeAdhocConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeAdhocConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeAdhocConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeAdhocConfigSetReqSizeof(void *msg);
-#define CsrWifiSmeAdhocConfigSetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeBlacklistReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeBlacklistReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeBlacklistReqSizeof(void *msg);
-extern void CsrWifiSmeBlacklistReqSerFree(void *msg);
-
-#define CsrWifiSmeCalibrationDataGetReqSer CsrWifiEventSer
-#define CsrWifiSmeCalibrationDataGetReqDes CsrWifiEventDes
-#define CsrWifiSmeCalibrationDataGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeCalibrationDataGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeCalibrationDataSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCalibrationDataSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCalibrationDataSetReqSizeof(void *msg);
-extern void CsrWifiSmeCalibrationDataSetReqSerFree(void *msg);
-
-#define CsrWifiSmeCcxConfigGetReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeCcxConfigGetReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeCcxConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeCcxConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeCcxConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCcxConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCcxConfigSetReqSizeof(void *msg);
-#define CsrWifiSmeCcxConfigSetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeCoexConfigGetReqSer CsrWifiEventSer
-#define CsrWifiSmeCoexConfigGetReqDes CsrWifiEventDes
-#define CsrWifiSmeCoexConfigGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeCoexConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeCoexConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCoexConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCoexConfigSetReqSizeof(void *msg);
-#define CsrWifiSmeCoexConfigSetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeCoexInfoGetReqSer CsrWifiEventSer
-#define CsrWifiSmeCoexInfoGetReqDes CsrWifiEventDes
-#define CsrWifiSmeCoexInfoGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeCoexInfoGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeConnectReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeConnectReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeConnectReqSizeof(void *msg);
-extern void CsrWifiSmeConnectReqSerFree(void *msg);
-
-#define CsrWifiSmeConnectionConfigGetReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeConnectionConfigGetReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeConnectionConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeConnectionConfigGetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeConnectionInfoGetReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeConnectionInfoGetReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeConnectionInfoGetReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeConnectionInfoGetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeConnectionStatsGetReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeConnectionStatsGetReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeConnectionStatsGetReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeConnectionStatsGetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeDeactivateReqSer CsrWifiEventSer
-#define CsrWifiSmeDeactivateReqDes CsrWifiEventDes
-#define CsrWifiSmeDeactivateReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeDeactivateReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeDisconnectReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeDisconnectReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeDisconnectReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeDisconnectReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeEventMaskSetReqSer CsrWifiEventCsrUint32Ser
-#define CsrWifiSmeEventMaskSetReqDes CsrWifiEventCsrUint32Des
-#define CsrWifiSmeEventMaskSetReqSizeof CsrWifiEventCsrUint32Sizeof
-#define CsrWifiSmeEventMaskSetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeHostConfigGetReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeHostConfigGetReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeHostConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeHostConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeHostConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeHostConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeHostConfigSetReqSizeof(void *msg);
-#define CsrWifiSmeHostConfigSetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeKeyReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeKeyReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeKeyReqSizeof(void *msg);
-#define CsrWifiSmeKeyReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeLinkQualityGetReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeLinkQualityGetReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeLinkQualityGetReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeLinkQualityGetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeMibConfigGetReqSer CsrWifiEventSer
-#define CsrWifiSmeMibConfigGetReqDes CsrWifiEventDes
-#define CsrWifiSmeMibConfigGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeMibConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeMibConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMibConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMibConfigSetReqSizeof(void *msg);
-#define CsrWifiSmeMibConfigSetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeMibGetNextReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMibGetNextReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMibGetNextReqSizeof(void *msg);
-extern void CsrWifiSmeMibGetNextReqSerFree(void *msg);
-
-extern u8 *CsrWifiSmeMibGetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMibGetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMibGetReqSizeof(void *msg);
-extern void CsrWifiSmeMibGetReqSerFree(void *msg);
-
-extern u8 *CsrWifiSmeMibSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMibSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMibSetReqSizeof(void *msg);
-extern void CsrWifiSmeMibSetReqSerFree(void *msg);
-
-extern u8 *CsrWifiSmeMulticastAddressReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMulticastAddressReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMulticastAddressReqSizeof(void *msg);
-extern void CsrWifiSmeMulticastAddressReqSerFree(void *msg);
-
-extern u8 *CsrWifiSmePacketFilterSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmePacketFilterSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmePacketFilterSetReqSizeof(void *msg);
-extern void CsrWifiSmePacketFilterSetReqSerFree(void *msg);
-
-#define CsrWifiSmePermanentMacAddressGetReqSer CsrWifiEventSer
-#define CsrWifiSmePermanentMacAddressGetReqDes CsrWifiEventDes
-#define CsrWifiSmePermanentMacAddressGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmePermanentMacAddressGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmePmkidReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmePmkidReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmePmkidReqSizeof(void *msg);
-extern void CsrWifiSmePmkidReqSerFree(void *msg);
-
-#define CsrWifiSmePowerConfigGetReqSer CsrWifiEventSer
-#define CsrWifiSmePowerConfigGetReqDes CsrWifiEventDes
-#define CsrWifiSmePowerConfigGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmePowerConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmePowerConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmePowerConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmePowerConfigSetReqSizeof(void *msg);
-#define CsrWifiSmePowerConfigSetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeRegulatoryDomainInfoGetReqSer CsrWifiEventSer
-#define CsrWifiSmeRegulatoryDomainInfoGetReqDes CsrWifiEventDes
-#define CsrWifiSmeRegulatoryDomainInfoGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeRegulatoryDomainInfoGetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeRoamingConfigGetReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeRoamingConfigGetReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeRoamingConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeRoamingConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeRoamingConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeRoamingConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeRoamingConfigSetReqSizeof(void *msg);
-#define CsrWifiSmeRoamingConfigSetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeScanConfigGetReqSer CsrWifiEventSer
-#define CsrWifiSmeScanConfigGetReqDes CsrWifiEventDes
-#define CsrWifiSmeScanConfigGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeScanConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeScanConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeScanConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeScanConfigSetReqSizeof(void *msg);
-extern void CsrWifiSmeScanConfigSetReqSerFree(void *msg);
-
-extern u8 *CsrWifiSmeScanFullReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeScanFullReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeScanFullReqSizeof(void *msg);
-extern void CsrWifiSmeScanFullReqSerFree(void *msg);
-
-#define CsrWifiSmeScanResultsFlushReqSer CsrWifiEventSer
-#define CsrWifiSmeScanResultsFlushReqDes CsrWifiEventDes
-#define CsrWifiSmeScanResultsFlushReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeScanResultsFlushReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeScanResultsGetReqSer CsrWifiEventSer
-#define CsrWifiSmeScanResultsGetReqDes CsrWifiEventDes
-#define CsrWifiSmeScanResultsGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeScanResultsGetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeSmeStaConfigGetReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeSmeStaConfigGetReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeSmeStaConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeSmeStaConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeSmeStaConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeSmeStaConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg);
-#define CsrWifiSmeSmeStaConfigSetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeStationMacAddressGetReqSer CsrWifiEventSer
-#define CsrWifiSmeStationMacAddressGetReqDes CsrWifiEventDes
-#define CsrWifiSmeStationMacAddressGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeStationMacAddressGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeTspecReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeTspecReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeTspecReqSizeof(void *msg);
-extern void CsrWifiSmeTspecReqSerFree(void *msg);
-
-#define CsrWifiSmeVersionsGetReqSer CsrWifiEventSer
-#define CsrWifiSmeVersionsGetReqDes CsrWifiEventDes
-#define CsrWifiSmeVersionsGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeVersionsGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeWifiFlightmodeReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeWifiFlightmodeReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeWifiFlightmodeReqSizeof(void *msg);
-extern void CsrWifiSmeWifiFlightmodeReqSerFree(void *msg);
-
-#define CsrWifiSmeWifiOffReqSer CsrWifiEventSer
-#define CsrWifiSmeWifiOffReqDes CsrWifiEventDes
-#define CsrWifiSmeWifiOffReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeWifiOffReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeWifiOnReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeWifiOnReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeWifiOnReqSizeof(void *msg);
-extern void CsrWifiSmeWifiOnReqSerFree(void *msg);
-
-extern u8 *CsrWifiSmeCloakedSsidsSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCloakedSsidsSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCloakedSsidsSetReqSizeof(void *msg);
-extern void CsrWifiSmeCloakedSsidsSetReqSerFree(void *msg);
-
-#define CsrWifiSmeCloakedSsidsGetReqSer CsrWifiEventSer
-#define CsrWifiSmeCloakedSsidsGetReqDes CsrWifiEventDes
-#define CsrWifiSmeCloakedSsidsGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeCloakedSsidsGetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeSmeCommonConfigGetReqSer CsrWifiEventSer
-#define CsrWifiSmeSmeCommonConfigGetReqDes CsrWifiEventDes
-#define CsrWifiSmeSmeCommonConfigGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeSmeCommonConfigGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeSmeCommonConfigSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeSmeCommonConfigSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeSmeCommonConfigSetReqSizeof(void *msg);
-#define CsrWifiSmeSmeCommonConfigSetReqSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeInterfaceCapabilityGetReqSer CsrWifiEventSer
-#define CsrWifiSmeInterfaceCapabilityGetReqDes CsrWifiEventDes
-#define CsrWifiSmeInterfaceCapabilityGetReqSizeof CsrWifiEventSizeof
-#define CsrWifiSmeInterfaceCapabilityGetReqSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeWpsConfigurationReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeWpsConfigurationReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeWpsConfigurationReqSizeof(void *msg);
-extern void CsrWifiSmeWpsConfigurationReqSerFree(void *msg);
-
-extern u8 *CsrWifiSmeSetReqSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeSetReqDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeSetReqSizeof(void *msg);
-extern void CsrWifiSmeSetReqSerFree(void *msg);
-
-#define CsrWifiSmeActivateCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeActivateCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeActivateCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeActivateCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeAdhocConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeAdhocConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg);
-#define CsrWifiSmeAdhocConfigGetCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeAdhocConfigSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeAdhocConfigSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeAdhocConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeAdhocConfigSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeAssociationCompleteIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeAssociationCompleteIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeAssociationCompleteIndSizeof(void *msg);
-extern void CsrWifiSmeAssociationCompleteIndSerFree(void *msg);
-
-extern u8 *CsrWifiSmeAssociationStartIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeAssociationStartIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeAssociationStartIndSizeof(void *msg);
-#define CsrWifiSmeAssociationStartIndSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeBlacklistCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeBlacklistCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeBlacklistCfmSizeof(void *msg);
-extern void CsrWifiSmeBlacklistCfmSerFree(void *msg);
-
-extern u8 *CsrWifiSmeCalibrationDataGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCalibrationDataGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCalibrationDataGetCfmSizeof(void *msg);
-extern void CsrWifiSmeCalibrationDataGetCfmSerFree(void *msg);
-
-#define CsrWifiSmeCalibrationDataSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeCalibrationDataSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeCalibrationDataSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeCalibrationDataSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeCcxConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCcxConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCcxConfigGetCfmSizeof(void *msg);
-#define CsrWifiSmeCcxConfigGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeCcxConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCcxConfigSetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCcxConfigSetCfmSizeof(void *msg);
-#define CsrWifiSmeCcxConfigSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeCoexConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCoexConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCoexConfigGetCfmSizeof(void *msg);
-#define CsrWifiSmeCoexConfigGetCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeCoexConfigSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeCoexConfigSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeCoexConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeCoexConfigSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeCoexInfoGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCoexInfoGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCoexInfoGetCfmSizeof(void *msg);
-#define CsrWifiSmeCoexInfoGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeConnectCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeConnectCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeConnectCfmSizeof(void *msg);
-#define CsrWifiSmeConnectCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeConnectionConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeConnectionConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeConnectionConfigGetCfmSizeof(void *msg);
-extern void CsrWifiSmeConnectionConfigGetCfmSerFree(void *msg);
-
-extern u8 *CsrWifiSmeConnectionInfoGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeConnectionInfoGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeConnectionInfoGetCfmSizeof(void *msg);
-extern void CsrWifiSmeConnectionInfoGetCfmSerFree(void *msg);
-
-extern u8 *CsrWifiSmeConnectionQualityIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeConnectionQualityIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeConnectionQualityIndSizeof(void *msg);
-#define CsrWifiSmeConnectionQualityIndSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeConnectionStatsGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeConnectionStatsGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeConnectionStatsGetCfmSizeof(void *msg);
-#define CsrWifiSmeConnectionStatsGetCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeDeactivateCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeDeactivateCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeDeactivateCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeDeactivateCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeDisconnectCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeDisconnectCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeDisconnectCfmSizeof(void *msg);
-#define CsrWifiSmeDisconnectCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeEventMaskSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeEventMaskSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeEventMaskSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeEventMaskSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeHostConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeHostConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeHostConfigGetCfmSizeof(void *msg);
-#define CsrWifiSmeHostConfigGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeHostConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeHostConfigSetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeHostConfigSetCfmSizeof(void *msg);
-#define CsrWifiSmeHostConfigSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeIbssStationIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeIbssStationIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeIbssStationIndSizeof(void *msg);
-#define CsrWifiSmeIbssStationIndSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeKeyCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeKeyCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeKeyCfmSizeof(void *msg);
-#define CsrWifiSmeKeyCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeLinkQualityGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeLinkQualityGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeLinkQualityGetCfmSizeof(void *msg);
-#define CsrWifiSmeLinkQualityGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeMediaStatusIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMediaStatusIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMediaStatusIndSizeof(void *msg);
-extern void CsrWifiSmeMediaStatusIndSerFree(void *msg);
-
-extern u8 *CsrWifiSmeMibConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMibConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMibConfigGetCfmSizeof(void *msg);
-#define CsrWifiSmeMibConfigGetCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeMibConfigSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeMibConfigSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeMibConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeMibConfigSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeMibGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMibGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMibGetCfmSizeof(void *msg);
-extern void CsrWifiSmeMibGetCfmSerFree(void *msg);
-
-extern u8 *CsrWifiSmeMibGetNextCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMibGetNextCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMibGetNextCfmSizeof(void *msg);
-extern void CsrWifiSmeMibGetNextCfmSerFree(void *msg);
-
-#define CsrWifiSmeMibSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeMibSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeMibSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeMibSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeMicFailureIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMicFailureIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMicFailureIndSizeof(void *msg);
-#define CsrWifiSmeMicFailureIndSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeMulticastAddressCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeMulticastAddressCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeMulticastAddressCfmSizeof(void *msg);
-extern void CsrWifiSmeMulticastAddressCfmSerFree(void *msg);
-
-extern u8 *CsrWifiSmePacketFilterSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmePacketFilterSetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmePacketFilterSetCfmSizeof(void *msg);
-#define CsrWifiSmePacketFilterSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmePermanentMacAddressGetCfmSer(u8 *ptr, size_t *len,
-	void *msg);
-extern void *CsrWifiSmePermanentMacAddressGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmePermanentMacAddressGetCfmSizeof(void *msg);
-#define CsrWifiSmePermanentMacAddressGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmePmkidCandidateListIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmePmkidCandidateListIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmePmkidCandidateListIndSizeof(void *msg);
-extern void CsrWifiSmePmkidCandidateListIndSerFree(void *msg);
-
-extern u8 *CsrWifiSmePmkidCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmePmkidCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmePmkidCfmSizeof(void *msg);
-extern void CsrWifiSmePmkidCfmSerFree(void *msg);
-
-extern u8 *CsrWifiSmePowerConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmePowerConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmePowerConfigGetCfmSizeof(void *msg);
-#define CsrWifiSmePowerConfigGetCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmePowerConfigSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmePowerConfigSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmePowerConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmePowerConfigSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeRegulatoryDomainInfoGetCfmSer(u8 *ptr, size_t *len,
-	void *msg);
-extern void *CsrWifiSmeRegulatoryDomainInfoGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeRegulatoryDomainInfoGetCfmSizeof(void *msg);
-#define CsrWifiSmeRegulatoryDomainInfoGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeRoamCompleteIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeRoamCompleteIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeRoamCompleteIndSizeof(void *msg);
-#define CsrWifiSmeRoamCompleteIndSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeRoamStartIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeRoamStartIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeRoamStartIndSizeof(void *msg);
-#define CsrWifiSmeRoamStartIndSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeRoamingConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeRoamingConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeRoamingConfigGetCfmSizeof(void *msg);
-#define CsrWifiSmeRoamingConfigGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeRoamingConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeRoamingConfigSetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeRoamingConfigSetCfmSizeof(void *msg);
-#define CsrWifiSmeRoamingConfigSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeScanConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeScanConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeScanConfigGetCfmSizeof(void *msg);
-extern void CsrWifiSmeScanConfigGetCfmSerFree(void *msg);
-
-#define CsrWifiSmeScanConfigSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeScanConfigSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeScanConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeScanConfigSetCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeScanFullCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeScanFullCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeScanFullCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeScanFullCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeScanResultIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeScanResultIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeScanResultIndSizeof(void *msg);
-extern void CsrWifiSmeScanResultIndSerFree(void *msg);
-
-#define CsrWifiSmeScanResultsFlushCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeScanResultsFlushCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeScanResultsFlushCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeScanResultsFlushCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeScanResultsGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeScanResultsGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeScanResultsGetCfmSizeof(void *msg);
-extern void CsrWifiSmeScanResultsGetCfmSerFree(void *msg);
-
-extern u8 *CsrWifiSmeSmeStaConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeSmeStaConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeSmeStaConfigGetCfmSizeof(void *msg);
-#define CsrWifiSmeSmeStaConfigGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeSmeStaConfigSetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeSmeStaConfigSetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeSmeStaConfigSetCfmSizeof(void *msg);
-#define CsrWifiSmeSmeStaConfigSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeStationMacAddressGetCfmSer(u8 *ptr, size_t *len,
-	void *msg);
-extern void *CsrWifiSmeStationMacAddressGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeStationMacAddressGetCfmSizeof(void *msg);
-#define CsrWifiSmeStationMacAddressGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeTspecIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeTspecIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeTspecIndSizeof(void *msg);
-extern void CsrWifiSmeTspecIndSerFree(void *msg);
-
-extern u8 *CsrWifiSmeTspecCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeTspecCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeTspecCfmSizeof(void *msg);
-extern void CsrWifiSmeTspecCfmSerFree(void *msg);
-
-extern u8 *CsrWifiSmeVersionsGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeVersionsGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeVersionsGetCfmSizeof(void *msg);
-extern void CsrWifiSmeVersionsGetCfmSerFree(void *msg);
-
-#define CsrWifiSmeWifiFlightmodeCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeWifiFlightmodeCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeWifiFlightmodeCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeWifiFlightmodeCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeWifiOffIndSer CsrWifiEventCsrUint8Ser
-#define CsrWifiSmeWifiOffIndDes CsrWifiEventCsrUint8Des
-#define CsrWifiSmeWifiOffIndSizeof CsrWifiEventCsrUint8Sizeof
-#define CsrWifiSmeWifiOffIndSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeWifiOffCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeWifiOffCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeWifiOffCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeWifiOffCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeWifiOnCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeWifiOnCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeWifiOnCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeWifiOnCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeCloakedSsidsSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeCloakedSsidsSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeCloakedSsidsSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeCloakedSsidsSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeCloakedSsidsGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCloakedSsidsGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCloakedSsidsGetCfmSizeof(void *msg);
-extern void CsrWifiSmeCloakedSsidsGetCfmSerFree(void *msg);
-
-extern u8 *CsrWifiSmeWifiOnIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeWifiOnIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeWifiOnIndSizeof(void *msg);
-#define CsrWifiSmeWifiOnIndSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeSmeCommonConfigGetCfmSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeSmeCommonConfigGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeSmeCommonConfigGetCfmSizeof(void *msg);
-#define CsrWifiSmeSmeCommonConfigGetCfmSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeSmeCommonConfigSetCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeSmeCommonConfigSetCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeSmeCommonConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeSmeCommonConfigSetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeInterfaceCapabilityGetCfmSer(u8 *ptr, size_t *len,
-	void *msg);
-extern void *CsrWifiSmeInterfaceCapabilityGetCfmDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeInterfaceCapabilityGetCfmSizeof(void *msg);
-#define CsrWifiSmeInterfaceCapabilityGetCfmSerFree CsrWifiSmePfree
-
-extern u8 *CsrWifiSmeErrorIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeErrorIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeErrorIndSizeof(void *msg);
-extern void CsrWifiSmeErrorIndSerFree(void *msg);
-
-extern u8 *CsrWifiSmeInfoIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeInfoIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeInfoIndSizeof(void *msg);
-extern void CsrWifiSmeInfoIndSerFree(void *msg);
-
-extern u8 *CsrWifiSmeCoreDumpIndSer(u8 *ptr, size_t *len, void *msg);
-extern void *CsrWifiSmeCoreDumpIndDes(u8 *buffer, size_t len);
-extern size_t CsrWifiSmeCoreDumpIndSizeof(void *msg);
-extern void CsrWifiSmeCoreDumpIndSerFree(void *msg);
-
-#define CsrWifiSmeAmpStatusChangeIndSer CsrWifiEventCsrUint16CsrUint8Ser
-#define CsrWifiSmeAmpStatusChangeIndDes CsrWifiEventCsrUint16CsrUint8Des
-#define CsrWifiSmeAmpStatusChangeIndSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
-#define CsrWifiSmeAmpStatusChangeIndSerFree CsrWifiSmePfree
-
-#define CsrWifiSmeWpsConfigurationCfmSer CsrWifiEventCsrUint16Ser
-#define CsrWifiSmeWpsConfigurationCfmDes CsrWifiEventCsrUint16Des
-#define CsrWifiSmeWpsConfigurationCfmSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiSmeWpsConfigurationCfmSerFree CsrWifiSmePfree
-
-#endif /* CSR_WIFI_SME_SERIALIZE_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_task.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_task.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_sme_task.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_sme_task.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/*****************************************************************************
-
-	(c) Cambridge Silicon Radio Limited 2011
-	All rights reserved and confidential information of CSR
-
-	Refer to LICENSE.txt included with this source for details
-	on the license terms.
-
-*****************************************************************************/
-
-/* Note: this is an auto-generated file. */
-
-#ifndef CSR_WIFI_SME_TASK_H__
-#define CSR_WIFI_SME_TASK_H__
-
-#include "csr_sched.h"
-
-#define CSR_WIFI_SME_LOG_ID 0x1202FFFF
-extern CsrSchedQid CSR_WIFI_SME_IFACEQUEUE;
-void CsrWifiSmeInit(void **gash);
-void CsrWifiSmeDeinit(void **gash);
-void CsrWifiSmeHandler(void **gash);
-
-#endif /* CSR_WIFI_SME_TASK_H__ */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_vif_utils.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_vif_utils.h
--- linux-libre-3.10-gnu/drivers/staging/csr/csr_wifi_vif_utils.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/csr_wifi_vif_utils.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-/*****************************************************************************
-
-            (c) Cambridge Silicon Radio Limited 2011
-            All rights reserved and confidential information of CSR
-
-            Refer to LICENSE.txt included with this source for details
-            on the license terms.
-
-*****************************************************************************/
-
-#ifndef CSR_WIFI_VIF_UTILS_H
-#define CSR_WIFI_VIF_UTILS_H
-
-/* STANDARD INCLUDES ********************************************************/
-
-/* PROJECT INCLUDES *********************************************************/
-/* including this file for CsrWifiInterfaceMode*/
-#include "csr_wifi_private_common.h"
-
-/* MACROS *******************************************************************/
-
-/* Common macros for NME and SME to be used temporarily until SoftMAC changes are made */
-#define CSR_WIFI_NUM_INTERFACES        (u8)0x1
-#define CSR_WIFI_INTERFACE_IN_USE      (u16)0x0
-
-#endif /* CSR_WIFI_VIF_UTILS_H */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/data_tx.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/data_tx.c
--- linux-libre-3.10-gnu/drivers/staging/csr/data_tx.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/data_tx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     data_tx.c
- *
- * PURPOSE:
- *      This file provides functions to send data requests to the UniFi.
- *
- * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include "csr_wifi_hip_unifi.h"
-#include "unifi_priv.h"
-
-int
-uf_verify_m4(unifi_priv_t *priv, const unsigned char *packet, unsigned int length)
-{
-	const unsigned char *p = packet;
-	u16 keyinfo;
-
-
-	if (length < (4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1 + 8))
-		return 1;
-
-	p += 8;
-	keyinfo = p[5] << 8 | p[6]; /* big-endian */
-	if (
-	  (p[0] == 1 || p[0] == 2) /* protocol version 802.1X-2001 (WPA) or -2004 (WPA2) */ &&
-	  p[1] == 3 /* EAPOL-Key */ &&
-	  /* don't bother checking p[2] p[3] (hh ll, packet body length) */
-	  (p[4] == 254 || p[4] == 2) /* descriptor type P802.1i-D3.0 (WPA) or 802.11i-2004 (WPA2) */ &&
-	  ((keyinfo & 0x0007) == 1 || (keyinfo & 0x0007) == 2) /* key descriptor version */ &&
-	 (keyinfo & ~0x0207U) == 0x0108 && /* key info for 4/4 or 4/2 -- ignore key desc version and sec bit (since varies in WPA 4/4) */
-	  (p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 0] == 0 && /* key data length (2 octets) 0 for 4/4 only */
-	   p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1] == 0)
-	) {
-		unifi_trace(priv, UDBG1, "uf_verify_m4: M4 detected\n");
-		return 0;
-	} else {
-		return 1;
-	}
-}
-
-/*
- * ---------------------------------------------------------------------------
- *
- *      Data transport signals.
- *
- * ---------------------------------------------------------------------------
- */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/drv.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/drv.c
--- linux-libre-3.10-gnu/drivers/staging/csr/drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/drv.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2193 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     drv.c
- *
- *  PURPOSE:
- *      Conventional device interface for debugging/monitoring of the
- *      driver and h/w using unicli. This interface is also being used
- *      by the SME linux implementation and the helper apps.
- *
- * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-
-/*
- * Porting Notes:
- * Part of this file contains an example for how to glue the OS layer
- * with the HIP core lib, the SDIO glue layer, and the SME.
- *
- * When the unifi_sdio.ko modules loads, the linux kernel calls unifi_load().
- * unifi_load() calls uf_sdio_load() which is exported by the SDIO glue
- * layer. uf_sdio_load() registers this driver with the underlying SDIO driver.
- * When a card is detected, the SDIO glue layer calls register_unifi_sdio()
- * to pass the SDIO function context and ask the OS layer to initialise
- * the card. register_unifi_sdio() allocates all the private data of the OS
- * layer and calls uf_run_unifihelper() to start the SME. The SME calls
- * unifi_sys_wifi_on_req() which uses the HIP core lib to initialise the card.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <asm/uaccess.h>
-#include <linux/jiffies.h>
-#include <linux/version.h>
-
-#include "csr_wifi_hip_unifiversion.h"
-#include "unifi_priv.h"
-#include "csr_wifi_hip_conversions.h"
-#include "unifi_native.h"
-
-/* Module parameter variables */
-int buswidth = 0;               /* 0 means use default, values 1,4 */
-int sdio_clock = 50000;         /* kHz */
-int unifi_debug = 0;
-/* fw_init prevents f/w initialisation on error. */
-int fw_init[MAX_UNIFI_DEVS] = {-1, -1};
-int use_5g = 0;
-int led_mask = 0;               /* 0x0c00 for dev-pc-1503c, dev-pc-1528a */
-int disable_hw_reset = 0;
-int disable_power_control = 0;
-int enable_wol = UNIFI_WOL_OFF; /* 0 for none, 1 for SDIO IRQ, 2 for PIO */
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-int tl_80211d = (int)CSR_WIFI_SME_80211D_TRUST_LEVEL_MIB;
-#endif
-int sdio_block_size = -1;      /* Override SDIO block size */
-int sdio_byte_mode = 0;        /* 0 for block mode + padding, 1 for byte mode */
-int coredump_max = CSR_WIFI_HIP_NUM_COREDUMP_BUFFERS;
-int run_bh_once = -1;          /* Set for scheduled interrupt mode, -1 = default */
-int bh_priority = -1;
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-#define UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA   (1 << 1)
-#define UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP  (1 << 2)
-int log_hip_signals = 0;
-#endif
-
-MODULE_DESCRIPTION("CSR UniFi (SDIO)");
-
-module_param(buswidth,    int, S_IRUGO|S_IWUSR);
-module_param(sdio_clock,  int, S_IRUGO|S_IWUSR);
-module_param(unifi_debug, int, S_IRUGO|S_IWUSR);
-module_param_array(fw_init, int, NULL, S_IRUGO|S_IWUSR);
-module_param(use_5g,      int, S_IRUGO|S_IWUSR);
-module_param(led_mask,    int, S_IRUGO|S_IWUSR);
-module_param(disable_hw_reset,  int, S_IRUGO|S_IWUSR);
-module_param(disable_power_control,  int, S_IRUGO|S_IWUSR);
-module_param(enable_wol,  int, S_IRUGO|S_IWUSR);
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-module_param(tl_80211d,   int, S_IRUGO|S_IWUSR);
-#endif
-module_param(sdio_block_size, int, S_IRUGO|S_IWUSR);
-module_param(sdio_byte_mode, int, S_IRUGO|S_IWUSR);
-module_param(coredump_max, int, S_IRUGO|S_IWUSR);
-module_param(run_bh_once, int, S_IRUGO|S_IWUSR);
-module_param(bh_priority, int, S_IRUGO|S_IWUSR);
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-module_param(log_hip_signals, int, S_IRUGO|S_IWUSR);
-#endif
-
-MODULE_PARM_DESC(buswidth, "SDIO bus width (0=default), set 1 for 1-bit or 4 for 4-bit mode");
-MODULE_PARM_DESC(sdio_clock, "SDIO bus frequency in kHz, (default = 50 MHz)");
-MODULE_PARM_DESC(unifi_debug, "Diagnostic reporting level");
-MODULE_PARM_DESC(fw_init, "Set to 0 to prevent f/w initialization on error");
-MODULE_PARM_DESC(use_5g, "Use the 5G (802.11a) radio band");
-MODULE_PARM_DESC(led_mask, "LED mask flags");
-MODULE_PARM_DESC(disable_hw_reset, "Set to 1 to disable hardware reset");
-MODULE_PARM_DESC(disable_power_control, "Set to 1 to disable SDIO power control");
-MODULE_PARM_DESC(enable_wol, "Enable wake-on-wlan function 0=off, 1=SDIO, 2=PIO");
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-MODULE_PARM_DESC(tl_80211d, "802.11d Trust Level (1-6, default = 5)");
-#endif
-MODULE_PARM_DESC(sdio_block_size, "Set to override SDIO block size");
-MODULE_PARM_DESC(sdio_byte_mode, "Set to 1 for byte mode SDIO");
-MODULE_PARM_DESC(coredump_max, "Number of chip mini-coredump buffers to allocate");
-MODULE_PARM_DESC(run_bh_once, "Run BH only when firmware interrupts");
-MODULE_PARM_DESC(bh_priority, "Modify the BH thread priority");
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-MODULE_PARM_DESC(log_hip_signals, "Set to 1 to enable HIP signal offline logging");
-#endif
-
-
-/* Callback for event logging to UDI clients */
-static void udi_log_event(ul_client_t *client,
-                          const u8 *signal, int signal_len,
-                          const bulk_data_param_t *bulkdata,
-                          int dir);
-
-static void udi_set_log_filter(ul_client_t *pcli,
-                               unifiio_filter_t *udi_filter);
-
-
-/* Mutex to protect access to  priv->sme_cli */
-DEFINE_SEMAPHORE(udi_mutex);
-
-s32 CsrHipResultToStatus(CsrResult csrResult)
-{
-    s32 r = -EIO;
-
-    switch (csrResult)
-    {
-    case CSR_RESULT_SUCCESS:
-        r = 0;
-        break;
-    case CSR_WIFI_HIP_RESULT_RANGE:
-        r = -ERANGE;
-        break;
-    case CSR_WIFI_HIP_RESULT_NO_DEVICE:
-        r = -ENODEV;
-        break;
-    case CSR_WIFI_HIP_RESULT_INVALID_VALUE:
-        r = -EINVAL;
-        break;
-    case CSR_WIFI_HIP_RESULT_NOT_FOUND:
-        r = -ENOENT;
-        break;
-    case CSR_WIFI_HIP_RESULT_NO_SPACE:
-        r = -ENOSPC;
-        break;
-    case CSR_WIFI_HIP_RESULT_NO_MEMORY:
-        r = -ENOMEM;
-        break;
-    case CSR_RESULT_FAILURE:
-        r = -EIO;
-        break;
-    default:
-        /*unifi_warning(card->ospriv, "CsrHipResultToStatus: Unrecognised csrResult error code: %d\n", csrResult);*/
-        r = -EIO;
-    }
-    return r;
-}
-
-
-static const char*
-trace_putest_cmdid(unifi_putest_command_t putest_cmd)
-{
-	switch (putest_cmd) {
-	case UNIFI_PUTEST_START:
-		return "START";
-	case UNIFI_PUTEST_STOP:
-		return "STOP";
-	case UNIFI_PUTEST_SET_SDIO_CLOCK:
-		return "SET CLOCK";
-	case UNIFI_PUTEST_CMD52_READ:
-		return "CMD52R";
-	case UNIFI_PUTEST_CMD52_BLOCK_READ:
-		return "CMD52BR";
-	case UNIFI_PUTEST_CMD52_WRITE:
-		return "CMD52W";
-	case UNIFI_PUTEST_DL_FW:
-		return "D/L FW";
-	case UNIFI_PUTEST_DL_FW_BUFF:
-		return "D/L FW BUFFER";
-	case UNIFI_PUTEST_COREDUMP_PREPARE:
-		return "PREPARE COREDUMP";
-	case UNIFI_PUTEST_GP_READ16:
-		return "GP16R";
-	case UNIFI_PUTEST_GP_WRITE16:
-		return "GP16W";
-	default:
-		return "ERROR: unrecognised command";
-	}
- }
-
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-int uf_register_hip_offline_debug(unifi_priv_t *priv)
-{
-    ul_client_t *udi_cli;
-    int i;
-
-    udi_cli = ul_register_client(priv, CLI_USING_WIRE_FORMAT, udi_log_event);
-    if (udi_cli == NULL) {
-        /* Too many clients already using this device */
-        unifi_error(priv, "Too many UDI clients already open\n");
-        return -ENOSPC;
-    }
-    unifi_trace(priv, UDBG1, "Offline HIP client is registered\n");
-
-    down(&priv->udi_logging_mutex);
-    udi_cli->event_hook = udi_log_event;
-    unifi_set_udi_hook(priv->card, logging_handler);
-    /* Log all signals by default */
-    for (i = 0; i < SIG_FILTER_SIZE; i++) {
-        udi_cli->signal_filter[i] = 0xFFFF;
-    }
-    priv->logging_client = udi_cli;
-    up(&priv->udi_logging_mutex);
-
-    return 0;
-}
-
-int uf_unregister_hip_offline_debug(unifi_priv_t *priv)
-{
-    ul_client_t *udi_cli = priv->logging_client;
-    if (udi_cli == NULL)
-    {
-        unifi_error(priv, "Unknown HIP client unregister request\n");
-        return -ERANGE;
-    }
-
-    unifi_trace(priv, UDBG1, "Offline HIP client is unregistered\n");
-
-    down(&priv->udi_logging_mutex);
-    priv->logging_client = NULL;
-    udi_cli->event_hook = NULL;
-    up(&priv->udi_logging_mutex);
-
-    ul_deregister_client(udi_cli);
-
-    return 0;
-}
-#endif
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_open
- *  unifi_release
- *
- *      Open and release entry points for the UniFi debug driver.
- *
- *  Arguments:
- *      Normal linux driver args.
- *
- *  Returns:
- *      Linux error code.
- * ---------------------------------------------------------------------------
- */
-static int
-unifi_open(struct inode *inode, struct file *file)
-{
-    int devno;
-    unifi_priv_t *priv;
-    ul_client_t *udi_cli;
-
-    devno = MINOR(inode->i_rdev) >> 1;
-
-    /*
-     * Increase the ref_count for the char device clients.
-     * Make sure you call uf_put_instance() to decreace it if
-     * unifi_open returns an error.
-     */
-    priv = uf_get_instance(devno);
-    if (priv == NULL) {
-        unifi_error(NULL, "unifi_open: No device present\n");
-        return -ENODEV;
-    }
-
-    /* Register this instance in the client's list. */
-    /* The minor number determines the nature of the client (Unicli or SME). */
-    if (MINOR(inode->i_rdev) & 0x1) {
-        udi_cli = ul_register_client(priv, CLI_USING_WIRE_FORMAT, udi_log_event);
-        if (udi_cli == NULL) {
-            /* Too many clients already using this device */
-            unifi_error(priv, "Too many clients already open\n");
-            uf_put_instance(devno);
-            return -ENOSPC;
-        }
-        unifi_trace(priv, UDBG1, "Client is registered to /dev/unifiudi%d\n", devno);
-    } else {
-        /*
-         * Even-numbered device nodes are the control application.
-         * This is the userspace helper containing SME or
-         * unifi_manager.
-         */
-
-        down(&udi_mutex);
-
-#ifdef CSR_SME_USERSPACE
-        /* Check if a config client is already attached */
-        if (priv->sme_cli) {
-            up(&udi_mutex);
-            uf_put_instance(devno);
-
-            unifi_info(priv, "There is already a configuration client using the character device\n");
-            return -EBUSY;
-        }
-#endif /* CSR_SME_USERSPACE */
-
-#ifdef CSR_SUPPORT_SME
-        udi_cli = ul_register_client(priv,
-                                     CLI_USING_WIRE_FORMAT | CLI_SME_USERSPACE,
-                                     sme_log_event);
-#else
-        /* Config client for native driver */
-        udi_cli = ul_register_client(priv,
-                                     0,
-                                     sme_native_log_event);
-#endif
-        if (udi_cli == NULL) {
-            /* Too many clients already using this device */
-            up(&udi_mutex);
-            uf_put_instance(devno);
-
-            unifi_error(priv, "Too many clients already open\n");
-            return -ENOSPC;
-        }
-
-        /*
-         * Fill-in the pointer to the configuration client.
-         * This is the SME userspace helper or unifi_manager.
-         * Not used in the SME embedded version.
-         */
-        unifi_trace(priv, UDBG1, "SME client (id:%d s:0x%X) is registered\n",
-                    udi_cli->client_id, udi_cli->sender_id);
-        /* Store the SME UniFi Linux Client */
-        if (priv->sme_cli == NULL) {
-            priv->sme_cli = udi_cli;
-        }
-
-        up(&udi_mutex);
-    }
-
-
-    /*
-     * Store the pointer to the client.
-     * All char driver's entry points will pass this pointer.
-     */
-    file->private_data = udi_cli;
-
-    return 0;
-} /* unifi_open() */
-
-
-static int
-unifi_release(struct inode *inode, struct file *filp)
-{
-    ul_client_t *udi_cli = (void*)filp->private_data;
-    int devno;
-    unifi_priv_t *priv;
-
-    priv = uf_find_instance(udi_cli->instance);
-    if (!priv) {
-        unifi_error(priv, "unifi_close: instance for device not found\n");
-        return -ENODEV;
-    }
-
-    devno = MINOR(inode->i_rdev) >> 1;
-
-    /* Even device nodes are the config client (i.e. SME or unifi_manager) */
-    if ((MINOR(inode->i_rdev) & 0x1) == 0) {
-
-        if (priv->sme_cli != udi_cli) {
-            unifi_notice(priv, "Surprise closing config device: not the sme client\n");
-        }
-        unifi_notice(priv, "SME client close (unifi%d)\n", devno);
-
-        /*
-         * Clear sme_cli before calling unifi_sys_... so it doesn't try to
-         * queue a reply to the (now gone) SME.
-         */
-        down(&udi_mutex);
-        priv->sme_cli = NULL;
-        up(&udi_mutex);
-
-#ifdef CSR_SME_USERSPACE
-        /* Power-down when config client closes */
-        {
-            CsrWifiRouterCtrlWifiOffReq req = {{CSR_WIFI_ROUTER_CTRL_HIP_REQ, 0, 0, 0, NULL}};
-            CsrWifiRouterCtrlWifiOffReqHandler(priv, &req.common);
-        }
-
-        uf_sme_deinit(priv);
-
-       /* It is possible that a blocking SME request was made from another process
-        * which did not get read by the SME before the WifiOffReq.
-        * So check for a pending request which will go unanswered and cancel
-        * the wait for event. As only one blocking request can be in progress at
-        * a time, up to one event should be completed.
-        */
-       uf_sme_cancel_request(priv, 0);
-
-#endif /* CSR_SME_USERSPACE */
-    } else {
-
-        unifi_trace(priv, UDBG2, "UDI client close (unifiudi%d)\n", devno);
-
-        /* If the pointer matches the logging client, stop logging. */
-        down(&priv->udi_logging_mutex);
-        if (udi_cli == priv->logging_client) {
-            priv->logging_client = NULL;
-        }
-        up(&priv->udi_logging_mutex);
-
-        if (udi_cli == priv->amp_client) {
-            priv->amp_client = NULL;
-        }
-    }
-
-    /* Deregister this instance from the client's list. */
-    ul_deregister_client(udi_cli);
-
-    uf_put_instance(devno);
-
-    return 0;
-} /* unifi_release() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_read
- *
- *      The read() driver entry point.
- *
- *  Arguments:
- *      filp        The file descriptor returned by unifi_open()
- *      p           The user space buffer to copy the read data
- *      len         The size of the p buffer
- *      poff
- *
- *  Returns:
- *      number of bytes read or an error code on failure
- * ---------------------------------------------------------------------------
- */
-static ssize_t
-unifi_read(struct file *filp, char *p, size_t len, loff_t *poff)
-{
-    ul_client_t *pcli = (void*)filp->private_data;
-    unifi_priv_t *priv;
-    udi_log_t *logptr = NULL;
-    udi_msg_t *msgptr;
-    struct list_head *l;
-    int msglen;
-
-    priv = uf_find_instance(pcli->instance);
-    if (!priv) {
-        unifi_error(priv, "invalid priv\n");
-        return -ENODEV;
-    }
-
-    if (!pcli->udi_enabled) {
-        unifi_error(priv, "unifi_read: unknown client.");
-        return -EINVAL;
-    }
-
-    if (list_empty(&pcli->udi_log)) {
-        if (filp->f_flags & O_NONBLOCK) {
-            /* Non-blocking - just return if the udi_log is empty */
-            return 0;
-        } else {
-            /* Blocking - wait on the UDI wait queue */
-            if (wait_event_interruptible(pcli->udi_wq,
-                !list_empty(&pcli->udi_log)))
-            {
-                unifi_error(priv, "unifi_read: wait_event_interruptible failed.");
-                return -ERESTARTSYS;
-            }
-        }
-    }
-
-    /* Read entry from list head and remove it from the list */
-    if (down_interruptible(&pcli->udi_sem)) {
-        return -ERESTARTSYS;
-    }
-    l = pcli->udi_log.next;
-    list_del(l);
-    up(&pcli->udi_sem);
-
-    /* Get a pointer to whole struct */
-    logptr = list_entry(l, udi_log_t, q);
-    if (logptr == NULL) {
-        unifi_error(priv, "unifi_read: failed to get event.\n");
-        return -EINVAL;
-    }
-
-    /* Get the real message */
-    msgptr = &logptr->msg;
-    msglen = msgptr->length;
-    if (msglen > len) {
-        printk(KERN_WARNING "truncated read to %d actual msg len is %lu\n", msglen, (long unsigned int)len);
-        msglen = len;
-    }
-
-    /* and pass it to the client (SME or Unicli). */
-    if (copy_to_user(p, msgptr, msglen))
-    {
-        printk(KERN_ERR "Failed to copy UDI log to user\n");
-        kfree(logptr);
-        return -EFAULT;
-    }
-
-    /* It is our resposibility to free the message buffer. */
-    kfree(logptr);
-
-    return msglen;
-
-} /* unifi_read() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- * udi_send_signal_unpacked
- *
- *      Sends an unpacked signal to UniFi.
- *
- * Arguments:
- *      priv            Pointer to private context struct
- *      data            Pointer to request structure and data to send
- *      data_len        Length of data in data pointer.
- *
- * Returns:
- *      Number of bytes written, error otherwise.
- *
- * Notes:
- *      All clients that use this function to send a signal to the unifi
- *      must use the host formatted structures.
- * ---------------------------------------------------------------------------
- */
-static int
-udi_send_signal_unpacked(unifi_priv_t *priv, unsigned char* data, uint data_len)
-{
-    CSR_SIGNAL *sigptr = (CSR_SIGNAL*)data;
-    CSR_DATAREF *datarefptr;
-    bulk_data_param_t bulk_data;
-    uint signal_size, i;
-    uint bulk_data_offset = 0;
-    int bytecount, r;
-    CsrResult csrResult;
-
-    /* Number of bytes in the signal */
-    signal_size = SigGetSize(sigptr);
-    if (!signal_size || (signal_size > data_len)) {
-        unifi_error(priv, "unifi_sme_mlme_req - Invalid signal 0x%x size should be %d bytes\n",
-                    sigptr->SignalPrimitiveHeader.SignalId,
-                    signal_size);
-        return -EINVAL;
-    }
-    bytecount = signal_size;
-
-    /* Get a pointer to the information of the first data reference */
-    datarefptr = (CSR_DATAREF*)&sigptr->u;
-
-    /* Initialize the offset in the data buffer, bulk data is right after the signal. */
-    bulk_data_offset = signal_size;
-
-    /* store the references and the size of the bulk data to the bulkdata structure */
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
-        /* the length of the bulk data is in the signal */
-        if ((datarefptr+i)->DataLength) {
-            void *dest;
-
-            csrResult = unifi_net_data_malloc(priv, &bulk_data.d[i], (datarefptr+i)->DataLength);
-            if (csrResult != CSR_RESULT_SUCCESS) {
-                unifi_error(priv, "udi_send_signal_unpacked: failed to allocate request_data.\n");
-                return -EIO;
-            }
-
-            dest = (void*)bulk_data.d[i].os_data_ptr;
-            memcpy(dest, data + bulk_data_offset, bulk_data.d[i].data_length);
-        } else {
-            bulk_data.d[i].data_length = 0;
-        }
-
-        bytecount += bulk_data.d[i].data_length;
-        /* advance the offset, to point the next bulk data */
-        bulk_data_offset += bulk_data.d[i].data_length;
-    }
-
-
-    unifi_trace(priv, UDBG3, "SME Send: signal 0x%.4X\n", sigptr->SignalPrimitiveHeader.SignalId);
-
-    /* Send the signal. */
-    r = ul_send_signal_unpacked(priv, sigptr, &bulk_data);
-    if (r < 0) {
-        unifi_error(priv, "udi_send_signal_unpacked: send failed (%d)\n", r);
-        for(i=0;i<UNIFI_MAX_DATA_REFERENCES;i++) {
-            if(bulk_data.d[i].data_length != 0) {
-                unifi_net_data_free(priv, &bulk_data.d[i]);
-            }
-        }
-        return -EIO;
-    }
-
-    return bytecount;
-} /* udi_send_signal_unpacked() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- * udi_send_signal_raw
- *
- *      Sends a packed signal to UniFi.
- *
- * Arguments:
- *      priv            Pointer to private context struct
- *      buf             Pointer to request structure and data to send
- *      buflen          Length of data in data pointer.
- *
- * Returns:
- *      Number of bytes written, error otherwise.
- *
- * Notes:
- *      All clients that use this function to send a signal to the unifi
- *      must use the wire formatted structures.
- * ---------------------------------------------------------------------------
- */
-static int
-udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen)
-{
-    int signal_size;
-    int sig_id;
-    bulk_data_param_t data_ptrs;
-    int i, r;
-    unsigned int num_data_refs;
-    int bytecount;
-    CsrResult csrResult;
-
-    /*
-     * The signal is the first thing in buf, the signal id is the
-     * first 16 bits of the signal.
-     */
-    /* Number of bytes in the signal */
-    sig_id = GET_SIGNAL_ID(buf);
-    signal_size = buflen;
-    signal_size -= GET_PACKED_DATAREF_LEN(buf, 0);
-    signal_size -= GET_PACKED_DATAREF_LEN(buf, 1);
-    if ((signal_size <= 0) || (signal_size > buflen)) {
-        unifi_error(priv, "udi_send_signal_raw - Couldn't find length of signal 0x%x\n",
-                    sig_id);
-        return -EINVAL;
-    }
-    unifi_trace(priv, UDBG2, "udi_send_signal_raw: signal 0x%.4X len:%d\n",
-                sig_id, signal_size);
-    /* Zero the data ref arrays */
-    memset(&data_ptrs, 0, sizeof(data_ptrs));
-
-    /*
-     * Find the number of associated bulk data packets.  Scan through
-     * the data refs to check that we have enough data and pick out
-     * pointers to appended bulk data.
-     */
-    num_data_refs = 0;
-    bytecount = signal_size;
-
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i)
-    {
-        unsigned int len = GET_PACKED_DATAREF_LEN(buf, i);
-        unifi_trace(priv, UDBG3, "udi_send_signal_raw: data_ref length = %d\n", len);
-
-        if (len != 0) {
-            void *dest;
-
-            csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[i], len);
-            if (csrResult != CSR_RESULT_SUCCESS) {
-                unifi_error(priv, "udi_send_signal_raw: failed to allocate request_data.\n");
-                return -EIO;
-            }
-
-            dest = (void*)data_ptrs.d[i].os_data_ptr;
-            memcpy(dest, buf + bytecount, len);
-
-            bytecount += len;
-            num_data_refs++;
-        }
-        data_ptrs.d[i].data_length = len;
-    }
-
-    unifi_trace(priv, UDBG3, "Queueing signal 0x%.4X from UDI with %u data refs\n",
-          sig_id,
-          num_data_refs);
-
-    if (bytecount > buflen) {
-        unifi_error(priv, "udi_send_signal_raw: Not enough data (%d instead of %d)\n", buflen, bytecount);
-        return -EINVAL;
-    }
-
-    /* Send the signal calling the function that uses the wire-formatted signals. */
-    r = ul_send_signal_raw(priv, buf, signal_size, &data_ptrs);
-    if (r < 0) {
-        unifi_error(priv, "udi_send_signal_raw: send failed (%d)\n", r);
-        return -EIO;
-    }
-
-#ifdef CSR_NATIVE_LINUX
-    if (sig_id == CSR_MLME_POWERMGT_REQUEST_ID) {
-        int power_mode = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((buf +
-                                              SIZEOF_SIGNAL_HEADER + (UNIFI_MAX_DATA_REFERENCES*SIZEOF_DATAREF)));
-#ifdef CSR_SUPPORT_WEXT
-        /* Overide the wext power mode to the new value */
-        priv->wext_conf.power_mode = power_mode;
-#endif
-        /* Configure deep sleep signaling */
-        if (power_mode || (priv->interfacePriv[0]->connected == UnifiNotConnected)) {
-            csrResult = unifi_configure_low_power_mode(priv->card,
-                                                   UNIFI_LOW_POWER_ENABLED,
-                                                   UNIFI_PERIODIC_WAKE_HOST_DISABLED);
-        } else {
-            csrResult = unifi_configure_low_power_mode(priv->card,
-                                                   UNIFI_LOW_POWER_DISABLED,
-                                                   UNIFI_PERIODIC_WAKE_HOST_DISABLED);
-        }
-    }
-#endif
-
-    return bytecount;
-} /* udi_send_signal_raw */
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_write
- *
- *      The write() driver entry point.
- *      A UniFi Debug Interface client such as unicli can write a signal
- *      plus bulk data to the driver for sending to the UniFi chip.
- *
- *      Only one signal may be sent per write operation.
- *
- *  Arguments:
- *      filp        The file descriptor returned by unifi_open()
- *      p           The user space buffer to get the data from
- *      len         The size of the p buffer
- *      poff
- *
- *  Returns:
- *      number of bytes written or an error code on failure
- * ---------------------------------------------------------------------------
- */
-static ssize_t
-unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff)
-{
-    ul_client_t *pcli = (ul_client_t*)filp->private_data;
-    unifi_priv_t *priv;
-    unsigned char *buf;
-    unsigned char *bufptr;
-    int remaining;
-    int bytes_written;
-    int r;
-    bulk_data_param_t bulkdata;
-    CsrResult csrResult;
-
-    priv = uf_find_instance(pcli->instance);
-    if (!priv) {
-        unifi_error(priv, "invalid priv\n");
-        return -ENODEV;
-    }
-
-    unifi_trace(priv, UDBG5, "unifi_write: len = %d\n", len);
-
-    if (!pcli->udi_enabled) {
-        unifi_error(priv, "udi disabled\n");
-        return -EINVAL;
-    }
-
-    /*
-     * AMP client sends only one signal at a time, so we can use
-     * unifi_net_data_malloc to save the extra copy.
-     */
-    if (pcli == priv->amp_client) {
-        int signal_size;
-        int sig_id;
-        unsigned char *signal_buf;
-        char *user_data_buf;
-
-        csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], len);
-        if (csrResult != CSR_RESULT_SUCCESS) {
-            unifi_error(priv, "unifi_write: failed to allocate request_data.\n");
-            return -ENOMEM;
-        }
-
-        user_data_buf = (char*)bulkdata.d[0].os_data_ptr;
-
-        /* Get the data from the AMP client. */
-        if (copy_from_user((void*)user_data_buf, p, len)) {
-            unifi_error(priv, "unifi_write: copy from user failed\n");
-            unifi_net_data_free(priv, &bulkdata.d[0]);
-            return -EFAULT;
-        }
-
-        bulkdata.d[1].os_data_ptr = NULL;
-        bulkdata.d[1].data_length = 0;
-
-        /* Number of bytes in the signal */
-        sig_id = GET_SIGNAL_ID(bulkdata.d[0].os_data_ptr);
-        signal_size = len;
-        signal_size -= GET_PACKED_DATAREF_LEN(bulkdata.d[0].os_data_ptr, 0);
-        signal_size -= GET_PACKED_DATAREF_LEN(bulkdata.d[0].os_data_ptr, 1);
-        if ((signal_size <= 0) || (signal_size > len)) {
-            unifi_error(priv, "unifi_write - Couldn't find length of signal 0x%x\n",
-                        sig_id);
-            unifi_net_data_free(priv, &bulkdata.d[0]);
-            return -EINVAL;
-        }
-
-        unifi_trace(priv, UDBG2, "unifi_write: signal 0x%.4X len:%d\n",
-                    sig_id, signal_size);
-
-	/* Allocate a buffer for the signal */
-	signal_buf = kmemdup(bulkdata.d[0].os_data_ptr, signal_size,
-				GFP_KERNEL);
-        if (!signal_buf) {
-            unifi_net_data_free(priv, &bulkdata.d[0]);
-            return -ENOMEM;
-        }
-
-        /* Get the signal from the os_data_ptr */
-        signal_buf[5] = (pcli->sender_id >> 8) & 0xff;
-
-        if (signal_size < len) {
-            /* Remove the signal from the os_data_ptr */
-            bulkdata.d[0].data_length -= signal_size;
-            bulkdata.d[0].os_data_ptr += signal_size;
-        } else {
-            bulkdata.d[0].data_length = 0;
-            bulkdata.d[0].os_data_ptr = NULL;
-        }
-
-        /* Send the signal calling the function that uses the wire-formatted signals. */
-        r = ul_send_signal_raw(priv, signal_buf, signal_size, &bulkdata);
-        if (r < 0) {
-            unifi_error(priv, "unifi_write: send failed (%d)\n", r);
-            if (bulkdata.d[0].os_data_ptr != NULL) {
-                unifi_net_data_free(priv, &bulkdata.d[0]);
-            }
-        }
-
-        /* Free the signal buffer and return */
-        kfree(signal_buf);
-        return len;
-    }
-
-    buf = kmalloc(len, GFP_KERNEL);
-    if (!buf) {
-        return -ENOMEM;
-    }
-
-    /* Get the data from the client (SME or Unicli). */
-    if (copy_from_user((void*)buf, p, len)) {
-        unifi_error(priv, "copy from user failed\n");
-        kfree(buf);
-        return -EFAULT;
-    }
-
-    /*
-     * In SME userspace build read() contains a SYS or MGT message.
-     * Note that even though the SME sends one signal at a time, we can not
-     * use unifi_net_data_malloc because in the early stages, before having
-     * initialised the core, it will fail since the I/O block size is unknown.
-     */
-#ifdef CSR_SME_USERSPACE
-    if (pcli->configuration & CLI_SME_USERSPACE) {
-        CsrWifiRouterTransportRecv(priv, buf, len);
-        kfree(buf);
-        return len;
-    }
-#endif
-
-    /* ul_send_signal_raw will  do a sanity check of len against signal content */
-
-    /*
-     * udi_send_signal_raw() and udi_send_signal_unpacked() return the number of bytes consumed.
-     * A write call can pass multiple signal concatenated together.
-     */
-    bytes_written = 0;
-    remaining = len;
-    bufptr = buf;
-    while (remaining > 0)
-    {
-        int r;
-
-        /*
-         * Set the SenderProcessId.
-         * The SignalPrimitiveHeader is the first 3 16-bit words of the signal,
-         * the SenderProcessId is bytes 4,5.
-         * The MSB of the sender ID needs to be set to the client ID.
-         * The LSB is controlled by the SME.
-         */
-        bufptr[5] = (pcli->sender_id >> 8) & 0xff;
-
-        /* use the appropriate interface, depending on the clients' configuration */
-        if (pcli->configuration & CLI_USING_WIRE_FORMAT) {
-            unifi_trace(priv, UDBG1, "unifi_write: call udi_send_signal().\n");
-            r = udi_send_signal_raw(priv, bufptr, remaining);
-        } else {
-            r = udi_send_signal_unpacked(priv, bufptr, remaining);
-        }
-        if (r < 0) {
-            /* Set the return value to the error code */
-            unifi_error(priv, "unifi_write: (udi or sme)_send_signal() returns %d\n", r);
-            bytes_written = r;
-            break;
-        }
-        bufptr += r;
-        remaining -= r;
-        bytes_written += r;
-    }
-
-    kfree(buf);
-
-    return bytes_written;
-} /* unifi_write() */
-
-
-static const char* build_type_to_string(unsigned char build_type)
-{
-    switch (build_type)
-    {
-    case UNIFI_BUILD_NME: return "NME";
-    case UNIFI_BUILD_WEXT: return "WEXT";
-    case UNIFI_BUILD_AP: return "AP";
-    }
-    return "unknown";
-}
-
-
-/*
- * ----------------------------------------------------------------
- *  unifi_ioctl
- *
- *      Ioctl handler for unifi driver.
- *
- * Arguments:
- *  inodep          Pointer to inode structure.
- *  filp            Pointer to file structure.
- *  cmd             Ioctl cmd passed by user.
- *  arg             Ioctl arg passed by user.
- *
- * Returns:
- *      0 on success, -ve error code on error.
- * ----------------------------------------------------------------
- */
-static long
-unifi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-    ul_client_t *pcli = (ul_client_t*)filp->private_data;
-    unifi_priv_t *priv;
-    struct net_device *dev;
-    int r = 0;
-    int int_param, i;
-    u8* buf;
-    CsrResult csrResult;
-#if (defined CSR_SUPPORT_SME)
-    unifi_cfg_command_t cfg_cmd;
-#if (defined CSR_SUPPORT_WEXT)
-    CsrWifiSmeCoexConfig coex_config;
-    unsigned char uchar_param;
-    unsigned char varbind[MAX_VARBIND_LENGTH];
-    int vblen;
-#endif
-#endif
-    unifi_putest_command_t putest_cmd;
-
-    priv = uf_find_instance(pcli->instance);
-    if (!priv) {
-        unifi_error(priv, "ioctl error: unknown instance=%d\n", pcli->instance);
-        r = -ENODEV;
-        goto out;
-    }
-    unifi_trace(priv, UDBG5, "unifi_ioctl: cmd=0x%X, arg=0x%lX\n", cmd, arg);
-
-    switch (cmd) {
-
-      case UNIFI_GET_UDI_ENABLE:
-        unifi_trace(priv, UDBG4, "UniFi Get UDI Enable\n");
-
-        down(&priv->udi_logging_mutex);
-        int_param = (priv->logging_client == NULL) ? 0 : 1;
-        up(&priv->udi_logging_mutex);
-
-        if (put_user(int_param, (int*)arg))
-        {
-            unifi_error(priv, "UNIFI_GET_UDI_ENABLE: Failed to copy to user\n");
-            r = -EFAULT;
-            goto out;
-        }
-        break;
-
-      case UNIFI_SET_UDI_ENABLE:
-        unifi_trace(priv, UDBG4, "UniFi Set UDI Enable\n");
-        if (get_user(int_param, (int*)arg))
-        {
-            unifi_error(priv, "UNIFI_SET_UDI_ENABLE: Failed to copy from user\n");
-            r = -EFAULT;
-            goto out;
-        }
-
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-        if (log_hip_signals) {
-            unifi_error(priv, "omnicli cannot be used when log_hip_signals is used\n");
-            r = -EFAULT;
-            goto out;
-        }
-#endif
-
-        down(&priv->udi_logging_mutex);
-        if (int_param) {
-            pcli->event_hook = udi_log_event;
-            unifi_set_udi_hook(priv->card, logging_handler);
-            /* Log all signals by default */
-            for (i = 0; i < SIG_FILTER_SIZE; i++) {
-                pcli->signal_filter[i] = 0xFFFF;
-            }
-            priv->logging_client = pcli;
-
-        } else {
-            priv->logging_client = NULL;
-            pcli->event_hook = NULL;
-        }
-        up(&priv->udi_logging_mutex);
-
-        break;
-
-      case UNIFI_SET_MIB:
-        unifi_trace(priv, UDBG4, "UniFi Set MIB\n");
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-        /* Read first 2 bytes and check length */
-        if (copy_from_user((void*)varbind, (void*)arg, 2)) {
-            unifi_error(priv,
-                        "UNIFI_SET_MIB: Failed to copy in varbind header\n");
-            r = -EFAULT;
-            goto out;
-        }
-        vblen = varbind[1];
-        if ((vblen + 2) > MAX_VARBIND_LENGTH) {
-            unifi_error(priv,
-                        "UNIFI_SET_MIB: Varbind too long (%d, limit %d)\n",
-                        (vblen+2), MAX_VARBIND_LENGTH);
-            r = -EINVAL;
-            goto out;
-        }
-        /* Read rest of varbind */
-        if (copy_from_user((void*)(varbind+2), (void*)(arg+2), vblen)) {
-            unifi_error(priv, "UNIFI_SET_MIB: Failed to copy in varbind\n");
-            r = -EFAULT;
-            goto out;
-        }
-
-        /* send to SME */
-        vblen += 2;
-        r = sme_mgt_mib_set(priv, varbind, vblen);
-        if (r) {
-            goto out;
-        }
-#else
-        unifi_notice(priv, "UNIFI_SET_MIB: Unsupported.\n");
-#endif /* CSR_SUPPORT_WEXT */
-        break;
-
-      case UNIFI_GET_MIB:
-        unifi_trace(priv, UDBG4, "UniFi Get MIB\n");
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-        /* Read first 2 bytes and check length */
-        if (copy_from_user((void*)varbind, (void*)arg, 2)) {
-            unifi_error(priv, "UNIFI_GET_MIB: Failed to copy in varbind header\n");
-            r = -EFAULT;
-            goto out;
-        }
-        vblen = varbind[1];
-        if ((vblen+2) > MAX_VARBIND_LENGTH) {
-            unifi_error(priv, "UNIFI_GET_MIB: Varbind too long (%d, limit %d)\n",
-                        (vblen+2), MAX_VARBIND_LENGTH);
-            r = -EINVAL;
-            goto out;
-        }
-        /* Read rest of varbind */
-        if (copy_from_user((void*)(varbind+2), (void*)(arg+2), vblen)) {
-            unifi_error(priv, "UNIFI_GET_MIB: Failed to copy in varbind\n");
-            r = -EFAULT;
-            goto out;
-        }
-
-        vblen += 2;
-        r = sme_mgt_mib_get(priv, varbind, &vblen);
-        if (r) {
-            goto out;
-        }
-        /* copy out varbind */
-        if (vblen > MAX_VARBIND_LENGTH) {
-            unifi_error(priv,
-                        "UNIFI_GET_MIB: Varbind result too long (%d, limit %d)\n",
-                        vblen, MAX_VARBIND_LENGTH);
-            r = -EINVAL;
-            goto out;
-        }
-        if (copy_to_user((void*)arg, varbind, vblen)) {
-            r = -EFAULT;
-            goto out;
-        }
-#else
-        unifi_notice(priv, "UNIFI_GET_MIB: Unsupported.\n");
-#endif /* CSR_SUPPORT_WEXT */
-        break;
-
-      case UNIFI_CFG:
-#if (defined CSR_SUPPORT_SME)
-        if (get_user(cfg_cmd, (unifi_cfg_command_t*)arg))
-        {
-            unifi_error(priv, "UNIFI_CFG: Failed to get the command\n");
-            r = -EFAULT;
-            goto out;
-        }
-
-        unifi_trace(priv, UDBG1, "UNIFI_CFG: Command is %d (t=%u) sz=%d\n",
-                    cfg_cmd, jiffies_to_msecs(jiffies), sizeof(unifi_cfg_command_t));
-        switch (cfg_cmd) {
-          case UNIFI_CFG_POWER:
-            r = unifi_cfg_power(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_CFG_POWERSAVE:
-            r = unifi_cfg_power_save(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_CFG_POWERSUPPLY:
-            r = unifi_cfg_power_supply(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_CFG_FILTER:
-            r = unifi_cfg_packet_filters(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_CFG_GET:
-            r = unifi_cfg_get_info(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_CFG_WMM_QOSINFO:
-            r = unifi_cfg_wmm_qos_info(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_CFG_WMM_ADDTS:
-            r = unifi_cfg_wmm_addts(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_CFG_WMM_DELTS:
-            r = unifi_cfg_wmm_delts(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_CFG_STRICT_DRAFT_N:
-            r = unifi_cfg_strict_draft_n(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_CFG_ENABLE_OKC:
-            r = unifi_cfg_enable_okc(priv, (unsigned char*)arg);
-            break;
-#ifdef CSR_SUPPORT_SME
-          case UNIFI_CFG_CORE_DUMP:
-            CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,CSR_WIFI_SME_CONTROL_INDICATION_ERROR);
-            unifi_trace(priv, UDBG2, "UNIFI_CFG_CORE_DUMP: sent wifi off indication\n");
-            break;
-#endif
-#ifdef CSR_SUPPORT_WEXT_AP
-          case UNIFI_CFG_SET_AP_CONFIG:
-            r= unifi_cfg_set_ap_config(priv,(unsigned char*)arg);
-            break;
-#endif
-          default:
-            unifi_error(priv, "UNIFI_CFG: Unknown Command (%d)\n", cfg_cmd);
-            r = -EINVAL;
-            goto out;
-        }
-#endif
-
-        break;
-
-      case UNIFI_PUTEST:
-        if (get_user(putest_cmd, (unifi_putest_command_t*)arg))
-        {
-            unifi_error(priv, "UNIFI_PUTEST: Failed to get the command\n");
-            r = -EFAULT;
-            goto out;
-        }
-
-        unifi_trace(priv, UDBG1, "UNIFI_PUTEST: Command is %s\n",
-                    trace_putest_cmdid(putest_cmd));
-        switch (putest_cmd) {
-          case UNIFI_PUTEST_START:
-            r = unifi_putest_start(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_STOP:
-            r = unifi_putest_stop(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_SET_SDIO_CLOCK:
-            r = unifi_putest_set_sdio_clock(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_CMD52_READ:
-            r = unifi_putest_cmd52_read(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_CMD52_BLOCK_READ:
-            r = unifi_putest_cmd52_block_read(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_CMD52_WRITE:
-            r = unifi_putest_cmd52_write(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_DL_FW:
-            r = unifi_putest_dl_fw(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_DL_FW_BUFF:
-            r = unifi_putest_dl_fw_buff(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_COREDUMP_PREPARE:
-            r = unifi_putest_coredump_prepare(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_GP_READ16:
-            r = unifi_putest_gp_read16(priv, (unsigned char*)arg);
-            break;
-          case UNIFI_PUTEST_GP_WRITE16:
-            r = unifi_putest_gp_write16(priv, (unsigned char*)arg);
-            break;
-          default:
-            unifi_error(priv, "UNIFI_PUTEST: Unknown Command (%d)\n", putest_cmd);
-            r = -EINVAL;
-            goto out;
-        }
-
-        break;
-      case UNIFI_BUILD_TYPE:
-        unifi_trace(priv, UDBG2, "UNIFI_BUILD_TYPE userspace=%s\n", build_type_to_string(*(unsigned char*)arg));
-#ifndef CSR_SUPPORT_WEXT_AP
-        if (UNIFI_BUILD_AP == *(unsigned char*)arg)
-        {
-            unifi_error(priv, "Userspace has AP support, which is incompatible\n");
-        }
-#endif
-
-#ifndef CSR_SUPPORT_WEXT
-        if (UNIFI_BUILD_WEXT == *(unsigned char*)arg)
-        {
-            unifi_error(priv, "Userspace has WEXT support, which is incompatible\n");
-        }
-#endif
-        break;
-      case UNIFI_INIT_HW:
-        unifi_trace(priv, UDBG2, "UNIFI_INIT_HW.\n");
-        priv->init_progress = UNIFI_INIT_NONE;
-
-#if defined(CSR_SUPPORT_WEXT) || defined (CSR_NATIVE_LINUX)
-        /* At this point we are ready to start the SME. */
-        r = sme_mgt_wifi_on(priv);
-        if (r) {
-            goto out;
-        }
-#endif
-
-        break;
-
-      case UNIFI_INIT_NETDEV:
-        {
-            /* get the proper interfaceTagId */
-            u16 interfaceTag=0;
-            netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-            dev = priv->netdev[interfaceTag];
-            unifi_trace(priv, UDBG2, "UNIFI_INIT_NETDEV.\n");
-
-            if (copy_from_user((void*)dev->dev_addr, (void*)arg, 6)) {
-                r = -EFAULT;
-                goto out;
-            }
-
-            /* Attach the network device to the stack */
-            if (!interfacePriv->netdev_registered)
-            {
-                r = uf_register_netdev(priv,interfaceTag);
-                if (r) {
-                    unifi_error(priv, "Failed to register the network device.\n");
-                    goto out;
-                }
-            }
-
-            /* Apply scheduled interrupt mode, if requested by module param */
-            if (run_bh_once != -1) {
-                unifi_set_interrupt_mode(priv->card, (u32)run_bh_once);
-            }
-
-            priv->init_progress = UNIFI_INIT_COMPLETED;
-
-            /* Firmware initialisation is complete, so let the SDIO bus
-             * clock be raised when convienent to the core.
-             */
-            unifi_request_max_sdio_clock(priv->card);
-
-#ifdef CSR_SUPPORT_WEXT
-            /* Notify the Android wpa_supplicant that we are ready */
-            wext_send_started_event(priv);
-#endif
-
-            unifi_info(priv, "UniFi ready\n");
-
-#ifdef ANDROID_BUILD
-            /* Release the wakelock */
-            unifi_trace(priv, UDBG1, "netdev_init: release wake lock\n");
-            wake_unlock(&unifi_sdio_wake_lock);
-#endif
-#ifdef CSR_NATIVE_SOFTMAC /* For softmac dev, force-enable the network interface rather than wait for a connected-ind */
-            {
-                struct net_device *dev = priv->netdev[interfaceTag];
-#ifdef CSR_SUPPORT_WEXT
-                interfacePriv->wait_netdev_change = TRUE;
-#endif
-                netif_carrier_on(dev);
-            }
-#endif
-        }
-        break;
-      case UNIFI_GET_INIT_STATUS:
-        unifi_trace(priv, UDBG2, "UNIFI_GET_INIT_STATUS.\n");
-        if (put_user(priv->init_progress, (int*)arg))
-        {
-            printk(KERN_ERR "UNIFI_GET_INIT_STATUS: Failed to copy to user\n");
-            r = -EFAULT;
-            goto out;
-        }
-        break;
-
-      case UNIFI_KICK:
-        unifi_trace(priv, UDBG4, "Kick UniFi\n");
-        unifi_sdio_interrupt_handler(priv->card);
-        break;
-
-      case UNIFI_SET_DEBUG:
-        unifi_debug = arg;
-        unifi_trace(priv, UDBG4, "unifi_debug set to %d\n", unifi_debug);
-        break;
-
-      case UNIFI_SET_TRACE:
-        /* no longer supported */
-        r = -EINVAL;
-        break;
-
-
-      case UNIFI_SET_UDI_LOG_MASK:
-        {
-            unifiio_filter_t udi_filter;
-            uint16_t *sig_ids_addr;
-#define UF_MAX_SIG_IDS  128     /* Impose a sensible limit */
-
-            if (copy_from_user((void*)(&udi_filter), (void*)arg, sizeof(udi_filter))) {
-                r = -EFAULT;
-                goto out;
-            }
-            if ((udi_filter.action < UfSigFil_AllOn) ||
-                (udi_filter.action > UfSigFil_SelectOff))
-            {
-                printk(KERN_WARNING
-                       "UNIFI_SET_UDI_LOG_MASK: Bad action value: %d\n",
-                       udi_filter.action);
-                r = -EINVAL;
-                goto out;
-            }
-            /* No signal list for "All" actions */
-            if ((udi_filter.action == UfSigFil_AllOn) ||
-                (udi_filter.action == UfSigFil_AllOff))
-            {
-                udi_filter.num_sig_ids = 0;
-            }
-
-            if (udi_filter.num_sig_ids > UF_MAX_SIG_IDS) {
-                printk(KERN_WARNING
-                       "UNIFI_SET_UDI_LOG_MASK: too many signal ids (%d, max %d)\n",
-                       udi_filter.num_sig_ids, UF_MAX_SIG_IDS);
-                r = -EINVAL;
-                goto out;
-            }
-
-            /* Copy in signal id list if given */
-            if (udi_filter.num_sig_ids > 0) {
-                /* Preserve userspace address of sig_ids array */
-                sig_ids_addr = udi_filter.sig_ids;
-                /* Allocate kernel memory for sig_ids and copy to it */
-                udi_filter.sig_ids =
-                    kmalloc(udi_filter.num_sig_ids * sizeof(uint16_t), GFP_KERNEL);
-                if (!udi_filter.sig_ids) {
-                    r = -ENOMEM;
-                    goto out;
-                }
-                if (copy_from_user((void*)udi_filter.sig_ids,
-                                   (void*)sig_ids_addr,
-                                   udi_filter.num_sig_ids * sizeof(uint16_t)))
-                {
-                    kfree(udi_filter.sig_ids);
-                    r = -EFAULT;
-                    goto out;
-                }
-            }
-
-            udi_set_log_filter(pcli, &udi_filter);
-
-            if (udi_filter.num_sig_ids > 0) {
-                kfree(udi_filter.sig_ids);
-            }
-        }
-        break;
-
-      case UNIFI_SET_AMP_ENABLE:
-        unifi_trace(priv, UDBG4, "UniFi Set AMP Enable\n");
-        if (get_user(int_param, (int*)arg))
-        {
-            unifi_error(priv, "UNIFI_SET_AMP_ENABLE: Failed to copy from user\n");
-            r = -EFAULT;
-            goto out;
-        }
-
-        if (int_param) {
-            priv->amp_client = pcli;
-        } else {
-            priv->amp_client = NULL;
-        }
-
-        int_param = 0;
-        buf = (u8*)&int_param;
-        buf[0] = UNIFI_SOFT_COMMAND_Q_LENGTH - 1;
-        buf[1] = UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1;
-        if (copy_to_user((void*)arg, &int_param, sizeof(int))) {
-            r = -EFAULT;
-            goto out;
-        }
-        break;
-
-      case UNIFI_SET_UDI_SNAP_MASK:
-        {
-            unifiio_snap_filter_t snap_filter;
-
-            if (copy_from_user((void*)(&snap_filter), (void*)arg, sizeof(snap_filter))) {
-                r = -EFAULT;
-                goto out;
-            }
-
-            if (pcli->snap_filter.count) {
-                pcli->snap_filter.count = 0;
-                kfree(pcli->snap_filter.protocols);
-            }
-
-            if (snap_filter.count == 0) {
-                break;
-            }
-
-            pcli->snap_filter.protocols = kmalloc(snap_filter.count * sizeof(u16), GFP_KERNEL);
-            if (!pcli->snap_filter.protocols) {
-                r = -ENOMEM;
-                goto out;
-            }
-            if (copy_from_user((void*)pcli->snap_filter.protocols,
-                               (void*)snap_filter.protocols,
-                               snap_filter.count * sizeof(u16)))
-            {
-                kfree(pcli->snap_filter.protocols);
-                r = -EFAULT;
-                goto out;
-            }
-
-            pcli->snap_filter.count = snap_filter.count;
-
-        }
-        break;
-
-      case UNIFI_SME_PRESENT:
-        {
-            u8 ind;
-            unifi_trace(priv, UDBG4, "UniFi SME Present IOCTL.\n");
-            if (copy_from_user((void*)(&int_param), (void*)arg, sizeof(int)))
-            {
-                printk(KERN_ERR "UNIFI_SME_PRESENT: Failed to copy from user\n");
-                r = -EFAULT;
-                goto out;
-            }
-
-            priv->sme_is_present = int_param;
-            if (priv->sme_is_present == 1) {
-                ind = CONFIG_SME_PRESENT;
-            } else {
-                ind = CONFIG_SME_NOT_PRESENT;
-            }
-            /* Send an indication to the helper app. */
-            ul_log_config_ind(priv, &ind, sizeof(u8));
-        }
-        break;
-
-      case UNIFI_CFG_PERIOD_TRAFFIC:
-      {
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-          CsrWifiSmeCoexConfig coexConfig;
-#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
-        unifi_trace(priv, UDBG4, "UniFi Configure Periodic Traffic.\n");
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-        if (copy_from_user((void*)(&uchar_param), (void*)arg, sizeof(unsigned char))) {
-            unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n");
-            r = -EFAULT;
-            goto out;
-        }
-
-        if (uchar_param == 0) {
-            r = sme_mgt_coex_config_get(priv, &coexConfig);
-            if (r) {
-                unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Get unifi_CoexInfoValue failed.\n");
-                goto out;
-            }
-            if (copy_to_user((void*)(arg + 1),
-                             (void*)&coexConfig,
-                             sizeof(CsrWifiSmeCoexConfig))) {
-                r = -EFAULT;
-                goto out;
-            }
-            goto out;
-        }
-
-        if (copy_from_user((void*)(&coex_config), (void*)(arg + 1), sizeof(CsrWifiSmeCoexConfig)))
-        {
-            unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Failed to copy from user\n");
-            r = -EFAULT;
-            goto out;
-        }
-
-        coexConfig = coex_config;
-        r = sme_mgt_coex_config_set(priv, &coexConfig);
-        if (r) {
-            unifi_error(priv, "UNIFI_CFG_PERIOD_TRAFFIC: Set unifi_CoexInfoValue failed.\n");
-            goto out;
-        }
-
-#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
-        break;
-      }
-      case UNIFI_CFG_UAPSD_TRAFFIC:
-        unifi_trace(priv, UDBG4, "UniFi Configure U-APSD Mask.\n");
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-        if (copy_from_user((void*)(&uchar_param), (void*)arg, sizeof(unsigned char))) {
-            unifi_error(priv, "UNIFI_CFG_UAPSD_TRAFFIC: Failed to copy from user\n");
-            r = -EFAULT;
-            goto out;
-        }
-        unifi_trace(priv, UDBG4, "New U-APSD Mask: 0x%x\n", uchar_param);
-#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT */
-        break;
-
-#ifndef UNIFI_DISABLE_COREDUMP
-      case UNIFI_COREDUMP_GET_REG:
-        unifi_trace(priv, UDBG4, "Mini-coredump data request\n");
-        {
-            unifiio_coredump_req_t dump_req;    /* Public OS layer structure */
-            unifi_coredump_req_t priv_req;      /* Private HIP structure */
-
-            if (copy_from_user((void*)(&dump_req), (void*)arg, sizeof(dump_req))) {
-                r = -EFAULT;
-                goto out;
-            }
-            memset(&priv_req, 0, sizeof(priv_req));
-            priv_req.index = dump_req.index;
-            priv_req.offset = dump_req.offset;
-
-            /* Convert OS-layer's XAP memory space ID to HIP's ID in case they differ */
-            switch (dump_req.space) {
-                case UNIFIIO_COREDUMP_MAC_REG: priv_req.space = UNIFI_COREDUMP_MAC_REG; break;
-                case UNIFIIO_COREDUMP_PHY_REG: priv_req.space = UNIFI_COREDUMP_PHY_REG; break;
-                case UNIFIIO_COREDUMP_SH_DMEM: priv_req.space = UNIFI_COREDUMP_SH_DMEM; break;
-                case UNIFIIO_COREDUMP_MAC_DMEM: priv_req.space = UNIFI_COREDUMP_MAC_DMEM; break;
-                case UNIFIIO_COREDUMP_PHY_DMEM: priv_req.space = UNIFI_COREDUMP_PHY_DMEM; break;
-                case UNIFIIO_COREDUMP_TRIGGER_MAGIC: priv_req.space = UNIFI_COREDUMP_TRIGGER_MAGIC; break;
-                default:
-                  r = -EINVAL;
-                  goto out;
-            }
-
-            if (priv_req.space == UNIFI_COREDUMP_TRIGGER_MAGIC) {
-                /* Force a coredump grab now */
-                unifi_trace(priv, UDBG2, "UNIFI_COREDUMP_GET_REG: Force capture\n");
-                csrResult = unifi_coredump_capture(priv->card, &priv_req);
-                r = CsrHipResultToStatus(csrResult);
-                unifi_trace(priv, UDBG5, "UNIFI_COREDUMP_GET_REG: status %d\n", r);
-            } else {
-                /* Retrieve the appropriate register entry */
-                csrResult = unifi_coredump_get_value(priv->card, &priv_req);
-                r = CsrHipResultToStatus(csrResult);
-                if (r) {
-                    unifi_trace(priv, UDBG5, "UNIFI_COREDUMP_GET_REG: Status %d\n", r);
-                    goto out;
-                }
-                /* Update the OS-layer structure with values returned in the private */
-                dump_req.value = priv_req.value;
-                dump_req.timestamp = priv_req.timestamp;
-                dump_req.requestor = priv_req.requestor;
-                dump_req.serial = priv_req.serial;
-                dump_req.chip_ver = priv_req.chip_ver;
-                dump_req.fw_ver = priv_req.fw_ver;
-                dump_req.drv_build = 0;
-
-                unifi_trace(priv, UDBG6,
-                            "Dump: %d (seq %d): V:0x%04x (%d) @0x%02x:%04x = 0x%04x\n",
-                            dump_req.index, dump_req.serial,
-                            dump_req.chip_ver, dump_req.drv_build,
-                            dump_req.space, dump_req.offset, dump_req.value);
-            }
-            if (copy_to_user((void*)arg, (void*)&dump_req, sizeof(dump_req))) {
-                r = -EFAULT;
-                goto out;
-            }
-        }
-        break;
-#endif
-      default:
-        r = -EINVAL;
-    }
-
-out:
-    return (long)r;
-} /* unifi_ioctl() */
-
-
-
-static unsigned int
-unifi_poll(struct file *filp, poll_table *wait)
-{
-    ul_client_t *pcli = (ul_client_t*)filp->private_data;
-    unsigned int mask = 0;
-    int ready;
-
-    ready = !list_empty(&pcli->udi_log);
-
-    poll_wait(filp, &pcli->udi_wq, wait);
-
-    if (ready) {
-        mask |= POLLIN | POLLRDNORM;    /* readable */
-    }
-
-    return mask;
-} /* unifi_poll() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  udi_set_log_filter
- *
- *      Configure the bit mask that determines which signal primitives are
- *      passed to the logging process.
- *
- *  Arguments:
- *      pcli            Pointer to the client to configure.
- *      udi_filter      Pointer to a unifiio_filter_t containing instructions.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      SigGetFilterPos() returns a 32-bit value that contains an index and a
- *      mask for accessing a signal_filter array. The top 16 bits specify an
- *      index into a signal_filter, the bottom 16 bits specify a mask to
- *      apply.
- * ---------------------------------------------------------------------------
- */
-static void
-udi_set_log_filter(ul_client_t *pcli, unifiio_filter_t *udi_filter)
-{
-    u32 filter_pos;
-    int i;
-
-    if (udi_filter->action == UfSigFil_AllOn)
-    {
-        for (i = 0; i < SIG_FILTER_SIZE; i++) {
-            pcli->signal_filter[i] = 0xFFFF;
-        }
-    }
-    else if (udi_filter->action == UfSigFil_AllOff)
-    {
-        for (i = 0; i < SIG_FILTER_SIZE; i++) {
-            pcli->signal_filter[i] = 0;
-        }
-    }
-    else if (udi_filter->action == UfSigFil_SelectOn)
-    {
-        for (i = 0; i < udi_filter->num_sig_ids; i++) {
-            filter_pos = SigGetFilterPos(udi_filter->sig_ids[i]);
-            if (filter_pos == 0xFFFFFFFF)
-            {
-                printk(KERN_WARNING
-                       "Unrecognised signal id (0x%X) specifed in logging filter\n",
-                       udi_filter->sig_ids[i]);
-            } else {
-                pcli->signal_filter[filter_pos >> 16] |= (filter_pos & 0xFFFF);
-            }
-        }
-    }
-    else if (udi_filter->action == UfSigFil_SelectOff)
-    {
-        for (i = 0; i < udi_filter->num_sig_ids; i++) {
-            filter_pos = SigGetFilterPos(udi_filter->sig_ids[i]);
-            if (filter_pos == 0xFFFFFFFF)
-            {
-                printk(KERN_WARNING
-                       "Unrecognised signal id (0x%X) specifed in logging filter\n",
-                       udi_filter->sig_ids[i]);
-            } else {
-                pcli->signal_filter[filter_pos >> 16] &= ~(filter_pos & 0xFFFF);
-            }
-        }
-    }
-
-} /* udi_set_log_filter() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  udi_log_event
- *
- *      Callback function to be registered as the UDI hook callback.
- *      Copies the signal content into a new udi_log_t struct and adds
- *      it to the read queue for this UDI client.
- *
- *  Arguments:
- *      pcli            A pointer to the client instance.
- *      signal          Pointer to the received signal.
- *      signal_len      Size of the signal structure in bytes.
- *      bulkdata        Pointers to any associated bulk data.
- *      dir             Direction of the signal. Zero means from host,
- *                      non-zero means to host.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-udi_log_event(ul_client_t *pcli,
-              const u8 *signal, int signal_len,
-              const bulk_data_param_t *bulkdata,
-              int dir)
-{
-    udi_log_t *logptr;
-    u8 *p;
-    int i;
-    int total_len;
-    udi_msg_t *msgptr;
-    u32 filter_pos;
-#ifdef OMNICLI_LINUX_EXTRA_LOG
-    static volatile unsigned int printk_cpu = UINT_MAX;
-    unsigned long long t;
-    unsigned long nanosec_rem;
-    unsigned long n_1000;
-#endif
-
-    /* Just a sanity check */
-    if ((signal == NULL) || (signal_len <= 0)) {
-        return;
-    }
-
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-    /* When HIP offline signal logging is enabled, omnicli cannot run */
-    if (log_hip_signals)
-    {
-        /* Add timestamp */
-        if (log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP)
-        {
-            int timestamp = jiffies_to_msecs(jiffies);
-            unifi_debug_log_to_buf("T:");
-            unifi_debug_log_to_buf("%04X%04X ", *(((u16*)&timestamp) + 1),
-                                   *(u16*)&timestamp);
-        }
-
-        /* Add signal */
-        unifi_debug_log_to_buf("S%s:%04X R:%04X D:%04X ",
-                               dir ? "T" : "F",
-                               *(u16*)signal,
-                               *(u16*)(signal + 2),
-                               *(u16*)(signal + 4));
-        unifi_debug_hex_to_buf(signal + 6, signal_len - 6);
-
-        /* Add bulk data (assume 1 bulk data per signal) */
-        if ((log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA) &&
-            (bulkdata->d[0].data_length > 0))
-        {
-            unifi_debug_log_to_buf("\nD:");
-            unifi_debug_hex_to_buf(bulkdata->d[0].os_data_ptr, bulkdata->d[0].data_length);
-        }
-        unifi_debug_log_to_buf("\n");
-
-        return;
-    }
-#endif
-
-#ifdef CSR_NATIVE_LINUX
-    uf_native_process_udi_signal(pcli, signal, signal_len, bulkdata, dir);
-#endif
-
-    /*
-     * Apply the logging filter - only report signals that have their
-     * bit set in the filter mask.
-     */
-    filter_pos = SigGetFilterPos(GET_SIGNAL_ID(signal));
-
-    if ((filter_pos != 0xFFFFFFFF) &&
-        ((pcli->signal_filter[filter_pos >> 16] & (filter_pos & 0xFFFF)) == 0))
-    {
-        /* Signal is not wanted by client */
-        return;
-    }
-
-
-    /* Calculate the buffer we need to store signal plus bulk data */
-    total_len = signal_len;
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
-        total_len += bulkdata->d[i].data_length;
-    }
-
-    /* Allocate log structure plus actual signal. */
-    logptr = kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL);
-
-    if (logptr == NULL) {
-        printk(KERN_ERR
-               "Failed to allocate %lu bytes for a UDI log record\n",
-               (long unsigned int)(sizeof(udi_log_t) + total_len));
-        return;
-    }
-
-    /* Fill in udi_log struct */
-    INIT_LIST_HEAD(&logptr->q);
-    msgptr = &logptr->msg;
-    msgptr->length = sizeof(udi_msg_t) + total_len;
-#ifdef OMNICLI_LINUX_EXTRA_LOG
-    t = cpu_clock(printk_cpu);
-    nanosec_rem = do_div(t, 1000000000);
-    n_1000 = nanosec_rem/1000;
-    msgptr->timestamp = (t <<10 ) | ((unsigned long)(n_1000 >> 10) & 0x3ff);
-#else
-    msgptr->timestamp = jiffies_to_msecs(jiffies);
-#endif
-    msgptr->direction = dir;
-    msgptr->signal_length = signal_len;
-
-    /* Copy signal and bulk data to the log */
-    p = (u8 *)(msgptr + 1);
-    memcpy(p, signal, signal_len);
-    p += signal_len;
-
-    /* Append any bulk data */
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
-        int len = bulkdata->d[i].data_length;
-
-        /*
-         * Len here might not be the same as the length in the bulk data slot.
-         * The slot length will always be even, but len could be odd.
-         */
-        if (len > 0) {
-            if (bulkdata->d[i].os_data_ptr) {
-                memcpy(p, bulkdata->d[i].os_data_ptr, len);
-            } else {
-                memset(p, 0, len);
-            }
-            p += len;
-        }
-    }
-
-    /* Add to tail of log queue */
-    if (down_interruptible(&pcli->udi_sem)) {
-        printk(KERN_WARNING "udi_log_event_q: Failed to get udi sem\n");
-        kfree(logptr);
-        return;
-    }
-    list_add_tail(&logptr->q, &pcli->udi_log);
-    up(&pcli->udi_sem);
-
-    /* Wake any waiting user process */
-    wake_up_interruptible(&pcli->udi_wq);
-
-} /* udi_log_event() */
-
-#ifdef CSR_SME_USERSPACE
-int
-uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length)
-{
-    udi_log_t *logptr;
-    udi_msg_t *msgptr;
-    u8 *p;
-
-    /* Just a sanity check */
-    if ((buffer == NULL) || (length <= 0)) {
-        return -EINVAL;
-    }
-
-    /* Allocate log structure plus actual signal. */
-    logptr = kmalloc(sizeof(udi_log_t) + length, GFP_ATOMIC);
-    if (logptr == NULL) {
-        unifi_error(priv, "Failed to allocate %d bytes for an SME message\n",
-                    sizeof(udi_log_t) + length);
-                    kfree(buffer);
-                    return -ENOMEM;
-    }
-
-    /* Fill in udi_log struct */
-    INIT_LIST_HEAD(&logptr->q);
-    msgptr = &logptr->msg;
-    msgptr->length = sizeof(udi_msg_t) + length;
-    msgptr->signal_length = length;
-
-    /* Copy signal and bulk data to the log */
-    p = (u8 *)(msgptr + 1);
-    memcpy(p, buffer, length);
-
-    /* Add to tail of log queue */
-    down(&udi_mutex);
-    if (priv->sme_cli == NULL) {
-        kfree(logptr);
-        kfree(buffer);
-        up(&udi_mutex);
-        unifi_info(priv, "Message for the SME dropped, SME has gone away\n");
-        return 0;
-    }
-
-    down(&priv->sme_cli->udi_sem);
-    list_add_tail(&logptr->q, &priv->sme_cli->udi_log);
-    up(&priv->sme_cli->udi_sem);
-
-    /* Wake any waiting user process */
-    wake_up_interruptible(&priv->sme_cli->udi_wq);
-    up(&udi_mutex);
-
-    /* It is our responsibility to free the buffer allocated in build_packed_*() */
-    kfree(buffer);
-
-    return 0;
-
-} /* uf_sme_queue_message() */
-#endif
-
-/*
- ****************************************************************************
- *
- *      Driver instantiation
- *
- ****************************************************************************
- */
-static const struct file_operations unifi_fops = {
-    .owner      = THIS_MODULE,
-    .open       = unifi_open,
-    .release    = unifi_release,
-    .read       = unifi_read,
-    .write      = unifi_write,
-    .unlocked_ioctl = unifi_ioctl,
-    .poll       = unifi_poll,
-};
-
-static dev_t unifi_first_devno;
-static struct class *unifi_class;
-
-
-int uf_create_device_nodes(unifi_priv_t *priv, int bus_id)
-{
-    dev_t devno;
-    int r;
-
-    cdev_init(&priv->unifi_cdev, &unifi_fops);
-
-    /* cdev_init() should set the cdev owner, but it does not */
-    priv->unifi_cdev.owner = THIS_MODULE;
-
-    devno = MKDEV(MAJOR(unifi_first_devno),
-                  MINOR(unifi_first_devno) + (bus_id * 2));
-    r = cdev_add(&priv->unifi_cdev, devno, 1);
-    if (r) {
-        return r;
-    }
-
-#ifdef SDIO_EXPORTS_STRUCT_DEVICE
-    if (!device_create(unifi_class, priv->unifi_device,
-                       devno, priv, "unifi%d", bus_id)) {
-#else
-    priv->unifi_device = device_create(unifi_class, NULL,
-                                       devno, priv, "unifi%d", bus_id);
-    if (priv->unifi_device == NULL) {
-#endif /* SDIO_EXPORTS_STRUCT_DEVICE */
-
-        cdev_del(&priv->unifi_cdev);
-        return -EINVAL;
-    }
-
-    cdev_init(&priv->unifiudi_cdev, &unifi_fops);
-
-    /* cdev_init() should set the cdev owner, but it does not */
-    priv->unifiudi_cdev.owner = THIS_MODULE;
-
-    devno = MKDEV(MAJOR(unifi_first_devno),
-                  MINOR(unifi_first_devno) + (bus_id * 2) + 1);
-    r = cdev_add(&priv->unifiudi_cdev, devno, 1);
-    if (r) {
-        device_destroy(unifi_class, priv->unifi_cdev.dev);
-        cdev_del(&priv->unifi_cdev);
-        return r;
-    }
-
-    if (!device_create(unifi_class,
-#ifdef SDIO_EXPORTS_STRUCT_DEVICE
-                       priv->unifi_device,
-#else
-                       NULL,
-#endif /* SDIO_EXPORTS_STRUCT_DEVICE */
-                       devno, priv, "unifiudi%d", bus_id)) {
-        device_destroy(unifi_class, priv->unifi_cdev.dev);
-        cdev_del(&priv->unifiudi_cdev);
-        cdev_del(&priv->unifi_cdev);
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-
-void uf_destroy_device_nodes(unifi_priv_t *priv)
-{
-	device_destroy(unifi_class, priv->unifiudi_cdev.dev);
-	device_destroy(unifi_class, priv->unifi_cdev.dev);
-	cdev_del(&priv->unifiudi_cdev);
-	cdev_del(&priv->unifi_cdev);
-}
-
-
-
-/*
- * ----------------------------------------------------------------
- *  uf_create_debug_device
- *
- *      Allocates device numbers for unifi character device nodes
- *      and creates a unifi class in sysfs
- *
- * Arguments:
- *  fops          Pointer to the char device operations structure.
- *
- * Returns:
- *      0 on success, -ve error code on error.
- * ----------------------------------------------------------------
- */
-static int
-uf_create_debug_device(const struct file_operations *fops)
-{
-    int ret;
-
-    /* Allocate two device numbers for each device. */
-    ret = alloc_chrdev_region(&unifi_first_devno, 0, MAX_UNIFI_DEVS*2, UNIFI_NAME);
-    if (ret) {
-        unifi_error(NULL, "Failed to add alloc dev numbers: %d\n", ret);
-        return ret;
-    }
-
-    /* Create a UniFi class */
-    unifi_class = class_create(THIS_MODULE, UNIFI_NAME);
-    if (IS_ERR(unifi_class)) {
-        unifi_error(NULL, "Failed to create UniFi class\n");
-
-        /* Release device numbers */
-        unregister_chrdev_region(unifi_first_devno, MAX_UNIFI_DEVS*2);
-        unifi_first_devno = 0;
-        return -EINVAL;
-    }
-
-    return 0;
-} /* uf_create_debug_device() */
-
-
-/*
- * ----------------------------------------------------------------
- *  uf_remove_debug_device
- *
- *      Destroys the unifi class and releases the allocated
- *      device numbers for unifi character device nodes.
- *
- * Arguments:
- *
- * Returns:
- * ----------------------------------------------------------------
- */
-static void
-uf_remove_debug_device(void)
-{
-    /* Destroy the UniFi class */
-    class_destroy(unifi_class);
-
-    /* Release device numbers */
-    unregister_chrdev_region(unifi_first_devno, MAX_UNIFI_DEVS*2);
-    unifi_first_devno = 0;
-
-} /* uf_remove_debug_device() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *
- *      Module loading.
- *
- * ---------------------------------------------------------------------------
- */
-int __init
-unifi_load(void)
-{
-    int r;
-
-    printk("UniFi SDIO Driver: %s %s %s\n",
-            CSR_WIFI_VERSION,
-           __DATE__, __TIME__);
-
-#ifdef CSR_SME_USERSPACE
-#ifdef CSR_SUPPORT_WEXT
-    printk("CSR SME with WEXT support\n");
-#else
-    printk("CSR SME no WEXT support\n");
-#endif /* CSR_SUPPORT_WEXT */
-#endif /* CSR_SME_USERSPACE */
-
-#ifdef CSR_NATIVE_LINUX
-#ifdef CSR_SUPPORT_WEXT
-#error WEXT unsupported in the native driver
-#endif
-    printk("CSR native no WEXT support\n");
-#endif
-#ifdef CSR_WIFI_SPLIT_PATCH
-    printk("Split patch support\n");
-#endif
-    printk("Kernel %d.%d.%d\n",
-           ((LINUX_VERSION_CODE) >> 16) & 0xff,
-           ((LINUX_VERSION_CODE) >> 8) & 0xff,
-           (LINUX_VERSION_CODE) & 0xff);
-    /*
-     * Instantiate the /dev/unifi* device nodes.
-     * We must do this before registering with the SDIO driver because it
-     * will immediately call the "insert" callback if the card is
-     * already present.
-     */
-    r = uf_create_debug_device(&unifi_fops);
-    if (r) {
-        return r;
-    }
-
-    /* Now register with the SDIO driver */
-    r = uf_sdio_load();
-    if (r) {
-        uf_remove_debug_device();
-        return r;
-    }
-
-    if (sdio_block_size > -1) {
-        unifi_info(NULL, "sdio_block_size %d\n", sdio_block_size);
-    }
-
-    if (sdio_byte_mode) {
-        unifi_info(NULL, "sdio_byte_mode\n");
-    }
-
-    if (disable_power_control) {
-        unifi_info(NULL, "disable_power_control\n");
-    }
-
-    if (disable_hw_reset) {
-        unifi_info(NULL, "disable_hw_reset\n");
-    }
-
-    if (enable_wol) {
-        unifi_info(NULL, "enable_wol %d\n", enable_wol);
-    }
-
-    if (run_bh_once != -1) {
-        unifi_info(NULL, "run_bh_once %d\n", run_bh_once);
-    }
-
-    return 0;
-} /* unifi_load() */
-
-
-void __exit
-unifi_unload(void)
-{
-    /* The SDIO remove hook will call unifi_disconnect(). */
-    uf_sdio_unload();
-
-    uf_remove_debug_device();
-
-} /* unifi_unload() */
-
-module_init(unifi_load);
-module_exit(unifi_unload);
-
-MODULE_DESCRIPTION("UniFi Device driver");
-MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
-MODULE_LICENSE("GPL and additional rights");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/firmware.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/firmware.c
--- linux-libre-3.10-gnu/drivers/staging/csr/firmware.c	2013-07-01 10:38:12.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/firmware.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,396 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     firmware.c
- *
- *  PURPOSE:
- *      Implements the f/w related HIP core lib API.
- *      It is part of the porting exercise in Linux.
- *
- *      Also, it contains example code for reading the loader and f/w files
- *      from the userspace and starting the SME in Linux.
- *
- * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/kmod.h>
-#include <linux/vmalloc.h>
-#include <linux/firmware.h>
-#include <asm/uaccess.h>
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_unifi_udi.h"
-#include "unifiio.h"
-#include "unifi_priv.h"
-
-/*
- * ---------------------------------------------------------------------------
- *
- *      F/W download. Part of the HIP core API
- *
- * ---------------------------------------------------------------------------
- */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_fw_read_start
- *
- *      Returns a structure to be passed in unifi_fw_read().
- *      This structure is an OS specific description of the f/w file.
- *      In the linux implementation it is a buffer with the f/w and its' length.
- *      The HIP driver calls this functions to request for the loader or
- *      the firmware file.
- *      The structure pointer can be freed when unifi_fw_read_stop() is called.
- *
- *  Arguments:
- *      ospriv          Pointer to driver context.
- *      is_fw           Type of firmware to retrieve
- *      info            Versions information. Can be used to determine
- *                      the appropriate f/w file to load.
- *
- *  Returns:
- *      O on success, non-zero otherwise.
- *
- * ---------------------------------------------------------------------------
- */
-void*
-unifi_fw_read_start(void *ospriv, s8 is_fw, const card_info_t *info)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-    CSR_UNUSED(info);
-
-    if (is_fw == UNIFI_FW_STA) {
-        /* F/w may have been released after a previous successful download. */
-        if (priv->fw_sta.dl_data == NULL) {
-            unifi_trace(priv, UDBG2, "Attempt reload of sta f/w\n");
-            uf_reject_firmware_files(priv, UNIFI_FW_STA);
-        }
-        /* Set up callback struct for readfunc() */
-        if (priv->fw_sta.dl_data != NULL) {
-            return &priv->fw_sta;
-        }
-
-    } else {
-        unifi_error(priv, "downloading firmware... unknown request: %d\n", is_fw);
-    }
-
-    return NULL;
-} /* unifi_fw_read_start() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_fw_read_stop
- *
- *      Called when the HIP driver has finished using the loader or
- *      the firmware file.
- *      The firmware buffer may be released now.
- *
- *  Arguments:
- *      ospriv          Pointer to driver context.
- *      dlpriv          The pointer returned by unifi_fw_read_start()
- *
- * ---------------------------------------------------------------------------
- */
-void
-unifi_fw_read_stop(void *ospriv, void *dlpriv)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-    struct dlpriv *dl_struct = (struct dlpriv *)dlpriv;
-
-    if (dl_struct != NULL) {
-        if (dl_struct->dl_data != NULL) {
-            unifi_trace(priv, UDBG2, "Release f/w buffer %p, %d bytes\n",
-                        dl_struct->dl_data, dl_struct->dl_len);
-        }
-        uf_release_firmware(priv, dl_struct);
-    }
-
-} /* unifi_fw_read_stop() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_fw_open_buffer
- *
- *  Returns a handle for a buffer dynamically allocated by the driver,
- *  e.g. into which a firmware file may have been converted from another format
- *  which is the case with some production test images.
- *
- *  The handle may then be used by unifi_fw_read() to access the contents of
- *  the buffer.
- *
- *  Arguments:
- *      ospriv          Pointer to driver context.
- *      fwbuf           Buffer containing firmware image
- *      len             Length of buffer in bytes
- *
- *  Returns
- *      Handle for buffer, or NULL on error
- * ---------------------------------------------------------------------------
- */
-void *
-unifi_fw_open_buffer(void *ospriv, void *fwbuf, u32 len)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-
-    if (fwbuf == NULL) {
-        return NULL;
-    }
-    priv->fw_conv.dl_data = fwbuf;
-    priv->fw_conv.dl_len = len;
-    priv->fw_conv.fw_desc = NULL;   /* No OS f/w resource is associated */
-
-    return &priv->fw_conv;
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_fw_close_buffer
- *
- *  Releases any handle for a buffer dynamically allocated by the driver,
- *  e.g. into which a firmware file may have been converted from another format
- *  which is the case with some production test images.
- *
- *
- *  Arguments:
- *      ospriv          Pointer to driver context.
- *      fwbuf           Buffer containing firmware image
- *
- *  Returns
- *      Handle for buffer, or NULL on error
- * ---------------------------------------------------------------------------
- */
-void unifi_fw_close_buffer(void *ospriv, void *fwbuf)
-{
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_fw_read
- *
- *      The HIP driver calls this function to ask for a part of the loader or
- *      the firmware file.
- *
- *  Arguments:
- *      ospriv          Pointer to driver context.
- *      arg             The pointer returned by unifi_fw_read_start().
- *      offset          The offset in the file to return from.
- *      buf             A buffer to store the requested data.
- *      len             The size of the buf and the size of the requested data.
- *
- *  Returns
- *      The number of bytes read from the firmware image, or -ve on error
- * ---------------------------------------------------------------------------
- */
-s32
-unifi_fw_read(void *ospriv, void *arg, u32 offset, void *buf, u32 len)
-{
-    const struct dlpriv *dlpriv = arg;
-
-    if (offset >= dlpriv->dl_len) {
-        /* at end of file */
-        return 0;
-    }
-
-    if ((offset + len) > dlpriv->dl_len) {
-        /* attempt to read past end of file */
-        return -1;
-    }
-
-    memcpy(buf, dlpriv->dl_data+offset, len);
-
-    return len;
-
-} /* unifi_fw_read() */
-
-
-
-
-#define UNIFIHELPER_INIT_MODE_SMEUSER   2
-#define UNIFIHELPER_INIT_MODE_NATIVE    1
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_run_unifihelper
- *
- *      Ask userspace to send us firmware for download by running
- *      '/usr/sbin/unififw'.
- *      The same script starts the SME userspace application.
- *      Derived from net_run_sbin_hotplug().
- *
- *  Arguments:
- *      priv            Pointer to OS private struct.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-int
-uf_run_unifihelper(unifi_priv_t *priv)
-{
-#ifdef ANDROID_BUILD
-    char *prog = "/system/bin/unififw";
-#else
-    char *prog = "/usr/sbin/unififw";
-#endif /* ANDROID_BUILD */
-
-    char *argv[6], *envp[4];
-    char inst_str[8];
-    char init_mode[8];
-    int i, r;
-
-#if (defined CSR_SME_USERSPACE) && (!defined CSR_SUPPORT_WEXT)
-    unifi_trace(priv, UDBG1, "SME userspace build: run unifi_helper manually\n");
-    return 0;
-#endif
-
-    unifi_trace(priv, UDBG1, "starting %s\n", prog);
-
-    snprintf(inst_str,   8, "%d", priv->instance);
-#if (defined CSR_SME_USERSPACE)
-    snprintf(init_mode, 8, "%d", UNIFIHELPER_INIT_MODE_SMEUSER);
-#else
-    snprintf(init_mode, 8, "%d", UNIFIHELPER_INIT_MODE_NATIVE);
-#endif /* CSR_SME_USERSPACE */
-
-    i = 0;
-    argv[i++] = prog;
-    argv[i++] = inst_str;
-    argv[i++] = init_mode;
-    argv[i++] = 0;
-    argv[i] = 0;
-    /* Don't add more args without making argv bigger */
-
-    /* minimal command environment */
-    i = 0;
-    envp[i++] = "HOME=/";
-    envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-    envp[i] = 0;
-    /* Don't add more without making envp bigger */
-
-    unifi_trace(priv, UDBG2, "running %s %s %s\n", argv[0], argv[1], argv[2]);
-
-    r = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
-
-    return r;
-} /* uf_run_unifihelper() */
-
-#ifdef CSR_WIFI_SPLIT_PATCH
-static u8 is_ap_mode(unifi_priv_t *priv)
-{
-    if (priv == NULL || priv->interfacePriv[0] == NULL)
-    {
-        return FALSE;
-    }
-
-    /* Test for mode requiring AP patch */
-    return(CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode));
-}
-#endif
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_reject_firmware_files
- *
- *      Get the firmware files from userspace.
- *
- *  Arguments:
- *      priv            Pointer to OS private struct.
- *      is_fw           type of firmware to load (UNIFI_FW_STA/LOADER)
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-int uf_reject_firmware_files(unifi_priv_t *priv, int is_fw)
-{
-    /* uses the default method to get the firmware */
-    const struct firmware *fw_entry;
-    int postfix;
-#define UNIFI_MAX_FW_PATH_LEN       32
-    char fw_name[UNIFI_MAX_FW_PATH_LEN];
-    int r;
-
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-    if (priv->mib_data.length) {
-        vfree(priv->mib_data.data);
-        priv->mib_data.data = NULL;
-        priv->mib_data.length = 0;
-    }
-#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/
-
-    postfix = priv->instance;
-
-    if (is_fw == UNIFI_FW_STA) {
-        /* Free kernel buffer and reload */
-        uf_release_firmware(priv, &priv->fw_sta);
-#ifdef CSR_WIFI_SPLIT_PATCH
-        scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
-                  postfix, (is_ap_mode(priv) ? "ap.xbv" : "staonly.xbv") );
-#else
-        scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
-                  postfix, "sta.xbv" );
-#endif
-        r = reject_firmware(&fw_entry, fw_name, priv->unifi_device);
-        if (r == 0) {
-            priv->fw_sta.dl_data = fw_entry->data;
-            priv->fw_sta.dl_len = fw_entry->size;
-            priv->fw_sta.fw_desc = (void *)fw_entry;
-        } else {
-            unifi_trace(priv, UDBG2, "Firmware file not available\n");
-        }
-    }
-
-    return 0;
-
-} /* uf_reject_firmware_files() */
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_release_firmware_files
- *
- *      Release all buffers used to store firmware files
- *
- *  Arguments:
- *      priv            Pointer to OS private struct.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-int uf_release_firmware_files(unifi_priv_t *priv)
-{
-    uf_release_firmware(priv, &priv->fw_sta);
-
-    return 0;
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_release_firmware
- *
- *      Release specific buffer used to store firmware
- *
- *  Arguments:
- *      priv            Pointer to OS private struct.
- *      to_free         Pointer to specific buffer to release
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-int uf_release_firmware(unifi_priv_t *priv, struct dlpriv *to_free)
-{
-    if (to_free != NULL) {
-        release_firmware((const struct firmware *)to_free->fw_desc);
-        to_free->fw_desc = NULL;
-        to_free->dl_data = NULL;
-        to_free->dl_len = 0;
-    }
-    return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/inet.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/inet.c
--- linux-libre-3.10-gnu/drivers/staging/csr/inet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/inet.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,104 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     inet.c
- *
- *  PURPOSE:
- *      Routines related to IP address changes.
- *      Optional part of the porting exercise. It uses system network
- *      handlers to obtain the UniFi IP address and pass it to the SME
- *      using the unifi_sys_ip_configured_ind().
- *
- * Copyright (C) 2008-2009 Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/inetdevice.h>
-#include <linux/notifier.h>
-
-#include "unifi_priv.h"
-#include "csr_wifi_hip_conversions.h"
-
-/*
- * The inet notifier is global and not per-netdev.  To avoid having a
- * notifier registered when there are no unifi devices present, it's
- * registered after the first unifi network device is registered, and
- * unregistered when the last unifi network device is unregistered.
- */
-
-static atomic_t inet_notif_refs = ATOMIC_INIT(0);
-
-static int uf_inetaddr_event(struct notifier_block *notif, unsigned long event, void *ifa)
-{
-    struct net_device *ndev;
-    unifi_priv_t *priv;
-    struct in_ifaddr *if_addr;
-    netInterface_priv_t *InterfacePriv = (netInterface_priv_t *)NULL;
-
-    if (!ifa || !((struct in_ifaddr *)ifa)->ifa_dev) {
-        unifi_trace(NULL, UDBG1, "uf_inetaddr_event (%lu) ifa=%p\n", event, ifa);
-        return NOTIFY_DONE;
-    }
-
-    ndev = ((struct in_ifaddr *)ifa)->ifa_dev->dev;
-    InterfacePriv = (netInterface_priv_t*) netdev_priv(ndev);
-
-    /* As the notifier is global, the call may be for a non-UniFi netdev.
-     * Therefore check the netdev_priv to make sure it's a known UniFi one.
-     */
-    if (uf_find_netdev_priv(InterfacePriv) == -1) {
-        unifi_trace(NULL, UDBG1, "uf_inetaddr_event (%lu) ndev=%p, other netdev_priv=%p\n",
-                    event, ndev, InterfacePriv);
-        return NOTIFY_DONE;
-    }
-
-    if (!InterfacePriv->privPtr) {
-        unifi_error(NULL, "uf_inetaddr_event null priv (%lu) ndev=%p, InterfacePriv=%p\n",
-                    event, ndev, InterfacePriv);
-        return NOTIFY_DONE;
-    }
-
-    priv = InterfacePriv->privPtr;
-    if_addr = (struct in_ifaddr *)ifa;
-
-    /* If this event is for a UniFi device, notify the SME that an IP
-     * address has been added or removed. */
-    if (uf_find_priv(priv) != -1) {
-        switch (event) {
-            case NETDEV_UP:
-                unifi_info(priv, "IP address assigned for %s\n", priv->netdev[InterfacePriv->InterfaceTag]->name);
-                priv->sta_ip_address = if_addr->ifa_address;
-#ifdef CSR_SUPPORT_WEXT
-                sme_mgt_packet_filter_set(priv);
-#endif
-                break;
-            case NETDEV_DOWN:
-                unifi_info(priv, "IP address removed for %s\n", priv->netdev[InterfacePriv->InterfaceTag]->name);
-                priv->sta_ip_address = 0xFFFFFFFF;
-#ifdef CSR_SUPPORT_WEXT
-                sme_mgt_packet_filter_set(priv);
-#endif
-                break;
-        }
-    }
-
-    return NOTIFY_DONE;
-}
-
-static struct notifier_block uf_inetaddr_notifier = {
-    .notifier_call = uf_inetaddr_event,
-};
-
-void uf_register_inet_notifier(void)
-{
-	if (atomic_inc_return(&inet_notif_refs) == 1)
-		register_inetaddr_notifier(&uf_inetaddr_notifier);
-}
-
-void uf_unregister_inet_notifier(void)
-{
-	if (atomic_dec_return(&inet_notif_refs) == 0)
-		unregister_inetaddr_notifier(&uf_inetaddr_notifier);
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/init_hw.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/init_hw.c
--- linux-libre-3.10-gnu/drivers/staging/csr/init_hw.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/init_hw.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,108 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     init_hw.c
- *
- * PURPOSE:
- *      Use the HIP core lib to initialise the UniFi chip.
- *      It is part of the porting exercise in Linux.
- *
- * Copyright (C) 2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include "csr_wifi_hip_unifi.h"
-#include "unifi_priv.h"
-
-
-#define MAX_INIT_ATTEMPTS        4
-
-extern int led_mask;
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_init_hw
- *
- *      Resets hardware, downloads and initialises f/w.
- *      This function demonstrates how to use the HIP core lib API
- *      to implement the SME unifi_sys_wifi_on_req() part of the SYS API.
- *
- *      In a simple implementation, all this function needs to do is call
- *      unifi_init_card() and then unifi_card_info().
- *      In the Linux implementation, it will retry to initialise UniFi or
- *      try to debug the reasons if unifi_init_card() returns an error.
- *
- *  Arguments:
- *      ospriv          Pointer to OS driver structure for the device.
- *
- *  Returns:
- *      O on success, non-zero otherwise.
- *
- * ---------------------------------------------------------------------------
- */
-int
-uf_init_hw(unifi_priv_t *priv)
-{
-    int attempts = 0;
-    int priv_instance;
-    CsrResult csrResult = CSR_RESULT_FAILURE;
-
-    priv_instance = uf_find_priv(priv);
-    if (priv_instance == -1) {
-        unifi_warning(priv, "uf_init_hw: Unknown priv instance, will use fw_init[0]\n");
-        priv_instance = 0;
-    }
-
-    while (1) {
-        if (attempts > MAX_INIT_ATTEMPTS) {
-            unifi_error(priv, "Failed to initialise UniFi after %d attempts, "
-                        "giving up.\n",
-                        attempts);
-            break;
-        }
-        attempts++;
-
-        unifi_info(priv, "Initialising UniFi, attempt %d\n", attempts);
-
-        if (fw_init[priv_instance] > 0) {
-            unifi_notice(priv, "f/w init prevented by module parameter\n");
-            break;
-        } else if (fw_init[priv_instance] == 0) {
-            fw_init[priv_instance] ++;
-        }
-
-        /*
-         * Initialise driver core. This will perform a reset of UniFi
-         * internals, but not the SDIO CCCR.
-         */
-        CsrSdioClaim(priv->sdio);
-        csrResult = unifi_init_card(priv->card, led_mask);
-        CsrSdioRelease(priv->sdio);
-
-        if (csrResult == CSR_WIFI_HIP_RESULT_NO_DEVICE) {
-            return CsrHipResultToStatus(csrResult);
-        }
-        if (csrResult == CSR_WIFI_HIP_RESULT_NOT_FOUND) {
-            unifi_error(priv, "Firmware file required, but not found.\n");
-            return CsrHipResultToStatus(csrResult);
-        }
-        if (csrResult != CSR_RESULT_SUCCESS) {
-            /* failed. Reset h/w and try again */
-            unifi_error(priv, "Failed to initialise UniFi chip.\n");
-            continue;
-        }
-
-        /* Get the version information from the lib_hip */
-        unifi_card_info(priv->card, &priv->card_info);
-
-        return CsrHipResultToStatus(csrResult);
-    }
-
-    return CsrHipResultToStatus(csrResult);
-
-} /* uf_init_hw */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/io.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/io.c
--- linux-libre-3.10-gnu/drivers/staging/csr/io.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/io.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1098 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     io.c
- *
- *  PURPOSE:
- *      This file contains routines that the SDIO driver can call when a
- *      UniFi card is first inserted (or detected) and removed.
- *
- *      When used with sdioemb, the udev scripts (at least on Ubuntu) don't
- *      recognise a UniFi being added to the system. This is because sdioemb
- *      does not register itself as a device_driver, it uses it's own code
- *      to handle insert and remove.
- *      To have Ubuntu recognise UniFi, edit /etc/udev/rules.d/85-ifupdown.rules
- *      to change this line:
- *          SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start"
- *      to these:
- *          #SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start"
- *          SUBSYSTEM=="net", GOTO="net_start"
- *
- *      Then you can add a stanza to /etc/network/interfaces like this:
- *          auto eth1
- *          iface eth1 inet dhcp
- *          wpa-conf /etc/wpa_supplicant.conf
- *      This will then automatically associate when a car dis inserted.
- *
- * Copyright (C) 2006-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_unifiversion.h"
-#include "csr_wifi_hip_unifi_udi.h"   /* for unifi_print_status() */
-#include "unifiio.h"
-#include "unifi_priv.h"
-
-/*
- * Array of pointers to context structs for unifi devices that are present.
- * The index in the array corresponds to the wlan interface number
- * (if "wlan*" is used). If "eth*" is used, the eth* numbers are allocated
- * after any Ethernet cards.
- *
- * The Arasan PCI-SDIO controller card supported by this driver has 2 slots,
- * hence a max of 2 devices.
- */
-static unifi_priv_t *Unifi_instances[MAX_UNIFI_DEVS];
-
-/* Array of pointers to netdev objects used by the UniFi driver, as there
- * are now many per instance. This is used to determine which netdev events
- * are for UniFi as opposed to other net interfaces.
- */
-static netInterface_priv_t *Unifi_netdev_instances[MAX_UNIFI_DEVS * CSR_WIFI_NUM_INTERFACES];
-
-/*
- * Array to hold the status of each unifi device in each slot.
- * We only process an insert event when In_use[] for the slot is
- * UNIFI_DEV_NOT_IN_USE. Otherwise, it means that the slot is in use or
- * we are in the middle of a cleanup (the action on unplug).
- */
-#define UNIFI_DEV_NOT_IN_USE    0
-#define UNIFI_DEV_IN_USE        1
-#define UNIFI_DEV_CLEANUP       2
-static int In_use[MAX_UNIFI_DEVS];
-/*
- * Mutex to prevent UDI clients to open the character device before the priv
- * is created and initialised.
- */
-DEFINE_SEMAPHORE(Unifi_instance_mutex);
-/*
- * When the device is removed, unregister waits on Unifi_cleanup_wq
- * until all the UDI clients release the character device.
- */
-DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq);
-
-#ifdef CONFIG_PROC_FS
-/*
- * seq_file wrappers for procfile show routines.
- */
-static int uf_proc_show(struct seq_file *m, void *v);
-
-#define UNIFI_DEBUG_TXT_BUFFER (8 * 1024)
-
-static int uf_proc_open(struct inode *inode, struct file *file)
-{
-	return single_open_size(file, uf_proc_show, PDE_DATA(inode),
-				UNIFI_DEBUG_TXT_BUFFER);
-}
-
-static const struct file_operations uf_proc_fops = {
-	.open		= uf_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-#endif /* CONFIG_PROC_FS */
-
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-
-static CsrResult signal_buffer_init(unifi_priv_t * priv, int size)
-{
-    int i;
-
-    priv->rxSignalBuffer.writePointer =
-    priv->rxSignalBuffer.readPointer = 0;
-    priv->rxSignalBuffer.size = size;
-    /* Allocating Memory for Signal primitive pointer */
-    for(i=0; i<size; i++)
-    {
-         priv->rxSignalBuffer.rx_buff[i].sig_len=0;
-         priv->rxSignalBuffer.rx_buff[i].bufptr = kmalloc(UNIFI_PACKED_SIGBUF_SIZE, GFP_KERNEL);
-         if (priv->rxSignalBuffer.rx_buff[i].bufptr == NULL)
-         {
-             int j;
-             unifi_error(priv,"signal_buffer_init:Failed to Allocate shared memory for T-H signals \n");
-             for(j=0;j<i;j++)
-             {
-                 priv->rxSignalBuffer.rx_buff[j].sig_len=0;
-                 kfree(priv->rxSignalBuffer.rx_buff[j].bufptr);
-                 priv->rxSignalBuffer.rx_buff[j].bufptr = NULL;
-             }
-             return -1;
-         }
-    }
-    return 0;
-}
-
-
-static void signal_buffer_free(unifi_priv_t * priv, int size)
-{
-    int i;
-
-    for(i=0; i<size; i++)
-    {
-         priv->rxSignalBuffer.rx_buff[i].sig_len=0;
-         kfree(priv->rxSignalBuffer.rx_buff[i].bufptr);
-         priv->rxSignalBuffer.rx_buff[i].bufptr = NULL;
-    }
-}
-#endif
-/*
- * ---------------------------------------------------------------------------
- *  uf_register_netdev
- *
- *      Registers the network interface, installes the qdisc,
- *      and registers the inet handler.
- *      In the porting exercise, register the driver to the network
- *      stack if necessary.
- *
- *  Arguments:
- *      priv          Pointer to driver context.
- *
- *  Returns:
- *      O on success, non-zero otherwise.
- *
- *  Notes:
- *      We will only unregister when the card is ejected, so we must
- *      only do it once.
- * ---------------------------------------------------------------------------
- */
-int
-uf_register_netdev(unifi_priv_t *priv, int interfaceTag)
-{
-    int r;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "uf_register_netdev bad interfaceTag\n");
-        return -EINVAL;
-    }
-
-    /*
-     * Allocates a device number and registers device with the network
-     * stack.
-     */
-    unifi_trace(priv, UDBG5, "uf_register_netdev: netdev %d - 0x%p\n",
-            interfaceTag, priv->netdev[interfaceTag]);
-    r = register_netdev(priv->netdev[interfaceTag]);
-    if (r) {
-        unifi_error(priv, "Failed to register net device\n");
-        return -EINVAL;
-    }
-
-    /* The device is registed */
-    interfacePriv->netdev_registered = 1;
-
-#ifdef CSR_SUPPORT_SME
-    /*
-     * Register the inet handler; it notifies us for changes in the IP address.
-     */
-    uf_register_inet_notifier();
-#endif /* CSR_SUPPORT_SME */
-
-    unifi_notice(priv, "unifi%d is %s\n",
-            priv->instance, priv->netdev[interfaceTag]->name);
-
-    return 0;
-} /* uf_register_netdev */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_unregister_netdev
- *
- *      Unregisters the network interface and the inet handler.
- *
- *  Arguments:
- *      priv          Pointer to driver context.
- *
- *  Returns:
- *      None.
- *
- * ---------------------------------------------------------------------------
- */
-void
-uf_unregister_netdev(unifi_priv_t *priv)
-{
-    int i=0;
-
-#ifdef CSR_SUPPORT_SME
-    /* Unregister the inet handler... */
-    uf_unregister_inet_notifier();
-#endif /* CSR_SUPPORT_SME */
-
-    for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
-        netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
-        if (interfacePriv->netdev_registered) {
-            unifi_trace(priv, UDBG5,
-                    "uf_unregister_netdev: netdev %d - 0x%p\n",
-                    i, priv->netdev[i]);
-
-            /* ... and the netdev */
-            unregister_netdev(priv->netdev[i]);
-            interfacePriv->netdev_registered = 0;
-        }
-
-        interfacePriv->interfaceMode = 0;
-
-        /* Enable all queues by default */
-        interfacePriv->queueEnabled[0] = 1;
-        interfacePriv->queueEnabled[1] = 1;
-        interfacePriv->queueEnabled[2] = 1;
-        interfacePriv->queueEnabled[3] = 1;
-    }
-
-    priv->totalInterfaceCount = 0;
-} /* uf_unregister_netdev() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  register_unifi_sdio
- *
- *      This function is called from the Probe (or equivalent) method of
- *      the SDIO driver when a UniFi card is detected.
- *      We allocate the Linux net_device struct, initialise the HIP core
- *      lib, create the char device nodes and start the userspace helper
- *      to initialise the device.
- *
- *  Arguments:
- *      sdio_dev        Pointer to SDIO context handle to use for all
- *                      SDIO ops.
- *      bus_id          A small number indicating the SDIO card position on the
- *                      bus. Typically this is the slot number, e.g. 0, 1 etc.
- *                      Valid values are 0 to MAX_UNIFI_DEVS-1.
- *      dev             Pointer to kernel device manager struct.
- *
- *  Returns:
- *      Pointer to the unifi instance, or NULL on error.
- * ---------------------------------------------------------------------------
- */
-static unifi_priv_t *
-register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev)
-{
-    unifi_priv_t *priv = NULL;
-    int r = -1;
-    CsrResult csrResult;
-
-    if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
-        unifi_error(priv, "register_unifi_sdio: invalid device %d\n",
-                bus_id);
-        return NULL;
-    }
-
-    down(&Unifi_instance_mutex);
-
-    if (In_use[bus_id] != UNIFI_DEV_NOT_IN_USE) {
-        unifi_error(priv, "register_unifi_sdio: device %d is already in use\n",
-                bus_id);
-        goto failed0;
-    }
-
-
-    /* Allocate device private and net_device structs */
-    priv = uf_alloc_netdevice(sdio_dev, bus_id);
-    if (priv == NULL) {
-        unifi_error(priv, "Failed to allocate driver private\n");
-        goto failed0;
-    }
-
-    priv->unifi_device = dev;
-
-    SET_NETDEV_DEV(priv->netdev[0], dev);
-
-    /* We are not ready to send data yet. */
-    netif_carrier_off(priv->netdev[0]);
-
-    /* Allocate driver context. */
-    priv->card = unifi_alloc_card(priv->sdio, priv);
-    if (priv->card == NULL) {
-        unifi_error(priv, "Failed to allocate UniFi driver card struct.\n");
-        goto failed1;
-    }
-
-    if (Unifi_instances[bus_id]) {
-        unifi_error(priv, "Internal error: instance for slot %d is already taken\n",
-                bus_id);
-    }
-    Unifi_instances[bus_id] = priv;
-    In_use[bus_id] = UNIFI_DEV_IN_USE;
-
-    /* Save the netdev_priv for use by the netdev event callback mechanism */
-    Unifi_netdev_instances[bus_id * CSR_WIFI_NUM_INTERFACES] = netdev_priv(priv->netdev[0]);
-
-    /* Initialise the mini-coredump capture buffers */
-    csrResult = unifi_coredump_init(priv->card, (u16)coredump_max);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "Couldn't allocate mini-coredump buffers\n");
-    }
-
-    /* Create the character device nodes */
-    r = uf_create_device_nodes(priv, bus_id);
-    if (r) {
-        goto failed1;
-    }
-
-    /*
-     * We use the slot number as unifi device index.
-     */
-    scnprintf(priv->proc_entry_name, 64, "driver/unifi%d", priv->instance);
-    /*
-     * The following complex casting is in place in order to eliminate 64-bit compilation warning
-     * "cast to/from pointer from/to integer of different size"
-     */
-    if (!proc_create_data(priv->proc_entry_name, 0, NULL,
-			  &uf_proc_fops, (void *)(long)priv->instance))
-    {
-        unifi_error(priv, "unifi: can't create /proc/driver/unifi\n");
-    }
-
-    /* Allocate the net_device for interfaces other than 0. */
-    {
-        int i;
-        priv->totalInterfaceCount =0;
-
-        for(i=1;i<CSR_WIFI_NUM_INTERFACES;i++)
-        {
-            if( !uf_alloc_netdevice_for_other_interfaces(priv,i) )
-            {
-                /* error occured while allocating the net_device for interface[i]. The net_device are
-                 * allocated for the interfaces with id<i. Dont worry, all the allocated net_device will
-                 * be releasing chen the control goes to the label failed0.
-                 */
-                unifi_error(priv, "Failed to allocate driver private for interface[%d]\n",i);
-                goto failed0;
-            }
-            else
-            {
-                SET_NETDEV_DEV(priv->netdev[i], dev);
-
-                /* We are not ready to send data yet. */
-                netif_carrier_off(priv->netdev[i]);
-
-                /* Save the netdev_priv for use by the netdev event callback mechanism */
-                Unifi_netdev_instances[bus_id * CSR_WIFI_NUM_INTERFACES + i] = netdev_priv(priv->netdev[i]);
-            }
-        }
-
-        for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
-        {
-            netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
-            interfacePriv->netdev_registered=0;
-        }
-    }
-
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-    if (signal_buffer_init(priv, CSR_WIFI_RX_SIGNAL_BUFFER_SIZE))
-    {
-        unifi_error(priv,"Failed to allocate shared memory for T-H signals\n");
-        goto failed2;
-    }
-    priv->rx_workqueue = create_singlethread_workqueue("rx_workq");
-    if (priv->rx_workqueue == NULL) {
-        unifi_error(priv,"create_singlethread_workqueue failed \n");
-        goto failed3;
-    }
-    INIT_WORK(&priv->rx_work_struct, rx_wq_handler);
-#endif
-
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-    if (log_hip_signals)
-    {
-        uf_register_hip_offline_debug(priv);
-    }
-#endif
-
-    /* Initialise the SME related threads and parameters */
-    r = uf_sme_init(priv);
-    if (r) {
-        unifi_error(priv, "SME initialisation failed.\n");
-        goto failed4;
-    }
-
-    /*
-     * Run the userspace helper program (unififw) to perform
-     * the device initialisation.
-     */
-    unifi_trace(priv, UDBG1, "run UniFi helper app...\n");
-    r = uf_run_unifihelper(priv);
-    if (r) {
-        unifi_notice(priv, "unable to run UniFi helper app\n");
-        /* Not a fatal error. */
-    }
-
-    up(&Unifi_instance_mutex);
-
-    return priv;
-
-failed4:
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-if (log_hip_signals)
-{
-    uf_unregister_hip_offline_debug(priv);
-}
-#endif
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-    flush_workqueue(priv->rx_workqueue);
-    destroy_workqueue(priv->rx_workqueue);
-failed3:
-    signal_buffer_free(priv,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE);
-failed2:
-#endif
-    /* Remove the device nodes */
-    uf_destroy_device_nodes(priv);
-failed1:
-    /* Deregister priv->netdev_client */
-    ul_deregister_client(priv->netdev_client);
-
-failed0:
-    if (priv && priv->card) {
-        unifi_coredump_free(priv->card);
-        unifi_free_card(priv->card);
-    }
-    if (priv) {
-        uf_free_netdevice(priv);
-    }
-
-    up(&Unifi_instance_mutex);
-
-    return NULL;
-} /* register_unifi_sdio() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  ask_unifi_sdio_cleanup
- *
- *      We can not free our private context, until all the char device
- *      clients have closed the file handles. unregister_unifi_sdio() which
- *      is called when a card is removed, waits on Unifi_cleanup_wq until
- *      the reference count becomes zero. It is time to wake it up now.
- *
- *  Arguments:
- *      priv          Pointer to driver context.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void
-ask_unifi_sdio_cleanup(unifi_priv_t *priv)
-{
-
-    /*
-     * Now clear the flag that says the old instance is in use.
-     * This is used to prevent a new instance being started before old
-     * one has finshed closing down, for example if bounce makes the card
-     * appear to be ejected and re-inserted quickly.
-     */
-    In_use[priv->instance] = UNIFI_DEV_CLEANUP;
-
-    unifi_trace(NULL, UDBG5, "ask_unifi_sdio_cleanup: wake up cleanup workqueue.\n");
-    wake_up(&Unifi_cleanup_wq);
-
-} /* ask_unifi_sdio_cleanup() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  cleanup_unifi_sdio
- *
- *      Release any resources owned by a unifi instance.
- *
- *  Arguments:
- *      priv          Pointer to the instance to free.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void
-cleanup_unifi_sdio(unifi_priv_t *priv)
-{
-    int priv_instance;
-    int i;
-    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
-
-    /* Remove the device nodes */
-    uf_destroy_device_nodes(priv);
-
-    /* Mark this device as gone away by NULLing the entry in Unifi_instances */
-    Unifi_instances[priv->instance] = NULL;
-
-    unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: remove_proc_entry\n");
-    /*
-     * Free the children of priv before unifi_free_netdevice() frees
-     * the priv struct
-     */
-    remove_proc_entry(priv->proc_entry_name, 0);
-
-
-    /* Unregister netdev as a client. */
-    if (priv->netdev_client) {
-        unifi_trace(priv, UDBG2, "Netdev client (id:%d s:0x%X) is unregistered\n",
-                priv->netdev_client->client_id, priv->netdev_client->sender_id);
-        ul_deregister_client(priv->netdev_client);
-    }
-
-    /* Destroy the SME related threads and parameters */
-    uf_sme_deinit(priv);
-
-#ifdef CSR_SME_USERSPACE
-    priv->smepriv = NULL;
-#endif
-
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-    if (log_hip_signals)
-    {
-        uf_unregister_hip_offline_debug(priv);
-    }
-#endif
-
-    /* Free any packets left in the Rx queues */
-    for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
-    {
-        uf_free_pending_rx_packets(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address,i);
-        uf_free_pending_rx_packets(priv, UF_CONTROLLED_PORT_Q, broadcast_address,i);
-    }
-    /*
-     * We need to free the resources held by the core, which include tx skbs,
-     * otherwise we can not call unregister_netdev().
-     */
-    if (priv->card) {
-        unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: free card\n");
-        unifi_coredump_free(priv->card);
-        unifi_free_card(priv->card);
-        priv->card = NULL;
-    }
-
-    /*
-     * Unregister the network device.
-     * We can not unregister the netdev before we release
-     * all pending packets in the core.
-     */
-    uf_unregister_netdev(priv);
-    priv->totalInterfaceCount = 0;
-
-    /* Clear the table of registered netdev_priv's */
-    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
-        Unifi_netdev_instances[priv->instance * CSR_WIFI_NUM_INTERFACES + i] = NULL;
-    }
-
-    unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: uf_free_netdevice\n");
-    /*
-     * When uf_free_netdevice() returns, the priv is invalid
-     * so we need to remember the instance to clear the global flag later.
-     */
-    priv_instance = priv->instance;
-
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-    flush_workqueue(priv->rx_workqueue);
-    destroy_workqueue(priv->rx_workqueue);
-    signal_buffer_free(priv,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE);
-#endif
-
-    /* Priv is freed as part of the net_device */
-    uf_free_netdevice(priv);
-
-    /*
-     * Now clear the flag that says the old instance is in use.
-     * This is used to prevent a new instance being started before old
-     * one has finshed closing down, for example if bounce makes the card
-     * appear to be ejected and re-inserted quickly.
-     */
-    In_use[priv_instance] = UNIFI_DEV_NOT_IN_USE;
-
-    unifi_trace(NULL, UDBG5, "cleanup_unifi_sdio: DONE.\n");
-
-} /* cleanup_unifi_sdio() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unregister_unifi_sdio
- *
- *      Call from SDIO driver when it detects that UniFi has been removed.
- *
- *  Arguments:
- *      bus_id          Number of the card that was ejected.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void
-unregister_unifi_sdio(int bus_id)
-{
-    unifi_priv_t *priv;
-    int interfaceTag=0;
-    u8 reason = CONFIG_IND_EXIT;
-
-    if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
-        unifi_error(NULL, "unregister_unifi_sdio: invalid device %d\n",
-                bus_id);
-        return;
-    }
-
-    priv = Unifi_instances[bus_id];
-    if (priv == NULL) {
-        unifi_error(priv, "unregister_unifi_sdio: device %d is not registered\n",
-                bus_id);
-        return;
-    }
-
-    /* Stop the network traffic before freeing the core. */
-    for(interfaceTag=0;interfaceTag<priv->totalInterfaceCount;interfaceTag++)
-    {
-        netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-        if(interfacePriv->netdev_registered)
-        {
-            netif_carrier_off(priv->netdev[interfaceTag]);
-            netif_tx_stop_all_queues(priv->netdev[interfaceTag]);
-        }
-    }
-
-#ifdef CSR_NATIVE_LINUX
-    /*
-     * If the unifi thread was started, signal it to stop.  This
-     * should cause any userspace processes with open unifi device to
-     * close them.
-     */
-    uf_stop_thread(priv, &priv->bh_thread);
-
-    /* Unregister the interrupt handler */
-    if (csr_sdio_linux_remove_irq(priv->sdio)) {
-        unifi_notice(priv,
-                "csr_sdio_linux_remove_irq failed to talk to card.\n");
-    }
-
-    /* Ensure no MLME functions are waiting on a the mlme_event semaphore. */
-    uf_abort_mlme(priv);
-#endif /* CSR_NATIVE_LINUX */
-
-    ul_log_config_ind(priv, &reason, sizeof(u8));
-
-    /* Deregister the UDI hook from the core. */
-    unifi_remove_udi_hook(priv->card, logging_handler);
-
-    uf_put_instance(bus_id);
-
-    /*
-     * Wait until the device is cleaned up. i.e., when all userspace
-     * processes have closed any open unifi devices.
-     */
-    wait_event(Unifi_cleanup_wq, In_use[bus_id] == UNIFI_DEV_CLEANUP);
-    unifi_trace(NULL, UDBG5, "Received clean up event\n");
-
-    /* Now we can free the private context and the char device nodes */
-    cleanup_unifi_sdio(priv);
-
-} /* unregister_unifi_sdio() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_find_instance
- *
- *      Find the context structure for a given UniFi device instance.
- *
- *  Arguments:
- *      inst            The instance number to look for.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-unifi_priv_t *
-uf_find_instance(int inst)
-{
-    if ((inst < 0) || (inst >= MAX_UNIFI_DEVS)) {
-        return NULL;
-    }
-    return Unifi_instances[inst];
-} /* uf_find_instance() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_find_priv
- *
- *      Find the device instance for a given context structure.
- *
- *  Arguments:
- *      priv            The context structure pointer to look for.
- *
- *  Returns:
- *      index of instance, -1 otherwise.
- * ---------------------------------------------------------------------------
- */
-int
-uf_find_priv(unifi_priv_t *priv)
-{
-    int inst;
-
-    if (!priv) {
-        return -1;
-    }
-
-    for (inst = 0; inst < MAX_UNIFI_DEVS; inst++) {
-        if (Unifi_instances[inst] == priv) {
-            return inst;
-        }
-    }
-
-    return -1;
-} /* uf_find_priv() */
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_find_netdev_priv
- *
- *      Find the device instance for a given netdev context structure.
- *
- *  Arguments:
- *      priv            The context structure pointer to look for.
- *
- *  Returns:
- *      index of instance, -1 otherwise.
- * ---------------------------------------------------------------------------
- */
-int
-uf_find_netdev_priv(netInterface_priv_t *priv)
-{
-    int inst;
-
-    if (!priv) {
-        return -1;
-    }
-
-    for (inst = 0; inst < MAX_UNIFI_DEVS * CSR_WIFI_NUM_INTERFACES; inst++) {
-        if (Unifi_netdev_instances[inst] == priv) {
-            return inst;
-        }
-    }
-
-    return -1;
-} /* uf_find_netdev_priv() */
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_get_instance
- *
- *      Find the context structure for a given UniFi device instance
- *      and increment the reference count.
- *
- *  Arguments:
- *      inst            The instance number to look for.
- *
- *  Returns:
- *      Pointer to the instance or NULL if no instance exists.
- * ---------------------------------------------------------------------------
- */
-unifi_priv_t *
-uf_get_instance(int inst)
-{
-    unifi_priv_t *priv;
-
-    down(&Unifi_instance_mutex);
-
-    priv = uf_find_instance(inst);
-    if (priv) {
-        priv->ref_count++;
-    }
-
-    up(&Unifi_instance_mutex);
-
-    return priv;
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_put_instance
- *
- *      Decrement the context reference count, freeing resources and
- *      shutting down the driver when the count reaches zero.
- *
- *  Arguments:
- *      inst            The instance number to look for.
- *
- *  Returns:
- *      Pointer to the instance or NULL if no instance exists.
- * ---------------------------------------------------------------------------
- */
-void
-uf_put_instance(int inst)
-{
-    unifi_priv_t *priv;
-
-    down(&Unifi_instance_mutex);
-
-    priv = uf_find_instance(inst);
-    if (priv) {
-        priv->ref_count--;
-        if (priv->ref_count == 0) {
-            ask_unifi_sdio_cleanup(priv);
-        }
-    }
-
-    up(&Unifi_instance_mutex);
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_proc_show
- *
- *      Read method for driver node in /proc/driver/unifi0
- *
- *  Arguments:
- *      page
- *      start
- *      offset
- *      count
- *      eof
- *      data
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-#ifdef CONFIG_PROC_FS
-static int uf_proc_show(struct seq_file *m, void *v)
-{
-	unifi_priv_t *priv;
-	int i;
-
-	/*
-	 * The following complex casting is in place in order to eliminate
-	 * 64-bit compilation warning "cast to/from pointer from/to integer of
-	 * different size"
-	 */
-	priv = uf_find_instance((long)m->private);
-	if (!priv)
-		return 0;
-
-	seq_printf(m, "UniFi SDIO Driver: %s %s %s\n",
-		   CSR_WIFI_VERSION, __DATE__, __TIME__);
-#ifdef CSR_SME_USERSPACE
-	seq_puts(m, "SME: CSR userspace ");
-#ifdef CSR_SUPPORT_WEXT
-	seq_puts(m, "with WEXT support\n");
-#else
-	seq_putc(m, '\n');
-#endif /* CSR_SUPPORT_WEXT */
-#endif /* CSR_SME_USERSPACE */
-#ifdef CSR_NATIVE_LINUX
-	seq_puts(m, "SME: native\n");
-#endif
-
-#ifdef CSR_SUPPORT_SME
-	seq_printf(m, "Firmware (ROM) build:%u, Patch:%u\n",
-		   priv->card_info.fw_build,
-		   priv->sme_versions.firmwarePatch);
-#endif
-
-	unifi_print_status(priv->card, m);
-
-	seq_printf(m, "Last dbg str: %s\n", priv->last_debug_string);
-
-	seq_puts(m, "Last dbg16:");
-	for (i = 0; i < 8; i++)
-		seq_printf(m, " %04X", priv->last_debug_word16[i]);
-	seq_putc(m, '\n');
-	seq_puts(m, "           ");
-	for (; i < 16; i++)
-		seq_printf(m, " %04X", priv->last_debug_word16[i]);
-	seq_putc(m, '\n');
-	return 0;
-}
-#endif
-
-
-
-
-static void
-uf_lx_suspend(CsrSdioFunction *sdio_ctx)
-{
-    unifi_priv_t *priv = sdio_ctx->driverData;
-    unifi_suspend(priv);
-
-    CsrSdioSuspendAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS);
-}
-
-static void
-uf_lx_resume(CsrSdioFunction *sdio_ctx)
-{
-    unifi_priv_t *priv = sdio_ctx->driverData;
-    unifi_resume(priv);
-
-    CsrSdioResumeAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS);
-}
-
-static int active_slot = MAX_UNIFI_DEVS;
-static struct device *os_devices[MAX_UNIFI_DEVS];
-
-void
-uf_add_os_device(int bus_id, struct device *os_device)
-{
-    if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
-        unifi_error(NULL, "uf_add_os_device: invalid device %d\n",
-                bus_id);
-        return;
-    }
-
-    active_slot = bus_id;
-    os_devices[bus_id] = os_device;
-} /* uf_add_os_device() */
-
-void
-uf_remove_os_device(int bus_id)
-{
-    if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
-        unifi_error(NULL, "uf_remove_os_device: invalid device %d\n",
-                bus_id);
-        return;
-    }
-
-    active_slot = bus_id;
-    os_devices[bus_id] = NULL;
-} /* uf_remove_os_device() */
-
-static void
-uf_sdio_inserted(CsrSdioFunction *sdio_ctx)
-{
-	unifi_priv_t *priv;
-
-	unifi_trace(NULL, UDBG5, "uf_sdio_inserted(0x%p), slot_id=%d, dev=%p\n",
-		      sdio_ctx, active_slot, os_devices[active_slot]);
-
-	priv = register_unifi_sdio(sdio_ctx, active_slot, os_devices[active_slot]);
-	if (priv == NULL) {
-		CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_FAILURE);
-		return;
-	}
-
-	sdio_ctx->driverData = priv;
-
-	CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS);
-} /* uf_sdio_inserted() */
-
-
-static void
-uf_sdio_removed(CsrSdioFunction *sdio_ctx)
-{
-	unregister_unifi_sdio(active_slot);
-	CsrSdioRemovedAcknowledge(sdio_ctx);
-} /* uf_sdio_removed() */
-
-
-static void
-uf_sdio_dsr_handler(CsrSdioFunction *sdio_ctx)
-{
-	unifi_priv_t *priv = sdio_ctx->driverData;
-
-	unifi_sdio_interrupt_handler(priv->card);
-} /* uf_sdio_dsr_handler() */
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_sdio_int_handler
- *
- *      Interrupt callback function for SDIO interrupts.
- *      This is called in kernel context (i.e. not interrupt context).
- *      We retrieve the unifi context pointer and call the main UniFi
- *      interrupt handler.
- *
- *  Arguments:
- *      fdev      SDIO context pointer
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static CsrSdioInterruptDsrCallback
-uf_sdio_int_handler(CsrSdioFunction *sdio_ctx)
-{
-	return uf_sdio_dsr_handler;
-} /* uf_sdio_int_handler() */
-
-
-
-
-static CsrSdioFunctionId unifi_ids[] =
-{
-	{
-		.manfId = SDIO_MANF_ID_CSR,
-		.cardId = SDIO_CARD_ID_UNIFI_3,
-		.sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_3,
-		.sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE,
-	},
-	{
-		.manfId = SDIO_MANF_ID_CSR,
-		.cardId = SDIO_CARD_ID_UNIFI_4,
-		.sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_4,
-		.sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE,
-	}
-};
-
-
-/*
- * Structure to register with the glue layer.
- */
-static CsrSdioFunctionDriver unifi_sdioFunction_drv =
-{
-	.inserted = uf_sdio_inserted,
-	.removed = uf_sdio_removed,
-	.intr = uf_sdio_int_handler,
-	.suspend = uf_lx_suspend,
-	.resume = uf_lx_resume,
-
-	.ids = unifi_ids,
-	.idsCount = sizeof(unifi_ids) / sizeof(unifi_ids[0])
-};
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_sdio_load
- *  uf_sdio_unload
- *
- *      These functions are called from the main module load and unload
- *      functions. They perform the appropriate operations for the monolithic
- *      driver.
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-int __init
-uf_sdio_load(void)
-{
-	CsrResult csrResult;
-
-	csrResult = CsrSdioFunctionDriverRegister(&unifi_sdioFunction_drv);
-	if (csrResult != CSR_RESULT_SUCCESS) {
-		unifi_error(NULL, "Failed to register UniFi SDIO driver: csrResult=%d\n", csrResult);
-		return -EIO;
-	}
-
-	return 0;
-} /* uf_sdio_load() */
-
-
-
-void __exit
-uf_sdio_unload(void)
-{
-	CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv);
-} /* uf_sdio_unload() */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/csr/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/csr/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-config CSR_WIFI
-	tristate "CSR wireless driver"
-	depends on MMC && CFG80211_WEXT && INET
-	select WIRELESS_EXT
-	select WEXT_PRIV
-	help
-	  Driver for the CSR wireless SDIO device.
-
-	  If unsure, select N.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/LICENSE.txt linux-libre-3.11-rc7-gnu/drivers/staging/csr/LICENSE.txt
--- linux-libre-3.10-gnu/drivers/staging/csr/LICENSE.txt	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/LICENSE.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-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.
-
-Except as contained in this notice, the names of above-listed
-copyright holders and the names of any contributors shall not be used
-in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization.
-
-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 COPYRIGHT HOLDERS OR
-CONTRIBUTORS 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.
-
-Alternatively, this software may be distributed under the terms of the
-GNU General Public License ("GPL") version 2 as published
-by the Free Software Foundation.
-
-As a special exception, if other files instantiate templates or use
-macros or inline functions from this file, or you compile this file
-and link it with other works to produce a work based on this file,
-this file does not by itself cause the resulting work to be covered by
-the GNU General Public License. However the source code for this file
-must still be made available in accordance with section (3) of the GNU
-General Public License.
-
-This exception does not invalidate any other reasons why a work based
-on this file might be covered by the GNU General Public License.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/csr/Makefile
--- linux-libre-3.10-gnu/drivers/staging/csr/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-ccflags-y	:= -DCSR_SME_USERSPACE -DCSR_SUPPORT_SME -DREMOTE_SYS_SAP -DCSR_WIFI_SECURITY_WAPI_ENABLE -DENABLE_SHUTDOWN -DUNIFI_DEBUG
-ccflags-y	+= -DSDIO_EXPORTS_STRUCT_DEVICE -DCSR_WIFI_SUPPORT_MMC_DRIVER -DCSR_WIFI_SINGLE_FUNCTION -DCSR_WIFI_SPLIT_PATCH
-ccflags-y	+= -DCSR_SUPPORT_WEXT -DREMOTE_SYS_SAP  -DREMOTE_MGT_SAP -DCSR_WIFI_SECURITY_WAPI_ENABLE -DCSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND -DENABLE_SHUTDOWN -DCSR_WIFI_NME_ENABLE -DCSR_WIFI_AP_ENABLE -DCSR_SUPPORT_WEXT_AP -DCSR_WIFI_REQUEUE_PACKET_TO_HAL
-
-obj-$(CONFIG_CSR_WIFI)	+= csr_wifi.o
-obj-$(CONFIG_CSR_WIFI)	+= csr_helper.o
-
-csr_wifi-y :=	bh.o				\
-		data_tx.o			\
-		drv.o				\
-		firmware.o			\
-		inet.o				\
-		init_hw.o			\
-		io.o				\
-		monitor.o			\
-		netdev.o			\
-		os.o				\
-		putest.o			\
-		sdio_events.o			\
-		sdio_mmc.o			\
-		sdio_stubs.o			\
-		sme_blocking.o			\
-		ul_int.o			\
-		unifi_dbg.o			\
-		unifi_event.o			\
-		unifi_pdu_processing.o		\
-		unifi_sme.o			\
-		csr_wifi_hip_card_sdio.o	\
-		csr_wifi_hip_card_sdio_intr.o	\
-		csr_wifi_hip_card_sdio_mem.o	\
-		csr_wifi_hip_chiphelper.o	\
-		csr_wifi_hip_download.o		\
-		csr_wifi_hip_dump.o		\
-		csr_wifi_hip_packing.o		\
-		csr_wifi_hip_send.o		\
-		csr_wifi_hip_signals.o		\
-		csr_wifi_hip_ta_sampling.o	\
-		csr_wifi_hip_udi.o		\
-		csr_wifi_hip_unifi_signal_names.o	\
-		csr_wifi_hip_xbv.o		\
-		csr_wifi_nme_ap_converter_init.o		\
-		csr_wifi_nme_ap_free_downstream_contents.o	\
-		csr_wifi_nme_ap_free_upstream_contents.o	\
-		csr_wifi_nme_ap_serialize.o	\
-		csr_wifi_nme_ap_sef.o		\
-		csr_wifi_router_ctrl_sef.o	\
-		csr_wifi_router_sef.o		\
-		csr_wifi_router_transport.o	\
-		csr_wifi_sme_sef.o		\
-		csr_wifi_sme_converter_init.o	\
-		csr_wifi_sme_free_downstream_contents.o		\
-		csr_wifi_sme_free_upstream_contents.o		\
-		csr_wifi_sme_serialize.o			\
-		csr_wifi_router_ctrl_converter_init.o		\
-		csr_wifi_router_ctrl_free_downstream_contents.o	\
-		csr_wifi_router_ctrl_free_upstream_contents.o	\
-		csr_wifi_router_ctrl_serialize.o		\
-		csr_wifi_router_converter_init.o		\
-		csr_wifi_router_free_downstream_contents.o	\
-		csr_wifi_router_free_upstream_contents.o	\
-		csr_wifi_router_serialize.o			\
-		sme_mgt.o			\
-		sme_sys.o			\
-		sme_userspace.o 		\
-		sme_wext.o			\
-		wext_events.o
-
-csr_helper-y :=	csr_time.o			\
-		csr_util.o			\
-		csr_framework_ext.o		\
-		csr_wifi_serialize_primitive_types.o	\
-		csr_serialize_primitive_types.o	\
-		csr_msgconv.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/mlme.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/mlme.c
--- linux-libre-3.10-gnu/drivers/staging/csr/mlme.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/mlme.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,433 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     mlme.c
- *
- * PURPOSE:
- *      This file provides functions to send MLME requests to the UniFi.
- *
- * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include "csr_wifi_hip_unifi.h"
-#include "unifi_priv.h"
-
-/*
- * ---------------------------------------------------------------------------
- * unifi_mlme_wait_for_reply
- *
- *      Wait for a reply after sending a signal.
- *
- * Arguments:
- *      priv            Pointer to device private context struct
- *      ul_client       Pointer to linux client
- *      sig_reply_id    ID of the expected reply (defined in sigs.h).
- *      timeout         timeout in ms
- *
- * Returns:
- *      0 on success, -ve POSIX code on error.
- *
- * Notes:
- *      This function waits for a specific (sig_reply_id) signal from UniFi.
- *      It also match the sequence number of the received (cfm) signal, with
- *      the latest sequence number of the signal (req) we have sent.
- *      These two number match be equal.
- *      Should only be used for waiting xxx.cfm signals and only after
- *      we have sent the matching xxx.req signal to UniFi.
- *      If no response is received within the expected time (timeout), we assume
- *      that the UniFi is busy and return an error.
- *      If the wait is aborted by a kernel signal arriving, we stop waiting.
- *      If a response from UniFi is not what we expected, we discard it and
- *      wait again. This could be a response from an aborted request. If we
- *      see several bad responses we assume we have lost synchronisation with
- *      UniFi.
- * ---------------------------------------------------------------------------
- */
-static int
-unifi_mlme_wait_for_reply(unifi_priv_t *priv, ul_client_t *pcli, int sig_reply_id, int timeout)
-{
-    int retries = 0;
-    long r;
-    long t = timeout;
-    unsigned int sent_seq_no;
-
-    /* Convert t in ms to jiffies */
-    t = msecs_to_jiffies(t);
-
-    do {
-        /* Wait for the confirm or timeout. */
-        r = wait_event_interruptible_timeout(pcli->udi_wq,
-                                             (pcli->wake_up_wq_id) || (priv->io_aborted == 1),
-                                             t);
-        /* Check for general i/o error */
-        if (priv->io_aborted) {
-            unifi_error(priv, "MLME operation aborted\n");
-            return -EIO;
-        }
-
-        /*
-         * If r=0 the request has timed-out.
-         * If r>0 the request has completed successfully.
-         * If r=-ERESTARTSYS an event (kill signal) has interrupted the wait_event.
-         */
-        if ((r == 0) && (pcli->wake_up_wq_id == 0)) {
-            unifi_error(priv, "mlme_wait: timed-out waiting for 0x%.4X, after %lu msec.\n",
-                        sig_reply_id,  jiffies_to_msecs(t));
-            pcli->wake_up_wq_id = 0;
-            return -ETIMEDOUT;
-        } else if (r == -ERESTARTSYS) {
-            unifi_error(priv, "mlme_wait: waiting for 0x%.4X was aborted.\n", sig_reply_id);
-            pcli->wake_up_wq_id = 0;
-            return -EINTR;
-        } else {
-            /* Get the sequence number of the signal that we previously set. */
-            if (pcli->seq_no != 0) {
-                sent_seq_no = pcli->seq_no - 1;
-            } else {
-                sent_seq_no = 0x0F;
-            }
-
-            unifi_trace(priv, UDBG5, "Received 0x%.4X, seq: (r:%d, s:%d)\n",
-                        pcli->wake_up_wq_id,
-                        pcli->wake_seq_no, sent_seq_no);
-
-            /* The two sequence ids must match. */
-            if (pcli->wake_seq_no == sent_seq_no) {
-                /* and the signal ids must match. */
-                if (sig_reply_id == pcli->wake_up_wq_id) {
-                    /* Found the expected signal */
-                    break;
-                } else {
-                    /* This should never happen ... */
-                    unifi_error(priv, "mlme_wait: mismatching signal id (0x%.4X - exp 0x%.4X) (seq %d)\n",
-                                pcli->wake_up_wq_id,
-                                sig_reply_id,
-                                pcli->wake_seq_no);
-                    pcli->wake_up_wq_id = 0;
-                    return -EIO;
-                }
-            }
-            /* Wait for the next signal. */
-            pcli->wake_up_wq_id = 0;
-
-            retries ++;
-            if (retries >= 3) {
-                unifi_error(priv, "mlme_wait: confirm wait retries exhausted (0x%.4X - exp 0x%.4X)\n",
-                            pcli->wake_up_wq_id,
-                            sig_reply_id);
-                pcli->wake_up_wq_id = 0;
-                return -EIO;
-            }
-        }
-    } while (1);
-
-    pcli->wake_up_wq_id = 0;
-
-    return 0;
-} /* unifi_mlme_wait_for_reply() */
-
-
-/*
- * ---------------------------------------------------------------------------
- * unifi_mlme_blocking_request
- *
- *      Send a MLME request signal to UniFi.
- *
- * Arguments:
- *      priv            Pointer to device private context struct
- *      pcli            Pointer to context of calling process
- *      sig             Pointer to the signal to send
- *      data_ptrs       Pointer to the bulk data of the signal
- *      timeout         The request's timeout.
- *
- * Returns:
- *      0 on success, 802.11 result code on error.
- * ---------------------------------------------------------------------------
- */
-int
-unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli,
-                            CSR_SIGNAL *sig, bulk_data_param_t *data_ptrs,
-                            int timeout)
-{
-    int r;
-
-    if (sig->SignalPrimitiveHeader.SignalId == 0) {
-        unifi_error(priv, "unifi_mlme_blocking_request: Invalid Signal Id (0x%x)\n",
-                    sig->SignalPrimitiveHeader.SignalId);
-        return -EINVAL;
-    }
-
-    down(&priv->mlme_blocking_mutex);
-
-    sig->SignalPrimitiveHeader.ReceiverProcessId = 0;
-    sig->SignalPrimitiveHeader.SenderProcessId = pcli->sender_id | pcli->seq_no;
-
-    unifi_trace(priv, UDBG2, "Send client=%d, S:0x%04X, sig 0x%.4X\n",
-                pcli->client_id,
-                sig->SignalPrimitiveHeader.SenderProcessId,
-                sig->SignalPrimitiveHeader.SignalId);
-    /* Send the signal to UniFi */
-    r = ul_send_signal_unpacked(priv, sig, data_ptrs);
-    if (r) {
-        up(&priv->mlme_blocking_mutex);
-        unifi_error(priv, "Error queueing MLME REQUEST signal\n");
-        return r;
-    }
-
-    unifi_trace(priv, UDBG5, "Send 0x%.4X, seq = %d\n",
-                sig->SignalPrimitiveHeader.SignalId, pcli->seq_no);
-
-    /*
-     * Advance the sequence number of the last sent signal, only
-     * if the signal has been successfully set.
-     */
-    pcli->seq_no++;
-    if (pcli->seq_no > 0x0F) {
-        pcli->seq_no = 0;
-    }
-
-    r = unifi_mlme_wait_for_reply(priv, pcli, (sig->SignalPrimitiveHeader.SignalId + 1), timeout);
-    up(&priv->mlme_blocking_mutex);
-
-    if (r) {
-        unifi_error(priv, "Error waiting for MLME CONFIRM signal\n");
-        return r;
-    }
-
-    return 0;
-} /* unifi_mlme_blocking_request() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_mlme_copy_reply_and_wakeup_client
- *
- *      Copy the reply signal from UniFi to the client's structure
- *      and wake up the waiting client.
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-unifi_mlme_copy_reply_and_wakeup_client(ul_client_t *pcli,
-                                        CSR_SIGNAL *signal, int signal_len,
-                                        const bulk_data_param_t *bulkdata)
-{
-    int i;
-
-    /* Copy the signal to the reply */
-    memcpy(pcli->reply_signal, signal, signal_len);
-
-    /* Get the sequence number of the signal that woke us up. */
-    pcli->wake_seq_no = pcli->reply_signal->SignalPrimitiveHeader.ReceiverProcessId & 0x0F;
-
-    /* Append any bulk data */
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
-        if (bulkdata->d[i].data_length > 0) {
-            if (bulkdata->d[i].os_data_ptr) {
-                memcpy(pcli->reply_bulkdata[i]->ptr, bulkdata->d[i].os_data_ptr, bulkdata->d[i].data_length);
-                pcli->reply_bulkdata[i]->length = bulkdata->d[i].data_length;
-            } else {
-                pcli->reply_bulkdata[i]->length = 0;
-            }
-        }
-    }
-
-    /* Wake the requesting MLME function. */
-    pcli->wake_up_wq_id = pcli->reply_signal->SignalPrimitiveHeader.SignalId;
-    wake_up_interruptible(&pcli->udi_wq);
-
-} /* unifi_mlme_copy_reply_and_wakeup_client() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_abort_mlme
- *
- *      Abort any MLME operation in progress.
- *      This is used in the error recovery mechanism.
- *
- *  Arguments:
- *      priv          Pointer to driver context.
- *
- *  Returns:
- *      0 on success.
- * ---------------------------------------------------------------------------
- */
-int
-uf_abort_mlme(unifi_priv_t *priv)
-{
-    ul_client_t *ul_cli;
-
-    /* Ensure no MLME functions are waiting on a the mlme_event semaphore. */
-    priv->io_aborted = 1;
-
-    ul_cli = priv->netdev_client;
-    if (ul_cli) {
-        wake_up_interruptible(&ul_cli->udi_wq);
-    }
-
-    ul_cli = priv->wext_client;
-    if (ul_cli) {
-        wake_up_interruptible(&ul_cli->udi_wq);
-    }
-
-    return 0;
-} /* uf_abort_mlme() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *
- *      Human-readable decoding of Reason and Result codes.
- *
- * ---------------------------------------------------------------------------
- */
-
-struct mlme_code {
-    const char *name;
-    int id;
-};
-
-static const struct mlme_code Result_codes[] = {
-    { "Success",                             0x0000 },
-    { "Unspecified Failure",                 0x0001 },
-    /* (Reserved)                      0x0002 - 0x0009 */
-    { "Refused Capabilities Mismatch",       0x000A },
-    /* (Reserved)                          0x000B */
-    { "Refused External Reason",             0x000C },
-    /* (Reserved)                      0x000D - 0x0010 */
-    { "Refused AP Out Of Memory",            0x0011 },
-    { "Refused Basic Rates Mismatch",        0x0012 },
-    /* (Reserved)                      0x0013 - 0x001F */
-    { "Failure",                             0x0020 },
-    /* (Reserved)                      0x0021 - 0x0024 */
-    { "Refused Reason Unspecified",          0x0025 },
-    { "Invalid Parameters",                  0x0026 },
-    { "Rejected With Suggested Changes",     0x0027 },
-    /* (Reserved)                      0x0028 - 0x002E */
-    { "Rejected For Delay Period",           0x002F },
-    { "Not Allowed",                         0x0030 },
-    { "Not Present",                         0x0031 },
-    { "Not QSTA",                            0x0032 },
-    /* (Reserved)                      0x0033 - 0x7FFF */
-    { "Timeout",                             0x8000 },
-    { "Too Many Simultaneous Requests",      0x8001 },
-    { "BSS Already Started Or Joined",       0x8002 },
-    { "Not Supported",                       0x8003 },
-    { "Transmission Failure",                0x8004 },
-    { "Refused Not Authenticated",           0x8005 },
-    { "Reset Required Before Start",         0x8006 },
-    { "LM Info Unavailable",                 0x8007 },
-    { NULL, -1 }
-};
-
-static const struct mlme_code Reason_codes[] = {
-    /* (Reserved)                      0x0000 */
-    { "Unspecified Reason",              0x0001 },
-    { "Authentication Not Valid",        0x0002 },
-    { "Deauthenticated Leave BSS",       0x0003 },
-    { "Disassociated Inactivity",        0x0004 },
-    { "AP Overload",                     0x0005 },
-    { "Class2 Frame Error",              0x0006 },
-    { "Class3 Frame Error",              0x0007 },
-    { "Disassociated Leave BSS",         0x0008 },
-    { "Association Not Authenticated",   0x0009 },
-    { "Disassociated Power Capability",  0x000A },
-    { "Disassociated Supported Channels", 0x000B },
-    /* (Reserved)                      0x000C */
-    { "Invalid Information Element",     0x000D },
-    { "Michael MIC Failure",             0x000E },
-    { "Fourway Handshake Timeout",       0x000F },
-    { "Group Key Update Timeout",        0x0010 },
-    { "Handshake Element Different",     0x0011 },
-    { "Invalid Group Cipher",            0x0012 },
-    { "Invalid Pairwise Cipher",         0x0013 },
-    { "Invalid AKMP",                    0x0014 },
-    { "Unsupported RSN IE Version",      0x0015 },
-    { "Invalid RSN IE Capabilities",     0x0016 },
-    { "Dot1X Auth Failed",               0x0017 },
-    { "Cipher Rejected By Policy",       0x0018 },
-    /* (Reserved)                  0x0019 - 0x001F */
-    { "QoS Unspecified Reason",          0x0020 },
-    { "QoS Insufficient Bandwidth",      0x0021 },
-    { "QoS Excessive Not Ack",           0x0022 },
-    { "QoS TXOP Limit Exceeded",         0x0023 },
-    { "QSTA Leaving",                    0x0024 },
-    { "End TS, End DLS, End BA",         0x0025 },
-    { "Unknown TS, Unknown DLS, Unknown BA", 0x0026 },
-    { "Timeout",                         0x0027 },
-    /* (Reserved)                  0x0028 - 0x002C */
-    { "STAKey Mismatch",                 0x002D },
-    { NULL, -1 }
-};
-
-
-static const char *
-lookup_something(const struct mlme_code *n, int id)
-{
-    for (; n->name; n++) {
-        if (n->id == id) {
-            return n->name;
-        }
-    }
-
-    /* not found */
-    return NULL;
-} /* lookup_something() */
-
-
-const char *
-lookup_result_code(int result)
-{
-    static char fallback[16];
-    const char *str;
-
-    str = lookup_something(Result_codes, result);
-
-    if (str == NULL) {
-        snprintf(fallback, 16, "%d", result);
-        str = fallback;
-    }
-
-    return str;
-} /* lookup_result_code() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  lookup_reason
- *
- *      Return a description string for a WiFi MLME ReasonCode.
- *
- *  Arguments:
- *      reason          The ReasonCode to interpret.
- *
- *  Returns:
- *      Pointer to description string.
- * ---------------------------------------------------------------------------
- */
-const char *
-lookup_reason_code(int reason)
-{
-    static char fallback[16];
-    const char *str;
-
-    str = lookup_something(Reason_codes, reason);
-
-    if (str == NULL) {
-        snprintf(fallback, 16, "%d", reason);
-        str = fallback;
-    }
-
-    return str;
-} /* lookup_reason_code() */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/monitor.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/monitor.c
--- linux-libre-3.10-gnu/drivers/staging/csr/monitor.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/monitor.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,384 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     monitor.c
- *
- * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-
-#include "unifi_priv.h"
-
-#ifdef UNIFI_SNIFF_ARPHRD
-
-
-#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_RADIOTAP)
-#include <net/ieee80211_radiotap.h>
-#endif
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW ETH_P_ALL
-#endif
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_start_sniff
- *
- *      Start UniFi capture in SNIFF mode, i.e capture everything it hears.
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *
- *  Returns:
- *      0 on success or kernel error code
- * ---------------------------------------------------------------------------
- */
-int
-uf_start_sniff(unifi_priv_t *priv)
-{
-    ul_client_t *pcli = priv->wext_client;
-    CSR_SIGNAL signal;
-    CSR_MLME_SNIFFJOIN_REQUEST *req = &signal.u.MlmeSniffjoinRequest;
-    int timeout = 1000;
-    int r;
-
-    req->Ifindex = priv->if_index;
-    req->Channel = priv->wext_conf.channel;
-    req->ChannelStartingFactor = 0;
-
-    signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SNIFFJOIN_REQUEST_ID;
-
-    r = unifi_mlme_blocking_request(priv, pcli, &signal, NULL, timeout);
-    if (r < 0) {
-        unifi_error(priv, "failed to send SNIFFJOIN request, error %d\n", r);
-        return r;
-    }
-
-    r = pcli->reply_signal->u.MlmeSniffjoinConfirm.Resultcode;
-    if (r) {
-        unifi_notice(priv, "SNIFFJOIN request was rejected with result 0x%X (%s)\n",
-                     r, lookup_result_code(r));
-        return -EIO;
-    }
-
-    return 0;
-} /* uf_start_sniff() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- * netrx_radiotap
- *
- *      Reformat a UniFi SNIFFDATA signal into a radiotap packet.
- *
- * Arguments:
- *      priv            OS private context pointer.
- *      ind             Pointer to a MA_UNITDATA_INDICATION or
- *                      DS_UNITDATA_INDICATION indication structure.
- *
- * Notes:
- *      Radiotap header values are all little-endian, UniFi signals will have
- *      been converted to host-endian.
- * ---------------------------------------------------------------------------
- */
-#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_RADIOTAP)
-static void
-netrx_radiotap(unifi_priv_t *priv,
-               const CSR_MA_SNIFFDATA_INDICATION *ind,
-               struct sk_buff *skb_orig)
-{
-    struct net_device *dev = priv->netdev;
-    struct sk_buff *skb = NULL;
-    unsigned char *ptr;
-    unsigned char *base;
-    int ind_data_len = skb_orig->len - 2 - ETH_HLEN;
-    struct unifi_rx_radiotap_header {
-        struct ieee80211_radiotap_header rt_hdr;
-        /* IEEE80211_RADIOTAP_TSFT */
-        u64 rt_tsft;
-        /* IEEE80211_RADIOTAP_FLAGS */
-        u8  rt_flags;
-        /* IEEE80211_RADIOTAP_RATE */
-        u8  rt_rate;
-        /* IEEE80211_RADIOTAP_CHANNEL */
-        u16 rt_chan;
-        u16 rt_chan_flags;
-        /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
-        u8  rt_dbm_antsignal;
-        /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
-        u8  rt_dbm_antnoise;
-        /* IEEE80211_RADIOTAP_ANTENNA */
-        u8  rt_antenna;
-
-        /* pad to 4-byte boundary */
-        u8 pad[3];
-    } __attribute__((__packed__));
-
-    struct unifi_rx_radiotap_header *unifi_rt;
-    int signal, noise, snr;
-
-    if (ind_data_len <= 0) {
-        unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n");
-        return;
-    }
-
-    /*
-     * Allocate a SKB for the received data packet, including radiotap
-     * header.
-     */
-    skb = dev_alloc_skb(ind_data_len + sizeof(struct unifi_rx_radiotap_header) + 4);
-    if (! skb) {
-        unifi_error(priv, "alloc_skb failed.\n");
-        priv->stats.rx_errors++;
-        return;
-    }
-
-    base = skb->data;
-
-    /* Reserve the radiotap header at the front of skb */
-    unifi_rt = (struct unifi_rx_radiotap_header *)
-        skb_put(skb, sizeof(struct unifi_rx_radiotap_header));
-
-    /* Copy in the 802.11 frame */
-    ptr = skb_put(skb, ind_data_len);
-    memcpy(ptr, skb_orig->data, ind_data_len);
-
-    unifi_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
-    unifi_rt->rt_hdr.it_pad = 0;	/* always good to zero */
-    unifi_rt->rt_hdr.it_len = sizeof(struct unifi_rx_radiotap_header);
-
-    /* Big bitfield of all the fields we provide in radiotap */
-    unifi_rt->rt_hdr.it_present = 0
-        | (1 << IEEE80211_RADIOTAP_TSFT)
-        | (1 << IEEE80211_RADIOTAP_FLAGS)
-        | (1 << IEEE80211_RADIOTAP_RATE)
-        | (1 << IEEE80211_RADIOTAP_CHANNEL)
-        | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)
-        | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)
-        | (1 << IEEE80211_RADIOTAP_ANTENNA)
-        ;
-
-
-    /* No flags to set */
-    unifi_rt->rt_tsft = (((u64)ind->Timestamp.x[7]) | (((u64)ind->Timestamp.x[6]) << 8) |
-                         (((u64)ind->Timestamp.x[5]) << 16) | (((u64)ind->Timestamp.x[4]) << 24) |
-                         (((u64)ind->Timestamp.x[3]) << 32) | (((u64)ind->Timestamp.x[2]) << 40) |
-                         (((u64)ind->Timestamp.x[1]) << 48) | (((u64)ind->Timestamp.x[0]) << 56));
-
-    unifi_rt->rt_flags = 0;
-
-    unifi_rt->rt_rate = ind->Rate;
-
-    unifi_rt->rt_chan = cpu_to_le16(ieee80211chan2mhz(priv->wext_conf.channel));
-    unifi_rt->rt_chan_flags = 0;
-
-    /* Convert signal to dBm */
-    signal = (s16)unifi2host_16(ind->Rssi);  /* in dBm */
-    snr    = (s16)unifi2host_16(ind->Snr);   /* in dB */
-    noise  = signal - snr;
-
-    unifi_rt->rt_dbm_antsignal = signal;
-    unifi_rt->rt_dbm_antnoise = noise;
-
-    unifi_rt->rt_antenna = ind->AntennaId;
-
-
-    skb->dev = dev;
-    skb->mac_header = skb->data;
-    skb->pkt_type = PACKET_OTHERHOST;
-    skb->protocol = __constant_htons(ETH_P_80211_RAW);
-    memset(skb->cb, 0, sizeof(skb->cb));
-
-    /* Pass up to Linux network stack */
-    netif_rx_ni(skb);
-
-    dev->last_rx = jiffies;
-
-    /* Bump the rx stats */
-    priv->stats.rx_packets++;
-    priv->stats.rx_bytes += ind_data_len;
-
-} /* netrx_radiotap() */
-#endif /* RADIOTAP */
-
-
-/*
- * ---------------------------------------------------------------------------
- * netrx_prism
- *
- *      Reformat a UniFi SNIFFDATA signal into a Prism format sniff packet.
- *
- * Arguments:
- *      priv            OS private context pointer.
- *      ind             Pointer to a MA_UNITDATA_INDICATION or
- *                      DS_UNITDATA_INDICATION indication structure.
- *
- * Notes:
- *      Radiotap header values are all little-endian, UniFi signals will have
- *      been converted to host-endian.
- * ---------------------------------------------------------------------------
- */
-#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_PRISM)
-static void
-netrx_prism(unifi_priv_t *priv,
-            const CSR_MA_SNIFFDATA_INDICATION *ind,
-            struct sk_buff *skb_orig)
-{
-    struct net_device *dev = priv->netdev;
-    struct sk_buff *skb = NULL;
-    unsigned char *ptr;
-    unsigned char *base;
-    int ind_data_len = skb_orig->len - 2 - ETH_HLEN;
-#define WLANCAP_MAGIC_COOKIE_V1 0x80211001
-    struct avs_header_v1 {
-        uint32  version;
-        uint32  length;
-        uint64  mactime;
-        uint64  hosttime;
-        uint32  phytype;
-        uint32  channel;
-        uint32  datarate;
-        uint32  antenna;
-        uint32  priority;
-        uint32  ssi_type;
-        int32   ssi_signal;
-        int32   ssi_noise;
-        uint32  preamble;
-        uint32  encoding;
-    } *avs;
-    int signal, noise, snr;
-
-    if (ind_data_len <= 0) {
-        unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n");
-        return;
-    }
-
-    /*
-     * Allocate a SKB for the received data packet, including radiotap
-     * header.
-     */
-    skb = dev_alloc_skb(ind_data_len + sizeof(struct avs_header_v1) + 4);
-    if (! skb) {
-        unifi_error(priv, "alloc_skb failed.\n");
-        priv->stats.rx_errors++;
-        return;
-    }
-
-    base = skb->data;
-
-    /* Reserve the radiotap header at the front of skb */
-    avs = (struct avs_header_v1 *)skb_put(skb, sizeof(struct avs_header_v1));
-
-    /* Copy in the 802.11 frame */
-    ptr = skb_put(skb, ind_data_len);
-    memcpy(ptr, skb_orig->data, ind_data_len);
-
-    /* Convert signal to dBm */
-    signal = 0x10000 - ((s16)unifi2host_16(ind->Rssi));  /* in dBm */
-    snr    = (s16)unifi2host_16(ind->Snr);   /* in dB */
-    noise  = signal - snr;
-
-    avs->version        = htonl(WLANCAP_MAGIC_COOKIE_V1);
-    avs->length         = htonl(sizeof(struct avs_header_v1));
-    avs->mactime        = __cpu_to_be64(ind->Timestamp);
-    avs->hosttime       = __cpu_to_be64(jiffies);
-    avs->phytype        = htonl(9);             /* dss_ofdm_dot11_g */
-    avs->channel        = htonl(priv->wext_conf.channel);
-    avs->datarate       = htonl(ind->Rate * 5);
-    avs->antenna        = htonl(ind->Antenna);
-    avs->priority       = htonl(0);             /* unknown */
-    avs->ssi_type       = htonl(2);             /* dBm */
-    avs->ssi_signal     = htonl(signal);
-    avs->ssi_noise      = htonl(noise);
-    avs->preamble       = htonl(0); /* unknown */
-    avs->encoding       = htonl(0); /* unknown */
-
-
-    skb->dev = dev;
-    skb->mac.raw = skb->data;
-    skb->pkt_type = PACKET_OTHERHOST;
-    skb->protocol = __constant_htons(ETH_P_80211_RAW);
-    memset(skb->cb, 0, sizeof(skb->cb));
-
-    /* Pass up to Linux network stack */
-    netif_rx_ni(skb);
-
-    dev->last_rx = jiffies;
-
-    /* Bump the rx stats */
-    priv->stats.rx_packets++;
-    priv->stats.rx_bytes += ind_data_len;
-
-} /* netrx_prism() */
-#endif /* PRISM */
-
-
-/*
- * ---------------------------------------------------------------------------
- * ma_sniffdata_ind
- *
- *      Reformat a UniFi SNIFFDATA signal into a network
- *
- * Arguments:
- *      ospriv          OS private context pointer.
- *      ind             Pointer to a MA_UNITDATA_INDICATION or
- *                      DS_UNITDATA_INDICATION indication structure.
- *      bulkdata        Pointer to a bulk data structure, describing
- *                      the data received.
- *
- * Notes:
- *      Radiotap header values are all little-endian, UniFi signals will have
- *      been converted to host-endian.
- * ---------------------------------------------------------------------------
- */
-void
-ma_sniffdata_ind(void *ospriv,
-                 const CSR_MA_SNIFFDATA_INDICATION *ind,
-                 const bulk_data_param_t *bulkdata)
-{
-    unifi_priv_t *priv = ospriv;
-    struct net_device *dev = priv->netdev;
-    struct sk_buff *skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
-
-    if (bulkdata->d[0].data_length == 0) {
-        unifi_warning(priv, "rx: MA-SNIFFDATA indication with zero bulk data\n");
-        return;
-    }
-
-    skb->len = bulkdata->d[0].data_length;
-
-    /* We only process data packets if the interface is open */
-    if (unlikely(!netif_running(dev))) {
-        priv->stats.rx_dropped++;
-        priv->wext_conf.wireless_stats.discard.misc++;
-        dev_kfree_skb(skb);
-        return;
-    }
-
-    if (ind->ReceptionStatus) {
-        priv->stats.rx_dropped++;
-        priv->wext_conf.wireless_stats.discard.misc++;
-        printk(KERN_INFO "unifi: Dropping corrupt sniff packet\n");
-        dev_kfree_skb(skb);
-        return;
-    }
-
-#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_PRISM)
-    netrx_prism(priv, ind, skb);
-#endif /* PRISM */
-
-#if (UNIFI_SNIFF_ARPHRD == ARPHRD_IEEE80211_RADIOTAP)
-    netrx_radiotap(priv, ind, skb);
-#endif /* RADIOTAP */
-
-    dev_kfree_skb(skb);
-
-} /* ma_sniffdata_ind() */
-
-
-#endif /* UNIFI_SNIFF_ARPHRD */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/netdev.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/netdev.c
--- linux-libre-3.10-gnu/drivers/staging/csr/netdev.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/netdev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,3307 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     netdev.c
- *
- * PURPOSE:
- *      This file provides the upper edge interface to the linux netdevice
- *      and wireless extensions.
- *      It is part of the porting exercise.
- *
- * Copyright (C) 2005-2010 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-
-/*
- * Porting Notes:
- * This file implements the data plane of the UniFi linux driver.
- *
- * All the Tx packets are passed to the HIP core lib, using the
- * unifi_send_signal() API. For EAPOL packets use the MLME-EAPOL.req
- * signal, for all other use the MLME-UNITDATA.req. The unifi_send_signal()
- * expects the wire-formatted (packed) signal. For convenience, in the OS
- * layer we only use the native (unpacked) signal structures. The HIP core lib
- * provides the write_pack() helper function to convert to the packed signal.
- * The packet is stored in the bulk data of the signal. We do not need to
- * allocate new memory to store the packet, because unifi_net_data_malloc()
- * is implemented to return a skb, which is the format of packet in Linux.
- * The HIP core lib frees the bulk data buffers, so we do not need to do
- * this in the OS layer.
- *
- * All the Rx packets are MLME-UNITDATA.ind signals, passed by the HIP core lib
- * in unifi_receive_event(). We do not need to allocate an skb and copy the
- * received packet because the HIP core lib has stored in memory allocated by
- * unifi_net_data_malloc(). Also, we can perform the 802.11 to Ethernet
- * translation in-place because we allocate the extra memory allocated in
- * unifi_net_data_malloc().
- *
- * If possible, the porting exercise should appropriately implement
- * unifi_net_data_malloc() and unifi_net_data_free() to save copies between
- * network and driver buffers.
- */
-
-#include <linux/types.h>
-#include <linux/etherdevice.h>
-#include <linux/mutex.h>
-#include <linux/semaphore.h>
-#include <linux/vmalloc.h>
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-#include "unifi_priv.h"
-#include <net/pkt_sched.h>
-
-
-/* Wext handler is supported only if CSR_SUPPORT_WEXT is defined */
-#ifdef CSR_SUPPORT_WEXT
-extern struct iw_handler_def unifi_iw_handler_def;
-#endif /* CSR_SUPPORT_WEXT */
-static void check_ba_frame_age_timeout( unifi_priv_t *priv,
-                                            netInterface_priv_t *interfacePriv,
-                                            ba_session_rx_struct *ba_session);
-static void process_ba_frame(unifi_priv_t *priv,
-                             netInterface_priv_t *interfacePriv,
-                             ba_session_rx_struct *ba_session,
-                             frame_desc_struct *frame_desc);
-static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv);
-static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata);
-static void process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata);
-static int uf_net_open(struct net_device *dev);
-static int uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int uf_net_stop(struct net_device *dev);
-static struct net_device_stats *uf_net_get_stats(struct net_device *dev);
-static u16 uf_net_select_queue(struct net_device *dev, struct sk_buff *skb);
-static netdev_tx_t uf_net_xmit(struct sk_buff *skb, struct net_device *dev);
-static void uf_set_multicast_list(struct net_device *dev);
-
-
-typedef int (*tx_signal_handler)(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority);
-
-#ifdef CONFIG_NET_SCHED
-/*
- * Queueing Discipline Interface
- * Only used if kernel is configured with CONFIG_NET_SCHED
- */
-
-/*
- * The driver uses the qdisc interface to buffer and control all
- * outgoing traffic. We create a root qdisc, register our qdisc operations
- * and later we create two subsidiary pfifo queues for the uncontrolled
- * and controlled ports.
- *
- * The network stack delivers all outgoing packets in our enqueue handler.
- * There, we classify the packet and decide whether to store it or drop it
- * (if the controlled port state is set to "discard").
- * If the packet is enqueued, the network stack call our dequeue handler.
- * There, we decide whether we can send the packet, delay it or drop it
- * (the controlled port configuration might have changed meanwhile).
- * If a packet is dequeued, then the network stack calls our hard_start_xmit
- * handler where finally we send the packet.
- *
- * If the hard_start_xmit handler fails to send the packet, we return
- * NETDEV_TX_BUSY and the network stack call our requeue handler where
- * we put the packet back in the same queue in came from.
- *
- */
-
-struct uf_sched_data
-{
-    /* Traffic Classifier TBD */
-    struct tcf_proto *filter_list;
-    /* Our two queues */
-    struct Qdisc *queues[UNIFI_TRAFFIC_Q_MAX];
-};
-
-struct uf_tx_packet_data {
-    /* Queue the packet is stored in */
-    unifi_TrafficQueue queue;
-    /* QoS Priority determined when enqueing packet */
-    CSR_PRIORITY priority;
-    /* Debug */
-    unsigned long host_tag;
-};
-
-#endif /* CONFIG_NET_SCHED */
-
-static const struct net_device_ops uf_netdev_ops =
-{
-    .ndo_open = uf_net_open,
-    .ndo_stop = uf_net_stop,
-    .ndo_start_xmit = uf_net_xmit,
-    .ndo_do_ioctl = uf_net_ioctl,
-    .ndo_get_stats = uf_net_get_stats, /* called by /proc/net/dev */
-    .ndo_set_rx_mode = uf_set_multicast_list,
-    .ndo_select_queue = uf_net_select_queue,
-};
-
-static u8 oui_rfc1042[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-static u8 oui_8021h[P80211_OUI_LEN]   = { 0x00, 0x00, 0xf8 };
-
-
-/* Callback for event logging to blocking clients */
-static void netdev_mlme_event_handler(ul_client_t  *client,
-                                      const u8 *sig_packed, int sig_len,
-                                      const bulk_data_param_t *bulkdata,
-                                      int dir);
-
-#ifdef CSR_SUPPORT_WEXT
-/* Declare netdev_notifier block which will contain the state change
- * handler callback function
- */
-static struct notifier_block uf_netdev_notifier;
-#endif
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_alloc_netdevice
- *
- *      Allocate memory for the net_device and device private structs
- *      for this interface.
- *      Fill in the fields, but don't register the interface yet.
- *      We need to configure the UniFi first.
- *
- *  Arguments:
- *      sdio_dev        Pointer to SDIO context handle to use for all
- *                      SDIO ops.
- *      bus_id          A small number indicating the SDIO card position on the
- *                      bus. Typically this is the slot number, e.g. 0, 1 etc.
- *                      Valid values are 0 to MAX_UNIFI_DEVS-1.
- *
- *  Returns:
- *      Pointer to device private struct.
- *
- *  Notes:
- *      The net_device and device private structs are allocated together
- *      and should be freed by freeing the net_device pointer.
- * ---------------------------------------------------------------------------
- */
-unifi_priv_t *
-uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id)
-{
-    struct net_device *dev;
-    unifi_priv_t *priv;
-    netInterface_priv_t *interfacePriv;
-#ifdef CSR_SUPPORT_WEXT
-    int rc;
-#endif
-    unsigned char i; /* loop index */
-
-    /*
-     * Allocate netdevice struct, assign name template and
-     * setup as an ethernet device.
-     * The net_device and private structs are zeroed. Ether_setup() then
-     * sets up ethernet handlers and values.
-     * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
-     * so use "eth*" (like other wireless extns drivers).
-     */
-    dev = alloc_etherdev_mq(sizeof(unifi_priv_t) + sizeof(netInterface_priv_t), UNIFI_TRAFFIC_Q_MAX);
-
-    if (dev == NULL) {
-        return NULL;
-    }
-
-    /* Set up back pointer from priv to netdev */
-    interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    priv = (unifi_priv_t *)(interfacePriv + 1);
-    interfacePriv->privPtr = priv;
-    interfacePriv->InterfaceTag = 0;
-
-
-    /* Initialize all supported netdev interface to be NULL */
-    for(i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
-        priv->netdev[i] = NULL;
-        priv->interfacePriv[i] = NULL;
-    }
-    priv->netdev[0] = dev;
-    priv->interfacePriv[0] = interfacePriv;
-
-    /* Setup / override net_device fields */
-    dev->netdev_ops = &uf_netdev_ops;
-
-#ifdef CSR_SUPPORT_WEXT
-    dev->wireless_handlers = &unifi_iw_handler_def;
-#if IW_HANDLER_VERSION < 6
-    dev->get_wireless_stats = unifi_get_wireless_stats;
-#endif /* IW_HANDLER_VERSION */
-#endif /* CSR_SUPPORT_WEXT */
-
-    /* This gives us enough headroom to add the 802.11 header */
-    dev->needed_headroom = 32;
-
-    /* Use bus_id as instance number */
-    priv->instance = bus_id;
-    /* Store SDIO pointer to pass in the core */
-    priv->sdio = sdio_dev;
-
-    sdio_dev->driverData = (void*)priv;
-    /* Consider UniFi to be uninitialised */
-    priv->init_progress = UNIFI_INIT_NONE;
-
-    priv->prev_queue = 0;
-
-    /*
-     * Initialise the clients structure array.
-     * We do not need protection around ul_init_clients() because
-     * the character device can not be used until uf_alloc_netdevice()
-     * returns and Unifi_instances[bus_id]=priv is set, since unifi_open()
-     * will return -ENODEV.
-     */
-    ul_init_clients(priv);
-
-    /*
-     * Register a new ul client to send the multicast list signals.
-     * Note: priv->instance must be set before calling this.
-     */
-    priv->netdev_client = ul_register_client(priv,
-            0,
-            netdev_mlme_event_handler);
-    if (priv->netdev_client == NULL) {
-        unifi_error(priv,
-                "Failed to register a unifi client for background netdev processing\n");
-        free_netdev(priv->netdev[0]);
-        return NULL;
-    }
-    unifi_trace(priv, UDBG2, "Netdev %p client (id:%d s:0x%X) is registered\n",
-            dev, priv->netdev_client->client_id, priv->netdev_client->sender_id);
-
-    priv->sta_wmm_capabilities = 0;
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_SUPPORT_SME))
-    priv->wapi_multicast_filter = 0;
-    priv->wapi_unicast_filter = 0;
-    priv->wapi_unicast_queued_pkt_filter = 0;
-#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
-    priv->isWapiConnection = FALSE;
-#endif
-#endif
-
-    /* Enable all queues by default */
-    interfacePriv->queueEnabled[0] = 1;
-    interfacePriv->queueEnabled[1] = 1;
-    interfacePriv->queueEnabled[2] = 1;
-    interfacePriv->queueEnabled[3] = 1;
-
-#ifdef CSR_SUPPORT_SME
-    priv->allPeerDozing = 0;
-#endif
-    /*
-     * Initialise the OS private struct.
-     */
-    /*
-     * Instead of deciding in advance to use 11bg or 11a, we could do a more
-     * clever scan on both radios.
-     */
-    if (use_5g) {
-        priv->if_index = CSR_INDEX_5G;
-        unifi_info(priv, "Using the 802.11a radio\n");
-    } else {
-        priv->if_index = CSR_INDEX_2G4;
-    }
-
-    /* Initialise bh thread structure */
-    priv->bh_thread.thread_task = NULL;
-    priv->bh_thread.block_thread = 1;
-    init_waitqueue_head(&priv->bh_thread.wakeup_q);
-    priv->bh_thread.wakeup_flag = 0;
-    sprintf(priv->bh_thread.name, "uf_bh_thread");
-
-    /* reset the connected state for the interface */
-    interfacePriv->connected = UnifiConnectedUnknown;  /* -1 unknown, 0 no, 1 yes */
-
-#ifdef USE_DRIVER_LOCK
-    sema_init(&priv->lock, 1);
-#endif /* USE_DRIVER_LOCK */
-
-    spin_lock_init(&priv->send_signal_lock);
-
-    spin_lock_init(&priv->m4_lock);
-    sema_init(&priv->ba_mutex, 1);
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-    spin_lock_init(&priv->wapi_lock);
-#endif
-
-#ifdef CSR_SUPPORT_SME
-    spin_lock_init(&priv->staRecord_lock);
-    spin_lock_init(&priv->tx_q_lock);
-#endif
-
-    /* Create the Traffic Analysis workqueue */
-    priv->unifi_workqueue = create_singlethread_workqueue("unifi_workq");
-    if (priv->unifi_workqueue == NULL) {
-        /* Deregister priv->netdev_client */
-        ul_deregister_client(priv->netdev_client);
-        free_netdev(priv->netdev[0]);
-        return NULL;
-    }
-
-#ifdef CSR_SUPPORT_SME
-    /* Create the Multicast Addresses list work structure */
-    INIT_WORK(&priv->multicast_list_task, uf_multicast_list_wq);
-
-    /* Create m4 buffering work structure */
-    INIT_WORK(&interfacePriv->send_m4_ready_task, uf_send_m4_ready_wq);
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-    /* Create work structure to buffer the WAPI data packets to be sent to SME for encryption */
-    INIT_WORK(&interfacePriv->send_pkt_to_encrypt, uf_send_pkt_to_encrypt);
-#endif
-#endif
-
-    priv->ref_count = 1;
-
-    priv->amp_client = NULL;
-    priv->coredump_mode = 0;
-    priv->ptest_mode = 0;
-    priv->wol_suspend = FALSE;
-    INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list);
-    INIT_LIST_HEAD(&interfacePriv->rx_controlled_list);
-    sema_init(&priv->rx_q_sem, 1);
-
-#ifdef CSR_SUPPORT_WEXT
-    interfacePriv->netdev_callback_registered = FALSE;
-    interfacePriv->wait_netdev_change = FALSE;
-    /* Register callback for netdevice state changes */
-    if ((rc = register_netdevice_notifier(&uf_netdev_notifier)) == 0) {
-        interfacePriv->netdev_callback_registered = TRUE;
-    }
-    else {
-        unifi_warning(priv, "Failed to register netdevice notifier : %d %p\n", rc, dev);
-    }
-#endif /* CSR_SUPPORT_WEXT */
-
-#ifdef CSR_WIFI_SPLIT_PATCH
-    /* set it to some invalid value */
-    priv->pending_mode_set.common.destination = 0xaaaa;
-#endif
-
-    return priv;
-} /* uf_alloc_netdevice() */
-
-/*
- *---------------------------------------------------------------------------
- *  uf_alloc_netdevice_for_other_interfaces
- *
- *      Allocate memory for the net_device and device private structs
- *      for this interface.
- *      Fill in the fields, but don't register the interface yet.
- *      We need to configure the UniFi first.
- *
- *  Arguments:
- *      interfaceTag   Interface number.
- *      sdio_dev        Pointer to SDIO context handle to use for all
- *                      SDIO ops.
- *      bus_id          A small number indicating the SDIO card position on the
- *                      bus. Typically this is the slot number, e.g. 0, 1 etc.
- *                      Valid values are 0 to MAX_UNIFI_DEVS-1.
- *
- *  Returns:
- *      Pointer to device private struct.
- *
- *  Notes:
- *      The device private structure contains the interfaceTag and pointer to the unifi_priv
- *      structure created allocated by net_device od interface0.
- *      The net_device and device private structs are allocated together
- *      and should be freed by freeing the net_device pointer.
- * ---------------------------------------------------------------------------
- */
-u8
-uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, u16 interfaceTag)
-{
-    struct net_device *dev;
-    netInterface_priv_t *interfacePriv;
-
-    /*
-     * Allocate netdevice struct, assign name template and
-     * setup as an ethernet device.
-     * The net_device and private structs are zeroed. Ether_setup() then
-     * sets up ethernet handlers and values.
-     * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
-     * so use "eth*" (like other wireless extns drivers).
-     */
-    dev = alloc_etherdev_mq(sizeof(netInterface_priv_t), 1);
-    if (dev == NULL) {
-        return FALSE;
-    }
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "uf_alloc_netdevice_for_other_interfaces bad interfaceTag\n");
-        return FALSE;
-    }
-
-    /* Set up back pointer from priv to netdev */
-    interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    interfacePriv->privPtr = priv;
-    interfacePriv->InterfaceTag = interfaceTag;
-    priv->netdev[interfaceTag] = dev;
-    priv->interfacePriv[interfacePriv->InterfaceTag] = interfacePriv;
-
-    /* reset the connected state for the interface */
-    interfacePriv->connected = UnifiConnectedUnknown;  /* -1 unknown, 0 no, 1 yes */
-    INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list);
-    INIT_LIST_HEAD(&interfacePriv->rx_controlled_list);
-
-    /* Setup / override net_device fields */
-    dev->netdev_ops = &uf_netdev_ops;
-
-#ifdef CSR_SUPPORT_WEXT
-    dev->wireless_handlers = &unifi_iw_handler_def;
-#if IW_HANDLER_VERSION < 6
-    dev->get_wireless_stats = unifi_get_wireless_stats;
-#endif /* IW_HANDLER_VERSION */
-#endif /* CSR_SUPPORT_WEXT */
-    return TRUE;
-} /* uf_alloc_netdevice() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_free_netdevice
- *
- *      Unregister the network device and free the memory allocated for it.
- *      NB This includes the memory for the priv struct.
- *
- *  Arguments:
- *      priv            Device private pointer.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-int
-uf_free_netdevice(unifi_priv_t *priv)
-{
-    int i;
-    unsigned long flags;
-
-    unifi_trace(priv, UDBG1, "uf_free_netdevice\n");
-
-    if (!priv) {
-        return -EINVAL;
-    }
-
-    /*
-     * Free any buffers used for holding firmware
-     */
-    uf_release_firmware_files(priv);
-
-#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
-    if (priv->connection_config.mlmeAssociateReqInformationElements) {
-        kfree(priv->connection_config.mlmeAssociateReqInformationElements);
-    }
-    priv->connection_config.mlmeAssociateReqInformationElements = NULL;
-    priv->connection_config.mlmeAssociateReqInformationElementsLength = 0;
-
-    if (priv->mib_data.length) {
-        vfree(priv->mib_data.data);
-    }
-    priv->mib_data.data = NULL;
-    priv->mib_data.length = 0;
-
-#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/
-
-    /* Free any bulkdata buffers allocated for M4 caching */
-    spin_lock_irqsave(&priv->m4_lock, flags);
-    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
-        netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
-        if (interfacePriv->m4_bulk_data.data_length > 0) {
-            unifi_trace(priv, UDBG5, "uf_free_netdevice: free M4 bulkdata %d\n", i);
-            unifi_net_data_free(priv, &interfacePriv->m4_bulk_data);
-        }
-    }
-    spin_unlock_irqrestore(&priv->m4_lock, flags);
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-    /* Free any bulkdata buffers allocated for M4 caching */
-    spin_lock_irqsave(&priv->wapi_lock, flags);
-    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
-        netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
-        if (interfacePriv->wapi_unicast_bulk_data.data_length > 0) {
-            unifi_trace(priv, UDBG5, "uf_free_netdevice: free WAPI PKT bulk data %d\n", i);
-            unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
-        }
-    }
-    spin_unlock_irqrestore(&priv->wapi_lock, flags);
-#endif
-
-#ifdef CSR_SUPPORT_WEXT
-    /* Unregister callback for netdevice state changes */
-    unregister_netdevice_notifier(&uf_netdev_notifier);
-#endif /* CSR_SUPPORT_WEXT */
-
-#ifdef CSR_SUPPORT_SME
-    /* Cancel work items and destroy the workqueue */
-    cancel_work_sync(&priv->multicast_list_task);
-#endif
-/* Destroy the workqueues. */
-    flush_workqueue(priv->unifi_workqueue);
-    destroy_workqueue(priv->unifi_workqueue);
-
-    /* Free up netdev in reverse order: priv is allocated with netdev[0].
-     * So, netdev[0] should be freed after all other netdevs are freed up
-     */
-    for (i=CSR_WIFI_NUM_INTERFACES-1; i>=0; i--) {
-        /*Free the netdev struct and priv, which are all one lump*/
-        if (priv->netdev[i]) {
-            unifi_error(priv, "uf_free_netdevice: netdev %d %p\n", i, priv->netdev[i]);
-            free_netdev(priv->netdev[i]);
-        }
-    }
-
-    return 0;
-} /* uf_free_netdevice() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_net_open
- *
- *      Called when userland does "ifconfig wlan0 up".
- *
- *  Arguments:
- *      dev             Device pointer.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static int
-uf_net_open(struct net_device *dev)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    /* If we haven't finished UniFi initialisation, we can't start */
-    if (priv->init_progress != UNIFI_INIT_COMPLETED) {
-        unifi_warning(priv, "%s: unifi not ready, failing net_open\n", __FUNCTION__);
-        return -EINVAL;
-    }
-
-#if (defined CSR_NATIVE_LINUX) && (defined UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
-    /*
-     * To sniff, the user must do "iwconfig mode monitor", which sets
-     * priv->wext_conf.mode to IW_MODE_MONITOR.
-     * Then he/she must do "ifconfig ethn up", which calls this fn.
-     * There is no point in starting the sniff with SNIFFJOIN until
-     * this point.
-     */
-    if (priv->wext_conf.mode == IW_MODE_MONITOR) {
-        int err;
-        err = uf_start_sniff(priv);
-        if (err) {
-            return err;
-        }
-        netif_carrier_on(dev);
-    }
-#endif
-
-#ifdef CSR_SUPPORT_WEXT
-    if (interfacePriv->wait_netdev_change) {
-        unifi_trace(priv, UDBG1, "%s: Waiting for NETDEV_CHANGE, assume connected\n",
-                    __FUNCTION__);
-        interfacePriv->connected = UnifiConnected;
-        interfacePriv->wait_netdev_change = FALSE;
-    }
-#endif
-
-    netif_tx_start_all_queues(dev);
-
-    return 0;
-} /* uf_net_open() */
-
-
-static int
-uf_net_stop(struct net_device *dev)
-{
-#if defined(CSR_NATIVE_LINUX) && defined(UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    /* Stop sniffing if in Monitor mode */
-    if (priv->wext_conf.mode == IW_MODE_MONITOR) {
-        if (priv->card) {
-            int err;
-            err = unifi_reset_state(priv, dev->dev_addr, 1);
-            if (err) {
-                return err;
-            }
-        }
-    }
-#endif
-
-    netif_tx_stop_all_queues(dev);
-
-    return 0;
-} /* uf_net_stop() */
-
-
-/* This is called after the WE handlers */
-static int
-uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-    int rc;
-
-    rc = -EOPNOTSUPP;
-
-    return rc;
-} /* uf_net_ioctl() */
-
-
-
-static struct net_device_stats *
-uf_net_get_stats(struct net_device *dev)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-
-    return &interfacePriv->stats;
-} /* uf_net_get_stats() */
-
-static CSR_PRIORITY uf_get_packet_priority(unifi_priv_t *priv, netInterface_priv_t *interfacePriv, struct sk_buff *skb, const int proto)
-{
-    CSR_PRIORITY priority = CSR_CONTENTION;
-
-    priority = (CSR_PRIORITY) (skb->priority >> 5);
-
-    if (priority == CSR_QOS_UP0) { /* 0 */
-
-        unifi_trace(priv, UDBG5, "uf_get_packet_priority: proto = 0x%.4X\n", proto);
-
-        switch (proto) {
-            case 0x0800:        /* IPv4 */
-            case 0x814C:        /* SNMP */
-            case 0x880C:        /* GSMP */
-                priority = (CSR_PRIORITY) (skb->data[1 + ETH_HLEN] >> 5);
-                break;
-
-            case 0x8100:        /* VLAN */
-                priority = (CSR_PRIORITY) (skb->data[0 + ETH_HLEN] >> 5);
-                break;
-
-            case 0x86DD:        /* IPv6 */
-                priority = (CSR_PRIORITY) ((skb->data[0 + ETH_HLEN] & 0x0E) >> 1);
-                break;
-
-            default:
-                priority = CSR_QOS_UP0;
-                break;
-        }
-    }
-
-    /* Check if we are allowed to transmit on this AC. Because of ACM we may have to downgrade to a lower
-     * priority */
-    if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA ||
-        interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) {
-        unifi_TrafficQueue queue;
-
-        /* Keep trying lower priorities until we find a queue
-         * Priority to queue mapping is 1,2 - BK, 0,3 - BE, 4,5 - VI, 6,7 - VO */
-        queue = unifi_frame_priority_to_queue(priority);
-
-        while (queue > UNIFI_TRAFFIC_Q_BK && !interfacePriv->queueEnabled[queue]) {
-            queue--;
-            priority = unifi_get_default_downgrade_priority(queue);
-        }
-    }
-
-    unifi_trace(priv, UDBG5, "Packet priority = %d\n", priority);
-
-    return priority;
-}
-
-/*
- */
-/*
- * ---------------------------------------------------------------------------
- *  get_packet_priority
- *
- *  Arguments:
- *      priv             private data area of functional driver
- *      skb              socket buffer
- *      ehdr             ethernet header to fetch protocol
- *      interfacePriv    For accessing station record database
- *
- *
- *  Returns:
- *      CSR_PRIORITY.
- * ---------------------------------------------------------------------------
- */
-CSR_PRIORITY
-get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, netInterface_priv_t *interfacePriv)
-{
-    CSR_PRIORITY priority = CSR_CONTENTION;
-    const int proto = ntohs(ehdr->h_proto);
-
-    u8 interfaceMode = interfacePriv->interfaceMode;
-
-    /* Priority Mapping for all the Modes */
-    switch(interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-            unifi_trace(priv, UDBG4, "mode is STA \n");
-            if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1) {
-                priority = uf_get_packet_priority(priv, interfacePriv, skb, proto);
-            } else {
-                priority = CSR_CONTENTION;
-            }
-            break;
-#ifdef CSR_SUPPORT_SME
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-            {
-                CsrWifiRouterCtrlStaInfo_t * dstStaInfo =
-                    CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,ehdr->h_dest, interfacePriv->InterfaceTag);
-                unifi_trace(priv, UDBG4, "mode is AP \n");
-                if (!(ehdr->h_dest[0] & 0x01) && dstStaInfo && dstStaInfo->wmmOrQosEnabled) {
-                    /* If packet is not Broadcast/multicast */
-                    priority = uf_get_packet_priority(priv, interfacePriv, skb, proto);
-                } else {
-                    /* Since packet destination is not QSTA, set priority to CSR_CONTENTION */
-                    unifi_trace(priv, UDBG4, "Destination is not QSTA or BroadCast/Multicast\n");
-                    priority = CSR_CONTENTION;
-                }
-            }
-            break;
-#endif
-        default:
-            unifi_trace(priv, UDBG3, " mode unknown in %s func, mode=%x\n", __FUNCTION__, interfaceMode);
-    }
-    unifi_trace(priv, UDBG5, "priority = %x\n", priority);
-
-    return priority;
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_net_select_queue
- *
- *      Called by the kernel to select which queue to put the packet in
- *
- *  Arguments:
- *      dev             Device pointer
- *      skb             Packet
- *
- *  Returns:
- *      Queue index
- * ---------------------------------------------------------------------------
- */
-static u16
-uf_net_select_queue(struct net_device *dev, struct sk_buff *skb)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = (unifi_priv_t *)interfacePriv->privPtr;
-    struct ethhdr ehdr;
-    unifi_TrafficQueue queue;
-    int proto;
-    CSR_PRIORITY priority;
-
-    memcpy(&ehdr, skb->data, ETH_HLEN);
-    proto = ntohs(ehdr.h_proto);
-
-    /* 802.1x - apply controlled/uncontrolled port rules */
-    if ((proto != ETH_P_PAE)
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-            && (proto != ETH_P_WAI)
-#endif
-       ) {
-        /* queues 0 - 3 */
-        priority = get_packet_priority(priv, skb, &ehdr, interfacePriv);
-        queue = unifi_frame_priority_to_queue(priority);
-    } else {
-        /* queue 4 */
-        queue = UNIFI_TRAFFIC_Q_EAPOL;
-    }
-
-
-    return (u16)queue;
-} /* uf_net_select_queue() */
-
-int
-skb_add_llc_snap(struct net_device *dev, struct sk_buff *skb, int proto)
-{
-    llc_snap_hdr_t *snap;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int headroom;
-
-    /* get the headroom available in skb */
-    headroom = skb_headroom(skb);
-    /* step 1: classify ether frame, DIX or 802.3? */
-
-    if (proto < 0x600) {
-        /* codes <= 1500 reserved for 802.3 lengths */
-        /* it's 802.3, pass ether payload unchanged,  */
-        unifi_trace(priv, UDBG3, "802.3 len: %d\n", skb->len);
-
-        /*   leave off any PAD octets.  */
-        skb_trim(skb, proto);
-    } else if (proto == ETH_P_8021Q) {
-
-        /* Store the VLAN SNAP (should be 87-65). */
-        u16 vlan_snap = *(u16*)skb->data;
-        /* check for headroom availability before skb_push 14 = (4 + 10) */
-        if (headroom < 14) {
-            unifi_trace(priv, UDBG3, "cant append vlan snap: debug\n");
-            return -1;
-        }
-        /* Add AA-AA-03-00-00-00 */
-        snap = (llc_snap_hdr_t *)skb_push(skb, 4);
-        snap->dsap = snap->ssap = 0xAA;
-        snap->ctrl = 0x03;
-        memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
-
-        /* Add AA-AA-03-00-00-00 */
-        snap = (llc_snap_hdr_t *)skb_push(skb, 10);
-        snap->dsap = snap->ssap = 0xAA;
-        snap->ctrl = 0x03;
-        memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
-
-        /* Add the VLAN specific information */
-        snap->protocol = htons(proto);
-        *(u16*)(snap + 1) = vlan_snap;
-
-    } else
-    {
-        /* it's DIXII, time for some conversion */
-        unifi_trace(priv, UDBG3, "DIXII len: %d\n", skb->len);
-
-        /* check for headroom availability before skb_push */
-        if (headroom < sizeof(llc_snap_hdr_t)) {
-            unifi_trace(priv, UDBG3, "cant append snap: debug\n");
-            return -1;
-        }
-        /* tack on SNAP */
-        snap = (llc_snap_hdr_t *)skb_push(skb, sizeof(llc_snap_hdr_t));
-        snap->dsap = snap->ssap = 0xAA;
-        snap->ctrl = 0x03;
-        /* Use the appropriate OUI. */
-        if ((proto == ETH_P_AARP) || (proto == ETH_P_IPX)) {
-            memcpy(snap->oui, oui_8021h, P80211_OUI_LEN);
-        } else {
-            memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
-        }
-        snap->protocol = htons(proto);
-    }
-
-    return 0;
-} /* skb_add_llc_snap() */
-
-#ifdef CSR_SUPPORT_SME
-static int
-_identify_sme_ma_pkt_ind(unifi_priv_t *priv,
-                         const s8 *oui, u16 protocol,
-                         const CSR_SIGNAL *signal,
-                         bulk_data_param_t *bulkdata,
-                         const unsigned char *daddr,
-                         const unsigned char *saddr)
-{
-    CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication;
-    int r;
-    u8 i;
-
-    unifi_trace(priv, UDBG5,
-            "_identify_sme_ma_pkt_ind -->\n");
-    for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
-        if (priv->sme_unidata_ind_filters[i].in_use) {
-            if (!memcmp(oui, priv->sme_unidata_ind_filters[i].oui, 3) &&
-                    (protocol == priv->sme_unidata_ind_filters[i].protocol)) {
-
-                /* Send to client */
-                if (priv->sme_cli) {
-                    /*
-                     * Pass the packet to the SME, using unifi_sys_ma_unitdata_ind().
-                     * The frame needs to be converted according to the encapsulation.
-                     */
-                    unifi_trace(priv, UDBG1,
-                            "_identify_sme_ma_pkt_ind: handle=%d, encap=%d, proto=%x\n",
-                            i, priv->sme_unidata_ind_filters[i].encapsulation,
-                            priv->sme_unidata_ind_filters[i].protocol);
-                    if (priv->sme_unidata_ind_filters[i].encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) {
-                        struct sk_buff *skb;
-                        /* The translation is performed on skb... */
-                        skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
-                        skb->len = bulkdata->d[0].data_length;
-
-                        unifi_trace(priv, UDBG1,
-                                "_identify_sme_ma_pkt_ind: skb_80211_to_ether -->\n");
-                        r = skb_80211_to_ether(priv, skb, daddr, saddr,
-                                signal, bulkdata);
-                        unifi_trace(priv, UDBG1,
-                                "_identify_sme_ma_pkt_ind: skb_80211_to_ether <--\n");
-                        if (r) {
-                            return -EINVAL;
-                        }
-
-                        /* ... but we indicate buffer and length */
-                        bulkdata->d[0].os_data_ptr = skb->data;
-                        bulkdata->d[0].data_length = skb->len;
-                    } else {
-                        /* Add the MAC addresses before the SNAP */
-                        bulkdata->d[0].os_data_ptr -= 2*ETH_ALEN;
-                        bulkdata->d[0].data_length += 2*ETH_ALEN;
-                        memcpy((void*)bulkdata->d[0].os_data_ptr, daddr, ETH_ALEN);
-                        memcpy((void*)bulkdata->d[0].os_data_ptr + ETH_ALEN, saddr, ETH_ALEN);
-                    }
-
-                    unifi_trace(priv, UDBG1,
-                            "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind -->\n");
-                    CsrWifiRouterMaPacketIndSend(priv->sme_unidata_ind_filters[i].appHandle,
-                            (pkt_ind->VirtualInterfaceIdentifier & 0xff),
-                            i,
-                            pkt_ind->ReceptionStatus,
-                            bulkdata->d[0].data_length,
-                            (u8*)bulkdata->d[0].os_data_ptr,
-                            NULL,
-                            pkt_ind->Rssi,
-                            pkt_ind->Snr,
-                            pkt_ind->ReceivedRate);
-
-
-                    unifi_trace(priv, UDBG1,
-                            "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind <--\n");
-                }
-
-                return 1;
-            }
-        }
-    }
-
-    return -1;
-}
-#endif /* CSR_SUPPORT_SME */
-
-/*
- * ---------------------------------------------------------------------------
- *  skb_80211_to_ether
- *
- *      Make sure the received frame is in Ethernet (802.3) form.
- *      De-encapsulates SNAP if necessary, adds a ethernet header.
- *      The source buffer should not contain an 802.11 MAC header
- *
- *  Arguments:
- *      payload         Pointer to packet data received from UniFi.
- *      payload_length  Number of bytes of data received from UniFi.
- *      daddr           Destination MAC address.
- *      saddr           Source MAC address.
- *
- *  Returns:
- *      0 on success, -1 if the packet is bad and should be dropped,
- *      1 if the packet was forwarded to the SME or AMP client.
- * ---------------------------------------------------------------------------
- */
-int
-skb_80211_to_ether(unifi_priv_t *priv, struct sk_buff *skb,
-                   const unsigned char *daddr, const unsigned char *saddr,
-                   const CSR_SIGNAL *signal,
-                   bulk_data_param_t *bulkdata)
-{
-    unsigned char *payload;
-    int payload_length;
-    struct ethhdr *eth;
-    llc_snap_hdr_t *snap;
-    int headroom;
-#define UF_VLAN_LLC_HEADER_SIZE     18
-    static const u8 vlan_inner_snap[] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 };
-#if defined(CSR_NATIVE_SOFTMAC) && defined(CSR_SUPPORT_SME)
-    const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
-#endif
-
-    if(skb== NULL || daddr == NULL || saddr == NULL){
-        unifi_error(priv,"skb_80211_to_ether: PBC fail\n");
-        return 1;
-    }
-
-    payload = skb->data;
-    payload_length = skb->len;
-
-    snap = (llc_snap_hdr_t *)payload;
-    eth  = (struct ethhdr *)payload;
-
-    /* get the skb headroom size */
-    headroom = skb_headroom(skb);
-
-    /*
-     * Test for the various encodings
-     */
-    if ((payload_length >= sizeof(llc_snap_hdr_t)) &&
-            (snap->dsap == 0xAA) &&
-            (snap->ssap == 0xAA) &&
-            (snap->ctrl == 0x03) &&
-            (snap->oui[0] == 0) &&
-            (snap->oui[1] == 0) &&
-            ((snap->oui[2] == 0) || (snap->oui[2] == 0xF8)))
-    {
-        /* AppleTalk AARP (2) or IPX SNAP */
-        if ((snap->oui[2] == 0) &&
-                ((ntohs(snap->protocol) == ETH_P_AARP) || (ntohs(snap->protocol) == ETH_P_IPX)))
-        {
-            u16 len;
-
-            unifi_trace(priv, UDBG3, "%s len: %d\n",
-                    (ntohs(snap->protocol) == ETH_P_AARP) ? "ETH_P_AARP" : "ETH_P_IPX",
-                    payload_length);
-
-            /* check for headroom availability before skb_push */
-            if (headroom < (2 * ETH_ALEN + 2)) {
-                unifi_warning(priv, "headroom not available to skb_push ether header\n");
-                return -1;
-            }
-
-            /* Add 802.3 header and leave full payload */
-            len = htons(skb->len);
-            memcpy(skb_push(skb, 2), &len, 2);
-            memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
-            memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);
-
-            return 0;
-        }
-        /* VLAN-tagged IP */
-        if ((snap->oui[2] == 0) && (ntohs(snap->protocol) == ETH_P_8021Q))
-        {
-            /*
-             * The translation doesn't change the packet length, so is done in-place.
-             *
-             * Example header (from Std 802.11-2007 Annex M):
-             * AA-AA-03-00-00-00-81-00-87-65-AA-AA-03-00-00-00-08-06
-             * -------SNAP-------p1-p1-ll-ll-------SNAP--------p2-p2
-             * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-p1-p1-ll-ll-p2-p2
-             * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-81-00-87-65-08-06
-             */
-            u16 vlan_snap;
-
-            if (payload_length < UF_VLAN_LLC_HEADER_SIZE) {
-                unifi_warning(priv, "VLAN SNAP header too short: %d bytes\n", payload_length);
-                return -1;
-            }
-
-            if (memcmp(payload + 10, vlan_inner_snap, 6)) {
-                unifi_warning(priv, "VLAN malformatted SNAP header.\n");
-                return -1;
-            }
-
-            unifi_trace(priv, UDBG3, "VLAN SNAP: %02x-%02x\n", payload[8], payload[9]);
-            unifi_trace(priv, UDBG3, "VLAN len: %d\n", payload_length);
-
-            /* Create the 802.3 header */
-
-            vlan_snap = *((u16*)(payload + 8));
-
-            /* Create LLC header without byte-swapping */
-            eth->h_proto = snap->protocol;
-
-            memcpy(eth->h_dest, daddr, ETH_ALEN);
-            memcpy(eth->h_source, saddr, ETH_ALEN);
-            *(u16*)(eth + 1) = vlan_snap;
-            return 0;
-        }
-
-        /* it's a SNAP + RFC1042 frame */
-        unifi_trace(priv, UDBG3, "SNAP+RFC1042 len: %d\n", payload_length);
-
-        /* chop SNAP+llc header from skb. */
-        skb_pull(skb, sizeof(llc_snap_hdr_t));
-
-        /* Since skb_pull called above to chop snap+llc, no need to check for headroom
-         * availability before skb_push
-         */
-        /* create 802.3 header at beginning of skb. */
-        eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
-        memcpy(eth->h_dest, daddr, ETH_ALEN);
-        memcpy(eth->h_source, saddr, ETH_ALEN);
-        /* Copy protocol field without byte-swapping */
-        eth->h_proto = snap->protocol;
-    } else {
-        u16 len;
-
-        /* check for headroom availability before skb_push */
-        if (headroom < (2 * ETH_ALEN + 2)) {
-            unifi_warning(priv, "headroom not available to skb_push ether header\n");
-            return -1;
-        }
-        /* Add 802.3 header and leave full payload */
-        len = htons(skb->len);
-        memcpy(skb_push(skb, 2), &len, 2);
-        memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
-        memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);
-
-        return 1;
-    }
-
-    return 0;
-} /* skb_80211_to_ether() */
-
-
-static CsrWifiRouterCtrlPortAction verify_port(unifi_priv_t *priv, unsigned char *address, int queue, u16 interfaceTag)
-{
-#ifdef CSR_NATIVE_LINUX
-#ifdef CSR_SUPPORT_WEXT
-    if (queue == UF_CONTROLLED_PORT_Q) {
-        return priv->wext_conf.block_controlled_port;
-    } else {
-        return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN;
-    }
-#else
-    return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN; /* default to open for softmac dev */
-#endif
-#else
-    return uf_sme_port_state(priv, address, queue, interfaceTag);
-#endif
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  prepare_and_add_macheader
- *
- *
- *      These functions adds mac header for packet from netdev
- *      to UniFi for transmission.
- *      EAP protocol packets are also appended with Mac header &
- *      sent using send_ma_pkt_request().
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *      skb             Socket buffer containing data packet to transmit
- *      newSkb          Socket buffer containing data packet + Mac header if no sufficient headroom in skb
- *      serviceClass    to append QOS control header in Mac header
- *      bulkdata        if newSkb allocated then bulkdata updated to send to unifi
- *      interfaceTag    the interfaceID on which activity going on
- *      daddr           destination address
- *      saddr           source address
- *      protection      protection bit set in framce control of mac header
- *
- *  Returns:
- *      Zero on success or error code.
- * ---------------------------------------------------------------------------
- */
-
-int prepare_and_add_macheader(unifi_priv_t *priv, struct sk_buff *skb, struct sk_buff *newSkb,
-                              CSR_PRIORITY priority,
-                              bulk_data_param_t *bulkdata,
-                              u16 interfaceTag,
-                              const u8 *daddr,
-                              const u8 *saddr,
-                              u8 protection)
-{
-    u16 fc = 0;
-    u8 qc = 0;
-    u8 macHeaderLengthInBytes = MAC_HEADER_SIZE, *bufPtr = NULL;
-    bulk_data_param_t data_ptrs;
-    CsrResult csrResult;
-    int headroom =0;
-    u8 direction = 0;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    u8 *addressOne;
-    u8 bQosNull = false;
-
-    if (skb == NULL) {
-        unifi_error(priv,"prepare_and_add_macheader: Invalid SKB reference\n");
-        return -1;
-    }
-
-    /* add a MAC header refer: 7.1.3.1 Frame Control field in P802.11REVmb.book */
-    if (priority != CSR_CONTENTION) {
-        /* EAPOL packets don't go as QOS_DATA */
-        if (priority == CSR_MANAGEMENT) {
-            fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
-        } else {
-            /* Qos Control Field */
-            macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
-
-            if (skb->len) {
-
-                fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA);
-            } else {
-                fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_NULL);
-                bQosNull = true;
-            }
-        }
-    } else {
-        if(skb->len == 0) {
-            fc |= cpu_to_le16(IEEE802_11_FC_TYPE_NULL);
-        } else {
-            fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
-        }
-    }
-
-    switch (interfacePriv->interfaceMode)
-    {
-        case  CSR_WIFI_ROUTER_CTRL_MODE_STA:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-            direction = 2;
-            fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK);
-            break;
-        case  CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-            direction = 0;
-            break;
-        case  CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            direction = 1;
-            fc |= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK);
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
-            if (priority == CSR_MANAGEMENT ) {
-
-                direction = 2;
-                fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK);
-            } else {
-                /* Data frames have to use WDS 4 address frames */
-                direction = 3;
-                fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK | IEEE802_11_FC_FROM_DS_MASK);
-                macHeaderLengthInBytes += 6;
-            }
-            break;
-        default:
-            unifi_warning(priv, "prepare_and_add_macheader: Unknown mode %d\n",
-                          interfacePriv->interfaceMode);
-    }
-
-
-    /* If Sta is QOS & HTC is supported then need to set 'order' bit */
-    /* We don't support HT Control for now */
-
-    if(protection) {
-        fc |= cpu_to_le16(IEEE802_11_FC_PROTECTED_MASK);
-    }
-
-    /* check the skb headroom before pushing mac header */
-    headroom = skb_headroom(skb);
-
-    if (headroom < macHeaderLengthInBytes) {
-        unifi_trace(priv, UDBG5,
-                    "prepare_and_add_macheader: Allocate headroom extra %d bytes\n",
-                    macHeaderLengthInBytes);
-
-        csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);
-
-        if (csrResult != CSR_RESULT_SUCCESS) {
-            unifi_error(priv, " failed to allocate request_data. in %s func\n", __FUNCTION__);
-            return -1;
-        }
-        newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr);
-        newSkb->len = skb->len + macHeaderLengthInBytes;
-
-        memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes,
-                skb->data, skb->len);
-
-        bulkdata->d[0].os_data_ptr = newSkb->data;
-        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb;
-        bulkdata->d[0].data_length = newSkb->len;
-
-        bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;
-
-        /* The old skb will not be used again */
-            kfree_skb(skb);
-    } else {
-
-        /* headroom has sufficient size, so will get proper pointer */
-        bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
-        bulkdata->d[0].os_data_ptr = skb->data;
-        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
-        bulkdata->d[0].data_length = skb->len;
-    }
-
-    /* Frame the actual MAC header */
-
-    memset(bufPtr, 0, macHeaderLengthInBytes);
-
-    /* copy frameControl field */
-    memcpy(bufPtr, &fc, sizeof(fc));
-    bufPtr += sizeof(fc);
-    macHeaderLengthInBytes -= sizeof(fc);
-
-    /* Duration/ID field which is 2 bytes */
-    bufPtr += 2;
-    macHeaderLengthInBytes -= 2;
-
-    switch(direction)
-    {
-        case 0:
-            /* Its an Ad-Hoc no need to route it through AP */
-            /* Address1: MAC address of the destination from eth header */
-            memcpy(bufPtr, daddr, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-
-            /* Address2: MAC address of the source */
-            memcpy(bufPtr, saddr, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-
-            /* Address3: the BSSID (locally generated in AdHoc (creators Bssid)) */
-            memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-            break;
-        case 1:
-           /* Address1: MAC address of the actual destination */
-            memcpy(bufPtr, daddr, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-            /* Address2: The MAC address of the AP */
-            memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-
-            /* Address3: MAC address of the source from eth header */
-            memcpy(bufPtr, saddr, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-            break;
-        case  2:
-            /* Address1: To AP is the MAC address of the AP to which its associated */
-            memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-
-            /* Address2: MAC address of the source from eth header */
-            memcpy(bufPtr, saddr, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-
-            /* Address3: MAC address of the actual destination on the distribution system */
-            memcpy(bufPtr, daddr, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-            break;
-        case 3:
-            memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-
-            /* Address2: MAC address of the source from eth header */
-            memcpy(bufPtr, saddr, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-
-            /* Address3: MAC address of the actual destination on the distribution system */
-            memcpy(bufPtr, daddr, ETH_ALEN);
-            bufPtr += ETH_ALEN;
-            macHeaderLengthInBytes -= ETH_ALEN;
-            break;
-        default:
-            unifi_error(priv,"Unknown direction =%d : Not handled now\n",direction);
-            return -1;
-    }
-    /* 2 bytes of frame control field, appended by firmware */
-    bufPtr += 2;
-    macHeaderLengthInBytes -= 2;
-
-    if (3 == direction) {
-        /* Address4: MAC address of the source */
-        memcpy(bufPtr, saddr, ETH_ALEN);
-        bufPtr += ETH_ALEN;
-        macHeaderLengthInBytes -= ETH_ALEN;
-    }
-
-    /* IF Qos Data or Qos Null Data then set QosControl field */
-    if ((priority != CSR_CONTENTION) && (macHeaderLengthInBytes >= QOS_CONTROL_HEADER_SIZE)) {
-
-        if (priority > 7) {
-            unifi_trace(priv, UDBG1, "data packets priority is more than 7, priority = %x\n", priority);
-            qc |= 7;
-        } else {
-            qc |= priority;
-        }
-        /*assigning address1
-        * Address1 offset taken fromm bufPtr(currently bufPtr pointing to Qos contorl) variable in reverse direction
-        * Address4 don't exit
-        */
-
-        addressOne = bufPtr- ADDRESS_ONE_OFFSET;
-
-        if (addressOne[0] & 0x1) {
-            /* multicast/broadcast frames, no acknowledgement needed */
-            qc |= 1 << 5;
-        }
-        /* non-AP mode only for now */
-        if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA ||
-           interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS ||
-           interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) {
-           /* In case of STA and IBSS case eosp and txop limit is 0. */
-        } else {
-            if(bQosNull) {
-                qc |= 1 << 4;
-            }
-        }
-
-        /* append Qos control field to mac header */
-        bufPtr[0] = qc;
-        /* txop limit is 0 */
-        bufPtr[1] = 0;
-        macHeaderLengthInBytes -= QOS_CONTROL_HEADER_SIZE;
-    }
-    if (macHeaderLengthInBytes) {
-        unifi_warning(priv, " Mac header not appended properly\n");
-        return -1;
-    }
-    return 0;
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  send_ma_pkt_request
- *
- *      These functions send a data packet to UniFi for transmission.
- *      EAP protocol packets are also sent as send_ma_pkt_request().
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *      skb             Socket buffer containing data packet to transmit
- *      ehdr            Pointer to Ethernet header within skb.
- *
- *  Returns:
- *      Zero on success or error code.
- * ---------------------------------------------------------------------------
- */
-
-static int
-send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority)
-{
-    int r;
-    u16 i;
-    u8 eapolStore = FALSE;
-    struct sk_buff *newSkb = NULL;
-    bulk_data_param_t bulkdata;
-    const int proto = ntohs(ehdr->h_proto);
-    u16 interfaceTag;
-    CsrWifiMacAddress peerAddress;
-    CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED;
-    s8 protection;
-    netInterface_priv_t *interfacePriv = NULL;
-    CSR_RATE TransmitRate = (CSR_RATE)0;
-
-    unifi_trace(priv, UDBG5, "entering send_ma_pkt_request\n");
-
-    /* Get the interface Tag by means of source Mac address */
-    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
-        if (!memcmp(priv->netdev[i]->dev_addr, ehdr->h_source, ETH_ALEN)) {
-            interfaceTag = i;
-            interfacePriv = priv->interfacePriv[interfaceTag];
-            break;
-        }
-    }
-
-    if (interfacePriv == NULL) {
-        /* No match found - error */
-        interfaceTag = 0;
-        interfacePriv = priv->interfacePriv[interfaceTag];
-        unifi_warning(priv, "Mac address not matching ... debugging needed\n");
-        interfacePriv->stats.tx_dropped++;
-        kfree_skb(skb);
-        return -1;
-    }
-
-    /* Add a SNAP header if necessary */
-    if (skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto) != 0) {
-        /* convert failed */
-        unifi_error(priv, "skb_add_llc_snap failed.\n");
-        kfree_skb(skb);
-        return -1;
-    }
-
-    bulkdata.d[0].os_data_ptr = skb->data;
-    bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
-    bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len;
-    bulkdata.d[1].os_data_ptr = NULL;
-    bulkdata.d[1].os_net_buf_ptr = NULL;
-    bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
-
-#ifdef CSR_SUPPORT_SME
-    /* Notify the TA module for the Tx frame  for non AP/P2PGO mode*/
-    if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) &&
-        (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) {
-        unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX,
-                        &bulkdata.d[0], ehdr->h_source,
-                        priv->netdev[interfaceTag]->dev_addr,
-                        jiffies_to_msecs(jiffies),
-                        0);     /* rate is unknown on tx */
-    }
-#endif /* CSR_SUPPORT_SME */
-
-    if ((proto == ETH_P_PAE)
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-            || (proto == ETH_P_WAI)
-#endif
-       )
-    {
-        /* check for m4 detection */
-        if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) {
-            eapolStore = TRUE;
-        }
-    }
-
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-    if (proto == ETH_P_WAI)
-     {
-        protection = 0; /*WAI packets always sent unencrypted*/
-     }
-   else
-     {
-#endif
-#ifdef CSR_SUPPORT_SME
-    if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, ehdr->h_dest)) < 0) {
-        unifi_warning(priv, "unicast address, but destination not in station record database\n");
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-        return -1;
-    }
-#else
-    protection = 0;
-#endif
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-   }
-#endif
-
-    /* append Mac header for Eapol as well as data packet */
-    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, ehdr->h_dest, ehdr->h_source, protection)) {
-        unifi_error(priv, "failed to create MAC header\n");
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-        return -1;
-    }
-
-    /* RA address must contain the immediate destination MAC address that is similar to
-     * the Address 1 field of 802.11 Mac header here 4 is: (sizeof(framecontrol) + sizeof (durationID))
-     * which is address 1 field
-     */
-    memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
-
-    unifi_trace(priv, UDBG5, "RA[0]=%x, RA[1]=%x, RA[2]=%x, RA[3]=%x, RA[4]=%x, RA[5]=%x\n",
-                peerAddress.a[0],peerAddress.a[1], peerAddress.a[2], peerAddress.a[3],
-                peerAddress.a[4],peerAddress.a[5]);
-
-
-    if ((proto == ETH_P_PAE)
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-            || (proto == ETH_P_WAI)
-#endif
-       )
-    {
-        CSR_SIGNAL signal;
-        CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
-
-        /* initialize signal to zero */
-        memset(&signal, 0, sizeof(CSR_SIGNAL));
-
-        /* Frame MA_PACKET request */
-        signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
-        signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
-        signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
-
-        transmissionControl = req->TransmissionControl = 0;
-#ifdef CSR_SUPPORT_SME
-        if (eapolStore)
-        {
-            netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);
-
-            /* Fill the MA-PACKET.req */
-
-            req->Priority = priority;
-            unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);
-
-            /* rate selected by firmware */
-            req->TransmitRate = 0;
-            req->HostTag = CSR_WIFI_EAPOL_M4_HOST_TAG;
-            /* RA address matching with address 1 of Mac header */
-            memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
-
-            spin_lock(&priv->m4_lock);
-            /* Store the M4-PACKET.req for later */
-            interfacePriv->m4_signal = signal;
-            interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
-            interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length;
-            interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
-            interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
-            spin_unlock(&priv->m4_lock);
-
-            /* Signal the workqueue to call CsrWifiRouterCtrlM4ReadyToSendIndSend().
-             * It cannot be called directly from the tx path because it
-             * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
-             */
-            queue_work(priv->unifi_workqueue, &netpriv->send_m4_ready_task);
-
-            return 0;
-        }
-#endif
-    }/*EAPOL or WAI packet*/
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-    if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) && \
-        (priv->wapi_unicast_filter) && \
-        (proto != ETH_P_PAE) && \
-        (proto != ETH_P_WAI) && \
-        (skb->len > 0))
-    {
-        CSR_SIGNAL signal;
-        CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
-        netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);
-
-        unifi_trace(priv, UDBG4, "send_ma_pkt_request() - WAPI unicast data packet when USKID = 1 \n");
-
-        /* initialize signal to zero */
-        memset(&signal, 0, sizeof(CSR_SIGNAL));
-        /* Frame MA_PACKET request */
-        signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
-        signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
-        signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
-
-        /* Fill the MA-PACKET.req */
-        req->TransmissionControl = 0;
-        req->Priority = priority;
-        unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);
-        req->TransmitRate = (CSR_RATE) 0; /* rate selected by firmware */
-        req->HostTag = 0xffffffff;        /* Ask for a new HostTag */
-        /* RA address matching with address 1 of Mac header */
-        memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
-
-        /* Store the M4-PACKET.req for later */
-        spin_lock(&priv->wapi_lock);
-        interfacePriv->wapi_unicast_ma_pkt_sig = signal;
-        interfacePriv->wapi_unicast_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
-        interfacePriv->wapi_unicast_bulk_data.data_length = bulkdata.d[0].data_length;
-        interfacePriv->wapi_unicast_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
-        interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
-        spin_unlock(&priv->wapi_lock);
-
-        /* Signal the workqueue to call CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend().
-         * It cannot be called directly from the tx path because it
-         * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
-         */
-        queue_work(priv->unifi_workqueue, &netpriv->send_pkt_to_encrypt);
-
-        return 0;
-    }
-#endif
-
-    if(priv->cmanrTestMode)
-    {
-        TransmitRate = priv->cmanrTestModeTransmitRate;
-        unifi_trace(priv, UDBG2, "send_ma_pkt_request: cmanrTestModeTransmitRate = %d TransmitRate=%d\n",
-                    priv->cmanrTestModeTransmitRate,
-                    TransmitRate
-                   );
-    }
-
-    /* Send UniFi msg */
-    /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
-    r = uf_process_ma_packet_req(priv,
-                                 peerAddress.a,
-                                 0xffffffff,  /* Ask for a new HostTag */
-                                 interfaceTag,
-                                 transmissionControl,
-                                 TransmitRate,
-                                 priority,
-                                 priv->netdev_client->sender_id,
-                                 &bulkdata);
-
-    if (r) {
-        unifi_trace(priv, UDBG1, "(HIP validation failure) r = %x\n", r);
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-        return -1;
-    }
-
-    unifi_trace(priv, UDBG3, "leaving send_ma_pkt_request, UNITDATA result code = %d\n", r);
-
-    return r;
-} /* send_ma_pkt_request() */
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_net_xmit
- *
- *      This function is called by the higher level stack to transmit an
- *      ethernet packet.
- *
- *  Arguments:
- *      skb     Ethernet packet to send.
- *      dev     Pointer to the linux net device.
- *
- *  Returns:
- *      0   on success (packet was consumed, not necessarily transmitted)
- *      1   if packet was requeued
- *     -1   on error
- *
- *
- *  Notes:
- *      The controlled port is handled in the qdisc dequeue handler.
- * ---------------------------------------------------------------------------
- */
-static netdev_tx_t
-uf_net_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct ethhdr ehdr;
-    int proto, port;
-    int result;
-    static tx_signal_handler tx_handler;
-    CSR_PRIORITY priority;
-    CsrWifiRouterCtrlPortAction port_action;
-
-    unifi_trace(priv, UDBG5, "unifi_net_xmit: skb = %x\n", skb);
-
-    memcpy(&ehdr, skb->data, ETH_HLEN);
-    proto = ntohs(ehdr.h_proto);
-    priority = get_packet_priority(priv, skb, &ehdr, interfacePriv);
-
-    /* All frames are sent as MA-PACKET.req (EAPOL also) */
-    tx_handler = send_ma_pkt_request;
-
-    /* 802.1x - apply controlled/uncontrolled port rules */
-    if ((proto != ETH_P_PAE)
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-            && (proto != ETH_P_WAI)
-#endif
-       ) {
-        port = UF_CONTROLLED_PORT_Q;
-    } else {
-        /* queue 4 */
-        port = UF_UNCONTROLLED_PORT_Q;
-    }
-
-    /* Uncontrolled port rules apply */
-    port_action = verify_port(priv
-        , (((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode)||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI== interfacePriv->interfaceMode))? interfacePriv->bssid.a: ehdr.h_dest)
-        , port
-        , interfacePriv->InterfaceTag);
-
-    if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
-        unifi_trace(priv, UDBG5,
-                    "uf_net_xmit: %s controlled port open\n",
-                    port ? "" : "un");
-        /* Remove the ethernet header */
-        skb_pull(skb, ETH_HLEN);
-        result = tx_handler(priv, skb, &ehdr, priority);
-    } else {
-
-        /* Discard the packet if necessary */
-        unifi_trace(priv, UDBG2,
-                "uf_net_xmit: %s controlled port %s\n",
-                port ? "" : "un", port_action==CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK ? "blocked" : "closed");
-        interfacePriv->stats.tx_dropped++;
-        kfree_skb(skb);
-
-        return NETDEV_TX_OK;
-    }
-
-    if (result == NETDEV_TX_OK) {
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-    	/* Don't update the tx stats when the pkt is to be sent for sw encryption*/
-    	if (!((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
-              (priv->wapi_unicast_filter == 1)))
-        {
-            dev->trans_start = jiffies;
-            /* Should really count tx stats in the UNITDATA.status signal but
-             * that doesn't have the length.
-             */
-            interfacePriv->stats.tx_packets++;
-            /* count only the packet payload */
-            interfacePriv->stats.tx_bytes += skb->len;
-
-        }
-#else
-    	dev->trans_start = jiffies;
-
-        /*
-         * Should really count tx stats in the UNITDATA.status signal but
-         * that doesn't have the length.
-         */
-        interfacePriv->stats.tx_packets++;
-        /* count only the packet payload */
-        interfacePriv->stats.tx_bytes += skb->len;
-#endif
-    } else if (result < 0) {
-
-        /* Failed to send: fh queue was full, and the skb was discarded.
-         * Return OK to indicate that the buffer was consumed, to stop the
-         * kernel re-transmitting the freed buffer.
-         */
-        interfacePriv->stats.tx_dropped++;
-        unifi_trace(priv, UDBG1, "unifi_net_xmit: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
-        result = NETDEV_TX_OK;
-    }
-
-    /* The skb will have been freed by send_XXX_request() */
-
-    return result;
-} /* uf_net_xmit() */
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_pause_xmit
- *  unifi_restart_xmit
- *
- *      These functions are called from the UniFi core to control the flow
- *      of packets from the upper layers.
- *      unifi_pause_xmit() is called when the internal queue is full and
- *      should take action to stop unifi_ma_unitdata() being called.
- *      When the queue has drained, unifi_restart_xmit() will be called to
- *      re-enable the flow of packets for transmission.
- *
- *  Arguments:
- *      ospriv          OS private context pointer.
- *
- *  Returns:
- *      unifi_pause_xmit() is called from interrupt context.
- * ---------------------------------------------------------------------------
- */
-void
-unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue)
-{
-    unifi_priv_t *priv = ospriv;
-    int i; /* used as a loop counter */
-
-    unifi_trace(priv, UDBG2, "Stopping queue %d\n", queue);
-
-    for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
-    {
-        if (netif_running(priv->netdev[i]))
-        {
-            netif_stop_subqueue(priv->netdev[i], (u16)queue);
-        }
-    }
-
-#ifdef CSR_SUPPORT_SME
-    if(queue<=3) {
-        routerStartBuffering(priv,queue);
-        unifi_trace(priv,UDBG2,"Start buffering %d\n", queue);
-     } else {
-        routerStartBuffering(priv,0);
-        unifi_error(priv, "Start buffering %d defaulting to 0\n", queue);
-     }
-#endif
-
-} /* unifi_pause_xmit() */
-
-void
-unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue)
-{
-    unifi_priv_t *priv = ospriv;
-    int i=0; /* used as a loop counter */
-
-    unifi_trace(priv, UDBG2, "Waking queue %d\n", queue);
-
-    for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
-    {
-        if (netif_running(priv->netdev[i]))
-        {
-            netif_wake_subqueue(priv->netdev[i], (u16)queue);
-        }
-    }
-
-#ifdef CSR_SUPPORT_SME
-    if(queue <=3) {
-        routerStopBuffering(priv,queue);
-        uf_send_buffered_frames(priv,queue);
-    } else {
-        routerStopBuffering(priv,0);
-        uf_send_buffered_frames(priv,0);
-    }
-#endif
-} /* unifi_restart_xmit() */
-
-
-static void
-indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_buff *skb, CSR_SIGNAL *signal,
-                bulk_data_param_t *bulkdata)
-{
-    int r, sr = 0;
-    struct net_device *dev;
-
-#ifdef CSR_SUPPORT_SME
-    llc_snap_hdr_t *snap;
-
-    snap = (llc_snap_hdr_t *)skb->data;
-
-    sr = _identify_sme_ma_pkt_ind(priv,
-                                  snap->oui, ntohs(snap->protocol),
-                                  signal,
-                                  bulkdata,
-                                  dst_a, src_a );
-#endif
-
-    /*
-     * Decapsulate any SNAP header and
-     * prepend an ethernet header so that the skb manipulation and ARP
-     * stuff works.
-     */
-    r = skb_80211_to_ether(priv, skb, dst_a, src_a,
-                           signal, bulkdata);
-    if (r == -1) {
-        /* Drop the packet and return */
-        priv->interfacePriv[ifTag]->stats.rx_errors++;
-        priv->interfacePriv[ifTag]->stats.rx_frame_errors++;
-        unifi_net_data_free(priv, &bulkdata->d[0]);
-        unifi_notice(priv, "indicate_rx_skb: Discard unknown frame.\n");
-        return;
-    }
-
-    /* Handle the case where packet is sent up through the subscription
-     * API but should not be given to the network stack (AMP PAL case)
-     * LLC header is different from WiFi and the packet has been subscribed for
-     */
-    if (r == 1 && sr == 1) {
-        unifi_net_data_free(priv, &bulkdata->d[0]);
-        unifi_trace(priv, UDBG5, "indicate_rx_skb: Data given to subscription"
-                "API, not being given to kernel\n");
-        return;
-    }
-
-    dev = priv->netdev[ifTag];
-    /* Now we look like a regular ethernet frame */
-    /* Fill in SKB meta data */
-    skb->dev = dev;
-    skb->protocol = eth_type_trans(skb, dev);
-    skb->ip_summed = CHECKSUM_UNNECESSARY;
-
-    /* Test for an overlength frame */
-    if (skb->len > (dev->mtu + ETH_HLEN)) {
-        /* A bogus length ethfrm has been encap'd. */
-        /* Is someone trying an oflow attack? */
-        unifi_error(priv, "%s: oversize frame (%d > %d)\n",
-                    dev->name,
-                    skb->len, dev->mtu + ETH_HLEN);
-
-        /* Drop the packet and return */
-        priv->interfacePriv[ifTag]->stats.rx_errors++;
-        priv->interfacePriv[ifTag]->stats.rx_length_errors++;
-        unifi_net_data_free(priv, &bulkdata->d[0]);
-        return;
-    }
-
-
-    if(priv->cmanrTestMode)
-    {
-        const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
-        priv->cmanrTestModeTransmitRate = pkt_ind->ReceivedRate;
-        unifi_trace(priv, UDBG2, "indicate_rx_skb: cmanrTestModeTransmitRate=%d\n", priv->cmanrTestModeTransmitRate);
-    }
-
-    /* Pass SKB up the stack */
-#ifdef CSR_WIFI_USE_NETIF_RX
-        netif_rx(skb);
-#else
-        netif_rx_ni(skb);
-#endif
-
-    if (dev != NULL) {
-        dev->last_rx = jiffies;
-    }
-
-    /* Bump rx stats */
-    priv->interfacePriv[ifTag]->stats.rx_packets++;
-    priv->interfacePriv[ifTag]->stats.rx_bytes += bulkdata->d[0].data_length;
-
-    return;
-}
-
-void
-uf_process_rx_pending_queue(unifi_priv_t *priv, int queue,
-                            CsrWifiMacAddress source_address,
-                            int indicate, u16 interfaceTag)
-{
-    rx_buffered_packets_t *rx_q_item;
-    struct list_head *rx_list;
-    struct list_head *n;
-    struct list_head *l_h;
-    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "uf_process_rx_pending_queue bad interfaceTag\n");
-        return;
-    }
-
-    if (queue == UF_CONTROLLED_PORT_Q) {
-        rx_list = &interfacePriv->rx_controlled_list;
-    } else {
-        rx_list = &interfacePriv->rx_uncontrolled_list;
-    }
-
-    down(&priv->rx_q_sem);
-    list_for_each_safe(l_h, n, rx_list) {
-        rx_q_item = list_entry(l_h, rx_buffered_packets_t, q);
-
-        /* Validate against the source address */
-        if (memcmp(broadcast_address.a, source_address.a, ETH_ALEN) &&
-                memcmp(rx_q_item->sa.a, source_address.a, ETH_ALEN)) {
-
-            unifi_trace(priv, UDBG2,
-                        "uf_process_rx_pending_queue: Skipping sa=%02X%02X%02X%02X%02X%02X skb=%p, bulkdata=%p\n",
-                        rx_q_item->sa.a[0], rx_q_item->sa.a[1],
-                        rx_q_item->sa.a[2], rx_q_item->sa.a[3],
-                        rx_q_item->sa.a[4], rx_q_item->sa.a[5],
-                        rx_q_item->skb, &rx_q_item->bulkdata.d[0]);
-            continue;
-        }
-
-        list_del(l_h);
-
-
-        unifi_trace(priv, UDBG2,
-                    "uf_process_rx_pending_queue: Was Blocked skb=%p, bulkdata=%p\n",
-                    rx_q_item->skb, &rx_q_item->bulkdata);
-
-        if (indicate) {
-            indicate_rx_skb(priv, interfaceTag, rx_q_item->da.a, rx_q_item->sa.a, rx_q_item->skb, &rx_q_item->signal, &rx_q_item->bulkdata);
-        } else {
-            interfacePriv->stats.rx_dropped++;
-            unifi_net_data_free(priv, &rx_q_item->bulkdata.d[0]);
-        }
-
-        /* It is our resposibility to free the Rx structure object. */
-        kfree(rx_q_item);
-    }
-    up(&priv->rx_q_sem);
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_resume_data_plane
- *
- *      Is called when the (un)controlled port is set to open,
- *      to notify the network stack to schedule for transmission
- *      any packets queued in the qdisk while port was closed and
- *      indicated to the stack any packets buffered in the Rx queues.
- *
- *  Arguments:
- *      priv        Pointer to device private struct
- *
- *  Returns:
- * ---------------------------------------------------------------------------
- */
-void
-uf_resume_data_plane(unifi_priv_t *priv, int queue,
-                     CsrWifiMacAddress peer_address,
-                     u16 interfaceTag)
-{
-#ifdef CSR_SUPPORT_WEXT
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-#endif
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "uf_resume_data_plane bad interfaceTag\n");
-        return;
-    }
-
-    unifi_trace(priv, UDBG2, "Resuming netif\n");
-
-    /*
-     * If we are waiting for the net device to enter the up state, don't
-     * process the rx queue yet as it will be done by the callback when
-     * the device is ready.
-     */
-#ifdef CSR_SUPPORT_WEXT
-    if (!interfacePriv->wait_netdev_change)
-#endif
-    {
-#ifdef CONFIG_NET_SCHED
-        if (netif_running(priv->netdev[interfaceTag])) {
-            netif_tx_schedule_all(priv->netdev[interfaceTag]);
-        }
-#endif
-        uf_process_rx_pending_queue(priv, queue, peer_address, 1,interfaceTag);
-    }
-} /* uf_resume_data_plane() */
-
-
-void uf_free_pending_rx_packets(unifi_priv_t *priv, int queue, CsrWifiMacAddress peer_address,u16 interfaceTag)
-{
-    uf_process_rx_pending_queue(priv, queue, peer_address, 0,interfaceTag);
-
-} /* uf_free_pending_rx_packets() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_rx
- *
- *      Reformat a UniFi data received packet into a p80211 packet and
- *      pass it up the protocol stack.
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void
-unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
-{
-    u16 interfaceTag;
-    bulk_data_desc_t *pData;
-    const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
-    struct sk_buff *skb;
-    CsrWifiRouterCtrlPortAction port_action;
-    u8 dataFrameType;
-    int proto;
-    int queue;
-
-    u8 da[ETH_ALEN], sa[ETH_ALEN];
-    u8 toDs, fromDs, frameType, macHeaderLengthInBytes = MAC_HEADER_SIZE;
-    u16 frameControl;
-    netInterface_priv_t *interfacePriv;
-    struct ethhdr ehdr;
-
-    interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    /* Sanity check that the VIF refers to a sensible interface */
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
-    {
-        unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
-        unifi_net_data_free(priv,&bulkdata->d[0]);
-        return;
-    }
-
-    /* Sanity check that the VIF refers to an allocated netdev */
-    if (!interfacePriv->netdev_registered)
-    {
-        unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
-        unifi_net_data_free(priv, &bulkdata->d[0]);
-        return;
-    }
-
-    if (bulkdata->d[0].data_length == 0) {
-        unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
-        unifi_net_data_free(priv,&bulkdata->d[0]);
-        return;
-    }
-
-
-    skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
-    skb->len = bulkdata->d[0].data_length;
-
-    /* Point to the addresses */
-    toDs = (skb->data[1] & 0x01) ? 1 : 0;
-    fromDs = (skb->data[1] & 0x02) ? 1 : 0;
-
-    memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */
-    memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */
-
-
-    pData = &bulkdata->d[0];
-    frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr);
-    frameType = ((frameControl & 0x000C) >> 2);
-
-    dataFrameType =((frameControl & 0x00f0) >> 4);
-    unifi_trace(priv, UDBG6,
-                "%s: Receive Data Frame Type %d \n", __FUNCTION__,dataFrameType);
-
-    switch(dataFrameType)
-    {
-        case QOS_DATA:
-        case QOS_DATA_NULL:
-            /* If both are set then the Address4 exists (only for AP) */
-            if (fromDs && toDs)
-            {
-                /* 6 is the size of Address4 field */
-                macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6);
-            }
-            else
-            {
-                macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
-            }
-
-            /* If order bit set then HT control field is the part of MAC header */
-            if (frameControl & FRAME_CONTROL_ORDER_BIT)
-                macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE;
-            break;
-        default:
-            if (fromDs && toDs)
-                macHeaderLengthInBytes += 6;
-    }
-
-    /* Prepare the ethernet header from snap header of skb data */
-    switch(dataFrameType)
-    {
-        case DATA_NULL:
-        case QOS_DATA_NULL:
-            /* This is for only queue info fetching, EAPOL wont come as
-             * null data so the proto is initialized as zero
-             */
-            proto = 0x0;
-            break;
-        default:
-            {
-                llc_snap_hdr_t *snap;
-                /* Fetch a snap header to find protocol (for IPV4/IPV6 packets
-                 * the snap header fetching offset is same)
-                 */
-                snap = (llc_snap_hdr_t *) (skb->data + macHeaderLengthInBytes);
-
-                /* prepare the ethernet header from the snap header & addresses */
-                ehdr.h_proto = snap->protocol;
-                memcpy(ehdr.h_dest, da, ETH_ALEN);
-                memcpy(ehdr.h_source, sa, ETH_ALEN);
-            }
-            proto = ntohs(ehdr.h_proto);
-    }
-    unifi_trace(priv, UDBG3, "in unifi_rx protocol from snap header = 0x%x\n", proto);
-
-    if ((proto != ETH_P_PAE)
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-            && (proto != ETH_P_WAI)
-#endif
-       ) {
-        queue = UF_CONTROLLED_PORT_Q;
-    } else {
-        queue = UF_UNCONTROLLED_PORT_Q;
-    }
-
-    port_action = verify_port(priv, (unsigned char*)sa, queue, interfaceTag);
-    unifi_trace(priv, UDBG3, "in unifi_rx port action is = 0x%x & queue = %x\n", port_action, queue);
-
-#ifdef CSR_SUPPORT_SME
-    /* Notify the TA module for the Rx frame for non P2PGO and AP cases*/
-    if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) &&
-            (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))
-    {
-        /* Remove MAC header of length(macHeaderLengthInBytes) before sampling */
-        skb_pull(skb, macHeaderLengthInBytes);
-        pData->os_data_ptr = skb->data;
-        pData->data_length -= macHeaderLengthInBytes;
-
-        if (pData->data_length) {
-            unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX,
-                            &bulkdata->d[0],
-                            sa, priv->netdev[interfaceTag]->dev_addr,
-                            jiffies_to_msecs(jiffies),
-                            pkt_ind->ReceivedRate);
-        }
-    } else {
-
-        /* AP/P2PGO specific handling here */
-        CsrWifiRouterCtrlStaInfo_t * srcStaInfo =
-            CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag);
-
-        /* Defensive check only; Source address is already checked in
-        process_ma_packet_ind and we should have a valid source address here */
-
-         if(srcStaInfo == NULL) {
-            CsrWifiMacAddress peerMacAddress;
-            /* Unknown data PDU */
-            memcpy(peerMacAddress.a,sa,ETH_ALEN);
-            unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__,
-            sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
-            CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-            return;
-        }
-
-       /* For AP GO mode, don't store the PDUs */
-        if (port_action != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
-            /* Drop the packet and return */
-            CsrWifiMacAddress peerMacAddress;
-            memcpy(peerMacAddress.a,sa,ETH_ALEN);
-            unifi_trace(priv, UDBG3, "%s: Port is not open: unexpected frame from peer = %x:%x:%x:%x:%x:%x\n",
-                        __FUNCTION__, sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
-
-            CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
-            interfacePriv->stats.rx_dropped++;
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-            unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__,
-                         proto, queue ? "Controlled" : "Un-controlled");
-            return;
-        }
-
-         /* Qos NULL/Data NULL  are freed here and not processed further */
-        if((dataFrameType == QOS_DATA_NULL) || (dataFrameType == DATA_NULL)){
-            unifi_trace(priv, UDBG5, "%s: Null Frame Received and Freed\n", __FUNCTION__);
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-            return;
-        }
-
-        /* Now we have done with MAC header so proceed with the real data part*/
-        /* This function takes care of appropriate routing for AP/P2PGO case*/
-        /* the function hadnles following things
-           2. Routing the PDU to appropriate location
-           3. Error case handling
-           */
-        if(!(uf_ap_process_data_pdu(priv, skb, &ehdr, srcStaInfo,
-             signal,
-             bulkdata,
-             macHeaderLengthInBytes)))
-        {
-            return;
-        }
-        unifi_trace(priv, UDBG5, "unifi_rx: no specific AP handling process as normal frame, MAC Header len %d\n",macHeaderLengthInBytes);
-        /* Remove the MAC header for subsequent conversion */
-        skb_pull(skb, macHeaderLengthInBytes);
-        pData->os_data_ptr = skb->data;
-        pData->data_length -= macHeaderLengthInBytes;
-        pData->os_net_buf_ptr = (unsigned char*)skb;
-        pData->net_buf_length = skb->len;
-    }
-#endif /* CSR_SUPPORT_SME */
-
-
-    /* Now that the MAC header is removed, null-data frames have zero length
-     * and can be dropped
-     */
-    if (pData->data_length == 0) {
-        if (((frameControl & 0x00f0) >> 4) != QOS_DATA_NULL &&
-            ((frameControl & 0x00f0) >> 4) != DATA_NULL) {
-            unifi_trace(priv, UDBG1, "Zero length frame, but not null-data %04x\n", frameControl);
-        }
-        unifi_net_data_free(priv, &bulkdata->d[0]);
-        return;
-    }
-
-    if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
-        /* Drop the packet and return */
-        interfacePriv->stats.rx_dropped++;
-        unifi_net_data_free(priv, &bulkdata->d[0]);
-        unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n",
-                     __FUNCTION__, proto, queue ? "controlled" : "uncontrolled");
-        return;
-    } else if ( (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK) ||
-                   (interfacePriv->connected != UnifiConnected) ) {
-
-        /* Buffer the packet into the Rx queues */
-        rx_buffered_packets_t *rx_q_item;
-        struct list_head *rx_list;
-
-        rx_q_item = kmalloc(sizeof(rx_buffered_packets_t),
-                GFP_KERNEL);
-        if (rx_q_item == NULL) {
-            unifi_error(priv, "%s: Failed to allocate %d bytes for rx packet record\n",
-                        __FUNCTION__, sizeof(rx_buffered_packets_t));
-            interfacePriv->stats.rx_dropped++;
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-            return;
-        }
-
-        INIT_LIST_HEAD(&rx_q_item->q);
-        rx_q_item->bulkdata = *bulkdata;
-        rx_q_item->skb = skb;
-        rx_q_item->signal = *signal;
-        memcpy(rx_q_item->sa.a, sa, ETH_ALEN);
-        memcpy(rx_q_item->da.a, da, ETH_ALEN);
-        unifi_trace(priv, UDBG2, "%s: Blocked skb=%p, bulkdata=%p\n",
-                    __FUNCTION__, rx_q_item->skb, &rx_q_item->bulkdata);
-
-        if (queue == UF_CONTROLLED_PORT_Q) {
-            rx_list = &interfacePriv->rx_controlled_list;
-        } else {
-            rx_list = &interfacePriv->rx_uncontrolled_list;
-        }
-
-        /* Add to tail of packets queue */
-        down(&priv->rx_q_sem);
-        list_add_tail(&rx_q_item->q, rx_list);
-        up(&priv->rx_q_sem);
-
-        return;
-
-    }
-
-    indicate_rx_skb(priv, interfaceTag, da, sa, skb, signal, bulkdata);
-
-} /* unifi_rx() */
-
-static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
-{
-    u16 interfaceTag;
-    const CSR_MA_PACKET_CONFIRM *pkt_cfm = &signal->u.MaPacketConfirm;
-    netInterface_priv_t *interfacePriv;
-
-    interfaceTag = (pkt_cfm->VirtualInterfaceIdentifier & 0xff);
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    /* Sanity check that the VIF refers to a sensible interface */
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
-    {
-        unifi_error(priv, "%s: MA-PACKET confirm with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
-        return;
-    }
-#ifdef CSR_SUPPORT_SME
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-
-        uf_process_ma_pkt_cfm_for_ap(priv,interfaceTag,pkt_cfm);
-    } else if (interfacePriv->m4_sent && (pkt_cfm->HostTag == interfacePriv->m4_hostTag)) {
-        /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/
-        CsrResult result = pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE;
-        CsrWifiMacAddress peerMacAddress;
-        memcpy(peerMacAddress.a, interfacePriv->m4_signal.u.MaPacketRequest.Ra.x, ETH_ALEN);
-
-        unifi_trace(priv, UDBG1, "%s: Sending M4 Transmit CFM\n", __FUNCTION__);
-        CsrWifiRouterCtrlM4TransmittedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0,
-                                              interfaceTag,
-                                              peerMacAddress,
-                                              result);
-        interfacePriv->m4_sent = FALSE;
-        interfacePriv->m4_hostTag = 0xffffffff;
-    }
-#endif
-    return;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_rx
- *
- *      Reformat a UniFi data received packet into a p80211 packet and
- *      pass it up the protocol stack.
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
-{
-    u16 interfaceTag;
-    bulk_data_desc_t *pData;
-    CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication;
-    struct sk_buff *skb;
-    u16 frameControl;
-    netInterface_priv_t *interfacePriv;
-    u8 da[ETH_ALEN], sa[ETH_ALEN];
-    u8 *bssid = NULL, *ba_addr = NULL;
-    u8 toDs, fromDs, frameType;
-    u8 i =0;
-
-#ifdef CSR_SUPPORT_SME
-    u8 dataFrameType = 0;
-    u8 powerSaveChanged = FALSE;
-    u8 pmBit = 0;
-    CsrWifiRouterCtrlStaInfo_t *srcStaInfo = NULL;
-    u16 qosControl;
-
-#endif
-
-    interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-
-    /* Sanity check that the VIF refers to a sensible interface */
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
-    {
-        unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
-        unifi_net_data_free(priv,&bulkdata->d[0]);
-        return;
-    }
-
-    /* Sanity check that the VIF refers to an allocated netdev */
-    if (!interfacePriv->netdev_registered)
-    {
-        unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
-        unifi_net_data_free(priv, &bulkdata->d[0]);
-        return;
-    }
-
-    if (bulkdata->d[0].data_length == 0) {
-        unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
-        unifi_net_data_free(priv,&bulkdata->d[0]);
-        return;
-    }
-    /* For monitor mode we need to pass this indication to the registered application
-    handle this separately*/
-    /* MIC failure is already taken care of so no need to send the PDUs which are not successfully received in non-monitor mode*/
-    if(pkt_ind->ReceptionStatus != CSR_RX_SUCCESS)
-    {
-        unifi_warning(priv, "%s: MA-PACKET indication with status = %d\n",__FUNCTION__, pkt_ind->ReceptionStatus);
-        unifi_net_data_free(priv,&bulkdata->d[0]);
-        return;
-    }
-
-
-    skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
-    skb->len = bulkdata->d[0].data_length;
-
-    /* Point to the addresses */
-    toDs = (skb->data[1] & 0x01) ? 1 : 0;
-    fromDs = (skb->data[1] & 0x02) ? 1 : 0;
-
-    memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */
-    memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */
-
-    /* Find the BSSID, which will be used to match the BA session */
-    if (toDs && fromDs)
-    {
-        unifi_trace(priv, UDBG6, "4 address frame - don't try to find BSSID\n");
-        bssid = NULL;
-    }
-    else
-    {
-        bssid = (u8 *) (skb->data + 4 + 12 - (fromDs * 6) - (toDs * 12));
-    }
-
-    pData = &bulkdata->d[0];
-    frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr);
-    frameType = ((frameControl & 0x000C) >> 2);
-
-    unifi_trace(priv, UDBG3, "Rx Frame Type: %d sn: %d\n",frameType,
-         (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff);
-    if(frameType == IEEE802_11_FRAMETYPE_CONTROL){
-#ifdef CSR_SUPPORT_SME
-        unifi_trace(priv, UDBG6, "%s: Received Control Frame\n", __FUNCTION__);
-
-        if((frameControl & 0x00f0) == 0x00A0){
-            /* This is a PS-POLL request */
-            u8 pmBit = (frameControl & 0x1000)?0x01:0x00;
-            unifi_trace(priv, UDBG6, "%s: Received PS-POLL Frame\n", __FUNCTION__);
-
-            uf_process_ps_poll(priv,sa,da,pmBit,interfaceTag);
-        }
-        else {
-            unifi_warning(priv, "%s: Non PS-POLL control frame is received\n", __FUNCTION__);
-        }
-#endif
-        unifi_net_data_free(priv,&bulkdata->d[0]);
-        return;
-    }
-    if(frameType != IEEE802_11_FRAMETYPE_DATA) {
-        unifi_warning(priv, "%s: Non control Non Data frame is received\n",__FUNCTION__);
-        unifi_net_data_free(priv,&bulkdata->d[0]);
-        return;
-    }
-
-#ifdef CSR_SUPPORT_SME
-    if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
-       (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)){
-
-        srcStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag);
-
-        if(srcStaInfo == NULL) {
-            CsrWifiMacAddress peerMacAddress;
-            /* Unknown data PDU */
-            memcpy(peerMacAddress.a,sa,ETH_ALEN);
-            unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__,
-            sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
-            CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-            return;
-        }
-
-        /*
-        verify power management bit here so as to ensure host and unifi are always
-        in sync with power management status of peer.
-
-        If we do it later, it may so happen we have stored the frame in BA re-ordering
-        buffer and hence host and unifi are out of sync for power management status
-        */
-
-        pmBit = (frameControl & 0x1000)?0x01:0x00;
-        powerSaveChanged = uf_process_pm_bit_for_peer(priv,srcStaInfo,pmBit,interfaceTag);
-
-        /* Update station last activity time */
-        srcStaInfo->activity_flag = TRUE;
-
-        /* For Qos Frame if PM bit is toggled to indicate the change in power save state then it shall not be
-        considered as Trigger Frame. Enter only if WMM STA and peer is in Power save */
-
-        dataFrameType = ((frameControl & 0x00f0) >> 4);
-
-        if((powerSaveChanged == FALSE)&&(srcStaInfo->wmmOrQosEnabled == TRUE)&&
-        (srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)){
-
-            if((dataFrameType == QOS_DATA) || (dataFrameType == QOS_DATA_NULL)){
-
-                /*
-                 * QoS control field is offset from frame control by 2 (frame control)
-                 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
-                 */
-                if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
-                    qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 30);
-                }
-                else{
-                    qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 24);
-                }
-                unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl);
-                uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag);
-            }
-        }
-    }
-
-#endif
-
-    if( ((frameControl & 0x00f0) >> 4) == QOS_DATA) {
-        u8 *qos_control_ptr = (u8*)bulkdata->d[0].os_data_ptr + (((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK))?30: 24);
-        int tID = *qos_control_ptr & IEEE802_11_QC_TID_MASK; /* using ls octet of qos control */
-        ba_session_rx_struct *ba_session;
-        u8 ba_session_idx = 0;
-        /* Get the BA originator address */
-        if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-           interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO){
-            ba_addr = sa;
-        }else{
-            ba_addr = bssid;
-        }
-
-        down(&priv->ba_mutex);
-        for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
-            ba_session = interfacePriv->ba_session_rx[ba_session_idx];
-            if (ba_session){
-                unifi_trace(priv, UDBG6, "found ba_session=0x%x ba_session_idx=%d", ba_session, ba_session_idx);
-                if ((!memcmp(ba_session->macAddress.a, ba_addr, ETH_ALEN)) && (ba_session->tID == tID)){
-                        frame_desc_struct frame_desc;
-                        frame_desc.bulkdata = *bulkdata;
-                        frame_desc.signal = *signal;
-                        frame_desc.sn = (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff;
-                        frame_desc.active = TRUE;
-                        unifi_trace(priv, UDBG6, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__, ba_session_idx);
-                        process_ba_frame(priv, interfacePriv, ba_session, &frame_desc);
-                        up(&priv->ba_mutex);
-                        process_ba_complete(priv, interfacePriv);
-                        break;
-                }
-            }
-        }
-        if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
-            up(&priv->ba_mutex);
-            unifi_trace(priv, UDBG6, "%s: calling process_amsdu()", __FUNCTION__);
-            process_amsdu(priv, signal, bulkdata);
-        }
-    } else {
-        unifi_trace(priv, UDBG6, "calling unifi_rx()");
-        unifi_rx(priv, signal, bulkdata);
-    }
-
-    /* check if the frames in reorder buffer has aged, the check
-     * is done after receive processing so that if the missing frame
-     * has arrived in this receive process, then it is handled cleanly.
-     *
-     * And also this code here takes care that timeout check is made for all
-     * the receive indications
-     */
-    down(&priv->ba_mutex);
-    for (i=0; i < MAX_SUPPORTED_BA_SESSIONS_RX; i++){
-        ba_session_rx_struct *ba_session;
-        ba_session = interfacePriv->ba_session_rx[i];
-            if (ba_session){
-                check_ba_frame_age_timeout(priv, interfacePriv, ba_session);
-            }
-    }
-    up(&priv->ba_mutex);
-    process_ba_complete(priv, interfacePriv);
-
-}
-/*
- * ---------------------------------------------------------------------------
- *  uf_set_multicast_list
- *
- *      This function is called by the higher level stack to set
- *      a list of multicast rx addresses.
- *
- *  Arguments:
- *      dev             Network Device pointer.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-
-static void
-uf_set_multicast_list(struct net_device *dev)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-#ifdef CSR_NATIVE_LINUX
-    unifi_trace(priv, UDBG3, "uf_set_multicast_list unsupported\n");
-    return;
-#else
-
-    u8 *mc_list = interfacePriv->mc_list;
-    struct netdev_hw_addr *mc_addr;
-    int mc_addr_count;
-
-    if (priv->init_progress != UNIFI_INIT_COMPLETED) {
-        return;
-    }
-
-    mc_addr_count = netdev_mc_count(dev);
-
-    unifi_trace(priv, UDBG3,
-            "uf_set_multicast_list (count=%d)\n", mc_addr_count);
-
-
-    /* Not enough space? */
-    if (mc_addr_count > UNIFI_MAX_MULTICAST_ADDRESSES) {
-        return;
-    }
-
-    /* Store the list to be processed by the work item. */
-    interfacePriv->mc_list_count = mc_addr_count;
-    netdev_hw_addr_list_for_each(mc_addr, &dev->mc) {
-        memcpy(mc_list, mc_addr->addr, ETH_ALEN);
-        mc_list += ETH_ALEN;
-    }
-
-    /* Send a message to the workqueue */
-    queue_work(priv->unifi_workqueue, &priv->multicast_list_task);
-#endif
-
-} /* uf_set_multicast_list() */
-
-/*
- * ---------------------------------------------------------------------------
- *  netdev_mlme_event_handler
- *
- *      Callback function to be used as the udi_event_callback when registering
- *      as a netdev client.
- *      To use it, a client specifies this function as the udi_event_callback
- *      to ul_register_client(). The signal dispatcher in
- *      unifi_receive_event() will call this function to deliver a signal.
- *
- *  Arguments:
- *      pcli            Pointer to the client instance.
- *      signal          Pointer to the received signal.
- *      signal_len      Size of the signal structure in bytes.
- *      bulkdata        Pointer to structure containing any associated bulk data.
- *      dir             Direction of the signal. Zero means from host,
- *                      non-zero means to host.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void
-netdev_mlme_event_handler(ul_client_t *pcli, const u8 *sig_packed, int sig_len,
-                          const bulk_data_param_t *bulkdata_o, int dir)
-{
-    CSR_SIGNAL signal;
-    unifi_priv_t *priv = uf_find_instance(pcli->instance);
-    int id, r;
-    bulk_data_param_t bulkdata;
-
-    /* Just a sanity check */
-    if (sig_packed == NULL) {
-        return;
-    }
-
-    /*
-     * This copy is to silence a compiler warning about discarding the
-     * const qualifier.
-     */
-    bulkdata = *bulkdata_o;
-
-    /* Get the unpacked signal */
-    r = read_unpack_signal(sig_packed, &signal);
-    if (r) {
-        /*
-         * The CSR_MLME_CONNECTED_INDICATION_ID has a receiverID=0 so will
-         * fall through this case. It is safe to ignore this signal.
-         */
-        unifi_trace(priv, UDBG1,
-                    "Netdev - Received unknown signal 0x%.4X.\n",
-                    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed));
-        return;
-    }
-
-    id = signal.SignalPrimitiveHeader.SignalId;
-    unifi_trace(priv, UDBG3, "Netdev - Process signal 0x%.4X\n", id);
-
-    /*
-     * Take the appropriate action for the signal.
-     */
-    switch (id) {
-        case CSR_MA_PACKET_ERROR_INDICATION_ID:
-            process_ma_packet_error_ind(priv, &signal, &bulkdata);
-            break;
-        case CSR_MA_PACKET_INDICATION_ID:
-            process_ma_packet_ind(priv, &signal, &bulkdata);
-            break;
-        case  CSR_MA_PACKET_CONFIRM_ID:
-            process_ma_packet_cfm(priv, &signal, &bulkdata);
-            break;
-#ifdef CSR_SUPPORT_SME
-        case CSR_MLME_SET_TIM_CONFIRM_ID:
-            /* Handle TIM confirms from FW & set the station record's TIM state appropriately,
-             * In case of failures, tries with max_retransmit limit
-             */
-            uf_handle_tim_cfm(priv, &signal.u.MlmeSetTimConfirm, signal.SignalPrimitiveHeader.ReceiverProcessId);
-            break;
-#endif
-        case CSR_DEBUG_STRING_INDICATION_ID:
-            debug_string_indication(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length);
-            break;
-
-        case CSR_DEBUG_WORD16_INDICATION_ID:
-            debug_word16_indication(priv, &signal);
-            break;
-
-        case CSR_DEBUG_GENERIC_CONFIRM_ID:
-        case CSR_DEBUG_GENERIC_INDICATION_ID:
-            debug_generic_indication(priv, &signal);
-            break;
-        default:
-            break;
-    }
-
-} /* netdev_mlme_event_handler() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_net_get_name
- *
- *      Retrieve the name (e.g. eth1) associated with this network device
- *
- *  Arguments:
- *      dev             Pointer to the network device.
- *      name            Buffer to write name
- *      len             Size of buffer in bytes
- *
- *  Returns:
- *      None
- *
- *  Notes:
- * ---------------------------------------------------------------------------
- */
-void uf_net_get_name(struct net_device *dev, char *name, int len)
-{
-    *name = '\0';
-    if (dev) {
-        strlcpy(name, dev->name, (len > IFNAMSIZ) ? IFNAMSIZ : len);
-    }
-
-} /* uf_net_get_name */
-
-#ifdef CSR_SUPPORT_WEXT
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_netdev_event
- *
- *     Callback function to handle netdev state changes
- *
- *  Arguments:
- *      notif           Pointer to a notifier_block.
- *      event           Event prompting notification
- *      ptr             net_device pointer
- *
- *  Returns:
- *      None
- *
- *  Notes:
- *   The event handler is global, and may occur on non-UniFi netdevs.
- * ---------------------------------------------------------------------------
- */
-static int
-uf_netdev_event(struct notifier_block *notif, unsigned long event, void* ptr) {
-    struct net_device *netdev = ptr;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(netdev);
-    unifi_priv_t *priv = NULL;
-    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
-
-    /* Check that the event is for a UniFi netdev. If it's not, the netdev_priv
-     * structure is not safe to use.
-     */
-    if (uf_find_netdev_priv(interfacePriv) == -1) {
-        unifi_trace(NULL, UDBG1, "uf_netdev_event: ignore e=%d, ptr=%p, priv=%p %s\n",
-                    event, ptr, interfacePriv, netdev->name);
-        return 0;
-    }
-
-    switch(event) {
-    case NETDEV_CHANGE:
-        priv = interfacePriv->privPtr;
-        unifi_trace(priv, UDBG1, "NETDEV_CHANGE: %p %s %s waiting for it\n",
-                    ptr,
-                    netdev->name,
-                    interfacePriv->wait_netdev_change ? "" : "not");
-
-        if (interfacePriv->wait_netdev_change) {
-            netif_tx_wake_all_queues(priv->netdev[interfacePriv->InterfaceTag]);
-            interfacePriv->connected = UnifiConnected;
-            interfacePriv->wait_netdev_change = FALSE;
-            /* Note: passing the broadcast address here will allow anyone to attempt to join our adhoc network */
-            uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1,interfacePriv->InterfaceTag);
-            uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1,interfacePriv->InterfaceTag);
-        }
-        break;
-
-    default:
-        break;
-    }
-    return 0;
-}
-
-static struct notifier_block uf_netdev_notifier = {
-    .notifier_call = uf_netdev_event,
-};
-#endif /* CSR_SUPPORT_WEXT */
-
-
-static void
-        process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
-{
-    u32 offset;
-    u32 length = bulkdata->d[0].data_length;
-    u32 subframe_length, subframe_body_length, dot11_hdr_size;
-    u8 *ptr;
-    bulk_data_param_t subframe_bulkdata;
-    u8 *dot11_hdr_ptr = (u8*)bulkdata->d[0].os_data_ptr;
-    CsrResult csrResult;
-    u16 frameControl;
-    u8 *qos_control_ptr;
-
-    frameControl = le16_to_cpu(*((u16*)dot11_hdr_ptr));
-    qos_control_ptr = dot11_hdr_ptr + (((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK))?30: 24);
-    if(!(*qos_control_ptr & IEEE802_11_QC_A_MSDU_PRESENT)) {
-        unifi_trace(priv, UDBG6, "%s: calling unifi_rx()", __FUNCTION__);
-        unifi_rx(priv, signal, bulkdata);
-        return;
-    }
-    *qos_control_ptr &= ~(IEEE802_11_QC_A_MSDU_PRESENT);
-
-    ptr = qos_control_ptr + 2;
-    offset = dot11_hdr_size = ptr - dot11_hdr_ptr;
-
-    while(length > (offset + sizeof(struct ethhdr) + sizeof(llc_snap_hdr_t))) {
-        subframe_body_length = ntohs(((struct ethhdr*)ptr)->h_proto);
-        if(subframe_body_length > IEEE802_11_MAX_DATA_LEN) {
-            unifi_error(priv, "%s: bad subframe_body_length = %d\n", __FUNCTION__, subframe_body_length);
-            break;
-        }
-        subframe_length = sizeof(struct ethhdr) + subframe_body_length;
-        memset(&subframe_bulkdata, 0, sizeof(bulk_data_param_t));
-
-        csrResult = unifi_net_data_malloc(priv, &subframe_bulkdata.d[0], dot11_hdr_size + subframe_body_length);
-
-        if (csrResult != CSR_RESULT_SUCCESS) {
-            unifi_error(priv, "%s: unifi_net_data_malloc failed\n", __FUNCTION__);
-            break;
-        }
-
-        memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr, dot11_hdr_ptr, dot11_hdr_size);
-
-
-        /* When to DS=0 and from DS=0, address 3 will already have BSSID so no need to re-program */
-        if ((frameControl & IEEE802_11_FC_TO_DS_MASK) && !(frameControl & IEEE802_11_FC_FROM_DS_MASK)){
-                memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET, ((struct ethhdr*)ptr)->h_dest, ETH_ALEN);
-        }
-        else if (!(frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
-                memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET,
-                         ((struct ethhdr*)ptr)->h_source,
-                           ETH_ALEN);
-        }
-
-        memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + dot11_hdr_size,
-                ptr + sizeof(struct ethhdr),
-                             subframe_body_length);
-        unifi_trace(priv, UDBG6, "%s: calling unifi_rx. length = %d subframe_length = %d\n", __FUNCTION__, length, subframe_length);
-        unifi_rx(priv, signal, &subframe_bulkdata);
-
-        subframe_length = (subframe_length + 3)&(~0x3);
-        ptr += subframe_length;
-        offset += subframe_length;
-    }
-    unifi_net_data_free(priv, &bulkdata->d[0]);
-}
-
-
-#define SN_TO_INDEX(__ba_session, __sn) (((__sn - __ba_session->start_sn) & 0xFFF) % __ba_session->wind_size)
-
-
-#define ADVANCE_EXPECTED_SN(__ba_session) \
-{ \
-    __ba_session->expected_sn++; \
-    __ba_session->expected_sn &= 0xFFF; \
-}
-
-#define FREE_BUFFER_SLOT(__ba_session, __index) \
-{ \
-    __ba_session->occupied_slots--; \
-    __ba_session->buffer[__index].active = FALSE; \
-    ADVANCE_EXPECTED_SN(__ba_session); \
-}
-
-static void add_frame_to_ba_complete(unifi_priv_t *priv,
-                          netInterface_priv_t *interfacePriv,
-                          frame_desc_struct *frame_desc)
-{
-    interfacePriv->ba_complete[interfacePriv->ba_complete_index] = *frame_desc;
-    interfacePriv->ba_complete_index++;
-}
-
-
-static void update_expected_sn(unifi_priv_t *priv,
-                          netInterface_priv_t *interfacePriv,
-                          ba_session_rx_struct *ba_session,
-                          u16 sn)
-{
-    int i, j;
-    u16 gap;
-
-    gap = (sn - ba_session->expected_sn) & 0xFFF;
-    unifi_trace(priv, UDBG6, "%s: process the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__, sn, gap);
-    for(j = 0; j < gap && j < ba_session->wind_size; j++) {
-        i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
-        unifi_trace(priv, UDBG6, "%s: process the slot index = %d\n", __FUNCTION__, i);
-        if(ba_session->buffer[i].active) {
-            add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
-            unifi_trace(priv, UDBG6, "%s: process the frame at index = %d expected_sn = %d\n", __FUNCTION__, i, ba_session->expected_sn);
-            FREE_BUFFER_SLOT(ba_session, i);
-        } else {
-            unifi_trace(priv, UDBG6, "%s: empty slot at index = %d\n", __FUNCTION__, i);
-            ADVANCE_EXPECTED_SN(ba_session);
-        }
-    }
-    ba_session->expected_sn = sn;
-}
-
-
-static void complete_ready_sequence(unifi_priv_t *priv,
-                               netInterface_priv_t *interfacePriv,
-                               ba_session_rx_struct *ba_session)
-{
-    int i;
-
-    i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
-    while (ba_session->buffer[i].active) {
-        add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
-        unifi_trace(priv, UDBG6, "%s: completed stored frame(expected_sn=%d) at i = %d\n", __FUNCTION__, ba_session->expected_sn, i);
-        FREE_BUFFER_SLOT(ba_session, i);
-        i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
-    }
-}
-
-
-void scroll_ba_window(unifi_priv_t *priv,
-                                netInterface_priv_t *interfacePriv,
-                                ba_session_rx_struct *ba_session,
-                                u16 sn)
-{
-    if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) {
-        update_expected_sn(priv, interfacePriv, ba_session, sn);
-        complete_ready_sequence(priv, interfacePriv, ba_session);
-    }
-}
-
-
-static int consume_frame_or_get_buffer_index(unifi_priv_t *priv,
-                                            netInterface_priv_t *interfacePriv,
-                                            ba_session_rx_struct *ba_session,
-                                            u16 sn,
-                                            frame_desc_struct *frame_desc) {
-    int i;
-    u16 sn_temp;
-
-    if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) {
-
-        /* once we are in BA window, set the flag for BA trigger */
-        if(!ba_session->trigger_ba_after_ssn){
-            ba_session->trigger_ba_after_ssn = TRUE;
-        }
-
-        sn_temp = ba_session->expected_sn + ba_session->wind_size;
-        unifi_trace(priv, UDBG6, "%s: new frame: sn=%d\n", __FUNCTION__, sn);
-        if(!(((sn - sn_temp) & 0xFFF) > 2048)) {
-            u16 new_expected_sn;
-            unifi_trace(priv, UDBG6, "%s: frame is out of window\n", __FUNCTION__);
-            sn_temp = (sn - ba_session->wind_size) & 0xFFF;
-            new_expected_sn = (sn_temp + 1) & 0xFFF;
-            update_expected_sn(priv, interfacePriv, ba_session, new_expected_sn);
-        }
-        i = -1;
-        if (sn == ba_session->expected_sn) {
-            unifi_trace(priv, UDBG6, "%s: sn = ba_session->expected_sn = %d\n", __FUNCTION__, sn);
-            ADVANCE_EXPECTED_SN(ba_session);
-            add_frame_to_ba_complete(priv, interfacePriv, frame_desc);
-        } else {
-            i = SN_TO_INDEX(ba_session, sn);
-            unifi_trace(priv, UDBG6, "%s: sn(%d) != ba_session->expected_sn(%d), i = %d\n", __FUNCTION__, sn, ba_session->expected_sn, i);
-            if (ba_session->buffer[i].active) {
-                unifi_trace(priv, UDBG6, "%s: free frame at i = %d\n", __FUNCTION__, i);
-                i = -1;
-                unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
-            }
-        }
-    } else {
-        i = -1;
-        if(!ba_session->trigger_ba_after_ssn){
-            unifi_trace(priv, UDBG6, "%s: frame before ssn, pass it up: sn=%d\n", __FUNCTION__, sn);
-            add_frame_to_ba_complete(priv, interfacePriv, frame_desc);
-        }else{
-            unifi_trace(priv, UDBG6, "%s: old frame, drop: sn=%d, expected_sn=%d\n", __FUNCTION__, sn, ba_session->expected_sn);
-            unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
-        }
-    }
-    return i;
-}
-
-
-
-static void process_ba_frame(unifi_priv_t *priv,
-                                             netInterface_priv_t *interfacePriv,
-                                             ba_session_rx_struct *ba_session,
-                                             frame_desc_struct *frame_desc)
-{
-    int i;
-    u16 sn = frame_desc->sn;
-
-    if (ba_session->timeout) {
-        mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024)));
-    }
-    unifi_trace(priv, UDBG6, "%s: got frame(sn=%d)\n", __FUNCTION__, sn);
-
-    i = consume_frame_or_get_buffer_index(priv, interfacePriv, ba_session, sn, frame_desc);
-    if(i >= 0) {
-        unifi_trace(priv, UDBG6, "%s: store frame(sn=%d) at i = %d\n", __FUNCTION__, sn, i);
-        ba_session->buffer[i] = *frame_desc;
-        ba_session->buffer[i].recv_time = CsrTimeGet(NULL);
-        ba_session->occupied_slots++;
-    } else {
-        unifi_trace(priv, UDBG6, "%s: frame consumed - sn = %d\n", __FUNCTION__, sn);
-    }
-    complete_ready_sequence(priv, interfacePriv, ba_session);
-}
-
-
-static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv)
-{
-    frame_desc_struct *frame_desc;
-    u8 i;
-
-    for(i = 0; i < interfacePriv->ba_complete_index; i++) {
-        frame_desc = &interfacePriv->ba_complete[i];
-        unifi_trace(priv, UDBG6, "%s: calling process_amsdu()\n", __FUNCTION__);
-        process_amsdu(priv, &frame_desc->signal, &frame_desc->bulkdata);
-    }
-    interfacePriv->ba_complete_index = 0;
-
-}
-
-
-/* Check if the frames in BA reoder buffer has aged and
- * if so release the frames to upper processes and move
- * the window
- */
-static void check_ba_frame_age_timeout( unifi_priv_t *priv,
-                                        netInterface_priv_t *interfacePriv,
-                                        ba_session_rx_struct *ba_session)
-{
-    u32 now;
-    u32 age;
-    u8 i, j;
-    u16 sn_temp;
-
-    /* gap is started at 1 because we have buffered frames and
-     * hence a minimum gap of 1 exists
-     */
-    u8 gap=1;
-
-    now = CsrTimeGet(NULL);
-
-    if (ba_session->occupied_slots)
-    {
-        /* expected sequence has not arrived so start searching from next
-         * sequence number until a frame is available and determine the gap.
-         * Check if the frame available has timedout, if so advance the
-         * expected sequence number and release the frames
-         */
-        sn_temp = (ba_session->expected_sn + 1) & 0xFFF;
-
-        for(j = 0; j < ba_session->wind_size; j++)
-        {
-            i = SN_TO_INDEX(ba_session, sn_temp);
-
-            if(ba_session->buffer[i].active)
-            {
-                unifi_trace(priv, UDBG6, "check age at slot index = %d sn = %d recv_time = %u now = %u\n",
-                                        i,
-                                        ba_session->buffer[i].sn,
-                                        ba_session->buffer[i].recv_time,
-                                        now);
-
-                if (ba_session->buffer[i].recv_time > now)
-                {
-                    /* timer wrap */
-                    age = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, ba_session->buffer[i].recv_time), now);
-                }
-                else
-                {
-                    age = (u32)CsrTimeSub(now, ba_session->buffer[i].recv_time);
-                }
-
-                if (age >= CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT)
-                {
-                    unifi_trace(priv, UDBG2, "release the frame at index = %d gap = %d expected_sn = %d sn = %d\n",
-                                            i,
-                                            gap,
-                                            ba_session->expected_sn,
-                                            ba_session->buffer[i].sn);
-
-                    /* if it has timedout don't wait for missing frames, move the window */
-                    while (gap--)
-                    {
-                        ADVANCE_EXPECTED_SN(ba_session);
-                    }
-                    add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
-                    FREE_BUFFER_SLOT(ba_session, i);
-                    complete_ready_sequence(priv, interfacePriv, ba_session);
-                }
-                break;
-
-            }
-            else
-            {
-                /* advance temp sequence number and frame gap */
-                sn_temp = (sn_temp + 1) & 0xFFF;
-                gap++;
-            }
-        }
-    }
-}
-
-
-static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
-{
-    u16 interfaceTag;
-    const CSR_MA_PACKET_ERROR_INDICATION *pkt_err_ind = &signal->u.MaPacketErrorIndication;
-    netInterface_priv_t *interfacePriv;
-    ba_session_rx_struct *ba_session;
-    u8 ba_session_idx = 0;
-    CSR_PRIORITY        UserPriority;
-    CSR_SEQUENCE_NUMBER sn;
-
-    interfaceTag = (pkt_err_ind->VirtualInterfaceIdentifier & 0xff);
-
-
-    /* Sanity check that the VIF refers to a sensible interface */
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
-    {
-        unifi_error(priv, "%s: MaPacketErrorIndication indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
-        return;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-    UserPriority = pkt_err_ind->UserPriority;
-    if(UserPriority > 15) {
-        unifi_error(priv, "%s: MaPacketErrorIndication indication with bad UserPriority=%d\n", __FUNCTION__, UserPriority);
-    }
-    sn = pkt_err_ind->SequenceNumber;
-
-    down(&priv->ba_mutex);
-    /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */
-    for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
-        ba_session = interfacePriv->ba_session_rx[ba_session_idx];
-        if (ba_session){
-            if ((!memcmp(ba_session->macAddress.a, pkt_err_ind->PeerQstaAddress.x, ETH_ALEN)) && (ba_session->tID == UserPriority)){
-                if (ba_session->timeout) {
-                    mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024)));
-                }
-                scroll_ba_window(priv, interfacePriv, ba_session, sn);
-                break;
-            }
-        }
-    }
-
-    up(&priv->ba_mutex);
-    process_ba_complete(priv, interfacePriv);
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/os.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/os.c
--- linux-libre-3.10-gnu/drivers/staging/csr/os.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/os.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,477 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *  FILE:     os.c
- *
- *  PURPOSE:
- *      Routines to fulfil the OS-abstraction for the HIP lib.
- *      It is part of the porting exercise.
- *
- * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-
-/**
- * The HIP lib OS abstraction consists of the implementation
- * of the functions in this file. It is part of the porting exercise.
- */
-
-#include "unifi_priv.h"
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_net_data_malloc
- *
- *      Allocate an OS specific net data buffer of "size" bytes.
- *      The bulk_data_slot.os_data_ptr must be initialised to point
- *      to the buffer allocated. The bulk_data_slot.length must be
- *      initialised to the requested size, zero otherwise.
- *      The bulk_data_slot.os_net_buf_ptr can be initialised to
- *      an OS specific pointer to be used in the unifi_net_data_free().
- *
- *
- *  Arguments:
- *      ospriv              Pointer to device private context struct.
- *      bulk_data_slot      Pointer to the bulk data structure to initialise.
- *      size                Size of the buffer to be allocated.
- *
- *  Returns:
- *      CSR_RESULT_SUCCESS on success, CSR_RESULT_FAILURE otherwise.
- * ---------------------------------------------------------------------------
- */
-CsrResult
-unifi_net_data_malloc(void *ospriv, bulk_data_desc_t *bulk_data_slot, unsigned int size)
-{
-    struct sk_buff *skb;
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-    int rounded_length;
-
-    if (priv->card_info.sdio_block_size == 0) {
-        unifi_error(priv, "unifi_net_data_malloc: Invalid SDIO block size\n");
-        return CSR_RESULT_FAILURE;
-    }
-
-    rounded_length = (size + priv->card_info.sdio_block_size - 1) & ~(priv->card_info.sdio_block_size - 1);
-
-    /*
-     * (ETH_HLEN + 2) bytes tailroom for header manipulation
-     * CSR_WIFI_ALIGN_BYTES bytes headroom for alignment manipulation
-     */
-    skb = dev_alloc_skb(rounded_length + 2 + ETH_HLEN + CSR_WIFI_ALIGN_BYTES);
-    if (! skb) {
-        unifi_error(ospriv, "alloc_skb failed.\n");
-        bulk_data_slot->os_net_buf_ptr = NULL;
-        bulk_data_slot->net_buf_length = 0;
-        bulk_data_slot->os_data_ptr = NULL;
-        bulk_data_slot->data_length = 0;
-        return CSR_RESULT_FAILURE;
-    }
-
-    bulk_data_slot->os_net_buf_ptr = (const unsigned char*)skb;
-    bulk_data_slot->net_buf_length = rounded_length + 2 + ETH_HLEN + CSR_WIFI_ALIGN_BYTES;
-    bulk_data_slot->os_data_ptr = (const void*)skb->data;
-    bulk_data_slot->data_length = size;
-
-    return CSR_RESULT_SUCCESS;
-} /* unifi_net_data_malloc() */
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_net_data_free
- *
- *      Free an OS specific net data buffer.
- *      The bulk_data_slot.length must be initialised to 0.
- *
- *
- *  Arguments:
- *      ospriv              Pointer to device private context struct.
- *      bulk_data_slot      Pointer to the bulk data structure that
- *                          holds the data to be freed.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-unifi_net_data_free(void *ospriv, bulk_data_desc_t *bulk_data_slot)
-{
-    struct sk_buff *skb;
-    CSR_UNUSED(ospriv);
-
-    skb = (struct sk_buff *)bulk_data_slot->os_net_buf_ptr;
-    dev_kfree_skb(skb);
-
-    bulk_data_slot->net_buf_length = 0;
-    bulk_data_slot->data_length = 0;
-    bulk_data_slot->os_data_ptr = bulk_data_slot->os_net_buf_ptr = NULL;
-
-} /* unifi_net_data_free() */
-
-
-/*
-* ---------------------------------------------------------------------------
-*  unifi_net_dma_align
-*
-*      DMA align an OS specific net data buffer.
-*      The buffer must be empty.
-*
-*
-*  Arguments:
-*      ospriv              Pointer to device private context struct.
-*      bulk_data_slot      Pointer to the bulk data structure that
-*                          holds the data to be aligned.
-*
-*  Returns:
-*      None.
-* ---------------------------------------------------------------------------
-*/
-CsrResult
-unifi_net_dma_align(void *ospriv, bulk_data_desc_t *bulk_data_slot)
-{
-    struct sk_buff *skb;
-    unsigned long buf_address;
-    int offset;
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-
-    if ((bulk_data_slot == NULL) || (CSR_WIFI_ALIGN_BYTES == 0)) {
-        return CSR_RESULT_SUCCESS;
-    }
-
-    if ((bulk_data_slot->os_data_ptr == NULL) || (bulk_data_slot->data_length == 0)) {
-        return CSR_RESULT_SUCCESS;
-    }
-
-    buf_address = (unsigned long)(bulk_data_slot->os_data_ptr) & (CSR_WIFI_ALIGN_BYTES - 1);
-
-    unifi_trace(priv, UDBG5,
-                "unifi_net_dma_align: Allign buffer (0x%p) by %d bytes\n",
-                bulk_data_slot->os_data_ptr, buf_address);
-
-    offset = CSR_WIFI_ALIGN_BYTES - buf_address;
-    if (offset < 0) {
-        unifi_error(priv, "unifi_net_dma_align: Failed (offset=%d)\n", offset);
-        return CSR_RESULT_FAILURE;
-    }
-
-    skb = (struct sk_buff*)(bulk_data_slot->os_net_buf_ptr);
-    skb_reserve(skb, offset);
-    bulk_data_slot->os_net_buf_ptr = (const unsigned char*)skb;
-    bulk_data_slot->os_data_ptr = (const void*)(skb->data);
-
-    return CSR_RESULT_SUCCESS;
-
-} /* unifi_net_dma_align() */
-
-#ifdef ANDROID_TIMESTAMP
-static volatile unsigned int printk_cpu = UINT_MAX;
-char tbuf[30];
-
-char* print_time(void )
-{
-    unsigned long long t;
-    unsigned long nanosec_rem;
-
-    t = cpu_clock(printk_cpu);
-    nanosec_rem = do_div(t, 1000000000);
-    sprintf(tbuf, "[%5lu.%06lu] ",
-                    (unsigned long) t,
-                    nanosec_rem / 1000);
-
-    return tbuf;
-}
-#endif
-
-
-/* Module parameters */
-extern int unifi_debug;
-
-#ifdef UNIFI_DEBUG
-#define DEBUG_BUFFER_SIZE       120
-
-#define FORMAT_TRACE(_s, _len, _args, _fmt)             \
-    do {                                                \
-        va_start(_args, _fmt);                          \
-        _len += vsnprintf(&(_s)[_len],                  \
-                         (DEBUG_BUFFER_SIZE - _len),    \
-                         _fmt, _args);                  \
-        va_end(_args);                                  \
-        if (_len >= DEBUG_BUFFER_SIZE) {                \
-            (_s)[DEBUG_BUFFER_SIZE - 2] = '\n';         \
-            (_s)[DEBUG_BUFFER_SIZE - 1] = 0;            \
-        }                                               \
-    } while (0)
-
-void
-unifi_error(void* ospriv, const char *fmt, ...)
-{
-    unifi_priv_t *priv = (unifi_priv_t*) ospriv;
-    char s[DEBUG_BUFFER_SIZE];
-    va_list args;
-    unsigned int len;
-#ifdef ANDROID_TIMESTAMP
-    if (priv != NULL) {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi%d: ", print_time(), priv->instance);
-    } else {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi: ", print_time());
-    }
-#else
-    if (priv != NULL) {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi%d: ", priv->instance);
-    } else {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi: ");
-    }
-#endif /* ANDROID_TIMESTAMP */
-    FORMAT_TRACE(s, len, args, fmt);
-
-    printk("%s", s);
-}
-
-void
-unifi_warning(void* ospriv, const char *fmt, ...)
-{
-    unifi_priv_t *priv = (unifi_priv_t*) ospriv;
-    char s[DEBUG_BUFFER_SIZE];
-    va_list args;
-    unsigned int len;
-
-#ifdef ANDROID_TIMESTAMP
-    if (priv != NULL) {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "%s unifi%d: ", print_time(), priv->instance);
-    } else {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "%s unifi: ", print_time());
-    }
-#else
-    if (priv != NULL) {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "unifi%d: ", priv->instance);
-    } else {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "unifi: ");
-    }
-#endif /* ANDROID_TIMESTAMP */
-
-    FORMAT_TRACE(s, len, args, fmt);
-
-    printk("%s", s);
-}
-
-
-void
-unifi_notice(void* ospriv, const char *fmt, ...)
-{
-    unifi_priv_t *priv = (unifi_priv_t*) ospriv;
-    char s[DEBUG_BUFFER_SIZE];
-    va_list args;
-    unsigned int len;
-
-#ifdef ANDROID_TIMESTAMP
-    if (priv != NULL) {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "%s unifi%d: ", print_time(), priv->instance);
-    } else {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "%s unifi: ", print_time());
-    }
-#else
-    if (priv != NULL) {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "unifi%d: ", priv->instance);
-    } else {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "unifi: ");
-    }
-#endif /* ANDROID_TIMESTAMP */
-
-    FORMAT_TRACE(s, len, args, fmt);
-
-    printk("%s", s);
-}
-
-
-void
-unifi_info(void* ospriv, const char *fmt, ...)
-{
-    unifi_priv_t *priv = (unifi_priv_t*) ospriv;
-    char s[DEBUG_BUFFER_SIZE];
-    va_list args;
-    unsigned int len;
-
-#ifdef ANDROID_TIMESTAMP
-    if (priv != NULL) {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "%s unifi%d: ", print_time(), priv->instance);
-    } else {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "%s unifi: ", print_time());
-    }
-#else
-    if (priv != NULL) {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "unifi%d: ", priv->instance);
-    } else {
-        len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "unifi: ");
-    }
-#endif /* ANDROID_TIMESTAMP */
-
-    FORMAT_TRACE(s, len, args, fmt);
-
-    printk("%s", s);
-}
-
-/* debugging */
-void
-unifi_trace(void* ospriv, int level, const char *fmt, ...)
-{
-    unifi_priv_t *priv = (unifi_priv_t*) ospriv;
-    char s[DEBUG_BUFFER_SIZE];
-    va_list args;
-    unsigned int len;
-
-    if (unifi_debug >= level) {
-#ifdef ANDROID_TIMESTAMP
-        if (priv != NULL) {
-            len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi%d: ", print_time(), priv->instance);
-        } else {
-            len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi: ", print_time());
-        }
-#else
-        if (priv != NULL) {
-            len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi%d: ", priv->instance);
-        } else {
-            len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi: ");
-        }
-#endif /* ANDROID_TIMESTAMP */
-
-        FORMAT_TRACE(s, len, args, fmt);
-
-        printk("%s", s);
-    }
-}
-
-#else
-
-void
-unifi_error_nop(void* ospriv, const char *fmt, ...)
-{
-}
-
-void
-unifi_trace_nop(void* ospriv, int level, const char *fmt, ...)
-{
-}
-
-#endif /* UNIFI_DEBUG */
-
-
-/*
- * ---------------------------------------------------------------------------
- *
- *      Debugging support.
- *
- * ---------------------------------------------------------------------------
- */
-
-#ifdef UNIFI_DEBUG
-
-/* Memory dump with level filter controlled by unifi_debug */
-void
-unifi_dump(void *ospriv, int level, const char *msg, void *mem, u16 len)
-{
-    unifi_priv_t *priv = (unifi_priv_t*) ospriv;
-
-    if (unifi_debug >= level) {
-#ifdef ANDROID_TIMESTAMP
-        if (priv != NULL) {
-            printk(KERN_ERR "%s unifi%d: --- dump: %s ---\n", print_time(), priv->instance, msg ? msg : "");
-        } else {
-            printk(KERN_ERR "%s unifi: --- dump: %s ---\n", print_time(), msg ? msg : "");
-        }
-#else
-        if (priv != NULL) {
-            printk(KERN_ERR "unifi%d: --- dump: %s ---\n", priv->instance, msg ? msg : "");
-        } else {
-            printk(KERN_ERR "unifi: --- dump: %s ---\n", msg ? msg : "");
-        }
-#endif /* ANDROID_TIMESTAMP */
-        dump(mem, len);
-
-        if (priv != NULL) {
-            printk(KERN_ERR "unifi%d: --- end of dump ---\n", priv->instance);
-        } else {
-            printk(KERN_ERR "unifi: --- end of dump ---\n");
-        }
-    }
-}
-
-/* Memory dump that appears all the time, use sparingly */
-void
-dump(void *mem, u16 len)
-{
-    int i, col = 0;
-    unsigned char *pdata = (unsigned char *)mem;
-#ifdef ANDROID_TIMESTAMP
-    printk("timestamp %s \n", print_time());
-#endif /* ANDROID_TIMESTAMP */
-    if (mem == NULL) {
-        printk("(null dump)\n");
-        return;
-    }
-    for (i = 0; i < len; i++) {
-        if (col == 0)
-            printk("0x%02X: ", i);
-
-        printk(" %02X", pdata[i]);
-
-        if (++col == 16) {
-            printk("\n");
-            col = 0;
-        }
-    }
-    if (col)
-        printk("\n");
-} /* dump() */
-
-
-void
-dump16(void *mem, u16 len)
-{
-    int i, col=0;
-    unsigned short *p = (unsigned short *)mem;
-#ifdef ANDROID_TIMESTAMP
-    printk("timestamp %s \n", print_time());
-#endif /* ANDROID_TIMESTAMP */
-    for (i = 0; i < len; i+=2) {
-        if (col == 0)
-            printk("0x%02X: ", i);
-
-        printk(" %04X", *p++);
-
-        if (++col == 8) {
-            printk("\n");
-            col = 0;
-        }
-    }
-    if (col)
-        printk("\n");
-}
-
-
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-void
-dump_str(void *mem, u16 len)
-{
-    int i;
-    unsigned char *pdata = (unsigned char *)mem;
-#ifdef ANDROID_TIMESTAMP
-    printk("timestamp %s \n", print_time());
-#endif /* ANDROID_TIMESTAMP */
-    for (i = 0; i < len; i++) {
-        printk("%c", pdata[i]);
-    }
-	printk("\n");
-
-} /* dump_str() */
-#endif /* CSR_ONLY_NOTES */
-
-
-#endif /* UNIFI_DEBUG */
-
-
-/* ---------------------------------------------------------------------------
- *                              - End -
- * ------------------------------------------------------------------------- */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/putest.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/putest.c
--- linux-libre-3.10-gnu/drivers/staging/csr/putest.c	2013-07-01 10:38:12.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/putest.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,685 +0,0 @@
-/*
- * ***************************************************************************
- *  FILE:     putest.c
- *
- *  PURPOSE:    putest related functions.
- *
- *  Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ***************************************************************************
- */
-
-#include <linux/vmalloc.h>
-#include <linux/firmware.h>
-
-#include "unifi_priv.h"
-#include "csr_wifi_hip_chiphelper.h"
-
-#define UNIFI_PROC_BOTH 3
-
-
-int unifi_putest_cmd52_read(unifi_priv_t *priv, unsigned char *arg)
-{
-    struct unifi_putest_cmd52 cmd52_params;
-    u8 *arg_pos;
-    unsigned int cmd_param_size;
-    int r;
-    CsrResult csrResult;
-    unsigned char ret_buffer[32];
-    u8 *ret_buffer_pos;
-    u8 retries;
-
-    arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
-    if (get_user(cmd_param_size, (int*)arg_pos)) {
-        unifi_error(priv,
-                    "unifi_putest_cmd52_read: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    if (cmd_param_size != sizeof(struct unifi_putest_cmd52)) {
-        unifi_error(priv,
-                    "unifi_putest_cmd52_read: cmd52 struct mismatch\n");
-        return -EINVAL;
-    }
-
-    arg_pos += sizeof(unsigned int);
-    if (copy_from_user(&cmd52_params,
-                       (void*)arg_pos,
-                       sizeof(struct unifi_putest_cmd52))) {
-        unifi_error(priv,
-                    "unifi_putest_cmd52_read: Failed to get the cmd52 params\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG2, "cmd52r: func=%d addr=0x%x ",
-                cmd52_params.funcnum, cmd52_params.addr);
-
-    retries = 3;
-    CsrSdioClaim(priv->sdio);
-    do {
-        if (cmd52_params.funcnum == 0) {
-            csrResult = CsrSdioF0Read8(priv->sdio, cmd52_params.addr, &cmd52_params.data);
-        } else {
-            csrResult = CsrSdioRead8(priv->sdio, cmd52_params.addr, &cmd52_params.data);
-        }
-    } while (--retries && ((csrResult == CSR_SDIO_RESULT_CRC_ERROR) || (csrResult == CSR_SDIO_RESULT_TIMEOUT)));
-    CsrSdioRelease(priv->sdio);
-
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv,
-                    "\nunifi_putest_cmd52_read: Read8() failed (csrResult=0x%x)\n", csrResult);
-        return -EFAULT;
-    }
-    unifi_trace(priv, UDBG2, "data=%d\n", cmd52_params.data);
-
-    /* Copy the info to the out buffer */
-    *(unifi_putest_command_t*)ret_buffer = UNIFI_PUTEST_CMD52_READ;
-    ret_buffer_pos = (u8*)(((unifi_putest_command_t*)ret_buffer) + 1);
-    *(unsigned int*)ret_buffer_pos = sizeof(struct unifi_putest_cmd52);
-    ret_buffer_pos += sizeof(unsigned int);
-    memcpy(ret_buffer_pos, &cmd52_params, sizeof(struct unifi_putest_cmd52));
-    ret_buffer_pos += sizeof(struct unifi_putest_cmd52);
-
-    r = copy_to_user((void*)arg,
-                     ret_buffer,
-                     ret_buffer_pos - ret_buffer);
-    if (r) {
-        unifi_error(priv,
-                    "unifi_putest_cmd52_read: Failed to return the data\n");
-        return -EFAULT;
-    }
-
-    return 0;
-}
-
-
-int unifi_putest_cmd52_write(unifi_priv_t *priv, unsigned char *arg)
-{
-    struct unifi_putest_cmd52 cmd52_params;
-    u8 *arg_pos;
-    unsigned int cmd_param_size;
-    CsrResult csrResult;
-    u8 retries;
-
-    arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
-    if (get_user(cmd_param_size, (int*)arg_pos)) {
-        unifi_error(priv,
-                    "unifi_putest_cmd52_write: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    if (cmd_param_size != sizeof(struct unifi_putest_cmd52)) {
-        unifi_error(priv,
-                    "unifi_putest_cmd52_write: cmd52 struct mismatch\n");
-        return -EINVAL;
-    }
-
-    arg_pos += sizeof(unsigned int);
-    if (copy_from_user(&cmd52_params,
-                       (void*)(arg_pos),
-                       sizeof(struct unifi_putest_cmd52))) {
-        unifi_error(priv,
-                    "unifi_putest_cmd52_write: Failed to get the cmd52 params\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG2, "cmd52w: func=%d addr=0x%x data=%d\n",
-                cmd52_params.funcnum, cmd52_params.addr, cmd52_params.data);
-
-    retries = 3;
-    CsrSdioClaim(priv->sdio);
-    do {
-        if (cmd52_params.funcnum == 0) {
-            csrResult = CsrSdioF0Write8(priv->sdio, cmd52_params.addr, cmd52_params.data);
-        } else {
-            csrResult = CsrSdioWrite8(priv->sdio, cmd52_params.addr, cmd52_params.data);
-        }
-    } while (--retries && ((csrResult == CSR_SDIO_RESULT_CRC_ERROR) || (csrResult == CSR_SDIO_RESULT_TIMEOUT)));
-    CsrSdioRelease(priv->sdio);
-
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv,
-                    "unifi_putest_cmd52_write: Write8() failed (csrResult=0x%x)\n", csrResult);
-        return -EFAULT;
-    }
-
-    return 0;
-}
-
-int unifi_putest_gp_read16(unifi_priv_t *priv, unsigned char *arg)
-{
-    struct unifi_putest_gp_rw16 gp_r16_params;
-    u8 *arg_pos;
-    unsigned int cmd_param_size;
-    int r;
-    CsrResult csrResult;
-    unsigned char ret_buffer[32];
-    u8 *ret_buffer_pos;
-
-    arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
-    if (get_user(cmd_param_size, (int*)arg_pos)) {
-        unifi_error(priv,
-                    "unifi_putest_gp_read16: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    if (cmd_param_size != sizeof(struct unifi_putest_gp_rw16)) {
-        unifi_error(priv,
-                    "unifi_putest_gp_read16: struct mismatch\n");
-        return -EINVAL;
-    }
-
-    arg_pos += sizeof(unsigned int);
-    if (copy_from_user(&gp_r16_params,
-                       (void*)arg_pos,
-                       sizeof(struct unifi_putest_gp_rw16))) {
-        unifi_error(priv,
-                    "unifi_putest_gp_read16: Failed to get the params\n");
-        return -EFAULT;
-    }
-    CsrSdioClaim(priv->sdio);
-    csrResult = unifi_card_read16(priv->card, gp_r16_params.addr, &gp_r16_params.data);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv,
-                    "unifi_putest_gp_read16: unifi_card_read16() GP=0x%x failed (csrResult=0x%x)\n", gp_r16_params.addr, csrResult);
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG2, "gp_r16: GP=0x%08x, data=0x%04x\n", gp_r16_params.addr, gp_r16_params.data);
-
-    /* Copy the info to the out buffer */
-    *(unifi_putest_command_t*)ret_buffer = UNIFI_PUTEST_GP_READ16;
-    ret_buffer_pos = (u8*)(((unifi_putest_command_t*)ret_buffer) + 1);
-    *(unsigned int*)ret_buffer_pos = sizeof(struct unifi_putest_gp_rw16);
-    ret_buffer_pos += sizeof(unsigned int);
-    memcpy(ret_buffer_pos, &gp_r16_params, sizeof(struct unifi_putest_gp_rw16));
-    ret_buffer_pos += sizeof(struct unifi_putest_gp_rw16);
-
-    r = copy_to_user((void*)arg,
-                     ret_buffer,
-                     ret_buffer_pos - ret_buffer);
-    if (r) {
-        unifi_error(priv,
-                    "unifi_putest_gp_read16: Failed to return the data\n");
-        return -EFAULT;
-    }
-
-    return 0;
-}
-
-int unifi_putest_gp_write16(unifi_priv_t *priv, unsigned char *arg)
-{
-    struct unifi_putest_gp_rw16 gp_w16_params;
-    u8 *arg_pos;
-    unsigned int cmd_param_size;
-    CsrResult csrResult;
-
-    arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
-    if (get_user(cmd_param_size, (int*)arg_pos)) {
-        unifi_error(priv,
-                    "unifi_putest_gp_write16: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    if (cmd_param_size != sizeof(struct unifi_putest_gp_rw16)) {
-        unifi_error(priv,
-                    "unifi_putest_gp_write16: struct mismatch\n");
-        return -EINVAL;
-    }
-
-    arg_pos += sizeof(unsigned int);
-    if (copy_from_user(&gp_w16_params,
-                       (void*)(arg_pos),
-                       sizeof(struct unifi_putest_gp_rw16))) {
-        unifi_error(priv,
-                    "unifi_putest_gp_write16: Failed to get the params\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG2, "gp_w16: GP=0x%08x, data=0x%04x\n", gp_w16_params.addr, gp_w16_params.data);
-    CsrSdioClaim(priv->sdio);
-    csrResult = unifi_card_write16(priv->card, gp_w16_params.addr, gp_w16_params.data);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv,
-                    "unifi_putest_gp_write16: unifi_card_write16() GP=%x failed (csrResult=0x%x)\n", gp_w16_params.addr, csrResult);
-        return -EFAULT;
-    }
-
-    return 0;
-}
-
-int unifi_putest_set_sdio_clock(unifi_priv_t *priv, unsigned char *arg)
-{
-    int sdio_clock_speed;
-    CsrResult csrResult;
-
-    if (get_user(sdio_clock_speed, (int*)(((unifi_putest_command_t*)arg) + 1))) {
-        unifi_error(priv,
-                    "unifi_putest_set_sdio_clock: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG2, "set sdio clock: %d KHz\n", sdio_clock_speed);
-
-    CsrSdioClaim(priv->sdio);
-    csrResult = CsrSdioMaxBusClockFrequencySet(priv->sdio, sdio_clock_speed * 1000);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv,
-                    "unifi_putest_set_sdio_clock: Set clock failed (csrResult=0x%x)\n", csrResult);
-        return -EFAULT;
-    }
-
-    return 0;
-}
-
-
-int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg)
-{
-    int r;
-    CsrResult csrResult;
-    int already_in_test = priv->ptest_mode;
-
-    /* Ensure that sme_sys_suspend() doesn't power down the chip because:
-     *  1) Power is needed anyway for ptest.
-     *  2) The app code uses the START ioctl as a reset, so it gets called
-     *     multiple times. If the app stops the XAPs, but the power_down/up
-     *     sequence doesn't actually power down the chip, there can be problems
-     *     resetting, because part of the power_up sequence disables function 1
-     */
-    priv->ptest_mode = 1;
-
-    /* Suspend the SME and UniFi */
-    if (priv->sme_cli) {
-        r = sme_sys_suspend(priv);
-        if (r) {
-            unifi_error(priv,
-                        "unifi_putest_start: failed to suspend UniFi\n");
-            return r;
-        }
-    }
-
-    /* Application may have stopped the XAPs, but they are needed for reset */
-    if (already_in_test) {
-        CsrSdioClaim(priv->sdio);
-        csrResult = unifi_start_processors(priv->card);
-        CsrSdioRelease(priv->sdio);
-        if (csrResult != CSR_RESULT_SUCCESS) {
-            unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
-        }
-    } else {
-        /* Ensure chip is powered for the case where there's no unifi_helper */
-        CsrSdioClaim(priv->sdio);
-        csrResult = CsrSdioPowerOn(priv->sdio);
-        CsrSdioRelease(priv->sdio);
-        if (csrResult != CSR_RESULT_SUCCESS) {
-            unifi_error(priv, "CsrSdioPowerOn csrResult = %d\n", csrResult);
-        }
-    }
-    CsrSdioClaim(priv->sdio);
-    csrResult = unifi_init(priv->card);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv,
-                    "unifi_putest_start: failed to init UniFi\n");
-        return CsrHipResultToStatus(csrResult);
-    }
-
-    return 0;
-}
-
-
-int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg)
-{
-    int r = 0;
-    CsrResult csrResult;
-
-    /* Application may have stopped the XAPs, but they are needed for reset */
-    CsrSdioClaim(priv->sdio);
-    csrResult = unifi_start_processors(priv->card);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
-    }
-
-    /* PUTEST_STOP is also used to resume the XAPs after SME coredump.
-     * Don't power off the chip, leave that to the normal wifi-off which is
-     * about to carry on. No need to resume the SME either, as it wasn't suspended.
-     */
-    if (priv->coredump_mode) {
-        priv->coredump_mode = 0;
-        return 0;
-    }
-
-    /* At this point function 1 is enabled and the XAPs are running, so it is
-     * safe to let the card power down. Power is restored later, asynchronously,
-     * during the wifi_on requested by the SME.
-     */
-    CsrSdioClaim(priv->sdio);
-    CsrSdioPowerOff(priv->sdio);
-    CsrSdioRelease(priv->sdio);
-
-    /* Resume the SME and UniFi */
-    if (priv->sme_cli) {
-        r = sme_sys_resume(priv);
-        if (r) {
-            unifi_error(priv,
-                        "unifi_putest_stop: failed to resume SME\n");
-        }
-    }
-    priv->ptest_mode = 0;
-
-    return r;
-}
-
-
-int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg)
-{
-#define UF_PUTEST_MAX_FW_FILE_NAME      16
-#define UNIFI_MAX_FW_PATH_LEN           32
-    unsigned int fw_name_length;
-    unsigned char fw_name[UF_PUTEST_MAX_FW_FILE_NAME+1];
-    unsigned char *name_buffer;
-    int postfix;
-    char fw_path[UNIFI_MAX_FW_PATH_LEN];
-    const struct firmware *fw_entry;
-    struct dlpriv temp_fw_sta;
-    int r;
-    CsrResult csrResult;
-
-    /* Get the f/w file name length */
-    if (get_user(fw_name_length, (unsigned int*)(((unifi_putest_command_t*)arg) + 1))) {
-        unifi_error(priv,
-                    "unifi_putest_dl_fw: Failed to get the length argument\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG2, "unifi_putest_dl_fw: file name size = %d\n", fw_name_length);
-
-    /* Sanity check for the f/w file name length */
-    if (fw_name_length > UF_PUTEST_MAX_FW_FILE_NAME) {
-        unifi_error(priv,
-                    "unifi_putest_dl_fw: F/W file name is too long\n");
-        return -EINVAL;
-    }
-
-    /* Get the f/w file name */
-    name_buffer = ((unsigned char*)arg) + sizeof(unifi_putest_command_t) + sizeof(unsigned int);
-    if (copy_from_user(fw_name, (void*)name_buffer, fw_name_length)) {
-        unifi_error(priv, "unifi_putest_dl_fw: Failed to get the file name\n");
-        return -EFAULT;
-    }
-    fw_name[fw_name_length] = '\0';
-    unifi_trace(priv, UDBG2, "unifi_putest_dl_fw: file = %s\n", fw_name);
-
-    /* Keep the existing f/w to a temp, we need to restore it later */
-    temp_fw_sta = priv->fw_sta;
-
-    /* Get the putest f/w */
-    postfix = priv->instance;
-    scnprintf(fw_path, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
-              postfix, fw_name);
-    r = reject_firmware(&fw_entry, fw_path, priv->unifi_device);
-    if (r == 0) {
-        priv->fw_sta.fw_desc = (void *)fw_entry;
-        priv->fw_sta.dl_data = fw_entry->data;
-        priv->fw_sta.dl_len = fw_entry->size;
-    } else {
-        unifi_error(priv, "Firmware file not available\n");
-        return -EINVAL;
-    }
-
-    /* Application may have stopped the XAPs, but they are needed for reset */
-    CsrSdioClaim(priv->sdio);
-    csrResult = unifi_start_processors(priv->card);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
-    }
-
-    /* Download the f/w. On UF6xxx this will cause the f/w file to convert
-     * into patch format and download via the ROM boot loader
-     */
-    CsrSdioClaim(priv->sdio);
-    csrResult = unifi_download(priv->card, 0x0c00);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv,
-                    "unifi_putest_dl_fw: failed to download the f/w\n");
-        goto free_fw;
-    }
-
-    /* Free the putest f/w... */
-free_fw:
-    uf_release_firmware(priv, &priv->fw_sta);
-    /* ... and restore the original f/w */
-    priv->fw_sta = temp_fw_sta;
-
-    return CsrHipResultToStatus(csrResult);
-}
-
-
-int unifi_putest_dl_fw_buff(unifi_priv_t *priv, unsigned char *arg)
-{
-    unsigned int fw_length;
-    unsigned char *fw_buf = NULL;
-    unsigned char *fw_user_ptr;
-    struct dlpriv temp_fw_sta;
-    CsrResult csrResult;
-
-    /* Get the f/w buffer length */
-    if (get_user(fw_length, (unsigned int*)(((unifi_putest_command_t*)arg) + 1))) {
-        unifi_error(priv,
-                    "unifi_putest_dl_fw_buff: Failed to get the length arg\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG2, "unifi_putest_dl_fw_buff: size = %d\n", fw_length);
-
-    /* Sanity check for the buffer length */
-    if (fw_length == 0 || fw_length > 0xfffffff) {
-        unifi_error(priv,
-                    "unifi_putest_dl_fw_buff: buffer length bad %u\n", fw_length);
-        return -EINVAL;
-    }
-
-    /* Buffer for kernel copy of the f/w image */
-    fw_buf = kmalloc(fw_length, GFP_KERNEL);
-    if (!fw_buf) {
-        unifi_error(priv, "unifi_putest_dl_fw_buff: malloc fail\n");
-        return -ENOMEM;
-    }
-
-    /* Get the f/w image */
-    fw_user_ptr = ((unsigned char*)arg) + sizeof(unifi_putest_command_t) + sizeof(unsigned int);
-    if (copy_from_user(fw_buf, (void*)fw_user_ptr, fw_length)) {
-        unifi_error(priv, "unifi_putest_dl_fw_buff: Failed to get the buffer\n");
-        kfree(fw_buf);
-        return -EFAULT;
-    }
-
-    /* Save the existing f/w to a temp, we need to restore it later */
-    temp_fw_sta = priv->fw_sta;
-
-    /* Setting fw_desc NULL indicates to the core that no f/w file was loaded
-     * via the kernel reject_firmware() mechanism. This indicates to the core
-     * that it shouldn't call release_firmware() after the download is done.
-     */
-    priv->fw_sta.fw_desc = NULL;            /* No OS f/w resource */
-    priv->fw_sta.dl_data = fw_buf;
-    priv->fw_sta.dl_len = fw_length;
-
-    /* Application may have stopped the XAPs, but they are needed for reset */
-    CsrSdioClaim(priv->sdio);
-    csrResult = unifi_start_processors(priv->card);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
-    }
-
-    /* Download the f/w. On UF6xxx this will cause the f/w file to convert
-     * into patch format and download via the ROM boot loader
-     */
-    CsrSdioClaim(priv->sdio);
-    csrResult = unifi_download(priv->card, 0x0c00);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv,
-                    "unifi_putest_dl_fw_buff: failed to download the f/w\n");
-        goto free_fw;
-    }
-
-free_fw:
-    /* Finished with the putest f/w, so restore the station f/w */
-    priv->fw_sta = temp_fw_sta;
-    kfree(fw_buf);
-
-    return CsrHipResultToStatus(csrResult);
-}
-
-
-int unifi_putest_coredump_prepare(unifi_priv_t *priv, unsigned char *arg)
-{
-    u16 data_u16;
-    s32 i;
-    CsrResult r;
-
-    unifi_info(priv, "Preparing for SDIO coredump\n");
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE)
-    unifi_debug_buf_dump();
-#endif
-
-    /* Sanity check that userspace hasn't called a PUTEST_START, because that
-     * would have reset UniFi, potentially power cycling it and losing context
-     */
-    if (priv->ptest_mode) {
-        unifi_error(priv, "PUTEST_START shouldn't be used before a coredump\n");
-    }
-
-    /* Flag that the userspace has requested coredump. Even if this preparation
-     * fails, the SME will call PUTEST_STOP to tidy up.
-     */
-    priv->coredump_mode = 1;
-
-    for (i = 0; i < 3; i++) {
-        CsrSdioClaim(priv->sdio);
-        r = CsrSdioRead16(priv->sdio, CHIP_HELPER_UNIFI_GBL_CHIP_VERSION*2, &data_u16);
-        CsrSdioRelease(priv->sdio);
-        if (r != CSR_RESULT_SUCCESS) {
-            unifi_info(priv, "Failed to read chip version! Try %d\n", i);
-
-            /* First try, re-enable function which may have been disabled by f/w panic */
-            if (i == 0) {
-                unifi_info(priv, "Try function enable\n");
-                CsrSdioClaim(priv->sdio);
-                r = CsrSdioFunctionEnable(priv->sdio);
-                CsrSdioRelease(priv->sdio);
-                if (r != CSR_RESULT_SUCCESS) {
-                    unifi_error(priv, "CsrSdioFunctionEnable failed %d\n", r);
-                }
-                continue;
-            }
-
-            /* Subsequent tries, reset */
-
-            /* Set clock speed low */
-            CsrSdioClaim(priv->sdio);
-            r = CsrSdioMaxBusClockFrequencySet(priv->sdio, UNIFI_SDIO_CLOCK_SAFE_HZ);
-            CsrSdioRelease(priv->sdio);
-            if (r != CSR_RESULT_SUCCESS) {
-                unifi_error(priv, "CsrSdioMaxBusClockFrequencySet() failed %d\n", r);
-            }
-
-            /* Card software reset */
-            CsrSdioClaim(priv->sdio);
-            r = unifi_card_hard_reset(priv->card);
-            CsrSdioRelease(priv->sdio);
-            if (r != CSR_RESULT_SUCCESS) {
-                unifi_error(priv, "unifi_card_hard_reset() failed %d\n", r);
-            }
-        } else {
-            unifi_info(priv, "Read chip version of 0x%04x\n", data_u16);
-            break;
-        }
-    }
-
-    if (r != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "Failed to prepare chip\n");
-        return -EIO;
-    }
-
-    /* Stop the XAPs for coredump. The PUTEST_STOP must be called, e.g. at
-     * Raw SDIO deinit, to resume them.
-     */
-    CsrSdioClaim(priv->sdio);
-    r = unifi_card_stop_processor(priv->card, UNIFI_PROC_BOTH);
-    CsrSdioRelease(priv->sdio);
-    if (r != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "Failed to stop processors\n");
-    }
-
-    return 0;
-}
-
-int unifi_putest_cmd52_block_read(unifi_priv_t *priv, unsigned char *arg)
-{
-    struct unifi_putest_block_cmd52_r block_cmd52;
-    u8 *arg_pos;
-    unsigned int cmd_param_size;
-    CsrResult r;
-    u8 *block_local_buffer;
-
-    arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
-    if (get_user(cmd_param_size, (int*)arg_pos)) {
-        unifi_error(priv,
-                    "cmd52r_block: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    if (cmd_param_size != sizeof(struct unifi_putest_block_cmd52_r)) {
-        unifi_error(priv,
-                    "cmd52r_block: cmd52 struct mismatch\n");
-        return -EINVAL;
-    }
-
-    arg_pos += sizeof(unsigned int);
-    if (copy_from_user(&block_cmd52,
-                       (void*)arg_pos,
-                       sizeof(struct unifi_putest_block_cmd52_r))) {
-        unifi_error(priv,
-                    "cmd52r_block: Failed to get the cmd52 params\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG2, "cmd52r_block: func=%d addr=0x%x len=0x%x ",
-                block_cmd52.funcnum, block_cmd52.addr, block_cmd52.length);
-
-    block_local_buffer = vmalloc(block_cmd52.length);
-    if (block_local_buffer == NULL) {
-        unifi_error(priv, "cmd52r_block: Failed to allocate buffer\n");
-        return -ENOMEM;
-    }
-
-    CsrSdioClaim(priv->sdio);
-    r = unifi_card_readn(priv->card, block_cmd52.addr, block_local_buffer, block_cmd52.length);
-    CsrSdioRelease(priv->sdio);
-    if (r != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "cmd52r_block: unifi_readn failed\n");
-        return -EIO;
-    }
-
-    if (copy_to_user((void*)block_cmd52.data,
-                     block_local_buffer,
-                     block_cmd52.length)) {
-        unifi_error(priv,
-                    "cmd52r_block: Failed to return the data\n");
-        return -EFAULT;
-    }
-
-    return 0;
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sdio_events.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/sdio_events.c
--- linux-libre-3.10-gnu/drivers/staging/csr/sdio_events.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sdio_events.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,134 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     sdio_events.c
- *
- * PURPOSE:
- *      Process the events received by the SDIO glue layer.
- *      Optional part of the porting exercise.
- *
- * Copyright (C) 2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include "unifi_priv.h"
-
-
-/*
- * Porting Notes:
- * There are two ways to support the suspend/resume system events in a driver.
- * In some operating systems these events are delivered to the OS driver
- * directly from the system. In this case, the OS driver needs to pass these
- * events to the API described in the CSR SDIO Abstration API document.
- * In Linux, and other embedded operating systems, the suspend/resume events
- * come from the SDIO driver. In this case, simply get these events in the
- * SDIO glue layer and notify the OS layer.
- *
- * In either case, typically, the events are processed by the SME.
- * Use the unifi_sys_suspend_ind() and unifi_sys_resume_ind() to pass
- * the events to the SME.
- */
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_suspend
- *
- *      Handles a suspend request from the SDIO driver.
- *
- *  Arguments:
- *      ospriv          Pointer to OS driver context.
- *
- * ---------------------------------------------------------------------------
- */
-void unifi_suspend(void *ospriv)
-{
-    unifi_priv_t *priv = ospriv;
-    int interfaceTag=0;
-
-    /* For powered suspend, tell the resume's wifi_on() not to reinit UniFi */
-    priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE;
-
-    unifi_trace(priv, UDBG1, "unifi_suspend: wol_suspend %d, enable_wol %d",
-                priv->wol_suspend, enable_wol );
-
-    /* Stop network traffic. */
-    /* need to stop all the netdevices*/
-    for( interfaceTag=0;interfaceTag<CSR_WIFI_NUM_INTERFACES;interfaceTag++)
-    {
-        netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-        if (interfacePriv->netdev_registered == 1)
-        {
-            if( priv->wol_suspend ) {
-                unifi_trace(priv, UDBG1, "unifi_suspend: Don't netif_carrier_off");
-            } else {
-                unifi_trace(priv, UDBG1, "unifi_suspend: netif_carrier_off");
-                netif_carrier_off(priv->netdev[interfaceTag]);
-            }
-            netif_tx_stop_all_queues(priv->netdev[interfaceTag]);
-        }
-    }
-
-    unifi_trace(priv, UDBG1, "unifi_suspend: suspend SME");
-
-    sme_sys_suspend(priv);
-
-} /* unifi_suspend() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_resume
- *
- *      Handles a resume request from the SDIO driver.
- *
- *  Arguments:
- *      ospriv          Pointer to OS driver context.
- *
- * ---------------------------------------------------------------------------
- */
-void unifi_resume(void *ospriv)
-{
-    unifi_priv_t *priv = ospriv;
-    int interfaceTag=0;
-    int r;
-    int wol = priv->wol_suspend;
-
-    unifi_trace(priv, UDBG1, "unifi_resume: resume SME, enable_wol=%d", enable_wol);
-
-    /* The resume causes wifi-on which will re-enable the BH and reinstall the ISR */
-    r = sme_sys_resume(priv);
-    if (r) {
-        unifi_error(priv, "Failed to resume UniFi\n");
-    }
-
-    /* Resume the network interfaces. For the cold resume case, this will
-     * happen upon reconnection.
-     */
-    if (wol) {
-        unifi_trace(priv, UDBG1, "unifi_resume: try to enable carrier");
-
-        /* need to start all the netdevices*/
-        for( interfaceTag=0;interfaceTag<CSR_WIFI_NUM_INTERFACES;interfaceTag++) {
-            netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-            unifi_trace(priv, UDBG1, "unifi_resume: interfaceTag %d netdev_registered %d mode %d\n",
-                   interfaceTag, interfacePriv->netdev_registered, interfacePriv->interfaceMode);
-
-            if (interfacePriv->netdev_registered == 1)
-            {
-                netif_carrier_on(priv->netdev[interfaceTag]);
-                netif_tx_start_all_queues(priv->netdev[interfaceTag]);
-            }
-        }
-
-        /* Kick the BH thread (with reason=host) to poll for data that may have
-         * arrived during a powered suspend. This caters for the case where the SME
-         * doesn't interact with the chip (e.g install autonomous scans) during resume.
-         */
-        unifi_send_signal(priv->card, NULL, 0, NULL);
-    }
-
-} /* unifi_resume() */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sdio_mmc.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/sdio_mmc.c
--- linux-libre-3.10-gnu/drivers/staging/csr/sdio_mmc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sdio_mmc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1288 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *
- * FILE: sdio_mmc.c
- *
- * PURPOSE: SDIO driver interface for generic MMC stack.
- *
- * Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/mutex.h>
-#include <linux/gfp.h>
-#include <linux/mmc/core.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio.h>
-#include <linux/suspend.h>
-
-#include "unifi_priv.h"
-
-#ifdef ANDROID_BUILD
-struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */
-#endif
-
-static CsrSdioFunctionDriver *sdio_func_drv;
-
-#ifdef CONFIG_PM
-static int uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr);
-#endif
-
-/*
- * We need to keep track of the power on/off because we can not call
- * mmc_power_restore_host() when the card is already powered.
- * Even then, we need to patch the MMC driver to add a power_restore handler
- * in the mmc_sdio_ops structure. If the MMC driver before 2.6.37 is not patched,
- * mmc_power_save_host() and mmc_power_restore_host() are no-ops in the kernel,
- * returning immediately (at least on x86).
- */
-static int card_is_powered = 1;
-
-/* MMC uses ENOMEDIUM to indicate card gone away */
-
-static CsrResult
-ConvertSdioToCsrSdioResult(int r)
-{
-    CsrResult csrResult = CSR_RESULT_FAILURE;
-
-    switch (r) {
-    case 0:
-        csrResult = CSR_RESULT_SUCCESS;
-    break;
-    case -EIO:
-    case -EILSEQ:
-        csrResult = CSR_SDIO_RESULT_CRC_ERROR;
-    break;
-    /* Timeout errors */
-    case -ETIMEDOUT:
-    case -EBUSY:
-        csrResult = CSR_SDIO_RESULT_TIMEOUT;
-    break;
-    case -ENODEV:
-    case -ENOMEDIUM:
-        csrResult = CSR_SDIO_RESULT_NO_DEVICE;
-    break;
-    case -EINVAL:
-        csrResult = CSR_SDIO_RESULT_INVALID_VALUE;
-    break;
-    case -ENOMEM:
-    case -ENOSYS:
-    case -ERANGE:
-    case -ENXIO:
-        csrResult = CSR_RESULT_FAILURE;
-    break;
-    default:
-        unifi_warning(NULL, "Unrecognised SDIO error code: %d\n", r);
-    break;
-    }
-
-    return csrResult;
-}
-
-
-static int
-csr_io_rw_direct(struct mmc_card *card, int write, uint8_t fn,
-                 uint32_t addr, uint8_t in, uint8_t* out)
-{
-    struct mmc_command cmd;
-    int err;
-
-    BUG_ON(!card);
-    BUG_ON(fn > 7);
-
-    memset(&cmd, 0, sizeof(struct mmc_command));
-
-    cmd.opcode = SD_IO_RW_DIRECT;
-    cmd.arg = write ? 0x80000000 : 0x00000000;
-    cmd.arg |= fn << 28;
-    cmd.arg |= (write && out) ? 0x08000000 : 0x00000000;
-    cmd.arg |= addr << 9;
-    cmd.arg |= in;
-    cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
-
-    err = mmc_wait_for_cmd(card->host, &cmd, 0);
-    if (err)
-        return err;
-
-    /* this function is not exported, so we will need to sort it out here
-     * for now, lets hard code it to sdio */
-    if (0) {
-        /* old arg (mmc_host_is_spi(card->host)) { */
-        /* host driver already reported errors */
-    } else {
-        if (cmd.resp[0] & R5_ERROR) {
-            printk(KERN_ERR "%s: r5 error 0x%02x\n",
-                   __FUNCTION__, cmd.resp[0]);
-            return -EIO;
-        }
-        if (cmd.resp[0] & R5_FUNCTION_NUMBER)
-            return -EINVAL;
-        if (cmd.resp[0] & R5_OUT_OF_RANGE)
-            return -ERANGE;
-    }
-
-    if (out) {
-        if (0) {    /* old argument (mmc_host_is_spi(card->host)) */
-            *out = (cmd.resp[0] >> 8) & 0xFF;
-        }
-        else {
-            *out = cmd.resp[0] & 0xFF;
-        }
-    }
-
-    return CSR_RESULT_SUCCESS;
-}
-
-
-CsrResult
-CsrSdioRead8(CsrSdioFunction *function, u32 address, u8 *data)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err = 0;
-
-    _sdio_claim_host(func);
-    *data = sdio_readb(func, address, &err);
-    _sdio_release_host(func);
-
-    if (err) {
-        return ConvertSdioToCsrSdioResult(err);
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioRead8() */
-
-CsrResult
-CsrSdioWrite8(CsrSdioFunction *function, u32 address, u8 data)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err = 0;
-
-    _sdio_claim_host(func);
-    sdio_writeb(func, data, address, &err);
-    _sdio_release_host(func);
-
-    if (err) {
-        return ConvertSdioToCsrSdioResult(err);
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioWrite8() */
-
-CsrResult
-CsrSdioRead16(CsrSdioFunction *function, u32 address, u16 *data)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err;
-    uint8_t b0, b1;
-
-    _sdio_claim_host(func);
-    b0 = sdio_readb(func, address, &err);
-    if (err) {
-        _sdio_release_host(func);
-        return ConvertSdioToCsrSdioResult(err);
-    }
-
-    b1 = sdio_readb(func, address+1, &err);
-    if (err) {
-        _sdio_release_host(func);
-        return ConvertSdioToCsrSdioResult(err);
-    }
-    _sdio_release_host(func);
-
-    *data = ((uint16_t)b1 << 8) | b0;
-
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioRead16() */
-
-
-CsrResult
-CsrSdioWrite16(CsrSdioFunction *function, u32 address, u16 data)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err;
-    uint8_t b0, b1;
-
-    _sdio_claim_host(func);
-    b1 = (data >> 8) & 0xFF;
-    sdio_writeb(func, b1, address+1, &err);
-    if (err) {
-        _sdio_release_host(func);
-        return ConvertSdioToCsrSdioResult(err);
-    }
-
-    b0 = data & 0xFF;
-    sdio_writeb(func, b0, address, &err);
-    if (err) {
-        _sdio_release_host(func);
-        return ConvertSdioToCsrSdioResult(err);
-    }
-
-    _sdio_release_host(func);
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioWrite16() */
-
-
-CsrResult
-CsrSdioF0Read8(CsrSdioFunction *function, u32 address, u8 *data)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err = 0;
-
-    _sdio_claim_host(func);
-#ifdef MMC_QUIRK_LENIENT_FN0
-    *data = sdio_f0_readb(func, address, &err);
-#else
-    err = csr_io_rw_direct(func->card, 0, 0, address, 0, data);
-#endif
-    _sdio_release_host(func);
-
-    if (err) {
-        return ConvertSdioToCsrSdioResult(err);
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioF0Read8() */
-
-CsrResult
-CsrSdioF0Write8(CsrSdioFunction *function, u32 address, u8 data)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err = 0;
-
-    _sdio_claim_host(func);
-#ifdef MMC_QUIRK_LENIENT_FN0
-    sdio_f0_writeb(func, data, address, &err);
-#else
-    err = csr_io_rw_direct(func->card, 1, 0, address, data, NULL);
-#endif
-    _sdio_release_host(func);
-
-    if (err) {
-        return ConvertSdioToCsrSdioResult(err);
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioF0Write8() */
-
-
-CsrResult
-CsrSdioRead(CsrSdioFunction *function, u32 address, void *data, u32 length)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err;
-
-    _sdio_claim_host(func);
-    err = sdio_readsb(func, data, address, length);
-    _sdio_release_host(func);
-
-    if (err) {
-        return ConvertSdioToCsrSdioResult(err);
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioRead() */
-
-CsrResult
-CsrSdioWrite(CsrSdioFunction *function, u32 address, const void *data, u32 length)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err;
-
-    _sdio_claim_host(func);
-    err = sdio_writesb(func, address, (void*)data, length);
-    _sdio_release_host(func);
-
-    if (err) {
-        return ConvertSdioToCsrSdioResult(err);
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioWrite() */
-
-
-static int
-csr_sdio_enable_hs(struct mmc_card *card)
-{
-    int ret;
-    u8 speed;
-
-    if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) {
-        /* We've asked for HS clock rates, but controller doesn't
-         * claim to support it. We should limit the clock
-         * to 25MHz via module parameter.
-         */
-        printk(KERN_INFO "unifi: request HS but not MMC_CAP_SD_HIGHSPEED");
-        return 0;
-    }
-
-    if (!card->cccr.high_speed)
-        return 0;
-
-#if 1
-    ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
-    if (ret)
-        return ret;
-
-    speed |= SDIO_SPEED_EHS;
-#else
-    /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
-    speed = SDIO_SPEED_EHS | SDIO_SPEED_SHS;
-#endif
-
-    ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
-    if (ret)
-        return ret;
-
-    mmc_card_set_highspeed(card);
-    card->host->ios.timing = MMC_TIMING_SD_HS;
-    card->host->ops->set_ios(card->host, &card->host->ios);
-
-    return 0;
-}
-
-static int
-csr_sdio_disable_hs(struct mmc_card *card)
-{
-    int ret;
-    u8 speed;
-
-    if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
-        return 0;
-
-    if (!card->cccr.high_speed)
-        return 0;
-#if 1
-    ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
-    if (ret)
-        return ret;
-
-    speed &= ~SDIO_SPEED_EHS;
-#else
-    /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
-    speed = SDIO_SPEED_SHS; /* clear SDIO_SPEED_EHS */
-#endif
-
-    ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
-    if (ret)
-        return ret;
-
-    card->state &= ~MMC_STATE_HIGHSPEED;
-    card->host->ios.timing = MMC_TIMING_LEGACY;
-    card->host->ops->set_ios(card->host, &card->host->ios);
-
-    return 0;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioMaxBusClockFrequencySet
- *
- *      Set the maximum SDIO bus clock speed to use.
- *
- *  Arguments:
- *      sdio            SDIO context pointer
- *      maxFrequency         maximum clock speed in Hz
- *
- *  Returns:
- *      an error code.
- * ---------------------------------------------------------------------------
- */
-CsrResult
-CsrSdioMaxBusClockFrequencySet(CsrSdioFunction *function, u32 maxFrequency)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    struct mmc_host *host = func->card->host;
-    struct mmc_ios *ios = &host->ios;
-    unsigned int max_hz;
-    int err;
-	u32 max_khz = maxFrequency/1000;
-
-    if (!max_khz || max_khz > sdio_clock) {
-        max_khz = sdio_clock;
-    }
-
-    _sdio_claim_host(func);
-    max_hz = 1000 * max_khz;
-    if (max_hz > host->f_max) {
-        max_hz = host->f_max;
-    }
-
-    if (max_hz > 25000000) {
-        err = csr_sdio_enable_hs(func->card);
-    } else {
-        err = csr_sdio_disable_hs(func->card);
-    }
-    if (err) {
-        printk(KERN_ERR "SDIO warning: Failed to configure SDIO clock mode\n");
-        _sdio_release_host(func);
-		return CSR_RESULT_SUCCESS;
-    }
-
-    ios->clock = max_hz;
-    host->ops->set_ios(host, ios);
-
-    _sdio_release_host(func);
-
-	return CSR_RESULT_SUCCESS;
-} /* CsrSdioMaxBusClockFrequencySet() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioInterruptEnable
- *  CsrSdioInterruptDisable
- *
- *      Enable or disable the SDIO interrupt.
- *      The driver disables the SDIO interrupt until the i/o thread can
- *      process it.
- *      The SDIO interrupt can be disabled by modifying the SDIO_INT_ENABLE
- *      register in the Card Common Control Register block, but this requires
- *      two CMD52 operations. A better solution is to mask the interrupt at
- *      the host controller.
- *
- *  Arguments:
- *      sdio            SDIO context pointer
- *
- *  Returns:
- *      Zero on success or a UniFi driver error code.
- *
- * ---------------------------------------------------------------------------
- */
-CsrResult
-CsrSdioInterruptEnable(CsrSdioFunction *function)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err = 0;
-
-#ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
-    sdio_unblock_card_irq(func);
-#else
-    _sdio_claim_host(func);
-    /* Write the Int Enable in CCCR block */
-#ifdef MMC_QUIRK_LENIENT_FN0
-    sdio_f0_writeb(func, 0x3, SDIO_CCCR_IENx, &err);
-#else
-    err = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x03, NULL);
-#endif
-    _sdio_release_host(func);
-
-    if (err) {
-        printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
-        return ConvertSdioToCsrSdioResult(err);
-    }
-#endif
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioInterruptEnable() */
-
-CsrResult
-CsrSdioInterruptDisable(CsrSdioFunction *function)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err = 0;
-
-#ifdef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
-    sdio_block_card_irq(func);
-#else
-    _sdio_claim_host(func);
-    /* Write the Int Enable in CCCR block */
-#ifdef MMC_QUIRK_LENIENT_FN0
-    sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &err);
-#else
-    err = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL);
-#endif
-    _sdio_release_host(func);
-
-    if (err) {
-        printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
-        return ConvertSdioToCsrSdioResult(err);
-    }
-#endif
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioInterruptDisable() */
-
-
-void CsrSdioInterruptAcknowledge(CsrSdioFunction *function)
-{
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioFunctionEnable
- *
- *      Enable i/o on function 1.
- *
- *  Arguments:
- *      sdio            SDIO context pointer
- *
- * Returns:
- *      UniFi driver error code.
- * ---------------------------------------------------------------------------
- */
-CsrResult
-CsrSdioFunctionEnable(CsrSdioFunction *function)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err;
-
-    /* Enable UniFi function 1 (the 802.11 part). */
-    _sdio_claim_host(func);
-    err = sdio_enable_func(func);
-    _sdio_release_host(func);
-    if (err) {
-        unifi_error(NULL, "Failed to enable SDIO function %d\n", func->num);
-    }
-
-    return ConvertSdioToCsrSdioResult(err);
-} /* CsrSdioFunctionEnable() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioFunctionDisable
- *
- *      Enable i/o on function 1.
- *
- *  Arguments:
- *      sdio            SDIO context pointer
- *
- * Returns:
- *      UniFi driver error code.
- * ---------------------------------------------------------------------------
- */
-CsrResult
-CsrSdioFunctionDisable(CsrSdioFunction *function)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int err;
-
-    /* Disable UniFi function 1 (the 802.11 part). */
-    _sdio_claim_host(func);
-    err = sdio_disable_func(func);
-    _sdio_release_host(func);
-    if (err) {
-        unifi_error(NULL, "Failed to disable SDIO function %d\n", func->num);
-    }
-
-    return ConvertSdioToCsrSdioResult(err);
-} /* CsrSdioFunctionDisable() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioFunctionActive
- *
- *      No-op as the bus goes to an active state at the start of every
- *      command.
- *
- *  Arguments:
- *      sdio            SDIO context pointer
- * ---------------------------------------------------------------------------
- */
-void
-CsrSdioFunctionActive(CsrSdioFunction *function)
-{
-} /* CsrSdioFunctionActive() */
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioFunctionIdle
- *
- *      Set the function as idle.
- *
- *  Arguments:
- *      sdio            SDIO context pointer
- * ---------------------------------------------------------------------------
- */
-void
-CsrSdioFunctionIdle(CsrSdioFunction *function)
-{
-} /* CsrSdioFunctionIdle() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioPowerOn
- *
- *      Power on UniFi.
- *
- *  Arguments:
- *      sdio            SDIO context pointer
- * ---------------------------------------------------------------------------
- */
-CsrResult
-CsrSdioPowerOn(CsrSdioFunction *function)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    struct mmc_host *host = func->card->host;
-
-    _sdio_claim_host(func);
-    if (!card_is_powered) {
-        mmc_power_restore_host(host);
-        card_is_powered = 1;
-    } else {
-        printk(KERN_INFO "SDIO: Skip power on; card is already powered.\n");
-    }
-    _sdio_release_host(func);
-
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioPowerOn() */
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioPowerOff
- *
- *      Power off UniFi.
- *
- *  Arguments:
- *      sdio            SDIO context pointer
- * ---------------------------------------------------------------------------
- */
-void
-CsrSdioPowerOff(CsrSdioFunction *function)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    struct mmc_host *host = func->card->host;
-
-    _sdio_claim_host(func);
-    if (card_is_powered) {
-        mmc_power_save_host(host);
-        card_is_powered = 0;
-    } else {
-        printk(KERN_INFO "SDIO: Skip power off; card is already powered off.\n");
-    }
-    _sdio_release_host(func);
-} /* CsrSdioPowerOff() */
-
-
-static int
-sdio_set_block_size_ignore_first_error(struct sdio_func *func, unsigned blksz)
-{
-    int ret;
-
-    if (blksz > func->card->host->max_blk_size)
-        return -EINVAL;
-
-    if (blksz == 0) {
-        blksz = min(func->max_blksize, func->card->host->max_blk_size);
-        blksz = min(blksz, 512u);
-    }
-
-    /*
-     * Ignore -ERANGE (OUT_OF_RANGE in R5) on the first byte as
-     * the block size may be invalid until both bytes are written.
-     */
-    ret = csr_io_rw_direct(func->card, 1, 0,
-                           SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
-                           blksz & 0xff, NULL);
-    if (ret && ret != -ERANGE)
-        return ret;
-    ret = csr_io_rw_direct(func->card, 1, 0,
-                           SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
-                           (blksz >> 8) & 0xff, NULL);
-    if (ret)
-        return ret;
-    func->cur_blksize = blksz;
-
-    return 0;
-}
-
-CsrResult
-CsrSdioBlockSizeSet(CsrSdioFunction *function, u16 blockSize)
-{
-    struct sdio_func *func = (struct sdio_func *)function->priv;
-    int r = 0;
-
-    /* Module parameter overrides */
-    if (sdio_block_size > -1) {
-        blockSize = sdio_block_size;
-    }
-
-    unifi_trace(NULL, UDBG1, "Set SDIO function block size to %d\n",
-                blockSize);
-
-    _sdio_claim_host(func);
-    r = sdio_set_block_size(func, blockSize);
-    _sdio_release_host(func);
-
-    /*
-     * The MMC driver for kernels prior to 2.6.32 may fail this request
-     * with -ERANGE. In this case use our workaround.
-     */
-    if (r == -ERANGE) {
-        _sdio_claim_host(func);
-        r = sdio_set_block_size_ignore_first_error(func, blockSize);
-        _sdio_release_host(func);
-    }
-    if (r) {
-        unifi_error(NULL, "Error %d setting block size\n", r);
-    }
-
-    /* Determine the achieved block size to pass to the core */
-    function->blockSize = func->cur_blksize;
-
-    return ConvertSdioToCsrSdioResult(r);
-} /* CsrSdioBlockSizeSet() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioHardReset
- *
- *      Hard Resets UniFi is possible.
- *
- *  Arguments:
- *      sdio            SDIO context pointer
- * ---------------------------------------------------------------------------
- */
-CsrResult
-CsrSdioHardReset(CsrSdioFunction *function)
-{
-    return CSR_RESULT_FAILURE;
-} /* CsrSdioHardReset() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_glue_sdio_int_handler
- *
- *      Interrupt callback function for SDIO interrupts.
- *      This is called in kernel context (i.e. not interrupt context).
- *
- *  Arguments:
- *      func      SDIO context pointer
- *
- *  Returns:
- *      None.
- *
- *  Note: Called with host already claimed.
- * ---------------------------------------------------------------------------
- */
-static void
-uf_glue_sdio_int_handler(struct sdio_func *func)
-{
-    CsrSdioFunction *sdio_ctx;
-    CsrSdioInterruptDsrCallback func_dsr_callback;
-    int r;
-
-    sdio_ctx = sdio_get_drvdata(func);
-    if (!sdio_ctx) {
-        return;
-    }
-
-#ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
-    /*
-     * Normally, we are not allowed to do any SDIO commands here.
-     * However, this is called in a thread context and with the SDIO lock
-     * so we disable the interrupts here instead of trying to do complicated
-     * things with the SDIO lock.
-     */
-#ifdef MMC_QUIRK_LENIENT_FN0
-    sdio_f0_writeb(func, 0, SDIO_CCCR_IENx, &r);
-#else
-    r = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL);
-#endif
-    if (r) {
-        printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts %d\n", r);
-    }
-#endif
-
-    /* If the function driver has registered a handler, call it */
-    if (sdio_func_drv && sdio_func_drv->intr) {
-
-        func_dsr_callback = sdio_func_drv->intr(sdio_ctx);
-
-        /* If interrupt handle returns a DSR handle, call it */
-        if (func_dsr_callback) {
-            func_dsr_callback(sdio_ctx);
-        }
-    }
-
-} /* uf_glue_sdio_int_handler() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  csr_sdio_linux_remove_irq
- *
- *      Unregister the interrupt handler.
- *      This means that the linux layer can not process interrupts any more.
- *
- *  Arguments:
- *      sdio      SDIO context pointer
- *
- *  Returns:
- *      Status of the removal.
- * ---------------------------------------------------------------------------
- */
-int csr_sdio_linux_remove_irq(CsrSdioFunction *function)
-{
-	struct sdio_func *func = (struct sdio_func *)function->priv;
-	int r;
-
-	unifi_trace(NULL, UDBG1, "csr_sdio_linux_remove_irq\n");
-
-	sdio_claim_host(func);
-	r = sdio_release_irq(func);
-	sdio_release_host(func);
-
-	return r;
-
-} /* csr_sdio_linux_remove_irq() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  csr_sdio_linux_install_irq
- *
- *      Register the interrupt handler.
- *      This means that the linux layer can process interrupts.
- *
- *  Arguments:
- *      sdio      SDIO context pointer
- *
- *  Returns:
- *      Status of the removal.
- * ---------------------------------------------------------------------------
- */
-int csr_sdio_linux_install_irq(CsrSdioFunction *function)
-{
-	struct sdio_func *func = (struct sdio_func *)function->priv;
-	int r;
-
-	unifi_trace(NULL, UDBG1, "csr_sdio_linux_install_irq\n");
-
-	/* Register our interrupt handle */
-	sdio_claim_host(func);
-	r = sdio_claim_irq(func, uf_glue_sdio_int_handler);
-	sdio_release_host(func);
-
-	/* If the interrupt was installed earlier, is fine */
-	if (r == -EBUSY)
-		r = 0;
-
-	return r;
-} /* csr_sdio_linux_install_irq() */
-
-#ifdef CONFIG_PM
-
-/*
- * Power Management notifier
- */
-struct uf_sdio_mmc_pm_notifier
-{
-    struct list_head list;
-
-    CsrSdioFunction *sdio_ctx;
-    struct notifier_block pm_notifier;
-};
-
-/* PM notifier list head */
-static struct uf_sdio_mmc_pm_notifier uf_sdio_mmc_pm_notifiers = {
-    .sdio_ctx = NULL,
-};
-
-/*
- * ---------------------------------------------------------------------------
- * uf_sdio_mmc_register_pm_notifier
- * uf_sdio_mmc_unregister_pm_notifier
- *
- *      Register/unregister for power management events. A list is used to
- *      allow multiple card instances to be supported.
- *
- *  Arguments:
- *      sdio_ctx - CSR SDIO context to associate PM notifier to
- *
- *  Returns:
- *      Register function returns NULL on error
- * ---------------------------------------------------------------------------
- */
-static struct uf_sdio_mmc_pm_notifier *
-uf_sdio_mmc_register_pm_notifier(CsrSdioFunction *sdio_ctx)
-{
-    /* Allocate notifier context for this card instance */
-    struct uf_sdio_mmc_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_mmc_pm_notifier), GFP_KERNEL);
-
-    if (notifier_ctx)
-    {
-        notifier_ctx->sdio_ctx = sdio_ctx;
-        notifier_ctx->pm_notifier.notifier_call = uf_sdio_mmc_power_event;
-
-        list_add(&notifier_ctx->list, &uf_sdio_mmc_pm_notifiers.list);
-
-        if (register_pm_notifier(&notifier_ctx->pm_notifier)) {
-            printk(KERN_ERR "unifi: register_pm_notifier failed\n");
-        }
-    }
-
-    return notifier_ctx;
-}
-
-static void
-uf_sdio_mmc_unregister_pm_notifier(CsrSdioFunction *sdio_ctx)
-{
-    struct uf_sdio_mmc_pm_notifier *notifier_ctx;
-    struct list_head *node, *q;
-
-    list_for_each_safe(node, q, &uf_sdio_mmc_pm_notifiers.list) {
-        notifier_ctx = list_entry(node, struct uf_sdio_mmc_pm_notifier, list);
-
-        /* If it matches, unregister and free the notifier context */
-        if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
-        {
-            if (unregister_pm_notifier(&notifier_ctx->pm_notifier)) {
-                printk(KERN_ERR "unifi: unregister_pm_notifier failed\n");
-            }
-
-            /* Remove from list */
-            notifier_ctx->sdio_ctx = NULL;
-            list_del(node);
-            kfree(notifier_ctx);
-        }
-    }
-}
-
-/*
- * ---------------------------------------------------------------------------
- * uf_sdio_mmc_power_event
- *
- *      Handler for power management events.
- *
- *      We need to handle suspend/resume events while the userspace is unsuspended
- *      to allow the SME to run its suspend/resume state machines.
- *
- *  Arguments:
- *      event   event ID
- *
- *  Returns:
- *      Status of the event handling
- * ---------------------------------------------------------------------------
- */
-static int
-uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-    struct uf_sdio_mmc_pm_notifier *notifier_ctx = container_of(this,
-                                                                struct uf_sdio_mmc_pm_notifier,
-                                                                pm_notifier);
-
-    /* Call the CSR SDIO function driver's suspend/resume method
-     * while the userspace is unsuspended.
-     */
-    switch (event) {
-        case PM_POST_HIBERNATION:
-        case PM_POST_SUSPEND:
-            printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ );
-            if (sdio_func_drv && sdio_func_drv->resume) {
-                sdio_func_drv->resume(notifier_ctx->sdio_ctx);
-            }
-            break;
-
-        case PM_HIBERNATION_PREPARE:
-        case PM_SUSPEND_PREPARE:
-            printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ );
-            if (sdio_func_drv && sdio_func_drv->suspend) {
-                sdio_func_drv->suspend(notifier_ctx->sdio_ctx);
-            }
-            break;
-    }
-    return NOTIFY_DONE;
-}
-
-#endif /* CONFIG_PM */
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_glue_sdio_probe
- *
- *      Card insert callback.
- *
- * Arguments:
- *      func            Our (glue layer) context pointer.
- *
- * Returns:
- *      UniFi driver error code.
- * ---------------------------------------------------------------------------
- */
-static int
-uf_glue_sdio_probe(struct sdio_func *func,
-                   const struct sdio_device_id *id)
-{
-    int instance;
-    CsrSdioFunction *sdio_ctx;
-
-    /* First of all claim the SDIO driver */
-    sdio_claim_host(func);
-
-    /* Assume that the card is already powered */
-    card_is_powered = 1;
-
-    /* Assumes one card per host, which is true for SDIO */
-    instance = func->card->host->index;
-    printk("sdio bus_id: %16s - UniFi card 0x%X inserted\n",
-           sdio_func_id(func), instance);
-
-    /* Allocate context */
-    sdio_ctx = kmalloc(sizeof(CsrSdioFunction), GFP_KERNEL);
-    if (sdio_ctx == NULL) {
-        sdio_release_host(func);
-        return -ENOMEM;
-    }
-
-    /* Initialise the context */
-    sdio_ctx->sdioId.manfId  = func->vendor;
-    sdio_ctx->sdioId.cardId  = func->device;
-    sdio_ctx->sdioId.sdioFunction  = func->num;
-    sdio_ctx->sdioId.sdioInterface = func->class;
-    sdio_ctx->blockSize = func->cur_blksize;
-    sdio_ctx->priv = (void *)func;
-    sdio_ctx->features = 0;
-
-    /* Module parameter enables byte mode */
-    if (sdio_byte_mode) {
-        sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE;
-    }
-
-    if (func->card->host->caps & MMC_CAP_SD_HIGHSPEED) {
-        unifi_trace(NULL, UDBG1, "MMC_CAP_SD_HIGHSPEED is available\n");
-    }
-
-#ifdef MMC_QUIRK_LENIENT_FN0
-    func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
-#endif
-
-    /* Pass context to the SDIO driver */
-    sdio_set_drvdata(func, sdio_ctx);
-
-#ifdef CONFIG_PM
-    /* Register to get PM events */
-    if (uf_sdio_mmc_register_pm_notifier(sdio_ctx) == NULL) {
-        unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__);
-    }
-#endif
-
-    /* Register this device with the SDIO function driver */
-    /* Call the main UniFi driver inserted handler */
-    if (sdio_func_drv && sdio_func_drv->inserted) {
-        uf_add_os_device(instance, &func->dev);
-        sdio_func_drv->inserted(sdio_ctx);
-    }
-
-    /* We have finished, so release the SDIO driver */
-    sdio_release_host(func);
-
-#ifdef ANDROID_BUILD
-    /* Take the wakelock */
-    unifi_trace(NULL, UDBG1, "probe: take wake lock\n");
-    wake_lock(&unifi_sdio_wake_lock);
-#endif
-
-    return 0;
-} /* uf_glue_sdio_probe() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_glue_sdio_remove
- *
- *      Card removal callback.
- *
- * Arguments:
- *      func            Our (glue layer) context pointer.
- *
- * Returns:
- *      UniFi driver error code.
- * ---------------------------------------------------------------------------
- */
-static void
-uf_glue_sdio_remove(struct sdio_func *func)
-{
-    CsrSdioFunction *sdio_ctx;
-
-    sdio_ctx = sdio_get_drvdata(func);
-    if (!sdio_ctx) {
-        return;
-    }
-
-    unifi_info(NULL, "UniFi card removed\n");
-
-    /* Clean up the SDIO function driver */
-    if (sdio_func_drv && sdio_func_drv->removed) {
-        uf_remove_os_device(func->card->host->index);
-        sdio_func_drv->removed(sdio_ctx);
-    }
-
-#ifdef CONFIG_PM
-    /* Unregister for PM events */
-    uf_sdio_mmc_unregister_pm_notifier(sdio_ctx);
-#endif
-
-    kfree(sdio_ctx);
-
-} /* uf_glue_sdio_remove */
-
-
-/*
- * SDIO ids *must* be statically declared, so we can't take
- * them from the list passed in csr_sdio_register_driver().
- */
-static const struct sdio_device_id unifi_ids[] = {
-    { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_3) },
-    { SDIO_DEVICE(SDIO_MANF_ID_CSR,SDIO_CARD_ID_UNIFI_4) },
-    { /* end: all zeroes */				},
-};
-
-MODULE_DEVICE_TABLE(sdio, unifi_ids);
-
-#ifdef CONFIG_PM
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_glue_sdio_suspend
- *
- *      Card suspend callback. The userspace will already be suspended.
- *
- * Arguments:
- *      dev            The struct device owned by the MMC driver
- *
- * Returns:
- *      None
- * ---------------------------------------------------------------------------
- */
-static int
-uf_glue_sdio_suspend(struct device *dev)
-{
-    unifi_trace(NULL, UDBG1, "uf_glue_sdio_suspend");
-
-    return 0;
-} /* uf_glue_sdio_suspend */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_glue_sdio_resume
- *
- *      Card resume callback. The userspace will still be suspended.
- *
- * Arguments:
- *      dev            The struct device owned by the MMC driver
- *
- * Returns:
- *      None
- * ---------------------------------------------------------------------------
- */
-static int
-uf_glue_sdio_resume(struct device *dev)
-{
-    unifi_trace(NULL, UDBG1, "uf_glue_sdio_resume");
-
-#ifdef ANDROID_BUILD
-    unifi_trace(NULL, UDBG1, "resume: take wakelock\n");
-    wake_lock(&unifi_sdio_wake_lock);
-#endif
-
-    return 0;
-
-} /* uf_glue_sdio_resume */
-
-static struct dev_pm_ops unifi_pm_ops = {
-    .suspend = uf_glue_sdio_suspend,
-    .resume  = uf_glue_sdio_resume,
-};
-
-#define UNIFI_PM_OPS  (&unifi_pm_ops)
-
-#else
-
-#define UNIFI_PM_OPS  NULL
-
-#endif /* CONFIG_PM */
-
-static struct sdio_driver unifi_driver = {
-    .probe      = uf_glue_sdio_probe,
-    .remove     = uf_glue_sdio_remove,
-    .name       = "unifi",
-    .id_table	= unifi_ids,
-    .drv.pm     = UNIFI_PM_OPS,
-};
-
-
-/*
- * ---------------------------------------------------------------------------
- *  CsrSdioFunctionDriverRegister
- *  CsrSdioFunctionDriverUnregister
- *
- *      These functions are called from the main module load and unload
- *      functions. They perform the appropriate operations for the
- *      linux MMC/SDIO driver.
- *
- *  Arguments:
- *      sdio_drv    Pointer to the function driver's SDIO structure.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-CsrResult
-CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv)
-{
-    int r;
-
-    printk("UniFi: Using native Linux MMC driver for SDIO.\n");
-
-    if (sdio_func_drv) {
-        unifi_error(NULL, "sdio_mmc: UniFi driver already registered\n");
-        return CSR_SDIO_RESULT_INVALID_VALUE;
-    }
-
-#ifdef ANDROID_BUILD
-    wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work");
-#endif
-
-    /* Save the registered driver description */
-    /*
-     * FIXME:
-     * Need a table here to handle a call to register for just one function.
-     * mmc only allows us to register for the whole device
-     */
-    sdio_func_drv = sdio_drv;
-
-#ifdef CONFIG_PM
-    /* Initialise PM notifier list */
-    INIT_LIST_HEAD(&uf_sdio_mmc_pm_notifiers.list);
-#endif
-
-    /* Register ourself with mmc_core */
-    r = sdio_register_driver(&unifi_driver);
-    if (r) {
-        printk(KERN_ERR "unifi_sdio: Failed to register UniFi SDIO driver: %d\n", r);
-        return ConvertSdioToCsrSdioResult(r);
-    }
-
-    return CSR_RESULT_SUCCESS;
-} /* CsrSdioFunctionDriverRegister() */
-
-
-
-void
-CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv)
-{
-    printk(KERN_INFO "UniFi: unregister from MMC sdio\n");
-
-#ifdef ANDROID_BUILD
-    wake_lock_destroy(&unifi_sdio_wake_lock);
-#endif
-    sdio_unregister_driver(&unifi_driver);
-
-    sdio_func_drv = NULL;
-
-} /* CsrSdioFunctionDriverUnregister() */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sdio_stubs.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/sdio_stubs.c
--- linux-libre-3.10-gnu/drivers/staging/csr/sdio_stubs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sdio_stubs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,82 +0,0 @@
-/*
- * Stubs for some of the bottom edge functions.
- *
- * These stubs are optional functions in the bottom edge (SDIO driver
- * interface) API that not all platforms or SDIO drivers may support.
- *
- * They're declared as weak symbols so they can be overridden by
- * simply providing a non-weak declaration.
- *
- * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- */
-#include "csr_wifi_hip_unifi.h"
-
-void __attribute__((weak)) CsrSdioFunctionIdle(CsrSdioFunction *function)
-{
-}
-
-void __attribute__((weak)) CsrSdioFunctionActive(CsrSdioFunction *function)
-{
-}
-
-CsrResult __attribute__((weak)) CsrSdioPowerOn(CsrSdioFunction *function)
-{
-    return CSR_RESULT_SUCCESS;
-}
-
-void __attribute__((weak)) CsrSdioPowerOff(CsrSdioFunction *function)
-{
-}
-
-CsrResult __attribute__((weak)) CsrSdioHardReset(CsrSdioFunction *function)
-{
-    return CSR_SDIO_RESULT_NOT_RESET;
-}
-
-CsrResult __attribute__((weak)) CsrSdioBlockSizeSet(CsrSdioFunction *function,
-                                                   u16 blockSize)
-{
-    return CSR_RESULT_SUCCESS;
-}
-
-CsrResult __attribute__((weak)) CsrSdioSuspend(CsrSdioFunction *function)
-{
-    return CSR_RESULT_SUCCESS;
-}
-
-CsrResult __attribute__((weak)) CsrSdioResume(CsrSdioFunction *function)
-{
-    return CSR_RESULT_SUCCESS;
-}
-
-int __attribute__((weak)) csr_sdio_linux_install_irq(CsrSdioFunction *function)
-{
-    return 0;
-}
-
-int __attribute__((weak)) csr_sdio_linux_remove_irq(CsrSdioFunction *function)
-{
-    return 0;
-}
-
-void __attribute__((weak)) CsrSdioInsertedAcknowledge(CsrSdioFunction *function, CsrResult result)
-{
-}
-
-void __attribute__((weak)) CsrSdioRemovedAcknowledge(CsrSdioFunction *function)
-{
-}
-
-void __attribute__((weak)) CsrSdioSuspendAcknowledge(CsrSdioFunction *function, CsrResult result)
-{
-}
-
-void __attribute__((weak)) CsrSdioResumeAcknowledge(CsrSdioFunction *function, CsrResult result)
-{
-}
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sme_blocking.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_blocking.c
--- linux-libre-3.10-gnu/drivers/staging/csr/sme_blocking.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_blocking.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1466 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     sme_mgt_blocking.c
- *
- * PURPOSE:
- *      This file contains the driver specific implementation of
- *      the WEXT <==> SME MGT interface for all SME builds that support WEXT.
- *
- * Copyright (C) 2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-
-#include "unifi_priv.h"
-
-
-/*
- * This file also contains the implementation of the asynchronous
- * requests to the SME.
- *
- * Before calling an asynchronous SME function, we call sme_init_request()
- * which gets hold of the SME semaphore and updates the request status.
- * The semaphore makes sure that there is only one pending request to
- * the SME at a time.
- *
- * Now we are ready to call the SME function, but only if
- * sme_init_request() has returned 0.
- *
- * When the SME function returns, we need to wait
- * for the reply. This is done in sme_wait_for_reply().
- * If the request times-out, the request status is set to SME_REQUEST_TIMEDOUT
- * and the sme_wait_for_reply() returns.
- *
- * If the SME replies in time, we call sme_complete_request().
- * There we change the request status to SME_REQUEST_RECEIVED. This will
- * wake up the process waiting on sme_wait_for_reply().
- * It is important that we copy the reply data in priv->sme_reply
- * before calling sme_complete_request().
- *
- * Handling the wext requests, we need to block
- * until the SME sends the response to our request.
- * We use the sme_init_request() and sme_wait_for_reply()
- * to implement this behavior in the following functions:
- * sme_mgt_wifi_on()
- * sme_mgt_wifi_off()
- * sme_mgt_scan_full()
- * sme_mgt_scan_results_get_async()
- * sme_mgt_connect()
- * unifi_mgt_media_status_ind()
- * sme_mgt_disconnect()
- * sme_mgt_pmkid()
- * sme_mgt_key()
- * sme_mgt_mib_get()
- * sme_mgt_mib_set()
- * sme_mgt_versions_get()
- * sme_mgt_set_value()
- * sme_mgt_get_value()
- * sme_mgt_set_value_async()
- * sme_mgt_get_value_async()
- * sme_mgt_packet_filter_set()
- * sme_mgt_tspec()
- */
-
-
-/*
- * Handling the suspend and resume system events, we need to block
- * until the SME sends the response to our indication.
- * We use the sme_init_request() and sme_wait_for_reply()
- * to implement this behavior in the following functions:
- * sme_sys_suspend()
- * sme_sys_resume()
- */
-
-#define UNIFI_SME_MGT_SHORT_TIMEOUT    10000
-#define UNIFI_SME_MGT_LONG_TIMEOUT     19000
-#define UNIFI_SME_SYS_LONG_TIMEOUT     10000
-
-#ifdef UNIFI_DEBUG
-# define sme_wait_for_reply(priv, t) _sme_wait_for_reply(priv, t, __func__)
-#else
-# define sme_wait_for_reply(priv, t) _sme_wait_for_reply(priv, t, NULL)
-#endif
-
-static int
-sme_init_request(unifi_priv_t *priv)
-{
-    if (priv == NULL) {
-        unifi_error(priv, "sme_init_request: Invalid priv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG5, "sme_init_request: wait sem\n");
-
-    /* Grab the SME semaphore until the reply comes, or timeout */
-    if (down_interruptible(&priv->sme_sem)) {
-        unifi_error(priv, "sme_init_request: Failed to get SME semaphore\n");
-        return -EIO;
-    }
-    unifi_trace(priv, UDBG5, "sme_init_request: got sem: pending\n");
-
-    priv->sme_reply.request_status = SME_REQUEST_PENDING;
-
-    return 0;
-
-} /* sme_init_request() */
-
-
-void
-uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *func)
-{
-    if (priv == NULL) {
-        unifi_error(priv, "sme_complete_request: Invalid priv\n");
-        return;
-    }
-
-    if (priv->sme_reply.request_status != SME_REQUEST_PENDING) {
-        unifi_notice(priv,
-                    "sme_complete_request: request not pending %s (s:%d)\n",
-                    (func ? func : ""), priv->sme_reply.request_status);
-        return;
-    }
-    unifi_trace(priv, UDBG5,
-                "sme_complete_request: completed %s (s:%d)\n",
-                (func ? func : ""), priv->sme_reply.request_status);
-
-    priv->sme_reply.request_status = SME_REQUEST_RECEIVED;
-    priv->sme_reply.reply_status = reply_status;
-
-    wake_up_interruptible(&priv->sme_request_wq);
-
-    return;
-}
-
-
-void
-uf_sme_cancel_request(unifi_priv_t *priv, CsrResult reply_status)
-{
-    /* Check for a blocking SME request in progress, and cancel the wait.
-     * This should be used when the character device is closed.
-     */
-
-    if (priv == NULL) {
-        unifi_error(priv, "sme_cancel_request: Invalid priv\n");
-        return;
-    }
-
-    /* If no request is pending, nothing to wake up */
-    if (priv->sme_reply.request_status != SME_REQUEST_PENDING) {
-        unifi_trace(priv, UDBG5,
-                    "sme_cancel_request: no request was pending (s:%d)\n",
-                    priv->sme_reply.request_status);
-        /* Nothing to do */
-        return;
-    }
-    unifi_trace(priv, UDBG5,
-                "sme_cancel_request: request cancelled (s:%d)\n",
-                priv->sme_reply.request_status);
-
-    /* Wake up the wait with an error status */
-    priv->sme_reply.request_status = SME_REQUEST_CANCELLED;
-    priv->sme_reply.reply_status = reply_status; /* unimportant since the CANCELLED state will fail the ioctl */
-
-    wake_up_interruptible(&priv->sme_request_wq);
-
-    return;
-}
-
-
-static int
-_sme_wait_for_reply(unifi_priv_t *priv,
-        unsigned long timeout, const char *func)
-{
-    long r;
-
-    unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s sleep\n", func ? func : "");
-    r = wait_event_interruptible_timeout(priv->sme_request_wq,
-                                         (priv->sme_reply.request_status != SME_REQUEST_PENDING),
-                                         msecs_to_jiffies(timeout));
-    unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s awake (%d)\n", func ? func : "", r);
-
-    if (r == -ERESTARTSYS) {
-        /* The thread was killed */
-        unifi_info(priv, "ERESTARTSYS in _sme_wait_for_reply\n");
-        up(&priv->sme_sem);
-        return r;
-    }
-    if (priv->sme_reply.request_status == SME_REQUEST_CANCELLED) {
-        unifi_trace(priv, UDBG5, "Cancelled waiting for SME to reply (%s s:%d, t:%d, r:%d)\n",
-                    (func ? func : ""), priv->sme_reply.request_status, timeout, r);
-
-        /* Release the SME semaphore that was downed in sme_init_request() */
-        up(&priv->sme_sem);
-        return -EIO; /* fail the ioctl */
-    }
-    if ((r == 0) && (priv->sme_reply.request_status != SME_REQUEST_RECEIVED)) {
-        unifi_notice(priv, "Timeout waiting for SME to reply (%s s:%d, t:%d)\n",
-                     (func ? func : ""), priv->sme_reply.request_status, timeout);
-
-        priv->sme_reply.request_status = SME_REQUEST_TIMEDOUT;
-
-        /* Release the SME semaphore that was downed in sme_init_request() */
-        up(&priv->sme_sem);
-
-        return -ETIMEDOUT;
-    }
-
-    unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s received (%d)\n",
-                func ? func : "", r);
-
-    /* Release the SME semaphore that was downed in sme_init_request() */
-    up(&priv->sme_sem);
-
-    return 0;
-} /* sme_wait_for_reply() */
-
-
-
-
-#ifdef CSR_SUPPORT_WEXT
-int sme_mgt_wifi_on(unifi_priv_t *priv)
-{
-    u16 numElements;
-    CsrWifiSmeDataBlock* dataList;
-#ifdef CSR_SUPPORT_WEXT_AP
-    int r;
-#endif
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_wifi_on: invalid smepriv\n");
-        return -EIO;
-    }
-
-    if (priv->mib_data.length) {
-        numElements = 1;
-        dataList = &priv->mib_data;
-    } else {
-        numElements = 0;
-        dataList = NULL;
-    }
-    /* Start the SME */
-#ifdef CSR_SUPPORT_WEXT_AP
-    r = sme_init_request(priv);
-    if (r) {
-        return -EIO;
-    }
-#endif
-    CsrWifiSmeWifiOnReqSend(0, priv->sta_mac_address, numElements, dataList);
-#ifdef CSR_SUPPORT_WEXT_AP
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_wifi_on: unifi_mgt_wifi_oo_req <-- (r=%d, status=%d)\n",
-                r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    return 0;
-#endif
-} /* sme_mgt_wifi_on() */
-
-
-int sme_mgt_wifi_off(unifi_priv_t *priv)
-{
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_wifi_off: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    /* Stop the SME */
-    CsrWifiSmeWifiOffReqSend(0);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_wifi_off: unifi_mgt_wifi_off_req <-- (r=%d, status=%d)\n",
-                r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-
-} /* sme_mgt_wifi_off */
-
-int sme_mgt_key(unifi_priv_t *priv, CsrWifiSmeKey *sme_key,
-        CsrWifiSmeListAction action)
-{
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_key: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeKeyReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action, *sme_key);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-
-int sme_mgt_scan_full(unifi_priv_t *priv,
-        CsrWifiSsid *specific_ssid,
-        int num_channels,
-        unsigned char *channel_list)
-{
-    CsrWifiMacAddress bcastAddress = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }};
-    u8 is_active = (num_channels > 0) ? TRUE : FALSE;
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_scan_full: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_scan_full: -->\n");
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    /* If a channel list is provided, do an active scan */
-    if (is_active) {
-        unifi_trace(priv, UDBG1,
-                    "channel list - num_channels: %d, active scan\n",
-                    num_channels);
-    }
-
-    CsrWifiSmeScanFullReqSend(0,
-                              specific_ssid->length?1:0, /* 0 or 1 SSIDS */
-                              specific_ssid,
-                              bcastAddress,
-                              is_active,
-                              CSR_WIFI_SME_BSS_TYPE_ANY_BSS,
-                              CSR_WIFI_SME_SCAN_TYPE_ALL,
-                              (u16)num_channels, channel_list,
-                              0, NULL);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4, "sme_mgt_scan_full: <-- (status=%d)\n", priv->sme_reply.reply_status);
-    if (priv->sme_reply.reply_status == CSR_WIFI_RESULT_UNAVAILABLE)
-        return 0; /* initial scan already underway */
-    else
-        return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-
-int sme_mgt_scan_results_get_async(unifi_priv_t *priv,
-        struct iw_request_info *info,
-        char *scan_results,
-        long scan_results_len)
-{
-    u16 scan_result_list_count;
-    CsrWifiSmeScanResult *scan_result_list;
-    CsrWifiSmeScanResult *scan_result;
-    int r;
-    int i;
-    char *current_ev = scan_results;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_scan_results_get_async: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeScanResultsGetReqSend(0);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT);
-    if (r)
-        return r;
-
-    scan_result_list_count = priv->sme_reply.reply_scan_results_count;
-    scan_result_list = priv->sme_reply.reply_scan_results;
-    unifi_trace(priv, UDBG2,
-                "scan_results: Scan returned %d, numElements=%d\n",
-                r, scan_result_list_count);
-
-    /* OK, now we have the scan results */
-    for (i = 0; i < scan_result_list_count; ++i) {
-        scan_result = &scan_result_list[i];
-
-        unifi_trace(priv, UDBG2, "Scan Result: %.*s\n",
-                    scan_result->ssid.length,
-                    scan_result->ssid.ssid);
-
-        r = unifi_translate_scan(priv->netdev[0], info,
-                                 current_ev,
-                                 scan_results + scan_results_len,
-                                 scan_result, i+1);
-
-        if (r < 0) {
-            kfree(scan_result_list);
-            priv->sme_reply.reply_scan_results_count = 0;
-            priv->sme_reply.reply_scan_results = NULL;
-            return r;
-        }
-
-        current_ev += r;
-    }
-
-    /*
-     * Free the scan results allocated in unifi_mgt_scan_results_get_cfm()
-     * and invalidate the reply_scan_results to avoid re-using
-     * the freed pointers.
-     */
-    kfree(scan_result_list);
-    priv->sme_reply.reply_scan_results_count = 0;
-    priv->sme_reply.reply_scan_results = NULL;
-
-    unifi_trace(priv, UDBG2,
-                "scan_results: Scan translated to %d bytes\n",
-                current_ev - scan_results);
-    return (current_ev - scan_results);
-}
-
-
-int sme_mgt_connect(unifi_priv_t *priv)
-{
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_connect: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG2, "sme_mgt_connect: %.*s\n",
-                priv->connection_config.ssid.length,
-                priv->connection_config.ssid.ssid);
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeConnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE, priv->connection_config);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    if (priv->sme_reply.reply_status)
-        unifi_trace(priv, UDBG1, "sme_mgt_connect: failed with SME status %d\n",
-                    priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-
-int sme_mgt_disconnect(unifi_priv_t *priv)
-{
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_disconnect: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeDisconnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4, "sme_mgt_disconnect: <-- (status=%d)\n", priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-
-int sme_mgt_pmkid(unifi_priv_t *priv,
-        CsrWifiSmeListAction action,
-        CsrWifiSmePmkidList *pmkid_list)
-{
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_pmkid: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmePmkidReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action,
-                        pmkid_list->pmkidsCount, pmkid_list->pmkids);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4, "sme_mgt_pmkid: <-- (status=%d)\n", priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-
-int sme_mgt_mib_get(unifi_priv_t *priv,
-        unsigned char *varbind, int *length)
-{
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_mib_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    priv->mib_cfm_buffer = varbind;
-    priv->mib_cfm_buffer_length = MAX_VARBIND_LENGTH;
-
-    CsrWifiSmeMibGetReqSend(0, *length, varbind);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r) {
-        priv->mib_cfm_buffer_length = 0;
-        priv->mib_cfm_buffer = NULL;
-        return r;
-    }
-
-    *length = priv->mib_cfm_buffer_length;
-
-    priv->mib_cfm_buffer_length = 0;
-    priv->mib_cfm_buffer = NULL;
-    unifi_trace(priv, UDBG4, "sme_mgt_mib_get: <-- (status=%d)\n", priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-int sme_mgt_mib_set(unifi_priv_t *priv,
-        unsigned char *varbind, int length)
-{
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_mib_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeMibSetReqSend(0, length, varbind);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4, "sme_mgt_mib_set: <-- (status=%d)\n", priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-#endif /* CSR_SUPPORT_WEXT */
-
-int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_set_value_async: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmePowerConfigSetReqSend(0, *powerConfig);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_set_value_async: unifi_mgt_set_value_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_set_value: invalid smepriv\n");
-        return -EIO;
-    }
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtPowerConfigSetReq(priv->smepriv, *powerConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-int sme_mgt_sme_config_set(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, CsrWifiSmeDeviceConfig *deviceConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_sme_config_set: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeSmeStaConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, *staConfig);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_sme_config_set: CsrWifiSmeSmeStaConfigSetReq <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeSmeCommonConfigSetReqSend(0, *deviceConfig);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_sme_config_set: CsrWifiSmeSmeCommonConfigSetReq <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_sme_config_set: invalid smepriv\n");
-        return -EIO;
-    }
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtSmeConfigSetReq(priv->smepriv, *staConfig);
-    status = CsrWifiSmeMgtDeviceConfigSetReq(priv->smepriv, *deviceConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-#ifdef CSR_SUPPORT_WEXT
-
-int sme_mgt_mib_config_set(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_mib_config_set: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeMibConfigSetReqSend(0, *mibConfig);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_mib_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_mib_config_set: invalid smepriv\n");
-        return -EIO;
-    }
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtMibConfigSetReq(priv->smepriv, *mibConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-int sme_mgt_coex_config_set(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_coex_config_set: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeCoexConfigSetReqSend(0, *coexConfig);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_coex_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_coex_config_set: invalid smepriv\n");
-        return -EIO;
-    }
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtCoexConfigSetReq(priv->smepriv, *coexConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-#endif /* CSR_SUPPORT_WEXT */
-
-int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_host_config_set: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeHostConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, *hostConfig);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_host_config_set: unifi_mgt_set_host_config_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_host_config_set: invalid smepriv\n");
-        return -EIO;
-    }
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtHostConfigSetReq(priv->smepriv, *hostConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-#ifdef CSR_SUPPORT_WEXT
-
-int sme_mgt_versions_get(unifi_priv_t *priv, CsrWifiSmeVersions *versions)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_versions_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_versions_get: unifi_mgt_versions_get_req -->\n");
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeVersionsGetReqSend(0);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (versions != NULL) {
-        memcpy((unsigned char*)versions,
-               (unsigned char*)&priv->sme_reply.versions,
-               sizeof(CsrWifiSmeVersions));
-    }
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_versions_get: unifi_mgt_versions_get_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtVersionsGetReq(priv->smepriv, versions);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-#endif /* CSR_SUPPORT_WEXT */
-
-int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_power_config_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_power_config_get: unifi_mgt_power_config_req -->\n");
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmePowerConfigGetReqSend(0);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (powerConfig != NULL) {
-        memcpy((unsigned char*)powerConfig,
-               (unsigned char*)&priv->sme_reply.powerConfig,
-               sizeof(CsrWifiSmePowerConfig));
-    }
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_get_versions: unifi_mgt_power_config_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtPowerConfigGetReq(priv->smepriv, powerConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-int sme_mgt_host_config_get(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_host_config_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_host_config_get: unifi_mgt_host_config_get_req -->\n");
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeHostConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (hostConfig != NULL)
-        memcpy((unsigned char*)hostConfig,
-               (unsigned char*)&priv->sme_reply.hostConfig,
-               sizeof(CsrWifiSmeHostConfig));
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_host_config_get: unifi_mgt_host_config_get_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtHostConfigGetReq(priv->smepriv, hostConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-int sme_mgt_sme_config_get(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, CsrWifiSmeDeviceConfig *deviceConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_sme_config_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_sme_config_get: unifi_mgt_sme_config_get_req -->\n");
-
-    /* Common device config */
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeSmeCommonConfigGetReqSend(0);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (deviceConfig != NULL)
-        memcpy((unsigned char*)deviceConfig,
-               (unsigned char*)&priv->sme_reply.deviceConfig,
-               sizeof(CsrWifiSmeDeviceConfig));
-
-    /* STA config */
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeSmeStaConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (staConfig != NULL)
-        memcpy((unsigned char*)staConfig,
-               (unsigned char*)&priv->sme_reply.staConfig,
-               sizeof(CsrWifiSmeStaConfig));
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_sme_config_get: unifi_mgt_sme_config_get_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtSmeConfigGetReq(priv->smepriv, staConfig);
-    status = CsrWifiSmeMgtDeviceConfigGetReq(priv->smepriv, deviceConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-int sme_mgt_coex_info_get(unifi_priv_t *priv, CsrWifiSmeCoexInfo *coexInfo)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_coex_info_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req -->\n");
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeCoexInfoGetReqSend(0);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (coexInfo != NULL)
-        memcpy((unsigned char*)coexInfo,
-               (unsigned char*)&priv->sme_reply.coexInfo,
-               sizeof(CsrWifiSmeCoexInfo));
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtCoexInfoGetReq(priv->smepriv, coexInfo);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-#ifdef CSR_SUPPORT_WEXT
-
-int sme_mgt_coex_config_get(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_coex_config_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req -->\n");
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeCoexConfigGetReqSend(0);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (coexConfig != NULL)
-        memcpy((unsigned char*)coexConfig,
-               (unsigned char*)&priv->sme_reply.coexConfig,
-               sizeof(CsrWifiSmeCoexConfig));
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtCoexConfigGetReq(priv->smepriv, coexConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-int sme_mgt_mib_config_get(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_mib_config_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req -->\n");
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeMibConfigGetReqSend(0);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (mibConfig != NULL)
-        memcpy((unsigned char*)mibConfig,
-               (unsigned char*)&priv->sme_reply.mibConfig,
-               sizeof(CsrWifiSmeMibConfig));
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtMibConfigGetReq(priv->smepriv, mibConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-int sme_mgt_connection_info_get(unifi_priv_t *priv, CsrWifiSmeConnectionInfo *connectionInfo)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_connection_info_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req -->\n");
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeConnectionInfoGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (connectionInfo != NULL)
-        memcpy((unsigned char*)connectionInfo,
-               (unsigned char*)&priv->sme_reply.connectionInfo,
-               sizeof(CsrWifiSmeConnectionInfo));
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtConnectionInfoGetReq(priv->smepriv, connectionInfo);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-int sme_mgt_connection_config_get(unifi_priv_t *priv, CsrWifiSmeConnectionConfig *connectionConfig)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_connection_config_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req -->\n");
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeConnectionConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (connectionConfig != NULL)
-        memcpy((unsigned char*)connectionConfig,
-               (unsigned char*)&priv->sme_reply.connectionConfig,
-               sizeof(CsrWifiSmeConnectionConfig));
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtConnectionConfigGetReq(priv->smepriv, connectionConfig);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-int sme_mgt_connection_stats_get(unifi_priv_t *priv, CsrWifiSmeConnectionStats *connectionStats)
-{
-#ifdef CSR_SME_USERSPACE
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_mgt_connection_stats_get: invalid smepriv\n");
-        return -EIO;
-    }
-
-    unifi_trace(priv, UDBG4, "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req -->\n");
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiSmeConnectionStatsGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    /* store the reply */
-    if (connectionStats != NULL)
-        memcpy((unsigned char*)connectionStats,
-               (unsigned char*)&priv->sme_reply.connectionStats,
-               sizeof(CsrWifiSmeConnectionStats));
-
-    unifi_trace(priv, UDBG4,
-                "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-
-    return convert_sme_error(priv->sme_reply.reply_status);
-#else
-    CsrResult status;
-    CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
-    status = CsrWifiSmeMgtConnectionStatsGetReq(priv->smepriv, connectionStats);
-    CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
-    return convert_sme_error(status);
-#endif
-}
-
-#endif /* CSR_SUPPORT_WEXT */
-
-int sme_mgt_packet_filter_set(unifi_priv_t *priv)
-{
-	CsrWifiIp4Address ipAddress = {{0xFF, 0xFF, 0xFF, 0xFF }};
-	if (priv->smepriv == NULL) {
-		unifi_error(priv, "sme_mgt_packet_filter_set: invalid smepriv\n");
-		return -EIO;
-	}
-	if (priv->packet_filters.arp_filter) {
-		ipAddress.a[0] = (priv->sta_ip_address      ) & 0xFF;
-		ipAddress.a[1] = (priv->sta_ip_address >>  8) & 0xFF;
-		ipAddress.a[2] = (priv->sta_ip_address >> 16) & 0xFF;
-		ipAddress.a[3] = (priv->sta_ip_address >> 24) & 0xFF;
-	}
-
-	unifi_trace(priv, UDBG5,
-		"sme_mgt_packet_filter_set: IP address %d.%d.%d.%d\n",
-		ipAddress.a[0], ipAddress.a[1],
-		ipAddress.a[2], ipAddress.a[3]);
-
-	/* Doesn't block for a confirm */
-	CsrWifiSmePacketFilterSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE,
-				     priv->packet_filters.tclas_ies_length,
-				     priv->filter_tclas_ies,
-				     priv->packet_filters.filter_mode,
-				     ipAddress);
-	return 0;
-}
-
-int sme_mgt_tspec(unifi_priv_t *priv, CsrWifiSmeListAction action,
-        u32 tid, CsrWifiSmeDataBlock *tspec, CsrWifiSmeDataBlock *tclas)
-{
-	int r;
-
-	if (priv->smepriv == NULL) {
-		unifi_error(priv, "sme_mgt_tspec: invalid smepriv\n");
-		return -EIO;
-	}
-
-	r = sme_init_request(priv);
-	if (r)
-		return -EIO;
-
-	CsrWifiSmeTspecReqSend(0, CSR_WIFI_INTERFACE_IN_USE,
-			      action, tid, TRUE, 0,
-			      tspec->length, tspec->data,
-			      tclas->length, tclas->data);
-	r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-	if (r)
-		return r;
-
-	unifi_trace(priv, UDBG4, "sme_mgt_tspec: <-- (status=%d)\n", priv->sme_reply.reply_status);
-	return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-
-
-int sme_sys_suspend(unifi_priv_t *priv)
-{
-    int r;
-    CsrResult csrResult;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_sys_suspend: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    /* Suspend the SME, which MAY cause it to power down UniFi */
-    CsrWifiRouterCtrlSuspendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, 0, priv->wol_suspend);
-    r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT);
-    if (r) {
-        /* No reply - forcibly power down in case the request wasn't processed */
-        unifi_notice(priv,
-                     "suspend: SME did not reply %s, ",
-                     (priv->ptest_mode | priv->wol_suspend) ? "leave powered" : "power off UniFi anyway\n");
-
-        /* Leave power on for production test, though */
-        if (!priv->ptest_mode) {
-            /* Put UniFi to deep sleep, in case we can not power it off */
-            CsrSdioClaim(priv->sdio);
-            unifi_trace(priv, UDBG1, "Force deep sleep");
-            csrResult = unifi_force_low_power_mode(priv->card);
-
-            /* For WOL, the UniFi must stay powered */
-            if (!priv->wol_suspend) {
-                unifi_trace(priv, UDBG1, "Power off\n");
-                CsrSdioPowerOff(priv->sdio);
-            }
-            CsrSdioRelease(priv->sdio);
-        }
-    }
-
-    if (priv->wol_suspend) {
-        unifi_trace(priv, UDBG1, "UniFi left powered for WOL\n");
-
-        /* Remove the IRQ, which also disables the card SDIO interrupt.
-         * Disabling the card SDIO interrupt enables the PIO WOL source.
-         * Removal of the of the handler ensures that in both SDIO and PIO cases
-         * the card interrupt only wakes the host. The card will be polled
-         * after resume to handle any pending data.
-         */
-        if (csr_sdio_linux_remove_irq(priv->sdio)) {
-            unifi_notice(priv, "WOL csr_sdio_linux_remove_irq failed\n");
-        }
-
-        if (enable_wol == UNIFI_WOL_SDIO) {
-            /* Because csr_sdio_linux_remove_irq() disabled the card SDIO interrupt,
-             * it must be left enabled to wake-on-SDIO.
-             */
-            unifi_trace(priv, UDBG1, "Enable card SDIO interrupt for SDIO WOL\n");
-
-            CsrSdioClaim(priv->sdio);
-            csrResult = CsrSdioInterruptEnable(priv->sdio);
-            CsrSdioRelease(priv->sdio);
-
-            if (csrResult != CSR_RESULT_SUCCESS) {
-                unifi_error(priv, "WOL CsrSdioInterruptEnable failed %d\n", csrResult);
-            }
-        } else {
-            unifi_trace(priv, UDBG1, "Disabled card SDIO interrupt for PIO WOL\n");
-        }
-
-        /* Prevent the BH thread from running during the suspend.
-         * Upon resume, sme_sys_resume() will trigger a wifi-on, this will cause
-         * the BH thread to be re-enabled and reinstall the ISR.
-         */
-        priv->bh_thread.block_thread = 1;
-
-        unifi_trace(priv, UDBG1, "unifi_suspend: suspended BH");
-    }
-
-    /* Consider UniFi to be uninitialised */
-    priv->init_progress = UNIFI_INIT_NONE;
-
-    unifi_trace(priv, UDBG1, "sme_sys_suspend: <-- (r=%d status=%d)\n", r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-
-int sme_sys_resume(unifi_priv_t *priv)
-{
-    int r;
-
-    unifi_trace(priv, UDBG1, "sme_sys_resume %s\n", priv->wol_suspend ? "warm" : "");
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_sys_resume: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiRouterCtrlResumeIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, priv->wol_suspend);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT);
-    if (r)
-        unifi_notice(priv,
-                "resume: SME did not reply, return success anyway\n");
-
-    return 0;
-}
-
-#ifdef CSR_SUPPORT_WEXT_AP
-int sme_ap_stop(unifi_priv_t *priv,u16 interface_tag)
-{
-    int r;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_ap_stop: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiNmeApStopReqSend(0,interface_tag);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_ap_stop <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-
-}
-
-int sme_ap_start(unifi_priv_t *priv,u16 interface_tag,
-                 CsrWifiSmeApConfig_t * ap_config)
-{
-    int r;
-    CsrWifiSmeApP2pGoConfig p2p_go_param;
-    memset(&p2p_go_param,0,sizeof(CsrWifiSmeApP2pGoConfig));
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_ap_start: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiNmeApStartReqSend(0,interface_tag,CSR_WIFI_AP_TYPE_LEGACY,FALSE,
-                             ap_config->ssid,1,ap_config->channel,
-                             ap_config->credentials,ap_config->max_connections,
-                             p2p_go_param,FALSE);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-    if (r)
-        return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_ap_start <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-}
-
-int sme_ap_config(unifi_priv_t *priv,
-                  CsrWifiSmeApMacConfig *ap_mac_config,
-                  CsrWifiNmeApConfig *group_security_config)
-{
-    int r;
-    CsrWifiSmeApP2pGoConfig p2p_go_param;
-    memset(&p2p_go_param,0,sizeof(CsrWifiSmeApP2pGoConfig));
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_ap_config: invalid smepriv\n");
-        return -EIO;
-    }
-
-    r = sme_init_request(priv);
-    if (r)
-        return -EIO;
-
-    CsrWifiNmeApConfigSetReqSend(0,*group_security_config,
-                                 *ap_mac_config);
-
-    r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT);
-	if (r)
-		return r;
-
-    unifi_trace(priv, UDBG4,
-                "sme_ap_config <-- (r=%d status=%d)\n",
-                r, priv->sme_reply.reply_status);
-    return convert_sme_error(priv->sme_reply.reply_status);
-}
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sme_mgt.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_mgt.c
--- linux-libre-3.10-gnu/drivers/staging/csr/sme_mgt.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_mgt.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1012 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     sme_mgt.c
- *
- * PURPOSE:
- *      This file contains the driver specific implementation of
- *      the SME MGT SAP.
- *      It is part of the porting exercise.
- *
- * Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-
-#include "csr_wifi_hip_unifiversion.h"
-#include "unifi_priv.h"
-#include "csr_wifi_hip_conversions.h"
-/*
- * This file implements the SME MGT API. It contains the following functions:
- * CsrWifiSmeWifiFlightmodeCfmSend()
- * CsrWifiSmeWifiOnCfmSend()
- * CsrWifiSmeWifiOffCfmSend()
- * CsrWifiSmeWifiOffIndSend()
- * CsrWifiSmeScanFullCfmSend()
- * CsrWifiSmeScanResultsGetCfmSend()
- * CsrWifiSmeScanResultIndSend()
- * CsrWifiSmeScanResultsFlushCfmSend()
- * CsrWifiSmeConnectCfmSend()
- * CsrWifiSmeMediaStatusIndSend()
- * CsrWifiSmeDisconnectCfmSend()
- * CsrWifiSmeKeyCfmSend()
- * CsrWifiSmeMulticastAddressCfmSend()
- * CsrWifiSmeSetValueCfmSend()
- * CsrWifiSmeGetValueCfmSend()
- * CsrWifiSmeMicFailureIndSend()
- * CsrWifiSmePmkidCfmSend()
- * CsrWifiSmePmkidCandidateListIndSend()
- * CsrWifiSmeMibSetCfmSend()
- * CsrWifiSmeMibGetCfmSend()
- * CsrWifiSmeMibGetNextCfmSend()
- * CsrWifiSmeConnectionQualityIndSend()
- * CsrWifiSmePacketFilterSetCfmSend()
- * CsrWifiSmeTspecCfmSend()
- * CsrWifiSmeTspecIndSend()
- * CsrWifiSmeBlacklistCfmSend()
- * CsrWifiSmeEventMaskSetCfmSend()
- * CsrWifiSmeRoamStartIndSend()
- * CsrWifiSmeRoamCompleteIndSend()
- * CsrWifiSmeAssociationStartIndSend()
- * CsrWifiSmeAssociationCompleteIndSend()
- * CsrWifiSmeIbssStationIndSend()
- */
-
-
-void CsrWifiSmeMicFailureIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeMicFailureInd* ind = (CsrWifiSmeMicFailureInd*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeMicFailureIndSend: invalid priv\n");
-        return;
-    }
-
-    unifi_trace(priv, UDBG1,
-                "CsrWifiSmeMicFailureIndSend: count=%d, KeyType=%d\n",
-                ind->count, ind->keyType);
-
-    wext_send_michaelmicfailure_event(priv, ind->count, ind->address, ind->keyType, ind->interfaceTag);
-#endif
-}
-
-
-void CsrWifiSmePmkidCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmePmkidCfm* cfm = (CsrWifiSmePmkidCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmePmkidCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    /*
-     * WEXT never does a GET operation the PMKIDs, so we don't need
-     * handle data returned in pmkids.
-     */
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-
-void CsrWifiSmePmkidCandidateListIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmePmkidCandidateListInd* ind = (CsrWifiSmePmkidCandidateListInd*)msg;
-    int i;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "CsrWifiSmePmkidCandidateListIndSend: invalid smepriv\n");
-        return;
-    }
-
-    for (i = 0; i < ind->pmkidCandidatesCount; i++)
-    {
-        wext_send_pmkid_candidate_event(priv, ind->pmkidCandidates[i].bssid, ind->pmkidCandidates[i].preAuthAllowed, ind->interfaceTag);
-    }
-#endif
-}
-
-void CsrWifiSmeScanResultsFlushCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeScanResultsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeScanResultsGetCfm* cfm = (CsrWifiSmeScanResultsGetCfm*)msg;
-    int bytesRequired = cfm->scanResultsCount * sizeof(CsrWifiSmeScanResult);
-    int i;
-    u8* current_buff;
-    CsrWifiSmeScanResult* scanCopy;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeScanResultsGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    /* Calc the size of the buffer reuired */
-    for (i = 0; i < cfm->scanResultsCount; ++i) {
-        const CsrWifiSmeScanResult *scan_result = &cfm->scanResults[i];
-        bytesRequired += scan_result->informationElementsLength;
-    }
-
-    /* Take a Copy of the scan Results :-) */
-    scanCopy = kmalloc(bytesRequired, GFP_KERNEL);
-    memcpy(scanCopy, cfm->scanResults, sizeof(CsrWifiSmeScanResult) * cfm->scanResultsCount);
-
-    /* Take a Copy of the Info Elements AND update the scan result pointers */
-    current_buff = (u8*)&scanCopy[cfm->scanResultsCount];
-    for (i = 0; i < cfm->scanResultsCount; ++i)
-    {
-        CsrWifiSmeScanResult *scan_result = &scanCopy[i];
-        memcpy(current_buff, scan_result->informationElements, scan_result->informationElementsLength);
-        scan_result->informationElements = current_buff;
-        current_buff += scan_result->informationElementsLength;
-    }
-
-    priv->sme_reply.reply_scan_results_count = cfm->scanResultsCount;
-    priv->sme_reply.reply_scan_results = scanCopy;
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-
-void CsrWifiSmeScanFullCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeScanFullCfm* cfm = (CsrWifiSmeScanFullCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeScanFullCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-
-void CsrWifiSmeScanResultIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-
-}
-
-
-void CsrWifiSmeConnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeConnectCfm* cfm = (CsrWifiSmeConnectCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeConnectCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-
-void CsrWifiSmeDisconnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeDisconnectCfm* cfm = (CsrWifiSmeDisconnectCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeDisconnectCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-
-void CsrWifiSmeKeyCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeKeyCfm* cfm = (CsrWifiSmeKeyCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeKeyCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-
-void CsrWifiSmeMulticastAddressCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeMulticastAddressCfm* cfm = (CsrWifiSmeMulticastAddressCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeMulticastAddressCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeWifiFlightmodeCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeWifiFlightmodeCfm* cfm = (CsrWifiSmeWifiFlightmodeCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeWifiFlightmodeCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeWifiOnCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeWifiOnCfm* cfm = (CsrWifiSmeWifiOnCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeWifiOnCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    unifi_trace(priv, UDBG4,
-                "CsrWifiSmeWifiOnCfmSend: wake up status %d\n", cfm->status);
-#ifdef CSR_SUPPORT_WEXT_AP
-    sme_complete_request(priv, cfm->status);
-#endif
-
-#endif
-}
-
-void CsrWifiSmeWifiOffCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeWifiOffCfm* cfm = (CsrWifiSmeWifiOffCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeWifiOffCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-
-void CsrWifiSmeWifiOffIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeWifiOffInd* ind = (CsrWifiSmeWifiOffInd*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiRouterCtrlStoppedReqSend: Invalid ospriv.\n");
-        return;
-    }
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlStoppedReqSend: invalid smepriv\n");
-        return;
-    }
-
-    /*
-     * If the status indicates an error, the SME is in a stopped state.
-     * We need to start it again in order to reinitialise UniFi.
-     */
-    switch (ind->reason) {
-        case CSR_WIFI_SME_CONTROL_INDICATION_ERROR:
-          unifi_trace(priv, UDBG1,
-                      "CsrWifiRouterCtrlStoppedReqSend: Restarting SME (ind:%d)\n",
-                      ind->reason);
-
-          /* On error, restart the SME */
-          sme_mgt_wifi_on(priv);
-          break;
-        case CSR_WIFI_SME_CONTROL_INDICATION_EXIT:
-#ifdef CSR_SUPPORT_WEXT_AP
-          sme_complete_request(priv, 0);
-#endif
-          break;
-        default:
-          break;
-    }
-
-#endif
-}
-
-void CsrWifiSmeVersionsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeVersionsGetCfm* cfm = (CsrWifiSmeVersionsGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeVersionsGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.versions = cfm->versions;
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmePowerConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmePowerConfigGetCfm* cfm = (CsrWifiSmePowerConfigGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmePowerConfigGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.powerConfig = cfm->powerConfig;
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeHostConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeHostConfigGetCfm* cfm = (CsrWifiSmeHostConfigGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeHostConfigGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.hostConfig = cfm->hostConfig;
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeCoexInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeCoexInfoGetCfm* cfm = (CsrWifiSmeCoexInfoGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeCoexInfoGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.coexInfo = cfm->coexInfo;
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeCoexConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeCoexConfigGetCfm* cfm = (CsrWifiSmeCoexConfigGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeCoexConfigGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.coexConfig = cfm->coexConfig;
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeMibConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeMibConfigGetCfm* cfm = (CsrWifiSmeMibConfigGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeMibConfigGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.mibConfig = cfm->mibConfig;
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeConnectionInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeConnectionInfoGetCfm* cfm = (CsrWifiSmeConnectionInfoGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeConnectionInfoGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.connectionInfo = cfm->connectionInfo;
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeConnectionConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeConnectionConfigGetCfm* cfm = (CsrWifiSmeConnectionConfigGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeConnectionConfigGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.connectionConfig = cfm->connectionConfig;
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeConnectionStatsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeConnectionStatsGetCfm* cfm = (CsrWifiSmeConnectionStatsGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeConnectionStatsGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.connectionStats = cfm->connectionStats;
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeMibSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeMibSetCfm* cfm = (CsrWifiSmeMibSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeMibSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeMibGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeMibGetCfm* cfm = (CsrWifiSmeMibGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeMibGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    if (cfm->mibAttribute == NULL) {
-        unifi_error(priv, "CsrWifiSmeMibGetCfmSend: Empty reply.\n");
-        sme_complete_request(priv, cfm->status);
-        return;
-    }
-
-    if ((priv->mib_cfm_buffer != NULL) &&
-        (priv->mib_cfm_buffer_length >= cfm->mibAttributeLength)) {
-        memcpy(priv->mib_cfm_buffer, cfm->mibAttribute, cfm->mibAttributeLength);
-        priv->mib_cfm_buffer_length = cfm->mibAttributeLength;
-    } else {
-        unifi_error(priv,
-                    "CsrWifiSmeMibGetCfmSend: No room to store MIB data (have=%d need=%d).\n",
-                    priv->mib_cfm_buffer_length, cfm->mibAttributeLength);
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeMibGetNextCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeMibGetNextCfm* cfm = (CsrWifiSmeMibGetNextCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeMibGetNextCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    /* Need to copy MIB data */
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeConnectionQualityIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeConnectionQualityInd* ind = (CsrWifiSmeConnectionQualityInd*)msg;
-    int signal, noise, snr;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeConnectionQualityIndSend: Invalid ospriv.\n");
-        return;
-    }
-
-    /*
-     * level and noise below are mapped into an unsigned 8 bit number,
-     * ranging from [-192; 63]. The way this is achieved is simply to
-     * add 0x100 onto the number if it is negative,
-     * once clipped to the correct range.
-     */
-    signal = ind->linkQuality.unifiRssi;
-    /* Clip range of snr */
-    snr    = (ind->linkQuality.unifiSnr > 0) ? ind->linkQuality.unifiSnr : 0; /* In dB relative, from 0 - 255 */
-    snr    = (snr < 255) ? snr : 255;
-    noise  = signal - snr;
-
-    /* Clip range of signal */
-    signal = (signal < 63) ? signal : 63;
-    signal = (signal > -192) ? signal : -192;
-
-    /* Clip range of noise */
-    noise = (noise < 63) ? noise : 63;
-    noise = (noise > -192) ? noise : -192;
-
-    /* Make u8 */
-    signal = ( signal < 0 ) ? signal + 0x100 : signal;
-    noise = ( noise < 0 ) ? noise + 0x100 : noise;
-
-    priv->wext_wireless_stats.qual.level   = (u8)signal; /* -192 : 63 */
-    priv->wext_wireless_stats.qual.noise   = (u8)noise;  /* -192 : 63 */
-    priv->wext_wireless_stats.qual.qual    = snr;         /* 0 : 255 */
-    priv->wext_wireless_stats.qual.updated = 0;
-
-#if WIRELESS_EXT > 16
-    priv->wext_wireless_stats.qual.updated |= IW_QUAL_LEVEL_UPDATED |
-                                              IW_QUAL_NOISE_UPDATED |
-                                              IW_QUAL_QUAL_UPDATED;
-#if WIRELESS_EXT > 18
-    priv->wext_wireless_stats.qual.updated |= IW_QUAL_DBM;
-#endif
-#endif
-#endif
-}
-
-void CsrWifiSmePacketFilterSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmePacketFilterSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    /* The packet filter set request does not block for a reply */
-}
-
-void CsrWifiSmeTspecCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeTspecCfm* cfm = (CsrWifiSmeTspecCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeTspecCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeTspecIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeBlacklistCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeEventMaskSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-
-void CsrWifiSmeRoamStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeRoamCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    /* This is called when the association completes, before any 802.1x authentication */
-}
-
-void CsrWifiSmeAssociationStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeAssociationCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeIbssStationIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeWifiOnIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeRestrictedAccessEnableCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeRestrictedAccessDisableCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-
-void CsrWifiSmeAdhocConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeAdhocConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeAdhocConfigSetCfm* cfm = (CsrWifiSmeAdhocConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeCalibrationDataGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeCalibrationDataSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeCalibrationDataSetCfm* cfm = (CsrWifiSmeCalibrationDataSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeCcxConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeCcxConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeCcxConfigSetCfm* cfm = (CsrWifiSmeCcxConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeCloakedSsidsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeCloakedSsidsSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeCloakedSsidsSetCfm* cfm = (CsrWifiSmeCloakedSsidsSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-
-void CsrWifiSmeCoexConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeCoexConfigSetCfm* cfm = (CsrWifiSmeCoexConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeHostConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeHostConfigSetCfm* cfm = (CsrWifiSmeHostConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeLinkQualityGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-
-void CsrWifiSmeMibConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeMibConfigSetCfm* cfm = (CsrWifiSmeMibConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmePermanentMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmePowerConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmePowerConfigSetCfm* cfm = (CsrWifiSmePowerConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeRoamingConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeMediaStatusIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeMediaStatusInd* ind = (CsrWifiSmeMediaStatusInd*)msg;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "CsrWifiSmeMediaStatusIndSend: invalid smepriv\n");
-        return;
-    }
-
-    if (ind->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) {
-        /*
-         * Send wireless-extension event up to userland to announce
-         * connection.
-         */
-        wext_send_assoc_event(priv,
-                              (unsigned char *)ind->connectionInfo.bssid.a,
-                              (unsigned char *)ind->connectionInfo.assocReqInfoElements,
-                              ind->connectionInfo.assocReqInfoElementsLength,
-                              (unsigned char *)ind->connectionInfo.assocRspInfoElements,
-                              ind->connectionInfo.assocRspInfoElementsLength,
-                              (unsigned char *)ind->connectionInfo.assocScanInfoElements,
-                              ind->connectionInfo.assocScanInfoElementsLength);
-
-	unifi_trace(priv, UDBG2, "CsrWifiSmeMediaStatusIndSend: IBSS=%pM\n",
-				 ind->connectionInfo.bssid.a);
-
-        sme_mgt_packet_filter_set(priv);
-
-    } else  {
-        /*
-         * Send wireless-extension event up to userland to announce
-         * connection lost to a BSS.
-         */
-        wext_send_disassoc_event(priv);
-    }
-#endif
-}
-
-void CsrWifiSmeRoamingConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeRoamingConfigSetCfm* cfm = (CsrWifiSmeRoamingConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeRoamingConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeScanConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeScanConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_SUPPORT_WEXT
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeScanConfigSetCfm* cfm = (CsrWifiSmeScanConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-#endif
-}
-
-void CsrWifiSmeStationMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeSmeCommonConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeSmeCommonConfigGetCfm* cfm = (CsrWifiSmeSmeCommonConfigGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeCommonConfigGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.deviceConfig = cfm->deviceConfig;
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeSmeStaConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeSmeStaConfigGetCfm* cfm = (CsrWifiSmeSmeStaConfigGetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeStaConfigGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    priv->sme_reply.staConfig = cfm->smeConfig;
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeSmeCommonConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeSmeCommonConfigSetCfm* cfm = (CsrWifiSmeSmeCommonConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeCommonConfigGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeSmeStaConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiSmeSmeStaConfigSetCfm* cfm = (CsrWifiSmeSmeStaConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiSmeSmeStaConfigGetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeErrorIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeInfoIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeCoreDumpIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-void CsrWifiSmeAmpStatusChangeIndHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiSmeActivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-void CsrWifiSmeDeactivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-#ifdef CSR_SUPPORT_WEXT
-#ifdef CSR_SUPPORT_WEXT_AP
-void CsrWifiNmeApStartCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiNmeApStartCfm* cfm = (CsrWifiNmeApStartCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiNmeApStartCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiNmeApStopCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiNmeApStopCfm* cfm = (CsrWifiNmeApStopCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiNmeApStopCfmSend: Invalid ospriv.\n");
-        return;
-    }
-
-    sme_complete_request(priv, cfm->status);
-}
-
-void CsrWifiNmeApConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiNmeApConfigSetCfm* cfm = (CsrWifiNmeApConfigSetCfm*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiNmeApConfigSetCfmSend: Invalid ospriv.\n");
-        return;
-    }
-    sme_complete_request(priv, cfm->status);
-}
-#endif
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sme_native.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_native.c
--- linux-libre-3.10-gnu/drivers/staging/csr/sme_native.c	2013-07-01 10:38:12.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_native.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,566 +0,0 @@
-/*
- * ***************************************************************************
- *
- *  FILE:     sme_native.c
- *
- * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ***************************************************************************
- */
-
-#include <linux/netdevice.h>
-#include "unifi_priv.h"
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-
-static const unsigned char wildcard_address[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-int
-uf_sme_init(unifi_priv_t *priv)
-{
-    sema_init(&priv->mlme_blocking_mutex, 1);
-
-#ifdef CSR_SUPPORT_WEXT
-    {
-        int r = uf_init_wext_interface(priv);
-        if (r != 0) {
-            return r;
-        }
-    }
-#endif
-
-    return 0;
-} /* uf_sme_init() */
-
-
-void
-uf_sme_deinit(unifi_priv_t *priv)
-{
-
-    /* Free memory allocated for the scan table */
-/*    unifi_clear_scan_table(priv); */
-
-    /* Cancel any pending workqueue tasks */
-    flush_workqueue(priv->unifi_workqueue);
-
-#ifdef CSR_SUPPORT_WEXT
-    uf_deinit_wext_interface(priv);
-#endif
-
-} /* uf_sme_deinit() */
-
-
-int sme_mgt_wifi_on(unifi_priv_t *priv)
-{
-    int r,i;
-    s32 csrResult;
-
-    if (priv == NULL) {
-        return -EINVAL;
-    }
-    /* Initialize the interface mode to None */
-    for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
-        priv->interfacePriv[i]->interfaceMode = 0;
-    }
-
-    /* Set up interface mode so that get_packet_priority() can
-     * select the right QOS priority when WMM is enabled.
-     */
-    priv->interfacePriv[0]->interfaceMode = CSR_WIFI_ROUTER_CTRL_MODE_STA;
-
-    r = uf_reject_firmware_files(priv, UNIFI_FW_STA);
-    if (r) {
-        unifi_error(priv, "sme_mgt_wifi_on: Failed to get f/w\n");
-        return r;
-    }
-
-    /*
-     * The request to initialise UniFi might come while UniFi is running.
-     * We need to block all I/O activity until the reset completes, otherwise
-     * an SDIO error might occur resulting an indication to the SME which
-     * makes it think that the initialisation has failed.
-     */
-    priv->bh_thread.block_thread = 1;
-
-    /* Power on UniFi */
-    CsrSdioClaim(priv->sdio);
-    csrResult = CsrSdioPowerOn(priv->sdio);
-    CsrSdioRelease(priv->sdio);
-    if(csrResult != CSR_RESULT_SUCCESS && csrResult != CSR_SDIO_RESULT_NOT_RESET) {
-        return -EIO;
-    }
-
-    if (csrResult == CSR_RESULT_SUCCESS) {
-        /* Initialise UniFi hardware */
-        r = uf_init_hw(priv);
-        if (r) {
-            return r;
-        }
-    }
-
-    /* Re-enable the I/O thread */
-    priv->bh_thread.block_thread = 0;
-
-    /* Disable deep sleep signalling during the firmware initialisation, to
-     * prevent the wakeup mechanism raising the SDIO clock beyond INIT before
-     * the first MLME-RESET.ind. It gets re-enabled at the CONNECTED.ind,
-     * immediately after the MLME-RESET.ind
-     */
-    csrResult = unifi_configure_low_power_mode(priv->card,
-                                           UNIFI_LOW_POWER_DISABLED,
-                                           UNIFI_PERIODIC_WAKE_HOST_DISABLED);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_warning(priv,
-                      "sme_mgt_wifi_on: unifi_configure_low_power_mode() returned an error\n");
-    }
-
-
-    /* Start the I/O thread */
-    CsrSdioClaim(priv->sdio);
-    r = uf_init_bh(priv);
-    if (r) {
-        CsrSdioPowerOff(priv->sdio);
-        CsrSdioRelease(priv->sdio);
-        return r;
-    }
-    CsrSdioRelease(priv->sdio);
-
-    priv->init_progress = UNIFI_INIT_FW_DOWNLOADED;
-
-    return 0;
-}
-
-int
-sme_sys_suspend(unifi_priv_t *priv)
-{
-    const int interfaceNum = 0;     /* FIXME */
-    CsrResult csrResult;
-
-    /* Abort any pending requests. */
-    uf_abort_mlme(priv);
-
-    /* Allow our mlme request to go through. */
-    priv->io_aborted = 0;
-
-    /* Send MLME-RESET.req to UniFi. */
-    unifi_reset_state(priv, priv->netdev[interfaceNum]->dev_addr, 0);
-
-    /* Stop the network traffic */
-    netif_carrier_off(priv->netdev[interfaceNum]);
-
-    /* Put UniFi to deep sleep */
-    CsrSdioClaim(priv->sdio);
-    csrResult = unifi_force_low_power_mode(priv->card);
-    CsrSdioRelease(priv->sdio);
-
-    return 0;
-} /* sme_sys_suspend() */
-
-
-int
-sme_sys_resume(unifi_priv_t *priv)
-{
-#ifdef CSR_SUPPORT_WEXT
-    /* Send disconnect event so clients will re-initialise connection. */
-    memset(priv->wext_conf.current_ssid, 0, UNIFI_MAX_SSID_LEN);
-    memset((void*)priv->wext_conf.current_bssid, 0, ETH_ALEN);
-    priv->wext_conf.capability = 0;
-    wext_send_disassoc_event(priv);
-#endif
-    return 0;
-} /* sme_sys_resume() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  sme_native_log_event
- *
- *      Callback function to be registered as the SME event callback.
- *      Copies the signal content into a new udi_log_t struct and adds
- *      it to the read queue for the SME client.
- *
- *  Arguments:
- *      arg             This is the value given to unifi_add_udi_hook, in
- *                      this case a pointer to the client instance.
- *      signal          Pointer to the received signal.
- *      signal_len      Size of the signal structure in bytes.
- *      bulkdata        Pointers to any associated bulk data.
- *      dir             Direction of the signal. Zero means from host,
- *                      non-zero means to host.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-sme_native_log_event(ul_client_t *pcli,
-                     const u8 *sig_packed, int sig_len,
-                     const bulk_data_param_t *bulkdata,
-                     int dir)
-{
-    unifi_priv_t *priv;
-    udi_log_t *logptr;
-    u8 *p;
-    int i, r;
-    int signal_len;
-    int total_len;
-    udi_msg_t *msgptr;
-    CSR_SIGNAL signal;
-    ul_client_t *client = pcli;
-
-    if (client == NULL) {
-        unifi_error(NULL, "sme_native_log_event: client has exited\n");
-        return;
-    }
-
-    priv = uf_find_instance(client->instance);
-    if (!priv) {
-        unifi_error(priv, "invalid priv\n");
-        return;
-    }
-
-    /* Just a sanity check */
-    if ((sig_packed == NULL) || (sig_len <= 0)) {
-        return;
-    }
-
-    /* Get the unpacked signal */
-    r = read_unpack_signal(sig_packed, &signal);
-    if (r == 0) {
-        signal_len = SigGetSize(&signal);
-    } else {
-        u16 receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sig_packed) + sizeof(u16)) & 0xFF00;
-
-        /* The control indications are 1 byte, pass them to client. */
-        if (sig_len == 1) {
-            unifi_trace(priv, UDBG5,
-                        "Control indication (0x%x) for native SME.\n",
-                        *sig_packed);
-
-            *(u8*)&signal = *sig_packed;
-            signal_len = sig_len;
-        } else if (receiver_id == 0) {
-            /*
-             * Also "unknown" signals with a ReceiverId of 0 are passed to the client
-             * without unpacking. (This is a code size optimisation to allow signals
-             * that the driver not interested in to be dropped from the unpack code).
-             */
-            unifi_trace(priv, UDBG5,
-                        "Signal 0x%.4X with ReceiverId 0 for native SME.\n",
-                        CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed));
-
-            *(u8*)&signal = *sig_packed;
-            signal_len = sig_len;
-        } else {
-            unifi_error(priv,
-                        "sme_native_log_event - Received unknown signal 0x%.4X.\n",
-                        CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed));
-            return;
-        }
-    }
-
-    unifi_trace(priv, UDBG3, "sme_native_log_event: signal 0x%.4X for %d\n",
-                signal.SignalPrimitiveHeader.SignalId,
-                client->client_id);
-
-    total_len = signal_len;
-    /* Calculate the buffer we need to store signal plus bulk data */
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
-        total_len += bulkdata->d[i].data_length;
-    }
-
-    /* Allocate log structure plus actual signal. */
-    logptr = kmalloc(sizeof(udi_log_t) + total_len, GFP_KERNEL);
-
-    if (logptr == NULL) {
-        unifi_error(priv,
-                    "Failed to allocate %d bytes for a UDI log record\n",
-                    sizeof(udi_log_t) + total_len);
-        return;
-    }
-
-    /* Fill in udi_log struct */
-    INIT_LIST_HEAD(&logptr->q);
-    msgptr = &logptr->msg;
-    msgptr->length = sizeof(udi_msg_t) + total_len;
-    msgptr->timestamp = jiffies_to_msecs(jiffies);
-    msgptr->direction = dir;
-    msgptr->signal_length = signal_len;
-
-    /* Copy signal and bulk data to the log */
-    p = (u8 *)(msgptr + 1);
-    memcpy(p, &signal, signal_len);
-    p += signal_len;
-
-    /* Append any bulk data */
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
-        int len = bulkdata->d[i].data_length;
-
-        /*
-         * Len here might not be the same as the length in the bulk data slot.
-         * The slot length will always be even, but len could be odd.
-         */
-        if (len > 0) {
-            if (bulkdata->d[i].os_data_ptr) {
-                memcpy(p, bulkdata->d[i].os_data_ptr, len);
-            } else {
-                memset(p, 0, len);
-            }
-            p += len;
-        }
-    }
-
-    /* Add to tail of log queue */
-    down(&client->udi_sem);
-    list_add_tail(&logptr->q, &client->udi_log);
-    up(&client->udi_sem);
-
-    /* Wake any waiting user process */
-    wake_up_interruptible(&client->udi_wq);
-
-} /* sme_native_log_event() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_ta_indicate_protocol
- *
- *      Report that a packet of a particular type has been seen
- *
- *  Arguments:
- *      drv_priv        The device context pointer passed to ta_init.
- *      protocol        The protocol type enum value.
- *      direction       Whether the packet was a tx or rx.
- *      src_addr        The source MAC address from the data packet.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      We defer the actual sending to a background workqueue,
- *      see uf_ta_ind_wq().
- * ---------------------------------------------------------------------------
- */
-void
-unifi_ta_indicate_protocol(void *ospriv,
-                           CsrWifiRouterCtrlTrafficPacketType packet_type,
-                           CsrWifiRouterCtrlProtocolDirection direction,
-                           const CsrWifiMacAddress *src_addr)
-{
-
-} /* unifi_ta_indicate_protocol */
-
-/*
- * ---------------------------------------------------------------------------
- * unifi_ta_indicate_sampling
- *
- *      Send the TA sampling information to the SME.
- *
- *  Arguments:
- *      drv_priv        The device context pointer passed to ta_init.
- *      stats           The TA sampling data to send.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-unifi_ta_indicate_sampling(void *ospriv, CsrWifiRouterCtrlTrafficStats *stats)
-{
-
-} /* unifi_ta_indicate_sampling() */
-
-
-void
-unifi_ta_indicate_l4stats(void *ospriv,
-                            u32 rxTcpThroughput,
-                            u32 txTcpThroughput,
-                            u32 rxUdpThroughput,
-                            u32 txUdpThroughput)
-{
-
-} /* unifi_ta_indicate_l4stats() */
-
-/*
- * ---------------------------------------------------------------------------
- * uf_native_process_udi_signal
- *
- *      Process interesting signals from the UDI interface.
- *
- *  Arguments:
- *      pcli            A pointer to the client instance.
- *      signal          Pointer to the received signal.
- *      signal_len      Size of the signal structure in bytes.
- *      bulkdata        Pointers to any associated bulk data.
- *      dir             Direction of the signal. Zero means from host,
- *                      non-zero means to host.
- *
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-uf_native_process_udi_signal(ul_client_t *pcli,
-                             const u8 *packed_signal, int packed_signal_len,
-                             const bulk_data_param_t *bulkdata, int dir)
-{
-
-} /* uf_native_process_udi_signal() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  sme_native_mlme_event_handler
- *
- *      Callback function to be used as the udi_event_callback when registering
- *      as a client.
- *      This function implements a blocking request-reply interface for WEXT.
- *      To use it, a client specifies this function as the udi_event_callback
- *      to ul_register_client(). The signal dispatcher in
- *      unifi_receive_event() will call this function to deliver a signal.
- *
- *  Arguments:
- *      pcli            Pointer to the client instance.
- *      signal          Pointer to the received signal.
- *      signal_len      Size of the signal structure in bytes.
- *      bulkdata        Pointer to structure containing any associated bulk data.
- *      dir             Direction of the signal. Zero means from host,
- *                      non-zero means to host.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-sme_native_mlme_event_handler(ul_client_t *pcli,
-                              const u8 *sig_packed, int sig_len,
-                              const bulk_data_param_t *bulkdata,
-                              int dir)
-{
-    CSR_SIGNAL signal;
-    int signal_len;
-    unifi_priv_t *priv = uf_find_instance(pcli->instance);
-    int id, r;
-
-    /* Just a sanity check */
-    if ((sig_packed == NULL) || (sig_len <= 0)) {
-        return;
-    }
-
-    /* Get the unpacked signal */
-    r = read_unpack_signal(sig_packed, &signal);
-    if (r == 0) {
-        signal_len = SigGetSize(&signal);
-    } else {
-        unifi_error(priv,
-                    "sme_native_mlme_event_handler - Received unknown signal 0x%.4X.\n",
-                    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed));
-        return;
-    }
-
-    id = signal.SignalPrimitiveHeader.SignalId;
-    unifi_trace(priv, UDBG4, "wext - Process signal 0x%.4X\n", id);
-
-    /*
-     * Take the appropriate action for the signal.
-     */
-    switch (id) {
-        /*
-         * Confirm replies from UniFi.
-         * These all have zero or one CSR_DATAREF member. (FIXME: check this is still true for softmac)
-         */
-        case CSR_MA_PACKET_CONFIRM_ID:
-        case CSR_MLME_RESET_CONFIRM_ID:
-        case CSR_MLME_GET_CONFIRM_ID:
-        case CSR_MLME_SET_CONFIRM_ID:
-        case CSR_MLME_GET_NEXT_CONFIRM_ID:
-        case CSR_MLME_POWERMGT_CONFIRM_ID:
-        case CSR_MLME_SCAN_CONFIRM_ID:
-        case CSR_MLME_HL_SYNC_CONFIRM_ID:
-        case CSR_MLME_MEASURE_CONFIRM_ID:
-        case CSR_MLME_SETKEYS_CONFIRM_ID:
-        case CSR_MLME_DELETEKEYS_CONFIRM_ID:
-        case CSR_MLME_HL_SYNC_CANCEL_CONFIRM_ID:
-        case CSR_MLME_ADD_PERIODIC_CONFIRM_ID:
-        case CSR_MLME_DEL_PERIODIC_CONFIRM_ID:
-        case CSR_MLME_ADD_AUTONOMOUS_SCAN_CONFIRM_ID:
-        case CSR_MLME_DEL_AUTONOMOUS_SCAN_CONFIRM_ID:
-        case CSR_MLME_SET_PACKET_FILTER_CONFIRM_ID:
-        case CSR_MLME_STOP_MEASURE_CONFIRM_ID:
-        case CSR_MLME_PAUSE_AUTONOMOUS_SCAN_CONFIRM_ID:
-        case CSR_MLME_ADD_TRIGGERED_GET_CONFIRM_ID:
-        case CSR_MLME_DEL_TRIGGERED_GET_CONFIRM_ID:
-        case CSR_MLME_ADD_BLACKOUT_CONFIRM_ID:
-        case CSR_MLME_DEL_BLACKOUT_CONFIRM_ID:
-        case CSR_MLME_ADD_RX_TRIGGER_CONFIRM_ID:
-        case CSR_MLME_DEL_RX_TRIGGER_CONFIRM_ID:
-        case CSR_MLME_CONNECT_STATUS_CONFIRM_ID:
-        case CSR_MLME_MODIFY_BSS_PARAMETER_CONFIRM_ID:
-        case CSR_MLME_ADD_TEMPLATE_CONFIRM_ID:
-        case CSR_MLME_CONFIG_QUEUE_CONFIRM_ID:
-        case CSR_MLME_ADD_TSPEC_CONFIRM_ID:
-        case CSR_MLME_DEL_TSPEC_CONFIRM_ID:
-        case CSR_MLME_START_AGGREGATION_CONFIRM_ID:
-        case CSR_MLME_STOP_AGGREGATION_CONFIRM_ID:
-        case CSR_MLME_SM_START_CONFIRM_ID:
-        case CSR_MLME_LEAVE_CONFIRM_ID:
-        case CSR_MLME_SET_TIM_CONFIRM_ID:
-        case CSR_MLME_GET_KEY_SEQUENCE_CONFIRM_ID:
-        case CSR_MLME_SET_CHANNEL_CONFIRM_ID:
-        case CSR_MLME_ADD_MULTICAST_ADDRESS_CONFIRM_ID:
-        case CSR_DEBUG_GENERIC_CONFIRM_ID:
-            unifi_mlme_copy_reply_and_wakeup_client(pcli, &signal, signal_len, bulkdata);
-            break;
-
-        case CSR_MLME_CONNECTED_INDICATION_ID:
-            /* We currently ignore the connected-ind for softmac f/w development */
-            unifi_info(priv, "CSR_MLME_CONNECTED_INDICATION_ID ignored\n");
-            break;
-
-        default:
-            break;
-    }
-
-} /* sme_native_mlme_event_handler() */
-
-
-
-/*
- * -------------------------------------------------------------------------
- *  unifi_reset_state
- *
- *      Ensure that a MAC address has been set.
- *      Send the MLME-RESET signal.
- *      This must be called at least once before starting to do any
- *      network activities (e.g. scan, join etc).
- *
- * Arguments:
- *      priv            Pointer to device private context struct
- *      macaddr         Pointer to chip MAC address.
- *                      If this is FF:FF:FF:FF:FF:FF it will be replaced
- *                      with the MAC address from the chip.
- *      set_default_mib 1 if the f/w must reset the MIB to the default values
- *                      0 otherwise
- *
- * Returns:
- *      0 on success, an error code otherwise.
- * -------------------------------------------------------------------------
- */
-int
-unifi_reset_state(unifi_priv_t *priv, unsigned char *macaddr,
-                  unsigned char set_default_mib)
-{
-    int r = 0;
-
-#ifdef CSR_SUPPORT_WEXT
-    /* The reset clears any 802.11 association. */
-    priv->wext_conf.flag_associated = 0;
-#endif
-
-    return r;
-} /* unifi_reset_state() */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sme_sys.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_sys.c
--- linux-libre-3.10-gnu/drivers/staging/csr/sme_sys.c	2013-07-01 10:38:12.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_sys.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,3260 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     sme_sys.c
- *
- * PURPOSE:
- *      Driver specific implementation of the SME SYS SAP.
- *      It is part of the porting exercise.
- *
- * Copyright (C) 2008-2011 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-
-#include "csr_wifi_hip_unifiversion.h"
-#include "unifi_priv.h"
-#include "csr_wifi_hip_conversions.h"
-#ifdef CSR_SUPPORT_WEXT_AP
-#include "csr_wifi_sme_sef.h"
-#endif
-
-/*
- * This file implements the SME SYS API and contains the following functions:
- * CsrWifiRouterCtrlMediaStatusReqHandler()
- * CsrWifiRouterCtrlHipReqHandler()
- * CsrWifiRouterCtrlPortConfigureReqHandler()
- * CsrWifiRouterCtrlWifiOnReqHandler()
- * CsrWifiRouterCtrlWifiOffReqHandler()
- * CsrWifiRouterCtrlSuspendResHandler()
- * CsrWifiRouterCtrlResumeResHandler()
- * CsrWifiRouterCtrlQosControlReqHandler()
- * CsrWifiRouterCtrlConfigurePowerModeReqHandler()
- * CsrWifiRouterCtrlWifiOnResHandler()
- * CsrWifiRouterCtrlWifiOffRspHandler()
- * CsrWifiRouterCtrlMulticastAddressResHandler()
- * CsrWifiRouterCtrlTrafficConfigReqHandler()
- * CsrWifiRouterCtrlTrafficClassificationReqHandler()
- * CsrWifiRouterCtrlTclasAddReqHandler()
- * CsrWifiRouterCtrlTclasDelReqHandler()
- * CsrWifiRouterCtrlSetModeReqHandler()
- * CsrWifiRouterCtrlWapiMulticastFilterReqHandler()
- * CsrWifiRouterCtrlWapiUnicastFilterReqHandler()
- * CsrWifiRouterCtrlWapiUnicastTxPktReqHandler()
- * CsrWifiRouterCtrlWapiRxPktReqHandler()
- * CsrWifiRouterCtrlWapiFilterReqHandler()
- */
-
-#ifdef CSR_SUPPORT_SME
-static void check_inactivity_timer_expire_func(unsigned long data);
-void uf_send_disconnected_ind_wq(struct work_struct *work);
-#endif
-
-void send_auto_ma_packet_confirm(unifi_priv_t *priv,
-                                 netInterface_priv_t *interfacePriv,
-                                 struct list_head *buffered_frames_list)
-{
-    tx_buffered_packets_t *buffered_frame_item = NULL;
-    struct list_head *listHead;
-    struct list_head *placeHolder;
-    int client_id;
-
-    CSR_SIGNAL unpacked_signal;
-    u8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE];
-    u16 packed_siglen;
-
-
-    list_for_each_safe(listHead, placeHolder, buffered_frames_list)
-    {
-        buffered_frame_item = list_entry(listHead, tx_buffered_packets_t, q);
-
-        if(!buffered_frame_item) {
-            unifi_error(priv, "Entry should exist, otherwise it is a (BUG)\n");
-            continue;
-        }
-
-        if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_NONE) &&
-            (priv->wifi_on_state == wifi_on_done))
-        {
-
-            unifi_warning(priv, "Send MA_PACKET_CONFIRM to SenderProcessId = %x for (HostTag = %x TransmissionControl = %x)\n",
-                                 (buffered_frame_item->leSenderProcessId),
-                                 buffered_frame_item->hostTag,
-                                 buffered_frame_item->transmissionControl);
-
-            client_id = buffered_frame_item->leSenderProcessId & 0xFF00;
-
-            if (client_id == priv->sme_cli->sender_id)
-            {
-                /* construct a MA-PACKET.confirm message for SME */
-                memset(&unpacked_signal, 0, sizeof(unpacked_signal));
-                unpacked_signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_CONFIRM_ID;
-                unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId = buffered_frame_item->leSenderProcessId;
-                unpacked_signal.SignalPrimitiveHeader.SenderProcessId = CSR_WIFI_ROUTER_IFACEQUEUE;
-
-                unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,
-                                                                                                     interfacePriv->InterfaceTag);
-                unpacked_signal.u.MaPacketConfirm.TransmissionStatus = CSR_RESULT_FAILURE;
-                unpacked_signal.u.MaPacketConfirm.RetryCount = 0;
-                unpacked_signal.u.MaPacketConfirm.Rate = buffered_frame_item->rate;
-                unpacked_signal.u.MaPacketConfirm.HostTag = buffered_frame_item->hostTag;
-
-                write_pack(&unpacked_signal, sigbuf, &packed_siglen);
-                unifi_warning(priv, "MA_PACKET_CONFIRM for SME (0x%x, 0x%x, 0x%x, 0x%x)\n",
-                                         unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId,
-                                         unpacked_signal.SignalPrimitiveHeader.SenderProcessId,
-                                         unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier,
-                                         unpacked_signal.u.MaPacketConfirm.HostTag);
-
-                CsrWifiRouterCtrlHipIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
-                                            packed_siglen,
-                                            (u8 *)sigbuf,
-                                            0, NULL,
-                                            0, NULL);
-            }
-            else if((buffered_frame_item->hostTag & 0x80000000))
-            {
-                /* construct a MA-PACKET.confirm message for NME */
-                unifi_warning(priv, "MA_PACKET_CONFIRM for NME (0x%x, 0x%x, 0x%x, 0x%x)\n",
-                                    buffered_frame_item->leSenderProcessId,
-                                    buffered_frame_item->interfaceTag,
-                                    buffered_frame_item->transmissionControl,
-                                    (buffered_frame_item->hostTag & 0x3FFFFFFF));
-
-                CsrWifiRouterMaPacketCfmSend((buffered_frame_item->leSenderProcessId & 0xFF),
-                                            buffered_frame_item->interfaceTag,
-                                            CSR_RESULT_FAILURE,
-                                            (buffered_frame_item->hostTag & 0x3FFFFFFF),
-                                            buffered_frame_item->rate);
-
-            }
-            else
-            {
-                unifi_warning(priv, "Buffered packet dropped without sending a confirm\n");
-            }
-
-        }
-
-        list_del(listHead);
-        kfree(buffered_frame_item);
-        buffered_frame_item = NULL;
-    }
-}
-
-void CsrWifiRouterCtrlMediaStatusReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlMediaStatusReq* req = (CsrWifiRouterCtrlMediaStatusReq*)msg;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
-    unsigned long flags;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid smepriv\n");
-        return;
-    }
-    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid interfaceTag\n");
-        return;
-    }
-    unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlMediaStatusReqHandler: Mode = %d req->mediaStatus = %d\n",interfacePriv->interfaceMode,req->mediaStatus);
-    if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AMP) {
-        bulk_data_desc_t bulk_data;
-
-        bulk_data.data_length = 0;
-
-        spin_lock_irqsave(&priv->m4_lock, flags);
-        if (interfacePriv->m4_bulk_data.data_length > 0) {
-            bulk_data = interfacePriv->m4_bulk_data;
-            interfacePriv->m4_bulk_data.net_buf_length = 0;
-            interfacePriv->m4_bulk_data.data_length = 0;
-            interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
-        }
-        spin_unlock_irqrestore(&priv->m4_lock, flags);
-
-        if (bulk_data.data_length != 0) {
-            unifi_trace(priv, UDBG5, "CsrWifiRouterCtrlMediaStatusReqHandler: free M4\n");
-            unifi_net_data_free(priv, &bulk_data);
-        }
-
-        if ((req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) &&
-            (interfacePriv->connected != UnifiConnected)) {
-
-            switch(interfacePriv->interfaceMode){
-                case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-                case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-                    interfacePriv->connected = UnifiConnected;
-                    netif_carrier_on(priv->netdev[req->interfaceTag]);
-#ifdef CSR_SUPPORT_WEXT
-                    wext_send_started_event(priv);
-#endif
-                    unifi_trace(priv, UDBG1,
-                                "CsrWifiRouterCtrlMediaStatusReqHandler: AP/P2PGO setting netif_carrier_on\n");
-                    netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]);
-                    break;
-
-                default:
-#ifdef CSR_SUPPORT_WEXT
-                /* In the WEXT builds (sme and native), the userspace is not ready
-                 * to process any EAPOL or WAPI packets, until it has been informed
-                 * of the NETDEV_CHANGE.
-                 */
-                if (interfacePriv->netdev_callback_registered && (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI)) {
-                    interfacePriv->wait_netdev_change = TRUE;
-                    unifi_trace(priv, UDBG1,
-                                "CsrWifiRouterCtrlMediaStatusReqHandler: waiting for NETDEV_CHANGE\n");
-                    /*
-                     * Carrier can go to on, only after wait_netdev_change is set to TRUE.
-                     * Otherwise there can be a race in uf_netdev_event().
-                     */
-                    netif_carrier_on(priv->netdev[req->interfaceTag]);
-                    unifi_trace(priv, UDBG1,
-                                "CsrWifiRouterCtrlMediaStatusReqHandler: STA/P2PCLI setting netif_carrier_on\n");
-                }
-                else
-#endif
-                {
-                    /* In the NME build, the userspace does not wait for the NETDEV_CHANGE
-                     * so it is ready to process all the EAPOL or WAPI packets.
-                     * At this point, we enable all the Tx queues, and we indicate any packets
-                     * that are queued (and the respective port is opened).
-                     */
-                    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
-                    interfacePriv->connected = UnifiConnected;
-                    unifi_trace(priv, UDBG1,
-                                "CsrWifiRouterMediaStatusReqHandler: UnifiConnected && netif_carrier_on\n");
-                    netif_carrier_on(priv->netdev[req->interfaceTag]);
-                    netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]);
-                    uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag);
-                    uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag);
-                }
-                break;
-            }
-        }
-
-        if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED) {
-#ifdef CSR_SUPPORT_WEXT
-            unifi_trace(priv, UDBG1,
-                        "CsrWifiRouterMediaStatusReqHandler: cancel waiting for NETDEV_CHANGE\n");
-            interfacePriv->wait_netdev_change = FALSE;
-#endif
-            unifi_trace(priv, UDBG1,
-                        "CsrWifiRouterMediaStatusReqHandler: setting netif_carrier_off\n");
-            netif_carrier_off(priv->netdev[req->interfaceTag]);
-#ifdef CSR_SUPPORT_WEXT
-            switch(interfacePriv->interfaceMode){
-                case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-                case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-                     wext_send_started_event(priv);
-                     break;
-                default:
-                     break;
-            }
-#endif
-            interfacePriv->connected = UnifiNotConnected;
-        }
-    } else {
-        /* For AMP, just update the L2 connected flag */
-        if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) {
-            unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP connected\n");
-            interfacePriv->connected = UnifiConnected;
-        } else {
-            unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP disconnected\n");
-            interfacePriv->connected = UnifiNotConnected;
-        }
-    }
-}
-
-
-void CsrWifiRouterCtrlHipReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlHipReq* hipreq = (CsrWifiRouterCtrlHipReq*)msg;
-    bulk_data_param_t bulkdata;
-    u8 *signal_ptr;
-    int signal_length;
-    int r=0;
-    void *dest;
-    CsrResult csrResult;
-    CSR_SIGNAL *signal;
-    u16 interfaceTag = 0;
-    CSR_MA_PACKET_REQUEST *req;
-    netInterface_priv_t *interfacePriv;
-
-    if (priv == NULL) {
-        return;
-    }
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid smepriv\n");
-        return;
-    }
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid interfaceTag\n");
-        return;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    /* Initialize bulkdata to avoid os_net_buf is garbage */
-    memset(&bulkdata, 0, sizeof(bulk_data_param_t));
-
-    signal = (CSR_SIGNAL *)hipreq->mlmeCommand;
-
-    unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: 0x04%X ---->\n",
-                *((u16*)hipreq->mlmeCommand));
-
-    /* Construct the signal. */
-    signal_ptr = (u8*)hipreq->mlmeCommand;
-    signal_length = hipreq->mlmeCommandLength;
-
-    /*
-     * The MSB of the sender ID needs to be set to the client ID.
-     * The LSB is controlled by the SME.
-     */
-    signal_ptr[5] = (priv->sme_cli->sender_id >> 8) & 0xff;
-
-    /* Allocate buffers for the bulk data. */
-    if (hipreq->dataRef1Length) {
-        csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], hipreq->dataRef1Length);
-        if (csrResult == CSR_RESULT_SUCCESS) {
-            dest = (void*)bulkdata.d[0].os_data_ptr;
-            memcpy(dest, hipreq->dataRef1, hipreq->dataRef1Length);
-            bulkdata.d[0].data_length = hipreq->dataRef1Length;
-        } else {
-            unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n");
-            return;
-        }
-    } else {
-        bulkdata.d[0].os_data_ptr = NULL;
-        bulkdata.d[0].data_length = 0;
-    }
-    if (hipreq->dataRef2Length) {
-        csrResult = unifi_net_data_malloc(priv, &bulkdata.d[1], hipreq->dataRef2Length);
-        if (csrResult == CSR_RESULT_SUCCESS) {
-            dest = (void*)bulkdata.d[1].os_data_ptr;
-            memcpy(dest, hipreq->dataRef2, hipreq->dataRef2Length);
-            bulkdata.d[1].data_length = hipreq->dataRef2Length;
-        } else {
-            if (bulkdata.d[0].data_length)
-            {
-                unifi_net_data_free(priv, &bulkdata.d[0]);
-            }
-            unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n");
-            return;
-        }
-    } else {
-        bulkdata.d[1].os_data_ptr = NULL;
-        bulkdata.d[1].data_length = 0;
-    }
-
-    unifi_trace(priv, UDBG3, "SME SEND: Signal 0x%.4X \n",
-                *((u16*)signal_ptr));
-    if (signal->SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_REQUEST_ID)
-    {
-        CSR_SIGNAL unpacked_signal;
-        read_unpack_signal((u8 *) signal, &unpacked_signal);
-        req = &unpacked_signal.u.MaPacketRequest;
-        interfaceTag = req->VirtualInterfaceIdentifier & 0xff;
-        switch(interfacePriv->interfaceMode)
-        {
-            case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
-                unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid mode: NONE \n");
-                break;
-            default:
-                unifi_trace(priv, UDBG5, "mode is %x\n", interfacePriv->interfaceMode);
-        }
-        /* While sending ensure that first 2 bits b31 and b30 are 00. These are used for local routing*/
-        r = uf_process_ma_packet_req(priv, req->Ra.x, (req->HostTag & 0x3FFFFFFF), interfaceTag,
-                                     req->TransmissionControl, req->TransmitRate,
-                                     req->Priority, signal->SignalPrimitiveHeader.SenderProcessId,
-                                     &bulkdata);
-        if (r)
-        {
-            if (bulkdata.d[0].data_length)
-            {
-                unifi_net_data_free(priv, &bulkdata.d[0]);
-            }
-            if (bulkdata.d[1].data_length)
-            {
-                unifi_net_data_free(priv, &bulkdata.d[1]);
-            }
-        }
-    } else {
-        /* ul_send_signal_raw frees the bulk data if it fails */
-        r = ul_send_signal_raw(priv, signal_ptr, signal_length, &bulkdata);
-    }
-
-    if (r) {
-        unifi_error(priv,
-                    "CsrWifiRouterCtrlHipReqHandler: Failed to send signal (0x%.4X - %u)\n",
-                    *((u16*)signal_ptr), r);
-        CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,CSR_WIFI_SME_CONTROL_INDICATION_ERROR);
-    }
-
-    unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: <----\n");
-}
-
-#ifdef CSR_WIFI_SEND_GRATUITOUS_ARP
-static void
-uf_send_gratuitous_arp(unifi_priv_t *priv, u16 interfaceTag)
-{
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    CSR_PRIORITY priority;
-    CSR_SIGNAL signal;
-    bulk_data_param_t bulkdata;
-    CsrResult csrResult;
-    struct sk_buff *skb, *newSkb = NULL;
-    s8 protection;
-    int r;
-    static const u8 arp_req[36] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,
-                                         0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
-                                         0x00, 0x02, 0x5f, 0x20, 0x2f, 0x02,
-                                         0xc0, 0xa8, 0x00, 0x02,
-                                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-                                         0xc0, 0xa8, 0x00, 0x02};
-
-    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], sizeof(arp_req));
-    if (csrResult != CSR_RESULT_SUCCESS)
-    {
-        unifi_error(priv, "Failed to allocate bulk data in CsrWifiSmeRoamCompleteIndHandler()\n");
-        return;
-    }
-    skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
-    skb->len = bulkdata.d[0].data_length;
-
-    memcpy(skb->data, arp_req, sizeof(arp_req));
-    /* add MAC and IP address */
-    memcpy(skb->data + 16, priv->netdev[interfaceTag]->dev_addr, ETH_ALEN);
-    skb->data[22] = (priv->sta_ip_address      ) & 0xFF;
-    skb->data[23] = (priv->sta_ip_address >>  8) & 0xFF;
-    skb->data[24] = (priv->sta_ip_address >> 16) & 0xFF;
-    skb->data[25] = (priv->sta_ip_address >> 24) & 0xFF;
-    skb->data[32] = (priv->sta_ip_address      ) & 0xFF;
-    skb->data[33] = (priv->sta_ip_address >>  8) & 0xFF;
-    skb->data[34] = (priv->sta_ip_address >> 16) & 0xFF;
-    skb->data[35] = (priv->sta_ip_address >> 24) & 0xFF;
-
-    bulkdata.d[1].os_data_ptr = NULL;
-    bulkdata.d[1].os_net_buf_ptr = NULL;
-    bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
-
-    if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, &arp_req[26])) < 0)
-    {
-        unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: Failed to determine protection mode\n");
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-        return;
-    }
-
-    if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1)
-    {
-        priority = CSR_QOS_UP0;
-    }
-    else
-    {
-        priority = CSR_CONTENTION;
-    }
-
-    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata,
-                                  interfaceTag, &arp_req[26],
-                                  priv->netdev[interfaceTag]->dev_addr, protection))
-    {
-        unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: failed to create MAC header\n");
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-        return;
-    }
-    bulkdata.d[0].os_data_ptr = skb->data;
-    bulkdata.d[0].os_net_buf_ptr = skb;
-    bulkdata.d[0].data_length = skb->len;
-
-    unifi_frame_ma_packet_req(priv, priority, 0, 0xffffffff, interfaceTag,
-                              CSR_NO_CONFIRM_REQUIRED, priv->netdev_client->sender_id,
-                              interfacePriv->bssid.a, &signal);
-
-    r = ul_send_signal_unpacked(priv, &signal, &bulkdata);
-    if (r)
-    {
-        unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: failed to send QOS data null packet result: %d\n",r);
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-        return;
-    }
-
-}
-#endif /* CSR_WIFI_SEND_GRATUITOUS_ARP */
-
-/*
- * ---------------------------------------------------------------------------
- * configure_data_port
- *
- *      Store the new controlled port configuration.
- *
- * Arguments:
- *      priv            Pointer to device private context struct
- *      port_cfg        Pointer to the port configuration
- *
- * Returns:
- *      An unifi_ControlledPortAction value.
- * ---------------------------------------------------------------------------
- */
-static int
-configure_data_port(unifi_priv_t *priv,
-        CsrWifiRouterCtrlPortAction port_action,
-        const CsrWifiMacAddress *macAddress,
-        const int queue,
-        u16 interfaceTag)
-{
-    const u8 broadcast_mac_address[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
-    unifi_port_config_t *port;
-    netInterface_priv_t *interfacePriv;
-    int i;
-    const char* controlled_string; /* cosmetic "controlled"/"uncontrolled" for trace */
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "configure_data_port: bad interfaceTag\n");
-        return -EFAULT;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if (queue == UF_CONTROLLED_PORT_Q) {
-        port = &interfacePriv->controlled_data_port;
-        controlled_string = "controlled";
-    } else {
-        port = &interfacePriv->uncontrolled_data_port;
-        controlled_string = "uncontrolled";
-    }
-
-	unifi_trace(priv, UDBG2,
-		"port config request %pM %s with port_action %d.\n",
-		macAddress->a, controlled_string, port_action);
-
-    /* If the new configuration has the broadcast MAC address or if we are in infrastructure mode then clear the list first and set port overide mode */
-    if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode ||
-        interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) ||
-        !memcmp(macAddress->a, broadcast_mac_address, ETH_ALEN)) {
-
-        port->port_cfg[0].port_action = port_action;
-        port->port_cfg[0].mac_address = *macAddress;
-        port->port_cfg[0].in_use = TRUE;
-        port->entries_in_use = 1;
-        port->overide_action = UF_DATA_PORT_OVERIDE;
-
-        unifi_trace(priv, UDBG2, "%s port override on\n",
-                    (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
-
-        /* Discard the remaining entries in the port config table */
-        for (i = 1; i < UNIFI_MAX_CONNECTIONS; i++) {
-            port->port_cfg[i].in_use = FALSE;
-        }
-
-        if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
-            unifi_trace(priv, UDBG1, "%s port broadcast set to open.\n",
-                        (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
-
-            /*
-             * Ask stack to schedule for transmission any packets queued
-             * while controlled port was not open.
-             * Use netif_schedule() instead of netif_wake_queue() because
-             * transmission should be already enabled at this point. If it
-             * is not, probably the interface is down and should remain as is.
-             */
-            uf_resume_data_plane(priv, queue, *macAddress, interfaceTag);
-
-#ifdef CSR_WIFI_SEND_GRATUITOUS_ARP
-            if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
-                (queue == UF_CONTROLLED_PORT_Q) && (priv->sta_ip_address != 0xFFFFFFFF))
-            {
-                uf_send_gratuitous_arp(priv, interfaceTag);
-            }
-#endif
-        } else {
-            unifi_trace(priv, UDBG1, "%s port broadcast set to %s.\n",
-                        (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled",
-                        (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) ? "discard": "closed");
-
-            /* If port is closed, discard all the pending Rx packets */
-            if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
-                uf_free_pending_rx_packets(priv, queue, *macAddress,interfaceTag);
-            }
-        }
-    } else {
-        /* store the new configuration, either in the entry with matching mac address (if already present),
-         * otherwise in a new entry
-         */
-
-        int found_entry_flag;
-        int first_free_slot = -1;
-
-        /* If leaving override mode, free the port entry used for override */
-        if (port->overide_action == UF_DATA_PORT_OVERIDE) {
-            port->port_cfg[0].in_use = FALSE;
-            port->entries_in_use = 0;
-            port->overide_action = UF_DATA_PORT_NOT_OVERIDE;
-
-            unifi_trace(priv, UDBG2, "%s port override off\n",
-                        (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
-        }
-
-        found_entry_flag = 0;
-        for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-            if (port->port_cfg[i].in_use) {
-                if (!memcmp(&port->port_cfg[i].mac_address.a, macAddress->a, ETH_ALEN)) {
-                    /* We've seen this address before, reconfigure it */
-                    port->port_cfg[i].port_action = port_action;
-                    found_entry_flag = 1;
-                    break;
-                }
-            } else if (first_free_slot == -1) {
-                /* Remember the first free slot on the way past so it can be claimed
-                 * if this turns out to be a new MAC address (to save walking the list again).
-                 */
-                first_free_slot = i;
-            }
-        }
-
-        /* At this point we found an existing entry and have updated it, or need to
-         * add a new entry. If all slots are allocated, give up and return an error.
-         */
-        if (!found_entry_flag) {
-            if (first_free_slot == -1) {
-                unifi_error(priv, "no free slot found in port config array (%d used)\n", port->entries_in_use);
-                return -EFAULT;
-            } else {
-                port->entries_in_use++;
-            }
-
-            unifi_trace(priv, UDBG3, "port config index assigned in config_data_port = %d\n", first_free_slot);
-            port->port_cfg[first_free_slot].in_use = TRUE;
-            port->port_cfg[first_free_slot].port_action = port_action;
-            port->port_cfg[first_free_slot].mac_address = *macAddress;
-        }
-
-        if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
-            /*
-             * Ask stack to schedule for transmission any packets queued
-             * while controlled port was not open.
-             * Use netif_schedule() instead of netif_wake_queue() because
-             * transmission should be already enabled at this point. If it
-             * is not, probably the interface is down and should remain as is.
-             */
-            uf_resume_data_plane(priv, queue, *macAddress, interfaceTag);
-        }
-
-        /*
-         * If port is closed, discard all the pending Rx packets
-         * coming from the peer station.
-         */
-        if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
-            uf_free_pending_rx_packets(priv, queue, *macAddress,interfaceTag);
-        }
-
-	unifi_trace(priv, UDBG2,
-		"port config %pM with port_action %d.\n",
-		macAddress->a, port_action);
-    }
-    return 0;
-} /* configure_data_port() */
-
-
-void CsrWifiRouterCtrlPortConfigureReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlPortConfigureReq* req = (CsrWifiRouterCtrlPortConfigureReq*)msg;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
-
-    unifi_trace(priv, UDBG3, "entering CsrWifiRouterCtrlPortConfigureReqHandler\n");
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlPortConfigureReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    /* To update the protection status of the peer/station */
-    switch(interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
-	    case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-            /* Since for Unifi as a station, the station record not maintained & interfaceID is
-             * only needed to update the peer protection status
-             */
-            interfacePriv->protect = req->setProtection;
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            {
-                u8 i;
-                CsrWifiRouterCtrlStaInfo_t *staRecord;
-                /* Ifscontrolled port is open means, The peer has been added to station record
-                 * so that the protection corresponding to the peer is valid in this req
-                 */
-                if (req->controlledPortAction == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
-                    for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
-                        staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
-                        if (staRecord) {
-                                /* Find the matching station record & set the protection type */
-                                if (!memcmp(req->macAddress.a, staRecord->peerMacAddress.a, ETH_ALEN)) {
-                                        staRecord->protection = req->setProtection;
-                                        break;
-                                }
-                        }
-                    }
-                }
-            }
-            break;
-        default:
-            unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlPortConfigureReqHandler(0x%.4X) Uncaught mode %d\n",
-                        msg->source, interfacePriv->interfaceMode);
-    }
-
-    configure_data_port(priv, req->uncontrolledPortAction, (const CsrWifiMacAddress *)&req->macAddress,
-                        UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
-    configure_data_port(priv, req->controlledPortAction, (const CsrWifiMacAddress *)&req->macAddress,
-                        UF_CONTROLLED_PORT_Q, req->interfaceTag);
-
-    CsrWifiRouterCtrlPortConfigureCfmSend(msg->source,req->clientData,req->interfaceTag,
-                                      CSR_RESULT_SUCCESS, req->macAddress);
-    unifi_trace(priv, UDBG3, "leaving CsrWifiRouterCtrlPortConfigureReqHandler\n");
-}
-
-
-void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlVersions versions;
-    CsrWifiRouterCtrlWifiOnReq* req = (CsrWifiRouterCtrlWifiOnReq*)msg;
-    int r,i;
-    CsrResult csrResult;
-
-    if (priv == NULL) {
-        return;
-    }
-    if( priv->wol_suspend ) {
-        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Don't reset mode\n");
-    } else {
-#ifdef ANDROID_BUILD
-        /* Take the wakelock while Wi-Fi On is in progress */
-        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: take wake lock\n");
-        wake_lock(&unifi_sdio_wake_lock);
-#endif
-        for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
-            unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Setting interface %d to NONE\n", i );
-
-            priv->interfacePriv[i]->interfaceMode = 0;
-        }
-    }
-    unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X) req->dataLength=%d req->data=0x%x\n", msg->source, req->dataLength, req->data);
-
-    if(req->dataLength==3 && req->data && req->data[0]==0 && req->data[1]==1 && req->data[2]==1)
-    {
-        priv->cmanrTestMode = TRUE;
-        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: cmanrTestMode=%d\n", priv->cmanrTestMode);
-    }
-    else
-    {
-        priv->cmanrTestMode = FALSE;
-    }
-
-    /*
-     * The request to initialise UniFi might come while UniFi is running.
-     * We need to block all I/O activity until the reset completes, otherwise
-     * an SDIO error might occur resulting an indication to the SME which
-     * makes it think that the initialisation has failed.
-     */
-    priv->bh_thread.block_thread = 1;
-
-    /* Update the wifi_on state */
-    priv->wifi_on_state = wifi_on_in_progress;
-
-    /* If UniFi was unpowered, acquire the firmware for download to chip */
-    if (!priv->wol_suspend) {
-        r = uf_reject_firmware_files(priv, UNIFI_FW_STA);
-        if (r) {
-            unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n");
-            CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
-            return;
-        }
-    } else {
-        unifi_trace(priv, UDBG1, "Don't need firmware\n");
-    }
-
-    /* Power on UniFi (which may not necessarily have been off) */
-    CsrSdioClaim(priv->sdio);
-    csrResult = CsrSdioPowerOn(priv->sdio);
-    CsrSdioRelease(priv->sdio);
-    if (csrResult != CSR_RESULT_SUCCESS && csrResult != CSR_SDIO_RESULT_NOT_RESET) {
-        unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to power on UniFi\n");
-        CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
-        return;
-    }
-
-    /* If CsrSdioPowerOn() returns CSR_RESULT_SUCCESS, it means that we need to initialise UniFi */
-    if (csrResult == CSR_RESULT_SUCCESS && !priv->wol_suspend) {
-        /* Initialise UniFi hardware */
-        r = uf_init_hw(priv);
-        if (r) {
-            unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
-            CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
-            return;
-        }
-    } else {
-        unifi_trace(priv, UDBG1, "UniFi already initialised\n");
-    }
-
-    /* Completed handling of wake up from suspend with UniFi powered */
-    priv->wol_suspend = FALSE;
-
-    /* Re-enable the I/O thread */
-    priv->bh_thread.block_thread = 0;
-
-    /*
-     * Start the I/O thread. The thread might be already running.
-     * This fine, just carry on with the request.
-     */
-    r = uf_init_bh(priv);
-    if (r) {
-        CsrSdioClaim(priv->sdio);
-        CsrSdioPowerOff(priv->sdio);
-        CsrSdioRelease(priv->sdio);
-        CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
-        return;
-    }
-
-    /* Get the version information from the core */
-    unifi_card_info(priv->card, &priv->card_info);
-
-    /* Set the sme queue id */
-    priv->CSR_WIFI_SME_IFACEQUEUE = msg->source;
-    CSR_WIFI_SME_IFACEQUEUE = msg->source;
-
-
-    /* Copy to the unifiio_card_info structure. */
-    versions.chipId = priv->card_info.chip_id;
-    versions.chipVersion = priv->card_info.chip_version;
-    versions.firmwareBuild = priv->card_info.fw_build;
-    versions.firmwareHip = priv->card_info.fw_hip_version;
-    versions.routerBuild = (char*)CSR_WIFI_VERSION;
-    versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
-
-    CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);
-
-    /* Update the wifi_on state */
-    priv->wifi_on_state = wifi_on_done;
-}
-
-
-/*
- * wifi_off:
- *      Common code for CsrWifiRouterCtrlWifiOffReqHandler() and
- *      CsrWifiRouterCtrlWifiOffRspHandler().
- */
-static void
-wifi_off(unifi_priv_t *priv)
-{
-    int power_off;
-    int priv_instance;
-    int i;
-    CsrResult csrResult;
-
-
-    /* Already off? */
-    if (priv->wifi_on_state == wifi_on_unspecified) {
-        unifi_trace(priv, UDBG1, "wifi_off already\n");
-        return;
-    }
-
-    unifi_trace(priv, UDBG1, "wifi_off\n");
-
-    /* Destroy the Traffic Analysis Module */
-    cancel_work_sync(&priv->ta_ind_work.task);
-    cancel_work_sync(&priv->ta_sample_ind_work.task);
-#ifdef CSR_SUPPORT_WEXT
-    cancel_work_sync(&priv->sme_config_task);
-    wext_send_disassoc_event(priv);
-#endif
-
-    /* Cancel pending M4 stuff */
-    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
-        if (priv->netdev[i]) {
-            netInterface_priv_t *netpriv = (netInterface_priv_t *) netdev_priv(priv->netdev[i]);
-            cancel_work_sync(&netpriv->send_m4_ready_task);
-        }
-    }
-    flush_workqueue(priv->unifi_workqueue);
-
-    /* fw_init parameter can prevent power off UniFi, for debugging */
-    priv_instance = uf_find_priv(priv);
-    if (priv_instance == -1) {
-        unifi_warning(priv,
-                "CsrWifiRouterCtrlStopReqHandler: Unknown priv instance, will power off card.\n");
-        power_off = 1;
-    } else {
-        power_off = (fw_init[priv_instance] > 0) ? 0 : 1;
-    }
-
-    /* Production test mode requires power to the chip, too */
-    if (priv->ptest_mode) {
-        power_off = 0;
-    }
-
-    /* Stop the bh_thread */
-    uf_stop_thread(priv, &priv->bh_thread);
-
-    /* Read the f/w panic codes, if any. Protect against second wifi_off() call,
-     * which may happen if SME requests a wifi_off and closes the char device */
-    if (priv->init_progress != UNIFI_INIT_NONE) {
-        CsrSdioClaim(priv->sdio);
-        unifi_capture_panic(priv->card);
-        CsrSdioRelease(priv->sdio);
-    }
-
-    /* Unregister the interrupt handler */
-    if (csr_sdio_linux_remove_irq(priv->sdio)) {
-        unifi_notice(priv,
-                "csr_sdio_linux_remove_irq failed to talk to card.\n");
-    }
-
-    if (power_off) {
-        unifi_trace(priv, UDBG2,
-                    "Force low power and try to power off\n");
-        /* Put UniFi to deep sleep, in case we can not power it off */
-        CsrSdioClaim(priv->sdio);
-        csrResult = unifi_force_low_power_mode(priv->card);
-        CsrSdioRelease(priv->sdio);
-
-        CsrSdioPowerOff(priv->sdio);
-    }
-
-    /* Consider UniFi to be uninitialised */
-    priv->init_progress = UNIFI_INIT_NONE;
-    priv->wifi_on_state = wifi_on_unspecified;
-
-
-} /* wifi_off() */
-
-
-void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg;
-    int i = 0;
-
-    if (priv == NULL) {
-        return;
-    }
-
-    unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOffReqHandler(0x%.4X)\n", msg->source);
-
-    /* Stop the network traffic on all interfaces before freeing the core. */
-    for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
-        netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
-        if (interfacePriv->netdev_registered == 1) {
-            netif_carrier_off(priv->netdev[i]);
-            netif_tx_stop_all_queues(priv->netdev[i]);
-            interfacePriv->connected = UnifiConnectedUnknown;
-        }
-        interfacePriv->interfaceMode = 0;
-
-        /* Enable all queues by default */
-        interfacePriv->queueEnabled[0] = 1;
-        interfacePriv->queueEnabled[1] = 1;
-        interfacePriv->queueEnabled[2] = 1;
-        interfacePriv->queueEnabled[3] = 1;
-    }
-    wifi_off(priv);
-
-    CsrWifiRouterCtrlWifiOffCfmSend(msg->source,req->clientData);
-
-    /* If this is called in response to closing the character device, the
-     * caller must use uf_sme_cancel_request() to terminate any pending SME
-     * blocking request or there will be a delay while the operation times out.
-     */
-}
-
-
-void CsrWifiRouterCtrlQosControlReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlQosControlReq* req = (CsrWifiRouterCtrlQosControlReq*)msg;
-    netInterface_priv_t *interfacePriv;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlQosControlReqHandler:scontrol = %d", req->control);
-
-    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
-        return;
-    }
-    interfacePriv = priv->interfacePriv[req->interfaceTag];
-
-    if (req->control == CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON) {
-        priv->sta_wmm_capabilities |= QOS_CAPABILITY_WMM_ENABLED;
-        unifi_trace(priv, UDBG1, "WMM enabled\n");
-
-        unifi_trace(priv, UDBG1, "Queue Config %x\n", req->queueConfig);
-
-        interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BK] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE)?1:0;
-        interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BE] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE)?1:0;
-        interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VI] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE)?1:0;
-        interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VO] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE)?1:0;
-
-    } else {
-        priv->sta_wmm_capabilities = 0;
-        unifi_trace(priv, UDBG1, "WMM disabled\n");
-    }
-}
-
-
-void CsrWifiRouterCtrlTclasAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlTclasAddReq* req = (CsrWifiRouterCtrlTclasAddReq*)msg;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlTclasAddReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    CsrWifiRouterCtrlTclasAddCfmSend(msg->source, req->clientData, req->interfaceTag , CSR_RESULT_SUCCESS);
-}
-
-void CsrWifiRouterCtrlTclasDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlTclasDelReq* req = (CsrWifiRouterCtrlTclasDelReq*)msg;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlTclasDelReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    CsrWifiRouterCtrlTclasDelCfmSend(msg->source, req->clientData, req->interfaceTag, CSR_RESULT_SUCCESS);
-}
-
-
-void CsrWifiRouterCtrlConfigurePowerModeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlConfigurePowerModeReq* req = (CsrWifiRouterCtrlConfigurePowerModeReq*)msg;
-    enum unifi_low_power_mode pm;
-    CsrResult csrResult;
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlConfigurePowerModeReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    if (req->mode == CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED) {
-        pm = UNIFI_LOW_POWER_DISABLED;
-    } else {
-        pm = UNIFI_LOW_POWER_ENABLED;
-    }
-
-    unifi_trace(priv, UDBG2,
-                "CsrWifiRouterCtrlConfigurePowerModeReqHandler (mode=%d, wake=%d)\n",
-                req->mode, req->wakeHost);
-    csrResult = unifi_configure_low_power_mode(priv->card, pm,
-                                               (req->wakeHost ? UNIFI_PERIODIC_WAKE_HOST_ENABLED : UNIFI_PERIODIC_WAKE_HOST_DISABLED));
-}
-
-
-void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlWifiOnRes* res = (CsrWifiRouterCtrlWifiOnRes*)msg;
-
-    if (priv == NULL) {
-        unifi_error(NULL, "CsrWifiRouterCtrlWifiOnResHandler: Invalid ospriv.\n");
-        return;
-    }
-
-    unifi_trace(priv, UDBG1,
-                "CsrWifiRouterCtrlWifiOnResHandler: status %d (patch %u)\n", res->status, res->smeVersions.firmwarePatch);
-
-    if (res->smeVersions.firmwarePatch != 0) {
-        unifi_info(priv, "Firmware patch %d\n", res->smeVersions.firmwarePatch);
-    }
-
-    if (res->numInterfaceAddress > CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "WifiOnResHandler bad numInterfaceAddress %d\n", res->numInterfaceAddress);
-        return;
-    }
-
-    /* UniFi is now initialised, complete the init. */
-    if (res->status == CSR_RESULT_SUCCESS)
-    {
-        int i; /* used as a loop counter */
-        u32 intmode = CSR_WIFI_INTMODE_DEFAULT;
-#ifdef CSR_WIFI_SPLIT_PATCH
-        u8 switching_ap_fw = FALSE;
-#endif
-        /* Register the UniFi device with the OS network manager */
-        unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n");
-
-        /* Store the MAC address in the netdev */
-        for(i=0;i<res->numInterfaceAddress;i++)
-        {
-            memcpy(priv->netdev[i]->dev_addr, res->stationMacAddress[i].a, ETH_ALEN);
-        }
-
-        /* Copy version structure into the private versions field */
-        priv->sme_versions = res->smeVersions;
-
-        unifi_trace(priv, UDBG2, "network interfaces count = %d\n",
-                    res->numInterfaceAddress);
-
-        /* Register the netdevs for each interface. */
-        for(i=0;i<res->numInterfaceAddress;i++)
-        {
-            netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
-            if(!interfacePriv->netdev_registered)
-            {
-                int r;
-                unifi_trace(priv, UDBG3, "registering net device %d\n", i);
-                r = uf_register_netdev(priv, i);
-                if (r)
-                {
-                    /* unregister the net_device that are registered in the previous iterations */
-                    uf_unregister_netdev(priv);
-                    unifi_error(priv, "Failed to register the network device.\n");
-                    CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
-                    return;
-                }
-            }
-#ifdef CSR_WIFI_SPLIT_PATCH
-            else
-            {
-                /* If a netdev is already registered, we have received this WifiOnRes
-                 * in response to switching AP/STA firmware in a ModeSetReq.
-                 * Rememeber this in order to send a ModeSetCfm once
-                 */
-                switching_ap_fw = TRUE;
-            }
-#endif
-        }
-        priv->totalInterfaceCount = res->numInterfaceAddress;
-
-        /* If the MIB has selected f/w scheduled interrupt mode, apply it now
-         * but let module param override.
-         */
-        if (run_bh_once != -1) {
-            intmode = (u32)run_bh_once;
-        } else if (res->scheduledInterrupt) {
-            intmode = CSR_WIFI_INTMODE_RUN_BH_ONCE;
-        }
-        unifi_set_interrupt_mode(priv->card, intmode);
-
-        priv->init_progress = UNIFI_INIT_COMPLETED;
-
-        /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
-        CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS);
-
-#ifdef CSR_WIFI_SPLIT_PATCH
-        if (switching_ap_fw && (priv->pending_mode_set.common.destination != 0xaaaa)) {
-            unifi_info(priv, "Completed firmware reload with %s patch\n",
-                CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode) ? "AP" : "STA");
-
-            /* Confirm the ModeSetReq that requested the AP/STA patch switch */
-            CsrWifiRouterCtrlModeSetCfmSend(priv->pending_mode_set.common.source,
-                                            priv->pending_mode_set.clientData,
-                                            priv->pending_mode_set.interfaceTag,
-                                            priv->pending_mode_set.mode,
-                                            CSR_RESULT_SUCCESS);
-            priv->pending_mode_set.common.destination = 0xaaaa;
-        }
-#endif
-        unifi_info(priv, "UniFi ready\n");
-
-#ifdef ANDROID_BUILD
-        /* Release the wakelock */
-        unifi_trace(priv, UDBG1, "ready: release wake lock\n");
-        wake_unlock(&unifi_sdio_wake_lock);
-#endif
-        /* Firmware initialisation is complete, so let the SDIO bus
-         * clock be raised when convienent to the core.
-         */
-        unifi_request_max_sdio_clock(priv->card);
-
-#ifdef CSR_SUPPORT_WEXT
-        /* Notify the Android wpa_supplicant that we are ready */
-        wext_send_started_event(priv);
-
-        queue_work(priv->unifi_workqueue, &priv->sme_config_task);
-#endif
-
-    } else {
-        /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
-        CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
-    }
-}
-
-
-void CsrWifiRouterCtrlWifiOffResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-
-void CsrWifiRouterCtrlMulticastAddressResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-
-void CsrWifiRouterMaPacketSubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterMaPacketSubscribeReq* req = (CsrWifiRouterMaPacketSubscribeReq*)msg;
-    u8 i;
-    CsrResult result;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterMaPacketSubscribeReqHandler: invalid priv\n");
-        return;
-    }
-
-    /* Look for an unused filter */
-
-    result = CSR_WIFI_RESULT_NO_ROOM;
-    for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
-
-        if (!priv->sme_unidata_ind_filters[i].in_use) {
-
-            priv->sme_unidata_ind_filters[i].in_use = 1;
-            priv->sme_unidata_ind_filters[i].appHandle = msg->source;
-            priv->sme_unidata_ind_filters[i].encapsulation = req->encapsulation;
-            priv->sme_unidata_ind_filters[i].protocol = req->protocol;
-
-            priv->sme_unidata_ind_filters[i].oui[2] = (u8)  (req->oui        & 0xFF);
-            priv->sme_unidata_ind_filters[i].oui[1] = (u8) ((req->oui >>  8) & 0xFF);
-            priv->sme_unidata_ind_filters[i].oui[0] = (u8) ((req->oui >> 16) & 0xFF);
-
-            result = CSR_RESULT_SUCCESS;
-            break;
-        }
-    }
-
-    unifi_trace(priv, UDBG1,
-                "subscribe_req: encap=%d, handle=%d, result=%d\n",
-                req->encapsulation, i, result);
-    CsrWifiRouterMaPacketSubscribeCfmSend(msg->source,req->interfaceTag, i, result, 0);
-}
-
-
-void CsrWifiRouterMaPacketUnsubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterMaPacketUnsubscribeReq* req = (CsrWifiRouterMaPacketUnsubscribeReq*)msg;
-    CsrResult result;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterMaPacketUnsubscribeReqHandler: invalid priv\n");
-        return;
-    }
-
-    result = CSR_WIFI_RESULT_NOT_FOUND;
-
-    if (req->subscriptionHandle < MAX_MA_UNIDATA_IND_FILTERS) {
-        if (priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use) {
-            priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use = 0;
-            result = CSR_RESULT_SUCCESS;
-        } else {
-            result = CSR_WIFI_RESULT_NOT_FOUND;
-        }
-    }
-
-    unifi_trace(priv, UDBG1,
-                "unsubscribe_req: handle=%d, result=%d\n",
-                req->subscriptionHandle, result);
-    CsrWifiRouterMaPacketUnsubscribeCfmSend(msg->source,req->interfaceTag, result);
-}
-
-
-void CsrWifiRouterCtrlCapabilitiesReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlCapabilitiesReq* req = (CsrWifiRouterCtrlCapabilitiesReq*)msg;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlCapabilitiesReqHandler: invalid priv\n");
-        return;
-    }
-
-    CsrWifiRouterCtrlCapabilitiesCfmSend(msg->source,req->clientData,
-            UNIFI_SOFT_COMMAND_Q_LENGTH - 1,
-            UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1);
-}
-
-
-void CsrWifiRouterCtrlSuspendResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlSuspendRes* res = (CsrWifiRouterCtrlSuspendRes*)msg;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlSuspendResHandler: invalid priv\n");
-        return;
-    }
-
-    sme_complete_request(priv, res->status);
-}
-
-
-void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlResumeRes* res = (CsrWifiRouterCtrlResumeRes*)msg;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlResumeResHandler: invalid priv\n");
-        return;
-    }
-
-    sme_complete_request(priv, res->status);
-}
-
-
-void CsrWifiRouterCtrlTrafficConfigReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlTrafficConfigReq* req = (CsrWifiRouterCtrlTrafficConfigReq*)msg;
-    CsrResult csrResult;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlTrafficConfigReqHandler: invalid smepriv\n");
-        return;
-    }
-    if (req->trafficConfigType == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER)
-    {
-        req->config.packetFilter |= CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM;
-    }
-    csrResult = unifi_ta_configure(priv->card, req->trafficConfigType, (const CsrWifiRouterCtrlTrafficConfig *)&req->config);
-}
-
-void CsrWifiRouterCtrlTrafficClassificationReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlTrafficClassificationReq* req = (CsrWifiRouterCtrlTrafficClassificationReq*)msg;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlTrafficClassificationReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    unifi_ta_classification(priv->card, req->trafficType, req->period);
-}
-
-static int
-_sys_packet_req(unifi_priv_t *priv, const CSR_SIGNAL *signal,
-        u8 subscriptionHandle,
-        u16 frameLength, u8 *frame,
-        int proto)
-{
-    int r;
-    const sme_ma_unidata_ind_filter_t *subs;
-    bulk_data_param_t bulkdata;
-    CSR_MA_PACKET_REQUEST req = signal->u.MaPacketRequest;
-    struct sk_buff *skb, *newSkb = NULL;
-    CsrWifiMacAddress peerMacAddress;
-    CsrResult csrResult;
-    u16 interfaceTag = req.VirtualInterfaceIdentifier & 0xff;
-    u8 eapolStore = FALSE;
-    s8 protection = 0;
-    netInterface_priv_t *interfacePriv;
-    unsigned long flags;
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "_sys_packet_req: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
-        return -EINVAL;
-    }
-    interfacePriv = priv->interfacePriv[interfaceTag];
-    if (!priv->sme_unidata_ind_filters[subscriptionHandle].in_use) {
-        unifi_error(priv, "_sys_packet_req: unknown subscription.\n");
-        return -EINVAL;
-    }
-
-    subs = &priv->sme_unidata_ind_filters[subscriptionHandle];
-    unifi_trace(priv, UDBG1,
-                "_sys_packet_req: handle=%d, subs=%p, encap=%d\n",
-                subscriptionHandle, subs, subs->encapsulation);
-
-    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], frameLength);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "_sys_packet_req: failed to allocate bulkdata.\n");
-        return (int)CsrHipResultToStatus(csrResult);
-    }
-
-    /* get the peer Mac address */
-    memcpy(&peerMacAddress, frame, ETH_ALEN);
-
-    /* Determine if we need to add encapsulation header */
-    if (subs->encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) {
-        memcpy((void*)bulkdata.d[0].os_data_ptr, frame, frameLength);
-
-        /* The translation is performed on the skb */
-        skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;
-
-        unifi_trace(priv, UDBG1,
-                    "_sys_packet_req: skb_add_llc_snap -->\n");
-        r = skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto);
-        unifi_trace(priv, UDBG1,
-                    "_sys_packet_req: skb_add_llc_snap <--\n");
-        if (r) {
-            unifi_error(priv,
-                        "_sys_packet_req: failed to translate eth frame.\n");
-            unifi_net_data_free(priv,&bulkdata.d[0]);
-            return r;
-        }
-
-        bulkdata.d[0].data_length = skb->len;
-    } else {
-        /* Crop the MAC addresses from the packet */
-        memcpy((void*)bulkdata.d[0].os_data_ptr, frame + 2*ETH_ALEN, frameLength - 2*ETH_ALEN);
-        bulkdata.d[0].data_length = frameLength - 2*ETH_ALEN;
-        skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;
-        skb->len = bulkdata.d[0].data_length;
-
-    }
-
-    bulkdata.d[1].os_data_ptr = NULL;
-    bulkdata.d[1].os_net_buf_ptr = NULL;
-    bulkdata.d[1].data_length = 0;
-
-    /* check for m4 detection */
-    if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) {
-        eapolStore = TRUE;
-    }
-
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-    if (proto == ETH_P_WAI)
-     {
-        protection = 0; /*WAI packets always sent unencrypted*/
-     }
-   else
-     {
-#endif
-
-#ifdef CSR_SUPPORT_SME
-    if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, peerMacAddress.a)) < 0) {
-        unifi_error(priv, "unicast address, but destination not in station record database\n");
-        unifi_net_data_free(priv,&bulkdata.d[0]);
-        return -1;
-    }
-#else
-    protection = 0;
-#endif
-
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-    }
-#endif
-
-    /* add Mac header */
-    if (prepare_and_add_macheader(priv, skb, newSkb, req.Priority, &bulkdata, interfaceTag, frame, frame + ETH_ALEN, protection)) {
-        unifi_error(priv, "failed to create MAC header\n");
-        unifi_net_data_free(priv,&bulkdata.d[0]);
-        return -1;
-    }
-
-    if (eapolStore) {
-        spin_lock_irqsave(&priv->m4_lock, flags);
-        /* Store the EAPOL M4 packet for later */
-        interfacePriv->m4_signal = *signal;
-        interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
-        interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length;
-        interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
-        interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
-        spin_unlock_irqrestore(&priv->m4_lock, flags);
-        /* Send a signal to SME */
-        unifi_trace(priv, UDBG1, "_sys_packet_req: Sending CsrWifiRouterCtrlM4ReadyToSendInd\n");
-        CsrWifiRouterCtrlM4ReadyToSendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress);
-        return 0;
-    }
-
-    /* Send the signal to UniFi */
-      /* Set the B31 to 1 for local routing*/
-    r= uf_process_ma_packet_req(priv,  peerMacAddress.a, (req.HostTag | 0x80000000), interfaceTag, 0,
-                                (CSR_RATE)0, req.Priority, signal->SignalPrimitiveHeader.SenderProcessId, &bulkdata);
-    if (r) {
-        unifi_error(priv,
-                    "_sys_packet_req: failed to send signal.\n");
-        unifi_net_data_free(priv,&bulkdata.d[0]);
-        return r;
-    }
-    /* The final CsrWifiRouterMaPacketCfmSend() will called when the actual MA-PACKET.cfm is received from the chip */
-
-    return 0;
-}
-
-void CsrWifiRouterMaPacketReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    int r;
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterMaPacketReq* mareq = (CsrWifiRouterMaPacketReq*)msg;
-    llc_snap_hdr_t *snap;
-    u16 snap_protocol;
-    CSR_SIGNAL signal;
-    CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
-    CsrWifiRouterCtrlPortAction controlPortaction;
-    u8 *daddr, *saddr;
-    u16 interfaceTag = mareq->interfaceTag & 0x00ff;
-    int queue;
-    netInterface_priv_t *interfacePriv;
-
-    if (!mareq->frame || !priv || !priv->smepriv)
-    {
-        unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: invalid frame/priv/priv->smepriv\n");
-        return;
-    }
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
-        return;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-    /* get a pointer to dest & source Mac address */
-    daddr = mareq->frame;
-    saddr = (mareq->frame + ETH_ALEN);
-    /* point to the proper position of frame, since frame has MAC header */
-    snap = (llc_snap_hdr_t *) (mareq->frame + 2 * ETH_ALEN);
-    snap_protocol = ntohs(snap->protocol);
-    if((snap_protocol == ETH_P_PAE)
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-       || (snap_protocol == ETH_P_WAI)
-#endif
-    )
-    {
-        queue = UF_UNCONTROLLED_PORT_Q;
-    }
-    else
-    {
-        queue = UF_CONTROLLED_PORT_Q;
-    }
-
-    /* Controlled port restrictions apply to the packets */
-    controlPortaction = uf_sme_port_state(priv, daddr, queue, interfaceTag);
-    if (controlPortaction != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)
-    {
-        unifi_warning(priv, "CsrWifiRouterMaPacketReqHandler: (%s)controlled port is closed.\n", (queue == UF_CONTROLLED_PORT_Q)?"":"un");
-        if(mareq->cfmRequested)
-        {
-            CsrWifiRouterMaPacketCfmSend(msg->source,
-                                     interfaceTag,
-                                     CSR_RESULT_FAILURE,
-                                     mareq->hostTag, 0);
-        }
-        return;
-    }
-
-    signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
-    /* Store the appHandle in the LSB of the SenderId. */
-    CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->sme_cli->sender_id & 0xff00) | (unsigned int)msg->source),
-                                     (u8*)&signal.SignalPrimitiveHeader.SenderProcessId);
-    signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
-
-    /* Fill in the MA-PACKET.req signal */
-    memcpy(req->Ra.x, daddr, ETH_ALEN);
-    req->Priority = mareq->priority;
-    req->TransmitRate = 0; /* Let firmware select the rate*/
-    req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag);
-    req->HostTag = mareq->hostTag;
-
-    if(mareq->cfmRequested)
-        req->TransmissionControl = 0;
-    else
-        req->TransmissionControl = CSR_NO_CONFIRM_REQUIRED;
-
-    r = _sys_packet_req(priv, &signal, mareq->subscriptionHandle,
-            mareq->frameLength, mareq->frame, snap_protocol);
-
-    if (r && mareq->cfmRequested)
-    {
-        CsrWifiRouterMaPacketCfmSend(msg->source,interfaceTag,
-                                     CSR_RESULT_FAILURE,
-                                     mareq->hostTag, 0);
-    }
-    return;
-}
-
-void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-void CsrWifiRouterCtrlM4TransmitReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlM4TransmitReq* req = (CsrWifiRouterCtrlM4TransmitReq*)msg;
-    int r;
-    bulk_data_param_t bulkdata;
-    netInterface_priv_t *interfacePriv;
-    CSR_SIGNAL m4_signal;
-    unsigned long flags;
-
-    if (priv == NULL) {
-        unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid smepriv\n");
-        return;
-    }
-    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "M4TransmitReqHandler: interfaceTag >= CSR_WIFI_NUM_INTERFACES\n");
-        return;
-    }
-
-    interfacePriv = priv->interfacePriv[req->interfaceTag];
-    spin_lock_irqsave(&priv->m4_lock, flags);
-    if (interfacePriv->m4_bulk_data.data_length == 0) {
-        spin_unlock_irqrestore(&priv->m4_lock, flags);
-        unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid buffer\n");
-        return;
-    }
-
-    memcpy(&bulkdata.d[0], &interfacePriv->m4_bulk_data, sizeof(bulk_data_desc_t));
-
-    interfacePriv->m4_bulk_data.net_buf_length = 0;
-    interfacePriv->m4_bulk_data.data_length = 0;
-    interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
-    m4_signal = interfacePriv->m4_signal;
-    spin_unlock_irqrestore(&priv->m4_lock, flags);
-
-    bulkdata.d[1].os_data_ptr = NULL;
-    bulkdata.d[1].data_length = 0;
-
-    interfacePriv->m4_sent = TRUE;
-    m4_signal.u.MaPacketRequest.HostTag |= 0x80000000;
-    /* Store the hostTag for later varification */
-    interfacePriv->m4_hostTag = m4_signal.u.MaPacketRequest.HostTag;
-    r = ul_send_signal_unpacked(priv, &m4_signal, &bulkdata);
-    unifi_trace(priv, UDBG1,
-                "CsrWifiRouterCtrlM4TransmitReqHandler: sent\n");
-    if (r) {
-        unifi_error(priv,
-                    "CsrWifiRouterCtrlM4TransmitReqHandler: failed to send signal.\n");
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-    }
-}
-
-/* reset the station records when the mode is set as CSR_WIFI_ROUTER_CTRL_MODE_NONE */
-static void CsrWifiRouterCtrlResetStationRecordList(unifi_priv_t *priv, u16 interfaceTag)
-{
-    u8 i,j;
-    CsrWifiRouterCtrlStaInfo_t *staInfo=NULL;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    unsigned long lock_flags;
-
-    /* create a list for sending confirms of un-delivered packets */
-    struct list_head send_cfm_list;
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "CsrWifiRouterCtrlResetStationRecordList: bad interfaceTag\n");
-        return;
-    }
-
-    INIT_LIST_HEAD(&send_cfm_list);
-
-    /* Reset the station record to NULL if mode is NONE */
-    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        if ((staInfo=interfacePriv->staInfo[i]) != NULL) {
-            uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                                 &send_cfm_list,
-                                                 &(staInfo->mgtFrames));
-            uf_flush_list(priv,&(staInfo->mgtFrames));
-            for(j=0;j<MAX_ACCESS_CATOGORY;j++){
-                uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                                     &send_cfm_list,
-                                                     &(staInfo->dataPdu[j]));
-                uf_flush_list(priv,&(staInfo->dataPdu[j]));
-            }
-
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            /* Removing station record information from port config array */
-            memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
-            staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-            staInfo->peerControlledPort->in_use = FALSE;
-            interfacePriv->controlled_data_port.entries_in_use--;
-
-            memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
-            staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-            staInfo->peerUnControlledPort->in_use = FALSE;
-            interfacePriv->uncontrolled_data_port.entries_in_use--;
-
-            kfree(interfacePriv->staInfo[i]);
-            interfacePriv->staInfo[i] = NULL;
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-        }
-    }
-    /* after the critical region process the list of frames that requested cfm
-     * and send cfm to requestor one by one
-     */
-    send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
-
-#ifdef CSR_SUPPORT_SME
-    /* Interface Independent, no of packet queued, incase of mode is None or AP set to 0 */
-    switch(interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-        case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
-            if (priv->noOfPktQueuedInDriver) {
-                unifi_warning(priv, "After reset the noOfPktQueuedInDriver = %x\n", priv->noOfPktQueuedInDriver);
-                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                priv->noOfPktQueuedInDriver = 0;
-                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-            }
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-            break;
-        default:
-            unifi_error(priv, "interfacemode is not correct in CsrWifiRouterCtrlResetStationRecordList: debug\n");
-    }
-#endif
-
-    if (((interfacePriv->controlled_data_port.entries_in_use != 0) || (interfacePriv->uncontrolled_data_port.entries_in_use != 0))
-            && (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE)) {
-        /* Print in case if the value of entries goes to -ve/+ve (apart from 0)
-         * we expect the entries should be zero here if mode is set as NONE
-         */
-        unifi_trace(priv, UDBG3, "In %s controlled port entries = %d, uncontrolled port entries = %d\n",
-                   __FUNCTION__, interfacePriv->controlled_data_port.entries_in_use,
-                   interfacePriv->uncontrolled_data_port.entries_in_use);
-    }
-}
-
-void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, u16 interfaceTag)
-{
-    netInterface_priv_t *interfacePriv;
-
-    /* create a list for sending confirms of un-delivered packets */
-    struct list_head send_cfm_list;
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "CsrWifiRouterCtrlInterfaceReset: bad interfaceTag\n");
-        return;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    INIT_LIST_HEAD(&send_cfm_list);
-
-    /* Enable all queues by default */
-    interfacePriv->queueEnabled[0] = 1;
-    interfacePriv->queueEnabled[1] = 1;
-    interfacePriv->queueEnabled[2] = 1;
-    interfacePriv->queueEnabled[3] = 1;
-
-    uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                             &send_cfm_list,
-                                             &(interfacePriv->genericMgtFrames));
-    uf_flush_list(priv,&(interfacePriv->genericMgtFrames));
-
-    uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                             &send_cfm_list,
-                                             &(interfacePriv->genericMulticastOrBroadCastMgtFrames));
-    uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastMgtFrames));
-
-    uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                             &send_cfm_list,
-                                             &(interfacePriv->genericMulticastOrBroadCastFrames));
-
-    uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastFrames));
-
-    /*  process the list of frames that requested cfm
-    and send cfm to requestor one by one */
-    send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
-
-    /* Reset the station record to NULL if mode is tried to set as NONE */
-    switch(interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-        case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR:
-        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
-            /* station records not available in these modes */
-            break;
-        default:
-            CsrWifiRouterCtrlResetStationRecordList(priv,interfaceTag);
-    }
-
-    interfacePriv->num_stations_joined = 0;
-    interfacePriv->sta_activity_check_enabled = FALSE;
-}
-
-
-void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlModeSetReq* req = (CsrWifiRouterCtrlModeSetReq*)msg;
-
-    if (priv == NULL)
-    {
-        unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES)
-    {
-        netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
-#ifdef CSR_WIFI_SPLIT_PATCH
-        u8 old_mode = interfacePriv->interfaceMode;
-#endif
-        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n",
-                interfacePriv->interfaceMode);
-
-        interfacePriv->interfaceMode = req->mode;
-
-#ifdef CSR_WIFI_SPLIT_PATCH
-        /* Detect a change in mode that requires a switch to/from the AP firmware patch.
-         * This should only happen when transitioning in/out of AP modes.
-         */
-        if (CSR_WIFI_HIP_IS_AP_FW(req->mode) != CSR_WIFI_HIP_IS_AP_FW(old_mode))
-        {
-            CsrWifiRouterCtrlVersions versions;
-            int r;
-
-#ifdef ANDROID_BUILD
-            /* Take the wakelock while switching patch */
-            unifi_trace(priv, UDBG1, "patch switch: take wake lock\n");
-            wake_lock(&unifi_sdio_wake_lock);
-#endif
-            unifi_info(priv, "Resetting UniFi with %s patch\n", CSR_WIFI_HIP_IS_AP_FW(req->mode) ? "AP" : "STA");
-
-            r = uf_reject_firmware_files(priv, UNIFI_FW_STA);
-            if (r) {
-                unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: Failed to get f/w\n");
-                CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
-                                                req->mode, CSR_RESULT_FAILURE);
-                return;
-            }
-
-            /* Block the I/O thread */
-            priv->bh_thread.block_thread = 1;
-
-            /* Reset and download the new patch */
-            r = uf_init_hw(priv);
-            if (r) {
-                unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
-                CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
-                                                req->mode, CSR_RESULT_FAILURE);
-                return;
-            }
-
-            /* Re-enable the I/O thread */
-            priv->bh_thread.block_thread = 0;
-
-            /* Get the version information from the core */
-            unifi_card_info(priv->card, &priv->card_info);
-
-            /* Copy to the unifiio_card_info structure. */
-            versions.chipId = priv->card_info.chip_id;
-            versions.chipVersion = priv->card_info.chip_version;
-            versions.firmwareBuild = priv->card_info.fw_build;
-            versions.firmwareHip = priv->card_info.fw_hip_version;
-            versions.routerBuild = (char*)CSR_WIFI_VERSION;
-            versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
-
-            /* Now that new firmware is running, send a WifiOnInd to the NME. This will
-             * cause it to retransfer the MIB.
-             */
-            CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);
-
-            /* Store the request so we know where to send the ModeSetCfm */
-            priv->pending_mode_set = *req;
-        }
-        else
-#endif
-        {
-            /* No patch switch, confirm straightaway */
-            CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
-                                            req->mode, CSR_RESULT_SUCCESS);
-        }
-
-        interfacePriv->bssid = req->bssid;
-        /* For modes other than AP/P2PGO, set below member FALSE */
-        interfacePriv->intraBssEnabled = FALSE;
-        /* Initialise the variable bcTimSet with a value
-         * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
-         */
-        interfacePriv->bcTimSet = 0xFF;
-        interfacePriv->bcTimSetReqPendingFlag = FALSE;
-        /* Initialise the variable bcTimSetReqQueued with a value
-         * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
-         */
-        interfacePriv->bcTimSetReqQueued =0xFF;
-        CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag);
-
-        if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-           req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-            interfacePriv->protect = req->protection;
-            interfacePriv->dtimActive=FALSE;
-            interfacePriv->multicastPduHostTag = 0xffffffff;
-            /* For AP/P2PGO mode SME sending intraBssDistEnabled
-             * i.e. for AP: intraBssDistEnabled = TRUE, for P2PGO
-             * intraBssDistEnabled = TRUE/FALSE on requirement
-             */
-            interfacePriv->intraBssEnabled = req->intraBssDistEnabled;
-            unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlModeSetReqHandler: IntraBssDisEnabled = %d\n",
-                        req->intraBssDistEnabled);
-        } else if (req->mode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) {
-              netif_carrier_off(priv->netdev[req->interfaceTag]);
-              interfacePriv->connected = UnifiConnectedUnknown;
-        }
-    }
-    else {
-        unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid interfaceTag :%d\n",req->interfaceTag);
-    }
-}
-
-void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-}
-
-/* delete the station record from the station record data base */
-static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *req)
-{
-    u8 j;
-    CsrWifiRouterCtrlStaInfo_t *staInfo = NULL;
-    unifi_port_config_t *controlledPort;
-    unifi_port_config_t *unControlledPort;
-    netInterface_priv_t *interfacePriv;
-
-    u8 ba_session_idx = 0;
-    ba_session_rx_struct *ba_session_rx = NULL;
-    ba_session_tx_struct *ba_session_tx = NULL;
-
-    /* create a list for sending confirms of un-delivered packets */
-    struct list_head send_cfm_list;
-
-    unsigned long lock_flags;
-
-    if ((req->peerRecordHandle >= UNIFI_MAX_CONNECTIONS) || (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)) {
-        unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", req->peerRecordHandle, req->interfaceTag);
-        return CSR_RESULT_FAILURE;
-    }
-
-    INIT_LIST_HEAD(&send_cfm_list);
-
-    interfacePriv = priv->interfacePriv[req->interfaceTag];
-    /* remove the station record & make it NULL */
-    if ((staInfo=interfacePriv->staInfo[req->peerRecordHandle])!=NULL) {
-
-        uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                                 &send_cfm_list,
-                                                 &(staInfo->mgtFrames));
-
-        uf_flush_list(priv,&(staInfo->mgtFrames));
-        for(j=0;j<MAX_ACCESS_CATOGORY;j++){
-            uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                                     &send_cfm_list,
-                                                     &(staInfo->dataPdu[j]));
-            uf_flush_list(priv,&(staInfo->dataPdu[j]));
-        }
-
-        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-        /* clear the port configure array info, for the corresponding peer entry */
-        controlledPort = &interfacePriv->controlled_data_port;
-        unControlledPort = &interfacePriv->uncontrolled_data_port;
-
-        unifi_trace(priv, UDBG1, "peer_delete_record: Peer found handle = %d, port in use: cont(%d), unCont(%d)\n",
-                    req->peerRecordHandle, controlledPort->entries_in_use, unControlledPort->entries_in_use);
-
-        memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
-        staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-        staInfo->peerControlledPort->in_use = FALSE;
-        if (controlledPort->entries_in_use) {
-            controlledPort->entries_in_use--;
-        } else {
-            unifi_warning(priv, "number of controlled port entries is zero, trying to decrement: debug\n");
-        }
-
-        memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
-        staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-        staInfo->peerUnControlledPort->in_use = FALSE;
-        if (unControlledPort->entries_in_use) {
-            unControlledPort->entries_in_use--;
-        } else {
-            unifi_warning(priv, "number of uncontrolled port entries is zero, trying to decrement: debug\n");
-        }
-
-        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-        /* update the TIM with zero */
-        if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS &&
-                staInfo->timSet == CSR_WIFI_TIM_SET) {
-            unifi_trace(priv, UDBG3, "peer is deleted so TIM updated to 0, in firmware\n");
-            update_tim(priv,staInfo->aid,0,req->interfaceTag, req->peerRecordHandle);
-        }
-
-
-        /* Stop BA session if it is active, for this peer address all BA sessions
-        (per tID per role) are closed */
-
-        down(&priv->ba_mutex);
-        for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
-            ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx];
-            if(ba_session_rx) {
-                if(!memcmp(ba_session_rx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
-                    blockack_session_stop(priv,
-                                        req->interfaceTag,
-                                        CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT,
-                                        ba_session_rx->tID,
-                                        ba_session_rx->macAddress);
-                }
-            }
-        }
-
-        for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
-            ba_session_tx = priv->interfacePriv[req->interfaceTag]->ba_session_tx[ba_session_idx];
-            if(ba_session_tx) {
-                if(!memcmp(ba_session_tx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
-                    blockack_session_stop(priv,
-                                        req->interfaceTag,
-                                        CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR,
-                                        ba_session_tx->tID,
-                                        ba_session_tx->macAddress);
-                }
-            }
-        }
-
-        up(&priv->ba_mutex);
-
-#ifdef CSR_SUPPORT_SME
-        unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid);
-        cancel_work_sync(&staInfo->send_disconnected_ind_task);
-#endif
-
-        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-#ifdef CSR_SUPPORT_SME
-        interfacePriv->num_stations_joined--;
-
-        staInfo->nullDataHostTag = INVALID_HOST_TAG;
-
-        if ((interfacePriv->sta_activity_check_enabled) &&
-            (interfacePriv->num_stations_joined < STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD))
-        {
-            unifi_trace(priv, UDBG1, "STOPPING the Inactivity Timer (num of stations = %d)\n", interfacePriv->num_stations_joined);
-            interfacePriv->sta_activity_check_enabled = FALSE;
-            del_timer_sync(&interfacePriv->sta_activity_check_timer);
-        }
-#endif
-
-        /* Free the station record for corresponding peer */
-        kfree(interfacePriv->staInfo[req->peerRecordHandle]);
-        interfacePriv->staInfo[req->peerRecordHandle] = NULL;
-        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-
-        /* after the critical region process the list of frames that requested cfm
-        and send cfm to requestor one by one */
-        send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);
-
-
-    }
-    else
-    {
-        unifi_trace(priv, UDBG3, " peer not found: Delete request Peer handle[%d]\n", req->peerRecordHandle);
-    }
-
-    return CSR_RESULT_SUCCESS;
-}
-
-void CsrWifiRouterCtrlPeerDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    CsrWifiRouterCtrlPeerDelReq* req = (CsrWifiRouterCtrlPeerDelReq*)msg;
-    CsrResult status = CSR_RESULT_SUCCESS;
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    netInterface_priv_t *interfacePriv;
-
-    unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerDelReqHandler\n");
-    if (priv == NULL)
-    {
-        unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
-    {
-        unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: bad interfaceTag\n");
-        return;
-    }
-
-    interfacePriv = priv->interfacePriv[req->interfaceTag];
-
-    switch(interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            /* remove the station from station record data base */
-            status = peer_delete_record(priv, req);
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-        default:
-            /* No station record to maintain in these modes */
-            break;
-    }
-
-    CsrWifiRouterCtrlPeerDelCfmSend(msg->source,req->clientData,req->interfaceTag,status);
-    unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerDelReqHandler \n");
-}
-
-/* Add the new station to the station record data base */
-static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *req,u32 *handle)
-{
-    u8 i, powerModeTemp = 0;
-    u8 freeSlotFound = FALSE;
-    CsrWifiRouterCtrlStaInfo_t *newRecord = NULL;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
-    u32 currentTime, currentTimeHi;
-    unsigned long lock_flags;
-
-    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "peer_add_new_record: bad interfaceTag\n");
-        return CSR_RESULT_FAILURE;
-    }
-
-    currentTime = CsrTimeGet(&currentTimeHi);
-
-    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        if(interfacePriv->staInfo[i] == NULL) {
-            /* Slot is empty, so can be used for station record */
-            freeSlotFound = TRUE;
-            *handle = i;
-
-            /* Allocate for the new station record , to avoid race condition would happen between ADD_PEER &
-             * DEL_PEER the allocation made atomic memory rather than kernel memory
-             */
-            newRecord = kmalloc(sizeof(CsrWifiRouterCtrlStaInfo_t), GFP_ATOMIC);
-            if (!newRecord) {
-                unifi_error(priv, "failed to allocate the %d bytes of mem for station record\n",
-                            sizeof(CsrWifiRouterCtrlStaInfo_t));
-                return CSR_RESULT_FAILURE;
-            }
-
-            unifi_trace(priv, UDBG1, "peer_add_new_record: handle = %d AID = %d addr = %x:%x:%x:%x:%x:%x LI=%u\n",
-                        *handle, req->associationId, req->peerMacAddress.a[0], req->peerMacAddress.a[1], req->peerMacAddress.a[2],
-                        req->peerMacAddress.a[3], req->peerMacAddress.a[4], req->peerMacAddress.a[5],
-                        req->staInfo.listenIntervalInTus);
-
-            /* disable the preemption until station record updated */
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-
-            interfacePriv->staInfo[i] = newRecord;
-            /* Initialize the record*/
-            memset(newRecord,0,sizeof(CsrWifiRouterCtrlStaInfo_t));
-            /* update the station record */
-            memcpy(newRecord->peerMacAddress.a, req->peerMacAddress.a, ETH_ALEN);
-            newRecord->wmmOrQosEnabled = req->staInfo.wmmOrQosEnabled;
-
-            /* maxSpLength is bit map in qosInfo field, so converting accordingly */
-            newRecord->maxSpLength = req->staInfo.maxSpLength * 2;
-
-            /*Max SP 0 mean any number of packets. since we buffer only 512
-            packets we are hard coding this to zero for the moment */
-
-            if(newRecord->maxSpLength == 0)
-                newRecord->maxSpLength=512;
-
-            newRecord->assignedHandle = i;
-
-             /* copy power save mode of all access catagory (Trigger/Delivery/both enabled/disabled) */
-            powerModeTemp = (u8) ((req->staInfo.powersaveMode >> 4) & 0xff);
-
-            if(!(req->staInfo.powersaveMode & 0x0001))
-                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
-            else
-               newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= powerModeTemp & 0x03;
-
-            if(!(req->staInfo.powersaveMode & 0x0002))
-                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
-            else
-               newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= ((powerModeTemp & 0x0C)>> 2);
-
-            if(!(req->staInfo.powersaveMode & 0x0004))
-                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
-            else
-               newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= ((powerModeTemp & 0x30)>> 4);
-
-            if(!(req->staInfo.powersaveMode & 0x0008))
-                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
-            else
-               newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= ((powerModeTemp & 0xC0)>> 6);
-
-            {
-                u8 k;
-                for(k=0; k< MAX_ACCESS_CATOGORY ;k++)
-                    unifi_trace(priv, UDBG2, "peer_add_new_record: WMM : %d ,AC %d, powersaveMode %x \n",
-                            req->staInfo.wmmOrQosEnabled,k,newRecord->powersaveMode[k]);
-            }
-
-            unifi_trace(priv, UDBG3, "newRecord->wmmOrQosEnabled : %d , MAX SP : %d\n",
-                    newRecord->wmmOrQosEnabled,newRecord->maxSpLength);
-
-            /* Initialize the mgtFrames & data Pdu list */
-            {
-                u8 j;
-                INIT_LIST_HEAD(&newRecord->mgtFrames);
-                for(j = 0; j < MAX_ACCESS_CATOGORY; j++) {
-                    INIT_LIST_HEAD(&newRecord->dataPdu[j]);
-                }
-            }
-
-            newRecord->lastActivity = currentTime;
-            newRecord->activity_flag = TRUE;
-
-            /* enable the preemption as station record updated */
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-
-            /* First time port actions are set for the peer with below information */
-            configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
-                                UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
-
-            if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) {
-                configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
-                                    UF_CONTROLLED_PORT_Q, req->interfaceTag);
-            } else {
-                configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD, &newRecord->peerMacAddress,
-                                    UF_CONTROLLED_PORT_Q, req->interfaceTag);
-            }
-
-
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            /* Port status must be already set before calling the Add Peer request */
-            newRecord->peerControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
-                                                                      UF_CONTROLLED_PORT_Q, req->interfaceTag);
-            newRecord->peerUnControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
-                                                                        UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
-
-            if (!newRecord->peerControlledPort || !newRecord->peerUnControlledPort) {
-                /* enable the preemption as station record failed to update */
-                unifi_warning(priv, "Un/ControlledPort record not found in port configuration array index = %d\n", i);
-                kfree(interfacePriv->staInfo[i]);
-                interfacePriv->staInfo[i] = NULL;
-                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-                return CSR_RESULT_FAILURE;
-            }
-
-            newRecord->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE;
-
-            /* changes done during block ack handling */
-            newRecord->txSuspend = FALSE;
-
-            /*U-APSD related data structure*/
-            newRecord->timRequestPendingFlag = FALSE;
-
-            /* Initialise the variable updateTimReqQueued with a value
-             * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
-             */
-            newRecord->updateTimReqQueued = 0xFF;
-            newRecord->timSet = CSR_WIFI_TIM_RESET;
-            newRecord->uapsdActive = FALSE;
-            newRecord->noOfSpFramesSent =0;
-            newRecord->triggerFramePriority = CSR_QOS_UP0;
-
-            /* The protection bit is updated once the port opens for corresponding peer in
-             * routerPortConfigure request */
-
-            /* update the association ID */
-            newRecord->aid = req->associationId;
-
-#ifdef CSR_SUPPORT_SME
-            interfacePriv->num_stations_joined++;
-            newRecord->interfacePriv = interfacePriv;
-            newRecord->listenIntervalInTus = req->staInfo.listenIntervalInTus;
-            newRecord->nullDataHostTag = INVALID_HOST_TAG;
-
-            INIT_WORK(&newRecord->send_disconnected_ind_task, uf_send_disconnected_ind_wq);
-
-            if(!(interfacePriv->sta_activity_check_enabled) &&
-               (interfacePriv->num_stations_joined >= STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD)){
-                unifi_trace(priv, UDBG1,
-                            "peer_add_new_record: STARTING the Inactivity Timer (num of stations = %d)",
-                            interfacePriv->num_stations_joined);
-
-                interfacePriv->sta_activity_check_enabled = TRUE;
-                interfacePriv->sta_activity_check_timer.function = check_inactivity_timer_expire_func;
-                interfacePriv->sta_activity_check_timer.data = (unsigned long)interfacePriv;
-
-                init_timer(&interfacePriv->sta_activity_check_timer);
-                mod_timer(&interfacePriv->sta_activity_check_timer,
-                          (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));
-
-            }
-#endif
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-            break;
-        }
-    }
-
-    if(!freeSlotFound) {
-        unifi_error(priv, "Limited connectivity, Free slot not found for station record addition\n");
-        return CSR_RESULT_FAILURE;
-    }
-    return CSR_RESULT_SUCCESS;
-}
-
-#ifdef CSR_SUPPORT_SME
-static void check_inactivity_timer_expire_func(unsigned long data)
-{
-    struct unifi_priv *priv;
-    CsrWifiRouterCtrlStaInfo_t *sta_record = NULL;
-    u8 i = 0;
-    u32 now;
-    u32 inactive_time;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *) data;
-
-    if (!interfacePriv)
-    {
-        return;
-    }
-
-    priv = interfacePriv->privPtr;
-
-    if (interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES)
-    {
-        unifi_error(priv, "check_inactivity_timer_expire_func: Invalid interfaceTag\n");
-        return;
-    }
-
-    /* RUN Algorithm to check inactivity for each connected station */
-    now = CsrTimeGet(NULL);
-
-    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        if(interfacePriv->staInfo[i] != NULL) {
-            sta_record = interfacePriv->staInfo[i];
-
-            if (sta_record->activity_flag == TRUE){
-                sta_record->activity_flag = FALSE;
-                sta_record->lastActivity = now;
-                continue;
-            }
-
-            if (sta_record->lastActivity > now)
-            {
-                /* simple timer wrap (for 1 wrap) */
-                inactive_time = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, sta_record->lastActivity), now);
-            }
-            else
-            {
-                inactive_time = (u32)CsrTimeSub(now, sta_record->lastActivity);
-            }
-
-            if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
-            {
-                unifi_trace(priv, UDBG1, "STA is Inactive - AID = %d inactive_time = %d\n",
-                                        sta_record->aid,
-                                        inactive_time);
-
-                /* station is in-active, if it is in active mode send a null frame
-                 * and the station should acknowledge the null frame, if acknowledgement
-                 * is not received throw out the station.
-                 * If the station is in Power Save, update TIM for the station so
-                 * that it wakes up and register some activity through PS-Poll or
-                 * trigger frame.
-                 */
-                 if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
-                 {
-                    unifi_trace(priv, UDBG1, "STA power save state - Active, send a NULL frame to check if it is ALIVE\n");
-                    uf_send_nulldata ( priv,
-                                       sta_record->interfacePriv->InterfaceTag,
-                                       sta_record->peerMacAddress.a,
-                                       CSR_CONTENTION,
-                                       sta_record);
-                 }
-                 else if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
-                 {
-                    if((sta_record->timSet == CSR_WIFI_TIM_SET) ||
-                       (sta_record->timSet == CSR_WIFI_TIM_SETTING))
-                    {
-                        unifi_trace(priv, UDBG1, "STA power save state - PS, TIM is already SET\n");
-
-                        /* If TIM is set and we do not have any activity for
-                         * more than 3 listen intervals then send a disconnected
-                         * indication to SME, to delete the station from station
-                         * record list.
-                         * The inactivity is already more than STA_INACTIVE_TIMEOUT_VAL
-                         * and this check ensures if the listen interval is a larger
-                         * value than STA_INACTIVE_TIMEOUT_VAL.
-                         */
-                         if (inactive_time > (3 * (sta_record->listenIntervalInTus * 1024)))
-                         {
-                            unifi_trace(priv, UDBG1, "STA is inactive for more than 3 listen intervals\n");
-                            queue_work( priv->unifi_workqueue,
-                                        &sta_record->send_disconnected_ind_task);
-                         }
-
-                    }
-                    else
-                    {
-                        unifi_trace(priv, UDBG1, "STA power save state - PS, update TIM to see if it is ALIVE\n");
-                        update_tim(priv,
-                                   sta_record->aid,
-                                   CSR_WIFI_TIM_SET,
-                                   interfacePriv->InterfaceTag,
-                                   sta_record->assignedHandle);
-                    }
-                 }
-            }
-        }
-    }
-
-    /* re-run the timer interrupt */
-    mod_timer(&interfacePriv->sta_activity_check_timer,
-              (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));
-
-}
-
-
-void uf_send_disconnected_ind_wq(struct work_struct *work)
-{
-
-    CsrWifiRouterCtrlStaInfo_t *staInfo = container_of(work, CsrWifiRouterCtrlStaInfo_t, send_disconnected_ind_task);
-    unifi_priv_t *priv;
-    u16 interfaceTag;
-    struct list_head send_cfm_list;
-    u8 j;
-
-    if(!staInfo) {
-        return;
-    }
-
-    if(!staInfo->interfacePriv) {
-        return;
-    }
-
-    priv = staInfo->interfacePriv->privPtr;
-    interfaceTag =  staInfo->interfacePriv->InterfaceTag;
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "uf_send_disconnected_ind_wq: invalid interfaceTag\n");
-        return;
-    }
-
-    /* The SME/NME may be waiting for confirmation for requested frames to this station.
-     * So loop through buffered frames for this station and if confirmation is
-     * requested, send auto confirmation with failure status. Also flush the frames so
-     * that these are not processed again in PEER_DEL_REQ handler.
-     */
-    INIT_LIST_HEAD(&send_cfm_list);
-
-    uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                             &send_cfm_list,
-                                             &(staInfo->mgtFrames));
-
-    uf_flush_list(priv, &(staInfo->mgtFrames));
-
-    for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
-        uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                                 &send_cfm_list,
-                                                 &(staInfo->dataPdu[j]));
-
-        uf_flush_list(priv,&(staInfo->dataPdu[j]));
-    }
-
-    send_auto_ma_packet_confirm(priv, staInfo->interfacePriv, &send_cfm_list);
-
-    unifi_warning(priv, "uf_send_disconnected_ind_wq: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
-                staInfo->peerMacAddress.a[0],
-                staInfo->peerMacAddress.a[1],
-                staInfo->peerMacAddress.a[2],
-                staInfo->peerMacAddress.a[3],
-                staInfo->peerMacAddress.a[4],
-                staInfo->peerMacAddress.a[5]);
-
-    CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
-                                      0,
-                                      staInfo->interfacePriv->InterfaceTag,
-                                      staInfo->peerMacAddress,
-                                      CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
-
-
-    return;
-}
-
-
-#endif
-void CsrWifiRouterCtrlPeerAddReqHandler(void* drvpriv,CsrWifiFsmEvent* msg)
-{
-    CsrWifiRouterCtrlPeerAddReq* req = (CsrWifiRouterCtrlPeerAddReq*)msg;
-    CsrResult status = CSR_RESULT_SUCCESS;
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    u32 handle = 0;
-    netInterface_priv_t *interfacePriv;
-
-    unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerAddReqHandler \n");
-    if (priv == NULL)
-    {
-        unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
-    {
-        unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: bad interfaceTag\n");
-        return;
-    }
-
-    interfacePriv = priv->interfacePriv[req->interfaceTag];
-
-    switch(interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            /* Add station record */
-            status = peer_add_new_record(priv,req,&handle);
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-        default:
-            /* No station record to maintain in these modes */
-            break;
-    }
-
-    CsrWifiRouterCtrlPeerAddCfmSend(msg->source,req->clientData,req->interfaceTag,req->peerMacAddress,handle,status);
-    unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerAddReqHandler \n");
-}
-
-void CsrWifiRouterCtrlPeerUpdateReqHandler(void* drvpriv,CsrWifiFsmEvent* msg)
-{
-    CsrWifiRouterCtrlPeerUpdateReq* req = (CsrWifiRouterCtrlPeerUpdateReq*)msg;
-    CsrResult status = CSR_RESULT_SUCCESS;
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-
-    unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerUpdateReqHandler \n");
-    if (priv == NULL)
-    {
-        unifi_error(priv, "CsrWifiRouterCtrlPeerUpdateReqHandler: invalid smepriv\n");
-        return;
-    }
-
-    CsrWifiRouterCtrlPeerUpdateCfmSend(msg->source,req->clientData,req->interfaceTag,status);
-    unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerUpdateReqHandler \n");
-}
-
-
- void CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    /* This will never be called as it is intercepted in the Userspace */
-}
-
-void CsrWifiRouterCtrlRawSdioInitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    /* This will never be called as it is intercepted in the Userspace */
-}
-
-void
-uf_send_ba_err_wq(struct work_struct *work)
-{
-    ba_session_rx_struct *ba_session = container_of(work, ba_session_rx_struct, send_ba_err_task);
-    unifi_priv_t *priv;
-
-    if(!ba_session) {
-        return;
-    }
-
-    if(!ba_session->interfacePriv) {
-        return;
-    }
-
-    priv = ba_session->interfacePriv->privPtr;
-
-    if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
-        return;
-    }
-
-    unifi_warning(priv, "%s: Calling CsrWifiRouterCtrlBlockAckErrorIndSend(%d, %d, %d, %d, %x:%x:%x:%x:%x:%x, %d)\n",
-                    __FUNCTION__,
-                    priv->CSR_WIFI_SME_IFACEQUEUE,
-                    0,
-                    ba_session->interfacePriv->InterfaceTag,
-                    ba_session->tID,
-                    ba_session->macAddress.a[0],
-                    ba_session->macAddress.a[1],
-                    ba_session->macAddress.a[2],
-                    ba_session->macAddress.a[3],
-                    ba_session->macAddress.a[4],
-                    ba_session->macAddress.a[5],
-                    CSR_RESULT_SUCCESS
-                 );
-    CsrWifiRouterCtrlBlockAckErrorIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
-                    0,
-                    ba_session->interfacePriv->InterfaceTag,
-                    ba_session->tID,
-                    ba_session->macAddress,
-                    CSR_RESULT_SUCCESS);
-}
-
-
-static void ba_session_terminate_timer_func(unsigned long data)
-{
-    ba_session_rx_struct *ba_session = (ba_session_rx_struct*)data;
-    struct unifi_priv *priv;
-
-    if(!ba_session) {
-        return;
-    }
-
-    if(!ba_session->interfacePriv) {
-        return;
-    }
-
-    priv = ba_session->interfacePriv->privPtr;
-
-    if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
-        return;
-    }
-
-    queue_work(priv->unifi_workqueue, &ba_session->send_ba_err_task);
-}
-
-
-u8 blockack_session_stop(unifi_priv_t *priv,
-                                     u16 interfaceTag,
-                                     CsrWifiRouterCtrlBlockAckRole role,
-                                     u16 tID,
-                                     CsrWifiMacAddress macAddress)
-{
-    netInterface_priv_t *interfacePriv;
-    ba_session_rx_struct *ba_session_rx = NULL;
-    ba_session_tx_struct *ba_session_tx = NULL;
-    u8 ba_session_idx = 0;
-    int i;
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
-        return FALSE;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if(!interfacePriv) {
-        unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
-        return FALSE;
-    }
-
-    if(tID > 15) {
-        unifi_error(priv, "%s: bad tID = %d\n", __FUNCTION__, tID);
-        return FALSE;
-    }
-
-    if((role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR) &&
-        (role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT)) {
-        unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
-        return FALSE;
-        }
-
-	unifi_warning(priv,
-		"%s: stopping ba_session for peer = %pM role = %d tID = %d\n",
-		__func__, macAddress.a, role, tID);
-
-    /* find out the appropriate ba session (/station /tid /role) for which stop is requested */
-    if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){
-        for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
-
-            ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];
-
-            if(ba_session_rx){
-                if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
-                    break;
-                }
-            }
-        }
-
-        if (!ba_session_rx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX)) {
-            unifi_error(priv, "%s: bad ba_session for Rx [tID=%d]\n", __FUNCTION__, tID);
-            return FALSE;
-        }
-
-
-        if(ba_session_rx->timeout) {
-            del_timer_sync(&ba_session_rx->timer);
-        }
-        cancel_work_sync(&ba_session_rx->send_ba_err_task);
-        for (i = 0; i < ba_session_rx->wind_size; i++) {
-            if(ba_session_rx->buffer[i].active) {
-                frame_desc_struct *frame_desc = &ba_session_rx->buffer[i];
-                unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
-            }
-        }
-        kfree(ba_session_rx->buffer);
-
-        interfacePriv->ba_session_rx[ba_session_idx] = NULL;
-        kfree(ba_session_rx);
-    }else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
-        for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
-        ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
-            if(ba_session_tx){
-                if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
-                    break;
-                }
-            }
-        }
-
-        if (!ba_session_tx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX)) {
-            unifi_error(priv, "%s: bad ba_session for Tx [tID=%d]\n", __FUNCTION__, tID);
-            return FALSE;
-        }
-        interfacePriv->ba_session_tx[ba_session_idx] = NULL;
-        kfree(ba_session_tx);
-
-    }
-
-    return TRUE;
-}
-
-
-void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    CsrWifiRouterCtrlBlockAckDisableReq* req = (CsrWifiRouterCtrlBlockAckDisableReq*)msg;
-    u8 r;
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-
-    unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__);
-
-    down(&priv->ba_mutex);
-    r = blockack_session_stop(priv,
-                              req->interfaceTag,
-                              req->role,
-                              req->trafficStreamID,
-                              req->macAddress);
-    up(&priv->ba_mutex);
-
-    CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source,
-                                            req->clientData,
-                                            req->interfaceTag,
-                                            r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);
-
-    unifi_trace(priv, UDBG6, "%s: out ok\n", __FUNCTION__);
-}
-
-
-u8 blockack_session_start(unifi_priv_t *priv,
-                               u16 interfaceTag,
-                               u16 tID,
-                               u16 timeout,
-                               CsrWifiRouterCtrlBlockAckRole role,
-                               u16 wind_size,
-                               u16 start_sn,
-                               CsrWifiMacAddress macAddress
-                              )
-{
-    netInterface_priv_t *interfacePriv;
-    ba_session_rx_struct *ba_session_rx = NULL;
-    ba_session_tx_struct *ba_session_tx = NULL;
-    u8 ba_session_idx = 0;
-
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
-        return FALSE;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if(!interfacePriv) {
-        unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
-        return FALSE;
-    }
-
-    if(tID > 15)
-    {
-        unifi_error(priv, "%s: bad tID=%d\n", __FUNCTION__, tID);
-        return FALSE;
-    }
-
-    if(wind_size > MAX_BA_WIND_SIZE) {
-        unifi_error(priv, "%s: bad wind_size = %d\n", __FUNCTION__, wind_size);
-        return FALSE;
-    }
-
-    if(role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR &&
-       role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT) {
-        unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
-        return FALSE;
-    }
-
-	unifi_warning(priv,
-		"%s: ba session with peer= (%pM)\n", __func__,
-		macAddress.a);
-
-    unifi_warning(priv, "%s: ba session for tID=%d timeout=%d role=%d wind_size=%d start_sn=%d\n", __FUNCTION__,
-                  tID,
-                  timeout,
-                  role,
-                  wind_size,
-                  start_sn);
-
-    /* Check if BA session exists for per station, per TID, per role or not.
-    if BA session exists update parameters and if it does not exist
-    create a new BA session */
-    if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
-        for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
-            ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
-            if (ba_session_tx) {
-                if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
-                    unifi_warning(priv, "%s: ba_session for Tx already exists\n", __FUNCTION__);
-                    return TRUE;
-                }
-            }
-        }
-
-        /* we have to create new ba_session_tx struct */
-         ba_session_tx = NULL;
-
-        /* loop through until an empty BA session slot is there and save the session there */
-        for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX ; ba_session_idx++){
-            if (!(interfacePriv->ba_session_tx[ba_session_idx])){
-                break;
-            }
-        }
-        if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX){
-            unifi_error(priv, "%s: All ba_session used for Tx, NO free session available\n", __FUNCTION__);
-            return FALSE;
-        }
-
-        /* create and populate the new BA session structure */
-        ba_session_tx = kzalloc(sizeof(ba_session_tx_struct), GFP_KERNEL);
-        if (!ba_session_tx) {
-            unifi_error(priv, "%s: kmalloc failed for ba_session_tx\n", __FUNCTION__);
-            return FALSE;
-        }
-
-        ba_session_tx->interfacePriv = interfacePriv;
-        ba_session_tx->tID = tID;
-        ba_session_tx->macAddress = macAddress;
-
-        interfacePriv->ba_session_tx[ba_session_idx] = ba_session_tx;
-
-    } else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){
-
-        for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
-            ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];
-            if (ba_session_rx) {
-                if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
-                    unifi_warning(priv, "%s: ba_session for Rx[tID = %d] already exists\n", __FUNCTION__, tID);
-
-                    if(ba_session_rx->wind_size == wind_size &&
-                        ba_session_rx->timeout == timeout &&
-                        ba_session_rx->expected_sn == start_sn) {
-                        return TRUE;
-                    }
-
-                    if(ba_session_rx->timeout) {
-                        del_timer_sync(&ba_session_rx->timer);
-                        ba_session_rx->timeout = 0;
-                    }
-
-                    if(ba_session_rx->wind_size != wind_size) {
-                        blockack_session_stop(priv, interfaceTag, role, tID, macAddress);
-                    } else {
-                        if (timeout) {
-                            ba_session_rx->timeout = timeout;
-                            ba_session_rx->timer.function = ba_session_terminate_timer_func;
-                            ba_session_rx->timer.data = (unsigned long)ba_session_rx;
-                            init_timer(&ba_session_rx->timer);
-                            mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
-                        }
-                        /*
-                         * The starting sequence number shall remain same if the BA
-                         * enable request is issued to update BA parameters only. If
-                         * it is not same, then we scroll our window to the new starting
-                         * sequence number. This could happen if the DELBA frame from
-                         * originator is lost and then we receive ADDBA frame with new SSN.
-                        */
-                        if(ba_session_rx->start_sn != start_sn) {
-                            scroll_ba_window(priv, interfacePriv, ba_session_rx, start_sn);
-                        }
-                        return TRUE;
-                    }
-                }
-            }
-        }
-
-        /* we could have a valid BA session pointer here or un-initialized
-        ba session pointer. but in any case we have to create a new session.
-        so re-initialize the ba_session pointer */
-        ba_session_rx = NULL;
-
-        /* loop through until an empty BA session slot is there and save the session there */
-        for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX ; ba_session_idx++){
-            if (!(interfacePriv->ba_session_rx[ba_session_idx])){
-                break;
-            }
-        }
-        if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
-            unifi_error(priv, "%s: All ba_session used for Rx, NO free session available\n", __FUNCTION__);
-            return FALSE;
-        }
-
-        /* It is observed that with some devices there is a race between
-         * EAPOL exchanges and BA session establishment. This results in
-         * some EAPOL authentication packets getting stuck in BA reorder
-         * buffer and hence the conection cannot be established. To avoid
-         * this we check here if the EAPOL authentication is complete and
-         * if so then only allow the BA session to establish.
-         *
-         * It is verified that the peers normally re-establish
-         * the BA session after the initial rejection.
-         */
-        if (CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN != uf_sme_port_state(priv, macAddress.a, UF_CONTROLLED_PORT_Q, interfacePriv->InterfaceTag))
-        {
-            unifi_warning(priv, "blockack_session_start: Controlled port not opened, Reject BA request\n");
-            return FALSE;
-        }
-
-        ba_session_rx = kzalloc(sizeof(ba_session_rx_struct), GFP_KERNEL);
-        if (!ba_session_rx) {
-            unifi_error(priv, "%s: kmalloc failed for ba_session_rx\n", __FUNCTION__);
-            return FALSE;
-        }
-
-        ba_session_rx->wind_size = wind_size;
-        ba_session_rx->start_sn = ba_session_rx->expected_sn = start_sn;
-        ba_session_rx->trigger_ba_after_ssn = FALSE;
-
-        ba_session_rx->buffer = kzalloc(ba_session_rx->wind_size*sizeof(frame_desc_struct), GFP_KERNEL);
-        if (!ba_session_rx->buffer) {
-            kfree(ba_session_rx);
-            unifi_error(priv, "%s: kmalloc failed for buffer\n", __FUNCTION__);
-            return FALSE;
-        }
-
-        INIT_WORK(&ba_session_rx->send_ba_err_task, uf_send_ba_err_wq);
-        if (timeout) {
-            ba_session_rx->timeout = timeout;
-            ba_session_rx->timer.function = ba_session_terminate_timer_func;
-            ba_session_rx->timer.data = (unsigned long)ba_session_rx;
-            init_timer(&ba_session_rx->timer);
-            mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
-        }
-
-        ba_session_rx->interfacePriv = interfacePriv;
-        ba_session_rx->tID = tID;
-        ba_session_rx->macAddress = macAddress;
-
-        interfacePriv->ba_session_rx[ba_session_idx] = ba_session_rx;
-    }
-    return TRUE;
-}
-
-void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-    CsrWifiRouterCtrlBlockAckEnableReq* req = (CsrWifiRouterCtrlBlockAckEnableReq*)msg;
-    u8 r;
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-
-    unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
-    down(&priv->ba_mutex);
-    r = blockack_session_start(priv,
-                               req->interfaceTag,
-                               req->trafficStreamID,
-                               req->timeout,
-                               req->role,
-                               req->bufferSize,
-                               req->ssn,
-                               req->macAddress
-                              );
-    up(&priv->ba_mutex);
-
-    CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source,
-                                           req->clientData,
-                                           req->interfaceTag,
-                                           r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);
-    unifi_trace(priv, UDBG6, "<<%s: r=%d\n", __FUNCTION__, r);
-
-}
-
-void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
-
-    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
-
-        unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
-
-        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status);
-
-        /* status 1 - Filter on
-        * status 0 - Filter off */
-        priv->wapi_multicast_filter = req->status;
-
-        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
-    } else {
-
-    	unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
-
-    }
-#elif defined(UNIFI_DEBUG)
-    /*WAPI Disabled*/
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastFilterReqHandler: called when WAPI isn't enabled\n");
-#endif
-}
-
-void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
-
-    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
-
-        unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
-
-        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status);
-
-        if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) {
-            /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */
-            priv->wapi_unicast_queued_pkt_filter = 1;
-        }
-
-        /* status 1 - Filter ON
-         * status 0 - Filter OFF */
-        priv->wapi_unicast_filter = req->status;
-
-        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
-    } else {
-
-    	 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
-
-    }
-#elif defined(UNIFI_DEBUG)
-    /*WAPI Disabled*/
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastFilterReqHandler: called when WAPI isn't enabled\n");
-#endif
-}
-
-void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlWapiRxPktReq* req =  (CsrWifiRouterCtrlWapiRxPktReq*)msg;
-    int client_id, receiver_id;
-    bulk_data_param_t bulkdata;
-    CsrResult res;
-    ul_client_t *client;
-    CSR_SIGNAL signal;
-    CSR_MA_PACKET_INDICATION *pkt_ind;
-    netInterface_priv_t *interfacePriv;
-
-    if (priv == NULL) {
-	    unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid priv\n", __func__);
-	    return;
-    }
-
-    if (priv->smepriv == NULL) {
-	    unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid sme priv\n", __func__);
-	    return;
-    }
-
-    interfacePriv = priv->interfacePriv[req->interfaceTag];
-
-    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
-
-    	unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
-
-
-        if (req->dataLength == 0 || req->data == NULL) {
-             unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: invalid request\n",__FUNCTION__);
-             return;
-        }
-
-        res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
-        if (res != CSR_RESULT_SUCCESS) {
-             unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: Could not allocate net data\n",__FUNCTION__);
-             return;
-        }
-
-        /* This function is expected to be called only when the MIC has been verified by SME to be correct
-         * So reset the reception status to rx_success */
-        res = read_unpack_signal(req->signal, &signal);
-        if (res) {
-	          unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Received unknown or corrupted signal.\n");
-	          return;
-        }
-        pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication);
-        if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) {
-	          unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus);
-	          return;
-        } else {
-	          unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiRxPktReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__);
-	          pkt_ind->ReceptionStatus = CSR_RX_SUCCESS;
-	          write_pack(&signal, req->signal, &(req->signalLength));
-        }
-
-        memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
-
-        receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(s16)) & 0xFFF0;
-        client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
-
-        client = &priv->ul_clients[client_id];
-
-        if (client && client->event_hook) {
-              unifi_trace(priv, UDBG3,
-                          "CsrWifiRouterCtrlWapiRxPktReq: "
-                          "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n",
-                          client->client_id, client->sender_id, receiver_id,
-                          CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal));
-
-              client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST);
-        } else {
-              unifi_trace(priv, UDBG4, "No client to give the packet to\n");
-              unifi_net_data_free(priv, &bulkdata.d[0]);
-        }
-
-        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
-    } else {
-    	unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
-    }
-#elif defined(UNIFI_DEBUG)
-    /*WAPI Disabled*/
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: called when WAPI isn't enabled\n");
-#endif
-}
-
-void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-
-	unifi_priv_t *priv = (unifi_priv_t*) drvpriv;
-    CsrWifiRouterCtrlWapiUnicastTxPktReq *req 	= (CsrWifiRouterCtrlWapiUnicastTxPktReq*) msg;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
-    bulk_data_param_t bulkdata;
-    u8 macHeaderLengthInBytes = MAC_HEADER_SIZE;
-    /*KeyID, Reserved, PN, MIC*/
-    u8 appendedCryptoFields = 1 + 1 + 16 + 16;
-    CsrResult result;
-    /* Retrieve the MA PACKET REQ fields from the Signal retained from send_ma_pkt_request() */
-    CSR_MA_PACKET_REQUEST *storedSignalMAPktReq = &interfacePriv->wapi_unicast_ma_pkt_sig.u.MaPacketRequest;
-
-    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
-
-        unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
-
-        if (priv == NULL) {
-            unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid priv\n",__FUNCTION__);
-            return;
-        }
-        if (priv->smepriv == NULL) {
-            unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid sme priv\n",__FUNCTION__);
-            return;
-        }
-        if (req->data == NULL) {
-            unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid request\n",__FUNCTION__);
-            return;
-        } else {
-            /* If it is QoS data (type = data subtype = QoS), frame header contains QoS control field */
-            if ((req->data[0] & 0x88) == 0x88) {
-      	        macHeaderLengthInBytes  = macHeaderLengthInBytes + QOS_CONTROL_HEADER_SIZE;
-            }
-        }
-        if ( !(req->dataLength>(macHeaderLengthInBytes+appendedCryptoFields)) ) {
-            unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid dataLength\n",__FUNCTION__);
-            return;
-        }
-
-	    /* Encrypted DATA Packet contained in (req->data)
-         * -------------------------------------------------------------------
-         * |MAC Header|  KeyId   | Reserved |    PN    | xxDataxx | xxMICxxx |
-         * -------------------------------------------------------------------
-         *                                             (<-----Encrypted----->)
-         * -------------------------------------------------------------------
-         * |24/26(QoS)|    1     |    1     |    16    |    x     |    16    |
-         * -------------------------------------------------------------------
-         */
-        result = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
-        if (result != CSR_RESULT_SUCCESS) {
-             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: Could not allocate net data\n",__FUNCTION__);
-             return;
-        }
-        memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
-        bulkdata.d[0].data_length = req->dataLength;
-        bulkdata.d[1].os_data_ptr = NULL;
-        bulkdata.d[1].data_length = 0;
-
-        /* Send UniFi msg */
-        /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
-        result = uf_process_ma_packet_req(priv,
-    	                                  storedSignalMAPktReq->Ra.x,
-                                          storedSignalMAPktReq->HostTag,/* Ask for a new HostTag */
-                                          req->interfaceTag,
-                                          storedSignalMAPktReq->TransmissionControl,
-                                          storedSignalMAPktReq->TransmitRate,
-                                          storedSignalMAPktReq->Priority, /* Retained value */
-                                          interfacePriv->wapi_unicast_ma_pkt_sig.SignalPrimitiveHeader.SenderProcessId, /*FIXME AP: VALIDATE ???*/
-                                          &bulkdata);
-
-        if (result == NETDEV_TX_OK) {
-             (priv->netdev[req->interfaceTag])->trans_start = jiffies;
-             /* Should really count tx stats in the UNITDATA.status signal but
-              * that doesn't have the length.
-              */
-             interfacePriv->stats.tx_packets++;
-
-             /* count only the packet payload */
-             interfacePriv->stats.tx_bytes += req->dataLength - macHeaderLengthInBytes - appendedCryptoFields;
-             unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Sent), sent count = %x\n", interfacePriv->stats.tx_packets);
-        } else {
-             /* Failed to send: fh queue was full, and the skb was discarded*/
-             unifi_trace(priv, UDBG1, "(HIP validation failure) Result = %d\n", result);
-             unifi_net_data_free(priv, &bulkdata.d[0]);
-
-             interfacePriv->stats.tx_dropped++;
-             unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
-        }
-
-        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
-
-    } else {
-
-    	unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
-
-    }
-#elif defined(UNIFI_DEBUG)
-    /*WAPI Disabled*/
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: called when WAPI SW ENCRYPTION isn't enabled\n");
-#endif
-}
-
-void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-
-#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    CsrWifiRouterCtrlWapiFilterReq* req = (CsrWifiRouterCtrlWapiFilterReq*)msg;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
-
-    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
-
-        unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
-
-        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiFilterReq: req->isWapiConnected [0/1] = %d \n",req->isWapiConnected);
-
-        priv->isWapiConnection = req->isWapiConnected;
-
-        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
-    } else {
-
-    	unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
-
-    }
-#endif
-
-#elif defined(UNIFI_DEBUG)
-    /*WAPI Disabled*/
-    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
-    unifi_error(priv,"CsrWifiRouterCtrlWapiFilterReq: called when WAPI isn't enabled\n");
-#endif
-}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sme_userspace.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_userspace.c
--- linux-libre-3.10-gnu/drivers/staging/csr/sme_userspace.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_userspace.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,315 +0,0 @@
-/*
- *****************************************************************************
- *
- * FILE : sme_userspace.c
- *
- * PURPOSE : Support functions for userspace SME helper application.
- *
- *
- * Copyright (C) 2008-2011 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- *****************************************************************************
- */
-
-#include "unifi_priv.h"
-
-/*
- * Fix Me..... These need to be the correct values...
- * Dynamic from the user space.
- */
-CsrSchedQid CSR_WIFI_ROUTER_IFACEQUEUE   = 0xFFFF;
-CsrSchedQid CSR_WIFI_SME_IFACEQUEUE      = 0xFFFF;
-#ifdef CSR_SUPPORT_WEXT_AP
-CsrSchedQid CSR_WIFI_NME_IFACEQUEUE      = 0xFFFF;
-#endif
-int
-uf_sme_init(unifi_priv_t *priv)
-{
-    int i, j;
-
-    CsrWifiRouterTransportInit(priv);
-
-    priv->smepriv = priv;
-
-    init_waitqueue_head(&priv->sme_request_wq);
-
-    priv->filter_tclas_ies = NULL;
-    memset(&priv->packet_filters, 0, sizeof(uf_cfg_bcast_packet_filter_t));
-
-#ifdef CSR_SUPPORT_WEXT
-    priv->ignore_bssid_join = FALSE;
-    priv->mib_data.length = 0;
-
-    uf_sme_wext_set_defaults(priv);
-#endif /* CSR_SUPPORT_WEXT*/
-
-    priv->sta_ip_address = 0xFFFFFFFF;
-
-    priv->wifi_on_state = wifi_on_unspecified;
-
-    sema_init(&priv->sme_sem, 1);
-    memset(&priv->sme_reply, 0, sizeof(sme_reply_t));
-
-    priv->ta_ind_work.in_use = 0;
-    priv->ta_sample_ind_work.in_use = 0;
-
-    priv->CSR_WIFI_SME_IFACEQUEUE = 0xFFFF;
-
-    for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
-        priv->sme_unidata_ind_filters[i].in_use = 0;
-    }
-
-    /* Create a work queue item for Traffic Analysis indications to SME */
-    INIT_WORK(&priv->ta_ind_work.task, uf_ta_ind_wq);
-    INIT_WORK(&priv->ta_sample_ind_work.task, uf_ta_sample_ind_wq);
-#ifdef CSR_SUPPORT_WEXT
-    INIT_WORK(&priv->sme_config_task, uf_sme_config_wq);
-#endif
-
-    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
-        netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
-        interfacePriv->m4_sent = FALSE;
-        interfacePriv->m4_bulk_data.net_buf_length = 0;
-        interfacePriv->m4_bulk_data.data_length = 0;
-        interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
-
-        memset(&interfacePriv->controlled_data_port, 0, sizeof(unifi_port_config_t));
-        interfacePriv->controlled_data_port.entries_in_use = 1;
-        interfacePriv->controlled_data_port.port_cfg[0].in_use = TRUE;
-        interfacePriv->controlled_data_port.port_cfg[0].port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-        interfacePriv->controlled_data_port.overide_action = UF_DATA_PORT_OVERIDE;
-
-        memset(&interfacePriv->uncontrolled_data_port, 0, sizeof(unifi_port_config_t));
-        interfacePriv->uncontrolled_data_port.entries_in_use = 1;
-        interfacePriv->uncontrolled_data_port.port_cfg[0].in_use = TRUE;
-        interfacePriv->uncontrolled_data_port.port_cfg[0].port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-        interfacePriv->uncontrolled_data_port.overide_action = UF_DATA_PORT_OVERIDE;
-
-        /* Mark the remainder of the port config table as unallocated */
-        for(j = 1; j < UNIFI_MAX_CONNECTIONS; j++) {
-            interfacePriv->controlled_data_port.port_cfg[j].in_use = FALSE;
-            interfacePriv->controlled_data_port.port_cfg[j].port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-
-            interfacePriv->uncontrolled_data_port.port_cfg[j].in_use = FALSE;
-            interfacePriv->uncontrolled_data_port.port_cfg[j].port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-        }
-
-        /* intializing the lists */
-        INIT_LIST_HEAD(&interfacePriv->genericMgtFrames);
-        INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastMgtFrames);
-        INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastFrames);
-
-        for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) {
-            interfacePriv->staInfo[j] = NULL;
-        }
-
-        interfacePriv->num_stations_joined = 0;
-        interfacePriv->sta_activity_check_enabled = FALSE;
-    }
-
-
-    return 0;
-} /* uf_sme_init() */
-
-
-void
-uf_sme_deinit(unifi_priv_t *priv)
-{
-    int i,j;
-    u8 ba_session_idx;
-    ba_session_rx_struct *ba_session_rx = NULL;
-    ba_session_tx_struct *ba_session_tx = NULL;
-    CsrWifiRouterCtrlStaInfo_t *staInfo = NULL;
-    netInterface_priv_t *interfacePriv = NULL;
-
-    /* Free any TCLASs previously allocated */
-    if (priv->packet_filters.tclas_ies_length) {
-        priv->packet_filters.tclas_ies_length = 0;
-        kfree(priv->filter_tclas_ies);
-        priv->filter_tclas_ies = NULL;
-    }
-
-    for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
-        priv->sme_unidata_ind_filters[i].in_use = 0;
-    }
-
-    /* Remove all the Peer database, before going down */
-    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
-        down(&priv->ba_mutex);
-        for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
-            ba_session_rx = priv->interfacePriv[i]->ba_session_rx[ba_session_idx];
-            if(ba_session_rx) {
-                blockack_session_stop(priv,
-                                    i,
-                                    CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT,
-                                    ba_session_rx->tID,
-                                    ba_session_rx->macAddress);
-            }
-        }
-        for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
-            ba_session_tx = priv->interfacePriv[i]->ba_session_tx[ba_session_idx];
-            if(ba_session_tx) {
-                blockack_session_stop(priv,
-                                    i,
-                                    CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR,
-                                    ba_session_tx->tID,
-                                    ba_session_tx->macAddress);
-            }
-        }
-
-        up(&priv->ba_mutex);
-        interfacePriv = priv->interfacePriv[i];
-        if(interfacePriv){
-            for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) {
-                if ((staInfo=interfacePriv->staInfo[j]) != NULL) {
-                    /* Clear the STA activity parameters before freeing station Record */
-                    unifi_trace(priv, UDBG1, "uf_sme_deinit: Canceling work queue for STA with AID: %d\n", staInfo->aid);
-                    cancel_work_sync(&staInfo->send_disconnected_ind_task);
-                    staInfo->nullDataHostTag = INVALID_HOST_TAG;
-                }
-            }
-            if (interfacePriv->sta_activity_check_enabled){
-                interfacePriv->sta_activity_check_enabled = FALSE;
-                del_timer_sync(&interfacePriv->sta_activity_check_timer);
-            }
-        }
-        CsrWifiRouterCtrlInterfaceReset(priv, i);
-        priv->interfacePriv[i]->interfaceMode = CSR_WIFI_ROUTER_CTRL_MODE_NONE;
-    }
-
-
-} /* uf_sme_deinit() */
-
-
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_ta_indicate_protocol
- *
- *      Report that a packet of a particular type has been seen
- *
- *  Arguments:
- *      drv_priv        The device context pointer passed to ta_init.
- *      protocol        The protocol type enum value.
- *      direction       Whether the packet was a tx or rx.
- *      src_addr        The source MAC address from the data packet.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      We defer the actual sending to a background workqueue,
- *      see uf_ta_ind_wq().
- * ---------------------------------------------------------------------------
- */
-void
-unifi_ta_indicate_protocol(void *ospriv,
-                           CsrWifiRouterCtrlTrafficPacketType packet_type,
-                           CsrWifiRouterCtrlProtocolDirection direction,
-                           const CsrWifiMacAddress *src_addr)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-
-    if (priv->ta_ind_work.in_use) {
-        unifi_warning(priv,
-                "unifi_ta_indicate_protocol: workqueue item still in use, not sending\n");
-        return;
-    }
-
-    if (CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX == direction)
-    {
-        u16 interfaceTag = 0;
-        CsrWifiRouterCtrlTrafficProtocolIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,
-                interfaceTag,
-                packet_type,
-                direction,
-                *src_addr);
-    }
-    else
-    {
-        priv->ta_ind_work.packet_type = packet_type;
-        priv->ta_ind_work.direction = direction;
-        priv->ta_ind_work.src_addr = *src_addr;
-
-        queue_work(priv->unifi_workqueue, &priv->ta_ind_work.task);
-    }
-
-} /* unifi_ta_indicate_protocol() */
-
-
-/*
- * ---------------------------------------------------------------------------
- * unifi_ta_indicate_sampling
- *
- *      Send the TA sampling information to the SME.
- *
- *  Arguments:
- *      drv_priv        The device context pointer passed to ta_init.
- *      stats   The TA sampling data to send.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-unifi_ta_indicate_sampling(void *ospriv, CsrWifiRouterCtrlTrafficStats *stats)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-
-    if (!priv) {
-        return;
-    }
-
-    if (priv->ta_sample_ind_work.in_use) {
-        unifi_warning(priv,
-                     "unifi_ta_indicate_sampling: workqueue item still in use, not sending\n");
-        return;
-    }
-
-    priv->ta_sample_ind_work.stats = *stats;
-
-    queue_work(priv->unifi_workqueue, &priv->ta_sample_ind_work.task);
-
-} /* unifi_ta_indicate_sampling() */
-
-
-/*
- * ---------------------------------------------------------------------------
- * unifi_ta_indicate_l4stats
- *
- *      Send the TA TCP/UDP throughput information to the driver.
- *
- *  Arguments:
- *    drv_priv        The device context pointer passed to ta_init.
- *    rxTcpThroughput TCP RX throughput in KiloBytes
- *    txTcpThroughput TCP TX throughput in KiloBytes
- *    rxUdpThroughput UDP RX throughput in KiloBytes
- *    txUdpThroughput UDP TX throughput in KiloBytes
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-unifi_ta_indicate_l4stats(void *ospriv,
-                          u32 rxTcpThroughput,
-                          u32 txTcpThroughput,
-                          u32 rxUdpThroughput,
-                          u32 txUdpThroughput)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-
-    if (!priv) {
-        return;
-    }
-    /* Save the info. The actual action will be taken in unifi_ta_indicate_sampling() */
-    priv->rxTcpThroughput = rxTcpThroughput;
-    priv->txTcpThroughput = txTcpThroughput;
-    priv->rxUdpThroughput = rxUdpThroughput;
-    priv->txUdpThroughput = txUdpThroughput;
-} /* unifi_ta_indicate_l4stats() */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sme_userspace.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_userspace.h
--- linux-libre-3.10-gnu/drivers/staging/csr/sme_userspace.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_userspace.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,38 +0,0 @@
-/*
- * ***************************************************************************
- *  FILE:     sme_userspace.h
- *
- *  PURPOSE:    SME related definitions.
- *
- *  Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ***************************************************************************
- */
-#ifndef __LINUX_SME_USERSPACE_H__
-#define __LINUX_SME_USERSPACE_H__ 1
-
-#include <linux/kernel.h>
-
-int uf_sme_init(unifi_priv_t *priv);
-void uf_sme_deinit(unifi_priv_t *priv);
-int uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length);
-
-
-#include "csr_wifi_router_lib.h"
-#include "csr_wifi_router_sef.h"
-#include "csr_wifi_router_ctrl_lib.h"
-#include "csr_wifi_router_ctrl_sef.h"
-#include "csr_wifi_sme_task.h"
-#ifdef CSR_SUPPORT_WEXT_AP
-#include "csr_wifi_nme_ap_lib.h"
-#endif
-#include "csr_wifi_sme_lib.h"
-
-void CsrWifiRouterTransportInit(unifi_priv_t *priv);
-void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8 *buffer, size_t bufferLength);
-void CsrWifiRouterTransportDeInit(unifi_priv_t *priv);
-
-#endif /* __LINUX_SME_USERSPACE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/sme_wext.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_wext.c
--- linux-libre-3.10-gnu/drivers/staging/csr/sme_wext.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/sme_wext.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,3327 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     sme_wext.c
- *
- * PURPOSE:
- *      Handlers for ioctls from iwconfig.
- *      These provide the control plane operations.
- *
- * Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/types.h>
-#include <linux/etherdevice.h>
-#include <linux/if_arp.h>
-#include <asm/uaccess.h>
-#include <linux/ctype.h>
-#include "unifi_priv.h"
-#include <linux/rtnetlink.h>
-
-#define CHECK_INITED(_priv)                             \
-    do {                                                    \
-        if (_priv->init_progress != UNIFI_INIT_COMPLETED) { \
-            unifi_trace(_priv, UDBG2, "%s unifi not ready, failing wext call\n", __FUNCTION__); \
-            return -ENODEV;                                 \
-        }                                                   \
-    } while (0)
-
-/* Workaround for the wpa_supplicant hanging issue - disabled on Android */
-#ifndef ANDROID_BUILD
-#define CSR_WIFI_WEXT_HANG_WORKAROUND
-#endif
-
-#ifdef CSR_WIFI_WEXT_HANG_WORKAROUND
-# define UF_RTNL_LOCK()    rtnl_lock()
-# define UF_RTNL_UNLOCK()  rtnl_unlock()
-#else
-# define UF_RTNL_LOCK()
-# define UF_RTNL_UNLOCK()
-#endif
-
-
-/*
- * ---------------------------------------------------------------------------
- *      Helper functions
- * ---------------------------------------------------------------------------
- */
-
-/*
- * ---------------------------------------------------------------------------
- *  wext_freq_to_channel
- *  channel_to_mhz
- *
- *      These functions convert between channel number and frequency.
- *
- *  Arguments:
- *      ch      Channel number, as defined in 802.11 specs
- *      m, e    Mantissa and exponent as provided by wireless extension.
- *
- *  Returns:
- *      channel or frequency (in MHz) value
- * ---------------------------------------------------------------------------
- */
-static int
-wext_freq_to_channel(int m, int e)
-{
-    int mhz;
-
-    mhz = m;
-    while (e < 6) {
-        mhz /= 10;
-        e++;
-    }
-    while (e > 6) {
-        mhz *= 10;
-        e--;
-    }
-
-    if (mhz >= 5000) {
-        return ((mhz - 5000) / 5);
-    }
-
-    if (mhz == 2482) {
-        return 14;
-    }
-
-    if (mhz >= 2407) {
-        return ((mhz - 2407) / 5);
-    }
-
-    return 0;
-} /* wext_freq_to_channel() */
-
-static int
-channel_to_mhz(int ch, int dot11a)
-{
-
-    if (ch == 0) return 0;
-    if (ch > 200) return 0;
-
-    /* 5G */
-    if (dot11a) {
-        return (5000 + (5 * ch));
-    }
-
-    /* 2.4G */
-    if (ch == 14) {
-        return 2484;
-    }
-
-    if ((ch < 14) && (ch > 0)) {
-        return (2407 + (5 * ch));
-    }
-
-    return 0;
-}
-#ifdef CSR_SUPPORT_WEXT_AP
-void uf_sme_wext_ap_set_defaults(unifi_priv_t *priv)
-{
-    memcpy(priv->ap_config.ssid.ssid,"defaultssid",sizeof("defaultssid"));
-
-    priv->ap_config.ssid.length = 8;
-    priv->ap_config.channel = 6;
-    priv->ap_config.if_index = 1;
-    priv->ap_config.credentials.authType = 0;
-    priv->ap_config.max_connections=8;
-
-    priv->group_sec_config.apGroupkeyTimeout = 0;
-    priv->group_sec_config.apStrictGtkRekey = 0;
-    priv->group_sec_config.apGmkTimeout = 0;
-    priv->group_sec_config.apResponseTimeout = 100; /* Default*/
-    priv->group_sec_config.apRetransLimit = 3; /* Default*/
-    /* Set default params even if they may not be used*/
-    /* Until Here*/
-
-    priv->ap_mac_config.preamble = CSR_WIFI_SME_USE_LONG_PREAMBLE;
-    priv->ap_mac_config.shortSlotTimeEnabled = FALSE;
-    priv->ap_mac_config.ctsProtectionType=CSR_WIFI_SME_CTS_PROTECTION_AUTOMATIC;
-
-    priv->ap_mac_config.wmmEnabled = TRUE;
-    priv->ap_mac_config.wmmApParams[0].cwMin=4;
-    priv->ap_mac_config.wmmApParams[0].cwMax=10;
-    priv->ap_mac_config.wmmApParams[0].aifs=3;
-    priv->ap_mac_config.wmmApParams[0].txopLimit=0;
-    priv->ap_mac_config.wmmApParams[0].admissionControlMandatory=FALSE;
-    priv->ap_mac_config.wmmApParams[1].cwMin=4;
-    priv->ap_mac_config.wmmApParams[1].cwMax=10;
-    priv->ap_mac_config.wmmApParams[1].aifs=7;
-    priv->ap_mac_config.wmmApParams[1].txopLimit=0;
-    priv->ap_mac_config.wmmApParams[1].admissionControlMandatory=FALSE;
-    priv->ap_mac_config.wmmApParams[2].cwMin=3;
-    priv->ap_mac_config.wmmApParams[2].cwMax=4;
-    priv->ap_mac_config.wmmApParams[2].aifs=1;
-    priv->ap_mac_config.wmmApParams[2].txopLimit=94;
-    priv->ap_mac_config.wmmApParams[2].admissionControlMandatory=FALSE;
-    priv->ap_mac_config.wmmApParams[3].cwMin=2;
-    priv->ap_mac_config.wmmApParams[3].cwMax=3;
-    priv->ap_mac_config.wmmApParams[3].aifs=1;
-    priv->ap_mac_config.wmmApParams[3].txopLimit=47;
-    priv->ap_mac_config.wmmApParams[3].admissionControlMandatory=FALSE;
-
-    priv->ap_mac_config.wmmApBcParams[0].cwMin=4;
-    priv->ap_mac_config.wmmApBcParams[0].cwMax=10;
-    priv->ap_mac_config.wmmApBcParams[0].aifs=3;
-    priv->ap_mac_config.wmmApBcParams[0].txopLimit=0;
-    priv->ap_mac_config.wmmApBcParams[0].admissionControlMandatory=FALSE;
-    priv->ap_mac_config.wmmApBcParams[1].cwMin=4;
-    priv->ap_mac_config.wmmApBcParams[1].cwMax=10;
-    priv->ap_mac_config.wmmApBcParams[1].aifs=7;
-    priv->ap_mac_config.wmmApBcParams[1].txopLimit=0;
-    priv->ap_mac_config.wmmApBcParams[1].admissionControlMandatory=FALSE;
-    priv->ap_mac_config.wmmApBcParams[2].cwMin=3;
-    priv->ap_mac_config.wmmApBcParams[2].cwMax=4;
-    priv->ap_mac_config.wmmApBcParams[2].aifs=2;
-    priv->ap_mac_config.wmmApBcParams[2].txopLimit=94;
-    priv->ap_mac_config.wmmApBcParams[2].admissionControlMandatory=FALSE;
-    priv->ap_mac_config.wmmApBcParams[3].cwMin=2;
-    priv->ap_mac_config.wmmApBcParams[3].cwMax=3;
-    priv->ap_mac_config.wmmApBcParams[3].aifs=2;
-    priv->ap_mac_config.wmmApBcParams[3].txopLimit=47;
-    priv->ap_mac_config.wmmApBcParams[3].admissionControlMandatory=FALSE;
-
-    priv->ap_mac_config.accessType=CSR_WIFI_AP_ACCESS_TYPE_NONE;
-    priv->ap_mac_config.macAddressListCount=0;
-    priv->ap_mac_config.macAddressList=NULL;
-
-    priv->ap_mac_config.apHtParams.rxStbc=1;
-    priv->ap_mac_config.apHtParams.rifsModeAllowed=TRUE;
-    priv->ap_mac_config.apHtParams.greenfieldSupported=FALSE;
-    priv->ap_mac_config.apHtParams.shortGi20MHz=TRUE;
-    priv->ap_mac_config.apHtParams.htProtection=0;
-    priv->ap_mac_config.apHtParams.dualCtsProtection=FALSE;
-
-    priv->ap_mac_config.phySupportedBitmap =
-            (CSR_WIFI_SME_AP_PHY_SUPPORT_B|CSR_WIFI_SME_AP_PHY_SUPPORT_G|CSR_WIFI_SME_AP_PHY_SUPPORT_N);
-    priv->ap_mac_config.beaconInterval= 100;
-    priv->ap_mac_config.dtimPeriod=3;
-    priv->ap_mac_config.maxListenInterval=0x00ff;/* Set it to a large value
-                                                    to enable different types of
-                                                    devices to join us */
-    priv->ap_mac_config.supportedRatesCount =
-           uf_configure_supported_rates(priv->ap_mac_config.supportedRates,priv->ap_mac_config.phySupportedBitmap);
-}
-#endif
-/*
- * ---------------------------------------------------------------------------
- *  uf_sme_wext_set_defaults
- *
- *      Set up power-on defaults for driver config.
- *
- *      Note: The SME Management API *cannot* be used in this function.
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-uf_sme_wext_set_defaults(unifi_priv_t *priv)
-{
-    memset(&priv->connection_config, 0, sizeof(CsrWifiSmeConnectionConfig));
-
-    priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE;
-    priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
-    priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
-    priv->connection_config.privacyMode = CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED;
-    priv->connection_config.wmmQosInfo = 0xFF;
-    priv->connection_config.ifIndex = CSR_WIFI_SME_RADIO_IF_BOTH;
-    priv->connection_config.adhocJoinOnly = FALSE;
-    priv->connection_config.adhocChannel = 6;
-
-    priv->wep_tx_key_index = 0;
-
-    priv->wext_wireless_stats.qual.qual = 0;
-    priv->wext_wireless_stats.qual.level = 0;
-    priv->wext_wireless_stats.qual.noise = 0;
-    priv->wext_wireless_stats.qual.updated = 0x70;
-#ifdef CSR_SUPPORT_WEXT_AP
-    /* Initialize the default configuration for AP */
-    uf_sme_wext_ap_set_defaults(priv);
-#endif
-
-
-} /* uf_sme_wext_set_defaults() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *      WEXT methods
- * ---------------------------------------------------------------------------
- */
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_giwname   - handler for SIOCGIWNAME
- *  unifi_siwfreq   - handler for SIOCSIWFREQ
- *  unifi_giwfreq   - handler for SIOCGIWFREQ
- *  unifi_siwmode   - handler for SIOCSIWMODE
- *  unifi_giwmode   - handler for SIOCGIWMODE
- *  unifi_giwrange  - handler for SIOCGIWRANGE
- *  unifi_siwap     - handler for SIOCSIWAP
- *  unifi_giwap     - handler for SIOCGIWAP
- *  unifi_siwscan   - handler for SIOCSIWSCAN
- *  unifi_giwscan   - handler for SIOCGIWSCAN
- *  unifi_siwessid  - handler for SIOCSIWESSID
- *  unifi_giwessid  - handler for SIOCGIWESSID
- *  unifi_siwencode - handler for SIOCSIWENCODE
- *  unifi_giwencode - handler for SIOCGIWENCODE
- *
- *      Handler functions for IW extensions.
- *      These are registered via the unifi_iw_handler_def struct below
- *      and called by the generic IW driver support code.
- *      See include/net/iw_handler.h.
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static int
-iwprivsdefs(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    int r;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    CsrWifiSmeMibConfig mibConfig;
-    CsrWifiSmePowerConfig powerConfig;
-
-    unifi_trace(priv, UDBG1, "iwprivs80211defaults: reload defaults\n");
-
-    uf_sme_wext_set_defaults(priv);
-
-    /* Get, modify and set the MIB data */
-    r = sme_mgt_mib_config_get(priv, &mibConfig);
-    if (r) {
-        unifi_error(priv, "iwprivs80211defaults: Get CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-    mibConfig.dot11RtsThreshold = 2347;
-    mibConfig.dot11FragmentationThreshold = 2346;
-    r = sme_mgt_mib_config_set(priv, &mibConfig);
-    if (r) {
-        unifi_error(priv, "iwprivs80211defaults: Set CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-
-    powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW;
-    powerConfig.listenIntervalTu = 100;
-    powerConfig.rxDtims = 1;
-
-    r = sme_mgt_power_config_set(priv, &powerConfig);
-    if (r) {
-        unifi_error(priv, "iwprivs80211defaults: Set unifi_PowerConfigValue failed.\n");
-        return r;
-    }
-
-    return 0;
-} /* iwprivsdefs() */
-
-static int
-iwprivs80211ps(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    int r = 0;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    int ps_mode = (int)(*extra);
-    CsrWifiSmePowerConfig powerConfig;
-
-    unifi_trace(priv, UDBG1, "iwprivs80211ps: power save mode = %d\n", ps_mode);
-
-    r = sme_mgt_power_config_get(priv, &powerConfig);
-    if (r) {
-        unifi_error(priv, "iwprivs80211ps: Get unifi_PowerConfigValue failed.\n");
-        return r;
-    }
-
-    switch (ps_mode) {
-        case CSR_PMM_ACTIVE_MODE:
-            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW;
-            break;
-        case CSR_PMM_POWER_SAVE:
-            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH;
-            break;
-        case CSR_PMM_FAST_POWER_SAVE:
-            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_MED;
-            break;
-        default:
-            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO;
-            break;
-    }
-
-    r = sme_mgt_power_config_set(priv, &powerConfig);
-    if (r) {
-        unifi_error(priv, "iwprivs80211ps: Set unifi_PowerConfigValue failed.\n");
-    }
-
-    return r;
-}
-
-static int
-iwprivg80211ps(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    CsrWifiSmePowerConfig powerConfig;
-    int r;
-
-    r = sme_mgt_power_config_get(priv, &powerConfig);
-    if (r) {
-        unifi_error(priv, "iwprivg80211ps: Get 802.11 power mode failed.\n");
-        return r;
-    }
-
-    switch (powerConfig.powerSaveLevel) {
-        case CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW:
-            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
-                     "Power save mode: %d (Active)",
-                     powerConfig.powerSaveLevel);
-            break;
-        case CSR_WIFI_SME_POWER_SAVE_LEVEL_MED:
-            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
-                     "Power save mode: %d (Fast)",
-                     powerConfig.powerSaveLevel);
-            break;
-        case CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH:
-            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
-                     "Power save mode: %d (Full)",
-                     powerConfig.powerSaveLevel);
-            break;
-        case CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO:
-            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
-                     "Power save mode: %d (Auto)",
-                     powerConfig.powerSaveLevel);
-            break;
-        default:
-            snprintf(extra, IWPRIV_POWER_SAVE_MAX_STRING,
-                     "Power save mode: %d (Unknown)",
-                     powerConfig.powerSaveLevel);
-            break;
-    }
-
-    wrqu->data.length = strlen(extra) + 1;
-
-    return 0;
-}
-
-static int
-iwprivssmedebug(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    /* No longer supported on the API */
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE)
-    unifi_debug_buf_dump();
-#endif
-
-    return 0;
-}
-
-#ifdef CSR_SUPPORT_WEXT_AP
-#define PARAM_TYPE_INT 0
-#define PARAM_TYPE_STRING 1
-#define CSR_WIFI_MAX_SSID_LEN 32
-#define CSR_WIFI_MAX_SEC_LEN 16
-#define CSR_WIFI_MAX_KEY_LEN 65
-
-static int hex_look_up(char x)
-{
-    if(x>='0' && x<='9')
-        return (x-48);
-    if(x>= 'a' && x <= 'f')
-        return (x-87);
-    return -1;
-}
-
-static int power (int a, int b)
-{
-    int i;
-    int num =1;
-    for(i=0;i<b;i++)
-       num *=a;
-    return num;
-}
-
-static int decode_parameter_from_string(unifi_priv_t* priv, char **str_ptr,
-                                        const char *token, int param_type,
-                                        void  *dst, int param_max_len)
-{
-    u8 int_str[7] = "0";
-    u32 param_str_len;
-    u8  *param_str_begin,*param_str_end;
-    u8  *orig_str = *str_ptr;
-
-    if (!strncmp(*str_ptr, token, strlen(token))) {
-        strsep(str_ptr, "=,");
-        param_str_begin = *str_ptr;
-        strsep(str_ptr, "=,");
-        if (*str_ptr == NULL) {
-            param_str_len = strlen(param_str_begin);
-        } else {
-            param_str_end = *str_ptr-1;
-            param_str_len = param_str_end - param_str_begin;
-        }
-        unifi_trace(priv,UDBG2,"'token:%s', len:%d, ", token, param_str_len);
-        if (param_str_len > param_max_len) {
-            unifi_notice(priv,"extracted param len:%d is > MAX:%d\n",param_str_len, param_max_len);
-            param_str_len = param_max_len;
-        }
-        switch (param_type) {
-            case PARAM_TYPE_INT:
-            {
-                u32 *pdst_int = dst,num =0;
-                int i,j=0;
-                if (param_str_len > sizeof(int_str)) {
-                    param_str_len = sizeof(int_str);
-                }
-                memcpy(int_str, param_str_begin, param_str_len);
-                for(i = param_str_len; i>0;i--) {
-                    if(int_str[i-1] >= '0' && int_str[i-1] <='9') {
-                        num += ((int_str[i-1]-'0')*power(10,j));
-                        j++;
-                    } else {
-                        unifi_error(priv,"decode_parameter_from_string:not a number %c\n",(int_str[i-1]));
-                        return -1;
-                    }
-                }
-                *pdst_int = num;
-                unifi_trace(priv,UDBG2,"decode_parameter_from_string:decoded int = %d\n",*pdst_int);
-            }
-            break;
-            default:
-                memcpy(dst, param_str_begin, param_str_len);
-                *((char *)dst + param_str_len) = 0;
-                unifi_trace(priv,UDBG2,"decode_parameter_from_string:decoded string = %s\n",(char *)dst);
-            break;
-        }
-    } else {
-        unifi_error(priv,"decode_parameter_from_string: Token:%s not found in %s \n",token,orig_str);
-        return -1;
-    }
-    return 0;
-}
-static int store_ap_advanced_config_from_string(unifi_priv_t *priv, char *param_str)
-{
-    char * str_ptr=param_str;
-    int ret = 0,tmp_var;
-    char phy_mode[6];
-    CsrWifiSmeApMacConfig * ap_mac_config = &priv->ap_mac_config;
-
-    /* Check for BI */
-    ret = decode_parameter_from_string(priv, &str_ptr, "BI=",
-                                       PARAM_TYPE_INT, &tmp_var, 5);
-    if(ret) {
-        unifi_error(priv,"store_ap_advanced_config_from_string: BI not found\n");
-        return -1;
-    }
-    ap_mac_config->beaconInterval = tmp_var;
-    ret = decode_parameter_from_string(priv, &str_ptr, "DTIM_PER=",
-                                        PARAM_TYPE_INT, &tmp_var, 5);
-    if(ret) {
-        unifi_error(priv,"store_ap_advanced_config_from_string: DTIM_PER not found\n");
-        return -1;
-    }
-    ap_mac_config->dtimPeriod = tmp_var;
-    ret = decode_parameter_from_string(priv, &str_ptr, "WMM=",
-                                        PARAM_TYPE_INT, &tmp_var, 5);
-    if(ret) {
-        unifi_error(priv,"store_ap_advanced_config_from_string: WMM not found\n");
-        return -1;
-    }
-    ap_mac_config->wmmEnabled = tmp_var;
-    ret = decode_parameter_from_string(priv, &str_ptr, "PHY=",
-                                        PARAM_TYPE_STRING, phy_mode, 5);
-    if(ret) {
-        unifi_error(priv,"store_ap_advanced_config_from_string: PHY not found\n");
-    } else {
-       if(strstr(phy_mode,"b")){
-           ap_mac_config->phySupportedBitmap = CSR_WIFI_SME_AP_PHY_SUPPORT_B;
-       }
-       if(strstr(phy_mode,"g")) {
-           ap_mac_config->phySupportedBitmap |= CSR_WIFI_SME_AP_PHY_SUPPORT_G;
-       }
-       if(strstr(phy_mode,"n")) {
-           ap_mac_config->phySupportedBitmap |= CSR_WIFI_SME_AP_PHY_SUPPORT_N;
-       }
-       ap_mac_config->supportedRatesCount =
-       uf_configure_supported_rates(ap_mac_config->supportedRates, ap_mac_config->phySupportedBitmap);
-    }
-    return ret;
-}
-
-static int store_ap_config_from_string( unifi_priv_t * priv,char *param_str)
-
-{
-    char *str_ptr = param_str;
-    char sub_cmd[16];
-    char sec[CSR_WIFI_MAX_SEC_LEN];
-    char key[CSR_WIFI_MAX_KEY_LEN];
-    int ret = 0,tmp_var;
-    CsrWifiSmeApConfig_t *ap_config = &priv->ap_config;
-    CsrWifiSmeApMacConfig * ap_mac_config = &priv->ap_mac_config;
-    memset(sub_cmd, 0, sizeof(sub_cmd));
-    if(!strstr(param_str,"END")) {
-        unifi_error(priv,"store_ap_config_from_string:Invalid config string:%s\n",param_str);
-        return -1;
-    }
-    if (decode_parameter_from_string(priv,&str_ptr, "ASCII_CMD=",
-        PARAM_TYPE_STRING, sub_cmd, 6) != 0) {
-         return -1;
-    }
-    if (strncmp(sub_cmd, "AP_CFG", 6)) {
-
-        if(!strncmp(sub_cmd ,"ADVCFG", 6)) {
-           return store_ap_advanced_config_from_string(priv, str_ptr);
-        }
-        unifi_error(priv,"store_ap_config_from_string: sub_cmd:%s != 'AP_CFG or ADVCFG'!\n", sub_cmd);
-        return -1;
-    }
-    memset(ap_config, 0, sizeof(CsrWifiSmeApConfig_t));
-    ret = decode_parameter_from_string(priv,&str_ptr, "SSID=",
-                                       PARAM_TYPE_STRING, ap_config->ssid.ssid,
-                                       CSR_WIFI_MAX_SSID_LEN);
-    if(ret) {
-        unifi_error(priv,"store_ap_config_from_string: SSID not found\n");
-        return -1;
-    }
-    ap_config->ssid.length = strlen(ap_config->ssid.ssid);
-
-    ret = decode_parameter_from_string(priv, &str_ptr, "SEC=",
-                                       PARAM_TYPE_STRING, sec, CSR_WIFI_MAX_SEC_LEN);
-    if(ret) {
-        unifi_error(priv,"store_ap_config_from_string: SEC not found\n");
-        return -1;
-    }
-    ret = decode_parameter_from_string(priv,&str_ptr, "KEY=",
-                         PARAM_TYPE_STRING,  key, CSR_WIFI_MAX_KEY_LEN);
-    if(!strcasecmp(sec,"open")) {
-        unifi_trace(priv,UDBG2,"store_ap_config_from_string: security open");
-        ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM;
-        if(ret) {
-            unifi_notice(priv,"store_ap_config_from_string: KEY not found:fine with Open\n");
-        }
-    }
-    else if(!strcasecmp(sec,"wpa2-psk")) {
-        int i,j=0;
-        CsrWifiNmeApAuthPers *pers =
-                            ((CsrWifiNmeApAuthPers *)&(ap_config->credentials.nmeAuthType.authTypePersonal));
-        u8 *psk = pers->authPers_credentials.psk.psk;
-
-        unifi_trace(priv,UDBG2,"store_ap_config_from_string: security WPA2");
-        if(ret) {
-            unifi_error(priv,"store_ap_config_from_string: KEY not found for WPA2\n");
-            return -1;
-        }
-        ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL;
-        pers->authSupport = CSR_WIFI_SME_RSN_AUTH_WPA2PSK;
-        pers->rsnCapabilities =0;
-        pers->wapiCapabilities =0;
-        pers->pskOrPassphrase=CSR_WIFI_NME_AP_CREDENTIAL_TYPE_PSK;
-        pers->authPers_credentials.psk.encryptionMode =
-                 (CSR_WIFI_NME_ENCRYPTION_CIPHER_PAIRWISE_CCMP |CSR_WIFI_NME_ENCRYPTION_CIPHER_GROUP_CCMP) ;
-        for(i=0;i<32;i++){
-           psk[i] = (16*hex_look_up(key[j]))+hex_look_up(key[j+1]);
-           j+=2;
-        }
-
-    } else {
-       unifi_notice(priv,"store_ap_config_from_string: Unknown security: Assuming Open");
-       ap_config->credentials.authType = CSR_WIFI_SME_AP_AUTH_TYPE_OPEN_SYSTEM;
-       return -1;
-    }
-   /* Get the decoded value in a temp int variable to ensure that other fields within the struct
-      which are of type other than int are not over written */
-    ret = decode_parameter_from_string(priv,&str_ptr, "CHANNEL=", PARAM_TYPE_INT, &tmp_var, 5);
-    if(ret)
-        return -1;
-    ap_config->channel = tmp_var;
-    ret = decode_parameter_from_string(priv,&str_ptr, "PREAMBLE=", PARAM_TYPE_INT, &tmp_var, 5);
-    if(ret)
-        return -1;
-    ap_mac_config->preamble = tmp_var;
-    ret = decode_parameter_from_string(priv,&str_ptr, "MAX_SCB=", PARAM_TYPE_INT,  &tmp_var, 5);
-    ap_config->max_connections = tmp_var;
-    return ret;
-}
-
-static int
-iwprivsapstart(struct net_device *dev, struct iw_request_info *info,
-               union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int r;
-
-    unifi_trace(priv, UDBG1, "iwprivsapstart\n" );
-    r = sme_ap_start(priv,interfacePriv->InterfaceTag,&priv->ap_config);
-    if(r) {
-        unifi_error(priv,"iwprivsapstart AP START failed : %d\n",-r);
-    }
-    return r;
-}
-
-static int
-iwprivsapconfig(struct net_device *dev, struct iw_request_info *info,
-                union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    char  *cfg_str = NULL;
-    int r;
-
-    unifi_trace(priv, UDBG1, "iwprivsapconfig\n" );
-    if (wrqu->data.length != 0) {
-        char *str;
-        if (!(cfg_str = kmalloc(wrqu->data.length+1, GFP_KERNEL)))
-        {
-            return -ENOMEM;
-        }
-        if (copy_from_user(cfg_str, wrqu->data.pointer, wrqu->data.length)) {
-            kfree(cfg_str);
-            return -EFAULT;
-        }
-        cfg_str[wrqu->data.length] = 0;
-        unifi_trace(priv,UDBG2,"length:%d\n",wrqu->data.length);
-        unifi_trace(priv,UDBG2,"AP configuration string:%s\n",cfg_str);
-        str = cfg_str;
-       if ((r = store_ap_config_from_string(priv,str))) {
-           unifi_error(priv, "iwprivsapconfig:Failed  to decode the string %d\n",r);
-           kfree(cfg_str);
-           return -EIO;
-
-       }
-    } else {
-        unifi_error(priv,"iwprivsapconfig argument length = 0 \n");
-        return -EIO;
-    }
-    r = sme_ap_config(priv, &priv->ap_mac_config, &priv->group_sec_config);
-    if(r) {
-        unifi_error(priv,"iwprivsapstop AP Config failed : %d\n",-r);
-    } else if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-        interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-        unifi_trace(priv, UDBG1, "iwprivsapconfig: Starting the AP");
-        r = sme_ap_start(priv,interfacePriv->InterfaceTag,&priv->ap_config);
-        if(r) {
-            unifi_error(priv,"iwprivsapstart AP START failed : %d\n",-r);
-        }
-    }
-    kfree(cfg_str);
-    return r;
-}
-
-static int
-iwprivsapstop(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int r;
-    u16 interface_tag = interfacePriv->InterfaceTag;
-
-    unifi_trace(priv, UDBG1, "iwprivsapstop\n" );
-    r = sme_ap_stop(priv,interface_tag);
-    if(r) {
-        unifi_error(priv,"iwprivsapstop AP STOP failed : %d\n",-r);
-    }
-    return r;
-}
-
-#ifdef ANDROID_BUILD
-static int
-iwprivsapfwreload(struct net_device *dev, struct iw_request_info *info,
-                  union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    unifi_trace(priv, UDBG1, "iwprivsapfwreload\n" );
-    return 0;
-}
-
-static int
-iwprivsstackstart(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    unifi_trace(priv, UDBG1, "iwprivsstackstart\n" );
-    return 0;
-}
-
-static int
-iwprivsstackstop(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int r = 0;
-    u16 interface_tag = interfacePriv->InterfaceTag;
-
-    unifi_trace(priv, UDBG1, "iwprivsstackstop\n" );
-
-    switch(interfacePriv->interfaceMode) {
-        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-            r = sme_mgt_disconnect(priv);
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            r = sme_ap_stop(priv,interface_tag);
-            break;
-        default :
-            break;
-    }
-
-    if(r) {
-        unifi_error(priv,"iwprivsstackstop Stack stop failed : %d\n",-r);
-    }
-    return 0;
-}
-#endif /* ANDROID_BUILD */
-#endif /* CSR_SUPPORT_WEXT_AP */
-
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-static int
-iwprivsconfwapi(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    u8 enable;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    unifi_trace(priv, UDBG1, "iwprivsconfwapi\n" );
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "iwprivsconfwapi: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-    enable = *(u8*)(extra);
-
-    if (enable) {
-        priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
-        priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK | CSR_WIFI_SME_AUTH_MODE_WAPI_WAI);
-        priv->connection_config.encryptionModeMask |=
-            CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4;
-    } else {
-        priv->connection_config.authModeMask &= ~(CSR_WIFI_SME_AUTH_MODE_WAPI_WAIPSK | CSR_WIFI_SME_AUTH_MODE_WAPI_WAI);
-        priv->connection_config.encryptionModeMask &=
-            ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4);
-    }
-
-    return 0;
-}
-
-static int
-iwprivswpikey(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    int r = 0, i;
-    CsrWifiSmeKey key;
-    unifiio_wapi_key_t inKey;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    unifi_trace(priv, UDBG1, "iwprivswpikey\n" );
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "iwprivswpikey: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-    inKey = *(unifiio_wapi_key_t*)(extra);
-
-    if (inKey.unicastKey) {
-        key.keyType   = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;
-    } else {
-        key.keyType   = CSR_WIFI_SME_KEY_TYPE_GROUP;
-    }
-
-    key.keyIndex  = inKey.keyIndex;
-
-    /* memcpy(key.keyRsc, inKey.keyRsc, 16); */
-    for (i = 0; i < 16; i+= 2)
-    {
-        key.keyRsc[i/2] = inKey.keyRsc[i+1] << 8 | inKey.keyRsc[i];
-    }
-
-    memcpy(key.address.a, inKey.address, 6);
-    key.keyLength = 32;
-    memcpy(key.key, inKey.key, 32);
-    key.authenticator = 0;
-    key.wepTxKey = 0;
-
-    unifi_trace(priv, UDBG1, "keyType = %d, keyIndex = %d, wepTxKey = %d, keyRsc = %x:%x, auth = %d, address = %x:%x, "
-                "keylength = %d, key = %x:%x\n", key.keyType, key.keyIndex, key.wepTxKey,
-                key.keyRsc[0], key.keyRsc[7], key.authenticator,
-                key.address.a[0], key.address.a[5], key.keyLength, key.key[0],
-                key.key[15]);
-
-    r = sme_mgt_key(priv, &key, CSR_WIFI_SME_LIST_ACTION_ADD);
-    if (r) {
-        unifi_error(priv, "SETKEYS request was rejected with result %d\n", r);
-        return convert_sme_error(r);
-    }
-
-    return r;
-}
-#endif
-
-
-static int
-unifi_giwname(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    char *name = wrqu->name;
-    unifi_trace(priv, UDBG2, "unifi_giwname\n");
-
-    if (priv->if_index == CSR_INDEX_5G) {
-        strcpy(name, "IEEE 802.11-a");
-    } else {
-        strcpy(name, "IEEE 802.11-bgn");
-    }
-    return 0;
-} /* unifi_giwname() */
-
-
-static int
-unifi_siwfreq(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_freq *freq = (struct iw_freq *)wrqu;
-
-    unifi_trace(priv, UDBG2, "unifi_siwfreq\n");
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwfreq: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    /*
-     * Channel is stored in the connection configuration,
-     * and set later when ask for a connection.
-     */
-    if ((freq->e == 0) && (freq->m <= 1000)) {
-        priv->connection_config.adhocChannel = freq->m;
-    } else {
-        priv->connection_config.adhocChannel = wext_freq_to_channel(freq->m, freq->e);
-    }
-
-    return 0;
-} /* unifi_siwfreq() */
-
-
-static int
-unifi_giwfreq(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_freq *freq = (struct iw_freq *)wrqu;
-    int err = 0;
-    CsrWifiSmeConnectionInfo connectionInfo;
-
-    unifi_trace(priv, UDBG2, "unifi_giwfreq\n");
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_giwfreq: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    UF_RTNL_UNLOCK();
-    err = sme_mgt_connection_info_get(priv, &connectionInfo);
-    UF_RTNL_LOCK();
-
-    freq->m = channel_to_mhz(connectionInfo.channelNumber,
-            (connectionInfo.networkType80211 == CSR_WIFI_SME_RADIO_IF_GHZ_5_0));
-    freq->e = 6;
-
-    return convert_sme_error(err);
-} /* unifi_giwfreq() */
-
-
-static int
-unifi_siwmode(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    unifi_trace(priv, UDBG2, "unifi_siwmode\n");
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwmode: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    switch(wrqu->mode) {
-        case IW_MODE_ADHOC:
-            priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_ADHOC;
-            break;
-        case IW_MODE_INFRA:
-            priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE;
-            break;
-        case IW_MODE_AUTO:
-            priv->connection_config.bssType = CSR_WIFI_SME_BSS_TYPE_ANY_BSS;
-            break;
-        default:
-            unifi_notice(priv, "Unknown IW MODE value.\n");
-    }
-
-    /* Clear the SSID and BSSID configuration */
-    priv->connection_config.ssid.length = 0;
-    memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN);
-
-    return 0;
-} /* unifi_siwmode() */
-
-
-
-static int
-unifi_giwmode(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    int r = 0;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    CsrWifiSmeConnectionConfig connectionConfig;
-
-    unifi_trace(priv, UDBG2, "unifi_giwmode\n");
-    CHECK_INITED(priv);
-
-    unifi_trace(priv, UDBG2, "unifi_giwmode: Exisitng mode = 0x%x\n",
-                interfacePriv->interfaceMode);
-    switch(interfacePriv->interfaceMode) {
-        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-           wrqu->mode = IW_MODE_INFRA;
-           break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            wrqu->mode = IW_MODE_MASTER;
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-            wrqu->mode = IW_MODE_ADHOC;
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2P:
-        case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
-            UF_RTNL_UNLOCK();
-            r = sme_mgt_connection_config_get(priv, &connectionConfig);
-            UF_RTNL_LOCK();
-            if (r == 0) {
-                switch(connectionConfig.bssType) {
-                    case CSR_WIFI_SME_BSS_TYPE_ADHOC:
-                        wrqu->mode = IW_MODE_ADHOC;
-                        break;
-                    case CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE:
-                        wrqu->mode = IW_MODE_INFRA;
-                        break;
-                    default:
-                        wrqu->mode = IW_MODE_AUTO;
-                        unifi_notice(priv, "Unknown IW MODE value.\n");
-                }
-            }
-            break;
-        default:
-            wrqu->mode = IW_MODE_AUTO;
-            unifi_notice(priv, "Unknown IW MODE value.\n");
-
-    }
-    unifi_trace(priv, UDBG4, "unifi_giwmode: mode = 0x%x\n", wrqu->mode);
-    return r;
-} /* unifi_giwmode() */
-
-
-
-static int
-unifi_giwrange(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    struct iw_point *dwrq = &wrqu->data;
-    struct iw_range *range = (struct iw_range *) extra;
-    int i;
-
-    unifi_trace(NULL, UDBG2, "unifi_giwrange\n");
-
-    dwrq->length = sizeof(struct iw_range);
-    memset(range, 0, sizeof(*range));
-    range->min_nwid = 0x0000;
-    range->max_nwid = 0x0000;
-
-    /*
-     * Don't report the frequency/channel table, then the channel
-     * number returned elsewhere will be printed as a channel number.
-     */
-
-    /* Ranges of values reported in quality structs */
-    range->max_qual.qual  = 40;         /* Max expected qual value */
-    range->max_qual.level = -120;       /* Noise floor in dBm */
-    range->max_qual.noise = -120;       /* Noise floor in dBm */
-
-
-    /* space for IW_MAX_BITRATES (8 up to WE15, 32 later) */
-    i = 0;
-#if WIRELESS_EXT > 15
-    range->bitrate[i++] =   2 * 500000;
-    range->bitrate[i++] =   4 * 500000;
-    range->bitrate[i++] =  11 * 500000;
-    range->bitrate[i++] =  22 * 500000;
-    range->bitrate[i++] =  12 * 500000;
-    range->bitrate[i++] =  18 * 500000;
-    range->bitrate[i++] =  24 * 500000;
-    range->bitrate[i++] =  36 * 500000;
-    range->bitrate[i++] =  48 * 500000;
-    range->bitrate[i++] =  72 * 500000;
-    range->bitrate[i++] =  96 * 500000;
-    range->bitrate[i++] = 108 * 500000;
-#else
-    range->bitrate[i++] =   2 * 500000;
-    range->bitrate[i++] =   4 * 500000;
-    range->bitrate[i++] =  11 * 500000;
-    range->bitrate[i++] =  22 * 500000;
-    range->bitrate[i++] =  24 * 500000;
-    range->bitrate[i++] =  48 * 500000;
-    range->bitrate[i++] =  96 * 500000;
-    range->bitrate[i++] = 108 * 500000;
-#endif /* WIRELESS_EXT < 16 */
-    range->num_bitrates = i;
-
-    range->max_encoding_tokens = NUM_WEPKEYS;
-    range->num_encoding_sizes = 2;
-    range->encoding_size[0] = 5;
-    range->encoding_size[1] = 13;
-
-    range->we_version_source = 20;
-    range->we_version_compiled = WIRELESS_EXT;
-
-    /* Number of channels available in h/w */
-    range->num_channels = 14;
-    /* Number of entries in freq[] array */
-    range->num_frequency = 14;
-    for (i = 0; (i < range->num_frequency) && (i < IW_MAX_FREQUENCIES); i++) {
-        int chan = i + 1;
-        range->freq[i].i = chan;
-        range->freq[i].m = channel_to_mhz(chan, 0);
-        range->freq[i].e = 6;
-    }
-    if ((i+3) < IW_MAX_FREQUENCIES) {
-        range->freq[i].i = 36;
-        range->freq[i].m = channel_to_mhz(36, 1);
-        range->freq[i].e = 6;
-        range->freq[i+1].i = 40;
-        range->freq[i+1].m = channel_to_mhz(40, 1);
-        range->freq[i+1].e = 6;
-        range->freq[i+2].i = 44;
-        range->freq[i+2].m = channel_to_mhz(44, 1);
-        range->freq[i+2].e = 6;
-        range->freq[i+3].i = 48;
-        range->freq[i+3].m = channel_to_mhz(48, 1);
-        range->freq[i+3].e = 6;
-    }
-
-#if WIRELESS_EXT > 16
-    /* Event capability (kernel + driver) */
-    range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
-            IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
-            IW_EVENT_CAPA_MASK(SIOCGIWAP) |
-            IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
-    range->event_capa[1] = IW_EVENT_CAPA_K_1;
-    range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
-            IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
-            IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
-            IW_EVENT_CAPA_MASK(IWEVEXPIRED));
-#endif /* WIRELESS_EXT > 16 */
-
-#if WIRELESS_EXT > 17
-    range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-        IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-#endif /* WIRELESS_EXT > 17 */
-
-
-    return 0;
-} /* unifi_giwrange() */
-
-
-static int
-unifi_siwap(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int err = 0;
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwap: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) {
-        return -EINVAL;
-    }
-
-	unifi_trace(priv, UDBG1, "unifi_siwap: asked for %pM\n",
-		wrqu->ap_addr.sa_data);
-
-    if (is_zero_ether_addr(wrqu->ap_addr.sa_data)) {
-        priv->ignore_bssid_join = FALSE;
-        err = sme_mgt_disconnect(priv);
-        if (err) {
-            unifi_trace(priv, UDBG4, "unifi_siwap: Disconnect failed, status %d\n", err);
-        }
-        return 0;
-    }
-
-    if (priv->ignore_bssid_join) {
-        unifi_trace(priv, UDBG4, "unifi_siwap: ignoring second join\n");
-        priv->ignore_bssid_join = FALSE;
-    } else {
-        memcpy(priv->connection_config.bssid.a, wrqu->ap_addr.sa_data, ETH_ALEN);
-        unifi_trace(priv, UDBG1, "unifi_siwap: Joining %X:%X:%X:%X:%X:%X\n",
-                    priv->connection_config.bssid.a[0],
-                    priv->connection_config.bssid.a[1],
-                    priv->connection_config.bssid.a[2],
-                    priv->connection_config.bssid.a[3],
-                    priv->connection_config.bssid.a[4],
-                    priv->connection_config.bssid.a[5]);
-        err = sme_mgt_connect(priv);
-        if (err) {
-            unifi_error(priv, "unifi_siwap: Join failed, status %d\n", err);
-            return convert_sme_error(err);
-        }
-    }
-
-    return 0;
-} /* unifi_siwap() */
-
-
-static int
-unifi_giwap(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    CsrWifiSmeConnectionInfo connectionInfo;
-    int r = 0;
-    u8 *bssid;
-
-    CHECK_INITED(priv);
-    unifi_trace(priv, UDBG2, "unifi_giwap\n");
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "iwprivswpikey: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_connection_info_get(priv, &connectionInfo);
-    UF_RTNL_LOCK();
-
-    if (r == 0) {
-        bssid = connectionInfo.bssid.a;
-        wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-		unifi_trace(priv, UDBG4, "unifi_giwap: BSSID = %pM\n", bssid);
-
-        memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN);
-    } else {
-        memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
-    }
-
-    return 0;
-} /* unifi_giwap() */
-
-
-static int
-unifi_siwscan(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int r;
-    CsrWifiSsid scan_ssid;
-    unsigned char *channel_list = NULL;
-    int chans_good = 0;
-#if WIRELESS_EXT > 17
-    struct iw_point *data = &wrqu->data;
-    struct iw_scan_req *req = (struct iw_scan_req *) extra;
-#endif
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwscan: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-#if WIRELESS_EXT > 17
-    /* Providing a valid channel list will force an active scan */
-    if (req) {
-        if ((req->num_channels > 0) && (req->num_channels < IW_MAX_FREQUENCIES)) {
-            channel_list = kmalloc(req->num_channels, GFP_KERNEL);
-            if (channel_list) {
-                int i;
-                for (i = 0; i < req->num_channels; i++) {
-                    /* Convert frequency to channel number */
-                    int ch = wext_freq_to_channel(req->channel_list[i].m,
-                            req->channel_list[i].e);
-                    if (ch) {
-                        channel_list[chans_good++] = ch;
-                    }
-                }
-                unifi_trace(priv, UDBG1,
-                            "SIWSCAN: Scanning %d channels\n", chans_good);
-            } else {
-                /* Fall back to scanning all */
-                unifi_error(priv, "SIWSCAN: Can't alloc channel_list (%d)\n",
-                        req->num_channels);
-            }
-        }
-    }
-
-    if (req && (data->flags & IW_SCAN_THIS_ESSID)) {
-        memcpy(scan_ssid.ssid, req->essid, req->essid_len);
-        scan_ssid.length = req->essid_len;
-        unifi_trace(priv, UDBG1,
-                    "SIWSCAN: Scanning for %.*s\n",
-                    scan_ssid.length, scan_ssid.ssid);
-    } else
-#endif
-    {
-        unifi_trace(priv, UDBG1, "SIWSCAN: Scanning for all APs\n");
-        scan_ssid.length = 0;
-    }
-
-    r = sme_mgt_scan_full(priv, &scan_ssid, chans_good, channel_list);
-    if (r) {
-        unifi_error(priv, "SIWSCAN: Scan returned error %d\n", r);
-    } else {
-        unifi_trace(priv, UDBG1, "SIWSCAN: Scan done\n");
-        wext_send_scan_results_event(priv);
-    }
-
-    if (channel_list) {
-        kfree(channel_list);
-    }
-
-    return r;
-
-} /* unifi_siwscan() */
-
-
-static const unsigned char *
-unifi_find_info_element(int id, const unsigned char *info, int len)
-{
-    const unsigned char *ie = info;
-
-    while (len > 1)
-    {
-        int e_id, e_len;
-        e_id = ie[0];
-        e_len = ie[1];
-
-        /* Return if we find a match */
-        if (e_id == id)
-        {
-            return ie;
-        }
-
-        len -= (e_len + 2);
-        ie  += (e_len + 2);
-    }
-
-    return NULL;
-} /* unifi_find_info_element() */
-
-
-/*
- * Translate scan data returned from the card to a card independent
- * format that the Wireless Tools will understand - Jean II
- */
-int
-unifi_translate_scan(struct net_device *dev,
-                     struct iw_request_info *info,
-                     char *current_ev, char *end_buf,
-                     CsrWifiSmeScanResult *scan_data,
-                     int scan_index)
-{
-    struct iw_event iwe;                /* Temporary buffer */
-    unsigned char *info_elems;
-    int info_elem_len;
-    const unsigned char *elem;
-    u16 capabilities;
-    int signal, noise, snr;
-    char *start_buf = current_ev;
-    char *current_val;  /* For rates */
-    int i, r;
-
-    info_elems    = scan_data->informationElements;
-    info_elem_len = scan_data->informationElementsLength;
-
-    if (!scan_data->informationElementsLength || !scan_data->informationElements) {
-        unifi_error(NULL, "*** NULL SCAN IEs ***\n");
-        return -EIO;
-    }
-
-    /* get capinfo bits */
-    capabilities = scan_data->capabilityInformation;
-
-    unifi_trace(NULL, UDBG5, "Capabilities: 0x%x\n", capabilities);
-
-    /* First entry *MUST* be the AP MAC address */
-    memset(&iwe, 0, sizeof(iwe));
-    iwe.cmd = SIOCGIWAP;
-    iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-    memcpy(iwe.u.ap_addr.sa_data, scan_data->bssid.a, ETH_ALEN);
-    iwe.len = IW_EV_ADDR_LEN;
-    r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_ADDR_LEN);
-    if (r < 0) {
-        return r;
-    }
-    start_buf += r;
-
-    /* Other entries will be displayed in the order we give them */
-
-    /* Add the ESSID */
-    /* find SSID in Info Elems */
-    elem = unifi_find_info_element(IE_SSID_ID, info_elems, info_elem_len);
-    if (elem) {
-        int e_len = elem[1];
-        const unsigned char *e_ptr = elem + 2;
-        unsigned char buf[33];
-
-        memset(&iwe, 0, sizeof(iwe));
-        iwe.cmd = SIOCGIWESSID;
-        iwe.u.essid.length = e_len;
-        if (iwe.u.essid.length > 32) {
-            iwe.u.essid.length = 32;
-        }
-        iwe.u.essid.flags = scan_index;
-        memcpy(buf, e_ptr, iwe.u.essid.length);
-        buf[iwe.u.essid.length] = '\0';
-        r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, buf);
-        if (r < 0) {
-            return r;
-        }
-        start_buf += r;
-
-    }
-
-    /* Add mode */
-    memset(&iwe, 0, sizeof(iwe));
-    iwe.cmd = SIOCGIWMODE;
-    if (scan_data->bssType == CSR_WIFI_SME_BSS_TYPE_INFRASTRUCTURE) {
-        iwe.u.mode = IW_MODE_INFRA;
-    } else {
-        iwe.u.mode = IW_MODE_ADHOC;
-    }
-    iwe.len = IW_EV_UINT_LEN;
-    r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_UINT_LEN);
-    if (r < 0) {
-        return r;
-    }
-    start_buf += r;
-
-    /* Add frequency. iwlist will convert to channel using table given in giwrange */
-    memset(&iwe, 0, sizeof(iwe));
-    iwe.cmd = SIOCGIWFREQ;
-    iwe.u.freq.m = scan_data->channelFrequency;
-    iwe.u.freq.e = 6;
-    r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_FREQ_LEN);
-    if (r < 0) {
-        return r;
-    }
-    start_buf += r;
-
-
-    /* Add quality statistics */
-    iwe.cmd = IWEVQUAL;
-    /*
-     * level and noise below are mapped into an unsigned 8 bit number,
-     * ranging from [-192; 63]. The way this is achieved is simply to
-     * add 0x100 onto the number if it is negative,
-     * once clipped to the correct range.
-     */
-    signal = scan_data->rssi; /* This value is in dBm */
-    /* Clip range of snr */
-    snr    = (scan_data->snr > 0) ? scan_data->snr : 0; /* In dB relative, from 0 - 255 */
-    snr    = (snr < 255) ? snr : 255;
-    noise  = signal - snr;
-
-    /* Clip range of signal */
-    signal = (signal < 63) ? signal : 63;
-    signal = (signal > -192) ? signal : -192;
-
-    /* Clip range of noise */
-    noise = (noise < 63) ? noise : 63;
-    noise = (noise > -192) ? noise : -192;
-
-    /* Make u8 */
-    signal = ( signal < 0 ) ? signal + 0x100 : signal;
-    noise = ( noise < 0 ) ? noise + 0x100 : noise;
-
-    iwe.u.qual.level = (u8)signal; /* -192 : 63 */
-    iwe.u.qual.noise = (u8)noise;  /* -192 : 63 */
-    iwe.u.qual.qual = snr;         /* 0 : 255 */
-    iwe.u.qual.updated = 0;
-#if WIRELESS_EXT > 16
-    iwe.u.qual.updated |= IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED |
-        IW_QUAL_QUAL_UPDATED;
-#if WIRELESS_EXT > 18
-    iwe.u.qual.updated |= IW_QUAL_DBM;
-#endif
-#endif
-    r = uf_iwe_stream_add_event(info, start_buf, end_buf, &iwe, IW_EV_QUAL_LEN);
-    if (r < 0) {
-        return r;
-    }
-    start_buf += r;
-
-    /* Add encryption capability */
-    iwe.cmd = SIOCGIWENCODE;
-    if (capabilities & SIG_CAP_PRIVACY) {
-        iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-    } else {
-        iwe.u.data.flags = IW_ENCODE_DISABLED;
-    }
-    iwe.u.data.length = 0;
-    iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
-    r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, "");
-    if (r < 0) {
-        return r;
-    }
-    start_buf += r;
-
-
-    /*
-     * Rate : stuffing multiple values in a single event require a bit
-     * more of magic - Jean II
-     */
-    current_val = start_buf + IW_EV_LCP_LEN;
-
-    iwe.cmd = SIOCGIWRATE;
-    /* Those two flags are ignored... */
-    iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
-    elem = unifi_find_info_element(IE_SUPPORTED_RATES_ID,
-            info_elems, info_elem_len);
-    if (elem) {
-        int e_len = elem[1];
-        const unsigned char *e_ptr = elem + 2;
-
-        /*
-         * Count how many rates we have.
-         * Zero marks the end of the list, if the list is not truncated.
-         */
-        /* Max 8 values */
-        for (i = 0; i < e_len; i++) {
-            if (e_ptr[i] == 0) {
-                break;
-            }
-            /* Bit rate given in 500 kb/s units (+ 0x80) */
-            iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
-            /* Add new value to event */
-            r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
-            if (r < 0) {
-                return r;
-            }
-            current_val +=r;
-
-        }
-    }
-    elem = unifi_find_info_element(IE_EXTENDED_SUPPORTED_RATES_ID,
-            info_elems, info_elem_len);
-    if (elem) {
-        int e_len = elem[1];
-        const unsigned char *e_ptr = elem + 2;
-
-        /*
-         * Count how many rates we have.
-         * Zero marks the end of the list, if the list is not truncated.
-         */
-        /* Max 8 values */
-        for (i = 0; i < e_len; i++) {
-            if (e_ptr[i] == 0) {
-                break;
-            }
-            /* Bit rate given in 500 kb/s units (+ 0x80) */
-            iwe.u.bitrate.value = ((e_ptr[i] & 0x7f) * 500000);
-            /* Add new value to event */
-            r = uf_iwe_stream_add_value(info, start_buf, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
-            if (r < 0) {
-                return r;
-            }
-            current_val +=r;
-        }
-    }
-    /* Check if we added any rates event */
-    if ((current_val - start_buf) > IW_EV_LCP_LEN) {
-        start_buf = current_val;
-    }
-
-
-#if WIRELESS_EXT > 17
-    memset(&iwe, 0, sizeof(iwe));
-    iwe.cmd = IWEVGENIE;
-    iwe.u.data.length = info_elem_len;
-
-    r = uf_iwe_stream_add_point(info, start_buf, end_buf, &iwe, info_elems);
-    if (r < 0) {
-        return r;
-    }
-
-    start_buf += r;
-#endif /* WE > 17 */
-
-    return (start_buf - current_ev);
-} /* unifi_translate_scan() */
-
-
-
-static int
-unifi_giwscan(struct net_device *dev, struct iw_request_info *info,
-              union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_point *dwrq = &wrqu->data;
-    int r;
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_giwscan: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    unifi_trace(priv, UDBG1,
-            "unifi_giwscan: buffer (%d bytes) \n",
-            dwrq->length);
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_scan_results_get_async(priv, info, extra, dwrq->length);
-    UF_RTNL_LOCK();
-    if (r < 0) {
-        unifi_trace(priv, UDBG1,
-                "unifi_giwscan: buffer (%d bytes) not big enough.\n",
-                dwrq->length);
-        return r;
-    }
-
-    dwrq->length = r;
-    dwrq->flags = 0;
-
-    return 0;
-} /* unifi_giwscan() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_siwessid
- *
- *      Request to join a network or start and AdHoc.
- *
- *  Arguments:
- *      dev             Pointer to network device struct.
- *      info            Pointer to broken-out ioctl request.
- *      data            Pointer to argument data.
- *      essid           Pointer to string giving name of network to join
- *                      or start
- *
- *  Returns:
- *      0 on success and everything complete
- *      -EINPROGRESS to have the higher level call the commit method.
- * ---------------------------------------------------------------------------
- */
-static int
-unifi_siwessid(struct net_device *dev, struct iw_request_info *info,
-               struct iw_point *data, char *essid)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int len;
-    int err = 0;
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwessid: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    len = 0;
-    if (data->flags & 1) {
-        /* Limit length  */
-        len = data->length;
-        if (len > UNIFI_MAX_SSID_LEN) {
-            len = UNIFI_MAX_SSID_LEN;
-        }
-    }
-
-#ifdef UNIFI_DEBUG
-    {
-        char essid_str[UNIFI_MAX_SSID_LEN+1];
-        int i;
-
-        for (i = 0; i < len; i++) {
-            essid_str[i] = (isprint(essid[i]) ? essid[i] : '?');
-        }
-        essid_str[i] = '\0';
-
-        unifi_trace(priv, UDBG1, "unifi_siwessid: asked for '%*s' (%d)\n", len, essid_str, len);
-        unifi_trace(priv, UDBG2, " with authModeMask = %d", priv->connection_config.authModeMask);
-    }
-#endif
-
-    memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN);
-    if (len) {
-        if (essid[len - 1] == 0) {
-            len --;
-        }
-
-        memcpy(priv->connection_config.ssid.ssid, essid, len);
-        priv->connection_config.ssid.length = len;
-
-    } else {
-        priv->connection_config.ssid.length = 0;
-    }
-
-    UF_RTNL_UNLOCK();
-    err = sme_mgt_connect(priv);
-    UF_RTNL_LOCK();
-    if (err) {
-        unifi_error(priv, "unifi_siwessid: Join failed, status %d\n", err);
-        return convert_sme_error(err);
-    }
-
-    return 0;
-} /* unifi_siwessid() */
-
-
-static int
-unifi_giwessid(struct net_device *dev, struct iw_request_info *info,
-               union iwreq_data *wrqu, char *essid)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_point *data = &wrqu->essid;
-    CsrWifiSmeConnectionInfo connectionInfo;
-    int r = 0;
-
-    unifi_trace(priv, UDBG2, "unifi_giwessid\n");
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_giwessid: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_connection_info_get(priv, &connectionInfo);
-    UF_RTNL_LOCK();
-
-    if (r == 0) {
-        data->length = connectionInfo.ssid.length;
-        strncpy(essid,
-                connectionInfo.ssid.ssid,
-                data->length);
-        data->flags = 1;            /* active */
-
-        unifi_trace(priv, UDBG2, "unifi_giwessid: %.*s\n",
-                data->length, essid);
-    }
-
-
-    return 0;
-} /* unifi_giwessid() */
-
-
-static int
-unifi_siwrate(struct net_device *dev, struct iw_request_info *info,
-              union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_param *args = &wrqu->bitrate;
-    CsrWifiSmeMibConfig mibConfig;
-    int r;
-
-    CHECK_INITED(priv);
-    unifi_trace(priv, UDBG2, "unifi_siwrate\n");
-
-    /*
-     * If args->fixed == 0, value is max rate or -1 for best
-     * If args->fixed == 1, value is rate to set or -1 for best
-     * args->disabled and args->flags are not used in SIOCSIWRATE
-     */
-
-    /* Get, modify and set the MIB data */
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_mib_config_get(priv, &mibConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_siwrate: Get CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-
-    /* Default to auto rate algorithm */
-    /* in 500Kbit/s, 0 means auto */
-    mibConfig.unifiFixTxDataRate = 0;
-
-    if (args->value != -1) {
-        mibConfig.unifiFixTxDataRate = args->value / 500000;
-    }
-
-    /* 1 means rate is a maximum, 2 means rate is a set value */
-    if (args->fixed == 1) {
-        mibConfig.unifiFixMaxTxDataRate = 0;
-    } else {
-        mibConfig.unifiFixMaxTxDataRate = 1;
-    }
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_mib_config_set(priv, &mibConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_siwrate: Set CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-
-
-    return 0;
-} /* unifi_siwrate() */
-
-
-
-static int
-unifi_giwrate(struct net_device *dev, struct iw_request_info *info,
-              union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_param *args = &wrqu->bitrate;
-    int r;
-    int bitrate, flag;
-    CsrWifiSmeMibConfig mibConfig;
-    CsrWifiSmeConnectionStats connectionStats;
-
-    unifi_trace(priv, UDBG2, "unifi_giwrate\n");
-    CHECK_INITED(priv);
-
-    flag = 0;
-    bitrate = 0;
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_mib_config_get(priv, &mibConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_giwrate: Get CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-
-    bitrate = mibConfig.unifiFixTxDataRate;
-    flag = mibConfig.unifiFixMaxTxDataRate;
-
-    /* Used the value returned by the SME if MIB returns 0 */
-    if (bitrate == 0) {
-        UF_RTNL_UNLOCK();
-        r = sme_mgt_connection_stats_get(priv, &connectionStats);
-        UF_RTNL_LOCK();
-        /* Ignore errors, we may be disconnected */
-        if (r == 0) {
-            bitrate = connectionStats.unifiTxDataRate;
-        }
-    }
-
-    args->value = bitrate * 500000;
-    args->fixed = !flag;
-
-    return 0;
-} /* unifi_giwrate() */
-
-
-static int
-unifi_siwrts(struct net_device *dev, struct iw_request_info *info,
-             union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int val = wrqu->rts.value;
-    int r = 0;
-    CsrWifiSmeMibConfig mibConfig;
-
-    unifi_trace(priv, UDBG2, "unifi_siwrts\n");
-    CHECK_INITED(priv);
-
-    if (wrqu->rts.disabled) {
-        val = 2347;
-    }
-
-    if ( (val < 0) || (val > 2347) )
-    {
-        return -EINVAL;
-    }
-
-    /* Get, modify and set the MIB data */
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_mib_config_get(priv, &mibConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_siwrts: Get CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-    mibConfig.dot11RtsThreshold = val;
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_mib_config_set(priv, &mibConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_siwrts: Set CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-
-    return 0;
-}
-
-
-static int
-unifi_giwrts(struct net_device *dev, struct iw_request_info *info,
-             union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int r;
-    int rts_thresh;
-    CsrWifiSmeMibConfig mibConfig;
-
-    unifi_trace(priv, UDBG2, "unifi_giwrts\n");
-    CHECK_INITED(priv);
-
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_mib_config_get(priv, &mibConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_giwrts: Get CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-
-    rts_thresh = mibConfig.dot11RtsThreshold;
-    if (rts_thresh > 2347) {
-        rts_thresh = 2347;
-    }
-
-    wrqu->rts.value = rts_thresh;
-    wrqu->rts.disabled = (rts_thresh == 2347);
-    wrqu->rts.fixed = 1;
-
-    return 0;
-}
-
-
-static int
-unifi_siwfrag(struct net_device *dev, struct iw_request_info *info,
-              union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int val = wrqu->frag.value;
-    int r = 0;
-    CsrWifiSmeMibConfig mibConfig;
-
-    unifi_trace(priv, UDBG2, "unifi_siwfrag\n");
-    CHECK_INITED(priv);
-
-    if (wrqu->frag.disabled)
-        val = 2346;
-
-    if ( (val < 256) || (val > 2347) )
-        return -EINVAL;
-
-    /* Get, modify and set the MIB data */
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_mib_config_get(priv, &mibConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_siwfrag: Get CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-    /* Fragmentation Threashold must be even */
-    mibConfig.dot11FragmentationThreshold = (val & ~0x1);
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_mib_config_set(priv, &mibConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_siwfrag: Set CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-
-    return 0;
-}
-
-
-static int
-unifi_giwfrag(struct net_device *dev, struct iw_request_info *info,
-              union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int r;
-    int frag_thresh;
-    CsrWifiSmeMibConfig mibConfig;
-
-    unifi_trace(priv, UDBG2, "unifi_giwfrag\n");
-    CHECK_INITED(priv);
-
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_mib_config_get(priv, &mibConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_giwfrag: Get CsrWifiSmeMibConfigValue failed.\n");
-        return r;
-    }
-
-    frag_thresh = mibConfig.dot11FragmentationThreshold;
-
-    /* Build the return structure */
-    wrqu->frag.value = frag_thresh;
-    wrqu->frag.disabled = (frag_thresh >= 2346);
-    wrqu->frag.fixed = 1;
-
-    return 0;
-}
-
-
-static int
-unifi_siwencode(struct net_device *dev, struct iw_request_info *info,
-                union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_point *erq = &wrqu->encoding;
-    int index;
-    int rc = 0;
-    int privacy = -1;
-    CsrWifiSmeKey sme_key;
-
-    unifi_trace(priv, UDBG2, "unifi_siwencode\n");
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwencode: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    /*
-     * Key index is encoded in the flags.
-     * 0 - use current default,
-     * 1-4 - if a key value is given set that key
-     *       if not use that key
-     */
-    index = (erq->flags & IW_ENCODE_INDEX);  /* key number, 1-4 */
-    if ((index < 0) || (index > 4)) {
-        unifi_error(priv, "unifi_siwencode: Request to set an invalid key (index:%d)", index);
-        return -EINVAL;
-    }
-
-    /*
-     * Basic checking: do we have a key to set ?
-     * The IW_ENCODE_NOKEY flag is set when no key is present (only change flags),
-     * but older versions rely on sending a key id 1-4.
-     */
-    if (erq->length > 0) {
-
-        /* Check the size of the key */
-        if ((erq->length > LARGE_KEY_SIZE) || (erq->length < SMALL_KEY_SIZE)) {
-            unifi_error(priv, "unifi_siwencode: Request to set an invalid key (length:%d)",
-                        erq->length);
-            return -EINVAL;
-        }
-
-        /* Check the index (none (i.e. 0) means use current) */
-        if ((index < 1) || (index > 4)) {
-            /* If we do not have a previous key, use 1 as default */
-            if (!priv->wep_tx_key_index) {
-                priv->wep_tx_key_index = 1;
-            }
-            index = priv->wep_tx_key_index;
-        }
-
-        /* If we didn't have a key and a valid index is set, we want to remember it*/
-        if (!priv->wep_tx_key_index) {
-            priv->wep_tx_key_index = index;
-        }
-
-        unifi_trace(priv, UDBG1, "Tx key Index is %d\n", priv->wep_tx_key_index);
-
-        privacy = 1;
-
-        /* Check if the key is not marked as invalid */
-        if ((erq->flags & IW_ENCODE_NOKEY) == 0) {
-
-            unifi_trace(priv, UDBG1, "New %s key (len=%d, index=%d)\n",
-                        (priv->wep_tx_key_index == index) ? "tx" : "",
-                        erq->length, index);
-
-            sme_key.wepTxKey = (priv->wep_tx_key_index == index);
-            if (priv->wep_tx_key_index == index) {
-                sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;
-            } else {
-                sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP;
-            }
-            /* Key index is zero based in SME but 1 based in wext */
-            sme_key.keyIndex = (index - 1);
-            sme_key.keyLength = erq->length;
-            sme_key.authenticator = 0;
-            memset(sme_key.address.a, 0xFF, ETH_ALEN);
-            memcpy(sme_key.key, extra, erq->length);
-
-            UF_RTNL_UNLOCK();
-            rc = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
-            UF_RTNL_LOCK();
-            if (rc) {
-                unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc);
-                return convert_sme_error(rc);
-            }
-
-            /* Store the key to be reported by the SIOCGIWENCODE handler */
-            priv->wep_keys[index - 1].len = erq->length;
-            memcpy(priv->wep_keys[index - 1].key, extra, erq->length);
-        }
-    } else {
-        /*
-         * No additional key data, so it must be a request to change the
-         * active key.
-         */
-        if (index != 0) {
-            unifi_trace(priv, UDBG1, "Tx key Index is %d\n", index - 1);
-
-            /* Store the index to be reported by the SIOCGIWENCODE handler */
-            priv->wep_tx_key_index = index;
-
-            sme_key.wepTxKey = 1;
-            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;
-
-            /* Key index is zero based in SME but 1 based in wext */
-            sme_key.keyIndex = (index - 1);
-            sme_key.keyLength = 0;
-            sme_key.authenticator = 0;
-            UF_RTNL_UNLOCK();
-            rc = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
-            UF_RTNL_LOCK();
-            if (rc) {
-                unifi_error(priv, "unifi_siwencode: Set key failed (%d)", rc);
-                return convert_sme_error(rc);
-            }
-
-            /* Turn on encryption */
-            privacy = 1;
-        }
-    }
-
-    /* Read the flags */
-    if (erq->flags & IW_ENCODE_DISABLED) {
-        /* disable encryption */
-        unifi_trace(priv, UDBG1, "disable WEP encryption\n");
-        privacy = 0;
-
-        priv->wep_tx_key_index = 0;
-
-        unifi_trace(priv, UDBG1, "IW_ENCODE_DISABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
-        priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
-    }
-
-    if (erq->flags & IW_ENCODE_RESTRICTED) {
-        /* Use shared key auth */
-        unifi_trace(priv, UDBG1, "IW_ENCODE_RESTRICTED: CSR_WIFI_SME_AUTH_MODE_80211_SHARED\n");
-        priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_SHARED;
-
-        /* Turn on encryption */
-        privacy = 1;
-    }
-    if (erq->flags & IW_ENCODE_OPEN) {
-        unifi_trace(priv, UDBG1, "IW_ENCODE_OPEN: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
-        priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
-    }
-
-    /* Commit the changes to flags if needed */
-    if (privacy != -1) {
-        priv->connection_config.privacyMode = privacy ? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED : CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED;
-        priv->connection_config.encryptionModeMask = privacy ? (CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 |
-                CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 |
-                CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40 |
-                CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104) :
-            CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
-    }
-
-    return convert_sme_error(rc);
-
-} /* unifi_siwencode() */
-
-
-
-static int
-unifi_giwencode(struct net_device *dev, struct iw_request_info *info,
-                union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_point *erq = &wrqu->encoding;
-
-    unifi_trace(priv, UDBG2, "unifi_giwencode\n");
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_giwencode: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    if (priv->connection_config.authModeMask == CSR_WIFI_SME_AUTH_MODE_80211_SHARED) {
-        erq->flags = IW_ENCODE_RESTRICTED;
-    }
-    else {
-        if (priv->connection_config.privacyMode == CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED) {
-            erq->flags = IW_ENCODE_DISABLED;
-        } else {
-            erq->flags = IW_ENCODE_OPEN;
-        }
-    }
-
-    erq->length = 0;
-
-    if (erq->flags != IW_ENCODE_DISABLED) {
-        int index = priv->wep_tx_key_index;
-
-        if ((index > 0) && (index <= NUM_WEPKEYS)) {
-            erq->flags |= (index & IW_ENCODE_INDEX);
-            erq->length = priv->wep_keys[index - 1].len;
-            memcpy(extra, priv->wep_keys[index - 1].key, erq->length);
-        } else {
-            unifi_notice(priv, "unifi_giwencode: Surprise, do not have a valid key index (%d)\n",
-                         index);
-        }
-    }
-
-    return 0;
-} /* unifi_giwencode() */
-
-
-static int
-unifi_siwpower(struct net_device *dev, struct iw_request_info *info,
-               union iwreq_data *wrqu, char *extra)
-{
-    struct iw_param *args = &wrqu->power;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int listen_interval, wake_for_dtim;
-    int r = 0;
-    CsrWifiSmePowerConfig powerConfig;
-
-    unifi_trace(priv, UDBG2, "unifi_siwpower\n");
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwpower: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_power_config_get(priv, &powerConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_siwpower: Get unifi_PowerConfigValue failed.\n");
-        return r;
-    }
-
-    listen_interval = -1;
-    wake_for_dtim = -1;
-    if (args->disabled) {
-        powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW;
-    }
-    else
-    {
-        powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH;
-
-        switch (args->flags & IW_POWER_TYPE) {
-            case 0:
-                /* not specified */
-                break;
-            case IW_POWER_PERIOD:
-                listen_interval = args->value / 1000;
-                break;
-            default:
-                return -EINVAL;
-        }
-
-        switch (args->flags & IW_POWER_MODE) {
-            case 0:
-                /* not specified */
-                break;
-            case IW_POWER_UNICAST_R:
-                /* not interested in broadcast packets */
-                wake_for_dtim = 0;
-                break;
-            case IW_POWER_ALL_R:
-                /* yes, we are interested in broadcast packets */
-                wake_for_dtim = 1;
-                break;
-            default:
-                return -EINVAL;
-        }
-    }
-
-    if (listen_interval > 0) {
-        powerConfig.listenIntervalTu = listen_interval;
-        unifi_trace(priv, UDBG4, "unifi_siwpower: new Listen Interval = %d.\n",
-                    powerConfig.listenIntervalTu);
-    }
-
-    if (wake_for_dtim >= 0) {
-        powerConfig.rxDtims = wake_for_dtim;
-    }
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_power_config_set(priv, &powerConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_siwpower: Set unifi_PowerConfigValue failed.\n");
-        return r;
-    }
-
-    return 0;
-} /* unifi_siwpower() */
-
-
-static int
-unifi_giwpower(struct net_device *dev, struct iw_request_info *info,
-               union iwreq_data *wrqu, char *extra)
-{
-    struct iw_param *args = &wrqu->power;
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    CsrWifiSmePowerConfig powerConfig;
-    int r;
-
-    unifi_trace(priv, UDBG2, "unifi_giwpower\n");
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_giwpower: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    args->flags = 0;
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_power_config_get(priv, &powerConfig);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "unifi_giwpower: Get unifi_PowerConfigValue failed.\n");
-        return r;
-    }
-
-    unifi_trace(priv, UDBG4, "unifi_giwpower: mode=%d\n",
-                powerConfig.powerSaveLevel);
-
-    args->disabled = (powerConfig.powerSaveLevel == CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW);
-    if (args->disabled) {
-        args->flags = 0;
-        return 0;
-    }
-
-    args->value = powerConfig.listenIntervalTu * 1000;
-    args->flags |= IW_POWER_PERIOD;
-
-    if (powerConfig.rxDtims) {
-        args->flags |= IW_POWER_ALL_R;
-    } else {
-        args->flags |= IW_POWER_UNICAST_R;
-    }
-
-    return 0;
-} /* unifi_giwpower() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_siwcommit - handler for SIOCSIWCOMMIT
- *
- *      Apply all the parameters that have been set.
- *      In practice this means:
- *       - do a scan
- *       - join a network or start an AdHoc
- *       - authenticate and associate.
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static int
-unifi_siwcommit(struct net_device *dev, struct iw_request_info *info,
-                union iwreq_data *wrqu, char *extra)
-{
-    return 0;
-} /* unifi_siwcommit() */
-
-
-
-static int
-unifi_siwmlme(struct net_device *dev, struct iw_request_info *info,
-              union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_mlme *mlme = (struct iw_mlme *)extra;
-
-    unifi_trace(priv, UDBG2, "unifi_siwmlme\n");
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwmlme: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    switch (mlme->cmd) {
-        case IW_MLME_DEAUTH:
-        case IW_MLME_DISASSOC:
-            UF_RTNL_UNLOCK();
-            sme_mgt_disconnect(priv);
-            UF_RTNL_LOCK();
-            break;
-        default:
-            return -EOPNOTSUPP;
-    }
-
-    return 0;
-} /* unifi_siwmlme() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_siwgenie
- *  unifi_giwgenie
- *
- *      WPA : Generic IEEE 802.11 information element (e.g., for WPA/RSN/WMM).
- *      Handlers for SIOCSIWGENIE, SIOCGIWGENIE - set/get generic IE
- *
- *      The host program (e.g. wpa_supplicant) uses this call to set the
- *      additional IEs to accompany the next (Associate?) request.
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- *  Notes:
- *      From wireless.h:
- *        This ioctl uses struct iw_point and data buffer that includes IE id
- *        and len fields. More than one IE may be included in the
- *        request. Setting the generic IE to empty buffer (len=0) removes the
- *        generic IE from the driver.
- * ---------------------------------------------------------------------------
- */
-static int
-unifi_siwgenie(struct net_device *dev, struct iw_request_info *info,
-               union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int len;
-
-    unifi_trace(priv, UDBG2, "unifi_siwgenie\n");
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwgenie: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    if ( priv->connection_config.mlmeAssociateReqInformationElements) {
-        kfree( priv->connection_config.mlmeAssociateReqInformationElements);
-    }
-    priv->connection_config.mlmeAssociateReqInformationElementsLength = 0;
-    priv->connection_config.mlmeAssociateReqInformationElements = NULL;
-
-    len = wrqu->data.length;
-    if (len == 0) {
-        return 0;
-    }
-
-    priv->connection_config.mlmeAssociateReqInformationElements = kmalloc(len, GFP_KERNEL);
-    if (priv->connection_config.mlmeAssociateReqInformationElements == NULL) {
-        return -ENOMEM;
-    }
-
-    priv->connection_config.mlmeAssociateReqInformationElementsLength = len;
-    memcpy( priv->connection_config.mlmeAssociateReqInformationElements, extra, len);
-
-    return 0;
-} /* unifi_siwgenie() */
-
-
-static int
-unifi_giwgenie(struct net_device *dev, struct iw_request_info *info,
-               union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    int len;
-
-    unifi_trace(priv, UDBG2, "unifi_giwgenie\n");
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_giwgenie: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    len = priv->connection_config.mlmeAssociateReqInformationElementsLength;
-
-    if (len == 0) {
-        wrqu->data.length = 0;
-        return 0;
-    }
-
-    if (wrqu->data.length < len) {
-        return -E2BIG;
-    }
-
-    wrqu->data.length = len;
-    memcpy(extra, priv->connection_config.mlmeAssociateReqInformationElements, len);
-
-    return 0;
-} /* unifi_giwgenie() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_siwauth
- *  unifi_giwauth
- *
- *      Handlers for SIOCSIWAUTH, SIOCGIWAUTH
- *      Set/get various authentication parameters.
- *
- *  Arguments:
- *
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static int
-_unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
-               union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    CsrWifiSmeAuthModeMask new_auth;
-
-    unifi_trace(priv, UDBG2, "unifi_siwauth\n");
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwauth: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    /*
-     * This ioctl is safe to call even when UniFi is powered off.
-     * wpa_supplicant calls it to test whether we support WPA.
-     */
-
-    switch (wrqu->param.flags & IW_AUTH_INDEX) {
-
-        case IW_AUTH_WPA_ENABLED:
-            unifi_trace(priv, UDBG1, "IW_AUTH_WPA_ENABLED: %d\n", wrqu->param.value);
-
-            if (wrqu->param.value == 0) {
-                unifi_trace(priv, UDBG5, "IW_AUTH_WPA_ENABLED: CSR_WIFI_SME_AUTH_MODE_80211_OPEN\n");
-                priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
-            }
-            break;
-
-        case IW_AUTH_PRIVACY_INVOKED:
-            unifi_trace(priv, UDBG1, "IW_AUTH_PRIVACY_INVOKED: %d\n", wrqu->param.value);
-
-            priv->connection_config.privacyMode = wrqu->param.value ? CSR_WIFI_SME_80211_PRIVACY_MODE_ENABLED : CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED;
-            if (wrqu->param.value == CSR_WIFI_SME_80211_PRIVACY_MODE_DISABLED)
-            {
-                priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
-            }
-            break;
-
-        case IW_AUTH_80211_AUTH_ALG:
-            /*
-               IW_AUTH_ALG_OPEN_SYSTEM      0x00000001
-               IW_AUTH_ALG_SHARED_KEY       0x00000002
-               IW_AUTH_ALG_LEAP             0x00000004
-               */
-            new_auth = 0;
-            if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM) {
-                unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_OPEN_SYSTEM)\n", wrqu->param.value);
-                new_auth |= CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
-            }
-            if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY) {
-                unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_SHARED_KEY)\n", wrqu->param.value);
-                new_auth |= CSR_WIFI_SME_AUTH_MODE_80211_SHARED;
-            }
-            if (wrqu->param.value & IW_AUTH_ALG_LEAP) {
-                /* Initial exchanges using open-system to set EAP */
-                unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: %d (IW_AUTH_ALG_LEAP)\n", wrqu->param.value);
-                new_auth |= CSR_WIFI_SME_AUTH_MODE_8021X_OTHER1X;
-            }
-            if (new_auth == 0) {
-                unifi_trace(priv, UDBG1, "IW_AUTH_80211_AUTH_ALG: invalid value %d\n",
-                        wrqu->param.value);
-                return -EINVAL;
-            } else {
-                priv->connection_config.authModeMask = new_auth;
-            }
-            break;
-
-        case IW_AUTH_WPA_VERSION:
-            unifi_trace(priv, UDBG1, "IW_AUTH_WPA_VERSION: %d\n", wrqu->param.value);
-            priv->ignore_bssid_join = TRUE;
-            /*
-               IW_AUTH_WPA_VERSION_DISABLED 0x00000001
-               IW_AUTH_WPA_VERSION_WPA      0x00000002
-               IW_AUTH_WPA_VERSION_WPA2     0x00000004
-               */
-
-            if (!(wrqu->param.value & IW_AUTH_WPA_VERSION_DISABLED)) {
-
-                priv->connection_config.authModeMask = CSR_WIFI_SME_AUTH_MODE_80211_OPEN;
-
-                if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA) {
-                    unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA, WPA-PSK\n");
-                    priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA | CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK);
-                }
-                if (wrqu->param.value & IW_AUTH_WPA_VERSION_WPA2) {
-                    unifi_trace(priv, UDBG4, "IW_AUTH_WPA_VERSION: WPA2, WPA2-PSK\n");
-                    priv->connection_config.authModeMask |= (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 | CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK);
-                }
-            }
-            break;
-
-        case IW_AUTH_CIPHER_PAIRWISE:
-            unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_PAIRWISE: %d\n", wrqu->param.value);
-            /*
-             * one of:
-             IW_AUTH_CIPHER_NONE	0x00000001
-             IW_AUTH_CIPHER_WEP40	0x00000002
-             IW_AUTH_CIPHER_TKIP	0x00000004
-             IW_AUTH_CIPHER_CCMP	0x00000008
-             IW_AUTH_CIPHER_WEP104	0x00000010
-             */
-
-            priv->connection_config.encryptionModeMask = CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE;
-
-            if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
-                priv->connection_config.encryptionModeMask |=
-                    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP40 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40;
-            }
-            if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
-                priv->connection_config.encryptionModeMask |=
-                    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_WEP104 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104;
-            }
-            if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
-                priv->connection_config.encryptionModeMask |=
-                    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_TKIP | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP;
-            }
-            if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
-                priv->connection_config.encryptionModeMask |=
-                    CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_CCMP | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP;
-            }
-
-            break;
-
-        case IW_AUTH_CIPHER_GROUP:
-            unifi_trace(priv, UDBG1, "IW_AUTH_CIPHER_GROUP: %d\n", wrqu->param.value);
-            /*
-             * Use the WPA version and the group cipher suite to set the permitted
-             * group key in the MIB. f/w uses this value to validate WPA and RSN IEs
-             * in the probe responses from the desired BSS(ID)
-             */
-
-            priv->connection_config.encryptionModeMask &= ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40 |
-                    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104 |
-                    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP |
-                    CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP);
-            if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
-                priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP40;
-            }
-            if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
-                priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_WEP104;
-            }
-            if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
-                priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_TKIP;
-            }
-            if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
-                priv->connection_config.encryptionModeMask |= CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_CCMP;
-            }
-
-            break;
-
-        case IW_AUTH_KEY_MGMT:
-            unifi_trace(priv, UDBG1, "IW_AUTH_KEY_MGMT: %d\n", wrqu->param.value);
-            /*
-               IW_AUTH_KEY_MGMT_802_1X 1
-               IW_AUTH_KEY_MGMT_PSK    2
-               */
-            if (priv->connection_config.authModeMask & (CSR_WIFI_SME_AUTH_MODE_8021X_WPA | CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK)) {
-                /* Check for explicitly set mode. */
-                if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) {
-                    priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPAPSK;
-                }
-                if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) {
-                    priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA;
-                }
-                unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA: %d\n",
-                            priv->connection_config.authModeMask);
-            }
-            if (priv->connection_config.authModeMask & (CSR_WIFI_SME_AUTH_MODE_8021X_WPA2 | CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK)) {
-                /* Check for explicitly set mode. */
-                if (wrqu->param.value == IW_AUTH_KEY_MGMT_802_1X) {
-                    priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2PSK;
-                }
-                if (wrqu->param.value == IW_AUTH_KEY_MGMT_PSK) {
-                    priv->connection_config.authModeMask &= ~CSR_WIFI_SME_AUTH_MODE_8021X_WPA2;
-                }
-                unifi_trace(priv, UDBG5, "IW_AUTH_KEY_MGMT: WPA2: %d\n",
-                            priv->connection_config.authModeMask);
-            }
-
-            break;
-        case IW_AUTH_TKIP_COUNTERMEASURES:
-            /*
-             * Set to true at the start of the 60 second backup-off period
-             * following 2 MichaelMIC failures within 60s.
-             */
-            unifi_trace(priv, UDBG1, "IW_AUTH_TKIP_COUNTERMEASURES: %d\n", wrqu->param.value);
-            break;
-
-        case IW_AUTH_DROP_UNENCRYPTED:
-            /*
-             * Set to true on init.
-             * Set to false just before associate if encryption will not be
-             * required.
-             *
-             * Note this is not the same as the 802.1X controlled port
-             */
-            unifi_trace(priv, UDBG1, "IW_AUTH_DROP_UNENCRYPTED: %d\n", wrqu->param.value);
-            break;
-
-        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-            /*
-             * This is set by wpa_supplicant to allow unencrypted EAPOL messages
-             * even if pairwise keys are set when not using WPA. IEEE 802.1X
-             * specifies that these frames are not encrypted, but WPA encrypts
-             * them when pairwise keys are in use.
-             * I think the UniFi f/w handles this decision for us.
-             */
-            unifi_trace(priv, UDBG1, "IW_AUTH_RX_UNENCRYPTED_EAPOL: %d\n", wrqu->param.value);
-            break;
-
-        case IW_AUTH_ROAMING_CONTROL:
-            unifi_trace(priv, UDBG1, "IW_AUTH_ROAMING_CONTROL: %d\n", wrqu->param.value);
-            break;
-
-        default:
-            unifi_trace(priv, UDBG1, "Unsupported auth param %d to 0x%X\n",
-                        wrqu->param.flags & IW_AUTH_INDEX,
-                        wrqu->param.value);
-            return -EOPNOTSUPP;
-    }
-
-    unifi_trace(priv, UDBG2, "authModeMask = %d", priv->connection_config.authModeMask);
-
-    return 0;
-} /* _unifi_siwauth() */
-
-
-static int
-unifi_siwauth(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    int err = 0;
-
-    UF_RTNL_UNLOCK();
-    err = _unifi_siwauth(dev, info, wrqu, extra);
-    UF_RTNL_LOCK();
-
-    return err;
-} /* unifi_siwauth() */
-
-
-static int
-unifi_giwauth(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    unifi_trace(NULL, UDBG2, "unifi_giwauth\n");
-    return -EOPNOTSUPP;
-} /* unifi_giwauth() */
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_siwencodeext
- *  unifi_giwencodeext
- *
- *      Handlers for SIOCSIWENCODEEXT, SIOCGIWENCODEEXT - set/get
- *      encoding token & mode
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      For WPA/WPA2 we don't take note of the IW_ENCODE_EXT_SET_TX_KEY flag.
- *      This flag means "use this key to encode transmissions"; we just
- *      assume only one key will be set and that is the one to use.
- * ---------------------------------------------------------------------------
- */
-static int
-_unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-    int r = 0;
-    unsigned char *keydata;
-    unsigned char tkip_key[32];
-    int keyid;
-    unsigned char *a = (unsigned char *)ext->addr.sa_data;
-    CsrWifiSmeKey sme_key;
-    CsrWifiSmeKeyType key_type;
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwencodeext: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-    unifi_trace(priv, UDBG1, "siwencodeext: flags=0x%X, alg=%d, ext_flags=0x%X, len=%d, index=%d,\n",
-                wrqu->encoding.flags, ext->alg, ext->ext_flags,
-                ext->key_len, (wrqu->encoding.flags & IW_ENCODE_INDEX));
-	unifi_trace(priv, UDBG3, "              addr=%pM\n", a);
-
-    if ((ext->key_len == 0) && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
-        /* This means use a different key (given by key_idx) for Tx. */
-        /* NYI */
-        unifi_trace(priv, UDBG1, KERN_ERR "unifi_siwencodeext: NYI should change tx key id here!!\n");
-        return -ENOTSUPP;
-    }
-
-    memset(&sme_key, 0, sizeof(sme_key));
-
-    keydata = (unsigned char *)(ext + 1);
-    keyid = (wrqu->encoding.flags & IW_ENCODE_INDEX);
-
-    /*
-     * Check for request to delete keys for an address.
-     */
-    /* Pick out request for no privacy. */
-    if (ext->alg == IW_ENCODE_ALG_NONE) {
-
-        unifi_trace(priv, UDBG1, "Deleting %s key %d\n",
-                    (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ? "GROUP" : "PAIRWISE",
-                    keyid);
-
-        if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP;
-        } else {
-            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;
-        }
-        sme_key.keyIndex = (keyid - 1);
-        sme_key.keyLength = 0;
-        sme_key.authenticator = 0;
-        memcpy(sme_key.address.a, a, ETH_ALEN);
-        UF_RTNL_UNLOCK();
-        r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_REMOVE);
-        UF_RTNL_LOCK();
-        if (r) {
-            unifi_error(priv, "Delete key request was rejected with result %d\n", r);
-            return convert_sme_error(r);
-        }
-
-        return 0;
-    }
-
-    /*
-     * Request is to set a key, not delete
-     */
-
-    /* Pick out WEP and use set_wep_key(). */
-    if (ext->alg == IW_ENCODE_ALG_WEP) {
-        /* WEP-40, WEP-104 */
-
-        /* Check for valid key length */
-        if (!((ext->key_len == 5) || (ext->key_len == 13))) {
-            unifi_trace(priv, UDBG1, KERN_ERR "Invalid length for WEP key: %d\n", ext->key_len);
-            return -EINVAL;
-        }
-
-        unifi_trace(priv, UDBG1, "Setting WEP key %d tx:%d\n",
-                    keyid, ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY);
-
-        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-            sme_key.wepTxKey = TRUE;
-            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_PAIRWISE;
-        } else {
-            sme_key.wepTxKey = FALSE;
-            sme_key.keyType = CSR_WIFI_SME_KEY_TYPE_GROUP;
-        }
-        sme_key.keyIndex = (keyid - 1);
-        sme_key.keyLength = ext->key_len;
-        sme_key.authenticator = 0;
-        memset(sme_key.address.a, 0xFF, ETH_ALEN);
-        memcpy(sme_key.key, keydata, ext->key_len);
-        UF_RTNL_UNLOCK();
-        r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
-        UF_RTNL_LOCK();
-        if (r) {
-            unifi_error(priv, "siwencodeext: Set key failed (%d)", r);
-            return convert_sme_error(r);
-        }
-
-        return 0;
-    }
-
-    /*
-     *
-     * If we reach here, we are dealing with a WPA/WPA2 key
-     *
-     */
-    if (ext->key_len > 32) {
-        return -EINVAL;
-    }
-
-    /*
-     * TKIP keys from wpa_supplicant need swapping.
-     * What about other supplicants (when they come along)?
-     */
-    if ((ext->alg == IW_ENCODE_ALG_TKIP) && (ext->key_len == 32)) {
-        memcpy(tkip_key, keydata, 16);
-        memcpy(tkip_key + 16, keydata + 24, 8);
-        memcpy(tkip_key + 24, keydata + 16, 8);
-        keydata = tkip_key;
-    }
-
-    key_type = (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) ?
-        CSR_WIFI_SME_KEY_TYPE_GROUP : /* Group Key */
-        CSR_WIFI_SME_KEY_TYPE_PAIRWISE; /* Pairwise Key */
-
-    sme_key.keyType = key_type;
-    sme_key.keyIndex = (keyid - 1);
-    sme_key.keyLength = ext->key_len;
-    sme_key.authenticator = 0;
-    memcpy(sme_key.address.a, ext->addr.sa_data, ETH_ALEN);
-    if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
-
-		unifi_trace(priv, UDBG5, "RSC first 6 bytes = %*phC\n",
-					 6, ext->rx_seq);
-
-        /* memcpy((u8*)(&sme_key.keyRsc), ext->rx_seq, 8); */
-        sme_key.keyRsc[0] = ext->rx_seq[1] << 8 | ext->rx_seq[0];
-        sme_key.keyRsc[1] = ext->rx_seq[3] << 8 | ext->rx_seq[2];
-        sme_key.keyRsc[2] = ext->rx_seq[5] << 8 | ext->rx_seq[4];
-        sme_key.keyRsc[3] = ext->rx_seq[7] << 8 | ext->rx_seq[6];
-
-    }
-
-    memcpy(sme_key.key, keydata, ext->key_len);
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_key(priv, &sme_key, CSR_WIFI_SME_LIST_ACTION_ADD);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "SETKEYS request was rejected with result %d\n", r);
-        return convert_sme_error(r);
-    }
-
-    return r;
-} /* _unifi_siwencodeext() */
-
-
-static int
-unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    int err = 0;
-
-    err = _unifi_siwencodeext(dev, info, wrqu, extra);
-
-    return err;
-} /* unifi_siwencodeext() */
-
-
-static int
-unifi_giwencodeext(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    return -EOPNOTSUPP;
-} /* unifi_giwencodeext() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_siwpmksa
- *
- *      SIOCSIWPMKSA - PMKSA cache operation
- *      The caller passes a pmksa structure:
- *        - cmd         one of ADD, REMOVE, FLUSH
- *        - bssid       MAC address
- *        - pmkid       ID string (16 bytes)
- *
- *  Arguments:
- *      None.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      This is not needed since we provide a siwgenie method.
- * ---------------------------------------------------------------------------
- */
-#define UNIFI_PMKID_KEY_SIZE 16
-static int
-unifi_siwpmksa(struct net_device *dev, struct iw_request_info *info,
-        union iwreq_data *wrqu, char *extra)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-    struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
-    CsrResult r = 0;
-    CsrWifiSmePmkidList pmkid_list;
-    CsrWifiSmePmkid pmkid;
-    CsrWifiSmeListAction action;
-
-    CHECK_INITED(priv);
-
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-       unifi_error(priv, "unifi_siwpmksa: not permitted in Mode %d\n",
-                                      interfacePriv->interfaceMode);
-       return -EPERM;
-    }
-
-
-	unifi_trace(priv, UDBG1, "SIWPMKSA: cmd %d, %pM\n", pmksa->cmd,
-		pmksa->bssid.sa_data);
-
-    pmkid_list.pmkids = NULL;
-    switch (pmksa->cmd) {
-      case IW_PMKSA_ADD:
-        pmkid_list.pmkids = &pmkid;
-        action = CSR_WIFI_SME_LIST_ACTION_ADD;
-        pmkid_list.pmkidsCount = 1;
-        memcpy(pmkid.bssid.a, pmksa->bssid.sa_data, ETH_ALEN);
-        memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE);
-        break;
-      case IW_PMKSA_REMOVE:
-        pmkid_list.pmkids = &pmkid;
-        action = CSR_WIFI_SME_LIST_ACTION_REMOVE;
-        pmkid_list.pmkidsCount = 1;
-        memcpy(pmkid.bssid.a, pmksa->bssid.sa_data, ETH_ALEN);
-        memcpy(pmkid.pmkid, pmksa->pmkid, UNIFI_PMKID_KEY_SIZE);
-        break;
-      case IW_PMKSA_FLUSH:
-        /* Replace current PMKID's with an empty list */
-        pmkid_list.pmkidsCount = 0;
-        action = CSR_WIFI_SME_LIST_ACTION_FLUSH;
-        break;
-      default:
-        unifi_notice(priv, "SIWPMKSA: Unknown command (0x%x)\n", pmksa->cmd);
-        return -EINVAL;
-    }
-
-    /* Set the Value the pmkid's will have 1 added OR 1 removed OR be cleared at this point */
-    UF_RTNL_UNLOCK();
-    r = sme_mgt_pmkid(priv, action, &pmkid_list);
-    UF_RTNL_LOCK();
-    if (r) {
-        unifi_error(priv, "SIWPMKSA: Set PMKID's Failed.\n");
-    }
-
-    return r;
-
-} /* unifi_siwpmksa() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_get_wireless_stats
- *
- *      get_wireless_stats method for Linux wireless extensions.
- *
- *  Arguments:
- *      dev             Pointer to associated netdevice.
- *
- *  Returns:
- *      Pointer to iw_statistics struct.
- * ---------------------------------------------------------------------------
- */
-struct iw_statistics *
-unifi_get_wireless_stats(struct net_device *dev)
-{
-    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    if (priv->init_progress != UNIFI_INIT_COMPLETED) {
-        return NULL;
-    }
-
-    return &priv->wext_wireless_stats;
-} /* unifi_get_wireless_stats() */
-
-
-/*
- * Structures to export the Wireless Handlers
- */
-
-static const struct iw_priv_args unifi_private_args[] = {
-    /*{ cmd,         set_args,                            get_args, name } */
-    { SIOCIWS80211POWERSAVEPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE, "iwprivs80211ps" },
-    { SIOCIWG80211POWERSAVEPRIV, IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IWPRIV_POWER_SAVE_MAX_STRING, "iwprivg80211ps" },
-    { SIOCIWS80211RELOADDEFAULTSPRIV, IW_PRIV_TYPE_NONE,
-        IW_PRIV_TYPE_NONE, "iwprivsdefs" },
-    { SIOCIWSSMEDEBUGPRIV, IW_PRIV_TYPE_CHAR | IWPRIV_SME_DEBUG_MAX_STRING, IW_PRIV_TYPE_NONE, "iwprivssmedebug" },
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-    { SIOCIWSCONFWAPIPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
-        IW_PRIV_TYPE_NONE, "iwprivsconfwapi" },
-    { SIOCIWSWAPIKEYPRIV, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(unifiio_wapi_key_t),
-        IW_PRIV_TYPE_NONE, "iwprivswpikey" },
-#endif
-#ifdef CSR_SUPPORT_WEXT_AP
-    { SIOCIWSAPCFGPRIV, IW_PRIV_TYPE_CHAR | 256, IW_PRIV_TYPE_NONE, "AP_SET_CFG" },
-    { SIOCIWSAPSTARTPRIV, 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED|IWPRIV_SME_MAX_STRING,"AP_BSS_START" },
-    { SIOCIWSAPSTOPPRIV, IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0,
-      IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0, "AP_BSS_STOP" },
-#ifdef ANDROID_BUILD
-    { SIOCIWSFWRELOADPRIV, IW_PRIV_TYPE_CHAR |256,
-      IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|0, "WL_FW_RELOAD" },
-    { SIOCIWSSTACKSTART, 0,
-      IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|IWPRIV_SME_MAX_STRING, "START" },
-    { SIOCIWSSTACKSTOP, 0,
-      IW_PRIV_TYPE_CHAR |IW_PRIV_SIZE_FIXED|IWPRIV_SME_MAX_STRING, "STOP" },
-#endif /* ANDROID_BUILD */
-#endif /* CSR_SUPPORT_WEXT_AP */
-};
-
-static const iw_handler unifi_handler[] =
-{
-    (iw_handler) unifi_siwcommit,           /* SIOCSIWCOMMIT */
-    (iw_handler) unifi_giwname,             /* SIOCGIWNAME */
-    (iw_handler) NULL,                      /* SIOCSIWNWID */
-    (iw_handler) NULL,                      /* SIOCGIWNWID */
-    (iw_handler) unifi_siwfreq,             /* SIOCSIWFREQ */
-    (iw_handler) unifi_giwfreq,             /* SIOCGIWFREQ */
-    (iw_handler) unifi_siwmode,             /* SIOCSIWMODE */
-    (iw_handler) unifi_giwmode,             /* SIOCGIWMODE */
-    (iw_handler) NULL,                      /* SIOCSIWSENS */
-    (iw_handler) NULL,                      /* SIOCGIWSENS */
-    (iw_handler) NULL,                      /* SIOCSIWRANGE */
-    (iw_handler) unifi_giwrange,            /* SIOCGIWRANGE */
-    (iw_handler) NULL,                      /* SIOCSIWPRIV */
-    (iw_handler) NULL,                      /* SIOCGIWPRIV */
-    (iw_handler) NULL,                      /* SIOCSIWSTATS */
-    (iw_handler) NULL,                      /* SIOCGIWSTATS */
-    (iw_handler) NULL,                      /* SIOCSIWSPY */
-    (iw_handler) NULL,                      /* SIOCGIWSPY */
-    (iw_handler) NULL,                      /* SIOCSIWTHRSPY */
-    (iw_handler) NULL,                      /* SIOCGIWTHRSPY */
-    (iw_handler) unifi_siwap,               /* SIOCSIWAP */
-    (iw_handler) unifi_giwap,               /* SIOCGIWAP */
-#if WIRELESS_EXT > 17
-    /* WPA : IEEE 802.11 MLME requests */
-    unifi_siwmlme,              /* SIOCSIWMLME, request MLME operation */
-#else
-    (iw_handler) NULL,                      /* -- hole -- */
-#endif
-    (iw_handler) NULL,                      /* SIOCGIWAPLIST */
-    (iw_handler) unifi_siwscan,             /* SIOCSIWSCAN */
-    (iw_handler) unifi_giwscan,             /* SIOCGIWSCAN */
-    (iw_handler) unifi_siwessid,            /* SIOCSIWESSID */
-    (iw_handler) unifi_giwessid,            /* SIOCGIWESSID */
-    (iw_handler) NULL,                      /* SIOCSIWNICKN */
-    (iw_handler) NULL,                      /* SIOCGIWNICKN */
-    (iw_handler) NULL,                      /* -- hole -- */
-    (iw_handler) NULL,                      /* -- hole -- */
-    unifi_siwrate,                          /* SIOCSIWRATE */
-    unifi_giwrate,                          /* SIOCGIWRATE */
-    unifi_siwrts,                           /* SIOCSIWRTS */
-    unifi_giwrts,                           /* SIOCGIWRTS */
-    unifi_siwfrag,                          /* SIOCSIWFRAG */
-    unifi_giwfrag,                          /* SIOCGIWFRAG */
-    (iw_handler) NULL,                      /* SIOCSIWTXPOW */
-    (iw_handler) NULL,                      /* SIOCGIWTXPOW */
-    (iw_handler) NULL,                      /* SIOCSIWRETRY */
-    (iw_handler) NULL,                      /* SIOCGIWRETRY */
-    unifi_siwencode,                        /* SIOCSIWENCODE */
-    unifi_giwencode,                        /* SIOCGIWENCODE */
-    unifi_siwpower,                         /* SIOCSIWPOWER */
-    unifi_giwpower,                         /* SIOCGIWPOWER */
-#if WIRELESS_EXT > 17
-    (iw_handler) NULL,                      /* -- hole -- */
-    (iw_handler) NULL,                      /* -- hole -- */
-
-    /* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). */
-    unifi_siwgenie,             /* SIOCSIWGENIE */      /* set generic IE */
-    unifi_giwgenie,             /* SIOCGIWGENIE */      /* get generic IE */
-
-    /* WPA : Authentication mode parameters */
-    unifi_siwauth,              /* SIOCSIWAUTH */       /* set authentication mode params */
-    unifi_giwauth,              /* SIOCGIWAUTH */       /* get authentication mode params */
-
-    /* WPA : Extended version of encoding configuration */
-    unifi_siwencodeext,         /* SIOCSIWENCODEEXT */  /* set encoding token & mode */
-    unifi_giwencodeext,         /* SIOCGIWENCODEEXT */  /* get encoding token & mode */
-
-    /* WPA2 : PMKSA cache management */
-    unifi_siwpmksa,             /* SIOCSIWPMKSA */      /* PMKSA cache operation */
-    (iw_handler) NULL,          /* -- hole -- */
-#endif /* WIRELESS_EXT > 17 */
-};
-
-
-static const iw_handler unifi_private_handler[] =
-{
-    iwprivs80211ps,                 /* SIOCIWFIRSTPRIV */
-    iwprivg80211ps,                 /* SIOCIWFIRSTPRIV + 1 */
-    iwprivsdefs,                    /* SIOCIWFIRSTPRIV + 2 */
-    (iw_handler) NULL,
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-    iwprivsconfwapi,                /* SIOCIWFIRSTPRIV + 4 */
-    (iw_handler) NULL,              /* SIOCIWFIRSTPRIV + 5 */
-    iwprivswpikey,                  /* SIOCIWFIRSTPRIV + 6 */
-#else
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-#endif
-    (iw_handler) NULL,
-    iwprivssmedebug,                /* SIOCIWFIRSTPRIV + 8 */
-#ifdef CSR_SUPPORT_WEXT_AP
-    (iw_handler) NULL,
-    iwprivsapconfig,
-    (iw_handler) NULL,
-    iwprivsapstart,
-    (iw_handler) NULL,
-    iwprivsapstop,
-    (iw_handler) NULL,
-#ifdef ANDROID_BUILD
-    iwprivsapfwreload,
-    (iw_handler) NULL,
-    iwprivsstackstart,
-    (iw_handler) NULL,
-    iwprivsstackstop,
-#else
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-#endif /* ANDROID_BUILD */
-#else
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-    (iw_handler) NULL,
-#endif /* CSR_SUPPORT_WEXT_AP */
-};
-
-struct iw_handler_def unifi_iw_handler_def =
-{
-    .num_standard       = sizeof(unifi_handler) / sizeof(iw_handler),
-    .num_private        = sizeof(unifi_private_handler) / sizeof(iw_handler),
-    .num_private_args   = sizeof(unifi_private_args) / sizeof(struct iw_priv_args),
-    .standard           = (iw_handler *) unifi_handler,
-    .private            = (iw_handler *) unifi_private_handler,
-    .private_args       = (struct iw_priv_args *) unifi_private_args,
-#if IW_HANDLER_VERSION >= 6
-    .get_wireless_stats = unifi_get_wireless_stats,
-#endif
-};
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/ul_int.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/ul_int.c
--- linux-libre-3.10-gnu/drivers/staging/csr/ul_int.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/ul_int.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,528 +0,0 @@
-/*
- * ***************************************************************************
- *  FILE:     ul_int.c
- *
- *  PURPOSE:
- *      Manage list of client applications using UniFi.
- *
- * Copyright (C) 2006-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ***************************************************************************
- */
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-#include "unifi_priv.h"
-#include "unifiio.h"
-#include "unifi_os.h"
-
-static void free_bulkdata_buffers(unifi_priv_t *priv, bulk_data_param_t *bulkdata);
-static void reset_driver_status(unifi_priv_t *priv);
-
-/*
- * ---------------------------------------------------------------------------
- *  ul_init_clients
- *
- *      Initialise the clients array to empty.
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      This function needs to be called before priv is stored in
- *      Unifi_instances[].
- * ---------------------------------------------------------------------------
- */
-void
-ul_init_clients(unifi_priv_t *priv)
-{
-    int id;
-    ul_client_t *ul_clients;
-
-    sema_init(&priv->udi_logging_mutex, 1);
-    priv->logging_client = NULL;
-
-    ul_clients = priv->ul_clients;
-
-    for (id = 0; id < MAX_UDI_CLIENTS; id++) {
-        memset(&ul_clients[id], 0, sizeof(ul_client_t));
-
-        ul_clients[id].client_id = id;
-        ul_clients[id].sender_id = UDI_SENDER_ID_BASE + (id << UDI_SENDER_ID_SHIFT);
-        ul_clients[id].instance = -1;
-        ul_clients[id].event_hook = NULL;
-
-        INIT_LIST_HEAD(&ul_clients[id].udi_log);
-        init_waitqueue_head(&ul_clients[id].udi_wq);
-        sema_init(&ul_clients[id].udi_sem, 1);
-
-        ul_clients[id].wake_up_wq_id = 0;
-        ul_clients[id].seq_no = 0;
-        ul_clients[id].wake_seq_no = 0;
-        ul_clients[id].snap_filter.count = 0;
-    }
-} /* ul_init_clients() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  ul_register_client
- *
- *      This function registers a new ul client.
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *      configuration   Special configuration for the client.
- *      udi_event_clbk  Callback for receiving event from unifi.
- *
- *  Returns:
- *      0 if a new clients is registered, -1 otherwise.
- * ---------------------------------------------------------------------------
- */
-ul_client_t *
-ul_register_client(unifi_priv_t *priv, unsigned int configuration,
-                   udi_event_t udi_event_clbk)
-{
-    unsigned char id, ref;
-    ul_client_t *ul_clients;
-
-    ul_clients = priv->ul_clients;
-
-    /* check for an unused entry */
-    for (id = 0; id < MAX_UDI_CLIENTS; id++) {
-        if (ul_clients[id].udi_enabled == 0) {
-            ul_clients[id].instance = priv->instance;
-            ul_clients[id].udi_enabled = 1;
-            ul_clients[id].configuration = configuration;
-
-            /* Allocate memory for the reply signal.. */
-            ul_clients[id].reply_signal = kmalloc(sizeof(CSR_SIGNAL), GFP_KERNEL);
-            if (ul_clients[id].reply_signal == NULL) {
-                unifi_error(priv, "Failed to allocate reply signal for client.\n");
-                return NULL;
-            }
-            /* .. and the bulk data of the reply signal. */
-            for (ref = 0; ref < UNIFI_MAX_DATA_REFERENCES; ref ++) {
-                ul_clients[id].reply_bulkdata[ref] = kmalloc(sizeof(bulk_data_t), GFP_KERNEL);
-                /* If allocation fails, free allocated memory. */
-                if (ul_clients[id].reply_bulkdata[ref] == NULL) {
-                    for (; ref > 0; ref --) {
-                        kfree(ul_clients[id].reply_bulkdata[ref - 1]);
-                    }
-                    kfree(ul_clients[id].reply_signal);
-                    unifi_error(priv, "Failed to allocate bulk data buffers for client.\n");
-                    return NULL;
-                }
-            }
-
-            /* Set the event callback. */
-            ul_clients[id].event_hook = udi_event_clbk;
-
-            unifi_trace(priv, UDBG2, "UDI %d (0x%x) registered. configuration = 0x%x\n",
-                        id, &ul_clients[id], configuration);
-            return &ul_clients[id];
-        }
-    }
-    return NULL;
-} /* ul_register_client() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  ul_deregister_client
- *
- *      This function deregisters a blocking UDI client.
- *
- *  Arguments:
- *      client      Pointer to the client we deregister.
- *
- *  Returns:
- *      0 if a new clients is deregistered.
- * ---------------------------------------------------------------------------
- */
-int
-ul_deregister_client(ul_client_t *ul_client)
-{
-    struct list_head *pos, *n;
-    udi_log_t *logptr;
-    unifi_priv_t *priv = uf_find_instance(ul_client->instance);
-    int ref;
-
-    ul_client->instance = -1;
-    ul_client->event_hook = NULL;
-    ul_client->udi_enabled = 0;
-    unifi_trace(priv, UDBG5, "UDI (0x%x) deregistered.\n", ul_client);
-
-    /* Free memory allocated for the reply signal and its bulk data. */
-    kfree(ul_client->reply_signal);
-    for (ref = 0; ref < UNIFI_MAX_DATA_REFERENCES; ref ++) {
-        kfree(ul_client->reply_bulkdata[ref]);
-    }
-
-    if (ul_client->snap_filter.count) {
-        ul_client->snap_filter.count = 0;
-        kfree(ul_client->snap_filter.protocols);
-    }
-
-    /* Free anything pending on the udi_log list */
-    down(&ul_client->udi_sem);
-    list_for_each_safe(pos, n, &ul_client->udi_log)
-    {
-        logptr = list_entry(pos, udi_log_t, q);
-        list_del(pos);
-        kfree(logptr);
-    }
-    up(&ul_client->udi_sem);
-
-    return 0;
-} /* ul_deregister_client() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  logging_handler
- *
- *      This function is registered with the driver core.
- *      It is called every time a UniFi HIP Signal is sent. It iterates over
- *      the list of processes interested in receiving log events and
- *      delivers the events to them.
- *
- *  Arguments:
- *      ospriv      Pointer to driver's private data.
- *      sigdata     Pointer to the packed signal buffer.
- *      signal_len  Length of the packed signal.
- *      bulkdata    Pointer to the signal's bulk data.
- *      dir         Direction of the signal
- *                  0 = from-host
- *                  1 = to-host
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-logging_handler(void *ospriv,
-                u8 *sigdata, u32 signal_len,
-                const bulk_data_param_t *bulkdata,
-                enum udi_log_direction direction)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-    ul_client_t *client;
-    int dir;
-
-    dir = (direction == UDI_LOG_FROM_HOST) ? UDI_FROM_HOST : UDI_TO_HOST;
-
-    down(&priv->udi_logging_mutex);
-    client = priv->logging_client;
-    if (client != NULL) {
-        client->event_hook(client, sigdata, signal_len,
-                           bulkdata, dir);
-    }
-    up(&priv->udi_logging_mutex);
-
-} /* logging_handler() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  ul_log_config_ind
- *
- *      This function uses the client's register callback
- *      to indicate configuration information e.g core errors.
- *
- *  Arguments:
- *      priv        Pointer to driver's private data.
- *      conf_param  Pointer to the configuration data.
- *      len         Length of the configuration data.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-ul_log_config_ind(unifi_priv_t *priv, u8 *conf_param, int len)
-{
-#ifdef CSR_SUPPORT_SME
-    if (priv->smepriv == NULL)
-    {
-        return;
-    }
-    if ((CONFIG_IND_ERROR == (*conf_param)) && (priv->wifi_on_state == wifi_on_in_progress)) {
-        unifi_notice(priv, "ul_log_config_ind: wifi on in progress, suppress error\n");
-    } else {
-        /* wifi_off_ind (error or exit) */
-        CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, (CsrWifiRouterCtrlControlIndication)(*conf_param));
-    }
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-    unifi_debug_buf_dump();
-#endif
-#else
-    bulk_data_param_t bulkdata;
-
-    /*
-     * If someone killed unifi_managed before the driver was unloaded
-     * the g_drvpriv pointer is going to be NULL. In this case it is
-     * safe to assume that there is no client to get the indication.
-     */
-    if (!priv) {
-        unifi_notice(NULL, "uf_sme_event_ind: NULL priv\n");
-        return;
-    }
-
-    /* Create a null bulkdata structure. */
-    bulkdata.d[0].data_length = 0;
-    bulkdata.d[1].data_length = 0;
-
-    sme_native_log_event(priv->sme_cli, conf_param, sizeof(u8),
-                         &bulkdata, UDI_CONFIG_IND);
-
-#endif /* CSR_SUPPORT_SME */
-
-} /* ul_log_config_ind */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  free_bulkdata_buffers
- *
- *      Free the bulkdata buffers e.g. after a failed unifi_send_signal().
- *
- *  Arguments:
- *      priv        Pointer to device private struct
- *      bulkdata    Pointer to bulkdata parameter table
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void
-free_bulkdata_buffers(unifi_priv_t *priv, bulk_data_param_t *bulkdata)
-{
-    int i;
-
-    if (bulkdata) {
-        for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; ++i) {
-            if (bulkdata->d[i].data_length != 0) {
-                unifi_net_data_free(priv, (bulk_data_desc_t *)(&bulkdata->d[i]));
-                /* data_length is now 0 */
-            }
-        }
-    }
-
-} /* free_bulkdata_buffers */
-
-static int
-_align_bulk_data_buffers(unifi_priv_t *priv, u8 *signal,
-                         bulk_data_param_t *bulkdata)
-{
-    unsigned int i;
-
-    if ((bulkdata == NULL) || (CSR_WIFI_ALIGN_BYTES == 0)) {
-        return 0;
-    }
-
-    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
-    {
-        struct sk_buff *skb;
-        /*
-        * The following complex casting is in place in order to eliminate 64-bit compilation warning
-        * "cast to/from pointer from/to integer of different size"
-        */
-        u32 align_offset = (u32)(long)(bulkdata->d[i].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1);
-        if (align_offset)
-        {
-            skb = (struct sk_buff*)bulkdata->d[i].os_net_buf_ptr;
-            if (skb == NULL) {
-                unifi_warning(priv,
-                              "_align_bulk_data_buffers: Align offset found (%d) but skb is NULL!\n",
-                              align_offset);
-                return -EINVAL;
-            }
-            if (bulkdata->d[i].data_length == 0) {
-                unifi_warning(priv,
-                              "_align_bulk_data_buffers: Align offset found (%d) but length is zero\n",
-                              align_offset);
-                return CSR_RESULT_SUCCESS;
-            }
-            unifi_trace(priv, UDBG5,
-                        "Align f-h buffer (0x%p) by %d bytes (skb->data: 0x%p)\n",
-                        bulkdata->d[i].os_data_ptr, align_offset, skb->data);
-
-
-            /* Check if there is enough headroom... */
-            if (unlikely(skb_headroom(skb) < align_offset))
-            {
-                struct sk_buff *tmp = skb;
-
-                unifi_trace(priv, UDBG5, "Headroom not enough - realloc it\n");
-                skb = skb_realloc_headroom(skb, align_offset);
-                if (skb == NULL) {
-                    unifi_error(priv,
-                                "_align_bulk_data_buffers: skb_realloc_headroom failed - signal is dropped\n");
-                    return -EFAULT;
-                }
-                /* Free the old bulk data only if allocation succeeds */
-                kfree_skb(tmp);
-                /* Bulkdata needs to point to the new skb */
-                bulkdata->d[i].os_net_buf_ptr = (const unsigned char*)skb;
-                bulkdata->d[i].os_data_ptr = (const void*)skb->data;
-            }
-            /* ... before pushing the data to the right alignment offset */
-            skb_push(skb, align_offset);
-
-        }
-        /* The direction bit is zero for the from-host */
-        signal[SIZEOF_SIGNAL_HEADER + (i * SIZEOF_DATAREF) + 1] = align_offset;
-
-    }
-    return 0;
-} /* _align_bulk_data_buffers() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  ul_send_signal_unpacked
- *
- *      This function sends a host formatted signal to unifi.
- *
- *  Arguments:
- *      priv        Pointer to driver's private data.
- *      sigptr      Pointer to the signal.
- *      bulkdata    Pointer to the signal's bulk data.
- *
- *  Returns:
- *      O on success, error code otherwise.
- *
- *  Notes:
- *  The signals have to be sent in the format described in the host interface
- *  specification, i.e wire formatted. Certain clients use the host formatted
- *  structures. The write_pack() transforms the host formatted signal
- *  into the wired formatted signal. The code is in the core, since the signals
- *  are defined therefore binded to the host interface specification.
- * ---------------------------------------------------------------------------
- */
-int
-ul_send_signal_unpacked(unifi_priv_t *priv, CSR_SIGNAL *sigptr,
-                        bulk_data_param_t *bulkdata)
-{
-    u8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE];
-    u16 packed_siglen;
-    CsrResult csrResult;
-    unsigned long lock_flags;
-    int r;
-
-
-    csrResult = write_pack(sigptr, sigbuf, &packed_siglen);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "Malformed HIP signal in ul_send_signal_unpacked()\n");
-        return CsrHipResultToStatus(csrResult);
-    }
-    r = _align_bulk_data_buffers(priv, sigbuf, (bulk_data_param_t*)bulkdata);
-    if (r) {
-        return r;
-    }
-
-    spin_lock_irqsave(&priv->send_signal_lock, lock_flags);
-    csrResult = unifi_send_signal(priv->card, sigbuf, packed_siglen, bulkdata);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-  /*      free_bulkdata_buffers(priv, (bulk_data_param_t *)bulkdata); */
-        spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
-        return CsrHipResultToStatus(csrResult);
-    }
-    spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
-
-    return 0;
-} /* ul_send_signal_unpacked() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  reset_driver_status
- *
- *      This function is called from ul_send_signal_raw() when it detects
- *      that the SME has sent a MLME-RESET request.
- *
- *  Arguments:
- *      priv        Pointer to device private struct
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-static void
-reset_driver_status(unifi_priv_t *priv)
-{
-    priv->sta_wmm_capabilities = 0;
-#ifdef CSR_NATIVE_LINUX
-#ifdef CSR_SUPPORT_WEXT
-    priv->wext_conf.flag_associated = 0;
-    priv->wext_conf.block_controlled_port = CSR_WIFI_ROUTER_PORT_ACTION_8021X_PORT_OPEN;
-    priv->wext_conf.bss_wmm_capabilities = 0;
-    priv->wext_conf.disable_join_on_ssid_set = 0;
-#endif
-#endif
-} /* reset_driver_status() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  ul_send_signal_raw
- *
- *      This function sends a wire formatted data signal to unifi.
- *
- *  Arguments:
- *      priv        Pointer to driver's private data.
- *      sigptr      Pointer to the signal.
- *      siglen      Length of the signal.
- *      bulkdata    Pointer to the signal's bulk data.
- *
- *  Returns:
- *      O on success, error code otherwise.
- * ---------------------------------------------------------------------------
- */
-int
-ul_send_signal_raw(unifi_priv_t *priv, unsigned char *sigptr, int siglen,
-                   bulk_data_param_t *bulkdata)
-{
-    CsrResult csrResult;
-    unsigned long lock_flags;
-    int r;
-
-    /*
-     * Make sure that the signal is updated with the bulk data
-     * alignment for DMA.
-     */
-    r = _align_bulk_data_buffers(priv, (u8*)sigptr, bulkdata);
-    if (r) {
-        return r;
-    }
-
-    spin_lock_irqsave(&priv->send_signal_lock, lock_flags);
-    csrResult = unifi_send_signal(priv->card, sigptr, siglen, bulkdata);
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        free_bulkdata_buffers(priv, bulkdata);
-        spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
-        return CsrHipResultToStatus(csrResult);
-    }
-    spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
-
-    /*
-     * Since this is use by unicli, if we get an MLME reset request
-     * we need to initialize a few status parameters
-     * that the driver uses to make decisions.
-     */
-    if (GET_SIGNAL_ID(sigptr) == CSR_MLME_RESET_REQUEST_ID) {
-        reset_driver_status(priv);
-    }
-
-    return 0;
-} /* ul_send_signal_raw() */
-
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_clients.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_clients.h
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_clients.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_clients.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,129 +0,0 @@
-/*
- *****************************************************************************
- *
- * FILE : unifi_clients.h
- *
- * PURPOSE : Private header file for unifi clients.
- *
- *           UDI = UniFi Debug Interface
- *
- * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- *****************************************************************************
- */
-#ifndef __LINUX_UNIFI_CLIENTS_H__
-#define __LINUX_UNIFI_CLIENTS_H__ 1
-
-#include <linux/kernel.h>
-
-#define MAX_UDI_CLIENTS 8
-
-/* The start of the range of process ids allocated for ul clients */
-#define UDI_SENDER_ID_BASE      0xC000
-#define UDI_SENDER_ID_SHIFT     8
-
-
-/* Structure to hold a UDI logged signal */
-typedef struct {
-
-    /* List link structure */
-    struct list_head q;
-
-    /* The message that will be passed to the user app */
-    udi_msg_t msg;
-
-    /* Signal body and data follow */
-
-} udi_log_t;
-
-
-
-typedef struct ul_client ul_client_t;
-
-typedef void (*udi_event_t)(ul_client_t *client,
-                            const u8 *sigdata, int signal_len,
-                            const bulk_data_param_t *bulkdata,
-                            int dir);
-
-void logging_handler(void *ospriv,
-                     u8 *sigdata, u32 signal_len,
-                     const bulk_data_param_t *bulkdata,
-                     enum udi_log_direction direction);
-
-
-/*
- * Structure describing a bulk data slot.
- * The length field is used to indicate empty/occupied state.
- */
-typedef struct _bulk_data
-{
-    unsigned char ptr[2000];
-    unsigned int length;
-} bulk_data_t;
-
-
-struct ul_client {
-    /* Index of this client in the ul_clients array. */
-    int client_id;
-
-    /* Index of UniFi device to which this client is attached. */
-    int instance;
-
-    /* Flag to say whether this client has been enabled. */
-    int udi_enabled;
-
-    /* Value to use in signal->SenderProcessId */
-    int sender_id;
-
-    /* Configuration flags, e.g blocking, logging, etc. */
-    unsigned int configuration;
-
-    udi_event_t event_hook;
-
-    /* A list to hold signals received from UniFi for reading by read() */
-    struct list_head udi_log;
-
-    /* Semaphore to protect the udi_log list */
-    struct semaphore udi_sem;
-
-    /*
-     * Linux waitqueue to support blocking read and poll.
-     * Logging clients should wait on udi_log. while
-     * blocking clients should wait on wake_up_wq.
-     */
-    wait_queue_head_t udi_wq;
-    CSR_SIGNAL* reply_signal;
-    bulk_data_t* reply_bulkdata[UNIFI_MAX_DATA_REFERENCES];
-
-    u16 signal_filter[SIG_FILTER_SIZE];
-
-
-    /* ------------------------------------------------------------------- */
-    /* Code below here is used by the sme_native configuration only */
-
-    /* Flag to wake up blocking clients waiting on udi_wq. */
-    int wake_up_wq_id;
-
-    /*
-     * A 0x00 - 0x0F mask to apply in signal->SenderProcessId.
-     * Every time we do a blocking mlme request we increase this value.
-     * The mlme_wait_for_reply() will wait for this sequence number.
-     * Only the MLME blocking functions update this field.
-     */
-    unsigned char seq_no;
-
-    /*
-     * A 0x00 - 0x0F counter, containing the sequence number of
-     * the signal that this client has last received.
-     * Only the MLME blocking functions update this field.
-     */
-    unsigned char wake_seq_no;
-
-    unifiio_snap_filter_t snap_filter;
-}; /* struct ul_client */
-
-
-#endif /* __LINUX_UNIFI_CLIENTS_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_config.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_config.h
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_config.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_config.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,34 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *
- * FILE: unifi_config.h
- *
- * PURPOSE:
- *      This header file provides parameters that configure the operation
- *      of the driver.
- *
- * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#ifndef __UNIFI_CONFIG_H__
-#define __UNIFI_CONFIG_H__ 1
-
-/*
- * Override for the SDIO function block size on this host. When byte mode CMD53s
- * are not used/supported by the SD host controller, transfers are padded up to
- * the next block boundary. The 512-byte default on UF6xxx wastes too much space
- * on the chip, so the block size is reduced to support this configuration.
- */
-#define CSR_WIFI_HIP_SDIO_BLOCK_SIZE  64
-
-/* Define the number of mini-coredump buffers to allocate at startup. These are
- * used to record chip status for the last n unexpected resets.
- */
-#define CSR_WIFI_HIP_NUM_COREDUMP_BUFFERS  5
-
-
-#endif /* __UNIFI_CONFIG_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_dbg.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_dbg.c
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_dbg.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_dbg.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,110 +0,0 @@
-/*
- * ***************************************************************************
- *  FILE:     unifi_dbg.c
- *
- *  PURPOSE:
- *      Handle debug signals received from UniFi.
- *
- * Copyright (C) 2007-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ***************************************************************************
- */
-#include "unifi_priv.h"
-
-/*
- * ---------------------------------------------------------------------------
- *  debug_string_indication
- *  debug_word16_indication
- *
- *      Handlers for debug indications.
- *
- *  Arguments:
- *      priv            Pointer to private context structure.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-debug_string_indication(unifi_priv_t *priv, const unsigned char *extra, unsigned int extralen)
-{
-    const unsigned int maxlen = sizeof(priv->last_debug_string) - 1;
-
-    if (extralen > maxlen) {
-        extralen = maxlen;
-    }
-
-    strncpy(priv->last_debug_string, extra, extralen);
-
-    /* Make sure the string is terminated */
-    priv->last_debug_string[extralen] = '\0';
-
-    unifi_info(priv, "unifi debug: %s\n", priv->last_debug_string);
-
-} /* debug_string_indication() */
-
-
-
-void
-debug_word16_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr)
-{
-    int i;
-
-    if (priv == NULL) {
-        unifi_info(priv, "Priv is NULL\n");
-        return;
-    }
-
-    for (i = 0; i < 16; i++) {
-        priv->last_debug_word16[i] =
-                sigptr->u.DebugWord16Indication.DebugWords[i];
-    }
-
-    if (priv->last_debug_word16[0] == 0xFA11) {
-        unsigned long ts;
-        ts = (priv->last_debug_word16[6] << 16) | priv->last_debug_word16[5];
-        unifi_info(priv, " %10lu: %s fault %04x, arg %04x (x%d)\n",
-                   ts,
-                   priv->last_debug_word16[3] == 0x8000 ? "MAC" :
-                   priv->last_debug_word16[3] == 0x4000 ? "PHY" :
-                   "???",
-                   priv->last_debug_word16[1],
-                   priv->last_debug_word16[2],
-                   priv->last_debug_word16[4]);
-    }
-    else if (priv->last_debug_word16[0] != 0xDBAC)
-        /* suppress SDL Trace output (note: still available to unicli). */
-    {
-        unifi_info(priv, "unifi debug: %04X %04X %04X %04X %04X %04X %04X %04X\n",
-                   priv->last_debug_word16[0], priv->last_debug_word16[1],
-                   priv->last_debug_word16[2], priv->last_debug_word16[3],
-                   priv->last_debug_word16[4], priv->last_debug_word16[5],
-                   priv->last_debug_word16[6], priv->last_debug_word16[7]);
-        unifi_info(priv, "             %04X %04X %04X %04X %04X %04X %04X %04X\n",
-                   priv->last_debug_word16[8], priv->last_debug_word16[9],
-                   priv->last_debug_word16[10], priv->last_debug_word16[11],
-                   priv->last_debug_word16[12], priv->last_debug_word16[13],
-                   priv->last_debug_word16[14], priv->last_debug_word16[15]);
-    }
-
-} /* debug_word16_indication() */
-
-
-void
-debug_generic_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr)
-{
-    unifi_info(priv, "debug: %04X %04X %04X %04X %04X %04X %04X %04X\n",
-               sigptr->u.DebugGenericIndication.DebugWords[0],
-               sigptr->u.DebugGenericIndication.DebugWords[1],
-               sigptr->u.DebugGenericIndication.DebugWords[2],
-               sigptr->u.DebugGenericIndication.DebugWords[3],
-               sigptr->u.DebugGenericIndication.DebugWords[4],
-               sigptr->u.DebugGenericIndication.DebugWords[5],
-               sigptr->u.DebugGenericIndication.DebugWords[6],
-               sigptr->u.DebugGenericIndication.DebugWords[7]);
-
-} /* debug_generic_indication() */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_event.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_event.c
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_event.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_event.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,692 +0,0 @@
-/*
- * ***************************************************************************
- *  FILE:     unifi_event.c
- *
- *  PURPOSE:
- *      Process the signals received by UniFi.
- *      It is part of the porting exercise.
- *
- * Copyright (C) 2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ***************************************************************************
- */
-
-
-/*
- * Porting notes:
- * The implementation of unifi_receive_event() in Linux is fairly complicated.
- * The linux driver support multiple userspace applications and several
- * build configurations, so the received signals are processed by different
- * processes and multiple times.
- * In a simple implementation, this function needs to deliver:
- * - The MLME-UNITDATA.ind signals to the Rx data plane and to the Traffic
- *   Analysis using unifi_ta_sample().
- * - The MLME-UNITDATA-STATUS.ind signals to the Tx data plane.
- * - All the other signals to the SME using unifi_sys_hip_ind().
- */
-
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-#include "unifi_priv.h"
-
-
-/*
- * ---------------------------------------------------------------------------
- *  send_to_client
- *
- *      Helper for unifi_receive_event.
- *
- *      This function forwards a signal to one client.
- *
- *  Arguments:
- *      priv        Pointer to driver's private data.
- *      client      Pointer to the client structure.
- *      receiver_id The reciever id of the signal.
- *      sigdata     Pointer to the packed signal buffer.
- *      siglen      Length of the packed signal.
- *      bulkdata    Pointer to the signal's bulk data.
- *
- *  Returns:
- *      None.
- *
- * ---------------------------------------------------------------------------
- */
-static void send_to_client(unifi_priv_t *priv, ul_client_t *client,
-        int receiver_id,
-        unsigned char *sigdata, int siglen,
-        const bulk_data_param_t *bulkdata)
-{
-    if (client && client->event_hook) {
-        /*unifi_trace(priv, UDBG3,
-                "Receive: client %d, (s:0x%X, r:0x%X) - Signal 0x%.4X \n",
-                client->client_id, client->sender_id, receiver_id,
-                CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));*/
-
-        client->event_hook(client, sigdata, siglen, bulkdata, UDI_TO_HOST);
-    }
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  process_pkt_data_ind
- *
- *      Dispatcher for received signals.
- *
- *      This function receives the 'to host' signals and forwards
- *      them to the unifi linux clients.
- *
- *  Arguments:
- *      priv         Context
- *      sigdata      Pointer to the packed signal buffer(Its in form of MA-PACKET.ind).
- *      bulkdata     Pointer to signal's bulkdata
- *      freeBulkData Pointer to a flag which gets set if the bulkdata needs to
- *                   be freed after calling the logging handlers. If it is not
- *                   set the bulkdata must be freed by the MLME handler or
- *                   passed to the network stack.
- *  Returns:
- *      TRUE if the packet should be routed to the SME etc.
- *      FALSE if the packet is for the driver or network stack
- * ---------------------------------------------------------------------------
- */
-static u8 check_routing_pkt_data_ind(unifi_priv_t *priv,
-        u8 *sigdata,
-        const bulk_data_param_t* bulkdata,
-        u8 *freeBulkData,
-        netInterface_priv_t *interfacePriv)
-{
-    u16  frmCtrl, receptionStatus, frmCtrlSubType;
-    u8 *macHdrLocation;
-    u8 interfaceTag;
-    u8 isDataFrame;
-    u8 isProtocolVerInvalid = FALSE;
-    u8 isDataFrameSubTypeNoData = FALSE;
-
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-    static const u8 wapiProtocolIdSNAPHeader[] = {0x88,0xb4};
-    static const u8 wapiProtocolIdSNAPHeaderOffset = 6;
-    u8 *destAddr;
-    u8 *srcAddr;
-    u8 isWapiUnicastPkt = FALSE;
-
-#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
-    u16 qosControl;
-#endif
-
-    u8 llcSnapHeaderOffset = 0;
-
-    destAddr = (u8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET;
-    srcAddr  = (u8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;
-
-    /*Individual/Group bit - Bit 0 of first byte*/
-    isWapiUnicastPkt = (!(destAddr[0] & 0x01)) ? TRUE : FALSE;
-#endif
-
-#define CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET    sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22
-
-    *freeBulkData = FALSE;
-
-    /* Fetch the MAC header location from  MA_PKT_IND packet */
-    macHdrLocation = (u8 *) bulkdata->d[0].os_data_ptr;
-    /* Fetch the Frame Control value from  MAC header */
-    frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation);
-
-    /* Pull out interface tag from virtual interface identifier */
-    interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff;
-
-    /* check for MIC failure before processing the signal */
-    receptionStatus = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET);
-
-    /* To discard any spurious MIC failures that could be reported by the firmware */
-    isDataFrame = ((frmCtrl & IEEE80211_FC_TYPE_MASK) == (IEEE802_11_FC_TYPE_DATA & IEEE80211_FC_TYPE_MASK)) ? TRUE : FALSE;
-    /* 0x00 is the only valid protocol version*/
-    isProtocolVerInvalid = (frmCtrl & IEEE80211_FC_PROTO_VERSION_MASK) ? TRUE : FALSE;
-    frmCtrlSubType = (frmCtrl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET;
-    /*Exclude the no data & reserved sub-types from MIC failure processing*/
-    isDataFrameSubTypeNoData = (((frmCtrlSubType>0x03)&&(frmCtrlSubType<0x08)) || (frmCtrlSubType>0x0B)) ? TRUE : FALSE;
-    if ((receptionStatus == CSR_MICHAEL_MIC_ERROR) &&
-        ((!isDataFrame) || isProtocolVerInvalid || (isDataFrame && isDataFrameSubTypeNoData))) {
-        /* Currently MIC errors are discarded for frames other than data frames. This might need changing when we start
-         * supporting 802.11w (Protected Management frames)
-         */
-        *freeBulkData = TRUE;
-        unifi_trace(priv, UDBG4, "Discarding this frame and ignoring the MIC failure as this is a garbage/non-data/no data frame\n");
-        return FALSE;
-     }
-
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-
-    if (receptionStatus == CSR_MICHAEL_MIC_ERROR) {
-
-        if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) {
-
-#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
-            if ((isDataFrame) &&
-                ((IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK) == (frmCtrl & IEEE80211_FC_SUBTYPE_MASK)) &&
-                (priv->isWapiConnection))
-            {
-            	qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation + (((frmCtrl & IEEE802_11_FC_TO_DS_MASK) && (frmCtrl & IEEE802_11_FC_FROM_DS_MASK)) ? 30 : 24) );
-
-            	unifi_trace(priv, UDBG4, "check_routing_pkt_data_ind() :: Value of the QoS control field - 0x%04x \n", qosControl);
-
-                if (qosControl & IEEE802_11_QC_NON_TID_BITS_MASK)
-                {
-                	unifi_trace(priv, UDBG4, "Ignore the MIC failure and pass the MPDU to the stack when any of bits [4-15] is set in the QoS control field\n");
-
-            		/*Exclude the MIC [16] and the PN [16] that are appended by the firmware*/
-            		((bulk_data_param_t*)bulkdata)->d[0].data_length = bulkdata->d[0].data_length - 32;
-
-            		/*Clear the reception status of the signal (CSR_RX_SUCCESS)*/
-            		*(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET)     = 0x00;
-            		*(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET+1)   = 0x00;
-
-            		*freeBulkData = FALSE;
-
-            		return FALSE;
-                }
-            }
-#endif
-            /* If this MIC ERROR reported by the firmware is either for
-             *    [1] a WAPI Multicast MPDU and the Multicast filter has NOT been set (It is set only when group key index (MSKID) = 1 in Group Rekeying)   OR
-             *    [2] a WAPI Unicast MPDU and either the CONTROL PORT is open or the WAPI Unicast filter or filter(s) is NOT set
-             * then report a MIC FAILURE indication to the SME.
-             */
-#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
-    	if ((priv->wapi_multicast_filter == 0) || isWapiUnicastPkt) {
-#else
-        /*When SW encryption is enabled and USKID=1 (wapi_unicast_filter = 1), we are expected
-		 *to receive MIC failure INDs for unicast MPDUs*/
-    	if ( ((priv->wapi_multicast_filter == 0) && !isWapiUnicastPkt) ||
-             ((priv->wapi_unicast_filter   == 0) &&  isWapiUnicastPkt) ) {
-#endif
-                /*Discard the frame*/
-                *freeBulkData = TRUE;
-                unifi_trace(priv, UDBG4, "Discarding the contents of the frame with MIC failure \n");
-
-                if (isWapiUnicastPkt &&
-                    ((uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag) != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)||
-#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
-                    (priv->wapi_unicast_filter) ||
-#endif
-                    (priv->wapi_unicast_queued_pkt_filter))) {
-
-                    /* Workaround to handle MIC failures reported by the firmware for encrypted packets from the AP
-                     * while we are in the process of re-association induced by unsupported WAPI Unicast key index
-                     *             - Discard the packets with MIC failures "until" we have
-                     *               a. negotiated a key,
-                     *               b. opened the CONTROL PORT and
-                     *               c. the AP has started using the new key
-                     */
-                    unifi_trace(priv, UDBG4, "Ignoring the MIC failure as either a. CONTROL PORT isn't OPEN or b. Unicast filter is set or c. WAPI AP using old key for buffered pkts\n");
-
-                    /*Ignore this MIC failure*/
-                    return FALSE;
-
-                }/*WAPI re-key specific workaround*/
-
-                unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind - MIC FAILURE : interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n",
-                            interfaceTag, srcAddr[0], srcAddr[1], srcAddr[2], srcAddr[3], srcAddr[4], srcAddr[5]);
-                unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind - MIC FAILURE : Dest Addr %x:%x:%x:%x:%x:%x\n",
-                            destAddr[0], destAddr[1], destAddr[2], destAddr[3], destAddr[4], destAddr[5]);
-                unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind - MIC FAILURE : Control Port State - 0x%.4X \n",
-                            uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag));
-
-                unifi_error(priv, "MIC failure in %s\n", __FUNCTION__);
-
-                /*Report the MIC failure to the SME*/
-                return TRUE;
-            }
-        }/* STA mode */
-        else {
-            /* Its AP Mode . Just Return */
-            *freeBulkData = TRUE;
-            unifi_error(priv, "MIC failure in %s\n", __FUNCTION__);
-            return TRUE;
-         } /* AP mode */
-    }/* MIC error */
-#else
-    if (receptionStatus == CSR_MICHAEL_MIC_ERROR) {
-        *freeBulkData = TRUE;
-        unifi_error(priv, "MIC failure in %s\n", __FUNCTION__);
-        return TRUE;
-    }
-#endif /*CSR_WIFI_SECURITY_WAPI_ENABLE*/
-
-    unifi_trace(priv, UDBG4, "frmCtrl = 0x%04x %s\n",
-                frmCtrl,
-                (((frmCtrl & 0x000c)>>FRAME_CONTROL_TYPE_FIELD_OFFSET) == IEEE802_11_FRAMETYPE_MANAGEMENT) ?
-                    "Mgt" : "Ctrl/Data");
-
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-    /* To ignore MIC failures reported due to the WAPI AP using the old key for queued packets before
-     * starting to use the new key negotiated as part of unicast re-keying
-     */
-    if ((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA)&&
-        isWapiUnicastPkt &&
-        (receptionStatus == CSR_RX_SUCCESS) &&
-        (priv->wapi_unicast_queued_pkt_filter==1)) {
-
-        unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): WAPI unicast pkt received when the (wapi_unicast_queued_pkt_filter) is set\n");
-
-        if (isDataFrame) {
-            switch(frmCtrl & IEEE80211_FC_SUBTYPE_MASK) {
-                case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
-                    llcSnapHeaderOffset = MAC_HEADER_SIZE + 2;
-                    break;
-                case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK:
-                case IEEE802_11_FC_TYPE_NULL & IEEE80211_FC_SUBTYPE_MASK:
-                    break;
-                default:
-                    llcSnapHeaderOffset = MAC_HEADER_SIZE;
-            }
-        }
-
-        if (llcSnapHeaderOffset > 0) {
-        	/* QoS data or Data */
-            unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): SNAP header found & its offset %d\n",llcSnapHeaderOffset);
-            if (memcmp((u8 *)(bulkdata->d[0].os_data_ptr+llcSnapHeaderOffset+wapiProtocolIdSNAPHeaderOffset),
-                       wapiProtocolIdSNAPHeader,sizeof(wapiProtocolIdSNAPHeader))) {
-
-            	unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): This is a data & NOT a WAI protocol packet\n");
-                /* On the first unicast data pkt that is decrypted successfully after re-keying, reset the filter */
-                priv->wapi_unicast_queued_pkt_filter = 0;
-                unifi_trace(priv, UDBG4, "check_routing_pkt_data_ind(): WAPI AP has started using the new unicast key, no more MIC failures expected (reset filter)\n");
-            }
-            else {
-                unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): WAPI - This is a WAI protocol packet\n");
-            }
-        }
-	}
-#endif
-
-
-    switch ((frmCtrl & 0x000c)>>FRAME_CONTROL_TYPE_FIELD_OFFSET) {
-        case IEEE802_11_FRAMETYPE_MANAGEMENT:
-            *freeBulkData = TRUE;       /* Free (after SME handler copies it) */
-
-            /* In P2P device mode, filter the legacy AP beacons here */
-            if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2P)&&\
-               ((CSR_WIFI_80211_GET_FRAME_SUBTYPE(macHdrLocation)) == CSR_WIFI_80211_FRAME_SUBTYPE_BEACON)){
-
-                u8 *pSsid, *pSsidLen;
-                static u8 P2PWildCardSsid[CSR_WIFI_P2P_WILDCARD_SSID_LENGTH] = {'D', 'I', 'R', 'E', 'C', 'T', '-'};
-
-                pSsidLen = macHdrLocation + MAC_HEADER_SIZE + CSR_WIFI_BEACON_FIXED_LENGTH;
-                pSsid = pSsidLen + 2;
-
-                if(*(pSsidLen + 1) >= CSR_WIFI_P2P_WILDCARD_SSID_LENGTH){
-                    if(memcmp(pSsid, P2PWildCardSsid, CSR_WIFI_P2P_WILDCARD_SSID_LENGTH) == 0){
-                        unifi_trace(priv, UDBG6, "Received a P2P Beacon, pass it to SME\n");
-                        return TRUE;
-                    }
-                }
-                unifi_trace(priv, UDBG6, "Received a Legacy AP beacon in P2P mode, drop it\n");
-                return FALSE;
-            }
-            return TRUE;                /* Route to SME */
-        case IEEE802_11_FRAMETYPE_DATA:
-        case IEEE802_11_FRAMETYPE_CONTROL:
-            *freeBulkData = FALSE;      /* Network stack or MLME handler frees */
-            return FALSE;
-        default:
-            unifi_error(priv, "Unhandled frame type %04x\n", frmCtrl);
-            *freeBulkData = TRUE;       /* Not interested, but must free it */
-            return FALSE;
-    }
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_process_receive_event
- *
- *      Dispatcher for received signals.
- *
- *      This function receives the 'to host' signals and forwards
- *      them to the unifi linux clients.
- *
- *  Arguments:
- *      ospriv      Pointer to driver's private data.
- *      sigdata     Pointer to the packed signal buffer.
- *      siglen      Length of the packed signal.
- *      bulkdata    Pointer to the signal's bulk data.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *  The signals are received in the format described in the host interface
- *  specification, i.e wire formatted. Certain clients use the same format
- *  to interpret them and other clients use the host formatted structures.
- *  Each client has to call read_unpack_signal() to transform the wire
- *  formatted signal into the host formatted signal, if necessary.
- *  The code is in the core, since the signals are defined therefore
- *  binded to the host interface specification.
- * ---------------------------------------------------------------------------
- */
-static void
-unifi_process_receive_event(void *ospriv,
-                            u8 *sigdata, u32 siglen,
-                            const bulk_data_param_t *bulkdata)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-    int i, receiver_id;
-    int client_id;
-    s16 signal_id;
-    u8 pktIndToSme = FALSE, freeBulkData = FALSE;
-
-    unifi_trace(priv, UDBG5, "unifi_process_receive_event: "
-                "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
-                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*0) & 0xFFFF,
-                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*1) & 0xFFFF,
-                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*2) & 0xFFFF,
-                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*3) & 0xFFFF,
-                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*4) & 0xFFFF,
-                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*5) & 0xFFFF,
-                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*6) & 0xFFFF,
-                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*7) & 0xFFFF,
-                siglen);
-
-    receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)) & 0xFF00;
-    client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
-    signal_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata);
-
-
-
-    /* check for the type of frame received (checks for 802.11 management frames) */
-    if (signal_id == CSR_MA_PACKET_INDICATION_ID)
-    {
-#define CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET    14
-        u8 interfaceTag;
-        netInterface_priv_t *interfacePriv;
-
-        /* Pull out interface tag from virtual interface identifier */
-        interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff;
-        interfacePriv = priv->interfacePriv[interfaceTag];
-
-        /* Update activity for this station in case of IBSS */
-#ifdef CSR_SUPPORT_SME
-        if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS)
-        {
-            u8 *saddr;
-            /* Fetch the source address from  mac header */
-            saddr = (u8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;
-            unifi_trace(priv, UDBG5,
-                                    "Updating sta activity in IBSS interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n",
-                                    interfaceTag, saddr[0], saddr[1], saddr[2], saddr[3], saddr[4], saddr[5]);
-
-            uf_update_sta_activity(priv, interfaceTag, saddr);
-        }
-#endif
-
-        pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv);
-
-        unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO");
-
-    }
-
-    if (pktIndToSme)
-    {
-        /* Management MA_PACKET_IND for SME */
-        if(sigdata != NULL && bulkdata != NULL){
-            send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
-        }
-        else{
-            unifi_error(priv, "unifi_receive_event2: sigdata or Bulkdata is NULL \n");
-        }
-#ifdef CSR_NATIVE_LINUX
-        send_to_client(priv, priv->wext_client,
-                receiver_id,
-                sigdata, siglen, bulkdata);
-#endif
-    }
-    else
-    {
-        /* Signals with ReceiverId==0 are also reported to SME / WEXT,
-         * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs
-         */
-        if (!receiver_id) {
-               if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) {
-                      uf_process_ma_vif_availibility_ind(priv, sigdata, siglen);
-               }
-               else if (signal_id != CSR_MA_PACKET_INDICATION_ID) {
-                      send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
-#ifdef CSR_NATIVE_LINUX
-                      send_to_client(priv, priv->wext_client,
-                                     receiver_id,
-                                     sigdata, siglen, bulkdata);
-#endif
-               }
-               else
-               {
-
-#if (defined(CSR_SUPPORT_SME) && defined(CSR_WIFI_SECURITY_WAPI_ENABLE))
-                   #define CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET    sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22
-                   netInterface_priv_t *interfacePriv;
-                   u8 interfaceTag;
-                   u16 receptionStatus = CSR_RX_SUCCESS;
-
-                   /* Pull out interface tag from virtual interface identifier */
-                   interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff;
-                   interfacePriv = priv->interfacePriv[interfaceTag];
-
-                   /* check for MIC failure */
-                   receptionStatus = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET);
-
-                   /* Send a WAPI MPDU to SME for re-check MIC if the respective filter has been set*/
-                   if ((!freeBulkData) &&
-                       (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) &&
-                       (receptionStatus == CSR_MICHAEL_MIC_ERROR) &&
-                       ((priv->wapi_multicast_filter == 1)
-#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
-                         || (priv->wapi_unicast_filter == 1)
-#endif
-                       ))
-                   {
-                       CSR_SIGNAL signal;
-                       u8 *destAddr;
-                       CsrResult res;
-                       u16 interfaceTag = 0;
-                       u8 isMcastPkt = TRUE;
-
-                       unifi_trace(priv, UDBG6, "Received a WAPI data packet when the Unicast/Multicast filter is set\n");
-                       res = read_unpack_signal(sigdata, &signal);
-                       if (res) {
-                           unifi_error(priv, "Received unknown or corrupted signal (0x%x).\n",
-                                       CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));
-                           return;
-                       }
-
-                       /* Check if the type of MPDU and the respective filter status*/
-                       destAddr = (u8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET;
-                       isMcastPkt = (destAddr[0] & 0x01) ? TRUE : FALSE;
-                       unifi_trace(priv, UDBG6,
-                                   "1.MPDU type: (%s), 2.Multicast filter: (%s), 3. Unicast filter: (%s)\n",
-                                   ((isMcastPkt) ? "Multiast":"Unicast"),
-                                   ((priv->wapi_multicast_filter) ? "Enabled":"Disabled"),
-                                   ((priv->wapi_unicast_filter)  ? "Enabled":"Disabled"));
-
-                       if (((isMcastPkt) && (priv->wapi_multicast_filter == 1))
-#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
-                           || ((!isMcastPkt) && (priv->wapi_unicast_filter == 1))
-#endif
-                          )
-                        {
-                            unifi_trace(priv, UDBG4, "Sending the WAPI MPDU for MIC check\n");
-                            CsrWifiRouterCtrlWapiRxMicCheckIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (u8*)bulkdata->d[0].os_data_ptr);
-
-                            for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
-                                if (bulkdata->d[i].data_length != 0) {
-                                    unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
-                                }
-                           }
-                           return;
-                       }
-                   } /* CSR_MA_PACKET_INDICATION_ID */
-#endif /*CSR_SUPPORT_SME && CSR_WIFI_SECURITY_WAPI_ENABLE*/
-               }
-        }
-
-        /* calls the registered clients handler callback func.
-         * netdev_mlme_event_handler is one of the registered handler used to route
-         * data packet to network stack or AMP/EAPOL related data to SME
-         *
-         * The freeBulkData check ensures that, it has received a management frame and
-         * the frame needs to be freed here. So not to be passed to netdev handler
-         */
-        if(!freeBulkData){
-            if ((client_id < MAX_UDI_CLIENTS) &&
-                    (&priv->ul_clients[client_id] != priv->logging_client)) {
-            	unifi_trace(priv, UDBG6, "Call the registered clients handler callback func\n");
-                send_to_client(priv, &priv->ul_clients[client_id],
-                        receiver_id,
-                        sigdata, siglen, bulkdata);
-            }
-        }
-    }
-
-    /*
-     * Free bulk data buffers here unless it is a CSR_MA_PACKET_INDICATION
-     */
-    switch (signal_id)
-    {
-#ifdef UNIFI_SNIFF_ARPHRD
-        case CSR_MA_SNIFFDATA_INDICATION_ID:
-#endif
-            break;
-
-        case CSR_MA_PACKET_INDICATION_ID:
-            if (!freeBulkData)
-            {
-                break;
-            }
-            /* FALLS THROUGH... */
-        default:
-            for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
-                if (bulkdata->d[i].data_length != 0) {
-                    unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
-                }
-            }
-    }
-
-} /* unifi_process_receive_event() */
-
-
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-static u8 signal_buffer_is_full(unifi_priv_t* priv)
-{
-    return (((priv->rxSignalBuffer.writePointer + 1)% priv->rxSignalBuffer.size) == (priv->rxSignalBuffer.readPointer));
-}
-
-void unifi_rx_queue_flush(void *ospriv)
-{
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-
-    unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr =  %d\n",
-                priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer);
-    if(priv != NULL) {
-        u8 readPointer = priv->rxSignalBuffer.readPointer;
-        while (readPointer != priv->rxSignalBuffer.writePointer)
-        {
-             rx_buff_struct_t *buf = &priv->rxSignalBuffer.rx_buff[readPointer];
-             unifi_trace(priv, UDBG6, "rx_wq_handler: RdPtr = %d WritePtr =  %d\n",
-                         readPointer,priv->rxSignalBuffer.writePointer);
-             unifi_process_receive_event(priv, buf->bufptr, buf->sig_len, &buf->data_ptrs);
-             readPointer ++;
-             if(readPointer >= priv->rxSignalBuffer.size) {
-                    readPointer = 0;
-             }
-        }
-        priv->rxSignalBuffer.readPointer = readPointer;
-    }
-}
-
-void rx_wq_handler(struct work_struct *work)
-{
-    unifi_priv_t *priv = container_of(work, unifi_priv_t, rx_work_struct);
-    unifi_rx_queue_flush(priv);
-}
-#endif
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  unifi_receive_event
- *
- *      Dispatcher for received signals.
- *
- *      This function receives the 'to host' signals and forwards
- *      them to the unifi linux clients.
- *
- *  Arguments:
- *      ospriv      Pointer to driver's private data.
- *      sigdata     Pointer to the packed signal buffer.
- *      siglen      Length of the packed signal.
- *      bulkdata    Pointer to the signal's bulk data.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *  The signals are received in the format described in the host interface
- *  specification, i.e wire formatted. Certain clients use the same format
- *  to interpret them and other clients use the host formatted structures.
- *  Each client has to call read_unpack_signal() to transform the wire
- *  formatted signal into the host formatted signal, if necessary.
- *  The code is in the core, since the signals are defined therefore
- *  binded to the host interface specification.
- * ---------------------------------------------------------------------------
- */
-void
-unifi_receive_event(void *ospriv,
-                    u8 *sigdata, u32 siglen,
-                    const bulk_data_param_t *bulkdata)
-{
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-    u8 writePointer;
-    int i;
-    rx_buff_struct_t * rx_buff;
-
-    unifi_trace(priv, UDBG5, "unifi_receive_event: "
-            "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
-            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*0) & 0xFFFF,
-            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*1) & 0xFFFF,
-            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*2) & 0xFFFF,
-            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*3) & 0xFFFF,
-            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*4) & 0xFFFF,
-            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*5) & 0xFFFF,
-            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*6) & 0xFFFF,
-            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*7) & 0xFFFF, siglen);
-    if(signal_buffer_is_full(priv)) {
-        unifi_error(priv,"TO HOST signal queue FULL dropping the PDU\n");
-        for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
-            if (bulkdata->d[i].data_length != 0) {
-                unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
-            }
-        }
-        return;
-    }
-    writePointer = priv->rxSignalBuffer.writePointer;
-    rx_buff = &priv->rxSignalBuffer.rx_buff[writePointer];
-    memcpy(rx_buff->bufptr,sigdata,siglen);
-    rx_buff->sig_len = siglen;
-    rx_buff->data_ptrs = *bulkdata;
-    writePointer++;
-    if(writePointer >= priv->rxSignalBuffer.size) {
-        writePointer =0;
-    }
-    unifi_trace(priv, UDBG4, "unifi_receive_event:writePtr = %d\n",priv->rxSignalBuffer.writePointer);
-    priv->rxSignalBuffer.writePointer = writePointer;
-
-#ifndef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
-    queue_work(priv->rx_workqueue, &priv->rx_work_struct);
-#endif
-
-#else
-    unifi_process_receive_event(ospriv, sigdata, siglen, bulkdata);
-#endif
-} /* unifi_receive_event() */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifiio.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifiio.h
--- linux-libre-3.10-gnu/drivers/staging/csr/unifiio.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifiio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,398 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *
- *  FILE: unifiio.h
- *
- *      Public definitions for the UniFi linux driver.
- *      This is mostly ioctl command values and structs.
- *
- *      Include <sys/ioctl.h> or similar before this file
- *
- * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#ifndef __UNIFIIO_H__
-#define __UNIFIIO_H__
-
-#include <linux/types.h>
-
-#define UNIFI_GET_UDI_ENABLE    _IOR('u',  1, int)
-#define UNIFI_SET_UDI_ENABLE    _IOW('u',  2, int)
-/* Values for UDI_ENABLE */
-#define UDI_ENABLE_DATA         0x1
-#define UDI_ENABLE_CONTROL      0x2
-
-/* MIB set/get. Arg is a pointer to a varbind */
-#define UNIFI_GET_MIB           _IOWR('u',  3, unsigned char *)
-#define UNIFI_SET_MIB           _IOW ('u',  4, unsigned char *)
-#define MAX_VARBIND_LENGTH 127
-
-/* Private IOCTLs */
-#define SIOCIWS80211POWERSAVEPRIV           SIOCIWFIRSTPRIV
-#define SIOCIWG80211POWERSAVEPRIV           SIOCIWFIRSTPRIV + 1
-#define SIOCIWS80211RELOADDEFAULTSPRIV      SIOCIWFIRSTPRIV + 2
-#define SIOCIWSCONFWAPIPRIV                 SIOCIWFIRSTPRIV + 4
-#define SIOCIWSWAPIKEYPRIV                  SIOCIWFIRSTPRIV + 6
-#define SIOCIWSSMEDEBUGPRIV                 SIOCIWFIRSTPRIV + 8
-#define SIOCIWSAPCFGPRIV                    SIOCIWFIRSTPRIV + 10
-#define SIOCIWSAPSTARTPRIV                  SIOCIWFIRSTPRIV + 12
-#define SIOCIWSAPSTOPPRIV                   SIOCIWFIRSTPRIV + 14
-#define SIOCIWSFWRELOADPRIV                 SIOCIWFIRSTPRIV + 16
-#define SIOCIWSSTACKSTART                   SIOCIWFIRSTPRIV + 18
-#define SIOCIWSSTACKSTOP                    SIOCIWFIRSTPRIV + 20
-
-
-
-#define IWPRIV_POWER_SAVE_MAX_STRING 32
-#define IWPRIV_SME_DEBUG_MAX_STRING 32
-#define IWPRIV_SME_MAX_STRING 120
-
-
-/* Private configuration commands */
-#define UNIFI_CFG               _IOWR('u',  5, unsigned char *)
-/*
- * <------------------  Read/Write Buffer  -------------------->
- * _____________________________________________________________
- * |    Cmd    |    Arg    |   ...  Buffer (opt)  ...          |
- * -------------------------------------------------------------
- * <-- uint --><-- uint --><-----  unsigned char buffer  ------>
- *
- * Cmd:    A unifi_cfg_command_t command.
- * Arg:    Out:Length     if Cmd==UNIFI_CFG_GET
- *         In:PowerOnOff  if Cmd==UNIFI_CFG_POWER
- *         In:PowerMode   if Cmd==UNIFI_CFG_POWERSAVE
- *         In:Length      if Cmd==UNIFI_CFG_FILTER
- *         In:WMM Qos Info if Cmd==UNIFI_CFG_WMM_QOS_INFO
- * Buffer: Out:Data       if Cmd==UNIFI_CFG_GET
- *         NULL           if Cmd==UNIFI_CFG_POWER
- *         NULL           if Cmd==UNIFI_CFG_POWERSAVE
- *         In:Filters     if Cmd==UNIFI_CFG_FILTER
- *
- * where Filters is a uf_cfg_bcast_packet_filter_t structure
- * followed by 0 - n tclas_t structures. The length of the tclas_t
- * structures is obtained by uf_cfg_bcast_packet_filter_t::tclas_ies_length.
- */
-
-
-#define UNIFI_PUTEST            _IOWR('u',  6, unsigned char *)
-/*
- * <------------------  Read/Write Buffer  -------------------->
- * _____________________________________________________________
- * |    Cmd    |    Arg    |   ...  Buffer (opt)  ...          |
- * -------------------------------------------------------------
- * <-- uint --><-- uint --><-----  unsigned char buffer  ------>
- *
- * Cmd:    A unifi_putest_command_t command.
- * Arg:    N/A                           if Cmd==UNIFI_PUTEST_START
- *         N/A                           if Cmd==UNIFI_PUTEST_STOP
- *         In:int (Clock Speed)          if Cmd==UNIFI_PUTEST_SET_SDIO_CLOCK
- *         In/Out:sizeof(unifi_putest_cmd52) if Cmd==UNIFI_PUTEST_CMD52_READ
- *         In:sizeof(unifi_putest_cmd52) if Cmd==UNIFI_PUTEST_CMD52_WRITE
- *         In:uint (f/w file name length) if Cmd==UNIFI_PUTEST_DL_FW
- * Buffer: NULL                          if Cmd==UNIFI_PUTEST_START
- *         NULL                          if Cmd==UNIFI_PUTEST_STOP
- *         NULL                          if Cmd==UNIFI_PUTEST_SET_SDIO_CLOCK
- *         In/Out:unifi_putest_cmd52     if Cmd==UNIFI_PUTEST_CMD52_READ
- *         In:unifi_putest_cmd52         if Cmd==UNIFI_PUTEST_CMD52_WRITE
- *         In:f/w file name              if Cmd==UNIFI_PUTEST_DL_FW
- */
-
-#define UNIFI_BUILD_TYPE _IOWR('u', 7, unsigned char)
-#define UNIFI_BUILD_NME 1
-#define UNIFI_BUILD_WEXT 2
-#define UNIFI_BUILD_AP 3
-
-/* debugging */
-#define UNIFI_KICK              _IO ('u',  0x10)
-#define UNIFI_SET_DEBUG         _IO ('u',  0x11)
-#define UNIFI_SET_TRACE         _IO ('u',  0x12)
-
-#define UNIFI_GET_INIT_STATUS   _IOR ('u', 0x15, int)
-#define UNIFI_SET_UDI_LOG_MASK  _IOR('u',  0x18, unifiio_filter_t)
-#define UNIFI_SET_UDI_SNAP_MASK _IOW('u',  0x1a, unifiio_snap_filter_t)
-#define UNIFI_SET_AMP_ENABLE    _IOWR('u',  0x1b, int)
-
-#define UNIFI_INIT_HW           _IOR ('u', 0x13, unsigned char)
-#define UNIFI_INIT_NETDEV       _IOW ('u', 0x14, unsigned char[6])
-#define UNIFI_SME_PRESENT       _IOW ('u', 0x19, int)
-
-#define UNIFI_CFG_PERIOD_TRAFFIC _IOW ('u', 0x21, unsigned char *)
-#define UNIFI_CFG_UAPSD_TRAFFIC _IOW ('u', 0x22, unsigned char)
-
-#define UNIFI_COREDUMP_GET_REG  _IOWR('u', 0x23, unifiio_coredump_req_t)
-
-
-/*
- * Following reset, f/w may only be downloaded using CMD52.
- * This is slow, so there is a facility to download a secondary
- * loader first which supports CMD53.
- * If loader_len is > 0, then loader_data is assumed to point to
- * a suitable secondary loader that can be used to download the
- * main image.
- *
- * The driver will run the host protocol initialisation sequence
- * after downloading the image.
- *
- * If both lengths are zero, then the f/w is assumed to have been
- * booted from Flash and the host protocol initialisation sequence
- * is run.
- */
-typedef struct {
-
-    /* Number of bytes in the image */
-    int img_len;
-
-    /* Pointer to image data. */
-    unsigned char *img_data;
-
-
-    /* Number of bytes in the loader image */
-    int loader_len;
-
-    /* Pointer to loader image data. */
-    unsigned char *loader_data;
-
-} unifiio_img_t;
-
-
-/* Structure of data read from the unifi device. */
-typedef struct
-{
-    /* Length (in bytes) of entire structure including appended bulk data */
-    int length;
-
-    /* System time (in milliseconds) that signal was transferred */
-    int timestamp;
-
-    /* Direction in which signal was transferred. */
-    int direction;
-#define UDI_FROM_HOST   0
-#define UDI_TO_HOST     1
-#define UDI_CONFIG_IND  2
-
-    /* The length of the signal (in bytes) not including bulk data */
-    int signal_length;
-
-    /* Signal body follows, then any bulk data */
-
-} udi_msg_t;
-
-
-typedef enum
-{
-    UfSigFil_AllOn = 0,         /* Log all signal IDs */
-    UfSigFil_AllOff = 1,        /* Don't log any signal IDs */
-    UfSigFil_SelectOn = 2,      /* Log these signal IDs */
-    UfSigFil_SelectOff = 3      /* Don't log these signal IDs */
-} uf_sigfilter_action_t;
-
-typedef struct {
-
-    /* Number of 16-bit ints in the sig_ids array */
-    int num_sig_ids;
-    /* The action to perform */
-    uf_sigfilter_action_t action;
-    /* List of signal IDs to pass or block */
-    unsigned short *sig_ids;
-
-} unifiio_filter_t;
-
-
-typedef struct {
-    /* Number of 16-bit ints in the protocols array */
-    u16 count;
-    /* List of protocol ids to pass */
-    u16 *protocols;
-} unifiio_snap_filter_t;
-
-
-
-typedef u8 unifi_putest_command_t;
-
-#define UNIFI_PUTEST_START 0
-#define UNIFI_PUTEST_STOP 1
-#define UNIFI_PUTEST_SET_SDIO_CLOCK 2
-#define UNIFI_PUTEST_CMD52_READ 3
-#define UNIFI_PUTEST_CMD52_WRITE 4
-#define UNIFI_PUTEST_DL_FW 5
-#define UNIFI_PUTEST_DL_FW_BUFF 6
-#define UNIFI_PUTEST_CMD52_BLOCK_READ 7
-#define UNIFI_PUTEST_COREDUMP_PREPARE 8
-#define UNIFI_PUTEST_GP_READ16 9
-#define UNIFI_PUTEST_GP_WRITE16 10
-
-
-struct unifi_putest_cmd52 {
-    int funcnum;
-    unsigned long addr;
-    unsigned char data;
-};
-
-
-struct unifi_putest_block_cmd52_r {
-    int           funcnum;
-    unsigned long addr;
-    unsigned int  length;
-    unsigned char *data;
-};
-
-struct unifi_putest_gp_rw16 {
-    unsigned long addr;        /* generic address */
-    unsigned short data;
-};
-
-typedef enum unifi_cfg_command {
-    UNIFI_CFG_GET,
-    UNIFI_CFG_POWER,
-    UNIFI_CFG_POWERSAVE,
-    UNIFI_CFG_FILTER,
-    UNIFI_CFG_POWERSUPPLY,
-    UNIFI_CFG_WMM_QOSINFO,
-    UNIFI_CFG_WMM_ADDTS,
-    UNIFI_CFG_WMM_DELTS,
-    UNIFI_CFG_STRICT_DRAFT_N,
-    UNIFI_CFG_ENABLE_OKC,
-    UNIFI_CFG_SET_AP_CONFIG,
-    UNIFI_CFG_CORE_DUMP /* request to take a fw core dump */
-} unifi_cfg_command_t;
-
-typedef enum unifi_cfg_power {
-    UNIFI_CFG_POWER_UNSPECIFIED,
-    UNIFI_CFG_POWER_OFF,
-    UNIFI_CFG_POWER_ON
-} unifi_cfg_power_t;
-
-typedef enum unifi_cfg_powersupply {
-    UNIFI_CFG_POWERSUPPLY_UNSPECIFIED,
-    UNIFI_CFG_POWERSUPPLY_MAINS,
-    UNIFI_CFG_POWERSUPPLY_BATTERIES
-} unifi_cfg_powersupply_t;
-
-typedef enum unifi_cfg_powersave {
-    UNIFI_CFG_POWERSAVE_UNSPECIFIED,
-    UNIFI_CFG_POWERSAVE_NONE,
-    UNIFI_CFG_POWERSAVE_FAST,
-    UNIFI_CFG_POWERSAVE_FULL,
-    UNIFI_CFG_POWERSAVE_AUTO
-} unifi_cfg_powersave_t;
-
-typedef enum unifi_cfg_get {
-    UNIFI_CFG_GET_COEX,
-    UNIFI_CFG_GET_POWER_MODE,
-    UNIFI_CFG_GET_VERSIONS,
-    UNIFI_CFG_GET_POWER_SUPPLY,
-    UNIFI_CFG_GET_INSTANCE,
-    UNIFI_CFG_GET_AP_CONFIG
-} unifi_cfg_get_t;
-
-#define UNIFI_CFG_FILTER_NONE            0x0000
-#define UNIFI_CFG_FILTER_DHCP            0x0001
-#define UNIFI_CFG_FILTER_ARP             0x0002
-#define UNIFI_CFG_FILTER_NBNS            0x0004
-#define UNIFI_CFG_FILTER_NBDS            0x0008
-#define UNIFI_CFG_FILTER_CUPS            0x0010
-#define UNIFI_CFG_FILTER_ALL             0xFFFF
-
-
-typedef struct uf_cfg_bcast_packet_filter
-{
-    unsigned long filter_mode;     //as defined by HIP protocol
-    unsigned char arp_filter;
-    unsigned char dhcp_filter;
-    unsigned long tclas_ies_length; // length of tclas_ies in bytes
-    unsigned char tclas_ies[1];    // variable length depending on above field
-} uf_cfg_bcast_packet_filter_t;
-
-typedef struct uf_cfg_ap_config
-{
-    u8    phySupportedBitmap;
-    u8    channel;
-    u16   beaconInterval;
-    u8    dtimPeriod;
-    u8     wmmEnabled;
-    u8    shortSlotTimeEnabled;
-    u16   groupkeyTimeout;
-    u8     strictGtkRekeyEnabled;
-    u16   gmkTimeout;
-    u16   responseTimeout;
-    u8    retransLimit;
-    u8    rxStbc;
-    u8     rifsModeAllowed;
-    u8    dualCtsProtection;
-    u8    ctsProtectionType;
-    u16   maxListenInterval;
-}uf_cfg_ap_config_t;
-
-typedef struct tcpic_clsfr
-{
-    __u8 cls_fr_type;
-    __u8 cls_fr_mask;
-    __u8 version;
-    __u8 source_ip_addr[4];
-    __u8 dest_ip_addr[4];
-    __u16 source_port;
-    __u16 dest_port;
-    __u8 dscp;
-    __u8 protocol;
-    __u8 reserved;
-} __attribute__ ((packed)) tcpip_clsfr_t;
-
-typedef struct tclas {
-    __u8 element_id;
-    __u8 length;
-    __u8 user_priority;
-    tcpip_clsfr_t tcp_ip_cls_fr;
-} __attribute__ ((packed)) tclas_t;
-
-
-#define CONFIG_IND_ERROR            0x01
-#define CONFIG_IND_EXIT             0x02
-#define CONFIG_SME_NOT_PRESENT      0x10
-#define CONFIG_SME_PRESENT          0x20
-
-/* WAPI Key */
-typedef struct
-{
-    u8                          unicastKey;
-    /* If non zero, then unicast key otherwise group key */
-    u8                          keyIndex;
-    u8                          keyRsc[16];
-    u8                          authenticator;
-    /* If non zero, then authenticator otherwise supplicant */
-    u8                          address[6];
-    u8                          key[32];
-} unifiio_wapi_key_t;
-
-/* Values describing XAP memory regions captured by the mini-coredump system */
-typedef enum unifiio_coredump_space {
-    UNIFIIO_COREDUMP_MAC_REG,
-    UNIFIIO_COREDUMP_PHY_REG,
-    UNIFIIO_COREDUMP_SH_DMEM,
-    UNIFIIO_COREDUMP_MAC_DMEM,
-    UNIFIIO_COREDUMP_PHY_DMEM,
-    UNIFIIO_COREDUMP_TRIGGER_MAGIC = 0xFEED
-} unifiio_coredump_space_t;
-
-/* Userspace tool uses this structure to retrieve a register value from a
- * mini-coredump buffer previously saved by the HIP
- */
-typedef struct unifiio_coredump_req {
-    /* From user */
-    int index;                      /* 0=newest, -1=oldest */
-    unsigned int offset;            /* register offset in space */
-    unifiio_coredump_space_t space; /* memory space */
-    /* Filled by driver */
-    unsigned int drv_build;         /* driver build id */
-    unsigned int chip_ver;          /* chip version */
-    unsigned int fw_ver;            /* firmware version */
-    int requestor;                  /* requestor: 0=auto dump, 1=manual */
-    unsigned int timestamp;         /* time of capture by driver */
-    unsigned int serial;            /* capture serial number */
-    int value;                      /* 16 bit register value, -ve for error */
-} unifiio_coredump_req_t;           /* Core-dumped register value request */
-
-#endif /* __UNIFIIO_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_native.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_native.h
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_native.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_native.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,257 +0,0 @@
-/*
- *****************************************************************************
- *
- * FILE : unifi_native.h
- *
- * PURPOSE : Private header file for unifi driver support to wireless extensions.
- *
- *           UDI = UniFi Debug Interface
- *
- * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- *****************************************************************************
- */
-#ifndef __LINUX_UNIFI_NATIVE_H__
-#define __LINUX_UNIFI_NATIVE_H__ 1
-
-#include <linux/kernel.h>
-#include <linux/if_arp.h>
-
-
-/*
- *      scan.c wext.c autojoin.c
- */
-/* Structure to hold results of a scan */
-typedef struct scan_info {
-
-/*    CSR_MLME_SCAN_INDICATION msi; */
-
-    unsigned char *info_elems;
-    int info_elem_length;
-
-} scan_info_t;
-
-
-#define IE_VECTOR_MAXLEN 1024
-
-#ifdef CSR_SUPPORT_WEXT
-/*
- * Structre to hold the wireless network configuration info.
- */
-struct wext_config {
-
-    /* Requested channel when setting up an adhoc network */
-    int channel;
-
-    /* wireless extns mode: IW_MODE_AUTO, ADHOC, INFRA, MASTER ... MONITOR */
-    int mode;
-
-    /* The capabilities of the currently joined network */
-    int capability;
-
-    /* The interval between beacons if we create an IBSS */
-    int beacon_period;
-
-    /*
-    * Power-save parameters
-    */
-    /* The listen interval to ask for in Associate req. */
-    int assoc_listen_interval;
-    /* Power-mode to put UniFi into */
-
-    unsigned char desired_ssid[UNIFI_MAX_SSID_LEN];     /* the last ESSID set by SIOCSIWESSID */
-    int power_mode;
-    /* Whether to wake for broadcast packets (using DTIM interval) */
-    int wakeup_for_dtims;
-
-    /* Currently selected WEP Key ID (0..3) */
-    int wep_key_id;
-
-    wep_key_t wep_keys[NUM_WEPKEYS];
-
-/*    CSR_AUTHENTICATION_TYPE auth_type; */
-    int privacy;
-
-    u32 join_failure_timeout;
-    u32 auth_failure_timeout;
-    u32 assoc_failure_timeout;
-
-    unsigned char generic_ie[IE_VECTOR_MAXLEN];
-    int generic_ie_len;
-
-    struct iw_statistics wireless_stats;
-
-
-    /* the ESSID we are currently associated to */
-    unsigned char current_ssid[UNIFI_MAX_SSID_LEN];
-    /* the BSSID we are currently associated to */
-    unsigned char current_bssid[6];
-
-    /*
-    * IW_AUTH_WPA_VERSION_DISABLED 0x00000001
-    * IW_AUTH_WPA_VERSION_WPA      0x00000002
-    * IW_AUTH_WPA_VERSION_WPA2     0x00000004
-    */
-    unsigned char wpa_version;
-
-    /*
-     * cipher selection:
-    * IW_AUTH_CIPHER_NONE	0x00000001
-    * IW_AUTH_CIPHER_WEP40	0x00000002
-    * IW_AUTH_CIPHER_TKIP	0x00000004
-    * IW_AUTH_CIPHER_CCMP	0x00000008
-    * IW_AUTH_CIPHER_WEP104	0x00000010
-    */
-    unsigned char pairwise_cipher_used;
-    unsigned char group_cipher_used;
-
-    unsigned int frag_thresh;
-    unsigned int rts_thresh;
-
-    /* U-APSD value, send with Association Request to WMM Enabled APs */
-    unsigned char wmm_bss_uapsd_mask;
-    /* The WMM capabilities of the selected BSS */
-    unsigned int bss_wmm_capabilities;
-
-    /* Flag to prevent a join when the ssid is set */
-    int disable_join_on_ssid_set;
-
-    /* Scan info */
-#define UNIFI_MAX_SCANS 32
-    scan_info_t scan_list[UNIFI_MAX_SCANS];
-    int num_scan_info;
-
-    /* Flag on whether non-802.1x packets are allowed out */
-/*    CsrWifiRouterPortAction block_controlled_port;*/
-
-    /* Flag on whether we have completed an authenticate/associate process */
-    unsigned int flag_associated        : 1;
-}; /* struct wext_config */
-
-#endif /* CSR_SUPPORT_WEXT */
-
-
-/*
- *      wext.c
- */
-/*int mlme_set_protection(unifi_priv_t *priv, unsigned char *addr,
-                        CSR_PROTECT_TYPE prot, CSR_KEY_TYPE key_type);
-*/
-
-/*
- * scan.c
- */
-/*
-void unifi_scan_indication_handler(unifi_priv_t *priv,
-                                   const CSR_MLME_SCAN_INDICATION *msg,
-                                   const unsigned char *extra,
-                                   unsigned int len);
-*/
-void unifi_clear_scan_table(unifi_priv_t *priv);
-scan_info_t *unifi_get_scan_report(unifi_priv_t *priv, int index);
-
-
-/*
- * Utility functions
- */
-const unsigned char *unifi_find_info_element(int id,
-                                             const unsigned char *info,
-                                             int len);
-int unifi_add_info_element(unsigned char *info,
-                           int ie_id,
-                           const unsigned char *ie_data,
-                           int ie_len);
-
-/*
- *      autojoin.c
- */
-/* Higher level fns */
-int unifi_autojoin(unifi_priv_t *priv, const char *ssid);
-/*
-int unifi_do_scan(unifi_priv_t *priv, int scantype, CSR_BSS_TYPE bsstype,
-                  const char *ssid, int ssid_len);
-*/
-int unifi_set_powermode(unifi_priv_t *priv);
-int unifi_join_ap(unifi_priv_t *priv, scan_info_t *si);
-int unifi_join_bss(unifi_priv_t *priv, unsigned char *macaddr);
-int unifi_leave(unifi_priv_t *priv);
-unsigned int unifi_get_wmm_bss_capabilities(unifi_priv_t *priv,
-                                            unsigned char *ie_vector,
-                                            int ie_len, int *ap_capabilities);
-
-/*
- * Status and management.
- */
-int uf_init_wext_interface(unifi_priv_t *priv);
-void uf_deinit_wext_interface(unifi_priv_t *priv);
-
-/*
- * Function to reset UniFi's 802.11 state by sending MLME-RESET.req
- */
-int unifi_reset_state(unifi_priv_t *priv, unsigned char *macaddr, unsigned char set_default_mib);
-
-
-/*
- *      mlme.c
- */
-/* Abort an MLME operation - useful in error recovery */
-int uf_abort_mlme(unifi_priv_t *priv);
-
-int unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli,
-                                CSR_SIGNAL *sig, bulk_data_param_t *data_ptrs,
-                                int timeout);
-void unifi_mlme_copy_reply_and_wakeup_client(ul_client_t *pcli,
-                                             CSR_SIGNAL *signal, int signal_len,
-                                             const bulk_data_param_t *bulkdata);
-
-/*
- * Utility functions
- */
-const char *lookup_reason_code(int reason);
-const char *lookup_result_code(int result);
-
-
-/*
- *      sme_native.c
- */
-int uf_sme_init(unifi_priv_t *priv);
-void uf_sme_deinit(unifi_priv_t *priv);
-int sme_sys_suspend(unifi_priv_t *priv);
-int sme_sys_resume(unifi_priv_t *priv);
-int sme_mgt_wifi_on(unifi_priv_t *priv);
-
-/* Callback for event logging to SME clients (unifi_manager) */
-void sme_native_log_event(ul_client_t *client,
-                          const u8 *sig_packed, int sig_len,
-                          const bulk_data_param_t *bulkdata,
-                          int dir);
-
-void sme_native_mlme_event_handler(ul_client_t *pcli,
-                                   const u8 *sig_packed, int sig_len,
-                                   const bulk_data_param_t *bulkdata,
-                                   int dir);
-
-/* Task to query statistics from the MIB */
-#define UF_SME_STATS_WQ_TIMEOUT     2000    /* in msecs */
-void uf_sme_stats_wq(struct work_struct *work);
-
-void uf_native_process_udi_signal(ul_client_t *pcli,
-                                  const u8 *packed_signal,
-                                  int packed_signal_len,
-                                  const bulk_data_param_t *bulkdata, int dir);
-#ifdef UNIFI_SNIFF_ARPHRD
-/*
- * monitor.c
- */
-int uf_start_sniff(unifi_priv_t *priv);
-/*
-void ma_sniffdata_ind(void *ospriv,
-                      const CSR_MA_SNIFFDATA_INDICATION *ind,
-                      const bulk_data_param_t *bulkdata);
-*/
-#endif /* ARPHRD_IEEE80211_PRISM */
-
-#endif /* __LINUX_UNIFI_NATIVE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_os.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_os.h
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_os.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_os.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,122 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- *
- * FILE: os_linux/unifi_os.h
- *
- * PURPOSE:
- *      This header file provides the OS-dependent facilities for a linux
- *      environment.
- *
- * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#ifndef __UNIFI_OS_LINUX_H__
-#define __UNIFI_OS_LINUX_H__ 1
-
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-
-/*
- * Needed for core/signals.c
- */
-#include <stddef.h>
-
-
-/* Define INLINE directive*/
-#define INLINE      inline
-
-/* Malloc and free */
-CsrResult unifi_net_data_malloc(void *ospriv, bulk_data_desc_t *bulk_data_slot, unsigned int size);
-void unifi_net_data_free(void *ospriv, bulk_data_desc_t *bulk_data_slot);
-#define CSR_WIFI_ALIGN_BYTES    4
-CsrResult unifi_net_dma_align(void *ospriv, bulk_data_desc_t *bulk_data_slot);
-
-/*
- * Byte Order
- * Note that __le*_to_cpu and __cpu_to_le* return an unsigned value!
- */
-#ifdef __KERNEL__
-#define unifi2host_16(n)	(__le16_to_cpu((n)))
-#define unifi2host_32(n)	(__le32_to_cpu((n)))
-#define host2unifi_16(n)	(__cpu_to_le16((n)))
-#define host2unifi_32(n)	(__cpu_to_le32((n)))
-#endif
-
-/* Module parameters */
-extern int unifi_debug;
-
-/* debugging */
-#ifdef UNIFI_DEBUG
-/*
- * unifi_debug is a verbosity level for debug messages
- * UDBG0 msgs are always printed if UNIFI_DEBUG is defined
- * UDBG1 msgs are printed if UNIFI_DEBUG is defined and unifi_debug > 0
- * etc.
- */
-
-#define ASSERT(cond)                                            \
-    do {                                                            \
-        if (!(cond)) {                                              \
-            printk("Assertion failed in %s at %s:%d: %s\n",         \
-                    __FUNCTION__, __FILE__, __LINE__, #cond);        \
-        }                                                           \
-    } while (0)
-
-
-void unifi_dump(void *ospriv, int lvl, const char *msg, void *mem, u16 len);
-void dump(void *mem, u16 len);
-void dump16(void *mem, u16 len);
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-void dump_str(void *mem, u16 len);
-#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */
-
-void unifi_error(void* ospriv, const char *fmt, ...);
-void unifi_warning(void* ospriv, const char *fmt, ...);
-void unifi_notice(void* ospriv, const char *fmt, ...);
-void unifi_info(void* ospriv, const char *fmt, ...);
-
-void unifi_trace(void* ospriv, int level, const char *fmt, ...);
-
-#else
-
-/* Stubs */
-
-#define ASSERT(cond)
-
-static inline void unifi_dump(void *ospriv, int lvl, const char *msg, void *mem, u16 len) {}
-static inline void dump(void *mem, u16 len) {}
-static inline void dump16(void *mem, u16 len) {}
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-static inline void dump_str(void *mem, u16 len) {}
-#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */
-
-void unifi_error_nop(void* ospriv, const char *fmt, ...);
-void unifi_trace_nop(void* ospriv, int level, const char *fmt, ...);
-#define unifi_error if(1);else unifi_error_nop
-#define unifi_warning if(1);else unifi_error_nop
-#define unifi_notice if(1);else unifi_error_nop
-#define unifi_info if(1);else unifi_error_nop
-#define unifi_trace if(1);else unifi_trace_nop
-
-#endif /* UNIFI_DEBUG */
-
-
-/* Different levels of diagnostic detail... */
-#define UDBG0       0   /* always prints in debug build */
-#define UDBG1       1
-#define UDBG2       2
-#define UDBG3       3
-#define UDBG4       4
-#define UDBG5       5
-#define UDBG6       6
-#define UDBG7       7
-
-
-#endif /* __UNIFI_OS_LINUX_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_pdu_processing.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_pdu_processing.c
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_pdu_processing.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_pdu_processing.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,3729 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     unifi_pdu_processing.c
- *
- * PURPOSE:
- *      This file provides the PDU handling functionality before it gets sent to unfi and after
- *      receiving a PDU from unifi
- *
- * Copyright (C) 2010 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-
-#include <linux/types.h>
-#include <linux/etherdevice.h>
-#include <linux/vmalloc.h>
-
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-#include "csr_time.h"
-#include "unifi_priv.h"
-#include <net/pkt_sched.h>
-
-#ifdef CSR_SUPPORT_SME
-static void _update_buffered_pkt_params_after_alignment(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
-                                                        tx_buffered_packets_t* buffered_pkt)
-{
-    struct sk_buff *skb ;
-    u32 align_offset;
-
-    if (priv == NULL || bulkdata == NULL || buffered_pkt == NULL){
-        return;
-    }
-
-    skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
-    align_offset = (u32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1);
-    if(align_offset){
-        skb_pull(skb,align_offset);
-    }
-
-    buffered_pkt->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
-    buffered_pkt->bulkdata.data_length = bulkdata->d[0].data_length;
-    buffered_pkt->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
-    buffered_pkt->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
-}
-#endif
-
-void
-unifi_frame_ma_packet_req(unifi_priv_t *priv, CSR_PRIORITY priority,
-                          CSR_RATE TransmitRate, CSR_CLIENT_TAG hostTag,
-                          u16 interfaceTag, CSR_TRANSMISSION_CONTROL transmissionControl,
-                          CSR_PROCESS_ID leSenderProcessId, u8 *peerMacAddress,
-                          CSR_SIGNAL *signal)
-{
-
-    CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest;
-    netInterface_priv_t *interfacePriv;
-    u8 ba_session_idx = 0;
-    ba_session_tx_struct *ba_session = NULL;
-    u8 *ba_addr = NULL;
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-	unifi_trace(priv, UDBG5,
-		"In unifi_frame_ma_packet_req, Frame for Peer: %pMF\n",
-		peerMacAddress);
-    signal->SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
-    signal->SignalPrimitiveHeader.ReceiverProcessId = 0;
-    signal->SignalPrimitiveHeader.SenderProcessId = leSenderProcessId;
-
-    /* Fill the MA-PACKET.req */
-    req->Priority = priority;
-    unifi_trace(priv, UDBG3, "Tx Frame with Priority: 0x%x\n", req->Priority);
-
-    /* A value of 0 is used for auto selection of rates. But for P2P GO case
-     * for action frames the rate is governed by SME. Hence instead of 0,
-     * the rate is filled in with the value passed here
-     */
-    req->TransmitRate = TransmitRate;
-
-    /* packets from netdev then no confirm required but packets from
-     * Nme/Sme eapol data frames requires the confirmation
-     */
-    req->TransmissionControl = transmissionControl;
-    req->VirtualInterfaceIdentifier =
-           uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag);
-    memcpy(req->Ra.x, peerMacAddress, ETH_ALEN);
-
-    if (hostTag == 0xffffffff) {
-        req->HostTag = interfacePriv->tag++;
-        req->HostTag |= 0x40000000;
-        unifi_trace(priv, UDBG3, "new host tag assigned = 0x%x\n", req->HostTag);
-        interfacePriv->tag &= 0x0fffffff;
-    } else {
-        req->HostTag = hostTag;
-        unifi_trace(priv, UDBG3, "host tag got from SME  = 0x%x\n", req->HostTag);
-    }
-    /* check if BA session exists for the peer MAC address on same tID */
-    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO){
-        ba_addr = peerMacAddress;
-    }else{
-        ba_addr = interfacePriv->bssid.a;
-    }
-    for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
-        ba_session = interfacePriv->ba_session_tx[ba_session_idx];
-        if (ba_session){
-           if ((!memcmp(ba_session->macAddress.a, ba_addr, ETH_ALEN)) && (ba_session->tID == priority)){
-                req->TransmissionControl |= CSR_ALLOW_BA;
-                break;
-            }
-        }
-    }
-
-    unifi_trace(priv, UDBG5, "leaving unifi_frame_ma_packet_req\n");
-}
-
-#ifdef CSR_SUPPORT_SME
-
-#define TRANSMISSION_CONTROL_TRIGGER_MASK 0x0001
-#define TRANSMISSION_CONTROL_EOSP_MASK 0x0002
-
-static
-int frame_and_send_queued_pdu(unifi_priv_t* priv,tx_buffered_packets_t* buffered_pkt,
-            CsrWifiRouterCtrlStaInfo_t *staRecord,u8 moreData , u8 eosp)
-{
-
-    CSR_SIGNAL signal;
-    bulk_data_param_t bulkdata;
-    int result;
-    u8 toDs, fromDs, macHeaderLengthInBytes = MAC_HEADER_SIZE;
-    u8 *qc;
-    u16 *fc = (u16*)(buffered_pkt->bulkdata.os_data_ptr);
-    unsigned long lock_flags;
-    unifi_trace(priv, UDBG3, "frame_and_send_queued_pdu with moreData: %d , EOSP: %d\n",moreData,eosp);
-    unifi_frame_ma_packet_req(priv, buffered_pkt->priority, buffered_pkt->rate, buffered_pkt->hostTag,
-               buffered_pkt->interfaceTag, buffered_pkt->transmissionControl,
-               buffered_pkt->leSenderProcessId, buffered_pkt->peerMacAddress.a, &signal);
-    bulkdata.d[0].os_data_ptr = buffered_pkt->bulkdata.os_data_ptr;
-    bulkdata.d[0].data_length = buffered_pkt->bulkdata.data_length;
-    bulkdata.d[0].os_net_buf_ptr = buffered_pkt->bulkdata.os_net_buf_ptr;
-    bulkdata.d[0].net_buf_length = buffered_pkt->bulkdata.net_buf_length;
-    bulkdata.d[1].os_data_ptr = NULL;
-    bulkdata.d[1].data_length = 0;
-    bulkdata.d[1].os_net_buf_ptr =0;
-    bulkdata.d[1].net_buf_length =0;
-
-    if(moreData) {
-        *fc |= cpu_to_le16(IEEE802_11_FC_MOREDATA_MASK);
-    } else {
-        *fc &= cpu_to_le16(~IEEE802_11_FC_MOREDATA_MASK);
-    }
-
-    if((staRecord != NULL)&& (staRecord->wmmOrQosEnabled == TRUE))
-    {
-        unifi_trace(priv, UDBG3, "frame_and_send_queued_pdu WMM Enabled: %d \n",staRecord->wmmOrQosEnabled);
-
-        toDs = (*fc & cpu_to_le16(IEEE802_11_FC_TO_DS_MASK))?1 : 0;
-        fromDs = (*fc & cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK))? 1: 0;
-
-        switch(le16_to_cpu(*fc) & IEEE80211_FC_SUBTYPE_MASK)
-        {
-            case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
-            case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK:
-                /* If both are set then the Address4 exists (only for AP) */
-                if (fromDs && toDs) {
-                    /* 6 is the size of Address4 field */
-                    macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6);
-                } else {
-                    macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
-                }
-
-                /* If order bit set then HT control field is the part of MAC header */
-                if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
-                    macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE;
-                    qc = (u8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6));
-                } else {
-                    qc = (u8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2));
-                }
-                *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4));
-                break;
-            default:
-                if (fromDs && toDs)
-                    macHeaderLengthInBytes += 6;
-        }
-
-    }
-    result = ul_send_signal_unpacked(priv, &signal, &bulkdata);
-    if(result){
-        _update_buffered_pkt_params_after_alignment(priv, &bulkdata,buffered_pkt);
-    }
-
- /* Decrement the packet counts queued in driver */
-    if (result != -ENOSPC) {
-        /* protect entire counter updation by disabling preemption */
-        if (!priv->noOfPktQueuedInDriver) {
-            unifi_error(priv, "packets queued in driver 0 still decrementing\n");
-        } else {
-            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-            priv->noOfPktQueuedInDriver--;
-            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-        }
-        /* Sta Record is available for all unicast (except genericMgt Frames) & in other case its NULL */
-        if (staRecord) {
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            if (!staRecord->noOfPktQueued) {
-                unifi_error(priv, "packets queued in driver per station is 0 still decrementing\n");
-            } else {
-                staRecord->noOfPktQueued--;
-            }
-            /* if the STA alive probe frame has failed then reset the saved host tag */
-            if (result){
-                if (staRecord->nullDataHostTag == buffered_pkt->hostTag){
-                    staRecord->nullDataHostTag = INVALID_HOST_TAG;
-                }
-            }
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-        }
-
-    }
-    return result;
-}
-#ifdef CSR_SUPPORT_SME
-static
-void set_eosp_transmit_ctrl(unifi_priv_t *priv, struct list_head *txList)
-{
-    /* dequeue the tx data packets from the appropriate queue */
-    tx_buffered_packets_t *tx_q_item = NULL;
-    struct list_head *listHead;
-    struct list_head *placeHolder;
-    unsigned long lock_flags;
-
-
-    unifi_trace(priv, UDBG5, "entering set_eosp_transmit_ctrl\n");
-    /* check for list empty */
-    if (list_empty(txList)) {
-        unifi_warning(priv, "In set_eosp_transmit_ctrl, the list is empty\n");
-        return;
-    }
-
-    /* return the last node , and modify it. */
-
-    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-    list_for_each_prev_safe(listHead, placeHolder, txList) {
-        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
-        tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
-        tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
-        unifi_trace(priv, UDBG1,
-                "set_eosp_transmit_ctrl Transmission Control = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag);
-        unifi_trace(priv,UDBG3,"in set_eosp_transmit_ctrl no.of buffered frames %d\n",priv->noOfPktQueuedInDriver);
-        break;
-    }
-    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-    unifi_trace(priv, UDBG1,"List Empty %d\n",list_empty(txList));
-    unifi_trace(priv, UDBG5, "leaving set_eosp_transmit_ctrl\n");
-    return;
-}
-
-static
-void send_vif_availibility_rsp(unifi_priv_t *priv,CSR_VIF_IDENTIFIER vif,CSR_RESULT_CODE resultCode)
-{
-    CSR_SIGNAL signal;
-    CSR_MA_VIF_AVAILABILITY_RESPONSE *rsp;
-    bulk_data_param_t *bulkdata = NULL;
-    int r;
-
-    unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : invoked with resultCode = %d \n", resultCode);
-
-    memset(&signal,0,sizeof(CSR_SIGNAL));
-    rsp = &signal.u.MaVifAvailabilityResponse;
-    rsp->VirtualInterfaceIdentifier = vif;
-    rsp->ResultCode = resultCode;
-    signal.SignalPrimitiveHeader.SignalId = CSR_MA_VIF_AVAILABILITY_RESPONSE_ID;
-    signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
-    signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
-
-    /* Send the signal to UniFi */
-    r = ul_send_signal_unpacked(priv, &signal, bulkdata);
-    if(r) {
-        unifi_error(priv,"Availibility response sending failed %x status %d\n",vif,r);
-    }
-    else {
-        unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : status = %d \n", r);
-    }
-}
-#endif
-
-static
-void verify_and_accomodate_tx_packet(unifi_priv_t *priv)
-{
-    tx_buffered_packets_t *tx_q_item;
-    unsigned long lock_flags;
-    struct list_head *listHead, *list;
-    struct list_head *placeHolder;
-    u8 i, j,eospFramedeleted=0;
-    u8 thresholdExcedeDueToBroadcast = TRUE;
-    /* it will be made it interface Specific in the future when multi interfaces are supported ,
-    right now interface 0 is considered */
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[0];
-    CsrWifiRouterCtrlStaInfo_t *staInfo = NULL;
-
-    unifi_trace(priv, UDBG3, "entering verify_and_accomodate_tx_packet\n");
-
-    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        staInfo = interfacePriv->staInfo[i];
-            if (staInfo && (staInfo->noOfPktQueued >= CSR_WIFI_DRIVER_MAX_PKT_QUEUING_THRESHOLD_PER_PEER)) {
-            /* remove the first(oldest) packet from the all the access catogory, since data
-             * packets for station record crossed the threshold limit (64 for AP supporting
-             * 8 peers)
-             */
-            unifi_trace(priv,UDBG3,"number of station pkts queued=  %d for sta id = %d\n", staInfo->noOfPktQueued, staInfo->aid);
-            for(j = 0; j < MAX_ACCESS_CATOGORY; j++) {
-                list = &staInfo->dataPdu[j];
-                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                list_for_each_safe(listHead, placeHolder, list) {
-                    tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
-                    list_del(listHead);
-                    thresholdExcedeDueToBroadcast = FALSE;
-                    unifi_net_data_free(priv, &tx_q_item->bulkdata);
-                    kfree(tx_q_item);
-                    tx_q_item = NULL;
-                    if (!priv->noOfPktQueuedInDriver) {
-                        unifi_error(priv, "packets queued in driver 0 still decrementing in %s\n", __FUNCTION__);
-                    } else {
-                        /* protection provided by spinlock */
-                        priv->noOfPktQueuedInDriver--;
-
-                    }
-                    /* Sta Record is available for all unicast (except genericMgt Frames) & in other case its NULL */
-                    if (!staInfo->noOfPktQueued) {
-                        unifi_error(priv, "packets queued in driver per station is 0 still decrementing in %s\n", __FUNCTION__);
-                    } else {
-                        spin_lock(&priv->staRecord_lock);
-                        staInfo->noOfPktQueued--;
-                        spin_unlock(&priv->staRecord_lock);
-                    }
-                    break;
-                }
-                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-            }
-        }
-    }
-    if (thresholdExcedeDueToBroadcast &&  interfacePriv->noOfbroadcastPktQueued > CSR_WIFI_DRIVER_MINIMUM_BROADCAST_PKT_THRESHOLD ) {
-        /* Remove the packets from genericMulticastOrBroadCastFrames queue
-         * (the max packets in driver is reached due to broadcast/multicast frames)
-         */
-        spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-        list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
-            tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
-            if(eospFramedeleted){
-                tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
-                tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
-                unifi_trace(priv, UDBG1,"updating eosp for next packet hostTag:= 0x%x ",tx_q_item->hostTag);
-                eospFramedeleted =0;
-                break;
-            }
-
-            if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK ){
-               eospFramedeleted = 1;
-            }
-            unifi_trace(priv,UDBG1, "freeing of multicast packets ToC = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag);
-            list_del(listHead);
-            unifi_net_data_free(priv, &tx_q_item->bulkdata);
-            kfree(tx_q_item);
-            priv->noOfPktQueuedInDriver--;
-            spin_lock(&priv->staRecord_lock);
-            interfacePriv->noOfbroadcastPktQueued--;
-            spin_unlock(&priv->staRecord_lock);
-            if(!eospFramedeleted){
-                break;
-            }
-        }
-        spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-    }
-    unifi_trace(priv, UDBG3, "leaving verify_and_accomodate_tx_packet\n");
-}
-
-static
-CsrResult enque_tx_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
-                            struct list_head *list, CSR_SIGNAL *signal,
-                            u8 requeueOnSamePos)
-{
-
-    /* queue the tx data packets on to appropriate queue */
-    CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest;
-    tx_buffered_packets_t *tx_q_item;
-    unsigned long lock_flags;
-
-    unifi_trace(priv, UDBG5, "entering enque_tx_data_pdu\n");
-    if(!list) {
-       unifi_error(priv,"List is not specified\n");
-       return CSR_RESULT_FAILURE;
-    }
-
-    /* Removes aged packets & adds the incoming packet */
-    if (priv->noOfPktQueuedInDriver >= CSR_WIFI_DRIVER_SUPPORT_FOR_MAX_PKT_QUEUEING) {
-        unifi_trace(priv,UDBG3,"number of pkts queued=  %d \n", priv->noOfPktQueuedInDriver);
-        verify_and_accomodate_tx_packet(priv);
-    }
-
-
-
-    tx_q_item = kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC);
-    if (tx_q_item == NULL) {
-        unifi_error(priv,
-                "Failed to allocate %d bytes for tx packet record\n",
-                sizeof(tx_buffered_packets_t));
-        return CSR_RESULT_FAILURE;
-    }
-
-    /* disable the preemption */
-    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-    INIT_LIST_HEAD(&tx_q_item->q);
-    /* fill the tx_q structure members */
-    tx_q_item->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
-    tx_q_item->bulkdata.data_length = bulkdata->d[0].data_length;
-    tx_q_item->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
-    tx_q_item->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
-    tx_q_item->interfaceTag = req->VirtualInterfaceIdentifier & 0xff;
-    tx_q_item->hostTag = req->HostTag;
-    tx_q_item->leSenderProcessId = signal->SignalPrimitiveHeader.SenderProcessId;
-    tx_q_item->transmissionControl = req->TransmissionControl;
-    tx_q_item->priority = req->Priority;
-    tx_q_item->rate = req->TransmitRate;
-    memcpy(tx_q_item->peerMacAddress.a, req->Ra.x, ETH_ALEN);
-
-
-
-    if (requeueOnSamePos) {
-        list_add(&tx_q_item->q, list);
-    } else {
-        list_add_tail(&tx_q_item->q, list);
-    }
-
-    /* Count of packet queued in driver */
-    priv->noOfPktQueuedInDriver++;
-    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-    unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n");
-    return CSR_RESULT_SUCCESS;
-}
-
-#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
-CsrResult unifi_reque_ma_packet_request (void *ospriv, u32 host_tag,
-                                         u16 txStatus, bulk_data_desc_t *bulkDataDesc)
-{
-    CsrResult status = CSR_RESULT_SUCCESS;
-    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-    netInterface_priv_t *interfacePriv;
-    struct list_head *list = NULL;
-    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
-    bulk_data_param_t bulkData;
-    CSR_SIGNAL signal;
-    CSR_PRIORITY priority = 0;
-    u16 interfaceTag = 0;
-    unifi_TrafficQueue priority_q;
-    u16 frameControl = 0, frameType = 0;
-    unsigned long lock_flags;
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    /* If the current mode is not AP or P2PGO then just return failure
-     * to clear the hip slot
-     */
-    if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
-        (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))) {
-        return CSR_RESULT_FAILURE;
-    }
-
-    unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: host_tag = 0x%x\n", host_tag);
-
-    staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,
-                                                                    (((u8 *) bulkDataDesc->os_data_ptr) + 4),
-                                                                    interfaceTag);
-    if (NULL == staRecord) {
-        unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid STA record \n");
-        return CSR_RESULT_FAILURE;
-    }
-
-    /* Update TIM if MA-PACKET.cfm fails with status as Tx-retry-limit or No-BSS and then just return failure
-     * to clear the hip slot associated with the Packet
-     */
-    if (CSR_TX_RETRY_LIMIT == txStatus || CSR_TX_NO_BSS == txStatus) {
-        if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING)
-        {
-            unifi_trace(priv, UDBG2, "unifi_reque_ma_packet_request: CFM failed with Retry Limit or No BSS-->update TIM\n");
-            if (!staRecord->timRequestPendingFlag) {
-                update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle);
-            }
-            else {
-                /* Cache the TimSet value so that it will processed immidiatly after
-                 * completing the current setTim Request
-                 */
-                staRecord->updateTimReqQueued = 1;
-                unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: One more UpdateTim Request(:%d)Queued for AID %x\n",
-                                         staRecord->updateTimReqQueued, staRecord->aid);
-            }
-        }
-        return CSR_RESULT_FAILURE;
-    }
-    else if ((CSR_TX_LIFETIME == txStatus) ||  (CSR_TX_BLOCK_ACK_TIMEOUT == txStatus) ||
-             (CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED == txStatus) ||
-             (CSR_TX_REJECTED_PEER_STATION_SLEEPING == txStatus)    ||
-             (CSR_TX_REJECTED_DTIM_STARTED == txStatus)) {
-        /* Extract the Frame control and the frame type */
-        frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr);
-        frameType =  ((frameControl & IEEE80211_FC_TYPE_MASK) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);
-
-        /* Mgmt frames will not be re-queued for Tx
-         * so just return failure to clear the hip slot
-         */
-        if (IEEE802_11_FRAMETYPE_MANAGEMENT == frameType) {
-            return CSR_RESULT_FAILURE;
-        }
-        else if (IEEE802_11_FRAMETYPE_DATA == frameType) {
-            /* QOS NULL and DATA NULL frames will not be re-queued for Tx
-             * so just return failure to clear the hip slot
-             */
-            if ((((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET) == QOS_DATA_NULL) ||
-                (((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET)== DATA_NULL )) {
-                return CSR_RESULT_FAILURE;
-            }
-        }
-
-        /* Extract the Packet priority */
-        if (TRUE == staRecord->wmmOrQosEnabled) {
-            u16 qosControl = 0;
-            u8  dataFrameType = 0;
-
-            dataFrameType =((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> 4);
-
-            if (dataFrameType == QOS_DATA) {
-                /* QoS control field is offset from frame control by 2 (frame control)
-                 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
-                 */
-                if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)) {
-                    qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 30);
-                }
-                else {
-                    qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 24);
-                }
-            }
-
-            priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
-
-            if (priority < CSR_QOS_UP0 || priority > CSR_QOS_UP7) {
-                unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid priority:%x \n", priority);
-                return CSR_RESULT_FAILURE;
-            }
-        }
-        else {
-            priority = CSR_CONTENTION;
-        }
-
-        /* Frame Bulk data to requeue it back to HAL Queues */
-        bulkData.d[0].os_data_ptr    = bulkDataDesc->os_data_ptr;
-        bulkData.d[0].data_length    = bulkDataDesc->data_length;
-        bulkData.d[0].os_net_buf_ptr = bulkDataDesc->os_net_buf_ptr;
-        bulkData.d[0].net_buf_length = bulkDataDesc->net_buf_length;
-
-        bulkData.d[1].os_data_ptr    = NULL;
-        bulkData.d[1].os_net_buf_ptr = NULL;
-        bulkData.d[1].data_length    = bulkData.d[1].net_buf_length = 0;
-
-        /* Initialize signal to zero */
-        memset(&signal, 0, sizeof(CSR_SIGNAL));
-
-        /* Frame MA Packet Req */
-        unifi_frame_ma_packet_req(priv, priority, 0, host_tag,
-                              interfaceTag, CSR_NO_CONFIRM_REQUIRED,
-                              priv->netdev_client->sender_id,
-                              staRecord->peerMacAddress.a, &signal);
-
-        /* Find the Q-Priority */
-        priority_q = unifi_frame_priority_to_queue(priority);
-        list = &staRecord->dataPdu[priority_q];
-
-        /* Place the Packet on to HAL Queue */
-        status = enque_tx_data_pdu(priv, &bulkData, list, &signal, TRUE);
-
-        /* Update the Per-station queued packet counter */
-        if (!status) {
-            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
-            staRecord->noOfPktQueued++;
-            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
-        }
-    }
-    else {
-        /* Packet will not be re-queued for any of the other MA Packet Tx failure
-         * reasons so just return failure to clear the hip slot
-         */
-        return CSR_RESULT_FAILURE;
-    }
-
-    return status;
-}
-#endif
-
-static void is_all_ac_deliver_enabled_and_moredata(CsrWifiRouterCtrlStaInfo_t *staRecord, u8 *allDeliveryEnabled, u8 *dataAvailable)
-{
-    u8 i;
-    *allDeliveryEnabled = TRUE;
-    for (i = 0 ;i < MAX_ACCESS_CATOGORY; i++) {
-        if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) {
-            /* One is is not Delivery Enabled */
-            *allDeliveryEnabled = FALSE;
-            break;
-        }
-    }
-    if (*allDeliveryEnabled) {
-        *dataAvailable = (!list_empty(&staRecord->dataPdu[0]) || !list_empty(&staRecord->dataPdu[1])
-                          ||!list_empty(&staRecord->dataPdu[2]) ||!list_empty(&staRecord->dataPdu[3])
-                          ||!list_empty(&staRecord->mgtFrames));
-    }
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_handle_tim_cfm
- *
- *
- *      This function updates tim status in host depending confirm status from firmware
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *      cfm             CSR_MLME_SET_TIM_CONFIRM
- *      receiverProcessId SenderProcessID to fetch handle & timSet status
- *
- * ---------------------------------------------------------------------------
- */
-void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, u16 receiverProcessId)
-{
-    u8 handle = CSR_WIFI_GET_STATION_HANDLE_FROM_RECEIVER_ID(receiverProcessId);
-    u8 timSetStatus = CSR_WIFI_GET_TIMSET_STATE_FROM_RECEIVER_ID(receiverProcessId);
-    u16 interfaceTag = (cfm->VirtualInterfaceIdentifier & 0xff);
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
-    /* This variable holds what TIM value we wanted to set in firmware */
-    u16 timSetValue = 0;
-    /* Irrespective of interface the count maintained */
-    static u8 retryCount = 0;
-    unsigned long lock_flags;
-    unifi_trace(priv, UDBG3, "entering %s, handle = %x, timSetStatus = %x\n", __FUNCTION__, handle, timSetStatus);
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_warning(priv, "bad interfaceTag = %x\n", interfaceTag);
-        return;
-    }
-
-    if ((handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) && (handle >= UNIFI_MAX_CONNECTIONS)) {
-        unifi_warning(priv, "bad station Handle = %x\n", handle);
-        return;
-    }
-
-    if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
-        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-        if ((staRecord = ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]))) == NULL) {
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-            unifi_warning(priv, "uf_handle_tim_cfm: station record is NULL  handle = %x\n", handle);
-            return;
-        }
-       spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-    }
-    switch(timSetStatus)
-    {
-        case CSR_WIFI_TIM_SETTING:
-            timSetValue = CSR_WIFI_TIM_SET;
-            break;
-        case CSR_WIFI_TIM_RESETTING:
-            timSetValue = CSR_WIFI_TIM_RESET;
-            break;
-        default:
-            unifi_warning(priv, "timSet state is %x: Debug\n", timSetStatus);
-            return;
-    }
-
-    /* check TIM confirm for success/failures */
-    switch(cfm->ResultCode)
-    {
-        case CSR_RC_SUCCESS:
-            if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
-                /* Unicast frame & station record available */
-                if (timSetStatus == staRecord->timSet) {
-                    staRecord->timSet = timSetValue;
-                    /* fh_cmd_q can also be full at some point of time!,
-                     * resetting count as queue is cleaned by firmware at this point
-                     */
-                    retryCount = 0;
-                    unifi_trace(priv, UDBG2, "tim (%s) successfully in firmware\n", (timSetValue)?"SET":"RESET");
-                } else {
-                    unifi_trace(priv, UDBG3, "receiver processID = %x, success: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x, handle = %x\n",
-                                 receiverProcessId, timSetStatus, staRecord->timSet, handle);
-                }
-
-                /* Reset TIM pending flag to send next TIM request */
-                staRecord->timRequestPendingFlag = FALSE;
-
-                /* Make sure that one more UpdateTim request is queued, if Queued its value
-                 * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
-                 */
-                if (0xFF != staRecord->updateTimReqQueued)
-                {
-                    /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
-                    if (staRecord->timSet != staRecord->updateTimReqQueued)
-                    {
-                       unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateTimReq \n");
-
-                       update_tim(priv, staRecord->aid, staRecord->updateTimReqQueued, interfaceTag, handle);
-
-                       staRecord->updateTimReqQueued = 0xFF;
-                    }
-                }
-            } else {
-
-                interfacePriv->bcTimSet = timSetValue;
-                /* fh_cmd_q can also be full at some point of time!,
-                 * resetting count as queue is cleaned by firmware at this point
-                 */
-                retryCount = 0;
-                unifi_trace(priv, UDBG3, "tim (%s) successfully for broadcast frame in firmware\n", (timSetValue)?"SET":"RESET");
-
-                /* Reset DTIM pending flag to send next DTIM request */
-                interfacePriv->bcTimSetReqPendingFlag = FALSE;
-
-                /* Make sure that one more UpdateDTim request is queued, if Queued its value
-                 * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
-                 */
-                if (0xFF != interfacePriv->bcTimSetReqQueued)
-                {
-                    /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
-                    if (interfacePriv->bcTimSet != interfacePriv->bcTimSetReqQueued)
-                    {
-                        unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateDTimReq \n");
-
-                        update_tim(priv, 0, interfacePriv->bcTimSetReqQueued, interfaceTag, 0xFFFFFFFF);
-
-                        interfacePriv->bcTimSetReqQueued = 0xFF;
-                    }
-                }
-
-            }
-            break;
-        case CSR_RC_INVALID_PARAMETERS:
-        case CSR_RC_INSUFFICIENT_RESOURCE:
-            /* check for max retry limit & send again
-             * MAX_RETRY_LIMIT is not maintained for each set of transactions..Its generic
-             * If failure crosses this Limit, we have to take a call to FIX
-             */
-            if (retryCount > UNIFI_MAX_RETRY_LIMIT) {
-                u8 moreData = FALSE;
-                retryCount = 0;
-                /* Because of continuos traffic in fh_cmd_q the tim set request is failing (exceeding retry limit)
-                 * but if we didn't synchronize our timSet varible state with firmware then it can cause below issues
-                 * cond 1. We want to SET tim in firmware if its fails & max retry limit reached
-                 *   -> If host set's the timSet to 1, we wont try to send(as max retry reached) update tim but
-                 *   firmware is not updated with queue(TIM) status so it wont set TIM in beacon finally host start piling
-                 *    up data & wont try to set tim in firmware (This can cause worser performance)
-                 * cond 2. We want to reset tim in firmware it fails & reaches max retry limit
-                 *   -> If host sets the timSet to Zero, it wont try to set a TIM request unless we wont have any packets
-                 *   to be queued, so beacon unnecessarily advertizes the TIM
-                 */
-
-                if(staRecord) {
-                    if(!staRecord->wmmOrQosEnabled) {
-                        moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
-                                !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
-                                !list_empty(&staRecord->mgtFrames));
-                    } else {
-                        /* Peer is QSTA */
-                        u8 allDeliveryEnabled = 0, dataAvailable = 0;
-                        /* Check if all AC's are Delivery Enabled */
-                        is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
-                        /*check for more data in non-delivery enabled queues*/
-                        moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable));
-
-                    }
-                    /* To avoid cond 1 & 2, check internal Queues status, if we have more Data then set RESET the timSet(0),
-                     *  so we are trying to be in sync with firmware & next packets before queuing atleast try to
-                     *  set TIM in firmware otherwise it SET timSet(1)
-                     */
-                    if (moreData) {
-                        staRecord->timSet = CSR_WIFI_TIM_RESET;
-                    } else {
-                        staRecord->timSet = CSR_WIFI_TIM_SET;
-                    }
-                } else {
-                    /* Its a broadcast frames */
-                    moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
-                               !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
-                    if (moreData) {
-                        update_tim(priv, 0, CSR_WIFI_TIM_SET, interfaceTag, 0xFFFFFFFF);
-                    } else {
-                        update_tim(priv, 0, CSR_WIFI_TIM_RESET, interfaceTag, 0xFFFFFFFF);
-                    }
-                }
-
-                unifi_error(priv, "no of error's for TIM setting crossed the Limit: verify\n");
-                return;
-            }
-            retryCount++;
-
-            if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
-                if (timSetStatus == staRecord->timSet) {
-                    unifi_warning(priv, "tim request failed, retry for AID = %x\n", staRecord->aid);
-                    update_tim(priv, staRecord->aid, timSetValue, interfaceTag, handle);
-                } else {
-                    unifi_trace(priv, UDBG1, "failure: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x\n",
-                                  timSetStatus, staRecord->timSet);
-                }
-            } else {
-                unifi_warning(priv, "tim request failed, retry for broadcast frames\n");
-                update_tim(priv, 0, timSetValue, interfaceTag, 0xFFFFFFFF);
-            }
-            break;
-        default:
-            unifi_warning(priv, "tim update request failed resultcode = %x\n", cfm->ResultCode);
-    }
-
-    unifi_trace(priv, UDBG2, "leaving %s\n", __FUNCTION__);
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  update_tim
- *
- *
- *      This function updates tim status in firmware for AID[1 to UNIFI_MAX_CONNECTIONS] or
- *       AID[0] for broadcast/multicast packets.
- *
- *      NOTE: The LSB (least significant BYTE) of senderId while sending this MLME premitive
- *       has been modified(utilized) as below
- *
- *       SenderID in signal's SignalPrimitiveHeader is 2 byte the lowe byte bitmap is below
- *
- *       station handle(6 bits)      timSet Status (2 bits)
- *       ---------------------       ----------------------
- *       0  0  0  0  0  0        |       0  0
- *
- * timSet Status can be one of below:
- *
- * CSR_WIFI_TIM_RESET
- * CSR_WIFI_TIM_RESETTING
- * CSR_WIFI_TIM_SET
- * CSR_WIFI_TIM_SETTING
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *      aid             can be 1 t0 UNIFI_MAX_CONNECTIONS & 0 means multicast/broadcast
- *      setTim          value SET(1) / RESET(0)
- *      interfaceTag    the interfaceID on which activity going on
- *      handle          from  (0 <= handle < UNIFI_MAX_CONNECTIONS)
- *
- * ---------------------------------------------------------------------------
- */
-void update_tim(unifi_priv_t * priv, u16 aid, u8 setTim, u16 interfaceTag, u32 handle)
-{
-    CSR_SIGNAL signal;
-    s32 r;
-    CSR_MLME_SET_TIM_REQUEST *req = &signal.u.MlmeSetTimRequest;
-    bulk_data_param_t *bulkdata = NULL;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    u8 senderIdLsb = 0;
-    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
-    u32 oldTimSetStatus = 0, timSetStatus = 0;
-
-    unifi_trace(priv, UDBG5, "entering the update_tim routine\n");
-
-
-    if (handle == 0xFFFFFFFF) {
-        handle &= CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE;
-        if (setTim == interfacePriv->bcTimSet)
-        {
-            unifi_trace(priv, UDBG3, "update_tim, Drop:Hdl=%x, timval=%d, globalTim=%d\n", handle, setTim, interfacePriv->bcTimSet);
-            return;
-        }
-    } else if ((handle != 0xFFFFFFFF) && (handle >= UNIFI_MAX_CONNECTIONS)) {
-        unifi_warning(priv, "bad station Handle = %x\n", handle);
-        return;
-    }
-
-    if (setTim) {
-        timSetStatus =  CSR_WIFI_TIM_SETTING;
-    } else {
-        timSetStatus =  CSR_WIFI_TIM_RESETTING;
-    }
-
-    if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
-        if ((staRecord = ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]))) == NULL) {
-            unifi_warning(priv, "station record is NULL in  update_tim: handle = %x :debug\n", handle);
-            return;
-        }
-        /* In case of signal sending failed, revert back to old state */
-        oldTimSetStatus = staRecord->timSet;
-        staRecord->timSet = timSetStatus;
-    }
-
-    /* pack senderID LSB */
-    senderIdLsb = CSR_WIFI_PACK_SENDER_ID_LSB_FOR_TIM_REQ(handle,  timSetStatus);
-
-    /* initialize signal to zero */
-    memset(&signal, 0, sizeof(CSR_SIGNAL));
-
-    /* Frame the MLME-SET-TIM request */
-    signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SET_TIM_REQUEST_ID;
-    signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
-    CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->netdev_client->sender_id & 0xff00) | senderIdLsb),
-                   (u8*)&signal.SignalPrimitiveHeader.SenderProcessId);
-
-    /* set The virtual interfaceIdentifier, aid, tim value */
-    req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag);
-    req->AssociationId = aid;
-    req->TimValue = setTim;
-
-
-    unifi_trace(priv, UDBG2, "update_tim:AID %x,senderIdLsb = 0x%x, handle = 0x%x, timSetStatus = %x, sender proceesID = %x \n",
-                aid,senderIdLsb, handle, timSetStatus, signal.SignalPrimitiveHeader.SenderProcessId);
-
-    /* Send the signal to UniFi */
-    r = ul_send_signal_unpacked(priv, &signal, bulkdata);
-    if (r) {
-        /* No need to free bulk data, as TIM request doesn't carries any data */
-        unifi_error(priv, "Error queueing CSR_MLME_SET_TIM_REQUEST signal\n");
-        if (staRecord) {
-            staRecord->timSet = oldTimSetStatus ;
-        }
-        else
-        {
-            /* MLME_SET_TIM.req sending failed here for AID0, so revert back our bcTimSet status */
-            interfacePriv->bcTimSet = !setTim;
-        }
-    }
-    else {
-        /* Update tim request pending flag and ensure no more TIM set requests are send
-           for the same station until TIM confirm is received */
-        if (staRecord) {
-            staRecord->timRequestPendingFlag = TRUE;
-        }
-        else
-        {
-            /* Update tim request (for AID 0) pending flag and ensure no more DTIM set requests are send
-             * for the same station until TIM confirm is received
-             */
-            interfacePriv->bcTimSetReqPendingFlag = TRUE;
-        }
-    }
-    unifi_trace(priv, UDBG5, "leaving the update_tim routine\n");
-}
-
-static
-void process_peer_active_transition(unifi_priv_t * priv,
-                                    CsrWifiRouterCtrlStaInfo_t *staRecord,
-                                    u16 interfaceTag)
-{
-    int r,i;
-    u8 spaceAvail[4] = {TRUE,TRUE,TRUE,TRUE};
-    tx_buffered_packets_t * buffered_pkt = NULL;
-    unsigned long lock_flags;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    unifi_trace(priv, UDBG5, "entering process_peer_active_transition\n");
-
-    if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
-        /* giving more priority to multicast packets so delaying unicast packets*/
-        unifi_trace(priv,UDBG2, "Multicast transmission is going on so resume unicast transmission after DTIM over\n");
-
-        /* As station is active now, even though AP is not able to send frames to it
-         * because of DTIM, it needs to reset the TIM here
-         */
-        if (!staRecord->timRequestPendingFlag){
-            if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){
-                update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle);
-            }
-        }
-        else
-        {
-            /* Cache the TimSet value so that it will processed immidiatly after
-             * completing the current setTim Request
-             */
-            staRecord->updateTimReqQueued = 0;
-            unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
-                        staRecord->aid);
-        }
-        return;
-    }
-    while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
-        buffered_pkt->transmissionControl &=
-                     ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
-        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) {
-            unifi_trace(priv, UDBG2, "p_p_a_t:(ENOSPC) Mgt Frame queueing \n");
-            /* Enqueue at the head of the queue */
-            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-            list_add(&buffered_pkt->q, &staRecord->mgtFrames);
-            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-            priv->pausedStaHandle[3]=(u8)(staRecord->assignedHandle);
-            spaceAvail[3] = FALSE;
-            break;
-        } else {
-            if(r){
-                unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                /* the PDU failed where we can't do any thing so free the storage */
-                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-            }
-            kfree(buffered_pkt);
-        }
-    }
-    if (!staRecord->timRequestPendingFlag) {
-        if (staRecord->txSuspend) {
-            if(staRecord->timSet == CSR_WIFI_TIM_SET) {
-                update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
-            }
-            return;
-        }
-    }
-    else
-    {
-        /* Cache the TimSet value so that it will processed immidiatly after
-         * completing the current setTim Request
-         */
-        staRecord->updateTimReqQueued = 0;
-        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
-                    staRecord->aid);
-    }
-    for(i=3;i>=0;i--) {
-        if(!spaceAvail[i])
-            continue;
-        unifi_trace(priv, UDBG6, "p_p_a_t:data pkt sending for AC %d \n",i);
-        while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
-           buffered_pkt->transmissionControl &=
-                      ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
-           if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) {
-               /* Clear the trigger bit transmission control*/
-               /* Enqueue at the head of the queue */
-               spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-               list_add(&buffered_pkt->q, &staRecord->dataPdu[i]);
-               spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-               priv->pausedStaHandle[i]=(u8)(staRecord->assignedHandle);
-               break;
-           } else {
-              if(r){
-                  unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                  /* the PDU failed where we can't do any thing so free the storage */
-                  unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-               }
-              kfree(buffered_pkt);
-           }
-        }
-    }
-    if (!staRecord->timRequestPendingFlag){
-        if((staRecord->timSet  == CSR_WIFI_TIM_SET) || (staRecord->timSet  == CSR_WIFI_TIM_SETTING)) {
-            unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n");
-            update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
-        }
-    }
-    else
-    {
-        /* Cache the TimSet value so that it will processed immidiatly after
-         * completing the current setTim Request
-         */
-        staRecord->updateTimReqQueued = 0;
-        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
-                    staRecord->aid);
-    }
-    unifi_trace(priv, UDBG5, "leaving process_peer_active_transition\n");
-}
-
-
-
-void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,u16 interfaceTag, const CSR_MA_PACKET_CONFIRM *pkt_cfm)
-{
-    netInterface_priv_t *interfacePriv;
-    u8 i;
-    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-
-    if(pkt_cfm->HostTag == interfacePriv->multicastPduHostTag) {
-         unifi_trace(priv,UDBG2,"CFM for marked Multicast Tag = %x\n",interfacePriv->multicastPduHostTag);
-         interfacePriv->multicastPduHostTag = 0xffffffff;
-         resume_suspended_uapsd(priv,interfaceTag);
-         resume_unicast_buffered_frames(priv,interfaceTag);
-         if(list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) &&
-              list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
-            unifi_trace(priv,UDBG1,"Resetting multicastTIM");
-            if (!interfacePriv->bcTimSetReqPendingFlag)
-            {
-                update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF);
-            }
-            else
-            {
-                /* Cache the DTimSet value so that it will processed immidiatly after
-                 * completing the current setDTim Request
-                 */
-                 interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
-                 unifi_trace(priv, UDBG2, "uf_process_ma_pkt_cfm_for_ap : One more UpdateDTim Request(%d) Queued \n",
-                             interfacePriv->bcTimSetReqQueued);
-            }
-
-        }
-        return;
-    }
-
-    /* Check if it is a Confirm for null data frame used
-     * for probing station activity
-     */
-    for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
-        if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) {
-
-            unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n",
-                                    pkt_cfm->HostTag,
-                                    pkt_cfm->TransmissionStatus
-                                    );
-            staRecord->nullDataHostTag = INVALID_HOST_TAG;
-
-            if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){
-                u32 now;
-                u32 inactive_time;
-
-                unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n");
-                /* Recheck if there is some activity after null data is sent.
-                *
-                * If still there is no activity then send a disconnected indication
-                * to SME to delete the station record.
-                */
-                if (staRecord->activity_flag){
-                    return;
-                }
-                now = CsrTimeGet(NULL);
-
-                if (staRecord->lastActivity > now)
-                {
-                    /* simple timer wrap (for 1 wrap) */
-                    inactive_time = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity),
-                                               now);
-                }
-                else
-                {
-                    inactive_time = (u32)CsrTimeSub(now, staRecord->lastActivity);
-                }
-
-                if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
-                {
-                    struct list_head send_cfm_list;
-                    u8 j;
-
-                    /* The SME/NME may be waiting for confirmation for requested frames to this station.
-                     * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a
-                     * a defensive check, it loops through buffered frames for this station and if confirmation
-                     * is requested, send auto confirmation with failure status. Also flush the frames so
-                     * that these are not processed again in PEER_DEL_REQ handler.
-                     */
-                    INIT_LIST_HEAD(&send_cfm_list);
-
-                    uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                                             &send_cfm_list,
-                                                             &(staRecord->mgtFrames));
-
-                    uf_flush_list(priv, &(staRecord->mgtFrames));
-
-                    for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
-                        uf_prepare_send_cfm_list_for_queued_pkts(priv,
-                                                                 &send_cfm_list,
-                                                                 &(staRecord->dataPdu[j]));
-
-                        uf_flush_list(priv,&(staRecord->dataPdu[j]));
-                    }
-
-                    send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list);
-
-
-
-                    unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
-                                             staRecord->peerMacAddress.a[0],
-                                             staRecord->peerMacAddress.a[1],
-                                             staRecord->peerMacAddress.a[2],
-                                             staRecord->peerMacAddress.a[3],
-                                             staRecord->peerMacAddress.a[4],
-                                             staRecord->peerMacAddress.a[5]);
-
-                    CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
-                                                      0,
-                                                      staRecord->interfacePriv->InterfaceTag,
-                                                      staRecord->peerMacAddress,
-                                                      CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
-                }
-
-            }
-            else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL)
-            {
-                 staRecord->activity_flag = TRUE;
-            }
-        }
-    }
-}
-
-#endif
-u16 uf_get_vif_identifier (CsrWifiRouterCtrlMode mode, u16 tag)
-{
-    switch(mode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-            return (0x02<<8|tag);
-
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            return (0x03<<8|tag);
-
-        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-            return (0x01<<8|tag);
-
-        case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR:
-            return (0x04<<8|tag);
-        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
-            return (0x05<<8|tag);
-        default:
-            return tag;
-    }
-}
-
-#ifdef CSR_SUPPORT_SME
-
-/*
- * ---------------------------------------------------------------------------
- *  update_macheader
- *
- *
- *      These functions updates mac header for intra BSS packet
- *      routing.
- *      NOTE: This function always has to be called in rx context which
- *      is in bh thread context since GFP_KERNEL is used. In soft IRQ/ Interrupt
- *      context shouldn't be used
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *      skb             Socket buffer containing data packet to transmit
- *      newSkb          Socket buffer containing data packet + Mac header if no sufficient headroom in skb
- *      priority        to append QOS control header in Mac header
- *      bulkdata        if newSkb allocated then bulkdata updated to send to unifi
- *      interfaceTag    the interfaceID on which activity going on
- *      macHeaderLengthInBytes no. of bytes of mac header in received frame
- *      qosDestination  used to append Qos control field
- *
- *  Returns:
- *      Zero on success or -1 on error.
- * ---------------------------------------------------------------------------
- */
-
-static int update_macheader(unifi_priv_t *priv, struct sk_buff *skb,
-                            struct sk_buff *newSkb, CSR_PRIORITY *priority,
-                            bulk_data_param_t *bulkdata, u16 interfaceTag,
-                            u8 macHeaderLengthInBytes,
-                            u8 qosDestination)
-{
-
-    u16 *fc = NULL;
-    u8 direction = 0, toDs, fromDs;
-    u8 *bufPtr = NULL;
-    u8 sa[ETH_ALEN], da[ETH_ALEN];
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    int headroom;
-    u8 macHeaderBuf[IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE] = {0};
-
-    unifi_trace(priv, UDBG5, "entering the update_macheader function\n");
-
-    /* temporary buffer for the Mac header storage */
-    memcpy(macHeaderBuf, skb->data, macHeaderLengthInBytes);
-
-    /* remove the Macheader from the skb */
-    skb_pull(skb, macHeaderLengthInBytes);
-
-    /* get the skb headroom for skb_push check */
-    headroom = skb_headroom(skb);
-
-    /*  pointer to frame control field */
-    fc = (u16*) macHeaderBuf;
-
-    toDs = (*fc & cpu_to_le16(IEEE802_11_FC_TO_DS_MASK))?1 : 0;
-    fromDs = (*fc & cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK))? 1: 0;
-    unifi_trace(priv, UDBG5, "In update_macheader function, fromDs = %x, toDs = %x\n", fromDs, toDs);
-    direction = ((fromDs | (toDs << 1)) & 0x3);
-
-    /* Address1 or 3 from the macheader */
-    memcpy(da, macHeaderBuf+4+toDs*12, ETH_ALEN);
-    /* Address2, 3 or 4 from the mac header */
-    memcpy(sa, macHeaderBuf+10+fromDs*(6+toDs*8), ETH_ALEN);
-
-    unifi_trace(priv, UDBG3, "update_macheader:direction = %x\n", direction);
-    /* update the toDs, fromDs & address fields in Mac header */
-    switch(direction)
-    {
-        case 2:
-            /* toDs = 1 & fromDs = 0 , toAp when frames received from peer
-             * while sending this packet to Destination the Mac header changed
-             * as fromDs = 1 & toDs = 0, fromAp
-             */
-            *fc &= cpu_to_le16(~IEEE802_11_FC_TO_DS_MASK);
-            *fc |= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK);
-            /* Address1: MAC address of the actual destination (4 = 2+2) */
-            memcpy(macHeaderBuf + 4, da, ETH_ALEN);
-            /* Address2: The MAC address of the AP (10 = 2+2+6) */
-            memcpy(macHeaderBuf + 10, &interfacePriv->bssid, ETH_ALEN);
-            /* Address3: MAC address of the actual source from mac header (16 = 2+2+6+6) */
-            memcpy(macHeaderBuf + 16, sa, ETH_ALEN);
-            break;
-        case 3:
-            unifi_trace(priv, UDBG3, "when both the toDs & fromDS set, NOT SUPPORTED\n");
-            break;
-        default:
-            unifi_trace(priv, UDBG3, "problem in decoding packet in update_macheader \n");
-            return -1;
-    }
-
-    /* frameType is Data always, Validation is done before calling this function */
-
-    /* check for the souce station type */
-    switch(le16_to_cpu(*fc) & IEEE80211_FC_SUBTYPE_MASK)
-    {
-        case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
-            /* No need to modify the qos control field */
-            if (!qosDestination) {
-
-                /* If source Sta is QOS enabled & if this bit set, then HTC is supported by
-                 * peer station & htc field present in macHeader
-                 */
-                if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
-                    /* HT control field present in Mac header
-                     * 6 = sizeof(qosControl) + sizeof(htc)
-                     */
-                    macHeaderLengthInBytes -= 6;
-                } else {
-                    macHeaderLengthInBytes -= 2;
-                }
-                /* Destination STA is non qos so change subtype to DATA */
-                *fc &= cpu_to_le16(~IEEE80211_FC_SUBTYPE_MASK);
-                *fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
-                /* remove the qos control field & HTC(if present). new macHeaderLengthInBytes is less than old
-                 * macHeaderLengthInBytes so no need to verify skb headroom
-                 */
-                if (headroom < macHeaderLengthInBytes) {
-                    unifi_trace(priv, UDBG1, " sufficient headroom not there to push updated mac header \n");
-                    return -1;
-                }
-                bufPtr = (u8 *) skb_push(skb, macHeaderLengthInBytes);
-
-                /*  update bulk data os_data_ptr */
-                bulkdata->d[0].os_data_ptr = skb->data;
-                bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
-                bulkdata->d[0].data_length = skb->len;
-
-            } else {
-                /* pointing to QOS control field */
-                u8 qc;
-                if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
-                    qc = *((u8*)(macHeaderBuf + (macHeaderLengthInBytes - 4 - 2)));
-                } else {
-                    qc = *((u8*)(macHeaderBuf + (macHeaderLengthInBytes - 2)));
-                }
-
-                if ((qc & IEEE802_11_QC_TID_MASK) > 7) {
-                    *priority = 7;
-                } else {
-                    *priority = qc & IEEE802_11_QC_TID_MASK;
-                }
-
-                unifi_trace(priv, UDBG1, "Incoming packet priority from QSTA is %x\n", *priority);
-
-                if (headroom < macHeaderLengthInBytes) {
-                    unifi_trace(priv, UDBG3, " sufficient headroom not there to push updated mac header \n");
-                    return -1;
-                }
-                bufPtr = (u8 *) skb_push(skb, macHeaderLengthInBytes);
-            }
-            break;
-        default:
-            {
-                bulk_data_param_t data_ptrs;
-                CsrResult csrResult;
-                unifi_trace(priv, UDBG5, "normal Data packet, NO QOS \n");
-
-                if (qosDestination) {
-                    u8 qc = 0;
-                    unifi_trace(priv, UDBG3, "destination is QOS station \n");
-
-                    /* Set Ma-Packet.req UP to UP0 */
-                    *priority = CSR_QOS_UP0;
-
-                    /* prepare the qos control field */
-                    qc |= CSR_QOS_UP0;
-                    /* no Amsdu is in ap buffer so eosp is left 0 */
-                    if (da[0] & 0x1) {
-                        /* multicast/broadcast frames, no acknowledgement needed */
-                        qc |= 1 << 5;
-                    }
-
-                    /* update new Mac header Length with 2 = sizeof(qos control) */
-                    macHeaderLengthInBytes += 2;
-
-                    /* received DATA frame but destiantion is QOS station so update subtype to QOS*/
-                    *fc &= cpu_to_le16(~IEEE80211_FC_SUBTYPE_MASK);
-                    *fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA);
-
-                    /* appendQosControlOffset = macHeaderLengthInBytes - 2, since source sta is not QOS */
-                    macHeaderBuf[macHeaderLengthInBytes - 2] = qc;
-                    /* txopLimit is 0 */
-                    macHeaderBuf[macHeaderLengthInBytes - 1] = 0;
-                    if (headroom < macHeaderLengthInBytes) {
-                        csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);
-
-                        if (csrResult != CSR_RESULT_SUCCESS) {
-                            unifi_error(priv, " failed to allocate request_data. in update_macheader func\n");
-                            return -1;
-                        }
-                        newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr);
-                        newSkb->len = skb->len + macHeaderLengthInBytes;
-
-                        memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes,
-                                skb->data, skb->len);
-
-                        bulkdata->d[0].os_data_ptr = newSkb->data;
-                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb;
-                        bulkdata->d[0].data_length = newSkb->len;
-
-                        bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;
-
-                        /* The old skb will not be used again */
-                        kfree_skb(skb);
-                    } else {
-                        /* skb headroom is sufficient to append Macheader */
-                        bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
-                        bulkdata->d[0].os_data_ptr = skb->data;
-                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
-                        bulkdata->d[0].data_length = skb->len;
-                    }
-                } else {
-                    unifi_trace(priv, UDBG3, "destination is not a QSTA\n");
-                    if (headroom < macHeaderLengthInBytes) {
-                        csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);
-
-                        if (csrResult != CSR_RESULT_SUCCESS) {
-                            unifi_error(priv, " failed to allocate request_data. in update_macheader func\n");
-                            return -1;
-                        }
-                        newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr);
-                        newSkb->len = skb->len + macHeaderLengthInBytes;
-
-                        memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes,
-                                skb->data, skb->len);
-
-                        bulkdata->d[0].os_data_ptr = newSkb->data;
-                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb;
-                        bulkdata->d[0].data_length = newSkb->len;
-
-                        bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;
-
-                        /* The old skb will not be used again */
-                        kfree_skb(skb);
-                    } else {
-                        /* skb headroom is sufficient to append Macheader */
-                        bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
-                        bulkdata->d[0].os_data_ptr = skb->data;
-                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
-                        bulkdata->d[0].data_length = skb->len;
-                    }
-                }
-            }
-    }
-
-    /* prepare the complete skb, by pushing the MAC header to the beginning of the skb->data */
-    unifi_trace(priv, UDBG5, "updated Mac Header: %d \n",macHeaderLengthInBytes);
-    memcpy(bufPtr, macHeaderBuf, macHeaderLengthInBytes);
-
-    unifi_trace(priv, UDBG5, "leaving the update_macheader function\n");
-    return 0;
-}
-/*
- * ---------------------------------------------------------------------------
- *  uf_ap_process_data_pdu
- *
- *
- *      Takes care of intra BSS admission control & routing packets within BSS
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *      skb             Socket buffer containing data packet to transmit
- *      ehdr            ethernet header to fetch priority of packet
- *      srcStaInfo      source stations record for connection verification
- *      packed_signal
- *      signal_len
- *      signal          MA-PACKET.indication signal
- *      bulkdata        if newSkb allocated then bulkdata updated to send to unifi
- *      macHeaderLengthInBytes no. of bytes of mac header in received frame
- *
- *  Returns:
- *      Zero on success(ap processing complete) or -1 if packet also have to be sent to NETDEV.
- * ---------------------------------------------------------------------------
- */
-int
-uf_ap_process_data_pdu(unifi_priv_t *priv, struct sk_buff *skb,
-                       struct ethhdr *ehdr, CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
-                       const CSR_SIGNAL *signal,
-                       bulk_data_param_t *bulkdata,
-                       u8 macHeaderLengthInBytes)
-{
-    const CSR_MA_PACKET_INDICATION *ind = &(signal->u.MaPacketIndication);
-    u16 interfaceTag = (ind->VirtualInterfaceIdentifier & 0x00ff);
-    struct sk_buff *newSkb = NULL;
-    /* pointer to skb or private skb created using skb_copy() */
-    struct sk_buff *skbPtr = skb;
-    u8 sendToNetdev = FALSE;
-    u8 qosDestination = FALSE;
-    CSR_PRIORITY priority = CSR_CONTENTION;
-    CsrWifiRouterCtrlStaInfo_t *dstStaInfo = NULL;
-    netInterface_priv_t *interfacePriv;
-
-    unifi_trace(priv, UDBG5, "entering  uf_ap_process_data_pdu %d\n",macHeaderLengthInBytes);
-    /* InterfaceTag validation from MA_PACKET.indication */
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_trace(priv, UDBG1, "Interface Tag is Invalid in uf_ap_process_data_pdu\n");
-        unifi_net_data_free(priv, &bulkdata->d[0]);
-        return 0;
-    }
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) &&
-       (interfacePriv->intraBssEnabled == FALSE)) {
-        unifi_trace(priv, UDBG2, "uf_ap_process_data_pdu:P2P GO intrabssEnabled?= %d\n", interfacePriv->intraBssEnabled);
-
-        /*In P2P GO case, if intraBSS distribution Disabled then don't do IntraBSS routing */
-        /* If destination in our BSS then drop otherwise give packet to netdev */
-        dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, ehdr->h_dest, interfaceTag);
-        if (dstStaInfo) {
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-            return 0;
-        }
-        /* May be associated P2PCLI trying to send the packets on backbone (Netdev) */
-        return -1;
-    }
-
-    if(!memcmp(ehdr->h_dest, interfacePriv->bssid.a, ETH_ALEN)) {
-        /* This packet will be given to the TCP/IP stack since this packet is for us(AP)
-         * No routing needed */
-        unifi_trace(priv, UDBG4, "destination address is csr_ap\n");
-        return -1;
-    }
-
-    /* fetch the destination record from station record database */
-    dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, ehdr->h_dest, interfaceTag);
-
-    /* AP mode processing, & if packet is unicast */
-    if(!dstStaInfo) {
-        if (!(ehdr->h_dest[0] & 0x1)) {
-            /* destination not in station record & its a unicast packet, so pass the packet to network stack */
-            unifi_trace(priv, UDBG3, "unicast frame & destination record not exist, send to netdev proto = %x\n", htons(skb->protocol));
-            return -1;
-        } else {
-            /* packet is multicast/broadcast */
-            /* copy the skb to skbPtr, send skb to netdev & skbPtr to multicast/broad cast list */
-            unifi_trace(priv, UDBG5, "skb_copy, in  uf_ap_process_data_pdu, protocol = %x\n", htons(skb->protocol));
-            skbPtr = skb_copy(skb, GFP_KERNEL);
-            if(skbPtr == NULL) {
-                /* We don't have memory to don't send the frame in BSS*/
-                unifi_notice(priv, "broacast/multicast frame can't be sent in BSS No memeory: proto = %x\n", htons(skb->protocol));
-                return -1;
-            }
-            sendToNetdev = TRUE;
-        }
-    } else {
-
-        /* validate the Peer & Destination Station record */
-        if (uf_process_station_records_for_sending_data(priv, interfaceTag, srcStaInfo, dstStaInfo)) {
-            unifi_notice(priv, "uf_ap_process_data_pdu: station record validation failed \n");
-            interfacePriv->stats.rx_errors++;
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-            return 0;
-        }
-    }
-
-    /* BroadCast packet received and it's been sent as non QOS packets.
-     * Since WMM spec not mandates broadcast/multicast to be sent as QOS data only,
-     * if all Peers are QSTA
-     */
-    if(sendToNetdev) {
-       /* BroadCast packet and it's been sent as non QOS packets */
-        qosDestination = FALSE;
-    } else if(dstStaInfo && (dstStaInfo->wmmOrQosEnabled == TRUE)) {
-          qosDestination = TRUE;
-    }
-
-    unifi_trace(priv, UDBG3, "uf_ap_process_data_pdu QoS destination  = %s\n", (qosDestination)? "TRUE": "FALSE");
-
-    /* packet is allowed to send to unifi, update the Mac header */
-    if (update_macheader(priv, skbPtr, newSkb, &priority, bulkdata, interfaceTag, macHeaderLengthInBytes, qosDestination)) {
-        interfacePriv->stats.rx_errors++;
-        unifi_notice(priv, "(Packet Drop) failed to update the Mac header in uf_ap_process_data_pdu\n");
-        if (sendToNetdev) {
-            /*  Free's the skb_copy(skbPtr) data since packet processing failed */
-            bulkdata->d[0].os_data_ptr = skbPtr->data;
-            bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skbPtr;
-            bulkdata->d[0].data_length = skbPtr->len;
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-        }
-        return -1;
-    }
-
-    unifi_trace(priv, UDBG3, "Mac Header updated...calling uf_process_ma_packet_req \n");
-
-    /* Packet is ready to send to unifi ,transmissionControl = 0x0004, confirmation is not needed for data packets */
-    if (uf_process_ma_packet_req(priv,  ehdr->h_dest, 0xffffffff, interfaceTag, CSR_NO_CONFIRM_REQUIRED, (CSR_RATE)0,priority, priv->netdev_client->sender_id, bulkdata)) {
-        if (sendToNetdev) {
-            unifi_trace(priv, UDBG1, "In uf_ap_process_data_pdu, (Packet Drop) uf_process_ma_packet_req failed. freeing skb_copy data (original data sent to Netdev)\n");
-            /*  Free's the skb_copy(skbPtr) data since packet processing failed */
-            bulkdata->d[0].os_data_ptr = skbPtr->data;
-            bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skbPtr;
-            bulkdata->d[0].data_length = skbPtr->len;
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-        } else {
-            /* This free's the skb data */
-            unifi_trace(priv, UDBG1, "In uf_ap_process_data_pdu, (Packet Drop). Unicast data so freeing original skb \n");
-            unifi_net_data_free(priv, &bulkdata->d[0]);
-        }
-    }
-    unifi_trace(priv, UDBG5, "leaving  uf_ap_process_data_pdu\n");
-
-    if (sendToNetdev) {
-        /* The packet is multicast/broadcast, so after AP processing packet has to
-         * be sent to netdev, if peer port state is open
-        */
-        unifi_trace(priv, UDBG4, "Packet will be routed to NetDev\n");
-        return -1;
-    }
-    /* Ap handled the packet & its a unicast packet, no need to send to netdev */
-    return 0;
-}
-
-#endif
-
-CsrResult uf_process_ma_packet_req(unifi_priv_t *priv,
-                                   u8 *peerMacAddress,
-                                   CSR_CLIENT_TAG hostTag,
-                                   u16 interfaceTag,
-                                   CSR_TRANSMISSION_CONTROL transmissionControl,
-                                   CSR_RATE TransmitRate,
-                                   CSR_PRIORITY priority,
-                                   CSR_PROCESS_ID leSenderProcessId,
-                                   bulk_data_param_t *bulkdata)
-{
-    CsrResult status = CSR_RESULT_SUCCESS;
-    CSR_SIGNAL signal;
-    int result;
-#ifdef CSR_SUPPORT_SME
-   CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
-    const u8 *macHdrLocation =  bulkdata->d[0].os_data_ptr;
-    CsrWifiPacketType pktType;
-    int frameType = 0;
-    u8 queuePacketDozing = FALSE;
-    u32 priority_q;
-    u16 frmCtrl;
-    struct list_head * list = NULL; /* List to which buffered PDUs are to be enqueued*/
-    u8 setBcTim=FALSE;
-    netInterface_priv_t *interfacePriv;
-    u8 requeueOnSamePos = FALSE;
-    u32 handle = 0xFFFFFFFF;
-    unsigned long lock_flags;
-
-	unifi_trace(priv, UDBG5,
-		"entering uf_process_ma_packet_req, peer: %pMF\n",
-		peerMacAddress);
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "interfaceTag >= CSR_WIFI_NUM_INTERFACES, interfacetag = %d\n", interfaceTag);
-        return CSR_RESULT_FAILURE;
-    }
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-
-    /* fetch the station record for corresponding peer mac address */
-    if ((staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, peerMacAddress, interfaceTag))) {
-        handle = staRecord->assignedHandle;
-    }
-
-    /* Frame ma-packet.req, this is saved/transmitted depend on queue state */
-    unifi_frame_ma_packet_req(priv, priority, TransmitRate, hostTag,
-                              interfaceTag, transmissionControl, leSenderProcessId,
-                              peerMacAddress, &signal);
-
-   /* Since it's common path between STA & AP mode, in case of STA packet
-     * need not to be queued but in AP case we have to queue PDU's in
-     * different scenarios
-     */
-    switch(interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            /* For this mode processing done below */
-            break;
-        default:
-            /* In case of STA/IBSS/P2PCLI/AMP, no checks needed send the packet down & return */
-            unifi_trace(priv, UDBG5, "In %s, interface mode is %x \n", __FUNCTION__, interfacePriv->interfaceMode);
-            if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) {
-                unifi_warning(priv, "In %s, interface mode NONE \n", __FUNCTION__);
-            }
-            if ((result = ul_send_signal_unpacked(priv, &signal, bulkdata))) {
-                status = CSR_RESULT_FAILURE;
-            }
-            return status;
-    }
-
-    /* -----Only AP/P2pGO mode handling falls below----- */
-
-    /* convert priority to queue */
-    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
-
-    /* check the powersave status of the peer */
-    if (staRecord && (staRecord->currentPeerState ==
-                     CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)) {
-        /* Peer is dozing & packet have to be delivered, so buffer the packet &
-         * update the TIM
-         */
-        queuePacketDozing = TRUE;
-    }
-
-    /* find the type of frame unicast or mulicast/broadcast */
-    if (*peerMacAddress & 0x1) {
-        /* Multicast/broadCast data are always triggered by vif_availability.ind
-         * at the DTIM
-         */
-        pktType = CSR_WIFI_MULTICAST_PDU;
-    } else {
-        pktType = CSR_WIFI_UNICAST_PDU;
-    }
-
-    /* Fetch the frame control field from mac header & check for frame type */
-    frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation);
-
-    /* Processing done according to Frame/Packet type */
-    frameType =  ((frmCtrl & 0x000c) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);
-    switch(frameType)
-    {
-        case IEEE802_11_FRAMETYPE_MANAGEMENT:
-
-            switch(pktType)
-            {
-                case CSR_WIFI_UNICAST_PDU:
-                    unifi_trace(priv, UDBG5, "management unicast PDU in uf_process_ma_packet_req \n");
-                    /* push the packet in to the queue with appropriate mgt list */
-                    if (!staRecord) {
-                        /* push the packet to the unifi if list is empty (if packet lost how to re-enque) */
-                        if (list_empty(&interfacePriv->genericMgtFrames)) {
-#ifdef CSR_SUPPORT_SME
-                            if(!(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
-#endif
-
-                            unifi_trace(priv, UDBG3, "genericMgtFrames list is empty uf_process_ma_packet_req \n");
-                            result = ul_send_signal_unpacked(priv, &signal, bulkdata);
-                            /*  reque only on ENOSPC */
-                            if(result == -ENOSPC) {
-                                /* requeue the failed packet to genericMgtFrame with same position */
-                                unifi_trace(priv, UDBG1, "(ENOSPC) Sending genericMgtFrames Failed so buffering\n");
-                                list = &interfacePriv->genericMgtFrames;
-                                requeueOnSamePos = TRUE;
-                            }
-#ifdef CSR_SUPPORT_SME
-                            }else{
-                                list = &interfacePriv->genericMgtFrames;
-                                unifi_trace(priv, UDBG3, "genericMgtFrames queue empty and dtim started\n hosttag is 0x%x,\n",signal.u.MaPacketRequest.HostTag);
-                                update_eosp_to_head_of_broadcast_list_head(priv,interfaceTag);
-                           }
-#endif
-                        } else {
-                            /* Queue the packet to genericMgtFrame of unifi_priv_t data structure */
-                            list = &interfacePriv->genericMgtFrames;
-                            unifi_trace(priv, UDBG2, "genericMgtFrames queue not empty\n");
-                        }
-                    } else {
-                        /* check peer power state */
-                        if (queuePacketDozing || !list_empty(&staRecord->mgtFrames) || IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
-                            /* peer is in dozing mode, so queue packet in mgt frame list of station record */
-                           /*if multicast traffic is going on, buffer the unicast packets*/
-                            list = &staRecord->mgtFrames;
-
-                            unifi_trace(priv, UDBG1, "staRecord->MgtFrames list empty? = %s, handle = %d, queuePacketDozing = %d\n",
-                                        (list_empty(&staRecord->mgtFrames))? "YES": "NO", staRecord->assignedHandle, queuePacketDozing);
-                            if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)){
-                                update_eosp_to_head_of_broadcast_list_head(priv,interfaceTag);
-                            }
-
-                        } else {
-                            unifi_trace(priv, UDBG5, "staRecord->mgtFrames list is empty uf_process_ma_packet_req \n");
-                            result = ul_send_signal_unpacked(priv, &signal, bulkdata);
-                            if(result == -ENOSPC) {
-                                /* requeue the failed packet to staRecord->mgtFrames with same position */
-                                list = &staRecord->mgtFrames;
-                                requeueOnSamePos = TRUE;
-                                unifi_trace(priv, UDBG1, "(ENOSPC) Sending MgtFrames Failed handle = %d so buffering\n",staRecord->assignedHandle);
-                                priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
-                            } else if (result) {
-                                status = CSR_RESULT_FAILURE;
-                            }
-                        }
-                    }
-                    break;
-                case CSR_WIFI_MULTICAST_PDU:
-                    unifi_trace(priv, UDBG5, "management multicast/broadcast PDU in uf_process_ma_packet_req 'QUEUE it' \n");
-                    /* Queue the packet to genericMulticastOrBroadCastMgtFrames of unifi_priv_t data structure
-                     * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM
-                     */
-
-                    list = &interfacePriv->genericMulticastOrBroadCastMgtFrames;
-                    if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS) &&
-                            (list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
-                        setBcTim=TRUE;
-                    }
-                    break;
-                default:
-                    unifi_error(priv, "condition never meets: packet type unrecognized\n");
-            }
-            break;
-        case IEEE802_11_FRAMETYPE_DATA:
-            switch(pktType)
-            {
-                case CSR_WIFI_UNICAST_PDU:
-                    unifi_trace(priv, UDBG5, "data unicast PDU in uf_process_ma_packet_req \n");
-                    /* check peer power state, list status & peer port status */
-                    if(!staRecord) {
-                        unifi_error(priv, "In %s unicast but staRecord = NULL\n", __FUNCTION__);
-                        return CSR_RESULT_FAILURE;
-                    } else if (queuePacketDozing || isRouterBufferEnabled(priv,priority_q)|| !list_empty(&staRecord->dataPdu[priority_q]) || IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
-                        /* peer is in dozing mode, so queue packet in mgt frame list of station record */
-                        /* if multicast traffic is going on, buffet the unicast packets */
-                        unifi_trace(priv, UDBG2, "Enqueued to staRecord->dataPdu[%d] queuePacketDozing=%d,\
-                                Buffering enabled = %d \n", priority_q,queuePacketDozing,isRouterBufferEnabled(priv,priority_q));
-                        list = &staRecord->dataPdu[priority_q];
-                    } else {
-                        unifi_trace(priv, UDBG5, "staRecord->dataPdu[%d] list is empty uf_process_ma_packet_req \n", priority_q);
-                        /* Pdu allowed to send to unifi */
-                        result = ul_send_signal_unpacked(priv, &signal, bulkdata);
-                        if(result == -ENOSPC) {
-                            /* requeue the failed packet to staRecord->dataPdu[priority_q] with same position */
-                            unifi_trace(priv, UDBG1, "(ENOSPC) Sending Unicast DataPDU to queue %d Failed so buffering\n",priority_q);
-                            requeueOnSamePos = TRUE;
-                            list = &staRecord->dataPdu[priority_q];
-                            priv->pausedStaHandle[priority_q]=(u8)(staRecord->assignedHandle);
-                            if(!isRouterBufferEnabled(priv,priority_q)) {
-                                unifi_error(priv,"Buffering Not enabled for queue %d \n",priority_q);
-                            }
-                        } else if (result) {
-                            status = CSR_RESULT_FAILURE;
-                        }
-                    }
-                    break;
-                case CSR_WIFI_MULTICAST_PDU:
-                    unifi_trace(priv, UDBG5, "data multicast/broadcast PDU in uf_process_ma_packet_req \n");
-                    /* Queue the packet to genericMulticastOrBroadCastFrames list of unifi_priv_t data structure
-                     * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM
-                     */
-                    list = &interfacePriv->genericMulticastOrBroadCastFrames;
-                    if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
-                        setBcTim = TRUE;
-                    }
-                    break;
-                default:
-                    unifi_error(priv, "condition never meets: packet type un recognized\n");
-            }
-            break;
-        default:
-            unifi_error(priv, "unrecognized frame type\n");
-    }
-    if(list) {
-        status = enque_tx_data_pdu(priv, bulkdata,list, &signal,requeueOnSamePos);
-        /* Record no. of packet queued for each peer */
-        if (staRecord && (pktType == CSR_WIFI_UNICAST_PDU) && (!status)) {
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            staRecord->noOfPktQueued++;
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-        }
-        else if ((pktType == CSR_WIFI_MULTICAST_PDU) && (!status))
-        {
-            /* If broadcast Tim is set && queuing is successful, then only update TIM */
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            interfacePriv->noOfbroadcastPktQueued++;
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-        }
-    }
-    /* If broadcast Tim is set && queuing is successful, then only update TIM */
-    if(setBcTim && !status) {
-        unifi_trace(priv, UDBG3, "tim set due to broadcast pkt\n");
-        if (!interfacePriv->bcTimSetReqPendingFlag)
-        {
-            update_tim(priv,0,CSR_WIFI_TIM_SET,interfaceTag, handle);
-        }
-        else
-        {
-            /* Cache the TimSet value so that it will processed immidiatly after
-            * completing the current setTim Request
-            */
-            interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_SET;
-            unifi_trace(priv, UDBG2, "uf_process_ma_packet_req : One more UpdateDTim Request(:%d) Queued \n",
-                        interfacePriv->bcTimSetReqQueued);
-        }
-    } else if(staRecord && staRecord->currentPeerState ==
-                            CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) {
-        if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) {
-            if(!staRecord->wmmOrQosEnabled) {
-                if(!list_empty(&staRecord->mgtFrames) ||
-                   !list_empty(&staRecord->dataPdu[3]) ||
-                   !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])) {
-                    unifi_trace(priv, UDBG3, "tim set due to unicast pkt & peer in powersave\n");
-                    if (!staRecord->timRequestPendingFlag){
-                        update_tim(priv,staRecord->aid,1,interfaceTag, handle);
-                    }
-                    else
-                    {
-                        /* Cache the TimSet value so that it will processed immidiatly after
-                         * completing the current setTim Request
-                         */
-                        staRecord->updateTimReqQueued = 1;
-                        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
-                                    staRecord->aid);
-                    }
-                }
-            } else {
-                /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */
-                u8 allDeliveryEnabled = 0, dataAvailable = 0;
-                /* Check if all AC's are Delivery Enabled */
-                is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
-                if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)
-                    || (!list_empty(&staRecord->mgtFrames))) {
-                    if (!staRecord->timRequestPendingFlag) {
-                        update_tim(priv,staRecord->aid,1,interfaceTag, handle);
-                    }
-                    else
-                    {
-                        /* Cache the TimSet value so that it will processed immidiatly after
-                         * completing the current setTim Request
-                         */
-                        staRecord->updateTimReqQueued = 1;
-                        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
-                                    staRecord->aid);
-                    }
-                }
-            }
-        }
-    }
-
-    if((list) && (pktType == CSR_WIFI_UNICAST_PDU && !queuePacketDozing) && !(isRouterBufferEnabled(priv,priority_q)) && !(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
-        unifi_trace(priv, UDBG2, "buffering cleared for queue = %d So resending buffered frames\n",priority_q);
-        uf_send_buffered_frames(priv, priority_q);
-    }
-    unifi_trace(priv, UDBG5, "leaving uf_process_ma_packet_req \n");
-    return status;
-#else
-#ifdef CSR_NATIVE_LINUX
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "interfaceTag >= CSR_WIFI_NUM_INTERFACES, interfacetag = %d\n", interfaceTag);
-        return CSR_RESULT_FAILURE;
-    }
-    /* Frame ma-packet.req, this is saved/transmitted depend on queue state */
-    unifi_frame_ma_packet_req(priv, priority, TransmitRate, hostTag, interfaceTag,
-            transmissionControl, leSenderProcessId,
-            peerMacAddress, &signal);
-    result = ul_send_signal_unpacked(priv, &signal, bulkdata);
-    if (result) {
-        return CSR_RESULT_FAILURE;
-    }
-#endif
-    return status;
-#endif
-}
-
-#ifdef CSR_SUPPORT_SME
-s8 uf_get_protection_bit_from_interfacemode(unifi_priv_t *priv, u16 interfaceTag, const u8 *daddr)
-{
-    s8 protection = 0;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    switch(interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
-        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
-            protection = interfacePriv->protect;
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            {
-                CsrWifiRouterCtrlStaInfo_t *dstStaInfo = NULL;
-                if (daddr[0] & 0x1) {
-                    unifi_trace(priv, UDBG3, "broadcast/multicast packet in send_ma_pkt_request\n");
-                    /* In this mode, the protect member of priv structure has an information of how
-                     * AP/P2PGO has started, & the member updated in set mode request for AP/P2PGO
-                     */
-                    protection = interfacePriv->protect;
-                } else {
-                    /* fetch the destination record from station record database */
-                    dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, daddr, interfaceTag);
-                    if (!dstStaInfo) {
-                        unifi_trace(priv, UDBG3, "peer not found in station record in send_ma_pkt_request\n");
-                        return -1;
-                    }
-                    protection = dstStaInfo->protection;
-                }
-            }
-            break;
-        default:
-            unifi_trace(priv, UDBG2, "mode unknown in send_ma_pkt_request\n");
-    }
-    return protection;
-}
-#endif
-#ifdef CSR_SUPPORT_SME
-u8 send_multicast_frames(unifi_priv_t *priv, u16 interfaceTag)
-{
-    int r;
-    tx_buffered_packets_t * buffered_pkt = NULL;
-    u8 moreData = FALSE;
-    u8 pduSent =0;
-    unsigned long lock_flags;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    u32 hostTag = 0xffffffff;
-
-    if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_VO)) {
-        while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
-            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK);
-            moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;
-
-
-            unifi_trace(priv,UDBG2,"DTIM Occurred for interface:sending Mgt packet %d\n",interfaceTag);
-
-            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) {
-               unifi_trace(priv,UDBG1,"frame_and_send_queued_pdu failed with ENOSPC for host tag = %x\n", buffered_pkt->hostTag);
-               /* Enqueue at the head of the queue */
-               spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-               list_add(&buffered_pkt->q, &interfacePriv->genericMulticastOrBroadCastMgtFrames);
-               spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-               break;
-            } else {
-                unifi_trace(priv,UDBG1,"send_multicast_frames: Send genericMulticastOrBroadCastMgtFrames (%x, %x)\n",
-                                        buffered_pkt->hostTag,
-                                        r);
-                if(r) {
-                   unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-                }
-                if(!moreData) {
-
-                    interfacePriv->dtimActive = FALSE;
-                    if(!r) {
-                        hostTag = buffered_pkt->hostTag;
-                        pduSent++;
-                    } else {
-                        send_vif_availibility_rsp(priv,uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag),CSR_RC_UNSPECIFIED_FAILURE);
-                    }
-                }
-                /* Buffered frame sent successfully */
-                spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-                interfacePriv->noOfbroadcastPktQueued--;
-                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-                kfree(buffered_pkt);
-           }
-
-        }
-    }
-    if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_CONTENTION)) {
-        while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastFrames))) {
-            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
-            moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;
-
-
-            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) {
-                /* Clear the trigger bit transmission control*/
-                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK);
-                /* Enqueue at the head of the queue */
-                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                list_add(&buffered_pkt->q, &interfacePriv->genericMulticastOrBroadCastFrames);
-                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-                break;
-            } else {
-                if(r) {
-                    unifi_trace(priv,UDBG1,"send_multicast_frames: Send genericMulticastOrBroadCastFrame failed (%x, %x)\n",
-                                            buffered_pkt->hostTag,
-                                            r);
-                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-                }
-                if(!moreData) {
-                    interfacePriv->dtimActive = FALSE;
-                    if(!r) {
-                        pduSent ++;
-                        hostTag = buffered_pkt->hostTag;
-                    } else {
-                        send_vif_availibility_rsp(priv,uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag),CSR_RC_UNSPECIFIED_FAILURE);
-                    }
-                }
-                /* Buffered frame sent successfully */
-                spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-                interfacePriv->noOfbroadcastPktQueued--;
-                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-                kfree(buffered_pkt);
-            }
-        }
-    }
-    if((interfacePriv->dtimActive == FALSE)) {
-        /* Record the host Tag*/
-        unifi_trace(priv,UDBG2,"send_multicast_frames: Recorded hostTag of EOSP packet: = 0x%x\n",hostTag);
-        interfacePriv->multicastPduHostTag = hostTag;
-    }
-    return pduSent;
-}
-#endif
-void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,u8 *sigdata,
-                                        u32 siglen)
-{
-#ifdef CSR_SUPPORT_SME
-    CSR_SIGNAL signal;
-    CSR_MA_VIF_AVAILABILITY_INDICATION *ind;
-    int r;
-    u16 interfaceTag;
-    u8 pduSent =0;
-    CSR_RESULT_CODE resultCode = CSR_RC_SUCCESS;
-    netInterface_priv_t *interfacePriv;
-
-    unifi_trace(priv, UDBG3,
-            "uf_process_ma_vif_availibility_ind: Process signal 0x%.4X\n",
-            *((u16*)sigdata));
-
-    r = read_unpack_signal(sigdata, &signal);
-    if (r) {
-        unifi_error(priv,
-                    "uf_process_ma_vif_availibility_ind: Received unknown signal 0x%.4X.\n",
-                    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));
-        return;
-    }
-    ind = &signal.u.MaVifAvailabilityIndication;
-    interfaceTag=ind->VirtualInterfaceIdentifier & 0xff;
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "in vif_availability_ind interfaceTag is wrong\n");
-        return;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if(ind->Multicast) {
-        if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames) &&
-            list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames)) {
-            /* This condition can occur because of a potential race where the
-               TIM is not yet reset as host is waiting for confirm but it is sent
-               by firmware and DTIM occurs*/
-            unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag);
-            send_vif_availibility_rsp(priv,ind->VirtualInterfaceIdentifier,CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES);
-            interfacePriv->dtimActive = FALSE;
-            if(interfacePriv->multicastPduHostTag == 0xffffffff) {
-                unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag);
-                /* This may be an extra request in very rare race conditions but it is fine as it would atleast remove the potential lock up */
-                if (!interfacePriv->bcTimSetReqPendingFlag)
-                {
-                    update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF);
-                }
-                else
-                {
-                    /* Cache the TimSet value so that it will processed immidiatly after
-                     * completing the current setTim Request
-                     */
-                    interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
-                    unifi_trace(priv, UDBG2, "uf_process_ma_vif_availibility_ind : One more UpdateDTim Request(%d) Queued \n",
-                                interfacePriv->bcTimSetReqQueued);
-                }
-            }
-            return;
-        }
-        if(interfacePriv->dtimActive) {
-            unifi_trace(priv,UDBG2,"DTIM Occurred for already active DTIM interface %d\n",interfaceTag);
-            return;
-        } else {
-            unifi_trace(priv,UDBG2,"DTIM Occurred for interface %d\n",interfaceTag);
-            if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
-                set_eosp_transmit_ctrl(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames);
-            } else {
-                set_eosp_transmit_ctrl(priv,&interfacePriv->genericMulticastOrBroadCastFrames);
-            }
-        }
-        interfacePriv->dtimActive = TRUE;
-        pduSent = send_multicast_frames(priv,interfaceTag);
-    }
-    else {
-        unifi_error(priv,"Interface switching is not supported %d\n",interfaceTag);
-        resultCode = CSR_RC_NOT_SUPPORTED;
-        send_vif_availibility_rsp(priv,ind->VirtualInterfaceIdentifier,CSR_RC_NOT_SUPPORTED);
-    }
-#endif
-}
-#ifdef CSR_SUPPORT_SME
-
-#define  GET_ACTIVE_INTERFACE_TAG(priv) 0
-
-static u8 uf_is_more_data_for_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord)
-{
-    s8 i;
-
-    for(i=UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--)
-    {
-        if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
-             ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
-             &&(!list_empty(&staRecord->dataPdu[i]))) {
-            unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data Available AC = %d\n", i);
-            return TRUE;
-        }
-    }
-
-    unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data NOT Available \n");
-    return FALSE;
-}
-
-static u8 uf_is_more_data_for_usp_delivery(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord, unifi_TrafficQueue queue)
-{
-    s8 i;
-
-    for(i = queue; i >= UNIFI_TRAFFIC_Q_BK; i--)
-    {
-        if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
-             ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
-             &&(!list_empty(&staRecord->dataPdu[i]))) {
-            unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data Available AC = %d\n", i);
-            return TRUE;
-        }
-    }
-
-    unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data NOT Available \n");
-    return FALSE;
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_send_buffered_data_from_delivery_ac
- *
- *      This function takes care of
- *      -> Parsing the delivery enabled queue & sending frame down to HIP
- *      -> Setting EOSP=1 when USP to be terminated
- *      -> Depending on MAX SP length services the USP
- *
- * NOTE:This function always called from uf_handle_uspframes_delivery(), Dont
- *      call this function from any other location in code
- *
- *  Arguments:
- *      priv        Pointer to device private context struct
- *      vif         interface specific HIP vif instance
- *      staInfo     peer for which UAPSD to be scheduled
- *      queue       AC from which Data to be sent in USP
- *      txList      access category for processing list
- * ---------------------------------------------------------------------------
- */
-void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv,
-                                            CsrWifiRouterCtrlStaInfo_t * staInfo,
-                                            u8 queue,
-                                            struct list_head *txList)
-{
-
-    u16 interfaceTag = GET_ACTIVE_INTERFACE_TAG(priv);
-    tx_buffered_packets_t * buffered_pkt = NULL;
-    unsigned long lock_flags;
-    u8 eosp=FALSE;
-    s8 r =0;
-    u8 moreData = FALSE;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    unifi_trace(priv, UDBG2, "++uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);
-
-    if (queue > UNIFI_TRAFFIC_Q_VO)
-    {
-        return;
-    }
-    while((buffered_pkt=dequeue_tx_data_pdu(priv, txList))) {
-        if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
-            unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: DTIM Active, suspend UAPSD, staId: 0x%x\n",
-                        staInfo->aid);
-
-            /* Once resume called, the U-APSD delivery operation will resume */
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            staInfo->uspSuspend = TRUE;
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-            /* re-queueing the packet as DTIM started */
-            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-            list_add(&buffered_pkt->q,txList);
-            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-            break;
-        }
-
-        buffered_pkt->transmissionControl &=
-                 ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-
-
-        if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)) {
-
-             buffered_pkt->transmissionControl = TRANSMISSION_CONTROL_TRIGGER_MASK;
-
-             /* Check All delivery enables Ac for more data, because caller of this
-              * function not aware about last packet
-              * (First check in moreData fetching helps in draining out Mgt frames Q)
-              */
-              moreData = (!list_empty(txList) || uf_is_more_data_for_usp_delivery(priv, staInfo, queue));
-
-              if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength - 1)) {
-                  moreData = FALSE;
-              }
-
-              if(moreData == FALSE) {
-                  eosp = TRUE;
-                  buffered_pkt->transmissionControl =
-                      (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-              }
-        } else {
-            /* Non QoS and non U-APSD */
-            unifi_warning(priv, "uf_send_buffered_data_from_delivery_ac: non U-APSD !!! \n");
-        }
-
-        unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_delivery_ac : MoreData:%d, EOSP:%d\n",moreData,eosp);
-
-        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) {
-
-            unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: UASPD suspended, ENOSPC in hipQ=%x\n", queue);
-
-            /* Once resume called, the U-APSD delivery operation will resume */
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            staInfo->uspSuspend = TRUE;
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-
-            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-            list_add(&buffered_pkt->q,txList);
-            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-            priv->pausedStaHandle[queue]=(u8)(staInfo->assignedHandle);
-            break;
-        } else {
-            if(r){
-                /* the PDU failed where we can't do any thing so free the storage */
-                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-            }
-            kfree(buffered_pkt);
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            staInfo->noOfSpFramesSent++;
-            if((!moreData) || (staInfo->noOfSpFramesSent == staInfo->maxSpLength)) {
-                unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: Terminating USP\n");
-                staInfo->uapsdActive = FALSE;
-                staInfo->uspSuspend = FALSE;
-                staInfo->noOfSpFramesSent = 0;
-                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-                break;
-            }
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-        }
-    }
-    unifi_trace(priv, UDBG2, "--uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);
-}
-
-void uf_send_buffered_data_from_ac(unifi_priv_t *priv,
-                                   CsrWifiRouterCtrlStaInfo_t * staInfo,
-                                   u8 queue,
-                                   struct list_head *txList)
-{
-    tx_buffered_packets_t * buffered_pkt = NULL;
-    unsigned long lock_flags;
-    u8 eosp=FALSE;
-    u8 moreData = FALSE;
-    s8 r =0;
-
-    unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_ac :\n");
-
-    while(!isRouterBufferEnabled(priv,queue) &&
-                    ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){
-
-        buffered_pkt->transmissionControl &=
-                 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
-
-        unifi_trace(priv,UDBG3,"uf_send_buffered_data_from_ac : MoreData:%d, EOSP:%d\n",moreData,eosp);
-
-        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) {
-           /* Enqueue at the head of the queue */
-           spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-           list_add(&buffered_pkt->q,txList);
-           spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-           if(staInfo != NULL){
-              priv->pausedStaHandle[queue]=(u8)(staInfo->assignedHandle);
-           }
-           unifi_trace(priv,UDBG3," uf_send_buffered_data_from_ac: PDU sending failed .. no space for queue %d \n",queue);
-           } else {
-            if(r){
-                /* the PDU failed where we can't do any thing so free the storage */
-                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-            }
-            kfree(buffered_pkt);
-      }
-  }
-
-}
-
-void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
-{
-    u16 interfaceTag = GET_ACTIVE_INTERFACE_TAG(priv);
-    u32 startIndex=0,endIndex=0;
-    CsrWifiRouterCtrlStaInfo_t * staInfo = NULL;
-    u8 queue;
-    u8 moreData = FALSE;
-
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
-        (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)))
-        return;
-
-    queue = (q<=3)?q:0;
-
-    if(interfacePriv->dtimActive) {
-        /* this function updates dtimActive*/
-        send_multicast_frames(priv,interfaceTag);
-        if(!interfacePriv->dtimActive) {
-            moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
-             !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
-            if(!moreData) {
-                if (!interfacePriv->bcTimSetReqPendingFlag)
-                {
-                    update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0XFFFFFFFF);
-                }
-                else
-                {
-                    /* Cache the TimSet value so that it will processed immidiatly after
-                     * completing the current setTim Request
-                     */
-                    interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
-                    unifi_trace(priv, UDBG2, "uf_send_buffered_frames : One more UpdateDTim Request(%d) Queued \n",
-                                interfacePriv->bcTimSetReqQueued);
-                }
-            }
-        } else {
-            moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
-                        !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
-           if(!moreData) {
-               /* This should never happen but if it happens, we need a way out */
-               unifi_error(priv,"ERROR: No More Data but DTIM is active sending Response\n");
-               send_vif_availibility_rsp(priv,uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag),CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES);
-               interfacePriv->dtimActive = FALSE;
-           }
-        }
-        return;
-    }
-    if(priv->pausedStaHandle[queue] > 7) {
-        priv->pausedStaHandle[queue] = 0;
-    }
-
-    if(queue == UNIFI_TRAFFIC_Q_VO) {
-
-
-        unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying mgt from queue=%d\n",queue);
-        for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) {
-            staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
-            if(!staInfo ) {
-                continue;
-            } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
-                       &&(staInfo->uapsdActive == FALSE) ) {
-                continue;
-            }
-
-            if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
-                               &&(staInfo->uapsdActive == FALSE)){
-                            /*Non-UAPSD case push the management frames out*/
-               if(!list_empty(&staInfo->mgtFrames)){
-                    uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
-                }
-            }
-
-            if(isRouterBufferEnabled(priv,queue)) {
-                unifi_notice(priv,"uf_send_buffered_frames : No space Left for queue = %d\n",queue);
-                break;
-            }
-        }
-        /*push generic management frames out*/
-        if(!list_empty(&interfacePriv->genericMgtFrames)) {
-            unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying generic mgt from queue=%d\n",queue);
-            uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames);
-        }
-    }
-
-
-    unifi_trace(priv,UDBG2,"uf_send_buffered_frames : Resume called for Queue=%d\n",queue);
-    unifi_trace(priv,UDBG2,"uf_send_buffered_frames : start=%d end=%d\n",startIndex,endIndex);
-
-    startIndex = priv->pausedStaHandle[queue];
-    endIndex = (startIndex + UNIFI_MAX_CONNECTIONS -1) % UNIFI_MAX_CONNECTIONS;
-
-    while(startIndex != endIndex) {
-        staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
-        if(!staInfo) {
-            startIndex ++;
-            if(startIndex >= UNIFI_MAX_CONNECTIONS) {
-                startIndex = 0;
-            }
-            continue;
-        } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
-                   &&(staInfo->uapsdActive == FALSE)) {
-            startIndex ++;
-            if(startIndex >= UNIFI_MAX_CONNECTIONS) {
-                startIndex = 0;
-            }
-            continue;
-        }
-        /* Peer is active or U-APSD is active so send PDUs to the peer */
-        unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying data from queue=%d\n",queue);
-
-
-        if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
-                           &&(staInfo->uapsdActive == FALSE)) {
-           if(!list_empty(&staInfo->dataPdu[queue])) {
-
-               /*Non-UAPSD case push the AC frames out*/
-               uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue]));
-           }
-        }
-        startIndex ++;
-        if(startIndex >= UNIFI_MAX_CONNECTIONS) {
-           startIndex = 0;
-        }
-    }
-    if(isRouterBufferEnabled(priv,queue)) {
-        priv->pausedStaHandle[queue] = endIndex;
-    } else {
-        priv->pausedStaHandle[queue] = 0;
-    }
-
-    /* U-APSD might have stopped because of ENOSPC in lib_hip (pause activity).
-     * So restart it if U-APSD was active with any of the station
-     */
-    unifi_trace(priv, UDBG4, "csrWifiHipSendBufferedFrames: UAPSD Resume Q=%x\n", queue);
-    resume_suspended_uapsd(priv, interfaceTag);
-}
-
-
-u8 uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord)
-{
-    u8 i;
-
-    for(i=0;i<=3;i++)
-    {
-        if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
-                ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_LEGACY_POWER_SAVE))
-                &&(!list_empty(&staRecord->dataPdu[i]))){
-
-         return TRUE;
-        }
-    }
-
-    if(((staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
-            ||(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_LEGACY_POWER_SAVE))
-            &&(!list_empty(&staRecord->mgtFrames))){
-
-     return TRUE;
-    }
-
-
-
-    return FALSE;
-}
-
-
-int uf_process_station_records_for_sending_data(unifi_priv_t *priv,u16 interfaceTag,
-                                                 CsrWifiRouterCtrlStaInfo_t *srcStaInfo,
-                                                 CsrWifiRouterCtrlStaInfo_t *dstStaInfo)
-{
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    unifi_trace(priv, UDBG5, "entering uf_process_station_records_for_sending_data\n");
-
-    if (srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED) {
-        unifi_error(priv, "Peer State not connected AID = %x, handle = %x, control port state = %x\n",
-                    srcStaInfo->aid, srcStaInfo->assignedHandle, srcStaInfo->peerControlledPort->port_action);
-        return -1;
-    }
-    switch (interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-            unifi_trace(priv, UDBG5, "mode is AP/P2PGO\n");
-            break;
-        default:
-            unifi_warning(priv, "mode is nor AP neither P2PGO, packet cant be xmit\n");
-            return -1;
-    }
-
-    switch(dstStaInfo->peerControlledPort->port_action)
-    {
-        case CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD:
-        case CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK:
-            unifi_trace(priv, UDBG5, "destination port is closed/blocked, discarding the packet\n");
-            return -1;
-        default:
-            unifi_trace(priv, UDBG5, "destination port state is open\n");
-    }
-
-    /* port state is open, destination station record is valid, Power save state is
-     * validated in uf_process_ma_packet_req function
-     */
-    unifi_trace(priv, UDBG5, "leaving uf_process_station_records_for_sending_data\n");
-    return 0;
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_handle_uspframes_delivery
- *
- *      This function takes care of handling USP session for peer, when
- *      -> trigger frame from peer
- *      -> suspended USP to be processed (resumed)
- *
- *      NOTE: uf_send_buffered_data_from_delivery_ac() always called from this function, Dont
- *      make a direct call to uf_send_buffered_data_from_delivery_ac() from any other part of
- *      code
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *      staInfo         peer for which UAPSD to be scheduled
- *      interfaceTag    virtual interface tag
- * ---------------------------------------------------------------------------
- */
-static void uf_handle_uspframes_delivery(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t *staInfo, u16 interfaceTag)
-{
-
-    s8 i;
-    u8 allDeliveryEnabled = 0, dataAvailable = 0;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    unsigned long lock_flags;
-
-    unifi_trace(priv, UDBG2, " ++ uf_handle_uspframes_delivery, uapsd active=%x, suspended?=%x\n",
-                staInfo->uapsdActive, staInfo->uspSuspend);
-
-    /* Check for Buffered frames according to priority order & deliver it
-     *  1. AC_VO delivery enable & Mgt frames available
-     *  2. Process remaining Ac's from order AC_VO to AC_BK
-     */
-
-    /* USP initiated by WMMPS enabled peer  & SET the status flag to TRUE */
-    if (!staInfo->uspSuspend && staInfo->uapsdActive)
-    {
-        unifi_notice(priv, "uf_handle_uspframes_delivery: U-APSD already active! STA=%x:%x:%x:%x:%x:%x\n",
-                staInfo->peerMacAddress.a[0], staInfo->peerMacAddress.a[1],
-                staInfo->peerMacAddress.a[2], staInfo->peerMacAddress.a[3],
-                staInfo->peerMacAddress.a[4], staInfo->peerMacAddress.a[5]);
-        return;
-    }
-
-    spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-    staInfo->uapsdActive = TRUE;
-    staInfo->uspSuspend = FALSE;
-    spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-
-    if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)||
-        (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE))
-        && (!list_empty(&staInfo->mgtFrames))) {
-
-         /* Management queue has data &&  UNIFI_TRAFFIC_Q_VO is delivery enable */
-        unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Sending buffered management frames\n");
-        uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
-    }
-
-    if (!uf_is_more_data_for_delivery_ac(priv, staInfo)) {
-        /* All delivery enable AC's are empty, so QNULL to be sent to terminate the USP
-         * NOTE: If we have sent Mgt frame also, we must send QNULL followed to terminate USP
-         */
-        if (!staInfo->uspSuspend) {
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            staInfo->uapsdActive = FALSE;
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-
-            unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: sending QNull for trigger\n");
-            uf_send_qos_null(priv, interfaceTag, staInfo->peerMacAddress.a, (CSR_PRIORITY) staInfo->triggerFramePriority, staInfo);
-            staInfo->triggerFramePriority = CSR_QOS_UP0;
-        } else {
-            unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: MgtQ xfer suspended\n");
-        }
-    } else {
-        for(i = UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--) {
-            if(((staInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
-                ||(staInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
-                && (!list_empty(&staInfo->dataPdu[i]))) {
-                /* Deliver Data according to AC priority (from VO to BK) as part of USP */
-                unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Buffered data frames from Queue (%d) for USP\n", i);
-                uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]);
-            }
-
-            if ((!staInfo->uapsdActive) ||
-                    (staInfo->uspSuspend && IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
-                /* If DTIM active found on one AC, No need to parse the remaining AC's
-                 * as USP suspended. Break out of loop
-                 */
-                unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: suspend=%x,  DTIM=%x, USP terminated=%s\n",
-                           staInfo->uspSuspend, IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag),
-                           staInfo->uapsdActive?"NO":"YES");
-                break;
-            }
-        }
-    }
-
-    /* Depending on the USP status, update the TIM accordingly for delivery enabled AC only
-     * (since we are not manipulating any Non-delivery list(AC))
-     */
-    is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable);
-    if ((allDeliveryEnabled && !dataAvailable)) {
-        if ((staInfo->timSet != CSR_WIFI_TIM_RESET) || (staInfo->timSet != CSR_WIFI_TIM_RESETTING)) {
-            staInfo->updateTimReqQueued = (u8) CSR_WIFI_TIM_RESET;
-            unifi_trace(priv, UDBG4, " --uf_handle_uspframes_delivery, UAPSD timset\n");
-            if (!staInfo->timRequestPendingFlag) {
-                update_tim(priv, staInfo->aid, 0, interfaceTag, staInfo->assignedHandle);
-            }
-        }
-    }
-    unifi_trace(priv, UDBG2, " --uf_handle_uspframes_delivery, uapsd active=%x, suspend?=%x\n",
-                staInfo->uapsdActive, staInfo->uspSuspend);
-}
-
-void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv,
-                                     CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
-                                     u16 qosControl,
-                                     u16 interfaceTag)
-{
-    CSR_PRIORITY priority;
-    unifi_TrafficQueue priority_q;
-    unsigned long lock_flags;
-
-    unifi_trace(priv, UDBG2, "++uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
-    /* If recceived Frames trigger Frame and Devlivery enabled AC has data
-     * then transmit from High priorty delivery enabled AC
-     */
-    priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
-    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
-
-    if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
-        ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) {
-        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-        srcStaInfo->triggerFramePriority = priority;
-        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-        unifi_trace(priv, UDBG2, "uf_process_wmm_deliver_ac_uapsd: trigger frame, Begin U-APSD, triggerQ=%x\n", priority_q);
-        uf_handle_uspframes_delivery(priv, srcStaInfo, interfaceTag);
-    }
-    unifi_trace(priv, UDBG2, "--uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
-}
-
-
-void uf_send_qos_null(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo)
-{
-    bulk_data_param_t bulkdata;
-    CsrResult csrResult;
-    struct sk_buff *skb, *newSkb = NULL;
-    CsrWifiMacAddress peerAddress;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_EOSP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK);
-    int r;
-    CSR_SIGNAL signal;
-    u32 priority_q;
-    CSR_RATE transmitRate = 0;
-
-
-    /* Send a Null Frame to Peer,
-     * 32= size of mac header  */
-    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE + QOS_CONTROL_HEADER_SIZE);
-
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, " failed to allocate request_data. in uf_send_qos_null func\n");
-        return ;
-    }
-    skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
-    skb->len = 0;
-    bulkdata.d[0].os_data_ptr = skb->data;
-    bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
-    bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len;
-    bulkdata.d[1].os_data_ptr = NULL;
-    bulkdata.d[1].os_net_buf_ptr = NULL;
-    bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
-
-    /* For null frames protection bit should not be set in MAC header, so passing value 0 below for protection field */
-
-    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, da, interfacePriv->bssid.a, 0)) {
-        unifi_error(priv, "failed to create MAC header\n");
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-        return;
-    }
-    memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
-    /* convert priority to queue */
-    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
-
-    /* Frame ma-packet.req, this is saved/transmitted depend on queue state
-     * send the null frame at data rate of 1 Mb/s for AP or 6 Mb/s for P2PGO
-     */
-    switch (interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-            transmitRate = 2;
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            transmitRate = 12;
-            break;
-        default:
-            transmitRate = 0;
-    }
-    unifi_frame_ma_packet_req(priv, priority, transmitRate, 0xffffffff, interfaceTag,
-                              transmissionControl, priv->netdev_client->sender_id,
-                              peerAddress.a, &signal);
-
-    r = ul_send_signal_unpacked(priv, &signal, &bulkdata);
-    if(r) {
-        unifi_error(priv, "failed to send QOS data null packet result: %d\n",r);
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-    }
-
-    return;
-
-}
-void uf_send_nulldata(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo)
-{
-    bulk_data_param_t bulkdata;
-    CsrResult csrResult;
-    struct sk_buff *skb, *newSkb = NULL;
-    CsrWifiMacAddress peerAddress;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    CSR_TRANSMISSION_CONTROL transmissionControl = 0;
-    int r;
-    CSR_SIGNAL signal;
-    u32 priority_q;
-    CSR_RATE transmitRate = 0;
-    CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
-    unsigned long lock_flags;
-
-    /* Send a Null Frame to Peer, size = 24 for MAC header */
-    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE);
-
-    if (csrResult != CSR_RESULT_SUCCESS) {
-        unifi_error(priv, "uf_send_nulldata: Failed to allocate memory for NULL frame\n");
-        return ;
-    }
-    skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
-    skb->len = 0;
-    bulkdata.d[0].os_data_ptr = skb->data;
-    bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
-    bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len;
-    bulkdata.d[1].os_data_ptr = NULL;
-    bulkdata.d[1].os_net_buf_ptr = NULL;
-    bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
-
-    /* For null frames protection bit should not be set in MAC header, so passing value 0 below for protection field */
-    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, da, interfacePriv->bssid.a, 0)) {
-        unifi_error(priv, "uf_send_nulldata: Failed to create MAC header\n");
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-        return;
-    }
-    memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
-    /* convert priority to queue */
-    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
-    transmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED);
-
-    /* Frame ma-packet.req, this is saved/transmitted depend on queue state
-     * send the null frame at data rate of 1 Mb/s for AP or 6 Mb/s for P2PGO
-     */
-    switch (interfacePriv->interfaceMode)
-    {
-        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
-            transmitRate = 2;
-            break;
-        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
-            transmitRate = 12;
-            break;
-        default:
-            transmitRate = 0;
-    }
-    unifi_frame_ma_packet_req(priv, priority, transmitRate, INVALID_HOST_TAG, interfaceTag,
-                              transmissionControl, priv->netdev_client->sender_id,
-                              peerAddress.a, &signal);
-
-    /* Save host tag to check the status on reception of MA packet confirm */
-    srcStaInfo->nullDataHostTag = req->HostTag;
-    unifi_trace(priv, UDBG1, "uf_send_nulldata: STA AID = %d hostTag = %x\n", srcStaInfo->aid, req->HostTag);
-
-    r = ul_send_signal_unpacked(priv, &signal, &bulkdata);
-
-    if(r == -ENOSPC) {
-        unifi_trace(priv, UDBG1, "uf_send_nulldata: ENOSPC Requeue the Null frame\n");
-        enque_tx_data_pdu(priv, &bulkdata, &srcStaInfo->dataPdu[priority_q], &signal, 1);
-        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-        srcStaInfo->noOfPktQueued++;
-        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-
-
-    }
-    if(r && r != -ENOSPC){
-        unifi_error(priv, "uf_send_nulldata: Failed to send Null frame Error = %d\n",r);
-        unifi_net_data_free(priv, &bulkdata.d[0]);
-        srcStaInfo->nullDataHostTag = INVALID_HOST_TAG;
-    }
-
-    return;
-}
-
-u8 uf_check_broadcast_bssid(unifi_priv_t *priv, const bulk_data_param_t *bulkdata)
-{
-    u8 *bssid = NULL;
-    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
-    u8 toDs, fromDs;
-
-    toDs = (((bulkdata->d[0].os_data_ptr)[1]) & 0x01) ? 1 : 0;
-    fromDs =(((bulkdata->d[0].os_data_ptr)[1]) & 0x02) ? 1 : 0;
-
-     if (toDs && fromDs)
-    {
-        unifi_trace(priv, UDBG6, "Address 4 present, Don't try to find BSSID\n");
-        bssid = NULL;
-    }
-    else if((toDs == 0) && (fromDs ==0))
-    {
-        /* BSSID is Address 3 */
-        bssid = (u8 *) (bulkdata->d[0].os_data_ptr + 4 + (2 * ETH_ALEN));
-    }
-    else if(toDs)
-    {
-        /* BSSID is Address 1 */
-        bssid = (u8 *) (bulkdata->d[0].os_data_ptr + 4);
-    }
-    else if(fromDs)
-    {
-        /* BSSID is Address 2 */
-        bssid = (u8 *) (bulkdata->d[0].os_data_ptr + 4 + ETH_ALEN);
-    }
-
-    if (memcmp(broadcast_address.a, bssid, ETH_ALEN)== 0)
-    {
-        return TRUE;
-    }
-    else
-    {
-        return FALSE;
-    }
-}
-
-
-u8 uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
-                                u8 pmBit,u16 interfaceTag)
-{
-    u8 moreData = FALSE;
-    u8 powerSaveChanged = FALSE;
-    unsigned long lock_flags;
-
-    unifi_trace(priv, UDBG3, "entering uf_process_pm_bit_for_peer\n");
-    if (pmBit) {
-        priv->allPeerDozing |= (0x01 << (srcStaInfo->assignedHandle));
-    } else {
-        priv->allPeerDozing &= ~(0x01 << (srcStaInfo->assignedHandle));
-    }
-    if(pmBit) {
-        if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) {
-
-            /* disable the preemption */
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            srcStaInfo->currentPeerState =CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE;
-            powerSaveChanged = TRUE;
-            /* enable the preemption */
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-        } else {
-            return powerSaveChanged;
-        }
-    } else {
-        if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) {
-            /* disable the preemption */
-            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-            srcStaInfo->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE;
-            powerSaveChanged = TRUE;
-            /* enable the preemption */
-            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-        }else {
-            return powerSaveChanged;
-        }
-    }
-
-
-    if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) {
-        unifi_trace(priv,UDBG3, "Peer with AID = %d is active now\n",srcStaInfo->aid);
-        process_peer_active_transition(priv,srcStaInfo,interfaceTag);
-    } else {
-        unifi_trace(priv,UDBG3, "Peer with AID = %d is in PS Now\n",srcStaInfo->aid);
-        /* Set TIM if needed */
-        if(!srcStaInfo->wmmOrQosEnabled) {
-            moreData = (!list_empty(&srcStaInfo->mgtFrames) ||
-                        !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_VO])||
-                        !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]));
-            if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
-                unifi_trace(priv, UDBG3, "This condition should not occur\n");
-                if (!srcStaInfo->timRequestPendingFlag){
-                    update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
-                }
-                else
-                {
-                    /* Cache the TimSet value so that it will processed immidiatly after
-                     * completing the current setTim Request
-                     */
-                    srcStaInfo->updateTimReqQueued = 1;
-                    unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
-                                srcStaInfo->aid);
-                }
-
-            }
-        } else {
-            u8 allDeliveryEnabled = 0, dataAvailable = 0;
-            unifi_trace(priv, UDBG5, "Qos in AP Mode\n");
-            /* Check if all AC's are Delivery Enabled */
-            is_all_ac_deliver_enabled_and_moredata(srcStaInfo, &allDeliveryEnabled, &dataAvailable);
-            /*check for more data in non-delivery enabled queues*/
-            moreData = (uf_is_more_data_for_non_delivery_ac(srcStaInfo) || (allDeliveryEnabled && dataAvailable));
-
-            if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
-                if (!srcStaInfo->timRequestPendingFlag){
-                    update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
-                }
-                else
-                {
-                    /* Cache the TimSet value so that it will processed immidiatly after
-                     * completing the current setTim Request
-                     */
-                    srcStaInfo->updateTimReqQueued = 1;
-                    unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
-                                srcStaInfo->aid);
-                }
-            }
-        }
-    }
-    unifi_trace(priv, UDBG3, "leaving uf_process_pm_bit_for_peer\n");
-    return powerSaveChanged;
-}
-
-
-
-void uf_process_ps_poll(unifi_priv_t *priv,u8* sa,u8* da,u8 pmBit,u16 interfaceTag)
-{
-    CsrWifiRouterCtrlStaInfo_t *staRecord =
-    CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, sa, interfaceTag);
-    tx_buffered_packets_t * buffered_pkt = NULL;
-    CsrWifiMacAddress peerMacAddress;
-    unsigned long lock_flags;
-    s8 r =0;
-    u8 moreData = FALSE;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    unifi_trace(priv, UDBG3, "entering uf_process_ps_poll\n");
-    if(!staRecord) {
-        memcpy(peerMacAddress.a,sa,ETH_ALEN);
-        unifi_trace(priv, UDBG3, "In uf_process_ps_poll, sta record not found:unexpected frame addr = %x:%x:%x:%x:%x:%x\n",
-                sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
-        CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
-        return;
-    }
-
-    uf_process_pm_bit_for_peer(priv,staRecord,pmBit,interfaceTag);
-
-    /* Update station last activity time */
-    staRecord->activity_flag = TRUE;
-
-    /* This should not change the PM bit as PS-POLL has PM bit always set */
-    if(!pmBit) {
-        unifi_notice (priv," PM bit reset in PS-POLL\n");
-        return;
-    }
-
-    if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
-        /* giving more priority to multicast packets so dropping ps-poll*/
-        unifi_notice (priv," multicast transmission is going on so don't take action on PS-POLL\n");
-        return;
-    }
-
-    if(!staRecord->wmmOrQosEnabled) {
-        if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
-            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
-            moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
-                        !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
-                        !list_empty(&staRecord->mgtFrames));
-
-            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
-                /* Clear the trigger bit transmission control*/
-                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-                /* Enqueue at the head of the queue */
-                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                list_add(&buffered_pkt->q, &staRecord->mgtFrames);
-                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-                unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
-                priv->pausedStaHandle[3]=(u8)(staRecord->assignedHandle);
-            } else {
-                if(r){
-                    unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                    /* the PDU failed where we can't do any thing so free the storage */
-                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-                }
-                kfree(buffered_pkt);
-            }
-        } else if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]))) {
-            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
-            moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
-                        !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]));
-
-            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
-                /* Clear the trigger bit transmission control*/
-                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-                /* Enqueue at the head of the queue */
-                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]);
-                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-                priv->pausedStaHandle[3]=(u8)(staRecord->assignedHandle);
-                unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
-            } else {
-                if(r){
-                    unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                    /* the PDU failed where we can't do any thing so free the storage */
-                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-                }
-                kfree(buffered_pkt);
-            }
-        } else  if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]))) {
-            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
-            moreData = !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);
-
-            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
-                /* Clear the trigger bit transmission control*/
-                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-                /* Enqueue at the head of the queue */
-                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);
-                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-                priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
-                unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
-            } else {
-                if(r){
-                    unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                    /* the PDU failed where we can't do any thing so free the storage */
-                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-                }
-                kfree(buffered_pkt);
-            }
-        } else {
-         /* Actually since we have sent an ACK, there
-         * there is no need to send a NULL frame*/
-        }
-        moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
-           !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
-            !list_empty(&staRecord->mgtFrames));
-        if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
-            unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
-            if (!staRecord->timRequestPendingFlag){
-                update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
-            }
-            else
-            {
-                /* Cache the TimSet value so that it will processed immidiatly after
-                 * completing the current setTim Request
-                 */
-                staRecord->updateTimReqQueued = 0;
-                unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
-                            staRecord->aid);
-            }
-        }
-    } else {
-
-        u8 allDeliveryEnabled = 0, dataAvailable = 0;
-        unifi_trace(priv, UDBG3,"Qos Support station.Processing PS-Poll\n");
-
-        /*Send Data From Management Frames*/
-        /* Priority orders for delivering the buffered packets are
-         * 1. Deliver the Management frames if there
-         * 2. Other access category frames which are non deliver enable including UNIFI_TRAFFIC_Q_VO
-         * priority is from VO->BK
-         */
-
-        /* Check if all AC's are Delivery Enabled */
-        is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
-
-        if (allDeliveryEnabled) {
-            unifi_trace(priv, UDBG3, "uf_process_ps_poll: All ACs are delivery enable so Sending QOS Null in response of Ps-poll\n");
-            uf_send_qos_null(priv,interfaceTag,sa,CSR_QOS_UP0,staRecord);
-            return;
-        }
-
-        if (!list_empty(&staRecord->mgtFrames)) {
-             if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
-                    /* We dont have packets in non delivery enabled UNIFI_TRAFFIC_Q_VO, So we are looking in management
-                     * queue of the station record
-                     */
-                    moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
-                    buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-
-                    /* Last parameter is EOSP & its false always for PS-POLL processing */
-                    if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
-                        /* Clear the trigger bit transmission control*/
-                        buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-                        /* Enqueue at the head of the queue */
-                        spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                        list_add(&buffered_pkt->q, &staRecord->mgtFrames);
-                        spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-                        priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
-                        unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
-                    } else {
-                        if(r){
-                            unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                            /* the PDU failed where we can't do any thing so free the storage */
-                            unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-                        }
-                        kfree(buffered_pkt);
-                    }
-                } else {
-                    unifi_error(priv, "uf_process_ps_poll: Mgt frame list empty!! \n");
-                }
-
-        } else {
-            s8 i;
-            /* We dont have buffered packet in mangement frame queue (1 failed), So proceed with condition 2
-             * UNIFI_TRAFFIC_Q_VO -> VI -> BE -> BK
-             */
-            for(i= 3; i>=0; i--) {
-                if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) {
-                    /* Send One packet, if queue is NULL then continue */
-                    if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
-                        moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
-
-                        buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-
-                        /* Last parameter is EOSP & its false always for PS-POLL processing */
-                        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
-                            /* Clear the trigger bit transmission control*/
-                            buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
-                            /* Enqueue at the head of the queue */
-                            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                            list_add(&buffered_pkt->q, &staRecord->dataPdu[i]);
-                            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-                            priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
-                            unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
-                        } else {
-                            if(r) {
-                                unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                                /* the PDU failed where we can't do any thing so free the storage */
-                                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-                            }
-                            kfree(buffered_pkt);
-                        }
-                        break;
-                    }
-                }
-            }
-        }
-        /* Check if all AC's are Delivery Enabled */
-        is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
-        /*check for more data in non-delivery enabled queues*/
-        moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable));
-        if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
-            unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
-            if (!staRecord->timRequestPendingFlag){
-                update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
-            }
-            else
-            {
-                /* Cache the TimSet value so that it will processed immidiatly after
-                 * completing the current setTim Request
-                 */
-                staRecord->updateTimReqQueued = 0;
-                unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
-                            staRecord->aid);
-            }
-
-        }
-    }
-
-        unifi_trace(priv, UDBG3, "leaving uf_process_ps_poll\n");
-}
-
-
-
-void add_to_send_cfm_list(unifi_priv_t * priv,
-                          tx_buffered_packets_t *tx_q_item,
-                          struct list_head *frames_need_cfm_list)
-{
-    tx_buffered_packets_t *send_cfm_list_item = NULL;
-
-    send_cfm_list_item = kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC);
-
-    if(send_cfm_list_item == NULL){
-        unifi_warning(priv, "%s: Failed to allocate memory for new list item \n");
-        return;
-    }
-
-    INIT_LIST_HEAD(&send_cfm_list_item->q);
-
-    send_cfm_list_item->hostTag = tx_q_item->hostTag;
-    send_cfm_list_item->interfaceTag = tx_q_item->interfaceTag;
-    send_cfm_list_item->transmissionControl = tx_q_item->transmissionControl;
-    send_cfm_list_item->leSenderProcessId = tx_q_item->leSenderProcessId;
-    send_cfm_list_item->rate = tx_q_item->rate;
-    memcpy(send_cfm_list_item->peerMacAddress.a, tx_q_item->peerMacAddress.a, ETH_ALEN);
-    send_cfm_list_item->priority = tx_q_item->priority;
-
-    list_add_tail(&send_cfm_list_item->q, frames_need_cfm_list);
-}
-
-void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv,
-                                                 struct list_head *frames_need_cfm_list,
-                                                 struct list_head * list)
-{
-    tx_buffered_packets_t *tx_q_item = NULL;
-    struct list_head *listHead;
-    struct list_head *placeHolder;
-    unsigned long lock_flags;
-
-    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-
-    /* Search through the list and if confirmation required for any frames,
-    add it to the send_cfm list */
-    list_for_each_safe(listHead, placeHolder, list) {
-        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
-
-        if(!tx_q_item) {
-            unifi_error(priv, "Entry should exist, otherwise it is a (BUG)\n");
-            continue;
-        }
-
-        /* check if confirmation is requested and if the sender ID
-        is not netdevice client then save the entry in the list for need cfms */
-        if (!(tx_q_item->transmissionControl & CSR_NO_CONFIRM_REQUIRED) &&
-            (tx_q_item->leSenderProcessId != priv->netdev_client->sender_id)){
-             unifi_trace(priv, UDBG1, "%s: SenderProcessID=%x host tag=%x transmission control=%x\n",
-                __FUNCTION__,
-                tx_q_item->leSenderProcessId,
-                tx_q_item->hostTag,
-                tx_q_item->transmissionControl);
-
-             add_to_send_cfm_list(priv, tx_q_item, frames_need_cfm_list);
-        }
-    }
-
-    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-
-}
-
-
-
-void uf_flush_list(unifi_priv_t * priv, struct list_head * list)
-{
-    tx_buffered_packets_t *tx_q_item;
-    struct list_head *listHead;
-    struct list_head *placeHolder;
-    unsigned long lock_flags;
-
-    unifi_trace(priv, UDBG5, "entering the uf_flush_list \n");
-
-    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-    /* go through list, delete & free memory */
-    list_for_each_safe(listHead, placeHolder, list) {
-        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
-
-        if(!tx_q_item) {
-            unifi_error(priv, "entry should exists, otherwise crashes (bug)\n");
-        }
-        unifi_trace(priv, UDBG5,
-                "proccess_tx:  in uf_flush_list peerMacAddress=%02X%02X%02X%02X%02X%02X senderProcessId=%x\n",
-                tx_q_item->peerMacAddress.a[0], tx_q_item->peerMacAddress.a[1],
-                tx_q_item->peerMacAddress.a[2], tx_q_item->peerMacAddress.a[3],
-                tx_q_item->peerMacAddress.a[4], tx_q_item->peerMacAddress.a[5],
-                tx_q_item->leSenderProcessId);
-
-        list_del(listHead);
-        /* free the allocated memory */
-        unifi_net_data_free(priv, &tx_q_item->bulkdata);
-        kfree(tx_q_item);
-        tx_q_item = NULL;
-        if (!priv->noOfPktQueuedInDriver) {
-            unifi_error(priv, "packets queued in driver 0 still decrementing in %s\n", __FUNCTION__);
-        } else {
-            priv->noOfPktQueuedInDriver--;
-        }
-    }
-    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-}
-
-tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList)
-{
-    /* dequeue the tx data packets from the appropriate queue */
-    tx_buffered_packets_t *tx_q_item = NULL;
-    struct list_head *listHead;
-    struct list_head *placeHolder;
-    unsigned long lock_flags;
-
-    unifi_trace(priv, UDBG5, "entering dequeue_tx_data_pdu\n");
-    /* check for list empty */
-    if (list_empty(txList)) {
-        unifi_trace(priv, UDBG5, "In dequeue_tx_data_pdu, the list is empty\n");
-        return NULL;
-    }
-
-    /* Verification, if packet count is negetive */
-    if (priv->noOfPktQueuedInDriver == 0xFFFF) {
-        unifi_warning(priv, "no packet available in queue: debug");
-        return NULL;
-    }
-
-    /* return first node after header, & delete from the list  && atleast one item exist */
-    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-    list_for_each_safe(listHead, placeHolder, txList) {
-        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
-        list_del(listHead);
-        break;
-    }
-    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-
-    if (tx_q_item) {
-        unifi_trace(priv, UDBG5,
-                "proccess_tx:  In dequeue_tx_data_pdu peerMacAddress=%02X%02X%02X%02X%02X%02X senderProcessId=%x\n",
-                tx_q_item->peerMacAddress.a[0], tx_q_item->peerMacAddress.a[1],
-                tx_q_item->peerMacAddress.a[2], tx_q_item->peerMacAddress.a[3],
-                tx_q_item->peerMacAddress.a[4], tx_q_item->peerMacAddress.a[5],
-                tx_q_item->leSenderProcessId);
-    }
-
-    unifi_trace(priv, UDBG5, "leaving dequeue_tx_data_pdu\n");
-    return tx_q_item;
-}
-/* generic function to get the station record handler */
-CsrWifiRouterCtrlStaInfo_t *CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(unifi_priv_t *priv,
-        const u8 *peerMacAddress,
-        u16 interfaceTag)
-{
-    u8 i;
-    netInterface_priv_t *interfacePriv;
-    unsigned long lock_flags;
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "interfaceTag is not proper, interfaceTag = %d\n", interfaceTag);
-        return NULL;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    /* disable the preemption until station record is fetched */
-    spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-
-    for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        if (interfacePriv->staInfo[i]!= NULL) {
-            if (!memcmp(((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]))->peerMacAddress.a, peerMacAddress, ETH_ALEN)) {
-                /* enable the preemption as station record is fetched */
-                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-                unifi_trace(priv, UDBG5, "peer entry found in station record\n");
-                return ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]));
-            }
-        }
-    }
-    /* enable the preemption as station record is fetched */
-    spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-    unifi_trace(priv, UDBG5, "peer entry not found in station record\n");
-    return NULL;
-}
-/* generic function to get the station record handler from the handle */
-CsrWifiRouterCtrlStaInfo_t * CsrWifiRouterCtrlGetStationRecordFromHandle(unifi_priv_t *priv,
-                                                                 u32 handle,
-                                                                 u16 interfaceTag)
-{
-    netInterface_priv_t *interfacePriv;
-
-    if ((handle >= UNIFI_MAX_CONNECTIONS) || (interfaceTag >= CSR_WIFI_NUM_INTERFACES)) {
-        unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", handle, interfaceTag);
-        return NULL;
-    }
-    interfacePriv = priv->interfacePriv[interfaceTag];
-    return ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]));
-}
-
-/* Function to do inactivity */
-void uf_check_inactivity(unifi_priv_t *priv, u16 interfaceTag, u32 currentTime)
-{
-    u32 i;
-    CsrWifiRouterCtrlStaInfo_t *staInfo;
-    u32 elapsedTime;    /* Time in microseconds */
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    CsrWifiMacAddress peerMacAddress;
-    unsigned long lock_flags;
-
-    if (interfacePriv == NULL) {
-        unifi_trace(priv, UDBG3, "uf_check_inactivity: Interface priv is NULL \n");
-        return;
-    }
-
-    spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-    /* Go through the list of stations to check for inactivity */
-    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv, i, interfaceTag);
-        if(!staInfo ) {
-            continue;
-        }
-
-        unifi_trace(priv, UDBG3, "Running Inactivity handler Time %xus station's last activity %xus\n",
-                currentTime, staInfo->lastActivity);
-
-
-        elapsedTime = (currentTime >= staInfo->lastActivity)?
-                (currentTime - staInfo->lastActivity):
-                (~((u32)0) - staInfo->lastActivity + currentTime);
-        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-
-        if (elapsedTime > MAX_INACTIVITY_INTERVAL) {
-            memcpy((u8*)&peerMacAddress, (u8*)&staInfo->peerMacAddress, sizeof(CsrWifiMacAddress));
-
-            /* Indicate inactivity for the station */
-            unifi_trace(priv, UDBG3, "Station %x:%x:%x:%x:%x:%x inactive since %xus\n sending Inactive Ind\n",
-                        peerMacAddress.a[0], peerMacAddress.a[1],
-                        peerMacAddress.a[2], peerMacAddress.a[3],
-                        peerMacAddress.a[4], peerMacAddress.a[5],
-                        elapsedTime);
-
-            CsrWifiRouterCtrlStaInactiveIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress);
-        }
-    }
-
-    interfacePriv->last_inactivity_check = currentTime;
-}
-
-/* Function to update activity of a station */
-void uf_update_sta_activity(unifi_priv_t *priv, u16 interfaceTag, const u8 *peerMacAddress)
-{
-    u32 elapsedTime, currentTime;    /* Time in microseconds */
-    u32 timeHi;         /* Not used - Time in microseconds */
-    CsrWifiRouterCtrlStaInfo_t *staInfo;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    unsigned long lock_flags;
-
-    if (interfacePriv == NULL) {
-        unifi_trace(priv, UDBG3, "uf_check_inactivity: Interface priv is NULL \n");
-        return;
-    }
-
-    currentTime = CsrTimeGet(&timeHi);
-
-
-    staInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, peerMacAddress, interfaceTag);
-
-    if (staInfo == NULL) {
-        unifi_trace(priv, UDBG4, "Sta does not exist yet");
-        return;
-    }
-
-    spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-    /* Update activity */
-    staInfo->lastActivity = currentTime;
-
-    /* See if inactivity handler needs to be run
-     * Here it is theoretically possible that the counter may have wrapped around. But
-     * since we just want to know when to run the inactivity handler it does not really matter.
-     * Especially since this is data path it makes sense in keeping it simple and avoiding
-     * 64 bit handling */
-    elapsedTime = (currentTime >= interfacePriv->last_inactivity_check)?
-                    (currentTime - interfacePriv->last_inactivity_check):
-                    (~((u32)0) - interfacePriv->last_inactivity_check + currentTime);
-
-    spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-
-    /* Check if it is time to run the inactivity handler */
-    if (elapsedTime > INACTIVITY_CHECK_INTERVAL) {
-        uf_check_inactivity(priv, interfaceTag, currentTime);
-    }
-}
-void resume_unicast_buffered_frames(unifi_priv_t *priv, u16 interfaceTag)
-{
-
-   netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-   u8 i;
-   int j;
-   tx_buffered_packets_t * buffered_pkt = NULL;
-   u8 hipslotFree[4] = {TRUE,TRUE,TRUE,TRUE};
-   int r;
-   unsigned long lock_flags;
-
-   while(!isRouterBufferEnabled(priv,3) &&
-                            ((buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMgtFrames))!=NULL)) {
-        buffered_pkt->transmissionControl &=
-                     ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
-        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,0,FALSE)) == -ENOSPC) {
-            /* Enqueue at the head of the queue */
-            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-            list_add(&buffered_pkt->q, &interfacePriv->genericMgtFrames);
-            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-            hipslotFree[3]=FALSE;
-            break;
-        }else {
-            if(r){
-                unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                /* the PDU failed where we can't do any thing so free the storage */
-                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-            }
-            kfree(buffered_pkt);
-        }
-   }
-   for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        CsrWifiRouterCtrlStaInfo_t *staInfo = interfacePriv->staInfo[i];
-        if(!hipslotFree[0] && !hipslotFree[1] && !hipslotFree[2] && !hipslotFree[3]) {
-            unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full \n");
-            break;
-        }
-        if (staInfo && (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)) {
-          while((( TRUE == hipslotFree[3] ) && (buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->mgtFrames)))) {
-              buffered_pkt->transmissionControl &=
-                           ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
-              if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) {
-                  unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full for voice queue\n");
-                  /* Enqueue at the head of the queue */
-                  spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                  list_add(&buffered_pkt->q, &staInfo->mgtFrames);
-                  spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-                  priv->pausedStaHandle[3]=(u8)(staInfo->assignedHandle);
-                  hipslotFree[3] = FALSE;
-                  break;
-              } else {
-                  if(r){
-                      unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                      /* the PDU failed where we can't do any thing so free the storage */
-                      unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-                  }
-                  kfree(buffered_pkt);
-              }
-          }
-
-          for(j=3;j>=0;j--) {
-              if(!hipslotFree[j])
-                  continue;
-
-              while((buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->dataPdu[j]))) {
-                 buffered_pkt->transmissionControl &=
-                            ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
-                 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) {
-                     /* Enqueue at the head of the queue */
-                     spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-                     list_add(&buffered_pkt->q, &staInfo->dataPdu[j]);
-                     spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-                     priv->pausedStaHandle[j]=(u8)(staInfo->assignedHandle);
-                     hipslotFree[j]=FALSE;
-                     break;
-                 } else {
-                    if(r){
-                        unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
-                        /* the PDU failed where we can't do any thing so free the storage */
-                        unifi_net_data_free(priv, &buffered_pkt->bulkdata);
-                     }
-                    kfree(buffered_pkt);
-                 }
-              }
-          }
-       }
-    }
-}
-void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,u16 interfaceTag)
-{
-
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-    unsigned long lock_flags;
-    struct list_head *listHead;
-    struct list_head *placeHolder;
-    tx_buffered_packets_t *tx_q_item;
-
-    if (interfacePriv->noOfbroadcastPktQueued) {
-
-        /* Update the EOSP to the HEAD of b/c list
-         * because we have received any mgmt packet so it should not hold for long time
-         * peer may time out.
-         */
-        spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
-        list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
-            tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
-            tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
-            tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
-            unifi_trace(priv, UDBG1,"updating eosp for list Head hostTag:= 0x%x ",tx_q_item->hostTag);
-            break;
-        }
-        spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-    }
-}
-
-/*
- * ---------------------------------------------------------------------------
- *  resume_suspended_uapsd
- *
- *      This function takes care processing packets of Unscheduled Service Period,
- *      which been suspended earlier due to DTIM/HIP ENOSPC scenarios
- *
- *  Arguments:
- *      priv            Pointer to device private context struct
- *      interfaceTag    For which resume should happen
- * ---------------------------------------------------------------------------
- */
-void resume_suspended_uapsd(unifi_priv_t* priv,u16 interfaceTag)
-{
-
-   u8 startIndex;
-   CsrWifiRouterCtrlStaInfo_t * staInfo = NULL;
-    unsigned long lock_flags;
-
-    unifi_trace(priv, UDBG2, "++resume_suspended_uapsd: \n");
-    for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) {
-        staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
-
-        if(!staInfo || !staInfo->wmmOrQosEnabled) {
-            continue;
-        } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
-                   &&staInfo->uapsdActive && staInfo->uspSuspend) {
-            /* U-APSD Still active & previously suspended either ENOSPC of FH queues OR
-             * due to DTIM activity
-             */
-            uf_handle_uspframes_delivery(priv, staInfo, interfaceTag);
-        } else {
-            unifi_trace(priv, UDBG2, "resume_suspended_uapsd: PS state=%x, uapsdActive?=%x, suspend?=%x\n",
-                        staInfo->currentPeerState, staInfo->uapsdActive, staInfo->uspSuspend);
-            if (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
-            {
-                spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
-                staInfo->uapsdActive = FALSE;
-                staInfo->uspSuspend = FALSE;
-                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-            }
-        }
-    }
-    unifi_trace(priv, UDBG2, "--resume_suspended_uapsd:\n");
-}
-
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_priv.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_priv.h
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_priv.h	2013-07-01 10:38:12.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_priv.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1136 +0,0 @@
-/*
- *****************************************************************************
- *
- * FILE : unifi_priv.h
- *
- * PURPOSE : Private header file for unifi driver.
- *
- *           UDI = UniFi Debug Interface
- *
- * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- *****************************************************************************
- */
-#ifndef __LINUX_UNIFI_PRIV_H__
-#define __LINUX_UNIFI_PRIV_H__ 1
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-#include <linux/cdev.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-
-#ifdef CSR_WIFI_SUPPORT_MMC_DRIVER
-#include <linux/mmc/core.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio.h>
-#endif /* CSR_WIFI_SUPPORT_MMC_DRIVER */
-
-#include <linux/fs.h>
-
-#ifdef ANDROID_BUILD
-#include <linux/wakelock.h>
-#endif
-
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_unifi_udi.h"
-#include "csr_wifi_router_lib.h"
-#include "unifiio.h"
-#ifndef CSR_WIFI_HIP_TA_DISABLE
-#include "csr_wifi_vif_utils.h"
-#endif
-
-/* Define the unifi_priv_t before include the unifi_native.h */
-struct unifi_priv;
-typedef struct unifi_priv unifi_priv_t;
-#ifdef CSR_SUPPORT_WEXT_AP
-struct CsrWifiSmeApConfig;
-typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t;
-#endif
-#ifdef CSR_SUPPORT_WEXT
-#include "unifi_wext.h"
-#endif
-
-#ifdef ANDROID_BUILD
-extern struct wake_lock unifi_sdio_wake_lock;
-#endif
-
-#include "unifi_clients.h"
-
-#ifdef CSR_NATIVE_LINUX
-#include "sme_native/unifi_native.h"
-#else
-#include "unifi_sme.h"
-#endif
-
-/* The device major number to use when registering the udi driver */
-#define UNIFI_NAME      "unifi"
-/*
- * MAX_UNIFI_DEVS defines the maximum number of UniFi devices that can be present.
- * This number should be set to the number of SDIO slots supported by the SDIO
- * host controller on the platform.
- * Note: If MAX_UNIFI_DEVS value changes, fw_init[] needs to be corrected in drv.c
- */
-#define MAX_UNIFI_DEVS  2
-
-/* 802.11 Mac header offsets */
-#define MAC_HEADER_SIZE  24
-#define QOS_CONTROL_HEADER_SIZE 2
-#define HT_CONTROL_HEADER_SIZE  4
-#define QOS_DATA 0x8
-#define QOS_DATA_NULL 0xc
-#define DATA_NULL 0x04
-#define FRAME_CONTROL_ORDER_BIT 0x8000
-#define FRAME_CONTROL_TYPE_FIELD_OFFSET  2
-#define FRAME_CONTROL_SUBTYPE_FIELD_OFFSET  4
-#define IEEE802_11_FRAMETYPE_DATA 0x02
-#define IEEE802_11_FRAMETYPE_CONTROL 0x01
-#define IEEE802_11_FRAMETYPE_MANAGEMENT 0x00
-#define IEEE802_11_FRAMETYPE_RESERVED 0x03
-
-/* octet offset from start of mac header for certain fields */
-#define IEEE802_11_ADDR3_OFFSET 16
-#define IEEE802_11_SEQUENCE_CONTROL_OFFSET 22
-#define IEEE802_11_MAX_DATA_LEN 2304
-
-/* frame control (FC) masks, for frame control as 16 bit integer */
-#define IEEE802_11_FC_TO_DS_MASK 0x100
-#define IEEE802_11_FC_FROM_DS_MASK 0x200
-#define IEEE802_11_FC_MOREDATA_MASK 0x2000
-#define IEEE802_11_FC_PROTECTED_MASK 0x4000
-#define IEEE80211_FC_ORDER_MASK 0x8000
-#define IEEE80211_FC_SUBTYPE_MASK 0x00f0
-#define IEEE80211_FC_TYPE_MASK 0x000c
-#define IEEE80211_FC_PROTO_VERSION_MASK 0x0003
-
-/*  selected type and subtype combinations as in 7.1.3.1 table 1
-    For frame control as 16 bit integer, or for ls octet
-*/
-#define IEEE802_11_FC_TYPE_DATA 0x08
-#define IEEE802_11_FC_TYPE_NULL 0x48
-#define IEEE802_11_FC_TYPE_QOS_NULL 0xc8
-#define IEEE802_11_FC_TYPE_QOS_DATA 0x88
-
-#define IEEE802_11_FC_TYPE_DATA_SUBTYPE_RESERVED 0x0D
-
-/* qos control (QC) masks for qos control as 16 bit integer, or for ls octet */
-#define IEEE802_11_QC_TID_MASK 0x0f
-#define IEEE802_11_QC_A_MSDU_PRESENT 0x80
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND))
-#define IEEE802_11_QC_NON_TID_BITS_MASK 0xFFF0
-#endif
-
-#define CSR_WIFI_EAPOL_M4_HOST_TAG 0x50000000
-#define IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE 36
-#define MAX_ACCESS_CATOGORY 4
-
-/* Time in us to check for inactivity of stations 5 mins */
-#define INACTIVITY_CHECK_INTERVAL   300000000
-/* Time in us before a station is flagged as inactive */
-#define MAX_INACTIVITY_INTERVAL     300000000
-
-
-/* Define for maximum BA session */
-#define MAX_SUPPORTED_BA_SESSIONS_TX   1
-#define MAX_SUPPORTED_BA_SESSIONS_RX   4
-
-#define MAX_BA_WIND_SIZE 64
-#define MAC_HEADER_ADDR1_OFFSET     4
-#define MAC_HEADER_ADDR2_OFFSET     10
-
-/* Define for age (in us) value for frames in MPDU reorder buffer */
-#define CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT  30000 /* 30 milli seconds */
-
-/* This macro used in prepare_and_add_macheader*/
-#define ADDRESS_ONE_OFFSET 20
-
-/* Defines for STA inactivity detection */
-#define     STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD           1                /* in number of stations */
-#define     STA_INACTIVE_DETECTION_TIMER_INTERVAL              30               /* in seconds */
-#define     STA_INACTIVE_TIMEOUT_VAL                           120*1000*1000    /* 120 seconds */
-
-/* Test for modes requiring AP firmware patch */
-#define CSR_WIFI_HIP_IS_AP_FW(mode) ((((mode) == CSR_WIFI_ROUTER_CTRL_MODE_AP) || \
-                                      ((mode) == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) ? TRUE : FALSE)
-
-/* Defines used in beacon filtering in case of P2P */
-#define CSR_WIFI_P2P_WILDCARD_SSID_LENGTH        0x7
-#define CSR_WIFI_80211_FRAME_SUBTYPE_BEACON      0x8
-#define CSR_WIFI_BEACON_FIXED_LENGTH             12
-#define CSR_WIFI_FRAME_SUBTYPE_BIT_OFFSET        4
-#define CSR_WIFI_80211_FRAME_SUBTYPE_BIT_MASK    ((u8)(0xF << CSR_WIFI_FRAME_SUBTYPE_BIT_OFFSET))
-
-#define CSR_WIFI_80211_GET_FRAME_SUBTYPE(frameBuffer) \
-    ((u8)(((u8 *)frameBuffer)[0] & CSR_WIFI_80211_FRAME_SUBTYPE_BIT_MASK) >> CSR_WIFI_FRAME_SUBTYPE_BIT_OFFSET)
-
-/* For M4 request received via netdev*/
-
-typedef u8 CsrWifiPacketType;
-#define CSR_WIFI_UNICAST_PDU   ((CsrWifiPacketType) 0x00)
-#define CSR_WIFI_MULTICAST_PDU ((CsrWifiPacketType) 0x1)
-#define CSR_WIFI_BROADCAST_PDU ((CsrWifiPacketType) 0x2)
-
-#define PRIO_TO_NICE(prio)  ((prio) - MAX_RT_PRIO - 20)
-
-/* Module parameter variables */
-extern int buswidth;
-extern int sdio_clock;
-extern int use_5g;
-extern int disable_hw_reset;
-extern int disable_power_control;
-extern int enable_wol;
-extern int sme_debug;
-extern int fw_init[MAX_UNIFI_DEVS];
-extern int tl_80211d;
-extern int sdio_byte_mode;
-extern int sdio_block_size;
-extern int coredump_max;
-extern int run_bh_once;
-extern int bh_priority;
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-extern int log_hip_signals;
-#endif
-
-struct dlpriv {
-    const unsigned char *dl_data;
-    int dl_len;
-    void *fw_desc;
-};
-
-
-struct uf_thread {
-
-    struct task_struct *thread_task;
-
-    /* wait_queue for waking the unifi_thread kernel thread */
-    wait_queue_head_t wakeup_q;
-    unsigned int wakeup_flag;
-
-    /*
-     * Use it to block the I/O thread when
-     * an error occurs or UniFi is reinitialised.
-     */
-    int block_thread;
-
-    char name[16];
-    int prio;
-};
-
-/*
- * Link list to hold the received packets for the period the port
- * remains closed.
- */
-typedef struct rx_buffered_packets {
-    /* List link structure */
-    struct list_head q;
-    /* Packet to indicate when the port reopens */
-    struct sk_buff *skb;
-    /* Bulkdata to free in case the port closes and need to discard the packet */
-    bulk_data_param_t bulkdata;
-    /* The source address of the packet */
-    CsrWifiMacAddress sa;
-    /* The destination address of the packet */
-    CsrWifiMacAddress da;
-    /* Corresponding signal */
-    CSR_SIGNAL signal;
-} rx_buffered_packets_t;
-
-
-typedef u8 CsrWifiAcPowersaveMode;
-#define CSR_WIFI_AC_TRIGGER_ONLY_ENABLED 0x00
-#define CSR_WIFI_AC_DELIVERY_ONLY_ENABLE 0X01
-#define CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED 0X03
-#define CSR_WIFI_AC_LEGACY_POWER_SAVE 0X02
-
-
-#define IS_DELIVERY_ENABLED(mode) (mode & CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)? 1: 0
-#define IS_DELIVERY_AND_TRIGGER_ENABLED(mode) ((mode & CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)||(mode & CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))? 1: 0
-#define IS_DTIM_ACTIVE(flag,hostTag) ((flag == TRUE || hostTag != INVALID_HOST_TAG))
-#define INVALID_HOST_TAG 0xFFFFFFFF
-#define UNIFI_TRAFFIC_Q_CONTENTION UNIFI_TRAFFIC_Q_BE
-
-
-
-
-/* Queue to be used for contention priority */
-
-/*
- * Link list to hold the tx packets for the period the peer
- * powersave/free slots in unifi
- */
-typedef struct tx_buffered_packets {
-    /* List link structure */
-    struct list_head q;
-    u16 interfaceTag;
-    CSR_CLIENT_TAG hostTag;
-    CSR_PROCESS_ID leSenderProcessId;
-    CSR_TRANSMISSION_CONTROL transmissionControl;
-    CSR_RATE rate;
-    /* Bulkdata to free in case the port closes and need to discard the packet */
-    bulk_data_desc_t bulkdata;
-    /* The source address of the packet */
-    CsrWifiMacAddress peerMacAddress;
-    CSR_PRIORITY priority;
-} tx_buffered_packets_t;
-
-/* station record has this data structure */
-typedef struct CsrWifiRouterCtrlStaInfo_t {
-
-    /* Sme sends these parameters */
-    CsrWifiMacAddress peerMacAddress;
-    u32 assignedHandle;
-    u8 wmmOrQosEnabled;
-    CsrWifiAcPowersaveMode powersaveMode[MAX_ACCESS_CATOGORY];
-    u16 maxSpLength;
-    u8 uapsdActive;
-    u16 noOfSpFramesSent;
-
-    /* Router/Driver database */
-#ifdef CSR_SUPPORT_SME
-    unifi_port_cfg_t *peerControlledPort;
-    unifi_port_cfg_t *peerUnControlledPort;
-
-    /* Inactivity feature parameters */
-    struct netInterface_priv *interfacePriv;
-    struct work_struct send_disconnected_ind_task;
-    u8 activity_flag;
-    u16 listenIntervalInTus;
-    CSR_CLIENT_TAG nullDataHostTag;
-
-    /* Activity timestamps for the station */
-    u32 lastActivity;
-
-    /* during m/c transmission sp suspended */
-    u8 uspSuspend;
-    CSR_PRIORITY triggerFramePriority;
-#endif
-    CsrWifiRouterCtrlPeerStatus currentPeerState;
-    struct list_head dataPdu[MAX_ACCESS_CATOGORY];
-    struct list_head mgtFrames;
-    u8 spStatus;
-    u8 prevFrmType;
-    u8 prevFrmAccessCatogory;
-    u8 protection;
-    u16 aid;
-    u8 txSuspend;
-    u8 timSet;
-    /* Dont change the value of below macro for SET & RESET */
-#define CSR_WIFI_TIM_RESET       0
-#define CSR_WIFI_TIM_SET         1
-#define CSR_WIFI_TIM_RESETTING   2
-#define CSR_WIFI_TIM_SETTING     3
-
-    u8 timRequestPendingFlag;
-    u8 updateTimReqQueued;
-    u16 noOfPktQueued;
-}CsrWifiRouterCtrlStaInfo_t;
-
-#ifdef CSR_SUPPORT_WEXT_AP
-struct CsrWifiSmeApConfig {
-    CsrWifiSsid ssid;
-    u16 channel;
-    CsrWifiNmeApCredentials credentials;
-    u8 max_connections;
-    u8 if_index;
-};
-#endif
-
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-/* This is a test code and may be removed later*/
-#define CSR_WIFI_RX_SIGNAL_BUFFER_SIZE    (60+1)
-
-typedef struct
-{
-    u8 *bufptr; /* Signal Primitive */
-    bulk_data_param_t data_ptrs; /* Bulk Data pointers */
-    u16 sig_len;
-}rx_buff_struct_t;
-
-typedef struct
-{
-    u8 writePointer; /**< write pointer */
-    u8 readPointer;  /**< read pointer */
-    u8 size;         /**< size of circular buffer */
-    rx_buff_struct_t rx_buff[CSR_WIFI_RX_SIGNAL_BUFFER_SIZE];    /**< Element of ciruclar buffer */
-} rxCircularBuffer_t;
-
-void rx_wq_handler(struct work_struct *work);
-#endif
-
-struct unifi_priv {
-
-    card_t *card;
-    CsrSdioFunction *sdio;
-
-    /* Index into Unifi_instances[] for this device. */
-    int instance;
-    /* Reference count for this instance */
-    int ref_count;
-
-    /* Firmware images */
-    struct dlpriv fw_sta;
-    struct dlpriv fw_conv;  /* used for conversion of production test image */
-
-    /* Char device related structures */
-    struct cdev unifi_cdev;
-    struct cdev unifiudi_cdev;
-    struct device *unifi_device;
-
-    /* Which wireless interface to use (1 - 2.4GHz, 2 - 5GHz) */
-    CSR_IFINTERFACE if_index;
-
-    /* For multiple interface support */
-    struct net_device *netdev[CSR_WIFI_NUM_INTERFACES];
-    struct netInterface_priv *interfacePriv[CSR_WIFI_NUM_INTERFACES];
-
-    u8 totalInterfaceCount;
-
-    int prev_queue;
-
-    /* Name of node under /proc */
-    char proc_entry_name[64];
-
-    /*
-     * Flags:
-     *  drop_unencrypted
-     *                - Not used?
-     *  netdev_registered
-     *                - whether the netdev has been registered.
-     */
-    unsigned int drop_unencrypted       : 1;
-
-    /* Our list of unifi linux clients. */
-    ul_client_t ul_clients[MAX_UDI_CLIENTS];
-
-    /* Mutex to protect using the logging hook after UDI client is gone */
-    struct semaphore udi_logging_mutex;
-    /* Pointer to the ul_clients[] array */
-    ul_client_t *logging_client;
-
-    /* A ul_client_t* used to send the netdev related MIB requests. */
-    ul_client_t *netdev_client;
-
-    /* The SME ul_client_t pointer. */
-    ul_client_t *sme_cli;
-
-    /* The AMP ul_client_t pointer. */
-    ul_client_t *amp_client;
-
-    /*
-     * Semaphore for locking the top-half to one user process.
-     * This is necessary to prevent multiple processes calling driver
-     * operations. This can happen because the network driver entry points
-     * can be called from multiple processes.
-     */
-#ifdef USE_DRIVER_LOCK
-    struct semaphore lock;
-#endif /* USE_DRIVER_LOCK */
-
-    /* Flag to say that an operation was aborted */
-    int io_aborted;
-
-    struct uf_thread bh_thread;
-
-#define UNIFI_INIT_NONE         0x00
-#define UNIFI_INIT_IN_PROGRESS  0x01
-#define UNIFI_INIT_FW_DOWNLOADED 0x02
-#define UNIFI_INIT_COMPLETED    0x04
-    unsigned char init_progress;
-
-    int sme_is_present;
-
-    /* The WMM features that UniFi uses in the current BSS */
-    unsigned int sta_wmm_capabilities;
-
-    /* Debug only */
-    char last_debug_string[256];
-    unsigned short last_debug_word16[16];
-
-#ifdef CSR_SUPPORT_SME
-  /* lock to protect the tx queues list */
-    spinlock_t tx_q_lock;
-    u8 allPeerDozing;
-    u8 pausedStaHandle[MAX_ACCESS_CATOGORY];
-    /* Max packet the driver can queue, irrespective of interface number */
-    u16 noOfPktQueuedInDriver;
-#define CSR_WIFI_DRIVER_SUPPORT_FOR_MAX_PKT_QUEUEING 512
-#define CSR_WIFI_DRIVER_MAX_PKT_QUEUING_THRESHOLD_PER_PEER 64
-#define CSR_WIFI_DRIVER_MINIMUM_BROADCAST_PKT_THRESHOLD 3
-
-    u8 routerBufferEnable[MAX_ACCESS_CATOGORY];
-    /* lock to protect stainfo members and priv members*/
-    spinlock_t staRecord_lock;
-#endif
-#ifdef CSR_NATIVE_LINUX
-#ifdef CSR_SUPPORT_WEXT
-    /* wireless config */
-    struct wext_config wext_conf;
-#endif
-
-    /* Mutex to protect the MLME blocking requests */
-    struct semaphore mlme_blocking_mutex;
-
-    /* The ul_client that provides the blocking API for WEXT calls */
-    ul_client_t *wext_client;
-
-#endif /* CSR_NATIVE_LINUX */
-
-#ifdef CSR_SUPPORT_SME
-    wait_queue_head_t sme_request_wq;
-    /* Semaphore to protect the SME blocking requests */
-    struct semaphore sme_sem;
-    /* Structure to hold the SME blocking requests data*/
-    sme_reply_t sme_reply;
-
-    /* Structure to hold a traffic protocol indication */
-    struct ta_ind {
-        struct work_struct task;
-        CsrWifiRouterCtrlTrafficPacketType packet_type;
-        CsrWifiRouterCtrlProtocolDirection direction;
-        CsrWifiMacAddress src_addr;
-        int in_use;
-    } ta_ind_work;
-
-    struct ta_sample_ind {
-        struct work_struct task;
-        CsrWifiRouterCtrlTrafficStats stats;
-        int in_use;
-    } ta_sample_ind_work;
-
-    __be32 sta_ip_address;
-    CsrWifiRouterCtrlSmeVersions    sme_versions;
-
-    /*
-     * Flag to reflect state of unifi_sys_wifi_on_*() progress.
-     * This indicates whether we are in an "wifi on" state when we are
-     * allowed to indication errors with unifi_mgt_wifi_off_ind()
-     */
-    enum {
-        wifi_on_unspecified = -1,
-        wifi_on_in_progress = 0,
-        wifi_on_done = 1,
-    } wifi_on_state;
-
-    /* Userspace TaskId for the SME Set when a wifi on req is received */
-    CsrSchedQid CSR_WIFI_SME_IFACEQUEUE;
-
-    struct work_struct multicast_list_task;
-    /*
-     * The SME installs filters to ask for specific MA-UNITDATA.req
-     * to be passed to different SME components.
-     */
-#define MAX_MA_UNIDATA_IND_FILTERS      8
-    sme_ma_unidata_ind_filter_t sme_unidata_ind_filters[MAX_MA_UNIDATA_IND_FILTERS];
-
-/* UNIFI_CFG related parameters */
-    uf_cfg_bcast_packet_filter_t packet_filters;
-    unsigned char *filter_tclas_ies;
- /* The structure that holds all the connection configuration. */
-    CsrWifiSmeConnectionConfig connection_config;
-#ifdef CSR_SUPPORT_WEXT
-
-    int ignore_bssid_join;
-    struct iw_statistics wext_wireless_stats;
-
-    /* The MIB and MAC address files contents, read from userspace */
-    CsrWifiSmeDataBlock mib_data;
-    CsrWifiMacAddress sta_mac_address;
-
-    int wep_tx_key_index;
-    wep_key_t wep_keys[NUM_WEPKEYS];
-
-
-#ifdef CSR_SUPPORT_WEXT_AP
-    CsrWifiSmeApMacConfig ap_mac_config;
-    CsrWifiNmeApConfig group_sec_config;
-    CsrWifiSmeApConfig_t ap_config;
-#endif
-    struct work_struct sme_config_task;
-
-#endif /* CSR_SUPPORT_WEXT */
-
-#endif /* CSR_SUPPORT_SME */
-
-#ifdef CSR_SME_USERSPACE
-    void *smepriv;
-#endif /* CSR_SME_USERSPACE */
-
-    card_info_t card_info;
-
-    /* Mutex to protect unifi_send_signal() */
-    spinlock_t send_signal_lock;
-
-
-    /*
-     * The workqueue to offload the TA run
-     * and the multicast addresses list set
-     */
-    struct workqueue_struct *unifi_workqueue;
-
-    unsigned char *mib_cfm_buffer;
-    unsigned int mib_cfm_buffer_length;
-
-    int ptest_mode;     /* Set when in production test mode */
-    int coredump_mode;  /* Set when SME has requested a coredump */
-    u8 wol_suspend; /* Set when suspending with UniFi powered */
-
-#define UF_UNCONTROLLED_PORT_Q      0
-#define UF_CONTROLLED_PORT_Q        1
-
-    /* Semaphore to protect the rx queues list */
-    struct semaphore rx_q_sem;
-
-    /* Spinlock to protect M4 data */
-    spinlock_t m4_lock;
-    /* Mutex to protect BA RX data */
-    struct semaphore ba_mutex;
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-    /* Spinlock to protect the WAPI data */
-    spinlock_t wapi_lock;
-#endif
-
-    /* Array to indicate if a particular Tx queue is paused, this may not be
-     * required in a multiqueue implementation since we can directly stop kernel
-     * queues */
-    u8 tx_q_paused_flag[UNIFI_TRAFFIC_Q_MAX];
-
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-    struct workqueue_struct *rx_workqueue;
-    struct work_struct rx_work_struct;
-    rxCircularBuffer_t rxSignalBuffer;
-
-#endif
-
-    u32 rxTcpThroughput;
-    u32 txTcpThroughput;
-    u32 rxUdpThroughput;
-    u32 txUdpThroughput;
-
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-    /*Set if multicast KeyID = 1*/
-    u8 wapi_multicast_filter;
-    /*Set if unicast KeyID = 1*/
-    u8 wapi_unicast_filter;
-    u8 wapi_unicast_queued_pkt_filter;
-#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
-    u8  isWapiConnection;
-#endif
-#endif
-
-#ifdef CSR_WIFI_SPLIT_PATCH
-    CsrWifiRouterCtrlModeSetReq pending_mode_set;
-#endif
-
-    u8 cmanrTestMode;
-    CSR_RATE cmanrTestModeTransmitRate;
-
-};
-
-typedef struct {
-    u16 queue_length[4];
-    u8 os_queue_paused;
-} unifi_OsQosInfo;
-
-
-typedef struct {
-    u8 active;
-    bulk_data_param_t bulkdata;
-    CSR_SIGNAL signal;
-    u16 sn;
-    u32 recv_time;
-} frame_desc_struct;
-
-typedef struct {
-    frame_desc_struct *buffer;
-    u16 wind_size;
-    u16 occupied_slots;
-    struct timer_list timer;
-    u16 timeout;
-    u16 expected_sn;
-    u16 start_sn;
-    u8   trigger_ba_after_ssn;
-    struct netInterface_priv *interfacePriv;
-    u16 tID;
-    CsrWifiMacAddress macAddress;
-    struct work_struct send_ba_err_task;
-} ba_session_rx_struct;
-
-
-typedef struct {
-    struct netInterface_priv *interfacePriv;
-    u16 tID;
-    CsrWifiMacAddress macAddress;
-} ba_session_tx_struct;
-
-typedef struct netInterface_priv
-{
-    u16 InterfaceTag;
-    struct unifi_priv *privPtr;
-    ba_session_tx_struct *ba_session_tx[MAX_SUPPORTED_BA_SESSIONS_TX];
-    ba_session_rx_struct *ba_session_rx[MAX_SUPPORTED_BA_SESSIONS_RX];
-    frame_desc_struct ba_complete[MAX_BA_WIND_SIZE];
-    u8 ba_complete_index;
-    u8 queueEnabled[UNIFI_NO_OF_TX_QS];
-    struct work_struct send_m4_ready_task;
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
-    struct work_struct send_pkt_to_encrypt;
-#endif
-    struct net_device_stats stats;
-    u8 interfaceMode;
-    u8 protect;
-    CsrWifiMacAddress bssid;
-    /*
-    * Flag to reflect state of CONNECTED indication signal.
-    * This indicates whether we are "joined" an Access Point (i.e. have
-    * nominated an AP and are receiving beacons) but give no indication
-    * of whether we are authenticated and/or associated.
-    */
-    enum {
-        UnifiConnectedUnknown = -1,
-        UnifiNotConnected = 0,
-        UnifiConnected = 1,
-    } connected;
-#ifdef CSR_SUPPORT_WEXT
-    /* Tracks when we are waiting for a netdevice state change callback */
-    u8 wait_netdev_change;
-    /* True if we have successfully registered for netdev callbacks */
-    u8 netdev_callback_registered;
-#endif /* CSR_SUPPORT_WEXT */
-    unsigned int netdev_registered;
-#define UNIFI_MAX_MULTICAST_ADDRESSES 10
-    /* The multicast addresses list that the thread needs to set. */
-    u8 mc_list[UNIFI_MAX_MULTICAST_ADDRESSES*ETH_ALEN];
-    /* The multicast addresses count that the thread needs to set. */
-    int mc_list_count;
-    u32 tag;
-#ifdef CSR_SUPPORT_SME
-    /* (un)controlled port configuration */
-    unifi_port_config_t controlled_data_port;
-    unifi_port_config_t uncontrolled_data_port;
-
-    /* station record maintenance related data structures */
-    u8 num_stations_joined;
-    CsrWifiRouterCtrlStaInfo_t *(staInfo)[UNIFI_MAX_CONNECTIONS];
-    struct list_head genericMgtFrames;
-    struct list_head genericMulticastOrBroadCastFrames;
-    struct list_head genericMulticastOrBroadCastMgtFrames;
-
-    /* Timer for detecting station inactivity */
-    struct timer_list sta_activity_check_timer;
-    u8 sta_activity_check_enabled;
-
-    /* Timestamp when the last inactivity check was done */
-    u32 last_inactivity_check;
-
-    /*number of multicast or borad cast packets  queued*/
-    u16 noOfbroadcastPktQueued;
-#endif
-    /* A list to hold the buffered uncontrolled port packets */
-    struct list_head rx_uncontrolled_list;
-    /* A list to hold the buffered controlled port packets */
-    struct list_head rx_controlled_list;
-    /* Buffered M4 signal to take care of WPA race condition */
-    CSR_SIGNAL m4_signal;
-    bulk_data_desc_t m4_bulk_data;
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-    /* Buffered WAPI Unicast MA Packet Request for encryption in Sme */
-    CSR_SIGNAL wapi_unicast_ma_pkt_sig;
-    bulk_data_desc_t wapi_unicast_bulk_data;
-#endif
-
-    /* This should be removed and m4_hostTag should be used for checking*/
-    u8 m4_sent;
-    CSR_CLIENT_TAG m4_hostTag;
-    u8 dtimActive;
-    u8 intraBssEnabled;
-    u32 multicastPduHostTag; /* Used to set the tim after getting
-       a confirm for it */
-    u8 bcTimSet;
-    u8 bcTimSetReqPendingFlag;
-    u8 bcTimSetReqQueued;
-} netInterface_priv_t;
-
-#ifdef CSR_SUPPORT_SME
-#define routerStartBuffering(priv,queue) priv->routerBufferEnable[(queue)] = TRUE;
-#define routerStopBuffering(priv,queue) priv->routerBufferEnable[(queue)]  = FALSE;
-#define isRouterBufferEnabled(priv,queue) priv->routerBufferEnable[(queue)]
-#endif
-
-#ifdef USE_DRIVER_LOCK
-#define LOCK_DRIVER(_p)         down_interruptible(&(_p)->lock)
-#define UNLOCK_DRIVER(_p)       up(&(_p)->lock)
-#else
-#define LOCK_DRIVER(_p)         (void)(_p); /* as nothing */
-#define UNLOCK_DRIVER(_p)       (void)(_p); /* as nothing */
-#endif /* USE_DRIVER_LOCK */
-
-s32 CsrHipResultToStatus(CsrResult csrResult);
-
-
-/*
- * SDIO related functions and callbacks
- */
-int  uf_sdio_load(void);
-void uf_sdio_unload(void);
-unifi_priv_t *uf_find_instance(int inst);
-int uf_find_priv(unifi_priv_t *priv);
-int uf_find_netdev_priv(netInterface_priv_t *priv);
-unifi_priv_t *uf_get_instance(int inst);
-void uf_put_instance(int inst);
-int csr_sdio_linux_install_irq(CsrSdioFunction *sdio);
-int csr_sdio_linux_remove_irq(CsrSdioFunction *sdio);
-
-void uf_add_os_device(int bus_id, struct device *os_device);
-void uf_remove_os_device(int bus_id);
-
-
-
-/*
- * Claim/release SDIO
- *
- * For multifunction cards, we cannot grub the SDIO lock around the unifi_bh()
- * as this prevents other functions using SDIO.
- * Since some of CSR SDIO API is used regardless of trying to lock unifi_bh()
- * we have followed this scheme:
- * 1. If a function needs protection only when CSR_WIFI_SINGLE_FUNCTION is defined
- *    then we call CsrSdioClaim/CsrSdioRelease().
- * 2. If a function needs protection only when CSR_WIFI_SINGLE_FUNCTION is not defined
- *    then we call _sdio_claim_host/_sdio_claim_host(). Use of this should be restricted
- *    to the SDIO glue layer only (e.g. sdio_mmc.c).
- * 3. If a function needs protection, regardless of the CSR_WIFI_SINGLE_FUNCTION
- *    then we call directly the sdio_claim_host/sdio_release_host().
- *    Use of this must be restricted to the SDIO glue layer only (e.g. sdio_mmc.c).
- *
- * Note: The _func and function pointers are _not_ the same.
- * The former is the (struct sdio_func*) context, which restricts the use to the SDIO glue layer.
- * The latter is the (CsrSdioFunction*) context, which allows calls from all layers.
- */
-
-#ifdef CSR_WIFI_SUPPORT_MMC_DRIVER
-
-#ifdef CSR_WIFI_SINGLE_FUNCTION
-#define CsrSdioClaim(function)    sdio_claim_host((function)->priv);
-#define CsrSdioRelease(function)  sdio_release_host((function)->priv);
-
-#define _sdio_claim_host(_func)
-#define _sdio_release_host(_func)
-
-#else
-#define CsrSdioClaim(function)
-#define CsrSdioRelease(function)
-
-#define _sdio_claim_host(_func)     sdio_claim_host(_func)
-#define _sdio_release_host(_func)   sdio_release_host(_func)
-
-#endif /* CSR_WIFI_SINGLE_FUNCTION */
-
-#else
-#define _sdio_claim_host(_func)
-#define _sdio_release_host(_func)
-
-#define CsrSdioClaim(function)
-#define CsrSdioRelease(function)
-
-#endif /* CSR_WIFI_SUPPORT_MMC_DRIVER */
-
-
-/*
- * Functions to allocate and free an ethernet device.
- */
-unifi_priv_t *uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id);
-int uf_free_netdevice(unifi_priv_t *priv);
-
-/* Allocating function for other interfaces */
-u8 uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, u16 interfaceTag);
-
-/*
- * Firmware download related functions.
- */
-int uf_run_unifihelper(unifi_priv_t *priv);
-int uf_reject_firmware_files(unifi_priv_t *priv, int is_fw);
-int uf_release_firmware_files(unifi_priv_t *priv);
-int uf_release_firmware(unifi_priv_t *priv, struct dlpriv *to_free);
-
-/*
- * Functions to create and delete the device nodes.
- */
-int uf_create_device_nodes(unifi_priv_t *priv, int bus_id);
-void uf_destroy_device_nodes(unifi_priv_t *priv);
-
-/*
- * Upper Edge Initialisation functions
- */
-int uf_init_bh(unifi_priv_t *priv);
-int uf_init_hw(unifi_priv_t *priv);
-
-/* Thread related helper functions */
-int uf_start_thread(unifi_priv_t *priv, struct uf_thread *thread, int (*func)(void *));
-void uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread);
-void uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread);
-
-
-/*
- * Unifi Linux functions
- */
-void ul_init_clients(unifi_priv_t *priv);
-
-/* Configuration flags */
-#define CLI_USING_WIRE_FORMAT   0x0002
-#define CLI_SME_USERSPACE       0x0020
-ul_client_t *ul_register_client(unifi_priv_t *priv,
-        unsigned int configuration,
-        udi_event_t udi_event_clbk);
-int ul_deregister_client(ul_client_t *pcli);
-
-int ul_send_signal_unpacked(unifi_priv_t *priv,
-                            CSR_SIGNAL *sigptr,
-                            bulk_data_param_t *bulkdata);
-int ul_send_signal_raw(unifi_priv_t *priv,
-                       unsigned char *sigptr, int siglen,
-                       bulk_data_param_t *bulkdata);
-
-void ul_log_config_ind(unifi_priv_t *priv, u8 *conf_param, int len);
-
-
-/*
- * Data plane operations
- */
-/*
- *      data_tx.c
- */
-int uf_verify_m4(unifi_priv_t *priv, const unsigned char *packet,
-        unsigned int length);
-
-#ifdef CSR_SUPPORT_SME
-u8 uf_check_broadcast_bssid(unifi_priv_t *priv, const bulk_data_param_t *bulkdata);
-u8 uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t * srcStaInfo,u8 pmBit,u16 interfaceTag);
-void uf_process_ps_poll(unifi_priv_t *priv,u8* sa,u8* da,u8 pmBit,u16 interfaceTag);
-int uf_ap_process_data_pdu(unifi_priv_t *priv, struct sk_buff *skb,
-                   struct ethhdr *ehdr, CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
-                   const CSR_SIGNAL *signal,
-                   bulk_data_param_t *bulkdata,
-                   u8 macHeaderLengthInBytes);
-u8 uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord);
-void uf_process_wmm_deliver_ac_uapsd (  unifi_priv_t * priv,
-                                        CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
-                                        u16 qosControl,
-                                        u16 interfaceTag);
-
-void uf_send_buffered_data_from_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo, u8 queue, struct list_head *txList);
-void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo, u8 queue, struct list_head *txList);
-
-void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo);
-void uf_send_qos_null(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo);
-void uf_send_nulldata(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo);
-
-
-
-#endif
-CsrResult uf_process_ma_packet_req(unifi_priv_t *priv,  u8 *peerMacAddress, CSR_CLIENT_TAG hostTag, u16 interfaceTag, CSR_TRANSMISSION_CONTROL transmissionControl, CSR_RATE TransmitRate, CSR_PRIORITY priority, CSR_PROCESS_ID senderId, bulk_data_param_t *bulkdata);
-void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,u8 *sigdata, u32 siglen);
-#ifdef CSR_SUPPORT_SME
-void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue queue);
-int uf_process_station_records_for_sending_data(unifi_priv_t *priv,u16 interfaceTag,
-                                                 CsrWifiRouterCtrlStaInfo_t *srcStaInfo,
-                                                 CsrWifiRouterCtrlStaInfo_t *dstStaInfo);
-void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv,
-                                                 struct list_head *frames_need_cfm_list,
-                                                 struct list_head * list);
-void send_auto_ma_packet_confirm(unifi_priv_t *priv,
-                                 netInterface_priv_t *interfacePriv,
-                                 struct list_head *buffered_frames_list);
-void uf_flush_list(unifi_priv_t * priv, struct list_head * list);
-tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList);
-void resume_unicast_buffered_frames(unifi_priv_t *priv, u16 interfaceTag);
-void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,u16 interfaceTag);
-void resume_suspended_uapsd(unifi_priv_t* priv,u16 interfaceTag);
-#endif
-/*
- *      netdev.c
- */
-
-#ifndef P80211_OUI_LEN
-#define P80211_OUI_LEN  3
-#endif
-typedef struct {
-    u8    dsap;   /* always 0xAA */
-    u8    ssap;   /* always 0xAA */
-    u8    ctrl;   /* always 0x03 */
-    u8    oui[P80211_OUI_LEN];    /* organizational universal id */
-    u16 protocol;
-} __attribute__ ((packed)) llc_snap_hdr_t;
-int skb_add_llc_snap(struct net_device *dev, struct sk_buff *skb, int proto);
-int skb_80211_to_ether(unifi_priv_t *priv, struct sk_buff *skb,
-        const unsigned char *daddr, const unsigned char *saddr,
-        const CSR_SIGNAL *signal,
-        bulk_data_param_t *bulkdata);
-
-const char *result_code_str(int result);
-
-
-/* prepares & appends the Mac header for the payload */
-int prepare_and_add_macheader(unifi_priv_t *priv,
-                              struct sk_buff *skb,
-                              struct sk_buff *newSkb,
-                              CSR_PRIORITY priority,
-                              bulk_data_param_t *bulkdata,
-                              u16 interfaceTag,
-                              const u8 *daddr,
-                              const u8 *saddr,
-                              u8 protection);
-CSR_PRIORITY
-get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, netInterface_priv_t *interfacePriv);
-
-void
-unifi_frame_ma_packet_req(unifi_priv_t *priv, CSR_PRIORITY priority,
-                          CSR_RATE TransmitRate, CSR_CLIENT_TAG hostTag,
-                          u16 interfaceTag, CSR_TRANSMISSION_CONTROL transmissionControl,
-                          CSR_PROCESS_ID leSenderProcessId, u8 *peerMacAddress,
-                          CSR_SIGNAL *signal);
-
-
-/* Pack the LSB to include station handle & status of tim set */
-#define CSR_WIFI_PACK_SENDER_ID_LSB_FOR_TIM_REQ(handle, timState)  ((handle << 2) | timState)
-/* get the station record handle from the sender ID */
-#define CSR_WIFI_GET_STATION_HANDLE_FROM_RECEIVER_ID(receiverProcessId) (u8) ((receiverProcessId & 0xff) >> 2)
-/* get the timSet status from the sender ID */
-#define CSR_WIFI_GET_TIMSET_STATE_FROM_RECEIVER_ID(receiverProcessId)  (u8) (receiverProcessId & 0x03)
-
-/* handle is 6 bits to accomodate in senderId LSB (only 64 station can be associated) */
-#define CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE 0x3F
-
-void update_tim(unifi_priv_t * priv, u16 aid, u8 setTim, u16 interfaceTag, u32 handle);
-void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, u16 senderProcessId);
-
-/* Clear the Peer station Record, in case of wifioff/unexpected card removal */
-void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, u16 interfaceTag);
-
-void scroll_ba_window(unifi_priv_t *priv,
-                      netInterface_priv_t *interfacePriv,
-                      ba_session_rx_struct *ba_session,
-                      u16 sn);
-
-u8 blockack_session_stop(unifi_priv_t *priv,
-                              u16 interfaceTag,
-                              CsrWifiRouterCtrlBlockAckRole role,
-                              u16 tID,
-                              CsrWifiMacAddress macAddress);
-#ifdef CSR_SUPPORT_SME
-/* Fetch the protection information from interface Mode */
-s8 uf_get_protection_bit_from_interfacemode(unifi_priv_t *priv, u16 interfaceTag, const u8 *daddr);
-#endif
-
-/* Fetch the station record handler from data base for matching Mac address */
-#ifdef CSR_SUPPORT_SME
-CsrWifiRouterCtrlStaInfo_t *CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(unifi_priv_t *priv,
-                                                                                const u8 *peerMacAddress,
-                                                                                u16 interfaceTag);
-
-/* Fetch the station record handler from data base for matching handle */
-CsrWifiRouterCtrlStaInfo_t * CsrWifiRouterCtrlGetStationRecordFromHandle(unifi_priv_t *priv,
-                                                                 u32 handle,
-                                                                 u16 interfaceTag);
-
-void uf_update_sta_activity(unifi_priv_t *priv, u16 interfaceTag, const u8 *peerMacAddress);
-void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,u16 interfaceTag, const CSR_MA_PACKET_CONFIRM *pkt_cfm);
-#endif
-
-void uf_resume_data_plane(unifi_priv_t *priv, int queue,
-                          CsrWifiMacAddress peer_address,
-                          u16 interfaceTag);
-void uf_free_pending_rx_packets(unifi_priv_t *priv, int queue,
-        CsrWifiMacAddress peer_address,u16 interfaceTag);
-
-int uf_register_netdev(unifi_priv_t *priv, int numOfInterface);
-void uf_unregister_netdev(unifi_priv_t *priv);
-
-void uf_net_get_name(struct net_device *dev, char *name, int len);
-
-void uf_send_queue_info(unifi_priv_t *priv);
-u16 uf_get_vif_identifier(CsrWifiRouterCtrlMode mode, u16 tag);
-
-void uf_process_rx_pending_queue(unifi_priv_t *priv, int queue,
-                                 CsrWifiMacAddress source_address,
-                                 int indicate, u16 interfaceTag);
-
-#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
-int uf_register_hip_offline_debug(unifi_priv_t *priv);
-int uf_unregister_hip_offline_debug(unifi_priv_t *priv);
-#endif
-
-/*
- *      inet.c
- */
-void uf_register_inet_notifier(void);
-void uf_unregister_inet_notifier(void);
-
-
-/*
- * Suspend / Resume handlers
- */
-void unifi_resume(void *ospriv);
-void unifi_suspend(void *ospriv);
-
-
-#define QOS_CAPABILITY_WMM_ENABLED      0x0001
-#define QOS_CAPABILITY_WMM_UAPSD        0x0002
-#define QOS_CAPABILITY_ACM_BE_ENABLED   0x0010
-#define QOS_CAPABILITY_ACM_BK_ENABLED   0x0020
-#define QOS_CAPABILITY_ACM_VI_ENABLED   0x0040
-#define QOS_CAPABILITY_ACM_VO_ENABLED   0x0080
-#define QOS_CAPABILITY_TS_BE_ENABLED    0x0100
-#define QOS_CAPABILITY_TS_BK_ENABLED    0x0200
-#define QOS_CAPABILITY_TS_VI_ENABLED    0x0400
-#define QOS_CAPABILITY_TS_VO_ENABLED    0x0800
-
-
-/* EAPOL PDUS */
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888e
-#endif
-#ifndef ETH_P_WAI
-#define ETH_P_WAI 0x88b4
-#endif
-/*
- * unifi_dbg.c
- */
-void debug_string_indication(unifi_priv_t *priv,
-        const unsigned char *extra,
-        unsigned int extralen);
-void debug_word16_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr);
-void debug_generic_indication(unifi_priv_t *priv, const CSR_SIGNAL *sigptr);
-
-
-/*
- * putest.c
- */
-int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg);
-int unifi_putest_cmd52_block_read(unifi_priv_t *priv, unsigned char *arg);
-int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg);
-int unifi_putest_set_sdio_clock(unifi_priv_t *priv, unsigned char *arg);
-int unifi_putest_cmd52_read(unifi_priv_t *priv, unsigned char *arg);
-int unifi_putest_coredump_prepare(unifi_priv_t *priv, unsigned char *arg);
-int unifi_putest_cmd52_write(unifi_priv_t *priv, unsigned char *arg);
-int unifi_putest_gp_read16(unifi_priv_t *priv, unsigned char *arg);
-int unifi_putest_gp_write16(unifi_priv_t *priv, unsigned char *arg);
-
-int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg);
-int unifi_putest_dl_fw_buff(unifi_priv_t *priv, unsigned char *arg);
-
-#endif /* __LINUX_UNIFI_PRIV_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_sme.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_sme.c
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_sme.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_sme.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1225 +0,0 @@
-/*
- * ***************************************************************************
- *  FILE:     unifi_sme.c
- *
- *  PURPOSE:    SME related functions.
- *
- *  Copyright (C) 2007-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ***************************************************************************
- */
-
-#include "unifi_priv.h"
-#include "csr_wifi_hip_unifi.h"
-#include "csr_wifi_hip_conversions.h"
-#include <linux/sched/rt.h>
-
-
-
-    int
-convert_sme_error(CsrResult error)
-{
-    switch (error) {
-        case CSR_RESULT_SUCCESS:
-            return 0;
-        case CSR_RESULT_FAILURE:
-        case CSR_WIFI_RESULT_NOT_FOUND:
-        case CSR_WIFI_RESULT_TIMED_OUT:
-        case CSR_WIFI_RESULT_CANCELLED:
-        case CSR_WIFI_RESULT_UNAVAILABLE:
-            return -EIO;
-        case CSR_WIFI_RESULT_NO_ROOM:
-            return -EBUSY;
-        case CSR_WIFI_RESULT_INVALID_PARAMETER:
-            return -EINVAL;
-        case CSR_WIFI_RESULT_UNSUPPORTED:
-            return -EOPNOTSUPP;
-        default:
-            return -EIO;
-    }
-}
-
-
-/*
- * ---------------------------------------------------------------------------
- *  sme_log_event
- *
- *      Callback function to be registered as the SME event callback.
- *      Copies the signal content into a new udi_log_t struct and adds
- *      it to the read queue for the SME client.
- *
- *  Arguments:
- *      arg             This is the value given to unifi_add_udi_hook, in
- *                      this case a pointer to the client instance.
- *      signal          Pointer to the received signal.
- *      signal_len      Size of the signal structure in bytes.
- *      bulkdata        Pointers to any associated bulk data.
- *      dir             Direction of the signal. Zero means from host,
- *                      non-zero means to host.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-    void
-sme_log_event(ul_client_t *pcli,
-        const u8 *signal, int signal_len,
-        const bulk_data_param_t *bulkdata,
-        int dir)
-{
-    unifi_priv_t *priv;
-    CSR_SIGNAL unpacked_signal;
-    CsrWifiSmeDataBlock mlmeCommand;
-    CsrWifiSmeDataBlock dataref1;
-    CsrWifiSmeDataBlock dataref2;
-    CsrResult result = CSR_RESULT_SUCCESS;
-    int r;
-
-    /* Just a sanity check */
-    if ((signal == NULL) || (signal_len <= 0)) {
-        return;
-    }
-
-    priv = uf_find_instance(pcli->instance);
-    if (!priv) {
-        unifi_error(priv, "sme_log_event: invalid priv\n");
-        return;
-    }
-
-    if (priv->smepriv == NULL) {
-        unifi_error(priv, "sme_log_event: invalid smepriv\n");
-        return;
-    }
-
-    unifi_trace(priv, UDBG3,
-            "sme_log_event: Process signal 0x%.4X\n",
-            CSR_GET_UINT16_FROM_LITTLE_ENDIAN(signal));
-
-
-    /* If the signal is known, then do any filtering required, otherwise it pass it to the SME. */
-    r = read_unpack_signal(signal, &unpacked_signal);
-    if (r == CSR_RESULT_SUCCESS) {
-        if ((unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_STRING_INDICATION_ID) ||
-            (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_WORD16_INDICATION_ID))
-        {
-            return;
-        }
-        if (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_INDICATION_ID)
-        {
-            u16 frmCtrl;
-            u8 unicastPdu = TRUE;
-            u8 *macHdrLocation;
-            u8 *raddr = NULL, *taddr = NULL;
-            CsrWifiMacAddress peerMacAddress;
-            /* Check if we need to send CsrWifiRouterCtrlMicFailureInd*/
-            CSR_MA_PACKET_INDICATION *ind = &unpacked_signal.u.MaPacketIndication;
-
-            macHdrLocation = (u8 *) bulkdata->d[0].os_data_ptr;
-            /* Fetch the frame control value from  mac header */
-            frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation);
-
-            /* Point to the addresses */
-            raddr = macHdrLocation + MAC_HEADER_ADDR1_OFFSET;
-            taddr = macHdrLocation + MAC_HEADER_ADDR2_OFFSET;
-
-            memcpy(peerMacAddress.a, taddr, ETH_ALEN);
-
-            if(ind->ReceptionStatus == CSR_MICHAEL_MIC_ERROR)
-            {
-                if (*raddr & 0x1)
-                    unicastPdu = FALSE;
-
-                CsrWifiRouterCtrlMicFailureIndSend (priv->CSR_WIFI_SME_IFACEQUEUE, 0,
-                        (ind->VirtualInterfaceIdentifier & 0xff),peerMacAddress,
-                        unicastPdu);
-                return;
-            }
-            else
-            {
-                if(ind->ReceptionStatus == CSR_RX_SUCCESS)
-                {
-                    u8 pmBit = (frmCtrl & 0x1000)?0x01:0x00;
-                    u16 interfaceTag = (ind->VirtualInterfaceIdentifier & 0xff);
-                    CsrWifiRouterCtrlStaInfo_t *srcStaInfo =  CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,taddr,interfaceTag);
-                    if((srcStaInfo != NULL) && (uf_check_broadcast_bssid(priv, bulkdata)== FALSE))
-                    {
-                        uf_process_pm_bit_for_peer(priv,srcStaInfo,pmBit,interfaceTag);
-
-                        /* Update station last activity flag */
-                        srcStaInfo->activity_flag = TRUE;
-                    }
-                }
-            }
-        }
-
-        if (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_CONFIRM_ID)
-        {
-            CSR_MA_PACKET_CONFIRM *cfm = &unpacked_signal.u.MaPacketConfirm;
-            u16 interfaceTag = (cfm->VirtualInterfaceIdentifier & 0xff);
-            netInterface_priv_t *interfacePriv;
-            CSR_MA_PACKET_REQUEST *req;
-            CsrWifiMacAddress peerMacAddress;
-
-            if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
-            {
-                unifi_error(priv, "Bad MA_PACKET_CONFIRM interfaceTag %d\n", interfaceTag);
-                return;
-            }
-
-            unifi_trace(priv,UDBG1,"MA-PACKET Confirm (%x, %x)\n", cfm->HostTag, cfm->TransmissionStatus);
-
-            interfacePriv = priv->interfacePriv[interfaceTag];
-#ifdef CSR_SUPPORT_SME
-            if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
-                 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-
-                if(cfm->HostTag == interfacePriv->multicastPduHostTag){
-                    uf_process_ma_pkt_cfm_for_ap(priv ,interfaceTag, cfm);
-                }
-            }
-#endif
-
-            req = &interfacePriv->m4_signal.u.MaPacketRequest;
-
-            if(cfm->HostTag & 0x80000000)
-            {
-                if (cfm->TransmissionStatus != CSR_TX_SUCCESSFUL)
-                {
-                    result = CSR_RESULT_FAILURE;
-                }
-#ifdef CSR_SUPPORT_SME
-                memcpy(peerMacAddress.a, req->Ra.x, ETH_ALEN);
-                /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/
-                if (interfacePriv->m4_sent && (cfm->HostTag == interfacePriv->m4_hostTag))
-                {
-                    unifi_trace(priv, UDBG1, "%s: Sending M4 Transmit CFM\n", __FUNCTION__);
-                    CsrWifiRouterCtrlM4TransmittedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0,
-                            interfaceTag,
-                            peerMacAddress,
-                            result);
-                    interfacePriv->m4_sent = FALSE;
-                    interfacePriv->m4_hostTag = 0xffffffff;
-                }
-#endif
-                /* If EAPOL was requested via router APIs then send cfm else ignore*/
-                if((cfm->HostTag & 0x80000000) != CSR_WIFI_EAPOL_M4_HOST_TAG) {
-                    CsrWifiRouterMaPacketCfmSend((u16)signal[2],
-                        cfm->VirtualInterfaceIdentifier,
-                        result,
-                        (cfm->HostTag & 0x3fffffff), cfm->Rate);
-                } else {
-                    unifi_trace(priv, UDBG1, "%s: M4 received from netdevice\n", __FUNCTION__);
-                }
-                return;
-            }
-        }
-    }
-
-    mlmeCommand.length = signal_len;
-    mlmeCommand.data = (u8*)signal;
-
-    dataref1.length = bulkdata->d[0].data_length;
-    if (dataref1.length > 0) {
-        dataref1.data = (u8 *) bulkdata->d[0].os_data_ptr;
-    } else
-    {
-        dataref1.data = NULL;
-    }
-
-    dataref2.length = bulkdata->d[1].data_length;
-    if (dataref2.length > 0) {
-        dataref2.data = (u8 *) bulkdata->d[1].os_data_ptr;
-    } else
-    {
-        dataref2.data = NULL;
-    }
-
-    CsrWifiRouterCtrlHipIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, mlmeCommand.length, mlmeCommand.data,
-            dataref1.length, dataref1.data,
-            dataref2.length, dataref2.data);
-
-} /* sme_log_event() */
-
-
-/*
- * ---------------------------------------------------------------------------
- * uf_sme_port_state
- *
- *      Return the state of the controlled port.
- *
- * Arguments:
- *      priv            Pointer to device private context struct
- *      address    Pointer to the destination for tx or sender for rx address
- *      queue           Controlled or uncontrolled queue
- *
- * Returns:
- *      An unifi_ControlledPortAction value.
- * ---------------------------------------------------------------------------
- */
-CsrWifiRouterCtrlPortAction
-uf_sme_port_state(unifi_priv_t *priv, unsigned char *address, int queue, u16 interfaceTag)
-{
-    int i;
-    unifi_port_config_t *port;
-    netInterface_priv_t *interfacePriv;
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "uf_sme_port_state: bad interfaceTag\n");
-        return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-    }
-
-    interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if (queue == UF_CONTROLLED_PORT_Q) {
-        port = &interfacePriv->controlled_data_port;
-    } else {
-        port = &interfacePriv->uncontrolled_data_port;
-    }
-
-    if (!port->entries_in_use) {
-        unifi_trace(priv, UDBG5, "No port configurations, return Discard.\n");
-        return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
-    }
-
-    /* If the port configuration is common for all destinations, return it. */
-    if (port->overide_action == UF_DATA_PORT_OVERIDE) {
-        unifi_trace(priv, UDBG5, "Single port configuration (%d).\n",
-                port->port_cfg[0].port_action);
-        return port->port_cfg[0].port_action;
-    }
-
-    unifi_trace(priv, UDBG5, "Multiple (%d) port configurations.\n", port->entries_in_use);
-
-    /* If multiple configurations exist.. */
-    for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        /* .. go through the list and match the destination address. */
-        if (port->port_cfg[i].in_use &&
-            memcmp(address, port->port_cfg[i].mac_address.a, ETH_ALEN) == 0) {
-            /* Return the desired action. */
-            return port->port_cfg[i].port_action;
-        }
-    }
-
-    /* Could not find any information, return Open. */
-    unifi_trace(priv, UDBG5, "port configuration not found, return Open.\n");
-    return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN;
-} /* uf_sme_port_state() */
-
-/*
- * ---------------------------------------------------------------------------
- * uf_sme_port_config_handle
- *
- *      Return the port config handle of the controlled/uncontrolled port.
- *
- * Arguments:
- *      priv            Pointer to device private context struct
- *      address    Pointer to the destination for tx or sender for rx address
- *      queue           Controlled or uncontrolled queue
- *
- * Returns:
- *      An  unifi_port_cfg_t* .
- * ---------------------------------------------------------------------------
- */
-unifi_port_cfg_t*
-uf_sme_port_config_handle(unifi_priv_t *priv, unsigned char *address, int queue, u16 interfaceTag)
-{
-    int i;
-    unifi_port_config_t *port;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "uf_sme_port_config_handle: bad interfaceTag\n");
-        return NULL;
-    }
-
-    if (queue == UF_CONTROLLED_PORT_Q) {
-        port = &interfacePriv->controlled_data_port;
-    } else {
-        port = &interfacePriv->uncontrolled_data_port;
-    }
-
-    if (!port->entries_in_use) {
-        unifi_trace(priv, UDBG5, "No port configurations, return Discard.\n");
-        return NULL;
-    }
-
-    /* If the port configuration is common for all destinations, return it. */
-    if (port->overide_action == UF_DATA_PORT_OVERIDE) {
-        unifi_trace(priv, UDBG5, "Single port configuration (%d).\n",
-                port->port_cfg[0].port_action);
-        if (address) {
-            unifi_trace(priv, UDBG5, "addr[0] = %x, addr[1] = %x, addr[2] = %x, addr[3] = %x\n", address[0], address[1], address[2], address[3]);
-        }
-        return &port->port_cfg[0];
-    }
-
-    unifi_trace(priv, UDBG5, "Multiple port configurations.\n");
-
-    /* If multiple configurations exist.. */
-    for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
-        /* .. go through the list and match the destination address. */
-        if (port->port_cfg[i].in_use &&
-            memcmp(address, port->port_cfg[i].mac_address.a, ETH_ALEN) == 0) {
-            /* Return the desired action. */
-            return &port->port_cfg[i];
-        }
-    }
-
-    /* Could not find any information, return Open. */
-    unifi_trace(priv, UDBG5, "port configuration not found, returning NULL (debug).\n");
-    return NULL;
-} /* uf_sme_port_config_handle */
-
-void
-uf_multicast_list_wq(struct work_struct *work)
-{
-    unifi_priv_t *priv = container_of(work, unifi_priv_t,
-            multicast_list_task);
-    int i;
-    u16 interfaceTag = 0;
-    CsrWifiMacAddress* multicast_address_list = NULL;
-    int mc_count;
-    u8 *mc_list;
-    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "uf_multicast_list_wq: bad interfaceTag\n");
-        return;
-    }
-
-    unifi_trace(priv, UDBG5,
-            "uf_multicast_list_wq: list count = %d\n",
-            interfacePriv->mc_list_count);
-
-    /* Flush the current list */
-    CsrWifiRouterCtrlMulticastAddressIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, interfaceTag, CSR_WIFI_SME_LIST_ACTION_FLUSH, 0, NULL);
-
-    mc_count = interfacePriv->mc_list_count;
-    mc_list = interfacePriv->mc_list;
-    /*
-     * Allocate a new list, need to free it later
-     * in unifi_mgt_multicast_address_cfm().
-     */
-    multicast_address_list = kmalloc(mc_count * sizeof(CsrWifiMacAddress), GFP_KERNEL);
-
-    if (multicast_address_list == NULL) {
-        return;
-    }
-
-    for (i = 0; i < mc_count; i++) {
-        memcpy(multicast_address_list[i].a, mc_list, ETH_ALEN);
-        mc_list += ETH_ALEN;
-    }
-
-    if (priv->smepriv == NULL) {
-        kfree(multicast_address_list);
-        return;
-    }
-
-    CsrWifiRouterCtrlMulticastAddressIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,
-            interfaceTag,
-            CSR_WIFI_SME_LIST_ACTION_ADD,
-            mc_count, multicast_address_list);
-
-    /* The SME will take a copy of the addreses*/
-    kfree(multicast_address_list);
-}
-
-
-int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg)
-{
-    unifi_cfg_power_t cfg_power;
-    int rc;
-    int wol;
-
-    if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) {
-        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    switch (cfg_power) {
-        case UNIFI_CFG_POWER_OFF:
-            priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE;
-            rc = sme_sys_suspend(priv);
-            if (rc) {
-                return rc;
-            }
-            break;
-        case UNIFI_CFG_POWER_ON:
-            wol = priv->wol_suspend;
-            rc = sme_sys_resume(priv);
-            if (rc) {
-                return rc;
-            }
-            if (wol) {
-                /* Kick the BH to ensure pending transfers are handled when
-                 * a suspend happened with card powered.
-                 */
-                unifi_send_signal(priv->card, NULL, 0, NULL);
-            }
-            break;
-        default:
-            unifi_error(priv, "WIFI POWER: Unknown value.\n");
-            return -EINVAL;
-    }
-
-    return 0;
-}
-
-
-int unifi_cfg_power_save(unifi_priv_t *priv, unsigned char *arg)
-{
-    unifi_cfg_powersave_t cfg_power_save;
-    CsrWifiSmePowerConfig powerConfig;
-    int rc;
-
-    if (get_user(cfg_power_save, (unifi_cfg_powersave_t*)(((unifi_cfg_command_t*)arg) + 1))) {
-        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    /* Get the coex info from the SME */
-    rc = sme_mgt_power_config_get(priv, &powerConfig);
-    if (rc) {
-        unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n");
-        return rc;
-    }
-
-    switch (cfg_power_save) {
-        case UNIFI_CFG_POWERSAVE_NONE:
-            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW;
-            break;
-        case UNIFI_CFG_POWERSAVE_FAST:
-            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_MED;
-            break;
-        case UNIFI_CFG_POWERSAVE_FULL:
-            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH;
-            break;
-        case UNIFI_CFG_POWERSAVE_AUTO:
-            powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO;
-            break;
-        default:
-            unifi_error(priv, "POWERSAVE: Unknown value.\n");
-            return -EINVAL;
-    }
-
-    rc = sme_mgt_power_config_set(priv, &powerConfig);
-
-    if (rc) {
-        unifi_error(priv, "UNIFI_CFG: Set unifi_PowerConfigValue failed.\n");
-    }
-
-    return rc;
-}
-
-
-int unifi_cfg_power_supply(unifi_priv_t *priv, unsigned char *arg)
-{
-    unifi_cfg_powersupply_t cfg_power_supply;
-    CsrWifiSmeHostConfig hostConfig;
-    int rc;
-
-    if (get_user(cfg_power_supply, (unifi_cfg_powersupply_t*)(((unifi_cfg_command_t*)arg) + 1))) {
-        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    /* Get the coex info from the SME */
-    rc = sme_mgt_host_config_get(priv, &hostConfig);
-    if (rc) {
-        unifi_error(priv, "UNIFI_CFG: Get unifi_HostConfigValue failed.\n");
-        return rc;
-    }
-
-    switch (cfg_power_supply) {
-        case UNIFI_CFG_POWERSUPPLY_MAINS:
-            hostConfig.powerMode = CSR_WIFI_SME_HOST_POWER_MODE_ACTIVE;
-            break;
-        case UNIFI_CFG_POWERSUPPLY_BATTERIES:
-            hostConfig.powerMode = CSR_WIFI_SME_HOST_POWER_MODE_POWER_SAVE;
-            break;
-        default:
-            unifi_error(priv, "POWERSUPPLY: Unknown value.\n");
-            return -EINVAL;
-    }
-
-    rc = sme_mgt_host_config_set(priv, &hostConfig);
-    if (rc) {
-        unifi_error(priv, "UNIFI_CFG: Set unifi_HostConfigValue failed.\n");
-    }
-
-    return rc;
-}
-
-
-int unifi_cfg_packet_filters(unifi_priv_t *priv, unsigned char *arg)
-{
-    unsigned char *tclas_buffer;
-    unsigned int tclas_buffer_length;
-    tclas_t *dhcp_tclas;
-    int rc;
-
-    /* Free any TCLASs previously allocated */
-    if (priv->packet_filters.tclas_ies_length) {
-        kfree(priv->filter_tclas_ies);
-        priv->filter_tclas_ies = NULL;
-    }
-
-    tclas_buffer = ((unsigned char*)arg) + sizeof(unifi_cfg_command_t) + sizeof(unsigned int);
-    if (copy_from_user(&priv->packet_filters, (void*)tclas_buffer,
-                sizeof(uf_cfg_bcast_packet_filter_t))) {
-        unifi_error(priv, "UNIFI_CFG: Failed to get the filter struct\n");
-        return -EFAULT;
-    }
-
-    tclas_buffer_length = priv->packet_filters.tclas_ies_length;
-
-    /* Allocate TCLASs if necessary */
-    if (priv->packet_filters.dhcp_filter) {
-        priv->packet_filters.tclas_ies_length += sizeof(tclas_t);
-    }
-    if (priv->packet_filters.tclas_ies_length > 0) {
-        priv->filter_tclas_ies = kmalloc(priv->packet_filters.tclas_ies_length, GFP_KERNEL);
-        if (priv->filter_tclas_ies == NULL) {
-            return -ENOMEM;
-        }
-        if (tclas_buffer_length) {
-            tclas_buffer += sizeof(uf_cfg_bcast_packet_filter_t) - sizeof(unsigned char*);
-            if (copy_from_user(priv->filter_tclas_ies,
-                        tclas_buffer,
-                        tclas_buffer_length)) {
-                unifi_error(priv, "UNIFI_CFG: Failed to get the TCLAS buffer\n");
-                return -EFAULT;
-            }
-        }
-    }
-
-    if(priv->packet_filters.dhcp_filter)
-    {
-        /* Append the DHCP tclas IE */
-        dhcp_tclas = (tclas_t*)(priv->filter_tclas_ies + tclas_buffer_length);
-        memset(dhcp_tclas, 0, sizeof(tclas_t));
-        dhcp_tclas->element_id = 14;
-        dhcp_tclas->length = sizeof(tcpip_clsfr_t) + 1;
-        dhcp_tclas->user_priority = 0;
-        dhcp_tclas->tcp_ip_cls_fr.cls_fr_type = 1;
-        dhcp_tclas->tcp_ip_cls_fr.version = 4;
-        ((u8*)(&dhcp_tclas->tcp_ip_cls_fr.source_port))[0] = 0x00;
-        ((u8*)(&dhcp_tclas->tcp_ip_cls_fr.source_port))[1] = 0x44;
-        ((u8*)(&dhcp_tclas->tcp_ip_cls_fr.dest_port))[0] = 0x00;
-        ((u8*)(&dhcp_tclas->tcp_ip_cls_fr.dest_port))[1] = 0x43;
-        dhcp_tclas->tcp_ip_cls_fr.protocol = 0x11;
-        dhcp_tclas->tcp_ip_cls_fr.cls_fr_mask = 0x58; //bits: 3,4,6
-    }
-
-    rc = sme_mgt_packet_filter_set(priv);
-
-    return rc;
-}
-
-
-int unifi_cfg_wmm_qos_info(unifi_priv_t *priv, unsigned char *arg)
-{
-    u8 wmm_qos_info;
-    int rc = 0;
-
-    if (get_user(wmm_qos_info, (u8*)(((unifi_cfg_command_t*)arg) + 1))) {
-        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    /* Store the value in the connection info */
-    priv->connection_config.wmmQosInfo = wmm_qos_info;
-
-    return rc;
-}
-
-
-int unifi_cfg_wmm_addts(unifi_priv_t *priv, unsigned char *arg)
-{
-    u32 addts_tid;
-    u8 addts_ie_length;
-    u8 *addts_ie;
-    u8 *addts_params;
-    CsrWifiSmeDataBlock tspec;
-    CsrWifiSmeDataBlock tclas;
-    int rc;
-
-    addts_params = (u8*)(((unifi_cfg_command_t*)arg) + 1);
-    if (get_user(addts_tid, (u32*)addts_params)) {
-        unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    addts_params += sizeof(u32);
-    if (get_user(addts_ie_length, (u8*)addts_params)) {
-        unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG4, "addts: tid = 0x%x ie_length = %d\n",
-            addts_tid, addts_ie_length);
-
-    addts_ie = kmalloc(addts_ie_length, GFP_KERNEL);
-    if (addts_ie == NULL) {
-        unifi_error(priv,
-                "unifi_cfg_wmm_addts: Failed to malloc %d bytes for addts_ie buffer\n",
-                addts_ie_length);
-        return -ENOMEM;
-    }
-
-    addts_params += sizeof(u8);
-    rc = copy_from_user(addts_ie, addts_params, addts_ie_length);
-    if (rc) {
-        unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the addts buffer\n");
-        kfree(addts_ie);
-        return -EFAULT;
-    }
-
-    tspec.data = addts_ie;
-    tspec.length = addts_ie_length;
-    tclas.data = NULL;
-    tclas.length = 0;
-
-    rc = sme_mgt_tspec(priv, CSR_WIFI_SME_LIST_ACTION_ADD, addts_tid,
-            &tspec, &tclas);
-
-    kfree(addts_ie);
-    return rc;
-}
-
-
-int unifi_cfg_wmm_delts(unifi_priv_t *priv, unsigned char *arg)
-{
-    u32 delts_tid;
-    u8 *delts_params;
-    CsrWifiSmeDataBlock tspec;
-    CsrWifiSmeDataBlock tclas;
-    int rc;
-
-    delts_params = (u8*)(((unifi_cfg_command_t*)arg) + 1);
-    if (get_user(delts_tid, (u32*)delts_params)) {
-        unifi_error(priv, "unifi_cfg_wmm_delts: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG4, "delts: tid = 0x%x\n", delts_tid);
-
-    tspec.data = tclas.data = NULL;
-    tspec.length = tclas.length = 0;
-
-    rc = sme_mgt_tspec(priv, CSR_WIFI_SME_LIST_ACTION_REMOVE, delts_tid,
-            &tspec, &tclas);
-
-    return rc;
-}
-
-int unifi_cfg_strict_draft_n(unifi_priv_t *priv, unsigned char *arg)
-{
-    u8 strict_draft_n;
-    u8 *strict_draft_n_params;
-    int rc;
-
-    CsrWifiSmeStaConfig  staConfig;
-    CsrWifiSmeDeviceConfig  deviceConfig;
-
-    strict_draft_n_params = (u8*)(((unifi_cfg_command_t*)arg) + 1);
-    if (get_user(strict_draft_n, (u8*)strict_draft_n_params)) {
-        unifi_error(priv, "unifi_cfg_strict_draft_n: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG4, "strict_draft_n: = %s\n", ((strict_draft_n) ? "yes":"no"));
-
-    rc = sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig);
-
-    if (rc) {
-        unifi_warning(priv, "unifi_cfg_strict_draft_n: Get unifi_SMEConfigValue failed.\n");
-        return -EFAULT;
-    }
-
-    deviceConfig.enableStrictDraftN = strict_draft_n;
-
-    rc = sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig);
-    if (rc) {
-        unifi_warning(priv, "unifi_cfg_strict_draft_n: Set unifi_SMEConfigValue failed.\n");
-        rc = -EFAULT;
-    }
-
-    return rc;
-}
-
-
-int unifi_cfg_enable_okc(unifi_priv_t *priv, unsigned char *arg)
-{
-    u8 enable_okc;
-    u8 *enable_okc_params;
-    int rc;
-
-    CsrWifiSmeStaConfig staConfig;
-    CsrWifiSmeDeviceConfig deviceConfig;
-
-    enable_okc_params = (u8*)(((unifi_cfg_command_t*)arg) + 1);
-    if (get_user(enable_okc, (u8*)enable_okc_params)) {
-        unifi_error(priv, "unifi_cfg_enable_okc: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    unifi_trace(priv, UDBG4, "enable_okc: = %s\n", ((enable_okc) ? "yes":"no"));
-
-    rc = sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig);
-    if (rc) {
-        unifi_warning(priv, "unifi_cfg_enable_okc: Get unifi_SMEConfigValue failed.\n");
-        return -EFAULT;
-    }
-
-    staConfig.enableOpportunisticKeyCaching = enable_okc;
-
-    rc = sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig);
-    if (rc) {
-        unifi_warning(priv, "unifi_cfg_enable_okc: Set unifi_SMEConfigValue failed.\n");
-        rc = -EFAULT;
-    }
-
-    return rc;
-}
-
-
-int unifi_cfg_get_info(unifi_priv_t *priv, unsigned char *arg)
-{
-    unifi_cfg_get_t get_cmd;
-    char inst_name[IFNAMSIZ];
-    int rc;
-
-    if (get_user(get_cmd, (unifi_cfg_get_t*)(((unifi_cfg_command_t*)arg) + 1))) {
-        unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
-        return -EFAULT;
-    }
-
-    switch (get_cmd) {
-        case UNIFI_CFG_GET_COEX:
-            {
-                CsrWifiSmeCoexInfo coexInfo;
-                /* Get the coex info from the SME */
-                rc = sme_mgt_coex_info_get(priv, &coexInfo);
-                if (rc) {
-                    unifi_error(priv, "UNIFI_CFG: Get unifi_CoexInfoValue failed.\n");
-                    return rc;
-                }
-
-                /* Copy the info to the out buffer */
-                if (copy_to_user((void*)arg,
-                            &coexInfo,
-                            sizeof(CsrWifiSmeCoexInfo))) {
-                    unifi_error(priv, "UNIFI_CFG: Failed to copy the coex info\n");
-                    return -EFAULT;
-                }
-                break;
-            }
-        case UNIFI_CFG_GET_POWER_MODE:
-            {
-                CsrWifiSmePowerConfig powerConfig;
-                rc = sme_mgt_power_config_get(priv, &powerConfig);
-                if (rc) {
-                    unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n");
-                    return rc;
-                }
-
-                /* Copy the info to the out buffer */
-                if (copy_to_user((void*)arg,
-                            &powerConfig.powerSaveLevel,
-                            sizeof(CsrWifiSmePowerSaveLevel))) {
-                    unifi_error(priv, "UNIFI_CFG: Failed to copy the power save info\n");
-                    return -EFAULT;
-                }
-                break;
-            }
-        case UNIFI_CFG_GET_POWER_SUPPLY:
-            {
-                CsrWifiSmeHostConfig hostConfig;
-                rc = sme_mgt_host_config_get(priv, &hostConfig);
-                if (rc) {
-                    unifi_error(priv, "UNIFI_CFG: Get unifi_HostConfigValue failed.\n");
-                    return rc;
-                }
-
-                /* Copy the info to the out buffer */
-                if (copy_to_user((void*)arg,
-                            &hostConfig.powerMode,
-                            sizeof(CsrWifiSmeHostPowerMode))) {
-                    unifi_error(priv, "UNIFI_CFG: Failed to copy the host power mode\n");
-                    return -EFAULT;
-                }
-                break;
-            }
-        case UNIFI_CFG_GET_VERSIONS:
-            break;
-        case UNIFI_CFG_GET_INSTANCE:
-            {
-                u16 InterfaceId=0;
-                uf_net_get_name(priv->netdev[InterfaceId], &inst_name[0], sizeof(inst_name));
-
-                /* Copy the info to the out buffer */
-                if (copy_to_user((void*)arg,
-                            &inst_name[0],
-                            sizeof(inst_name))) {
-                    unifi_error(priv, "UNIFI_CFG: Failed to copy the instance name\n");
-                    return -EFAULT;
-                }
-            }
-            break;
-
-        case UNIFI_CFG_GET_AP_CONFIG:
-            {
-#ifdef CSR_SUPPORT_WEXT_AP
-                uf_cfg_ap_config_t cfg_ap_config;
-
-		memset(&cfg_ap_config, 0, sizeof(cfg_ap_config));
-                cfg_ap_config.channel = priv->ap_config.channel;
-                cfg_ap_config.beaconInterval = priv->ap_mac_config.beaconInterval;
-                cfg_ap_config.wmmEnabled = priv->ap_mac_config.wmmEnabled;
-                cfg_ap_config.dtimPeriod = priv->ap_mac_config.dtimPeriod;
-                cfg_ap_config.phySupportedBitmap = priv->ap_mac_config.phySupportedBitmap;
-                if (copy_to_user((void*)arg,
-                            &cfg_ap_config,
-                            sizeof(uf_cfg_ap_config_t))) {
-                    unifi_error(priv, "UNIFI_CFG: Failed to copy the AP configuration\n");
-                    return -EFAULT;
-                }
-#else
-                   return -EPERM;
-#endif
-            }
-            break;
-
-
-        default:
-            unifi_error(priv, "unifi_cfg_get_info: Unknown value.\n");
-            return -EINVAL;
-    }
-
-    return 0;
-}
-#ifdef CSR_SUPPORT_WEXT_AP
-int
- uf_configure_supported_rates(u8 * supportedRates, u8 phySupportedBitmap)
-{
-    int i=0;
-    u8 b=FALSE, g = FALSE, n = FALSE;
-    b = phySupportedBitmap & CSR_WIFI_SME_AP_PHY_SUPPORT_B;
-    n = phySupportedBitmap & CSR_WIFI_SME_AP_PHY_SUPPORT_N;
-    g = phySupportedBitmap & CSR_WIFI_SME_AP_PHY_SUPPORT_G;
-    if(b || g) {
-        supportedRates[i++]=0x82;
-        supportedRates[i++]=0x84;
-        supportedRates[i++]=0x8b;
-        supportedRates[i++]=0x96;
-    } else if(n) {
-        /* For some strange reasons WiFi stack needs both b and g rates*/
-        supportedRates[i++]=0x02;
-        supportedRates[i++]=0x04;
-        supportedRates[i++]=0x0b;
-        supportedRates[i++]=0x16;
-        supportedRates[i++]=0x0c;
-        supportedRates[i++]=0x12;
-        supportedRates[i++]=0x18;
-	supportedRates[i++]=0x24;
-        supportedRates[i++]=0x30;
-        supportedRates[i++]=0x48;
-        supportedRates[i++]=0x60;
-        supportedRates[i++]=0x6c;
-    }
-    if(g) {
-        if(!b) {
-            supportedRates[i++]=0x8c;
-            supportedRates[i++]=0x98;
-            supportedRates[i++]=0xb0;
-        } else {
-            supportedRates[i++]=0x0c;
-            supportedRates[i++]=0x18;
-            supportedRates[i++]=0x30;
-        }
-        supportedRates[i++]=0x48;
-        supportedRates[i++]=0x12;
-        supportedRates[i++]=0x24;
-        supportedRates[i++]=0x60;
-        supportedRates[i++]=0x6c;
-    }
-    return i;
-}
-int unifi_cfg_set_ap_config(unifi_priv_t * priv,unsigned char* arg)
-{
-    uf_cfg_ap_config_t cfg_ap_config;
-    char *buffer;
-
-    buffer = ((unsigned char*)arg) + sizeof(unifi_cfg_command_t) + sizeof(unsigned int);
-    if (copy_from_user(&cfg_ap_config, (void*)buffer,
-                sizeof(uf_cfg_ap_config_t))) {
-        unifi_error(priv, "UNIFI_CFG: Failed to get the ap config struct\n");
-        return -EFAULT;
-    }
-    priv->ap_config.channel = cfg_ap_config.channel;
-    priv->ap_mac_config.dtimPeriod = cfg_ap_config.dtimPeriod;
-    priv->ap_mac_config.beaconInterval = cfg_ap_config.beaconInterval;
-    priv->group_sec_config.apGroupkeyTimeout = cfg_ap_config.groupkeyTimeout;
-    priv->group_sec_config.apStrictGtkRekey = cfg_ap_config.strictGtkRekeyEnabled;
-    priv->group_sec_config.apGmkTimeout = cfg_ap_config.gmkTimeout;
-    priv->group_sec_config.apResponseTimeout = cfg_ap_config.responseTimeout;
-    priv->group_sec_config.apRetransLimit = cfg_ap_config.retransLimit;
-
-    priv->ap_mac_config.shortSlotTimeEnabled = cfg_ap_config.shortSlotTimeEnabled;
-    priv->ap_mac_config.ctsProtectionType=cfg_ap_config.ctsProtectionType;
-
-    priv->ap_mac_config.wmmEnabled = cfg_ap_config.wmmEnabled;
-
-    priv->ap_mac_config.apHtParams.rxStbc=cfg_ap_config.rxStbc;
-    priv->ap_mac_config.apHtParams.rifsModeAllowed=cfg_ap_config.rifsModeAllowed;
-
-    priv->ap_mac_config.phySupportedBitmap = cfg_ap_config.phySupportedBitmap;
-    priv->ap_mac_config.maxListenInterval=cfg_ap_config.maxListenInterval;
-
-    priv->ap_mac_config.supportedRatesCount=     uf_configure_supported_rates(priv->ap_mac_config.supportedRates,priv->ap_mac_config.phySupportedBitmap);
-
-    return 0;
-}
-
-#endif
-#ifdef CSR_SUPPORT_WEXT
-
-    void
-uf_sme_config_wq(struct work_struct *work)
-{
-    CsrWifiSmeStaConfig  staConfig;
-    CsrWifiSmeDeviceConfig  deviceConfig;
-    unifi_priv_t *priv = container_of(work, unifi_priv_t, sme_config_task);
-
-    /* Register to receive indications from the SME */
-    CsrWifiSmeEventMaskSetReqSend(0,
-            CSR_WIFI_SME_INDICATIONS_WIFIOFF | CSR_WIFI_SME_INDICATIONS_CONNECTIONQUALITY |
-            CSR_WIFI_SME_INDICATIONS_MEDIASTATUS | CSR_WIFI_SME_INDICATIONS_MICFAILURE);
-
-    if (sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig)) {
-        unifi_warning(priv, "uf_sme_config_wq: Get unifi_SMEConfigValue failed.\n");
-        return;
-    }
-
-    if (priv->if_index == CSR_INDEX_5G) {
-        staConfig.ifIndex = CSR_WIFI_SME_RADIO_IF_GHZ_5_0;
-    } else {
-        staConfig.ifIndex = CSR_WIFI_SME_RADIO_IF_GHZ_2_4;
-    }
-
-    deviceConfig.trustLevel = (CsrWifiSme80211dTrustLevel)tl_80211d;
-    if (sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig)) {
-        unifi_warning(priv,
-                "SME config for 802.11d Trust Level and Radio Band failed.\n");
-        return;
-    }
-
-} /* uf_sme_config_wq() */
-
-#endif /* CSR_SUPPORT_WEXT */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_ta_ind_wq
- *
- *      Deferred work queue function to send Traffic Analysis protocols
- *      indications to the SME.
- *      These are done in a deferred work queue for two reasons:
- *       - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
- *       - we want to load the main driver data path as lightly as possible
- *
- *      The TA classifications already come from a workqueue.
- *
- *  Arguments:
- *      work    Pointer to work queue item.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-    void
-uf_ta_ind_wq(struct work_struct *work)
-{
-    struct ta_ind *ind = container_of(work, struct ta_ind, task);
-    unifi_priv_t *priv = container_of(ind, unifi_priv_t, ta_ind_work);
-    u16 interfaceTag = 0;
-
-
-    CsrWifiRouterCtrlTrafficProtocolIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,
-            interfaceTag,
-            ind->packet_type,
-            ind->direction,
-            ind->src_addr);
-    ind->in_use = 0;
-
-} /* uf_ta_ind_wq() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_ta_sample_ind_wq
- *
- *      Deferred work queue function to send Traffic Analysis sample
- *      indications to the SME.
- *      These are done in a deferred work queue for two reasons:
- *       - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
- *       - we want to load the main driver data path as lightly as possible
- *
- *      The TA classifications already come from a workqueue.
- *
- *  Arguments:
- *      work    Pointer to work queue item.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-    void
-uf_ta_sample_ind_wq(struct work_struct *work)
-{
-    struct ta_sample_ind *ind = container_of(work, struct ta_sample_ind, task);
-    unifi_priv_t *priv = container_of(ind, unifi_priv_t, ta_sample_ind_work);
-    u16 interfaceTag = 0;
-
-     unifi_trace(priv, UDBG5, "rxtcp %d txtcp %d rxudp %d txudp %d prio %d\n",
-        priv->rxTcpThroughput,
-        priv->txTcpThroughput,
-        priv->rxUdpThroughput,
-        priv->txUdpThroughput,
-        priv->bh_thread.prio);
-
-    if(priv->rxTcpThroughput > 1000)
-    {
-        if (bh_priority == -1 && priv->bh_thread.prio != 1)
-        {
-            struct sched_param param;
-            priv->bh_thread.prio = 1;
-            unifi_trace(priv, UDBG1, "%s new thread (RT) priority = %d\n",
-                        priv->bh_thread.name, priv->bh_thread.prio);
-            param.sched_priority = priv->bh_thread.prio;
-            sched_setscheduler(priv->bh_thread.thread_task, SCHED_FIFO, &param);
-        }
-    } else
-    {
-        if (bh_priority == -1 && priv->bh_thread.prio != DEFAULT_PRIO)
-        {
-            struct sched_param param;
-            param.sched_priority = 0;
-            sched_setscheduler(priv->bh_thread.thread_task, SCHED_NORMAL, &param);
-            priv->bh_thread.prio = DEFAULT_PRIO;
-            unifi_trace(priv, UDBG1, "%s new thread priority = %d\n",
-                        priv->bh_thread.name, priv->bh_thread.prio);
-            set_user_nice(priv->bh_thread.thread_task, PRIO_TO_NICE(priv->bh_thread.prio));
-        }
-    }
-
-    CsrWifiRouterCtrlTrafficSampleIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, interfaceTag, ind->stats);
-
-    ind->in_use = 0;
-
-} /* uf_ta_sample_ind_wq() */
-
-
-/*
- * ---------------------------------------------------------------------------
- *  uf_send_m4_ready_wq
- *
- *      Deferred work queue function to send M4 ReadyToSend inds to the SME.
- *      These are done in a deferred work queue for two reasons:
- *       - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
- *       - we want to load the main driver data path as lightly as possible
- *
- *  Arguments:
- *      work    Pointer to work queue item.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void
-uf_send_m4_ready_wq(struct work_struct *work)
-{
-    netInterface_priv_t *InterfacePriv = container_of(work, netInterface_priv_t, send_m4_ready_task);
-    u16 iface = InterfacePriv->InterfaceTag;
-    unifi_priv_t *priv = InterfacePriv->privPtr;
-    CSR_MA_PACKET_REQUEST *req = &InterfacePriv->m4_signal.u.MaPacketRequest;
-    CsrWifiMacAddress peer;
-    unsigned long flags;
-
-    /* The peer address was stored in the signal */
-    spin_lock_irqsave(&priv->m4_lock, flags);
-    memcpy(peer.a, req->Ra.x, sizeof(peer.a));
-    spin_unlock_irqrestore(&priv->m4_lock, flags);
-
-    /* Send a signal to SME */
-    CsrWifiRouterCtrlM4ReadyToSendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, iface, peer);
-
-	unifi_trace(priv, UDBG1, "M4ReadyToSendInd sent for peer %pMF\n",
-		peer.a);
-
-} /* uf_send_m4_ready_wq() */
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-/*
- * ---------------------------------------------------------------------------
- *  uf_send_pkt_to_encrypt
- *
- *      Deferred work queue function to send the WAPI data pkts to SME when unicast KeyId = 1
- *      These are done in a deferred work queue for two reasons:
- *       - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
- *       - we want to load the main driver data path as lightly as possible
- *
- *  Arguments:
- *      work    Pointer to work queue item.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-void uf_send_pkt_to_encrypt(struct work_struct *work)
-{
-    netInterface_priv_t *interfacePriv = container_of(work, netInterface_priv_t, send_pkt_to_encrypt);
-    u16 interfaceTag = interfacePriv->InterfaceTag;
-    unifi_priv_t *priv = interfacePriv->privPtr;
-
-    u32 pktBulkDataLength;
-    u8 *pktBulkData;
-    unsigned long flags;
-
-    if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) {
-
-        pktBulkDataLength = interfacePriv->wapi_unicast_bulk_data.data_length;
-
-        if (pktBulkDataLength > 0) {
-		    pktBulkData = kmalloc(pktBulkDataLength, GFP_KERNEL);
-	    } else {
-		    unifi_error(priv, "uf_send_pkt_to_encrypt() : invalid buffer\n");
-		    return;
-	    }
-
-        spin_lock_irqsave(&priv->wapi_lock, flags);
-        /* Copy over the MA PKT REQ bulk data */
-        memcpy(pktBulkData, (u8*)interfacePriv->wapi_unicast_bulk_data.os_data_ptr, pktBulkDataLength);
-        /* Free any bulk data buffers allocated for the WAPI Data pkt */
-        unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
-        interfacePriv->wapi_unicast_bulk_data.net_buf_length = 0;
-        interfacePriv->wapi_unicast_bulk_data.data_length = 0;
-        interfacePriv->wapi_unicast_bulk_data.os_data_ptr = interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = NULL;
-        spin_unlock_irqrestore(&priv->wapi_lock, flags);
-
-        CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, pktBulkDataLength, pktBulkData);
-        unifi_trace(priv, UDBG1, "WapiUnicastTxEncryptInd sent to SME\n");
-
-        kfree(pktBulkData); /* Would have been copied over by the SME Handler */
-
-    } else {
-	    unifi_warning(priv, "uf_send_pkt_to_encrypt() is NOT applicable for interface mode - %d\n",interfacePriv->interfaceMode);
-    }
-}/* uf_send_pkt_to_encrypt() */
-#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_sme.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_sme.h
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_sme.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_sme.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,245 +0,0 @@
-/*
- * ***************************************************************************
- *  FILE:     unifi_sme.h
- *
- *  PURPOSE:    SME related definitions.
- *
- *  Copyright (C) 2007-2011 by Cambridge Silicon Radio Ltd.
- *
- *  Refer to LICENSE.txt included with this source code for details on
- *  the license terms.
- *
- * ***************************************************************************
- */
-#ifndef __LINUX_UNIFI_SME_H__
-#define __LINUX_UNIFI_SME_H__ 1
-
-#include <linux/kernel.h>
-
-#ifdef CSR_SME_USERSPACE
-#include "sme_userspace.h"
-#endif
-
-#include "csr_wifi_sme_lib.h"
-
-typedef int unifi_data_port_action;
-
-typedef struct unifi_port_cfg
-{
-    /* TRUE if this port entry is allocated */
-    u8 in_use;
-    CsrWifiRouterCtrlPortAction port_action;
-    CsrWifiMacAddress mac_address;
-} unifi_port_cfg_t;
-
-#define UNIFI_MAX_CONNECTIONS           8
-#define UNIFI_MAX_RETRY_LIMIT           5
-#define UF_DATA_PORT_NOT_OVERIDE        0
-#define UF_DATA_PORT_OVERIDE            1
-
-typedef struct unifi_port_config
-{
-    int entries_in_use;
-    int overide_action;
-    unifi_port_cfg_t port_cfg[UNIFI_MAX_CONNECTIONS];
-} unifi_port_config_t;
-
-
-enum sme_request_status {
-    SME_REQUEST_EMPTY,
-    SME_REQUEST_PENDING,
-    SME_REQUEST_RECEIVED,
-    SME_REQUEST_TIMEDOUT,
-    SME_REQUEST_CANCELLED,
-};
-
-/* Structure to hold a UDI logged signal */
-typedef struct {
-
-    /* The current status of the request */
-    enum sme_request_status request_status;
-
-    /* The status the SME has passed to us */
-    CsrResult reply_status;
-
-    /* SME's reply to a get request */
-    CsrWifiSmeVersions versions;
-    CsrWifiSmePowerConfig powerConfig;
-    CsrWifiSmeHostConfig hostConfig;
-    CsrWifiSmeStaConfig staConfig;
-    CsrWifiSmeDeviceConfig deviceConfig;
-    CsrWifiSmeCoexInfo coexInfo;
-    CsrWifiSmeCoexConfig coexConfig;
-    CsrWifiSmeMibConfig mibConfig;
-    CsrWifiSmeConnectionInfo connectionInfo;
-    CsrWifiSmeConnectionConfig connectionConfig;
-    CsrWifiSmeConnectionStats connectionStats;
-
-
-    /* SME's reply to a scan request */
-    u16 reply_scan_results_count;
-    CsrWifiSmeScanResult* reply_scan_results;
-
-} sme_reply_t;
-
-
-typedef struct {
-    u16 appHandle;
-    CsrWifiRouterEncapsulation encapsulation;
-    u16 protocol;
-    u8 oui[3];
-    u8 in_use;
-} sme_ma_unidata_ind_filter_t;
-
-
-CsrWifiRouterCtrlPortAction uf_sme_port_state(unifi_priv_t *priv,
-                                          unsigned char *address,
-                                          int queue,
-                                          u16 interfaceTag);
-unifi_port_cfg_t *uf_sme_port_config_handle(unifi_priv_t *priv,
-                                            unsigned char *address,
-                                            int queue,
-                                            u16 interfaceTag);
-
-
-
-/* Callback for event logging to SME clients */
-void sme_log_event(ul_client_t *client, const u8 *signal, int signal_len,
-                   const bulk_data_param_t *bulkdata, int dir);
-
-/* The workqueue task to the set the multicast addresses list */
-void uf_multicast_list_wq(struct work_struct *work);
-
-/* The workqueue task to execute the TA module */
-void uf_ta_wq(struct work_struct *work);
-
-
-/*
- * SME blocking helper functions
- */
-#ifdef UNIFI_DEBUG
-# define sme_complete_request(priv, status)   uf_sme_complete_request(priv, status, __func__)
-#else
-# define sme_complete_request(priv, status)   uf_sme_complete_request(priv, status, NULL)
-#endif
-
-void uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *func);
-void uf_sme_cancel_request(unifi_priv_t *priv, CsrResult reply_status);
-
-
-/*
- * Blocking functions using the SME SYS API.
- */
-int sme_sys_suspend(unifi_priv_t *priv);
-int sme_sys_resume(unifi_priv_t *priv);
-
-
-/*
- * Traffic Analysis workqueue jobs
- */
-void uf_ta_ind_wq(struct work_struct *work);
-void uf_ta_sample_ind_wq(struct work_struct *work);
-
-/*
- * SME config workqueue job
- */
-void uf_sme_config_wq(struct work_struct *work);
-
-/*
- * To send M4 read to send IND
- */
-void uf_send_m4_ready_wq(struct work_struct *work);
-
-#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
-/*
- * To send data pkt to Sme for encryption
- */
-void uf_send_pkt_to_encrypt(struct work_struct *work);
-#endif
-
-int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig);
-int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig);
-int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig);
-int sme_mgt_host_config_get(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig);
-int sme_mgt_sme_config_set(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, CsrWifiSmeDeviceConfig *deviceConfig);
-int sme_mgt_sme_config_get(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, CsrWifiSmeDeviceConfig *deviceConfig);
-int sme_mgt_coex_info_get(unifi_priv_t *priv, CsrWifiSmeCoexInfo *coexInfo);
-int sme_mgt_packet_filter_set(unifi_priv_t *priv);
-int sme_mgt_tspec(unifi_priv_t *priv, CsrWifiSmeListAction action,
-                  u32 tid, CsrWifiSmeDataBlock *tspec, CsrWifiSmeDataBlock *tclas);
-
-#ifdef CSR_SUPPORT_WEXT
-/*
- * Blocking functions using the SME MGT API.
- */
-int sme_mgt_wifi_on(unifi_priv_t *priv);
-int sme_mgt_wifi_off(unifi_priv_t *priv);
-/*int sme_mgt_set_value_async(unifi_priv_t *priv, unifi_AppValue *app_value);
-int sme_mgt_get_value_async(unifi_priv_t *priv, unifi_AppValue *app_value);
-int sme_mgt_get_value(unifi_priv_t *priv, unifi_AppValue *app_value);
-int sme_mgt_set_value(unifi_priv_t *priv, unifi_AppValue *app_value);
-*/
-int sme_mgt_coex_config_set(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig);
-int sme_mgt_coex_config_get(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig);
-int sme_mgt_mib_config_set(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig);
-int sme_mgt_mib_config_get(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig);
-
-int sme_mgt_connection_info_set(unifi_priv_t *priv, CsrWifiSmeConnectionInfo *connectionInfo);
-int sme_mgt_connection_info_get(unifi_priv_t *priv, CsrWifiSmeConnectionInfo *connectionInfo);
-int sme_mgt_connection_config_set(unifi_priv_t *priv, CsrWifiSmeConnectionConfig *connectionConfig);
-int sme_mgt_connection_config_get(unifi_priv_t *priv, CsrWifiSmeConnectionConfig *connectionConfig);
-int sme_mgt_connection_stats_get(unifi_priv_t *priv, CsrWifiSmeConnectionStats *connectionStats);
-
-int sme_mgt_versions_get(unifi_priv_t *priv, CsrWifiSmeVersions *versions);
-
-
-int sme_mgt_scan_full(unifi_priv_t *priv, CsrWifiSsid *specific_ssid,
-                      int num_channels, unsigned char *channel_list);
-int sme_mgt_scan_results_get_async(unifi_priv_t *priv,
-                                   struct iw_request_info *info,
-                                   char *scan_results,
-                                   long scan_results_len);
-int sme_mgt_disconnect(unifi_priv_t *priv);
-int sme_mgt_connect(unifi_priv_t *priv);
-int sme_mgt_key(unifi_priv_t *priv, CsrWifiSmeKey *sme_key,
-                CsrWifiSmeListAction action);
-int sme_mgt_pmkid(unifi_priv_t *priv, CsrWifiSmeListAction action,
-                  CsrWifiSmePmkidList *pmkid_list);
-int sme_mgt_mib_get(unifi_priv_t *priv,
-                    unsigned char *varbind, int *length);
-int sme_mgt_mib_set(unifi_priv_t *priv,
-                    unsigned char *varbind, int length);
-#ifdef CSR_SUPPORT_WEXT_AP
-int sme_ap_start(unifi_priv_t *priv,u16 interface_tag,CsrWifiSmeApConfig_t *ap_config);
-int sme_ap_stop(unifi_priv_t *priv,u16 interface_tag);
-int sme_ap_config(unifi_priv_t *priv,CsrWifiSmeApMacConfig *ap_mac_config, CsrWifiNmeApConfig *group_security_config);
-int uf_configure_supported_rates(u8 * supportedRates, u8 phySupportedBitmap);
-#endif
-int unifi_translate_scan(struct net_device *dev,
-                         struct iw_request_info *info,
-                         char *current_ev, char *end_buf,
-                         CsrWifiSmeScanResult *scan_data,
-                         int scan_index);
-
-#endif /* CSR_SUPPORT_WEXT */
-
-int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg);
-int unifi_cfg_power_save(unifi_priv_t *priv, unsigned char *arg);
-int unifi_cfg_power_supply(unifi_priv_t *priv, unsigned char *arg);
-int unifi_cfg_packet_filters(unifi_priv_t *priv, unsigned char *arg);
-int unifi_cfg_wmm_qos_info(unifi_priv_t *priv, unsigned char *arg);
-int unifi_cfg_wmm_addts(unifi_priv_t *priv, unsigned char *arg);
-int unifi_cfg_wmm_delts(unifi_priv_t *priv, unsigned char *arg);
-int unifi_cfg_get_info(unifi_priv_t *priv, unsigned char *arg);
-int unifi_cfg_strict_draft_n(unifi_priv_t *priv, unsigned char *arg);
-int unifi_cfg_enable_okc(unifi_priv_t *priv, unsigned char *arg);
-#ifdef CSR_SUPPORT_WEXT_AP
-int unifi_cfg_set_ap_config(unifi_priv_t * priv,unsigned char* arg);
-#endif
-
-
-
-int convert_sme_error(CsrResult error);
-
-
-#endif /* __LINUX_UNIFI_SME_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/unifi_wext.h linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_wext.h
--- linux-libre-3.10-gnu/drivers/staging/csr/unifi_wext.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/unifi_wext.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,108 +0,0 @@
-/*
- *****************************************************************************
- *
- * FILE : unifi_wext.h
- *
- * PURPOSE : Private header file for unifi driver support to wireless extensions.
- *
- * Copyright (C) 2005-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
-*****************************************************************************
- */
-#ifndef __LINUX_UNIFI_WEXT_H__
-#define __LINUX_UNIFI_WEXT_H__ 1
-
-#include <linux/kernel.h>
-#include <net/iw_handler.h>
-#include "csr_wifi_sme_prim.h"
-
-/*
- *      wext.c
- */
-/* A few details needed for WEP (Wireless Equivalent Privacy) */
-#define UNIFI_MAX_KEY_SIZE      16
-#define NUM_WEPKEYS              4
-#define SMALL_KEY_SIZE           5
-#define LARGE_KEY_SIZE          13
-typedef struct wep_key_t {
-    int len;
-    unsigned char key[UNIFI_MAX_KEY_SIZE];  /* 40-bit and 104-bit keys */
-} wep_key_t;
-
-#define UNIFI_SCAN_ACTIVE       0
-#define UNIFI_SCAN_PASSIVE      1
-#define UNIFI_MAX_SSID_LEN      32
-
-#define MAX_WPA_IE_LEN 64
-#define MAX_RSN_IE_LEN 255
-
-/*
- * Function to register in the netdev to report wireless stats.
- */
-struct iw_statistics *unifi_get_wireless_stats(struct net_device *dev);
-
-void uf_sme_wext_set_defaults(unifi_priv_t *priv);
-
-
-/*
- *      wext_events.c
- */
-/* Functions to generate Wireless Extension events */
-void wext_send_scan_results_event(unifi_priv_t *priv);
-void wext_send_assoc_event(unifi_priv_t *priv, unsigned char *bssid,
-                           unsigned char *req_ie, int req_ie_len,
-                           unsigned char *resp_ie, int resp_ie_len,
-                           unsigned char *scan_ie, unsigned int scan_ie_len);
-void wext_send_disassoc_event(unifi_priv_t *priv);
-void wext_send_michaelmicfailure_event(unifi_priv_t *priv,
-                                       u16 count, CsrWifiMacAddress address,
-                                       CsrWifiSmeKeyType keyType, u16 interfaceTag);
-void wext_send_pmkid_candidate_event(unifi_priv_t *priv, CsrWifiMacAddress bssid, u8 preauth_allowed, u16 interfaceTag);
-void wext_send_started_event(unifi_priv_t *priv);
-
-
-static inline int
-uf_iwe_stream_add_point(struct iw_request_info *info, char *start, char *stop,
-                        struct iw_event *piwe, char *extra)
-{
-    char *new_start;
-
-    new_start = iwe_stream_add_point(info, start, stop, piwe, extra);
-    if (unlikely(new_start == start))
-        return -E2BIG;
-
-    return (new_start - start);
-}
-
-
-static inline int
-uf_iwe_stream_add_event(struct iw_request_info *info, char *start, char *stop,
-                        struct iw_event *piwe, int len)
-{
-    char *new_start;
-
-    new_start = iwe_stream_add_event(info, start, stop, piwe, len);
-    if (unlikely(new_start == start))
-        return -E2BIG;
-
-    return (new_start - start);
-}
-
-static inline int
-uf_iwe_stream_add_value(struct iw_request_info *info, char *stream, char *start,
-                        char *stop, struct iw_event *piwe, int len)
-{
-    char *new_start;
-
-    new_start = iwe_stream_add_value(info, stream, start, stop, piwe, len);
-    if (unlikely(new_start == start))
-        return -E2BIG;
-
-    return (new_start - start);
-}
-
-
-#endif /* __LINUX_UNIFI_WEXT_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/csr/wext_events.c linux-libre-3.11-rc7-gnu/drivers/staging/csr/wext_events.c
--- linux-libre-3.10-gnu/drivers/staging/csr/wext_events.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/csr/wext_events.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,283 +0,0 @@
-/*
- * ---------------------------------------------------------------------------
- * FILE:     wext_events.c
- *
- * PURPOSE:
- *      Code to generate iwevents.
- *
- * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ---------------------------------------------------------------------------
- */
-#include <linux/types.h>
-#include <linux/etherdevice.h>
-#include <linux/if_arp.h>
-#include "csr_wifi_hip_unifi.h"
-#include "unifi_priv.h"
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  wext_send_assoc_event
- *
- *      Send wireless-extension events up to userland to announce
- *      successful association with an AP.
- *
- *  Arguments:
- *      priv                    Pointer to driver context.
- *      bssid                   MAC address of AP we associated with
- *      req_ie, req_ie_len      IEs in the original request
- *      resp_ie, resp_ie_len    IEs in the response
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      This is sent on first successful association, and again if we
- *      roam to another AP.
- * ---------------------------------------------------------------------------
- */
-void
-wext_send_assoc_event(unifi_priv_t *priv, unsigned char *bssid,
-                      unsigned char *req_ie, int req_ie_len,
-                      unsigned char *resp_ie, int resp_ie_len,
-                      unsigned char *scan_ie, unsigned int scan_ie_len)
-{
-#if WIRELESS_EXT > 17
-    union iwreq_data wrqu;
-
-    if (req_ie_len == 0) req_ie = NULL;
-    wrqu.data.length = req_ie_len;
-    wrqu.data.flags = 0;
-    wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], IWEVASSOCREQIE, &wrqu, req_ie);
-
-    if (resp_ie_len == 0) resp_ie = NULL;
-    wrqu.data.length = resp_ie_len;
-    wrqu.data.flags = 0;
-    wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], IWEVASSOCRESPIE, &wrqu, resp_ie);
-
-    if (scan_ie_len > 0) {
-        wrqu.data.length = scan_ie_len;
-        wrqu.data.flags = 0;
-        wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], IWEVGENIE, &wrqu, scan_ie);
-    }
-
-    memcpy(&wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
-    wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], SIOCGIWAP, &wrqu, NULL);
-#endif
-} /* wext_send_assoc_event() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  wext_send_disassoc_event
- *
- *      Send a wireless-extension event up to userland to announce
- *      that we disassociated from an AP.
- *
- *  Arguments:
- *      priv                    Pointer to driver context.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      The semantics of wpa_supplicant (the userland SME application) are
- *      that a SIOCGIWAP event with MAC address of all zero means
- *      disassociate.
- * ---------------------------------------------------------------------------
- */
-void
-wext_send_disassoc_event(unifi_priv_t *priv)
-{
-#if WIRELESS_EXT > 17
-    union iwreq_data wrqu;
-
-    memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
-    wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], SIOCGIWAP, &wrqu, NULL);
-#endif
-} /* wext_send_disassoc_event() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  wext_send_scan_results_event
- *
- *      Send wireless-extension events up to userland to announce
- *      completion of a scan.
- *
- *  Arguments:
- *      priv                    Pointer to driver context.
- *
- *  Returns:
- *      None.
- *
- *  Notes:
- *      This doesn't actually report the results, they are retrieved
- *      using the SIOCGIWSCAN ioctl command.
- * ---------------------------------------------------------------------------
- */
-void
-wext_send_scan_results_event(unifi_priv_t *priv)
-{
-#if WIRELESS_EXT > 17
-    union iwreq_data wrqu;
-
-    wrqu.data.length = 0;
-    wrqu.data.flags = 0;
-    wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], SIOCGIWSCAN, &wrqu, NULL);
-
-#endif
-} /* wext_send_scan_results_event() */
-
-
-
-/*
- * ---------------------------------------------------------------------------
- *  wext_send_michaelmicfailure_event
- *
- *      Send wireless-extension events up to userland to announce
- *      completion of a scan.
- *
- *  Arguments:
- *      priv            Pointer to driver context.
- *      count, macaddr, key_type, key_idx, tsc
- *                      Parameters from report from UniFi.
- *
- *  Returns:
- *      None.
- * ---------------------------------------------------------------------------
- */
-#if WIRELESS_EXT >= 18
-static inline void
-_send_michaelmicfailure_event(struct net_device *dev,
-                              int count, const unsigned char *macaddr,
-                              int key_type, int key_idx,
-                              unsigned char *tsc)
-{
-    union iwreq_data wrqu;
-    struct iw_michaelmicfailure mmf;
-
-    memset(&mmf, 0, sizeof(mmf));
-
-    mmf.flags = key_idx & IW_MICFAILURE_KEY_ID;
-    if (key_type == CSR_GROUP) {
-        mmf.flags |= IW_MICFAILURE_GROUP;
-    } else {
-        mmf.flags |= IW_MICFAILURE_PAIRWISE;
-    }
-    mmf.flags |= ((count << 5) & IW_MICFAILURE_COUNT);
-
-    mmf.src_addr.sa_family = ARPHRD_ETHER;
-    memcpy(mmf.src_addr.sa_data, macaddr, ETH_ALEN);
-
-    memcpy(mmf.tsc, tsc, IW_ENCODE_SEQ_MAX_SIZE);
-
-    memset(&wrqu, 0, sizeof(wrqu));
-    wrqu.data.length = sizeof(mmf);
-
-    wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&mmf);
-}
-#elif WIRELESS_EXT >= 15
-static inline void
-_send_michaelmicfailure_event(struct net_device *dev,
-                              int count, const unsigned char *macaddr,
-                              int key_type, int key_idx,
-                              unsigned char *tsc)
-{
-    union iwreq_data wrqu;
-    char buf[128];
-
-	sprintf(buf,
-		"MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=%pM)",
-		key_idx, (key_type == CSR_GROUP) ? "broad" : "uni", macaddr);
-    memset(&wrqu, 0, sizeof(wrqu));
-    wrqu.data.length = strlen(buf);
-    wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
-}
-#else /* WIRELESS_EXT >= 15 */
-static inline void
-_send_michaelmicfailure_event(struct net_device *dev,
-                              int count, const unsigned char *macaddr,
-                              int key_type, int key_idx,
-                              unsigned char *tsc)
-{
-    /* Not supported before WEXT 15 */
-}
-#endif /* WIRELESS_EXT >= 15 */
-
-
-void
-wext_send_michaelmicfailure_event(unifi_priv_t *priv,
-                                  u16 count,
-                                  CsrWifiMacAddress address,
-                                  CsrWifiSmeKeyType keyType,
-                                  u16 interfaceTag)
-{
-    unsigned char tsc[8] = {0};
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "wext_send_michaelmicfailure_event bad interfaceTag\n");
-        return;
-    }
-
-    _send_michaelmicfailure_event(priv->netdev[interfaceTag],
-                                  count,
-                                  address.a,
-                                  keyType,
-                                  0,
-                                  tsc);
-} /* wext_send_michaelmicfailure_event() */
-
-void
-wext_send_pmkid_candidate_event(unifi_priv_t *priv, CsrWifiMacAddress bssid, u8 preauth_allowed, u16 interfaceTag)
-{
-#if WIRELESS_EXT > 17
-    union iwreq_data wrqu;
-    struct iw_pmkid_cand pmkid_cand;
-
-    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
-        unifi_error(priv, "wext_send_pmkid_candidate_event bad interfaceTag\n");
-        return;
-    }
-
-    memset(&pmkid_cand, 0, sizeof(pmkid_cand));
-
-    if (preauth_allowed) {
-        pmkid_cand.flags |= IW_PMKID_CAND_PREAUTH;
-    }
-    pmkid_cand.bssid.sa_family = ARPHRD_ETHER;
-    memcpy(pmkid_cand.bssid.sa_data, bssid.a, ETH_ALEN);
-    /* Used as priority, smaller the number higher the priority, not really used in our case */
-    pmkid_cand.index = 1;
-
-    memset(&wrqu, 0, sizeof(wrqu));
-    wrqu.data.length = sizeof(pmkid_cand);
-
-    wireless_send_event(priv->netdev[interfaceTag], IWEVPMKIDCAND, &wrqu, (char *)&pmkid_cand);
-#endif
-} /* wext_send_pmkid_candidate_event() */
-
-/*
- * Send a custom WEXT event to say we have completed initialisation
- * and are now ready for WEXT ioctls. Used by Android wpa_supplicant.
- */
-void
-wext_send_started_event(unifi_priv_t *priv)
-{
-#if WIRELESS_EXT > 17
-    union iwreq_data wrqu;
-    char data[] = "STARTED";
-
-    wrqu.data.length = sizeof(data);
-    wrqu.data.flags = 0;
-    wireless_send_event(priv->netdev[CSR_WIFI_INTERFACE_IN_USE], IWEVCUSTOM, &wrqu, data);
-#endif
-} /* wext_send_started_event() */
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/comet.c linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/comet.c
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/comet.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/comet.c	2013-08-25 20:43:22.000000000 -0400
@@ -13,7 +13,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/hdlc.h>
 #include "pmcc4_sysdep.h"
 #include "sbecom_inline_linux.h"
@@ -35,235 +35,253 @@ extern int  cxt1e1_log_level;
 #define COMET_NUM_UNITS     5   /* Number of points per entry in table */
 
 /* forward references */
-STATIC void SetPwrLevel (comet_t * comet);
-STATIC void WrtRcvEqualizerTbl (ci_t * ci, comet_t * comet, u_int32_t *table);
-STATIC void WrtXmtWaveformTbl (ci_t * ci, comet_t * comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]);
+STATIC void SetPwrLevel(comet_t *comet);
+STATIC void WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table);
+STATIC void WrtXmtWaveformTbl(ci_t *ci, comet_t *comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]);
 
 
 void       *TWV_table[12] = {
-    TWVLongHaul0DB, TWVLongHaul7_5DB, TWVLongHaul15DB, TWVLongHaul22_5DB,
-    TWVShortHaul0, TWVShortHaul1, TWVShortHaul2, TWVShortHaul3, TWVShortHaul4,
-    TWVShortHaul5,
-    TWV_E1_75Ohm,    /** PORT POINT - 75 Ohm not supported **/
-    TWV_E1_120Ohm
+	TWVLongHaul0DB, TWVLongHaul7_5DB, TWVLongHaul15DB, TWVLongHaul22_5DB,
+	TWVShortHaul0, TWVShortHaul1, TWVShortHaul2, TWVShortHaul3,
+	TWVShortHaul4, TWVShortHaul5,
+	/** PORT POINT - 75 Ohm not supported **/
+	TWV_E1_75Ohm,
+	TWV_E1_120Ohm
 };
 
 
 static int
-lbo_tbl_lkup (int t1, int lbo)
-{
-    if ((lbo < CFG_LBO_LH0) || (lbo > CFG_LBO_E120))    /* error switches to
-                                                         * default */
-    {
-        if (t1)
-            lbo = CFG_LBO_LH0;  /* default T1 waveform table */
-        else
-            lbo = CFG_LBO_E120;     /* default E1 waveform table */
-    }
-    return (lbo - 1);               /* make index ZERO relative */
+lbo_tbl_lkup(int t1, int lbo) {
+	/* error switches to default */
+	if ((lbo < CFG_LBO_LH0) || (lbo > CFG_LBO_E120)) {
+		if (t1)
+			/* default T1 waveform table */
+			lbo = CFG_LBO_LH0;
+		else
+			/* default E1 waveform table */
+			lbo = CFG_LBO_E120;
+	}
+	/* make index ZERO relative */
+	return lbo - 1;
 }
 
-
-void
-init_comet (void *ci, comet_t * comet, u_int32_t port_mode, int clockmaster,
-            u_int8_t moreParams)
+void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
+		u_int8_t moreParams)
 {
-    u_int8_t isT1mode;
-    u_int8_t    tix = CFG_LBO_LH0;      /* T1 default */
-
-    isT1mode = IS_FRAME_ANY_T1 (port_mode);
-    /* T1 or E1 */
-    if (isT1mode)
-    {
-        pci_write_32 ((u_int32_t *) &comet->gbl_cfg, 0xa0);     /* Select T1 Mode & PIO
-                                                                 * output enabled */
-        tix = lbo_tbl_lkup (isT1mode, CFG_LBO_LH0);     /* default T1 waveform
-                                                         * table */
-    } else
-    {
-        pci_write_32 ((u_int32_t *) &comet->gbl_cfg, 0x81);     /* Select E1 Mode & PIO
-                                                                 * output enabled */
-        tix = lbo_tbl_lkup (isT1mode, CFG_LBO_E120);    /* default E1 waveform
-                                                         * table */
-    }
-
-    if (moreParams & CFG_LBO_MASK)
-        tix = lbo_tbl_lkup (isT1mode, moreParams & CFG_LBO_MASK);       /* dial-in requested
-                                                                         * waveform table */
-
-    /* Tx line Intfc cfg     ** Set for analog & no special patterns */
-    pci_write_32 ((u_int32_t *) &comet->tx_line_cfg, 0x00);     /* Transmit Line
-                                                                 * Interface Config. */
+	u_int8_t isT1mode;
+	/* T1 default */
+	u_int8_t    tix = CFG_LBO_LH0;
+	isT1mode = IS_FRAME_ANY_T1(port_mode);
+	/* T1 or E1 */
+	if (isT1mode) {
+		/* Select T1 Mode & PIO output enabled */
+		pci_write_32((u_int32_t *) &comet->gbl_cfg, 0xa0);
+		/* default T1 waveform table */
+		tix = lbo_tbl_lkup(isT1mode, CFG_LBO_LH0);
+	} else {
+		/* Select E1 Mode & PIO output enabled */
+		pci_write_32((u_int32_t *) &comet->gbl_cfg, 0x81);
+		/* default E1 waveform table */
+		tix = lbo_tbl_lkup(isT1mode, CFG_LBO_E120);
+	}
 
-    /* master test    ** Ignore Test settings for now */
-    pci_write_32 ((u_int32_t *) &comet->mtest, 0x00);   /* making sure it's
-                                                         * Default value */
+	if (moreParams & CFG_LBO_MASK)
+		/* dial-in requested waveform table */
+		tix = lbo_tbl_lkup(isT1mode, moreParams & CFG_LBO_MASK);
+	/* Tx line Intfc cfg Set for analog & no special patterns */
+	/* Transmit Line Interface Config. */
+	pci_write_32((u_int32_t *) &comet->tx_line_cfg, 0x00);
+	/* master test Ignore Test settings for now */
+	/* making sure it's Default value */
+	pci_write_32((u_int32_t *) &comet->mtest, 0x00);
+	/* Turn on Center (CENT) and everything else off */
+	/* RJAT cfg */
+	pci_write_32((u_int32_t *) &comet->rjat_cfg, 0x10);
+	/* Set Jitter Attenuation to recommend T1 values */
+	if (isT1mode) {
+		/* RJAT Divider N1 Control */
+		pci_write_32((u_int32_t *) &comet->rjat_n1clk, 0x2F);
+		/* RJAT Divider N2 Control */
+		pci_write_32((u_int32_t *) &comet->rjat_n2clk, 0x2F);
+	} else {
+		/* RJAT Divider N1 Control */
+		pci_write_32((u_int32_t *) &comet->rjat_n1clk, 0xFF);
+		/* RJAT Divider N2 Control */
+		pci_write_32((u_int32_t *) &comet->rjat_n2clk, 0xFF);
+	}
 
-    /* Turn on Center (CENT) and everything else off */
-    pci_write_32 ((u_int32_t *) &comet->rjat_cfg, 0x10);        /* RJAT cfg */
-    /* Set Jitter Attenuation to recommend T1 values */
-    if (isT1mode)
-    {
-        pci_write_32 ((u_int32_t *) &comet->rjat_n1clk, 0x2F);  /* RJAT Divider N1
-                                                                 * Control */
-        pci_write_32 ((u_int32_t *) &comet->rjat_n2clk, 0x2F);  /* RJAT Divider N2
-                                                                 * Control */
-    } else
-    {
-        pci_write_32 ((u_int32_t *) &comet->rjat_n1clk, 0xFF);  /* RJAT Divider N1
-                                                                 * Control */
-        pci_write_32 ((u_int32_t *) &comet->rjat_n2clk, 0xFF);  /* RJAT Divider N2
-                                                                 * Control */
-    }
+	/* Turn on Center (CENT) and everything else off */
+	/* TJAT Config. */
+	pci_write_32((u_int32_t *) &comet->tjat_cfg, 0x10);
 
-    /* Turn on Center (CENT) and everything else off */
-    pci_write_32 ((u_int32_t *) &comet->tjat_cfg, 0x10);        /* TJAT Config. */
+	/* Do not bypass jitter attenuation and bypass elastic store */
+	/* rx opts */
+	pci_write_32((u_int32_t *) &comet->rx_opt, 0x00);
 
-    /* Do not bypass jitter attenuation and bypass elastic store */
-    pci_write_32 ((u_int32_t *) &comet->rx_opt, 0x00);  /* rx opts */
+	/* TJAT ctrl & TJAT divider ctrl */
+	/* Set Jitter Attenuation to recommended T1 values */
+	if (isT1mode) {
+		/* TJAT Divider N1 Control */
+		pci_write_32((u_int32_t *) &comet->tjat_n1clk, 0x2F);
+		/* TJAT Divider N2  Control */
+		pci_write_32((u_int32_t *) &comet->tjat_n2clk, 0x2F);
+	} else {
+		/* TJAT Divider N1 Control */
+		pci_write_32((u_int32_t *) &comet->tjat_n1clk, 0xFF);
+		/* TJAT Divider N2 Control */
+		pci_write_32((u_int32_t *) &comet->tjat_n2clk, 0xFF);
+	}
 
-    /* TJAT ctrl & TJAT divider ctrl */
-    /* Set Jitter Attenuation to recommended T1 values */
-    if (isT1mode)
-    {
-        pci_write_32 ((u_int32_t *) &comet->tjat_n1clk, 0x2F);  /* TJAT Divider N1
-                                                                 * Control */
-        pci_write_32 ((u_int32_t *) &comet->tjat_n2clk, 0x2F);  /* TJAT Divider N2
-                                                                 * Control */
-    } else
-    {
-        pci_write_32 ((u_int32_t *) &comet->tjat_n1clk, 0xFF);  /* TJAT Divider N1
-                                                                 * Control */
-        pci_write_32 ((u_int32_t *) &comet->tjat_n2clk, 0xFF);  /* TJAT Divider N2
-                                                                 * Control */
-    }
+	/* 1c: rx ELST cfg   20: tx ELST cfg  28&38: rx&tx data link ctrl */
 
-    /* 1c: rx ELST cfg   20: tx ELST cfg  28&38: rx&tx data link ctrl */
-    if (isT1mode)
-    {                               /* Select 193-bit frame format */
-        pci_write_32 ((u_int32_t *) &comet->rx_elst_cfg, 0x00);
-        pci_write_32 ((u_int32_t *) &comet->tx_elst_cfg, 0x00);
-    } else
-    {                               /* Select 256-bit frame format */
-        pci_write_32 ((u_int32_t *) &comet->rx_elst_cfg, 0x03);
-        pci_write_32 ((u_int32_t *) &comet->tx_elst_cfg, 0x03);
-        pci_write_32 ((u_int32_t *) &comet->rxce1_ctl, 0x00);   /* disable T1 data link
-                                                                 * receive */
-        pci_write_32 ((u_int32_t *) &comet->txci1_ctl, 0x00);   /* disable T1 data link
-                                                                 * transmit */
-    }
+	/* Select 193-bit frame format */
+	if (isT1mode) {
+		pci_write_32((u_int32_t *) &comet->rx_elst_cfg, 0x00);
+		pci_write_32((u_int32_t *) &comet->tx_elst_cfg, 0x00);
+	} else {
+		/* Select 256-bit frame format */
+		pci_write_32((u_int32_t *) &comet->rx_elst_cfg, 0x03);
+		pci_write_32((u_int32_t *) &comet->tx_elst_cfg, 0x03);
+		/* disable T1 data link receive */
+		pci_write_32((u_int32_t *) &comet->rxce1_ctl, 0x00);
+		/* disable T1 data link transmit */
+		pci_write_32((u_int32_t *) &comet->txci1_ctl, 0x00);
+	}
 
     /* the following is a default value */
     /* Enable 8 out of 10 validation */
-    pci_write_32 ((u_int32_t *) &comet->t1_rboc_ena, 0x00);     /* t1RBOC
-                                                                 * enable(BOC:BitOriented
-                                                                 * Code) */
-    if (isT1mode)
-    {
+	 /* t1RBOC enable(BOC:BitOriented Code) */
+	pci_write_32((u_int32_t *) &comet->t1_rboc_ena, 0x00);
+	if (isT1mode)
+	{
 
-        /* IBCD cfg: aka Inband Code Detection ** loopback code length set to */
-        pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x04);    /* 6 bit down, 5 bit up
-                                                                 * (assert)  */
-        pci_write_32 ((u_int32_t *) &comet->ibcd_act, 0x08);    /* line loopback
-                                                                 * activate pattern */
-        pci_write_32 ((u_int32_t *) &comet->ibcd_deact, 0x24);  /* deactivate code
-                                                                 * pattern (i.e.001) */
-    }
+	/* IBCD cfg: aka Inband Code Detection ** loopback code length set to */
+		/* 6 bit down, 5 bit up (assert) */
+		pci_write_32((u_int32_t *) &comet->ibcd_cfg, 0x04);
+		/* line loopback activate pattern */
+		pci_write_32((u_int32_t *) &comet->ibcd_act, 0x08);
+		/* deactivate code pattern (i.e.001) */
+		pci_write_32((u_int32_t *) &comet->ibcd_deact, 0x24);
+	}
     /* 10: CDRC cfg 28&38: rx&tx data link 1 ctrl 48: t1 frmr cfg  */
     /* 50: SIGX cfg, COSS (change of signaling state) 54: XBAS cfg  */
     /* 60: t1 ALMI cfg */
     /* Configure Line Coding */
 
-    switch (port_mode)
-    {
-    case CFG_FRAME_SF:              /* 1 - T1 B8ZS */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0x20); /* 5:B8ZS */
-        pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0);
-        break;
-    case CFG_FRAME_ESF:     /* 2 - T1 B8ZS */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->rxce1_ctl, 0x20);   /* Bit 5: T1 DataLink
-                                                                 * Enable */
-        pci_write_32 ((u_int32_t *) &comet->txci1_ctl, 0x20);   /* 5: T1 DataLink Enable */
-        pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0x30); /* 4:ESF  5:ESFFA */
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0x04);    /* 2:ESF */
-        pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0x30); /* 4:ESF  5:B8ZS */
-        pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0x10); /* 4:ESF */
-        break;
-    case CFG_FRAME_E1PLAIN:         /* 3 - HDB3 */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x40);
-        break;
-    case CFG_FRAME_E1CAS:           /* 4 - HDB3 */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x60);
-        pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0);
-        break;
-    case CFG_FRAME_E1CRC:           /* 5 - HDB3 */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x10);
-        pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0xc2);
-        break;
-    case CFG_FRAME_E1CRC_CAS:       /* 6 - HDB3 */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x70);
-        pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x82);
-        break;
-    case CFG_FRAME_SF_AMI:          /* 7 - T1 AMI */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80);    /* Enable AMI Line
-                                                                 * Decoding */
-        pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        break;
-    case CFG_FRAME_ESF_AMI:         /* 8 - T1 AMI */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80);    /* Enable AMI Line
-                                                                 * Decoding */
-        pci_write_32 ((u_int32_t *) &comet->rxce1_ctl, 0x20);   /* 5: T1 DataLink Enable */
-        pci_write_32 ((u_int32_t *) &comet->txci1_ctl, 0x20);   /* 5: T1 DataLink Enable */
-        pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0x30); /* Bit 4:ESF  5:ESFFA */
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0x04);    /* 2:ESF */
-        pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0x10); /* 4:ESF */
-        pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0x10); /* 4:ESF */
-        break;
-    case CFG_FRAME_E1PLAIN_AMI:       /* 9 - AMI */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80);    /* Enable AMI Line
-                                                                 * Decoding */
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x80);
-        pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x40);
-        break;
-    case CFG_FRAME_E1CAS_AMI:       /* 10 - AMI */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80);    /* Enable AMI Line
-                                                                 * Decoding */
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0xe0);
-        pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0);
-        break;
-    case CFG_FRAME_E1CRC_AMI:       /* 11 - AMI */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80);    /* Enable AMI Line
-                                                                 * Decoding */
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x90);
-        pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0xc2);
-        break;
-    case CFG_FRAME_E1CRC_CAS_AMI:   /* 12 - AMI */
-        pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80);    /* Enable AMI Line
-                                                                 * Decoding */
-        pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0);
-        pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0xf0);
-        pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x82);
-        break;
-    }                               /* end switch */
+	switch (port_mode)
+	{
+	/* 1 - T1 B8ZS */
+	case CFG_FRAME_SF:
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->t1_frmr_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		/* 5:B8ZS */
+		pci_write_32((u_int32_t *) &comet->t1_xbas_cfg, 0x20);
+		pci_write_32((u_int32_t *) &comet->t1_almi_cfg, 0);
+		break;
+	/* 2 - T1 B8ZS */
+	case CFG_FRAME_ESF:
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
+		/* Bit 5: T1 DataLink Enable */
+		pci_write_32((u_int32_t *) &comet->rxce1_ctl, 0x20);
+		/* 5: T1 DataLink Enable */
+		pci_write_32((u_int32_t *) &comet->txci1_ctl, 0x20);
+		/* 4:ESF  5:ESFFA */
+		pci_write_32((u_int32_t *) &comet->t1_frmr_cfg, 0x30);
+		/* 2:ESF */
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0x04);
+		/* 4:ESF  5:B8ZS */
+		pci_write_32((u_int32_t *) &comet->t1_xbas_cfg, 0x30);
+		/* 4:ESF */
+		pci_write_32((u_int32_t *) &comet->t1_almi_cfg, 0x10);
+		break;
+	/* 3 - HDB3 */
+	case CFG_FRAME_E1PLAIN:
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0x40);
+		break;
+	/* 4 - HDB3 */
+	case CFG_FRAME_E1CAS:
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x60);
+		pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0);
+		break;
+	/* 5 - HDB3 */
+	case CFG_FRAME_E1CRC:
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x10);
+		pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0xc2);
+		break;
+	/* 6 - HDB3 */
+	case CFG_FRAME_E1CRC_CAS:
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x70);
+		pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0x82);
+		break;
+	/* 7 - T1 AMI */
+	case CFG_FRAME_SF_AMI:
+		/* Enable AMI Line Decoding */
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
+		pci_write_32((u_int32_t *) &comet->t1_frmr_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->t1_xbas_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->t1_almi_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		break;
+	/* 8 - T1 AMI */
+	case CFG_FRAME_ESF_AMI:
+		/* Enable AMI Line Decoding */
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
+		/* 5: T1 DataLink Enable */
+		pci_write_32((u_int32_t *) &comet->rxce1_ctl, 0x20);
+		/* 5: T1 DataLink Enable */
+		pci_write_32((u_int32_t *) &comet->txci1_ctl, 0x20);
+		/* Bit 4:ESF  5:ESFFA */
+		pci_write_32((u_int32_t *) &comet->t1_frmr_cfg, 0x30);
+		/* 2:ESF */
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0x04);
+		/* 4:ESF */
+		pci_write_32((u_int32_t *) &comet->t1_xbas_cfg, 0x10);
+		/* 4:ESF */
+		pci_write_32((u_int32_t *) &comet->t1_almi_cfg, 0x10);
+		break;
+	/* 9 - AMI */
+	case CFG_FRAME_E1PLAIN_AMI:
+		/* Enable AMI Line Decoding */
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x80);
+		pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0x40);
+		break;
+	/* 10 - AMI */
+	case CFG_FRAME_E1CAS_AMI:
+		/* Enable AMI Line Decoding */
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0xe0);
+		pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0);
+		break;
+	/* 11 - AMI */
+	case CFG_FRAME_E1CRC_AMI:
+		/* Enable AMI Line Decoding */
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0x90);
+		pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0xc2);
+		break;
+	/* 12 - AMI */
+	case CFG_FRAME_E1CRC_CAS_AMI:
+		/* Enable AMI Line Decoding */
+		pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0x80);
+		pci_write_32((u_int32_t *) &comet->sigx_cfg, 0);
+		pci_write_32((u_int32_t *) &comet->e1_tran_cfg, 0xf0);
+		pci_write_32((u_int32_t *) &comet->e1_frmr_aopts, 0x82);
+		break;
+	}	/* end switch */
 
     /***
      * Set Full Frame mode (NXDSO[1] = 0, NXDSO[0] = 0)
@@ -277,101 +295,109 @@ init_comet (void *ci, comet_t * comet, u
 
     /* 0x30: "BRIF cfg"; 0x20 is 'CMODE', 0x03 is (bit) rate */
     /* note "rate bits can only be set once after reset" */
-    if (clockmaster)
-    {                               /* CMODE == clockMode, 0=clock master (so
-                                     * all 3 others should be slave) */
-        if (isT1mode)               /* rate = 1.544 Mb/s */
-            pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x00);        /* Comet 0 Master
-                                                                         * Mode(CMODE=0) */
-        else                        /* rate = 2.048 Mb/s */
-            pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x01);        /* Comet 0 Master
-                                                                         * Mode(CMODE=0) */
+	if (clockmaster)
+		{
+		/* CMODE == clockMode, 0=clock master (so all 3 others should be slave) */
+		/* rate = 1.544 Mb/s */
+		if (isT1mode)
+			/* Comet 0 Master Mode(CMODE=0) */
+			pci_write_32((u_int32_t *) &comet->brif_cfg, 0x00);
+		/* rate = 2.048 Mb/s */
+		else
+			/* Comet 0 Master Mode(CMODE=0) */
+			pci_write_32((u_int32_t *) &comet->brif_cfg, 0x01);
 
-        /* 31: BRIF frame pulse cfg  06: tx timing options */
-        pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, 0x00);  /* Master Mode
-                                                                 * i.e.FPMODE=0 (@0x20) */
-        if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL)
-        {
-            if (cxt1e1_log_level >= LOG_SBEBUG12)
-                pr_info(">> %s: clockmaster internal clock\n", __func__);
-            pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d); /* internal oscillator */
-        } else                      /* external clock source */
-        {
-            if (cxt1e1_log_level >= LOG_SBEBUG12)
-                pr_info(">> %s: clockmaster external clock\n", __func__);
-            pci_write_32 ((u_int32_t *) &comet->tx_time, 0x09); /* loop timing
-                                                                 * (external) */
-        }
+		/* 31: BRIF frame pulse cfg  06: tx timing options */
 
-    } else                          /* slave */
-    {
-        if (isT1mode)
-            pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x20);        /* Slave Mode(CMODE=1,
-                                                                         * see above) */
-        else
-            pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x21);        /* Slave Mode (CMODE=1) */
-        pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, 0x20);  /* Slave Mode i.e.
-                                                                 * FPMODE=1 (@0x20) */
-        if (cxt1e1_log_level >= LOG_SBEBUG12)
-            pr_info(">> %s: clockslave internal clock\n", __func__);
-        pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d);     /* oscillator timing */
-    }
+		/* Master Mode i.e.FPMODE=0 (@0x20) */
+		pci_write_32((u_int32_t *) &comet->brif_fpcfg, 0x00);
+		if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL)
+			{
+			if (cxt1e1_log_level >= LOG_SBEBUG12)
+				pr_info(">> %s: clockmaster internal clock\n", __func__);
+			/* internal oscillator */
+			pci_write_32((u_int32_t *) &comet->tx_time, 0x0d);
+		} else {
+			/* external clock source */
+			if (cxt1e1_log_level >= LOG_SBEBUG12)
+				pr_info(">> %s: clockmaster external clock\n", __func__);
+			/* loop timing(external) */
+			pci_write_32((u_int32_t *) &comet->tx_time, 0x09);
+		}
 
-    /* 32: BRIF parity F-bit cfg */
-    /* Totem-pole operation */
-    pci_write_32 ((u_int32_t *) &comet->brif_pfcfg, 0x01);      /* Receive Backplane
-                                                                 * Parity/F-bit */
+	} else  {
+		/* slave */
+		if (isT1mode)
+			/* Slave Mode(CMODE=1, see above) */
+			pci_write_32((u_int32_t *) &comet->brif_cfg, 0x20);
+		else
+			/* Slave Mode(CMODE=1)*/
+			pci_write_32((u_int32_t *) &comet->brif_cfg, 0x21);
+		/* Slave Mode i.e. FPMODE=1 (@0x20) */
+		pci_write_32((u_int32_t *) &comet->brif_fpcfg, 0x20);
+	if (cxt1e1_log_level >= LOG_SBEBUG12)
+		pr_info(">> %s: clockslave internal clock\n", __func__);
+	/* oscillator timing */
+	pci_write_32((u_int32_t *) &comet->tx_time, 0x0d);
+	}
+
+	/* 32: BRIF parity F-bit cfg */
+	/* Totem-pole operation */
+	/* Receive Backplane Parity/F-bit */
+	pci_write_32((u_int32_t *) &comet->brif_pfcfg, 0x01);
 
     /* dc: RLPS equalizer V ref */
     /* Configuration */
-    if (isT1mode)
-        pci_write_32 ((u_int32_t *) &comet->rlps_eqvr, 0x2c);   /* RLPS Equalizer
-                                                                 * Voltage  */
-    else
-        pci_write_32 ((u_int32_t *) &comet->rlps_eqvr, 0x34);   /* RLPS Equalizer
-                                                                 * Voltage  */
+	if (isT1mode)
+		/* RLPS Equalizer Voltage  */
+		pci_write_32((u_int32_t *) &comet->rlps_eqvr, 0x2c);
+	else
+		/* RLPS Equalizer Voltage  */
+		pci_write_32((u_int32_t *) &comet->rlps_eqvr, 0x34);
 
     /* Reserved bit set and SQUELCH enabled */
     /* f8: RLPS cfg & status  f9: RLPS ALOS detect/clear threshold */
-    pci_write_32 ((u_int32_t *) &comet->rlps_cfgsts, 0x11);     /* RLPS Configuration
-                                                                 * Status */
-    if (isT1mode)
-        pci_write_32 ((u_int32_t *) &comet->rlps_alos_thresh, 0x55);    /* ? */
-    else
-        pci_write_32 ((u_int32_t *) &comet->rlps_alos_thresh, 0x22);    /* ? */
+	/* RLPS Configuration Status */
+	pci_write_32((u_int32_t *) &comet->rlps_cfgsts, 0x11);
+	if (isT1mode)
+		 /* ? */
+		pci_write_32((u_int32_t *) &comet->rlps_alos_thresh, 0x55);
+	else
+		/* ? */
+		pci_write_32((u_int32_t *) &comet->rlps_alos_thresh, 0x22);
 
 
     /* Set Full Frame mode (NXDSO[1] = 0, NXDSO[0] = 0) */
     /* CMODE=0: Clock slave mode with BTCLK as an input, DE=1: Use rising */
     /* edge of BTCLK for data, FE=1: Use rising edge of BTCLK for frame, */
     /* CMS=0: Use backplane freq, RATE[1:0]=0,0: T1 */
-/***    Transmit side is always an Input, Slave Clock*/
-    /* 40: BTIF cfg  41: BTIF frame pulse cfg */
-    if (isT1mode)
-        pci_write_32 ((u_int32_t *) &comet->btif_cfg, 0x38);    /* BTIF Configuration
-                                                                 * Reg. */
-    else
-        pci_write_32 ((u_int32_t *) &comet->btif_cfg, 0x39);    /* BTIF Configuration
-                                                                 * Reg. */
-
-    pci_write_32 ((u_int32_t *) &comet->btif_fpcfg, 0x01);      /* BTIF Frame Pulse
-                                                                 * Config. */
+    /***    Transmit side is always an Input, Slave Clock*/
+    /* 40: BTIF cfg  41: loop timing(external) */
+	/*BTIF frame pulse cfg */
+	if (isT1mode)
+		/* BTIF Configuration  Reg. */
+		pci_write_32((u_int32_t *) &comet->btif_cfg, 0x38);
+	else
+		/* BTIF Configuration  Reg. */
+		pci_write_32((u_int32_t *) &comet->btif_cfg, 0x39);
+	/* BTIF Frame Pulse Config. */
+	pci_write_32((u_int32_t *) &comet->btif_fpcfg, 0x01);
 
     /* 0a: master diag  06: tx timing options */
     /* if set Comet to loop back */
 
     /* Comets set to normal */
-    pci_write_32 ((u_int32_t *) &comet->mdiag, 0x00);
+	pci_write_32((u_int32_t *) &comet->mdiag, 0x00);
 
     /* BTCLK driven by TCLKI internally (crystal driven) and Xmt Elasted  */
     /* Store is enabled. */
 
-    WrtXmtWaveformTbl (ci, comet, TWV_table[tix]);
-    if (isT1mode)
-        WrtRcvEqualizerTbl ((ci_t *) ci, comet, &T1_Equalizer[0]);
-    else
-        WrtRcvEqualizerTbl ((ci_t *) ci, comet, &E1_Equalizer[0]);
-    SetPwrLevel (comet);
+	WrtXmtWaveformTbl(ci, comet, TWV_table[tix]);
+	if (isT1mode)
+		WrtRcvEqualizerTbl((ci_t *) ci, comet, &T1_Equalizer[0]);
+	else
+		WrtRcvEqualizerTbl((ci_t *) ci, comet, &E1_Equalizer[0]);
+	SetPwrLevel(comet);
 }
 
 /*
@@ -382,15 +408,15 @@ init_comet (void *ci, comet_t * comet, u
 ** Returns:     Nothing
 */
 STATIC void
-WrtXmtWaveform (ci_t * ci, comet_t * comet, u_int32_t sample, u_int32_t unit, u_int8_t data)
+WrtXmtWaveform(ci_t *ci, comet_t *comet, u_int32_t sample, u_int32_t unit, u_int8_t data)
 {
-    u_int8_t    WaveformAddr;
+	u_int8_t    WaveformAddr;
 
-    WaveformAddr = (sample << 3) + (unit & 7);
-    pci_write_32 ((u_int32_t *) &comet->xlpg_pwave_addr, WaveformAddr);
-    pci_flush_write (ci);           /* for write order preservation when
-                                     * Optimizing driver */
-    pci_write_32 ((u_int32_t *) &comet->xlpg_pwave_data, 0x7F & data);
+	WaveformAddr = (sample << 3) + (unit & 7);
+	pci_write_32((u_int32_t *) &comet->xlpg_pwave_addr, WaveformAddr);
+	/* for write order preservation when Optimizing driver */
+	pci_flush_write(ci);
+	pci_write_32((u_int32_t *) &comet->xlpg_pwave_data, 0x7F & data);
 }
 
 /*
@@ -400,19 +426,19 @@ WrtXmtWaveform (ci_t * ci, comet_t * com
 ** Returns:     Nothing
 */
 STATIC void
-WrtXmtWaveformTbl (ci_t * ci, comet_t * comet,
-                   u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS])
+WrtXmtWaveformTbl(ci_t *ci, comet_t *comet,
+		  u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS])
 {
-    u_int32_t sample, unit;
+	u_int32_t sample, unit;
 
-    for (sample = 0; sample < COMET_NUM_SAMPLES; sample++)
-    {
-        for (unit = 0; unit < COMET_NUM_UNITS; unit++)
-            WrtXmtWaveform (ci, comet, sample, unit, table[sample][unit]);
-    }
+	for (sample = 0; sample < COMET_NUM_SAMPLES; sample++)
+		{
+		for (unit = 0; unit < COMET_NUM_UNITS; unit++)
+			WrtXmtWaveform(ci, comet, sample, unit, table[sample][unit]);
+		}
 
     /* Enable transmitter and set output amplitude */
-    pci_write_32 ((u_int32_t *) &comet->xlpg_cfg, table[COMET_NUM_SAMPLES][0]);
+	pci_write_32((u_int32_t *) &comet->xlpg_cfg, table[COMET_NUM_SAMPLES][0]);
 }
 
 
@@ -427,60 +453,60 @@ WrtXmtWaveformTbl (ci_t * ci, comet_t *
 */
 
 STATIC void
-WrtRcvEqualizerTbl (ci_t * ci, comet_t * comet, u_int32_t *table)
+WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table)
 {
-    u_int32_t   ramaddr;
-    volatile u_int32_t value;
+	u_int32_t   ramaddr;
+	volatile u_int32_t value;
 
-    for (ramaddr = 0; ramaddr < 256; ramaddr++)
-    {
-        /*** the following lines are per Errata 7, 2.5 ***/
-        {
-            pci_write_32 ((u_int32_t *) &comet->rlps_eq_rwsel, 0x80);   /* Set up for a read
-                                                                         * operation */
-            pci_flush_write (ci);   /* for write order preservation when
-                                     * Optimizing driver */
-            pci_write_32 ((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); /* write the addr,
-                                                                                  * initiate a read */
-            pci_flush_write (ci);   /* for write order preservation when
-                                     * Optimizing driver */
-            /*
-             * wait 3 line rate clock cycles to ensure address bits are
-             * captured by T1/E1 clock
-             */
-            OS_uwait (4, "wret");   /* 683ns * 3 = 1366 ns, approx 2us (but
-                                     * use 4us) */
-        }
+	for (ramaddr = 0; ramaddr < 256; ramaddr++) {
+	/*** the following lines are per Errata 7, 2.5 ***/
+		{
+		/* Set up for a read operation */
+		pci_write_32((u_int32_t *) &comet->rlps_eq_rwsel, 0x80);
+		/* for write order preservation when Optimizing driver */
+		pci_flush_write(ci);
+		/* write the addr, initiate a read */
+		pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr);
+		/* for write order preservation when Optimizing driver */
+		pci_flush_write(ci);
+		/*
+		* wait 3 line rate clock cycles to ensure address bits are
+		* captured by T1/E1 clock
+		*/
 
-        value = *table++;
-        pci_write_32 ((u_int32_t *) &comet->rlps_idata3, (u_int8_t) (value >> 24));
-        pci_write_32 ((u_int32_t *) &comet->rlps_idata2, (u_int8_t) (value >> 16));
-        pci_write_32 ((u_int32_t *) &comet->rlps_idata1, (u_int8_t) (value >> 8));
-        pci_write_32 ((u_int32_t *) &comet->rlps_idata0, (u_int8_t) value);
-        pci_flush_write (ci);       /* for write order preservation when
-                                     * Optimizing driver */
+		/* 683ns * 3 = 1366 ns, approx 2us (but use 4us) */
+		OS_uwait(4, "wret");
+	}
 
-        /* Storing RAM address, causes RAM to be updated */
+	value = *table++;
+	pci_write_32((u_int32_t *) &comet->rlps_idata3, (u_int8_t) (value >> 24));
+	pci_write_32((u_int32_t *) &comet->rlps_idata2, (u_int8_t) (value >> 16));
+	pci_write_32((u_int32_t *) &comet->rlps_idata1, (u_int8_t) (value >> 8));
+	pci_write_32((u_int32_t *) &comet->rlps_idata0, (u_int8_t) value);
+	 /* for write order preservation when Optimizing driver */
+	pci_flush_write(ci);
 
-        pci_write_32 ((u_int32_t *) &comet->rlps_eq_rwsel, 0);  /* Set up for a write
-                                                                 * operation */
-        pci_flush_write (ci);       /* for write order preservation when
-                                     * Optimizing driver */
-        pci_write_32 ((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); /* write the addr,
-                                                                                 * initiate a read */
-        pci_flush_write (ci);       /* for write order preservation when
-                                     * Optimizing driver */
-        /*
-         * wait 3 line rate clock cycles to ensure address bits are captured
-         * by T1/E1 clock
-         */
-        OS_uwait (4, "wret");       /* 683ns * 3 = 1366 ns, approx 2us (but
-                                     * use 4us) */
-    }
+	/* Storing RAM address, causes RAM to be updated */
 
-    pci_write_32 ((u_int32_t *) &comet->rlps_eq_cfg, 0xCB);     /* Enable Equalizer &
-                                                                 * set it to use 256
-                                                                 * periods */
+		/* Set up for a write operation */
+		pci_write_32((u_int32_t *) &comet->rlps_eq_rwsel, 0);
+		/* for write order preservation when optimizing driver */
+		pci_flush_write(ci);
+		/* write the addr, initiate a read */
+		pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr);
+		 /* for write order preservation when optimizing driver */
+		pci_flush_write(ci);
+
+	/*
+	* wait 3 line rate clock cycles to ensure address bits are captured
+	* by T1/E1 clock
+	*/
+		/* 683ns * 3 = 1366 ns, approx 2us (but use 4us) */
+		OS_uwait(4, "wret");
+	}
+
+	/* Enable Equalizer & set it to use 256 periods */
+	pci_write_32((u_int32_t *) &comet->rlps_eq_cfg, 0xCB);
 }
 
 
@@ -491,9 +517,9 @@ WrtRcvEqualizerTbl (ci_t * ci, comet_t *
 */
 
 STATIC void
-SetPwrLevel (comet_t * comet)
+SetPwrLevel(comet_t *comet)
 {
-    volatile u_int32_t temp;
+	volatile u_int32_t temp;
 
 /*
 **    Algorithm to Balance the Power Distribution of Ttip Tring
@@ -507,22 +533,20 @@ SetPwrLevel (comet_t * comet)
 **    Repeat these steps for register F5
 **    Write 0x01 to register F6
 */
-    pci_write_32 ((u_int32_t *) &comet->xlpg_fdata_sel, 0x00);  /* XLPG Fuse Data Select */
-
-    pci_write_32 ((u_int32_t *) &comet->xlpg_atest_pctl, 0x01); /* XLPG Analog Test
-                                                                 * Positive control */
-    pci_write_32 ((u_int32_t *) &comet->xlpg_atest_pctl, 0x01);
-
-    temp = pci_read_32 ((u_int32_t *) &comet->xlpg_atest_pctl) & 0xfe;
-    pci_write_32 ((u_int32_t *) &comet->xlpg_atest_pctl, temp);
-
-    pci_write_32 ((u_int32_t *) &comet->xlpg_atest_nctl, 0x01); /* XLPG Analog Test
-                                                                 * Negative control */
-    pci_write_32 ((u_int32_t *) &comet->xlpg_atest_nctl, 0x01);
-
-    temp = pci_read_32 ((u_int32_t *) &comet->xlpg_atest_nctl) & 0xfe;
-    pci_write_32 ((u_int32_t *) &comet->xlpg_atest_nctl, temp);
-    pci_write_32 ((u_int32_t *) &comet->xlpg_fdata_sel, 0x01);  /* XLPG */
+	/* XLPG Fuse Data Select */
+	pci_write_32((u_int32_t *) &comet->xlpg_fdata_sel, 0x00);
+	/* XLPG Analog Test Positive control */
+	pci_write_32((u_int32_t *) &comet->xlpg_atest_pctl, 0x01);
+	pci_write_32((u_int32_t *) &comet->xlpg_atest_pctl, 0x01);
+	temp = pci_read_32((u_int32_t *) &comet->xlpg_atest_pctl) & 0xfe;
+	pci_write_32((u_int32_t *) &comet->xlpg_atest_pctl, temp);
+	pci_write_32((u_int32_t *) &comet->xlpg_atest_nctl, 0x01);
+	pci_write_32((u_int32_t *) &comet->xlpg_atest_nctl, 0x01);
+	/* XLPG Analog Test Negative control */
+	temp = pci_read_32((u_int32_t *) &comet->xlpg_atest_nctl) & 0xfe;
+	pci_write_32((u_int32_t *) &comet->xlpg_atest_nctl, temp);
+	/* XLPG */
+	pci_write_32((u_int32_t *) &comet->xlpg_fdata_sel, 0x01);
 }
 
 
@@ -535,33 +559,30 @@ SetPwrLevel (comet_t * comet)
 */
 #if 0
 STATIC void
-SetCometOps (comet_t * comet)
+SetCometOps(comet_t *comet)
 {
-    volatile u_int8_t rd_value;
-
-    if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2))
-    {
-        rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_cfg);     /* read the BRIF
-                                                                                 * Configuration */
-        rd_value &= ~0x20;
-        pci_write_32 ((u_int32_t *) &comet->brif_cfg, (u_int32_t) rd_value);
-
-        rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_fpcfg);   /* read the BRIF Frame
-                                                                                 * Pulse Configuration */
-        rd_value &= ~0x20;
-        pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, (u_int8_t) rd_value);
-    } else
-    {
-        rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_cfg);     /* read the BRIF
-                                                                                 * Configuration */
-        rd_value |= 0x20;
-        pci_write_32 ((u_int32_t *) &comet->brif_cfg, (u_int32_t) rd_value);
+	volatile u_int8_t rd_value;
 
-        rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_fpcfg);   /* read the BRIF Frame
-                                                                                 * Pulse Configuration */
-        rd_value |= 0x20;
-        pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, (u_int8_t) rd_value);
-    }
+	if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2))
+	{
+		/* read the BRIF Configuration */
+		rd_value = (u_int8_t) pci_read_32((u_int32_t *) &comet->brif_cfg);
+		rd_value &= ~0x20;
+		pci_write_32((u_int32_t *) &comet->brif_cfg, (u_int32_t) rd_value);
+		/* read the BRIF Frame Pulse Configuration */
+		rd_value = (u_int8_t) pci_read_32((u_int32_t *) &comet->brif_fpcfg);
+		rd_value &= ~0x20;
+		pci_write_32((u_int32_t *) &comet->brif_fpcfg, (u_int8_t) rd_value);
+	} else {
+	/* read the BRIF Configuration */
+	rd_value = (u_int8_t) pci_read_32((u_int32_t *) &comet->brif_cfg);
+	rd_value |= 0x20;
+	pci_write_32((u_int32_t *) &comet->brif_cfg, (u_int32_t) rd_value);
+	/* read the BRIF Frame Pulse Configuration */
+	rd_value = (u_int8_t) pci_read_32((u_int32_t *) &comet->brif_fpcfg);
+	rd_value |= 0x20;
+	pci_write_32(u_int32_t *) & comet->brif_fpcfg, (u_int8_t) rd_value);
+	}
 }
 #endif
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/functions.c linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/functions.c
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/functions.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/functions.c	2013-08-25 20:43:22.000000000 -0400
@@ -14,7 +14,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/slab.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/byteorder.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
@@ -97,7 +97,7 @@ pci_write_32 (u_int32_t *p, u_int32_t v)
 
 
 void
-pci_flush_write (ci_t * ci)
+pci_flush_write (ci_t *ci)
 {
     volatile u_int32_t v;
 
@@ -202,7 +202,7 @@ sd_line_is_ok (void *user)
 {
     struct net_device *ndev = (struct net_device *) user;
 
-    return (netif_carrier_ok (ndev));
+    return netif_carrier_ok (ndev);
 }
 
 void
@@ -246,7 +246,7 @@ sd_queue_stopped (void *user)
 {
     struct net_device *ndev = (struct net_device *) user;
 
-    return (netif_queue_stopped (ndev));
+    return netif_queue_stopped (ndev);
 }
 
 void sd_recv_consume(void *token, size_t len, void *user)
@@ -279,7 +279,7 @@ VMETRO_TRACE (void *x)
 
 
 void
-VMETRO_TRIGGER (ci_t * ci, int x)
+VMETRO_TRIGGER (ci_t *ci, int x)
 {
     comet_t    *comet;
     volatile u_int32_t data;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/hwprobe.c linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/hwprobe.c
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/hwprobe.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/hwprobe.c	2013-08-25 20:43:22.000000000 -0400
@@ -50,7 +50,7 @@ struct s_hdw_info hdw_info[MAX_BOARDS];
 
 
 void        __init
-show_two (hdw_info_t * hi, int brdno)
+show_two (hdw_info_t *hi, int brdno)
 {
     ci_t       *ci;
     struct pci_dev *pdev;
@@ -102,7 +102,7 @@ show_two (hdw_info_t * hi, int brdno)
 
 
 void        __init
-hdw_sn_get (hdw_info_t * hi, int brdno)
+hdw_sn_get (hdw_info_t *hi, int brdno)
 {
     /* obtain hardware EEPROM information */
     long        addr;
@@ -222,7 +222,7 @@ cleanup_devs (void)
 
 
 STATIC int  __init
-c4_hdw_init (struct pci_dev * pdev, int found)
+c4_hdw_init (struct pci_dev *pdev, int found)
 {
     hdw_info_t *hi;
     int         i;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/linux.c linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/linux.c
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/linux.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/linux.c	2013-08-25 20:43:22.000000000 -0400
@@ -144,7 +144,7 @@ getuserbychan (int channum)
 
 
 char       *
-get_hdlc_name (hdlc_device * hdlc)
+get_hdlc_name (hdlc_device *hdlc)
 {
     struct c4_priv *priv = hdlc->priv;
     struct net_device *dev = getuserbychan (priv->channum);
@@ -185,7 +185,7 @@ mkret (int bsd)
  * within a port's group.
  */
 void
-c4_wk_chan_restart (mch_t * ch)
+c4_wk_chan_restart (mch_t *ch)
 {
     mpi_t      *pi = ch->up;
 
@@ -203,7 +203,7 @@ c4_wk_chan_restart (mch_t * ch)
 }
 
 status_t
-c4_wk_chan_init (mpi_t * pi, mch_t * ch)
+c4_wk_chan_init (mpi_t *pi, mch_t *ch)
 {
     /*
      * this will be used to restart a stopped channel
@@ -218,7 +218,7 @@ c4_wk_chan_init (mpi_t * pi, mch_t * ch)
 }
 
 status_t
-c4_wq_port_init (mpi_t * pi)
+c4_wq_port_init (mpi_t *pi)
 {
 
     char        name[16], *np;  /* NOTE: name of the queue limited by system
@@ -241,7 +241,7 @@ c4_wq_port_init (mpi_t * pi)
 }
 
 void
-c4_wq_port_cleanup (mpi_t * pi)
+c4_wq_port_cleanup (mpi_t *pi)
 {
     /*
      * PORT POINT: cannot call this if WQ is statically allocated w/in
@@ -278,7 +278,7 @@ c4_ebus_interrupt (int irq, void *dev_in
 
 
 static int
-void_open (struct net_device * ndev)
+void_open (struct net_device *ndev)
 {
     pr_info("%s: trying to open master device !\n", ndev->name);
     return -1;
@@ -286,7 +286,7 @@ void_open (struct net_device * ndev)
 
 
 STATIC int
-chan_open (struct net_device * ndev)
+chan_open (struct net_device *ndev)
 {
     hdlc_device *hdlc = dev_to_hdlc (ndev);
     const struct c4_priv *priv = hdlc->priv;
@@ -306,7 +306,7 @@ chan_open (struct net_device * ndev)
 
 
 STATIC int
-chan_close (struct net_device * ndev)
+chan_close (struct net_device *ndev)
 {
     hdlc_device *hdlc = dev_to_hdlc (ndev);
     const struct c4_priv *priv = hdlc->priv;
@@ -320,14 +320,14 @@ chan_close (struct net_device * ndev)
 
 
 STATIC int
-chan_dev_ioctl (struct net_device * dev, struct ifreq * ifr, int cmd)
+chan_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 {
     return hdlc_ioctl (dev, ifr, cmd);
 }
 
 
 STATIC int
-chan_attach_noop (struct net_device * ndev, unsigned short foo_1, unsigned short foo_2)
+chan_attach_noop (struct net_device *ndev, unsigned short foo_1, unsigned short foo_2)
 {
     return 0;                   /* our driver has nothing to do here, show's
                                  * over, go home */
@@ -335,7 +335,7 @@ chan_attach_noop (struct net_device * nd
 
 
 STATIC struct net_device_stats *
-chan_get_stats (struct net_device * ndev)
+chan_get_stats (struct net_device *ndev)
 {
     mch_t      *ch;
     struct net_device_stats *nstats;
@@ -388,14 +388,14 @@ chan_get_stats (struct net_device * ndev
 
 
 static ci_t *
-get_ci_by_dev (struct net_device * ndev)
+get_ci_by_dev (struct net_device *ndev)
 {
     return (ci_t *)(netdev_priv(ndev));
 }
 
 
 STATIC int
-c4_linux_xmit (struct sk_buff * skb, struct net_device * ndev)
+c4_linux_xmit (struct sk_buff *skb, struct net_device *ndev)
 {
     const struct c4_priv *priv;
     int         rval;
@@ -417,8 +417,8 @@ static const struct net_device_ops chan_
 };
 
 STATIC struct net_device *
-create_chan (struct net_device * ndev, ci_t * ci,
-             struct sbecom_chan_param * cp)
+create_chan (struct net_device *ndev, ci_t *ci,
+             struct sbecom_chan_param *cp)
 {
     hdlc_device *hdlc;
     struct net_device *dev;
@@ -510,7 +510,7 @@ create_chan (struct net_device * ndev, c
 
 /* the idea here is to get port information and pass it back (using pointer) */
 STATIC      status_t
-do_get_port (struct net_device * ndev, void *data)
+do_get_port (struct net_device *ndev, void *data)
 {
     int         ret;
     ci_t       *ci;             /* ci stands for card information */
@@ -535,7 +535,7 @@ do_get_port (struct net_device * ndev, v
 
 /* this function copys the user data and then calls the real action function */
 STATIC      status_t
-do_set_port (struct net_device * ndev, void *data)
+do_set_port (struct net_device *ndev, void *data)
 {
     ci_t       *ci;             /* ci stands for card information */
     struct sbecom_port_param pp;/* copy data to kernel land */
@@ -557,7 +557,7 @@ do_set_port (struct net_device * ndev, v
 
 /* work the port loopback mode as per directed */
 STATIC      status_t
-do_port_loop (struct net_device * ndev, void *data)
+do_port_loop (struct net_device *ndev, void *data)
 {
     struct sbecom_port_param pp;
     ci_t       *ci;
@@ -572,7 +572,7 @@ do_port_loop (struct net_device * ndev,
 
 /* set the specified register with the given value / or just read it */
 STATIC      status_t
-do_framer_rw (struct net_device * ndev, void *data)
+do_framer_rw (struct net_device *ndev, void *data)
 {
     struct sbecom_port_param pp;
     ci_t       *ci;
@@ -593,7 +593,7 @@ do_framer_rw (struct net_device * ndev,
 
 /* set the specified register with the given value / or just read it */
 STATIC      status_t
-do_pld_rw (struct net_device * ndev, void *data)
+do_pld_rw (struct net_device *ndev, void *data)
 {
     struct sbecom_port_param pp;
     ci_t       *ci;
@@ -614,7 +614,7 @@ do_pld_rw (struct net_device * ndev, voi
 
 /* set the specified register with the given value / or just read it */
 STATIC      status_t
-do_musycc_rw (struct net_device * ndev, void *data)
+do_musycc_rw (struct net_device *ndev, void *data)
 {
     struct c4_musycc_param mp;
     ci_t       *ci;
@@ -634,7 +634,7 @@ do_musycc_rw (struct net_device * ndev,
 }
 
 STATIC      status_t
-do_get_chan (struct net_device * ndev, void *data)
+do_get_chan (struct net_device *ndev, void *data)
 {
     struct sbecom_chan_param cp;
     int         ret;
@@ -652,7 +652,7 @@ do_get_chan (struct net_device * ndev, v
 }
 
 STATIC      status_t
-do_set_chan (struct net_device * ndev, void *data)
+do_set_chan (struct net_device *ndev, void *data)
 {
     struct sbecom_chan_param cp;
     int         ret;
@@ -673,7 +673,7 @@ do_set_chan (struct net_device * ndev, v
 }
 
 STATIC      status_t
-do_create_chan (struct net_device * ndev, void *data)
+do_create_chan (struct net_device *ndev, void *data)
 {
     ci_t       *ci;
     struct net_device *dev;
@@ -700,7 +700,7 @@ do_create_chan (struct net_device * ndev
 }
 
 STATIC      status_t
-do_get_chan_stats (struct net_device * ndev, void *data)
+do_get_chan_stats (struct net_device *ndev, void *data)
 {
     struct c4_chan_stats_wrap ccs;
     int         ret;
@@ -721,7 +721,7 @@ do_get_chan_stats (struct net_device * n
     return 0;
 }
 STATIC      status_t
-do_set_loglevel (struct net_device * ndev, void *data)
+do_set_loglevel (struct net_device *ndev, void *data)
 {
     unsigned int cxt1e1_log_level;
 
@@ -732,7 +732,7 @@ do_set_loglevel (struct net_device * nde
 }
 
 STATIC      status_t
-do_deluser (struct net_device * ndev, int lockit)
+do_deluser (struct net_device *ndev, int lockit)
 {
     if (ndev->flags & IFF_UP)
         return -EBUSY;
@@ -763,7 +763,7 @@ do_deluser (struct net_device * ndev, in
 }
 
 int
-do_del_chan (struct net_device * musycc_dev, void *data)
+do_del_chan (struct net_device *musycc_dev, void *data)
 {
     struct sbecom_chan_param cp;
     char        buf[sizeof (CHANNAME) + 3];
@@ -787,7 +787,7 @@ do_del_chan (struct net_device * musycc_
 int         c4_reset_board (void *);
 
 int
-do_reset (struct net_device * musycc_dev, void *data)
+do_reset (struct net_device *musycc_dev, void *data)
 {
     const struct c4_priv *priv;
     int         i;
@@ -816,7 +816,7 @@ do_reset (struct net_device * musycc_dev
 }
 
 int
-do_reset_chan_stats (struct net_device * musycc_dev, void *data)
+do_reset_chan_stats (struct net_device *musycc_dev, void *data)
 {
     struct sbecom_chan_param cp;
 
@@ -827,7 +827,7 @@ do_reset_chan_stats (struct net_device *
 }
 
 STATIC      status_t
-c4_ioctl (struct net_device * ndev, struct ifreq * ifr, int cmd)
+c4_ioctl (struct net_device *ndev, struct ifreq *ifr, int cmd)
 {
     ci_t       *ci;
     void       *data;
@@ -954,7 +954,7 @@ static void c4_setup(struct net_device *
 }
 
 struct net_device *__init
-c4_add_dev (hdw_info_t * hi, int brdno, unsigned long f0, unsigned long f1,
+c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
             int irq0, int irq1)
 {
     struct net_device *ndev;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/musycc.c linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/musycc.c
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/musycc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/musycc.c	2013-08-25 20:43:22.000000000 -0400
@@ -74,7 +74,7 @@ void        musycc_update_timeslots(mpi_
 
 #if 1
 STATIC int
-musycc_dump_rxbuffer_ring(mch_t * ch, int lockit)
+musycc_dump_rxbuffer_ring(mch_t *ch, int lockit)
 {
     struct mdesc *m;
     unsigned long flags = 0;
@@ -140,7 +140,7 @@ musycc_dump_rxbuffer_ring(mch_t * ch, in
 
 #if 1
 STATIC int
-musycc_dump_txbuffer_ring(mch_t * ch, int lockit)
+musycc_dump_txbuffer_ring(mch_t *ch, int lockit)
 {
     struct mdesc *m;
     unsigned long flags = 0;
@@ -205,7 +205,7 @@ musycc_dump_txbuffer_ring(mch_t * ch, in
  */
 
 status_t
-musycc_dump_ring(ci_t * ci, unsigned int chan)
+musycc_dump_ring(ci_t *ci, unsigned int chan)
 {
     mch_t      *ch;
 
@@ -248,7 +248,7 @@ musycc_dump_ring(ci_t * ci, unsigned int
 
 
 status_t
-musycc_dump_rings(ci_t * ci, unsigned int start_chan)
+musycc_dump_rings(ci_t *ci, unsigned int start_chan)
 {
     unsigned int chan;
 
@@ -264,7 +264,7 @@ musycc_dump_rings(ci_t * ci, unsigned in
  */
 
 void
-musycc_init_mdt(mpi_t * pi)
+musycc_init_mdt(mpi_t *pi)
 {
     u_int32_t  *addr, cfg;
     int         i;
@@ -288,7 +288,7 @@ musycc_init_mdt(mpi_t * pi)
 /* Set TX thp to the next unprocessed md */
 
 void
-musycc_update_tx_thp(mch_t * ch)
+musycc_update_tx_thp(mch_t *ch)
 {
     struct mdesc *md;
     unsigned long flags;
@@ -443,7 +443,7 @@ musycc_wq_chan_restart(void *arg)      /
   */
 
 void
-musycc_chan_restart(mch_t * ch)
+musycc_chan_restart(mch_t *ch)
 {
 #ifdef RLD_RESTART_DEBUG
     pr_info("++ musycc_chan_restart[%d]: txd_irq_srv @ %p = sts %x\n",
@@ -461,7 +461,7 @@ musycc_chan_restart(mch_t * ch)
 
 
 void
-rld_put_led(mpi_t * pi, u_int32_t ledval)
+rld_put_led(mpi_t *pi, u_int32_t ledval)
 {
     static u_int32_t led = 0;
 
@@ -477,7 +477,7 @@ rld_put_led(mpi_t * pi, u_int32_t ledval
 #define MUSYCC_SR_RETRY_CNT  9
 
 void
-musycc_serv_req(mpi_t * pi, u_int32_t req)
+musycc_serv_req(mpi_t *pi, u_int32_t req)
 {
     volatile u_int32_t r;
     int         rcnt;
@@ -578,7 +578,7 @@ rewrite:
 
 #ifdef  SBE_PMCC4_ENABLE
 void
-musycc_update_timeslots(mpi_t * pi)
+musycc_update_timeslots(mpi_t *pi)
 {
     int         i, ch;
     char        e1mode = IS_FRAME_ANY_E1(pi->p.port_mode);
@@ -640,7 +640,7 @@ musycc_update_timeslots(mpi_t * pi)
 
 #ifdef SBE_WAN256T3_ENABLE
 void
-musycc_update_timeslots(mpi_t * pi)
+musycc_update_timeslots(mpi_t *pi)
 {
     mch_t      *ch;
 
@@ -703,7 +703,7 @@ musycc_chan_proto(int proto)
 
 #ifdef SBE_WAN256T3_ENABLE
 STATIC void __init
-musycc_init_port(mpi_t * pi)
+musycc_init_port(mpi_t *pi)
 {
     pci_write_32((u_int32_t *) &pi->reg->gbp, OS_vtophys(pi->regram));
 
@@ -737,7 +737,7 @@ musycc_init_port(mpi_t * pi)
 
 
 status_t    __init
-musycc_init(ci_t * ci)
+musycc_init(ci_t *ci)
 {
     char       *regaddr;        /* temp for address boundary calculations */
     int         i, gchan;
@@ -832,7 +832,7 @@ musycc_init(ci_t * ci)
 
 
 void
-musycc_bh_tx_eom(mpi_t * pi, int gchan)
+musycc_bh_tx_eom(mpi_t *pi, int gchan)
 {
     mch_t      *ch;
     struct mdesc *md;
@@ -1010,7 +1010,7 @@ musycc_bh_tx_eom(mpi_t * pi, int gchan)
 
 
 STATIC void
-musycc_bh_rx_eom(mpi_t * pi, int gchan)
+musycc_bh_rx_eom(mpi_t *pi, int gchan)
 {
     mch_t      *ch;
     void       *m, *m2;
@@ -1229,7 +1229,7 @@ unsigned long
 #else
 void
 #endif
-musycc_intr_bh_tasklet(ci_t * ci)
+musycc_intr_bh_tasklet(ci_t *ci)
 {
     mpi_t      *pi;
     mch_t      *ch;
@@ -1517,7 +1517,7 @@ musycc_intr_bh_tasklet(ci_t * ci)
 
 #if 0
 int         __init
-musycc_new_chan(ci_t * ci, int channum, void *user)
+musycc_new_chan(ci_t *ci, int channum, void *user)
 {
     mch_t      *ch;
 
@@ -1546,7 +1546,7 @@ musycc_new_chan(ci_t * ci, int channum,
 
 #ifdef SBE_PMCC4_ENABLE
 status_t
-musycc_chan_down(ci_t * dummy, int channum)
+musycc_chan_down(ci_t *dummy, int channum)
 {
     mpi_t      *pi;
     mch_t      *ch;
@@ -1597,7 +1597,7 @@ musycc_chan_down(ci_t * dummy, int chann
 
 
 int
-musycc_del_chan(ci_t * ci, int channum)
+musycc_del_chan(ci_t *ci, int channum)
 {
     mch_t      *ch;
 
@@ -1613,7 +1613,7 @@ musycc_del_chan(ci_t * ci, int channum)
 
 
 int
-musycc_del_chan_stats(ci_t * ci, int channum)
+musycc_del_chan_stats(ci_t *ci, int channum)
 {
     mch_t      *ch;
 
@@ -1628,7 +1628,7 @@ musycc_del_chan_stats(ci_t * ci, int cha
 
 
 int
-musycc_start_xmit(ci_t * ci, int channum, void *mem_token)
+musycc_start_xmit(ci_t *ci, int channum, void *mem_token)
 {
     mch_t      *ch;
     struct mdesc *md;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/pmcc4_drv.c linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/pmcc4_drv.c
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/pmcc4_drv.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/pmcc4_drv.c	2013-08-25 20:43:22.000000000 -0400
@@ -28,7 +28,7 @@
 #include <linux/sched.h>        /* include for timer */
 #include <linux/timer.h>        /* include for timer */
 #include <linux/hdlc.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include "sbecom_inline_linux.h"
 #include "libsbew.h"
@@ -123,7 +123,7 @@ c4_find_chan (int channum)
                 {
                     if ((ch->state != UNASSIGNED) &&
                         (ch->channum == channum))
-                        return (ch);
+                        return ch;
                 }
             }
     return 0;
@@ -193,7 +193,7 @@ c4_new (void *hi)
 #define COMET_LBCMD_READ  0x80  /* read only (do not set, return read value) */
 
 void
-checkPorts (ci_t * ci)
+checkPorts (ci_t *ci)
 {
 #ifndef CONFIG_SBE_PMCC4_NCOMM
     /*
@@ -459,7 +459,7 @@ checkPorts (ci_t * ci)
 
 
 STATIC void
-c4_watchdog (ci_t * ci)
+c4_watchdog (ci_t *ci)
 {
     if (drvr_state != SBE_DRVR_AVAILABLE)
     {
@@ -512,7 +512,7 @@ c4_cleanup (void)
  */
 
 int
-c4_get_portcfg (ci_t * ci)
+c4_get_portcfg (ci_t *ci)
 {
     comet_t    *comet;
     int         portnum, mask;
@@ -536,7 +536,7 @@ c4_get_portcfg (ci_t * ci)
 /* nothing herein should generate interrupts */
 
 status_t    __init
-c4_init (ci_t * ci, u_char *func0, u_char *func1)
+c4_init (ci_t *ci, u_char *func0, u_char *func1)
 {
     mpi_t      *pi;
     mch_t      *ch;
@@ -670,7 +670,7 @@ c4_init (ci_t * ci, u_char *func0, u_cha
 /* better be fully setup to handle interrupts when you call this */
 
 status_t    __init
-c4_init2 (ci_t * ci)
+c4_init2 (ci_t *ci)
 {
     status_t    ret;
 
@@ -698,7 +698,7 @@ c4_init2 (ci_t * ci)
 /* This function sets the loopback mode (or clears it, as the case may be). */
 
 int
-c4_loop_port (ci_t * ci, int portnum, u_int8_t cmd)
+c4_loop_port (ci_t *ci, int portnum, u_int8_t cmd)
 {
     comet_t    *comet;
     volatile u_int32_t loopValue;
@@ -757,7 +757,7 @@ c4_loop_port (ci_t * ci, int portnum, u_
  */
 
 status_t
-c4_frame_rw (ci_t * ci, struct sbecom_port_param * pp)
+c4_frame_rw (ci_t *ci, struct sbecom_port_param *pp)
 {
     comet_t    *comet;
     volatile u_int32_t data;
@@ -796,7 +796,7 @@ c4_frame_rw (ci_t * ci, struct sbecom_po
  */
 
 status_t
-c4_pld_rw (ci_t * ci, struct sbecom_port_param * pp)
+c4_pld_rw (ci_t *ci, struct sbecom_port_param *pp)
 {
     volatile u_int32_t *regaddr;
     volatile u_int32_t data;
@@ -834,7 +834,7 @@ c4_pld_rw (ci_t * ci, struct sbecom_port
  */
 
 status_t
-c4_musycc_rw (ci_t * ci, struct c4_musycc_param * mcp)
+c4_musycc_rw (ci_t *ci, struct c4_musycc_param *mcp)
 {
     mpi_t      *pi;
     volatile u_int32_t *dph;    /* hardware implemented register */
@@ -898,7 +898,7 @@ c4_musycc_rw (ci_t * ci, struct c4_musyc
 }
 
 status_t
-c4_get_port (ci_t * ci, int portnum)
+c4_get_port (ci_t *ci, int portnum)
 {
     if (portnum >= ci->max_port)    /* sanity check */
         return ENXIO;
@@ -913,7 +913,7 @@ c4_get_port (ci_t * ci, int portnum)
 }
 
 status_t
-c4_set_port (ci_t * ci, int portnum)
+c4_set_port (ci_t *ci, int portnum)
 {
     mpi_t      *pi;
     struct sbecom_port_param *pp;
@@ -942,7 +942,7 @@ c4_set_port (ci_t * ci, int portnum)
 
         if ((ret = c4_wq_port_init (pi)))       /* create/init
                                                  * workqueue_struct */
-            return (ret);
+            return ret;
     }
 
     init_comet (ci, pi->cometbase, pp->port_mode, 1 /* clockmaster == true */ , pp->portP);
@@ -1018,7 +1018,7 @@ c4_set_port (ci_t * ci, int portnum)
 unsigned int max_int = 0;
 
 status_t
-c4_new_chan (ci_t * ci, int portnum, int channum, void *user)
+c4_new_chan (ci_t *ci, int portnum, int channum, void *user)
 {
     mpi_t      *pi;
     mch_t      *ch;
@@ -1111,7 +1111,7 @@ c4_del_chan_stats (int channum)
 
 
 status_t
-c4_set_chan (int channum, struct sbecom_chan_param * p)
+c4_set_chan (int channum, struct sbecom_chan_param *p)
 {
     mch_t      *ch;
     int         i, x = 0;
@@ -1162,7 +1162,7 @@ c4_set_chan (int channum, struct sbecom_
 
 
 status_t
-c4_get_chan (int channum, struct sbecom_chan_param * p)
+c4_get_chan (int channum, struct sbecom_chan_param *p)
 {
     mch_t      *ch;
 
@@ -1173,7 +1173,7 @@ c4_get_chan (int channum, struct sbecom_
 }
 
 status_t
-c4_get_chan_stats (int channum, struct sbecom_chan_stats * p)
+c4_get_chan_stats (int channum, struct sbecom_chan_stats *p)
 {
     mch_t      *ch;
 
@@ -1185,7 +1185,7 @@ c4_get_chan_stats (int channum, struct s
 }
 
 STATIC int
-c4_fifo_alloc (mpi_t * pi, int chan, int *len)
+c4_fifo_alloc (mpi_t *pi, int chan, int *len)
 {
     int         i, l = 0, start = 0, max = 0, maxstart = 0;
 
@@ -1222,7 +1222,7 @@ c4_fifo_alloc (mpi_t * pi, int chan, int
 }
 
 void
-c4_fifo_free (mpi_t * pi, int chan)
+c4_fifo_free (mpi_t *pi, int chan)
 {
     int         i;
 
@@ -1236,7 +1236,7 @@ c4_fifo_free (mpi_t * pi, int chan)
 
 
 status_t
-c4_chan_up (ci_t * ci, int channum)
+c4_chan_up (ci_t *ci, int channum)
 {
     mpi_t      *pi;
     mch_t      *ch;
@@ -1467,7 +1467,7 @@ errfree:
 /* stop the hardware from servicing & interrupting */
 
 void
-c4_stopwd (ci_t * ci)
+c4_stopwd (ci_t *ci)
 {
     OS_stop_watchdog (&ci->wd);
     SD_SEM_TAKE (&ci->sem_wdbusy, "_stop_");    /* ensure WD not running */
@@ -1476,7 +1476,7 @@ c4_stopwd (ci_t * ci)
 
 
 void
-sbecom_get_brdinfo (ci_t * ci, struct sbe_brd_info * bip, u_int8_t *bsn)
+sbecom_get_brdinfo (ci_t *ci, struct sbe_brd_info *bip, u_int8_t *bsn)
 {
     char       *np;
     u_int32_t   sn = 0;
@@ -1485,7 +1485,7 @@ sbecom_get_brdinfo (ci_t * ci, struct sb
     bip->brdno = ci->brdno;         /* our board number */
     bip->brd_id = ci->brd_id;
     bip->brd_hdw_id = ci->hdw_bid;
-    bip->brd_chan_cnt = MUSYCC_NCHANS * ci->max_port;   /* number of channels
+    bip->brd_chan_cnt = MUSYCC_NCHANS *ci->max_port;   /* number of channels
                                                          * being used */
     bip->brd_port_cnt = ci->max_port;   /* number of ports being used */
     bip->brd_pci_speed = BINFO_PCI_SPEED_unk;   /* PCI speed not yet
@@ -1535,7 +1535,7 @@ sbecom_get_brdinfo (ci_t * ci, struct sb
 
 
 status_t
-c4_get_iidinfo (ci_t * ci, struct sbe_iid_info * iip)
+c4_get_iidinfo (ci_t *ci, struct sbe_iid_info *iip)
 {
     struct net_device *dev;
     char       *np;
@@ -1624,7 +1624,7 @@ wanpmcC4T1E1_getBaseAddress (int cardID,
         }
         ci = ci->next;              /* next board, if any */
     }
-    return (base);
+    return base;
 }
 
 #endif                          /*** CONFIG_SBE_PMCC4_NCOMM ***/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/pmcc4.h linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/pmcc4.h
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/pmcc4.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/pmcc4.h	2013-08-25 20:43:22.000000000 -0400
@@ -85,15 +85,15 @@ void        c4_cleanup (void);
 status_t    c4_chan_up (ci_t *, int channum);
 status_t    c4_del_chan_stats (int channum);
 status_t    c4_del_chan (int channum);
-status_t    c4_get_iidinfo (ci_t * ci, struct sbe_iid_info * iip);
+status_t    c4_get_iidinfo (ci_t *ci, struct sbe_iid_info *iip);
 int         c4_is_chan_up (int channum);
 
 void       *getuserbychan (int channum);
-void        pci_flush_write (ci_t * ci);
+void        pci_flush_write (ci_t *ci);
 void        sbecom_set_loglevel (int debuglevel);
-char       *sbeid_get_bdname (ci_t * ci);
-void        sbeid_set_bdtype (ci_t * ci);
-void        sbeid_set_hdwbid (ci_t * ci);
+char       *sbeid_get_bdname (ci_t *ci);
+void        sbeid_set_bdtype (ci_t *ci);
+void        sbeid_set_hdwbid (ci_t *ci);
 u_int32_t   sbeCrc (u_int8_t *, u_int32_t, u_int32_t, u_int32_t *);
 
 void        VMETRO_TRACE (void *);       /* put data into 8 LEDs */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/sbecom_inline_linux.h linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/sbecom_inline_linux.h
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/sbecom_inline_linux.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/sbecom_inline_linux.h	2013-08-25 20:43:22.000000000 -0400
@@ -177,7 +177,7 @@ struct watchdog
 
 
 static inline int
-OS_start_watchdog (struct watchdog * wd)
+OS_start_watchdog (struct watchdog *wd)
 {
     wd->h.expires = jiffies + wd->ticks;
     add_timer (&wd->h);
@@ -186,7 +186,7 @@ OS_start_watchdog (struct watchdog * wd)
 
 
 static inline int
-OS_stop_watchdog (struct watchdog * wd)
+OS_stop_watchdog (struct watchdog *wd)
 {
     del_timer_sync (&wd->h);
     return 0;
@@ -194,7 +194,7 @@ OS_stop_watchdog (struct watchdog * wd)
 
 
 static inline int
-OS_free_watchdog (struct watchdog * wd)
+OS_free_watchdog (struct watchdog *wd)
 {
     OS_stop_watchdog (wd);
     OS_kfree (wd);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/sbeid.c linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/sbeid.c
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/sbeid.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/sbeid.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,7 +27,7 @@
 
 
 char       *
-sbeid_get_bdname (ci_t * ci)
+sbeid_get_bdname (ci_t *ci)
 {
     char       *np = 0;
 
@@ -73,7 +73,7 @@ sbeid_get_bdname (ci_t * ci)
 /* given the presetting of brd_id, set the corresponding hdw_id */
 
 void
-sbeid_set_hdwbid (ci_t * ci)
+sbeid_set_hdwbid (ci_t *ci)
 {
     /*
      * set SBE's unique hardware identification (for legacy boards might not
@@ -170,7 +170,7 @@ sbeid_set_hdwbid (ci_t * ci)
 /* given the presetting of hdw_bid, set the corresponding brd_id */
 
 void
-sbeid_set_bdtype (ci_t * ci)
+sbeid_set_bdtype (ci_t *ci)
 {
     /* set SBE's unique PCI VENDOR/DEVID */
     switch (ci->hdw_bid)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/cxt1e1/sbeproc.h linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/sbeproc.h
--- linux-libre-3.10-gnu/drivers/staging/cxt1e1/sbeproc.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/cxt1e1/sbeproc.h	2013-08-25 20:43:22.000000000 -0400
@@ -28,11 +28,11 @@ int __init  sbecom_proc_brd_init (ci_t *
 
 #else
 
-static inline void sbecom_proc_brd_cleanup(ci_t * ci)
+static inline void sbecom_proc_brd_cleanup(ci_t *ci)
 {
 }
 
-static inline int __init sbecom_proc_brd_init(ci_t * ci)
+static inline int __init sbecom_proc_brd_init(ci_t *ci)
 {
 	return 0;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dgrp/dgrp_dpa_ops.c linux-libre-3.11-rc7-gnu/drivers/staging/dgrp/dgrp_dpa_ops.c
--- linux-libre-3.10-gnu/drivers/staging/dgrp/dgrp_dpa_ops.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dgrp/dgrp_dpa_ops.c	2013-08-25 20:43:22.000000000 -0400
@@ -392,7 +392,7 @@ static long dgrp_dpa_ioctl(struct file *
 		getnode.nd_rx_byte = nd->nd_rx_byte;
 
 		memset(&getnode.nd_ps_desc, 0, MAX_DESC_LEN);
-		strncpy(getnode.nd_ps_desc, nd->nd_ps_desc, MAX_DESC_LEN);
+		strlcpy(getnode.nd_ps_desc, nd->nd_ps_desc, MAX_DESC_LEN);
 
 		if (copy_to_user(uarg, &getnode, sizeof(struct digi_node)))
 			return -EFAULT;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dgrp/dgrp_net_ops.c linux-libre-3.11-rc7-gnu/drivers/staging/dgrp/dgrp_net_ops.c
--- linux-libre-3.10-gnu/drivers/staging/dgrp/dgrp_net_ops.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dgrp/dgrp_net_ops.c	2013-08-25 20:43:22.000000000 -0400
@@ -278,7 +278,7 @@ static void parity_scan(struct ch_struct
 		switch (ch->ch_pscan_state) {
 		default:
 			/* reset to sanity and fall through */
-			ch->ch_pscan_state = 0 ;
+			ch->ch_pscan_state = 0;
 
 		case 0:
 			/* No FF seen yet */
@@ -1607,7 +1607,7 @@ static int dgrp_send(struct nd_struct *n
 					if ((ch->ch_pun.un_flag & UN_LOW) != 0 ?
 					    (n <= TBUF_LOW) :
 					    (ch->ch_pun.un_flag & UN_TIME) != 0 ?
-					    ((jiffies - ch->ch_waketime) >= 0) :
+					    time_is_before_jiffies(ch->ch_waketime) :
 					    (n == 0 && ch->ch_s_tpos == ch->ch_s_tin) &&
 					    ((ch->ch_pun.un_flag & UN_EMPTY) != 0 ||
 					    ((ch->ch_tun.un_open_count &&
@@ -3083,7 +3083,7 @@ check_query:
 						nd->nd_hw_ver = (b[8] << 8) | b[9];
 						nd->nd_sw_ver = (b[10] << 8) | b[11];
 						nd->nd_hw_id = b[6];
-						desclen = ((plen - 12) > MAX_DESC_LEN) ? MAX_DESC_LEN :
+						desclen = (plen - 12 > MAX_DESC_LEN - 1) ? MAX_DESC_LEN - 1 :
 							plen - 12;
 
 						if (desclen <= 0) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dgrp/dgrp_sysfs.c linux-libre-3.11-rc7-gnu/drivers/staging/dgrp/dgrp_sysfs.c
--- linux-libre-3.10-gnu/drivers/staging/dgrp/dgrp_sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dgrp/dgrp_sysfs.c	2013-08-25 20:43:22.000000000 -0400
@@ -273,7 +273,7 @@ void dgrp_create_node_class_sysfs_files(
 		sprintf(name, "node%ld", nd->nd_major);
 
 	nd->nd_class_dev = device_create(dgrp_class, dgrp_class_nodes_dev,
-		MKDEV(0, nd->nd_major), NULL, name);
+		MKDEV(0, nd->nd_major), NULL, "%s", name);
 
 	ret = sysfs_create_group(&nd->nd_class_dev->kobj,
 				 &dgrp_node_attribute_group);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dgrp/drp.h linux-libre-3.11-rc7-gnu/drivers/staging/dgrp/drp.h
--- linux-libre-3.10-gnu/drivers/staging/dgrp/drp.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dgrp/drp.h	2013-08-25 20:43:22.000000000 -0400
@@ -674,7 +674,7 @@ struct nd_struct {
 	ushort	     nd_hw_ver;		  /* HW version returned from PS   */
 	ushort	     nd_sw_ver;		  /* SW version returned from PS   */
 	uint	     nd_hw_id;		  /* HW ID returned from PS	   */
-	u8	  nd_ps_desc[MAX_DESC_LEN+1];  /* Description from PS	*/
+	u8	  nd_ps_desc[MAX_DESC_LEN];  /* Description from PS	*/
 	uint	     nd_vpd_len;		/* VPD len, if any */
 	u8	     nd_vpd[VPDSIZE];		/* VPD, if any */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dwc2/core.c linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/core.c
--- linux-libre-3.10-gnu/drivers/staging/dwc2/core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/core.c	2013-08-25 20:43:22.000000000 -0400
@@ -506,8 +506,7 @@ static void dwc2_config_fifos(struct dwc
 	struct dwc2_core_params *params = hsotg->core_params;
 	u32 rxfsiz, nptxfsiz, ptxfsiz, hptxfsiz, dfifocfg;
 
-	if (!(hsotg->hwcfg2 & GHWCFG2_DYNAMIC_FIFO) ||
-	    !params->enable_dynamic_fifo)
+	if (!params->enable_dynamic_fifo)
 		return;
 
 	dev_dbg(hsotg->dev, "Total FIFO Size=%d\n", hsotg->total_fifo_size);
@@ -1146,16 +1145,10 @@ void dwc2_hc_cleanup(struct dwc2_hsotg *
 static void dwc2_hc_set_even_odd_frame(struct dwc2_hsotg *hsotg,
 				       struct dwc2_host_chan *chan, u32 *hcchar)
 {
-	u32 hfnum, frnum;
-
 	if (chan->ep_type == USB_ENDPOINT_XFER_INT ||
 	    chan->ep_type == USB_ENDPOINT_XFER_ISOC) {
-		hfnum = readl(hsotg->regs + HFNUM);
-		frnum = hfnum >> HFNUM_FRNUM_SHIFT &
-			HFNUM_FRNUM_MASK >> HFNUM_FRNUM_SHIFT;
-
 		/* 1 if _next_ frame is odd, 0 if it's even */
-		if (frnum & 0x1)
+		if (!(dwc2_hcd_get_frame_number(hsotg) & 0x1))
 			*hcchar |= HCCHAR_ODDFRM;
 	}
 }
@@ -1696,7 +1689,7 @@ u32 dwc2_calc_frame_interval(struct dwc2
 	    GHWCFG2_FS_PHY_TYPE_DEDICATED)
 		clock = 48;
 
-	if ((hprt0 & HPRT0_SPD_MASK) == 0)
+	if ((hprt0 & HPRT0_SPD_MASK) == HPRT0_SPD_HIGH_SPEED)
 		/* High speed case */
 		return 125 * clock;
 	else
@@ -1815,8 +1808,6 @@ void dwc2_dump_global_registers(struct d
 {
 #ifdef DEBUG
 	u32 __iomem *addr;
-	int i, ep_num;
-	char *txfsiz;
 
 	dev_dbg(hsotg->dev, "Core Global Registers\n");
 	addr = hsotg->regs + GOTGCTL;
@@ -1892,23 +1883,6 @@ void dwc2_dump_global_registers(struct d
 	dev_dbg(hsotg->dev, "HPTXFSIZ	 @0x%08lX : 0x%08X\n",
 		(unsigned long)addr, readl(addr));
 
-	if (hsotg->core_params->en_multiple_tx_fifo <= 0) {
-		ep_num = hsotg->hwcfg4 >> GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT &
-			 GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK >>
-					 GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
-		txfsiz = "DPTXFSIZ";
-	} else {
-		ep_num = hsotg->hwcfg4 >> GHWCFG4_NUM_IN_EPS_SHIFT &
-			 GHWCFG4_NUM_IN_EPS_MASK >> GHWCFG4_NUM_IN_EPS_SHIFT;
-		txfsiz = "DIENPTXF";
-	}
-
-	for (i = 0; i < ep_num; i++) {
-		addr = hsotg->regs + DPTXFSIZN(i + 1);
-		dev_dbg(hsotg->dev, "%s[%d] @0x%08lX : 0x%08X\n", txfsiz, i + 1,
-			(unsigned long)addr, readl(addr));
-	}
-
 	addr = hsotg->regs + PCGCTL;
 	dev_dbg(hsotg->dev, "PCGCTL	 @0x%08lX : 0x%08X\n",
 		(unsigned long)addr, readl(addr));
@@ -2298,7 +2272,7 @@ int dwc2_set_param_phy_type(struct dwc2_
 #ifndef NO_FS_PHY_HW_CHECKS
 		valid = 0;
 #else
-		val = 0;
+		val = DWC2_PHY_TYPE_PARAM_FS;
 		dev_dbg(hsotg->dev, "Setting phy_type to %d\n", val);
 		retval = -EINVAL;
 #endif
@@ -2325,7 +2299,7 @@ int dwc2_set_param_phy_type(struct dwc2_
 			dev_err(hsotg->dev,
 				"%d invalid for phy_type. Check HW configuration.\n",
 				val);
-		val = 0;
+		val = DWC2_PHY_TYPE_PARAM_FS;
 		if (hs_phy_type != GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED) {
 			if (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI ||
 			    hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI)
@@ -2360,8 +2334,8 @@ int dwc2_set_param_speed(struct dwc2_hso
 		valid = 0;
 	}
 
-	if (val == 0 && dwc2_get_param_phy_type(hsotg) ==
-					DWC2_PHY_TYPE_PARAM_FS)
+	if (val == DWC2_SPEED_PARAM_HIGH &&
+	    dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS)
 		valid = 0;
 
 	if (!valid) {
@@ -2370,7 +2344,7 @@ int dwc2_set_param_speed(struct dwc2_hso
 				"%d invalid for speed parameter. Check HW configuration.\n",
 				val);
 		val = dwc2_get_param_phy_type(hsotg) == DWC2_PHY_TYPE_PARAM_FS ?
-				1 : 0;
+				DWC2_SPEED_PARAM_FULL : DWC2_SPEED_PARAM_HIGH;
 		dev_dbg(hsotg->dev, "Setting speed to %d\n", val);
 		retval = -EINVAL;
 	}
@@ -2668,7 +2642,7 @@ int dwc2_set_param_otg_ver(struct dwc2_h
  * for the DWC_otg core. It returns non-0 if any parameters are invalid.
  */
 int dwc2_set_parameters(struct dwc2_hsotg *hsotg,
-			struct dwc2_core_params *params)
+			const struct dwc2_core_params *params)
 {
 	int retval = 0;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dwc2/core_intr.c linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/core_intr.c
--- linux-libre-3.10-gnu/drivers/staging/dwc2/core_intr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/core_intr.c	2013-08-25 20:43:22.000000000 -0400
@@ -403,8 +403,7 @@ static void dwc2_handle_usb_suspend_intr
 #define GINTMSK_COMMON	(GINTSTS_WKUPINT | GINTSTS_SESSREQINT |		\
 			 GINTSTS_CONIDSTSCHNG | GINTSTS_OTGINT |	\
 			 GINTSTS_MODEMIS | GINTSTS_DISCONNINT |		\
-			 GINTSTS_USBSUSP | GINTSTS_RESTOREDONE |	\
-			 GINTSTS_PRTINT)
+			 GINTSTS_USBSUSP | GINTSTS_PRTINT)
 
 /*
  * This function returns the Core Interrupt register
@@ -450,7 +449,7 @@ irqreturn_t dwc2_handle_common_intr(int
 {
 	struct dwc2_hsotg *hsotg = dev;
 	u32 gintsts;
-	int retval = 0;
+	irqreturn_t retval = IRQ_NONE;
 
 	if (dwc2_check_core_status(hsotg) < 0) {
 		dev_warn(hsotg->dev, "Controller is disconnected\n");
@@ -461,7 +460,7 @@ irqreturn_t dwc2_handle_common_intr(int
 
 	gintsts = dwc2_read_common_intr(hsotg);
 	if (gintsts & ~GINTSTS_PRTINT)
-		retval = 1;
+		retval = IRQ_HANDLED;
 
 	if (gintsts & GINTSTS_MODEMIS)
 		dwc2_handle_mode_mismatch_intr(hsotg);
@@ -478,12 +477,6 @@ irqreturn_t dwc2_handle_common_intr(int
 	if (gintsts & GINTSTS_USBSUSP)
 		dwc2_handle_usb_suspend_intr(hsotg);
 
-	if (gintsts & GINTSTS_RESTOREDONE) {
-		gintsts = GINTSTS_RESTOREDONE;
-		writel(gintsts, hsotg->regs + GINTSTS);
-		dev_dbg(hsotg->dev, " --Restore done interrupt received--\n");
-	}
-
 	if (gintsts & GINTSTS_PRTINT) {
 		/*
 		 * The port interrupt occurs while in device mode with HPRT0
@@ -500,6 +493,6 @@ irqreturn_t dwc2_handle_common_intr(int
 
 	spin_unlock(&hsotg->lock);
 out:
-	return IRQ_RETVAL(retval);
+	return retval;
 }
 EXPORT_SYMBOL_GPL(dwc2_handle_common_intr);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dwc2/hcd.c linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/hcd.c
--- linux-libre-3.10-gnu/drivers/staging/dwc2/hcd.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/hcd.c	2013-08-25 20:43:22.000000000 -0400
@@ -1563,9 +1563,9 @@ static int dwc2_hcd_hub_control(struct d
 		break;
 
 	case GetPortStatus:
-		dev_dbg(hsotg->dev,
-			"GetPortStatus wIndex=0x%04x flags=0x%08x\n", windex,
-			hsotg->flags.d32);
+		dev_vdbg(hsotg->dev,
+			 "GetPortStatus wIndex=0x%04x flags=0x%08x\n", windex,
+			 hsotg->flags.d32);
 		if (!windex || windex > 1)
 			goto error;
 
@@ -1598,7 +1598,7 @@ static int dwc2_hcd_hub_control(struct d
 		}
 
 		hprt0 = readl(hsotg->regs + HPRT0);
-		dev_dbg(hsotg->dev, "  HPRT0: 0x%08x\n", hprt0);
+		dev_vdbg(hsotg->dev, "  HPRT0: 0x%08x\n", hprt0);
 
 		if (hprt0 & HPRT0_CONNSTS)
 			port_status |= USB_PORT_STAT_CONNECTION;
@@ -1623,7 +1623,7 @@ static int dwc2_hcd_hub_control(struct d
 			port_status |= USB_PORT_STAT_TEST;
 		/* USB_PORT_FEAT_INDICATOR unsupported always 0 */
 
-		dev_dbg(hsotg->dev, "port_status=%08x\n", port_status);
+		dev_vdbg(hsotg->dev, "port_status=%08x\n", port_status);
 		*(__le32 *)buf = cpu_to_le32(port_status);
 		break;
 
@@ -2533,9 +2533,8 @@ static void _dwc2_hcd_endpoint_reset(str
 static irqreturn_t _dwc2_hcd_irq(struct usb_hcd *hcd)
 {
 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
-	int retval = dwc2_hcd_intr(hsotg);
 
-	return IRQ_RETVAL(retval);
+	return dwc2_handle_hcd_intr(hsotg);
 }
 
 /*
@@ -2702,7 +2701,7 @@ EXPORT_SYMBOL_GPL(dwc2_set_all_params);
  * a negative error on failure.
  */
 int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
-		  struct dwc2_core_params *params)
+		  const struct dwc2_core_params *params)
 {
 	struct usb_hcd *hcd;
 	struct dwc2_host_chan *channel;
@@ -2919,7 +2918,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hso
 	 * allocates the DMA buffer pool, registers the USB bus, requests the
 	 * IRQ line, and calls hcd_start method.
 	 */
-	retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);
+	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (retval < 0)
 		goto error3;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dwc2/hcd.h linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/hcd.h
--- linux-libre-3.10-gnu/drivers/staging/dwc2/hcd.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/hcd.h	2013-08-25 20:43:22.000000000 -0400
@@ -448,10 +448,10 @@ static inline u8 dwc2_hcd_is_pipe_out(st
 }
 
 extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
-			 struct dwc2_core_params *params);
+			 const struct dwc2_core_params *params);
 extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg);
 extern int dwc2_set_parameters(struct dwc2_hsotg *hsotg,
-			       struct dwc2_core_params *params);
+			       const struct dwc2_core_params *params);
 extern void dwc2_set_all_params(struct dwc2_core_params *params, int value);
 
 /* Transaction Execution Functions */
@@ -646,14 +646,14 @@ extern void dwc2_hcd_save_data_toggle(st
 /* HCD Core API */
 
 /**
- * dwc2_hcd_intr() - Called on every hardware interrupt
+ * dwc2_handle_hcd_intr() - Called on every hardware interrupt
  *
  * @hsotg: The DWC2 HCD
  *
- * Returns non zero if interrupt is handled
- * Return 0 if interrupt is not handled
+ * Returns IRQ_HANDLED if interrupt is handled
+ * Return IRQ_NONE if interrupt is not handled
  */
-extern int dwc2_hcd_intr(struct dwc2_hsotg *hsotg);
+extern irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg);
 
 /**
  * dwc2_hcd_stop() - Halts the DWC_otg host mode operation
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dwc2/hcd_intr.c linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/hcd_intr.c
--- linux-libre-3.10-gnu/drivers/staging/dwc2/hcd_intr.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/hcd_intr.c	2013-08-25 20:43:22.000000000 -0400
@@ -115,16 +115,13 @@ static void dwc2_sof_intr(struct dwc2_hs
 {
 	struct list_head *qh_entry;
 	struct dwc2_qh *qh;
-	u32 hfnum;
 	enum dwc2_transaction_type tr_type;
 
 #ifdef DEBUG_SOF
 	dev_vdbg(hsotg->dev, "--Start of Frame Interrupt--\n");
 #endif
 
-	hfnum = readl(hsotg->regs + HFNUM);
-	hsotg->frame_number = hfnum >> HFNUM_FRNUM_SHIFT &
-			    HFNUM_FRNUM_MASK >> HFNUM_FRNUM_SHIFT;
+	hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg);
 
 	dwc2_track_missed_sofs(hsotg);
 
@@ -244,6 +241,7 @@ static void dwc2_hprt0_enable(struct dwc
 	u32 usbcfg;
 	u32 prtspd;
 	u32 hcfg;
+	u32 fslspclksel;
 	u32 hfir;
 
 	dev_vdbg(hsotg->dev, "%s(%p)\n", __func__, hsotg);
@@ -275,6 +273,7 @@ static void dwc2_hprt0_enable(struct dwc
 		}
 
 		hcfg = readl(hsotg->regs + HCFG);
+		fslspclksel = hcfg & HCFG_FSLSPCLKSEL_MASK;
 
 		if (prtspd == HPRT0_SPD_LOW_SPEED &&
 		    params->host_ls_low_power_phy_clk ==
@@ -282,8 +281,7 @@ static void dwc2_hprt0_enable(struct dwc
 			/* 6 MHZ */
 			dev_vdbg(hsotg->dev,
 				 "FS_PHY programming HCFG to 6 MHz\n");
-			if ((hcfg & HCFG_FSLSPCLKSEL_MASK) !=
-			    HCFG_FSLSPCLKSEL_6_MHZ) {
+			if (fslspclksel != HCFG_FSLSPCLKSEL_6_MHZ) {
 				hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 				hcfg |= HCFG_FSLSPCLKSEL_6_MHZ;
 				writel(hcfg, hsotg->regs + HCFG);
@@ -293,8 +291,7 @@ static void dwc2_hprt0_enable(struct dwc
 			/* 48 MHZ */
 			dev_vdbg(hsotg->dev,
 				 "FS_PHY programming HCFG to 48 MHz\n");
-			if ((hcfg & HCFG_FSLSPCLKSEL_MASK) !=
-			    HCFG_FSLSPCLKSEL_48_MHZ) {
+			if (fslspclksel != HCFG_FSLSPCLKSEL_48_MHZ) {
 				hcfg &= ~HCFG_FSLSPCLKSEL_MASK;
 				hcfg |= HCFG_FSLSPCLKSEL_48_MHZ;
 				writel(hcfg, hsotg->regs + HCFG);
@@ -2060,14 +2057,14 @@ static void dwc2_hc_intr(struct dwc2_hso
 }
 
 /* This function handles interrupts for the HCD */
-int dwc2_hcd_intr(struct dwc2_hsotg *hsotg)
+irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg)
 {
 	u32 gintsts, dbg_gintsts;
-	int retval = 0;
+	irqreturn_t retval = IRQ_NONE;
 
 	if (dwc2_check_core_status(hsotg) < 0) {
 		dev_warn(hsotg->dev, "Controller is disconnected\n");
-		return 0;
+		return retval;
 	}
 
 	spin_lock(&hsotg->lock);
@@ -2077,10 +2074,10 @@ int dwc2_hcd_intr(struct dwc2_hsotg *hso
 		gintsts = dwc2_read_core_intr(hsotg);
 		if (!gintsts) {
 			spin_unlock(&hsotg->lock);
-			return 0;
+			return retval;
 		}
 
-		retval = 1;
+		retval = IRQ_HANDLED;
 
 		dbg_gintsts = gintsts;
 #ifndef DEBUG_SOF
@@ -2102,9 +2099,6 @@ int dwc2_hcd_intr(struct dwc2_hsotg *hso
 			dwc2_rx_fifo_level_intr(hsotg);
 		if (gintsts & GINTSTS_NPTXFEMP)
 			dwc2_np_tx_fifo_empty_intr(hsotg);
-		if (gintsts & GINTSTS_I2CINT)
-			/* Todo: Implement i2cintr handler */
-			writel(GINTSTS_I2CINT, hsotg->regs + GINTSTS);
 		if (gintsts & GINTSTS_PRTINT)
 			dwc2_port_intr(hsotg);
 		if (gintsts & GINTSTS_HCHINT)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/dwc2/pci.c linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/pci.c
--- linux-libre-3.10-gnu/drivers/staging/dwc2/pci.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/dwc2/pci.c	2013-08-25 20:43:22.000000000 -0400
@@ -59,7 +59,7 @@
 
 static const char dwc2_driver_name[] = "dwc2";
 
-static struct dwc2_core_params dwc2_module_params = {
+static const struct dwc2_core_params dwc2_module_params = {
 	.otg_cap			= -1,
 	.otg_ver			= -1,
 	.dma_enable			= -1,
@@ -101,8 +101,6 @@ static void dwc2_driver_remove(struct pc
 {
 	struct dwc2_hsotg *hsotg = pci_get_drvdata(dev);
 
-	dev_dbg(&dev->dev, "%s(%p)\n", __func__, dev);
-
 	dwc2_hcd_remove(hsotg);
 	pci_disable_device(dev);
 }
@@ -125,18 +123,14 @@ static int dwc2_driver_probe(struct pci_
 	struct dwc2_hsotg *hsotg;
 	int retval;
 
-	dev_dbg(&dev->dev, "%s(%p)\n", __func__, dev);
-
 	hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL);
 	if (!hsotg)
 		return -ENOMEM;
 
-	pci_set_power_state(dev, PCI_D0);
-
 	hsotg->dev = &dev->dev;
-	hsotg->regs = devm_request_and_ioremap(&dev->dev, &dev->resource[0]);
-	if (!hsotg->regs)
-		return -ENOMEM;
+	hsotg->regs = devm_ioremap_resource(&dev->dev, &dev->resource[0]);
+	if (IS_ERR(hsotg->regs))
+		return PTR_ERR(hsotg->regs);
 
 	dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
 		(unsigned long)pci_resource_start(dev, 0), hsotg->regs);
@@ -153,7 +147,6 @@ static int dwc2_driver_probe(struct pci_
 	}
 
 	pci_set_drvdata(dev, hsotg);
-	dev_dbg(&dev->dev, "hsotg=%p\n", hsotg);
 
 	return retval;
 }
@@ -162,6 +155,10 @@ static DEFINE_PCI_DEVICE_TABLE(dwc2_pci_
 	{
 		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_PRODUCT_ID_HAPS_HSOTG),
 	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_STMICRO,
+			   PCI_DEVICE_ID_STMICRO_USB_OTG),
+	},
 	{ /* end: all zeroes */ }
 };
 MODULE_DEVICE_TABLE(pci, dwc2_pci_ids);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/echo/echo.c linux-libre-3.11-rc7-gnu/drivers/staging/echo/echo.c
--- linux-libre-3.10-gnu/drivers/staging/echo/echo.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/echo/echo.c	2013-08-25 20:43:22.000000000 -0400
@@ -267,13 +267,13 @@ struct oslec_state *oslec_create(int len
 		goto error_snap;
 
 	ec->cond_met = 0;
-	ec->Pstates = 0;
-	ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
-	ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
+	ec->pstates = 0;
+	ec->ltxacc = ec->lrxacc = ec->lcleanacc = ec->lclean_bgacc = 0;
+	ec->ltx = ec->lrx = ec->lclean = ec->lclean_bg = 0;
 	ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
-	ec->Lbgn = ec->Lbgn_acc = 0;
-	ec->Lbgn_upper = 200;
-	ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
+	ec->lbgn = ec->lbgn_acc = 0;
+	ec->lbgn_upper = 200;
+	ec->lbgn_upper_acc = ec->lbgn_upper << 13;
 
 	return ec;
 
@@ -314,13 +314,13 @@ void oslec_flush(struct oslec_state *ec)
 {
 	int i;
 
-	ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
-	ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
+	ec->ltxacc = ec->lrxacc = ec->lcleanacc = ec->lclean_bgacc = 0;
+	ec->ltx = ec->lrx = ec->lclean = ec->lclean_bg = 0;
 	ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
 
-	ec->Lbgn = ec->Lbgn_acc = 0;
-	ec->Lbgn_upper = 200;
-	ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
+	ec->lbgn = ec->lbgn_acc = 0;
+	ec->lbgn_upper = 200;
+	ec->lbgn_upper_acc = ec->lbgn_upper << 13;
 
 	ec->nonupdate_dwell = 0;
 
@@ -332,7 +332,7 @@ void oslec_flush(struct oslec_state *ec)
 		memset(ec->fir_taps16[i], 0, ec->taps * sizeof(int16_t));
 
 	ec->curr_pos = ec->taps - 1;
-	ec->Pstates = 0;
+	ec->pstates = 0;
 }
 EXPORT_SYMBOL_GPL(oslec_flush);
 
@@ -418,33 +418,33 @@ int16_t oslec_update(struct oslec_state
 		new = (int)tx * (int)tx;
 		old = (int)ec->fir_state.history[ec->fir_state.curr_pos] *
 		    (int)ec->fir_state.history[ec->fir_state.curr_pos];
-		ec->Pstates +=
+		ec->pstates +=
 		    ((new - old) + (1 << (ec->log2taps - 1))) >> ec->log2taps;
-		if (ec->Pstates < 0)
-			ec->Pstates = 0;
+		if (ec->pstates < 0)
+			ec->pstates = 0;
 	}
 
 	/* Calculate short term average levels using simple single pole IIRs */
 
-	ec->Ltxacc += abs(tx) - ec->Ltx;
-	ec->Ltx = (ec->Ltxacc + (1 << 4)) >> 5;
-	ec->Lrxacc += abs(rx) - ec->Lrx;
-	ec->Lrx = (ec->Lrxacc + (1 << 4)) >> 5;
+	ec->ltxacc += abs(tx) - ec->ltx;
+	ec->ltx = (ec->ltxacc + (1 << 4)) >> 5;
+	ec->lrxacc += abs(rx) - ec->lrx;
+	ec->lrx = (ec->lrxacc + (1 << 4)) >> 5;
 
 	/* Foreground filter */
 
 	ec->fir_state.coeffs = ec->fir_taps16[0];
 	echo_value = fir16(&ec->fir_state, tx);
 	ec->clean = rx - echo_value;
-	ec->Lcleanacc += abs(ec->clean) - ec->Lclean;
-	ec->Lclean = (ec->Lcleanacc + (1 << 4)) >> 5;
+	ec->lcleanacc += abs(ec->clean) - ec->lclean;
+	ec->lclean = (ec->lcleanacc + (1 << 4)) >> 5;
 
 	/* Background filter */
 
 	echo_value = fir16(&ec->fir_state_bg, tx);
 	clean_bg = rx - echo_value;
-	ec->Lclean_bgacc += abs(clean_bg) - ec->Lclean_bg;
-	ec->Lclean_bg = (ec->Lclean_bgacc + (1 << 4)) >> 5;
+	ec->lclean_bgacc += abs(clean_bg) - ec->lclean_bg;
+	ec->lclean_bg = (ec->lclean_bgacc + (1 << 4)) >> 5;
 
 	/* Background Filter adaption */
 
@@ -455,7 +455,7 @@ int16_t oslec_update(struct oslec_state
 	ec->factor = 0;
 	ec->shift = 0;
 	if ((ec->nonupdate_dwell == 0)) {
-		int P, logP, shift;
+		int p, logp, shift;
 
 		/* Determine:
 
@@ -490,9 +490,9 @@ int16_t oslec_update(struct oslec_state
 		   for a divide versus a top_bit() implementation.
 		 */
 
-		P = MIN_TX_POWER_FOR_ADAPTION + ec->Pstates;
-		logP = top_bit(P) + ec->log2taps;
-		shift = 30 - 2 - logP;
+		p = MIN_TX_POWER_FOR_ADAPTION + ec->pstates;
+		logp = top_bit(p) + ec->log2taps;
+		shift = 30 - 2 - logp;
 		ec->shift = shift;
 
 		lms_adapt_bg(ec, clean_bg, shift);
@@ -502,7 +502,7 @@ int16_t oslec_update(struct oslec_state
 	   near end speech */
 
 	ec->adapt = 0;
-	if ((ec->Lrx > MIN_RX_POWER_FOR_ADAPTION) && (ec->Lrx > ec->Ltx))
+	if ((ec->lrx > MIN_RX_POWER_FOR_ADAPTION) && (ec->lrx > ec->ltx))
 		ec->nonupdate_dwell = DTD_HANGOVER;
 	if (ec->nonupdate_dwell)
 		ec->nonupdate_dwell--;
@@ -515,9 +515,9 @@ int16_t oslec_update(struct oslec_state
 	if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) &&
 	    (ec->nonupdate_dwell == 0) &&
 	    /* (ec->Lclean_bg < 0.875*ec->Lclean) */
-	    (8 * ec->Lclean_bg < 7 * ec->Lclean) &&
+	    (8 * ec->lclean_bg < 7 * ec->lclean) &&
 	    /* (ec->Lclean_bg < 0.125*ec->Ltx) */
-	    (8 * ec->Lclean_bg < ec->Ltx)) {
+	    (8 * ec->lclean_bg < ec->ltx)) {
 		if (ec->cond_met == 6) {
 			/*
 			 * BG filter has had better results for 6 consecutive
@@ -541,14 +541,14 @@ int16_t oslec_update(struct oslec_state
 		 * non-linearity in the channel.".
 		 */
 
-		if ((16 * ec->Lclean < ec->Ltx)) {
+		if ((16 * ec->lclean < ec->ltx)) {
 			/*
 			 * Our e/c has improved echo by at least 24 dB (each
 			 * factor of 2 is 6dB, so 2*2*2*2=16 is the same as
 			 * 6+6+6+6=24dB)
 			 */
 			if (ec->adaption_mode & ECHO_CAN_USE_CNG) {
-				ec->cng_level = ec->Lbgn;
+				ec->cng_level = ec->lbgn;
 
 				/*
 				 * Very elementary comfort noise generation.
@@ -571,10 +571,10 @@ int16_t oslec_update(struct oslec_state
 
 			} else if (ec->adaption_mode & ECHO_CAN_USE_CLIP) {
 				/* This sounds much better than CNG */
-				if (ec->clean_nlp > ec->Lbgn)
-					ec->clean_nlp = ec->Lbgn;
-				if (ec->clean_nlp < -ec->Lbgn)
-					ec->clean_nlp = -ec->Lbgn;
+				if (ec->clean_nlp > ec->lbgn)
+					ec->clean_nlp = ec->lbgn;
+				if (ec->clean_nlp < -ec->lbgn)
+					ec->clean_nlp = -ec->lbgn;
 			} else {
 				/*
 				 * just mute the residual, doesn't sound very
@@ -593,9 +593,9 @@ int16_t oslec_update(struct oslec_state
 			 * level signals like near end speech.  When combined
 			 * with CNG or especially CLIP seems to work OK.
 			 */
-			if (ec->Lclean < 40) {
-				ec->Lbgn_acc += abs(ec->clean) - ec->Lbgn;
-				ec->Lbgn = (ec->Lbgn_acc + (1 << 11)) >> 12;
+			if (ec->lclean < 40) {
+				ec->lbgn_acc += abs(ec->clean) - ec->lbgn;
+				ec->lbgn = (ec->lbgn_acc + (1 << 11)) >> 12;
 			}
 		}
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/echo/echo.h linux-libre-3.11-rc7-gnu/drivers/staging/echo/echo.h
--- linux-libre-3.10-gnu/drivers/staging/echo/echo.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/echo/echo.h	2013-08-25 20:43:22.000000000 -0400
@@ -139,24 +139,24 @@ struct oslec_state {
 	int adaption_mode;
 
 	int cond_met;
-	int32_t Pstates;
+	int32_t pstates;
 	int16_t adapt;
 	int32_t factor;
 	int16_t shift;
 
 	/* Average levels and averaging filter states */
-	int Ltxacc;
-	int Lrxacc;
-	int Lcleanacc;
-	int Lclean_bgacc;
-	int Ltx;
-	int Lrx;
-	int Lclean;
-	int Lclean_bg;
-	int Lbgn;
-	int Lbgn_acc;
-	int Lbgn_upper;
-	int Lbgn_upper_acc;
+	int ltxacc;
+	int lrxacc;
+	int lcleanacc;
+	int lclean_bgacc;
+	int ltx;
+	int lrx;
+	int lclean;
+	int lclean_bg;
+	int lbgn;
+	int lbgn_acc;
+	int lbgn_upper;
+	int lbgn_upper_acc;
 
 	/* foreground and background filter states */
 	struct fir16_state_t fir_state;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/frontier/alphatrack.c linux-libre-3.11-rc7-gnu/drivers/staging/frontier/alphatrack.c
--- linux-libre-3.10-gnu/drivers/staging/frontier/alphatrack.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/frontier/alphatrack.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,13 +24,14 @@
  * raw interrupt reports.
  */
 
-/* Note: this currently uses a dumb ringbuffer for reads and writes.
+/*
+ * Note: this currently uses a dumb ringbuffer for reads and writes.
  * A more optimal driver would cache and kill off outstanding urbs that are
  * now invalid, and ignore ones that already were in the queue but valid
  * as we only have 30 commands for the alphatrack. In particular this is
  * key for getting lights to flash in time as otherwise many commands
  * can be buffered up before the light change makes it to the interface.
-*/
+ */
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -100,7 +101,8 @@ static int debug = ALPHATRACK_DEBUG;
 module_param(debug, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
 
-/* All interrupt in transfers are collected in a ring buffer to
+/*
+ * All interrupt in transfers are collected in a ring buffer to
  * avoid racing conditions and get better performance of the driver.
  */
 
@@ -109,8 +111,7 @@ static int ring_buffer_size = RING_BUFFE
 module_param(ring_buffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size");
 
-/* The write_buffer can one day contain more than one interrupt out transfer.
- */
+/* The write_buffer can one day contain more than one interrupt out transfer.*/
 
 static int write_buffer_size = WRITE_BUFFER_SIZE;
 module_param(write_buffer_size, int, S_IRUGO);
@@ -199,9 +200,7 @@ static void usb_alphatrack_abort_transfe
 			usb_kill_urb(dev->interrupt_out_urb);
 }
 
-/**
- *	usb_alphatrack_delete
- */
+/** usb_alphatrack_delete */
 static void usb_alphatrack_delete(struct usb_alphatrack *dev)
 {
 	usb_alphatrack_abort_transfers(dev);
@@ -213,9 +212,7 @@ static void usb_alphatrack_delete(struct
 	kfree(dev);		/* fixme oldi_buffer */
 }
 
-/**
- *	usb_alphatrack_interrupt_in_callback
- */
+/** usb_alphatrack_interrupt_in_callback */
 
 static void usb_alphatrack_interrupt_in_callback(struct urb *urb)
 {
@@ -296,9 +293,7 @@ exit:
 	wake_up_interruptible(&dev->read_wait);
 }
 
-/**
- *	usb_alphatrack_interrupt_out_callback
- */
+/** usb_alphatrack_interrupt_out_callback */
 static void usb_alphatrack_interrupt_out_callback(struct urb *urb)
 {
 	struct usb_alphatrack *dev = urb->context;
@@ -315,9 +310,7 @@ static void usb_alphatrack_interrupt_out
 	wake_up_interruptible(&dev->write_wait);
 }
 
-/**
- *	usb_alphatrack_open
- */
+/** usb_alphatrack_open */
 static int usb_alphatrack_open(struct inode *inode, struct file *file)
 {
 	struct usb_alphatrack *dev;
@@ -398,9 +391,7 @@ unlock_disconnect_exit:
 	return retval;
 }
 
-/**
- *	usb_alphatrack_release
- */
+/** usb_alphatrack_release */
 static int usb_alphatrack_release(struct inode *inode, struct file *file)
 {
 	struct usb_alphatrack *dev;
@@ -447,9 +438,7 @@ exit:
 	return retval;
 }
 
-/**
- *	usb_alphatrack_poll
- */
+/** usb_alphatrack_poll */
 static unsigned int usb_alphatrack_poll(struct file *file, poll_table *wait)
 {
 	struct usb_alphatrack *dev;
@@ -468,9 +457,7 @@ static unsigned int usb_alphatrack_poll(
 	return mask;
 }
 
-/**
- *	usb_alphatrack_read
- */
+/** usb_alphatrack_read */
 static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer,
 				   size_t count, loff_t *ppos)
 {
@@ -539,9 +526,7 @@ exit:
 	return retval;
 }
 
-/**
- *	usb_alphatrack_write
- */
+/** usb_alphatrack_write */
 static ssize_t usb_alphatrack_write(struct file *file,
 				    const char __user *buffer, size_t count,
 				    loff_t *ppos)
@@ -601,7 +586,7 @@ static ssize_t usb_alphatrack_write(stru
 	}
 
 	if (dev->interrupt_out_endpoint == NULL) {
-		dev_err(&dev->intf->dev, "Endpoint should not be be null!\n");
+		dev_err(&dev->intf->dev, "Endpoint should not be null!\n");
 		goto unlock_exit;
 	}
 
@@ -718,8 +703,10 @@ static int usb_alphatrack_probe(struct u
 
 	true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
 
-	/* FIXME - there are more usb_alloc routines for dma correctness.
-	   Needed? */
+	/*
+	 * FIXME - there are more usb_alloc routines for dma correctness.
+	 * Needed?
+	 */
 	dev->ring_buffer = kmalloc_array(true_size,
 					 sizeof(struct alphatrack_icmd),
 					 GFP_KERNEL);
@@ -840,11 +827,11 @@ static void usb_alphatrack_disconnect(st
 		mutex_unlock(&dev->mtx);
 		usb_alphatrack_delete(dev);
 	} else {
+		atomic_set(&dev->writes_pending, 0);
 		dev->intf = NULL;
 		mutex_unlock(&dev->mtx);
 	}
 
-	atomic_set(&dev->writes_pending, 0);
 	mutex_unlock(&disconnect_mutex);
 
 	dev_info(&intf->dev, "Alphatrack Surface #%d now disconnected\n",
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/frontier/alphatrack.h linux-libre-3.11-rc7-gnu/drivers/staging/frontier/alphatrack.h
--- linux-libre-3.10-gnu/drivers/staging/frontier/alphatrack.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/frontier/alphatrack.h	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,8 @@ struct alphatrack_ocmd {
 	unsigned char cmd[8];
 };
 
-/* These are unused by the present driver but provide documentation for the
+/*
+ * These are unused by the present driver but provide documentation for the
  * userspace API.
  */
 enum LightID {
@@ -58,7 +59,8 @@ enum LightID {
 #define BUTTONMASK_PRESS2      0x00008010
 #define BUTTONMASK_PRESS3      0x00002020
 
-/* last 3 bytes are the slider position
+/*
+ * last 3 bytes are the slider position
  * 40 is the actual slider moving, the most sig bits, and 3 lsb
  */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/frontier/tranzport.c linux-libre-3.11-rc7-gnu/drivers/staging/frontier/tranzport.c
--- linux-libre-3.10-gnu/drivers/staging/frontier/tranzport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/frontier/tranzport.c	2013-08-25 20:43:22.000000000 -0400
@@ -86,7 +86,8 @@ static int debug = TRANZPORT_DEBUG;
 module_param(debug, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
 
-/* All interrupt in transfers are collected in a ring buffer to
+/*
+ * All interrupt in transfers are collected in a ring buffer to
  * avoid racing conditions and get better performance of the driver.
  */
 
@@ -95,7 +96,8 @@ static int ring_buffer_size = RING_BUFFE
 module_param(ring_buffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size in reports");
 
-/* The write_buffer can one day contain more than one interrupt out transfer.
+/*
+ * The write_buffer can one day contain more than one interrupt out transfer.
  */
 static int write_buffer_size = WRITE_BUFFER_SIZE;
 module_param(write_buffer_size, int, S_IRUGO);
@@ -565,9 +567,9 @@ static ssize_t usb_tranzport_read(struct
 			newwheel = (*dev->ring_buffer)[next_tail].cmd[6];
 			oldwheel = (*dev->ring_buffer)[dev->ring_tail].cmd[6];
 			/* if both are wheel events, and
-			   no buttons have changes (FIXME, do I have to check?),
-			   and we are the same sign, we can compress +- 7F
-			*/
+			 * no buttons have changes (FIXME, do I have to check?),
+			 * and we are the same sign, we can compress +- 7F
+			 */
 			dbg_info(&dev->intf->dev,
 				"%s: trying to compress: "
 				"%02x%02x%02x%02x%02x%02x%02x%02x\n",
@@ -729,7 +731,7 @@ static ssize_t usb_tranzport_write(struc
 	}
 
 	if (dev->interrupt_out_endpoint == NULL) {
-		dev_err(&dev->intf->dev, "Endpoint should not be be null!\n");
+		dev_err(&dev->intf->dev, "Endpoint should not be null!\n");
 		goto unlock_exit;
 	}
 
@@ -842,8 +844,10 @@ static int usb_tranzport_probe(struct us
 		ring_buffer_size = RING_BUFFER_SIZE;
 	true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
 
-	/* FIXME - there are more usb_alloc routines for dma correctness.
-	   Needed? */
+	/*
+	 * FIXME - there are more usb_alloc routines for dma correctness.
+	 * Needed?
+	 */
 
 	dev->ring_buffer =
 	    kmalloc((true_size * sizeof(struct tranzport_cmd)) + 8, GFP_KERNEL);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c
--- linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c	2013-08-25 20:43:22.000000000 -0400
@@ -132,16 +132,16 @@ void card_bootload(struct net_device *de
 	pdata = (u32 *) bootimage;
 	size = sizeof(bootimage);
 
-	// check for odd word
-	if (size & 0x0003) {
+	/* check for odd word */
+	if (size & 0x0003)
 		size += 4;
-	}
-	// Provide mutual exclusive access while reading ASIC registers.
+
+	/* Provide mutual exclusive access while reading ASIC registers. */
 	spin_lock_irqsave(&info->dpram_lock, flags);
 
-	// need to set i/o base address initially and hardware will autoincrement
+	/* need to set i/o base address initially and hardware will autoincrement */
 	ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_BASE);
-	// write bytes
+	/* write bytes */
 	for (i = 0; i < (size >> 2); i++) {
 		templong = *pdata++;
 		outl(templong, dev->base_addr + FT1000_REG_MAG_DPDATA);
@@ -345,11 +345,10 @@ int card_download(struct net_device *dev
 
 			handshake = get_handshake(dev, HANDSHAKE_DSP_BL_READY);
 
-			if (handshake == HANDSHAKE_DSP_BL_READY) {
+			if (handshake == HANDSHAKE_DSP_BL_READY)
 				put_handshake(dev, HANDSHAKE_DRIVER_READY);
-			} else {
+			else
 				Status = FAILURE;
-			}
 
 			uiState = STATE_BOOT_DWNLD;
 
@@ -391,7 +390,7 @@ int card_download(struct net_device *dev
 						Status = FAILURE;
 						break;
 					}
-					// Provide mutual exclusive access while reading ASIC registers.
+					/* Provide mutual exclusive access while reading ASIC registers. */
 					spin_lock_irqsave(&info->dpram_lock,
 							  flags);
 					/*
@@ -505,15 +504,15 @@ int card_download(struct net_device *dev
 					break;
 
 				case REQUEST_MAILBOX_DATA:
-					// Convert length from byte count to word count. Make sure we round up.
+					/* Convert length from byte count to word count. Make sure we round up. */
 					word_length =
 						(long)(info->DSPInfoBlklen + 1) / 2;
 					put_request_value(dev, word_length);
 					pMailBoxData =
-						(struct drv_msg *) & info->DSPInfoBlk[0];
+						(struct drv_msg *) &info->DSPInfoBlk[0];
 					pUsData =
-						(u16 *) & pMailBoxData->data[0];
-					// Provide mutual exclusive access while reading ASIC registers.
+						(u16 *) &pMailBoxData->data[0];
+					/* Provide mutual exclusive access while reading ASIC registers. */
 					spin_lock_irqsave(&info->dpram_lock,
 							  flags);
 					if (file_version == 5) {
@@ -538,9 +537,9 @@ int card_download(struct net_device *dev
 						outw(DWNLD_MAG_PS_HDR_LOC,
 							 dev->base_addr +
 							 FT1000_REG_DPRAM_ADDR);
-						if (word_length & 0x01) {
+						if (word_length & 0x01)
 							word_length++;
-						}
+
 						word_length = word_length / 2;
 
 						for (; word_length > 0; word_length--) {	/* In words */
@@ -565,7 +564,7 @@ int card_download(struct net_device *dev
 						(u16 *) ((long)pFileStart +
 							pFileHdr5->
 							version_data_offset);
-					// Provide mutual exclusive access while reading ASIC registers.
+					/* Provide mutual exclusive access while reading ASIC registers. */
 					spin_lock_irqsave(&info->dpram_lock,
 							  flags);
 					/*
@@ -692,7 +691,7 @@ int card_download(struct net_device *dev
 
 			if (pHdr->portdest == 0x80	/* DspOAM */
 				&& (pHdr->portsrc == 0x00	/* Driver */
-				|| pHdr->portsrc == 0x10 /* FMM */ )) {
+				|| pHdr->portsrc == 0x10 /* FMM */)) {
 				uiState = STATE_SECTION_PROV;
 			} else {
 				DEBUG(1,
@@ -711,13 +710,13 @@ int card_download(struct net_device *dev
 			pHdr = (struct pseudo_hdr *) pUcFile;
 
 			if (pHdr->checksum == hdr_checksum(pHdr)) {
-				if (pHdr->portdest != 0x80 /* Dsp OAM */ ) {
+				if (pHdr->portdest != 0x80 /* Dsp OAM */) {
 					uiState = STATE_DONE_PROV;
 					break;
 				}
 				usHdrLength = ntohs(pHdr->length);	/* Byte length for PROV records */
 
-				// Get buffer for provisioning data
+				/* Get buffer for provisioning data */
 				pbuffer =
 					kmalloc((usHdrLength + sizeof(struct pseudo_hdr)),
 						GFP_ATOMIC);
@@ -725,7 +724,7 @@ int card_download(struct net_device *dev
 					memcpy(pbuffer, (void *)pUcFile,
 						   (u32) (usHdrLength +
 							   sizeof(struct pseudo_hdr)));
-					// link provisioning data
+					/* link provisioning data */
 					pprov_record =
 						kmalloc(sizeof(struct prov_record),
 							GFP_ATOMIC);
@@ -735,7 +734,7 @@ int card_download(struct net_device *dev
 						list_add_tail(&pprov_record->
 								  list,
 								  &info->prov_list);
-						// Move to next entry if available
+						/* Move to next entry if available */
 						pUcFile =
 							(u8 *) ((unsigned long) pUcFile +
 								   (unsigned long) ((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr));
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
--- linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c	2013-08-25 20:43:22.000000000 -0400
@@ -164,7 +164,7 @@ static const struct file_operations ft10
 static int ft1000NotifyProc(struct notifier_block *this, unsigned long event,
 				void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct ft1000_info *info;
 
 	info = netdev_priv(dev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c
--- linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,29 +1,31 @@
-//---------------------------------------------------------------------------
-// FT1000 driver for Flarion Flash OFDM NIC Device
-//
-// Copyright (C) 2006 Flarion Technologies, All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 of the License, or (at your option) any
-// later version. This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-// more details. You should have received a copy of the GNU General Public
-// License along with this program; if not, write to the
-// Free Software Foundation, Inc., 59 Temple Place -
-// Suite 330, Boston, MA 02111-1307, USA.
-//---------------------------------------------------------------------------
-//
-// File:         ft1000_chdev.c
-//
-// Description:  Custom character device dispatch routines.
-//
-// History:
-// 8/29/02    Whc                Ported to Linux.
-// 6/05/06    Whc                Porting to Linux 2.6.9
-//
-//---------------------------------------------------------------------------
+/*
+*---------------------------------------------------------------------------
+* FT1000 driver for Flarion Flash OFDM NIC Device
+*
+* Copyright (C) 2006 Flarion Technologies, All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the Free
+* Software Foundation; either version 2 of the License, or (at your option) any
+* later version. This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+* more details. You should have received a copy of the GNU General Public
+* License along with this program; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place -
+* Suite 330, Boston, MA 02111-1307, USA.
+*---------------------------------------------------------------------------
+*
+* File:         ft1000_chdev.c
+*
+* Description:  Custom character device dispatch routines.
+*
+* History:
+* 8/29/02    Whc                Ported to Linux.
+* 6/05/06    Whc                Porting to Linux 2.6.9
+*
+*---------------------------------------------------------------------------
+*/
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -38,25 +40,24 @@
 
 static int ft1000_flarion_cnt = 0;
 
-static int ft1000_open (struct inode *inode, struct file *file);
+static int ft1000_open(struct inode *inode, struct file *file);
 static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait);
 static long ft1000_ioctl(struct file *file, unsigned int command,
                            unsigned long argument);
-static int ft1000_release (struct inode *inode, struct file *file);
+static int ft1000_release(struct inode *inode, struct file *file);
 
-// List to free receive command buffer pool
+/* List to free receive command buffer pool */
 struct list_head freercvpool;
 
-// lock to arbitrate free buffer list for receive command data
+/* lock to arbitrate free buffer list for receive command data */
 spinlock_t free_buff_lock;
 
 int numofmsgbuf = 0;
 
-//
-// Table of entry-point routines for char device
-//
-static const struct file_operations ft1000fops =
-{
+/*
+* Table of entry-point routines for char device
+*/
+static const struct file_operations ft1000fops = {
 	.unlocked_ioctl	= ft1000_ioctl,
 	.poll		= ft1000_poll_dev,
 	.open		= ft1000_open,
@@ -64,34 +65,35 @@ static const struct file_operations ft10
 	.llseek		= no_llseek,
 };
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_get_buffer
-//
-// Parameters:
-//
-// Returns:
-//
-// Description:
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/*
+---------------------------------------------------------------------------
+* Function:    ft1000_get_buffer
+*
+* Parameters:
+*
+* Returns:
+*
+* Description:
+*
+* Notes:
+*
+*---------------------------------------------------------------------------
+*/
 struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist)
 {
     unsigned long flags;
 	struct dpram_blk *ptr;
 
     spin_lock_irqsave(&free_buff_lock, flags);
-    // Check if buffer is available
-    if ( list_empty(bufflist) ) {
+    /* Check if buffer is available */
+    if (list_empty(bufflist)) {
         DEBUG("ft1000_get_buffer:  No more buffer - %d\n", numofmsgbuf);
         ptr = NULL;
-    }
-    else {
+    } else {
         numofmsgbuf--;
 	ptr = list_entry(bufflist->next, struct dpram_blk, list);
         list_del(&ptr->list);
-        //DEBUG("ft1000_get_buffer: number of free msg buffers = %d\n", numofmsgbuf);
+        /* DEBUG("ft1000_get_buffer: number of free msg buffers = %d\n", numofmsgbuf); */
     }
     spin_unlock_irqrestore(&free_buff_lock, flags);
 
@@ -101,42 +103,46 @@ struct dpram_blk *ft1000_get_buffer(stru
 
 
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_free_buffer
-//
-// Parameters:
-//
-// Returns:
-//
-// Description:
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/*
+*---------------------------------------------------------------------------
+* Function:    ft1000_free_buffer
+*
+* Parameters:
+*
+* Returns:
+*
+* Description:
+*
+* Notes:
+*
+*---------------------------------------------------------------------------
+*/
 void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist)
 {
     unsigned long flags;
 
     spin_lock_irqsave(&free_buff_lock, flags);
-    // Put memory back to list
+    /* Put memory back to list */
     list_add_tail(&pdpram_blk->list, plist);
     numofmsgbuf++;
-    //DEBUG("ft1000_free_buffer: number of free msg buffers = %d\n", numofmsgbuf);
+    /*DEBUG("ft1000_free_buffer: number of free msg buffers = %d\n", numofmsgbuf); */
     spin_unlock_irqrestore(&free_buff_lock, flags);
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_CreateDevice
-//
-// Parameters:  dev - pointer to adapter object
-//
-// Returns:     0 if successful
-//
-// Description: Creates a private char device.
-//
-// Notes:       Only called by init_module().
-//
-//---------------------------------------------------------------------------
+/*
+*---------------------------------------------------------------------------
+* Function:    ft1000_CreateDevice
+*
+* Parameters:  dev - pointer to adapter object
+*
+* Returns:     0 if successful
+*
+* Description: Creates a private char device.
+*
+* Notes:       Only called by init_module().
+*
+*---------------------------------------------------------------------------
+*/
 int ft1000_create_dev(struct ft1000_usb *dev)
 {
     int result;
@@ -144,20 +150,19 @@ int ft1000_create_dev(struct ft1000_usb
 	struct dentry *dir, *file;
 	struct ft1000_debug_dirs *tmp;
 
-    // make a new device name
+    /* make a new device name */
     sprintf(dev->DeviceName, "%s%d", "FT1000_", dev->CardNumber);
 
     DEBUG("%s: number of instance = %d\n", __func__, ft1000_flarion_cnt);
     DEBUG("DeviceCreated = %x\n", dev->DeviceCreated);
 
-    if (dev->DeviceCreated)
-    {
+    if (dev->DeviceCreated) {
 	DEBUG("%s: \"%s\" already registered\n", __func__, dev->DeviceName);
 	return -EIO;
     }
 
 
-    // register the device
+    /* register the device */
     DEBUG("%s: \"%s\" debugfs device registration\n", __func__, dev->DeviceName);
 
 	tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL);
@@ -186,7 +191,7 @@ int ft1000_create_dev(struct ft1000_usb
 
     DEBUG("%s: registered debugfs directory \"%s\"\n", __func__, dev->DeviceName);
 
-    // initialize application information
+    /* initialize application information */
     dev->appcnt = 0;
     for (i=0; i<MAX_NUM_APP; i++) {
         dev->app_info[i].nTxMsg = 0;
@@ -198,7 +203,7 @@ int ft1000_create_dev(struct ft1000_usb
         dev->app_info[i].DspBCMsgFlag = 0;
         dev->app_info[i].NumOfMsg = 0;
         init_waitqueue_head(&dev->app_info[i].wait_dpram_msg);
-        INIT_LIST_HEAD (&dev->app_info[i].app_sqlist);
+        INIT_LIST_HEAD(&dev->app_info[i].app_sqlist);
     }
 
     dev->DeviceCreated = TRUE;
@@ -214,16 +219,18 @@ fail:
 	return result;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_DestroyDeviceDEBUG
-//
-// Parameters:  dev - pointer to adapter object
-//
-// Description: Destroys a private char device.
-//
-// Notes:       Only called by cleanup_module().
-//
-//---------------------------------------------------------------------------
+/*
+*---------------------------------------------------------------------------
+* Function:    ft1000_DestroyDeviceDEBUG
+*
+* Parameters:  dev - pointer to adapter object
+*
+* Description: Destroys a private char device.
+*
+* Notes:       Only called by cleanup_module().
+*
+*---------------------------------------------------------------------------
+*/
 void ft1000_destroy_dev(struct net_device *netdev)
 {
 	struct ft1000_info *info = netdev_priv(netdev);
@@ -238,8 +245,7 @@ void ft1000_destroy_dev(struct net_devic
 
 
 
-    if (dev->DeviceCreated)
-	{
+    if (dev->DeviceCreated) {
         ft1000_flarion_cnt--;
 		list_for_each_safe(pos, q, &dev->nodes.list) {
 			dir = list_entry(pos, struct ft1000_debug_dirs, list);
@@ -253,7 +259,7 @@ void ft1000_destroy_dev(struct net_devic
 		DEBUG("%s: unregistered device \"%s\"\n", __func__,
 					   dev->DeviceName);
 
-        // Make sure we free any memory reserve for slow Queue
+        /* Make sure we free any memory reserve for slow Queue */
         for (i=0; i<MAX_NUM_APP; i++) {
             while (list_empty(&dev->app_info[i].app_sqlist) == 0) {
                 pdpram_blk = list_entry(dev->app_info[i].app_sqlist.next, struct dpram_blk, list);
@@ -264,7 +270,7 @@ void ft1000_destroy_dev(struct net_devic
             wake_up_interruptible(&dev->app_info[i].wait_dpram_msg);
         }
 
-        // Remove buffer allocated for receive command data
+        /* Remove buffer allocated for receive command data */
         if (ft1000_flarion_cnt == 0) {
             while (list_empty(&freercvpool) == 0) {
 		ptr = list_entry(freercvpool.next, struct dpram_blk, list);
@@ -279,17 +285,19 @@ void ft1000_destroy_dev(struct net_devic
 
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_open
-//
-// Parameters:
-//
-// Description:
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static int ft1000_open (struct inode *inode, struct file *file)
+/*
+*---------------------------------------------------------------------------
+* Function:    ft1000_open
+*
+* Parameters:
+*
+* Description:
+*
+* Notes:
+*
+*---------------------------------------------------------------------------
+*/
+static int ft1000_open(struct inode *inode, struct file *file)
 {
 	struct ft1000_info *info;
 	struct ft1000_usb *dev = (struct ft1000_usb *)inode->i_private;
@@ -301,22 +309,22 @@ static int ft1000_open (struct inode *in
 
 	info = file->private_data = netdev_priv(dev->net);
 
-    DEBUG("f_owner = %p number of application = %d\n", (&file->f_owner), dev->appcnt );
+    DEBUG("f_owner = %p number of application = %d\n", (&file->f_owner), dev->appcnt);
 
-    // Check if maximum number of application exceeded
+    /* Check if maximum number of application exceeded */
     if (dev->appcnt > MAX_NUM_APP) {
         DEBUG("Maximum number of application exceeded\n");
         return -EACCES;
     }
 
-    // Search for available application info block
+    /* Search for available application info block */
     for (i=0; i<MAX_NUM_APP; i++) {
-        if ( (dev->app_info[i].fileobject == NULL) ) {
+        if ((dev->app_info[i].fileobject == NULL)) {
             break;
         }
     }
 
-    // Fail due to lack of application info block
+    /* Fail due to lack of application info block */
     if (i == MAX_NUM_APP) {
         DEBUG("Could not find an application info block\n");
         return -EACCES;
@@ -334,16 +342,18 @@ static int ft1000_open (struct inode *in
 }
 
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_poll_dev
-//
-// Parameters:
-//
-// Description:
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/*
+*---------------------------------------------------------------------------
+* Function:    ft1000_poll_dev
+*
+* Parameters:
+*
+* Description:
+*
+* Notes:
+*
+*---------------------------------------------------------------------------
+*/
 
 static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait)
 {
@@ -352,24 +362,24 @@ static unsigned int ft1000_poll_dev(stru
 	struct ft1000_usb *dev = info->priv;
     int i;
 
-    //DEBUG("ft1000_poll_dev called\n");
+    /* DEBUG("ft1000_poll_dev called\n"); */
     if (ft1000_flarion_cnt == 0) {
         DEBUG("FT1000:ft1000_poll_dev called when ft1000_flarion_cnt is zero\n");
         return (-EBADF);
     }
 
-    // Search for matching file object
+    /* Search for matching file object */
     for (i=0; i<MAX_NUM_APP; i++) {
-        if ( dev->app_info[i].fileobject == &file->f_owner) {
-            //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", dev->app_info[i].app_id);
+        if (dev->app_info[i].fileobject == &file->f_owner) {
+            /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", dev->app_info[i].app_id); */
             break;
         }
     }
 
-    // Could not find application info block
+    /* Could not find application info block */
     if (i == MAX_NUM_APP) {
         DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n");
-        return ( -EACCES );
+        return (-EACCES);
     }
 
     if (list_empty(&dev->app_info[i].app_sqlist) == 0) {
@@ -377,23 +387,25 @@ static unsigned int ft1000_poll_dev(stru
         return(POLLIN | POLLRDNORM | POLLPRI);
     }
 
-    poll_wait (file, &dev->app_info[i].wait_dpram_msg, wait);
-    //DEBUG("FT1000:ft1000_poll_dev:Polling for data from DSP\n");
+    poll_wait(file, &dev->app_info[i].wait_dpram_msg, wait);
+    /* DEBUG("FT1000:ft1000_poll_dev:Polling for data from DSP\n"); */
 
     return (0);
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_ioctl
-//
-// Parameters:
-//
-// Description:
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static long ft1000_ioctl (struct file *file, unsigned int command,
+/*
+*---------------------------------------------------------------------------
+* Function:    ft1000_ioctl
+*
+* Parameters:
+*
+* Description:
+*
+* Notes:
+*
+*---------------------------------------------------------------------------
+*/
+static long ft1000_ioctl(struct file *file, unsigned int command,
                            unsigned long argument)
 {
     void __user *argp = (void __user *)argument;
@@ -417,21 +429,21 @@ static long ft1000_ioctl (struct file *f
     unsigned short ledStat=0;
     unsigned short conStat=0;
 
-    //DEBUG("ft1000_ioctl called\n");
+    /* DEBUG("ft1000_ioctl called\n"); */
 
     if (ft1000_flarion_cnt == 0) {
         DEBUG("FT1000:ft1000_ioctl called when ft1000_flarion_cnt is zero\n");
         return (-EBADF);
     }
 
-    //DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument);
+    /* DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); */
 
 	info = file->private_data;
 	ft1000dev = info->priv;
     cmd = _IOC_NR(command);
-    //DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd);
+    /* DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd); */
 
-    // process the command
+    /* process the command */
     switch (cmd) {
     case IOCTL_REGISTER_CMD:
             DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_REGISTER called\n");
@@ -441,7 +453,7 @@ static long ft1000_ioctl (struct file *f
                 break;
             }
             if (tempword == DSPBCMSGID) {
-                // Search for matching file object
+                /* Search for matching file object */
                 for (i=0; i<MAX_NUM_APP; i++) {
                     if (ft1000dev->app_info[i].fileobject == &file->f_owner) {
                         ft1000dev->app_info[i].DspBCMsgFlag = 1;
@@ -457,7 +469,7 @@ static long ft1000_ioctl (struct file *f
 
         get_ver_data.drv_ver = FT1000_DRV_VER;
 
-        if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data)) ) {
+        if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data))) {
             DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n");
             result = -EFAULT;
             break;
@@ -467,20 +479,20 @@ static long ft1000_ioctl (struct file *f
 
         break;
     case IOCTL_CONNECT:
-        // Connect Message
+        /* Connect Message */
         DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n");
         ConnectionMsg[79] = 0xfc;
 			   card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c);
 
         break;
     case IOCTL_DISCONNECT:
-        // Disconnect Message
+        /* Disconnect Message */
         DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n");
         ConnectionMsg[79] = 0xfd;
 			   card_send_command(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c);
         break;
     case IOCTL_GET_DSP_STAT_CMD:
-        //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n");
+        /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); */
 	memset(&get_stat_data, 0, sizeof(get_stat_data));
         memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ);
         memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ);
@@ -494,8 +506,7 @@ static long ft1000_ioctl (struct file *f
                 ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX);
                 get_stat_data.ConStat = ntohs(conStat);
                 DEBUG("FT1000:ft1000_ioctl: ConStat = 0x%x\n", get_stat_data.ConStat);
-            }
-            else {
+            } else {
                 get_stat_data.ConStat = 0x0f;
             }
 
@@ -504,10 +515,10 @@ static long ft1000_ioctl (struct file *f
         get_stat_data.nRxPkts = info->stats.rx_packets;
         get_stat_data.nTxBytes = info->stats.tx_bytes;
         get_stat_data.nRxBytes = info->stats.rx_bytes;
-        do_gettimeofday ( &tv );
+        do_gettimeofday(&tv);
         get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm);
         DEBUG("Connection Time = %d\n", (int)get_stat_data.ConTm);
-        if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data)) ) {
+        if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data))) {
             DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n");
             result = -EFAULT;
             break;
@@ -517,7 +528,7 @@ static long ft1000_ioctl (struct file *f
     case IOCTL_SET_DPRAM_CMD:
         {
             IOCTL_DPRAM_BLK *dpram_data = NULL;
-            //IOCTL_DPRAM_COMMAND dpram_command;
+            /* IOCTL_DPRAM_COMMAND dpram_command; */
             u16 qtype;
             u16 msgsz;
 		struct pseudo_hdr *ppseudo_hdr;
@@ -526,7 +537,7 @@ static long ft1000_ioctl (struct file *f
             u16 app_index;
             u16 status;
 
-            //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n");
+            /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n");*/
 
 
             if (ft1000_flarion_cnt == 0) {
@@ -545,12 +556,12 @@ static long ft1000_ioctl (struct file *f
 
             if (info->CardReady) {
 
-               //DEBUG("FT1000:ft1000_ioctl: try to SET_DPRAM \n");
+               /* DEBUG("FT1000:ft1000_ioctl: try to SET_DPRAM \n"); */
 
-                // Get the length field to see how many bytes to copy
+                /* Get the length field to see how many bytes to copy */
                 result = get_user(msgsz, (__u16 __user *)argp);
-                msgsz = ntohs (msgsz);
-                //DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz);
+                msgsz = ntohs(msgsz);
+                /* DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); */
 
                 if (msgsz > MAX_CMD_SQSIZE) {
                     DEBUG("FT1000:ft1000_ioctl: bad message length = %d\n", msgsz);
@@ -563,12 +574,11 @@ static long ft1000_ioctl (struct file *f
 		if (!dpram_data)
 			break;
 
-                if ( copy_from_user(dpram_data, argp, msgsz+2) ) {
+                if (copy_from_user(dpram_data, argp, msgsz+2)) {
                     DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n");
                     result = -EFAULT;
-                }
-                else {
-                    // Check if this message came from a registered application
+                } else {
+                    /* Check if this message came from a registered application */
                     for (i=0; i<MAX_NUM_APP; i++) {
                         if (ft1000dev->app_info[i].fileobject == &file->f_owner) {
                             break;
@@ -582,28 +592,27 @@ static long ft1000_ioctl (struct file *f
                     }
                     app_index = i;
 
-                    // Check message qtype type which is the lower byte within qos_class
+                    /* Check message qtype type which is the lower byte within qos_class */
                     qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff;
-                    //DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype);
+                    /* DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype); */
                     if (qtype) {
-                    }
-                    else {
-                        // Put message into Slow Queue
-                        // Only put a message into the DPRAM if msg doorbell is available
+                    } else {
+                        /* Put message into Slow Queue */
+                        /* Only put a message into the DPRAM if msg doorbell is available */
                         status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
-                        //DEBUG("FT1000_ft1000_ioctl: READ REGISTER tempword=%x\n", tempword);
+                        /* DEBUG("FT1000_ft1000_ioctl: READ REGISTER tempword=%x\n", tempword); */
                         if (tempword & FT1000_DB_DPRAM_TX) {
-                            // Suspend for 2ms and try again due to DSP doorbell busy
+                            /* Suspend for 2ms and try again due to DSP doorbell busy */
                             mdelay(2);
                             status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
                             if (tempword & FT1000_DB_DPRAM_TX) {
-                                // Suspend for 1ms and try again due to DSP doorbell busy
+                                /* Suspend for 1ms and try again due to DSP doorbell busy */
                                 mdelay(1);
                                 status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
                                 if (tempword & FT1000_DB_DPRAM_TX) {
                                     status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
                                     if (tempword & FT1000_DB_DPRAM_TX) {
-                                        // Suspend for 3ms and try again due to DSP doorbell busy
+                                        /* Suspend for 3ms and try again due to DSP doorbell busy */
                                         mdelay(3);
                                         status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL);
                                         if (tempword & FT1000_DB_DPRAM_TX) {
@@ -617,11 +626,11 @@ static long ft1000_ioctl (struct file *f
                             }
                         }
 
-                        //DEBUG("FT1000_ft1000_ioctl: finished reading register\n");
+                        /*DEBUG("FT1000_ft1000_ioctl: finished reading register\n"); */
 
-                        // Make sure we are within the limits of the slow queue memory limitation
-                        if ( (msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ) ) {
-                            // Need to put sequence number plus new checksum for message
+                        /* Make sure we are within the limits of the slow queue memory limitation */
+                        if ((msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ)) {
+                            /* Need to put sequence number plus new checksum for message */
                             pmsg = (u16 *)&dpram_data->pseudohdr;
 				ppseudo_hdr = (struct pseudo_hdr *)pmsg;
                             total_len = msgsz+2;
@@ -629,15 +638,15 @@ static long ft1000_ioctl (struct file *f
                                 total_len++;
                             }
 
-                            // Insert slow queue sequence number
+                            /* Insert slow queue sequence number */
                             ppseudo_hdr->seq_num = info->squeseqnum++;
                             ppseudo_hdr->portsrc = ft1000dev->app_info[app_index].app_id;
-                            // Calculate new checksum
+                            /* Calculate new checksum */
                             ppseudo_hdr->checksum = *pmsg++;
-                            //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum);
+                            /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */
                             for (i=1; i<7; i++) {
                                 ppseudo_hdr->checksum ^= *pmsg++;
-                                //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum);
+                                /* DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); */
                             }
                             pmsg++;
 				ppseudo_hdr = (struct pseudo_hdr *)pmsg;
@@ -645,14 +654,12 @@ static long ft1000_ioctl (struct file *f
 
 
                             ft1000dev->app_info[app_index].nTxMsg++;
-                        }
-                        else {
+                        } else {
                             result = -EINVAL;
                         }
                     }
                 }
-            }
-            else {
+            } else {
                 DEBUG("FT1000:ft1000_ioctl: Card not ready take messages\n");
                 result = -EACCES;
             }
@@ -666,21 +673,21 @@ static long ft1000_ioctl (struct file *f
             IOCTL_DPRAM_BLK __user *pioctl_dpram;
             int msglen;
 
-            //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n");
+            /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); */
 
             if (ft1000_flarion_cnt == 0) {
                 return (-EBADF);
             }
 
-            // Search for matching file object
+            /* Search for matching file object */
             for (i=0; i<MAX_NUM_APP; i++) {
                 if (ft1000dev->app_info[i].fileobject == &file->f_owner) {
-                    //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id);
+                    /*DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */
                     break;
                 }
             }
 
-            // Could not find application info block
+            /* Could not find application info block */
             if (i == MAX_NUM_APP) {
                 DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n");
                 result = -EBADF;
@@ -690,30 +697,29 @@ static long ft1000_ioctl (struct file *f
             result = 0;
             pioctl_dpram = argp;
             if (list_empty(&ft1000dev->app_info[i].app_sqlist) == 0) {
-                //DEBUG("FT1000:ft1000_ioctl:Message detected in slow queue\n");
+                /* DEBUG("FT1000:ft1000_ioctl:Message detected in slow queue\n"); */
                 spin_lock_irqsave(&free_buff_lock, flags);
                 pdpram_blk = list_entry(ft1000dev->app_info[i].app_sqlist.next, struct dpram_blk, list);
                 list_del(&pdpram_blk->list);
                 ft1000dev->app_info[i].NumOfMsg--;
-                //DEBUG("FT1000:ft1000_ioctl:NumOfMsg for app %d = %d\n", i, ft1000dev->app_info[i].NumOfMsg);
+                /* DEBUG("FT1000:ft1000_ioctl:NumOfMsg for app %d = %d\n", i, ft1000dev->app_info[i].NumOfMsg); */
                 spin_unlock_irqrestore(&free_buff_lock, flags);
                 msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ;
                 result = get_user(msglen, &pioctl_dpram->total_len);
 		if (result)
 			break;
 		msglen = htons(msglen);
-                //DEBUG("FT1000:ft1000_ioctl:msg length = %x\n", msglen);
-                if(copy_to_user (&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen))
-				{
+                /* DEBUG("FT1000:ft1000_ioctl:msg length = %x\n", msglen); */
+                if (copy_to_user (&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) {
 					DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n");
-	             	result = -EFAULT;
-	             	break;
+			result = -EFAULT;
+			break;
 				}
 
                 ft1000_free_buffer(pdpram_blk, &freercvpool);
                 result = msglen;
             }
-            //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM no message\n");
+            /* DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM no message\n"); */
         }
         break;
 
@@ -726,17 +732,19 @@ static long ft1000_ioctl (struct file *f
     return result;
 }
 
-//---------------------------------------------------------------------------
-// Function:    ft1000_release
-//
-// Parameters:
-//
-// Description:
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static int ft1000_release (struct inode *inode, struct file *file)
+/*
+*---------------------------------------------------------------------------
+* Function:    ft1000_release
+*
+* Parameters:
+*
+* Description:
+*
+* Notes:
+*
+*---------------------------------------------------------------------------
+*/
+static int ft1000_release(struct inode *inode, struct file *file)
 {
 	struct ft1000_info *info;
     struct net_device *dev;
@@ -755,10 +763,10 @@ static int ft1000_release (struct inode
         return (-EBADF);
     }
 
-    // Search for matching file object
+    /* Search for matching file object */
     for (i=0; i<MAX_NUM_APP; i++) {
-        if ( ft1000dev->app_info[i].fileobject == &file->f_owner) {
-            //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id);
+        if (ft1000dev->app_info[i].fileobject == &file->f_owner) {
+            /* DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", ft1000dev->app_info[i].app_id); */
             break;
         }
     }
@@ -773,11 +781,10 @@ static int ft1000_release (struct inode
         ft1000_free_buffer(pdpram_blk, &freercvpool);
     }
 
-    // initialize application information
+    /* initialize application information */
     ft1000dev->appcnt--;
     DEBUG("ft1000_chdev:%s:appcnt = %d\n", __FUNCTION__, ft1000dev->appcnt);
     ft1000dev->app_info[i].fileobject = NULL;
 
     return 0;
 }
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h
--- linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,91 +1,89 @@
-//---------------------------------------------------------------------------
-// FT1000 driver for Flarion Flash OFDM NIC Device
-//
-// Copyright (C) 2002 Flarion Technologies, All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 of the License, or (at your option) any
-// later version. This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-// more details. You should have received a copy of the GNU General Public
-// License along with this program; if not, write to the
-// Free Software Foundation, Inc., 59 Temple Place -
-// Suite 330, Boston, MA 02111-1307, USA.
-//---------------------------------------------------------------------------
-//
-// File:         ft1000_ioctl.h
-//
-// Description:    Common structures and defines relating to IOCTL
-//
-// History:
-// 11/5/02    Whc                Created.
-//
-//---------------------------------------------------------------------------//---------------------------------------------------------------------------
+/*
+*---------------------------------------------------------------------------
+* FT1000 driver for Flarion Flash OFDM NIC Device
+*
+* Copyright (C) 2002 Flarion Technologies, All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License as published by the Free
+* Software Foundation; either version 2 of the License, or (at your option) any
+* later version. This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+* more details. You should have received a copy of the GNU General Public
+* License along with this program; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place -
+* Suite 330, Boston, MA 02111-1307, USA.
+*---------------------------------------------------------------------------
+*
+* File:         ft1000_ioctl.h
+*
+* Description:    Common structures and defines relating to IOCTL
+*
+* History:
+* 11/5/02    Whc                Created.
+*
+*---------------------------------------------------------------------------//---------------------------------------------------------------------------
+*/
 #ifndef _FT1000IOCTLH_
 #define _FT1000IOCTLH_
 
-typedef struct _IOCTL_GET_VER
-{
+typedef struct _IOCTL_GET_VER {
     unsigned long drv_ver;
 } __attribute__ ((packed)) IOCTL_GET_VER, *PIOCTL_GET_VER;
 
-//Data structure for Dsp statistics
-typedef struct _IOCTL_GET_DSP_STAT
-{
-    unsigned char DspVer[DSPVERSZ];        // DSP version number
-    unsigned char HwSerNum[HWSERNUMSZ];    // Hardware Serial Number
-    unsigned char Sku[SKUSZ];              // SKU
-    unsigned char eui64[EUISZ];            // EUI64
-    unsigned short ConStat;                // Connection Status
-                                //    Bits 0-3 = Connection Status Field
-                                //               0000=Idle (Disconnect)
-                                //               0001=Searching
-                                //               0010=Active (Connected)
-                                //               0011=Waiting for L2 down
-                                //               0100=Sleep
-    unsigned short LedStat;                // Led Status
-                                //    Bits 0-3   = Signal Strength Field
-                                //                 0000 = -105dBm to -92dBm
-                                //                 0001 = -92dBm to -85dBm
-                                //                 0011 = -85dBm to -75dBm
-                                //                 0111 = -75dBm to -50dBm
-                                //                 1111 = -50dBm to 0dBm
-                                //    Bits 4-7   = Reserved
-                                //    Bits 8-11  = SNR Field
-                                //                 0000 = <2dB
-                                //                 0001 = 2dB to 8dB
-                                //                 0011 = 8dB to 15dB
-                                //                 0111 = 15dB to 22dB
-                                //                 1111 = >22dB
-                                //    Bits 12-15 = Reserved
-    unsigned long nTxPkts;                // Number of packets transmitted from host to dsp
-    unsigned long nRxPkts;                // Number of packets received from dsp to host
-    unsigned long nTxBytes;               // Number of bytes transmitted from host to dsp
-    unsigned long nRxBytes;               // Number of bytes received from dsp to host
-    unsigned long ConTm;                  // Current session connection time in seconds
-    unsigned char CalVer[CALVERSZ];       // Proprietary Calibration Version
-    unsigned char CalDate[CALDATESZ];     // Proprietary Calibration Date
+/* Data structure for Dsp statistics */
+typedef struct _IOCTL_GET_DSP_STAT {
+    unsigned char DspVer[DSPVERSZ];        /* DSP version number */
+    unsigned char HwSerNum[HWSERNUMSZ];    /* Hardware Serial Number */
+    unsigned char Sku[SKUSZ];              /* SKU */
+    unsigned char eui64[EUISZ];            /* EUI64 */
+    unsigned short ConStat;                /* Connection Status */
+                                /*    Bits 0-3 = Connection Status Field */
+                                /*               0000=Idle (Disconnect) */
+                                /*               0001=Searching */
+                                /*               0010=Active (Connected) */
+                                /*               0011=Waiting for L2 down */
+                                /*               0100=Sleep */
+    unsigned short LedStat;                /* Led Status */
+                                /*    Bits 0-3   = Signal Strength Field */
+                                /*                 0000 = -105dBm to -92dBm */
+                                /*                 0001 = -92dBm to -85dBm */
+                                /*                 0011 = -85dBm to -75dBm */
+                                /*                 0111 = -75dBm to -50dBm */
+                                /*                 1111 = -50dBm to 0dBm */
+                                /*    Bits 4-7   = Reserved */
+                                /*    Bits 8-11  = SNR Field */
+                                /*                 0000 = <2dB */
+                                /*                 0001 = 2dB to 8dB */
+                                /*                 0011 = 8dB to 15dB */
+                                /*                 0111 = 15dB to 22dB */
+                                /*                 1111 = >22dB */
+                                /*    Bits 12-15 = Reserved */
+    unsigned long nTxPkts;                /* Number of packets transmitted from host to dsp */
+    unsigned long nRxPkts;                /* Number of packets received from dsp to host */
+    unsigned long nTxBytes;               /* Number of bytes transmitted from host to dsp */
+    unsigned long nRxBytes;               /* Number of bytes received from dsp to host */
+    unsigned long ConTm;                  /* Current session connection time in seconds */
+    unsigned char CalVer[CALVERSZ];       /* Proprietary Calibration Version */
+    unsigned char CalDate[CALDATESZ];     /* Proprietary Calibration Date */
 } __attribute__ ((packed)) IOCTL_GET_DSP_STAT, *PIOCTL_GET_DSP_STAT;
 
-//Data structure for Dual Ported RAM messaging between Host and Dsp
-typedef struct _IOCTL_DPRAM_BLK
-{
+/* Data structure for Dual Ported RAM messaging between Host and Dsp */
+typedef struct _IOCTL_DPRAM_BLK {
     unsigned short total_len;
 	struct pseudo_hdr pseudohdr;
     unsigned char buffer[1780];
 } __attribute__ ((packed)) IOCTL_DPRAM_BLK, *PIOCTL_DPRAM_BLK;
 
-typedef struct _IOCTL_DPRAM_COMMAND
-{
+typedef struct _IOCTL_DPRAM_COMMAND {
     unsigned short extra;
     IOCTL_DPRAM_BLK dpram_blk;
 } __attribute__ ((packed)) IOCTL_DPRAM_COMMAND, *PIOCTL_DPRAM_COMMAND;
 
-//
-// Custom IOCTL command codes
-//
+/*
+* Custom IOCTL command codes
+*/
 #define FT1000_MAGIC_CODE      'F'
 
 #define IOCTL_REGISTER_CMD					0
@@ -96,12 +94,12 @@ typedef struct _IOCTL_DPRAM_COMMAND
 #define IOCTL_CONNECT               10
 #define IOCTL_DISCONNECT            11
 
-#define IOCTL_FT1000_GET_DSP_STAT _IOR (FT1000_MAGIC_CODE, IOCTL_GET_DSP_STAT_CMD, sizeof(IOCTL_GET_DSP_STAT) )
-#define IOCTL_FT1000_GET_VER _IOR (FT1000_MAGIC_CODE, IOCTL_GET_VER_CMD, sizeof(IOCTL_GET_VER) )
-#define IOCTL_FT1000_CONNECT _IOW (FT1000_MAGIC_CODE, IOCTL_CONNECT, 0 )
-#define IOCTL_FT1000_DISCONNECT _IOW (FT1000_MAGIC_CODE, IOCTL_DISCONNECT, 0 )
-#define IOCTL_FT1000_SET_DPRAM _IOW (FT1000_MAGIC_CODE, IOCTL_SET_DPRAM_CMD, sizeof(IOCTL_DPRAM_BLK) )
-#define IOCTL_FT1000_GET_DPRAM _IOR (FT1000_MAGIC_CODE, IOCTL_GET_DPRAM_CMD, sizeof(IOCTL_DPRAM_BLK) )
-#define IOCTL_FT1000_REGISTER  _IOW (FT1000_MAGIC_CODE, IOCTL_REGISTER_CMD, sizeof(unsigned short *) )
-#endif // _FT1000IOCTLH_
+#define IOCTL_FT1000_GET_DSP_STAT _IOR(FT1000_MAGIC_CODE, IOCTL_GET_DSP_STAT_CMD, sizeof(IOCTL_GET_DSP_STAT)
+#define IOCTL_FT1000_GET_VER _IOR(FT1000_MAGIC_CODE, IOCTL_GET_VER_CMD, sizeof(IOCTL_GET_VER)
+#define IOCTL_FT1000_CONNECT _IOW(FT1000_MAGIC_CODE, IOCTL_CONNECT, 0
+#define IOCTL_FT1000_DISCONNECT _IOW(FT1000_MAGIC_CODE, IOCTL_DISCONNECT, 0
+#define IOCTL_FT1000_SET_DPRAM _IOW(FT1000_MAGIC_CODE, IOCTL_SET_DPRAM_CMD, sizeof(IOCTL_DPRAM_BLK)
+#define IOCTL_FT1000_GET_DPRAM _IOR(FT1000_MAGIC_CODE, IOCTL_GET_DPRAM_CMD, sizeof(IOCTL_DPRAM_BLK)
+#define IOCTL_FT1000_REGISTER  _IOW(FT1000_MAGIC_CODE, IOCTL_REGISTER_CMD, sizeof(unsigned short *)
+#endif /* _FT1000IOCTLH_ */
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c
--- linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c	2013-08-25 20:43:22.000000000 -0400
@@ -166,7 +166,7 @@ static const struct file_operations ft10
 static int
 ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr)
 {
-	struct net_device *dev = ptr;
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct ft1000_info *info;
 	struct proc_dir_entry *ft1000_proc_file;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c
--- linux-libre-3.10-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c	2013-07-01 10:36:49.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c	2013-08-31 17:56:22.000000000 -0400
@@ -79,8 +79,12 @@ static int ft1000_probe(struct usb_inter
 	ft1000dev->dev = dev;
 	ft1000dev->status = 0;
 	ft1000dev->net = NULL;
-	ft1000dev->tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
-	ft1000dev->rx_urb = usb_alloc_urb(0, GFP_ATOMIC);
+	ft1000dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	ft1000dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!ft1000dev->tx_urb || !ft1000dev->rx_urb) {
+		ret = -ENOMEM;
+		goto err_fw;
+	}
 
 	DEBUG("ft1000_probe is called\n");
 	numaltsetting = interface->num_altsetting;
@@ -209,6 +213,8 @@ err_thread:
 err_load:
 	kfree(pFileStart);
 err_fw:
+	usb_free_urb(ft1000dev->rx_urb);
+	usb_free_urb(ft1000dev->tx_urb);
 	kfree(ft1000dev);
 	return ret;
 }
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/fwserial/fwserial.c linux-libre-3.11-rc7-gnu/drivers/staging/fwserial/fwserial.c
--- linux-libre-3.10-gnu/drivers/staging/fwserial/fwserial.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/fwserial/fwserial.c	2013-08-25 20:43:22.000000000 -0400
@@ -18,6 +18,8 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/device.h>
@@ -101,13 +103,16 @@ struct fwtty_transaction {
 };
 
 #define to_device(a, b)			(a->b)
-#define fwtty_err(p, s, v...)		dev_err(to_device(p, device), s, ##v)
-#define fwtty_info(p, s, v...)		dev_info(to_device(p, device), s, ##v)
-#define fwtty_notice(p, s, v...)	dev_notice(to_device(p, device), s, ##v)
-#define fwtty_dbg(p, s, v...)		\
-		dev_dbg(to_device(p, device), "%s: " s, __func__, ##v)
-#define fwtty_err_ratelimited(p, s, v...) \
-		dev_err_ratelimited(to_device(p, device), s, ##v)
+#define fwtty_err(p, fmt, ...)						\
+	dev_err(to_device(p, device), fmt, ##__VA_ARGS__)
+#define fwtty_info(p, fmt, ...)						\
+	dev_info(to_device(p, device), fmt, ##__VA_ARGS__)
+#define fwtty_notice(p, fmt, ...)					\
+	dev_notice(to_device(p, device), fmt, ##__VA_ARGS__)
+#define fwtty_dbg(p, fmt, ...)						\
+	dev_dbg(to_device(p, device), "%s: " fmt, __func__, ##__VA_ARGS__)
+#define fwtty_err_ratelimited(p, fmt, ...)				\
+	dev_err_ratelimited(to_device(p, device), fmt, ##__VA_ARGS__)
 
 #ifdef DEBUG
 static inline void debug_short_write(struct fwtty_port *port, int c, int n)
@@ -118,7 +123,7 @@ static inline void debug_short_write(str
 		spin_lock_bh(&port->lock);
 		avail = dma_fifo_avail(&port->tx_fifo);
 		spin_unlock_bh(&port->lock);
-		fwtty_dbg(port, "short write: avail:%d req:%d wrote:%d",
+		fwtty_dbg(port, "short write: avail:%d req:%d wrote:%d\n",
 			  avail, c, n);
 	}
 }
@@ -197,22 +202,22 @@ static void fwtty_log_tx_error(struct fw
 {
 	switch (rcode) {
 	case RCODE_SEND_ERROR:
-		fwtty_err_ratelimited(port, "card busy");
+		fwtty_err_ratelimited(port, "card busy\n");
 		break;
 	case RCODE_ADDRESS_ERROR:
-		fwtty_err_ratelimited(port, "bad unit addr or write length");
+		fwtty_err_ratelimited(port, "bad unit addr or write length\n");
 		break;
 	case RCODE_DATA_ERROR:
-		fwtty_err_ratelimited(port, "failed rx");
+		fwtty_err_ratelimited(port, "failed rx\n");
 		break;
 	case RCODE_NO_ACK:
-		fwtty_err_ratelimited(port, "missing ack");
+		fwtty_err_ratelimited(port, "missing ack\n");
 		break;
 	case RCODE_BUSY:
-		fwtty_err_ratelimited(port, "remote busy");
+		fwtty_err_ratelimited(port, "remote busy\n");
 		break;
 	default:
-		fwtty_err_ratelimited(port, "failed tx: %d", rcode);
+		fwtty_err_ratelimited(port, "failed tx: %d\n", rcode);
 	}
 }
 
@@ -287,7 +292,7 @@ static void __fwtty_restart_tx(struct fw
 		schedule_delayed_work(&port->drain, 0);
 	avail = dma_fifo_avail(&port->tx_fifo);
 
-	fwtty_dbg(port, "fifo len: %d avail: %d", len, avail);
+	fwtty_dbg(port, "fifo len: %d avail: %d\n", len, avail);
 }
 
 static void fwtty_restart_tx(struct fwtty_port *port)
@@ -323,7 +328,7 @@ static void fwtty_update_port_status(str
 	if (delta & TIOCM_CTS)
 		++port->icount.cts;
 
-	fwtty_dbg(port, "status: %x delta: %x", status, delta);
+	fwtty_dbg(port, "status: %x delta: %x\n", status, delta);
 
 	if (delta & TIOCM_CAR) {
 		tty = tty_port_tty_get(&port->port);
@@ -509,7 +514,7 @@ static void fwtty_emit_breaks(struct wor
 	n = (elapsed * port->cps) / HZ + 1;
 	port->break_last = now;
 
-	fwtty_dbg(port, "sending %d brks", n);
+	fwtty_dbg(port, "sending %d brks\n", n);
 
 	while (n) {
 		t = min(n, 16);
@@ -570,7 +575,7 @@ static int fwtty_buffer_rx(struct fwtty_
 	size_t size = (n + sizeof(struct buffered_rx) + 0xFF) & ~0xFF;
 
 	if (port->buffered + n > HIGH_WATERMARK) {
-		fwtty_err_ratelimited(port, "overflowed rx buffer: buffered: %d new: %zu wtrmk: %d",
+		fwtty_err_ratelimited(port, "overflowed rx buffer: buffered: %d new: %zu wtrmk: %d\n",
 				      port->buffered, n, HIGH_WATERMARK);
 		return 0;
 	}
@@ -599,7 +604,7 @@ static int fwtty_rx(struct fwtty_port *p
 	unsigned lsr;
 	int err = 0;
 
-	fwtty_dbg(port, "%d", n);
+	fwtty_dbg(port, "%d\n", n);
 	profile_size_distrib(port->stats.reads, n);
 
 	if (port->write_only) {
@@ -689,7 +694,7 @@ static void fwtty_port_handler(struct fw
 	rcu_read_unlock();
 	if (!peer || peer != rcu_access_pointer(port->peer)) {
 		rcode = RCODE_ADDRESS_ERROR;
-		fwtty_err_ratelimited(port, "ignoring unauthenticated data");
+		fwtty_err_ratelimited(port, "ignoring unauthenticated data\n");
 		goto respond;
 	}
 
@@ -746,7 +751,7 @@ static void fwtty_tx_complete(struct fw_
 	struct fwtty_port *port = txn->port;
 	int len;
 
-	fwtty_dbg(port, "rcode: %d", rcode);
+	fwtty_dbg(port, "rcode: %d\n", rcode);
 
 	switch (rcode) {
 	case RCODE_COMPLETE:
@@ -809,7 +814,7 @@ static int fwtty_tx(struct fwtty_port *p
 		n = dma_fifo_out_pend(&port->tx_fifo, &txn->dma_pended);
 		spin_unlock_bh(&port->lock);
 
-		fwtty_dbg(port, "out: %u rem: %d", txn->dma_pended.len, n);
+		fwtty_dbg(port, "out: %u rem: %d\n", txn->dma_pended.len, n);
 
 		if (n < 0) {
 			kmem_cache_free(fwtty_txn_cache, txn);
@@ -819,7 +824,8 @@ static int fwtty_tx(struct fwtty_port *p
 				profile_size_distrib(port->stats.txns, 0);
 			else {
 				++port->stats.fifo_errs;
-				fwtty_err_ratelimited(port, "fifo err: %d", n);
+				fwtty_err_ratelimited(port, "fifo err: %d\n",
+						      n);
 			}
 			break;
 		}
@@ -877,7 +883,7 @@ static void fwtty_write_xchar(struct fwt
 
 	++port->stats.xchars;
 
-	fwtty_dbg(port, "%02x", ch);
+	fwtty_dbg(port, "%02x\n", ch);
 
 	rcu_read_lock();
 	peer = rcu_dereference(port->peer);
@@ -964,7 +970,7 @@ static void fwtty_port_dtr_rts(struct tt
 {
 	struct fwtty_port *port = to_port(tty_port, port);
 
-	fwtty_dbg(port, "on/off: %d", on);
+	fwtty_dbg(port, "on/off: %d\n", on);
 
 	spin_lock_bh(&port->lock);
 	/* Don't change carrier state if this is a console */
@@ -992,7 +998,7 @@ static int fwtty_port_carrier_raised(str
 
 	rc = (port->mstatus & TIOCM_CAR);
 
-	fwtty_dbg(port, "%d", rc);
+	fwtty_dbg(port, "%d\n", rc);
 
 	return rc;
 }
@@ -1177,7 +1183,7 @@ static int fwtty_write(struct tty_struct
 	struct fwtty_port *port = tty->driver_data;
 	int n, len;
 
-	fwtty_dbg(port, "%d", c);
+	fwtty_dbg(port, "%d\n", c);
 	profile_size_distrib(port->stats.writes, c);
 
 	spin_lock_bh(&port->lock);
@@ -1204,7 +1210,7 @@ static int fwtty_write_room(struct tty_s
 	n = dma_fifo_avail(&port->tx_fifo);
 	spin_unlock_bh(&port->lock);
 
-	fwtty_dbg(port, "%d", n);
+	fwtty_dbg(port, "%d\n", n);
 
 	return n;
 }
@@ -1218,7 +1224,7 @@ static int fwtty_chars_in_buffer(struct
 	n = dma_fifo_level(&port->tx_fifo);
 	spin_unlock_bh(&port->lock);
 
-	fwtty_dbg(port, "%d", n);
+	fwtty_dbg(port, "%d\n", n);
 
 	return n;
 }
@@ -1227,7 +1233,7 @@ static void fwtty_send_xchar(struct tty_
 {
 	struct fwtty_port *port = tty->driver_data;
 
-	fwtty_dbg(port, "%02x", ch);
+	fwtty_dbg(port, "%02x\n", ch);
 
 	fwtty_write_xchar(port, ch);
 }
@@ -1254,7 +1260,7 @@ static void fwtty_unthrottle(struct tty_
 {
 	struct fwtty_port *port = tty->driver_data;
 
-	fwtty_dbg(port, "CRTSCTS: %d", (C_CRTSCTS(tty) != 0));
+	fwtty_dbg(port, "CRTSCTS: %d\n", (C_CRTSCTS(tty) != 0));
 
 	profile_fifo_avail(port, port->stats.unthrottle);
 
@@ -1409,7 +1415,7 @@ static int fwtty_break_ctl(struct tty_st
 	struct fwtty_port *port = tty->driver_data;
 	long ret;
 
-	fwtty_dbg(port, "%d", state);
+	fwtty_dbg(port, "%d\n", state);
 
 	if (state == -1) {
 		set_bit(STOP_TX, &port->flags);
@@ -1446,7 +1452,7 @@ static int fwtty_tiocmget(struct tty_str
 	tiocm = (port->mctrl & MCTRL_MASK) | (port->mstatus & ~MCTRL_MASK);
 	spin_unlock_bh(&port->lock);
 
-	fwtty_dbg(port, "%x", tiocm);
+	fwtty_dbg(port, "%x\n", tiocm);
 
 	return tiocm;
 }
@@ -1455,7 +1461,7 @@ static int fwtty_tiocmset(struct tty_str
 {
 	struct fwtty_port *port = tty->driver_data;
 
-	fwtty_dbg(port, "set: %x clear: %x", set, clear);
+	fwtty_dbg(port, "set: %x clear: %x\n", set, clear);
 
 	/* TODO: simulate loopback if TIOCM_LOOP set */
 
@@ -1775,7 +1781,7 @@ static void fwserial_virt_plug_complete(
 	if (port->port.console && port->fwcon_ops->notify != NULL)
 		(*port->fwcon_ops->notify)(FWCON_NOTIFY_ATTACH, port->con_data);
 
-	fwtty_info(&peer->unit, "peer (guid:%016llx) connected on %s",
+	fwtty_info(&peer->unit, "peer (guid:%016llx) connected on %s\n",
 		   (unsigned long long)peer->guid, dev_name(port->device));
 }
 
@@ -1797,7 +1803,7 @@ static inline int fwserial_send_mgmt_syn
 					   pkt, be16_to_cpu(pkt->hdr.len));
 		if (rcode == RCODE_BUSY || rcode == RCODE_SEND_ERROR ||
 		    rcode == RCODE_GENERATION) {
-			fwtty_dbg(&peer->unit, "mgmt write error: %d", rcode);
+			fwtty_dbg(&peer->unit, "mgmt write error: %d\n", rcode);
 			continue;
 		} else
 			break;
@@ -1918,7 +1924,7 @@ static int fwserial_connect_peer(struct
 
 	port = fwserial_find_port(peer);
 	if (!port) {
-		fwtty_err(&peer->unit, "avail ports in use");
+		fwtty_err(&peer->unit, "avail ports in use\n");
 		err = -EBUSY;
 		goto free_pkt;
 	}
@@ -2056,7 +2062,7 @@ static struct fwtty_peer *__fwserial_pee
 		 * has created its remote unit device before this driver has
 		 * been probed for any unit devices...
 		 */
-		fwtty_err(card, "unknown card (guid %016llx)",
+		fwtty_err(card, "unknown card (guid %016llx)\n",
 			  (unsigned long long) card->guid);
 		return NULL;
 	}
@@ -2084,8 +2090,8 @@ static void __dump_peer_list(struct fw_c
 	list_for_each_entry_rcu(peer, &serial->peer_list, list) {
 		int g = peer->generation;
 		smp_rmb();
-		fwtty_dbg(card, "peer(%d:%x) guid: %016llx\n", g,
-			  peer->node_id, (unsigned long long) peer->guid);
+		fwtty_dbg(card, "peer(%d:%x) guid: %016llx\n",
+			  g, peer->node_id, (unsigned long long) peer->guid);
 	}
 }
 #else
@@ -2173,7 +2179,7 @@ static int fwserial_add_peer(struct fw_s
 	peer->serial = serial;
 	list_add_rcu(&peer->list, &serial->peer_list);
 
-	fwtty_info(&peer->unit, "peer added (guid:%016llx)",
+	fwtty_info(&peer->unit, "peer added (guid:%016llx)\n",
 		   (unsigned long long)peer->guid);
 
 	/* identify the local unit & virt cable to loopback port */
@@ -2236,7 +2242,7 @@ static void fwserial_remove_peer(struct
 
 	list_del_rcu(&peer->list);
 
-	fwtty_info(&peer->unit, "peer removed (guid:%016llx)",
+	fwtty_info(&peer->unit, "peer removed (guid:%016llx)\n",
 		   (unsigned long long)peer->guid);
 
 	spin_unlock_bh(&peer->lock);
@@ -2324,7 +2330,7 @@ static int fwserial_create(struct fw_uni
 
 	err = fwtty_ports_add(serial);
 	if (err) {
-		fwtty_err(&unit, "no space in port table");
+		fwtty_err(&unit, "no space in port table\n");
 		goto free_ports;
 	}
 
@@ -2335,7 +2341,8 @@ static int fwserial_create(struct fw_uni
 						   card->device);
 		if (IS_ERR(tty_dev)) {
 			err = PTR_ERR(tty_dev);
-			fwtty_err(&unit, "register tty device error (%d)", err);
+			fwtty_err(&unit, "register tty device error (%d)\n",
+				  err);
 			goto unregister_ttys;
 		}
 
@@ -2352,7 +2359,8 @@ static int fwserial_create(struct fw_uni
 						    card->device);
 		if (IS_ERR(loop_dev)) {
 			err = PTR_ERR(loop_dev);
-			fwtty_err(&unit, "create loop device failed (%d)", err);
+			fwtty_err(&unit, "create loop device failed (%d)\n",
+				  err);
 			goto unregister_ttys;
 		}
 		serial->ports[j]->device = loop_dev;
@@ -2372,14 +2380,14 @@ static int fwserial_create(struct fw_uni
 
 	list_add_rcu(&serial->list, &fwserial_list);
 
-	fwtty_notice(&unit, "TTY over FireWire on device %s (guid %016llx)",
+	fwtty_notice(&unit, "TTY over FireWire on device %s (guid %016llx)\n",
 		     dev_name(card->device), (unsigned long long) card->guid);
 
 	err = fwserial_add_peer(serial, unit);
 	if (!err)
 		return 0;
 
-	fwtty_err(&unit, "unable to add peer unit device (%d)", err);
+	fwtty_err(&unit, "unable to add peer unit device (%d)\n", err);
 
 	/* fall-through to error processing */
 	debugfs_remove_recursive(serial->debugfs);
@@ -2438,9 +2446,9 @@ free_ports:
  * last peer for a given fw_card triggering the destruction of the same
  * fw_serial for the same fw_card.
  */
-static int fwserial_probe(struct device *dev)
+static int fwserial_probe(struct fw_unit *unit,
+			  const struct ieee1394_device_id *id)
 {
-	struct fw_unit *unit = fw_unit(dev);
 	struct fw_serial *serial;
 	int err;
 
@@ -2462,9 +2470,9 @@ static int fwserial_probe(struct device
  * specific fw_card). If this is the last peer being removed, then trigger
  * the destruction of the underlying TTYs.
  */
-static int fwserial_remove(struct device *dev)
+static void fwserial_remove(struct fw_unit *unit)
 {
-	struct fwtty_peer *peer = dev_get_drvdata(dev);
+	struct fwtty_peer *peer = dev_get_drvdata(&unit->device);
 	struct fw_serial *serial = peer->serial;
 	int i;
 
@@ -2484,8 +2492,6 @@ static int fwserial_remove(struct device
 		kref_put(&serial->kref, fwserial_destroy);
 	}
 	mutex_unlock(&fwserial_list_mutex);
-
-	return 0;
 }
 
 /**
@@ -2530,10 +2536,10 @@ static struct fw_driver fwserial_driver
 		.owner  = THIS_MODULE,
 		.name   = KBUILD_MODNAME,
 		.bus    = &fw_bus_type,
-		.probe  = fwserial_probe,
-		.remove = fwserial_remove,
 	},
+	.probe    = fwserial_probe,
 	.update   = fwserial_update,
+	.remove   = fwserial_remove,
 	.id_table = fwserial_id_table,
 };
 
@@ -2621,7 +2627,7 @@ static void fwserial_handle_plug_req(str
 	switch (peer->state) {
 	case FWPS_NOT_ATTACHED:
 		if (!port) {
-			fwtty_err(&peer->unit, "no more ports avail");
+			fwtty_err(&peer->unit, "no more ports avail\n");
 			fill_plug_rsp_nack(pkt);
 		} else {
 			peer->port = port;
@@ -2663,7 +2669,7 @@ static void fwserial_handle_plug_req(str
 			fwtty_write_port_status(tmp);
 			spin_lock_bh(&peer->lock);
 		} else {
-			fwtty_err(&peer->unit, "PLUG_RSP error (%d)", rcode);
+			fwtty_err(&peer->unit, "PLUG_RSP error (%d)\n", rcode);
 			port = peer_revert_state(peer);
 		}
 	}
@@ -2715,7 +2721,8 @@ static void fwserial_handle_unplug_req(s
 	spin_lock_bh(&peer->lock);
 	if (peer->state == FWPS_UNPLUG_RESPONDING) {
 		if (rcode != RCODE_COMPLETE)
-			fwtty_err(&peer->unit, "UNPLUG_RSP error (%d)", rcode);
+			fwtty_err(&peer->unit, "UNPLUG_RSP error (%d)\n",
+				  rcode);
 		port = peer_revert_state(peer);
 	}
 cleanup:
@@ -2750,19 +2757,19 @@ static int fwserial_parse_mgmt_write(str
 		 * already removed from the bus -- and the removal was
 		 * processed before we rec'd this transaction
 		 */
-		fwtty_err(&peer->unit, "peer already removed");
+		fwtty_err(&peer->unit, "peer already removed\n");
 		spin_unlock_bh(&peer->lock);
 		return RCODE_ADDRESS_ERROR;
 	}
 
 	rcode = RCODE_COMPLETE;
 
-	fwtty_dbg(&peer->unit, "mgmt: hdr.code: %04hx", pkt->hdr.code);
+	fwtty_dbg(&peer->unit, "mgmt: hdr.code: %04hx\n", pkt->hdr.code);
 
 	switch (be16_to_cpu(pkt->hdr.code) & FWSC_CODE_MASK) {
 	case FWSC_VIRT_CABLE_PLUG:
 		if (work_pending(&peer->work)) {
-			fwtty_err(&peer->unit, "plug req: busy");
+			fwtty_err(&peer->unit, "plug req: busy\n");
 			rcode = RCODE_CONFLICT_ERROR;
 
 		} else {
@@ -2777,7 +2784,7 @@ static int fwserial_parse_mgmt_write(str
 			rcode = RCODE_CONFLICT_ERROR;
 
 		} else if (be16_to_cpu(pkt->hdr.code) & FWSC_RSP_NACK) {
-			fwtty_notice(&peer->unit, "NACK plug rsp");
+			fwtty_notice(&peer->unit, "NACK plug rsp\n");
 			port = peer_revert_state(peer);
 
 		} else {
@@ -2793,7 +2800,7 @@ static int fwserial_parse_mgmt_write(str
 
 	case FWSC_VIRT_CABLE_UNPLUG:
 		if (work_pending(&peer->work)) {
-			fwtty_err(&peer->unit, "unplug req: busy");
+			fwtty_err(&peer->unit, "unplug req: busy\n");
 			rcode = RCODE_CONFLICT_ERROR;
 		} else {
 			PREPARE_WORK(&peer->work, fwserial_handle_unplug_req);
@@ -2806,14 +2813,14 @@ static int fwserial_parse_mgmt_write(str
 			rcode = RCODE_CONFLICT_ERROR;
 		else {
 			if (be16_to_cpu(pkt->hdr.code) & FWSC_RSP_NACK)
-				fwtty_notice(&peer->unit, "NACK unplug?");
+				fwtty_notice(&peer->unit, "NACK unplug?\n");
 			port = peer_revert_state(peer);
 			reset = true;
 		}
 		break;
 
 	default:
-		fwtty_err(&peer->unit, "unknown mgmt code %d",
+		fwtty_err(&peer->unit, "unknown mgmt code %d\n",
 			  be16_to_cpu(pkt->hdr.code));
 		rcode = RCODE_DATA_ERROR;
 	}
@@ -2847,7 +2854,7 @@ static void fwserial_mgmt_handler(struct
 	rcu_read_lock();
 	peer = __fwserial_peer_by_node_id(card, generation, source);
 	if (!peer) {
-		fwtty_dbg(card, "peer(%d:%x) not found", generation, source);
+		fwtty_dbg(card, "peer(%d:%x) not found\n", generation, source);
 		__dump_peer_list(card);
 		rcode = RCODE_CONFLICT_ERROR;
 
@@ -2897,7 +2904,7 @@ static int __init fwserial_init(void)
 
 	err = tty_register_driver(fwtty_driver);
 	if (err) {
-		driver_err("register tty driver failed (%d)", err);
+		pr_err("register tty driver failed (%d)\n", err);
 		goto put_tty;
 	}
 
@@ -2922,7 +2929,7 @@ static int __init fwserial_init(void)
 
 		err = tty_register_driver(fwloop_driver);
 		if (err) {
-			driver_err("register loop driver failed (%d)", err);
+			pr_err("register loop driver failed (%d)\n", err);
 			goto put_loop;
 		}
 	}
@@ -2948,7 +2955,7 @@ static int __init fwserial_init(void)
 	err = fw_core_add_address_handler(&fwserial_mgmt_addr_handler,
 					  &fwserial_mgmt_addr_region);
 	if (err) {
-		driver_err("add management handler failed (%d)", err);
+		pr_err("add management handler failed (%d)\n", err);
 		goto destroy_cache;
 	}
 
@@ -2956,13 +2963,13 @@ static int __init fwserial_init(void)
 		FW_UNIT_ADDRESS(fwserial_mgmt_addr_handler.offset);
 	err = fw_core_add_descriptor(&fwserial_unit_directory);
 	if (err) {
-		driver_err("add unit descriptor failed (%d)", err);
+		pr_err("add unit descriptor failed (%d)\n", err);
 		goto remove_handler;
 	}
 
 	err = driver_register(&fwserial_driver.driver);
 	if (err) {
-		driver_err("register fwserial driver failed (%d)", err);
+		pr_err("register fwserial driver failed (%d)\n", err);
 		goto remove_descriptor;
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/fwserial/fwserial.h linux-libre-3.11-rc7-gnu/drivers/staging/fwserial/fwserial.h
--- linux-libre-3.10-gnu/drivers/staging/fwserial/fwserial.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/fwserial/fwserial.h	2013-08-25 20:43:22.000000000 -0400
@@ -356,8 +356,6 @@ static const char loop_dev_name[] = "fwl
 
 extern struct tty_driver *fwtty_driver;
 
-#define driver_err(s, v...)	pr_err(KBUILD_MODNAME ": " s, ##v)
-
 struct fwtty_port *fwtty_port_get(unsigned index);
 void fwtty_port_put(struct fwtty_port *port);
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/gdm72xx/gdm_qos.c linux-libre-3.11-rc7-gnu/drivers/staging/gdm72xx/gdm_qos.c
--- linux-libre-3.10-gnu/drivers/staging/gdm72xx/gdm_qos.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/gdm72xx/gdm_qos.c	2013-08-25 20:43:22.000000000 -0400
@@ -250,8 +250,8 @@ static void send_qos_list(struct nic *ni
 
 	list_for_each_entry_safe(entry, n, head, list) {
 		list_del(&entry->list);
-		free_qos_entry(entry);
 		gdm_wimax_send_tx(entry->skb, entry->dev);
+		free_qos_entry(entry);
 	}
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/gdm72xx/gdm_wimax.c linux-libre-3.11-rc7-gnu/drivers/staging/gdm72xx/gdm_wimax.c
--- linux-libre-3.10-gnu/drivers/staging/gdm72xx/gdm_wimax.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/gdm72xx/gdm_wimax.c	2013-08-25 20:43:22.000000000 -0400
@@ -939,8 +939,7 @@ int register_wimax_device(struct phy_dev
 	struct net_device *dev;
 	int ret;
 
-	dev = (struct net_device *)alloc_netdev(sizeof(*nic),
-						"wm%d", ether_setup);
+	dev = alloc_netdev(sizeof(*nic), "wm%d", ether_setup);
 
 	if (dev == NULL) {
 		pr_err("alloc_etherdev failed\n");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/gdm72xx/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/gdm72xx/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/gdm72xx/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/gdm72xx/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -4,7 +4,7 @@
 
 menuconfig WIMAX_GDM72XX
 	tristate "GCT GDM72xx WiMAX support"
-	depends on NET
+	depends on NET && (USB || MMC)
 	help
 	  Support for the GCT GDM72xx WiMAX chip
 
@@ -19,7 +19,7 @@ config WIMAX_GDM72XX_K_MODE
 	default n
 
 config WIMAX_GDM72XX_WIMAX2
-	bool "Enable WIMAX2 support"
+	bool "Enable WiMAX2 support"
 	default n
 
 choice
@@ -27,18 +27,18 @@ choice
 
 config WIMAX_GDM72XX_USB
 	bool "USB interface"
-	depends on USB
+	depends on (USB = y || USB = WIMAX_GDM72XX)
 
 config WIMAX_GDM72XX_SDIO
 	bool "SDIO interface"
-	depends on MMC
+	depends on (MMC = y || MMC = WIMAX_GDM72XX)
 
 endchoice
 
 if WIMAX_GDM72XX_USB
 
 config WIMAX_GDM72XX_USB_PM
-	bool "Enable power managerment support"
+	bool "Enable power management support"
 	depends on PM_RUNTIME
 
 endif # WIMAX_GDM72XX_USB
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/goldfish/goldfish_audio.c linux-libre-3.11-rc7-gnu/drivers/staging/goldfish/goldfish_audio.c
--- linux-libre-3.10-gnu/drivers/staging/goldfish/goldfish_audio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/goldfish/goldfish_audio.c	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,5 @@
-/* drivers/misc/goldfish_audio.c
+/*
+ * drivers/misc/goldfish_audio.c
  *
  * Copyright (C) 2007 Google, Inc.
  * Copyright (C) 2012 Intel, Inc.
@@ -47,10 +48,11 @@ struct goldfish_audio {
 	int read_supported;         /* true if we have audio input support */
 };
 
-/* We will allocate two read buffers and two write buffers.
-   Having two read buffers facilitate stereo -> mono conversion.
-   Having two write buffers facilitate interleaved IO.
-*/
+/*
+ *  We will allocate two read buffers and two write buffers.
+ *  Having two read buffers facilitate stereo -> mono conversion.
+ *  Having two write buffers facilitate interleaved IO.
+ */
 #define READ_BUFFER_SIZE        16384
 #define WRITE_BUFFER_SIZE       16384
 #define COMBINED_BUFFER_SIZE    ((2 * READ_BUFFER_SIZE) + \
@@ -59,8 +61,10 @@ struct goldfish_audio {
 #define AUDIO_READ(data, addr)		(readl(data->reg_base + addr))
 #define AUDIO_WRITE(data, addr, x)	(writel(x, data->reg_base + addr))
 
-/* temporary variable used between goldfish_audio_probe() and
-   goldfish_audio_open() */
+/*
+ *  temporary variable used between goldfish_audio_probe() and
+ *  goldfish_audio_open()
+ */
 static struct goldfish_audio *audio_data;
 
 enum {
@@ -161,8 +165,10 @@ static ssize_t goldfish_audio_write(stru
 		}
 
 		spin_lock_irqsave(&data->lock, irq_flags);
-		/* clear the buffer empty flag, and signal the emulator
-		 * to start writing the buffer */
+		/*
+		 *  clear the buffer empty flag, and signal the emulator
+		 *  to start writing the buffer
+		 */
 		if (kbuf == data->write_buffer1) {
 			data->buffer_status &= ~AUDIO_INT_WRITE_BUFFER_1_EMPTY;
 			AUDIO_WRITE(data, AUDIO_WRITE_BUFFER_1, copy);
@@ -225,8 +231,10 @@ static irqreturn_t goldfish_audio_interr
 	/* read buffer status flags */
 	status = AUDIO_READ(data, AUDIO_INT_STATUS);
 	status &= AUDIO_INT_MASK;
-	/* if buffers are newly empty, wake up blocked
-	   goldfish_audio_write() call */
+	/*
+	 *  if buffers are newly empty, wake up blocked
+	 *  goldfish_audio_write() call
+	 */
 	if (status) {
 		data->buffer_status = status;
 		wake_up(&data->wait);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/goldfish/goldfish_nand.c linux-libre-3.11-rc7-gnu/drivers/staging/goldfish/goldfish_nand.c
--- linux-libre-3.10-gnu/drivers/staging/goldfish/goldfish_nand.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/goldfish/goldfish_nand.c	2013-08-25 20:43:22.000000000 -0400
@@ -326,9 +326,10 @@ static int goldfish_nand_init_device(str
 			(mtd->writesize + mtd->oobsize) * mtd->writesize;
 	do_div(mtd->size, mtd->writesize + mtd->oobsize);
 	mtd->size *= mtd->writesize;
-	dev_dbg(&pdev->dev, 
+	dev_dbg(&pdev->dev,
 		"goldfish nand dev%d: size %llx, page %d, extra %d, erase %d\n",
-		       id, mtd->size, mtd->writesize, mtd->oobsize, mtd->erasesize);
+		       id, mtd->size, mtd->writesize,
+		       mtd->oobsize, mtd->erasesize);
 	spin_unlock_irqrestore(&nand->lock, irq_flags);
 
 	mtd->priv = nand;
@@ -340,7 +341,7 @@ static int goldfish_nand_init_device(str
 	result = goldfish_nand_cmd(mtd, NAND_CMD_GET_DEV_NAME, 0, name_len,
 									name);
 	if (result != name_len) {
-		dev_err(&pdev->dev, 
+		dev_err(&pdev->dev,
 			"goldfish_nand_init_device failed to get dev name %d != %d\n",
 			       result, name_len);
 		return -ENODEV;
@@ -391,7 +392,7 @@ static int goldfish_nand_probe(struct pl
 
 	version = readl(base + NAND_VERSION);
 	if (version != NAND_VERSION_CURRENT) {
-		dev_err(&pdev->dev, 
+		dev_err(&pdev->dev,
 			"goldfish_nand_init: version mismatch, got %d, expected %d\n",
 				version, NAND_VERSION_CURRENT);
 		return -ENODEV;
@@ -400,7 +401,7 @@ static int goldfish_nand_probe(struct pl
 	if (num_dev == 0)
 		return -ENODEV;
 
-	nand = devm_kzalloc(&pdev->dev, sizeof(*nand) + 
+	nand = devm_kzalloc(&pdev->dev, sizeof(*nand) +
 				sizeof(struct mtd_info) * num_dev, GFP_KERNEL);
 	if (nand == NULL)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/goldfish/goldfish_nand_reg.h linux-libre-3.11-rc7-gnu/drivers/staging/goldfish/goldfish_nand_reg.h
--- linux-libre-3.10-gnu/drivers/staging/goldfish/goldfish_nand_reg.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/goldfish/goldfish_nand_reg.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,27 +1,30 @@
-/* drivers/mtd/devices/goldfish_nand_reg.h
-**
-** Copyright (C) 2007 Google, Inc.
-**
-** This software is licensed under the terms of the GNU General Public
-** License version 2, as published by the Free Software Foundation, and
-** may be copied, distributed, and modified under those terms.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-** GNU General Public License for more details.
-**
-*/
+/*
+ * drivers/mtd/devices/goldfish_nand_reg.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
 
 #ifndef GOLDFISH_NAND_REG_H
 #define GOLDFISH_NAND_REG_H
 
 enum nand_cmd {
-	NAND_CMD_GET_DEV_NAME,  /* Write device name for NAND_DEV to NAND_DATA (vaddr) */
+	/* Write device name for NAND_DEV to NAND_DATA (vaddr) */
+	NAND_CMD_GET_DEV_NAME,
 	NAND_CMD_READ,
 	NAND_CMD_WRITE,
 	NAND_CMD_ERASE,
-	NAND_CMD_BLOCK_BAD_GET, /* NAND_RESULT is 1 if block is bad, 0 if it is not */
+	/* NAND_RESULT is 1 if block is bad, 0 if it is not */
+	NAND_CMD_BLOCK_BAD_GET,
 	NAND_CMD_BLOCK_BAD_SET,
 	NAND_CMD_READ_WITH_PARAMS,
 	NAND_CMD_WRITE_WITH_PARAMS,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/accel/lis3l02dq_core.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/accel/lis3l02dq_core.c
--- linux-libre-3.10-gnu/drivers/staging/iio/accel/lis3l02dq_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/accel/lis3l02dq_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -257,6 +257,8 @@ static int lis3l02dq_read_raw(struct iio
 			ret = lis3l02dq_read_reg_s16(indio_dev, reg, val);
 		}
 		mutex_unlock(&indio_dev->mlock);
+		if (ret < 0)
+			goto error_ret;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7192.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7192.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7192.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7192.c	2013-08-25 20:43:22.000000000 -0400
@@ -326,7 +326,7 @@ static ssize_t ad7192_write_frequency(st
 	unsigned long lval;
 	int div, ret;
 
-	ret = strict_strtoul(buf, 10, &lval);
+	ret = kstrtoul(buf, 10, &lval);
 	if (ret)
 		return ret;
 	if (lval == 0)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7280a.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7280a.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7280a.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7280a.c	2013-08-25 20:43:22.000000000 -0400
@@ -632,7 +632,7 @@ static ssize_t ad7280_write_channel_conf
 	long val;
 	int ret;
 
-	ret = strict_strtol(buf, 10, &val);
+	ret = kstrtol(buf, 10, &val);
 	if (ret)
 		return ret;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7291.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7291.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7291.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7291.c	2013-08-25 20:43:22.000000000 -0400
@@ -21,6 +21,8 @@
 #include <linux/iio/sysfs.h>
 #include <linux/iio/events.h>
 
+#include "ad7291.h"
+
 /*
  * Simplified handling
  *
@@ -39,33 +41,9 @@
 #define AD7291_VOLTAGE			0x01
 #define AD7291_T_SENSE			0x02
 #define AD7291_T_AVERAGE		0x03
-#define AD7291_CH0_DATA_HIGH		0x04
-#define AD7291_CH0_DATA_LOW		0x05
-#define AD7291_CH0_HYST			0x06
-#define AD7291_CH1_DATA_HIGH		0x07
-#define AD7291_CH1_DATA_LOW		0x08
-#define AD7291_CH1_HYST			0x09
-#define AD7291_CH2_DATA_HIGH		0x0A
-#define AD7291_CH2_DATA_LOW		0x0B
-#define AD7291_CH2_HYST			0x0C
-#define AD7291_CH3_DATA_HIGH		0x0D
-#define AD7291_CH3_DATA_LOW		0x0E
-#define AD7291_CH3_HYST			0x0F
-#define AD7291_CH4_DATA_HIGH		0x10
-#define AD7291_CH4_DATA_LOW		0x11
-#define AD7291_CH4_HYST			0x12
-#define AD7291_CH5_DATA_HIGH		0x13
-#define AD7291_CH5_DATA_LOW		0x14
-#define AD7291_CH5_HYST			0x15
-#define AD7291_CH6_DATA_HIGH		0x16
-#define AD7291_CH6_DATA_LOW		0x17
-#define AD7291_CH6_HYST			0x18
-#define AD7291_CH7_DATA_HIGH		0x19
-#define AD7291_CH7_DATA_LOW		0x1A
-#define AD7291_CH7_HYST			0x2B
-#define AD7291_T_SENSE_HIGH		0x1C
-#define AD7291_T_SENSE_LOW		0x1D
-#define AD7291_T_SENSE_HYST		0x1E
+#define AD7291_DATA_HIGH(x)		((x) * 3 + 0x4)
+#define AD7291_DATA_LOW(x)		((x) * 3 + 0x5)
+#define AD7291_HYST(x)			((x) * 3 + 0x6)
 #define AD7291_VOLTAGE_ALERT_STATUS	0x1F
 #define AD7291_T_ALERT_STATUS		0x20
 
@@ -100,7 +78,6 @@
 struct ad7291_chip_info {
 	struct i2c_client	*client;
 	struct regulator	*reg;
-	u16			int_vref_mv;
 	u16			command;
 	u16			c_mask;	/* Active voltage channels for events */
 	struct mutex		state_lock;
@@ -111,45 +88,22 @@ static int ad7291_i2c_read(struct ad7291
 	struct i2c_client *client = chip->client;
 	int ret = 0;
 
-	ret = i2c_smbus_read_word_data(client, reg);
+	ret = i2c_smbus_read_word_swapped(client, reg);
 	if (ret < 0) {
 		dev_err(&client->dev, "I2C read error\n");
 		return ret;
 	}
 
-	*data = swab16((u16)ret);
+	*data = ret;
 
 	return 0;
 }
 
 static int ad7291_i2c_write(struct ad7291_chip_info *chip, u8 reg, u16 data)
 {
-	return i2c_smbus_write_word_data(chip->client, reg, swab16(data));
-}
-
-static ssize_t ad7291_store_reset(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct ad7291_chip_info *chip = iio_priv(indio_dev);
-
-	return ad7291_i2c_write(chip, AD7291_COMMAND,
-				chip->command | AD7291_RESET);
+	return i2c_smbus_write_word_swapped(chip->client, reg, data);
 }
 
-static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, ad7291_store_reset, 0);
-
-static struct attribute *ad7291_attributes[] = {
-	&iio_dev_attr_reset.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ad7291_attribute_group = {
-	.attrs = ad7291_attributes,
-};
-
 static irqreturn_t ad7291_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
@@ -255,31 +209,31 @@ static inline ssize_t ad7291_set_hyst(st
 static IIO_DEVICE_ATTR(in_temp0_thresh_both_hyst_raw,
 		       S_IRUGO | S_IWUSR,
 		       ad7291_show_hyst, ad7291_set_hyst,
-		       AD7291_T_SENSE_HYST);
+		       AD7291_HYST(8));
 static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
 		       S_IRUGO | S_IWUSR,
-		       ad7291_show_hyst, ad7291_set_hyst, AD7291_CH0_HYST);
+		       ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(0));
 static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
 		       S_IRUGO | S_IWUSR,
-		       ad7291_show_hyst, ad7291_set_hyst, AD7291_CH1_HYST);
+		       ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(1));
 static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
 		       S_IRUGO | S_IWUSR,
-		       ad7291_show_hyst, ad7291_set_hyst, AD7291_CH2_HYST);
+		       ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(2));
 static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
 		       S_IRUGO | S_IWUSR,
-		       ad7291_show_hyst, ad7291_set_hyst, AD7291_CH3_HYST);
+		       ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(3));
 static IIO_DEVICE_ATTR(in_voltage4_thresh_both_hyst_raw,
 		       S_IRUGO | S_IWUSR,
-		       ad7291_show_hyst, ad7291_set_hyst, AD7291_CH4_HYST);
+		       ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(4));
 static IIO_DEVICE_ATTR(in_voltage5_thresh_both_hyst_raw,
 		       S_IRUGO | S_IWUSR,
-		       ad7291_show_hyst, ad7291_set_hyst, AD7291_CH5_HYST);
+		       ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(5));
 static IIO_DEVICE_ATTR(in_voltage6_thresh_both_hyst_raw,
 		       S_IRUGO | S_IWUSR,
-		       ad7291_show_hyst, ad7291_set_hyst, AD7291_CH6_HYST);
+		       ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(6));
 static IIO_DEVICE_ATTR(in_voltage7_thresh_both_hyst_raw,
 		       S_IRUGO | S_IWUSR,
-		       ad7291_show_hyst, ad7291_set_hyst, AD7291_CH7_HYST);
+		       ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(7));
 
 static struct attribute *ad7291_event_attributes[] = {
 	&iio_dev_attr_in_temp0_thresh_both_hyst_raw.dev_attr.attr,
@@ -294,53 +248,45 @@ static struct attribute *ad7291_event_at
 	NULL,
 };
 
-/* high / low */
-static u8 ad7291_limit_regs[9][2] = {
-	{ AD7291_CH0_DATA_HIGH, AD7291_CH0_DATA_LOW },
-	{ AD7291_CH1_DATA_HIGH, AD7291_CH1_DATA_LOW },
-	{ AD7291_CH2_DATA_HIGH, AD7291_CH2_DATA_LOW },
-	{ AD7291_CH3_DATA_HIGH, AD7291_CH3_DATA_LOW }, /* FIXME: ? */
-	{ AD7291_CH4_DATA_HIGH, AD7291_CH4_DATA_LOW },
-	{ AD7291_CH5_DATA_HIGH, AD7291_CH5_DATA_LOW },
-	{ AD7291_CH6_DATA_HIGH, AD7291_CH6_DATA_LOW },
-	{ AD7291_CH7_DATA_HIGH, AD7291_CH7_DATA_LOW },
-	/* temp */
-	{ AD7291_T_SENSE_HIGH, AD7291_T_SENSE_LOW },
-};
+static unsigned int ad7291_threshold_reg(u64 event_code)
+{
+	unsigned int offset;
+
+	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+	case IIO_VOLTAGE:
+		offset = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+		break;
+	case IIO_TEMP:
+		offset = 8;
+		break;
+	default:
+	    return 0;
+	}
+
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
+		return AD7291_DATA_LOW(offset);
+	else
+		return AD7291_DATA_HIGH(offset);
+}
 
 static int ad7291_read_event_value(struct iio_dev *indio_dev,
 				   u64 event_code,
 				   int *val)
 {
 	struct ad7291_chip_info *chip = iio_priv(indio_dev);
-
 	int ret;
-	u8 reg;
 	u16 uval;
-	s16 signval;
+
+	ret = ad7291_i2c_read(chip, ad7291_threshold_reg(event_code), &uval);
+	if (ret < 0)
+		return ret;
 
 	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
 	case IIO_VOLTAGE:
-		reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]
-			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-			   IIO_EV_DIR_RISING)];
-
-		ret = ad7291_i2c_read(chip, reg, &uval);
-		if (ret < 0)
-			return ret;
 		*val = uval & AD7291_VALUE_MASK;
 		return 0;
-
 	case IIO_TEMP:
-		reg = ad7291_limit_regs[8]
-			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-			   IIO_EV_DIR_RISING)];
-
-		ret = ad7291_i2c_read(chip, reg, &signval);
-		if (ret < 0)
-			return ret;
-		signval = (s16)((signval & AD7291_VALUE_MASK) << 4) >> 4;
-		*val = signval;
+		*val = sign_extend32(uval, 11);
 		return 0;
 	default:
 		return -EINVAL;
@@ -352,28 +298,21 @@ static int ad7291_write_event_value(stru
 				    int val)
 {
 	struct ad7291_chip_info *chip = iio_priv(indio_dev);
-	u8 reg;
-	s16 signval;
 
 	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
 	case IIO_VOLTAGE:
 		if (val > AD7291_VALUE_MASK || val < 0)
 			return -EINVAL;
-		reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]
-			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-			   IIO_EV_DIR_RISING)];
-		return ad7291_i2c_write(chip, reg, val);
+		break;
 	case IIO_TEMP:
 		if (val > 2047 || val < -2048)
 			return -EINVAL;
-		reg = ad7291_limit_regs[8]
-			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-			   IIO_EV_DIR_RISING)];
-		signval = val;
-		return ad7291_i2c_write(chip, reg, *(u16 *)&signval);
+		break;
 	default:
 		return -EINVAL;
-	};
+	}
+
+	return ad7291_i2c_write(chip, ad7291_threshold_reg(event_code), val);
 }
 
 static int ad7291_read_event_config(struct iio_dev *indio_dev,
@@ -456,9 +395,7 @@ static int ad7291_read_raw(struct iio_de
 {
 	int ret;
 	struct ad7291_chip_info *chip = iio_priv(indio_dev);
-	unsigned int scale_uv;
 	u16 regval;
-	s16 signval;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -479,44 +416,47 @@ static int ad7291_read_raw(struct iio_de
 				return ret;
 			}
 			/* Read voltage */
-			ret = i2c_smbus_read_word_data(chip->client,
+			ret = i2c_smbus_read_word_swapped(chip->client,
 						       AD7291_VOLTAGE);
 			if (ret < 0) {
 				mutex_unlock(&chip->state_lock);
 				return ret;
 			}
-			*val = swab16((u16)ret) & AD7291_VALUE_MASK;
+			*val = ret & AD7291_VALUE_MASK;
 			mutex_unlock(&chip->state_lock);
 			return IIO_VAL_INT;
 		case IIO_TEMP:
 			/* Assumes tsense bit of command register always set */
-			ret = i2c_smbus_read_word_data(chip->client,
+			ret = i2c_smbus_read_word_swapped(chip->client,
 						       AD7291_T_SENSE);
 			if (ret < 0)
 				return ret;
-			signval = (s16)((swab16((u16)ret) &
-				AD7291_VALUE_MASK) << 4) >> 4;
-			*val = signval;
+			*val = sign_extend32(ret, 11);
 			return IIO_VAL_INT;
 		default:
 			return -EINVAL;
 		}
 	case IIO_CHAN_INFO_AVERAGE_RAW:
-		ret = i2c_smbus_read_word_data(chip->client,
+		ret = i2c_smbus_read_word_swapped(chip->client,
 					       AD7291_T_AVERAGE);
 			if (ret < 0)
 				return ret;
-			signval = (s16)((swab16((u16)ret) &
-				AD7291_VALUE_MASK) << 4) >> 4;
-			*val = signval;
+			*val = sign_extend32(ret, 11);
 			return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		case IIO_VOLTAGE:
-			scale_uv = (chip->int_vref_mv * 1000) >> AD7291_BITS;
-			*val =  scale_uv / 1000;
-			*val2 = (scale_uv % 1000) * 1000;
-			return IIO_VAL_INT_PLUS_MICRO;
+			if (chip->reg) {
+				int vref;
+				vref = regulator_get_voltage(chip->reg);
+				if (vref < 0)
+					return vref;
+				*val = vref / 1000;
+			} else {
+				*val = 2500;
+			}
+			*val2 = AD7291_BITS;
+			return IIO_VAL_FRACTIONAL_LOG2;
 		case IIO_TEMP:
 			/*
 			 * One LSB of the ADC corresponds to 0.25 deg C.
@@ -571,21 +511,22 @@ static struct attribute_group ad7291_eve
 };
 
 static const struct iio_info ad7291_info = {
-	.attrs = &ad7291_attribute_group,
 	.read_raw = &ad7291_read_raw,
 	.read_event_config = &ad7291_read_event_config,
 	.write_event_config = &ad7291_write_event_config,
 	.read_event_value = &ad7291_read_event_value,
 	.write_event_value = &ad7291_write_event_value,
 	.event_attrs = &ad7291_event_attribute_group,
+	.driver_module = THIS_MODULE,
 };
 
 static int ad7291_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
+	struct ad7291_platform_data *pdata = client->dev.platform_data;
 	struct ad7291_chip_info *chip;
 	struct iio_dev *indio_dev;
-	int ret = 0, voltage_uv = 0;
+	int ret = 0;
 
 	indio_dev = iio_device_alloc(sizeof(*chip));
 	if (indio_dev == NULL) {
@@ -594,12 +535,14 @@ static int ad7291_probe(struct i2c_clien
 	}
 	chip = iio_priv(indio_dev);
 
-	chip->reg = regulator_get(&client->dev, "vcc");
-	if (!IS_ERR(chip->reg)) {
+	if (pdata && pdata->use_external_ref) {
+		chip->reg = regulator_get(&client->dev, "vref");
+		if (IS_ERR(chip->reg))
+			goto error_free;
+
 		ret = regulator_enable(chip->reg);
 		if (ret)
 			goto error_put_reg;
-		voltage_uv = regulator_get_voltage(chip->reg);
 	}
 
 	mutex_init(&chip->state_lock);
@@ -612,12 +555,8 @@ static int ad7291_probe(struct i2c_clien
 			AD7291_T_SENSE_MASK | /* Tsense always enabled */
 			AD7291_ALERT_POLARITY; /* set irq polarity low level */
 
-	if (voltage_uv) {
-		chip->int_vref_mv = voltage_uv / 1000;
+	if (pdata && pdata->use_external_ref)
 		chip->command |= AD7291_EXT_REF;
-	} else {
-		chip->int_vref_mv = 2500; /* Build-in ref */
-	}
 
 	indio_dev->name = id->name;
 	indio_dev->channels = ad7291_channels;
@@ -654,21 +593,18 @@ static int ad7291_probe(struct i2c_clien
 	if (ret)
 		goto error_unreg_irq;
 
-	dev_info(&client->dev, "%s ADC registered.\n",
-			 id->name);
-
 	return 0;
 
 error_unreg_irq:
 	if (client->irq)
 		free_irq(client->irq, indio_dev);
 error_disable_reg:
-	if (!IS_ERR(chip->reg))
+	if (chip->reg)
 		regulator_disable(chip->reg);
 error_put_reg:
-	if (!IS_ERR(chip->reg))
+	if (chip->reg)
 		regulator_put(chip->reg);
-
+error_free:
 	iio_device_free(indio_dev);
 error_ret:
 	return ret;
@@ -684,7 +620,7 @@ static int ad7291_remove(struct i2c_clie
 	if (client->irq)
 		free_irq(client->irq, indio_dev);
 
-	if (!IS_ERR(chip->reg)) {
+	if (chip->reg) {
 		regulator_disable(chip->reg);
 		regulator_put(chip->reg);
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7291.h linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7291.h
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7291.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7291.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,12 @@
+#ifndef __IIO_AD7291_H__
+#define __IIO_AD7291_H__
+
+/**
+ * struct ad7291_platform_data - AD7291 platform data
+ * @use_external_ref: Whether to use an external or internal reference voltage
+ */
+struct ad7291_platform_data {
+	bool use_external_ref;
+};
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7606_core.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7606_core.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7606_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7606_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -125,9 +125,12 @@ static ssize_t ad7606_store_range(struct
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	struct ad7606_state *st = iio_priv(indio_dev);
 	unsigned long lval;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &lval);
+	if (ret)
+		return ret;
 
-	if (strict_strtoul(buf, 10, &lval))
-		return -EINVAL;
 	if (!(lval == 5000 || lval == 10000)) {
 		dev_err(dev, "range is not supported\n");
 		return -EINVAL;
@@ -173,8 +176,9 @@ static ssize_t ad7606_store_oversampling
 	unsigned long lval;
 	int ret;
 
-	if (strict_strtoul(buf, 10, &lval))
-		return -EINVAL;
+	ret = kstrtoul(buf, 10, &lval);
+	if (ret)
+		return ret;
 
 	ret = ad7606_oversampling_get_index(lval);
 	if (ret < 0) {
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7606_par.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7606_par.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7606_par.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7606_par.c	2013-08-25 20:43:22.000000000 -0400
@@ -112,8 +112,6 @@ static int ad7606_par_remove(struct plat
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, resource_size(res));
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7816.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7816.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/ad7816.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad7816.c	2013-08-25 20:43:22.000000000 -0400
@@ -175,9 +175,9 @@ static ssize_t ad7816_store_channel(stru
 	unsigned long data;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &data);
+	ret = kstrtoul(buf, 10, &data);
 	if (ret)
-		return -EINVAL;
+		return ret;
 
 	if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) {
 		dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n",
@@ -290,7 +290,9 @@ static inline ssize_t ad7816_set_oti(str
 	u8 data;
 	int ret;
 
-	ret = strict_strtol(buf, 10, &value);
+	ret = kstrtol(buf, 10, &value);
+	if (ret)
+		return ret;
 
 	if (chip->channel_id > AD7816_CS_MAX) {
 		dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/ad799x_core.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad799x_core.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/ad799x_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/ad799x_core.c	2013-08-25 20:43:22.000000000 -0400
@@ -226,7 +226,7 @@ static ssize_t ad799x_write_frequency(st
 	int ret, i;
 	u8 t;
 
-	ret = strict_strtol(buf, 10, &val);
+	ret = kstrtol(buf, 10, &val);
 	if (ret)
 		return ret;
 
@@ -337,7 +337,7 @@ static ssize_t ad799x_write_channel_conf
 	long val;
 	int ret;
 
-	ret = strict_strtol(buf, 10, &val);
+	ret = kstrtol(buf, 10, &val);
 	if (ret)
 		return ret;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/lpc32xx_adc.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/lpc32xx_adc.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/lpc32xx_adc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/lpc32xx_adc.c	2013-08-25 20:43:22.000000000 -0400
@@ -215,7 +215,6 @@ static int lpc32xx_adc_remove(struct pla
 
 	iio_device_unregister(iodev);
 	free_irq(irq, info);
-	platform_set_drvdata(pdev, NULL);
 	clk_put(info->clk);
 	iounmap(info->adc_base);
 	iio_device_free(iodev);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/mxs-lradc.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/mxs-lradc.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/mxs-lradc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/mxs-lradc.c	2013-08-25 20:43:22.000000000 -0400
@@ -234,7 +234,6 @@ static int mxs_lradc_read_raw(struct iio
 {
 	struct mxs_lradc *lradc = iio_priv(iio_dev);
 	int ret;
-	unsigned long mask;
 
 	if (m != IIO_CHAN_INFO_RAW)
 		return -EINVAL;
@@ -243,12 +242,6 @@ static int mxs_lradc_read_raw(struct iio
 	if (chan->channel > LRADC_MAX_TOTAL_CHANS)
 		return -EINVAL;
 
-	/* Validate the channel if it doesn't intersect with reserved chans. */
-	bitmap_set(&mask, chan->channel, 1);
-	ret = iio_validate_scan_mask_onehot(iio_dev, &mask);
-	if (ret)
-		return -EINVAL;
-
 	/*
 	 * See if there is no buffered operation in progess. If there is, simply
 	 * bail out. This can be improved to support both buffered and raw IO at
@@ -620,7 +613,7 @@ static irqreturn_t mxs_lradc_trigger_han
 		((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
 	unsigned int i, j = 0;
 
-	for_each_set_bit(i, iio->active_scan_mask, iio->masklength) {
+	for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
 		lradc->buffer[j] = readl(lradc->base + LRADC_CH(j));
 		writel(chan_value, lradc->base + LRADC_CH(j));
 		lradc->buffer[j] &= LRADC_CH_VALUE_MASK;
@@ -661,12 +654,13 @@ static int mxs_lradc_trigger_init(struct
 {
 	int ret;
 	struct iio_trigger *trig;
+	struct mxs_lradc *lradc = iio_priv(iio);
 
 	trig = iio_trigger_alloc("%s-dev%i", iio->name, iio->id);
 	if (trig == NULL)
 		return -ENOMEM;
 
-	trig->dev.parent = iio->dev.parent;
+	trig->dev.parent = lradc->dev;
 	iio_trigger_set_drvdata(trig, iio);
 	trig->ops = &mxs_lradc_trigger_ops;
 
@@ -676,15 +670,17 @@ static int mxs_lradc_trigger_init(struct
 		return ret;
 	}
 
-	iio->trig = trig;
+	lradc->trig = trig;
 
 	return 0;
 }
 
 static void mxs_lradc_trigger_remove(struct iio_dev *iio)
 {
-	iio_trigger_unregister(iio->trig);
-	iio_trigger_free(iio->trig);
+	struct mxs_lradc *lradc = iio_priv(iio);
+
+	iio_trigger_unregister(lradc->trig);
+	iio_trigger_free(lradc->trig);
 }
 
 static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
@@ -774,8 +770,7 @@ static bool mxs_lradc_validate_scan_mask
 					const unsigned long *mask)
 {
 	struct mxs_lradc *lradc = iio_priv(iio);
-	const int len = iio->masklength;
-	const int map_chans = bitmap_weight(mask, len);
+	const int map_chans = bitmap_weight(mask, LRADC_MAX_TOTAL_CHANS);
 	int rsvd_chans = 0;
 	unsigned long rsvd_mask = 0;
 
@@ -792,7 +787,7 @@ static bool mxs_lradc_validate_scan_mask
 		rsvd_chans++;
 
 	/* Test for attempts to map channels with special mode of operation. */
-	if (bitmap_intersects(mask, &rsvd_mask, len))
+	if (bitmap_intersects(mask, &rsvd_mask, LRADC_MAX_TOTAL_CHANS))
 		return false;
 
 	/* Test for attempts to map more channels then available slots. */
@@ -968,6 +963,7 @@ static int mxs_lradc_probe(struct platfo
 	iio->modes = INDIO_DIRECT_MODE;
 	iio->channels = mxs_lradc_chan_spec;
 	iio->num_channels = ARRAY_SIZE(mxs_lradc_chan_spec);
+	iio->masklength = LRADC_MAX_TOTAL_CHANS;
 
 	ret = iio_triggered_buffer_setup(iio, &iio_pollfunc_store_time,
 				&mxs_lradc_trigger_handler,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/adc/spear_adc.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/spear_adc.c
--- linux-libre-3.10-gnu/drivers/staging/iio/adc/spear_adc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/adc/spear_adc.c	2013-08-25 20:43:22.000000000 -0400
@@ -407,7 +407,6 @@ static int spear_adc_remove(struct platf
 	struct spear_adc_info *info = iio_priv(iodev);
 
 	iio_device_unregister(iodev);
-	platform_set_drvdata(pdev, NULL);
 	clk_disable_unprepare(info->clk);
 	clk_put(info->clk);
 	iounmap(info->adc_base_spear6xx);
@@ -416,11 +415,13 @@ static int spear_adc_remove(struct platf
 	return 0;
 }
 
+#ifdef CONFIG_OF
 static const struct of_device_id spear_adc_dt_ids[] = {
 	{ .compatible = "st,spear600-adc", },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, spear_adc_dt_ids);
+#endif
 
 static struct platform_driver spear_adc_driver = {
 	.probe		= spear_adc_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/gyro/adis16130_core.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/gyro/adis16130_core.c
--- linux-libre-3.10-gnu/drivers/staging/iio/gyro/adis16130_core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/gyro/adis16130_core.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,178 +0,0 @@
-/*
- * ADIS16130 Digital Output, High Precision Angular Rate Sensor driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-#define ADIS16130_CON         0x0
-#define ADIS16130_CON_RD      (1 << 6)
-#define ADIS16130_IOP         0x1
-
-/* 1 = data-ready signal low when unread data on all channels; */
-#define ADIS16130_IOP_ALL_RDY (1 << 3)
-#define ADIS16130_IOP_SYNC    (1 << 0) /* 1 = synchronization enabled */
-#define ADIS16130_RATEDATA    0x8 /* Gyroscope output, rate of rotation */
-#define ADIS16130_TEMPDATA    0xA /* Temperature output */
-#define ADIS16130_RATECS      0x28 /* Gyroscope channel setup */
-#define ADIS16130_RATECS_EN   (1 << 3) /* 1 = channel enable; */
-#define ADIS16130_TEMPCS      0x2A /* Temperature channel setup */
-#define ADIS16130_TEMPCS_EN   (1 << 3)
-#define ADIS16130_RATECONV    0x30
-#define ADIS16130_TEMPCONV    0x32
-#define ADIS16130_MODE        0x38
-#define ADIS16130_MODE_24BIT  (1 << 1) /* 1 = 24-bit resolution; */
-
-/**
- * struct adis16130_state - device instance specific data
- * @us:			actual spi_device to write data
- * @buf_lock:		mutex to protect tx and rx
- * @buf:		unified tx/rx buffer
- **/
-struct adis16130_state {
-	struct spi_device		*us;
-	struct mutex			buf_lock;
-	u8				buf[4] ____cacheline_aligned;
-};
-
-static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
-{
-	int ret;
-	struct adis16130_state *st = iio_priv(indio_dev);
-	struct spi_message msg;
-	struct spi_transfer xfer = {
-		.tx_buf = st->buf,
-		.rx_buf = st->buf,
-		.len = 4,
-	};
-
-	mutex_lock(&st->buf_lock);
-
-	st->buf[0] = ADIS16130_CON_RD | reg_addr;
-	st->buf[1] = st->buf[2] = st->buf[3] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-	ret = spi_sync(st->us, &msg);
-	ret = spi_read(st->us, st->buf, 4);
-
-	if (ret == 0)
-		*val = (st->buf[1] << 16) | (st->buf[2] << 8) | st->buf[3];
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-static int adis16130_read_raw(struct iio_dev *indio_dev,
-			      struct iio_chan_spec const *chan,
-			      int *val, int *val2,
-			      long mask)
-{
-	int ret;
-	u32 temp;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16130_spi_read(indio_dev, chan->address, &temp);
-	mutex_unlock(&indio_dev->mlock);
-	if (ret)
-		return ret;
-	*val = temp;
-	return IIO_VAL_INT;
-}
-
-static const struct iio_chan_spec adis16130_channels[] = {
-	{
-		.type = IIO_ANGL_VEL,
-		.modified = 1,
-		.channel2 = IIO_MOD_Z,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-		.address = ADIS16130_RATEDATA,
-	}, {
-		.type = IIO_TEMP,
-		.indexed = 1,
-		.channel = 0,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-		.address = ADIS16130_TEMPDATA,
-	}
-};
-
-static const struct iio_info adis16130_info = {
-	.read_raw = &adis16130_read_raw,
-	.driver_module = THIS_MODULE,
-};
-
-static int adis16130_probe(struct spi_device *spi)
-{
-	int ret;
-	struct adis16130_state *st;
-	struct iio_dev *indio_dev;
-
-	/* setup the industrialio driver allocated elements */
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	st = iio_priv(indio_dev);
-	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, indio_dev);
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-	indio_dev->name = spi->dev.driver->name;
-	indio_dev->channels = adis16130_channels;
-	indio_dev->num_channels = ARRAY_SIZE(adis16130_channels);
-	indio_dev->dev.parent = &spi->dev;
-	indio_dev->info = &adis16130_info;
-	indio_dev->modes = INDIO_DIRECT_MODE;
-
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-
-	return 0;
-
-error_free_dev:
-	iio_device_free(indio_dev);
-
-error_ret:
-	return ret;
-}
-
-/* fixme, confirm ordering in this function */
-static int adis16130_remove(struct spi_device *spi)
-{
-	iio_device_unregister(spi_get_drvdata(spi));
-	iio_device_free(spi_get_drvdata(spi));
-
-	return 0;
-}
-
-static struct spi_driver adis16130_driver = {
-	.driver = {
-		.name = "adis16130",
-		.owner = THIS_MODULE,
-	},
-	.probe = adis16130_probe,
-	.remove = adis16130_remove,
-};
-module_spi_driver(adis16130_driver);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16130 High Precision Angular Rate");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("spi:adis16130");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/gyro/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/iio/gyro/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/iio/gyro/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/gyro/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -10,13 +10,6 @@ config ADIS16060
 	  Say yes here to build support for Analog Devices adis16060 wide bandwidth
 	  yaw rate gyroscope with SPI.
 
-config ADIS16130
-	tristate "Analog Devices ADIS16130 High Precision Angular Rate Sensor driver"
-	depends on SPI
-	help
-	  Say yes here to build support for Analog Devices ADIS16130 High Precision
-	  Angular Rate Sensor driver.
-
 config ADIS16260
 	tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver"
 	depends on SPI
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/gyro/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/iio/gyro/Makefile
--- linux-libre-3.10-gnu/drivers/staging/iio/gyro/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/gyro/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,8 +5,5 @@
 adis16060-y             := adis16060_core.o
 obj-$(CONFIG_ADIS16060) += adis16060.o
 
-adis16130-y             := adis16130_core.o
-obj-$(CONFIG_ADIS16130) += adis16130.o
-
 adis16260-y             := adis16260_core.o
 obj-$(CONFIG_ADIS16260) += adis16260.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/trigger/iio-trig-gpio.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/trigger/iio-trig-gpio.c
--- linux-libre-3.10-gnu/drivers/staging/iio/trigger/iio-trig-gpio.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/trigger/iio-trig-gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,167 +0,0 @@
-/*
- * Industrial I/O - gpio based trigger support
- *
- * Copyright (c) 2008 Jonathan Cameron
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * Currently this is more of a functioning proof of concept than a full
- * fledged trigger driver.
- *
- * TODO:
- *
- * Add board config elements to allow specification of startup settings.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/slab.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-
-static LIST_HEAD(iio_gpio_trigger_list);
-static DEFINE_MUTEX(iio_gpio_trigger_list_lock);
-
-struct iio_gpio_trigger_info {
-	struct mutex in_use;
-	unsigned int irq;
-};
-/*
- * Need to reference count these triggers and only enable gpio interrupts
- * as appropriate.
- */
-
-/* So what functionality do we want in here?... */
-/* set high / low as interrupt type? */
-
-static irqreturn_t iio_gpio_trigger_poll(int irq, void *private)
-{
-	/* Timestamp not currently provided */
-	iio_trigger_poll(private, 0);
-	return IRQ_HANDLED;
-}
-
-static const struct iio_trigger_ops iio_gpio_trigger_ops = {
-	.owner = THIS_MODULE,
-};
-
-static int iio_gpio_trigger_probe(struct platform_device *pdev)
-{
-	struct iio_gpio_trigger_info *trig_info;
-	struct iio_trigger *trig, *trig2;
-	unsigned long irqflags;
-	struct resource *irq_res;
-	int irq, ret = 0, irq_res_cnt = 0;
-
-	do {
-		irq_res = platform_get_resource(pdev,
-				IORESOURCE_IRQ, irq_res_cnt);
-
-		if (irq_res == NULL) {
-			if (irq_res_cnt == 0)
-				dev_err(&pdev->dev, "No GPIO IRQs specified");
-			break;
-		}
-		irqflags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED;
-
-		for (irq = irq_res->start; irq <= irq_res->end; irq++) {
-
-			trig = iio_trigger_alloc("irqtrig%d", irq);
-			if (!trig) {
-				ret = -ENOMEM;
-				goto error_free_completed_registrations;
-			}
-
-			trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
-			if (!trig_info) {
-				ret = -ENOMEM;
-				goto error_put_trigger;
-			}
-			iio_trigger_set_drvdata(trig, trig_info);
-			trig_info->irq = irq;
-			trig->ops = &iio_gpio_trigger_ops;
-			ret = request_irq(irq, iio_gpio_trigger_poll,
-					  irqflags, trig->name, trig);
-			if (ret) {
-				dev_err(&pdev->dev,
-					"request IRQ-%d failed", irq);
-				goto error_free_trig_info;
-			}
-
-			ret = iio_trigger_register(trig);
-			if (ret)
-				goto error_release_irq;
-
-			list_add_tail(&trig->alloc_list,
-					&iio_gpio_trigger_list);
-		}
-
-		irq_res_cnt++;
-	} while (irq_res != NULL);
-
-
-	return 0;
-
-/* First clean up the partly allocated trigger */
-error_release_irq:
-	free_irq(irq, trig);
-error_free_trig_info:
-	kfree(trig_info);
-error_put_trigger:
-	iio_trigger_put(trig);
-error_free_completed_registrations:
-	/* The rest should have been added to the iio_gpio_trigger_list */
-	list_for_each_entry_safe(trig,
-				 trig2,
-				 &iio_gpio_trigger_list,
-				 alloc_list) {
-		trig_info = iio_trigger_get_drvdata(trig);
-		free_irq(gpio_to_irq(trig_info->irq), trig);
-		kfree(trig_info);
-		iio_trigger_unregister(trig);
-	}
-
-	return ret;
-}
-
-static int iio_gpio_trigger_remove(struct platform_device *pdev)
-{
-	struct iio_trigger *trig, *trig2;
-	struct iio_gpio_trigger_info *trig_info;
-
-	mutex_lock(&iio_gpio_trigger_list_lock);
-	list_for_each_entry_safe(trig,
-				 trig2,
-				 &iio_gpio_trigger_list,
-				 alloc_list) {
-		trig_info = iio_trigger_get_drvdata(trig);
-		iio_trigger_unregister(trig);
-		free_irq(trig_info->irq, trig);
-		kfree(trig_info);
-		iio_trigger_put(trig);
-	}
-	mutex_unlock(&iio_gpio_trigger_list_lock);
-
-	return 0;
-}
-
-static struct platform_driver iio_gpio_trigger_driver = {
-	.probe = iio_gpio_trigger_probe,
-	.remove = iio_gpio_trigger_remove,
-	.driver = {
-		.name = "iio_gpio_trigger",
-		.owner = THIS_MODULE,
-	},
-};
-
-module_platform_driver(iio_gpio_trigger_driver);
-
-MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
-MODULE_DESCRIPTION("Example gpio trigger for the iio subsystem");
-MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/trigger/iio-trig-sysfs.c linux-libre-3.11-rc7-gnu/drivers/staging/iio/trigger/iio-trig-sysfs.c
--- linux-libre-3.10-gnu/drivers/staging/iio/trigger/iio-trig-sysfs.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/trigger/iio-trig-sysfs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,227 +0,0 @@
-/*
- * Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-#include <linux/irq_work.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger.h>
-
-struct iio_sysfs_trig {
-	struct iio_trigger *trig;
-	struct irq_work work;
-	int id;
-	struct list_head l;
-};
-
-static LIST_HEAD(iio_sysfs_trig_list);
-static DEFINE_MUTEX(iio_syfs_trig_list_mut);
-
-static int iio_sysfs_trigger_probe(int id);
-static ssize_t iio_sysfs_trig_add(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf,
-				  size_t len)
-{
-	int ret;
-	unsigned long input;
-
-	ret = strict_strtoul(buf, 10, &input);
-	if (ret)
-		return ret;
-	ret = iio_sysfs_trigger_probe(input);
-	if (ret)
-		return ret;
-	return len;
-}
-static DEVICE_ATTR(add_trigger, S_IWUSR, NULL, &iio_sysfs_trig_add);
-
-static int iio_sysfs_trigger_remove(int id);
-static ssize_t iio_sysfs_trig_remove(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf,
-				     size_t len)
-{
-	int ret;
-	unsigned long input;
-
-	ret = strict_strtoul(buf, 10, &input);
-	if (ret)
-		return ret;
-	ret = iio_sysfs_trigger_remove(input);
-	if (ret)
-		return ret;
-	return len;
-}
-
-static DEVICE_ATTR(remove_trigger, S_IWUSR, NULL, &iio_sysfs_trig_remove);
-
-static struct attribute *iio_sysfs_trig_attrs[] = {
-	&dev_attr_add_trigger.attr,
-	&dev_attr_remove_trigger.attr,
-	NULL,
-};
-
-static const struct attribute_group iio_sysfs_trig_group = {
-	.attrs = iio_sysfs_trig_attrs,
-};
-
-static const struct attribute_group *iio_sysfs_trig_groups[] = {
-	&iio_sysfs_trig_group,
-	NULL
-};
-
-
-/* Nothing to actually do upon release */
-static void iio_trigger_sysfs_release(struct device *dev)
-{
-}
-
-static struct device iio_sysfs_trig_dev = {
-	.bus = &iio_bus_type,
-	.groups = iio_sysfs_trig_groups,
-	.release = &iio_trigger_sysfs_release,
-};
-
-static void iio_sysfs_trigger_work(struct irq_work *work)
-{
-	struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig,
-							work);
-
-	iio_trigger_poll(trig->trig, 0);
-}
-
-static ssize_t iio_sysfs_trigger_poll(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct iio_trigger *trig = to_iio_trigger(dev);
-	struct iio_sysfs_trig *sysfs_trig = iio_trigger_get_drvdata(trig);
-
-	irq_work_queue(&sysfs_trig->work);
-
-	return count;
-}
-
-static DEVICE_ATTR(trigger_now, S_IWUSR, NULL, iio_sysfs_trigger_poll);
-
-static struct attribute *iio_sysfs_trigger_attrs[] = {
-	&dev_attr_trigger_now.attr,
-	NULL,
-};
-
-static const struct attribute_group iio_sysfs_trigger_attr_group = {
-	.attrs = iio_sysfs_trigger_attrs,
-};
-
-static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = {
-	&iio_sysfs_trigger_attr_group,
-	NULL
-};
-
-static const struct iio_trigger_ops iio_sysfs_trigger_ops = {
-	.owner = THIS_MODULE,
-};
-
-static int iio_sysfs_trigger_probe(int id)
-{
-	struct iio_sysfs_trig *t;
-	int ret;
-	bool foundit = false;
-	mutex_lock(&iio_syfs_trig_list_mut);
-	list_for_each_entry(t, &iio_sysfs_trig_list, l)
-		if (id == t->id) {
-			foundit = true;
-			break;
-		}
-	if (foundit) {
-		ret = -EINVAL;
-		goto out1;
-	}
-	t = kmalloc(sizeof(*t), GFP_KERNEL);
-	if (t == NULL) {
-		ret = -ENOMEM;
-		goto out1;
-	}
-	t->id = id;
-	t->trig = iio_trigger_alloc("sysfstrig%d", id);
-	if (!t->trig) {
-		ret = -ENOMEM;
-		goto free_t;
-	}
-
-	t->trig->dev.groups = iio_sysfs_trigger_attr_groups;
-	t->trig->ops = &iio_sysfs_trigger_ops;
-	t->trig->dev.parent = &iio_sysfs_trig_dev;
-	iio_trigger_set_drvdata(t->trig, t);
-
-	init_irq_work(&t->work, iio_sysfs_trigger_work);
-
-	ret = iio_trigger_register(t->trig);
-	if (ret)
-		goto out2;
-	list_add(&t->l, &iio_sysfs_trig_list);
-	__module_get(THIS_MODULE);
-	mutex_unlock(&iio_syfs_trig_list_mut);
-	return 0;
-
-out2:
-	iio_trigger_put(t->trig);
-free_t:
-	kfree(t);
-out1:
-	mutex_unlock(&iio_syfs_trig_list_mut);
-	return ret;
-}
-
-static int iio_sysfs_trigger_remove(int id)
-{
-	bool foundit = false;
-	struct iio_sysfs_trig *t;
-	mutex_lock(&iio_syfs_trig_list_mut);
-	list_for_each_entry(t, &iio_sysfs_trig_list, l)
-		if (id == t->id) {
-			foundit = true;
-			break;
-		}
-	if (!foundit) {
-		mutex_unlock(&iio_syfs_trig_list_mut);
-		return -EINVAL;
-	}
-
-	iio_trigger_unregister(t->trig);
-	iio_trigger_free(t->trig);
-
-	list_del(&t->l);
-	kfree(t);
-	module_put(THIS_MODULE);
-	mutex_unlock(&iio_syfs_trig_list_mut);
-	return 0;
-}
-
-
-static int __init iio_sysfs_trig_init(void)
-{
-	device_initialize(&iio_sysfs_trig_dev);
-	dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger");
-	return device_add(&iio_sysfs_trig_dev);
-}
-module_init(iio_sysfs_trig_init);
-
-static void __exit iio_sysfs_trig_exit(void)
-{
-	device_unregister(&iio_sysfs_trig_dev);
-}
-module_exit(iio_sysfs_trig_exit);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Sysfs based trigger for the iio subsystem");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:iio-trig-sysfs");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/trigger/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/iio/trigger/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/iio/trigger/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/trigger/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -12,23 +12,6 @@ config IIO_PERIODIC_RTC_TRIGGER
 	  Provides support for using periodic capable real time
 	  clocks as IIO triggers.
 
-config IIO_GPIO_TRIGGER
-	tristate "GPIO trigger"
-	depends on GPIOLIB
-	help
-	  Provides support for using GPIO pins as IIO triggers.
-
-config IIO_SYSFS_TRIGGER
-	tristate "SYSFS trigger"
-	depends on SYSFS
-	select IRQ_WORK
-	help
-	  Provides support for using SYSFS entry as IIO triggers.
-	  If unsure, say N (but it's safe to say "Y").
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called iio-trig-sysfs.
-
 config IIO_BFIN_TMR_TRIGGER
 	tristate "Blackfin TIMER trigger"
 	depends on BLACKFIN
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/iio/trigger/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/iio/trigger/Makefile
--- linux-libre-3.10-gnu/drivers/staging/iio/trigger/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/iio/trigger/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -3,6 +3,4 @@
 #
 
 obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o
-obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o
-obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o
 obj-$(CONFIG_IIO_BFIN_TMR_TRIGGER) += iio-trig-bfin-timer.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/imx-drm-core.c linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/imx-drm-core.c
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/imx-drm-core.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/imx-drm-core.c	2013-08-25 20:43:22.000000000 -0400
@@ -144,7 +144,7 @@ int imx_drm_crtc_panel_format(struct drm
 		u32 interface_pix_fmt)
 {
 	return imx_drm_crtc_panel_format_pins(crtc, encoder_type,
-					      interface_pix_fmt, 0, 0);
+					      interface_pix_fmt, 2, 3);
 }
 EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format);
 
@@ -491,7 +491,6 @@ int imx_drm_add_crtc(struct drm_crtc *cr
 {
 	struct imx_drm_device *imxdrm = __imx_drm_device();
 	struct imx_drm_crtc *imx_drm_crtc;
-	const struct drm_crtc_funcs *crtc_funcs;
 	int ret;
 
 	mutex_lock(&imxdrm->mutex);
@@ -512,8 +511,6 @@ int imx_drm_add_crtc(struct drm_crtc *cr
 	imx_drm_crtc->cookie.cookie = cookie;
 	imx_drm_crtc->cookie.id = id;
 
-	crtc_funcs = imx_drm_helper_funcs->crtc_funcs;
-
 	imx_drm_crtc->crtc = crtc;
 	imx_drm_crtc->imxdrm = imxdrm;
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/imx-ldb.c linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/imx-ldb.c
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/imx-ldb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/imx-ldb.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,625 @@
+/*
+ * i.MX drm driver - LVDS display bridge
+ *
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <video/of_videomode.h>
+#include <linux/regmap.h>
+#include <linux/videodev2.h>
+
+#include "imx-drm.h"
+
+#define DRIVER_NAME "imx-ldb"
+
+#define LDB_CH0_MODE_EN_TO_DI0		(1 << 0)
+#define LDB_CH0_MODE_EN_TO_DI1		(3 << 0)
+#define LDB_CH0_MODE_EN_MASK		(3 << 0)
+#define LDB_CH1_MODE_EN_TO_DI0		(1 << 2)
+#define LDB_CH1_MODE_EN_TO_DI1		(3 << 2)
+#define LDB_CH1_MODE_EN_MASK		(3 << 2)
+#define LDB_SPLIT_MODE_EN		(1 << 4)
+#define LDB_DATA_WIDTH_CH0_24		(1 << 5)
+#define LDB_BIT_MAP_CH0_JEIDA		(1 << 6)
+#define LDB_DATA_WIDTH_CH1_24		(1 << 7)
+#define LDB_BIT_MAP_CH1_JEIDA		(1 << 8)
+#define LDB_DI0_VS_POL_ACT_LOW		(1 << 9)
+#define LDB_DI1_VS_POL_ACT_LOW		(1 << 10)
+#define LDB_BGREF_RMODE_INT		(1 << 15)
+
+#define con_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, connector)
+#define enc_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, encoder)
+
+struct imx_ldb;
+
+struct imx_ldb_channel {
+	struct imx_ldb *ldb;
+	struct drm_connector connector;
+	struct imx_drm_connector *imx_drm_connector;
+	struct drm_encoder encoder;
+	struct imx_drm_encoder *imx_drm_encoder;
+	int chno;
+	void *edid;
+	int edid_len;
+	struct drm_display_mode mode;
+	int mode_valid;
+};
+
+struct bus_mux {
+	int reg;
+	int shift;
+	int mask;
+};
+
+struct imx_ldb {
+	struct regmap *regmap;
+	struct device *dev;
+	struct imx_ldb_channel channel[2];
+	struct clk *clk[2]; /* our own clock */
+	struct clk *clk_sel[4]; /* parent of display clock */
+	struct clk *clk_pll[2]; /* upstream clock we can adjust */
+	u32 ldb_ctrl;
+	const struct bus_mux *lvds_mux;
+};
+
+static enum drm_connector_status imx_ldb_connector_detect(
+		struct drm_connector *connector, bool force)
+{
+	return connector_status_connected;
+}
+
+static void imx_ldb_connector_destroy(struct drm_connector *connector)
+{
+	/* do not free here */
+}
+
+static int imx_ldb_connector_get_modes(struct drm_connector *connector)
+{
+	struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
+	int num_modes = 0;
+
+	if (imx_ldb_ch->edid) {
+		drm_mode_connector_update_edid_property(connector,
+							imx_ldb_ch->edid);
+		num_modes = drm_add_edid_modes(connector, imx_ldb_ch->edid);
+	}
+
+	if (imx_ldb_ch->mode_valid) {
+		struct drm_display_mode *mode;
+
+		mode = drm_mode_create(connector->dev);
+		drm_mode_copy(mode, &imx_ldb_ch->mode);
+		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+		drm_mode_probed_add(connector, mode);
+		num_modes++;
+	}
+
+	return num_modes;
+}
+
+static int imx_ldb_connector_mode_valid(struct drm_connector *connector,
+			  struct drm_display_mode *mode)
+{
+	return 0;
+}
+
+static struct drm_encoder *imx_ldb_connector_best_encoder(
+		struct drm_connector *connector)
+{
+	struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
+
+	return &imx_ldb_ch->encoder;
+}
+
+static void imx_ldb_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static bool imx_ldb_encoder_mode_fixup(struct drm_encoder *encoder,
+			   const struct drm_display_mode *mode,
+			   struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
+		unsigned long serial_clk, unsigned long di_clk)
+{
+	int ret;
+
+	dev_dbg(ldb->dev, "%s: now: %ld want: %ld\n", __func__,
+			clk_get_rate(ldb->clk_pll[chno]), serial_clk);
+	clk_set_rate(ldb->clk_pll[chno], serial_clk);
+
+	dev_dbg(ldb->dev, "%s after: %ld\n", __func__,
+			clk_get_rate(ldb->clk_pll[chno]));
+
+	dev_dbg(ldb->dev, "%s: now: %ld want: %ld\n", __func__,
+			clk_get_rate(ldb->clk[chno]),
+			(long int)di_clk);
+	clk_set_rate(ldb->clk[chno], di_clk);
+
+	dev_dbg(ldb->dev, "%s after: %ld\n", __func__,
+			clk_get_rate(ldb->clk[chno]));
+
+	/* set display clock mux to LDB input clock */
+	ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk[chno]);
+	if (ret) {
+		dev_err(ldb->dev, "unable to set di%d parent clock to ldb_di%d\n", mux, chno);
+	}
+}
+
+static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
+{
+	struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+	struct imx_ldb *ldb = imx_ldb_ch->ldb;
+	struct drm_display_mode *mode = &encoder->crtc->mode;
+	u32 pixel_fmt;
+	unsigned long serial_clk;
+	unsigned long di_clk = mode->clock * 1000;
+	int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->imx_drm_encoder,
+					     encoder->crtc);
+
+	if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
+		/* dual channel LVDS mode */
+		serial_clk = 3500UL * mode->clock;
+		imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk);
+		imx_ldb_set_clock(ldb, mux, 1, serial_clk, di_clk);
+	} else {
+		serial_clk = 7000UL * mode->clock;
+		imx_ldb_set_clock(ldb, mux, imx_ldb_ch->chno, serial_clk, di_clk);
+	}
+
+	switch (imx_ldb_ch->chno) {
+	case 0:
+		pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH0_24) ?
+			V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666;
+		break;
+	case 1:
+		pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH1_24) ?
+			V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666;
+		break;
+	default:
+		dev_err(ldb->dev, "unable to config di%d panel format\n",
+			imx_ldb_ch->chno);
+		pixel_fmt = V4L2_PIX_FMT_RGB24;
+	}
+
+	imx_drm_crtc_panel_format(encoder->crtc, DRM_MODE_ENCODER_LVDS,
+			pixel_fmt);
+}
+
+static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
+{
+	struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+	struct imx_ldb *ldb = imx_ldb_ch->ldb;
+	int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
+	int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->imx_drm_encoder,
+					     encoder->crtc);
+
+	if (dual) {
+		clk_prepare_enable(ldb->clk[0]);
+		clk_prepare_enable(ldb->clk[1]);
+	}
+
+	if (imx_ldb_ch == &ldb->channel[0] || dual) {
+		ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
+		if (mux == 0 || ldb->lvds_mux)
+			ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0;
+		else if (mux == 1)
+			ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI1;
+	}
+	if (imx_ldb_ch == &ldb->channel[1] || dual) {
+		ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
+		if (mux == 1 || ldb->lvds_mux)
+			ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI1;
+		else if (mux == 0)
+			ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI0;
+	}
+
+	if (ldb->lvds_mux) {
+		const struct bus_mux *lvds_mux = NULL;
+
+		if (imx_ldb_ch == &ldb->channel[0])
+			lvds_mux = &ldb->lvds_mux[0];
+		else if (imx_ldb_ch == &ldb->channel[1])
+			lvds_mux = &ldb->lvds_mux[1];
+
+		regmap_update_bits(ldb->regmap, lvds_mux->reg, lvds_mux->mask,
+				   mux << lvds_mux->shift);
+	}
+
+	regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
+}
+
+static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
+			 struct drm_display_mode *mode,
+			 struct drm_display_mode *adjusted_mode)
+{
+	struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+	struct imx_ldb *ldb = imx_ldb_ch->ldb;
+	int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
+
+	if (mode->clock > 170000) {
+		dev_warn(ldb->dev,
+			 "%s: mode exceeds 170 MHz pixel clock\n", __func__);
+	}
+	if (mode->clock > 85000 && !dual) {
+		dev_warn(ldb->dev,
+			 "%s: mode exceeds 85 MHz pixel clock\n", __func__);
+	}
+
+	/* FIXME - assumes straight connections DI0 --> CH0, DI1 --> CH1 */
+	if (imx_ldb_ch == &ldb->channel[0]) {
+		if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+			ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW;
+		else if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+			ldb->ldb_ctrl &= ~LDB_DI0_VS_POL_ACT_LOW;
+	}
+	if (imx_ldb_ch == &ldb->channel[1]) {
+		if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+			ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW;
+		else if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+			ldb->ldb_ctrl &= ~LDB_DI1_VS_POL_ACT_LOW;
+	}
+}
+
+static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
+{
+	struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+	struct imx_ldb *ldb = imx_ldb_ch->ldb;
+
+	/*
+	 * imx_ldb_encoder_disable is called by
+	 * drm_helper_disable_unused_functions without
+	 * the encoder being enabled before.
+	 */
+	if (imx_ldb_ch == &ldb->channel[0] &&
+	    (ldb->ldb_ctrl & LDB_CH0_MODE_EN_MASK) == 0)
+		return;
+	else if (imx_ldb_ch == &ldb->channel[1] &&
+		 (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0)
+		return;
+
+	if (imx_ldb_ch == &ldb->channel[0])
+		ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
+	else if (imx_ldb_ch == &ldb->channel[1])
+		ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
+
+	regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
+
+	if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
+		clk_disable_unprepare(ldb->clk[0]);
+		clk_disable_unprepare(ldb->clk[1]);
+	}
+}
+
+static void imx_ldb_encoder_destroy(struct drm_encoder *encoder)
+{
+	/* do not free here */
+}
+
+static struct drm_connector_funcs imx_ldb_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = imx_ldb_connector_detect,
+	.destroy = imx_ldb_connector_destroy,
+};
+
+static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = {
+	.get_modes = imx_ldb_connector_get_modes,
+	.best_encoder = imx_ldb_connector_best_encoder,
+	.mode_valid = imx_ldb_connector_mode_valid,
+};
+
+static struct drm_encoder_funcs imx_ldb_encoder_funcs = {
+	.destroy = imx_ldb_encoder_destroy,
+};
+
+static struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = {
+	.dpms = imx_ldb_encoder_dpms,
+	.mode_fixup = imx_ldb_encoder_mode_fixup,
+	.prepare = imx_ldb_encoder_prepare,
+	.commit = imx_ldb_encoder_commit,
+	.mode_set = imx_ldb_encoder_mode_set,
+	.disable = imx_ldb_encoder_disable,
+};
+
+static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno)
+{
+	char clkname[16];
+
+	sprintf(clkname, "di%d", chno);
+	ldb->clk[chno] = devm_clk_get(ldb->dev, clkname);
+	if (IS_ERR(ldb->clk[chno]))
+		return PTR_ERR(ldb->clk[chno]);
+
+	sprintf(clkname, "di%d_pll", chno);
+	ldb->clk_pll[chno] = devm_clk_get(ldb->dev, clkname);
+	if (IS_ERR(ldb->clk_pll[chno]))
+		return PTR_ERR(ldb->clk_pll[chno]);
+
+	return 0;
+}
+
+static int imx_ldb_register(struct imx_ldb_channel *imx_ldb_ch)
+{
+	int ret;
+	struct imx_ldb *ldb = imx_ldb_ch->ldb;
+
+	ret = imx_ldb_get_clk(ldb, imx_ldb_ch->chno);
+	if (ret)
+		return ret;
+	if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
+		ret |= imx_ldb_get_clk(ldb, 1);
+		if (ret)
+			return ret;
+	}
+
+	imx_ldb_ch->connector.funcs = &imx_ldb_connector_funcs;
+	imx_ldb_ch->encoder.funcs = &imx_ldb_encoder_funcs;
+
+	imx_ldb_ch->encoder.encoder_type = DRM_MODE_ENCODER_LVDS;
+	imx_ldb_ch->connector.connector_type = DRM_MODE_CONNECTOR_LVDS;
+
+	drm_encoder_helper_add(&imx_ldb_ch->encoder,
+			&imx_ldb_encoder_helper_funcs);
+	ret = imx_drm_add_encoder(&imx_ldb_ch->encoder,
+			&imx_ldb_ch->imx_drm_encoder, THIS_MODULE);
+	if (ret) {
+		dev_err(ldb->dev, "adding encoder failed with %d\n", ret);
+		return ret;
+	}
+
+	drm_connector_helper_add(&imx_ldb_ch->connector,
+			&imx_ldb_connector_helper_funcs);
+
+	ret = imx_drm_add_connector(&imx_ldb_ch->connector,
+			&imx_ldb_ch->imx_drm_connector, THIS_MODULE);
+	if (ret) {
+		imx_drm_remove_encoder(imx_ldb_ch->imx_drm_encoder);
+		dev_err(ldb->dev, "adding connector failed with %d\n", ret);
+		return ret;
+	}
+
+	drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
+			&imx_ldb_ch->encoder);
+
+	return 0;
+}
+
+enum {
+	LVDS_BIT_MAP_SPWG,
+	LVDS_BIT_MAP_JEIDA
+};
+
+static const char *imx_ldb_bit_mappings[] = {
+	[LVDS_BIT_MAP_SPWG]  = "spwg",
+	[LVDS_BIT_MAP_JEIDA] = "jeida",
+};
+
+const int of_get_data_mapping(struct device_node *np)
+{
+	const char *bm;
+	int ret, i;
+
+	ret = of_property_read_string(np, "fsl,data-mapping", &bm);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++)
+		if (!strcasecmp(bm, imx_ldb_bit_mappings[i]))
+			return i;
+
+	return -EINVAL;
+}
+
+static struct bus_mux imx6q_lvds_mux[2] = {
+	{
+		.reg = IOMUXC_GPR3,
+		.shift = 6,
+		.mask = IMX6Q_GPR3_LVDS0_MUX_CTL_MASK,
+	}, {
+		.reg = IOMUXC_GPR3,
+		.shift = 8,
+		.mask = IMX6Q_GPR3_LVDS1_MUX_CTL_MASK,
+	}
+};
+
+/*
+ * For a device declaring compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb",
+ * of_match_device will walk through this list and take the first entry
+ * matching any of its compatible values. Therefore, the more generic
+ * entries (in this case fsl,imx53-ldb) need to be ordered last.
+ */
+static const struct of_device_id imx_ldb_dt_ids[] = {
+	{ .compatible = "fsl,imx6q-ldb", .data = imx6q_lvds_mux, },
+	{ .compatible = "fsl,imx53-ldb", .data = NULL, },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids);
+
+static int imx_ldb_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	const struct of_device_id *of_id =
+			of_match_device(of_match_ptr(imx_ldb_dt_ids),
+					&pdev->dev);
+	struct device_node *child;
+	const u8 *edidp;
+	struct imx_ldb *imx_ldb;
+	int datawidth;
+	int mapping;
+	int dual;
+	int ret;
+	int i;
+
+	imx_ldb = devm_kzalloc(&pdev->dev, sizeof(*imx_ldb), GFP_KERNEL);
+	if (!imx_ldb)
+		return -ENOMEM;
+
+	imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+	if (IS_ERR(imx_ldb->regmap)) {
+		dev_err(&pdev->dev, "failed to get parent regmap\n");
+		return PTR_ERR(imx_ldb->regmap);
+	}
+
+	imx_ldb->dev = &pdev->dev;
+
+	if (of_id)
+		imx_ldb->lvds_mux = of_id->data;
+
+	dual = of_property_read_bool(np, "fsl,dual-channel");
+	if (dual)
+		imx_ldb->ldb_ctrl |= LDB_SPLIT_MODE_EN;
+
+	/*
+	 * There are three diferent possible clock mux configurations:
+	 * i.MX53:  ipu1_di0_sel, ipu1_di1_sel
+	 * i.MX6q:  ipu1_di0_sel, ipu1_di1_sel, ipu2_di0_sel, ipu2_di1_sel
+	 * i.MX6dl: ipu1_di0_sel, ipu1_di1_sel, lcdif_sel
+	 * Map them all to di0_sel...di3_sel.
+	 */
+	for (i = 0; i < 4; i++) {
+		char clkname[16];
+
+		sprintf(clkname, "di%d_sel", i);
+		imx_ldb->clk_sel[i] = devm_clk_get(imx_ldb->dev, clkname);
+		if (IS_ERR(imx_ldb->clk_sel[i])) {
+			ret = PTR_ERR(imx_ldb->clk_sel[i]);
+			imx_ldb->clk_sel[i] = NULL;
+			break;
+		}
+	}
+	if (i == 0)
+		return ret;
+
+	for_each_child_of_node(np, child) {
+		struct imx_ldb_channel *channel;
+
+		ret = of_property_read_u32(child, "reg", &i);
+		if (ret || i < 0 || i > 1)
+			return -EINVAL;
+
+		if (dual && i > 0) {
+			dev_warn(&pdev->dev, "dual-channel mode, ignoring second output\n");
+			continue;
+		}
+
+		if (!of_device_is_available(child))
+			continue;
+
+		channel = &imx_ldb->channel[i];
+		channel->ldb = imx_ldb;
+		channel->chno = i;
+
+		edidp = of_get_property(child, "edid", &channel->edid_len);
+		if (edidp) {
+			channel->edid = kmemdup(edidp, channel->edid_len,
+						GFP_KERNEL);
+		} else {
+			ret = of_get_drm_display_mode(child, &channel->mode, 0);
+			if (!ret)
+				channel->mode_valid = 1;
+		}
+
+		ret = of_property_read_u32(child, "fsl,data-width", &datawidth);
+		if (ret)
+			datawidth = 0;
+		else if (datawidth != 18 && datawidth != 24)
+			return -EINVAL;
+
+		mapping = of_get_data_mapping(child);
+		switch (mapping) {
+		case LVDS_BIT_MAP_SPWG:
+			if (datawidth == 24) {
+				if (i == 0 || dual)
+					imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24;
+				if (i == 1 || dual)
+					imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24;
+			}
+			break;
+		case LVDS_BIT_MAP_JEIDA:
+			if (datawidth == 18) {
+				dev_err(&pdev->dev, "JEIDA standard only supported in 24 bit\n");
+				return -EINVAL;
+			}
+			if (i == 0 || dual)
+				imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | LDB_BIT_MAP_CH0_JEIDA;
+			if (i == 1 || dual)
+				imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | LDB_BIT_MAP_CH1_JEIDA;
+			break;
+		default:
+			dev_err(&pdev->dev, "data mapping not specified or invalid\n");
+			return -EINVAL;
+		}
+
+		ret = imx_ldb_register(channel);
+		if (ret)
+			return ret;
+
+		imx_drm_encoder_add_possible_crtcs(channel->imx_drm_encoder, child);
+	}
+
+	platform_set_drvdata(pdev, imx_ldb);
+
+	return 0;
+}
+
+static int imx_ldb_remove(struct platform_device *pdev)
+{
+	struct imx_ldb *imx_ldb = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		struct imx_ldb_channel *channel = &imx_ldb->channel[i];
+		struct drm_connector *connector = &channel->connector;
+		struct drm_encoder *encoder = &channel->encoder;
+
+		drm_mode_connector_detach_encoder(connector, encoder);
+
+		imx_drm_remove_connector(channel->imx_drm_connector);
+		imx_drm_remove_encoder(channel->imx_drm_encoder);
+	}
+
+	return 0;
+}
+
+static struct platform_driver imx_ldb_driver = {
+	.probe		= imx_ldb_probe,
+	.remove		= imx_ldb_remove,
+	.driver		= {
+		.of_match_table = imx_ldb_dt_ids,
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+module_platform_driver(imx_ldb_driver);
+
+MODULE_DESCRIPTION("i.MX LVDS driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/imx-tve.c linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/imx-tve.c
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/imx-tve.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/imx-tve.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/clk-provider.h>
 #include <linux/module.h>
 #include <linux/of_i2c.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
@@ -610,15 +609,6 @@ static int imx_tve_probe(struct platform
 	}
 
 	if (tve->mode == TVE_MODE_VGA) {
-		struct pinctrl *pinctrl;
-
-		pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-		if (IS_ERR(pinctrl)) {
-			ret = PTR_ERR(pinctrl);
-			dev_warn(&pdev->dev, "failed to setup pinctrl: %d", ret);
-			return ret;
-		}
-
 		ret = of_property_read_u32(np, "fsl,hsync-pin", &tve->hsync_pin);
 		if (ret < 0) {
 			dev_err(&pdev->dev, "failed to get vsync pin\n");
@@ -638,11 +628,9 @@ static int imx_tve_probe(struct platform
 		return -ENOENT;
 	}
 
-	base = devm_request_and_ioremap(&pdev->dev, res);
-	if (!base) {
-		dev_err(&pdev->dev, "failed to remap memory region\n");
-		return -ENOENT;
-	}
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
 
 	tve_regmap_config.lock_arg = tve;
 	tve->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "tve", base,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/ipu-v3/ipu-common.c linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipu-v3/ipu-common.c
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/ipu-v3/ipu-common.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipu-v3/ipu-common.c	2013-08-25 20:43:22.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/list.h>
 #include <linux/irq.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
 #include <linux/of_device.h>
 
 #include "imx-ipu-v3.h"
@@ -799,16 +800,18 @@ err_di_0:
 static void ipu_irq_handle(struct ipu_soc *ipu, const int *regs, int num_regs)
 {
 	unsigned long status;
-	int i, bit, irq_base;
+	int i, bit, irq;
 
 	for (i = 0; i < num_regs; i++) {
 
 		status = ipu_cm_read(ipu, IPU_INT_STAT(regs[i]));
 		status &= ipu_cm_read(ipu, IPU_INT_CTRL(regs[i]));
 
-		irq_base = ipu->irq_start + regs[i] * 32;
-		for_each_set_bit(bit, &status, 32)
-			generic_handle_irq(irq_base + bit);
+		for_each_set_bit(bit, &status, 32) {
+			irq = irq_linear_revmap(ipu->domain, regs[i] * 32 + bit);
+			if (irq)
+				generic_handle_irq(irq);
+		}
 	}
 }
 
@@ -838,57 +841,15 @@ static void ipu_err_irq_handler(unsigned
 	chained_irq_exit(chip, desc);
 }
 
-static void ipu_ack_irq(struct irq_data *d)
-{
-	struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->irq - ipu->irq_start;
-
-	ipu_cm_write(ipu, 1 << (irq % 32), IPU_INT_STAT(irq / 32));
-}
-
-static void ipu_unmask_irq(struct irq_data *d)
-{
-	struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->irq - ipu->irq_start;
-	unsigned long flags;
-	u32 reg;
-
-	spin_lock_irqsave(&ipu->lock, flags);
-
-	reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32));
-	reg |= 1 << (irq % 32);
-	ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32));
-
-	spin_unlock_irqrestore(&ipu->lock, flags);
-}
-
-static void ipu_mask_irq(struct irq_data *d)
-{
-	struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
-	unsigned int irq = d->irq - ipu->irq_start;
-	unsigned long flags;
-	u32 reg;
-
-	spin_lock_irqsave(&ipu->lock, flags);
-
-	reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32));
-	reg &= ~(1 << (irq % 32));
-	ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32));
-
-	spin_unlock_irqrestore(&ipu->lock, flags);
-}
-
-static struct irq_chip ipu_irq_chip = {
-	.name = "IPU",
-	.irq_ack = ipu_ack_irq,
-	.irq_mask = ipu_mask_irq,
-	.irq_unmask = ipu_unmask_irq,
-};
-
 int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel,
 		enum ipu_channel_irq irq_type)
 {
-	return ipu->irq_start + irq_type + channel->num;
+	int irq = irq_linear_revmap(ipu->domain, irq_type + channel->num);
+
+	if (!irq)
+		irq = irq_create_mapping(ipu->domain, irq_type + channel->num);
+
+	return irq;
 }
 EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq);
 
@@ -975,18 +936,48 @@ err_register:
 	return ret;
 }
 
+
 static int ipu_irq_init(struct ipu_soc *ipu)
 {
-	int i;
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
+	unsigned long unused[IPU_NUM_IRQS / 32] = {
+		0x400100d0, 0xffe000fd,
+		0x400100d0, 0xffe000fd,
+		0x400100d0, 0xffe000fd,
+		0x4077ffff, 0xffe7e1fd,
+		0x23fffffe, 0x8880fff0,
+		0xf98fe7d0, 0xfff81fff,
+		0x400100d0, 0xffe000fd,
+		0x00000000,
+	};
+	int ret, i;
 
-	ipu->irq_start = irq_alloc_descs(-1, 0, IPU_NUM_IRQS, 0);
-	if (ipu->irq_start < 0)
-		return ipu->irq_start;
+	ipu->domain = irq_domain_add_linear(ipu->dev->of_node, IPU_NUM_IRQS,
+					    &irq_generic_chip_ops, ipu);
+	if (!ipu->domain) {
+		dev_err(ipu->dev, "failed to add irq domain\n");
+		return -ENODEV;
+	}
 
-	for (i = ipu->irq_start; i < ipu->irq_start + IPU_NUM_IRQS; i++) {
-		irq_set_chip_and_handler(i, &ipu_irq_chip, handle_level_irq);
-		set_irq_flags(i, IRQF_VALID);
-		irq_set_chip_data(i, ipu);
+	ret = irq_alloc_domain_generic_chips(ipu->domain, 32, 1, "IPU",
+					     handle_level_irq, 0, IRQF_VALID, 0);
+	if (ret < 0) {
+		dev_err(ipu->dev, "failed to alloc generic irq chips\n");
+		irq_domain_remove(ipu->domain);
+		return ret;
+	}
+
+	for (i = 0; i < IPU_NUM_IRQS; i += 32) {
+		gc = irq_get_domain_generic_chip(ipu->domain, i);
+		gc->reg_base = ipu->cm_reg;
+		gc->unused = unused[i / 32];
+		ct = gc->chip_types;
+		ct->chip.irq_ack = irq_gc_ack_set_bit;
+		ct->chip.irq_mask = irq_gc_mask_clr_bit;
+		ct->chip.irq_unmask = irq_gc_mask_set_bit;
+		ct->regs.ack = IPU_INT_STAT(i / 32);
+		ct->regs.mask = IPU_INT_CTRL(i / 32);
 	}
 
 	irq_set_chained_handler(ipu->irq_sync, ipu_irq_handler);
@@ -999,20 +990,22 @@ static int ipu_irq_init(struct ipu_soc *
 
 static void ipu_irq_exit(struct ipu_soc *ipu)
 {
-	int i;
+	int i, irq;
 
 	irq_set_chained_handler(ipu->irq_err, NULL);
 	irq_set_handler_data(ipu->irq_err, NULL);
 	irq_set_chained_handler(ipu->irq_sync, NULL);
 	irq_set_handler_data(ipu->irq_sync, NULL);
 
-	for (i = ipu->irq_start; i < ipu->irq_start + IPU_NUM_IRQS; i++) {
-		set_irq_flags(i, 0);
-		irq_set_chip(i, NULL);
-		irq_set_chip_data(i, NULL);
+	/* TODO: remove irq_domain_generic_chips */
+
+	for (i = 0; i < IPU_NUM_IRQS; i++) {
+		irq = irq_linear_revmap(ipu->domain, i);
+		if (irq)
+			irq_dispose_mapping(irq);
 	}
 
-	irq_free_descs(ipu->irq_start, IPU_NUM_IRQS);
+	irq_domain_remove(ipu->domain);
 }
 
 static int ipu_probe(struct platform_device *pdev)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/ipu-v3/ipu-di.c linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipu-v3/ipu-di.c
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/ipu-v3/ipu-di.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipu-v3/ipu-di.c	2013-08-25 20:43:22.000000000 -0400
@@ -603,7 +603,12 @@ int ipu_di_init_sync_panel(struct ipu_di
 
 		vsync_cnt = 3;
 		if (di->id == 1)
-			vsync_cnt = 6;
+			/*
+			 * TODO: change only for TVEv2, parallel display
+			 * uses pin 2 / 3
+			 */
+			if (!(sig->hsync_pin == 2 && sig->vsync_pin == 3))
+				vsync_cnt = 6;
 
 		if (sig->Hsync_pol) {
 			if (sig->hsync_pin == 2)
@@ -614,11 +619,11 @@ int ipu_di_init_sync_panel(struct ipu_di
 				di_gen |= DI_GEN_POLARITY_7;
 		}
 		if (sig->Vsync_pol) {
-			if (sig->hsync_pin == 3)
+			if (sig->vsync_pin == 3)
 				di_gen |= DI_GEN_POLARITY_3;
-			else if (sig->hsync_pin == 6)
+			else if (sig->vsync_pin == 6)
 				di_gen |= DI_GEN_POLARITY_6;
-			else if (sig->hsync_pin == 8)
+			else if (sig->vsync_pin == 8)
 				di_gen |= DI_GEN_POLARITY_8;
 		}
 	}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c	2013-08-25 20:43:22.000000000 -0400
@@ -61,7 +61,7 @@ struct dmfc_channel_data {
 
 static const struct dmfc_channel_data dmfcdata[] = {
 	{
-		.ipu_channel	= 23,
+		.ipu_channel	= IPUV3_CHANNEL_MEM_BG_SYNC,
 		.channel_reg	= DMFC_DP_CHAN,
 		.shift		= DMFC_DP_CHAN_5B_23,
 		.eot_shift	= 20,
@@ -73,13 +73,13 @@ static const struct dmfc_channel_data dm
 		.eot_shift	= 22,
 		.max_fifo_lines	= 1,
 	}, {
-		.ipu_channel	= 27,
+		.ipu_channel	= IPUV3_CHANNEL_MEM_FG_SYNC,
 		.channel_reg	= DMFC_DP_CHAN,
 		.shift		= DMFC_DP_CHAN_5F_27,
 		.eot_shift	= 21,
 		.max_fifo_lines	= 2,
 	}, {
-		.ipu_channel	= 28,
+		.ipu_channel	= IPUV3_CHANNEL_MEM_DC_SYNC,
 		.channel_reg	= DMFC_WR_CHAN,
 		.shift		= DMFC_WR_CHAN_1_28,
 		.eot_shift	= 16,
@@ -292,7 +292,7 @@ int ipu_dmfc_alloc_bandwidth(struct dmfc
 {
 	struct ipu_dmfc_priv *priv = dmfc->priv;
 	int slots = dmfc_bandwidth_to_slots(priv, bandwidth_pixel_per_second);
-	int segment = 0, ret = 0;
+	int segment = -1, ret = 0;
 
 	dev_dbg(priv->dev, "dmfc: trying to allocate %ldMpixel/s for IPU channel %d\n",
 			bandwidth_pixel_per_second / 1000000,
@@ -307,7 +307,17 @@ int ipu_dmfc_alloc_bandwidth(struct dmfc
 		goto out;
 	}
 
-	segment = dmfc_find_slots(priv, slots);
+	/* Always allocate at least 128*4 bytes (2 slots) */
+	if (slots < 2)
+		slots = 2;
+
+	/* For the MEM_BG channel, first try to allocate twice the slots */
+	if (dmfc->data->ipu_channel == IPUV3_CHANNEL_MEM_BG_SYNC)
+		segment = dmfc_find_slots(priv, slots * 2);
+	if (segment >= 0)
+		slots *= 2;
+	else
+		segment = dmfc_find_slots(priv, slots);
 	if (segment < 0) {
 		ret = -EBUSY;
 		goto out;
@@ -391,7 +401,7 @@ int ipu_dmfc_init(struct ipu_soc *ipu, s
 	 * We have a total bandwidth of clkrate * 4pixel divided
 	 * into 8 slots.
 	 */
-	priv->bandwidth_per_slot = clk_get_rate(ipu_clk) / 8;
+	priv->bandwidth_per_slot = clk_get_rate(ipu_clk) * 4 / 8;
 
 	dev_dbg(dev, "dmfc: 8 slots with %ldMpixel/s bandwidth each\n",
 			priv->bandwidth_per_slot / 1000000);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/ipu-v3/ipu-prv.h linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipu-v3/ipu-prv.h
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/ipu-v3/ipu-prv.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipu-v3/ipu-prv.h	2013-08-25 20:43:22.000000000 -0400
@@ -110,7 +110,7 @@ struct ipu_soc;
 #define IDMAC_BAND_EN(ch)		IPU_IDMAC_REG(0x0040 + 4 * ((ch) / 32))
 #define IDMAC_CHA_BUSY(ch)		IPU_IDMAC_REG(0x0100 + 4 * ((ch) / 32))
 
-#define IPU_NUM_IRQS	(32 * 5)
+#define IPU_NUM_IRQS	(32 * 15)
 
 enum ipu_modules {
 	IPU_CONF_CSI0_EN		= (1 << 0),
@@ -170,9 +170,9 @@ struct ipu_soc {
 
 	struct ipuv3_channel	channel[64];
 
-	int			irq_start;
 	int			irq_sync;
 	int			irq_err;
+	struct irq_domain	*domain;
 
 	struct ipu_dc_priv	*dc_priv;
 	struct ipu_dp_priv	*dp_priv;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/ipuv3-crtc.c linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipuv3-crtc.c
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/ipuv3-crtc.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/ipuv3-crtc.c	2013-08-25 20:43:22.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <drm/drmP.h>
-#include <drm/drm_fb_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <linux/fb.h>
 #include <linux/clk.h>
@@ -42,9 +41,6 @@ struct ipu_framebuffer {
 };
 
 struct ipu_crtc {
-	struct drm_fb_helper	fb_helper;
-	struct ipu_framebuffer	ifb;
-	int			num_crtcs;
 	struct device		*dev;
 	struct drm_crtc		base;
 	struct imx_drm_crtc	*imx_crtc;
@@ -54,7 +50,6 @@ struct ipu_crtc {
 	struct dmfc_channel	*dmfc;
 	struct ipu_di		*di;
 	int			enabled;
-	struct ipu_priv		*ipu_priv;
 	struct drm_pending_vblank_event *page_flip_event;
 	struct drm_framebuffer	*newfb;
 	int			irq;
@@ -152,6 +147,7 @@ static int ipu_page_flip(struct drm_crtc
 
 	ipu_crtc->newfb = fb;
 	ipu_crtc->page_flip_event = event;
+	crtc->fb = fb;
 
 	return 0;
 }
@@ -334,7 +330,6 @@ static irqreturn_t ipu_irq_handler(int i
 	imx_drm_handle_vblank(ipu_crtc->imx_crtc);
 
 	if (ipu_crtc->newfb) {
-		ipu_crtc->base.fb = ipu_crtc->newfb;
 		ipu_crtc->newfb = NULL;
 		ipu_drm_set_base(&ipu_crtc->base, 0, 0);
 		ipu_crtc_handle_pageflip(ipu_crtc);
@@ -364,17 +359,12 @@ static void ipu_crtc_commit(struct drm_c
 	ipu_fb_enable(ipu_crtc);
 }
 
-static void ipu_crtc_load_lut(struct drm_crtc *crtc)
-{
-}
-
 static struct drm_crtc_helper_funcs ipu_helper_funcs = {
 	.dpms = ipu_crtc_dpms,
 	.mode_fixup = ipu_crtc_mode_fixup,
 	.mode_set = ipu_crtc_mode_set,
 	.prepare = ipu_crtc_prepare,
 	.commit = ipu_crtc_commit,
-	.load_lut = ipu_crtc_load_lut,
 };
 
 static int ipu_enable_vblank(struct drm_crtc *crtc)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -30,6 +30,13 @@ config DRM_IMX_TVE
 	  Choose this to enable the internal Television Encoder (TVe)
 	  found on i.MX53 processors.
 
+config DRM_IMX_LDB
+	tristate "Support for LVDS displays"
+	depends on DRM_IMX
+	help
+	  Choose this to enable the internal LVDS Display Bridge (LDB)
+	  found on i.MX53 and i.MX6 processors.
+
 config DRM_IMX_IPUV3_CORE
 	tristate "IPUv3 core support"
 	depends on DRM_IMX
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/Makefile
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/Makefile	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -5,6 +5,7 @@ obj-$(CONFIG_DRM_IMX) += imxdrm.o
 
 obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o
 obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o
+obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
 obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o
 obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/
 obj-$(CONFIG_DRM_IMX_IPUV3)	+= ipuv3-crtc.o
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/parallel-display.c linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/parallel-display.c
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/parallel-display.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/parallel-display.c	2013-08-25 20:43:22.000000000 -0400
@@ -23,7 +23,6 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <linux/videodev2.h>
-#include <linux/pinctrl/consumer.h>
 
 #include "imx-drm.h"
 
@@ -206,20 +205,11 @@ static int imx_pd_probe(struct platform_
 	struct imx_parallel_display *imxpd;
 	int ret;
 	const char *fmt;
-	struct pinctrl *pinctrl;
 
 	imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL);
 	if (!imxpd)
 		return -ENOMEM;
 
-	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	if (IS_ERR(pinctrl)) {
-		ret = PTR_ERR(pinctrl);
-		dev_warn(&pdev->dev, "pinctrl_get_select_default failed with %d",
-				ret);
-		return ret;
-	}
-
 	edidp = of_get_property(np, "edid", &imxpd->edid_len);
 	if (edidp)
 		imxpd->edid = kmemdup(edidp, imxpd->edid_len, GFP_KERNEL);
@@ -265,6 +255,7 @@ static const struct of_device_id imx_pd_
 	{ .compatible = "fsl,imx-parallel-display", },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, imx_pd_dt_ids);
 
 static struct platform_driver imx_pd_driver = {
 	.probe		= imx_pd_probe,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/imx-drm/TODO linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/TODO
--- linux-libre-3.10-gnu/drivers/staging/imx-drm/TODO	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/imx-drm/TODO	2013-08-25 20:43:22.000000000 -0400
@@ -6,7 +6,6 @@ TODO:
 - Factor out more code to common helper functions
 - decide where to put the base driver. It is not specific to a subsystem
   and would be used by DRM/KMS and media/V4L2
-- convert irq driver to irq_domain_add_linear
 
 Missing features (not necessarily for moving out of staging):
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/Kconfig	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -62,6 +62,8 @@ source "drivers/staging/line6/Kconfig"
 
 source "drivers/staging/octeon/Kconfig"
 
+source "drivers/staging/octeon-usb/Kconfig"
+
 source "drivers/staging/serqt_usb2/Kconfig"
 
 source "drivers/staging/vt6655/Kconfig"
@@ -116,10 +118,6 @@ source "drivers/staging/ozwpan/Kconfig"
 
 source "drivers/staging/gdm72xx/Kconfig"
 
-source "drivers/staging/csr/Kconfig"
-
-source "drivers/staging/ti-soc-thermal/Kconfig"
-
 source "drivers/staging/silicom/Kconfig"
 
 source "drivers/staging/ced1401/Kconfig"
@@ -140,4 +138,8 @@ source "drivers/staging/netlogic/Kconfig
 
 source "drivers/staging/dwc2/Kconfig"
 
+source "drivers/staging/lustre/Kconfig"
+
+source "drivers/staging/btmtk_usb/Kconfig"
+
 endif # STAGING
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/init.c linux-libre-3.11-rc7-gnu/drivers/staging/keucr/init.c
--- linux-libre-3.10-gnu/drivers/staging/keucr/init.c	2013-07-01 10:43:06.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/init.c	2013-08-31 18:02:54.000000000 -0400
@@ -19,13 +19,13 @@ int ENE_InitMedia(struct us_data *us)
 	int	result;
 	BYTE	MiscReg03 = 0;
 
-	printk(KERN_INFO "--- Init Media ---\n");
-	result = ENE_Read_BYTE(us, REG_CARD_STATUS, &MiscReg03);
+	dev_info(&us->pusb_dev->dev, "--- Init Media ---\n");
+	result = ene_read_byte(us, REG_CARD_STATUS, &MiscReg03);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk(KERN_ERR "Read register fail !!\n");
+		dev_err(&us->pusb_dev->dev, "Failed to read register\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
-	printk(KERN_INFO "MiscReg03 = %x\n", MiscReg03);
+	dev_info(&us->pusb_dev->dev, "MiscReg03 = %x\n", MiscReg03);
 
 	if (MiscReg03 & 0x02) {
 		if (!us->SM_Status.Ready && !us->MS_Status.Ready) {
@@ -39,9 +39,9 @@ int ENE_InitMedia(struct us_data *us)
 }
 
 /*
- * ENE_Read_BYTE() :
+ * ene_read_byte() :
  */
-int ENE_Read_BYTE(struct us_data *us, WORD index, void *buf)
+int ene_read_byte(struct us_data *us, WORD index, void *buf)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int result;
@@ -67,11 +67,13 @@ int ENE_SMInit(struct us_data *us)
 	int	result;
 	BYTE	buf[0x200];
 
-	printk(KERN_INFO "transport --- ENE_SMInit\n");
+	dev_dbg(&us->pusb_dev->dev, "transport --- ENE_SMInit\n");
 
 	result = ENE_LoadBinCode(us, SM_INIT_PATTERN);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk(KERN_INFO "Load SM Init Code Fail !!\n");
+		dev_info(&us->pusb_dev->dev,
+			 "Failed to load SmartMedia init code\n: result= %x\n",
+			 result);
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -84,26 +86,33 @@ int ENE_SMInit(struct us_data *us)
 
 	result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk(KERN_ERR
-		       "Execution SM Init Code Fail !! result = %x\n", result);
+		dev_err(&us->pusb_dev->dev,
+			"Failed to load SmartMedia init code: result = %x\n",
+			result);
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
-	us->SM_Status = *(PSM_STATUS)&buf[0];
+	us->SM_Status = *(struct keucr_sm_status *)&buf[0];
 
 	us->SM_DeviceID = buf[1];
 	us->SM_CardID   = buf[2];
 
 	if (us->SM_Status.Insert && us->SM_Status.Ready) {
-		printk(KERN_INFO "Insert     = %x\n", us->SM_Status.Insert);
-		printk(KERN_INFO "Ready      = %x\n", us->SM_Status.Ready);
-		printk(KERN_INFO "WtP        = %x\n", us->SM_Status.WtP);
-		printk(KERN_INFO "DeviceID   = %x\n", us->SM_DeviceID);
-		printk(KERN_INFO "CardID     = %x\n", us->SM_CardID);
+		dev_info(&us->pusb_dev->dev, "Insert     = %x\n",
+					     us->SM_Status.Insert);
+		dev_info(&us->pusb_dev->dev, "Ready      = %x\n",
+					     us->SM_Status.Ready);
+		dev_info(&us->pusb_dev->dev, "WtP        = %x\n",
+					     us->SM_Status.WtP);
+		dev_info(&us->pusb_dev->dev, "DeviceID   = %x\n",
+					     us->SM_DeviceID);
+		dev_info(&us->pusb_dev->dev, "CardID     = %x\n",
+					     us->SM_CardID);
 		MediaChange = 1;
 		Check_D_MediaFmt(us);
 	} else {
-		printk(KERN_ERR "SM Card Not Ready --- %x\n", buf[0]);
+		dev_err(&us->pusb_dev->dev,
+			"SmartMedia Card Not Ready --- %x\n", buf[0]);
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -120,7 +129,7 @@ int ENE_LoadBinCode(struct us_data *us,
 	/* void *buf; */
 	PBYTE buf;
 
-	/* printk(KERN_INFO "transport --- ENE_LoadBinCode\n"); */
+	/* dev_info(&us->pusb_dev->dev, "transport --- ENE_LoadBinCode\n"); */
 	if (us->BIN_FLAG == flag)
 		return USB_STOR_TRANSPORT_GOOD;
 
@@ -131,11 +140,11 @@ int ENE_LoadBinCode(struct us_data *us,
 	switch (flag) {
 	/* For SS */
 	case SM_INIT_PATTERN:
-		printk(KERN_INFO "SM_INIT_PATTERN\n");
+		dev_dbg(&us->pusb_dev->dev, "SM_INIT_PATTERN\n");
 		memcpy(buf, SM_Init, 0x800);
 		break;
 	case SM_RW_PATTERN:
-		printk(KERN_INFO "SM_RW_PATTERN\n");
+		dev_dbg(&us->pusb_dev->dev, "SM_RW_PATTERN\n");
 		memcpy(buf, SM_Rdwr, 0x800);
 		break;
 	}
@@ -166,12 +175,13 @@ int ENE_SendScsiCmd(struct us_data *us,
 		     cswlen = 0, partial = 0;
 	unsigned int residue;
 
-	/* printk(KERN_INFO "transport --- ENE_SendScsiCmd\n"); */
+	/* dev_dbg(&us->pusb_dev->dev, "transport --- ENE_SendScsiCmd\n"); */
 	/* send cmd to out endpoint */
 	result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
 					    bcb, US_BULK_CB_WRAP_LEN, NULL);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk(KERN_ERR "send cmd to out endpoint fail ---\n");
+		dev_err(&us->pusb_dev->dev,
+				"send cmd to out endpoint fail ---\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -190,7 +200,7 @@ int ENE_SendScsiCmd(struct us_data *us,
 			result = usb_stor_bulk_transfer_sg(us, pipe, buf,
 						transfer_length, 0, &partial);
 		if (result != USB_STOR_XFER_GOOD) {
-			printk(KERN_ERR "data transfer fail ---\n");
+			dev_err(&us->pusb_dev->dev, "data transfer fail ---\n");
 			return USB_STOR_TRANSPORT_ERROR;
 		}
 	}
@@ -200,14 +210,16 @@ int ENE_SendScsiCmd(struct us_data *us,
 						US_BULK_CS_WRAP_LEN, &cswlen);
 
 	if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
-		printk(KERN_WARNING "Received 0-length CSW; retrying...\n");
+		dev_warn(&us->pusb_dev->dev,
+				"Received 0-length CSW; retrying...\n");
 		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 					bcs, US_BULK_CS_WRAP_LEN, &cswlen);
 	}
 
 	if (result == USB_STOR_XFER_STALLED) {
 		/* get the status again */
-		printk(KERN_WARNING "Attempting to get CSW (2nd try)...\n");
+		dev_warn(&us->pusb_dev->dev,
+				"Attempting to get CSW (2nd try)...\n");
 		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 						bcs, US_BULK_CS_WRAP_LEN, NULL);
 	}
@@ -244,7 +256,7 @@ int ENE_Read_Data(struct us_data *us, vo
 	struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
 	int result;
 
-	/* printk(KERN_INFO "transport --- ENE_Read_Data\n"); */
+	/* dev_dbg(&us->pusb_dev->dev, "transport --- ENE_Read_Data\n"); */
 	/* set up the command wrapper */
 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -319,55 +331,3 @@ int ENE_Write_Data(struct us_data *us, v
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-/*
- * usb_stor_print_cmd():
- */
-void usb_stor_print_cmd(struct scsi_cmnd *srb)
-{
-	PBYTE	Cdb = srb->cmnd;
-	DWORD	cmd = Cdb[0];
-	DWORD	bn  =	((Cdb[2] << 24) & 0xff000000) |
-			((Cdb[3] << 16) & 0x00ff0000) |
-			((Cdb[4] << 8) & 0x0000ff00) |
-			((Cdb[5] << 0) & 0x000000ff);
-	WORD	blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff);
-
-	switch (cmd) {
-	case TEST_UNIT_READY:
-		/* printk(KERN_INFO
-			 "scsi cmd %X --- SCSIOP_TEST_UNIT_READY\n", cmd); */
-		break;
-	case INQUIRY:
-		printk(KERN_INFO "scsi cmd %X --- SCSIOP_INQUIRY\n", cmd);
-		break;
-	case MODE_SENSE:
-		printk(KERN_INFO "scsi cmd %X --- SCSIOP_MODE_SENSE\n", cmd);
-		break;
-	case START_STOP:
-		printk(KERN_INFO "scsi cmd %X --- SCSIOP_START_STOP\n", cmd);
-		break;
-	case READ_CAPACITY:
-		printk(KERN_INFO "scsi cmd %X --- SCSIOP_READ_CAPACITY\n", cmd);
-		break;
-	case READ_10:
-		/*  printk(KERN_INFO
-			   "scsi cmd %X --- SCSIOP_READ,bn = %X, blen = %X\n"
-			   ,cmd, bn, blen); */
-		break;
-	case WRITE_10:
-		/* printk(KERN_INFO
-			  "scsi cmd %X --- SCSIOP_WRITE,
-			  bn = %X, blen = %X\n" , cmd, bn, blen); */
-		break;
-	case ALLOW_MEDIUM_REMOVAL:
-		printk(KERN_INFO
-			"scsi cmd %X --- SCSIOP_ALLOW_MEDIUM_REMOVAL\n", cmd);
-		break;
-	default:
-		printk(KERN_INFO "scsi cmd %X --- Other cmd\n", cmd);
-		break;
-	}
-	bn = 0;
-	blen = 0;
-}
-
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/scsiglue.c linux-libre-3.11-rc7-gnu/drivers/staging/keucr/scsiglue.c
--- linux-libre-3.10-gnu/drivers/staging/keucr/scsiglue.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/scsiglue.c	2013-08-25 20:43:22.000000000 -0400
@@ -73,7 +73,8 @@ static int slave_configure(struct scsi_d
 		if (us->fflags & US_FL_CAPACITY_HEURISTICS)
 			sdev->guess_capacity = 1;
 		if (sdev->scsi_level > SCSI_2)
-			sdev->sdev_target->scsi_level = sdev->scsi_level = SCSI_2;
+			sdev->sdev_target->scsi_level = sdev->scsi_level
+								= SCSI_2;
 		sdev->retry_hwerror = 1;
 		sdev->allow_restart = 1;
 		sdev->last_sector_bug = 1;
@@ -144,7 +145,7 @@ static int command_abort(struct scsi_cmn
 	scsi_lock(us_to_host(us));
 	if (us->srb != srb) {
 		scsi_unlock(us_to_host(us));
-		printk("-- nothing to abort\n");
+		dev_info(&us->pusb_dev->dev, "-- nothing to abort\n");
 		return FAILED;
 	}
 
@@ -319,8 +320,11 @@ static ssize_t store_max_sectors(struct
 	return -EINVAL;
 }
 
-static DEVICE_ATTR(max_sectors, S_IRUGO | S_IWUSR, show_max_sectors, store_max_sectors);
-static struct device_attribute *sysfs_device_attr_list[] = {&dev_attr_max_sectors, NULL, };
+static DEVICE_ATTR(max_sectors, S_IRUGO | S_IWUSR, show_max_sectors,
+							store_max_sectors);
+static struct device_attribute *sysfs_device_attr_list[] = {
+	&dev_attr_max_sectors, NULL,
+};
 
 /* this defines our host template, with which we'll allocate hosts */
 
@@ -393,8 +397,9 @@ unsigned char usb_stor_sense_invalidCDB[
 /*
  * usb_stor_access_xfer_buf()
  */
-unsigned int usb_stor_access_xfer_buf(struct us_data *us, unsigned char *buffer,
-	unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
+unsigned int usb_stor_access_xfer_buf(struct us_data *us,
+	unsigned char *buffer, unsigned int buflen,
+	struct scsi_cmnd *srb, struct scatterlist **sgptr,
 	unsigned int *offset, enum xfer_buf_dir dir)
 {
 	unsigned int cnt;
@@ -424,7 +429,7 @@ unsigned int usb_stor_access_xfer_buf(st
 
 		while (sglen > 0) {
 			unsigned int plen = min(sglen,
-						(unsigned int)PAGE_SIZE - poff);
+					(unsigned int)PAGE_SIZE - poff);
 			unsigned char *ptr = kmap(page);
 
 			if (dir == TO_XFER_BUF)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/smil.h linux-libre-3.11-rc7-gnu/drivers/staging/keucr/smil.h
--- linux-libre-3.10-gnu/drivers/staging/keucr/smil.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/smil.h	2013-08-25 20:43:22.000000000 -0400
@@ -168,7 +168,7 @@ SmartMedia Model & Attribute
 /***************************************************************************
 Struct Definition
 ***************************************************************************/
-struct SSFDCTYPE {
+struct keucr_media_info {
 	BYTE Model;
 	BYTE Attribute;
 	BYTE MaxZones;
@@ -177,30 +177,14 @@ struct SSFDCTYPE {
 	WORD MaxLogBlocks;
 };
 
-typedef struct SSFDCTYPE_T {
-	BYTE Model;
-	BYTE Attribute;
-	BYTE MaxZones;
-	BYTE MaxSectors;
-	WORD MaxBlocks;
-	WORD MaxLogBlocks;
-} *SSFDCTYPE_T;
-
-struct ADDRESS {
+struct keucr_media_address {
 	BYTE Zone;	/* Zone Number */
 	BYTE Sector;	/* Sector(512byte) Number on Block */
 	WORD PhyBlock;	/* Physical Block Number on Zone */
 	WORD LogBlock;	/* Logical Block Number of Zone */
 };
 
-typedef struct ADDRESS_T {
-	BYTE Zone;	/* Zone Number */
-	BYTE Sector;	/* Sector(512byte) Number on Block */
-	WORD PhyBlock;	/* Physical Block Number on Zone */
-	WORD LogBlock;	/* Logical Block Number of Zone */
-} *ADDRESS_T;
-
-struct CIS_AREA {
+struct keucr_media_area {
 	BYTE Sector;	/* Sector(512byte) Number on Block */
 	WORD PhyBlock;	/* Physical Block Number on Zone 0 */
 };
@@ -215,9 +199,9 @@ extern WORD	ReadBlock;
 extern WORD	WriteBlock;
 extern DWORD	MediaChange;
 
-extern struct SSFDCTYPE  Ssfdc;
-extern struct ADDRESS    Media;
-extern struct CIS_AREA   CisArea;
+extern struct keucr_media_info    Ssfdc;
+extern struct keucr_media_address Media;
+extern struct keucr_media_area    CisArea;
 
 /*
  * SMILMain.c
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/smilmain.c linux-libre-3.11-rc7-gnu/drivers/staging/keucr/smilmain.c
--- linux-libre-3.10-gnu/drivers/staging/keucr/smilmain.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/smilmain.c	2013-08-25 20:43:22.000000000 -0400
@@ -4,204 +4,135 @@
 #include "smcommon.h"
 #include "smil.h"
 
-int         Check_D_LogCHS              (WORD *,BYTE *,BYTE *);
-void        Initialize_D_Media          (void);
-void        PowerOff_D_Media            (void);
-int         Check_D_MediaPower          (void);
-int         Check_D_MediaExist          (void);
-int         Check_D_MediaWP             (void);
-int         Check_D_MediaFmt            (struct us_data *);
-int         Check_D_MediaFmtForEraseAll (struct us_data *);
-int         Conv_D_MediaAddr            (struct us_data *, DWORD);
-int         Inc_D_MediaAddr             (struct us_data *);
-int         Check_D_FirstSect           (void);
-int         Check_D_LastSect            (void);
-int         Media_D_ReadOneSect         (struct us_data *, WORD, BYTE *);
-int         Media_D_WriteOneSect        (struct us_data *, WORD, BYTE *);
-int         Media_D_CopyBlockHead       (struct us_data *);
-int         Media_D_CopyBlockTail       (struct us_data *);
-int         Media_D_EraseOneBlock       (void);
-int         Media_D_EraseAllBlock       (void);
+int         Check_D_LogCHS(WORD *, BYTE *, BYTE *);
+void        Initialize_D_Media(void);
+void        PowerOff_D_Media(void);
+int         Check_D_MediaPower(void);
+int         Check_D_MediaExist(void);
+int         Check_D_MediaWP(void);
+int         Check_D_MediaFmt(struct us_data *);
+int         Check_D_MediaFmtForEraseAll(struct us_data *);
+int         Conv_D_MediaAddr(struct us_data *, DWORD);
+int         Inc_D_MediaAddr(struct us_data *);
+int         Check_D_FirstSect(void);
+int         Check_D_LastSect(void);
+int         Media_D_ReadOneSect(struct us_data *, WORD, BYTE *);
+int         Media_D_WriteOneSect(struct us_data *, WORD, BYTE *);
+int         Media_D_CopyBlockHead(struct us_data *);
+int         Media_D_CopyBlockTail(struct us_data *);
+int         Media_D_EraseOneBlock(void);
+int         Media_D_EraseAllBlock(void);
 
-int  Copy_D_BlockAll             (struct us_data *, DWORD);
-int  Copy_D_BlockHead            (struct us_data *);
-int  Copy_D_BlockTail            (struct us_data *);
-int  Reassign_D_BlockHead        (struct us_data *);
+int  Copy_D_BlockAll(struct us_data *, DWORD);
+int  Copy_D_BlockHead(struct us_data *);
+int  Copy_D_BlockTail(struct us_data *);
+int  Reassign_D_BlockHead(struct us_data *);
 
-int  Assign_D_WriteBlock         (void);
-int  Release_D_ReadBlock         (struct us_data *);
-int  Release_D_WriteBlock        (struct us_data *);
-int  Release_D_CopySector        (struct us_data *);
+int  Assign_D_WriteBlock(void);
+int  Release_D_ReadBlock(struct us_data *);
+int  Release_D_WriteBlock(struct us_data *);
+int  Release_D_CopySector(struct us_data *);
 
-int  Copy_D_PhyOneSect           (struct us_data *);
-int  Read_D_PhyOneSect           (struct us_data *, WORD, BYTE *);
-int  Write_D_PhyOneSect          (struct us_data *, WORD, BYTE *);
-int  Erase_D_PhyOneBlock         (struct us_data *);
+int  Copy_D_PhyOneSect(struct us_data *);
+int  Read_D_PhyOneSect(struct us_data *, WORD, BYTE *);
+int  Write_D_PhyOneSect(struct us_data *, WORD, BYTE *);
+int  Erase_D_PhyOneBlock(struct us_data *);
 
-int  Set_D_PhyFmtValue           (struct us_data *);
-int  Search_D_CIS                (struct us_data *);
-int  Make_D_LogTable             (struct us_data *);
-void Check_D_BlockIsFull         (void);
+int  Set_D_PhyFmtValue(struct us_data *);
+int  Search_D_CIS(struct us_data *);
+int  Make_D_LogTable(struct us_data *);
+void Check_D_BlockIsFull(void);
 
-int  MarkFail_D_PhyOneBlock      (struct us_data *);
+int  MarkFail_D_PhyOneBlock(struct us_data *);
 
 DWORD ErrXDCode;
 DWORD ErrCode;
-//BYTE  SectBuf[SECTSIZE];
 static BYTE  WorkBuf[SECTSIZE];
 static BYTE  Redundant[REDTSIZE];
 static BYTE  WorkRedund[REDTSIZE];
-//WORD  Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK];
-static WORD  *Log2Phy[MAX_ZONENUM];                 // 128 x 1000,   Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK];
-static BYTE  Assign[MAX_ZONENUM][MAX_BLOCKNUM/8];
+/* 128 x 1000, Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK]; */
+static WORD  *Log2Phy[MAX_ZONENUM];
+static BYTE  Assign[MAX_ZONENUM][MAX_BLOCKNUM / 8];
 static WORD  AssignStart[MAX_ZONENUM];
 WORD  ReadBlock;
 WORD  WriteBlock;
 DWORD MediaChange;
 static DWORD SectCopyMode;
 
-//BIT Control Macro
-static BYTE BitData[] = { 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 } ;
-#define Set_D_Bit(a,b)    (a[(BYTE)((b)/8)]|= BitData[(b)%8])
-#define Clr_D_Bit(a,b)    (a[(BYTE)((b)/8)]&=~BitData[(b)%8])
-#define Chk_D_Bit(a,b)    (a[(BYTE)((b)/8)] & BitData[(b)%8])
+/* BIT Control Macro */
+static BYTE BitData[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
+#define Set_D_Bit(a, b)    (a[(BYTE)((b) / 8)] |= BitData[(b) % 8])
+#define Clr_D_Bit(a, b)    (a[(BYTE)((b) / 8)] &= ~BitData[(b) % 8])
+#define Chk_D_Bit(a, b)    (a[(BYTE)((b) / 8)] & BitData[(b) % 8])
 
-//extern PBYTE    SMHostAddr;
 BYTE     IsSSFDCCompliance;
 BYTE     IsXDCompliance;
 
 
-//
-////Power Control & Media Exist Check Function
-////----- Init_D_SmartMedia() --------------------------------------------
-//int Init_D_SmartMedia(void)
-//{
-//    int     i;
-//
-//    EMCR_Print("Init_D_SmartMedia start\n");
-//    for (i=0; i<MAX_ZONENUM; i++)
-//    {
-//        if (Log2Phy[i]!=NULL)
-//        {
-//            EMCR_Print("ExFreePool Zone = %x, Addr = %x\n", i, Log2Phy[i]);
-//            ExFreePool(Log2Phy[i]);
-//            Log2Phy[i] = NULL;
-//        }
-//    }
-//
-//    Initialize_D_Media();
-//    return(NO_ERROR);
-//}
-
-//----- SM_FreeMem() -------------------------------------------------
+/* ----- SM_FreeMem() ------------------------------------------------- */
 int SM_FreeMem(void)
 {
 	int	i;
 
 	pr_info("SM_FreeMem start\n");
-	for (i=0; i<MAX_ZONENUM; i++)
-	{
-		if (Log2Phy[i]!=NULL)
-		{
+	for (i = 0; i < MAX_ZONENUM; i++) {
+		if (Log2Phy[i] != NULL) {
 			pr_info("Free Zone = %x, Addr = %p\n", i, Log2Phy[i]);
 			kfree(Log2Phy[i]);
 			Log2Phy[i] = NULL;
 		}
 	}
-	return(NO_ERROR);
+	return NO_ERROR;
 }
 
-////----- Pwoff_D_SmartMedia() -------------------------------------------
-//int Pwoff_D_SmartMedia(void)
-//{
-//    PowerOff_D_Media();
-//    return(NO_ERROR);
-//}
-//
-////----- Check_D_SmartMedia() -------------------------------------------
-//int Check_D_SmartMedia(void)
-//{
-//    if (Check_D_MediaExist())
-//        return(ErrCode);
-//
-//    return(NO_ERROR);
-//}
-//
-////----- Check_D_Parameter() --------------------------------------------
-//int Check_D_Parameter(PFDO_DEVICE_EXTENSION fdoExt,WORD *pcyl,BYTE *phead,BYTE *psect)
-//{
-//    if (Check_D_MediaPower())
-//        return(ErrCode);
-//
-//    if (Check_D_MediaFmt(fdoExt))
-//        return(ErrCode);
-//
-//    if (Check_D_LogCHS(pcyl,phead,psect))
-//        return(ErrCode);
-//
-//    return(NO_ERROR);
-//}
-
-//SmartMedia Read/Write/Erase Function
-//----- Media_D_ReadSector() -------------------------------------------
-int Media_D_ReadSector(struct us_data *us, DWORD start,WORD count,BYTE *buf)
+/* SmartMedia Read/Write/Erase Function */
+/* ----- Media_D_ReadSector() ------------------------------------------- */
+int Media_D_ReadSector(struct us_data *us, DWORD start, WORD count, BYTE *buf)
 {
 	WORD len, bn;
 
-	//if (Check_D_MediaPower())        ; ¦b 6250 don't care
-	//    return(ErrCode);
-	//if (Check_D_MediaFmt(fdoExt))    ;
-	//    return(ErrCode);
 	if (Conv_D_MediaAddr(us, start))
-		return(ErrCode);
+		return ErrCode;
 
-	while(1)
-	{
+	while (1) {
 		len = Ssfdc.MaxSectors - Media.Sector;
 		if (count > len)
 			bn = len;
 		else
 			bn = count;
-		//if (Media_D_ReadOneSect(fdoExt, SectBuf))
-		//if (Media_D_ReadOneSect(fdoExt, count, buf))
-		if (Media_D_ReadOneSect(us, bn, buf))
-		{
+
+		if (Media_D_ReadOneSect(us, bn, buf)) {
 			ErrCode = ERR_EccReadErr;
-			return(ErrCode);
+			return ErrCode;
 		}
 
 		Media.Sector += bn;
 		count -= bn;
 
-		if (count<=0)
+		if (count <= 0)
 			break;
 
 		buf += bn * SECTSIZE;
 
 		if (Inc_D_MediaAddr(us))
-			return(ErrCode);
+			return ErrCode;
 	}
 
-	return(NO_ERROR);
+	return NO_ERROR;
 }
-// here
-//----- Media_D_CopySector() ------------------------------------------
-int Media_D_CopySector(struct us_data *us, DWORD start,WORD count,BYTE *buf)
+/* here */
+/* ----- Media_D_CopySector() ------------------------------------------ */
+int Media_D_CopySector(struct us_data *us, DWORD start, WORD count, BYTE *buf)
 {
-	//DWORD mode;
-	//int i;
 	WORD len, bn;
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
 	/* pr_info("Media_D_CopySector !!!\n"); */
 	if (Conv_D_MediaAddr(us, start))
-		return(ErrCode);
+		return ErrCode;
 
-	while(1)
-	{
+	while (1) {
 		if (Assign_D_WriteBlock())
-			return(ERROR);
+			return ERROR;
 
 		len = Ssfdc.MaxSectors - Media.Sector;
 		if (count > len)
@@ -209,607 +140,137 @@ int Media_D_CopySector(struct us_data *u
 		else
 		bn = count;
 
-		//if (Ssfdc_D_CopyBlock(fdoExt,count,buf,Redundant))
-		if (Ssfdc_D_CopyBlock(us,bn,buf,Redundant))
-		{
+		if (Ssfdc_D_CopyBlock(us, bn, buf, Redundant)) {
 			ErrCode = ERR_WriteFault;
-			return(ErrCode);
+			return ErrCode;
 		}
 
 		Media.Sector = 0x1F;
-		//if (Release_D_ReadBlock(fdoExt))
-		if (Release_D_CopySector(us))
-		{
-			if (ErrCode==ERR_HwError)
-			{
+		if (Release_D_CopySector(us)) {
+			if (ErrCode == ERR_HwError) {
 				ErrCode = ERR_WriteFault;
-				return(ErrCode);
+				return ErrCode;
 			}
 		}
 		count -= bn;
 
-		if (count<=0)
+		if (count <= 0)
 			break;
 
 		buf += bn * SECTSIZE;
 
 		if (Inc_D_MediaAddr(us))
-			return(ErrCode);
+			return ErrCode;
 
 	}
-	return(NO_ERROR);
+	return NO_ERROR;
 }
 
-//----- Release_D_CopySector() ------------------------------------------
+/* ----- Release_D_CopySector() ------------------------------------------ */
 int Release_D_CopySector(struct us_data *us)
 {
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-	Log2Phy[Media.Zone][Media.LogBlock]=WriteBlock;
-	Media.PhyBlock=ReadBlock;
+	Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock;
+	Media.PhyBlock = ReadBlock;
 
-	if (Media.PhyBlock==NO_ASSIGN)
-	{
-		Media.PhyBlock=WriteBlock;
-		return(SMSUCCESS);
+	if (Media.PhyBlock == NO_ASSIGN) {
+		Media.PhyBlock = WriteBlock;
+		return SMSUCCESS;
 	}
 
-	Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
-	Media.PhyBlock=WriteBlock;
-
-	return(SMSUCCESS);
-}
-/*
-//----- Media_D_WriteSector() ------------------------------------------
-int Media_D_WriteSector(PFDO_DEVICE_EXTENSION fdoExt, DWORD start,WORD count,BYTE *buf)
-{
-    int i;
-    WORD len, bn;
-    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-    ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-    //if (Check_D_MediaPower())
-    //    return(ErrCode);
-    //
-    //if (Check_D_MediaFmt(fdoExt))
-    //    return(ErrCode);
-    //
-    //if (Check_D_MediaWP())
-    //    return(ErrCode);
-
-    if (Conv_D_MediaAddr(fdoExt, start))
-        return(ErrCode);
-
-    //ENE_Print("Media_D_WriteSector --- Sector = %x\n", Media.Sector);
-    if (Check_D_FirstSect())
-    {
-        if (Media_D_CopyBlockHead(fdoExt))
-        {
-            ErrCode = ERR_WriteFault;
-            return(ErrCode);
-        }
-    }
-
-    while(1)
-    {
-        if (!Check_D_FirstSect())
-        {
-            if (Assign_D_WriteBlock())
-                return(ErrCode);
-        }
-
-        len = Ssfdc.MaxSectors - Media.Sector;
-        if (count > len)
-           bn = len;
-        else
-           bn = count;
-        //for(i=0;i<SECTSIZE;i++)
-        //    SectBuf[i]=*buf++;
-
-        //if (Media_D_WriteOneSect(fdoExt, SectBuf))
-        if (Media_D_WriteOneSect(fdoExt, bn, buf))
-        {
-            ErrCode = ERR_WriteFault;
-            return(ErrCode);
-        }
-
-        Media.Sector += bn - 1;
-
-        if (!Check_D_LastSect())
-        {
-            if (Release_D_ReadBlock(fdoExt))
-
-            {    if (ErrCode==ERR_HwError)
-                {
-                    ErrCode = ERR_WriteFault;
-                    return(ErrCode);
-                }
-            }
-        }
-
-        count -= bn;
-
-        if (count<=0)
-            break;
-
-        buf += bn * SECTSIZE;
-
-        //if (--count<=0)
-        //    break;
-
-        if (Inc_D_MediaAddr(fdoExt))
-            return(ErrCode);
-    }
-
-    if (!Check_D_LastSect())
-        return(NO_ERROR);
-
-    if (Inc_D_MediaAddr(fdoExt))
-        return(ErrCode);
-
-    if (Media_D_CopyBlockTail(fdoExt))
-    {
-        ErrCode = ERR_WriteFault;
-        return(ErrCode);
-    }
-
-    return(NO_ERROR);
-}
-//
-////----- Media_D_EraseBlock() -------------------------------------------
-//int Media_D_EraseBlock(PFDO_DEVICE_EXTENSION fdoExt, DWORD start,WORD count)
-//{
-//    if (Check_D_MediaPower())
-//        return(ErrCode);
-//
-//    if (Check_D_MediaFmt(fdoExt))
-//        return(ErrCode);
-//
-//    if (Check_D_MediaWP())
-//        return(ErrCode);
-//
-//    if (Conv_D_MediaAddr(start))
-//        return(ErrCode);
-//
-//    while(Check_D_FirstSect()) {
-//        if (Inc_D_MediaAddr(fdoExt))
-//            return(ErrCode);
-//
-//        if (--count<=0)
-//            return(NO_ERROR);
-//    }
-//
-//    while(1) {
-//        if (!Check_D_LastSect())
-//            if (Media_D_EraseOneBlock())
-//                if (ErrCode==ERR_HwError)
-//                {
-//                    ErrCode = ERR_WriteFault;
-//                    return(ErrCode);
-//                }
-//
-//        if (Inc_D_MediaAddr(fdoExt))
-//            return(ErrCode);
-//
-//        if (--count<=0)
-//            return(NO_ERROR);
-//    }
-//}
-//
-////----- Media_D_EraseAll() ---------------------------------------------
-//int Media_D_EraseAll(PFDO_DEVICE_EXTENSION fdoExt)
-//{
-//    if (Check_D_MediaPower())
-//        return(ErrCode);
-//
-//    if (Check_D_MediaFmtForEraseAll(fdoExt))
-//        return(ErrCode);
-//
-//    if (Check_D_MediaWP())
-//        return(ErrCode);
-//
-//    if (Media_D_EraseAllBlock())
-//        return(ErrCode);
-//
-//    return(NO_ERROR);
-//}
-
-//SmartMedia Write Function for One Sector Write Mode
-//----- Media_D_OneSectWriteStart() ------------------------------------
-int Media_D_OneSectWriteStart(PFDO_DEVICE_EXTENSION fdoExt,DWORD start,BYTE *buf)
-{
-//  int i;
-//  SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-//  ADDRESS_T   bb = (ADDRESS_T) &Media;
-//
-//  //if (Check_D_MediaPower())
-//  //    return(ErrCode);
-//  //if (Check_D_MediaFmt(fdoExt))
-//  //    return(ErrCode);
-//  //if (Check_D_MediaWP())
-//  //    return(ErrCode);
-//  if (Conv_D_MediaAddr(fdoExt, start))
-//      return(ErrCode);
-//
-//  if (Check_D_FirstSect())
-//      if (Media_D_CopyBlockHead(fdoExt))
-//      {
-//          ErrCode = ERR_WriteFault;
-//          return(ErrCode);
-//      }
-//
-//  if (!Check_D_FirstSect())
-//      if (Assign_D_WriteBlock())
-//          return(ErrCode);
-//
-//  //for(i=0;i<SECTSIZE;i++)
-//  //    SectBuf[i]=*buf++;
-//
-//  //if (Media_D_WriteOneSect(fdoExt, SectBuf))
-//  if (Media_D_WriteOneSect(fdoExt, buf))
-//  {
-//      ErrCode = ERR_WriteFault;
-//      return(ErrCode);
-//  }
-//
-//  if (!Check_D_LastSect())
-//  {
-//      if (Release_D_ReadBlock(fdoExt))
-//          if (ErrCode==ERR_HwError)
-//          {
-//              ErrCode = ERR_WriteFault;
-//              return(ErrCode);
-//          }
-//  }
-
-    return(NO_ERROR);
-}
-
-//----- Media_D_OneSectWriteNext() -------------------------------------
-int Media_D_OneSectWriteNext(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf)
-{
-//  int i;
-//  SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-//  ADDRESS_T   bb = (ADDRESS_T) &Media;
-//
-//  if (Inc_D_MediaAddr(fdoExt))
-//      return(ErrCode);
-//
-//  if (!Check_D_FirstSect())
-//    if (Assign_D_WriteBlock())
-//      return(ErrCode);
-//
-//  //for(i=0;i<SECTSIZE;i++)
-//  //    SectBuf[i]=*buf++;
-//
-//  //if (Media_D_WriteOneSect(fdoExt, SectBuf))
-//  if (Media_D_WriteOneSect(fdoExt, buf))
-//  {
-//      ErrCode = ERR_WriteFault;
-//      return(ErrCode);
-//  }
-//
-//  if (!Check_D_LastSect())
-//  {
-//      if (Release_D_ReadBlock(fdoExt))
-//          if (ErrCode==ERR_HwError)
-//          {
-//              ErrCode = ERR_WriteFault;
-//              return(ErrCode);
-//          }
-//  }
+	Clr_D_Bit(Assign[Media.Zone], Media.PhyBlock);
+	Media.PhyBlock = WriteBlock;
 
-    return(NO_ERROR);
+	return SMSUCCESS;
 }
 
-//----- Media_D_OneSectWriteFlush() ------------------------------------
-int Media_D_OneSectWriteFlush(PFDO_DEVICE_EXTENSION fdoExt)
-{
-    if (!Check_D_LastSect())
-        return(NO_ERROR);
-
-    if (Inc_D_MediaAddr(fdoExt))
-        return(ErrCode);
-
-    if (Media_D_CopyBlockTail(fdoExt))
-    {
-        ErrCode = ERR_WriteFault;
-        return(ErrCode);
-    }
-
-    return(NO_ERROR);
-}
-//
-////LED Tern On/Off Subroutine
-////----- SM_EnableLED() -----------------------------------------------
-//void SM_EnableLED(PFDO_DEVICE_EXTENSION fdoExt, BOOLEAN enable)
-//{
-//    if (fdoExt->Drive_IsSWLED)
-//    {
-//        if (enable)
-//           Led_D_TernOn();
-//        else
-//           Led_D_TernOff();
-//    }
-//}
-//
-////----- Led_D_TernOn() -------------------------------------------------
-//void Led_D_TernOn(void)
-//{
-//    if (Check_D_CardStsChg())
-//        MediaChange=ERROR;
-//
-//    Cnt_D_LedOn();
-//}
-//
-////----- Led_D_TernOff() ------------------------------------------------
-//void Led_D_TernOff(void)
-//{
-//    if (Check_D_CardStsChg())
-//        MediaChange=ERROR;
-//
-//    Cnt_D_LedOff();
-//}
-//
-////SmartMedia Logical Format Subroutine
-////----- Check_D_LogCHS() -----------------------------------------------
-//int Check_D_LogCHS(WORD *c,BYTE *h,BYTE *s)
-//{
-//    switch(Ssfdc.Model) {
-//        case SSFDC1MB:   *c=125; *h= 4; *s= 4; break;
-//        case SSFDC2MB:   *c=125; *h= 4; *s= 8; break;
-//        case SSFDC4MB:   *c=250; *h= 4; *s= 8; break;
-//        case SSFDC8MB:   *c=250; *h= 4; *s=16; break;
-//        case SSFDC16MB:  *c=500; *h= 4; *s=16; break;
-//        case SSFDC32MB:  *c=500; *h= 8; *s=16; break;
-//        case SSFDC64MB:  *c=500; *h= 8; *s=32; break;
-//        case SSFDC128MB: *c=500; *h=16; *s=32; break;
-//        default:         *c= 0;  *h= 0; *s= 0; ErrCode = ERR_NoSmartMedia;    return(ERROR);
-//    }
-//
-//    return(SMSUCCESS);
-//}
-//
-////Power Control & Media Exist Check Subroutine
-////----- Initialize_D_Media() -------------------------------------------
-//void Initialize_D_Media(void)
-//{
-//    ErrCode      = NO_ERROR;
-//    MediaChange  = ERROR;
-//    SectCopyMode = COMPLETED;
-//    Cnt_D_Reset();
-//}
-//
-////----- PowerOff_D_Media() ---------------------------------------------
-//void PowerOff_D_Media(void)
-//{
-//    Cnt_D_PowerOff();
-//}
-//
-////----- Check_D_MediaPower() -------------------------------------------
-//int Check_D_MediaPower(void)
-//{
-//    //usleep(56*1024);
-//    if (Check_D_CardStsChg())
-//        MediaChange = ERROR;
-//    //usleep(56*1024);
-//    if ((!Check_D_CntPower())&&(!MediaChange))  // ¦³ power & Media ¨S³Q change, «h return success
-//        return(SMSUCCESS);
-//    //usleep(56*1024);
-//
-//    if (Check_D_CardExist())                    // Check if card is not exist, return err
-//    {
-//        ErrCode        = ERR_NoSmartMedia;
-//        MediaChange = ERROR;
-//        return(ERROR);
-//    }
-//    //usleep(56*1024);
-//    if (Cnt_D_PowerOn())
-//    {
-//        ErrCode        = ERR_NoSmartMedia;
-//        MediaChange = ERROR;
-//        return(ERROR);
-//    }
-//    //usleep(56*1024);
-//    Ssfdc_D_Reset(fdoExt);
-//    //usleep(56*1024);
-//    return(SMSUCCESS);
-//}
-//
-////-----Check_D_MediaExist() --------------------------------------------
-//int Check_D_MediaExist(void)
-//{
-//    if (Check_D_CardStsChg())
-//        MediaChange = ERROR;
-//
-//    if (!Check_D_CardExist())
-//    {
-//        if (!MediaChange)
-//            return(SMSUCCESS);
-//
-//        ErrCode = ERR_ChangedMedia;
-//        return(ERROR);
-//    }
-//
-//    ErrCode = ERR_NoSmartMedia;
-//
-//    return(ERROR);
-//}
-//
-////----- Check_D_MediaWP() ----------------------------------------------
-//int Check_D_MediaWP(void)
-//{
-//    if (Ssfdc.Attribute &MWP)
-//    {
-//        ErrCode = ERR_WrtProtect;
-//        return(ERROR);
-//    }
-//
-//    return(SMSUCCESS);
-//}
-*/
-//SmartMedia Physical Format Test Subroutine
-//----- Check_D_MediaFmt() ---------------------------------------------
+/* SmartMedia Physical Format Test Subroutine */
+/* ----- Check_D_MediaFmt() --------------------------------------------- */
 int Check_D_MediaFmt(struct us_data *us)
 {
 	pr_info("Check_D_MediaFmt\n");
-	//ULONG i,j, result=FALSE, zone,block;
 
-	//usleep(56*1024);
 	if (!MediaChange)
-		return(SMSUCCESS);
+		return SMSUCCESS;
 
 	MediaChange  = ERROR;
 	SectCopyMode = COMPLETED;
 
-	//usleep(56*1024);
-	if (Set_D_PhyFmtValue(us))
-	{
+	if (Set_D_PhyFmtValue(us)) {
 		ErrCode = ERR_UnknownMedia;
-		return(ERROR);
+		return ERROR;
 	}
-	
-	//usleep(56*1024);
-	if (Search_D_CIS(us))
-	{
+
+	if (Search_D_CIS(us)) {
 		ErrCode = ERR_IllegalFmt;
-		return(ERROR);
+		return ERROR;
 	}
 
-
-    MediaChange = SMSUCCESS;
-    return(SMSUCCESS);
+	MediaChange = SMSUCCESS;
+	return SMSUCCESS;
 }
-/*
-////----- Check_D_BlockIsFull() ----------------------------------
-//void Check_D_BlockIsFull()
-//{
-//    ULONG i, block;
-//
-//    if (IsXDCompliance || IsSSFDCCompliance)
-//    {
-//       // If the blocks are full then return write-protect.
-//       block = Ssfdc.MaxBlocks/8;
-//       for (Media.Zone=0; Media.Zone<Ssfdc.MaxZones; Media.Zone++)
-//       {
-//           if (Log2Phy[Media.Zone]==NULL)
-//           {
-//               if (Make_D_LogTable())
-//               {
-//                   ErrCode = ERR_IllegalFmt;
-//                   return;
-//               }
-//           }
-//
-//           for (i=0; i<block; i++)
-//           {
-//               if (Assign[Media.Zone][i] != 0xFF)
-//                  return;
-//           }
-//       }
-//       Ssfdc.Attribute |= WP;
-//    }
-//}
-//
-//
-////----- Check_D_MediaFmtForEraseAll() ----------------------------------
-//int Check_D_MediaFmtForEraseAll(PFDO_DEVICE_EXTENSION fdoExt)
-//{
-//    MediaChange  = ERROR;
-//    SectCopyMode = COMPLETED;
-//
-//    if (Set_D_PhyFmtValue(fdoExt))
-//    {
-//        ErrCode = ERR_UnknownMedia;
-//        return(ERROR);
-//    }
-//
-//    if (Search_D_CIS(fdoExt))
-//    {
-//        ErrCode = ERR_IllegalFmt;
-//        return(ERROR);
-//    }
-//
-//    return(SMSUCCESS);
-//}
-*/
-//SmartMedia Physical Address Control Subroutine
-//----- Conv_D_MediaAddr() ---------------------------------------------
+
+/* SmartMedia Physical Address Control Subroutine */
+/* ----- Conv_D_MediaAddr() --------------------------------------------- */
 int Conv_D_MediaAddr(struct us_data *us, DWORD addr)
 {
 	DWORD temp;
-	//ULONG  zz;
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
-	temp           = addr/Ssfdc.MaxSectors;
-	Media.Zone     = (BYTE) (temp/Ssfdc.MaxLogBlocks);
+	temp           = addr / Ssfdc.MaxSectors;
+	Media.Zone     = (BYTE) (temp / Ssfdc.MaxLogBlocks);
 
-	if (Log2Phy[Media.Zone]==NULL)
-	{
-		if (Make_D_LogTable(us))
-		{
+	if (Log2Phy[Media.Zone] == NULL) {
+		if (Make_D_LogTable(us)) {
 			ErrCode = ERR_IllegalFmt;
-			return(ERROR);
+			return ERROR;
 		}
 	}
 
-	Media.Sector   = (BYTE) (addr%Ssfdc.MaxSectors);
-	Media.LogBlock = (WORD) (temp%Ssfdc.MaxLogBlocks);
+	Media.Sector   = (BYTE) (addr % Ssfdc.MaxSectors);
+	Media.LogBlock = (WORD) (temp % Ssfdc.MaxLogBlocks);
 
-	if (Media.Zone<Ssfdc.MaxZones)
-	{
+	if (Media.Zone < Ssfdc.MaxZones) {
 		Clr_D_RedundantData(Redundant);
 		Set_D_LogBlockAddr(Redundant);
 		Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
-		return(SMSUCCESS);
+		return SMSUCCESS;
 	}
 
 	ErrCode = ERR_OutOfLBA;
-	return(ERROR);
+	return ERROR;
 }
 
-//----- Inc_D_MediaAddr() ----------------------------------------------
+/* ----- Inc_D_MediaAddr() ---------------------------------------------- */
 int Inc_D_MediaAddr(struct us_data *us)
 {
 	WORD        LogBlock = Media.LogBlock;
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
-	if (++Media.Sector<Ssfdc.MaxSectors)
-		return(SMSUCCESS);
+	if (++Media.Sector < Ssfdc.MaxSectors)
+		return SMSUCCESS;
 
-	if (Log2Phy[Media.Zone]==NULL)
-	{
-		if (Make_D_LogTable(us))
-		{
+	if (Log2Phy[Media.Zone] == NULL) {
+		if (Make_D_LogTable(us)) {
 			ErrCode = ERR_IllegalFmt;
-			return(ERROR);
+			return ERROR;
 		}
 	}
 
-	Media.Sector=0;
+	Media.Sector = 0;
 	Media.LogBlock = LogBlock;
 
-	if (++Media.LogBlock<Ssfdc.MaxLogBlocks)
-	{
+	if (++Media.LogBlock < Ssfdc.MaxLogBlocks) {
 		Clr_D_RedundantData(Redundant);
 		Set_D_LogBlockAddr(Redundant);
-		Media.PhyBlock=Log2Phy[Media.Zone][Media.LogBlock];
-		return(SMSUCCESS);
+		Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
+		return SMSUCCESS;
 	}
 
-	Media.LogBlock=0;
+	Media.LogBlock = 0;
 
-	if (++Media.Zone<Ssfdc.MaxZones)
-	{
-		if (Log2Phy[Media.Zone]==NULL)
-		{
-			if (Make_D_LogTable(us))
-			{
+	if (++Media.Zone < Ssfdc.MaxZones) {
+		if (Log2Phy[Media.Zone] == NULL) {
+			if (Make_D_LogTable(us)) {
 				ErrCode = ERR_IllegalFmt;
-				return(ERROR);
+				return ERROR;
 			}
 		}
 
@@ -817,1034 +278,508 @@ int Inc_D_MediaAddr(struct us_data *us)
 
 		Clr_D_RedundantData(Redundant);
 		Set_D_LogBlockAddr(Redundant);
-		Media.PhyBlock=Log2Phy[Media.Zone][Media.LogBlock];
-		return(SMSUCCESS);
+		Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
+		return SMSUCCESS;
 	}
 
-	Media.Zone=0;
+	Media.Zone = 0;
 	ErrCode = ERR_OutOfLBA;
 
-	return(ERROR);
-}
-/*
-//----- Check_D_FirstSect() --------------------------------------------
-int Check_D_FirstSect(void)
-{
-    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-    ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-    if (!Media.Sector)
-        return(SMSUCCESS);
-
-    return(ERROR);
+	return ERROR;
 }
 
-//----- Check_D_LastSect() ---------------------------------------------
-int Check_D_LastSect(void)
-{
-    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-    ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-    if (Media.Sector<(Ssfdc.MaxSectors-1))
-        return(ERROR);
-
-    return(SMSUCCESS);
-}
-*/
-//SmartMedia Read/Write Subroutine with Retry
-//----- Media_D_ReadOneSect() ------------------------------------------
+/* SmartMedia Read/Write Subroutine with Retry */
+/* ----- Media_D_ReadOneSect() ------------------------------------------ */
 int Media_D_ReadOneSect(struct us_data *us, WORD count, BYTE *buf)
 {
 	DWORD err, retry;
 
 	if (!Read_D_PhyOneSect(us, count, buf))
-		return(SMSUCCESS);
-	if (ErrCode==ERR_HwError)
-		return(ERROR);
-	if (ErrCode==ERR_DataStatus)
-		return(ERROR);
+		return SMSUCCESS;
+	if (ErrCode == ERR_HwError)
+		return ERROR;
+	if (ErrCode == ERR_DataStatus)
+		return ERROR;
 
 #ifdef RDERR_REASSIGN
-	if (Ssfdc.Attribute &MWP)
-	{
-		if (ErrCode==ERR_CorReadErr)
-			return(SMSUCCESS);
-		return(ERROR);
+	if (Ssfdc.Attribute & MWP) {
+		if (ErrCode == ERR_CorReadErr)
+			return SMSUCCESS;
+		return ERROR;
 	}
 
-	err=ErrCode;
-	for(retry=0; retry<2; retry++)
-	{
-		if (Copy_D_BlockAll(us, (err==ERR_EccReadErr)?REQ_FAIL:REQ_ERASE))
-		{
-			if (ErrCode==ERR_HwError)
-				return(ERROR);
+	err = ErrCode;
+	for (retry = 0; retry < 2; retry++) {
+		if (Copy_D_BlockAll(us,
+			(err == ERR_EccReadErr) ? REQ_FAIL : REQ_ERASE)) {
+			if (ErrCode == ERR_HwError)
+				return ERROR;
 			continue;
 		}
 
 		ErrCode = err;
-		if (ErrCode==ERR_CorReadErr)
-			return(SMSUCCESS);
-		return(ERROR);
+		if (ErrCode == ERR_CorReadErr)
+			return SMSUCCESS;
+		return ERROR;
 	}
 
 	MediaChange = ERROR;
 #else
-	if (ErrCode==ERR_CorReadErr) return(SMSUCCESS);
+	if (ErrCode == ERR_CorReadErr)
+		return SMSUCCESS;
 #endif
 
-	return(ERROR);
-}
-/*
-//----- Media_D_WriteOneSect() -----------------------------------------
-int Media_D_WriteOneSect(PFDO_DEVICE_EXTENSION fdoExt, WORD count, BYTE *buf)
-{
-    DWORD retry;
-    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-    ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-    if (!Write_D_PhyOneSect(fdoExt, count, buf))
-        return(SMSUCCESS);
-    if (ErrCode==ERR_HwError)
-        return(ERROR);
-
-    for(retry=1; retry<2; retry++)
-    {
-        if (Reassign_D_BlockHead(fdoExt))
-        {
-            if (ErrCode==ERR_HwError)
-                return(ERROR);
-            continue;
-        }
-
-        if (!Write_D_PhyOneSect(fdoExt, count, buf))
-            return(SMSUCCESS);
-        if (ErrCode==ERR_HwError)
-            return(ERROR);
-    }
-
-    if (Release_D_WriteBlock(fdoExt))
-        return(ERROR);
-
-    ErrCode        = ERR_WriteFault;
-    MediaChange = ERROR;
-    return(ERROR);
-}
-
-//SmartMedia Data Copy Subroutine with Retry
-//----- Media_D_CopyBlockHead() ----------------------------------------
-int Media_D_CopyBlockHead(PFDO_DEVICE_EXTENSION fdoExt)
-{
-    DWORD retry;
-
-    for(retry=0; retry<2; retry++)
-    {
-        if (!Copy_D_BlockHead(fdoExt))
-            return(SMSUCCESS);
-        if (ErrCode==ERR_HwError)
-            return(ERROR);
-    }
-
-    MediaChange = ERROR;
-    return(ERROR);
+	return ERROR;
 }
 
-//----- Media_D_CopyBlockTail() ----------------------------------------
-int Media_D_CopyBlockTail(PFDO_DEVICE_EXTENSION fdoExt)
-{
-    DWORD retry;
-
-    if (!Copy_D_BlockTail(fdoExt))
-        return(SMSUCCESS);
-    if (ErrCode==ERR_HwError)
-        return(ERROR);
-
-    for(retry=1; retry<2; retry++)
-    {
-        if (Reassign_D_BlockHead(fdoExt))
-        {
-            if (ErrCode==ERR_HwError)
-                return(ERROR);
-            continue;
-        }
-
-        if (!Copy_D_BlockTail(fdoExt))
-            return(SMSUCCESS);
-        if (ErrCode==ERR_HwError)
-            return(ERROR);
-    }
-
-    if (Release_D_WriteBlock(fdoExt))
-        return(ERROR);
-
-    ErrCode        = ERR_WriteFault;
-    MediaChange = ERROR;
-    return(ERROR);
-}
-//
-////----- Media_D_EraseOneBlock() ----------------------------------------
-//int Media_D_EraseOneBlock(void)
-//{
-//    WORD        LogBlock = Media.LogBlock;
-//    WORD        PhyBlock = Media.PhyBlock;
-//    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-//    ADDRESS_T   bb = (ADDRESS_T) &Media;
-//
-//    if (Media.PhyBlock==NO_ASSIGN)
-//        return(SMSUCCESS);
-//
-//    if (Log2Phy[Media.Zone]==NULL)
-//    {
-//        if (Make_D_LogTable())
-//        {
-//            ErrCode = ERR_IllegalFmt;
-//            return(ERROR);
-//        }
-//    }
-//    Media.LogBlock = LogBlock;
-//    Media.PhyBlock = PhyBlock;
-//
-//    Log2Phy[Media.Zone][Media.LogBlock]=NO_ASSIGN;
-//
-//    if (Erase_D_PhyOneBlock(fdoExt))
-//    {
-//        if (ErrCode==ERR_HwError)
-//            return(ERROR);
-//        if (MarkFail_D_PhyOneBlock())
-//            return(ERROR);
-//
-//        ErrCode = ERR_WriteFault;
-//        return(ERROR);
-//    }
-//
-//    Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
-//    Media.PhyBlock=NO_ASSIGN;
-//    return(SMSUCCESS);
-//}
-//
-////SmartMedia Erase Subroutine
-////----- Media_D_EraseAllBlock() ----------------------------------------
-//int Media_D_EraseAllBlock(void)
-//{
-//    WORD cis=0;
-//
-//    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-//    ADDRESS_T   bb = (ADDRESS_T) &Media;
-//
-//    MediaChange = ERROR;
-//    Media.Sector   = 0;
-//
-//    for(Media.Zone=0; Media.Zone<Ssfdc.MaxZones; Media.Zone++)
-//        for(Media.PhyBlock=0; Media.PhyBlock<Ssfdc.MaxBlocks; Media.PhyBlock++) {
-//            if (Ssfdc_D_ReadRedtData(Redundant))
-//            {
-//                Ssfdc_D_Reset(fdoExt);
-//                return(ERROR);
-//            }
-//
-//            Ssfdc_D_Reset(fdoExt);
-//            if (!Check_D_FailBlock(Redundant))
-//            {
-//                if (cis)
-//                {
-//                    if (Ssfdc_D_EraseBlock(fdoExt))
-//                    {
-//                        ErrCode = ERR_HwError;
-//                        return(ERROR);
-//                    }
-//
-//                    if (Ssfdc_D_CheckStatus())
-//                    {
-//                        if (MarkFail_D_PhyOneBlock())
-//                            return(ERROR);
-//                    }
-//
-//                    continue;
-//                }
-//
-//                if (Media.PhyBlock!=CisArea.PhyBlock)
-//                {
-//                    ErrCode = ERR_IllegalFmt;
-//                    return(ERROR);
-//                }
-//
-//                cis++;
-//            }
-//
-//        }
-//    return(SMSUCCESS);
-//}
-*/
-//SmartMedia Physical Sector Data Copy Subroutine
-//----- Copy_D_BlockAll() ----------------------------------------------
+/* SmartMedia Physical Sector Data Copy Subroutine */
+/* ----- Copy_D_BlockAll() ---------------------------------------------- */
 int Copy_D_BlockAll(struct us_data *us, DWORD mode)
 {
 	BYTE sect;
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
-	sect=Media.Sector;
+	sect = Media.Sector;
 
 	if (Assign_D_WriteBlock())
-		return(ERROR);
-	if (mode==REQ_FAIL)
-		SectCopyMode=REQ_FAIL;
+		return ERROR;
+	if (mode == REQ_FAIL)
+		SectCopyMode = REQ_FAIL;
 
-	for(Media.Sector=0; Media.Sector<Ssfdc.MaxSectors; Media.Sector++)
-	{
-		if (Copy_D_PhyOneSect(us))
-		{
-			if (ErrCode==ERR_HwError)
-				return(ERROR);
+	for (Media.Sector = 0; Media.Sector < Ssfdc.MaxSectors;
+							Media.Sector++) {
+		if (Copy_D_PhyOneSect(us)) {
+			if (ErrCode == ERR_HwError)
+				return ERROR;
 			if (Release_D_WriteBlock(us))
-				return(ERROR);
+				return ERROR;
 
 			ErrCode = ERR_WriteFault;
-			Media.PhyBlock=ReadBlock;
-			Media.Sector=sect;
+			Media.PhyBlock = ReadBlock;
+			Media.Sector = sect;
 
-			return(ERROR);
+			return ERROR;
 		}
 	}
 
 	if (Release_D_ReadBlock(us))
-		return(ERROR);
-
-	Media.PhyBlock=WriteBlock;
-	Media.Sector=sect;
-	return(SMSUCCESS);
-}
-/*
-//----- Copy_D_BlockHead() ---------------------------------------------
-int Copy_D_BlockHead(PFDO_DEVICE_EXTENSION fdoExt)
-{
-    BYTE sect;
-    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-    ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-    sect=Media.Sector;
-    if (Assign_D_WriteBlock())
-        return(ERROR);
-
-    for(Media.Sector=0; Media.Sector<sect; Media.Sector++)
-    {
-        if (Copy_D_PhyOneSect(fdoExt))
-        {
-            if (ErrCode==ERR_HwError)
-                return(ERROR);
-            if (Release_D_WriteBlock(fdoExt))
-                return(ERROR);
-
-            ErrCode = ERR_WriteFault;
-            Media.PhyBlock=ReadBlock;
-            Media.Sector=sect;
-
-            return(ERROR);
-        }
-    }
-
-    Media.PhyBlock=WriteBlock;
-    Media.Sector=sect;
-    return(SMSUCCESS);
-}
-
-//----- Copy_D_BlockTail() ---------------------------------------------
-int Copy_D_BlockTail(PFDO_DEVICE_EXTENSION fdoExt)
-{
-    BYTE sect;
-    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-    ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-    for(sect=Media.Sector; Media.Sector<Ssfdc.MaxSectors; Media.Sector++)
-    {
-        if (Copy_D_PhyOneSect(fdoExt))
-        {
-            if (ErrCode==ERR_HwError)
-                return(ERROR);
-
-            Media.PhyBlock=WriteBlock;
-            Media.Sector=sect;
-
-            return(ERROR);
-        }
-    }
-
-    if (Release_D_ReadBlock(fdoExt))
-        return(ERROR);
+		return ERROR;
 
-    Media.PhyBlock=WriteBlock;
-    Media.Sector=sect;
-    return(SMSUCCESS);
+	Media.PhyBlock = WriteBlock;
+	Media.Sector = sect;
+	return SMSUCCESS;
 }
 
-//----- Reassign_D_BlockHead() -----------------------------------------
-int Reassign_D_BlockHead(PFDO_DEVICE_EXTENSION fdoExt)
-{
-    DWORD  mode;
-    WORD   block;
-    BYTE   sect;
-    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-    ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-    mode=SectCopyMode;
-    block=ReadBlock;
-    sect=Media.Sector;
-
-    if (Assign_D_WriteBlock())
-        return(ERROR);
-
-    SectCopyMode=REQ_FAIL;
-
-    for(Media.Sector=0; Media.Sector<sect; Media.Sector++)
-    {
-        if (Copy_D_PhyOneSect(fdoExt))
-        {
-            if (ErrCode==ERR_HwError)
-                return(ERROR);
-            if (Release_D_WriteBlock(fdoExt))
-                return(ERROR);
-
-            ErrCode = ERR_WriteFault;
-            SectCopyMode=mode;
-            WriteBlock=ReadBlock;
-            ReadBlock=block;
-            Media.Sector=sect;
-            Media.PhyBlock=WriteBlock;
-
-            return(ERROR);
-        }
-    }
-
-    if (Release_D_ReadBlock(fdoExt))
-        return(ERROR);
-
-    SectCopyMode=mode;
-    ReadBlock=block;
-    Media.Sector=sect;
-    Media.PhyBlock=WriteBlock;
-    return(SMSUCCESS);
-}
-*/
-//SmartMedia Physical Block Assign/Release Subroutine
-//----- Assign_D_WriteBlock() ------------------------------------------
+/* SmartMedia Physical Block Assign/Release Subroutine */
+/* ----- Assign_D_WriteBlock() ------------------------------------------ */
 int Assign_D_WriteBlock(void)
 {
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
-	ReadBlock=Media.PhyBlock;
+	ReadBlock = Media.PhyBlock;
 
-	for(WriteBlock=AssignStart[Media.Zone]; WriteBlock<Ssfdc.MaxBlocks; WriteBlock++)
-	{
-		if (!Chk_D_Bit(Assign[Media.Zone],WriteBlock))
-		{
-			Set_D_Bit(Assign[Media.Zone],WriteBlock);
-			AssignStart[Media.Zone]=WriteBlock+1;
-			Media.PhyBlock=WriteBlock;
-			SectCopyMode=REQ_ERASE;
-			//ErrXDCode = NO_ERROR;
-			return(SMSUCCESS);
+	for (WriteBlock = AssignStart[Media.Zone];
+			WriteBlock < Ssfdc.MaxBlocks; WriteBlock++) {
+		if (!Chk_D_Bit(Assign[Media.Zone], WriteBlock)) {
+			Set_D_Bit(Assign[Media.Zone], WriteBlock);
+			AssignStart[Media.Zone] = WriteBlock + 1;
+			Media.PhyBlock = WriteBlock;
+			SectCopyMode = REQ_ERASE;
+			return SMSUCCESS;
 		}
 	}
 
-	for(WriteBlock=0; WriteBlock<AssignStart[Media.Zone]; WriteBlock++)
-	{
-		if (!Chk_D_Bit(Assign[Media.Zone],WriteBlock))
-		{
-			Set_D_Bit(Assign[Media.Zone],WriteBlock);
-			AssignStart[Media.Zone]=WriteBlock+1;
-			Media.PhyBlock=WriteBlock;
-			SectCopyMode=REQ_ERASE;
-			//ErrXDCode = NO_ERROR;
-			return(SMSUCCESS);
+	for (WriteBlock = 0;
+			WriteBlock < AssignStart[Media.Zone]; WriteBlock++) {
+		if (!Chk_D_Bit(Assign[Media.Zone], WriteBlock)) {
+			Set_D_Bit(Assign[Media.Zone], WriteBlock);
+			AssignStart[Media.Zone] = WriteBlock + 1;
+			Media.PhyBlock = WriteBlock;
+			SectCopyMode = REQ_ERASE;
+			return SMSUCCESS;
 		}
 	}
 
-	WriteBlock=NO_ASSIGN;
+	WriteBlock = NO_ASSIGN;
 	ErrCode = ERR_WriteFault;
-	// For xD test
-	//Ssfdc.Attribute |= WP;
-	//ErrXDCode = ERR_WrtProtect;
-	return(ERROR);
+
+	return ERROR;
 }
 
-//----- Release_D_ReadBlock() ------------------------------------------
+/* ----- Release_D_ReadBlock() ------------------------------------------ */
 int Release_D_ReadBlock(struct us_data *us)
 {
 	DWORD mode;
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
-	mode=SectCopyMode;
-	SectCopyMode=COMPLETED;
+	mode = SectCopyMode;
+	SectCopyMode = COMPLETED;
 
-	if (mode==COMPLETED)
-		return(SMSUCCESS);
+	if (mode == COMPLETED)
+		return SMSUCCESS;
 
-	Log2Phy[Media.Zone][Media.LogBlock]=WriteBlock;
-	Media.PhyBlock=ReadBlock;
+	Log2Phy[Media.Zone][Media.LogBlock] = WriteBlock;
+	Media.PhyBlock = ReadBlock;
 
-	if (Media.PhyBlock==NO_ASSIGN)
-	{
-		Media.PhyBlock=WriteBlock;
-		return(SMSUCCESS);
+	if (Media.PhyBlock == NO_ASSIGN) {
+		Media.PhyBlock = WriteBlock;
+		return SMSUCCESS;
 	}
 
-	if (mode==REQ_ERASE)
-	{
-		if (Erase_D_PhyOneBlock(us))
-		{
-			if (ErrCode==ERR_HwError) return(ERROR);
-			if (MarkFail_D_PhyOneBlock(us)) return(ERROR);
-		}
-		else
-			Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
-	}
-	else if (MarkFail_D_PhyOneBlock(us))
-		return(ERROR);
+	if (mode == REQ_ERASE) {
+		if (Erase_D_PhyOneBlock(us)) {
+			if (ErrCode == ERR_HwError)
+				return ERROR;
+			if (MarkFail_D_PhyOneBlock(us))
+				return ERROR;
+		} else
+			Clr_D_Bit(Assign[Media.Zone], Media.PhyBlock);
+	} else if (MarkFail_D_PhyOneBlock(us))
+		return ERROR;
 
-	Media.PhyBlock=WriteBlock;
-	return(SMSUCCESS);
+	Media.PhyBlock = WriteBlock;
+	return SMSUCCESS;
 }
 
-//----- Release_D_WriteBlock() -----------------------------------------
+/* ----- Release_D_WriteBlock() ----------------------------------------- */
 int Release_D_WriteBlock(struct us_data *us)
 {
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
-	SectCopyMode=COMPLETED;
-	Media.PhyBlock=WriteBlock;
+	SectCopyMode = COMPLETED;
+	Media.PhyBlock = WriteBlock;
 
 	if (MarkFail_D_PhyOneBlock(us))
-		return(ERROR);
+		return ERROR;
 
-	Media.PhyBlock=ReadBlock;
-	return(SMSUCCESS);
+	Media.PhyBlock = ReadBlock;
+	return SMSUCCESS;
 }
 
-//SmartMedia Physical Sector Data Copy Subroutine
-//----- Copy_D_PhyOneSect() --------------------------------------------
+/* SmartMedia Physical Sector Data Copy Subroutine */
+/* ----- Copy_D_PhyOneSect() -------------------------------------------- */
 int Copy_D_PhyOneSect(struct us_data *us)
 {
 	int           i;
 	DWORD  err, retry;
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
 	/* pr_info("Copy_D_PhyOneSect --- Secotr = %x\n", Media.Sector); */
-	if (ReadBlock!=NO_ASSIGN)
-	{
-		Media.PhyBlock=ReadBlock;
-		for(retry=0; retry<2; retry++)
-		{
-			if (retry!=0)
-			{
+	if (ReadBlock != NO_ASSIGN) {
+		Media.PhyBlock = ReadBlock;
+		for (retry = 0; retry < 2; retry++) {
+			if (retry != 0) {
 				Ssfdc_D_Reset(us);
-				if (Ssfdc_D_ReadCisSect(us,WorkBuf,WorkRedund))
-				{ ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+				if (Ssfdc_D_ReadCisSect(us, WorkBuf,
+								WorkRedund)) {
+					ErrCode = ERR_HwError;
+					MediaChange = ERROR;
+					return ERROR;
+				}
 
-				if (Check_D_CISdata(WorkBuf,WorkRedund))
-				{ ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+				if (Check_D_CISdata(WorkBuf, WorkRedund)) {
+					ErrCode = ERR_HwError;
+					MediaChange = ERROR;
+					return ERROR;
+				}
 			}
 
-			if (Ssfdc_D_ReadSect(us,WorkBuf,WorkRedund))
-			{ ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
-			if (Check_D_DataStatus(WorkRedund))
-			{ err=ERROR; break; }
-			if (!Check_D_ReadError(WorkRedund))
-			{ err=SMSUCCESS; break; }
-			if (!Check_D_Correct(WorkBuf,WorkRedund))
-			{ err=SMSUCCESS; break; }
+			if (Ssfdc_D_ReadSect(us, WorkBuf, WorkRedund)) {
+				ErrCode = ERR_HwError;
+				MediaChange = ERROR;
+				return ERROR;
+			}
+			if (Check_D_DataStatus(WorkRedund)) {
+				err = ERROR;
+				break;
+			}
+			if (!Check_D_ReadError(WorkRedund)) {
+				err = SMSUCCESS;
+				break;
+			}
+			if (!Check_D_Correct(WorkBuf, WorkRedund)) {
+				err = SMSUCCESS;
+				break;
+			}
 
-			err=ERROR;
-			SectCopyMode=REQ_FAIL;
+			err = ERROR;
+			SectCopyMode = REQ_FAIL;
 		}
-	}
-	else
-	{
-		err=SMSUCCESS;
-		for(i=0; i<SECTSIZE; i++)
-			WorkBuf[i]=DUMMY_DATA;
+	} else {
+		err = SMSUCCESS;
+		for (i = 0; i < SECTSIZE; i++)
+			WorkBuf[i] = DUMMY_DATA;
 		Clr_D_RedundantData(WorkRedund);
 	}
 
 	Set_D_LogBlockAddr(WorkRedund);
-	if (err==ERROR)
-	{
+	if (err == ERROR) {
 		Set_D_RightECC(WorkRedund);
 		Set_D_DataStaus(WorkRedund);
 	}
 
-	Media.PhyBlock=WriteBlock;
+	Media.PhyBlock = WriteBlock;
 
-	if (Ssfdc_D_WriteSectForCopy(us, WorkBuf, WorkRedund))
-	{ ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
-	if (Ssfdc_D_CheckStatus())
-	{ ErrCode = ERR_WriteFault; return(ERROR); }
+	if (Ssfdc_D_WriteSectForCopy(us, WorkBuf, WorkRedund)) {
+		ErrCode = ERR_HwError;
+		MediaChange = ERROR;
+		return ERROR;
+	}
+	if (Ssfdc_D_CheckStatus()) {
+		ErrCode = ERR_WriteFault;
+		return ERROR;
+	}
 
-	Media.PhyBlock=ReadBlock;
-	return(SMSUCCESS);
+	Media.PhyBlock = ReadBlock;
+	return SMSUCCESS;
 }
 
-//SmartMedia Physical Sector Read/Write/Erase Subroutine
-//----- Read_D_PhyOneSect() --------------------------------------------
+/* SmartMedia Physical Sector Read/Write/Erase Subroutine */
+/* ----- Read_D_PhyOneSect() -------------------------------------------- */
 int Read_D_PhyOneSect(struct us_data *us, WORD count, BYTE *buf)
 {
 	int           i;
 	DWORD  retry;
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
-	if (Media.PhyBlock==NO_ASSIGN)
-	{
-		for(i=0; i<SECTSIZE; i++)
-			*buf++=DUMMY_DATA;
-		return(SMSUCCESS);
+	if (Media.PhyBlock == NO_ASSIGN) {
+		for (i = 0; i < SECTSIZE; i++)
+			*buf++ = DUMMY_DATA;
+		return SMSUCCESS;
 	}
 
-	for(retry=0; retry<2; retry++)
-	{
-		if (retry!=0)
-		{
+	for (retry = 0; retry < 2; retry++) {
+		if (retry != 0) {
 			Ssfdc_D_Reset(us);
 
-			if (Ssfdc_D_ReadCisSect(us,WorkBuf,WorkRedund))
-			{ ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
-			if (Check_D_CISdata(WorkBuf,WorkRedund))
-			{ ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
+			if (Ssfdc_D_ReadCisSect(us, WorkBuf, WorkRedund)) {
+				ErrCode = ERR_HwError;
+				MediaChange = ERROR;
+				return ERROR;
+			}
+			if (Check_D_CISdata(WorkBuf, WorkRedund)) {
+				ErrCode = ERR_HwError;
+				MediaChange = ERROR;
+				return ERROR;
+			}
 		}
 
-		//if (Ssfdc_D_ReadSect(fdoExt,buf,Redundant))
-		if (Ssfdc_D_ReadBlock(us,count,buf,Redundant))
-		{ ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
-		if (Check_D_DataStatus(Redundant))
-		{ ErrCode = ERR_DataStatus; return(ERROR); }
+		if (Ssfdc_D_ReadBlock(us, count, buf, Redundant)) {
+			ErrCode = ERR_HwError;
+			MediaChange = ERROR;
+			return ERROR;
+		}
+		if (Check_D_DataStatus(Redundant)) {
+			ErrCode = ERR_DataStatus;
+			return ERROR;
+		}
 
 		if (!Check_D_ReadError(Redundant))
-			return(SMSUCCESS);
+			return SMSUCCESS;
 
-		if (!Check_D_Correct(buf,Redundant))
-		{ ErrCode = ERR_CorReadErr; return(ERROR); }
+		if (!Check_D_Correct(buf, Redundant)) {
+			ErrCode = ERR_CorReadErr;
+			return ERROR;
+		}
 	}
 
 	ErrCode = ERR_EccReadErr;
-	return(ERROR);
+	return ERROR;
 }
-/*
-//----- Write_D_PhyOneSect() -------------------------------------------
-int Write_D_PhyOneSect(PFDO_DEVICE_EXTENSION fdoExt, WORD count, BYTE *buf)
-{
-    SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-    ADDRESS_T   bb = (ADDRESS_T) &Media;
 
-    //if (Ssfdc_D_WriteSect(fdoExt,buf,Redundant))
-    if (Ssfdc_D_WriteBlock(fdoExt,count,buf,Redundant))
-    { ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
-    if (Ssfdc_D_CheckStatus())
-    { ErrCode = ERR_WriteFault; return(ERROR); }
-
-    return(SMSUCCESS);
-}
-*/
-//----- Erase_D_PhyOneBlock() ------------------------------------------
+/* ----- Erase_D_PhyOneBlock() ------------------------------------------ */
 int Erase_D_PhyOneBlock(struct us_data *us)
 {
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-	if (Ssfdc_D_EraseBlock(us))
-	{ ErrCode = ERR_HwError; MediaChange=ERROR; return(ERROR); }
-	if (Ssfdc_D_CheckStatus())
-	{ ErrCode = ERR_WriteFault; return(ERROR); }
+	if (Ssfdc_D_EraseBlock(us)) {
+		ErrCode = ERR_HwError;
+		MediaChange = ERROR;
+		return ERROR;
+	}
+	if (Ssfdc_D_CheckStatus()) {
+		ErrCode = ERR_WriteFault;
+		return ERROR;
+	}
 
-	return(SMSUCCESS);
+	return SMSUCCESS;
 }
 
-//SmartMedia Physical Format Check Local Subroutine
-//----- Set_D_PhyFmtValue() --------------------------------------------
+/* SmartMedia Physical Format Check Local Subroutine */
+/* ----- Set_D_PhyFmtValue() -------------------------------------------- */
 int Set_D_PhyFmtValue(struct us_data *us)
 {
-//    PPDO_DEVICE_EXTENSION   pdoExt;
-//    BYTE      idcode[4];
-//    DWORD     UserDefData_1, UserDefData_2, Data, mask;
-//
-//    //if (!fdoExt->ChildDeviceObject)       return(ERROR);
-//    //pdoExt = fdoExt->ChildDeviceObject->DeviceExtension;
-//
-//    Ssfdc_D_ReadID(idcode, READ_ID_1);
-//
-    //if (Set_D_SsfdcModel(idcode[1]))
-    if (Set_D_SsfdcModel(us->SM_DeviceID))
-        return(ERROR);
-
-//    //Use Multi-function pin to differentiate SM and xD.
-//    UserDefData_1 = ReadPCIReg(fdoExt->BusID, fdoExt->DevID, fdoExt->FuncID, PCI_REG_USER_DEF) & 0x80;
-//    if (UserDefData_1)
-//    {
-//       if ( READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x80 )      fdoExt->DiskType = DISKTYPE_XD;
-//       if ( READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x40 )      fdoExt->DiskType = DISKTYPE_SM;
-//
-//       if ( IsXDCompliance && (fdoExt->DiskType == DISKTYPE_XD) )
-//       {
-//          Ssfdc_D_ReadID(idcode, READ_ID_3);
-//          if (idcode[2] != 0xB5)
-//             return(ERROR);
-//       }
-//    }
-//
-//    //Use GPIO to differentiate SM and xD.
-//    UserDefData_2 = ReadPCIReg(fdoExt->BusID, fdoExt->DevID, fdoExt->FuncID, PCI_REG_USER_DEF) >> 8;
-//    if ( UserDefData_2 )
-//    {
-//       Data = ReadPCIReg(fdoExt->BusID, fdoExt->DevID, 0, 0xAC);
-//
-//       mask = 1 << (UserDefData_2-1);
-//       // 1 : xD , 0 : SM
-//       if ( Data & mask)
-//          fdoExt->DiskType = DISKTYPE_XD;
-//       else
-//          fdoExt->DiskType = DISKTYPE_SM;
-//
-//       if ( IsXDCompliance && (fdoExt->DiskType == DISKTYPE_XD) )
-//       {
-//          Ssfdc_D_ReadID(idcode, READ_ID_3);
-//          if (idcode[2] != 0xB5)
-//             return(ERROR);
-//       }
-//    }
-//
-//    if ( !(UserDefData_1 | UserDefData_2) )
-//    {
-//      // Use UserDefine Register to differentiate SM and xD.
-//      Ssfdc_D_ReadID(idcode, READ_ID_3);
-//
-//      if (idcode[2] == 0xB5)
-//         fdoExt->DiskType = DISKTYPE_XD;
-//      else
-//      {
-//          if (!IsXDCompliance)
-//             fdoExt->DiskType = DISKTYPE_SM;
-//          else
-//             return(ERROR);
-//      }
-//
-//      if (fdoExt->UserDef_DiskType == 0x04)  fdoExt->DiskType = DISKTYPE_XD;
-//      if (fdoExt->UserDef_DiskType == 0x08)  fdoExt->DiskType = DISKTYPE_SM;
-//    }
-//
-//    if (!fdoExt->UserDef_DisableWP)
-//    {
-//       if (fdoExt->DiskType == DISKTYPE_SM)
-//       {
-//           if (Check_D_SsfdcWP())
-//              Ssfdc.Attribute|=WP;
-//       }
-//    }
+	if (Set_D_SsfdcModel(us->SM_DeviceID))
+		return ERROR;
 
-    return(SMSUCCESS);
+	return SMSUCCESS;
 }
 
-//----- Search_D_CIS() -------------------------------------------------
+/* ----- Search_D_CIS() ------------------------------------------------- */
 int Search_D_CIS(struct us_data *us)
 {
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
-
-	Media.Zone=0; Media.Sector=0;
+	Media.Zone = 0;
+	Media.Sector = 0;
 
-	for (Media.PhyBlock=0; Media.PhyBlock<(Ssfdc.MaxBlocks-Ssfdc.MaxLogBlocks-1); Media.PhyBlock++)
-	{
-		if (Ssfdc_D_ReadRedtData(us, Redundant))
-		{
+	for (Media.PhyBlock = 0;
+		Media.PhyBlock < (Ssfdc.MaxBlocks - Ssfdc.MaxLogBlocks - 1);
+		Media.PhyBlock++) {
+		if (Ssfdc_D_ReadRedtData(us, Redundant)) {
 			Ssfdc_D_Reset(us);
-			return(ERROR);
+			return ERROR;
 		}
 
 		if (!Check_D_FailBlock(Redundant))
 			break;
 	}
 
-	if (Media.PhyBlock==(Ssfdc.MaxBlocks-Ssfdc.MaxLogBlocks-1))
-	{
+	if (Media.PhyBlock == (Ssfdc.MaxBlocks - Ssfdc.MaxLogBlocks - 1)) {
 		Ssfdc_D_Reset(us);
-		return(ERROR);
+		return ERROR;
 	}
 
-	while (Media.Sector<CIS_SEARCH_SECT)
-	{
-		if (Media.Sector)
-		{
-			if (Ssfdc_D_ReadRedtData(us, Redundant))
-			{
+	while (Media.Sector < CIS_SEARCH_SECT) {
+		if (Media.Sector) {
+			if (Ssfdc_D_ReadRedtData(us, Redundant)) {
 				Ssfdc_D_Reset(us);
-				return(ERROR);
+				return ERROR;
 			}
 		}
-		if (!Check_D_DataStatus(Redundant))
-		{
-			if (Ssfdc_D_ReadSect(us,WorkBuf,Redundant))
-			{
+		if (!Check_D_DataStatus(Redundant)) {
+			if (Ssfdc_D_ReadSect(us, WorkBuf, Redundant)) {
 				Ssfdc_D_Reset(us);
-				return(ERROR);
+				return ERROR;
 			}
 
-			if (Check_D_CISdata(WorkBuf,Redundant))
-			{
+			if (Check_D_CISdata(WorkBuf, Redundant)) {
 				Ssfdc_D_Reset(us);
-				return(ERROR);
+				return ERROR;
 			}
 
-			CisArea.PhyBlock=Media.PhyBlock;
-			CisArea.Sector=Media.Sector;
+			CisArea.PhyBlock = Media.PhyBlock;
+			CisArea.Sector = Media.Sector;
 			Ssfdc_D_Reset(us);
-			return(SMSUCCESS);
+			return SMSUCCESS;
 		}
 
 		Media.Sector++;
 	}
 
 	Ssfdc_D_Reset(us);
-	return(ERROR);
+	return ERROR;
 }
 
-//----- Make_D_LogTable() ----------------------------------------------
+/* ----- Make_D_LogTable() ---------------------------------------------- */
 int Make_D_LogTable(struct us_data *us)
 {
-	WORD  phyblock,logblock;
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
+	WORD  phyblock, logblock;
 
-	if (Log2Phy[Media.Zone]==NULL)
-	{
-		Log2Phy[Media.Zone] = kmalloc(MAX_LOGBLOCK*sizeof(WORD), GFP_KERNEL);
+	if (Log2Phy[Media.Zone] == NULL) {
+		Log2Phy[Media.Zone] = kmalloc(MAX_LOGBLOCK * sizeof(WORD),
+								GFP_KERNEL);
 		/* pr_info("ExAllocatePool Zone = %x, Addr = %x\n",
 				Media.Zone, Log2Phy[Media.Zone]); */
-		if (Log2Phy[Media.Zone]==NULL)
-			return(ERROR);
+		if (Log2Phy[Media.Zone] == NULL)
+			return ERROR;
 	}
 
-	Media.Sector=0;
-
-	//for(Media.Zone=0; Media.Zone<MAX_ZONENUM; Media.Zone++)
-	//for(Media.Zone=0; Media.Zone<Ssfdc.MaxZones; Media.Zone++)
-	{
-		/* pr_info("Make_D_LogTable --- MediaZone = 0x%x\n",
-							Media.Zone); */
-		for(Media.LogBlock=0; Media.LogBlock<Ssfdc.MaxLogBlocks; Media.LogBlock++)
-			Log2Phy[Media.Zone][Media.LogBlock]=NO_ASSIGN;
+	Media.Sector = 0;
 
-		for(Media.PhyBlock=0; Media.PhyBlock<(MAX_BLOCKNUM/8); Media.PhyBlock++)
-			Assign[Media.Zone][Media.PhyBlock]=0x00;
+	/* pr_info("Make_D_LogTable --- MediaZone = 0x%x\n",
+						Media.Zone); */
+	for (Media.LogBlock = 0; Media.LogBlock < Ssfdc.MaxLogBlocks;
+						Media.LogBlock++)
+		Log2Phy[Media.Zone][Media.LogBlock] = NO_ASSIGN;
 
-		for(Media.PhyBlock=0; Media.PhyBlock<Ssfdc.MaxBlocks; Media.PhyBlock++)
-		{
-			if ((!Media.Zone) && (Media.PhyBlock<=CisArea.PhyBlock))
-			{
-				Set_D_Bit(Assign[Media.Zone],Media.PhyBlock);
-				continue;
-			}
+	for (Media.PhyBlock = 0; Media.PhyBlock < (MAX_BLOCKNUM / 8);
+						Media.PhyBlock++)
+		Assign[Media.Zone][Media.PhyBlock] = 0x00;
 
-			if (Ssfdc_D_ReadRedtData(us, Redundant))
-			{ Ssfdc_D_Reset(us); return(ERROR); }
+	for (Media.PhyBlock = 0; Media.PhyBlock < Ssfdc.MaxBlocks;
+						Media.PhyBlock++) {
+		if ((!Media.Zone) && (Media.PhyBlock <= CisArea.PhyBlock)) {
+			Set_D_Bit(Assign[Media.Zone], Media.PhyBlock);
+			continue;
+		}
 
-			if (!Check_D_DataBlank(Redundant))
-				continue;
+		if (Ssfdc_D_ReadRedtData(us, Redundant)) {
+			Ssfdc_D_Reset(us);
+			return ERROR;
+		}
 
-			Set_D_Bit(Assign[Media.Zone],Media.PhyBlock);
+		if (!Check_D_DataBlank(Redundant))
+			continue;
 
-			if (Check_D_FailBlock(Redundant))
-				continue;
+		Set_D_Bit(Assign[Media.Zone], Media.PhyBlock);
 
-			//if (Check_D_DataStatus(Redundant))
-			//    continue;
+		if (Check_D_FailBlock(Redundant))
+			continue;
 
-			if (Load_D_LogBlockAddr(Redundant))
-				continue;
+		if (Load_D_LogBlockAddr(Redundant))
+			continue;
 
-			if (Media.LogBlock>=Ssfdc.MaxLogBlocks)
-				continue;
+		if (Media.LogBlock >= Ssfdc.MaxLogBlocks)
+			continue;
 
-			if (Log2Phy[Media.Zone][Media.LogBlock]==NO_ASSIGN)
-			{
-				Log2Phy[Media.Zone][Media.LogBlock]=Media.PhyBlock;
-				continue;
-			}
+		if (Log2Phy[Media.Zone][Media.LogBlock] == NO_ASSIGN) {
+			Log2Phy[Media.Zone][Media.LogBlock] = Media.PhyBlock;
+			continue;
+		}
 
-			phyblock     = Media.PhyBlock;
-			logblock     = Media.LogBlock;
-			Media.Sector = (BYTE)(Ssfdc.MaxSectors-1);
+		phyblock     = Media.PhyBlock;
+		logblock     = Media.LogBlock;
+		Media.Sector = (BYTE)(Ssfdc.MaxSectors - 1);
 
-			if (Ssfdc_D_ReadRedtData(us, Redundant))
-			{ Ssfdc_D_Reset(us); return(ERROR); }
+		if (Ssfdc_D_ReadRedtData(us, Redundant)) {
+			Ssfdc_D_Reset(us);
+			return ERROR;
+		}
 
-			if (!Load_D_LogBlockAddr(Redundant))
-			{
-				if (Media.LogBlock==logblock)
-				{
-					Media.PhyBlock=Log2Phy[Media.Zone][logblock];
+		if (!Load_D_LogBlockAddr(Redundant) &&
+				(Media.LogBlock == logblock)) {
+			Media.PhyBlock = Log2Phy[Media.Zone][logblock];
 
-					if (Ssfdc_D_ReadRedtData(us, Redundant))
-					{ Ssfdc_D_Reset(us); return(ERROR); }
+			if (Ssfdc_D_ReadRedtData(us, Redundant)) {
+				Ssfdc_D_Reset(us);
+				return ERROR;
+			}
 
-					Media.PhyBlock=phyblock;
+			Media.PhyBlock = phyblock;
 
-					if (!Load_D_LogBlockAddr(Redundant))
-					{
-						if (Media.LogBlock!=logblock)
-						{
-							Media.PhyBlock=Log2Phy[Media.Zone][logblock];
-							Log2Phy[Media.Zone][logblock]=phyblock;
-						}
-					}
-					else
-					{
-						Media.PhyBlock=Log2Phy[Media.Zone][logblock];
-						Log2Phy[Media.Zone][logblock]=phyblock;
-					}
+			if (!Load_D_LogBlockAddr(Redundant)) {
+				if (Media.LogBlock != logblock) {
+					Media.PhyBlock =
+						Log2Phy[Media.Zone][logblock];
+					Log2Phy[Media.Zone][logblock] =
+								phyblock;
 				}
+			} else {
+				Media.PhyBlock = Log2Phy[Media.Zone][logblock];
+				Log2Phy[Media.Zone][logblock] = phyblock;
 			}
+		}
 
-			Media.Sector=0;
-
-// here Not yet
-//#ifdef L2P_ERR_ERASE
-//			if (!(Ssfdc.Attribute &MWP))
-//			{
-//				Ssfdc_D_Reset(fdoExt);
-//				if (Ssfdc_D_EraseBlock(fdoExt))
-//					return(ERROR);
-//
-//				if (Ssfdc_D_CheckStatus())
-//				{
-//					if (MarkFail_D_PhyOneBlock())
-//						return(ERROR);
-//				}
-//				else
-//					Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
-//			}
-//#else
-//			Ssfdc.Attribute|=MWP;
-//#endif
-			Media.PhyBlock=phyblock;
-
-		} // End for (Media.PhyBlock<Ssfdc.MaxBlocks)
+		Media.Sector = 0;
+		Media.PhyBlock = phyblock;
 
-		AssignStart[Media.Zone]=0;
+	AssignStart[Media.Zone] = 0;
 
-	} // End for (Media.Zone<MAX_ZONENUM)
+	} /* End for (Media.Zone<MAX_ZONENUM) */
 
 	Ssfdc_D_Reset(us);
-	return(SMSUCCESS);
+	return SMSUCCESS;
 }
 
-//----- MarkFail_D_PhyOneBlock() ---------------------------------------
+/* ----- MarkFail_D_PhyOneBlock() --------------------------------------- */
 int MarkFail_D_PhyOneBlock(struct us_data *us)
 {
 	BYTE sect;
-	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
-	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
-	sect=Media.Sector;
+	sect = Media.Sector;
 	Set_D_FailBlock(WorkRedund);
-	//Ssfdc_D_WriteRedtMode();
 
-	for(Media.Sector=0; Media.Sector<Ssfdc.MaxSectors; Media.Sector++)
-	{
-		if (Ssfdc_D_WriteRedtData(us, WorkRedund))
-		{
+	for (Media.Sector = 0; Media.Sector < Ssfdc.MaxSectors;
+							Media.Sector++) {
+		if (Ssfdc_D_WriteRedtData(us, WorkRedund)) {
 			Ssfdc_D_Reset(us);
 			Media.Sector   = sect;
 			ErrCode        = ERR_HwError;
 			MediaChange = ERROR;
-			return(ERROR);
-		} // NO Status Check
+			return ERROR;
+		} /* NO Status Check */
 	}
 
 	Ssfdc_D_Reset(us);
-	Media.Sector=sect;
-	return(SMSUCCESS);
+	Media.Sector = sect;
+	return SMSUCCESS;
 }
-/*
-//
-////----- SM_Init() ----------------------------------------------------
-//void SM_Init(void)
-//{
-//    _Hw_D_ClrIntCardChg();
-//    _Hw_D_SetIntMask();
-//    // For DMA Interrupt
-//    _Hw_D_ClrDMAIntCardChg();
-//    _Hw_D_SetDMAIntMask();
-//}
-//
-////----- Media_D_EraseAllRedtData() -----------------------------------
-//int Media_D_EraseAllRedtData(DWORD Index, BOOLEAN CheckBlock)
-//{
-//    BYTE    i;
-//
-//    if (Check_D_MediaPower())
-//        return(ErrCode);
-//
-//    if (Check_D_MediaWP())
-//        return(ErrCode);
-//
-//    for (i=0; i<REDTSIZE; i++)
-//        WorkRedund[i] = 0xFF;
-//
-//    Media.Zone = (BYTE)Index;
-//    for (Media.PhyBlock=0; Media.PhyBlock<Ssfdc.MaxBlocks; Media.PhyBlock++)
-//    {
-//        if ((!Media.Zone) && (Media.PhyBlock<=CisArea.PhyBlock))
-//            continue;
-//
-//        if (Ssfdc_D_EraseBlock(fdoExt))
-//        {
-//            ErrCode = ERR_HwError;
-//            return(ERROR);
-//        }
-//
-//        for(Media.Sector=0; Media.Sector<Ssfdc.MaxSectors; Media.Sector++)
-//        {
-//            Ssfdc_D_WriteRedtMode();
-//
-//            if (Ssfdc_D_WriteRedtData(WorkRedund))
-//            {
-//                Ssfdc_D_Reset(fdoExt);
-//                ErrCode        = ERR_HwError;
-//                MediaChange    = ERROR;
-//                return(ERROR);
-//            } // NO Status Check
-//        }
-//
-//        Ssfdc_D_Reset(fdoExt);
-//    }
-//
-//    Ssfdc_D_Reset(fdoExt);
-//
-//    return(SMSUCCESS);
-//}
-//
-////----- Media_D_GetMediaInfo() ---------------------------------------
-//DWORD Media_D_GetMediaInfo(PFDO_DEVICE_EXTENSION fdoExt, PIOCTL_MEDIA_INFO_IN pParamIn, PIOCTL_MEDIA_INFO_OUT pParamOut)
-//{
-//    pParamOut->ErrCode = STATUS_CMD_FAIL;
-//
-//    Init_D_SmartMedia();
-//
-//    if (Check_D_MediaPower())
-//        return (ErrCode==ERR_NoSmartMedia) ? STATUS_CMD_NO_MEDIA : STATUS_CMD_FAIL;
-//
-//    if (Set_D_PhyFmtValue(fdoExt))
-//        return STATUS_CMD_FAIL;
-//
-//    //usleep(56*1024);
-//    if (Search_D_CIS(fdoExt))
-//        return STATUS_CMD_FAIL;
-//
-//    if (Check_D_MediaWP())
-//        return STATUS_CMD_MEDIA_WP;
-//
-//    pParamOut->PageSize  = Ssfdc.MaxSectors;
-//    pParamOut->BlockSize = Ssfdc.MaxBlocks;
-//    pParamOut->ZoneSize  = Ssfdc.MaxZones;
-//
-//    return STATUS_CMD_SUCCESS;
-//}*/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/smilsub.c linux-libre-3.11-rc7-gnu/drivers/staging/keucr/smilsub.c
--- linux-libre-3.10-gnu/drivers/staging/keucr/smilsub.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/smilsub.c	2013-08-25 20:43:22.000000000 -0400
@@ -33,9 +33,9 @@ void   _Set_D_ECCdata(BYTE, BYTE *);
 void   _Calc_D_ECCdata(BYTE *);
 
 
-struct SSFDCTYPE                Ssfdc;
-struct ADDRESS                  Media;
-struct CIS_AREA                 CisArea;
+struct keucr_media_info         Ssfdc;
+struct keucr_media_address      Media;
+struct keucr_media_area         CisArea;
 
 static BYTE                            EccBuf[6];
 extern PBYTE                    SMHostAddr;
@@ -103,8 +103,10 @@ int Load_D_LogBlockAddr(BYTE *redundant)
 {
 	WORD addr1, addr2;
 
-	addr1 = (WORD)*(redundant + REDT_ADDR1H)*0x0100 + (WORD)*(redundant + REDT_ADDR1L);
-	addr2 = (WORD)*(redundant + REDT_ADDR2H)*0x0100 + (WORD)*(redundant + REDT_ADDR2L);
+	addr1 = (WORD)*(redundant + REDT_ADDR1H)*0x0100 +
+					(WORD)*(redundant + REDT_ADDR1L);
+	addr2 = (WORD)*(redundant + REDT_ADDR2H)*0x0100 +
+					(WORD)*(redundant + REDT_ADDR2L);
 
 	if (addr1 == addr2)
 		if ((addr1 & 0xF000) == 0x1000) {
@@ -151,7 +153,8 @@ void Set_D_LogBlockAddr(BYTE *redundant)
 	if ((hweight16(addr) % 2))
 		addr++;
 
-	*(redundant + REDT_ADDR1H) = *(redundant + REDT_ADDR2H) = (BYTE)(addr / 0x0100);
+	*(redundant + REDT_ADDR1H) = *(redundant + REDT_ADDR2H) =
+							(BYTE)(addr / 0x0100);
 	*(redundant + REDT_ADDR1L) = *(redundant + REDT_ADDR2L) = (BYTE)addr;
 }
 
@@ -191,7 +194,9 @@ int Ssfdc_D_ReadCisSect(struct us_data *
 	Media.Sector = CisArea.Sector;
 
 	if (Ssfdc_D_ReadSect(us, buf, redundant)) {
-		Media.Zone = zone; Media.PhyBlock = block; Media.Sector = sector;
+		Media.Zone = zone;
+		Media.PhyBlock = block;
+		Media.Sector = sector;
 		return ERROR;
 	}
 
@@ -209,7 +214,8 @@ int Ssfdc_D_ReadSect(struct us_data *us,
 
 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk("Load SM RW Code Fail !!\n");
+		dev_err(&us->pusb_dev->dev,
+			"Failed to load SmartMedia read/write code\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -252,7 +258,8 @@ int Ssfdc_D_ReadSect(struct us_data *us,
 }
 
 /* ----- Ssfdc_D_ReadBlock() --------------------------------------------- */
-int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf, BYTE *redundant)
+int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,
+							BYTE *redundant)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int	result;
@@ -260,7 +267,8 @@ int Ssfdc_D_ReadBlock(struct us_data *us
 
 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk("Load SM RW Code Fail !!\n");
+		dev_err(&us->pusb_dev->dev,
+			"Failed to load SmartMedia read/write code\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -304,7 +312,8 @@ int Ssfdc_D_ReadBlock(struct us_data *us
 
 
 /* ----- Ssfdc_D_CopyBlock() -------------------------------------------- */
-int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf, BYTE *redundant)
+int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,
+							BYTE *redundant)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int	result;
@@ -312,7 +321,8 @@ int Ssfdc_D_CopyBlock(struct us_data *us
 
 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk("Load SM RW Code Fail !!\n");
+		dev_err(&us->pusb_dev->dev,
+			"Failed to load SmartMedia read/write code\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -358,7 +368,8 @@ int Ssfdc_D_WriteSectForCopy(struct us_d
 
 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk("Load SM RW Code Fail !!\n");
+		dev_err(&us->pusb_dev->dev,
+			"Failed to load SmartMedia read/write code\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -396,7 +407,8 @@ int Ssfdc_D_EraseBlock(struct us_data *u
 
 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk("Load SM RW Code Fail !!\n");
+		dev_err(&us->pusb_dev->dev,
+			"Failed to load SmartMedia read/write code\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -431,7 +443,8 @@ int Ssfdc_D_ReadRedtData(struct us_data
 
 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk("Load SM RW Code Fail !!\n");
+		dev_err(&us->pusb_dev->dev,
+			"Failed to load SmartMedia read/write code\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -470,7 +483,8 @@ int Ssfdc_D_WriteRedtData(struct us_data
 
 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD) {
-		printk("Load SM RW Code Fail !!\n");
+		dev_err(&us->pusb_dev->dev,
+			"Failed to load SmartMedia read/write code\n");
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
@@ -611,7 +625,7 @@ int Set_D_SsfdcModel(BYTE dcode)
 		return ERROR;
 	}
 
-    return SMSUCCESS;
+	return SMSUCCESS;
 }
 
 /* ----- _Check_D_DevCode() --------------------------------------------- */
@@ -686,8 +700,8 @@ int Check_D_CISdata(BYTE *buf, BYTE *red
 /* ----- Set_D_RightECC() ---------------------------------------------- */
 void Set_D_RightECC(BYTE *redundant)
 {
-    /* Driver ECC Check */
-    return;
+	/* Driver ECC Check */
+	return;
 }
 
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/smscsi.c linux-libre-3.11-rc7-gnu/drivers/staging/keucr/smscsi.c
--- linux-libre-3.10-gnu/drivers/staging/keucr/smscsi.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/smscsi.c	2013-08-25 20:43:22.000000000 -0400
@@ -56,7 +56,7 @@ int SM_SCSIIrp(struct us_data *us, struc
 	return result;
 }
 
-/* ----- SM_SCSI_Test_Unit_Ready() -------------------------------------------------- */
+/* ----- SM_SCSI_Test_Unit_Ready() ------------------------------------- */
 int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
 {
 	if (us->SM_Status.Insert && us->SM_Status.Ready)
@@ -69,21 +69,27 @@ int SM_SCSI_Test_Unit_Ready(struct us_da
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-/* ----- SM_SCSI_Inquiry() -------------------------------------------------- */
+/* ----- SM_SCSI_Inquiry() --------------------------------------------- */
 int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
 {
-	BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
+	BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00,
+				 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20,
+				 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65,
+				 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20,
+				 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
 
 	usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF);
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
 
-/* ----- SM_SCSI_Mode_Sense() -------------------------------------------------- */
+/* ----- SM_SCSI_Mode_Sense() ------------------------------------------ */
 int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
 {
-	BYTE	mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
-	BYTE	mediaWP[12]   = {0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
+	BYTE	mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00,
+				0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
+	BYTE	mediaWP[12]   = {0x0b, 0x00, 0x80, 0x08, 0x00, 0x00,
+				0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
 
 	if (us->SM_Status.WtP)
 		usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF);
@@ -94,7 +100,7 @@ int SM_SCSI_Mode_Sense(struct us_data *u
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-/* ----- SM_SCSI_Read_Capacity() -------------------------------------------------- */
+/* ----- SM_SCSI_Read_Capacity() --------------------------------------- */
 int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
 {
 	unsigned int offset = 0;
@@ -103,14 +109,14 @@ int SM_SCSI_Read_Capacity(struct us_data
 	WORD    bl_len;
 	BYTE    buf[8];
 
-	printk("SM_SCSI_Read_Capacity\n");
+	dev_dbg(&us->pusb_dev->dev, "SM_SCSI_Read_Capacity\n");
 
 	bl_len = 0x200;
 	bl_num = Ssfdc.MaxLogBlocks * Ssfdc.MaxSectors * Ssfdc.MaxZones - 1;
 
 	us->bl_num = bl_num;
-	printk("bl_len = %x\n", bl_len);
-	printk("bl_num = %x\n", bl_num);
+	dev_dbg(&us->pusb_dev->dev, "bl_len = %x\n", bl_len);
+	dev_dbg(&us->pusb_dev->dev, "bl_num = %x\n", bl_num);
 
 	buf[0] = (bl_num >> 24) & 0xff;
 	buf[1] = (bl_num >> 16) & 0xff;
@@ -131,8 +137,10 @@ int SM_SCSI_Read(struct us_data *us, str
 {
 	int result = 0;
 	PBYTE	Cdb = srb->cmnd;
-	DWORD bn  =  ((Cdb[2] << 24) & 0xff000000) | ((Cdb[3] << 16) & 0x00ff0000) |
-		((Cdb[4] << 8) & 0x0000ff00) | ((Cdb[5] << 0) & 0x000000ff);
+	DWORD bn  =  ((Cdb[2] << 24) & 0xff000000) |
+			((Cdb[3] << 16) & 0x00ff0000) |
+			((Cdb[4] << 8) & 0x0000ff00) |
+			((Cdb[5] << 0) & 0x000000ff);
 	WORD  blen = ((Cdb[7] << 8) & 0xff00)     | ((Cdb[8] << 0) & 0x00ff);
 	DWORD	blenByte = blen * 0x200;
 	void	*buf;
@@ -161,8 +169,10 @@ int SM_SCSI_Write(struct us_data *us, st
 {
 	int result = 0;
 	PBYTE	Cdb = srb->cmnd;
-	DWORD bn  =  ((Cdb[2] << 24) & 0xff000000) | ((Cdb[3] << 16) & 0x00ff0000) |
-		((Cdb[4] << 8) & 0x0000ff00) | ((Cdb[5] << 0) & 0x000000ff);
+	DWORD bn  =  ((Cdb[2] << 24) & 0xff000000) |
+			((Cdb[3] << 16) & 0x00ff0000) |
+			((Cdb[4] << 8) & 0x0000ff00) |
+			((Cdb[5] << 0) & 0x000000ff);
 	WORD  blen = ((Cdb[7] << 8) & 0xff00)     | ((Cdb[8] << 0) & 0x00ff);
 	DWORD	blenByte = blen * 0x200;
 	void	*buf;
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/transport.c linux-libre-3.11-rc7-gnu/drivers/staging/keucr/transport.c
--- linux-libre-3.10-gnu/drivers/staging/keucr/transport.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/transport.c	2013-08-25 20:43:22.000000000 -0400
@@ -79,6 +79,47 @@ static int usb_stor_msg_common(struct us
 }
 
 /*
+ * usb_stor_print_cmd():
+ */
+static void usb_stor_print_cmd(struct us_data *us, struct scsi_cmnd *srb)
+{
+	PBYTE   Cdb = srb->cmnd;
+	DWORD   cmd = Cdb[0];
+
+	switch (cmd) {
+	case TEST_UNIT_READY:
+		break;
+	case INQUIRY:
+		dev_dbg(&us->pusb_dev->dev,
+				"scsi cmd %X --- SCSIOP_INQUIRY\n", cmd);
+		break;
+	case MODE_SENSE:
+		dev_dbg(&us->pusb_dev->dev,
+				"scsi cmd %X --- SCSIOP_MODE_SENSE\n", cmd);
+		break;
+	case START_STOP:
+		dev_dbg(&us->pusb_dev->dev,
+				"scsi cmd %X --- SCSIOP_START_STOP\n", cmd);
+		break;
+	case READ_CAPACITY:
+		dev_dbg(&us->pusb_dev->dev,
+				"scsi cmd %X --- SCSIOP_READ_CAPACITY\n", cmd);
+		break;
+	case READ_10:
+		break;
+	case WRITE_10:
+		break;
+	case ALLOW_MEDIUM_REMOVAL:
+		dev_dbg(&us->pusb_dev->dev,
+			"scsi cmd %X --- SCSIOP_ALLOW_MEDIUM_REMOVAL\n", cmd);
+		break;
+	default:
+		dev_dbg(&us->pusb_dev->dev, "scsi cmd %X --- Other cmd\n", cmd);
+		break;
+	}
+}
+
+/*
  * usb_stor_control_msg()
  */
 int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
@@ -303,7 +344,7 @@ void usb_stor_invoke_transport(struct sc
 	int result;
 
 	/* pr_info("transport --- usb_stor_invoke_transport\n"); */
-	usb_stor_print_cmd(srb);
+	usb_stor_print_cmd(us, srb);
 	/* send the command to the transport layer */
 	scsi_set_resid(srb, 0);
 	result = us->transport(srb, us); /* usb_stor_Bulk_transport; */
@@ -429,7 +470,7 @@ void ENE_stor_invoke_transport(struct sc
 	int result = 0;
 
 	/* pr_info("transport --- ENE_stor_invoke_transport\n"); */
-	usb_stor_print_cmd(srb);
+	usb_stor_print_cmd(us, srb);
 	/* send the command to the transport layer */
 	scsi_set_resid(srb, 0);
 	if (!(us->SM_Status.Ready))
@@ -708,8 +749,8 @@ int usb_stor_Bulk_transport(struct scsi_
 
 		} else {
 			residue = min(residue, transfer_length);
-			scsi_set_resid(srb, max(scsi_get_resid(srb),
-							(int) residue));
+			scsi_set_resid(srb, max_t(int, scsi_get_resid(srb),
+							residue));
 		}
 	}
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/transport.h linux-libre-3.11-rc7-gnu/drivers/staging/keucr/transport.h
--- linux-libre-3.10-gnu/drivers/staging/keucr/transport.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/transport.h	2013-08-25 20:43:22.000000000 -0400
@@ -29,7 +29,6 @@
 extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*);
 extern int usb_stor_Bulk_max_lun(struct us_data *);
 extern int usb_stor_Bulk_reset(struct us_data *);
-extern void usb_stor_print_cmd(struct scsi_cmnd *);
 extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*);
 extern void usb_stor_stop_transport(struct us_data *);
 extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
@@ -61,7 +60,7 @@ extern int ENE_InitMedia(struct us_data
 extern int ENE_SMInit(struct us_data *);
 extern int ENE_SendScsiCmd(struct us_data*, BYTE, void*, int);
 extern int ENE_LoadBinCode(struct us_data*, BYTE);
-extern int ENE_Read_BYTE(struct us_data*, WORD index, void *buf);
+extern int ene_read_byte(struct us_data*, WORD index, void *buf);
 extern int ENE_Read_Data(struct us_data*, void *buf, unsigned int length);
 extern int ENE_Write_Data(struct us_data*, void *buf, unsigned int length);
 extern void BuildSenseBuffer(struct scsi_cmnd *, int);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/usb.c linux-libre-3.11-rc7-gnu/drivers/staging/keucr/usb.c
--- linux-libre-3.10-gnu/drivers/staging/keucr/usb.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/usb.c	2013-08-25 20:43:22.000000000 -0400
@@ -24,13 +24,13 @@ MODULE_LICENSE("GPL");
 
 static unsigned int delay_use = 1;
 
-static struct usb_device_id eucr_usb_ids [] = {
+static struct usb_device_id eucr_usb_ids[] = {
 	{ USB_DEVICE(0x058f, 0x6366) },
 	{ USB_DEVICE(0x0cf2, 0x6230) },
 	{ USB_DEVICE(0x0cf2, 0x6250) },
 	{ }                                            /* Terminating entry */
 };
-MODULE_DEVICE_TABLE (usb, eucr_usb_ids);
+MODULE_DEVICE_TABLE(usb, eucr_usb_ids);
 
 
 #ifdef CONFIG_PM
@@ -65,7 +65,7 @@ static int eucr_resume(struct usb_interf
 
 	us->Power_IsResum = true;
 
-	us->SM_Status = *(PSM_STATUS)&tmp;
+	us->SM_Status = *(struct keucr_sm_status *)&tmp;
 
 	return 0;
 }
@@ -85,9 +85,9 @@ static int eucr_reset_resume(struct usb_
 	 * the device
 	 */
 
- 	us->Power_IsResum = true;
+	us->Power_IsResum = true;
 
-	us->SM_Status = *(PSM_STATUS)&tmp;
+	us->SM_Status = *(struct keucr_sm_status *)&tmp;
 
 	return 0;
 }
@@ -124,16 +124,18 @@ static int eucr_post_reset(struct usb_in
 	return 0;
 }
 
-void fill_inquiry_response(struct us_data *us, unsigned char *data, unsigned int data_len)
+void fill_inquiry_response(struct us_data *us, unsigned char *data,
+							unsigned int data_len)
 {
 	pr_info("usb --- fill_inquiry_response\n");
 	if (data_len < 36) /* You lose. */
 		return;
 
 	if (data[0]&0x20) {
-		memset(data+8,0,28);
+		memset(data+8, 0, 28);
 	} else {
-		u16 bcdDevice = le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
+		u16 bcdDevice =
+			le16_to_cpu(us->pusb_dev->descriptor.bcdDevice);
 		memcpy(data+8, us->unusual_dev->vendorName,
 			strlen(us->unusual_dev->vendorName) > 8 ? 8 :
 			strlen(us->unusual_dev->vendorName));
@@ -148,7 +150,7 @@ void fill_inquiry_response(struct us_dat
 	usb_stor_set_xfer_buf(us, data, data_len, us->srb, TO_XFER_BUF);
 }
 
-static int usb_stor_control_thread(void * __us)
+static int usb_stor_control_thread(void *__us)
 {
 	struct us_data *us = (struct us_data *)__us;
 	struct Scsi_Host *host = us_to_host(us);
@@ -194,7 +196,8 @@ static int usb_stor_control_thread(void
 			us->srb->result = DID_BAD_TARGET << 16;
 		} else if ((us->srb->cmnd[0] == INQUIRY)
 			   && (us->fflags & US_FL_FIX_INQUIRY)) {
-			unsigned char data_ptr[36] = {0x00, 0x80, 0x02, 0x02, 0x1F, 0x00, 0x00, 0x00};
+			unsigned char data_ptr[36] = {0x00, 0x80, 0x02, 0x02,
+						0x1F, 0x00, 0x00, 0x00};
 
 			fill_inquiry_response(us, data_ptr, 36);
 			us->srb->result = SAM_STAT_GOOD;
@@ -253,13 +256,15 @@ static int associate_dev(struct us_data
 	usb_set_intfdata(intf, us);
 
 	/* Allocate the device-related DMA-mapped buffers */
-	us->cr = usb_alloc_coherent(us->pusb_dev, sizeof(*us->cr), GFP_KERNEL, &us->cr_dma);
+	us->cr = usb_alloc_coherent(us->pusb_dev, sizeof(*us->cr), GFP_KERNEL,
+							&us->cr_dma);
 	if (!us->cr) {
 		pr_info("usb_ctrlrequest allocation failed\n");
 		return -ENOMEM;
 	}
 
-	us->iobuf = usb_alloc_coherent(us->pusb_dev, US_IOBUF_SIZE, GFP_KERNEL, &us->iobuf_dma);
+	us->iobuf = usb_alloc_coherent(us->pusb_dev, US_IOBUF_SIZE, GFP_KERNEL,
+							&us->iobuf_dma);
 	if (!us->iobuf) {
 		pr_info("I/O buffer allocation failed\n");
 		return -ENOMEM;
@@ -275,7 +280,8 @@ static int associate_dev(struct us_data
 static int get_device_info(struct us_data *us, const struct usb_device_id *id)
 {
 	struct usb_device *dev = us->pusb_dev;
-	struct usb_interface_descriptor *idesc = &us->pusb_intf->cur_altsetting->desc;
+	struct usb_interface_descriptor *idesc =
+					&us->pusb_intf->cur_altsetting->desc;
 
 	pr_info("usb --- get_device_info\n");
 
@@ -374,10 +380,13 @@ static int get_pipes(struct us_data *us)
 	/* Calculate and store the pipe values */
 	us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0);
 	us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0);
-	us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-	us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+	us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev,
+			ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+	us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev,
+			ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
 	if (ep_int) {
-		us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+		us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev,
+			ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
 		us->ep_bInterval = ep_int->bInterval;
 	}
 	return 0;
@@ -433,10 +442,9 @@ static void dissociate_dev(struct us_dat
 	kfree(us->sensebuf);
 
 	/* Free the device-related DMA-mapped buffers */
-	if (us->cr)
-		usb_free_coherent(us->pusb_dev, sizeof(*us->cr), us->cr, us->cr_dma);
-	if (us->iobuf)
-		usb_free_coherent(us->pusb_dev, US_IOBUF_SIZE, us->iobuf, us->iobuf_dma);
+	usb_free_coherent(us->pusb_dev, sizeof(*us->cr), us->cr, us->cr_dma);
+	usb_free_coherent(us->pusb_dev, US_IOBUF_SIZE, us->iobuf,
+			  us->iobuf_dma);
 
 	/* Remove our private data from the interface */
 	usb_set_intfdata(us->pusb_intf, NULL);
@@ -485,7 +493,7 @@ static void release_everything(struct us
 	scsi_host_put(us_to_host(us));
 }
 
-static int usb_stor_scan_thread(void * __us)
+static int usb_stor_scan_thread(void *__us)
 {
 	struct us_data *us = (struct us_data *)__us;
 
@@ -515,7 +523,8 @@ static int usb_stor_scan_thread(void * _
 	complete_and_exit(&us->scanning_done, 0);
 }
 
-static int eucr_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int eucr_probe(struct usb_interface *intf,
+					const struct usb_device_id *id)
 {
 	struct Scsi_Host *host;
 	struct us_data *us;
@@ -525,7 +534,7 @@ static int eucr_probe(struct usb_interfa
 
 	pr_info("usb --- eucr_probe\n");
 
-      host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us));
+	host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us));
 	if (!host) {
 		pr_info("Unable to allocate the scsi host\n");
 		return -ENOMEM;
@@ -585,7 +594,7 @@ static int eucr_probe(struct usb_interfa
 	wake_up_process(th);
 
 	/* probe card type */
-	result = ENE_Read_BYTE(us, REG_CARD_STATUS, &MiscReg03);
+	result = ene_read_byte(us, REG_CARD_STATUS, &MiscReg03);
 	if (result != USB_STOR_XFER_GOOD) {
 		result = USB_STOR_TRANSPORT_ERROR;
 		quiesce_and_remove_host(us);
@@ -595,9 +604,9 @@ static int eucr_probe(struct usb_interfa
 	if (!(MiscReg03 & 0x02)) {
 		result = -ENODEV;
 		quiesce_and_remove_host(us);
-		pr_info("keucr: The driver only supports SM/MS card.\
-			To use SD card, \
-			please build driver/usb/storage/ums-eneub6250.ko\n");
+		pr_info("keucr: The driver only supports SM/MS card. "
+			"To use SD card, "
+			"please build driver/usb/storage/ums-eneub6250.ko\n");
 		goto BadDevice;
 	}
 
@@ -623,9 +632,9 @@ static void eucr_disconnect(struct usb_i
 static struct usb_driver usb_storage_driver = {
 	.name =		"eucr",
 	.probe =		eucr_probe,
-    	.suspend =	    eucr_suspend,
+	.suspend =	    eucr_suspend,
 	.resume =	    eucr_resume,
-    	.reset_resume =	eucr_reset_resume,
+	.reset_resume =	eucr_reset_resume,
 	.disconnect =	eucr_disconnect,
 	.pre_reset =	eucr_pre_reset,
 	.post_reset =	eucr_post_reset,
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/keucr/usb.h linux-libre-3.11-rc7-gnu/drivers/staging/keucr/usb.h
--- linux-libre-3.10-gnu/drivers/staging/keucr/usb.h	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/keucr/usb.h	2013-08-25 20:43:22.000000000 -0400
@@ -1,4 +1,4 @@
-// Driver for USB Mass Storage compliant devices
+/* Driver for USB Mass Storage compliant devices */
 
 #ifndef _USB_H_
 #define _USB_H_
@@ -19,26 +19,26 @@ struct scsi_cmnd;
  */
 
 struct us_unusual_dev {
-	const char* vendorName;
-	const char* productName;
+	const char *vendorName;
+	const char *productName;
 	__u8  useProtocol;
 	__u8  useTransport;
 	int (*initFunction)(struct us_data *);
 };
 
-//EnE HW Register
+/* EnE HW Register */
 #define REG_CARD_STATUS     0xFF83
 #define REG_HW_TRAP1        0xFF89
 
-// SRB Status. Refers /usr/include/wine/wine/wnaspi32.h & SCSI sense key
-#define SS_SUCCESS                  0x00      // No Sense
+/* SRB Status. Refers /usr/include/wine/wine/wnaspi32.h & SCSI sense key */
+#define SS_SUCCESS                  0x00      /* No Sense */
 #define SS_NOT_READY                0x02
 #define SS_MEDIUM_ERR               0x03
 #define SS_HW_ERR                   0x04
 #define SS_ILLEGAL_REQUEST          0x05
 #define SS_UNIT_ATTENTION           0x06
 
-//ENE Load FW Pattern
+/* ENE Load FW Pattern */
 #define SD_INIT1_PATTERN   1
 #define SD_INIT2_PATTERN   2
 #define SD_RW_PATTERN      3
@@ -51,39 +51,40 @@ struct us_unusual_dev {
 #define FDIR_WRITE        0
 #define FDIR_READ         1
 
-typedef struct _SD_STATUS {
-    BYTE    Insert:1;
-    BYTE    Ready:1;
-    BYTE    MediaChange:1;
-    BYTE    IsMMC:1;
-    BYTE    HiCapacity:1;
-    BYTE    HiSpeed:1;
-    BYTE    WtP:1;
-    BYTE    Reserved:1;
-} SD_STATUS, *PSD_STATUS;
+struct keucr_sd_status {
+	BYTE    Insert:1;
+	BYTE    Ready:1;
+	BYTE    MediaChange:1;
+	BYTE    IsMMC:1;
+	BYTE    HiCapacity:1;
+	BYTE    HiSpeed:1;
+	BYTE    WtP:1;
+	BYTE    Reserved:1;
+};
 
-typedef struct _MS_STATUS {
-    BYTE    Insert:1;
-    BYTE    Ready:1;
-    BYTE    MediaChange:1;
-    BYTE    IsMSPro:1;
-    BYTE    IsMSPHG:1;
-    BYTE    Reserved1:1;
-    BYTE    WtP:1;
-    BYTE    Reserved2:1;
-} MS_STATUS, *PMS_STATUS;
+struct keucr_ms_status {
+	BYTE    Insert:1;
+	BYTE    Ready:1;
+	BYTE    MediaChange:1;
+	BYTE    IsMSPro:1;
+	BYTE    IsMSPHG:1;
+	BYTE    Reserved1:1;
+	BYTE    WtP:1;
+	BYTE    Reserved2:1;
+};
 
-typedef struct _SM_STATUS {
-    BYTE    Insert:1;
-    BYTE    Ready:1;
-    BYTE    MediaChange:1;
-    BYTE    Reserved:3;
-    BYTE    WtP:1;
-    BYTE    IsMS:1;
-} SM_STATUS, *PSM_STATUS;
+struct keucr_sm_status {
+	BYTE    Insert:1;
+	BYTE    Ready:1;
+	BYTE    MediaChange:1;
+	BYTE    Reserved:3;
+	BYTE    WtP:1;
+	BYTE    IsMS:1;
+};
 
-// SD Block Length
-#define SD_BLOCK_LEN                            9       // 2^9 = 512 Bytes, The HW maximum read/write data length
+/* SD Block Length */
+#define SD_BLOCK_LEN		9	/* 2^9 = 512 Bytes,
+				The HW maximum read/write data length */
 
 /* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
 #define US_FLIDX_URB_ACTIVE	0	/* current_urb is in use    */
@@ -107,9 +108,9 @@ typedef struct _SM_STATUS {
 #define US_IOBUF_SIZE		64	/* Size of the DMA-mapped I/O buffer */
 #define US_SENSE_SIZE		18	/* Size of the autosense data buffer */
 
-typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
-typedef int (*trans_reset)(struct us_data*);
-typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
+typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data *);
+typedef int (*trans_reset)(struct us_data *);
+typedef void (*proto_cmnd)(struct scsi_cmnd *, struct us_data *);
 typedef void (*extra_data_destructor)(void *);	/* extra data destructor */
 typedef void (*pm_hook)(struct us_data *, int);	/* power management hook */
 
@@ -176,19 +177,19 @@ struct us_data {
 #ifdef CONFIG_PM
 	pm_hook			suspend_resume_hook;
 #endif
-	// for 6250 code
-	SD_STATUS   SD_Status;
-	MS_STATUS   MS_Status;
-	SM_STATUS   SM_Status;
+	/* for 6250 code */
+	struct keucr_sd_status   SD_Status;
+	struct keucr_ms_status   MS_Status;
+	struct keucr_sm_status   SM_Status;
 
-	//----- SD Control Data ----------------
-	//SD_REGISTER SD_Regs;
+	/* ----- SD Control Data ---------------- */
+	/* SD_REGISTER SD_Regs; */
 	WORD        SD_Block_Mult;
 	BYTE        SD_READ_BL_LEN;
 	WORD        SD_C_SIZE;
 	BYTE        SD_C_SIZE_MULT;
 
-	// SD/MMC New spec.
+	/* SD/MMC New spec. */
 	BYTE        SD_SPEC_VER;
 	BYTE        SD_CSD_VER;
 	BYTE        SD20_HIGH_CAPACITY;
@@ -196,15 +197,15 @@ struct us_data {
 	BYTE        MMC_SPEC_VER;
 	BYTE        MMC_BusWidth;
 	BYTE        MMC_HIGH_CAPACITY;
-	
-	//----- MS Control Data ----------------
+
+	/* ----- MS Control Data ---------------- */
 	BOOLEAN             MS_SWWP;
 	DWORD               MSP_TotalBlock;
 	/* MS_LibControl       MS_Lib; */
 	BOOLEAN             MS_IsRWPage;
 	WORD                MS_Model;
 
-	//----- SM Control Data ----------------
+	/* ----- SM Control Data ---------------- */
 	BYTE		SM_DeviceID;
 	BYTE		SM_CardID;
 
@@ -212,16 +213,18 @@ struct us_data {
 	BYTE		BIN_FLAG;
 	DWORD		bl_num;
 	int		SrbStatus;
-	
-	//------Power Managerment ---------------
-	BOOLEAN         Power_IsResum;	
+
+	/* ------Power Managerment --------------- */
+	BOOLEAN         Power_IsResum;
 };
 
 /* Convert between us_data and the corresponding Scsi_Host */
-static inline struct Scsi_Host *us_to_host(struct us_data *us) {
+static inline struct Scsi_Host *us_to_host(struct us_data *us)
+{
 	return container_of((void *) us, struct Scsi_Host, hostdata);
 }
-static inline struct us_data *host_to_us(struct Scsi_Host *host) {
+static inline struct us_data *host_to_us(struct Scsi_Host *host)
+{
 	return (struct us_data *) host->hostdata;
 }
 
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/line6/pcm.c linux-libre-3.11-rc7-gnu/drivers/staging/line6/pcm.c
--- linux-libre-3.10-gnu/drivers/staging/line6/pcm.c	2013-06-30 18:13:29.000000000 -0400
+++ linux-libre-3.11-rc7-gnu/drivers/staging/line6/pcm.c	2013-08-25 20:43:22.000000000 -0400
@@ -107,11 +107,15 @@ static bool test_flags(unsigned long fla
 
 int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
 {
-	unsigned long flags_old =
-	    __sync_fetch_and_or(&line6pcm->flags, channels);
-	unsigned long flags_new = flags_old | channels;
-	unsigned long flags_final = flags_old;
-	int err = 0;
+	unsigned long flags_old, flags_new, flags_final;
+	int err;
+
+	do {
+		flags_old = ACCESS_ONCE(line6pcm->flags);
+		flags_new = flags_old | channels;
+	} while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
+
+	flags_final = flags_old;
 
 	line6pcm->prev_fbuf = NULL;
 
@@ -197,9 +201,12 @@ pcm_acquire_error:
 
 int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)
 {
-	unsigned long flags_old =
-	    __sync_fetch_and_and(&line6pcm->flags, ~channels);
-	unsigned long flags_new = flags_old & ~channels;
+	unsigned long flags_old, flags_new;
+
+	do {
+		flags_old = ACCESS_ONCE(line6pcm->flags);
+		flags_new = flags_old & ~channels;
+	} while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
 
 	if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM))
 		line6_unlink_audio_in_urbs(line6pcm);
@@ -385,8 +392,11 @@ static int snd_line6_pcm_free(struct snd
 */
 static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
 {
-	if (substream->runtime && snd_pcm_running(substream))
+	if (substream->runtime && snd_pcm_running(substream)) {
+		snd_pcm_stream_lock_irq(substream);
 		snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+		snd_pcm_stream_unlock_irq(substream);
+	}
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/bitmap.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/bitmap.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/bitmap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/bitmap.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,111 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+#ifndef _LIBCFS_BITMAP_H_
+#define _LIBCFS_BITMAP_H_
+
+
+typedef struct {
+	int	     size;
+	unsigned long   data[0];
+} cfs_bitmap_t;
+
+#define CFS_BITMAP_SIZE(nbits) \
+     (((nbits/BITS_PER_LONG)+1)*sizeof(long)+sizeof(cfs_bitmap_t))
+
+static inline
+cfs_bitmap_t *CFS_ALLOCATE_BITMAP(int size)
+{
+	cfs_bitmap_t *ptr;
+
+	OBD_ALLOC(ptr, CFS_BITMAP_SIZE(size));
+	if (ptr == NULL)
+		RETURN(ptr);
+
+	ptr->size = size;
+
+	RETURN (ptr);
+}
+
+#define CFS_FREE_BITMAP(ptr)	OBD_FREE(ptr, CFS_BITMAP_SIZE(ptr->size))
+
+static inline
+void cfs_bitmap_set(cfs_bitmap_t *bitmap, int nbit)
+{
+	set_bit(nbit, bitmap->data);
+}
+
+static inline
+void cfs_bitmap_clear(cfs_bitmap_t *bitmap, int nbit)
+{
+	test_and_clear_bit(nbit, bitmap->data);
+}
+
+static inline
+int cfs_bitmap_check(cfs_bitmap_t *bitmap, int nbit)
+{
+	return test_bit(nbit, bitmap->data);
+}
+
+static inline
+int cfs_bitmap_test_and_clear(cfs_bitmap_t *bitmap, int nbit)
+{
+	return test_and_clear_bit(nbit, bitmap->data);
+}
+
+/* return 0 is bitmap has none set bits */
+static inline
+int cfs_bitmap_check_empty(cfs_bitmap_t *bitmap)
+{
+	return find_first_bit(bitmap->data, bitmap->size) == bitmap->size;
+}
+
+static inline
+void cfs_bitmap_copy(cfs_bitmap_t *new, cfs_bitmap_t *old)
+{
+	int newsize;
+
+	LASSERT(new->size >= old->size);
+	newsize = new->size;
+	memcpy(new, old, CFS_BITMAP_SIZE(old->size));
+	new->size = newsize;
+}
+
+#define cfs_foreach_bit(bitmap, pos)					\
+	for ((pos) = find_first_bit((bitmap)->data, bitmap->size);	\
+	     (pos) < (bitmap)->size;					\
+	     (pos) = find_next_bit((bitmap)->data, (bitmap)->size, (pos) + 1))
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/curproc.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/curproc.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/curproc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/curproc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/curproc.h
+ *
+ * Lustre curproc API declaration
+ *
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ */
+
+#ifndef __LIBCFS_CURPROC_H__
+#define __LIBCFS_CURPROC_H__
+
+/*
+ * Portable API to access common characteristics of "current" UNIX process.
+ *
+ * Implemented in portals/include/libcfs/<os>/
+ */
+int    cfs_curproc_groups_nr(void);
+int    current_is_in_group(gid_t group);
+void   cfs_curproc_groups_dump(gid_t *array, int size);
+
+/*
+ * Plus, platform-specific constant
+ *
+ * CFS_CURPROC_COMM_MAX,
+ *
+ * and opaque scalar type
+ *
+ * kernel_cap_t
+ */
+
+/* check if task is running in compat mode.*/
+int current_is_32bit(void);
+#define current_pid()		(current->pid)
+#define current_comm()		(current->comm)
+int cfs_get_environ(const char *key, char *value, int *val_len);
+
+typedef __u32 cfs_cap_t;
+
+#define CFS_CAP_CHOWN		   0
+#define CFS_CAP_DAC_OVERRIDE	    1
+#define CFS_CAP_DAC_READ_SEARCH	 2
+#define CFS_CAP_FOWNER		  3
+#define CFS_CAP_FSETID		  4
+#define CFS_CAP_LINUX_IMMUTABLE	 9
+#define CFS_CAP_SYS_ADMIN	      21
+#define CFS_CAP_SYS_BOOT	       23
+#define CFS_CAP_SYS_RESOURCE	   24
+
+#define CFS_CAP_FS_MASK ((1 << CFS_CAP_CHOWN) |		 \
+			 (1 << CFS_CAP_DAC_OVERRIDE) |	  \
+			 (1 << CFS_CAP_DAC_READ_SEARCH) |       \
+			 (1 << CFS_CAP_FOWNER) |		\
+			 (1 << CFS_CAP_FSETID ) |	       \
+			 (1 << CFS_CAP_LINUX_IMMUTABLE) |       \
+			 (1 << CFS_CAP_SYS_ADMIN) |	     \
+			 (1 << CFS_CAP_SYS_BOOT) |	      \
+			 (1 << CFS_CAP_SYS_RESOURCE))
+
+void cfs_cap_raise(cfs_cap_t cap);
+void cfs_cap_lower(cfs_cap_t cap);
+int cfs_cap_raised(cfs_cap_t cap);
+cfs_cap_t cfs_curproc_cap_pack(void);
+void cfs_curproc_cap_unpack(cfs_cap_t cap);
+int cfs_capable(cfs_cap_t cap);
+
+/* __LIBCFS_CURPROC_H__ */
+#endif
+/*
+ * Local variables:
+ * c-indentation-style: "K&R"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * fill-column: 80
+ * scroll-step: 1
+ * End:
+ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,214 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_cpu.h
+ *
+ * CPU partition
+ *   . CPU partition is virtual processing unit
+ *
+ *   . CPU partition can present 1-N cores, or 1-N NUMA nodes,
+ *     in other words, CPU partition is a processors pool.
+ *
+ * CPU Partition Table (CPT)
+ *   . a set of CPU partitions
+ *
+ *   . There are two modes for CPT: CFS_CPU_MODE_NUMA and CFS_CPU_MODE_SMP
+ *
+ *   . User can specify total number of CPU partitions while creating a
+ *     CPT, ID of CPU partition is always start from 0.
+ *
+ *     Example: if there are 8 cores on the system, while creating a CPT
+ *     with cpu_npartitions=4:
+ *	      core[0, 1] = partition[0], core[2, 3] = partition[1]
+ *	      core[4, 5] = partition[2], core[6, 7] = partition[3]
+ *
+ *	  cpu_npartitions=1:
+ *	      core[0, 1, ... 7] = partition[0]
+ *
+ *   . User can also specify CPU partitions by string pattern
+ *
+ *     Examples: cpu_partitions="0[0,1], 1[2,3]"
+ *	       cpu_partitions="N 0[0-3], 1[4-8]"
+ *
+ *     The first character "N" means following numbers are numa ID
+ *
+ *   . NUMA allocators, CPU affinity threads are built over CPU partitions,
+ *     instead of HW CPUs or HW nodes.
+ *
+ *   . By default, Lustre modules should refer to the global cfs_cpt_table,
+ *     instead of accessing HW CPUs directly, so concurrency of Lustre can be
+ *     configured by cpu_npartitions of the global cfs_cpt_table
+ *
+ *   . If cpu_npartitions=1(all CPUs in one pool), lustre should work the
+ *     same way as 2.2 or earlier versions
+ *
+ * Author: liang@whamcloud.com
+ */
+
+#ifndef __LIBCFS_CPU_H__
+#define __LIBCFS_CPU_H__
+
+#ifndef HAVE_LIBCFS_CPT
+
+typedef unsigned long		cpumask_t;
+typedef unsigned long		nodemask_t;
+
+struct cfs_cpt_table {
+	/* # of CPU partitions */
+	int			ctb_nparts;
+	/* cpu mask */
+	cpumask_t		ctb_mask;
+	/* node mask */
+	nodemask_t		ctb_nodemask;
+	/* version */
+	__u64			ctb_version;
+};
+
+#endif /* !HAVE_LIBCFS_CPT */
+
+/* any CPU partition */
+#define CFS_CPT_ANY		(-1)
+
+extern struct cfs_cpt_table	*cfs_cpt_table;
+
+/**
+ * destroy a CPU partition table
+ */
+void cfs_cpt_table_free(struct cfs_cpt_table *cptab);
+/**
+ * create a cfs_cpt_table with \a ncpt number of partitions
+ */
+struct cfs_cpt_table *cfs_cpt_table_alloc(unsigned int ncpt);
+/**
+ * print string information of cpt-table
+ */
+int cfs_cpt_table_print(struct cfs_cpt_table *cptab, char *buf, int len);
+/**
+ * return total number of CPU partitions in \a cptab
+ */
+int
+cfs_cpt_number(struct cfs_cpt_table *cptab);
+/**
+ * return number of HW cores or hypter-threadings in a CPU partition \a cpt
+ */
+int cfs_cpt_weight(struct cfs_cpt_table *cptab, int cpt);
+/**
+ * is there any online CPU in CPU partition \a cpt
+ */
+int cfs_cpt_online(struct cfs_cpt_table *cptab, int cpt);
+/**
+ * return cpumask of CPU partition \a cpt
+ */
+cpumask_t *cfs_cpt_cpumask(struct cfs_cpt_table *cptab, int cpt);
+/**
+ * return nodemask of CPU partition \a cpt
+ */
+nodemask_t *cfs_cpt_nodemask(struct cfs_cpt_table *cptab, int cpt);
+/**
+ * shadow current HW processor ID to CPU-partition ID of \a cptab
+ */
+int cfs_cpt_current(struct cfs_cpt_table *cptab, int remap);
+/**
+ * shadow HW processor ID \a CPU to CPU-partition ID by \a cptab
+ */
+int cfs_cpt_of_cpu(struct cfs_cpt_table *cptab, int cpu);
+/**
+ * bind current thread on a CPU-partition \a cpt of \a cptab
+ */
+int cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt);
+/**
+ * add \a cpu to CPU partion @cpt of \a cptab, return 1 for success,
+ * otherwise 0 is returned
+ */
+int cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu);
+/**
+ * remove \a cpu from CPU partition \a cpt of \a cptab
+ */
+void cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu);
+/**
+ * add all cpus in \a mask to CPU partition \a cpt
+ * return 1 if successfully set all CPUs, otherwise return 0
+ */
+int cfs_cpt_set_cpumask(struct cfs_cpt_table *cptab,
+			int cpt, cpumask_t *mask);
+/**
+ * remove all cpus in \a mask from CPU partition \a cpt
+ */
+void cfs_cpt_unset_cpumask(struct cfs_cpt_table *cptab,
+			   int cpt, cpumask_t *mask);
+/**
+ * add all cpus in NUMA node \a node to CPU partition \a cpt
+ * return 1 if successfully set all CPUs, otherwise return 0
+ */
+int cfs_cpt_set_node(struct cfs_cpt_table *cptab, int cpt, int node);
+/**
+ * remove all cpus in NUMA node \a node from CPU partition \a cpt
+ */
+void cfs_cpt_unset_node(struct cfs_cpt_table *cptab, int cpt, int node);
+
+/**
+ * add all cpus in node mask \a mask to CPU partition \a cpt
+ * return 1 if successfully set all CPUs, otherwise return 0
+ */
+int cfs_cpt_set_nodemask(struct cfs_cpt_table *cptab,
+			 int cpt, nodemask_t *mask);
+/**
+ * remove all cpus in node mask \a mask from CPU partition \a cpt
+ */
+void cfs_cpt_unset_nodemask(struct cfs_cpt_table *cptab,
+			    int cpt, nodemask_t *mask);
+/**
+ * unset all cpus for CPU partition \a cpt
+ */
+void cfs_cpt_clear(struct cfs_cpt_table *cptab, int cpt);
+/**
+ * convert partition id \a cpt to numa node id, if there are more than one
+ * nodes in this partition, it might return a different node id each time.
+ */
+int cfs_cpt_spread_node(struct cfs_cpt_table *cptab, int cpt);
+
+/**
+ * iterate over all CPU partitions in \a cptab
+ */
+#define cfs_cpt_for_each(i, cptab)	\
+	for (i = 0; i < cfs_cpt_number(cptab); i++)
+
+#ifndef __read_mostly
+# define __read_mostly
+#endif
+
+#ifndef ____cacheline_aligned
+#define ____cacheline_aligned
+#endif
+
+int  cfs_cpu_init(void);
+void cfs_cpu_fini(void);
+
+#endif /* __LIBCFS_CPU_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_crypto.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,201 @@
+/* GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see http://www.gnu.org/licenses
+ *
+ * Please  visit http://www.xyratex.com/contact if you need additional
+ * information or have any questions.
+ *
+ * GPL HEADER END
+ */
+
+/*
+ * Copyright 2012 Xyratex Technology Limited
+ */
+
+#ifndef _LIBCFS_CRYPTO_H
+#define _LIBCFS_CRYPTO_H
+
+struct cfs_crypto_hash_type {
+	char		*cht_name;      /**< hash algorithm name, equal to
+					 * format name for crypto api */
+	unsigned int    cht_key;	/**< init key by default (vaild for
+					 * 4 bytes context like crc32, adler */
+	unsigned int    cht_size;       /**< hash digest size */
+};
+
+enum cfs_crypto_hash_alg {
+	CFS_HASH_ALG_NULL       = 0,
+	CFS_HASH_ALG_ADLER32,
+	CFS_HASH_ALG_CRC32,
+	CFS_HASH_ALG_MD5,
+	CFS_HASH_ALG_SHA1,
+	CFS_HASH_ALG_SHA256,
+	CFS_HASH_ALG_SHA384,
+	CFS_HASH_ALG_SHA512,
+	CFS_HASH_ALG_CRC32C,
+	CFS_HASH_ALG_MAX
+};
+
+static struct cfs_crypto_hash_type hash_types[] = {
+	[CFS_HASH_ALG_NULL]    = { "null",     0,      0 },
+	[CFS_HASH_ALG_ADLER32] = { "adler32",  1,      4 },
+	[CFS_HASH_ALG_CRC32]   = { "crc32",   ~0,      4 },
+	[CFS_HASH_ALG_CRC32C]  = { "crc32c",  ~0,      4 },
+	[CFS_HASH_ALG_MD5]     = { "md5",      0,     16 },
+	[CFS_HASH_ALG_SHA1]    = { "sha1",     0,     20 },
+	[CFS_HASH_ALG_SHA256]  = { "sha256",   0,     32 },
+	[CFS_HASH_ALG_SHA384]  = { "sha384",   0,     48 },
+	[CFS_HASH_ALG_SHA512]  = { "sha512",   0,     64 },
+};
+
+/**    Return pointer to type of hash for valid hash algorithm identifier */
+static inline const struct cfs_crypto_hash_type *
+		    cfs_crypto_hash_type(unsigned char hash_alg)
+{
+	struct cfs_crypto_hash_type *ht;
+
+	if (hash_alg < CFS_HASH_ALG_MAX) {
+		ht = &hash_types[hash_alg];
+		if (ht->cht_name)
+			return ht;
+	}
+	return NULL;
+}
+
+/**     Return hash name for valid hash algorithm identifier or "unknown" */
+static inline const char *cfs_crypto_hash_name(unsigned char hash_alg)
+{
+	const struct cfs_crypto_hash_type *ht;
+
+	ht = cfs_crypto_hash_type(hash_alg);
+	if (ht)
+		return ht->cht_name;
+	else
+		return "unknown";
+}
+
+/**     Return digest size for valid algorithm identifier or 0 */
+static inline int cfs_crypto_hash_digestsize(unsigned char hash_alg)
+{
+	const struct cfs_crypto_hash_type *ht;
+
+	ht = cfs_crypto_hash_type(hash_alg);
+	if (ht)
+		return ht->cht_size;
+	else
+		return 0;
+}
+
+/**     Return hash identifier for valid hash algorithm name or 0xFF */
+static inline unsigned char cfs_crypto_hash_alg(const char *algname)
+{
+	unsigned char   i;
+
+	for (i = 0; i < CFS_HASH_ALG_MAX; i++)
+		if (!strcmp(hash_types[i].cht_name, algname))
+			break;
+	return (i == CFS_HASH_ALG_MAX ? 0xFF : i);
+}
+
+/**     Calculate hash digest for buffer.
+ *      @param alg	    id of hash algorithm
+ *      @param buf	    buffer of data
+ *      @param buf_len	buffer len
+ *      @param key	    initial value for algorithm, if it is NULL,
+ *			    default initial value should be used.
+ *      @param key_len	len of initial value
+ *      @param hash	   [out] pointer to hash, if it is NULL, hash_len is
+ *			    set to valid digest size in bytes, retval -ENOSPC.
+ *      @param hash_len       [in,out] size of hash buffer
+ *      @returns	      status of operation
+ *      @retval -EINVAL       if buf, buf_len, hash_len or alg_id is invalid
+ *      @retval -ENODEV       if this algorithm is unsupported
+ *      @retval -ENOSPC       if pointer to hash is NULL, or hash_len less than
+ *			    digest size
+ *      @retval 0	     for success
+ *      @retval < 0	   other errors from lower layers.
+ */
+int cfs_crypto_hash_digest(unsigned char alg,
+			   const void *buf, unsigned int buf_len,
+			   unsigned char *key, unsigned int key_len,
+			   unsigned char *hash, unsigned int *hash_len);
+
+/* cfs crypto hash descriptor */
+struct cfs_crypto_hash_desc;
+
+/**     Allocate and initialize desriptor for hash algorithm.
+ *      @param alg	    algorithm id
+ *      @param key	    initial value for algorithm, if it is NULL,
+ *			    default initial value should be used.
+ *      @param key_len	len of initial value
+ *      @returns	      pointer to descriptor of hash instance
+ *      @retval ERR_PTR(error) when errors occured.
+ */
+struct cfs_crypto_hash_desc*
+	cfs_crypto_hash_init(unsigned char alg,
+			     unsigned char *key, unsigned int key_len);
+
+/**    Update digest by part of data.
+ *     @param desc	      hash descriptor
+ *     @param page	      data page
+ *     @param offset	    data offset
+ *     @param len	       data len
+ *     @returns		 status of operation
+ *     @retval 0		for success.
+ */
+int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *desc,
+				struct page *page, unsigned int offset,
+				unsigned int len);
+
+/**    Update digest by part of data.
+ *     @param desc	      hash descriptor
+ *     @param buf	       pointer to data buffer
+ *     @param buf_len	   size of data at buffer
+ *     @returns		 status of operation
+ *     @retval 0		for success.
+ */
+int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *desc, const void *buf,
+			   unsigned int buf_len);
+
+/**    Finalize hash calculation, copy hash digest to buffer, destroy hash
+ *     descriptor.
+ *     @param desc	      hash descriptor
+ *     @param hash	      buffer pointer to store hash digest
+ *     @param hash_len	  pointer to hash buffer size, if NULL
+ *			      destory hash descriptor
+ *     @returns		 status of operation
+ *     @retval -ENOSPC	  if hash is NULL, or *hash_len less than
+ *			      digest size
+ *     @retval 0		for success
+ *     @retval < 0	      other errors from lower layers.
+ */
+int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *desc,
+			  unsigned char *hash, unsigned int *hash_len);
+/**
+ *      Register crypto hash algorithms
+ */
+int cfs_crypto_register(void);
+
+/**
+ *      Unregister
+ */
+void cfs_crypto_unregister(void);
+
+/**     Return hash speed in Mbytes per second for valid hash algorithm
+ *      identifier. If test was unsuccessfull -1 would be return.
+ */
+int cfs_crypto_hash_speed(unsigned char hash_alg);
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,350 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_debug.h
+ *
+ * Debug messages and assertions
+ *
+ */
+
+#ifndef __LIBCFS_DEBUG_H__
+#define __LIBCFS_DEBUG_H__
+
+/*
+ *  Debugging
+ */
+extern unsigned int libcfs_subsystem_debug;
+extern unsigned int libcfs_stack;
+extern unsigned int libcfs_debug;
+extern unsigned int libcfs_printk;
+extern unsigned int libcfs_console_ratelimit;
+extern unsigned int libcfs_watchdog_ratelimit;
+extern unsigned int libcfs_console_max_delay;
+extern unsigned int libcfs_console_min_delay;
+extern unsigned int libcfs_console_backoff;
+extern unsigned int libcfs_debug_binary;
+extern char libcfs_debug_file_path_arr[PATH_MAX];
+
+int libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys);
+int libcfs_debug_str2mask(int *mask, const char *str, int is_subsys);
+
+/* Has there been an LBUG? */
+extern unsigned int libcfs_catastrophe;
+extern unsigned int libcfs_panic_on_lbug;
+
+/**
+ * Format for debug message headers
+ */
+struct ptldebug_header {
+	__u32 ph_len;
+	__u32 ph_flags;
+	__u32 ph_subsys;
+	__u32 ph_mask;
+	__u16 ph_cpu_id;
+	__u16 ph_type;
+	__u32 ph_sec;
+	__u64 ph_usec;
+	__u32 ph_stack;
+	__u32 ph_pid;
+	__u32 ph_extern_pid;
+	__u32 ph_line_num;
+} __attribute__((packed));
+
+
+#define PH_FLAG_FIRST_RECORD 1
+
+/* Debugging subsystems (32 bits, non-overlapping) */
+/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */
+#define S_UNDEFINED   0x00000001
+#define S_MDC	 0x00000002
+#define S_MDS	 0x00000004
+#define S_OSC	 0x00000008
+#define S_OST	 0x00000010
+#define S_CLASS       0x00000020
+#define S_LOG	 0x00000040
+#define S_LLITE       0x00000080
+#define S_RPC	 0x00000100
+#define S_MGMT	0x00000200
+#define S_LNET	0x00000400
+#define S_LND	 0x00000800 /* ALL LNDs */
+#define S_PINGER      0x00001000
+#define S_FILTER      0x00002000
+/* unused */
+#define S_ECHO	0x00008000
+#define S_LDLM	0x00010000
+#define S_LOV	 0x00020000
+#define S_LQUOTA      0x00040000
+#define S_OSD		0x00080000
+/* unused */
+/* unused */
+/* unused */
+#define S_LMV	 0x00800000 /* b_new_cmd */
+/* unused */
+#define S_SEC	 0x02000000 /* upcall cache */
+#define S_GSS	 0x04000000 /* b_new_cmd */
+/* unused */
+#define S_MGC	 0x10000000
+#define S_MGS	 0x20000000
+#define S_FID	 0x40000000 /* b_new_cmd */
+#define S_FLD	 0x80000000 /* b_new_cmd */
+/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */
+
+/* Debugging masks (32 bits, non-overlapping) */
+/* keep these in sync with lnet/utils/debug.c and lnet/libcfs/debug.c */
+#define D_TRACE       0x00000001 /* ENTRY/EXIT markers */
+#define D_INODE       0x00000002
+#define D_SUPER       0x00000004
+#define D_EXT2	0x00000008 /* anything from ext2_debug */
+#define D_MALLOC      0x00000010 /* print malloc, free information */
+#define D_CACHE       0x00000020 /* cache-related items */
+#define D_INFO	0x00000040 /* general information */
+#define D_IOCTL       0x00000080 /* ioctl related information */
+#define D_NETERROR    0x00000100 /* network errors */
+#define D_NET	 0x00000200 /* network communications */
+#define D_WARNING     0x00000400 /* CWARN(...) == CDEBUG (D_WARNING, ...) */
+#define D_BUFFS       0x00000800
+#define D_OTHER       0x00001000
+#define D_DENTRY      0x00002000
+#define D_NETTRACE    0x00004000
+#define D_PAGE	0x00008000 /* bulk page handling */
+#define D_DLMTRACE    0x00010000
+#define D_ERROR       0x00020000 /* CERROR(...) == CDEBUG (D_ERROR, ...) */
+#define D_EMERG       0x00040000 /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
+#define D_HA	  0x00080000 /* recovery and failover */
+#define D_RPCTRACE    0x00100000 /* for distributed debugging */
+#define D_VFSTRACE    0x00200000
+#define D_READA       0x00400000 /* read-ahead */
+#define D_MMAP	0x00800000
+#define D_CONFIG      0x01000000
+#define D_CONSOLE     0x02000000
+#define D_QUOTA       0x04000000
+#define D_SEC	 0x08000000
+#define D_LFSCK	      0x10000000 /* For both OI scrub and LFSCK */
+/* keep these in sync with lnet/{utils,libcfs}/debug.c */
+
+#define D_HSM	 D_TRACE
+
+#define D_CANTMASK   (D_ERROR | D_EMERG | D_WARNING | D_CONSOLE)
+
+#ifndef DEBUG_SUBSYSTEM
+# define DEBUG_SUBSYSTEM S_UNDEFINED
+#endif
+
+#define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600))	 /* jiffies */
+#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */
+#define CDEBUG_DEFAULT_BACKOFF   2
+typedef struct {
+	cfs_time_t      cdls_next;
+	unsigned int    cdls_delay;
+	int	     cdls_count;
+} cfs_debug_limit_state_t;
+
+struct libcfs_debug_msg_data {
+	const char	       *msg_file;
+	const char	       *msg_fn;
+	int		      msg_subsys;
+	int		      msg_line;
+	int		      msg_mask;
+	cfs_debug_limit_state_t  *msg_cdls;
+};
+
+#define LIBCFS_DEBUG_MSG_DATA_INIT(data, mask, cdls)	\
+do {							\
+	(data)->msg_subsys = DEBUG_SUBSYSTEM;	       \
+	(data)->msg_file   = __FILE__;		      \
+	(data)->msg_fn     = __FUNCTION__;		  \
+	(data)->msg_line   = __LINE__;		      \
+	(data)->msg_cdls   = (cdls);			\
+	(data)->msg_mask   = (mask);			\
+} while (0)
+
+#define LIBCFS_DEBUG_MSG_DATA_DECL(dataname, mask, cdls)    \
+	static struct libcfs_debug_msg_data dataname = {    \
+	       .msg_subsys = DEBUG_SUBSYSTEM,	       \
+	       .msg_file   = __FILE__,		      \
+	       .msg_fn     = __FUNCTION__,		  \
+	       .msg_line   = __LINE__,		      \
+	       .msg_cdls   = (cdls)	 };	      \
+	dataname.msg_mask   = (mask);
+
+
+
+/**
+ * Filters out logging messages based on mask and subsystem.
+ */
+static inline int cfs_cdebug_show(unsigned int mask, unsigned int subsystem)
+{
+	return mask & D_CANTMASK ||
+		((libcfs_debug & mask) && (libcfs_subsystem_debug & subsystem));
+}
+
+#define __CDEBUG(cdls, mask, format, ...)			       \
+do {								    \
+	static struct libcfs_debug_msg_data msgdata;		    \
+									\
+	CFS_CHECK_STACK(&msgdata, mask, cdls);			  \
+									\
+	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {		   \
+		LIBCFS_DEBUG_MSG_DATA_INIT(&msgdata, mask, cdls);       \
+		libcfs_debug_msg(&msgdata, format, ## __VA_ARGS__);     \
+	}							       \
+} while (0)
+
+#define CDEBUG(mask, format, ...) __CDEBUG(NULL, mask, format, ## __VA_ARGS__)
+
+#define CDEBUG_LIMIT(mask, format, ...)	 \
+do {					    \
+	static cfs_debug_limit_state_t cdls;    \
+						\
+	__CDEBUG(&cdls, mask, format, ## __VA_ARGS__);\
+} while (0)
+
+
+
+
+#define CWARN(format, ...)	  CDEBUG_LIMIT(D_WARNING, format, ## __VA_ARGS__)
+#define CERROR(format, ...)	 CDEBUG_LIMIT(D_ERROR, format, ## __VA_ARGS__)
+#define CNETERR(format, a...)       CDEBUG_LIMIT(D_NETERROR, format, ## a)
+#define CEMERG(format, ...)	 CDEBUG_LIMIT(D_EMERG, format, ## __VA_ARGS__)
+
+#define LCONSOLE(mask, format, ...) CDEBUG(D_CONSOLE | (mask), format, ## __VA_ARGS__)
+#define LCONSOLE_INFO(format, ...)  CDEBUG_LIMIT(D_CONSOLE, format, ## __VA_ARGS__)
+#define LCONSOLE_WARN(format, ...)  CDEBUG_LIMIT(D_CONSOLE | D_WARNING, format, ## __VA_ARGS__)
+#define LCONSOLE_ERROR_MSG(errnum, format, ...) CDEBUG_LIMIT(D_CONSOLE | D_ERROR, \
+			   "%x-%x: " format, errnum, LERRCHKSUM(errnum), ## __VA_ARGS__)
+#define LCONSOLE_ERROR(format, ...) LCONSOLE_ERROR_MSG(0x00, format, ## __VA_ARGS__)
+
+#define LCONSOLE_EMERG(format, ...) CDEBUG(D_CONSOLE | D_EMERG, format, ## __VA_ARGS__)
+
+
+void libcfs_log_goto(struct libcfs_debug_msg_data *, const char *, long_ptr_t);
+#define GOTO(label, rc)						 \
+do {								    \
+	if (cfs_cdebug_show(D_TRACE, DEBUG_SUBSYSTEM)) {		\
+		LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_TRACE, NULL);     \
+		libcfs_log_goto(&msgdata, #label, (long_ptr_t)(rc));    \
+	} else {							\
+		(void)(rc);					     \
+	}							       \
+	goto label;						     \
+} while (0)
+
+
+/*
+ * if rc == NULL, we need to code as RETURN((void *)NULL), otherwise
+ * there will be a warning in osx.
+ */
+#if defined(__GNUC__)
+
+long libcfs_log_return(struct libcfs_debug_msg_data *, long rc);
+#if BITS_PER_LONG > 32
+#define RETURN(rc)							\
+do {									\
+	EXIT_NESTING;							\
+	if (cfs_cdebug_show(D_TRACE, DEBUG_SUBSYSTEM)) {		\
+		LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_TRACE, NULL);	\
+		return (typeof(rc))libcfs_log_return(&msgdata,		\
+						     (long)(rc));	\
+	}								\
+									\
+	return (rc);							\
+} while (0)
+#else /* BITS_PER_LONG == 32 */
+/* We need an on-stack variable, because we cannot case a 32-bit pointer
+ * directly to (long long) without generating a complier warning/error, yet
+ * casting directly to (long) will truncate 64-bit return values. The log
+ * values will print as 32-bit values, but they always have been. LU-1436
+ */
+#define RETURN(rc)							\
+do {									\
+	EXIT_NESTING;							\
+	if (cfs_cdebug_show(D_TRACE, DEBUG_SUBSYSTEM)) {		\
+		typeof(rc) __rc = (rc);					\
+		LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_TRACE, NULL);	\
+		libcfs_log_return(&msgdata, (long_ptr_t)__rc);		\
+		return __rc;						\
+	}								\
+									\
+	return (rc);							\
+} while (0)
+#endif /* BITS_PER_LONG > 32 */
+
+#elif defined(_MSC_VER)
+#define RETURN(rc)						      \
+do {								    \
+	CDEBUG(D_TRACE, "Process leaving.\n");			  \
+	EXIT_NESTING;						   \
+	return (rc);						    \
+} while (0)
+#else
+# error "Unkown compiler"
+#endif /* __GNUC__ */
+
+#define ENTRY							   \
+ENTRY_NESTING;							  \
+do {								    \
+	CDEBUG(D_TRACE, "Process entered\n");			   \
+} while (0)
+
+#define EXIT							    \
+do {								    \
+	CDEBUG(D_TRACE, "Process leaving\n");			   \
+	EXIT_NESTING;						   \
+} while(0)
+
+#define RETURN_EXIT							\
+do {									\
+	EXIT;								\
+	return;								\
+} while (0)
+
+extern int libcfs_debug_msg(struct libcfs_debug_msg_data *msgdata,
+			    const char *format1, ...)
+	__attribute__ ((format (printf, 2, 3)));
+
+extern int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
+			      const char *format1,
+			      va_list args, const char *format2, ...)
+	__attribute__ ((format (printf, 4, 5)));
+
+/* other external symbols that tracefile provides: */
+extern int cfs_trace_copyin_string(char *knl_buffer, int knl_buffer_nob,
+				   const char *usr_buffer, int usr_buffer_nob);
+extern int cfs_trace_copyout_string(char *usr_buffer, int usr_buffer_nob,
+				    const char *knl_buffer, char *append);
+
+#define LIBCFS_DEBUG_FILE_PATH_DEFAULT "/tmp/lustre-log"
+
+#endif	/* __LIBCFS_DEBUG_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_fail.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,170 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see http://www.gnu.org/licenses
+ *
+ * Please contact Oracle Corporation, Inc., 500 Oracle Parkway, Redwood Shores,
+ * CA 94065 USA or visit www.oracle.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Oracle Corporation, Inc.
+ */
+
+#ifndef _LIBCFS_FAIL_H
+#define _LIBCFS_FAIL_H
+
+extern unsigned long cfs_fail_loc;
+extern unsigned int cfs_fail_val;
+
+extern wait_queue_head_t cfs_race_waitq;
+extern int cfs_race_state;
+
+int __cfs_fail_check_set(__u32 id, __u32 value, int set);
+int __cfs_fail_timeout_set(__u32 id, __u32 value, int ms, int set);
+
+enum {
+	CFS_FAIL_LOC_NOSET      = 0,
+	CFS_FAIL_LOC_ORSET      = 1,
+	CFS_FAIL_LOC_RESET      = 2,
+	CFS_FAIL_LOC_VALUE      = 3
+};
+
+/* Failure injection control */
+#define CFS_FAIL_MASK_SYS    0x0000FF00
+#define CFS_FAIL_MASK_LOC   (0x000000FF | CFS_FAIL_MASK_SYS)
+
+#define CFS_FAILED_BIT       30
+/* CFS_FAILED is 0x40000000 */
+#define CFS_FAILED	  (1 << CFS_FAILED_BIT)
+
+#define CFS_FAIL_ONCE_BIT    31
+/* CFS_FAIL_ONCE is 0x80000000 */
+#define CFS_FAIL_ONCE       (1 << CFS_FAIL_ONCE_BIT)
+
+/* The following flags aren't made to be combined */
+#define CFS_FAIL_SKIP	0x20000000 /* skip N times then fail */
+#define CFS_FAIL_SOME	0x10000000 /* only fail N times */
+#define CFS_FAIL_RAND	0x08000000 /* fail 1/N of the times */
+#define CFS_FAIL_USR1	0x04000000 /* user flag */
+
+#define CFS_FAIL_PRECHECK(id) (cfs_fail_loc &&				\
+			      (cfs_fail_loc & CFS_FAIL_MASK_LOC) ==	   \
+			      ((id) & CFS_FAIL_MASK_LOC))
+
+static inline int cfs_fail_check_set(__u32 id, __u32 value,
+				     int set, int quiet)
+{
+	int ret = 0;
+
+	if (unlikely(CFS_FAIL_PRECHECK(id) &&
+		     (ret = __cfs_fail_check_set(id, value, set)))) {
+		if (quiet) {
+			CDEBUG(D_INFO, "*** cfs_fail_loc=%x, val=%u***\n",
+			       id, value);
+		} else {
+			LCONSOLE_INFO("*** cfs_fail_loc=%x, val=%u***\n",
+				      id, value);
+		}
+	}
+
+	return ret;
+}
+
+/* If id hit cfs_fail_loc, return 1, otherwise return 0 */
+#define CFS_FAIL_CHECK(id) \
+	cfs_fail_check_set(id, 0, CFS_FAIL_LOC_NOSET, 0)
+#define CFS_FAIL_CHECK_QUIET(id) \
+	cfs_fail_check_set(id, 0, CFS_FAIL_LOC_NOSET, 1)
+
+/* If id hit cfs_fail_loc and cfs_fail_val == (-1 or value) return 1,
+ * otherwise return 0 */
+#define CFS_FAIL_CHECK_VALUE(id, value) \
+	cfs_fail_check_set(id, value, CFS_FAIL_LOC_VALUE, 0)
+#define CFS_FAIL_CHECK_VALUE_QUIET(id, value) \
+	cfs_fail_check_set(id, value, CFS_FAIL_LOC_VALUE, 1)
+
+/* If id hit cfs_fail_loc, cfs_fail_loc |= value and return 1,
+ * otherwise return 0 */
+#define CFS_FAIL_CHECK_ORSET(id, value) \
+	cfs_fail_check_set(id, value, CFS_FAIL_LOC_ORSET, 0)
+#define CFS_FAIL_CHECK_ORSET_QUIET(id, value) \
+	cfs_fail_check_set(id, value, CFS_FAIL_LOC_ORSET, 1)
+
+/* If id hit cfs_fail_loc, cfs_fail_loc = value and return 1,
+ * otherwise return 0 */
+#define CFS_FAIL_CHECK_RESET(id, value) \
+	cfs_fail_check_set(id, value, CFS_FAIL_LOC_RESET, 0)
+#define CFS_FAIL_CHECK_RESET_QUIET(id, value) \
+	cfs_fail_check_set(id, value, CFS_FAIL_LOC_RESET, 1)
+
+static inline int cfs_fail_timeout_set(__u32 id, __u32 value, int ms, int set)
+{
+	if (unlikely(CFS_FAIL_PRECHECK(id)))
+		return __cfs_fail_timeout_set(id, value, ms, set);
+	else
+		return 0;
+}
+
+/* If id hit cfs_fail_loc, sleep for seconds or milliseconds */
+#define CFS_FAIL_TIMEOUT(id, secs) \
+	cfs_fail_timeout_set(id, 0, secs * 1000, CFS_FAIL_LOC_NOSET)
+
+#define CFS_FAIL_TIMEOUT_MS(id, ms) \
+	cfs_fail_timeout_set(id, 0, ms, CFS_FAIL_LOC_NOSET)
+
+/* If id hit cfs_fail_loc, cfs_fail_loc |= value and
+ * sleep seconds or milliseconds */
+#define CFS_FAIL_TIMEOUT_ORSET(id, value, secs) \
+	cfs_fail_timeout_set(id, value, secs * 1000, CFS_FAIL_LOC_ORSET)
+
+#define CFS_FAIL_TIMEOUT_MS_ORSET(id, value, ms) \
+	cfs_fail_timeout_set(id, value, ms, CFS_FAIL_LOC_ORSET)
+
+/* The idea here is to synchronise two threads to force a race. The
+ * first thread that calls this with a matching fail_loc is put to
+ * sleep. The next thread that calls with the same fail_loc wakes up
+ * the first and continues. */
+static inline void cfs_race(__u32 id)
+{
+
+	if (CFS_FAIL_PRECHECK(id)) {
+		if (unlikely(__cfs_fail_check_set(id, 0, CFS_FAIL_LOC_NOSET))) {
+			int rc;
+			cfs_race_state = 0;
+			CERROR("cfs_race id %x sleeping\n", id);
+			cfs_wait_event_interruptible(cfs_race_waitq,
+						     cfs_race_state != 0, rc);
+			CERROR("cfs_fail_race id %x awake, rc=%d\n", id, rc);
+		} else {
+			CERROR("cfs_fail_race id %x waking\n", id);
+			cfs_race_state = 1;
+			wake_up(&cfs_race_waitq);
+		}
+	}
+}
+#define CFS_RACE(id) cfs_race(id)
+
+#endif /* _LIBCFS_FAIL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,234 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LIBCFS_LIBCFS_H__
+#define __LIBCFS_LIBCFS_H__
+
+#if !__GNUC__
+#define __attribute__(x)
+#endif
+
+#include <linux/libcfs/linux/libcfs.h>
+
+#include "curproc.h"
+
+#ifndef offsetof
+# define offsetof(typ,memb) ((long)(long_ptr_t)((char *)&(((typ *)0)->memb)))
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) ((sizeof (a)) / (sizeof ((a)[0])))
+#endif
+
+#if !defined(swap)
+#define swap(x,y) do { typeof(x) z = x; x = y; y = z; } while (0)
+#endif
+
+#if !defined(container_of)
+/* given a pointer @ptr to the field @member embedded into type (usually
+ * struct) @type, return pointer to the embedding instance of @type. */
+#define container_of(ptr, type, member) \
+	((type *)((char *)(ptr)-(char *)(&((type *)0)->member)))
+#endif
+
+static inline int __is_po2(unsigned long long val)
+{
+	return !(val & (val - 1));
+}
+
+#define IS_PO2(val) __is_po2((unsigned long long)(val))
+
+#define LOWEST_BIT_SET(x)       ((x) & ~((x) - 1))
+
+/*
+ * Lustre Error Checksum: calculates checksum
+ * of Hex number by XORing each bit.
+ */
+#define LERRCHKSUM(hexnum) (((hexnum) & 0xf) ^ ((hexnum) >> 4 & 0xf) ^ \
+			   ((hexnum) >> 8 & 0xf))
+
+
+/*
+ * Some (nomina odiosa sunt) platforms define NULL as naked 0. This confuses
+ * Lustre RETURN(NULL) macro.
+ */
+#if defined(NULL)
+#undef NULL
+#endif
+
+#define NULL ((void *)0)
+
+#define LUSTRE_SRV_LNET_PID      LUSTRE_LNET_PID
+
+
+#include <linux/list.h>
+
+#ifndef cfs_for_each_possible_cpu
+#  error cfs_for_each_possible_cpu is not supported by kernel!
+#endif
+
+/* libcfs tcpip */
+int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask);
+int libcfs_ipif_enumerate(char ***names);
+void libcfs_ipif_free_enumeration(char **names, int n);
+int libcfs_sock_listen(socket_t **sockp, __u32 ip, int port, int backlog);
+int libcfs_sock_accept(socket_t **newsockp, socket_t *sock);
+void libcfs_sock_abort_accept(socket_t *sock);
+int libcfs_sock_connect(socket_t **sockp, int *fatal,
+			__u32 local_ip, int local_port,
+			__u32 peer_ip, int peer_port);
+int libcfs_sock_setbuf(socket_t *socket, int txbufsize, int rxbufsize);
+int libcfs_sock_getbuf(socket_t *socket, int *txbufsize, int *rxbufsize);
+int libcfs_sock_getaddr(socket_t *socket, int remote, __u32 *ip, int *port);
+int libcfs_sock_write(socket_t *sock, void *buffer, int nob, int timeout);
+int libcfs_sock_read(socket_t *sock, void *buffer, int nob, int timeout);
+void libcfs_sock_release(socket_t *sock);
+
+/* libcfs watchdogs */
+struct lc_watchdog;
+
+/* Add a watchdog which fires after "time" milliseconds of delay.  You have to
+ * touch it once to enable it. */
+struct lc_watchdog *lc_watchdog_add(int time,
+				    void (*cb)(pid_t pid, void *),
+				    void *data);
+
+/* Enables a watchdog and resets its timer. */
+void lc_watchdog_touch(struct lc_watchdog *lcw, int timeout);
+#define CFS_GET_TIMEOUT(svc) (max_t(int, obd_timeout,		   \
+			  AT_OFF ? 0 : at_get(&svc->srv_at_estimate)) * \
+			  svc->srv_watchdog_factor)
+
+/* Disable a watchdog; touch it to restart it. */
+void lc_watchdog_disable(struct lc_watchdog *lcw);
+
+/* Clean up the watchdog */
+void lc_watchdog_delete(struct lc_watchdog *lcw);
+
+/* Dump a debug log */
+void lc_watchdog_dumplog(pid_t pid, void *data);
+
+
+/* need both kernel and user-land acceptor */
+#define LNET_ACCEPTOR_MIN_RESERVED_PORT    512
+#define LNET_ACCEPTOR_MAX_RESERVED_PORT    1023
+
+/*
+ * libcfs pseudo device operations
+ *
+ * struct psdev_t and
+ * misc_register() and
+ * misc_deregister() are declared in
+ * libcfs/<os>/<os>-prim.h
+ *
+ * It's just draft now.
+ */
+
+struct cfs_psdev_file {
+	unsigned long   off;
+	void	    *private_data;
+	unsigned long   reserved1;
+	unsigned long   reserved2;
+};
+
+struct cfs_psdev_ops {
+	int (*p_open)(unsigned long, void *);
+	int (*p_close)(unsigned long, void *);
+	int (*p_read)(struct cfs_psdev_file *, char *, unsigned long);
+	int (*p_write)(struct cfs_psdev_file *, char *, unsigned long);
+	int (*p_ioctl)(struct cfs_psdev_file *, unsigned long, void *);
+};
+
+/*
+ * Drop into debugger, if possible. Implementation is provided by platform.
+ */
+
+void cfs_enter_debugger(void);
+
+/*
+ * Defined by platform
+ */
+int unshare_fs_struct(void);
+sigset_t cfs_get_blocked_sigs(void);
+sigset_t cfs_block_allsigs(void);
+sigset_t cfs_block_sigs(unsigned long sigs);
+sigset_t cfs_block_sigsinv(unsigned long sigs);
+void cfs_restore_sigs(sigset_t);
+int cfs_signal_pending(void);
+void cfs_clear_sigpending(void);
+
+/*
+ * Random number handling
+ */
+
+/* returns a random 32-bit integer */
+unsigned int cfs_rand(void);
+/* seed the generator */
+void cfs_srand(unsigned int, unsigned int);
+void cfs_get_random_bytes(void *buf, int size);
+
+#include <linux/libcfs/libcfs_debug.h>
+#include <linux/libcfs/libcfs_cpu.h>
+#include <linux/libcfs/libcfs_private.h>
+#include <linux/libcfs/libcfs_ioctl.h>
+#include <linux/libcfs/libcfs_prim.h>
+#include <linux/libcfs/libcfs_time.h>
+#include <linux/libcfs/libcfs_string.h>
+#include <linux/libcfs/libcfs_kernelcomm.h>
+#include <linux/libcfs/libcfs_workitem.h>
+#include <linux/libcfs/libcfs_hash.h>
+#include <linux/libcfs/libcfs_heap.h>
+#include <linux/libcfs/libcfs_fail.h>
+#include <linux/libcfs/params_tree.h>
+#include <linux/libcfs/libcfs_crypto.h>
+
+/* container_of depends on "likely" which is defined in libcfs_private.h */
+static inline void *__container_of(void *ptr, unsigned long shift)
+{
+	if (unlikely(IS_ERR(ptr) || ptr == NULL))
+		return ptr;
+	else
+		return (char *)ptr - shift;
+}
+
+#define container_of0(ptr, type, member) \
+	((type *)__container_of((void *)(ptr), offsetof(type, member)))
+
+#define SET_BUT_UNUSED(a) do { } while(sizeof(a) - sizeof(a))
+
+#define _LIBCFS_H
+
+#endif /* _LIBCFS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,851 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_hash.h
+ *
+ * Hashing routines
+ *
+ */
+
+#ifndef __LIBCFS_HASH_H__
+#define __LIBCFS_HASH_H__
+/*
+ * Knuth recommends primes in approximately golden ratio to the maximum
+ * integer representable by a machine word for multiplicative hashing.
+ * Chuck Lever verified the effectiveness of this technique:
+ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
+ *
+ * These primes are chosen to be bit-sparse, that is operations on
+ * them can use shifts and additions instead of multiplications for
+ * machines where multiplications are slow.
+ */
+/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
+#define CFS_GOLDEN_RATIO_PRIME_32 0x9e370001UL
+/*  2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
+#define CFS_GOLDEN_RATIO_PRIME_64 0x9e37fffffffc0001ULL
+
+/*
+ * Ideally we would use HAVE_HASH_LONG for this, but on linux we configure
+ * the linux kernel and user space at the same time, so we need to differentiate
+ * between them explicitely. If this is not needed on other architectures, then
+ * we'll need to move the functions to archi specific headers.
+ */
+
+#include <linux/hash.h>
+
+#define cfs_hash_long(val, bits)    hash_long(val, bits)
+
+/** disable debug */
+#define CFS_HASH_DEBUG_NONE	 0
+/** record hash depth and output to console when it's too deep,
+ *  computing overhead is low but consume more memory */
+#define CFS_HASH_DEBUG_1	    1
+/** expensive, check key validation */
+#define CFS_HASH_DEBUG_2	    2
+
+#define CFS_HASH_DEBUG_LEVEL	CFS_HASH_DEBUG_NONE
+
+struct cfs_hash_ops;
+struct cfs_hash_lock_ops;
+struct cfs_hash_hlist_ops;
+
+typedef union {
+	rwlock_t		rw;		/**< rwlock */
+	spinlock_t		spin;		/**< spinlock */
+} cfs_hash_lock_t;
+
+/**
+ * cfs_hash_bucket is a container of:
+ * - lock, couter ...
+ * - array of hash-head starting from hsb_head[0], hash-head can be one of
+ *   . cfs_hash_head_t
+ *   . cfs_hash_head_dep_t
+ *   . cfs_hash_dhead_t
+ *   . cfs_hash_dhead_dep_t
+ *   which depends on requirement of user
+ * - some extra bytes (caller can require it while creating hash)
+ */
+typedef struct cfs_hash_bucket {
+	cfs_hash_lock_t		hsb_lock;	/**< bucket lock */
+	__u32			hsb_count;	/**< current entries */
+	__u32			hsb_version;	/**< change version */
+	unsigned int		hsb_index;	/**< index of bucket */
+	int			hsb_depmax;	/**< max depth on bucket */
+	long			hsb_head[0];	/**< hash-head array */
+} cfs_hash_bucket_t;
+
+/**
+ * cfs_hash bucket descriptor, it's normally in stack of caller
+ */
+typedef struct cfs_hash_bd {
+	cfs_hash_bucket_t	  *bd_bucket;      /**< address of bucket */
+	unsigned int		bd_offset;      /**< offset in bucket */
+} cfs_hash_bd_t;
+
+#define CFS_HASH_NAME_LEN	   16      /**< default name length */
+#define CFS_HASH_BIGNAME_LEN	64      /**< bigname for param tree */
+
+#define CFS_HASH_BKT_BITS	   3       /**< default bits of bucket */
+#define CFS_HASH_BITS_MAX	   30      /**< max bits of bucket */
+#define CFS_HASH_BITS_MIN	   CFS_HASH_BKT_BITS
+
+/**
+ * common hash attributes.
+ */
+enum cfs_hash_tag {
+	/**
+	 * don't need any lock, caller will protect operations with it's
+	 * own lock. With this flag:
+	 *  . CFS_HASH_NO_BKTLOCK, CFS_HASH_RW_BKTLOCK, CFS_HASH_SPIN_BKTLOCK
+	 *    will be ignored.
+	 *  . Some functions will be disabled with this flag, i.e:
+	 *    cfs_hash_for_each_empty, cfs_hash_rehash
+	 */
+	CFS_HASH_NO_LOCK	= 1 << 0,
+	/** no bucket lock, use one spinlock to protect the whole hash */
+	CFS_HASH_NO_BKTLOCK     = 1 << 1,
+	/** rwlock to protect bucket */
+	CFS_HASH_RW_BKTLOCK     = 1 << 2,
+	/** spinlcok to protect bucket */
+	CFS_HASH_SPIN_BKTLOCK   = 1 << 3,
+	/** always add new item to tail */
+	CFS_HASH_ADD_TAIL       = 1 << 4,
+	/** hash-table doesn't have refcount on item */
+	CFS_HASH_NO_ITEMREF     = 1 << 5,
+	/** big name for param-tree */
+	CFS_HASH_BIGNAME	= 1 << 6,
+	/** track global count */
+	CFS_HASH_COUNTER	= 1 << 7,
+	/** rehash item by new key */
+	CFS_HASH_REHASH_KEY     = 1 << 8,
+	/** Enable dynamic hash resizing */
+	CFS_HASH_REHASH	 = 1 << 9,
+	/** can shrink hash-size */
+	CFS_HASH_SHRINK	 = 1 << 10,
+	/** assert hash is empty on exit */
+	CFS_HASH_ASSERT_EMPTY   = 1 << 11,
+	/** record hlist depth */
+	CFS_HASH_DEPTH	  = 1 << 12,
+	/**
+	 * rehash is always scheduled in a different thread, so current
+	 * change on hash table is non-blocking
+	 */
+	CFS_HASH_NBLK_CHANGE    = 1 << 13,
+	/** NB, we typed hs_flags as  __u16, please change it
+	 * if you need to extend >=16 flags */
+};
+
+/** most used attributes */
+#define CFS_HASH_DEFAULT       (CFS_HASH_RW_BKTLOCK | \
+				CFS_HASH_COUNTER | CFS_HASH_REHASH)
+
+/**
+ * cfs_hash is a hash-table implementation for general purpose, it can support:
+ *    . two refcount modes
+ *      hash-table with & without refcount
+ *    . four lock modes
+ *      nolock, one-spinlock, rw-bucket-lock, spin-bucket-lock
+ *    . general operations
+ *      lookup, add(add_tail or add_head), delete
+ *    . rehash
+ *      grows or shrink
+ *    . iteration
+ *      locked iteration and unlocked iteration
+ *    . bigname
+ *      support long name hash
+ *    . debug
+ *      trace max searching depth
+ *
+ * Rehash:
+ * When the htable grows or shrinks, a separate task (cfs_hash_rehash_worker)
+ * is spawned to handle the rehash in the background, it's possible that other
+ * processes can concurrently perform additions, deletions, and lookups
+ * without being blocked on rehash completion, because rehash will release
+ * the global wrlock for each bucket.
+ *
+ * rehash and iteration can't run at the same time because it's too tricky
+ * to keep both of them safe and correct.
+ * As they are relatively rare operations, so:
+ *   . if iteration is in progress while we try to launch rehash, then
+ *     it just giveup, iterator will launch rehash at the end.
+ *   . if rehash is in progress while we try to iterate the hash table,
+ *     then we just wait (shouldn't be very long time), anyway, nobody
+ *     should expect iteration of whole hash-table to be non-blocking.
+ *
+ * During rehashing, a (key,object) pair may be in one of two buckets,
+ * depending on whether the worker task has yet to transfer the object
+ * to its new location in the table. Lookups and deletions need to search both
+ * locations; additions must take care to only insert into the new bucket.
+ */
+
+typedef struct cfs_hash {
+	/** serialize with rehash, or serialize all operations if
+	 * the hash-table has CFS_HASH_NO_BKTLOCK */
+	cfs_hash_lock_t	     hs_lock;
+	/** hash operations */
+	struct cfs_hash_ops	*hs_ops;
+	/** hash lock operations */
+	struct cfs_hash_lock_ops   *hs_lops;
+	/** hash list operations */
+	struct cfs_hash_hlist_ops  *hs_hops;
+	/** hash buckets-table */
+	cfs_hash_bucket_t	 **hs_buckets;
+	/** total number of items on this hash-table */
+	atomic_t		hs_count;
+	/** hash flags, see cfs_hash_tag for detail */
+	__u16		       hs_flags;
+	/** # of extra-bytes for bucket, for user saving extended attributes */
+	__u16		       hs_extra_bytes;
+	/** wants to iterate */
+	__u8			hs_iterating;
+	/** hash-table is dying */
+	__u8			hs_exiting;
+	/** current hash bits */
+	__u8			hs_cur_bits;
+	/** min hash bits */
+	__u8			hs_min_bits;
+	/** max hash bits */
+	__u8			hs_max_bits;
+	/** bits for rehash */
+	__u8			hs_rehash_bits;
+	/** bits for each bucket */
+	__u8			hs_bkt_bits;
+	/** resize min threshold */
+	__u16		       hs_min_theta;
+	/** resize max threshold */
+	__u16		       hs_max_theta;
+	/** resize count */
+	__u32		       hs_rehash_count;
+	/** # of iterators (caller of cfs_hash_for_each_*) */
+	__u32		       hs_iterators;
+	/** rehash workitem */
+	cfs_workitem_t	      hs_rehash_wi;
+	/** refcount on this hash table */
+	atomic_t		hs_refcount;
+	/** rehash buckets-table */
+	cfs_hash_bucket_t	 **hs_rehash_buckets;
+#if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1
+	/** serialize debug members */
+	spinlock_t			hs_dep_lock;
+	/** max depth */
+	unsigned int		hs_dep_max;
+	/** id of the deepest bucket */
+	unsigned int		hs_dep_bkt;
+	/** offset in the deepest bucket */
+	unsigned int		hs_dep_off;
+	/** bits when we found the max depth */
+	unsigned int		hs_dep_bits;
+	/** workitem to output max depth */
+	cfs_workitem_t	      hs_dep_wi;
+#endif
+	/** name of htable */
+	char			hs_name[0];
+} cfs_hash_t;
+
+typedef struct cfs_hash_lock_ops {
+	/** lock the hash table */
+	void    (*hs_lock)(cfs_hash_lock_t *lock, int exclusive);
+	/** unlock the hash table */
+	void    (*hs_unlock)(cfs_hash_lock_t *lock, int exclusive);
+	/** lock the hash bucket */
+	void    (*hs_bkt_lock)(cfs_hash_lock_t *lock, int exclusive);
+	/** unlock the hash bucket */
+	void    (*hs_bkt_unlock)(cfs_hash_lock_t *lock, int exclusive);
+} cfs_hash_lock_ops_t;
+
+typedef struct cfs_hash_hlist_ops {
+	/** return hlist_head of hash-head of @bd */
+	struct hlist_head *(*hop_hhead)(cfs_hash_t *hs, cfs_hash_bd_t *bd);
+	/** return hash-head size */
+	int (*hop_hhead_size)(cfs_hash_t *hs);
+	/** add @hnode to hash-head of @bd */
+	int (*hop_hnode_add)(cfs_hash_t *hs,
+			     cfs_hash_bd_t *bd, struct hlist_node *hnode);
+	/** remove @hnode from hash-head of @bd */
+	int (*hop_hnode_del)(cfs_hash_t *hs,
+			     cfs_hash_bd_t *bd, struct hlist_node *hnode);
+} cfs_hash_hlist_ops_t;
+
+typedef struct cfs_hash_ops {
+	/** return hashed value from @key */
+	unsigned (*hs_hash)(cfs_hash_t *hs, const void *key, unsigned mask);
+	/** return key address of @hnode */
+	void *   (*hs_key)(struct hlist_node *hnode);
+	/** copy key from @hnode to @key */
+	void     (*hs_keycpy)(struct hlist_node *hnode, void *key);
+	/**
+	 *  compare @key with key of @hnode
+	 *  returns 1 on a match
+	 */
+	int      (*hs_keycmp)(const void *key, struct hlist_node *hnode);
+	/** return object address of @hnode, i.e: container_of(...hnode) */
+	void *   (*hs_object)(struct hlist_node *hnode);
+	/** get refcount of item, always called with holding bucket-lock */
+	void     (*hs_get)(cfs_hash_t *hs, struct hlist_node *hnode);
+	/** release refcount of item */
+	void     (*hs_put)(cfs_hash_t *hs, struct hlist_node *hnode);
+	/** release refcount of item, always called with holding bucket-lock */
+	void     (*hs_put_locked)(cfs_hash_t *hs, struct hlist_node *hnode);
+	/** it's called before removing of @hnode */
+	void     (*hs_exit)(cfs_hash_t *hs, struct hlist_node *hnode);
+} cfs_hash_ops_t;
+
+/** total number of buckets in @hs */
+#define CFS_HASH_NBKT(hs)       \
+	(1U << ((hs)->hs_cur_bits - (hs)->hs_bkt_bits))
+
+/** total number of buckets in @hs while rehashing */
+#define CFS_HASH_RH_NBKT(hs)    \
+	(1U << ((hs)->hs_rehash_bits - (hs)->hs_bkt_bits))
+
+/** number of hlist for in bucket */
+#define CFS_HASH_BKT_NHLIST(hs) (1U << (hs)->hs_bkt_bits)
+
+/** total number of hlist in @hs */
+#define CFS_HASH_NHLIST(hs)     (1U << (hs)->hs_cur_bits)
+
+/** total number of hlist in @hs while rehashing */
+#define CFS_HASH_RH_NHLIST(hs)  (1U << (hs)->hs_rehash_bits)
+
+static inline int
+cfs_hash_with_no_lock(cfs_hash_t *hs)
+{
+	/* caller will serialize all operations for this hash-table */
+	return (hs->hs_flags & CFS_HASH_NO_LOCK) != 0;
+}
+
+static inline int
+cfs_hash_with_no_bktlock(cfs_hash_t *hs)
+{
+	/* no bucket lock, one single lock to protect the hash-table */
+	return (hs->hs_flags & CFS_HASH_NO_BKTLOCK) != 0;
+}
+
+static inline int
+cfs_hash_with_rw_bktlock(cfs_hash_t *hs)
+{
+	/* rwlock to protect hash bucket */
+	return (hs->hs_flags & CFS_HASH_RW_BKTLOCK) != 0;
+}
+
+static inline int
+cfs_hash_with_spin_bktlock(cfs_hash_t *hs)
+{
+	/* spinlock to protect hash bucket */
+	return (hs->hs_flags & CFS_HASH_SPIN_BKTLOCK) != 0;
+}
+
+static inline int
+cfs_hash_with_add_tail(cfs_hash_t *hs)
+{
+	return (hs->hs_flags & CFS_HASH_ADD_TAIL) != 0;
+}
+
+static inline int
+cfs_hash_with_no_itemref(cfs_hash_t *hs)
+{
+	/* hash-table doesn't keep refcount on item,
+	 * item can't be removed from hash unless it's
+	 * ZERO refcount */
+	return (hs->hs_flags & CFS_HASH_NO_ITEMREF) != 0;
+}
+
+static inline int
+cfs_hash_with_bigname(cfs_hash_t *hs)
+{
+	return (hs->hs_flags & CFS_HASH_BIGNAME) != 0;
+}
+
+static inline int
+cfs_hash_with_counter(cfs_hash_t *hs)
+{
+	return (hs->hs_flags & CFS_HASH_COUNTER) != 0;
+}
+
+static inline int
+cfs_hash_with_rehash(cfs_hash_t *hs)
+{
+	return (hs->hs_flags & CFS_HASH_REHASH) != 0;
+}
+
+static inline int
+cfs_hash_with_rehash_key(cfs_hash_t *hs)
+{
+	return (hs->hs_flags & CFS_HASH_REHASH_KEY) != 0;
+}
+
+static inline int
+cfs_hash_with_shrink(cfs_hash_t *hs)
+{
+	return (hs->hs_flags & CFS_HASH_SHRINK) != 0;
+}
+
+static inline int
+cfs_hash_with_assert_empty(cfs_hash_t *hs)
+{
+	return (hs->hs_flags & CFS_HASH_ASSERT_EMPTY) != 0;
+}
+
+static inline int
+cfs_hash_with_depth(cfs_hash_t *hs)
+{
+	return (hs->hs_flags & CFS_HASH_DEPTH) != 0;
+}
+
+static inline int
+cfs_hash_with_nblk_change(cfs_hash_t *hs)
+{
+	return (hs->hs_flags & CFS_HASH_NBLK_CHANGE) != 0;
+}
+
+static inline int
+cfs_hash_is_exiting(cfs_hash_t *hs)
+{       /* cfs_hash_destroy is called */
+	return hs->hs_exiting;
+}
+
+static inline int
+cfs_hash_is_rehashing(cfs_hash_t *hs)
+{       /* rehash is launched */
+	return hs->hs_rehash_bits != 0;
+}
+
+static inline int
+cfs_hash_is_iterating(cfs_hash_t *hs)
+{       /* someone is calling cfs_hash_for_each_* */
+	return hs->hs_iterating || hs->hs_iterators != 0;
+}
+
+static inline int
+cfs_hash_bkt_size(cfs_hash_t *hs)
+{
+	return offsetof(cfs_hash_bucket_t, hsb_head[0]) +
+	       hs->hs_hops->hop_hhead_size(hs) * CFS_HASH_BKT_NHLIST(hs) +
+	       hs->hs_extra_bytes;
+}
+
+#define CFS_HOP(hs, op)	   (hs)->hs_ops->hs_ ## op
+
+static inline unsigned
+cfs_hash_id(cfs_hash_t *hs, const void *key, unsigned mask)
+{
+	return CFS_HOP(hs, hash)(hs, key, mask);
+}
+
+static inline void *
+cfs_hash_key(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	return CFS_HOP(hs, key)(hnode);
+}
+
+static inline void
+cfs_hash_keycpy(cfs_hash_t *hs, struct hlist_node *hnode, void *key)
+{
+	if (CFS_HOP(hs, keycpy) != NULL)
+		CFS_HOP(hs, keycpy)(hnode, key);
+}
+
+/**
+ * Returns 1 on a match,
+ */
+static inline int
+cfs_hash_keycmp(cfs_hash_t *hs, const void *key, struct hlist_node *hnode)
+{
+	return CFS_HOP(hs, keycmp)(key, hnode);
+}
+
+static inline void *
+cfs_hash_object(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	return CFS_HOP(hs, object)(hnode);
+}
+
+static inline void
+cfs_hash_get(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	return CFS_HOP(hs, get)(hs, hnode);
+}
+
+static inline void
+cfs_hash_put_locked(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	LASSERT(CFS_HOP(hs, put_locked) != NULL);
+
+	return CFS_HOP(hs, put_locked)(hs, hnode);
+}
+
+static inline void
+cfs_hash_put(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	LASSERT(CFS_HOP(hs, put) != NULL);
+
+	return CFS_HOP(hs, put)(hs, hnode);
+}
+
+static inline void
+cfs_hash_exit(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	if (CFS_HOP(hs, exit))
+		CFS_HOP(hs, exit)(hs, hnode);
+}
+
+static inline void cfs_hash_lock(cfs_hash_t *hs, int excl)
+{
+	hs->hs_lops->hs_lock(&hs->hs_lock, excl);
+}
+
+static inline void cfs_hash_unlock(cfs_hash_t *hs, int excl)
+{
+	hs->hs_lops->hs_unlock(&hs->hs_lock, excl);
+}
+
+static inline int cfs_hash_dec_and_lock(cfs_hash_t *hs,
+					atomic_t *condition)
+{
+	LASSERT(cfs_hash_with_no_bktlock(hs));
+	return atomic_dec_and_lock(condition, &hs->hs_lock.spin);
+}
+
+static inline void cfs_hash_bd_lock(cfs_hash_t *hs,
+				    cfs_hash_bd_t *bd, int excl)
+{
+	hs->hs_lops->hs_bkt_lock(&bd->bd_bucket->hsb_lock, excl);
+}
+
+static inline void cfs_hash_bd_unlock(cfs_hash_t *hs,
+				      cfs_hash_bd_t *bd, int excl)
+{
+	hs->hs_lops->hs_bkt_unlock(&bd->bd_bucket->hsb_lock, excl);
+}
+
+/**
+ * operations on cfs_hash bucket (bd: bucket descriptor),
+ * they are normally for hash-table without rehash
+ */
+void cfs_hash_bd_get(cfs_hash_t *hs, const void *key, cfs_hash_bd_t *bd);
+
+static inline void cfs_hash_bd_get_and_lock(cfs_hash_t *hs, const void *key,
+					    cfs_hash_bd_t *bd, int excl)
+{
+	cfs_hash_bd_get(hs, key, bd);
+	cfs_hash_bd_lock(hs, bd, excl);
+}
+
+static inline unsigned cfs_hash_bd_index_get(cfs_hash_t *hs, cfs_hash_bd_t *bd)
+{
+	return bd->bd_offset | (bd->bd_bucket->hsb_index << hs->hs_bkt_bits);
+}
+
+static inline void cfs_hash_bd_index_set(cfs_hash_t *hs,
+					 unsigned index, cfs_hash_bd_t *bd)
+{
+	bd->bd_bucket = hs->hs_buckets[index >> hs->hs_bkt_bits];
+	bd->bd_offset = index & (CFS_HASH_BKT_NHLIST(hs) - 1U);
+}
+
+static inline void *
+cfs_hash_bd_extra_get(cfs_hash_t *hs, cfs_hash_bd_t *bd)
+{
+	return (void *)bd->bd_bucket +
+	       cfs_hash_bkt_size(hs) - hs->hs_extra_bytes;
+}
+
+static inline __u32
+cfs_hash_bd_version_get(cfs_hash_bd_t *bd)
+{
+	/* need hold cfs_hash_bd_lock */
+	return bd->bd_bucket->hsb_version;
+}
+
+static inline __u32
+cfs_hash_bd_count_get(cfs_hash_bd_t *bd)
+{
+	/* need hold cfs_hash_bd_lock */
+	return bd->bd_bucket->hsb_count;
+}
+
+static inline int
+cfs_hash_bd_depmax_get(cfs_hash_bd_t *bd)
+{
+	return bd->bd_bucket->hsb_depmax;
+}
+
+static inline int
+cfs_hash_bd_compare(cfs_hash_bd_t *bd1, cfs_hash_bd_t *bd2)
+{
+	if (bd1->bd_bucket->hsb_index != bd2->bd_bucket->hsb_index)
+		return bd1->bd_bucket->hsb_index - bd2->bd_bucket->hsb_index;
+
+	if (bd1->bd_offset != bd2->bd_offset)
+		return bd1->bd_offset - bd2->bd_offset;
+
+	return 0;
+}
+
+void cfs_hash_bd_add_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+			    struct hlist_node *hnode);
+void cfs_hash_bd_del_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+			    struct hlist_node *hnode);
+void cfs_hash_bd_move_locked(cfs_hash_t *hs, cfs_hash_bd_t *bd_old,
+			     cfs_hash_bd_t *bd_new, struct hlist_node *hnode);
+
+static inline int cfs_hash_bd_dec_and_lock(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+					   atomic_t *condition)
+{
+	LASSERT(cfs_hash_with_spin_bktlock(hs));
+	return atomic_dec_and_lock(condition,
+				       &bd->bd_bucket->hsb_lock.spin);
+}
+
+static inline struct hlist_head *cfs_hash_bd_hhead(cfs_hash_t *hs,
+						  cfs_hash_bd_t *bd)
+{
+	return hs->hs_hops->hop_hhead(hs, bd);
+}
+
+struct hlist_node *cfs_hash_bd_lookup_locked(cfs_hash_t *hs,
+					    cfs_hash_bd_t *bd, const void *key);
+struct hlist_node *cfs_hash_bd_peek_locked(cfs_hash_t *hs,
+					  cfs_hash_bd_t *bd, const void *key);
+struct hlist_node *cfs_hash_bd_findadd_locked(cfs_hash_t *hs,
+					     cfs_hash_bd_t *bd, const void *key,
+					     struct hlist_node *hnode,
+					     int insist_add);
+struct hlist_node *cfs_hash_bd_finddel_locked(cfs_hash_t *hs,
+					     cfs_hash_bd_t *bd, const void *key,
+					     struct hlist_node *hnode);
+
+/**
+ * operations on cfs_hash bucket (bd: bucket descriptor),
+ * they are safe for hash-table with rehash
+ */
+void cfs_hash_dual_bd_get(cfs_hash_t *hs, const void *key, cfs_hash_bd_t *bds);
+void cfs_hash_dual_bd_lock(cfs_hash_t *hs, cfs_hash_bd_t *bds, int excl);
+void cfs_hash_dual_bd_unlock(cfs_hash_t *hs, cfs_hash_bd_t *bds, int excl);
+
+static inline void cfs_hash_dual_bd_get_and_lock(cfs_hash_t *hs, const void *key,
+						 cfs_hash_bd_t *bds, int excl)
+{
+	cfs_hash_dual_bd_get(hs, key, bds);
+	cfs_hash_dual_bd_lock(hs, bds, excl);
+}
+
+struct hlist_node *cfs_hash_dual_bd_lookup_locked(cfs_hash_t *hs,
+						 cfs_hash_bd_t *bds,
+						 const void *key);
+struct hlist_node *cfs_hash_dual_bd_findadd_locked(cfs_hash_t *hs,
+						  cfs_hash_bd_t *bds,
+						  const void *key,
+						  struct hlist_node *hnode,
+						  int insist_add);
+struct hlist_node *cfs_hash_dual_bd_finddel_locked(cfs_hash_t *hs,
+						  cfs_hash_bd_t *bds,
+						  const void *key,
+						  struct hlist_node *hnode);
+
+/* Hash init/cleanup functions */
+cfs_hash_t *cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits,
+			    unsigned bkt_bits, unsigned extra_bytes,
+			    unsigned min_theta, unsigned max_theta,
+			    cfs_hash_ops_t *ops, unsigned flags);
+
+cfs_hash_t *cfs_hash_getref(cfs_hash_t *hs);
+void cfs_hash_putref(cfs_hash_t *hs);
+
+/* Hash addition functions */
+void cfs_hash_add(cfs_hash_t *hs, const void *key,
+		  struct hlist_node *hnode);
+int cfs_hash_add_unique(cfs_hash_t *hs, const void *key,
+			struct hlist_node *hnode);
+void *cfs_hash_findadd_unique(cfs_hash_t *hs, const void *key,
+			      struct hlist_node *hnode);
+
+/* Hash deletion functions */
+void *cfs_hash_del(cfs_hash_t *hs, const void *key, struct hlist_node *hnode);
+void *cfs_hash_del_key(cfs_hash_t *hs, const void *key);
+
+/* Hash lookup/for_each functions */
+#define CFS_HASH_LOOP_HOG       1024
+
+typedef int (*cfs_hash_for_each_cb_t)(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+				      struct hlist_node *node, void *data);
+void *cfs_hash_lookup(cfs_hash_t *hs, const void *key);
+void cfs_hash_for_each(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
+void cfs_hash_for_each_safe(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
+int  cfs_hash_for_each_nolock(cfs_hash_t *hs,
+			      cfs_hash_for_each_cb_t, void *data);
+int  cfs_hash_for_each_empty(cfs_hash_t *hs,
+			     cfs_hash_for_each_cb_t, void *data);
+void cfs_hash_for_each_key(cfs_hash_t *hs, const void *key,
+			   cfs_hash_for_each_cb_t, void *data);
+typedef int (*cfs_hash_cond_opt_cb_t)(void *obj, void *data);
+void cfs_hash_cond_del(cfs_hash_t *hs, cfs_hash_cond_opt_cb_t, void *data);
+
+void cfs_hash_hlist_for_each(cfs_hash_t *hs, unsigned hindex,
+			     cfs_hash_for_each_cb_t, void *data);
+int  cfs_hash_is_empty(cfs_hash_t *hs);
+__u64 cfs_hash_size_get(cfs_hash_t *hs);
+
+/*
+ * Rehash - Theta is calculated to be the average chained
+ * hash depth assuming a perfectly uniform hash funcion.
+ */
+void cfs_hash_rehash_cancel_locked(cfs_hash_t *hs);
+void cfs_hash_rehash_cancel(cfs_hash_t *hs);
+int  cfs_hash_rehash(cfs_hash_t *hs, int do_rehash);
+void cfs_hash_rehash_key(cfs_hash_t *hs, const void *old_key,
+			 void *new_key, struct hlist_node *hnode);
+
+#if CFS_HASH_DEBUG_LEVEL > CFS_HASH_DEBUG_1
+/* Validate hnode references the correct key */
+static inline void
+cfs_hash_key_validate(cfs_hash_t *hs, const void *key,
+		      struct hlist_node *hnode)
+{
+	LASSERT(cfs_hash_keycmp(hs, key, hnode));
+}
+
+/* Validate hnode is in the correct bucket */
+static inline void
+cfs_hash_bucket_validate(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+			 struct hlist_node *hnode)
+{
+	cfs_hash_bd_t   bds[2];
+
+	cfs_hash_dual_bd_get(hs, cfs_hash_key(hs, hnode), bds);
+	LASSERT(bds[0].bd_bucket == bd->bd_bucket ||
+		bds[1].bd_bucket == bd->bd_bucket);
+}
+
+#else /* CFS_HASH_DEBUG_LEVEL > CFS_HASH_DEBUG_1 */
+
+static inline void
+cfs_hash_key_validate(cfs_hash_t *hs, const void *key,
+		      struct hlist_node *hnode) {}
+
+static inline void
+cfs_hash_bucket_validate(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+			 struct hlist_node *hnode) {}
+
+#endif /* CFS_HASH_DEBUG_LEVEL */
+
+#define CFS_HASH_THETA_BITS  10
+#define CFS_HASH_MIN_THETA  (1U << (CFS_HASH_THETA_BITS - 1))
+#define CFS_HASH_MAX_THETA  (1U << (CFS_HASH_THETA_BITS + 1))
+
+/* Return integer component of theta */
+static inline int __cfs_hash_theta_int(int theta)
+{
+	return (theta >> CFS_HASH_THETA_BITS);
+}
+
+/* Return a fractional value between 0 and 999 */
+static inline int __cfs_hash_theta_frac(int theta)
+{
+	return ((theta * 1000) >> CFS_HASH_THETA_BITS) -
+	       (__cfs_hash_theta_int(theta) * 1000);
+}
+
+static inline int __cfs_hash_theta(cfs_hash_t *hs)
+{
+	return (atomic_read(&hs->hs_count) <<
+		CFS_HASH_THETA_BITS) >> hs->hs_cur_bits;
+}
+
+static inline void __cfs_hash_set_theta(cfs_hash_t *hs, int min, int max)
+{
+	LASSERT(min < max);
+	hs->hs_min_theta = (__u16)min;
+	hs->hs_max_theta = (__u16)max;
+}
+
+/* Generic debug formatting routines mainly for proc handler */
+struct seq_file;
+int cfs_hash_debug_header(struct seq_file *m);
+int cfs_hash_debug_str(cfs_hash_t *hs, struct seq_file *m);
+
+/*
+ * Generic djb2 hash algorithm for character arrays.
+ */
+static inline unsigned
+cfs_hash_djb2_hash(const void *key, size_t size, unsigned mask)
+{
+	unsigned i, hash = 5381;
+
+	LASSERT(key != NULL);
+
+	for (i = 0; i < size; i++)
+		hash = hash * 33 + ((char *)key)[i];
+
+	return (hash & mask);
+}
+
+/*
+ * Generic u32 hash algorithm.
+ */
+static inline unsigned
+cfs_hash_u32_hash(const __u32 key, unsigned mask)
+{
+	return ((key * CFS_GOLDEN_RATIO_PRIME_32) & mask);
+}
+
+/*
+ * Generic u64 hash algorithm.
+ */
+static inline unsigned
+cfs_hash_u64_hash(const __u64 key, unsigned mask)
+{
+	return ((unsigned)(key * CFS_GOLDEN_RATIO_PRIME_64) & mask);
+}
+
+/** iterate over all buckets in @bds (array of cfs_hash_bd_t) */
+#define cfs_hash_for_each_bd(bds, n, i) \
+	for (i = 0; i < n && (bds)[i].bd_bucket != NULL; i++)
+
+/** iterate over all buckets of @hs */
+#define cfs_hash_for_each_bucket(hs, bd, pos)		   \
+	for (pos = 0;					   \
+	     pos < CFS_HASH_NBKT(hs) &&			 \
+	     ((bd)->bd_bucket = (hs)->hs_buckets[pos]) != NULL; pos++)
+
+/** iterate over all hlist of bucket @bd */
+#define cfs_hash_bd_for_each_hlist(hs, bd, hlist)	       \
+	for ((bd)->bd_offset = 0;			       \
+	     (bd)->bd_offset < CFS_HASH_BKT_NHLIST(hs) &&       \
+	     (hlist = cfs_hash_bd_hhead(hs, bd)) != NULL;       \
+	     (bd)->bd_offset++)
+
+/* !__LIBCFS__HASH_H__ */
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_heap.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_heap.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_heap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_heap.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,200 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.  A copy is
+ * included in the COPYING file that accompanied this code.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2011 Intel Corporation
+ */
+/*
+ * libcfs/include/libcfs/heap.h
+ *
+ * Author: Eric Barton	<eeb@whamcloud.com>
+ *	   Liang Zhen	<liang@whamcloud.com>
+ */
+
+#ifndef __LIBCFS_HEAP_H__
+#define __LIBCFS_HEAP_H__
+
+/** \defgroup heap Binary heap
+ *
+ * The binary heap is a scalable data structure created using a binary tree. It
+ * is capable of maintaining large sets of elements sorted usually by one or
+ * more element properties, but really based on anything that can be used as a
+ * binary predicate in order to determine the relevant ordering of any two nodes
+ * that belong to the set. There is no search operation, rather the intention is
+ * for the element of the lowest priority which will always be at the root of
+ * the tree (as this is an implementation of a min-heap) to be removed by users
+ * for consumption.
+ *
+ * Users of the heap should embed a \e cfs_binheap_node_t object instance on
+ * every object of the set that they wish the binary heap instance to handle,
+ * and (at a minimum) provide a cfs_binheap_ops_t::hop_compare() implementation
+ * which is used by the heap as the binary predicate during its internal sorting
+ * operations.
+ *
+ * The current implementation enforces no locking scheme, and so assumes the
+ * user caters for locking between calls to insert, delete and lookup
+ * operations. Since the only consumer for the data structure at this point
+ * are NRS policies, and these operate on a per-CPT basis, binary heap instances
+ * are tied to a specific CPT.
+ * @{
+ */
+
+/**
+ * Binary heap node.
+ *
+ * Objects of this type are embedded into objects of the ordered set that is to
+ * be maintained by a \e cfs_binheap_t instance.
+ */
+typedef struct {
+	/** Index into the binary tree */
+	unsigned int	chn_index;
+} cfs_binheap_node_t;
+
+#define CBH_SHIFT	9
+#define CBH_SIZE       (1 << CBH_SHIFT)		    /* # ptrs per level */
+#define CBH_MASK       (CBH_SIZE - 1)
+#define CBH_NOB	(CBH_SIZE * sizeof(cfs_binheap_node_t *))
+
+#define CBH_POISON	0xdeadbeef
+
+/**
+ * Binary heap flags.
+ */
+enum {
+	CBH_FLAG_ATOMIC_GROW	= 1,
+};
+
+struct cfs_binheap;
+
+/**
+ * Binary heap operations.
+ */
+typedef struct {
+	/**
+	 * Called right before inserting a node into the binary heap.
+	 *
+	 * Implementing this operation is optional.
+	 *
+	 * \param[in] h The heap
+	 * \param[in] e The node
+	 *
+	 * \retval 0 success
+	 * \retval != 0 error
+	 */
+	int		(*hop_enter)(struct cfs_binheap *h,
+				     cfs_binheap_node_t *e);
+	/**
+	 * Called right after removing a node from the binary heap.
+	 *
+	 * Implementing this operation is optional.
+	 *
+	 * \param[in] h The heap
+	 * \param[in] e The node
+	 */
+	void		(*hop_exit)(struct cfs_binheap *h,
+				    cfs_binheap_node_t *e);
+	/**
+	 * A binary predicate which is called during internal heap sorting
+	 * operations, and used in order to determine the relevant ordering of
+	 * two heap nodes.
+	 *
+	 * Implementing this operation is mandatory.
+	 *
+	 * \param[in] a The first heap node
+	 * \param[in] b The second heap node
+	 *
+	 * \retval 0 Node a > node b
+	 * \retval 1 Node a < node b
+	 *
+	 * \see cfs_binheap_bubble()
+	 * \see cfs_biheap_sink()
+	 */
+	int		(*hop_compare)(cfs_binheap_node_t *a,
+				       cfs_binheap_node_t *b);
+} cfs_binheap_ops_t;
+
+/**
+ * Binary heap object.
+ *
+ * Sorts elements of type \e cfs_binheap_node_t
+ */
+typedef struct cfs_binheap {
+	/** Triple indirect */
+	cfs_binheap_node_t  ****cbh_elements3;
+	/** double indirect */
+	cfs_binheap_node_t   ***cbh_elements2;
+	/** single indirect */
+	cfs_binheap_node_t    **cbh_elements1;
+	/** # elements referenced */
+	unsigned int		cbh_nelements;
+	/** high water mark */
+	unsigned int		cbh_hwm;
+	/** user flags */
+	unsigned int		cbh_flags;
+	/** operations table */
+	cfs_binheap_ops_t      *cbh_ops;
+	/** private data */
+	void		       *cbh_private;
+	/** associated CPT table */
+	struct cfs_cpt_table   *cbh_cptab;
+	/** associated CPT id of this cfs_binheap_t::cbh_cptab */
+	int			cbh_cptid;
+} cfs_binheap_t;
+
+void cfs_binheap_destroy(cfs_binheap_t *h);
+cfs_binheap_t *cfs_binheap_create(cfs_binheap_ops_t *ops, unsigned int flags,
+				  unsigned count, void *arg,
+				  struct cfs_cpt_table *cptab, int cptid);
+cfs_binheap_node_t *cfs_binheap_find(cfs_binheap_t *h, unsigned int idx);
+int cfs_binheap_insert(cfs_binheap_t *h, cfs_binheap_node_t *e);
+void cfs_binheap_remove(cfs_binheap_t *h, cfs_binheap_node_t *e);
+
+static inline int
+cfs_binheap_size(cfs_binheap_t *h)
+{
+	return h->cbh_nelements;
+}
+
+static inline int
+cfs_binheap_is_empty(cfs_binheap_t *h)
+{
+	return h->cbh_nelements == 0;
+}
+
+static inline cfs_binheap_node_t *
+cfs_binheap_root(cfs_binheap_t *h)
+{
+	return cfs_binheap_find(h, 0);
+}
+
+static inline cfs_binheap_node_t *
+cfs_binheap_remove_root(cfs_binheap_t *h)
+{
+	cfs_binheap_node_t *e = cfs_binheap_find(h, 0);
+
+	if (e != NULL)
+		cfs_binheap_remove(h, e);
+	return e;
+}
+
+/** @} heap */
+
+#endif /* __LIBCFS_HEAP_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_ioctl.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,222 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_ioctl.h
+ *
+ * Low-level ioctl data structures. Kernel ioctl functions declared here,
+ * and user space functions are in libcfsutil_ioctl.h.
+ *
+ */
+
+#ifndef __LIBCFS_IOCTL_H__
+#define __LIBCFS_IOCTL_H__
+
+
+#define LIBCFS_IOCTL_VERSION 0x0001000a
+
+struct libcfs_ioctl_data {
+	__u32 ioc_len;
+	__u32 ioc_version;
+
+	__u64 ioc_nid;
+	__u64 ioc_u64[1];
+
+	__u32 ioc_flags;
+	__u32 ioc_count;
+	__u32 ioc_net;
+	__u32 ioc_u32[7];
+
+	__u32 ioc_inllen1;
+	char *ioc_inlbuf1;
+	__u32 ioc_inllen2;
+	char *ioc_inlbuf2;
+
+	__u32 ioc_plen1; /* buffers in userspace */
+	char *ioc_pbuf1;
+	__u32 ioc_plen2; /* buffers in userspace */
+	char *ioc_pbuf2;
+
+	char ioc_bulk[0];
+};
+
+
+struct libcfs_ioctl_hdr {
+	__u32 ioc_len;
+	__u32 ioc_version;
+};
+
+struct libcfs_debug_ioctl_data
+{
+	struct libcfs_ioctl_hdr hdr;
+	unsigned int subs;
+	unsigned int debug;
+};
+
+#define LIBCFS_IOC_INIT(data)			   \
+do {						    \
+	memset(&data, 0, sizeof(data));		 \
+	data.ioc_version = LIBCFS_IOCTL_VERSION;	\
+	data.ioc_len = sizeof(data);		    \
+} while (0)
+
+
+struct libcfs_ioctl_handler {
+	struct list_head item;
+	int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_data *data);
+};
+
+#define DECLARE_IOCTL_HANDLER(ident, func)		      \
+	struct libcfs_ioctl_handler ident = {		   \
+		/* .item = */ LIST_HEAD_INIT(ident.item),   \
+		/* .handle_ioctl = */ func		      \
+	}
+
+
+/* FIXME check conflict with lustre_lib.h */
+#define LIBCFS_IOC_DEBUG_MASK	     _IOWR('f', 250, long)
+
+
+/* ioctls for manipulating snapshots 30- */
+#define IOC_LIBCFS_TYPE		   'e'
+#define IOC_LIBCFS_MIN_NR		 30
+/* libcfs ioctls */
+#define IOC_LIBCFS_PANIC		   _IOWR('e', 30, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_CLEAR_DEBUG	     _IOWR('e', 31, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_MARK_DEBUG	      _IOWR('e', 32, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LWT_CONTROL	     _IOWR('e', 33, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LWT_SNAPSHOT	    _IOWR('e', 34, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LWT_LOOKUP_STRING       _IOWR('e', 35, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_MEMHOG		  _IOWR('e', 36, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_PING_TEST	       _IOWR('e', 37, IOCTL_LIBCFS_TYPE)
+/* lnet ioctls */
+#define IOC_LIBCFS_GET_NI		  _IOWR('e', 50, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_FAIL_NID		_IOWR('e', 51, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_ADD_ROUTE	       _IOWR('e', 52, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_DEL_ROUTE	       _IOWR('e', 53, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_ROUTE	       _IOWR('e', 54, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_NOTIFY_ROUTER	   _IOWR('e', 55, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_UNCONFIGURE	     _IOWR('e', 56, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_PORTALS_COMPATIBILITY   _IOWR('e', 57, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LNET_DIST	       _IOWR('e', 58, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_CONFIGURE	       _IOWR('e', 59, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_TESTPROTOCOMPAT	 _IOWR('e', 60, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_PING		    _IOWR('e', 61, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_DEBUG_PEER	      _IOWR('e', 62, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_LNETST		  _IOWR('e', 63, IOCTL_LIBCFS_TYPE)
+/* lnd ioctls */
+#define IOC_LIBCFS_REGISTER_MYNID	  _IOWR('e', 70, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_CLOSE_CONNECTION	_IOWR('e', 71, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_PUSH_CONNECTION	 _IOWR('e', 72, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_CONN		_IOWR('e', 73, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_DEL_PEER		_IOWR('e', 74, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_ADD_PEER		_IOWR('e', 75, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_PEER		_IOWR('e', 76, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_TXDESC	      _IOWR('e', 77, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_ADD_INTERFACE	   _IOWR('e', 78, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_DEL_INTERFACE	   _IOWR('e', 79, IOCTL_LIBCFS_TYPE)
+#define IOC_LIBCFS_GET_INTERFACE	   _IOWR('e', 80, IOCTL_LIBCFS_TYPE)
+
+#define IOC_LIBCFS_MAX_NR			     80
+
+static inline int libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)
+{
+	int len = sizeof(*data);
+	len += cfs_size_round(data->ioc_inllen1);
+	len += cfs_size_round(data->ioc_inllen2);
+	return len;
+}
+
+static inline int libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data)
+{
+	if (data->ioc_len > (1<<30)) {
+		CERROR ("LIBCFS ioctl: ioc_len larger than 1<<30\n");
+		return 1;
+	}
+	if (data->ioc_inllen1 > (1<<30)) {
+		CERROR ("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n");
+		return 1;
+	}
+	if (data->ioc_inllen2 > (1<<30)) {
+		CERROR ("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n");
+		return 1;
+	}
+	if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
+		CERROR ("LIBCFS ioctl: inlbuf1 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
+		CERROR ("LIBCFS ioctl: inlbuf2 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_pbuf1 && !data->ioc_plen1) {
+		CERROR ("LIBCFS ioctl: pbuf1 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_pbuf2 && !data->ioc_plen2) {
+		CERROR ("LIBCFS ioctl: pbuf2 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_plen1 && !data->ioc_pbuf1) {
+		CERROR ("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n");
+		return 1;
+	}
+	if (data->ioc_plen2 && !data->ioc_pbuf2) {
+		CERROR ("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n");
+		return 1;
+	}
+	if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_len ) {
+		CERROR ("LIBCFS ioctl: packlen != ioc_len\n");
+		return 1;
+	}
+	if (data->ioc_inllen1 &&
+	    data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') {
+		CERROR ("LIBCFS ioctl: inlbuf1 not 0 terminated\n");
+		return 1;
+	}
+	if (data->ioc_inllen2 &&
+	    data->ioc_bulk[cfs_size_round(data->ioc_inllen1) +
+			   data->ioc_inllen2 - 1] != '\0') {
+		CERROR ("LIBCFS ioctl: inlbuf2 not 0 terminated\n");
+		return 1;
+	}
+	return 0;
+}
+
+
+extern int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand);
+extern int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand);
+extern int libcfs_ioctl_getdata(char *buf, char *end, void *arg);
+extern int libcfs_ioctl_popdata(void *arg, void *buf, int size);
+
+
+#endif /* __LIBCFS_IOCTL_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,117 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * Author: Nathan Rutman <nathan.rutman@sun.com>
+ *
+ * libcfs/include/libcfs/libcfs_kernelcomm.h
+ *
+ * Kernel <-> userspace communication routines.
+ * The definitions below are used in the kernel and userspace.
+ *
+ */
+
+#ifndef __LIBCFS_KERNELCOMM_H__
+#define __LIBCFS_KERNELCOMM_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
+#endif
+
+
+/* KUC message header.
+ * All current and future KUC messages should use this header.
+ * To avoid having to include Lustre headers from libcfs, define this here.
+ */
+struct kuc_hdr {
+	__u16 kuc_magic;
+	__u8  kuc_transport;  /* Each new Lustre feature should use a different
+				 transport */
+	__u8  kuc_flags;
+	__u16 kuc_msgtype;    /* Message type or opcode, transport-specific */
+	__u16 kuc_msglen;     /* Including header */
+} __attribute__((aligned(sizeof(__u64))));
+
+#define KUC_MAGIC  0x191C /*Lustre9etLinC */
+#define KUC_FL_BLOCK 0x01   /* Wait for send */
+
+/* kuc_msgtype values are defined in each transport */
+enum kuc_transport_type {
+	KUC_TRANSPORT_GENERIC   = 1,
+	KUC_TRANSPORT_HSM       = 2,
+	KUC_TRANSPORT_CHANGELOG = 3,
+};
+
+enum kuc_generic_message_type {
+	KUC_MSG_SHUTDOWN = 1,
+};
+
+/* prototype for callback function on kuc groups */
+typedef int (*libcfs_kkuc_cb_t)(__u32 data, void *cb_arg);
+
+/* KUC Broadcast Groups. This determines which userspace process hears which
+ * messages.  Mutliple transports may be used within a group, or multiple
+ * groups may use the same transport.  Broadcast
+ * groups need not be used if e.g. a UID is specified instead;
+ * use group 0 to signify unicast.
+ */
+#define KUC_GRP_HSM	   0x02
+#define KUC_GRP_MAX	   KUC_GRP_HSM
+
+/* Kernel methods */
+extern int libcfs_kkuc_msg_put(struct file *fp, void *payload);
+extern int libcfs_kkuc_group_put(int group, void *payload);
+extern int libcfs_kkuc_group_add(struct file *fp, int uid, int group,
+				 __u32 data);
+extern int libcfs_kkuc_group_rem(int uid, int group);
+extern int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func,
+				     void *cb_arg);
+
+#define LK_FLG_STOP 0x01
+
+/* kernelcomm control structure, passed from userspace to kernel */
+typedef struct lustre_kernelcomm {
+	__u32 lk_wfd;
+	__u32 lk_rfd;
+	__u32 lk_uid;
+	__u32 lk_group;
+	__u32 lk_data;
+	__u32 lk_flags;
+} __attribute__((packed)) lustre_kernelcomm;
+
+/* Userspace methods */
+extern int libcfs_ukuc_start(lustre_kernelcomm *l, int groups);
+extern int libcfs_ukuc_stop(lustre_kernelcomm *l);
+extern int libcfs_ukuc_msg_get(lustre_kernelcomm *l, char *buf, int maxsize,
+			       int transport);
+
+#endif /* __LIBCFS_KERNELCOMM_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_prim.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,101 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_prim.h
+ *
+ * General primitives.
+ *
+ */
+
+#ifndef __LIBCFS_PRIM_H__
+#define __LIBCFS_PRIM_H__
+
+#ifndef EXPORT_SYMBOL
+# define EXPORT_SYMBOL(s)
+#endif
+
+/*
+ * Schedule
+ */
+void cfs_pause(cfs_duration_t ticks);
+
+/*
+ * Timer
+ */
+typedef  void (cfs_timer_func_t)(ulong_ptr_t);
+void schedule_timeout_and_set_state(cfs_task_state_t, int64_t);
+
+void init_waitqueue_entry_current(wait_queue_t *link);
+int64_t waitq_timedwait(wait_queue_t *, cfs_task_state_t, int64_t);
+void waitq_wait(wait_queue_t *, cfs_task_state_t);
+void add_wait_queue_exclusive_head(wait_queue_head_t *, wait_queue_t *);
+
+void cfs_init_timer(timer_list_t *t);
+void cfs_timer_init(timer_list_t *t, cfs_timer_func_t *func, void *arg);
+void cfs_timer_done(timer_list_t *t);
+void cfs_timer_arm(timer_list_t *t, cfs_time_t deadline);
+void cfs_timer_disarm(timer_list_t *t);
+int  cfs_timer_is_armed(timer_list_t *t);
+cfs_time_t cfs_timer_deadline(timer_list_t *t);
+
+/*
+ * Memory
+ */
+#ifndef memory_pressure_get
+#define memory_pressure_get() (0)
+#endif
+#ifndef memory_pressure_set
+#define memory_pressure_set() do {} while (0)
+#endif
+#ifndef memory_pressure_clr
+#define memory_pressure_clr() do {} while (0)
+#endif
+
+static inline int cfs_memory_pressure_get_and_set(void)
+{
+	int old = memory_pressure_get();
+
+	if (!old)
+		memory_pressure_set();
+	return old;
+}
+
+static inline void cfs_memory_pressure_restore(int old)
+{
+	if (old)
+		memory_pressure_set();
+	else
+		memory_pressure_clr();
+	return;
+}
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,577 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_private.h
+ *
+ * Various defines for libcfs.
+ *
+ */
+
+#ifndef __LIBCFS_PRIVATE_H__
+#define __LIBCFS_PRIVATE_H__
+
+/* XXX this layering violation is for nidstrings */
+#include <linux/lnet/types.h>
+
+#ifndef DEBUG_SUBSYSTEM
+# define DEBUG_SUBSYSTEM S_UNDEFINED
+#endif
+
+
+
+/*
+ * When this is on, LASSERT macro includes check for assignment used instead
+ * of equality check, but doesn't have unlikely(). Turn this on from time to
+ * time to make test-builds. This shouldn't be on for production release.
+ */
+#define LASSERT_CHECKED (0)
+
+
+#define LASSERTF(cond, fmt, ...)					\
+do {									\
+	if (unlikely(!(cond))) {					\
+		LIBCFS_DEBUG_MSG_DATA_DECL(__msg_data, D_EMERG, NULL);	\
+		libcfs_debug_msg(&__msg_data,				\
+				 "ASSERTION( %s ) failed: " fmt, #cond,	\
+				 ## __VA_ARGS__);			\
+		lbug_with_loc(&__msg_data);				\
+	}								\
+} while (0)
+
+#define LASSERT(cond) LASSERTF(cond, "\n")
+
+#ifdef CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK
+/**
+ * This is for more expensive checks that one doesn't want to be enabled all
+ * the time. LINVRNT() has to be explicitly enabled by
+ * CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK option.
+ */
+# define LINVRNT(exp) LASSERT(exp)
+#else
+# define LINVRNT(exp) ((void)sizeof!!(exp))
+#endif
+
+#define KLASSERT(e) LASSERT(e)
+
+void lbug_with_loc(struct libcfs_debug_msg_data *) __attribute__((noreturn));
+
+#define LBUG()							  \
+do {								    \
+	LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_EMERG, NULL);	     \
+	lbug_with_loc(&msgdata);					\
+} while(0)
+
+extern atomic_t libcfs_kmemory;
+/*
+ * Memory
+ */
+
+# define libcfs_kmem_inc(ptr, size)		\
+do {						\
+	atomic_add(size, &libcfs_kmemory);	\
+} while (0)
+
+# define libcfs_kmem_dec(ptr, size)		\
+do {						\
+	atomic_sub(size, &libcfs_kmemory);	\
+} while (0)
+
+# define libcfs_kmem_read()			\
+	atomic_read(&libcfs_kmemory)
+
+
+#ifndef LIBCFS_VMALLOC_SIZE
+#define LIBCFS_VMALLOC_SIZE	(2 << PAGE_CACHE_SHIFT) /* 2 pages */
+#endif
+
+#define LIBCFS_ALLOC_PRE(size, mask)					    \
+do {									    \
+	LASSERT(!in_interrupt() ||					    \
+		((size) <= LIBCFS_VMALLOC_SIZE &&			    \
+		 ((mask) & GFP_ATOMIC)) != 0);			    \
+} while (0)
+
+#define LIBCFS_ALLOC_POST(ptr, size)					    \
+do {									    \
+	if (unlikely((ptr) == NULL)) {					    \
+		CERROR("LNET: out of memory at %s:%d (tried to alloc '"	    \
+		       #ptr "' = %d)\n", __FILE__, __LINE__, (int)(size));  \
+		CERROR("LNET: %d total bytes allocated by lnet\n",	    \
+		       libcfs_kmem_read());				    \
+	} else {							    \
+		memset((ptr), 0, (size));				    \
+		libcfs_kmem_inc((ptr), (size));				    \
+		CDEBUG(D_MALLOC, "alloc '" #ptr "': %d at %p (tot %d).\n",  \
+		       (int)(size), (ptr), libcfs_kmem_read());		    \
+	}								   \
+} while (0)
+
+/**
+ * allocate memory with GFP flags @mask
+ */
+#define LIBCFS_ALLOC_GFP(ptr, size, mask)				    \
+do {									    \
+	LIBCFS_ALLOC_PRE((size), (mask));				    \
+	(ptr) = (size) <= LIBCFS_VMALLOC_SIZE ?				    \
+		kmalloc((size), (mask)) : vmalloc(size);	    \
+	LIBCFS_ALLOC_POST((ptr), (size));				    \
+} while (0)
+
+/**
+ * default allocator
+ */
+#define LIBCFS_ALLOC(ptr, size) \
+	LIBCFS_ALLOC_GFP(ptr, size, __GFP_IO)
+
+/**
+ * non-sleeping allocator
+ */
+#define LIBCFS_ALLOC_ATOMIC(ptr, size) \
+	LIBCFS_ALLOC_GFP(ptr, size, GFP_ATOMIC)
+
+/**
+ * allocate memory for specified CPU partition
+ *   \a cptab != NULL, \a cpt is CPU partition id of \a cptab
+ *   \a cptab == NULL, \a cpt is HW NUMA node id
+ */
+#define LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, mask)		    \
+do {									    \
+	LIBCFS_ALLOC_PRE((size), (mask));				    \
+	(ptr) = (size) <= LIBCFS_VMALLOC_SIZE ?				    \
+		kmalloc_node((size), (mask), cfs_cpt_spread_node(cptab, cpt)) :\
+		vmalloc_node(size, cfs_cpt_spread_node(cptab, cpt));	    \
+	LIBCFS_ALLOC_POST((ptr), (size));				    \
+} while (0)
+
+/** default numa allocator */
+#define LIBCFS_CPT_ALLOC(ptr, cptab, cpt, size)				    \
+	LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, __GFP_IO)
+
+#define LIBCFS_FREE(ptr, size)					  \
+do {								    \
+	int s = (size);						 \
+	if (unlikely((ptr) == NULL)) {				  \
+		CERROR("LIBCFS: free NULL '" #ptr "' (%d bytes) at "    \
+		       "%s:%d\n", s, __FILE__, __LINE__);	       \
+		break;						  \
+	}							       \
+	libcfs_kmem_dec((ptr), s);				      \
+	CDEBUG(D_MALLOC, "kfreed '" #ptr "': %d at %p (tot %d).\n",     \
+	       s, (ptr), libcfs_kmem_read());				\
+	if (unlikely(s > LIBCFS_VMALLOC_SIZE))			  \
+		vfree(ptr);				    \
+	else							    \
+		kfree(ptr);					  \
+} while (0)
+
+/******************************************************************************/
+
+/* htonl hack - either this, or compile with -O2. Stupid byteorder/generic.h */
+#if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__)
+#define ___htonl(x) __cpu_to_be32(x)
+#define ___htons(x) __cpu_to_be16(x)
+#define ___ntohl(x) __be32_to_cpu(x)
+#define ___ntohs(x) __be16_to_cpu(x)
+#define htonl(x) ___htonl(x)
+#define ntohl(x) ___ntohl(x)
+#define htons(x) ___htons(x)
+#define ntohs(x) ___ntohs(x)
+#endif
+
+void libcfs_debug_dumpstack(task_t *tsk);
+void libcfs_run_upcall(char **argv);
+void libcfs_run_lbug_upcall(struct libcfs_debug_msg_data *);
+void libcfs_debug_dumplog(void);
+int libcfs_debug_init(unsigned long bufsize);
+int libcfs_debug_cleanup(void);
+int libcfs_debug_clear_buffer(void);
+int libcfs_debug_mark_buffer(const char *text);
+
+void libcfs_debug_set_level(unsigned int debug_level);
+
+
+/*
+ * allocate per-cpu-partition data, returned value is an array of pointers,
+ * variable can be indexed by CPU ID.
+ *	cptable != NULL: size of array is number of CPU partitions
+ *	cptable == NULL: size of array is number of HW cores
+ */
+void *cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size);
+/*
+ * destory per-cpu-partition variable
+ */
+void  cfs_percpt_free(void *vars);
+int   cfs_percpt_number(void *vars);
+void *cfs_percpt_current(void *vars);
+void *cfs_percpt_index(void *vars, int idx);
+
+#define cfs_percpt_for_each(var, i, vars)		\
+	for (i = 0; i < cfs_percpt_number(vars) &&	\
+		    ((var) = (vars)[i]) != NULL; i++)
+
+/*
+ * allocate a variable array, returned value is an array of pointers.
+ * Caller can specify length of array by count.
+ */
+void *cfs_array_alloc(int count, unsigned int size);
+void  cfs_array_free(void *vars);
+
+#define LASSERT_ATOMIC_ENABLED	  (1)
+
+#if LASSERT_ATOMIC_ENABLED
+
+/** assert value of @a is equal to @v */
+#define LASSERT_ATOMIC_EQ(a, v)				 \
+do {							    \
+	LASSERTF(atomic_read(a) == v,		       \
+		 "value: %d\n", atomic_read((a)));	  \
+} while (0)
+
+/** assert value of @a is unequal to @v */
+#define LASSERT_ATOMIC_NE(a, v)				 \
+do {							    \
+	LASSERTF(atomic_read(a) != v,		       \
+		 "value: %d\n", atomic_read((a)));	  \
+} while (0)
+
+/** assert value of @a is little than @v */
+#define LASSERT_ATOMIC_LT(a, v)				 \
+do {							    \
+	LASSERTF(atomic_read(a) < v,			\
+		 "value: %d\n", atomic_read((a)));	  \
+} while (0)
+
+/** assert value of @a is little/equal to @v */
+#define LASSERT_ATOMIC_LE(a, v)				 \
+do {							    \
+	LASSERTF(atomic_read(a) <= v,		       \
+		 "value: %d\n", atomic_read((a)));	  \
+} while (0)
+
+/** assert value of @a is great than @v */
+#define LASSERT_ATOMIC_GT(a, v)				 \
+do {							    \
+	LASSERTF(atomic_read(a) > v,			\
+		 "value: %d\n", atomic_read((a)));	  \
+} while (0)
+
+/** assert value of @a is great/equal to @v */
+#define LASSERT_ATOMIC_GE(a, v)				 \
+do {							    \
+	LASSERTF(atomic_read(a) >= v,		       \
+		 "value: %d\n", atomic_read((a)));	  \
+} while (0)
+
+/** assert value of @a is great than @v1 and little than @v2 */
+#define LASSERT_ATOMIC_GT_LT(a, v1, v2)			 \
+do {							    \
+	int __v = atomic_read(a);			   \
+	LASSERTF(__v > v1 && __v < v2, "value: %d\n", __v);     \
+} while (0)
+
+/** assert value of @a is great than @v1 and little/equal to @v2 */
+#define LASSERT_ATOMIC_GT_LE(a, v1, v2)			 \
+do {							    \
+	int __v = atomic_read(a);			   \
+	LASSERTF(__v > v1 && __v <= v2, "value: %d\n", __v);    \
+} while (0)
+
+/** assert value of @a is great/equal to @v1 and little than @v2 */
+#define LASSERT_ATOMIC_GE_LT(a, v1, v2)			 \
+do {							    \
+	int __v = atomic_read(a);			   \
+	LASSERTF(__v >= v1 && __v < v2, "value: %d\n", __v);    \
+} while (0)
+
+/** assert value of @a is great/equal to @v1 and little/equal to @v2 */
+#define LASSERT_ATOMIC_GE_LE(a, v1, v2)			 \
+do {							    \
+	int __v = atomic_read(a);			   \
+	LASSERTF(__v >= v1 && __v <= v2, "value: %d\n", __v);   \
+} while (0)
+
+#else /* !LASSERT_ATOMIC_ENABLED */
+
+#define LASSERT_ATOMIC_EQ(a, v)		 do {} while (0)
+#define LASSERT_ATOMIC_NE(a, v)		 do {} while (0)
+#define LASSERT_ATOMIC_LT(a, v)		 do {} while (0)
+#define LASSERT_ATOMIC_LE(a, v)		 do {} while (0)
+#define LASSERT_ATOMIC_GT(a, v)		 do {} while (0)
+#define LASSERT_ATOMIC_GE(a, v)		 do {} while (0)
+#define LASSERT_ATOMIC_GT_LT(a, v1, v2)	 do {} while (0)
+#define LASSERT_ATOMIC_GT_LE(a, v1, v2)	 do {} while (0)
+#define LASSERT_ATOMIC_GE_LT(a, v1, v2)	 do {} while (0)
+#define LASSERT_ATOMIC_GE_LE(a, v1, v2)	 do {} while (0)
+
+#endif /* LASSERT_ATOMIC_ENABLED */
+
+#define LASSERT_ATOMIC_ZERO(a)		  LASSERT_ATOMIC_EQ(a, 0)
+#define LASSERT_ATOMIC_POS(a)		   LASSERT_ATOMIC_GT(a, 0)
+
+#define CFS_ALLOC_PTR(ptr)      LIBCFS_ALLOC(ptr, sizeof (*(ptr)));
+#define CFS_FREE_PTR(ptr)       LIBCFS_FREE(ptr, sizeof (*(ptr)));
+
+/*
+ * percpu partition lock
+ *
+ * There are some use-cases like this in Lustre:
+ * . each CPU partition has it's own private data which is frequently changed,
+ *   and mostly by the local CPU partition.
+ * . all CPU partitions share some global data, these data are rarely changed.
+ *
+ * LNet is typical example.
+ * CPU partition lock is designed for this kind of use-cases:
+ * . each CPU partition has it's own private lock
+ * . change on private data just needs to take the private lock
+ * . read on shared data just needs to take _any_ of private locks
+ * . change on shared data needs to take _all_ private locks,
+ *   which is slow and should be really rare.
+ */
+
+enum {
+	CFS_PERCPT_LOCK_EX	= -1, /* negative */
+};
+
+
+struct cfs_percpt_lock {
+	/* cpu-partition-table for this lock */
+	struct cfs_cpt_table	*pcl_cptab;
+	/* exclusively locked */
+	unsigned int		pcl_locked;
+	/* private lock table */
+	spinlock_t		**pcl_locks;
+};
+
+/* return number of private locks */
+static inline int
+cfs_percpt_lock_num(struct cfs_percpt_lock *pcl)
+{
+	return cfs_cpt_number(pcl->pcl_cptab);
+}
+
+
+/*
+ * create a cpu-partition lock based on CPU partition table \a cptab,
+ * each private lock has extra \a psize bytes padding data
+ */
+struct cfs_percpt_lock *cfs_percpt_lock_alloc(struct cfs_cpt_table *cptab);
+/* destroy a cpu-partition lock */
+void cfs_percpt_lock_free(struct cfs_percpt_lock *pcl);
+
+/* lock private lock \a index of \a pcl */
+void cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index);
+/* unlock private lock \a index of \a pcl */
+void cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index);
+/* create percpt (atomic) refcount based on @cptab */
+atomic_t **cfs_percpt_atomic_alloc(struct cfs_cpt_table *cptab, int val);
+/* destroy percpt refcount */
+void cfs_percpt_atomic_free(atomic_t **refs);
+/* return sum of all percpu refs */
+int cfs_percpt_atomic_summary(atomic_t **refs);
+
+
+/** Compile-time assertion.
+
+ * Check an invariant described by a constant expression at compile time by
+ * forcing a compiler error if it does not hold.  \a cond must be a constant
+ * expression as defined by the ISO C Standard:
+ *
+ *       6.8.4.2  The switch statement
+ *       ....
+ *       [#3] The expression of each case label shall be  an  integer
+ *       constant   expression  and  no  two  of  the  case  constant
+ *       expressions in the same switch statement shall have the same
+ *       value  after  conversion...
+ *
+ */
+#define CLASSERT(cond) do {switch(42) {case (cond): case 0: break;}} while (0)
+
+/* support decl needed both by kernel and liblustre */
+int	 libcfs_isknown_lnd(int type);
+char       *libcfs_lnd2modname(int type);
+char       *libcfs_lnd2str(int type);
+int	 libcfs_str2lnd(const char *str);
+char       *libcfs_net2str(__u32 net);
+char       *libcfs_nid2str(lnet_nid_t nid);
+__u32       libcfs_str2net(const char *str);
+lnet_nid_t  libcfs_str2nid(const char *str);
+int	 libcfs_str2anynid(lnet_nid_t *nid, const char *str);
+char       *libcfs_id2str(lnet_process_id_t id);
+void	cfs_free_nidlist(struct list_head *list);
+int	 cfs_parse_nidlist(char *str, int len, struct list_head *list);
+int	 cfs_match_nid(lnet_nid_t nid, struct list_head *list);
+
+/** \addtogroup lnet_addr
+ * @{ */
+/* how an LNET NID encodes net:address */
+/** extract the address part of an lnet_nid_t */
+#define LNET_NIDADDR(nid)      ((__u32)((nid) & 0xffffffff))
+/** extract the network part of an lnet_nid_t */
+#define LNET_NIDNET(nid)       ((__u32)(((nid) >> 32)) & 0xffffffff)
+/** make an lnet_nid_t from a network part and an address part */
+#define LNET_MKNID(net,addr)   ((((__u64)(net))<<32)|((__u64)(addr)))
+/* how net encodes type:number */
+#define LNET_NETNUM(net)       ((net) & 0xffff)
+#define LNET_NETTYP(net)       (((net) >> 16) & 0xffff)
+#define LNET_MKNET(typ,num)    ((((__u32)(typ))<<16)|((__u32)(num)))
+/** @} lnet_addr */
+
+/* max value for numeric network address */
+#define MAX_NUMERIC_VALUE 0xffffffff
+
+/* implication */
+#define ergo(a, b) (!(a) || (b))
+/* logical equivalence */
+#define equi(a, b) (!!(a) == !!(b))
+
+#ifndef CFS_CURRENT_TIME
+# define CFS_CURRENT_TIME time(0)
+#endif
+
+/* --------------------------------------------------------------------
+ * Light-weight trace
+ * Support for temporary event tracing with minimal Heisenberg effect.
+ * All stuff about lwt are put in arch/kp30.h
+ * -------------------------------------------------------------------- */
+
+struct libcfs_device_userstate
+{
+	int	   ldu_memhog_pages;
+	struct page   *ldu_memhog_root_page;
+};
+
+/* what used to be in portals_lib.h */
+#ifndef MIN
+# define MIN(a,b) (((a)<(b)) ? (a): (b))
+#endif
+#ifndef MAX
+# define MAX(a,b) (((a)>(b)) ? (a): (b))
+#endif
+
+#define MKSTR(ptr) ((ptr))? (ptr) : ""
+
+static inline int cfs_size_round4 (int val)
+{
+	return (val + 3) & (~0x3);
+}
+
+#ifndef HAVE_CFS_SIZE_ROUND
+static inline int cfs_size_round (int val)
+{
+	return (val + 7) & (~0x7);
+}
+#define HAVE_CFS_SIZE_ROUND
+#endif
+
+static inline int cfs_size_round16(int val)
+{
+	return (val + 0xf) & (~0xf);
+}
+
+static inline int cfs_size_round32(int val)
+{
+	return (val + 0x1f) & (~0x1f);
+}
+
+static inline int cfs_size_round0(int val)
+{
+	if (!val)
+		return 0;
+	return (val + 1 + 7) & (~0x7);
+}
+
+static inline size_t cfs_round_strlen(char *fset)
+{
+	return (size_t)cfs_size_round((int)strlen(fset) + 1);
+}
+
+/* roundup \a val to power2 */
+static inline unsigned int cfs_power2_roundup(unsigned int val)
+{
+	if (val != LOWEST_BIT_SET(val)) { /* not a power of 2 already */
+		do {
+			val &= ~LOWEST_BIT_SET(val);
+		} while (val != LOWEST_BIT_SET(val));
+		/* ...and round up */
+		val <<= 1;
+	}
+	return val;
+}
+
+#define LOGL(var,len,ptr)				       \
+do {							    \
+	if (var)						\
+		memcpy((char *)ptr, (const char *)var, len);    \
+	ptr += cfs_size_round(len);			     \
+} while (0)
+
+#define LOGU(var,len,ptr)				       \
+do {							    \
+	if (var)						\
+		memcpy((char *)var, (const char *)ptr, len);    \
+	ptr += cfs_size_round(len);			     \
+} while (0)
+
+#define LOGL0(var,len,ptr)			      \
+do {						    \
+	if (!len)				       \
+		break;				  \
+	memcpy((char *)ptr, (const char *)var, len);    \
+	*((char *)(ptr) + len) = 0;		     \
+	ptr += cfs_size_round(len + 1);		 \
+} while (0)
+
+/**
+ *  Lustre Network Driver types.
+ */
+enum {
+	/* Only add to these values (i.e. don't ever change or redefine them):
+	 * network addresses depend on them... */
+	QSWLND    = 1,
+	SOCKLND   = 2,
+	GMLND     = 3, /* obsolete, keep it so that libcfs_nid2str works */
+	PTLLND    = 4,
+	O2IBLND   = 5,
+	CIBLND    = 6,
+	OPENIBLND = 7,
+	IIBLND    = 8,
+	LOLND     = 9,
+	RALND     = 10,
+	VIBLND    = 11,
+	MXLND     = 12,
+	GNILND    = 13,
+};
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,137 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_string.h
+ *
+ * Generic string manipulation functions.
+ *
+ * Author: Nathan Rutman <nathan.rutman@sun.com>
+ */
+
+#ifndef __LIBCFS_STRING_H__
+#define __LIBCFS_STRING_H__
+
+/* libcfs_string.c */
+/* string comparison ignoring case */
+int cfs_strncasecmp(const char *s1, const char *s2, size_t n);
+/* Convert a text string to a bitmask */
+int cfs_str2mask(const char *str, const char *(*bit2str)(int bit),
+		 int *oldmask, int minmask, int allmask);
+
+/* Allocate space for and copy an existing string.
+ * Must free with kfree().
+ */
+char *cfs_strdup(const char *str, u_int32_t flags);
+
+/* safe vsnprintf */
+int cfs_vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
+
+/* safe snprintf */
+int cfs_snprintf(char *buf, size_t size, const char *fmt, ...);
+
+/* trim leading and trailing space characters */
+char *cfs_firststr(char *str, size_t size);
+
+/**
+ * Structure to represent NULL-less strings.
+ */
+struct cfs_lstr {
+	char		*ls_str;
+	int		ls_len;
+};
+
+/*
+ * Structure to represent \<range_expr\> token of the syntax.
+ */
+struct cfs_range_expr {
+	/*
+	 * Link to cfs_expr_list::el_exprs.
+	 */
+	struct list_head	re_link;
+	__u32		re_lo;
+	__u32		re_hi;
+	__u32		re_stride;
+};
+
+struct cfs_expr_list {
+	struct list_head	el_link;
+	struct list_head	el_exprs;
+};
+
+static inline int
+cfs_iswhite(char c)
+{
+	switch (c) {
+	case ' ':
+	case '\t':
+	case '\n':
+	case '\r':
+		return 1;
+	default:
+		break;
+	}
+	return 0;
+}
+
+char *cfs_trimwhite(char *str);
+int cfs_gettok(struct cfs_lstr *next, char delim, struct cfs_lstr *res);
+int cfs_str2num_check(char *str, int nob, unsigned *num,
+		      unsigned min, unsigned max);
+int cfs_range_expr_parse(struct cfs_lstr *src, unsigned min, unsigned max,
+			 int single_tok, struct cfs_range_expr **expr);
+int cfs_expr_list_match(__u32 value, struct cfs_expr_list *expr_list);
+int cfs_expr_list_values(struct cfs_expr_list *expr_list,
+			 int max, __u32 **values);
+static inline void
+cfs_expr_list_values_free(__u32 *values, int num)
+{
+	/* This array is allocated by LIBCFS_ALLOC(), so it shouldn't be freed
+	 * by OBD_FREE() if it's called by module other than libcfs & LNet,
+	 * otherwise we will see fake memory leak */
+	LIBCFS_FREE(values, num * sizeof(values[0]));
+}
+
+void cfs_expr_list_free(struct cfs_expr_list *expr_list);
+void cfs_expr_list_print(struct cfs_expr_list *expr_list);
+int cfs_expr_list_parse(char *str, int len, unsigned min, unsigned max,
+			struct cfs_expr_list **elpp);
+void cfs_expr_list_free_list(struct list_head *list);
+int cfs_ip_addr_parse(char *str, int len, struct list_head *list);
+int cfs_ip_addr_match(__u32 addr, struct list_head *list);
+void cfs_ip_addr_free(struct list_head *list);
+
+#define	strtoul(str, endp, base)	simple_strtoul(str, endp, base)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,132 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_time.h
+ *
+ * Time functions.
+ *
+ */
+
+#ifndef __LIBCFS_TIME_H__
+#define __LIBCFS_TIME_H__
+/*
+ * generic time manipulation functions.
+ */
+
+static inline cfs_time_t cfs_time_add(cfs_time_t t, cfs_duration_t d)
+{
+	return (cfs_time_t)(t + d);
+}
+
+static inline cfs_duration_t cfs_time_sub(cfs_time_t t1, cfs_time_t t2)
+{
+	return (cfs_time_t)(t1 - t2);
+}
+
+static inline int cfs_time_after(cfs_time_t t1, cfs_time_t t2)
+{
+	return cfs_time_before(t2, t1);
+}
+
+static inline int cfs_time_aftereq(cfs_time_t t1, cfs_time_t t2)
+{
+	return cfs_time_beforeq(t2, t1);
+}
+
+
+static inline cfs_time_t cfs_time_shift(int seconds)
+{
+	return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds));
+}
+
+static inline long cfs_timeval_sub(struct timeval *large, struct timeval *small,
+				   struct timeval *result)
+{
+	long r = (long) (
+		(large->tv_sec - small->tv_sec) * ONE_MILLION +
+		(large->tv_usec - small->tv_usec));
+	if (result != NULL) {
+		result->tv_usec = r % ONE_MILLION;
+		result->tv_sec = r / ONE_MILLION;
+	}
+	return r;
+}
+
+static inline void cfs_slow_warning(cfs_time_t now, int seconds, char *msg)
+{
+	if (cfs_time_after(cfs_time_current(),
+			   cfs_time_add(now, cfs_time_seconds(15))))
+		CERROR("slow %s "CFS_TIME_T" sec\n", msg,
+		       cfs_duration_sec(cfs_time_sub(cfs_time_current(),now)));
+}
+
+#define CFS_RATELIMIT(seconds)				  \
+({							      \
+	/*						      \
+	 * XXX nikita: non-portable initializer		 \
+	 */						     \
+	static time_t __next_message = 0;		       \
+	int result;					     \
+								\
+	if (cfs_time_after(cfs_time_current(), __next_message)) \
+		result = 1;				     \
+	else {						  \
+		__next_message = cfs_time_shift(seconds);       \
+		result = 0;				     \
+	}						       \
+	result;						 \
+})
+
+/*
+ * helper function similar to do_gettimeofday() of Linux kernel
+ */
+static inline void cfs_fs_timeval(struct timeval *tv)
+{
+	cfs_fs_time_t time;
+
+	cfs_fs_time_current(&time);
+	cfs_fs_time_usec(&time, tv);
+}
+
+/*
+ * return valid time-out based on user supplied one. Currently we only check
+ * that time-out is not shorted than allowed.
+ */
+static inline cfs_duration_t cfs_timeout_cap(cfs_duration_t timeout)
+{
+	if (timeout < CFS_TICK)
+		timeout = CFS_TICK;
+	return timeout;
+}
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_workitem.h
+ *
+ * Author: Isaac Huang  <he.h.huang@oracle.com>
+ *	 Liang Zhen   <zhen.liang@sun.com>
+ *
+ * A workitems is deferred work with these semantics:
+ * - a workitem always runs in thread context.
+ * - a workitem can be concurrent with other workitems but is strictly
+ *   serialized with respect to itself.
+ * - no CPU affinity, a workitem does not necessarily run on the same CPU
+ *   that schedules it. However, this might change in the future.
+ * - if a workitem is scheduled again before it has a chance to run, it
+ *   runs only once.
+ * - if a workitem is scheduled while it runs, it runs again after it
+ *   completes; this ensures that events occurring while other events are
+ *   being processed receive due attention. This behavior also allows a
+ *   workitem to reschedule itself.
+ *
+ * Usage notes:
+ * - a workitem can sleep but it should be aware of how that sleep might
+ *   affect others.
+ * - a workitem runs inside a kernel thread so there's no user space to access.
+ * - do not use a workitem if the scheduling latency can't be tolerated.
+ *
+ * When wi_action returns non-zero, it means the workitem has either been
+ * freed or reused and workitem scheduler won't touch it any more.
+ */
+
+#ifndef __LIBCFS_WORKITEM_H__
+#define __LIBCFS_WORKITEM_H__
+
+struct cfs_wi_sched;
+
+void cfs_wi_sched_destroy(struct cfs_wi_sched *);
+int cfs_wi_sched_create(char *name, struct cfs_cpt_table *cptab, int cpt,
+			int nthrs, struct cfs_wi_sched **);
+
+struct cfs_workitem;
+
+typedef int (*cfs_wi_action_t) (struct cfs_workitem *);
+typedef struct cfs_workitem {
+	/** chain on runq or rerunq */
+	struct list_head       wi_list;
+	/** working function */
+	cfs_wi_action_t  wi_action;
+	/** arg for working function */
+	void	    *wi_data;
+	/** in running */
+	unsigned short   wi_running:1;
+	/** scheduled */
+	unsigned short   wi_scheduled:1;
+} cfs_workitem_t;
+
+static inline void
+cfs_wi_init(cfs_workitem_t *wi, void *data, cfs_wi_action_t action)
+{
+	INIT_LIST_HEAD(&wi->wi_list);
+
+	wi->wi_running   = 0;
+	wi->wi_scheduled = 0;
+	wi->wi_data      = data;
+	wi->wi_action    = action;
+}
+
+void cfs_wi_schedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi);
+int  cfs_wi_deschedule(struct cfs_wi_sched *sched, cfs_workitem_t *wi);
+void cfs_wi_exit(struct cfs_wi_sched *sched, cfs_workitem_t *wi);
+
+int  cfs_wi_startup(void);
+void cfs_wi_shutdown(void);
+
+/** # workitem scheduler loops before reschedule */
+#define CFS_WI_RESCHED    128
+
+#endif /* __LIBCFS_WORKITEM_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/kp30.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,286 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LIBCFS_LINUX_KP30_H__
+#define __LIBCFS_LINUX_KP30_H__
+
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/kmod.h>
+#include <linux/notifier.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/time.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <asm/atomic.h>
+#include <asm/uaccess.h>
+#include <linux/rwsem.h>
+#include <linux/proc_fs.h>
+#include <linux/file.h>
+#include <linux/smp.h>
+#include <linux/ctype.h>
+#include <linux/compiler.h>
+#ifdef HAVE_MM_INLINE
+# include <linux/mm_inline.h>
+#endif
+#include <linux/kallsyms.h>
+#include <linux/moduleparam.h>
+#include <linux/scatterlist.h>
+
+#include <linux/libcfs/linux/portals_compat25.h>
+
+
+#define prepare_work(wq,cb,cbdata)					    \
+do {									  \
+	INIT_WORK((wq), (void *)(cb));					\
+} while (0)
+
+#define cfs_get_work_data(type,field,data) container_of(data,type,field)
+
+
+#define our_recalc_sigpending(current) recalc_sigpending()
+#define strtok(a,b) strpbrk(a, b)
+#define work_struct_t      struct work_struct
+
+#ifdef CONFIG_SMP
+#else
+#endif
+
+
+#define SEM_COUNT(sem)	  ((sem)->count)
+
+
+/* ------------------------------------------------------------------- */
+
+#define PORTAL_SYMBOL_REGISTER(x)
+#define PORTAL_SYMBOL_UNREGISTER(x)
+
+
+
+
+/******************************************************************************/
+/* Module parameter support */
+#define CFS_MODULE_PARM(name, t, type, perm, desc) \
+	module_param(name, type, perm);\
+	MODULE_PARM_DESC(name, desc)
+
+#define CFS_SYSFS_MODULE_PARM  1 /* module parameters accessible via sysfs */
+
+/******************************************************************************/
+
+#if (__GNUC__)
+/* Use the special GNU C __attribute__ hack to have the compiler check the
+ * printf style argument string against the actual argument count and
+ * types.
+ */
+#ifdef printf
+# warning printf has been defined as a macro...
+# undef printf
+#endif
+
+#endif /* __GNUC__ */
+
+# define fprintf(a, format, b...) CDEBUG(D_OTHER, format , ## b)
+# define printf(format, b...) CDEBUG(D_OTHER, format , ## b)
+# define time(a) CURRENT_TIME
+
+# define cfs_num_present_cpus()  num_present_cpus()
+
+/******************************************************************************/
+/* Light-weight trace
+ * Support for temporary event tracing with minimal Heisenberg effect. */
+#define LWT_SUPPORT  0
+
+#define LWT_MEMORY   (16<<20)
+
+#ifndef KLWT_SUPPORT
+#  if !defined(BITS_PER_LONG)
+#   error "BITS_PER_LONG not defined"
+#  endif
+
+/* kernel hasn't defined this? */
+typedef struct {
+	long long   lwte_when;
+	char       *lwte_where;
+	void       *lwte_task;
+	long	lwte_p1;
+	long	lwte_p2;
+	long	lwte_p3;
+	long	lwte_p4;
+# if BITS_PER_LONG > 32
+	long	lwte_pad;
+# endif
+} lwt_event_t;
+#endif /* !KLWT_SUPPORT */
+
+#if LWT_SUPPORT
+#  if !KLWT_SUPPORT
+
+typedef struct _lwt_page {
+	struct list_head	       lwtp_list;
+	struct page	     *lwtp_page;
+	lwt_event_t	     *lwtp_events;
+} lwt_page_t;
+
+typedef struct {
+	int		lwtc_current_index;
+	lwt_page_t	*lwtc_current_page;
+} lwt_cpu_t;
+
+extern int       lwt_enabled;
+extern lwt_cpu_t lwt_cpus[];
+
+/* Note that we _don't_ define LWT_EVENT at all if LWT_SUPPORT isn't set.
+ * This stuff is meant for finding specific problems; it never stays in
+ * production code... */
+
+#define LWTSTR(n)       #n
+#define LWTWHERE(f,l)   f ":" LWTSTR(l)
+#define LWT_EVENTS_PER_PAGE (PAGE_CACHE_SIZE / sizeof (lwt_event_t))
+
+#define LWT_EVENT(p1, p2, p3, p4)				       \
+do {								    \
+	unsigned long    flags;					 \
+	lwt_cpu_t       *cpu;					   \
+	lwt_page_t      *p;					     \
+	lwt_event_t     *e;					     \
+									\
+	if (lwt_enabled) {					      \
+		local_irq_save (flags);				 \
+									\
+		cpu = &lwt_cpus[smp_processor_id()];		    \
+		p = cpu->lwtc_current_page;			     \
+		e = &p->lwtp_events[cpu->lwtc_current_index++];	 \
+									\
+		if (cpu->lwtc_current_index >= LWT_EVENTS_PER_PAGE) {   \
+			cpu->lwtc_current_page =			\
+				list_entry (p->lwtp_list.next,      \
+						lwt_page_t, lwtp_list); \
+			cpu->lwtc_current_index = 0;		    \
+		}						       \
+									\
+		e->lwte_when  = get_cycles();			   \
+		e->lwte_where = LWTWHERE(__FILE__,__LINE__);	    \
+		e->lwte_task  = current;				\
+		e->lwte_p1    = (long)(p1);			     \
+		e->lwte_p2    = (long)(p2);			     \
+		e->lwte_p3    = (long)(p3);			     \
+		e->lwte_p4    = (long)(p4);			     \
+									\
+		local_irq_restore (flags);			      \
+	}							       \
+} while (0)
+
+#endif /* !KLWT_SUPPORT */
+
+extern int  lwt_init (void);
+extern void lwt_fini (void);
+extern int  lwt_lookup_string (int *size, char *knlptr,
+			       char *usrptr, int usrsize);
+extern int  lwt_control (int enable, int clear);
+extern int  lwt_snapshot (cfs_cycles_t *now, int *ncpu, int *total_size,
+			  void *user_ptr, int user_size);
+#endif /* LWT_SUPPORT */
+
+/* ------------------------------------------------------------------ */
+
+#define IOCTL_LIBCFS_TYPE long
+
+#ifdef __CYGWIN__
+# ifndef BITS_PER_LONG
+#   define BITS_PER_LONG 64
+# endif
+#endif
+
+# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
+# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a)
+
+/* this is a bit chunky */
+
+#define _LWORDSIZE BITS_PER_LONG
+
+# define LPU64 "%llu"
+# define LPD64 "%lld"
+# define LPX64 "%#llx"
+# define LPX64i "%llx"
+# define LPO64 "%#llo"
+# define LPF64 "L"
+
+/*
+ * long_ptr_t & ulong_ptr_t, same to "long" for gcc
+ */
+# define LPLU "%lu"
+# define LPLD "%ld"
+# define LPLX "%#lx"
+
+/*
+ * pid_t
+ */
+# define LPPID "%d"
+
+
+#undef _LWORDSIZE
+
+/* compat macroses */
+
+
+#ifndef get_cpu
+# ifdef CONFIG_PREEMPT
+#  define get_cpu()  ({ preempt_disable(); smp_processor_id(); })
+#  define put_cpu()  preempt_enable()
+# else
+#  define get_cpu()  smp_processor_id()
+#  define put_cpu()
+# endif
+#else
+#endif /* get_cpu & put_cpu */
+
+#define INIT_CTL_NAME(a)
+#define INIT_STRATEGY(a)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/libcfs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,125 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LIBCFS_LINUX_LIBCFS_H__
+#define __LIBCFS_LINUX_LIBCFS_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
+#endif
+
+
+
+#include <stdarg.h>
+#include <linux/libcfs/linux/linux-cpu.h>
+#include <linux/libcfs/linux/linux-time.h>
+#include <linux/libcfs/linux/linux-mem.h>
+#include <linux/libcfs/linux/linux-prim.h>
+#include <linux/libcfs/linux/linux-lock.h>
+#include <linux/libcfs/linux/linux-fs.h>
+#include <linux/libcfs/linux/linux-tcpip.h>
+#include <linux/libcfs/linux/linux-bitops.h>
+#include <linux/libcfs/linux/linux-types.h>
+#include <linux/libcfs/linux/kp30.h>
+
+#include <asm/types.h>
+#include <linux/types.h>
+#include <asm/timex.h>
+#include <linux/sched.h> /* THREAD_SIZE */
+#include <linux/rbtree.h>
+
+#define LUSTRE_TRACE_SIZE (THREAD_SIZE >> 5)
+
+#if !defined(__x86_64__)
+# ifdef  __ia64__
+#  define CDEBUG_STACK() (THREAD_SIZE -				 \
+			  ((unsigned long)__builtin_dwarf_cfa() &       \
+			   (THREAD_SIZE - 1)))
+# else
+#  define CDEBUG_STACK() (THREAD_SIZE -				 \
+			  ((unsigned long)__builtin_frame_address(0) &  \
+			   (THREAD_SIZE - 1)))
+# endif /* __ia64__ */
+
+#define __CHECK_STACK(msgdata, mask, cdls)			      \
+do {								    \
+	if (unlikely(CDEBUG_STACK() > libcfs_stack)) {		  \
+		LIBCFS_DEBUG_MSG_DATA_INIT(msgdata, D_WARNING, NULL);   \
+		libcfs_stack = CDEBUG_STACK();			  \
+		libcfs_debug_msg(msgdata,			       \
+				 "maximum lustre stack %lu\n",	  \
+				 CDEBUG_STACK());		       \
+		(msgdata)->msg_mask = mask;			     \
+		(msgdata)->msg_cdls = cdls;			     \
+		dump_stack();					   \
+	      /*panic("LBUG");*/					\
+	}							       \
+} while (0)
+#define CFS_CHECK_STACK(msgdata, mask, cdls)  __CHECK_STACK(msgdata, mask, cdls)
+#else /* __x86_64__ */
+#define CFS_CHECK_STACK(msgdata, mask, cdls) do {} while(0)
+#define CDEBUG_STACK() (0L)
+#endif /* __x86_64__ */
+
+/* initial pid  */
+#define LUSTRE_LNET_PID	  12345
+
+#define ENTRY_NESTING_SUPPORT (1)
+#define ENTRY_NESTING   do {;} while (0)
+#define EXIT_NESTING   do {;} while (0)
+#define __current_nesting_level() (0)
+
+/**
+ * Platform specific declarations for cfs_curproc API (libcfs/curproc.h)
+ *
+ * Implementation is in linux-curproc.c
+ */
+#define CFS_CURPROC_COMM_MAX (sizeof ((struct task_struct *)0)->comm)
+
+#include <linux/capability.h>
+
+/* long integer with size equal to pointer */
+typedef unsigned long ulong_ptr_t;
+typedef long long_ptr_t;
+
+#ifndef WITH_WATCHDOG
+#define WITH_WATCHDOG
+#endif
+
+
+
+
+#endif /* _LINUX_LIBCFS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-bitops.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-bitops.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-bitops.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-bitops.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/linux/linux-bitops.h
+ */
+#include <linux/bitops.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,175 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/linux/linux-mem.h
+ *
+ * Basic library routines.
+ *
+ * Author: liang@whamcloud.com
+ */
+
+#ifndef __LIBCFS_LINUX_CPU_H__
+#define __LIBCFS_LINUX_CPU_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
+#endif
+
+
+#include <linux/cpu.h>
+#include <linux/cpuset.h>
+#include <linux/topology.h>
+#include <linux/version.h>
+
+
+#ifdef CONFIG_SMP
+
+#define HAVE_LIBCFS_CPT
+
+/** virtual processing unit */
+struct cfs_cpu_partition {
+	/* CPUs mask for this partition */
+	cpumask_t			*cpt_cpumask;
+	/* nodes mask for this partition */
+	nodemask_t			*cpt_nodemask;
+	/* spread rotor for NUMA allocator */
+	unsigned			cpt_spread_rotor;
+};
+
+/** descriptor for CPU partitions */
+struct cfs_cpt_table {
+	/* version, reserved for hotplug */
+	unsigned			ctb_version;
+	/* spread rotor for NUMA allocator */
+	unsigned			ctb_spread_rotor;
+	/* # of CPU partitions */
+	unsigned			ctb_nparts;
+	/* partitions tables */
+	struct cfs_cpu_partition	*ctb_parts;
+	/* shadow HW CPU to CPU partition ID */
+	int				*ctb_cpu2cpt;
+	/* all cpus in this partition table */
+	cpumask_t			*ctb_cpumask;
+	/* all nodes in this partition table */
+	nodemask_t			*ctb_nodemask;
+};
+
+void cfs_cpu_core_siblings(int cpu, cpumask_t *mask);
+void cfs_cpu_ht_siblings(int cpu, cpumask_t *mask);
+void cfs_node_to_cpumask(int node, cpumask_t *mask);
+int cfs_cpu_core_nsiblings(int cpu);
+int cfs_cpu_ht_nsiblings(int cpu);
+
+/**
+ * comment out definitions for compatible layer
+ * #define CFS_CPU_NR			  NR_CPUS
+ *
+ * typedef cpumask_t			   cfs_cpumask_t;
+ *
+ * #define cfs_cpu_current()		   smp_processor_id()
+ * #define cfs_cpu_online(i)		   cpu_online(i)
+ * #define cfs_cpu_online_num()		num_online_cpus()
+ * #define cfs_cpu_online_for_each(i)	  for_each_online_cpu(i)
+ * #define cfs_cpu_possible_num()	      num_possible_cpus()
+ * #define cfs_cpu_possible_for_each(i)	for_each_possible_cpu(i)
+ *
+ * #ifdef CONFIG_CPUMASK_SIZE
+ * #define cfs_cpu_mask_size()		 cpumask_size()
+ * #else
+ * #define cfs_cpu_mask_size()		 sizeof(cfs_cpumask_t)
+ * #endif
+ *
+ * #define cfs_cpu_mask_set(i, mask)	   cpu_set(i, mask)
+ * #define cfs_cpu_mask_unset(i, mask)	 cpu_clear(i, mask)
+ * #define cfs_cpu_mask_isset(i, mask)	 cpu_isset(i, mask)
+ * #define cfs_cpu_mask_clear(mask)	    cpus_clear(mask)
+ * #define cfs_cpu_mask_empty(mask)	    cpus_empty(mask)
+ * #define cfs_cpu_mask_weight(mask)	   cpus_weight(mask)
+ * #define cfs_cpu_mask_first(mask)	    first_cpu(mask)
+ * #define cfs_cpu_mask_any_online(mask)      (any_online_cpu(mask) != NR_CPUS)
+ * #define cfs_cpu_mask_for_each(i, mask)      for_each_cpu_mask(i, mask)
+ * #define cfs_cpu_mask_bind(t, mask)	  set_cpus_allowed(t, mask)
+ *
+ * #ifdef HAVE_CPUMASK_COPY
+ * #define cfs_cpu_mask_copy(dst, src)	 cpumask_copy(dst, src)
+ * #else
+ * #define cfs_cpu_mask_copy(dst, src)	 memcpy(dst, src, sizeof(*src))
+ * #endif
+ *
+ * static inline void
+ * cfs_cpu_mask_of_online(cfs_cpumask_t *mask)
+ * {
+ * cfs_cpu_mask_copy(mask, &cpu_online_map);
+ * }
+ *
+ * #ifdef CONFIG_NUMA
+ *
+ * #define CFS_NODE_NR			 MAX_NUMNODES
+ *
+ * typedef nodemask_t			  cfs_node_mask_t;
+ *
+ * #define cfs_node_of_cpu(cpu)		cpu_to_node(cpu)
+ * #define cfs_node_online(i)		  node_online(i)
+ * #define cfs_node_online_num()	       num_online_nodes()
+ * #define cfs_node_online_for_each(i)	 for_each_online_node(i)
+ * #define cfs_node_possible_num()	     num_possible_nodes()
+ * #define cfs_node_possible_for_each(i)       for_each_node(i)
+ *
+ * static inline void cfs_node_to_cpumask(int node, cfs_cpumask_t *mask)
+ * {
+ * #if defined(HAVE_NODE_TO_CPUMASK)
+ *      *mask = node_to_cpumask(node);
+ * #elif defined(HAVE_CPUMASK_OF_NODE)
+ *      cfs_cpu_mask_copy(mask, cpumask_of_node(node));
+ * #else
+ * # error "Needs node_to_cpumask or cpumask_of_node"
+ * #endif
+ * }
+ *
+ * #define cfs_node_mask_set(i, mask)	  node_set(i, mask)
+ * #define cfs_node_mask_unset(i, mask)	node_clear(i, mask)
+ * #define cfs_node_mask_isset(i, mask)	node_isset(i, mask)
+ * #define cfs_node_mask_clear(mask)	   nodes_reset(mask)
+ * #define cfs_node_mask_empty(mask)	   nodes_empty(mask)
+ * #define cfs_node_mask_weight(mask)	  nodes_weight(mask)
+ * #define cfs_node_mask_for_each(i, mask)     for_each_node_mask(i, mask)
+ * #define cfs_node_mask_copy(dst, src)	memcpy(dst, src, sizeof(*src))
+ *
+ * static inline void
+ * cfs_node_mask_of_online(cfs_node_mask_t *mask)
+ * {
+ *       cfs_node_mask_copy(mask, &node_online_map);
+ * }
+ *
+ * #endif
+ */
+
+#endif /* CONFIG_SMP */
+#endif /* __LIBCFS_LINUX_CPU_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-crypto.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-crypto.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-crypto.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-crypto.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,49 @@
+ /*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see http://www.gnu.org/licenses
+ *
+ * Please  visit http://www.xyratex.com/contact if you need additional
+ * information or have any questions.
+ *
+ * GPL HEADER END
+ */
+
+/*
+ * Copyright 2012 Xyratex Technology Limited
+ */
+
+/**
+ * Linux crypto hash specific functions.
+ */
+
+/**
+ * Functions for start/stop shash CRC32 algorithm.
+ */
+int cfs_crypto_crc32_register(void);
+void cfs_crypto_crc32_unregister(void);
+
+/**
+ * Functions for start/stop shash adler32 algorithm.
+ */
+int cfs_crypto_adler32_register(void);
+void cfs_crypto_adler32_unregister(void);
+
+/**
+ * Functions for start/stop shash crc32 pclmulqdq
+ */
+int cfs_crypto_crc32_pclmul_register(void);
+void cfs_crypto_crc32_pclmul_unregister(void);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-fs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/linux/linux-fs.h
+ *
+ * Basic library routines.
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_FS_H__
+#define __LIBCFS_LINUX_CFS_FS_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
+#endif
+
+
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/mount.h>
+#include <linux/backing-dev.h>
+#include <linux/posix_acl_xattr.h>
+
+#define filp_size(f)					\
+	(i_size_read((f)->f_dentry->d_inode))
+#define filp_poff(f)					\
+	(&(f)->f_pos)
+
+# define do_fsync(fp, flag)				\
+	((fp)->f_op->fsync(fp, 0, LLONG_MAX, flag))
+
+#define filp_read(fp, buf, size, pos)			\
+	((fp)->f_op->read((fp), (buf), (size), pos))
+
+#define filp_write(fp, buf, size, pos)			\
+	((fp)->f_op->write((fp), (buf), (size), pos))
+
+#define filp_fsync(fp)					\
+	do_fsync(fp, 1)
+
+#define flock_type(fl)			((fl)->fl_type)
+#define flock_set_type(fl, type)	do { (fl)->fl_type = (type); } while (0)
+#define flock_pid(fl)			((fl)->fl_pid)
+#define flock_set_pid(fl, pid)		do { (fl)->fl_pid = (pid); } while (0)
+#define flock_start(fl)			((fl)->fl_start)
+#define flock_set_start(fl, st)		do { (fl)->fl_start = (st); } while (0)
+#define flock_end(fl)			((fl)->fl_end)
+#define flock_set_end(fl, end)		do { (fl)->fl_end = (end); } while (0)
+
+#ifndef IFSHIFT
+#define IFSHIFT			12
+#endif
+
+#ifndef IFTODT
+#define IFTODT(type)		(((type) & S_IFMT) >> IFSHIFT)
+#endif
+#ifndef DTTOIF
+#define DTTOIF(dirtype)		((dirtype) << IFSHIFT)
+#endif
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-lock.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-lock.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-lock.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-lock.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,204 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/linux/linux-lock.h
+ *
+ * Basic library routines.
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_LOCK_H__
+#define __LIBCFS_LINUX_CFS_LOCK_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
+#endif
+
+
+#include <linux/mutex.h>
+
+/*
+ * IMPORTANT !!!!!!!!
+ *
+ * All locks' declaration are not guaranteed to be initialized,
+ * Althought some of they are initialized in Linux. All locks
+ * declared by CFS_DECL_* should be initialized explicitly.
+ */
+
+/*
+ * spin_lock "implementation" (use Linux kernel's primitives)
+ *
+ * - spin_lock_init(x)
+ * - spin_lock(x)
+ * - spin_lock_bh(x)
+ * - spin_lock_bh_init(x)
+ * - spin_unlock(x)
+ * - spin_unlock_bh(x)
+ * - spin_trylock(x)
+ * - spin_is_locked(x)
+ *
+ * - spin_lock_irq(x)
+ * - spin_lock_irqsave(x, f)
+ * - spin_unlock_irqrestore(x, f)
+ * - read_lock_irqsave(lock, f)
+ * - write_lock_irqsave(lock, f)
+ * - write_unlock_irqrestore(lock, f)
+ */
+
+/*
+ * spinlock "implementation"
+ */
+
+
+
+
+/*
+ * rw_semaphore "implementation" (use Linux kernel's primitives)
+ *
+ * - sema_init(x)
+ * - init_rwsem(x)
+ * - down_read(x)
+ * - up_read(x)
+ * - down_write(x)
+ * - up_write(x)
+ */
+
+
+#define fini_rwsem(s)		do {} while (0)
+
+
+/*
+ * rwlock_t "implementation" (use Linux kernel's primitives)
+ *
+ * - rwlock_init(x)
+ * - read_lock(x)
+ * - read_unlock(x)
+ * - write_lock(x)
+ * - write_unlock(x)
+ * - write_lock_bh(x)
+ * - write_unlock_bh(x)
+ *
+ * - RW_LOCK_UNLOCKED
+ */
+
+
+#ifndef DEFINE_RWLOCK
+#define DEFINE_RWLOCK(lock)	rwlock_t lock = __RW_LOCK_UNLOCKED(lock)
+#endif
+
+/*
+ * completion "implementation" (use Linux kernel's primitives)
+ *
+ * - DECLARE_COMPLETION(work)
+ * - INIT_COMPLETION(c)
+ * - COMPLETION_INITIALIZER(work)
+ * - init_completion(c)
+ * - complete(c)
+ * - wait_for_completion(c)
+ * - wait_for_completion_interruptible(c)
+ * - fini_completion(c)
+ */
+#define fini_completion(c) do { } while (0)
+
+/*
+ * semaphore "implementation" (use Linux kernel's primitives)
+ * - DEFINE_SEMAPHORE(name)
+ * - sema_init(sem, val)
+ * - up(sem)
+ * - down(sem)
+ * - down_interruptible(sem)
+ * - down_trylock(sem)
+ */
+
+/*
+ * mutex "implementation" (use Linux kernel's primitives)
+ *
+ * - DEFINE_MUTEX(name)
+ * - mutex_init(x)
+ * - mutex_lock(x)
+ * - mutex_unlock(x)
+ * - mutex_trylock(x)
+ * - mutex_is_locked(x)
+ * - mutex_destroy(x)
+ */
+
+#ifndef lockdep_set_class
+
+/**************************************************************************
+ *
+ * Lockdep "implementation". Also see liblustre.h
+ *
+ **************************************************************************/
+
+struct lock_class_key {
+	;
+};
+
+#define lockdep_set_class(lock, key) \
+	do { (void)sizeof(lock); (void)sizeof(key); } while (0)
+/* This has to be a macro, so that `subclass' can be undefined in kernels
+ * that do not support lockdep. */
+
+
+static inline void lockdep_off(void)
+{
+}
+
+static inline void lockdep_on(void)
+{
+}
+#else
+
+#endif /* lockdep_set_class */
+
+#ifndef CONFIG_DEBUG_LOCK_ALLOC
+#ifndef mutex_lock_nested
+#define mutex_lock_nested(mutex, subclass) mutex_lock(mutex)
+#endif
+
+#ifndef spin_lock_nested
+#define spin_lock_nested(lock, subclass) spin_lock(lock)
+#endif
+
+#ifndef down_read_nested
+#define down_read_nested(lock, subclass) down_read(lock)
+#endif
+
+#ifndef down_write_nested
+#define down_write_nested(lock, subclass) down_write(lock)
+#endif
+#endif /* CONFIG_DEBUG_LOCK_ALLOC */
+
+
+#endif /* __LIBCFS_LINUX_CFS_LOCK_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,120 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/linux/linux-mem.h
+ *
+ * Basic library routines.
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_MEM_H__
+#define __LIBCFS_LINUX_CFS_MEM_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
+#endif
+
+
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include <linux/memcontrol.h>
+#include <linux/mm_inline.h>
+
+#define CFS_PAGE_MASK		   (~((__u64)PAGE_CACHE_SIZE-1))
+#define page_index(p)       ((p)->index)
+
+#define memory_pressure_get() (current->flags & PF_MEMALLOC)
+#define memory_pressure_set() do { current->flags |= PF_MEMALLOC; } while (0)
+#define memory_pressure_clr() do { current->flags &= ~PF_MEMALLOC; } while (0)
+
+#if BITS_PER_LONG == 32
+/* limit to lowmem on 32-bit systems */
+#define NUM_CACHEPAGES \
+	min(num_physpages, 1UL << (30 - PAGE_CACHE_SHIFT) * 3 / 4)
+#else
+#define NUM_CACHEPAGES num_physpages
+#endif
+
+/*
+ * In Linux there is no way to determine whether current execution context is
+ * blockable.
+ */
+#define ALLOC_ATOMIC_TRY   GFP_ATOMIC
+
+#define DECL_MMSPACE		mm_segment_t __oldfs
+#define MMSPACE_OPEN \
+	do { __oldfs = get_fs(); set_fs(get_ds());} while(0)
+#define MMSPACE_CLOSE	       set_fs(__oldfs)
+
+/*
+ * Shrinker
+ */
+
+# define SHRINKER_ARGS(sc, nr_to_scan, gfp_mask)  \
+		       struct shrinker *shrinker, \
+		       struct shrink_control *sc
+# define shrink_param(sc, var) ((sc)->var)
+
+typedef int (*shrinker_t)(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask));
+
+static inline
+struct shrinker *set_shrinker(int seek, shrinker_t func)
+{
+	struct shrinker *s;
+
+	s = kmalloc(sizeof(*s), GFP_KERNEL);
+	if (s == NULL)
+		return (NULL);
+
+	s->shrink = func;
+	s->seeks = seek;
+
+	register_shrinker(s);
+
+	return s;
+}
+
+static inline
+void remove_shrinker(struct shrinker *shrinker)
+{
+	if (shrinker == NULL)
+		return;
+
+	unregister_shrinker(shrinker);
+	kfree(shrinker);
+}
+
+#endif /* __LINUX_CFS_MEM_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-prim.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-prim.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-prim.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-prim.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,241 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/linux/linux-prim.h
+ *
+ * Basic library routines.
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_PRIM_H__
+#define __LIBCFS_LINUX_CFS_PRIM_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
+#endif
+
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/timer.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/random.h>
+
+#include <linux/miscdevice.h>
+#include <linux/libcfs/linux/portals_compat25.h>
+#include <asm/div64.h>
+
+#include <linux/libcfs/linux/linux-time.h>
+
+
+/*
+ * CPU
+ */
+#ifdef for_each_possible_cpu
+#define cfs_for_each_possible_cpu(cpu) for_each_possible_cpu(cpu)
+#elif defined(for_each_cpu)
+#define cfs_for_each_possible_cpu(cpu) for_each_cpu(cpu)
+#endif
+
+#ifdef NR_CPUS
+#else
+#define NR_CPUS     1
+#endif
+
+/*
+ * cache
+ */
+
+/*
+ * IRQs
+ */
+
+
+/*
+ * Pseudo device register
+ */
+typedef struct miscdevice		psdev_t;
+
+/*
+ * Sysctl register
+ */
+typedef struct ctl_table		ctl_table_t;
+typedef struct ctl_table_header		ctl_table_header_t;
+
+#define cfs_register_sysctl_table(t, a) register_sysctl_table(t)
+
+#define DECLARE_PROC_HANDLER(name)		      \
+static int					      \
+LL_PROC_PROTO(name)				     \
+{						       \
+	DECLARE_LL_PROC_PPOS_DECL;		      \
+							\
+	return proc_call_handler(table->data, write,    \
+				 ppos, buffer, lenp,    \
+				 __##name);	     \
+}
+
+/*
+ * Symbol register
+ */
+#define cfs_symbol_register(s, p)       do {} while(0)
+#define cfs_symbol_unregister(s)	do {} while(0)
+#define cfs_symbol_get(s)	       symbol_get(s)
+#define cfs_symbol_put(s)	       symbol_put(s)
+
+typedef struct module module_t;
+
+/*
+ * Proc file system APIs
+ */
+typedef struct proc_dir_entry	   proc_dir_entry_t;
+
+/*
+ * Wait Queue
+ */
+
+
+typedef long			    cfs_task_state_t;
+
+#define CFS_DECL_WAITQ(wq)		DECLARE_WAIT_QUEUE_HEAD(wq)
+
+/*
+ * Task struct
+ */
+typedef struct task_struct	      task_t;
+#define DECL_JOURNAL_DATA	   void *journal_info
+#define PUSH_JOURNAL		do {    \
+	journal_info = current->journal_info;   \
+	current->journal_info = NULL;	   \
+	} while(0)
+#define POP_JOURNAL		 do {    \
+	current->journal_info = journal_info;   \
+	} while(0)
+
+/* Module interfaces */
+#define cfs_module(name, version, init, fini) \
+	module_init(init);		    \
+	module_exit(fini)
+
+/*
+ * Signal
+ */
+
+/*
+ * Timer
+ */
+typedef struct timer_list timer_list_t;
+
+
+#ifndef wait_event_timeout /* Only for RHEL3 2.4.21 kernel */
+#define __wait_event_timeout(wq, condition, timeout, ret)	\
+do {							     \
+	int __ret = 0;					   \
+	if (!(condition)) {				      \
+		wait_queue_t __wait;			     \
+		unsigned long expire;			    \
+								 \
+		init_waitqueue_entry(&__wait, current);	  \
+		expire = timeout + jiffies;		      \
+		add_wait_queue(&wq, &__wait);		    \
+		for (;;) {				       \
+			set_current_state(TASK_UNINTERRUPTIBLE); \
+			if (condition)			   \
+				break;			   \
+			if (jiffies > expire) {		  \
+				ret = jiffies - expire;	  \
+				break;			   \
+			}					\
+			schedule_timeout(timeout);	       \
+		}						\
+		current->state = TASK_RUNNING;		   \
+		remove_wait_queue(&wq, &__wait);		 \
+	}							\
+} while (0)
+/*
+   retval == 0; condition met; we're good.
+   retval > 0; timed out.
+*/
+#define cfs_waitq_wait_event_timeout(wq, condition, timeout, ret)    \
+do {								 \
+	ret = 0;						     \
+	if (!(condition))					    \
+		__wait_event_timeout(wq, condition, timeout, ret);   \
+} while (0)
+#else
+#define cfs_waitq_wait_event_timeout(wq, condition, timeout, ret)    \
+	ret = wait_event_timeout(wq, condition, timeout)
+#endif
+
+#define cfs_waitq_wait_event_interruptible_timeout(wq, c, timeout, ret) \
+	ret = wait_event_interruptible_timeout(wq, c, timeout)
+
+/*
+ * atomic
+ */
+
+
+#define cfs_atomic_add_unless(atom, a, u)    atomic_add_unless(atom, a, u)
+#define cfs_atomic_cmpxchg(atom, old, nv)    atomic_cmpxchg(atom, old, nv)
+
+/*
+ * membar
+ */
+
+
+/*
+ * interrupt
+ */
+
+
+/*
+ * might_sleep
+ */
+
+/*
+ * group_info
+ */
+typedef struct group_info group_info_t;
+
+
+/*
+ * Random bytes
+ */
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-tcpip.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-tcpip.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-tcpip.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-tcpip.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,87 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/linux/linux-tcpip.h
+ *
+ * Basic library routines.
+ */
+
+#ifndef __LIBCFS_LINUX_CFS_TCP_H__
+#define __LIBCFS_LINUX_CFS_TCP_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
+#endif
+
+
+#include <net/sock.h>
+
+#ifndef HIPQUAD
+// XXX Should just kill all users
+#if defined(__LITTLE_ENDIAN)
+#define HIPQUAD(addr) \
+	((unsigned char *)&addr)[3], \
+	((unsigned char *)&addr)[2], \
+	((unsigned char *)&addr)[1], \
+	((unsigned char *)&addr)[0]
+#elif defined(__BIG_ENDIAN)
+#define HIPQUAD NIPQUAD
+#else
+#error "Please fix asm/byteorder.h"
+#endif /* __LITTLE_ENDIAN */
+#endif
+
+typedef struct socket   socket_t;
+
+#define SOCK_SNDBUF(so)	 ((so)->sk->sk_sndbuf)
+#define SOCK_TEST_NOSPACE(so)   test_bit(SOCK_NOSPACE, &(so)->flags)
+
+static inline int
+cfs_sock_error(struct socket *sock)
+{
+	return sock->sk->sk_err;
+}
+
+static inline int
+cfs_sock_wmem_queued(struct socket *sock)
+{
+	return sock->sk->sk_wmem_queued;
+}
+
+#define cfs_sk_sleep(sk)	sk_sleep(sk)
+
+#define DEFAULT_NET	(&init_net)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,275 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/linux/linux-time.h
+ *
+ * Implementation of portable time API for Linux (kernel and user-level).
+ *
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ */
+
+#ifndef __LIBCFS_LINUX_LINUX_TIME_H__
+#define __LIBCFS_LINUX_LINUX_TIME_H__
+
+#ifndef __LIBCFS_LIBCFS_H__
+#error Do not #include this file directly. #include <linux/libcfs/libcfs.h> instead
+#endif
+
+
+/* Portable time API */
+
+/*
+ * Platform provides three opaque data-types:
+ *
+ *  cfs_time_t	represents point in time. This is internal kernel
+ *		    time rather than "wall clock". This time bears no
+ *		    relation to gettimeofday().
+ *
+ *  cfs_duration_t    represents time interval with resolution of internal
+ *		    platform clock
+ *
+ *  cfs_fs_time_t     represents instance in world-visible time. This is
+ *		    used in file-system time-stamps
+ *
+ *  cfs_time_t     cfs_time_current(void);
+ *  cfs_time_t     cfs_time_add    (cfs_time_t, cfs_duration_t);
+ *  cfs_duration_t cfs_time_sub    (cfs_time_t, cfs_time_t);
+ *  int	    cfs_impl_time_before (cfs_time_t, cfs_time_t);
+ *  int	    cfs_impl_time_before_eq(cfs_time_t, cfs_time_t);
+ *
+ *  cfs_duration_t cfs_duration_build(int64_t);
+ *
+ *  time_t	 cfs_duration_sec (cfs_duration_t);
+ *  void	   cfs_duration_usec(cfs_duration_t, struct timeval *);
+ *  void	   cfs_duration_nsec(cfs_duration_t, struct timespec *);
+ *
+ *  void	   cfs_fs_time_current(cfs_fs_time_t *);
+ *  time_t	 cfs_fs_time_sec    (cfs_fs_time_t *);
+ *  void	   cfs_fs_time_usec   (cfs_fs_time_t *, struct timeval *);
+ *  void	   cfs_fs_time_nsec   (cfs_fs_time_t *, struct timespec *);
+ *  int	    cfs_fs_time_before (cfs_fs_time_t *, cfs_fs_time_t *);
+ *  int	    cfs_fs_time_beforeq(cfs_fs_time_t *, cfs_fs_time_t *);
+ *
+ *  CFS_TIME_FORMAT
+ *  CFS_DURATION_FORMAT
+ *
+ */
+
+#define ONE_BILLION ((u_int64_t)1000000000)
+#define ONE_MILLION 1000000
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/time.h>
+#include <asm/div64.h>
+
+#include <linux/libcfs/linux/portals_compat25.h>
+
+/*
+ * post 2.5 kernels.
+ */
+
+#include <linux/jiffies.h>
+
+typedef struct timespec cfs_fs_time_t;
+
+static inline void cfs_fs_time_usec(cfs_fs_time_t *t, struct timeval *v)
+{
+	v->tv_sec  = t->tv_sec;
+	v->tv_usec = t->tv_nsec / 1000;
+}
+
+static inline void cfs_fs_time_nsec(cfs_fs_time_t *t, struct timespec *s)
+{
+	*s = *t;
+}
+
+/*
+ * internal helper function used by cfs_fs_time_before*()
+ */
+static inline unsigned long long __cfs_fs_time_flat(cfs_fs_time_t *t)
+{
+	return (unsigned long long)t->tv_sec * ONE_BILLION + t->tv_nsec;
+}
+
+
+/*
+ * Generic kernel stuff
+ */
+
+typedef unsigned long cfs_time_t;      /* jiffies */
+typedef long cfs_duration_t;
+typedef cycles_t cfs_cycles_t;
+
+static inline int cfs_time_before(cfs_time_t t1, cfs_time_t t2)
+{
+	return time_before(t1, t2);
+}
+
+static inline int cfs_time_beforeq(cfs_time_t t1, cfs_time_t t2)
+{
+	return time_before_eq(t1, t2);
+}
+
+static inline cfs_time_t cfs_time_current(void)
+{
+	return jiffies;
+}
+
+static inline time_t cfs_time_current_sec(void)
+{
+	return get_seconds();
+}
+
+static inline void cfs_fs_time_current(cfs_fs_time_t *t)
+{
+	*t = CURRENT_TIME;
+}
+
+static inline time_t cfs_fs_time_sec(cfs_fs_time_t *t)
+{
+	return t->tv_sec;
+}
+
+static inline int cfs_fs_time_before(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
+{
+	return __cfs_fs_time_flat(t1) <  __cfs_fs_time_flat(t2);
+}
+
+static inline int cfs_fs_time_beforeq(cfs_fs_time_t *t1, cfs_fs_time_t *t2)
+{
+	return __cfs_fs_time_flat(t1) <= __cfs_fs_time_flat(t2);
+}
+
+#if 0
+static inline cfs_duration_t cfs_duration_build(int64_t nano)
+{
+#if (BITS_PER_LONG == 32)
+	/* We cannot use do_div(t, ONE_BILLION), do_div can only process
+	 * 64 bits n and 32 bits base */
+	int64_t  t = nano * HZ;
+	do_div(t, 1000);
+	do_div(t, 1000000);
+	return (cfs_duration_t)t;
+#else
+	return (nano * HZ / ONE_BILLION);
+#endif
+}
+#endif
+
+static inline cfs_duration_t cfs_time_seconds(int seconds)
+{
+	return ((cfs_duration_t)seconds) * HZ;
+}
+
+static inline time_t cfs_duration_sec(cfs_duration_t d)
+{
+	return d / HZ;
+}
+
+static inline void cfs_duration_usec(cfs_duration_t d, struct timeval *s)
+{
+#if (BITS_PER_LONG == 32) && (HZ > 4096)
+	__u64 t;
+
+	s->tv_sec = d / HZ;
+	t = (d - (cfs_duration_t)s->tv_sec * HZ) * ONE_MILLION;
+	do_div(t, HZ);
+	s->tv_usec = t;
+#else
+	s->tv_sec = d / HZ;
+	s->tv_usec = ((d - (cfs_duration_t)s->tv_sec * HZ) * \
+		ONE_MILLION) / HZ;
+#endif
+}
+
+static inline void cfs_duration_nsec(cfs_duration_t d, struct timespec *s)
+{
+#if (BITS_PER_LONG == 32)
+	__u64 t;
+
+	s->tv_sec = d / HZ;
+	t = (d - s->tv_sec * HZ) * ONE_BILLION;
+	do_div(t, HZ);
+	s->tv_nsec = t;
+#else
+	s->tv_sec = d / HZ;
+	s->tv_nsec = ((d - s->tv_sec * HZ) * ONE_BILLION) / HZ;
+#endif
+}
+
+#define cfs_time_current_64 get_jiffies_64
+
+static inline __u64 cfs_time_add_64(__u64 t, __u64 d)
+{
+	return t + d;
+}
+
+static inline __u64 cfs_time_shift_64(int seconds)
+{
+	return cfs_time_add_64(cfs_time_current_64(),
+			       cfs_time_seconds(seconds));
+}
+
+static inline int cfs_time_before_64(__u64 t1, __u64 t2)
+{
+	return (__s64)t2 - (__s64)t1 > 0;
+}
+
+static inline int cfs_time_beforeq_64(__u64 t1, __u64 t2)
+{
+	return (__s64)t2 - (__s64)t1 >= 0;
+}
+
+
+/*
+ * One jiffy
+ */
+#define CFS_TICK		(1)
+
+#define CFS_TIME_T	      "%lu"
+#define CFS_DURATION_T	  "%ld"
+
+
+#endif /* __LIBCFS_LINUX_LINUX_TIME_H__ */
+/*
+ * Local variables:
+ * c-indentation-style: "K&R"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * fill-column: 80
+ * scroll-step: 1
+ * End:
+ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-types.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-types.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/linux-types.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/user-bitops.h
+ */
+#include <linux/types.h>
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/portals_compat25.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/portals_compat25.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/linux/portals_compat25.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/linux/portals_compat25.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,114 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LIBCFS_LINUX_PORTALS_COMPAT_H__
+#define __LIBCFS_LINUX_PORTALS_COMPAT_H__
+
+// XXX BUG 1511 -- remove this stanza and all callers when bug 1511 is resolved
+#if defined(SPINLOCK_DEBUG) && SPINLOCK_DEBUG
+#  define SIGNAL_MASK_ASSERT() \
+   LASSERT(current->sighand->siglock.magic == SPINLOCK_MAGIC)
+#else
+# define SIGNAL_MASK_ASSERT()
+#endif
+// XXX BUG 1511 -- remove this stanza and all callers when bug 1511 is resolved
+
+#define SIGNAL_MASK_LOCK(task, flags)				  \
+	spin_lock_irqsave(&task->sighand->siglock, flags)
+#define SIGNAL_MASK_UNLOCK(task, flags)				\
+	spin_unlock_irqrestore(&task->sighand->siglock, flags)
+#define USERMODEHELPER(path, argv, envp)			       \
+	call_usermodehelper(path, argv, envp, 1)
+#define clear_tsk_thread_flag(current, TIF_SIGPENDING)	  clear_tsk_thread_flag(current,       \
+							TIF_SIGPENDING)
+# define smp_num_cpus	      num_online_cpus()
+
+#define cfs_wait_event_interruptible(wq, condition, ret)	       \
+	ret = wait_event_interruptible(wq, condition)
+#define cfs_wait_event_interruptible_exclusive(wq, condition, ret)     \
+	ret = wait_event_interruptible_exclusive(wq, condition)
+
+#define THREAD_NAME(comm, len, fmt, a...)			      \
+	snprintf(comm, len, fmt, ## a)
+
+/* 2.6 alloc_page users can use page->lru */
+#define PAGE_LIST_ENTRY lru
+#define PAGE_LIST(page) ((page)->lru)
+
+#ifndef __user
+#define __user
+#endif
+
+#ifndef __fls
+#define __cfs_fls fls
+#else
+#define __cfs_fls __fls
+#endif
+
+#define ll_proc_dointvec(table, write, filp, buffer, lenp, ppos)	\
+	proc_dointvec(table, write, buffer, lenp, ppos);
+
+#define ll_proc_dolongvec(table, write, filp, buffer, lenp, ppos)	\
+	proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
+#define ll_proc_dostring(table, write, filp, buffer, lenp, ppos)	\
+	proc_dostring(table, write, buffer, lenp, ppos);
+#define LL_PROC_PROTO(name)					     \
+	name(ctl_table_t *table, int write,		      \
+	     void __user *buffer, size_t *lenp, loff_t *ppos)
+#define DECLARE_LL_PROC_PPOS_DECL
+
+/* helper for sysctl handlers */
+int proc_call_handler(void *data, int write,
+		      loff_t *ppos, void *buffer, size_t *lenp,
+		      int (*handler)(void *data, int write,
+				     loff_t pos, void *buffer, int len));
+/*
+ * CPU
+ */
+#ifdef for_each_possible_cpu
+#define cfs_for_each_possible_cpu(cpu) for_each_possible_cpu(cpu)
+#elif defined(for_each_cpu)
+#define cfs_for_each_possible_cpu(cpu) for_each_cpu(cpu)
+#endif
+
+#ifdef NR_CPUS
+#else
+#define NR_CPUS     1
+#endif
+
+#define cfs_register_sysctl_table(t, a) register_sysctl_table(t)
+
+#endif /* _PORTALS_COMPAT_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/lucache.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/lucache.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/lucache.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/lucache.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,162 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LUCACHE_H
+#define _LUCACHE_H
+
+#include <linux/libcfs/libcfs.h>
+
+/** \defgroup ucache ucache
+ *
+ * @{
+ */
+
+#define UC_CACHE_NEW	    0x01
+#define UC_CACHE_ACQUIRING      0x02
+#define UC_CACHE_INVALID	0x04
+#define UC_CACHE_EXPIRED	0x08
+
+#define UC_CACHE_IS_NEW(i)	  ((i)->ue_flags & UC_CACHE_NEW)
+#define UC_CACHE_IS_INVALID(i)      ((i)->ue_flags & UC_CACHE_INVALID)
+#define UC_CACHE_IS_ACQUIRING(i)    ((i)->ue_flags & UC_CACHE_ACQUIRING)
+#define UC_CACHE_IS_EXPIRED(i)      ((i)->ue_flags & UC_CACHE_EXPIRED)
+#define UC_CACHE_IS_VALID(i)	((i)->ue_flags == 0)
+
+#define UC_CACHE_SET_NEW(i)	 (i)->ue_flags |= UC_CACHE_NEW
+#define UC_CACHE_SET_INVALID(i)     (i)->ue_flags |= UC_CACHE_INVALID
+#define UC_CACHE_SET_ACQUIRING(i)   (i)->ue_flags |= UC_CACHE_ACQUIRING
+#define UC_CACHE_SET_EXPIRED(i)     (i)->ue_flags |= UC_CACHE_EXPIRED
+#define UC_CACHE_SET_VALID(i)       (i)->ue_flags = 0
+
+#define UC_CACHE_CLEAR_NEW(i)       (i)->ue_flags &= ~UC_CACHE_NEW
+#define UC_CACHE_CLEAR_ACQUIRING(i) (i)->ue_flags &= ~UC_CACHE_ACQUIRING
+#define UC_CACHE_CLEAR_INVALID(i)   (i)->ue_flags &= ~UC_CACHE_INVALID
+#define UC_CACHE_CLEAR_EXPIRED(i)   (i)->ue_flags &= ~UC_CACHE_EXPIRED
+
+struct upcall_cache_entry;
+
+struct md_perm {
+	lnet_nid_t      mp_nid;
+	__u32	   mp_perm;
+};
+
+struct md_identity {
+	struct upcall_cache_entry *mi_uc_entry;
+	uid_t		      mi_uid;
+	gid_t		      mi_gid;
+	group_info_t	  *mi_ginfo;
+	int			mi_nperms;
+	struct md_perm	    *mi_perms;
+};
+
+struct upcall_cache_entry {
+	struct list_head	      ue_hash;
+	__u64		   ue_key;
+	atomic_t	    ue_refcount;
+	int		     ue_flags;
+	wait_queue_head_t	     ue_waitq;
+	cfs_time_t	      ue_acquire_expire;
+	cfs_time_t	      ue_expire;
+	union {
+		struct md_identity     identity;
+	} u;
+};
+
+#define UC_CACHE_HASH_SIZE	(128)
+#define UC_CACHE_HASH_INDEX(id)   ((id) & (UC_CACHE_HASH_SIZE - 1))
+#define UC_CACHE_UPCALL_MAXPATH   (1024UL)
+
+struct upcall_cache;
+
+struct upcall_cache_ops {
+	void	    (*init_entry)(struct upcall_cache_entry *, void *args);
+	void	    (*free_entry)(struct upcall_cache *,
+				      struct upcall_cache_entry *);
+	int	     (*upcall_compare)(struct upcall_cache *,
+					  struct upcall_cache_entry *,
+					  __u64 key, void *args);
+	int	     (*downcall_compare)(struct upcall_cache *,
+					    struct upcall_cache_entry *,
+					    __u64 key, void *args);
+	int	     (*do_upcall)(struct upcall_cache *,
+				     struct upcall_cache_entry *);
+	int	     (*parse_downcall)(struct upcall_cache *,
+					  struct upcall_cache_entry *, void *);
+};
+
+struct upcall_cache {
+	struct list_head		uc_hashtable[UC_CACHE_HASH_SIZE];
+	spinlock_t		uc_lock;
+	rwlock_t		uc_upcall_rwlock;
+
+	char			uc_name[40];		/* for upcall */
+	char			uc_upcall[UC_CACHE_UPCALL_MAXPATH];
+	int			uc_acquire_expire;	/* seconds */
+	int			uc_entry_expire;	/* seconds */
+	struct upcall_cache_ops	*uc_ops;
+};
+
+struct upcall_cache_entry *upcall_cache_get_entry(struct upcall_cache *cache,
+						  __u64 key, void *args);
+void upcall_cache_put_entry(struct upcall_cache *cache,
+			    struct upcall_cache_entry *entry);
+int upcall_cache_downcall(struct upcall_cache *cache, __u32 err, __u64 key,
+			  void *args);
+void upcall_cache_flush_idle(struct upcall_cache *cache);
+void upcall_cache_flush_all(struct upcall_cache *cache);
+void upcall_cache_flush_one(struct upcall_cache *cache, __u64 key, void *args);
+struct upcall_cache *upcall_cache_init(const char *name, const char *upcall,
+				       struct upcall_cache_ops *ops);
+void upcall_cache_cleanup(struct upcall_cache *cache);
+
+#if 0
+struct upcall_cache_entry *upcall_cache_get_entry(struct upcall_cache *hash,
+						  __u64 key, __u32 primary,
+						  __u32 ngroups, __u32 *groups);
+void upcall_cache_put_entry(struct upcall_cache *hash,
+			    struct upcall_cache_entry *entry);
+int upcall_cache_downcall(struct upcall_cache *hash, __u32 err, __u64 key,
+			  __u32 primary, __u32 ngroups, __u32 *groups);
+void upcall_cache_flush_idle(struct upcall_cache *cache);
+void upcall_cache_flush_all(struct upcall_cache *cache);
+struct upcall_cache *upcall_cache_init(const char *name);
+void upcall_cache_cleanup(struct upcall_cache *hash);
+
+#endif
+
+/** @} ucache */
+
+#endif /* _LUCACHE_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/params_tree.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/params_tree.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/libcfs/params_tree.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/libcfs/params_tree.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,166 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * API and structure definitions for params_tree.
+ *
+ * Author: LiuYing <emoly.liu@oracle.com>
+ */
+#ifndef __PARAMS_TREE_H__
+#define __PARAMS_TREE_H__
+
+#include <linux/libcfs/libcfs.h>
+
+#undef LPROCFS
+#if  defined(CONFIG_PROC_FS)
+# define LPROCFS
+#endif
+
+#ifdef LPROCFS
+typedef struct file			     cfs_param_file_t;
+typedef struct inode			    cfs_inode_t;
+typedef struct proc_inode		       cfs_proc_inode_t;
+typedef struct seq_file			 cfs_seq_file_t;
+typedef struct seq_operations		   cfs_seq_ops_t;
+typedef struct file_operations		  cfs_param_file_ops_t;
+typedef module_t			   *cfs_param_module_t;
+typedef struct proc_dir_entry		   cfs_param_dentry_t;
+typedef struct poll_table_struct		cfs_poll_table_t;
+#define CFS_PARAM_MODULE			THIS_MODULE
+#define cfs_file_private(file)		  (file->private_data)
+#define cfs_dentry_data(dentry)		 (dentry->data)
+#define cfs_proc_inode_pde(proc_inode)	  (proc_inode->pde)
+#define cfs_proc_inode(proc_inode)	      (proc_inode->vfs_inode)
+#define cfs_seq_read_common		     seq_read
+#define cfs_seq_lseek_common		    seq_lseek
+#define cfs_seq_private(seq)		    (seq->private)
+#define cfs_seq_printf(seq, format, ...)	seq_printf(seq, format,  \
+							   ## __VA_ARGS__)
+#define cfs_seq_release(inode, file)	    seq_release(inode, file)
+#define cfs_seq_puts(seq, s)		    seq_puts(seq, s)
+#define cfs_seq_putc(seq, s)		    seq_putc(seq, s)
+#define cfs_seq_read(file, buf, count, ppos, rc) (rc = seq_read(file, buf, \
+							    count, ppos))
+#define cfs_seq_open(file, ops, rc)	     (rc = seq_open(file, ops))
+
+#else /* !LPROCFS */
+
+typedef struct cfs_params_file {
+	void	   *param_private;
+	loff_t	  param_pos;
+	unsigned int    param_flags;
+} cfs_param_file_t;
+
+typedef struct cfs_param_inode {
+	void    *param_private;
+} cfs_inode_t;
+
+typedef struct cfs_param_dentry {
+	void *param_data;
+} cfs_param_dentry_t;
+
+typedef struct cfs_proc_inode {
+	cfs_param_dentry_t *param_pde;
+	cfs_inode_t	 param_inode;
+} cfs_proc_inode_t;
+
+struct cfs_seq_operations;
+typedef struct cfs_seq_file {
+	char		      *buf;
+	size_t		     size;
+	size_t		     from;
+	size_t		     count;
+	loff_t		     index;
+	loff_t		     version;
+	struct mutex			lock;
+	struct cfs_seq_operations *op;
+	void		      *private;
+} cfs_seq_file_t;
+
+typedef struct cfs_seq_operations {
+	void *(*start) (cfs_seq_file_t *m, loff_t *pos);
+	void  (*stop) (cfs_seq_file_t *m, void *v);
+	void *(*next) (cfs_seq_file_t *m, void *v, loff_t *pos);
+	int   (*show) (cfs_seq_file_t *m, void *v);
+} cfs_seq_ops_t;
+
+typedef void *cfs_param_module_t;
+typedef void *cfs_poll_table_t;
+
+typedef struct cfs_param_file_ops {
+	cfs_param_module_t owner;
+	int (*open) (cfs_inode_t *, struct file *);
+	loff_t (*llseek)(struct file *, loff_t, int);
+	int (*release) (cfs_inode_t *, cfs_param_file_t *);
+	unsigned int (*poll) (struct file *, cfs_poll_table_t *);
+	ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
+	ssize_t (*read)(struct file *, char *, size_t, loff_t *);
+} cfs_param_file_ops_t;
+typedef cfs_param_file_ops_t *cfs_lproc_filep_t;
+
+static inline cfs_proc_inode_t *FAKE_PROC_I(const cfs_inode_t *inode)
+{
+	return container_of(inode, cfs_proc_inode_t, param_inode);
+}
+
+#define CFS_PARAM_MODULE			NULL
+#define cfs_file_private(file)		  (file->param_private)
+#define cfs_dentry_data(dentry)		 (dentry->param_data)
+#define cfs_proc_inode(proc_inode)	      (proc_inode->param_inode)
+#define cfs_proc_inode_pde(proc_inode)	  (proc_inode->param_pde)
+#define cfs_seq_read_common		     NULL
+#define cfs_seq_lseek_common		    NULL
+#define cfs_seq_private(seq)		    (seq->private)
+#define cfs_seq_read(file, buf, count, ppos, rc) do {} while(0)
+#define cfs_seq_open(file, ops, rc)		     \
+do {						    \
+	 cfs_seq_file_t *p = cfs_file_private(file);    \
+	 if (!p) {				      \
+		LIBCFS_ALLOC(p, sizeof(*p));	    \
+		if (!p) {			       \
+			rc = -ENOMEM;		   \
+			break;			  \
+		}				       \
+		cfs_file_private(file) = p;	     \
+	}					       \
+	memset(p, 0, sizeof(*p));		       \
+	p->op = ops;				    \
+	rc = 0;					 \
+} while(0)
+
+#endif /* LPROCFS */
+
+/* XXX: params_tree APIs */
+
+#endif  /* __PARAMS_TREE_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/api.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/api.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/api.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/api.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,220 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LNET_API_H__
+#define __LNET_API_H__
+
+/** \defgroup lnet LNet
+ *
+ * The Lustre Networking subsystem.
+ *
+ * LNet is an asynchronous message-passing API, which provides an unreliable
+ * connectionless service that can't guarantee any order. It supports OFA IB,
+ * TCP/IP, and Cray Portals, and routes between heterogeneous networks.
+ *
+ * LNet can run both in OS kernel space and in userspace as a library.
+ * @{
+ */
+
+#include <linux/lnet/types.h>
+
+/** \defgroup lnet_init_fini Initialization and cleanup
+ * The LNet must be properly initialized before any LNet calls can be made.
+ * @{ */
+int LNetInit(void);
+void LNetFini(void);
+
+int LNetNIInit(lnet_pid_t requested_pid);
+int LNetNIFini(void);
+/** @} lnet_init_fini */
+
+/** \defgroup lnet_addr LNet addressing and basic types
+ *
+ * Addressing scheme and basic data types of LNet.
+ *
+ * The LNet API is memory-oriented, so LNet must be able to address not only
+ * end-points but also memory region within a process address space.
+ * An ::lnet_nid_t addresses an end-point. An ::lnet_pid_t identifies a process
+ * in a node. A portal represents an opening in the address space of a
+ * process. Match bits is criteria to identify a region of memory inside a
+ * portal, and offset specifies an offset within the memory region.
+ *
+ * LNet creates a table of portals for each process during initialization.
+ * This table has MAX_PORTALS entries and its size can't be dynamically
+ * changed. A portal stays empty until the owning process starts to add
+ * memory regions to it. A portal is sometimes called an index because
+ * it's an entry in the portals table of a process.
+ *
+ * \see LNetMEAttach
+ * @{ */
+int LNetGetId(unsigned int index, lnet_process_id_t *id);
+int LNetDist(lnet_nid_t nid, lnet_nid_t *srcnid, __u32 *order);
+void LNetSnprintHandle(char *str, int str_len, lnet_handle_any_t handle);
+
+/** @} lnet_addr */
+
+
+/** \defgroup lnet_me Match entries
+ *
+ * A match entry (abbreviated as ME) describes a set of criteria to accept
+ * incoming requests.
+ *
+ * A portal is essentially a match list plus a set of attributes. A match
+ * list is a chain of MEs. Each ME includes a pointer to a memory descriptor
+ * and a set of match criteria. The match criteria can be used to reject
+ * incoming requests based on process ID or the match bits provided in the
+ * request. MEs can be dynamically inserted into a match list by LNetMEAttach()
+ * and LNetMEInsert(), and removed from its list by LNetMEUnlink().
+ * @{ */
+int LNetMEAttach(unsigned int      portal,
+		 lnet_process_id_t match_id_in,
+		 __u64	     match_bits_in,
+		 __u64	     ignore_bits_in,
+		 lnet_unlink_t     unlink_in,
+		 lnet_ins_pos_t    pos_in,
+		 lnet_handle_me_t *handle_out);
+
+int LNetMEInsert(lnet_handle_me_t  current_in,
+		 lnet_process_id_t match_id_in,
+		 __u64	     match_bits_in,
+		 __u64	     ignore_bits_in,
+		 lnet_unlink_t     unlink_in,
+		 lnet_ins_pos_t    position_in,
+		 lnet_handle_me_t *handle_out);
+
+int LNetMEUnlink(lnet_handle_me_t current_in);
+/** @} lnet_me */
+
+/** \defgroup lnet_md Memory descriptors
+ *
+ * A memory descriptor contains information about a region of a user's
+ * memory (either in kernel or user space) and optionally points to an
+ * event queue where information about the operations performed on the
+ * memory descriptor are recorded. Memory descriptor is abbreviated as
+ * MD and can be used interchangeably with the memory region it describes.
+ *
+ * The LNet API provides two operations to create MDs: LNetMDAttach()
+ * and LNetMDBind(); one operation to unlink and release the resources
+ * associated with a MD: LNetMDUnlink().
+ * @{ */
+int LNetMDAttach(lnet_handle_me_t  current_in,
+		 lnet_md_t	 md_in,
+		 lnet_unlink_t     unlink_in,
+		 lnet_handle_md_t *handle_out);
+
+int LNetMDBind(lnet_md_t	 md_in,
+	       lnet_unlink_t     unlink_in,
+	       lnet_handle_md_t *handle_out);
+
+int LNetMDUnlink(lnet_handle_md_t md_in);
+/** @} lnet_md */
+
+/** \defgroup lnet_eq Events and event queues
+ *
+ * Event queues (abbreviated as EQ) are used to log operations performed on
+ * local MDs. In particular, they signal the completion of a data transmission
+ * into or out of a MD. They can also be used to hold acknowledgments for
+ * completed PUT operations and indicate when a MD has been unlinked. Multiple
+ * MDs can share a single EQ. An EQ may have an optional event handler
+ * associated with it. If an event handler exists, it will be run for each
+ * event that is deposited into the EQ.
+ *
+ * In addition to the lnet_handle_eq_t, the LNet API defines two types
+ * associated with events: The ::lnet_event_kind_t defines the kinds of events
+ * that can be stored in an EQ. The lnet_event_t defines a structure that
+ * holds the information about with an event.
+ *
+ * There are five functions for dealing with EQs: LNetEQAlloc() is used to
+ * create an EQ and allocate the resources needed, while LNetEQFree()
+ * releases these resources and free the EQ. LNetEQGet() retrieves the next
+ * event from an EQ, and LNetEQWait() can be used to block a process until
+ * an EQ has at least one event. LNetEQPoll() can be used to test or wait
+ * on multiple EQs.
+ * @{ */
+int LNetEQAlloc(unsigned int       count_in,
+		lnet_eq_handler_t  handler,
+		lnet_handle_eq_t  *handle_out);
+
+int LNetEQFree(lnet_handle_eq_t eventq_in);
+
+int LNetEQGet(lnet_handle_eq_t  eventq_in,
+	      lnet_event_t     *event_out);
+
+
+int LNetEQWait(lnet_handle_eq_t  eventq_in,
+	       lnet_event_t     *event_out);
+
+int LNetEQPoll(lnet_handle_eq_t *eventqs_in,
+	       int	       neq_in,
+	       int	       timeout_ms,
+	       lnet_event_t     *event_out,
+	       int	      *which_eq_out);
+/** @} lnet_eq */
+
+/** \defgroup lnet_data Data movement operations
+ *
+ * The LNet API provides two data movement operations: LNetPut()
+ * and LNetGet().
+ * @{ */
+int LNetPut(lnet_nid_t	self,
+	    lnet_handle_md_t  md_in,
+	    lnet_ack_req_t    ack_req_in,
+	    lnet_process_id_t target_in,
+	    unsigned int      portal_in,
+	    __u64	     match_bits_in,
+	    unsigned int      offset_in,
+	    __u64	     hdr_data_in);
+
+int LNetGet(lnet_nid_t	self,
+	    lnet_handle_md_t  md_in,
+	    lnet_process_id_t target_in,
+	    unsigned int      portal_in,
+	    __u64	     match_bits_in,
+	    unsigned int      offset_in);
+/** @} lnet_data */
+
+
+/** \defgroup lnet_misc Miscellaneous operations.
+ * Miscellaneous operations.
+ * @{ */
+
+int LNetSetLazyPortal(int portal);
+int LNetClearLazyPortal(int portal);
+int LNetCtl(unsigned int cmd, void *arg);
+int LNetSetAsync(lnet_process_id_t id, int nasync);
+
+/** @} lnet_misc */
+
+/** @} lnet */
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/api-support.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/api-support.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/api-support.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/api-support.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LNET_API_SUPPORT_H__
+#define __LNET_API_SUPPORT_H__
+
+#include <linux/lnet/linux/api-support.h>
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/types.h>
+#include <linux/lnet/lnet.h>
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lib-lnet.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lib-lnet.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lib-lnet.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,874 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/include/lnet/lib-lnet.h
+ *
+ * Top level include for library side routines
+ */
+
+#ifndef __LNET_LIB_LNET_H__
+#define __LNET_LIB_LNET_H__
+
+#include <linux/lnet/linux/lib-lnet.h>
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/types.h>
+#include <linux/lnet/lnet.h>
+#include <linux/lnet/lib-types.h>
+
+extern lnet_t  the_lnet;			/* THE network */
+
+#if  defined(LNET_USE_LIB_FREELIST)
+/* 1 CPT, simplify implementation... */
+# define LNET_CPT_MAX_BITS      0
+
+#else /* KERNEL and no freelist */
+
+# if (BITS_PER_LONG == 32)
+/* 2 CPTs, allowing more CPTs might make us under memory pressure */
+#  define LNET_CPT_MAX_BITS     1
+
+# else /* 64-bit system */
+/*
+ * 256 CPTs for thousands of CPUs, allowing more CPTs might make us
+ * under risk of consuming all lh_cookie.
+ */
+#  define LNET_CPT_MAX_BITS     8
+# endif /* BITS_PER_LONG == 32 */
+#endif
+
+/* max allowed CPT number */
+#define LNET_CPT_MAX	    (1 << LNET_CPT_MAX_BITS)
+
+#define LNET_CPT_NUMBER	 (the_lnet.ln_cpt_number)
+#define LNET_CPT_BITS	   (the_lnet.ln_cpt_bits)
+#define LNET_CPT_MASK	   ((1ULL << LNET_CPT_BITS) - 1)
+
+/** exclusive lock */
+#define LNET_LOCK_EX	    CFS_PERCPT_LOCK_EX
+
+static inline int lnet_is_wire_handle_none (lnet_handle_wire_t *wh)
+{
+	return (wh->wh_interface_cookie == LNET_WIRE_HANDLE_COOKIE_NONE &&
+		wh->wh_object_cookie == LNET_WIRE_HANDLE_COOKIE_NONE);
+}
+
+static inline int lnet_md_exhausted (lnet_libmd_t *md)
+{
+	return (md->md_threshold == 0 ||
+		((md->md_options & LNET_MD_MAX_SIZE) != 0 &&
+		 md->md_offset + md->md_max_size > md->md_length));
+}
+
+static inline int lnet_md_unlinkable (lnet_libmd_t *md)
+{
+	/* Should unlink md when its refcount is 0 and either:
+	 *  - md has been flagged for deletion (by auto unlink or LNetM[DE]Unlink,
+	 *    in the latter case md may not be exhausted).
+	 *  - auto unlink is on and md is exhausted.
+	 */
+	if (md->md_refcount != 0)
+		return 0;
+
+	if ((md->md_flags & LNET_MD_FLAG_ZOMBIE) != 0)
+		return 1;
+
+	return ((md->md_flags & LNET_MD_FLAG_AUTO_UNLINK) != 0 &&
+		lnet_md_exhausted(md));
+}
+
+#define lnet_cpt_table()	(the_lnet.ln_cpt_table)
+#define lnet_cpt_current()	cfs_cpt_current(the_lnet.ln_cpt_table, 1)
+
+static inline int
+lnet_cpt_of_cookie(__u64 cookie)
+{
+	unsigned int cpt = (cookie >> LNET_COOKIE_TYPE_BITS) & LNET_CPT_MASK;
+
+	/* LNET_CPT_NUMBER doesn't have to be power2, which means we can
+	 * get illegal cpt from it's invalid cookie */
+	return cpt < LNET_CPT_NUMBER ? cpt : cpt % LNET_CPT_NUMBER;
+}
+
+static inline void
+lnet_res_lock(int cpt)
+{
+	cfs_percpt_lock(the_lnet.ln_res_lock, cpt);
+}
+
+static inline void
+lnet_res_unlock(int cpt)
+{
+	cfs_percpt_unlock(the_lnet.ln_res_lock, cpt);
+}
+
+static inline int
+lnet_res_lock_current(void)
+{
+	int cpt = lnet_cpt_current();
+
+	lnet_res_lock(cpt);
+	return cpt;
+}
+
+static inline void
+lnet_net_lock(int cpt)
+{
+	cfs_percpt_lock(the_lnet.ln_net_lock, cpt);
+}
+
+static inline void
+lnet_net_unlock(int cpt)
+{
+	cfs_percpt_unlock(the_lnet.ln_net_lock, cpt);
+}
+
+static inline int
+lnet_net_lock_current(void)
+{
+	int cpt = lnet_cpt_current();
+
+	lnet_net_lock(cpt);
+	return cpt;
+}
+
+#define LNET_LOCK()		lnet_net_lock(LNET_LOCK_EX)
+#define LNET_UNLOCK()		lnet_net_unlock(LNET_LOCK_EX)
+
+
+#define lnet_ptl_lock(ptl)	spin_lock(&(ptl)->ptl_lock)
+#define lnet_ptl_unlock(ptl)	spin_unlock(&(ptl)->ptl_lock)
+#define lnet_eq_wait_lock()	spin_lock(&the_lnet.ln_eq_wait_lock)
+#define lnet_eq_wait_unlock()	spin_unlock(&the_lnet.ln_eq_wait_lock)
+#define lnet_ni_lock(ni)	spin_lock(&(ni)->ni_lock)
+#define lnet_ni_unlock(ni)	spin_unlock(&(ni)->ni_lock)
+#define LNET_MUTEX_LOCK(m)	mutex_lock(m)
+#define LNET_MUTEX_UNLOCK(m)	mutex_unlock(m)
+
+
+#define MAX_PORTALS     64
+
+/* these are only used by code with LNET_USE_LIB_FREELIST, but we still
+ * exported them to !LNET_USE_LIB_FREELIST for easy implemetation */
+#define LNET_FL_MAX_MES		2048
+#define LNET_FL_MAX_MDS		2048
+#define LNET_FL_MAX_EQS		512
+#define LNET_FL_MAX_MSGS	2048    /* Outstanding messages */
+
+#ifdef LNET_USE_LIB_FREELIST
+
+int lnet_freelist_init(lnet_freelist_t *fl, int n, int size);
+void lnet_freelist_fini(lnet_freelist_t *fl);
+
+static inline void *
+lnet_freelist_alloc (lnet_freelist_t *fl)
+{
+	/* ALWAYS called with liblock held */
+	lnet_freeobj_t *o;
+
+	if (list_empty (&fl->fl_list))
+		return (NULL);
+
+	o = list_entry (fl->fl_list.next, lnet_freeobj_t, fo_list);
+	list_del (&o->fo_list);
+	return ((void *)&o->fo_contents);
+}
+
+static inline void
+lnet_freelist_free (lnet_freelist_t *fl, void *obj)
+{
+	/* ALWAYS called with liblock held */
+	lnet_freeobj_t *o = list_entry (obj, lnet_freeobj_t, fo_contents);
+
+	list_add (&o->fo_list, &fl->fl_list);
+}
+
+
+static inline lnet_eq_t *
+lnet_eq_alloc (void)
+{
+	/* NEVER called with resource lock held */
+	struct lnet_res_container *rec = &the_lnet.ln_eq_container;
+	lnet_eq_t		  *eq;
+
+	LASSERT(LNET_CPT_NUMBER == 1);
+
+	lnet_res_lock(0);
+	eq = (lnet_eq_t *)lnet_freelist_alloc(&rec->rec_freelist);
+	lnet_res_unlock(0);
+
+	return eq;
+}
+
+static inline void
+lnet_eq_free_locked(lnet_eq_t *eq)
+{
+	/* ALWAYS called with resource lock held */
+	struct lnet_res_container *rec = &the_lnet.ln_eq_container;
+
+	LASSERT(LNET_CPT_NUMBER == 1);
+	lnet_freelist_free(&rec->rec_freelist, eq);
+}
+
+static inline void
+lnet_eq_free(lnet_eq_t *eq)
+{
+	lnet_res_lock(0);
+	lnet_eq_free_locked(eq);
+	lnet_res_unlock(0);
+}
+
+static inline lnet_libmd_t *
+lnet_md_alloc (lnet_md_t *umd)
+{
+	/* NEVER called with resource lock held */
+	struct lnet_res_container *rec = the_lnet.ln_md_containers[0];
+	lnet_libmd_t		  *md;
+
+	LASSERT(LNET_CPT_NUMBER == 1);
+
+	lnet_res_lock(0);
+	md = (lnet_libmd_t *)lnet_freelist_alloc(&rec->rec_freelist);
+	lnet_res_unlock(0);
+
+	if (md != NULL)
+		INIT_LIST_HEAD(&md->md_list);
+
+	return md;
+}
+
+static inline void
+lnet_md_free_locked(lnet_libmd_t *md)
+{
+	/* ALWAYS called with resource lock held */
+	struct lnet_res_container *rec = the_lnet.ln_md_containers[0];
+
+	LASSERT(LNET_CPT_NUMBER == 1);
+	lnet_freelist_free(&rec->rec_freelist, md);
+}
+
+static inline void
+lnet_md_free(lnet_libmd_t *md)
+{
+	lnet_res_lock(0);
+	lnet_md_free_locked(md);
+	lnet_res_unlock(0);
+}
+
+static inline lnet_me_t *
+lnet_me_alloc(void)
+{
+	/* NEVER called with resource lock held */
+	struct lnet_res_container *rec = the_lnet.ln_me_containers[0];
+	lnet_me_t		  *me;
+
+	LASSERT(LNET_CPT_NUMBER == 1);
+
+	lnet_res_lock(0);
+	me = (lnet_me_t *)lnet_freelist_alloc(&rec->rec_freelist);
+	lnet_res_unlock(0);
+
+	return me;
+}
+
+static inline void
+lnet_me_free_locked(lnet_me_t *me)
+{
+	/* ALWAYS called with resource lock held */
+	struct lnet_res_container *rec = the_lnet.ln_me_containers[0];
+
+	LASSERT(LNET_CPT_NUMBER == 1);
+	lnet_freelist_free(&rec->rec_freelist, me);
+}
+
+static inline void
+lnet_me_free(lnet_me_t *me)
+{
+	lnet_res_lock(0);
+	lnet_me_free_locked(me);
+	lnet_res_unlock(0);
+}
+
+static inline lnet_msg_t *
+lnet_msg_alloc (void)
+{
+	/* NEVER called with network lock held */
+	struct lnet_msg_container *msc = the_lnet.ln_msg_containers[0];
+	lnet_msg_t		  *msg;
+
+	LASSERT(LNET_CPT_NUMBER == 1);
+
+	lnet_net_lock(0);
+	msg = (lnet_msg_t *)lnet_freelist_alloc(&msc->msc_freelist);
+	lnet_net_unlock(0);
+
+	if (msg != NULL) {
+		/* NULL pointers, clear flags etc */
+		memset(msg, 0, sizeof(*msg));
+	}
+	return msg;
+}
+
+static inline void
+lnet_msg_free_locked(lnet_msg_t *msg)
+{
+	/* ALWAYS called with network lock held */
+	struct lnet_msg_container *msc = the_lnet.ln_msg_containers[0];
+
+	LASSERT(LNET_CPT_NUMBER == 1);
+	LASSERT(!msg->msg_onactivelist);
+	lnet_freelist_free(&msc->msc_freelist, msg);
+}
+
+static inline void
+lnet_msg_free (lnet_msg_t *msg)
+{
+	lnet_net_lock(0);
+	lnet_msg_free_locked(msg);
+	lnet_net_unlock(0);
+}
+
+#else /* !LNET_USE_LIB_FREELIST */
+
+static inline lnet_eq_t *
+lnet_eq_alloc (void)
+{
+	/* NEVER called with liblock held */
+	lnet_eq_t *eq;
+
+	LIBCFS_ALLOC(eq, sizeof(*eq));
+	return (eq);
+}
+
+static inline void
+lnet_eq_free(lnet_eq_t *eq)
+{
+	/* ALWAYS called with resource lock held */
+	LIBCFS_FREE(eq, sizeof(*eq));
+}
+
+static inline lnet_libmd_t *
+lnet_md_alloc (lnet_md_t *umd)
+{
+	/* NEVER called with liblock held */
+	lnet_libmd_t *md;
+	unsigned int  size;
+	unsigned int  niov;
+
+	if ((umd->options & LNET_MD_KIOV) != 0) {
+		niov = umd->length;
+		size = offsetof(lnet_libmd_t, md_iov.kiov[niov]);
+	} else {
+		niov = ((umd->options & LNET_MD_IOVEC) != 0) ?
+		       umd->length : 1;
+		size = offsetof(lnet_libmd_t, md_iov.iov[niov]);
+	}
+
+	LIBCFS_ALLOC(md, size);
+
+	if (md != NULL) {
+		/* Set here in case of early free */
+		md->md_options = umd->options;
+		md->md_niov = niov;
+		INIT_LIST_HEAD(&md->md_list);
+	}
+
+	return (md);
+}
+
+static inline void
+lnet_md_free(lnet_libmd_t *md)
+{
+	/* ALWAYS called with resource lock held */
+	unsigned int  size;
+
+	if ((md->md_options & LNET_MD_KIOV) != 0)
+		size = offsetof(lnet_libmd_t, md_iov.kiov[md->md_niov]);
+	else
+		size = offsetof(lnet_libmd_t, md_iov.iov[md->md_niov]);
+
+	LIBCFS_FREE(md, size);
+}
+
+static inline lnet_me_t *
+lnet_me_alloc (void)
+{
+	/* NEVER called with liblock held */
+	lnet_me_t *me;
+
+	LIBCFS_ALLOC(me, sizeof(*me));
+	return (me);
+}
+
+static inline void
+lnet_me_free(lnet_me_t *me)
+{
+	/* ALWAYS called with resource lock held */
+	LIBCFS_FREE(me, sizeof(*me));
+}
+
+static inline lnet_msg_t *
+lnet_msg_alloc(void)
+{
+	/* NEVER called with liblock held */
+	lnet_msg_t *msg;
+
+	LIBCFS_ALLOC(msg, sizeof(*msg));
+
+	/* no need to zero, LIBCFS_ALLOC does for us */
+	return (msg);
+}
+
+static inline void
+lnet_msg_free(lnet_msg_t *msg)
+{
+	/* ALWAYS called with network lock held */
+	LASSERT(!msg->msg_onactivelist);
+	LIBCFS_FREE(msg, sizeof(*msg));
+}
+
+#define lnet_eq_free_locked(eq)		lnet_eq_free(eq)
+#define lnet_md_free_locked(md)		lnet_md_free(md)
+#define lnet_me_free_locked(me)		lnet_me_free(me)
+#define lnet_msg_free_locked(msg)	lnet_msg_free(msg)
+
+#endif /* LNET_USE_LIB_FREELIST */
+
+lnet_libhandle_t *lnet_res_lh_lookup(struct lnet_res_container *rec,
+				     __u64 cookie);
+void lnet_res_lh_initialize(struct lnet_res_container *rec,
+			    lnet_libhandle_t *lh);
+static inline void
+lnet_res_lh_invalidate(lnet_libhandle_t *lh)
+{
+	/* ALWAYS called with resource lock held */
+	/* NB: cookie is still useful, don't reset it */
+	list_del(&lh->lh_hash_chain);
+}
+
+static inline void
+lnet_eq2handle (lnet_handle_eq_t *handle, lnet_eq_t *eq)
+{
+	if (eq == NULL) {
+		LNetInvalidateHandle(handle);
+		return;
+	}
+
+	handle->cookie = eq->eq_lh.lh_cookie;
+}
+
+static inline lnet_eq_t *
+lnet_handle2eq(lnet_handle_eq_t *handle)
+{
+	/* ALWAYS called with resource lock held */
+	lnet_libhandle_t *lh;
+
+	lh = lnet_res_lh_lookup(&the_lnet.ln_eq_container, handle->cookie);
+	if (lh == NULL)
+		return NULL;
+
+	return lh_entry(lh, lnet_eq_t, eq_lh);
+}
+
+static inline void
+lnet_md2handle (lnet_handle_md_t *handle, lnet_libmd_t *md)
+{
+	handle->cookie = md->md_lh.lh_cookie;
+}
+
+static inline lnet_libmd_t *
+lnet_handle2md(lnet_handle_md_t *handle)
+{
+	/* ALWAYS called with resource lock held */
+	lnet_libhandle_t *lh;
+	int		 cpt;
+
+	cpt = lnet_cpt_of_cookie(handle->cookie);
+	lh = lnet_res_lh_lookup(the_lnet.ln_md_containers[cpt],
+				handle->cookie);
+	if (lh == NULL)
+		return NULL;
+
+	return lh_entry(lh, lnet_libmd_t, md_lh);
+}
+
+static inline lnet_libmd_t *
+lnet_wire_handle2md(lnet_handle_wire_t *wh)
+{
+	/* ALWAYS called with resource lock held */
+	lnet_libhandle_t *lh;
+	int		 cpt;
+
+	if (wh->wh_interface_cookie != the_lnet.ln_interface_cookie)
+		return NULL;
+
+	cpt = lnet_cpt_of_cookie(wh->wh_object_cookie);
+	lh = lnet_res_lh_lookup(the_lnet.ln_md_containers[cpt],
+				wh->wh_object_cookie);
+	if (lh == NULL)
+		return NULL;
+
+	return lh_entry(lh, lnet_libmd_t, md_lh);
+}
+
+static inline void
+lnet_me2handle (lnet_handle_me_t *handle, lnet_me_t *me)
+{
+	handle->cookie = me->me_lh.lh_cookie;
+}
+
+static inline lnet_me_t *
+lnet_handle2me(lnet_handle_me_t *handle)
+{
+	/* ALWAYS called with resource lock held */
+	lnet_libhandle_t *lh;
+	int		 cpt;
+
+	cpt = lnet_cpt_of_cookie(handle->cookie);
+	lh = lnet_res_lh_lookup(the_lnet.ln_me_containers[cpt],
+				handle->cookie);
+	if (lh == NULL)
+		return NULL;
+
+	return lh_entry(lh, lnet_me_t, me_lh);
+}
+
+static inline void
+lnet_peer_addref_locked(lnet_peer_t *lp)
+{
+	LASSERT (lp->lp_refcount > 0);
+	lp->lp_refcount++;
+}
+
+extern void lnet_destroy_peer_locked(lnet_peer_t *lp);
+
+static inline void
+lnet_peer_decref_locked(lnet_peer_t *lp)
+{
+	LASSERT (lp->lp_refcount > 0);
+	lp->lp_refcount--;
+	if (lp->lp_refcount == 0)
+		lnet_destroy_peer_locked(lp);
+}
+
+static inline int
+lnet_isrouter(lnet_peer_t *lp)
+{
+	return lp->lp_rtr_refcount != 0;
+}
+
+static inline void
+lnet_ni_addref_locked(lnet_ni_t *ni, int cpt)
+{
+	LASSERT(cpt >= 0 && cpt < LNET_CPT_NUMBER);
+	LASSERT(*ni->ni_refs[cpt] >= 0);
+
+	(*ni->ni_refs[cpt])++;
+}
+
+static inline void
+lnet_ni_addref(lnet_ni_t *ni)
+{
+	lnet_net_lock(0);
+	lnet_ni_addref_locked(ni, 0);
+	lnet_net_unlock(0);
+}
+
+static inline void
+lnet_ni_decref_locked(lnet_ni_t *ni, int cpt)
+{
+	LASSERT(cpt >= 0 && cpt < LNET_CPT_NUMBER);
+	LASSERT(*ni->ni_refs[cpt] > 0);
+
+	(*ni->ni_refs[cpt])--;
+}
+
+static inline void
+lnet_ni_decref(lnet_ni_t *ni)
+{
+	lnet_net_lock(0);
+	lnet_ni_decref_locked(ni, 0);
+	lnet_net_unlock(0);
+}
+
+void lnet_ni_free(lnet_ni_t *ni);
+
+static inline int
+lnet_nid2peerhash(lnet_nid_t nid)
+{
+	return cfs_hash_long(nid, LNET_PEER_HASH_BITS);
+}
+
+static inline struct list_head *
+lnet_net2rnethash(__u32 net)
+{
+	return &the_lnet.ln_remote_nets_hash[(LNET_NETNUM(net) +
+		LNET_NETTYP(net)) &
+		((1U << the_lnet.ln_remote_nets_hbits) - 1)];
+}
+
+extern lnd_t the_lolnd;
+
+
+extern int lnet_cpt_of_nid_locked(lnet_nid_t nid);
+extern int lnet_cpt_of_nid(lnet_nid_t nid);
+extern lnet_ni_t *lnet_nid2ni_locked(lnet_nid_t nid, int cpt);
+extern lnet_ni_t *lnet_net2ni_locked(__u32 net, int cpt);
+extern lnet_ni_t *lnet_net2ni(__u32 net);
+
+int lnet_notify(lnet_ni_t *ni, lnet_nid_t peer, int alive, cfs_time_t when);
+void lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, cfs_time_t when);
+int lnet_add_route(__u32 net, unsigned int hops, lnet_nid_t gateway_nid);
+int lnet_check_routes(void);
+int lnet_del_route(__u32 net, lnet_nid_t gw_nid);
+void lnet_destroy_routes(void);
+int lnet_get_route(int idx, __u32 *net, __u32 *hops,
+		   lnet_nid_t *gateway, __u32 *alive);
+void lnet_proc_init(void);
+void lnet_proc_fini(void);
+int  lnet_rtrpools_alloc(int im_a_router);
+void lnet_rtrpools_free(void);
+lnet_remotenet_t *lnet_find_net_locked (__u32 net);
+
+int lnet_islocalnid(lnet_nid_t nid);
+int lnet_islocalnet(__u32 net);
+
+void lnet_msg_attach_md(lnet_msg_t *msg, lnet_libmd_t *md,
+			unsigned int offset, unsigned int mlen);
+void lnet_msg_detach_md(lnet_msg_t *msg, int status);
+void lnet_build_unlink_event(lnet_libmd_t *md, lnet_event_t *ev);
+void lnet_build_msg_event(lnet_msg_t *msg, lnet_event_kind_t ev_type);
+void lnet_msg_commit(lnet_msg_t *msg, int cpt);
+void lnet_msg_decommit(lnet_msg_t *msg, int cpt, int status);
+
+void lnet_eq_enqueue_event(lnet_eq_t *eq, lnet_event_t *ev);
+void lnet_prep_send(lnet_msg_t *msg, int type, lnet_process_id_t target,
+		    unsigned int offset, unsigned int len);
+int lnet_send(lnet_nid_t nid, lnet_msg_t *msg, lnet_nid_t rtr_nid);
+void lnet_return_tx_credits_locked(lnet_msg_t *msg);
+void lnet_return_rx_credits_locked(lnet_msg_t *msg);
+
+/* portals functions */
+/* portals attributes */
+static inline int
+lnet_ptl_is_lazy(lnet_portal_t *ptl)
+{
+	return !!(ptl->ptl_options & LNET_PTL_LAZY);
+}
+
+static inline int
+lnet_ptl_is_unique(lnet_portal_t *ptl)
+{
+	return !!(ptl->ptl_options & LNET_PTL_MATCH_UNIQUE);
+}
+
+static inline int
+lnet_ptl_is_wildcard(lnet_portal_t *ptl)
+{
+	return !!(ptl->ptl_options & LNET_PTL_MATCH_WILDCARD);
+}
+
+static inline void
+lnet_ptl_setopt(lnet_portal_t *ptl, int opt)
+{
+	ptl->ptl_options |= opt;
+}
+
+static inline void
+lnet_ptl_unsetopt(lnet_portal_t *ptl, int opt)
+{
+	ptl->ptl_options &= ~opt;
+}
+
+/* match-table functions */
+struct list_head *lnet_mt_match_head(struct lnet_match_table *mtable,
+			       lnet_process_id_t id, __u64 mbits);
+struct lnet_match_table *lnet_mt_of_attach(unsigned int index,
+					   lnet_process_id_t id, __u64 mbits,
+					   __u64 ignore_bits,
+					   lnet_ins_pos_t pos);
+int lnet_mt_match_md(struct lnet_match_table *mtable,
+		     struct lnet_match_info *info, struct lnet_msg *msg);
+
+/* portals match/attach functions */
+void lnet_ptl_attach_md(lnet_me_t *me, lnet_libmd_t *md,
+			struct list_head *matches, struct list_head *drops);
+void lnet_ptl_detach_md(lnet_me_t *me, lnet_libmd_t *md);
+int lnet_ptl_match_md(struct lnet_match_info *info, struct lnet_msg *msg);
+
+/* initialized and finalize portals */
+int lnet_portals_create(void);
+void lnet_portals_destroy(void);
+
+/* message functions */
+int lnet_parse (lnet_ni_t *ni, lnet_hdr_t *hdr,
+		lnet_nid_t fromnid, void *private, int rdma_req);
+void lnet_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
+	       unsigned int offset, unsigned int mlen, unsigned int rlen);
+lnet_msg_t *lnet_create_reply_msg (lnet_ni_t *ni, lnet_msg_t *get_msg);
+void lnet_set_reply_msg_len(lnet_ni_t *ni, lnet_msg_t *msg, unsigned int len);
+void lnet_finalize(lnet_ni_t *ni, lnet_msg_t *msg, int rc);
+void lnet_drop_delayed_msg_list(struct list_head *head, char *reason);
+void lnet_recv_delayed_msg_list(struct list_head *head);
+
+int lnet_msg_container_setup(struct lnet_msg_container *container, int cpt);
+void lnet_msg_container_cleanup(struct lnet_msg_container *container);
+void lnet_msg_containers_destroy(void);
+int lnet_msg_containers_create(void);
+
+char *lnet_msgtyp2str (int type);
+void lnet_print_hdr (lnet_hdr_t * hdr);
+int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold);
+
+void lnet_counters_get(lnet_counters_t *counters);
+void lnet_counters_reset(void);
+
+unsigned int lnet_iov_nob (unsigned int niov, struct iovec *iov);
+int lnet_extract_iov (int dst_niov, struct iovec *dst,
+		      int src_niov, struct iovec *src,
+		      unsigned int offset, unsigned int len);
+
+unsigned int lnet_kiov_nob (unsigned int niov, lnet_kiov_t *iov);
+int lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
+		      int src_niov, lnet_kiov_t *src,
+		      unsigned int offset, unsigned int len);
+
+void lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov,
+			unsigned int doffset,
+			unsigned int nsiov, struct iovec *siov,
+			unsigned int soffset, unsigned int nob);
+void lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov,
+			 unsigned int iovoffset,
+			 unsigned int nkiov, lnet_kiov_t *kiov,
+			 unsigned int kiovoffset, unsigned int nob);
+void lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov,
+			 unsigned int kiovoffset,
+			 unsigned int niov, struct iovec *iov,
+			 unsigned int iovoffset, unsigned int nob);
+void lnet_copy_kiov2kiov (unsigned int ndkiov, lnet_kiov_t *dkiov,
+			  unsigned int doffset,
+			  unsigned int nskiov, lnet_kiov_t *skiov,
+			  unsigned int soffset, unsigned int nob);
+
+static inline void
+lnet_copy_iov2flat(int dlen, void *dest, unsigned int doffset,
+		   unsigned int nsiov, struct iovec *siov, unsigned int soffset,
+		   unsigned int nob)
+{
+	struct iovec diov = {/*.iov_base = */ dest, /*.iov_len = */ dlen};
+
+	lnet_copy_iov2iov(1, &diov, doffset,
+			  nsiov, siov, soffset, nob);
+}
+
+static inline void
+lnet_copy_kiov2flat(int dlen, void *dest, unsigned int doffset,
+		    unsigned int nsiov, lnet_kiov_t *skiov, unsigned int soffset,
+		    unsigned int nob)
+{
+	struct iovec diov = {/* .iov_base = */ dest, /* .iov_len = */ dlen};
+
+	lnet_copy_kiov2iov(1, &diov, doffset,
+			   nsiov, skiov, soffset, nob);
+}
+
+static inline void
+lnet_copy_flat2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
+		   int slen, void *src, unsigned int soffset, unsigned int nob)
+{
+	struct iovec siov = {/*.iov_base = */ src, /*.iov_len = */slen};
+	lnet_copy_iov2iov(ndiov, diov, doffset,
+			  1, &siov, soffset, nob);
+}
+
+static inline void
+lnet_copy_flat2kiov(unsigned int ndiov, lnet_kiov_t *dkiov, unsigned int doffset,
+		    int slen, void *src, unsigned int soffset, unsigned int nob)
+{
+	struct iovec siov = {/* .iov_base = */ src, /* .iov_len = */ slen};
+	lnet_copy_iov2kiov(ndiov, dkiov, doffset,
+			   1, &siov, soffset, nob);
+}
+
+void lnet_me_unlink(lnet_me_t *me);
+
+void lnet_md_unlink(lnet_libmd_t *md);
+void lnet_md_deconstruct(lnet_libmd_t *lmd, lnet_md_t *umd);
+
+void lnet_register_lnd(lnd_t *lnd);
+void lnet_unregister_lnd(lnd_t *lnd);
+int lnet_set_ip_niaddr (lnet_ni_t *ni);
+
+int lnet_connect(socket_t **sockp, lnet_nid_t peer_nid,
+		 __u32 local_ip, __u32 peer_ip, int peer_port);
+void lnet_connect_console_error(int rc, lnet_nid_t peer_nid,
+				__u32 peer_ip, int port);
+int lnet_count_acceptor_nis(void);
+int lnet_acceptor_timeout(void);
+int lnet_acceptor_port(void);
+
+int lnet_count_acceptor_nis(void);
+int lnet_acceptor_port(void);
+
+int lnet_acceptor_start(void);
+void lnet_acceptor_stop(void);
+
+void lnet_get_tunables(void);
+int lnet_peers_start_down(void);
+int lnet_peer_buffer_credits(lnet_ni_t *ni);
+
+int lnet_router_checker_start(void);
+void lnet_router_checker_stop(void);
+void lnet_swap_pinginfo(lnet_ping_info_t *info);
+
+int lnet_ping_target_init(void);
+void lnet_ping_target_fini(void);
+int lnet_ping(lnet_process_id_t id, int timeout_ms,
+	      lnet_process_id_t *ids, int n_ids);
+
+int lnet_parse_ip2nets (char **networksp, char *ip2nets);
+int lnet_parse_routes (char *route_str, int *im_a_router);
+int lnet_parse_networks (struct list_head *nilist, char *networks);
+
+int lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid, int cpt);
+lnet_peer_t *lnet_find_peer_locked(struct lnet_peer_table *ptable,
+				   lnet_nid_t nid);
+void lnet_peer_tables_cleanup(void);
+void lnet_peer_tables_destroy(void);
+int lnet_peer_tables_create(void);
+void lnet_debug_peer(lnet_nid_t nid);
+
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lib-types.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lib-types.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lib-types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lib-types.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,765 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/include/lnet/lib-types.h
+ *
+ * Types used by the library side routines that do not need to be
+ * exposed to the user application
+ */
+
+#ifndef __LNET_LIB_TYPES_H__
+#define __LNET_LIB_TYPES_H__
+
+#include <linux/lnet/linux/lib-types.h>
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/list.h>
+#include <linux/lnet/types.h>
+
+#define WIRE_ATTR       __attribute__((packed))
+
+/* Packed version of lnet_process_id_t to transfer via network */
+typedef struct {
+	lnet_nid_t nid;
+	lnet_pid_t pid;   /* node id / process id */
+} WIRE_ATTR lnet_process_id_packed_t;
+
+/* The wire handle's interface cookie only matches one network interface in
+ * one epoch (i.e. new cookie when the interface restarts or the node
+ * reboots).  The object cookie only matches one object on that interface
+ * during that object's lifetime (i.e. no cookie re-use). */
+typedef struct {
+	__u64 wh_interface_cookie;
+	__u64 wh_object_cookie;
+} WIRE_ATTR lnet_handle_wire_t;
+
+typedef enum {
+	LNET_MSG_ACK = 0,
+	LNET_MSG_PUT,
+	LNET_MSG_GET,
+	LNET_MSG_REPLY,
+	LNET_MSG_HELLO,
+} lnet_msg_type_t;
+
+/* The variant fields of the portals message header are aligned on an 8
+ * byte boundary in the message header.  Note that all types used in these
+ * wire structs MUST be fixed size and the smaller types are placed at the
+ * end. */
+typedef struct lnet_ack {
+	lnet_handle_wire_t  dst_wmd;
+	__u64	       match_bits;
+	__u32	       mlength;
+} WIRE_ATTR lnet_ack_t;
+
+typedef struct lnet_put {
+	lnet_handle_wire_t  ack_wmd;
+	__u64	       match_bits;
+	__u64	       hdr_data;
+	__u32	       ptl_index;
+	__u32	       offset;
+} WIRE_ATTR lnet_put_t;
+
+typedef struct lnet_get {
+	lnet_handle_wire_t  return_wmd;
+	__u64	       match_bits;
+	__u32	       ptl_index;
+	__u32	       src_offset;
+	__u32	       sink_length;
+} WIRE_ATTR lnet_get_t;
+
+typedef struct lnet_reply {
+	lnet_handle_wire_t  dst_wmd;
+} WIRE_ATTR lnet_reply_t;
+
+typedef struct lnet_hello {
+	__u64	      incarnation;
+	__u32	      type;
+} WIRE_ATTR lnet_hello_t;
+
+typedef struct {
+	lnet_nid_t	  dest_nid;
+	lnet_nid_t	  src_nid;
+	lnet_pid_t	  dest_pid;
+	lnet_pid_t	  src_pid;
+	__u32	       type;	       /* lnet_msg_type_t */
+	__u32	       payload_length;     /* payload data to follow */
+	/*<------__u64 aligned------->*/
+	union {
+		lnet_ack_t   ack;
+		lnet_put_t   put;
+		lnet_get_t   get;
+		lnet_reply_t reply;
+		lnet_hello_t hello;
+	} msg;
+} WIRE_ATTR lnet_hdr_t;
+
+/* A HELLO message contains a magic number and protocol version
+ * code in the header's dest_nid, the peer's NID in the src_nid, and
+ * LNET_MSG_HELLO in the type field.  All other common fields are zero
+ * (including payload_size; i.e. no payload).
+ * This is for use by byte-stream LNDs (e.g. TCP/IP) to check the peer is
+ * running the same protocol and to find out its NID. These LNDs should
+ * exchange HELLO messages when a connection is first established.  Individual
+ * LNDs can put whatever else they fancy in lnet_hdr_t::msg.
+ */
+typedef struct {
+	__u32   magic;			  /* LNET_PROTO_TCP_MAGIC */
+	__u16   version_major;		  /* increment on incompatible change */
+	__u16   version_minor;		  /* increment on compatible change */
+} WIRE_ATTR lnet_magicversion_t;
+
+/* PROTO MAGIC for LNDs */
+#define LNET_PROTO_IB_MAGIC		 0x0be91b91
+#define LNET_PROTO_RA_MAGIC		 0x0be91b92
+#define LNET_PROTO_QSW_MAGIC		0x0be91b93
+#define LNET_PROTO_GNI_MAGIC		0xb00fbabe /* ask Kim */
+#define LNET_PROTO_TCP_MAGIC		0xeebc0ded
+#define LNET_PROTO_PTL_MAGIC		0x50746C4E /* 'PtlN' unique magic */
+#define LNET_PROTO_MX_MAGIC		 0x4d583130 /* 'MX10'! */
+#define LNET_PROTO_ACCEPTOR_MAGIC	   0xacce7100
+#define LNET_PROTO_PING_MAGIC	       0x70696E67 /* 'ping' */
+
+/* Placeholder for a future "unified" protocol across all LNDs */
+/* Current LNDs that receive a request with this magic will respond with a
+ * "stub" reply using their current protocol */
+#define LNET_PROTO_MAGIC		    0x45726963 /* ! */
+
+
+#define LNET_PROTO_TCP_VERSION_MAJOR	1
+#define LNET_PROTO_TCP_VERSION_MINOR	0
+
+/* Acceptor connection request */
+typedef struct {
+	__u32       acr_magic;		  /* PTL_ACCEPTOR_PROTO_MAGIC */
+	__u32       acr_version;		/* protocol version */
+	__u64       acr_nid;		    /* target NID */
+} WIRE_ATTR lnet_acceptor_connreq_t;
+
+#define LNET_PROTO_ACCEPTOR_VERSION       1
+
+/* forward refs */
+struct lnet_libmd;
+
+typedef struct lnet_msg {
+	struct list_head	    msg_activelist;
+	struct list_head	    msg_list;	   /* Q for credits/MD */
+
+	lnet_process_id_t     msg_target;
+	/* where is it from, it's only for building event */
+	lnet_nid_t		msg_from;
+	__u32			msg_type;
+
+	/* commited for sending */
+	unsigned int		msg_tx_committed:1;
+	/* CPT # this message committed for sending */
+	unsigned int		msg_tx_cpt:15;
+	/* commited for receiving */
+	unsigned int		msg_rx_committed:1;
+	/* CPT # this message committed for receiving */
+	unsigned int		msg_rx_cpt:15;
+	/* queued for tx credit */
+	unsigned int		msg_tx_delayed:1;
+	/* queued for RX buffer */
+	unsigned int		msg_rx_delayed:1;
+	/* ready for pending on RX delay list */
+	unsigned int		msg_rx_ready_delay:1;
+
+	unsigned int	  msg_vmflush:1;      /* VM trying to free memory */
+	unsigned int	  msg_target_is_router:1; /* sending to a router */
+	unsigned int	  msg_routing:1;      /* being forwarded */
+	unsigned int	  msg_ack:1;	  /* ack on finalize (PUT) */
+	unsigned int	  msg_sending:1;      /* outgoing message */
+	unsigned int	  msg_receiving:1;    /* being received */
+	unsigned int	  msg_txcredit:1;     /* taken an NI send credit */
+	unsigned int	  msg_peertxcredit:1; /* taken a peer send credit */
+	unsigned int	  msg_rtrcredit:1;    /* taken a globel router credit */
+	unsigned int	  msg_peerrtrcredit:1; /* taken a peer router credit */
+	unsigned int	  msg_onactivelist:1; /* on the activelist */
+
+	struct lnet_peer     *msg_txpeer;	 /* peer I'm sending to */
+	struct lnet_peer     *msg_rxpeer;	 /* peer I received from */
+
+	void		 *msg_private;
+	struct lnet_libmd    *msg_md;
+
+	unsigned int	  msg_len;
+	unsigned int	  msg_wanted;
+	unsigned int	  msg_offset;
+	unsigned int	  msg_niov;
+	struct iovec	 *msg_iov;
+	lnet_kiov_t	  *msg_kiov;
+
+	lnet_event_t	  msg_ev;
+	lnet_hdr_t	    msg_hdr;
+} lnet_msg_t;
+
+
+typedef struct lnet_libhandle {
+	struct list_head	    lh_hash_chain;
+	__u64		 lh_cookie;
+} lnet_libhandle_t;
+
+#define lh_entry(ptr, type, member) \
+	((type *)((char *)(ptr)-(char *)(&((type *)0)->member)))
+
+typedef struct lnet_eq {
+	struct list_head		eq_list;
+	lnet_libhandle_t	eq_lh;
+	lnet_seq_t		eq_enq_seq;
+	lnet_seq_t		eq_deq_seq;
+	unsigned int		eq_size;
+	lnet_eq_handler_t	eq_callback;
+	lnet_event_t		*eq_events;
+	int			**eq_refs;	/* percpt refcount for EQ */
+} lnet_eq_t;
+
+typedef struct lnet_me {
+	struct list_head	     me_list;
+	lnet_libhandle_t       me_lh;
+	lnet_process_id_t      me_match_id;
+	unsigned int	   me_portal;
+	unsigned int	   me_pos;		/* hash offset in mt_hash */
+	__u64		  me_match_bits;
+	__u64		  me_ignore_bits;
+	lnet_unlink_t	  me_unlink;
+	struct lnet_libmd     *me_md;
+} lnet_me_t;
+
+typedef struct lnet_libmd {
+	struct list_head	    md_list;
+	lnet_libhandle_t      md_lh;
+	lnet_me_t	    *md_me;
+	char		 *md_start;
+	unsigned int	  md_offset;
+	unsigned int	  md_length;
+	unsigned int	  md_max_size;
+	int		   md_threshold;
+	int		   md_refcount;
+	unsigned int	  md_options;
+	unsigned int	  md_flags;
+	void		 *md_user_ptr;
+	lnet_eq_t	    *md_eq;
+	unsigned int	  md_niov;		/* # frags */
+	union {
+		struct iovec  iov[LNET_MAX_IOV];
+		lnet_kiov_t   kiov[LNET_MAX_IOV];
+	} md_iov;
+} lnet_libmd_t;
+
+#define LNET_MD_FLAG_ZOMBIE	   (1 << 0)
+#define LNET_MD_FLAG_AUTO_UNLINK      (1 << 1)
+
+#ifdef LNET_USE_LIB_FREELIST
+typedef struct
+{
+	void		  *fl_objs;	  /* single contiguous array of objects */
+	int		    fl_nobjs;	 /* the number of them */
+	int		    fl_objsize;       /* the size (including overhead) of each of them */
+	struct list_head	     fl_list;	  /* where they are enqueued */
+} lnet_freelist_t;
+
+typedef struct
+{
+	struct list_head	     fo_list;	     /* enqueue on fl_list */
+	void		  *fo_contents;	 /* aligned contents */
+} lnet_freeobj_t;
+#endif
+
+typedef struct {
+	/* info about peers we are trying to fail */
+	struct list_head	     tp_list;	     /* ln_test_peers */
+	lnet_nid_t	     tp_nid;	      /* matching nid */
+	unsigned int	   tp_threshold;	/* # failures to simulate */
+} lnet_test_peer_t;
+
+#define LNET_COOKIE_TYPE_MD    1
+#define LNET_COOKIE_TYPE_ME    2
+#define LNET_COOKIE_TYPE_EQ    3
+#define LNET_COOKIE_TYPE_BITS  2
+#define LNET_COOKIE_MASK	((1ULL << LNET_COOKIE_TYPE_BITS) - 1ULL)
+
+struct lnet_ni;				  /* forward ref */
+
+typedef struct lnet_lnd
+{
+	/* fields managed by portals */
+	struct list_head	    lnd_list;	     /* stash in the LND table */
+	int		   lnd_refcount;	 /* # active instances */
+
+	/* fields initialised by the LND */
+	unsigned int	  lnd_type;
+
+	int  (*lnd_startup) (struct lnet_ni *ni);
+	void (*lnd_shutdown) (struct lnet_ni *ni);
+	int  (*lnd_ctl)(struct lnet_ni *ni, unsigned int cmd, void *arg);
+
+	/* In data movement APIs below, payload buffers are described as a set
+	 * of 'niov' fragments which are...
+	 * EITHER
+	 *    in virtual memory (struct iovec *iov != NULL)
+	 * OR
+	 *    in pages (kernel only: plt_kiov_t *kiov != NULL).
+	 * The LND may NOT overwrite these fragment descriptors.
+	 * An 'offset' and may specify a byte offset within the set of
+	 * fragments to start from
+	 */
+
+	/* Start sending a preformatted message.  'private' is NULL for PUT and
+	 * GET messages; otherwise this is a response to an incoming message
+	 * and 'private' is the 'private' passed to lnet_parse().  Return
+	 * non-zero for immediate failure, otherwise complete later with
+	 * lnet_finalize() */
+	int (*lnd_send)(struct lnet_ni *ni, void *private, lnet_msg_t *msg);
+
+	/* Start receiving 'mlen' bytes of payload data, skipping the following
+	 * 'rlen' - 'mlen' bytes. 'private' is the 'private' passed to
+	 * lnet_parse().  Return non-zero for immedaite failure, otherwise
+	 * complete later with lnet_finalize().  This also gives back a receive
+	 * credit if the LND does flow control. */
+	int (*lnd_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
+			int delayed, unsigned int niov,
+			struct iovec *iov, lnet_kiov_t *kiov,
+			unsigned int offset, unsigned int mlen, unsigned int rlen);
+
+	/* lnet_parse() has had to delay processing of this message
+	 * (e.g. waiting for a forwarding buffer or send credits).  Give the
+	 * LND a chance to free urgently needed resources.  If called, return 0
+	 * for success and do NOT give back a receive credit; that has to wait
+	 * until lnd_recv() gets called.  On failure return < 0 and
+	 * release resources; lnd_recv() will not be called. */
+	int (*lnd_eager_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
+			      void **new_privatep);
+
+	/* notification of peer health */
+	void (*lnd_notify)(struct lnet_ni *ni, lnet_nid_t peer, int alive);
+
+	/* query of peer aliveness */
+	void (*lnd_query)(struct lnet_ni *ni, lnet_nid_t peer, cfs_time_t *when);
+
+	/* accept a new connection */
+	int (*lnd_accept)(struct lnet_ni *ni, socket_t *sock);
+
+} lnd_t;
+
+#define LNET_NI_STATUS_UP      0x15aac0de
+#define LNET_NI_STATUS_DOWN    0xdeadface
+#define LNET_NI_STATUS_INVALID 0x00000000
+typedef struct {
+	lnet_nid_t ns_nid;
+	__u32      ns_status;
+	__u32      ns_unused;
+} WIRE_ATTR lnet_ni_status_t;
+
+struct lnet_tx_queue {
+	int			tq_credits;	/* # tx credits free */
+	int			tq_credits_min;	/* lowest it's been */
+	int			tq_credits_max;	/* total # tx credits */
+	struct list_head		tq_delayed;	/* delayed TXs */
+};
+
+#define LNET_MAX_INTERFACES   16
+
+typedef struct lnet_ni {
+	spinlock_t		ni_lock;
+	struct list_head		ni_list;	/* chain on ln_nis */
+	struct list_head		ni_cptlist;	/* chain on ln_nis_cpt */
+	int			ni_maxtxcredits; /* # tx credits  */
+	/* # per-peer send credits */
+	int			ni_peertxcredits;
+	/* # per-peer router buffer credits */
+	int			ni_peerrtrcredits;
+	/* seconds to consider peer dead */
+	int			ni_peertimeout;
+	int			ni_ncpts;	/* number of CPTs */
+	__u32			*ni_cpts;	/* bond NI on some CPTs */
+	lnet_nid_t		ni_nid;		/* interface's NID */
+	void			*ni_data;	/* instance-specific data */
+	lnd_t			*ni_lnd;	/* procedural interface */
+	struct lnet_tx_queue	**ni_tx_queues;	/* percpt TX queues */
+	int			**ni_refs;	/* percpt reference count */
+	long			ni_last_alive;	/* when I was last alive */
+	lnet_ni_status_t	*ni_status;	/* my health status */
+	/* equivalent interfaces to use */
+	char			*ni_interfaces[LNET_MAX_INTERFACES];
+} lnet_ni_t;
+
+#define LNET_PROTO_PING_MATCHBITS	0x8000000000000000LL
+
+/* NB: value of these features equal to LNET_PROTO_PING_VERSION_x
+ * of old LNet, so there shouldn't be any compatibility issue */
+#define LNET_PING_FEAT_INVAL		(0)		/* no feature */
+#define LNET_PING_FEAT_BASE		(1 << 0)	/* just a ping */
+#define LNET_PING_FEAT_NI_STATUS	(1 << 1)	/* return NI status */
+
+#define LNET_PING_FEAT_MASK		(LNET_PING_FEAT_BASE | \
+					 LNET_PING_FEAT_NI_STATUS)
+
+typedef struct {
+	__u32			pi_magic;
+	__u32			pi_features;
+	lnet_pid_t		pi_pid;
+	__u32			pi_nnis;
+	lnet_ni_status_t	pi_ni[0];
+} WIRE_ATTR lnet_ping_info_t;
+
+/* router checker data, per router */
+#define LNET_MAX_RTR_NIS   16
+#define LNET_PINGINFO_SIZE offsetof(lnet_ping_info_t, pi_ni[LNET_MAX_RTR_NIS])
+typedef struct {
+	/* chain on the_lnet.ln_zombie_rcd or ln_deathrow_rcd */
+	struct list_head		rcd_list;
+	lnet_handle_md_t	rcd_mdh;	/* ping buffer MD */
+	struct lnet_peer	*rcd_gateway;	/* reference to gateway */
+	lnet_ping_info_t	*rcd_pinginfo;	/* ping buffer */
+} lnet_rc_data_t;
+
+typedef struct lnet_peer {
+	struct list_head	lp_hashlist;	  /* chain on peer hash */
+	struct list_head	lp_txq;	       /* messages blocking for tx credits */
+	struct list_head	lp_rtrq;	      /* messages blocking for router credits */
+	struct list_head	lp_rtr_list;	  /* chain on router list */
+	int	       lp_txcredits;	 /* # tx credits available */
+	int	       lp_mintxcredits;      /* low water mark */
+	int	       lp_rtrcredits;	/* # router credits */
+	int	       lp_minrtrcredits;     /* low water mark */
+	unsigned int      lp_alive:1;	   /* alive/dead? */
+	unsigned int      lp_notify:1;	  /* notification outstanding? */
+	unsigned int      lp_notifylnd:1;       /* outstanding notification for LND? */
+	unsigned int      lp_notifying:1;       /* some thread is handling notification */
+	unsigned int      lp_ping_notsent;      /* SEND event outstanding from ping */
+	int	       lp_alive_count;       /* # times router went dead<->alive */
+	long	      lp_txqnob;	    /* bytes queued for sending */
+	cfs_time_t	lp_timestamp;	 /* time of last aliveness news */
+	cfs_time_t	lp_ping_timestamp;    /* time of last ping attempt */
+	cfs_time_t	lp_ping_deadline;     /* != 0 if ping reply expected */
+	cfs_time_t	lp_last_alive;	/* when I was last alive */
+	cfs_time_t	lp_last_query;	/* when lp_ni was queried last time */
+	lnet_ni_t	*lp_ni;		/* interface peer is on */
+	lnet_nid_t	lp_nid;	       /* peer's NID */
+	int	       lp_refcount;	  /* # refs */
+	int			lp_cpt;		/* CPT this peer attached on */
+	/* # refs from lnet_route_t::lr_gateway */
+	int			lp_rtr_refcount;
+	/* returned RC ping features */
+	unsigned int		lp_ping_feats;
+	struct list_head		lp_routes;	/* routers on this peer */
+	lnet_rc_data_t		*lp_rcd;	/* router checker state */
+} lnet_peer_t;
+
+
+/* peer hash size */
+#define LNET_PEER_HASH_BITS     9
+#define LNET_PEER_HASH_SIZE     (1 << LNET_PEER_HASH_BITS)
+
+/* peer hash table */
+struct lnet_peer_table {
+	int			pt_version;	/* /proc validity stamp */
+	int			pt_number;	/* # peers extant */
+	struct list_head		pt_deathrow;	/* zombie peers */
+	struct list_head		*pt_hash;	/* NID->peer hash */
+};
+
+/* peer aliveness is enabled only on routers for peers in a network where the
+ * lnet_ni_t::ni_peertimeout has been set to a positive value */
+#define lnet_peer_aliveness_enabled(lp) (the_lnet.ln_routing != 0 && \
+					 (lp)->lp_ni->ni_peertimeout > 0)
+
+typedef struct {
+	struct list_head		lr_list;	/* chain on net */
+	struct list_head		lr_gwlist;	/* chain on gateway */
+	lnet_peer_t		*lr_gateway;	/* router node */
+	__u32			lr_net;		/* remote network number */
+	int			lr_seq;		/* sequence for round-robin */
+	unsigned int		lr_downis;	/* number of down NIs */
+	unsigned int		lr_hops;	/* how far I am */
+} lnet_route_t;
+
+#define LNET_REMOTE_NETS_HASH_DEFAULT	(1U << 7)
+#define LNET_REMOTE_NETS_HASH_MAX	(1U << 16)
+#define LNET_REMOTE_NETS_HASH_SIZE	(1 << the_lnet.ln_remote_nets_hbits)
+
+typedef struct {
+	struct list_head	      lrn_list;       /* chain on ln_remote_nets_hash */
+	struct list_head	      lrn_routes;     /* routes to me */
+	__u32		   lrn_net;	/* my net number */
+} lnet_remotenet_t;
+
+typedef struct {
+	struct list_head rbp_bufs;	     /* my free buffer pool */
+	struct list_head rbp_msgs;	     /* messages blocking for a buffer */
+	int	rbp_npages;	   /* # pages in each buffer */
+	int	rbp_nbuffers;	 /* # buffers */
+	int	rbp_credits;	  /* # free buffers / blocked messages */
+	int	rbp_mincredits;       /* low water mark */
+} lnet_rtrbufpool_t;
+
+typedef struct {
+	struct list_head	     rb_list;	     /* chain on rbp_bufs */
+	lnet_rtrbufpool_t     *rb_pool;	     /* owning pool */
+	lnet_kiov_t	    rb_kiov[0];	  /* the buffer space */
+} lnet_rtrbuf_t;
+
+typedef struct {
+	__u32	msgs_alloc;
+	__u32	msgs_max;
+	__u32	errors;
+	__u32	send_count;
+	__u32	recv_count;
+	__u32	route_count;
+	__u32	drop_count;
+	__u64	send_length;
+	__u64	recv_length;
+	__u64	route_length;
+	__u64	drop_length;
+} WIRE_ATTR lnet_counters_t;
+
+#define LNET_PEER_HASHSIZE   503		/* prime! */
+
+#define LNET_NRBPOOLS	 3		 /* # different router buffer pools */
+
+enum {
+	/* Didn't match anything */
+	LNET_MATCHMD_NONE	= (1 << 0),
+	/* Matched OK */
+	LNET_MATCHMD_OK		= (1 << 1),
+	/* Must be discarded */
+	LNET_MATCHMD_DROP	= (1 << 2),
+	/* match and buffer is exhausted */
+	LNET_MATCHMD_EXHAUSTED  = (1 << 3),
+	/* match or drop */
+	LNET_MATCHMD_FINISH     = (LNET_MATCHMD_OK | LNET_MATCHMD_DROP),
+};
+
+/* Options for lnet_portal_t::ptl_options */
+#define LNET_PTL_LAZY	       (1 << 0)
+#define LNET_PTL_MATCH_UNIQUE       (1 << 1)    /* unique match, for RDMA */
+#define LNET_PTL_MATCH_WILDCARD     (1 << 2)    /* wildcard match, request portal */
+
+/* parameter for matching operations (GET, PUT) */
+struct lnet_match_info {
+	__u64			mi_mbits;
+	lnet_process_id_t	mi_id;
+	unsigned int		mi_opc;
+	unsigned int		mi_portal;
+	unsigned int		mi_rlength;
+	unsigned int		mi_roffset;
+};
+
+/* ME hash of RDMA portal */
+#define LNET_MT_HASH_BITS		8
+#define LNET_MT_HASH_SIZE		(1 << LNET_MT_HASH_BITS)
+#define LNET_MT_HASH_MASK		(LNET_MT_HASH_SIZE - 1)
+/* we allocate (LNET_MT_HASH_SIZE + 1) entries for lnet_match_table::mt_hash,
+ * the last entry is reserved for MEs with ignore-bits */
+#define LNET_MT_HASH_IGNORE		LNET_MT_HASH_SIZE
+/* __u64 has 2^6 bits, so need 2^(LNET_MT_HASH_BITS - LNET_MT_BITS_U64) which
+ * is 4 __u64s as bit-map, and add an extra __u64 (only use one bit) for the
+ * ME-list with ignore-bits, which is mtable::mt_hash[LNET_MT_HASH_IGNORE] */
+#define LNET_MT_BITS_U64		6	/* 2^6 bits */
+#define LNET_MT_EXHAUSTED_BITS		(LNET_MT_HASH_BITS - LNET_MT_BITS_U64)
+#define LNET_MT_EXHAUSTED_BMAP		((1 << LNET_MT_EXHAUSTED_BITS) + 1)
+
+/* portal match table */
+struct lnet_match_table {
+	/* reserved for upcoming patches, CPU partition ID */
+	unsigned int		mt_cpt;
+	unsigned int		mt_portal;      /* portal index */
+	/* match table is set as "enabled" if there's non-exhausted MD
+	 * attached on mt_mhash, it's only valide for wildcard portal */
+	unsigned int		mt_enabled;
+	/* bitmap to flag whether MEs on mt_hash are exhausted or not */
+	__u64			mt_exhausted[LNET_MT_EXHAUSTED_BMAP];
+	struct list_head		*mt_mhash;      /* matching hash */
+};
+
+/* these are only useful for wildcard portal */
+/* Turn off message rotor for wildcard portals */
+#define	LNET_PTL_ROTOR_OFF	0
+/* round-robin dispatch all PUT messages for wildcard portals */
+#define	LNET_PTL_ROTOR_ON	1
+/* round-robin dispatch routed PUT message for wildcard portals */
+#define	LNET_PTL_ROTOR_RR_RT	2
+/* dispatch routed PUT message by hashing source NID for wildcard portals */
+#define	LNET_PTL_ROTOR_HASH_RT	3
+
+typedef struct lnet_portal {
+	spinlock_t		ptl_lock;
+	unsigned int		ptl_index;	/* portal ID, reserved */
+	/* flags on this portal: lazy, unique... */
+	unsigned int		ptl_options;
+	/* list of messags which are stealing buffer */
+	struct list_head		ptl_msg_stealing;
+	/* messages blocking for MD */
+	struct list_head		ptl_msg_delayed;
+	/* Match table for each CPT */
+	struct lnet_match_table	**ptl_mtables;
+	/* spread rotor of incoming "PUT" */
+	int			ptl_rotor;
+	/* # active entries for this portal */
+	int		     ptl_mt_nmaps;
+	/* array of active entries' cpu-partition-id */
+	int		     ptl_mt_maps[0];
+} lnet_portal_t;
+
+#define LNET_LH_HASH_BITS	12
+#define LNET_LH_HASH_SIZE	(1ULL << LNET_LH_HASH_BITS)
+#define LNET_LH_HASH_MASK	(LNET_LH_HASH_SIZE - 1)
+
+/* resource container (ME, MD, EQ) */
+struct lnet_res_container {
+	unsigned int		rec_type;	/* container type */
+	__u64			rec_lh_cookie;	/* cookie generator */
+	struct list_head		rec_active;	/* active resource list */
+	struct list_head		*rec_lh_hash;	/* handle hash */
+#ifdef LNET_USE_LIB_FREELIST
+	lnet_freelist_t		rec_freelist;	/* freelist for resources */
+#endif
+};
+
+/* message container */
+struct lnet_msg_container {
+	int			msc_init;	/* initialized or not */
+	/* max # threads finalizing */
+	int			msc_nfinalizers;
+	/* msgs waiting to complete finalizing */
+	struct list_head		msc_finalizing;
+	struct list_head		msc_active;	/* active message list */
+	/* threads doing finalization */
+	void			**msc_finalizers;
+#ifdef LNET_USE_LIB_FREELIST
+	lnet_freelist_t		msc_freelist;	/* freelist for messages */
+#endif
+};
+
+/* Router Checker states */
+#define LNET_RC_STATE_SHUTDOWN		0	/* not started */
+#define LNET_RC_STATE_RUNNING		1	/* started up OK */
+#define LNET_RC_STATE_STOPPING		2	/* telling thread to stop */
+
+typedef struct
+{
+	/* CPU partition table of LNet */
+	struct cfs_cpt_table		*ln_cpt_table;
+	/* number of CPTs in ln_cpt_table */
+	unsigned int			ln_cpt_number;
+	unsigned int			ln_cpt_bits;
+
+	/* protect LNet resources (ME/MD/EQ) */
+	struct cfs_percpt_lock		*ln_res_lock;
+	/* # portals */
+	int				ln_nportals;
+	/* the vector of portals */
+	lnet_portal_t			**ln_portals;
+	/* percpt ME containers */
+	struct lnet_res_container	**ln_me_containers;
+	/* percpt MD container */
+	struct lnet_res_container	**ln_md_containers;
+
+	/* Event Queue container */
+	struct lnet_res_container	ln_eq_container;
+	wait_queue_head_t			ln_eq_waitq;
+	spinlock_t			ln_eq_wait_lock;
+	unsigned int			ln_remote_nets_hbits;
+
+	/* protect NI, peer table, credits, routers, rtrbuf... */
+	struct cfs_percpt_lock		*ln_net_lock;
+	/* percpt message containers for active/finalizing/freed message */
+	struct lnet_msg_container	**ln_msg_containers;
+	lnet_counters_t			**ln_counters;
+	struct lnet_peer_table		**ln_peer_tables;
+	/* failure simulation */
+	struct list_head			ln_test_peers;
+
+	struct list_head			ln_nis;		/* LND instances */
+	/* NIs bond on specific CPT(s) */
+	struct list_head			ln_nis_cpt;
+	/* dying LND instances */
+	struct list_head			ln_nis_zombie;
+	lnet_ni_t			*ln_loni;	/* the loopback NI */
+	/* NI to wait for events in */
+	lnet_ni_t			*ln_eq_waitni;
+
+	/* remote networks with routes to them */
+	struct list_head			*ln_remote_nets_hash;
+	/* validity stamp */
+	__u64				ln_remote_nets_version;
+	/* list of all known routers */
+	struct list_head			ln_routers;
+	/* validity stamp */
+	__u64				ln_routers_version;
+	/* percpt router buffer pools */
+	lnet_rtrbufpool_t		**ln_rtrpools;
+
+	lnet_handle_md_t		ln_ping_target_md;
+	lnet_handle_eq_t		ln_ping_target_eq;
+	lnet_ping_info_t		*ln_ping_info;
+
+	/* router checker startup/shutdown state */
+	int				ln_rc_state;
+	/* router checker's event queue */
+	lnet_handle_eq_t		ln_rc_eqh;
+	/* rcd still pending on net */
+	struct list_head			ln_rcd_deathrow;
+	/* rcd ready for free */
+	struct list_head			ln_rcd_zombie;
+	/* serialise startup/shutdown */
+	struct semaphore		ln_rc_signal;
+
+	struct mutex			ln_api_mutex;
+	struct mutex			ln_lnd_mutex;
+	int				ln_init;	/* LNetInit() called? */
+	/* Have I called LNetNIInit myself? */
+	int				ln_niinit_self;
+	/* LNetNIInit/LNetNIFini counter */
+	int				ln_refcount;
+	/* shutdown in progress */
+	int				ln_shutdown;
+
+	int				ln_routing;	/* am I a router? */
+	lnet_pid_t			ln_pid;		/* requested pid */
+	/* uniquely identifies this ni in this epoch */
+	__u64				ln_interface_cookie;
+	/* registered LNDs */
+	struct list_head			ln_lnds;
+
+	/* space for network names */
+	char				*ln_network_tokens;
+	int				ln_network_tokens_nob;
+	/* test protocol compatibility flags */
+	int				ln_testprotocompat;
+
+} lnet_t;
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/linux/api-support.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/linux/api-support.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/linux/api-support.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/linux/api-support.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LINUX_API_SUPPORT_H__
+#define __LINUX_API_SUPPORT_H__
+
+#ifndef __LNET_API_SUPPORT_H__
+#error Do not #include this file directly. #include <lnet /api-support.h> instead
+#endif
+
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/linux/lib-lnet.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/linux/lib-lnet.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/linux/lib-lnet.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/linux/lib-lnet.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,72 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LNET_LINUX_LIB_LNET_H__
+#define __LNET_LINUX_LIB_LNET_H__
+
+#ifndef __LNET_LIB_LNET_H__
+#error Do not #include this file directly. #include <linux/lnet/lib-lnet.h> instead
+#endif
+
+# include <asm/page.h>
+# include <linux/string.h>
+# include <asm/io.h>
+# include <linux/libcfs/libcfs.h>
+
+static inline __u64
+lnet_page2phys (struct page *p)
+{
+	/* compiler optimizer will elide unused branches */
+
+	switch (sizeof(typeof(page_to_phys(p)))) {
+	case 4:
+		/* page_to_phys returns a 32 bit physical address.  This must
+		 * be a 32 bit machine with <= 4G memory and we must ensure we
+		 * don't sign extend when converting to 64 bits. */
+		return (unsigned long)page_to_phys(p);
+
+	case 8:
+		/* page_to_phys returns a 64 bit physical address :) */
+		return page_to_phys(p);
+
+	default:
+		LBUG();
+		return 0;
+	}
+}
+
+
+#define LNET_ROUTER
+
+#endif /* __LNET_LINUX_LIB_LNET_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/linux/lib-types.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/linux/lib-types.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/linux/lib-types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/linux/lib-types.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LNET_LINUX_LIB_TYPES_H__
+#define __LNET_LINUX_LIB_TYPES_H__
+
+#ifndef __LNET_LIB_TYPES_H__
+#error Do not #include this file directly. #include <linux/lnet/lib-types.h> instead
+#endif
+
+# include <linux/uio.h>
+# include <linux/types.h>
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/linux/lnet.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/linux/lnet.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/linux/lnet.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/linux/lnet.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,56 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LNET_LINUX_LNET_H__
+#define __LNET_LINUX_LNET_H__
+
+#ifndef __LNET_H__
+#error Do not #include this file directly. #include <linux/lnet/lnet.h> instead
+#endif
+
+/*
+ * lnet.h
+ *
+ * User application interface file
+ */
+
+#include <linux/uio.h>
+#include <linux/types.h>
+
+#define cfs_tcp_sendpage(sk, page, offset, size, flags) \
+	tcp_sendpage(sk, page, offset, size, flags)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lnetctl.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lnetctl.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lnetctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lnetctl.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,80 @@
+/*
+ *   This file is part of Portals, http://www.sf.net/projects/lustre/
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * header for libptlctl.a
+ */
+#ifndef _PTLCTL_H_
+#define _PTLCTL_H_
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/types.h>
+
+#define LNET_DEV_ID 0
+#define LNET_DEV_PATH "/dev/lnet"
+#define LNET_DEV_MAJOR 10
+#define LNET_DEV_MINOR 240
+#define OBD_DEV_ID 1
+#define OBD_DEV_NAME "obd"
+#define OBD_DEV_PATH "/dev/" OBD_DEV_NAME
+#define OBD_DEV_MAJOR 10
+#define OBD_DEV_MINOR 241
+#define SMFS_DEV_ID  2
+#define SMFS_DEV_PATH "/dev/snapdev"
+#define SMFS_DEV_MAJOR 10
+#define SMFS_DEV_MINOR 242
+
+int ptl_initialize(int argc, char **argv);
+int jt_ptl_network(int argc, char **argv);
+int jt_ptl_list_nids(int argc, char **argv);
+int jt_ptl_which_nid(int argc, char **argv);
+int jt_ptl_print_interfaces(int argc, char **argv);
+int jt_ptl_add_interface(int argc, char **argv);
+int jt_ptl_del_interface(int argc, char **argv);
+int jt_ptl_print_peers (int argc, char **argv);
+int jt_ptl_add_peer (int argc, char **argv);
+int jt_ptl_del_peer (int argc, char **argv);
+int jt_ptl_print_connections (int argc, char **argv);
+int jt_ptl_disconnect(int argc, char **argv);
+int jt_ptl_push_connection(int argc, char **argv);
+int jt_ptl_print_active_txs(int argc, char **argv);
+int jt_ptl_ping(int argc, char **argv);
+int jt_ptl_mynid(int argc, char **argv);
+int jt_ptl_add_uuid(int argc, char **argv);
+int jt_ptl_add_uuid_old(int argc, char **argv); /* backwards compatibility  */
+int jt_ptl_close_uuid(int argc, char **argv);
+int jt_ptl_del_uuid(int argc, char **argv);
+int jt_ptl_add_route (int argc, char **argv);
+int jt_ptl_del_route (int argc, char **argv);
+int jt_ptl_notify_router (int argc, char **argv);
+int jt_ptl_print_routes (int argc, char **argv);
+int jt_ptl_fail_nid (int argc, char **argv);
+int jt_ptl_lwt(int argc, char **argv);
+int jt_ptl_testprotocompat(int argc, char **argv);
+int jt_ptl_memhog(int argc, char **argv);
+
+int dbg_initialize(int argc, char **argv);
+int jt_dbg_filter(int argc, char **argv);
+int jt_dbg_show(int argc, char **argv);
+int jt_dbg_list(int argc, char **argv);
+int jt_dbg_debug_kernel(int argc, char **argv);
+int jt_dbg_debug_daemon(int argc, char **argv);
+int jt_dbg_debug_file(int argc, char **argv);
+int jt_dbg_clear_debug_buf(int argc, char **argv);
+int jt_dbg_mark_debug_buf(int argc, char **argv);
+int jt_dbg_modules(int argc, char **argv);
+int jt_dbg_panic(int argc, char **argv);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lnet.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lnet.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lnet.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lnet.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LNET_H__
+#define __LNET_H__
+
+/*
+ * lnet.h
+ *
+ * User application interface file
+ */
+#include <linux/lnet/linux/lnet.h>
+
+#include <linux/lnet/types.h>
+#include <linux/lnet/api.h>
+
+#define LNET_NIDSTR_COUNT  1024    /* # of nidstrings */
+#define LNET_NIDSTR_SIZE   32      /* size of each one (see below for usage) */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lnetst.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lnetst.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lnetst.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lnetst.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,491 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/include/lnet/lnetst.h
+ *
+ * Author: Liang Zhen <liangzhen@clusterfs.com>
+ */
+
+#ifndef __LNET_ST_H__
+#define __LNET_ST_H__
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lnet.h>
+#include <linux/lnet/lib-types.h>
+
+#define LST_FEAT_NONE		(0)
+#define LST_FEAT_BULK_LEN	(1 << 0)	/* enable variable page size */
+
+#define LST_FEATS_EMPTY		(LST_FEAT_NONE)
+#define LST_FEATS_MASK		(LST_FEAT_NONE | LST_FEAT_BULK_LEN)
+
+#define LST_NAME_SIZE	   32	      /* max name buffer length */
+
+#define LSTIO_DEBUG	     0xC00	   /* debug */
+#define LSTIO_SESSION_NEW       0xC01	   /* create session */
+#define LSTIO_SESSION_END       0xC02	   /* end session */
+#define LSTIO_SESSION_INFO      0xC03	   /* query session */
+#define LSTIO_GROUP_ADD	 0xC10	   /* add group */
+#define LSTIO_GROUP_LIST	0xC11	   /* list all groups in session */
+#define LSTIO_GROUP_INFO	0xC12	   /* query defailt infomation of specified group */
+#define LSTIO_GROUP_DEL	 0xC13	   /* delete group */
+#define LSTIO_NODES_ADD	 0xC14	   /* add nodes to specified group */
+#define LSTIO_GROUP_UPDATE      0xC15	   /* update group */
+#define LSTIO_BATCH_ADD	 0xC20	   /* add batch */
+#define LSTIO_BATCH_START       0xC21	   /* start batch */
+#define LSTIO_BATCH_STOP	0xC22	   /* stop batch */
+#define LSTIO_BATCH_DEL	 0xC23	   /* delete batch */
+#define LSTIO_BATCH_LIST	0xC24	   /* show all batches in the session */
+#define LSTIO_BATCH_INFO	0xC25	   /* show defail of specified batch */
+#define LSTIO_TEST_ADD	  0xC26	   /* add test (to batch) */
+#define LSTIO_BATCH_QUERY       0xC27	   /* query batch status */
+#define LSTIO_STAT_QUERY	0xC30	   /* get stats */
+
+typedef struct {
+	lnet_nid_t	      ses_nid;		/* nid of console node */
+	__u64		   ses_stamp;	      /* time stamp */
+} lst_sid_t;					    /*** session id */
+
+extern lst_sid_t LST_INVALID_SID;
+
+typedef struct {
+	__u64		   bat_id;		 /* unique id in session */
+} lst_bid_t;					    /*** batch id (group of tests) */
+
+/* Status of test node */
+#define LST_NODE_ACTIVE	 0x1		     /* node in this session */
+#define LST_NODE_BUSY	   0x2		     /* node is taken by other session */
+#define LST_NODE_DOWN	   0x4		     /* node is down */
+#define LST_NODE_UNKNOWN	0x8		     /* node not in session */
+
+typedef struct {
+	lnet_process_id_t       nde_id;		 /* id of node */
+	int		     nde_state;	      /* state of node */
+} lstcon_node_ent_t;				    /*** node entry, for list_group command */
+
+typedef struct {
+	int		     nle_nnode;	      /* # of nodes */
+	int		     nle_nactive;	    /* # of active nodes */
+	int		     nle_nbusy;	      /* # of busy nodes */
+	int		     nle_ndown;	      /* # of down nodes */
+	int		     nle_nunknown;	   /* # of unknown nodes */
+} lstcon_ndlist_ent_t;				  /*** node_list entry, for list_batch command */
+
+typedef struct {
+	int		     tse_type;	       /* test type */
+	int		     tse_loop;	       /* loop count */
+	int		     tse_concur;	     /* concurrency of test */
+} lstcon_test_ent_t;				    /*** test summary entry, for list_batch command */
+
+typedef struct {
+	int		     bae_state;	      /* batch status */
+	int		     bae_timeout;	    /* batch timeout */
+	int		     bae_ntest;	      /* # of tests in the batch */
+} lstcon_batch_ent_t;				   /*** batch summary entry, for list_batch command */
+
+typedef struct {
+	lstcon_ndlist_ent_t     tbe_cli_nle;	    /* client (group) node_list entry */
+	lstcon_ndlist_ent_t     tbe_srv_nle;	    /* server (group) node_list entry */
+	union {
+		lstcon_test_ent_t  tbe_test;	    /* test entry */
+		lstcon_batch_ent_t tbe_batch;	   /* batch entry */
+	} u;
+} lstcon_test_batch_ent_t;			      /*** test/batch verbose information entry,
+							 *** for list_batch command */
+
+typedef struct {
+	struct list_head	      rpe_link;	       /* link chain */
+	lnet_process_id_t       rpe_peer;	       /* peer's id */
+	struct timeval	  rpe_stamp;	      /* time stamp of RPC */
+	int		     rpe_state;	      /* peer's state */
+	int		     rpe_rpc_errno;	  /* RPC errno */
+
+	lst_sid_t	       rpe_sid;		/* peer's session id */
+	int		     rpe_fwk_errno;	  /* framework errno */
+	int		     rpe_priv[4];	    /* private data */
+	char		    rpe_payload[0];	 /* private reply payload */
+} lstcon_rpc_ent_t;
+
+typedef struct {
+	int		     trs_rpc_stat[4];	/* RPCs stat (0: total, 1: failed, 2: finished, 4: reserved */
+	int		     trs_rpc_errno;	  /* RPC errno */
+	int		     trs_fwk_stat[8];	/* framework stat */
+	int		     trs_fwk_errno;	  /* errno of the first remote error */
+	void		   *trs_fwk_private;	/* private framework stat */
+} lstcon_trans_stat_t;
+
+static inline int
+lstcon_rpc_stat_total(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_rpc_stat[0] : stat->trs_rpc_stat[0];
+}
+
+static inline int
+lstcon_rpc_stat_success(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_rpc_stat[1] : stat->trs_rpc_stat[1];
+}
+
+static inline int
+lstcon_rpc_stat_failure(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_rpc_stat[2] : stat->trs_rpc_stat[2];
+}
+
+static inline int
+lstcon_sesop_stat_success(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
+}
+
+static inline int
+lstcon_sesop_stat_failure(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
+}
+
+static inline int
+lstcon_sesqry_stat_active(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
+}
+
+static inline int
+lstcon_sesqry_stat_busy(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
+}
+
+static inline int
+lstcon_sesqry_stat_unknown(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[2] : stat->trs_fwk_stat[2];
+}
+
+static inline int
+lstcon_tsbop_stat_success(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
+}
+
+static inline int
+lstcon_tsbop_stat_failure(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
+}
+
+static inline int
+lstcon_tsbqry_stat_idle(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
+}
+
+static inline int
+lstcon_tsbqry_stat_run(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
+}
+
+static inline int
+lstcon_tsbqry_stat_failure(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[2] : stat->trs_fwk_stat[2];
+}
+
+static inline int
+lstcon_statqry_stat_success(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
+}
+
+static inline int
+lstcon_statqry_stat_failure(lstcon_trans_stat_t *stat, int inc)
+{
+	return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
+}
+
+/* create a session */
+typedef struct {
+	int		     lstio_ses_key;	  /* IN: local key */
+	int		     lstio_ses_timeout;      /* IN: session timeout */
+	int		     lstio_ses_force;	/* IN: force create ? */
+	/** IN: session features */
+	unsigned		lstio_ses_feats;
+	lst_sid_t	      *lstio_ses_idp;	  /* OUT: session id */
+	int		     lstio_ses_nmlen;	/* IN: name length */
+	char		   *lstio_ses_namep;	/* IN: session name */
+} lstio_session_new_args_t;
+
+/* query current session */
+typedef struct {
+	lst_sid_t	      *lstio_ses_idp;	  /* OUT: session id */
+	int		    *lstio_ses_keyp;	 /* OUT: local key */
+	/** OUT: session features */
+	unsigned	       *lstio_ses_featp;
+	lstcon_ndlist_ent_t    *lstio_ses_ndinfo;       /* OUT: */
+	int		     lstio_ses_nmlen;	/* IN: name length */
+	char		   *lstio_ses_namep;	/* OUT: session name */
+} lstio_session_info_args_t;
+
+/* delete a session */
+typedef struct {
+	int		     lstio_ses_key;	  /* IN: session key */
+} lstio_session_end_args_t;
+
+#define LST_OPC_SESSION	 1
+#define LST_OPC_GROUP	   2
+#define LST_OPC_NODES	   3
+#define LST_OPC_BATCHCLI	4
+#define LST_OPC_BATCHSRV	5
+
+typedef struct {
+	int		     lstio_dbg_key;	  /* IN: session key */
+	int		     lstio_dbg_type;	 /* IN: debug sessin|batch|group|nodes list */
+	int		     lstio_dbg_flags;	/* IN: reserved debug flags */
+	int		     lstio_dbg_timeout;      /* IN: timeout of debug */
+
+	int		     lstio_dbg_nmlen;	/* IN: len of name */
+	char		   *lstio_dbg_namep;	/* IN: name of group|batch */
+	int		     lstio_dbg_count;	/* IN: # of test nodes to debug */
+	lnet_process_id_t      *lstio_dbg_idsp;	 /* IN: id of test nodes */
+	struct list_head	     *lstio_dbg_resultp;      /* OUT: list head of result buffer */
+} lstio_debug_args_t;
+
+typedef struct {
+	int		     lstio_grp_key;	  /* IN: session key */
+	int		     lstio_grp_nmlen;	/* IN: name length */
+	char		   *lstio_grp_namep;	/* IN: group name */
+} lstio_group_add_args_t;
+
+typedef struct {
+	int		     lstio_grp_key;	  /* IN: session key */
+	int		     lstio_grp_nmlen;	/* IN: name length */
+	char		   *lstio_grp_namep;	/* IN: group name */
+} lstio_group_del_args_t;
+
+#define LST_GROUP_CLEAN	 1		       /* remove inactive nodes in the group */
+#define LST_GROUP_REFRESH       2		       /* refresh inactive nodes in the group */
+#define LST_GROUP_RMND	  3		       /* delete nodes from the group */
+
+typedef struct {
+	int		     lstio_grp_key;	  /* IN: session key */
+	int		     lstio_grp_opc;	  /* IN: OPC */
+	int		     lstio_grp_args;	 /* IN: arguments */
+	int		     lstio_grp_nmlen;	/* IN: name length */
+	char		   *lstio_grp_namep;	/* IN: group name */
+	int		     lstio_grp_count;	/* IN: # of nodes id */
+	lnet_process_id_t      *lstio_grp_idsp;	 /* IN: array of nodes */
+	struct list_head	     *lstio_grp_resultp;      /* OUT: list head of result buffer */
+} lstio_group_update_args_t;
+
+typedef struct {
+	int		     lstio_grp_key;	  /* IN: session key */
+	int		     lstio_grp_nmlen;	/* IN: name length */
+	char		   *lstio_grp_namep;	/* IN: group name */
+	int		     lstio_grp_count;	/* IN: # of nodes */
+	/** OUT: session features */
+	unsigned	       *lstio_grp_featp;
+	lnet_process_id_t      *lstio_grp_idsp;	 /* IN: nodes */
+	struct list_head	     *lstio_grp_resultp;      /* OUT: list head of result buffer */
+} lstio_group_nodes_args_t;
+
+typedef struct {
+	int		     lstio_grp_key;	  /* IN: session key */
+	int		     lstio_grp_idx;	  /* IN: group idx */
+	int		     lstio_grp_nmlen;	/* IN: name len */
+	char		   *lstio_grp_namep;	/* OUT: name */
+} lstio_group_list_args_t;
+
+typedef struct {
+	int		     lstio_grp_key;	  /* IN: session key */
+	int		     lstio_grp_nmlen;	/* IN: name len */
+	char		   *lstio_grp_namep;	/* IN: name */
+	lstcon_ndlist_ent_t    *lstio_grp_entp;	 /* OUT: description of group */
+
+	int		    *lstio_grp_idxp;	 /* IN/OUT: node index */
+	int		    *lstio_grp_ndentp;       /* IN/OUT: # of nodent */
+	lstcon_node_ent_t      *lstio_grp_dentsp;       /* OUT: nodent array */
+} lstio_group_info_args_t;
+
+#define LST_DEFAULT_BATCH       "batch"		 /* default batch name */
+
+typedef struct {
+	int		     lstio_bat_key;	  /* IN: session key */
+	int		     lstio_bat_nmlen;	/* IN: name length */
+	char		   *lstio_bat_namep;	/* IN: batch name */
+} lstio_batch_add_args_t;
+
+typedef struct {
+	int		     lstio_bat_key;	  /* IN: session key */
+	int		     lstio_bat_nmlen;	/* IN: name length */
+	char		   *lstio_bat_namep;	/* IN: batch name */
+} lstio_batch_del_args_t;
+
+typedef struct {
+	int		     lstio_bat_key;	  /* IN: session key */
+	int		     lstio_bat_timeout;      /* IN: timeout for the batch */
+	int		     lstio_bat_nmlen;	/* IN: name length */
+	char		   *lstio_bat_namep;	/* IN: batch name */
+	struct list_head	     *lstio_bat_resultp;      /* OUT: list head of result buffer */
+} lstio_batch_run_args_t;
+
+typedef struct {
+	int		     lstio_bat_key;	  /* IN: session key */
+	int		     lstio_bat_force;	/* IN: abort unfinished test RPC */
+	int		     lstio_bat_nmlen;	/* IN: name length */
+	char		   *lstio_bat_namep;	/* IN: batch name */
+	struct list_head	     *lstio_bat_resultp;      /* OUT: list head of result buffer */
+} lstio_batch_stop_args_t;
+
+typedef struct {
+	int		     lstio_bat_key;	  /* IN: session key */
+	int		     lstio_bat_testidx;      /* IN: test index */
+	int		     lstio_bat_client;       /* IN: is test client? */
+	int		     lstio_bat_timeout;      /* IN: timeout for waiting */
+	int		     lstio_bat_nmlen;	/* IN: name length */
+	char		   *lstio_bat_namep;	/* IN: batch name */
+	struct list_head	     *lstio_bat_resultp;      /* OUT: list head of result buffer */
+} lstio_batch_query_args_t;
+
+typedef struct {
+	int		     lstio_bat_key;	  /* IN: session key */
+	int		     lstio_bat_idx;	  /* IN: index */
+	int		     lstio_bat_nmlen;	/* IN: name length */
+	char		   *lstio_bat_namep;	/* IN: batch name */
+} lstio_batch_list_args_t;
+
+typedef struct {
+	int		     lstio_bat_key;	  /* IN: session key */
+	int		     lstio_bat_nmlen;	/* IN: name length */
+	char		   *lstio_bat_namep;	/* IN: name */
+	int		     lstio_bat_server;       /* IN: query server or not */
+	int		     lstio_bat_testidx;      /* IN: test index */
+	lstcon_test_batch_ent_t *lstio_bat_entp;	/* OUT: batch ent */
+
+	int		    *lstio_bat_idxp;	 /* IN/OUT: index of node */
+	int		    *lstio_bat_ndentp;       /* IN/OUT: # of nodent */
+	lstcon_node_ent_t      *lstio_bat_dentsp;       /* array of nodent */
+} lstio_batch_info_args_t;
+
+/* add stat in session */
+typedef struct {
+	int		     lstio_sta_key;	  /* IN: session key */
+	int		     lstio_sta_timeout;      /* IN: timeout for stat requst */
+	int		     lstio_sta_nmlen;	/* IN: group name length */
+	char		   *lstio_sta_namep;	/* IN: group name */
+	int		     lstio_sta_count;	/* IN: # of pid */
+	lnet_process_id_t      *lstio_sta_idsp;	 /* IN: pid */
+	struct list_head	     *lstio_sta_resultp;      /* OUT: list head of result buffer */
+} lstio_stat_args_t;
+
+typedef enum {
+	LST_TEST_BULK   = 1,
+	LST_TEST_PING   = 2
+} lst_test_type_t;
+
+/* create a test in a batch */
+#define LST_MAX_CONCUR	  1024		    /* Max concurrency of test */
+
+typedef struct {
+	int		     lstio_tes_key;	  /* IN: session key */
+	int		     lstio_tes_bat_nmlen;    /* IN: batch name len */
+	char		   *lstio_tes_bat_name;     /* IN: batch name */
+	int		     lstio_tes_type;	 /* IN: test type */
+	int		     lstio_tes_oneside;      /* IN: one sided test */
+	int		     lstio_tes_loop;	 /* IN: loop count */
+	int		     lstio_tes_concur;       /* IN: concurrency */
+
+	int		     lstio_tes_dist;	 /* IN: node distribution in destination groups */
+	int		     lstio_tes_span;	 /* IN: node span in destination groups */
+	int		     lstio_tes_sgrp_nmlen;   /* IN: source group name length */
+	char		   *lstio_tes_sgrp_name;    /* IN: group name */
+	int		     lstio_tes_dgrp_nmlen;   /* IN: destination group name length */
+	char		   *lstio_tes_dgrp_name;    /* IN: group name */
+
+	int		     lstio_tes_param_len;    /* IN: param buffer len */
+	void		   *lstio_tes_param;	/* IN: parameter for specified test:
+							       lstio_bulk_param_t,
+							       lstio_ping_param_t,
+							       ... more */
+	int		    *lstio_tes_retp;	 /* OUT: private returned value */
+	struct list_head	     *lstio_tes_resultp;      /* OUT: list head of result buffer */
+} lstio_test_args_t;
+
+typedef enum {
+	LST_BRW_READ    = 1,
+	LST_BRW_WRITE   = 2
+} lst_brw_type_t;
+
+typedef enum {
+	LST_BRW_CHECK_NONE   = 1,
+	LST_BRW_CHECK_SIMPLE = 2,
+	LST_BRW_CHECK_FULL   = 3
+} lst_brw_flags_t;
+
+typedef struct {
+	int		     blk_opc;		/* bulk operation code */
+	int		     blk_size;	       /* size (bytes) */
+	int		     blk_time;	       /* time of running the test*/
+	int		     blk_flags;	      /* reserved flags */
+} lst_test_bulk_param_t;
+
+typedef struct {
+	int		     png_size;	       /* size of ping message */
+	int		     png_time;	       /* time */
+	int		     png_loop;	       /* loop */
+	int		     png_flags;	      /* reserved flags */
+} lst_test_ping_param_t;
+
+/* more tests */
+typedef struct {
+	__u32 errors;
+	__u32 rpcs_sent;
+	__u32 rpcs_rcvd;
+	__u32 rpcs_dropped;
+	__u32 rpcs_expired;
+	__u64 bulk_get;
+	__u64 bulk_put;
+} WIRE_ATTR srpc_counters_t;
+
+typedef struct {
+	/** milliseconds since current session started */
+	__u32 running_ms;
+	__u32 active_batches;
+	__u32 zombie_sessions;
+	__u32 brw_errors;
+	__u32 ping_errors;
+} WIRE_ATTR sfw_counters_t;
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lnet-sysctl.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lnet-sysctl.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/lnet-sysctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/lnet-sysctl.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LNET_SYSCTL_H__
+#define __LNET_SYSCTL_H__
+
+#if defined(CONFIG_SYSCTL)
+
+
+#define CTL_KRANAL      201
+#define CTL_O2IBLND     205
+#define CTL_PTLLND      206
+#define CTL_QSWNAL      207
+#define CTL_SOCKLND     208
+#define CTL_GNILND      210
+
+
+#endif
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/ptllnd.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/ptllnd.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/ptllnd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/ptllnd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,94 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/include/lnet/ptllnd.h
+ *
+ * Author: PJ Kirner <pjkirner@clusterfs.com>
+ */
+
+/*
+ * The PTLLND was designed to support Portals with
+ * Lustre and non-lustre UNLINK semantics.
+ * However for now the two targets are Cray Portals
+ * on the XT3 and Lustre Portals (for testing) both
+ * have Lustre UNLINK semantics, so this is defined
+ * by default.
+ */
+#define LUSTRE_PORTALS_UNLINK_SEMANTICS
+
+
+#ifdef _USING_LUSTRE_PORTALS_
+
+/* NIDs are 64-bits on Lustre Portals */
+#define FMT_NID LPU64
+#define FMT_PID "%d"
+
+/* When using Lustre Portals Lustre completion semantics are imlicit*/
+#define PTL_MD_LUSTRE_COMPLETION_SEMANTICS      0
+
+#else /* _USING_CRAY_PORTALS_ */
+
+/* NIDs are integers on Cray Portals */
+#define FMT_NID "%u"
+#define FMT_PID "%d"
+
+/* When using Cray Portals this is defined in the Cray Portals Header*/
+/*#define PTL_MD_LUSTRE_COMPLETION_SEMANTICS */
+
+/* Can compare handles directly on Cray Portals */
+#define PtlHandleIsEqual(a,b) ((a) == (b))
+
+/* Diffrent error types on Cray Portals*/
+#define ptl_err_t ptl_ni_fail_t
+
+/*
+ * The Cray Portals has no maximum number of IOVs.  The
+ * maximum is limited only by memory and size of the
+ * int parameters (2^31-1).
+ * Lustre only really require that the underyling
+ * implemenation to support at least LNET_MAX_IOV,
+ * so for Cray portals we can safely just use that
+ * value here.
+ *
+ */
+#define PTL_MD_MAX_IOV	  LNET_MAX_IOV
+
+#endif
+
+#define FMT_PTLID "ptlid:"FMT_PID"-"FMT_NID
+
+/* Align incoming small request messages to an 8 byte boundary if this is
+ * supported to avoid alignment issues on some architectures */
+#ifndef PTL_MD_LOCAL_ALIGN8
+# define PTL_MD_LOCAL_ALIGN8 0
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/ptllnd_wire.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/ptllnd_wire.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/ptllnd_wire.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/ptllnd_wire.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,124 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/include/lnet/ptllnd_wire.h
+ *
+ * Author: PJ Kirner <pjkirner@clusterfs.com>
+ */
+
+/* Minimum buffer size that any peer will post to receive ptllnd messages */
+#define PTLLND_MIN_BUFFER_SIZE  256
+
+/************************************************************************
+ * Tunable defaults that {u,k}lnds/ptllnd should have in common.
+ */
+
+#define PTLLND_PORTAL	   9	  /* The same portal PTLPRC used when talking to cray portals */
+#define PTLLND_PID	      9	  /* The Portals PID */
+#define PTLLND_PEERCREDITS      8	  /* concurrent sends to 1 peer */
+
+/* Default buffer size for kernel ptllnds (guaranteed eager) */
+#define PTLLND_MAX_KLND_MSG_SIZE 512
+
+/* Default buffer size for catamount ptllnds (not guaranteed eager) - large
+ * enough to avoid RDMA for anything sent while control is not in liblustre */
+#define PTLLND_MAX_ULND_MSG_SIZE 512
+
+
+/************************************************************************
+ * Portals LND Wire message format.
+ * These are sent in sender's byte order (i.e. receiver flips).
+ */
+
+#define PTL_RESERVED_MATCHBITS  0x100	/* below this value is reserved
+					 * above is for bulk data transfer */
+#define LNET_MSG_MATCHBITS       0      /* the value for the message channel */
+
+typedef struct
+{
+	lnet_hdr_t	kptlim_hdr;	     /* portals header */
+	char	      kptlim_payload[0];      /* piggy-backed payload */
+} WIRE_ATTR kptl_immediate_msg_t;
+
+typedef struct
+{
+	lnet_hdr_t	kptlrm_hdr;	     /* portals header */
+	__u64	     kptlrm_matchbits;       /* matchbits */
+} WIRE_ATTR kptl_rdma_msg_t;
+
+typedef struct
+{
+	__u64	     kptlhm_matchbits;       /* matchbits */
+	__u32	     kptlhm_max_msg_size;    /* max message size */
+} WIRE_ATTR kptl_hello_msg_t;
+
+typedef struct
+{
+	/* First 2 fields fixed FOR ALL TIME */
+	__u32	   ptlm_magic;     /* I'm a Portals LND message */
+	__u16	   ptlm_version;   /* this is my version number */
+	__u8	    ptlm_type;      /* the message type */
+	__u8	    ptlm_credits;   /* returned credits */
+	__u32	   ptlm_nob;       /* # bytes in whole message */
+	__u32	   ptlm_cksum;     /* checksum (0 == no checksum) */
+	__u64	   ptlm_srcnid;    /* sender's NID */
+	__u64	   ptlm_srcstamp;  /* sender's incarnation */
+	__u64	   ptlm_dstnid;    /* destination's NID */
+	__u64	   ptlm_dststamp;  /* destination's incarnation */
+	__u32	   ptlm_srcpid;    /* sender's PID */
+	__u32	   ptlm_dstpid;    /* destination's PID */
+
+	 union {
+		kptl_immediate_msg_t    immediate;
+		kptl_rdma_msg_t	 rdma;
+		kptl_hello_msg_t	hello;
+	} WIRE_ATTR ptlm_u;
+
+} kptl_msg_t;
+
+/* kptl_msg_t::ptlm_credits is only a __u8 */
+#define PTLLND_MSG_MAX_CREDITS ((typeof(((kptl_msg_t*) 0)->ptlm_credits)) -1)
+
+#define PTLLND_MSG_MAGIC		LNET_PROTO_PTL_MAGIC
+#define PTLLND_MSG_VERSION	      0x04
+
+#define PTLLND_RDMA_OK		  0x00
+#define PTLLND_RDMA_FAIL		0x01
+
+#define PTLLND_MSG_TYPE_INVALID	 0x00
+#define PTLLND_MSG_TYPE_PUT	     0x01
+#define PTLLND_MSG_TYPE_GET	     0x02
+#define PTLLND_MSG_TYPE_IMMEDIATE       0x03    /* No bulk data xfer*/
+#define PTLLND_MSG_TYPE_NOOP	    0x04
+#define PTLLND_MSG_TYPE_HELLO	   0x05
+#define PTLLND_MSG_TYPE_NAK	     0x06
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/socklnd.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/socklnd.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/socklnd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/socklnd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,103 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/include/lnet/socklnd.h
+ *
+ * #defines shared between socknal implementation and utilities
+ */
+#ifndef __LNET_LNET_SOCKLND_H__
+#define __LNET_LNET_SOCKLND_H__
+
+#include <linux/lnet/types.h>
+#include <linux/lnet/lib-types.h>
+
+#define SOCKLND_CONN_NONE     (-1)
+#define SOCKLND_CONN_ANY	0
+#define SOCKLND_CONN_CONTROL    1
+#define SOCKLND_CONN_BULK_IN    2
+#define SOCKLND_CONN_BULK_OUT   3
+#define SOCKLND_CONN_NTYPES     4
+
+#define SOCKLND_CONN_ACK	SOCKLND_CONN_BULK_IN
+
+typedef struct {
+	__u32		   kshm_magic;     /* magic number of socklnd message */
+	__u32		   kshm_version;   /* version of socklnd message */
+	lnet_nid_t	      kshm_src_nid;   /* sender's nid */
+	lnet_nid_t	      kshm_dst_nid;   /* destination nid */
+	lnet_pid_t	      kshm_src_pid;   /* sender's pid */
+	lnet_pid_t	      kshm_dst_pid;   /* destination pid */
+	__u64		   kshm_src_incarnation; /* sender's incarnation */
+	__u64		   kshm_dst_incarnation; /* destination's incarnation */
+	__u32		   kshm_ctype;     /* connection type */
+	__u32		   kshm_nips;      /* # IP addrs */
+	__u32		   kshm_ips[0];    /* IP addrs */
+} WIRE_ATTR ksock_hello_msg_t;
+
+typedef struct {
+	lnet_hdr_t	      ksnm_hdr;       /* lnet hdr */
+
+	/*
+	 * ksnm_payload is removed because of winnt compiler's limitation:
+	 * zero-sized array can only be placed at the tail of [nested]
+	 * structure definitions. lnet payload will be stored just after
+	 * the body of structure ksock_lnet_msg_t
+	 */
+} WIRE_ATTR ksock_lnet_msg_t;
+
+typedef struct {
+	__u32		   ksm_type;       /* type of socklnd message */
+	__u32		   ksm_csum;       /* checksum if != 0 */
+	__u64		   ksm_zc_cookies[2]; /* Zero-Copy request/ACK cookie */
+	union {
+		ksock_lnet_msg_t lnetmsg;       /* lnet message, it's empty if it's NOOP */
+	} WIRE_ATTR ksm_u;
+} WIRE_ATTR ksock_msg_t;
+
+static inline void
+socklnd_init_msg(ksock_msg_t *msg, int type)
+{
+	msg->ksm_csum	   = 0;
+	msg->ksm_type	   = type;
+	msg->ksm_zc_cookies[0]  = msg->ksm_zc_cookies[1]  = 0;
+}
+
+#define KSOCK_MSG_NOOP	  0xc0	    /* ksm_u empty */
+#define KSOCK_MSG_LNET	  0xc1	    /* lnet msg */
+
+/* We need to know this number to parse hello msg from ksocklnd in
+ * other LND (usocklnd, for example) */
+#define KSOCK_PROTO_V2	  2
+#define KSOCK_PROTO_V3	  3
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/types.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/types.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/include/linux/lnet/types.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/include/linux/lnet/types.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,503 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LNET_TYPES_H__
+#define __LNET_TYPES_H__
+
+/** \addtogroup lnet
+ * @{ */
+
+#include <linux/libcfs/libcfs.h>
+
+/** \addtogroup lnet_addr
+ * @{ */
+
+/** Portal reserved for LNet's own use.
+ * \see lustre/include/lustre/lustre_idl.h for Lustre portal assignments.
+ */
+#define LNET_RESERVED_PORTAL      0
+
+/**
+ * Address of an end-point in an LNet network.
+ *
+ * A node can have multiple end-points and hence multiple addresses.
+ * An LNet network can be a simple network (e.g. tcp0) or a network of
+ * LNet networks connected by LNet routers. Therefore an end-point address
+ * has two parts: network ID, and address within a network.
+ *
+ * \see LNET_NIDNET, LNET_NIDADDR, and LNET_MKNID.
+ */
+typedef __u64 lnet_nid_t;
+/**
+ * ID of a process in a node. Shortened as PID to distinguish from
+ * lnet_process_id_t, the global process ID.
+ */
+typedef __u32 lnet_pid_t;
+
+/** wildcard NID that matches any end-point address */
+#define LNET_NID_ANY      ((lnet_nid_t) -1)
+/** wildcard PID that matches any lnet_pid_t */
+#define LNET_PID_ANY      ((lnet_pid_t) -1)
+
+#define LNET_PID_RESERVED 0xf0000000 /* reserved bits in PID */
+#define LNET_PID_USERFLAG 0x80000000 /* set in userspace peers */
+
+#define LNET_TIME_FOREVER    (-1)
+
+/**
+ * Objects maintained by the LNet are accessed through handles. Handle types
+ * have names of the form lnet_handle_xx_t, where xx is one of the two letter
+ * object type codes ('eq' for event queue, 'md' for memory descriptor, and
+ * 'me' for match entry).
+ * Each type of object is given a unique handle type to enhance type checking.
+ * The type lnet_handle_any_t can be used when a generic handle is needed.
+ * Every handle value can be converted into a value of type lnet_handle_any_t
+ * without loss of information.
+ */
+typedef struct {
+	__u64	 cookie;
+} lnet_handle_any_t;
+
+typedef lnet_handle_any_t lnet_handle_eq_t;
+typedef lnet_handle_any_t lnet_handle_md_t;
+typedef lnet_handle_any_t lnet_handle_me_t;
+
+#define LNET_WIRE_HANDLE_COOKIE_NONE   (-1)
+
+/**
+ * Invalidate handle \a h.
+ */
+static inline void LNetInvalidateHandle(lnet_handle_any_t *h)
+{
+	h->cookie = LNET_WIRE_HANDLE_COOKIE_NONE;
+}
+
+/**
+ * Compare handles \a h1 and \a h2.
+ *
+ * \return 1 if handles are equal, 0 if otherwise.
+ */
+static inline int LNetHandleIsEqual (lnet_handle_any_t h1, lnet_handle_any_t h2)
+{
+	return (h1.cookie == h2.cookie);
+}
+
+/**
+ * Check whether handle \a h is invalid.
+ *
+ * \return 1 if handle is invalid, 0 if valid.
+ */
+static inline int LNetHandleIsInvalid(lnet_handle_any_t h)
+{
+	return (LNET_WIRE_HANDLE_COOKIE_NONE == h.cookie);
+}
+
+/**
+ * Global process ID.
+ */
+typedef struct {
+	/** node id */
+	lnet_nid_t nid;
+	/** process id */
+	lnet_pid_t pid;
+} lnet_process_id_t;
+/** @} lnet_addr */
+
+/** \addtogroup lnet_me
+ * @{ */
+
+/**
+ * Specifies whether the match entry or memory descriptor should be unlinked
+ * automatically (LNET_UNLINK) or not (LNET_RETAIN).
+ */
+typedef enum {
+	LNET_RETAIN = 0,
+	LNET_UNLINK
+} lnet_unlink_t;
+
+/**
+ * Values of the type lnet_ins_pos_t are used to control where a new match
+ * entry is inserted. The value LNET_INS_BEFORE is used to insert the new
+ * entry before the current entry or before the head of the list. The value
+ * LNET_INS_AFTER is used to insert the new entry after the current entry
+ * or after the last item in the list.
+ */
+typedef enum {
+	/** insert ME before current position or head of the list */
+	LNET_INS_BEFORE,
+	/** insert ME after current position or tail of the list */
+	LNET_INS_AFTER,
+	/** attach ME at tail of local CPU partition ME list */
+	LNET_INS_LOCAL
+} lnet_ins_pos_t;
+
+/** @} lnet_me */
+
+/** \addtogroup lnet_md
+ * @{ */
+
+/**
+ * Defines the visible parts of a memory descriptor. Values of this type
+ * are used to initialize memory descriptors.
+ */
+typedef struct {
+	/**
+	 * Specify the memory region associated with the memory descriptor.
+	 * If the options field has:
+	 * - LNET_MD_KIOV bit set: The start field points to the starting
+	 * address of an array of lnet_kiov_t and the length field specifies
+	 * the number of entries in the array. The length can't be bigger
+	 * than LNET_MAX_IOV. The lnet_kiov_t is used to describe page-based
+	 * fragments that are not necessarily mapped in virtal memory.
+	 * - LNET_MD_IOVEC bit set: The start field points to the starting
+	 * address of an array of struct iovec and the length field specifies
+	 * the number of entries in the array. The length can't be bigger
+	 * than LNET_MAX_IOV. The struct iovec is used to describe fragments
+	 * that have virtual addresses.
+	 * - Otherwise: The memory region is contiguous. The start field
+	 * specifies the starting address for the memory region and the
+	 * length field specifies its length.
+	 *
+	 * When the memory region is fragmented, all fragments but the first
+	 * one must start on page boundary, and all but the last must end on
+	 * page boundary.
+	 */
+	void	    *start;
+	unsigned int     length;
+	/**
+	 * Specifies the maximum number of operations that can be performed
+	 * on the memory descriptor. An operation is any action that could
+	 * possibly generate an event. In the usual case, the threshold value
+	 * is decremented for each operation on the MD. When the threshold
+	 * drops to zero, the MD becomes inactive and does not respond to
+	 * operations. A threshold value of LNET_MD_THRESH_INF indicates that
+	 * there is no bound on the number of operations that may be applied
+	 * to a MD.
+	 */
+	int	      threshold;
+	/**
+	 * Specifies the largest incoming request that the memory descriptor
+	 * should respond to. When the unused portion of a MD (length -
+	 * local offset) falls below this value, the MD becomes inactive and
+	 * does not respond to further operations. This value is only used
+	 * if the LNET_MD_MAX_SIZE option is set.
+	 */
+	int	      max_size;
+	/**
+	 * Specifies the behavior of the memory descriptor. A bitwise OR
+	 * of the following values can be used:
+	 * - LNET_MD_OP_PUT: The LNet PUT operation is allowed on this MD.
+	 * - LNET_MD_OP_GET: The LNet GET operation is allowed on this MD.
+	 * - LNET_MD_MANAGE_REMOTE: The offset used in accessing the memory
+	 *   region is provided by the incoming request. By default, the
+	 *   offset is maintained locally. When maintained locally, the
+	 *   offset is incremented by the length of the request so that
+	 *   the next operation (PUT or GET) will access the next part of
+	 *   the memory region. Note that only one offset variable exists
+	 *   per memory descriptor. If both PUT and GET operations are
+	 *   performed on a memory descriptor, the offset is updated each time.
+	 * - LNET_MD_TRUNCATE: The length provided in the incoming request can
+	 *   be reduced to match the memory available in the region (determined
+	 *   by subtracting the offset from the length of the memory region).
+	 *   By default, if the length in the incoming operation is greater
+	 *   than the amount of memory available, the operation is rejected.
+	 * - LNET_MD_ACK_DISABLE: An acknowledgment should not be sent for
+	 *   incoming PUT operations, even if requested. By default,
+	 *   acknowledgments are sent for PUT operations that request an
+	 *   acknowledgment. Acknowledgments are never sent for GET operations.
+	 *   The data sent in the REPLY serves as an implicit acknowledgment.
+	 * - LNET_MD_KIOV: The start and length fields specify an array of
+	 *   lnet_kiov_t.
+	 * - LNET_MD_IOVEC: The start and length fields specify an array of
+	 *   struct iovec.
+	 * - LNET_MD_MAX_SIZE: The max_size field is valid.
+	 *
+	 * Note:
+	 * - LNET_MD_KIOV or LNET_MD_IOVEC allows for a scatter/gather
+	 *   capability for memory descriptors. They can't be both set.
+	 * - When LNET_MD_MAX_SIZE is set, the total length of the memory
+	 *   region (i.e. sum of all fragment lengths) must not be less than
+	 *   \a max_size.
+	 */
+	unsigned int     options;
+	/**
+	 * A user-specified value that is associated with the memory
+	 * descriptor. The value does not need to be a pointer, but must fit
+	 * in the space used by a pointer. This value is recorded in events
+	 * associated with operations on this MD.
+	 */
+	void	    *user_ptr;
+	/**
+	 * A handle for the event queue used to log the operations performed on
+	 * the memory region. If this argument is a NULL handle (i.e. nullified
+	 * by LNetInvalidateHandle()), operations performed on this memory
+	 * descriptor are not logged.
+	 */
+	lnet_handle_eq_t eq_handle;
+} lnet_md_t;
+
+/* Max Transfer Unit (minimum supported everywhere).
+ * CAVEAT EMPTOR, with multinet (i.e. routers forwarding between networks)
+ * these limits are system wide and not interface-local. */
+#define LNET_MTU_BITS	20
+#define LNET_MTU	(1 << LNET_MTU_BITS)
+
+/** limit on the number of fragments in discontiguous MDs */
+#define LNET_MAX_IOV    256
+
+/* Max payload size */
+# define LNET_MAX_PAYLOAD	CONFIG_LNET_MAX_PAYLOAD
+# if (LNET_MAX_PAYLOAD < LNET_MTU)
+#  error "LNET_MAX_PAYLOAD too small - error in configure --with-max-payload-mb"
+# else
+#  if (LNET_MAX_PAYLOAD > (PAGE_SIZE * LNET_MAX_IOV))
+/*  PAGE_SIZE is a constant: check with cpp! */
+#   error "LNET_MAX_PAYLOAD too large - error in configure --with-max-payload-mb"
+#  endif
+# endif
+
+/**
+ * Options for the MD structure. See lnet_md_t::options.
+ */
+#define LNET_MD_OP_PUT	       (1 << 0)
+/** See lnet_md_t::options. */
+#define LNET_MD_OP_GET	       (1 << 1)
+/** See lnet_md_t::options. */
+#define LNET_MD_MANAGE_REMOTE	(1 << 2)
+/* unused			    (1 << 3) */
+/** See lnet_md_t::options. */
+#define LNET_MD_TRUNCATE	     (1 << 4)
+/** See lnet_md_t::options. */
+#define LNET_MD_ACK_DISABLE	  (1 << 5)
+/** See lnet_md_t::options. */
+#define LNET_MD_IOVEC		(1 << 6)
+/** See lnet_md_t::options. */
+#define LNET_MD_MAX_SIZE	     (1 << 7)
+/** See lnet_md_t::options. */
+#define LNET_MD_KIOV		 (1 << 8)
+
+/* For compatibility with Cray Portals */
+#define LNET_MD_PHYS			 0
+
+/** Infinite threshold on MD operations. See lnet_md_t::threshold */
+#define LNET_MD_THRESH_INF       (-1)
+
+/* NB lustre portals uses struct iovec internally! */
+typedef struct iovec lnet_md_iovec_t;
+
+/**
+ * A page-based fragment of a MD.
+ */
+typedef struct {
+	/** Pointer to the page where the fragment resides */
+	struct page      *kiov_page;
+	/** Length in bytes of the fragment */
+	unsigned int     kiov_len;
+	/**
+	 * Starting offset of the fragment within the page. Note that the
+	 * end of the fragment must not pass the end of the page; i.e.,
+	 * kiov_len + kiov_offset <= PAGE_CACHE_SIZE.
+	 */
+	unsigned int     kiov_offset;
+} lnet_kiov_t;
+/** @} lnet_md */
+
+/** \addtogroup lnet_eq
+ * @{ */
+
+/**
+ * Six types of events can be logged in an event queue.
+ */
+typedef enum {
+	/** An incoming GET operation has completed on the MD. */
+	LNET_EVENT_GET		= 1,
+	/**
+	 * An incoming PUT operation has completed on the MD. The
+	 * underlying layers will not alter the memory (on behalf of this
+	 * operation) once this event has been logged.
+	 */
+	LNET_EVENT_PUT,
+	/**
+	 * A REPLY operation has completed. This event is logged after the
+	 * data (if any) from the REPLY has been written into the MD.
+	 */
+	LNET_EVENT_REPLY,
+	/** An acknowledgment has been received. */
+	LNET_EVENT_ACK,
+	/**
+	 * An outgoing send (PUT or GET) operation has completed. This event
+	 * is logged after the entire buffer has been sent and it is safe for
+	 * the caller to reuse the buffer.
+	 *
+	 * Note:
+	 * - The LNET_EVENT_SEND doesn't guarantee message delivery. It can
+	 *   happen even when the message has not yet been put out on wire.
+	 * - It's unsafe to assume that in an outgoing GET operation
+	 *   the LNET_EVENT_SEND event would happen before the
+	 *   LNET_EVENT_REPLY event. The same holds for LNET_EVENT_SEND and
+	 *   LNET_EVENT_ACK events in an outgoing PUT operation.
+	 */
+	LNET_EVENT_SEND,
+	/**
+	 * A MD has been unlinked. Note that LNetMDUnlink() does not
+	 * necessarily trigger an LNET_EVENT_UNLINK event.
+	 * \see LNetMDUnlink
+	 */
+	LNET_EVENT_UNLINK,
+} lnet_event_kind_t;
+
+#define LNET_SEQ_BASETYPE       long
+typedef unsigned LNET_SEQ_BASETYPE lnet_seq_t;
+#define LNET_SEQ_GT(a,b)	(((signed LNET_SEQ_BASETYPE)((a) - (b))) > 0)
+
+/* XXX
+ * cygwin need the pragma line, not clear if it's needed in other places.
+ * checking!!!
+ */
+#ifdef __CYGWIN__
+#pragma pack(push, 4)
+#endif
+
+/**
+ * Information about an event on a MD.
+ */
+typedef struct {
+	/** The identifier (nid, pid) of the target. */
+	lnet_process_id_t   target;
+	/** The identifier (nid, pid) of the initiator. */
+	lnet_process_id_t   initiator;
+	/**
+	 * The NID of the immediate sender. If the request has been forwarded
+	 * by routers, this is the NID of the last hop; otherwise it's the
+	 * same as the initiator.
+	 */
+	lnet_nid_t	  sender;
+	/** Indicates the type of the event. */
+	lnet_event_kind_t   type;
+	/** The portal table index specified in the request */
+	unsigned int	pt_index;
+	/** A copy of the match bits specified in the request. */
+	__u64	       match_bits;
+	/** The length (in bytes) specified in the request. */
+	unsigned int	rlength;
+	/**
+	 * The length (in bytes) of the data that was manipulated by the
+	 * operation. For truncated operations, the manipulated length will be
+	 * the number of bytes specified by the MD (possibly with an offset,
+	 * see lnet_md_t). For all other operations, the manipulated length
+	 * will be the length of the requested operation, i.e. rlength.
+	 */
+	unsigned int	mlength;
+	/**
+	 * The handle to the MD associated with the event. The handle may be
+	 * invalid if the MD has been unlinked.
+	 */
+	lnet_handle_md_t    md_handle;
+	/**
+	 * A snapshot of the state of the MD immediately after the event has
+	 * been processed. In particular, the threshold field in md will
+	 * reflect the value of the threshold after the operation occurred.
+	 */
+	lnet_md_t	   md;
+	/**
+	 * 64 bits of out-of-band user data. Only valid for LNET_EVENT_PUT.
+	 * \see LNetPut
+	 */
+	__u64	       hdr_data;
+	/**
+	 * Indicates the completion status of the operation. It's 0 for
+	 * successful operations, otherwise it's an error code.
+	 */
+	int		 status;
+	/**
+	 * Indicates whether the MD has been unlinked. Note that:
+	 * - An event with unlinked set is the last event on the MD.
+	 * - This field is also set for an explicit LNET_EVENT_UNLINK event.
+	 * \see LNetMDUnlink
+	 */
+	int		 unlinked;
+	/**
+	 * The displacement (in bytes) into the memory region that the
+	 * operation used. The offset can be determined by the operation for
+	 * a remote managed MD or by the local MD.
+	 * \see lnet_md_t::options
+	 */
+	unsigned int	offset;
+	/**
+	 * The sequence number for this event. Sequence numbers are unique
+	 * to each event.
+	 */
+	volatile lnet_seq_t sequence;
+} lnet_event_t;
+#ifdef __CYGWIN__
+#pragma pop
+#endif
+
+/**
+ * Event queue handler function type.
+ *
+ * The EQ handler runs for each event that is deposited into the EQ. The
+ * handler is supplied with a pointer to the event that triggered the
+ * handler invocation.
+ *
+ * The handler must not block, must be reentrant, and must not call any LNet
+ * API functions. It should return as quickly as possible.
+ */
+typedef void (*lnet_eq_handler_t)(lnet_event_t *event);
+#define LNET_EQ_HANDLER_NONE NULL
+/** @} lnet_eq */
+
+/** \addtogroup lnet_data
+ * @{ */
+
+/**
+ * Specify whether an acknowledgment should be sent by target when the PUT
+ * operation completes (i.e., when the data has been written to a MD of the
+ * target process).
+ *
+ * \see lnet_md_t::options for the discussion on LNET_MD_ACK_DISABLE by which
+ * acknowledgments can be disabled for a MD.
+ */
+typedef enum {
+	/** Request an acknowledgment */
+	LNET_ACK_REQ,
+	/** Request that no acknowledgment should be generated. */
+	LNET_NOACK_REQ
+} lnet_ack_req_t;
+/** @} lnet_data */
+
+/** @} lnet */
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/lustre/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/lustre/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3 @@
+source "drivers/staging/lustre/lustre/Kconfig"
+
+source "drivers/staging/lustre/lnet/Kconfig"
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,40 @@
+config LNET
+	tristate "Lustre networking subsystem"
+	depends on LUSTRE_FS
+
+config LNET_MAX_PAYLOAD
+	int "Lustre lnet max transfer payload (default 2MB)"
+	depends on LUSTRE_FS
+	default "1048576"
+	help
+	  This option defines the maximum size of payload in bytes that lnet
+	  can put into its transport.
+
+	  If unsure, use default.
+
+config LNET_SELFTEST
+	tristate "Lustre networking self testing"
+	depends on LNET
+	help
+	  Choose Y here if you want to do lnet self testing. To compile this
+	  as a module, choose M here: the module will be called lnet_selftest.
+
+	  To compile this as a kernel modules, choose M here and it will be
+	  called lnet_selftest.
+
+	  If unsure, say N.
+
+	  See also http://wiki.lustre.org/
+
+config LNET_XPRT_IB
+	tristate "LNET infiniband support"
+	depends on LNET && INFINIBAND && INFINIBAND_ADDR_TRANS
+	default LNET && INFINIBAND
+	help
+	  This option allows the LNET users to use infiniband as an
+	  RDMA-enabled transport.
+
+	  To compile this as a kernel module, choose M here and it will be
+	  called ko2iblnd.
+
+	  If unsure, say N.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/Makefile
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+obj-$(CONFIG_LNET) += o2iblnd/  socklnd/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,5 @@
+obj-$(CONFIG_LNET_XPRT_IB) += ko2iblnd.o
+ko2iblnd-y := o2iblnd.o o2iblnd_cb.o o2iblnd_modparams.o
+
+
+ccflags-y := -I$(src)/../../include
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3259 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/klnds/o2iblnd/o2iblnd.c
+ *
+ * Author: Eric Barton <eric@bartonsoftware.com>
+ */
+
+#include "o2iblnd.h"
+#include <asm/div64.h>
+
+lnd_t the_o2iblnd = {
+	.lnd_type       = O2IBLND,
+	.lnd_startup    = kiblnd_startup,
+	.lnd_shutdown   = kiblnd_shutdown,
+	.lnd_ctl	= kiblnd_ctl,
+	.lnd_query      = kiblnd_query,
+	.lnd_send       = kiblnd_send,
+	.lnd_recv       = kiblnd_recv,
+};
+
+kib_data_t	      kiblnd_data;
+
+__u32
+kiblnd_cksum (void *ptr, int nob)
+{
+	char  *c  = ptr;
+	__u32  sum = 0;
+
+	while (nob-- > 0)
+		sum = ((sum << 1) | (sum >> 31)) + *c++;
+
+	/* ensure I don't return 0 (== no checksum) */
+	return (sum == 0) ? 1 : sum;
+}
+
+static char *
+kiblnd_msgtype2str(int type)
+{
+	switch (type) {
+	case IBLND_MSG_CONNREQ:
+		return "CONNREQ";
+
+	case IBLND_MSG_CONNACK:
+		return "CONNACK";
+
+	case IBLND_MSG_NOOP:
+		return "NOOP";
+
+	case IBLND_MSG_IMMEDIATE:
+		return "IMMEDIATE";
+
+	case IBLND_MSG_PUT_REQ:
+		return "PUT_REQ";
+
+	case IBLND_MSG_PUT_NAK:
+		return "PUT_NAK";
+
+	case IBLND_MSG_PUT_ACK:
+		return "PUT_ACK";
+
+	case IBLND_MSG_PUT_DONE:
+		return "PUT_DONE";
+
+	case IBLND_MSG_GET_REQ:
+		return "GET_REQ";
+
+	case IBLND_MSG_GET_DONE:
+		return "GET_DONE";
+
+	default:
+		return "???";
+	}
+}
+
+static int
+kiblnd_msgtype2size(int type)
+{
+	const int hdr_size = offsetof(kib_msg_t, ibm_u);
+
+	switch (type) {
+	case IBLND_MSG_CONNREQ:
+	case IBLND_MSG_CONNACK:
+		return hdr_size + sizeof(kib_connparams_t);
+
+	case IBLND_MSG_NOOP:
+		return hdr_size;
+
+	case IBLND_MSG_IMMEDIATE:
+		return offsetof(kib_msg_t, ibm_u.immediate.ibim_payload[0]);
+
+	case IBLND_MSG_PUT_REQ:
+		return hdr_size + sizeof(kib_putreq_msg_t);
+
+	case IBLND_MSG_PUT_ACK:
+		return hdr_size + sizeof(kib_putack_msg_t);
+
+	case IBLND_MSG_GET_REQ:
+		return hdr_size + sizeof(kib_get_msg_t);
+
+	case IBLND_MSG_PUT_NAK:
+	case IBLND_MSG_PUT_DONE:
+	case IBLND_MSG_GET_DONE:
+		return hdr_size + sizeof(kib_completion_msg_t);
+	default:
+		return -1;
+	}
+}
+
+static int
+kiblnd_unpack_rd(kib_msg_t *msg, int flip)
+{
+	kib_rdma_desc_t   *rd;
+	int		nob;
+	int		n;
+	int		i;
+
+	LASSERT (msg->ibm_type == IBLND_MSG_GET_REQ ||
+		 msg->ibm_type == IBLND_MSG_PUT_ACK);
+
+	rd = msg->ibm_type == IBLND_MSG_GET_REQ ?
+			      &msg->ibm_u.get.ibgm_rd :
+			      &msg->ibm_u.putack.ibpam_rd;
+
+	if (flip) {
+		__swab32s(&rd->rd_key);
+		__swab32s(&rd->rd_nfrags);
+	}
+
+	n = rd->rd_nfrags;
+
+	if (n <= 0 || n > IBLND_MAX_RDMA_FRAGS) {
+		CERROR("Bad nfrags: %d, should be 0 < n <= %d\n",
+		       n, IBLND_MAX_RDMA_FRAGS);
+		return 1;
+	}
+
+	nob = offsetof (kib_msg_t, ibm_u) +
+	      kiblnd_rd_msg_size(rd, msg->ibm_type, n);
+
+	if (msg->ibm_nob < nob) {
+		CERROR("Short %s: %d(%d)\n",
+		       kiblnd_msgtype2str(msg->ibm_type), msg->ibm_nob, nob);
+		return 1;
+	}
+
+	if (!flip)
+		return 0;
+
+	for (i = 0; i < n; i++) {
+		__swab32s(&rd->rd_frags[i].rf_nob);
+		__swab64s(&rd->rd_frags[i].rf_addr);
+	}
+
+	return 0;
+}
+
+void
+kiblnd_pack_msg (lnet_ni_t *ni, kib_msg_t *msg, int version,
+		 int credits, lnet_nid_t dstnid, __u64 dststamp)
+{
+	kib_net_t *net = ni->ni_data;
+
+	/* CAVEAT EMPTOR! all message fields not set here should have been
+	 * initialised previously. */
+	msg->ibm_magic    = IBLND_MSG_MAGIC;
+	msg->ibm_version  = version;
+	/*   ibm_type */
+	msg->ibm_credits  = credits;
+	/*   ibm_nob */
+	msg->ibm_cksum    = 0;
+	msg->ibm_srcnid   = ni->ni_nid;
+	msg->ibm_srcstamp = net->ibn_incarnation;
+	msg->ibm_dstnid   = dstnid;
+	msg->ibm_dststamp = dststamp;
+
+	if (*kiblnd_tunables.kib_cksum) {
+		/* NB ibm_cksum zero while computing cksum */
+		msg->ibm_cksum = kiblnd_cksum(msg, msg->ibm_nob);
+	}
+}
+
+int
+kiblnd_unpack_msg(kib_msg_t *msg, int nob)
+{
+	const int hdr_size = offsetof(kib_msg_t, ibm_u);
+	__u32     msg_cksum;
+	__u16     version;
+	int       msg_nob;
+	int       flip;
+
+	/* 6 bytes are enough to have received magic + version */
+	if (nob < 6) {
+		CERROR("Short message: %d\n", nob);
+		return -EPROTO;
+	}
+
+	if (msg->ibm_magic == IBLND_MSG_MAGIC) {
+		flip = 0;
+	} else if (msg->ibm_magic == __swab32(IBLND_MSG_MAGIC)) {
+		flip = 1;
+	} else {
+		CERROR("Bad magic: %08x\n", msg->ibm_magic);
+		return -EPROTO;
+	}
+
+	version = flip ? __swab16(msg->ibm_version) : msg->ibm_version;
+	if (version != IBLND_MSG_VERSION &&
+	    version != IBLND_MSG_VERSION_1) {
+		CERROR("Bad version: %x\n", version);
+		return -EPROTO;
+	}
+
+	if (nob < hdr_size) {
+		CERROR("Short message: %d\n", nob);
+		return -EPROTO;
+	}
+
+	msg_nob = flip ? __swab32(msg->ibm_nob) : msg->ibm_nob;
+	if (msg_nob > nob) {
+		CERROR("Short message: got %d, wanted %d\n", nob, msg_nob);
+		return -EPROTO;
+	}
+
+	/* checksum must be computed with ibm_cksum zero and BEFORE anything
+	 * gets flipped */
+	msg_cksum = flip ? __swab32(msg->ibm_cksum) : msg->ibm_cksum;
+	msg->ibm_cksum = 0;
+	if (msg_cksum != 0 &&
+	    msg_cksum != kiblnd_cksum(msg, msg_nob)) {
+		CERROR("Bad checksum\n");
+		return -EPROTO;
+	}
+
+	msg->ibm_cksum = msg_cksum;
+
+	if (flip) {
+		/* leave magic unflipped as a clue to peer endianness */
+		msg->ibm_version = version;
+		CLASSERT (sizeof(msg->ibm_type) == 1);
+		CLASSERT (sizeof(msg->ibm_credits) == 1);
+		msg->ibm_nob     = msg_nob;
+		__swab64s(&msg->ibm_srcnid);
+		__swab64s(&msg->ibm_srcstamp);
+		__swab64s(&msg->ibm_dstnid);
+		__swab64s(&msg->ibm_dststamp);
+	}
+
+	if (msg->ibm_srcnid == LNET_NID_ANY) {
+		CERROR("Bad src nid: %s\n", libcfs_nid2str(msg->ibm_srcnid));
+		return -EPROTO;
+	}
+
+	if (msg_nob < kiblnd_msgtype2size(msg->ibm_type)) {
+		CERROR("Short %s: %d(%d)\n", kiblnd_msgtype2str(msg->ibm_type),
+		       msg_nob, kiblnd_msgtype2size(msg->ibm_type));
+		return -EPROTO;
+	}
+
+	switch (msg->ibm_type) {
+	default:
+		CERROR("Unknown message type %x\n", msg->ibm_type);
+		return -EPROTO;
+
+	case IBLND_MSG_NOOP:
+	case IBLND_MSG_IMMEDIATE:
+	case IBLND_MSG_PUT_REQ:
+		break;
+
+	case IBLND_MSG_PUT_ACK:
+	case IBLND_MSG_GET_REQ:
+		if (kiblnd_unpack_rd(msg, flip))
+			return -EPROTO;
+		break;
+
+	case IBLND_MSG_PUT_NAK:
+	case IBLND_MSG_PUT_DONE:
+	case IBLND_MSG_GET_DONE:
+		if (flip)
+			__swab32s(&msg->ibm_u.completion.ibcm_status);
+		break;
+
+	case IBLND_MSG_CONNREQ:
+	case IBLND_MSG_CONNACK:
+		if (flip) {
+			__swab16s(&msg->ibm_u.connparams.ibcp_queue_depth);
+			__swab16s(&msg->ibm_u.connparams.ibcp_max_frags);
+			__swab32s(&msg->ibm_u.connparams.ibcp_max_msg_size);
+		}
+		break;
+	}
+	return 0;
+}
+
+int
+kiblnd_create_peer(lnet_ni_t *ni, kib_peer_t **peerp, lnet_nid_t nid)
+{
+	kib_peer_t	*peer;
+	kib_net_t	*net = ni->ni_data;
+	int		cpt = lnet_cpt_of_nid(nid);
+	unsigned long   flags;
+
+	LASSERT(net != NULL);
+	LASSERT(nid != LNET_NID_ANY);
+
+	LIBCFS_CPT_ALLOC(peer, lnet_cpt_table(), cpt, sizeof(*peer));
+	if (peer == NULL) {
+		CERROR("Cannot allocate peer\n");
+		return -ENOMEM;
+	}
+
+	memset(peer, 0, sizeof(*peer));	 /* zero flags etc */
+
+	peer->ibp_ni = ni;
+	peer->ibp_nid = nid;
+	peer->ibp_error = 0;
+	peer->ibp_last_alive = 0;
+	atomic_set(&peer->ibp_refcount, 1);  /* 1 ref for caller */
+
+	INIT_LIST_HEAD(&peer->ibp_list);     /* not in the peer table yet */
+	INIT_LIST_HEAD(&peer->ibp_conns);
+	INIT_LIST_HEAD(&peer->ibp_tx_queue);
+
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	/* always called with a ref on ni, which prevents ni being shutdown */
+	LASSERT (net->ibn_shutdown == 0);
+
+	/* npeers only grows with the global lock held */
+	atomic_inc(&net->ibn_npeers);
+
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	*peerp = peer;
+	return 0;
+}
+
+void
+kiblnd_destroy_peer (kib_peer_t *peer)
+{
+	kib_net_t *net = peer->ibp_ni->ni_data;
+
+	LASSERT (net != NULL);
+	LASSERT (atomic_read(&peer->ibp_refcount) == 0);
+	LASSERT (!kiblnd_peer_active(peer));
+	LASSERT (peer->ibp_connecting == 0);
+	LASSERT (peer->ibp_accepting == 0);
+	LASSERT (list_empty(&peer->ibp_conns));
+	LASSERT (list_empty(&peer->ibp_tx_queue));
+
+	LIBCFS_FREE(peer, sizeof(*peer));
+
+	/* NB a peer's connections keep a reference on their peer until
+	 * they are destroyed, so we can be assured that _all_ state to do
+	 * with this peer has been cleaned up when its refcount drops to
+	 * zero. */
+	atomic_dec(&net->ibn_npeers);
+}
+
+kib_peer_t *
+kiblnd_find_peer_locked (lnet_nid_t nid)
+{
+	/* the caller is responsible for accounting the additional reference
+	 * that this creates */
+	struct list_head       *peer_list = kiblnd_nid2peerlist(nid);
+	struct list_head       *tmp;
+	kib_peer_t       *peer;
+
+	list_for_each (tmp, peer_list) {
+
+		peer = list_entry(tmp, kib_peer_t, ibp_list);
+
+		LASSERT (peer->ibp_connecting > 0 || /* creating conns */
+			 peer->ibp_accepting > 0 ||
+			 !list_empty(&peer->ibp_conns));  /* active conn */
+
+		if (peer->ibp_nid != nid)
+			continue;
+
+		CDEBUG(D_NET, "got peer [%p] -> %s (%d) version: %x\n",
+		       peer, libcfs_nid2str(nid),
+		       atomic_read(&peer->ibp_refcount),
+		       peer->ibp_version);
+		return peer;
+	}
+	return NULL;
+}
+
+void
+kiblnd_unlink_peer_locked (kib_peer_t *peer)
+{
+	LASSERT (list_empty(&peer->ibp_conns));
+
+	LASSERT (kiblnd_peer_active(peer));
+	list_del_init(&peer->ibp_list);
+	/* lose peerlist's ref */
+	kiblnd_peer_decref(peer);
+}
+
+int
+kiblnd_get_peer_info (lnet_ni_t *ni, int index,
+		      lnet_nid_t *nidp, int *count)
+{
+	kib_peer_t	    *peer;
+	struct list_head	    *ptmp;
+	int		    i;
+	unsigned long	  flags;
+
+	read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	for (i = 0; i < kiblnd_data.kib_peer_hash_size; i++) {
+
+		list_for_each (ptmp, &kiblnd_data.kib_peers[i]) {
+
+			peer = list_entry(ptmp, kib_peer_t, ibp_list);
+			LASSERT (peer->ibp_connecting > 0 ||
+				 peer->ibp_accepting > 0 ||
+				 !list_empty(&peer->ibp_conns));
+
+			if (peer->ibp_ni != ni)
+				continue;
+
+			if (index-- > 0)
+				continue;
+
+			*nidp = peer->ibp_nid;
+			*count = atomic_read(&peer->ibp_refcount);
+
+			read_unlock_irqrestore(&kiblnd_data.kib_global_lock,
+					       flags);
+			return 0;
+		}
+	}
+
+	read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+	return -ENOENT;
+}
+
+void
+kiblnd_del_peer_locked (kib_peer_t *peer)
+{
+	struct list_head	   *ctmp;
+	struct list_head	   *cnxt;
+	kib_conn_t	   *conn;
+
+	if (list_empty(&peer->ibp_conns)) {
+		kiblnd_unlink_peer_locked(peer);
+	} else {
+		list_for_each_safe (ctmp, cnxt, &peer->ibp_conns) {
+			conn = list_entry(ctmp, kib_conn_t, ibc_list);
+
+			kiblnd_close_conn_locked(conn, 0);
+		}
+		/* NB closing peer's last conn unlinked it. */
+	}
+	/* NB peer now unlinked; might even be freed if the peer table had the
+	 * last ref on it. */
+}
+
+int
+kiblnd_del_peer (lnet_ni_t *ni, lnet_nid_t nid)
+{
+	LIST_HEAD	 (zombies);
+	struct list_head	    *ptmp;
+	struct list_head	    *pnxt;
+	kib_peer_t	    *peer;
+	int		    lo;
+	int		    hi;
+	int		    i;
+	unsigned long	  flags;
+	int		    rc = -ENOENT;
+
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	if (nid != LNET_NID_ANY) {
+		lo = hi = kiblnd_nid2peerlist(nid) - kiblnd_data.kib_peers;
+	} else {
+		lo = 0;
+		hi = kiblnd_data.kib_peer_hash_size - 1;
+	}
+
+	for (i = lo; i <= hi; i++) {
+		list_for_each_safe (ptmp, pnxt, &kiblnd_data.kib_peers[i]) {
+			peer = list_entry(ptmp, kib_peer_t, ibp_list);
+			LASSERT (peer->ibp_connecting > 0 ||
+				 peer->ibp_accepting > 0 ||
+				 !list_empty(&peer->ibp_conns));
+
+			if (peer->ibp_ni != ni)
+				continue;
+
+			if (!(nid == LNET_NID_ANY || peer->ibp_nid == nid))
+				continue;
+
+			if (!list_empty(&peer->ibp_tx_queue)) {
+				LASSERT (list_empty(&peer->ibp_conns));
+
+				list_splice_init(&peer->ibp_tx_queue,
+						     &zombies);
+			}
+
+			kiblnd_del_peer_locked(peer);
+			rc = 0;	 /* matched something */
+		}
+	}
+
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	kiblnd_txlist_done(ni, &zombies, -EIO);
+
+	return rc;
+}
+
+kib_conn_t *
+kiblnd_get_conn_by_idx (lnet_ni_t *ni, int index)
+{
+	kib_peer_t	    *peer;
+	struct list_head	    *ptmp;
+	kib_conn_t	    *conn;
+	struct list_head	    *ctmp;
+	int		    i;
+	unsigned long	  flags;
+
+	read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	for (i = 0; i < kiblnd_data.kib_peer_hash_size; i++) {
+		list_for_each (ptmp, &kiblnd_data.kib_peers[i]) {
+
+			peer = list_entry(ptmp, kib_peer_t, ibp_list);
+			LASSERT (peer->ibp_connecting > 0 ||
+				 peer->ibp_accepting > 0 ||
+				 !list_empty(&peer->ibp_conns));
+
+			if (peer->ibp_ni != ni)
+				continue;
+
+			list_for_each (ctmp, &peer->ibp_conns) {
+				if (index-- > 0)
+					continue;
+
+				conn = list_entry(ctmp, kib_conn_t,
+						      ibc_list);
+				kiblnd_conn_addref(conn);
+				read_unlock_irqrestore(&kiblnd_data.kib_global_lock,
+						       flags);
+				return conn;
+			}
+		}
+	}
+
+	read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+	return NULL;
+}
+
+void
+kiblnd_debug_rx (kib_rx_t *rx)
+{
+	CDEBUG(D_CONSOLE, "      %p status %d msg_type %x cred %d\n",
+	       rx, rx->rx_status, rx->rx_msg->ibm_type,
+	       rx->rx_msg->ibm_credits);
+}
+
+void
+kiblnd_debug_tx (kib_tx_t *tx)
+{
+	CDEBUG(D_CONSOLE, "      %p snd %d q %d w %d rc %d dl %lx "
+	       "cookie "LPX64" msg %s%s type %x cred %d\n",
+	       tx, tx->tx_sending, tx->tx_queued, tx->tx_waiting,
+	       tx->tx_status, tx->tx_deadline, tx->tx_cookie,
+	       tx->tx_lntmsg[0] == NULL ? "-" : "!",
+	       tx->tx_lntmsg[1] == NULL ? "-" : "!",
+	       tx->tx_msg->ibm_type, tx->tx_msg->ibm_credits);
+}
+
+void
+kiblnd_debug_conn (kib_conn_t *conn)
+{
+	struct list_head	*tmp;
+	int		i;
+
+	spin_lock(&conn->ibc_lock);
+
+	CDEBUG(D_CONSOLE, "conn[%d] %p [version %x] -> %s: \n",
+	       atomic_read(&conn->ibc_refcount), conn,
+	       conn->ibc_version, libcfs_nid2str(conn->ibc_peer->ibp_nid));
+	CDEBUG(D_CONSOLE, "   state %d nposted %d/%d cred %d o_cred %d r_cred %d\n",
+	       conn->ibc_state, conn->ibc_noops_posted,
+	       conn->ibc_nsends_posted, conn->ibc_credits,
+	       conn->ibc_outstanding_credits, conn->ibc_reserved_credits);
+	CDEBUG(D_CONSOLE, "   comms_err %d\n", conn->ibc_comms_error);
+
+	CDEBUG(D_CONSOLE, "   early_rxs:\n");
+	list_for_each(tmp, &conn->ibc_early_rxs)
+		kiblnd_debug_rx(list_entry(tmp, kib_rx_t, rx_list));
+
+	CDEBUG(D_CONSOLE, "   tx_noops:\n");
+	list_for_each(tmp, &conn->ibc_tx_noops)
+		kiblnd_debug_tx(list_entry(tmp, kib_tx_t, tx_list));
+
+	CDEBUG(D_CONSOLE, "   tx_queue_nocred:\n");
+	list_for_each(tmp, &conn->ibc_tx_queue_nocred)
+		kiblnd_debug_tx(list_entry(tmp, kib_tx_t, tx_list));
+
+	CDEBUG(D_CONSOLE, "   tx_queue_rsrvd:\n");
+	list_for_each(tmp, &conn->ibc_tx_queue_rsrvd)
+		kiblnd_debug_tx(list_entry(tmp, kib_tx_t, tx_list));
+
+	CDEBUG(D_CONSOLE, "   tx_queue:\n");
+	list_for_each(tmp, &conn->ibc_tx_queue)
+		kiblnd_debug_tx(list_entry(tmp, kib_tx_t, tx_list));
+
+	CDEBUG(D_CONSOLE, "   active_txs:\n");
+	list_for_each(tmp, &conn->ibc_active_txs)
+		kiblnd_debug_tx(list_entry(tmp, kib_tx_t, tx_list));
+
+	CDEBUG(D_CONSOLE, "   rxs:\n");
+	for (i = 0; i < IBLND_RX_MSGS(conn->ibc_version); i++)
+		kiblnd_debug_rx(&conn->ibc_rxs[i]);
+
+	spin_unlock(&conn->ibc_lock);
+}
+
+int
+kiblnd_translate_mtu(int value)
+{
+	switch (value) {
+	default:
+		return -1;
+	case 0:
+		return 0;
+	case 256:
+		return IB_MTU_256;
+	case 512:
+		return IB_MTU_512;
+	case 1024:
+		return IB_MTU_1024;
+	case 2048:
+		return IB_MTU_2048;
+	case 4096:
+		return IB_MTU_4096;
+	}
+}
+
+static void
+kiblnd_setup_mtu_locked(struct rdma_cm_id *cmid)
+{
+	int	   mtu;
+
+	/* XXX There is no path record for iWARP, set by netdev->change_mtu? */
+	if (cmid->route.path_rec == NULL)
+		return;
+
+	mtu = kiblnd_translate_mtu(*kiblnd_tunables.kib_ib_mtu);
+	LASSERT (mtu >= 0);
+	if (mtu != 0)
+		cmid->route.path_rec->mtu = mtu;
+}
+
+static int
+kiblnd_get_completion_vector(kib_conn_t *conn, int cpt)
+{
+	cpumask_t	*mask;
+	int		vectors;
+	int		off;
+	int		i;
+	lnet_nid_t	nid = conn->ibc_peer->ibp_nid;
+
+	vectors = conn->ibc_cmid->device->num_comp_vectors;
+	if (vectors <= 1)
+		return 0;
+
+	mask = cfs_cpt_cpumask(lnet_cpt_table(), cpt);
+
+	/* hash NID to CPU id in this partition... */
+	off = do_div(nid, cpus_weight(*mask));
+	for_each_cpu_mask(i, *mask) {
+		if (off-- == 0)
+			return i % vectors;
+	}
+
+	LBUG();
+	return 1;
+}
+
+kib_conn_t *
+kiblnd_create_conn(kib_peer_t *peer, struct rdma_cm_id *cmid,
+		   int state, int version)
+{
+	/* CAVEAT EMPTOR:
+	 * If the new conn is created successfully it takes over the caller's
+	 * ref on 'peer'.  It also "owns" 'cmid' and destroys it when it itself
+	 * is destroyed.  On failure, the caller's ref on 'peer' remains and
+	 * she must dispose of 'cmid'.  (Actually I'd block forever if I tried
+	 * to destroy 'cmid' here since I'm called from the CM which still has
+	 * its ref on 'cmid'). */
+	rwlock_t		*glock = &kiblnd_data.kib_global_lock;
+	kib_net_t	      *net = peer->ibp_ni->ni_data;
+	kib_dev_t	      *dev;
+	struct ib_qp_init_attr *init_qp_attr;
+	struct kib_sched_info	*sched;
+	kib_conn_t		*conn;
+	struct ib_cq		*cq;
+	unsigned long		flags;
+	int			cpt;
+	int			rc;
+	int			i;
+
+	LASSERT(net != NULL);
+	LASSERT(!in_interrupt());
+
+	dev = net->ibn_dev;
+
+	cpt = lnet_cpt_of_nid(peer->ibp_nid);
+	sched = kiblnd_data.kib_scheds[cpt];
+
+	LASSERT(sched->ibs_nthreads > 0);
+
+	LIBCFS_CPT_ALLOC(init_qp_attr, lnet_cpt_table(), cpt,
+			 sizeof(*init_qp_attr));
+	if (init_qp_attr == NULL) {
+		CERROR("Can't allocate qp_attr for %s\n",
+		       libcfs_nid2str(peer->ibp_nid));
+		goto failed_0;
+	}
+
+	LIBCFS_CPT_ALLOC(conn, lnet_cpt_table(), cpt, sizeof(*conn));
+	if (conn == NULL) {
+		CERROR("Can't allocate connection for %s\n",
+		       libcfs_nid2str(peer->ibp_nid));
+		goto failed_1;
+	}
+
+	conn->ibc_state = IBLND_CONN_INIT;
+	conn->ibc_version = version;
+	conn->ibc_peer = peer;		  /* I take the caller's ref */
+	cmid->context = conn;		   /* for future CM callbacks */
+	conn->ibc_cmid = cmid;
+
+	INIT_LIST_HEAD(&conn->ibc_early_rxs);
+	INIT_LIST_HEAD(&conn->ibc_tx_noops);
+	INIT_LIST_HEAD(&conn->ibc_tx_queue);
+	INIT_LIST_HEAD(&conn->ibc_tx_queue_rsrvd);
+	INIT_LIST_HEAD(&conn->ibc_tx_queue_nocred);
+	INIT_LIST_HEAD(&conn->ibc_active_txs);
+	spin_lock_init(&conn->ibc_lock);
+
+	LIBCFS_CPT_ALLOC(conn->ibc_connvars, lnet_cpt_table(), cpt,
+			 sizeof(*conn->ibc_connvars));
+	if (conn->ibc_connvars == NULL) {
+		CERROR("Can't allocate in-progress connection state\n");
+		goto failed_2;
+	}
+
+	write_lock_irqsave(glock, flags);
+	if (dev->ibd_failover) {
+		write_unlock_irqrestore(glock, flags);
+		CERROR("%s: failover in progress\n", dev->ibd_ifname);
+		goto failed_2;
+	}
+
+	if (dev->ibd_hdev->ibh_ibdev != cmid->device) {
+		/* wakeup failover thread and teardown connection */
+		if (kiblnd_dev_can_failover(dev)) {
+			list_add_tail(&dev->ibd_fail_list,
+				      &kiblnd_data.kib_failed_devs);
+			wake_up(&kiblnd_data.kib_failover_waitq);
+		}
+
+		write_unlock_irqrestore(glock, flags);
+		CERROR("cmid HCA(%s), kib_dev(%s) need failover\n",
+		       cmid->device->name, dev->ibd_ifname);
+		goto failed_2;
+	}
+
+	kiblnd_hdev_addref_locked(dev->ibd_hdev);
+	conn->ibc_hdev = dev->ibd_hdev;
+
+	kiblnd_setup_mtu_locked(cmid);
+
+	write_unlock_irqrestore(glock, flags);
+
+	LIBCFS_CPT_ALLOC(conn->ibc_rxs, lnet_cpt_table(), cpt,
+			 IBLND_RX_MSGS(version) * sizeof(kib_rx_t));
+	if (conn->ibc_rxs == NULL) {
+		CERROR("Cannot allocate RX buffers\n");
+		goto failed_2;
+	}
+
+	rc = kiblnd_alloc_pages(&conn->ibc_rx_pages, cpt,
+				IBLND_RX_MSG_PAGES(version));
+	if (rc != 0)
+		goto failed_2;
+
+	kiblnd_map_rx_descs(conn);
+
+	cq = ib_create_cq(cmid->device,
+			  kiblnd_cq_completion, kiblnd_cq_event, conn,
+			  IBLND_CQ_ENTRIES(version),
+			  kiblnd_get_completion_vector(conn, cpt));
+	if (IS_ERR(cq)) {
+		CERROR("Can't create CQ: %ld, cqe: %d\n",
+		       PTR_ERR(cq), IBLND_CQ_ENTRIES(version));
+		goto failed_2;
+	}
+
+	conn->ibc_cq = cq;
+
+	rc = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+	if (rc != 0) {
+		CERROR("Can't request completion notificiation: %d\n", rc);
+		goto failed_2;
+	}
+
+	init_qp_attr->event_handler = kiblnd_qp_event;
+	init_qp_attr->qp_context = conn;
+	init_qp_attr->cap.max_send_wr = IBLND_SEND_WRS(version);
+	init_qp_attr->cap.max_recv_wr = IBLND_RECV_WRS(version);
+	init_qp_attr->cap.max_send_sge = 1;
+	init_qp_attr->cap.max_recv_sge = 1;
+	init_qp_attr->sq_sig_type = IB_SIGNAL_REQ_WR;
+	init_qp_attr->qp_type = IB_QPT_RC;
+	init_qp_attr->send_cq = cq;
+	init_qp_attr->recv_cq = cq;
+
+	conn->ibc_sched = sched;
+
+	rc = rdma_create_qp(cmid, conn->ibc_hdev->ibh_pd, init_qp_attr);
+	if (rc != 0) {
+		CERROR("Can't create QP: %d, send_wr: %d, recv_wr: %d\n",
+		       rc, init_qp_attr->cap.max_send_wr,
+		       init_qp_attr->cap.max_recv_wr);
+		goto failed_2;
+	}
+
+	LIBCFS_FREE(init_qp_attr, sizeof(*init_qp_attr));
+
+	/* 1 ref for caller and each rxmsg */
+	atomic_set(&conn->ibc_refcount, 1 + IBLND_RX_MSGS(version));
+	conn->ibc_nrx = IBLND_RX_MSGS(version);
+
+	/* post receives */
+	for (i = 0; i < IBLND_RX_MSGS(version); i++) {
+		rc = kiblnd_post_rx(&conn->ibc_rxs[i],
+				    IBLND_POSTRX_NO_CREDIT);
+		if (rc != 0) {
+			CERROR("Can't post rxmsg: %d\n", rc);
+
+			/* Make posted receives complete */
+			kiblnd_abort_receives(conn);
+
+			/* correct # of posted buffers
+			 * NB locking needed now I'm racing with completion */
+			spin_lock_irqsave(&sched->ibs_lock, flags);
+			conn->ibc_nrx -= IBLND_RX_MSGS(version) - i;
+			spin_unlock_irqrestore(&sched->ibs_lock, flags);
+
+			/* cmid will be destroyed by CM(ofed) after cm_callback
+			 * returned, so we can't refer it anymore
+			 * (by kiblnd_connd()->kiblnd_destroy_conn) */
+			rdma_destroy_qp(conn->ibc_cmid);
+			conn->ibc_cmid = NULL;
+
+			/* Drop my own and unused rxbuffer refcounts */
+			while (i++ <= IBLND_RX_MSGS(version))
+				kiblnd_conn_decref(conn);
+
+			return NULL;
+		}
+	}
+
+	/* Init successful! */
+	LASSERT (state == IBLND_CONN_ACTIVE_CONNECT ||
+		 state == IBLND_CONN_PASSIVE_WAIT);
+	conn->ibc_state = state;
+
+	/* 1 more conn */
+	atomic_inc(&net->ibn_nconns);
+	return conn;
+
+ failed_2:
+	kiblnd_destroy_conn(conn);
+ failed_1:
+	LIBCFS_FREE(init_qp_attr, sizeof(*init_qp_attr));
+ failed_0:
+	return NULL;
+}
+
+void
+kiblnd_destroy_conn (kib_conn_t *conn)
+{
+	struct rdma_cm_id *cmid = conn->ibc_cmid;
+	kib_peer_t	*peer = conn->ibc_peer;
+	int		rc;
+
+	LASSERT (!in_interrupt());
+	LASSERT (atomic_read(&conn->ibc_refcount) == 0);
+	LASSERT (list_empty(&conn->ibc_early_rxs));
+	LASSERT (list_empty(&conn->ibc_tx_noops));
+	LASSERT (list_empty(&conn->ibc_tx_queue));
+	LASSERT (list_empty(&conn->ibc_tx_queue_rsrvd));
+	LASSERT (list_empty(&conn->ibc_tx_queue_nocred));
+	LASSERT (list_empty(&conn->ibc_active_txs));
+	LASSERT (conn->ibc_noops_posted == 0);
+	LASSERT (conn->ibc_nsends_posted == 0);
+
+	switch (conn->ibc_state) {
+	default:
+		/* conn must be completely disengaged from the network */
+		LBUG();
+
+	case IBLND_CONN_DISCONNECTED:
+		/* connvars should have been freed already */
+		LASSERT (conn->ibc_connvars == NULL);
+		break;
+
+	case IBLND_CONN_INIT:
+		break;
+	}
+
+	/* conn->ibc_cmid might be destroyed by CM already */
+	if (cmid != NULL && cmid->qp != NULL)
+		rdma_destroy_qp(cmid);
+
+	if (conn->ibc_cq != NULL) {
+		rc = ib_destroy_cq(conn->ibc_cq);
+		if (rc != 0)
+			CWARN("Error destroying CQ: %d\n", rc);
+	}
+
+	if (conn->ibc_rx_pages != NULL)
+		kiblnd_unmap_rx_descs(conn);
+
+	if (conn->ibc_rxs != NULL) {
+		LIBCFS_FREE(conn->ibc_rxs,
+			    IBLND_RX_MSGS(conn->ibc_version) * sizeof(kib_rx_t));
+	}
+
+	if (conn->ibc_connvars != NULL)
+		LIBCFS_FREE(conn->ibc_connvars, sizeof(*conn->ibc_connvars));
+
+	if (conn->ibc_hdev != NULL)
+		kiblnd_hdev_decref(conn->ibc_hdev);
+
+	/* See CAVEAT EMPTOR above in kiblnd_create_conn */
+	if (conn->ibc_state != IBLND_CONN_INIT) {
+		kib_net_t *net = peer->ibp_ni->ni_data;
+
+		kiblnd_peer_decref(peer);
+		rdma_destroy_id(cmid);
+		atomic_dec(&net->ibn_nconns);
+	}
+
+	LIBCFS_FREE(conn, sizeof(*conn));
+}
+
+int
+kiblnd_close_peer_conns_locked (kib_peer_t *peer, int why)
+{
+	kib_conn_t	     *conn;
+	struct list_head	     *ctmp;
+	struct list_head	     *cnxt;
+	int		     count = 0;
+
+	list_for_each_safe (ctmp, cnxt, &peer->ibp_conns) {
+		conn = list_entry(ctmp, kib_conn_t, ibc_list);
+
+		CDEBUG(D_NET, "Closing conn -> %s, "
+			      "version: %x, reason: %d\n",
+		       libcfs_nid2str(peer->ibp_nid),
+		       conn->ibc_version, why);
+
+		kiblnd_close_conn_locked(conn, why);
+		count++;
+	}
+
+	return count;
+}
+
+int
+kiblnd_close_stale_conns_locked (kib_peer_t *peer,
+				 int version, __u64 incarnation)
+{
+	kib_conn_t	     *conn;
+	struct list_head	     *ctmp;
+	struct list_head	     *cnxt;
+	int		     count = 0;
+
+	list_for_each_safe (ctmp, cnxt, &peer->ibp_conns) {
+		conn = list_entry(ctmp, kib_conn_t, ibc_list);
+
+		if (conn->ibc_version     == version &&
+		    conn->ibc_incarnation == incarnation)
+			continue;
+
+		CDEBUG(D_NET, "Closing stale conn -> %s version: %x, "
+			      "incarnation:"LPX64"(%x, "LPX64")\n",
+		       libcfs_nid2str(peer->ibp_nid),
+		       conn->ibc_version, conn->ibc_incarnation,
+		       version, incarnation);
+
+		kiblnd_close_conn_locked(conn, -ESTALE);
+		count++;
+	}
+
+	return count;
+}
+
+int
+kiblnd_close_matching_conns (lnet_ni_t *ni, lnet_nid_t nid)
+{
+	kib_peer_t	     *peer;
+	struct list_head	     *ptmp;
+	struct list_head	     *pnxt;
+	int		     lo;
+	int		     hi;
+	int		     i;
+	unsigned long	   flags;
+	int		     count = 0;
+
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	if (nid != LNET_NID_ANY)
+		lo = hi = kiblnd_nid2peerlist(nid) - kiblnd_data.kib_peers;
+	else {
+		lo = 0;
+		hi = kiblnd_data.kib_peer_hash_size - 1;
+	}
+
+	for (i = lo; i <= hi; i++) {
+		list_for_each_safe (ptmp, pnxt, &kiblnd_data.kib_peers[i]) {
+
+			peer = list_entry(ptmp, kib_peer_t, ibp_list);
+			LASSERT (peer->ibp_connecting > 0 ||
+				 peer->ibp_accepting > 0 ||
+				 !list_empty(&peer->ibp_conns));
+
+			if (peer->ibp_ni != ni)
+				continue;
+
+			if (!(nid == LNET_NID_ANY || nid == peer->ibp_nid))
+				continue;
+
+			count += kiblnd_close_peer_conns_locked(peer, 0);
+		}
+	}
+
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	/* wildcards always succeed */
+	if (nid == LNET_NID_ANY)
+		return 0;
+
+	return (count == 0) ? -ENOENT : 0;
+}
+
+int
+kiblnd_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg)
+{
+	struct libcfs_ioctl_data *data = arg;
+	int		       rc = -EINVAL;
+
+	switch(cmd) {
+	case IOC_LIBCFS_GET_PEER: {
+		lnet_nid_t   nid = 0;
+		int	  count = 0;
+
+		rc = kiblnd_get_peer_info(ni, data->ioc_count,
+					  &nid, &count);
+		data->ioc_nid    = nid;
+		data->ioc_count  = count;
+		break;
+	}
+
+	case IOC_LIBCFS_DEL_PEER: {
+		rc = kiblnd_del_peer(ni, data->ioc_nid);
+		break;
+	}
+	case IOC_LIBCFS_GET_CONN: {
+		kib_conn_t *conn;
+
+		rc = 0;
+		conn = kiblnd_get_conn_by_idx(ni, data->ioc_count);
+		if (conn == NULL) {
+			rc = -ENOENT;
+			break;
+		}
+
+		LASSERT (conn->ibc_cmid != NULL);
+		data->ioc_nid = conn->ibc_peer->ibp_nid;
+		if (conn->ibc_cmid->route.path_rec == NULL)
+			data->ioc_u32[0] = 0; /* iWarp has no path MTU */
+		else
+			data->ioc_u32[0] =
+			ib_mtu_enum_to_int(conn->ibc_cmid->route.path_rec->mtu);
+		kiblnd_conn_decref(conn);
+		break;
+	}
+	case IOC_LIBCFS_CLOSE_CONNECTION: {
+		rc = kiblnd_close_matching_conns(ni, data->ioc_nid);
+		break;
+	}
+
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+void
+kiblnd_query (lnet_ni_t *ni, lnet_nid_t nid, cfs_time_t *when)
+{
+	cfs_time_t	last_alive = 0;
+	cfs_time_t	now = cfs_time_current();
+	rwlock_t	*glock = &kiblnd_data.kib_global_lock;
+	kib_peer_t	*peer;
+	unsigned long	flags;
+
+	read_lock_irqsave(glock, flags);
+
+	peer = kiblnd_find_peer_locked(nid);
+	if (peer != NULL) {
+		LASSERT (peer->ibp_connecting > 0 || /* creating conns */
+			 peer->ibp_accepting > 0 ||
+			 !list_empty(&peer->ibp_conns));  /* active conn */
+		last_alive = peer->ibp_last_alive;
+	}
+
+	read_unlock_irqrestore(glock, flags);
+
+	if (last_alive != 0)
+		*when = last_alive;
+
+	/* peer is not persistent in hash, trigger peer creation
+	 * and connection establishment with a NULL tx */
+	if (peer == NULL)
+		kiblnd_launch_tx(ni, NULL, nid);
+
+	CDEBUG(D_NET, "Peer %s %p, alive %ld secs ago\n",
+	       libcfs_nid2str(nid), peer,
+	       last_alive ? cfs_duration_sec(now - last_alive) : -1);
+	return;
+}
+
+void
+kiblnd_free_pages(kib_pages_t *p)
+{
+	int	npages = p->ibp_npages;
+	int	i;
+
+	for (i = 0; i < npages; i++) {
+		if (p->ibp_pages[i] != NULL)
+			__free_page(p->ibp_pages[i]);
+	}
+
+	LIBCFS_FREE(p, offsetof(kib_pages_t, ibp_pages[npages]));
+}
+
+int
+kiblnd_alloc_pages(kib_pages_t **pp, int cpt, int npages)
+{
+	kib_pages_t	*p;
+	int		i;
+
+	LIBCFS_CPT_ALLOC(p, lnet_cpt_table(), cpt,
+			 offsetof(kib_pages_t, ibp_pages[npages]));
+	if (p == NULL) {
+		CERROR("Can't allocate descriptor for %d pages\n", npages);
+		return -ENOMEM;
+	}
+
+	memset(p, 0, offsetof(kib_pages_t, ibp_pages[npages]));
+	p->ibp_npages = npages;
+
+	for (i = 0; i < npages; i++) {
+		p->ibp_pages[i] = alloc_pages_node(
+				    cfs_cpt_spread_node(lnet_cpt_table(), cpt),
+				    __GFP_IO, 0);
+		if (p->ibp_pages[i] == NULL) {
+			CERROR("Can't allocate page %d of %d\n", i, npages);
+			kiblnd_free_pages(p);
+			return -ENOMEM;
+		}
+	}
+
+	*pp = p;
+	return 0;
+}
+
+void
+kiblnd_unmap_rx_descs(kib_conn_t *conn)
+{
+	kib_rx_t *rx;
+	int       i;
+
+	LASSERT (conn->ibc_rxs != NULL);
+	LASSERT (conn->ibc_hdev != NULL);
+
+	for (i = 0; i < IBLND_RX_MSGS(conn->ibc_version); i++) {
+		rx = &conn->ibc_rxs[i];
+
+		LASSERT (rx->rx_nob >= 0); /* not posted */
+
+		kiblnd_dma_unmap_single(conn->ibc_hdev->ibh_ibdev,
+					KIBLND_UNMAP_ADDR(rx, rx_msgunmap,
+							  rx->rx_msgaddr),
+					IBLND_MSG_SIZE, DMA_FROM_DEVICE);
+	}
+
+	kiblnd_free_pages(conn->ibc_rx_pages);
+
+	conn->ibc_rx_pages = NULL;
+}
+
+void
+kiblnd_map_rx_descs(kib_conn_t *conn)
+{
+	kib_rx_t       *rx;
+	struct page    *pg;
+	int	     pg_off;
+	int	     ipg;
+	int	     i;
+
+	for (pg_off = ipg = i = 0;
+	     i < IBLND_RX_MSGS(conn->ibc_version); i++) {
+		pg = conn->ibc_rx_pages->ibp_pages[ipg];
+		rx = &conn->ibc_rxs[i];
+
+		rx->rx_conn = conn;
+		rx->rx_msg = (kib_msg_t *)(((char *)page_address(pg)) + pg_off);
+
+		rx->rx_msgaddr = kiblnd_dma_map_single(conn->ibc_hdev->ibh_ibdev,
+						       rx->rx_msg, IBLND_MSG_SIZE,
+						       DMA_FROM_DEVICE);
+		LASSERT (!kiblnd_dma_mapping_error(conn->ibc_hdev->ibh_ibdev,
+						   rx->rx_msgaddr));
+		KIBLND_UNMAP_ADDR_SET(rx, rx_msgunmap, rx->rx_msgaddr);
+
+		CDEBUG(D_NET,"rx %d: %p "LPX64"("LPX64")\n",
+		       i, rx->rx_msg, rx->rx_msgaddr,
+		       lnet_page2phys(pg) + pg_off);
+
+		pg_off += IBLND_MSG_SIZE;
+		LASSERT (pg_off <= PAGE_SIZE);
+
+		if (pg_off == PAGE_SIZE) {
+			pg_off = 0;
+			ipg++;
+			LASSERT (ipg <= IBLND_RX_MSG_PAGES(conn->ibc_version));
+		}
+	}
+}
+
+static void
+kiblnd_unmap_tx_pool(kib_tx_pool_t *tpo)
+{
+	kib_hca_dev_t  *hdev = tpo->tpo_hdev;
+	kib_tx_t       *tx;
+	int	     i;
+
+	LASSERT (tpo->tpo_pool.po_allocated == 0);
+
+	if (hdev == NULL)
+		return;
+
+	for (i = 0; i < tpo->tpo_pool.po_size; i++) {
+		tx = &tpo->tpo_tx_descs[i];
+		kiblnd_dma_unmap_single(hdev->ibh_ibdev,
+					KIBLND_UNMAP_ADDR(tx, tx_msgunmap,
+							  tx->tx_msgaddr),
+					IBLND_MSG_SIZE, DMA_TO_DEVICE);
+	}
+
+	kiblnd_hdev_decref(hdev);
+	tpo->tpo_hdev = NULL;
+}
+
+static kib_hca_dev_t *
+kiblnd_current_hdev(kib_dev_t *dev)
+{
+	kib_hca_dev_t *hdev;
+	unsigned long  flags;
+	int	    i = 0;
+
+	read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+	while (dev->ibd_failover) {
+		read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+		if (i++ % 50 == 0)
+			CDEBUG(D_NET, "%s: Wait for failover\n",
+			       dev->ibd_ifname);
+		schedule_timeout(cfs_time_seconds(1) / 100);
+
+		read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+	}
+
+	kiblnd_hdev_addref_locked(dev->ibd_hdev);
+	hdev = dev->ibd_hdev;
+
+	read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	return hdev;
+}
+
+static void
+kiblnd_map_tx_pool(kib_tx_pool_t *tpo)
+{
+	kib_pages_t    *txpgs = tpo->tpo_tx_pages;
+	kib_pool_t     *pool  = &tpo->tpo_pool;
+	kib_net_t      *net   = pool->po_owner->ps_net;
+	kib_dev_t      *dev;
+	struct page    *page;
+	kib_tx_t       *tx;
+	int	     page_offset;
+	int	     ipage;
+	int	     i;
+
+	LASSERT (net != NULL);
+
+	dev = net->ibn_dev;
+
+	/* pre-mapped messages are not bigger than 1 page */
+	CLASSERT (IBLND_MSG_SIZE <= PAGE_SIZE);
+
+	/* No fancy arithmetic when we do the buffer calculations */
+	CLASSERT (PAGE_SIZE % IBLND_MSG_SIZE == 0);
+
+	tpo->tpo_hdev = kiblnd_current_hdev(dev);
+
+	for (ipage = page_offset = i = 0; i < pool->po_size; i++) {
+		page = txpgs->ibp_pages[ipage];
+		tx = &tpo->tpo_tx_descs[i];
+
+		tx->tx_msg = (kib_msg_t *)(((char *)page_address(page)) +
+					   page_offset);
+
+		tx->tx_msgaddr = kiblnd_dma_map_single(
+			tpo->tpo_hdev->ibh_ibdev, tx->tx_msg,
+			IBLND_MSG_SIZE, DMA_TO_DEVICE);
+		LASSERT (!kiblnd_dma_mapping_error(tpo->tpo_hdev->ibh_ibdev,
+						   tx->tx_msgaddr));
+		KIBLND_UNMAP_ADDR_SET(tx, tx_msgunmap, tx->tx_msgaddr);
+
+		list_add(&tx->tx_list, &pool->po_free_list);
+
+		page_offset += IBLND_MSG_SIZE;
+		LASSERT (page_offset <= PAGE_SIZE);
+
+		if (page_offset == PAGE_SIZE) {
+			page_offset = 0;
+			ipage++;
+			LASSERT (ipage <= txpgs->ibp_npages);
+		}
+	}
+}
+
+struct ib_mr *
+kiblnd_find_dma_mr(kib_hca_dev_t *hdev, __u64 addr, __u64 size)
+{
+	__u64   index;
+
+	LASSERT (hdev->ibh_mrs[0] != NULL);
+
+	if (hdev->ibh_nmrs == 1)
+		return hdev->ibh_mrs[0];
+
+	index = addr >> hdev->ibh_mr_shift;
+
+	if (index <  hdev->ibh_nmrs &&
+	    index == ((addr + size - 1) >> hdev->ibh_mr_shift))
+		return hdev->ibh_mrs[index];
+
+	return NULL;
+}
+
+struct ib_mr *
+kiblnd_find_rd_dma_mr(kib_hca_dev_t *hdev, kib_rdma_desc_t *rd)
+{
+	struct ib_mr *prev_mr;
+	struct ib_mr *mr;
+	int	   i;
+
+	LASSERT (hdev->ibh_mrs[0] != NULL);
+
+	if (*kiblnd_tunables.kib_map_on_demand > 0 &&
+	    *kiblnd_tunables.kib_map_on_demand <= rd->rd_nfrags)
+		return NULL;
+
+	if (hdev->ibh_nmrs == 1)
+		return hdev->ibh_mrs[0];
+
+	for (i = 0, mr = prev_mr = NULL;
+	     i < rd->rd_nfrags; i++) {
+		mr = kiblnd_find_dma_mr(hdev,
+					rd->rd_frags[i].rf_addr,
+					rd->rd_frags[i].rf_nob);
+		if (prev_mr == NULL)
+			prev_mr = mr;
+
+		if (mr == NULL || prev_mr != mr) {
+			/* Can't covered by one single MR */
+			mr = NULL;
+			break;
+		}
+	}
+
+	return mr;
+}
+
+void
+kiblnd_destroy_fmr_pool(kib_fmr_pool_t *pool)
+{
+	LASSERT (pool->fpo_map_count == 0);
+
+	if (pool->fpo_fmr_pool != NULL)
+		ib_destroy_fmr_pool(pool->fpo_fmr_pool);
+
+	if (pool->fpo_hdev != NULL)
+		kiblnd_hdev_decref(pool->fpo_hdev);
+
+	LIBCFS_FREE(pool, sizeof(kib_fmr_pool_t));
+}
+
+void
+kiblnd_destroy_fmr_pool_list(struct list_head *head)
+{
+	kib_fmr_pool_t *pool;
+
+	while (!list_empty(head)) {
+		pool = list_entry(head->next, kib_fmr_pool_t, fpo_list);
+		list_del(&pool->fpo_list);
+		kiblnd_destroy_fmr_pool(pool);
+	}
+}
+
+static int kiblnd_fmr_pool_size(int ncpts)
+{
+	int size = *kiblnd_tunables.kib_fmr_pool_size / ncpts;
+
+	return max(IBLND_FMR_POOL, size);
+}
+
+static int kiblnd_fmr_flush_trigger(int ncpts)
+{
+	int size = *kiblnd_tunables.kib_fmr_flush_trigger / ncpts;
+
+	return max(IBLND_FMR_POOL_FLUSH, size);
+}
+
+int
+kiblnd_create_fmr_pool(kib_fmr_poolset_t *fps, kib_fmr_pool_t **pp_fpo)
+{
+	/* FMR pool for RDMA */
+	kib_dev_t	       *dev = fps->fps_net->ibn_dev;
+	kib_fmr_pool_t	  *fpo;
+	struct ib_fmr_pool_param param = {
+		.max_pages_per_fmr = LNET_MAX_PAYLOAD/PAGE_SIZE,
+		.page_shift	= PAGE_SHIFT,
+		.access	    = (IB_ACCESS_LOCAL_WRITE |
+				      IB_ACCESS_REMOTE_WRITE),
+		.pool_size	   = fps->fps_pool_size,
+		.dirty_watermark   = fps->fps_flush_trigger,
+		.flush_function    = NULL,
+		.flush_arg	 = NULL,
+		.cache	     = !!*kiblnd_tunables.kib_fmr_cache};
+	int rc;
+
+	LIBCFS_CPT_ALLOC(fpo, lnet_cpt_table(), fps->fps_cpt, sizeof(*fpo));
+	if (fpo == NULL)
+		return -ENOMEM;
+
+	fpo->fpo_hdev = kiblnd_current_hdev(dev);
+
+	fpo->fpo_fmr_pool = ib_create_fmr_pool(fpo->fpo_hdev->ibh_pd, &param);
+	if (IS_ERR(fpo->fpo_fmr_pool)) {
+		rc = PTR_ERR(fpo->fpo_fmr_pool);
+		CERROR("Failed to create FMR pool: %d\n", rc);
+
+		kiblnd_hdev_decref(fpo->fpo_hdev);
+		LIBCFS_FREE(fpo, sizeof(kib_fmr_pool_t));
+		return rc;
+	}
+
+	fpo->fpo_deadline = cfs_time_shift(IBLND_POOL_DEADLINE);
+	fpo->fpo_owner    = fps;
+	*pp_fpo = fpo;
+
+	return 0;
+}
+
+static void
+kiblnd_fail_fmr_poolset(kib_fmr_poolset_t *fps, struct list_head *zombies)
+{
+	if (fps->fps_net == NULL) /* intialized? */
+		return;
+
+	spin_lock(&fps->fps_lock);
+
+	while (!list_empty(&fps->fps_pool_list)) {
+		kib_fmr_pool_t *fpo = list_entry(fps->fps_pool_list.next,
+						 kib_fmr_pool_t, fpo_list);
+		fpo->fpo_failed = 1;
+		list_del(&fpo->fpo_list);
+		if (fpo->fpo_map_count == 0)
+			list_add(&fpo->fpo_list, zombies);
+		else
+			list_add(&fpo->fpo_list, &fps->fps_failed_pool_list);
+	}
+
+	spin_unlock(&fps->fps_lock);
+}
+
+static void
+kiblnd_fini_fmr_poolset(kib_fmr_poolset_t *fps)
+{
+	if (fps->fps_net != NULL) { /* initialized? */
+		kiblnd_destroy_fmr_pool_list(&fps->fps_failed_pool_list);
+		kiblnd_destroy_fmr_pool_list(&fps->fps_pool_list);
+	}
+}
+
+static int
+kiblnd_init_fmr_poolset(kib_fmr_poolset_t *fps, int cpt, kib_net_t *net,
+			int pool_size, int flush_trigger)
+{
+	kib_fmr_pool_t *fpo;
+	int	     rc;
+
+	memset(fps, 0, sizeof(kib_fmr_poolset_t));
+
+	fps->fps_net = net;
+	fps->fps_cpt = cpt;
+	fps->fps_pool_size = pool_size;
+	fps->fps_flush_trigger = flush_trigger;
+	spin_lock_init(&fps->fps_lock);
+	INIT_LIST_HEAD(&fps->fps_pool_list);
+	INIT_LIST_HEAD(&fps->fps_failed_pool_list);
+
+	rc = kiblnd_create_fmr_pool(fps, &fpo);
+	if (rc == 0)
+		list_add_tail(&fpo->fpo_list, &fps->fps_pool_list);
+
+	return rc;
+}
+
+static int
+kiblnd_fmr_pool_is_idle(kib_fmr_pool_t *fpo, cfs_time_t now)
+{
+	if (fpo->fpo_map_count != 0) /* still in use */
+		return 0;
+	if (fpo->fpo_failed)
+		return 1;
+	return cfs_time_aftereq(now, fpo->fpo_deadline);
+}
+
+void
+kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status)
+{
+	LIST_HEAD     (zombies);
+	kib_fmr_pool_t    *fpo = fmr->fmr_pool;
+	kib_fmr_poolset_t *fps = fpo->fpo_owner;
+	cfs_time_t	 now = cfs_time_current();
+	kib_fmr_pool_t    *tmp;
+	int		rc;
+
+	rc = ib_fmr_pool_unmap(fmr->fmr_pfmr);
+	LASSERT (rc == 0);
+
+	if (status != 0) {
+		rc = ib_flush_fmr_pool(fpo->fpo_fmr_pool);
+		LASSERT (rc == 0);
+	}
+
+	fmr->fmr_pool = NULL;
+	fmr->fmr_pfmr = NULL;
+
+	spin_lock(&fps->fps_lock);
+	fpo->fpo_map_count --;  /* decref the pool */
+
+	list_for_each_entry_safe(fpo, tmp, &fps->fps_pool_list, fpo_list) {
+		/* the first pool is persistent */
+		if (fps->fps_pool_list.next == &fpo->fpo_list)
+			continue;
+
+		if (kiblnd_fmr_pool_is_idle(fpo, now)) {
+			list_move(&fpo->fpo_list, &zombies);
+			fps->fps_version ++;
+		}
+	}
+	spin_unlock(&fps->fps_lock);
+
+	if (!list_empty(&zombies))
+		kiblnd_destroy_fmr_pool_list(&zombies);
+}
+
+int
+kiblnd_fmr_pool_map(kib_fmr_poolset_t *fps, __u64 *pages, int npages,
+		    __u64 iov, kib_fmr_t *fmr)
+{
+	struct ib_pool_fmr *pfmr;
+	kib_fmr_pool_t     *fpo;
+	__u64	       version;
+	int		 rc;
+
+ again:
+	spin_lock(&fps->fps_lock);
+	version = fps->fps_version;
+	list_for_each_entry(fpo, &fps->fps_pool_list, fpo_list) {
+		fpo->fpo_deadline = cfs_time_shift(IBLND_POOL_DEADLINE);
+		fpo->fpo_map_count++;
+		spin_unlock(&fps->fps_lock);
+
+		pfmr = ib_fmr_pool_map_phys(fpo->fpo_fmr_pool,
+					    pages, npages, iov);
+		if (likely(!IS_ERR(pfmr))) {
+			fmr->fmr_pool = fpo;
+			fmr->fmr_pfmr = pfmr;
+			return 0;
+		}
+
+		spin_lock(&fps->fps_lock);
+		fpo->fpo_map_count--;
+		if (PTR_ERR(pfmr) != -EAGAIN) {
+			spin_unlock(&fps->fps_lock);
+			return PTR_ERR(pfmr);
+		}
+
+		/* EAGAIN and ... */
+		if (version != fps->fps_version) {
+			spin_unlock(&fps->fps_lock);
+			goto again;
+		}
+	}
+
+	if (fps->fps_increasing) {
+		spin_unlock(&fps->fps_lock);
+		CDEBUG(D_NET, "Another thread is allocating new "
+		       "FMR pool, waiting for her to complete\n");
+		schedule();
+		goto again;
+
+	}
+
+	if (cfs_time_before(cfs_time_current(), fps->fps_next_retry)) {
+		/* someone failed recently */
+		spin_unlock(&fps->fps_lock);
+		return -EAGAIN;
+	}
+
+	fps->fps_increasing = 1;
+	spin_unlock(&fps->fps_lock);
+
+	CDEBUG(D_NET, "Allocate new FMR pool\n");
+	rc = kiblnd_create_fmr_pool(fps, &fpo);
+	spin_lock(&fps->fps_lock);
+	fps->fps_increasing = 0;
+	if (rc == 0) {
+		fps->fps_version++;
+		list_add_tail(&fpo->fpo_list, &fps->fps_pool_list);
+	} else {
+		fps->fps_next_retry = cfs_time_shift(IBLND_POOL_RETRY);
+	}
+	spin_unlock(&fps->fps_lock);
+
+	goto again;
+}
+
+static void
+kiblnd_fini_pool(kib_pool_t *pool)
+{
+	LASSERT (list_empty(&pool->po_free_list));
+	LASSERT (pool->po_allocated == 0);
+
+	CDEBUG(D_NET, "Finalize %s pool\n", pool->po_owner->ps_name);
+}
+
+static void
+kiblnd_init_pool(kib_poolset_t *ps, kib_pool_t *pool, int size)
+{
+	CDEBUG(D_NET, "Initialize %s pool\n", ps->ps_name);
+
+	memset(pool, 0, sizeof(kib_pool_t));
+	INIT_LIST_HEAD(&pool->po_free_list);
+	pool->po_deadline = cfs_time_shift(IBLND_POOL_DEADLINE);
+	pool->po_owner    = ps;
+	pool->po_size     = size;
+}
+
+void
+kiblnd_destroy_pool_list(struct list_head *head)
+{
+	kib_pool_t *pool;
+
+	while (!list_empty(head)) {
+		pool = list_entry(head->next, kib_pool_t, po_list);
+		list_del(&pool->po_list);
+
+		LASSERT (pool->po_owner != NULL);
+		pool->po_owner->ps_pool_destroy(pool);
+	}
+}
+
+static void
+kiblnd_fail_poolset(kib_poolset_t *ps, struct list_head *zombies)
+{
+	if (ps->ps_net == NULL) /* intialized? */
+		return;
+
+	spin_lock(&ps->ps_lock);
+	while (!list_empty(&ps->ps_pool_list)) {
+		kib_pool_t *po = list_entry(ps->ps_pool_list.next,
+					    kib_pool_t, po_list);
+		po->po_failed = 1;
+		list_del(&po->po_list);
+		if (po->po_allocated == 0)
+			list_add(&po->po_list, zombies);
+		else
+			list_add(&po->po_list, &ps->ps_failed_pool_list);
+	}
+	spin_unlock(&ps->ps_lock);
+}
+
+static void
+kiblnd_fini_poolset(kib_poolset_t *ps)
+{
+	if (ps->ps_net != NULL) { /* initialized? */
+		kiblnd_destroy_pool_list(&ps->ps_failed_pool_list);
+		kiblnd_destroy_pool_list(&ps->ps_pool_list);
+	}
+}
+
+static int
+kiblnd_init_poolset(kib_poolset_t *ps, int cpt,
+		    kib_net_t *net, char *name, int size,
+		    kib_ps_pool_create_t po_create,
+		    kib_ps_pool_destroy_t po_destroy,
+		    kib_ps_node_init_t nd_init,
+		    kib_ps_node_fini_t nd_fini)
+{
+	kib_pool_t	*pool;
+	int		rc;
+
+	memset(ps, 0, sizeof(kib_poolset_t));
+
+	ps->ps_cpt	    = cpt;
+	ps->ps_net	  = net;
+	ps->ps_pool_create  = po_create;
+	ps->ps_pool_destroy = po_destroy;
+	ps->ps_node_init    = nd_init;
+	ps->ps_node_fini    = nd_fini;
+	ps->ps_pool_size    = size;
+	if (strlcpy(ps->ps_name, name, sizeof(ps->ps_name))
+	    >= sizeof(ps->ps_name))
+		return -E2BIG;
+	spin_lock_init(&ps->ps_lock);
+	INIT_LIST_HEAD(&ps->ps_pool_list);
+	INIT_LIST_HEAD(&ps->ps_failed_pool_list);
+
+	rc = ps->ps_pool_create(ps, size, &pool);
+	if (rc == 0)
+		list_add(&pool->po_list, &ps->ps_pool_list);
+	else
+		CERROR("Failed to create the first pool for %s\n", ps->ps_name);
+
+	return rc;
+}
+
+static int
+kiblnd_pool_is_idle(kib_pool_t *pool, cfs_time_t now)
+{
+	if (pool->po_allocated != 0) /* still in use */
+		return 0;
+	if (pool->po_failed)
+		return 1;
+	return cfs_time_aftereq(now, pool->po_deadline);
+}
+
+void
+kiblnd_pool_free_node(kib_pool_t *pool, struct list_head *node)
+{
+	LIST_HEAD  (zombies);
+	kib_poolset_t  *ps = pool->po_owner;
+	kib_pool_t     *tmp;
+	cfs_time_t      now = cfs_time_current();
+
+	spin_lock(&ps->ps_lock);
+
+	if (ps->ps_node_fini != NULL)
+		ps->ps_node_fini(pool, node);
+
+	LASSERT (pool->po_allocated > 0);
+	list_add(node, &pool->po_free_list);
+	pool->po_allocated --;
+
+	list_for_each_entry_safe(pool, tmp, &ps->ps_pool_list, po_list) {
+		/* the first pool is persistent */
+		if (ps->ps_pool_list.next == &pool->po_list)
+			continue;
+
+		if (kiblnd_pool_is_idle(pool, now))
+			list_move(&pool->po_list, &zombies);
+	}
+	spin_unlock(&ps->ps_lock);
+
+	if (!list_empty(&zombies))
+		kiblnd_destroy_pool_list(&zombies);
+}
+
+struct list_head *
+kiblnd_pool_alloc_node(kib_poolset_t *ps)
+{
+	struct list_head	    *node;
+	kib_pool_t	    *pool;
+	int		    rc;
+
+ again:
+	spin_lock(&ps->ps_lock);
+	list_for_each_entry(pool, &ps->ps_pool_list, po_list) {
+		if (list_empty(&pool->po_free_list))
+			continue;
+
+		pool->po_allocated ++;
+		pool->po_deadline = cfs_time_shift(IBLND_POOL_DEADLINE);
+		node = pool->po_free_list.next;
+		list_del(node);
+
+		if (ps->ps_node_init != NULL) {
+			/* still hold the lock */
+			ps->ps_node_init(pool, node);
+		}
+		spin_unlock(&ps->ps_lock);
+		return node;
+	}
+
+	/* no available tx pool and ... */
+	if (ps->ps_increasing) {
+		/* another thread is allocating a new pool */
+		spin_unlock(&ps->ps_lock);
+		CDEBUG(D_NET, "Another thread is allocating new "
+		       "%s pool, waiting for her to complete\n",
+		       ps->ps_name);
+		schedule();
+		goto again;
+	}
+
+	if (cfs_time_before(cfs_time_current(), ps->ps_next_retry)) {
+		/* someone failed recently */
+		spin_unlock(&ps->ps_lock);
+		return NULL;
+	}
+
+	ps->ps_increasing = 1;
+	spin_unlock(&ps->ps_lock);
+
+	CDEBUG(D_NET, "%s pool exhausted, allocate new pool\n", ps->ps_name);
+
+	rc = ps->ps_pool_create(ps, ps->ps_pool_size, &pool);
+
+	spin_lock(&ps->ps_lock);
+	ps->ps_increasing = 0;
+	if (rc == 0) {
+		list_add_tail(&pool->po_list, &ps->ps_pool_list);
+	} else {
+		ps->ps_next_retry = cfs_time_shift(IBLND_POOL_RETRY);
+		CERROR("Can't allocate new %s pool because out of memory\n",
+		       ps->ps_name);
+	}
+	spin_unlock(&ps->ps_lock);
+
+	goto again;
+}
+
+void
+kiblnd_pmr_pool_unmap(kib_phys_mr_t *pmr)
+{
+	kib_pmr_pool_t      *ppo = pmr->pmr_pool;
+	struct ib_mr	*mr  = pmr->pmr_mr;
+
+	pmr->pmr_mr = NULL;
+	kiblnd_pool_free_node(&ppo->ppo_pool, &pmr->pmr_list);
+	if (mr != NULL)
+		ib_dereg_mr(mr);
+}
+
+int
+kiblnd_pmr_pool_map(kib_pmr_poolset_t *pps, kib_hca_dev_t *hdev,
+		    kib_rdma_desc_t *rd, __u64 *iova, kib_phys_mr_t **pp_pmr)
+{
+	kib_phys_mr_t *pmr;
+	struct list_head    *node;
+	int	    rc;
+	int	    i;
+
+	node = kiblnd_pool_alloc_node(&pps->pps_poolset);
+	if (node == NULL) {
+		CERROR("Failed to allocate PMR descriptor\n");
+		return -ENOMEM;
+	}
+
+	pmr = container_of(node, kib_phys_mr_t, pmr_list);
+	if (pmr->pmr_pool->ppo_hdev != hdev) {
+		kiblnd_pool_free_node(&pmr->pmr_pool->ppo_pool, node);
+		return -EAGAIN;
+	}
+
+	for (i = 0; i < rd->rd_nfrags; i ++) {
+		pmr->pmr_ipb[i].addr = rd->rd_frags[i].rf_addr;
+		pmr->pmr_ipb[i].size = rd->rd_frags[i].rf_nob;
+	}
+
+	pmr->pmr_mr = ib_reg_phys_mr(hdev->ibh_pd,
+				     pmr->pmr_ipb, rd->rd_nfrags,
+				     IB_ACCESS_LOCAL_WRITE |
+				     IB_ACCESS_REMOTE_WRITE,
+				     iova);
+	if (!IS_ERR(pmr->pmr_mr)) {
+		pmr->pmr_iova = *iova;
+		*pp_pmr = pmr;
+		return 0;
+	}
+
+	rc = PTR_ERR(pmr->pmr_mr);
+	CERROR("Failed ib_reg_phys_mr: %d\n", rc);
+
+	pmr->pmr_mr = NULL;
+	kiblnd_pool_free_node(&pmr->pmr_pool->ppo_pool, node);
+
+	return rc;
+}
+
+static void
+kiblnd_destroy_pmr_pool(kib_pool_t *pool)
+{
+	kib_pmr_pool_t *ppo = container_of(pool, kib_pmr_pool_t, ppo_pool);
+	kib_phys_mr_t  *pmr;
+
+	LASSERT (pool->po_allocated == 0);
+
+	while (!list_empty(&pool->po_free_list)) {
+		pmr = list_entry(pool->po_free_list.next,
+				     kib_phys_mr_t, pmr_list);
+
+		LASSERT (pmr->pmr_mr == NULL);
+		list_del(&pmr->pmr_list);
+
+		if (pmr->pmr_ipb != NULL) {
+			LIBCFS_FREE(pmr->pmr_ipb,
+				    IBLND_MAX_RDMA_FRAGS *
+				    sizeof(struct ib_phys_buf));
+		}
+
+		LIBCFS_FREE(pmr, sizeof(kib_phys_mr_t));
+	}
+
+	kiblnd_fini_pool(pool);
+	if (ppo->ppo_hdev != NULL)
+		kiblnd_hdev_decref(ppo->ppo_hdev);
+
+	LIBCFS_FREE(ppo, sizeof(kib_pmr_pool_t));
+}
+
+static inline int kiblnd_pmr_pool_size(int ncpts)
+{
+	int size = *kiblnd_tunables.kib_pmr_pool_size / ncpts;
+
+	return max(IBLND_PMR_POOL, size);
+}
+
+static int
+kiblnd_create_pmr_pool(kib_poolset_t *ps, int size, kib_pool_t **pp_po)
+{
+	struct kib_pmr_pool	*ppo;
+	struct kib_pool		*pool;
+	kib_phys_mr_t		*pmr;
+	int			i;
+
+	LIBCFS_CPT_ALLOC(ppo, lnet_cpt_table(),
+			 ps->ps_cpt, sizeof(kib_pmr_pool_t));
+	if (ppo == NULL) {
+		CERROR("Failed to allocate PMR pool\n");
+		return -ENOMEM;
+	}
+
+	pool = &ppo->ppo_pool;
+	kiblnd_init_pool(ps, pool, size);
+
+	for (i = 0; i < size; i++) {
+		LIBCFS_CPT_ALLOC(pmr, lnet_cpt_table(),
+				 ps->ps_cpt, sizeof(kib_phys_mr_t));
+		if (pmr == NULL)
+			break;
+
+		pmr->pmr_pool = ppo;
+		LIBCFS_CPT_ALLOC(pmr->pmr_ipb, lnet_cpt_table(), ps->ps_cpt,
+				 IBLND_MAX_RDMA_FRAGS * sizeof(*pmr->pmr_ipb));
+		if (pmr->pmr_ipb == NULL)
+			break;
+
+		list_add(&pmr->pmr_list, &pool->po_free_list);
+	}
+
+	if (i < size) {
+		ps->ps_pool_destroy(pool);
+		return -ENOMEM;
+	}
+
+	ppo->ppo_hdev = kiblnd_current_hdev(ps->ps_net->ibn_dev);
+	*pp_po = pool;
+	return 0;
+}
+
+static void
+kiblnd_destroy_tx_pool(kib_pool_t *pool)
+{
+	kib_tx_pool_t  *tpo = container_of(pool, kib_tx_pool_t, tpo_pool);
+	int	     i;
+
+	LASSERT (pool->po_allocated == 0);
+
+	if (tpo->tpo_tx_pages != NULL) {
+		kiblnd_unmap_tx_pool(tpo);
+		kiblnd_free_pages(tpo->tpo_tx_pages);
+	}
+
+	if (tpo->tpo_tx_descs == NULL)
+		goto out;
+
+	for (i = 0; i < pool->po_size; i++) {
+		kib_tx_t *tx = &tpo->tpo_tx_descs[i];
+
+		list_del(&tx->tx_list);
+		if (tx->tx_pages != NULL)
+			LIBCFS_FREE(tx->tx_pages,
+				    LNET_MAX_IOV *
+				    sizeof(*tx->tx_pages));
+		if (tx->tx_frags != NULL)
+			LIBCFS_FREE(tx->tx_frags,
+				    IBLND_MAX_RDMA_FRAGS *
+					    sizeof(*tx->tx_frags));
+		if (tx->tx_wrq != NULL)
+			LIBCFS_FREE(tx->tx_wrq,
+				    (1 + IBLND_MAX_RDMA_FRAGS) *
+				    sizeof(*tx->tx_wrq));
+		if (tx->tx_sge != NULL)
+			LIBCFS_FREE(tx->tx_sge,
+				    (1 + IBLND_MAX_RDMA_FRAGS) *
+				    sizeof(*tx->tx_sge));
+		if (tx->tx_rd != NULL)
+			LIBCFS_FREE(tx->tx_rd,
+				    offsetof(kib_rdma_desc_t,
+					     rd_frags[IBLND_MAX_RDMA_FRAGS]));
+	}
+
+	LIBCFS_FREE(tpo->tpo_tx_descs,
+		    pool->po_size * sizeof(kib_tx_t));
+out:
+	kiblnd_fini_pool(pool);
+	LIBCFS_FREE(tpo, sizeof(kib_tx_pool_t));
+}
+
+static int kiblnd_tx_pool_size(int ncpts)
+{
+	int ntx = *kiblnd_tunables.kib_ntx / ncpts;
+
+	return max(IBLND_TX_POOL, ntx);
+}
+
+static int
+kiblnd_create_tx_pool(kib_poolset_t *ps, int size, kib_pool_t **pp_po)
+{
+	int	    i;
+	int	    npg;
+	kib_pool_t    *pool;
+	kib_tx_pool_t *tpo;
+
+	LIBCFS_CPT_ALLOC(tpo, lnet_cpt_table(), ps->ps_cpt, sizeof(*tpo));
+	if (tpo == NULL) {
+		CERROR("Failed to allocate TX pool\n");
+		return -ENOMEM;
+	}
+
+	pool = &tpo->tpo_pool;
+	kiblnd_init_pool(ps, pool, size);
+	tpo->tpo_tx_descs = NULL;
+	tpo->tpo_tx_pages = NULL;
+
+	npg = (size * IBLND_MSG_SIZE + PAGE_SIZE - 1) / PAGE_SIZE;
+	if (kiblnd_alloc_pages(&tpo->tpo_tx_pages, ps->ps_cpt, npg) != 0) {
+		CERROR("Can't allocate tx pages: %d\n", npg);
+		LIBCFS_FREE(tpo, sizeof(kib_tx_pool_t));
+		return -ENOMEM;
+	}
+
+	LIBCFS_CPT_ALLOC(tpo->tpo_tx_descs, lnet_cpt_table(), ps->ps_cpt,
+			 size * sizeof(kib_tx_t));
+	if (tpo->tpo_tx_descs == NULL) {
+		CERROR("Can't allocate %d tx descriptors\n", size);
+		ps->ps_pool_destroy(pool);
+		return -ENOMEM;
+	}
+
+	memset(tpo->tpo_tx_descs, 0, size * sizeof(kib_tx_t));
+
+	for (i = 0; i < size; i++) {
+		kib_tx_t *tx = &tpo->tpo_tx_descs[i];
+
+		tx->tx_pool = tpo;
+		if (ps->ps_net->ibn_fmr_ps != NULL) {
+			LIBCFS_CPT_ALLOC(tx->tx_pages,
+					 lnet_cpt_table(), ps->ps_cpt,
+					 LNET_MAX_IOV * sizeof(*tx->tx_pages));
+			if (tx->tx_pages == NULL)
+				break;
+		}
+
+		LIBCFS_CPT_ALLOC(tx->tx_frags, lnet_cpt_table(), ps->ps_cpt,
+				 IBLND_MAX_RDMA_FRAGS * sizeof(*tx->tx_frags));
+		if (tx->tx_frags == NULL)
+			break;
+
+		sg_init_table(tx->tx_frags, IBLND_MAX_RDMA_FRAGS);
+
+		LIBCFS_CPT_ALLOC(tx->tx_wrq, lnet_cpt_table(), ps->ps_cpt,
+				 (1 + IBLND_MAX_RDMA_FRAGS) *
+				 sizeof(*tx->tx_wrq));
+		if (tx->tx_wrq == NULL)
+			break;
+
+		LIBCFS_CPT_ALLOC(tx->tx_sge, lnet_cpt_table(), ps->ps_cpt,
+				 (1 + IBLND_MAX_RDMA_FRAGS) *
+				 sizeof(*tx->tx_sge));
+		if (tx->tx_sge == NULL)
+			break;
+
+		LIBCFS_CPT_ALLOC(tx->tx_rd, lnet_cpt_table(), ps->ps_cpt,
+				 offsetof(kib_rdma_desc_t,
+					  rd_frags[IBLND_MAX_RDMA_FRAGS]));
+		if (tx->tx_rd == NULL)
+			break;
+	}
+
+	if (i == size) {
+		kiblnd_map_tx_pool(tpo);
+		*pp_po = pool;
+		return 0;
+	}
+
+	ps->ps_pool_destroy(pool);
+	return -ENOMEM;
+}
+
+static void
+kiblnd_tx_init(kib_pool_t *pool, struct list_head *node)
+{
+	kib_tx_poolset_t *tps = container_of(pool->po_owner, kib_tx_poolset_t,
+					     tps_poolset);
+	kib_tx_t	 *tx  = list_entry(node, kib_tx_t, tx_list);
+
+	tx->tx_cookie = tps->tps_next_tx_cookie ++;
+}
+
+void
+kiblnd_net_fini_pools(kib_net_t *net)
+{
+	int	i;
+
+	cfs_cpt_for_each(i, lnet_cpt_table()) {
+		kib_tx_poolset_t	*tps;
+		kib_fmr_poolset_t	*fps;
+		kib_pmr_poolset_t	*pps;
+
+		if (net->ibn_tx_ps != NULL) {
+			tps = net->ibn_tx_ps[i];
+			kiblnd_fini_poolset(&tps->tps_poolset);
+		}
+
+		if (net->ibn_fmr_ps != NULL) {
+			fps = net->ibn_fmr_ps[i];
+			kiblnd_fini_fmr_poolset(fps);
+		}
+
+		if (net->ibn_pmr_ps != NULL) {
+			pps = net->ibn_pmr_ps[i];
+			kiblnd_fini_poolset(&pps->pps_poolset);
+		}
+	}
+
+	if (net->ibn_tx_ps != NULL) {
+		cfs_percpt_free(net->ibn_tx_ps);
+		net->ibn_tx_ps = NULL;
+	}
+
+	if (net->ibn_fmr_ps != NULL) {
+		cfs_percpt_free(net->ibn_fmr_ps);
+		net->ibn_fmr_ps = NULL;
+	}
+
+	if (net->ibn_pmr_ps != NULL) {
+		cfs_percpt_free(net->ibn_pmr_ps);
+		net->ibn_pmr_ps = NULL;
+	}
+}
+
+int
+kiblnd_net_init_pools(kib_net_t *net, __u32 *cpts, int ncpts)
+{
+	unsigned long	flags;
+	int		cpt;
+	int		rc;
+	int		i;
+
+	read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+	if (*kiblnd_tunables.kib_map_on_demand == 0 &&
+	    net->ibn_dev->ibd_hdev->ibh_nmrs == 1) {
+		read_unlock_irqrestore(&kiblnd_data.kib_global_lock,
+					   flags);
+		goto create_tx_pool;
+	}
+
+	read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	if (*kiblnd_tunables.kib_fmr_pool_size <
+	    *kiblnd_tunables.kib_ntx / 4) {
+		CERROR("Can't set fmr pool size (%d) < ntx / 4(%d)\n",
+		       *kiblnd_tunables.kib_fmr_pool_size,
+		       *kiblnd_tunables.kib_ntx / 4);
+		rc = -EINVAL;
+		goto failed;
+	}
+
+	/* TX pool must be created later than FMR/PMR, see LU-2268
+	 * for details */
+	LASSERT(net->ibn_tx_ps == NULL);
+
+	/* premapping can fail if ibd_nmr > 1, so we always create
+	 * FMR/PMR pool and map-on-demand if premapping failed */
+
+	net->ibn_fmr_ps = cfs_percpt_alloc(lnet_cpt_table(),
+					   sizeof(kib_fmr_poolset_t));
+	if (net->ibn_fmr_ps == NULL) {
+		CERROR("Failed to allocate FMR pool array\n");
+		rc = -ENOMEM;
+		goto failed;
+	}
+
+	for (i = 0; i < ncpts; i++) {
+		cpt = (cpts == NULL) ? i : cpts[i];
+		rc = kiblnd_init_fmr_poolset(net->ibn_fmr_ps[cpt], cpt, net,
+					     kiblnd_fmr_pool_size(ncpts),
+					     kiblnd_fmr_flush_trigger(ncpts));
+		if (rc == -ENOSYS && i == 0) /* no FMR */
+			break; /* create PMR pool */
+
+		if (rc != 0) { /* a real error */
+			CERROR("Can't initialize FMR pool for CPT %d: %d\n",
+			       cpt, rc);
+			goto failed;
+		}
+	}
+
+	if (i > 0) {
+		LASSERT(i == ncpts);
+		goto create_tx_pool;
+	}
+
+	cfs_percpt_free(net->ibn_fmr_ps);
+	net->ibn_fmr_ps = NULL;
+
+	CWARN("Device does not support FMR, failing back to PMR\n");
+
+	if (*kiblnd_tunables.kib_pmr_pool_size <
+	    *kiblnd_tunables.kib_ntx / 4) {
+		CERROR("Can't set pmr pool size (%d) < ntx / 4(%d)\n",
+		       *kiblnd_tunables.kib_pmr_pool_size,
+		       *kiblnd_tunables.kib_ntx / 4);
+		rc = -EINVAL;
+		goto failed;
+	}
+
+	net->ibn_pmr_ps = cfs_percpt_alloc(lnet_cpt_table(),
+					   sizeof(kib_pmr_poolset_t));
+	if (net->ibn_pmr_ps == NULL) {
+		CERROR("Failed to allocate PMR pool array\n");
+		rc = -ENOMEM;
+		goto failed;
+	}
+
+	for (i = 0; i < ncpts; i++) {
+		cpt = (cpts == NULL) ? i : cpts[i];
+		rc = kiblnd_init_poolset(&net->ibn_pmr_ps[cpt]->pps_poolset,
+					 cpt, net, "PMR",
+					 kiblnd_pmr_pool_size(ncpts),
+					 kiblnd_create_pmr_pool,
+					 kiblnd_destroy_pmr_pool, NULL, NULL);
+		if (rc != 0) {
+			CERROR("Can't initialize PMR pool for CPT %d: %d\n",
+			       cpt, rc);
+			goto failed;
+		}
+	}
+
+ create_tx_pool:
+	net->ibn_tx_ps = cfs_percpt_alloc(lnet_cpt_table(),
+					  sizeof(kib_tx_poolset_t));
+	if (net->ibn_tx_ps == NULL) {
+		CERROR("Failed to allocate tx pool array\n");
+		rc = -ENOMEM;
+		goto failed;
+	}
+
+	for (i = 0; i < ncpts; i++) {
+		cpt = (cpts == NULL) ? i : cpts[i];
+		rc = kiblnd_init_poolset(&net->ibn_tx_ps[cpt]->tps_poolset,
+					 cpt, net, "TX",
+					 kiblnd_tx_pool_size(ncpts),
+					 kiblnd_create_tx_pool,
+					 kiblnd_destroy_tx_pool,
+					 kiblnd_tx_init, NULL);
+		if (rc != 0) {
+			CERROR("Can't initialize TX pool for CPT %d: %d\n",
+			       cpt, rc);
+			goto failed;
+		}
+	}
+
+	return 0;
+ failed:
+	kiblnd_net_fini_pools(net);
+	LASSERT(rc != 0);
+	return rc;
+}
+
+static int
+kiblnd_hdev_get_attr(kib_hca_dev_t *hdev)
+{
+	struct ib_device_attr *attr;
+	int		    rc;
+
+	/* It's safe to assume a HCA can handle a page size
+	 * matching that of the native system */
+	hdev->ibh_page_shift = PAGE_SHIFT;
+	hdev->ibh_page_size  = 1 << PAGE_SHIFT;
+	hdev->ibh_page_mask  = ~((__u64)hdev->ibh_page_size - 1);
+
+	LIBCFS_ALLOC(attr, sizeof(*attr));
+	if (attr == NULL) {
+		CERROR("Out of memory\n");
+		return -ENOMEM;
+	}
+
+	rc = ib_query_device(hdev->ibh_ibdev, attr);
+	if (rc == 0)
+		hdev->ibh_mr_size = attr->max_mr_size;
+
+	LIBCFS_FREE(attr, sizeof(*attr));
+
+	if (rc != 0) {
+		CERROR("Failed to query IB device: %d\n", rc);
+		return rc;
+	}
+
+	if (hdev->ibh_mr_size == ~0ULL) {
+		hdev->ibh_mr_shift = 64;
+		return 0;
+	}
+
+	for (hdev->ibh_mr_shift = 0;
+	     hdev->ibh_mr_shift < 64; hdev->ibh_mr_shift ++) {
+		if (hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) ||
+		    hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) - 1)
+			return 0;
+	}
+
+	CERROR("Invalid mr size: "LPX64"\n", hdev->ibh_mr_size);
+	return -EINVAL;
+}
+
+void
+kiblnd_hdev_cleanup_mrs(kib_hca_dev_t *hdev)
+{
+	int     i;
+
+	if (hdev->ibh_nmrs == 0 || hdev->ibh_mrs == NULL)
+		return;
+
+	for (i = 0; i < hdev->ibh_nmrs; i++) {
+		if (hdev->ibh_mrs[i] == NULL)
+			break;
+
+		ib_dereg_mr(hdev->ibh_mrs[i]);
+	}
+
+	LIBCFS_FREE(hdev->ibh_mrs, sizeof(*hdev->ibh_mrs) * hdev->ibh_nmrs);
+	hdev->ibh_mrs  = NULL;
+	hdev->ibh_nmrs = 0;
+}
+
+void
+kiblnd_hdev_destroy(kib_hca_dev_t *hdev)
+{
+	kiblnd_hdev_cleanup_mrs(hdev);
+
+	if (hdev->ibh_pd != NULL)
+		ib_dealloc_pd(hdev->ibh_pd);
+
+	if (hdev->ibh_cmid != NULL)
+		rdma_destroy_id(hdev->ibh_cmid);
+
+	LIBCFS_FREE(hdev, sizeof(*hdev));
+}
+
+int
+kiblnd_hdev_setup_mrs(kib_hca_dev_t *hdev)
+{
+	struct ib_mr *mr;
+	int	   i;
+	int	   rc;
+	__u64	 mm_size;
+	__u64	 mr_size;
+	int	   acflags = IB_ACCESS_LOCAL_WRITE |
+				IB_ACCESS_REMOTE_WRITE;
+
+	rc = kiblnd_hdev_get_attr(hdev);
+	if (rc != 0)
+		return rc;
+
+	if (hdev->ibh_mr_shift == 64) {
+		LIBCFS_ALLOC(hdev->ibh_mrs, 1 * sizeof(*hdev->ibh_mrs));
+		if (hdev->ibh_mrs == NULL) {
+			CERROR("Failed to allocate MRs table\n");
+			return -ENOMEM;
+		}
+
+		hdev->ibh_mrs[0] = NULL;
+		hdev->ibh_nmrs   = 1;
+
+		mr = ib_get_dma_mr(hdev->ibh_pd, acflags);
+		if (IS_ERR(mr)) {
+			CERROR("Failed ib_get_dma_mr : %ld\n", PTR_ERR(mr));
+			kiblnd_hdev_cleanup_mrs(hdev);
+			return PTR_ERR(mr);
+		}
+
+		hdev->ibh_mrs[0] = mr;
+
+		goto out;
+	}
+
+	mr_size = (1ULL << hdev->ibh_mr_shift);
+	mm_size = (unsigned long)high_memory - PAGE_OFFSET;
+
+	hdev->ibh_nmrs = (int)((mm_size + mr_size - 1) >> hdev->ibh_mr_shift);
+
+	if (hdev->ibh_mr_shift < 32 || hdev->ibh_nmrs > 1024) {
+		/* it's 4T..., assume we will re-code at that time */
+		CERROR("Can't support memory size: x"LPX64
+		       " with MR size: x"LPX64"\n", mm_size, mr_size);
+		return -EINVAL;
+	}
+
+	/* create an array of MRs to cover all memory */
+	LIBCFS_ALLOC(hdev->ibh_mrs, sizeof(*hdev->ibh_mrs) * hdev->ibh_nmrs);
+	if (hdev->ibh_mrs == NULL) {
+		CERROR("Failed to allocate MRs' table\n");
+		return -ENOMEM;
+	}
+
+	memset(hdev->ibh_mrs, 0, sizeof(*hdev->ibh_mrs) * hdev->ibh_nmrs);
+
+	for (i = 0; i < hdev->ibh_nmrs; i++) {
+		struct ib_phys_buf ipb;
+		__u64	      iova;
+
+		ipb.size = hdev->ibh_mr_size;
+		ipb.addr = i * mr_size;
+		iova     = ipb.addr;
+
+		mr = ib_reg_phys_mr(hdev->ibh_pd, &ipb, 1, acflags, &iova);
+		if (IS_ERR(mr)) {
+			CERROR("Failed ib_reg_phys_mr addr "LPX64
+			       " size "LPX64" : %ld\n",
+			       ipb.addr, ipb.size, PTR_ERR(mr));
+			kiblnd_hdev_cleanup_mrs(hdev);
+			return PTR_ERR(mr);
+		}
+
+		LASSERT (iova == ipb.addr);
+
+		hdev->ibh_mrs[i] = mr;
+	}
+
+out:
+	if (hdev->ibh_mr_size != ~0ULL || hdev->ibh_nmrs != 1)
+		LCONSOLE_INFO("Register global MR array, MR size: "
+			      LPX64", array size: %d\n",
+			      hdev->ibh_mr_size, hdev->ibh_nmrs);
+	return 0;
+}
+
+static int
+kiblnd_dummy_callback(struct rdma_cm_id *cmid, struct rdma_cm_event *event)
+{       /* DUMMY */
+	return 0;
+}
+
+static int
+kiblnd_dev_need_failover(kib_dev_t *dev)
+{
+	struct rdma_cm_id  *cmid;
+	struct sockaddr_in  srcaddr;
+	struct sockaddr_in  dstaddr;
+	int		 rc;
+
+	if (dev->ibd_hdev == NULL || /* initializing */
+	    dev->ibd_hdev->ibh_cmid == NULL || /* listener is dead */
+	    *kiblnd_tunables.kib_dev_failover > 1) /* debugging */
+		return 1;
+
+	/* XXX: it's UGLY, but I don't have better way to find
+	 * ib-bonding HCA failover because:
+	 *
+	 * a. no reliable CM event for HCA failover...
+	 * b. no OFED API to get ib_device for current net_device...
+	 *
+	 * We have only two choices at this point:
+	 *
+	 * a. rdma_bind_addr(), it will conflict with listener cmid
+	 * b. rdma_resolve_addr() to zero addr */
+	cmid = kiblnd_rdma_create_id(kiblnd_dummy_callback, dev, RDMA_PS_TCP,
+				     IB_QPT_RC);
+	if (IS_ERR(cmid)) {
+		rc = PTR_ERR(cmid);
+		CERROR("Failed to create cmid for failover: %d\n", rc);
+		return rc;
+	}
+
+	memset(&srcaddr, 0, sizeof(srcaddr));
+	srcaddr.sin_family      = AF_INET;
+	srcaddr.sin_addr.s_addr = (__force u32)htonl(dev->ibd_ifip);
+
+	memset(&dstaddr, 0, sizeof(dstaddr));
+	dstaddr.sin_family = AF_INET;
+	rc = rdma_resolve_addr(cmid, (struct sockaddr *)&srcaddr,
+			       (struct sockaddr *)&dstaddr, 1);
+	if (rc != 0 || cmid->device == NULL) {
+		CERROR("Failed to bind %s:%u.%u.%u.%u to device(%p): %d\n",
+		       dev->ibd_ifname, HIPQUAD(dev->ibd_ifip),
+		       cmid->device, rc);
+		rdma_destroy_id(cmid);
+		return rc;
+	}
+
+	if (dev->ibd_hdev->ibh_ibdev == cmid->device) {
+		/* don't need device failover */
+		rdma_destroy_id(cmid);
+		return 0;
+	}
+
+	return 1;
+}
+
+int
+kiblnd_dev_failover(kib_dev_t *dev)
+{
+	LIST_HEAD      (zombie_tpo);
+	LIST_HEAD      (zombie_ppo);
+	LIST_HEAD      (zombie_fpo);
+	struct rdma_cm_id  *cmid  = NULL;
+	kib_hca_dev_t      *hdev  = NULL;
+	kib_hca_dev_t      *old;
+	struct ib_pd       *pd;
+	kib_net_t	  *net;
+	struct sockaddr_in  addr;
+	unsigned long       flags;
+	int		 rc = 0;
+	int		    i;
+
+	LASSERT (*kiblnd_tunables.kib_dev_failover > 1 ||
+		 dev->ibd_can_failover ||
+		 dev->ibd_hdev == NULL);
+
+	rc = kiblnd_dev_need_failover(dev);
+	if (rc <= 0)
+		goto out;
+
+	if (dev->ibd_hdev != NULL &&
+	    dev->ibd_hdev->ibh_cmid != NULL) {
+		/* XXX it's not good to close old listener at here,
+		 * because we can fail to create new listener.
+		 * But we have to close it now, otherwise rdma_bind_addr
+		 * will return EADDRINUSE... How crap! */
+		write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+		cmid = dev->ibd_hdev->ibh_cmid;
+		/* make next schedule of kiblnd_dev_need_failover()
+		 * return 1 for me */
+		dev->ibd_hdev->ibh_cmid  = NULL;
+		write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+		rdma_destroy_id(cmid);
+	}
+
+	cmid = kiblnd_rdma_create_id(kiblnd_cm_callback, dev, RDMA_PS_TCP,
+				     IB_QPT_RC);
+	if (IS_ERR(cmid)) {
+		rc = PTR_ERR(cmid);
+		CERROR("Failed to create cmid for failover: %d\n", rc);
+		goto out;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sin_family      = AF_INET;
+	addr.sin_addr.s_addr = (__force u32)htonl(dev->ibd_ifip);
+	addr.sin_port	= htons(*kiblnd_tunables.kib_service);
+
+	/* Bind to failover device or port */
+	rc = rdma_bind_addr(cmid, (struct sockaddr *)&addr);
+	if (rc != 0 || cmid->device == NULL) {
+		CERROR("Failed to bind %s:%u.%u.%u.%u to device(%p): %d\n",
+		       dev->ibd_ifname, HIPQUAD(dev->ibd_ifip),
+		       cmid->device, rc);
+		rdma_destroy_id(cmid);
+		goto out;
+	}
+
+	LIBCFS_ALLOC(hdev, sizeof(*hdev));
+	if (hdev == NULL) {
+		CERROR("Failed to allocate kib_hca_dev\n");
+		rdma_destroy_id(cmid);
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	atomic_set(&hdev->ibh_ref, 1);
+	hdev->ibh_dev   = dev;
+	hdev->ibh_cmid  = cmid;
+	hdev->ibh_ibdev = cmid->device;
+
+	pd = ib_alloc_pd(cmid->device);
+	if (IS_ERR(pd)) {
+		rc = PTR_ERR(pd);
+		CERROR("Can't allocate PD: %d\n", rc);
+		goto out;
+	}
+
+	hdev->ibh_pd = pd;
+
+	rc = rdma_listen(cmid, 0);
+	if (rc != 0) {
+		CERROR("Can't start new listener: %d\n", rc);
+		goto out;
+	}
+
+	rc = kiblnd_hdev_setup_mrs(hdev);
+	if (rc != 0) {
+		CERROR("Can't setup device: %d\n", rc);
+		goto out;
+	}
+
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	old = dev->ibd_hdev;
+	dev->ibd_hdev = hdev; /* take over the refcount */
+	hdev = old;
+
+	list_for_each_entry(net, &dev->ibd_nets, ibn_list) {
+		cfs_cpt_for_each(i, lnet_cpt_table()) {
+			kiblnd_fail_poolset(&net->ibn_tx_ps[i]->tps_poolset,
+					    &zombie_tpo);
+
+			if (net->ibn_fmr_ps != NULL) {
+				kiblnd_fail_fmr_poolset(net->ibn_fmr_ps[i],
+							&zombie_fpo);
+
+			} else if (net->ibn_pmr_ps != NULL) {
+				kiblnd_fail_poolset(&net->ibn_pmr_ps[i]->
+						    pps_poolset, &zombie_ppo);
+			}
+		}
+	}
+
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+ out:
+	if (!list_empty(&zombie_tpo))
+		kiblnd_destroy_pool_list(&zombie_tpo);
+	if (!list_empty(&zombie_ppo))
+		kiblnd_destroy_pool_list(&zombie_ppo);
+	if (!list_empty(&zombie_fpo))
+		kiblnd_destroy_fmr_pool_list(&zombie_fpo);
+	if (hdev != NULL)
+		kiblnd_hdev_decref(hdev);
+
+	if (rc != 0)
+		dev->ibd_failed_failover++;
+	else
+		dev->ibd_failed_failover = 0;
+
+	return rc;
+}
+
+void
+kiblnd_destroy_dev (kib_dev_t *dev)
+{
+	LASSERT (dev->ibd_nnets == 0);
+	LASSERT (list_empty(&dev->ibd_nets));
+
+	list_del(&dev->ibd_fail_list);
+	list_del(&dev->ibd_list);
+
+	if (dev->ibd_hdev != NULL)
+		kiblnd_hdev_decref(dev->ibd_hdev);
+
+	LIBCFS_FREE(dev, sizeof(*dev));
+}
+
+kib_dev_t *
+kiblnd_create_dev(char *ifname)
+{
+	struct net_device *netdev;
+	kib_dev_t	 *dev;
+	__u32	      netmask;
+	__u32	      ip;
+	int		up;
+	int		rc;
+
+	rc = libcfs_ipif_query(ifname, &up, &ip, &netmask);
+	if (rc != 0) {
+		CERROR("Can't query IPoIB interface %s: %d\n",
+		       ifname, rc);
+		return NULL;
+	}
+
+	if (!up) {
+		CERROR("Can't query IPoIB interface %s: it's down\n", ifname);
+		return NULL;
+	}
+
+	LIBCFS_ALLOC(dev, sizeof(*dev));
+	if (dev == NULL)
+		return NULL;
+
+	memset(dev, 0, sizeof(*dev));
+	netdev = dev_get_by_name(&init_net, ifname);
+	if (netdev == NULL) {
+		dev->ibd_can_failover = 0;
+	} else {
+		dev->ibd_can_failover = !!(netdev->flags & IFF_MASTER);
+		dev_put(netdev);
+	}
+
+	INIT_LIST_HEAD(&dev->ibd_nets);
+	INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */
+	INIT_LIST_HEAD(&dev->ibd_fail_list);
+	dev->ibd_ifip = ip;
+	strcpy(&dev->ibd_ifname[0], ifname);
+
+	/* initialize the device */
+	rc = kiblnd_dev_failover(dev);
+	if (rc != 0) {
+		CERROR("Can't initialize device: %d\n", rc);
+		LIBCFS_FREE(dev, sizeof(*dev));
+		return NULL;
+	}
+
+	list_add_tail(&dev->ibd_list,
+			  &kiblnd_data.kib_devs);
+	return dev;
+}
+
+void
+kiblnd_base_shutdown(void)
+{
+	struct kib_sched_info	*sched;
+	int			i;
+
+	LASSERT (list_empty(&kiblnd_data.kib_devs));
+
+	CDEBUG(D_MALLOC, "before LND base cleanup: kmem %d\n",
+	       atomic_read(&libcfs_kmemory));
+
+	switch (kiblnd_data.kib_init) {
+	default:
+		LBUG();
+
+	case IBLND_INIT_ALL:
+	case IBLND_INIT_DATA:
+		LASSERT (kiblnd_data.kib_peers != NULL);
+		for (i = 0; i < kiblnd_data.kib_peer_hash_size; i++) {
+			LASSERT (list_empty(&kiblnd_data.kib_peers[i]));
+		}
+		LASSERT (list_empty(&kiblnd_data.kib_connd_zombies));
+		LASSERT (list_empty(&kiblnd_data.kib_connd_conns));
+
+		/* flag threads to terminate; wake and wait for them to die */
+		kiblnd_data.kib_shutdown = 1;
+
+		/* NB: we really want to stop scheduler threads net by net
+		 * instead of the whole module, this should be improved
+		 * with dynamic configuration LNet */
+		cfs_percpt_for_each(sched, i, kiblnd_data.kib_scheds)
+			wake_up_all(&sched->ibs_waitq);
+
+		wake_up_all(&kiblnd_data.kib_connd_waitq);
+		wake_up_all(&kiblnd_data.kib_failover_waitq);
+
+		i = 2;
+		while (atomic_read(&kiblnd_data.kib_nthreads) != 0) {
+			i++;
+			CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET, /* power of 2? */
+			       "Waiting for %d threads to terminate\n",
+			       atomic_read(&kiblnd_data.kib_nthreads));
+			cfs_pause(cfs_time_seconds(1));
+		}
+
+		/* fall through */
+
+	case IBLND_INIT_NOTHING:
+		break;
+	}
+
+	if (kiblnd_data.kib_peers != NULL) {
+		LIBCFS_FREE(kiblnd_data.kib_peers,
+			    sizeof(struct list_head) *
+			    kiblnd_data.kib_peer_hash_size);
+	}
+
+	if (kiblnd_data.kib_scheds != NULL)
+		cfs_percpt_free(kiblnd_data.kib_scheds);
+
+	CDEBUG(D_MALLOC, "after LND base cleanup: kmem %d\n",
+	       atomic_read(&libcfs_kmemory));
+
+	kiblnd_data.kib_init = IBLND_INIT_NOTHING;
+	module_put(THIS_MODULE);
+}
+
+void
+kiblnd_shutdown (lnet_ni_t *ni)
+{
+	kib_net_t	*net = ni->ni_data;
+	rwlock_t     *g_lock = &kiblnd_data.kib_global_lock;
+	int	       i;
+	unsigned long     flags;
+
+	LASSERT(kiblnd_data.kib_init == IBLND_INIT_ALL);
+
+	if (net == NULL)
+		goto out;
+
+	CDEBUG(D_MALLOC, "before LND net cleanup: kmem %d\n",
+	       atomic_read(&libcfs_kmemory));
+
+	write_lock_irqsave(g_lock, flags);
+	net->ibn_shutdown = 1;
+	write_unlock_irqrestore(g_lock, flags);
+
+	switch (net->ibn_init) {
+	default:
+		LBUG();
+
+	case IBLND_INIT_ALL:
+		/* nuke all existing peers within this net */
+		kiblnd_del_peer(ni, LNET_NID_ANY);
+
+		/* Wait for all peer state to clean up */
+		i = 2;
+		while (atomic_read(&net->ibn_npeers) != 0) {
+			i++;
+			CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET, /* 2**n? */
+			       "%s: waiting for %d peers to disconnect\n",
+			       libcfs_nid2str(ni->ni_nid),
+			       atomic_read(&net->ibn_npeers));
+			cfs_pause(cfs_time_seconds(1));
+		}
+
+		kiblnd_net_fini_pools(net);
+
+		write_lock_irqsave(g_lock, flags);
+		LASSERT(net->ibn_dev->ibd_nnets > 0);
+		net->ibn_dev->ibd_nnets--;
+		list_del(&net->ibn_list);
+		write_unlock_irqrestore(g_lock, flags);
+
+		/* fall through */
+
+	case IBLND_INIT_NOTHING:
+		LASSERT (atomic_read(&net->ibn_nconns) == 0);
+
+		if (net->ibn_dev != NULL &&
+		    net->ibn_dev->ibd_nnets == 0)
+			kiblnd_destroy_dev(net->ibn_dev);
+
+		break;
+	}
+
+	CDEBUG(D_MALLOC, "after LND net cleanup: kmem %d\n",
+	       atomic_read(&libcfs_kmemory));
+
+	net->ibn_init = IBLND_INIT_NOTHING;
+	ni->ni_data = NULL;
+
+	LIBCFS_FREE(net, sizeof(*net));
+
+out:
+	if (list_empty(&kiblnd_data.kib_devs))
+		kiblnd_base_shutdown();
+	return;
+}
+
+int
+kiblnd_base_startup(void)
+{
+	struct kib_sched_info	*sched;
+	int			rc;
+	int			i;
+
+	LASSERT (kiblnd_data.kib_init == IBLND_INIT_NOTHING);
+
+	try_module_get(THIS_MODULE);
+	memset(&kiblnd_data, 0, sizeof(kiblnd_data)); /* zero pointers, flags etc */
+
+	rwlock_init(&kiblnd_data.kib_global_lock);
+
+	INIT_LIST_HEAD(&kiblnd_data.kib_devs);
+	INIT_LIST_HEAD(&kiblnd_data.kib_failed_devs);
+
+	kiblnd_data.kib_peer_hash_size = IBLND_PEER_HASH_SIZE;
+	LIBCFS_ALLOC(kiblnd_data.kib_peers,
+		     sizeof(struct list_head) *
+			    kiblnd_data.kib_peer_hash_size);
+	if (kiblnd_data.kib_peers == NULL) {
+		goto failed;
+	}
+	for (i = 0; i < kiblnd_data.kib_peer_hash_size; i++)
+		INIT_LIST_HEAD(&kiblnd_data.kib_peers[i]);
+
+	spin_lock_init(&kiblnd_data.kib_connd_lock);
+	INIT_LIST_HEAD(&kiblnd_data.kib_connd_conns);
+	INIT_LIST_HEAD(&kiblnd_data.kib_connd_zombies);
+	init_waitqueue_head(&kiblnd_data.kib_connd_waitq);
+	init_waitqueue_head(&kiblnd_data.kib_failover_waitq);
+
+	kiblnd_data.kib_scheds = cfs_percpt_alloc(lnet_cpt_table(),
+						  sizeof(*sched));
+	if (kiblnd_data.kib_scheds == NULL)
+		goto failed;
+
+	cfs_percpt_for_each(sched, i, kiblnd_data.kib_scheds) {
+		int	nthrs;
+
+		spin_lock_init(&sched->ibs_lock);
+		INIT_LIST_HEAD(&sched->ibs_conns);
+		init_waitqueue_head(&sched->ibs_waitq);
+
+		nthrs = cfs_cpt_weight(lnet_cpt_table(), i);
+		if (*kiblnd_tunables.kib_nscheds > 0) {
+			nthrs = min(nthrs, *kiblnd_tunables.kib_nscheds);
+		} else {
+			/* max to half of CPUs, another half is reserved for
+			 * upper layer modules */
+			nthrs = min(max(IBLND_N_SCHED, nthrs >> 1), nthrs);
+		}
+
+		sched->ibs_nthreads_max = nthrs;
+		sched->ibs_cpt = i;
+	}
+
+	kiblnd_data.kib_error_qpa.qp_state = IB_QPS_ERR;
+
+	/* lists/ptrs/locks initialised */
+	kiblnd_data.kib_init = IBLND_INIT_DATA;
+	/*****************************************************/
+
+	rc = kiblnd_thread_start(kiblnd_connd, NULL, "kiblnd_connd");
+	if (rc != 0) {
+		CERROR("Can't spawn o2iblnd connd: %d\n", rc);
+		goto failed;
+	}
+
+	if (*kiblnd_tunables.kib_dev_failover != 0)
+		rc = kiblnd_thread_start(kiblnd_failover_thread, NULL,
+					 "kiblnd_failover");
+
+	if (rc != 0) {
+		CERROR("Can't spawn o2iblnd failover thread: %d\n", rc);
+		goto failed;
+	}
+
+	/* flag everything initialised */
+	kiblnd_data.kib_init = IBLND_INIT_ALL;
+	/*****************************************************/
+
+	return 0;
+
+ failed:
+	kiblnd_base_shutdown();
+	return -ENETDOWN;
+}
+
+int
+kiblnd_start_schedulers(struct kib_sched_info *sched)
+{
+	int	rc = 0;
+	int	nthrs;
+	int	i;
+
+	if (sched->ibs_nthreads == 0) {
+		if (*kiblnd_tunables.kib_nscheds > 0) {
+			nthrs = sched->ibs_nthreads_max;
+		} else {
+			nthrs = cfs_cpt_weight(lnet_cpt_table(),
+					       sched->ibs_cpt);
+			nthrs = min(max(IBLND_N_SCHED, nthrs >> 1), nthrs);
+			nthrs = min(IBLND_N_SCHED_HIGH, nthrs);
+		}
+	} else {
+		LASSERT(sched->ibs_nthreads <= sched->ibs_nthreads_max);
+		/* increase one thread if there is new interface */
+		nthrs = (sched->ibs_nthreads < sched->ibs_nthreads_max);
+	}
+
+	for (i = 0; i < nthrs; i++) {
+		long	id;
+		char	name[20];
+		id = KIB_THREAD_ID(sched->ibs_cpt, sched->ibs_nthreads + i);
+		snprintf(name, sizeof(name), "kiblnd_sd_%02ld_%02ld",
+			 KIB_THREAD_CPT(id), KIB_THREAD_TID(id));
+		rc = kiblnd_thread_start(kiblnd_scheduler, (void *)id, name);
+		if (rc == 0)
+			continue;
+
+		CERROR("Can't spawn thread %d for scheduler[%d]: %d\n",
+		       sched->ibs_cpt, sched->ibs_nthreads + i, rc);
+		break;
+	}
+
+	sched->ibs_nthreads += i;
+	return rc;
+}
+
+int
+kiblnd_dev_start_threads(kib_dev_t *dev, int newdev, __u32 *cpts, int ncpts)
+{
+	int	cpt;
+	int	rc;
+	int	i;
+
+	for (i = 0; i < ncpts; i++) {
+		struct kib_sched_info *sched;
+
+		cpt = (cpts == NULL) ? i : cpts[i];
+		sched = kiblnd_data.kib_scheds[cpt];
+
+		if (!newdev && sched->ibs_nthreads > 0)
+			continue;
+
+		rc = kiblnd_start_schedulers(kiblnd_data.kib_scheds[cpt]);
+		if (rc != 0) {
+			CERROR("Failed to start scheduler threads for %s\n",
+			       dev->ibd_ifname);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+kib_dev_t *
+kiblnd_dev_search(char *ifname)
+{
+	kib_dev_t	*alias = NULL;
+	kib_dev_t	*dev;
+	char		*colon;
+	char		*colon2;
+
+	colon = strchr(ifname, ':');
+	list_for_each_entry(dev, &kiblnd_data.kib_devs, ibd_list) {
+		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
+			return dev;
+
+		if (alias != NULL)
+			continue;
+
+		colon2 = strchr(dev->ibd_ifname, ':');
+		if (colon != NULL)
+			*colon = 0;
+		if (colon2 != NULL)
+			*colon2 = 0;
+
+		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
+			alias = dev;
+
+		if (colon != NULL)
+			*colon = ':';
+		if (colon2 != NULL)
+			*colon2 = ':';
+	}
+	return alias;
+}
+
+int
+kiblnd_startup (lnet_ni_t *ni)
+{
+	char		     *ifname;
+	kib_dev_t		*ibdev = NULL;
+	kib_net_t		*net;
+	struct timeval	    tv;
+	unsigned long	     flags;
+	int		       rc;
+	int			  newdev;
+
+	LASSERT (ni->ni_lnd == &the_o2iblnd);
+
+	if (kiblnd_data.kib_init == IBLND_INIT_NOTHING) {
+		rc = kiblnd_base_startup();
+		if (rc != 0)
+			return rc;
+	}
+
+	LIBCFS_ALLOC(net, sizeof(*net));
+	ni->ni_data = net;
+	if (net == NULL)
+		goto failed;
+
+	memset(net, 0, sizeof(*net));
+
+	do_gettimeofday(&tv);
+	net->ibn_incarnation = (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec;
+
+	ni->ni_peertimeout    = *kiblnd_tunables.kib_peertimeout;
+	ni->ni_maxtxcredits   = *kiblnd_tunables.kib_credits;
+	ni->ni_peertxcredits  = *kiblnd_tunables.kib_peertxcredits;
+	ni->ni_peerrtrcredits = *kiblnd_tunables.kib_peerrtrcredits;
+
+	if (ni->ni_interfaces[0] != NULL) {
+		/* Use the IPoIB interface specified in 'networks=' */
+
+		CLASSERT (LNET_MAX_INTERFACES > 1);
+		if (ni->ni_interfaces[1] != NULL) {
+			CERROR("Multiple interfaces not supported\n");
+			goto failed;
+		}
+
+		ifname = ni->ni_interfaces[0];
+	} else {
+		ifname = *kiblnd_tunables.kib_default_ipif;
+	}
+
+	if (strlen(ifname) >= sizeof(ibdev->ibd_ifname)) {
+		CERROR("IPoIB interface name too long: %s\n", ifname);
+		goto failed;
+	}
+
+	ibdev = kiblnd_dev_search(ifname);
+
+	newdev = ibdev == NULL;
+	/* hmm...create kib_dev even for alias */
+	if (ibdev == NULL || strcmp(&ibdev->ibd_ifname[0], ifname) != 0)
+		ibdev = kiblnd_create_dev(ifname);
+
+	if (ibdev == NULL)
+		goto failed;
+
+	net->ibn_dev = ibdev;
+	ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), ibdev->ibd_ifip);
+
+	rc = kiblnd_dev_start_threads(ibdev, newdev,
+				      ni->ni_cpts, ni->ni_ncpts);
+	if (rc != 0)
+		goto failed;
+
+	rc = kiblnd_net_init_pools(net, ni->ni_cpts, ni->ni_ncpts);
+	if (rc != 0) {
+		CERROR("Failed to initialize NI pools: %d\n", rc);
+		goto failed;
+	}
+
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+	ibdev->ibd_nnets++;
+	list_add_tail(&net->ibn_list, &ibdev->ibd_nets);
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	net->ibn_init = IBLND_INIT_ALL;
+
+	return 0;
+
+failed:
+	if (net->ibn_dev == NULL && ibdev != NULL)
+		kiblnd_destroy_dev(ibdev);
+
+	kiblnd_shutdown(ni);
+
+	CDEBUG(D_NET, "kiblnd_startup failed\n");
+	return -ENETDOWN;
+}
+
+void __exit
+kiblnd_module_fini (void)
+{
+	lnet_unregister_lnd(&the_o2iblnd);
+	kiblnd_tunables_fini();
+}
+
+int __init
+kiblnd_module_init (void)
+{
+	int    rc;
+
+	CLASSERT (sizeof(kib_msg_t) <= IBLND_MSG_SIZE);
+	CLASSERT (offsetof(kib_msg_t, ibm_u.get.ibgm_rd.rd_frags[IBLND_MAX_RDMA_FRAGS])
+		  <= IBLND_MSG_SIZE);
+	CLASSERT (offsetof(kib_msg_t, ibm_u.putack.ibpam_rd.rd_frags[IBLND_MAX_RDMA_FRAGS])
+		  <= IBLND_MSG_SIZE);
+
+	rc = kiblnd_tunables_init();
+	if (rc != 0)
+		return rc;
+
+	lnet_register_lnd(&the_o2iblnd);
+
+	return 0;
+}
+
+MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
+MODULE_DESCRIPTION("Kernel OpenIB gen2 LND v2.00");
+MODULE_LICENSE("GPL");
+
+module_init(kiblnd_module_init);
+module_exit(kiblnd_module_fini);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3529 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/klnds/o2iblnd/o2iblnd_cb.c
+ *
+ * Author: Eric Barton <eric@bartonsoftware.com>
+ */
+
+#include "o2iblnd.h"
+
+void
+kiblnd_tx_done (lnet_ni_t *ni, kib_tx_t *tx)
+{
+	lnet_msg_t *lntmsg[2];
+	kib_net_t  *net = ni->ni_data;
+	int	 rc;
+	int	 i;
+
+	LASSERT (net != NULL);
+	LASSERT (!in_interrupt());
+	LASSERT (!tx->tx_queued);	       /* mustn't be queued for sending */
+	LASSERT (tx->tx_sending == 0);	  /* mustn't be awaiting sent callback */
+	LASSERT (!tx->tx_waiting);	      /* mustn't be awaiting peer response */
+	LASSERT (tx->tx_pool != NULL);
+
+	kiblnd_unmap_tx(ni, tx);
+
+	/* tx may have up to 2 lnet msgs to finalise */
+	lntmsg[0] = tx->tx_lntmsg[0]; tx->tx_lntmsg[0] = NULL;
+	lntmsg[1] = tx->tx_lntmsg[1]; tx->tx_lntmsg[1] = NULL;
+	rc = tx->tx_status;
+
+	if (tx->tx_conn != NULL) {
+		LASSERT (ni == tx->tx_conn->ibc_peer->ibp_ni);
+
+		kiblnd_conn_decref(tx->tx_conn);
+		tx->tx_conn = NULL;
+	}
+
+	tx->tx_nwrq = 0;
+	tx->tx_status = 0;
+
+	kiblnd_pool_free_node(&tx->tx_pool->tpo_pool, &tx->tx_list);
+
+	/* delay finalize until my descs have been freed */
+	for (i = 0; i < 2; i++) {
+		if (lntmsg[i] == NULL)
+			continue;
+
+		lnet_finalize(ni, lntmsg[i], rc);
+	}
+}
+
+void
+kiblnd_txlist_done (lnet_ni_t *ni, struct list_head *txlist, int status)
+{
+	kib_tx_t *tx;
+
+	while (!list_empty (txlist)) {
+		tx = list_entry (txlist->next, kib_tx_t, tx_list);
+
+		list_del(&tx->tx_list);
+		/* complete now */
+		tx->tx_waiting = 0;
+		tx->tx_status = status;
+		kiblnd_tx_done(ni, tx);
+	}
+}
+
+kib_tx_t *
+kiblnd_get_idle_tx(lnet_ni_t *ni, lnet_nid_t target)
+{
+	kib_net_t		*net = (kib_net_t *)ni->ni_data;
+	struct list_head		*node;
+	kib_tx_t		*tx;
+	kib_tx_poolset_t	*tps;
+
+	tps = net->ibn_tx_ps[lnet_cpt_of_nid(target)];
+	node = kiblnd_pool_alloc_node(&tps->tps_poolset);
+	if (node == NULL)
+		return NULL;
+	tx = container_of(node, kib_tx_t, tx_list);
+
+	LASSERT (tx->tx_nwrq == 0);
+	LASSERT (!tx->tx_queued);
+	LASSERT (tx->tx_sending == 0);
+	LASSERT (!tx->tx_waiting);
+	LASSERT (tx->tx_status == 0);
+	LASSERT (tx->tx_conn == NULL);
+	LASSERT (tx->tx_lntmsg[0] == NULL);
+	LASSERT (tx->tx_lntmsg[1] == NULL);
+	LASSERT (tx->tx_u.pmr == NULL);
+	LASSERT (tx->tx_nfrags == 0);
+
+	return tx;
+}
+
+void
+kiblnd_drop_rx(kib_rx_t *rx)
+{
+	kib_conn_t		*conn	= rx->rx_conn;
+	struct kib_sched_info	*sched	= conn->ibc_sched;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&sched->ibs_lock, flags);
+	LASSERT(conn->ibc_nrx > 0);
+	conn->ibc_nrx--;
+	spin_unlock_irqrestore(&sched->ibs_lock, flags);
+
+	kiblnd_conn_decref(conn);
+}
+
+int
+kiblnd_post_rx (kib_rx_t *rx, int credit)
+{
+	kib_conn_t	 *conn = rx->rx_conn;
+	kib_net_t	  *net = conn->ibc_peer->ibp_ni->ni_data;
+	struct ib_recv_wr  *bad_wrq = NULL;
+	struct ib_mr       *mr;
+	int		 rc;
+
+	LASSERT (net != NULL);
+	LASSERT (!in_interrupt());
+	LASSERT (credit == IBLND_POSTRX_NO_CREDIT ||
+		 credit == IBLND_POSTRX_PEER_CREDIT ||
+		 credit == IBLND_POSTRX_RSRVD_CREDIT);
+
+	mr = kiblnd_find_dma_mr(conn->ibc_hdev, rx->rx_msgaddr, IBLND_MSG_SIZE);
+	LASSERT (mr != NULL);
+
+	rx->rx_sge.lkey   = mr->lkey;
+	rx->rx_sge.addr   = rx->rx_msgaddr;
+	rx->rx_sge.length = IBLND_MSG_SIZE;
+
+	rx->rx_wrq.next = NULL;
+	rx->rx_wrq.sg_list = &rx->rx_sge;
+	rx->rx_wrq.num_sge = 1;
+	rx->rx_wrq.wr_id = kiblnd_ptr2wreqid(rx, IBLND_WID_RX);
+
+	LASSERT (conn->ibc_state >= IBLND_CONN_INIT);
+	LASSERT (rx->rx_nob >= 0);	      /* not posted */
+
+	if (conn->ibc_state > IBLND_CONN_ESTABLISHED) {
+		kiblnd_drop_rx(rx);	     /* No more posts for this rx */
+		return 0;
+	}
+
+	rx->rx_nob = -1;			/* flag posted */
+
+	rc = ib_post_recv(conn->ibc_cmid->qp, &rx->rx_wrq, &bad_wrq);
+	if (rc != 0) {
+		CERROR("Can't post rx for %s: %d, bad_wrq: %p\n",
+		       libcfs_nid2str(conn->ibc_peer->ibp_nid), rc, bad_wrq);
+		rx->rx_nob = 0;
+	}
+
+	if (conn->ibc_state < IBLND_CONN_ESTABLISHED) /* Initial post */
+		return rc;
+
+	if (rc != 0) {
+		kiblnd_close_conn(conn, rc);
+		kiblnd_drop_rx(rx);	     /* No more posts for this rx */
+		return rc;
+	}
+
+	if (credit == IBLND_POSTRX_NO_CREDIT)
+		return 0;
+
+	spin_lock(&conn->ibc_lock);
+	if (credit == IBLND_POSTRX_PEER_CREDIT)
+		conn->ibc_outstanding_credits++;
+	else
+		conn->ibc_reserved_credits++;
+	spin_unlock(&conn->ibc_lock);
+
+	kiblnd_check_sends(conn);
+	return 0;
+}
+
+kib_tx_t *
+kiblnd_find_waiting_tx_locked(kib_conn_t *conn, int txtype, __u64 cookie)
+{
+	struct list_head   *tmp;
+
+	list_for_each(tmp, &conn->ibc_active_txs) {
+		kib_tx_t *tx = list_entry(tmp, kib_tx_t, tx_list);
+
+		LASSERT (!tx->tx_queued);
+		LASSERT (tx->tx_sending != 0 || tx->tx_waiting);
+
+		if (tx->tx_cookie != cookie)
+			continue;
+
+		if (tx->tx_waiting &&
+		    tx->tx_msg->ibm_type == txtype)
+			return tx;
+
+		CWARN("Bad completion: %swaiting, type %x (wanted %x)\n",
+		      tx->tx_waiting ? "" : "NOT ",
+		      tx->tx_msg->ibm_type, txtype);
+	}
+	return NULL;
+}
+
+void
+kiblnd_handle_completion(kib_conn_t *conn, int txtype, int status, __u64 cookie)
+{
+	kib_tx_t    *tx;
+	lnet_ni_t   *ni = conn->ibc_peer->ibp_ni;
+	int	  idle;
+
+	spin_lock(&conn->ibc_lock);
+
+	tx = kiblnd_find_waiting_tx_locked(conn, txtype, cookie);
+	if (tx == NULL) {
+		spin_unlock(&conn->ibc_lock);
+
+		CWARN("Unmatched completion type %x cookie "LPX64" from %s\n",
+		      txtype, cookie, libcfs_nid2str(conn->ibc_peer->ibp_nid));
+		kiblnd_close_conn(conn, -EPROTO);
+		return;
+	}
+
+	if (tx->tx_status == 0) {	       /* success so far */
+		if (status < 0) {	       /* failed? */
+			tx->tx_status = status;
+		} else if (txtype == IBLND_MSG_GET_REQ) {
+			lnet_set_reply_msg_len(ni, tx->tx_lntmsg[1], status);
+		}
+	}
+
+	tx->tx_waiting = 0;
+
+	idle = !tx->tx_queued && (tx->tx_sending == 0);
+	if (idle)
+		list_del(&tx->tx_list);
+
+	spin_unlock(&conn->ibc_lock);
+
+	if (idle)
+		kiblnd_tx_done(ni, tx);
+}
+
+void
+kiblnd_send_completion(kib_conn_t *conn, int type, int status, __u64 cookie)
+{
+	lnet_ni_t   *ni = conn->ibc_peer->ibp_ni;
+	kib_tx_t    *tx = kiblnd_get_idle_tx(ni, conn->ibc_peer->ibp_nid);
+
+	if (tx == NULL) {
+		CERROR("Can't get tx for completion %x for %s\n",
+		       type, libcfs_nid2str(conn->ibc_peer->ibp_nid));
+		return;
+	}
+
+	tx->tx_msg->ibm_u.completion.ibcm_status = status;
+	tx->tx_msg->ibm_u.completion.ibcm_cookie = cookie;
+	kiblnd_init_tx_msg(ni, tx, type, sizeof(kib_completion_msg_t));
+
+	kiblnd_queue_tx(tx, conn);
+}
+
+void
+kiblnd_handle_rx (kib_rx_t *rx)
+{
+	kib_msg_t    *msg = rx->rx_msg;
+	kib_conn_t   *conn = rx->rx_conn;
+	lnet_ni_t    *ni = conn->ibc_peer->ibp_ni;
+	int	   credits = msg->ibm_credits;
+	kib_tx_t     *tx;
+	int	   rc = 0;
+	int	   rc2;
+	int	   post_credit;
+
+	LASSERT (conn->ibc_state >= IBLND_CONN_ESTABLISHED);
+
+	CDEBUG (D_NET, "Received %x[%d] from %s\n",
+		msg->ibm_type, credits,
+		libcfs_nid2str(conn->ibc_peer->ibp_nid));
+
+	if (credits != 0) {
+		/* Have I received credits that will let me send? */
+		spin_lock(&conn->ibc_lock);
+
+		if (conn->ibc_credits + credits >
+		    IBLND_MSG_QUEUE_SIZE(conn->ibc_version)) {
+			rc2 = conn->ibc_credits;
+			spin_unlock(&conn->ibc_lock);
+
+			CERROR("Bad credits from %s: %d + %d > %d\n",
+			       libcfs_nid2str(conn->ibc_peer->ibp_nid),
+			       rc2, credits,
+			       IBLND_MSG_QUEUE_SIZE(conn->ibc_version));
+
+			kiblnd_close_conn(conn, -EPROTO);
+			kiblnd_post_rx(rx, IBLND_POSTRX_NO_CREDIT);
+			return;
+		}
+
+		conn->ibc_credits += credits;
+
+		/* This ensures the credit taken by NOOP can be returned */
+		if (msg->ibm_type == IBLND_MSG_NOOP &&
+		    !IBLND_OOB_CAPABLE(conn->ibc_version)) /* v1 only */
+			conn->ibc_outstanding_credits++;
+
+		spin_unlock(&conn->ibc_lock);
+		kiblnd_check_sends(conn);
+	}
+
+	switch (msg->ibm_type) {
+	default:
+		CERROR("Bad IBLND message type %x from %s\n",
+		       msg->ibm_type, libcfs_nid2str(conn->ibc_peer->ibp_nid));
+		post_credit = IBLND_POSTRX_NO_CREDIT;
+		rc = -EPROTO;
+		break;
+
+	case IBLND_MSG_NOOP:
+		if (IBLND_OOB_CAPABLE(conn->ibc_version)) {
+			post_credit = IBLND_POSTRX_NO_CREDIT;
+			break;
+		}
+
+		if (credits != 0) /* credit already posted */
+			post_credit = IBLND_POSTRX_NO_CREDIT;
+		else	      /* a keepalive NOOP */
+			post_credit = IBLND_POSTRX_PEER_CREDIT;
+		break;
+
+	case IBLND_MSG_IMMEDIATE:
+		post_credit = IBLND_POSTRX_DONT_POST;
+		rc = lnet_parse(ni, &msg->ibm_u.immediate.ibim_hdr,
+				msg->ibm_srcnid, rx, 0);
+		if (rc < 0)		     /* repost on error */
+			post_credit = IBLND_POSTRX_PEER_CREDIT;
+		break;
+
+	case IBLND_MSG_PUT_REQ:
+		post_credit = IBLND_POSTRX_DONT_POST;
+		rc = lnet_parse(ni, &msg->ibm_u.putreq.ibprm_hdr,
+				msg->ibm_srcnid, rx, 1);
+		if (rc < 0)		     /* repost on error */
+			post_credit = IBLND_POSTRX_PEER_CREDIT;
+		break;
+
+	case IBLND_MSG_PUT_NAK:
+		CWARN ("PUT_NACK from %s\n",
+		       libcfs_nid2str(conn->ibc_peer->ibp_nid));
+		post_credit = IBLND_POSTRX_RSRVD_CREDIT;
+		kiblnd_handle_completion(conn, IBLND_MSG_PUT_REQ,
+					 msg->ibm_u.completion.ibcm_status,
+					 msg->ibm_u.completion.ibcm_cookie);
+		break;
+
+	case IBLND_MSG_PUT_ACK:
+		post_credit = IBLND_POSTRX_RSRVD_CREDIT;
+
+		spin_lock(&conn->ibc_lock);
+		tx = kiblnd_find_waiting_tx_locked(conn, IBLND_MSG_PUT_REQ,
+					msg->ibm_u.putack.ibpam_src_cookie);
+		if (tx != NULL)
+			list_del(&tx->tx_list);
+		spin_unlock(&conn->ibc_lock);
+
+		if (tx == NULL) {
+			CERROR("Unmatched PUT_ACK from %s\n",
+			       libcfs_nid2str(conn->ibc_peer->ibp_nid));
+			rc = -EPROTO;
+			break;
+		}
+
+		LASSERT (tx->tx_waiting);
+		/* CAVEAT EMPTOR: I could be racing with tx_complete, but...
+		 * (a) I can overwrite tx_msg since my peer has received it!
+		 * (b) tx_waiting set tells tx_complete() it's not done. */
+
+		tx->tx_nwrq = 0;		/* overwrite PUT_REQ */
+
+		rc2 = kiblnd_init_rdma(conn, tx, IBLND_MSG_PUT_DONE,
+				       kiblnd_rd_size(&msg->ibm_u.putack.ibpam_rd),
+				       &msg->ibm_u.putack.ibpam_rd,
+				       msg->ibm_u.putack.ibpam_dst_cookie);
+		if (rc2 < 0)
+			CERROR("Can't setup rdma for PUT to %s: %d\n",
+			       libcfs_nid2str(conn->ibc_peer->ibp_nid), rc2);
+
+		spin_lock(&conn->ibc_lock);
+		tx->tx_waiting = 0;	/* clear waiting and queue atomically */
+		kiblnd_queue_tx_locked(tx, conn);
+		spin_unlock(&conn->ibc_lock);
+		break;
+
+	case IBLND_MSG_PUT_DONE:
+		post_credit = IBLND_POSTRX_PEER_CREDIT;
+		kiblnd_handle_completion(conn, IBLND_MSG_PUT_ACK,
+					 msg->ibm_u.completion.ibcm_status,
+					 msg->ibm_u.completion.ibcm_cookie);
+		break;
+
+	case IBLND_MSG_GET_REQ:
+		post_credit = IBLND_POSTRX_DONT_POST;
+		rc = lnet_parse(ni, &msg->ibm_u.get.ibgm_hdr,
+				msg->ibm_srcnid, rx, 1);
+		if (rc < 0)		     /* repost on error */
+			post_credit = IBLND_POSTRX_PEER_CREDIT;
+		break;
+
+	case IBLND_MSG_GET_DONE:
+		post_credit = IBLND_POSTRX_RSRVD_CREDIT;
+		kiblnd_handle_completion(conn, IBLND_MSG_GET_REQ,
+					 msg->ibm_u.completion.ibcm_status,
+					 msg->ibm_u.completion.ibcm_cookie);
+		break;
+	}
+
+	if (rc < 0)			     /* protocol error */
+		kiblnd_close_conn(conn, rc);
+
+	if (post_credit != IBLND_POSTRX_DONT_POST)
+		kiblnd_post_rx(rx, post_credit);
+}
+
+void
+kiblnd_rx_complete (kib_rx_t *rx, int status, int nob)
+{
+	kib_msg_t    *msg = rx->rx_msg;
+	kib_conn_t   *conn = rx->rx_conn;
+	lnet_ni_t    *ni = conn->ibc_peer->ibp_ni;
+	kib_net_t    *net = ni->ni_data;
+	int	   rc;
+	int	   err = -EIO;
+
+	LASSERT (net != NULL);
+	LASSERT (rx->rx_nob < 0);	       /* was posted */
+	rx->rx_nob = 0;			 /* isn't now */
+
+	if (conn->ibc_state > IBLND_CONN_ESTABLISHED)
+		goto ignore;
+
+	if (status != IB_WC_SUCCESS) {
+		CNETERR("Rx from %s failed: %d\n",
+			libcfs_nid2str(conn->ibc_peer->ibp_nid), status);
+		goto failed;
+	}
+
+	LASSERT (nob >= 0);
+	rx->rx_nob = nob;
+
+	rc = kiblnd_unpack_msg(msg, rx->rx_nob);
+	if (rc != 0) {
+		CERROR ("Error %d unpacking rx from %s\n",
+			rc, libcfs_nid2str(conn->ibc_peer->ibp_nid));
+		goto failed;
+	}
+
+	if (msg->ibm_srcnid != conn->ibc_peer->ibp_nid ||
+	    msg->ibm_dstnid != ni->ni_nid ||
+	    msg->ibm_srcstamp != conn->ibc_incarnation ||
+	    msg->ibm_dststamp != net->ibn_incarnation) {
+		CERROR ("Stale rx from %s\n",
+			libcfs_nid2str(conn->ibc_peer->ibp_nid));
+		err = -ESTALE;
+		goto failed;
+	}
+
+	/* set time last known alive */
+	kiblnd_peer_alive(conn->ibc_peer);
+
+	/* racing with connection establishment/teardown! */
+
+	if (conn->ibc_state < IBLND_CONN_ESTABLISHED) {
+		rwlock_t  *g_lock = &kiblnd_data.kib_global_lock;
+		unsigned long  flags;
+
+		write_lock_irqsave(g_lock, flags);
+		/* must check holding global lock to eliminate race */
+		if (conn->ibc_state < IBLND_CONN_ESTABLISHED) {
+			list_add_tail(&rx->rx_list, &conn->ibc_early_rxs);
+			write_unlock_irqrestore(g_lock, flags);
+			return;
+		}
+		write_unlock_irqrestore(g_lock, flags);
+	}
+	kiblnd_handle_rx(rx);
+	return;
+
+ failed:
+	CDEBUG(D_NET, "rx %p conn %p\n", rx, conn);
+	kiblnd_close_conn(conn, err);
+ ignore:
+	kiblnd_drop_rx(rx);		     /* Don't re-post rx. */
+}
+
+struct page *
+kiblnd_kvaddr_to_page (unsigned long vaddr)
+{
+	struct page *page;
+
+	if (vaddr >= VMALLOC_START &&
+	    vaddr < VMALLOC_END) {
+		page = vmalloc_to_page ((void *)vaddr);
+		LASSERT (page != NULL);
+		return page;
+	}
+#ifdef CONFIG_HIGHMEM
+	if (vaddr >= PKMAP_BASE &&
+	    vaddr < (PKMAP_BASE + LAST_PKMAP * PAGE_SIZE)) {
+		/* No highmem pages only used for bulk (kiov) I/O */
+		CERROR("find page for address in highmem\n");
+		LBUG();
+	}
+#endif
+	page = virt_to_page (vaddr);
+	LASSERT (page != NULL);
+	return page;
+}
+
+static int
+kiblnd_fmr_map_tx(kib_net_t *net, kib_tx_t *tx, kib_rdma_desc_t *rd, int nob)
+{
+	kib_hca_dev_t		*hdev;
+	__u64			*pages = tx->tx_pages;
+	kib_fmr_poolset_t	*fps;
+	int			npages;
+	int			size;
+	int			cpt;
+	int			rc;
+	int			i;
+
+	LASSERT(tx->tx_pool != NULL);
+	LASSERT(tx->tx_pool->tpo_pool.po_owner != NULL);
+
+	hdev  = tx->tx_pool->tpo_hdev;
+
+	for (i = 0, npages = 0; i < rd->rd_nfrags; i++) {
+		for (size = 0; size <  rd->rd_frags[i].rf_nob;
+			       size += hdev->ibh_page_size) {
+			pages[npages ++] = (rd->rd_frags[i].rf_addr &
+					    hdev->ibh_page_mask) + size;
+		}
+	}
+
+	cpt = tx->tx_pool->tpo_pool.po_owner->ps_cpt;
+
+	fps = net->ibn_fmr_ps[cpt];
+	rc = kiblnd_fmr_pool_map(fps, pages, npages, 0, &tx->tx_u.fmr);
+	if (rc != 0) {
+		CERROR ("Can't map %d pages: %d\n", npages, rc);
+		return rc;
+	}
+
+	/* If rd is not tx_rd, it's going to get sent to a peer, who will need
+	 * the rkey */
+	rd->rd_key = (rd != tx->tx_rd) ? tx->tx_u.fmr.fmr_pfmr->fmr->rkey :
+					 tx->tx_u.fmr.fmr_pfmr->fmr->lkey;
+	rd->rd_frags[0].rf_addr &= ~hdev->ibh_page_mask;
+	rd->rd_frags[0].rf_nob   = nob;
+	rd->rd_nfrags = 1;
+
+	return 0;
+}
+
+static int
+kiblnd_pmr_map_tx(kib_net_t *net, kib_tx_t *tx, kib_rdma_desc_t *rd, int nob)
+{
+	kib_hca_dev_t		*hdev;
+	kib_pmr_poolset_t	*pps;
+	__u64			iova;
+	int			cpt;
+	int			rc;
+
+	LASSERT(tx->tx_pool != NULL);
+	LASSERT(tx->tx_pool->tpo_pool.po_owner != NULL);
+
+	hdev = tx->tx_pool->tpo_hdev;
+
+	iova = rd->rd_frags[0].rf_addr & ~hdev->ibh_page_mask;
+
+	cpt = tx->tx_pool->tpo_pool.po_owner->ps_cpt;
+
+	pps = net->ibn_pmr_ps[cpt];
+	rc = kiblnd_pmr_pool_map(pps, hdev, rd, &iova, &tx->tx_u.pmr);
+	if (rc != 0) {
+		CERROR("Failed to create MR by phybuf: %d\n", rc);
+		return rc;
+	}
+
+	/* If rd is not tx_rd, it's going to get sent to a peer, who will need
+	 * the rkey */
+	rd->rd_key = (rd != tx->tx_rd) ? tx->tx_u.pmr->pmr_mr->rkey :
+					 tx->tx_u.pmr->pmr_mr->lkey;
+	rd->rd_nfrags = 1;
+	rd->rd_frags[0].rf_addr = iova;
+	rd->rd_frags[0].rf_nob  = nob;
+
+	return 0;
+}
+
+void
+kiblnd_unmap_tx(lnet_ni_t *ni, kib_tx_t *tx)
+{
+	kib_net_t  *net = ni->ni_data;
+
+	LASSERT(net != NULL);
+
+	if (net->ibn_fmr_ps != NULL && tx->tx_u.fmr.fmr_pfmr != NULL) {
+		kiblnd_fmr_pool_unmap(&tx->tx_u.fmr, tx->tx_status);
+		tx->tx_u.fmr.fmr_pfmr = NULL;
+
+	} else if (net->ibn_pmr_ps != NULL && tx->tx_u.pmr != NULL) {
+		kiblnd_pmr_pool_unmap(tx->tx_u.pmr);
+		tx->tx_u.pmr = NULL;
+	}
+
+	if (tx->tx_nfrags != 0) {
+		kiblnd_dma_unmap_sg(tx->tx_pool->tpo_hdev->ibh_ibdev,
+				    tx->tx_frags, tx->tx_nfrags, tx->tx_dmadir);
+		tx->tx_nfrags = 0;
+	}
+}
+
+int
+kiblnd_map_tx(lnet_ni_t *ni, kib_tx_t *tx,
+	      kib_rdma_desc_t *rd, int nfrags)
+{
+	kib_hca_dev_t      *hdev  = tx->tx_pool->tpo_hdev;
+	kib_net_t	  *net   = ni->ni_data;
+	struct ib_mr       *mr    = NULL;
+	__u32	       nob;
+	int		 i;
+
+	/* If rd is not tx_rd, it's going to get sent to a peer and I'm the
+	 * RDMA sink */
+	tx->tx_dmadir = (rd != tx->tx_rd) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+	tx->tx_nfrags = nfrags;
+
+	rd->rd_nfrags =
+		kiblnd_dma_map_sg(hdev->ibh_ibdev,
+				  tx->tx_frags, tx->tx_nfrags, tx->tx_dmadir);
+
+	for (i = 0, nob = 0; i < rd->rd_nfrags; i++) {
+		rd->rd_frags[i].rf_nob  = kiblnd_sg_dma_len(
+			hdev->ibh_ibdev, &tx->tx_frags[i]);
+		rd->rd_frags[i].rf_addr = kiblnd_sg_dma_address(
+			hdev->ibh_ibdev, &tx->tx_frags[i]);
+		nob += rd->rd_frags[i].rf_nob;
+	}
+
+	/* looking for pre-mapping MR */
+	mr = kiblnd_find_rd_dma_mr(hdev, rd);
+	if (mr != NULL) {
+		/* found pre-mapping MR */
+		rd->rd_key = (rd != tx->tx_rd) ? mr->rkey : mr->lkey;
+		return 0;
+	}
+
+	if (net->ibn_fmr_ps != NULL)
+		return kiblnd_fmr_map_tx(net, tx, rd, nob);
+	else if (net->ibn_pmr_ps != NULL)
+		return kiblnd_pmr_map_tx(net, tx, rd, nob);
+
+	return -EINVAL;
+}
+
+
+int
+kiblnd_setup_rd_iov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
+		    unsigned int niov, struct iovec *iov, int offset, int nob)
+{
+	kib_net_t	  *net = ni->ni_data;
+	struct page	*page;
+	struct scatterlist *sg;
+	unsigned long       vaddr;
+	int		 fragnob;
+	int		 page_offset;
+
+	LASSERT (nob > 0);
+	LASSERT (niov > 0);
+	LASSERT (net != NULL);
+
+	while (offset >= iov->iov_len) {
+		offset -= iov->iov_len;
+		niov--;
+		iov++;
+		LASSERT (niov > 0);
+	}
+
+	sg = tx->tx_frags;
+	do {
+		LASSERT (niov > 0);
+
+		vaddr = ((unsigned long)iov->iov_base) + offset;
+		page_offset = vaddr & (PAGE_SIZE - 1);
+		page = kiblnd_kvaddr_to_page(vaddr);
+		if (page == NULL) {
+			CERROR ("Can't find page\n");
+			return -EFAULT;
+		}
+
+		fragnob = min((int)(iov->iov_len - offset), nob);
+		fragnob = min(fragnob, (int)PAGE_SIZE - page_offset);
+
+		sg_set_page(sg, page, fragnob, page_offset);
+		sg++;
+
+		if (offset + fragnob < iov->iov_len) {
+			offset += fragnob;
+		} else {
+			offset = 0;
+			iov++;
+			niov--;
+		}
+		nob -= fragnob;
+	} while (nob > 0);
+
+	return kiblnd_map_tx(ni, tx, rd, sg - tx->tx_frags);
+}
+
+int
+kiblnd_setup_rd_kiov (lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
+		      int nkiov, lnet_kiov_t *kiov, int offset, int nob)
+{
+	kib_net_t	  *net = ni->ni_data;
+	struct scatterlist *sg;
+	int		 fragnob;
+
+	CDEBUG(D_NET, "niov %d offset %d nob %d\n", nkiov, offset, nob);
+
+	LASSERT (nob > 0);
+	LASSERT (nkiov > 0);
+	LASSERT (net != NULL);
+
+	while (offset >= kiov->kiov_len) {
+		offset -= kiov->kiov_len;
+		nkiov--;
+		kiov++;
+		LASSERT (nkiov > 0);
+	}
+
+	sg = tx->tx_frags;
+	do {
+		LASSERT (nkiov > 0);
+
+		fragnob = min((int)(kiov->kiov_len - offset), nob);
+
+		sg_set_page(sg, kiov->kiov_page, fragnob,
+			    kiov->kiov_offset + offset);
+		sg++;
+
+		offset = 0;
+		kiov++;
+		nkiov--;
+		nob -= fragnob;
+	} while (nob > 0);
+
+	return kiblnd_map_tx(ni, tx, rd, sg - tx->tx_frags);
+}
+
+int
+kiblnd_post_tx_locked (kib_conn_t *conn, kib_tx_t *tx, int credit)
+{
+	kib_msg_t	 *msg = tx->tx_msg;
+	kib_peer_t	*peer = conn->ibc_peer;
+	int		ver = conn->ibc_version;
+	int		rc;
+	int		done;
+	struct ib_send_wr *bad_wrq;
+
+	LASSERT (tx->tx_queued);
+	/* We rely on this for QP sizing */
+	LASSERT (tx->tx_nwrq > 0);
+	LASSERT (tx->tx_nwrq <= 1 + IBLND_RDMA_FRAGS(ver));
+
+	LASSERT (credit == 0 || credit == 1);
+	LASSERT (conn->ibc_outstanding_credits >= 0);
+	LASSERT (conn->ibc_outstanding_credits <= IBLND_MSG_QUEUE_SIZE(ver));
+	LASSERT (conn->ibc_credits >= 0);
+	LASSERT (conn->ibc_credits <= IBLND_MSG_QUEUE_SIZE(ver));
+
+	if (conn->ibc_nsends_posted == IBLND_CONCURRENT_SENDS(ver)) {
+		/* tx completions outstanding... */
+		CDEBUG(D_NET, "%s: posted enough\n",
+		       libcfs_nid2str(peer->ibp_nid));
+		return -EAGAIN;
+	}
+
+	if (credit != 0 && conn->ibc_credits == 0) {   /* no credits */
+		CDEBUG(D_NET, "%s: no credits\n",
+		       libcfs_nid2str(peer->ibp_nid));
+		return -EAGAIN;
+	}
+
+	if (credit != 0 && !IBLND_OOB_CAPABLE(ver) &&
+	    conn->ibc_credits == 1 &&   /* last credit reserved */
+	    msg->ibm_type != IBLND_MSG_NOOP) {      /* for NOOP */
+		CDEBUG(D_NET, "%s: not using last credit\n",
+		       libcfs_nid2str(peer->ibp_nid));
+		return -EAGAIN;
+	}
+
+	/* NB don't drop ibc_lock before bumping tx_sending */
+	list_del(&tx->tx_list);
+	tx->tx_queued = 0;
+
+	if (msg->ibm_type == IBLND_MSG_NOOP &&
+	    (!kiblnd_need_noop(conn) ||     /* redundant NOOP */
+	     (IBLND_OOB_CAPABLE(ver) && /* posted enough NOOP */
+	      conn->ibc_noops_posted == IBLND_OOB_MSGS(ver)))) {
+		/* OK to drop when posted enough NOOPs, since
+		 * kiblnd_check_sends will queue NOOP again when
+		 * posted NOOPs complete */
+		spin_unlock(&conn->ibc_lock);
+		kiblnd_tx_done(peer->ibp_ni, tx);
+		spin_lock(&conn->ibc_lock);
+		CDEBUG(D_NET, "%s(%d): redundant or enough NOOP\n",
+		       libcfs_nid2str(peer->ibp_nid),
+		       conn->ibc_noops_posted);
+		return 0;
+	}
+
+	kiblnd_pack_msg(peer->ibp_ni, msg, ver, conn->ibc_outstanding_credits,
+			peer->ibp_nid, conn->ibc_incarnation);
+
+	conn->ibc_credits -= credit;
+	conn->ibc_outstanding_credits = 0;
+	conn->ibc_nsends_posted++;
+	if (msg->ibm_type == IBLND_MSG_NOOP)
+		conn->ibc_noops_posted++;
+
+	/* CAVEAT EMPTOR!  This tx could be the PUT_DONE of an RDMA
+	 * PUT.  If so, it was first queued here as a PUT_REQ, sent and
+	 * stashed on ibc_active_txs, matched by an incoming PUT_ACK,
+	 * and then re-queued here.  It's (just) possible that
+	 * tx_sending is non-zero if we've not done the tx_complete()
+	 * from the first send; hence the ++ rather than = below. */
+	tx->tx_sending++;
+	list_add(&tx->tx_list, &conn->ibc_active_txs);
+
+	/* I'm still holding ibc_lock! */
+	if (conn->ibc_state != IBLND_CONN_ESTABLISHED) {
+		rc = -ECONNABORTED;
+	} else if (tx->tx_pool->tpo_pool.po_failed ||
+		 conn->ibc_hdev != tx->tx_pool->tpo_hdev) {
+		/* close_conn will launch failover */
+		rc = -ENETDOWN;
+	} else {
+		rc = ib_post_send(conn->ibc_cmid->qp,
+				  tx->tx_wrq, &bad_wrq);
+	}
+
+	conn->ibc_last_send = jiffies;
+
+	if (rc == 0)
+		return 0;
+
+	/* NB credits are transferred in the actual
+	 * message, which can only be the last work item */
+	conn->ibc_credits += credit;
+	conn->ibc_outstanding_credits += msg->ibm_credits;
+	conn->ibc_nsends_posted--;
+	if (msg->ibm_type == IBLND_MSG_NOOP)
+		conn->ibc_noops_posted--;
+
+	tx->tx_status = rc;
+	tx->tx_waiting = 0;
+	tx->tx_sending--;
+
+	done = (tx->tx_sending == 0);
+	if (done)
+		list_del(&tx->tx_list);
+
+	spin_unlock(&conn->ibc_lock);
+
+	if (conn->ibc_state == IBLND_CONN_ESTABLISHED)
+		CERROR("Error %d posting transmit to %s\n",
+		       rc, libcfs_nid2str(peer->ibp_nid));
+	else
+		CDEBUG(D_NET, "Error %d posting transmit to %s\n",
+		       rc, libcfs_nid2str(peer->ibp_nid));
+
+	kiblnd_close_conn(conn, rc);
+
+	if (done)
+		kiblnd_tx_done(peer->ibp_ni, tx);
+
+	spin_lock(&conn->ibc_lock);
+
+	return -EIO;
+}
+
+void
+kiblnd_check_sends (kib_conn_t *conn)
+{
+	int	ver = conn->ibc_version;
+	lnet_ni_t *ni = conn->ibc_peer->ibp_ni;
+	kib_tx_t  *tx;
+
+	/* Don't send anything until after the connection is established */
+	if (conn->ibc_state < IBLND_CONN_ESTABLISHED) {
+		CDEBUG(D_NET, "%s too soon\n",
+		       libcfs_nid2str(conn->ibc_peer->ibp_nid));
+		return;
+	}
+
+	spin_lock(&conn->ibc_lock);
+
+	LASSERT (conn->ibc_nsends_posted <= IBLND_CONCURRENT_SENDS(ver));
+	LASSERT (!IBLND_OOB_CAPABLE(ver) ||
+		 conn->ibc_noops_posted <= IBLND_OOB_MSGS(ver));
+	LASSERT (conn->ibc_reserved_credits >= 0);
+
+	while (conn->ibc_reserved_credits > 0 &&
+	       !list_empty(&conn->ibc_tx_queue_rsrvd)) {
+		tx = list_entry(conn->ibc_tx_queue_rsrvd.next,
+				    kib_tx_t, tx_list);
+		list_del(&tx->tx_list);
+		list_add_tail(&tx->tx_list, &conn->ibc_tx_queue);
+		conn->ibc_reserved_credits--;
+	}
+
+	if (kiblnd_need_noop(conn)) {
+		spin_unlock(&conn->ibc_lock);
+
+		tx = kiblnd_get_idle_tx(ni, conn->ibc_peer->ibp_nid);
+		if (tx != NULL)
+			kiblnd_init_tx_msg(ni, tx, IBLND_MSG_NOOP, 0);
+
+		spin_lock(&conn->ibc_lock);
+		if (tx != NULL)
+			kiblnd_queue_tx_locked(tx, conn);
+	}
+
+	kiblnd_conn_addref(conn); /* 1 ref for me.... (see b21911) */
+
+	for (;;) {
+		int credit;
+
+		if (!list_empty(&conn->ibc_tx_queue_nocred)) {
+			credit = 0;
+			tx = list_entry(conn->ibc_tx_queue_nocred.next,
+					    kib_tx_t, tx_list);
+		} else if (!list_empty(&conn->ibc_tx_noops)) {
+			LASSERT (!IBLND_OOB_CAPABLE(ver));
+			credit = 1;
+			tx = list_entry(conn->ibc_tx_noops.next,
+					kib_tx_t, tx_list);
+		} else if (!list_empty(&conn->ibc_tx_queue)) {
+			credit = 1;
+			tx = list_entry(conn->ibc_tx_queue.next,
+					    kib_tx_t, tx_list);
+		} else
+			break;
+
+		if (kiblnd_post_tx_locked(conn, tx, credit) != 0)
+			break;
+	}
+
+	spin_unlock(&conn->ibc_lock);
+
+	kiblnd_conn_decref(conn); /* ...until here */
+}
+
+void
+kiblnd_tx_complete (kib_tx_t *tx, int status)
+{
+	int	   failed = (status != IB_WC_SUCCESS);
+	kib_conn_t   *conn = tx->tx_conn;
+	int	   idle;
+
+	LASSERT (tx->tx_sending > 0);
+
+	if (failed) {
+		if (conn->ibc_state == IBLND_CONN_ESTABLISHED)
+			CNETERR("Tx -> %s cookie "LPX64
+				" sending %d waiting %d: failed %d\n",
+				libcfs_nid2str(conn->ibc_peer->ibp_nid),
+				tx->tx_cookie, tx->tx_sending, tx->tx_waiting,
+				status);
+
+		kiblnd_close_conn(conn, -EIO);
+	} else {
+		kiblnd_peer_alive(conn->ibc_peer);
+	}
+
+	spin_lock(&conn->ibc_lock);
+
+	/* I could be racing with rdma completion.  Whoever makes 'tx' idle
+	 * gets to free it, which also drops its ref on 'conn'. */
+
+	tx->tx_sending--;
+	conn->ibc_nsends_posted--;
+	if (tx->tx_msg->ibm_type == IBLND_MSG_NOOP)
+		conn->ibc_noops_posted--;
+
+	if (failed) {
+		tx->tx_waiting = 0;	     /* don't wait for peer */
+		tx->tx_status = -EIO;
+	}
+
+	idle = (tx->tx_sending == 0) &&	 /* This is the final callback */
+	       !tx->tx_waiting &&	       /* Not waiting for peer */
+	       !tx->tx_queued;		  /* Not re-queued (PUT_DONE) */
+	if (idle)
+		list_del(&tx->tx_list);
+
+	kiblnd_conn_addref(conn);	       /* 1 ref for me.... */
+
+	spin_unlock(&conn->ibc_lock);
+
+	if (idle)
+		kiblnd_tx_done(conn->ibc_peer->ibp_ni, tx);
+
+	kiblnd_check_sends(conn);
+
+	kiblnd_conn_decref(conn);	       /* ...until here */
+}
+
+void
+kiblnd_init_tx_msg (lnet_ni_t *ni, kib_tx_t *tx, int type, int body_nob)
+{
+	kib_hca_dev_t     *hdev = tx->tx_pool->tpo_hdev;
+	struct ib_sge     *sge = &tx->tx_sge[tx->tx_nwrq];
+	struct ib_send_wr *wrq = &tx->tx_wrq[tx->tx_nwrq];
+	int		nob = offsetof (kib_msg_t, ibm_u) + body_nob;
+	struct ib_mr      *mr;
+
+	LASSERT (tx->tx_nwrq >= 0);
+	LASSERT (tx->tx_nwrq < IBLND_MAX_RDMA_FRAGS + 1);
+	LASSERT (nob <= IBLND_MSG_SIZE);
+
+	kiblnd_init_msg(tx->tx_msg, type, body_nob);
+
+	mr = kiblnd_find_dma_mr(hdev, tx->tx_msgaddr, nob);
+	LASSERT (mr != NULL);
+
+	sge->lkey   = mr->lkey;
+	sge->addr   = tx->tx_msgaddr;
+	sge->length = nob;
+
+	memset(wrq, 0, sizeof(*wrq));
+
+	wrq->next       = NULL;
+	wrq->wr_id      = kiblnd_ptr2wreqid(tx, IBLND_WID_TX);
+	wrq->sg_list    = sge;
+	wrq->num_sge    = 1;
+	wrq->opcode     = IB_WR_SEND;
+	wrq->send_flags = IB_SEND_SIGNALED;
+
+	tx->tx_nwrq++;
+}
+
+int
+kiblnd_init_rdma (kib_conn_t *conn, kib_tx_t *tx, int type,
+		  int resid, kib_rdma_desc_t *dstrd, __u64 dstcookie)
+{
+	kib_msg_t	 *ibmsg = tx->tx_msg;
+	kib_rdma_desc_t   *srcrd = tx->tx_rd;
+	struct ib_sge     *sge = &tx->tx_sge[0];
+	struct ib_send_wr *wrq = &tx->tx_wrq[0];
+	int		rc  = resid;
+	int		srcidx;
+	int		dstidx;
+	int		wrknob;
+
+	LASSERT (!in_interrupt());
+	LASSERT (tx->tx_nwrq == 0);
+	LASSERT (type == IBLND_MSG_GET_DONE ||
+		 type == IBLND_MSG_PUT_DONE);
+
+	srcidx = dstidx = 0;
+
+	while (resid > 0) {
+		if (srcidx >= srcrd->rd_nfrags) {
+			CERROR("Src buffer exhausted: %d frags\n", srcidx);
+			rc = -EPROTO;
+			break;
+		}
+
+		if (dstidx == dstrd->rd_nfrags) {
+			CERROR("Dst buffer exhausted: %d frags\n", dstidx);
+			rc = -EPROTO;
+			break;
+		}
+
+		if (tx->tx_nwrq == IBLND_RDMA_FRAGS(conn->ibc_version)) {
+			CERROR("RDMA too fragmented for %s (%d): "
+			       "%d/%d src %d/%d dst frags\n",
+			       libcfs_nid2str(conn->ibc_peer->ibp_nid),
+			       IBLND_RDMA_FRAGS(conn->ibc_version),
+			       srcidx, srcrd->rd_nfrags,
+			       dstidx, dstrd->rd_nfrags);
+			rc = -EMSGSIZE;
+			break;
+		}
+
+		wrknob = MIN(MIN(kiblnd_rd_frag_size(srcrd, srcidx),
+				 kiblnd_rd_frag_size(dstrd, dstidx)), resid);
+
+		sge = &tx->tx_sge[tx->tx_nwrq];
+		sge->addr   = kiblnd_rd_frag_addr(srcrd, srcidx);
+		sge->lkey   = kiblnd_rd_frag_key(srcrd, srcidx);
+		sge->length = wrknob;
+
+		wrq = &tx->tx_wrq[tx->tx_nwrq];
+
+		wrq->next       = wrq + 1;
+		wrq->wr_id      = kiblnd_ptr2wreqid(tx, IBLND_WID_RDMA);
+		wrq->sg_list    = sge;
+		wrq->num_sge    = 1;
+		wrq->opcode     = IB_WR_RDMA_WRITE;
+		wrq->send_flags = 0;
+
+		wrq->wr.rdma.remote_addr = kiblnd_rd_frag_addr(dstrd, dstidx);
+		wrq->wr.rdma.rkey	= kiblnd_rd_frag_key(dstrd, dstidx);
+
+		srcidx = kiblnd_rd_consume_frag(srcrd, srcidx, wrknob);
+		dstidx = kiblnd_rd_consume_frag(dstrd, dstidx, wrknob);
+
+		resid -= wrknob;
+
+		tx->tx_nwrq++;
+		wrq++;
+		sge++;
+	}
+
+	if (rc < 0)			     /* no RDMA if completing with failure */
+		tx->tx_nwrq = 0;
+
+	ibmsg->ibm_u.completion.ibcm_status = rc;
+	ibmsg->ibm_u.completion.ibcm_cookie = dstcookie;
+	kiblnd_init_tx_msg(conn->ibc_peer->ibp_ni, tx,
+			   type, sizeof (kib_completion_msg_t));
+
+	return rc;
+}
+
+void
+kiblnd_queue_tx_locked (kib_tx_t *tx, kib_conn_t *conn)
+{
+	struct list_head   *q;
+
+	LASSERT (tx->tx_nwrq > 0);	      /* work items set up */
+	LASSERT (!tx->tx_queued);	       /* not queued for sending already */
+	LASSERT (conn->ibc_state >= IBLND_CONN_ESTABLISHED);
+
+	tx->tx_queued = 1;
+	tx->tx_deadline = jiffies + (*kiblnd_tunables.kib_timeout * HZ);
+
+	if (tx->tx_conn == NULL) {
+		kiblnd_conn_addref(conn);
+		tx->tx_conn = conn;
+		LASSERT (tx->tx_msg->ibm_type != IBLND_MSG_PUT_DONE);
+	} else {
+		/* PUT_DONE first attached to conn as a PUT_REQ */
+		LASSERT (tx->tx_conn == conn);
+		LASSERT (tx->tx_msg->ibm_type == IBLND_MSG_PUT_DONE);
+	}
+
+	switch (tx->tx_msg->ibm_type) {
+	default:
+		LBUG();
+
+	case IBLND_MSG_PUT_REQ:
+	case IBLND_MSG_GET_REQ:
+		q = &conn->ibc_tx_queue_rsrvd;
+		break;
+
+	case IBLND_MSG_PUT_NAK:
+	case IBLND_MSG_PUT_ACK:
+	case IBLND_MSG_PUT_DONE:
+	case IBLND_MSG_GET_DONE:
+		q = &conn->ibc_tx_queue_nocred;
+		break;
+
+	case IBLND_MSG_NOOP:
+		if (IBLND_OOB_CAPABLE(conn->ibc_version))
+			q = &conn->ibc_tx_queue_nocred;
+		else
+			q = &conn->ibc_tx_noops;
+		break;
+
+	case IBLND_MSG_IMMEDIATE:
+		q = &conn->ibc_tx_queue;
+		break;
+	}
+
+	list_add_tail(&tx->tx_list, q);
+}
+
+void
+kiblnd_queue_tx (kib_tx_t *tx, kib_conn_t *conn)
+{
+	spin_lock(&conn->ibc_lock);
+	kiblnd_queue_tx_locked(tx, conn);
+	spin_unlock(&conn->ibc_lock);
+
+	kiblnd_check_sends(conn);
+}
+
+static int kiblnd_resolve_addr(struct rdma_cm_id *cmid,
+			       struct sockaddr_in *srcaddr,
+			       struct sockaddr_in *dstaddr,
+			       int timeout_ms)
+{
+	unsigned short port;
+	int rc;
+
+	/* allow the port to be reused */
+	rc = rdma_set_reuseaddr(cmid, 1);
+	if (rc != 0) {
+		CERROR("Unable to set reuse on cmid: %d\n", rc);
+		return rc;
+	}
+
+	/* look for a free privileged port */
+	for (port = PROT_SOCK-1; port > 0; port--) {
+		srcaddr->sin_port = htons(port);
+		rc = rdma_resolve_addr(cmid,
+				       (struct sockaddr *)srcaddr,
+				       (struct sockaddr *)dstaddr,
+				       timeout_ms);
+		if (rc == 0) {
+			CDEBUG(D_NET, "bound to port %hu\n", port);
+			return 0;
+		} else if (rc == -EADDRINUSE || rc == -EADDRNOTAVAIL) {
+			CDEBUG(D_NET, "bind to port %hu failed: %d\n",
+			       port, rc);
+		} else {
+			return rc;
+		}
+	}
+
+	CERROR("Failed to bind to a free privileged port\n");
+	return rc;
+}
+
+void
+kiblnd_connect_peer (kib_peer_t *peer)
+{
+	struct rdma_cm_id *cmid;
+	kib_dev_t	 *dev;
+	kib_net_t	 *net = peer->ibp_ni->ni_data;
+	struct sockaddr_in srcaddr;
+	struct sockaddr_in dstaddr;
+	int		rc;
+
+	LASSERT (net != NULL);
+	LASSERT (peer->ibp_connecting > 0);
+
+	cmid = kiblnd_rdma_create_id(kiblnd_cm_callback, peer, RDMA_PS_TCP,
+				     IB_QPT_RC);
+
+	if (IS_ERR(cmid)) {
+		CERROR("Can't create CMID for %s: %ld\n",
+		       libcfs_nid2str(peer->ibp_nid), PTR_ERR(cmid));
+		rc = PTR_ERR(cmid);
+		goto failed;
+	}
+
+	dev = net->ibn_dev;
+	memset(&srcaddr, 0, sizeof(srcaddr));
+	srcaddr.sin_family = AF_INET;
+	srcaddr.sin_addr.s_addr = htonl(dev->ibd_ifip);
+
+	memset(&dstaddr, 0, sizeof(dstaddr));
+	dstaddr.sin_family = AF_INET;
+	dstaddr.sin_port = htons(*kiblnd_tunables.kib_service);
+	dstaddr.sin_addr.s_addr = htonl(LNET_NIDADDR(peer->ibp_nid));
+
+	kiblnd_peer_addref(peer);	       /* cmid's ref */
+
+	if (*kiblnd_tunables.kib_use_priv_port) {
+		rc = kiblnd_resolve_addr(cmid, &srcaddr, &dstaddr,
+					 *kiblnd_tunables.kib_timeout * 1000);
+	} else {
+		rc = rdma_resolve_addr(cmid,
+				       (struct sockaddr *)&srcaddr,
+				       (struct sockaddr *)&dstaddr,
+				       *kiblnd_tunables.kib_timeout * 1000);
+	}
+	if (rc != 0) {
+		/* Can't initiate address resolution:  */
+		CERROR("Can't resolve addr for %s: %d\n",
+		       libcfs_nid2str(peer->ibp_nid), rc);
+		goto failed2;
+	}
+
+	LASSERT (cmid->device != NULL);
+	CDEBUG(D_NET, "%s: connection bound to %s:%u.%u.%u.%u:%s\n",
+	       libcfs_nid2str(peer->ibp_nid), dev->ibd_ifname,
+	       HIPQUAD(dev->ibd_ifip), cmid->device->name);
+
+	return;
+
+ failed2:
+	kiblnd_peer_decref(peer);	       /* cmid's ref */
+	rdma_destroy_id(cmid);
+ failed:
+	kiblnd_peer_connect_failed(peer, 1, rc);
+}
+
+void
+kiblnd_launch_tx (lnet_ni_t *ni, kib_tx_t *tx, lnet_nid_t nid)
+{
+	kib_peer_t	*peer;
+	kib_peer_t	*peer2;
+	kib_conn_t	*conn;
+	rwlock_t	*g_lock = &kiblnd_data.kib_global_lock;
+	unsigned long      flags;
+	int		rc;
+
+	/* If I get here, I've committed to send, so I complete the tx with
+	 * failure on any problems */
+
+	LASSERT (tx == NULL || tx->tx_conn == NULL); /* only set when assigned a conn */
+	LASSERT (tx == NULL || tx->tx_nwrq > 0);     /* work items have been set up */
+
+	/* First time, just use a read lock since I expect to find my peer
+	 * connected */
+	read_lock_irqsave(g_lock, flags);
+
+	peer = kiblnd_find_peer_locked(nid);
+	if (peer != NULL && !list_empty(&peer->ibp_conns)) {
+		/* Found a peer with an established connection */
+		conn = kiblnd_get_conn_locked(peer);
+		kiblnd_conn_addref(conn); /* 1 ref for me... */
+
+		read_unlock_irqrestore(g_lock, flags);
+
+		if (tx != NULL)
+			kiblnd_queue_tx(tx, conn);
+		kiblnd_conn_decref(conn); /* ...to here */
+		return;
+	}
+
+	read_unlock(g_lock);
+	/* Re-try with a write lock */
+	write_lock(g_lock);
+
+	peer = kiblnd_find_peer_locked(nid);
+	if (peer != NULL) {
+		if (list_empty(&peer->ibp_conns)) {
+			/* found a peer, but it's still connecting... */
+			LASSERT (peer->ibp_connecting != 0 ||
+				 peer->ibp_accepting != 0);
+			if (tx != NULL)
+				list_add_tail(&tx->tx_list,
+						  &peer->ibp_tx_queue);
+			write_unlock_irqrestore(g_lock, flags);
+		} else {
+			conn = kiblnd_get_conn_locked(peer);
+			kiblnd_conn_addref(conn); /* 1 ref for me... */
+
+			write_unlock_irqrestore(g_lock, flags);
+
+			if (tx != NULL)
+				kiblnd_queue_tx(tx, conn);
+			kiblnd_conn_decref(conn); /* ...to here */
+		}
+		return;
+	}
+
+	write_unlock_irqrestore(g_lock, flags);
+
+	/* Allocate a peer ready to add to the peer table and retry */
+	rc = kiblnd_create_peer(ni, &peer, nid);
+	if (rc != 0) {
+		CERROR("Can't create peer %s\n", libcfs_nid2str(nid));
+		if (tx != NULL) {
+			tx->tx_status = -EHOSTUNREACH;
+			tx->tx_waiting = 0;
+			kiblnd_tx_done(ni, tx);
+		}
+		return;
+	}
+
+	write_lock_irqsave(g_lock, flags);
+
+	peer2 = kiblnd_find_peer_locked(nid);
+	if (peer2 != NULL) {
+		if (list_empty(&peer2->ibp_conns)) {
+			/* found a peer, but it's still connecting... */
+			LASSERT (peer2->ibp_connecting != 0 ||
+				 peer2->ibp_accepting != 0);
+			if (tx != NULL)
+				list_add_tail(&tx->tx_list,
+						  &peer2->ibp_tx_queue);
+			write_unlock_irqrestore(g_lock, flags);
+		} else {
+			conn = kiblnd_get_conn_locked(peer2);
+			kiblnd_conn_addref(conn); /* 1 ref for me... */
+
+			write_unlock_irqrestore(g_lock, flags);
+
+			if (tx != NULL)
+				kiblnd_queue_tx(tx, conn);
+			kiblnd_conn_decref(conn); /* ...to here */
+		}
+
+		kiblnd_peer_decref(peer);
+		return;
+	}
+
+	/* Brand new peer */
+	LASSERT (peer->ibp_connecting == 0);
+	peer->ibp_connecting = 1;
+
+	/* always called with a ref on ni, which prevents ni being shutdown */
+	LASSERT (((kib_net_t *)ni->ni_data)->ibn_shutdown == 0);
+
+	if (tx != NULL)
+		list_add_tail(&tx->tx_list, &peer->ibp_tx_queue);
+
+	kiblnd_peer_addref(peer);
+	list_add_tail(&peer->ibp_list, kiblnd_nid2peerlist(nid));
+
+	write_unlock_irqrestore(g_lock, flags);
+
+	kiblnd_connect_peer(peer);
+	kiblnd_peer_decref(peer);
+}
+
+int
+kiblnd_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
+{
+	lnet_hdr_t       *hdr = &lntmsg->msg_hdr;
+	int	       type = lntmsg->msg_type;
+	lnet_process_id_t target = lntmsg->msg_target;
+	int	       target_is_router = lntmsg->msg_target_is_router;
+	int	       routing = lntmsg->msg_routing;
+	unsigned int      payload_niov = lntmsg->msg_niov;
+	struct iovec     *payload_iov = lntmsg->msg_iov;
+	lnet_kiov_t      *payload_kiov = lntmsg->msg_kiov;
+	unsigned int      payload_offset = lntmsg->msg_offset;
+	unsigned int      payload_nob = lntmsg->msg_len;
+	kib_msg_t	*ibmsg;
+	kib_tx_t	 *tx;
+	int	       nob;
+	int	       rc;
+
+	/* NB 'private' is different depending on what we're sending.... */
+
+	CDEBUG(D_NET, "sending %d bytes in %d frags to %s\n",
+	       payload_nob, payload_niov, libcfs_id2str(target));
+
+	LASSERT (payload_nob == 0 || payload_niov > 0);
+	LASSERT (payload_niov <= LNET_MAX_IOV);
+
+	/* Thread context */
+	LASSERT (!in_interrupt());
+	/* payload is either all vaddrs or all pages */
+	LASSERT (!(payload_kiov != NULL && payload_iov != NULL));
+
+	switch (type) {
+	default:
+		LBUG();
+		return (-EIO);
+
+	case LNET_MSG_ACK:
+		LASSERT (payload_nob == 0);
+		break;
+
+	case LNET_MSG_GET:
+		if (routing || target_is_router)
+			break;		  /* send IMMEDIATE */
+
+		/* is the REPLY message too small for RDMA? */
+		nob = offsetof(kib_msg_t, ibm_u.immediate.ibim_payload[lntmsg->msg_md->md_length]);
+		if (nob <= IBLND_MSG_SIZE)
+			break;		  /* send IMMEDIATE */
+
+		tx = kiblnd_get_idle_tx(ni, target.nid);
+		if (tx == NULL) {
+			CERROR("Can't allocate txd for GET to %s\n",
+			       libcfs_nid2str(target.nid));
+			return -ENOMEM;
+		}
+
+		ibmsg = tx->tx_msg;
+
+		if ((lntmsg->msg_md->md_options & LNET_MD_KIOV) == 0)
+			rc = kiblnd_setup_rd_iov(ni, tx,
+						 &ibmsg->ibm_u.get.ibgm_rd,
+						 lntmsg->msg_md->md_niov,
+						 lntmsg->msg_md->md_iov.iov,
+						 0, lntmsg->msg_md->md_length);
+		else
+			rc = kiblnd_setup_rd_kiov(ni, tx,
+						  &ibmsg->ibm_u.get.ibgm_rd,
+						  lntmsg->msg_md->md_niov,
+						  lntmsg->msg_md->md_iov.kiov,
+						  0, lntmsg->msg_md->md_length);
+		if (rc != 0) {
+			CERROR("Can't setup GET sink for %s: %d\n",
+			       libcfs_nid2str(target.nid), rc);
+			kiblnd_tx_done(ni, tx);
+			return -EIO;
+		}
+
+		nob = offsetof(kib_get_msg_t, ibgm_rd.rd_frags[tx->tx_nfrags]);
+		ibmsg->ibm_u.get.ibgm_cookie = tx->tx_cookie;
+		ibmsg->ibm_u.get.ibgm_hdr = *hdr;
+
+		kiblnd_init_tx_msg(ni, tx, IBLND_MSG_GET_REQ, nob);
+
+		tx->tx_lntmsg[1] = lnet_create_reply_msg(ni, lntmsg);
+		if (tx->tx_lntmsg[1] == NULL) {
+			CERROR("Can't create reply for GET -> %s\n",
+			       libcfs_nid2str(target.nid));
+			kiblnd_tx_done(ni, tx);
+			return -EIO;
+		}
+
+		tx->tx_lntmsg[0] = lntmsg;      /* finalise lntmsg[0,1] on completion */
+		tx->tx_waiting = 1;	     /* waiting for GET_DONE */
+		kiblnd_launch_tx(ni, tx, target.nid);
+		return 0;
+
+	case LNET_MSG_REPLY:
+	case LNET_MSG_PUT:
+		/* Is the payload small enough not to need RDMA? */
+		nob = offsetof(kib_msg_t, ibm_u.immediate.ibim_payload[payload_nob]);
+		if (nob <= IBLND_MSG_SIZE)
+			break;		  /* send IMMEDIATE */
+
+		tx = kiblnd_get_idle_tx(ni, target.nid);
+		if (tx == NULL) {
+			CERROR("Can't allocate %s txd for %s\n",
+			       type == LNET_MSG_PUT ? "PUT" : "REPLY",
+			       libcfs_nid2str(target.nid));
+			return -ENOMEM;
+		}
+
+		if (payload_kiov == NULL)
+			rc = kiblnd_setup_rd_iov(ni, tx, tx->tx_rd,
+						 payload_niov, payload_iov,
+						 payload_offset, payload_nob);
+		else
+			rc = kiblnd_setup_rd_kiov(ni, tx, tx->tx_rd,
+						  payload_niov, payload_kiov,
+						  payload_offset, payload_nob);
+		if (rc != 0) {
+			CERROR("Can't setup PUT src for %s: %d\n",
+			       libcfs_nid2str(target.nid), rc);
+			kiblnd_tx_done(ni, tx);
+			return -EIO;
+		}
+
+		ibmsg = tx->tx_msg;
+		ibmsg->ibm_u.putreq.ibprm_hdr = *hdr;
+		ibmsg->ibm_u.putreq.ibprm_cookie = tx->tx_cookie;
+		kiblnd_init_tx_msg(ni, tx, IBLND_MSG_PUT_REQ, sizeof(kib_putreq_msg_t));
+
+		tx->tx_lntmsg[0] = lntmsg;      /* finalise lntmsg on completion */
+		tx->tx_waiting = 1;	     /* waiting for PUT_{ACK,NAK} */
+		kiblnd_launch_tx(ni, tx, target.nid);
+		return 0;
+	}
+
+	/* send IMMEDIATE */
+
+	LASSERT (offsetof(kib_msg_t, ibm_u.immediate.ibim_payload[payload_nob])
+		 <= IBLND_MSG_SIZE);
+
+	tx = kiblnd_get_idle_tx(ni, target.nid);
+	if (tx == NULL) {
+		CERROR ("Can't send %d to %s: tx descs exhausted\n",
+			type, libcfs_nid2str(target.nid));
+		return -ENOMEM;
+	}
+
+	ibmsg = tx->tx_msg;
+	ibmsg->ibm_u.immediate.ibim_hdr = *hdr;
+
+	if (payload_kiov != NULL)
+		lnet_copy_kiov2flat(IBLND_MSG_SIZE, ibmsg,
+				    offsetof(kib_msg_t, ibm_u.immediate.ibim_payload),
+				    payload_niov, payload_kiov,
+				    payload_offset, payload_nob);
+	else
+		lnet_copy_iov2flat(IBLND_MSG_SIZE, ibmsg,
+				   offsetof(kib_msg_t, ibm_u.immediate.ibim_payload),
+				   payload_niov, payload_iov,
+				   payload_offset, payload_nob);
+
+	nob = offsetof(kib_immediate_msg_t, ibim_payload[payload_nob]);
+	kiblnd_init_tx_msg(ni, tx, IBLND_MSG_IMMEDIATE, nob);
+
+	tx->tx_lntmsg[0] = lntmsg;	      /* finalise lntmsg on completion */
+	kiblnd_launch_tx(ni, tx, target.nid);
+	return 0;
+}
+
+void
+kiblnd_reply (lnet_ni_t *ni, kib_rx_t *rx, lnet_msg_t *lntmsg)
+{
+	lnet_process_id_t target = lntmsg->msg_target;
+	unsigned int      niov = lntmsg->msg_niov;
+	struct iovec     *iov = lntmsg->msg_iov;
+	lnet_kiov_t      *kiov = lntmsg->msg_kiov;
+	unsigned int      offset = lntmsg->msg_offset;
+	unsigned int      nob = lntmsg->msg_len;
+	kib_tx_t	 *tx;
+	int	       rc;
+
+	tx = kiblnd_get_idle_tx(ni, rx->rx_conn->ibc_peer->ibp_nid);
+	if (tx == NULL) {
+		CERROR("Can't get tx for REPLY to %s\n",
+		       libcfs_nid2str(target.nid));
+		goto failed_0;
+	}
+
+	if (nob == 0)
+		rc = 0;
+	else if (kiov == NULL)
+		rc = kiblnd_setup_rd_iov(ni, tx, tx->tx_rd,
+					 niov, iov, offset, nob);
+	else
+		rc = kiblnd_setup_rd_kiov(ni, tx, tx->tx_rd,
+					  niov, kiov, offset, nob);
+
+	if (rc != 0) {
+		CERROR("Can't setup GET src for %s: %d\n",
+		       libcfs_nid2str(target.nid), rc);
+		goto failed_1;
+	}
+
+	rc = kiblnd_init_rdma(rx->rx_conn, tx,
+			      IBLND_MSG_GET_DONE, nob,
+			      &rx->rx_msg->ibm_u.get.ibgm_rd,
+			      rx->rx_msg->ibm_u.get.ibgm_cookie);
+	if (rc < 0) {
+		CERROR("Can't setup rdma for GET from %s: %d\n",
+		       libcfs_nid2str(target.nid), rc);
+		goto failed_1;
+	}
+
+	if (nob == 0) {
+		/* No RDMA: local completion may happen now! */
+		lnet_finalize(ni, lntmsg, 0);
+	} else {
+		/* RDMA: lnet_finalize(lntmsg) when it
+		 * completes */
+		tx->tx_lntmsg[0] = lntmsg;
+	}
+
+	kiblnd_queue_tx(tx, rx->rx_conn);
+	return;
+
+ failed_1:
+	kiblnd_tx_done(ni, tx);
+ failed_0:
+	lnet_finalize(ni, lntmsg, -EIO);
+}
+
+int
+kiblnd_recv (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
+	     unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov,
+	     unsigned int offset, unsigned int mlen, unsigned int rlen)
+{
+	kib_rx_t    *rx = private;
+	kib_msg_t   *rxmsg = rx->rx_msg;
+	kib_conn_t  *conn = rx->rx_conn;
+	kib_tx_t    *tx;
+	kib_msg_t   *txmsg;
+	int	  nob;
+	int	  post_credit = IBLND_POSTRX_PEER_CREDIT;
+	int	  rc = 0;
+
+	LASSERT (mlen <= rlen);
+	LASSERT (!in_interrupt());
+	/* Either all pages or all vaddrs */
+	LASSERT (!(kiov != NULL && iov != NULL));
+
+	switch (rxmsg->ibm_type) {
+	default:
+		LBUG();
+
+	case IBLND_MSG_IMMEDIATE:
+		nob = offsetof(kib_msg_t, ibm_u.immediate.ibim_payload[rlen]);
+		if (nob > rx->rx_nob) {
+			CERROR ("Immediate message from %s too big: %d(%d)\n",
+				libcfs_nid2str(rxmsg->ibm_u.immediate.ibim_hdr.src_nid),
+				nob, rx->rx_nob);
+			rc = -EPROTO;
+			break;
+		}
+
+		if (kiov != NULL)
+			lnet_copy_flat2kiov(niov, kiov, offset,
+					    IBLND_MSG_SIZE, rxmsg,
+					    offsetof(kib_msg_t, ibm_u.immediate.ibim_payload),
+					    mlen);
+		else
+			lnet_copy_flat2iov(niov, iov, offset,
+					   IBLND_MSG_SIZE, rxmsg,
+					   offsetof(kib_msg_t, ibm_u.immediate.ibim_payload),
+					   mlen);
+		lnet_finalize (ni, lntmsg, 0);
+		break;
+
+	case IBLND_MSG_PUT_REQ:
+		if (mlen == 0) {
+			lnet_finalize(ni, lntmsg, 0);
+			kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, 0,
+					       rxmsg->ibm_u.putreq.ibprm_cookie);
+			break;
+		}
+
+		tx = kiblnd_get_idle_tx(ni, conn->ibc_peer->ibp_nid);
+		if (tx == NULL) {
+			CERROR("Can't allocate tx for %s\n",
+			       libcfs_nid2str(conn->ibc_peer->ibp_nid));
+			/* Not replying will break the connection */
+			rc = -ENOMEM;
+			break;
+		}
+
+		txmsg = tx->tx_msg;
+		if (kiov == NULL)
+			rc = kiblnd_setup_rd_iov(ni, tx,
+						 &txmsg->ibm_u.putack.ibpam_rd,
+						 niov, iov, offset, mlen);
+		else
+			rc = kiblnd_setup_rd_kiov(ni, tx,
+						  &txmsg->ibm_u.putack.ibpam_rd,
+						  niov, kiov, offset, mlen);
+		if (rc != 0) {
+			CERROR("Can't setup PUT sink for %s: %d\n",
+			       libcfs_nid2str(conn->ibc_peer->ibp_nid), rc);
+			kiblnd_tx_done(ni, tx);
+			/* tell peer it's over */
+			kiblnd_send_completion(rx->rx_conn, IBLND_MSG_PUT_NAK, rc,
+					       rxmsg->ibm_u.putreq.ibprm_cookie);
+			break;
+		}
+
+		nob = offsetof(kib_putack_msg_t, ibpam_rd.rd_frags[tx->tx_nfrags]);
+		txmsg->ibm_u.putack.ibpam_src_cookie = rxmsg->ibm_u.putreq.ibprm_cookie;
+		txmsg->ibm_u.putack.ibpam_dst_cookie = tx->tx_cookie;
+
+		kiblnd_init_tx_msg(ni, tx, IBLND_MSG_PUT_ACK, nob);
+
+		tx->tx_lntmsg[0] = lntmsg;      /* finalise lntmsg on completion */
+		tx->tx_waiting = 1;	     /* waiting for PUT_DONE */
+		kiblnd_queue_tx(tx, conn);
+
+		/* reposted buffer reserved for PUT_DONE */
+		post_credit = IBLND_POSTRX_NO_CREDIT;
+		break;
+
+	case IBLND_MSG_GET_REQ:
+		if (lntmsg != NULL) {
+			/* Optimized GET; RDMA lntmsg's payload */
+			kiblnd_reply(ni, rx, lntmsg);
+		} else {
+			/* GET didn't match anything */
+			kiblnd_send_completion(rx->rx_conn, IBLND_MSG_GET_DONE,
+					       -ENODATA,
+					       rxmsg->ibm_u.get.ibgm_cookie);
+		}
+		break;
+	}
+
+	kiblnd_post_rx(rx, post_credit);
+	return rc;
+}
+
+int
+kiblnd_thread_start(int (*fn)(void *arg), void *arg, char *name)
+{
+	task_t *task = kthread_run(fn, arg, name);
+
+	if (IS_ERR(task))
+		return PTR_ERR(task);
+
+	atomic_inc(&kiblnd_data.kib_nthreads);
+	return 0;
+}
+
+void
+kiblnd_thread_fini (void)
+{
+	atomic_dec (&kiblnd_data.kib_nthreads);
+}
+
+void
+kiblnd_peer_alive (kib_peer_t *peer)
+{
+	/* This is racy, but everyone's only writing cfs_time_current() */
+	peer->ibp_last_alive = cfs_time_current();
+	mb();
+}
+
+void
+kiblnd_peer_notify (kib_peer_t *peer)
+{
+	int	   error = 0;
+	cfs_time_t    last_alive = 0;
+	unsigned long flags;
+
+	read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	if (list_empty(&peer->ibp_conns) &&
+	    peer->ibp_accepting == 0 &&
+	    peer->ibp_connecting == 0 &&
+	    peer->ibp_error != 0) {
+		error = peer->ibp_error;
+		peer->ibp_error = 0;
+
+		last_alive = peer->ibp_last_alive;
+	}
+
+	read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	if (error != 0)
+		lnet_notify(peer->ibp_ni,
+			    peer->ibp_nid, 0, last_alive);
+}
+
+void
+kiblnd_close_conn_locked (kib_conn_t *conn, int error)
+{
+	/* This just does the immediate housekeeping.  'error' is zero for a
+	 * normal shutdown which can happen only after the connection has been
+	 * established.  If the connection is established, schedule the
+	 * connection to be finished off by the connd.  Otherwise the connd is
+	 * already dealing with it (either to set it up or tear it down).
+	 * Caller holds kib_global_lock exclusively in irq context */
+	kib_peer_t       *peer = conn->ibc_peer;
+	kib_dev_t	*dev;
+	unsigned long     flags;
+
+	LASSERT (error != 0 || conn->ibc_state >= IBLND_CONN_ESTABLISHED);
+
+	if (error != 0 && conn->ibc_comms_error == 0)
+		conn->ibc_comms_error = error;
+
+	if (conn->ibc_state != IBLND_CONN_ESTABLISHED)
+		return; /* already being handled  */
+
+	if (error == 0 &&
+	    list_empty(&conn->ibc_tx_noops) &&
+	    list_empty(&conn->ibc_tx_queue) &&
+	    list_empty(&conn->ibc_tx_queue_rsrvd) &&
+	    list_empty(&conn->ibc_tx_queue_nocred) &&
+	    list_empty(&conn->ibc_active_txs)) {
+		CDEBUG(D_NET, "closing conn to %s\n",
+		       libcfs_nid2str(peer->ibp_nid));
+	} else {
+		CNETERR("Closing conn to %s: error %d%s%s%s%s%s\n",
+		       libcfs_nid2str(peer->ibp_nid), error,
+		       list_empty(&conn->ibc_tx_queue) ? "" : "(sending)",
+		       list_empty(&conn->ibc_tx_noops) ? "" : "(sending_noops)",
+		       list_empty(&conn->ibc_tx_queue_rsrvd) ? "" : "(sending_rsrvd)",
+		       list_empty(&conn->ibc_tx_queue_nocred) ? "" : "(sending_nocred)",
+		       list_empty(&conn->ibc_active_txs) ? "" : "(waiting)");
+	}
+
+	dev = ((kib_net_t *)peer->ibp_ni->ni_data)->ibn_dev;
+	list_del(&conn->ibc_list);
+	/* connd (see below) takes over ibc_list's ref */
+
+	if (list_empty (&peer->ibp_conns) &&    /* no more conns */
+	    kiblnd_peer_active(peer)) {	 /* still in peer table */
+		kiblnd_unlink_peer_locked(peer);
+
+		/* set/clear error on last conn */
+		peer->ibp_error = conn->ibc_comms_error;
+	}
+
+	kiblnd_set_conn_state(conn, IBLND_CONN_CLOSING);
+
+	if (error != 0 &&
+	    kiblnd_dev_can_failover(dev)) {
+		list_add_tail(&dev->ibd_fail_list,
+			      &kiblnd_data.kib_failed_devs);
+		wake_up(&kiblnd_data.kib_failover_waitq);
+	}
+
+	spin_lock_irqsave(&kiblnd_data.kib_connd_lock, flags);
+
+	list_add_tail(&conn->ibc_list, &kiblnd_data.kib_connd_conns);
+	wake_up(&kiblnd_data.kib_connd_waitq);
+
+	spin_unlock_irqrestore(&kiblnd_data.kib_connd_lock, flags);
+}
+
+void
+kiblnd_close_conn(kib_conn_t *conn, int error)
+{
+	unsigned long flags;
+
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	kiblnd_close_conn_locked(conn, error);
+
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+}
+
+void
+kiblnd_handle_early_rxs(kib_conn_t *conn)
+{
+	unsigned long    flags;
+	kib_rx_t	*rx;
+
+	LASSERT(!in_interrupt());
+	LASSERT(conn->ibc_state >= IBLND_CONN_ESTABLISHED);
+
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+	while (!list_empty(&conn->ibc_early_rxs)) {
+		rx = list_entry(conn->ibc_early_rxs.next,
+				    kib_rx_t, rx_list);
+		list_del(&rx->rx_list);
+		write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+		kiblnd_handle_rx(rx);
+
+		write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+	}
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+}
+
+void
+kiblnd_abort_txs(kib_conn_t *conn, struct list_head *txs)
+{
+	LIST_HEAD       (zombies);
+	struct list_head	  *tmp;
+	struct list_head	  *nxt;
+	kib_tx_t	    *tx;
+
+	spin_lock(&conn->ibc_lock);
+
+	list_for_each_safe (tmp, nxt, txs) {
+		tx = list_entry (tmp, kib_tx_t, tx_list);
+
+		if (txs == &conn->ibc_active_txs) {
+			LASSERT (!tx->tx_queued);
+			LASSERT (tx->tx_waiting ||
+				 tx->tx_sending != 0);
+		} else {
+			LASSERT (tx->tx_queued);
+		}
+
+		tx->tx_status = -ECONNABORTED;
+		tx->tx_waiting = 0;
+
+		if (tx->tx_sending == 0) {
+			tx->tx_queued = 0;
+			list_del (&tx->tx_list);
+			list_add (&tx->tx_list, &zombies);
+		}
+	}
+
+	spin_unlock(&conn->ibc_lock);
+
+	kiblnd_txlist_done(conn->ibc_peer->ibp_ni, &zombies, -ECONNABORTED);
+}
+
+void
+kiblnd_finalise_conn (kib_conn_t *conn)
+{
+	LASSERT (!in_interrupt());
+	LASSERT (conn->ibc_state > IBLND_CONN_INIT);
+
+	kiblnd_set_conn_state(conn, IBLND_CONN_DISCONNECTED);
+
+	/* abort_receives moves QP state to IB_QPS_ERR.  This is only required
+	 * for connections that didn't get as far as being connected, because
+	 * rdma_disconnect() does this for free. */
+	kiblnd_abort_receives(conn);
+
+	/* Complete all tx descs not waiting for sends to complete.
+	 * NB we should be safe from RDMA now that the QP has changed state */
+
+	kiblnd_abort_txs(conn, &conn->ibc_tx_noops);
+	kiblnd_abort_txs(conn, &conn->ibc_tx_queue);
+	kiblnd_abort_txs(conn, &conn->ibc_tx_queue_rsrvd);
+	kiblnd_abort_txs(conn, &conn->ibc_tx_queue_nocred);
+	kiblnd_abort_txs(conn, &conn->ibc_active_txs);
+
+	kiblnd_handle_early_rxs(conn);
+}
+
+void
+kiblnd_peer_connect_failed (kib_peer_t *peer, int active, int error)
+{
+	LIST_HEAD    (zombies);
+	unsigned long     flags;
+
+	LASSERT (error != 0);
+	LASSERT (!in_interrupt());
+
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	if (active) {
+		LASSERT (peer->ibp_connecting > 0);
+		peer->ibp_connecting--;
+	} else {
+		LASSERT (peer->ibp_accepting > 0);
+		peer->ibp_accepting--;
+	}
+
+	if (peer->ibp_connecting != 0 ||
+	    peer->ibp_accepting != 0) {
+		/* another connection attempt under way... */
+		write_unlock_irqrestore(&kiblnd_data.kib_global_lock,
+					    flags);
+		return;
+	}
+
+	if (list_empty(&peer->ibp_conns)) {
+		/* Take peer's blocked transmits to complete with error */
+		list_add(&zombies, &peer->ibp_tx_queue);
+		list_del_init(&peer->ibp_tx_queue);
+
+		if (kiblnd_peer_active(peer))
+			kiblnd_unlink_peer_locked(peer);
+
+		peer->ibp_error = error;
+	} else {
+		/* Can't have blocked transmits if there are connections */
+		LASSERT (list_empty(&peer->ibp_tx_queue));
+	}
+
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	kiblnd_peer_notify(peer);
+
+	if (list_empty (&zombies))
+		return;
+
+	CNETERR("Deleting messages for %s: connection failed\n",
+		libcfs_nid2str(peer->ibp_nid));
+
+	kiblnd_txlist_done(peer->ibp_ni, &zombies, -EHOSTUNREACH);
+}
+
+void
+kiblnd_connreq_done(kib_conn_t *conn, int status)
+{
+	kib_peer_t	*peer = conn->ibc_peer;
+	kib_tx_t	  *tx;
+	struct list_head	 txs;
+	unsigned long      flags;
+	int		active;
+
+	active = (conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT);
+
+	CDEBUG(D_NET,"%s: active(%d), version(%x), status(%d)\n",
+	       libcfs_nid2str(peer->ibp_nid), active,
+	       conn->ibc_version, status);
+
+	LASSERT (!in_interrupt());
+	LASSERT ((conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT &&
+		  peer->ibp_connecting > 0) ||
+		 (conn->ibc_state == IBLND_CONN_PASSIVE_WAIT &&
+		  peer->ibp_accepting > 0));
+
+	LIBCFS_FREE(conn->ibc_connvars, sizeof(*conn->ibc_connvars));
+	conn->ibc_connvars = NULL;
+
+	if (status != 0) {
+		/* failed to establish connection */
+		kiblnd_peer_connect_failed(peer, active, status);
+		kiblnd_finalise_conn(conn);
+		return;
+	}
+
+	/* connection established */
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	conn->ibc_last_send = jiffies;
+	kiblnd_set_conn_state(conn, IBLND_CONN_ESTABLISHED);
+	kiblnd_peer_alive(peer);
+
+	/* Add conn to peer's list and nuke any dangling conns from a different
+	 * peer instance... */
+	kiblnd_conn_addref(conn);	       /* +1 ref for ibc_list */
+	list_add(&conn->ibc_list, &peer->ibp_conns);
+	if (active)
+		peer->ibp_connecting--;
+	else
+		peer->ibp_accepting--;
+
+	if (peer->ibp_version == 0) {
+		peer->ibp_version     = conn->ibc_version;
+		peer->ibp_incarnation = conn->ibc_incarnation;
+	}
+
+	if (peer->ibp_version     != conn->ibc_version ||
+	    peer->ibp_incarnation != conn->ibc_incarnation) {
+		kiblnd_close_stale_conns_locked(peer, conn->ibc_version,
+						conn->ibc_incarnation);
+		peer->ibp_version     = conn->ibc_version;
+		peer->ibp_incarnation = conn->ibc_incarnation;
+	}
+
+	/* grab pending txs while I have the lock */
+	list_add(&txs, &peer->ibp_tx_queue);
+	list_del_init(&peer->ibp_tx_queue);
+
+	if (!kiblnd_peer_active(peer) ||	/* peer has been deleted */
+	    conn->ibc_comms_error != 0) {       /* error has happened already */
+		lnet_ni_t *ni = peer->ibp_ni;
+
+		/* start to shut down connection */
+		kiblnd_close_conn_locked(conn, -ECONNABORTED);
+		write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+		kiblnd_txlist_done(ni, &txs, -ECONNABORTED);
+
+		return;
+	}
+
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	/* Schedule blocked txs */
+	spin_lock(&conn->ibc_lock);
+	while (!list_empty(&txs)) {
+		tx = list_entry(txs.next, kib_tx_t, tx_list);
+		list_del(&tx->tx_list);
+
+		kiblnd_queue_tx_locked(tx, conn);
+	}
+	spin_unlock(&conn->ibc_lock);
+
+	kiblnd_check_sends(conn);
+
+	/* schedule blocked rxs */
+	kiblnd_handle_early_rxs(conn);
+}
+
+void
+kiblnd_reject(struct rdma_cm_id *cmid, kib_rej_t *rej)
+{
+	int	  rc;
+
+	rc = rdma_reject(cmid, rej, sizeof(*rej));
+
+	if (rc != 0)
+		CWARN("Error %d sending reject\n", rc);
+}
+
+int
+kiblnd_passive_connect (struct rdma_cm_id *cmid, void *priv, int priv_nob)
+{
+	rwlock_t		*g_lock = &kiblnd_data.kib_global_lock;
+	kib_msg_t	     *reqmsg = priv;
+	kib_msg_t	     *ackmsg;
+	kib_dev_t	     *ibdev;
+	kib_peer_t	    *peer;
+	kib_peer_t	    *peer2;
+	kib_conn_t	    *conn;
+	lnet_ni_t	     *ni  = NULL;
+	kib_net_t	     *net = NULL;
+	lnet_nid_t	     nid;
+	struct rdma_conn_param cp;
+	kib_rej_t	      rej;
+	int		    version = IBLND_MSG_VERSION;
+	unsigned long	  flags;
+	int		    rc;
+	struct sockaddr_in    *peer_addr;
+	LASSERT (!in_interrupt());
+
+	/* cmid inherits 'context' from the corresponding listener id */
+	ibdev = (kib_dev_t *)cmid->context;
+	LASSERT (ibdev != NULL);
+
+	memset(&rej, 0, sizeof(rej));
+	rej.ibr_magic		= IBLND_MSG_MAGIC;
+	rej.ibr_why		  = IBLND_REJECT_FATAL;
+	rej.ibr_cp.ibcp_max_msg_size = IBLND_MSG_SIZE;
+
+	peer_addr = (struct sockaddr_in *)&(cmid->route.addr.dst_addr);
+	if (*kiblnd_tunables.kib_require_priv_port &&
+	    ntohs(peer_addr->sin_port) >= PROT_SOCK) {
+		__u32 ip = ntohl(peer_addr->sin_addr.s_addr);
+		CERROR("Peer's port (%u.%u.%u.%u:%hu) is not privileged\n",
+		       HIPQUAD(ip), ntohs(peer_addr->sin_port));
+		goto failed;
+	}
+
+	if (priv_nob < offsetof(kib_msg_t, ibm_type)) {
+		CERROR("Short connection request\n");
+		goto failed;
+	}
+
+	/* Future protocol version compatibility support!  If the
+	 * o2iblnd-specific protocol changes, or when LNET unifies
+	 * protocols over all LNDs, the initial connection will
+	 * negotiate a protocol version.  I trap this here to avoid
+	 * console errors; the reject tells the peer which protocol I
+	 * speak. */
+	if (reqmsg->ibm_magic == LNET_PROTO_MAGIC ||
+	    reqmsg->ibm_magic == __swab32(LNET_PROTO_MAGIC))
+		goto failed;
+	if (reqmsg->ibm_magic == IBLND_MSG_MAGIC &&
+	    reqmsg->ibm_version != IBLND_MSG_VERSION &&
+	    reqmsg->ibm_version != IBLND_MSG_VERSION_1)
+		goto failed;
+	if (reqmsg->ibm_magic == __swab32(IBLND_MSG_MAGIC) &&
+	    reqmsg->ibm_version != __swab16(IBLND_MSG_VERSION) &&
+	    reqmsg->ibm_version != __swab16(IBLND_MSG_VERSION_1))
+		goto failed;
+
+	rc = kiblnd_unpack_msg(reqmsg, priv_nob);
+	if (rc != 0) {
+		CERROR("Can't parse connection request: %d\n", rc);
+		goto failed;
+	}
+
+	nid = reqmsg->ibm_srcnid;
+	ni  = lnet_net2ni(LNET_NIDNET(reqmsg->ibm_dstnid));
+
+	if (ni != NULL) {
+		net = (kib_net_t *)ni->ni_data;
+		rej.ibr_incarnation = net->ibn_incarnation;
+	}
+
+	if (ni == NULL ||			 /* no matching net */
+	    ni->ni_nid != reqmsg->ibm_dstnid ||   /* right NET, wrong NID! */
+	    net->ibn_dev != ibdev) {	      /* wrong device */
+		CERROR("Can't accept %s on %s (%s:%d:%u.%u.%u.%u): "
+		       "bad dst nid %s\n", libcfs_nid2str(nid),
+		       ni == NULL ? "NA" : libcfs_nid2str(ni->ni_nid),
+		       ibdev->ibd_ifname, ibdev->ibd_nnets,
+		       HIPQUAD(ibdev->ibd_ifip),
+		       libcfs_nid2str(reqmsg->ibm_dstnid));
+
+		goto failed;
+	}
+
+       /* check time stamp as soon as possible */
+	if (reqmsg->ibm_dststamp != 0 &&
+	    reqmsg->ibm_dststamp != net->ibn_incarnation) {
+		CWARN("Stale connection request\n");
+		rej.ibr_why = IBLND_REJECT_CONN_STALE;
+		goto failed;
+	}
+
+	/* I can accept peer's version */
+	version = reqmsg->ibm_version;
+
+	if (reqmsg->ibm_type != IBLND_MSG_CONNREQ) {
+		CERROR("Unexpected connreq msg type: %x from %s\n",
+		       reqmsg->ibm_type, libcfs_nid2str(nid));
+		goto failed;
+	}
+
+	if (reqmsg->ibm_u.connparams.ibcp_queue_depth !=
+	    IBLND_MSG_QUEUE_SIZE(version)) {
+		CERROR("Can't accept %s: incompatible queue depth %d (%d wanted)\n",
+		       libcfs_nid2str(nid), reqmsg->ibm_u.connparams.ibcp_queue_depth,
+		       IBLND_MSG_QUEUE_SIZE(version));
+
+		if (version == IBLND_MSG_VERSION)
+			rej.ibr_why = IBLND_REJECT_MSG_QUEUE_SIZE;
+
+		goto failed;
+	}
+
+	if (reqmsg->ibm_u.connparams.ibcp_max_frags !=
+	    IBLND_RDMA_FRAGS(version)) {
+		CERROR("Can't accept %s(version %x): "
+		       "incompatible max_frags %d (%d wanted)\n",
+		       libcfs_nid2str(nid), version,
+		       reqmsg->ibm_u.connparams.ibcp_max_frags,
+		       IBLND_RDMA_FRAGS(version));
+
+		if (version == IBLND_MSG_VERSION)
+			rej.ibr_why = IBLND_REJECT_RDMA_FRAGS;
+
+		goto failed;
+
+	}
+
+	if (reqmsg->ibm_u.connparams.ibcp_max_msg_size > IBLND_MSG_SIZE) {
+		CERROR("Can't accept %s: message size %d too big (%d max)\n",
+		       libcfs_nid2str(nid),
+		       reqmsg->ibm_u.connparams.ibcp_max_msg_size,
+		       IBLND_MSG_SIZE);
+		goto failed;
+	}
+
+	/* assume 'nid' is a new peer; create  */
+	rc = kiblnd_create_peer(ni, &peer, nid);
+	if (rc != 0) {
+		CERROR("Can't create peer for %s\n", libcfs_nid2str(nid));
+		rej.ibr_why = IBLND_REJECT_NO_RESOURCES;
+		goto failed;
+	}
+
+	write_lock_irqsave(g_lock, flags);
+
+	peer2 = kiblnd_find_peer_locked(nid);
+	if (peer2 != NULL) {
+		if (peer2->ibp_version == 0) {
+			peer2->ibp_version     = version;
+			peer2->ibp_incarnation = reqmsg->ibm_srcstamp;
+		}
+
+		/* not the guy I've talked with */
+		if (peer2->ibp_incarnation != reqmsg->ibm_srcstamp ||
+		    peer2->ibp_version     != version) {
+			kiblnd_close_peer_conns_locked(peer2, -ESTALE);
+			write_unlock_irqrestore(g_lock, flags);
+
+			CWARN("Conn stale %s [old ver: %x, new ver: %x]\n",
+			      libcfs_nid2str(nid), peer2->ibp_version, version);
+
+			kiblnd_peer_decref(peer);
+			rej.ibr_why = IBLND_REJECT_CONN_STALE;
+			goto failed;
+		}
+
+		/* tie-break connection race in favour of the higher NID */
+		if (peer2->ibp_connecting != 0 &&
+		    nid < ni->ni_nid) {
+			write_unlock_irqrestore(g_lock, flags);
+
+			CWARN("Conn race %s\n", libcfs_nid2str(peer2->ibp_nid));
+
+			kiblnd_peer_decref(peer);
+			rej.ibr_why = IBLND_REJECT_CONN_RACE;
+			goto failed;
+		}
+
+		peer2->ibp_accepting++;
+		kiblnd_peer_addref(peer2);
+
+		write_unlock_irqrestore(g_lock, flags);
+		kiblnd_peer_decref(peer);
+		peer = peer2;
+	} else {
+		/* Brand new peer */
+		LASSERT (peer->ibp_accepting == 0);
+		LASSERT (peer->ibp_version == 0 &&
+			 peer->ibp_incarnation == 0);
+
+		peer->ibp_accepting   = 1;
+		peer->ibp_version     = version;
+		peer->ibp_incarnation = reqmsg->ibm_srcstamp;
+
+		/* I have a ref on ni that prevents it being shutdown */
+		LASSERT (net->ibn_shutdown == 0);
+
+		kiblnd_peer_addref(peer);
+		list_add_tail(&peer->ibp_list, kiblnd_nid2peerlist(nid));
+
+		write_unlock_irqrestore(g_lock, flags);
+	}
+
+	conn = kiblnd_create_conn(peer, cmid, IBLND_CONN_PASSIVE_WAIT, version);
+	if (conn == NULL) {
+		kiblnd_peer_connect_failed(peer, 0, -ENOMEM);
+		kiblnd_peer_decref(peer);
+		rej.ibr_why = IBLND_REJECT_NO_RESOURCES;
+		goto failed;
+	}
+
+	/* conn now "owns" cmid, so I return success from here on to ensure the
+	 * CM callback doesn't destroy cmid. */
+
+	conn->ibc_incarnation      = reqmsg->ibm_srcstamp;
+	conn->ibc_credits	  = IBLND_MSG_QUEUE_SIZE(version);
+	conn->ibc_reserved_credits = IBLND_MSG_QUEUE_SIZE(version);
+	LASSERT (conn->ibc_credits + conn->ibc_reserved_credits + IBLND_OOB_MSGS(version)
+		 <= IBLND_RX_MSGS(version));
+
+	ackmsg = &conn->ibc_connvars->cv_msg;
+	memset(ackmsg, 0, sizeof(*ackmsg));
+
+	kiblnd_init_msg(ackmsg, IBLND_MSG_CONNACK,
+			sizeof(ackmsg->ibm_u.connparams));
+	ackmsg->ibm_u.connparams.ibcp_queue_depth  = IBLND_MSG_QUEUE_SIZE(version);
+	ackmsg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
+	ackmsg->ibm_u.connparams.ibcp_max_frags    = IBLND_RDMA_FRAGS(version);
+
+	kiblnd_pack_msg(ni, ackmsg, version, 0, nid, reqmsg->ibm_srcstamp);
+
+	memset(&cp, 0, sizeof(cp));
+	cp.private_data	= ackmsg;
+	cp.private_data_len    = ackmsg->ibm_nob;
+	cp.responder_resources = 0;	     /* No atomic ops or RDMA reads */
+	cp.initiator_depth     = 0;
+	cp.flow_control	= 1;
+	cp.retry_count	 = *kiblnd_tunables.kib_retry_count;
+	cp.rnr_retry_count     = *kiblnd_tunables.kib_rnr_retry_count;
+
+	CDEBUG(D_NET, "Accept %s\n", libcfs_nid2str(nid));
+
+	rc = rdma_accept(cmid, &cp);
+	if (rc != 0) {
+		CERROR("Can't accept %s: %d\n", libcfs_nid2str(nid), rc);
+		rej.ibr_version = version;
+		rej.ibr_why     = IBLND_REJECT_FATAL;
+
+		kiblnd_reject(cmid, &rej);
+		kiblnd_connreq_done(conn, rc);
+		kiblnd_conn_decref(conn);
+	}
+
+	lnet_ni_decref(ni);
+	return 0;
+
+ failed:
+	if (ni != NULL)
+		lnet_ni_decref(ni);
+
+	rej.ibr_version = version;
+	rej.ibr_cp.ibcp_queue_depth = IBLND_MSG_QUEUE_SIZE(version);
+	rej.ibr_cp.ibcp_max_frags   = IBLND_RDMA_FRAGS(version);
+	kiblnd_reject(cmid, &rej);
+
+	return -ECONNREFUSED;
+}
+
+void
+kiblnd_reconnect (kib_conn_t *conn, int version,
+		  __u64 incarnation, int why, kib_connparams_t *cp)
+{
+	kib_peer_t    *peer = conn->ibc_peer;
+	char	  *reason;
+	int	    retry = 0;
+	unsigned long  flags;
+
+	LASSERT (conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT);
+	LASSERT (peer->ibp_connecting > 0);     /* 'conn' at least */
+
+	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	/* retry connection if it's still needed and no other connection
+	 * attempts (active or passive) are in progress
+	 * NB: reconnect is still needed even when ibp_tx_queue is
+	 * empty if ibp_version != version because reconnect may be
+	 * initiated by kiblnd_query() */
+	if ((!list_empty(&peer->ibp_tx_queue) ||
+	     peer->ibp_version != version) &&
+	    peer->ibp_connecting == 1 &&
+	    peer->ibp_accepting == 0) {
+		retry = 1;
+		peer->ibp_connecting++;
+
+		peer->ibp_version     = version;
+		peer->ibp_incarnation = incarnation;
+	}
+
+	write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	if (!retry)
+		return;
+
+	switch (why) {
+	default:
+		reason = "Unknown";
+		break;
+
+	case IBLND_REJECT_CONN_STALE:
+		reason = "stale";
+		break;
+
+	case IBLND_REJECT_CONN_RACE:
+		reason = "conn race";
+		break;
+
+	case IBLND_REJECT_CONN_UNCOMPAT:
+		reason = "version negotiation";
+		break;
+	}
+
+	CNETERR("%s: retrying (%s), %x, %x, "
+		"queue_dep: %d, max_frag: %d, msg_size: %d\n",
+		libcfs_nid2str(peer->ibp_nid),
+		reason, IBLND_MSG_VERSION, version,
+		cp != NULL? cp->ibcp_queue_depth :IBLND_MSG_QUEUE_SIZE(version),
+		cp != NULL? cp->ibcp_max_frags   : IBLND_RDMA_FRAGS(version),
+		cp != NULL? cp->ibcp_max_msg_size: IBLND_MSG_SIZE);
+
+	kiblnd_connect_peer(peer);
+}
+
+void
+kiblnd_rejected (kib_conn_t *conn, int reason, void *priv, int priv_nob)
+{
+	kib_peer_t    *peer = conn->ibc_peer;
+
+	LASSERT (!in_interrupt());
+	LASSERT (conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT);
+
+	switch (reason) {
+	case IB_CM_REJ_STALE_CONN:
+		kiblnd_reconnect(conn, IBLND_MSG_VERSION, 0,
+				 IBLND_REJECT_CONN_STALE, NULL);
+		break;
+
+	case IB_CM_REJ_INVALID_SERVICE_ID:
+		CNETERR("%s rejected: no listener at %d\n",
+			libcfs_nid2str(peer->ibp_nid),
+			*kiblnd_tunables.kib_service);
+		break;
+
+	case IB_CM_REJ_CONSUMER_DEFINED:
+		if (priv_nob >= offsetof(kib_rej_t, ibr_padding)) {
+			kib_rej_t	*rej	 = priv;
+			kib_connparams_t *cp	  = NULL;
+			int	       flip	= 0;
+			__u64	     incarnation = -1;
+
+			/* NB. default incarnation is -1 because:
+			 * a) V1 will ignore dst incarnation in connreq.
+			 * b) V2 will provide incarnation while rejecting me,
+			 *    -1 will be overwrote.
+			 *
+			 * if I try to connect to a V1 peer with V2 protocol,
+			 * it rejected me then upgrade to V2, I have no idea
+			 * about the upgrading and try to reconnect with V1,
+			 * in this case upgraded V2 can find out I'm trying to
+			 * talk to the old guy and reject me(incarnation is -1).
+			 */
+
+			if (rej->ibr_magic == __swab32(IBLND_MSG_MAGIC) ||
+			    rej->ibr_magic == __swab32(LNET_PROTO_MAGIC)) {
+				__swab32s(&rej->ibr_magic);
+				__swab16s(&rej->ibr_version);
+				flip = 1;
+			}
+
+			if (priv_nob >= sizeof(kib_rej_t) &&
+			    rej->ibr_version > IBLND_MSG_VERSION_1) {
+				/* priv_nob is always 148 in current version
+				 * of OFED, so we still need to check version.
+				 * (define of IB_CM_REJ_PRIVATE_DATA_SIZE) */
+				cp = &rej->ibr_cp;
+
+				if (flip) {
+					__swab64s(&rej->ibr_incarnation);
+					__swab16s(&cp->ibcp_queue_depth);
+					__swab16s(&cp->ibcp_max_frags);
+					__swab32s(&cp->ibcp_max_msg_size);
+				}
+
+				incarnation = rej->ibr_incarnation;
+			}
+
+			if (rej->ibr_magic != IBLND_MSG_MAGIC &&
+			    rej->ibr_magic != LNET_PROTO_MAGIC) {
+				CERROR("%s rejected: consumer defined fatal error\n",
+				       libcfs_nid2str(peer->ibp_nid));
+				break;
+			}
+
+			if (rej->ibr_version != IBLND_MSG_VERSION &&
+			    rej->ibr_version != IBLND_MSG_VERSION_1) {
+				CERROR("%s rejected: o2iblnd version %x error\n",
+				       libcfs_nid2str(peer->ibp_nid),
+				       rej->ibr_version);
+				break;
+			}
+
+			if (rej->ibr_why     == IBLND_REJECT_FATAL &&
+			    rej->ibr_version == IBLND_MSG_VERSION_1) {
+				CDEBUG(D_NET, "rejected by old version peer %s: %x\n",
+				       libcfs_nid2str(peer->ibp_nid), rej->ibr_version);
+
+				if (conn->ibc_version != IBLND_MSG_VERSION_1)
+					rej->ibr_why = IBLND_REJECT_CONN_UNCOMPAT;
+			}
+
+			switch (rej->ibr_why) {
+			case IBLND_REJECT_CONN_RACE:
+			case IBLND_REJECT_CONN_STALE:
+			case IBLND_REJECT_CONN_UNCOMPAT:
+				kiblnd_reconnect(conn, rej->ibr_version,
+						 incarnation, rej->ibr_why, cp);
+				break;
+
+			case IBLND_REJECT_MSG_QUEUE_SIZE:
+				CERROR("%s rejected: incompatible message queue depth %d, %d\n",
+				       libcfs_nid2str(peer->ibp_nid), cp->ibcp_queue_depth,
+				       IBLND_MSG_QUEUE_SIZE(conn->ibc_version));
+				break;
+
+			case IBLND_REJECT_RDMA_FRAGS:
+				CERROR("%s rejected: incompatible # of RDMA fragments %d, %d\n",
+				       libcfs_nid2str(peer->ibp_nid), cp->ibcp_max_frags,
+				       IBLND_RDMA_FRAGS(conn->ibc_version));
+				break;
+
+			case IBLND_REJECT_NO_RESOURCES:
+				CERROR("%s rejected: o2iblnd no resources\n",
+				       libcfs_nid2str(peer->ibp_nid));
+				break;
+
+			case IBLND_REJECT_FATAL:
+				CERROR("%s rejected: o2iblnd fatal error\n",
+				       libcfs_nid2str(peer->ibp_nid));
+				break;
+
+			default:
+				CERROR("%s rejected: o2iblnd reason %d\n",
+				       libcfs_nid2str(peer->ibp_nid),
+				       rej->ibr_why);
+				break;
+			}
+			break;
+		}
+		/* fall through */
+	default:
+		CNETERR("%s rejected: reason %d, size %d\n",
+			libcfs_nid2str(peer->ibp_nid), reason, priv_nob);
+		break;
+	}
+
+	kiblnd_connreq_done(conn, -ECONNREFUSED);
+}
+
+void
+kiblnd_check_connreply (kib_conn_t *conn, void *priv, int priv_nob)
+{
+	kib_peer_t    *peer = conn->ibc_peer;
+	lnet_ni_t     *ni   = peer->ibp_ni;
+	kib_net_t     *net  = ni->ni_data;
+	kib_msg_t     *msg  = priv;
+	int	    ver  = conn->ibc_version;
+	int	    rc   = kiblnd_unpack_msg(msg, priv_nob);
+	unsigned long  flags;
+
+	LASSERT (net != NULL);
+
+	if (rc != 0) {
+		CERROR("Can't unpack connack from %s: %d\n",
+		       libcfs_nid2str(peer->ibp_nid), rc);
+		goto failed;
+	}
+
+	if (msg->ibm_type != IBLND_MSG_CONNACK) {
+		CERROR("Unexpected message %d from %s\n",
+		       msg->ibm_type, libcfs_nid2str(peer->ibp_nid));
+		rc = -EPROTO;
+		goto failed;
+	}
+
+	if (ver != msg->ibm_version) {
+		CERROR("%s replied version %x is different with "
+		       "requested version %x\n",
+		       libcfs_nid2str(peer->ibp_nid), msg->ibm_version, ver);
+		rc = -EPROTO;
+		goto failed;
+	}
+
+	if (msg->ibm_u.connparams.ibcp_queue_depth !=
+	    IBLND_MSG_QUEUE_SIZE(ver)) {
+		CERROR("%s has incompatible queue depth %d(%d wanted)\n",
+		       libcfs_nid2str(peer->ibp_nid),
+		       msg->ibm_u.connparams.ibcp_queue_depth,
+		       IBLND_MSG_QUEUE_SIZE(ver));
+		rc = -EPROTO;
+		goto failed;
+	}
+
+	if (msg->ibm_u.connparams.ibcp_max_frags !=
+	    IBLND_RDMA_FRAGS(ver)) {
+		CERROR("%s has incompatible max_frags %d (%d wanted)\n",
+		       libcfs_nid2str(peer->ibp_nid),
+		       msg->ibm_u.connparams.ibcp_max_frags,
+		       IBLND_RDMA_FRAGS(ver));
+		rc = -EPROTO;
+		goto failed;
+	}
+
+	if (msg->ibm_u.connparams.ibcp_max_msg_size > IBLND_MSG_SIZE) {
+		CERROR("%s max message size %d too big (%d max)\n",
+		       libcfs_nid2str(peer->ibp_nid),
+		       msg->ibm_u.connparams.ibcp_max_msg_size,
+		       IBLND_MSG_SIZE);
+		rc = -EPROTO;
+		goto failed;
+	}
+
+	read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+	if (msg->ibm_dstnid == ni->ni_nid &&
+	    msg->ibm_dststamp == net->ibn_incarnation)
+		rc = 0;
+	else
+		rc = -ESTALE;
+	read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	if (rc != 0) {
+		CERROR("Bad connection reply from %s, rc = %d, "
+		       "version: %x max_frags: %d\n",
+		       libcfs_nid2str(peer->ibp_nid), rc,
+		       msg->ibm_version, msg->ibm_u.connparams.ibcp_max_frags);
+		goto failed;
+	}
+
+	conn->ibc_incarnation      = msg->ibm_srcstamp;
+	conn->ibc_credits	  =
+	conn->ibc_reserved_credits = IBLND_MSG_QUEUE_SIZE(ver);
+	LASSERT (conn->ibc_credits + conn->ibc_reserved_credits + IBLND_OOB_MSGS(ver)
+		 <= IBLND_RX_MSGS(ver));
+
+	kiblnd_connreq_done(conn, 0);
+	return;
+
+ failed:
+	/* NB My QP has already established itself, so I handle anything going
+	 * wrong here by setting ibc_comms_error.
+	 * kiblnd_connreq_done(0) moves the conn state to ESTABLISHED, but then
+	 * immediately tears it down. */
+
+	LASSERT (rc != 0);
+	conn->ibc_comms_error = rc;
+	kiblnd_connreq_done(conn, 0);
+}
+
+int
+kiblnd_active_connect (struct rdma_cm_id *cmid)
+{
+	kib_peer_t	      *peer = (kib_peer_t *)cmid->context;
+	kib_conn_t	      *conn;
+	kib_msg_t	       *msg;
+	struct rdma_conn_param   cp;
+	int		      version;
+	__u64		    incarnation;
+	unsigned long	    flags;
+	int		      rc;
+
+	read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	incarnation = peer->ibp_incarnation;
+	version     = (peer->ibp_version == 0) ? IBLND_MSG_VERSION :
+						 peer->ibp_version;
+
+	read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	conn = kiblnd_create_conn(peer, cmid, IBLND_CONN_ACTIVE_CONNECT, version);
+	if (conn == NULL) {
+		kiblnd_peer_connect_failed(peer, 1, -ENOMEM);
+		kiblnd_peer_decref(peer); /* lose cmid's ref */
+		return -ENOMEM;
+	}
+
+	/* conn "owns" cmid now, so I return success from here on to ensure the
+	 * CM callback doesn't destroy cmid. conn also takes over cmid's ref
+	 * on peer */
+
+	msg = &conn->ibc_connvars->cv_msg;
+
+	memset(msg, 0, sizeof(*msg));
+	kiblnd_init_msg(msg, IBLND_MSG_CONNREQ, sizeof(msg->ibm_u.connparams));
+	msg->ibm_u.connparams.ibcp_queue_depth  = IBLND_MSG_QUEUE_SIZE(version);
+	msg->ibm_u.connparams.ibcp_max_frags    = IBLND_RDMA_FRAGS(version);
+	msg->ibm_u.connparams.ibcp_max_msg_size = IBLND_MSG_SIZE;
+
+	kiblnd_pack_msg(peer->ibp_ni, msg, version,
+			0, peer->ibp_nid, incarnation);
+
+	memset(&cp, 0, sizeof(cp));
+	cp.private_data	= msg;
+	cp.private_data_len    = msg->ibm_nob;
+	cp.responder_resources = 0;	     /* No atomic ops or RDMA reads */
+	cp.initiator_depth     = 0;
+	cp.flow_control	= 1;
+	cp.retry_count	 = *kiblnd_tunables.kib_retry_count;
+	cp.rnr_retry_count     = *kiblnd_tunables.kib_rnr_retry_count;
+
+	LASSERT(cmid->context == (void *)conn);
+	LASSERT(conn->ibc_cmid == cmid);
+
+	rc = rdma_connect(cmid, &cp);
+	if (rc != 0) {
+		CERROR("Can't connect to %s: %d\n",
+		       libcfs_nid2str(peer->ibp_nid), rc);
+		kiblnd_connreq_done(conn, rc);
+		kiblnd_conn_decref(conn);
+	}
+
+	return 0;
+}
+
+int
+kiblnd_cm_callback(struct rdma_cm_id *cmid, struct rdma_cm_event *event)
+{
+	kib_peer_t  *peer;
+	kib_conn_t  *conn;
+	int	  rc;
+
+	switch (event->event) {
+	default:
+		CERROR("Unexpected event: %d, status: %d\n",
+		       event->event, event->status);
+		LBUG();
+
+	case RDMA_CM_EVENT_CONNECT_REQUEST:
+		/* destroy cmid on failure */
+		rc = kiblnd_passive_connect(cmid,
+					    (void *)KIBLND_CONN_PARAM(event),
+					    KIBLND_CONN_PARAM_LEN(event));
+		CDEBUG(D_NET, "connreq: %d\n", rc);
+		return rc;
+
+	case RDMA_CM_EVENT_ADDR_ERROR:
+		peer = (kib_peer_t *)cmid->context;
+		CNETERR("%s: ADDR ERROR %d\n",
+		       libcfs_nid2str(peer->ibp_nid), event->status);
+		kiblnd_peer_connect_failed(peer, 1, -EHOSTUNREACH);
+		kiblnd_peer_decref(peer);
+		return -EHOSTUNREACH;      /* rc != 0 destroys cmid */
+
+	case RDMA_CM_EVENT_ADDR_RESOLVED:
+		peer = (kib_peer_t *)cmid->context;
+
+		CDEBUG(D_NET,"%s Addr resolved: %d\n",
+		       libcfs_nid2str(peer->ibp_nid), event->status);
+
+		if (event->status != 0) {
+			CNETERR("Can't resolve address for %s: %d\n",
+				libcfs_nid2str(peer->ibp_nid), event->status);
+			rc = event->status;
+		} else {
+			rc = rdma_resolve_route(
+				cmid, *kiblnd_tunables.kib_timeout * 1000);
+			if (rc == 0)
+				return 0;
+			/* Can't initiate route resolution */
+			CERROR("Can't resolve route for %s: %d\n",
+			       libcfs_nid2str(peer->ibp_nid), rc);
+		}
+		kiblnd_peer_connect_failed(peer, 1, rc);
+		kiblnd_peer_decref(peer);
+		return rc;		      /* rc != 0 destroys cmid */
+
+	case RDMA_CM_EVENT_ROUTE_ERROR:
+		peer = (kib_peer_t *)cmid->context;
+		CNETERR("%s: ROUTE ERROR %d\n",
+			libcfs_nid2str(peer->ibp_nid), event->status);
+		kiblnd_peer_connect_failed(peer, 1, -EHOSTUNREACH);
+		kiblnd_peer_decref(peer);
+		return -EHOSTUNREACH;	   /* rc != 0 destroys cmid */
+
+	case RDMA_CM_EVENT_ROUTE_RESOLVED:
+		peer = (kib_peer_t *)cmid->context;
+		CDEBUG(D_NET,"%s Route resolved: %d\n",
+		       libcfs_nid2str(peer->ibp_nid), event->status);
+
+		if (event->status == 0)
+			return kiblnd_active_connect(cmid);
+
+		CNETERR("Can't resolve route for %s: %d\n",
+		       libcfs_nid2str(peer->ibp_nid), event->status);
+		kiblnd_peer_connect_failed(peer, 1, event->status);
+		kiblnd_peer_decref(peer);
+		return event->status;	   /* rc != 0 destroys cmid */
+
+	case RDMA_CM_EVENT_UNREACHABLE:
+		conn = (kib_conn_t *)cmid->context;
+		LASSERT(conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT ||
+			conn->ibc_state == IBLND_CONN_PASSIVE_WAIT);
+		CNETERR("%s: UNREACHABLE %d\n",
+		       libcfs_nid2str(conn->ibc_peer->ibp_nid), event->status);
+		kiblnd_connreq_done(conn, -ENETDOWN);
+		kiblnd_conn_decref(conn);
+		return 0;
+
+	case RDMA_CM_EVENT_CONNECT_ERROR:
+		conn = (kib_conn_t *)cmid->context;
+		LASSERT(conn->ibc_state == IBLND_CONN_ACTIVE_CONNECT ||
+			conn->ibc_state == IBLND_CONN_PASSIVE_WAIT);
+		CNETERR("%s: CONNECT ERROR %d\n",
+			libcfs_nid2str(conn->ibc_peer->ibp_nid), event->status);
+		kiblnd_connreq_done(conn, -ENOTCONN);
+		kiblnd_conn_decref(conn);
+		return 0;
+
+	case RDMA_CM_EVENT_REJECTED:
+		conn = (kib_conn_t *)cmid->context;
+		switch (conn->ibc_state) {
+		default:
+			LBUG();
+
+		case IBLND_CONN_PASSIVE_WAIT:
+			CERROR ("%s: REJECTED %d\n",
+				libcfs_nid2str(conn->ibc_peer->ibp_nid),
+				event->status);
+			kiblnd_connreq_done(conn, -ECONNRESET);
+			break;
+
+		case IBLND_CONN_ACTIVE_CONNECT:
+			kiblnd_rejected(conn, event->status,
+					(void *)KIBLND_CONN_PARAM(event),
+					KIBLND_CONN_PARAM_LEN(event));
+			break;
+		}
+		kiblnd_conn_decref(conn);
+		return 0;
+
+	case RDMA_CM_EVENT_ESTABLISHED:
+		conn = (kib_conn_t *)cmid->context;
+		switch (conn->ibc_state) {
+		default:
+			LBUG();
+
+		case IBLND_CONN_PASSIVE_WAIT:
+			CDEBUG(D_NET, "ESTABLISHED (passive): %s\n",
+			       libcfs_nid2str(conn->ibc_peer->ibp_nid));
+			kiblnd_connreq_done(conn, 0);
+			break;
+
+		case IBLND_CONN_ACTIVE_CONNECT:
+			CDEBUG(D_NET, "ESTABLISHED(active): %s\n",
+			       libcfs_nid2str(conn->ibc_peer->ibp_nid));
+			kiblnd_check_connreply(conn,
+					       (void *)KIBLND_CONN_PARAM(event),
+					       KIBLND_CONN_PARAM_LEN(event));
+			break;
+		}
+		/* net keeps its ref on conn! */
+		return 0;
+
+	case RDMA_CM_EVENT_TIMEWAIT_EXIT:
+		CDEBUG(D_NET, "Ignore TIMEWAIT_EXIT event\n");
+		return 0;
+	case RDMA_CM_EVENT_DISCONNECTED:
+		conn = (kib_conn_t *)cmid->context;
+		if (conn->ibc_state < IBLND_CONN_ESTABLISHED) {
+			CERROR("%s DISCONNECTED\n",
+			       libcfs_nid2str(conn->ibc_peer->ibp_nid));
+			kiblnd_connreq_done(conn, -ECONNRESET);
+		} else {
+			kiblnd_close_conn(conn, 0);
+		}
+		kiblnd_conn_decref(conn);
+		cmid->context = NULL;
+		return 0;
+
+	case RDMA_CM_EVENT_DEVICE_REMOVAL:
+		LCONSOLE_ERROR_MSG(0x131,
+				   "Received notification of device removal\n"
+				   "Please shutdown LNET to allow this to proceed\n");
+		/* Can't remove network from underneath LNET for now, so I have
+		 * to ignore this */
+		return 0;
+
+	case RDMA_CM_EVENT_ADDR_CHANGE:
+		LCONSOLE_INFO("Physical link changed (eg hca/port)\n");
+		return 0;
+	}
+}
+
+static int
+kiblnd_check_txs_locked(kib_conn_t *conn, struct list_head *txs)
+{
+	kib_tx_t	  *tx;
+	struct list_head	*ttmp;
+
+	list_for_each (ttmp, txs) {
+		tx = list_entry (ttmp, kib_tx_t, tx_list);
+
+		if (txs != &conn->ibc_active_txs) {
+			LASSERT (tx->tx_queued);
+		} else {
+			LASSERT (!tx->tx_queued);
+			LASSERT (tx->tx_waiting || tx->tx_sending != 0);
+		}
+
+		if (cfs_time_aftereq (jiffies, tx->tx_deadline)) {
+			CERROR("Timed out tx: %s, %lu seconds\n",
+			       kiblnd_queue2str(conn, txs),
+			       cfs_duration_sec(jiffies - tx->tx_deadline));
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int
+kiblnd_conn_timed_out_locked(kib_conn_t *conn)
+{
+	return  kiblnd_check_txs_locked(conn, &conn->ibc_tx_queue) ||
+		kiblnd_check_txs_locked(conn, &conn->ibc_tx_noops) ||
+		kiblnd_check_txs_locked(conn, &conn->ibc_tx_queue_rsrvd) ||
+		kiblnd_check_txs_locked(conn, &conn->ibc_tx_queue_nocred) ||
+		kiblnd_check_txs_locked(conn, &conn->ibc_active_txs);
+}
+
+void
+kiblnd_check_conns (int idx)
+{
+	LIST_HEAD (closes);
+	LIST_HEAD (checksends);
+	struct list_head    *peers = &kiblnd_data.kib_peers[idx];
+	struct list_head    *ptmp;
+	kib_peer_t    *peer;
+	kib_conn_t    *conn;
+	struct list_head    *ctmp;
+	unsigned long  flags;
+
+	/* NB. We expect to have a look at all the peers and not find any
+	 * RDMAs to time out, so we just use a shared lock while we
+	 * take a look... */
+	read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
+
+	list_for_each (ptmp, peers) {
+		peer = list_entry (ptmp, kib_peer_t, ibp_list);
+
+		list_for_each (ctmp, &peer->ibp_conns) {
+			int timedout;
+			int sendnoop;
+
+			conn = list_entry(ctmp, kib_conn_t, ibc_list);
+
+			LASSERT (conn->ibc_state == IBLND_CONN_ESTABLISHED);
+
+			spin_lock(&conn->ibc_lock);
+
+			sendnoop = kiblnd_need_noop(conn);
+			timedout = kiblnd_conn_timed_out_locked(conn);
+			if (!sendnoop && !timedout) {
+				spin_unlock(&conn->ibc_lock);
+				continue;
+			}
+
+			if (timedout) {
+				CERROR("Timed out RDMA with %s (%lu): "
+				       "c: %u, oc: %u, rc: %u\n",
+				       libcfs_nid2str(peer->ibp_nid),
+				       cfs_duration_sec(cfs_time_current() -
+							peer->ibp_last_alive),
+				       conn->ibc_credits,
+				       conn->ibc_outstanding_credits,
+				       conn->ibc_reserved_credits);
+				list_add(&conn->ibc_connd_list, &closes);
+			} else {
+				list_add(&conn->ibc_connd_list,
+					     &checksends);
+			}
+			/* +ref for 'closes' or 'checksends' */
+			kiblnd_conn_addref(conn);
+
+			spin_unlock(&conn->ibc_lock);
+		}
+	}
+
+	read_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
+
+	/* Handle timeout by closing the whole
+	 * connection. We can only be sure RDMA activity
+	 * has ceased once the QP has been modified. */
+	while (!list_empty(&closes)) {
+		conn = list_entry(closes.next,
+				      kib_conn_t, ibc_connd_list);
+		list_del(&conn->ibc_connd_list);
+		kiblnd_close_conn(conn, -ETIMEDOUT);
+		kiblnd_conn_decref(conn);
+	}
+
+	/* In case we have enough credits to return via a
+	 * NOOP, but there were no non-blocking tx descs
+	 * free to do it last time... */
+	while (!list_empty(&checksends)) {
+		conn = list_entry(checksends.next,
+				      kib_conn_t, ibc_connd_list);
+		list_del(&conn->ibc_connd_list);
+		kiblnd_check_sends(conn);
+		kiblnd_conn_decref(conn);
+	}
+}
+
+void
+kiblnd_disconnect_conn (kib_conn_t *conn)
+{
+	LASSERT (!in_interrupt());
+	LASSERT (current == kiblnd_data.kib_connd);
+	LASSERT (conn->ibc_state == IBLND_CONN_CLOSING);
+
+	rdma_disconnect(conn->ibc_cmid);
+	kiblnd_finalise_conn(conn);
+
+	kiblnd_peer_notify(conn->ibc_peer);
+}
+
+int
+kiblnd_connd (void *arg)
+{
+	wait_queue_t     wait;
+	unsigned long      flags;
+	kib_conn_t	*conn;
+	int		timeout;
+	int		i;
+	int		dropped_lock;
+	int		peer_index = 0;
+	unsigned long      deadline = jiffies;
+
+	cfs_block_allsigs ();
+
+	init_waitqueue_entry_current (&wait);
+	kiblnd_data.kib_connd = current;
+
+	spin_lock_irqsave(&kiblnd_data.kib_connd_lock, flags);
+
+	while (!kiblnd_data.kib_shutdown) {
+
+		dropped_lock = 0;
+
+		if (!list_empty (&kiblnd_data.kib_connd_zombies)) {
+			conn = list_entry(kiblnd_data. \
+					      kib_connd_zombies.next,
+					      kib_conn_t, ibc_list);
+			list_del(&conn->ibc_list);
+
+			spin_unlock_irqrestore(&kiblnd_data.kib_connd_lock,
+					       flags);
+			dropped_lock = 1;
+
+			kiblnd_destroy_conn(conn);
+
+			spin_lock_irqsave(&kiblnd_data.kib_connd_lock, flags);
+		}
+
+		if (!list_empty(&kiblnd_data.kib_connd_conns)) {
+			conn = list_entry(kiblnd_data.kib_connd_conns.next,
+					      kib_conn_t, ibc_list);
+			list_del(&conn->ibc_list);
+
+			spin_unlock_irqrestore(&kiblnd_data.kib_connd_lock,
+					       flags);
+			dropped_lock = 1;
+
+			kiblnd_disconnect_conn(conn);
+			kiblnd_conn_decref(conn);
+
+			spin_lock_irqsave(&kiblnd_data.kib_connd_lock, flags);
+		}
+
+		/* careful with the jiffy wrap... */
+		timeout = (int)(deadline - jiffies);
+		if (timeout <= 0) {
+			const int n = 4;
+			const int p = 1;
+			int       chunk = kiblnd_data.kib_peer_hash_size;
+
+			spin_unlock_irqrestore(&kiblnd_data.kib_connd_lock, flags);
+			dropped_lock = 1;
+
+			/* Time to check for RDMA timeouts on a few more
+			 * peers: I do checks every 'p' seconds on a
+			 * proportion of the peer table and I need to check
+			 * every connection 'n' times within a timeout
+			 * interval, to ensure I detect a timeout on any
+			 * connection within (n+1)/n times the timeout
+			 * interval. */
+
+			if (*kiblnd_tunables.kib_timeout > n * p)
+				chunk = (chunk * n * p) /
+					*kiblnd_tunables.kib_timeout;
+			if (chunk == 0)
+				chunk = 1;
+
+			for (i = 0; i < chunk; i++) {
+				kiblnd_check_conns(peer_index);
+				peer_index = (peer_index + 1) %
+					     kiblnd_data.kib_peer_hash_size;
+			}
+
+			deadline += p * HZ;
+			spin_lock_irqsave(&kiblnd_data.kib_connd_lock, flags);
+		}
+
+		if (dropped_lock)
+			continue;
+
+		/* Nothing to do for 'timeout'  */
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&kiblnd_data.kib_connd_waitq, &wait);
+		spin_unlock_irqrestore(&kiblnd_data.kib_connd_lock, flags);
+
+		waitq_timedwait(&wait, TASK_INTERRUPTIBLE, timeout);
+
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&kiblnd_data.kib_connd_waitq, &wait);
+		spin_lock_irqsave(&kiblnd_data.kib_connd_lock, flags);
+	}
+
+	spin_unlock_irqrestore(&kiblnd_data.kib_connd_lock, flags);
+
+	kiblnd_thread_fini();
+	return 0;
+}
+
+void
+kiblnd_qp_event(struct ib_event *event, void *arg)
+{
+	kib_conn_t *conn = arg;
+
+	switch (event->event) {
+	case IB_EVENT_COMM_EST:
+		CDEBUG(D_NET, "%s established\n",
+		       libcfs_nid2str(conn->ibc_peer->ibp_nid));
+		return;
+
+	default:
+		CERROR("%s: Async QP event type %d\n",
+		       libcfs_nid2str(conn->ibc_peer->ibp_nid), event->event);
+		return;
+	}
+}
+
+void
+kiblnd_complete (struct ib_wc *wc)
+{
+	switch (kiblnd_wreqid2type(wc->wr_id)) {
+	default:
+		LBUG();
+
+	case IBLND_WID_RDMA:
+		/* We only get RDMA completion notification if it fails.  All
+		 * subsequent work items, including the final SEND will fail
+		 * too.  However we can't print out any more info about the
+		 * failing RDMA because 'tx' might be back on the idle list or
+		 * even reused already if we didn't manage to post all our work
+		 * items */
+		CNETERR("RDMA (tx: %p) failed: %d\n",
+			kiblnd_wreqid2ptr(wc->wr_id), wc->status);
+		return;
+
+	case IBLND_WID_TX:
+		kiblnd_tx_complete(kiblnd_wreqid2ptr(wc->wr_id), wc->status);
+		return;
+
+	case IBLND_WID_RX:
+		kiblnd_rx_complete(kiblnd_wreqid2ptr(wc->wr_id), wc->status,
+				   wc->byte_len);
+		return;
+	}
+}
+
+void
+kiblnd_cq_completion(struct ib_cq *cq, void *arg)
+{
+	/* NB I'm not allowed to schedule this conn once its refcount has
+	 * reached 0.  Since fundamentally I'm racing with scheduler threads
+	 * consuming my CQ I could be called after all completions have
+	 * occurred.  But in this case, ibc_nrx == 0 && ibc_nsends_posted == 0
+	 * and this CQ is about to be destroyed so I NOOP. */
+	kib_conn_t		*conn = (kib_conn_t *)arg;
+	struct kib_sched_info	*sched = conn->ibc_sched;
+	unsigned long		flags;
+
+	LASSERT(cq == conn->ibc_cq);
+
+	spin_lock_irqsave(&sched->ibs_lock, flags);
+
+	conn->ibc_ready = 1;
+
+	if (!conn->ibc_scheduled &&
+	    (conn->ibc_nrx > 0 ||
+	     conn->ibc_nsends_posted > 0)) {
+		kiblnd_conn_addref(conn); /* +1 ref for sched_conns */
+		conn->ibc_scheduled = 1;
+		list_add_tail(&conn->ibc_sched_list, &sched->ibs_conns);
+
+		if (waitqueue_active(&sched->ibs_waitq))
+			wake_up(&sched->ibs_waitq);
+	}
+
+	spin_unlock_irqrestore(&sched->ibs_lock, flags);
+}
+
+void
+kiblnd_cq_event(struct ib_event *event, void *arg)
+{
+	kib_conn_t *conn = arg;
+
+	CERROR("%s: async CQ event type %d\n",
+	       libcfs_nid2str(conn->ibc_peer->ibp_nid), event->event);
+}
+
+int
+kiblnd_scheduler(void *arg)
+{
+	long			id = (long)arg;
+	struct kib_sched_info	*sched;
+	kib_conn_t		*conn;
+	wait_queue_t		wait;
+	unsigned long		flags;
+	struct ib_wc		wc;
+	int			did_something;
+	int			busy_loops = 0;
+	int			rc;
+
+	cfs_block_allsigs();
+
+	init_waitqueue_entry_current(&wait);
+
+	sched = kiblnd_data.kib_scheds[KIB_THREAD_CPT(id)];
+
+	rc = cfs_cpt_bind(lnet_cpt_table(), sched->ibs_cpt);
+	if (rc != 0) {
+		CWARN("Failed to bind on CPT %d, please verify whether "
+		      "all CPUs are healthy and reload modules if necessary, "
+		      "otherwise your system might under risk of low "
+		      "performance\n", sched->ibs_cpt);
+	}
+
+	spin_lock_irqsave(&sched->ibs_lock, flags);
+
+	while (!kiblnd_data.kib_shutdown) {
+		if (busy_loops++ >= IBLND_RESCHED) {
+			spin_unlock_irqrestore(&sched->ibs_lock, flags);
+
+			cond_resched();
+			busy_loops = 0;
+
+			spin_lock_irqsave(&sched->ibs_lock, flags);
+		}
+
+		did_something = 0;
+
+		if (!list_empty(&sched->ibs_conns)) {
+			conn = list_entry(sched->ibs_conns.next,
+					      kib_conn_t, ibc_sched_list);
+			/* take over kib_sched_conns' ref on conn... */
+			LASSERT(conn->ibc_scheduled);
+			list_del(&conn->ibc_sched_list);
+			conn->ibc_ready = 0;
+
+			spin_unlock_irqrestore(&sched->ibs_lock, flags);
+
+			rc = ib_poll_cq(conn->ibc_cq, 1, &wc);
+			if (rc == 0) {
+				rc = ib_req_notify_cq(conn->ibc_cq,
+						      IB_CQ_NEXT_COMP);
+				if (rc < 0) {
+					CWARN("%s: ib_req_notify_cq failed: %d, "
+					      "closing connection\n",
+					      libcfs_nid2str(conn->ibc_peer->ibp_nid), rc);
+					kiblnd_close_conn(conn, -EIO);
+					kiblnd_conn_decref(conn);
+					spin_lock_irqsave(&sched->ibs_lock,
+							      flags);
+					continue;
+				}
+
+				rc = ib_poll_cq(conn->ibc_cq, 1, &wc);
+			}
+
+			if (rc < 0) {
+				CWARN("%s: ib_poll_cq failed: %d, "
+				      "closing connection\n",
+				      libcfs_nid2str(conn->ibc_peer->ibp_nid),
+				      rc);
+				kiblnd_close_conn(conn, -EIO);
+				kiblnd_conn_decref(conn);
+				spin_lock_irqsave(&sched->ibs_lock, flags);
+				continue;
+			}
+
+			spin_lock_irqsave(&sched->ibs_lock, flags);
+
+			if (rc != 0 || conn->ibc_ready) {
+				/* There may be another completion waiting; get
+				 * another scheduler to check while I handle
+				 * this one... */
+				/* +1 ref for sched_conns */
+				kiblnd_conn_addref(conn);
+				list_add_tail(&conn->ibc_sched_list,
+						  &sched->ibs_conns);
+				if (waitqueue_active(&sched->ibs_waitq))
+					wake_up(&sched->ibs_waitq);
+			} else {
+				conn->ibc_scheduled = 0;
+			}
+
+			if (rc != 0) {
+				spin_unlock_irqrestore(&sched->ibs_lock, flags);
+				kiblnd_complete(&wc);
+
+				spin_lock_irqsave(&sched->ibs_lock, flags);
+			}
+
+			kiblnd_conn_decref(conn); /* ...drop my ref from above */
+			did_something = 1;
+		}
+
+		if (did_something)
+			continue;
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue_exclusive(&sched->ibs_waitq, &wait);
+		spin_unlock_irqrestore(&sched->ibs_lock, flags);
+
+		waitq_wait(&wait, TASK_INTERRUPTIBLE);
+		busy_loops = 0;
+
+		remove_wait_queue(&sched->ibs_waitq, &wait);
+		set_current_state(TASK_RUNNING);
+		spin_lock_irqsave(&sched->ibs_lock, flags);
+	}
+
+	spin_unlock_irqrestore(&sched->ibs_lock, flags);
+
+	kiblnd_thread_fini();
+	return 0;
+}
+
+int
+kiblnd_failover_thread(void *arg)
+{
+	rwlock_t		*glock = &kiblnd_data.kib_global_lock;
+	kib_dev_t	 *dev;
+	wait_queue_t     wait;
+	unsigned long      flags;
+	int		rc;
+
+	LASSERT (*kiblnd_tunables.kib_dev_failover != 0);
+
+	cfs_block_allsigs ();
+
+	init_waitqueue_entry_current(&wait);
+	write_lock_irqsave(glock, flags);
+
+	while (!kiblnd_data.kib_shutdown) {
+		int     do_failover = 0;
+		int     long_sleep;
+
+		list_for_each_entry(dev, &kiblnd_data.kib_failed_devs,
+				    ibd_fail_list) {
+			if (cfs_time_before(cfs_time_current(),
+					    dev->ibd_next_failover))
+				continue;
+			do_failover = 1;
+			break;
+		}
+
+		if (do_failover) {
+			list_del_init(&dev->ibd_fail_list);
+			dev->ibd_failover = 1;
+			write_unlock_irqrestore(glock, flags);
+
+			rc = kiblnd_dev_failover(dev);
+
+			write_lock_irqsave(glock, flags);
+
+			LASSERT (dev->ibd_failover);
+			dev->ibd_failover = 0;
+			if (rc >= 0) { /* Device is OK or failover succeed */
+				dev->ibd_next_failover = cfs_time_shift(3);
+				continue;
+			}
+
+			/* failed to failover, retry later */
+			dev->ibd_next_failover =
+				cfs_time_shift(min(dev->ibd_failed_failover, 10));
+			if (kiblnd_dev_can_failover(dev)) {
+				list_add_tail(&dev->ibd_fail_list,
+					      &kiblnd_data.kib_failed_devs);
+			}
+
+			continue;
+		}
+
+		/* long sleep if no more pending failover */
+		long_sleep = list_empty(&kiblnd_data.kib_failed_devs);
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue(&kiblnd_data.kib_failover_waitq, &wait);
+		write_unlock_irqrestore(glock, flags);
+
+		rc = schedule_timeout(long_sleep ? cfs_time_seconds(10) :
+						   cfs_time_seconds(1));
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&kiblnd_data.kib_failover_waitq, &wait);
+		write_lock_irqsave(glock, flags);
+
+		if (!long_sleep || rc != 0)
+			continue;
+
+		/* have a long sleep, routine check all active devices,
+		 * we need checking like this because if there is not active
+		 * connection on the dev and no SEND from local, we may listen
+		 * on wrong HCA for ever while there is a bonding failover */
+		list_for_each_entry(dev, &kiblnd_data.kib_devs, ibd_list) {
+			if (kiblnd_dev_can_failover(dev)) {
+				list_add_tail(&dev->ibd_fail_list,
+					      &kiblnd_data.kib_failed_devs);
+			}
+		}
+	}
+
+	write_unlock_irqrestore(glock, flags);
+
+	kiblnd_thread_fini();
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1057 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/klnds/o2iblnd/o2iblnd.h
+ *
+ * Author: Eric Barton <eric@bartonsoftware.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/uio.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/list.h>
+#include <linux/kmod.h>
+#include <linux/sysctl.h>
+#include <linux/pci.h>
+
+#include <net/sock.h>
+#include <linux/in.h>
+
+#define DEBUG_SUBSYSTEM S_LND
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lnet.h>
+#include <linux/lnet/lib-lnet.h>
+#include <linux/lnet/lnet-sysctl.h>
+
+#include <rdma/rdma_cm.h>
+#include <rdma/ib_cm.h>
+#include <rdma/ib_verbs.h>
+#include <rdma/ib_fmr_pool.h>
+
+#define IBLND_PEER_HASH_SIZE		101	/* # peer lists */
+/* # scheduler loops before reschedule */
+#define IBLND_RESCHED			100
+
+#define IBLND_N_SCHED			2
+#define IBLND_N_SCHED_HIGH		4
+
+typedef struct
+{
+	int	      *kib_dev_failover;     /* HCA failover */
+	unsigned int     *kib_service;	  /* IB service number */
+	int	      *kib_min_reconnect_interval; /* first failed connection retry... */
+	int	      *kib_max_reconnect_interval; /* ...exponentially increasing to this */
+	int	      *kib_cksum;	    /* checksum kib_msg_t? */
+	int	      *kib_timeout;	  /* comms timeout (seconds) */
+	int	      *kib_keepalive;	/* keepalive timeout (seconds) */
+	int	      *kib_ntx;	      /* # tx descs */
+	int	      *kib_credits;	  /* # concurrent sends */
+	int	      *kib_peertxcredits;    /* # concurrent sends to 1 peer */
+	int	      *kib_peerrtrcredits;   /* # per-peer router buffer credits */
+	int	      *kib_peercredits_hiw;  /* # when eagerly to return credits */
+	int	      *kib_peertimeout;      /* seconds to consider peer dead */
+	char	    **kib_default_ipif;     /* default IPoIB interface */
+	int	      *kib_retry_count;
+	int	      *kib_rnr_retry_count;
+	int	      *kib_concurrent_sends; /* send work queue sizing */
+	int		 *kib_ib_mtu;		/* IB MTU */
+	int	      *kib_map_on_demand;    /* map-on-demand if RD has more fragments
+						 * than this value, 0 disable map-on-demand */
+	int	      *kib_pmr_pool_size;    /* # physical MR in pool */
+	int	      *kib_fmr_pool_size;    /* # FMRs in pool */
+	int	      *kib_fmr_flush_trigger; /* When to trigger FMR flush */
+	int	      *kib_fmr_cache;	/* enable FMR pool cache? */
+#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
+	ctl_table_header_t *kib_sysctl;  /* sysctl interface */
+#endif
+	int	      *kib_require_priv_port;/* accept only privileged ports */
+	int	      *kib_use_priv_port;    /* use privileged port for active connect */
+	/* # threads on each CPT */
+	int		 *kib_nscheds;
+} kib_tunables_t;
+
+extern kib_tunables_t  kiblnd_tunables;
+
+#define IBLND_MSG_QUEUE_SIZE_V1      8	  /* V1 only : # messages/RDMAs in-flight */
+#define IBLND_CREDIT_HIGHWATER_V1    7	  /* V1 only : when eagerly to return credits */
+
+#define IBLND_CREDITS_DEFAULT	8	  /* default # of peer credits */
+#define IBLND_CREDITS_MAX	  ((typeof(((kib_msg_t*) 0)->ibm_credits)) - 1)  /* Max # of peer credits */
+
+#define IBLND_MSG_QUEUE_SIZE(v)    ((v) == IBLND_MSG_VERSION_1 ? \
+				     IBLND_MSG_QUEUE_SIZE_V1 :   \
+				     *kiblnd_tunables.kib_peertxcredits) /* # messages/RDMAs in-flight */
+#define IBLND_CREDITS_HIGHWATER(v) ((v) == IBLND_MSG_VERSION_1 ? \
+				     IBLND_CREDIT_HIGHWATER_V1 : \
+				     *kiblnd_tunables.kib_peercredits_hiw) /* when eagerly to return credits */
+
+#define kiblnd_rdma_create_id(cb, dev, ps, qpt) rdma_create_id(cb, dev, ps, qpt)
+
+static inline int
+kiblnd_concurrent_sends_v1(void)
+{
+	if (*kiblnd_tunables.kib_concurrent_sends > IBLND_MSG_QUEUE_SIZE_V1 * 2)
+		return IBLND_MSG_QUEUE_SIZE_V1 * 2;
+
+	if (*kiblnd_tunables.kib_concurrent_sends < IBLND_MSG_QUEUE_SIZE_V1 / 2)
+		return IBLND_MSG_QUEUE_SIZE_V1 / 2;
+
+	return *kiblnd_tunables.kib_concurrent_sends;
+}
+
+#define IBLND_CONCURRENT_SENDS(v)  ((v) == IBLND_MSG_VERSION_1 ? \
+				     kiblnd_concurrent_sends_v1() : \
+				     *kiblnd_tunables.kib_concurrent_sends)
+/* 2 OOB shall suffice for 1 keepalive and 1 returning credits */
+#define IBLND_OOB_CAPABLE(v)       ((v) != IBLND_MSG_VERSION_1)
+#define IBLND_OOB_MSGS(v)	   (IBLND_OOB_CAPABLE(v) ? 2 : 0)
+
+#define IBLND_MSG_SIZE	      (4<<10)		 /* max size of queued messages (inc hdr) */
+#define IBLND_MAX_RDMA_FRAGS	 LNET_MAX_IOV	   /* max # of fragments supported */
+#define IBLND_CFG_RDMA_FRAGS       (*kiblnd_tunables.kib_map_on_demand != 0 ? \
+				    *kiblnd_tunables.kib_map_on_demand :      \
+				     IBLND_MAX_RDMA_FRAGS)  /* max # of fragments configured by user */
+#define IBLND_RDMA_FRAGS(v)	((v) == IBLND_MSG_VERSION_1 ? \
+				     IBLND_MAX_RDMA_FRAGS : IBLND_CFG_RDMA_FRAGS)
+
+/************************/
+/* derived constants... */
+/* Pools (shared by connections on each CPT) */
+/* These pools can grow at runtime, so don't need give a very large value */
+#define IBLND_TX_POOL			256
+#define IBLND_PMR_POOL			256
+#define IBLND_FMR_POOL			256
+#define IBLND_FMR_POOL_FLUSH		192
+
+/* TX messages (shared by all connections) */
+#define IBLND_TX_MSGS()	    (*kiblnd_tunables.kib_ntx)
+
+/* RX messages (per connection) */
+#define IBLND_RX_MSGS(v)	    (IBLND_MSG_QUEUE_SIZE(v) * 2 + IBLND_OOB_MSGS(v))
+#define IBLND_RX_MSG_BYTES(v)       (IBLND_RX_MSGS(v) * IBLND_MSG_SIZE)
+#define IBLND_RX_MSG_PAGES(v)      ((IBLND_RX_MSG_BYTES(v) + PAGE_SIZE - 1) / PAGE_SIZE)
+
+/* WRs and CQEs (per connection) */
+#define IBLND_RECV_WRS(v)	    IBLND_RX_MSGS(v)
+#define IBLND_SEND_WRS(v)	  ((IBLND_RDMA_FRAGS(v) + 1) * IBLND_CONCURRENT_SENDS(v))
+#define IBLND_CQ_ENTRIES(v)	 (IBLND_RECV_WRS(v) + IBLND_SEND_WRS(v))
+
+struct kib_hca_dev;
+
+/* o2iblnd can run over aliased interface */
+#ifdef IFALIASZ
+#define KIB_IFNAME_SIZE	      IFALIASZ
+#else
+#define KIB_IFNAME_SIZE	      256
+#endif
+
+typedef struct
+{
+	struct list_head	   ibd_list;	  /* chain on kib_devs */
+	struct list_head	   ibd_fail_list;     /* chain on kib_failed_devs */
+	__u32		ibd_ifip;	  /* IPoIB interface IP */
+	/** IPoIB interface name */
+	char		 ibd_ifname[KIB_IFNAME_SIZE];
+	int		  ibd_nnets;	 /* # nets extant */
+
+	cfs_time_t	   ibd_next_failover;
+	int		  ibd_failed_failover; /* # failover failures */
+	unsigned int	 ibd_failover;      /* failover in progress */
+	unsigned int	 ibd_can_failover;  /* IPoIB interface is a bonding master */
+	struct list_head	   ibd_nets;
+	struct kib_hca_dev  *ibd_hdev;
+} kib_dev_t;
+
+typedef struct kib_hca_dev
+{
+	struct rdma_cm_id   *ibh_cmid;	  /* listener cmid */
+	struct ib_device    *ibh_ibdev;	 /* IB device */
+	int		  ibh_page_shift;    /* page shift of current HCA */
+	int		  ibh_page_size;     /* page size of current HCA */
+	__u64		ibh_page_mask;     /* page mask of current HCA */
+	int		  ibh_mr_shift;      /* bits shift of max MR size */
+	__u64		ibh_mr_size;       /* size of MR */
+	int		  ibh_nmrs;	  /* # of global MRs */
+	struct ib_mr       **ibh_mrs;	   /* global MR */
+	struct ib_pd	*ibh_pd;	    /* PD */
+	kib_dev_t	   *ibh_dev;	   /* owner */
+	atomic_t	 ibh_ref;	   /* refcount */
+} kib_hca_dev_t;
+
+/** # of seconds to keep pool alive */
+#define IBLND_POOL_DEADLINE     300
+/** # of seconds to retry if allocation failed */
+#define IBLND_POOL_RETRY	1
+
+typedef struct
+{
+	int		     ibp_npages;	     /* # pages */
+	struct page	    *ibp_pages[0];	   /* page array */
+} kib_pages_t;
+
+struct kib_pmr_pool;
+
+typedef struct {
+	struct list_head	      pmr_list;	       /* chain node */
+	struct ib_phys_buf     *pmr_ipb;		/* physical buffer */
+	struct ib_mr	   *pmr_mr;		 /* IB MR */
+	struct kib_pmr_pool    *pmr_pool;	       /* owner of this MR */
+	__u64		   pmr_iova;	       /* Virtual I/O address */
+	int		     pmr_refcount;	   /* reference count */
+} kib_phys_mr_t;
+
+struct kib_pool;
+struct kib_poolset;
+
+typedef int  (*kib_ps_pool_create_t)(struct kib_poolset *ps,
+				     int inc, struct kib_pool **pp_po);
+typedef void (*kib_ps_pool_destroy_t)(struct kib_pool *po);
+typedef void (*kib_ps_node_init_t)(struct kib_pool *po, struct list_head *node);
+typedef void (*kib_ps_node_fini_t)(struct kib_pool *po, struct list_head *node);
+
+struct kib_net;
+
+#define IBLND_POOL_NAME_LEN     32
+
+typedef struct kib_poolset
+{
+	spinlock_t		ps_lock;		/* serialize */
+	struct kib_net	 *ps_net;		 /* network it belongs to */
+	char		    ps_name[IBLND_POOL_NAME_LEN]; /* pool set name */
+	struct list_head	      ps_pool_list;	   /* list of pools */
+	struct list_head	      ps_failed_pool_list;    /* failed pool list */
+	cfs_time_t	      ps_next_retry;	  /* time stamp for retry if failed to allocate */
+	int		     ps_increasing;	  /* is allocating new pool */
+	int		     ps_pool_size;	   /* new pool size */
+	int			ps_cpt;			/* CPT id */
+
+	kib_ps_pool_create_t    ps_pool_create;	 /* create a new pool */
+	kib_ps_pool_destroy_t   ps_pool_destroy;	/* destroy a pool */
+	kib_ps_node_init_t      ps_node_init;	   /* initialize new allocated node */
+	kib_ps_node_fini_t      ps_node_fini;	   /* finalize node */
+} kib_poolset_t;
+
+typedef struct kib_pool
+{
+	struct list_head	      po_list;		/* chain on pool list */
+	struct list_head	      po_free_list;	   /* pre-allocated node */
+	kib_poolset_t	  *po_owner;	       /* pool_set of this pool */
+	cfs_time_t	      po_deadline;	    /* deadline of this pool */
+	int		     po_allocated;	   /* # of elements in use */
+	int		     po_failed;	      /* pool is created on failed HCA */
+	int		     po_size;		/* # of pre-allocated elements */
+} kib_pool_t;
+
+typedef struct {
+	kib_poolset_t	   tps_poolset;	    /* pool-set */
+	__u64		   tps_next_tx_cookie;     /* cookie of TX */
+} kib_tx_poolset_t;
+
+typedef struct {
+	kib_pool_t	      tpo_pool;	       /* pool */
+	struct kib_hca_dev     *tpo_hdev;	       /* device for this pool */
+	struct kib_tx	  *tpo_tx_descs;	   /* all the tx descriptors */
+	kib_pages_t	    *tpo_tx_pages;	   /* premapped tx msg pages */
+} kib_tx_pool_t;
+
+typedef struct {
+	kib_poolset_t	   pps_poolset;	    /* pool-set */
+} kib_pmr_poolset_t;
+
+typedef struct kib_pmr_pool {
+	struct kib_hca_dev     *ppo_hdev;	       /* device for this pool */
+	kib_pool_t	      ppo_pool;	       /* pool */
+} kib_pmr_pool_t;
+
+typedef struct
+{
+	spinlock_t		fps_lock;		/* serialize */
+	struct kib_net	 *fps_net;		/* IB network */
+	struct list_head	      fps_pool_list;	  /* FMR pool list */
+	struct list_head	      fps_failed_pool_list;   /* FMR pool list */
+	__u64		   fps_version;	    /* validity stamp */
+	int			fps_cpt;		/* CPT id */
+	int			fps_pool_size;
+	int			fps_flush_trigger;
+	/* is allocating new pool */
+	int			fps_increasing;
+	/* time stamp for retry if failed to allocate */
+	cfs_time_t		fps_next_retry;
+} kib_fmr_poolset_t;
+
+typedef struct
+{
+	struct list_head	      fpo_list;	       /* chain on pool list */
+	struct kib_hca_dev     *fpo_hdev;	       /* device for this pool */
+	kib_fmr_poolset_t      *fpo_owner;	      /* owner of this pool */
+	struct ib_fmr_pool     *fpo_fmr_pool;	   /* IB FMR pool */
+	cfs_time_t	      fpo_deadline;	   /* deadline of this pool */
+	int		     fpo_failed;	     /* fmr pool is failed */
+	int		     fpo_map_count;	  /* # of mapped FMR */
+} kib_fmr_pool_t;
+
+typedef struct {
+	struct ib_pool_fmr     *fmr_pfmr;	       /* IB pool fmr */
+	kib_fmr_pool_t	 *fmr_pool;	       /* pool of FMR */
+} kib_fmr_t;
+
+typedef struct kib_net
+{
+	struct list_head	   ibn_list;	  /* chain on kib_dev_t::ibd_nets */
+	__u64		ibn_incarnation;   /* my epoch */
+	int		  ibn_init;	  /* initialisation state */
+	int		  ibn_shutdown;      /* shutting down? */
+
+	atomic_t		ibn_npeers;	/* # peers extant */
+	atomic_t		ibn_nconns;	/* # connections extant */
+
+	kib_tx_poolset_t	**ibn_tx_ps;	/* tx pool-set */
+	kib_fmr_poolset_t	**ibn_fmr_ps;	/* fmr pool-set */
+	kib_pmr_poolset_t	**ibn_pmr_ps;	/* pmr pool-set */
+
+	kib_dev_t		*ibn_dev;	/* underlying IB device */
+} kib_net_t;
+
+#define KIB_THREAD_SHIFT		16
+#define KIB_THREAD_ID(cpt, tid)		((cpt) << KIB_THREAD_SHIFT | (tid))
+#define KIB_THREAD_CPT(id)		((id) >> KIB_THREAD_SHIFT)
+#define KIB_THREAD_TID(id)		((id) & ((1UL << KIB_THREAD_SHIFT) - 1))
+
+struct kib_sched_info {
+	/* serialise */
+	spinlock_t		ibs_lock;
+	/* schedulers sleep here */
+	wait_queue_head_t		ibs_waitq;
+	/* conns to check for rx completions */
+	struct list_head		ibs_conns;
+	/* number of scheduler threads */
+	int			ibs_nthreads;
+	/* max allowed scheduler threads */
+	int			ibs_nthreads_max;
+	int			ibs_cpt;	/* CPT id */
+};
+
+typedef struct
+{
+	int			kib_init;	/* initialisation state */
+	int			kib_shutdown;	/* shut down? */
+	struct list_head		kib_devs;	/* IB devices extant */
+	/* list head of failed devices */
+	struct list_head		kib_failed_devs;
+	/* schedulers sleep here */
+	wait_queue_head_t		kib_failover_waitq;
+	atomic_t		kib_nthreads;	/* # live threads */
+	/* stabilize net/dev/peer/conn ops */
+	rwlock_t		kib_global_lock;
+	/* hash table of all my known peers */
+	struct list_head		*kib_peers;
+	/* size of kib_peers */
+	int			kib_peer_hash_size;
+	/* the connd task (serialisation assertions) */
+	void			*kib_connd;
+	/* connections to setup/teardown */
+	struct list_head		kib_connd_conns;
+	/* connections with zero refcount */
+	struct list_head		kib_connd_zombies;
+	/* connection daemon sleeps here */
+	wait_queue_head_t		kib_connd_waitq;
+	spinlock_t		kib_connd_lock;	/* serialise */
+	struct ib_qp_attr	kib_error_qpa;	/* QP->ERROR */
+	/* percpt data for schedulers */
+	struct kib_sched_info	**kib_scheds;
+} kib_data_t;
+
+#define IBLND_INIT_NOTHING	 0
+#define IBLND_INIT_DATA	    1
+#define IBLND_INIT_ALL	     2
+
+/************************************************************************
+ * IB Wire message format.
+ * These are sent in sender's byte order (i.e. receiver flips).
+ */
+
+typedef struct kib_connparams
+{
+	__u16	     ibcp_queue_depth;
+	__u16	     ibcp_max_frags;
+	__u32	     ibcp_max_msg_size;
+} WIRE_ATTR kib_connparams_t;
+
+typedef struct
+{
+	lnet_hdr_t	ibim_hdr;	     /* portals header */
+	char	      ibim_payload[0];      /* piggy-backed payload */
+} WIRE_ATTR kib_immediate_msg_t;
+
+typedef struct
+{
+	__u32	     rf_nob;	       /* # bytes this frag */
+	__u64	     rf_addr;	      /* CAVEAT EMPTOR: misaligned!! */
+} WIRE_ATTR kib_rdma_frag_t;
+
+typedef struct
+{
+	__u32	     rd_key;	       /* local/remote key */
+	__u32	     rd_nfrags;	    /* # fragments */
+	kib_rdma_frag_t   rd_frags[0];	  /* buffer frags */
+} WIRE_ATTR kib_rdma_desc_t;
+
+typedef struct
+{
+	lnet_hdr_t	ibprm_hdr;	    /* portals header */
+	__u64	     ibprm_cookie;	 /* opaque completion cookie */
+} WIRE_ATTR kib_putreq_msg_t;
+
+typedef struct
+{
+	__u64	     ibpam_src_cookie;     /* reflected completion cookie */
+	__u64	     ibpam_dst_cookie;     /* opaque completion cookie */
+	kib_rdma_desc_t   ibpam_rd;	     /* sender's sink buffer */
+} WIRE_ATTR kib_putack_msg_t;
+
+typedef struct
+{
+	lnet_hdr_t	ibgm_hdr;	     /* portals header */
+	__u64	     ibgm_cookie;	  /* opaque completion cookie */
+	kib_rdma_desc_t   ibgm_rd;	      /* rdma descriptor */
+} WIRE_ATTR kib_get_msg_t;
+
+typedef struct
+{
+	__u64	     ibcm_cookie;	  /* opaque completion cookie */
+	__s32	     ibcm_status;	  /* < 0 failure: >= 0 length */
+} WIRE_ATTR kib_completion_msg_t;
+
+typedef struct
+{
+	/* First 2 fields fixed FOR ALL TIME */
+	__u32	     ibm_magic;	    /* I'm an ibnal message */
+	__u16	     ibm_version;	  /* this is my version number */
+
+	__u8	      ibm_type;	     /* msg type */
+	__u8	      ibm_credits;	  /* returned credits */
+	__u32	     ibm_nob;	      /* # bytes in whole message */
+	__u32	     ibm_cksum;	    /* checksum (0 == no checksum) */
+	__u64	     ibm_srcnid;	   /* sender's NID */
+	__u64	     ibm_srcstamp;	 /* sender's incarnation */
+	__u64	     ibm_dstnid;	   /* destination's NID */
+	__u64	     ibm_dststamp;	 /* destination's incarnation */
+
+	union {
+		kib_connparams_t      connparams;
+		kib_immediate_msg_t   immediate;
+		kib_putreq_msg_t      putreq;
+		kib_putack_msg_t      putack;
+		kib_get_msg_t	 get;
+		kib_completion_msg_t  completion;
+	} WIRE_ATTR ibm_u;
+} WIRE_ATTR kib_msg_t;
+
+#define IBLND_MSG_MAGIC LNET_PROTO_IB_MAGIC	/* unique magic */
+
+#define IBLND_MSG_VERSION_1	 0x11
+#define IBLND_MSG_VERSION_2	 0x12
+#define IBLND_MSG_VERSION	   IBLND_MSG_VERSION_2
+
+#define IBLND_MSG_CONNREQ	   0xc0	/* connection request */
+#define IBLND_MSG_CONNACK	   0xc1	/* connection acknowledge */
+#define IBLND_MSG_NOOP	      0xd0	/* nothing (just credits) */
+#define IBLND_MSG_IMMEDIATE	 0xd1	/* immediate */
+#define IBLND_MSG_PUT_REQ	   0xd2	/* putreq (src->sink) */
+#define IBLND_MSG_PUT_NAK	   0xd3	/* completion (sink->src) */
+#define IBLND_MSG_PUT_ACK	   0xd4	/* putack (sink->src) */
+#define IBLND_MSG_PUT_DONE	  0xd5	/* completion (src->sink) */
+#define IBLND_MSG_GET_REQ	   0xd6	/* getreq (sink->src) */
+#define IBLND_MSG_GET_DONE	  0xd7	/* completion (src->sink: all OK) */
+
+typedef struct {
+	__u32	    ibr_magic;	     /* sender's magic */
+	__u16	    ibr_version;	   /* sender's version */
+	__u8	     ibr_why;	       /* reject reason */
+	__u8	     ibr_padding;	   /* padding */
+	__u64	    ibr_incarnation;       /* incarnation of peer */
+	kib_connparams_t ibr_cp;		/* connection parameters */
+} WIRE_ATTR kib_rej_t;
+
+/* connection rejection reasons */
+#define IBLND_REJECT_CONN_RACE       1	  /* You lost connection race */
+#define IBLND_REJECT_NO_RESOURCES    2	  /* Out of memory/conns etc */
+#define IBLND_REJECT_FATAL	   3	  /* Anything else */
+
+#define IBLND_REJECT_CONN_UNCOMPAT   4	  /* incompatible version peer */
+#define IBLND_REJECT_CONN_STALE      5	  /* stale peer */
+
+#define IBLND_REJECT_RDMA_FRAGS      6	  /* Fatal: peer's rdma frags can't match mine */
+#define IBLND_REJECT_MSG_QUEUE_SIZE  7	  /* Fatal: peer's msg queue size can't match mine */
+
+/***********************************************************************/
+
+typedef struct kib_rx			   /* receive message */
+{
+	struct list_head		rx_list;      /* queue for attention */
+	struct kib_conn	  *rx_conn;      /* owning conn */
+	int		       rx_nob;       /* # bytes received (-1 while posted) */
+	enum ib_wc_status	 rx_status;    /* completion status */
+	kib_msg_t		*rx_msg;       /* message buffer (host vaddr) */
+	__u64		     rx_msgaddr;   /* message buffer (I/O addr) */
+	DECLARE_PCI_UNMAP_ADDR   (rx_msgunmap); /* for dma_unmap_single() */
+	struct ib_recv_wr	 rx_wrq;       /* receive work item... */
+	struct ib_sge	     rx_sge;       /* ...and its memory */
+} kib_rx_t;
+
+#define IBLND_POSTRX_DONT_POST    0	     /* don't post */
+#define IBLND_POSTRX_NO_CREDIT    1	     /* post: no credits */
+#define IBLND_POSTRX_PEER_CREDIT  2	     /* post: give peer back 1 credit */
+#define IBLND_POSTRX_RSRVD_CREDIT 3	     /* post: give myself back 1 reserved credit */
+
+typedef struct kib_tx			   /* transmit message */
+{
+	struct list_head		tx_list;      /* queue on idle_txs ibc_tx_queue etc. */
+	kib_tx_pool_t	    *tx_pool;      /* pool I'm from */
+	struct kib_conn	  *tx_conn;      /* owning conn */
+	short		     tx_sending;   /* # tx callbacks outstanding */
+	short		     tx_queued;    /* queued for sending */
+	short		     tx_waiting;   /* waiting for peer */
+	int		       tx_status;    /* LNET completion status */
+	unsigned long	     tx_deadline;  /* completion deadline */
+	__u64		     tx_cookie;    /* completion cookie */
+	lnet_msg_t	       *tx_lntmsg[2]; /* lnet msgs to finalize on completion */
+	kib_msg_t		*tx_msg;       /* message buffer (host vaddr) */
+	__u64		     tx_msgaddr;   /* message buffer (I/O addr) */
+	DECLARE_PCI_UNMAP_ADDR   (tx_msgunmap); /* for dma_unmap_single() */
+	int		       tx_nwrq;      /* # send work items */
+	struct ib_send_wr	*tx_wrq;       /* send work items... */
+	struct ib_sge	    *tx_sge;       /* ...and their memory */
+	kib_rdma_desc_t	  *tx_rd;	/* rdma descriptor */
+	int		       tx_nfrags;    /* # entries in... */
+	struct scatterlist       *tx_frags;     /* dma_map_sg descriptor */
+	__u64		    *tx_pages;     /* rdma phys page addrs */
+	union {
+		kib_phys_mr_t      *pmr;	/* MR for physical buffer */
+		kib_fmr_t	   fmr;	/* FMR */
+	}			 tx_u;
+	int		       tx_dmadir;    /* dma direction */
+} kib_tx_t;
+
+typedef struct kib_connvars
+{
+	/* connection-in-progress variables */
+	kib_msg_t		 cv_msg;
+} kib_connvars_t;
+
+typedef struct kib_conn
+{
+	struct kib_sched_info *ibc_sched;	/* scheduler information */
+	struct kib_peer     *ibc_peer;	  /* owning peer */
+	kib_hca_dev_t       *ibc_hdev;	  /* HCA bound on */
+	struct list_head	   ibc_list;	  /* stash on peer's conn list */
+	struct list_head	   ibc_sched_list;    /* schedule for attention */
+	__u16		ibc_version;       /* version of connection */
+	__u64		ibc_incarnation;   /* which instance of the peer */
+	atomic_t	 ibc_refcount;      /* # users */
+	int		  ibc_state;	 /* what's happening */
+	int		  ibc_nsends_posted; /* # uncompleted sends */
+	int		  ibc_noops_posted;  /* # uncompleted NOOPs */
+	int		  ibc_credits;       /* # credits I have */
+	int		  ibc_outstanding_credits; /* # credits to return */
+	int		  ibc_reserved_credits;/* # ACK/DONE msg credits */
+	int		  ibc_comms_error;   /* set on comms error */
+	unsigned int	     ibc_nrx:16;	/* receive buffers owned */
+	unsigned int	     ibc_scheduled:1;   /* scheduled for attention */
+	unsigned int	     ibc_ready:1;       /* CQ callback fired */
+	/* time of last send */
+	unsigned long	ibc_last_send;
+	/** link chain for kiblnd_check_conns only */
+	struct list_head	   ibc_connd_list;
+	/** rxs completed before ESTABLISHED */
+	struct list_head	   ibc_early_rxs;
+	/** IBLND_MSG_NOOPs for IBLND_MSG_VERSION_1 */
+	struct list_head	   ibc_tx_noops;
+	struct list_head	   ibc_tx_queue;       /* sends that need a credit */
+	struct list_head	   ibc_tx_queue_nocred;/* sends that don't need a credit */
+	struct list_head	   ibc_tx_queue_rsrvd; /* sends that need to reserve an ACK/DONE msg */
+	struct list_head	   ibc_active_txs;     /* active tx awaiting completion */
+	spinlock_t	     ibc_lock;		 /* serialise */
+	kib_rx_t	    *ibc_rxs;	    /* the rx descs */
+	kib_pages_t	 *ibc_rx_pages;       /* premapped rx msg pages */
+
+	struct rdma_cm_id   *ibc_cmid;	   /* CM id */
+	struct ib_cq	*ibc_cq;	     /* completion queue */
+
+	kib_connvars_t      *ibc_connvars;       /* in-progress connection state */
+} kib_conn_t;
+
+#define IBLND_CONN_INIT	       0	 /* being initialised */
+#define IBLND_CONN_ACTIVE_CONNECT     1	 /* active sending req */
+#define IBLND_CONN_PASSIVE_WAIT       2	 /* passive waiting for rtu */
+#define IBLND_CONN_ESTABLISHED	3	 /* connection established */
+#define IBLND_CONN_CLOSING	    4	 /* being closed */
+#define IBLND_CONN_DISCONNECTED       5	 /* disconnected */
+
+typedef struct kib_peer
+{
+	struct list_head	   ibp_list;	   /* stash on global peer list */
+	lnet_nid_t	   ibp_nid;	    /* who's on the other end(s) */
+	lnet_ni_t	   *ibp_ni;	     /* LNet interface */
+	atomic_t	 ibp_refcount;       /* # users */
+	struct list_head	   ibp_conns;	  /* all active connections */
+	struct list_head	   ibp_tx_queue;       /* msgs waiting for a conn */
+	__u16		ibp_version;	/* version of peer */
+	__u64		ibp_incarnation;    /* incarnation of peer */
+	int		  ibp_connecting;     /* current active connection attempts */
+	int		  ibp_accepting;      /* current passive connection attempts */
+	int		  ibp_error;	  /* errno on closing this peer */
+	cfs_time_t	   ibp_last_alive;     /* when (in jiffies) I was last alive */
+} kib_peer_t;
+
+extern kib_data_t      kiblnd_data;
+
+extern void kiblnd_hdev_destroy(kib_hca_dev_t *hdev);
+
+static inline void
+kiblnd_hdev_addref_locked(kib_hca_dev_t *hdev)
+{
+	LASSERT (atomic_read(&hdev->ibh_ref) > 0);
+	atomic_inc(&hdev->ibh_ref);
+}
+
+static inline void
+kiblnd_hdev_decref(kib_hca_dev_t *hdev)
+{
+	LASSERT (atomic_read(&hdev->ibh_ref) > 0);
+	if (atomic_dec_and_test(&hdev->ibh_ref))
+		kiblnd_hdev_destroy(hdev);
+}
+
+static inline int
+kiblnd_dev_can_failover(kib_dev_t *dev)
+{
+	if (!list_empty(&dev->ibd_fail_list)) /* already scheduled */
+		return 0;
+
+	if (*kiblnd_tunables.kib_dev_failover == 0) /* disabled */
+		return 0;
+
+	if (*kiblnd_tunables.kib_dev_failover > 1) /* force failover */
+		return 1;
+
+	return dev->ibd_can_failover;
+}
+
+#define kiblnd_conn_addref(conn)				\
+do {							    \
+	CDEBUG(D_NET, "conn[%p] (%d)++\n",		      \
+	       (conn), atomic_read(&(conn)->ibc_refcount)); \
+	atomic_inc(&(conn)->ibc_refcount);		  \
+} while (0)
+
+#define kiblnd_conn_decref(conn)					\
+do {									\
+	unsigned long flags;						\
+									\
+	CDEBUG(D_NET, "conn[%p] (%d)--\n",				\
+	       (conn), atomic_read(&(conn)->ibc_refcount));		\
+	LASSERT_ATOMIC_POS(&(conn)->ibc_refcount);			\
+	if (atomic_dec_and_test(&(conn)->ibc_refcount)) {		\
+		spin_lock_irqsave(&kiblnd_data.kib_connd_lock, flags);	\
+		list_add_tail(&(conn)->ibc_list,			\
+				  &kiblnd_data.kib_connd_zombies);	\
+		wake_up(&kiblnd_data.kib_connd_waitq);		\
+		spin_unlock_irqrestore(&kiblnd_data.kib_connd_lock, flags);\
+	}								\
+} while (0)
+
+#define kiblnd_peer_addref(peer)				\
+do {							    \
+	CDEBUG(D_NET, "peer[%p] -> %s (%d)++\n",		\
+	       (peer), libcfs_nid2str((peer)->ibp_nid),	 \
+	       atomic_read (&(peer)->ibp_refcount));	\
+	atomic_inc(&(peer)->ibp_refcount);		  \
+} while (0)
+
+#define kiblnd_peer_decref(peer)				\
+do {							    \
+	CDEBUG(D_NET, "peer[%p] -> %s (%d)--\n",		\
+	       (peer), libcfs_nid2str((peer)->ibp_nid),	 \
+	       atomic_read (&(peer)->ibp_refcount));	\
+	LASSERT_ATOMIC_POS(&(peer)->ibp_refcount);	      \
+	if (atomic_dec_and_test(&(peer)->ibp_refcount))     \
+		kiblnd_destroy_peer(peer);		      \
+} while (0)
+
+static inline struct list_head *
+kiblnd_nid2peerlist (lnet_nid_t nid)
+{
+	unsigned int hash =
+		((unsigned int)nid) % kiblnd_data.kib_peer_hash_size;
+
+	return (&kiblnd_data.kib_peers [hash]);
+}
+
+static inline int
+kiblnd_peer_active (kib_peer_t *peer)
+{
+	/* Am I in the peer hash table? */
+	return (!list_empty(&peer->ibp_list));
+}
+
+static inline kib_conn_t *
+kiblnd_get_conn_locked (kib_peer_t *peer)
+{
+	LASSERT (!list_empty(&peer->ibp_conns));
+
+	/* just return the first connection */
+	return list_entry(peer->ibp_conns.next, kib_conn_t, ibc_list);
+}
+
+static inline int
+kiblnd_send_keepalive(kib_conn_t *conn)
+{
+	return (*kiblnd_tunables.kib_keepalive > 0) &&
+		cfs_time_after(jiffies, conn->ibc_last_send +
+			       *kiblnd_tunables.kib_keepalive*HZ);
+}
+
+static inline int
+kiblnd_need_noop(kib_conn_t *conn)
+{
+	LASSERT (conn->ibc_state >= IBLND_CONN_ESTABLISHED);
+
+	if (conn->ibc_outstanding_credits <
+	    IBLND_CREDITS_HIGHWATER(conn->ibc_version) &&
+	    !kiblnd_send_keepalive(conn))
+		return 0; /* No need to send NOOP */
+
+	if (IBLND_OOB_CAPABLE(conn->ibc_version)) {
+		if (!list_empty(&conn->ibc_tx_queue_nocred))
+			return 0; /* NOOP can be piggybacked */
+
+		/* No tx to piggyback NOOP onto or no credit to send a tx */
+		return (list_empty(&conn->ibc_tx_queue) ||
+			conn->ibc_credits == 0);
+	}
+
+	if (!list_empty(&conn->ibc_tx_noops) || /* NOOP already queued */
+	    !list_empty(&conn->ibc_tx_queue_nocred) || /* piggyback NOOP */
+	    conn->ibc_credits == 0)		    /* no credit */
+		return 0;
+
+	if (conn->ibc_credits == 1 &&      /* last credit reserved for */
+	    conn->ibc_outstanding_credits == 0) /* giving back credits */
+		return 0;
+
+	/* No tx to piggyback NOOP onto or no credit to send a tx */
+	return (list_empty(&conn->ibc_tx_queue) || conn->ibc_credits == 1);
+}
+
+static inline void
+kiblnd_abort_receives(kib_conn_t *conn)
+{
+	ib_modify_qp(conn->ibc_cmid->qp,
+		     &kiblnd_data.kib_error_qpa, IB_QP_STATE);
+}
+
+static inline const char *
+kiblnd_queue2str (kib_conn_t *conn, struct list_head *q)
+{
+	if (q == &conn->ibc_tx_queue)
+		return "tx_queue";
+
+	if (q == &conn->ibc_tx_queue_rsrvd)
+		return "tx_queue_rsrvd";
+
+	if (q == &conn->ibc_tx_queue_nocred)
+		return "tx_queue_nocred";
+
+	if (q == &conn->ibc_active_txs)
+		return "active_txs";
+
+	LBUG();
+	return NULL;
+}
+
+/* CAVEAT EMPTOR: We rely on descriptor alignment to allow us to use the
+ * lowest bits of the work request id to stash the work item type. */
+
+#define IBLND_WID_TX    0
+#define IBLND_WID_RDMA  1
+#define IBLND_WID_RX    2
+#define IBLND_WID_MASK  3UL
+
+static inline __u64
+kiblnd_ptr2wreqid (void *ptr, int type)
+{
+	unsigned long lptr = (unsigned long)ptr;
+
+	LASSERT ((lptr & IBLND_WID_MASK) == 0);
+	LASSERT ((type & ~IBLND_WID_MASK) == 0);
+	return (__u64)(lptr | type);
+}
+
+static inline void *
+kiblnd_wreqid2ptr (__u64 wreqid)
+{
+	return (void *)(((unsigned long)wreqid) & ~IBLND_WID_MASK);
+}
+
+static inline int
+kiblnd_wreqid2type (__u64 wreqid)
+{
+	return (wreqid & IBLND_WID_MASK);
+}
+
+static inline void
+kiblnd_set_conn_state (kib_conn_t *conn, int state)
+{
+	conn->ibc_state = state;
+	mb();
+}
+
+static inline void
+kiblnd_init_msg (kib_msg_t *msg, int type, int body_nob)
+{
+	msg->ibm_type = type;
+	msg->ibm_nob  = offsetof(kib_msg_t, ibm_u) + body_nob;
+}
+
+static inline int
+kiblnd_rd_size (kib_rdma_desc_t *rd)
+{
+	int   i;
+	int   size;
+
+	for (i = size = 0; i < rd->rd_nfrags; i++)
+		size += rd->rd_frags[i].rf_nob;
+
+	return size;
+}
+
+static inline __u64
+kiblnd_rd_frag_addr(kib_rdma_desc_t *rd, int index)
+{
+	return rd->rd_frags[index].rf_addr;
+}
+
+static inline __u32
+kiblnd_rd_frag_size(kib_rdma_desc_t *rd, int index)
+{
+	return rd->rd_frags[index].rf_nob;
+}
+
+static inline __u32
+kiblnd_rd_frag_key(kib_rdma_desc_t *rd, int index)
+{
+	return rd->rd_key;
+}
+
+static inline int
+kiblnd_rd_consume_frag(kib_rdma_desc_t *rd, int index, __u32 nob)
+{
+	if (nob < rd->rd_frags[index].rf_nob) {
+		rd->rd_frags[index].rf_addr += nob;
+		rd->rd_frags[index].rf_nob  -= nob;
+	} else {
+		index ++;
+	}
+
+	return index;
+}
+
+static inline int
+kiblnd_rd_msg_size(kib_rdma_desc_t *rd, int msgtype, int n)
+{
+	LASSERT (msgtype == IBLND_MSG_GET_REQ ||
+		 msgtype == IBLND_MSG_PUT_ACK);
+
+	return msgtype == IBLND_MSG_GET_REQ ?
+	       offsetof(kib_get_msg_t, ibgm_rd.rd_frags[n]) :
+	       offsetof(kib_putack_msg_t, ibpam_rd.rd_frags[n]);
+}
+
+
+static inline __u64
+kiblnd_dma_mapping_error(struct ib_device *dev, u64 dma_addr)
+{
+	return ib_dma_mapping_error(dev, dma_addr);
+}
+
+static inline __u64 kiblnd_dma_map_single(struct ib_device *dev,
+					  void *msg, size_t size,
+					  enum dma_data_direction direction)
+{
+	return ib_dma_map_single(dev, msg, size, direction);
+}
+
+static inline void kiblnd_dma_unmap_single(struct ib_device *dev,
+					   __u64 addr, size_t size,
+					  enum dma_data_direction direction)
+{
+	ib_dma_unmap_single(dev, addr, size, direction);
+}
+
+#define KIBLND_UNMAP_ADDR_SET(p, m, a)  do {} while (0)
+#define KIBLND_UNMAP_ADDR(p, m, a)      (a)
+
+static inline int kiblnd_dma_map_sg(struct ib_device *dev,
+				    struct scatterlist *sg, int nents,
+				    enum dma_data_direction direction)
+{
+	return ib_dma_map_sg(dev, sg, nents, direction);
+}
+
+static inline void kiblnd_dma_unmap_sg(struct ib_device *dev,
+				       struct scatterlist *sg, int nents,
+				       enum dma_data_direction direction)
+{
+	ib_dma_unmap_sg(dev, sg, nents, direction);
+}
+
+static inline __u64 kiblnd_sg_dma_address(struct ib_device *dev,
+					  struct scatterlist *sg)
+{
+	return ib_sg_dma_address(dev, sg);
+}
+
+static inline unsigned int kiblnd_sg_dma_len(struct ib_device *dev,
+					     struct scatterlist *sg)
+{
+	return ib_sg_dma_len(dev, sg);
+}
+
+/* XXX We use KIBLND_CONN_PARAM(e) as writable buffer, it's not strictly
+ * right because OFED1.2 defines it as const, to use it we have to add
+ * (void *) cast to overcome "const" */
+
+#define KIBLND_CONN_PARAM(e)	    ((e)->param.conn.private_data)
+#define KIBLND_CONN_PARAM_LEN(e)	((e)->param.conn.private_data_len)
+
+
+struct ib_mr *kiblnd_find_rd_dma_mr(kib_hca_dev_t *hdev,
+				    kib_rdma_desc_t *rd);
+struct ib_mr *kiblnd_find_dma_mr(kib_hca_dev_t *hdev,
+				 __u64 addr, __u64 size);
+void kiblnd_map_rx_descs(kib_conn_t *conn);
+void kiblnd_unmap_rx_descs(kib_conn_t *conn);
+int kiblnd_map_tx(lnet_ni_t *ni, kib_tx_t *tx,
+		  kib_rdma_desc_t *rd, int nfrags);
+void kiblnd_unmap_tx(lnet_ni_t *ni, kib_tx_t *tx);
+void kiblnd_pool_free_node(kib_pool_t *pool, struct list_head *node);
+struct list_head *kiblnd_pool_alloc_node(kib_poolset_t *ps);
+
+int  kiblnd_fmr_pool_map(kib_fmr_poolset_t *fps, __u64 *pages,
+			 int npages, __u64 iov, kib_fmr_t *fmr);
+void kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status);
+
+int  kiblnd_pmr_pool_map(kib_pmr_poolset_t *pps, kib_hca_dev_t *hdev,
+			 kib_rdma_desc_t *rd, __u64 *iova, kib_phys_mr_t **pp_pmr);
+void kiblnd_pmr_pool_unmap(kib_phys_mr_t *pmr);
+
+int  kiblnd_startup (lnet_ni_t *ni);
+void kiblnd_shutdown (lnet_ni_t *ni);
+int  kiblnd_ctl (lnet_ni_t *ni, unsigned int cmd, void *arg);
+void kiblnd_query (struct lnet_ni *ni, lnet_nid_t nid, cfs_time_t *when);
+
+int  kiblnd_tunables_init(void);
+void kiblnd_tunables_fini(void);
+
+int  kiblnd_connd (void *arg);
+int  kiblnd_scheduler(void *arg);
+int  kiblnd_thread_start(int (*fn)(void *arg), void *arg, char *name);
+int  kiblnd_failover_thread (void *arg);
+
+int  kiblnd_alloc_pages(kib_pages_t **pp, int cpt, int npages);
+void kiblnd_free_pages (kib_pages_t *p);
+
+int  kiblnd_cm_callback(struct rdma_cm_id *cmid,
+			struct rdma_cm_event *event);
+int  kiblnd_translate_mtu(int value);
+
+int  kiblnd_dev_failover(kib_dev_t *dev);
+int  kiblnd_create_peer (lnet_ni_t *ni, kib_peer_t **peerp, lnet_nid_t nid);
+void kiblnd_destroy_peer (kib_peer_t *peer);
+void kiblnd_destroy_dev (kib_dev_t *dev);
+void kiblnd_unlink_peer_locked (kib_peer_t *peer);
+void kiblnd_peer_alive (kib_peer_t *peer);
+kib_peer_t *kiblnd_find_peer_locked (lnet_nid_t nid);
+void kiblnd_peer_connect_failed (kib_peer_t *peer, int active, int error);
+int  kiblnd_close_stale_conns_locked (kib_peer_t *peer,
+				      int version, __u64 incarnation);
+int  kiblnd_close_peer_conns_locked (kib_peer_t *peer, int why);
+
+void kiblnd_connreq_done(kib_conn_t *conn, int status);
+kib_conn_t *kiblnd_create_conn (kib_peer_t *peer, struct rdma_cm_id *cmid,
+				int state, int version);
+void kiblnd_destroy_conn (kib_conn_t *conn);
+void kiblnd_close_conn (kib_conn_t *conn, int error);
+void kiblnd_close_conn_locked (kib_conn_t *conn, int error);
+
+int  kiblnd_init_rdma (kib_conn_t *conn, kib_tx_t *tx, int type,
+		       int nob, kib_rdma_desc_t *dstrd, __u64 dstcookie);
+
+void kiblnd_launch_tx (lnet_ni_t *ni, kib_tx_t *tx, lnet_nid_t nid);
+void kiblnd_queue_tx_locked (kib_tx_t *tx, kib_conn_t *conn);
+void kiblnd_queue_tx (kib_tx_t *tx, kib_conn_t *conn);
+void kiblnd_init_tx_msg (lnet_ni_t *ni, kib_tx_t *tx, int type, int body_nob);
+void kiblnd_txlist_done (lnet_ni_t *ni, struct list_head *txlist,
+			 int status);
+void kiblnd_check_sends (kib_conn_t *conn);
+
+void kiblnd_qp_event(struct ib_event *event, void *arg);
+void kiblnd_cq_event(struct ib_event *event, void *arg);
+void kiblnd_cq_completion(struct ib_cq *cq, void *arg);
+
+void kiblnd_pack_msg (lnet_ni_t *ni, kib_msg_t *msg, int version,
+		      int credits, lnet_nid_t dstnid, __u64 dststamp);
+int  kiblnd_unpack_msg(kib_msg_t *msg, int nob);
+int  kiblnd_post_rx (kib_rx_t *rx, int credit);
+
+int  kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
+int  kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
+		 unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov,
+		 unsigned int offset, unsigned int mlen, unsigned int rlen);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,493 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/klnds/o2iblnd/o2iblnd_modparams.c
+ *
+ * Author: Eric Barton <eric@bartonsoftware.com>
+ */
+
+#include "o2iblnd.h"
+
+static int service = 987;
+CFS_MODULE_PARM(service, "i", int, 0444,
+		"service number (within RDMA_PS_TCP)");
+
+static int cksum = 0;
+CFS_MODULE_PARM(cksum, "i", int, 0644,
+		"set non-zero to enable message (not RDMA) checksums");
+
+static int timeout = 50;
+CFS_MODULE_PARM(timeout, "i", int, 0644,
+		"timeout (seconds)");
+
+/* Number of threads in each scheduler pool which is percpt,
+ * we will estimate reasonable value based on CPUs if it's set to zero. */
+static int nscheds;
+CFS_MODULE_PARM(nscheds, "i", int, 0444,
+		"number of threads in each scheduler pool");
+
+/* NB: this value is shared by all CPTs, it can grow at runtime */
+static int ntx = 512;
+CFS_MODULE_PARM(ntx, "i", int, 0444,
+		"# of message descriptors allocated for each pool");
+
+/* NB: this value is shared by all CPTs */
+static int credits = 256;
+CFS_MODULE_PARM(credits, "i", int, 0444,
+		"# concurrent sends");
+
+static int peer_credits = 8;
+CFS_MODULE_PARM(peer_credits, "i", int, 0444,
+		"# concurrent sends to 1 peer");
+
+static int peer_credits_hiw = 0;
+CFS_MODULE_PARM(peer_credits_hiw, "i", int, 0444,
+		"when eagerly to return credits");
+
+static int peer_buffer_credits = 0;
+CFS_MODULE_PARM(peer_buffer_credits, "i", int, 0444,
+		"# per-peer router buffer credits");
+
+static int peer_timeout = 180;
+CFS_MODULE_PARM(peer_timeout, "i", int, 0444,
+		"Seconds without aliveness news to declare peer dead (<=0 to disable)");
+
+static char *ipif_name = "ib0";
+CFS_MODULE_PARM(ipif_name, "s", charp, 0444,
+		"IPoIB interface name");
+
+static int retry_count = 5;
+CFS_MODULE_PARM(retry_count, "i", int, 0644,
+		"Retransmissions when no ACK received");
+
+static int rnr_retry_count = 6;
+CFS_MODULE_PARM(rnr_retry_count, "i", int, 0644,
+		"RNR retransmissions");
+
+static int keepalive = 100;
+CFS_MODULE_PARM(keepalive, "i", int, 0644,
+		"Idle time in seconds before sending a keepalive");
+
+static int ib_mtu = 0;
+CFS_MODULE_PARM(ib_mtu, "i", int, 0444,
+		"IB MTU 256/512/1024/2048/4096");
+
+static int concurrent_sends = 0;
+CFS_MODULE_PARM(concurrent_sends, "i", int, 0444,
+		"send work-queue sizing");
+
+static int map_on_demand = 0;
+CFS_MODULE_PARM(map_on_demand, "i", int, 0444,
+		"map on demand");
+
+/* NB: this value is shared by all CPTs, it can grow at runtime */
+static int fmr_pool_size = 512;
+CFS_MODULE_PARM(fmr_pool_size, "i", int, 0444,
+		"size of fmr pool on each CPT (>= ntx / 4)");
+
+/* NB: this value is shared by all CPTs, it can grow at runtime */
+static int fmr_flush_trigger = 384;
+CFS_MODULE_PARM(fmr_flush_trigger, "i", int, 0444,
+		"# dirty FMRs that triggers pool flush");
+
+static int fmr_cache = 1;
+CFS_MODULE_PARM(fmr_cache, "i", int, 0444,
+		"non-zero to enable FMR caching");
+
+/* NB: this value is shared by all CPTs, it can grow at runtime */
+static int pmr_pool_size = 512;
+CFS_MODULE_PARM(pmr_pool_size, "i", int, 0444,
+		"size of MR cache pmr pool on each CPT");
+
+/*
+ * 0: disable failover
+ * 1: enable failover if necessary
+ * 2: force to failover (for debug)
+ */
+static int dev_failover = 0;
+CFS_MODULE_PARM(dev_failover, "i", int, 0444,
+	       "HCA failover for bonding (0 off, 1 on, other values reserved)");
+
+
+static int require_privileged_port = 0;
+CFS_MODULE_PARM(require_privileged_port, "i", int, 0644,
+		"require privileged port when accepting connection");
+
+static int use_privileged_port = 1;
+CFS_MODULE_PARM(use_privileged_port, "i", int, 0644,
+		"use privileged port when initiating connection");
+
+kib_tunables_t kiblnd_tunables = {
+	.kib_dev_failover	   = &dev_failover,
+	.kib_service		= &service,
+	.kib_cksum		  = &cksum,
+	.kib_timeout		= &timeout,
+	.kib_keepalive	      = &keepalive,
+	.kib_ntx		    = &ntx,
+	.kib_credits		= &credits,
+	.kib_peertxcredits	  = &peer_credits,
+	.kib_peercredits_hiw	= &peer_credits_hiw,
+	.kib_peerrtrcredits	 = &peer_buffer_credits,
+	.kib_peertimeout	    = &peer_timeout,
+	.kib_default_ipif	   = &ipif_name,
+	.kib_retry_count	    = &retry_count,
+	.kib_rnr_retry_count	= &rnr_retry_count,
+	.kib_concurrent_sends       = &concurrent_sends,
+	.kib_ib_mtu		 = &ib_mtu,
+	.kib_map_on_demand	  = &map_on_demand,
+	.kib_fmr_pool_size	  = &fmr_pool_size,
+	.kib_fmr_flush_trigger      = &fmr_flush_trigger,
+	.kib_fmr_cache	      = &fmr_cache,
+	.kib_pmr_pool_size	  = &pmr_pool_size,
+	.kib_require_priv_port      = &require_privileged_port,
+	.kib_use_priv_port	    = &use_privileged_port,
+	.kib_nscheds		    = &nscheds
+};
+
+#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
+
+static char ipif_basename_space[32];
+
+
+enum {
+	O2IBLND_SERVICE  = 1,
+	O2IBLND_CKSUM,
+	O2IBLND_TIMEOUT,
+	O2IBLND_NTX,
+	O2IBLND_CREDITS,
+	O2IBLND_PEER_TXCREDITS,
+	O2IBLND_PEER_CREDITS_HIW,
+	O2IBLND_PEER_RTRCREDITS,
+	O2IBLND_PEER_TIMEOUT,
+	O2IBLND_IPIF_BASENAME,
+	O2IBLND_RETRY_COUNT,
+	O2IBLND_RNR_RETRY_COUNT,
+	O2IBLND_KEEPALIVE,
+	O2IBLND_CONCURRENT_SENDS,
+	O2IBLND_IB_MTU,
+	O2IBLND_MAP_ON_DEMAND,
+	O2IBLND_FMR_POOL_SIZE,
+	O2IBLND_FMR_FLUSH_TRIGGER,
+	O2IBLND_FMR_CACHE,
+	O2IBLND_PMR_POOL_SIZE,
+	O2IBLND_DEV_FAILOVER
+};
+
+static ctl_table_t kiblnd_ctl_table[] = {
+	{
+		.ctl_name = O2IBLND_SERVICE,
+		.procname = "service",
+		.data     = &service,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_CKSUM,
+		.procname = "cksum",
+		.data     = &cksum,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_TIMEOUT,
+		.procname = "timeout",
+		.data     = &timeout,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_NTX,
+		.procname = "ntx",
+		.data     = &ntx,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_CREDITS,
+		.procname = "credits",
+		.data     = &credits,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_PEER_TXCREDITS,
+		.procname = "peer_credits",
+		.data     = &peer_credits,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_PEER_CREDITS_HIW,
+		.procname = "peer_credits_hiw",
+		.data     = &peer_credits_hiw,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_PEER_RTRCREDITS,
+		.procname = "peer_buffer_credits",
+		.data     = &peer_buffer_credits,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_PEER_TIMEOUT,
+		.procname = "peer_timeout",
+		.data     = &peer_timeout,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_IPIF_BASENAME,
+		.procname = "ipif_name",
+		.data     = ipif_basename_space,
+		.maxlen   = sizeof(ipif_basename_space),
+		.mode     = 0444,
+		.proc_handler = &proc_dostring
+	},
+	{
+		.ctl_name = O2IBLND_RETRY_COUNT,
+		.procname = "retry_count",
+		.data     = &retry_count,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_RNR_RETRY_COUNT,
+		.procname = "rnr_retry_count",
+		.data     = &rnr_retry_count,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_KEEPALIVE,
+		.procname = "keepalive",
+		.data     = &keepalive,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_CONCURRENT_SENDS,
+		.procname = "concurrent_sends",
+		.data     = &concurrent_sends,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_IB_MTU,
+		.procname = "ib_mtu",
+		.data     = &ib_mtu,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_MAP_ON_DEMAND,
+		.procname = "map_on_demand",
+		.data     = &map_on_demand,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+
+	{
+		.ctl_name = O2IBLND_FMR_POOL_SIZE,
+		.procname = "fmr_pool_size",
+		.data     = &fmr_pool_size,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_FMR_FLUSH_TRIGGER,
+		.procname = "fmr_flush_trigger",
+		.data     = &fmr_flush_trigger,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_FMR_CACHE,
+		.procname = "fmr_cache",
+		.data     = &fmr_cache,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_PMR_POOL_SIZE,
+		.procname = "pmr_pool_size",
+		.data     = &pmr_pool_size,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.ctl_name = O2IBLND_DEV_FAILOVER,
+		.procname = "dev_failover",
+		.data     = &dev_failover,
+		.maxlen   = sizeof(int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+	},
+	{0}
+};
+
+static ctl_table_t kiblnd_top_ctl_table[] = {
+	{
+		.ctl_name = CTL_O2IBLND,
+		.procname = "o2iblnd",
+		.data     = NULL,
+		.maxlen   = 0,
+		.mode     = 0555,
+		.child    = kiblnd_ctl_table
+	},
+	{0}
+};
+
+void
+kiblnd_initstrtunable(char *space, char *str, int size)
+{
+	strncpy(space, str, size);
+	space[size-1] = 0;
+}
+
+void
+kiblnd_sysctl_init (void)
+{
+	kiblnd_initstrtunable(ipif_basename_space, ipif_name,
+			      sizeof(ipif_basename_space));
+
+	kiblnd_tunables.kib_sysctl =
+		cfs_register_sysctl_table(kiblnd_top_ctl_table, 0);
+
+	if (kiblnd_tunables.kib_sysctl == NULL)
+		CWARN("Can't setup /proc tunables\n");
+}
+
+void
+kiblnd_sysctl_fini (void)
+{
+	if (kiblnd_tunables.kib_sysctl != NULL)
+		unregister_sysctl_table(kiblnd_tunables.kib_sysctl);
+}
+
+#else
+
+void
+kiblnd_sysctl_init (void)
+{
+}
+
+void
+kiblnd_sysctl_fini (void)
+{
+}
+
+#endif
+
+int
+kiblnd_tunables_init (void)
+{
+	if (kiblnd_translate_mtu(*kiblnd_tunables.kib_ib_mtu) < 0) {
+		CERROR("Invalid ib_mtu %d, expected 256/512/1024/2048/4096\n",
+		       *kiblnd_tunables.kib_ib_mtu);
+		return -EINVAL;
+	}
+
+	if (*kiblnd_tunables.kib_peertxcredits < IBLND_CREDITS_DEFAULT)
+		*kiblnd_tunables.kib_peertxcredits = IBLND_CREDITS_DEFAULT;
+
+	if (*kiblnd_tunables.kib_peertxcredits > IBLND_CREDITS_MAX)
+		*kiblnd_tunables.kib_peertxcredits = IBLND_CREDITS_MAX;
+
+	if (*kiblnd_tunables.kib_peertxcredits > *kiblnd_tunables.kib_credits)
+		*kiblnd_tunables.kib_peertxcredits = *kiblnd_tunables.kib_credits;
+
+	if (*kiblnd_tunables.kib_peercredits_hiw < *kiblnd_tunables.kib_peertxcredits / 2)
+		*kiblnd_tunables.kib_peercredits_hiw = *kiblnd_tunables.kib_peertxcredits / 2;
+
+	if (*kiblnd_tunables.kib_peercredits_hiw >= *kiblnd_tunables.kib_peertxcredits)
+		*kiblnd_tunables.kib_peercredits_hiw = *kiblnd_tunables.kib_peertxcredits - 1;
+
+	if (*kiblnd_tunables.kib_map_on_demand < 0 ||
+	    *kiblnd_tunables.kib_map_on_demand > IBLND_MAX_RDMA_FRAGS)
+		*kiblnd_tunables.kib_map_on_demand = 0; /* disable map-on-demand */
+
+	if (*kiblnd_tunables.kib_map_on_demand == 1)
+		*kiblnd_tunables.kib_map_on_demand = 2; /* don't make sense to create map if only one fragment */
+
+	if (*kiblnd_tunables.kib_concurrent_sends == 0) {
+		if (*kiblnd_tunables.kib_map_on_demand > 0 &&
+		    *kiblnd_tunables.kib_map_on_demand <= IBLND_MAX_RDMA_FRAGS / 8)
+			*kiblnd_tunables.kib_concurrent_sends = (*kiblnd_tunables.kib_peertxcredits) * 2;
+		else
+			*kiblnd_tunables.kib_concurrent_sends = (*kiblnd_tunables.kib_peertxcredits);
+	}
+
+	if (*kiblnd_tunables.kib_concurrent_sends > *kiblnd_tunables.kib_peertxcredits * 2)
+		*kiblnd_tunables.kib_concurrent_sends = *kiblnd_tunables.kib_peertxcredits * 2;
+
+	if (*kiblnd_tunables.kib_concurrent_sends < *kiblnd_tunables.kib_peertxcredits / 2)
+		*kiblnd_tunables.kib_concurrent_sends = *kiblnd_tunables.kib_peertxcredits / 2;
+
+	if (*kiblnd_tunables.kib_concurrent_sends < *kiblnd_tunables.kib_peertxcredits) {
+		CWARN("Concurrent sends %d is lower than message queue size: %d, "
+		      "performance may drop slightly.\n",
+		      *kiblnd_tunables.kib_concurrent_sends, *kiblnd_tunables.kib_peertxcredits);
+	}
+
+	kiblnd_sysctl_init();
+	return 0;
+}
+
+void
+kiblnd_tunables_fini (void)
+{
+	kiblnd_sysctl_fini();
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/Makefile
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,7 @@
+obj-$(CONFIG_LNET) += ksocklnd.o
+
+ksocklnd-y := socklnd.o socklnd_cb.o socklnd_proto.o socklnd_modparams.o socklnd_lib-linux.o
+
+
+
+ccflags-y := -I$(src)/../../include
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2902 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/klnds/socklnd/socklnd.c
+ *
+ * Author: Zach Brown <zab@zabbo.net>
+ * Author: Peter J. Braam <braam@clusterfs.com>
+ * Author: Phil Schwan <phil@clusterfs.com>
+ * Author: Eric Barton <eric@bartonsoftware.com>
+ */
+
+#include "socklnd.h"
+
+lnd_t		   the_ksocklnd;
+ksock_nal_data_t	ksocknal_data;
+
+ksock_interface_t *
+ksocknal_ip2iface(lnet_ni_t *ni, __u32 ip)
+{
+	ksock_net_t       *net = ni->ni_data;
+	int		i;
+	ksock_interface_t *iface;
+
+	for (i = 0; i < net->ksnn_ninterfaces; i++) {
+		LASSERT(i < LNET_MAX_INTERFACES);
+		iface = &net->ksnn_interfaces[i];
+
+		if (iface->ksni_ipaddr == ip)
+			return (iface);
+	}
+
+	return (NULL);
+}
+
+ksock_route_t *
+ksocknal_create_route (__u32 ipaddr, int port)
+{
+	ksock_route_t *route;
+
+	LIBCFS_ALLOC (route, sizeof (*route));
+	if (route == NULL)
+		return (NULL);
+
+	atomic_set (&route->ksnr_refcount, 1);
+	route->ksnr_peer = NULL;
+	route->ksnr_retry_interval = 0;	 /* OK to connect at any time */
+	route->ksnr_ipaddr = ipaddr;
+	route->ksnr_port = port;
+	route->ksnr_scheduled = 0;
+	route->ksnr_connecting = 0;
+	route->ksnr_connected = 0;
+	route->ksnr_deleted = 0;
+	route->ksnr_conn_count = 0;
+	route->ksnr_share_count = 0;
+
+	return (route);
+}
+
+void
+ksocknal_destroy_route (ksock_route_t *route)
+{
+	LASSERT (atomic_read(&route->ksnr_refcount) == 0);
+
+	if (route->ksnr_peer != NULL)
+		ksocknal_peer_decref(route->ksnr_peer);
+
+	LIBCFS_FREE (route, sizeof (*route));
+}
+
+int
+ksocknal_create_peer (ksock_peer_t **peerp, lnet_ni_t *ni, lnet_process_id_t id)
+{
+	ksock_net_t   *net = ni->ni_data;
+	ksock_peer_t  *peer;
+
+	LASSERT (id.nid != LNET_NID_ANY);
+	LASSERT (id.pid != LNET_PID_ANY);
+	LASSERT (!in_interrupt());
+
+	LIBCFS_ALLOC (peer, sizeof (*peer));
+	if (peer == NULL)
+		return -ENOMEM;
+
+	memset (peer, 0, sizeof (*peer));       /* NULL pointers/clear flags etc */
+
+	peer->ksnp_ni = ni;
+	peer->ksnp_id = id;
+	atomic_set (&peer->ksnp_refcount, 1);   /* 1 ref for caller */
+	peer->ksnp_closing = 0;
+	peer->ksnp_accepting = 0;
+	peer->ksnp_proto = NULL;
+	peer->ksnp_last_alive = 0;
+	peer->ksnp_zc_next_cookie = SOCKNAL_KEEPALIVE_PING + 1;
+
+	INIT_LIST_HEAD (&peer->ksnp_conns);
+	INIT_LIST_HEAD (&peer->ksnp_routes);
+	INIT_LIST_HEAD (&peer->ksnp_tx_queue);
+	INIT_LIST_HEAD (&peer->ksnp_zc_req_list);
+	spin_lock_init(&peer->ksnp_lock);
+
+	spin_lock_bh(&net->ksnn_lock);
+
+	if (net->ksnn_shutdown) {
+		spin_unlock_bh(&net->ksnn_lock);
+
+		LIBCFS_FREE(peer, sizeof(*peer));
+		CERROR("Can't create peer: network shutdown\n");
+		return -ESHUTDOWN;
+	}
+
+	net->ksnn_npeers++;
+
+	spin_unlock_bh(&net->ksnn_lock);
+
+	*peerp = peer;
+	return 0;
+}
+
+void
+ksocknal_destroy_peer (ksock_peer_t *peer)
+{
+	ksock_net_t    *net = peer->ksnp_ni->ni_data;
+
+	CDEBUG (D_NET, "peer %s %p deleted\n",
+		libcfs_id2str(peer->ksnp_id), peer);
+
+	LASSERT (atomic_read (&peer->ksnp_refcount) == 0);
+	LASSERT (peer->ksnp_accepting == 0);
+	LASSERT (list_empty (&peer->ksnp_conns));
+	LASSERT (list_empty (&peer->ksnp_routes));
+	LASSERT (list_empty (&peer->ksnp_tx_queue));
+	LASSERT (list_empty (&peer->ksnp_zc_req_list));
+
+	LIBCFS_FREE (peer, sizeof (*peer));
+
+	/* NB a peer's connections and routes keep a reference on their peer
+	 * until they are destroyed, so we can be assured that _all_ state to
+	 * do with this peer has been cleaned up when its refcount drops to
+	 * zero. */
+	spin_lock_bh(&net->ksnn_lock);
+	net->ksnn_npeers--;
+	spin_unlock_bh(&net->ksnn_lock);
+}
+
+ksock_peer_t *
+ksocknal_find_peer_locked (lnet_ni_t *ni, lnet_process_id_t id)
+{
+	struct list_head       *peer_list = ksocknal_nid2peerlist(id.nid);
+	struct list_head       *tmp;
+	ksock_peer_t     *peer;
+
+	list_for_each (tmp, peer_list) {
+
+		peer = list_entry (tmp, ksock_peer_t, ksnp_list);
+
+		LASSERT (!peer->ksnp_closing);
+
+		if (peer->ksnp_ni != ni)
+			continue;
+
+		if (peer->ksnp_id.nid != id.nid ||
+		    peer->ksnp_id.pid != id.pid)
+			continue;
+
+		CDEBUG(D_NET, "got peer [%p] -> %s (%d)\n",
+		       peer, libcfs_id2str(id),
+		       atomic_read(&peer->ksnp_refcount));
+		return (peer);
+	}
+	return (NULL);
+}
+
+ksock_peer_t *
+ksocknal_find_peer (lnet_ni_t *ni, lnet_process_id_t id)
+{
+	ksock_peer_t     *peer;
+
+	read_lock(&ksocknal_data.ksnd_global_lock);
+	peer = ksocknal_find_peer_locked(ni, id);
+	if (peer != NULL)			/* +1 ref for caller? */
+		ksocknal_peer_addref(peer);
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+
+	return (peer);
+}
+
+void
+ksocknal_unlink_peer_locked (ksock_peer_t *peer)
+{
+	int		i;
+	__u32	      ip;
+	ksock_interface_t *iface;
+
+	for (i = 0; i < peer->ksnp_n_passive_ips; i++) {
+		LASSERT (i < LNET_MAX_INTERFACES);
+		ip = peer->ksnp_passive_ips[i];
+
+		iface = ksocknal_ip2iface(peer->ksnp_ni, ip);
+		/* All IPs in peer->ksnp_passive_ips[] come from the
+		 * interface list, therefore the call must succeed. */
+		LASSERT (iface != NULL);
+
+		CDEBUG(D_NET, "peer=%p iface=%p ksni_nroutes=%d\n",
+		       peer, iface, iface->ksni_nroutes);
+		iface->ksni_npeers--;
+	}
+
+	LASSERT (list_empty(&peer->ksnp_conns));
+	LASSERT (list_empty(&peer->ksnp_routes));
+	LASSERT (!peer->ksnp_closing);
+	peer->ksnp_closing = 1;
+	list_del (&peer->ksnp_list);
+	/* lose peerlist's ref */
+	ksocknal_peer_decref(peer);
+}
+
+int
+ksocknal_get_peer_info (lnet_ni_t *ni, int index,
+			lnet_process_id_t *id, __u32 *myip, __u32 *peer_ip,
+			int *port, int *conn_count, int *share_count)
+{
+	ksock_peer_t      *peer;
+	struct list_head	*ptmp;
+	ksock_route_t     *route;
+	struct list_head	*rtmp;
+	int		i;
+	int		j;
+	int		rc = -ENOENT;
+
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) {
+
+		list_for_each (ptmp, &ksocknal_data.ksnd_peers[i]) {
+			peer = list_entry (ptmp, ksock_peer_t, ksnp_list);
+
+			if (peer->ksnp_ni != ni)
+				continue;
+
+			if (peer->ksnp_n_passive_ips == 0 &&
+			    list_empty(&peer->ksnp_routes)) {
+				if (index-- > 0)
+					continue;
+
+				*id = peer->ksnp_id;
+				*myip = 0;
+				*peer_ip = 0;
+				*port = 0;
+				*conn_count = 0;
+				*share_count = 0;
+				rc = 0;
+				goto out;
+			}
+
+			for (j = 0; j < peer->ksnp_n_passive_ips; j++) {
+				if (index-- > 0)
+					continue;
+
+				*id = peer->ksnp_id;
+				*myip = peer->ksnp_passive_ips[j];
+				*peer_ip = 0;
+				*port = 0;
+				*conn_count = 0;
+				*share_count = 0;
+				rc = 0;
+				goto out;
+			}
+
+			list_for_each (rtmp, &peer->ksnp_routes) {
+				if (index-- > 0)
+					continue;
+
+				route = list_entry(rtmp, ksock_route_t,
+						       ksnr_list);
+
+				*id = peer->ksnp_id;
+				*myip = route->ksnr_myipaddr;
+				*peer_ip = route->ksnr_ipaddr;
+				*port = route->ksnr_port;
+				*conn_count = route->ksnr_conn_count;
+				*share_count = route->ksnr_share_count;
+				rc = 0;
+				goto out;
+			}
+		}
+	}
+ out:
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+	return (rc);
+}
+
+void
+ksocknal_associate_route_conn_locked(ksock_route_t *route, ksock_conn_t *conn)
+{
+	ksock_peer_t      *peer = route->ksnr_peer;
+	int		type = conn->ksnc_type;
+	ksock_interface_t *iface;
+
+	conn->ksnc_route = route;
+	ksocknal_route_addref(route);
+
+	if (route->ksnr_myipaddr != conn->ksnc_myipaddr) {
+		if (route->ksnr_myipaddr == 0) {
+			/* route wasn't bound locally yet (the initial route) */
+			CDEBUG(D_NET, "Binding %s %u.%u.%u.%u to %u.%u.%u.%u\n",
+			       libcfs_id2str(peer->ksnp_id),
+			       HIPQUAD(route->ksnr_ipaddr),
+			       HIPQUAD(conn->ksnc_myipaddr));
+		} else {
+			CDEBUG(D_NET, "Rebinding %s %u.%u.%u.%u from "
+			       "%u.%u.%u.%u to %u.%u.%u.%u\n",
+			       libcfs_id2str(peer->ksnp_id),
+			       HIPQUAD(route->ksnr_ipaddr),
+			       HIPQUAD(route->ksnr_myipaddr),
+			       HIPQUAD(conn->ksnc_myipaddr));
+
+			iface = ksocknal_ip2iface(route->ksnr_peer->ksnp_ni,
+						  route->ksnr_myipaddr);
+			if (iface != NULL)
+				iface->ksni_nroutes--;
+		}
+		route->ksnr_myipaddr = conn->ksnc_myipaddr;
+		iface = ksocknal_ip2iface(route->ksnr_peer->ksnp_ni,
+					  route->ksnr_myipaddr);
+		if (iface != NULL)
+			iface->ksni_nroutes++;
+	}
+
+	route->ksnr_connected |= (1<<type);
+	route->ksnr_conn_count++;
+
+	/* Successful connection => further attempts can
+	 * proceed immediately */
+	route->ksnr_retry_interval = 0;
+}
+
+void
+ksocknal_add_route_locked (ksock_peer_t *peer, ksock_route_t *route)
+{
+	struct list_head	*tmp;
+	ksock_conn_t      *conn;
+	ksock_route_t     *route2;
+
+	LASSERT (!peer->ksnp_closing);
+	LASSERT (route->ksnr_peer == NULL);
+	LASSERT (!route->ksnr_scheduled);
+	LASSERT (!route->ksnr_connecting);
+	LASSERT (route->ksnr_connected == 0);
+
+	/* LASSERT(unique) */
+	list_for_each(tmp, &peer->ksnp_routes) {
+		route2 = list_entry(tmp, ksock_route_t, ksnr_list);
+
+		if (route2->ksnr_ipaddr == route->ksnr_ipaddr) {
+			CERROR ("Duplicate route %s %u.%u.%u.%u\n",
+				libcfs_id2str(peer->ksnp_id),
+				HIPQUAD(route->ksnr_ipaddr));
+			LBUG();
+		}
+	}
+
+	route->ksnr_peer = peer;
+	ksocknal_peer_addref(peer);
+	/* peer's routelist takes over my ref on 'route' */
+	list_add_tail(&route->ksnr_list, &peer->ksnp_routes);
+
+	list_for_each(tmp, &peer->ksnp_conns) {
+		conn = list_entry(tmp, ksock_conn_t, ksnc_list);
+
+		if (conn->ksnc_ipaddr != route->ksnr_ipaddr)
+			continue;
+
+		ksocknal_associate_route_conn_locked(route, conn);
+		/* keep going (typed routes) */
+	}
+}
+
+void
+ksocknal_del_route_locked (ksock_route_t *route)
+{
+	ksock_peer_t      *peer = route->ksnr_peer;
+	ksock_interface_t *iface;
+	ksock_conn_t      *conn;
+	struct list_head	*ctmp;
+	struct list_head	*cnxt;
+
+	LASSERT (!route->ksnr_deleted);
+
+	/* Close associated conns */
+	list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
+		conn = list_entry(ctmp, ksock_conn_t, ksnc_list);
+
+		if (conn->ksnc_route != route)
+			continue;
+
+		ksocknal_close_conn_locked (conn, 0);
+	}
+
+	if (route->ksnr_myipaddr != 0) {
+		iface = ksocknal_ip2iface(route->ksnr_peer->ksnp_ni,
+					  route->ksnr_myipaddr);
+		if (iface != NULL)
+			iface->ksni_nroutes--;
+	}
+
+	route->ksnr_deleted = 1;
+	list_del (&route->ksnr_list);
+	ksocknal_route_decref(route);	     /* drop peer's ref */
+
+	if (list_empty (&peer->ksnp_routes) &&
+	    list_empty (&peer->ksnp_conns)) {
+		/* I've just removed the last route to a peer with no active
+		 * connections */
+		ksocknal_unlink_peer_locked (peer);
+	}
+}
+
+int
+ksocknal_add_peer (lnet_ni_t *ni, lnet_process_id_t id, __u32 ipaddr, int port)
+{
+	struct list_head	*tmp;
+	ksock_peer_t      *peer;
+	ksock_peer_t      *peer2;
+	ksock_route_t     *route;
+	ksock_route_t     *route2;
+	int		rc;
+
+	if (id.nid == LNET_NID_ANY ||
+	    id.pid == LNET_PID_ANY)
+		return (-EINVAL);
+
+	/* Have a brand new peer ready... */
+	rc = ksocknal_create_peer(&peer, ni, id);
+	if (rc != 0)
+		return rc;
+
+	route = ksocknal_create_route (ipaddr, port);
+	if (route == NULL) {
+		ksocknal_peer_decref(peer);
+		return (-ENOMEM);
+	}
+
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	/* always called with a ref on ni, so shutdown can't have started */
+	LASSERT (((ksock_net_t *) ni->ni_data)->ksnn_shutdown == 0);
+
+	peer2 = ksocknal_find_peer_locked (ni, id);
+	if (peer2 != NULL) {
+		ksocknal_peer_decref(peer);
+		peer = peer2;
+	} else {
+		/* peer table takes my ref on peer */
+		list_add_tail (&peer->ksnp_list,
+				   ksocknal_nid2peerlist (id.nid));
+	}
+
+	route2 = NULL;
+	list_for_each (tmp, &peer->ksnp_routes) {
+		route2 = list_entry(tmp, ksock_route_t, ksnr_list);
+
+		if (route2->ksnr_ipaddr == ipaddr)
+			break;
+
+		route2 = NULL;
+	}
+	if (route2 == NULL) {
+		ksocknal_add_route_locked(peer, route);
+		route->ksnr_share_count++;
+	} else {
+		ksocknal_route_decref(route);
+		route2->ksnr_share_count++;
+	}
+
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+	return (0);
+}
+
+void
+ksocknal_del_peer_locked (ksock_peer_t *peer, __u32 ip)
+{
+	ksock_conn_t     *conn;
+	ksock_route_t    *route;
+	struct list_head       *tmp;
+	struct list_head       *nxt;
+	int	       nshared;
+
+	LASSERT (!peer->ksnp_closing);
+
+	/* Extra ref prevents peer disappearing until I'm done with it */
+	ksocknal_peer_addref(peer);
+
+	list_for_each_safe (tmp, nxt, &peer->ksnp_routes) {
+		route = list_entry(tmp, ksock_route_t, ksnr_list);
+
+		/* no match */
+		if (!(ip == 0 || route->ksnr_ipaddr == ip))
+			continue;
+
+		route->ksnr_share_count = 0;
+		/* This deletes associated conns too */
+		ksocknal_del_route_locked (route);
+	}
+
+	nshared = 0;
+	list_for_each_safe (tmp, nxt, &peer->ksnp_routes) {
+		route = list_entry(tmp, ksock_route_t, ksnr_list);
+		nshared += route->ksnr_share_count;
+	}
+
+	if (nshared == 0) {
+		/* remove everything else if there are no explicit entries
+		 * left */
+
+		list_for_each_safe (tmp, nxt, &peer->ksnp_routes) {
+			route = list_entry(tmp, ksock_route_t, ksnr_list);
+
+			/* we should only be removing auto-entries */
+			LASSERT(route->ksnr_share_count == 0);
+			ksocknal_del_route_locked (route);
+		}
+
+		list_for_each_safe (tmp, nxt, &peer->ksnp_conns) {
+			conn = list_entry(tmp, ksock_conn_t, ksnc_list);
+
+			ksocknal_close_conn_locked(conn, 0);
+		}
+	}
+
+	ksocknal_peer_decref(peer);
+	/* NB peer unlinks itself when last conn/route is removed */
+}
+
+int
+ksocknal_del_peer (lnet_ni_t *ni, lnet_process_id_t id, __u32 ip)
+{
+	LIST_HEAD     (zombies);
+	struct list_head	*ptmp;
+	struct list_head	*pnxt;
+	ksock_peer_t      *peer;
+	int		lo;
+	int		hi;
+	int		i;
+	int		rc = -ENOENT;
+
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	if (id.nid != LNET_NID_ANY)
+		lo = hi = (int)(ksocknal_nid2peerlist(id.nid) - ksocknal_data.ksnd_peers);
+	else {
+		lo = 0;
+		hi = ksocknal_data.ksnd_peer_hash_size - 1;
+	}
+
+	for (i = lo; i <= hi; i++) {
+		list_for_each_safe (ptmp, pnxt,
+					&ksocknal_data.ksnd_peers[i]) {
+			peer = list_entry (ptmp, ksock_peer_t, ksnp_list);
+
+			if (peer->ksnp_ni != ni)
+				continue;
+
+			if (!((id.nid == LNET_NID_ANY || peer->ksnp_id.nid == id.nid) &&
+			      (id.pid == LNET_PID_ANY || peer->ksnp_id.pid == id.pid)))
+				continue;
+
+			ksocknal_peer_addref(peer);     /* a ref for me... */
+
+			ksocknal_del_peer_locked (peer, ip);
+
+			if (peer->ksnp_closing &&
+			    !list_empty(&peer->ksnp_tx_queue)) {
+				LASSERT (list_empty(&peer->ksnp_conns));
+				LASSERT (list_empty(&peer->ksnp_routes));
+
+				list_splice_init(&peer->ksnp_tx_queue,
+						     &zombies);
+			}
+
+			ksocknal_peer_decref(peer);     /* ...till here */
+
+			rc = 0;		 /* matched! */
+		}
+	}
+
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+	ksocknal_txlist_done(ni, &zombies, 1);
+
+	return (rc);
+}
+
+ksock_conn_t *
+ksocknal_get_conn_by_idx (lnet_ni_t *ni, int index)
+{
+	ksock_peer_t      *peer;
+	struct list_head	*ptmp;
+	ksock_conn_t      *conn;
+	struct list_head	*ctmp;
+	int		i;
+
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) {
+		list_for_each (ptmp, &ksocknal_data.ksnd_peers[i]) {
+			peer = list_entry (ptmp, ksock_peer_t, ksnp_list);
+
+			LASSERT (!peer->ksnp_closing);
+
+			if (peer->ksnp_ni != ni)
+				continue;
+
+			list_for_each (ctmp, &peer->ksnp_conns) {
+				if (index-- > 0)
+					continue;
+
+				conn = list_entry (ctmp, ksock_conn_t,
+						       ksnc_list);
+				ksocknal_conn_addref(conn);
+				read_unlock(&ksocknal_data. \
+						 ksnd_global_lock);
+				return (conn);
+			}
+		}
+	}
+
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+	return (NULL);
+}
+
+ksock_sched_t *
+ksocknal_choose_scheduler_locked(unsigned int cpt)
+{
+	struct ksock_sched_info	*info = ksocknal_data.ksnd_sched_info[cpt];
+	ksock_sched_t		*sched;
+	int			i;
+
+	LASSERT(info->ksi_nthreads > 0);
+
+	sched = &info->ksi_scheds[0];
+	/*
+	 * NB: it's safe so far, but info->ksi_nthreads could be changed
+	 * at runtime when we have dynamic LNet configuration, then we
+	 * need to take care of this.
+	 */
+	for (i = 1; i < info->ksi_nthreads; i++) {
+		if (sched->kss_nconns > info->ksi_scheds[i].kss_nconns)
+			sched = &info->ksi_scheds[i];
+	}
+
+	return sched;
+}
+
+int
+ksocknal_local_ipvec (lnet_ni_t *ni, __u32 *ipaddrs)
+{
+	ksock_net_t       *net = ni->ni_data;
+	int		i;
+	int		nip;
+
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	nip = net->ksnn_ninterfaces;
+	LASSERT (nip <= LNET_MAX_INTERFACES);
+
+	/* Only offer interfaces for additional connections if I have
+	 * more than one. */
+	if (nip < 2) {
+		read_unlock(&ksocknal_data.ksnd_global_lock);
+		return 0;
+	}
+
+	for (i = 0; i < nip; i++) {
+		ipaddrs[i] = net->ksnn_interfaces[i].ksni_ipaddr;
+		LASSERT (ipaddrs[i] != 0);
+	}
+
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+	return (nip);
+}
+
+int
+ksocknal_match_peerip (ksock_interface_t *iface, __u32 *ips, int nips)
+{
+	int   best_netmatch = 0;
+	int   best_xor      = 0;
+	int   best	  = -1;
+	int   this_xor;
+	int   this_netmatch;
+	int   i;
+
+	for (i = 0; i < nips; i++) {
+		if (ips[i] == 0)
+			continue;
+
+		this_xor = (ips[i] ^ iface->ksni_ipaddr);
+		this_netmatch = ((this_xor & iface->ksni_netmask) == 0) ? 1 : 0;
+
+		if (!(best < 0 ||
+		      best_netmatch < this_netmatch ||
+		      (best_netmatch == this_netmatch &&
+		       best_xor > this_xor)))
+			continue;
+
+		best = i;
+		best_netmatch = this_netmatch;
+		best_xor = this_xor;
+	}
+
+	LASSERT (best >= 0);
+	return (best);
+}
+
+int
+ksocknal_select_ips(ksock_peer_t *peer, __u32 *peerips, int n_peerips)
+{
+	rwlock_t		*global_lock = &ksocknal_data.ksnd_global_lock;
+	ksock_net_t	*net = peer->ksnp_ni->ni_data;
+	ksock_interface_t  *iface;
+	ksock_interface_t  *best_iface;
+	int		 n_ips;
+	int		 i;
+	int		 j;
+	int		 k;
+	__u32	       ip;
+	__u32	       xor;
+	int		 this_netmatch;
+	int		 best_netmatch;
+	int		 best_npeers;
+
+	/* CAVEAT EMPTOR: We do all our interface matching with an
+	 * exclusive hold of global lock at IRQ priority.  We're only
+	 * expecting to be dealing with small numbers of interfaces, so the
+	 * O(n**3)-ness shouldn't matter */
+
+	/* Also note that I'm not going to return more than n_peerips
+	 * interfaces, even if I have more myself */
+
+	write_lock_bh(global_lock);
+
+	LASSERT (n_peerips <= LNET_MAX_INTERFACES);
+	LASSERT (net->ksnn_ninterfaces <= LNET_MAX_INTERFACES);
+
+	/* Only match interfaces for additional connections
+	 * if I have > 1 interface */
+	n_ips = (net->ksnn_ninterfaces < 2) ? 0 :
+		MIN(n_peerips, net->ksnn_ninterfaces);
+
+	for (i = 0; peer->ksnp_n_passive_ips < n_ips; i++) {
+		/*	      ^ yes really... */
+
+		/* If we have any new interfaces, first tick off all the
+		 * peer IPs that match old interfaces, then choose new
+		 * interfaces to match the remaining peer IPS.
+		 * We don't forget interfaces we've stopped using; we might
+		 * start using them again... */
+
+		if (i < peer->ksnp_n_passive_ips) {
+			/* Old interface. */
+			ip = peer->ksnp_passive_ips[i];
+			best_iface = ksocknal_ip2iface(peer->ksnp_ni, ip);
+
+			/* peer passive ips are kept up to date */
+			LASSERT(best_iface != NULL);
+		} else {
+			/* choose a new interface */
+			LASSERT (i == peer->ksnp_n_passive_ips);
+
+			best_iface = NULL;
+			best_netmatch = 0;
+			best_npeers = 0;
+
+			for (j = 0; j < net->ksnn_ninterfaces; j++) {
+				iface = &net->ksnn_interfaces[j];
+				ip = iface->ksni_ipaddr;
+
+				for (k = 0; k < peer->ksnp_n_passive_ips; k++)
+					if (peer->ksnp_passive_ips[k] == ip)
+						break;
+
+				if (k < peer->ksnp_n_passive_ips) /* using it already */
+					continue;
+
+				k = ksocknal_match_peerip(iface, peerips, n_peerips);
+				xor = (ip ^ peerips[k]);
+				this_netmatch = ((xor & iface->ksni_netmask) == 0) ? 1 : 0;
+
+				if (!(best_iface == NULL ||
+				      best_netmatch < this_netmatch ||
+				      (best_netmatch == this_netmatch &&
+				       best_npeers > iface->ksni_npeers)))
+					continue;
+
+				best_iface = iface;
+				best_netmatch = this_netmatch;
+				best_npeers = iface->ksni_npeers;
+			}
+
+			best_iface->ksni_npeers++;
+			ip = best_iface->ksni_ipaddr;
+			peer->ksnp_passive_ips[i] = ip;
+			peer->ksnp_n_passive_ips = i+1;
+		}
+
+		LASSERT (best_iface != NULL);
+
+		/* mark the best matching peer IP used */
+		j = ksocknal_match_peerip(best_iface, peerips, n_peerips);
+		peerips[j] = 0;
+	}
+
+	/* Overwrite input peer IP addresses */
+	memcpy(peerips, peer->ksnp_passive_ips, n_ips * sizeof(*peerips));
+
+	write_unlock_bh(global_lock);
+
+	return (n_ips);
+}
+
+void
+ksocknal_create_routes(ksock_peer_t *peer, int port,
+		       __u32 *peer_ipaddrs, int npeer_ipaddrs)
+{
+	ksock_route_t       *newroute = NULL;
+	rwlock_t		*global_lock = &ksocknal_data.ksnd_global_lock;
+	lnet_ni_t	   *ni = peer->ksnp_ni;
+	ksock_net_t	 *net = ni->ni_data;
+	struct list_head	  *rtmp;
+	ksock_route_t       *route;
+	ksock_interface_t   *iface;
+	ksock_interface_t   *best_iface;
+	int		  best_netmatch;
+	int		  this_netmatch;
+	int		  best_nroutes;
+	int		  i;
+	int		  j;
+
+	/* CAVEAT EMPTOR: We do all our interface matching with an
+	 * exclusive hold of global lock at IRQ priority.  We're only
+	 * expecting to be dealing with small numbers of interfaces, so the
+	 * O(n**3)-ness here shouldn't matter */
+
+	write_lock_bh(global_lock);
+
+	if (net->ksnn_ninterfaces < 2) {
+		/* Only create additional connections
+		 * if I have > 1 interface */
+		write_unlock_bh(global_lock);
+		return;
+	}
+
+	LASSERT (npeer_ipaddrs <= LNET_MAX_INTERFACES);
+
+	for (i = 0; i < npeer_ipaddrs; i++) {
+		if (newroute != NULL) {
+			newroute->ksnr_ipaddr = peer_ipaddrs[i];
+		} else {
+			write_unlock_bh(global_lock);
+
+			newroute = ksocknal_create_route(peer_ipaddrs[i], port);
+			if (newroute == NULL)
+				return;
+
+			write_lock_bh(global_lock);
+		}
+
+		if (peer->ksnp_closing) {
+			/* peer got closed under me */
+			break;
+		}
+
+		/* Already got a route? */
+		route = NULL;
+		list_for_each(rtmp, &peer->ksnp_routes) {
+			route = list_entry(rtmp, ksock_route_t, ksnr_list);
+
+			if (route->ksnr_ipaddr == newroute->ksnr_ipaddr)
+				break;
+
+			route = NULL;
+		}
+		if (route != NULL)
+			continue;
+
+		best_iface = NULL;
+		best_nroutes = 0;
+		best_netmatch = 0;
+
+		LASSERT (net->ksnn_ninterfaces <= LNET_MAX_INTERFACES);
+
+		/* Select interface to connect from */
+		for (j = 0; j < net->ksnn_ninterfaces; j++) {
+			iface = &net->ksnn_interfaces[j];
+
+			/* Using this interface already? */
+			list_for_each(rtmp, &peer->ksnp_routes) {
+				route = list_entry(rtmp, ksock_route_t,
+						       ksnr_list);
+
+				if (route->ksnr_myipaddr == iface->ksni_ipaddr)
+					break;
+
+				route = NULL;
+			}
+			if (route != NULL)
+				continue;
+
+			this_netmatch = (((iface->ksni_ipaddr ^
+					   newroute->ksnr_ipaddr) &
+					   iface->ksni_netmask) == 0) ? 1 : 0;
+
+			if (!(best_iface == NULL ||
+			      best_netmatch < this_netmatch ||
+			      (best_netmatch == this_netmatch &&
+			       best_nroutes > iface->ksni_nroutes)))
+				continue;
+
+			best_iface = iface;
+			best_netmatch = this_netmatch;
+			best_nroutes = iface->ksni_nroutes;
+		}
+
+		if (best_iface == NULL)
+			continue;
+
+		newroute->ksnr_myipaddr = best_iface->ksni_ipaddr;
+		best_iface->ksni_nroutes++;
+
+		ksocknal_add_route_locked(peer, newroute);
+		newroute = NULL;
+	}
+
+	write_unlock_bh(global_lock);
+	if (newroute != NULL)
+		ksocknal_route_decref(newroute);
+}
+
+int
+ksocknal_accept (lnet_ni_t *ni, socket_t *sock)
+{
+	ksock_connreq_t    *cr;
+	int		 rc;
+	__u32	       peer_ip;
+	int		 peer_port;
+
+	rc = libcfs_sock_getaddr(sock, 1, &peer_ip, &peer_port);
+	LASSERT (rc == 0);		      /* we succeeded before */
+
+	LIBCFS_ALLOC(cr, sizeof(*cr));
+	if (cr == NULL) {
+		LCONSOLE_ERROR_MSG(0x12f, "Dropping connection request from "
+				   "%u.%u.%u.%u: memory exhausted\n",
+				   HIPQUAD(peer_ip));
+		return -ENOMEM;
+	}
+
+	lnet_ni_addref(ni);
+	cr->ksncr_ni   = ni;
+	cr->ksncr_sock = sock;
+
+	spin_lock_bh(&ksocknal_data.ksnd_connd_lock);
+
+	list_add_tail(&cr->ksncr_list, &ksocknal_data.ksnd_connd_connreqs);
+	wake_up(&ksocknal_data.ksnd_connd_waitq);
+
+	spin_unlock_bh(&ksocknal_data.ksnd_connd_lock);
+	return 0;
+}
+
+int
+ksocknal_connecting (ksock_peer_t *peer, __u32 ipaddr)
+{
+	ksock_route_t   *route;
+
+	list_for_each_entry (route, &peer->ksnp_routes, ksnr_list) {
+
+		if (route->ksnr_ipaddr == ipaddr)
+			return route->ksnr_connecting;
+	}
+	return 0;
+}
+
+int
+ksocknal_create_conn (lnet_ni_t *ni, ksock_route_t *route,
+		      socket_t *sock, int type)
+{
+	rwlock_t		*global_lock = &ksocknal_data.ksnd_global_lock;
+	LIST_HEAD     (zombies);
+	lnet_process_id_t  peerid;
+	struct list_head	*tmp;
+	__u64	      incarnation;
+	ksock_conn_t      *conn;
+	ksock_conn_t      *conn2;
+	ksock_peer_t      *peer = NULL;
+	ksock_peer_t      *peer2;
+	ksock_sched_t     *sched;
+	ksock_hello_msg_t *hello;
+	int		   cpt;
+	ksock_tx_t	*tx;
+	ksock_tx_t	*txtmp;
+	int		rc;
+	int		active;
+	char	      *warn = NULL;
+
+	active = (route != NULL);
+
+	LASSERT (active == (type != SOCKLND_CONN_NONE));
+
+	LIBCFS_ALLOC(conn, sizeof(*conn));
+	if (conn == NULL) {
+		rc = -ENOMEM;
+		goto failed_0;
+	}
+
+	memset (conn, 0, sizeof (*conn));
+
+	conn->ksnc_peer = NULL;
+	conn->ksnc_route = NULL;
+	conn->ksnc_sock = sock;
+	/* 2 ref, 1 for conn, another extra ref prevents socket
+	 * being closed before establishment of connection */
+	atomic_set (&conn->ksnc_sock_refcount, 2);
+	conn->ksnc_type = type;
+	ksocknal_lib_save_callback(sock, conn);
+	atomic_set (&conn->ksnc_conn_refcount, 1); /* 1 ref for me */
+
+	conn->ksnc_rx_ready = 0;
+	conn->ksnc_rx_scheduled = 0;
+
+	INIT_LIST_HEAD (&conn->ksnc_tx_queue);
+	conn->ksnc_tx_ready = 0;
+	conn->ksnc_tx_scheduled = 0;
+	conn->ksnc_tx_carrier = NULL;
+	atomic_set (&conn->ksnc_tx_nob, 0);
+
+	LIBCFS_ALLOC(hello, offsetof(ksock_hello_msg_t,
+				     kshm_ips[LNET_MAX_INTERFACES]));
+	if (hello == NULL) {
+		rc = -ENOMEM;
+		goto failed_1;
+	}
+
+	/* stash conn's local and remote addrs */
+	rc = ksocknal_lib_get_conn_addrs (conn);
+	if (rc != 0)
+		goto failed_1;
+
+	/* Find out/confirm peer's NID and connection type and get the
+	 * vector of interfaces she's willing to let me connect to.
+	 * Passive connections use the listener timeout since the peer sends
+	 * eagerly */
+
+	if (active) {
+		peer = route->ksnr_peer;
+		LASSERT(ni == peer->ksnp_ni);
+
+		/* Active connection sends HELLO eagerly */
+		hello->kshm_nips = ksocknal_local_ipvec(ni, hello->kshm_ips);
+		peerid = peer->ksnp_id;
+
+		write_lock_bh(global_lock);
+		conn->ksnc_proto = peer->ksnp_proto;
+		write_unlock_bh(global_lock);
+
+		if (conn->ksnc_proto == NULL) {
+			 conn->ksnc_proto = &ksocknal_protocol_v3x;
+#if SOCKNAL_VERSION_DEBUG
+			 if (*ksocknal_tunables.ksnd_protocol == 2)
+				 conn->ksnc_proto = &ksocknal_protocol_v2x;
+			 else if (*ksocknal_tunables.ksnd_protocol == 1)
+				 conn->ksnc_proto = &ksocknal_protocol_v1x;
+#endif
+		}
+
+		rc = ksocknal_send_hello (ni, conn, peerid.nid, hello);
+		if (rc != 0)
+			goto failed_1;
+	} else {
+		peerid.nid = LNET_NID_ANY;
+		peerid.pid = LNET_PID_ANY;
+
+		/* Passive, get protocol from peer */
+		conn->ksnc_proto = NULL;
+	}
+
+	rc = ksocknal_recv_hello (ni, conn, hello, &peerid, &incarnation);
+	if (rc < 0)
+		goto failed_1;
+
+	LASSERT (rc == 0 || active);
+	LASSERT (conn->ksnc_proto != NULL);
+	LASSERT (peerid.nid != LNET_NID_ANY);
+
+	cpt = lnet_cpt_of_nid(peerid.nid);
+
+	if (active) {
+		ksocknal_peer_addref(peer);
+		write_lock_bh(global_lock);
+	} else {
+		rc = ksocknal_create_peer(&peer, ni, peerid);
+		if (rc != 0)
+			goto failed_1;
+
+		write_lock_bh(global_lock);
+
+		/* called with a ref on ni, so shutdown can't have started */
+		LASSERT (((ksock_net_t *) ni->ni_data)->ksnn_shutdown == 0);
+
+		peer2 = ksocknal_find_peer_locked(ni, peerid);
+		if (peer2 == NULL) {
+			/* NB this puts an "empty" peer in the peer
+			 * table (which takes my ref) */
+			list_add_tail(&peer->ksnp_list,
+					  ksocknal_nid2peerlist(peerid.nid));
+		} else {
+			ksocknal_peer_decref(peer);
+			peer = peer2;
+		}
+
+		/* +1 ref for me */
+		ksocknal_peer_addref(peer);
+		peer->ksnp_accepting++;
+
+		/* Am I already connecting to this guy?  Resolve in
+		 * favour of higher NID... */
+		if (peerid.nid < ni->ni_nid &&
+		    ksocknal_connecting(peer, conn->ksnc_ipaddr)) {
+			rc = EALREADY;
+			warn = "connection race resolution";
+			goto failed_2;
+		}
+	}
+
+	if (peer->ksnp_closing ||
+	    (active && route->ksnr_deleted)) {
+		/* peer/route got closed under me */
+		rc = -ESTALE;
+		warn = "peer/route removed";
+		goto failed_2;
+	}
+
+	if (peer->ksnp_proto == NULL) {
+		/* Never connected before.
+		 * NB recv_hello may have returned EPROTO to signal my peer
+		 * wants a different protocol than the one I asked for.
+		 */
+		LASSERT (list_empty(&peer->ksnp_conns));
+
+		peer->ksnp_proto = conn->ksnc_proto;
+		peer->ksnp_incarnation = incarnation;
+	}
+
+	if (peer->ksnp_proto != conn->ksnc_proto ||
+	    peer->ksnp_incarnation != incarnation) {
+		/* Peer rebooted or I've got the wrong protocol version */
+		ksocknal_close_peer_conns_locked(peer, 0, 0);
+
+		peer->ksnp_proto = NULL;
+		rc = ESTALE;
+		warn = peer->ksnp_incarnation != incarnation ?
+		       "peer rebooted" :
+		       "wrong proto version";
+		goto failed_2;
+	}
+
+	switch (rc) {
+	default:
+		LBUG();
+	case 0:
+		break;
+	case EALREADY:
+		warn = "lost conn race";
+		goto failed_2;
+	case EPROTO:
+		warn = "retry with different protocol version";
+		goto failed_2;
+	}
+
+	/* Refuse to duplicate an existing connection, unless this is a
+	 * loopback connection */
+	if (conn->ksnc_ipaddr != conn->ksnc_myipaddr) {
+		list_for_each(tmp, &peer->ksnp_conns) {
+			conn2 = list_entry(tmp, ksock_conn_t, ksnc_list);
+
+			if (conn2->ksnc_ipaddr != conn->ksnc_ipaddr ||
+			    conn2->ksnc_myipaddr != conn->ksnc_myipaddr ||
+			    conn2->ksnc_type != conn->ksnc_type)
+				continue;
+
+			/* Reply on a passive connection attempt so the peer
+			 * realises we're connected. */
+			LASSERT (rc == 0);
+			if (!active)
+				rc = EALREADY;
+
+			warn = "duplicate";
+			goto failed_2;
+		}
+	}
+
+	/* If the connection created by this route didn't bind to the IP
+	 * address the route connected to, the connection/route matching
+	 * code below probably isn't going to work. */
+	if (active &&
+	    route->ksnr_ipaddr != conn->ksnc_ipaddr) {
+		CERROR("Route %s %u.%u.%u.%u connected to %u.%u.%u.%u\n",
+		       libcfs_id2str(peer->ksnp_id),
+		       HIPQUAD(route->ksnr_ipaddr),
+		       HIPQUAD(conn->ksnc_ipaddr));
+	}
+
+	/* Search for a route corresponding to the new connection and
+	 * create an association.  This allows incoming connections created
+	 * by routes in my peer to match my own route entries so I don't
+	 * continually create duplicate routes. */
+	list_for_each (tmp, &peer->ksnp_routes) {
+		route = list_entry(tmp, ksock_route_t, ksnr_list);
+
+		if (route->ksnr_ipaddr != conn->ksnc_ipaddr)
+			continue;
+
+		ksocknal_associate_route_conn_locked(route, conn);
+		break;
+	}
+
+	conn->ksnc_peer = peer;		 /* conn takes my ref on peer */
+	peer->ksnp_last_alive = cfs_time_current();
+	peer->ksnp_send_keepalive = 0;
+	peer->ksnp_error = 0;
+
+	sched = ksocknal_choose_scheduler_locked(cpt);
+	sched->kss_nconns++;
+	conn->ksnc_scheduler = sched;
+
+	conn->ksnc_tx_last_post = cfs_time_current();
+	/* Set the deadline for the outgoing HELLO to drain */
+	conn->ksnc_tx_bufnob = cfs_sock_wmem_queued(sock);
+	conn->ksnc_tx_deadline = cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
+	mb();   /* order with adding to peer's conn list */
+
+	list_add (&conn->ksnc_list, &peer->ksnp_conns);
+	ksocknal_conn_addref(conn);
+
+	ksocknal_new_packet(conn, 0);
+
+	conn->ksnc_zc_capable = ksocknal_lib_zc_capable(conn);
+
+	/* Take packets blocking for this connection. */
+	list_for_each_entry_safe(tx, txtmp, &peer->ksnp_tx_queue, tx_list) {
+		if (conn->ksnc_proto->pro_match_tx(conn, tx, tx->tx_nonblk) == SOCKNAL_MATCH_NO)
+				continue;
+
+		list_del (&tx->tx_list);
+		ksocknal_queue_tx_locked (tx, conn);
+	}
+
+	write_unlock_bh(global_lock);
+
+	/* We've now got a new connection.  Any errors from here on are just
+	 * like "normal" comms errors and we close the connection normally.
+	 * NB (a) we still have to send the reply HELLO for passive
+	 *	connections,
+	 *    (b) normal I/O on the conn is blocked until I setup and call the
+	 *	socket callbacks.
+	 */
+
+	CDEBUG(D_NET, "New conn %s p %d.x %u.%u.%u.%u -> %u.%u.%u.%u/%d"
+	       " incarnation:"LPD64" sched[%d:%d]\n",
+	       libcfs_id2str(peerid), conn->ksnc_proto->pro_version,
+	       HIPQUAD(conn->ksnc_myipaddr), HIPQUAD(conn->ksnc_ipaddr),
+	       conn->ksnc_port, incarnation, cpt,
+	       (int)(sched - &sched->kss_info->ksi_scheds[0]));
+
+	if (active) {
+		/* additional routes after interface exchange? */
+		ksocknal_create_routes(peer, conn->ksnc_port,
+				       hello->kshm_ips, hello->kshm_nips);
+	} else {
+		hello->kshm_nips = ksocknal_select_ips(peer, hello->kshm_ips,
+						       hello->kshm_nips);
+		rc = ksocknal_send_hello(ni, conn, peerid.nid, hello);
+	}
+
+	LIBCFS_FREE(hello, offsetof(ksock_hello_msg_t,
+				    kshm_ips[LNET_MAX_INTERFACES]));
+
+	/* setup the socket AFTER I've received hello (it disables
+	 * SO_LINGER).  I might call back to the acceptor who may want
+	 * to send a protocol version response and then close the
+	 * socket; this ensures the socket only tears down after the
+	 * response has been sent. */
+	if (rc == 0)
+		rc = ksocknal_lib_setup_sock(sock);
+
+	write_lock_bh(global_lock);
+
+	/* NB my callbacks block while I hold ksnd_global_lock */
+	ksocknal_lib_set_callback(sock, conn);
+
+	if (!active)
+		peer->ksnp_accepting--;
+
+	write_unlock_bh(global_lock);
+
+	if (rc != 0) {
+		write_lock_bh(global_lock);
+		if (!conn->ksnc_closing) {
+			/* could be closed by another thread */
+			ksocknal_close_conn_locked(conn, rc);
+		}
+		write_unlock_bh(global_lock);
+	} else if (ksocknal_connsock_addref(conn) == 0) {
+		/* Allow I/O to proceed. */
+		ksocknal_read_callback(conn);
+		ksocknal_write_callback(conn);
+		ksocknal_connsock_decref(conn);
+	}
+
+	ksocknal_connsock_decref(conn);
+	ksocknal_conn_decref(conn);
+	return rc;
+
+ failed_2:
+	if (!peer->ksnp_closing &&
+	    list_empty (&peer->ksnp_conns) &&
+	    list_empty (&peer->ksnp_routes)) {
+		list_add(&zombies, &peer->ksnp_tx_queue);
+		list_del_init(&peer->ksnp_tx_queue);
+		ksocknal_unlink_peer_locked(peer);
+	}
+
+	write_unlock_bh(global_lock);
+
+	if (warn != NULL) {
+		if (rc < 0)
+			CERROR("Not creating conn %s type %d: %s\n",
+			       libcfs_id2str(peerid), conn->ksnc_type, warn);
+		else
+			CDEBUG(D_NET, "Not creating conn %s type %d: %s\n",
+			      libcfs_id2str(peerid), conn->ksnc_type, warn);
+	}
+
+	if (!active) {
+		if (rc > 0) {
+			/* Request retry by replying with CONN_NONE
+			 * ksnc_proto has been set already */
+			conn->ksnc_type = SOCKLND_CONN_NONE;
+			hello->kshm_nips = 0;
+			ksocknal_send_hello(ni, conn, peerid.nid, hello);
+		}
+
+		write_lock_bh(global_lock);
+		peer->ksnp_accepting--;
+		write_unlock_bh(global_lock);
+	}
+
+	ksocknal_txlist_done(ni, &zombies, 1);
+	ksocknal_peer_decref(peer);
+
+ failed_1:
+	if (hello != NULL)
+		LIBCFS_FREE(hello, offsetof(ksock_hello_msg_t,
+					    kshm_ips[LNET_MAX_INTERFACES]));
+
+	LIBCFS_FREE (conn, sizeof(*conn));
+
+ failed_0:
+	libcfs_sock_release(sock);
+	return rc;
+}
+
+void
+ksocknal_close_conn_locked (ksock_conn_t *conn, int error)
+{
+	/* This just does the immmediate housekeeping, and queues the
+	 * connection for the reaper to terminate.
+	 * Caller holds ksnd_global_lock exclusively in irq context */
+	ksock_peer_t      *peer = conn->ksnc_peer;
+	ksock_route_t     *route;
+	ksock_conn_t      *conn2;
+	struct list_head	*tmp;
+
+	LASSERT (peer->ksnp_error == 0);
+	LASSERT (!conn->ksnc_closing);
+	conn->ksnc_closing = 1;
+
+	/* ksnd_deathrow_conns takes over peer's ref */
+	list_del (&conn->ksnc_list);
+
+	route = conn->ksnc_route;
+	if (route != NULL) {
+		/* dissociate conn from route... */
+		LASSERT (!route->ksnr_deleted);
+		LASSERT ((route->ksnr_connected & (1 << conn->ksnc_type)) != 0);
+
+		conn2 = NULL;
+		list_for_each(tmp, &peer->ksnp_conns) {
+			conn2 = list_entry(tmp, ksock_conn_t, ksnc_list);
+
+			if (conn2->ksnc_route == route &&
+			    conn2->ksnc_type == conn->ksnc_type)
+				break;
+
+			conn2 = NULL;
+		}
+		if (conn2 == NULL)
+			route->ksnr_connected &= ~(1 << conn->ksnc_type);
+
+		conn->ksnc_route = NULL;
+
+#if 0	   /* irrelevent with only eager routes */
+		/* make route least favourite */
+		list_del (&route->ksnr_list);
+		list_add_tail (&route->ksnr_list, &peer->ksnp_routes);
+#endif
+		ksocknal_route_decref(route);     /* drop conn's ref on route */
+	}
+
+	if (list_empty (&peer->ksnp_conns)) {
+		/* No more connections to this peer */
+
+		if (!list_empty(&peer->ksnp_tx_queue)) {
+			ksock_tx_t *tx;
+
+			LASSERT (conn->ksnc_proto == &ksocknal_protocol_v3x);
+
+			/* throw them to the last connection...,
+			 * these TXs will be send to /dev/null by scheduler */
+			list_for_each_entry(tx, &peer->ksnp_tx_queue,
+						tx_list)
+				ksocknal_tx_prep(conn, tx);
+
+			spin_lock_bh(&conn->ksnc_scheduler->kss_lock);
+			list_splice_init(&peer->ksnp_tx_queue,
+					     &conn->ksnc_tx_queue);
+			spin_unlock_bh(&conn->ksnc_scheduler->kss_lock);
+		}
+
+		peer->ksnp_proto = NULL;	/* renegotiate protocol version */
+		peer->ksnp_error = error;       /* stash last conn close reason */
+
+		if (list_empty (&peer->ksnp_routes)) {
+			/* I've just closed last conn belonging to a
+			 * peer with no routes to it */
+			ksocknal_unlink_peer_locked (peer);
+		}
+	}
+
+	spin_lock_bh(&ksocknal_data.ksnd_reaper_lock);
+
+	list_add_tail(&conn->ksnc_list,
+			  &ksocknal_data.ksnd_deathrow_conns);
+	wake_up(&ksocknal_data.ksnd_reaper_waitq);
+
+	spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
+}
+
+void
+ksocknal_peer_failed (ksock_peer_t *peer)
+{
+	int	notify = 0;
+	cfs_time_t last_alive = 0;
+
+	/* There has been a connection failure or comms error; but I'll only
+	 * tell LNET I think the peer is dead if it's to another kernel and
+	 * there are no connections or connection attempts in existance. */
+
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	if ((peer->ksnp_id.pid & LNET_PID_USERFLAG) == 0 &&
+	    list_empty(&peer->ksnp_conns) &&
+	    peer->ksnp_accepting == 0 &&
+	    ksocknal_find_connecting_route_locked(peer) == NULL) {
+		notify = 1;
+		last_alive = peer->ksnp_last_alive;
+	}
+
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+
+	if (notify)
+		lnet_notify (peer->ksnp_ni, peer->ksnp_id.nid, 0,
+			     last_alive);
+}
+
+void
+ksocknal_finalize_zcreq(ksock_conn_t *conn)
+{
+	ksock_peer_t     *peer = conn->ksnc_peer;
+	ksock_tx_t       *tx;
+	ksock_tx_t       *tmp;
+	LIST_HEAD    (zlist);
+
+	/* NB safe to finalize TXs because closing of socket will
+	 * abort all buffered data */
+	LASSERT (conn->ksnc_sock == NULL);
+
+	spin_lock(&peer->ksnp_lock);
+
+	list_for_each_entry_safe(tx, tmp, &peer->ksnp_zc_req_list, tx_zc_list) {
+		if (tx->tx_conn != conn)
+			continue;
+
+		LASSERT (tx->tx_msg.ksm_zc_cookies[0] != 0);
+
+		tx->tx_msg.ksm_zc_cookies[0] = 0;
+		tx->tx_zc_aborted = 1; /* mark it as not-acked */
+		list_del(&tx->tx_zc_list);
+		list_add(&tx->tx_zc_list, &zlist);
+	}
+
+	spin_unlock(&peer->ksnp_lock);
+
+	while (!list_empty(&zlist)) {
+		tx = list_entry(zlist.next, ksock_tx_t, tx_zc_list);
+
+		list_del(&tx->tx_zc_list);
+		ksocknal_tx_decref(tx);
+	}
+}
+
+void
+ksocknal_terminate_conn (ksock_conn_t *conn)
+{
+	/* This gets called by the reaper (guaranteed thread context) to
+	 * disengage the socket from its callbacks and close it.
+	 * ksnc_refcount will eventually hit zero, and then the reaper will
+	 * destroy it. */
+	ksock_peer_t     *peer = conn->ksnc_peer;
+	ksock_sched_t    *sched = conn->ksnc_scheduler;
+	int	       failed = 0;
+
+	LASSERT(conn->ksnc_closing);
+
+	/* wake up the scheduler to "send" all remaining packets to /dev/null */
+	spin_lock_bh(&sched->kss_lock);
+
+	/* a closing conn is always ready to tx */
+	conn->ksnc_tx_ready = 1;
+
+	if (!conn->ksnc_tx_scheduled &&
+	    !list_empty(&conn->ksnc_tx_queue)){
+		list_add_tail (&conn->ksnc_tx_list,
+			       &sched->kss_tx_conns);
+		conn->ksnc_tx_scheduled = 1;
+		/* extra ref for scheduler */
+		ksocknal_conn_addref(conn);
+
+		wake_up (&sched->kss_waitq);
+	}
+
+	spin_unlock_bh(&sched->kss_lock);
+
+	/* serialise with callbacks */
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	ksocknal_lib_reset_callback(conn->ksnc_sock, conn);
+
+	/* OK, so this conn may not be completely disengaged from its
+	 * scheduler yet, but it _has_ committed to terminate... */
+	conn->ksnc_scheduler->kss_nconns--;
+
+	if (peer->ksnp_error != 0) {
+		/* peer's last conn closed in error */
+		LASSERT (list_empty (&peer->ksnp_conns));
+		failed = 1;
+		peer->ksnp_error = 0;     /* avoid multiple notifications */
+	}
+
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+	if (failed)
+		ksocknal_peer_failed(peer);
+
+	/* The socket is closed on the final put; either here, or in
+	 * ksocknal_{send,recv}msg().  Since we set up the linger2 option
+	 * when the connection was established, this will close the socket
+	 * immediately, aborting anything buffered in it. Any hung
+	 * zero-copy transmits will therefore complete in finite time. */
+	ksocknal_connsock_decref(conn);
+}
+
+void
+ksocknal_queue_zombie_conn (ksock_conn_t *conn)
+{
+	/* Queue the conn for the reaper to destroy */
+
+	LASSERT(atomic_read(&conn->ksnc_conn_refcount) == 0);
+	spin_lock_bh(&ksocknal_data.ksnd_reaper_lock);
+
+	list_add_tail(&conn->ksnc_list, &ksocknal_data.ksnd_zombie_conns);
+	wake_up(&ksocknal_data.ksnd_reaper_waitq);
+
+	spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
+}
+
+void
+ksocknal_destroy_conn (ksock_conn_t *conn)
+{
+	cfs_time_t      last_rcv;
+
+	/* Final coup-de-grace of the reaper */
+	CDEBUG (D_NET, "connection %p\n", conn);
+
+	LASSERT (atomic_read (&conn->ksnc_conn_refcount) == 0);
+	LASSERT (atomic_read (&conn->ksnc_sock_refcount) == 0);
+	LASSERT (conn->ksnc_sock == NULL);
+	LASSERT (conn->ksnc_route == NULL);
+	LASSERT (!conn->ksnc_tx_scheduled);
+	LASSERT (!conn->ksnc_rx_scheduled);
+	LASSERT (list_empty(&conn->ksnc_tx_queue));
+
+	/* complete current receive if any */
+	switch (conn->ksnc_rx_state) {
+	case SOCKNAL_RX_LNET_PAYLOAD:
+		last_rcv = conn->ksnc_rx_deadline -
+			   cfs_time_seconds(*ksocknal_tunables.ksnd_timeout);
+		CERROR("Completing partial receive from %s[%d]"
+		       ", ip %d.%d.%d.%d:%d, with error, wanted: %d, left: %d, "
+		       "last alive is %ld secs ago\n",
+		       libcfs_id2str(conn->ksnc_peer->ksnp_id), conn->ksnc_type,
+		       HIPQUAD(conn->ksnc_ipaddr), conn->ksnc_port,
+		       conn->ksnc_rx_nob_wanted, conn->ksnc_rx_nob_left,
+		       cfs_duration_sec(cfs_time_sub(cfs_time_current(),
+					last_rcv)));
+		lnet_finalize (conn->ksnc_peer->ksnp_ni,
+			       conn->ksnc_cookie, -EIO);
+		break;
+	case SOCKNAL_RX_LNET_HEADER:
+		if (conn->ksnc_rx_started)
+			CERROR("Incomplete receive of lnet header from %s"
+			       ", ip %d.%d.%d.%d:%d, with error, protocol: %d.x.\n",
+			       libcfs_id2str(conn->ksnc_peer->ksnp_id),
+			       HIPQUAD(conn->ksnc_ipaddr), conn->ksnc_port,
+			       conn->ksnc_proto->pro_version);
+		break;
+	case SOCKNAL_RX_KSM_HEADER:
+		if (conn->ksnc_rx_started)
+			CERROR("Incomplete receive of ksock message from %s"
+			       ", ip %d.%d.%d.%d:%d, with error, protocol: %d.x.\n",
+			       libcfs_id2str(conn->ksnc_peer->ksnp_id),
+			       HIPQUAD(conn->ksnc_ipaddr), conn->ksnc_port,
+			       conn->ksnc_proto->pro_version);
+		break;
+	case SOCKNAL_RX_SLOP:
+		if (conn->ksnc_rx_started)
+			CERROR("Incomplete receive of slops from %s"
+			       ", ip %d.%d.%d.%d:%d, with error\n",
+			       libcfs_id2str(conn->ksnc_peer->ksnp_id),
+			       HIPQUAD(conn->ksnc_ipaddr), conn->ksnc_port);
+	       break;
+	default:
+		LBUG ();
+		break;
+	}
+
+	ksocknal_peer_decref(conn->ksnc_peer);
+
+	LIBCFS_FREE (conn, sizeof (*conn));
+}
+
+int
+ksocknal_close_peer_conns_locked (ksock_peer_t *peer, __u32 ipaddr, int why)
+{
+	ksock_conn_t       *conn;
+	struct list_head	 *ctmp;
+	struct list_head	 *cnxt;
+	int		 count = 0;
+
+	list_for_each_safe (ctmp, cnxt, &peer->ksnp_conns) {
+		conn = list_entry (ctmp, ksock_conn_t, ksnc_list);
+
+		if (ipaddr == 0 ||
+		    conn->ksnc_ipaddr == ipaddr) {
+			count++;
+			ksocknal_close_conn_locked (conn, why);
+		}
+	}
+
+	return (count);
+}
+
+int
+ksocknal_close_conn_and_siblings (ksock_conn_t *conn, int why)
+{
+	ksock_peer_t     *peer = conn->ksnc_peer;
+	__u32	     ipaddr = conn->ksnc_ipaddr;
+	int	       count;
+
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	count = ksocknal_close_peer_conns_locked (peer, ipaddr, why);
+
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+	return (count);
+}
+
+int
+ksocknal_close_matching_conns (lnet_process_id_t id, __u32 ipaddr)
+{
+	ksock_peer_t       *peer;
+	struct list_head	 *ptmp;
+	struct list_head	 *pnxt;
+	int		 lo;
+	int		 hi;
+	int		 i;
+	int		 count = 0;
+
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	if (id.nid != LNET_NID_ANY)
+		lo = hi = (int)(ksocknal_nid2peerlist(id.nid) - ksocknal_data.ksnd_peers);
+	else {
+		lo = 0;
+		hi = ksocknal_data.ksnd_peer_hash_size - 1;
+	}
+
+	for (i = lo; i <= hi; i++) {
+		list_for_each_safe (ptmp, pnxt,
+					&ksocknal_data.ksnd_peers[i]) {
+
+			peer = list_entry (ptmp, ksock_peer_t, ksnp_list);
+
+			if (!((id.nid == LNET_NID_ANY || id.nid == peer->ksnp_id.nid) &&
+			      (id.pid == LNET_PID_ANY || id.pid == peer->ksnp_id.pid)))
+				continue;
+
+			count += ksocknal_close_peer_conns_locked (peer, ipaddr, 0);
+		}
+	}
+
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+	/* wildcards always succeed */
+	if (id.nid == LNET_NID_ANY || id.pid == LNET_PID_ANY || ipaddr == 0)
+		return (0);
+
+	return (count == 0 ? -ENOENT : 0);
+}
+
+void
+ksocknal_notify (lnet_ni_t *ni, lnet_nid_t gw_nid, int alive)
+{
+	/* The router is telling me she's been notified of a change in
+	 * gateway state.... */
+	lnet_process_id_t  id = {0};
+
+	id.nid = gw_nid;
+	id.pid = LNET_PID_ANY;
+
+	CDEBUG (D_NET, "gw %s %s\n", libcfs_nid2str(gw_nid),
+		alive ? "up" : "down");
+
+	if (!alive) {
+		/* If the gateway crashed, close all open connections... */
+		ksocknal_close_matching_conns (id, 0);
+		return;
+	}
+
+	/* ...otherwise do nothing.  We can only establish new connections
+	 * if we have autroutes, and these connect on demand. */
+}
+
+void
+ksocknal_query (lnet_ni_t *ni, lnet_nid_t nid, cfs_time_t *when)
+{
+	int		connect = 1;
+	cfs_time_t	 last_alive = 0;
+	cfs_time_t	 now = cfs_time_current();
+	ksock_peer_t      *peer = NULL;
+	rwlock_t		*glock = &ksocknal_data.ksnd_global_lock;
+	lnet_process_id_t  id = {.nid = nid, .pid = LUSTRE_SRV_LNET_PID};
+
+	read_lock(glock);
+
+	peer = ksocknal_find_peer_locked(ni, id);
+	if (peer != NULL) {
+		struct list_head       *tmp;
+		ksock_conn_t     *conn;
+		int	       bufnob;
+
+		list_for_each (tmp, &peer->ksnp_conns) {
+			conn = list_entry(tmp, ksock_conn_t, ksnc_list);
+			bufnob = cfs_sock_wmem_queued(conn->ksnc_sock);
+
+			if (bufnob < conn->ksnc_tx_bufnob) {
+				/* something got ACKed */
+				conn->ksnc_tx_deadline =
+					cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
+				peer->ksnp_last_alive = now;
+				conn->ksnc_tx_bufnob = bufnob;
+			}
+		}
+
+		last_alive = peer->ksnp_last_alive;
+		if (ksocknal_find_connectable_route_locked(peer) == NULL)
+			connect = 0;
+	}
+
+	read_unlock(glock);
+
+	if (last_alive != 0)
+		*when = last_alive;
+
+	CDEBUG(D_NET, "Peer %s %p, alive %ld secs ago, connect %d\n",
+	       libcfs_nid2str(nid), peer,
+	       last_alive ? cfs_duration_sec(now - last_alive) : -1,
+	       connect);
+
+	if (!connect)
+		return;
+
+	ksocknal_add_peer(ni, id, LNET_NIDADDR(nid), lnet_acceptor_port());
+
+	write_lock_bh(glock);
+
+	peer = ksocknal_find_peer_locked(ni, id);
+	if (peer != NULL)
+		ksocknal_launch_all_connections_locked(peer);
+
+	write_unlock_bh(glock);
+	return;
+}
+
+void
+ksocknal_push_peer (ksock_peer_t *peer)
+{
+	int	       index;
+	int	       i;
+	struct list_head       *tmp;
+	ksock_conn_t     *conn;
+
+	for (index = 0; ; index++) {
+		read_lock(&ksocknal_data.ksnd_global_lock);
+
+		i = 0;
+		conn = NULL;
+
+		list_for_each (tmp, &peer->ksnp_conns) {
+			if (i++ == index) {
+				conn = list_entry (tmp, ksock_conn_t,
+						       ksnc_list);
+				ksocknal_conn_addref(conn);
+				break;
+			}
+		}
+
+		read_unlock(&ksocknal_data.ksnd_global_lock);
+
+		if (conn == NULL)
+			break;
+
+		ksocknal_lib_push_conn (conn);
+		ksocknal_conn_decref(conn);
+	}
+}
+
+int
+ksocknal_push (lnet_ni_t *ni, lnet_process_id_t id)
+{
+	ksock_peer_t      *peer;
+	struct list_head	*tmp;
+	int		index;
+	int		i;
+	int		j;
+	int		rc = -ENOENT;
+
+	for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) {
+		for (j = 0; ; j++) {
+			read_lock(&ksocknal_data.ksnd_global_lock);
+
+			index = 0;
+			peer = NULL;
+
+			list_for_each (tmp, &ksocknal_data.ksnd_peers[i]) {
+				peer = list_entry(tmp, ksock_peer_t,
+						      ksnp_list);
+
+				if (!((id.nid == LNET_NID_ANY ||
+				       id.nid == peer->ksnp_id.nid) &&
+				      (id.pid == LNET_PID_ANY ||
+				       id.pid == peer->ksnp_id.pid))) {
+					peer = NULL;
+					continue;
+				}
+
+				if (index++ == j) {
+					ksocknal_peer_addref(peer);
+					break;
+				}
+			}
+
+			read_unlock(&ksocknal_data.ksnd_global_lock);
+
+			if (peer != NULL) {
+				rc = 0;
+				ksocknal_push_peer (peer);
+				ksocknal_peer_decref(peer);
+			}
+		}
+
+	}
+
+	return (rc);
+}
+
+int
+ksocknal_add_interface(lnet_ni_t *ni, __u32 ipaddress, __u32 netmask)
+{
+	ksock_net_t       *net = ni->ni_data;
+	ksock_interface_t *iface;
+	int		rc;
+	int		i;
+	int		j;
+	struct list_head	*ptmp;
+	ksock_peer_t      *peer;
+	struct list_head	*rtmp;
+	ksock_route_t     *route;
+
+	if (ipaddress == 0 ||
+	    netmask == 0)
+		return (-EINVAL);
+
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	iface = ksocknal_ip2iface(ni, ipaddress);
+	if (iface != NULL) {
+		/* silently ignore dups */
+		rc = 0;
+	} else if (net->ksnn_ninterfaces == LNET_MAX_INTERFACES) {
+		rc = -ENOSPC;
+	} else {
+		iface = &net->ksnn_interfaces[net->ksnn_ninterfaces++];
+
+		iface->ksni_ipaddr = ipaddress;
+		iface->ksni_netmask = netmask;
+		iface->ksni_nroutes = 0;
+		iface->ksni_npeers = 0;
+
+		for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) {
+			list_for_each(ptmp, &ksocknal_data.ksnd_peers[i]) {
+				peer = list_entry(ptmp, ksock_peer_t,
+						      ksnp_list);
+
+				for (j = 0; j < peer->ksnp_n_passive_ips; j++)
+					if (peer->ksnp_passive_ips[j] == ipaddress)
+						iface->ksni_npeers++;
+
+				list_for_each(rtmp, &peer->ksnp_routes) {
+					route = list_entry(rtmp,
+							       ksock_route_t,
+							       ksnr_list);
+
+					if (route->ksnr_myipaddr == ipaddress)
+						iface->ksni_nroutes++;
+				}
+			}
+		}
+
+		rc = 0;
+		/* NB only new connections will pay attention to the new interface! */
+	}
+
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+	return (rc);
+}
+
+void
+ksocknal_peer_del_interface_locked(ksock_peer_t *peer, __u32 ipaddr)
+{
+	struct list_head	 *tmp;
+	struct list_head	 *nxt;
+	ksock_route_t      *route;
+	ksock_conn_t       *conn;
+	int		 i;
+	int		 j;
+
+	for (i = 0; i < peer->ksnp_n_passive_ips; i++)
+		if (peer->ksnp_passive_ips[i] == ipaddr) {
+			for (j = i+1; j < peer->ksnp_n_passive_ips; j++)
+				peer->ksnp_passive_ips[j-1] =
+					peer->ksnp_passive_ips[j];
+			peer->ksnp_n_passive_ips--;
+			break;
+		}
+
+	list_for_each_safe(tmp, nxt, &peer->ksnp_routes) {
+		route = list_entry (tmp, ksock_route_t, ksnr_list);
+
+		if (route->ksnr_myipaddr != ipaddr)
+			continue;
+
+		if (route->ksnr_share_count != 0) {
+			/* Manually created; keep, but unbind */
+			route->ksnr_myipaddr = 0;
+		} else {
+			ksocknal_del_route_locked(route);
+		}
+	}
+
+	list_for_each_safe(tmp, nxt, &peer->ksnp_conns) {
+		conn = list_entry(tmp, ksock_conn_t, ksnc_list);
+
+		if (conn->ksnc_myipaddr == ipaddr)
+			ksocknal_close_conn_locked (conn, 0);
+	}
+}
+
+int
+ksocknal_del_interface(lnet_ni_t *ni, __u32 ipaddress)
+{
+	ksock_net_t       *net = ni->ni_data;
+	int		rc = -ENOENT;
+	struct list_head	*tmp;
+	struct list_head	*nxt;
+	ksock_peer_t      *peer;
+	__u32	      this_ip;
+	int		i;
+	int		j;
+
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	for (i = 0; i < net->ksnn_ninterfaces; i++) {
+		this_ip = net->ksnn_interfaces[i].ksni_ipaddr;
+
+		if (!(ipaddress == 0 ||
+		      ipaddress == this_ip))
+			continue;
+
+		rc = 0;
+
+		for (j = i+1; j < net->ksnn_ninterfaces; j++)
+			net->ksnn_interfaces[j-1] =
+				net->ksnn_interfaces[j];
+
+		net->ksnn_ninterfaces--;
+
+		for (j = 0; j < ksocknal_data.ksnd_peer_hash_size; j++) {
+			list_for_each_safe(tmp, nxt,
+					       &ksocknal_data.ksnd_peers[j]) {
+				peer = list_entry(tmp, ksock_peer_t,
+						      ksnp_list);
+
+				if (peer->ksnp_ni != ni)
+					continue;
+
+				ksocknal_peer_del_interface_locked(peer, this_ip);
+			}
+		}
+	}
+
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+	return (rc);
+}
+
+int
+ksocknal_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg)
+{
+	lnet_process_id_t id = {0};
+	struct libcfs_ioctl_data *data = arg;
+	int rc;
+
+	switch(cmd) {
+	case IOC_LIBCFS_GET_INTERFACE: {
+		ksock_net_t       *net = ni->ni_data;
+		ksock_interface_t *iface;
+
+		read_lock(&ksocknal_data.ksnd_global_lock);
+
+		if (data->ioc_count >= (__u32)net->ksnn_ninterfaces) {
+			rc = -ENOENT;
+		} else {
+			rc = 0;
+			iface = &net->ksnn_interfaces[data->ioc_count];
+
+			data->ioc_u32[0] = iface->ksni_ipaddr;
+			data->ioc_u32[1] = iface->ksni_netmask;
+			data->ioc_u32[2] = iface->ksni_npeers;
+			data->ioc_u32[3] = iface->ksni_nroutes;
+		}
+
+		read_unlock(&ksocknal_data.ksnd_global_lock);
+		return rc;
+	}
+
+	case IOC_LIBCFS_ADD_INTERFACE:
+		return ksocknal_add_interface(ni,
+					      data->ioc_u32[0], /* IP address */
+					      data->ioc_u32[1]); /* net mask */
+
+	case IOC_LIBCFS_DEL_INTERFACE:
+		return ksocknal_del_interface(ni,
+					      data->ioc_u32[0]); /* IP address */
+
+	case IOC_LIBCFS_GET_PEER: {
+		__u32	    myip = 0;
+		__u32	    ip = 0;
+		int	      port = 0;
+		int	      conn_count = 0;
+		int	      share_count = 0;
+
+		rc = ksocknal_get_peer_info(ni, data->ioc_count,
+					    &id, &myip, &ip, &port,
+					    &conn_count,  &share_count);
+		if (rc != 0)
+			return rc;
+
+		data->ioc_nid    = id.nid;
+		data->ioc_count  = share_count;
+		data->ioc_u32[0] = ip;
+		data->ioc_u32[1] = port;
+		data->ioc_u32[2] = myip;
+		data->ioc_u32[3] = conn_count;
+		data->ioc_u32[4] = id.pid;
+		return 0;
+	}
+
+	case IOC_LIBCFS_ADD_PEER:
+		id.nid = data->ioc_nid;
+		id.pid = LUSTRE_SRV_LNET_PID;
+		return ksocknal_add_peer (ni, id,
+					  data->ioc_u32[0], /* IP */
+					  data->ioc_u32[1]); /* port */
+
+	case IOC_LIBCFS_DEL_PEER:
+		id.nid = data->ioc_nid;
+		id.pid = LNET_PID_ANY;
+		return ksocknal_del_peer (ni, id,
+					  data->ioc_u32[0]); /* IP */
+
+	case IOC_LIBCFS_GET_CONN: {
+		int	   txmem;
+		int	   rxmem;
+		int	   nagle;
+		ksock_conn_t *conn = ksocknal_get_conn_by_idx (ni, data->ioc_count);
+
+		if (conn == NULL)
+			return -ENOENT;
+
+		ksocknal_lib_get_conn_tunables(conn, &txmem, &rxmem, &nagle);
+
+		data->ioc_count  = txmem;
+		data->ioc_nid    = conn->ksnc_peer->ksnp_id.nid;
+		data->ioc_flags  = nagle;
+		data->ioc_u32[0] = conn->ksnc_ipaddr;
+		data->ioc_u32[1] = conn->ksnc_port;
+		data->ioc_u32[2] = conn->ksnc_myipaddr;
+		data->ioc_u32[3] = conn->ksnc_type;
+		data->ioc_u32[4] = conn->ksnc_scheduler->kss_info->ksi_cpt;
+		data->ioc_u32[5] = rxmem;
+		data->ioc_u32[6] = conn->ksnc_peer->ksnp_id.pid;
+		ksocknal_conn_decref(conn);
+		return 0;
+	}
+
+	case IOC_LIBCFS_CLOSE_CONNECTION:
+		id.nid = data->ioc_nid;
+		id.pid = LNET_PID_ANY;
+		return ksocknal_close_matching_conns (id,
+						      data->ioc_u32[0]);
+
+	case IOC_LIBCFS_REGISTER_MYNID:
+		/* Ignore if this is a noop */
+		if (data->ioc_nid == ni->ni_nid)
+			return 0;
+
+		CERROR("obsolete IOC_LIBCFS_REGISTER_MYNID: %s(%s)\n",
+		       libcfs_nid2str(data->ioc_nid),
+		       libcfs_nid2str(ni->ni_nid));
+		return -EINVAL;
+
+	case IOC_LIBCFS_PUSH_CONNECTION:
+		id.nid = data->ioc_nid;
+		id.pid = LNET_PID_ANY;
+		return ksocknal_push(ni, id);
+
+	default:
+		return -EINVAL;
+	}
+	/* not reached */
+}
+
+void
+ksocknal_free_buffers (void)
+{
+	LASSERT (atomic_read(&ksocknal_data.ksnd_nactive_txs) == 0);
+
+	if (ksocknal_data.ksnd_sched_info != NULL) {
+		struct ksock_sched_info	*info;
+		int			i;
+
+		cfs_percpt_for_each(info, i, ksocknal_data.ksnd_sched_info) {
+			if (info->ksi_scheds != NULL) {
+				LIBCFS_FREE(info->ksi_scheds,
+					    info->ksi_nthreads_max *
+					    sizeof(info->ksi_scheds[0]));
+			}
+		}
+		cfs_percpt_free(ksocknal_data.ksnd_sched_info);
+	}
+
+	LIBCFS_FREE (ksocknal_data.ksnd_peers,
+		     sizeof (struct list_head) *
+		     ksocknal_data.ksnd_peer_hash_size);
+
+	spin_lock(&ksocknal_data.ksnd_tx_lock);
+
+	if (!list_empty(&ksocknal_data.ksnd_idle_noop_txs)) {
+		struct list_head	zlist;
+		ksock_tx_t	*tx;
+
+		list_add(&zlist, &ksocknal_data.ksnd_idle_noop_txs);
+		list_del_init(&ksocknal_data.ksnd_idle_noop_txs);
+		spin_unlock(&ksocknal_data.ksnd_tx_lock);
+
+		while (!list_empty(&zlist)) {
+			tx = list_entry(zlist.next, ksock_tx_t, tx_list);
+			list_del(&tx->tx_list);
+			LIBCFS_FREE(tx, tx->tx_desc_size);
+		}
+	} else {
+		spin_unlock(&ksocknal_data.ksnd_tx_lock);
+	}
+}
+
+void
+ksocknal_base_shutdown(void)
+{
+	struct ksock_sched_info *info;
+	ksock_sched_t		*sched;
+	int			i;
+	int			j;
+
+	CDEBUG(D_MALLOC, "before NAL cleanup: kmem %d\n",
+	       atomic_read (&libcfs_kmemory));
+	LASSERT (ksocknal_data.ksnd_nnets == 0);
+
+	switch (ksocknal_data.ksnd_init) {
+	default:
+		LASSERT (0);
+
+	case SOCKNAL_INIT_ALL:
+	case SOCKNAL_INIT_DATA:
+		LASSERT (ksocknal_data.ksnd_peers != NULL);
+		for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) {
+			LASSERT (list_empty (&ksocknal_data.ksnd_peers[i]));
+		}
+
+		LASSERT(list_empty(&ksocknal_data.ksnd_nets));
+		LASSERT (list_empty (&ksocknal_data.ksnd_enomem_conns));
+		LASSERT (list_empty (&ksocknal_data.ksnd_zombie_conns));
+		LASSERT (list_empty (&ksocknal_data.ksnd_connd_connreqs));
+		LASSERT (list_empty (&ksocknal_data.ksnd_connd_routes));
+
+		if (ksocknal_data.ksnd_sched_info != NULL) {
+			cfs_percpt_for_each(info, i,
+					    ksocknal_data.ksnd_sched_info) {
+				if (info->ksi_scheds == NULL)
+					continue;
+
+				for (j = 0; j < info->ksi_nthreads_max; j++) {
+
+					sched = &info->ksi_scheds[j];
+					LASSERT(list_empty(&sched->\
+							       kss_tx_conns));
+					LASSERT(list_empty(&sched->\
+							       kss_rx_conns));
+					LASSERT(list_empty(&sched-> \
+						  kss_zombie_noop_txs));
+					LASSERT(sched->kss_nconns == 0);
+				}
+			}
+		}
+
+		/* flag threads to terminate; wake and wait for them to die */
+		ksocknal_data.ksnd_shuttingdown = 1;
+		wake_up_all(&ksocknal_data.ksnd_connd_waitq);
+		wake_up_all(&ksocknal_data.ksnd_reaper_waitq);
+
+		if (ksocknal_data.ksnd_sched_info != NULL) {
+			cfs_percpt_for_each(info, i,
+					    ksocknal_data.ksnd_sched_info) {
+				if (info->ksi_scheds == NULL)
+					continue;
+
+				for (j = 0; j < info->ksi_nthreads_max; j++) {
+					sched = &info->ksi_scheds[j];
+					wake_up_all(&sched->kss_waitq);
+				}
+			}
+		}
+
+		i = 4;
+		read_lock(&ksocknal_data.ksnd_global_lock);
+		while (ksocknal_data.ksnd_nthreads != 0) {
+			i++;
+			CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET, /* power of 2? */
+			       "waiting for %d threads to terminate\n",
+				ksocknal_data.ksnd_nthreads);
+			read_unlock(&ksocknal_data.ksnd_global_lock);
+			cfs_pause(cfs_time_seconds(1));
+			read_lock(&ksocknal_data.ksnd_global_lock);
+		}
+		read_unlock(&ksocknal_data.ksnd_global_lock);
+
+		ksocknal_free_buffers();
+
+		ksocknal_data.ksnd_init = SOCKNAL_INIT_NOTHING;
+		break;
+	}
+
+	CDEBUG(D_MALLOC, "after NAL cleanup: kmem %d\n",
+	       atomic_read (&libcfs_kmemory));
+
+	module_put(THIS_MODULE);
+}
+
+__u64
+ksocknal_new_incarnation (void)
+{
+	struct timeval tv;
+
+	/* The incarnation number is the time this module loaded and it
+	 * identifies this particular instance of the socknal.  Hopefully
+	 * we won't be able to reboot more frequently than 1MHz for the
+	 * forseeable future :) */
+
+	do_gettimeofday(&tv);
+
+	return (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec;
+}
+
+int
+ksocknal_base_startup(void)
+{
+	struct ksock_sched_info	*info;
+	int			rc;
+	int			i;
+
+	LASSERT (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING);
+	LASSERT (ksocknal_data.ksnd_nnets == 0);
+
+	memset (&ksocknal_data, 0, sizeof (ksocknal_data)); /* zero pointers */
+
+	ksocknal_data.ksnd_peer_hash_size = SOCKNAL_PEER_HASH_SIZE;
+	LIBCFS_ALLOC (ksocknal_data.ksnd_peers,
+		      sizeof (struct list_head) *
+		      ksocknal_data.ksnd_peer_hash_size);
+	if (ksocknal_data.ksnd_peers == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++)
+		INIT_LIST_HEAD(&ksocknal_data.ksnd_peers[i]);
+
+	rwlock_init(&ksocknal_data.ksnd_global_lock);
+	INIT_LIST_HEAD(&ksocknal_data.ksnd_nets);
+
+	spin_lock_init(&ksocknal_data.ksnd_reaper_lock);
+	INIT_LIST_HEAD (&ksocknal_data.ksnd_enomem_conns);
+	INIT_LIST_HEAD (&ksocknal_data.ksnd_zombie_conns);
+	INIT_LIST_HEAD (&ksocknal_data.ksnd_deathrow_conns);
+	init_waitqueue_head(&ksocknal_data.ksnd_reaper_waitq);
+
+	spin_lock_init(&ksocknal_data.ksnd_connd_lock);
+	INIT_LIST_HEAD (&ksocknal_data.ksnd_connd_connreqs);
+	INIT_LIST_HEAD (&ksocknal_data.ksnd_connd_routes);
+	init_waitqueue_head(&ksocknal_data.ksnd_connd_waitq);
+
+	spin_lock_init(&ksocknal_data.ksnd_tx_lock);
+	INIT_LIST_HEAD (&ksocknal_data.ksnd_idle_noop_txs);
+
+	/* NB memset above zeros whole of ksocknal_data */
+
+	/* flag lists/ptrs/locks initialised */
+	ksocknal_data.ksnd_init = SOCKNAL_INIT_DATA;
+	try_module_get(THIS_MODULE);
+
+	ksocknal_data.ksnd_sched_info = cfs_percpt_alloc(lnet_cpt_table(),
+							 sizeof(*info));
+	if (ksocknal_data.ksnd_sched_info == NULL)
+		goto failed;
+
+	cfs_percpt_for_each(info, i, ksocknal_data.ksnd_sched_info) {
+		ksock_sched_t	*sched;
+		int		nthrs;
+
+		nthrs = cfs_cpt_weight(lnet_cpt_table(), i);
+		if (*ksocknal_tunables.ksnd_nscheds > 0) {
+			nthrs = min(nthrs, *ksocknal_tunables.ksnd_nscheds);
+		} else {
+			/* max to half of CPUs, assume another half should be
+			 * reserved for upper layer modules */
+			nthrs = min(max(SOCKNAL_NSCHEDS, nthrs >> 1), nthrs);
+		}
+
+		info->ksi_nthreads_max = nthrs;
+		info->ksi_cpt = i;
+
+		LIBCFS_CPT_ALLOC(info->ksi_scheds, lnet_cpt_table(), i,
+				 info->ksi_nthreads_max * sizeof(*sched));
+		if (info->ksi_scheds == NULL)
+			goto failed;
+
+		for (; nthrs > 0; nthrs--) {
+			sched = &info->ksi_scheds[nthrs - 1];
+
+			sched->kss_info = info;
+			spin_lock_init(&sched->kss_lock);
+			INIT_LIST_HEAD(&sched->kss_rx_conns);
+			INIT_LIST_HEAD(&sched->kss_tx_conns);
+			INIT_LIST_HEAD(&sched->kss_zombie_noop_txs);
+			init_waitqueue_head(&sched->kss_waitq);
+		}
+	}
+
+	ksocknal_data.ksnd_connd_starting	 = 0;
+	ksocknal_data.ksnd_connd_failed_stamp     = 0;
+	ksocknal_data.ksnd_connd_starting_stamp   = cfs_time_current_sec();
+	/* must have at least 2 connds to remain responsive to accepts while
+	 * connecting */
+	if (*ksocknal_tunables.ksnd_nconnds < SOCKNAL_CONND_RESV + 1)
+		*ksocknal_tunables.ksnd_nconnds = SOCKNAL_CONND_RESV + 1;
+
+	if (*ksocknal_tunables.ksnd_nconnds_max <
+	    *ksocknal_tunables.ksnd_nconnds) {
+		ksocknal_tunables.ksnd_nconnds_max =
+			ksocknal_tunables.ksnd_nconnds;
+	}
+
+	for (i = 0; i < *ksocknal_tunables.ksnd_nconnds; i++) {
+		char name[16];
+		spin_lock_bh(&ksocknal_data.ksnd_connd_lock);
+		ksocknal_data.ksnd_connd_starting++;
+		spin_unlock_bh(&ksocknal_data.ksnd_connd_lock);
+
+
+		snprintf(name, sizeof(name), "socknal_cd%02d", i);
+		rc = ksocknal_thread_start(ksocknal_connd,
+					   (void *)((ulong_ptr_t)i), name);
+		if (rc != 0) {
+			spin_lock_bh(&ksocknal_data.ksnd_connd_lock);
+			ksocknal_data.ksnd_connd_starting--;
+			spin_unlock_bh(&ksocknal_data.ksnd_connd_lock);
+			CERROR("Can't spawn socknal connd: %d\n", rc);
+			goto failed;
+		}
+	}
+
+	rc = ksocknal_thread_start(ksocknal_reaper, NULL, "socknal_reaper");
+	if (rc != 0) {
+		CERROR ("Can't spawn socknal reaper: %d\n", rc);
+		goto failed;
+	}
+
+	/* flag everything initialised */
+	ksocknal_data.ksnd_init = SOCKNAL_INIT_ALL;
+
+	return 0;
+
+ failed:
+	ksocknal_base_shutdown();
+	return -ENETDOWN;
+}
+
+void
+ksocknal_debug_peerhash (lnet_ni_t *ni)
+{
+	ksock_peer_t	*peer = NULL;
+	struct list_head	*tmp;
+	int		i;
+
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) {
+		list_for_each (tmp, &ksocknal_data.ksnd_peers[i]) {
+			peer = list_entry (tmp, ksock_peer_t, ksnp_list);
+
+			if (peer->ksnp_ni == ni) break;
+
+			peer = NULL;
+		}
+	}
+
+	if (peer != NULL) {
+		ksock_route_t *route;
+		ksock_conn_t  *conn;
+
+		CWARN ("Active peer on shutdown: %s, ref %d, scnt %d, "
+		       "closing %d, accepting %d, err %d, zcookie "LPU64", "
+		       "txq %d, zc_req %d\n", libcfs_id2str(peer->ksnp_id),
+		       atomic_read(&peer->ksnp_refcount),
+		       peer->ksnp_sharecount, peer->ksnp_closing,
+		       peer->ksnp_accepting, peer->ksnp_error,
+		       peer->ksnp_zc_next_cookie,
+		       !list_empty(&peer->ksnp_tx_queue),
+		       !list_empty(&peer->ksnp_zc_req_list));
+
+		list_for_each (tmp, &peer->ksnp_routes) {
+			route = list_entry(tmp, ksock_route_t, ksnr_list);
+			CWARN ("Route: ref %d, schd %d, conn %d, cnted %d, "
+			       "del %d\n", atomic_read(&route->ksnr_refcount),
+			       route->ksnr_scheduled, route->ksnr_connecting,
+			       route->ksnr_connected, route->ksnr_deleted);
+		}
+
+		list_for_each (tmp, &peer->ksnp_conns) {
+			conn = list_entry(tmp, ksock_conn_t, ksnc_list);
+			CWARN ("Conn: ref %d, sref %d, t %d, c %d\n",
+			       atomic_read(&conn->ksnc_conn_refcount),
+			       atomic_read(&conn->ksnc_sock_refcount),
+			       conn->ksnc_type, conn->ksnc_closing);
+		}
+	}
+
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+	return;
+}
+
+void
+ksocknal_shutdown (lnet_ni_t *ni)
+{
+	ksock_net_t      *net = ni->ni_data;
+	int	       i;
+	lnet_process_id_t anyid = {0};
+
+	anyid.nid =  LNET_NID_ANY;
+	anyid.pid =  LNET_PID_ANY;
+
+	LASSERT(ksocknal_data.ksnd_init == SOCKNAL_INIT_ALL);
+	LASSERT(ksocknal_data.ksnd_nnets > 0);
+
+	spin_lock_bh(&net->ksnn_lock);
+	net->ksnn_shutdown = 1;		 /* prevent new peers */
+	spin_unlock_bh(&net->ksnn_lock);
+
+	/* Delete all peers */
+	ksocknal_del_peer(ni, anyid, 0);
+
+	/* Wait for all peer state to clean up */
+	i = 2;
+	spin_lock_bh(&net->ksnn_lock);
+	while (net->ksnn_npeers != 0) {
+		spin_unlock_bh(&net->ksnn_lock);
+
+		i++;
+		CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET, /* power of 2? */
+		       "waiting for %d peers to disconnect\n",
+		       net->ksnn_npeers);
+		cfs_pause(cfs_time_seconds(1));
+
+		ksocknal_debug_peerhash(ni);
+
+		spin_lock_bh(&net->ksnn_lock);
+	}
+	spin_unlock_bh(&net->ksnn_lock);
+
+	for (i = 0; i < net->ksnn_ninterfaces; i++) {
+		LASSERT (net->ksnn_interfaces[i].ksni_npeers == 0);
+		LASSERT (net->ksnn_interfaces[i].ksni_nroutes == 0);
+	}
+
+	list_del(&net->ksnn_list);
+	LIBCFS_FREE(net, sizeof(*net));
+
+	ksocknal_data.ksnd_nnets--;
+	if (ksocknal_data.ksnd_nnets == 0)
+		ksocknal_base_shutdown();
+}
+
+int
+ksocknal_enumerate_interfaces(ksock_net_t *net)
+{
+	char      **names;
+	int	 i;
+	int	 j;
+	int	 rc;
+	int	 n;
+
+	n = libcfs_ipif_enumerate(&names);
+	if (n <= 0) {
+		CERROR("Can't enumerate interfaces: %d\n", n);
+		return n;
+	}
+
+	for (i = j = 0; i < n; i++) {
+		int	up;
+		__u32      ip;
+		__u32      mask;
+
+		if (!strcmp(names[i], "lo")) /* skip the loopback IF */
+			continue;
+
+		rc = libcfs_ipif_query(names[i], &up, &ip, &mask);
+		if (rc != 0) {
+			CWARN("Can't get interface %s info: %d\n",
+			      names[i], rc);
+			continue;
+		}
+
+		if (!up) {
+			CWARN("Ignoring interface %s (down)\n",
+			      names[i]);
+			continue;
+		}
+
+		if (j == LNET_MAX_INTERFACES) {
+			CWARN("Ignoring interface %s (too many interfaces)\n",
+			      names[i]);
+			continue;
+		}
+
+		net->ksnn_interfaces[j].ksni_ipaddr = ip;
+		net->ksnn_interfaces[j].ksni_netmask = mask;
+		strncpy(&net->ksnn_interfaces[j].ksni_name[0],
+			names[i], IFNAMSIZ);
+		j++;
+	}
+
+	libcfs_ipif_free_enumeration(names, n);
+
+	if (j == 0)
+		CERROR("Can't find any usable interfaces\n");
+
+	return j;
+}
+
+int
+ksocknal_search_new_ipif(ksock_net_t *net)
+{
+	int	new_ipif = 0;
+	int	i;
+
+	for (i = 0; i < net->ksnn_ninterfaces; i++) {
+		char		*ifnam = &net->ksnn_interfaces[i].ksni_name[0];
+		char		*colon = strchr(ifnam, ':');
+		int		found  = 0;
+		ksock_net_t	*tmp;
+		int		j;
+
+		if (colon != NULL) /* ignore alias device */
+			*colon = 0;
+
+		list_for_each_entry(tmp, &ksocknal_data.ksnd_nets,
+					ksnn_list) {
+			for (j = 0; !found && j < tmp->ksnn_ninterfaces; j++) {
+				char *ifnam2 = &tmp->ksnn_interfaces[j].\
+					     ksni_name[0];
+				char *colon2 = strchr(ifnam2, ':');
+
+				if (colon2 != NULL)
+					*colon2 = 0;
+
+				found = strcmp(ifnam, ifnam2) == 0;
+				if (colon2 != NULL)
+					*colon2 = ':';
+			}
+			if (found)
+				break;
+		}
+
+		new_ipif += !found;
+		if (colon != NULL)
+			*colon = ':';
+	}
+
+	return new_ipif;
+}
+
+int
+ksocknal_start_schedulers(struct ksock_sched_info *info)
+{
+	int	nthrs;
+	int	rc = 0;
+	int	i;
+
+	if (info->ksi_nthreads == 0) {
+		if (*ksocknal_tunables.ksnd_nscheds > 0) {
+			nthrs = info->ksi_nthreads_max;
+		} else {
+			nthrs = cfs_cpt_weight(lnet_cpt_table(),
+					       info->ksi_cpt);
+			nthrs = min(max(SOCKNAL_NSCHEDS, nthrs >> 1), nthrs);
+			nthrs = min(SOCKNAL_NSCHEDS_HIGH, nthrs);
+		}
+		nthrs = min(nthrs, info->ksi_nthreads_max);
+	} else {
+		LASSERT(info->ksi_nthreads <= info->ksi_nthreads_max);
+		/* increase two threads if there is new interface */
+		nthrs = min(2, info->ksi_nthreads_max - info->ksi_nthreads);
+	}
+
+	for (i = 0; i < nthrs; i++) {
+		long		id;
+		char		name[20];
+		ksock_sched_t	*sched;
+		id = KSOCK_THREAD_ID(info->ksi_cpt, info->ksi_nthreads + i);
+		sched = &info->ksi_scheds[KSOCK_THREAD_SID(id)];
+		snprintf(name, sizeof(name), "socknal_sd%02d_%02d",
+			 info->ksi_cpt, (int)(sched - &info->ksi_scheds[0]));
+
+		rc = ksocknal_thread_start(ksocknal_scheduler,
+					   (void *)id, name);
+		if (rc == 0)
+			continue;
+
+		CERROR("Can't spawn thread %d for scheduler[%d]: %d\n",
+		       info->ksi_cpt, info->ksi_nthreads + i, rc);
+		break;
+	}
+
+	info->ksi_nthreads += i;
+	return rc;
+}
+
+int
+ksocknal_net_start_threads(ksock_net_t *net, __u32 *cpts, int ncpts)
+{
+	int	newif = ksocknal_search_new_ipif(net);
+	int	rc;
+	int	i;
+
+	LASSERT(ncpts > 0 && ncpts <= cfs_cpt_number(lnet_cpt_table()));
+
+	for (i = 0; i < ncpts; i++) {
+		struct ksock_sched_info	*info;
+		int cpt = (cpts == NULL) ? i : cpts[i];
+
+		LASSERT(cpt < cfs_cpt_number(lnet_cpt_table()));
+		info = ksocknal_data.ksnd_sched_info[cpt];
+
+		if (!newif && info->ksi_nthreads > 0)
+			continue;
+
+		rc = ksocknal_start_schedulers(info);
+		if (rc != 0)
+			return rc;
+	}
+	return 0;
+}
+
+int
+ksocknal_startup (lnet_ni_t *ni)
+{
+	ksock_net_t  *net;
+	int	   rc;
+	int	   i;
+
+	LASSERT (ni->ni_lnd == &the_ksocklnd);
+
+	if (ksocknal_data.ksnd_init == SOCKNAL_INIT_NOTHING) {
+		rc = ksocknal_base_startup();
+		if (rc != 0)
+			return rc;
+	}
+
+	LIBCFS_ALLOC(net, sizeof(*net));
+	if (net == NULL)
+		goto fail_0;
+
+	spin_lock_init(&net->ksnn_lock);
+	net->ksnn_incarnation = ksocknal_new_incarnation();
+	ni->ni_data = net;
+	ni->ni_peertimeout    = *ksocknal_tunables.ksnd_peertimeout;
+	ni->ni_maxtxcredits   = *ksocknal_tunables.ksnd_credits;
+	ni->ni_peertxcredits  = *ksocknal_tunables.ksnd_peertxcredits;
+	ni->ni_peerrtrcredits = *ksocknal_tunables.ksnd_peerrtrcredits;
+
+	if (ni->ni_interfaces[0] == NULL) {
+		rc = ksocknal_enumerate_interfaces(net);
+		if (rc <= 0)
+			goto fail_1;
+
+		net->ksnn_ninterfaces = 1;
+	} else {
+		for (i = 0; i < LNET_MAX_INTERFACES; i++) {
+			int    up;
+
+			if (ni->ni_interfaces[i] == NULL)
+				break;
+
+			rc = libcfs_ipif_query(
+				ni->ni_interfaces[i], &up,
+				&net->ksnn_interfaces[i].ksni_ipaddr,
+				&net->ksnn_interfaces[i].ksni_netmask);
+
+			if (rc != 0) {
+				CERROR("Can't get interface %s info: %d\n",
+				       ni->ni_interfaces[i], rc);
+				goto fail_1;
+			}
+
+			if (!up) {
+				CERROR("Interface %s is down\n",
+				       ni->ni_interfaces[i]);
+				goto fail_1;
+			}
+
+			strncpy(&net->ksnn_interfaces[i].ksni_name[0],
+				ni->ni_interfaces[i], IFNAMSIZ);
+		}
+		net->ksnn_ninterfaces = i;
+	}
+
+	/* call it before add it to ksocknal_data.ksnd_nets */
+	rc = ksocknal_net_start_threads(net, ni->ni_cpts, ni->ni_ncpts);
+	if (rc != 0)
+		goto fail_1;
+
+	ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid),
+				net->ksnn_interfaces[0].ksni_ipaddr);
+	list_add(&net->ksnn_list, &ksocknal_data.ksnd_nets);
+
+	ksocknal_data.ksnd_nnets++;
+
+	return 0;
+
+ fail_1:
+	LIBCFS_FREE(net, sizeof(*net));
+ fail_0:
+	if (ksocknal_data.ksnd_nnets == 0)
+		ksocknal_base_shutdown();
+
+	return -ENETDOWN;
+}
+
+
+void __exit
+ksocknal_module_fini (void)
+{
+	lnet_unregister_lnd(&the_ksocklnd);
+	ksocknal_tunables_fini();
+}
+
+int __init
+ksocknal_module_init (void)
+{
+	int    rc;
+
+	/* check ksnr_connected/connecting field large enough */
+	CLASSERT (SOCKLND_CONN_NTYPES <= 4);
+	CLASSERT (SOCKLND_CONN_ACK == SOCKLND_CONN_BULK_IN);
+
+	/* initialize the_ksocklnd */
+	the_ksocklnd.lnd_type     = SOCKLND;
+	the_ksocklnd.lnd_startup  = ksocknal_startup;
+	the_ksocklnd.lnd_shutdown = ksocknal_shutdown;
+	the_ksocklnd.lnd_ctl      = ksocknal_ctl;
+	the_ksocklnd.lnd_send     = ksocknal_send;
+	the_ksocklnd.lnd_recv     = ksocknal_recv;
+	the_ksocklnd.lnd_notify   = ksocknal_notify;
+	the_ksocklnd.lnd_query    = ksocknal_query;
+	the_ksocklnd.lnd_accept   = ksocknal_accept;
+
+	rc = ksocknal_tunables_init();
+	if (rc != 0)
+		return rc;
+
+	lnet_register_lnd(&the_ksocklnd);
+
+	return 0;
+}
+
+MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
+MODULE_DESCRIPTION("Kernel TCP Socket LND v3.0.0");
+MODULE_LICENSE("GPL");
+
+cfs_module(ksocknal, "3.0.0", ksocknal_module_init, ksocknal_module_fini);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2664 @@
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ *
+ *   Author: Zach Brown <zab@zabbo.net>
+ *   Author: Peter J. Braam <braam@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *   Author: Eric Barton <eric@bartonsoftware.com>
+ *
+ *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "socklnd.h"
+
+ksock_tx_t *
+ksocknal_alloc_tx(int type, int size)
+{
+	ksock_tx_t *tx = NULL;
+
+	if (type == KSOCK_MSG_NOOP) {
+		LASSERT(size == KSOCK_NOOP_TX_SIZE);
+
+		/* searching for a noop tx in free list */
+		spin_lock(&ksocknal_data.ksnd_tx_lock);
+
+		if (!list_empty(&ksocknal_data.ksnd_idle_noop_txs)) {
+			tx = list_entry(ksocknal_data.ksnd_idle_noop_txs. \
+					    next, ksock_tx_t, tx_list);
+			LASSERT(tx->tx_desc_size == size);
+			list_del(&tx->tx_list);
+		}
+
+		spin_unlock(&ksocknal_data.ksnd_tx_lock);
+	}
+
+	if (tx == NULL)
+		LIBCFS_ALLOC(tx, size);
+
+	if (tx == NULL)
+		return NULL;
+
+	atomic_set(&tx->tx_refcount, 1);
+	tx->tx_zc_aborted = 0;
+	tx->tx_zc_capable = 0;
+	tx->tx_zc_checked = 0;
+	tx->tx_desc_size  = size;
+
+	atomic_inc(&ksocknal_data.ksnd_nactive_txs);
+
+	return tx;
+}
+
+ksock_tx_t *
+ksocknal_alloc_tx_noop(__u64 cookie, int nonblk)
+{
+	ksock_tx_t *tx;
+
+	tx = ksocknal_alloc_tx(KSOCK_MSG_NOOP, KSOCK_NOOP_TX_SIZE);
+	if (tx == NULL) {
+		CERROR("Can't allocate noop tx desc\n");
+		return NULL;
+	}
+
+	tx->tx_conn     = NULL;
+	tx->tx_lnetmsg  = NULL;
+	tx->tx_kiov     = NULL;
+	tx->tx_nkiov    = 0;
+	tx->tx_iov      = tx->tx_frags.virt.iov;
+	tx->tx_niov     = 1;
+	tx->tx_nonblk   = nonblk;
+
+	socklnd_init_msg(&tx->tx_msg, KSOCK_MSG_NOOP);
+	tx->tx_msg.ksm_zc_cookies[1] = cookie;
+
+	return tx;
+}
+
+
+void
+ksocknal_free_tx (ksock_tx_t *tx)
+{
+	atomic_dec(&ksocknal_data.ksnd_nactive_txs);
+
+	if (tx->tx_lnetmsg == NULL && tx->tx_desc_size == KSOCK_NOOP_TX_SIZE) {
+		/* it's a noop tx */
+		spin_lock(&ksocknal_data.ksnd_tx_lock);
+
+		list_add(&tx->tx_list, &ksocknal_data.ksnd_idle_noop_txs);
+
+		spin_unlock(&ksocknal_data.ksnd_tx_lock);
+	} else {
+		LIBCFS_FREE(tx, tx->tx_desc_size);
+	}
+}
+
+int
+ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
+{
+	struct iovec  *iov = tx->tx_iov;
+	int    nob;
+	int    rc;
+
+	LASSERT (tx->tx_niov > 0);
+
+	/* Never touch tx->tx_iov inside ksocknal_lib_send_iov() */
+	rc = ksocknal_lib_send_iov(conn, tx);
+
+	if (rc <= 0)			    /* sent nothing? */
+		return (rc);
+
+	nob = rc;
+	LASSERT (nob <= tx->tx_resid);
+	tx->tx_resid -= nob;
+
+	/* "consume" iov */
+	do {
+		LASSERT (tx->tx_niov > 0);
+
+		if (nob < (int) iov->iov_len) {
+			iov->iov_base = (void *)((char *)iov->iov_base + nob);
+			iov->iov_len -= nob;
+			return (rc);
+		}
+
+		nob -= iov->iov_len;
+		tx->tx_iov = ++iov;
+		tx->tx_niov--;
+	} while (nob != 0);
+
+	return (rc);
+}
+
+int
+ksocknal_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
+{
+	lnet_kiov_t    *kiov = tx->tx_kiov;
+	int     nob;
+	int     rc;
+
+	LASSERT (tx->tx_niov == 0);
+	LASSERT (tx->tx_nkiov > 0);
+
+	/* Never touch tx->tx_kiov inside ksocknal_lib_send_kiov() */
+	rc = ksocknal_lib_send_kiov(conn, tx);
+
+	if (rc <= 0)			    /* sent nothing? */
+		return (rc);
+
+	nob = rc;
+	LASSERT (nob <= tx->tx_resid);
+	tx->tx_resid -= nob;
+
+	/* "consume" kiov */
+	do {
+		LASSERT(tx->tx_nkiov > 0);
+
+		if (nob < (int)kiov->kiov_len) {
+			kiov->kiov_offset += nob;
+			kiov->kiov_len -= nob;
+			return rc;
+		}
+
+		nob -= (int)kiov->kiov_len;
+		tx->tx_kiov = ++kiov;
+		tx->tx_nkiov--;
+	} while (nob != 0);
+
+	return (rc);
+}
+
+int
+ksocknal_transmit (ksock_conn_t *conn, ksock_tx_t *tx)
+{
+	int      rc;
+	int      bufnob;
+
+	if (ksocknal_data.ksnd_stall_tx != 0) {
+		cfs_pause(cfs_time_seconds(ksocknal_data.ksnd_stall_tx));
+	}
+
+	LASSERT (tx->tx_resid != 0);
+
+	rc = ksocknal_connsock_addref(conn);
+	if (rc != 0) {
+		LASSERT (conn->ksnc_closing);
+		return (-ESHUTDOWN);
+	}
+
+	do {
+		if (ksocknal_data.ksnd_enomem_tx > 0) {
+			/* testing... */
+			ksocknal_data.ksnd_enomem_tx--;
+			rc = -EAGAIN;
+		} else if (tx->tx_niov != 0) {
+			rc = ksocknal_send_iov (conn, tx);
+		} else {
+			rc = ksocknal_send_kiov (conn, tx);
+		}
+
+		bufnob = cfs_sock_wmem_queued(conn->ksnc_sock);
+		if (rc > 0)		     /* sent something? */
+			conn->ksnc_tx_bufnob += rc; /* account it */
+
+		if (bufnob < conn->ksnc_tx_bufnob) {
+			/* allocated send buffer bytes < computed; infer
+			 * something got ACKed */
+			conn->ksnc_tx_deadline =
+				cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
+			conn->ksnc_peer->ksnp_last_alive = cfs_time_current();
+			conn->ksnc_tx_bufnob = bufnob;
+			mb();
+		}
+
+		if (rc <= 0) { /* Didn't write anything? */
+
+			if (rc == 0) /* some stacks return 0 instead of -EAGAIN */
+				rc = -EAGAIN;
+
+			/* Check if EAGAIN is due to memory pressure */
+			if(rc == -EAGAIN && ksocknal_lib_memory_pressure(conn))
+				rc = -ENOMEM;
+
+			break;
+		}
+
+		/* socket's wmem_queued now includes 'rc' bytes */
+		atomic_sub (rc, &conn->ksnc_tx_nob);
+		rc = 0;
+
+	} while (tx->tx_resid != 0);
+
+	ksocknal_connsock_decref(conn);
+	return (rc);
+}
+
+int
+ksocknal_recv_iov (ksock_conn_t *conn)
+{
+	struct iovec *iov = conn->ksnc_rx_iov;
+	int     nob;
+	int     rc;
+
+	LASSERT (conn->ksnc_rx_niov > 0);
+
+	/* Never touch conn->ksnc_rx_iov or change connection
+	 * status inside ksocknal_lib_recv_iov */
+	rc = ksocknal_lib_recv_iov(conn);
+
+	if (rc <= 0)
+		return (rc);
+
+	/* received something... */
+	nob = rc;
+
+	conn->ksnc_peer->ksnp_last_alive = cfs_time_current();
+	conn->ksnc_rx_deadline =
+		cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
+	mb();		       /* order with setting rx_started */
+	conn->ksnc_rx_started = 1;
+
+	conn->ksnc_rx_nob_wanted -= nob;
+	conn->ksnc_rx_nob_left -= nob;
+
+	do {
+		LASSERT (conn->ksnc_rx_niov > 0);
+
+		if (nob < (int)iov->iov_len) {
+			iov->iov_len -= nob;
+			iov->iov_base = (void *)((char *)iov->iov_base + nob);
+			return (-EAGAIN);
+		}
+
+		nob -= iov->iov_len;
+		conn->ksnc_rx_iov = ++iov;
+		conn->ksnc_rx_niov--;
+	} while (nob != 0);
+
+	return (rc);
+}
+
+int
+ksocknal_recv_kiov (ksock_conn_t *conn)
+{
+	lnet_kiov_t   *kiov = conn->ksnc_rx_kiov;
+	int     nob;
+	int     rc;
+	LASSERT (conn->ksnc_rx_nkiov > 0);
+
+	/* Never touch conn->ksnc_rx_kiov or change connection
+	 * status inside ksocknal_lib_recv_iov */
+	rc = ksocknal_lib_recv_kiov(conn);
+
+	if (rc <= 0)
+		return (rc);
+
+	/* received something... */
+	nob = rc;
+
+	conn->ksnc_peer->ksnp_last_alive = cfs_time_current();
+	conn->ksnc_rx_deadline =
+		cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
+	mb();		       /* order with setting rx_started */
+	conn->ksnc_rx_started = 1;
+
+	conn->ksnc_rx_nob_wanted -= nob;
+	conn->ksnc_rx_nob_left -= nob;
+
+	do {
+		LASSERT (conn->ksnc_rx_nkiov > 0);
+
+		if (nob < (int) kiov->kiov_len) {
+			kiov->kiov_offset += nob;
+			kiov->kiov_len -= nob;
+			return -EAGAIN;
+		}
+
+		nob -= kiov->kiov_len;
+		conn->ksnc_rx_kiov = ++kiov;
+		conn->ksnc_rx_nkiov--;
+	} while (nob != 0);
+
+	return 1;
+}
+
+int
+ksocknal_receive (ksock_conn_t *conn)
+{
+	/* Return 1 on success, 0 on EOF, < 0 on error.
+	 * Caller checks ksnc_rx_nob_wanted to determine
+	 * progress/completion. */
+	int     rc;
+	ENTRY;
+
+	if (ksocknal_data.ksnd_stall_rx != 0) {
+		cfs_pause(cfs_time_seconds (ksocknal_data.ksnd_stall_rx));
+	}
+
+	rc = ksocknal_connsock_addref(conn);
+	if (rc != 0) {
+		LASSERT (conn->ksnc_closing);
+		return (-ESHUTDOWN);
+	}
+
+	for (;;) {
+		if (conn->ksnc_rx_niov != 0)
+			rc = ksocknal_recv_iov (conn);
+		else
+			rc = ksocknal_recv_kiov (conn);
+
+		if (rc <= 0) {
+			/* error/EOF or partial receive */
+			if (rc == -EAGAIN) {
+				rc = 1;
+			} else if (rc == 0 && conn->ksnc_rx_started) {
+				/* EOF in the middle of a message */
+				rc = -EPROTO;
+			}
+			break;
+		}
+
+		/* Completed a fragment */
+
+		if (conn->ksnc_rx_nob_wanted == 0) {
+			rc = 1;
+			break;
+		}
+	}
+
+	ksocknal_connsock_decref(conn);
+	RETURN (rc);
+}
+
+void
+ksocknal_tx_done (lnet_ni_t *ni, ksock_tx_t *tx)
+{
+	lnet_msg_t  *lnetmsg = tx->tx_lnetmsg;
+	int	  rc = (tx->tx_resid == 0 && !tx->tx_zc_aborted) ? 0 : -EIO;
+	ENTRY;
+
+	LASSERT(ni != NULL || tx->tx_conn != NULL);
+
+	if (tx->tx_conn != NULL)
+		ksocknal_conn_decref(tx->tx_conn);
+
+	if (ni == NULL && tx->tx_conn != NULL)
+		ni = tx->tx_conn->ksnc_peer->ksnp_ni;
+
+	ksocknal_free_tx (tx);
+	if (lnetmsg != NULL) /* KSOCK_MSG_NOOP go without lnetmsg */
+		lnet_finalize (ni, lnetmsg, rc);
+
+	EXIT;
+}
+
+void
+ksocknal_txlist_done (lnet_ni_t *ni, struct list_head *txlist, int error)
+{
+	ksock_tx_t *tx;
+
+	while (!list_empty (txlist)) {
+		tx = list_entry (txlist->next, ksock_tx_t, tx_list);
+
+		if (error && tx->tx_lnetmsg != NULL) {
+			CNETERR("Deleting packet type %d len %d %s->%s\n",
+				le32_to_cpu (tx->tx_lnetmsg->msg_hdr.type),
+				le32_to_cpu (tx->tx_lnetmsg->msg_hdr.payload_length),
+				libcfs_nid2str(le64_to_cpu(tx->tx_lnetmsg->msg_hdr.src_nid)),
+				libcfs_nid2str(le64_to_cpu(tx->tx_lnetmsg->msg_hdr.dest_nid)));
+		} else if (error) {
+			CNETERR("Deleting noop packet\n");
+		}
+
+		list_del (&tx->tx_list);
+
+		LASSERT (atomic_read(&tx->tx_refcount) == 1);
+		ksocknal_tx_done (ni, tx);
+	}
+}
+
+static void
+ksocknal_check_zc_req(ksock_tx_t *tx)
+{
+	ksock_conn_t   *conn = tx->tx_conn;
+	ksock_peer_t   *peer = conn->ksnc_peer;
+
+	/* Set tx_msg.ksm_zc_cookies[0] to a unique non-zero cookie and add tx
+	 * to ksnp_zc_req_list if some fragment of this message should be sent
+	 * zero-copy.  Our peer will send an ACK containing this cookie when
+	 * she has received this message to tell us we can signal completion.
+	 * tx_msg.ksm_zc_cookies[0] remains non-zero while tx is on
+	 * ksnp_zc_req_list. */
+	LASSERT (tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
+	LASSERT (tx->tx_zc_capable);
+
+	tx->tx_zc_checked = 1;
+
+	if (conn->ksnc_proto == &ksocknal_protocol_v1x ||
+	    !conn->ksnc_zc_capable)
+		return;
+
+	/* assign cookie and queue tx to pending list, it will be released when
+	 * a matching ack is received. See ksocknal_handle_zcack() */
+
+	ksocknal_tx_addref(tx);
+
+	spin_lock(&peer->ksnp_lock);
+
+	/* ZC_REQ is going to be pinned to the peer */
+	tx->tx_deadline =
+		cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
+
+	LASSERT (tx->tx_msg.ksm_zc_cookies[0] == 0);
+
+	tx->tx_msg.ksm_zc_cookies[0] = peer->ksnp_zc_next_cookie++;
+
+	if (peer->ksnp_zc_next_cookie == 0)
+		peer->ksnp_zc_next_cookie = SOCKNAL_KEEPALIVE_PING + 1;
+
+	list_add_tail(&tx->tx_zc_list, &peer->ksnp_zc_req_list);
+
+	spin_unlock(&peer->ksnp_lock);
+}
+
+static void
+ksocknal_uncheck_zc_req(ksock_tx_t *tx)
+{
+	ksock_peer_t   *peer = tx->tx_conn->ksnc_peer;
+
+	LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
+	LASSERT(tx->tx_zc_capable);
+
+	tx->tx_zc_checked = 0;
+
+	spin_lock(&peer->ksnp_lock);
+
+	if (tx->tx_msg.ksm_zc_cookies[0] == 0) {
+		/* Not waiting for an ACK */
+		spin_unlock(&peer->ksnp_lock);
+		return;
+	}
+
+	tx->tx_msg.ksm_zc_cookies[0] = 0;
+	list_del(&tx->tx_zc_list);
+
+	spin_unlock(&peer->ksnp_lock);
+
+	ksocknal_tx_decref(tx);
+}
+
+int
+ksocknal_process_transmit (ksock_conn_t *conn, ksock_tx_t *tx)
+{
+	int	    rc;
+
+	if (tx->tx_zc_capable && !tx->tx_zc_checked)
+		ksocknal_check_zc_req(tx);
+
+	rc = ksocknal_transmit (conn, tx);
+
+	CDEBUG (D_NET, "send(%d) %d\n", tx->tx_resid, rc);
+
+	if (tx->tx_resid == 0) {
+		/* Sent everything OK */
+		LASSERT (rc == 0);
+
+		return (0);
+	}
+
+	if (rc == -EAGAIN)
+		return (rc);
+
+	if (rc == -ENOMEM) {
+		static int counter;
+
+		counter++;   /* exponential backoff warnings */
+		if ((counter & (-counter)) == counter)
+			CWARN("%u ENOMEM tx %p (%u allocated)\n",
+			      counter, conn, atomic_read(&libcfs_kmemory));
+
+		/* Queue on ksnd_enomem_conns for retry after a timeout */
+		spin_lock_bh(&ksocknal_data.ksnd_reaper_lock);
+
+		/* enomem list takes over scheduler's ref... */
+		LASSERT (conn->ksnc_tx_scheduled);
+		list_add_tail(&conn->ksnc_tx_list,
+				  &ksocknal_data.ksnd_enomem_conns);
+		if (!cfs_time_aftereq(cfs_time_add(cfs_time_current(),
+						   SOCKNAL_ENOMEM_RETRY),
+				   ksocknal_data.ksnd_reaper_waketime))
+			wake_up (&ksocknal_data.ksnd_reaper_waitq);
+
+		spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
+		return (rc);
+	}
+
+	/* Actual error */
+	LASSERT (rc < 0);
+
+	if (!conn->ksnc_closing) {
+		switch (rc) {
+		case -ECONNRESET:
+			LCONSOLE_WARN("Host %u.%u.%u.%u reset our connection "
+				      "while we were sending data; it may have "
+				      "rebooted.\n",
+				      HIPQUAD(conn->ksnc_ipaddr));
+			break;
+		default:
+			LCONSOLE_WARN("There was an unexpected network error "
+				      "while writing to %u.%u.%u.%u: %d.\n",
+				      HIPQUAD(conn->ksnc_ipaddr), rc);
+			break;
+		}
+		CDEBUG(D_NET, "[%p] Error %d on write to %s"
+		       " ip %d.%d.%d.%d:%d\n", conn, rc,
+		       libcfs_id2str(conn->ksnc_peer->ksnp_id),
+		       HIPQUAD(conn->ksnc_ipaddr),
+		       conn->ksnc_port);
+	}
+
+	if (tx->tx_zc_checked)
+		ksocknal_uncheck_zc_req(tx);
+
+	/* it's not an error if conn is being closed */
+	ksocknal_close_conn_and_siblings (conn,
+					  (conn->ksnc_closing) ? 0 : rc);
+
+	return (rc);
+}
+
+void
+ksocknal_launch_connection_locked (ksock_route_t *route)
+{
+
+	/* called holding write lock on ksnd_global_lock */
+
+	LASSERT (!route->ksnr_scheduled);
+	LASSERT (!route->ksnr_connecting);
+	LASSERT ((ksocknal_route_mask() & ~route->ksnr_connected) != 0);
+
+	route->ksnr_scheduled = 1;	      /* scheduling conn for connd */
+	ksocknal_route_addref(route);	   /* extra ref for connd */
+
+	spin_lock_bh(&ksocknal_data.ksnd_connd_lock);
+
+	list_add_tail(&route->ksnr_connd_list,
+			  &ksocknal_data.ksnd_connd_routes);
+	wake_up(&ksocknal_data.ksnd_connd_waitq);
+
+	spin_unlock_bh(&ksocknal_data.ksnd_connd_lock);
+}
+
+void
+ksocknal_launch_all_connections_locked (ksock_peer_t *peer)
+{
+	ksock_route_t *route;
+
+	/* called holding write lock on ksnd_global_lock */
+	for (;;) {
+		/* launch any/all connections that need it */
+		route = ksocknal_find_connectable_route_locked(peer);
+		if (route == NULL)
+			return;
+
+		ksocknal_launch_connection_locked(route);
+	}
+}
+
+ksock_conn_t *
+ksocknal_find_conn_locked(ksock_peer_t *peer, ksock_tx_t *tx, int nonblk)
+{
+	struct list_head       *tmp;
+	ksock_conn_t     *conn;
+	ksock_conn_t     *typed = NULL;
+	ksock_conn_t     *fallback = NULL;
+	int	       tnob     = 0;
+	int	       fnob     = 0;
+
+	list_for_each (tmp, &peer->ksnp_conns) {
+		ksock_conn_t *c  = list_entry(tmp, ksock_conn_t, ksnc_list);
+		int	   nob = atomic_read(&c->ksnc_tx_nob) +
+				    cfs_sock_wmem_queued(c->ksnc_sock);
+		int	   rc;
+
+		LASSERT (!c->ksnc_closing);
+		LASSERT (c->ksnc_proto != NULL &&
+			 c->ksnc_proto->pro_match_tx != NULL);
+
+		rc = c->ksnc_proto->pro_match_tx(c, tx, nonblk);
+
+		switch (rc) {
+		default:
+			LBUG();
+		case SOCKNAL_MATCH_NO: /* protocol rejected the tx */
+			continue;
+
+		case SOCKNAL_MATCH_YES: /* typed connection */
+			if (typed == NULL || tnob > nob ||
+			    (tnob == nob && *ksocknal_tunables.ksnd_round_robin &&
+			     cfs_time_after(typed->ksnc_tx_last_post, c->ksnc_tx_last_post))) {
+				typed = c;
+				tnob  = nob;
+			}
+			break;
+
+		case SOCKNAL_MATCH_MAY: /* fallback connection */
+			if (fallback == NULL || fnob > nob ||
+			    (fnob == nob && *ksocknal_tunables.ksnd_round_robin &&
+			     cfs_time_after(fallback->ksnc_tx_last_post, c->ksnc_tx_last_post))) {
+				fallback = c;
+				fnob     = nob;
+			}
+			break;
+		}
+	}
+
+	/* prefer the typed selection */
+	conn = (typed != NULL) ? typed : fallback;
+
+	if (conn != NULL)
+		conn->ksnc_tx_last_post = cfs_time_current();
+
+	return conn;
+}
+
+void
+ksocknal_tx_prep(ksock_conn_t *conn, ksock_tx_t *tx)
+{
+	conn->ksnc_proto->pro_pack(tx);
+
+	atomic_add (tx->tx_nob, &conn->ksnc_tx_nob);
+	ksocknal_conn_addref(conn); /* +1 ref for tx */
+	tx->tx_conn = conn;
+}
+
+void
+ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn)
+{
+	ksock_sched_t *sched = conn->ksnc_scheduler;
+	ksock_msg_t   *msg = &tx->tx_msg;
+	ksock_tx_t    *ztx = NULL;
+	int	    bufnob = 0;
+
+	/* called holding global lock (read or irq-write) and caller may
+	 * not have dropped this lock between finding conn and calling me,
+	 * so we don't need the {get,put}connsock dance to deref
+	 * ksnc_sock... */
+	LASSERT(!conn->ksnc_closing);
+
+	CDEBUG (D_NET, "Sending to %s ip %d.%d.%d.%d:%d\n",
+		libcfs_id2str(conn->ksnc_peer->ksnp_id),
+		HIPQUAD(conn->ksnc_ipaddr),
+		conn->ksnc_port);
+
+	ksocknal_tx_prep(conn, tx);
+
+	/* Ensure the frags we've been given EXACTLY match the number of
+	 * bytes we want to send.  Many TCP/IP stacks disregard any total
+	 * size parameters passed to them and just look at the frags.
+	 *
+	 * We always expect at least 1 mapped fragment containing the
+	 * complete ksocknal message header. */
+	LASSERT (lnet_iov_nob (tx->tx_niov, tx->tx_iov) +
+		 lnet_kiov_nob(tx->tx_nkiov, tx->tx_kiov) ==
+		 (unsigned int)tx->tx_nob);
+	LASSERT (tx->tx_niov >= 1);
+	LASSERT (tx->tx_resid == tx->tx_nob);
+
+	CDEBUG (D_NET, "Packet %p type %d, nob %d niov %d nkiov %d\n",
+		tx, (tx->tx_lnetmsg != NULL) ? tx->tx_lnetmsg->msg_hdr.type:
+					       KSOCK_MSG_NOOP,
+		tx->tx_nob, tx->tx_niov, tx->tx_nkiov);
+
+	/*
+	 * FIXME: SOCK_WMEM_QUEUED and SOCK_ERROR could block in __DARWIN8__
+	 * but they're used inside spinlocks a lot.
+	 */
+	bufnob = cfs_sock_wmem_queued(conn->ksnc_sock);
+	spin_lock_bh(&sched->kss_lock);
+
+	if (list_empty(&conn->ksnc_tx_queue) && bufnob == 0) {
+		/* First packet starts the timeout */
+		conn->ksnc_tx_deadline =
+			cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
+		if (conn->ksnc_tx_bufnob > 0) /* something got ACKed */
+			conn->ksnc_peer->ksnp_last_alive = cfs_time_current();
+		conn->ksnc_tx_bufnob = 0;
+		mb(); /* order with adding to tx_queue */
+	}
+
+	if (msg->ksm_type == KSOCK_MSG_NOOP) {
+		/* The packet is noop ZC ACK, try to piggyback the ack_cookie
+		 * on a normal packet so I don't need to send it */
+		LASSERT (msg->ksm_zc_cookies[1] != 0);
+		LASSERT (conn->ksnc_proto->pro_queue_tx_zcack != NULL);
+
+		if (conn->ksnc_proto->pro_queue_tx_zcack(conn, tx, 0))
+			ztx = tx; /* ZC ACK piggybacked on ztx release tx later */
+
+	} else {
+		/* It's a normal packet - can it piggback a noop zc-ack that
+		 * has been queued already? */
+		LASSERT (msg->ksm_zc_cookies[1] == 0);
+		LASSERT (conn->ksnc_proto->pro_queue_tx_msg != NULL);
+
+		ztx = conn->ksnc_proto->pro_queue_tx_msg(conn, tx);
+		/* ztx will be released later */
+	}
+
+	if (ztx != NULL) {
+		atomic_sub (ztx->tx_nob, &conn->ksnc_tx_nob);
+		list_add_tail(&ztx->tx_list, &sched->kss_zombie_noop_txs);
+	}
+
+	if (conn->ksnc_tx_ready &&      /* able to send */
+	    !conn->ksnc_tx_scheduled) { /* not scheduled to send */
+		/* +1 ref for scheduler */
+		ksocknal_conn_addref(conn);
+		list_add_tail (&conn->ksnc_tx_list,
+				   &sched->kss_tx_conns);
+		conn->ksnc_tx_scheduled = 1;
+		wake_up (&sched->kss_waitq);
+	}
+
+	spin_unlock_bh(&sched->kss_lock);
+}
+
+
+ksock_route_t *
+ksocknal_find_connectable_route_locked (ksock_peer_t *peer)
+{
+	cfs_time_t     now = cfs_time_current();
+	struct list_head    *tmp;
+	ksock_route_t *route;
+
+	list_for_each (tmp, &peer->ksnp_routes) {
+		route = list_entry (tmp, ksock_route_t, ksnr_list);
+
+		LASSERT (!route->ksnr_connecting || route->ksnr_scheduled);
+
+		if (route->ksnr_scheduled)      /* connections being established */
+			continue;
+
+		/* all route types connected ? */
+		if ((ksocknal_route_mask() & ~route->ksnr_connected) == 0)
+			continue;
+
+		if (!(route->ksnr_retry_interval == 0 || /* first attempt */
+		      cfs_time_aftereq(now, route->ksnr_timeout))) {
+			CDEBUG(D_NET,
+			       "Too soon to retry route %u.%u.%u.%u "
+			       "(cnted %d, interval %ld, %ld secs later)\n",
+			       HIPQUAD(route->ksnr_ipaddr),
+			       route->ksnr_connected,
+			       route->ksnr_retry_interval,
+			       cfs_duration_sec(route->ksnr_timeout - now));
+			continue;
+		}
+
+		return (route);
+	}
+
+	return (NULL);
+}
+
+ksock_route_t *
+ksocknal_find_connecting_route_locked (ksock_peer_t *peer)
+{
+	struct list_head	*tmp;
+	ksock_route_t     *route;
+
+	list_for_each (tmp, &peer->ksnp_routes) {
+		route = list_entry (tmp, ksock_route_t, ksnr_list);
+
+		LASSERT (!route->ksnr_connecting || route->ksnr_scheduled);
+
+		if (route->ksnr_scheduled)
+			return (route);
+	}
+
+	return (NULL);
+}
+
+int
+ksocknal_launch_packet (lnet_ni_t *ni, ksock_tx_t *tx, lnet_process_id_t id)
+{
+	ksock_peer_t     *peer;
+	ksock_conn_t     *conn;
+	rwlock_t     *g_lock;
+	int	       retry;
+	int	       rc;
+
+	LASSERT (tx->tx_conn == NULL);
+
+	g_lock = &ksocknal_data.ksnd_global_lock;
+
+	for (retry = 0;; retry = 1) {
+		read_lock(g_lock);
+		peer = ksocknal_find_peer_locked(ni, id);
+		if (peer != NULL) {
+			if (ksocknal_find_connectable_route_locked(peer) == NULL) {
+				conn = ksocknal_find_conn_locked(peer, tx, tx->tx_nonblk);
+				if (conn != NULL) {
+					/* I've got no routes that need to be
+					 * connecting and I do have an actual
+					 * connection... */
+					ksocknal_queue_tx_locked (tx, conn);
+					read_unlock(g_lock);
+					return (0);
+				}
+			}
+		}
+
+		/* I'll need a write lock... */
+		read_unlock(g_lock);
+
+		write_lock_bh(g_lock);
+
+		peer = ksocknal_find_peer_locked(ni, id);
+		if (peer != NULL)
+			break;
+
+		write_unlock_bh(g_lock);
+
+		if ((id.pid & LNET_PID_USERFLAG) != 0) {
+			CERROR("Refusing to create a connection to "
+			       "userspace process %s\n", libcfs_id2str(id));
+			return -EHOSTUNREACH;
+		}
+
+		if (retry) {
+			CERROR("Can't find peer %s\n", libcfs_id2str(id));
+			return -EHOSTUNREACH;
+		}
+
+		rc = ksocknal_add_peer(ni, id,
+				       LNET_NIDADDR(id.nid),
+				       lnet_acceptor_port());
+		if (rc != 0) {
+			CERROR("Can't add peer %s: %d\n",
+			       libcfs_id2str(id), rc);
+			return rc;
+		}
+	}
+
+	ksocknal_launch_all_connections_locked(peer);
+
+	conn = ksocknal_find_conn_locked(peer, tx, tx->tx_nonblk);
+	if (conn != NULL) {
+		/* Connection exists; queue message on it */
+		ksocknal_queue_tx_locked (tx, conn);
+		write_unlock_bh(g_lock);
+		return (0);
+	}
+
+	if (peer->ksnp_accepting > 0 ||
+	    ksocknal_find_connecting_route_locked (peer) != NULL) {
+		/* the message is going to be pinned to the peer */
+		tx->tx_deadline =
+			cfs_time_shift(*ksocknal_tunables.ksnd_timeout);
+
+		/* Queue the message until a connection is established */
+		list_add_tail (&tx->tx_list, &peer->ksnp_tx_queue);
+		write_unlock_bh(g_lock);
+		return 0;
+	}
+
+	write_unlock_bh(g_lock);
+
+	/* NB Routes may be ignored if connections to them failed recently */
+	CNETERR("No usable routes to %s\n", libcfs_id2str(id));
+	return (-EHOSTUNREACH);
+}
+
+int
+ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
+{
+	int	       mpflag = 0;
+	int	       type = lntmsg->msg_type;
+	lnet_process_id_t target = lntmsg->msg_target;
+	unsigned int      payload_niov = lntmsg->msg_niov;
+	struct iovec     *payload_iov = lntmsg->msg_iov;
+	lnet_kiov_t      *payload_kiov = lntmsg->msg_kiov;
+	unsigned int      payload_offset = lntmsg->msg_offset;
+	unsigned int      payload_nob = lntmsg->msg_len;
+	ksock_tx_t       *tx;
+	int	       desc_size;
+	int	       rc;
+
+	/* NB 'private' is different depending on what we're sending.
+	 * Just ignore it... */
+
+	CDEBUG(D_NET, "sending %u bytes in %d frags to %s\n",
+	       payload_nob, payload_niov, libcfs_id2str(target));
+
+	LASSERT (payload_nob == 0 || payload_niov > 0);
+	LASSERT (payload_niov <= LNET_MAX_IOV);
+	/* payload is either all vaddrs or all pages */
+	LASSERT (!(payload_kiov != NULL && payload_iov != NULL));
+	LASSERT (!in_interrupt ());
+
+	if (payload_iov != NULL)
+		desc_size = offsetof(ksock_tx_t,
+				     tx_frags.virt.iov[1 + payload_niov]);
+	else
+		desc_size = offsetof(ksock_tx_t,
+				     tx_frags.paged.kiov[payload_niov]);
+
+	if (lntmsg->msg_vmflush)
+		mpflag = cfs_memory_pressure_get_and_set();
+	tx = ksocknal_alloc_tx(KSOCK_MSG_LNET, desc_size);
+	if (tx == NULL) {
+		CERROR("Can't allocate tx desc type %d size %d\n",
+		       type, desc_size);
+		if (lntmsg->msg_vmflush)
+			cfs_memory_pressure_restore(mpflag);
+		return (-ENOMEM);
+	}
+
+	tx->tx_conn = NULL;		     /* set when assigned a conn */
+	tx->tx_lnetmsg = lntmsg;
+
+	if (payload_iov != NULL) {
+		tx->tx_kiov = NULL;
+		tx->tx_nkiov = 0;
+		tx->tx_iov = tx->tx_frags.virt.iov;
+		tx->tx_niov = 1 +
+			      lnet_extract_iov(payload_niov, &tx->tx_iov[1],
+					       payload_niov, payload_iov,
+					       payload_offset, payload_nob);
+	} else {
+		tx->tx_niov = 1;
+		tx->tx_iov = &tx->tx_frags.paged.iov;
+		tx->tx_kiov = tx->tx_frags.paged.kiov;
+		tx->tx_nkiov = lnet_extract_kiov(payload_niov, tx->tx_kiov,
+						 payload_niov, payload_kiov,
+						 payload_offset, payload_nob);
+
+		if (payload_nob >= *ksocknal_tunables.ksnd_zc_min_payload)
+			tx->tx_zc_capable = 1;
+	}
+
+	socklnd_init_msg(&tx->tx_msg, KSOCK_MSG_LNET);
+
+	/* The first fragment will be set later in pro_pack */
+	rc = ksocknal_launch_packet(ni, tx, target);
+	if (lntmsg->msg_vmflush)
+		cfs_memory_pressure_restore(mpflag);
+	if (rc == 0)
+		return (0);
+
+	ksocknal_free_tx(tx);
+	return (-EIO);
+}
+
+int
+ksocknal_thread_start(int (*fn)(void *arg), void *arg, char *name)
+{
+	task_t *task = kthread_run(fn, arg, name);
+
+	if (IS_ERR(task))
+		return PTR_ERR(task);
+
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+	ksocknal_data.ksnd_nthreads++;
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+	return 0;
+}
+
+void
+ksocknal_thread_fini (void)
+{
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+	ksocknal_data.ksnd_nthreads--;
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+}
+
+int
+ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
+{
+	static char ksocknal_slop_buffer[4096];
+
+	int	    nob;
+	unsigned int   niov;
+	int	    skipped;
+
+	LASSERT(conn->ksnc_proto != NULL);
+
+	if ((*ksocknal_tunables.ksnd_eager_ack & conn->ksnc_type) != 0) {
+		/* Remind the socket to ack eagerly... */
+		ksocknal_lib_eager_ack(conn);
+	}
+
+	if (nob_to_skip == 0) {	 /* right at next packet boundary now */
+		conn->ksnc_rx_started = 0;
+		mb();		       /* racing with timeout thread */
+
+		switch (conn->ksnc_proto->pro_version) {
+		case  KSOCK_PROTO_V2:
+		case  KSOCK_PROTO_V3:
+			conn->ksnc_rx_state = SOCKNAL_RX_KSM_HEADER;
+			conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space;
+			conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg;
+
+			conn->ksnc_rx_nob_wanted = offsetof(ksock_msg_t, ksm_u);
+			conn->ksnc_rx_nob_left = offsetof(ksock_msg_t, ksm_u);
+			conn->ksnc_rx_iov[0].iov_len  = offsetof(ksock_msg_t, ksm_u);
+			break;
+
+		case KSOCK_PROTO_V1:
+			/* Receiving bare lnet_hdr_t */
+			conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
+			conn->ksnc_rx_nob_wanted = sizeof(lnet_hdr_t);
+			conn->ksnc_rx_nob_left = sizeof(lnet_hdr_t);
+
+			conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space;
+			conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg.ksm_u.lnetmsg;
+			conn->ksnc_rx_iov[0].iov_len  = sizeof (lnet_hdr_t);
+			break;
+
+		default:
+			LBUG ();
+		}
+		conn->ksnc_rx_niov = 1;
+
+		conn->ksnc_rx_kiov = NULL;
+		conn->ksnc_rx_nkiov = 0;
+		conn->ksnc_rx_csum = ~0;
+		return (1);
+	}
+
+	/* Set up to skip as much as possible now.  If there's more left
+	 * (ran out of iov entries) we'll get called again */
+
+	conn->ksnc_rx_state = SOCKNAL_RX_SLOP;
+	conn->ksnc_rx_nob_left = nob_to_skip;
+	conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space;
+	skipped = 0;
+	niov = 0;
+
+	do {
+		nob = MIN (nob_to_skip, sizeof (ksocknal_slop_buffer));
+
+		conn->ksnc_rx_iov[niov].iov_base = ksocknal_slop_buffer;
+		conn->ksnc_rx_iov[niov].iov_len  = nob;
+		niov++;
+		skipped += nob;
+		nob_to_skip -=nob;
+
+	} while (nob_to_skip != 0 &&    /* mustn't overflow conn's rx iov */
+		 niov < sizeof(conn->ksnc_rx_iov_space) / sizeof (struct iovec));
+
+	conn->ksnc_rx_niov = niov;
+	conn->ksnc_rx_kiov = NULL;
+	conn->ksnc_rx_nkiov = 0;
+	conn->ksnc_rx_nob_wanted = skipped;
+	return (0);
+}
+
+int
+ksocknal_process_receive (ksock_conn_t *conn)
+{
+	lnet_hdr_t	*lhdr;
+	lnet_process_id_t *id;
+	int		rc;
+
+	LASSERT (atomic_read(&conn->ksnc_conn_refcount) > 0);
+
+	/* NB: sched lock NOT held */
+	/* SOCKNAL_RX_LNET_HEADER is here for backward compatability */
+	LASSERT (conn->ksnc_rx_state == SOCKNAL_RX_KSM_HEADER ||
+		 conn->ksnc_rx_state == SOCKNAL_RX_LNET_PAYLOAD ||
+		 conn->ksnc_rx_state == SOCKNAL_RX_LNET_HEADER ||
+		 conn->ksnc_rx_state == SOCKNAL_RX_SLOP);
+ again:
+	if (conn->ksnc_rx_nob_wanted != 0) {
+		rc = ksocknal_receive(conn);
+
+		if (rc <= 0) {
+			LASSERT (rc != -EAGAIN);
+
+			if (rc == 0)
+				CDEBUG (D_NET, "[%p] EOF from %s"
+					" ip %d.%d.%d.%d:%d\n", conn,
+					libcfs_id2str(conn->ksnc_peer->ksnp_id),
+					HIPQUAD(conn->ksnc_ipaddr),
+					conn->ksnc_port);
+			else if (!conn->ksnc_closing)
+				CERROR ("[%p] Error %d on read from %s"
+					" ip %d.%d.%d.%d:%d\n",
+					conn, rc,
+					libcfs_id2str(conn->ksnc_peer->ksnp_id),
+					HIPQUAD(conn->ksnc_ipaddr),
+					conn->ksnc_port);
+
+			/* it's not an error if conn is being closed */
+			ksocknal_close_conn_and_siblings (conn,
+							  (conn->ksnc_closing) ? 0 : rc);
+			return (rc == 0 ? -ESHUTDOWN : rc);
+		}
+
+		if (conn->ksnc_rx_nob_wanted != 0) {
+			/* short read */
+			return (-EAGAIN);
+		}
+	}
+	switch (conn->ksnc_rx_state) {
+	case SOCKNAL_RX_KSM_HEADER:
+		if (conn->ksnc_flip) {
+			__swab32s(&conn->ksnc_msg.ksm_type);
+			__swab32s(&conn->ksnc_msg.ksm_csum);
+			__swab64s(&conn->ksnc_msg.ksm_zc_cookies[0]);
+			__swab64s(&conn->ksnc_msg.ksm_zc_cookies[1]);
+		}
+
+		if (conn->ksnc_msg.ksm_type != KSOCK_MSG_NOOP &&
+		    conn->ksnc_msg.ksm_type != KSOCK_MSG_LNET) {
+			CERROR("%s: Unknown message type: %x\n",
+			       libcfs_id2str(conn->ksnc_peer->ksnp_id),
+			       conn->ksnc_msg.ksm_type);
+			ksocknal_new_packet(conn, 0);
+			ksocknal_close_conn_and_siblings(conn, -EPROTO);
+			return (-EPROTO);
+		}
+
+		if (conn->ksnc_msg.ksm_type == KSOCK_MSG_NOOP &&
+		    conn->ksnc_msg.ksm_csum != 0 &&     /* has checksum */
+		    conn->ksnc_msg.ksm_csum != conn->ksnc_rx_csum) {
+			/* NOOP Checksum error */
+			CERROR("%s: Checksum error, wire:0x%08X data:0x%08X\n",
+			       libcfs_id2str(conn->ksnc_peer->ksnp_id),
+			       conn->ksnc_msg.ksm_csum, conn->ksnc_rx_csum);
+			ksocknal_new_packet(conn, 0);
+			ksocknal_close_conn_and_siblings(conn, -EPROTO);
+			return (-EIO);
+		}
+
+		if (conn->ksnc_msg.ksm_zc_cookies[1] != 0) {
+			__u64 cookie = 0;
+
+			LASSERT (conn->ksnc_proto != &ksocknal_protocol_v1x);
+
+			if (conn->ksnc_msg.ksm_type == KSOCK_MSG_NOOP)
+				cookie = conn->ksnc_msg.ksm_zc_cookies[0];
+
+			rc = conn->ksnc_proto->pro_handle_zcack(conn, cookie,
+					       conn->ksnc_msg.ksm_zc_cookies[1]);
+
+			if (rc != 0) {
+				CERROR("%s: Unknown ZC-ACK cookie: "LPU64", "LPU64"\n",
+				       libcfs_id2str(conn->ksnc_peer->ksnp_id),
+				       cookie, conn->ksnc_msg.ksm_zc_cookies[1]);
+				ksocknal_new_packet(conn, 0);
+				ksocknal_close_conn_and_siblings(conn, -EPROTO);
+				return (rc);
+			}
+		}
+
+		if (conn->ksnc_msg.ksm_type == KSOCK_MSG_NOOP) {
+			ksocknal_new_packet (conn, 0);
+			return 0;       /* NOOP is done and just return */
+		}
+
+		conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
+		conn->ksnc_rx_nob_wanted = sizeof(ksock_lnet_msg_t);
+		conn->ksnc_rx_nob_left = sizeof(ksock_lnet_msg_t);
+
+		conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space;
+		conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg.ksm_u.lnetmsg;
+		conn->ksnc_rx_iov[0].iov_len  = sizeof(ksock_lnet_msg_t);
+
+		conn->ksnc_rx_niov = 1;
+		conn->ksnc_rx_kiov = NULL;
+		conn->ksnc_rx_nkiov = 0;
+
+		goto again;     /* read lnet header now */
+
+	case SOCKNAL_RX_LNET_HEADER:
+		/* unpack message header */
+		conn->ksnc_proto->pro_unpack(&conn->ksnc_msg);
+
+		if ((conn->ksnc_peer->ksnp_id.pid & LNET_PID_USERFLAG) != 0) {
+			/* Userspace peer */
+			lhdr = &conn->ksnc_msg.ksm_u.lnetmsg.ksnm_hdr;
+			id   = &conn->ksnc_peer->ksnp_id;
+
+			/* Substitute process ID assigned at connection time */
+			lhdr->src_pid = cpu_to_le32(id->pid);
+			lhdr->src_nid = cpu_to_le64(id->nid);
+		}
+
+		conn->ksnc_rx_state = SOCKNAL_RX_PARSE;
+		ksocknal_conn_addref(conn);     /* ++ref while parsing */
+
+		rc = lnet_parse(conn->ksnc_peer->ksnp_ni,
+				&conn->ksnc_msg.ksm_u.lnetmsg.ksnm_hdr,
+				conn->ksnc_peer->ksnp_id.nid, conn, 0);
+		if (rc < 0) {
+			/* I just received garbage: give up on this conn */
+			ksocknal_new_packet(conn, 0);
+			ksocknal_close_conn_and_siblings (conn, rc);
+			ksocknal_conn_decref(conn);
+			return (-EPROTO);
+		}
+
+		/* I'm racing with ksocknal_recv() */
+		LASSERT (conn->ksnc_rx_state == SOCKNAL_RX_PARSE ||
+			 conn->ksnc_rx_state == SOCKNAL_RX_LNET_PAYLOAD);
+
+		if (conn->ksnc_rx_state != SOCKNAL_RX_LNET_PAYLOAD)
+			return 0;
+
+		/* ksocknal_recv() got called */
+		goto again;
+
+	case SOCKNAL_RX_LNET_PAYLOAD:
+		/* payload all received */
+		rc = 0;
+
+		if (conn->ksnc_rx_nob_left == 0 &&   /* not truncating */
+		    conn->ksnc_msg.ksm_csum != 0 &&  /* has checksum */
+		    conn->ksnc_msg.ksm_csum != conn->ksnc_rx_csum) {
+			CERROR("%s: Checksum error, wire:0x%08X data:0x%08X\n",
+			       libcfs_id2str(conn->ksnc_peer->ksnp_id),
+			       conn->ksnc_msg.ksm_csum, conn->ksnc_rx_csum);
+			rc = -EIO;
+		}
+
+		if (rc == 0 && conn->ksnc_msg.ksm_zc_cookies[0] != 0) {
+			LASSERT(conn->ksnc_proto != &ksocknal_protocol_v1x);
+
+			lhdr = &conn->ksnc_msg.ksm_u.lnetmsg.ksnm_hdr;
+			id   = &conn->ksnc_peer->ksnp_id;
+
+			rc = conn->ksnc_proto->pro_handle_zcreq(conn,
+					conn->ksnc_msg.ksm_zc_cookies[0],
+					*ksocknal_tunables.ksnd_nonblk_zcack ||
+					le64_to_cpu(lhdr->src_nid) != id->nid);
+		}
+
+		lnet_finalize(conn->ksnc_peer->ksnp_ni, conn->ksnc_cookie, rc);
+
+		if (rc != 0) {
+			ksocknal_new_packet(conn, 0);
+			ksocknal_close_conn_and_siblings (conn, rc);
+			return (-EPROTO);
+		}
+		/* Fall through */
+
+	case SOCKNAL_RX_SLOP:
+		/* starting new packet? */
+		if (ksocknal_new_packet (conn, conn->ksnc_rx_nob_left))
+			return 0;       /* come back later */
+		goto again;	     /* try to finish reading slop now */
+
+	default:
+		break;
+	}
+
+	/* Not Reached */
+	LBUG ();
+	return (-EINVAL);		       /* keep gcc happy */
+}
+
+int
+ksocknal_recv (lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
+	       unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov,
+	       unsigned int offset, unsigned int mlen, unsigned int rlen)
+{
+	ksock_conn_t  *conn = (ksock_conn_t *)private;
+	ksock_sched_t *sched = conn->ksnc_scheduler;
+
+	LASSERT (mlen <= rlen);
+	LASSERT (niov <= LNET_MAX_IOV);
+
+	conn->ksnc_cookie = msg;
+	conn->ksnc_rx_nob_wanted = mlen;
+	conn->ksnc_rx_nob_left   = rlen;
+
+	if (mlen == 0 || iov != NULL) {
+		conn->ksnc_rx_nkiov = 0;
+		conn->ksnc_rx_kiov = NULL;
+		conn->ksnc_rx_iov = conn->ksnc_rx_iov_space.iov;
+		conn->ksnc_rx_niov =
+			lnet_extract_iov(LNET_MAX_IOV, conn->ksnc_rx_iov,
+					 niov, iov, offset, mlen);
+	} else {
+		conn->ksnc_rx_niov = 0;
+		conn->ksnc_rx_iov  = NULL;
+		conn->ksnc_rx_kiov = conn->ksnc_rx_iov_space.kiov;
+		conn->ksnc_rx_nkiov =
+			lnet_extract_kiov(LNET_MAX_IOV, conn->ksnc_rx_kiov,
+					  niov, kiov, offset, mlen);
+	}
+
+	LASSERT (mlen ==
+		 lnet_iov_nob (conn->ksnc_rx_niov, conn->ksnc_rx_iov) +
+		 lnet_kiov_nob (conn->ksnc_rx_nkiov, conn->ksnc_rx_kiov));
+
+	LASSERT (conn->ksnc_rx_scheduled);
+
+	spin_lock_bh(&sched->kss_lock);
+
+	switch (conn->ksnc_rx_state) {
+	case SOCKNAL_RX_PARSE_WAIT:
+		list_add_tail(&conn->ksnc_rx_list, &sched->kss_rx_conns);
+		wake_up (&sched->kss_waitq);
+		LASSERT (conn->ksnc_rx_ready);
+		break;
+
+	case SOCKNAL_RX_PARSE:
+		/* scheduler hasn't noticed I'm parsing yet */
+		break;
+	}
+
+	conn->ksnc_rx_state = SOCKNAL_RX_LNET_PAYLOAD;
+
+	spin_unlock_bh(&sched->kss_lock);
+	ksocknal_conn_decref(conn);
+	return 0;
+}
+
+static inline int
+ksocknal_sched_cansleep(ksock_sched_t *sched)
+{
+	int	   rc;
+
+	spin_lock_bh(&sched->kss_lock);
+
+	rc = (!ksocknal_data.ksnd_shuttingdown &&
+	      list_empty(&sched->kss_rx_conns) &&
+	      list_empty(&sched->kss_tx_conns));
+
+	spin_unlock_bh(&sched->kss_lock);
+	return rc;
+}
+
+int ksocknal_scheduler(void *arg)
+{
+	struct ksock_sched_info	*info;
+	ksock_sched_t		*sched;
+	ksock_conn_t		*conn;
+	ksock_tx_t		*tx;
+	int			rc;
+	int			nloops = 0;
+	long			id = (long)arg;
+
+	info = ksocknal_data.ksnd_sched_info[KSOCK_THREAD_CPT(id)];
+	sched = &info->ksi_scheds[KSOCK_THREAD_SID(id)];
+
+	cfs_block_allsigs();
+
+	rc = cfs_cpt_bind(lnet_cpt_table(), info->ksi_cpt);
+	if (rc != 0) {
+		CERROR("Can't set CPT affinity to %d: %d\n",
+		       info->ksi_cpt, rc);
+	}
+
+	spin_lock_bh(&sched->kss_lock);
+
+	while (!ksocknal_data.ksnd_shuttingdown) {
+		int did_something = 0;
+
+		/* Ensure I progress everything semi-fairly */
+
+		if (!list_empty (&sched->kss_rx_conns)) {
+			conn = list_entry(sched->kss_rx_conns.next,
+					      ksock_conn_t, ksnc_rx_list);
+			list_del(&conn->ksnc_rx_list);
+
+			LASSERT(conn->ksnc_rx_scheduled);
+			LASSERT(conn->ksnc_rx_ready);
+
+			/* clear rx_ready in case receive isn't complete.
+			 * Do it BEFORE we call process_recv, since
+			 * data_ready can set it any time after we release
+			 * kss_lock. */
+			conn->ksnc_rx_ready = 0;
+			spin_unlock_bh(&sched->kss_lock);
+
+			rc = ksocknal_process_receive(conn);
+
+			spin_lock_bh(&sched->kss_lock);
+
+			/* I'm the only one that can clear this flag */
+			LASSERT(conn->ksnc_rx_scheduled);
+
+			/* Did process_receive get everything it wanted? */
+			if (rc == 0)
+				conn->ksnc_rx_ready = 1;
+
+			if (conn->ksnc_rx_state == SOCKNAL_RX_PARSE) {
+				/* Conn blocked waiting for ksocknal_recv()
+				 * I change its state (under lock) to signal
+				 * it can be rescheduled */
+				conn->ksnc_rx_state = SOCKNAL_RX_PARSE_WAIT;
+			} else if (conn->ksnc_rx_ready) {
+				/* reschedule for rx */
+				list_add_tail (&conn->ksnc_rx_list,
+						   &sched->kss_rx_conns);
+			} else {
+				conn->ksnc_rx_scheduled = 0;
+				/* drop my ref */
+				ksocknal_conn_decref(conn);
+			}
+
+			did_something = 1;
+		}
+
+		if (!list_empty (&sched->kss_tx_conns)) {
+			LIST_HEAD    (zlist);
+
+			if (!list_empty(&sched->kss_zombie_noop_txs)) {
+				list_add(&zlist,
+					     &sched->kss_zombie_noop_txs);
+				list_del_init(&sched->kss_zombie_noop_txs);
+			}
+
+			conn = list_entry(sched->kss_tx_conns.next,
+					      ksock_conn_t, ksnc_tx_list);
+			list_del (&conn->ksnc_tx_list);
+
+			LASSERT(conn->ksnc_tx_scheduled);
+			LASSERT(conn->ksnc_tx_ready);
+			LASSERT(!list_empty(&conn->ksnc_tx_queue));
+
+			tx = list_entry(conn->ksnc_tx_queue.next,
+					    ksock_tx_t, tx_list);
+
+			if (conn->ksnc_tx_carrier == tx)
+				ksocknal_next_tx_carrier(conn);
+
+			/* dequeue now so empty list => more to send */
+			list_del(&tx->tx_list);
+
+			/* Clear tx_ready in case send isn't complete.  Do
+			 * it BEFORE we call process_transmit, since
+			 * write_space can set it any time after we release
+			 * kss_lock. */
+			conn->ksnc_tx_ready = 0;
+			spin_unlock_bh(&sched->kss_lock);
+
+			if (!list_empty(&zlist)) {
+				/* free zombie noop txs, it's fast because
+				 * noop txs are just put in freelist */
+				ksocknal_txlist_done(NULL, &zlist, 0);
+			}
+
+			rc = ksocknal_process_transmit(conn, tx);
+
+			if (rc == -ENOMEM || rc == -EAGAIN) {
+				/* Incomplete send: replace tx on HEAD of tx_queue */
+				spin_lock_bh(&sched->kss_lock);
+				list_add(&tx->tx_list,
+					     &conn->ksnc_tx_queue);
+			} else {
+				/* Complete send; tx -ref */
+				ksocknal_tx_decref(tx);
+
+				spin_lock_bh(&sched->kss_lock);
+				/* assume space for more */
+				conn->ksnc_tx_ready = 1;
+			}
+
+			if (rc == -ENOMEM) {
+				/* Do nothing; after a short timeout, this
+				 * conn will be reposted on kss_tx_conns. */
+			} else if (conn->ksnc_tx_ready &&
+				   !list_empty (&conn->ksnc_tx_queue)) {
+				/* reschedule for tx */
+				list_add_tail (&conn->ksnc_tx_list,
+						   &sched->kss_tx_conns);
+			} else {
+				conn->ksnc_tx_scheduled = 0;
+				/* drop my ref */
+				ksocknal_conn_decref(conn);
+			}
+
+			did_something = 1;
+		}
+		if (!did_something ||	   /* nothing to do */
+		    ++nloops == SOCKNAL_RESCHED) { /* hogging CPU? */
+			spin_unlock_bh(&sched->kss_lock);
+
+			nloops = 0;
+
+			if (!did_something) {   /* wait for something to do */
+				cfs_wait_event_interruptible_exclusive(
+					sched->kss_waitq,
+					!ksocknal_sched_cansleep(sched), rc);
+				LASSERT (rc == 0);
+			} else {
+				cond_resched();
+			}
+
+			spin_lock_bh(&sched->kss_lock);
+		}
+	}
+
+	spin_unlock_bh(&sched->kss_lock);
+	ksocknal_thread_fini();
+	return 0;
+}
+
+/*
+ * Add connection to kss_rx_conns of scheduler
+ * and wakeup the scheduler.
+ */
+void ksocknal_read_callback (ksock_conn_t *conn)
+{
+	ksock_sched_t *sched;
+	ENTRY;
+
+	sched = conn->ksnc_scheduler;
+
+	spin_lock_bh(&sched->kss_lock);
+
+	conn->ksnc_rx_ready = 1;
+
+	if (!conn->ksnc_rx_scheduled) {  /* not being progressed */
+		list_add_tail(&conn->ksnc_rx_list,
+				  &sched->kss_rx_conns);
+		conn->ksnc_rx_scheduled = 1;
+		/* extra ref for scheduler */
+		ksocknal_conn_addref(conn);
+
+		wake_up (&sched->kss_waitq);
+	}
+	spin_unlock_bh(&sched->kss_lock);
+
+	EXIT;
+}
+
+/*
+ * Add connection to kss_tx_conns of scheduler
+ * and wakeup the scheduler.
+ */
+void ksocknal_write_callback (ksock_conn_t *conn)
+{
+	ksock_sched_t *sched;
+	ENTRY;
+
+	sched = conn->ksnc_scheduler;
+
+	spin_lock_bh(&sched->kss_lock);
+
+	conn->ksnc_tx_ready = 1;
+
+	if (!conn->ksnc_tx_scheduled && // not being progressed
+	    !list_empty(&conn->ksnc_tx_queue)){//packets to send
+		list_add_tail (&conn->ksnc_tx_list,
+				   &sched->kss_tx_conns);
+		conn->ksnc_tx_scheduled = 1;
+		/* extra ref for scheduler */
+		ksocknal_conn_addref(conn);
+
+		wake_up (&sched->kss_waitq);
+	}
+
+	spin_unlock_bh(&sched->kss_lock);
+
+	EXIT;
+}
+
+ksock_proto_t *
+ksocknal_parse_proto_version (ksock_hello_msg_t *hello)
+{
+	__u32   version = 0;
+
+	if (hello->kshm_magic == LNET_PROTO_MAGIC)
+		version = hello->kshm_version;
+	else if (hello->kshm_magic == __swab32(LNET_PROTO_MAGIC))
+		version = __swab32(hello->kshm_version);
+
+	if (version != 0) {
+#if SOCKNAL_VERSION_DEBUG
+		if (*ksocknal_tunables.ksnd_protocol == 1)
+			return NULL;
+
+		if (*ksocknal_tunables.ksnd_protocol == 2 &&
+		    version == KSOCK_PROTO_V3)
+			return NULL;
+#endif
+		if (version == KSOCK_PROTO_V2)
+			return &ksocknal_protocol_v2x;
+
+		if (version == KSOCK_PROTO_V3)
+			return &ksocknal_protocol_v3x;
+
+		return NULL;
+	}
+
+	if (hello->kshm_magic == le32_to_cpu(LNET_PROTO_TCP_MAGIC)) {
+		lnet_magicversion_t *hmv = (lnet_magicversion_t *)hello;
+
+		CLASSERT (sizeof (lnet_magicversion_t) ==
+			  offsetof (ksock_hello_msg_t, kshm_src_nid));
+
+		if (hmv->version_major == cpu_to_le16 (KSOCK_PROTO_V1_MAJOR) &&
+		    hmv->version_minor == cpu_to_le16 (KSOCK_PROTO_V1_MINOR))
+			return &ksocknal_protocol_v1x;
+	}
+
+	return NULL;
+}
+
+int
+ksocknal_send_hello (lnet_ni_t *ni, ksock_conn_t *conn,
+		     lnet_nid_t peer_nid, ksock_hello_msg_t *hello)
+{
+	/* CAVEAT EMPTOR: this byte flips 'ipaddrs' */
+	ksock_net_t	 *net = (ksock_net_t *)ni->ni_data;
+
+	LASSERT (hello->kshm_nips <= LNET_MAX_INTERFACES);
+
+	/* rely on caller to hold a ref on socket so it wouldn't disappear */
+	LASSERT (conn->ksnc_proto != NULL);
+
+	hello->kshm_src_nid	 = ni->ni_nid;
+	hello->kshm_dst_nid	 = peer_nid;
+	hello->kshm_src_pid	 = the_lnet.ln_pid;
+
+	hello->kshm_src_incarnation = net->ksnn_incarnation;
+	hello->kshm_ctype	   = conn->ksnc_type;
+
+	return conn->ksnc_proto->pro_send_hello(conn, hello);
+}
+
+int
+ksocknal_invert_type(int type)
+{
+	switch (type)
+	{
+	case SOCKLND_CONN_ANY:
+	case SOCKLND_CONN_CONTROL:
+		return (type);
+	case SOCKLND_CONN_BULK_IN:
+		return SOCKLND_CONN_BULK_OUT;
+	case SOCKLND_CONN_BULK_OUT:
+		return SOCKLND_CONN_BULK_IN;
+	default:
+		return (SOCKLND_CONN_NONE);
+	}
+}
+
+int
+ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn,
+		     ksock_hello_msg_t *hello, lnet_process_id_t *peerid,
+		     __u64 *incarnation)
+{
+	/* Return < 0	fatal error
+	 *	0	  success
+	 *	EALREADY   lost connection race
+	 *	EPROTO     protocol version mismatch
+	 */
+	socket_t	*sock = conn->ksnc_sock;
+	int		  active = (conn->ksnc_proto != NULL);
+	int		  timeout;
+	int		  proto_match;
+	int		  rc;
+	ksock_proto_t       *proto;
+	lnet_process_id_t    recv_id;
+
+	/* socket type set on active connections - not set on passive */
+	LASSERT (!active == !(conn->ksnc_type != SOCKLND_CONN_NONE));
+
+	timeout = active ? *ksocknal_tunables.ksnd_timeout :
+			    lnet_acceptor_timeout();
+
+	rc = libcfs_sock_read(sock, &hello->kshm_magic, sizeof (hello->kshm_magic), timeout);
+	if (rc != 0) {
+		CERROR ("Error %d reading HELLO from %u.%u.%u.%u\n",
+			rc, HIPQUAD(conn->ksnc_ipaddr));
+		LASSERT (rc < 0);
+		return rc;
+	}
+
+	if (hello->kshm_magic != LNET_PROTO_MAGIC &&
+	    hello->kshm_magic != __swab32(LNET_PROTO_MAGIC) &&
+	    hello->kshm_magic != le32_to_cpu (LNET_PROTO_TCP_MAGIC)) {
+		/* Unexpected magic! */
+		CERROR ("Bad magic(1) %#08x (%#08x expected) from "
+			"%u.%u.%u.%u\n", __cpu_to_le32 (hello->kshm_magic),
+			LNET_PROTO_TCP_MAGIC,
+			HIPQUAD(conn->ksnc_ipaddr));
+		return -EPROTO;
+	}
+
+	rc = libcfs_sock_read(sock, &hello->kshm_version,
+			      sizeof(hello->kshm_version), timeout);
+	if (rc != 0) {
+		CERROR ("Error %d reading HELLO from %u.%u.%u.%u\n",
+			rc, HIPQUAD(conn->ksnc_ipaddr));
+		LASSERT (rc < 0);
+		return rc;
+	}
+
+	proto = ksocknal_parse_proto_version(hello);
+	if (proto == NULL) {
+		if (!active) {
+			/* unknown protocol from peer, tell peer my protocol */
+			conn->ksnc_proto = &ksocknal_protocol_v3x;
+#if SOCKNAL_VERSION_DEBUG
+			if (*ksocknal_tunables.ksnd_protocol == 2)
+				conn->ksnc_proto = &ksocknal_protocol_v2x;
+			else if (*ksocknal_tunables.ksnd_protocol == 1)
+				conn->ksnc_proto = &ksocknal_protocol_v1x;
+#endif
+			hello->kshm_nips = 0;
+			ksocknal_send_hello(ni, conn, ni->ni_nid, hello);
+		}
+
+		CERROR ("Unknown protocol version (%d.x expected)"
+			" from %u.%u.%u.%u\n",
+			conn->ksnc_proto->pro_version,
+			HIPQUAD(conn->ksnc_ipaddr));
+
+		return -EPROTO;
+	}
+
+	proto_match = (conn->ksnc_proto == proto);
+	conn->ksnc_proto = proto;
+
+	/* receive the rest of hello message anyway */
+	rc = conn->ksnc_proto->pro_recv_hello(conn, hello, timeout);
+	if (rc != 0) {
+		CERROR("Error %d reading or checking hello from from %u.%u.%u.%u\n",
+		       rc, HIPQUAD(conn->ksnc_ipaddr));
+		LASSERT (rc < 0);
+		return rc;
+	}
+
+	*incarnation = hello->kshm_src_incarnation;
+
+	if (hello->kshm_src_nid == LNET_NID_ANY) {
+		CERROR("Expecting a HELLO hdr with a NID, but got LNET_NID_ANY"
+		       "from %u.%u.%u.%u\n", HIPQUAD(conn->ksnc_ipaddr));
+		return -EPROTO;
+	}
+
+	if (!active &&
+	    conn->ksnc_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) {
+		/* Userspace NAL assigns peer process ID from socket */
+		recv_id.pid = conn->ksnc_port | LNET_PID_USERFLAG;
+		recv_id.nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), conn->ksnc_ipaddr);
+	} else {
+		recv_id.nid = hello->kshm_src_nid;
+		recv_id.pid = hello->kshm_src_pid;
+	}
+
+	if (!active) {
+		*peerid = recv_id;
+
+		/* peer determines type */
+		conn->ksnc_type = ksocknal_invert_type(hello->kshm_ctype);
+		if (conn->ksnc_type == SOCKLND_CONN_NONE) {
+			CERROR ("Unexpected type %d from %s ip %u.%u.%u.%u\n",
+				hello->kshm_ctype, libcfs_id2str(*peerid),
+				HIPQUAD(conn->ksnc_ipaddr));
+			return -EPROTO;
+		}
+
+		return 0;
+	}
+
+	if (peerid->pid != recv_id.pid ||
+	    peerid->nid != recv_id.nid) {
+		LCONSOLE_ERROR_MSG(0x130, "Connected successfully to %s on host"
+				   " %u.%u.%u.%u, but they claimed they were "
+				   "%s; please check your Lustre "
+				   "configuration.\n",
+				   libcfs_id2str(*peerid),
+				   HIPQUAD(conn->ksnc_ipaddr),
+				   libcfs_id2str(recv_id));
+		return -EPROTO;
+	}
+
+	if (hello->kshm_ctype == SOCKLND_CONN_NONE) {
+		/* Possible protocol mismatch or I lost the connection race */
+		return proto_match ? EALREADY : EPROTO;
+	}
+
+	if (ksocknal_invert_type(hello->kshm_ctype) != conn->ksnc_type) {
+		CERROR ("Mismatched types: me %d, %s ip %u.%u.%u.%u %d\n",
+			conn->ksnc_type, libcfs_id2str(*peerid),
+			HIPQUAD(conn->ksnc_ipaddr),
+			hello->kshm_ctype);
+		return -EPROTO;
+	}
+
+	return 0;
+}
+
+int
+ksocknal_connect (ksock_route_t *route)
+{
+	LIST_HEAD    (zombies);
+	ksock_peer_t     *peer = route->ksnr_peer;
+	int	       type;
+	int	       wanted;
+	socket_t     *sock;
+	cfs_time_t	deadline;
+	int	       retry_later = 0;
+	int	       rc = 0;
+
+	deadline = cfs_time_add(cfs_time_current(),
+				cfs_time_seconds(*ksocknal_tunables.ksnd_timeout));
+
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	LASSERT (route->ksnr_scheduled);
+	LASSERT (!route->ksnr_connecting);
+
+	route->ksnr_connecting = 1;
+
+	for (;;) {
+		wanted = ksocknal_route_mask() & ~route->ksnr_connected;
+
+		/* stop connecting if peer/route got closed under me, or
+		 * route got connected while queued */
+		if (peer->ksnp_closing || route->ksnr_deleted ||
+		    wanted == 0) {
+			retry_later = 0;
+			break;
+		}
+
+		/* reschedule if peer is connecting to me */
+		if (peer->ksnp_accepting > 0) {
+			CDEBUG(D_NET,
+			       "peer %s(%d) already connecting to me, retry later.\n",
+			       libcfs_nid2str(peer->ksnp_id.nid), peer->ksnp_accepting);
+			retry_later = 1;
+		}
+
+		if (retry_later) /* needs reschedule */
+			break;
+
+		if ((wanted & (1 << SOCKLND_CONN_ANY)) != 0) {
+			type = SOCKLND_CONN_ANY;
+		} else if ((wanted & (1 << SOCKLND_CONN_CONTROL)) != 0) {
+			type = SOCKLND_CONN_CONTROL;
+		} else if ((wanted & (1 << SOCKLND_CONN_BULK_IN)) != 0) {
+			type = SOCKLND_CONN_BULK_IN;
+		} else {
+			LASSERT ((wanted & (1 << SOCKLND_CONN_BULK_OUT)) != 0);
+			type = SOCKLND_CONN_BULK_OUT;
+		}
+
+		write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+		if (cfs_time_aftereq(cfs_time_current(), deadline)) {
+			rc = -ETIMEDOUT;
+			lnet_connect_console_error(rc, peer->ksnp_id.nid,
+						   route->ksnr_ipaddr,
+						   route->ksnr_port);
+			goto failed;
+		}
+
+		rc = lnet_connect(&sock, peer->ksnp_id.nid,
+				  route->ksnr_myipaddr,
+				  route->ksnr_ipaddr, route->ksnr_port);
+		if (rc != 0)
+			goto failed;
+
+		rc = ksocknal_create_conn(peer->ksnp_ni, route, sock, type);
+		if (rc < 0) {
+			lnet_connect_console_error(rc, peer->ksnp_id.nid,
+						   route->ksnr_ipaddr,
+						   route->ksnr_port);
+			goto failed;
+		}
+
+		/* A +ve RC means I have to retry because I lost the connection
+		 * race or I have to renegotiate protocol version */
+		retry_later = (rc != 0);
+		if (retry_later)
+			CDEBUG(D_NET, "peer %s: conn race, retry later.\n",
+			       libcfs_nid2str(peer->ksnp_id.nid));
+
+		write_lock_bh(&ksocknal_data.ksnd_global_lock);
+	}
+
+	route->ksnr_scheduled = 0;
+	route->ksnr_connecting = 0;
+
+	if (retry_later) {
+		/* re-queue for attention; this frees me up to handle
+		 * the peer's incoming connection request */
+
+		if (rc == EALREADY ||
+		    (rc == 0 && peer->ksnp_accepting > 0)) {
+			/* We want to introduce a delay before next
+			 * attempt to connect if we lost conn race,
+			 * but the race is resolved quickly usually,
+			 * so min_reconnectms should be good heuristic */
+			route->ksnr_retry_interval =
+				cfs_time_seconds(*ksocknal_tunables.ksnd_min_reconnectms)/1000;
+			route->ksnr_timeout = cfs_time_add(cfs_time_current(),
+							   route->ksnr_retry_interval);
+		}
+
+		ksocknal_launch_connection_locked(route);
+	}
+
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+	return retry_later;
+
+ failed:
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	route->ksnr_scheduled = 0;
+	route->ksnr_connecting = 0;
+
+	/* This is a retry rather than a new connection */
+	route->ksnr_retry_interval *= 2;
+	route->ksnr_retry_interval =
+		MAX(route->ksnr_retry_interval,
+		    cfs_time_seconds(*ksocknal_tunables.ksnd_min_reconnectms)/1000);
+	route->ksnr_retry_interval =
+		MIN(route->ksnr_retry_interval,
+		    cfs_time_seconds(*ksocknal_tunables.ksnd_max_reconnectms)/1000);
+
+	LASSERT (route->ksnr_retry_interval != 0);
+	route->ksnr_timeout = cfs_time_add(cfs_time_current(),
+					   route->ksnr_retry_interval);
+
+	if (!list_empty(&peer->ksnp_tx_queue) &&
+	    peer->ksnp_accepting == 0 &&
+	    ksocknal_find_connecting_route_locked(peer) == NULL) {
+		ksock_conn_t *conn;
+
+		/* ksnp_tx_queue is queued on a conn on successful
+		 * connection for V1.x and V2.x */
+		if (!list_empty (&peer->ksnp_conns)) {
+			conn = list_entry(peer->ksnp_conns.next,
+					      ksock_conn_t, ksnc_list);
+			LASSERT (conn->ksnc_proto == &ksocknal_protocol_v3x);
+		}
+
+		/* take all the blocked packets while I've got the lock and
+		 * complete below... */
+		list_splice_init(&peer->ksnp_tx_queue, &zombies);
+	}
+
+#if 0	   /* irrelevent with only eager routes */
+	if (!route->ksnr_deleted) {
+		/* make this route least-favourite for re-selection */
+		list_del(&route->ksnr_list);
+		list_add_tail(&route->ksnr_list, &peer->ksnp_routes);
+	}
+#endif
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+	ksocknal_peer_failed(peer);
+	ksocknal_txlist_done(peer->ksnp_ni, &zombies, 1);
+	return 0;
+}
+
+/*
+ * check whether we need to create more connds.
+ * It will try to create new thread if it's necessary, @timeout can
+ * be updated if failed to create, so caller wouldn't keep try while
+ * running out of resource.
+ */
+static int
+ksocknal_connd_check_start(long sec, long *timeout)
+{
+	char name[16];
+	int rc;
+	int total = ksocknal_data.ksnd_connd_starting +
+		    ksocknal_data.ksnd_connd_running;
+
+	if (unlikely(ksocknal_data.ksnd_init < SOCKNAL_INIT_ALL)) {
+		/* still in initializing */
+		return 0;
+	}
+
+	if (total >= *ksocknal_tunables.ksnd_nconnds_max ||
+	    total > ksocknal_data.ksnd_connd_connecting + SOCKNAL_CONND_RESV) {
+		/* can't create more connd, or still have enough
+		 * threads to handle more connecting */
+		return 0;
+	}
+
+	if (list_empty(&ksocknal_data.ksnd_connd_routes)) {
+		/* no pending connecting request */
+		return 0;
+	}
+
+	if (sec - ksocknal_data.ksnd_connd_failed_stamp <= 1) {
+		/* may run out of resource, retry later */
+		*timeout = cfs_time_seconds(1);
+		return 0;
+	}
+
+	if (ksocknal_data.ksnd_connd_starting > 0) {
+		/* serialize starting to avoid flood */
+		return 0;
+	}
+
+	ksocknal_data.ksnd_connd_starting_stamp = sec;
+	ksocknal_data.ksnd_connd_starting++;
+	spin_unlock_bh(&ksocknal_data.ksnd_connd_lock);
+
+	/* NB: total is the next id */
+	snprintf(name, sizeof(name), "socknal_cd%02d", total);
+	rc = ksocknal_thread_start(ksocknal_connd, NULL, name);
+
+	spin_lock_bh(&ksocknal_data.ksnd_connd_lock);
+	if (rc == 0)
+		return 1;
+
+	/* we tried ... */
+	LASSERT(ksocknal_data.ksnd_connd_starting > 0);
+	ksocknal_data.ksnd_connd_starting--;
+	ksocknal_data.ksnd_connd_failed_stamp = cfs_time_current_sec();
+
+	return 1;
+}
+
+/*
+ * check whether current thread can exit, it will return 1 if there are too
+ * many threads and no creating in past 120 seconds.
+ * Also, this function may update @timeout to make caller come back
+ * again to recheck these conditions.
+ */
+static int
+ksocknal_connd_check_stop(long sec, long *timeout)
+{
+	int val;
+
+	if (unlikely(ksocknal_data.ksnd_init < SOCKNAL_INIT_ALL)) {
+		/* still in initializing */
+		return 0;
+	}
+
+	if (ksocknal_data.ksnd_connd_starting > 0) {
+		/* in progress of starting new thread */
+		return 0;
+	}
+
+	if (ksocknal_data.ksnd_connd_running <=
+	    *ksocknal_tunables.ksnd_nconnds) { /* can't shrink */
+		return 0;
+	}
+
+	/* created thread in past 120 seconds? */
+	val = (int)(ksocknal_data.ksnd_connd_starting_stamp +
+		    SOCKNAL_CONND_TIMEOUT - sec);
+
+	*timeout = (val > 0) ? cfs_time_seconds(val) :
+			       cfs_time_seconds(SOCKNAL_CONND_TIMEOUT);
+	if (val > 0)
+		return 0;
+
+	/* no creating in past 120 seconds */
+
+	return ksocknal_data.ksnd_connd_running >
+	       ksocknal_data.ksnd_connd_connecting + SOCKNAL_CONND_RESV;
+}
+
+/* Go through connd_routes queue looking for a route that we can process
+ * right now, @timeout_p can be updated if we need to come back later */
+static ksock_route_t *
+ksocknal_connd_get_route_locked(signed long *timeout_p)
+{
+	ksock_route_t *route;
+	cfs_time_t     now;
+
+	now = cfs_time_current();
+
+	/* connd_routes can contain both pending and ordinary routes */
+	list_for_each_entry (route, &ksocknal_data.ksnd_connd_routes,
+				 ksnr_connd_list) {
+
+		if (route->ksnr_retry_interval == 0 ||
+		    cfs_time_aftereq(now, route->ksnr_timeout))
+			return route;
+
+		if (*timeout_p == MAX_SCHEDULE_TIMEOUT ||
+		    (int)*timeout_p > (int)(route->ksnr_timeout - now))
+			*timeout_p = (int)(route->ksnr_timeout - now);
+	}
+
+	return NULL;
+}
+
+int
+ksocknal_connd (void *arg)
+{
+	spinlock_t    *connd_lock = &ksocknal_data.ksnd_connd_lock;
+	ksock_connreq_t   *cr;
+	wait_queue_t     wait;
+	int		nloops = 0;
+	int		cons_retry = 0;
+
+	cfs_block_allsigs ();
+
+	init_waitqueue_entry_current (&wait);
+
+	spin_lock_bh(connd_lock);
+
+	LASSERT(ksocknal_data.ksnd_connd_starting > 0);
+	ksocknal_data.ksnd_connd_starting--;
+	ksocknal_data.ksnd_connd_running++;
+
+	while (!ksocknal_data.ksnd_shuttingdown) {
+		ksock_route_t *route = NULL;
+		long sec = cfs_time_current_sec();
+		long timeout = MAX_SCHEDULE_TIMEOUT;
+		int  dropped_lock = 0;
+
+		if (ksocknal_connd_check_stop(sec, &timeout)) {
+			/* wakeup another one to check stop */
+			wake_up(&ksocknal_data.ksnd_connd_waitq);
+			break;
+		}
+
+		if (ksocknal_connd_check_start(sec, &timeout)) {
+			/* created new thread */
+			dropped_lock = 1;
+		}
+
+		if (!list_empty(&ksocknal_data.ksnd_connd_connreqs)) {
+			/* Connection accepted by the listener */
+			cr = list_entry(ksocknal_data.ksnd_connd_connreqs. \
+					    next, ksock_connreq_t, ksncr_list);
+
+			list_del(&cr->ksncr_list);
+			spin_unlock_bh(connd_lock);
+			dropped_lock = 1;
+
+			ksocknal_create_conn(cr->ksncr_ni, NULL,
+					     cr->ksncr_sock, SOCKLND_CONN_NONE);
+			lnet_ni_decref(cr->ksncr_ni);
+			LIBCFS_FREE(cr, sizeof(*cr));
+
+			spin_lock_bh(connd_lock);
+		}
+
+		/* Only handle an outgoing connection request if there
+		 * is a thread left to handle incoming connections and
+		 * create new connd */
+		if (ksocknal_data.ksnd_connd_connecting + SOCKNAL_CONND_RESV <
+		    ksocknal_data.ksnd_connd_running) {
+			route = ksocknal_connd_get_route_locked(&timeout);
+		}
+		if (route != NULL) {
+			list_del (&route->ksnr_connd_list);
+			ksocknal_data.ksnd_connd_connecting++;
+			spin_unlock_bh(connd_lock);
+			dropped_lock = 1;
+
+			if (ksocknal_connect(route)) {
+				/* consecutive retry */
+				if (cons_retry++ > SOCKNAL_INSANITY_RECONN) {
+					CWARN("massive consecutive "
+					      "re-connecting to %u.%u.%u.%u\n",
+					      HIPQUAD(route->ksnr_ipaddr));
+					cons_retry = 0;
+				}
+			} else {
+				cons_retry = 0;
+			}
+
+			ksocknal_route_decref(route);
+
+			spin_lock_bh(connd_lock);
+			ksocknal_data.ksnd_connd_connecting--;
+		}
+
+		if (dropped_lock) {
+			if (++nloops < SOCKNAL_RESCHED)
+				continue;
+			spin_unlock_bh(connd_lock);
+			nloops = 0;
+			cond_resched();
+			spin_lock_bh(connd_lock);
+			continue;
+		}
+
+		/* Nothing to do for 'timeout'  */
+		set_current_state(TASK_INTERRUPTIBLE);
+		add_wait_queue_exclusive(&ksocknal_data.ksnd_connd_waitq, &wait);
+		spin_unlock_bh(connd_lock);
+
+		nloops = 0;
+		waitq_timedwait(&wait, TASK_INTERRUPTIBLE, timeout);
+
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&ksocknal_data.ksnd_connd_waitq, &wait);
+		spin_lock_bh(connd_lock);
+	}
+	ksocknal_data.ksnd_connd_running--;
+	spin_unlock_bh(connd_lock);
+
+	ksocknal_thread_fini();
+	return 0;
+}
+
+ksock_conn_t *
+ksocknal_find_timed_out_conn (ksock_peer_t *peer)
+{
+	/* We're called with a shared lock on ksnd_global_lock */
+	ksock_conn_t      *conn;
+	struct list_head	*ctmp;
+
+	list_for_each (ctmp, &peer->ksnp_conns) {
+		int     error;
+		conn = list_entry (ctmp, ksock_conn_t, ksnc_list);
+
+		/* Don't need the {get,put}connsock dance to deref ksnc_sock */
+		LASSERT (!conn->ksnc_closing);
+
+		/* SOCK_ERROR will reset error code of socket in
+		 * some platform (like Darwin8.x) */
+		error = cfs_sock_error(conn->ksnc_sock);
+		if (error != 0) {
+			ksocknal_conn_addref(conn);
+
+			switch (error) {
+			case ECONNRESET:
+				CNETERR("A connection with %s "
+					"(%u.%u.%u.%u:%d) was reset; "
+					"it may have rebooted.\n",
+					libcfs_id2str(peer->ksnp_id),
+					HIPQUAD(conn->ksnc_ipaddr),
+					conn->ksnc_port);
+				break;
+			case ETIMEDOUT:
+				CNETERR("A connection with %s "
+					"(%u.%u.%u.%u:%d) timed out; the "
+					"network or node may be down.\n",
+					libcfs_id2str(peer->ksnp_id),
+					HIPQUAD(conn->ksnc_ipaddr),
+					conn->ksnc_port);
+				break;
+			default:
+				CNETERR("An unexpected network error %d "
+					"occurred with %s "
+					"(%u.%u.%u.%u:%d\n", error,
+					libcfs_id2str(peer->ksnp_id),
+					HIPQUAD(conn->ksnc_ipaddr),
+					conn->ksnc_port);
+				break;
+			}
+
+			return (conn);
+		}
+
+		if (conn->ksnc_rx_started &&
+		    cfs_time_aftereq(cfs_time_current(),
+				     conn->ksnc_rx_deadline)) {
+			/* Timed out incomplete incoming message */
+			ksocknal_conn_addref(conn);
+			CNETERR("Timeout receiving from %s (%u.%u.%u.%u:%d), "
+				"state %d wanted %d left %d\n",
+				libcfs_id2str(peer->ksnp_id),
+				HIPQUAD(conn->ksnc_ipaddr),
+				conn->ksnc_port,
+				conn->ksnc_rx_state,
+				conn->ksnc_rx_nob_wanted,
+				conn->ksnc_rx_nob_left);
+			return (conn);
+		}
+
+		if ((!list_empty(&conn->ksnc_tx_queue) ||
+		     cfs_sock_wmem_queued(conn->ksnc_sock) != 0) &&
+		    cfs_time_aftereq(cfs_time_current(),
+				     conn->ksnc_tx_deadline)) {
+			/* Timed out messages queued for sending or
+			 * buffered in the socket's send buffer */
+			ksocknal_conn_addref(conn);
+			CNETERR("Timeout sending data to %s (%u.%u.%u.%u:%d) "
+				"the network or that node may be down.\n",
+				libcfs_id2str(peer->ksnp_id),
+				HIPQUAD(conn->ksnc_ipaddr),
+				conn->ksnc_port);
+			return (conn);
+		}
+	}
+
+	return (NULL);
+}
+
+static inline void
+ksocknal_flush_stale_txs(ksock_peer_t *peer)
+{
+	ksock_tx_t	*tx;
+	LIST_HEAD      (stale_txs);
+
+	write_lock_bh(&ksocknal_data.ksnd_global_lock);
+
+	while (!list_empty (&peer->ksnp_tx_queue)) {
+		tx = list_entry (peer->ksnp_tx_queue.next,
+				     ksock_tx_t, tx_list);
+
+		if (!cfs_time_aftereq(cfs_time_current(),
+				      tx->tx_deadline))
+			break;
+
+		list_del (&tx->tx_list);
+		list_add_tail (&tx->tx_list, &stale_txs);
+	}
+
+	write_unlock_bh(&ksocknal_data.ksnd_global_lock);
+
+	ksocknal_txlist_done(peer->ksnp_ni, &stale_txs, 1);
+}
+
+int
+ksocknal_send_keepalive_locked(ksock_peer_t *peer)
+{
+	ksock_sched_t  *sched;
+	ksock_conn_t   *conn;
+	ksock_tx_t     *tx;
+
+	if (list_empty(&peer->ksnp_conns)) /* last_alive will be updated by create_conn */
+		return 0;
+
+	if (peer->ksnp_proto != &ksocknal_protocol_v3x)
+		return 0;
+
+	if (*ksocknal_tunables.ksnd_keepalive <= 0 ||
+	    cfs_time_before(cfs_time_current(),
+			    cfs_time_add(peer->ksnp_last_alive,
+					 cfs_time_seconds(*ksocknal_tunables.ksnd_keepalive))))
+		return 0;
+
+	if (cfs_time_before(cfs_time_current(),
+			    peer->ksnp_send_keepalive))
+		return 0;
+
+	/* retry 10 secs later, so we wouldn't put pressure
+	 * on this peer if we failed to send keepalive this time */
+	peer->ksnp_send_keepalive = cfs_time_shift(10);
+
+	conn = ksocknal_find_conn_locked(peer, NULL, 1);
+	if (conn != NULL) {
+		sched = conn->ksnc_scheduler;
+
+		spin_lock_bh(&sched->kss_lock);
+		if (!list_empty(&conn->ksnc_tx_queue)) {
+			spin_unlock_bh(&sched->kss_lock);
+			/* there is an queued ACK, don't need keepalive */
+			return 0;
+		}
+
+		spin_unlock_bh(&sched->kss_lock);
+	}
+
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+
+	/* cookie = 1 is reserved for keepalive PING */
+	tx = ksocknal_alloc_tx_noop(1, 1);
+	if (tx == NULL) {
+		read_lock(&ksocknal_data.ksnd_global_lock);
+		return -ENOMEM;
+	}
+
+	if (ksocknal_launch_packet(peer->ksnp_ni, tx, peer->ksnp_id) == 0) {
+		read_lock(&ksocknal_data.ksnd_global_lock);
+		return 1;
+	}
+
+	ksocknal_free_tx(tx);
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	return -EIO;
+}
+
+
+void
+ksocknal_check_peer_timeouts (int idx)
+{
+	struct list_head       *peers = &ksocknal_data.ksnd_peers[idx];
+	ksock_peer_t     *peer;
+	ksock_conn_t     *conn;
+	ksock_tx_t       *tx;
+
+ again:
+	/* NB. We expect to have a look at all the peers and not find any
+	 * connections to time out, so we just use a shared lock while we
+	 * take a look... */
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	list_for_each_entry(peer, peers, ksnp_list) {
+		cfs_time_t  deadline = 0;
+		int	 resid = 0;
+		int	 n     = 0;
+
+		if (ksocknal_send_keepalive_locked(peer) != 0) {
+			read_unlock(&ksocknal_data.ksnd_global_lock);
+			goto again;
+		}
+
+		conn = ksocknal_find_timed_out_conn (peer);
+
+		if (conn != NULL) {
+			read_unlock(&ksocknal_data.ksnd_global_lock);
+
+			ksocknal_close_conn_and_siblings (conn, -ETIMEDOUT);
+
+			/* NB we won't find this one again, but we can't
+			 * just proceed with the next peer, since we dropped
+			 * ksnd_global_lock and it might be dead already! */
+			ksocknal_conn_decref(conn);
+			goto again;
+		}
+
+		/* we can't process stale txs right here because we're
+		 * holding only shared lock */
+		if (!list_empty (&peer->ksnp_tx_queue)) {
+			ksock_tx_t *tx =
+				list_entry (peer->ksnp_tx_queue.next,
+						ksock_tx_t, tx_list);
+
+			if (cfs_time_aftereq(cfs_time_current(),
+					     tx->tx_deadline)) {
+
+				ksocknal_peer_addref(peer);
+				read_unlock(&ksocknal_data.ksnd_global_lock);
+
+				ksocknal_flush_stale_txs(peer);
+
+				ksocknal_peer_decref(peer);
+				goto again;
+			}
+		}
+
+		if (list_empty(&peer->ksnp_zc_req_list))
+			continue;
+
+		spin_lock(&peer->ksnp_lock);
+		list_for_each_entry(tx, &peer->ksnp_zc_req_list, tx_zc_list) {
+			if (!cfs_time_aftereq(cfs_time_current(),
+					      tx->tx_deadline))
+				break;
+			/* ignore the TX if connection is being closed */
+			if (tx->tx_conn->ksnc_closing)
+				continue;
+			n++;
+		}
+
+		if (n == 0) {
+			spin_unlock(&peer->ksnp_lock);
+			continue;
+		}
+
+		tx = list_entry(peer->ksnp_zc_req_list.next,
+				    ksock_tx_t, tx_zc_list);
+		deadline = tx->tx_deadline;
+		resid    = tx->tx_resid;
+		conn     = tx->tx_conn;
+		ksocknal_conn_addref(conn);
+
+		spin_unlock(&peer->ksnp_lock);
+		read_unlock(&ksocknal_data.ksnd_global_lock);
+
+		CERROR("Total %d stale ZC_REQs for peer %s detected; the "
+		       "oldest(%p) timed out %ld secs ago, "
+		       "resid: %d, wmem: %d\n",
+		       n, libcfs_nid2str(peer->ksnp_id.nid), tx,
+		       cfs_duration_sec(cfs_time_current() - deadline),
+		       resid, cfs_sock_wmem_queued(conn->ksnc_sock));
+
+		ksocknal_close_conn_and_siblings (conn, -ETIMEDOUT);
+		ksocknal_conn_decref(conn);
+		goto again;
+	}
+
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+}
+
+int
+ksocknal_reaper (void *arg)
+{
+	wait_queue_t     wait;
+	ksock_conn_t      *conn;
+	ksock_sched_t     *sched;
+	struct list_head	 enomem_conns;
+	int		nenomem_conns;
+	cfs_duration_t     timeout;
+	int		i;
+	int		peer_index = 0;
+	cfs_time_t	 deadline = cfs_time_current();
+
+	cfs_block_allsigs ();
+
+	INIT_LIST_HEAD(&enomem_conns);
+	init_waitqueue_entry_current (&wait);
+
+	spin_lock_bh(&ksocknal_data.ksnd_reaper_lock);
+
+	while (!ksocknal_data.ksnd_shuttingdown) {
+
+		if (!list_empty (&ksocknal_data.ksnd_deathrow_conns)) {
+			conn = list_entry (ksocknal_data. \
+					       ksnd_deathrow_conns.next,
+					       ksock_conn_t, ksnc_list);
+			list_del (&conn->ksnc_list);
+
+			spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
+
+			ksocknal_terminate_conn(conn);
+			ksocknal_conn_decref(conn);
+
+			spin_lock_bh(&ksocknal_data.ksnd_reaper_lock);
+			continue;
+		}
+
+		if (!list_empty (&ksocknal_data.ksnd_zombie_conns)) {
+			conn = list_entry (ksocknal_data.ksnd_zombie_conns.\
+					       next, ksock_conn_t, ksnc_list);
+			list_del (&conn->ksnc_list);
+
+			spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
+
+			ksocknal_destroy_conn(conn);
+
+			spin_lock_bh(&ksocknal_data.ksnd_reaper_lock);
+			continue;
+		}
+
+		if (!list_empty (&ksocknal_data.ksnd_enomem_conns)) {
+			list_add(&enomem_conns,
+				     &ksocknal_data.ksnd_enomem_conns);
+			list_del_init(&ksocknal_data.ksnd_enomem_conns);
+		}
+
+		spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
+
+		/* reschedule all the connections that stalled with ENOMEM... */
+		nenomem_conns = 0;
+		while (!list_empty (&enomem_conns)) {
+			conn = list_entry (enomem_conns.next,
+					       ksock_conn_t, ksnc_tx_list);
+			list_del (&conn->ksnc_tx_list);
+
+			sched = conn->ksnc_scheduler;
+
+			spin_lock_bh(&sched->kss_lock);
+
+			LASSERT(conn->ksnc_tx_scheduled);
+			conn->ksnc_tx_ready = 1;
+			list_add_tail(&conn->ksnc_tx_list,
+					  &sched->kss_tx_conns);
+			wake_up(&sched->kss_waitq);
+
+			spin_unlock_bh(&sched->kss_lock);
+			nenomem_conns++;
+		}
+
+		/* careful with the jiffy wrap... */
+		while ((timeout = cfs_time_sub(deadline,
+					       cfs_time_current())) <= 0) {
+			const int n = 4;
+			const int p = 1;
+			int       chunk = ksocknal_data.ksnd_peer_hash_size;
+
+			/* Time to check for timeouts on a few more peers: I do
+			 * checks every 'p' seconds on a proportion of the peer
+			 * table and I need to check every connection 'n' times
+			 * within a timeout interval, to ensure I detect a
+			 * timeout on any connection within (n+1)/n times the
+			 * timeout interval. */
+
+			if (*ksocknal_tunables.ksnd_timeout > n * p)
+				chunk = (chunk * n * p) /
+					*ksocknal_tunables.ksnd_timeout;
+			if (chunk == 0)
+				chunk = 1;
+
+			for (i = 0; i < chunk; i++) {
+				ksocknal_check_peer_timeouts (peer_index);
+				peer_index = (peer_index + 1) %
+					     ksocknal_data.ksnd_peer_hash_size;
+			}
+
+			deadline = cfs_time_add(deadline, cfs_time_seconds(p));
+		}
+
+		if (nenomem_conns != 0) {
+			/* Reduce my timeout if I rescheduled ENOMEM conns.
+			 * This also prevents me getting woken immediately
+			 * if any go back on my enomem list. */
+			timeout = SOCKNAL_ENOMEM_RETRY;
+		}
+		ksocknal_data.ksnd_reaper_waketime =
+			cfs_time_add(cfs_time_current(), timeout);
+
+		set_current_state (TASK_INTERRUPTIBLE);
+		add_wait_queue (&ksocknal_data.ksnd_reaper_waitq, &wait);
+
+		if (!ksocknal_data.ksnd_shuttingdown &&
+		    list_empty (&ksocknal_data.ksnd_deathrow_conns) &&
+		    list_empty (&ksocknal_data.ksnd_zombie_conns))
+			waitq_timedwait (&wait, TASK_INTERRUPTIBLE,
+					     timeout);
+
+		set_current_state (TASK_RUNNING);
+		remove_wait_queue (&ksocknal_data.ksnd_reaper_waitq, &wait);
+
+		spin_lock_bh(&ksocknal_data.ksnd_reaper_lock);
+	}
+
+	spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
+
+	ksocknal_thread_fini();
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,602 @@
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ *
+ *   Author: Zach Brown <zab@zabbo.net>
+ *   Author: Peter J. Braam <braam@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *   Author: Eric Barton <eric@bartonsoftware.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define DEBUG_PORTAL_ALLOC
+#define DEBUG_SUBSYSTEM S_LND
+
+#include "socklnd_lib-linux.h"
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lnet.h>
+#include <linux/lnet/lib-lnet.h>
+#include <linux/lnet/socklnd.h>
+#include <linux/lnet/lnet-sysctl.h>
+
+#define SOCKNAL_PEER_HASH_SIZE  101	     /* # peer lists */
+#define SOCKNAL_RESCHED	 100	     /* # scheduler loops before reschedule */
+#define SOCKNAL_INSANITY_RECONN 5000	    /* connd is trying on reconn infinitely */
+#define SOCKNAL_ENOMEM_RETRY    CFS_TICK	/* jiffies between retries */
+
+#define SOCKNAL_SINGLE_FRAG_TX      0	   /* disable multi-fragment sends */
+#define SOCKNAL_SINGLE_FRAG_RX      0	   /* disable multi-fragment receives */
+
+#define SOCKNAL_VERSION_DEBUG       0	   /* enable protocol version debugging */
+
+/* risk kmap deadlock on multi-frag I/O (backs off to single-frag if disabled).
+ * no risk if we're not running on a CONFIG_HIGHMEM platform. */
+#ifdef CONFIG_HIGHMEM
+# define SOCKNAL_RISK_KMAP_DEADLOCK  0
+#else
+# define SOCKNAL_RISK_KMAP_DEADLOCK  1
+#endif
+
+struct ksock_sched_info;
+
+typedef struct				  /* per scheduler state */
+{
+	spinlock_t		kss_lock;	/* serialise */
+	struct list_head		kss_rx_conns;	/* conn waiting to be read */
+	/* conn waiting to be written */
+	struct list_head		kss_tx_conns;
+	/* zombie noop tx list */
+	struct list_head		kss_zombie_noop_txs;
+	wait_queue_head_t		kss_waitq;	/* where scheduler sleeps */
+	/* # connections assigned to this scheduler */
+	int			kss_nconns;
+	struct ksock_sched_info	*kss_info;	/* owner of it */
+	struct page		*kss_rx_scratch_pgs[LNET_MAX_IOV];
+	struct iovec		kss_scratch_iov[LNET_MAX_IOV];
+} ksock_sched_t;
+
+struct ksock_sched_info {
+	int			ksi_nthreads_max; /* max allowed threads */
+	int			ksi_nthreads;	/* number of threads */
+	int			ksi_cpt;	/* CPT id */
+	ksock_sched_t		*ksi_scheds;	/* array of schedulers */
+};
+
+#define KSOCK_CPT_SHIFT			16
+#define KSOCK_THREAD_ID(cpt, sid)	(((cpt) << KSOCK_CPT_SHIFT) | (sid))
+#define KSOCK_THREAD_CPT(id)		((id) >> KSOCK_CPT_SHIFT)
+#define KSOCK_THREAD_SID(id)		((id) & ((1UL << KSOCK_CPT_SHIFT) - 1))
+
+typedef struct				  /* in-use interface */
+{
+	__u32		ksni_ipaddr;		/* interface's IP address */
+	__u32		ksni_netmask;		/* interface's network mask */
+	int		ksni_nroutes;		/* # routes using (active) */
+	int		ksni_npeers;		/* # peers using (passive) */
+	char		ksni_name[IFNAMSIZ];	/* interface name */
+} ksock_interface_t;
+
+typedef struct
+{
+	/* "stuck" socket timeout (seconds) */
+	int	      *ksnd_timeout;
+	/* # scheduler threads in each pool while starting */
+	int		 *ksnd_nscheds;
+	int	      *ksnd_nconnds;	 /* # connection daemons */
+	int	      *ksnd_nconnds_max;     /* max # connection daemons */
+	int	      *ksnd_min_reconnectms; /* first connection retry after (ms)... */
+	int	      *ksnd_max_reconnectms; /* ...exponentially increasing to this */
+	int	      *ksnd_eager_ack;       /* make TCP ack eagerly? */
+	int	      *ksnd_typed_conns;     /* drive sockets by type? */
+	int	      *ksnd_min_bulk;	/* smallest "large" message */
+	int	      *ksnd_tx_buffer_size;  /* socket tx buffer size */
+	int	      *ksnd_rx_buffer_size;  /* socket rx buffer size */
+	int	      *ksnd_nagle;	   /* enable NAGLE? */
+	int	      *ksnd_round_robin;     /* round robin for multiple interfaces */
+	int	      *ksnd_keepalive;       /* # secs for sending keepalive NOOP */
+	int	      *ksnd_keepalive_idle;  /* # idle secs before 1st probe */
+	int	      *ksnd_keepalive_count; /* # probes */
+	int	      *ksnd_keepalive_intvl; /* time between probes */
+	int	      *ksnd_credits;	 /* # concurrent sends */
+	int	      *ksnd_peertxcredits;   /* # concurrent sends to 1 peer */
+	int	      *ksnd_peerrtrcredits;  /* # per-peer router buffer credits */
+	int	      *ksnd_peertimeout;     /* seconds to consider peer dead */
+	int	      *ksnd_enable_csum;     /* enable check sum */
+	int	      *ksnd_inject_csum_error; /* set non-zero to inject checksum error */
+	int	      *ksnd_nonblk_zcack;    /* always send zc-ack on non-blocking connection */
+	unsigned int     *ksnd_zc_min_payload;  /* minimum zero copy payload size */
+	int	      *ksnd_zc_recv;	 /* enable ZC receive (for Chelsio TOE) */
+	int	      *ksnd_zc_recv_min_nfrags; /* minimum # of fragments to enable ZC receive */
+#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
+	ctl_table_header_t *ksnd_sysctl;   /* sysctl interface */
+#endif
+} ksock_tunables_t;
+
+typedef struct
+{
+	__u64		  ksnn_incarnation;	/* my epoch */
+	spinlock_t	  ksnn_lock;		/* serialise */
+	struct list_head	  ksnn_list;		/* chain on global list */
+	int		  ksnn_npeers;		/* # peers */
+	int		  ksnn_shutdown;	/* shutting down? */
+	int		  ksnn_ninterfaces;	/* IP interfaces */
+	ksock_interface_t ksnn_interfaces[LNET_MAX_INTERFACES];
+} ksock_net_t;
+
+/** connd timeout */
+#define SOCKNAL_CONND_TIMEOUT  120
+/** reserved thread for accepting & creating new connd */
+#define SOCKNAL_CONND_RESV     1
+
+typedef struct
+{
+	int			ksnd_init;	/* initialisation state */
+	int			ksnd_nnets;	/* # networks set up */
+	struct list_head		ksnd_nets;	/* list of nets */
+	/* stabilize peer/conn ops */
+	rwlock_t		ksnd_global_lock;
+	/* hash table of all my known peers */
+	struct list_head		*ksnd_peers;
+	int			ksnd_peer_hash_size; /* size of ksnd_peers */
+
+	int			ksnd_nthreads;	/* # live threads */
+	int			ksnd_shuttingdown; /* tell threads to exit */
+	/* schedulers information */
+	struct ksock_sched_info	**ksnd_sched_info;
+
+	atomic_t      ksnd_nactive_txs;    /* #active txs */
+
+	struct list_head	ksnd_deathrow_conns; /* conns to close: reaper_lock*/
+	struct list_head	ksnd_zombie_conns;   /* conns to free: reaper_lock */
+	struct list_head	ksnd_enomem_conns;   /* conns to retry: reaper_lock*/
+	wait_queue_head_t       ksnd_reaper_waitq;   /* reaper sleeps here */
+	cfs_time_t	ksnd_reaper_waketime;/* when reaper will wake */
+	spinlock_t	  ksnd_reaper_lock;	/* serialise */
+
+	int	       ksnd_enomem_tx;      /* test ENOMEM sender */
+	int	       ksnd_stall_tx;       /* test sluggish sender */
+	int	       ksnd_stall_rx;       /* test sluggish receiver */
+
+	struct list_head	ksnd_connd_connreqs; /* incoming connection requests */
+	struct list_head	ksnd_connd_routes;   /* routes waiting to be connected */
+	wait_queue_head_t       ksnd_connd_waitq;    /* connds sleep here */
+	int	       ksnd_connd_connecting;/* # connds connecting */
+	/** time stamp of the last failed connecting attempt */
+	long	      ksnd_connd_failed_stamp;
+	/** # starting connd */
+	unsigned	  ksnd_connd_starting;
+	/** time stamp of the last starting connd */
+	long	      ksnd_connd_starting_stamp;
+	/** # running connd */
+	unsigned	  ksnd_connd_running;
+	spinlock_t	  ksnd_connd_lock;	/* serialise */
+
+	struct list_head	  ksnd_idle_noop_txs;	/* list head for freed noop tx */
+	spinlock_t	  ksnd_tx_lock;		/* serialise, g_lock unsafe */
+
+} ksock_nal_data_t;
+
+#define SOCKNAL_INIT_NOTHING    0
+#define SOCKNAL_INIT_DATA       1
+#define SOCKNAL_INIT_ALL	2
+
+/* A packet just assembled for transmission is represented by 1 or more
+ * struct iovec fragments (the first frag contains the portals header),
+ * followed by 0 or more lnet_kiov_t fragments.
+ *
+ * On the receive side, initially 1 struct iovec fragment is posted for
+ * receive (the header).  Once the header has been received, the payload is
+ * received into either struct iovec or lnet_kiov_t fragments, depending on
+ * what the header matched or whether the message needs forwarding. */
+
+struct ksock_conn;			      /* forward ref */
+struct ksock_peer;			      /* forward ref */
+struct ksock_route;			     /* forward ref */
+struct ksock_proto;			     /* forward ref */
+
+typedef struct				  /* transmit packet */
+{
+	struct list_head     tx_list;	/* queue on conn for transmission etc */
+	struct list_head     tx_zc_list;     /* queue on peer for ZC request */
+	atomic_t   tx_refcount;    /* tx reference count */
+	int	    tx_nob;	 /* # packet bytes */
+	int	    tx_resid;       /* residual bytes */
+	int	    tx_niov;	/* # packet iovec frags */
+	struct iovec  *tx_iov;	 /* packet iovec frags */
+	int	    tx_nkiov;       /* # packet page frags */
+	unsigned short tx_zc_aborted;  /* aborted ZC request */
+	unsigned short tx_zc_capable:1; /* payload is large enough for ZC */
+	unsigned short tx_zc_checked:1; /* Have I checked if I should ZC? */
+	unsigned short tx_nonblk:1;    /* it's a non-blocking ACK */
+	lnet_kiov_t   *tx_kiov;	/* packet page frags */
+	struct ksock_conn  *tx_conn;	/* owning conn */
+	lnet_msg_t    *tx_lnetmsg;     /* lnet message for lnet_finalize() */
+	cfs_time_t     tx_deadline;    /* when (in jiffies) tx times out */
+	ksock_msg_t    tx_msg;	 /* socklnd message buffer */
+	int	    tx_desc_size;   /* size of this descriptor */
+	union {
+		struct {
+			struct iovec iov;       /* virt hdr */
+			lnet_kiov_t  kiov[0];   /* paged payload */
+		}		  paged;
+		struct {
+			struct iovec iov[1];    /* virt hdr + payload */
+		}		  virt;
+	}		       tx_frags;
+} ksock_tx_t;
+
+#define KSOCK_NOOP_TX_SIZE  ((int)offsetof(ksock_tx_t, tx_frags.paged.kiov[0]))
+
+/* network zero copy callback descriptor embedded in ksock_tx_t */
+
+/* space for the rx frag descriptors; we either read a single contiguous
+ * header, or up to LNET_MAX_IOV frags of payload of either type. */
+typedef union {
+	struct iovec     iov[LNET_MAX_IOV];
+	lnet_kiov_t      kiov[LNET_MAX_IOV];
+} ksock_rxiovspace_t;
+
+#define SOCKNAL_RX_KSM_HEADER   1	       /* reading ksock message header */
+#define SOCKNAL_RX_LNET_HEADER  2	       /* reading lnet message header */
+#define SOCKNAL_RX_PARSE	3	       /* Calling lnet_parse() */
+#define SOCKNAL_RX_PARSE_WAIT   4	       /* waiting to be told to read the body */
+#define SOCKNAL_RX_LNET_PAYLOAD 5	       /* reading lnet payload (to deliver here) */
+#define SOCKNAL_RX_SLOP	 6	       /* skipping body */
+
+typedef struct ksock_conn
+{
+	struct ksock_peer  *ksnc_peer;	 /* owning peer */
+	struct ksock_route *ksnc_route;	/* owning route */
+	struct list_head	  ksnc_list;	 /* stash on peer's conn list */
+	socket_t       *ksnc_sock;	 /* actual socket */
+	void	       *ksnc_saved_data_ready; /* socket's original data_ready() callback */
+	void	       *ksnc_saved_write_space; /* socket's original write_space() callback */
+	atomic_t	ksnc_conn_refcount; /* conn refcount */
+	atomic_t	ksnc_sock_refcount; /* sock refcount */
+	ksock_sched_t      *ksnc_scheduler;  /* who schedules this connection */
+	__u32	       ksnc_myipaddr;   /* my IP */
+	__u32	       ksnc_ipaddr;     /* peer's IP */
+	int		 ksnc_port;       /* peer's port */
+	signed int	  ksnc_type:3;     /* type of connection,
+					      * should be signed value */
+	unsigned int	    ksnc_closing:1;  /* being shut down */
+	unsigned int	    ksnc_flip:1;     /* flip or not, only for V2.x */
+	unsigned int	    ksnc_zc_capable:1; /* enable to ZC */
+	struct ksock_proto *ksnc_proto;      /* protocol for the connection */
+
+	/* reader */
+	struct list_head  ksnc_rx_list;     /* where I enq waiting input or a forwarding descriptor */
+	cfs_time_t	    ksnc_rx_deadline; /* when (in jiffies) receive times out */
+	__u8		  ksnc_rx_started;  /* started receiving a message */
+	__u8		  ksnc_rx_ready;    /* data ready to read */
+	__u8		  ksnc_rx_scheduled;/* being progressed */
+	__u8		  ksnc_rx_state;    /* what is being read */
+	int		   ksnc_rx_nob_left; /* # bytes to next hdr/body */
+	int		   ksnc_rx_nob_wanted; /* bytes actually wanted */
+	int		   ksnc_rx_niov;     /* # iovec frags */
+	struct iovec	 *ksnc_rx_iov;      /* the iovec frags */
+	int		   ksnc_rx_nkiov;    /* # page frags */
+	lnet_kiov_t	  *ksnc_rx_kiov;     /* the page frags */
+	ksock_rxiovspace_t    ksnc_rx_iov_space;/* space for frag descriptors */
+	__u32		 ksnc_rx_csum;     /* partial checksum for incoming data */
+	void		 *ksnc_cookie;      /* rx lnet_finalize passthru arg */
+	ksock_msg_t	   ksnc_msg;	 /* incoming message buffer:
+						 * V2.x message takes the
+						 * whole struct
+						 * V1.x message is a bare
+						 * lnet_hdr_t, it's stored in
+						 * ksnc_msg.ksm_u.lnetmsg */
+
+	/* WRITER */
+	struct list_head	    ksnc_tx_list;     /* where I enq waiting for output space */
+	struct list_head	    ksnc_tx_queue;    /* packets waiting to be sent */
+	ksock_tx_t	   *ksnc_tx_carrier;  /* next TX that can carry a LNet message or ZC-ACK */
+	cfs_time_t	    ksnc_tx_deadline; /* when (in jiffies) tx times out */
+	int		   ksnc_tx_bufnob;     /* send buffer marker */
+	atomic_t	  ksnc_tx_nob;	/* # bytes queued */
+	int		   ksnc_tx_ready;      /* write space */
+	int		   ksnc_tx_scheduled;  /* being progressed */
+	cfs_time_t	    ksnc_tx_last_post;  /* time stamp of the last posted TX */
+} ksock_conn_t;
+
+typedef struct ksock_route
+{
+	struct list_head	    ksnr_list;	/* chain on peer route list */
+	struct list_head	    ksnr_connd_list;  /* chain on ksnr_connd_routes */
+	struct ksock_peer    *ksnr_peer;	/* owning peer */
+	atomic_t	  ksnr_refcount;    /* # users */
+	cfs_time_t	    ksnr_timeout;     /* when (in jiffies) reconnection can happen next */
+	cfs_duration_t	ksnr_retry_interval; /* how long between retries */
+	__u32		 ksnr_myipaddr;    /* my IP */
+	__u32		 ksnr_ipaddr;      /* IP address to connect to */
+	int		   ksnr_port;	/* port to connect to */
+	unsigned int	  ksnr_scheduled:1; /* scheduled for attention */
+	unsigned int	  ksnr_connecting:1;/* connection establishment in progress */
+	unsigned int	  ksnr_connected:4; /* connections established by type */
+	unsigned int	  ksnr_deleted:1;   /* been removed from peer? */
+	unsigned int	  ksnr_share_count; /* created explicitly? */
+	int		   ksnr_conn_count;  /* # conns established by this route */
+} ksock_route_t;
+
+#define SOCKNAL_KEEPALIVE_PING	  1       /* cookie for keepalive ping */
+
+typedef struct ksock_peer
+{
+	struct list_head	    ksnp_list;	/* stash on global peer list */
+	cfs_time_t	    ksnp_last_alive;  /* when (in jiffies) I was last alive */
+	lnet_process_id_t     ksnp_id;       /* who's on the other end(s) */
+	atomic_t	  ksnp_refcount; /* # users */
+	int		   ksnp_sharecount;  /* lconf usage counter */
+	int		   ksnp_closing;  /* being closed */
+	int		   ksnp_accepting;/* # passive connections pending */
+	int		   ksnp_error;    /* errno on closing last conn */
+	__u64		 ksnp_zc_next_cookie;/* ZC completion cookie */
+	__u64		 ksnp_incarnation;   /* latest known peer incarnation */
+	struct ksock_proto   *ksnp_proto;    /* latest known peer protocol */
+	struct list_head	    ksnp_conns;    /* all active connections */
+	struct list_head	    ksnp_routes;   /* routes */
+	struct list_head	    ksnp_tx_queue; /* waiting packets */
+	spinlock_t	      ksnp_lock;	/* serialize, g_lock unsafe */
+	struct list_head	    ksnp_zc_req_list;   /* zero copy requests wait for ACK  */
+	cfs_time_t	    ksnp_send_keepalive; /* time to send keepalive */
+	lnet_ni_t	    *ksnp_ni;       /* which network */
+	int		   ksnp_n_passive_ips; /* # of... */
+	__u32		 ksnp_passive_ips[LNET_MAX_INTERFACES]; /* preferred local interfaces */
+} ksock_peer_t;
+
+typedef struct ksock_connreq
+{
+	struct list_head	    ksncr_list;     /* stash on ksnd_connd_connreqs */
+	lnet_ni_t	    *ksncr_ni;       /* chosen NI */
+	socket_t	 *ksncr_sock;     /* accepted socket */
+} ksock_connreq_t;
+
+extern ksock_nal_data_t ksocknal_data;
+extern ksock_tunables_t ksocknal_tunables;
+
+#define SOCKNAL_MATCH_NO	0	/* TX can't match type of connection */
+#define SOCKNAL_MATCH_YES       1	/* TX matches type of connection */
+#define SOCKNAL_MATCH_MAY       2	/* TX can be sent on the connection, but not preferred */
+
+typedef struct ksock_proto
+{
+	int	   pro_version;					      /* version number of protocol */
+	int	 (*pro_send_hello)(ksock_conn_t *, ksock_hello_msg_t *);     /* handshake function */
+	int	 (*pro_recv_hello)(ksock_conn_t *, ksock_hello_msg_t *, int);/* handshake function */
+	void	(*pro_pack)(ksock_tx_t *);				  /* message pack */
+	void	(*pro_unpack)(ksock_msg_t *);			       /* message unpack */
+	ksock_tx_t *(*pro_queue_tx_msg)(ksock_conn_t *, ksock_tx_t *);	  /* queue tx on the connection */
+	int	 (*pro_queue_tx_zcack)(ksock_conn_t *, ksock_tx_t *, __u64); /* queue ZC ack on the connection */
+	int	 (*pro_handle_zcreq)(ksock_conn_t *, __u64, int);	    /* handle ZC request */
+	int	 (*pro_handle_zcack)(ksock_conn_t *, __u64, __u64);	  /* handle ZC ACK */
+	int	 (*pro_match_tx)(ksock_conn_t *, ksock_tx_t *, int);	 /* msg type matches the connection type:
+										 * return value:
+										 *   return MATCH_NO  : no
+										 *   return MATCH_YES : matching type
+										 *   return MATCH_MAY : can be backup */
+} ksock_proto_t;
+
+extern ksock_proto_t ksocknal_protocol_v1x;
+extern ksock_proto_t ksocknal_protocol_v2x;
+extern ksock_proto_t ksocknal_protocol_v3x;
+
+#define KSOCK_PROTO_V1_MAJOR    LNET_PROTO_TCP_VERSION_MAJOR
+#define KSOCK_PROTO_V1_MINOR    LNET_PROTO_TCP_VERSION_MINOR
+#define KSOCK_PROTO_V1	  KSOCK_PROTO_V1_MAJOR
+
+#ifndef CPU_MASK_NONE
+#define CPU_MASK_NONE   0UL
+#endif
+
+static inline int
+ksocknal_route_mask(void)
+{
+	if (!*ksocknal_tunables.ksnd_typed_conns)
+		return (1 << SOCKLND_CONN_ANY);
+
+	return ((1 << SOCKLND_CONN_CONTROL) |
+		(1 << SOCKLND_CONN_BULK_IN) |
+		(1 << SOCKLND_CONN_BULK_OUT));
+}
+
+static inline struct list_head *
+ksocknal_nid2peerlist (lnet_nid_t nid)
+{
+	unsigned int hash = ((unsigned int)nid) % ksocknal_data.ksnd_peer_hash_size;
+
+	return (&ksocknal_data.ksnd_peers [hash]);
+}
+
+static inline void
+ksocknal_conn_addref (ksock_conn_t *conn)
+{
+	LASSERT (atomic_read(&conn->ksnc_conn_refcount) > 0);
+	atomic_inc(&conn->ksnc_conn_refcount);
+}
+
+extern void ksocknal_queue_zombie_conn (ksock_conn_t *conn);
+extern void ksocknal_finalize_zcreq(ksock_conn_t *conn);
+
+static inline void
+ksocknal_conn_decref (ksock_conn_t *conn)
+{
+	LASSERT (atomic_read(&conn->ksnc_conn_refcount) > 0);
+	if (atomic_dec_and_test(&conn->ksnc_conn_refcount))
+		ksocknal_queue_zombie_conn(conn);
+}
+
+static inline int
+ksocknal_connsock_addref (ksock_conn_t *conn)
+{
+	int   rc = -ESHUTDOWN;
+
+	read_lock(&ksocknal_data.ksnd_global_lock);
+	if (!conn->ksnc_closing) {
+		LASSERT(atomic_read(&conn->ksnc_sock_refcount) > 0);
+		atomic_inc(&conn->ksnc_sock_refcount);
+		rc = 0;
+	}
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+
+	return (rc);
+}
+
+static inline void
+ksocknal_connsock_decref (ksock_conn_t *conn)
+{
+	LASSERT (atomic_read(&conn->ksnc_sock_refcount) > 0);
+	if (atomic_dec_and_test(&conn->ksnc_sock_refcount)) {
+		LASSERT (conn->ksnc_closing);
+		libcfs_sock_release(conn->ksnc_sock);
+		conn->ksnc_sock = NULL;
+		ksocknal_finalize_zcreq(conn);
+	}
+}
+
+static inline void
+ksocknal_tx_addref (ksock_tx_t *tx)
+{
+	LASSERT (atomic_read(&tx->tx_refcount) > 0);
+	atomic_inc(&tx->tx_refcount);
+}
+
+extern void ksocknal_tx_prep (ksock_conn_t *, ksock_tx_t *tx);
+extern void ksocknal_tx_done (lnet_ni_t *ni, ksock_tx_t *tx);
+
+static inline void
+ksocknal_tx_decref (ksock_tx_t *tx)
+{
+	LASSERT (atomic_read(&tx->tx_refcount) > 0);
+	if (atomic_dec_and_test(&tx->tx_refcount))
+		ksocknal_tx_done(NULL, tx);
+}
+
+static inline void
+ksocknal_route_addref (ksock_route_t *route)
+{
+	LASSERT (atomic_read(&route->ksnr_refcount) > 0);
+	atomic_inc(&route->ksnr_refcount);
+}
+
+extern void ksocknal_destroy_route (ksock_route_t *route);
+
+static inline void
+ksocknal_route_decref (ksock_route_t *route)
+{
+	LASSERT (atomic_read (&route->ksnr_refcount) > 0);
+	if (atomic_dec_and_test(&route->ksnr_refcount))
+		ksocknal_destroy_route (route);
+}
+
+static inline void
+ksocknal_peer_addref (ksock_peer_t *peer)
+{
+	LASSERT (atomic_read (&peer->ksnp_refcount) > 0);
+	atomic_inc(&peer->ksnp_refcount);
+}
+
+extern void ksocknal_destroy_peer (ksock_peer_t *peer);
+
+static inline void
+ksocknal_peer_decref (ksock_peer_t *peer)
+{
+	LASSERT (atomic_read (&peer->ksnp_refcount) > 0);
+	if (atomic_dec_and_test(&peer->ksnp_refcount))
+		ksocknal_destroy_peer (peer);
+}
+
+int ksocknal_startup (lnet_ni_t *ni);
+void ksocknal_shutdown (lnet_ni_t *ni);
+int ksocknal_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg);
+int ksocknal_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
+int ksocknal_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
+		  int delayed, unsigned int niov,
+		  struct iovec *iov, lnet_kiov_t *kiov,
+		  unsigned int offset, unsigned int mlen, unsigned int rlen);
+int ksocknal_accept(lnet_ni_t *ni, socket_t *sock);
+
+extern int ksocknal_add_peer(lnet_ni_t *ni, lnet_process_id_t id, __u32 ip, int port);
+extern ksock_peer_t *ksocknal_find_peer_locked (lnet_ni_t *ni, lnet_process_id_t id);
+extern ksock_peer_t *ksocknal_find_peer (lnet_ni_t *ni, lnet_process_id_t id);
+extern void ksocknal_peer_failed (ksock_peer_t *peer);
+extern int ksocknal_create_conn (lnet_ni_t *ni, ksock_route_t *route,
+				 socket_t *sock, int type);
+extern void ksocknal_close_conn_locked (ksock_conn_t *conn, int why);
+extern void ksocknal_terminate_conn (ksock_conn_t *conn);
+extern void ksocknal_destroy_conn (ksock_conn_t *conn);
+extern int  ksocknal_close_peer_conns_locked (ksock_peer_t *peer,
+					      __u32 ipaddr, int why);
+extern int ksocknal_close_conn_and_siblings (ksock_conn_t *conn, int why);
+extern int ksocknal_close_matching_conns (lnet_process_id_t id, __u32 ipaddr);
+extern ksock_conn_t *ksocknal_find_conn_locked(ksock_peer_t *peer,
+					       ksock_tx_t *tx, int nonblk);
+
+extern int  ksocknal_launch_packet(lnet_ni_t *ni, ksock_tx_t *tx,
+				   lnet_process_id_t id);
+extern ksock_tx_t *ksocknal_alloc_tx(int type, int size);
+extern void ksocknal_free_tx (ksock_tx_t *tx);
+extern ksock_tx_t *ksocknal_alloc_tx_noop(__u64 cookie, int nonblk);
+extern void ksocknal_next_tx_carrier(ksock_conn_t *conn);
+extern void ksocknal_queue_tx_locked (ksock_tx_t *tx, ksock_conn_t *conn);
+extern void ksocknal_txlist_done (lnet_ni_t *ni, struct list_head *txlist,
+				  int error);
+extern void ksocknal_notify (lnet_ni_t *ni, lnet_nid_t gw_nid, int alive);
+extern void ksocknal_query (struct lnet_ni *ni, lnet_nid_t nid, cfs_time_t *when);
+extern int ksocknal_thread_start(int (*fn)(void *arg), void *arg, char *name);
+extern void ksocknal_thread_fini (void);
+extern void ksocknal_launch_all_connections_locked (ksock_peer_t *peer);
+extern ksock_route_t *ksocknal_find_connectable_route_locked (ksock_peer_t *peer);
+extern ksock_route_t *ksocknal_find_connecting_route_locked (ksock_peer_t *peer);
+extern int ksocknal_new_packet (ksock_conn_t *conn, int skip);
+extern int ksocknal_scheduler (void *arg);
+extern int ksocknal_connd (void *arg);
+extern int ksocknal_reaper (void *arg);
+extern int ksocknal_send_hello (lnet_ni_t *ni, ksock_conn_t *conn,
+				lnet_nid_t peer_nid, ksock_hello_msg_t *hello);
+extern int ksocknal_recv_hello (lnet_ni_t *ni, ksock_conn_t *conn,
+				ksock_hello_msg_t *hello, lnet_process_id_t *id,
+				__u64 *incarnation);
+extern void ksocknal_read_callback(ksock_conn_t *conn);
+extern void ksocknal_write_callback(ksock_conn_t *conn);
+
+extern int ksocknal_lib_zc_capable(ksock_conn_t *conn);
+extern void ksocknal_lib_save_callback(socket_t *sock, ksock_conn_t *conn);
+extern void ksocknal_lib_set_callback(socket_t *sock,  ksock_conn_t *conn);
+extern void ksocknal_lib_reset_callback(socket_t *sock, ksock_conn_t *conn);
+extern void ksocknal_lib_push_conn (ksock_conn_t *conn);
+extern int ksocknal_lib_get_conn_addrs (ksock_conn_t *conn);
+extern int ksocknal_lib_setup_sock (socket_t *so);
+extern int ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx);
+extern int ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx);
+extern void ksocknal_lib_eager_ack (ksock_conn_t *conn);
+extern int ksocknal_lib_recv_iov (ksock_conn_t *conn);
+extern int ksocknal_lib_recv_kiov (ksock_conn_t *conn);
+extern int ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem,
+					   int *rxmem, int *nagle);
+
+extern int ksocknal_tunables_init(void);
+extern void ksocknal_tunables_fini(void);
+extern int ksocknal_lib_tunables_init(void);
+extern void ksocknal_lib_tunables_fini(void);
+
+extern void ksocknal_lib_csum_tx(ksock_tx_t *tx);
+
+extern int ksocknal_lib_memory_pressure(ksock_conn_t *conn);
+extern int ksocknal_lib_bind_thread_to_cpu(int id);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1088 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#include "socklnd.h"
+
+# if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
+
+
+enum {
+	SOCKLND_TIMEOUT = 1,
+	SOCKLND_CREDITS,
+	SOCKLND_PEER_TXCREDITS,
+	SOCKLND_PEER_RTRCREDITS,
+	SOCKLND_PEER_TIMEOUT,
+	SOCKLND_NCONNDS,
+	SOCKLND_RECONNECTS_MIN,
+	SOCKLND_RECONNECTS_MAX,
+	SOCKLND_EAGER_ACK,
+	SOCKLND_ZERO_COPY,
+	SOCKLND_TYPED,
+	SOCKLND_BULK_MIN,
+	SOCKLND_RX_BUFFER_SIZE,
+	SOCKLND_TX_BUFFER_SIZE,
+	SOCKLND_NAGLE,
+	SOCKLND_IRQ_AFFINITY,
+	SOCKLND_ROUND_ROBIN,
+	SOCKLND_KEEPALIVE,
+	SOCKLND_KEEPALIVE_IDLE,
+	SOCKLND_KEEPALIVE_COUNT,
+	SOCKLND_KEEPALIVE_INTVL,
+	SOCKLND_BACKOFF_INIT,
+	SOCKLND_BACKOFF_MAX,
+	SOCKLND_PROTOCOL,
+	SOCKLND_ZERO_COPY_RECV,
+	SOCKLND_ZERO_COPY_RECV_MIN_NFRAGS
+};
+
+static ctl_table_t ksocknal_ctl_table[] = {
+	{
+		.ctl_name = SOCKLND_TIMEOUT,
+		.procname = "timeout",
+		.data     = &ksocknal_tunables.ksnd_timeout,
+		.maxlen   = sizeof (int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_CREDITS,
+		.procname = "credits",
+		.data     = &ksocknal_tunables.ksnd_credits,
+		.maxlen   = sizeof (int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	 {
+		.ctl_name = SOCKLND_PEER_TXCREDITS,
+		.procname = "peer_credits",
+		.data     = &ksocknal_tunables.ksnd_peertxcredits,
+		.maxlen   = sizeof (int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	 {
+		.ctl_name = SOCKLND_PEER_RTRCREDITS,
+		.procname = "peer_buffer_credits",
+		.data     = &ksocknal_tunables.ksnd_peerrtrcredits,
+		.maxlen   = sizeof (int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_PEER_TIMEOUT,
+		.procname = "peer_timeout",
+		.data     = &ksocknal_tunables.ksnd_peertimeout,
+		.maxlen   = sizeof (int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_NCONNDS,
+		.procname = "nconnds",
+		.data     = &ksocknal_tunables.ksnd_nconnds,
+		.maxlen   = sizeof (int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_RECONNECTS_MIN,
+		.procname = "min_reconnectms",
+		.data     = &ksocknal_tunables.ksnd_min_reconnectms,
+		.maxlen   = sizeof (int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_RECONNECTS_MAX,
+		.procname = "max_reconnectms",
+		.data     = &ksocknal_tunables.ksnd_max_reconnectms,
+		.maxlen   = sizeof (int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_EAGER_ACK,
+		.procname = "eager_ack",
+		.data     = &ksocknal_tunables.ksnd_eager_ack,
+		.maxlen   = sizeof (int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_ZERO_COPY,
+		.procname = "zero_copy",
+		.data     = &ksocknal_tunables.ksnd_zc_min_payload,
+		.maxlen   = sizeof (int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_ZERO_COPY_RECV,
+		.procname = "zero_copy_recv",
+		.data     = &ksocknal_tunables.ksnd_zc_recv,
+		.maxlen   = sizeof (int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+
+	{
+		.ctl_name = SOCKLND_ZERO_COPY_RECV_MIN_NFRAGS,
+		.procname = "zero_copy_recv",
+		.data     = &ksocknal_tunables.ksnd_zc_recv_min_nfrags,
+		.maxlen   = sizeof (int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_TYPED,
+		.procname = "typed",
+		.data     = &ksocknal_tunables.ksnd_typed_conns,
+		.maxlen   = sizeof (int),
+		.mode     = 0444,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_BULK_MIN,
+		.procname = "min_bulk",
+		.data     = &ksocknal_tunables.ksnd_min_bulk,
+		.maxlen   = sizeof (int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_RX_BUFFER_SIZE,
+		.procname = "rx_buffer_size",
+		.data     = &ksocknal_tunables.ksnd_rx_buffer_size,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_TX_BUFFER_SIZE,
+		.procname = "tx_buffer_size",
+		.data     = &ksocknal_tunables.ksnd_tx_buffer_size,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_NAGLE,
+		.procname = "nagle",
+		.data     = &ksocknal_tunables.ksnd_nagle,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_ROUND_ROBIN,
+		.procname = "round_robin",
+		.data     = &ksocknal_tunables.ksnd_round_robin,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_KEEPALIVE,
+		.procname = "keepalive",
+		.data     = &ksocknal_tunables.ksnd_keepalive,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_KEEPALIVE_IDLE,
+		.procname = "keepalive_idle",
+		.data     = &ksocknal_tunables.ksnd_keepalive_idle,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_KEEPALIVE_COUNT,
+		.procname = "keepalive_count",
+		.data     = &ksocknal_tunables.ksnd_keepalive_count,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+	{
+		.ctl_name = SOCKLND_KEEPALIVE_INTVL,
+		.procname = "keepalive_intvl",
+		.data     = &ksocknal_tunables.ksnd_keepalive_intvl,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+#if SOCKNAL_VERSION_DEBUG
+	{
+		.ctl_name = SOCKLND_PROTOCOL,
+		.procname = "protocol",
+		.data     = &ksocknal_tunables.ksnd_protocol,
+		.maxlen   = sizeof(int),
+		.mode     = 0644,
+		.proc_handler = &proc_dointvec,
+		.strategy = &sysctl_intvec,
+	},
+#endif
+	{0}
+};
+
+
+ctl_table_t ksocknal_top_ctl_table[] = {
+	{
+		.ctl_name = CTL_SOCKLND,
+		.procname = "socknal",
+		.data     = NULL,
+		.maxlen   = 0,
+		.mode     = 0555,
+		.child    = ksocknal_ctl_table
+	},
+	{ 0 }
+};
+
+int
+ksocknal_lib_tunables_init ()
+{
+	if (!*ksocknal_tunables.ksnd_typed_conns) {
+		int rc = -EINVAL;
+#if SOCKNAL_VERSION_DEBUG
+		if (*ksocknal_tunables.ksnd_protocol < 3)
+			rc = 0;
+#endif
+		if (rc != 0) {
+			CERROR("Protocol V3.x MUST have typed connections\n");
+			return rc;
+		}
+	}
+
+	if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags < 2)
+		*ksocknal_tunables.ksnd_zc_recv_min_nfrags = 2;
+	if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags > LNET_MAX_IOV)
+		*ksocknal_tunables.ksnd_zc_recv_min_nfrags = LNET_MAX_IOV;
+
+	ksocknal_tunables.ksnd_sysctl =
+		cfs_register_sysctl_table(ksocknal_top_ctl_table, 0);
+
+	if (ksocknal_tunables.ksnd_sysctl == NULL)
+		CWARN("Can't setup /proc tunables\n");
+
+	return 0;
+}
+
+void
+ksocknal_lib_tunables_fini ()
+{
+	if (ksocknal_tunables.ksnd_sysctl != NULL)
+		unregister_sysctl_table(ksocknal_tunables.ksnd_sysctl);
+}
+#else
+int
+ksocknal_lib_tunables_init ()
+{
+	return 0;
+}
+
+void
+ksocknal_lib_tunables_fini ()
+{
+}
+#endif /* # if CONFIG_SYSCTL && !CFS_SYSFS_MODULE_PARM */
+
+int
+ksocknal_lib_get_conn_addrs (ksock_conn_t *conn)
+{
+	int rc = libcfs_sock_getaddr(conn->ksnc_sock, 1,
+				     &conn->ksnc_ipaddr,
+				     &conn->ksnc_port);
+
+	/* Didn't need the {get,put}connsock dance to deref ksnc_sock... */
+	LASSERT (!conn->ksnc_closing);
+
+	if (rc != 0) {
+		CERROR ("Error %d getting sock peer IP\n", rc);
+		return rc;
+	}
+
+	rc = libcfs_sock_getaddr(conn->ksnc_sock, 0,
+				 &conn->ksnc_myipaddr, NULL);
+	if (rc != 0) {
+		CERROR ("Error %d getting sock local IP\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+int
+ksocknal_lib_zc_capable(ksock_conn_t *conn)
+{
+	int  caps = conn->ksnc_sock->sk->sk_route_caps;
+
+	if (conn->ksnc_proto == &ksocknal_protocol_v1x)
+		return 0;
+
+	/* ZC if the socket supports scatter/gather and doesn't need software
+	 * checksums */
+	return ((caps & NETIF_F_SG) != 0 && (caps & NETIF_F_ALL_CSUM) != 0);
+}
+
+int
+ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
+{
+	struct socket *sock = conn->ksnc_sock;
+	int	    nob;
+	int	    rc;
+
+	if (*ksocknal_tunables.ksnd_enable_csum	&& /* checksum enabled */
+	    conn->ksnc_proto == &ksocknal_protocol_v2x && /* V2.x connection  */
+	    tx->tx_nob == tx->tx_resid		 && /* frist sending    */
+	    tx->tx_msg.ksm_csum == 0)		     /* not checksummed  */
+		ksocknal_lib_csum_tx(tx);
+
+	/* NB we can't trust socket ops to either consume our iovs
+	 * or leave them alone. */
+
+	{
+#if SOCKNAL_SINGLE_FRAG_TX
+		struct iovec    scratch;
+		struct iovec   *scratchiov = &scratch;
+		unsigned int    niov = 1;
+#else
+		struct iovec   *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
+		unsigned int    niov = tx->tx_niov;
+#endif
+		struct msghdr msg = {
+			.msg_name       = NULL,
+			.msg_namelen    = 0,
+			.msg_iov	= scratchiov,
+			.msg_iovlen     = niov,
+			.msg_control    = NULL,
+			.msg_controllen = 0,
+			.msg_flags      = MSG_DONTWAIT
+		};
+		mm_segment_t oldmm = get_fs();
+		int  i;
+
+		for (nob = i = 0; i < niov; i++) {
+			scratchiov[i] = tx->tx_iov[i];
+			nob += scratchiov[i].iov_len;
+		}
+
+		if (!list_empty(&conn->ksnc_tx_queue) ||
+		    nob < tx->tx_resid)
+			msg.msg_flags |= MSG_MORE;
+
+		set_fs (KERNEL_DS);
+		rc = sock_sendmsg(sock, &msg, nob);
+		set_fs (oldmm);
+	}
+	return rc;
+}
+
+int
+ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
+{
+	struct socket *sock = conn->ksnc_sock;
+	lnet_kiov_t   *kiov = tx->tx_kiov;
+	int	    rc;
+	int	    nob;
+
+	/* Not NOOP message */
+	LASSERT (tx->tx_lnetmsg != NULL);
+
+	/* NB we can't trust socket ops to either consume our iovs
+	 * or leave them alone. */
+	if (tx->tx_msg.ksm_zc_cookies[0] != 0) {
+		/* Zero copy is enabled */
+		struct sock   *sk = sock->sk;
+		struct page   *page = kiov->kiov_page;
+		int	    offset = kiov->kiov_offset;
+		int	    fragsize = kiov->kiov_len;
+		int	    msgflg = MSG_DONTWAIT;
+
+		CDEBUG(D_NET, "page %p + offset %x for %d\n",
+			       page, offset, kiov->kiov_len);
+
+		if (!list_empty(&conn->ksnc_tx_queue) ||
+		    fragsize < tx->tx_resid)
+			msgflg |= MSG_MORE;
+
+		if (sk->sk_prot->sendpage != NULL) {
+			rc = sk->sk_prot->sendpage(sk, page,
+						   offset, fragsize, msgflg);
+		} else {
+			rc = cfs_tcp_sendpage(sk, page, offset, fragsize,
+					      msgflg);
+		}
+	} else {
+#if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK
+		struct iovec  scratch;
+		struct iovec *scratchiov = &scratch;
+		unsigned int  niov = 1;
+#else
+#ifdef CONFIG_HIGHMEM
+#warning "XXX risk of kmap deadlock on multiple frags..."
+#endif
+		struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
+		unsigned int  niov = tx->tx_nkiov;
+#endif
+		struct msghdr msg = {
+			.msg_name       = NULL,
+			.msg_namelen    = 0,
+			.msg_iov	= scratchiov,
+			.msg_iovlen     = niov,
+			.msg_control    = NULL,
+			.msg_controllen = 0,
+			.msg_flags      = MSG_DONTWAIT
+		};
+		mm_segment_t  oldmm = get_fs();
+		int	   i;
+
+		for (nob = i = 0; i < niov; i++) {
+			scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
+						 kiov[i].kiov_offset;
+			nob += scratchiov[i].iov_len = kiov[i].kiov_len;
+		}
+
+		if (!list_empty(&conn->ksnc_tx_queue) ||
+		    nob < tx->tx_resid)
+			msg.msg_flags |= MSG_MORE;
+
+		set_fs (KERNEL_DS);
+		rc = sock_sendmsg(sock, &msg, nob);
+		set_fs (oldmm);
+
+		for (i = 0; i < niov; i++)
+			kunmap(kiov[i].kiov_page);
+	}
+	return rc;
+}
+
+void
+ksocknal_lib_eager_ack (ksock_conn_t *conn)
+{
+	int	    opt = 1;
+	mm_segment_t   oldmm = get_fs();
+	struct socket *sock = conn->ksnc_sock;
+
+	/* Remind the socket to ACK eagerly.  If I don't, the socket might
+	 * think I'm about to send something it could piggy-back the ACK
+	 * on, introducing delay in completing zero-copy sends in my
+	 * peer. */
+
+	set_fs(KERNEL_DS);
+	sock->ops->setsockopt (sock, SOL_TCP, TCP_QUICKACK,
+			       (char *)&opt, sizeof (opt));
+	set_fs(oldmm);
+}
+
+int
+ksocknal_lib_recv_iov (ksock_conn_t *conn)
+{
+#if SOCKNAL_SINGLE_FRAG_RX
+	struct iovec  scratch;
+	struct iovec *scratchiov = &scratch;
+	unsigned int  niov = 1;
+#else
+	struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
+	unsigned int  niov = conn->ksnc_rx_niov;
+#endif
+	struct iovec *iov = conn->ksnc_rx_iov;
+	struct msghdr msg = {
+		.msg_name       = NULL,
+		.msg_namelen    = 0,
+		.msg_iov	= scratchiov,
+		.msg_iovlen     = niov,
+		.msg_control    = NULL,
+		.msg_controllen = 0,
+		.msg_flags      = 0
+	};
+	mm_segment_t oldmm = get_fs();
+	int	  nob;
+	int	  i;
+	int	  rc;
+	int	  fragnob;
+	int	  sum;
+	__u32	saved_csum;
+
+	/* NB we can't trust socket ops to either consume our iovs
+	 * or leave them alone. */
+	LASSERT (niov > 0);
+
+	for (nob = i = 0; i < niov; i++) {
+		scratchiov[i] = iov[i];
+		nob += scratchiov[i].iov_len;
+	}
+	LASSERT (nob <= conn->ksnc_rx_nob_wanted);
+
+	set_fs (KERNEL_DS);
+	rc = sock_recvmsg (conn->ksnc_sock, &msg, nob, MSG_DONTWAIT);
+	/* NB this is just a boolean..........................^ */
+	set_fs (oldmm);
+
+	saved_csum = 0;
+	if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
+		saved_csum = conn->ksnc_msg.ksm_csum;
+		conn->ksnc_msg.ksm_csum = 0;
+	}
+
+	if (saved_csum != 0) {
+		/* accumulate checksum */
+		for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
+			LASSERT (i < niov);
+
+			fragnob = iov[i].iov_len;
+			if (fragnob > sum)
+				fragnob = sum;
+
+			conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
+							   iov[i].iov_base, fragnob);
+		}
+		conn->ksnc_msg.ksm_csum = saved_csum;
+	}
+
+	return rc;
+}
+
+static void
+ksocknal_lib_kiov_vunmap(void *addr)
+{
+	if (addr == NULL)
+		return;
+
+	vunmap(addr);
+}
+
+static void *
+ksocknal_lib_kiov_vmap(lnet_kiov_t *kiov, int niov,
+		       struct iovec *iov, struct page **pages)
+{
+	void	     *addr;
+	int	       nob;
+	int	       i;
+
+	if (!*ksocknal_tunables.ksnd_zc_recv || pages == NULL)
+		return NULL;
+
+	LASSERT (niov <= LNET_MAX_IOV);
+
+	if (niov < 2 ||
+	    niov < *ksocknal_tunables.ksnd_zc_recv_min_nfrags)
+		return NULL;
+
+	for (nob = i = 0; i < niov; i++) {
+		if ((kiov[i].kiov_offset != 0 && i > 0) ||
+		    (kiov[i].kiov_offset + kiov[i].kiov_len != PAGE_CACHE_SIZE && i < niov - 1))
+			return NULL;
+
+		pages[i] = kiov[i].kiov_page;
+		nob += kiov[i].kiov_len;
+	}
+
+	addr = vmap(pages, niov, VM_MAP, PAGE_KERNEL);
+	if (addr == NULL)
+		return NULL;
+
+	iov->iov_base = addr + kiov[0].kiov_offset;
+	iov->iov_len = nob;
+
+	return addr;
+}
+
+int
+ksocknal_lib_recv_kiov (ksock_conn_t *conn)
+{
+#if SOCKNAL_SINGLE_FRAG_RX || !SOCKNAL_RISK_KMAP_DEADLOCK
+	struct iovec   scratch;
+	struct iovec  *scratchiov = &scratch;
+	struct page  **pages      = NULL;
+	unsigned int   niov       = 1;
+#else
+#ifdef CONFIG_HIGHMEM
+#warning "XXX risk of kmap deadlock on multiple frags..."
+#endif
+	struct iovec  *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
+	struct page  **pages      = conn->ksnc_scheduler->kss_rx_scratch_pgs;
+	unsigned int   niov       = conn->ksnc_rx_nkiov;
+#endif
+	lnet_kiov_t   *kiov = conn->ksnc_rx_kiov;
+	struct msghdr msg = {
+		.msg_name       = NULL,
+		.msg_namelen    = 0,
+		.msg_iov	= scratchiov,
+		.msg_control    = NULL,
+		.msg_controllen = 0,
+		.msg_flags      = 0
+	};
+	mm_segment_t oldmm = get_fs();
+	int	  nob;
+	int	  i;
+	int	  rc;
+	void	*base;
+	void	*addr;
+	int	  sum;
+	int	  fragnob;
+
+	/* NB we can't trust socket ops to either consume our iovs
+	 * or leave them alone. */
+	if ((addr = ksocknal_lib_kiov_vmap(kiov, niov, scratchiov, pages)) != NULL) {
+		nob = scratchiov[0].iov_len;
+		msg.msg_iovlen = 1;
+
+	} else {
+		for (nob = i = 0; i < niov; i++) {
+			nob += scratchiov[i].iov_len = kiov[i].kiov_len;
+			scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
+						 kiov[i].kiov_offset;
+		}
+		msg.msg_iovlen = niov;
+	}
+
+	LASSERT (nob <= conn->ksnc_rx_nob_wanted);
+
+	set_fs (KERNEL_DS);
+	rc = sock_recvmsg (conn->ksnc_sock, &msg, nob, MSG_DONTWAIT);
+	/* NB this is just a boolean.......................^ */
+	set_fs (oldmm);
+
+	if (conn->ksnc_msg.ksm_csum != 0) {
+		for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
+			LASSERT (i < niov);
+
+			/* Dang! have to kmap again because I have nowhere to stash the
+			 * mapped address.  But by doing it while the page is still
+			 * mapped, the kernel just bumps the map count and returns me
+			 * the address it stashed. */
+			base = kmap(kiov[i].kiov_page) + kiov[i].kiov_offset;
+			fragnob = kiov[i].kiov_len;
+			if (fragnob > sum)
+				fragnob = sum;
+
+			conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
+							   base, fragnob);
+
+			kunmap(kiov[i].kiov_page);
+		}
+	}
+
+	if (addr != NULL) {
+		ksocknal_lib_kiov_vunmap(addr);
+	} else {
+		for (i = 0; i < niov; i++)
+			kunmap(kiov[i].kiov_page);
+	}
+
+	return (rc);
+}
+
+void
+ksocknal_lib_csum_tx(ksock_tx_t *tx)
+{
+	int	  i;
+	__u32	csum;
+	void	*base;
+
+	LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg);
+	LASSERT(tx->tx_conn != NULL);
+	LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);
+
+	tx->tx_msg.ksm_csum = 0;
+
+	csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base,
+			     tx->tx_iov[0].iov_len);
+
+	if (tx->tx_kiov != NULL) {
+		for (i = 0; i < tx->tx_nkiov; i++) {
+			base = kmap(tx->tx_kiov[i].kiov_page) +
+			       tx->tx_kiov[i].kiov_offset;
+
+			csum = ksocknal_csum(csum, base, tx->tx_kiov[i].kiov_len);
+
+			kunmap(tx->tx_kiov[i].kiov_page);
+		}
+	} else {
+		for (i = 1; i < tx->tx_niov; i++)
+			csum = ksocknal_csum(csum, tx->tx_iov[i].iov_base,
+					     tx->tx_iov[i].iov_len);
+	}
+
+	if (*ksocknal_tunables.ksnd_inject_csum_error) {
+		csum++;
+		*ksocknal_tunables.ksnd_inject_csum_error = 0;
+	}
+
+	tx->tx_msg.ksm_csum = csum;
+}
+
+int
+ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle)
+{
+	mm_segment_t   oldmm = get_fs ();
+	struct socket *sock = conn->ksnc_sock;
+	int	    len;
+	int	    rc;
+
+	rc = ksocknal_connsock_addref(conn);
+	if (rc != 0) {
+		LASSERT (conn->ksnc_closing);
+		*txmem = *rxmem = *nagle = 0;
+		return (-ESHUTDOWN);
+	}
+
+	rc = libcfs_sock_getbuf(sock, txmem, rxmem);
+	if (rc == 0) {
+		len = sizeof(*nagle);
+		set_fs(KERNEL_DS);
+		rc = sock->ops->getsockopt(sock, SOL_TCP, TCP_NODELAY,
+					   (char *)nagle, &len);
+		set_fs(oldmm);
+	}
+
+	ksocknal_connsock_decref(conn);
+
+	if (rc == 0)
+		*nagle = !*nagle;
+	else
+		*txmem = *rxmem = *nagle = 0;
+
+	return (rc);
+}
+
+int
+ksocknal_lib_setup_sock (struct socket *sock)
+{
+	mm_segment_t    oldmm = get_fs ();
+	int	     rc;
+	int	     option;
+	int	     keep_idle;
+	int	     keep_intvl;
+	int	     keep_count;
+	int	     do_keepalive;
+	struct linger   linger;
+
+	sock->sk->sk_allocation = GFP_NOFS;
+
+	/* Ensure this socket aborts active sends immediately when we close
+	 * it. */
+
+	linger.l_onoff = 0;
+	linger.l_linger = 0;
+
+	set_fs (KERNEL_DS);
+	rc = sock_setsockopt (sock, SOL_SOCKET, SO_LINGER,
+			      (char *)&linger, sizeof (linger));
+	set_fs (oldmm);
+	if (rc != 0) {
+		CERROR ("Can't set SO_LINGER: %d\n", rc);
+		return (rc);
+	}
+
+	option = -1;
+	set_fs (KERNEL_DS);
+	rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_LINGER2,
+				    (char *)&option, sizeof (option));
+	set_fs (oldmm);
+	if (rc != 0) {
+		CERROR ("Can't set SO_LINGER2: %d\n", rc);
+		return (rc);
+	}
+
+	if (!*ksocknal_tunables.ksnd_nagle) {
+		option = 1;
+
+		set_fs (KERNEL_DS);
+		rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_NODELAY,
+					    (char *)&option, sizeof (option));
+		set_fs (oldmm);
+		if (rc != 0) {
+			CERROR ("Can't disable nagle: %d\n", rc);
+			return (rc);
+		}
+	}
+
+	rc = libcfs_sock_setbuf(sock,
+				*ksocknal_tunables.ksnd_tx_buffer_size,
+				*ksocknal_tunables.ksnd_rx_buffer_size);
+	if (rc != 0) {
+		CERROR ("Can't set buffer tx %d, rx %d buffers: %d\n",
+			*ksocknal_tunables.ksnd_tx_buffer_size,
+			*ksocknal_tunables.ksnd_rx_buffer_size, rc);
+		return (rc);
+	}
+
+/* TCP_BACKOFF_* sockopt tunables unsupported in stock kernels */
+
+	/* snapshot tunables */
+	keep_idle  = *ksocknal_tunables.ksnd_keepalive_idle;
+	keep_count = *ksocknal_tunables.ksnd_keepalive_count;
+	keep_intvl = *ksocknal_tunables.ksnd_keepalive_intvl;
+
+	do_keepalive = (keep_idle > 0 && keep_count > 0 && keep_intvl > 0);
+
+	option = (do_keepalive ? 1 : 0);
+	set_fs (KERNEL_DS);
+	rc = sock_setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE,
+			      (char *)&option, sizeof (option));
+	set_fs (oldmm);
+	if (rc != 0) {
+		CERROR ("Can't set SO_KEEPALIVE: %d\n", rc);
+		return (rc);
+	}
+
+	if (!do_keepalive)
+		return (0);
+
+	set_fs (KERNEL_DS);
+	rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPIDLE,
+				    (char *)&keep_idle, sizeof (keep_idle));
+	set_fs (oldmm);
+	if (rc != 0) {
+		CERROR ("Can't set TCP_KEEPIDLE: %d\n", rc);
+		return (rc);
+	}
+
+	set_fs (KERNEL_DS);
+	rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPINTVL,
+				    (char *)&keep_intvl, sizeof (keep_intvl));
+	set_fs (oldmm);
+	if (rc != 0) {
+		CERROR ("Can't set TCP_KEEPINTVL: %d\n", rc);
+		return (rc);
+	}
+
+	set_fs (KERNEL_DS);
+	rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPCNT,
+				    (char *)&keep_count, sizeof (keep_count));
+	set_fs (oldmm);
+	if (rc != 0) {
+		CERROR ("Can't set TCP_KEEPCNT: %d\n", rc);
+		return (rc);
+	}
+
+	return (0);
+}
+
+void
+ksocknal_lib_push_conn (ksock_conn_t *conn)
+{
+	struct sock    *sk;
+	struct tcp_sock *tp;
+	int	     nonagle;
+	int	     val = 1;
+	int	     rc;
+	mm_segment_t    oldmm;
+
+	rc = ksocknal_connsock_addref(conn);
+	if (rc != 0)			    /* being shut down */
+		return;
+
+	sk = conn->ksnc_sock->sk;
+	tp = tcp_sk(sk);
+
+	lock_sock (sk);
+	nonagle = tp->nonagle;
+	tp->nonagle = 1;
+	release_sock (sk);
+
+	oldmm = get_fs ();
+	set_fs (KERNEL_DS);
+
+	rc = sk->sk_prot->setsockopt (sk, SOL_TCP, TCP_NODELAY,
+				      (char *)&val, sizeof (val));
+	LASSERT (rc == 0);
+
+	set_fs (oldmm);
+
+	lock_sock (sk);
+	tp->nonagle = nonagle;
+	release_sock (sk);
+
+	ksocknal_connsock_decref(conn);
+}
+
+extern void ksocknal_read_callback (ksock_conn_t *conn);
+extern void ksocknal_write_callback (ksock_conn_t *conn);
+/*
+ * socket call back in Linux
+ */
+static void
+ksocknal_data_ready (struct sock *sk, int n)
+{
+	ksock_conn_t  *conn;
+	ENTRY;
+
+	/* interleave correctly with closing sockets... */
+	LASSERT(!in_irq());
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	conn = sk->sk_user_data;
+	if (conn == NULL) {	     /* raced with ksocknal_terminate_conn */
+		LASSERT (sk->sk_data_ready != &ksocknal_data_ready);
+		sk->sk_data_ready (sk, n);
+	} else
+		ksocknal_read_callback(conn);
+
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+
+	EXIT;
+}
+
+static void
+ksocknal_write_space (struct sock *sk)
+{
+	ksock_conn_t  *conn;
+	int	    wspace;
+	int	    min_wpace;
+
+	/* interleave correctly with closing sockets... */
+	LASSERT(!in_irq());
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	conn = sk->sk_user_data;
+	wspace = SOCKNAL_WSPACE(sk);
+	min_wpace = SOCKNAL_MIN_WSPACE(sk);
+
+	CDEBUG(D_NET, "sk %p wspace %d low water %d conn %p%s%s%s\n",
+	       sk, wspace, min_wpace, conn,
+	       (conn == NULL) ? "" : (conn->ksnc_tx_ready ?
+				      " ready" : " blocked"),
+	       (conn == NULL) ? "" : (conn->ksnc_tx_scheduled ?
+				      " scheduled" : " idle"),
+	       (conn == NULL) ? "" : (list_empty (&conn->ksnc_tx_queue) ?
+				      " empty" : " queued"));
+
+	if (conn == NULL) {	     /* raced with ksocknal_terminate_conn */
+		LASSERT (sk->sk_write_space != &ksocknal_write_space);
+		sk->sk_write_space (sk);
+
+		read_unlock(&ksocknal_data.ksnd_global_lock);
+		return;
+	}
+
+	if (wspace >= min_wpace) {	      /* got enough space */
+		ksocknal_write_callback(conn);
+
+		/* Clear SOCK_NOSPACE _after_ ksocknal_write_callback so the
+		 * ENOMEM check in ksocknal_transmit is race-free (think about
+		 * it). */
+
+		clear_bit (SOCK_NOSPACE, &sk->sk_socket->flags);
+	}
+
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+}
+
+void
+ksocknal_lib_save_callback(struct socket *sock, ksock_conn_t *conn)
+{
+	conn->ksnc_saved_data_ready = sock->sk->sk_data_ready;
+	conn->ksnc_saved_write_space = sock->sk->sk_write_space;
+}
+
+void
+ksocknal_lib_set_callback(struct socket *sock,  ksock_conn_t *conn)
+{
+	sock->sk->sk_user_data = conn;
+	sock->sk->sk_data_ready = ksocknal_data_ready;
+	sock->sk->sk_write_space = ksocknal_write_space;
+	return;
+}
+
+void
+ksocknal_lib_reset_callback(struct socket *sock, ksock_conn_t *conn)
+{
+	/* Remove conn's network callbacks.
+	 * NB I _have_ to restore the callback, rather than storing a noop,
+	 * since the socket could survive past this module being unloaded!! */
+	sock->sk->sk_data_ready = conn->ksnc_saved_data_ready;
+	sock->sk->sk_write_space = conn->ksnc_saved_write_space;
+
+	/* A callback could be in progress already; they hold a read lock
+	 * on ksnd_global_lock (to serialise with me) and NOOP if
+	 * sk_user_data is NULL. */
+	sock->sk->sk_user_data = NULL;
+
+	return ;
+}
+
+int
+ksocknal_lib_memory_pressure(ksock_conn_t *conn)
+{
+	int	    rc = 0;
+	ksock_sched_t *sched;
+
+	sched = conn->ksnc_scheduler;
+	spin_lock_bh(&sched->kss_lock);
+
+	if (!SOCK_TEST_NOSPACE(conn->ksnc_sock) &&
+	    !conn->ksnc_tx_ready) {
+		/* SOCK_NOSPACE is set when the socket fills
+		 * and cleared in the write_space callback
+		 * (which also sets ksnc_tx_ready).  If
+		 * SOCK_NOSPACE and ksnc_tx_ready are BOTH
+		 * zero, I didn't fill the socket and
+		 * write_space won't reschedule me, so I
+		 * return -ENOMEM to get my caller to retry
+		 * after a timeout */
+		rc = -ENOMEM;
+	}
+
+	spin_unlock_bh(&sched->kss_lock);
+
+	return rc;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,91 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#define DEBUG_PORTAL_ALLOC
+
+#ifndef __LINUX_SOCKNAL_LIB_H__
+#define __LINUX_SOCKNAL_LIB_H__
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+#include <linux/uio.h>
+#include <linux/if.h>
+
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/list.h>
+#include <linux/kmod.h>
+#include <linux/sysctl.h>
+#include <asm/uaccess.h>
+#include <asm/div64.h>
+#include <linux/syscalls.h>
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/libcfs/linux/portals_compat25.h>
+
+#include <linux/crc32.h>
+static inline __u32 ksocknal_csum(__u32 crc, unsigned char const *p, size_t len)
+{
+#if 1
+	return crc32_le(crc, p, len);
+#else
+	while (len-- > 0)
+		crc = ((crc + 0x100) & ~0xff) | ((crc + *p++) & 0xff) ;
+	return crc;
+#endif
+}
+
+#define SOCKNAL_WSPACE(sk)       sk_stream_wspace(sk)
+#define SOCKNAL_MIN_WSPACE(sk)   sk_stream_min_wspace(sk)
+
+/* assume one thread for each connection type */
+#define SOCKNAL_NSCHEDS		3
+#define SOCKNAL_NSCHEDS_HIGH	(SOCKNAL_NSCHEDS << 1)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_modparams.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ *
+ *   Author: Eric Barton <eric@bartonsoftware.com>
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "socklnd.h"
+
+static int sock_timeout = 50;
+CFS_MODULE_PARM(sock_timeout, "i", int, 0644,
+		"dead socket timeout (seconds)");
+
+static int credits = 256;
+CFS_MODULE_PARM(credits, "i", int, 0444,
+		"# concurrent sends");
+
+static int peer_credits = 8;
+CFS_MODULE_PARM(peer_credits, "i", int, 0444,
+		"# concurrent sends to 1 peer");
+
+static int peer_buffer_credits = 0;
+CFS_MODULE_PARM(peer_buffer_credits, "i", int, 0444,
+		"# per-peer router buffer credits");
+
+static int peer_timeout = 180;
+CFS_MODULE_PARM(peer_timeout, "i", int, 0444,
+		"Seconds without aliveness news to declare peer dead (<=0 to disable)");
+
+/* Number of daemons in each thread pool which is percpt,
+ * we will estimate reasonable value based on CPUs if it's not set. */
+static unsigned int nscheds;
+CFS_MODULE_PARM(nscheds, "i", int, 0444,
+		"# scheduler daemons in each pool while starting");
+
+static int nconnds = 4;
+CFS_MODULE_PARM(nconnds, "i", int, 0444,
+		"# connection daemons while starting");
+
+static int nconnds_max = 64;
+CFS_MODULE_PARM(nconnds_max, "i", int, 0444,
+		"max # connection daemons");
+
+static int min_reconnectms = 1000;
+CFS_MODULE_PARM(min_reconnectms, "i", int, 0644,
+		"min connection retry interval (mS)");
+
+static int max_reconnectms = 60000;
+CFS_MODULE_PARM(max_reconnectms, "i", int, 0644,
+		"max connection retry interval (mS)");
+
+# define DEFAULT_EAGER_ACK 0
+static int eager_ack = DEFAULT_EAGER_ACK;
+CFS_MODULE_PARM(eager_ack, "i", int, 0644,
+		"send tcp ack packets eagerly");
+
+static int typed_conns = 1;
+CFS_MODULE_PARM(typed_conns, "i", int, 0444,
+		"use different sockets for bulk");
+
+static int min_bulk = (1<<10);
+CFS_MODULE_PARM(min_bulk, "i", int, 0644,
+		"smallest 'large' message");
+
+# define DEFAULT_BUFFER_SIZE 0
+static int tx_buffer_size = DEFAULT_BUFFER_SIZE;
+CFS_MODULE_PARM(tx_buffer_size, "i", int, 0644,
+		"socket tx buffer size (0 for system default)");
+
+static int rx_buffer_size = DEFAULT_BUFFER_SIZE;
+CFS_MODULE_PARM(rx_buffer_size, "i", int, 0644,
+		"socket rx buffer size (0 for system default)");
+
+static int nagle = 0;
+CFS_MODULE_PARM(nagle, "i", int, 0644,
+		"enable NAGLE?");
+
+static int round_robin = 1;
+CFS_MODULE_PARM(round_robin, "i", int, 0644,
+		"Round robin for multiple interfaces");
+
+static int keepalive = 30;
+CFS_MODULE_PARM(keepalive, "i", int, 0644,
+		"# seconds before send keepalive");
+
+static int keepalive_idle = 30;
+CFS_MODULE_PARM(keepalive_idle, "i", int, 0644,
+		"# idle seconds before probe");
+
+#define DEFAULT_KEEPALIVE_COUNT  5
+static int keepalive_count = DEFAULT_KEEPALIVE_COUNT;
+CFS_MODULE_PARM(keepalive_count, "i", int, 0644,
+		"# missed probes == dead");
+
+static int keepalive_intvl = 5;
+CFS_MODULE_PARM(keepalive_intvl, "i", int, 0644,
+		"seconds between probes");
+
+static int enable_csum = 0;
+CFS_MODULE_PARM(enable_csum, "i", int, 0644,
+		"enable check sum");
+
+static int inject_csum_error = 0;
+CFS_MODULE_PARM(inject_csum_error, "i", int, 0644,
+		"set non-zero to inject a checksum error");
+
+static int nonblk_zcack = 1;
+CFS_MODULE_PARM(nonblk_zcack, "i", int, 0644,
+		"always send ZC-ACK on non-blocking connection");
+
+static unsigned int zc_min_payload = (16 << 10);
+CFS_MODULE_PARM(zc_min_payload, "i", int, 0644,
+		"minimum payload size to zero copy");
+
+static unsigned int zc_recv = 0;
+CFS_MODULE_PARM(zc_recv, "i", int, 0644,
+		"enable ZC recv for Chelsio driver");
+
+static unsigned int zc_recv_min_nfrags = 16;
+CFS_MODULE_PARM(zc_recv_min_nfrags, "i", int, 0644,
+		"minimum # of fragments to enable ZC recv");
+
+
+#if SOCKNAL_VERSION_DEBUG
+static int protocol = 3;
+CFS_MODULE_PARM(protocol, "i", int, 0644,
+		"protocol version");
+#endif
+
+ksock_tunables_t ksocknal_tunables;
+
+int ksocknal_tunables_init(void)
+{
+
+	/* initialize ksocknal_tunables structure */
+	ksocknal_tunables.ksnd_timeout	    = &sock_timeout;
+	ksocknal_tunables.ksnd_nscheds		  = &nscheds;
+	ksocknal_tunables.ksnd_nconnds	    = &nconnds;
+	ksocknal_tunables.ksnd_nconnds_max	= &nconnds_max;
+	ksocknal_tunables.ksnd_min_reconnectms    = &min_reconnectms;
+	ksocknal_tunables.ksnd_max_reconnectms    = &max_reconnectms;
+	ksocknal_tunables.ksnd_eager_ack	  = &eager_ack;
+	ksocknal_tunables.ksnd_typed_conns	= &typed_conns;
+	ksocknal_tunables.ksnd_min_bulk	   = &min_bulk;
+	ksocknal_tunables.ksnd_tx_buffer_size     = &tx_buffer_size;
+	ksocknal_tunables.ksnd_rx_buffer_size     = &rx_buffer_size;
+	ksocknal_tunables.ksnd_nagle	      = &nagle;
+	ksocknal_tunables.ksnd_round_robin	= &round_robin;
+	ksocknal_tunables.ksnd_keepalive	  = &keepalive;
+	ksocknal_tunables.ksnd_keepalive_idle     = &keepalive_idle;
+	ksocknal_tunables.ksnd_keepalive_count    = &keepalive_count;
+	ksocknal_tunables.ksnd_keepalive_intvl    = &keepalive_intvl;
+	ksocknal_tunables.ksnd_credits	    = &credits;
+	ksocknal_tunables.ksnd_peertxcredits      = &peer_credits;
+	ksocknal_tunables.ksnd_peerrtrcredits     = &peer_buffer_credits;
+	ksocknal_tunables.ksnd_peertimeout	= &peer_timeout;
+	ksocknal_tunables.ksnd_enable_csum	= &enable_csum;
+	ksocknal_tunables.ksnd_inject_csum_error  = &inject_csum_error;
+	ksocknal_tunables.ksnd_nonblk_zcack       = &nonblk_zcack;
+	ksocknal_tunables.ksnd_zc_min_payload     = &zc_min_payload;
+	ksocknal_tunables.ksnd_zc_recv	    = &zc_recv;
+	ksocknal_tunables.ksnd_zc_recv_min_nfrags = &zc_recv_min_nfrags;
+
+
+
+#if SOCKNAL_VERSION_DEBUG
+	ksocknal_tunables.ksnd_protocol	   = &protocol;
+#endif
+
+#if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
+	ksocknal_tunables.ksnd_sysctl	     =  NULL;
+#endif
+
+	if (*ksocknal_tunables.ksnd_zc_min_payload < (2 << 10))
+		*ksocknal_tunables.ksnd_zc_min_payload = (2 << 10);
+
+	/* initialize platform-sepcific tunables */
+	return ksocknal_lib_tunables_init();
+};
+
+void ksocknal_tunables_fini(void)
+{
+	ksocknal_lib_tunables_fini();
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,797 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ *
+ *   Author: Zach Brown <zab@zabbo.net>
+ *   Author: Peter J. Braam <braam@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *   Author: Eric Barton <eric@bartonsoftware.com>
+ *
+ *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "socklnd.h"
+
+/*
+ * Protocol entries :
+ *   pro_send_hello       : send hello message
+ *   pro_recv_hello       : receive hello message
+ *   pro_pack	     : pack message header
+ *   pro_unpack	   : unpack message header
+ *   pro_queue_tx_zcack() : Called holding BH lock: kss_lock
+ *			  return 1 if ACK is piggybacked, otherwise return 0
+ *   pro_queue_tx_msg()   : Called holding BH lock: kss_lock
+ *			  return the ACK that piggybacked by my message, or NULL
+ *   pro_handle_zcreq()   : handler of incoming ZC-REQ
+ *   pro_handle_zcack()   : handler of incoming ZC-ACK
+ *   pro_match_tx()       : Called holding glock
+ */
+
+static ksock_tx_t *
+ksocknal_queue_tx_msg_v1(ksock_conn_t *conn, ksock_tx_t *tx_msg)
+{
+	/* V1.x, just enqueue it */
+	list_add_tail(&tx_msg->tx_list, &conn->ksnc_tx_queue);
+	return NULL;
+}
+
+void
+ksocknal_next_tx_carrier(ksock_conn_t *conn)
+{
+	ksock_tx_t     *tx = conn->ksnc_tx_carrier;
+
+	/* Called holding BH lock: conn->ksnc_scheduler->kss_lock */
+	LASSERT (!list_empty(&conn->ksnc_tx_queue));
+	LASSERT (tx != NULL);
+
+	/* Next TX that can carry ZC-ACK or LNet message */
+	if (tx->tx_list.next == &conn->ksnc_tx_queue) {
+		/* no more packets queued */
+		conn->ksnc_tx_carrier = NULL;
+	} else {
+		conn->ksnc_tx_carrier = list_entry(tx->tx_list.next,
+						       ksock_tx_t, tx_list);
+		LASSERT (conn->ksnc_tx_carrier->tx_msg.ksm_type == tx->tx_msg.ksm_type);
+	}
+}
+
+static int
+ksocknal_queue_tx_zcack_v2(ksock_conn_t *conn,
+			   ksock_tx_t *tx_ack, __u64 cookie)
+{
+	ksock_tx_t *tx = conn->ksnc_tx_carrier;
+
+	LASSERT (tx_ack == NULL ||
+		 tx_ack->tx_msg.ksm_type == KSOCK_MSG_NOOP);
+
+	/*
+	 * Enqueue or piggyback tx_ack / cookie
+	 * . no tx can piggyback cookie of tx_ack (or cookie), just
+	 *   enqueue the tx_ack (if tx_ack != NUL) and return NULL.
+	 * . There is tx can piggyback cookie of tx_ack (or cookie),
+	 *   piggyback the cookie and return the tx.
+	 */
+	if (tx == NULL) {
+		if (tx_ack != NULL) {
+			list_add_tail(&tx_ack->tx_list,
+					  &conn->ksnc_tx_queue);
+			conn->ksnc_tx_carrier = tx_ack;
+		}
+		return 0;
+	}
+
+	if (tx->tx_msg.ksm_type == KSOCK_MSG_NOOP) {
+		/* tx is noop zc-ack, can't piggyback zc-ack cookie */
+		if (tx_ack != NULL)
+			list_add_tail(&tx_ack->tx_list,
+					  &conn->ksnc_tx_queue);
+		return 0;
+	}
+
+	LASSERT(tx->tx_msg.ksm_type == KSOCK_MSG_LNET);
+	LASSERT(tx->tx_msg.ksm_zc_cookies[1] == 0);
+
+	if (tx_ack != NULL)
+		cookie = tx_ack->tx_msg.ksm_zc_cookies[1];
+
+	/* piggyback the zc-ack cookie */
+	tx->tx_msg.ksm_zc_cookies[1] = cookie;
+	/* move on to the next TX which can carry cookie */
+	ksocknal_next_tx_carrier(conn);
+
+	return 1;
+}
+
+static ksock_tx_t *
+ksocknal_queue_tx_msg_v2(ksock_conn_t *conn, ksock_tx_t *tx_msg)
+{
+	ksock_tx_t  *tx  = conn->ksnc_tx_carrier;
+
+	/*
+	 * Enqueue tx_msg:
+	 * . If there is no NOOP on the connection, just enqueue
+	 *   tx_msg and return NULL
+	 * . If there is NOOP on the connection, piggyback the cookie
+	 *   and replace the NOOP tx, and return the NOOP tx.
+	 */
+	if (tx == NULL) { /* nothing on queue */
+		list_add_tail(&tx_msg->tx_list, &conn->ksnc_tx_queue);
+		conn->ksnc_tx_carrier = tx_msg;
+		return NULL;
+	}
+
+	if (tx->tx_msg.ksm_type == KSOCK_MSG_LNET) { /* nothing to carry */
+		list_add_tail(&tx_msg->tx_list, &conn->ksnc_tx_queue);
+		return NULL;
+	}
+
+	LASSERT (tx->tx_msg.ksm_type == KSOCK_MSG_NOOP);
+
+	/* There is a noop zc-ack can be piggybacked */
+	tx_msg->tx_msg.ksm_zc_cookies[1] = tx->tx_msg.ksm_zc_cookies[1];
+	ksocknal_next_tx_carrier(conn);
+
+	/* use new_tx to replace the noop zc-ack packet */
+	list_add(&tx_msg->tx_list, &tx->tx_list);
+	list_del(&tx->tx_list);
+
+	return tx;
+}
+
+static int
+ksocknal_queue_tx_zcack_v3(ksock_conn_t *conn,
+			   ksock_tx_t *tx_ack, __u64 cookie)
+{
+	ksock_tx_t *tx;
+
+	if (conn->ksnc_type != SOCKLND_CONN_ACK)
+		return ksocknal_queue_tx_zcack_v2(conn, tx_ack, cookie);
+
+	/* non-blocking ZC-ACK (to router) */
+	LASSERT (tx_ack == NULL ||
+		 tx_ack->tx_msg.ksm_type == KSOCK_MSG_NOOP);
+
+	if ((tx = conn->ksnc_tx_carrier) == NULL) {
+		if (tx_ack != NULL) {
+			list_add_tail(&tx_ack->tx_list,
+					  &conn->ksnc_tx_queue);
+			conn->ksnc_tx_carrier = tx_ack;
+		}
+		return 0;
+	}
+
+	/* conn->ksnc_tx_carrier != NULL */
+
+	if (tx_ack != NULL)
+		cookie = tx_ack->tx_msg.ksm_zc_cookies[1];
+
+	if (cookie == SOCKNAL_KEEPALIVE_PING) /* ignore keepalive PING */
+		return 1;
+
+	if (tx->tx_msg.ksm_zc_cookies[1] == SOCKNAL_KEEPALIVE_PING) {
+		/* replace the keepalive PING with a real ACK */
+		LASSERT (tx->tx_msg.ksm_zc_cookies[0] == 0);
+		tx->tx_msg.ksm_zc_cookies[1] = cookie;
+		return 1;
+	}
+
+	if (cookie == tx->tx_msg.ksm_zc_cookies[0] ||
+	    cookie == tx->tx_msg.ksm_zc_cookies[1]) {
+		CWARN("%s: duplicated ZC cookie: "LPU64"\n",
+		      libcfs_id2str(conn->ksnc_peer->ksnp_id), cookie);
+		return 1; /* XXX return error in the future */
+	}
+
+	if (tx->tx_msg.ksm_zc_cookies[0] == 0) {
+		/* NOOP tx has only one ZC-ACK cookie, can carry at least one more */
+		if (tx->tx_msg.ksm_zc_cookies[1] > cookie) {
+			tx->tx_msg.ksm_zc_cookies[0] = tx->tx_msg.ksm_zc_cookies[1];
+			tx->tx_msg.ksm_zc_cookies[1] = cookie;
+		} else {
+			tx->tx_msg.ksm_zc_cookies[0] = cookie;
+		}
+
+		if (tx->tx_msg.ksm_zc_cookies[0] - tx->tx_msg.ksm_zc_cookies[1] > 2) {
+			/* not likely to carry more ACKs, skip it to simplify logic */
+			ksocknal_next_tx_carrier(conn);
+		}
+
+		return 1;
+	}
+
+	/* takes two or more cookies already */
+
+	if (tx->tx_msg.ksm_zc_cookies[0] > tx->tx_msg.ksm_zc_cookies[1]) {
+		__u64   tmp = 0;
+
+		/* two seperated cookies: (a+2, a) or (a+1, a) */
+		LASSERT (tx->tx_msg.ksm_zc_cookies[0] -
+			 tx->tx_msg.ksm_zc_cookies[1] <= 2);
+
+		if (tx->tx_msg.ksm_zc_cookies[0] -
+		    tx->tx_msg.ksm_zc_cookies[1] == 2) {
+			if (cookie == tx->tx_msg.ksm_zc_cookies[1] + 1)
+				tmp = cookie;
+		} else if (cookie == tx->tx_msg.ksm_zc_cookies[1] - 1) {
+			tmp = tx->tx_msg.ksm_zc_cookies[1];
+		} else if (cookie == tx->tx_msg.ksm_zc_cookies[0] + 1) {
+			tmp = tx->tx_msg.ksm_zc_cookies[0];
+		}
+
+		if (tmp != 0) {
+			/* range of cookies */
+			tx->tx_msg.ksm_zc_cookies[0] = tmp - 1;
+			tx->tx_msg.ksm_zc_cookies[1] = tmp + 1;
+			return 1;
+		}
+
+	} else {
+		/* ksm_zc_cookies[0] < ksm_zc_cookies[1], it is range of cookies */
+		if (cookie >= tx->tx_msg.ksm_zc_cookies[0] &&
+		    cookie <= tx->tx_msg.ksm_zc_cookies[1]) {
+			CWARN("%s: duplicated ZC cookie: "LPU64"\n",
+			      libcfs_id2str(conn->ksnc_peer->ksnp_id), cookie);
+			return 1; /* XXX: return error in the future */
+		}
+
+		if (cookie == tx->tx_msg.ksm_zc_cookies[1] + 1) {
+			tx->tx_msg.ksm_zc_cookies[1] = cookie;
+			return 1;
+		}
+
+		if (cookie == tx->tx_msg.ksm_zc_cookies[0] - 1) {
+			tx->tx_msg.ksm_zc_cookies[0] = cookie;
+			return 1;
+		}
+	}
+
+	/* failed to piggyback ZC-ACK */
+	if (tx_ack != NULL) {
+		list_add_tail(&tx_ack->tx_list, &conn->ksnc_tx_queue);
+		/* the next tx can piggyback at least 1 ACK */
+		ksocknal_next_tx_carrier(conn);
+	}
+
+	return 0;
+}
+
+static int
+ksocknal_match_tx(ksock_conn_t *conn, ksock_tx_t *tx, int nonblk)
+{
+	int nob;
+
+#if SOCKNAL_VERSION_DEBUG
+	if (!*ksocknal_tunables.ksnd_typed_conns)
+		return SOCKNAL_MATCH_YES;
+#endif
+
+	if (tx == NULL || tx->tx_lnetmsg == NULL) {
+		/* noop packet */
+		nob = offsetof(ksock_msg_t, ksm_u);
+	} else {
+		nob = tx->tx_lnetmsg->msg_len +
+		      ((conn->ksnc_proto == &ksocknal_protocol_v1x) ?
+		       sizeof(lnet_hdr_t) : sizeof(ksock_msg_t));
+	}
+
+	/* default checking for typed connection */
+	switch (conn->ksnc_type) {
+	default:
+		CERROR("ksnc_type bad: %u\n", conn->ksnc_type);
+		LBUG();
+	case SOCKLND_CONN_ANY:
+		return SOCKNAL_MATCH_YES;
+
+	case SOCKLND_CONN_BULK_IN:
+		return SOCKNAL_MATCH_MAY;
+
+	case SOCKLND_CONN_BULK_OUT:
+		if (nob < *ksocknal_tunables.ksnd_min_bulk)
+			return SOCKNAL_MATCH_MAY;
+		else
+			return SOCKNAL_MATCH_YES;
+
+	case SOCKLND_CONN_CONTROL:
+		if (nob >= *ksocknal_tunables.ksnd_min_bulk)
+			return SOCKNAL_MATCH_MAY;
+		else
+			return SOCKNAL_MATCH_YES;
+	}
+}
+
+static int
+ksocknal_match_tx_v3(ksock_conn_t *conn, ksock_tx_t *tx, int nonblk)
+{
+	int nob;
+
+	if (tx == NULL || tx->tx_lnetmsg == NULL)
+		nob = offsetof(ksock_msg_t, ksm_u);
+	else
+		nob = tx->tx_lnetmsg->msg_len + sizeof(ksock_msg_t);
+
+	switch (conn->ksnc_type) {
+	default:
+		CERROR("ksnc_type bad: %u\n", conn->ksnc_type);
+		LBUG();
+	case SOCKLND_CONN_ANY:
+		return SOCKNAL_MATCH_NO;
+
+	case SOCKLND_CONN_ACK:
+		if (nonblk)
+			return SOCKNAL_MATCH_YES;
+		else if (tx == NULL || tx->tx_lnetmsg == NULL)
+			return SOCKNAL_MATCH_MAY;
+		else
+			return SOCKNAL_MATCH_NO;
+
+	case SOCKLND_CONN_BULK_OUT:
+		if (nonblk)
+			return SOCKNAL_MATCH_NO;
+		else if (nob < *ksocknal_tunables.ksnd_min_bulk)
+			return SOCKNAL_MATCH_MAY;
+		else
+			return SOCKNAL_MATCH_YES;
+
+	case SOCKLND_CONN_CONTROL:
+		if (nonblk)
+			return SOCKNAL_MATCH_NO;
+		else if (nob >= *ksocknal_tunables.ksnd_min_bulk)
+			return SOCKNAL_MATCH_MAY;
+		else
+			return SOCKNAL_MATCH_YES;
+	}
+}
+
+/* (Sink) handle incoming ZC request from sender */
+static int
+ksocknal_handle_zcreq(ksock_conn_t *c, __u64 cookie, int remote)
+{
+	ksock_peer_t   *peer = c->ksnc_peer;
+	ksock_conn_t   *conn;
+	ksock_tx_t     *tx;
+	int	     rc;
+
+	read_lock(&ksocknal_data.ksnd_global_lock);
+
+	conn = ksocknal_find_conn_locked(peer, NULL, !!remote);
+	if (conn != NULL) {
+		ksock_sched_t *sched = conn->ksnc_scheduler;
+
+		LASSERT(conn->ksnc_proto->pro_queue_tx_zcack != NULL);
+
+		spin_lock_bh(&sched->kss_lock);
+
+		rc = conn->ksnc_proto->pro_queue_tx_zcack(conn, NULL, cookie);
+
+		spin_unlock_bh(&sched->kss_lock);
+
+		if (rc) { /* piggybacked */
+			read_unlock(&ksocknal_data.ksnd_global_lock);
+			return 0;
+		}
+	}
+
+	read_unlock(&ksocknal_data.ksnd_global_lock);
+
+	/* ACK connection is not ready, or can't piggyback the ACK */
+	tx = ksocknal_alloc_tx_noop(cookie, !!remote);
+	if (tx == NULL)
+		return -ENOMEM;
+
+	if ((rc = ksocknal_launch_packet(peer->ksnp_ni, tx, peer->ksnp_id)) == 0)
+		return 0;
+
+	ksocknal_free_tx(tx);
+	return rc;
+}
+
+/* (Sender) handle ZC_ACK from sink */
+static int
+ksocknal_handle_zcack(ksock_conn_t *conn, __u64 cookie1, __u64 cookie2)
+{
+	ksock_peer_t      *peer = conn->ksnc_peer;
+	ksock_tx_t	*tx;
+	ksock_tx_t	*tmp;
+	LIST_HEAD     (zlist);
+	int		count;
+
+	if (cookie1 == 0)
+		cookie1 = cookie2;
+
+	count = (cookie1 > cookie2) ? 2 : (cookie2 - cookie1 + 1);
+
+	if (cookie2 == SOCKNAL_KEEPALIVE_PING &&
+	    conn->ksnc_proto == &ksocknal_protocol_v3x) {
+		/* keepalive PING for V3.x, just ignore it */
+		return count == 1 ? 0 : -EPROTO;
+	}
+
+	spin_lock(&peer->ksnp_lock);
+
+	list_for_each_entry_safe(tx, tmp,
+				     &peer->ksnp_zc_req_list, tx_zc_list) {
+		__u64 c = tx->tx_msg.ksm_zc_cookies[0];
+
+		if (c == cookie1 || c == cookie2 || (cookie1 < c && c < cookie2)) {
+			tx->tx_msg.ksm_zc_cookies[0] = 0;
+			list_del(&tx->tx_zc_list);
+			list_add(&tx->tx_zc_list, &zlist);
+
+			if (--count == 0)
+				break;
+		}
+	}
+
+	spin_unlock(&peer->ksnp_lock);
+
+	while (!list_empty(&zlist)) {
+		tx = list_entry(zlist.next, ksock_tx_t, tx_zc_list);
+		list_del(&tx->tx_zc_list);
+		ksocknal_tx_decref(tx);
+	}
+
+	return count == 0 ? 0 : -EPROTO;
+}
+
+static int
+ksocknal_send_hello_v1 (ksock_conn_t *conn, ksock_hello_msg_t *hello)
+{
+	socket_t	*sock = conn->ksnc_sock;
+	lnet_hdr_t	  *hdr;
+	lnet_magicversion_t *hmv;
+	int		  rc;
+	int		  i;
+
+	CLASSERT(sizeof(lnet_magicversion_t) == offsetof(lnet_hdr_t, src_nid));
+
+	LIBCFS_ALLOC(hdr, sizeof(*hdr));
+	if (hdr == NULL) {
+		CERROR("Can't allocate lnet_hdr_t\n");
+		return -ENOMEM;
+	}
+
+	hmv = (lnet_magicversion_t *)&hdr->dest_nid;
+
+	/* Re-organize V2.x message header to V1.x (lnet_hdr_t)
+	 * header and send out */
+	hmv->magic	 = cpu_to_le32 (LNET_PROTO_TCP_MAGIC);
+	hmv->version_major = cpu_to_le16 (KSOCK_PROTO_V1_MAJOR);
+	hmv->version_minor = cpu_to_le16 (KSOCK_PROTO_V1_MINOR);
+
+	if (the_lnet.ln_testprotocompat != 0) {
+		/* single-shot proto check */
+		LNET_LOCK();
+		if ((the_lnet.ln_testprotocompat & 1) != 0) {
+			hmv->version_major++;   /* just different! */
+			the_lnet.ln_testprotocompat &= ~1;
+		}
+		if ((the_lnet.ln_testprotocompat & 2) != 0) {
+			hmv->magic = LNET_PROTO_MAGIC;
+			the_lnet.ln_testprotocompat &= ~2;
+		}
+		LNET_UNLOCK();
+	}
+
+	hdr->src_nid	= cpu_to_le64 (hello->kshm_src_nid);
+	hdr->src_pid	= cpu_to_le32 (hello->kshm_src_pid);
+	hdr->type	   = cpu_to_le32 (LNET_MSG_HELLO);
+	hdr->payload_length = cpu_to_le32 (hello->kshm_nips * sizeof(__u32));
+	hdr->msg.hello.type = cpu_to_le32 (hello->kshm_ctype);
+	hdr->msg.hello.incarnation = cpu_to_le64 (hello->kshm_src_incarnation);
+
+	rc = libcfs_sock_write(sock, hdr, sizeof(*hdr),lnet_acceptor_timeout());
+
+	if (rc != 0) {
+		CNETERR("Error %d sending HELLO hdr to %u.%u.%u.%u/%d\n",
+			rc, HIPQUAD(conn->ksnc_ipaddr), conn->ksnc_port);
+		goto out;
+	}
+
+	if (hello->kshm_nips == 0)
+		goto out;
+
+	for (i = 0; i < (int) hello->kshm_nips; i++) {
+		hello->kshm_ips[i] = __cpu_to_le32 (hello->kshm_ips[i]);
+	}
+
+	rc = libcfs_sock_write(sock, hello->kshm_ips,
+			       hello->kshm_nips * sizeof(__u32),
+			       lnet_acceptor_timeout());
+	if (rc != 0) {
+		CNETERR("Error %d sending HELLO payload (%d)"
+			" to %u.%u.%u.%u/%d\n", rc, hello->kshm_nips,
+			HIPQUAD(conn->ksnc_ipaddr), conn->ksnc_port);
+	}
+out:
+	LIBCFS_FREE(hdr, sizeof(*hdr));
+
+	return rc;
+}
+
+static int
+ksocknal_send_hello_v2 (ksock_conn_t *conn, ksock_hello_msg_t *hello)
+{
+	socket_t   *sock = conn->ksnc_sock;
+	int	     rc;
+
+	hello->kshm_magic   = LNET_PROTO_MAGIC;
+	hello->kshm_version = conn->ksnc_proto->pro_version;
+
+	if (the_lnet.ln_testprotocompat != 0) {
+		/* single-shot proto check */
+		LNET_LOCK();
+		if ((the_lnet.ln_testprotocompat & 1) != 0) {
+			hello->kshm_version++;   /* just different! */
+			the_lnet.ln_testprotocompat &= ~1;
+		}
+		LNET_UNLOCK();
+	}
+
+	rc = libcfs_sock_write(sock, hello, offsetof(ksock_hello_msg_t, kshm_ips),
+			       lnet_acceptor_timeout());
+
+	if (rc != 0) {
+		CNETERR("Error %d sending HELLO hdr to %u.%u.%u.%u/%d\n",
+			rc, HIPQUAD(conn->ksnc_ipaddr), conn->ksnc_port);
+		return rc;
+	}
+
+	if (hello->kshm_nips == 0)
+		return 0;
+
+	rc = libcfs_sock_write(sock, hello->kshm_ips,
+			       hello->kshm_nips * sizeof(__u32),
+			       lnet_acceptor_timeout());
+	if (rc != 0) {
+		CNETERR("Error %d sending HELLO payload (%d)"
+			" to %u.%u.%u.%u/%d\n", rc, hello->kshm_nips,
+			HIPQUAD(conn->ksnc_ipaddr), conn->ksnc_port);
+	}
+
+	return rc;
+}
+
+static int
+ksocknal_recv_hello_v1(ksock_conn_t *conn, ksock_hello_msg_t *hello,int timeout)
+{
+	socket_t	*sock = conn->ksnc_sock;
+	lnet_hdr_t	  *hdr;
+	int		  rc;
+	int		  i;
+
+	LIBCFS_ALLOC(hdr, sizeof(*hdr));
+	if (hdr == NULL) {
+		CERROR("Can't allocate lnet_hdr_t\n");
+		return -ENOMEM;
+	}
+
+	rc = libcfs_sock_read(sock, &hdr->src_nid,
+			      sizeof (*hdr) - offsetof (lnet_hdr_t, src_nid),
+			      timeout);
+	if (rc != 0) {
+		CERROR ("Error %d reading rest of HELLO hdr from %u.%u.%u.%u\n",
+			rc, HIPQUAD(conn->ksnc_ipaddr));
+		LASSERT (rc < 0 && rc != -EALREADY);
+		goto out;
+	}
+
+	/* ...and check we got what we expected */
+	if (hdr->type != cpu_to_le32 (LNET_MSG_HELLO)) {
+		CERROR ("Expecting a HELLO hdr,"
+			" but got type %d from %u.%u.%u.%u\n",
+			le32_to_cpu (hdr->type),
+			HIPQUAD(conn->ksnc_ipaddr));
+		rc = -EPROTO;
+		goto out;
+	}
+
+	hello->kshm_src_nid	 = le64_to_cpu (hdr->src_nid);
+	hello->kshm_src_pid	 = le32_to_cpu (hdr->src_pid);
+	hello->kshm_src_incarnation = le64_to_cpu (hdr->msg.hello.incarnation);
+	hello->kshm_ctype	   = le32_to_cpu (hdr->msg.hello.type);
+	hello->kshm_nips	    = le32_to_cpu (hdr->payload_length) /
+					 sizeof (__u32);
+
+	if (hello->kshm_nips > LNET_MAX_INTERFACES) {
+		CERROR("Bad nips %d from ip %u.%u.%u.%u\n",
+		       hello->kshm_nips, HIPQUAD(conn->ksnc_ipaddr));
+		rc = -EPROTO;
+		goto out;
+	}
+
+	if (hello->kshm_nips == 0)
+		goto out;
+
+	rc = libcfs_sock_read(sock, hello->kshm_ips,
+			      hello->kshm_nips * sizeof(__u32), timeout);
+	if (rc != 0) {
+		CERROR ("Error %d reading IPs from ip %u.%u.%u.%u\n",
+			rc, HIPQUAD(conn->ksnc_ipaddr));
+		LASSERT (rc < 0 && rc != -EALREADY);
+		goto out;
+	}
+
+	for (i = 0; i < (int) hello->kshm_nips; i++) {
+		hello->kshm_ips[i] = __le32_to_cpu(hello->kshm_ips[i]);
+
+		if (hello->kshm_ips[i] == 0) {
+			CERROR("Zero IP[%d] from ip %u.%u.%u.%u\n",
+			       i, HIPQUAD(conn->ksnc_ipaddr));
+			rc = -EPROTO;
+			break;
+		}
+	}
+out:
+	LIBCFS_FREE(hdr, sizeof(*hdr));
+
+	return rc;
+}
+
+static int
+ksocknal_recv_hello_v2 (ksock_conn_t *conn, ksock_hello_msg_t *hello, int timeout)
+{
+	socket_t      *sock = conn->ksnc_sock;
+	int		rc;
+	int		i;
+
+	if (hello->kshm_magic == LNET_PROTO_MAGIC)
+		conn->ksnc_flip = 0;
+	else
+		conn->ksnc_flip = 1;
+
+	rc = libcfs_sock_read(sock, &hello->kshm_src_nid,
+			      offsetof(ksock_hello_msg_t, kshm_ips) -
+				       offsetof(ksock_hello_msg_t, kshm_src_nid),
+			      timeout);
+	if (rc != 0) {
+		CERROR ("Error %d reading HELLO from %u.%u.%u.%u\n",
+			rc, HIPQUAD(conn->ksnc_ipaddr));
+		LASSERT (rc < 0 && rc != -EALREADY);
+		return rc;
+	}
+
+	if (conn->ksnc_flip) {
+		__swab32s(&hello->kshm_src_pid);
+		__swab64s(&hello->kshm_src_nid);
+		__swab32s(&hello->kshm_dst_pid);
+		__swab64s(&hello->kshm_dst_nid);
+		__swab64s(&hello->kshm_src_incarnation);
+		__swab64s(&hello->kshm_dst_incarnation);
+		__swab32s(&hello->kshm_ctype);
+		__swab32s(&hello->kshm_nips);
+	}
+
+	if (hello->kshm_nips > LNET_MAX_INTERFACES) {
+		CERROR("Bad nips %d from ip %u.%u.%u.%u\n",
+		       hello->kshm_nips, HIPQUAD(conn->ksnc_ipaddr));
+		return -EPROTO;
+	}
+
+	if (hello->kshm_nips == 0)
+		return 0;
+
+	rc = libcfs_sock_read(sock, hello->kshm_ips,
+			      hello->kshm_nips * sizeof(__u32), timeout);
+	if (rc != 0) {
+		CERROR ("Error %d reading IPs from ip %u.%u.%u.%u\n",
+			rc, HIPQUAD(conn->ksnc_ipaddr));
+		LASSERT (rc < 0 && rc != -EALREADY);
+		return rc;
+	}
+
+	for (i = 0; i < (int) hello->kshm_nips; i++) {
+		if (conn->ksnc_flip)
+			__swab32s(&hello->kshm_ips[i]);
+
+		if (hello->kshm_ips[i] == 0) {
+			CERROR("Zero IP[%d] from ip %u.%u.%u.%u\n",
+			       i, HIPQUAD(conn->ksnc_ipaddr));
+			return -EPROTO;
+		}
+	}
+
+	return 0;
+}
+
+static void
+ksocknal_pack_msg_v1(ksock_tx_t *tx)
+{
+	/* V1.x has no KSOCK_MSG_NOOP */
+	LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
+	LASSERT(tx->tx_lnetmsg != NULL);
+
+	tx->tx_iov[0].iov_base = (void *)&tx->tx_lnetmsg->msg_hdr;
+	tx->tx_iov[0].iov_len  = sizeof(lnet_hdr_t);
+
+	tx->tx_resid = tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t);
+}
+
+static void
+ksocknal_pack_msg_v2(ksock_tx_t *tx)
+{
+	tx->tx_iov[0].iov_base = (void *)&tx->tx_msg;
+
+	if (tx->tx_lnetmsg != NULL) {
+		LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
+
+		tx->tx_msg.ksm_u.lnetmsg.ksnm_hdr = tx->tx_lnetmsg->msg_hdr;
+		tx->tx_iov[0].iov_len = sizeof(ksock_msg_t);
+		tx->tx_resid = tx->tx_nob = sizeof(ksock_msg_t) + tx->tx_lnetmsg->msg_len;
+	} else {
+		LASSERT(tx->tx_msg.ksm_type == KSOCK_MSG_NOOP);
+
+		tx->tx_iov[0].iov_len = offsetof(ksock_msg_t, ksm_u.lnetmsg.ksnm_hdr);
+		tx->tx_resid = tx->tx_nob = offsetof(ksock_msg_t,  ksm_u.lnetmsg.ksnm_hdr);
+	}
+	/* Don't checksum before start sending, because packet can be piggybacked with ACK */
+}
+
+static void
+ksocknal_unpack_msg_v1(ksock_msg_t *msg)
+{
+	msg->ksm_csum	   = 0;
+	msg->ksm_type	   = KSOCK_MSG_LNET;
+	msg->ksm_zc_cookies[0]  = msg->ksm_zc_cookies[1]  = 0;
+}
+
+static void
+ksocknal_unpack_msg_v2(ksock_msg_t *msg)
+{
+	return;  /* Do nothing */
+}
+
+ksock_proto_t  ksocknal_protocol_v1x =
+{
+	.pro_version	    = KSOCK_PROTO_V1,
+	.pro_send_hello	 = ksocknal_send_hello_v1,
+	.pro_recv_hello	 = ksocknal_recv_hello_v1,
+	.pro_pack	       = ksocknal_pack_msg_v1,
+	.pro_unpack	     = ksocknal_unpack_msg_v1,
+	.pro_queue_tx_msg       = ksocknal_queue_tx_msg_v1,
+	.pro_handle_zcreq       = NULL,
+	.pro_handle_zcack       = NULL,
+	.pro_queue_tx_zcack     = NULL,
+	.pro_match_tx	   = ksocknal_match_tx
+};
+
+ksock_proto_t  ksocknal_protocol_v2x =
+{
+	.pro_version	    = KSOCK_PROTO_V2,
+	.pro_send_hello	 = ksocknal_send_hello_v2,
+	.pro_recv_hello	 = ksocknal_recv_hello_v2,
+	.pro_pack	       = ksocknal_pack_msg_v2,
+	.pro_unpack	     = ksocknal_unpack_msg_v2,
+	.pro_queue_tx_msg       = ksocknal_queue_tx_msg_v2,
+	.pro_queue_tx_zcack     = ksocknal_queue_tx_zcack_v2,
+	.pro_handle_zcreq       = ksocknal_handle_zcreq,
+	.pro_handle_zcack       = ksocknal_handle_zcack,
+	.pro_match_tx	   = ksocknal_match_tx
+};
+
+ksock_proto_t  ksocknal_protocol_v3x =
+{
+	.pro_version	    = KSOCK_PROTO_V3,
+	.pro_send_hello	 = ksocknal_send_hello_v2,
+	.pro_recv_hello	 = ksocknal_recv_hello_v2,
+	.pro_pack	       = ksocknal_pack_msg_v2,
+	.pro_unpack	     = ksocknal_unpack_msg_v2,
+	.pro_queue_tx_msg       = ksocknal_queue_tx_msg_v2,
+	.pro_queue_tx_zcack     = ksocknal_queue_tx_zcack_v3,
+	.pro_handle_zcreq       = ksocknal_handle_zcreq,
+	.pro_handle_zcack       = ksocknal_handle_zcack,
+	.pro_match_tx	   = ksocknal_match_tx_v3
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/acceptor.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/acceptor.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/acceptor.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/acceptor.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,527 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+#include <linux/lnet/lib-lnet.h>
+
+
+static int   accept_port    = 988;
+static int   accept_backlog = 127;
+static int   accept_timeout = 5;
+
+struct {
+	int			pta_shutdown;
+	socket_t		*pta_sock;
+	struct completion	pta_signal;
+} lnet_acceptor_state;
+
+int
+lnet_acceptor_port(void)
+{
+	return accept_port;
+}
+
+static inline int
+lnet_accept_magic(__u32 magic, __u32 constant)
+{
+	return (magic == constant ||
+		magic == __swab32(constant));
+}
+
+
+EXPORT_SYMBOL(lnet_acceptor_port);
+
+static char *accept = "secure";
+
+CFS_MODULE_PARM(accept, "s", charp, 0444,
+		"Accept connections (secure|all|none)");
+CFS_MODULE_PARM(accept_port, "i", int, 0444,
+		"Acceptor's port (same on all nodes)");
+CFS_MODULE_PARM(accept_backlog, "i", int, 0444,
+		"Acceptor's listen backlog");
+CFS_MODULE_PARM(accept_timeout, "i", int, 0644,
+		"Acceptor's timeout (seconds)");
+
+static char *accept_type = NULL;
+
+int
+lnet_acceptor_get_tunables(void)
+{
+	/* Userland acceptor uses 'accept_type' instead of 'accept', due to
+	 * conflict with 'accept(2)', but kernel acceptor still uses 'accept'
+	 * for compatibility. Hence the trick. */
+	accept_type = accept;
+	return 0;
+}
+
+int
+lnet_acceptor_timeout(void)
+{
+	return accept_timeout;
+}
+EXPORT_SYMBOL(lnet_acceptor_timeout);
+
+void
+lnet_connect_console_error (int rc, lnet_nid_t peer_nid,
+			   __u32 peer_ip, int peer_port)
+{
+	switch (rc) {
+	/* "normal" errors */
+	case -ECONNREFUSED:
+		CNETERR("Connection to %s at host %u.%u.%u.%u on port %d was "
+			"refused: check that Lustre is running on that node.\n",
+			libcfs_nid2str(peer_nid),
+			HIPQUAD(peer_ip), peer_port);
+		break;
+	case -EHOSTUNREACH:
+	case -ENETUNREACH:
+		CNETERR("Connection to %s at host %u.%u.%u.%u "
+			"was unreachable: the network or that node may "
+			"be down, or Lustre may be misconfigured.\n",
+			libcfs_nid2str(peer_nid), HIPQUAD(peer_ip));
+		break;
+	case -ETIMEDOUT:
+		CNETERR("Connection to %s at host %u.%u.%u.%u on "
+			"port %d took too long: that node may be hung "
+			"or experiencing high load.\n",
+			libcfs_nid2str(peer_nid),
+			HIPQUAD(peer_ip), peer_port);
+		break;
+	case -ECONNRESET:
+		LCONSOLE_ERROR_MSG(0x11b, "Connection to %s at host %u.%u.%u.%u"
+				   " on port %d was reset: "
+				   "is it running a compatible version of "
+				   "Lustre and is %s one of its NIDs?\n",
+				   libcfs_nid2str(peer_nid),
+				   HIPQUAD(peer_ip), peer_port,
+				   libcfs_nid2str(peer_nid));
+		break;
+	case -EPROTO:
+		LCONSOLE_ERROR_MSG(0x11c, "Protocol error connecting to %s at "
+				   "host %u.%u.%u.%u on port %d: is it running "
+				   "a compatible version of Lustre?\n",
+				   libcfs_nid2str(peer_nid),
+				   HIPQUAD(peer_ip), peer_port);
+		break;
+	case -EADDRINUSE:
+		LCONSOLE_ERROR_MSG(0x11d, "No privileged ports available to "
+				   "connect to %s at host %u.%u.%u.%u on port "
+				   "%d\n", libcfs_nid2str(peer_nid),
+				   HIPQUAD(peer_ip), peer_port);
+		break;
+	default:
+		LCONSOLE_ERROR_MSG(0x11e, "Unexpected error %d connecting to %s"
+				   " at host %u.%u.%u.%u on port %d\n", rc,
+				   libcfs_nid2str(peer_nid),
+				   HIPQUAD(peer_ip), peer_port);
+		break;
+	}
+}
+EXPORT_SYMBOL(lnet_connect_console_error);
+
+int
+lnet_connect(socket_t **sockp, lnet_nid_t peer_nid,
+	    __u32 local_ip, __u32 peer_ip, int peer_port)
+{
+	lnet_acceptor_connreq_t cr;
+	socket_t	   *sock;
+	int		     rc;
+	int		     port;
+	int		     fatal;
+
+	CLASSERT (sizeof(cr) <= 16);	    /* not too big to be on the stack */
+
+	for (port = LNET_ACCEPTOR_MAX_RESERVED_PORT;
+	     port >= LNET_ACCEPTOR_MIN_RESERVED_PORT;
+	     --port) {
+		/* Iterate through reserved ports. */
+
+		rc = libcfs_sock_connect(&sock, &fatal,
+					 local_ip, port,
+					 peer_ip, peer_port);
+		if (rc != 0) {
+			if (fatal)
+				goto failed;
+			continue;
+		}
+
+		CLASSERT (LNET_PROTO_ACCEPTOR_VERSION == 1);
+
+		cr.acr_magic   = LNET_PROTO_ACCEPTOR_MAGIC;
+		cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
+		cr.acr_nid     = peer_nid;
+
+		if (the_lnet.ln_testprotocompat != 0) {
+			/* single-shot proto check */
+			lnet_net_lock(LNET_LOCK_EX);
+			if ((the_lnet.ln_testprotocompat & 4) != 0) {
+				cr.acr_version++;
+				the_lnet.ln_testprotocompat &= ~4;
+			}
+			if ((the_lnet.ln_testprotocompat & 8) != 0) {
+				cr.acr_magic = LNET_PROTO_MAGIC;
+				the_lnet.ln_testprotocompat &= ~8;
+			}
+			lnet_net_unlock(LNET_LOCK_EX);
+		}
+
+		rc = libcfs_sock_write(sock, &cr, sizeof(cr),
+				       accept_timeout);
+		if (rc != 0)
+			goto failed_sock;
+
+		*sockp = sock;
+		return 0;
+	}
+
+	rc = -EADDRINUSE;
+	goto failed;
+
+ failed_sock:
+	libcfs_sock_release(sock);
+ failed:
+	lnet_connect_console_error(rc, peer_nid, peer_ip, peer_port);
+	return rc;
+}
+EXPORT_SYMBOL(lnet_connect);
+
+
+/* Below is the code common for both kernel and MT user-space */
+
+int
+lnet_accept(socket_t *sock, __u32 magic)
+{
+	lnet_acceptor_connreq_t cr;
+	__u32		   peer_ip;
+	int		     peer_port;
+	int		     rc;
+	int		     flip;
+	lnet_ni_t	      *ni;
+	char		   *str;
+
+	LASSERT (sizeof(cr) <= 16);	     /* not too big for the stack */
+
+	rc = libcfs_sock_getaddr(sock, 1, &peer_ip, &peer_port);
+	LASSERT (rc == 0);		      /* we succeeded before */
+
+	if (!lnet_accept_magic(magic, LNET_PROTO_ACCEPTOR_MAGIC)) {
+
+		if (lnet_accept_magic(magic, LNET_PROTO_MAGIC)) {
+			/* future version compatibility!
+			 * When LNET unifies protocols over all LNDs, the first
+			 * thing sent will be a version query.  I send back
+			 * LNET_PROTO_ACCEPTOR_MAGIC to tell her I'm "old" */
+
+			memset (&cr, 0, sizeof(cr));
+			cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC;
+			cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
+			rc = libcfs_sock_write(sock, &cr, sizeof(cr),
+					       accept_timeout);
+
+			if (rc != 0)
+				CERROR("Error sending magic+version in response"
+				       "to LNET magic from %u.%u.%u.%u: %d\n",
+				       HIPQUAD(peer_ip), rc);
+			return -EPROTO;
+		}
+
+		if (magic == le32_to_cpu(LNET_PROTO_TCP_MAGIC))
+			str = "'old' socknal/tcpnal";
+		else if (lnet_accept_magic(magic, LNET_PROTO_RA_MAGIC))
+			str = "'old' ranal";
+		else
+			str = "unrecognised";
+
+		LCONSOLE_ERROR_MSG(0x11f, "Refusing connection from %u.%u.%u.%u"
+				   " magic %08x: %s acceptor protocol\n",
+				   HIPQUAD(peer_ip), magic, str);
+		return -EPROTO;
+	}
+
+	flip = (magic != LNET_PROTO_ACCEPTOR_MAGIC);
+
+	rc = libcfs_sock_read(sock, &cr.acr_version,
+			      sizeof(cr.acr_version),
+			      accept_timeout);
+	if (rc != 0) {
+		CERROR("Error %d reading connection request version from "
+		       "%u.%u.%u.%u\n", rc, HIPQUAD(peer_ip));
+		return -EIO;
+	}
+
+	if (flip)
+		__swab32s(&cr.acr_version);
+
+	if (cr.acr_version != LNET_PROTO_ACCEPTOR_VERSION) {
+		/* future version compatibility!
+		 * An acceptor-specific protocol rev will first send a version
+		 * query.  I send back my current version to tell her I'm
+		 * "old". */
+		int peer_version = cr.acr_version;
+
+		memset (&cr, 0, sizeof(cr));
+		cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC;
+		cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION;
+
+		rc = libcfs_sock_write(sock, &cr, sizeof(cr),
+				       accept_timeout);
+
+		if (rc != 0)
+			CERROR("Error sending magic+version in response"
+			       "to version %d from %u.%u.%u.%u: %d\n",
+			       peer_version, HIPQUAD(peer_ip), rc);
+		return -EPROTO;
+	}
+
+	rc = libcfs_sock_read(sock, &cr.acr_nid,
+			      sizeof(cr) -
+			      offsetof(lnet_acceptor_connreq_t, acr_nid),
+			      accept_timeout);
+	if (rc != 0) {
+		CERROR("Error %d reading connection request from "
+		       "%u.%u.%u.%u\n", rc, HIPQUAD(peer_ip));
+		return -EIO;
+	}
+
+	if (flip)
+		__swab64s(&cr.acr_nid);
+
+	ni = lnet_net2ni(LNET_NIDNET(cr.acr_nid));
+	if (ni == NULL ||	       /* no matching net */
+	    ni->ni_nid != cr.acr_nid) { /* right NET, wrong NID! */
+		if (ni != NULL)
+			lnet_ni_decref(ni);
+		LCONSOLE_ERROR_MSG(0x120, "Refusing connection from %u.%u.%u.%u"
+				   " for %s: No matching NI\n",
+				   HIPQUAD(peer_ip), libcfs_nid2str(cr.acr_nid));
+		return -EPERM;
+	}
+
+	if (ni->ni_lnd->lnd_accept == NULL) {
+		/* This catches a request for the loopback LND */
+		lnet_ni_decref(ni);
+		LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %u.%u.%u.%u"
+				  " for %s: NI doesn not accept IP connections\n",
+				  HIPQUAD(peer_ip), libcfs_nid2str(cr.acr_nid));
+		return -EPERM;
+	}
+
+	CDEBUG(D_NET, "Accept %s from %u.%u.%u.%u\n",
+	       libcfs_nid2str(cr.acr_nid), HIPQUAD(peer_ip));
+
+	rc = ni->ni_lnd->lnd_accept(ni, sock);
+
+	lnet_ni_decref(ni);
+	return rc;
+}
+
+int
+lnet_acceptor(void *arg)
+{
+	socket_t  *newsock;
+	int	    rc;
+	__u32	  magic;
+	__u32	  peer_ip;
+	int	    peer_port;
+	int	    secure = (int)((long_ptr_t)arg);
+
+	LASSERT (lnet_acceptor_state.pta_sock == NULL);
+
+	cfs_block_allsigs();
+
+	rc = libcfs_sock_listen(&lnet_acceptor_state.pta_sock,
+				0, accept_port, accept_backlog);
+	if (rc != 0) {
+		if (rc == -EADDRINUSE)
+			LCONSOLE_ERROR_MSG(0x122, "Can't start acceptor on port"
+					   " %d: port already in use\n",
+					   accept_port);
+		else
+			LCONSOLE_ERROR_MSG(0x123, "Can't start acceptor on port "
+					   "%d: unexpected error %d\n",
+					   accept_port, rc);
+
+		lnet_acceptor_state.pta_sock = NULL;
+	} else {
+		LCONSOLE(0, "Accept %s, port %d\n", accept_type, accept_port);
+	}
+
+	/* set init status and unblock parent */
+	lnet_acceptor_state.pta_shutdown = rc;
+	complete(&lnet_acceptor_state.pta_signal);
+
+	if (rc != 0)
+		return rc;
+
+	while (!lnet_acceptor_state.pta_shutdown) {
+
+		rc = libcfs_sock_accept(&newsock, lnet_acceptor_state.pta_sock);
+		if (rc != 0) {
+			if (rc != -EAGAIN) {
+				CWARN("Accept error %d: pausing...\n", rc);
+				cfs_pause(cfs_time_seconds(1));
+			}
+			continue;
+		}
+
+		/* maybe we're waken up with libcfs_sock_abort_accept() */
+		if (lnet_acceptor_state.pta_shutdown) {
+			libcfs_sock_release(newsock);
+			break;
+		}
+
+		rc = libcfs_sock_getaddr(newsock, 1, &peer_ip, &peer_port);
+		if (rc != 0) {
+			CERROR("Can't determine new connection's address\n");
+			goto failed;
+		}
+
+		if (secure && peer_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) {
+			CERROR("Refusing connection from %u.%u.%u.%u: "
+			       "insecure port %d\n",
+			       HIPQUAD(peer_ip), peer_port);
+			goto failed;
+		}
+
+		rc = libcfs_sock_read(newsock, &magic, sizeof(magic),
+				      accept_timeout);
+		if (rc != 0) {
+			CERROR("Error %d reading connection request from "
+			       "%u.%u.%u.%u\n", rc, HIPQUAD(peer_ip));
+			goto failed;
+		}
+
+		rc = lnet_accept(newsock, magic);
+		if (rc != 0)
+			goto failed;
+
+		continue;
+
+	failed:
+		libcfs_sock_release(newsock);
+	}
+
+	libcfs_sock_release(lnet_acceptor_state.pta_sock);
+	lnet_acceptor_state.pta_sock = NULL;
+
+	CDEBUG(D_NET, "Acceptor stopping\n");
+
+	/* unblock lnet_acceptor_stop() */
+	complete(&lnet_acceptor_state.pta_signal);
+	return 0;
+}
+
+static inline int
+accept2secure(const char *acc, long *sec)
+{
+	if (!strcmp(acc, "secure")) {
+		*sec = 1;
+		return 1;
+	} else if (!strcmp(acc, "all")) {
+		*sec = 0;
+		return 1;
+	} else if (!strcmp(acc, "none")) {
+		return 0;
+	} else {
+		LCONSOLE_ERROR_MSG(0x124, "Can't parse 'accept=\"%s\"'\n",
+				   acc);
+		return -EINVAL;
+	}
+}
+
+int
+lnet_acceptor_start(void)
+{
+	int  rc;
+	long rc2;
+	long secure;
+
+	LASSERT (lnet_acceptor_state.pta_sock == NULL);
+
+	rc = lnet_acceptor_get_tunables();
+	if (rc != 0)
+		return rc;
+
+
+	init_completion(&lnet_acceptor_state.pta_signal);
+	rc = accept2secure(accept_type, &secure);
+	if (rc <= 0) {
+		fini_completion(&lnet_acceptor_state.pta_signal);
+		return rc;
+	}
+
+	if (lnet_count_acceptor_nis() == 0)  /* not required */
+		return 0;
+
+	rc2 = PTR_ERR(kthread_run(lnet_acceptor,
+				  (void *)(ulong_ptr_t)secure,
+				  "acceptor_%03ld", secure));
+	if (IS_ERR_VALUE(rc2)) {
+		CERROR("Can't start acceptor thread: %ld\n", rc2);
+		fini_completion(&lnet_acceptor_state.pta_signal);
+
+		return -ESRCH;
+	}
+
+	/* wait for acceptor to startup */
+	wait_for_completion(&lnet_acceptor_state.pta_signal);
+
+	if (!lnet_acceptor_state.pta_shutdown) {
+		/* started OK */
+		LASSERT(lnet_acceptor_state.pta_sock != NULL);
+		return 0;
+	}
+
+	LASSERT(lnet_acceptor_state.pta_sock == NULL);
+	fini_completion(&lnet_acceptor_state.pta_signal);
+
+	return -ENETDOWN;
+}
+
+void
+lnet_acceptor_stop(void)
+{
+	if (lnet_acceptor_state.pta_sock == NULL) /* not running */
+		return;
+
+	lnet_acceptor_state.pta_shutdown = 1;
+	libcfs_sock_abort_accept(lnet_acceptor_state.pta_sock);
+
+	/* block until acceptor signals exit */
+	wait_for_completion(&lnet_acceptor_state.pta_signal);
+
+	fini_completion(&lnet_acceptor_state.pta_signal);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/api-errno.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/api-errno.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/api-errno.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/api-errno.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/lnet/api-errno.c
+ *
+ * Instantiate the string table of errors
+ */
+
+/* If you change these, you must update the number table in portals/errno.h */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/api-ni.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/api-ni.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/api-ni.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/api-ni.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1941 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+#include <linux/lnet/lib-lnet.h>
+#include <linux/log2.h>
+
+#define D_LNI D_CONSOLE
+
+lnet_t      the_lnet;			   /* THE state of the network */
+EXPORT_SYMBOL(the_lnet);
+
+
+static char *ip2nets = "";
+CFS_MODULE_PARM(ip2nets, "s", charp, 0444,
+		"LNET network <- IP table");
+
+static char *networks = "";
+CFS_MODULE_PARM(networks, "s", charp, 0444,
+		"local networks");
+
+static char *routes = "";
+CFS_MODULE_PARM(routes, "s", charp, 0444,
+		"routes to non-local networks");
+
+static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
+CFS_MODULE_PARM(rnet_htable_size, "i", int, 0444,
+		"size of remote network hash table");
+
+char *
+lnet_get_routes(void)
+{
+	return routes;
+}
+
+char *
+lnet_get_networks(void)
+{
+	char   *nets;
+	int     rc;
+
+	if (*networks != 0 && *ip2nets != 0) {
+		LCONSOLE_ERROR_MSG(0x101, "Please specify EITHER 'networks' or "
+				   "'ip2nets' but not both at once\n");
+		return NULL;
+	}
+
+	if (*ip2nets != 0) {
+		rc = lnet_parse_ip2nets(&nets, ip2nets);
+		return (rc == 0) ? nets : NULL;
+	}
+
+	if (*networks != 0)
+		return networks;
+
+	return "tcp";
+}
+
+void
+lnet_init_locks(void)
+{
+	spin_lock_init(&the_lnet.ln_eq_wait_lock);
+	init_waitqueue_head(&the_lnet.ln_eq_waitq);
+	mutex_init(&the_lnet.ln_lnd_mutex);
+	mutex_init(&the_lnet.ln_api_mutex);
+}
+
+void
+lnet_fini_locks(void)
+{
+}
+
+
+static int
+lnet_create_remote_nets_table(void)
+{
+	int		i;
+	struct list_head	*hash;
+
+	LASSERT(the_lnet.ln_remote_nets_hash == NULL);
+	LASSERT(the_lnet.ln_remote_nets_hbits > 0);
+	LIBCFS_ALLOC(hash, LNET_REMOTE_NETS_HASH_SIZE * sizeof(*hash));
+	if (hash == NULL) {
+		CERROR("Failed to create remote nets hash table\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++)
+		INIT_LIST_HEAD(&hash[i]);
+	the_lnet.ln_remote_nets_hash = hash;
+	return 0;
+}
+
+static void
+lnet_destroy_remote_nets_table(void)
+{
+	int		i;
+	struct list_head	*hash;
+
+	if (the_lnet.ln_remote_nets_hash == NULL)
+		return;
+
+	for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++)
+		LASSERT(list_empty(&the_lnet.ln_remote_nets_hash[i]));
+
+	LIBCFS_FREE(the_lnet.ln_remote_nets_hash,
+		    LNET_REMOTE_NETS_HASH_SIZE * sizeof(*hash));
+	the_lnet.ln_remote_nets_hash = NULL;
+}
+
+static void
+lnet_destroy_locks(void)
+{
+	if (the_lnet.ln_res_lock != NULL) {
+		cfs_percpt_lock_free(the_lnet.ln_res_lock);
+		the_lnet.ln_res_lock = NULL;
+	}
+
+	if (the_lnet.ln_net_lock != NULL) {
+		cfs_percpt_lock_free(the_lnet.ln_net_lock);
+		the_lnet.ln_net_lock = NULL;
+	}
+
+	lnet_fini_locks();
+}
+
+static int
+lnet_create_locks(void)
+{
+	lnet_init_locks();
+
+	the_lnet.ln_res_lock = cfs_percpt_lock_alloc(lnet_cpt_table());
+	if (the_lnet.ln_res_lock == NULL)
+		goto failed;
+
+	the_lnet.ln_net_lock = cfs_percpt_lock_alloc(lnet_cpt_table());
+	if (the_lnet.ln_net_lock == NULL)
+		goto failed;
+
+	return 0;
+
+ failed:
+	lnet_destroy_locks();
+	return -ENOMEM;
+}
+
+void lnet_assert_wire_constants (void)
+{
+	/* Wire protocol assertions generated by 'wirecheck'
+	 * running on Linux robert.bartonsoftware.com 2.6.8-1.521
+	 * #1 Mon Aug 16 09:01:18 EDT 2004 i686 athlon i386 GNU/Linux
+	 * with gcc version 3.3.3 20040412 (Red Hat Linux 3.3.3-7) */
+
+	/* Constants... */
+	CLASSERT (LNET_PROTO_TCP_MAGIC == 0xeebc0ded);
+	CLASSERT (LNET_PROTO_TCP_VERSION_MAJOR == 1);
+	CLASSERT (LNET_PROTO_TCP_VERSION_MINOR == 0);
+	CLASSERT (LNET_MSG_ACK == 0);
+	CLASSERT (LNET_MSG_PUT == 1);
+	CLASSERT (LNET_MSG_GET == 2);
+	CLASSERT (LNET_MSG_REPLY == 3);
+	CLASSERT (LNET_MSG_HELLO == 4);
+
+	/* Checks for struct ptl_handle_wire_t */
+	CLASSERT ((int)sizeof(lnet_handle_wire_t) == 16);
+	CLASSERT ((int)offsetof(lnet_handle_wire_t, wh_interface_cookie) == 0);
+	CLASSERT ((int)sizeof(((lnet_handle_wire_t *)0)->wh_interface_cookie) == 8);
+	CLASSERT ((int)offsetof(lnet_handle_wire_t, wh_object_cookie) == 8);
+	CLASSERT ((int)sizeof(((lnet_handle_wire_t *)0)->wh_object_cookie) == 8);
+
+	/* Checks for struct lnet_magicversion_t */
+	CLASSERT ((int)sizeof(lnet_magicversion_t) == 8);
+	CLASSERT ((int)offsetof(lnet_magicversion_t, magic) == 0);
+	CLASSERT ((int)sizeof(((lnet_magicversion_t *)0)->magic) == 4);
+	CLASSERT ((int)offsetof(lnet_magicversion_t, version_major) == 4);
+	CLASSERT ((int)sizeof(((lnet_magicversion_t *)0)->version_major) == 2);
+	CLASSERT ((int)offsetof(lnet_magicversion_t, version_minor) == 6);
+	CLASSERT ((int)sizeof(((lnet_magicversion_t *)0)->version_minor) == 2);
+
+	/* Checks for struct lnet_hdr_t */
+	CLASSERT ((int)sizeof(lnet_hdr_t) == 72);
+	CLASSERT ((int)offsetof(lnet_hdr_t, dest_nid) == 0);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->dest_nid) == 8);
+	CLASSERT ((int)offsetof(lnet_hdr_t, src_nid) == 8);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->src_nid) == 8);
+	CLASSERT ((int)offsetof(lnet_hdr_t, dest_pid) == 16);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->dest_pid) == 4);
+	CLASSERT ((int)offsetof(lnet_hdr_t, src_pid) == 20);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->src_pid) == 4);
+	CLASSERT ((int)offsetof(lnet_hdr_t, type) == 24);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->type) == 4);
+	CLASSERT ((int)offsetof(lnet_hdr_t, payload_length) == 28);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->payload_length) == 4);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg) == 32);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg) == 40);
+
+	/* Ack */
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.ack.dst_wmd) == 32);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.ack.dst_wmd) == 16);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.ack.match_bits) == 48);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.ack.match_bits) == 8);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.ack.mlength) == 56);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.ack.mlength) == 4);
+
+	/* Put */
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.ack_wmd) == 32);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.ack_wmd) == 16);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.match_bits) == 48);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.match_bits) == 8);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.hdr_data) == 56);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.hdr_data) == 8);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.ptl_index) == 64);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.ptl_index) == 4);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.put.offset) == 68);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.put.offset) == 4);
+
+	/* Get */
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.return_wmd) == 32);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.return_wmd) == 16);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.match_bits) == 48);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.match_bits) == 8);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.ptl_index) == 56);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.ptl_index) == 4);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.src_offset) == 60);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.src_offset) == 4);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.get.sink_length) == 64);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.get.sink_length) == 4);
+
+	/* Reply */
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.reply.dst_wmd) == 32);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.reply.dst_wmd) == 16);
+
+	/* Hello */
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.hello.incarnation) == 32);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.hello.incarnation) == 8);
+	CLASSERT ((int)offsetof(lnet_hdr_t, msg.hello.type) == 40);
+	CLASSERT ((int)sizeof(((lnet_hdr_t *)0)->msg.hello.type) == 4);
+}
+
+lnd_t *
+lnet_find_lnd_by_type (int type)
+{
+	lnd_t	      *lnd;
+	struct list_head	 *tmp;
+
+	/* holding lnd mutex */
+	list_for_each (tmp, &the_lnet.ln_lnds) {
+		lnd = list_entry(tmp, lnd_t, lnd_list);
+
+		if ((int)lnd->lnd_type == type)
+			return lnd;
+	}
+
+	return NULL;
+}
+
+void
+lnet_register_lnd (lnd_t *lnd)
+{
+	LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (libcfs_isknown_lnd(lnd->lnd_type));
+	LASSERT (lnet_find_lnd_by_type(lnd->lnd_type) == NULL);
+
+	list_add_tail (&lnd->lnd_list, &the_lnet.ln_lnds);
+	lnd->lnd_refcount = 0;
+
+	CDEBUG(D_NET, "%s LND registered\n", libcfs_lnd2str(lnd->lnd_type));
+
+	LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
+}
+EXPORT_SYMBOL(lnet_register_lnd);
+
+void
+lnet_unregister_lnd (lnd_t *lnd)
+{
+	LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (lnet_find_lnd_by_type(lnd->lnd_type) == lnd);
+	LASSERT (lnd->lnd_refcount == 0);
+
+	list_del (&lnd->lnd_list);
+	CDEBUG(D_NET, "%s LND unregistered\n", libcfs_lnd2str(lnd->lnd_type));
+
+	LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
+}
+EXPORT_SYMBOL(lnet_unregister_lnd);
+
+void
+lnet_counters_get(lnet_counters_t *counters)
+{
+	lnet_counters_t *ctr;
+	int		i;
+
+	memset(counters, 0, sizeof(*counters));
+
+	lnet_net_lock(LNET_LOCK_EX);
+
+	cfs_percpt_for_each(ctr, i, the_lnet.ln_counters) {
+		counters->msgs_max     += ctr->msgs_max;
+		counters->msgs_alloc   += ctr->msgs_alloc;
+		counters->errors       += ctr->errors;
+		counters->send_count   += ctr->send_count;
+		counters->recv_count   += ctr->recv_count;
+		counters->route_count  += ctr->route_count;
+		counters->drop_length  += ctr->drop_length;
+		counters->send_length  += ctr->send_length;
+		counters->recv_length  += ctr->recv_length;
+		counters->route_length += ctr->route_length;
+		counters->drop_length  += ctr->drop_length;
+
+	}
+	lnet_net_unlock(LNET_LOCK_EX);
+}
+EXPORT_SYMBOL(lnet_counters_get);
+
+void
+lnet_counters_reset(void)
+{
+	lnet_counters_t *counters;
+	int		i;
+
+	lnet_net_lock(LNET_LOCK_EX);
+
+	cfs_percpt_for_each(counters, i, the_lnet.ln_counters)
+		memset(counters, 0, sizeof(lnet_counters_t));
+
+	lnet_net_unlock(LNET_LOCK_EX);
+}
+EXPORT_SYMBOL(lnet_counters_reset);
+
+#ifdef LNET_USE_LIB_FREELIST
+
+int
+lnet_freelist_init (lnet_freelist_t *fl, int n, int size)
+{
+	char *space;
+
+	LASSERT (n > 0);
+
+	size += offsetof (lnet_freeobj_t, fo_contents);
+
+	LIBCFS_ALLOC(space, n * size);
+	if (space == NULL)
+		return (-ENOMEM);
+
+	INIT_LIST_HEAD (&fl->fl_list);
+	fl->fl_objs = space;
+	fl->fl_nobjs = n;
+	fl->fl_objsize = size;
+
+	do
+	{
+		memset (space, 0, size);
+		list_add ((struct list_head *)space, &fl->fl_list);
+		space += size;
+	} while (--n != 0);
+
+	return (0);
+}
+
+void
+lnet_freelist_fini (lnet_freelist_t *fl)
+{
+	struct list_head       *el;
+	int	       count;
+
+	if (fl->fl_nobjs == 0)
+		return;
+
+	count = 0;
+	for (el = fl->fl_list.next; el != &fl->fl_list; el = el->next)
+		count++;
+
+	LASSERT (count == fl->fl_nobjs);
+
+	LIBCFS_FREE(fl->fl_objs, fl->fl_nobjs * fl->fl_objsize);
+	memset (fl, 0, sizeof (*fl));
+}
+
+#endif /* LNET_USE_LIB_FREELIST */
+
+__u64
+lnet_create_interface_cookie (void)
+{
+	/* NB the interface cookie in wire handles guards against delayed
+	 * replies and ACKs appearing valid after reboot. Initialisation time,
+	 * even if it's only implemented to millisecond resolution is probably
+	 * easily good enough. */
+	struct timeval tv;
+	__u64	  cookie;
+	do_gettimeofday(&tv);
+	cookie = tv.tv_sec;
+	cookie *= 1000000;
+	cookie += tv.tv_usec;
+	return cookie;
+}
+
+static char *
+lnet_res_type2str(int type)
+{
+	switch (type) {
+	default:
+		LBUG();
+	case LNET_COOKIE_TYPE_MD:
+		return "MD";
+	case LNET_COOKIE_TYPE_ME:
+		return "ME";
+	case LNET_COOKIE_TYPE_EQ:
+		return "EQ";
+	}
+}
+
+void
+lnet_res_container_cleanup(struct lnet_res_container *rec)
+{
+	int	count = 0;
+
+	if (rec->rec_type == 0) /* not set yet, it's uninitialized */
+		return;
+
+	while (!list_empty(&rec->rec_active)) {
+		struct list_head *e = rec->rec_active.next;
+
+		list_del_init(e);
+		if (rec->rec_type == LNET_COOKIE_TYPE_EQ) {
+			lnet_eq_free(list_entry(e, lnet_eq_t, eq_list));
+
+		} else if (rec->rec_type == LNET_COOKIE_TYPE_MD) {
+			lnet_md_free(list_entry(e, lnet_libmd_t, md_list));
+
+		} else { /* NB: Active MEs should be attached on portals */
+			LBUG();
+		}
+		count++;
+	}
+
+	if (count > 0) {
+		/* Found alive MD/ME/EQ, user really should unlink/free
+		 * all of them before finalize LNet, but if someone didn't,
+		 * we have to recycle garbage for him */
+		CERROR("%d active elements on exit of %s container\n",
+		       count, lnet_res_type2str(rec->rec_type));
+	}
+
+#ifdef LNET_USE_LIB_FREELIST
+	lnet_freelist_fini(&rec->rec_freelist);
+#endif
+	if (rec->rec_lh_hash != NULL) {
+		LIBCFS_FREE(rec->rec_lh_hash,
+			    LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0]));
+		rec->rec_lh_hash = NULL;
+	}
+
+	rec->rec_type = 0; /* mark it as finalized */
+}
+
+int
+lnet_res_container_setup(struct lnet_res_container *rec,
+			 int cpt, int type, int objnum, int objsz)
+{
+	int	rc = 0;
+	int	i;
+
+	LASSERT(rec->rec_type == 0);
+
+	rec->rec_type = type;
+	INIT_LIST_HEAD(&rec->rec_active);
+
+#ifdef LNET_USE_LIB_FREELIST
+	memset(&rec->rec_freelist, 0, sizeof(rec->rec_freelist));
+	rc = lnet_freelist_init(&rec->rec_freelist, objnum, objsz);
+	if (rc != 0)
+		goto out;
+#endif
+	rec->rec_lh_cookie = (cpt << LNET_COOKIE_TYPE_BITS) | type;
+
+	/* Arbitrary choice of hash table size */
+	LIBCFS_CPT_ALLOC(rec->rec_lh_hash, lnet_cpt_table(), cpt,
+			 LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0]));
+	if (rec->rec_lh_hash == NULL) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < LNET_LH_HASH_SIZE; i++)
+		INIT_LIST_HEAD(&rec->rec_lh_hash[i]);
+
+	return 0;
+
+out:
+	CERROR("Failed to setup %s resource container\n",
+	       lnet_res_type2str(type));
+	lnet_res_container_cleanup(rec);
+	return rc;
+}
+
+static void
+lnet_res_containers_destroy(struct lnet_res_container **recs)
+{
+	struct lnet_res_container	*rec;
+	int				i;
+
+	cfs_percpt_for_each(rec, i, recs)
+		lnet_res_container_cleanup(rec);
+
+	cfs_percpt_free(recs);
+}
+
+static struct lnet_res_container **
+lnet_res_containers_create(int type, int objnum, int objsz)
+{
+	struct lnet_res_container	**recs;
+	struct lnet_res_container	*rec;
+	int				rc;
+	int				i;
+
+	recs = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*rec));
+	if (recs == NULL) {
+		CERROR("Failed to allocate %s resource containers\n",
+		       lnet_res_type2str(type));
+		return NULL;
+	}
+
+	cfs_percpt_for_each(rec, i, recs) {
+		rc = lnet_res_container_setup(rec, i, type, objnum, objsz);
+		if (rc != 0) {
+			lnet_res_containers_destroy(recs);
+			return NULL;
+		}
+	}
+
+	return recs;
+}
+
+lnet_libhandle_t *
+lnet_res_lh_lookup(struct lnet_res_container *rec, __u64 cookie)
+{
+	/* ALWAYS called with lnet_res_lock held */
+	struct list_head		*head;
+	lnet_libhandle_t	*lh;
+	unsigned int		hash;
+
+	if ((cookie & LNET_COOKIE_MASK) != rec->rec_type)
+		return NULL;
+
+	hash = cookie >> (LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS);
+	head = &rec->rec_lh_hash[hash & LNET_LH_HASH_MASK];
+
+	list_for_each_entry(lh, head, lh_hash_chain) {
+		if (lh->lh_cookie == cookie)
+			return lh;
+	}
+
+	return NULL;
+}
+
+void
+lnet_res_lh_initialize(struct lnet_res_container *rec, lnet_libhandle_t *lh)
+{
+	/* ALWAYS called with lnet_res_lock held */
+	unsigned int	ibits = LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS;
+	unsigned int	hash;
+
+	lh->lh_cookie = rec->rec_lh_cookie;
+	rec->rec_lh_cookie += 1 << ibits;
+
+	hash = (lh->lh_cookie >> ibits) & LNET_LH_HASH_MASK;
+
+	list_add(&lh->lh_hash_chain, &rec->rec_lh_hash[hash]);
+}
+
+
+int lnet_unprepare(void);
+
+int
+lnet_prepare(lnet_pid_t requested_pid)
+{
+	/* Prepare to bring up the network */
+	struct lnet_res_container **recs;
+	int			  rc = 0;
+
+	LASSERT (the_lnet.ln_refcount == 0);
+
+	the_lnet.ln_routing = 0;
+
+	LASSERT ((requested_pid & LNET_PID_USERFLAG) == 0);
+	the_lnet.ln_pid = requested_pid;
+
+	INIT_LIST_HEAD(&the_lnet.ln_test_peers);
+	INIT_LIST_HEAD(&the_lnet.ln_nis);
+	INIT_LIST_HEAD(&the_lnet.ln_nis_cpt);
+	INIT_LIST_HEAD(&the_lnet.ln_nis_zombie);
+	INIT_LIST_HEAD(&the_lnet.ln_routers);
+
+	rc = lnet_create_remote_nets_table();
+	if (rc != 0)
+		goto failed;
+
+	the_lnet.ln_interface_cookie = lnet_create_interface_cookie();
+
+	the_lnet.ln_counters = cfs_percpt_alloc(lnet_cpt_table(),
+						sizeof(lnet_counters_t));
+	if (the_lnet.ln_counters == NULL) {
+		CERROR("Failed to allocate counters for LNet\n");
+		rc = -ENOMEM;
+		goto failed;
+	}
+
+	rc = lnet_peer_tables_create();
+	if (rc != 0)
+		goto failed;
+
+	rc = lnet_msg_containers_create();
+	if (rc != 0)
+		goto failed;
+
+	rc = lnet_res_container_setup(&the_lnet.ln_eq_container, 0,
+				      LNET_COOKIE_TYPE_EQ, LNET_FL_MAX_EQS,
+				      sizeof(lnet_eq_t));
+	if (rc != 0)
+		goto failed;
+
+	recs = lnet_res_containers_create(LNET_COOKIE_TYPE_ME, LNET_FL_MAX_MES,
+					  sizeof(lnet_me_t));
+	if (recs == NULL)
+		goto failed;
+
+	the_lnet.ln_me_containers = recs;
+
+	recs = lnet_res_containers_create(LNET_COOKIE_TYPE_MD, LNET_FL_MAX_MDS,
+					  sizeof(lnet_libmd_t));
+	if (recs == NULL)
+		goto failed;
+
+	the_lnet.ln_md_containers = recs;
+
+	rc = lnet_portals_create();
+	if (rc != 0) {
+		CERROR("Failed to create portals for LNet: %d\n", rc);
+		goto failed;
+	}
+
+	return 0;
+
+ failed:
+	lnet_unprepare();
+	return rc;
+}
+
+int
+lnet_unprepare (void)
+{
+	/* NB no LNET_LOCK since this is the last reference.  All LND instances
+	 * have shut down already, so it is safe to unlink and free all
+	 * descriptors, even those that appear committed to a network op (eg MD
+	 * with non-zero pending count) */
+
+	lnet_fail_nid(LNET_NID_ANY, 0);
+
+	LASSERT(the_lnet.ln_refcount == 0);
+	LASSERT(list_empty(&the_lnet.ln_test_peers));
+	LASSERT(list_empty(&the_lnet.ln_nis));
+	LASSERT(list_empty(&the_lnet.ln_nis_cpt));
+	LASSERT(list_empty(&the_lnet.ln_nis_zombie));
+
+	lnet_portals_destroy();
+
+	if (the_lnet.ln_md_containers != NULL) {
+		lnet_res_containers_destroy(the_lnet.ln_md_containers);
+		the_lnet.ln_md_containers = NULL;
+	}
+
+	if (the_lnet.ln_me_containers != NULL) {
+		lnet_res_containers_destroy(the_lnet.ln_me_containers);
+		the_lnet.ln_me_containers = NULL;
+	}
+
+	lnet_res_container_cleanup(&the_lnet.ln_eq_container);
+
+	lnet_msg_containers_destroy();
+	lnet_peer_tables_destroy();
+	lnet_rtrpools_free();
+
+	if (the_lnet.ln_counters != NULL) {
+		cfs_percpt_free(the_lnet.ln_counters);
+		the_lnet.ln_counters = NULL;
+	}
+	lnet_destroy_remote_nets_table();
+
+	return 0;
+}
+
+lnet_ni_t  *
+lnet_net2ni_locked(__u32 net, int cpt)
+{
+	struct list_head	*tmp;
+	lnet_ni_t	*ni;
+
+	LASSERT(cpt != LNET_LOCK_EX);
+
+	list_for_each(tmp, &the_lnet.ln_nis) {
+		ni = list_entry(tmp, lnet_ni_t, ni_list);
+
+		if (LNET_NIDNET(ni->ni_nid) == net) {
+			lnet_ni_addref_locked(ni, cpt);
+			return ni;
+		}
+	}
+
+	return NULL;
+}
+
+lnet_ni_t *
+lnet_net2ni(__u32 net)
+{
+	lnet_ni_t *ni;
+
+	lnet_net_lock(0);
+	ni = lnet_net2ni_locked(net, 0);
+	lnet_net_unlock(0);
+
+	return ni;
+}
+EXPORT_SYMBOL(lnet_net2ni);
+
+static unsigned int
+lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number)
+{
+	__u64		key = nid;
+	unsigned int	val;
+
+	LASSERT(number >= 1 && number <= LNET_CPT_NUMBER);
+
+	if (number == 1)
+		return 0;
+
+	val = cfs_hash_long(key, LNET_CPT_BITS);
+	/* NB: LNET_CP_NUMBER doesn't have to be PO2 */
+	if (val < number)
+		return val;
+
+	return (unsigned int)(key + val + (val >> 1)) % number;
+}
+
+int
+lnet_cpt_of_nid_locked(lnet_nid_t nid)
+{
+	struct lnet_ni *ni;
+
+	/* must called with hold of lnet_net_lock */
+	if (LNET_CPT_NUMBER == 1)
+		return 0; /* the only one */
+
+	/* take lnet_net_lock(any) would be OK */
+	if (!list_empty(&the_lnet.ln_nis_cpt)) {
+		list_for_each_entry(ni, &the_lnet.ln_nis_cpt, ni_cptlist) {
+			if (LNET_NIDNET(ni->ni_nid) != LNET_NIDNET(nid))
+				continue;
+
+			LASSERT(ni->ni_cpts != NULL);
+			return ni->ni_cpts[lnet_nid_cpt_hash
+					   (nid, ni->ni_ncpts)];
+		}
+	}
+
+	return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER);
+}
+
+int
+lnet_cpt_of_nid(lnet_nid_t nid)
+{
+	int	cpt;
+	int	cpt2;
+
+	if (LNET_CPT_NUMBER == 1)
+		return 0; /* the only one */
+
+	if (list_empty(&the_lnet.ln_nis_cpt))
+		return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER);
+
+	cpt = lnet_net_lock_current();
+	cpt2 = lnet_cpt_of_nid_locked(nid);
+	lnet_net_unlock(cpt);
+
+	return cpt2;
+}
+EXPORT_SYMBOL(lnet_cpt_of_nid);
+
+int
+lnet_islocalnet(__u32 net)
+{
+	struct lnet_ni	*ni;
+	int		cpt;
+
+	cpt = lnet_net_lock_current();
+
+	ni = lnet_net2ni_locked(net, cpt);
+	if (ni != NULL)
+		lnet_ni_decref_locked(ni, cpt);
+
+	lnet_net_unlock(cpt);
+
+	return ni != NULL;
+}
+
+lnet_ni_t  *
+lnet_nid2ni_locked(lnet_nid_t nid, int cpt)
+{
+	struct lnet_ni	*ni;
+	struct list_head	*tmp;
+
+	LASSERT(cpt != LNET_LOCK_EX);
+
+	list_for_each(tmp, &the_lnet.ln_nis) {
+		ni = list_entry(tmp, lnet_ni_t, ni_list);
+
+		if (ni->ni_nid == nid) {
+			lnet_ni_addref_locked(ni, cpt);
+			return ni;
+		}
+	}
+
+	return NULL;
+}
+
+int
+lnet_islocalnid(lnet_nid_t nid)
+{
+	struct lnet_ni	*ni;
+	int		cpt;
+
+	cpt = lnet_net_lock_current();
+	ni = lnet_nid2ni_locked(nid, cpt);
+	if (ni != NULL)
+		lnet_ni_decref_locked(ni, cpt);
+	lnet_net_unlock(cpt);
+
+	return ni != NULL;
+}
+
+int
+lnet_count_acceptor_nis (void)
+{
+	/* Return the # of NIs that need the acceptor. */
+	int		count = 0;
+	struct list_head	*tmp;
+	struct lnet_ni	*ni;
+	int		cpt;
+
+	cpt = lnet_net_lock_current();
+	list_for_each(tmp, &the_lnet.ln_nis) {
+		ni = list_entry(tmp, lnet_ni_t, ni_list);
+
+		if (ni->ni_lnd->lnd_accept != NULL)
+			count++;
+	}
+
+	lnet_net_unlock(cpt);
+
+	return count;
+}
+
+static int
+lnet_ni_tq_credits(lnet_ni_t *ni)
+{
+	int	credits;
+
+	LASSERT(ni->ni_ncpts >= 1);
+
+	if (ni->ni_ncpts == 1)
+		return ni->ni_maxtxcredits;
+
+	credits = ni->ni_maxtxcredits / ni->ni_ncpts;
+	credits = max(credits, 8 * ni->ni_peertxcredits);
+	credits = min(credits, ni->ni_maxtxcredits);
+
+	return credits;
+}
+
+void
+lnet_shutdown_lndnis (void)
+{
+	int		i;
+	int		islo;
+	lnet_ni_t	 *ni;
+
+	/* NB called holding the global mutex */
+
+	/* All quiet on the API front */
+	LASSERT(!the_lnet.ln_shutdown);
+	LASSERT(the_lnet.ln_refcount == 0);
+	LASSERT(list_empty(&the_lnet.ln_nis_zombie));
+
+	lnet_net_lock(LNET_LOCK_EX);
+	the_lnet.ln_shutdown = 1;	/* flag shutdown */
+
+	/* Unlink NIs from the global table */
+	while (!list_empty(&the_lnet.ln_nis)) {
+		ni = list_entry(the_lnet.ln_nis.next,
+				    lnet_ni_t, ni_list);
+		/* move it to zombie list and nobody can find it anymore */
+		list_move(&ni->ni_list, &the_lnet.ln_nis_zombie);
+		lnet_ni_decref_locked(ni, 0);	/* drop ln_nis' ref */
+
+		if (!list_empty(&ni->ni_cptlist)) {
+			list_del_init(&ni->ni_cptlist);
+			lnet_ni_decref_locked(ni, 0);
+		}
+	}
+
+	/* Drop the cached eqwait NI. */
+	if (the_lnet.ln_eq_waitni != NULL) {
+		lnet_ni_decref_locked(the_lnet.ln_eq_waitni, 0);
+		the_lnet.ln_eq_waitni = NULL;
+	}
+
+	/* Drop the cached loopback NI. */
+	if (the_lnet.ln_loni != NULL) {
+		lnet_ni_decref_locked(the_lnet.ln_loni, 0);
+		the_lnet.ln_loni = NULL;
+	}
+
+	lnet_net_unlock(LNET_LOCK_EX);
+
+	/* Clear lazy portals and drop delayed messages which hold refs
+	 * on their lnet_msg_t::msg_rxpeer */
+	for (i = 0; i < the_lnet.ln_nportals; i++)
+		LNetClearLazyPortal(i);
+
+	/* Clear the peer table and wait for all peers to go (they hold refs on
+	 * their NIs) */
+	lnet_peer_tables_cleanup();
+
+	lnet_net_lock(LNET_LOCK_EX);
+	/* Now wait for the NI's I just nuked to show up on ln_zombie_nis
+	 * and shut them down in guaranteed thread context */
+	i = 2;
+	while (!list_empty(&the_lnet.ln_nis_zombie)) {
+		int	*ref;
+		int	j;
+
+		ni = list_entry(the_lnet.ln_nis_zombie.next,
+				    lnet_ni_t, ni_list);
+		list_del_init(&ni->ni_list);
+		cfs_percpt_for_each(ref, j, ni->ni_refs) {
+			if (*ref == 0)
+				continue;
+			/* still busy, add it back to zombie list */
+			list_add(&ni->ni_list, &the_lnet.ln_nis_zombie);
+			break;
+		}
+
+		while (!list_empty(&ni->ni_list)) {
+			lnet_net_unlock(LNET_LOCK_EX);
+			++i;
+			if ((i & (-i)) == i) {
+				CDEBUG(D_WARNING,
+				       "Waiting for zombie LNI %s\n",
+				       libcfs_nid2str(ni->ni_nid));
+			}
+			cfs_pause(cfs_time_seconds(1));
+			lnet_net_lock(LNET_LOCK_EX);
+			continue;
+		}
+
+		ni->ni_lnd->lnd_refcount--;
+		lnet_net_unlock(LNET_LOCK_EX);
+
+		islo = ni->ni_lnd->lnd_type == LOLND;
+
+		LASSERT (!in_interrupt ());
+		(ni->ni_lnd->lnd_shutdown)(ni);
+
+		/* can't deref lnd anymore now; it might have unregistered
+		 * itself...  */
+
+		if (!islo)
+			CDEBUG(D_LNI, "Removed LNI %s\n",
+			       libcfs_nid2str(ni->ni_nid));
+
+		lnet_ni_free(ni);
+		lnet_net_lock(LNET_LOCK_EX);
+	}
+
+	the_lnet.ln_shutdown = 0;
+	lnet_net_unlock(LNET_LOCK_EX);
+
+	if (the_lnet.ln_network_tokens != NULL) {
+		LIBCFS_FREE(the_lnet.ln_network_tokens,
+			    the_lnet.ln_network_tokens_nob);
+		the_lnet.ln_network_tokens = NULL;
+	}
+}
+
+int
+lnet_startup_lndnis (void)
+{
+	lnd_t			*lnd;
+	struct lnet_ni		*ni;
+	struct lnet_tx_queue	*tq;
+	struct list_head		nilist;
+	int			i;
+	int		rc = 0;
+	int		lnd_type;
+	int		nicount = 0;
+	char	      *nets = lnet_get_networks();
+
+	INIT_LIST_HEAD(&nilist);
+
+	if (nets == NULL)
+		goto failed;
+
+	rc = lnet_parse_networks(&nilist, nets);
+	if (rc != 0)
+		goto failed;
+
+	while (!list_empty(&nilist)) {
+		ni = list_entry(nilist.next, lnet_ni_t, ni_list);
+		lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid));
+
+		LASSERT (libcfs_isknown_lnd(lnd_type));
+
+		if (lnd_type == CIBLND    ||
+		    lnd_type == OPENIBLND ||
+		    lnd_type == IIBLND    ||
+		    lnd_type == VIBLND) {
+			CERROR("LND %s obsoleted\n",
+			       libcfs_lnd2str(lnd_type));
+			goto failed;
+		}
+
+		LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
+		lnd = lnet_find_lnd_by_type(lnd_type);
+
+		if (lnd == NULL) {
+			LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
+			rc = request_module("%s",
+						libcfs_lnd2modname(lnd_type));
+			LNET_MUTEX_LOCK(&the_lnet.ln_lnd_mutex);
+
+			lnd = lnet_find_lnd_by_type(lnd_type);
+			if (lnd == NULL) {
+				LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
+				CERROR("Can't load LND %s, module %s, rc=%d\n",
+				       libcfs_lnd2str(lnd_type),
+				       libcfs_lnd2modname(lnd_type), rc);
+				goto failed;
+			}
+		}
+
+		lnet_net_lock(LNET_LOCK_EX);
+		lnd->lnd_refcount++;
+		lnet_net_unlock(LNET_LOCK_EX);
+
+		ni->ni_lnd = lnd;
+
+		rc = (lnd->lnd_startup)(ni);
+
+		LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
+
+		if (rc != 0) {
+			LCONSOLE_ERROR_MSG(0x105, "Error %d starting up LNI %s"
+					   "\n",
+					   rc, libcfs_lnd2str(lnd->lnd_type));
+			lnet_net_lock(LNET_LOCK_EX);
+			lnd->lnd_refcount--;
+			lnet_net_unlock(LNET_LOCK_EX);
+			goto failed;
+		}
+
+		LASSERT (ni->ni_peertimeout <= 0 || lnd->lnd_query != NULL);
+
+		list_del(&ni->ni_list);
+
+		lnet_net_lock(LNET_LOCK_EX);
+		/* refcount for ln_nis */
+		lnet_ni_addref_locked(ni, 0);
+		list_add_tail(&ni->ni_list, &the_lnet.ln_nis);
+		if (ni->ni_cpts != NULL) {
+			list_add_tail(&ni->ni_cptlist,
+					  &the_lnet.ln_nis_cpt);
+			lnet_ni_addref_locked(ni, 0);
+		}
+
+		lnet_net_unlock(LNET_LOCK_EX);
+
+		if (lnd->lnd_type == LOLND) {
+			lnet_ni_addref(ni);
+			LASSERT (the_lnet.ln_loni == NULL);
+			the_lnet.ln_loni = ni;
+			continue;
+		}
+
+		if (ni->ni_peertxcredits == 0 ||
+		    ni->ni_maxtxcredits == 0) {
+			LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n",
+					   libcfs_lnd2str(lnd->lnd_type),
+					   ni->ni_peertxcredits == 0 ?
+					   "" : "per-peer ");
+			goto failed;
+		}
+
+		cfs_percpt_for_each(tq, i, ni->ni_tx_queues) {
+			tq->tq_credits_min =
+			tq->tq_credits_max =
+			tq->tq_credits = lnet_ni_tq_credits(ni);
+		}
+
+		CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n",
+		       libcfs_nid2str(ni->ni_nid), ni->ni_peertxcredits,
+		       lnet_ni_tq_credits(ni) * LNET_CPT_NUMBER,
+		       ni->ni_peerrtrcredits, ni->ni_peertimeout);
+
+		nicount++;
+	}
+
+	if (the_lnet.ln_eq_waitni != NULL && nicount > 1) {
+		lnd_type = the_lnet.ln_eq_waitni->ni_lnd->lnd_type;
+		LCONSOLE_ERROR_MSG(0x109, "LND %s can only run single-network"
+				   "\n",
+				   libcfs_lnd2str(lnd_type));
+		goto failed;
+	}
+
+	return 0;
+
+ failed:
+	lnet_shutdown_lndnis();
+
+	while (!list_empty(&nilist)) {
+		ni = list_entry(nilist.next, lnet_ni_t, ni_list);
+		list_del(&ni->ni_list);
+		lnet_ni_free(ni);
+	}
+
+	return -ENETDOWN;
+}
+
+/**
+ * Initialize LNet library.
+ *
+ * Only userspace program needs to call this function - it's automatically
+ * called in the kernel at module loading time. Caller has to call LNetFini()
+ * after a call to LNetInit(), if and only if the latter returned 0. It must
+ * be called exactly once.
+ *
+ * \return 0 on success, and -ve on failures.
+ */
+int
+LNetInit(void)
+{
+	int	rc;
+
+	lnet_assert_wire_constants();
+	LASSERT(!the_lnet.ln_init);
+
+	memset(&the_lnet, 0, sizeof(the_lnet));
+
+	/* refer to global cfs_cpt_table for now */
+	the_lnet.ln_cpt_table	= cfs_cpt_table;
+	the_lnet.ln_cpt_number	= cfs_cpt_number(cfs_cpt_table);
+
+	LASSERT(the_lnet.ln_cpt_number > 0);
+	if (the_lnet.ln_cpt_number > LNET_CPT_MAX) {
+		/* we are under risk of consuming all lh_cookie */
+		CERROR("Can't have %d CPTs for LNet (max allowed is %d), "
+		       "please change setting of CPT-table and retry\n",
+		       the_lnet.ln_cpt_number, LNET_CPT_MAX);
+		return -1;
+	}
+
+	while ((1 << the_lnet.ln_cpt_bits) < the_lnet.ln_cpt_number)
+		the_lnet.ln_cpt_bits++;
+
+	rc = lnet_create_locks();
+	if (rc != 0) {
+		CERROR("Can't create LNet global locks: %d\n", rc);
+		return -1;
+	}
+
+	the_lnet.ln_refcount = 0;
+	the_lnet.ln_init = 1;
+	LNetInvalidateHandle(&the_lnet.ln_rc_eqh);
+	INIT_LIST_HEAD(&the_lnet.ln_lnds);
+	INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie);
+	INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow);
+
+	/* The hash table size is the number of bits it takes to express the set
+	 * ln_num_routes, minus 1 (better to under estimate than over so we
+	 * don't waste memory). */
+	if (rnet_htable_size <= 0)
+		rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
+	else if (rnet_htable_size > LNET_REMOTE_NETS_HASH_MAX)
+		rnet_htable_size = LNET_REMOTE_NETS_HASH_MAX;
+	the_lnet.ln_remote_nets_hbits = max_t(int, 1,
+					   order_base_2(rnet_htable_size) - 1);
+
+	/* All LNDs apart from the LOLND are in separate modules.  They
+	 * register themselves when their module loads, and unregister
+	 * themselves when their module is unloaded. */
+	lnet_register_lnd(&the_lolnd);
+	return 0;
+}
+EXPORT_SYMBOL(LNetInit);
+
+/**
+ * Finalize LNet library.
+ *
+ * Only userspace program needs to call this function. It can be called
+ * at most once.
+ *
+ * \pre LNetInit() called with success.
+ * \pre All LNet users called LNetNIFini() for matching LNetNIInit() calls.
+ */
+void
+LNetFini(void)
+{
+	LASSERT(the_lnet.ln_init);
+	LASSERT(the_lnet.ln_refcount == 0);
+
+	while (!list_empty(&the_lnet.ln_lnds))
+		lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next,
+						   lnd_t, lnd_list));
+	lnet_destroy_locks();
+
+	the_lnet.ln_init = 0;
+}
+EXPORT_SYMBOL(LNetFini);
+
+/**
+ * Set LNet PID and start LNet interfaces, routing, and forwarding.
+ *
+ * Userspace program should call this after a successful call to LNetInit().
+ * Users must call this function at least once before any other functions.
+ * For each successful call there must be a corresponding call to
+ * LNetNIFini(). For subsequent calls to LNetNIInit(), \a requested_pid is
+ * ignored.
+ *
+ * The PID used by LNet may be different from the one requested.
+ * See LNetGetId().
+ *
+ * \param requested_pid PID requested by the caller.
+ *
+ * \return >= 0 on success, and < 0 error code on failures.
+ */
+int
+LNetNIInit(lnet_pid_t requested_pid)
+{
+	int	 im_a_router = 0;
+	int	 rc;
+
+	LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
+
+	LASSERT (the_lnet.ln_init);
+	CDEBUG(D_OTHER, "refs %d\n", the_lnet.ln_refcount);
+
+	if (the_lnet.ln_refcount > 0) {
+		rc = the_lnet.ln_refcount++;
+		goto out;
+	}
+
+	lnet_get_tunables();
+
+	if (requested_pid == LNET_PID_ANY) {
+		/* Don't instantiate LNET just for me */
+		rc = -ENETDOWN;
+		goto failed0;
+	}
+
+	rc = lnet_prepare(requested_pid);
+	if (rc != 0)
+		goto failed0;
+
+	rc = lnet_startup_lndnis();
+	if (rc != 0)
+		goto failed1;
+
+	rc = lnet_parse_routes(lnet_get_routes(), &im_a_router);
+	if (rc != 0)
+		goto failed2;
+
+	rc = lnet_check_routes();
+	if (rc != 0)
+		goto failed2;
+
+	rc = lnet_rtrpools_alloc(im_a_router);
+	if (rc != 0)
+		goto failed2;
+
+	rc = lnet_acceptor_start();
+	if (rc != 0)
+		goto failed2;
+
+	the_lnet.ln_refcount = 1;
+	/* Now I may use my own API functions... */
+
+	/* NB router checker needs the_lnet.ln_ping_info in
+	 * lnet_router_checker -> lnet_update_ni_status_locked */
+	rc = lnet_ping_target_init();
+	if (rc != 0)
+		goto failed3;
+
+	rc = lnet_router_checker_start();
+	if (rc != 0)
+		goto failed4;
+
+	lnet_proc_init();
+	goto out;
+
+ failed4:
+	lnet_ping_target_fini();
+ failed3:
+	the_lnet.ln_refcount = 0;
+	lnet_acceptor_stop();
+ failed2:
+	lnet_destroy_routes();
+	lnet_shutdown_lndnis();
+ failed1:
+	lnet_unprepare();
+ failed0:
+	LASSERT (rc < 0);
+ out:
+	LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
+	return rc;
+}
+EXPORT_SYMBOL(LNetNIInit);
+
+/**
+ * Stop LNet interfaces, routing, and forwarding.
+ *
+ * Users must call this function once for each successful call to LNetNIInit().
+ * Once the LNetNIFini() operation has been started, the results of pending
+ * API operations are undefined.
+ *
+ * \return always 0 for current implementation.
+ */
+int
+LNetNIFini()
+{
+	LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (the_lnet.ln_refcount > 0);
+
+	if (the_lnet.ln_refcount != 1) {
+		the_lnet.ln_refcount--;
+	} else {
+		LASSERT (!the_lnet.ln_niinit_self);
+
+		lnet_proc_fini();
+		lnet_router_checker_stop();
+		lnet_ping_target_fini();
+
+		/* Teardown fns that use my own API functions BEFORE here */
+		the_lnet.ln_refcount = 0;
+
+		lnet_acceptor_stop();
+		lnet_destroy_routes();
+		lnet_shutdown_lndnis();
+		lnet_unprepare();
+	}
+
+	LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(LNetNIFini);
+
+/**
+ * This is an ugly hack to export IOC_LIBCFS_DEBUG_PEER and
+ * IOC_LIBCFS_PORTALS_COMPATIBILITY commands to users, by tweaking the LNet
+ * internal ioctl handler.
+ *
+ * IOC_LIBCFS_PORTALS_COMPATIBILITY is now deprecated, don't use it.
+ *
+ * \param cmd IOC_LIBCFS_DEBUG_PEER to print debugging data about a peer.
+ * The data will be printed to system console. Don't use it excessively.
+ * \param arg A pointer to lnet_process_id_t, process ID of the peer.
+ *
+ * \return Always return 0 when called by users directly (i.e., not via ioctl).
+ */
+int
+LNetCtl(unsigned int cmd, void *arg)
+{
+	struct libcfs_ioctl_data *data = arg;
+	lnet_process_id_t	 id = {0};
+	lnet_ni_t		*ni;
+	int		       rc;
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (the_lnet.ln_refcount > 0);
+
+	switch (cmd) {
+	case IOC_LIBCFS_GET_NI:
+		rc = LNetGetId(data->ioc_count, &id);
+		data->ioc_nid = id.nid;
+		return rc;
+
+	case IOC_LIBCFS_FAIL_NID:
+		return lnet_fail_nid(data->ioc_nid, data->ioc_count);
+
+	case IOC_LIBCFS_ADD_ROUTE:
+		rc = lnet_add_route(data->ioc_net, data->ioc_count,
+				    data->ioc_nid);
+		return (rc != 0) ? rc : lnet_check_routes();
+
+	case IOC_LIBCFS_DEL_ROUTE:
+		return lnet_del_route(data->ioc_net, data->ioc_nid);
+
+	case IOC_LIBCFS_GET_ROUTE:
+		return lnet_get_route(data->ioc_count,
+				      &data->ioc_net, &data->ioc_count,
+				      &data->ioc_nid, &data->ioc_flags);
+	case IOC_LIBCFS_NOTIFY_ROUTER:
+		return lnet_notify(NULL, data->ioc_nid, data->ioc_flags,
+				   cfs_time_current() -
+				   cfs_time_seconds(cfs_time_current_sec() -
+						    (time_t)data->ioc_u64[0]));
+
+	case IOC_LIBCFS_PORTALS_COMPATIBILITY:
+		/* This can be removed once lustre stops calling it */
+		return 0;
+
+	case IOC_LIBCFS_LNET_DIST:
+		rc = LNetDist(data->ioc_nid, &data->ioc_nid, &data->ioc_u32[1]);
+		if (rc < 0 && rc != -EHOSTUNREACH)
+			return rc;
+
+		data->ioc_u32[0] = rc;
+		return 0;
+
+	case IOC_LIBCFS_TESTPROTOCOMPAT:
+		lnet_net_lock(LNET_LOCK_EX);
+		the_lnet.ln_testprotocompat = data->ioc_flags;
+		lnet_net_unlock(LNET_LOCK_EX);
+		return 0;
+
+	case IOC_LIBCFS_PING:
+		id.nid = data->ioc_nid;
+		id.pid = data->ioc_u32[0];
+		rc = lnet_ping(id, data->ioc_u32[1], /* timeout */
+			       (lnet_process_id_t *)data->ioc_pbuf1,
+			       data->ioc_plen1/sizeof(lnet_process_id_t));
+		if (rc < 0)
+			return rc;
+		data->ioc_count = rc;
+		return 0;
+
+	case IOC_LIBCFS_DEBUG_PEER: {
+		/* CAVEAT EMPTOR: this one designed for calling directly; not
+		 * via an ioctl */
+		id = *((lnet_process_id_t *) arg);
+
+		lnet_debug_peer(id.nid);
+
+		ni = lnet_net2ni(LNET_NIDNET(id.nid));
+		if (ni == NULL) {
+			CDEBUG(D_WARNING, "No NI for %s\n", libcfs_id2str(id));
+		} else {
+			if (ni->ni_lnd->lnd_ctl == NULL) {
+				CDEBUG(D_WARNING, "No ctl for %s\n",
+				       libcfs_id2str(id));
+			} else {
+				(void)ni->ni_lnd->lnd_ctl(ni, cmd, arg);
+			}
+
+			lnet_ni_decref(ni);
+		}
+		return 0;
+	}
+
+	default:
+		ni = lnet_net2ni(data->ioc_net);
+		if (ni == NULL)
+			return -EINVAL;
+
+		if (ni->ni_lnd->lnd_ctl == NULL)
+			rc = -EINVAL;
+		else
+			rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg);
+
+		lnet_ni_decref(ni);
+		return rc;
+	}
+	/* not reached */
+}
+EXPORT_SYMBOL(LNetCtl);
+
+/**
+ * Retrieve the lnet_process_id_t ID of LNet interface at \a index. Note that
+ * all interfaces share a same PID, as requested by LNetNIInit().
+ *
+ * \param index Index of the interface to look up.
+ * \param id On successful return, this location will hold the
+ * lnet_process_id_t ID of the interface.
+ *
+ * \retval 0 If an interface exists at \a index.
+ * \retval -ENOENT If no interface has been found.
+ */
+int
+LNetGetId(unsigned int index, lnet_process_id_t *id)
+{
+	struct lnet_ni	*ni;
+	struct list_head	*tmp;
+	int		cpt;
+	int		rc = -ENOENT;
+
+	LASSERT(the_lnet.ln_init);
+	LASSERT(the_lnet.ln_refcount > 0);
+
+	cpt = lnet_net_lock_current();
+
+	list_for_each(tmp, &the_lnet.ln_nis) {
+		if (index-- != 0)
+			continue;
+
+		ni = list_entry(tmp, lnet_ni_t, ni_list);
+
+		id->nid = ni->ni_nid;
+		id->pid = the_lnet.ln_pid;
+		rc = 0;
+		break;
+	}
+
+	lnet_net_unlock(cpt);
+	return rc;
+}
+EXPORT_SYMBOL(LNetGetId);
+
+/**
+ * Print a string representation of handle \a h into buffer \a str of
+ * \a len bytes.
+ */
+void
+LNetSnprintHandle(char *str, int len, lnet_handle_any_t h)
+{
+	snprintf(str, len, LPX64, h.cookie);
+}
+EXPORT_SYMBOL(LNetSnprintHandle);
+
+static int
+lnet_create_ping_info(void)
+{
+	int	       i;
+	int	       n;
+	int	       rc;
+	unsigned int      infosz;
+	lnet_ni_t	*ni;
+	lnet_process_id_t id;
+	lnet_ping_info_t *pinfo;
+
+	for (n = 0; ; n++) {
+		rc = LNetGetId(n, &id);
+		if (rc == -ENOENT)
+			break;
+
+		LASSERT (rc == 0);
+	}
+
+	infosz = offsetof(lnet_ping_info_t, pi_ni[n]);
+	LIBCFS_ALLOC(pinfo, infosz);
+	if (pinfo == NULL) {
+		CERROR("Can't allocate ping info[%d]\n", n);
+		return -ENOMEM;
+	}
+
+	pinfo->pi_nnis    = n;
+	pinfo->pi_pid     = the_lnet.ln_pid;
+	pinfo->pi_magic   = LNET_PROTO_PING_MAGIC;
+	pinfo->pi_features = LNET_PING_FEAT_NI_STATUS;
+
+	for (i = 0; i < n; i++) {
+		lnet_ni_status_t *ns = &pinfo->pi_ni[i];
+
+		rc = LNetGetId(i, &id);
+		LASSERT (rc == 0);
+
+		ns->ns_nid    = id.nid;
+		ns->ns_status = LNET_NI_STATUS_UP;
+
+		lnet_net_lock(0);
+
+		ni = lnet_nid2ni_locked(id.nid, 0);
+		LASSERT(ni != NULL);
+
+		lnet_ni_lock(ni);
+		LASSERT(ni->ni_status == NULL);
+		ni->ni_status = ns;
+		lnet_ni_unlock(ni);
+
+		lnet_ni_decref_locked(ni, 0);
+		lnet_net_unlock(0);
+	}
+
+	the_lnet.ln_ping_info = pinfo;
+	return 0;
+}
+
+static void
+lnet_destroy_ping_info(void)
+{
+	struct lnet_ni	*ni;
+
+	lnet_net_lock(0);
+
+	list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) {
+		lnet_ni_lock(ni);
+		ni->ni_status = NULL;
+		lnet_ni_unlock(ni);
+	}
+
+	lnet_net_unlock(0);
+
+	LIBCFS_FREE(the_lnet.ln_ping_info,
+		    offsetof(lnet_ping_info_t,
+			     pi_ni[the_lnet.ln_ping_info->pi_nnis]));
+	the_lnet.ln_ping_info = NULL;
+	return;
+}
+
+int
+lnet_ping_target_init(void)
+{
+	lnet_md_t	 md = {0};
+	lnet_handle_me_t  meh;
+	lnet_process_id_t id;
+	int	       rc;
+	int	       rc2;
+	int	       infosz;
+
+	rc = lnet_create_ping_info();
+	if (rc != 0)
+		return rc;
+
+	/* We can have a tiny EQ since we only need to see the unlink event on
+	 * teardown, which by definition is the last one! */
+	rc = LNetEQAlloc(2, LNET_EQ_HANDLER_NONE, &the_lnet.ln_ping_target_eq);
+	if (rc != 0) {
+		CERROR("Can't allocate ping EQ: %d\n", rc);
+		goto failed_0;
+	}
+
+	memset(&id, 0, sizeof(lnet_process_id_t));
+	id.nid = LNET_NID_ANY;
+	id.pid = LNET_PID_ANY;
+
+	rc = LNetMEAttach(LNET_RESERVED_PORTAL, id,
+			  LNET_PROTO_PING_MATCHBITS, 0,
+			  LNET_UNLINK, LNET_INS_AFTER,
+			  &meh);
+	if (rc != 0) {
+		CERROR("Can't create ping ME: %d\n", rc);
+		goto failed_1;
+	}
+
+	/* initialize md content */
+	infosz = offsetof(lnet_ping_info_t,
+			  pi_ni[the_lnet.ln_ping_info->pi_nnis]);
+	md.start     = the_lnet.ln_ping_info;
+	md.length    = infosz;
+	md.threshold = LNET_MD_THRESH_INF;
+	md.max_size  = 0;
+	md.options   = LNET_MD_OP_GET | LNET_MD_TRUNCATE |
+		       LNET_MD_MANAGE_REMOTE;
+	md.user_ptr  = NULL;
+	md.eq_handle = the_lnet.ln_ping_target_eq;
+
+	rc = LNetMDAttach(meh, md,
+			  LNET_RETAIN,
+			  &the_lnet.ln_ping_target_md);
+	if (rc != 0) {
+		CERROR("Can't attach ping MD: %d\n", rc);
+		goto failed_2;
+	}
+
+	return 0;
+
+ failed_2:
+	rc2 = LNetMEUnlink(meh);
+	LASSERT (rc2 == 0);
+ failed_1:
+	rc2 = LNetEQFree(the_lnet.ln_ping_target_eq);
+	LASSERT (rc2 == 0);
+ failed_0:
+	lnet_destroy_ping_info();
+	return rc;
+}
+
+void
+lnet_ping_target_fini(void)
+{
+	lnet_event_t    event;
+	int	     rc;
+	int	     which;
+	int	     timeout_ms = 1000;
+	sigset_t    blocked = cfs_block_allsigs();
+
+	LNetMDUnlink(the_lnet.ln_ping_target_md);
+	/* NB md could be busy; this just starts the unlink */
+
+	for (;;) {
+		rc = LNetEQPoll(&the_lnet.ln_ping_target_eq, 1,
+				timeout_ms, &event, &which);
+
+		/* I expect overflow... */
+		LASSERT (rc >= 0 || rc == -EOVERFLOW);
+
+		if (rc == 0) {
+			/* timed out: provide a diagnostic */
+			CWARN("Still waiting for ping MD to unlink\n");
+			timeout_ms *= 2;
+			continue;
+		}
+
+		/* Got a valid event */
+		if (event.unlinked)
+			break;
+	}
+
+	rc = LNetEQFree(the_lnet.ln_ping_target_eq);
+	LASSERT (rc == 0);
+	lnet_destroy_ping_info();
+	cfs_restore_sigs(blocked);
+}
+
+int
+lnet_ping (lnet_process_id_t id, int timeout_ms, lnet_process_id_t *ids, int n_ids)
+{
+	lnet_handle_eq_t     eqh;
+	lnet_handle_md_t     mdh;
+	lnet_event_t	 event;
+	lnet_md_t	    md = {0};
+	int		  which;
+	int		  unlinked = 0;
+	int		  replied = 0;
+	const int	    a_long_time = 60000; /* mS */
+	int		  infosz = offsetof(lnet_ping_info_t, pi_ni[n_ids]);
+	lnet_ping_info_t    *info;
+	lnet_process_id_t    tmpid;
+	int		  i;
+	int		  nob;
+	int		  rc;
+	int		  rc2;
+	sigset_t	 blocked;
+
+	if (n_ids <= 0 ||
+	    id.nid == LNET_NID_ANY ||
+	    timeout_ms > 500000 ||	      /* arbitrary limit! */
+	    n_ids > 20)			 /* arbitrary limit! */
+		return -EINVAL;
+
+	if (id.pid == LNET_PID_ANY)
+		id.pid = LUSTRE_SRV_LNET_PID;
+
+	LIBCFS_ALLOC(info, infosz);
+	if (info == NULL)
+		return -ENOMEM;
+
+	/* NB 2 events max (including any unlink event) */
+	rc = LNetEQAlloc(2, LNET_EQ_HANDLER_NONE, &eqh);
+	if (rc != 0) {
+		CERROR("Can't allocate EQ: %d\n", rc);
+		goto out_0;
+	}
+
+	/* initialize md content */
+	md.start     = info;
+	md.length    = infosz;
+	md.threshold = 2; /*GET/REPLY*/
+	md.max_size  = 0;
+	md.options   = LNET_MD_TRUNCATE;
+	md.user_ptr  = NULL;
+	md.eq_handle = eqh;
+
+	rc = LNetMDBind(md, LNET_UNLINK, &mdh);
+	if (rc != 0) {
+		CERROR("Can't bind MD: %d\n", rc);
+		goto out_1;
+	}
+
+	rc = LNetGet(LNET_NID_ANY, mdh, id,
+		     LNET_RESERVED_PORTAL,
+		     LNET_PROTO_PING_MATCHBITS, 0);
+
+	if (rc != 0) {
+		/* Don't CERROR; this could be deliberate! */
+
+		rc2 = LNetMDUnlink(mdh);
+		LASSERT (rc2 == 0);
+
+		/* NB must wait for the UNLINK event below... */
+		unlinked = 1;
+		timeout_ms = a_long_time;
+	}
+
+	do {
+		/* MUST block for unlink to complete */
+		if (unlinked)
+			blocked = cfs_block_allsigs();
+
+		rc2 = LNetEQPoll(&eqh, 1, timeout_ms, &event, &which);
+
+		if (unlinked)
+			cfs_restore_sigs(blocked);
+
+		CDEBUG(D_NET, "poll %d(%d %d)%s\n", rc2,
+		       (rc2 <= 0) ? -1 : event.type,
+		       (rc2 <= 0) ? -1 : event.status,
+		       (rc2 > 0 && event.unlinked) ? " unlinked" : "");
+
+		LASSERT (rc2 != -EOVERFLOW);     /* can't miss anything */
+
+		if (rc2 <= 0 || event.status != 0) {
+			/* timeout or error */
+			if (!replied && rc == 0)
+				rc = (rc2 < 0) ? rc2 :
+				     (rc2 == 0) ? -ETIMEDOUT :
+				     event.status;
+
+			if (!unlinked) {
+				/* Ensure completion in finite time... */
+				LNetMDUnlink(mdh);
+				/* No assertion (racing with network) */
+				unlinked = 1;
+				timeout_ms = a_long_time;
+			} else if (rc2 == 0) {
+				/* timed out waiting for unlink */
+				CWARN("ping %s: late network completion\n",
+				      libcfs_id2str(id));
+			}
+		} else if (event.type == LNET_EVENT_REPLY) {
+			replied = 1;
+			rc = event.mlength;
+		}
+
+	} while (rc2 <= 0 || !event.unlinked);
+
+	if (!replied) {
+		if (rc >= 0)
+			CWARN("%s: Unexpected rc >= 0 but no reply!\n",
+			      libcfs_id2str(id));
+		rc = -EIO;
+		goto out_1;
+	}
+
+	nob = rc;
+	LASSERT (nob >= 0 && nob <= infosz);
+
+	rc = -EPROTO;			   /* if I can't parse... */
+
+	if (nob < 8) {
+		/* can't check magic/version */
+		CERROR("%s: ping info too short %d\n",
+		       libcfs_id2str(id), nob);
+		goto out_1;
+	}
+
+	if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC)) {
+		lnet_swap_pinginfo(info);
+	} else if (info->pi_magic != LNET_PROTO_PING_MAGIC) {
+		CERROR("%s: Unexpected magic %08x\n",
+		       libcfs_id2str(id), info->pi_magic);
+		goto out_1;
+	}
+
+	if ((info->pi_features & LNET_PING_FEAT_NI_STATUS) == 0) {
+		CERROR("%s: ping w/o NI status: 0x%x\n",
+		       libcfs_id2str(id), info->pi_features);
+		goto out_1;
+	}
+
+	if (nob < offsetof(lnet_ping_info_t, pi_ni[0])) {
+		CERROR("%s: Short reply %d(%d min)\n", libcfs_id2str(id),
+		       nob, (int)offsetof(lnet_ping_info_t, pi_ni[0]));
+		goto out_1;
+	}
+
+	if (info->pi_nnis < n_ids)
+		n_ids = info->pi_nnis;
+
+	if (nob < offsetof(lnet_ping_info_t, pi_ni[n_ids])) {
+		CERROR("%s: Short reply %d(%d expected)\n", libcfs_id2str(id),
+		       nob, (int)offsetof(lnet_ping_info_t, pi_ni[n_ids]));
+		goto out_1;
+	}
+
+	rc = -EFAULT;			   /* If I SEGV... */
+
+	for (i = 0; i < n_ids; i++) {
+		tmpid.pid = info->pi_pid;
+		tmpid.nid = info->pi_ni[i].ns_nid;
+		if (copy_to_user(&ids[i], &tmpid, sizeof(tmpid)))
+			goto out_1;
+	}
+	rc = info->pi_nnis;
+
+ out_1:
+	rc2 = LNetEQFree(eqh);
+	if (rc2 != 0)
+		CERROR("rc2 %d\n", rc2);
+	LASSERT (rc2 == 0);
+
+ out_0:
+	LIBCFS_FREE(info, infosz);
+	return rc;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/config.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/config.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/config.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/config.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1264 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+#include <linux/lnet/lib-lnet.h>
+
+typedef struct {			    /* tmp struct for parsing routes */
+	struct list_head	 ltb_list;	/* stash on lists */
+	int		ltb_size;	/* allocated size */
+	char	       ltb_text[0];     /* text buffer */
+} lnet_text_buf_t;
+
+static int lnet_tbnob = 0;			/* track text buf allocation */
+#define LNET_MAX_TEXTBUF_NOB     (64<<10)	/* bound allocation */
+#define LNET_SINGLE_TEXTBUF_NOB  (4<<10)
+
+void
+lnet_syntax(char *name, char *str, int offset, int width)
+{
+	static char dots[LNET_SINGLE_TEXTBUF_NOB];
+	static char dashes[LNET_SINGLE_TEXTBUF_NOB];
+
+	memset(dots, '.', sizeof(dots));
+	dots[sizeof(dots)-1] = 0;
+	memset(dashes, '-', sizeof(dashes));
+	dashes[sizeof(dashes)-1] = 0;
+
+	LCONSOLE_ERROR_MSG(0x10f, "Error parsing '%s=\"%s\"'\n", name, str);
+	LCONSOLE_ERROR_MSG(0x110, "here...........%.*s..%.*s|%.*s|\n",
+			   (int)strlen(name), dots, offset, dots,
+			    (width < 1) ? 0 : width - 1, dashes);
+}
+
+int
+lnet_issep (char c)
+{
+	switch (c) {
+	case '\n':
+	case '\r':
+	case ';':
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+int
+lnet_net_unique(__u32 net, struct list_head *nilist)
+{
+	struct list_head       *tmp;
+	lnet_ni_t	*ni;
+
+	list_for_each (tmp, nilist) {
+		ni = list_entry(tmp, lnet_ni_t, ni_list);
+
+		if (LNET_NIDNET(ni->ni_nid) == net)
+			return 0;
+	}
+
+	return 1;
+}
+
+void
+lnet_ni_free(struct lnet_ni *ni)
+{
+	if (ni->ni_refs != NULL)
+		cfs_percpt_free(ni->ni_refs);
+
+	if (ni->ni_tx_queues != NULL)
+		cfs_percpt_free(ni->ni_tx_queues);
+
+	if (ni->ni_cpts != NULL)
+		cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts);
+
+	LIBCFS_FREE(ni, sizeof(*ni));
+}
+
+lnet_ni_t *
+lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist)
+{
+	struct lnet_tx_queue	*tq;
+	struct lnet_ni		*ni;
+	int			rc;
+	int			i;
+
+	if (!lnet_net_unique(net, nilist)) {
+		LCONSOLE_ERROR_MSG(0x111, "Duplicate network specified: %s\n",
+				   libcfs_net2str(net));
+		return NULL;
+	}
+
+	LIBCFS_ALLOC(ni, sizeof(*ni));
+	if (ni == NULL) {
+		CERROR("Out of memory creating network %s\n",
+		       libcfs_net2str(net));
+		return NULL;
+	}
+
+	spin_lock_init(&ni->ni_lock);
+	INIT_LIST_HEAD(&ni->ni_cptlist);
+	ni->ni_refs = cfs_percpt_alloc(lnet_cpt_table(),
+				       sizeof(*ni->ni_refs[0]));
+	if (ni->ni_refs == NULL)
+		goto failed;
+
+	ni->ni_tx_queues = cfs_percpt_alloc(lnet_cpt_table(),
+					    sizeof(*ni->ni_tx_queues[0]));
+	if (ni->ni_tx_queues == NULL)
+		goto failed;
+
+	cfs_percpt_for_each(tq, i, ni->ni_tx_queues)
+		INIT_LIST_HEAD(&tq->tq_delayed);
+
+	if (el == NULL) {
+		ni->ni_cpts  = NULL;
+		ni->ni_ncpts = LNET_CPT_NUMBER;
+	} else {
+		rc = cfs_expr_list_values(el, LNET_CPT_NUMBER, &ni->ni_cpts);
+		if (rc <= 0) {
+			CERROR("Failed to set CPTs for NI %s: %d\n",
+			       libcfs_net2str(net), rc);
+			goto failed;
+		}
+
+		LASSERT(rc <= LNET_CPT_NUMBER);
+		if (rc == LNET_CPT_NUMBER) {
+			LIBCFS_FREE(ni->ni_cpts, rc * sizeof(ni->ni_cpts[0]));
+			ni->ni_cpts = NULL;
+		}
+
+		ni->ni_ncpts = rc;
+	}
+
+	/* LND will fill in the address part of the NID */
+	ni->ni_nid = LNET_MKNID(net, 0);
+	ni->ni_last_alive = cfs_time_current_sec();
+	list_add_tail(&ni->ni_list, nilist);
+	return ni;
+ failed:
+	lnet_ni_free(ni);
+	return NULL;
+}
+
+int
+lnet_parse_networks(struct list_head *nilist, char *networks)
+{
+	struct cfs_expr_list *el = NULL;
+	int		tokensize = strlen(networks) + 1;
+	char		*tokens;
+	char		*str;
+	char		*tmp;
+	struct lnet_ni	*ni;
+	__u32		net;
+	int		nnets = 0;
+
+	if (strlen(networks) > LNET_SINGLE_TEXTBUF_NOB) {
+		/* _WAY_ conservative */
+		LCONSOLE_ERROR_MSG(0x112, "Can't parse networks: string too "
+				   "long\n");
+		return -EINVAL;
+	}
+
+	LIBCFS_ALLOC(tokens, tokensize);
+	if (tokens == NULL) {
+		CERROR("Can't allocate net tokens\n");
+		return -ENOMEM;
+	}
+
+	the_lnet.ln_network_tokens = tokens;
+	the_lnet.ln_network_tokens_nob = tokensize;
+	memcpy (tokens, networks, tokensize);
+	str = tmp = tokens;
+
+	/* Add in the loopback network */
+	ni = lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, nilist);
+	if (ni == NULL)
+		goto failed;
+
+	while (str != NULL && *str != 0) {
+		char	*comma = strchr(str, ',');
+		char	*bracket = strchr(str, '(');
+		char	*square = strchr(str, '[');
+		char	*iface;
+		int	niface;
+		int	rc;
+
+		/* NB we don't check interface conflicts here; it's the LNDs
+		 * responsibility (if it cares at all) */
+
+		if (square != NULL && (comma == NULL || square < comma)) {
+			/* i.e: o2ib0(ib0)[1,2], number between square
+			 * brackets are CPTs this NI needs to be bond */
+			if (bracket != NULL && bracket > square) {
+				tmp = square;
+				goto failed_syntax;
+			}
+
+			tmp = strchr(square, ']');
+			if (tmp == NULL) {
+				tmp = square;
+				goto failed_syntax;
+			}
+
+			rc = cfs_expr_list_parse(square, tmp - square + 1,
+						 0, LNET_CPT_NUMBER - 1, &el);
+			if (rc != 0) {
+				tmp = square;
+				goto failed_syntax;
+			}
+
+			while (square <= tmp)
+				*square++ = ' ';
+		}
+
+		if (bracket == NULL ||
+		    (comma != NULL && comma < bracket)) {
+
+			/* no interface list specified */
+
+			if (comma != NULL)
+				*comma++ = 0;
+			net = libcfs_str2net(cfs_trimwhite(str));
+
+			if (net == LNET_NIDNET(LNET_NID_ANY)) {
+				LCONSOLE_ERROR_MSG(0x113, "Unrecognised network"
+						   " type\n");
+				tmp = str;
+				goto failed_syntax;
+			}
+
+			if (LNET_NETTYP(net) != LOLND && /* LO is implicit */
+			    lnet_ni_alloc(net, el, nilist) == NULL)
+				goto failed;
+
+			if (el != NULL) {
+				cfs_expr_list_free(el);
+				el = NULL;
+			}
+
+			str = comma;
+			continue;
+		}
+
+		*bracket = 0;
+		net = libcfs_str2net(cfs_trimwhite(str));
+		if (net == LNET_NIDNET(LNET_NID_ANY)) {
+			tmp = str;
+			goto failed_syntax;
+		}
+
+		nnets++;
+		ni = lnet_ni_alloc(net, el, nilist);
+		if (ni == NULL)
+			goto failed;
+
+		if (el != NULL) {
+			cfs_expr_list_free(el);
+			el = NULL;
+		}
+
+		niface = 0;
+		iface = bracket + 1;
+
+		bracket = strchr(iface, ')');
+		if (bracket == NULL) {
+			tmp = iface;
+			goto failed_syntax;
+		}
+
+		*bracket = 0;
+		do {
+			comma = strchr(iface, ',');
+			if (comma != NULL)
+				*comma++ = 0;
+
+			iface = cfs_trimwhite(iface);
+			if (*iface == 0) {
+				tmp = iface;
+				goto failed_syntax;
+			}
+
+			if (niface == LNET_MAX_INTERFACES) {
+				LCONSOLE_ERROR_MSG(0x115, "Too many interfaces "
+						   "for net %s\n",
+						   libcfs_net2str(net));
+				goto failed;
+			}
+
+			ni->ni_interfaces[niface++] = iface;
+			iface = comma;
+		} while (iface != NULL);
+
+		str = bracket + 1;
+		comma = strchr(bracket + 1, ',');
+		if (comma != NULL) {
+			*comma = 0;
+			str = cfs_trimwhite(str);
+			if (*str != 0) {
+				tmp = str;
+				goto failed_syntax;
+			}
+			str = comma + 1;
+			continue;
+		}
+
+		str = cfs_trimwhite(str);
+		if (*str != 0) {
+			tmp = str;
+			goto failed_syntax;
+		}
+	}
+
+	LASSERT(!list_empty(nilist));
+	return 0;
+
+ failed_syntax:
+	lnet_syntax("networks", networks, (int)(tmp - tokens), strlen(tmp));
+ failed:
+	while (!list_empty(nilist)) {
+		ni = list_entry(nilist->next, lnet_ni_t, ni_list);
+
+		list_del(&ni->ni_list);
+		lnet_ni_free(ni);
+	}
+
+	if (el != NULL)
+		cfs_expr_list_free(el);
+
+	LIBCFS_FREE(tokens, tokensize);
+	the_lnet.ln_network_tokens = NULL;
+
+	return -EINVAL;
+}
+
+lnet_text_buf_t *
+lnet_new_text_buf (int str_len)
+{
+	lnet_text_buf_t *ltb;
+	int	      nob;
+
+	/* NB allocate space for the terminating 0 */
+	nob = offsetof(lnet_text_buf_t, ltb_text[str_len + 1]);
+	if (nob > LNET_SINGLE_TEXTBUF_NOB) {
+		/* _way_ conservative for "route net gateway..." */
+		CERROR("text buffer too big\n");
+		return NULL;
+	}
+
+	if (lnet_tbnob + nob > LNET_MAX_TEXTBUF_NOB) {
+		CERROR("Too many text buffers\n");
+		return NULL;
+	}
+
+	LIBCFS_ALLOC(ltb, nob);
+	if (ltb == NULL)
+		return NULL;
+
+	ltb->ltb_size = nob;
+	ltb->ltb_text[0] = 0;
+	lnet_tbnob += nob;
+	return ltb;
+}
+
+void
+lnet_free_text_buf (lnet_text_buf_t *ltb)
+{
+	lnet_tbnob -= ltb->ltb_size;
+	LIBCFS_FREE(ltb, ltb->ltb_size);
+}
+
+void
+lnet_free_text_bufs(struct list_head *tbs)
+{
+	lnet_text_buf_t  *ltb;
+
+	while (!list_empty(tbs)) {
+		ltb = list_entry(tbs->next, lnet_text_buf_t, ltb_list);
+
+		list_del(&ltb->ltb_list);
+		lnet_free_text_buf(ltb);
+	}
+}
+
+void
+lnet_print_text_bufs(struct list_head *tbs)
+{
+	struct list_head	*tmp;
+	lnet_text_buf_t   *ltb;
+
+	list_for_each (tmp, tbs) {
+		ltb = list_entry(tmp, lnet_text_buf_t, ltb_list);
+
+		CDEBUG(D_WARNING, "%s\n", ltb->ltb_text);
+	}
+
+	CDEBUG(D_WARNING, "%d allocated\n", lnet_tbnob);
+}
+
+int
+lnet_str2tbs_sep (struct list_head *tbs, char *str)
+{
+	struct list_head	pending;
+	char	     *sep;
+	int	       nob;
+	int	       i;
+	lnet_text_buf_t  *ltb;
+
+	INIT_LIST_HEAD(&pending);
+
+	/* Split 'str' into separate commands */
+	for (;;) {
+		/* skip leading whitespace */
+		while (cfs_iswhite(*str))
+			str++;
+
+		/* scan for separator or comment */
+		for (sep = str; *sep != 0; sep++)
+			if (lnet_issep(*sep) || *sep == '#')
+				break;
+
+		nob = (int)(sep - str);
+		if (nob > 0) {
+			ltb = lnet_new_text_buf(nob);
+			if (ltb == NULL) {
+				lnet_free_text_bufs(&pending);
+				return -1;
+			}
+
+			for (i = 0; i < nob; i++)
+				if (cfs_iswhite(str[i]))
+					ltb->ltb_text[i] = ' ';
+				else
+					ltb->ltb_text[i] = str[i];
+
+			ltb->ltb_text[nob] = 0;
+
+			list_add_tail(&ltb->ltb_list, &pending);
+		}
+
+		if (*sep == '#') {
+			/* scan for separator */
+			do {
+				sep++;
+			} while (*sep != 0 && !lnet_issep(*sep));
+		}
+
+		if (*sep == 0)
+			break;
+
+		str = sep + 1;
+	}
+
+	list_splice(&pending, tbs->prev);
+	return 0;
+}
+
+int
+lnet_expand1tb (struct list_head *list,
+	       char *str, char *sep1, char *sep2,
+	       char *item, int itemlen)
+{
+	int	      len1 = (int)(sep1 - str);
+	int	      len2 = strlen(sep2 + 1);
+	lnet_text_buf_t *ltb;
+
+	LASSERT (*sep1 == '[');
+	LASSERT (*sep2 == ']');
+
+	ltb = lnet_new_text_buf(len1 + itemlen + len2);
+	if (ltb == NULL)
+		return -ENOMEM;
+
+	memcpy(ltb->ltb_text, str, len1);
+	memcpy(&ltb->ltb_text[len1], item, itemlen);
+	memcpy(&ltb->ltb_text[len1+itemlen], sep2 + 1, len2);
+	ltb->ltb_text[len1 + itemlen + len2] = 0;
+
+	list_add_tail(&ltb->ltb_list, list);
+	return 0;
+}
+
+int
+lnet_str2tbs_expand (struct list_head *tbs, char *str)
+{
+	char	      num[16];
+	struct list_head	pending;
+	char	     *sep;
+	char	     *sep2;
+	char	     *parsed;
+	char	     *enditem;
+	int	       lo;
+	int	       hi;
+	int	       stride;
+	int	       i;
+	int	       nob;
+	int	       scanned;
+
+	INIT_LIST_HEAD(&pending);
+
+	sep = strchr(str, '[');
+	if (sep == NULL)			/* nothing to expand */
+		return 0;
+
+	sep2 = strchr(sep, ']');
+	if (sep2 == NULL)
+		goto failed;
+
+	for (parsed = sep; parsed < sep2; parsed = enditem) {
+
+		enditem = ++parsed;
+		while (enditem < sep2 && *enditem != ',')
+			enditem++;
+
+		if (enditem == parsed)		/* no empty items */
+			goto failed;
+
+		if (sscanf(parsed, "%d-%d/%d%n", &lo, &hi, &stride, &scanned) < 3) {
+
+			if (sscanf(parsed, "%d-%d%n", &lo, &hi, &scanned) < 2) {
+
+				/* simple string enumeration */
+				if (lnet_expand1tb(&pending, str, sep, sep2,
+						   parsed, (int)(enditem - parsed)) != 0)
+					goto failed;
+
+				continue;
+			}
+
+			stride = 1;
+		}
+
+		/* range expansion */
+
+		if (enditem != parsed + scanned) /* no trailing junk */
+			goto failed;
+
+		if (hi < 0 || lo < 0 || stride < 0 || hi < lo ||
+		    (hi - lo) % stride != 0)
+			goto failed;
+
+		for (i = lo; i <= hi; i += stride) {
+
+			snprintf(num, sizeof(num), "%d", i);
+			nob = strlen(num);
+			if (nob + 1 == sizeof(num))
+				goto failed;
+
+			if (lnet_expand1tb(&pending, str, sep, sep2,
+					   num, nob) != 0)
+				goto failed;
+		}
+	}
+
+	list_splice(&pending, tbs->prev);
+	return 1;
+
+ failed:
+	lnet_free_text_bufs(&pending);
+	return -1;
+}
+
+int
+lnet_parse_hops (char *str, unsigned int *hops)
+{
+	int     len = strlen(str);
+	int     nob = len;
+
+	return (sscanf(str, "%u%n", hops, &nob) >= 1 &&
+		nob == len &&
+		*hops > 0 && *hops < 256);
+}
+
+
+int
+lnet_parse_route (char *str, int *im_a_router)
+{
+	/* static scratch buffer OK (single threaded) */
+	static char       cmd[LNET_SINGLE_TEXTBUF_NOB];
+
+	struct list_head	nets;
+	struct list_head	gateways;
+	struct list_head       *tmp1;
+	struct list_head       *tmp2;
+	__u32	     net;
+	lnet_nid_t	nid;
+	lnet_text_buf_t  *ltb;
+	int	       rc;
+	char	     *sep;
+	char	     *token = str;
+	int	       ntokens = 0;
+	int	       myrc = -1;
+	unsigned int      hops;
+	int	       got_hops = 0;
+
+	INIT_LIST_HEAD(&gateways);
+	INIT_LIST_HEAD(&nets);
+
+	/* save a copy of the string for error messages */
+	strncpy(cmd, str, sizeof(cmd) - 1);
+	cmd[sizeof(cmd) - 1] = 0;
+
+	sep = str;
+	for (;;) {
+		/* scan for token start */
+		while (cfs_iswhite(*sep))
+			sep++;
+		if (*sep == 0) {
+			if (ntokens < (got_hops ? 3 : 2))
+				goto token_error;
+			break;
+		}
+
+		ntokens++;
+		token = sep++;
+
+		/* scan for token end */
+		while (*sep != 0 && !cfs_iswhite(*sep))
+			sep++;
+		if (*sep != 0)
+			*sep++ = 0;
+
+		if (ntokens == 1) {
+			tmp2 = &nets;		/* expanding nets */
+		} else if (ntokens == 2 &&
+			   lnet_parse_hops(token, &hops)) {
+			got_hops = 1;	   /* got a hop count */
+			continue;
+		} else {
+			tmp2 = &gateways;	/* expanding gateways */
+		}
+
+		ltb = lnet_new_text_buf(strlen(token));
+		if (ltb == NULL)
+			goto out;
+
+		strcpy(ltb->ltb_text, token);
+		tmp1 = &ltb->ltb_list;
+		list_add_tail(tmp1, tmp2);
+
+		while (tmp1 != tmp2) {
+			ltb = list_entry(tmp1, lnet_text_buf_t, ltb_list);
+
+			rc = lnet_str2tbs_expand(tmp1->next, ltb->ltb_text);
+			if (rc < 0)
+				goto token_error;
+
+			tmp1 = tmp1->next;
+
+			if (rc > 0) {		/* expanded! */
+				list_del(&ltb->ltb_list);
+				lnet_free_text_buf(ltb);
+				continue;
+			}
+
+			if (ntokens == 1) {
+				net = libcfs_str2net(ltb->ltb_text);
+				if (net == LNET_NIDNET(LNET_NID_ANY) ||
+				    LNET_NETTYP(net) == LOLND)
+					goto token_error;
+			} else {
+				nid = libcfs_str2nid(ltb->ltb_text);
+				if (nid == LNET_NID_ANY ||
+				    LNET_NETTYP(LNET_NIDNET(nid)) == LOLND)
+					goto token_error;
+			}
+		}
+	}
+
+	if (!got_hops)
+		hops = 1;
+
+	LASSERT (!list_empty(&nets));
+	LASSERT (!list_empty(&gateways));
+
+	list_for_each (tmp1, &nets) {
+		ltb = list_entry(tmp1, lnet_text_buf_t, ltb_list);
+		net = libcfs_str2net(ltb->ltb_text);
+		LASSERT (net != LNET_NIDNET(LNET_NID_ANY));
+
+		list_for_each (tmp2, &gateways) {
+			ltb = list_entry(tmp2, lnet_text_buf_t, ltb_list);
+			nid = libcfs_str2nid(ltb->ltb_text);
+			LASSERT (nid != LNET_NID_ANY);
+
+			if (lnet_islocalnid(nid)) {
+				*im_a_router = 1;
+				continue;
+			}
+
+			rc = lnet_add_route (net, hops, nid);
+			if (rc != 0) {
+				CERROR("Can't create route "
+				       "to %s via %s\n",
+				       libcfs_net2str(net),
+				       libcfs_nid2str(nid));
+				goto out;
+			}
+		}
+	}
+
+	myrc = 0;
+	goto out;
+
+ token_error:
+	lnet_syntax("routes", cmd, (int)(token - str), strlen(token));
+ out:
+	lnet_free_text_bufs(&nets);
+	lnet_free_text_bufs(&gateways);
+	return myrc;
+}
+
+int
+lnet_parse_route_tbs(struct list_head *tbs, int *im_a_router)
+{
+	lnet_text_buf_t   *ltb;
+
+	while (!list_empty(tbs)) {
+		ltb = list_entry(tbs->next, lnet_text_buf_t, ltb_list);
+
+		if (lnet_parse_route(ltb->ltb_text, im_a_router) < 0) {
+			lnet_free_text_bufs(tbs);
+			return -EINVAL;
+		}
+
+		list_del(&ltb->ltb_list);
+		lnet_free_text_buf(ltb);
+	}
+
+	return 0;
+}
+
+int
+lnet_parse_routes (char *routes, int *im_a_router)
+{
+	struct list_head	tbs;
+	int	       rc = 0;
+
+	*im_a_router = 0;
+
+	INIT_LIST_HEAD(&tbs);
+
+	if (lnet_str2tbs_sep(&tbs, routes) < 0) {
+		CERROR("Error parsing routes\n");
+		rc = -EINVAL;
+	} else {
+		rc = lnet_parse_route_tbs(&tbs, im_a_router);
+	}
+
+	LASSERT (lnet_tbnob == 0);
+	return rc;
+}
+
+int
+lnet_match_network_token(char *token, int len, __u32 *ipaddrs, int nip)
+{
+	LIST_HEAD	(list);
+	int		rc;
+	int		i;
+
+	rc = cfs_ip_addr_parse(token, len, &list);
+	if (rc != 0)
+		return rc;
+
+	for (rc = i = 0; !rc && i < nip; i++)
+		rc = cfs_ip_addr_match(ipaddrs[i], &list);
+
+	cfs_ip_addr_free(&list);
+
+	return rc;
+}
+
+int
+lnet_match_network_tokens(char *net_entry, __u32 *ipaddrs, int nip)
+{
+	static char tokens[LNET_SINGLE_TEXTBUF_NOB];
+
+	int   matched = 0;
+	int   ntokens = 0;
+	int   len;
+	char *net = NULL;
+	char *sep;
+	char *token;
+	int   rc;
+
+	LASSERT (strlen(net_entry) < sizeof(tokens));
+
+	/* work on a copy of the string */
+	strcpy(tokens, net_entry);
+	sep = tokens;
+	for (;;) {
+		/* scan for token start */
+		while (cfs_iswhite(*sep))
+			sep++;
+		if (*sep == 0)
+			break;
+
+		token = sep++;
+
+		/* scan for token end */
+		while (*sep != 0 && !cfs_iswhite(*sep))
+			sep++;
+		if (*sep != 0)
+			*sep++ = 0;
+
+		if (ntokens++ == 0) {
+			net = token;
+			continue;
+		}
+
+		len = strlen(token);
+
+		rc = lnet_match_network_token(token, len, ipaddrs, nip);
+		if (rc < 0) {
+			lnet_syntax("ip2nets", net_entry,
+				    (int)(token - tokens), len);
+			return rc;
+		}
+
+		matched |= (rc != 0);
+	}
+
+	if (!matched)
+		return 0;
+
+	strcpy(net_entry, net);		 /* replace with matched net */
+	return 1;
+}
+
+__u32
+lnet_netspec2net(char *netspec)
+{
+	char   *bracket = strchr(netspec, '(');
+	__u32   net;
+
+	if (bracket != NULL)
+		*bracket = 0;
+
+	net = libcfs_str2net(netspec);
+
+	if (bracket != NULL)
+		*bracket = '(';
+
+	return net;
+}
+
+int
+lnet_splitnets(char *source, struct list_head *nets)
+{
+	int	       offset = 0;
+	int	       offset2;
+	int	       len;
+	lnet_text_buf_t  *tb;
+	lnet_text_buf_t  *tb2;
+	struct list_head       *t;
+	char	     *sep;
+	char	     *bracket;
+	__u32	     net;
+
+	LASSERT (!list_empty(nets));
+	LASSERT (nets->next == nets->prev);     /* single entry */
+
+	tb = list_entry(nets->next, lnet_text_buf_t, ltb_list);
+
+	for (;;) {
+		sep = strchr(tb->ltb_text, ',');
+		bracket = strchr(tb->ltb_text, '(');
+
+		if (sep != NULL &&
+		    bracket != NULL &&
+		    bracket < sep) {
+			/* netspec lists interfaces... */
+
+			offset2 = offset + (int)(bracket - tb->ltb_text);
+			len = strlen(bracket);
+
+			bracket = strchr(bracket + 1, ')');
+
+			if (bracket == NULL ||
+			    !(bracket[1] == ',' || bracket[1] == 0)) {
+				lnet_syntax("ip2nets", source, offset2, len);
+				return -EINVAL;
+			}
+
+			sep = (bracket[1] == 0) ? NULL : bracket + 1;
+		}
+
+		if (sep != NULL)
+			*sep++ = 0;
+
+		net = lnet_netspec2net(tb->ltb_text);
+		if (net == LNET_NIDNET(LNET_NID_ANY)) {
+			lnet_syntax("ip2nets", source, offset,
+				    strlen(tb->ltb_text));
+			return -EINVAL;
+		}
+
+		list_for_each(t, nets) {
+			tb2 = list_entry(t, lnet_text_buf_t, ltb_list);
+
+			if (tb2 == tb)
+				continue;
+
+			if (net == lnet_netspec2net(tb2->ltb_text)) {
+				/* duplicate network */
+				lnet_syntax("ip2nets", source, offset,
+					    strlen(tb->ltb_text));
+				return -EINVAL;
+			}
+		}
+
+		if (sep == NULL)
+			return 0;
+
+		offset += (int)(sep - tb->ltb_text);
+		tb2 = lnet_new_text_buf(strlen(sep));
+		if (tb2 == NULL)
+			return -ENOMEM;
+
+		strcpy(tb2->ltb_text, sep);
+		list_add_tail(&tb2->ltb_list, nets);
+
+		tb = tb2;
+	}
+}
+
+int
+lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
+{
+	static char	networks[LNET_SINGLE_TEXTBUF_NOB];
+	static char	source[LNET_SINGLE_TEXTBUF_NOB];
+
+	struct list_head	  raw_entries;
+	struct list_head	  matched_nets;
+	struct list_head	  current_nets;
+	struct list_head	 *t;
+	struct list_head	 *t2;
+	lnet_text_buf_t    *tb;
+	lnet_text_buf_t    *tb2;
+	__u32	       net1;
+	__u32	       net2;
+	int		 len;
+	int		 count;
+	int		 dup;
+	int		 rc;
+
+	INIT_LIST_HEAD(&raw_entries);
+	if (lnet_str2tbs_sep(&raw_entries, ip2nets) < 0) {
+		CERROR("Error parsing ip2nets\n");
+		LASSERT (lnet_tbnob == 0);
+		return -EINVAL;
+	}
+
+	INIT_LIST_HEAD(&matched_nets);
+	INIT_LIST_HEAD(&current_nets);
+	networks[0] = 0;
+	count = 0;
+	len = 0;
+	rc = 0;
+
+	while (!list_empty(&raw_entries)) {
+		tb = list_entry(raw_entries.next, lnet_text_buf_t,
+				    ltb_list);
+
+		strncpy(source, tb->ltb_text, sizeof(source)-1);
+		source[sizeof(source)-1] = 0;
+
+		/* replace ltb_text with the network(s) add on match */
+		rc = lnet_match_network_tokens(tb->ltb_text, ipaddrs, nip);
+		if (rc < 0)
+			break;
+
+		list_del(&tb->ltb_list);
+
+		if (rc == 0) {		  /* no match */
+			lnet_free_text_buf(tb);
+			continue;
+		}
+
+		/* split into separate networks */
+		INIT_LIST_HEAD(&current_nets);
+		list_add(&tb->ltb_list, &current_nets);
+		rc = lnet_splitnets(source, &current_nets);
+		if (rc < 0)
+			break;
+
+		dup = 0;
+		list_for_each (t, &current_nets) {
+			tb = list_entry(t, lnet_text_buf_t, ltb_list);
+			net1 = lnet_netspec2net(tb->ltb_text);
+			LASSERT (net1 != LNET_NIDNET(LNET_NID_ANY));
+
+			list_for_each(t2, &matched_nets) {
+				tb2 = list_entry(t2, lnet_text_buf_t,
+						     ltb_list);
+				net2 = lnet_netspec2net(tb2->ltb_text);
+				LASSERT (net2 != LNET_NIDNET(LNET_NID_ANY));
+
+				if (net1 == net2) {
+					dup = 1;
+					break;
+				}
+			}
+
+			if (dup)
+				break;
+		}
+
+		if (dup) {
+			lnet_free_text_bufs(&current_nets);
+			continue;
+		}
+
+		list_for_each_safe(t, t2, &current_nets) {
+			tb = list_entry(t, lnet_text_buf_t, ltb_list);
+
+			list_del(&tb->ltb_list);
+			list_add_tail(&tb->ltb_list, &matched_nets);
+
+			len += snprintf(networks + len, sizeof(networks) - len,
+					"%s%s", (len == 0) ? "" : ",",
+					tb->ltb_text);
+
+			if (len >= sizeof(networks)) {
+				CERROR("Too many matched networks\n");
+				rc = -E2BIG;
+				goto out;
+			}
+		}
+
+		count++;
+	}
+
+ out:
+	lnet_free_text_bufs(&raw_entries);
+	lnet_free_text_bufs(&matched_nets);
+	lnet_free_text_bufs(&current_nets);
+	LASSERT (lnet_tbnob == 0);
+
+	if (rc < 0)
+		return rc;
+
+	*networksp = networks;
+	return count;
+}
+
+void
+lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip)
+{
+	LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
+}
+
+int
+lnet_ipaddr_enumerate (__u32 **ipaddrsp)
+{
+	int	up;
+	__u32      netmask;
+	__u32     *ipaddrs;
+	__u32     *ipaddrs2;
+	int	nip;
+	char     **ifnames;
+	int	nif = libcfs_ipif_enumerate(&ifnames);
+	int	i;
+	int	rc;
+
+	if (nif <= 0)
+		return nif;
+
+	LIBCFS_ALLOC(ipaddrs, nif * sizeof(*ipaddrs));
+	if (ipaddrs == NULL) {
+		CERROR("Can't allocate ipaddrs[%d]\n", nif);
+		libcfs_ipif_free_enumeration(ifnames, nif);
+		return -ENOMEM;
+	}
+
+	for (i = nip = 0; i < nif; i++) {
+		if (!strcmp(ifnames[i], "lo"))
+			continue;
+
+		rc = libcfs_ipif_query(ifnames[i], &up,
+				       &ipaddrs[nip], &netmask);
+		if (rc != 0) {
+			CWARN("Can't query interface %s: %d\n",
+			      ifnames[i], rc);
+			continue;
+		}
+
+		if (!up) {
+			CWARN("Ignoring interface %s: it's down\n",
+			      ifnames[i]);
+			continue;
+		}
+
+		nip++;
+	}
+
+	libcfs_ipif_free_enumeration(ifnames, nif);
+
+	if (nip == nif) {
+		*ipaddrsp = ipaddrs;
+	} else {
+		if (nip > 0) {
+			LIBCFS_ALLOC(ipaddrs2, nip * sizeof(*ipaddrs2));
+			if (ipaddrs2 == NULL) {
+				CERROR("Can't allocate ipaddrs[%d]\n", nip);
+				nip = -ENOMEM;
+			} else {
+				memcpy(ipaddrs2, ipaddrs,
+				       nip * sizeof(*ipaddrs));
+				*ipaddrsp = ipaddrs2;
+				rc = nip;
+			}
+		}
+		lnet_ipaddr_free_enumeration(ipaddrs, nif);
+	}
+	return nip;
+}
+
+int
+lnet_parse_ip2nets (char **networksp, char *ip2nets)
+{
+	__u32     *ipaddrs;
+	int	nip = lnet_ipaddr_enumerate(&ipaddrs);
+	int	rc;
+
+	if (nip < 0) {
+		LCONSOLE_ERROR_MSG(0x117, "Error %d enumerating local IP "
+				   "interfaces for ip2nets to match\n", nip);
+		return nip;
+	}
+
+	if (nip == 0) {
+		LCONSOLE_ERROR_MSG(0x118, "No local IP interfaces "
+				   "for ip2nets to match\n");
+		return -ENOENT;
+	}
+
+	rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
+	lnet_ipaddr_free_enumeration(ipaddrs, nip);
+
+	if (rc < 0) {
+		LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc);
+		return rc;
+	}
+
+	if (rc == 0) {
+		LCONSOLE_ERROR_MSG(0x11a, "ip2nets does not match "
+				   "any local IP interfaces\n");
+		return -ENOENT;
+	}
+
+	return 0;
+}
+
+int
+lnet_set_ip_niaddr (lnet_ni_t *ni)
+{
+	__u32  net = LNET_NIDNET(ni->ni_nid);
+	char **names;
+	int    n;
+	__u32  ip;
+	__u32  netmask;
+	int    up;
+	int    i;
+	int    rc;
+
+	/* Convenience for LNDs that use the IP address of a local interface as
+	 * the local address part of their NID */
+
+	if (ni->ni_interfaces[0] != NULL) {
+
+		CLASSERT (LNET_MAX_INTERFACES > 1);
+
+		if (ni->ni_interfaces[1] != NULL) {
+			CERROR("Net %s doesn't support multiple interfaces\n",
+			       libcfs_net2str(net));
+			return -EPERM;
+		}
+
+		rc = libcfs_ipif_query(ni->ni_interfaces[0],
+				       &up, &ip, &netmask);
+		if (rc != 0) {
+			CERROR("Net %s can't query interface %s: %d\n",
+			       libcfs_net2str(net), ni->ni_interfaces[0], rc);
+			return -EPERM;
+		}
+
+		if (!up) {
+			CERROR("Net %s can't use interface %s: it's down\n",
+			       libcfs_net2str(net), ni->ni_interfaces[0]);
+			return -ENETDOWN;
+		}
+
+		ni->ni_nid = LNET_MKNID(net, ip);
+		return 0;
+	}
+
+	n = libcfs_ipif_enumerate(&names);
+	if (n <= 0) {
+		CERROR("Net %s can't enumerate interfaces: %d\n",
+		       libcfs_net2str(net), n);
+		return 0;
+	}
+
+	for (i = 0; i < n; i++) {
+		if (!strcmp(names[i], "lo")) /* skip the loopback IF */
+			continue;
+
+		rc = libcfs_ipif_query(names[i], &up, &ip, &netmask);
+
+		if (rc != 0) {
+			CWARN("Net %s can't query interface %s: %d\n",
+			      libcfs_net2str(net), names[i], rc);
+			continue;
+		}
+
+		if (!up) {
+			CWARN("Net %s ignoring interface %s (down)\n",
+			      libcfs_net2str(net), names[i]);
+			continue;
+		}
+
+		libcfs_ipif_free_enumeration(names, n);
+		ni->ni_nid = LNET_MKNID(net, ip);
+		return 0;
+	}
+
+	CERROR("Net %s can't find any interfaces\n", libcfs_net2str(net));
+	libcfs_ipif_free_enumeration(names, n);
+	return -ENOENT;
+}
+EXPORT_SYMBOL(lnet_set_ip_niaddr);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-eq.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-eq.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-eq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-eq.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,447 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/lnet/lib-eq.c
+ *
+ * Library level Event queue management routines
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+#include <linux/lnet/lib-lnet.h>
+
+/**
+ * Create an event queue that has room for \a count number of events.
+ *
+ * The event queue is circular and older events will be overwritten by new
+ * ones if they are not removed in time by the user using the functions
+ * LNetEQGet(), LNetEQWait(), or LNetEQPoll(). It is up to the user to
+ * determine the appropriate size of the event queue to prevent this loss
+ * of events. Note that when EQ handler is specified in \a callback, no
+ * event loss can happen, since the handler is run for each event deposited
+ * into the EQ.
+ *
+ * \param count The number of events to be stored in the event queue. It
+ * will be rounded up to the next power of two.
+ * \param callback A handler function that runs when an event is deposited
+ * into the EQ. The constant value LNET_EQ_HANDLER_NONE can be used to
+ * indicate that no event handler is desired.
+ * \param handle On successful return, this location will hold a handle for
+ * the newly created EQ.
+ *
+ * \retval 0       On success.
+ * \retval -EINVAL If an parameter is not valid.
+ * \retval -ENOMEM If memory for the EQ can't be allocated.
+ *
+ * \see lnet_eq_handler_t for the discussion on EQ handler semantics.
+ */
+int
+LNetEQAlloc(unsigned int count, lnet_eq_handler_t callback,
+	    lnet_handle_eq_t *handle)
+{
+	lnet_eq_t     *eq;
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (the_lnet.ln_refcount > 0);
+
+	/* We need count to be a power of 2 so that when eq_{enq,deq}_seq
+	 * overflow, they don't skip entries, so the queue has the same
+	 * apparent capacity at all times */
+
+	count = cfs_power2_roundup(count);
+
+	if (callback != LNET_EQ_HANDLER_NONE && count != 0) {
+		CWARN("EQ callback is guaranteed to get every event, "
+		      "do you still want to set eqcount %d for polling "
+		      "event which will have locking overhead? "
+		      "Please contact with developer to confirm\n", count);
+	}
+
+	/* count can be 0 if only need callback, we can eliminate
+	 * overhead of enqueue event */
+	if (count == 0 && callback == LNET_EQ_HANDLER_NONE)
+		return -EINVAL;
+
+	eq = lnet_eq_alloc();
+	if (eq == NULL)
+		return -ENOMEM;
+
+	if (count != 0) {
+		LIBCFS_ALLOC(eq->eq_events, count * sizeof(lnet_event_t));
+		if (eq->eq_events == NULL)
+			goto failed;
+		/* NB allocator has set all event sequence numbers to 0,
+		 * so all them should be earlier than eq_deq_seq */
+	}
+
+	eq->eq_deq_seq = 1;
+	eq->eq_enq_seq = 1;
+	eq->eq_size = count;
+	eq->eq_callback = callback;
+
+	eq->eq_refs = cfs_percpt_alloc(lnet_cpt_table(),
+				       sizeof(*eq->eq_refs[0]));
+	if (eq->eq_refs == NULL)
+		goto failed;
+
+	/* MUST hold both exclusive lnet_res_lock */
+	lnet_res_lock(LNET_LOCK_EX);
+	/* NB: hold lnet_eq_wait_lock for EQ link/unlink, so we can do
+	 * both EQ lookup and poll event with only lnet_eq_wait_lock */
+	lnet_eq_wait_lock();
+
+	lnet_res_lh_initialize(&the_lnet.ln_eq_container, &eq->eq_lh);
+	list_add(&eq->eq_list, &the_lnet.ln_eq_container.rec_active);
+
+	lnet_eq_wait_unlock();
+	lnet_res_unlock(LNET_LOCK_EX);
+
+	lnet_eq2handle(handle, eq);
+	return 0;
+
+failed:
+	if (eq->eq_events != NULL)
+		LIBCFS_FREE(eq->eq_events, count * sizeof(lnet_event_t));
+
+	if (eq->eq_refs != NULL)
+		cfs_percpt_free(eq->eq_refs);
+
+	lnet_eq_free(eq);
+	return -ENOMEM;
+}
+EXPORT_SYMBOL(LNetEQAlloc);
+
+/**
+ * Release the resources associated with an event queue if it's idle;
+ * otherwise do nothing and it's up to the user to try again.
+ *
+ * \param eqh A handle for the event queue to be released.
+ *
+ * \retval 0 If the EQ is not in use and freed.
+ * \retval -ENOENT If \a eqh does not point to a valid EQ.
+ * \retval -EBUSY  If the EQ is still in use by some MDs.
+ */
+int
+LNetEQFree(lnet_handle_eq_t eqh)
+{
+	struct lnet_eq	*eq;
+	lnet_event_t	*events = NULL;
+	int		**refs = NULL;
+	int		*ref;
+	int		rc = 0;
+	int		size = 0;
+	int		i;
+
+	LASSERT(the_lnet.ln_init);
+	LASSERT(the_lnet.ln_refcount > 0);
+
+	lnet_res_lock(LNET_LOCK_EX);
+	/* NB: hold lnet_eq_wait_lock for EQ link/unlink, so we can do
+	 * both EQ lookup and poll event with only lnet_eq_wait_lock */
+	lnet_eq_wait_lock();
+
+	eq = lnet_handle2eq(&eqh);
+	if (eq == NULL) {
+		rc = -ENOENT;
+		goto out;
+	}
+
+	cfs_percpt_for_each(ref, i, eq->eq_refs) {
+		LASSERT(*ref >= 0);
+		if (*ref == 0)
+			continue;
+
+		CDEBUG(D_NET, "Event equeue (%d: %d) busy on destroy.\n",
+		       i, *ref);
+		rc = -EBUSY;
+		goto out;
+	}
+
+	/* stash for free after lock dropped */
+	events	= eq->eq_events;
+	size	= eq->eq_size;
+	refs	= eq->eq_refs;
+
+	lnet_res_lh_invalidate(&eq->eq_lh);
+	list_del(&eq->eq_list);
+	lnet_eq_free_locked(eq);
+ out:
+	lnet_eq_wait_unlock();
+	lnet_res_unlock(LNET_LOCK_EX);
+
+	if (events != NULL)
+		LIBCFS_FREE(events, size * sizeof(lnet_event_t));
+	if (refs != NULL)
+		cfs_percpt_free(refs);
+
+	return rc;
+}
+EXPORT_SYMBOL(LNetEQFree);
+
+void
+lnet_eq_enqueue_event(lnet_eq_t *eq, lnet_event_t *ev)
+{
+	/* MUST called with resource lock hold but w/o lnet_eq_wait_lock */
+	int index;
+
+	if (eq->eq_size == 0) {
+		LASSERT(eq->eq_callback != LNET_EQ_HANDLER_NONE);
+		eq->eq_callback(ev);
+		return;
+	}
+
+	lnet_eq_wait_lock();
+	ev->sequence = eq->eq_enq_seq++;
+
+	LASSERT(eq->eq_size == LOWEST_BIT_SET(eq->eq_size));
+	index = ev->sequence & (eq->eq_size - 1);
+
+	eq->eq_events[index] = *ev;
+
+	if (eq->eq_callback != LNET_EQ_HANDLER_NONE)
+		eq->eq_callback(ev);
+
+	/* Wake anyone waiting in LNetEQPoll() */
+	if (waitqueue_active(&the_lnet.ln_eq_waitq))
+		wake_up_all(&the_lnet.ln_eq_waitq);
+	lnet_eq_wait_unlock();
+}
+
+int
+lnet_eq_dequeue_event(lnet_eq_t *eq, lnet_event_t *ev)
+{
+	int		new_index = eq->eq_deq_seq & (eq->eq_size - 1);
+	lnet_event_t	*new_event = &eq->eq_events[new_index];
+	int		rc;
+	ENTRY;
+
+	/* must called with lnet_eq_wait_lock hold */
+	if (LNET_SEQ_GT(eq->eq_deq_seq, new_event->sequence))
+		RETURN(0);
+
+	/* We've got a new event... */
+	*ev = *new_event;
+
+	CDEBUG(D_INFO, "event: %p, sequence: %lu, eq->size: %u\n",
+	       new_event, eq->eq_deq_seq, eq->eq_size);
+
+	/* ...but did it overwrite an event we've not seen yet? */
+	if (eq->eq_deq_seq == new_event->sequence) {
+		rc = 1;
+	} else {
+		/* don't complain with CERROR: some EQs are sized small
+		 * anyway; if it's important, the caller should complain */
+		CDEBUG(D_NET, "Event Queue Overflow: eq seq %lu ev seq %lu\n",
+		       eq->eq_deq_seq, new_event->sequence);
+		rc = -EOVERFLOW;
+	}
+
+	eq->eq_deq_seq = new_event->sequence + 1;
+	RETURN(rc);
+}
+
+/**
+ * A nonblocking function that can be used to get the next event in an EQ.
+ * If an event handler is associated with the EQ, the handler will run before
+ * this function returns successfully. The event is removed from the queue.
+ *
+ * \param eventq A handle for the event queue.
+ * \param event On successful return (1 or -EOVERFLOW), this location will
+ * hold the next event in the EQ.
+ *
+ * \retval 0	  No pending event in the EQ.
+ * \retval 1	  Indicates success.
+ * \retval -ENOENT    If \a eventq does not point to a valid EQ.
+ * \retval -EOVERFLOW Indicates success (i.e., an event is returned) and that
+ * at least one event between this event and the last event obtained from the
+ * EQ has been dropped due to limited space in the EQ.
+ */
+int
+LNetEQGet (lnet_handle_eq_t eventq, lnet_event_t *event)
+{
+	int which;
+
+	return LNetEQPoll(&eventq, 1, 0,
+			 event, &which);
+}
+EXPORT_SYMBOL(LNetEQGet);
+
+/**
+ * Block the calling process until there is an event in the EQ.
+ * If an event handler is associated with the EQ, the handler will run before
+ * this function returns successfully. This function returns the next event
+ * in the EQ and removes it from the EQ.
+ *
+ * \param eventq A handle for the event queue.
+ * \param event On successful return (1 or -EOVERFLOW), this location will
+ * hold the next event in the EQ.
+ *
+ * \retval 1	  Indicates success.
+ * \retval -ENOENT    If \a eventq does not point to a valid EQ.
+ * \retval -EOVERFLOW Indicates success (i.e., an event is returned) and that
+ * at least one event between this event and the last event obtained from the
+ * EQ has been dropped due to limited space in the EQ.
+ */
+int
+LNetEQWait (lnet_handle_eq_t eventq, lnet_event_t *event)
+{
+	int which;
+
+	return LNetEQPoll(&eventq, 1, LNET_TIME_FOREVER,
+			 event, &which);
+}
+EXPORT_SYMBOL(LNetEQWait);
+
+
+static int
+lnet_eq_wait_locked(int *timeout_ms)
+{
+	int		tms = *timeout_ms;
+	int		wait;
+	wait_queue_t  wl;
+	cfs_time_t      now;
+
+	if (tms == 0)
+		return -1; /* don't want to wait and no new event */
+
+	init_waitqueue_entry_current(&wl);
+	set_current_state(TASK_INTERRUPTIBLE);
+	add_wait_queue(&the_lnet.ln_eq_waitq, &wl);
+
+	lnet_eq_wait_unlock();
+
+	if (tms < 0) {
+		waitq_wait(&wl, TASK_INTERRUPTIBLE);
+
+	} else {
+		struct timeval tv;
+
+		now = cfs_time_current();
+		waitq_timedwait(&wl, TASK_INTERRUPTIBLE,
+				    cfs_time_seconds(tms) / 1000);
+		cfs_duration_usec(cfs_time_sub(cfs_time_current(), now), &tv);
+		tms -= (int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
+		if (tms < 0) /* no more wait but may have new event */
+			tms = 0;
+	}
+
+	wait = tms != 0; /* might need to call here again */
+	*timeout_ms = tms;
+
+	lnet_eq_wait_lock();
+	remove_wait_queue(&the_lnet.ln_eq_waitq, &wl);
+
+	return wait;
+}
+
+
+
+/**
+ * Block the calling process until there's an event from a set of EQs or
+ * timeout happens.
+ *
+ * If an event handler is associated with the EQ, the handler will run before
+ * this function returns successfully, in which case the corresponding event
+ * is consumed.
+ *
+ * LNetEQPoll() provides a timeout to allow applications to poll, block for a
+ * fixed period, or block indefinitely.
+ *
+ * \param eventqs,neq An array of EQ handles, and size of the array.
+ * \param timeout_ms Time in milliseconds to wait for an event to occur on
+ * one of the EQs. The constant LNET_TIME_FOREVER can be used to indicate an
+ * infinite timeout.
+ * \param event,which On successful return (1 or -EOVERFLOW), \a event will
+ * hold the next event in the EQs, and \a which will contain the index of the
+ * EQ from which the event was taken.
+ *
+ * \retval 0	  No pending event in the EQs after timeout.
+ * \retval 1	  Indicates success.
+ * \retval -EOVERFLOW Indicates success (i.e., an event is returned) and that
+ * at least one event between this event and the last event obtained from the
+ * EQ indicated by \a which has been dropped due to limited space in the EQ.
+ * \retval -ENOENT    If there's an invalid handle in \a eventqs.
+ */
+int
+LNetEQPoll(lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
+	   lnet_event_t *event, int *which)
+{
+	int	wait = 1;
+	int	rc;
+	int	i;
+	ENTRY;
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (the_lnet.ln_refcount > 0);
+
+	if (neq < 1)
+		RETURN(-ENOENT);
+
+	lnet_eq_wait_lock();
+
+	for (;;) {
+		for (i = 0; i < neq; i++) {
+			lnet_eq_t *eq = lnet_handle2eq(&eventqs[i]);
+
+			if (eq == NULL) {
+				lnet_eq_wait_unlock();
+				RETURN(-ENOENT);
+			}
+
+			rc = lnet_eq_dequeue_event(eq, event);
+			if (rc != 0) {
+				lnet_eq_wait_unlock();
+				*which = i;
+				RETURN(rc);
+			}
+		}
+
+		if (wait == 0)
+			break;
+
+		/*
+		 * return value of lnet_eq_wait_locked:
+		 * -1 : did nothing and it's sure no new event
+		 *  1 : sleep inside and wait until new event
+		 *  0 : don't want to wait anymore, but might have new event
+		 *      so need to call dequeue again
+		 */
+		wait = lnet_eq_wait_locked(&timeout_ms);
+		if (wait < 0) /* no new event */
+			break;
+	}
+
+	lnet_eq_wait_unlock();
+	RETURN(0);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-md.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-md.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-md.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-md.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,451 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/lnet/lib-md.c
+ *
+ * Memory Descriptor management routines
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include <linux/lnet/lib-lnet.h>
+
+/* must be called with lnet_res_lock held */
+void
+lnet_md_unlink(lnet_libmd_t *md)
+{
+	if ((md->md_flags & LNET_MD_FLAG_ZOMBIE) == 0) {
+		/* first unlink attempt... */
+		lnet_me_t *me = md->md_me;
+
+		md->md_flags |= LNET_MD_FLAG_ZOMBIE;
+
+		/* Disassociate from ME (if any), and unlink it if it was created
+		 * with LNET_UNLINK */
+		if (me != NULL) {
+			/* detach MD from portal */
+			lnet_ptl_detach_md(me, md);
+			if (me->me_unlink == LNET_UNLINK)
+				lnet_me_unlink(me);
+		}
+
+		/* ensure all future handle lookups fail */
+		lnet_res_lh_invalidate(&md->md_lh);
+	}
+
+	if (md->md_refcount != 0) {
+		CDEBUG(D_NET, "Queueing unlink of md %p\n", md);
+		return;
+	}
+
+	CDEBUG(D_NET, "Unlinking md %p\n", md);
+
+	if (md->md_eq != NULL) {
+		int	cpt = lnet_cpt_of_cookie(md->md_lh.lh_cookie);
+
+		LASSERT(*md->md_eq->eq_refs[cpt] > 0);
+		(*md->md_eq->eq_refs[cpt])--;
+	}
+
+	LASSERT(!list_empty(&md->md_list));
+	list_del_init(&md->md_list);
+	lnet_md_free_locked(md);
+}
+
+static int
+lnet_md_build(lnet_libmd_t *lmd, lnet_md_t *umd, int unlink)
+{
+	int	  i;
+	unsigned int niov;
+	int	  total_length = 0;
+
+	lmd->md_me = NULL;
+	lmd->md_start = umd->start;
+	lmd->md_offset = 0;
+	lmd->md_max_size = umd->max_size;
+	lmd->md_options = umd->options;
+	lmd->md_user_ptr = umd->user_ptr;
+	lmd->md_eq = NULL;
+	lmd->md_threshold = umd->threshold;
+	lmd->md_refcount = 0;
+	lmd->md_flags = (unlink == LNET_UNLINK) ? LNET_MD_FLAG_AUTO_UNLINK : 0;
+
+	if ((umd->options & LNET_MD_IOVEC) != 0) {
+
+		if ((umd->options & LNET_MD_KIOV) != 0) /* Can't specify both */
+			return -EINVAL;
+
+		lmd->md_niov = niov = umd->length;
+		memcpy(lmd->md_iov.iov, umd->start,
+		       niov * sizeof (lmd->md_iov.iov[0]));
+
+		for (i = 0; i < (int)niov; i++) {
+			/* We take the base address on trust */
+			if (lmd->md_iov.iov[i].iov_len <= 0) /* invalid length */
+				return -EINVAL;
+
+			total_length += lmd->md_iov.iov[i].iov_len;
+		}
+
+		lmd->md_length = total_length;
+
+		if ((umd->options & LNET_MD_MAX_SIZE) != 0 && /* max size used */
+		    (umd->max_size < 0 ||
+		     umd->max_size > total_length)) // illegal max_size
+			return -EINVAL;
+
+	} else if ((umd->options & LNET_MD_KIOV) != 0) {
+		lmd->md_niov = niov = umd->length;
+		memcpy(lmd->md_iov.kiov, umd->start,
+		       niov * sizeof (lmd->md_iov.kiov[0]));
+
+		for (i = 0; i < (int)niov; i++) {
+			/* We take the page pointer on trust */
+			if (lmd->md_iov.kiov[i].kiov_offset +
+			    lmd->md_iov.kiov[i].kiov_len > PAGE_CACHE_SIZE )
+				return -EINVAL; /* invalid length */
+
+			total_length += lmd->md_iov.kiov[i].kiov_len;
+		}
+
+		lmd->md_length = total_length;
+
+		if ((umd->options & LNET_MD_MAX_SIZE) != 0 && /* max size used */
+		    (umd->max_size < 0 ||
+		     umd->max_size > total_length)) // illegal max_size
+			return -EINVAL;
+	} else {   /* contiguous */
+		lmd->md_length = umd->length;
+		lmd->md_niov = niov = 1;
+		lmd->md_iov.iov[0].iov_base = umd->start;
+		lmd->md_iov.iov[0].iov_len = umd->length;
+
+		if ((umd->options & LNET_MD_MAX_SIZE) != 0 && /* max size used */
+		    (umd->max_size < 0 ||
+		     umd->max_size > (int)umd->length)) // illegal max_size
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* must be called with resource lock held */
+static int
+lnet_md_link(lnet_libmd_t *md, lnet_handle_eq_t eq_handle, int cpt)
+{
+	struct lnet_res_container *container = the_lnet.ln_md_containers[cpt];
+
+	/* NB we are passed an allocated, but inactive md.
+	 * if we return success, caller may lnet_md_unlink() it.
+	 * otherwise caller may only lnet_md_free() it.
+	 */
+	/* This implementation doesn't know how to create START events or
+	 * disable END events.  Best to LASSERT our caller is compliant so
+	 * we find out quickly...  */
+	/*  TODO - reevaluate what should be here in light of
+	 * the removal of the start and end events
+	 * maybe there we shouldn't even allow LNET_EQ_NONE!)
+	 * LASSERT (eq == NULL);
+	 */
+	if (!LNetHandleIsInvalid(eq_handle)) {
+		md->md_eq = lnet_handle2eq(&eq_handle);
+
+		if (md->md_eq == NULL)
+			return -ENOENT;
+
+		(*md->md_eq->eq_refs[cpt])++;
+	}
+
+	lnet_res_lh_initialize(container, &md->md_lh);
+
+	LASSERT(list_empty(&md->md_list));
+	list_add(&md->md_list, &container->rec_active);
+
+	return 0;
+}
+
+/* must be called with lnet_res_lock held */
+void
+lnet_md_deconstruct(lnet_libmd_t *lmd, lnet_md_t *umd)
+{
+	/* NB this doesn't copy out all the iov entries so when a
+	 * discontiguous MD is copied out, the target gets to know the
+	 * original iov pointer (in start) and the number of entries it had
+	 * and that's all.
+	 */
+	umd->start = lmd->md_start;
+	umd->length = ((lmd->md_options & (LNET_MD_IOVEC | LNET_MD_KIOV)) == 0) ?
+		      lmd->md_length : lmd->md_niov;
+	umd->threshold = lmd->md_threshold;
+	umd->max_size = lmd->md_max_size;
+	umd->options = lmd->md_options;
+	umd->user_ptr = lmd->md_user_ptr;
+	lnet_eq2handle(&umd->eq_handle, lmd->md_eq);
+}
+
+int
+lnet_md_validate(lnet_md_t *umd)
+{
+	if (umd->start == NULL && umd->length != 0) {
+		CERROR("MD start pointer can not be NULL with length %u\n",
+		       umd->length);
+		return -EINVAL;
+	}
+
+	if ((umd->options & (LNET_MD_KIOV | LNET_MD_IOVEC)) != 0 &&
+	    umd->length > LNET_MAX_IOV) {
+		CERROR("Invalid option: too many fragments %u, %d max\n",
+		       umd->length, LNET_MAX_IOV);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * Create a memory descriptor and attach it to a ME
+ *
+ * \param meh A handle for a ME to associate the new MD with.
+ * \param umd Provides initial values for the user-visible parts of a MD.
+ * Other than its use for initialization, there is no linkage between this
+ * structure and the MD maintained by the LNet.
+ * \param unlink A flag to indicate whether the MD is automatically unlinked
+ * when it becomes inactive, either because the operation threshold drops to
+ * zero or because the available memory becomes less than \a umd.max_size.
+ * (Note that the check for unlinking a MD only occurs after the completion
+ * of a successful operation on the MD.) The value LNET_UNLINK enables auto
+ * unlinking; the value LNET_RETAIN disables it.
+ * \param handle On successful returns, a handle to the newly created MD is
+ * saved here. This handle can be used later in LNetMDUnlink().
+ *
+ * \retval 0       On success.
+ * \retval -EINVAL If \a umd is not valid.
+ * \retval -ENOMEM If new MD cannot be allocated.
+ * \retval -ENOENT Either \a meh or \a umd.eq_handle does not point to a
+ * valid object. Note that it's OK to supply a NULL \a umd.eq_handle by
+ * calling LNetInvalidateHandle() on it.
+ * \retval -EBUSY  If the ME pointed to by \a meh is already associated with
+ * a MD.
+ */
+int
+LNetMDAttach(lnet_handle_me_t meh, lnet_md_t umd,
+	     lnet_unlink_t unlink, lnet_handle_md_t *handle)
+{
+	LIST_HEAD		(matches);
+	LIST_HEAD		(drops);
+	struct lnet_me		*me;
+	struct lnet_libmd	*md;
+	int			cpt;
+	int			rc;
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (the_lnet.ln_refcount > 0);
+
+	if (lnet_md_validate(&umd) != 0)
+		return -EINVAL;
+
+	if ((umd.options & (LNET_MD_OP_GET | LNET_MD_OP_PUT)) == 0) {
+		CERROR("Invalid option: no MD_OP set\n");
+		return -EINVAL;
+	}
+
+	md = lnet_md_alloc(&umd);
+	if (md == NULL)
+		return -ENOMEM;
+
+	rc = lnet_md_build(md, &umd, unlink);
+	cpt = lnet_cpt_of_cookie(meh.cookie);
+
+	lnet_res_lock(cpt);
+	if (rc != 0)
+		goto failed;
+
+	me = lnet_handle2me(&meh);
+	if (me == NULL)
+		rc = -ENOENT;
+	else if (me->me_md != NULL)
+		rc = -EBUSY;
+	else
+		rc = lnet_md_link(md, umd.eq_handle, cpt);
+
+	if (rc != 0)
+		goto failed;
+
+	/* attach this MD to portal of ME and check if it matches any
+	 * blocked msgs on this portal */
+	lnet_ptl_attach_md(me, md, &matches, &drops);
+
+	lnet_md2handle(handle, md);
+
+	lnet_res_unlock(cpt);
+
+	lnet_drop_delayed_msg_list(&drops, "Bad match");
+	lnet_recv_delayed_msg_list(&matches);
+
+	return 0;
+
+ failed:
+	lnet_md_free_locked(md);
+
+	lnet_res_unlock(cpt);
+	return rc;
+}
+EXPORT_SYMBOL(LNetMDAttach);
+
+/**
+ * Create a "free floating" memory descriptor - a MD that is not associated
+ * with a ME. Such MDs are usually used in LNetPut() and LNetGet() operations.
+ *
+ * \param umd,unlink See the discussion for LNetMDAttach().
+ * \param handle On successful returns, a handle to the newly created MD is
+ * saved here. This handle can be used later in LNetMDUnlink(), LNetPut(),
+ * and LNetGet() operations.
+ *
+ * \retval 0       On success.
+ * \retval -EINVAL If \a umd is not valid.
+ * \retval -ENOMEM If new MD cannot be allocated.
+ * \retval -ENOENT \a umd.eq_handle does not point to a valid EQ. Note that
+ * it's OK to supply a NULL \a umd.eq_handle by calling
+ * LNetInvalidateHandle() on it.
+ */
+int
+LNetMDBind(lnet_md_t umd, lnet_unlink_t unlink, lnet_handle_md_t *handle)
+{
+	lnet_libmd_t	*md;
+	int		cpt;
+	int		rc;
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (the_lnet.ln_refcount > 0);
+
+	if (lnet_md_validate(&umd) != 0)
+		return -EINVAL;
+
+	if ((umd.options & (LNET_MD_OP_GET | LNET_MD_OP_PUT)) != 0) {
+		CERROR("Invalid option: GET|PUT illegal on active MDs\n");
+		return -EINVAL;
+	}
+
+	md = lnet_md_alloc(&umd);
+	if (md == NULL)
+		return -ENOMEM;
+
+	rc = lnet_md_build(md, &umd, unlink);
+
+	cpt = lnet_res_lock_current();
+	if (rc != 0)
+		goto failed;
+
+	rc = lnet_md_link(md, umd.eq_handle, cpt);
+	if (rc != 0)
+		goto failed;
+
+	lnet_md2handle(handle, md);
+
+	lnet_res_unlock(cpt);
+	return 0;
+
+ failed:
+	lnet_md_free_locked(md);
+
+	lnet_res_unlock(cpt);
+	return rc;
+}
+EXPORT_SYMBOL(LNetMDBind);
+
+/**
+ * Unlink the memory descriptor from any ME it may be linked to and release
+ * the internal resources associated with it.
+ *
+ * This function does not free the memory region associated with the MD;
+ * i.e., the memory the user allocated for this MD. If the ME associated with
+ * this MD is not NULL and was created with auto unlink enabled, the ME is
+ * unlinked as well (see LNetMEAttach()).
+ *
+ * Explicitly unlinking a MD via this function call has the same behavior as
+ * a MD that has been automatically unlinked, except that no LNET_EVENT_UNLINK
+ * is generated in the latter case.
+ *
+ * An unlinked event can be reported in two ways:
+ * - If there's no pending operations on the MD, it's unlinked immediately
+ *   and an LNET_EVENT_UNLINK event is logged before this function returns.
+ * - Otherwise, the MD is only marked for deletion when this function
+ *   returns, and the unlinked event will be piggybacked on the event of
+ *   the completion of the last operation by setting the unlinked field of
+ *   the event. No dedicated LNET_EVENT_UNLINK event is generated.
+ *
+ * Note that in both cases the unlinked field of the event is always set; no
+ * more event will happen on the MD after such an event is logged.
+ *
+ * \param mdh A handle for the MD to be unlinked.
+ *
+ * \retval 0       On success.
+ * \retval -ENOENT If \a mdh does not point to a valid MD object.
+ */
+int
+LNetMDUnlink (lnet_handle_md_t mdh)
+{
+	lnet_event_t	ev;
+	lnet_libmd_t	*md;
+	int		cpt;
+
+	LASSERT(the_lnet.ln_init);
+	LASSERT(the_lnet.ln_refcount > 0);
+
+	cpt = lnet_cpt_of_cookie(mdh.cookie);
+	lnet_res_lock(cpt);
+
+	md = lnet_handle2md(&mdh);
+	if (md == NULL) {
+		lnet_res_unlock(cpt);
+		return -ENOENT;
+	}
+
+	/* If the MD is busy, lnet_md_unlink just marks it for deletion, and
+	 * when the NAL is done, the completion event flags that the MD was
+	 * unlinked.  Otherwise, we enqueue an event now... */
+
+	if (md->md_eq != NULL &&
+	    md->md_refcount == 0) {
+		lnet_build_unlink_event(md, &ev);
+		lnet_eq_enqueue_event(md->md_eq, &ev);
+	}
+
+	lnet_md_unlink(md);
+
+	lnet_res_unlock(cpt);
+	return 0;
+}
+EXPORT_SYMBOL(LNetMDUnlink);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-me.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-me.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-me.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-me.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,297 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/lnet/lib-me.c
+ *
+ * Match Entry management routines
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include <linux/lnet/lib-lnet.h>
+
+/**
+ * Create and attach a match entry to the match list of \a portal. The new
+ * ME is empty, i.e. not associated with a memory descriptor. LNetMDAttach()
+ * can be used to attach a MD to an empty ME.
+ *
+ * \param portal The portal table index where the ME should be attached.
+ * \param match_id Specifies the match criteria for the process ID of
+ * the requester. The constants LNET_PID_ANY and LNET_NID_ANY can be
+ * used to wildcard either of the identifiers in the lnet_process_id_t
+ * structure.
+ * \param match_bits,ignore_bits Specify the match criteria to apply
+ * to the match bits in the incoming request. The ignore bits are used
+ * to mask out insignificant bits in the incoming match bits. The resulting
+ * bits are then compared to the ME's match bits to determine if the
+ * incoming request meets the match criteria.
+ * \param unlink Indicates whether the ME should be unlinked when the memory
+ * descriptor associated with it is unlinked (Note that the check for
+ * unlinking a ME only occurs when the memory descriptor is unlinked.).
+ * Valid values are LNET_RETAIN and LNET_UNLINK.
+ * \param pos Indicates whether the new ME should be prepended or
+ * appended to the match list. Allowed constants: LNET_INS_BEFORE,
+ * LNET_INS_AFTER.
+ * \param handle On successful returns, a handle to the newly created ME
+ * object is saved here. This handle can be used later in LNetMEInsert(),
+ * LNetMEUnlink(), or LNetMDAttach() functions.
+ *
+ * \retval 0       On success.
+ * \retval -EINVAL If \a portal is invalid.
+ * \retval -ENOMEM If new ME object cannot be allocated.
+ */
+int
+LNetMEAttach(unsigned int portal,
+	     lnet_process_id_t match_id,
+	     __u64 match_bits, __u64 ignore_bits,
+	     lnet_unlink_t unlink, lnet_ins_pos_t pos,
+	     lnet_handle_me_t *handle)
+{
+	struct lnet_match_table *mtable;
+	struct lnet_me		*me;
+	struct list_head		*head;
+
+	LASSERT(the_lnet.ln_init);
+	LASSERT(the_lnet.ln_refcount > 0);
+
+	if ((int)portal >= the_lnet.ln_nportals)
+		return -EINVAL;
+
+	mtable = lnet_mt_of_attach(portal, match_id,
+				   match_bits, ignore_bits, pos);
+	if (mtable == NULL) /* can't match portal type */
+		return -EPERM;
+
+	me = lnet_me_alloc();
+	if (me == NULL)
+		return -ENOMEM;
+
+	lnet_res_lock(mtable->mt_cpt);
+
+	me->me_portal = portal;
+	me->me_match_id = match_id;
+	me->me_match_bits = match_bits;
+	me->me_ignore_bits = ignore_bits;
+	me->me_unlink = unlink;
+	me->me_md = NULL;
+
+	lnet_res_lh_initialize(the_lnet.ln_me_containers[mtable->mt_cpt],
+			       &me->me_lh);
+	if (ignore_bits != 0)
+		head = &mtable->mt_mhash[LNET_MT_HASH_IGNORE];
+	else
+		head = lnet_mt_match_head(mtable, match_id, match_bits);
+
+	me->me_pos = head - &mtable->mt_mhash[0];
+	if (pos == LNET_INS_AFTER || pos == LNET_INS_LOCAL)
+		list_add_tail(&me->me_list, head);
+	else
+		list_add(&me->me_list, head);
+
+	lnet_me2handle(handle, me);
+
+	lnet_res_unlock(mtable->mt_cpt);
+	return 0;
+}
+EXPORT_SYMBOL(LNetMEAttach);
+
+/**
+ * Create and a match entry and insert it before or after the ME pointed to by
+ * \a current_meh. The new ME is empty, i.e. not associated with a memory
+ * descriptor. LNetMDAttach() can be used to attach a MD to an empty ME.
+ *
+ * This function is identical to LNetMEAttach() except for the position
+ * where the new ME is inserted.
+ *
+ * \param current_meh A handle for a ME. The new ME will be inserted
+ * immediately before or immediately after this ME.
+ * \param match_id,match_bits,ignore_bits,unlink,pos,handle See the discussion
+ * for LNetMEAttach().
+ *
+ * \retval 0       On success.
+ * \retval -ENOMEM If new ME object cannot be allocated.
+ * \retval -ENOENT If \a current_meh does not point to a valid match entry.
+ */
+int
+LNetMEInsert(lnet_handle_me_t current_meh,
+	     lnet_process_id_t match_id,
+	     __u64 match_bits, __u64 ignore_bits,
+	     lnet_unlink_t unlink, lnet_ins_pos_t pos,
+	     lnet_handle_me_t *handle)
+{
+	struct lnet_me		*current_me;
+	struct lnet_me		*new_me;
+	struct lnet_portal	*ptl;
+	int			cpt;
+
+	LASSERT(the_lnet.ln_init);
+	LASSERT(the_lnet.ln_refcount > 0);
+
+	if (pos == LNET_INS_LOCAL)
+		return -EPERM;
+
+	new_me = lnet_me_alloc();
+	if (new_me == NULL)
+		return -ENOMEM;
+
+	cpt = lnet_cpt_of_cookie(current_meh.cookie);
+
+	lnet_res_lock(cpt);
+
+	current_me = lnet_handle2me(&current_meh);
+	if (current_me == NULL) {
+		lnet_me_free_locked(new_me);
+
+		lnet_res_unlock(cpt);
+		return -ENOENT;
+	}
+
+	LASSERT(current_me->me_portal < the_lnet.ln_nportals);
+
+	ptl = the_lnet.ln_portals[current_me->me_portal];
+	if (lnet_ptl_is_unique(ptl)) {
+		/* nosense to insertion on unique portal */
+		lnet_me_free_locked(new_me);
+		lnet_res_unlock(cpt);
+		return -EPERM;
+	}
+
+	new_me->me_pos = current_me->me_pos;
+	new_me->me_portal = current_me->me_portal;
+	new_me->me_match_id = match_id;
+	new_me->me_match_bits = match_bits;
+	new_me->me_ignore_bits = ignore_bits;
+	new_me->me_unlink = unlink;
+	new_me->me_md = NULL;
+
+	lnet_res_lh_initialize(the_lnet.ln_me_containers[cpt], &new_me->me_lh);
+
+	if (pos == LNET_INS_AFTER)
+		list_add(&new_me->me_list, &current_me->me_list);
+	else
+		list_add_tail(&new_me->me_list, &current_me->me_list);
+
+	lnet_me2handle(handle, new_me);
+
+	lnet_res_unlock(cpt);
+
+	return 0;
+}
+EXPORT_SYMBOL(LNetMEInsert);
+
+/**
+ * Unlink a match entry from its match list.
+ *
+ * This operation also releases any resources associated with the ME. If a
+ * memory descriptor is attached to the ME, then it will be unlinked as well
+ * and an unlink event will be generated. It is an error to use the ME handle
+ * after calling LNetMEUnlink().
+ *
+ * \param meh A handle for the ME to be unlinked.
+ *
+ * \retval 0       On success.
+ * \retval -ENOENT If \a meh does not point to a valid ME.
+ * \see LNetMDUnlink() for the discussion on delivering unlink event.
+ */
+int
+LNetMEUnlink(lnet_handle_me_t meh)
+{
+	lnet_me_t	*me;
+	lnet_libmd_t	*md;
+	lnet_event_t	ev;
+	int		cpt;
+
+	LASSERT(the_lnet.ln_init);
+	LASSERT(the_lnet.ln_refcount > 0);
+
+	cpt = lnet_cpt_of_cookie(meh.cookie);
+	lnet_res_lock(cpt);
+
+	me = lnet_handle2me(&meh);
+	if (me == NULL) {
+		lnet_res_unlock(cpt);
+		return -ENOENT;
+	}
+
+	md = me->me_md;
+	if (md != NULL &&
+	    md->md_eq != NULL &&
+	    md->md_refcount == 0) {
+		lnet_build_unlink_event(md, &ev);
+		lnet_eq_enqueue_event(md->md_eq, &ev);
+	}
+
+	lnet_me_unlink(me);
+
+	lnet_res_unlock(cpt);
+	return 0;
+}
+EXPORT_SYMBOL(LNetMEUnlink);
+
+/* call with lnet_res_lock please */
+void
+lnet_me_unlink(lnet_me_t *me)
+{
+	list_del(&me->me_list);
+
+	if (me->me_md != NULL) {
+		lnet_libmd_t *md = me->me_md;
+
+		/* detach MD from portal of this ME */
+		lnet_ptl_detach_md(me, md);
+		lnet_md_unlink(md);
+	}
+
+	lnet_res_lh_invalidate(&me->me_lh);
+	lnet_me_free_locked(me);
+}
+
+#if 0
+static void
+lib_me_dump(lnet_me_t *me)
+{
+	CWARN("Match Entry %p ("LPX64")\n", me,
+	      me->me_lh.lh_cookie);
+
+	CWARN("\tMatch/Ignore\t= %016lx / %016lx\n",
+	      me->me_match_bits, me->me_ignore_bits);
+
+	CWARN("\tMD\t= %p\n", me->md);
+	CWARN("\tprev\t= %p\n",
+	      list_entry(me->me_list.prev, lnet_me_t, me_list));
+	CWARN("\tnext\t= %p\n",
+	      list_entry(me->me_list.next, lnet_me_t, me_list));
+}
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-move.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-move.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-move.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-move.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2441 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/lnet/lib-move.c
+ *
+ * Data movement routines
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include <linux/lnet/lib-lnet.h>
+
+static int local_nid_dist_zero = 1;
+CFS_MODULE_PARM(local_nid_dist_zero, "i", int, 0444,
+		"Reserved");
+
+int
+lnet_fail_nid (lnet_nid_t nid, unsigned int threshold)
+{
+	lnet_test_peer_t  *tp;
+	struct list_head	*el;
+	struct list_head	*next;
+	struct list_head	 cull;
+
+	LASSERT (the_lnet.ln_init);
+
+	/* NB: use lnet_net_lock(0) to serialize operations on test peers */
+	if (threshold != 0) {
+		/* Adding a new entry */
+		LIBCFS_ALLOC(tp, sizeof(*tp));
+		if (tp == NULL)
+			return -ENOMEM;
+
+		tp->tp_nid = nid;
+		tp->tp_threshold = threshold;
+
+		lnet_net_lock(0);
+		list_add_tail(&tp->tp_list, &the_lnet.ln_test_peers);
+		lnet_net_unlock(0);
+		return 0;
+	}
+
+	/* removing entries */
+	INIT_LIST_HEAD(&cull);
+
+	lnet_net_lock(0);
+
+	list_for_each_safe (el, next, &the_lnet.ln_test_peers) {
+		tp = list_entry (el, lnet_test_peer_t, tp_list);
+
+		if (tp->tp_threshold == 0 ||    /* needs culling anyway */
+		    nid == LNET_NID_ANY ||       /* removing all entries */
+		    tp->tp_nid == nid)	  /* matched this one */
+		{
+			list_del (&tp->tp_list);
+			list_add (&tp->tp_list, &cull);
+		}
+	}
+
+	lnet_net_unlock(0);
+
+	while (!list_empty (&cull)) {
+		tp = list_entry (cull.next, lnet_test_peer_t, tp_list);
+
+		list_del (&tp->tp_list);
+		LIBCFS_FREE(tp, sizeof (*tp));
+	}
+	return 0;
+}
+
+static int
+fail_peer (lnet_nid_t nid, int outgoing)
+{
+	lnet_test_peer_t *tp;
+	struct list_head       *el;
+	struct list_head       *next;
+	struct list_head	cull;
+	int	       fail = 0;
+
+	INIT_LIST_HEAD (&cull);
+
+	/* NB: use lnet_net_lock(0) to serialize operations on test peers */
+	lnet_net_lock(0);
+
+	list_for_each_safe (el, next, &the_lnet.ln_test_peers) {
+		tp = list_entry (el, lnet_test_peer_t, tp_list);
+
+		if (tp->tp_threshold == 0) {
+			/* zombie entry */
+			if (outgoing) {
+				/* only cull zombies on outgoing tests,
+				 * since we may be at interrupt priority on
+				 * incoming messages. */
+				list_del (&tp->tp_list);
+				list_add (&tp->tp_list, &cull);
+			}
+			continue;
+		}
+
+		if (tp->tp_nid == LNET_NID_ANY || /* fail every peer */
+		    nid == tp->tp_nid) {	/* fail this peer */
+			fail = 1;
+
+			if (tp->tp_threshold != LNET_MD_THRESH_INF) {
+				tp->tp_threshold--;
+				if (outgoing &&
+				    tp->tp_threshold == 0) {
+					/* see above */
+					list_del (&tp->tp_list);
+					list_add (&tp->tp_list, &cull);
+				}
+			}
+			break;
+		}
+	}
+
+	lnet_net_unlock(0);
+
+	while (!list_empty (&cull)) {
+		tp = list_entry (cull.next, lnet_test_peer_t, tp_list);
+		list_del (&tp->tp_list);
+
+		LIBCFS_FREE(tp, sizeof (*tp));
+	}
+
+	return (fail);
+}
+
+unsigned int
+lnet_iov_nob (unsigned int niov, struct iovec *iov)
+{
+	unsigned int nob = 0;
+
+	while (niov-- > 0)
+		nob += (iov++)->iov_len;
+
+	return (nob);
+}
+EXPORT_SYMBOL(lnet_iov_nob);
+
+void
+lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov, unsigned int doffset,
+		   unsigned int nsiov, struct iovec *siov, unsigned int soffset,
+		   unsigned int nob)
+{
+	/* NB diov, siov are READ-ONLY */
+	unsigned int  this_nob;
+
+	if (nob == 0)
+		return;
+
+	/* skip complete frags before 'doffset' */
+	LASSERT (ndiov > 0);
+	while (doffset >= diov->iov_len) {
+		doffset -= diov->iov_len;
+		diov++;
+		ndiov--;
+		LASSERT (ndiov > 0);
+	}
+
+	/* skip complete frags before 'soffset' */
+	LASSERT (nsiov > 0);
+	while (soffset >= siov->iov_len) {
+		soffset -= siov->iov_len;
+		siov++;
+		nsiov--;
+		LASSERT (nsiov > 0);
+	}
+
+	do {
+		LASSERT (ndiov > 0);
+		LASSERT (nsiov > 0);
+		this_nob = MIN(diov->iov_len - doffset,
+			       siov->iov_len - soffset);
+		this_nob = MIN(this_nob, nob);
+
+		memcpy ((char *)diov->iov_base + doffset,
+			(char *)siov->iov_base + soffset, this_nob);
+		nob -= this_nob;
+
+		if (diov->iov_len > doffset + this_nob) {
+			doffset += this_nob;
+		} else {
+			diov++;
+			ndiov--;
+			doffset = 0;
+		}
+
+		if (siov->iov_len > soffset + this_nob) {
+			soffset += this_nob;
+		} else {
+			siov++;
+			nsiov--;
+			soffset = 0;
+		}
+	} while (nob > 0);
+}
+EXPORT_SYMBOL(lnet_copy_iov2iov);
+
+int
+lnet_extract_iov (int dst_niov, struct iovec *dst,
+		  int src_niov, struct iovec *src,
+		  unsigned int offset, unsigned int len)
+{
+	/* Initialise 'dst' to the subset of 'src' starting at 'offset',
+	 * for exactly 'len' bytes, and return the number of entries.
+	 * NB not destructive to 'src' */
+	unsigned int    frag_len;
+	unsigned int    niov;
+
+	if (len == 0)			   /* no data => */
+		return (0);		     /* no frags */
+
+	LASSERT (src_niov > 0);
+	while (offset >= src->iov_len) {      /* skip initial frags */
+		offset -= src->iov_len;
+		src_niov--;
+		src++;
+		LASSERT (src_niov > 0);
+	}
+
+	niov = 1;
+	for (;;) {
+		LASSERT (src_niov > 0);
+		LASSERT ((int)niov <= dst_niov);
+
+		frag_len = src->iov_len - offset;
+		dst->iov_base = ((char *)src->iov_base) + offset;
+
+		if (len <= frag_len) {
+			dst->iov_len = len;
+			return (niov);
+		}
+
+		dst->iov_len = frag_len;
+
+		len -= frag_len;
+		dst++;
+		src++;
+		niov++;
+		src_niov--;
+		offset = 0;
+	}
+}
+EXPORT_SYMBOL(lnet_extract_iov);
+
+
+unsigned int
+lnet_kiov_nob (unsigned int niov, lnet_kiov_t *kiov)
+{
+	unsigned int  nob = 0;
+
+	while (niov-- > 0)
+		nob += (kiov++)->kiov_len;
+
+	return (nob);
+}
+EXPORT_SYMBOL(lnet_kiov_nob);
+
+void
+lnet_copy_kiov2kiov (unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
+		     unsigned int nsiov, lnet_kiov_t *siov, unsigned int soffset,
+		     unsigned int nob)
+{
+	/* NB diov, siov are READ-ONLY */
+	unsigned int    this_nob;
+	char	   *daddr = NULL;
+	char	   *saddr = NULL;
+
+	if (nob == 0)
+		return;
+
+	LASSERT (!in_interrupt ());
+
+	LASSERT (ndiov > 0);
+	while (doffset >= diov->kiov_len) {
+		doffset -= diov->kiov_len;
+		diov++;
+		ndiov--;
+		LASSERT (ndiov > 0);
+	}
+
+	LASSERT (nsiov > 0);
+	while (soffset >= siov->kiov_len) {
+		soffset -= siov->kiov_len;
+		siov++;
+		nsiov--;
+		LASSERT (nsiov > 0);
+	}
+
+	do {
+		LASSERT (ndiov > 0);
+		LASSERT (nsiov > 0);
+		this_nob = MIN(diov->kiov_len - doffset,
+			       siov->kiov_len - soffset);
+		this_nob = MIN(this_nob, nob);
+
+		if (daddr == NULL)
+			daddr = ((char *)kmap(diov->kiov_page)) +
+				diov->kiov_offset + doffset;
+		if (saddr == NULL)
+			saddr = ((char *)kmap(siov->kiov_page)) +
+				siov->kiov_offset + soffset;
+
+		/* Vanishing risk of kmap deadlock when mapping 2 pages.
+		 * However in practice at least one of the kiovs will be mapped
+		 * kernel pages and the map/unmap will be NOOPs */
+
+		memcpy (daddr, saddr, this_nob);
+		nob -= this_nob;
+
+		if (diov->kiov_len > doffset + this_nob) {
+			daddr += this_nob;
+			doffset += this_nob;
+		} else {
+			kunmap(diov->kiov_page);
+			daddr = NULL;
+			diov++;
+			ndiov--;
+			doffset = 0;
+		}
+
+		if (siov->kiov_len > soffset + this_nob) {
+			saddr += this_nob;
+			soffset += this_nob;
+		} else {
+			kunmap(siov->kiov_page);
+			saddr = NULL;
+			siov++;
+			nsiov--;
+			soffset = 0;
+		}
+	} while (nob > 0);
+
+	if (daddr != NULL)
+		kunmap(diov->kiov_page);
+	if (saddr != NULL)
+		kunmap(siov->kiov_page);
+}
+EXPORT_SYMBOL(lnet_copy_kiov2kiov);
+
+void
+lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov, unsigned int iovoffset,
+		    unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffset,
+		    unsigned int nob)
+{
+	/* NB iov, kiov are READ-ONLY */
+	unsigned int    this_nob;
+	char	   *addr = NULL;
+
+	if (nob == 0)
+		return;
+
+	LASSERT (!in_interrupt ());
+
+	LASSERT (niov > 0);
+	while (iovoffset >= iov->iov_len) {
+		iovoffset -= iov->iov_len;
+		iov++;
+		niov--;
+		LASSERT (niov > 0);
+	}
+
+	LASSERT (nkiov > 0);
+	while (kiovoffset >= kiov->kiov_len) {
+		kiovoffset -= kiov->kiov_len;
+		kiov++;
+		nkiov--;
+		LASSERT (nkiov > 0);
+	}
+
+	do {
+		LASSERT (niov > 0);
+		LASSERT (nkiov > 0);
+		this_nob = MIN(iov->iov_len - iovoffset,
+			       kiov->kiov_len - kiovoffset);
+		this_nob = MIN(this_nob, nob);
+
+		if (addr == NULL)
+			addr = ((char *)kmap(kiov->kiov_page)) +
+				kiov->kiov_offset + kiovoffset;
+
+		memcpy ((char *)iov->iov_base + iovoffset, addr, this_nob);
+		nob -= this_nob;
+
+		if (iov->iov_len > iovoffset + this_nob) {
+			iovoffset += this_nob;
+		} else {
+			iov++;
+			niov--;
+			iovoffset = 0;
+		}
+
+		if (kiov->kiov_len > kiovoffset + this_nob) {
+			addr += this_nob;
+			kiovoffset += this_nob;
+		} else {
+			kunmap(kiov->kiov_page);
+			addr = NULL;
+			kiov++;
+			nkiov--;
+			kiovoffset = 0;
+		}
+
+	} while (nob > 0);
+
+	if (addr != NULL)
+		kunmap(kiov->kiov_page);
+}
+EXPORT_SYMBOL(lnet_copy_kiov2iov);
+
+void
+lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffset,
+		    unsigned int niov, struct iovec *iov, unsigned int iovoffset,
+		    unsigned int nob)
+{
+	/* NB kiov, iov are READ-ONLY */
+	unsigned int    this_nob;
+	char	   *addr = NULL;
+
+	if (nob == 0)
+		return;
+
+	LASSERT (!in_interrupt ());
+
+	LASSERT (nkiov > 0);
+	while (kiovoffset >= kiov->kiov_len) {
+		kiovoffset -= kiov->kiov_len;
+		kiov++;
+		nkiov--;
+		LASSERT (nkiov > 0);
+	}
+
+	LASSERT (niov > 0);
+	while (iovoffset >= iov->iov_len) {
+		iovoffset -= iov->iov_len;
+		iov++;
+		niov--;
+		LASSERT (niov > 0);
+	}
+
+	do {
+		LASSERT (nkiov > 0);
+		LASSERT (niov > 0);
+		this_nob = MIN(kiov->kiov_len - kiovoffset,
+			       iov->iov_len - iovoffset);
+		this_nob = MIN(this_nob, nob);
+
+		if (addr == NULL)
+			addr = ((char *)kmap(kiov->kiov_page)) +
+				kiov->kiov_offset + kiovoffset;
+
+		memcpy (addr, (char *)iov->iov_base + iovoffset, this_nob);
+		nob -= this_nob;
+
+		if (kiov->kiov_len > kiovoffset + this_nob) {
+			addr += this_nob;
+			kiovoffset += this_nob;
+		} else {
+			kunmap(kiov->kiov_page);
+			addr = NULL;
+			kiov++;
+			nkiov--;
+			kiovoffset = 0;
+		}
+
+		if (iov->iov_len > iovoffset + this_nob) {
+			iovoffset += this_nob;
+		} else {
+			iov++;
+			niov--;
+			iovoffset = 0;
+		}
+	} while (nob > 0);
+
+	if (addr != NULL)
+		kunmap(kiov->kiov_page);
+}
+EXPORT_SYMBOL(lnet_copy_iov2kiov);
+
+int
+lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
+		   int src_niov, lnet_kiov_t *src,
+		   unsigned int offset, unsigned int len)
+{
+	/* Initialise 'dst' to the subset of 'src' starting at 'offset',
+	 * for exactly 'len' bytes, and return the number of entries.
+	 * NB not destructive to 'src' */
+	unsigned int    frag_len;
+	unsigned int    niov;
+
+	if (len == 0)			   /* no data => */
+		return (0);		     /* no frags */
+
+	LASSERT (src_niov > 0);
+	while (offset >= src->kiov_len) {      /* skip initial frags */
+		offset -= src->kiov_len;
+		src_niov--;
+		src++;
+		LASSERT (src_niov > 0);
+	}
+
+	niov = 1;
+	for (;;) {
+		LASSERT (src_niov > 0);
+		LASSERT ((int)niov <= dst_niov);
+
+		frag_len = src->kiov_len - offset;
+		dst->kiov_page = src->kiov_page;
+		dst->kiov_offset = src->kiov_offset + offset;
+
+		if (len <= frag_len) {
+			dst->kiov_len = len;
+			LASSERT (dst->kiov_offset + dst->kiov_len <= PAGE_CACHE_SIZE);
+			return (niov);
+		}
+
+		dst->kiov_len = frag_len;
+		LASSERT (dst->kiov_offset + dst->kiov_len <= PAGE_CACHE_SIZE);
+
+		len -= frag_len;
+		dst++;
+		src++;
+		niov++;
+		src_niov--;
+		offset = 0;
+	}
+}
+EXPORT_SYMBOL(lnet_extract_kiov);
+
+void
+lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
+	     unsigned int offset, unsigned int mlen, unsigned int rlen)
+{
+	unsigned int  niov = 0;
+	struct iovec *iov = NULL;
+	lnet_kiov_t  *kiov = NULL;
+	int	   rc;
+
+	LASSERT (!in_interrupt ());
+	LASSERT (mlen == 0 || msg != NULL);
+
+	if (msg != NULL) {
+		LASSERT(msg->msg_receiving);
+		LASSERT(!msg->msg_sending);
+		LASSERT(rlen == msg->msg_len);
+		LASSERT(mlen <= msg->msg_len);
+		LASSERT(msg->msg_offset == offset);
+		LASSERT(msg->msg_wanted == mlen);
+
+		msg->msg_receiving = 0;
+
+		if (mlen != 0) {
+			niov = msg->msg_niov;
+			iov  = msg->msg_iov;
+			kiov = msg->msg_kiov;
+
+			LASSERT (niov > 0);
+			LASSERT ((iov == NULL) != (kiov == NULL));
+		}
+	}
+
+	rc = (ni->ni_lnd->lnd_recv)(ni, private, msg, delayed,
+				    niov, iov, kiov, offset, mlen, rlen);
+	if (rc < 0)
+		lnet_finalize(ni, msg, rc);
+}
+
+void
+lnet_setpayloadbuffer(lnet_msg_t *msg)
+{
+	lnet_libmd_t *md = msg->msg_md;
+
+	LASSERT (msg->msg_len > 0);
+	LASSERT (!msg->msg_routing);
+	LASSERT (md != NULL);
+	LASSERT (msg->msg_niov == 0);
+	LASSERT (msg->msg_iov == NULL);
+	LASSERT (msg->msg_kiov == NULL);
+
+	msg->msg_niov = md->md_niov;
+	if ((md->md_options & LNET_MD_KIOV) != 0)
+		msg->msg_kiov = md->md_iov.kiov;
+	else
+		msg->msg_iov = md->md_iov.iov;
+}
+
+void
+lnet_prep_send(lnet_msg_t *msg, int type, lnet_process_id_t target,
+	       unsigned int offset, unsigned int len)
+{
+	msg->msg_type = type;
+	msg->msg_target = target;
+	msg->msg_len = len;
+	msg->msg_offset = offset;
+
+	if (len != 0)
+		lnet_setpayloadbuffer(msg);
+
+	memset (&msg->msg_hdr, 0, sizeof (msg->msg_hdr));
+	msg->msg_hdr.type	   = cpu_to_le32(type);
+	msg->msg_hdr.dest_nid       = cpu_to_le64(target.nid);
+	msg->msg_hdr.dest_pid       = cpu_to_le32(target.pid);
+	/* src_nid will be set later */
+	msg->msg_hdr.src_pid	= cpu_to_le32(the_lnet.ln_pid);
+	msg->msg_hdr.payload_length = cpu_to_le32(len);
+}
+
+void
+lnet_ni_send(lnet_ni_t *ni, lnet_msg_t *msg)
+{
+	void   *priv = msg->msg_private;
+	int     rc;
+
+	LASSERT (!in_interrupt ());
+	LASSERT (LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND ||
+		 (msg->msg_txcredit && msg->msg_peertxcredit));
+
+	rc = (ni->ni_lnd->lnd_send)(ni, priv, msg);
+	if (rc < 0)
+		lnet_finalize(ni, msg, rc);
+}
+
+int
+lnet_ni_eager_recv(lnet_ni_t *ni, lnet_msg_t *msg)
+{
+	int	rc;
+
+	LASSERT(!msg->msg_sending);
+	LASSERT(msg->msg_receiving);
+	LASSERT(!msg->msg_rx_ready_delay);
+	LASSERT(ni->ni_lnd->lnd_eager_recv != NULL);
+
+	msg->msg_rx_ready_delay = 1;
+	rc = (ni->ni_lnd->lnd_eager_recv)(ni, msg->msg_private, msg,
+					  &msg->msg_private);
+	if (rc != 0) {
+		CERROR("recv from %s / send to %s aborted: "
+		       "eager_recv failed %d\n",
+		       libcfs_nid2str(msg->msg_rxpeer->lp_nid),
+		       libcfs_id2str(msg->msg_target), rc);
+		LASSERT(rc < 0); /* required by my callers */
+	}
+
+	return rc;
+}
+
+/* NB: caller shall hold a ref on 'lp' as I'd drop lnet_net_lock */
+void
+lnet_ni_query_locked(lnet_ni_t *ni, lnet_peer_t *lp)
+{
+	cfs_time_t last_alive = 0;
+
+	LASSERT(lnet_peer_aliveness_enabled(lp));
+	LASSERT(ni->ni_lnd->lnd_query != NULL);
+
+	lnet_net_unlock(lp->lp_cpt);
+	(ni->ni_lnd->lnd_query)(ni, lp->lp_nid, &last_alive);
+	lnet_net_lock(lp->lp_cpt);
+
+	lp->lp_last_query = cfs_time_current();
+
+	if (last_alive != 0) /* NI has updated timestamp */
+		lp->lp_last_alive = last_alive;
+}
+
+/* NB: always called with lnet_net_lock held */
+static inline int
+lnet_peer_is_alive (lnet_peer_t *lp, cfs_time_t now)
+{
+	int	alive;
+	cfs_time_t deadline;
+
+	LASSERT (lnet_peer_aliveness_enabled(lp));
+
+	/* Trust lnet_notify() if it has more recent aliveness news, but
+	 * ignore the initial assumed death (see lnet_peers_start_down()).
+	 */
+	if (!lp->lp_alive && lp->lp_alive_count > 0 &&
+	    cfs_time_aftereq(lp->lp_timestamp, lp->lp_last_alive))
+		return 0;
+
+	deadline = cfs_time_add(lp->lp_last_alive,
+				cfs_time_seconds(lp->lp_ni->ni_peertimeout));
+	alive = cfs_time_after(deadline, now);
+
+	/* Update obsolete lp_alive except for routers assumed to be dead
+	 * initially, because router checker would update aliveness in this
+	 * case, and moreover lp_last_alive at peer creation is assumed.
+	 */
+	if (alive && !lp->lp_alive &&
+	    !(lnet_isrouter(lp) && lp->lp_alive_count == 0))
+		lnet_notify_locked(lp, 0, 1, lp->lp_last_alive);
+
+	return alive;
+}
+
+
+/* NB: returns 1 when alive, 0 when dead, negative when error;
+ *     may drop the lnet_net_lock */
+int
+lnet_peer_alive_locked (lnet_peer_t *lp)
+{
+	cfs_time_t now = cfs_time_current();
+
+	if (!lnet_peer_aliveness_enabled(lp))
+		return -ENODEV;
+
+	if (lnet_peer_is_alive(lp, now))
+		return 1;
+
+	/* Peer appears dead, but we should avoid frequent NI queries (at
+	 * most once per lnet_queryinterval seconds). */
+	if (lp->lp_last_query != 0) {
+		static const int lnet_queryinterval = 1;
+
+		cfs_time_t next_query =
+			   cfs_time_add(lp->lp_last_query,
+					cfs_time_seconds(lnet_queryinterval));
+
+		if (cfs_time_before(now, next_query)) {
+			if (lp->lp_alive)
+				CWARN("Unexpected aliveness of peer %s: "
+				      "%d < %d (%d/%d)\n",
+				      libcfs_nid2str(lp->lp_nid),
+				      (int)now, (int)next_query,
+				      lnet_queryinterval,
+				      lp->lp_ni->ni_peertimeout);
+			return 0;
+		}
+	}
+
+	/* query NI for latest aliveness news */
+	lnet_ni_query_locked(lp->lp_ni, lp);
+
+	if (lnet_peer_is_alive(lp, now))
+		return 1;
+
+	lnet_notify_locked(lp, 0, 0, lp->lp_last_alive);
+	return 0;
+}
+
+int
+lnet_post_send_locked(lnet_msg_t *msg, int do_send)
+{
+	/* lnet_send is going to lnet_net_unlock immediately after this,
+	 * so it sets do_send FALSE and I don't do the unlock/send/lock bit.
+	 * I return EAGAIN if msg blocked, EHOSTUNREACH if msg_txpeer
+	 * appears dead, and 0 if sent or OK to send */
+	struct lnet_peer	*lp = msg->msg_txpeer;
+	struct lnet_ni		*ni = lp->lp_ni;
+	struct lnet_tx_queue	*tq;
+	int			cpt;
+
+	/* non-lnet_send() callers have checked before */
+	LASSERT(!do_send || msg->msg_tx_delayed);
+	LASSERT(!msg->msg_receiving);
+	LASSERT(msg->msg_tx_committed);
+
+	cpt = msg->msg_tx_cpt;
+	tq = ni->ni_tx_queues[cpt];
+
+	/* NB 'lp' is always the next hop */
+	if ((msg->msg_target.pid & LNET_PID_USERFLAG) == 0 &&
+	    lnet_peer_alive_locked(lp) == 0) {
+		the_lnet.ln_counters[cpt]->drop_count++;
+		the_lnet.ln_counters[cpt]->drop_length += msg->msg_len;
+		lnet_net_unlock(cpt);
+
+		CNETERR("Dropping message for %s: peer not alive\n",
+			libcfs_id2str(msg->msg_target));
+		if (do_send)
+			lnet_finalize(ni, msg, -EHOSTUNREACH);
+
+		lnet_net_lock(cpt);
+		return EHOSTUNREACH;
+	}
+
+	if (!msg->msg_peertxcredit) {
+		LASSERT ((lp->lp_txcredits < 0) ==
+			 !list_empty(&lp->lp_txq));
+
+		msg->msg_peertxcredit = 1;
+		lp->lp_txqnob += msg->msg_len + sizeof(lnet_hdr_t);
+		lp->lp_txcredits--;
+
+		if (lp->lp_txcredits < lp->lp_mintxcredits)
+			lp->lp_mintxcredits = lp->lp_txcredits;
+
+		if (lp->lp_txcredits < 0) {
+			msg->msg_tx_delayed = 1;
+			list_add_tail(&msg->msg_list, &lp->lp_txq);
+			return EAGAIN;
+		}
+	}
+
+	if (!msg->msg_txcredit) {
+		LASSERT((tq->tq_credits < 0) ==
+			!list_empty(&tq->tq_delayed));
+
+		msg->msg_txcredit = 1;
+		tq->tq_credits--;
+
+		if (tq->tq_credits < tq->tq_credits_min)
+			tq->tq_credits_min = tq->tq_credits;
+
+		if (tq->tq_credits < 0) {
+			msg->msg_tx_delayed = 1;
+			list_add_tail(&msg->msg_list, &tq->tq_delayed);
+			return EAGAIN;
+		}
+	}
+
+	if (do_send) {
+		lnet_net_unlock(cpt);
+		lnet_ni_send(ni, msg);
+		lnet_net_lock(cpt);
+	}
+	return 0;
+}
+
+
+lnet_rtrbufpool_t *
+lnet_msg2bufpool(lnet_msg_t *msg)
+{
+	lnet_rtrbufpool_t	*rbp;
+	int			cpt;
+
+	LASSERT(msg->msg_rx_committed);
+
+	cpt = msg->msg_rx_cpt;
+	rbp = &the_lnet.ln_rtrpools[cpt][0];
+
+	LASSERT(msg->msg_len <= LNET_MTU);
+	while (msg->msg_len > (unsigned int)rbp->rbp_npages * PAGE_CACHE_SIZE) {
+		rbp++;
+		LASSERT(rbp < &the_lnet.ln_rtrpools[cpt][LNET_NRBPOOLS]);
+	}
+
+	return rbp;
+}
+
+int
+lnet_post_routed_recv_locked (lnet_msg_t *msg, int do_recv)
+{
+	/* lnet_parse is going to lnet_net_unlock immediately after this, so it
+	 * sets do_recv FALSE and I don't do the unlock/send/lock bit.  I
+	 * return EAGAIN if msg blocked and 0 if received or OK to receive */
+	lnet_peer_t	 *lp = msg->msg_rxpeer;
+	lnet_rtrbufpool_t   *rbp;
+	lnet_rtrbuf_t       *rb;
+
+	LASSERT (msg->msg_iov == NULL);
+	LASSERT (msg->msg_kiov == NULL);
+	LASSERT (msg->msg_niov == 0);
+	LASSERT (msg->msg_routing);
+	LASSERT (msg->msg_receiving);
+	LASSERT (!msg->msg_sending);
+
+	/* non-lnet_parse callers only receive delayed messages */
+	LASSERT(!do_recv || msg->msg_rx_delayed);
+
+	if (!msg->msg_peerrtrcredit) {
+		LASSERT ((lp->lp_rtrcredits < 0) ==
+			 !list_empty(&lp->lp_rtrq));
+
+		msg->msg_peerrtrcredit = 1;
+		lp->lp_rtrcredits--;
+		if (lp->lp_rtrcredits < lp->lp_minrtrcredits)
+			lp->lp_minrtrcredits = lp->lp_rtrcredits;
+
+		if (lp->lp_rtrcredits < 0) {
+			/* must have checked eager_recv before here */
+			LASSERT(msg->msg_rx_ready_delay);
+			msg->msg_rx_delayed = 1;
+			list_add_tail(&msg->msg_list, &lp->lp_rtrq);
+			return EAGAIN;
+		}
+	}
+
+	rbp = lnet_msg2bufpool(msg);
+
+	if (!msg->msg_rtrcredit) {
+		LASSERT ((rbp->rbp_credits < 0) ==
+			 !list_empty(&rbp->rbp_msgs));
+
+		msg->msg_rtrcredit = 1;
+		rbp->rbp_credits--;
+		if (rbp->rbp_credits < rbp->rbp_mincredits)
+			rbp->rbp_mincredits = rbp->rbp_credits;
+
+		if (rbp->rbp_credits < 0) {
+			/* must have checked eager_recv before here */
+			LASSERT(msg->msg_rx_ready_delay);
+			msg->msg_rx_delayed = 1;
+			list_add_tail(&msg->msg_list, &rbp->rbp_msgs);
+			return EAGAIN;
+		}
+	}
+
+	LASSERT (!list_empty(&rbp->rbp_bufs));
+	rb = list_entry(rbp->rbp_bufs.next, lnet_rtrbuf_t, rb_list);
+	list_del(&rb->rb_list);
+
+	msg->msg_niov = rbp->rbp_npages;
+	msg->msg_kiov = &rb->rb_kiov[0];
+
+	if (do_recv) {
+		int cpt = msg->msg_rx_cpt;
+
+		lnet_net_unlock(cpt);
+		lnet_ni_recv(lp->lp_ni, msg->msg_private, msg, 1,
+			     0, msg->msg_len, msg->msg_len);
+		lnet_net_lock(cpt);
+	}
+	return 0;
+}
+
+void
+lnet_return_tx_credits_locked(lnet_msg_t *msg)
+{
+	lnet_peer_t	*txpeer = msg->msg_txpeer;
+	lnet_msg_t	*msg2;
+
+	if (msg->msg_txcredit) {
+		struct lnet_ni	     *ni = txpeer->lp_ni;
+		struct lnet_tx_queue *tq = ni->ni_tx_queues[msg->msg_tx_cpt];
+
+		/* give back NI txcredits */
+		msg->msg_txcredit = 0;
+
+		LASSERT((tq->tq_credits < 0) ==
+			!list_empty(&tq->tq_delayed));
+
+		tq->tq_credits++;
+		if (tq->tq_credits <= 0) {
+			msg2 = list_entry(tq->tq_delayed.next,
+					      lnet_msg_t, msg_list);
+			list_del(&msg2->msg_list);
+
+			LASSERT(msg2->msg_txpeer->lp_ni == ni);
+			LASSERT(msg2->msg_tx_delayed);
+
+			(void) lnet_post_send_locked(msg2, 1);
+		}
+	}
+
+	if (msg->msg_peertxcredit) {
+		/* give back peer txcredits */
+		msg->msg_peertxcredit = 0;
+
+		LASSERT((txpeer->lp_txcredits < 0) ==
+			!list_empty(&txpeer->lp_txq));
+
+		txpeer->lp_txqnob -= msg->msg_len + sizeof(lnet_hdr_t);
+		LASSERT (txpeer->lp_txqnob >= 0);
+
+		txpeer->lp_txcredits++;
+		if (txpeer->lp_txcredits <= 0) {
+			msg2 = list_entry(txpeer->lp_txq.next,
+					      lnet_msg_t, msg_list);
+			list_del(&msg2->msg_list);
+
+			LASSERT(msg2->msg_txpeer == txpeer);
+			LASSERT(msg2->msg_tx_delayed);
+
+			(void) lnet_post_send_locked(msg2, 1);
+		}
+	}
+
+	if (txpeer != NULL) {
+		msg->msg_txpeer = NULL;
+		lnet_peer_decref_locked(txpeer);
+	}
+}
+
+void
+lnet_return_rx_credits_locked(lnet_msg_t *msg)
+{
+	lnet_peer_t	*rxpeer = msg->msg_rxpeer;
+	lnet_msg_t	*msg2;
+
+	if (msg->msg_rtrcredit) {
+		/* give back global router credits */
+		lnet_rtrbuf_t     *rb;
+		lnet_rtrbufpool_t *rbp;
+
+		/* NB If a msg ever blocks for a buffer in rbp_msgs, it stays
+		 * there until it gets one allocated, or aborts the wait
+		 * itself */
+		LASSERT (msg->msg_kiov != NULL);
+
+		rb = list_entry(msg->msg_kiov, lnet_rtrbuf_t, rb_kiov[0]);
+		rbp = rb->rb_pool;
+		LASSERT (rbp == lnet_msg2bufpool(msg));
+
+		msg->msg_kiov = NULL;
+		msg->msg_rtrcredit = 0;
+
+		LASSERT((rbp->rbp_credits < 0) ==
+			!list_empty(&rbp->rbp_msgs));
+		LASSERT((rbp->rbp_credits > 0) ==
+			!list_empty(&rbp->rbp_bufs));
+
+		list_add(&rb->rb_list, &rbp->rbp_bufs);
+		rbp->rbp_credits++;
+		if (rbp->rbp_credits <= 0) {
+			msg2 = list_entry(rbp->rbp_msgs.next,
+					      lnet_msg_t, msg_list);
+			list_del(&msg2->msg_list);
+
+			(void) lnet_post_routed_recv_locked(msg2, 1);
+		}
+	}
+
+	if (msg->msg_peerrtrcredit) {
+		/* give back peer router credits */
+		msg->msg_peerrtrcredit = 0;
+
+		LASSERT((rxpeer->lp_rtrcredits < 0) ==
+			!list_empty(&rxpeer->lp_rtrq));
+
+		rxpeer->lp_rtrcredits++;
+		if (rxpeer->lp_rtrcredits <= 0) {
+			msg2 = list_entry(rxpeer->lp_rtrq.next,
+					      lnet_msg_t, msg_list);
+			list_del(&msg2->msg_list);
+
+			(void) lnet_post_routed_recv_locked(msg2, 1);
+		}
+	}
+	if (rxpeer != NULL) {
+		msg->msg_rxpeer = NULL;
+		lnet_peer_decref_locked(rxpeer);
+	}
+}
+
+static int
+lnet_compare_routes(lnet_route_t *r1, lnet_route_t *r2)
+{
+	lnet_peer_t *p1 = r1->lr_gateway;
+	lnet_peer_t *p2 = r2->lr_gateway;
+
+	if (r1->lr_hops < r2->lr_hops)
+		return 1;
+
+	if (r1->lr_hops > r2->lr_hops)
+		return -1;
+
+	if (p1->lp_txqnob < p2->lp_txqnob)
+		return 1;
+
+	if (p1->lp_txqnob > p2->lp_txqnob)
+		return -1;
+
+	if (p1->lp_txcredits > p2->lp_txcredits)
+		return 1;
+
+	if (p1->lp_txcredits < p2->lp_txcredits)
+		return -1;
+
+	if (r1->lr_seq - r2->lr_seq <= 0)
+		return 1;
+
+	return -1;
+}
+
+static lnet_peer_t *
+lnet_find_route_locked(lnet_ni_t *ni, lnet_nid_t target, lnet_nid_t rtr_nid)
+{
+	lnet_remotenet_t	*rnet;
+	lnet_route_t		*rtr;
+	lnet_route_t		*rtr_best;
+	lnet_route_t		*rtr_last;
+	struct lnet_peer	*lp_best;
+	struct lnet_peer	*lp;
+	int			rc;
+
+	/* If @rtr_nid is not LNET_NID_ANY, return the gateway with
+	 * rtr_nid nid, otherwise find the best gateway I can use */
+
+	rnet = lnet_find_net_locked(LNET_NIDNET(target));
+	if (rnet == NULL)
+		return NULL;
+
+	lp_best = NULL;
+	rtr_best = rtr_last = NULL;
+	list_for_each_entry(rtr, &rnet->lrn_routes, lr_list) {
+		lp = rtr->lr_gateway;
+
+		if (!lp->lp_alive || /* gateway is down */
+		    ((lp->lp_ping_feats & LNET_PING_FEAT_NI_STATUS) != 0 &&
+		     rtr->lr_downis != 0)) /* NI to target is down */
+			continue;
+
+		if (ni != NULL && lp->lp_ni != ni)
+			continue;
+
+		if (lp->lp_nid == rtr_nid) /* it's pre-determined router */
+			return lp;
+
+		if (lp_best == NULL) {
+			rtr_best = rtr_last = rtr;
+			lp_best = lp;
+			continue;
+		}
+
+		/* no protection on below fields, but it's harmless */
+		if (rtr_last->lr_seq - rtr->lr_seq < 0)
+			rtr_last = rtr;
+
+		rc = lnet_compare_routes(rtr, rtr_best);
+		if (rc < 0)
+			continue;
+
+		rtr_best = rtr;
+		lp_best = lp;
+	}
+
+	/* set sequence number on the best router to the latest sequence + 1
+	 * so we can round-robin all routers, it's race and inaccurate but
+	 * harmless and functional  */
+	if (rtr_best != NULL)
+		rtr_best->lr_seq = rtr_last->lr_seq + 1;
+	return lp_best;
+}
+
+int
+lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
+{
+	lnet_nid_t		dst_nid = msg->msg_target.nid;
+	struct lnet_ni		*src_ni;
+	struct lnet_ni		*local_ni;
+	struct lnet_peer	*lp;
+	int			cpt;
+	int			cpt2;
+	int			rc;
+
+	/* NB: rtr_nid is set to LNET_NID_ANY for all current use-cases,
+	 * but we might want to use pre-determined router for ACK/REPLY
+	 * in the future */
+	/* NB: ni != NULL == interface pre-determined (ACK/REPLY) */
+	LASSERT (msg->msg_txpeer == NULL);
+	LASSERT (!msg->msg_sending);
+	LASSERT (!msg->msg_target_is_router);
+	LASSERT (!msg->msg_receiving);
+
+	msg->msg_sending = 1;
+
+	LASSERT(!msg->msg_tx_committed);
+	cpt = lnet_cpt_of_nid(rtr_nid == LNET_NID_ANY ? dst_nid : rtr_nid);
+ again:
+	lnet_net_lock(cpt);
+
+	if (the_lnet.ln_shutdown) {
+		lnet_net_unlock(cpt);
+		return -ESHUTDOWN;
+	}
+
+	if (src_nid == LNET_NID_ANY) {
+		src_ni = NULL;
+	} else {
+		src_ni = lnet_nid2ni_locked(src_nid, cpt);
+		if (src_ni == NULL) {
+			lnet_net_unlock(cpt);
+			LCONSOLE_WARN("Can't send to %s: src %s is not a "
+				      "local nid\n", libcfs_nid2str(dst_nid),
+				      libcfs_nid2str(src_nid));
+			return -EINVAL;
+		}
+		LASSERT (!msg->msg_routing);
+	}
+
+	/* Is this for someone on a local network? */
+	local_ni = lnet_net2ni_locked(LNET_NIDNET(dst_nid), cpt);
+
+	if (local_ni != NULL) {
+		if (src_ni == NULL) {
+			src_ni = local_ni;
+			src_nid = src_ni->ni_nid;
+		} else if (src_ni == local_ni) {
+			lnet_ni_decref_locked(local_ni, cpt);
+		} else {
+			lnet_ni_decref_locked(local_ni, cpt);
+			lnet_ni_decref_locked(src_ni, cpt);
+			lnet_net_unlock(cpt);
+			LCONSOLE_WARN("No route to %s via from %s\n",
+				      libcfs_nid2str(dst_nid),
+				      libcfs_nid2str(src_nid));
+			return -EINVAL;
+		}
+
+		LASSERT(src_nid != LNET_NID_ANY);
+		lnet_msg_commit(msg, cpt);
+
+		if (!msg->msg_routing)
+			msg->msg_hdr.src_nid = cpu_to_le64(src_nid);
+
+		if (src_ni == the_lnet.ln_loni) {
+			/* No send credit hassles with LOLND */
+			lnet_net_unlock(cpt);
+			lnet_ni_send(src_ni, msg);
+
+			lnet_net_lock(cpt);
+			lnet_ni_decref_locked(src_ni, cpt);
+			lnet_net_unlock(cpt);
+			return 0;
+		}
+
+		rc = lnet_nid2peer_locked(&lp, dst_nid, cpt);
+		/* lp has ref on src_ni; lose mine */
+		lnet_ni_decref_locked(src_ni, cpt);
+		if (rc != 0) {
+			lnet_net_unlock(cpt);
+			LCONSOLE_WARN("Error %d finding peer %s\n", rc,
+				      libcfs_nid2str(dst_nid));
+			/* ENOMEM or shutting down */
+			return rc;
+		}
+		LASSERT (lp->lp_ni == src_ni);
+	} else {
+		/* sending to a remote network */
+		lp = lnet_find_route_locked(src_ni, dst_nid, rtr_nid);
+		if (lp == NULL) {
+			if (src_ni != NULL)
+				lnet_ni_decref_locked(src_ni, cpt);
+			lnet_net_unlock(cpt);
+
+			LCONSOLE_WARN("No route to %s via %s "
+				      "(all routers down)\n",
+				      libcfs_id2str(msg->msg_target),
+				      libcfs_nid2str(src_nid));
+			return -EHOSTUNREACH;
+		}
+
+		/* rtr_nid is LNET_NID_ANY or NID of pre-determined router,
+		 * it's possible that rtr_nid isn't LNET_NID_ANY and lp isn't
+		 * pre-determined router, this can happen if router table
+		 * was changed when we release the lock */
+		if (rtr_nid != lp->lp_nid) {
+			cpt2 = lnet_cpt_of_nid_locked(lp->lp_nid);
+			if (cpt2 != cpt) {
+				if (src_ni != NULL)
+					lnet_ni_decref_locked(src_ni, cpt);
+				lnet_net_unlock(cpt);
+
+				rtr_nid = lp->lp_nid;
+				cpt = cpt2;
+				goto again;
+			}
+		}
+
+		CDEBUG(D_NET, "Best route to %s via %s for %s %d\n",
+		       libcfs_nid2str(dst_nid), libcfs_nid2str(lp->lp_nid),
+		       lnet_msgtyp2str(msg->msg_type), msg->msg_len);
+
+		if (src_ni == NULL) {
+			src_ni = lp->lp_ni;
+			src_nid = src_ni->ni_nid;
+		} else {
+			LASSERT (src_ni == lp->lp_ni);
+			lnet_ni_decref_locked(src_ni, cpt);
+		}
+
+		lnet_peer_addref_locked(lp);
+
+		LASSERT(src_nid != LNET_NID_ANY);
+		lnet_msg_commit(msg, cpt);
+
+		if (!msg->msg_routing) {
+			/* I'm the source and now I know which NI to send on */
+			msg->msg_hdr.src_nid = cpu_to_le64(src_nid);
+		}
+
+		msg->msg_target_is_router = 1;
+		msg->msg_target.nid = lp->lp_nid;
+		msg->msg_target.pid = LUSTRE_SRV_LNET_PID;
+	}
+
+	/* 'lp' is our best choice of peer */
+
+	LASSERT (!msg->msg_peertxcredit);
+	LASSERT (!msg->msg_txcredit);
+	LASSERT (msg->msg_txpeer == NULL);
+
+	msg->msg_txpeer = lp;		   /* msg takes my ref on lp */
+
+	rc = lnet_post_send_locked(msg, 0);
+	lnet_net_unlock(cpt);
+
+	if (rc == EHOSTUNREACH)
+		return -EHOSTUNREACH;
+
+	if (rc == 0)
+		lnet_ni_send(src_ni, msg);
+
+	return 0;
+}
+
+static void
+lnet_drop_message(lnet_ni_t *ni, int cpt, void *private, unsigned int nob)
+{
+	lnet_net_lock(cpt);
+	the_lnet.ln_counters[cpt]->drop_count++;
+	the_lnet.ln_counters[cpt]->drop_length += nob;
+	lnet_net_unlock(cpt);
+
+	lnet_ni_recv(ni, private, NULL, 0, 0, 0, nob);
+}
+
+static void
+lnet_recv_put(lnet_ni_t *ni, lnet_msg_t *msg)
+{
+	lnet_hdr_t	*hdr = &msg->msg_hdr;
+
+	if (msg->msg_wanted != 0)
+		lnet_setpayloadbuffer(msg);
+
+	lnet_build_msg_event(msg, LNET_EVENT_PUT);
+
+	/* Must I ACK?  If so I'll grab the ack_wmd out of the header and put
+	 * it back into the ACK during lnet_finalize() */
+	msg->msg_ack = (!lnet_is_wire_handle_none(&hdr->msg.put.ack_wmd) &&
+			(msg->msg_md->md_options & LNET_MD_ACK_DISABLE) == 0);
+
+	lnet_ni_recv(ni, msg->msg_private, msg, msg->msg_rx_delayed,
+		     msg->msg_offset, msg->msg_wanted, hdr->payload_length);
+}
+
+static int
+lnet_parse_put(lnet_ni_t *ni, lnet_msg_t *msg)
+{
+	lnet_hdr_t		*hdr = &msg->msg_hdr;
+	struct lnet_match_info	info;
+	int			rc;
+
+	/* Convert put fields to host byte order */
+	hdr->msg.put.match_bits	= le64_to_cpu(hdr->msg.put.match_bits);
+	hdr->msg.put.ptl_index	= le32_to_cpu(hdr->msg.put.ptl_index);
+	hdr->msg.put.offset	= le32_to_cpu(hdr->msg.put.offset);
+
+	info.mi_id.nid	= hdr->src_nid;
+	info.mi_id.pid	= hdr->src_pid;
+	info.mi_opc	= LNET_MD_OP_PUT;
+	info.mi_portal	= hdr->msg.put.ptl_index;
+	info.mi_rlength	= hdr->payload_length;
+	info.mi_roffset	= hdr->msg.put.offset;
+	info.mi_mbits	= hdr->msg.put.match_bits;
+
+	msg->msg_rx_ready_delay = ni->ni_lnd->lnd_eager_recv == NULL;
+
+ again:
+	rc = lnet_ptl_match_md(&info, msg);
+	switch (rc) {
+	default:
+		LBUG();
+
+	case LNET_MATCHMD_OK:
+		lnet_recv_put(ni, msg);
+		return 0;
+
+	case LNET_MATCHMD_NONE:
+		if (msg->msg_rx_delayed) /* attached on delayed list */
+			return 0;
+
+		rc = lnet_ni_eager_recv(ni, msg);
+		if (rc == 0)
+			goto again;
+		/* fall through */
+
+	case LNET_MATCHMD_DROP:
+		CNETERR("Dropping PUT from %s portal %d match "LPU64
+			" offset %d length %d: %d\n",
+			libcfs_id2str(info.mi_id), info.mi_portal,
+			info.mi_mbits, info.mi_roffset, info.mi_rlength, rc);
+
+		return ENOENT;	/* +ve: OK but no match */
+	}
+}
+
+static int
+lnet_parse_get(lnet_ni_t *ni, lnet_msg_t *msg, int rdma_get)
+{
+	struct lnet_match_info	info;
+	lnet_hdr_t		*hdr = &msg->msg_hdr;
+	lnet_handle_wire_t	reply_wmd;
+	int			rc;
+
+	/* Convert get fields to host byte order */
+	hdr->msg.get.match_bits	  = le64_to_cpu(hdr->msg.get.match_bits);
+	hdr->msg.get.ptl_index	  = le32_to_cpu(hdr->msg.get.ptl_index);
+	hdr->msg.get.sink_length  = le32_to_cpu(hdr->msg.get.sink_length);
+	hdr->msg.get.src_offset	  = le32_to_cpu(hdr->msg.get.src_offset);
+
+	info.mi_id.nid	= hdr->src_nid;
+	info.mi_id.pid	= hdr->src_pid;
+	info.mi_opc	= LNET_MD_OP_GET;
+	info.mi_portal	= hdr->msg.get.ptl_index;
+	info.mi_rlength	= hdr->msg.get.sink_length;
+	info.mi_roffset	= hdr->msg.get.src_offset;
+	info.mi_mbits	= hdr->msg.get.match_bits;
+
+	rc = lnet_ptl_match_md(&info, msg);
+	if (rc == LNET_MATCHMD_DROP) {
+		CNETERR("Dropping GET from %s portal %d match "LPU64
+			" offset %d length %d\n",
+			libcfs_id2str(info.mi_id), info.mi_portal,
+			info.mi_mbits, info.mi_roffset, info.mi_rlength);
+		return ENOENT;	/* +ve: OK but no match */
+	}
+
+	LASSERT(rc == LNET_MATCHMD_OK);
+
+	lnet_build_msg_event(msg, LNET_EVENT_GET);
+
+	reply_wmd = hdr->msg.get.return_wmd;
+
+	lnet_prep_send(msg, LNET_MSG_REPLY, info.mi_id,
+		       msg->msg_offset, msg->msg_wanted);
+
+	msg->msg_hdr.msg.reply.dst_wmd = reply_wmd;
+
+	if (rdma_get) {
+		/* The LND completes the REPLY from her recv procedure */
+		lnet_ni_recv(ni, msg->msg_private, msg, 0,
+			     msg->msg_offset, msg->msg_len, msg->msg_len);
+		return 0;
+	}
+
+	lnet_ni_recv(ni, msg->msg_private, NULL, 0, 0, 0, 0);
+	msg->msg_receiving = 0;
+
+	rc = lnet_send(ni->ni_nid, msg, LNET_NID_ANY);
+	if (rc < 0) {
+		/* didn't get as far as lnet_ni_send() */
+		CERROR("%s: Unable to send REPLY for GET from %s: %d\n",
+		       libcfs_nid2str(ni->ni_nid),
+		       libcfs_id2str(info.mi_id), rc);
+
+		lnet_finalize(ni, msg, rc);
+	}
+
+	return 0;
+}
+
+static int
+lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
+{
+	void	     *private = msg->msg_private;
+	lnet_hdr_t       *hdr = &msg->msg_hdr;
+	lnet_process_id_t src = {0};
+	lnet_libmd_t     *md;
+	int	       rlength;
+	int	       mlength;
+	int			cpt;
+
+	cpt = lnet_cpt_of_cookie(hdr->msg.reply.dst_wmd.wh_object_cookie);
+	lnet_res_lock(cpt);
+
+	src.nid = hdr->src_nid;
+	src.pid = hdr->src_pid;
+
+	/* NB handles only looked up by creator (no flips) */
+	md = lnet_wire_handle2md(&hdr->msg.reply.dst_wmd);
+	if (md == NULL || md->md_threshold == 0 || md->md_me != NULL) {
+		CNETERR("%s: Dropping REPLY from %s for %s "
+			"MD "LPX64"."LPX64"\n",
+			libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
+			(md == NULL) ? "invalid" : "inactive",
+			hdr->msg.reply.dst_wmd.wh_interface_cookie,
+			hdr->msg.reply.dst_wmd.wh_object_cookie);
+		if (md != NULL && md->md_me != NULL)
+			CERROR("REPLY MD also attached to portal %d\n",
+			       md->md_me->me_portal);
+
+		lnet_res_unlock(cpt);
+		return ENOENT;		  /* +ve: OK but no match */
+	}
+
+	LASSERT (md->md_offset == 0);
+
+	rlength = hdr->payload_length;
+	mlength = MIN(rlength, (int)md->md_length);
+
+	if (mlength < rlength &&
+	    (md->md_options & LNET_MD_TRUNCATE) == 0) {
+		CNETERR("%s: Dropping REPLY from %s length %d "
+			"for MD "LPX64" would overflow (%d)\n",
+			libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
+			rlength, hdr->msg.reply.dst_wmd.wh_object_cookie,
+			mlength);
+		lnet_res_unlock(cpt);
+		return ENOENT;	  /* +ve: OK but no match */
+	}
+
+	CDEBUG(D_NET, "%s: Reply from %s of length %d/%d into md "LPX64"\n",
+	       libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
+	       mlength, rlength, hdr->msg.reply.dst_wmd.wh_object_cookie);
+
+	lnet_msg_attach_md(msg, md, 0, mlength);
+
+	if (mlength != 0)
+		lnet_setpayloadbuffer(msg);
+
+	lnet_res_unlock(cpt);
+
+	lnet_build_msg_event(msg, LNET_EVENT_REPLY);
+
+	lnet_ni_recv(ni, private, msg, 0, 0, mlength, rlength);
+	return 0;
+}
+
+static int
+lnet_parse_ack(lnet_ni_t *ni, lnet_msg_t *msg)
+{
+	lnet_hdr_t       *hdr = &msg->msg_hdr;
+	lnet_process_id_t src = {0};
+	lnet_libmd_t     *md;
+	int			cpt;
+
+	src.nid = hdr->src_nid;
+	src.pid = hdr->src_pid;
+
+	/* Convert ack fields to host byte order */
+	hdr->msg.ack.match_bits = le64_to_cpu(hdr->msg.ack.match_bits);
+	hdr->msg.ack.mlength = le32_to_cpu(hdr->msg.ack.mlength);
+
+	cpt = lnet_cpt_of_cookie(hdr->msg.ack.dst_wmd.wh_object_cookie);
+	lnet_res_lock(cpt);
+
+	/* NB handles only looked up by creator (no flips) */
+	md = lnet_wire_handle2md(&hdr->msg.ack.dst_wmd);
+	if (md == NULL || md->md_threshold == 0 || md->md_me != NULL) {
+		/* Don't moan; this is expected */
+		CDEBUG(D_NET,
+		       "%s: Dropping ACK from %s to %s MD "LPX64"."LPX64"\n",
+		       libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
+		       (md == NULL) ? "invalid" : "inactive",
+		       hdr->msg.ack.dst_wmd.wh_interface_cookie,
+		       hdr->msg.ack.dst_wmd.wh_object_cookie);
+		if (md != NULL && md->md_me != NULL)
+			CERROR("Source MD also attached to portal %d\n",
+			       md->md_me->me_portal);
+
+		lnet_res_unlock(cpt);
+		return ENOENT;		  /* +ve! */
+	}
+
+	CDEBUG(D_NET, "%s: ACK from %s into md "LPX64"\n",
+	       libcfs_nid2str(ni->ni_nid), libcfs_id2str(src),
+	       hdr->msg.ack.dst_wmd.wh_object_cookie);
+
+	lnet_msg_attach_md(msg, md, 0, 0);
+
+	lnet_res_unlock(cpt);
+
+	lnet_build_msg_event(msg, LNET_EVENT_ACK);
+
+	lnet_ni_recv(ni, msg->msg_private, msg, 0, 0, 0, msg->msg_len);
+	return 0;
+}
+
+static int
+lnet_parse_forward_locked(lnet_ni_t *ni, lnet_msg_t *msg)
+{
+	int	rc = 0;
+
+	if (msg->msg_rxpeer->lp_rtrcredits <= 0 ||
+	    lnet_msg2bufpool(msg)->rbp_credits <= 0) {
+		if (ni->ni_lnd->lnd_eager_recv == NULL) {
+			msg->msg_rx_ready_delay = 1;
+		} else {
+			lnet_net_unlock(msg->msg_rx_cpt);
+			rc = lnet_ni_eager_recv(ni, msg);
+			lnet_net_lock(msg->msg_rx_cpt);
+		}
+	}
+
+	if (rc == 0)
+		rc = lnet_post_routed_recv_locked(msg, 0);
+	return rc;
+}
+
+char *
+lnet_msgtyp2str (int type)
+{
+	switch (type) {
+	case LNET_MSG_ACK:
+		return ("ACK");
+	case LNET_MSG_PUT:
+		return ("PUT");
+	case LNET_MSG_GET:
+		return ("GET");
+	case LNET_MSG_REPLY:
+		return ("REPLY");
+	case LNET_MSG_HELLO:
+		return ("HELLO");
+	default:
+		return ("<UNKNOWN>");
+	}
+}
+EXPORT_SYMBOL(lnet_msgtyp2str);
+
+void
+lnet_print_hdr(lnet_hdr_t * hdr)
+{
+	lnet_process_id_t src = {0};
+	lnet_process_id_t dst = {0};
+	char *type_str = lnet_msgtyp2str (hdr->type);
+
+	src.nid = hdr->src_nid;
+	src.pid = hdr->src_pid;
+
+	dst.nid = hdr->dest_nid;
+	dst.pid = hdr->dest_pid;
+
+	CWARN("P3 Header at %p of type %s\n", hdr, type_str);
+	CWARN("    From %s\n", libcfs_id2str(src));
+	CWARN("    To   %s\n", libcfs_id2str(dst));
+
+	switch (hdr->type) {
+	default:
+		break;
+
+	case LNET_MSG_PUT:
+		CWARN("    Ptl index %d, ack md "LPX64"."LPX64", "
+		      "match bits "LPU64"\n",
+		      hdr->msg.put.ptl_index,
+		      hdr->msg.put.ack_wmd.wh_interface_cookie,
+		      hdr->msg.put.ack_wmd.wh_object_cookie,
+		      hdr->msg.put.match_bits);
+		CWARN("    Length %d, offset %d, hdr data "LPX64"\n",
+		      hdr->payload_length, hdr->msg.put.offset,
+		      hdr->msg.put.hdr_data);
+		break;
+
+	case LNET_MSG_GET:
+		CWARN("    Ptl index %d, return md "LPX64"."LPX64", "
+		      "match bits "LPU64"\n", hdr->msg.get.ptl_index,
+		      hdr->msg.get.return_wmd.wh_interface_cookie,
+		      hdr->msg.get.return_wmd.wh_object_cookie,
+		      hdr->msg.get.match_bits);
+		CWARN("    Length %d, src offset %d\n",
+		      hdr->msg.get.sink_length,
+		      hdr->msg.get.src_offset);
+		break;
+
+	case LNET_MSG_ACK:
+		CWARN("    dst md "LPX64"."LPX64", "
+		      "manipulated length %d\n",
+		      hdr->msg.ack.dst_wmd.wh_interface_cookie,
+		      hdr->msg.ack.dst_wmd.wh_object_cookie,
+		      hdr->msg.ack.mlength);
+		break;
+
+	case LNET_MSG_REPLY:
+		CWARN("    dst md "LPX64"."LPX64", "
+		      "length %d\n",
+		      hdr->msg.reply.dst_wmd.wh_interface_cookie,
+		      hdr->msg.reply.dst_wmd.wh_object_cookie,
+		      hdr->payload_length);
+	}
+
+}
+
+int
+lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
+	   void *private, int rdma_req)
+{
+	int		rc = 0;
+	int		cpt;
+	int		for_me;
+	struct lnet_msg	*msg;
+	lnet_pid_t     dest_pid;
+	lnet_nid_t     dest_nid;
+	lnet_nid_t     src_nid;
+	__u32	  payload_length;
+	__u32	  type;
+
+	LASSERT (!in_interrupt ());
+
+	type = le32_to_cpu(hdr->type);
+	src_nid = le64_to_cpu(hdr->src_nid);
+	dest_nid = le64_to_cpu(hdr->dest_nid);
+	dest_pid = le32_to_cpu(hdr->dest_pid);
+	payload_length = le32_to_cpu(hdr->payload_length);
+
+	for_me = (ni->ni_nid == dest_nid);
+	cpt = lnet_cpt_of_nid(from_nid);
+
+	switch (type) {
+	case LNET_MSG_ACK:
+	case LNET_MSG_GET:
+		if (payload_length > 0) {
+			CERROR("%s, src %s: bad %s payload %d (0 expected)\n",
+			       libcfs_nid2str(from_nid),
+			       libcfs_nid2str(src_nid),
+			       lnet_msgtyp2str(type), payload_length);
+			return -EPROTO;
+		}
+		break;
+
+	case LNET_MSG_PUT:
+	case LNET_MSG_REPLY:
+		if (payload_length > (__u32)(for_me ? LNET_MAX_PAYLOAD : LNET_MTU)) {
+			CERROR("%s, src %s: bad %s payload %d "
+			       "(%d max expected)\n",
+			       libcfs_nid2str(from_nid),
+			       libcfs_nid2str(src_nid),
+			       lnet_msgtyp2str(type),
+			       payload_length,
+			       for_me ? LNET_MAX_PAYLOAD : LNET_MTU);
+			return -EPROTO;
+		}
+		break;
+
+	default:
+		CERROR("%s, src %s: Bad message type 0x%x\n",
+		       libcfs_nid2str(from_nid),
+		       libcfs_nid2str(src_nid), type);
+		return -EPROTO;
+	}
+
+	if (the_lnet.ln_routing &&
+	    ni->ni_last_alive != cfs_time_current_sec()) {
+		lnet_ni_lock(ni);
+
+		/* NB: so far here is the only place to set NI status to "up */
+		ni->ni_last_alive = cfs_time_current_sec();
+		if (ni->ni_status != NULL &&
+		    ni->ni_status->ns_status == LNET_NI_STATUS_DOWN)
+			ni->ni_status->ns_status = LNET_NI_STATUS_UP;
+		lnet_ni_unlock(ni);
+	}
+
+	/* Regard a bad destination NID as a protocol error.  Senders should
+	 * know what they're doing; if they don't they're misconfigured, buggy
+	 * or malicious so we chop them off at the knees :) */
+
+	if (!for_me) {
+		if (LNET_NIDNET(dest_nid) == LNET_NIDNET(ni->ni_nid)) {
+			/* should have gone direct */
+			CERROR ("%s, src %s: Bad dest nid %s "
+				"(should have been sent direct)\n",
+				libcfs_nid2str(from_nid),
+				libcfs_nid2str(src_nid),
+				libcfs_nid2str(dest_nid));
+			return -EPROTO;
+		}
+
+		if (lnet_islocalnid(dest_nid)) {
+			/* dest is another local NI; sender should have used
+			 * this node's NID on its own network */
+			CERROR ("%s, src %s: Bad dest nid %s "
+				"(it's my nid but on a different network)\n",
+				libcfs_nid2str(from_nid),
+				libcfs_nid2str(src_nid),
+				libcfs_nid2str(dest_nid));
+			return -EPROTO;
+		}
+
+		if (rdma_req && type == LNET_MSG_GET) {
+			CERROR ("%s, src %s: Bad optimized GET for %s "
+				"(final destination must be me)\n",
+				libcfs_nid2str(from_nid),
+				libcfs_nid2str(src_nid),
+				libcfs_nid2str(dest_nid));
+			return -EPROTO;
+		}
+
+		if (!the_lnet.ln_routing) {
+			CERROR ("%s, src %s: Dropping message for %s "
+				"(routing not enabled)\n",
+				libcfs_nid2str(from_nid),
+				libcfs_nid2str(src_nid),
+				libcfs_nid2str(dest_nid));
+			goto drop;
+		}
+	}
+
+	/* Message looks OK; we're not going to return an error, so we MUST
+	 * call back lnd_recv() come what may... */
+
+	if (!list_empty (&the_lnet.ln_test_peers) && /* normally we don't */
+	    fail_peer (src_nid, 0))	     /* shall we now? */
+	{
+		CERROR("%s, src %s: Dropping %s to simulate failure\n",
+		       libcfs_nid2str(from_nid), libcfs_nid2str(src_nid),
+		       lnet_msgtyp2str(type));
+		goto drop;
+	}
+
+	msg = lnet_msg_alloc();
+	if (msg == NULL) {
+		CERROR("%s, src %s: Dropping %s (out of memory)\n",
+		       libcfs_nid2str(from_nid), libcfs_nid2str(src_nid),
+		       lnet_msgtyp2str(type));
+		goto drop;
+	}
+
+	/* msg zeroed in lnet_msg_alloc; i.e. flags all clear, pointers NULL etc */
+
+	msg->msg_type = type;
+	msg->msg_private = private;
+	msg->msg_receiving = 1;
+	msg->msg_len = msg->msg_wanted = payload_length;
+	msg->msg_offset = 0;
+	msg->msg_hdr = *hdr;
+	/* for building message event */
+	msg->msg_from = from_nid;
+	if (!for_me) {
+		msg->msg_target.pid	= dest_pid;
+		msg->msg_target.nid	= dest_nid;
+		msg->msg_routing	= 1;
+
+	} else {
+		/* convert common msg->hdr fields to host byteorder */
+		msg->msg_hdr.type	= type;
+		msg->msg_hdr.src_nid	= src_nid;
+		msg->msg_hdr.src_pid	= le32_to_cpu(msg->msg_hdr.src_pid);
+		msg->msg_hdr.dest_nid	= dest_nid;
+		msg->msg_hdr.dest_pid	= dest_pid;
+		msg->msg_hdr.payload_length = payload_length;
+	}
+
+	lnet_net_lock(cpt);
+	rc = lnet_nid2peer_locked(&msg->msg_rxpeer, from_nid, cpt);
+	if (rc != 0) {
+		lnet_net_unlock(cpt);
+		CERROR("%s, src %s: Dropping %s "
+		       "(error %d looking up sender)\n",
+		       libcfs_nid2str(from_nid), libcfs_nid2str(src_nid),
+		       lnet_msgtyp2str(type), rc);
+		lnet_msg_free(msg);
+		goto drop;
+	}
+
+	lnet_msg_commit(msg, cpt);
+
+	if (!for_me) {
+		rc = lnet_parse_forward_locked(ni, msg);
+		lnet_net_unlock(cpt);
+
+		if (rc < 0)
+			goto free_drop;
+		if (rc == 0) {
+			lnet_ni_recv(ni, msg->msg_private, msg, 0,
+				     0, payload_length, payload_length);
+		}
+		return 0;
+	}
+
+	lnet_net_unlock(cpt);
+
+	switch (type) {
+	case LNET_MSG_ACK:
+		rc = lnet_parse_ack(ni, msg);
+		break;
+	case LNET_MSG_PUT:
+		rc = lnet_parse_put(ni, msg);
+		break;
+	case LNET_MSG_GET:
+		rc = lnet_parse_get(ni, msg, rdma_req);
+		break;
+	case LNET_MSG_REPLY:
+		rc = lnet_parse_reply(ni, msg);
+		break;
+	default:
+		LASSERT(0);
+		rc = -EPROTO;
+		goto free_drop;  /* prevent an unused label if !kernel */
+	}
+
+	if (rc == 0)
+		return 0;
+
+	LASSERT (rc == ENOENT);
+
+ free_drop:
+	LASSERT(msg->msg_md == NULL);
+	lnet_finalize(ni, msg, rc);
+
+ drop:
+	lnet_drop_message(ni, cpt, private, payload_length);
+	return 0;
+}
+EXPORT_SYMBOL(lnet_parse);
+
+void
+lnet_drop_delayed_msg_list(struct list_head *head, char *reason)
+{
+	while (!list_empty(head)) {
+		lnet_process_id_t	id = {0};
+		lnet_msg_t		*msg;
+
+		msg = list_entry(head->next, lnet_msg_t, msg_list);
+		list_del(&msg->msg_list);
+
+		id.nid = msg->msg_hdr.src_nid;
+		id.pid = msg->msg_hdr.src_pid;
+
+		LASSERT(msg->msg_md == NULL);
+		LASSERT(msg->msg_rx_delayed);
+		LASSERT(msg->msg_rxpeer != NULL);
+		LASSERT(msg->msg_hdr.type == LNET_MSG_PUT);
+
+		CWARN("Dropping delayed PUT from %s portal %d match "LPU64
+		      " offset %d length %d: %s\n",
+		      libcfs_id2str(id),
+		      msg->msg_hdr.msg.put.ptl_index,
+		      msg->msg_hdr.msg.put.match_bits,
+		      msg->msg_hdr.msg.put.offset,
+		      msg->msg_hdr.payload_length, reason);
+
+		/* NB I can't drop msg's ref on msg_rxpeer until after I've
+		 * called lnet_drop_message(), so I just hang onto msg as well
+		 * until that's done */
+
+		lnet_drop_message(msg->msg_rxpeer->lp_ni,
+				  msg->msg_rxpeer->lp_cpt,
+				  msg->msg_private, msg->msg_len);
+		/*
+		 * NB: message will not generate event because w/o attached MD,
+		 * but we still should give error code so lnet_msg_decommit()
+		 * can skip counters operations and other checks.
+		 */
+		lnet_finalize(msg->msg_rxpeer->lp_ni, msg, -ENOENT);
+	}
+}
+
+void
+lnet_recv_delayed_msg_list(struct list_head *head)
+{
+	while (!list_empty(head)) {
+		lnet_msg_t	  *msg;
+		lnet_process_id_t  id;
+
+		msg = list_entry(head->next, lnet_msg_t, msg_list);
+		list_del(&msg->msg_list);
+
+		/* md won't disappear under me, since each msg
+		 * holds a ref on it */
+
+		id.nid = msg->msg_hdr.src_nid;
+		id.pid = msg->msg_hdr.src_pid;
+
+		LASSERT(msg->msg_rx_delayed);
+		LASSERT(msg->msg_md != NULL);
+		LASSERT(msg->msg_rxpeer != NULL);
+		LASSERT(msg->msg_hdr.type == LNET_MSG_PUT);
+
+		CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d "
+		       "match "LPU64" offset %d length %d.\n",
+			libcfs_id2str(id), msg->msg_hdr.msg.put.ptl_index,
+			msg->msg_hdr.msg.put.match_bits,
+			msg->msg_hdr.msg.put.offset,
+			msg->msg_hdr.payload_length);
+
+		lnet_recv_put(msg->msg_rxpeer->lp_ni, msg);
+	}
+}
+
+/**
+ * Initiate an asynchronous PUT operation.
+ *
+ * There are several events associated with a PUT: completion of the send on
+ * the initiator node (LNET_EVENT_SEND), and when the send completes
+ * successfully, the receipt of an acknowledgment (LNET_EVENT_ACK) indicating
+ * that the operation was accepted by the target. The event LNET_EVENT_PUT is
+ * used at the target node to indicate the completion of incoming data
+ * delivery.
+ *
+ * The local events will be logged in the EQ associated with the MD pointed to
+ * by \a mdh handle. Using a MD without an associated EQ results in these
+ * events being discarded. In this case, the caller must have another
+ * mechanism (e.g., a higher level protocol) for determining when it is safe
+ * to modify the memory region associated with the MD.
+ *
+ * Note that LNet does not guarantee the order of LNET_EVENT_SEND and
+ * LNET_EVENT_ACK, though intuitively ACK should happen after SEND.
+ *
+ * \param self Indicates the NID of a local interface through which to send
+ * the PUT request. Use LNET_NID_ANY to let LNet choose one by itself.
+ * \param mdh A handle for the MD that describes the memory to be sent. The MD
+ * must be "free floating" (See LNetMDBind()).
+ * \param ack Controls whether an acknowledgment is requested.
+ * Acknowledgments are only sent when they are requested by the initiating
+ * process and the target MD enables them.
+ * \param target A process identifier for the target process.
+ * \param portal The index in the \a target's portal table.
+ * \param match_bits The match bits to use for MD selection at the target
+ * process.
+ * \param offset The offset into the target MD (only used when the target
+ * MD has the LNET_MD_MANAGE_REMOTE option set).
+ * \param hdr_data 64 bits of user data that can be included in the message
+ * header. This data is written to an event queue entry at the target if an
+ * EQ is present on the matching MD.
+ *
+ * \retval  0      Success, and only in this case events will be generated
+ * and logged to EQ (if it exists).
+ * \retval -EIO    Simulated failure.
+ * \retval -ENOMEM Memory allocation failure.
+ * \retval -ENOENT Invalid MD object.
+ *
+ * \see lnet_event_t::hdr_data and lnet_event_kind_t.
+ */
+int
+LNetPut(lnet_nid_t self, lnet_handle_md_t mdh, lnet_ack_req_t ack,
+	lnet_process_id_t target, unsigned int portal,
+	__u64 match_bits, unsigned int offset,
+	__u64 hdr_data)
+{
+	struct lnet_msg		*msg;
+	struct lnet_libmd	*md;
+	int			cpt;
+	int			rc;
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (the_lnet.ln_refcount > 0);
+
+	if (!list_empty (&the_lnet.ln_test_peers) && /* normally we don't */
+	    fail_peer (target.nid, 1))	  /* shall we now? */
+	{
+		CERROR("Dropping PUT to %s: simulated failure\n",
+		       libcfs_id2str(target));
+		return -EIO;
+	}
+
+	msg = lnet_msg_alloc();
+	if (msg == NULL) {
+		CERROR("Dropping PUT to %s: ENOMEM on lnet_msg_t\n",
+		       libcfs_id2str(target));
+		return -ENOMEM;
+	}
+	msg->msg_vmflush = !!memory_pressure_get();
+
+	cpt = lnet_cpt_of_cookie(mdh.cookie);
+	lnet_res_lock(cpt);
+
+	md = lnet_handle2md(&mdh);
+	if (md == NULL || md->md_threshold == 0 || md->md_me != NULL) {
+		CERROR("Dropping PUT ("LPU64":%d:%s): MD (%d) invalid\n",
+		       match_bits, portal, libcfs_id2str(target),
+		       md == NULL ? -1 : md->md_threshold);
+		if (md != NULL && md->md_me != NULL)
+			CERROR("Source MD also attached to portal %d\n",
+			       md->md_me->me_portal);
+		lnet_res_unlock(cpt);
+
+		lnet_msg_free(msg);
+		return -ENOENT;
+	}
+
+	CDEBUG(D_NET, "LNetPut -> %s\n", libcfs_id2str(target));
+
+	lnet_msg_attach_md(msg, md, 0, 0);
+
+	lnet_prep_send(msg, LNET_MSG_PUT, target, 0, md->md_length);
+
+	msg->msg_hdr.msg.put.match_bits = cpu_to_le64(match_bits);
+	msg->msg_hdr.msg.put.ptl_index = cpu_to_le32(portal);
+	msg->msg_hdr.msg.put.offset = cpu_to_le32(offset);
+	msg->msg_hdr.msg.put.hdr_data = hdr_data;
+
+	/* NB handles only looked up by creator (no flips) */
+	if (ack == LNET_ACK_REQ) {
+		msg->msg_hdr.msg.put.ack_wmd.wh_interface_cookie =
+			the_lnet.ln_interface_cookie;
+		msg->msg_hdr.msg.put.ack_wmd.wh_object_cookie =
+			md->md_lh.lh_cookie;
+	} else {
+		msg->msg_hdr.msg.put.ack_wmd.wh_interface_cookie =
+			LNET_WIRE_HANDLE_COOKIE_NONE;
+		msg->msg_hdr.msg.put.ack_wmd.wh_object_cookie =
+			LNET_WIRE_HANDLE_COOKIE_NONE;
+	}
+
+	lnet_res_unlock(cpt);
+
+	lnet_build_msg_event(msg, LNET_EVENT_SEND);
+
+	rc = lnet_send(self, msg, LNET_NID_ANY);
+	if (rc != 0) {
+		CNETERR( "Error sending PUT to %s: %d\n",
+		       libcfs_id2str(target), rc);
+		lnet_finalize (NULL, msg, rc);
+	}
+
+	/* completion will be signalled by an event */
+	return 0;
+}
+EXPORT_SYMBOL(LNetPut);
+
+lnet_msg_t *
+lnet_create_reply_msg (lnet_ni_t *ni, lnet_msg_t *getmsg)
+{
+	/* The LND can DMA direct to the GET md (i.e. no REPLY msg).  This
+	 * returns a msg for the LND to pass to lnet_finalize() when the sink
+	 * data has been received.
+	 *
+	 * CAVEAT EMPTOR: 'getmsg' is the original GET, which is freed when
+	 * lnet_finalize() is called on it, so the LND must call this first */
+
+	struct lnet_msg		*msg = lnet_msg_alloc();
+	struct lnet_libmd	*getmd = getmsg->msg_md;
+	lnet_process_id_t	peer_id = getmsg->msg_target;
+	int			cpt;
+
+	LASSERT(!getmsg->msg_target_is_router);
+	LASSERT(!getmsg->msg_routing);
+
+	cpt = lnet_cpt_of_cookie(getmd->md_lh.lh_cookie);
+	lnet_res_lock(cpt);
+
+	LASSERT (getmd->md_refcount > 0);
+
+	if (msg == NULL) {
+		CERROR ("%s: Dropping REPLY from %s: can't allocate msg\n",
+			libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id));
+		goto drop;
+	}
+
+	if (getmd->md_threshold == 0) {
+		CERROR ("%s: Dropping REPLY from %s for inactive MD %p\n",
+			libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id),
+			getmd);
+		lnet_res_unlock(cpt);
+		goto drop;
+	}
+
+	LASSERT(getmd->md_offset == 0);
+
+	CDEBUG(D_NET, "%s: Reply from %s md %p\n",
+	       libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id), getmd);
+
+	/* setup information for lnet_build_msg_event */
+	msg->msg_from = peer_id.nid;
+	msg->msg_type = LNET_MSG_GET; /* flag this msg as an "optimized" GET */
+	msg->msg_hdr.src_nid = peer_id.nid;
+	msg->msg_hdr.payload_length = getmd->md_length;
+	msg->msg_receiving = 1; /* required by lnet_msg_attach_md */
+
+	lnet_msg_attach_md(msg, getmd, getmd->md_offset, getmd->md_length);
+	lnet_res_unlock(cpt);
+
+	cpt = lnet_cpt_of_nid(peer_id.nid);
+
+	lnet_net_lock(cpt);
+	lnet_msg_commit(msg, cpt);
+	lnet_net_unlock(cpt);
+
+	lnet_build_msg_event(msg, LNET_EVENT_REPLY);
+
+	return msg;
+
+ drop:
+	cpt = lnet_cpt_of_nid(peer_id.nid);
+
+	lnet_net_lock(cpt);
+	the_lnet.ln_counters[cpt]->drop_count++;
+	the_lnet.ln_counters[cpt]->drop_length += getmd->md_length;
+	lnet_net_unlock(cpt);
+
+	if (msg != NULL)
+		lnet_msg_free(msg);
+
+	return NULL;
+}
+EXPORT_SYMBOL(lnet_create_reply_msg);
+
+void
+lnet_set_reply_msg_len(lnet_ni_t *ni, lnet_msg_t *reply, unsigned int len)
+{
+	/* Set the REPLY length, now the RDMA that elides the REPLY message has
+	 * completed and I know it. */
+	LASSERT (reply != NULL);
+	LASSERT (reply->msg_type == LNET_MSG_GET);
+	LASSERT (reply->msg_ev.type == LNET_EVENT_REPLY);
+
+	/* NB I trusted my peer to RDMA.  If she tells me she's written beyond
+	 * the end of my buffer, I might as well be dead. */
+	LASSERT (len <= reply->msg_ev.mlength);
+
+	reply->msg_ev.mlength = len;
+}
+EXPORT_SYMBOL(lnet_set_reply_msg_len);
+
+/**
+ * Initiate an asynchronous GET operation.
+ *
+ * On the initiator node, an LNET_EVENT_SEND is logged when the GET request
+ * is sent, and an LNET_EVENT_REPLY is logged when the data returned from
+ * the target node in the REPLY has been written to local MD.
+ *
+ * On the target node, an LNET_EVENT_GET is logged when the GET request
+ * arrives and is accepted into a MD.
+ *
+ * \param self,target,portal,match_bits,offset See the discussion in LNetPut().
+ * \param mdh A handle for the MD that describes the memory into which the
+ * requested data will be received. The MD must be "free floating" (See LNetMDBind()).
+ *
+ * \retval  0      Success, and only in this case events will be generated
+ * and logged to EQ (if it exists) of the MD.
+ * \retval -EIO    Simulated failure.
+ * \retval -ENOMEM Memory allocation failure.
+ * \retval -ENOENT Invalid MD object.
+ */
+int
+LNetGet(lnet_nid_t self, lnet_handle_md_t mdh,
+	lnet_process_id_t target, unsigned int portal,
+	__u64 match_bits, unsigned int offset)
+{
+	struct lnet_msg		*msg;
+	struct lnet_libmd	*md;
+	int			cpt;
+	int			rc;
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (the_lnet.ln_refcount > 0);
+
+	if (!list_empty (&the_lnet.ln_test_peers) && /* normally we don't */
+	    fail_peer (target.nid, 1))	  /* shall we now? */
+	{
+		CERROR("Dropping GET to %s: simulated failure\n",
+		       libcfs_id2str(target));
+		return -EIO;
+	}
+
+	msg = lnet_msg_alloc();
+	if (msg == NULL) {
+		CERROR("Dropping GET to %s: ENOMEM on lnet_msg_t\n",
+		       libcfs_id2str(target));
+		return -ENOMEM;
+	}
+
+	cpt = lnet_cpt_of_cookie(mdh.cookie);
+	lnet_res_lock(cpt);
+
+	md = lnet_handle2md(&mdh);
+	if (md == NULL || md->md_threshold == 0 || md->md_me != NULL) {
+		CERROR("Dropping GET ("LPU64":%d:%s): MD (%d) invalid\n",
+		       match_bits, portal, libcfs_id2str(target),
+		       md == NULL ? -1 : md->md_threshold);
+		if (md != NULL && md->md_me != NULL)
+			CERROR("REPLY MD also attached to portal %d\n",
+			       md->md_me->me_portal);
+
+		lnet_res_unlock(cpt);
+
+		lnet_msg_free(msg);
+
+		return -ENOENT;
+	}
+
+	CDEBUG(D_NET, "LNetGet -> %s\n", libcfs_id2str(target));
+
+	lnet_msg_attach_md(msg, md, 0, 0);
+
+	lnet_prep_send(msg, LNET_MSG_GET, target, 0, 0);
+
+	msg->msg_hdr.msg.get.match_bits = cpu_to_le64(match_bits);
+	msg->msg_hdr.msg.get.ptl_index = cpu_to_le32(portal);
+	msg->msg_hdr.msg.get.src_offset = cpu_to_le32(offset);
+	msg->msg_hdr.msg.get.sink_length = cpu_to_le32(md->md_length);
+
+	/* NB handles only looked up by creator (no flips) */
+	msg->msg_hdr.msg.get.return_wmd.wh_interface_cookie =
+		the_lnet.ln_interface_cookie;
+	msg->msg_hdr.msg.get.return_wmd.wh_object_cookie =
+		md->md_lh.lh_cookie;
+
+	lnet_res_unlock(cpt);
+
+	lnet_build_msg_event(msg, LNET_EVENT_SEND);
+
+	rc = lnet_send(self, msg, LNET_NID_ANY);
+	if (rc < 0) {
+		CNETERR( "Error sending GET to %s: %d\n",
+		       libcfs_id2str(target), rc);
+		lnet_finalize (NULL, msg, rc);
+	}
+
+	/* completion will be signalled by an event */
+	return 0;
+}
+EXPORT_SYMBOL(LNetGet);
+
+/**
+ * Calculate distance to node at \a dstnid.
+ *
+ * \param dstnid Target NID.
+ * \param srcnidp If not NULL, NID of the local interface to reach \a dstnid
+ * is saved here.
+ * \param orderp If not NULL, order of the route to reach \a dstnid is saved
+ * here.
+ *
+ * \retval 0 If \a dstnid belongs to a local interface, and reserved option
+ * local_nid_dist_zero is set, which is the default.
+ * \retval positives Distance to target NID, i.e. number of hops plus one.
+ * \retval -EHOSTUNREACH If \a dstnid is not reachable.
+ */
+int
+LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
+{
+	struct list_head		*e;
+	struct lnet_ni		*ni;
+	lnet_remotenet_t	*rnet;
+	__u32			dstnet = LNET_NIDNET(dstnid);
+	int			hops;
+	int			cpt;
+	__u32			order = 2;
+	struct list_head		*rn_list;
+
+	/* if !local_nid_dist_zero, I don't return a distance of 0 ever
+	 * (when lustre sees a distance of 0, it substitutes 0@lo), so I
+	 * keep order 0 free for 0@lo and order 1 free for a local NID
+	 * match */
+
+	LASSERT (the_lnet.ln_init);
+	LASSERT (the_lnet.ln_refcount > 0);
+
+	cpt = lnet_net_lock_current();
+
+	list_for_each (e, &the_lnet.ln_nis) {
+		ni = list_entry(e, lnet_ni_t, ni_list);
+
+		if (ni->ni_nid == dstnid) {
+			if (srcnidp != NULL)
+				*srcnidp = dstnid;
+			if (orderp != NULL) {
+				if (LNET_NETTYP(LNET_NIDNET(dstnid)) == LOLND)
+					*orderp = 0;
+				else
+					*orderp = 1;
+			}
+			lnet_net_unlock(cpt);
+
+			return local_nid_dist_zero ? 0 : 1;
+		}
+
+		if (LNET_NIDNET(ni->ni_nid) == dstnet) {
+			if (srcnidp != NULL)
+				*srcnidp = ni->ni_nid;
+			if (orderp != NULL)
+				*orderp = order;
+			lnet_net_unlock(cpt);
+			return 1;
+		}
+
+		order++;
+	}
+
+	rn_list = lnet_net2rnethash(dstnet);
+	list_for_each(e, rn_list) {
+		rnet = list_entry(e, lnet_remotenet_t, lrn_list);
+
+		if (rnet->lrn_net == dstnet) {
+			lnet_route_t *route;
+			lnet_route_t *shortest = NULL;
+
+			LASSERT (!list_empty(&rnet->lrn_routes));
+
+			list_for_each_entry(route, &rnet->lrn_routes,
+						lr_list) {
+				if (shortest == NULL ||
+				    route->lr_hops < shortest->lr_hops)
+					shortest = route;
+			}
+
+			LASSERT (shortest != NULL);
+			hops = shortest->lr_hops;
+			if (srcnidp != NULL)
+				*srcnidp = shortest->lr_gateway->lp_ni->ni_nid;
+			if (orderp != NULL)
+				*orderp = order;
+			lnet_net_unlock(cpt);
+			return hops + 1;
+		}
+		order++;
+	}
+
+	lnet_net_unlock(cpt);
+	return -EHOSTUNREACH;
+}
+EXPORT_SYMBOL(LNetDist);
+
+/**
+ * Set the number of asynchronous messages expected from a target process.
+ *
+ * This function is only meaningful for userspace callers. It's a no-op when
+ * called from kernel.
+ *
+ * Asynchronous messages are those that can come from a target when the
+ * userspace process is not waiting for IO to complete; e.g., AST callbacks
+ * from Lustre servers. Specifying the expected number of such messages
+ * allows them to be eagerly received when user process is not running in
+ * LNet; otherwise network errors may occur.
+ *
+ * \param id Process ID of the target process.
+ * \param nasync Number of asynchronous messages expected from the target.
+ *
+ * \return 0 on success, and an error code otherwise.
+ */
+int
+LNetSetAsync(lnet_process_id_t id, int nasync)
+{
+	return 0;
+}
+EXPORT_SYMBOL(LNetSetAsync);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-msg.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-msg.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-msg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-msg.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,650 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/lnet/lib-msg.c
+ *
+ * Message decoding, parsing and finalizing routines
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include <linux/lnet/lib-lnet.h>
+
+void
+lnet_build_unlink_event (lnet_libmd_t *md, lnet_event_t *ev)
+{
+	ENTRY;
+
+	memset(ev, 0, sizeof(*ev));
+
+	ev->status   = 0;
+	ev->unlinked = 1;
+	ev->type     = LNET_EVENT_UNLINK;
+	lnet_md_deconstruct(md, &ev->md);
+	lnet_md2handle(&ev->md_handle, md);
+	EXIT;
+}
+
+/*
+ * Don't need any lock, must be called after lnet_commit_md
+ */
+void
+lnet_build_msg_event(lnet_msg_t *msg, lnet_event_kind_t ev_type)
+{
+	lnet_hdr_t	*hdr = &msg->msg_hdr;
+	lnet_event_t	*ev  = &msg->msg_ev;
+
+	LASSERT(!msg->msg_routing);
+
+	ev->type = ev_type;
+
+	if (ev_type == LNET_EVENT_SEND) {
+		/* event for active message */
+		ev->target.nid    = le64_to_cpu(hdr->dest_nid);
+		ev->target.pid    = le32_to_cpu(hdr->dest_pid);
+		ev->initiator.nid = LNET_NID_ANY;
+		ev->initiator.pid = the_lnet.ln_pid;
+		ev->sender	  = LNET_NID_ANY;
+
+	} else {
+		/* event for passive message */
+		ev->target.pid    = hdr->dest_pid;
+		ev->target.nid    = hdr->dest_nid;
+		ev->initiator.pid = hdr->src_pid;
+		ev->initiator.nid = hdr->src_nid;
+		ev->rlength       = hdr->payload_length;
+		ev->sender	  = msg->msg_from;
+		ev->mlength	  = msg->msg_wanted;
+		ev->offset	  = msg->msg_offset;
+	}
+
+	switch (ev_type) {
+	default:
+		LBUG();
+
+	case LNET_EVENT_PUT: /* passive PUT */
+		ev->pt_index   = hdr->msg.put.ptl_index;
+		ev->match_bits = hdr->msg.put.match_bits;
+		ev->hdr_data   = hdr->msg.put.hdr_data;
+		return;
+
+	case LNET_EVENT_GET: /* passive GET */
+		ev->pt_index   = hdr->msg.get.ptl_index;
+		ev->match_bits = hdr->msg.get.match_bits;
+		ev->hdr_data   = 0;
+		return;
+
+	case LNET_EVENT_ACK: /* ACK */
+		ev->match_bits = hdr->msg.ack.match_bits;
+		ev->mlength    = hdr->msg.ack.mlength;
+		return;
+
+	case LNET_EVENT_REPLY: /* REPLY */
+		return;
+
+	case LNET_EVENT_SEND: /* active message */
+		if (msg->msg_type == LNET_MSG_PUT) {
+			ev->pt_index   = le32_to_cpu(hdr->msg.put.ptl_index);
+			ev->match_bits = le64_to_cpu(hdr->msg.put.match_bits);
+			ev->offset     = le32_to_cpu(hdr->msg.put.offset);
+			ev->mlength    =
+			ev->rlength    = le32_to_cpu(hdr->payload_length);
+			ev->hdr_data   = le64_to_cpu(hdr->msg.put.hdr_data);
+
+		} else {
+			LASSERT(msg->msg_type == LNET_MSG_GET);
+			ev->pt_index   = le32_to_cpu(hdr->msg.get.ptl_index);
+			ev->match_bits = le64_to_cpu(hdr->msg.get.match_bits);
+			ev->mlength    =
+			ev->rlength    = le32_to_cpu(hdr->msg.get.sink_length);
+			ev->offset     = le32_to_cpu(hdr->msg.get.src_offset);
+			ev->hdr_data   = 0;
+		}
+		return;
+	}
+}
+
+void
+lnet_msg_commit(lnet_msg_t *msg, int cpt)
+{
+	struct lnet_msg_container *container = the_lnet.ln_msg_containers[cpt];
+	lnet_counters_t		  *counters  = the_lnet.ln_counters[cpt];
+
+	/* routed message can be committed for both receiving and sending */
+	LASSERT(!msg->msg_tx_committed);
+
+	if (msg->msg_sending) {
+		LASSERT(!msg->msg_receiving);
+
+		msg->msg_tx_cpt = cpt;
+		msg->msg_tx_committed = 1;
+		if (msg->msg_rx_committed) { /* routed message REPLY */
+			LASSERT(msg->msg_onactivelist);
+			return;
+		}
+	} else {
+		LASSERT(!msg->msg_sending);
+		msg->msg_rx_cpt = cpt;
+		msg->msg_rx_committed = 1;
+	}
+
+	LASSERT(!msg->msg_onactivelist);
+	msg->msg_onactivelist = 1;
+	list_add(&msg->msg_activelist, &container->msc_active);
+
+	counters->msgs_alloc++;
+	if (counters->msgs_alloc > counters->msgs_max)
+		counters->msgs_max = counters->msgs_alloc;
+}
+
+static void
+lnet_msg_decommit_tx(lnet_msg_t *msg, int status)
+{
+	lnet_counters_t	*counters;
+	lnet_event_t	*ev = &msg->msg_ev;
+
+	LASSERT(msg->msg_tx_committed);
+	if (status != 0)
+		goto out;
+
+	counters = the_lnet.ln_counters[msg->msg_tx_cpt];
+	switch (ev->type) {
+	default: /* routed message */
+		LASSERT(msg->msg_routing);
+		LASSERT(msg->msg_rx_committed);
+		LASSERT(ev->type == 0);
+
+		counters->route_length += msg->msg_len;
+		counters->route_count++;
+		goto out;
+
+	case LNET_EVENT_PUT:
+		/* should have been decommitted */
+		LASSERT(!msg->msg_rx_committed);
+		/* overwritten while sending ACK */
+		LASSERT(msg->msg_type == LNET_MSG_ACK);
+		msg->msg_type = LNET_MSG_PUT; /* fix type */
+		break;
+
+	case LNET_EVENT_SEND:
+		LASSERT(!msg->msg_rx_committed);
+		if (msg->msg_type == LNET_MSG_PUT)
+			counters->send_length += msg->msg_len;
+		break;
+
+	case LNET_EVENT_GET:
+		LASSERT(msg->msg_rx_committed);
+		/* overwritten while sending reply, we should never be
+		 * here for optimized GET */
+		LASSERT(msg->msg_type == LNET_MSG_REPLY);
+		msg->msg_type = LNET_MSG_GET; /* fix type */
+		break;
+	}
+
+	counters->send_count++;
+ out:
+	lnet_return_tx_credits_locked(msg);
+	msg->msg_tx_committed = 0;
+}
+
+static void
+lnet_msg_decommit_rx(lnet_msg_t *msg, int status)
+{
+	lnet_counters_t	*counters;
+	lnet_event_t	*ev = &msg->msg_ev;
+
+	LASSERT(!msg->msg_tx_committed); /* decommitted or never committed */
+	LASSERT(msg->msg_rx_committed);
+
+	if (status != 0)
+		goto out;
+
+	counters = the_lnet.ln_counters[msg->msg_rx_cpt];
+	switch (ev->type) {
+	default:
+		LASSERT(ev->type == 0);
+		LASSERT(msg->msg_routing);
+		goto out;
+
+	case LNET_EVENT_ACK:
+		LASSERT(msg->msg_type == LNET_MSG_ACK);
+		break;
+
+	case LNET_EVENT_GET:
+		/* type is "REPLY" if it's an optimized GET on passive side,
+		 * because optimized GET will never be committed for sending,
+		 * so message type wouldn't be changed back to "GET" by
+		 * lnet_msg_decommit_tx(), see details in lnet_parse_get() */
+		LASSERT(msg->msg_type == LNET_MSG_REPLY ||
+			msg->msg_type == LNET_MSG_GET);
+		counters->send_length += msg->msg_wanted;
+		break;
+
+	case LNET_EVENT_PUT:
+		LASSERT(msg->msg_type == LNET_MSG_PUT);
+		break;
+
+	case LNET_EVENT_REPLY:
+		/* type is "GET" if it's an optimized GET on active side,
+		 * see details in lnet_create_reply_msg() */
+		LASSERT(msg->msg_type == LNET_MSG_GET ||
+			msg->msg_type == LNET_MSG_REPLY);
+		break;
+	}
+
+	counters->recv_count++;
+	if (ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_REPLY)
+		counters->recv_length += msg->msg_wanted;
+
+ out:
+	lnet_return_rx_credits_locked(msg);
+	msg->msg_rx_committed = 0;
+}
+
+void
+lnet_msg_decommit(lnet_msg_t *msg, int cpt, int status)
+{
+	int	cpt2 = cpt;
+
+	LASSERT(msg->msg_tx_committed || msg->msg_rx_committed);
+	LASSERT(msg->msg_onactivelist);
+
+	if (msg->msg_tx_committed) { /* always decommit for sending first */
+		LASSERT(cpt == msg->msg_tx_cpt);
+		lnet_msg_decommit_tx(msg, status);
+	}
+
+	if (msg->msg_rx_committed) {
+		/* forwarding msg committed for both receiving and sending */
+		if (cpt != msg->msg_rx_cpt) {
+			lnet_net_unlock(cpt);
+			cpt2 = msg->msg_rx_cpt;
+			lnet_net_lock(cpt2);
+		}
+		lnet_msg_decommit_rx(msg, status);
+	}
+
+	list_del(&msg->msg_activelist);
+	msg->msg_onactivelist = 0;
+
+	the_lnet.ln_counters[cpt2]->msgs_alloc--;
+
+	if (cpt2 != cpt) {
+		lnet_net_unlock(cpt2);
+		lnet_net_lock(cpt);
+	}
+}
+
+void
+lnet_msg_attach_md(lnet_msg_t *msg, lnet_libmd_t *md,
+		   unsigned int offset, unsigned int mlen)
+{
+	/* NB: @offset and @len are only useful for receiving */
+	/* Here, we attach the MD on lnet_msg and mark it busy and
+	 * decrementing its threshold. Come what may, the lnet_msg "owns"
+	 * the MD until a call to lnet_msg_detach_md or lnet_finalize()
+	 * signals completion. */
+	LASSERT(!msg->msg_routing);
+
+	msg->msg_md = md;
+	if (msg->msg_receiving) { /* commited for receiving */
+		msg->msg_offset = offset;
+		msg->msg_wanted = mlen;
+	}
+
+	md->md_refcount++;
+	if (md->md_threshold != LNET_MD_THRESH_INF) {
+		LASSERT(md->md_threshold > 0);
+		md->md_threshold--;
+	}
+
+	/* build umd in event */
+	lnet_md2handle(&msg->msg_ev.md_handle, md);
+	lnet_md_deconstruct(md, &msg->msg_ev.md);
+}
+
+void
+lnet_msg_detach_md(lnet_msg_t *msg, int status)
+{
+	lnet_libmd_t	*md = msg->msg_md;
+	int		unlink;
+
+	/* Now it's safe to drop my caller's ref */
+	md->md_refcount--;
+	LASSERT(md->md_refcount >= 0);
+
+	unlink = lnet_md_unlinkable(md);
+	if (md->md_eq != NULL) {
+		msg->msg_ev.status   = status;
+		msg->msg_ev.unlinked = unlink;
+		lnet_eq_enqueue_event(md->md_eq, &msg->msg_ev);
+	}
+
+	if (unlink)
+		lnet_md_unlink(md);
+
+	msg->msg_md = NULL;
+}
+
+static int
+lnet_complete_msg_locked(lnet_msg_t *msg, int cpt)
+{
+	lnet_handle_wire_t ack_wmd;
+	int		rc;
+	int		status = msg->msg_ev.status;
+
+	LASSERT (msg->msg_onactivelist);
+
+	if (status == 0 && msg->msg_ack) {
+		/* Only send an ACK if the PUT completed successfully */
+
+		lnet_msg_decommit(msg, cpt, 0);
+
+		msg->msg_ack = 0;
+		lnet_net_unlock(cpt);
+
+		LASSERT(msg->msg_ev.type == LNET_EVENT_PUT);
+		LASSERT(!msg->msg_routing);
+
+		ack_wmd = msg->msg_hdr.msg.put.ack_wmd;
+
+		lnet_prep_send(msg, LNET_MSG_ACK, msg->msg_ev.initiator, 0, 0);
+
+		msg->msg_hdr.msg.ack.dst_wmd = ack_wmd;
+		msg->msg_hdr.msg.ack.match_bits = msg->msg_ev.match_bits;
+		msg->msg_hdr.msg.ack.mlength = cpu_to_le32(msg->msg_ev.mlength);
+
+		/* NB: we probably want to use NID of msg::msg_from as 3rd
+		 * parameter (router NID) if it's routed message */
+		rc = lnet_send(msg->msg_ev.target.nid, msg, LNET_NID_ANY);
+
+		lnet_net_lock(cpt);
+		/*
+		 * NB: message is committed for sending, we should return
+		 * on success because LND will finalize this message later.
+		 *
+		 * Also, there is possibility that message is commited for
+		 * sending and also failed before delivering to LND,
+		 * i.e: ENOMEM, in that case we can't fall through either
+		 * because CPT for sending can be different with CPT for
+		 * receiving, so we should return back to lnet_finalize()
+		 * to make sure we are locking the correct partition.
+		 */
+		return rc;
+
+	} else if (status == 0 &&	/* OK so far */
+		   (msg->msg_routing && !msg->msg_sending)) {
+		/* not forwarded */
+		LASSERT(!msg->msg_receiving);	/* called back recv already */
+		lnet_net_unlock(cpt);
+
+		rc = lnet_send(LNET_NID_ANY, msg, LNET_NID_ANY);
+
+		lnet_net_lock(cpt);
+		/*
+		 * NB: message is committed for sending, we should return
+		 * on success because LND will finalize this message later.
+		 *
+		 * Also, there is possibility that message is commited for
+		 * sending and also failed before delivering to LND,
+		 * i.e: ENOMEM, in that case we can't fall through either:
+		 * - The rule is message must decommit for sending first if
+		 *   the it's committed for both sending and receiving
+		 * - CPT for sending can be different with CPT for receiving,
+		 *   so we should return back to lnet_finalize() to make
+		 *   sure we are locking the correct partition.
+		 */
+		return rc;
+	}
+
+	lnet_msg_decommit(msg, cpt, status);
+	lnet_msg_free_locked(msg);
+	return 0;
+}
+
+void
+lnet_finalize (lnet_ni_t *ni, lnet_msg_t *msg, int status)
+{
+	struct lnet_msg_container	*container;
+	int				my_slot;
+	int				cpt;
+	int				rc;
+	int				i;
+
+	LASSERT (!in_interrupt ());
+
+	if (msg == NULL)
+		return;
+#if 0
+	CDEBUG(D_WARNING, "%s msg->%s Flags:%s%s%s%s%s%s%s%s%s%s%s txp %s rxp %s\n",
+	       lnet_msgtyp2str(msg->msg_type), libcfs_id2str(msg->msg_target),
+	       msg->msg_target_is_router ? "t" : "",
+	       msg->msg_routing ? "X" : "",
+	       msg->msg_ack ? "A" : "",
+	       msg->msg_sending ? "S" : "",
+	       msg->msg_receiving ? "R" : "",
+	       msg->msg_delayed ? "d" : "",
+	       msg->msg_txcredit ? "C" : "",
+	       msg->msg_peertxcredit ? "c" : "",
+	       msg->msg_rtrcredit ? "F" : "",
+	       msg->msg_peerrtrcredit ? "f" : "",
+	       msg->msg_onactivelist ? "!" : "",
+	       msg->msg_txpeer == NULL ? "<none>" : libcfs_nid2str(msg->msg_txpeer->lp_nid),
+	       msg->msg_rxpeer == NULL ? "<none>" : libcfs_nid2str(msg->msg_rxpeer->lp_nid));
+#endif
+	msg->msg_ev.status = status;
+
+	if (msg->msg_md != NULL) {
+		cpt = lnet_cpt_of_cookie(msg->msg_md->md_lh.lh_cookie);
+
+		lnet_res_lock(cpt);
+		lnet_msg_detach_md(msg, status);
+		lnet_res_unlock(cpt);
+	}
+
+ again:
+	rc = 0;
+	if (!msg->msg_tx_committed && !msg->msg_rx_committed) {
+		/* not commited to network yet */
+		LASSERT(!msg->msg_onactivelist);
+		lnet_msg_free(msg);
+		return;
+	}
+
+	/*
+	 * NB: routed message can be commited for both receiving and sending,
+	 * we should finalize in LIFO order and keep counters correct.
+	 * (finalize sending first then finalize receiving)
+	 */
+	cpt = msg->msg_tx_committed ? msg->msg_tx_cpt : msg->msg_rx_cpt;
+	lnet_net_lock(cpt);
+
+	container = the_lnet.ln_msg_containers[cpt];
+	list_add_tail(&msg->msg_list, &container->msc_finalizing);
+
+	/* Recursion breaker.  Don't complete the message here if I am (or
+	 * enough other threads are) already completing messages */
+
+	my_slot = -1;
+	for (i = 0; i < container->msc_nfinalizers; i++) {
+		if (container->msc_finalizers[i] == current)
+			break;
+
+		if (my_slot < 0 && container->msc_finalizers[i] == NULL)
+			my_slot = i;
+	}
+
+	if (i < container->msc_nfinalizers || my_slot < 0) {
+		lnet_net_unlock(cpt);
+		return;
+	}
+
+	container->msc_finalizers[my_slot] = current;
+
+	while (!list_empty(&container->msc_finalizing)) {
+		msg = list_entry(container->msc_finalizing.next,
+				     lnet_msg_t, msg_list);
+
+		list_del(&msg->msg_list);
+
+		/* NB drops and regains the lnet lock if it actually does
+		 * anything, so my finalizing friends can chomp along too */
+		rc = lnet_complete_msg_locked(msg, cpt);
+		if (rc != 0)
+			break;
+	}
+
+	container->msc_finalizers[my_slot] = NULL;
+	lnet_net_unlock(cpt);
+
+	if (rc != 0)
+		goto again;
+}
+EXPORT_SYMBOL(lnet_finalize);
+
+void
+lnet_msg_container_cleanup(struct lnet_msg_container *container)
+{
+	int     count = 0;
+
+	if (container->msc_init == 0)
+		return;
+
+	while (!list_empty(&container->msc_active)) {
+		lnet_msg_t *msg = list_entry(container->msc_active.next,
+						 lnet_msg_t, msg_activelist);
+
+		LASSERT(msg->msg_onactivelist);
+		msg->msg_onactivelist = 0;
+		list_del(&msg->msg_activelist);
+		lnet_msg_free(msg);
+		count++;
+	}
+
+	if (count > 0)
+		CERROR("%d active msg on exit\n", count);
+
+	if (container->msc_finalizers != NULL) {
+		LIBCFS_FREE(container->msc_finalizers,
+			    container->msc_nfinalizers *
+			    sizeof(*container->msc_finalizers));
+		container->msc_finalizers = NULL;
+	}
+#ifdef LNET_USE_LIB_FREELIST
+	lnet_freelist_fini(&container->msc_freelist);
+#endif
+	container->msc_init = 0;
+}
+
+int
+lnet_msg_container_setup(struct lnet_msg_container *container, int cpt)
+{
+	int	rc;
+
+	container->msc_init = 1;
+
+	INIT_LIST_HEAD(&container->msc_active);
+	INIT_LIST_HEAD(&container->msc_finalizing);
+
+#ifdef LNET_USE_LIB_FREELIST
+	memset(&container->msc_freelist, 0, sizeof(lnet_freelist_t));
+
+	rc = lnet_freelist_init(&container->msc_freelist,
+				LNET_FL_MAX_MSGS, sizeof(lnet_msg_t));
+	if (rc != 0) {
+		CERROR("Failed to init freelist for message container\n");
+		lnet_msg_container_cleanup(container);
+		return rc;
+	}
+#else
+	rc = 0;
+#endif
+	/* number of CPUs */
+	container->msc_nfinalizers = cfs_cpt_weight(lnet_cpt_table(), cpt);
+
+	LIBCFS_CPT_ALLOC(container->msc_finalizers, lnet_cpt_table(), cpt,
+			 container->msc_nfinalizers *
+			 sizeof(*container->msc_finalizers));
+
+	if (container->msc_finalizers == NULL) {
+		CERROR("Failed to allocate message finalizers\n");
+		lnet_msg_container_cleanup(container);
+		return -ENOMEM;
+	}
+
+	return rc;
+}
+
+void
+lnet_msg_containers_destroy(void)
+{
+	struct lnet_msg_container *container;
+	int     i;
+
+	if (the_lnet.ln_msg_containers == NULL)
+		return;
+
+	cfs_percpt_for_each(container, i, the_lnet.ln_msg_containers)
+		lnet_msg_container_cleanup(container);
+
+	cfs_percpt_free(the_lnet.ln_msg_containers);
+	the_lnet.ln_msg_containers = NULL;
+}
+
+int
+lnet_msg_containers_create(void)
+{
+	struct lnet_msg_container *container;
+	int	rc;
+	int	i;
+
+	the_lnet.ln_msg_containers = cfs_percpt_alloc(lnet_cpt_table(),
+						      sizeof(*container));
+
+	if (the_lnet.ln_msg_containers == NULL) {
+		CERROR("Failed to allocate cpu-partition data for network\n");
+		return -ENOMEM;
+	}
+
+	cfs_percpt_for_each(container, i, the_lnet.ln_msg_containers) {
+		rc = lnet_msg_container_setup(container, i);
+		if (rc != 0) {
+			lnet_msg_containers_destroy();
+			return rc;
+		}
+	}
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-ptl.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-ptl.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lib-ptl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lib-ptl.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,938 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/lnet/lib-ptl.c
+ *
+ * portal & match routines
+ *
+ * Author: liang@whamcloud.com
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include <linux/lnet/lib-lnet.h>
+
+/* NB: add /proc interfaces in upcoming patches */
+int	portal_rotor	= LNET_PTL_ROTOR_HASH_RT;
+CFS_MODULE_PARM(portal_rotor, "i", int, 0644,
+		"redirect PUTs to different cpu-partitions");
+
+static int
+lnet_ptl_match_type(unsigned int index, lnet_process_id_t match_id,
+		    __u64 mbits, __u64 ignore_bits)
+{
+	struct lnet_portal	*ptl = the_lnet.ln_portals[index];
+	int			unique;
+
+	unique = ignore_bits == 0 &&
+		 match_id.nid != LNET_NID_ANY &&
+		 match_id.pid != LNET_PID_ANY;
+
+	LASSERT(!lnet_ptl_is_unique(ptl) || !lnet_ptl_is_wildcard(ptl));
+
+	/* prefer to check w/o any lock */
+	if (likely(lnet_ptl_is_unique(ptl) || lnet_ptl_is_wildcard(ptl)))
+		goto match;
+
+	/* unset, new portal */
+	lnet_ptl_lock(ptl);
+	/* check again with lock */
+	if (unlikely(lnet_ptl_is_unique(ptl) || lnet_ptl_is_wildcard(ptl))) {
+		lnet_ptl_unlock(ptl);
+		goto match;
+	}
+
+	/* still not set */
+	if (unique)
+		lnet_ptl_setopt(ptl, LNET_PTL_MATCH_UNIQUE);
+	else
+		lnet_ptl_setopt(ptl, LNET_PTL_MATCH_WILDCARD);
+
+	lnet_ptl_unlock(ptl);
+
+	return 1;
+
+ match:
+	if ((lnet_ptl_is_unique(ptl) && !unique) ||
+	    (lnet_ptl_is_wildcard(ptl) && unique))
+		return 0;
+	return 1;
+}
+
+static void
+lnet_ptl_enable_mt(struct lnet_portal *ptl, int cpt)
+{
+	struct lnet_match_table	*mtable = ptl->ptl_mtables[cpt];
+	int			i;
+
+	/* with hold of both lnet_res_lock(cpt) and lnet_ptl_lock */
+	LASSERT(lnet_ptl_is_wildcard(ptl));
+
+	mtable->mt_enabled = 1;
+
+	ptl->ptl_mt_maps[ptl->ptl_mt_nmaps] = cpt;
+	for (i = ptl->ptl_mt_nmaps - 1; i >= 0; i--) {
+		LASSERT(ptl->ptl_mt_maps[i] != cpt);
+		if (ptl->ptl_mt_maps[i] < cpt)
+			break;
+
+		/* swap to order */
+		ptl->ptl_mt_maps[i + 1] = ptl->ptl_mt_maps[i];
+		ptl->ptl_mt_maps[i] = cpt;
+	}
+
+	ptl->ptl_mt_nmaps++;
+}
+
+static void
+lnet_ptl_disable_mt(struct lnet_portal *ptl, int cpt)
+{
+	struct lnet_match_table	*mtable = ptl->ptl_mtables[cpt];
+	int			i;
+
+	/* with hold of both lnet_res_lock(cpt) and lnet_ptl_lock */
+	LASSERT(lnet_ptl_is_wildcard(ptl));
+
+	if (LNET_CPT_NUMBER == 1)
+		return; /* never disable the only match-table */
+
+	mtable->mt_enabled = 0;
+
+	LASSERT(ptl->ptl_mt_nmaps > 0 &&
+		ptl->ptl_mt_nmaps <= LNET_CPT_NUMBER);
+
+	/* remove it from mt_maps */
+	ptl->ptl_mt_nmaps--;
+	for (i = 0; i < ptl->ptl_mt_nmaps; i++) {
+		if (ptl->ptl_mt_maps[i] >= cpt) /* overwrite it */
+			ptl->ptl_mt_maps[i] = ptl->ptl_mt_maps[i + 1];
+	}
+}
+
+static int
+lnet_try_match_md(lnet_libmd_t *md,
+		  struct lnet_match_info *info, struct lnet_msg *msg)
+{
+	/* ALWAYS called holding the lnet_res_lock, and can't lnet_res_unlock;
+	 * lnet_match_blocked_msg() relies on this to avoid races */
+	unsigned int	offset;
+	unsigned int	mlength;
+	lnet_me_t	*me = md->md_me;
+
+	/* MD exhausted */
+	if (lnet_md_exhausted(md))
+		return LNET_MATCHMD_NONE | LNET_MATCHMD_EXHAUSTED;
+
+	/* mismatched MD op */
+	if ((md->md_options & info->mi_opc) == 0)
+		return LNET_MATCHMD_NONE;
+
+	/* mismatched ME nid/pid? */
+	if (me->me_match_id.nid != LNET_NID_ANY &&
+	    me->me_match_id.nid != info->mi_id.nid)
+		return LNET_MATCHMD_NONE;
+
+	if (me->me_match_id.pid != LNET_PID_ANY &&
+	    me->me_match_id.pid != info->mi_id.pid)
+		return LNET_MATCHMD_NONE;
+
+	/* mismatched ME matchbits? */
+	if (((me->me_match_bits ^ info->mi_mbits) & ~me->me_ignore_bits) != 0)
+		return LNET_MATCHMD_NONE;
+
+	/* Hurrah! This _is_ a match; check it out... */
+
+	if ((md->md_options & LNET_MD_MANAGE_REMOTE) == 0)
+		offset = md->md_offset;
+	else
+		offset = info->mi_roffset;
+
+	if ((md->md_options & LNET_MD_MAX_SIZE) != 0) {
+		mlength = md->md_max_size;
+		LASSERT(md->md_offset + mlength <= md->md_length);
+	} else {
+		mlength = md->md_length - offset;
+	}
+
+	if (info->mi_rlength <= mlength) {	/* fits in allowed space */
+		mlength = info->mi_rlength;
+	} else if ((md->md_options & LNET_MD_TRUNCATE) == 0) {
+		/* this packet _really_ is too big */
+		CERROR("Matching packet from %s, match "LPU64
+		       " length %d too big: %d left, %d allowed\n",
+		       libcfs_id2str(info->mi_id), info->mi_mbits,
+		       info->mi_rlength, md->md_length - offset, mlength);
+
+		return LNET_MATCHMD_DROP;
+	}
+
+	/* Commit to this ME/MD */
+	CDEBUG(D_NET, "Incoming %s index %x from %s of "
+	       "length %d/%d into md "LPX64" [%d] + %d\n",
+	       (info->mi_opc == LNET_MD_OP_PUT) ? "put" : "get",
+	       info->mi_portal, libcfs_id2str(info->mi_id), mlength,
+	       info->mi_rlength, md->md_lh.lh_cookie, md->md_niov, offset);
+
+	lnet_msg_attach_md(msg, md, offset, mlength);
+	md->md_offset = offset + mlength;
+
+	if (!lnet_md_exhausted(md))
+		return LNET_MATCHMD_OK;
+
+	/* Auto-unlink NOW, so the ME gets unlinked if required.
+	 * We bumped md->md_refcount above so the MD just gets flagged
+	 * for unlink when it is finalized. */
+	if ((md->md_flags & LNET_MD_FLAG_AUTO_UNLINK) != 0)
+		lnet_md_unlink(md);
+
+	return LNET_MATCHMD_OK | LNET_MATCHMD_EXHAUSTED;
+}
+
+static struct lnet_match_table *
+lnet_match2mt(struct lnet_portal *ptl, lnet_process_id_t id, __u64 mbits)
+{
+	if (LNET_CPT_NUMBER == 1)
+		return ptl->ptl_mtables[0]; /* the only one */
+
+	/* if it's a unique portal, return match-table hashed by NID */
+	return lnet_ptl_is_unique(ptl) ?
+	       ptl->ptl_mtables[lnet_cpt_of_nid(id.nid)] : NULL;
+}
+
+struct lnet_match_table *
+lnet_mt_of_attach(unsigned int index, lnet_process_id_t id,
+		  __u64 mbits, __u64 ignore_bits, lnet_ins_pos_t pos)
+{
+	struct lnet_portal	*ptl;
+	struct lnet_match_table	*mtable;
+
+	/* NB: called w/o lock */
+	LASSERT(index < the_lnet.ln_nportals);
+
+	if (!lnet_ptl_match_type(index, id, mbits, ignore_bits))
+		return NULL;
+
+	ptl = the_lnet.ln_portals[index];
+
+	mtable = lnet_match2mt(ptl, id, mbits);
+	if (mtable != NULL) /* unique portal or only one match-table */
+		return mtable;
+
+	/* it's a wildcard portal */
+	switch (pos) {
+	default:
+		return NULL;
+	case LNET_INS_BEFORE:
+	case LNET_INS_AFTER:
+		/* posted by no affinity thread, always hash to specific
+		 * match-table to avoid buffer stealing which is heavy */
+		return ptl->ptl_mtables[ptl->ptl_index % LNET_CPT_NUMBER];
+	case LNET_INS_LOCAL:
+		/* posted by cpu-affinity thread */
+		return ptl->ptl_mtables[lnet_cpt_current()];
+	}
+}
+
+static struct lnet_match_table *
+lnet_mt_of_match(struct lnet_match_info *info, struct lnet_msg *msg)
+{
+	struct lnet_match_table	*mtable;
+	struct lnet_portal	*ptl;
+	int			nmaps;
+	int			rotor;
+	int			routed;
+	int			cpt;
+
+	/* NB: called w/o lock */
+	LASSERT(info->mi_portal < the_lnet.ln_nportals);
+	ptl = the_lnet.ln_portals[info->mi_portal];
+
+	LASSERT(lnet_ptl_is_wildcard(ptl) || lnet_ptl_is_unique(ptl));
+
+	mtable = lnet_match2mt(ptl, info->mi_id, info->mi_mbits);
+	if (mtable != NULL)
+		return mtable;
+
+	/* it's a wildcard portal */
+	routed = LNET_NIDNET(msg->msg_hdr.src_nid) !=
+		 LNET_NIDNET(msg->msg_hdr.dest_nid);
+
+	if (portal_rotor == LNET_PTL_ROTOR_OFF ||
+	    (portal_rotor != LNET_PTL_ROTOR_ON && !routed)) {
+		cpt = lnet_cpt_current();
+		if (ptl->ptl_mtables[cpt]->mt_enabled)
+			return ptl->ptl_mtables[cpt];
+	}
+
+	rotor = ptl->ptl_rotor++; /* get round-robin factor */
+	if (portal_rotor == LNET_PTL_ROTOR_HASH_RT && routed)
+		cpt = lnet_cpt_of_nid(msg->msg_hdr.src_nid);
+	else
+		cpt = rotor % LNET_CPT_NUMBER;
+
+	if (!ptl->ptl_mtables[cpt]->mt_enabled) {
+		/* is there any active entry for this portal? */
+		nmaps = ptl->ptl_mt_nmaps;
+		/* map to an active mtable to avoid heavy "stealing" */
+		if (nmaps != 0) {
+			/* NB: there is possibility that ptl_mt_maps is being
+			 * changed because we are not under protection of
+			 * lnet_ptl_lock, but it shouldn't hurt anything */
+			cpt = ptl->ptl_mt_maps[rotor % nmaps];
+		}
+	}
+
+	return ptl->ptl_mtables[cpt];
+}
+
+static int
+lnet_mt_test_exhausted(struct lnet_match_table *mtable, int pos)
+{
+	__u64	*bmap;
+	int	i;
+
+	if (!lnet_ptl_is_wildcard(the_lnet.ln_portals[mtable->mt_portal]))
+		return 0;
+
+	if (pos < 0) { /* check all bits */
+		for (i = 0; i < LNET_MT_EXHAUSTED_BMAP; i++) {
+			if (mtable->mt_exhausted[i] != (__u64)(-1))
+				return 0;
+		}
+		return 1;
+	}
+
+	LASSERT(pos <= LNET_MT_HASH_IGNORE);
+	/* mtable::mt_mhash[pos] is marked as exhausted or not */
+	bmap = &mtable->mt_exhausted[pos >> LNET_MT_BITS_U64];
+	pos &= (1 << LNET_MT_BITS_U64) - 1;
+
+	return ((*bmap) & (1ULL << pos)) != 0;
+}
+
+static void
+lnet_mt_set_exhausted(struct lnet_match_table *mtable, int pos, int exhausted)
+{
+	__u64	*bmap;
+
+	LASSERT(lnet_ptl_is_wildcard(the_lnet.ln_portals[mtable->mt_portal]));
+	LASSERT(pos <= LNET_MT_HASH_IGNORE);
+
+	/* set mtable::mt_mhash[pos] as exhausted/non-exhausted */
+	bmap = &mtable->mt_exhausted[pos >> LNET_MT_BITS_U64];
+	pos &= (1 << LNET_MT_BITS_U64) - 1;
+
+	if (!exhausted)
+		*bmap &= ~(1ULL << pos);
+	else
+		*bmap |= 1ULL << pos;
+}
+
+struct list_head *
+lnet_mt_match_head(struct lnet_match_table *mtable,
+		   lnet_process_id_t id, __u64 mbits)
+{
+	struct lnet_portal *ptl = the_lnet.ln_portals[mtable->mt_portal];
+
+	if (lnet_ptl_is_wildcard(ptl)) {
+		return &mtable->mt_mhash[mbits & LNET_MT_HASH_MASK];
+	} else {
+		unsigned long hash = mbits + id.nid + id.pid;
+
+		LASSERT(lnet_ptl_is_unique(ptl));
+		hash = cfs_hash_long(hash, LNET_MT_HASH_BITS);
+		return &mtable->mt_mhash[hash];
+	}
+}
+
+int
+lnet_mt_match_md(struct lnet_match_table *mtable,
+		 struct lnet_match_info *info, struct lnet_msg *msg)
+{
+	struct list_head		*head;
+	lnet_me_t		*me;
+	lnet_me_t		*tmp;
+	int			exhausted = 0;
+	int			rc;
+
+	/* any ME with ignore bits? */
+	if (!list_empty(&mtable->mt_mhash[LNET_MT_HASH_IGNORE]))
+		head = &mtable->mt_mhash[LNET_MT_HASH_IGNORE];
+	else
+		head = lnet_mt_match_head(mtable, info->mi_id, info->mi_mbits);
+ again:
+	/* NB: only wildcard portal needs to return LNET_MATCHMD_EXHAUSTED */
+	if (lnet_ptl_is_wildcard(the_lnet.ln_portals[mtable->mt_portal]))
+		exhausted = LNET_MATCHMD_EXHAUSTED;
+
+	list_for_each_entry_safe(me, tmp, head, me_list) {
+		/* ME attached but MD not attached yet */
+		if (me->me_md == NULL)
+			continue;
+
+		LASSERT(me == me->me_md->md_me);
+
+		rc = lnet_try_match_md(me->me_md, info, msg);
+		if ((rc & LNET_MATCHMD_EXHAUSTED) == 0)
+			exhausted = 0; /* mlist is not empty */
+
+		if ((rc & LNET_MATCHMD_FINISH) != 0) {
+			/* don't return EXHAUSTED bit because we don't know
+			 * whether the mlist is empty or not */
+			return rc & ~LNET_MATCHMD_EXHAUSTED;
+		}
+	}
+
+	if (exhausted == LNET_MATCHMD_EXHAUSTED) { /* @head is exhausted */
+		lnet_mt_set_exhausted(mtable, head - mtable->mt_mhash, 1);
+		if (!lnet_mt_test_exhausted(mtable, -1))
+			exhausted = 0;
+	}
+
+	if (exhausted == 0 && head == &mtable->mt_mhash[LNET_MT_HASH_IGNORE]) {
+		head = lnet_mt_match_head(mtable, info->mi_id, info->mi_mbits);
+		goto again; /* re-check MEs w/o ignore-bits */
+	}
+
+	if (info->mi_opc == LNET_MD_OP_GET ||
+	    !lnet_ptl_is_lazy(the_lnet.ln_portals[info->mi_portal]))
+		return LNET_MATCHMD_DROP | exhausted;
+
+	return LNET_MATCHMD_NONE | exhausted;
+}
+
+static int
+lnet_ptl_match_early(struct lnet_portal *ptl, struct lnet_msg *msg)
+{
+	int	rc;
+
+	/* message arrived before any buffer posting on this portal,
+	 * simply delay or drop this message */
+	if (likely(lnet_ptl_is_wildcard(ptl) || lnet_ptl_is_unique(ptl)))
+		return 0;
+
+	lnet_ptl_lock(ptl);
+	/* check it again with hold of lock */
+	if (lnet_ptl_is_wildcard(ptl) || lnet_ptl_is_unique(ptl)) {
+		lnet_ptl_unlock(ptl);
+		return 0;
+	}
+
+	if (lnet_ptl_is_lazy(ptl)) {
+		if (msg->msg_rx_ready_delay) {
+			msg->msg_rx_delayed = 1;
+			list_add_tail(&msg->msg_list,
+					  &ptl->ptl_msg_delayed);
+		}
+		rc = LNET_MATCHMD_NONE;
+	} else {
+		rc = LNET_MATCHMD_DROP;
+	}
+
+	lnet_ptl_unlock(ptl);
+	return rc;
+}
+
+static int
+lnet_ptl_match_delay(struct lnet_portal *ptl,
+		     struct lnet_match_info *info, struct lnet_msg *msg)
+{
+	int	first = ptl->ptl_mt_maps[0]; /* read w/o lock */
+	int	rc = 0;
+	int	i;
+
+	/* steal buffer from other CPTs, and delay it if nothing to steal,
+	 * this function is more expensive than a regular match, but we
+	 * don't expect it can happen a lot */
+	LASSERT(lnet_ptl_is_wildcard(ptl));
+
+	for (i = 0; i < LNET_CPT_NUMBER; i++) {
+		struct lnet_match_table *mtable;
+		int			cpt;
+
+		cpt = (first + i) % LNET_CPT_NUMBER;
+		mtable = ptl->ptl_mtables[cpt];
+		if (i != 0 && i != LNET_CPT_NUMBER - 1 && !mtable->mt_enabled)
+			continue;
+
+		lnet_res_lock(cpt);
+		lnet_ptl_lock(ptl);
+
+		if (i == 0) { /* the first try, attach on stealing list */
+			list_add_tail(&msg->msg_list,
+					  &ptl->ptl_msg_stealing);
+		}
+
+		if (!list_empty(&msg->msg_list)) { /* on stealing list */
+			rc = lnet_mt_match_md(mtable, info, msg);
+
+			if ((rc & LNET_MATCHMD_EXHAUSTED) != 0 &&
+			    mtable->mt_enabled)
+				lnet_ptl_disable_mt(ptl, cpt);
+
+			if ((rc & LNET_MATCHMD_FINISH) != 0)
+				list_del_init(&msg->msg_list);
+
+		} else {
+			/* could be matched by lnet_ptl_attach_md()
+			 * which is called by another thread */
+			rc = msg->msg_md == NULL ?
+			     LNET_MATCHMD_DROP : LNET_MATCHMD_OK;
+		}
+
+		if (!list_empty(&msg->msg_list) && /* not matched yet */
+		    (i == LNET_CPT_NUMBER - 1 || /* the last CPT */
+		     ptl->ptl_mt_nmaps == 0 ||   /* no active CPT */
+		     (ptl->ptl_mt_nmaps == 1 &&  /* the only active CPT */
+		      ptl->ptl_mt_maps[0] == cpt))) {
+			/* nothing to steal, delay or drop */
+			list_del_init(&msg->msg_list);
+
+			if (lnet_ptl_is_lazy(ptl)) {
+				msg->msg_rx_delayed = 1;
+				list_add_tail(&msg->msg_list,
+						  &ptl->ptl_msg_delayed);
+				rc = LNET_MATCHMD_NONE;
+			} else {
+				rc = LNET_MATCHMD_DROP;
+			}
+		}
+
+		lnet_ptl_unlock(ptl);
+		lnet_res_unlock(cpt);
+
+		if ((rc & LNET_MATCHMD_FINISH) != 0 || msg->msg_rx_delayed)
+			break;
+	}
+
+	return rc;
+}
+
+int
+lnet_ptl_match_md(struct lnet_match_info *info, struct lnet_msg *msg)
+{
+	struct lnet_match_table	*mtable;
+	struct lnet_portal	*ptl;
+	int			rc;
+
+	CDEBUG(D_NET, "Request from %s of length %d into portal %d "
+	       "MB="LPX64"\n", libcfs_id2str(info->mi_id),
+	       info->mi_rlength, info->mi_portal, info->mi_mbits);
+
+	if (info->mi_portal >= the_lnet.ln_nportals) {
+		CERROR("Invalid portal %d not in [0-%d]\n",
+		       info->mi_portal, the_lnet.ln_nportals);
+		return LNET_MATCHMD_DROP;
+	}
+
+	ptl = the_lnet.ln_portals[info->mi_portal];
+	rc = lnet_ptl_match_early(ptl, msg);
+	if (rc != 0) /* matched or delayed early message */
+		return rc;
+
+	mtable = lnet_mt_of_match(info, msg);
+	lnet_res_lock(mtable->mt_cpt);
+
+	if (the_lnet.ln_shutdown) {
+		rc = LNET_MATCHMD_DROP;
+		goto out1;
+	}
+
+	rc = lnet_mt_match_md(mtable, info, msg);
+	if ((rc & LNET_MATCHMD_EXHAUSTED) != 0 && mtable->mt_enabled) {
+		lnet_ptl_lock(ptl);
+		lnet_ptl_disable_mt(ptl, mtable->mt_cpt);
+		lnet_ptl_unlock(ptl);
+	}
+
+	if ((rc & LNET_MATCHMD_FINISH) != 0)	/* matched or dropping */
+		goto out1;
+
+	if (!msg->msg_rx_ready_delay)
+		goto out1;
+
+	LASSERT(lnet_ptl_is_lazy(ptl));
+	LASSERT(!msg->msg_rx_delayed);
+
+	/* NB: we don't expect "delay" can happen a lot */
+	if (lnet_ptl_is_unique(ptl) || LNET_CPT_NUMBER == 1) {
+		lnet_ptl_lock(ptl);
+
+		msg->msg_rx_delayed = 1;
+		list_add_tail(&msg->msg_list, &ptl->ptl_msg_delayed);
+
+		lnet_ptl_unlock(ptl);
+		lnet_res_unlock(mtable->mt_cpt);
+
+	} else  {
+		lnet_res_unlock(mtable->mt_cpt);
+		rc = lnet_ptl_match_delay(ptl, info, msg);
+	}
+
+	if (msg->msg_rx_delayed) {
+		CDEBUG(D_NET,
+		       "Delaying %s from %s ptl %d MB "LPX64" off %d len %d\n",
+		       info->mi_opc == LNET_MD_OP_PUT ? "PUT" : "GET",
+		       libcfs_id2str(info->mi_id), info->mi_portal,
+		       info->mi_mbits, info->mi_roffset, info->mi_rlength);
+	}
+	goto out0;
+ out1:
+	lnet_res_unlock(mtable->mt_cpt);
+ out0:
+	/* EXHAUSTED bit is only meaningful for internal functions */
+	return rc & ~LNET_MATCHMD_EXHAUSTED;
+}
+
+void
+lnet_ptl_detach_md(lnet_me_t *me, lnet_libmd_t *md)
+{
+	LASSERT(me->me_md == md && md->md_me == me);
+
+	me->me_md = NULL;
+	md->md_me = NULL;
+}
+
+/* called with lnet_res_lock held */
+void
+lnet_ptl_attach_md(lnet_me_t *me, lnet_libmd_t *md,
+		   struct list_head *matches, struct list_head *drops)
+{
+	struct lnet_portal	*ptl = the_lnet.ln_portals[me->me_portal];
+	struct lnet_match_table	*mtable;
+	struct list_head		*head;
+	lnet_msg_t		*tmp;
+	lnet_msg_t		*msg;
+	int			exhausted = 0;
+	int			cpt;
+
+	LASSERT(md->md_refcount == 0); /* a brand new MD */
+
+	me->me_md = md;
+	md->md_me = me;
+
+	cpt = lnet_cpt_of_cookie(md->md_lh.lh_cookie);
+	mtable = ptl->ptl_mtables[cpt];
+
+	if (list_empty(&ptl->ptl_msg_stealing) &&
+	    list_empty(&ptl->ptl_msg_delayed) &&
+	    !lnet_mt_test_exhausted(mtable, me->me_pos))
+		return;
+
+	lnet_ptl_lock(ptl);
+	head = &ptl->ptl_msg_stealing;
+ again:
+	list_for_each_entry_safe(msg, tmp, head, msg_list) {
+		struct lnet_match_info	info;
+		lnet_hdr_t		*hdr;
+		int			rc;
+
+		LASSERT(msg->msg_rx_delayed || head == &ptl->ptl_msg_stealing);
+
+		hdr   = &msg->msg_hdr;
+		info.mi_id.nid	= hdr->src_nid;
+		info.mi_id.pid	= hdr->src_pid;
+		info.mi_opc	= LNET_MD_OP_PUT;
+		info.mi_portal	= hdr->msg.put.ptl_index;
+		info.mi_rlength	= hdr->payload_length;
+		info.mi_roffset	= hdr->msg.put.offset;
+		info.mi_mbits	= hdr->msg.put.match_bits;
+
+		rc = lnet_try_match_md(md, &info, msg);
+
+		exhausted = (rc & LNET_MATCHMD_EXHAUSTED) != 0;
+		if ((rc & LNET_MATCHMD_NONE) != 0) {
+			if (exhausted)
+				break;
+			continue;
+		}
+
+		/* Hurrah! This _is_ a match */
+		LASSERT((rc & LNET_MATCHMD_FINISH) != 0);
+		list_del_init(&msg->msg_list);
+
+		if (head == &ptl->ptl_msg_stealing) {
+			if (exhausted)
+				break;
+			/* stealing thread will handle the message */
+			continue;
+		}
+
+		if ((rc & LNET_MATCHMD_OK) != 0) {
+			list_add_tail(&msg->msg_list, matches);
+
+			CDEBUG(D_NET, "Resuming delayed PUT from %s portal %d "
+			       "match "LPU64" offset %d length %d.\n",
+			       libcfs_id2str(info.mi_id),
+			       info.mi_portal, info.mi_mbits,
+			       info.mi_roffset, info.mi_rlength);
+		} else {
+			list_add_tail(&msg->msg_list, drops);
+		}
+
+		if (exhausted)
+			break;
+	}
+
+	if (!exhausted && head == &ptl->ptl_msg_stealing) {
+		head = &ptl->ptl_msg_delayed;
+		goto again;
+	}
+
+	if (lnet_ptl_is_wildcard(ptl) && !exhausted) {
+		lnet_mt_set_exhausted(mtable, me->me_pos, 0);
+		if (!mtable->mt_enabled)
+			lnet_ptl_enable_mt(ptl, cpt);
+	}
+
+	lnet_ptl_unlock(ptl);
+}
+
+void
+lnet_ptl_cleanup(struct lnet_portal *ptl)
+{
+	struct lnet_match_table	*mtable;
+	int			i;
+
+	if (ptl->ptl_mtables == NULL) /* uninitialized portal */
+		return;
+
+	LASSERT(list_empty(&ptl->ptl_msg_delayed));
+	LASSERT(list_empty(&ptl->ptl_msg_stealing));
+	cfs_percpt_for_each(mtable, i, ptl->ptl_mtables) {
+		struct list_head	*mhash;
+		lnet_me_t	*me;
+		int		j;
+
+		if (mtable->mt_mhash == NULL) /* uninitialized match-table */
+			continue;
+
+		mhash = mtable->mt_mhash;
+		/* cleanup ME */
+		for (j = 0; j < LNET_MT_HASH_SIZE + 1; j++) {
+			while (!list_empty(&mhash[j])) {
+				me = list_entry(mhash[j].next,
+						    lnet_me_t, me_list);
+				CERROR("Active ME %p on exit\n", me);
+				list_del(&me->me_list);
+				lnet_me_free(me);
+			}
+		}
+		/* the extra entry is for MEs with ignore bits */
+		LIBCFS_FREE(mhash, sizeof(*mhash) * (LNET_MT_HASH_SIZE + 1));
+	}
+
+	cfs_percpt_free(ptl->ptl_mtables);
+	ptl->ptl_mtables = NULL;
+}
+
+int
+lnet_ptl_setup(struct lnet_portal *ptl, int index)
+{
+	struct lnet_match_table	*mtable;
+	struct list_head		*mhash;
+	int			i;
+	int			j;
+
+	ptl->ptl_mtables = cfs_percpt_alloc(lnet_cpt_table(),
+					    sizeof(struct lnet_match_table));
+	if (ptl->ptl_mtables == NULL) {
+		CERROR("Failed to create match table for portal %d\n", index);
+		return -ENOMEM;
+	}
+
+	ptl->ptl_index = index;
+	INIT_LIST_HEAD(&ptl->ptl_msg_delayed);
+	INIT_LIST_HEAD(&ptl->ptl_msg_stealing);
+	spin_lock_init(&ptl->ptl_lock);
+	cfs_percpt_for_each(mtable, i, ptl->ptl_mtables) {
+		/* the extra entry is for MEs with ignore bits */
+		LIBCFS_CPT_ALLOC(mhash, lnet_cpt_table(), i,
+				 sizeof(*mhash) * (LNET_MT_HASH_SIZE + 1));
+		if (mhash == NULL) {
+			CERROR("Failed to create match hash for portal %d\n",
+			       index);
+			goto failed;
+		}
+
+		memset(&mtable->mt_exhausted[0], -1,
+		       sizeof(mtable->mt_exhausted[0]) *
+		       LNET_MT_EXHAUSTED_BMAP);
+		mtable->mt_mhash = mhash;
+		for (j = 0; j < LNET_MT_HASH_SIZE + 1; j++)
+			INIT_LIST_HEAD(&mhash[j]);
+
+		mtable->mt_portal = index;
+		mtable->mt_cpt = i;
+	}
+
+	return 0;
+ failed:
+	lnet_ptl_cleanup(ptl);
+	return -ENOMEM;
+}
+
+void
+lnet_portals_destroy(void)
+{
+	int	i;
+
+	if (the_lnet.ln_portals == NULL)
+		return;
+
+	for (i = 0; i < the_lnet.ln_nportals; i++)
+		lnet_ptl_cleanup(the_lnet.ln_portals[i]);
+
+	cfs_array_free(the_lnet.ln_portals);
+	the_lnet.ln_portals = NULL;
+}
+
+int
+lnet_portals_create(void)
+{
+	int	size;
+	int	i;
+
+	size = offsetof(struct lnet_portal, ptl_mt_maps[LNET_CPT_NUMBER]);
+
+	the_lnet.ln_nportals = MAX_PORTALS;
+	the_lnet.ln_portals = cfs_array_alloc(the_lnet.ln_nportals, size);
+	if (the_lnet.ln_portals == NULL) {
+		CERROR("Failed to allocate portals table\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < the_lnet.ln_nportals; i++) {
+		if (lnet_ptl_setup(the_lnet.ln_portals[i], i)) {
+			lnet_portals_destroy();
+			return -ENOMEM;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Turn on the lazy portal attribute. Use with caution!
+ *
+ * This portal attribute only affects incoming PUT requests to the portal,
+ * and is off by default. By default, if there's no matching MD for an
+ * incoming PUT request, it is simply dropped. With the lazy attribute on,
+ * such requests are queued indefinitely until either a matching MD is
+ * posted to the portal or the lazy attribute is turned off.
+ *
+ * It would prevent dropped requests, however it should be regarded as the
+ * last line of defense - i.e. users must keep a close watch on active
+ * buffers on a lazy portal and once it becomes too low post more buffers as
+ * soon as possible. This is because delayed requests usually have detrimental
+ * effects on underlying network connections. A few delayed requests often
+ * suffice to bring an underlying connection to a complete halt, due to flow
+ * control mechanisms.
+ *
+ * There's also a DOS attack risk. If users don't post match-all MDs on a
+ * lazy portal, a malicious peer can easily stop a service by sending some
+ * PUT requests with match bits that won't match any MD. A routed server is
+ * especially vulnerable since the connections to its neighbor routers are
+ * shared among all clients.
+ *
+ * \param portal Index of the portal to enable the lazy attribute on.
+ *
+ * \retval 0       On success.
+ * \retval -EINVAL If \a portal is not a valid index.
+ */
+int
+LNetSetLazyPortal(int portal)
+{
+	struct lnet_portal *ptl;
+
+	if (portal < 0 || portal >= the_lnet.ln_nportals)
+		return -EINVAL;
+
+	CDEBUG(D_NET, "Setting portal %d lazy\n", portal);
+	ptl = the_lnet.ln_portals[portal];
+
+	lnet_res_lock(LNET_LOCK_EX);
+	lnet_ptl_lock(ptl);
+
+	lnet_ptl_setopt(ptl, LNET_PTL_LAZY);
+
+	lnet_ptl_unlock(ptl);
+	lnet_res_unlock(LNET_LOCK_EX);
+
+	return 0;
+}
+EXPORT_SYMBOL(LNetSetLazyPortal);
+
+/**
+ * Turn off the lazy portal attribute. Delayed requests on the portal,
+ * if any, will be all dropped when this function returns.
+ *
+ * \param portal Index of the portal to disable the lazy attribute on.
+ *
+ * \retval 0       On success.
+ * \retval -EINVAL If \a portal is not a valid index.
+ */
+int
+LNetClearLazyPortal(int portal)
+{
+	struct lnet_portal	*ptl;
+	LIST_HEAD		(zombies);
+
+	if (portal < 0 || portal >= the_lnet.ln_nportals)
+		return -EINVAL;
+
+	ptl = the_lnet.ln_portals[portal];
+
+	lnet_res_lock(LNET_LOCK_EX);
+	lnet_ptl_lock(ptl);
+
+	if (!lnet_ptl_is_lazy(ptl)) {
+		lnet_ptl_unlock(ptl);
+		lnet_res_unlock(LNET_LOCK_EX);
+		return 0;
+	}
+
+	if (the_lnet.ln_shutdown)
+		CWARN("Active lazy portal %d on exit\n", portal);
+	else
+		CDEBUG(D_NET, "clearing portal %d lazy\n", portal);
+
+	/* grab all the blocked messages atomically */
+	list_splice_init(&ptl->ptl_msg_delayed, &zombies);
+
+	lnet_ptl_unsetopt(ptl, LNET_PTL_LAZY);
+
+	lnet_ptl_unlock(ptl);
+	lnet_res_unlock(LNET_LOCK_EX);
+
+	lnet_drop_delayed_msg_list(&zombies, "Clearing lazy portal attr");
+
+	return 0;
+}
+EXPORT_SYMBOL(LNetClearLazyPortal);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lo.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lo.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/lo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/lo.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,120 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+#include <linux/lnet/lib-lnet.h>
+
+int
+lolnd_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
+{
+	LASSERT (!lntmsg->msg_routing);
+	LASSERT (!lntmsg->msg_target_is_router);
+
+	return lnet_parse(ni, &lntmsg->msg_hdr, ni->ni_nid, lntmsg, 0);
+}
+
+int
+lolnd_recv (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
+	    int delayed, unsigned int niov,
+	    struct iovec *iov, lnet_kiov_t *kiov,
+	    unsigned int offset, unsigned int mlen, unsigned int rlen)
+{
+	lnet_msg_t *sendmsg = private;
+
+	if (lntmsg != NULL) {		   /* not discarding */
+		if (sendmsg->msg_iov != NULL) {
+			if (iov != NULL)
+				lnet_copy_iov2iov(niov, iov, offset,
+						  sendmsg->msg_niov,
+						  sendmsg->msg_iov,
+						  sendmsg->msg_offset, mlen);
+			else
+				lnet_copy_iov2kiov(niov, kiov, offset,
+						   sendmsg->msg_niov,
+						   sendmsg->msg_iov,
+						   sendmsg->msg_offset, mlen);
+		} else {
+			if (iov != NULL)
+				lnet_copy_kiov2iov(niov, iov, offset,
+						   sendmsg->msg_niov,
+						   sendmsg->msg_kiov,
+						   sendmsg->msg_offset, mlen);
+			else
+				lnet_copy_kiov2kiov(niov, kiov, offset,
+						    sendmsg->msg_niov,
+						    sendmsg->msg_kiov,
+						    sendmsg->msg_offset, mlen);
+		}
+
+		lnet_finalize(ni, lntmsg, 0);
+	}
+
+	lnet_finalize(ni, sendmsg, 0);
+	return 0;
+}
+
+static int lolnd_instanced;
+
+void
+lolnd_shutdown(lnet_ni_t *ni)
+{
+	CDEBUG (D_NET, "shutdown\n");
+	LASSERT (lolnd_instanced);
+
+	lolnd_instanced = 0;
+}
+
+int
+lolnd_startup (lnet_ni_t *ni)
+{
+	LASSERT (ni->ni_lnd == &the_lolnd);
+	LASSERT (!lolnd_instanced);
+	lolnd_instanced = 1;
+
+	return (0);
+}
+
+lnd_t the_lolnd = {
+	/* .lnd_list       = */ {&the_lolnd.lnd_list, &the_lolnd.lnd_list},
+	/* .lnd_refcount   = */ 0,
+	/* .lnd_type       = */ LOLND,
+	/* .lnd_startup    = */ lolnd_startup,
+	/* .lnd_shutdown   = */ lolnd_shutdown,
+	/* .lnt_ctl	= */ NULL,
+	/* .lnd_send       = */ lolnd_send,
+	/* .lnd_recv       = */ lolnd_recv,
+	/* .lnd_eager_recv = */ NULL,
+	/* .lnd_notify     = */ NULL,
+	/* .lnd_accept     = */ NULL
+};
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/Makefile
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,8 @@
+obj-$(CONFIG_LNET) += lnet.o
+
+lnet-y := api-errno.o api-ni.o config.o lib-me.o lib-msg.o lib-eq.o	\
+	  lib-md.o lib-ptl.o lib-move.o module.o lo.o router.o		\
+	  router_proc.o acceptor.o peer.o
+
+
+ccflags-y := -I$(src)/../include
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/module.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/module.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/module.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/module.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,154 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+#include <linux/lnet/lib-lnet.h>
+
+static int config_on_load = 0;
+CFS_MODULE_PARM(config_on_load, "i", int, 0444,
+		"configure network at module load");
+
+static struct mutex lnet_config_mutex;
+
+int
+lnet_configure (void *arg)
+{
+	/* 'arg' only there so I can be passed to cfs_create_thread() */
+	int    rc = 0;
+
+	LNET_MUTEX_LOCK(&lnet_config_mutex);
+
+	if (!the_lnet.ln_niinit_self) {
+		rc = LNetNIInit(LUSTRE_SRV_LNET_PID);
+		if (rc >= 0) {
+			the_lnet.ln_niinit_self = 1;
+			rc = 0;
+		}
+	}
+
+	LNET_MUTEX_UNLOCK(&lnet_config_mutex);
+	return rc;
+}
+
+int
+lnet_unconfigure (void)
+{
+	int   refcount;
+
+	LNET_MUTEX_LOCK(&lnet_config_mutex);
+
+	if (the_lnet.ln_niinit_self) {
+		the_lnet.ln_niinit_self = 0;
+		LNetNIFini();
+	}
+
+	LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
+	refcount = the_lnet.ln_refcount;
+	LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
+
+	LNET_MUTEX_UNLOCK(&lnet_config_mutex);
+	return (refcount == 0) ? 0 : -EBUSY;
+}
+
+int
+lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data)
+{
+	int   rc;
+
+	switch (cmd) {
+	case IOC_LIBCFS_CONFIGURE:
+		return lnet_configure(NULL);
+
+	case IOC_LIBCFS_UNCONFIGURE:
+		return lnet_unconfigure();
+
+	default:
+		/* Passing LNET_PID_ANY only gives me a ref if the net is up
+		 * already; I'll need it to ensure the net can't go down while
+		 * I'm called into it */
+		rc = LNetNIInit(LNET_PID_ANY);
+		if (rc >= 0) {
+			rc = LNetCtl(cmd, data);
+			LNetNIFini();
+		}
+		return rc;
+	}
+}
+
+DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl);
+
+int
+init_lnet(void)
+{
+	int		  rc;
+	ENTRY;
+
+	mutex_init(&lnet_config_mutex);
+
+	rc = LNetInit();
+	if (rc != 0) {
+		CERROR("LNetInit: error %d\n", rc);
+		RETURN(rc);
+	}
+
+	rc = libcfs_register_ioctl(&lnet_ioctl_handler);
+	LASSERT (rc == 0);
+
+	if (config_on_load) {
+		/* Have to schedule a separate thread to avoid deadlocking
+		 * in modload */
+		(void) kthread_run(lnet_configure, NULL, "lnet_initd");
+	}
+
+	RETURN(0);
+}
+
+void
+fini_lnet(void)
+{
+	int rc;
+
+	rc = libcfs_deregister_ioctl(&lnet_ioctl_handler);
+	LASSERT (rc == 0);
+
+	LNetFini();
+}
+
+MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
+MODULE_DESCRIPTION("Portals v3.1");
+MODULE_LICENSE("GPL");
+
+cfs_module(lnet, "1.0.0", init_lnet, fini_lnet);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/peer.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/peer.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/peer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/peer.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,337 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/lnet/peer.c
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include <linux/lnet/lib-lnet.h>
+
+int
+lnet_peer_tables_create(void)
+{
+	struct lnet_peer_table	*ptable;
+	struct list_head		*hash;
+	int			i;
+	int			j;
+
+	the_lnet.ln_peer_tables = cfs_percpt_alloc(lnet_cpt_table(),
+						   sizeof(*ptable));
+	if (the_lnet.ln_peer_tables == NULL) {
+		CERROR("Failed to allocate cpu-partition peer tables\n");
+		return -ENOMEM;
+	}
+
+	cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
+		INIT_LIST_HEAD(&ptable->pt_deathrow);
+
+		LIBCFS_CPT_ALLOC(hash, lnet_cpt_table(), i,
+				 LNET_PEER_HASH_SIZE * sizeof(*hash));
+		if (hash == NULL) {
+			CERROR("Failed to create peer hash table\n");
+			lnet_peer_tables_destroy();
+			return -ENOMEM;
+		}
+
+		for (j = 0; j < LNET_PEER_HASH_SIZE; j++)
+			INIT_LIST_HEAD(&hash[j]);
+		ptable->pt_hash = hash; /* sign of initialization */
+	}
+
+	return 0;
+}
+
+void
+lnet_peer_tables_destroy(void)
+{
+	struct lnet_peer_table	*ptable;
+	struct list_head		*hash;
+	int			i;
+	int			j;
+
+	if (the_lnet.ln_peer_tables == NULL)
+		return;
+
+	cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
+		hash = ptable->pt_hash;
+		if (hash == NULL) /* not intialized */
+			break;
+
+		LASSERT(list_empty(&ptable->pt_deathrow));
+
+		ptable->pt_hash = NULL;
+		for (j = 0; j < LNET_PEER_HASH_SIZE; j++)
+			LASSERT(list_empty(&hash[j]));
+
+		LIBCFS_FREE(hash, LNET_PEER_HASH_SIZE * sizeof(*hash));
+	}
+
+	cfs_percpt_free(the_lnet.ln_peer_tables);
+	the_lnet.ln_peer_tables = NULL;
+}
+
+void
+lnet_peer_tables_cleanup(void)
+{
+	struct lnet_peer_table	*ptable;
+	int			i;
+	int			j;
+
+	LASSERT(the_lnet.ln_shutdown);	/* i.e. no new peers */
+
+	cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
+		lnet_net_lock(i);
+
+		for (j = 0; j < LNET_PEER_HASH_SIZE; j++) {
+			struct list_head *peers = &ptable->pt_hash[j];
+
+			while (!list_empty(peers)) {
+				lnet_peer_t *lp = list_entry(peers->next,
+								 lnet_peer_t,
+								 lp_hashlist);
+				list_del_init(&lp->lp_hashlist);
+				/* lose hash table's ref */
+				lnet_peer_decref_locked(lp);
+			}
+		}
+
+		lnet_net_unlock(i);
+	}
+
+	cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
+		LIST_HEAD	(deathrow);
+		lnet_peer_t	*lp;
+
+		lnet_net_lock(i);
+
+		for (j = 3; ptable->pt_number != 0; j++) {
+			lnet_net_unlock(i);
+
+			if ((j & (j - 1)) == 0) {
+				CDEBUG(D_WARNING,
+				       "Waiting for %d peers on peer table\n",
+				       ptable->pt_number);
+			}
+			cfs_pause(cfs_time_seconds(1) / 2);
+			lnet_net_lock(i);
+		}
+		list_splice_init(&ptable->pt_deathrow, &deathrow);
+
+		lnet_net_unlock(i);
+
+		while (!list_empty(&deathrow)) {
+			lp = list_entry(deathrow.next,
+					    lnet_peer_t, lp_hashlist);
+			list_del(&lp->lp_hashlist);
+			LIBCFS_FREE(lp, sizeof(*lp));
+		}
+	}
+}
+
+void
+lnet_destroy_peer_locked(lnet_peer_t *lp)
+{
+	struct lnet_peer_table *ptable;
+
+	LASSERT(lp->lp_refcount == 0);
+	LASSERT(lp->lp_rtr_refcount == 0);
+	LASSERT(list_empty(&lp->lp_txq));
+	LASSERT(list_empty(&lp->lp_hashlist));
+	LASSERT(lp->lp_txqnob == 0);
+
+	ptable = the_lnet.ln_peer_tables[lp->lp_cpt];
+	LASSERT(ptable->pt_number > 0);
+	ptable->pt_number--;
+
+	lnet_ni_decref_locked(lp->lp_ni, lp->lp_cpt);
+	lp->lp_ni = NULL;
+
+	list_add(&lp->lp_hashlist, &ptable->pt_deathrow);
+}
+
+lnet_peer_t *
+lnet_find_peer_locked(struct lnet_peer_table *ptable, lnet_nid_t nid)
+{
+	struct list_head	*peers;
+	lnet_peer_t	*lp;
+
+	LASSERT(!the_lnet.ln_shutdown);
+
+	peers = &ptable->pt_hash[lnet_nid2peerhash(nid)];
+	list_for_each_entry(lp, peers, lp_hashlist) {
+		if (lp->lp_nid == nid) {
+			lnet_peer_addref_locked(lp);
+			return lp;
+		}
+	}
+
+	return NULL;
+}
+
+int
+lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid, int cpt)
+{
+	struct lnet_peer_table	*ptable;
+	lnet_peer_t		*lp = NULL;
+	lnet_peer_t		*lp2;
+	int			cpt2;
+	int			rc = 0;
+
+	*lpp = NULL;
+	if (the_lnet.ln_shutdown) /* it's shutting down */
+		return -ESHUTDOWN;
+
+	/* cpt can be LNET_LOCK_EX if it's called from router functions */
+	cpt2 = cpt != LNET_LOCK_EX ? cpt : lnet_cpt_of_nid_locked(nid);
+
+	ptable = the_lnet.ln_peer_tables[cpt2];
+	lp = lnet_find_peer_locked(ptable, nid);
+	if (lp != NULL) {
+		*lpp = lp;
+		return 0;
+	}
+
+	if (!list_empty(&ptable->pt_deathrow)) {
+		lp = list_entry(ptable->pt_deathrow.next,
+				    lnet_peer_t, lp_hashlist);
+		list_del(&lp->lp_hashlist);
+	}
+
+	/*
+	 * take extra refcount in case another thread has shutdown LNet
+	 * and destroyed locks and peer-table before I finish the allocation
+	 */
+	ptable->pt_number++;
+	lnet_net_unlock(cpt);
+
+	if (lp != NULL)
+		memset(lp, 0, sizeof(*lp));
+	else
+		LIBCFS_CPT_ALLOC(lp, lnet_cpt_table(), cpt2, sizeof(*lp));
+
+	if (lp == NULL) {
+		rc = -ENOMEM;
+		lnet_net_lock(cpt);
+		goto out;
+	}
+
+	INIT_LIST_HEAD(&lp->lp_txq);
+	INIT_LIST_HEAD(&lp->lp_rtrq);
+	INIT_LIST_HEAD(&lp->lp_routes);
+
+	lp->lp_notify = 0;
+	lp->lp_notifylnd = 0;
+	lp->lp_notifying = 0;
+	lp->lp_alive_count = 0;
+	lp->lp_timestamp = 0;
+	lp->lp_alive = !lnet_peers_start_down(); /* 1 bit!! */
+	lp->lp_last_alive = cfs_time_current(); /* assumes alive */
+	lp->lp_last_query = 0; /* haven't asked NI yet */
+	lp->lp_ping_timestamp = 0;
+	lp->lp_ping_feats = LNET_PING_FEAT_INVAL;
+	lp->lp_nid = nid;
+	lp->lp_cpt = cpt2;
+	lp->lp_refcount = 2;	/* 1 for caller; 1 for hash */
+	lp->lp_rtr_refcount = 0;
+
+	lnet_net_lock(cpt);
+
+	if (the_lnet.ln_shutdown) {
+		rc = -ESHUTDOWN;
+		goto out;
+	}
+
+	lp2 = lnet_find_peer_locked(ptable, nid);
+	if (lp2 != NULL) {
+		*lpp = lp2;
+		goto out;
+	}
+
+	lp->lp_ni = lnet_net2ni_locked(LNET_NIDNET(nid), cpt2);
+	if (lp->lp_ni == NULL) {
+		rc = -EHOSTUNREACH;
+		goto out;
+	}
+
+	lp->lp_txcredits    =
+	lp->lp_mintxcredits = lp->lp_ni->ni_peertxcredits;
+	lp->lp_rtrcredits    =
+	lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni);
+
+	list_add_tail(&lp->lp_hashlist,
+			  &ptable->pt_hash[lnet_nid2peerhash(nid)]);
+	ptable->pt_version++;
+	*lpp = lp;
+
+	return 0;
+out:
+	if (lp != NULL)
+		list_add(&lp->lp_hashlist, &ptable->pt_deathrow);
+	ptable->pt_number--;
+	return rc;
+}
+
+void
+lnet_debug_peer(lnet_nid_t nid)
+{
+	char		*aliveness = "NA";
+	lnet_peer_t	*lp;
+	int		rc;
+	int		cpt;
+
+	cpt = lnet_cpt_of_nid(nid);
+	lnet_net_lock(cpt);
+
+	rc = lnet_nid2peer_locked(&lp, nid, cpt);
+	if (rc != 0) {
+		lnet_net_unlock(cpt);
+		CDEBUG(D_WARNING, "No peer %s\n", libcfs_nid2str(nid));
+		return;
+	}
+
+	if (lnet_isrouter(lp) || lnet_peer_aliveness_enabled(lp))
+		aliveness = lp->lp_alive ? "up" : "down";
+
+	CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n",
+	       libcfs_nid2str(lp->lp_nid), lp->lp_refcount,
+	       aliveness, lp->lp_ni->ni_peertxcredits,
+	       lp->lp_rtrcredits, lp->lp_minrtrcredits,
+	       lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob);
+
+	lnet_peer_decref_locked(lp);
+
+	lnet_net_unlock(cpt);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/router.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/router.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/router.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/router.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1694 @@
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ *
+ *   This file is part of Portals
+ *   http://sourceforge.net/projects/sandiaportals/
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+#include <linux/lnet/lib-lnet.h>
+
+#if  defined(LNET_ROUTER)
+
+#define LNET_NRB_TINY_MIN	512	/* min value for each CPT */
+#define LNET_NRB_TINY		(LNET_NRB_TINY_MIN * 4)
+#define LNET_NRB_SMALL_MIN	4096	/* min value for each CPT */
+#define LNET_NRB_SMALL		(LNET_NRB_SMALL_MIN * 4)
+#define LNET_NRB_LARGE_MIN	256	/* min value for each CPT */
+#define LNET_NRB_LARGE		(LNET_NRB_LARGE_MIN * 4)
+
+static char *forwarding = "";
+CFS_MODULE_PARM(forwarding, "s", charp, 0444,
+		"Explicitly enable/disable forwarding between networks");
+
+static int tiny_router_buffers;
+CFS_MODULE_PARM(tiny_router_buffers, "i", int, 0444,
+		"# of 0 payload messages to buffer in the router");
+static int small_router_buffers;
+CFS_MODULE_PARM(small_router_buffers, "i", int, 0444,
+		"# of small (1 page) messages to buffer in the router");
+static int large_router_buffers;
+CFS_MODULE_PARM(large_router_buffers, "i", int, 0444,
+		"# of large messages to buffer in the router");
+static int peer_buffer_credits = 0;
+CFS_MODULE_PARM(peer_buffer_credits, "i", int, 0444,
+		"# router buffer credits per peer");
+
+static int auto_down = 1;
+CFS_MODULE_PARM(auto_down, "i", int, 0444,
+		"Automatically mark peers down on comms error");
+
+int
+lnet_peer_buffer_credits(lnet_ni_t *ni)
+{
+	/* NI option overrides LNet default */
+	if (ni->ni_peerrtrcredits > 0)
+		return ni->ni_peerrtrcredits;
+	if (peer_buffer_credits > 0)
+		return peer_buffer_credits;
+
+	/* As an approximation, allow this peer the same number of router
+	 * buffers as it is allowed outstanding sends */
+	return ni->ni_peertxcredits;
+}
+
+/* forward ref's */
+static int lnet_router_checker(void *);
+#else
+
+int
+lnet_peer_buffer_credits(lnet_ni_t *ni)
+{
+	return 0;
+}
+
+#endif
+
+static int check_routers_before_use = 0;
+CFS_MODULE_PARM(check_routers_before_use, "i", int, 0444,
+		"Assume routers are down and ping them before use");
+
+static int avoid_asym_router_failure = 1;
+CFS_MODULE_PARM(avoid_asym_router_failure, "i", int, 0644,
+		"Avoid asymmetrical router failures (0 to disable)");
+
+static int dead_router_check_interval = 60;
+CFS_MODULE_PARM(dead_router_check_interval, "i", int, 0644,
+		"Seconds between dead router health checks (<= 0 to disable)");
+
+static int live_router_check_interval = 60;
+CFS_MODULE_PARM(live_router_check_interval, "i", int, 0644,
+		"Seconds between live router health checks (<= 0 to disable)");
+
+static int router_ping_timeout = 50;
+CFS_MODULE_PARM(router_ping_timeout, "i", int, 0644,
+		"Seconds to wait for the reply to a router health query");
+
+int
+lnet_peers_start_down(void)
+{
+	return check_routers_before_use;
+}
+
+void
+lnet_notify_locked(lnet_peer_t *lp, int notifylnd, int alive, cfs_time_t when)
+{
+	if (cfs_time_before(when, lp->lp_timestamp)) { /* out of date information */
+		CDEBUG(D_NET, "Out of date\n");
+		return;
+	}
+
+	lp->lp_timestamp = when;		/* update timestamp */
+	lp->lp_ping_deadline = 0;	       /* disable ping timeout */
+
+	if (lp->lp_alive_count != 0 &&	  /* got old news */
+	    (!lp->lp_alive) == (!alive)) {      /* new date for old news */
+		CDEBUG(D_NET, "Old news\n");
+		return;
+	}
+
+	/* Flag that notification is outstanding */
+
+	lp->lp_alive_count++;
+	lp->lp_alive = !(!alive);	       /* 1 bit! */
+	lp->lp_notify = 1;
+	lp->lp_notifylnd |= notifylnd;
+	if (lp->lp_alive)
+		lp->lp_ping_feats = LNET_PING_FEAT_INVAL; /* reset */
+
+	CDEBUG(D_NET, "set %s %d\n", libcfs_nid2str(lp->lp_nid), alive);
+}
+
+void
+lnet_ni_notify_locked(lnet_ni_t *ni, lnet_peer_t *lp)
+{
+	int	alive;
+	int	notifylnd;
+
+	/* Notify only in 1 thread at any time to ensure ordered notification.
+	 * NB individual events can be missed; the only guarantee is that you
+	 * always get the most recent news */
+
+	if (lp->lp_notifying)
+		return;
+
+	lp->lp_notifying = 1;
+
+	while (lp->lp_notify) {
+		alive     = lp->lp_alive;
+		notifylnd = lp->lp_notifylnd;
+
+		lp->lp_notifylnd = 0;
+		lp->lp_notify    = 0;
+
+		if (notifylnd && ni->ni_lnd->lnd_notify != NULL) {
+			lnet_net_unlock(lp->lp_cpt);
+
+			/* A new notification could happen now; I'll handle it
+			 * when control returns to me */
+
+			(ni->ni_lnd->lnd_notify)(ni, lp->lp_nid, alive);
+
+			lnet_net_lock(lp->lp_cpt);
+		}
+	}
+
+	lp->lp_notifying = 0;
+}
+
+
+static void
+lnet_rtr_addref_locked(lnet_peer_t *lp)
+{
+	LASSERT(lp->lp_refcount > 0);
+	LASSERT(lp->lp_rtr_refcount >= 0);
+
+	/* lnet_net_lock must be exclusively locked */
+	lp->lp_rtr_refcount++;
+	if (lp->lp_rtr_refcount == 1) {
+		struct list_head *pos;
+
+		/* a simple insertion sort */
+		list_for_each_prev(pos, &the_lnet.ln_routers) {
+			lnet_peer_t *rtr = list_entry(pos, lnet_peer_t,
+							  lp_rtr_list);
+
+			if (rtr->lp_nid < lp->lp_nid)
+				break;
+		}
+
+		list_add(&lp->lp_rtr_list, pos);
+		/* addref for the_lnet.ln_routers */
+		lnet_peer_addref_locked(lp);
+		the_lnet.ln_routers_version++;
+	}
+}
+
+static void
+lnet_rtr_decref_locked(lnet_peer_t *lp)
+{
+	LASSERT(lp->lp_refcount > 0);
+	LASSERT(lp->lp_rtr_refcount > 0);
+
+	/* lnet_net_lock must be exclusively locked */
+	lp->lp_rtr_refcount--;
+	if (lp->lp_rtr_refcount == 0) {
+		LASSERT(list_empty(&lp->lp_routes));
+
+		if (lp->lp_rcd != NULL) {
+			list_add(&lp->lp_rcd->rcd_list,
+				     &the_lnet.ln_rcd_deathrow);
+			lp->lp_rcd = NULL;
+		}
+
+		list_del(&lp->lp_rtr_list);
+		/* decref for the_lnet.ln_routers */
+		lnet_peer_decref_locked(lp);
+		the_lnet.ln_routers_version++;
+	}
+}
+
+lnet_remotenet_t *
+lnet_find_net_locked (__u32 net)
+{
+	lnet_remotenet_t	*rnet;
+	struct list_head		*tmp;
+	struct list_head		*rn_list;
+
+	LASSERT(!the_lnet.ln_shutdown);
+
+	rn_list = lnet_net2rnethash(net);
+	list_for_each(tmp, rn_list) {
+		rnet = list_entry(tmp, lnet_remotenet_t, lrn_list);
+
+		if (rnet->lrn_net == net)
+			return rnet;
+	}
+	return NULL;
+}
+
+static void lnet_shuffle_seed(void)
+{
+	static int seeded = 0;
+	int lnd_type, seed[2];
+	struct timeval tv;
+	lnet_ni_t *ni;
+	struct list_head *tmp;
+
+	if (seeded)
+		return;
+
+	cfs_get_random_bytes(seed, sizeof(seed));
+
+	/* Nodes with small feet have little entropy
+	 * the NID for this node gives the most entropy in the low bits */
+	list_for_each(tmp, &the_lnet.ln_nis) {
+		ni = list_entry(tmp, lnet_ni_t, ni_list);
+		lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid));
+
+		if (lnd_type != LOLND)
+			seed[0] ^= (LNET_NIDADDR(ni->ni_nid) | lnd_type);
+	}
+
+	do_gettimeofday(&tv);
+	cfs_srand(tv.tv_sec ^ seed[0], tv.tv_usec ^ seed[1]);
+	seeded = 1;
+	return;
+}
+
+/* NB expects LNET_LOCK held */
+void
+lnet_add_route_to_rnet (lnet_remotenet_t *rnet, lnet_route_t *route)
+{
+	unsigned int      len = 0;
+	unsigned int      offset = 0;
+	struct list_head       *e;
+
+	lnet_shuffle_seed();
+
+	list_for_each (e, &rnet->lrn_routes) {
+		len++;
+	}
+
+	/* len+1 positions to add a new entry, also prevents division by 0 */
+	offset = cfs_rand() % (len + 1);
+	list_for_each (e, &rnet->lrn_routes) {
+		if (offset == 0)
+			break;
+		offset--;
+	}
+	list_add(&route->lr_list, e);
+	list_add(&route->lr_gwlist, &route->lr_gateway->lp_routes);
+
+	the_lnet.ln_remote_nets_version++;
+	lnet_rtr_addref_locked(route->lr_gateway);
+}
+
+int
+lnet_add_route (__u32 net, unsigned int hops, lnet_nid_t gateway)
+{
+	struct list_head	  *e;
+	lnet_remotenet_t    *rnet;
+	lnet_remotenet_t    *rnet2;
+	lnet_route_t	*route;
+	lnet_ni_t	   *ni;
+	int		  add_route;
+	int		  rc;
+
+	CDEBUG(D_NET, "Add route: net %s hops %u gw %s\n",
+	       libcfs_net2str(net), hops, libcfs_nid2str(gateway));
+
+	if (gateway == LNET_NID_ANY ||
+	    LNET_NETTYP(LNET_NIDNET(gateway)) == LOLND ||
+	    net == LNET_NIDNET(LNET_NID_ANY) ||
+	    LNET_NETTYP(net) == LOLND ||
+	    LNET_NIDNET(gateway) == net ||
+	    hops < 1 || hops > 255)
+		return (-EINVAL);
+
+	if (lnet_islocalnet(net))	       /* it's a local network */
+		return 0;		       /* ignore the route entry */
+
+	/* Assume net, route, all new */
+	LIBCFS_ALLOC(route, sizeof(*route));
+	LIBCFS_ALLOC(rnet, sizeof(*rnet));
+	if (route == NULL || rnet == NULL) {
+		CERROR("Out of memory creating route %s %d %s\n",
+		       libcfs_net2str(net), hops, libcfs_nid2str(gateway));
+		if (route != NULL)
+			LIBCFS_FREE(route, sizeof(*route));
+		if (rnet != NULL)
+			LIBCFS_FREE(rnet, sizeof(*rnet));
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&rnet->lrn_routes);
+	rnet->lrn_net = net;
+	route->lr_hops = hops;
+	route->lr_net = net;
+
+	lnet_net_lock(LNET_LOCK_EX);
+
+	rc = lnet_nid2peer_locked(&route->lr_gateway, gateway, LNET_LOCK_EX);
+	if (rc != 0) {
+		lnet_net_unlock(LNET_LOCK_EX);
+
+		LIBCFS_FREE(route, sizeof(*route));
+		LIBCFS_FREE(rnet, sizeof(*rnet));
+
+		if (rc == -EHOSTUNREACH) { /* gateway is not on a local net */
+			return 0;	/* ignore the route entry */
+		} else {
+			CERROR("Error %d creating route %s %d %s\n", rc,
+			       libcfs_net2str(net), hops,
+			       libcfs_nid2str(gateway));
+		}
+		return rc;
+	}
+
+	LASSERT (!the_lnet.ln_shutdown);
+
+	rnet2 = lnet_find_net_locked(net);
+	if (rnet2 == NULL) {
+		/* new network */
+		list_add_tail(&rnet->lrn_list, lnet_net2rnethash(net));
+		rnet2 = rnet;
+	}
+
+	/* Search for a duplicate route (it's a NOOP if it is) */
+	add_route = 1;
+	list_for_each (e, &rnet2->lrn_routes) {
+		lnet_route_t *route2 = list_entry(e, lnet_route_t, lr_list);
+
+		if (route2->lr_gateway == route->lr_gateway) {
+			add_route = 0;
+			break;
+		}
+
+		/* our lookups must be true */
+		LASSERT (route2->lr_gateway->lp_nid != gateway);
+	}
+
+	if (add_route) {
+		lnet_peer_addref_locked(route->lr_gateway); /* +1 for notify */
+		lnet_add_route_to_rnet(rnet2, route);
+
+		ni = route->lr_gateway->lp_ni;
+		lnet_net_unlock(LNET_LOCK_EX);
+
+		/* XXX Assume alive */
+		if (ni->ni_lnd->lnd_notify != NULL)
+			(ni->ni_lnd->lnd_notify)(ni, gateway, 1);
+
+		lnet_net_lock(LNET_LOCK_EX);
+	}
+
+	/* -1 for notify or !add_route */
+	lnet_peer_decref_locked(route->lr_gateway);
+	lnet_net_unlock(LNET_LOCK_EX);
+
+	if (!add_route)
+		LIBCFS_FREE(route, sizeof(*route));
+
+	if (rnet != rnet2)
+		LIBCFS_FREE(rnet, sizeof(*rnet));
+
+	return 0;
+}
+
+int
+lnet_check_routes(void)
+{
+	lnet_remotenet_t	*rnet;
+	lnet_route_t		*route;
+	lnet_route_t		*route2;
+	struct list_head		*e1;
+	struct list_head		*e2;
+	int			cpt;
+	struct list_head		*rn_list;
+	int			i;
+
+	cpt = lnet_net_lock_current();
+
+	for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++) {
+		rn_list = &the_lnet.ln_remote_nets_hash[i];
+		list_for_each(e1, rn_list) {
+			rnet = list_entry(e1, lnet_remotenet_t, lrn_list);
+
+			route2 = NULL;
+			list_for_each(e2, &rnet->lrn_routes) {
+				lnet_nid_t	nid1;
+				lnet_nid_t	nid2;
+				int		net;
+
+				route = list_entry(e2, lnet_route_t,
+						       lr_list);
+
+				if (route2 == NULL) {
+					route2 = route;
+					continue;
+				}
+
+				if (route->lr_gateway->lp_ni ==
+				    route2->lr_gateway->lp_ni)
+					continue;
+
+				nid1 = route->lr_gateway->lp_nid;
+				nid2 = route2->lr_gateway->lp_nid;
+				net = rnet->lrn_net;
+
+				lnet_net_unlock(cpt);
+
+				CERROR("Routes to %s via %s and %s not "
+				       "supported\n",
+				       libcfs_net2str(net),
+				       libcfs_nid2str(nid1),
+				       libcfs_nid2str(nid2));
+				return -EINVAL;
+			}
+		}
+	}
+
+	lnet_net_unlock(cpt);
+	return 0;
+}
+
+int
+lnet_del_route(__u32 net, lnet_nid_t gw_nid)
+{
+	struct lnet_peer	*gateway;
+	lnet_remotenet_t	*rnet;
+	lnet_route_t		*route;
+	struct list_head		*e1;
+	struct list_head		*e2;
+	int			rc = -ENOENT;
+	struct list_head		*rn_list;
+	int			idx = 0;
+
+	CDEBUG(D_NET, "Del route: net %s : gw %s\n",
+	       libcfs_net2str(net), libcfs_nid2str(gw_nid));
+
+	/* NB Caller may specify either all routes via the given gateway
+	 * or a specific route entry actual NIDs) */
+
+	lnet_net_lock(LNET_LOCK_EX);
+	if (net == LNET_NIDNET(LNET_NID_ANY))
+		rn_list = &the_lnet.ln_remote_nets_hash[0];
+	else
+		rn_list = lnet_net2rnethash(net);
+
+ again:
+	list_for_each(e1, rn_list) {
+		rnet = list_entry(e1, lnet_remotenet_t, lrn_list);
+
+		if (!(net == LNET_NIDNET(LNET_NID_ANY) ||
+			net == rnet->lrn_net))
+			continue;
+
+		list_for_each(e2, &rnet->lrn_routes) {
+			route = list_entry(e2, lnet_route_t, lr_list);
+
+			gateway = route->lr_gateway;
+			if (!(gw_nid == LNET_NID_ANY ||
+			      gw_nid == gateway->lp_nid))
+				continue;
+
+			list_del(&route->lr_list);
+			list_del(&route->lr_gwlist);
+			the_lnet.ln_remote_nets_version++;
+
+			if (list_empty(&rnet->lrn_routes))
+				list_del(&rnet->lrn_list);
+			else
+				rnet = NULL;
+
+			lnet_rtr_decref_locked(gateway);
+			lnet_peer_decref_locked(gateway);
+
+			lnet_net_unlock(LNET_LOCK_EX);
+
+			LIBCFS_FREE(route, sizeof(*route));
+
+			if (rnet != NULL)
+				LIBCFS_FREE(rnet, sizeof(*rnet));
+
+			rc = 0;
+			lnet_net_lock(LNET_LOCK_EX);
+			goto again;
+		}
+	}
+
+	if (net == LNET_NIDNET(LNET_NID_ANY) &&
+	    ++idx < LNET_REMOTE_NETS_HASH_SIZE) {
+		rn_list = &the_lnet.ln_remote_nets_hash[idx];
+		goto again;
+	}
+	lnet_net_unlock(LNET_LOCK_EX);
+
+	return rc;
+}
+
+void
+lnet_destroy_routes (void)
+{
+	lnet_del_route(LNET_NIDNET(LNET_NID_ANY), LNET_NID_ANY);
+}
+
+int
+lnet_get_route(int idx, __u32 *net, __u32 *hops,
+	       lnet_nid_t *gateway, __u32 *alive)
+{
+	struct list_head		*e1;
+	struct list_head		*e2;
+	lnet_remotenet_t	*rnet;
+	lnet_route_t		*route;
+	int			cpt;
+	int			i;
+	struct list_head		*rn_list;
+
+	cpt = lnet_net_lock_current();
+
+	for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++) {
+		rn_list = &the_lnet.ln_remote_nets_hash[i];
+		list_for_each(e1, rn_list) {
+			rnet = list_entry(e1, lnet_remotenet_t, lrn_list);
+
+			list_for_each(e2, &rnet->lrn_routes) {
+				route = list_entry(e2, lnet_route_t,
+						       lr_list);
+
+				if (idx-- == 0) {
+					*net     = rnet->lrn_net;
+					*hops    = route->lr_hops;
+					*gateway = route->lr_gateway->lp_nid;
+					*alive   = route->lr_gateway->lp_alive;
+					lnet_net_unlock(cpt);
+					return 0;
+				}
+			}
+		}
+	}
+
+	lnet_net_unlock(cpt);
+	return -ENOENT;
+}
+
+void
+lnet_swap_pinginfo(lnet_ping_info_t *info)
+{
+	int	       i;
+	lnet_ni_status_t *stat;
+
+	__swab32s(&info->pi_magic);
+	__swab32s(&info->pi_features);
+	__swab32s(&info->pi_pid);
+	__swab32s(&info->pi_nnis);
+	for (i = 0; i < info->pi_nnis && i < LNET_MAX_RTR_NIS; i++) {
+		stat = &info->pi_ni[i];
+		__swab64s(&stat->ns_nid);
+		__swab32s(&stat->ns_status);
+	}
+	return;
+}
+
+/**
+ * parse router-checker pinginfo, record number of down NIs for remote
+ * networks on that router.
+ */
+static void
+lnet_parse_rc_info(lnet_rc_data_t *rcd)
+{
+	lnet_ping_info_t	*info = rcd->rcd_pinginfo;
+	struct lnet_peer	*gw   = rcd->rcd_gateway;
+	lnet_route_t		*rtr;
+
+	if (!gw->lp_alive)
+		return;
+
+	if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC))
+		lnet_swap_pinginfo(info);
+
+	/* NB always racing with network! */
+	if (info->pi_magic != LNET_PROTO_PING_MAGIC) {
+		CDEBUG(D_NET, "%s: Unexpected magic %08x\n",
+		       libcfs_nid2str(gw->lp_nid), info->pi_magic);
+		gw->lp_ping_feats = LNET_PING_FEAT_INVAL;
+		return;
+	}
+
+	gw->lp_ping_feats = info->pi_features;
+	if ((gw->lp_ping_feats & LNET_PING_FEAT_MASK) == 0) {
+		CDEBUG(D_NET, "%s: Unexpected features 0x%x\n",
+		       libcfs_nid2str(gw->lp_nid), gw->lp_ping_feats);
+		return; /* nothing I can understand */
+	}
+
+	if ((gw->lp_ping_feats & LNET_PING_FEAT_NI_STATUS) == 0)
+		return; /* can't carry NI status info */
+
+	list_for_each_entry(rtr, &gw->lp_routes, lr_gwlist) {
+		int	ptl_status = LNET_NI_STATUS_INVALID;
+		int	down = 0;
+		int	up = 0;
+		int	i;
+
+		for (i = 0; i < info->pi_nnis && i < LNET_MAX_RTR_NIS; i++) {
+			lnet_ni_status_t *stat = &info->pi_ni[i];
+			lnet_nid_t	 nid = stat->ns_nid;
+
+			if (nid == LNET_NID_ANY) {
+				CDEBUG(D_NET, "%s: unexpected LNET_NID_ANY\n",
+				       libcfs_nid2str(gw->lp_nid));
+				gw->lp_ping_feats = LNET_PING_FEAT_INVAL;
+				return;
+			}
+
+			if (LNET_NETTYP(LNET_NIDNET(nid)) == LOLND)
+				continue;
+
+			if (stat->ns_status == LNET_NI_STATUS_DOWN) {
+				if (LNET_NETTYP(LNET_NIDNET(nid)) != PTLLND)
+					down++;
+				else if (ptl_status != LNET_NI_STATUS_UP)
+					ptl_status = LNET_NI_STATUS_DOWN;
+				continue;
+			}
+
+			if (stat->ns_status == LNET_NI_STATUS_UP) {
+				if (LNET_NIDNET(nid) == rtr->lr_net) {
+					up = 1;
+					break;
+				}
+				/* ptl NIs are considered down only when
+				 * they're all down */
+				if (LNET_NETTYP(LNET_NIDNET(nid)) == PTLLND)
+					ptl_status = LNET_NI_STATUS_UP;
+				continue;
+			}
+
+			CDEBUG(D_NET, "%s: Unexpected status 0x%x\n",
+			       libcfs_nid2str(gw->lp_nid), stat->ns_status);
+			gw->lp_ping_feats = LNET_PING_FEAT_INVAL;
+			return;
+		}
+
+		if (up) { /* ignore downed NIs if NI for dest network is up */
+			rtr->lr_downis = 0;
+			continue;
+		}
+		rtr->lr_downis = down + (ptl_status == LNET_NI_STATUS_DOWN);
+	}
+}
+
+static void
+lnet_router_checker_event(lnet_event_t *event)
+{
+	lnet_rc_data_t		*rcd = event->md.user_ptr;
+	struct lnet_peer	*lp;
+
+	LASSERT(rcd != NULL);
+
+	if (event->unlinked) {
+		LNetInvalidateHandle(&rcd->rcd_mdh);
+		return;
+	}
+
+	LASSERT(event->type == LNET_EVENT_SEND ||
+		event->type == LNET_EVENT_REPLY);
+
+	lp = rcd->rcd_gateway;
+	LASSERT(lp != NULL);
+
+	 /* NB: it's called with holding lnet_res_lock, we have a few
+	  * places need to hold both locks at the same time, please take
+	  * care of lock ordering */
+	lnet_net_lock(lp->lp_cpt);
+	if (!lnet_isrouter(lp) || lp->lp_rcd != rcd) {
+		/* ignore if no longer a router or rcd is replaced */
+		goto out;
+	}
+
+	if (event->type == LNET_EVENT_SEND) {
+		lp->lp_ping_notsent = 0;
+		if (event->status == 0)
+			goto out;
+	}
+
+	/* LNET_EVENT_REPLY */
+	/* A successful REPLY means the router is up.  If _any_ comms
+	 * to the router fail I assume it's down (this will happen if
+	 * we ping alive routers to try to detect router death before
+	 * apps get burned). */
+
+	lnet_notify_locked(lp, 1, (event->status == 0), cfs_time_current());
+	/* The router checker will wake up very shortly and do the
+	 * actual notification.
+	 * XXX If 'lp' stops being a router before then, it will still
+	 * have the notification pending!!! */
+
+	if (avoid_asym_router_failure && event->status == 0)
+		lnet_parse_rc_info(rcd);
+
+ out:
+	lnet_net_unlock(lp->lp_cpt);
+}
+
+void
+lnet_wait_known_routerstate(void)
+{
+	lnet_peer_t	 *rtr;
+	struct list_head	  *entry;
+	int		  all_known;
+
+	LASSERT (the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING);
+
+	for (;;) {
+		int	cpt = lnet_net_lock_current();
+
+		all_known = 1;
+		list_for_each (entry, &the_lnet.ln_routers) {
+			rtr = list_entry(entry, lnet_peer_t, lp_rtr_list);
+
+			if (rtr->lp_alive_count == 0) {
+				all_known = 0;
+				break;
+			}
+		}
+
+		lnet_net_unlock(cpt);
+
+		if (all_known)
+			return;
+
+		cfs_pause(cfs_time_seconds(1));
+	}
+}
+
+void
+lnet_update_ni_status_locked(void)
+{
+	lnet_ni_t	*ni;
+	long		now;
+	int		timeout;
+
+	LASSERT(the_lnet.ln_routing);
+
+	timeout = router_ping_timeout +
+		  MAX(live_router_check_interval, dead_router_check_interval);
+
+	now = cfs_time_current_sec();
+	list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) {
+		if (ni->ni_lnd->lnd_type == LOLND)
+			continue;
+
+		if (now < ni->ni_last_alive + timeout)
+			continue;
+
+		lnet_ni_lock(ni);
+		/* re-check with lock */
+		if (now < ni->ni_last_alive + timeout) {
+			lnet_ni_unlock(ni);
+			continue;
+		}
+
+		LASSERT(ni->ni_status != NULL);
+
+		if (ni->ni_status->ns_status != LNET_NI_STATUS_DOWN) {
+			CDEBUG(D_NET, "NI(%s:%d) status changed to down\n",
+			       libcfs_nid2str(ni->ni_nid), timeout);
+			/* NB: so far, this is the only place to set
+			 * NI status to "down" */
+			ni->ni_status->ns_status = LNET_NI_STATUS_DOWN;
+		}
+		lnet_ni_unlock(ni);
+	}
+}
+
+void
+lnet_destroy_rc_data(lnet_rc_data_t *rcd)
+{
+	LASSERT(list_empty(&rcd->rcd_list));
+	/* detached from network */
+	LASSERT(LNetHandleIsInvalid(rcd->rcd_mdh));
+
+	if (rcd->rcd_gateway != NULL) {
+		int cpt = rcd->rcd_gateway->lp_cpt;
+
+		lnet_net_lock(cpt);
+		lnet_peer_decref_locked(rcd->rcd_gateway);
+		lnet_net_unlock(cpt);
+	}
+
+	if (rcd->rcd_pinginfo != NULL)
+		LIBCFS_FREE(rcd->rcd_pinginfo, LNET_PINGINFO_SIZE);
+
+	LIBCFS_FREE(rcd, sizeof(*rcd));
+}
+
+lnet_rc_data_t *
+lnet_create_rc_data_locked(lnet_peer_t *gateway)
+{
+	lnet_rc_data_t		*rcd = NULL;
+	lnet_ping_info_t	*pi;
+	int			rc;
+	int			i;
+
+	lnet_net_unlock(gateway->lp_cpt);
+
+	LIBCFS_ALLOC(rcd, sizeof(*rcd));
+	if (rcd == NULL)
+		goto out;
+
+	LNetInvalidateHandle(&rcd->rcd_mdh);
+	INIT_LIST_HEAD(&rcd->rcd_list);
+
+	LIBCFS_ALLOC(pi, LNET_PINGINFO_SIZE);
+	if (pi == NULL)
+		goto out;
+
+	memset(pi, 0, LNET_PINGINFO_SIZE);
+	for (i = 0; i < LNET_MAX_RTR_NIS; i++) {
+		pi->pi_ni[i].ns_nid = LNET_NID_ANY;
+		pi->pi_ni[i].ns_status = LNET_NI_STATUS_INVALID;
+	}
+	rcd->rcd_pinginfo = pi;
+
+	LASSERT (!LNetHandleIsInvalid(the_lnet.ln_rc_eqh));
+	rc = LNetMDBind((lnet_md_t){.start     = pi,
+				    .user_ptr  = rcd,
+				    .length    = LNET_PINGINFO_SIZE,
+				    .threshold = LNET_MD_THRESH_INF,
+				    .options   = LNET_MD_TRUNCATE,
+				    .eq_handle = the_lnet.ln_rc_eqh},
+			LNET_UNLINK,
+			&rcd->rcd_mdh);
+	if (rc < 0) {
+		CERROR("Can't bind MD: %d\n", rc);
+		goto out;
+	}
+	LASSERT(rc == 0);
+
+	lnet_net_lock(gateway->lp_cpt);
+	/* router table changed or someone has created rcd for this gateway */
+	if (!lnet_isrouter(gateway) || gateway->lp_rcd != NULL) {
+		lnet_net_unlock(gateway->lp_cpt);
+		goto out;
+	}
+
+	lnet_peer_addref_locked(gateway);
+	rcd->rcd_gateway = gateway;
+	gateway->lp_rcd = rcd;
+	gateway->lp_ping_notsent = 0;
+
+	return rcd;
+
+ out:
+	if (rcd != NULL) {
+		if (!LNetHandleIsInvalid(rcd->rcd_mdh)) {
+			rc = LNetMDUnlink(rcd->rcd_mdh);
+			LASSERT(rc == 0);
+		}
+		lnet_destroy_rc_data(rcd);
+	}
+
+	lnet_net_lock(gateway->lp_cpt);
+	return gateway->lp_rcd;
+}
+
+static int
+lnet_router_check_interval (lnet_peer_t *rtr)
+{
+	int secs;
+
+	secs = rtr->lp_alive ? live_router_check_interval :
+			       dead_router_check_interval;
+	if (secs < 0)
+		secs = 0;
+
+	return secs;
+}
+
+static void
+lnet_ping_router_locked (lnet_peer_t *rtr)
+{
+	lnet_rc_data_t *rcd = NULL;
+	cfs_time_t      now = cfs_time_current();
+	int	     secs;
+
+	lnet_peer_addref_locked(rtr);
+
+	if (rtr->lp_ping_deadline != 0 && /* ping timed out? */
+	    cfs_time_after(now, rtr->lp_ping_deadline))
+		lnet_notify_locked(rtr, 1, 0, now);
+
+	/* Run any outstanding notifications */
+	lnet_ni_notify_locked(rtr->lp_ni, rtr);
+
+	if (!lnet_isrouter(rtr) ||
+	    the_lnet.ln_rc_state != LNET_RC_STATE_RUNNING) {
+		/* router table changed or router checker is shutting down */
+		lnet_peer_decref_locked(rtr);
+		return;
+	}
+
+	rcd = rtr->lp_rcd != NULL ?
+	      rtr->lp_rcd : lnet_create_rc_data_locked(rtr);
+
+	if (rcd == NULL)
+		return;
+
+	secs = lnet_router_check_interval(rtr);
+
+	CDEBUG(D_NET,
+	       "rtr %s %d: deadline %lu ping_notsent %d alive %d "
+	       "alive_count %d lp_ping_timestamp %lu\n",
+	       libcfs_nid2str(rtr->lp_nid), secs,
+	       rtr->lp_ping_deadline, rtr->lp_ping_notsent,
+	       rtr->lp_alive, rtr->lp_alive_count, rtr->lp_ping_timestamp);
+
+	if (secs != 0 && !rtr->lp_ping_notsent &&
+	    cfs_time_after(now, cfs_time_add(rtr->lp_ping_timestamp,
+					     cfs_time_seconds(secs)))) {
+		int	       rc;
+		lnet_process_id_t id;
+		lnet_handle_md_t  mdh;
+
+		id.nid = rtr->lp_nid;
+		id.pid = LUSTRE_SRV_LNET_PID;
+		CDEBUG(D_NET, "Check: %s\n", libcfs_id2str(id));
+
+		rtr->lp_ping_notsent   = 1;
+		rtr->lp_ping_timestamp = now;
+
+		mdh = rcd->rcd_mdh;
+
+		if (rtr->lp_ping_deadline == 0) {
+			rtr->lp_ping_deadline =
+				cfs_time_shift(router_ping_timeout);
+		}
+
+		lnet_net_unlock(rtr->lp_cpt);
+
+		rc = LNetGet(LNET_NID_ANY, mdh, id, LNET_RESERVED_PORTAL,
+			     LNET_PROTO_PING_MATCHBITS, 0);
+
+		lnet_net_lock(rtr->lp_cpt);
+		if (rc != 0)
+			rtr->lp_ping_notsent = 0; /* no event pending */
+	}
+
+	lnet_peer_decref_locked(rtr);
+	return;
+}
+
+int
+lnet_router_checker_start(void)
+{
+	int	  rc;
+	int	  eqsz;
+
+	LASSERT (the_lnet.ln_rc_state == LNET_RC_STATE_SHUTDOWN);
+
+	if (check_routers_before_use &&
+	    dead_router_check_interval <= 0) {
+		LCONSOLE_ERROR_MSG(0x10a, "'dead_router_check_interval' must be"
+				   " set if 'check_routers_before_use' is set"
+				   "\n");
+		return -EINVAL;
+	}
+
+	if (!the_lnet.ln_routing &&
+	    live_router_check_interval <= 0 &&
+	    dead_router_check_interval <= 0)
+		return 0;
+
+	sema_init(&the_lnet.ln_rc_signal, 0);
+	/* EQ size doesn't matter; the callback is guaranteed to get every
+	 * event */
+	eqsz = 0;
+	rc = LNetEQAlloc(eqsz, lnet_router_checker_event,
+			 &the_lnet.ln_rc_eqh);
+	if (rc != 0) {
+		CERROR("Can't allocate EQ(%d): %d\n", eqsz, rc);
+		return -ENOMEM;
+	}
+
+	the_lnet.ln_rc_state = LNET_RC_STATE_RUNNING;
+	rc = PTR_ERR(kthread_run(lnet_router_checker,
+				 NULL, "router_checker"));
+	if (IS_ERR_VALUE(rc)) {
+		CERROR("Can't start router checker thread: %d\n", rc);
+		/* block until event callback signals exit */
+		down(&the_lnet.ln_rc_signal);
+		rc = LNetEQFree(the_lnet.ln_rc_eqh);
+		LASSERT(rc == 0);
+		the_lnet.ln_rc_state = LNET_RC_STATE_SHUTDOWN;
+		return -ENOMEM;
+	}
+
+	if (check_routers_before_use) {
+		/* Note that a helpful side-effect of pinging all known routers
+		 * at startup is that it makes them drop stale connections they
+		 * may have to a previous instance of me. */
+		lnet_wait_known_routerstate();
+	}
+
+	return 0;
+}
+
+void
+lnet_router_checker_stop (void)
+{
+	int rc;
+
+	if (the_lnet.ln_rc_state == LNET_RC_STATE_SHUTDOWN)
+		return;
+
+	LASSERT (the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING);
+	the_lnet.ln_rc_state = LNET_RC_STATE_STOPPING;
+
+	/* block until event callback signals exit */
+	down(&the_lnet.ln_rc_signal);
+	LASSERT(the_lnet.ln_rc_state == LNET_RC_STATE_SHUTDOWN);
+
+	rc = LNetEQFree(the_lnet.ln_rc_eqh);
+	LASSERT (rc == 0);
+	return;
+}
+
+static void
+lnet_prune_rc_data(int wait_unlink)
+{
+	lnet_rc_data_t		*rcd;
+	lnet_rc_data_t		*tmp;
+	lnet_peer_t		*lp;
+	struct list_head		head;
+	int			i = 2;
+
+	if (likely(the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING &&
+		   list_empty(&the_lnet.ln_rcd_deathrow) &&
+		   list_empty(&the_lnet.ln_rcd_zombie)))
+		return;
+
+	INIT_LIST_HEAD(&head);
+
+	lnet_net_lock(LNET_LOCK_EX);
+
+	if (the_lnet.ln_rc_state != LNET_RC_STATE_RUNNING) {
+		/* router checker is stopping, prune all */
+		list_for_each_entry(lp, &the_lnet.ln_routers,
+					lp_rtr_list) {
+			if (lp->lp_rcd == NULL)
+				continue;
+
+			LASSERT(list_empty(&lp->lp_rcd->rcd_list));
+			list_add(&lp->lp_rcd->rcd_list,
+				     &the_lnet.ln_rcd_deathrow);
+			lp->lp_rcd = NULL;
+		}
+	}
+
+	/* unlink all RCDs on deathrow list */
+	list_splice_init(&the_lnet.ln_rcd_deathrow, &head);
+
+	if (!list_empty(&head)) {
+		lnet_net_unlock(LNET_LOCK_EX);
+
+		list_for_each_entry(rcd, &head, rcd_list)
+			LNetMDUnlink(rcd->rcd_mdh);
+
+		lnet_net_lock(LNET_LOCK_EX);
+	}
+
+	list_splice_init(&head, &the_lnet.ln_rcd_zombie);
+
+	/* release all zombie RCDs */
+	while (!list_empty(&the_lnet.ln_rcd_zombie)) {
+		list_for_each_entry_safe(rcd, tmp, &the_lnet.ln_rcd_zombie,
+					     rcd_list) {
+			if (LNetHandleIsInvalid(rcd->rcd_mdh))
+				list_move(&rcd->rcd_list, &head);
+		}
+
+		wait_unlink = wait_unlink &&
+			      !list_empty(&the_lnet.ln_rcd_zombie);
+
+		lnet_net_unlock(LNET_LOCK_EX);
+
+		while (!list_empty(&head)) {
+			rcd = list_entry(head.next,
+					     lnet_rc_data_t, rcd_list);
+			list_del_init(&rcd->rcd_list);
+			lnet_destroy_rc_data(rcd);
+		}
+
+		if (!wait_unlink)
+			return;
+
+		i++;
+		CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET,
+		       "Waiting for rc buffers to unlink\n");
+		cfs_pause(cfs_time_seconds(1) / 4);
+
+		lnet_net_lock(LNET_LOCK_EX);
+	}
+
+	lnet_net_unlock(LNET_LOCK_EX);
+}
+
+
+#if  defined(LNET_ROUTER)
+
+static int
+lnet_router_checker(void *arg)
+{
+	lnet_peer_t       *rtr;
+	struct list_head	*entry;
+
+	cfs_block_allsigs();
+
+	LASSERT (the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING);
+
+	while (the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING) {
+		__u64	version;
+		int	cpt;
+		int	cpt2;
+
+		cpt = lnet_net_lock_current();
+rescan:
+		version = the_lnet.ln_routers_version;
+
+		list_for_each(entry, &the_lnet.ln_routers) {
+			rtr = list_entry(entry, lnet_peer_t, lp_rtr_list);
+
+			cpt2 = lnet_cpt_of_nid_locked(rtr->lp_nid);
+			if (cpt != cpt2) {
+				lnet_net_unlock(cpt);
+				cpt = cpt2;
+				lnet_net_lock(cpt);
+				/* the routers list has changed */
+				if (version != the_lnet.ln_routers_version)
+					goto rescan;
+			}
+
+			lnet_ping_router_locked(rtr);
+
+			/* NB dropped lock */
+			if (version != the_lnet.ln_routers_version) {
+				/* the routers list has changed */
+				goto rescan;
+			}
+		}
+
+		if (the_lnet.ln_routing)
+			lnet_update_ni_status_locked();
+
+		lnet_net_unlock(cpt);
+
+		lnet_prune_rc_data(0); /* don't wait for UNLINK */
+
+		/* Call cfs_pause() here always adds 1 to load average
+		 * because kernel counts # active tasks as nr_running
+		 * + nr_uninterruptible. */
+		schedule_timeout_and_set_state(TASK_INTERRUPTIBLE,
+						   cfs_time_seconds(1));
+	}
+
+	LASSERT(the_lnet.ln_rc_state == LNET_RC_STATE_STOPPING);
+
+	lnet_prune_rc_data(1); /* wait for UNLINK */
+
+	the_lnet.ln_rc_state = LNET_RC_STATE_SHUTDOWN;
+	up(&the_lnet.ln_rc_signal);
+	/* The unlink event callback will signal final completion */
+	return 0;
+}
+
+void
+lnet_destroy_rtrbuf(lnet_rtrbuf_t *rb, int npages)
+{
+	int sz = offsetof(lnet_rtrbuf_t, rb_kiov[npages]);
+
+	while (--npages >= 0)
+		__free_page(rb->rb_kiov[npages].kiov_page);
+
+	LIBCFS_FREE(rb, sz);
+}
+
+lnet_rtrbuf_t *
+lnet_new_rtrbuf(lnet_rtrbufpool_t *rbp, int cpt)
+{
+	int	    npages = rbp->rbp_npages;
+	int	    sz = offsetof(lnet_rtrbuf_t, rb_kiov[npages]);
+	struct page   *page;
+	lnet_rtrbuf_t *rb;
+	int	    i;
+
+	LIBCFS_CPT_ALLOC(rb, lnet_cpt_table(), cpt, sz);
+	if (rb == NULL)
+		return NULL;
+
+	rb->rb_pool = rbp;
+
+	for (i = 0; i < npages; i++) {
+		page = alloc_pages_node(
+				cfs_cpt_spread_node(lnet_cpt_table(), cpt),
+				__GFP_ZERO | GFP_IOFS, 0);
+		if (page == NULL) {
+			while (--i >= 0)
+				__free_page(rb->rb_kiov[i].kiov_page);
+
+			LIBCFS_FREE(rb, sz);
+			return NULL;
+		}
+
+		rb->rb_kiov[i].kiov_len = PAGE_CACHE_SIZE;
+		rb->rb_kiov[i].kiov_offset = 0;
+		rb->rb_kiov[i].kiov_page = page;
+	}
+
+	return rb;
+}
+
+void
+lnet_rtrpool_free_bufs(lnet_rtrbufpool_t *rbp)
+{
+	int		npages = rbp->rbp_npages;
+	int		nbuffers = 0;
+	lnet_rtrbuf_t	*rb;
+
+	if (rbp->rbp_nbuffers == 0) /* not initialized or already freed */
+		return;
+
+	LASSERT (list_empty(&rbp->rbp_msgs));
+	LASSERT (rbp->rbp_credits == rbp->rbp_nbuffers);
+
+	while (!list_empty(&rbp->rbp_bufs)) {
+		LASSERT (rbp->rbp_credits > 0);
+
+		rb = list_entry(rbp->rbp_bufs.next,
+				    lnet_rtrbuf_t, rb_list);
+		list_del(&rb->rb_list);
+		lnet_destroy_rtrbuf(rb, npages);
+		nbuffers++;
+	}
+
+	LASSERT (rbp->rbp_nbuffers == nbuffers);
+	LASSERT (rbp->rbp_credits == nbuffers);
+
+	rbp->rbp_nbuffers = rbp->rbp_credits = 0;
+}
+
+int
+lnet_rtrpool_alloc_bufs(lnet_rtrbufpool_t *rbp, int nbufs, int cpt)
+{
+	lnet_rtrbuf_t *rb;
+	int	    i;
+
+	if (rbp->rbp_nbuffers != 0) {
+		LASSERT (rbp->rbp_nbuffers == nbufs);
+		return 0;
+	}
+
+	for (i = 0; i < nbufs; i++) {
+		rb = lnet_new_rtrbuf(rbp, cpt);
+
+		if (rb == NULL) {
+			CERROR("Failed to allocate %d router bufs of %d pages\n",
+			       nbufs, rbp->rbp_npages);
+			return -ENOMEM;
+		}
+
+		rbp->rbp_nbuffers++;
+		rbp->rbp_credits++;
+		rbp->rbp_mincredits++;
+		list_add(&rb->rb_list, &rbp->rbp_bufs);
+
+		/* No allocation "under fire" */
+		/* Otherwise we'd need code to schedule blocked msgs etc */
+		LASSERT (!the_lnet.ln_routing);
+	}
+
+	LASSERT (rbp->rbp_credits == nbufs);
+	return 0;
+}
+
+void
+lnet_rtrpool_init(lnet_rtrbufpool_t *rbp, int npages)
+{
+	INIT_LIST_HEAD(&rbp->rbp_msgs);
+	INIT_LIST_HEAD(&rbp->rbp_bufs);
+
+	rbp->rbp_npages = npages;
+	rbp->rbp_credits = 0;
+	rbp->rbp_mincredits = 0;
+}
+
+void
+lnet_rtrpools_free(void)
+{
+	lnet_rtrbufpool_t *rtrp;
+	int		  i;
+
+	if (the_lnet.ln_rtrpools == NULL) /* uninitialized or freed */
+		return;
+
+	cfs_percpt_for_each(rtrp, i, the_lnet.ln_rtrpools) {
+		lnet_rtrpool_free_bufs(&rtrp[0]);
+		lnet_rtrpool_free_bufs(&rtrp[1]);
+		lnet_rtrpool_free_bufs(&rtrp[2]);
+	}
+
+	cfs_percpt_free(the_lnet.ln_rtrpools);
+	the_lnet.ln_rtrpools = NULL;
+}
+
+static int
+lnet_nrb_tiny_calculate(int npages)
+{
+	int	nrbs = LNET_NRB_TINY;
+
+	if (tiny_router_buffers < 0) {
+		LCONSOLE_ERROR_MSG(0x10c,
+				   "tiny_router_buffers=%d invalid when "
+				   "routing enabled\n", tiny_router_buffers);
+		return -1;
+	}
+
+	if (tiny_router_buffers > 0)
+		nrbs = tiny_router_buffers;
+
+	nrbs /= LNET_CPT_NUMBER;
+	return max(nrbs, LNET_NRB_TINY_MIN);
+}
+
+static int
+lnet_nrb_small_calculate(int npages)
+{
+	int	nrbs = LNET_NRB_SMALL;
+
+	if (small_router_buffers < 0) {
+		LCONSOLE_ERROR_MSG(0x10c,
+				   "small_router_buffers=%d invalid when "
+				   "routing enabled\n", small_router_buffers);
+		return -1;
+	}
+
+	if (small_router_buffers > 0)
+		nrbs = small_router_buffers;
+
+	nrbs /= LNET_CPT_NUMBER;
+	return max(nrbs, LNET_NRB_SMALL_MIN);
+}
+
+static int
+lnet_nrb_large_calculate(int npages)
+{
+	int	nrbs = LNET_NRB_LARGE;
+
+	if (large_router_buffers < 0) {
+		LCONSOLE_ERROR_MSG(0x10c,
+				   "large_router_buffers=%d invalid when "
+				   "routing enabled\n", large_router_buffers);
+		return -1;
+	}
+
+	if (large_router_buffers > 0)
+		nrbs = large_router_buffers;
+
+	nrbs /= LNET_CPT_NUMBER;
+	return max(nrbs, LNET_NRB_LARGE_MIN);
+}
+
+int
+lnet_rtrpools_alloc(int im_a_router)
+{
+	lnet_rtrbufpool_t *rtrp;
+	int	large_pages = (LNET_MTU + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	int	small_pages = 1;
+	int	nrb_tiny;
+	int	nrb_small;
+	int	nrb_large;
+	int	rc;
+	int	i;
+
+	if (!strcmp(forwarding, "")) {
+		/* not set either way */
+		if (!im_a_router)
+			return 0;
+	} else if (!strcmp(forwarding, "disabled")) {
+		/* explicitly disabled */
+		return 0;
+	} else if (!strcmp(forwarding, "enabled")) {
+		/* explicitly enabled */
+	} else {
+		LCONSOLE_ERROR_MSG(0x10b, "'forwarding' not set to either "
+				   "'enabled' or 'disabled'\n");
+		return -EINVAL;
+	}
+
+	nrb_tiny = lnet_nrb_tiny_calculate(0);
+	if (nrb_tiny < 0)
+		return -EINVAL;
+
+	nrb_small = lnet_nrb_small_calculate(small_pages);
+	if (nrb_small < 0)
+		return -EINVAL;
+
+	nrb_large = lnet_nrb_large_calculate(large_pages);
+	if (nrb_large < 0)
+		return -EINVAL;
+
+	the_lnet.ln_rtrpools = cfs_percpt_alloc(lnet_cpt_table(),
+						LNET_NRBPOOLS *
+						sizeof(lnet_rtrbufpool_t));
+	if (the_lnet.ln_rtrpools == NULL) {
+		LCONSOLE_ERROR_MSG(0x10c,
+				   "Failed to initialize router buffe pool\n");
+		return -ENOMEM;
+	}
+
+	cfs_percpt_for_each(rtrp, i, the_lnet.ln_rtrpools) {
+		lnet_rtrpool_init(&rtrp[0], 0);
+		rc = lnet_rtrpool_alloc_bufs(&rtrp[0], nrb_tiny, i);
+		if (rc != 0)
+			goto failed;
+
+		lnet_rtrpool_init(&rtrp[1], small_pages);
+		rc = lnet_rtrpool_alloc_bufs(&rtrp[1], nrb_small, i);
+		if (rc != 0)
+			goto failed;
+
+		lnet_rtrpool_init(&rtrp[2], large_pages);
+		rc = lnet_rtrpool_alloc_bufs(&rtrp[2], nrb_large, i);
+		if (rc != 0)
+			goto failed;
+	}
+
+	lnet_net_lock(LNET_LOCK_EX);
+	the_lnet.ln_routing = 1;
+	lnet_net_unlock(LNET_LOCK_EX);
+
+	return 0;
+
+ failed:
+	lnet_rtrpools_free();
+	return rc;
+}
+
+int
+lnet_notify(lnet_ni_t *ni, lnet_nid_t nid, int alive, cfs_time_t when)
+{
+	struct lnet_peer	*lp = NULL;
+	cfs_time_t		now = cfs_time_current();
+	int			cpt = lnet_cpt_of_nid(nid);
+
+	LASSERT (!in_interrupt ());
+
+	CDEBUG (D_NET, "%s notifying %s: %s\n",
+		(ni == NULL) ? "userspace" : libcfs_nid2str(ni->ni_nid),
+		libcfs_nid2str(nid),
+		alive ? "up" : "down");
+
+	if (ni != NULL &&
+	    LNET_NIDNET(ni->ni_nid) != LNET_NIDNET(nid)) {
+		CWARN ("Ignoring notification of %s %s by %s (different net)\n",
+			libcfs_nid2str(nid), alive ? "birth" : "death",
+			libcfs_nid2str(ni->ni_nid));
+		return -EINVAL;
+	}
+
+	/* can't do predictions... */
+	if (cfs_time_after(when, now)) {
+		CWARN ("Ignoring prediction from %s of %s %s "
+		       "%ld seconds in the future\n",
+		       (ni == NULL) ? "userspace" : libcfs_nid2str(ni->ni_nid),
+		       libcfs_nid2str(nid), alive ? "up" : "down",
+		       cfs_duration_sec(cfs_time_sub(when, now)));
+		return -EINVAL;
+	}
+
+	if (ni != NULL && !alive &&	     /* LND telling me she's down */
+	    !auto_down) {		       /* auto-down disabled */
+		CDEBUG(D_NET, "Auto-down disabled\n");
+		return 0;
+	}
+
+	lnet_net_lock(cpt);
+
+	if (the_lnet.ln_shutdown) {
+		lnet_net_unlock(cpt);
+		return -ESHUTDOWN;
+	}
+
+	lp = lnet_find_peer_locked(the_lnet.ln_peer_tables[cpt], nid);
+	if (lp == NULL) {
+		/* nid not found */
+		lnet_net_unlock(cpt);
+		CDEBUG(D_NET, "%s not found\n", libcfs_nid2str(nid));
+		return 0;
+	}
+
+	/* We can't fully trust LND on reporting exact peer last_alive
+	 * if he notifies us about dead peer. For example ksocklnd can
+	 * call us with when == _time_when_the_node_was_booted_ if
+	 * no connections were successfully established */
+	if (ni != NULL && !alive && when < lp->lp_last_alive)
+		when = lp->lp_last_alive;
+
+	lnet_notify_locked(lp, ni == NULL, alive, when);
+
+	lnet_ni_notify_locked(ni, lp);
+
+	lnet_peer_decref_locked(lp);
+
+	lnet_net_unlock(cpt);
+	return 0;
+}
+EXPORT_SYMBOL(lnet_notify);
+
+void
+lnet_get_tunables (void)
+{
+	return;
+}
+
+#else
+
+int
+lnet_notify (lnet_ni_t *ni, lnet_nid_t nid, int alive, cfs_time_t when)
+{
+	return -EOPNOTSUPP;
+}
+
+void
+lnet_router_checker (void)
+{
+	static time_t last = 0;
+	static int    running = 0;
+
+	time_t	    now = cfs_time_current_sec();
+	int	       interval = now - last;
+	int	       rc;
+	__u64	     version;
+	lnet_peer_t      *rtr;
+
+	/* It's no use to call me again within a sec - all intervals and
+	 * timeouts are measured in seconds */
+	if (last != 0 && interval < 2)
+		return;
+
+	if (last != 0 &&
+	    interval > MAX(live_router_check_interval,
+			   dead_router_check_interval))
+		CNETERR("Checker(%d/%d) not called for %d seconds\n",
+			live_router_check_interval, dead_router_check_interval,
+			interval);
+
+	LASSERT(LNET_CPT_NUMBER == 1);
+
+	lnet_net_lock(0);
+	LASSERT(!running); /* recursion check */
+	running = 1;
+	lnet_net_unlock(0);
+
+	last = now;
+
+	if (the_lnet.ln_rc_state == LNET_RC_STATE_STOPPING)
+		lnet_prune_rc_data(0); /* unlink all rcd and nowait */
+
+	/* consume all pending events */
+	while (1) {
+		int	  i;
+		lnet_event_t ev;
+
+		/* NB ln_rc_eqh must be the 1st in 'eventqs' otherwise the
+		 * recursion breaker in LNetEQPoll would fail */
+		rc = LNetEQPoll(&the_lnet.ln_rc_eqh, 1, 0, &ev, &i);
+		if (rc == 0)   /* no event pending */
+			break;
+
+		/* NB a lost SENT prevents me from pinging a router again */
+		if (rc == -EOVERFLOW) {
+			CERROR("Dropped an event!!!\n");
+			abort();
+		}
+
+		LASSERT (rc == 1);
+
+		lnet_router_checker_event(&ev);
+	}
+
+	if (the_lnet.ln_rc_state == LNET_RC_STATE_STOPPING) {
+		lnet_prune_rc_data(1); /* release rcd */
+		the_lnet.ln_rc_state = LNET_RC_STATE_SHUTDOWN;
+		running = 0;
+		return;
+	}
+
+	LASSERT (the_lnet.ln_rc_state == LNET_RC_STATE_RUNNING);
+
+	lnet_net_lock(0);
+
+	version = the_lnet.ln_routers_version;
+	list_for_each_entry (rtr, &the_lnet.ln_routers, lp_rtr_list) {
+		lnet_ping_router_locked(rtr);
+		LASSERT (version == the_lnet.ln_routers_version);
+	}
+
+	lnet_net_unlock(0);
+
+	running = 0; /* lock only needed for the recursion check */
+	return;
+}
+
+/* NB lnet_peers_start_down depends on me,
+ * so must be called before any peer creation */
+void
+lnet_get_tunables (void)
+{
+	char *s;
+
+	s = getenv("LNET_ROUTER_PING_TIMEOUT");
+	if (s != NULL) router_ping_timeout = atoi(s);
+
+	s = getenv("LNET_LIVE_ROUTER_CHECK_INTERVAL");
+	if (s != NULL) live_router_check_interval = atoi(s);
+
+	s = getenv("LNET_DEAD_ROUTER_CHECK_INTERVAL");
+	if (s != NULL) dead_router_check_interval = atoi(s);
+
+	/* This replaces old lnd_notify mechanism */
+	check_routers_before_use = 1;
+	if (dead_router_check_interval <= 0)
+		dead_router_check_interval = 30;
+}
+
+void
+lnet_rtrpools_free(void)
+{
+}
+
+int
+lnet_rtrpools_alloc(int im_a_arouter)
+{
+	return 0;
+}
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/router_proc.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/router_proc.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/lnet/router_proc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/lnet/router_proc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,950 @@
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ *
+ *   This file is part of Portals
+ *   http://sourceforge.net/projects/sandiaportals/
+ *
+ *   Portals is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Portals is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Portals; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
+
+#if  defined(LNET_ROUTER)
+
+/* This is really lnet_proc.c. You might need to update sanity test 215
+ * if any file format is changed. */
+
+static ctl_table_header_t *lnet_table_header = NULL;
+
+#define CTL_LNET	 (0x100)
+enum {
+	PSDEV_LNET_STATS = 100,
+	PSDEV_LNET_ROUTES,
+	PSDEV_LNET_ROUTERS,
+	PSDEV_LNET_PEERS,
+	PSDEV_LNET_BUFFERS,
+	PSDEV_LNET_NIS,
+	PSDEV_LNET_PTL_ROTOR,
+};
+
+#define LNET_LOFFT_BITS		(sizeof(loff_t) * 8)
+/*
+ * NB: max allowed LNET_CPT_BITS is 8 on 64-bit system and 2 on 32-bit system
+ */
+#define LNET_PROC_CPT_BITS	(LNET_CPT_BITS + 1)
+/* change version, 16 bits or 8 bits */
+#define LNET_PROC_VER_BITS	MAX(((MIN(LNET_LOFFT_BITS, 64)) / 4), 8)
+
+#define LNET_PROC_HASH_BITS	LNET_PEER_HASH_BITS
+/*
+ * bits for peer hash offset
+ * NB: we don't use the highest bit of *ppos because it's signed
+ */
+#define LNET_PROC_HOFF_BITS	(LNET_LOFFT_BITS -       \
+				 LNET_PROC_CPT_BITS -    \
+				 LNET_PROC_VER_BITS -    \
+				 LNET_PROC_HASH_BITS - 1)
+/* bits for hash index + position */
+#define LNET_PROC_HPOS_BITS	(LNET_PROC_HASH_BITS + LNET_PROC_HOFF_BITS)
+/* bits for peer hash table + hash version */
+#define LNET_PROC_VPOS_BITS	(LNET_PROC_HPOS_BITS + LNET_PROC_VER_BITS)
+
+#define LNET_PROC_CPT_MASK	((1ULL << LNET_PROC_CPT_BITS) - 1)
+#define LNET_PROC_VER_MASK	((1ULL << LNET_PROC_VER_BITS) - 1)
+#define LNET_PROC_HASH_MASK	((1ULL << LNET_PROC_HASH_BITS) - 1)
+#define LNET_PROC_HOFF_MASK	((1ULL << LNET_PROC_HOFF_BITS) - 1)
+
+#define LNET_PROC_CPT_GET(pos)				\
+	(int)(((pos) >> LNET_PROC_VPOS_BITS) & LNET_PROC_CPT_MASK)
+
+#define LNET_PROC_VER_GET(pos)				\
+	(int)(((pos) >> LNET_PROC_HPOS_BITS) & LNET_PROC_VER_MASK)
+
+#define LNET_PROC_HASH_GET(pos)				\
+	(int)(((pos) >> LNET_PROC_HOFF_BITS) & LNET_PROC_HASH_MASK)
+
+#define LNET_PROC_HOFF_GET(pos)				\
+	(int)((pos) & LNET_PROC_HOFF_MASK)
+
+#define LNET_PROC_POS_MAKE(cpt, ver, hash, off)		\
+	(((((loff_t)(cpt)) & LNET_PROC_CPT_MASK) << LNET_PROC_VPOS_BITS) |   \
+	((((loff_t)(ver)) & LNET_PROC_VER_MASK) << LNET_PROC_HPOS_BITS) |   \
+	((((loff_t)(hash)) & LNET_PROC_HASH_MASK) << LNET_PROC_HOFF_BITS) | \
+	((off) & LNET_PROC_HOFF_MASK))
+
+#define LNET_PROC_VERSION(v)	((unsigned int)((v) & LNET_PROC_VER_MASK))
+
+static int __proc_lnet_stats(void *data, int write,
+			     loff_t pos, void *buffer, int nob)
+{
+	int	      rc;
+	lnet_counters_t *ctrs;
+	int	      len;
+	char	    *tmpstr;
+	const int	tmpsiz = 256; /* 7 %u and 4 LPU64 */
+
+	if (write) {
+		lnet_counters_reset();
+		return 0;
+	}
+
+	/* read */
+
+	LIBCFS_ALLOC(ctrs, sizeof(*ctrs));
+	if (ctrs == NULL)
+		return -ENOMEM;
+
+	LIBCFS_ALLOC(tmpstr, tmpsiz);
+	if (tmpstr == NULL) {
+		LIBCFS_FREE(ctrs, sizeof(*ctrs));
+		return -ENOMEM;
+	}
+
+	lnet_counters_get(ctrs);
+
+	len = snprintf(tmpstr, tmpsiz,
+		       "%u %u %u %u %u %u %u "LPU64" "LPU64" "
+		       LPU64" "LPU64,
+		       ctrs->msgs_alloc, ctrs->msgs_max,
+		       ctrs->errors,
+		       ctrs->send_count, ctrs->recv_count,
+		       ctrs->route_count, ctrs->drop_count,
+		       ctrs->send_length, ctrs->recv_length,
+		       ctrs->route_length, ctrs->drop_length);
+
+	if (pos >= min_t(int, len, strlen(tmpstr)))
+		rc = 0;
+	else
+		rc = cfs_trace_copyout_string(buffer, nob,
+					      tmpstr + pos, "\n");
+
+	LIBCFS_FREE(tmpstr, tmpsiz);
+	LIBCFS_FREE(ctrs, sizeof(*ctrs));
+	return rc;
+}
+
+DECLARE_PROC_HANDLER(proc_lnet_stats);
+
+int LL_PROC_PROTO(proc_lnet_routes)
+{
+	const int	tmpsiz = 256;
+	char		*tmpstr;
+	char		*s;
+	int		rc = 0;
+	int		len;
+	int		ver;
+	int		off;
+
+	DECLARE_LL_PROC_PPOS_DECL;
+
+	CLASSERT(sizeof(loff_t) >= 4);
+
+	off = LNET_PROC_HOFF_GET(*ppos);
+	ver = LNET_PROC_VER_GET(*ppos);
+
+	LASSERT (!write);
+
+	if (*lenp == 0)
+		return 0;
+
+	LIBCFS_ALLOC(tmpstr, tmpsiz);
+	if (tmpstr == NULL)
+		return -ENOMEM;
+
+	s = tmpstr; /* points to current position in tmpstr[] */
+
+	if (*ppos == 0) {
+		s += snprintf(s, tmpstr + tmpsiz - s, "Routing %s\n",
+			      the_lnet.ln_routing ? "enabled" : "disabled");
+		LASSERT (tmpstr + tmpsiz - s > 0);
+
+		s += snprintf(s, tmpstr + tmpsiz - s, "%-8s %4s %7s %s\n",
+			      "net", "hops", "state", "router");
+		LASSERT (tmpstr + tmpsiz - s > 0);
+
+		lnet_net_lock(0);
+		ver = (unsigned int)the_lnet.ln_remote_nets_version;
+		lnet_net_unlock(0);
+		*ppos = LNET_PROC_POS_MAKE(0, ver, 0, off);
+	} else {
+		struct list_head		*n;
+		struct list_head		*r;
+		lnet_route_t		*route = NULL;
+		lnet_remotenet_t	*rnet  = NULL;
+		int			skip  = off - 1;
+		struct list_head		*rn_list;
+		int			i;
+
+		lnet_net_lock(0);
+
+		if (ver != LNET_PROC_VERSION(the_lnet.ln_remote_nets_version)) {
+			lnet_net_unlock(0);
+			LIBCFS_FREE(tmpstr, tmpsiz);
+			return -ESTALE;
+		}
+
+		for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE && route == NULL;
+		     i++) {
+			rn_list = &the_lnet.ln_remote_nets_hash[i];
+
+			n = rn_list->next;
+
+			while (n != rn_list && route == NULL) {
+				rnet = list_entry(n, lnet_remotenet_t,
+						      lrn_list);
+
+				r = rnet->lrn_routes.next;
+
+				while (r != &rnet->lrn_routes) {
+					lnet_route_t *re =
+						list_entry(r, lnet_route_t,
+							       lr_list);
+					if (skip == 0) {
+						route = re;
+						break;
+					}
+
+					skip--;
+					r = r->next;
+				}
+
+				n = n->next;
+			}
+		}
+
+		if (route != NULL) {
+			__u32	net   = rnet->lrn_net;
+			unsigned int hops  = route->lr_hops;
+			lnet_nid_t   nid   = route->lr_gateway->lp_nid;
+			int	  alive = route->lr_gateway->lp_alive;
+
+			s += snprintf(s, tmpstr + tmpsiz - s,
+				      "%-8s %4u %7s %s\n",
+				      libcfs_net2str(net), hops,
+				      alive ? "up" : "down",
+				      libcfs_nid2str(nid));
+			LASSERT(tmpstr + tmpsiz - s > 0);
+		}
+
+		lnet_net_unlock(0);
+	}
+
+	len = s - tmpstr;     /* how many bytes was written */
+
+	if (len > *lenp) {    /* linux-supplied buffer is too small */
+		rc = -EINVAL;
+	} else if (len > 0) { /* wrote something */
+		if (copy_to_user(buffer, tmpstr, len))
+			rc = -EFAULT;
+		else {
+			off += 1;
+			*ppos = LNET_PROC_POS_MAKE(0, ver, 0, off);
+		}
+	}
+
+	LIBCFS_FREE(tmpstr, tmpsiz);
+
+	if (rc == 0)
+		*lenp = len;
+
+	return rc;
+}
+
+int LL_PROC_PROTO(proc_lnet_routers)
+{
+	int	rc = 0;
+	char      *tmpstr;
+	char      *s;
+	const int  tmpsiz = 256;
+	int	len;
+	int	ver;
+	int	off;
+
+	DECLARE_LL_PROC_PPOS_DECL;
+
+	off = LNET_PROC_HOFF_GET(*ppos);
+	ver = LNET_PROC_VER_GET(*ppos);
+
+	LASSERT (!write);
+
+	if (*lenp == 0)
+		return 0;
+
+	LIBCFS_ALLOC(tmpstr, tmpsiz);
+	if (tmpstr == NULL)
+		return -ENOMEM;
+
+	s = tmpstr; /* points to current position in tmpstr[] */
+
+	if (*ppos == 0) {
+		s += snprintf(s, tmpstr + tmpsiz - s,
+			      "%-4s %7s %9s %6s %12s %9s %8s %7s %s\n",
+			      "ref", "rtr_ref", "alive_cnt", "state",
+			      "last_ping", "ping_sent", "deadline",
+			      "down_ni", "router");
+		LASSERT(tmpstr + tmpsiz - s > 0);
+
+		lnet_net_lock(0);
+		ver = (unsigned int)the_lnet.ln_routers_version;
+		lnet_net_unlock(0);
+		*ppos = LNET_PROC_POS_MAKE(0, ver, 0, off);
+	} else {
+		struct list_head		*r;
+		struct lnet_peer	*peer = NULL;
+		int			skip = off - 1;
+
+		lnet_net_lock(0);
+
+		if (ver != LNET_PROC_VERSION(the_lnet.ln_routers_version)) {
+			lnet_net_unlock(0);
+
+			LIBCFS_FREE(tmpstr, tmpsiz);
+			return -ESTALE;
+		}
+
+		r = the_lnet.ln_routers.next;
+
+		while (r != &the_lnet.ln_routers) {
+			lnet_peer_t *lp = list_entry(r, lnet_peer_t,
+							 lp_rtr_list);
+
+			if (skip == 0) {
+				peer = lp;
+				break;
+			}
+
+			skip--;
+			r = r->next;
+		}
+
+		if (peer != NULL) {
+			lnet_nid_t nid = peer->lp_nid;
+			cfs_time_t now = cfs_time_current();
+			cfs_time_t deadline = peer->lp_ping_deadline;
+			int nrefs     = peer->lp_refcount;
+			int nrtrrefs  = peer->lp_rtr_refcount;
+			int alive_cnt = peer->lp_alive_count;
+			int alive     = peer->lp_alive;
+			int pingsent  = !peer->lp_ping_notsent;
+			int last_ping = cfs_duration_sec(cfs_time_sub(now,
+						     peer->lp_ping_timestamp));
+			int down_ni   = 0;
+			lnet_route_t *rtr;
+
+			if ((peer->lp_ping_feats &
+			     LNET_PING_FEAT_NI_STATUS) != 0) {
+				list_for_each_entry(rtr, &peer->lp_routes,
+							lr_gwlist) {
+					/* downis on any route should be the
+					 * number of downis on the gateway */
+					if (rtr->lr_downis != 0) {
+						down_ni = rtr->lr_downis;
+						break;
+					}
+				}
+			}
+
+			if (deadline == 0)
+				s += snprintf(s, tmpstr + tmpsiz - s,
+					      "%-4d %7d %9d %6s %12d %9d %8s %7d %s\n",
+					      nrefs, nrtrrefs, alive_cnt,
+					      alive ? "up" : "down", last_ping,
+					      pingsent, "NA", down_ni,
+					      libcfs_nid2str(nid));
+			else
+				s += snprintf(s, tmpstr + tmpsiz - s,
+					      "%-4d %7d %9d %6s %12d %9d %8lu %7d %s\n",
+					      nrefs, nrtrrefs, alive_cnt,
+					      alive ? "up" : "down", last_ping,
+					      pingsent,
+					      cfs_duration_sec(cfs_time_sub(deadline, now)),
+					      down_ni, libcfs_nid2str(nid));
+			LASSERT (tmpstr + tmpsiz - s > 0);
+		}
+
+		lnet_net_unlock(0);
+	}
+
+	len = s - tmpstr;     /* how many bytes was written */
+
+	if (len > *lenp) {    /* linux-supplied buffer is too small */
+		rc = -EINVAL;
+	} else if (len > 0) { /* wrote something */
+		if (copy_to_user(buffer, tmpstr, len))
+			rc = -EFAULT;
+		else {
+			off += 1;
+			*ppos = LNET_PROC_POS_MAKE(0, ver, 0, off);
+		}
+	}
+
+	LIBCFS_FREE(tmpstr, tmpsiz);
+
+	if (rc == 0)
+		*lenp = len;
+
+	return rc;
+}
+
+int LL_PROC_PROTO(proc_lnet_peers)
+{
+	const int		tmpsiz  = 256;
+	struct lnet_peer_table	*ptable;
+	char			*tmpstr;
+	char			*s;
+	int			cpt  = LNET_PROC_CPT_GET(*ppos);
+	int			ver  = LNET_PROC_VER_GET(*ppos);
+	int			hash = LNET_PROC_HASH_GET(*ppos);
+	int			hoff = LNET_PROC_HOFF_GET(*ppos);
+	int			rc = 0;
+	int			len;
+
+	CLASSERT(LNET_PROC_HASH_BITS >= LNET_PEER_HASH_BITS);
+	LASSERT(!write);
+
+	if (*lenp == 0)
+		return 0;
+
+	if (cpt >= LNET_CPT_NUMBER) {
+		*lenp = 0;
+		return 0;
+	}
+
+	LIBCFS_ALLOC(tmpstr, tmpsiz);
+	if (tmpstr == NULL)
+		return -ENOMEM;
+
+	s = tmpstr; /* points to current position in tmpstr[] */
+
+	if (*ppos == 0) {
+		s += snprintf(s, tmpstr + tmpsiz - s,
+			      "%-24s %4s %5s %5s %5s %5s %5s %5s %5s %s\n",
+			      "nid", "refs", "state", "last", "max",
+			      "rtr", "min", "tx", "min", "queue");
+		LASSERT (tmpstr + tmpsiz - s > 0);
+
+		hoff++;
+	} else {
+		struct lnet_peer	*peer;
+		struct list_head		*p;
+		int			skip;
+ again:
+		p = NULL;
+		peer = NULL;
+		skip = hoff - 1;
+
+		lnet_net_lock(cpt);
+		ptable = the_lnet.ln_peer_tables[cpt];
+		if (hoff == 1)
+			ver = LNET_PROC_VERSION(ptable->pt_version);
+
+		if (ver != LNET_PROC_VERSION(ptable->pt_version)) {
+			lnet_net_unlock(cpt);
+			LIBCFS_FREE(tmpstr, tmpsiz);
+			return -ESTALE;
+		}
+
+		while (hash < LNET_PEER_HASH_SIZE) {
+			if (p == NULL)
+				p = ptable->pt_hash[hash].next;
+
+			while (p != &ptable->pt_hash[hash]) {
+				lnet_peer_t *lp = list_entry(p, lnet_peer_t,
+								 lp_hashlist);
+				if (skip == 0) {
+					peer = lp;
+
+					/* minor optimization: start from idx+1
+					 * on next iteration if we've just
+					 * drained lp_hashlist */
+					if (lp->lp_hashlist.next ==
+					    &ptable->pt_hash[hash]) {
+						hoff = 1;
+						hash++;
+					} else {
+						hoff++;
+					}
+
+					break;
+				}
+
+				skip--;
+				p = lp->lp_hashlist.next;
+			}
+
+			if (peer != NULL)
+				break;
+
+			p = NULL;
+			hoff = 1;
+			hash++;
+		}
+
+		if (peer != NULL) {
+			lnet_nid_t nid       = peer->lp_nid;
+			int	nrefs     = peer->lp_refcount;
+			int	lastalive = -1;
+			char      *aliveness = "NA";
+			int	maxcr     = peer->lp_ni->ni_peertxcredits;
+			int	txcr      = peer->lp_txcredits;
+			int	mintxcr   = peer->lp_mintxcredits;
+			int	rtrcr     = peer->lp_rtrcredits;
+			int	minrtrcr  = peer->lp_minrtrcredits;
+			int	txqnob    = peer->lp_txqnob;
+
+			if (lnet_isrouter(peer) ||
+			    lnet_peer_aliveness_enabled(peer))
+				aliveness = peer->lp_alive ? "up" : "down";
+
+			if (lnet_peer_aliveness_enabled(peer)) {
+				cfs_time_t     now = cfs_time_current();
+				cfs_duration_t delta;
+
+				delta = cfs_time_sub(now, peer->lp_last_alive);
+				lastalive = cfs_duration_sec(delta);
+
+				/* No need to mess up peers contents with
+				 * arbitrarily long integers - it suffices to
+				 * know that lastalive is more than 10000s old
+				 */
+				if (lastalive >= 10000)
+					lastalive = 9999;
+			}
+
+			lnet_net_unlock(cpt);
+
+			s += snprintf(s, tmpstr + tmpsiz - s,
+				      "%-24s %4d %5s %5d %5d %5d %5d %5d %5d %d\n",
+				      libcfs_nid2str(nid), nrefs, aliveness,
+				      lastalive, maxcr, rtrcr, minrtrcr, txcr,
+				      mintxcr, txqnob);
+			LASSERT (tmpstr + tmpsiz - s > 0);
+
+		} else { /* peer is NULL */
+			lnet_net_unlock(cpt);
+		}
+
+		if (hash == LNET_PEER_HASH_SIZE) {
+			cpt++;
+			hash = 0;
+			hoff = 1;
+			if (peer == NULL && cpt < LNET_CPT_NUMBER)
+				goto again;
+		}
+	}
+
+	len = s - tmpstr;     /* how many bytes was written */
+
+	if (len > *lenp) {    /* linux-supplied buffer is too small */
+		rc = -EINVAL;
+	} else if (len > 0) { /* wrote something */
+		if (copy_to_user(buffer, tmpstr, len))
+			rc = -EFAULT;
+		else
+			*ppos = LNET_PROC_POS_MAKE(cpt, ver, hash, hoff);
+	}
+
+	LIBCFS_FREE(tmpstr, tmpsiz);
+
+	if (rc == 0)
+		*lenp = len;
+
+	return rc;
+}
+
+static int __proc_lnet_buffers(void *data, int write,
+			       loff_t pos, void *buffer, int nob)
+{
+	char	    *s;
+	char	    *tmpstr;
+	int		tmpsiz;
+	int		idx;
+	int		len;
+	int		rc;
+	int		i;
+
+	LASSERT(!write);
+
+	/* (4 %d) * 4 * LNET_CPT_NUMBER */
+	tmpsiz = 64 * (LNET_NRBPOOLS + 1) * LNET_CPT_NUMBER;
+	LIBCFS_ALLOC(tmpstr, tmpsiz);
+	if (tmpstr == NULL)
+		return -ENOMEM;
+
+	s = tmpstr; /* points to current position in tmpstr[] */
+
+	s += snprintf(s, tmpstr + tmpsiz - s,
+		      "%5s %5s %7s %7s\n",
+		      "pages", "count", "credits", "min");
+	LASSERT (tmpstr + tmpsiz - s > 0);
+
+	if (the_lnet.ln_rtrpools == NULL)
+		goto out; /* I'm not a router */
+
+	for (idx = 0; idx < LNET_NRBPOOLS; idx++) {
+		lnet_rtrbufpool_t *rbp;
+
+		lnet_net_lock(LNET_LOCK_EX);
+		cfs_percpt_for_each(rbp, i, the_lnet.ln_rtrpools) {
+			s += snprintf(s, tmpstr + tmpsiz - s,
+				      "%5d %5d %7d %7d\n",
+				      rbp[idx].rbp_npages,
+				      rbp[idx].rbp_nbuffers,
+				      rbp[idx].rbp_credits,
+				      rbp[idx].rbp_mincredits);
+			LASSERT(tmpstr + tmpsiz - s > 0);
+		}
+		lnet_net_unlock(LNET_LOCK_EX);
+	}
+
+ out:
+	len = s - tmpstr;
+
+	if (pos >= min_t(int, len, strlen(tmpstr)))
+		rc = 0;
+	else
+		rc = cfs_trace_copyout_string(buffer, nob,
+					      tmpstr + pos, NULL);
+
+	LIBCFS_FREE(tmpstr, tmpsiz);
+	return rc;
+}
+
+DECLARE_PROC_HANDLER(proc_lnet_buffers);
+
+int LL_PROC_PROTO(proc_lnet_nis)
+{
+	int	tmpsiz = 128 * LNET_CPT_NUMBER;
+	int	rc = 0;
+	char      *tmpstr;
+	char      *s;
+	int	len;
+
+	DECLARE_LL_PROC_PPOS_DECL;
+
+	LASSERT (!write);
+
+	if (*lenp == 0)
+		return 0;
+
+	LIBCFS_ALLOC(tmpstr, tmpsiz);
+	if (tmpstr == NULL)
+		return -ENOMEM;
+
+	s = tmpstr; /* points to current position in tmpstr[] */
+
+	if (*ppos == 0) {
+		s += snprintf(s, tmpstr + tmpsiz - s,
+			      "%-24s %6s %5s %4s %4s %4s %5s %5s %5s\n",
+			      "nid", "status", "alive", "refs", "peer",
+			      "rtr", "max", "tx", "min");
+		LASSERT (tmpstr + tmpsiz - s > 0);
+	} else {
+		struct list_head	*n;
+		lnet_ni_t	 *ni   = NULL;
+		int		skip = *ppos - 1;
+
+		lnet_net_lock(0);
+
+		n = the_lnet.ln_nis.next;
+
+		while (n != &the_lnet.ln_nis) {
+			lnet_ni_t *a_ni = list_entry(n, lnet_ni_t, ni_list);
+
+			if (skip == 0) {
+				ni = a_ni;
+				break;
+			}
+
+			skip--;
+			n = n->next;
+		}
+
+		if (ni != NULL) {
+			struct lnet_tx_queue	*tq;
+			char	*stat;
+			long	now = cfs_time_current_sec();
+			int	last_alive = -1;
+			int	i;
+			int	j;
+
+			if (the_lnet.ln_routing)
+				last_alive = now - ni->ni_last_alive;
+
+			/* @lo forever alive */
+			if (ni->ni_lnd->lnd_type == LOLND)
+				last_alive = 0;
+
+			lnet_ni_lock(ni);
+			LASSERT(ni->ni_status != NULL);
+			stat = (ni->ni_status->ns_status ==
+				LNET_NI_STATUS_UP) ? "up" : "down";
+			lnet_ni_unlock(ni);
+
+			/* we actually output credits information for
+			 * TX queue of each partition */
+			cfs_percpt_for_each(tq, i, ni->ni_tx_queues) {
+				for (j = 0; ni->ni_cpts != NULL &&
+				     j < ni->ni_ncpts; j++) {
+					if (i == ni->ni_cpts[j])
+						break;
+				}
+
+				if (j == ni->ni_ncpts)
+					continue;
+
+				if (i != 0)
+					lnet_net_lock(i);
+
+				s += snprintf(s, tmpstr + tmpsiz - s,
+				      "%-24s %6s %5d %4d %4d %4d %5d %5d %5d\n",
+				      libcfs_nid2str(ni->ni_nid), stat,
+				      last_alive, *ni->ni_refs[i],
+				      ni->ni_peertxcredits,
+				      ni->ni_peerrtrcredits,
+				      tq->tq_credits_max,
+				      tq->tq_credits, tq->tq_credits_min);
+				if (i != 0)
+					lnet_net_unlock(i);
+			}
+			LASSERT(tmpstr + tmpsiz - s > 0);
+		}
+
+		lnet_net_unlock(0);
+	}
+
+	len = s - tmpstr;     /* how many bytes was written */
+
+	if (len > *lenp) {    /* linux-supplied buffer is too small */
+		rc = -EINVAL;
+	} else if (len > 0) { /* wrote something */
+		if (copy_to_user(buffer, tmpstr, len))
+			rc = -EFAULT;
+		else
+			*ppos += 1;
+	}
+
+	LIBCFS_FREE(tmpstr, tmpsiz);
+
+	if (rc == 0)
+		*lenp = len;
+
+	return rc;
+}
+
+struct lnet_portal_rotors {
+	int	     pr_value;
+	const char      *pr_name;
+	const char	*pr_desc;
+};
+
+static struct lnet_portal_rotors	portal_rotors[] = {
+	{
+		.pr_value = LNET_PTL_ROTOR_OFF,
+		.pr_name  = "OFF",
+		.pr_desc  = "Turn off message rotor for wildcard portals"
+	},
+	{
+		.pr_value = LNET_PTL_ROTOR_ON,
+		.pr_name  = "ON",
+		.pr_desc  = "round-robin dispatch all PUT messages for "
+			    "wildcard portals"
+	},
+	{
+		.pr_value = LNET_PTL_ROTOR_RR_RT,
+		.pr_name  = "RR_RT",
+		.pr_desc  = "round-robin dispatch routed PUT message for "
+			    "wildcard portals"
+	},
+	{
+		.pr_value = LNET_PTL_ROTOR_HASH_RT,
+		.pr_name  = "HASH_RT",
+		.pr_desc  = "dispatch routed PUT message by hashing source "
+			    "NID for wildcard portals"
+	},
+	{
+		.pr_value = -1,
+		.pr_name  = NULL,
+		.pr_desc  = NULL
+	},
+};
+
+extern int portal_rotor;
+
+static int __proc_lnet_portal_rotor(void *data, int write,
+				    loff_t pos, void *buffer, int nob)
+{
+	const int	buf_len	= 128;
+	char		*buf;
+	char		*tmp;
+	int		rc;
+	int		i;
+
+	LIBCFS_ALLOC(buf, buf_len);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	if (!write) {
+		lnet_res_lock(0);
+
+		for (i = 0; portal_rotors[i].pr_value >= 0; i++) {
+			if (portal_rotors[i].pr_value == portal_rotor)
+				break;
+		}
+
+		LASSERT(portal_rotors[i].pr_value == portal_rotor);
+		lnet_res_unlock(0);
+
+		rc = snprintf(buf, buf_len,
+			      "{\n\tportals: all\n"
+			      "\trotor: %s\n\tdescription: %s\n}",
+			      portal_rotors[i].pr_name,
+			      portal_rotors[i].pr_desc);
+
+		if (pos >= min_t(int, rc, buf_len)) {
+			rc = 0;
+		} else {
+			rc = cfs_trace_copyout_string(buffer, nob,
+					buf + pos, "\n");
+		}
+		goto out;
+	}
+
+	rc = cfs_trace_copyin_string(buf, buf_len, buffer, nob);
+	if (rc < 0)
+		goto out;
+
+	tmp = cfs_trimwhite(buf);
+
+	rc = -EINVAL;
+	lnet_res_lock(0);
+	for (i = 0; portal_rotors[i].pr_name != NULL; i++) {
+		if (cfs_strncasecmp(portal_rotors[i].pr_name, tmp,
+				    strlen(portal_rotors[i].pr_name)) == 0) {
+			portal_rotor = portal_rotors[i].pr_value;
+			rc = 0;
+			break;
+		}
+	}
+	lnet_res_unlock(0);
+out:
+	LIBCFS_FREE(buf, buf_len);
+	return rc;
+}
+DECLARE_PROC_HANDLER(proc_lnet_portal_rotor);
+
+static ctl_table_t lnet_table[] = {
+	/*
+	 * NB No .strategy entries have been provided since sysctl(8) prefers
+	 * to go via /proc for portability.
+	 */
+	{
+		INIT_CTL_NAME(PSDEV_LNET_STATS)
+		.procname = "stats",
+		.mode     = 0644,
+		.proc_handler = &proc_lnet_stats,
+	},
+	{
+		INIT_CTL_NAME(PSDEV_LNET_ROUTES)
+		.procname = "routes",
+		.mode     = 0444,
+		.proc_handler = &proc_lnet_routes,
+	},
+	{
+		INIT_CTL_NAME(PSDEV_LNET_ROUTERS)
+		.procname = "routers",
+		.mode     = 0444,
+		.proc_handler = &proc_lnet_routers,
+	},
+	{
+		INIT_CTL_NAME(PSDEV_LNET_PEERS)
+		.procname = "peers",
+		.mode     = 0444,
+		.proc_handler = &proc_lnet_peers,
+	},
+	{
+		INIT_CTL_NAME(PSDEV_LNET_PEERS)
+		.procname = "buffers",
+		.mode     = 0444,
+		.proc_handler = &proc_lnet_buffers,
+	},
+	{
+		INIT_CTL_NAME(PSDEV_LNET_NIS)
+		.procname = "nis",
+		.mode     = 0444,
+		.proc_handler = &proc_lnet_nis,
+	},
+	{
+		INIT_CTL_NAME(PSDEV_LNET_PTL_ROTOR)
+		.procname = "portal_rotor",
+		.mode     = 0644,
+		.proc_handler = &proc_lnet_portal_rotor,
+	},
+	{
+		INIT_CTL_NAME(0)
+	}
+};
+
+static ctl_table_t top_table[] = {
+	{
+		INIT_CTL_NAME(CTL_LNET)
+		.procname = "lnet",
+		.mode     = 0555,
+		.data     = NULL,
+		.maxlen   = 0,
+		.child    = lnet_table,
+	},
+	{
+		INIT_CTL_NAME(0)
+	}
+};
+
+void
+lnet_proc_init(void)
+{
+#ifdef CONFIG_SYSCTL
+	if (lnet_table_header == NULL)
+		lnet_table_header = cfs_register_sysctl_table(top_table, 0);
+#endif
+}
+
+void
+lnet_proc_fini(void)
+{
+#ifdef CONFIG_SYSCTL
+	if (lnet_table_header != NULL)
+		unregister_sysctl_table(lnet_table_header);
+
+	lnet_table_header = NULL;
+#endif
+}
+
+#else
+
+void
+lnet_proc_init(void)
+{
+}
+
+void
+lnet_proc_fini(void)
+{
+}
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/Makefile
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1 @@
+obj-$(CONFIG_LNET) := klnds/ lnet/ selftest/
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/brw_test.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/brw_test.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/brw_test.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/brw_test.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,499 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/brw_test.c
+ *
+ * Author: Isaac Huang <isaac@clusterfs.com>
+ */
+
+#include "selftest.h"
+
+static int brw_srv_workitems = SFW_TEST_WI_MAX;
+CFS_MODULE_PARM(brw_srv_workitems, "i", int, 0644, "# BRW server workitems");
+
+static int brw_inject_errors;
+CFS_MODULE_PARM(brw_inject_errors, "i", int, 0644,
+		"# data errors to inject randomly, zero by default");
+
+static void
+brw_client_fini (sfw_test_instance_t *tsi)
+{
+	srpc_bulk_t     *bulk;
+	sfw_test_unit_t *tsu;
+
+	LASSERT (tsi->tsi_is_client);
+
+	list_for_each_entry (tsu, &tsi->tsi_units, tsu_list) {
+		bulk = tsu->tsu_private;
+		if (bulk == NULL) continue;
+
+		srpc_free_bulk(bulk);
+		tsu->tsu_private = NULL;
+	}
+}
+
+int
+brw_client_init (sfw_test_instance_t *tsi)
+{
+	sfw_session_t	 *sn = tsi->tsi_batch->bat_session;
+	int		  flags;
+	int		  npg;
+	int		  len;
+	int		  opc;
+	srpc_bulk_t	 *bulk;
+	sfw_test_unit_t	 *tsu;
+
+	LASSERT(sn != NULL);
+	LASSERT(tsi->tsi_is_client);
+
+	if ((sn->sn_features & LST_FEAT_BULK_LEN) == 0) {
+		test_bulk_req_t  *breq = &tsi->tsi_u.bulk_v0;
+
+		opc   = breq->blk_opc;
+		flags = breq->blk_flags;
+		npg   = breq->blk_npg;
+		/* NB: this is not going to work for variable page size,
+		 * but we have to keep it for compatibility */
+		len   = npg * PAGE_CACHE_SIZE;
+
+	} else {
+		test_bulk_req_v1_t  *breq = &tsi->tsi_u.bulk_v1;
+
+		/* I should never get this step if it's unknown feature
+		 * because make_session will reject unknown feature */
+		LASSERT((sn->sn_features & ~LST_FEATS_MASK) == 0);
+
+		opc   = breq->blk_opc;
+		flags = breq->blk_flags;
+		len   = breq->blk_len;
+		npg   = (len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	}
+
+	if (npg > LNET_MAX_IOV || npg <= 0)
+		return -EINVAL;
+
+	if (opc != LST_BRW_READ && opc != LST_BRW_WRITE)
+		return -EINVAL;
+
+	if (flags != LST_BRW_CHECK_NONE &&
+	    flags != LST_BRW_CHECK_FULL && flags != LST_BRW_CHECK_SIMPLE)
+		return -EINVAL;
+
+	list_for_each_entry(tsu, &tsi->tsi_units, tsu_list) {
+		bulk = srpc_alloc_bulk(lnet_cpt_of_nid(tsu->tsu_dest.nid),
+				       npg, len, opc == LST_BRW_READ);
+		if (bulk == NULL) {
+			brw_client_fini(tsi);
+			return -ENOMEM;
+		}
+
+		tsu->tsu_private = bulk;
+	}
+
+	return 0;
+}
+
+#define BRW_POISON      0xbeefbeefbeefbeefULL
+#define BRW_MAGIC       0xeeb0eeb1eeb2eeb3ULL
+#define BRW_MSIZE       sizeof(__u64)
+
+int
+brw_inject_one_error (void)
+{
+	struct timeval tv;
+
+	if (brw_inject_errors <= 0) return 0;
+
+	do_gettimeofday(&tv);
+
+	if ((tv.tv_usec & 1) == 0) return 0;
+
+	return brw_inject_errors--;
+}
+
+void
+brw_fill_page (struct page *pg, int pattern, __u64 magic)
+{
+	char *addr = page_address(pg);
+	int   i;
+
+	LASSERT (addr != NULL);
+
+	if (pattern == LST_BRW_CHECK_NONE) return;
+
+	if (magic == BRW_MAGIC)
+		magic += brw_inject_one_error();
+
+	if (pattern == LST_BRW_CHECK_SIMPLE) {
+		memcpy(addr, &magic, BRW_MSIZE);
+		addr += PAGE_CACHE_SIZE - BRW_MSIZE;
+		memcpy(addr, &magic, BRW_MSIZE);
+		return;
+	}
+
+	if (pattern == LST_BRW_CHECK_FULL) {
+		for (i = 0; i < PAGE_CACHE_SIZE / BRW_MSIZE; i++)
+			memcpy(addr + i * BRW_MSIZE, &magic, BRW_MSIZE);
+		return;
+	}
+
+	LBUG ();
+	return;
+}
+
+int
+brw_check_page (struct page *pg, int pattern, __u64 magic)
+{
+	char  *addr = page_address(pg);
+	__u64  data = 0; /* make compiler happy */
+	int    i;
+
+	LASSERT (addr != NULL);
+
+	if (pattern == LST_BRW_CHECK_NONE)
+		return 0;
+
+	if (pattern == LST_BRW_CHECK_SIMPLE) {
+		data = *((__u64 *) addr);
+		if (data != magic) goto bad_data;
+
+		addr += PAGE_CACHE_SIZE - BRW_MSIZE;
+		data = *((__u64 *) addr);
+		if (data != magic) goto bad_data;
+
+		return 0;
+	}
+
+	if (pattern == LST_BRW_CHECK_FULL) {
+		for (i = 0; i < PAGE_CACHE_SIZE / BRW_MSIZE; i++) {
+			data = *(((__u64 *) addr) + i);
+			if (data != magic) goto bad_data;
+		}
+
+		return 0;
+	}
+
+	LBUG ();
+
+bad_data:
+	CERROR ("Bad data in page %p: "LPX64", "LPX64" expected\n",
+		pg, data, magic);
+	return 1;
+}
+
+void
+brw_fill_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
+{
+	int	 i;
+	struct page *pg;
+
+	for (i = 0; i < bk->bk_niov; i++) {
+		pg = bk->bk_iovs[i].kiov_page;
+		brw_fill_page(pg, pattern, magic);
+	}
+}
+
+int
+brw_check_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
+{
+	int	 i;
+	struct page *pg;
+
+	for (i = 0; i < bk->bk_niov; i++) {
+		pg = bk->bk_iovs[i].kiov_page;
+		if (brw_check_page(pg, pattern, magic) != 0) {
+			CERROR ("Bulk page %p (%d/%d) is corrupted!\n",
+				pg, i, bk->bk_niov);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int
+brw_client_prep_rpc (sfw_test_unit_t *tsu,
+		     lnet_process_id_t dest, srpc_client_rpc_t **rpcpp)
+{
+	srpc_bulk_t	 *bulk = tsu->tsu_private;
+	sfw_test_instance_t *tsi = tsu->tsu_instance;
+	sfw_session_t	    *sn = tsi->tsi_batch->bat_session;
+	srpc_client_rpc_t   *rpc;
+	srpc_brw_reqst_t    *req;
+	int		     flags;
+	int		     npg;
+	int		     len;
+	int		     opc;
+	int		     rc;
+
+	LASSERT(sn != NULL);
+	LASSERT(bulk != NULL);
+
+	if ((sn->sn_features & LST_FEAT_BULK_LEN) == 0) {
+		test_bulk_req_t *breq = &tsi->tsi_u.bulk_v0;
+
+		opc   = breq->blk_opc;
+		flags = breq->blk_flags;
+		npg   = breq->blk_npg;
+		len   = npg * PAGE_CACHE_SIZE;
+
+	} else {
+		test_bulk_req_v1_t  *breq = &tsi->tsi_u.bulk_v1;
+
+		/* I should never get this step if it's unknown feature
+		 * because make_session will reject unknown feature */
+		LASSERT((sn->sn_features & ~LST_FEATS_MASK) == 0);
+
+		opc   = breq->blk_opc;
+		flags = breq->blk_flags;
+		len   = breq->blk_len;
+		npg   = (len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	}
+
+	rc = sfw_create_test_rpc(tsu, dest, sn->sn_features, npg, len, &rpc);
+	if (rc != 0)
+		return rc;
+
+	memcpy(&rpc->crpc_bulk, bulk, offsetof(srpc_bulk_t, bk_iovs[npg]));
+	if (opc == LST_BRW_WRITE)
+		brw_fill_bulk(&rpc->crpc_bulk, flags, BRW_MAGIC);
+	else
+		brw_fill_bulk(&rpc->crpc_bulk, flags, BRW_POISON);
+
+	req = &rpc->crpc_reqstmsg.msg_body.brw_reqst;
+	req->brw_flags = flags;
+	req->brw_rw    = opc;
+	req->brw_len   = len;
+
+	*rpcpp = rpc;
+	return 0;
+}
+
+static void
+brw_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
+{
+	__u64		magic = BRW_MAGIC;
+	sfw_test_instance_t *tsi = tsu->tsu_instance;
+	sfw_session_t       *sn = tsi->tsi_batch->bat_session;
+	srpc_msg_t	  *msg = &rpc->crpc_replymsg;
+	srpc_brw_reply_t    *reply = &msg->msg_body.brw_reply;
+	srpc_brw_reqst_t    *reqst = &rpc->crpc_reqstmsg.msg_body.brw_reqst;
+
+	LASSERT (sn != NULL);
+
+	if (rpc->crpc_status != 0) {
+		CERROR ("BRW RPC to %s failed with %d\n",
+			libcfs_id2str(rpc->crpc_dest), rpc->crpc_status);
+		if (!tsi->tsi_stopping) /* rpc could have been aborted */
+			atomic_inc(&sn->sn_brw_errors);
+		goto out;
+	}
+
+	if (msg->msg_magic != SRPC_MSG_MAGIC) {
+		__swab64s(&magic);
+		__swab32s(&reply->brw_status);
+	}
+
+	CDEBUG (reply->brw_status ? D_WARNING : D_NET,
+		"BRW RPC to %s finished with brw_status: %d\n",
+		libcfs_id2str(rpc->crpc_dest), reply->brw_status);
+
+	if (reply->brw_status != 0) {
+		atomic_inc(&sn->sn_brw_errors);
+		rpc->crpc_status = -(int)reply->brw_status;
+		goto out;
+	}
+
+	if (reqst->brw_rw == LST_BRW_WRITE) goto out;
+
+	if (brw_check_bulk(&rpc->crpc_bulk, reqst->brw_flags, magic) != 0) {
+		CERROR ("Bulk data from %s is corrupted!\n",
+			libcfs_id2str(rpc->crpc_dest));
+		atomic_inc(&sn->sn_brw_errors);
+		rpc->crpc_status = -EBADMSG;
+	}
+
+out:
+	return;
+}
+
+void
+brw_server_rpc_done (srpc_server_rpc_t *rpc)
+{
+	srpc_bulk_t *blk = rpc->srpc_bulk;
+
+	if (blk == NULL) return;
+
+	if (rpc->srpc_status != 0)
+		CERROR ("Bulk transfer %s %s has failed: %d\n",
+			blk->bk_sink ? "from" : "to",
+			libcfs_id2str(rpc->srpc_peer), rpc->srpc_status);
+	else
+		CDEBUG (D_NET, "Transfered %d pages bulk data %s %s\n",
+			blk->bk_niov, blk->bk_sink ? "from" : "to",
+			libcfs_id2str(rpc->srpc_peer));
+
+	sfw_free_pages(rpc);
+}
+
+int
+brw_bulk_ready (srpc_server_rpc_t *rpc, int status)
+{
+	__u64	     magic = BRW_MAGIC;
+	srpc_brw_reply_t *reply = &rpc->srpc_replymsg.msg_body.brw_reply;
+	srpc_brw_reqst_t *reqst;
+	srpc_msg_t       *reqstmsg;
+
+	LASSERT (rpc->srpc_bulk != NULL);
+	LASSERT (rpc->srpc_reqstbuf != NULL);
+
+	reqstmsg = &rpc->srpc_reqstbuf->buf_msg;
+	reqst = &reqstmsg->msg_body.brw_reqst;
+
+	if (status != 0) {
+		CERROR ("BRW bulk %s failed for RPC from %s: %d\n",
+			reqst->brw_rw == LST_BRW_READ ? "READ" : "WRITE",
+			libcfs_id2str(rpc->srpc_peer), status);
+		return -EIO;
+	}
+
+	if (reqst->brw_rw == LST_BRW_READ)
+		return 0;
+
+	if (reqstmsg->msg_magic != SRPC_MSG_MAGIC)
+		__swab64s(&magic);
+
+	if (brw_check_bulk(rpc->srpc_bulk, reqst->brw_flags, magic) != 0) {
+		CERROR ("Bulk data from %s is corrupted!\n",
+			libcfs_id2str(rpc->srpc_peer));
+		reply->brw_status = EBADMSG;
+	}
+
+	return 0;
+}
+
+int
+brw_server_handle(struct srpc_server_rpc *rpc)
+{
+	struct srpc_service	*sv = rpc->srpc_scd->scd_svc;
+	srpc_msg_t       *replymsg = &rpc->srpc_replymsg;
+	srpc_msg_t       *reqstmsg = &rpc->srpc_reqstbuf->buf_msg;
+	srpc_brw_reply_t *reply = &replymsg->msg_body.brw_reply;
+	srpc_brw_reqst_t *reqst = &reqstmsg->msg_body.brw_reqst;
+	int		  npg;
+	int	       rc;
+
+	LASSERT (sv->sv_id == SRPC_SERVICE_BRW);
+
+	if (reqstmsg->msg_magic != SRPC_MSG_MAGIC) {
+		LASSERT (reqstmsg->msg_magic == __swab32(SRPC_MSG_MAGIC));
+
+		__swab32s(&reqst->brw_rw);
+		__swab32s(&reqst->brw_len);
+		__swab32s(&reqst->brw_flags);
+		__swab64s(&reqst->brw_rpyid);
+		__swab64s(&reqst->brw_bulkid);
+	}
+	LASSERT (reqstmsg->msg_type == (__u32)srpc_service2request(sv->sv_id));
+
+	reply->brw_status = 0;
+	rpc->srpc_done = brw_server_rpc_done;
+
+	if ((reqst->brw_rw != LST_BRW_READ && reqst->brw_rw != LST_BRW_WRITE) ||
+	    (reqst->brw_flags != LST_BRW_CHECK_NONE &&
+	     reqst->brw_flags != LST_BRW_CHECK_FULL &&
+	     reqst->brw_flags != LST_BRW_CHECK_SIMPLE)) {
+		reply->brw_status = EINVAL;
+		return 0;
+	}
+
+	if ((reqstmsg->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
+		replymsg->msg_ses_feats = LST_FEATS_MASK;
+		reply->brw_status = EPROTO;
+		return 0;
+	}
+
+	if ((reqstmsg->msg_ses_feats & LST_FEAT_BULK_LEN) == 0) {
+		/* compat with old version */
+		if ((reqst->brw_len & ~CFS_PAGE_MASK) != 0) {
+			reply->brw_status = EINVAL;
+			return 0;
+		}
+		npg = reqst->brw_len >> PAGE_CACHE_SHIFT;
+
+	} else {
+		npg = (reqst->brw_len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	}
+
+	replymsg->msg_ses_feats = reqstmsg->msg_ses_feats;
+
+	if (reqst->brw_len == 0 || npg > LNET_MAX_IOV) {
+		reply->brw_status = EINVAL;
+		return 0;
+	}
+
+	rc = sfw_alloc_pages(rpc, rpc->srpc_scd->scd_cpt, npg,
+			     reqst->brw_len,
+			     reqst->brw_rw == LST_BRW_WRITE);
+	if (rc != 0)
+		return rc;
+
+	if (reqst->brw_rw == LST_BRW_READ)
+		brw_fill_bulk(rpc->srpc_bulk, reqst->brw_flags, BRW_MAGIC);
+	else
+		brw_fill_bulk(rpc->srpc_bulk, reqst->brw_flags, BRW_POISON);
+
+	return 0;
+}
+
+sfw_test_client_ops_t brw_test_client;
+void brw_init_test_client(void)
+{
+	brw_test_client.tso_init       = brw_client_init;
+	brw_test_client.tso_fini       = brw_client_fini;
+	brw_test_client.tso_prep_rpc   = brw_client_prep_rpc;
+	brw_test_client.tso_done_rpc   = brw_client_done_rpc;
+};
+
+srpc_service_t brw_test_service;
+void brw_init_test_service(void)
+{
+
+	brw_test_service.sv_id	 = SRPC_SERVICE_BRW;
+	brw_test_service.sv_name       = "brw_test";
+	brw_test_service.sv_handler    = brw_server_handle;
+	brw_test_service.sv_bulk_ready = brw_bulk_ready;
+	brw_test_service.sv_wi_total   = brw_srv_workitems;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/conctl.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/conctl.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/conctl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/conctl.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,931 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/conctl.c
+ *
+ * IOC handle in kernel
+ *
+ * Author: Liang Zhen <liangzhen@clusterfs.com>
+ */
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
+#include <linux/lnet/lnetst.h>
+#include "console.h"
+
+int
+lst_session_new_ioctl(lstio_session_new_args_t *args)
+{
+	char      *name;
+	int	rc;
+
+	if (args->lstio_ses_idp   == NULL || /* address for output sid */
+	    args->lstio_ses_key   == 0 || /* no key is specified */
+	    args->lstio_ses_namep == NULL || /* session name */
+	    args->lstio_ses_nmlen <= 0 ||
+	    args->lstio_ses_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_ses_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			       args->lstio_ses_namep,
+			       args->lstio_ses_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
+		return -EFAULT;
+	}
+
+	name[args->lstio_ses_nmlen] = 0;
+
+	rc = lstcon_session_new(name,
+				args->lstio_ses_key,
+				args->lstio_ses_feats,
+				args->lstio_ses_force,
+				args->lstio_ses_timeout,
+				args->lstio_ses_idp);
+
+	LIBCFS_FREE(name, args->lstio_ses_nmlen + 1);
+	return rc;
+}
+
+int
+lst_session_end_ioctl(lstio_session_end_args_t *args)
+{
+	if (args->lstio_ses_key != console_session.ses_key)
+		return -EACCES;
+
+	return lstcon_session_end();
+}
+
+int
+lst_session_info_ioctl(lstio_session_info_args_t *args)
+{
+	/* no checking of key */
+
+	if (args->lstio_ses_idp   == NULL || /* address for ouput sid */
+	    args->lstio_ses_keyp  == NULL || /* address for ouput key */
+	    args->lstio_ses_featp  == NULL || /* address for ouput features */
+	    args->lstio_ses_ndinfo == NULL || /* address for output ndinfo */
+	    args->lstio_ses_namep == NULL || /* address for ouput name */
+	    args->lstio_ses_nmlen <= 0 ||
+	    args->lstio_ses_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	return lstcon_session_info(args->lstio_ses_idp,
+				   args->lstio_ses_keyp,
+				   args->lstio_ses_featp,
+				   args->lstio_ses_ndinfo,
+				   args->lstio_ses_namep,
+				   args->lstio_ses_nmlen);
+}
+
+int
+lst_debug_ioctl(lstio_debug_args_t *args)
+{
+	char   *name   = NULL;
+	int     client = 1;
+	int     rc;
+
+	if (args->lstio_dbg_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_dbg_resultp == NULL)
+		return -EINVAL;
+
+	if (args->lstio_dbg_namep != NULL && /* name of batch/group */
+	    (args->lstio_dbg_nmlen <= 0 ||
+	     args->lstio_dbg_nmlen > LST_NAME_SIZE))
+		return -EINVAL;
+
+	if (args->lstio_dbg_namep != NULL) {
+		LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1);
+		if (name == NULL)
+			return -ENOMEM;
+
+		if (copy_from_user(name, args->lstio_dbg_namep,
+				       args->lstio_dbg_nmlen)) {
+			LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
+
+			return -EFAULT;
+		}
+
+		name[args->lstio_dbg_nmlen] = 0;
+	}
+
+	rc = -EINVAL;
+
+	switch (args->lstio_dbg_type) {
+	case LST_OPC_SESSION:
+		rc = lstcon_session_debug(args->lstio_dbg_timeout,
+					  args->lstio_dbg_resultp);
+		break;
+
+	case LST_OPC_BATCHSRV:
+		client = 0;
+	case LST_OPC_BATCHCLI:
+		if (name == NULL)
+			goto out;
+
+		rc = lstcon_batch_debug(args->lstio_dbg_timeout,
+					name, client, args->lstio_dbg_resultp);
+		break;
+
+	case LST_OPC_GROUP:
+		if (name == NULL)
+			goto out;
+
+		rc = lstcon_group_debug(args->lstio_dbg_timeout,
+					name, args->lstio_dbg_resultp);
+		break;
+
+	case LST_OPC_NODES:
+		if (args->lstio_dbg_count <= 0 ||
+		    args->lstio_dbg_idsp == NULL)
+			goto out;
+
+		rc = lstcon_nodes_debug(args->lstio_dbg_timeout,
+					args->lstio_dbg_count,
+					args->lstio_dbg_idsp,
+					args->lstio_dbg_resultp);
+		break;
+
+	default:
+		break;
+	}
+
+out:
+	if (name != NULL)
+		LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1);
+
+	return rc;
+}
+
+int
+lst_group_add_ioctl(lstio_group_add_args_t *args)
+{
+	char	   *name;
+	int	     rc;
+
+	if (args->lstio_grp_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_grp_namep == NULL||
+	    args->lstio_grp_nmlen <= 0 ||
+	    args->lstio_grp_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			       args->lstio_grp_namep,
+			       args->lstio_grp_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_grp_nmlen);
+		return -EFAULT;
+	}
+
+	name[args->lstio_grp_nmlen] = 0;
+
+	rc = lstcon_group_add(name);
+
+	LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
+
+	return rc;
+}
+
+int
+lst_group_del_ioctl(lstio_group_del_args_t *args)
+{
+	int     rc;
+	char   *name;
+
+	if (args->lstio_grp_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_grp_namep == NULL ||
+	    args->lstio_grp_nmlen <= 0 ||
+	    args->lstio_grp_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			       args->lstio_grp_namep,
+			       args->lstio_grp_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
+		return -EFAULT;
+	}
+
+	name[args->lstio_grp_nmlen] = 0;
+
+	rc = lstcon_group_del(name);
+
+	LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
+
+	return rc;
+}
+
+int
+lst_group_update_ioctl(lstio_group_update_args_t *args)
+{
+	int     rc;
+	char   *name;
+
+	if (args->lstio_grp_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_grp_resultp == NULL ||
+	    args->lstio_grp_namep == NULL ||
+	    args->lstio_grp_nmlen <= 0 ||
+	    args->lstio_grp_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			   args->lstio_grp_namep,
+			   args->lstio_grp_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
+		return -EFAULT;
+	}
+
+	name[args->lstio_grp_nmlen] = 0;
+
+	switch (args->lstio_grp_opc) {
+	case LST_GROUP_CLEAN:
+		rc = lstcon_group_clean(name, args->lstio_grp_args);
+		break;
+
+	case LST_GROUP_REFRESH:
+		rc = lstcon_group_refresh(name, args->lstio_grp_resultp);
+		break;
+
+	case LST_GROUP_RMND:
+		if (args->lstio_grp_count  <= 0 ||
+		    args->lstio_grp_idsp == NULL) {
+			rc = -EINVAL;
+			break;
+		}
+		rc = lstcon_nodes_remove(name, args->lstio_grp_count,
+					 args->lstio_grp_idsp,
+					 args->lstio_grp_resultp);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
+
+	return rc;
+}
+
+int
+lst_nodes_add_ioctl(lstio_group_nodes_args_t *args)
+{
+	unsigned feats;
+	int     rc;
+	char   *name;
+
+	if (args->lstio_grp_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_grp_idsp == NULL || /* array of ids */
+	    args->lstio_grp_count <= 0 ||
+	    args->lstio_grp_resultp == NULL ||
+	    args->lstio_grp_featp == NULL ||
+	    args->lstio_grp_namep == NULL ||
+	    args->lstio_grp_nmlen <= 0 ||
+	    args->lstio_grp_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name, args->lstio_grp_namep,
+			       args->lstio_grp_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
+
+		return -EFAULT;
+	}
+
+	name[args->lstio_grp_nmlen] = 0;
+
+	rc = lstcon_nodes_add(name, args->lstio_grp_count,
+			      args->lstio_grp_idsp, &feats,
+			      args->lstio_grp_resultp);
+
+	LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
+	if (rc == 0 &&
+	    copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) {
+		return -EINVAL;
+	}
+
+	return rc;
+}
+
+int
+lst_group_list_ioctl(lstio_group_list_args_t *args)
+{
+	if (args->lstio_grp_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_grp_idx   < 0 ||
+	    args->lstio_grp_namep == NULL ||
+	    args->lstio_grp_nmlen <= 0 ||
+	    args->lstio_grp_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	return lstcon_group_list(args->lstio_grp_idx,
+			      args->lstio_grp_nmlen,
+			      args->lstio_grp_namep);
+}
+
+int
+lst_group_info_ioctl(lstio_group_info_args_t *args)
+{
+	char	   *name;
+	int	     ndent;
+	int	     index;
+	int	     rc;
+
+	if (args->lstio_grp_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_grp_namep == NULL ||
+	    args->lstio_grp_nmlen <= 0 ||
+	    args->lstio_grp_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	if (args->lstio_grp_entp  == NULL && /* output: group entry */
+	    args->lstio_grp_dentsp == NULL)  /* output: node entry */
+		return -EINVAL;
+
+	if (args->lstio_grp_dentsp != NULL) { /* have node entry */
+		if (args->lstio_grp_idxp == NULL || /* node index */
+		    args->lstio_grp_ndentp == NULL) /* # of node entry */
+			return -EINVAL;
+
+		if (copy_from_user(&ndent, args->lstio_grp_ndentp,
+				       sizeof(ndent)) ||
+		    copy_from_user(&index, args->lstio_grp_idxp,
+				       sizeof(index)))
+			return -EFAULT;
+
+		if (ndent <= 0 || index < 0)
+			return -EINVAL;
+	}
+
+	LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			       args->lstio_grp_namep,
+			       args->lstio_grp_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
+		return -EFAULT;
+	}
+
+	name[args->lstio_grp_nmlen] = 0;
+
+	rc = lstcon_group_info(name, args->lstio_grp_entp,
+			       &index, &ndent, args->lstio_grp_dentsp);
+
+	LIBCFS_FREE(name, args->lstio_grp_nmlen + 1);
+
+	if (rc != 0)
+		return rc;
+
+	if (args->lstio_grp_dentsp != NULL &&
+	    (copy_to_user(args->lstio_grp_idxp, &index, sizeof(index)) ||
+	     copy_to_user(args->lstio_grp_ndentp, &ndent, sizeof(ndent))))
+		rc = -EFAULT;
+
+	return 0;
+}
+
+int
+lst_batch_add_ioctl(lstio_batch_add_args_t *args)
+{
+	int	     rc;
+	char	   *name;
+
+	if (args->lstio_bat_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_bat_namep == NULL ||
+	    args->lstio_bat_nmlen <= 0 ||
+	    args->lstio_bat_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			       args->lstio_bat_namep,
+			       args->lstio_bat_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+		return -EFAULT;
+	}
+
+	name[args->lstio_bat_nmlen] = 0;
+
+	rc = lstcon_batch_add(name);
+
+	LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+
+	return rc;
+}
+
+int
+lst_batch_run_ioctl(lstio_batch_run_args_t *args)
+{
+	int	     rc;
+	char	   *name;
+
+	if (args->lstio_bat_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_bat_namep == NULL ||
+	    args->lstio_bat_nmlen <= 0 ||
+	    args->lstio_bat_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			       args->lstio_bat_namep,
+			       args->lstio_bat_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+		return -EFAULT;
+	}
+
+	name[args->lstio_bat_nmlen] = 0;
+
+	rc = lstcon_batch_run(name, args->lstio_bat_timeout,
+			      args->lstio_bat_resultp);
+
+	LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+
+	return rc;
+}
+
+int
+lst_batch_stop_ioctl(lstio_batch_stop_args_t *args)
+{
+	int	     rc;
+	char	   *name;
+
+	if (args->lstio_bat_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_bat_resultp == NULL ||
+	    args->lstio_bat_namep == NULL ||
+	    args->lstio_bat_nmlen <= 0 ||
+	    args->lstio_bat_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			       args->lstio_bat_namep,
+			       args->lstio_bat_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+		return -EFAULT;
+	}
+
+	name[args->lstio_bat_nmlen] = 0;
+
+	rc = lstcon_batch_stop(name, args->lstio_bat_force,
+			       args->lstio_bat_resultp);
+
+	LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+
+	return rc;
+}
+
+int
+lst_batch_query_ioctl(lstio_batch_query_args_t *args)
+{
+	char   *name;
+	int     rc;
+
+	if (args->lstio_bat_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_bat_resultp == NULL ||
+	    args->lstio_bat_namep == NULL ||
+	    args->lstio_bat_nmlen <= 0 ||
+	    args->lstio_bat_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	if (args->lstio_bat_testidx < 0)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			       args->lstio_bat_namep,
+			       args->lstio_bat_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+		return -EFAULT;
+	}
+
+	name[args->lstio_bat_nmlen] = 0;
+
+	rc = lstcon_test_batch_query(name,
+				     args->lstio_bat_testidx,
+				     args->lstio_bat_client,
+				     args->lstio_bat_timeout,
+				     args->lstio_bat_resultp);
+
+	LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+
+	return rc;
+}
+
+int
+lst_batch_list_ioctl(lstio_batch_list_args_t *args)
+{
+	if (args->lstio_bat_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_bat_idx   < 0 ||
+	    args->lstio_bat_namep == NULL ||
+	    args->lstio_bat_nmlen <= 0 ||
+	    args->lstio_bat_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	return lstcon_batch_list(args->lstio_bat_idx,
+			      args->lstio_bat_nmlen,
+			      args->lstio_bat_namep);
+}
+
+int
+lst_batch_info_ioctl(lstio_batch_info_args_t *args)
+{
+	char	   *name;
+	int	     rc;
+	int	     index;
+	int	     ndent;
+
+	if (args->lstio_bat_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_bat_namep == NULL || /* batch name */
+	    args->lstio_bat_nmlen <= 0 ||
+	    args->lstio_bat_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	if (args->lstio_bat_entp == NULL && /* output: batch entry */
+	    args->lstio_bat_dentsp == NULL) /* output: node entry */
+		return -EINVAL;
+
+	if (args->lstio_bat_dentsp != NULL) { /* have node entry */
+		if (args->lstio_bat_idxp == NULL || /* node index */
+		    args->lstio_bat_ndentp == NULL) /* # of node entry */
+			return -EINVAL;
+
+		if (copy_from_user(&index, args->lstio_bat_idxp,
+				       sizeof(index)) ||
+		    copy_from_user(&ndent, args->lstio_bat_ndentp,
+				       sizeof(ndent)))
+			return -EFAULT;
+
+		if (ndent <= 0 || index < 0)
+			return -EINVAL;
+	}
+
+	LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name,
+			       args->lstio_bat_namep, args->lstio_bat_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+		return -EFAULT;
+	}
+
+	name[args->lstio_bat_nmlen] = 0;
+
+	rc = lstcon_batch_info(name,
+			    args->lstio_bat_entp, args->lstio_bat_server,
+			    args->lstio_bat_testidx, &index, &ndent,
+			    args->lstio_bat_dentsp);
+
+	LIBCFS_FREE(name, args->lstio_bat_nmlen + 1);
+
+	if (rc != 0)
+		return rc;
+
+	if (args->lstio_bat_dentsp != NULL &&
+	    (copy_to_user(args->lstio_bat_idxp, &index, sizeof(index)) ||
+	     copy_to_user(args->lstio_bat_ndentp, &ndent, sizeof(ndent))))
+		rc = -EFAULT;
+
+	return rc;
+}
+
+int
+lst_stat_query_ioctl(lstio_stat_args_t *args)
+{
+	int	     rc;
+	char	   *name;
+
+	/* TODO: not finished */
+	if (args->lstio_sta_key != console_session.ses_key)
+		return -EACCES;
+
+	if (args->lstio_sta_resultp == NULL ||
+	    (args->lstio_sta_namep  == NULL &&
+	     args->lstio_sta_idsp   == NULL) ||
+	    args->lstio_sta_nmlen <= 0 ||
+	    args->lstio_sta_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	if (args->lstio_sta_idsp != NULL &&
+	    args->lstio_sta_count <= 0)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1);
+	if (name == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(name, args->lstio_sta_namep,
+			       args->lstio_sta_nmlen)) {
+		LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
+		return -EFAULT;
+	}
+
+	if (args->lstio_sta_idsp == NULL) {
+		rc = lstcon_group_stat(name, args->lstio_sta_timeout,
+				       args->lstio_sta_resultp);
+	} else {
+		rc = lstcon_nodes_stat(args->lstio_sta_count,
+				       args->lstio_sta_idsp,
+				       args->lstio_sta_timeout,
+				       args->lstio_sta_resultp);
+	}
+
+	LIBCFS_FREE(name, args->lstio_sta_nmlen + 1);
+
+	return rc;
+}
+
+int lst_test_add_ioctl(lstio_test_args_t *args)
+{
+	char	   *name;
+	char	   *srcgrp = NULL;
+	char	   *dstgrp = NULL;
+	void	   *param = NULL;
+	int	     ret = 0;
+	int	     rc = -ENOMEM;
+
+	if (args->lstio_tes_resultp == NULL ||
+	    args->lstio_tes_retp == NULL ||
+	    args->lstio_tes_bat_name == NULL || /* no specified batch */
+	    args->lstio_tes_bat_nmlen <= 0 ||
+	    args->lstio_tes_bat_nmlen > LST_NAME_SIZE ||
+	    args->lstio_tes_sgrp_name == NULL || /* no source group */
+	    args->lstio_tes_sgrp_nmlen <= 0 ||
+	    args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE ||
+	    args->lstio_tes_dgrp_name == NULL || /* no target group */
+	    args->lstio_tes_dgrp_nmlen <= 0 ||
+	    args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE)
+		return -EINVAL;
+
+	if (args->lstio_tes_loop == 0 || /* negative is infinite */
+	    args->lstio_tes_concur <= 0 ||
+	    args->lstio_tes_dist <= 0 ||
+	    args->lstio_tes_span <= 0)
+		return -EINVAL;
+
+	/* have parameter, check if parameter length is valid */
+	if (args->lstio_tes_param != NULL &&
+	    (args->lstio_tes_param_len <= 0 ||
+	     args->lstio_tes_param_len > PAGE_CACHE_SIZE - sizeof(lstcon_test_t)))
+		return -EINVAL;
+
+	LIBCFS_ALLOC(name, args->lstio_tes_bat_nmlen + 1);
+	if (name == NULL)
+		return rc;
+
+	LIBCFS_ALLOC(srcgrp, args->lstio_tes_sgrp_nmlen + 1);
+	if (srcgrp == NULL)
+		goto out;
+
+	LIBCFS_ALLOC(dstgrp, args->lstio_tes_dgrp_nmlen + 1);
+	 if (dstgrp == NULL)
+		goto out;
+
+	if (args->lstio_tes_param != NULL) {
+		LIBCFS_ALLOC(param, args->lstio_tes_param_len);
+		if (param == NULL)
+			goto out;
+	}
+
+	rc = -EFAULT;
+	if (copy_from_user(name,
+			      args->lstio_tes_bat_name,
+			      args->lstio_tes_bat_nmlen) ||
+	    copy_from_user(srcgrp,
+			      args->lstio_tes_sgrp_name,
+			      args->lstio_tes_sgrp_nmlen) ||
+	    copy_from_user(dstgrp,
+			      args->lstio_tes_dgrp_name,
+			      args->lstio_tes_dgrp_nmlen) ||
+	    copy_from_user(param, args->lstio_tes_param,
+			      args->lstio_tes_param_len))
+		goto out;
+
+	rc = lstcon_test_add(name,
+			    args->lstio_tes_type,
+			    args->lstio_tes_loop,
+			    args->lstio_tes_concur,
+			    args->lstio_tes_dist, args->lstio_tes_span,
+			    srcgrp, dstgrp, param, args->lstio_tes_param_len,
+			    &ret, args->lstio_tes_resultp);
+
+	if (ret != 0)
+		rc = (copy_to_user(args->lstio_tes_retp, &ret,
+				       sizeof(ret))) ? -EFAULT : 0;
+out:
+	if (name != NULL)
+		LIBCFS_FREE(name, args->lstio_tes_bat_nmlen + 1);
+
+	if (srcgrp != NULL)
+		LIBCFS_FREE(srcgrp, args->lstio_tes_sgrp_nmlen + 1);
+
+	if (dstgrp != NULL)
+		LIBCFS_FREE(dstgrp, args->lstio_tes_dgrp_nmlen + 1);
+
+	if (param != NULL)
+		LIBCFS_FREE(param, args->lstio_tes_param_len);
+
+	return rc;
+}
+
+int
+lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_data *data)
+{
+	char   *buf;
+	int     opc = data->ioc_u32[0];
+	int     rc;
+
+	if (cmd != IOC_LIBCFS_LNETST)
+		return -EINVAL;
+
+	if (data->ioc_plen1 > PAGE_CACHE_SIZE)
+		return -EINVAL;
+
+	LIBCFS_ALLOC(buf, data->ioc_plen1);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	/* copy in parameter */
+	if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) {
+		LIBCFS_FREE(buf, data->ioc_plen1);
+		return -EFAULT;
+	}
+
+	mutex_lock(&console_session.ses_mutex);
+
+	console_session.ses_laststamp = cfs_time_current_sec();
+
+	if (console_session.ses_shutdown) {
+		rc = -ESHUTDOWN;
+		goto out;
+	}
+
+	if (console_session.ses_expired)
+		lstcon_session_end();
+
+	if (opc != LSTIO_SESSION_NEW &&
+	    console_session.ses_state == LST_SESSION_NONE) {
+		CDEBUG(D_NET, "LST no active session\n");
+		rc = -ESRCH;
+		goto out;
+	}
+
+	memset(&console_session.ses_trans_stat, 0, sizeof(lstcon_trans_stat_t));
+
+	switch (opc) {
+		case LSTIO_SESSION_NEW:
+			rc = lst_session_new_ioctl((lstio_session_new_args_t *)buf);
+			break;
+		case LSTIO_SESSION_END:
+			rc = lst_session_end_ioctl((lstio_session_end_args_t *)buf);
+			break;
+		case LSTIO_SESSION_INFO:
+			rc = lst_session_info_ioctl((lstio_session_info_args_t *)buf);
+			break;
+		case LSTIO_DEBUG:
+			rc = lst_debug_ioctl((lstio_debug_args_t *)buf);
+			break;
+		case LSTIO_GROUP_ADD:
+			rc = lst_group_add_ioctl((lstio_group_add_args_t *)buf);
+			break;
+		case LSTIO_GROUP_DEL:
+			rc = lst_group_del_ioctl((lstio_group_del_args_t *)buf);
+			break;
+		case LSTIO_GROUP_UPDATE:
+			rc = lst_group_update_ioctl((lstio_group_update_args_t *)buf);
+			break;
+		case LSTIO_NODES_ADD:
+			rc = lst_nodes_add_ioctl((lstio_group_nodes_args_t *)buf);
+			break;
+		case LSTIO_GROUP_LIST:
+			rc = lst_group_list_ioctl((lstio_group_list_args_t *)buf);
+			break;
+		case LSTIO_GROUP_INFO:
+			rc = lst_group_info_ioctl((lstio_group_info_args_t *)buf);
+			break;
+		case LSTIO_BATCH_ADD:
+			rc = lst_batch_add_ioctl((lstio_batch_add_args_t *)buf);
+			break;
+		case LSTIO_BATCH_START:
+			rc = lst_batch_run_ioctl((lstio_batch_run_args_t *)buf);
+			break;
+		case LSTIO_BATCH_STOP:
+			rc = lst_batch_stop_ioctl((lstio_batch_stop_args_t *)buf);
+			break;
+		case LSTIO_BATCH_QUERY:
+			rc = lst_batch_query_ioctl((lstio_batch_query_args_t *)buf);
+			break;
+		case LSTIO_BATCH_LIST:
+			rc = lst_batch_list_ioctl((lstio_batch_list_args_t *)buf);
+			break;
+		case LSTIO_BATCH_INFO:
+			rc = lst_batch_info_ioctl((lstio_batch_info_args_t *)buf);
+			break;
+		case LSTIO_TEST_ADD:
+			rc = lst_test_add_ioctl((lstio_test_args_t *)buf);
+			break;
+		case LSTIO_STAT_QUERY:
+			rc = lst_stat_query_ioctl((lstio_stat_args_t *)buf);
+			break;
+		default:
+			rc = -EINVAL;
+	}
+
+	if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
+			     sizeof(lstcon_trans_stat_t)))
+		rc = -EFAULT;
+out:
+	mutex_unlock(&console_session.ses_mutex);
+
+	LIBCFS_FREE(buf, data->ioc_plen1);
+
+	return rc;
+}
+
+EXPORT_SYMBOL(lstcon_ioctl_entry);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/conrpc.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/conrpc.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/conrpc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/conrpc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1397 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/conctl.c
+ *
+ * Console framework rpcs
+ *
+ * Author: Liang Zhen <liang@whamcloud.com>
+ */
+
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
+#include "timer.h"
+#include "conrpc.h"
+#include "console.h"
+
+void lstcon_rpc_stat_reply(lstcon_rpc_trans_t *, srpc_msg_t *,
+			   lstcon_node_t *, lstcon_trans_stat_t *);
+
+static void
+lstcon_rpc_done(srpc_client_rpc_t *rpc)
+{
+	lstcon_rpc_t *crpc = (lstcon_rpc_t *)rpc->crpc_priv;
+
+	LASSERT(crpc != NULL && rpc == crpc->crp_rpc);
+	LASSERT(crpc->crp_posted && !crpc->crp_finished);
+
+	spin_lock(&rpc->crpc_lock);
+
+	if (crpc->crp_trans == NULL) {
+		/* Orphan RPC is not in any transaction,
+		 * I'm just a poor body and nobody loves me */
+		spin_unlock(&rpc->crpc_lock);
+
+		/* release it */
+		lstcon_rpc_put(crpc);
+		return;
+	}
+
+	/* not an orphan RPC */
+	crpc->crp_finished = 1;
+
+	if (crpc->crp_stamp == 0) {
+		/* not aborted */
+		LASSERT (crpc->crp_status == 0);
+
+		crpc->crp_stamp  = cfs_time_current();
+		crpc->crp_status = rpc->crpc_status;
+	}
+
+	/* wakeup (transaction)thread if I'm the last RPC in the transaction */
+	if (atomic_dec_and_test(&crpc->crp_trans->tas_remaining))
+		wake_up(&crpc->crp_trans->tas_waitq);
+
+	spin_unlock(&rpc->crpc_lock);
+}
+
+int
+lstcon_rpc_init(lstcon_node_t *nd, int service, unsigned feats,
+		int bulk_npg, int bulk_len, int embedded, lstcon_rpc_t *crpc)
+{
+	crpc->crp_rpc = sfw_create_rpc(nd->nd_id, service,
+				       feats, bulk_npg, bulk_len,
+				       lstcon_rpc_done, (void *)crpc);
+	if (crpc->crp_rpc == NULL)
+		return -ENOMEM;
+
+	crpc->crp_trans    = NULL;
+	crpc->crp_node     = nd;
+	crpc->crp_posted   = 0;
+	crpc->crp_finished = 0;
+	crpc->crp_unpacked = 0;
+	crpc->crp_status   = 0;
+	crpc->crp_stamp    = 0;
+	crpc->crp_embedded = embedded;
+	INIT_LIST_HEAD(&crpc->crp_link);
+
+	atomic_inc(&console_session.ses_rpc_counter);
+
+	return 0;
+}
+
+int
+lstcon_rpc_prep(lstcon_node_t *nd, int service, unsigned feats,
+		int bulk_npg, int bulk_len, lstcon_rpc_t **crpcpp)
+{
+	lstcon_rpc_t  *crpc = NULL;
+	int	    rc;
+
+	spin_lock(&console_session.ses_rpc_lock);
+
+	if (!list_empty(&console_session.ses_rpc_freelist)) {
+		crpc = list_entry(console_session.ses_rpc_freelist.next,
+				      lstcon_rpc_t, crp_link);
+		list_del_init(&crpc->crp_link);
+	}
+
+	spin_unlock(&console_session.ses_rpc_lock);
+
+	if (crpc == NULL) {
+		LIBCFS_ALLOC(crpc, sizeof(*crpc));
+		if (crpc == NULL)
+			return -ENOMEM;
+	}
+
+	rc = lstcon_rpc_init(nd, service, feats, bulk_npg, bulk_len, 0, crpc);
+	if (rc == 0) {
+		*crpcpp = crpc;
+		return 0;
+	}
+
+	LIBCFS_FREE(crpc, sizeof(*crpc));
+
+	return rc;
+}
+
+void
+lstcon_rpc_put(lstcon_rpc_t *crpc)
+{
+	srpc_bulk_t *bulk = &crpc->crp_rpc->crpc_bulk;
+	int	  i;
+
+	LASSERT (list_empty(&crpc->crp_link));
+
+	for (i = 0; i < bulk->bk_niov; i++) {
+		if (bulk->bk_iovs[i].kiov_page == NULL)
+			continue;
+
+		__free_page(bulk->bk_iovs[i].kiov_page);
+	}
+
+	srpc_client_rpc_decref(crpc->crp_rpc);
+
+	if (crpc->crp_embedded) {
+		/* embedded RPC, don't recycle it */
+		memset(crpc, 0, sizeof(*crpc));
+		crpc->crp_embedded = 1;
+
+	} else {
+		spin_lock(&console_session.ses_rpc_lock);
+
+		list_add(&crpc->crp_link,
+			     &console_session.ses_rpc_freelist);
+
+		spin_unlock(&console_session.ses_rpc_lock);
+	}
+
+	/* RPC is not alive now */
+	atomic_dec(&console_session.ses_rpc_counter);
+}
+
+void
+lstcon_rpc_post(lstcon_rpc_t *crpc)
+{
+	lstcon_rpc_trans_t *trans = crpc->crp_trans;
+
+	LASSERT (trans != NULL);
+
+	atomic_inc(&trans->tas_remaining);
+	crpc->crp_posted = 1;
+
+	sfw_post_rpc(crpc->crp_rpc);
+}
+
+static char *
+lstcon_rpc_trans_name(int transop)
+{
+	if (transop == LST_TRANS_SESNEW)
+		return "SESNEW";
+
+	if (transop == LST_TRANS_SESEND)
+		return "SESEND";
+
+	if (transop == LST_TRANS_SESQRY)
+		return "SESQRY";
+
+	if (transop == LST_TRANS_SESPING)
+		return "SESPING";
+
+	if (transop == LST_TRANS_TSBCLIADD)
+		return "TSBCLIADD";
+
+	if (transop == LST_TRANS_TSBSRVADD)
+		return "TSBSRVADD";
+
+	if (transop == LST_TRANS_TSBRUN)
+		return "TSBRUN";
+
+	if (transop == LST_TRANS_TSBSTOP)
+		return "TSBSTOP";
+
+	if (transop == LST_TRANS_TSBCLIQRY)
+		return "TSBCLIQRY";
+
+	if (transop == LST_TRANS_TSBSRVQRY)
+		return "TSBSRVQRY";
+
+	if (transop == LST_TRANS_STATQRY)
+		return "STATQRY";
+
+	return "Unknown";
+}
+
+int
+lstcon_rpc_trans_prep(struct list_head *translist,
+		      int transop, lstcon_rpc_trans_t **transpp)
+{
+	lstcon_rpc_trans_t *trans;
+
+	if (translist != NULL) {
+		list_for_each_entry(trans, translist, tas_link) {
+			/* Can't enqueue two private transaction on
+			 * the same object */
+			if ((trans->tas_opc & transop) == LST_TRANS_PRIVATE)
+				return -EPERM;
+		}
+	}
+
+	/* create a trans group */
+	LIBCFS_ALLOC(trans, sizeof(*trans));
+	if (trans == NULL)
+		return -ENOMEM;
+
+	trans->tas_opc = transop;
+
+	if (translist == NULL)
+		INIT_LIST_HEAD(&trans->tas_olink);
+	else
+		list_add_tail(&trans->tas_olink, translist);
+
+	list_add_tail(&trans->tas_link, &console_session.ses_trans_list);
+
+	INIT_LIST_HEAD(&trans->tas_rpcs_list);
+	atomic_set(&trans->tas_remaining, 0);
+	init_waitqueue_head(&trans->tas_waitq);
+
+	spin_lock(&console_session.ses_rpc_lock);
+	trans->tas_features = console_session.ses_features;
+	spin_unlock(&console_session.ses_rpc_lock);
+
+	*transpp = trans;
+	return 0;
+}
+
+void
+lstcon_rpc_trans_addreq(lstcon_rpc_trans_t *trans, lstcon_rpc_t *crpc)
+{
+	list_add_tail(&crpc->crp_link, &trans->tas_rpcs_list);
+	crpc->crp_trans = trans;
+}
+
+void
+lstcon_rpc_trans_abort(lstcon_rpc_trans_t *trans, int error)
+{
+	srpc_client_rpc_t *rpc;
+	lstcon_rpc_t      *crpc;
+	lstcon_node_t     *nd;
+
+	list_for_each_entry (crpc, &trans->tas_rpcs_list, crp_link) {
+		rpc = crpc->crp_rpc;
+
+		spin_lock(&rpc->crpc_lock);
+
+		if (!crpc->crp_posted || /* not posted */
+		    crpc->crp_stamp != 0) { /* rpc done or aborted already */
+			if (crpc->crp_stamp == 0) {
+				crpc->crp_stamp = cfs_time_current();
+				crpc->crp_status = -EINTR;
+			}
+			spin_unlock(&rpc->crpc_lock);
+			continue;
+		}
+
+		crpc->crp_stamp  = cfs_time_current();
+		crpc->crp_status = error;
+
+		spin_unlock(&rpc->crpc_lock);
+
+		sfw_abort_rpc(rpc);
+
+		if  (error != ETIMEDOUT)
+			continue;
+
+		nd = crpc->crp_node;
+		if (cfs_time_after(nd->nd_stamp, crpc->crp_stamp))
+			continue;
+
+		nd->nd_stamp = crpc->crp_stamp;
+		nd->nd_state = LST_NODE_DOWN;
+	}
+}
+
+static int
+lstcon_rpc_trans_check(lstcon_rpc_trans_t *trans)
+{
+	if (console_session.ses_shutdown &&
+	    !list_empty(&trans->tas_olink)) /* Not an end session RPC */
+		return 1;
+
+	return (atomic_read(&trans->tas_remaining) == 0) ? 1: 0;
+}
+
+int
+lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout)
+{
+	lstcon_rpc_t  *crpc;
+	int	    rc;
+
+	if (list_empty(&trans->tas_rpcs_list))
+		return 0;
+
+	if (timeout < LST_TRANS_MIN_TIMEOUT)
+		timeout = LST_TRANS_MIN_TIMEOUT;
+
+	CDEBUG(D_NET, "Transaction %s started\n",
+	       lstcon_rpc_trans_name(trans->tas_opc));
+
+	/* post all requests */
+	list_for_each_entry (crpc, &trans->tas_rpcs_list, crp_link) {
+		LASSERT (!crpc->crp_posted);
+
+		lstcon_rpc_post(crpc);
+	}
+
+	mutex_unlock(&console_session.ses_mutex);
+
+	rc = wait_event_interruptible_timeout(trans->tas_waitq,
+					      lstcon_rpc_trans_check(trans),
+					      cfs_time_seconds(timeout));
+	rc = (rc > 0) ? 0 : ((rc < 0) ? -EINTR : -ETIMEDOUT);
+
+	mutex_lock(&console_session.ses_mutex);
+
+	if (console_session.ses_shutdown)
+		rc = -ESHUTDOWN;
+
+	if (rc != 0 || atomic_read(&trans->tas_remaining) != 0) {
+		/* treat short timeout as canceled */
+		if (rc == -ETIMEDOUT && timeout < LST_TRANS_MIN_TIMEOUT * 2)
+			rc = -EINTR;
+
+		lstcon_rpc_trans_abort(trans, rc);
+	}
+
+	CDEBUG(D_NET, "Transaction %s stopped: %d\n",
+	       lstcon_rpc_trans_name(trans->tas_opc), rc);
+
+	lstcon_rpc_trans_stat(trans, lstcon_trans_stat());
+
+	return rc;
+}
+
+int
+lstcon_rpc_get_reply(lstcon_rpc_t *crpc, srpc_msg_t **msgpp)
+{
+	lstcon_node_t	*nd  = crpc->crp_node;
+	srpc_client_rpc_t    *rpc = crpc->crp_rpc;
+	srpc_generic_reply_t *rep;
+
+	LASSERT (nd != NULL && rpc != NULL);
+	LASSERT (crpc->crp_stamp != 0);
+
+	if (crpc->crp_status != 0) {
+		*msgpp = NULL;
+		return crpc->crp_status;
+	}
+
+	*msgpp = &rpc->crpc_replymsg;
+	if (!crpc->crp_unpacked) {
+		sfw_unpack_message(*msgpp);
+		crpc->crp_unpacked = 1;
+	}
+
+	if (cfs_time_after(nd->nd_stamp, crpc->crp_stamp))
+		return 0;
+
+	nd->nd_stamp = crpc->crp_stamp;
+	rep = &(*msgpp)->msg_body.reply;
+
+	if (rep->sid.ses_nid == LNET_NID_ANY)
+		nd->nd_state = LST_NODE_UNKNOWN;
+	else if (lstcon_session_match(rep->sid))
+		nd->nd_state = LST_NODE_ACTIVE;
+	else
+		nd->nd_state = LST_NODE_BUSY;
+
+	return 0;
+}
+
+void
+lstcon_rpc_trans_stat(lstcon_rpc_trans_t *trans, lstcon_trans_stat_t *stat)
+{
+	lstcon_rpc_t      *crpc;
+	srpc_msg_t	*rep;
+	int		error;
+
+	LASSERT (stat != NULL);
+
+	memset(stat, 0, sizeof(*stat));
+
+	list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
+		lstcon_rpc_stat_total(stat, 1);
+
+		LASSERT (crpc->crp_stamp != 0);
+
+		error = lstcon_rpc_get_reply(crpc, &rep);
+		if (error != 0) {
+			lstcon_rpc_stat_failure(stat, 1);
+			if (stat->trs_rpc_errno == 0)
+				stat->trs_rpc_errno = -error;
+
+			continue;
+		}
+
+		lstcon_rpc_stat_success(stat, 1);
+
+		lstcon_rpc_stat_reply(trans, rep, crpc->crp_node, stat);
+	}
+
+	if (trans->tas_opc == LST_TRANS_SESNEW && stat->trs_fwk_errno == 0) {
+		stat->trs_fwk_errno =
+		      lstcon_session_feats_check(trans->tas_features);
+	}
+
+	CDEBUG(D_NET, "transaction %s : success %d, failure %d, total %d, "
+		      "RPC error(%d), Framework error(%d)\n",
+	       lstcon_rpc_trans_name(trans->tas_opc),
+	       lstcon_rpc_stat_success(stat, 0),
+	       lstcon_rpc_stat_failure(stat, 0),
+	       lstcon_rpc_stat_total(stat, 0),
+	       stat->trs_rpc_errno, stat->trs_fwk_errno);
+
+	return;
+}
+
+int
+lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
+			     struct list_head *head_up,
+			     lstcon_rpc_readent_func_t readent)
+{
+	struct list_head	    tmp;
+	struct list_head	   *next;
+	lstcon_rpc_ent_t     *ent;
+	srpc_generic_reply_t *rep;
+	lstcon_rpc_t	 *crpc;
+	srpc_msg_t	   *msg;
+	lstcon_node_t	*nd;
+	cfs_duration_t	dur;
+	struct timeval	tv;
+	int		   error;
+
+	LASSERT (head_up != NULL);
+
+	next = head_up;
+
+	list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
+		if (copy_from_user(&tmp, next,
+				       sizeof(struct list_head)))
+			return -EFAULT;
+
+		if (tmp.next == head_up)
+			return 0;
+
+		next = tmp.next;
+
+		ent = list_entry(next, lstcon_rpc_ent_t, rpe_link);
+
+		LASSERT (crpc->crp_stamp != 0);
+
+		error = lstcon_rpc_get_reply(crpc, &msg);
+
+		nd = crpc->crp_node;
+
+		dur = (cfs_duration_t)cfs_time_sub(crpc->crp_stamp,
+		      (cfs_time_t)console_session.ses_id.ses_stamp);
+		cfs_duration_usec(dur, &tv);
+
+		if (copy_to_user(&ent->rpe_peer,
+				     &nd->nd_id, sizeof(lnet_process_id_t)) ||
+		    copy_to_user(&ent->rpe_stamp, &tv, sizeof(tv)) ||
+		    copy_to_user(&ent->rpe_state,
+				     &nd->nd_state, sizeof(nd->nd_state)) ||
+		    copy_to_user(&ent->rpe_rpc_errno, &error,
+				     sizeof(error)))
+			return -EFAULT;
+
+		if (error != 0)
+			continue;
+
+		/* RPC is done */
+		rep = (srpc_generic_reply_t *)&msg->msg_body.reply;
+
+		if (copy_to_user(&ent->rpe_sid,
+				     &rep->sid, sizeof(lst_sid_t)) ||
+		    copy_to_user(&ent->rpe_fwk_errno,
+				     &rep->status, sizeof(rep->status)))
+			return -EFAULT;
+
+		if (readent == NULL)
+			continue;
+
+		if ((error = readent(trans->tas_opc, msg, ent)) != 0)
+			return error;
+	}
+
+	return 0;
+}
+
+void
+lstcon_rpc_trans_destroy(lstcon_rpc_trans_t *trans)
+{
+	srpc_client_rpc_t *rpc;
+	lstcon_rpc_t      *crpc;
+	lstcon_rpc_t      *tmp;
+	int		count = 0;
+
+	list_for_each_entry_safe(crpc, tmp, &trans->tas_rpcs_list,
+				 crp_link) {
+		rpc = crpc->crp_rpc;
+
+		spin_lock(&rpc->crpc_lock);
+
+		/* free it if not posted or finished already */
+		if (!crpc->crp_posted || crpc->crp_finished) {
+			spin_unlock(&rpc->crpc_lock);
+
+			list_del_init(&crpc->crp_link);
+			lstcon_rpc_put(crpc);
+
+			continue;
+		}
+
+		/* rpcs can be still not callbacked (even LNetMDUnlink is called)
+		 * because huge timeout for inaccessible network, don't make
+		 * user wait for them, just abandon them, they will be recycled
+		 * in callback */
+
+		LASSERT (crpc->crp_status != 0);
+
+		crpc->crp_node  = NULL;
+		crpc->crp_trans = NULL;
+		list_del_init(&crpc->crp_link);
+		count ++;
+
+		spin_unlock(&rpc->crpc_lock);
+
+		atomic_dec(&trans->tas_remaining);
+	}
+
+	LASSERT (atomic_read(&trans->tas_remaining) == 0);
+
+	list_del(&trans->tas_link);
+	if (!list_empty(&trans->tas_olink))
+		list_del(&trans->tas_olink);
+
+	CDEBUG(D_NET, "Transaction %s destroyed with %d pending RPCs\n",
+	       lstcon_rpc_trans_name(trans->tas_opc), count);
+
+	LIBCFS_FREE(trans, sizeof(*trans));
+
+	return;
+}
+
+int
+lstcon_sesrpc_prep(lstcon_node_t *nd, int transop,
+		   unsigned feats, lstcon_rpc_t **crpc)
+{
+	srpc_mksn_reqst_t *msrq;
+	srpc_rmsn_reqst_t *rsrq;
+	int		rc;
+
+	switch (transop) {
+	case LST_TRANS_SESNEW:
+		rc = lstcon_rpc_prep(nd, SRPC_SERVICE_MAKE_SESSION,
+				     feats, 0, 0, crpc);
+		if (rc != 0)
+			return rc;
+
+		msrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.mksn_reqst;
+		msrq->mksn_sid     = console_session.ses_id;
+		msrq->mksn_force   = console_session.ses_force;
+		strncpy(msrq->mksn_name, console_session.ses_name,
+			strlen(console_session.ses_name));
+		break;
+
+	case LST_TRANS_SESEND:
+		rc = lstcon_rpc_prep(nd, SRPC_SERVICE_REMOVE_SESSION,
+				     feats, 0, 0, crpc);
+		if (rc != 0)
+			return rc;
+
+		rsrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.rmsn_reqst;
+		rsrq->rmsn_sid = console_session.ses_id;
+		break;
+
+	default:
+		LBUG();
+	}
+
+	return 0;
+}
+
+int
+lstcon_dbgrpc_prep(lstcon_node_t *nd, unsigned feats, lstcon_rpc_t **crpc)
+{
+	srpc_debug_reqst_t *drq;
+	int		    rc;
+
+	rc = lstcon_rpc_prep(nd, SRPC_SERVICE_DEBUG, feats, 0, 0, crpc);
+	if (rc != 0)
+		return rc;
+
+	drq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.dbg_reqst;
+
+	drq->dbg_sid   = console_session.ses_id;
+	drq->dbg_flags = 0;
+
+	return rc;
+}
+
+int
+lstcon_batrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
+		   lstcon_tsb_hdr_t *tsb, lstcon_rpc_t **crpc)
+{
+	lstcon_batch_t	   *batch;
+	srpc_batch_reqst_t *brq;
+	int		    rc;
+
+	rc = lstcon_rpc_prep(nd, SRPC_SERVICE_BATCH, feats, 0, 0, crpc);
+	if (rc != 0)
+		return rc;
+
+	brq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.bat_reqst;
+
+	brq->bar_sid     = console_session.ses_id;
+	brq->bar_bid     = tsb->tsb_id;
+	brq->bar_testidx = tsb->tsb_index;
+	brq->bar_opc     = transop == LST_TRANS_TSBRUN ? SRPC_BATCH_OPC_RUN :
+			   (transop == LST_TRANS_TSBSTOP ? SRPC_BATCH_OPC_STOP:
+			    SRPC_BATCH_OPC_QUERY);
+
+	if (transop != LST_TRANS_TSBRUN &&
+	    transop != LST_TRANS_TSBSTOP)
+		return 0;
+
+	LASSERT (tsb->tsb_index == 0);
+
+	batch = (lstcon_batch_t *)tsb;
+	brq->bar_arg = batch->bat_arg;
+
+	return 0;
+}
+
+int
+lstcon_statrpc_prep(lstcon_node_t *nd, unsigned feats, lstcon_rpc_t **crpc)
+{
+	srpc_stat_reqst_t *srq;
+	int		   rc;
+
+	rc = lstcon_rpc_prep(nd, SRPC_SERVICE_QUERY_STAT, feats, 0, 0, crpc);
+	if (rc != 0)
+		return rc;
+
+	srq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.stat_reqst;
+
+	srq->str_sid  = console_session.ses_id;
+	srq->str_type = 0; /* XXX remove it */
+
+	return 0;
+}
+
+lnet_process_id_packed_t *
+lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov)
+{
+	lnet_process_id_packed_t *pid;
+	int		       i;
+
+	i = idx / SFW_ID_PER_PAGE;
+
+	LASSERT (i < nkiov);
+
+	pid = (lnet_process_id_packed_t *)page_address(kiov[i].kiov_page);
+
+	return &pid[idx % SFW_ID_PER_PAGE];
+}
+
+int
+lstcon_dstnodes_prep(lstcon_group_t *grp, int idx,
+		     int dist, int span, int nkiov, lnet_kiov_t *kiov)
+{
+	lnet_process_id_packed_t *pid;
+	lstcon_ndlink_t	  *ndl;
+	lstcon_node_t	    *nd;
+	int		       start;
+	int		       end;
+	int		       i = 0;
+
+	LASSERT (dist >= 1);
+	LASSERT (span >= 1);
+	LASSERT (grp->grp_nnode >= 1);
+
+	if (span > grp->grp_nnode)
+		return -EINVAL;
+
+	start = ((idx / dist) * span) % grp->grp_nnode;
+	end   = ((idx / dist) * span + span - 1) % grp->grp_nnode;
+
+	list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link) {
+		nd = ndl->ndl_node;
+		if (i < start) {
+			i ++;
+			continue;
+		}
+
+		if (i > (end >= start ? end: grp->grp_nnode))
+			break;
+
+		pid = lstcon_next_id((i - start), nkiov, kiov);
+		pid->nid = nd->nd_id.nid;
+		pid->pid = nd->nd_id.pid;
+		i++;
+	}
+
+	if (start <= end) /* done */
+		return 0;
+
+	list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link) {
+		if (i > grp->grp_nnode + end)
+			break;
+
+		nd = ndl->ndl_node;
+		pid = lstcon_next_id((i - start), nkiov, kiov);
+		pid->nid = nd->nd_id.nid;
+		pid->pid = nd->nd_id.pid;
+		i++;
+	}
+
+	return 0;
+}
+
+int
+lstcon_pingrpc_prep(lst_test_ping_param_t *param, srpc_test_reqst_t *req)
+{
+	test_ping_req_t *prq = &req->tsr_u.ping;
+
+	prq->png_size   = param->png_size;
+	prq->png_flags  = param->png_flags;
+	/* TODO dest */
+	return 0;
+}
+
+int
+lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req)
+{
+	test_bulk_req_t *brq = &req->tsr_u.bulk_v0;
+
+	brq->blk_opc    = param->blk_opc;
+	brq->blk_npg    = (param->blk_size + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE;
+	brq->blk_flags  = param->blk_flags;
+
+	return 0;
+}
+
+int
+lstcon_bulkrpc_v1_prep(lst_test_bulk_param_t *param, srpc_test_reqst_t *req)
+{
+	test_bulk_req_v1_t *brq = &req->tsr_u.bulk_v1;
+
+	brq->blk_opc	= param->blk_opc;
+	brq->blk_flags	= param->blk_flags;
+	brq->blk_len	= param->blk_size;
+	brq->blk_offset	= 0; /* reserved */
+
+	return 0;
+}
+
+int
+lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
+		    lstcon_test_t *test, lstcon_rpc_t **crpc)
+{
+	lstcon_group_t    *sgrp = test->tes_src_grp;
+	lstcon_group_t    *dgrp = test->tes_dst_grp;
+	srpc_test_reqst_t *trq;
+	srpc_bulk_t       *bulk;
+	int		i;
+	int		   npg = 0;
+	int		   nob = 0;
+	int		   rc  = 0;
+
+	if (transop == LST_TRANS_TSBCLIADD) {
+		npg = sfw_id_pages(test->tes_span);
+		nob = (feats & LST_FEAT_BULK_LEN) == 0 ?
+		      npg * PAGE_CACHE_SIZE :
+		      sizeof(lnet_process_id_packed_t) * test->tes_span;
+	}
+
+	rc = lstcon_rpc_prep(nd, SRPC_SERVICE_TEST, feats, npg, nob, crpc);
+	if (rc != 0)
+		return rc;
+
+	trq  = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.tes_reqst;
+
+	if (transop == LST_TRANS_TSBSRVADD) {
+		int ndist = (sgrp->grp_nnode + test->tes_dist - 1) / test->tes_dist;
+		int nspan = (dgrp->grp_nnode + test->tes_span - 1) / test->tes_span;
+		int nmax = (ndist + nspan - 1) / nspan;
+
+		trq->tsr_ndest = 0;
+		trq->tsr_loop  = nmax * test->tes_dist * test->tes_concur;
+
+	} else {
+		bulk = &(*crpc)->crp_rpc->crpc_bulk;
+
+		for (i = 0; i < npg; i++) {
+			int	len;
+
+			LASSERT(nob > 0);
+
+			len = (feats & LST_FEAT_BULK_LEN) == 0 ?
+			      PAGE_CACHE_SIZE : min_t(int, nob, PAGE_CACHE_SIZE);
+			nob -= len;
+
+			bulk->bk_iovs[i].kiov_offset = 0;
+			bulk->bk_iovs[i].kiov_len    = len;
+			bulk->bk_iovs[i].kiov_page   =
+				alloc_page(GFP_IOFS);
+
+			if (bulk->bk_iovs[i].kiov_page == NULL) {
+				lstcon_rpc_put(*crpc);
+				return -ENOMEM;
+			}
+		}
+
+		bulk->bk_sink = 0;
+
+		LASSERT (transop == LST_TRANS_TSBCLIADD);
+
+		rc = lstcon_dstnodes_prep(test->tes_dst_grp,
+					  test->tes_cliidx++,
+					  test->tes_dist,
+					  test->tes_span,
+					  npg, &bulk->bk_iovs[0]);
+		if (rc != 0) {
+			lstcon_rpc_put(*crpc);
+			return rc;
+		}
+
+		trq->tsr_ndest = test->tes_span;
+		trq->tsr_loop  = test->tes_loop;
+	}
+
+	trq->tsr_sid	= console_session.ses_id;
+	trq->tsr_bid	= test->tes_hdr.tsb_id;
+	trq->tsr_concur     = test->tes_concur;
+	trq->tsr_is_client  = (transop == LST_TRANS_TSBCLIADD) ? 1 : 0;
+	trq->tsr_stop_onerr = !!test->tes_stop_onerr;
+
+	switch (test->tes_type) {
+	case LST_TEST_PING:
+		trq->tsr_service = SRPC_SERVICE_PING;
+		rc = lstcon_pingrpc_prep((lst_test_ping_param_t *)
+					 &test->tes_param[0], trq);
+		break;
+
+	case LST_TEST_BULK:
+		trq->tsr_service = SRPC_SERVICE_BRW;
+		if ((feats & LST_FEAT_BULK_LEN) == 0) {
+			rc = lstcon_bulkrpc_v0_prep((lst_test_bulk_param_t *)
+						    &test->tes_param[0], trq);
+		} else {
+			rc = lstcon_bulkrpc_v1_prep((lst_test_bulk_param_t *)
+						    &test->tes_param[0], trq);
+		}
+
+		break;
+	default:
+		LBUG();
+		break;
+	}
+
+	return rc;
+}
+
+int
+lstcon_sesnew_stat_reply(lstcon_rpc_trans_t *trans,
+			 lstcon_node_t *nd, srpc_msg_t *reply)
+{
+	srpc_mksn_reply_t *mksn_rep = &reply->msg_body.mksn_reply;
+	int		   status   = mksn_rep->mksn_status;
+
+	if (status == 0 &&
+	    (reply->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
+		mksn_rep->mksn_status = EPROTO;
+		status = EPROTO;
+	}
+
+	if (status == EPROTO) {
+		CNETERR("session protocol error from %s: %u\n",
+			libcfs_nid2str(nd->nd_id.nid),
+			reply->msg_ses_feats);
+	}
+
+	if (status != 0)
+		return status;
+
+	if (!trans->tas_feats_updated) {
+		trans->tas_feats_updated = 1;
+		trans->tas_features = reply->msg_ses_feats;
+	}
+
+	if (reply->msg_ses_feats != trans->tas_features) {
+		CNETERR("Framework features %x from %s is different with "
+			"features on this transaction: %x\n",
+			 reply->msg_ses_feats, libcfs_nid2str(nd->nd_id.nid),
+			 trans->tas_features);
+		status = mksn_rep->mksn_status = EPROTO;
+	}
+
+	if (status == 0) {
+		/* session timeout on remote node */
+		nd->nd_timeout = mksn_rep->mksn_timeout;
+	}
+
+	return status;
+}
+
+void
+lstcon_rpc_stat_reply(lstcon_rpc_trans_t *trans, srpc_msg_t *msg,
+		      lstcon_node_t *nd, lstcon_trans_stat_t *stat)
+{
+	srpc_rmsn_reply_t  *rmsn_rep;
+	srpc_debug_reply_t *dbg_rep;
+	srpc_batch_reply_t *bat_rep;
+	srpc_test_reply_t  *test_rep;
+	srpc_stat_reply_t  *stat_rep;
+	int		 rc = 0;
+
+	switch (trans->tas_opc) {
+	case LST_TRANS_SESNEW:
+		rc = lstcon_sesnew_stat_reply(trans, nd, msg);
+		if (rc == 0) {
+			lstcon_sesop_stat_success(stat, 1);
+			return;
+		}
+
+		lstcon_sesop_stat_failure(stat, 1);
+		break;
+
+	case LST_TRANS_SESEND:
+		rmsn_rep = &msg->msg_body.rmsn_reply;
+		/* ESRCH is not an error for end session */
+		if (rmsn_rep->rmsn_status == 0 ||
+		    rmsn_rep->rmsn_status == ESRCH) {
+			lstcon_sesop_stat_success(stat, 1);
+			return;
+		}
+
+		lstcon_sesop_stat_failure(stat, 1);
+		rc = rmsn_rep->rmsn_status;
+		break;
+
+	case LST_TRANS_SESQRY:
+	case LST_TRANS_SESPING:
+		dbg_rep = &msg->msg_body.dbg_reply;
+
+		if (dbg_rep->dbg_status == ESRCH) {
+			lstcon_sesqry_stat_unknown(stat, 1);
+			return;
+		}
+
+		if (lstcon_session_match(dbg_rep->dbg_sid))
+			lstcon_sesqry_stat_active(stat, 1);
+		else
+			lstcon_sesqry_stat_busy(stat, 1);
+		return;
+
+	case LST_TRANS_TSBRUN:
+	case LST_TRANS_TSBSTOP:
+		bat_rep = &msg->msg_body.bat_reply;
+
+		if (bat_rep->bar_status == 0) {
+			lstcon_tsbop_stat_success(stat, 1);
+			return;
+		}
+
+		if (bat_rep->bar_status == EPERM &&
+		    trans->tas_opc == LST_TRANS_TSBSTOP) {
+			lstcon_tsbop_stat_success(stat, 1);
+			return;
+		}
+
+		lstcon_tsbop_stat_failure(stat, 1);
+		rc = bat_rep->bar_status;
+		break;
+
+	case LST_TRANS_TSBCLIQRY:
+	case LST_TRANS_TSBSRVQRY:
+		bat_rep = &msg->msg_body.bat_reply;
+
+		if (bat_rep->bar_active != 0)
+			lstcon_tsbqry_stat_run(stat, 1);
+		else
+			lstcon_tsbqry_stat_idle(stat, 1);
+
+		if (bat_rep->bar_status == 0)
+			return;
+
+		lstcon_tsbqry_stat_failure(stat, 1);
+		rc = bat_rep->bar_status;
+		break;
+
+	case LST_TRANS_TSBCLIADD:
+	case LST_TRANS_TSBSRVADD:
+		test_rep = &msg->msg_body.tes_reply;
+
+		if (test_rep->tsr_status == 0) {
+			lstcon_tsbop_stat_success(stat, 1);
+			return;
+		}
+
+		lstcon_tsbop_stat_failure(stat, 1);
+		rc = test_rep->tsr_status;
+		break;
+
+	case LST_TRANS_STATQRY:
+		stat_rep = &msg->msg_body.stat_reply;
+
+		if (stat_rep->str_status == 0) {
+			lstcon_statqry_stat_success(stat, 1);
+			return;
+		}
+
+		lstcon_statqry_stat_failure(stat, 1);
+		rc = stat_rep->str_status;
+		break;
+
+	default:
+		LBUG();
+	}
+
+	if (stat->trs_fwk_errno == 0)
+		stat->trs_fwk_errno = rc;
+
+	return;
+}
+
+int
+lstcon_rpc_trans_ndlist(struct list_head *ndlist,
+			struct list_head *translist, int transop,
+			void *arg, lstcon_rpc_cond_func_t condition,
+			lstcon_rpc_trans_t **transpp)
+{
+	lstcon_rpc_trans_t *trans;
+	lstcon_ndlink_t    *ndl;
+	lstcon_node_t      *nd;
+	lstcon_rpc_t       *rpc;
+	unsigned	    feats;
+	int		 rc;
+
+	/* Creating session RPG for list of nodes */
+
+	rc = lstcon_rpc_trans_prep(translist, transop, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction %d: %d\n", transop, rc);
+		return rc;
+	}
+
+	feats = trans->tas_features;
+	list_for_each_entry(ndl, ndlist, ndl_link) {
+		rc = condition == NULL ? 1 :
+		     condition(transop, ndl->ndl_node, arg);
+
+		if (rc == 0)
+			continue;
+
+		if (rc < 0) {
+			CDEBUG(D_NET, "Condition error while creating RPC "
+				      " for transaction %d: %d\n", transop, rc);
+			break;
+		}
+
+		nd = ndl->ndl_node;
+
+		switch (transop) {
+		case LST_TRANS_SESNEW:
+		case LST_TRANS_SESEND:
+			rc = lstcon_sesrpc_prep(nd, transop, feats, &rpc);
+			break;
+		case LST_TRANS_SESQRY:
+		case LST_TRANS_SESPING:
+			rc = lstcon_dbgrpc_prep(nd, feats, &rpc);
+			break;
+		case LST_TRANS_TSBCLIADD:
+		case LST_TRANS_TSBSRVADD:
+			rc = lstcon_testrpc_prep(nd, transop, feats,
+						 (lstcon_test_t *)arg, &rpc);
+			break;
+		case LST_TRANS_TSBRUN:
+		case LST_TRANS_TSBSTOP:
+		case LST_TRANS_TSBCLIQRY:
+		case LST_TRANS_TSBSRVQRY:
+			rc = lstcon_batrpc_prep(nd, transop, feats,
+						(lstcon_tsb_hdr_t *)arg, &rpc);
+			break;
+		case LST_TRANS_STATQRY:
+			rc = lstcon_statrpc_prep(nd, feats, &rpc);
+			break;
+		default:
+			rc = -EINVAL;
+			break;
+		}
+
+		if (rc != 0) {
+			CERROR("Failed to create RPC for transaction %s: %d\n",
+			       lstcon_rpc_trans_name(transop), rc);
+			break;
+		}
+
+		lstcon_rpc_trans_addreq(trans, rpc);
+	}
+
+	if (rc == 0) {
+		*transpp = trans;
+		return 0;
+	}
+
+	lstcon_rpc_trans_destroy(trans);
+
+	return rc;
+}
+
+void
+lstcon_rpc_pinger(void *arg)
+{
+	stt_timer_t	*ptimer = (stt_timer_t *)arg;
+	lstcon_rpc_trans_t *trans;
+	lstcon_rpc_t       *crpc;
+	srpc_msg_t	 *rep;
+	srpc_debug_reqst_t *drq;
+	lstcon_ndlink_t    *ndl;
+	lstcon_node_t      *nd;
+	time_t	      intv;
+	int		 count = 0;
+	int		 rc;
+
+	/* RPC pinger is a special case of transaction,
+	 * it's called by timer at 8 seconds interval.
+	 */
+	mutex_lock(&console_session.ses_mutex);
+
+	if (console_session.ses_shutdown || console_session.ses_expired) {
+		mutex_unlock(&console_session.ses_mutex);
+		return;
+	}
+
+	if (!console_session.ses_expired &&
+	    cfs_time_current_sec() - console_session.ses_laststamp >
+	    (time_t)console_session.ses_timeout)
+		console_session.ses_expired = 1;
+
+	trans = console_session.ses_ping;
+
+	LASSERT (trans != NULL);
+
+	list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link) {
+		nd = ndl->ndl_node;
+
+		if (console_session.ses_expired) {
+			/* idle console, end session on all nodes */
+			if (nd->nd_state != LST_NODE_ACTIVE)
+				continue;
+
+			rc = lstcon_sesrpc_prep(nd, LST_TRANS_SESEND,
+						trans->tas_features, &crpc);
+			if (rc != 0) {
+				CERROR("Out of memory\n");
+				break;
+			}
+
+			lstcon_rpc_trans_addreq(trans, crpc);
+			lstcon_rpc_post(crpc);
+
+			continue;
+		}
+
+		crpc = &nd->nd_ping;
+
+		if (crpc->crp_rpc != NULL) {
+			LASSERT (crpc->crp_trans == trans);
+			LASSERT (!list_empty(&crpc->crp_link));
+
+			spin_lock(&crpc->crp_rpc->crpc_lock);
+
+			LASSERT(crpc->crp_posted);
+
+			if (!crpc->crp_finished) {
+				/* in flight */
+				spin_unlock(&crpc->crp_rpc->crpc_lock);
+				continue;
+			}
+
+			spin_unlock(&crpc->crp_rpc->crpc_lock);
+
+			lstcon_rpc_get_reply(crpc, &rep);
+
+			list_del_init(&crpc->crp_link);
+
+			lstcon_rpc_put(crpc);
+		}
+
+		if (nd->nd_state != LST_NODE_ACTIVE)
+			continue;
+
+		intv = cfs_duration_sec(cfs_time_sub(cfs_time_current(),
+						     nd->nd_stamp));
+		if (intv < (time_t)nd->nd_timeout / 2)
+			continue;
+
+		rc = lstcon_rpc_init(nd, SRPC_SERVICE_DEBUG,
+				     trans->tas_features, 0, 0, 1, crpc);
+		if (rc != 0) {
+			CERROR("Out of memory\n");
+			break;
+		}
+
+		drq = &crpc->crp_rpc->crpc_reqstmsg.msg_body.dbg_reqst;
+
+		drq->dbg_sid   = console_session.ses_id;
+		drq->dbg_flags = 0;
+
+		lstcon_rpc_trans_addreq(trans, crpc);
+		lstcon_rpc_post(crpc);
+
+		count ++;
+	}
+
+	if (console_session.ses_expired) {
+		mutex_unlock(&console_session.ses_mutex);
+		return;
+	}
+
+	CDEBUG(D_NET, "Ping %d nodes in session\n", count);
+
+	ptimer->stt_expires = (cfs_time_t)(cfs_time_current_sec() + LST_PING_INTERVAL);
+	stt_add_timer(ptimer);
+
+	mutex_unlock(&console_session.ses_mutex);
+}
+
+int
+lstcon_rpc_pinger_start(void)
+{
+	stt_timer_t    *ptimer;
+	int	     rc;
+
+	LASSERT (list_empty(&console_session.ses_rpc_freelist));
+	LASSERT (atomic_read(&console_session.ses_rpc_counter) == 0);
+
+	rc = lstcon_rpc_trans_prep(NULL, LST_TRANS_SESPING,
+				   &console_session.ses_ping);
+	if (rc != 0) {
+		CERROR("Failed to create console pinger\n");
+		return rc;
+	}
+
+	ptimer = &console_session.ses_ping_timer;
+	ptimer->stt_expires = (cfs_time_t)(cfs_time_current_sec() + LST_PING_INTERVAL);
+
+	stt_add_timer(ptimer);
+
+	return 0;
+}
+
+void
+lstcon_rpc_pinger_stop(void)
+{
+	LASSERT (console_session.ses_shutdown);
+
+	stt_del_timer(&console_session.ses_ping_timer);
+
+	lstcon_rpc_trans_abort(console_session.ses_ping, -ESHUTDOWN);
+	lstcon_rpc_trans_stat(console_session.ses_ping, lstcon_trans_stat());
+	lstcon_rpc_trans_destroy(console_session.ses_ping);
+
+	memset(lstcon_trans_stat(), 0, sizeof(lstcon_trans_stat_t));
+
+	console_session.ses_ping = NULL;
+}
+
+void
+lstcon_rpc_cleanup_wait(void)
+{
+	lstcon_rpc_trans_t *trans;
+	lstcon_rpc_t       *crpc;
+	struct list_head	 *pacer;
+	struct list_head	  zlist;
+
+	/* Called with hold of global mutex */
+
+	LASSERT (console_session.ses_shutdown);
+
+	while (!list_empty(&console_session.ses_trans_list)) {
+		list_for_each(pacer, &console_session.ses_trans_list) {
+			trans = list_entry(pacer, lstcon_rpc_trans_t,
+					       tas_link);
+
+			CDEBUG(D_NET, "Session closed, wakeup transaction %s\n",
+			       lstcon_rpc_trans_name(trans->tas_opc));
+
+			wake_up(&trans->tas_waitq);
+		}
+
+		mutex_unlock(&console_session.ses_mutex);
+
+		CWARN("Session is shutting down, "
+		      "waiting for termination of transactions\n");
+		cfs_pause(cfs_time_seconds(1));
+
+		mutex_lock(&console_session.ses_mutex);
+	}
+
+	spin_lock(&console_session.ses_rpc_lock);
+
+	lst_wait_until((atomic_read(&console_session.ses_rpc_counter) == 0),
+		       console_session.ses_rpc_lock,
+		       "Network is not accessable or target is down, "
+		       "waiting for %d console RPCs to being recycled\n",
+		       atomic_read(&console_session.ses_rpc_counter));
+
+	list_add(&zlist, &console_session.ses_rpc_freelist);
+	list_del_init(&console_session.ses_rpc_freelist);
+
+	spin_unlock(&console_session.ses_rpc_lock);
+
+	while (!list_empty(&zlist)) {
+		crpc = list_entry(zlist.next, lstcon_rpc_t, crp_link);
+
+		list_del(&crpc->crp_link);
+		LIBCFS_FREE(crpc, sizeof(lstcon_rpc_t));
+	}
+}
+
+int
+lstcon_rpc_module_init(void)
+{
+	INIT_LIST_HEAD(&console_session.ses_ping_timer.stt_list);
+	console_session.ses_ping_timer.stt_func = lstcon_rpc_pinger;
+	console_session.ses_ping_timer.stt_data = &console_session.ses_ping_timer;
+
+	console_session.ses_ping = NULL;
+
+	spin_lock_init(&console_session.ses_rpc_lock);
+	atomic_set(&console_session.ses_rpc_counter, 0);
+	INIT_LIST_HEAD(&console_session.ses_rpc_freelist);
+
+	return 0;
+}
+
+void
+lstcon_rpc_module_fini(void)
+{
+	LASSERT (list_empty(&console_session.ses_rpc_freelist));
+	LASSERT (atomic_read(&console_session.ses_rpc_counter) == 0);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/conrpc.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/conrpc.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/conrpc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/conrpc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,146 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * /lnet/selftest/conrpc.h
+ *
+ * Console rpc
+ *
+ * Author: Liang Zhen <liang@whamcloud.com>
+ */
+
+#ifndef __LST_CONRPC_H__
+#define __LST_CONRPC_H__
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lnet.h>
+#include <linux/lnet/lib-types.h>
+#include <linux/lnet/lnetst.h>
+#include "rpc.h"
+#include "selftest.h"
+
+/* Console rpc and rpc transaction */
+#define LST_TRANS_TIMEOUT       30
+#define LST_TRANS_MIN_TIMEOUT   3
+
+#define LST_VALIDATE_TIMEOUT(t) MIN(MAX(t, LST_TRANS_MIN_TIMEOUT), LST_TRANS_TIMEOUT)
+
+#define LST_PING_INTERVAL       8
+
+struct lstcon_rpc_trans;
+struct lstcon_tsb_hdr;
+struct lstcon_test;
+struct lstcon_node;
+
+typedef struct lstcon_rpc {
+	struct list_head	       crp_link;       /* chain on rpc transaction */
+	srpc_client_rpc_t       *crp_rpc;	/* client rpc */
+	struct lstcon_node      *crp_node;       /* destination node */
+	struct lstcon_rpc_trans *crp_trans;     /* conrpc transaction */
+
+	unsigned int		 crp_posted:1;   /* rpc is posted */
+	unsigned int		 crp_finished:1; /* rpc is finished */
+	unsigned int		 crp_unpacked:1; /* reply is unpacked */
+	/** RPC is embedded in other structure and can't free it */
+	unsigned int		 crp_embedded:1;
+	int		      crp_status;     /* console rpc errors */
+	cfs_time_t	       crp_stamp;      /* replied time stamp */
+} lstcon_rpc_t;
+
+typedef struct lstcon_rpc_trans {
+	struct list_head	    tas_olink;     /* link chain on owner list */
+	struct list_head	    tas_link;      /* link chain on global list */
+	int		   tas_opc;       /* operation code of transaction */
+	/* features mask is uptodate */
+	unsigned	      tas_feats_updated;
+	/* test features mask */
+	unsigned	      tas_features;
+	wait_queue_head_t	   tas_waitq;     /* wait queue head */
+	atomic_t	  tas_remaining; /* # of un-scheduled rpcs */
+	struct list_head	    tas_rpcs_list; /* queued requests */
+} lstcon_rpc_trans_t;
+
+#define LST_TRANS_PRIVATE       0x1000
+
+#define LST_TRANS_SESNEW	(LST_TRANS_PRIVATE | 0x01)
+#define LST_TRANS_SESEND	(LST_TRANS_PRIVATE | 0x02)
+#define LST_TRANS_SESQRY	0x03
+#define LST_TRANS_SESPING       0x04
+
+#define LST_TRANS_TSBCLIADD     (LST_TRANS_PRIVATE | 0x11)
+#define LST_TRANS_TSBSRVADD     (LST_TRANS_PRIVATE | 0x12)
+#define LST_TRANS_TSBRUN	(LST_TRANS_PRIVATE | 0x13)
+#define LST_TRANS_TSBSTOP       (LST_TRANS_PRIVATE | 0x14)
+#define LST_TRANS_TSBCLIQRY     0x15
+#define LST_TRANS_TSBSRVQRY     0x16
+
+#define LST_TRANS_STATQRY       0x21
+
+typedef int (* lstcon_rpc_cond_func_t)(int, struct lstcon_node *, void *);
+typedef int (* lstcon_rpc_readent_func_t)(int, srpc_msg_t *, lstcon_rpc_ent_t *);
+
+int  lstcon_sesrpc_prep(struct lstcon_node *nd, int transop,
+			unsigned version, lstcon_rpc_t **crpc);
+int  lstcon_dbgrpc_prep(struct lstcon_node *nd,
+			unsigned version, lstcon_rpc_t **crpc);
+int  lstcon_batrpc_prep(struct lstcon_node *nd, int transop, unsigned version,
+			struct lstcon_tsb_hdr *tsb, lstcon_rpc_t **crpc);
+int  lstcon_testrpc_prep(struct lstcon_node *nd, int transop, unsigned version,
+			 struct lstcon_test *test, lstcon_rpc_t **crpc);
+int  lstcon_statrpc_prep(struct lstcon_node *nd, unsigned version,
+			 lstcon_rpc_t **crpc);
+void lstcon_rpc_put(lstcon_rpc_t *crpc);
+int  lstcon_rpc_trans_prep(struct list_head *translist,
+			   int transop, lstcon_rpc_trans_t **transpp);
+int  lstcon_rpc_trans_ndlist(struct list_head *ndlist,
+			     struct list_head *translist, int transop,
+			     void *arg, lstcon_rpc_cond_func_t condition,
+			     lstcon_rpc_trans_t **transpp);
+void lstcon_rpc_trans_stat(lstcon_rpc_trans_t *trans,
+			   lstcon_trans_stat_t *stat);
+int  lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
+				  struct list_head *head_up,
+				  lstcon_rpc_readent_func_t readent);
+void lstcon_rpc_trans_abort(lstcon_rpc_trans_t *trans, int error);
+void lstcon_rpc_trans_destroy(lstcon_rpc_trans_t *trans);
+void lstcon_rpc_trans_addreq(lstcon_rpc_trans_t *trans, lstcon_rpc_t *req);
+int  lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout);
+int  lstcon_rpc_pinger_start(void);
+void lstcon_rpc_pinger_stop(void);
+void lstcon_rpc_cleanup_wait(void);
+int  lstcon_rpc_module_init(void);
+void lstcon_rpc_module_fini(void);
+
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/console.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/console.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/console.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/console.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2071 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/conctl.c
+ *
+ * Infrastructure of LST console
+ *
+ * Author: Liang Zhen <liangzhen@clusterfs.com>
+ */
+
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lib-lnet.h>
+#include "console.h"
+#include "conrpc.h"
+
+#define LST_NODE_STATE_COUNTER(nd, p)		   \
+do {						    \
+	if ((nd)->nd_state == LST_NODE_ACTIVE)	  \
+		(p)->nle_nactive ++;		    \
+	else if ((nd)->nd_state == LST_NODE_BUSY)       \
+		(p)->nle_nbusy ++;		      \
+	else if ((nd)->nd_state == LST_NODE_DOWN)       \
+		(p)->nle_ndown ++;		      \
+	else					    \
+		(p)->nle_nunknown ++;		   \
+	(p)->nle_nnode ++;			      \
+} while (0)
+
+lstcon_session_t	console_session;
+
+void
+lstcon_node_get(lstcon_node_t *nd)
+{
+	LASSERT (nd->nd_ref >= 1);
+
+	nd->nd_ref++;
+}
+
+static int
+lstcon_node_find(lnet_process_id_t id, lstcon_node_t **ndpp, int create)
+{
+	lstcon_ndlink_t *ndl;
+	unsigned int     idx = LNET_NIDADDR(id.nid) % LST_GLOBAL_HASHSIZE;
+
+	LASSERT (id.nid != LNET_NID_ANY);
+
+	list_for_each_entry(ndl, &console_session.ses_ndl_hash[idx], ndl_hlink) {
+		if (ndl->ndl_node->nd_id.nid != id.nid ||
+		    ndl->ndl_node->nd_id.pid != id.pid)
+			continue;
+
+		lstcon_node_get(ndl->ndl_node);
+		*ndpp = ndl->ndl_node;
+		return 0;
+	}
+
+	if (!create)
+		return -ENOENT;
+
+	LIBCFS_ALLOC(*ndpp, sizeof(lstcon_node_t) + sizeof(lstcon_ndlink_t));
+	if (*ndpp == NULL)
+		return -ENOMEM;
+
+	ndl = (lstcon_ndlink_t *)(*ndpp + 1);
+
+	ndl->ndl_node = *ndpp;
+
+	ndl->ndl_node->nd_ref   = 1;
+	ndl->ndl_node->nd_id    = id;
+	ndl->ndl_node->nd_stamp = cfs_time_current();
+	ndl->ndl_node->nd_state = LST_NODE_UNKNOWN;
+	ndl->ndl_node->nd_timeout = 0;
+	memset(&ndl->ndl_node->nd_ping, 0, sizeof(lstcon_rpc_t));
+
+	/* queued in global hash & list, no refcount is taken by
+	 * global hash & list, if caller release his refcount,
+	 * node will be released */
+	list_add_tail(&ndl->ndl_hlink, &console_session.ses_ndl_hash[idx]);
+	list_add_tail(&ndl->ndl_link, &console_session.ses_ndl_list);
+
+	return 0;
+}
+
+void
+lstcon_node_put(lstcon_node_t *nd)
+{
+	lstcon_ndlink_t  *ndl;
+
+	LASSERT (nd->nd_ref > 0);
+
+	if (--nd->nd_ref > 0)
+		return;
+
+	ndl = (lstcon_ndlink_t *)(nd + 1);
+
+	LASSERT (!list_empty(&ndl->ndl_link));
+	LASSERT (!list_empty(&ndl->ndl_hlink));
+
+	/* remove from session */
+	list_del(&ndl->ndl_link);
+	list_del(&ndl->ndl_hlink);
+
+	LIBCFS_FREE(nd, sizeof(lstcon_node_t) + sizeof(lstcon_ndlink_t));
+}
+
+static int
+lstcon_ndlink_find(struct list_head *hash,
+		   lnet_process_id_t id, lstcon_ndlink_t **ndlpp, int create)
+{
+	unsigned int     idx = LNET_NIDADDR(id.nid) % LST_NODE_HASHSIZE;
+	lstcon_ndlink_t *ndl;
+	lstcon_node_t   *nd;
+	int	      rc;
+
+	if (id.nid == LNET_NID_ANY)
+		return -EINVAL;
+
+	/* search in hash */
+	list_for_each_entry(ndl, &hash[idx], ndl_hlink) {
+		if (ndl->ndl_node->nd_id.nid != id.nid ||
+		    ndl->ndl_node->nd_id.pid != id.pid)
+			continue;
+
+		*ndlpp = ndl;
+		return 0;
+	}
+
+	if (create == 0)
+		return -ENOENT;
+
+	/* find or create in session hash */
+	rc = lstcon_node_find(id, &nd, (create == 1) ? 1 : 0);
+	if (rc != 0)
+		return rc;
+
+	LIBCFS_ALLOC(ndl, sizeof(lstcon_ndlink_t));
+	if (ndl == NULL) {
+		lstcon_node_put(nd);
+		return -ENOMEM;
+	}
+
+	*ndlpp = ndl;
+
+	ndl->ndl_node = nd;
+	INIT_LIST_HEAD(&ndl->ndl_link);
+	list_add_tail(&ndl->ndl_hlink, &hash[idx]);
+
+	return  0;
+}
+
+static void
+lstcon_ndlink_release(lstcon_ndlink_t *ndl)
+{
+	LASSERT (list_empty(&ndl->ndl_link));
+	LASSERT (!list_empty(&ndl->ndl_hlink));
+
+	list_del(&ndl->ndl_hlink); /* delete from hash */
+	lstcon_node_put(ndl->ndl_node);
+
+	LIBCFS_FREE(ndl, sizeof(*ndl));
+}
+
+static int
+lstcon_group_alloc(char *name, lstcon_group_t **grpp)
+{
+	lstcon_group_t *grp;
+	int	     i;
+
+	LIBCFS_ALLOC(grp, offsetof(lstcon_group_t,
+				   grp_ndl_hash[LST_NODE_HASHSIZE]));
+	if (grp == NULL)
+		return -ENOMEM;
+
+	memset(grp, 0, offsetof(lstcon_group_t,
+				grp_ndl_hash[LST_NODE_HASHSIZE]));
+
+	grp->grp_ref = 1;
+	if (name != NULL)
+		strcpy(grp->grp_name, name);
+
+	INIT_LIST_HEAD(&grp->grp_link);
+	INIT_LIST_HEAD(&grp->grp_ndl_list);
+	INIT_LIST_HEAD(&grp->grp_trans_list);
+
+	for (i = 0; i < LST_NODE_HASHSIZE; i++)
+		INIT_LIST_HEAD(&grp->grp_ndl_hash[i]);
+
+	*grpp = grp;
+
+	return 0;
+}
+
+static void
+lstcon_group_addref(lstcon_group_t *grp)
+{
+	grp->grp_ref ++;
+}
+
+static void lstcon_group_ndlink_release(lstcon_group_t *, lstcon_ndlink_t *);
+
+static void
+lstcon_group_drain(lstcon_group_t *grp, int keep)
+{
+	lstcon_ndlink_t *ndl;
+	lstcon_ndlink_t *tmp;
+
+	list_for_each_entry_safe(ndl, tmp, &grp->grp_ndl_list, ndl_link) {
+		if ((ndl->ndl_node->nd_state & keep) == 0)
+			lstcon_group_ndlink_release(grp, ndl);
+	}
+}
+
+static void
+lstcon_group_decref(lstcon_group_t *grp)
+{
+	int     i;
+
+	if (--grp->grp_ref > 0)
+		return;
+
+	if (!list_empty(&grp->grp_link))
+		list_del(&grp->grp_link);
+
+	lstcon_group_drain(grp, 0);
+
+	for (i = 0; i < LST_NODE_HASHSIZE; i++) {
+		LASSERT (list_empty(&grp->grp_ndl_hash[i]));
+	}
+
+	LIBCFS_FREE(grp, offsetof(lstcon_group_t,
+				  grp_ndl_hash[LST_NODE_HASHSIZE]));
+}
+
+static int
+lstcon_group_find(char *name, lstcon_group_t **grpp)
+{
+	lstcon_group_t   *grp;
+
+	list_for_each_entry(grp, &console_session.ses_grp_list, grp_link) {
+		if (strncmp(grp->grp_name, name, LST_NAME_SIZE) != 0)
+			continue;
+
+		lstcon_group_addref(grp);  /* +1 ref for caller */
+		*grpp = grp;
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+static void
+lstcon_group_put(lstcon_group_t *grp)
+{
+	lstcon_group_decref(grp);
+}
+
+static int
+lstcon_group_ndlink_find(lstcon_group_t *grp, lnet_process_id_t id,
+			 lstcon_ndlink_t **ndlpp, int create)
+{
+	int     rc;
+
+	rc = lstcon_ndlink_find(&grp->grp_ndl_hash[0], id, ndlpp, create);
+	if (rc != 0)
+		return rc;
+
+	if (!list_empty(&(*ndlpp)->ndl_link))
+		return 0;
+
+	list_add_tail(&(*ndlpp)->ndl_link, &grp->grp_ndl_list);
+	grp->grp_nnode ++;
+
+	return 0;
+}
+
+static void
+lstcon_group_ndlink_release(lstcon_group_t *grp, lstcon_ndlink_t *ndl)
+{
+	list_del_init(&ndl->ndl_link);
+	lstcon_ndlink_release(ndl);
+	grp->grp_nnode --;
+}
+
+static void
+lstcon_group_ndlink_move(lstcon_group_t *old,
+			 lstcon_group_t *new, lstcon_ndlink_t *ndl)
+{
+	unsigned int idx = LNET_NIDADDR(ndl->ndl_node->nd_id.nid) %
+			   LST_NODE_HASHSIZE;
+
+	list_del(&ndl->ndl_hlink);
+	list_del(&ndl->ndl_link);
+	old->grp_nnode --;
+
+	list_add_tail(&ndl->ndl_hlink, &new->grp_ndl_hash[idx]);
+	list_add_tail(&ndl->ndl_link, &new->grp_ndl_list);
+	new->grp_nnode ++;
+
+	return;
+}
+
+static void
+lstcon_group_move(lstcon_group_t *old, lstcon_group_t *new)
+{
+	lstcon_ndlink_t *ndl;
+
+	while (!list_empty(&old->grp_ndl_list)) {
+		ndl = list_entry(old->grp_ndl_list.next,
+				     lstcon_ndlink_t, ndl_link);
+		lstcon_group_ndlink_move(old, new, ndl);
+	}
+}
+
+int
+lstcon_sesrpc_condition(int transop, lstcon_node_t *nd, void *arg)
+{
+	lstcon_group_t *grp = (lstcon_group_t *)arg;
+
+	switch (transop) {
+	case LST_TRANS_SESNEW:
+		if (nd->nd_state == LST_NODE_ACTIVE)
+			return 0;
+		break;
+
+	case LST_TRANS_SESEND:
+		if (nd->nd_state != LST_NODE_ACTIVE)
+			return 0;
+
+		if (grp != NULL && nd->nd_ref > 1)
+			return 0;
+		break;
+
+	case LST_TRANS_SESQRY:
+		break;
+
+	default:
+		LBUG();
+	}
+
+	return 1;
+}
+
+int
+lstcon_sesrpc_readent(int transop, srpc_msg_t *msg,
+		      lstcon_rpc_ent_t *ent_up)
+{
+	srpc_debug_reply_t *rep;
+
+	switch (transop) {
+	case LST_TRANS_SESNEW:
+	case LST_TRANS_SESEND:
+		return 0;
+
+	case LST_TRANS_SESQRY:
+		rep = &msg->msg_body.dbg_reply;
+
+		if (copy_to_user(&ent_up->rpe_priv[0],
+				     &rep->dbg_timeout, sizeof(int)) ||
+		    copy_to_user(&ent_up->rpe_payload[0],
+				     &rep->dbg_name, LST_NAME_SIZE))
+			return -EFAULT;
+
+		return 0;
+
+	default:
+		LBUG();
+	}
+
+	return 0;
+}
+
+static int
+lstcon_group_nodes_add(lstcon_group_t *grp,
+		       int count, lnet_process_id_t *ids_up,
+		       unsigned *featp, struct list_head *result_up)
+{
+	lstcon_rpc_trans_t      *trans;
+	lstcon_ndlink_t	 *ndl;
+	lstcon_group_t	  *tmp;
+	lnet_process_id_t	id;
+	int		      i;
+	int		      rc;
+
+	rc = lstcon_group_alloc(NULL, &tmp);
+	if (rc != 0) {
+		CERROR("Out of memory\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0 ; i < count; i++) {
+		if (copy_from_user(&id, &ids_up[i], sizeof(id))) {
+			rc = -EFAULT;
+			break;
+		}
+
+		/* skip if it's in this group already */
+		rc = lstcon_group_ndlink_find(grp, id, &ndl, 0);
+		if (rc == 0)
+			continue;
+
+		/* add to tmp group */
+		rc = lstcon_group_ndlink_find(tmp, id, &ndl, 1);
+		if (rc != 0) {
+			CERROR("Can't create ndlink, out of memory\n");
+			break;
+		}
+	}
+
+	if (rc != 0) {
+		lstcon_group_put(tmp);
+		return rc;
+	}
+
+	rc = lstcon_rpc_trans_ndlist(&tmp->grp_ndl_list,
+				     &tmp->grp_trans_list, LST_TRANS_SESNEW,
+				     tmp, lstcon_sesrpc_condition, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction: %d\n", rc);
+		lstcon_group_put(tmp);
+		return rc;
+	}
+
+	/* post all RPCs */
+	lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
+
+	rc = lstcon_rpc_trans_interpreter(trans, result_up,
+					  lstcon_sesrpc_readent);
+	*featp = trans->tas_features;
+
+	/* destroy all RPGs */
+	lstcon_rpc_trans_destroy(trans);
+
+	lstcon_group_move(tmp, grp);
+	lstcon_group_put(tmp);
+
+	return rc;
+}
+
+static int
+lstcon_group_nodes_remove(lstcon_group_t *grp,
+			  int count, lnet_process_id_t *ids_up,
+			  struct list_head *result_up)
+{
+	lstcon_rpc_trans_t     *trans;
+	lstcon_ndlink_t	*ndl;
+	lstcon_group_t	 *tmp;
+	lnet_process_id_t       id;
+	int		     rc;
+	int		     i;
+
+	/* End session and remove node from the group */
+
+	rc = lstcon_group_alloc(NULL, &tmp);
+	if (rc != 0) {
+		CERROR("Out of memory\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < count; i++) {
+		if (copy_from_user(&id, &ids_up[i], sizeof(id))) {
+			rc = -EFAULT;
+			goto error;
+		}
+
+		/* move node to tmp group */
+		if (lstcon_group_ndlink_find(grp, id, &ndl, 0) == 0)
+			lstcon_group_ndlink_move(grp, tmp, ndl);
+	}
+
+	rc = lstcon_rpc_trans_ndlist(&tmp->grp_ndl_list,
+				     &tmp->grp_trans_list, LST_TRANS_SESEND,
+				     tmp, lstcon_sesrpc_condition, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction: %d\n", rc);
+		goto error;
+	}
+
+	lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
+
+	rc = lstcon_rpc_trans_interpreter(trans, result_up, NULL);
+
+	lstcon_rpc_trans_destroy(trans);
+	/* release nodes anyway, because we can't rollback status */
+	lstcon_group_put(tmp);
+
+	return rc;
+error:
+	lstcon_group_move(tmp, grp);
+	lstcon_group_put(tmp);
+
+	return rc;
+}
+
+int
+lstcon_group_add(char *name)
+{
+	lstcon_group_t *grp;
+	int	     rc;
+
+	rc = (lstcon_group_find(name, &grp) == 0)? -EEXIST: 0;
+	if (rc != 0) {
+		/* find a group with same name */
+		lstcon_group_put(grp);
+		return rc;
+	}
+
+	rc = lstcon_group_alloc(name, &grp);
+	if (rc != 0) {
+		CERROR("Can't allocate descriptor for group %s\n", name);
+		return -ENOMEM;
+	}
+
+	list_add_tail(&grp->grp_link, &console_session.ses_grp_list);
+
+	return rc;
+}
+
+int
+lstcon_nodes_add(char *name, int count, lnet_process_id_t *ids_up,
+		 unsigned *featp, struct list_head *result_up)
+{
+	lstcon_group_t	 *grp;
+	int		     rc;
+
+	LASSERT (count > 0);
+	LASSERT (ids_up != NULL);
+
+	rc = lstcon_group_find(name, &grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find group %s\n", name);
+		return rc;
+	}
+
+	if (grp->grp_ref > 2) {
+		/* referred by other threads or test */
+		CDEBUG(D_NET, "Group %s is busy\n", name);
+		lstcon_group_put(grp);
+
+		return -EBUSY;
+	}
+
+	rc = lstcon_group_nodes_add(grp, count, ids_up, featp, result_up);
+
+	lstcon_group_put(grp);
+
+	return rc;
+}
+
+int
+lstcon_group_del(char *name)
+{
+	lstcon_rpc_trans_t *trans;
+	lstcon_group_t     *grp;
+	int		 rc;
+
+	rc = lstcon_group_find(name, &grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find group: %s\n", name);
+		return rc;
+	}
+
+	if (grp->grp_ref > 2) {
+		/* referred by others threads or test */
+		CDEBUG(D_NET, "Group %s is busy\n", name);
+		lstcon_group_put(grp);
+		return -EBUSY;
+	}
+
+	rc = lstcon_rpc_trans_ndlist(&grp->grp_ndl_list,
+				     &grp->grp_trans_list, LST_TRANS_SESEND,
+				     grp, lstcon_sesrpc_condition, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction: %d\n", rc);
+		lstcon_group_put(grp);
+		return rc;
+	}
+
+	lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
+
+	lstcon_rpc_trans_destroy(trans);
+
+	lstcon_group_put(grp);
+	/* -ref for session, it's destroyed,
+	 * status can't be rolled back, destroy group anway */
+	lstcon_group_put(grp);
+
+	return rc;
+}
+
+int
+lstcon_group_clean(char *name, int args)
+{
+	lstcon_group_t *grp = NULL;
+	int	     rc;
+
+	rc = lstcon_group_find(name, &grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find group %s\n", name);
+		return rc;
+	}
+
+	if (grp->grp_ref > 2) {
+		/* referred by test */
+		CDEBUG(D_NET, "Group %s is busy\n", name);
+		lstcon_group_put(grp);
+		return -EBUSY;
+	}
+
+	args = (LST_NODE_ACTIVE | LST_NODE_BUSY |
+		LST_NODE_DOWN | LST_NODE_UNKNOWN) & ~args;
+
+	lstcon_group_drain(grp, args);
+
+	lstcon_group_put(grp);
+	/* release empty group */
+	if (list_empty(&grp->grp_ndl_list))
+		lstcon_group_put(grp);
+
+	return 0;
+}
+
+int
+lstcon_nodes_remove(char *name, int count,
+		    lnet_process_id_t *ids_up, struct list_head *result_up)
+{
+	lstcon_group_t *grp = NULL;
+	int	     rc;
+
+	rc = lstcon_group_find(name, &grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find group: %s\n", name);
+		return rc;
+	}
+
+	if (grp->grp_ref > 2) {
+		/* referred by test */
+		CDEBUG(D_NET, "Group %s is busy\n", name);
+		lstcon_group_put(grp);
+		return -EBUSY;
+	}
+
+	rc = lstcon_group_nodes_remove(grp, count, ids_up, result_up);
+
+	lstcon_group_put(grp);
+	/* release empty group */
+	if (list_empty(&grp->grp_ndl_list))
+		lstcon_group_put(grp);
+
+	return rc;
+}
+
+int
+lstcon_group_refresh(char *name, struct list_head *result_up)
+{
+	lstcon_rpc_trans_t      *trans;
+	lstcon_group_t	  *grp;
+	int		      rc;
+
+	rc = lstcon_group_find(name, &grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find group: %s\n", name);
+		return rc;
+	}
+
+	if (grp->grp_ref > 2) {
+		/* referred by test */
+		CDEBUG(D_NET, "Group %s is busy\n", name);
+		lstcon_group_put(grp);
+		return -EBUSY;
+	}
+
+	/* re-invite all inactive nodes int the group */
+	rc = lstcon_rpc_trans_ndlist(&grp->grp_ndl_list,
+				     &grp->grp_trans_list, LST_TRANS_SESNEW,
+				     grp, lstcon_sesrpc_condition, &trans);
+	if (rc != 0) {
+		/* local error, return */
+		CDEBUG(D_NET, "Can't create transaction: %d\n", rc);
+		lstcon_group_put(grp);
+		return rc;
+	}
+
+	lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
+
+	rc = lstcon_rpc_trans_interpreter(trans, result_up, NULL);
+
+	lstcon_rpc_trans_destroy(trans);
+	/* -ref for me */
+	lstcon_group_put(grp);
+
+	return rc;
+}
+
+int
+lstcon_group_list(int index, int len, char *name_up)
+{
+	lstcon_group_t *grp;
+
+	LASSERT (index >= 0);
+	LASSERT (name_up != NULL);
+
+	list_for_each_entry(grp, &console_session.ses_grp_list, grp_link) {
+		if (index-- == 0) {
+			return copy_to_user(name_up, grp->grp_name, len) ?
+			       -EFAULT : 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static int
+lstcon_nodes_getent(struct list_head *head, int *index_p,
+		    int *count_p, lstcon_node_ent_t *dents_up)
+{
+	lstcon_ndlink_t  *ndl;
+	lstcon_node_t    *nd;
+	int	       count = 0;
+	int	       index = 0;
+
+	LASSERT (index_p != NULL && count_p != NULL);
+	LASSERT (dents_up != NULL);
+	LASSERT (*index_p >= 0);
+	LASSERT (*count_p > 0);
+
+	list_for_each_entry(ndl, head, ndl_link) {
+		if (index++ < *index_p)
+			continue;
+
+		if (count >= *count_p)
+			break;
+
+		nd = ndl->ndl_node;
+		if (copy_to_user(&dents_up[count].nde_id,
+				     &nd->nd_id, sizeof(nd->nd_id)) ||
+		    copy_to_user(&dents_up[count].nde_state,
+				     &nd->nd_state, sizeof(nd->nd_state)))
+			return -EFAULT;
+
+		count ++;
+	}
+
+	if (index <= *index_p)
+		return -ENOENT;
+
+	*count_p = count;
+	*index_p = index;
+
+	return 0;
+}
+
+int
+lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p,
+		  int *index_p, int *count_p, lstcon_node_ent_t *dents_up)
+{
+	lstcon_ndlist_ent_t *gentp;
+	lstcon_group_t      *grp;
+	lstcon_ndlink_t     *ndl;
+	int		  rc;
+
+	rc = lstcon_group_find(name, &grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find group %s\n", name);
+		return rc;
+	}
+
+	if (dents_up != 0) {
+		/* verbose query */
+		rc = lstcon_nodes_getent(&grp->grp_ndl_list,
+					 index_p, count_p, dents_up);
+		lstcon_group_put(grp);
+
+		return rc;
+	}
+
+	/* non-verbose query */
+	LIBCFS_ALLOC(gentp, sizeof(lstcon_ndlist_ent_t));
+	if (gentp == NULL) {
+		CERROR("Can't allocate ndlist_ent\n");
+		lstcon_group_put(grp);
+
+		return -ENOMEM;
+	}
+
+	memset(gentp, 0, sizeof(lstcon_ndlist_ent_t));
+
+	list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link)
+		LST_NODE_STATE_COUNTER(ndl->ndl_node, gentp);
+
+	rc = copy_to_user(gents_p, gentp,
+			      sizeof(lstcon_ndlist_ent_t)) ? -EFAULT: 0;
+
+	LIBCFS_FREE(gentp, sizeof(lstcon_ndlist_ent_t));
+
+	lstcon_group_put(grp);
+
+	return 0;
+}
+
+int
+lstcon_batch_find(char *name, lstcon_batch_t **batpp)
+{
+	lstcon_batch_t   *bat;
+
+	list_for_each_entry(bat, &console_session.ses_bat_list, bat_link) {
+		if (strncmp(bat->bat_name, name, LST_NAME_SIZE) == 0) {
+			*batpp = bat;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+int
+lstcon_batch_add(char *name)
+{
+	lstcon_batch_t   *bat;
+	int	       i;
+	int	       rc;
+
+	rc = (lstcon_batch_find(name, &bat) == 0)? -EEXIST: 0;
+	if (rc != 0) {
+		CDEBUG(D_NET, "Batch %s already exists\n", name);
+		return rc;
+	}
+
+	LIBCFS_ALLOC(bat, sizeof(lstcon_batch_t));
+	if (bat == NULL) {
+		CERROR("Can't allocate descriptor for batch %s\n", name);
+		return -ENOMEM;
+	}
+
+	LIBCFS_ALLOC(bat->bat_cli_hash,
+		     sizeof(struct list_head) * LST_NODE_HASHSIZE);
+	if (bat->bat_cli_hash == NULL) {
+		CERROR("Can't allocate hash for batch %s\n", name);
+		LIBCFS_FREE(bat, sizeof(lstcon_batch_t));
+
+		return -ENOMEM;
+	}
+
+	LIBCFS_ALLOC(bat->bat_srv_hash,
+		     sizeof(struct list_head) * LST_NODE_HASHSIZE);
+	if (bat->bat_srv_hash == NULL) {
+		CERROR("Can't allocate hash for batch %s\n", name);
+		LIBCFS_FREE(bat->bat_cli_hash, LST_NODE_HASHSIZE);
+		LIBCFS_FREE(bat, sizeof(lstcon_batch_t));
+
+		return -ENOMEM;
+	}
+
+	strcpy(bat->bat_name, name);
+	bat->bat_hdr.tsb_index = 0;
+	bat->bat_hdr.tsb_id.bat_id = ++console_session.ses_id_cookie;
+
+	bat->bat_ntest = 0;
+	bat->bat_state = LST_BATCH_IDLE;
+
+	INIT_LIST_HEAD(&bat->bat_cli_list);
+	INIT_LIST_HEAD(&bat->bat_srv_list);
+	INIT_LIST_HEAD(&bat->bat_test_list);
+	INIT_LIST_HEAD(&bat->bat_trans_list);
+
+	for (i = 0; i < LST_NODE_HASHSIZE; i++) {
+		INIT_LIST_HEAD(&bat->bat_cli_hash[i]);
+		INIT_LIST_HEAD(&bat->bat_srv_hash[i]);
+	}
+
+	list_add_tail(&bat->bat_link, &console_session.ses_bat_list);
+
+	return rc;
+}
+
+int
+lstcon_batch_list(int index, int len, char *name_up)
+{
+	lstcon_batch_t    *bat;
+
+	LASSERT (name_up != NULL);
+	LASSERT (index >= 0);
+
+	list_for_each_entry(bat, &console_session.ses_bat_list, bat_link) {
+		if (index-- == 0) {
+			return copy_to_user(name_up,bat->bat_name, len) ?
+			       -EFAULT: 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+int
+lstcon_batch_info(char *name, lstcon_test_batch_ent_t *ent_up, int server,
+		  int testidx, int *index_p, int *ndent_p,
+		  lstcon_node_ent_t *dents_up)
+{
+	lstcon_test_batch_ent_t *entp;
+	struct list_head	      *clilst;
+	struct list_head	      *srvlst;
+	lstcon_test_t	   *test = NULL;
+	lstcon_batch_t	  *bat;
+	lstcon_ndlink_t	 *ndl;
+	int		      rc;
+
+	rc = lstcon_batch_find(name, &bat);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find batch %s\n", name);
+		return -ENOENT;
+	}
+
+	if (testidx > 0) {
+		/* query test, test index start from 1 */
+		list_for_each_entry(test, &bat->bat_test_list, tes_link) {
+			if (testidx-- == 1)
+				break;
+		}
+
+		if (testidx > 0) {
+			CDEBUG(D_NET, "Can't find specified test in batch\n");
+			return -ENOENT;
+		}
+	}
+
+	clilst = (test == NULL) ? &bat->bat_cli_list :
+				  &test->tes_src_grp->grp_ndl_list;
+	srvlst = (test == NULL) ? &bat->bat_srv_list :
+				  &test->tes_dst_grp->grp_ndl_list;
+
+	if (dents_up != NULL) {
+		rc = lstcon_nodes_getent((server ? srvlst: clilst),
+					 index_p, ndent_p, dents_up);
+		return rc;
+	}
+
+	/* non-verbose query */
+	LIBCFS_ALLOC(entp, sizeof(lstcon_test_batch_ent_t));
+	if (entp == NULL)
+		return -ENOMEM;
+
+	memset(entp, 0, sizeof(lstcon_test_batch_ent_t));
+
+	if (test == NULL) {
+		entp->u.tbe_batch.bae_ntest = bat->bat_ntest;
+		entp->u.tbe_batch.bae_state = bat->bat_state;
+
+	} else {
+
+		entp->u.tbe_test.tse_type   = test->tes_type;
+		entp->u.tbe_test.tse_loop   = test->tes_loop;
+		entp->u.tbe_test.tse_concur = test->tes_concur;
+	}
+
+	list_for_each_entry(ndl, clilst, ndl_link)
+		LST_NODE_STATE_COUNTER(ndl->ndl_node, &entp->tbe_cli_nle);
+
+	list_for_each_entry(ndl, srvlst, ndl_link)
+		LST_NODE_STATE_COUNTER(ndl->ndl_node, &entp->tbe_srv_nle);
+
+	rc = copy_to_user(ent_up, entp,
+			      sizeof(lstcon_test_batch_ent_t)) ? -EFAULT : 0;
+
+	LIBCFS_FREE(entp, sizeof(lstcon_test_batch_ent_t));
+
+	return rc;
+}
+
+int
+lstcon_batrpc_condition(int transop, lstcon_node_t *nd, void *arg)
+{
+	switch (transop) {
+	case LST_TRANS_TSBRUN:
+		if (nd->nd_state != LST_NODE_ACTIVE)
+			return -ENETDOWN;
+		break;
+
+	case LST_TRANS_TSBSTOP:
+		if (nd->nd_state != LST_NODE_ACTIVE)
+			return 0;
+		break;
+
+	case LST_TRANS_TSBCLIQRY:
+	case LST_TRANS_TSBSRVQRY:
+		break;
+	}
+
+	return 1;
+}
+
+static int
+lstcon_batch_op(lstcon_batch_t *bat, int transop,
+		struct list_head *result_up)
+{
+	lstcon_rpc_trans_t *trans;
+	int		 rc;
+
+	rc = lstcon_rpc_trans_ndlist(&bat->bat_cli_list,
+				     &bat->bat_trans_list, transop,
+				     bat, lstcon_batrpc_condition, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction: %d\n", rc);
+		return rc;
+	}
+
+	lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
+
+	rc = lstcon_rpc_trans_interpreter(trans, result_up, NULL);
+
+	lstcon_rpc_trans_destroy(trans);
+
+	return rc;
+}
+
+int
+lstcon_batch_run(char *name, int timeout, struct list_head *result_up)
+{
+	lstcon_batch_t *bat;
+	int	     rc;
+
+	if (lstcon_batch_find(name, &bat) != 0) {
+		CDEBUG(D_NET, "Can't find batch %s\n", name);
+		return -ENOENT;
+	}
+
+	bat->bat_arg = timeout;
+
+	rc = lstcon_batch_op(bat, LST_TRANS_TSBRUN, result_up);
+
+	/* mark batch as running if it's started in any node */
+	if (lstcon_tsbop_stat_success(lstcon_trans_stat(), 0) != 0)
+		bat->bat_state = LST_BATCH_RUNNING;
+
+	return rc;
+}
+
+int
+lstcon_batch_stop(char *name, int force, struct list_head *result_up)
+{
+	lstcon_batch_t *bat;
+	int	     rc;
+
+	if (lstcon_batch_find(name, &bat) != 0) {
+		CDEBUG(D_NET, "Can't find batch %s\n", name);
+		return -ENOENT;
+	}
+
+	bat->bat_arg = force;
+
+	rc = lstcon_batch_op(bat, LST_TRANS_TSBSTOP, result_up);
+
+	/* mark batch as stopped if all RPCs finished */
+	if (lstcon_tsbop_stat_failure(lstcon_trans_stat(), 0) == 0)
+		bat->bat_state = LST_BATCH_IDLE;
+
+	return rc;
+}
+
+static void
+lstcon_batch_destroy(lstcon_batch_t *bat)
+{
+	lstcon_ndlink_t    *ndl;
+	lstcon_test_t      *test;
+	int		 i;
+
+	list_del(&bat->bat_link);
+
+	while (!list_empty(&bat->bat_test_list)) {
+		test = list_entry(bat->bat_test_list.next,
+				      lstcon_test_t, tes_link);
+		LASSERT (list_empty(&test->tes_trans_list));
+
+		list_del(&test->tes_link);
+
+		lstcon_group_put(test->tes_src_grp);
+		lstcon_group_put(test->tes_dst_grp);
+
+		LIBCFS_FREE(test, offsetof(lstcon_test_t,
+					   tes_param[test->tes_paramlen]));
+	}
+
+	LASSERT (list_empty(&bat->bat_trans_list));
+
+	while (!list_empty(&bat->bat_cli_list)) {
+		ndl = list_entry(bat->bat_cli_list.next,
+				     lstcon_ndlink_t, ndl_link);
+		list_del_init(&ndl->ndl_link);
+
+		lstcon_ndlink_release(ndl);
+	}
+
+	while (!list_empty(&bat->bat_srv_list)) {
+		ndl = list_entry(bat->bat_srv_list.next,
+				     lstcon_ndlink_t, ndl_link);
+		list_del_init(&ndl->ndl_link);
+
+		lstcon_ndlink_release(ndl);
+	}
+
+	for (i = 0; i < LST_NODE_HASHSIZE; i++) {
+		LASSERT (list_empty(&bat->bat_cli_hash[i]));
+		LASSERT (list_empty(&bat->bat_srv_hash[i]));
+	}
+
+	LIBCFS_FREE(bat->bat_cli_hash,
+		    sizeof(struct list_head) * LST_NODE_HASHSIZE);
+	LIBCFS_FREE(bat->bat_srv_hash,
+		    sizeof(struct list_head) * LST_NODE_HASHSIZE);
+	LIBCFS_FREE(bat, sizeof(lstcon_batch_t));
+}
+
+int
+lstcon_testrpc_condition(int transop, lstcon_node_t *nd, void *arg)
+{
+	lstcon_test_t    *test;
+	lstcon_batch_t   *batch;
+	lstcon_ndlink_t  *ndl;
+	struct list_head       *hash;
+	struct list_head       *head;
+
+	test = (lstcon_test_t *)arg;
+	LASSERT (test != NULL);
+
+	batch = test->tes_batch;
+	LASSERT (batch != NULL);
+
+	if (test->tes_oneside &&
+	    transop == LST_TRANS_TSBSRVADD)
+		return 0;
+
+	if (nd->nd_state != LST_NODE_ACTIVE)
+		return -ENETDOWN;
+
+	if (transop == LST_TRANS_TSBCLIADD) {
+		hash = batch->bat_cli_hash;
+		head = &batch->bat_cli_list;
+
+	} else {
+		LASSERT (transop == LST_TRANS_TSBSRVADD);
+
+		hash = batch->bat_srv_hash;
+		head = &batch->bat_srv_list;
+	}
+
+	LASSERT (nd->nd_id.nid != LNET_NID_ANY);
+
+	if (lstcon_ndlink_find(hash, nd->nd_id, &ndl, 1) != 0)
+		return -ENOMEM;
+
+	if (list_empty(&ndl->ndl_link))
+		list_add_tail(&ndl->ndl_link, head);
+
+	return 1;
+}
+
+static int
+lstcon_test_nodes_add(lstcon_test_t *test, struct list_head *result_up)
+{
+	lstcon_rpc_trans_t     *trans;
+	lstcon_group_t	 *grp;
+	int		     transop;
+	int		     rc;
+
+	LASSERT (test->tes_src_grp != NULL);
+	LASSERT (test->tes_dst_grp != NULL);
+
+	transop = LST_TRANS_TSBSRVADD;
+	grp  = test->tes_dst_grp;
+again:
+	rc = lstcon_rpc_trans_ndlist(&grp->grp_ndl_list,
+				     &test->tes_trans_list, transop,
+				     test, lstcon_testrpc_condition, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction: %d\n", rc);
+		return rc;
+	}
+
+	lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
+
+	if (lstcon_trans_stat()->trs_rpc_errno != 0 ||
+	    lstcon_trans_stat()->trs_fwk_errno != 0) {
+		lstcon_rpc_trans_interpreter(trans, result_up, NULL);
+
+		lstcon_rpc_trans_destroy(trans);
+		/* return if any error */
+		CDEBUG(D_NET, "Failed to add test %s, "
+			      "RPC error %d, framework error %d\n",
+		       transop == LST_TRANS_TSBCLIADD ? "client" : "server",
+		       lstcon_trans_stat()->trs_rpc_errno,
+		       lstcon_trans_stat()->trs_fwk_errno);
+
+		return rc;
+	}
+
+	lstcon_rpc_trans_destroy(trans);
+
+	if (transop == LST_TRANS_TSBCLIADD)
+		return rc;
+
+	transop = LST_TRANS_TSBCLIADD;
+	grp = test->tes_src_grp;
+	test->tes_cliidx = 0;
+
+	/* requests to test clients */
+	goto again;
+}
+
+int
+lstcon_test_add(char *name, int type, int loop, int concur,
+		int dist, int span, char *src_name, char * dst_name,
+		void *param, int paramlen, int *retp,
+		struct list_head *result_up)
+{
+	lstcon_group_t  *src_grp = NULL;
+	lstcon_group_t  *dst_grp = NULL;
+	lstcon_test_t   *test    = NULL;
+	lstcon_batch_t  *batch;
+	int	      rc;
+
+	rc = lstcon_batch_find(name, &batch);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find batch %s\n", name);
+		return rc;
+	}
+
+	if (batch->bat_state != LST_BATCH_IDLE) {
+		CDEBUG(D_NET, "Can't change running batch %s\n", name);
+		return rc;
+	}
+
+	rc = lstcon_group_find(src_name, &src_grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find group %s\n", src_name);
+		goto out;
+	}
+
+	rc = lstcon_group_find(dst_name, &dst_grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find group %s\n", dst_name);
+		goto out;
+	}
+
+	if (dst_grp->grp_userland)
+		*retp = 1;
+
+	LIBCFS_ALLOC(test, offsetof(lstcon_test_t, tes_param[paramlen]));
+	if (!test) {
+		CERROR("Can't allocate test descriptor\n");
+		rc = -ENOMEM;
+
+		goto out;
+	}
+
+	memset(test, 0, offsetof(lstcon_test_t, tes_param[paramlen]));
+	test->tes_hdr.tsb_id    = batch->bat_hdr.tsb_id;
+	test->tes_batch	 = batch;
+	test->tes_type	  = type;
+	test->tes_oneside       = 0; /* TODO */
+	test->tes_loop	  = loop;
+	test->tes_concur	= concur;
+	test->tes_stop_onerr    = 1; /* TODO */
+	test->tes_span	  = span;
+	test->tes_dist	  = dist;
+	test->tes_cliidx	= 0; /* just used for creating RPC */
+	test->tes_src_grp       = src_grp;
+	test->tes_dst_grp       = dst_grp;
+	INIT_LIST_HEAD(&test->tes_trans_list);
+
+	if (param != NULL) {
+		test->tes_paramlen = paramlen;
+		memcpy(&test->tes_param[0], param, paramlen);
+	}
+
+	rc = lstcon_test_nodes_add(test, result_up);
+
+	if (rc != 0)
+		goto out;
+
+	if (lstcon_trans_stat()->trs_rpc_errno != 0 ||
+	    lstcon_trans_stat()->trs_fwk_errno != 0)
+		CDEBUG(D_NET, "Failed to add test %d to batch %s\n", type, name);
+
+	/* add to test list anyway, so user can check what's going on */
+	list_add_tail(&test->tes_link, &batch->bat_test_list);
+
+	batch->bat_ntest ++;
+	test->tes_hdr.tsb_index = batch->bat_ntest;
+
+	/*  hold groups so nobody can change them */
+	return rc;
+out:
+	if (test != NULL)
+		LIBCFS_FREE(test, offsetof(lstcon_test_t, tes_param[paramlen]));
+
+	if (dst_grp != NULL)
+		lstcon_group_put(dst_grp);
+
+	if (src_grp != NULL)
+		lstcon_group_put(src_grp);
+
+	return rc;
+}
+
+int
+lstcon_test_find(lstcon_batch_t *batch, int idx, lstcon_test_t **testpp)
+{
+	lstcon_test_t *test;
+
+	list_for_each_entry(test, &batch->bat_test_list, tes_link) {
+		if (idx == test->tes_hdr.tsb_index) {
+			*testpp = test;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+int
+lstcon_tsbrpc_readent(int transop, srpc_msg_t *msg,
+		      lstcon_rpc_ent_t *ent_up)
+{
+	srpc_batch_reply_t *rep = &msg->msg_body.bat_reply;
+
+	LASSERT (transop == LST_TRANS_TSBCLIQRY ||
+		 transop == LST_TRANS_TSBSRVQRY);
+
+	/* positive errno, framework error code */
+	if (copy_to_user(&ent_up->rpe_priv[0],
+			     &rep->bar_active, sizeof(rep->bar_active)))
+		return -EFAULT;
+
+	return 0;
+}
+
+int
+lstcon_test_batch_query(char *name, int testidx, int client,
+			int timeout, struct list_head *result_up)
+{
+	lstcon_rpc_trans_t *trans;
+	struct list_head	 *translist;
+	struct list_head	 *ndlist;
+	lstcon_tsb_hdr_t   *hdr;
+	lstcon_batch_t     *batch;
+	lstcon_test_t      *test = NULL;
+	int		 transop;
+	int		 rc;
+
+	rc = lstcon_batch_find(name, &batch);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find batch: %s\n", name);
+		return rc;
+	}
+
+	if (testidx == 0) {
+		translist = &batch->bat_trans_list;
+		ndlist    = &batch->bat_cli_list;
+		hdr       = &batch->bat_hdr;
+
+	} else {
+		/* query specified test only */
+		rc = lstcon_test_find(batch, testidx, &test);
+		if (rc != 0) {
+			CDEBUG(D_NET, "Can't find test: %d\n", testidx);
+			return rc;
+		}
+
+		translist = &test->tes_trans_list;
+		ndlist    = &test->tes_src_grp->grp_ndl_list;
+		hdr       = &test->tes_hdr;
+	}
+
+	transop = client ? LST_TRANS_TSBCLIQRY : LST_TRANS_TSBSRVQRY;
+
+	rc = lstcon_rpc_trans_ndlist(ndlist, translist, transop, hdr,
+				     lstcon_batrpc_condition, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction: %d\n", rc);
+		return rc;
+	}
+
+	lstcon_rpc_trans_postwait(trans, timeout);
+
+	if (testidx == 0 && /* query a batch, not a test */
+	    lstcon_rpc_stat_failure(lstcon_trans_stat(), 0) == 0 &&
+	    lstcon_tsbqry_stat_run(lstcon_trans_stat(), 0) == 0) {
+		/* all RPCs finished, and no active test */
+		batch->bat_state = LST_BATCH_IDLE;
+	}
+
+	rc = lstcon_rpc_trans_interpreter(trans, result_up,
+					  lstcon_tsbrpc_readent);
+	lstcon_rpc_trans_destroy(trans);
+
+	return rc;
+}
+
+int
+lstcon_statrpc_readent(int transop, srpc_msg_t *msg,
+		       lstcon_rpc_ent_t *ent_up)
+{
+	srpc_stat_reply_t *rep = &msg->msg_body.stat_reply;
+	sfw_counters_t    *sfwk_stat;
+	srpc_counters_t   *srpc_stat;
+	lnet_counters_t   *lnet_stat;
+
+	if (rep->str_status != 0)
+		return 0;
+
+	sfwk_stat = (sfw_counters_t *)&ent_up->rpe_payload[0];
+	srpc_stat = (srpc_counters_t *)((char *)sfwk_stat + sizeof(*sfwk_stat));
+	lnet_stat = (lnet_counters_t *)((char *)srpc_stat + sizeof(*srpc_stat));
+
+	if (copy_to_user(sfwk_stat, &rep->str_fw, sizeof(*sfwk_stat)) ||
+	    copy_to_user(srpc_stat, &rep->str_rpc, sizeof(*srpc_stat)) ||
+	    copy_to_user(lnet_stat, &rep->str_lnet, sizeof(*lnet_stat)))
+		return -EFAULT;
+
+	return 0;
+}
+
+int
+lstcon_ndlist_stat(struct list_head *ndlist,
+		   int timeout, struct list_head *result_up)
+{
+	struct list_head	  head;
+	lstcon_rpc_trans_t *trans;
+	int		 rc;
+
+	INIT_LIST_HEAD(&head);
+
+	rc = lstcon_rpc_trans_ndlist(ndlist, &head,
+				     LST_TRANS_STATQRY, NULL, NULL, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction: %d\n", rc);
+		return rc;
+	}
+
+	lstcon_rpc_trans_postwait(trans, LST_VALIDATE_TIMEOUT(timeout));
+
+	rc = lstcon_rpc_trans_interpreter(trans, result_up,
+					  lstcon_statrpc_readent);
+	lstcon_rpc_trans_destroy(trans);
+
+	return rc;
+}
+
+int
+lstcon_group_stat(char *grp_name, int timeout, struct list_head *result_up)
+{
+	lstcon_group_t     *grp;
+	int		 rc;
+
+	rc = lstcon_group_find(grp_name, &grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Can't find group %s\n", grp_name);
+		return rc;
+	}
+
+	rc = lstcon_ndlist_stat(&grp->grp_ndl_list, timeout, result_up);
+
+	lstcon_group_put(grp);
+
+	return rc;
+}
+
+int
+lstcon_nodes_stat(int count, lnet_process_id_t *ids_up,
+		  int timeout, struct list_head *result_up)
+{
+	lstcon_ndlink_t	 *ndl;
+	lstcon_group_t	  *tmp;
+	lnet_process_id_t	id;
+	int		      i;
+	int		      rc;
+
+	rc = lstcon_group_alloc(NULL, &tmp);
+	if (rc != 0) {
+		CERROR("Out of memory\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0 ; i < count; i++) {
+		if (copy_from_user(&id, &ids_up[i], sizeof(id))) {
+			rc = -EFAULT;
+			break;
+		}
+
+		/* add to tmp group */
+		rc = lstcon_group_ndlink_find(tmp, id, &ndl, 2);
+		if (rc != 0) {
+			CDEBUG((rc == -ENOMEM) ? D_ERROR : D_NET,
+			       "Failed to find or create %s: %d\n",
+			       libcfs_id2str(id), rc);
+			break;
+		}
+	}
+
+	if (rc != 0) {
+		lstcon_group_put(tmp);
+		return rc;
+	}
+
+	rc = lstcon_ndlist_stat(&tmp->grp_ndl_list, timeout, result_up);
+
+	lstcon_group_put(tmp);
+
+	return rc;
+}
+
+int
+lstcon_debug_ndlist(struct list_head *ndlist,
+		    struct list_head *translist,
+		    int timeout, struct list_head *result_up)
+{
+	lstcon_rpc_trans_t *trans;
+	int		 rc;
+
+	rc = lstcon_rpc_trans_ndlist(ndlist, translist, LST_TRANS_SESQRY,
+				     NULL, lstcon_sesrpc_condition, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction: %d\n", rc);
+		return rc;
+	}
+
+	lstcon_rpc_trans_postwait(trans, LST_VALIDATE_TIMEOUT(timeout));
+
+	rc = lstcon_rpc_trans_interpreter(trans, result_up,
+					  lstcon_sesrpc_readent);
+	lstcon_rpc_trans_destroy(trans);
+
+	return rc;
+}
+
+int
+lstcon_session_debug(int timeout, struct list_head *result_up)
+{
+	return lstcon_debug_ndlist(&console_session.ses_ndl_list,
+				   NULL, timeout, result_up);
+}
+
+int
+lstcon_batch_debug(int timeout, char *name,
+		   int client, struct list_head *result_up)
+{
+	lstcon_batch_t *bat;
+	int	     rc;
+
+	rc = lstcon_batch_find(name, &bat);
+	if (rc != 0)
+		return -ENOENT;
+
+	rc = lstcon_debug_ndlist(client ? &bat->bat_cli_list :
+					  &bat->bat_srv_list,
+				 NULL, timeout, result_up);
+
+	return rc;
+}
+
+int
+lstcon_group_debug(int timeout, char *name,
+		   struct list_head *result_up)
+{
+	lstcon_group_t *grp;
+	int	     rc;
+
+	rc = lstcon_group_find(name, &grp);
+	if (rc != 0)
+		return -ENOENT;
+
+	rc = lstcon_debug_ndlist(&grp->grp_ndl_list, NULL,
+				 timeout, result_up);
+	lstcon_group_put(grp);
+
+	return rc;
+}
+
+int
+lstcon_nodes_debug(int timeout,
+		   int count, lnet_process_id_t *ids_up,
+		   struct list_head *result_up)
+{
+	lnet_process_id_t  id;
+	lstcon_ndlink_t   *ndl;
+	lstcon_group_t    *grp;
+	int		i;
+	int		rc;
+
+	rc = lstcon_group_alloc(NULL, &grp);
+	if (rc != 0) {
+		CDEBUG(D_NET, "Out of memory\n");
+		return rc;
+	}
+
+	for (i = 0; i < count; i++) {
+		if (copy_from_user(&id, &ids_up[i], sizeof(id))) {
+			rc = -EFAULT;
+			break;
+		}
+
+		/* node is added to tmp group */
+		rc = lstcon_group_ndlink_find(grp, id, &ndl, 1);
+		if (rc != 0) {
+			CERROR("Can't create node link\n");
+			break;
+		}
+	}
+
+	if (rc != 0) {
+		lstcon_group_put(grp);
+		return rc;
+	}
+
+	rc = lstcon_debug_ndlist(&grp->grp_ndl_list, NULL,
+				 timeout, result_up);
+
+	lstcon_group_put(grp);
+
+	return rc;
+}
+
+int
+lstcon_session_match(lst_sid_t sid)
+{
+	return (console_session.ses_id.ses_nid   == sid.ses_nid &&
+		console_session.ses_id.ses_stamp == sid.ses_stamp) ?  1: 0;
+}
+
+static void
+lstcon_new_session_id(lst_sid_t *sid)
+{
+	lnet_process_id_t      id;
+
+	LASSERT (console_session.ses_state == LST_SESSION_NONE);
+
+	LNetGetId(1, &id);
+	sid->ses_nid   = id.nid;
+	sid->ses_stamp = cfs_time_current();
+}
+
+extern srpc_service_t lstcon_acceptor_service;
+
+int
+lstcon_session_new(char *name, int key, unsigned feats,
+		   int timeout, int force, lst_sid_t *sid_up)
+{
+	int     rc = 0;
+	int     i;
+
+	if (console_session.ses_state != LST_SESSION_NONE) {
+		/* session exists */
+		if (!force) {
+			CNETERR("Session %s already exists\n",
+				console_session.ses_name);
+			return -EEXIST;
+		}
+
+		rc = lstcon_session_end();
+
+		/* lstcon_session_end() only return local error */
+		if  (rc != 0)
+			return rc;
+	}
+
+	if ((feats & ~LST_FEATS_MASK) != 0) {
+		CNETERR("Unknown session features %x\n",
+			(feats & ~LST_FEATS_MASK));
+		return -EINVAL;
+	}
+
+	for (i = 0; i < LST_GLOBAL_HASHSIZE; i++)
+		LASSERT(list_empty(&console_session.ses_ndl_hash[i]));
+
+	lstcon_new_session_id(&console_session.ses_id);
+
+	console_session.ses_key	    = key;
+	console_session.ses_state   = LST_SESSION_ACTIVE;
+	console_session.ses_force   = !!force;
+	console_session.ses_features = feats;
+	console_session.ses_feats_updated = 0;
+	console_session.ses_timeout = (timeout <= 0) ?
+				      LST_CONSOLE_TIMEOUT : timeout;
+	strcpy(console_session.ses_name, name);
+
+	rc = lstcon_batch_add(LST_DEFAULT_BATCH);
+	if (rc != 0)
+		return rc;
+
+	rc = lstcon_rpc_pinger_start();
+	if (rc != 0) {
+		lstcon_batch_t *bat = NULL;
+
+		lstcon_batch_find(LST_DEFAULT_BATCH, &bat);
+		lstcon_batch_destroy(bat);
+
+		return rc;
+	}
+
+	if (copy_to_user(sid_up, &console_session.ses_id,
+			     sizeof(lst_sid_t)) == 0)
+		return rc;
+
+	lstcon_session_end();
+
+	return -EFAULT;
+}
+
+int
+lstcon_session_info(lst_sid_t *sid_up, int *key_up, unsigned *featp,
+		    lstcon_ndlist_ent_t *ndinfo_up, char *name_up, int len)
+{
+	lstcon_ndlist_ent_t *entp;
+	lstcon_ndlink_t     *ndl;
+	int		  rc = 0;
+
+	if (console_session.ses_state != LST_SESSION_ACTIVE)
+		return -ESRCH;
+
+	LIBCFS_ALLOC(entp, sizeof(*entp));
+	if (entp == NULL)
+		return -ENOMEM;
+
+	memset(entp, 0, sizeof(*entp));
+
+	list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link)
+		LST_NODE_STATE_COUNTER(ndl->ndl_node, entp);
+
+	if (copy_to_user(sid_up, &console_session.ses_id,
+			     sizeof(lst_sid_t)) ||
+	    copy_to_user(key_up, &console_session.ses_key,
+			     sizeof(*key_up)) ||
+	    copy_to_user(featp, &console_session.ses_features,
+			     sizeof(*featp)) ||
+	    copy_to_user(ndinfo_up, entp, sizeof(*entp)) ||
+	    copy_to_user(name_up, console_session.ses_name, len))
+		rc = -EFAULT;
+
+	LIBCFS_FREE(entp, sizeof(*entp));
+
+	return rc;
+}
+
+int
+lstcon_session_end()
+{
+	lstcon_rpc_trans_t *trans;
+	lstcon_group_t     *grp;
+	lstcon_batch_t     *bat;
+	int		 rc = 0;
+
+	LASSERT (console_session.ses_state == LST_SESSION_ACTIVE);
+
+	rc = lstcon_rpc_trans_ndlist(&console_session.ses_ndl_list,
+				     NULL, LST_TRANS_SESEND, NULL,
+				     lstcon_sesrpc_condition, &trans);
+	if (rc != 0) {
+		CERROR("Can't create transaction: %d\n", rc);
+		return rc;
+	}
+
+	console_session.ses_shutdown = 1;
+
+	lstcon_rpc_pinger_stop();
+
+	lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);
+
+	lstcon_rpc_trans_destroy(trans);
+	/* User can do nothing even rpc failed, so go on */
+
+	/* waiting for orphan rpcs to die */
+	lstcon_rpc_cleanup_wait();
+
+	console_session.ses_id    = LST_INVALID_SID;
+	console_session.ses_state = LST_SESSION_NONE;
+	console_session.ses_key   = 0;
+	console_session.ses_force = 0;
+	console_session.ses_feats_updated = 0;
+
+	/* destroy all batches */
+	while (!list_empty(&console_session.ses_bat_list)) {
+		bat = list_entry(console_session.ses_bat_list.next,
+				     lstcon_batch_t, bat_link);
+
+		lstcon_batch_destroy(bat);
+	}
+
+	/* destroy all groups */
+	while (!list_empty(&console_session.ses_grp_list)) {
+		grp = list_entry(console_session.ses_grp_list.next,
+				     lstcon_group_t, grp_link);
+		LASSERT (grp->grp_ref == 1);
+
+		lstcon_group_put(grp);
+	}
+
+	/* all nodes should be released */
+	LASSERT (list_empty(&console_session.ses_ndl_list));
+
+	console_session.ses_shutdown = 0;
+	console_session.ses_expired  = 0;
+
+	return rc;
+}
+
+int
+lstcon_session_feats_check(unsigned feats)
+{
+	int rc = 0;
+
+	if ((feats & ~LST_FEATS_MASK) != 0) {
+		CERROR("Can't support these features: %x\n",
+		       (feats & ~LST_FEATS_MASK));
+		return -EPROTO;
+	}
+
+	spin_lock(&console_session.ses_rpc_lock);
+
+	if (!console_session.ses_feats_updated) {
+		console_session.ses_feats_updated = 1;
+		console_session.ses_features = feats;
+	}
+
+	if (console_session.ses_features != feats)
+		rc = -EPROTO;
+
+	spin_unlock(&console_session.ses_rpc_lock);
+
+	if (rc != 0) {
+		CERROR("remote features %x do not match with "
+		       "session features %x of console\n",
+		       feats, console_session.ses_features);
+	}
+
+	return rc;
+}
+
+static int
+lstcon_acceptor_handle (srpc_server_rpc_t *rpc)
+{
+	srpc_msg_t	*rep  = &rpc->srpc_replymsg;
+	srpc_msg_t	*req  = &rpc->srpc_reqstbuf->buf_msg;
+	srpc_join_reqst_t *jreq = &req->msg_body.join_reqst;
+	srpc_join_reply_t *jrep = &rep->msg_body.join_reply;
+	lstcon_group_t    *grp  = NULL;
+	lstcon_ndlink_t   *ndl;
+	int		rc   = 0;
+
+	sfw_unpack_message(req);
+
+	mutex_lock(&console_session.ses_mutex);
+
+	jrep->join_sid = console_session.ses_id;
+
+	if (console_session.ses_id.ses_nid == LNET_NID_ANY) {
+		jrep->join_status = ESRCH;
+		goto out;
+	}
+
+	if (lstcon_session_feats_check(req->msg_ses_feats) != 0) {
+		jrep->join_status = EPROTO;
+		goto out;
+	}
+
+	if (jreq->join_sid.ses_nid != LNET_NID_ANY &&
+	     !lstcon_session_match(jreq->join_sid)) {
+		jrep->join_status = EBUSY;
+		goto out;
+	}
+
+	if (lstcon_group_find(jreq->join_group, &grp) != 0) {
+		rc = lstcon_group_alloc(jreq->join_group, &grp);
+		if (rc != 0) {
+			CERROR("Out of memory\n");
+			goto out;
+		}
+
+		list_add_tail(&grp->grp_link,
+				  &console_session.ses_grp_list);
+		lstcon_group_addref(grp);
+	}
+
+	if (grp->grp_ref > 2) {
+		/* Group in using */
+		jrep->join_status = EBUSY;
+		goto out;
+	}
+
+	rc = lstcon_group_ndlink_find(grp, rpc->srpc_peer, &ndl, 0);
+	if (rc == 0) {
+		jrep->join_status = EEXIST;
+		goto out;
+	}
+
+	rc = lstcon_group_ndlink_find(grp, rpc->srpc_peer, &ndl, 1);
+	if (rc != 0) {
+		CERROR("Out of memory\n");
+		goto out;
+	}
+
+	ndl->ndl_node->nd_state   = LST_NODE_ACTIVE;
+	ndl->ndl_node->nd_timeout = console_session.ses_timeout;
+
+	if (grp->grp_userland == 0)
+		grp->grp_userland = 1;
+
+	strcpy(jrep->join_session, console_session.ses_name);
+	jrep->join_timeout = console_session.ses_timeout;
+	jrep->join_status  = 0;
+
+out:
+	rep->msg_ses_feats = console_session.ses_features;
+	if (grp != NULL)
+		lstcon_group_put(grp);
+
+	mutex_unlock(&console_session.ses_mutex);
+
+	return rc;
+}
+
+srpc_service_t lstcon_acceptor_service;
+void lstcon_init_acceptor_service(void)
+{
+	/* initialize selftest console acceptor service table */
+	lstcon_acceptor_service.sv_name    = "join session";
+	lstcon_acceptor_service.sv_handler = lstcon_acceptor_handle;
+	lstcon_acceptor_service.sv_id      = SRPC_SERVICE_JOIN;
+	lstcon_acceptor_service.sv_wi_total = SFW_FRWK_WI_MAX;
+}
+
+extern int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_data *data);
+
+DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry);
+
+/* initialize console */
+int
+lstcon_console_init(void)
+{
+	int     i;
+	int     rc;
+
+	memset(&console_session, 0, sizeof(lstcon_session_t));
+
+	console_session.ses_id		    = LST_INVALID_SID;
+	console_session.ses_state	    = LST_SESSION_NONE;
+	console_session.ses_timeout	    = 0;
+	console_session.ses_force	    = 0;
+	console_session.ses_expired	    = 0;
+	console_session.ses_feats_updated   = 0;
+	console_session.ses_features	    = LST_FEATS_MASK;
+	console_session.ses_laststamp	    = cfs_time_current_sec();
+
+	mutex_init(&console_session.ses_mutex);
+
+	INIT_LIST_HEAD(&console_session.ses_ndl_list);
+	INIT_LIST_HEAD(&console_session.ses_grp_list);
+	INIT_LIST_HEAD(&console_session.ses_bat_list);
+	INIT_LIST_HEAD(&console_session.ses_trans_list);
+
+	LIBCFS_ALLOC(console_session.ses_ndl_hash,
+		     sizeof(struct list_head) * LST_GLOBAL_HASHSIZE);
+	if (console_session.ses_ndl_hash == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < LST_GLOBAL_HASHSIZE; i++)
+		INIT_LIST_HEAD(&console_session.ses_ndl_hash[i]);
+
+
+	/* initialize acceptor service table */
+	lstcon_init_acceptor_service();
+
+	rc = srpc_add_service(&lstcon_acceptor_service);
+	LASSERT (rc != -EBUSY);
+	if (rc != 0) {
+		LIBCFS_FREE(console_session.ses_ndl_hash,
+			    sizeof(struct list_head) * LST_GLOBAL_HASHSIZE);
+		return rc;
+	}
+
+	rc = srpc_service_add_buffers(&lstcon_acceptor_service,
+				      lstcon_acceptor_service.sv_wi_total);
+	if (rc != 0) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	rc = libcfs_register_ioctl(&lstcon_ioctl_handler);
+
+	if (rc == 0) {
+		lstcon_rpc_module_init();
+		return 0;
+	}
+
+out:
+	srpc_shutdown_service(&lstcon_acceptor_service);
+	srpc_remove_service(&lstcon_acceptor_service);
+
+	LIBCFS_FREE(console_session.ses_ndl_hash,
+		    sizeof(struct list_head) * LST_GLOBAL_HASHSIZE);
+
+	srpc_wait_service_shutdown(&lstcon_acceptor_service);
+
+	return rc;
+}
+
+int
+lstcon_console_fini(void)
+{
+	int     i;
+
+	libcfs_deregister_ioctl(&lstcon_ioctl_handler);
+
+	mutex_lock(&console_session.ses_mutex);
+
+	srpc_shutdown_service(&lstcon_acceptor_service);
+	srpc_remove_service(&lstcon_acceptor_service);
+
+	if (console_session.ses_state != LST_SESSION_NONE)
+		lstcon_session_end();
+
+	lstcon_rpc_module_fini();
+
+	mutex_unlock(&console_session.ses_mutex);
+
+	LASSERT (list_empty(&console_session.ses_ndl_list));
+	LASSERT (list_empty(&console_session.ses_grp_list));
+	LASSERT (list_empty(&console_session.ses_bat_list));
+	LASSERT (list_empty(&console_session.ses_trans_list));
+
+	for (i = 0; i < LST_NODE_HASHSIZE; i++) {
+		LASSERT (list_empty(&console_session.ses_ndl_hash[i]));
+	}
+
+	LIBCFS_FREE(console_session.ses_ndl_hash,
+		    sizeof(struct list_head) * LST_GLOBAL_HASHSIZE);
+
+	srpc_wait_service_shutdown(&lstcon_acceptor_service);
+
+	return 0;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/console.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/console.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/console.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/console.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,232 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/console.h
+ *
+ * kernel structure for LST console
+ *
+ * Author: Liang Zhen <liangzhen@clusterfs.com>
+ */
+
+#ifndef __LST_CONSOLE_H__
+#define __LST_CONSOLE_H__
+
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lnet.h>
+#include <linux/lnet/lib-types.h>
+#include <linux/lnet/lnetst.h>
+#include "selftest.h"
+#include "conrpc.h"
+
+typedef struct lstcon_node {
+	lnet_process_id_t    nd_id;	  /* id of the node */
+	int		  nd_ref;	 /* reference count */
+	int		  nd_state;       /* state of the node */
+	int		  nd_timeout;     /* session timeout */
+	cfs_time_t	   nd_stamp;       /* timestamp of last replied RPC */
+	struct lstcon_rpc    nd_ping;	/* ping rpc */
+} lstcon_node_t;				/*** node descriptor */
+
+typedef struct {
+	struct list_head	   ndl_link;       /* chain on list */
+	struct list_head	   ndl_hlink;      /* chain on hash */
+	lstcon_node_t       *ndl_node;       /* pointer to node */
+} lstcon_ndlink_t;			      /*** node link descriptor */
+
+typedef struct {
+	struct list_head	   grp_link;       /* chain on global group list */
+	int		  grp_ref;	/* reference count */
+	int		  grp_userland;   /* has userland nodes */
+	int		  grp_nnode;      /* # of nodes */
+	char		 grp_name[LST_NAME_SIZE]; /* group name */
+
+	struct list_head	   grp_trans_list; /* transaction list */
+	struct list_head	   grp_ndl_list;   /* nodes list */
+	struct list_head	   grp_ndl_hash[0];/* hash table for nodes */
+} lstcon_group_t;		    /*** (alias of nodes) group descriptor */
+
+#define LST_BATCH_IDLE	  0xB0	    /* idle batch */
+#define LST_BATCH_RUNNING       0xB1	    /* running batch */
+
+typedef struct lstcon_tsb_hdr {
+	lst_bid_t	       tsb_id;	 /* batch ID */
+	int		     tsb_index;      /* test index */
+} lstcon_tsb_hdr_t;
+
+typedef struct {
+	lstcon_tsb_hdr_t	bat_hdr;	/* test_batch header */
+	struct list_head	      bat_link;       /* chain on session's batches list */
+	int		     bat_ntest;      /* # of test */
+	int		     bat_state;      /* state of the batch */
+	int		     bat_arg;	/* parameter for run|stop, timeout for run, force for stop */
+	char		    bat_name[LST_NAME_SIZE]; /* name of batch */
+
+	struct list_head	      bat_test_list;  /* list head of tests (lstcon_test_t) */
+	struct list_head	      bat_trans_list; /* list head of transaction */
+	struct list_head	      bat_cli_list;   /* list head of client nodes (lstcon_node_t) */
+	struct list_head	     *bat_cli_hash;   /* hash table of client nodes */
+	struct list_head	      bat_srv_list;   /* list head of server nodes */
+	struct list_head	     *bat_srv_hash;   /* hash table of server nodes */
+} lstcon_batch_t;			     /*** (tests ) batch descritptor */
+
+typedef struct lstcon_test {
+	lstcon_tsb_hdr_t      tes_hdr;	/* test batch header */
+	struct list_head	    tes_link;       /* chain on batch's tests list */
+	lstcon_batch_t       *tes_batch;      /* pointer to batch */
+
+	int		   tes_type;       /* type of the test, i.e: bulk, ping */
+	int		   tes_stop_onerr; /* stop on error */
+	int		   tes_oneside;    /* one-sided test */
+	int		   tes_concur;     /* concurrency */
+	int		   tes_loop;       /* loop count */
+	int		   tes_dist;       /* nodes distribution of target group */
+	int		   tes_span;       /* nodes span of target group */
+	int		   tes_cliidx;     /* client index, used for RPC creating */
+
+	struct list_head  tes_trans_list; /* transaction list */
+	lstcon_group_t       *tes_src_grp;    /* group run the test */
+	lstcon_group_t       *tes_dst_grp;    /* target group */
+
+	int		   tes_paramlen;   /* test parameter length */
+	char		  tes_param[0];   /* test parameter */
+} lstcon_test_t;				/*** a single test descriptor */
+
+#define LST_GLOBAL_HASHSIZE     503	     /* global nodes hash table size */
+#define LST_NODE_HASHSIZE       239	     /* node hash table (for batch or group) */
+
+#define LST_SESSION_NONE	0x0	     /* no session */
+#define LST_SESSION_ACTIVE      0x1	     /* working session */
+
+#define LST_CONSOLE_TIMEOUT     300	     /* default console timeout */
+
+typedef struct {
+	struct mutex		ses_mutex;      /* only 1 thread in session */
+	lst_sid_t	       ses_id;	 /* global session id */
+	int		     ses_key;	/* local session key */
+	int		     ses_state;      /* state of session */
+	int		     ses_timeout;    /* timeout in seconds */
+	time_t		  ses_laststamp;  /* last operation stamp (seconds) */
+	/** tests features of the session */
+	unsigned		ses_features;
+	/** features are synced with remote test nodes */
+	unsigned		ses_feats_updated:1;
+	/** force creating */
+	unsigned		ses_force:1;
+	/** session is shutting down */
+	unsigned		ses_shutdown:1;
+	/** console is timedout */
+	unsigned		ses_expired:1;
+	__u64		   ses_id_cookie;  /* batch id cookie */
+	char		    ses_name[LST_NAME_SIZE];  /* session name */
+	lstcon_rpc_trans_t     *ses_ping;       /* session pinger */
+	stt_timer_t	     ses_ping_timer; /* timer for pinger */
+	lstcon_trans_stat_t     ses_trans_stat; /* transaction stats */
+
+	struct list_head	      ses_trans_list; /* global list of transaction */
+	struct list_head	      ses_grp_list;   /* global list of groups */
+	struct list_head	      ses_bat_list;   /* global list of batches */
+	struct list_head	      ses_ndl_list;   /* global list of nodes */
+	struct list_head	     *ses_ndl_hash;   /* hash table of nodes */
+
+	spinlock_t	  ses_rpc_lock;   /* serialize */
+	atomic_t	    ses_rpc_counter;/* # of initialized RPCs */
+	struct list_head	      ses_rpc_freelist; /* idle console rpc */
+} lstcon_session_t;			     /*** session descriptor */
+
+extern lstcon_session_t	 console_session;
+
+static inline lstcon_trans_stat_t *
+lstcon_trans_stat(void)
+{
+	return &console_session.ses_trans_stat;
+}
+
+static inline struct list_head *
+lstcon_id2hash (lnet_process_id_t id, struct list_head *hash)
+{
+	unsigned int idx = LNET_NIDADDR(id.nid) % LST_NODE_HASHSIZE;
+
+	return &hash[idx];
+}
+
+extern int lstcon_session_match(lst_sid_t sid);
+extern int lstcon_session_new(char *name, int key, unsigned version,
+			      int timeout, int flags, lst_sid_t *sid_up);
+extern int lstcon_session_info(lst_sid_t *sid_up, int *key, unsigned *verp,
+			       lstcon_ndlist_ent_t *entp, char *name_up, int len);
+extern int lstcon_session_end(void);
+extern int lstcon_session_debug(int timeout, struct list_head *result_up);
+extern int lstcon_session_feats_check(unsigned feats);
+extern int lstcon_batch_debug(int timeout, char *name,
+			      int client, struct list_head *result_up);
+extern int lstcon_group_debug(int timeout, char *name,
+			      struct list_head *result_up);
+extern int lstcon_nodes_debug(int timeout, int nnd, lnet_process_id_t *nds_up,
+			      struct list_head *result_up);
+extern int lstcon_group_add(char *name);
+extern int lstcon_group_del(char *name);
+extern int lstcon_group_clean(char *name, int args);
+extern int lstcon_group_refresh(char *name, struct list_head *result_up);
+extern int lstcon_nodes_add(char *name, int nnd, lnet_process_id_t *nds_up,
+			    unsigned *featp, struct list_head *result_up);
+extern int lstcon_nodes_remove(char *name, int nnd, lnet_process_id_t *nds_up,
+			       struct list_head *result_up);
+extern int lstcon_group_info(char *name, lstcon_ndlist_ent_t *gent_up,
+			     int *index_p, int *ndent_p, lstcon_node_ent_t *ndents_up);
+extern int lstcon_group_list(int idx, int len, char *name_up);
+extern int lstcon_batch_add(char *name);
+extern int lstcon_batch_run(char *name, int timeout,
+			    struct list_head *result_up);
+extern int lstcon_batch_stop(char *name, int force,
+			     struct list_head *result_up);
+extern int lstcon_test_batch_query(char *name, int testidx,
+				   int client, int timeout,
+				   struct list_head *result_up);
+extern int lstcon_batch_del(char *name);
+extern int lstcon_batch_list(int idx, int namelen, char *name_up);
+extern int lstcon_batch_info(char *name, lstcon_test_batch_ent_t *ent_up,
+			     int server, int testidx, int *index_p,
+			     int *ndent_p, lstcon_node_ent_t *dents_up);
+extern int lstcon_group_stat(char *grp_name, int timeout,
+			     struct list_head *result_up);
+extern int lstcon_nodes_stat(int count, lnet_process_id_t *ids_up,
+			     int timeout, struct list_head *result_up);
+extern int lstcon_test_add(char *name, int type, int loop, int concur,
+			   int dist, int span, char *src_name, char * dst_name,
+			   void *param, int paramlen, int *retp,
+			   struct list_head *result_up);
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/framework.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/framework.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/framework.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/framework.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1814 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/framework.c
+ *
+ * Author: Isaac Huang <isaac@clusterfs.com>
+ * Author: Liang Zhen  <liangzhen@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include "selftest.h"
+
+lst_sid_t LST_INVALID_SID = {LNET_NID_ANY, -1};
+
+static int session_timeout = 100;
+CFS_MODULE_PARM(session_timeout, "i", int, 0444,
+		"test session timeout in seconds (100 by default, 0 == never)");
+
+static int rpc_timeout = 64;
+CFS_MODULE_PARM(rpc_timeout, "i", int, 0644,
+		"rpc timeout in seconds (64 by default, 0 == never)");
+
+#define sfw_unpack_id(id)	       \
+do {				    \
+	__swab64s(&(id).nid);	   \
+	__swab32s(&(id).pid);	   \
+} while (0)
+
+#define sfw_unpack_sid(sid)	     \
+do {				    \
+	__swab64s(&(sid).ses_nid);      \
+	__swab64s(&(sid).ses_stamp);    \
+} while (0)
+
+#define sfw_unpack_fw_counters(fc)	\
+do {				      \
+	__swab32s(&(fc).running_ms);      \
+	__swab32s(&(fc).active_batches);  \
+	__swab32s(&(fc).zombie_sessions); \
+	__swab32s(&(fc).brw_errors);      \
+	__swab32s(&(fc).ping_errors);     \
+} while (0)
+
+#define sfw_unpack_rpc_counters(rc)     \
+do {				    \
+	__swab32s(&(rc).errors);	\
+	__swab32s(&(rc).rpcs_sent);     \
+	__swab32s(&(rc).rpcs_rcvd);     \
+	__swab32s(&(rc).rpcs_dropped);  \
+	__swab32s(&(rc).rpcs_expired);  \
+	__swab64s(&(rc).bulk_get);      \
+	__swab64s(&(rc).bulk_put);      \
+} while (0)
+
+#define sfw_unpack_lnet_counters(lc)    \
+do {				    \
+	__swab32s(&(lc).errors);	\
+	__swab32s(&(lc).msgs_max);      \
+	__swab32s(&(lc).msgs_alloc);    \
+	__swab32s(&(lc).send_count);    \
+	__swab32s(&(lc).recv_count);    \
+	__swab32s(&(lc).drop_count);    \
+	__swab32s(&(lc).route_count);   \
+	__swab64s(&(lc).send_length);   \
+	__swab64s(&(lc).recv_length);   \
+	__swab64s(&(lc).drop_length);   \
+	__swab64s(&(lc).route_length);  \
+} while (0)
+
+#define sfw_test_active(t)      (atomic_read(&(t)->tsi_nactive) != 0)
+#define sfw_batch_active(b)     (atomic_read(&(b)->bat_nactive) != 0)
+
+struct smoketest_framework {
+	struct list_head	 fw_zombie_rpcs;     /* RPCs to be recycled */
+	struct list_head	 fw_zombie_sessions; /* stopping sessions */
+	struct list_head	 fw_tests;	   /* registered test cases */
+	atomic_t       fw_nzombies;	/* # zombie sessions */
+	spinlock_t	   fw_lock;		/* serialise */
+	sfw_session_t	  *fw_session;		/* _the_ session */
+	int		   fw_shuttingdown;	/* shutdown in progress */
+	srpc_server_rpc_t *fw_active_srpc;	/* running RPC */
+} sfw_data;
+
+/* forward ref's */
+int sfw_stop_batch (sfw_batch_t *tsb, int force);
+void sfw_destroy_session (sfw_session_t *sn);
+
+static inline sfw_test_case_t *
+sfw_find_test_case(int id)
+{
+	sfw_test_case_t *tsc;
+
+	LASSERT (id <= SRPC_SERVICE_MAX_ID);
+	LASSERT (id > SRPC_FRAMEWORK_SERVICE_MAX_ID);
+
+	list_for_each_entry (tsc, &sfw_data.fw_tests, tsc_list) {
+		if (tsc->tsc_srv_service->sv_id == id)
+			return tsc;
+	}
+
+	return NULL;
+}
+
+static int
+sfw_register_test (srpc_service_t *service, sfw_test_client_ops_t *cliops)
+{
+	sfw_test_case_t *tsc;
+
+	if (sfw_find_test_case(service->sv_id) != NULL) {
+		CERROR ("Failed to register test %s (%d)\n",
+			service->sv_name, service->sv_id);
+		return -EEXIST;
+	}
+
+	LIBCFS_ALLOC(tsc, sizeof(sfw_test_case_t));
+	if (tsc == NULL)
+		return -ENOMEM;
+
+	memset(tsc, 0, sizeof(sfw_test_case_t));
+	tsc->tsc_cli_ops     = cliops;
+	tsc->tsc_srv_service = service;
+
+	list_add_tail(&tsc->tsc_list, &sfw_data.fw_tests);
+	return 0;
+}
+
+void
+sfw_add_session_timer (void)
+{
+	sfw_session_t *sn = sfw_data.fw_session;
+	stt_timer_t   *timer = &sn->sn_timer;
+
+	LASSERT (!sfw_data.fw_shuttingdown);
+
+	if (sn == NULL || sn->sn_timeout == 0)
+		return;
+
+	LASSERT (!sn->sn_timer_active);
+
+	sn->sn_timer_active = 1;
+	timer->stt_expires = cfs_time_add(sn->sn_timeout,
+					  cfs_time_current_sec());
+	stt_add_timer(timer);
+	return;
+}
+
+int
+sfw_del_session_timer (void)
+{
+	sfw_session_t *sn = sfw_data.fw_session;
+
+	if (sn == NULL || !sn->sn_timer_active)
+		return 0;
+
+	LASSERT (sn->sn_timeout != 0);
+
+	if (stt_del_timer(&sn->sn_timer)) { /* timer defused */
+		sn->sn_timer_active = 0;
+		return 0;
+	}
+
+	return EBUSY; /* racing with sfw_session_expired() */
+}
+
+/* called with sfw_data.fw_lock held */
+static void
+sfw_deactivate_session (void)
+{
+	sfw_session_t *sn = sfw_data.fw_session;
+	int	    nactive = 0;
+	sfw_batch_t   *tsb;
+	sfw_test_case_t *tsc;
+
+	if (sn == NULL) return;
+
+	LASSERT (!sn->sn_timer_active);
+
+	sfw_data.fw_session = NULL;
+	atomic_inc(&sfw_data.fw_nzombies);
+	list_add(&sn->sn_list, &sfw_data.fw_zombie_sessions);
+
+	spin_unlock(&sfw_data.fw_lock);
+
+	list_for_each_entry(tsc, &sfw_data.fw_tests, tsc_list) {
+		srpc_abort_service(tsc->tsc_srv_service);
+	}
+
+	spin_lock(&sfw_data.fw_lock);
+
+	list_for_each_entry (tsb, &sn->sn_batches, bat_list) {
+		if (sfw_batch_active(tsb)) {
+			nactive++;
+			sfw_stop_batch(tsb, 1);
+		}
+	}
+
+	if (nactive != 0)
+		return;   /* wait for active batches to stop */
+
+	list_del_init(&sn->sn_list);
+	spin_unlock(&sfw_data.fw_lock);
+
+	sfw_destroy_session(sn);
+
+	spin_lock(&sfw_data.fw_lock);
+}
+
+
+void
+sfw_session_expired (void *data)
+{
+	sfw_session_t *sn = data;
+
+	spin_lock(&sfw_data.fw_lock);
+
+	LASSERT (sn->sn_timer_active);
+	LASSERT (sn == sfw_data.fw_session);
+
+	CWARN ("Session expired! sid: %s-"LPU64", name: %s\n",
+	       libcfs_nid2str(sn->sn_id.ses_nid),
+	       sn->sn_id.ses_stamp, &sn->sn_name[0]);
+
+	sn->sn_timer_active = 0;
+	sfw_deactivate_session();
+
+	spin_unlock(&sfw_data.fw_lock);
+}
+
+static inline void
+sfw_init_session(sfw_session_t *sn, lst_sid_t sid,
+		 unsigned features, const char *name)
+{
+	stt_timer_t *timer = &sn->sn_timer;
+
+	memset(sn, 0, sizeof(sfw_session_t));
+	INIT_LIST_HEAD(&sn->sn_list);
+	INIT_LIST_HEAD(&sn->sn_batches);
+	atomic_set(&sn->sn_refcount, 1);	/* +1 for caller */
+	atomic_set(&sn->sn_brw_errors, 0);
+	atomic_set(&sn->sn_ping_errors, 0);
+	strlcpy(&sn->sn_name[0], name, sizeof(sn->sn_name));
+
+	sn->sn_timer_active = 0;
+	sn->sn_id	   = sid;
+	sn->sn_features	    = features;
+	sn->sn_timeout      = session_timeout;
+	sn->sn_started      = cfs_time_current();
+
+	timer->stt_data = sn;
+	timer->stt_func = sfw_session_expired;
+	INIT_LIST_HEAD(&timer->stt_list);
+}
+
+/* completion handler for incoming framework RPCs */
+void
+sfw_server_rpc_done(struct srpc_server_rpc *rpc)
+{
+	struct srpc_service	*sv	= rpc->srpc_scd->scd_svc;
+	int			status	= rpc->srpc_status;
+
+	CDEBUG (D_NET,
+		"Incoming framework RPC done: "
+		"service %s, peer %s, status %s:%d\n",
+		sv->sv_name, libcfs_id2str(rpc->srpc_peer),
+		swi_state2str(rpc->srpc_wi.swi_state),
+		status);
+
+	if (rpc->srpc_bulk != NULL)
+		sfw_free_pages(rpc);
+	return;
+}
+
+void
+sfw_client_rpc_fini (srpc_client_rpc_t *rpc)
+{
+	LASSERT (rpc->crpc_bulk.bk_niov == 0);
+	LASSERT (list_empty(&rpc->crpc_list));
+	LASSERT (atomic_read(&rpc->crpc_refcount) == 0);
+
+	CDEBUG (D_NET,
+		"Outgoing framework RPC done: "
+		"service %d, peer %s, status %s:%d:%d\n",
+		rpc->crpc_service, libcfs_id2str(rpc->crpc_dest),
+		swi_state2str(rpc->crpc_wi.swi_state),
+		rpc->crpc_aborted, rpc->crpc_status);
+
+	spin_lock(&sfw_data.fw_lock);
+
+	/* my callers must finish all RPCs before shutting me down */
+	LASSERT(!sfw_data.fw_shuttingdown);
+	list_add(&rpc->crpc_list, &sfw_data.fw_zombie_rpcs);
+
+	spin_unlock(&sfw_data.fw_lock);
+}
+
+sfw_batch_t *
+sfw_find_batch (lst_bid_t bid)
+{
+	sfw_session_t *sn = sfw_data.fw_session;
+	sfw_batch_t   *bat;
+
+	LASSERT (sn != NULL);
+
+	list_for_each_entry (bat, &sn->sn_batches, bat_list) {
+		if (bat->bat_id.bat_id == bid.bat_id)
+			return bat;
+	}
+
+	return NULL;
+}
+
+sfw_batch_t *
+sfw_bid2batch (lst_bid_t bid)
+{
+	sfw_session_t *sn = sfw_data.fw_session;
+	sfw_batch_t   *bat;
+
+	LASSERT (sn != NULL);
+
+	bat = sfw_find_batch(bid);
+	if (bat != NULL)
+		return bat;
+
+	LIBCFS_ALLOC(bat, sizeof(sfw_batch_t));
+	if (bat == NULL)
+		return NULL;
+
+	bat->bat_error    = 0;
+	bat->bat_session  = sn;
+	bat->bat_id       = bid;
+	atomic_set(&bat->bat_nactive, 0);
+	INIT_LIST_HEAD(&bat->bat_tests);
+
+	list_add_tail(&bat->bat_list, &sn->sn_batches);
+	return bat;
+}
+
+int
+sfw_get_stats (srpc_stat_reqst_t *request, srpc_stat_reply_t *reply)
+{
+	sfw_session_t  *sn = sfw_data.fw_session;
+	sfw_counters_t *cnt = &reply->str_fw;
+	sfw_batch_t    *bat;
+	struct timeval  tv;
+
+	reply->str_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;
+
+	if (request->str_sid.ses_nid == LNET_NID_ANY) {
+		reply->str_status = EINVAL;
+		return 0;
+	}
+
+	if (sn == NULL || !sfw_sid_equal(request->str_sid, sn->sn_id)) {
+		reply->str_status = ESRCH;
+		return 0;
+	}
+
+	lnet_counters_get(&reply->str_lnet);
+	srpc_get_counters(&reply->str_rpc);
+
+	/* send over the msecs since the session was started
+	 - with 32 bits to send, this is ~49 days */
+	cfs_duration_usec(cfs_time_sub(cfs_time_current(),
+				       sn->sn_started), &tv);
+
+	cnt->running_ms      = (__u32)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
+	cnt->brw_errors      = atomic_read(&sn->sn_brw_errors);
+	cnt->ping_errors     = atomic_read(&sn->sn_ping_errors);
+	cnt->zombie_sessions = atomic_read(&sfw_data.fw_nzombies);
+
+	cnt->active_batches = 0;
+	list_for_each_entry (bat, &sn->sn_batches, bat_list) {
+		if (atomic_read(&bat->bat_nactive) > 0)
+			cnt->active_batches++;
+	}
+
+	reply->str_status = 0;
+	return 0;
+}
+
+int
+sfw_make_session(srpc_mksn_reqst_t *request, srpc_mksn_reply_t *reply)
+{
+	sfw_session_t *sn = sfw_data.fw_session;
+	srpc_msg_t    *msg = container_of(request, srpc_msg_t,
+					  msg_body.mksn_reqst);
+	int	       cplen = 0;
+
+	if (request->mksn_sid.ses_nid == LNET_NID_ANY) {
+		reply->mksn_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;
+		reply->mksn_status = EINVAL;
+		return 0;
+	}
+
+	if (sn != NULL) {
+		reply->mksn_status  = 0;
+		reply->mksn_sid     = sn->sn_id;
+		reply->mksn_timeout = sn->sn_timeout;
+
+		if (sfw_sid_equal(request->mksn_sid, sn->sn_id)) {
+			atomic_inc(&sn->sn_refcount);
+			return 0;
+		}
+
+		if (!request->mksn_force) {
+			reply->mksn_status = EBUSY;
+			cplen = strlcpy(&reply->mksn_name[0], &sn->sn_name[0],
+					sizeof(reply->mksn_name));
+			if (cplen >= sizeof(reply->mksn_name))
+				return -E2BIG;
+			return 0;
+		}
+	}
+
+	/* reject the request if it requires unknown features
+	 * NB: old version will always accept all features because it's not
+	 * aware of srpc_msg_t::msg_ses_feats, it's a defect but it's also
+	 * harmless because it will return zero feature to console, and it's
+	 * console's responsibility to make sure all nodes in a session have
+	 * same feature mask. */
+	if ((msg->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
+		reply->mksn_status = EPROTO;
+		return 0;
+	}
+
+	/* brand new or create by force */
+	LIBCFS_ALLOC(sn, sizeof(sfw_session_t));
+	if (sn == NULL) {
+		CERROR ("Dropping RPC (mksn) under memory pressure.\n");
+		return -ENOMEM;
+	}
+
+	sfw_init_session(sn, request->mksn_sid,
+			 msg->msg_ses_feats, &request->mksn_name[0]);
+
+	spin_lock(&sfw_data.fw_lock);
+
+	sfw_deactivate_session();
+	LASSERT(sfw_data.fw_session == NULL);
+	sfw_data.fw_session = sn;
+
+	spin_unlock(&sfw_data.fw_lock);
+
+	reply->mksn_status  = 0;
+	reply->mksn_sid     = sn->sn_id;
+	reply->mksn_timeout = sn->sn_timeout;
+	return 0;
+}
+
+int
+sfw_remove_session (srpc_rmsn_reqst_t *request, srpc_rmsn_reply_t *reply)
+{
+	sfw_session_t *sn = sfw_data.fw_session;
+
+	reply->rmsn_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;
+
+	if (request->rmsn_sid.ses_nid == LNET_NID_ANY) {
+		reply->rmsn_status = EINVAL;
+		return 0;
+	}
+
+	if (sn == NULL || !sfw_sid_equal(request->rmsn_sid, sn->sn_id)) {
+		reply->rmsn_status = (sn == NULL) ? ESRCH : EBUSY;
+		return 0;
+	}
+
+	if (!atomic_dec_and_test(&sn->sn_refcount)) {
+		reply->rmsn_status = 0;
+		return 0;
+	}
+
+	spin_lock(&sfw_data.fw_lock);
+	sfw_deactivate_session();
+	spin_unlock(&sfw_data.fw_lock);
+
+	reply->rmsn_status = 0;
+	reply->rmsn_sid    = LST_INVALID_SID;
+	LASSERT(sfw_data.fw_session == NULL);
+	return 0;
+}
+
+int
+sfw_debug_session (srpc_debug_reqst_t *request, srpc_debug_reply_t *reply)
+{
+	sfw_session_t *sn = sfw_data.fw_session;
+
+	if (sn == NULL) {
+		reply->dbg_status = ESRCH;
+		reply->dbg_sid    = LST_INVALID_SID;
+		return 0;
+	}
+
+	reply->dbg_status  = 0;
+	reply->dbg_sid     = sn->sn_id;
+	reply->dbg_timeout = sn->sn_timeout;
+	if (strlcpy(reply->dbg_name, &sn->sn_name[0], sizeof(reply->dbg_name))
+	    >= sizeof(reply->dbg_name))
+		return -E2BIG;
+
+	return 0;
+}
+
+void
+sfw_test_rpc_fini (srpc_client_rpc_t *rpc)
+{
+	sfw_test_unit_t     *tsu = rpc->crpc_priv;
+	sfw_test_instance_t *tsi = tsu->tsu_instance;
+
+	/* Called with hold of tsi->tsi_lock */
+	LASSERT (list_empty(&rpc->crpc_list));
+	list_add(&rpc->crpc_list, &tsi->tsi_free_rpcs);
+}
+
+static inline int
+sfw_test_buffers(sfw_test_instance_t *tsi)
+{
+	struct sfw_test_case	*tsc = sfw_find_test_case(tsi->tsi_service);
+	struct srpc_service	*svc = tsc->tsc_srv_service;
+	int			nbuf;
+
+	nbuf = min(svc->sv_wi_total, tsi->tsi_loop) / svc->sv_ncpts;
+	return max(SFW_TEST_WI_MIN, nbuf + SFW_TEST_WI_EXTRA);
+}
+
+int
+sfw_load_test(struct sfw_test_instance *tsi)
+{
+	struct sfw_test_case	*tsc;
+	struct srpc_service	*svc;
+	int			nbuf;
+	int			rc;
+
+	LASSERT(tsi != NULL);
+	tsc = sfw_find_test_case(tsi->tsi_service);
+	nbuf = sfw_test_buffers(tsi);
+	LASSERT(tsc != NULL);
+	svc = tsc->tsc_srv_service;
+
+	if (tsi->tsi_is_client) {
+		tsi->tsi_ops = tsc->tsc_cli_ops;
+		return 0;
+	}
+
+	rc = srpc_service_add_buffers(svc, nbuf);
+	if (rc != 0) {
+		CWARN("Failed to reserve enough buffers: "
+		      "service %s, %d needed: %d\n", svc->sv_name, nbuf, rc);
+		/* NB: this error handler is not strictly correct, because
+		 * it may release more buffers than already allocated,
+		 * but it doesn't matter because request portal should
+		 * be lazy portal and will grow buffers if necessary. */
+		srpc_service_remove_buffers(svc, nbuf);
+		return -ENOMEM;
+	}
+
+	CDEBUG(D_NET, "Reserved %d buffers for test %s\n",
+	       nbuf * (srpc_serv_is_framework(svc) ?
+		       1 : cfs_cpt_number(cfs_cpt_table)), svc->sv_name);
+	return 0;
+}
+
+void
+sfw_unload_test(struct sfw_test_instance *tsi)
+{
+	struct sfw_test_case *tsc = sfw_find_test_case(tsi->tsi_service);
+
+	LASSERT(tsc != NULL);
+
+	if (tsi->tsi_is_client)
+		return;
+
+	/* shrink buffers, because request portal is lazy portal
+	 * which can grow buffers at runtime so we may leave
+	 * some buffers behind, but never mind... */
+	srpc_service_remove_buffers(tsc->tsc_srv_service,
+				    sfw_test_buffers(tsi));
+	return;
+}
+
+void
+sfw_destroy_test_instance (sfw_test_instance_t *tsi)
+{
+	srpc_client_rpc_t *rpc;
+	sfw_test_unit_t   *tsu;
+
+	if (!tsi->tsi_is_client) goto clean;
+
+	tsi->tsi_ops->tso_fini(tsi);
+
+	LASSERT (!tsi->tsi_stopping);
+	LASSERT (list_empty(&tsi->tsi_active_rpcs));
+	LASSERT (!sfw_test_active(tsi));
+
+	while (!list_empty(&tsi->tsi_units)) {
+		tsu = list_entry(tsi->tsi_units.next,
+				     sfw_test_unit_t, tsu_list);
+		list_del(&tsu->tsu_list);
+		LIBCFS_FREE(tsu, sizeof(*tsu));
+	}
+
+	while (!list_empty(&tsi->tsi_free_rpcs)) {
+		rpc = list_entry(tsi->tsi_free_rpcs.next,
+				     srpc_client_rpc_t, crpc_list);
+		list_del(&rpc->crpc_list);
+		LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc));
+	}
+
+clean:
+	sfw_unload_test(tsi);
+	LIBCFS_FREE(tsi, sizeof(*tsi));
+	return;
+}
+
+void
+sfw_destroy_batch (sfw_batch_t *tsb)
+{
+	sfw_test_instance_t *tsi;
+
+	LASSERT (!sfw_batch_active(tsb));
+	LASSERT (list_empty(&tsb->bat_list));
+
+	while (!list_empty(&tsb->bat_tests)) {
+		tsi = list_entry(tsb->bat_tests.next,
+				     sfw_test_instance_t, tsi_list);
+		list_del_init(&tsi->tsi_list);
+		sfw_destroy_test_instance(tsi);
+	}
+
+	LIBCFS_FREE(tsb, sizeof(sfw_batch_t));
+	return;
+}
+
+void
+sfw_destroy_session (sfw_session_t *sn)
+{
+	sfw_batch_t *batch;
+
+	LASSERT (list_empty(&sn->sn_list));
+	LASSERT (sn != sfw_data.fw_session);
+
+	while (!list_empty(&sn->sn_batches)) {
+		batch = list_entry(sn->sn_batches.next,
+				       sfw_batch_t, bat_list);
+		list_del_init(&batch->bat_list);
+		sfw_destroy_batch(batch);
+	}
+
+	LIBCFS_FREE(sn, sizeof(*sn));
+	atomic_dec(&sfw_data.fw_nzombies);
+	return;
+}
+
+void
+sfw_unpack_addtest_req(srpc_msg_t *msg)
+{
+	srpc_test_reqst_t *req = &msg->msg_body.tes_reqst;
+
+	LASSERT (msg->msg_type == SRPC_MSG_TEST_REQST);
+	LASSERT (req->tsr_is_client);
+
+	if (msg->msg_magic == SRPC_MSG_MAGIC)
+		return; /* no flipping needed */
+
+	LASSERT (msg->msg_magic == __swab32(SRPC_MSG_MAGIC));
+
+	if (req->tsr_service == SRPC_SERVICE_BRW) {
+		if ((msg->msg_ses_feats & LST_FEAT_BULK_LEN) == 0) {
+			test_bulk_req_t *bulk = &req->tsr_u.bulk_v0;
+
+			__swab32s(&bulk->blk_opc);
+			__swab32s(&bulk->blk_npg);
+			__swab32s(&bulk->blk_flags);
+
+		} else {
+			test_bulk_req_v1_t *bulk = &req->tsr_u.bulk_v1;
+
+			__swab16s(&bulk->blk_opc);
+			__swab16s(&bulk->blk_flags);
+			__swab32s(&bulk->blk_offset);
+			__swab32s(&bulk->blk_len);
+		}
+
+		return;
+	}
+
+	if (req->tsr_service == SRPC_SERVICE_PING) {
+		test_ping_req_t *ping = &req->tsr_u.ping;
+
+		__swab32s(&ping->png_size);
+		__swab32s(&ping->png_flags);
+		return;
+	}
+
+	LBUG ();
+	return;
+}
+
+int
+sfw_add_test_instance (sfw_batch_t *tsb, srpc_server_rpc_t *rpc)
+{
+	srpc_msg_t	  *msg = &rpc->srpc_reqstbuf->buf_msg;
+	srpc_test_reqst_t   *req = &msg->msg_body.tes_reqst;
+	srpc_bulk_t	 *bk = rpc->srpc_bulk;
+	int		  ndest = req->tsr_ndest;
+	sfw_test_unit_t     *tsu;
+	sfw_test_instance_t *tsi;
+	int		  i;
+	int		  rc;
+
+	LIBCFS_ALLOC(tsi, sizeof(*tsi));
+	if (tsi == NULL) {
+		CERROR ("Can't allocate test instance for batch: "LPU64"\n",
+			tsb->bat_id.bat_id);
+		return -ENOMEM;
+	}
+
+	memset(tsi, 0, sizeof(*tsi));
+	spin_lock_init(&tsi->tsi_lock);
+	atomic_set(&tsi->tsi_nactive, 0);
+	INIT_LIST_HEAD(&tsi->tsi_units);
+	INIT_LIST_HEAD(&tsi->tsi_free_rpcs);
+	INIT_LIST_HEAD(&tsi->tsi_active_rpcs);
+
+	tsi->tsi_stopping      = 0;
+	tsi->tsi_batch	 = tsb;
+	tsi->tsi_loop	  = req->tsr_loop;
+	tsi->tsi_concur	= req->tsr_concur;
+	tsi->tsi_service       = req->tsr_service;
+	tsi->tsi_is_client     = !!(req->tsr_is_client);
+	tsi->tsi_stoptsu_onerr = !!(req->tsr_stop_onerr);
+
+	rc = sfw_load_test(tsi);
+	if (rc != 0) {
+		LIBCFS_FREE(tsi, sizeof(*tsi));
+		return rc;
+	}
+
+	LASSERT (!sfw_batch_active(tsb));
+
+	if (!tsi->tsi_is_client) {
+		/* it's test server, just add it to tsb */
+		list_add_tail(&tsi->tsi_list, &tsb->bat_tests);
+		return 0;
+	}
+
+	LASSERT (bk != NULL);
+	LASSERT (bk->bk_niov * SFW_ID_PER_PAGE >= (unsigned int)ndest);
+	LASSERT((unsigned int)bk->bk_len >=
+		sizeof(lnet_process_id_packed_t) * ndest);
+
+	sfw_unpack_addtest_req(msg);
+	memcpy(&tsi->tsi_u, &req->tsr_u, sizeof(tsi->tsi_u));
+
+	for (i = 0; i < ndest; i++) {
+		lnet_process_id_packed_t *dests;
+		lnet_process_id_packed_t  id;
+		int		       j;
+
+		dests = page_address(bk->bk_iovs[i / SFW_ID_PER_PAGE].kiov_page);
+		LASSERT (dests != NULL);  /* my pages are within KVM always */
+		id = dests[i % SFW_ID_PER_PAGE];
+		if (msg->msg_magic != SRPC_MSG_MAGIC)
+			sfw_unpack_id(id);
+
+		for (j = 0; j < tsi->tsi_concur; j++) {
+			LIBCFS_ALLOC(tsu, sizeof(sfw_test_unit_t));
+			if (tsu == NULL) {
+				rc = -ENOMEM;
+				CERROR ("Can't allocate tsu for %d\n",
+					tsi->tsi_service);
+				goto error;
+			}
+
+			tsu->tsu_dest.nid = id.nid;
+			tsu->tsu_dest.pid = id.pid;
+			tsu->tsu_instance = tsi;
+			tsu->tsu_private  = NULL;
+			list_add_tail(&tsu->tsu_list, &tsi->tsi_units);
+		}
+	}
+
+	rc = tsi->tsi_ops->tso_init(tsi);
+	if (rc == 0) {
+		list_add_tail(&tsi->tsi_list, &tsb->bat_tests);
+		return 0;
+	}
+
+error:
+	LASSERT (rc != 0);
+	sfw_destroy_test_instance(tsi);
+	return rc;
+}
+
+static void
+sfw_test_unit_done (sfw_test_unit_t *tsu)
+{
+	sfw_test_instance_t *tsi = tsu->tsu_instance;
+	sfw_batch_t	 *tsb = tsi->tsi_batch;
+	sfw_session_t       *sn = tsb->bat_session;
+
+	LASSERT (sfw_test_active(tsi));
+
+	if (!atomic_dec_and_test(&tsi->tsi_nactive))
+		return;
+
+	/* the test instance is done */
+	spin_lock(&tsi->tsi_lock);
+
+	tsi->tsi_stopping = 0;
+
+	spin_unlock(&tsi->tsi_lock);
+
+	spin_lock(&sfw_data.fw_lock);
+
+	if (!atomic_dec_and_test(&tsb->bat_nactive) ||/* tsb still active */
+	    sn == sfw_data.fw_session) {		  /* sn also active */
+		spin_unlock(&sfw_data.fw_lock);
+		return;
+	}
+
+	LASSERT (!list_empty(&sn->sn_list)); /* I'm a zombie! */
+
+	list_for_each_entry (tsb, &sn->sn_batches, bat_list) {
+		if (sfw_batch_active(tsb)) {
+			spin_unlock(&sfw_data.fw_lock);
+			return;
+		}
+	}
+
+	list_del_init(&sn->sn_list);
+	spin_unlock(&sfw_data.fw_lock);
+
+	sfw_destroy_session(sn);
+	return;
+}
+
+void
+sfw_test_rpc_done (srpc_client_rpc_t *rpc)
+{
+	sfw_test_unit_t     *tsu = rpc->crpc_priv;
+	sfw_test_instance_t *tsi = tsu->tsu_instance;
+	int		  done = 0;
+
+	tsi->tsi_ops->tso_done_rpc(tsu, rpc);
+
+	spin_lock(&tsi->tsi_lock);
+
+	LASSERT (sfw_test_active(tsi));
+	LASSERT (!list_empty(&rpc->crpc_list));
+
+	list_del_init(&rpc->crpc_list);
+
+	/* batch is stopping or loop is done or get error */
+	if (tsi->tsi_stopping ||
+	    tsu->tsu_loop == 0 ||
+	    (rpc->crpc_status != 0 && tsi->tsi_stoptsu_onerr))
+		done = 1;
+
+	/* dec ref for poster */
+	srpc_client_rpc_decref(rpc);
+
+	spin_unlock(&tsi->tsi_lock);
+
+	if (!done) {
+		swi_schedule_workitem(&tsu->tsu_worker);
+		return;
+	}
+
+	sfw_test_unit_done(tsu);
+	return;
+}
+
+int
+sfw_create_test_rpc(sfw_test_unit_t *tsu, lnet_process_id_t peer,
+		    unsigned features, int nblk, int blklen,
+		    srpc_client_rpc_t **rpcpp)
+{
+	srpc_client_rpc_t   *rpc = NULL;
+	sfw_test_instance_t *tsi = tsu->tsu_instance;
+
+	spin_lock(&tsi->tsi_lock);
+
+	LASSERT (sfw_test_active(tsi));
+
+	if (!list_empty(&tsi->tsi_free_rpcs)) {
+		/* pick request from buffer */
+		rpc = list_entry(tsi->tsi_free_rpcs.next,
+				     srpc_client_rpc_t, crpc_list);
+		LASSERT (nblk == rpc->crpc_bulk.bk_niov);
+		list_del_init(&rpc->crpc_list);
+	}
+
+	spin_unlock(&tsi->tsi_lock);
+
+	if (rpc == NULL) {
+		rpc = srpc_create_client_rpc(peer, tsi->tsi_service, nblk,
+					     blklen, sfw_test_rpc_done,
+					     sfw_test_rpc_fini, tsu);
+	} else {
+		srpc_init_client_rpc(rpc, peer, tsi->tsi_service, nblk,
+				     blklen, sfw_test_rpc_done,
+				     sfw_test_rpc_fini, tsu);
+	}
+
+	if (rpc == NULL) {
+		CERROR("Can't create rpc for test %d\n", tsi->tsi_service);
+		return -ENOMEM;
+	}
+
+	rpc->crpc_reqstmsg.msg_ses_feats = features;
+	*rpcpp = rpc;
+
+	return 0;
+}
+
+int
+sfw_run_test (swi_workitem_t *wi)
+{
+	sfw_test_unit_t     *tsu = wi->swi_workitem.wi_data;
+	sfw_test_instance_t *tsi = tsu->tsu_instance;
+	srpc_client_rpc_t   *rpc = NULL;
+
+	LASSERT (wi == &tsu->tsu_worker);
+
+	if (tsi->tsi_ops->tso_prep_rpc(tsu, tsu->tsu_dest, &rpc) != 0) {
+		LASSERT (rpc == NULL);
+		goto test_done;
+	}
+
+	LASSERT (rpc != NULL);
+
+	spin_lock(&tsi->tsi_lock);
+
+	if (tsi->tsi_stopping) {
+		list_add(&rpc->crpc_list, &tsi->tsi_free_rpcs);
+		spin_unlock(&tsi->tsi_lock);
+		goto test_done;
+	}
+
+	if (tsu->tsu_loop > 0)
+		tsu->tsu_loop--;
+
+	list_add_tail(&rpc->crpc_list, &tsi->tsi_active_rpcs);
+	spin_unlock(&tsi->tsi_lock);
+
+	rpc->crpc_timeout = rpc_timeout;
+
+	spin_lock(&rpc->crpc_lock);
+	srpc_post_rpc(rpc);
+	spin_unlock(&rpc->crpc_lock);
+	return 0;
+
+test_done:
+	/*
+	 * No one can schedule me now since:
+	 * - previous RPC, if any, has done and
+	 * - no new RPC is initiated.
+	 * - my batch is still active; no one can run it again now.
+	 * Cancel pending schedules and prevent future schedule attempts:
+	 */
+	swi_exit_workitem(wi);
+	sfw_test_unit_done(tsu);
+	return 1;
+}
+
+int
+sfw_run_batch (sfw_batch_t *tsb)
+{
+	swi_workitem_t      *wi;
+	sfw_test_unit_t     *tsu;
+	sfw_test_instance_t *tsi;
+
+	if (sfw_batch_active(tsb)) {
+		CDEBUG(D_NET, "Batch already active: "LPU64" (%d)\n",
+		       tsb->bat_id.bat_id, atomic_read(&tsb->bat_nactive));
+		return 0;
+	}
+
+	list_for_each_entry (tsi, &tsb->bat_tests, tsi_list) {
+		if (!tsi->tsi_is_client) /* skip server instances */
+			continue;
+
+		LASSERT (!tsi->tsi_stopping);
+		LASSERT (!sfw_test_active(tsi));
+
+		atomic_inc(&tsb->bat_nactive);
+
+		list_for_each_entry (tsu, &tsi->tsi_units, tsu_list) {
+			atomic_inc(&tsi->tsi_nactive);
+			tsu->tsu_loop = tsi->tsi_loop;
+			wi = &tsu->tsu_worker;
+			swi_init_workitem(wi, tsu, sfw_run_test,
+					  lst_sched_test[\
+					  lnet_cpt_of_nid(tsu->tsu_dest.nid)]);
+			swi_schedule_workitem(wi);
+		}
+	}
+
+	return 0;
+}
+
+int
+sfw_stop_batch (sfw_batch_t *tsb, int force)
+{
+	sfw_test_instance_t *tsi;
+	srpc_client_rpc_t   *rpc;
+
+	if (!sfw_batch_active(tsb)) {
+		CDEBUG(D_NET, "Batch "LPU64" inactive\n", tsb->bat_id.bat_id);
+		return 0;
+	}
+
+	list_for_each_entry (tsi, &tsb->bat_tests, tsi_list) {
+		spin_lock(&tsi->tsi_lock);
+
+		if (!tsi->tsi_is_client ||
+		    !sfw_test_active(tsi) || tsi->tsi_stopping) {
+			spin_unlock(&tsi->tsi_lock);
+			continue;
+		}
+
+		tsi->tsi_stopping = 1;
+
+		if (!force) {
+			spin_unlock(&tsi->tsi_lock);
+			continue;
+		}
+
+		/* abort launched rpcs in the test */
+		list_for_each_entry(rpc, &tsi->tsi_active_rpcs, crpc_list) {
+			spin_lock(&rpc->crpc_lock);
+
+			srpc_abort_rpc(rpc, -EINTR);
+
+			spin_unlock(&rpc->crpc_lock);
+		}
+
+		spin_unlock(&tsi->tsi_lock);
+	}
+
+	return 0;
+}
+
+int
+sfw_query_batch (sfw_batch_t *tsb, int testidx, srpc_batch_reply_t *reply)
+{
+	sfw_test_instance_t *tsi;
+
+	if (testidx < 0)
+		return -EINVAL;
+
+	if (testidx == 0) {
+		reply->bar_active = atomic_read(&tsb->bat_nactive);
+		return 0;
+	}
+
+	list_for_each_entry (tsi, &tsb->bat_tests, tsi_list) {
+		if (testidx-- > 1)
+			continue;
+
+		reply->bar_active = atomic_read(&tsi->tsi_nactive);
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+void
+sfw_free_pages (srpc_server_rpc_t *rpc)
+{
+	srpc_free_bulk(rpc->srpc_bulk);
+	rpc->srpc_bulk = NULL;
+}
+
+int
+sfw_alloc_pages(struct srpc_server_rpc *rpc, int cpt, int npages, int len,
+		int sink)
+{
+	LASSERT(rpc->srpc_bulk == NULL);
+	LASSERT(npages > 0 && npages <= LNET_MAX_IOV);
+
+	rpc->srpc_bulk = srpc_alloc_bulk(cpt, npages, len, sink);
+	if (rpc->srpc_bulk == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+int
+sfw_add_test (srpc_server_rpc_t *rpc)
+{
+	sfw_session_t     *sn = sfw_data.fw_session;
+	srpc_test_reply_t *reply = &rpc->srpc_replymsg.msg_body.tes_reply;
+	srpc_test_reqst_t *request;
+	int		rc;
+	sfw_batch_t       *bat;
+
+	request = &rpc->srpc_reqstbuf->buf_msg.msg_body.tes_reqst;
+	reply->tsr_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;
+
+	if (request->tsr_loop == 0 ||
+	    request->tsr_concur == 0 ||
+	    request->tsr_sid.ses_nid == LNET_NID_ANY ||
+	    request->tsr_ndest > SFW_MAX_NDESTS ||
+	    (request->tsr_is_client && request->tsr_ndest == 0) ||
+	    request->tsr_concur > SFW_MAX_CONCUR ||
+	    request->tsr_service > SRPC_SERVICE_MAX_ID ||
+	    request->tsr_service <= SRPC_FRAMEWORK_SERVICE_MAX_ID) {
+		reply->tsr_status = EINVAL;
+		return 0;
+	}
+
+	if (sn == NULL || !sfw_sid_equal(request->tsr_sid, sn->sn_id) ||
+	    sfw_find_test_case(request->tsr_service) == NULL) {
+		reply->tsr_status = ENOENT;
+		return 0;
+	}
+
+	bat = sfw_bid2batch(request->tsr_bid);
+	if (bat == NULL) {
+		CERROR ("Dropping RPC (%s) from %s under memory pressure.\n",
+			rpc->srpc_scd->scd_svc->sv_name,
+			libcfs_id2str(rpc->srpc_peer));
+		return -ENOMEM;
+	}
+
+	if (sfw_batch_active(bat)) {
+		reply->tsr_status = EBUSY;
+		return 0;
+	}
+
+	if (request->tsr_is_client && rpc->srpc_bulk == NULL) {
+		/* rpc will be resumed later in sfw_bulk_ready */
+		int	npg = sfw_id_pages(request->tsr_ndest);
+		int	len;
+
+		if ((sn->sn_features & LST_FEAT_BULK_LEN) == 0) {
+			len = npg * PAGE_CACHE_SIZE;
+
+		} else  {
+			len = sizeof(lnet_process_id_packed_t) *
+			      request->tsr_ndest;
+		}
+
+		return sfw_alloc_pages(rpc, CFS_CPT_ANY, npg, len, 1);
+	}
+
+	rc = sfw_add_test_instance(bat, rpc);
+	CDEBUG (rc == 0 ? D_NET : D_WARNING,
+		"%s test: sv %d %s, loop %d, concur %d, ndest %d\n",
+		rc == 0 ? "Added" : "Failed to add", request->tsr_service,
+		request->tsr_is_client ? "client" : "server",
+		request->tsr_loop, request->tsr_concur, request->tsr_ndest);
+
+	reply->tsr_status = (rc < 0) ? -rc : rc;
+	return 0;
+}
+
+int
+sfw_control_batch (srpc_batch_reqst_t *request, srpc_batch_reply_t *reply)
+{
+	sfw_session_t *sn = sfw_data.fw_session;
+	int	    rc = 0;
+	sfw_batch_t   *bat;
+
+	reply->bar_sid = (sn == NULL) ? LST_INVALID_SID : sn->sn_id;
+
+	if (sn == NULL || !sfw_sid_equal(request->bar_sid, sn->sn_id)) {
+		reply->bar_status = ESRCH;
+		return 0;
+	}
+
+	bat = sfw_find_batch(request->bar_bid);
+	if (bat == NULL) {
+		reply->bar_status = ENOENT;
+		return 0;
+	}
+
+	switch (request->bar_opc) {
+	case SRPC_BATCH_OPC_RUN:
+		rc = sfw_run_batch(bat);
+		break;
+
+	case SRPC_BATCH_OPC_STOP:
+		rc = sfw_stop_batch(bat, request->bar_arg);
+		break;
+
+	case SRPC_BATCH_OPC_QUERY:
+		rc = sfw_query_batch(bat, request->bar_testidx, reply);
+		break;
+
+	default:
+		return -EINVAL; /* drop it */
+	}
+
+	reply->bar_status = (rc < 0) ? -rc : rc;
+	return 0;
+}
+
+int
+sfw_handle_server_rpc(struct srpc_server_rpc *rpc)
+{
+	struct srpc_service	*sv = rpc->srpc_scd->scd_svc;
+	srpc_msg_t     *reply	= &rpc->srpc_replymsg;
+	srpc_msg_t     *request	= &rpc->srpc_reqstbuf->buf_msg;
+	unsigned	features = LST_FEATS_MASK;
+	int		rc = 0;
+
+	LASSERT(sfw_data.fw_active_srpc == NULL);
+	LASSERT(sv->sv_id <= SRPC_FRAMEWORK_SERVICE_MAX_ID);
+
+	spin_lock(&sfw_data.fw_lock);
+
+	if (sfw_data.fw_shuttingdown) {
+		spin_unlock(&sfw_data.fw_lock);
+		return -ESHUTDOWN;
+	}
+
+	/* Remove timer to avoid racing with it or expiring active session */
+	if (sfw_del_session_timer() != 0) {
+		CERROR("Dropping RPC (%s) from %s: racing with expiry timer.",
+		       sv->sv_name, libcfs_id2str(rpc->srpc_peer));
+		spin_unlock(&sfw_data.fw_lock);
+		return -EAGAIN;
+	}
+
+	sfw_data.fw_active_srpc = rpc;
+	spin_unlock(&sfw_data.fw_lock);
+
+	sfw_unpack_message(request);
+	LASSERT(request->msg_type == srpc_service2request(sv->sv_id));
+
+	/* rpc module should have checked this */
+	LASSERT(request->msg_version == SRPC_MSG_VERSION);
+
+	if (sv->sv_id != SRPC_SERVICE_MAKE_SESSION &&
+	    sv->sv_id != SRPC_SERVICE_DEBUG) {
+		sfw_session_t *sn = sfw_data.fw_session;
+
+		if (sn != NULL &&
+		    sn->sn_features != request->msg_ses_feats) {
+			CNETERR("Features of framework RPC don't match "
+				"features of current session: %x/%x\n",
+				request->msg_ses_feats, sn->sn_features);
+			reply->msg_body.reply.status = EPROTO;
+			reply->msg_body.reply.sid    = sn->sn_id;
+			goto out;
+		}
+
+	} else if ((request->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
+		/* NB: at this point, old version will ignore features and
+		 * create new session anyway, so console should be able
+		 * to handle this */
+		reply->msg_body.reply.status = EPROTO;
+		goto out;
+	}
+
+	switch(sv->sv_id) {
+	default:
+		LBUG ();
+	case SRPC_SERVICE_TEST:
+		rc = sfw_add_test(rpc);
+		break;
+
+	case SRPC_SERVICE_BATCH:
+		rc = sfw_control_batch(&request->msg_body.bat_reqst,
+				       &reply->msg_body.bat_reply);
+		break;
+
+	case SRPC_SERVICE_QUERY_STAT:
+		rc = sfw_get_stats(&request->msg_body.stat_reqst,
+				   &reply->msg_body.stat_reply);
+		break;
+
+	case SRPC_SERVICE_DEBUG:
+		rc = sfw_debug_session(&request->msg_body.dbg_reqst,
+				       &reply->msg_body.dbg_reply);
+		break;
+
+	case SRPC_SERVICE_MAKE_SESSION:
+		rc = sfw_make_session(&request->msg_body.mksn_reqst,
+				      &reply->msg_body.mksn_reply);
+		break;
+
+	case SRPC_SERVICE_REMOVE_SESSION:
+		rc = sfw_remove_session(&request->msg_body.rmsn_reqst,
+					&reply->msg_body.rmsn_reply);
+		break;
+	}
+
+	if (sfw_data.fw_session != NULL)
+		features = sfw_data.fw_session->sn_features;
+ out:
+	reply->msg_ses_feats = features;
+	rpc->srpc_done = sfw_server_rpc_done;
+	spin_lock(&sfw_data.fw_lock);
+
+	if (!sfw_data.fw_shuttingdown)
+		sfw_add_session_timer();
+
+	sfw_data.fw_active_srpc = NULL;
+	spin_unlock(&sfw_data.fw_lock);
+	return rc;
+}
+
+int
+sfw_bulk_ready(struct srpc_server_rpc *rpc, int status)
+{
+	struct srpc_service	*sv = rpc->srpc_scd->scd_svc;
+	int			rc;
+
+	LASSERT(rpc->srpc_bulk != NULL);
+	LASSERT(sv->sv_id == SRPC_SERVICE_TEST);
+	LASSERT(sfw_data.fw_active_srpc == NULL);
+	LASSERT(rpc->srpc_reqstbuf->buf_msg.msg_body.tes_reqst.tsr_is_client);
+
+	spin_lock(&sfw_data.fw_lock);
+
+	if (status != 0) {
+		CERROR("Bulk transfer failed for RPC: "
+		       "service %s, peer %s, status %d\n",
+		       sv->sv_name, libcfs_id2str(rpc->srpc_peer), status);
+		spin_unlock(&sfw_data.fw_lock);
+		return -EIO;
+	}
+
+	if (sfw_data.fw_shuttingdown) {
+		spin_unlock(&sfw_data.fw_lock);
+		return -ESHUTDOWN;
+	}
+
+	if (sfw_del_session_timer() != 0) {
+		CERROR("Dropping RPC (%s) from %s: racing with expiry timer",
+		       sv->sv_name, libcfs_id2str(rpc->srpc_peer));
+		spin_unlock(&sfw_data.fw_lock);
+		return -EAGAIN;
+	}
+
+	sfw_data.fw_active_srpc = rpc;
+	spin_unlock(&sfw_data.fw_lock);
+
+	rc = sfw_add_test(rpc);
+
+	spin_lock(&sfw_data.fw_lock);
+
+	if (!sfw_data.fw_shuttingdown)
+		sfw_add_session_timer();
+
+	sfw_data.fw_active_srpc = NULL;
+	spin_unlock(&sfw_data.fw_lock);
+	return rc;
+}
+
+srpc_client_rpc_t *
+sfw_create_rpc(lnet_process_id_t peer, int service,
+	       unsigned features, int nbulkiov, int bulklen,
+	       void (*done)(srpc_client_rpc_t *), void *priv)
+{
+	srpc_client_rpc_t *rpc = NULL;
+
+	spin_lock(&sfw_data.fw_lock);
+
+	LASSERT (!sfw_data.fw_shuttingdown);
+	LASSERT (service <= SRPC_FRAMEWORK_SERVICE_MAX_ID);
+
+	if (nbulkiov == 0 && !list_empty(&sfw_data.fw_zombie_rpcs)) {
+		rpc = list_entry(sfw_data.fw_zombie_rpcs.next,
+				     srpc_client_rpc_t, crpc_list);
+		list_del(&rpc->crpc_list);
+
+		srpc_init_client_rpc(rpc, peer, service, 0, 0,
+				     done, sfw_client_rpc_fini, priv);
+	}
+
+	spin_unlock(&sfw_data.fw_lock);
+
+	if (rpc == NULL) {
+		rpc = srpc_create_client_rpc(peer, service,
+					     nbulkiov, bulklen, done,
+					     nbulkiov != 0 ?  NULL :
+					     sfw_client_rpc_fini,
+					     priv);
+	}
+
+	if (rpc != NULL) /* "session" is concept in framework */
+		rpc->crpc_reqstmsg.msg_ses_feats = features;
+
+	return rpc;
+}
+
+void
+sfw_unpack_message (srpc_msg_t *msg)
+{
+	if (msg->msg_magic == SRPC_MSG_MAGIC)
+		return; /* no flipping needed */
+
+	/* srpc module should guarantee I wouldn't get crap */
+	LASSERT (msg->msg_magic == __swab32(SRPC_MSG_MAGIC));
+
+	if (msg->msg_type == SRPC_MSG_STAT_REQST) {
+		srpc_stat_reqst_t *req = &msg->msg_body.stat_reqst;
+
+		__swab32s(&req->str_type);
+		__swab64s(&req->str_rpyid);
+		sfw_unpack_sid(req->str_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_STAT_REPLY) {
+		srpc_stat_reply_t *rep = &msg->msg_body.stat_reply;
+
+		__swab32s(&rep->str_status);
+		sfw_unpack_sid(rep->str_sid);
+		sfw_unpack_fw_counters(rep->str_fw);
+		sfw_unpack_rpc_counters(rep->str_rpc);
+		sfw_unpack_lnet_counters(rep->str_lnet);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_MKSN_REQST) {
+		srpc_mksn_reqst_t *req = &msg->msg_body.mksn_reqst;
+
+		__swab64s(&req->mksn_rpyid);
+		__swab32s(&req->mksn_force);
+		sfw_unpack_sid(req->mksn_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_MKSN_REPLY) {
+		srpc_mksn_reply_t *rep = &msg->msg_body.mksn_reply;
+
+		__swab32s(&rep->mksn_status);
+		__swab32s(&rep->mksn_timeout);
+		sfw_unpack_sid(rep->mksn_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_RMSN_REQST) {
+		srpc_rmsn_reqst_t *req = &msg->msg_body.rmsn_reqst;
+
+		__swab64s(&req->rmsn_rpyid);
+		sfw_unpack_sid(req->rmsn_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_RMSN_REPLY) {
+		srpc_rmsn_reply_t *rep = &msg->msg_body.rmsn_reply;
+
+		__swab32s(&rep->rmsn_status);
+		sfw_unpack_sid(rep->rmsn_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_DEBUG_REQST) {
+		srpc_debug_reqst_t *req = &msg->msg_body.dbg_reqst;
+
+		__swab64s(&req->dbg_rpyid);
+		__swab32s(&req->dbg_flags);
+		sfw_unpack_sid(req->dbg_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_DEBUG_REPLY) {
+		srpc_debug_reply_t *rep = &msg->msg_body.dbg_reply;
+
+		__swab32s(&rep->dbg_nbatch);
+		__swab32s(&rep->dbg_timeout);
+		sfw_unpack_sid(rep->dbg_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_BATCH_REQST) {
+		srpc_batch_reqst_t *req = &msg->msg_body.bat_reqst;
+
+		__swab32s(&req->bar_opc);
+		__swab64s(&req->bar_rpyid);
+		__swab32s(&req->bar_testidx);
+		__swab32s(&req->bar_arg);
+		sfw_unpack_sid(req->bar_sid);
+		__swab64s(&req->bar_bid.bat_id);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_BATCH_REPLY) {
+		srpc_batch_reply_t *rep = &msg->msg_body.bat_reply;
+
+		__swab32s(&rep->bar_status);
+		sfw_unpack_sid(rep->bar_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_TEST_REQST) {
+		srpc_test_reqst_t *req = &msg->msg_body.tes_reqst;
+
+		__swab64s(&req->tsr_rpyid);
+		__swab64s(&req->tsr_bulkid);
+		__swab32s(&req->tsr_loop);
+		__swab32s(&req->tsr_ndest);
+		__swab32s(&req->tsr_concur);
+		__swab32s(&req->tsr_service);
+		sfw_unpack_sid(req->tsr_sid);
+		__swab64s(&req->tsr_bid.bat_id);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_TEST_REPLY) {
+		srpc_test_reply_t *rep = &msg->msg_body.tes_reply;
+
+		__swab32s(&rep->tsr_status);
+		sfw_unpack_sid(rep->tsr_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_JOIN_REQST) {
+		srpc_join_reqst_t *req = &msg->msg_body.join_reqst;
+
+		__swab64s(&req->join_rpyid);
+		sfw_unpack_sid(req->join_sid);
+		return;
+	}
+
+	if (msg->msg_type == SRPC_MSG_JOIN_REPLY) {
+		srpc_join_reply_t *rep = &msg->msg_body.join_reply;
+
+		__swab32s(&rep->join_status);
+		__swab32s(&rep->join_timeout);
+		sfw_unpack_sid(rep->join_sid);
+		return;
+	}
+
+	LBUG ();
+	return;
+}
+
+void
+sfw_abort_rpc (srpc_client_rpc_t *rpc)
+{
+	LASSERT(atomic_read(&rpc->crpc_refcount) > 0);
+	LASSERT(rpc->crpc_service <= SRPC_FRAMEWORK_SERVICE_MAX_ID);
+
+	spin_lock(&rpc->crpc_lock);
+	srpc_abort_rpc(rpc, -EINTR);
+	spin_unlock(&rpc->crpc_lock);
+	return;
+}
+
+void
+sfw_post_rpc (srpc_client_rpc_t *rpc)
+{
+	spin_lock(&rpc->crpc_lock);
+
+	LASSERT (!rpc->crpc_closed);
+	LASSERT (!rpc->crpc_aborted);
+	LASSERT (list_empty(&rpc->crpc_list));
+	LASSERT (!sfw_data.fw_shuttingdown);
+
+	rpc->crpc_timeout = rpc_timeout;
+	srpc_post_rpc(rpc);
+
+	spin_unlock(&rpc->crpc_lock);
+	return;
+}
+
+static srpc_service_t sfw_services[] =
+{
+	{
+		/* sv_id */    SRPC_SERVICE_DEBUG,
+		/* sv_name */  "debug",
+		0
+	},
+	{
+		/* sv_id */    SRPC_SERVICE_QUERY_STAT,
+		/* sv_name */  "query stats",
+		0
+	},
+	{
+		/* sv_id */    SRPC_SERVICE_MAKE_SESSION,
+		/* sv_name */  "make session",
+		0
+	},
+	{
+		/* sv_id */    SRPC_SERVICE_REMOVE_SESSION,
+		/* sv_name */  "remove session",
+		0
+	},
+	{
+		/* sv_id */    SRPC_SERVICE_BATCH,
+		/* sv_name */  "batch service",
+		0
+	},
+	{
+		/* sv_id */    SRPC_SERVICE_TEST,
+		/* sv_name */  "test service",
+		0
+	},
+	{
+		/* sv_id */    0,
+		/* sv_name */  NULL,
+		0
+	}
+};
+
+extern sfw_test_client_ops_t ping_test_client;
+extern srpc_service_t	ping_test_service;
+extern void ping_init_test_client(void);
+extern void ping_init_test_service(void);
+
+extern sfw_test_client_ops_t brw_test_client;
+extern srpc_service_t	brw_test_service;
+extern void brw_init_test_client(void);
+extern void brw_init_test_service(void);
+
+
+int
+sfw_startup (void)
+{
+	int	      i;
+	int	      rc;
+	int	      error;
+	srpc_service_t  *sv;
+	sfw_test_case_t *tsc;
+
+
+	if (session_timeout < 0) {
+		CERROR ("Session timeout must be non-negative: %d\n",
+			session_timeout);
+		return -EINVAL;
+	}
+
+	if (rpc_timeout < 0) {
+		CERROR ("RPC timeout must be non-negative: %d\n",
+			rpc_timeout);
+		return -EINVAL;
+	}
+
+	if (session_timeout == 0)
+		CWARN ("Zero session_timeout specified "
+		       "- test sessions never expire.\n");
+
+	if (rpc_timeout == 0)
+		CWARN ("Zero rpc_timeout specified "
+		       "- test RPC never expire.\n");
+
+	memset(&sfw_data, 0, sizeof(struct smoketest_framework));
+
+	sfw_data.fw_session     = NULL;
+	sfw_data.fw_active_srpc = NULL;
+	spin_lock_init(&sfw_data.fw_lock);
+	atomic_set(&sfw_data.fw_nzombies, 0);
+	INIT_LIST_HEAD(&sfw_data.fw_tests);
+	INIT_LIST_HEAD(&sfw_data.fw_zombie_rpcs);
+	INIT_LIST_HEAD(&sfw_data.fw_zombie_sessions);
+
+	brw_init_test_client();
+	brw_init_test_service();
+	rc = sfw_register_test(&brw_test_service, &brw_test_client);
+	LASSERT (rc == 0);
+
+	ping_init_test_client();
+	ping_init_test_service();
+	rc = sfw_register_test(&ping_test_service, &ping_test_client);
+	LASSERT (rc == 0);
+
+	error = 0;
+	list_for_each_entry (tsc, &sfw_data.fw_tests, tsc_list) {
+		sv = tsc->tsc_srv_service;
+
+		rc = srpc_add_service(sv);
+		LASSERT (rc != -EBUSY);
+		if (rc != 0) {
+			CWARN ("Failed to add %s service: %d\n",
+			       sv->sv_name, rc);
+			error = rc;
+		}
+	}
+
+	for (i = 0; ; i++) {
+		sv = &sfw_services[i];
+		if (sv->sv_name == NULL) break;
+
+		sv->sv_bulk_ready = NULL;
+		sv->sv_handler    = sfw_handle_server_rpc;
+		sv->sv_wi_total   = SFW_FRWK_WI_MAX;
+		if (sv->sv_id == SRPC_SERVICE_TEST)
+			sv->sv_bulk_ready = sfw_bulk_ready;
+
+		rc = srpc_add_service(sv);
+		LASSERT (rc != -EBUSY);
+		if (rc != 0) {
+			CWARN ("Failed to add %s service: %d\n",
+			       sv->sv_name, rc);
+			error = rc;
+		}
+
+		/* about to sfw_shutdown, no need to add buffer */
+		if (error) continue;
+
+		rc = srpc_service_add_buffers(sv, sv->sv_wi_total);
+		if (rc != 0) {
+			CWARN("Failed to reserve enough buffers: "
+			      "service %s, %d needed: %d\n",
+			      sv->sv_name, sv->sv_wi_total, rc);
+			error = -ENOMEM;
+		}
+	}
+
+	if (error != 0)
+		sfw_shutdown();
+	return error;
+}
+
+void
+sfw_shutdown (void)
+{
+	srpc_service_t	*sv;
+	sfw_test_case_t	*tsc;
+	int		 i;
+
+	spin_lock(&sfw_data.fw_lock);
+
+	sfw_data.fw_shuttingdown = 1;
+	lst_wait_until(sfw_data.fw_active_srpc == NULL, sfw_data.fw_lock,
+		       "waiting for active RPC to finish.\n");
+
+	if (sfw_del_session_timer() != 0)
+		lst_wait_until(sfw_data.fw_session == NULL, sfw_data.fw_lock,
+			       "waiting for session timer to explode.\n");
+
+	sfw_deactivate_session();
+	lst_wait_until(atomic_read(&sfw_data.fw_nzombies) == 0,
+		       sfw_data.fw_lock,
+		       "waiting for %d zombie sessions to die.\n",
+		       atomic_read(&sfw_data.fw_nzombies));
+
+	spin_unlock(&sfw_data.fw_lock);
+
+	for (i = 0; ; i++) {
+		sv = &sfw_services[i];
+		if (sv->sv_name == NULL)
+			break;
+
+		srpc_shutdown_service(sv);
+		srpc_remove_service(sv);
+	}
+
+	list_for_each_entry (tsc, &sfw_data.fw_tests, tsc_list) {
+		sv = tsc->tsc_srv_service;
+		srpc_shutdown_service(sv);
+		srpc_remove_service(sv);
+	}
+
+	while (!list_empty(&sfw_data.fw_zombie_rpcs)) {
+		srpc_client_rpc_t *rpc;
+
+		rpc = list_entry(sfw_data.fw_zombie_rpcs.next,
+				     srpc_client_rpc_t, crpc_list);
+		list_del(&rpc->crpc_list);
+
+		LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc));
+	}
+
+	for (i = 0; ; i++) {
+		sv = &sfw_services[i];
+		if (sv->sv_name == NULL)
+			break;
+
+		srpc_wait_service_shutdown(sv);
+	}
+
+	while (!list_empty(&sfw_data.fw_tests)) {
+		tsc = list_entry(sfw_data.fw_tests.next,
+				     sfw_test_case_t, tsc_list);
+
+		srpc_wait_service_shutdown(tsc->tsc_srv_service);
+
+		list_del(&tsc->tsc_list);
+		LIBCFS_FREE(tsc, sizeof(*tsc));
+	}
+
+	return;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/Makefile
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,6 @@
+obj-$(CONFIG_LNET_SELFTEST) := lnet_selftest.o
+
+lnet_selftest-y := console.o conrpc.o conctl.o framework.o timer.o rpc.o \
+		   module.o ping_test.o brw_test.o
+
+ccflags-y := -I$(src)/../include
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/module.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/module.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/module.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/module.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,169 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include "selftest.h"
+
+enum {
+	LST_INIT_NONE		= 0,
+	LST_INIT_WI_SERIAL,
+	LST_INIT_WI_TEST,
+	LST_INIT_RPC,
+	LST_INIT_FW,
+	LST_INIT_CONSOLE
+};
+
+extern int lstcon_console_init(void);
+extern int lstcon_console_fini(void);
+
+static int lst_init_step = LST_INIT_NONE;
+
+struct cfs_wi_sched *lst_sched_serial;
+struct cfs_wi_sched **lst_sched_test;
+
+void
+lnet_selftest_fini(void)
+{
+	int	i;
+
+	switch (lst_init_step) {
+		case LST_INIT_CONSOLE:
+			lstcon_console_fini();
+		case LST_INIT_FW:
+			sfw_shutdown();
+		case LST_INIT_RPC:
+			srpc_shutdown();
+		case LST_INIT_WI_TEST:
+			for (i = 0;
+			     i < cfs_cpt_number(lnet_cpt_table()); i++) {
+				if (lst_sched_test[i] == NULL)
+					continue;
+				cfs_wi_sched_destroy(lst_sched_test[i]);
+			}
+			LIBCFS_FREE(lst_sched_test,
+				    sizeof(lst_sched_test[0]) *
+				    cfs_cpt_number(lnet_cpt_table()));
+			lst_sched_test = NULL;
+
+		case LST_INIT_WI_SERIAL:
+			cfs_wi_sched_destroy(lst_sched_serial);
+			lst_sched_serial = NULL;
+		case LST_INIT_NONE:
+			break;
+		default:
+			LBUG();
+	}
+	return;
+}
+
+void
+lnet_selftest_structure_assertion(void)
+{
+	CLASSERT(sizeof(srpc_msg_t) == 160);
+	CLASSERT(sizeof(srpc_test_reqst_t) == 70);
+	CLASSERT(offsetof(srpc_msg_t, msg_body.tes_reqst.tsr_concur) == 72);
+	CLASSERT(offsetof(srpc_msg_t, msg_body.tes_reqst.tsr_ndest) == 78);
+	CLASSERT(sizeof(srpc_stat_reply_t) == 136);
+	CLASSERT(sizeof(srpc_stat_reqst_t) == 28);
+}
+
+int
+lnet_selftest_init(void)
+{
+	int	nscheds;
+	int	rc;
+	int	i;
+
+	rc = cfs_wi_sched_create("lst_s", lnet_cpt_table(), CFS_CPT_ANY,
+				 1, &lst_sched_serial);
+	if (rc != 0) {
+		CERROR("Failed to create serial WI scheduler for LST\n");
+		return rc;
+	}
+	lst_init_step = LST_INIT_WI_SERIAL;
+
+	nscheds = cfs_cpt_number(lnet_cpt_table());
+	LIBCFS_ALLOC(lst_sched_test, sizeof(lst_sched_test[0]) * nscheds);
+	if (lst_sched_test == NULL)
+		goto error;
+
+	lst_init_step = LST_INIT_WI_TEST;
+	for (i = 0; i < nscheds; i++) {
+		int nthrs = cfs_cpt_weight(lnet_cpt_table(), i);
+
+		/* reserve at least one CPU for LND */
+		nthrs = max(nthrs - 1, 1);
+		rc = cfs_wi_sched_create("lst_t", lnet_cpt_table(), i,
+					 nthrs, &lst_sched_test[i]);
+		if (rc != 0) {
+			CERROR("Failed to create CPT affinity WI scheduler "
+			       "%d for LST\n", i);
+			goto error;
+		}
+	}
+
+	rc = srpc_startup();
+	if (rc != 0) {
+		CERROR("LST can't startup rpc\n");
+		goto error;
+	}
+	lst_init_step = LST_INIT_RPC;
+
+	rc = sfw_startup();
+	if (rc != 0) {
+		CERROR("LST can't startup framework\n");
+		goto error;
+	}
+	lst_init_step = LST_INIT_FW;
+
+	rc = lstcon_console_init();
+	if (rc != 0) {
+		CERROR("LST can't startup console\n");
+		goto error;
+	}
+	lst_init_step = LST_INIT_CONSOLE;
+	return 0;
+error:
+	lnet_selftest_fini();
+	return rc;
+}
+
+
+MODULE_DESCRIPTION("LNet Selftest");
+MODULE_LICENSE("GPL");
+
+cfs_module(lnet, "0.9.0", lnet_selftest_init, lnet_selftest_fini);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/ping_test.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/ping_test.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/ping_test.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/ping_test.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,229 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/conctl.c
+ *
+ * Test client & Server
+ *
+ * Author: Liang Zhen <liangzhen@clusterfs.com>
+ */
+
+#include "selftest.h"
+
+#define LST_PING_TEST_MAGIC     0xbabeface
+
+int ping_srv_workitems = SFW_TEST_WI_MAX;
+CFS_MODULE_PARM(ping_srv_workitems, "i", int, 0644, "# PING server workitems");
+
+typedef struct {
+	spinlock_t	pnd_lock;	/* serialize */
+	int		pnd_counter;	/* sequence counter */
+} lst_ping_data_t;
+
+static lst_ping_data_t  lst_ping_data;
+
+static int
+ping_client_init(sfw_test_instance_t *tsi)
+{
+	sfw_session_t *sn = tsi->tsi_batch->bat_session;
+
+	LASSERT(tsi->tsi_is_client);
+	LASSERT(sn != NULL && (sn->sn_features & ~LST_FEATS_MASK) == 0);
+
+	spin_lock_init(&lst_ping_data.pnd_lock);
+	lst_ping_data.pnd_counter = 0;
+
+	return 0;
+}
+
+static void
+ping_client_fini (sfw_test_instance_t *tsi)
+{
+	sfw_session_t *sn = tsi->tsi_batch->bat_session;
+	int	    errors;
+
+	LASSERT (sn != NULL);
+	LASSERT (tsi->tsi_is_client);
+
+	errors = atomic_read(&sn->sn_ping_errors);
+	if (errors)
+		CWARN ("%d pings have failed.\n", errors);
+	else
+		CDEBUG (D_NET, "Ping test finished OK.\n");
+}
+
+static int
+ping_client_prep_rpc(sfw_test_unit_t *tsu,
+		     lnet_process_id_t dest, srpc_client_rpc_t **rpc)
+{
+	srpc_ping_reqst_t   *req;
+	sfw_test_instance_t *tsi = tsu->tsu_instance;
+	sfw_session_t       *sn  = tsi->tsi_batch->bat_session;
+	struct timeval       tv;
+	int		     rc;
+
+	LASSERT(sn != NULL);
+	LASSERT((sn->sn_features & ~LST_FEATS_MASK) == 0);
+
+	rc = sfw_create_test_rpc(tsu, dest, sn->sn_features, 0, 0, rpc);
+	if (rc != 0)
+		return rc;
+
+	req = &(*rpc)->crpc_reqstmsg.msg_body.ping_reqst;
+
+	req->pnr_magic = LST_PING_TEST_MAGIC;
+
+	spin_lock(&lst_ping_data.pnd_lock);
+	req->pnr_seq = lst_ping_data.pnd_counter++;
+	spin_unlock(&lst_ping_data.pnd_lock);
+
+	cfs_fs_timeval(&tv);
+	req->pnr_time_sec  = tv.tv_sec;
+	req->pnr_time_usec = tv.tv_usec;
+
+	return rc;
+}
+
+static void
+ping_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
+{
+	sfw_test_instance_t *tsi = tsu->tsu_instance;
+	sfw_session_t       *sn = tsi->tsi_batch->bat_session;
+	srpc_ping_reqst_t   *reqst = &rpc->crpc_reqstmsg.msg_body.ping_reqst;
+	srpc_ping_reply_t   *reply = &rpc->crpc_replymsg.msg_body.ping_reply;
+	struct timeval       tv;
+
+	LASSERT (sn != NULL);
+
+	if (rpc->crpc_status != 0) {
+		if (!tsi->tsi_stopping) /* rpc could have been aborted */
+			atomic_inc(&sn->sn_ping_errors);
+		CERROR ("Unable to ping %s (%d): %d\n",
+			libcfs_id2str(rpc->crpc_dest),
+			reqst->pnr_seq, rpc->crpc_status);
+		return;
+	}
+
+	if (rpc->crpc_replymsg.msg_magic != SRPC_MSG_MAGIC) {
+		__swab32s(&reply->pnr_seq);
+		__swab32s(&reply->pnr_magic);
+		__swab32s(&reply->pnr_status);
+	}
+
+	if (reply->pnr_magic != LST_PING_TEST_MAGIC) {
+		rpc->crpc_status = -EBADMSG;
+		atomic_inc(&sn->sn_ping_errors);
+		CERROR ("Bad magic %u from %s, %u expected.\n",
+			reply->pnr_magic, libcfs_id2str(rpc->crpc_dest),
+			LST_PING_TEST_MAGIC);
+		return;
+	}
+
+	if (reply->pnr_seq != reqst->pnr_seq) {
+		rpc->crpc_status = -EBADMSG;
+		atomic_inc(&sn->sn_ping_errors);
+		CERROR ("Bad seq %u from %s, %u expected.\n",
+			reply->pnr_seq, libcfs_id2str(rpc->crpc_dest),
+			reqst->pnr_seq);
+		return;
+	}
+
+	cfs_fs_timeval(&tv);
+	CDEBUG (D_NET, "%d reply in %u usec\n", reply->pnr_seq,
+		(unsigned)((tv.tv_sec - (unsigned)reqst->pnr_time_sec) * 1000000
+			   + (tv.tv_usec - reqst->pnr_time_usec)));
+	return;
+}
+
+static int
+ping_server_handle(struct srpc_server_rpc *rpc)
+{
+	struct srpc_service	*sv  = rpc->srpc_scd->scd_svc;
+	srpc_msg_t	*reqstmsg = &rpc->srpc_reqstbuf->buf_msg;
+	srpc_msg_t	  *replymsg = &rpc->srpc_replymsg;
+	srpc_ping_reqst_t *req = &reqstmsg->msg_body.ping_reqst;
+	srpc_ping_reply_t *rep = &rpc->srpc_replymsg.msg_body.ping_reply;
+
+	LASSERT (sv->sv_id == SRPC_SERVICE_PING);
+
+	if (reqstmsg->msg_magic != SRPC_MSG_MAGIC) {
+		LASSERT (reqstmsg->msg_magic == __swab32(SRPC_MSG_MAGIC));
+
+		__swab32s(&req->pnr_seq);
+		__swab32s(&req->pnr_magic);
+		__swab64s(&req->pnr_time_sec);
+		__swab64s(&req->pnr_time_usec);
+	}
+	LASSERT (reqstmsg->msg_type == srpc_service2request(sv->sv_id));
+
+	if (req->pnr_magic != LST_PING_TEST_MAGIC) {
+		CERROR ("Unexpect magic %08x from %s\n",
+			req->pnr_magic, libcfs_id2str(rpc->srpc_peer));
+		return -EINVAL;
+	}
+
+	rep->pnr_seq   = req->pnr_seq;
+	rep->pnr_magic = LST_PING_TEST_MAGIC;
+
+	if ((reqstmsg->msg_ses_feats & ~LST_FEATS_MASK) != 0) {
+		replymsg->msg_ses_feats = LST_FEATS_MASK;
+		rep->pnr_status = EPROTO;
+		return 0;
+	}
+
+	replymsg->msg_ses_feats = reqstmsg->msg_ses_feats;
+
+	CDEBUG(D_NET, "Get ping %d from %s\n",
+	       req->pnr_seq, libcfs_id2str(rpc->srpc_peer));
+	return 0;
+}
+
+sfw_test_client_ops_t ping_test_client;
+void ping_init_test_client(void)
+{
+	ping_test_client.tso_init     = ping_client_init;
+	ping_test_client.tso_fini     = ping_client_fini;
+	ping_test_client.tso_prep_rpc = ping_client_prep_rpc;
+	ping_test_client.tso_done_rpc = ping_client_done_rpc;
+}
+
+srpc_service_t ping_test_service;
+void ping_init_test_service(void)
+{
+	ping_test_service.sv_id       = SRPC_SERVICE_PING;
+	ping_test_service.sv_name     = "ping_test";
+	ping_test_service.sv_handler  = ping_server_handle;
+	ping_test_service.sv_wi_total = ping_srv_workitems;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/rpc.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/rpc.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/rpc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/rpc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1666 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/rpc.c
+ *
+ * Author: Isaac Huang <isaac@clusterfs.com>
+ *
+ * 2012-05-13: Liang Zhen <liang@whamcloud.com>
+ * - percpt data for service to improve smp performance
+ * - code cleanup
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include "selftest.h"
+
+typedef enum {
+	SRPC_STATE_NONE,
+	SRPC_STATE_NI_INIT,
+	SRPC_STATE_EQ_INIT,
+	SRPC_STATE_RUNNING,
+	SRPC_STATE_STOPPING,
+} srpc_state_t;
+
+struct smoketest_rpc {
+	spinlock_t	 rpc_glock;	/* global lock */
+	srpc_service_t	*rpc_services[SRPC_SERVICE_MAX_ID + 1];
+	lnet_handle_eq_t rpc_lnet_eq;	/* _the_ LNet event queue */
+	srpc_state_t	 rpc_state;
+	srpc_counters_t	 rpc_counters;
+	__u64		 rpc_matchbits;	/* matchbits counter */
+} srpc_data;
+
+static inline int
+srpc_serv_portal(int svc_id)
+{
+	return svc_id < SRPC_FRAMEWORK_SERVICE_MAX_ID ?
+	       SRPC_FRAMEWORK_REQUEST_PORTAL : SRPC_REQUEST_PORTAL;
+}
+
+/* forward ref's */
+int srpc_handle_rpc (swi_workitem_t *wi);
+
+void srpc_get_counters (srpc_counters_t *cnt)
+{
+	spin_lock(&srpc_data.rpc_glock);
+	*cnt = srpc_data.rpc_counters;
+	spin_unlock(&srpc_data.rpc_glock);
+}
+
+void srpc_set_counters (const srpc_counters_t *cnt)
+{
+	spin_lock(&srpc_data.rpc_glock);
+	srpc_data.rpc_counters = *cnt;
+	spin_unlock(&srpc_data.rpc_glock);
+}
+
+int
+srpc_add_bulk_page(srpc_bulk_t *bk, struct page *pg, int i, int nob)
+{
+	nob = min(nob, (int)PAGE_CACHE_SIZE);
+
+	LASSERT(nob > 0);
+	LASSERT(i >= 0 && i < bk->bk_niov);
+
+	bk->bk_iovs[i].kiov_offset = 0;
+	bk->bk_iovs[i].kiov_page   = pg;
+	bk->bk_iovs[i].kiov_len    = nob;
+	return nob;
+}
+
+void
+srpc_free_bulk (srpc_bulk_t *bk)
+{
+	int	 i;
+	struct page *pg;
+
+	LASSERT (bk != NULL);
+
+	for (i = 0; i < bk->bk_niov; i++) {
+		pg = bk->bk_iovs[i].kiov_page;
+		if (pg == NULL) break;
+
+		__free_page(pg);
+	}
+
+	LIBCFS_FREE(bk, offsetof(srpc_bulk_t, bk_iovs[bk->bk_niov]));
+	return;
+}
+
+srpc_bulk_t *
+srpc_alloc_bulk(int cpt, unsigned bulk_npg, unsigned bulk_len, int sink)
+{
+	srpc_bulk_t  *bk;
+	struct page  **pages;
+	int	      i;
+
+	LASSERT(bulk_npg > 0 && bulk_npg <= LNET_MAX_IOV);
+
+	LIBCFS_CPT_ALLOC(bk, lnet_cpt_table(), cpt,
+			 offsetof(srpc_bulk_t, bk_iovs[bulk_npg]));
+	if (bk == NULL) {
+		CERROR("Can't allocate descriptor for %d pages\n", bulk_npg);
+		return NULL;
+	}
+
+	memset(bk, 0, offsetof(srpc_bulk_t, bk_iovs[bulk_npg]));
+	bk->bk_sink   = sink;
+	bk->bk_len    = bulk_len;
+	bk->bk_niov   = bulk_npg;
+	UNUSED(pages);
+
+	for (i = 0; i < bulk_npg; i++) {
+		struct page *pg;
+		int	    nob;
+
+		pg = alloc_pages_node(cfs_cpt_spread_node(lnet_cpt_table(), cpt),
+				      GFP_IOFS, 0);
+		if (pg == NULL) {
+			CERROR("Can't allocate page %d of %d\n", i, bulk_npg);
+			srpc_free_bulk(bk);
+			return NULL;
+		}
+
+		nob = srpc_add_bulk_page(bk, pg, i, bulk_len);
+		bulk_len -= nob;
+	}
+
+	return bk;
+}
+
+static inline __u64
+srpc_next_id (void)
+{
+	__u64 id;
+
+	spin_lock(&srpc_data.rpc_glock);
+	id = srpc_data.rpc_matchbits++;
+	spin_unlock(&srpc_data.rpc_glock);
+	return id;
+}
+
+void
+srpc_init_server_rpc(struct srpc_server_rpc *rpc,
+		     struct srpc_service_cd *scd,
+		     struct srpc_buffer *buffer)
+{
+	memset(rpc, 0, sizeof(*rpc));
+	swi_init_workitem(&rpc->srpc_wi, rpc, srpc_handle_rpc,
+			  srpc_serv_is_framework(scd->scd_svc) ?
+			  lst_sched_serial : lst_sched_test[scd->scd_cpt]);
+
+	rpc->srpc_ev.ev_fired = 1; /* no event expected now */
+
+	rpc->srpc_scd      = scd;
+	rpc->srpc_reqstbuf = buffer;
+	rpc->srpc_peer     = buffer->buf_peer;
+	rpc->srpc_self     = buffer->buf_self;
+	LNetInvalidateHandle(&rpc->srpc_replymdh);
+}
+
+static void
+srpc_service_fini(struct srpc_service *svc)
+{
+	struct srpc_service_cd	*scd;
+	struct srpc_server_rpc	*rpc;
+	struct srpc_buffer	*buf;
+	struct list_head		*q;
+	int			i;
+
+	if (svc->sv_cpt_data == NULL)
+		return;
+
+	cfs_percpt_for_each(scd, i, svc->sv_cpt_data) {
+		while (1) {
+			if (!list_empty(&scd->scd_buf_posted))
+				q = &scd->scd_buf_posted;
+			else if (!list_empty(&scd->scd_buf_blocked))
+				q = &scd->scd_buf_blocked;
+			else
+				break;
+
+			while (!list_empty(q)) {
+				buf = list_entry(q->next,
+						     struct srpc_buffer,
+						     buf_list);
+				list_del(&buf->buf_list);
+				LIBCFS_FREE(buf, sizeof(*buf));
+			}
+		}
+
+		LASSERT(list_empty(&scd->scd_rpc_active));
+
+		while (!list_empty(&scd->scd_rpc_free)) {
+			rpc = list_entry(scd->scd_rpc_free.next,
+					     struct srpc_server_rpc,
+					     srpc_list);
+			list_del(&rpc->srpc_list);
+			LIBCFS_FREE(rpc, sizeof(*rpc));
+		}
+	}
+
+	cfs_percpt_free(svc->sv_cpt_data);
+	svc->sv_cpt_data = NULL;
+}
+
+static int
+srpc_service_nrpcs(struct srpc_service *svc)
+{
+	int nrpcs = svc->sv_wi_total / svc->sv_ncpts;
+
+	return srpc_serv_is_framework(svc) ?
+	       max(nrpcs, SFW_FRWK_WI_MIN) : max(nrpcs, SFW_TEST_WI_MIN);
+}
+
+int srpc_add_buffer(struct swi_workitem *wi);
+
+static int
+srpc_service_init(struct srpc_service *svc)
+{
+	struct srpc_service_cd	*scd;
+	struct srpc_server_rpc	*rpc;
+	int			nrpcs;
+	int			i;
+	int			j;
+
+	svc->sv_shuttingdown = 0;
+
+	svc->sv_cpt_data = cfs_percpt_alloc(lnet_cpt_table(),
+					    sizeof(struct srpc_service_cd));
+	if (svc->sv_cpt_data == NULL)
+		return -ENOMEM;
+
+	svc->sv_ncpts = srpc_serv_is_framework(svc) ?
+			1 : cfs_cpt_number(lnet_cpt_table());
+	nrpcs = srpc_service_nrpcs(svc);
+
+	cfs_percpt_for_each(scd, i, svc->sv_cpt_data) {
+		scd->scd_cpt = i;
+		scd->scd_svc = svc;
+		spin_lock_init(&scd->scd_lock);
+		INIT_LIST_HEAD(&scd->scd_rpc_free);
+		INIT_LIST_HEAD(&scd->scd_rpc_active);
+		INIT_LIST_HEAD(&scd->scd_buf_posted);
+		INIT_LIST_HEAD(&scd->scd_buf_blocked);
+
+		scd->scd_ev.ev_data = scd;
+		scd->scd_ev.ev_type = SRPC_REQUEST_RCVD;
+
+		/* NB: don't use lst_sched_serial for adding buffer,
+		 * see details in srpc_service_add_buffers() */
+		swi_init_workitem(&scd->scd_buf_wi, scd,
+				  srpc_add_buffer, lst_sched_test[i]);
+
+		if (i != 0 && srpc_serv_is_framework(svc)) {
+			/* NB: framework service only needs srpc_service_cd for
+			 * one partition, but we allocate for all to make
+			 * it easier to implement, it will waste a little
+			 * memory but nobody should care about this */
+			continue;
+		}
+
+		for (j = 0; j < nrpcs; j++) {
+			LIBCFS_CPT_ALLOC(rpc, lnet_cpt_table(),
+					 i, sizeof(*rpc));
+			if (rpc == NULL) {
+				srpc_service_fini(svc);
+				return -ENOMEM;
+			}
+			list_add(&rpc->srpc_list, &scd->scd_rpc_free);
+		}
+	}
+
+	return 0;
+}
+
+int
+srpc_add_service(struct srpc_service *sv)
+{
+	int id = sv->sv_id;
+
+	LASSERT(0 <= id && id <= SRPC_SERVICE_MAX_ID);
+
+	if (srpc_service_init(sv) != 0)
+		return -ENOMEM;
+
+	spin_lock(&srpc_data.rpc_glock);
+
+	LASSERT(srpc_data.rpc_state == SRPC_STATE_RUNNING);
+
+	if (srpc_data.rpc_services[id] != NULL) {
+		spin_unlock(&srpc_data.rpc_glock);
+		goto failed;
+	}
+
+	srpc_data.rpc_services[id] = sv;
+	spin_unlock(&srpc_data.rpc_glock);
+
+	CDEBUG(D_NET, "Adding service: id %d, name %s\n", id, sv->sv_name);
+	return 0;
+
+ failed:
+	srpc_service_fini(sv);
+	return -EBUSY;
+}
+
+int
+srpc_remove_service (srpc_service_t *sv)
+{
+	int id = sv->sv_id;
+
+	spin_lock(&srpc_data.rpc_glock);
+
+	if (srpc_data.rpc_services[id] != sv) {
+		spin_unlock(&srpc_data.rpc_glock);
+		return -ENOENT;
+	}
+
+	srpc_data.rpc_services[id] = NULL;
+	spin_unlock(&srpc_data.rpc_glock);
+	return 0;
+}
+
+int
+srpc_post_passive_rdma(int portal, int local, __u64 matchbits, void *buf,
+		       int len, int options, lnet_process_id_t peer,
+		       lnet_handle_md_t *mdh, srpc_event_t *ev)
+{
+	int		 rc;
+	lnet_md_t	 md;
+	lnet_handle_me_t meh;
+
+	rc = LNetMEAttach(portal, peer, matchbits, 0, LNET_UNLINK,
+			  local ? LNET_INS_LOCAL : LNET_INS_AFTER, &meh);
+	if (rc != 0) {
+		CERROR ("LNetMEAttach failed: %d\n", rc);
+		LASSERT (rc == -ENOMEM);
+		return -ENOMEM;
+	}
+
+	md.threshold = 1;
+	md.user_ptr  = ev;
+	md.start     = buf;
+	md.length    = len;
+	md.options   = options;
+	md.eq_handle = srpc_data.rpc_lnet_eq;
+
+	rc = LNetMDAttach(meh, md, LNET_UNLINK, mdh);
+	if (rc != 0) {
+		CERROR ("LNetMDAttach failed: %d\n", rc);
+		LASSERT (rc == -ENOMEM);
+
+		rc = LNetMEUnlink(meh);
+		LASSERT (rc == 0);
+		return -ENOMEM;
+	}
+
+	CDEBUG (D_NET,
+		"Posted passive RDMA: peer %s, portal %d, matchbits "LPX64"\n",
+		libcfs_id2str(peer), portal, matchbits);
+	return 0;
+}
+
+int
+srpc_post_active_rdma(int portal, __u64 matchbits, void *buf, int len,
+		      int options, lnet_process_id_t peer, lnet_nid_t self,
+		      lnet_handle_md_t *mdh, srpc_event_t *ev)
+{
+	int       rc;
+	lnet_md_t md;
+
+	md.user_ptr  = ev;
+	md.start     = buf;
+	md.length    = len;
+	md.eq_handle = srpc_data.rpc_lnet_eq;
+	md.threshold = ((options & LNET_MD_OP_GET) != 0) ? 2 : 1;
+	md.options   = options & ~(LNET_MD_OP_PUT | LNET_MD_OP_GET);
+
+	rc = LNetMDBind(md, LNET_UNLINK, mdh);
+	if (rc != 0) {
+		CERROR ("LNetMDBind failed: %d\n", rc);
+		LASSERT (rc == -ENOMEM);
+		return -ENOMEM;
+	}
+
+	/* this is kind of an abuse of the LNET_MD_OP_{PUT,GET} options.
+	 * they're only meaningful for MDs attached to an ME (i.e. passive
+	 * buffers... */
+	if ((options & LNET_MD_OP_PUT) != 0) {
+		rc = LNetPut(self, *mdh, LNET_NOACK_REQ, peer,
+			     portal, matchbits, 0, 0);
+	} else {
+		LASSERT ((options & LNET_MD_OP_GET) != 0);
+
+		rc = LNetGet(self, *mdh, peer, portal, matchbits, 0);
+	}
+
+	if (rc != 0) {
+		CERROR ("LNet%s(%s, %d, "LPD64") failed: %d\n",
+			((options & LNET_MD_OP_PUT) != 0) ? "Put" : "Get",
+			libcfs_id2str(peer), portal, matchbits, rc);
+
+		/* The forthcoming unlink event will complete this operation
+		 * with failure, so fall through and return success here.
+		 */
+		rc = LNetMDUnlink(*mdh);
+		LASSERT (rc == 0);
+	} else {
+		CDEBUG (D_NET,
+			"Posted active RDMA: peer %s, portal %u, matchbits "LPX64"\n",
+			libcfs_id2str(peer), portal, matchbits);
+	}
+	return 0;
+}
+
+int
+srpc_post_active_rqtbuf(lnet_process_id_t peer, int service, void *buf,
+			int len, lnet_handle_md_t *mdh, srpc_event_t *ev)
+{
+	return srpc_post_active_rdma(srpc_serv_portal(service), service,
+				     buf, len, LNET_MD_OP_PUT, peer,
+				     LNET_NID_ANY, mdh, ev);
+}
+
+int
+srpc_post_passive_rqtbuf(int service, int local, void *buf, int len,
+			 lnet_handle_md_t *mdh, srpc_event_t *ev)
+{
+	lnet_process_id_t any = {0};
+
+	any.nid = LNET_NID_ANY;
+	any.pid = LNET_PID_ANY;
+
+	return srpc_post_passive_rdma(srpc_serv_portal(service),
+				      local, service, buf, len,
+				      LNET_MD_OP_PUT, any, mdh, ev);
+}
+
+int
+srpc_service_post_buffer(struct srpc_service_cd *scd, struct srpc_buffer *buf)
+{
+	struct srpc_service	*sv = scd->scd_svc;
+	struct srpc_msg		*msg = &buf->buf_msg;
+	int			rc;
+
+	LNetInvalidateHandle(&buf->buf_mdh);
+	list_add(&buf->buf_list, &scd->scd_buf_posted);
+	scd->scd_buf_nposted++;
+	spin_unlock(&scd->scd_lock);
+
+	rc = srpc_post_passive_rqtbuf(sv->sv_id,
+				      !srpc_serv_is_framework(sv),
+				      msg, sizeof(*msg), &buf->buf_mdh,
+				      &scd->scd_ev);
+
+	/* At this point, a RPC (new or delayed) may have arrived in
+	 * msg and its event handler has been called. So we must add
+	 * buf to scd_buf_posted _before_ dropping scd_lock */
+
+	spin_lock(&scd->scd_lock);
+
+	if (rc == 0) {
+		if (!sv->sv_shuttingdown)
+			return 0;
+
+		spin_unlock(&scd->scd_lock);
+		/* srpc_shutdown_service might have tried to unlink me
+		 * when my buf_mdh was still invalid */
+		LNetMDUnlink(buf->buf_mdh);
+		spin_lock(&scd->scd_lock);
+		return 0;
+	}
+
+	scd->scd_buf_nposted--;
+	if (sv->sv_shuttingdown)
+		return rc; /* don't allow to change scd_buf_posted */
+
+	list_del(&buf->buf_list);
+	spin_unlock(&scd->scd_lock);
+
+	LIBCFS_FREE(buf, sizeof(*buf));
+
+	spin_lock(&scd->scd_lock);
+	return rc;
+}
+
+int
+srpc_add_buffer(struct swi_workitem *wi)
+{
+	struct srpc_service_cd	*scd = wi->swi_workitem.wi_data;
+	struct srpc_buffer	*buf;
+	int			rc = 0;
+
+	/* it's called by workitem scheduler threads, these threads
+	 * should have been set CPT affinity, so buffers will be posted
+	 * on CPT local list of Portal */
+	spin_lock(&scd->scd_lock);
+
+	while (scd->scd_buf_adjust > 0 &&
+	       !scd->scd_svc->sv_shuttingdown) {
+		scd->scd_buf_adjust--; /* consume it */
+		scd->scd_buf_posting++;
+
+		spin_unlock(&scd->scd_lock);
+
+		LIBCFS_ALLOC(buf, sizeof(*buf));
+		if (buf == NULL) {
+			CERROR("Failed to add new buf to service: %s\n",
+			       scd->scd_svc->sv_name);
+			spin_lock(&scd->scd_lock);
+			rc = -ENOMEM;
+			break;
+		}
+
+		spin_lock(&scd->scd_lock);
+		if (scd->scd_svc->sv_shuttingdown) {
+			spin_unlock(&scd->scd_lock);
+			LIBCFS_FREE(buf, sizeof(*buf));
+
+			spin_lock(&scd->scd_lock);
+			rc = -ESHUTDOWN;
+			break;
+		}
+
+		rc = srpc_service_post_buffer(scd, buf);
+		if (rc != 0)
+			break; /* buf has been freed inside */
+
+		LASSERT(scd->scd_buf_posting > 0);
+		scd->scd_buf_posting--;
+		scd->scd_buf_total++;
+		scd->scd_buf_low = MAX(2, scd->scd_buf_total / 4);
+	}
+
+	if (rc != 0) {
+		scd->scd_buf_err_stamp = cfs_time_current_sec();
+		scd->scd_buf_err = rc;
+
+		LASSERT(scd->scd_buf_posting > 0);
+		scd->scd_buf_posting--;
+	}
+
+	spin_unlock(&scd->scd_lock);
+	return 0;
+}
+
+int
+srpc_service_add_buffers(struct srpc_service *sv, int nbuffer)
+{
+	struct srpc_service_cd	*scd;
+	int			rc = 0;
+	int			i;
+
+	LASSERTF(nbuffer > 0, "nbuffer must be positive: %d\n", nbuffer);
+
+	cfs_percpt_for_each(scd, i, sv->sv_cpt_data) {
+		spin_lock(&scd->scd_lock);
+
+		scd->scd_buf_err = 0;
+		scd->scd_buf_err_stamp = 0;
+		scd->scd_buf_posting = 0;
+		scd->scd_buf_adjust = nbuffer;
+		/* start to post buffers */
+		swi_schedule_workitem(&scd->scd_buf_wi);
+		spin_unlock(&scd->scd_lock);
+
+		/* framework service only post buffer for one partition  */
+		if (srpc_serv_is_framework(sv))
+			break;
+	}
+
+	cfs_percpt_for_each(scd, i, sv->sv_cpt_data) {
+		spin_lock(&scd->scd_lock);
+		/*
+		 * NB: srpc_service_add_buffers() can be called inside
+		 * thread context of lst_sched_serial, and we don't normally
+		 * allow to sleep inside thread context of WI scheduler
+		 * because it will block current scheduler thread from doing
+		 * anything else, even worse, it could deadlock if it's
+		 * waiting on result from another WI of the same scheduler.
+		 * However, it's safe at here because scd_buf_wi is scheduled
+		 * by thread in a different WI scheduler (lst_sched_test),
+		 * so we don't have any risk of deadlock, though this could
+		 * block all WIs pending on lst_sched_serial for a moment
+		 * which is not good but not fatal.
+		 */
+		lst_wait_until(scd->scd_buf_err != 0 ||
+			       (scd->scd_buf_adjust == 0 &&
+				scd->scd_buf_posting == 0),
+			       scd->scd_lock, "waiting for adding buffer\n");
+
+		if (scd->scd_buf_err != 0 && rc == 0)
+			rc = scd->scd_buf_err;
+
+		spin_unlock(&scd->scd_lock);
+	}
+
+	return rc;
+}
+
+void
+srpc_service_remove_buffers(struct srpc_service *sv, int nbuffer)
+{
+	struct srpc_service_cd	*scd;
+	int			num;
+	int			i;
+
+	LASSERT(!sv->sv_shuttingdown);
+
+	cfs_percpt_for_each(scd, i, sv->sv_cpt_data) {
+		spin_lock(&scd->scd_lock);
+
+		num = scd->scd_buf_total + scd->scd_buf_posting;
+		scd->scd_buf_adjust -= min(nbuffer, num);
+
+		spin_unlock(&scd->scd_lock);
+	}
+}
+
+/* returns 1 if sv has finished, otherwise 0 */
+int
+srpc_finish_service(struct srpc_service *sv)
+{
+	struct srpc_service_cd	*scd;
+	struct srpc_server_rpc	*rpc;
+	int			i;
+
+	LASSERT(sv->sv_shuttingdown); /* srpc_shutdown_service called */
+
+	cfs_percpt_for_each(scd, i, sv->sv_cpt_data) {
+		spin_lock(&scd->scd_lock);
+		if (!swi_deschedule_workitem(&scd->scd_buf_wi))
+			return 0;
+
+		if (scd->scd_buf_nposted > 0) {
+			CDEBUG(D_NET, "waiting for %d posted buffers to unlink",
+			       scd->scd_buf_nposted);
+			spin_unlock(&scd->scd_lock);
+			return 0;
+		}
+
+		if (list_empty(&scd->scd_rpc_active)) {
+			spin_unlock(&scd->scd_lock);
+			continue;
+		}
+
+		rpc = list_entry(scd->scd_rpc_active.next,
+				     struct srpc_server_rpc, srpc_list);
+		CNETERR("Active RPC %p on shutdown: sv %s, peer %s, "
+			"wi %s scheduled %d running %d, "
+			"ev fired %d type %d status %d lnet %d\n",
+			rpc, sv->sv_name, libcfs_id2str(rpc->srpc_peer),
+			swi_state2str(rpc->srpc_wi.swi_state),
+			rpc->srpc_wi.swi_workitem.wi_scheduled,
+			rpc->srpc_wi.swi_workitem.wi_running,
+			rpc->srpc_ev.ev_fired, rpc->srpc_ev.ev_type,
+			rpc->srpc_ev.ev_status, rpc->srpc_ev.ev_lnet);
+		spin_unlock(&scd->scd_lock);
+		return 0;
+	}
+
+	/* no lock needed from now on */
+	srpc_service_fini(sv);
+	return 1;
+}
+
+/* called with sv->sv_lock held */
+void
+srpc_service_recycle_buffer(struct srpc_service_cd *scd, srpc_buffer_t *buf)
+{
+	if (!scd->scd_svc->sv_shuttingdown && scd->scd_buf_adjust >= 0) {
+		if (srpc_service_post_buffer(scd, buf) != 0) {
+			CWARN("Failed to post %s buffer\n",
+			      scd->scd_svc->sv_name);
+		}
+		return;
+	}
+
+	/* service is shutting down, or we want to recycle some buffers */
+	scd->scd_buf_total--;
+
+	if (scd->scd_buf_adjust < 0) {
+		scd->scd_buf_adjust++;
+		if (scd->scd_buf_adjust < 0 &&
+		    scd->scd_buf_total == 0 && scd->scd_buf_posting == 0) {
+			CDEBUG(D_INFO,
+			       "Try to recyle %d buffers but nothing left\n",
+			       scd->scd_buf_adjust);
+			scd->scd_buf_adjust = 0;
+		}
+	}
+
+	spin_unlock(&scd->scd_lock);
+	LIBCFS_FREE(buf, sizeof(*buf));
+	spin_lock(&scd->scd_lock);
+}
+
+void
+srpc_abort_service(struct srpc_service *sv)
+{
+	struct srpc_service_cd	*scd;
+	struct srpc_server_rpc	*rpc;
+	int			i;
+
+	CDEBUG(D_NET, "Aborting service: id %d, name %s\n",
+	       sv->sv_id, sv->sv_name);
+
+	cfs_percpt_for_each(scd, i, sv->sv_cpt_data) {
+		spin_lock(&scd->scd_lock);
+
+		/* schedule in-flight RPCs to notice the abort, NB:
+		 * racing with incoming RPCs; complete fix should make test
+		 * RPCs carry session ID in its headers */
+		list_for_each_entry(rpc, &scd->scd_rpc_active, srpc_list) {
+			rpc->srpc_aborted = 1;
+			swi_schedule_workitem(&rpc->srpc_wi);
+		}
+
+		spin_unlock(&scd->scd_lock);
+	}
+}
+
+void
+srpc_shutdown_service(srpc_service_t *sv)
+{
+	struct srpc_service_cd	*scd;
+	struct srpc_server_rpc	*rpc;
+	srpc_buffer_t		*buf;
+	int			i;
+
+	CDEBUG(D_NET, "Shutting down service: id %d, name %s\n",
+	       sv->sv_id, sv->sv_name);
+
+	cfs_percpt_for_each(scd, i, sv->sv_cpt_data)
+		spin_lock(&scd->scd_lock);
+
+	sv->sv_shuttingdown = 1; /* i.e. no new active RPC */
+
+	cfs_percpt_for_each(scd, i, sv->sv_cpt_data)
+		spin_unlock(&scd->scd_lock);
+
+	cfs_percpt_for_each(scd, i, sv->sv_cpt_data) {
+		spin_lock(&scd->scd_lock);
+
+		/* schedule in-flight RPCs to notice the shutdown */
+		list_for_each_entry(rpc, &scd->scd_rpc_active, srpc_list)
+			swi_schedule_workitem(&rpc->srpc_wi);
+
+		spin_unlock(&scd->scd_lock);
+
+		/* OK to traverse scd_buf_posted without lock, since no one
+		 * touches scd_buf_posted now */
+		list_for_each_entry(buf, &scd->scd_buf_posted, buf_list)
+			LNetMDUnlink(buf->buf_mdh);
+	}
+}
+
+int
+srpc_send_request (srpc_client_rpc_t *rpc)
+{
+	srpc_event_t *ev = &rpc->crpc_reqstev;
+	int	   rc;
+
+	ev->ev_fired = 0;
+	ev->ev_data  = rpc;
+	ev->ev_type  = SRPC_REQUEST_SENT;
+
+	rc = srpc_post_active_rqtbuf(rpc->crpc_dest, rpc->crpc_service,
+				     &rpc->crpc_reqstmsg, sizeof(srpc_msg_t),
+				     &rpc->crpc_reqstmdh, ev);
+	if (rc != 0) {
+		LASSERT (rc == -ENOMEM);
+		ev->ev_fired = 1;  /* no more event expected */
+	}
+	return rc;
+}
+
+int
+srpc_prepare_reply (srpc_client_rpc_t *rpc)
+{
+	srpc_event_t *ev = &rpc->crpc_replyev;
+	__u64	*id = &rpc->crpc_reqstmsg.msg_body.reqst.rpyid;
+	int	   rc;
+
+	ev->ev_fired = 0;
+	ev->ev_data  = rpc;
+	ev->ev_type  = SRPC_REPLY_RCVD;
+
+	*id = srpc_next_id();
+
+	rc = srpc_post_passive_rdma(SRPC_RDMA_PORTAL, 0, *id,
+				    &rpc->crpc_replymsg, sizeof(srpc_msg_t),
+				    LNET_MD_OP_PUT, rpc->crpc_dest,
+				    &rpc->crpc_replymdh, ev);
+	if (rc != 0) {
+		LASSERT (rc == -ENOMEM);
+		ev->ev_fired = 1;  /* no more event expected */
+	}
+	return rc;
+}
+
+int
+srpc_prepare_bulk (srpc_client_rpc_t *rpc)
+{
+	srpc_bulk_t  *bk = &rpc->crpc_bulk;
+	srpc_event_t *ev = &rpc->crpc_bulkev;
+	__u64	*id = &rpc->crpc_reqstmsg.msg_body.reqst.bulkid;
+	int	   rc;
+	int	   opt;
+
+	LASSERT (bk->bk_niov <= LNET_MAX_IOV);
+
+	if (bk->bk_niov == 0) return 0; /* nothing to do */
+
+	opt = bk->bk_sink ? LNET_MD_OP_PUT : LNET_MD_OP_GET;
+	opt |= LNET_MD_KIOV;
+
+	ev->ev_fired = 0;
+	ev->ev_data  = rpc;
+	ev->ev_type  = SRPC_BULK_REQ_RCVD;
+
+	*id = srpc_next_id();
+
+	rc = srpc_post_passive_rdma(SRPC_RDMA_PORTAL, 0, *id,
+				    &bk->bk_iovs[0], bk->bk_niov, opt,
+				    rpc->crpc_dest, &bk->bk_mdh, ev);
+	if (rc != 0) {
+		LASSERT (rc == -ENOMEM);
+		ev->ev_fired = 1;  /* no more event expected */
+	}
+	return rc;
+}
+
+int
+srpc_do_bulk (srpc_server_rpc_t *rpc)
+{
+	srpc_event_t  *ev = &rpc->srpc_ev;
+	srpc_bulk_t   *bk = rpc->srpc_bulk;
+	__u64	  id = rpc->srpc_reqstbuf->buf_msg.msg_body.reqst.bulkid;
+	int	    rc;
+	int	    opt;
+
+	LASSERT (bk != NULL);
+
+	opt = bk->bk_sink ? LNET_MD_OP_GET : LNET_MD_OP_PUT;
+	opt |= LNET_MD_KIOV;
+
+	ev->ev_fired = 0;
+	ev->ev_data  = rpc;
+	ev->ev_type  = bk->bk_sink ? SRPC_BULK_GET_RPLD : SRPC_BULK_PUT_SENT;
+
+	rc = srpc_post_active_rdma(SRPC_RDMA_PORTAL, id,
+				   &bk->bk_iovs[0], bk->bk_niov, opt,
+				   rpc->srpc_peer, rpc->srpc_self,
+				   &bk->bk_mdh, ev);
+	if (rc != 0)
+		ev->ev_fired = 1;  /* no more event expected */
+	return rc;
+}
+
+/* only called from srpc_handle_rpc */
+void
+srpc_server_rpc_done(srpc_server_rpc_t *rpc, int status)
+{
+	struct srpc_service_cd	*scd = rpc->srpc_scd;
+	struct srpc_service	*sv  = scd->scd_svc;
+	srpc_buffer_t		*buffer;
+
+	LASSERT (status != 0 || rpc->srpc_wi.swi_state == SWI_STATE_DONE);
+
+	rpc->srpc_status = status;
+
+	CDEBUG_LIMIT (status == 0 ? D_NET : D_NETERROR,
+		"Server RPC %p done: service %s, peer %s, status %s:%d\n",
+		rpc, sv->sv_name, libcfs_id2str(rpc->srpc_peer),
+		swi_state2str(rpc->srpc_wi.swi_state), status);
+
+	if (status != 0) {
+		spin_lock(&srpc_data.rpc_glock);
+		srpc_data.rpc_counters.rpcs_dropped++;
+		spin_unlock(&srpc_data.rpc_glock);
+	}
+
+	if (rpc->srpc_done != NULL)
+		(*rpc->srpc_done) (rpc);
+	LASSERT(rpc->srpc_bulk == NULL);
+
+	spin_lock(&scd->scd_lock);
+
+	if (rpc->srpc_reqstbuf != NULL) {
+		/* NB might drop sv_lock in srpc_service_recycle_buffer, but
+		 * sv won't go away for scd_rpc_active must not be empty */
+		srpc_service_recycle_buffer(scd, rpc->srpc_reqstbuf);
+		rpc->srpc_reqstbuf = NULL;
+	}
+
+	list_del(&rpc->srpc_list); /* from scd->scd_rpc_active */
+
+	/*
+	 * No one can schedule me now since:
+	 * - I'm not on scd_rpc_active.
+	 * - all LNet events have been fired.
+	 * Cancel pending schedules and prevent future schedule attempts:
+	 */
+	LASSERT(rpc->srpc_ev.ev_fired);
+	swi_exit_workitem(&rpc->srpc_wi);
+
+	if (!sv->sv_shuttingdown && !list_empty(&scd->scd_buf_blocked)) {
+		buffer = list_entry(scd->scd_buf_blocked.next,
+					srpc_buffer_t, buf_list);
+		list_del(&buffer->buf_list);
+
+		srpc_init_server_rpc(rpc, scd, buffer);
+		list_add_tail(&rpc->srpc_list, &scd->scd_rpc_active);
+		swi_schedule_workitem(&rpc->srpc_wi);
+	} else {
+		list_add(&rpc->srpc_list, &scd->scd_rpc_free);
+	}
+
+	spin_unlock(&scd->scd_lock);
+	return;
+}
+
+/* handles an incoming RPC */
+int
+srpc_handle_rpc(swi_workitem_t *wi)
+{
+	struct srpc_server_rpc	*rpc = wi->swi_workitem.wi_data;
+	struct srpc_service_cd	*scd = rpc->srpc_scd;
+	struct srpc_service	*sv = scd->scd_svc;
+	srpc_event_t		*ev = &rpc->srpc_ev;
+	int			rc = 0;
+
+	LASSERT(wi == &rpc->srpc_wi);
+
+	spin_lock(&scd->scd_lock);
+
+	if (sv->sv_shuttingdown || rpc->srpc_aborted) {
+		spin_unlock(&scd->scd_lock);
+
+		if (rpc->srpc_bulk != NULL)
+			LNetMDUnlink(rpc->srpc_bulk->bk_mdh);
+		LNetMDUnlink(rpc->srpc_replymdh);
+
+		if (ev->ev_fired) { /* no more event, OK to finish */
+			srpc_server_rpc_done(rpc, -ESHUTDOWN);
+			return 1;
+		}
+		return 0;
+	}
+
+	spin_unlock(&scd->scd_lock);
+
+	switch (wi->swi_state) {
+	default:
+		LBUG ();
+	case SWI_STATE_NEWBORN: {
+		srpc_msg_t	   *msg;
+		srpc_generic_reply_t *reply;
+
+		msg = &rpc->srpc_reqstbuf->buf_msg;
+		reply = &rpc->srpc_replymsg.msg_body.reply;
+
+		if (msg->msg_magic == 0) {
+			/* moaned already in srpc_lnet_ev_handler */
+			srpc_server_rpc_done(rpc, EBADMSG);
+			return 1;
+		}
+
+		srpc_unpack_msg_hdr(msg);
+		if (msg->msg_version != SRPC_MSG_VERSION) {
+			CWARN("Version mismatch: %u, %u expected, from %s\n",
+			      msg->msg_version, SRPC_MSG_VERSION,
+			      libcfs_id2str(rpc->srpc_peer));
+			reply->status = EPROTO;
+			/* drop through and send reply */
+		} else {
+			reply->status = 0;
+			rc = (*sv->sv_handler)(rpc);
+			LASSERT(reply->status == 0 || !rpc->srpc_bulk);
+			if (rc != 0) {
+				srpc_server_rpc_done(rpc, rc);
+				return 1;
+			}
+		}
+
+		wi->swi_state = SWI_STATE_BULK_STARTED;
+
+		if (rpc->srpc_bulk != NULL) {
+			rc = srpc_do_bulk(rpc);
+			if (rc == 0)
+				return 0; /* wait for bulk */
+
+			LASSERT (ev->ev_fired);
+			ev->ev_status = rc;
+		}
+	}
+	case SWI_STATE_BULK_STARTED:
+		LASSERT (rpc->srpc_bulk == NULL || ev->ev_fired);
+
+		if (rpc->srpc_bulk != NULL) {
+			rc = ev->ev_status;
+
+			if (sv->sv_bulk_ready != NULL)
+				rc = (*sv->sv_bulk_ready) (rpc, rc);
+
+			if (rc != 0) {
+				srpc_server_rpc_done(rpc, rc);
+				return 1;
+			}
+		}
+
+		wi->swi_state = SWI_STATE_REPLY_SUBMITTED;
+		rc = srpc_send_reply(rpc);
+		if (rc == 0)
+			return 0; /* wait for reply */
+		srpc_server_rpc_done(rpc, rc);
+		return 1;
+
+	case SWI_STATE_REPLY_SUBMITTED:
+		if (!ev->ev_fired) {
+			CERROR("RPC %p: bulk %p, service %d\n",
+			       rpc, rpc->srpc_bulk, sv->sv_id);
+			CERROR("Event: status %d, type %d, lnet %d\n",
+			       ev->ev_status, ev->ev_type, ev->ev_lnet);
+			LASSERT (ev->ev_fired);
+		}
+
+		wi->swi_state = SWI_STATE_DONE;
+		srpc_server_rpc_done(rpc, ev->ev_status);
+		return 1;
+	}
+
+	return 0;
+}
+
+void
+srpc_client_rpc_expired (void *data)
+{
+	srpc_client_rpc_t *rpc = data;
+
+	CWARN ("Client RPC expired: service %d, peer %s, timeout %d.\n",
+	       rpc->crpc_service, libcfs_id2str(rpc->crpc_dest),
+	       rpc->crpc_timeout);
+
+	spin_lock(&rpc->crpc_lock);
+
+	rpc->crpc_timeout = 0;
+	srpc_abort_rpc(rpc, -ETIMEDOUT);
+
+	spin_unlock(&rpc->crpc_lock);
+
+	spin_lock(&srpc_data.rpc_glock);
+	srpc_data.rpc_counters.rpcs_expired++;
+	spin_unlock(&srpc_data.rpc_glock);
+}
+
+inline void
+srpc_add_client_rpc_timer (srpc_client_rpc_t *rpc)
+{
+	stt_timer_t *timer = &rpc->crpc_timer;
+
+	if (rpc->crpc_timeout == 0) return;
+
+	INIT_LIST_HEAD(&timer->stt_list);
+	timer->stt_data    = rpc;
+	timer->stt_func    = srpc_client_rpc_expired;
+	timer->stt_expires = cfs_time_add(rpc->crpc_timeout,
+					  cfs_time_current_sec());
+	stt_add_timer(timer);
+	return;
+}
+
+/*
+ * Called with rpc->crpc_lock held.
+ *
+ * Upon exit the RPC expiry timer is not queued and the handler is not
+ * running on any CPU. */
+void
+srpc_del_client_rpc_timer (srpc_client_rpc_t *rpc)
+{
+	/* timer not planted or already exploded */
+	if (rpc->crpc_timeout == 0)
+		return;
+
+	/* timer sucessfully defused */
+	if (stt_del_timer(&rpc->crpc_timer))
+		return;
+
+	/* timer detonated, wait for it to explode */
+	while (rpc->crpc_timeout != 0) {
+		spin_unlock(&rpc->crpc_lock);
+
+		schedule();
+
+		spin_lock(&rpc->crpc_lock);
+	}
+}
+
+void
+srpc_client_rpc_done (srpc_client_rpc_t *rpc, int status)
+{
+	swi_workitem_t *wi = &rpc->crpc_wi;
+
+	LASSERT(status != 0 || wi->swi_state == SWI_STATE_DONE);
+
+	spin_lock(&rpc->crpc_lock);
+
+	rpc->crpc_closed = 1;
+	if (rpc->crpc_status == 0)
+		rpc->crpc_status = status;
+
+	srpc_del_client_rpc_timer(rpc);
+
+	CDEBUG_LIMIT ((status == 0) ? D_NET : D_NETERROR,
+		"Client RPC done: service %d, peer %s, status %s:%d:%d\n",
+		rpc->crpc_service, libcfs_id2str(rpc->crpc_dest),
+		swi_state2str(wi->swi_state), rpc->crpc_aborted, status);
+
+	/*
+	 * No one can schedule me now since:
+	 * - RPC timer has been defused.
+	 * - all LNet events have been fired.
+	 * - crpc_closed has been set, preventing srpc_abort_rpc from
+	 *   scheduling me.
+	 * Cancel pending schedules and prevent future schedule attempts:
+	 */
+	LASSERT (!srpc_event_pending(rpc));
+	swi_exit_workitem(wi);
+
+	spin_unlock(&rpc->crpc_lock);
+
+	(*rpc->crpc_done)(rpc);
+	return;
+}
+
+/* sends an outgoing RPC */
+int
+srpc_send_rpc (swi_workitem_t *wi)
+{
+	int		rc = 0;
+	srpc_client_rpc_t *rpc;
+	srpc_msg_t	*reply;
+	int		do_bulk;
+
+	LASSERT(wi != NULL);
+
+	rpc = wi->swi_workitem.wi_data;
+
+	LASSERT (rpc != NULL);
+	LASSERT (wi == &rpc->crpc_wi);
+
+	reply = &rpc->crpc_replymsg;
+	do_bulk = rpc->crpc_bulk.bk_niov > 0;
+
+	spin_lock(&rpc->crpc_lock);
+
+	if (rpc->crpc_aborted) {
+		spin_unlock(&rpc->crpc_lock);
+		goto abort;
+	}
+
+	spin_unlock(&rpc->crpc_lock);
+
+	switch (wi->swi_state) {
+	default:
+		LBUG ();
+	case SWI_STATE_NEWBORN:
+		LASSERT (!srpc_event_pending(rpc));
+
+		rc = srpc_prepare_reply(rpc);
+		if (rc != 0) {
+			srpc_client_rpc_done(rpc, rc);
+			return 1;
+		}
+
+		rc = srpc_prepare_bulk(rpc);
+		if (rc != 0) break;
+
+		wi->swi_state = SWI_STATE_REQUEST_SUBMITTED;
+		rc = srpc_send_request(rpc);
+		break;
+
+	case SWI_STATE_REQUEST_SUBMITTED:
+		/* CAVEAT EMPTOR: rqtev, rpyev, and bulkev may come in any
+		 * order; however, they're processed in a strict order:
+		 * rqt, rpy, and bulk. */
+		if (!rpc->crpc_reqstev.ev_fired) break;
+
+		rc = rpc->crpc_reqstev.ev_status;
+		if (rc != 0) break;
+
+		wi->swi_state = SWI_STATE_REQUEST_SENT;
+		/* perhaps more events, fall thru */
+	case SWI_STATE_REQUEST_SENT: {
+		srpc_msg_type_t type = srpc_service2reply(rpc->crpc_service);
+
+		if (!rpc->crpc_replyev.ev_fired) break;
+
+		rc = rpc->crpc_replyev.ev_status;
+		if (rc != 0) break;
+
+		srpc_unpack_msg_hdr(reply);
+		if (reply->msg_type != type ||
+		    (reply->msg_magic != SRPC_MSG_MAGIC &&
+		     reply->msg_magic != __swab32(SRPC_MSG_MAGIC))) {
+			CWARN ("Bad message from %s: type %u (%d expected),"
+			       " magic %u (%d expected).\n",
+			       libcfs_id2str(rpc->crpc_dest),
+			       reply->msg_type, type,
+			       reply->msg_magic, SRPC_MSG_MAGIC);
+			rc = -EBADMSG;
+			break;
+		}
+
+		if (do_bulk && reply->msg_body.reply.status != 0) {
+			CWARN ("Remote error %d at %s, unlink bulk buffer in "
+			       "case peer didn't initiate bulk transfer\n",
+			       reply->msg_body.reply.status,
+			       libcfs_id2str(rpc->crpc_dest));
+			LNetMDUnlink(rpc->crpc_bulk.bk_mdh);
+		}
+
+		wi->swi_state = SWI_STATE_REPLY_RECEIVED;
+	}
+	case SWI_STATE_REPLY_RECEIVED:
+		if (do_bulk && !rpc->crpc_bulkev.ev_fired) break;
+
+		rc = do_bulk ? rpc->crpc_bulkev.ev_status : 0;
+
+		/* Bulk buffer was unlinked due to remote error. Clear error
+		 * since reply buffer still contains valid data.
+		 * NB rpc->crpc_done shouldn't look into bulk data in case of
+		 * remote error. */
+		if (do_bulk && rpc->crpc_bulkev.ev_lnet == LNET_EVENT_UNLINK &&
+		    rpc->crpc_status == 0 && reply->msg_body.reply.status != 0)
+			rc = 0;
+
+		wi->swi_state = SWI_STATE_DONE;
+		srpc_client_rpc_done(rpc, rc);
+		return 1;
+	}
+
+	if (rc != 0) {
+		spin_lock(&rpc->crpc_lock);
+		srpc_abort_rpc(rpc, rc);
+		spin_unlock(&rpc->crpc_lock);
+	}
+
+abort:
+	if (rpc->crpc_aborted) {
+		LNetMDUnlink(rpc->crpc_reqstmdh);
+		LNetMDUnlink(rpc->crpc_replymdh);
+		LNetMDUnlink(rpc->crpc_bulk.bk_mdh);
+
+		if (!srpc_event_pending(rpc)) {
+			srpc_client_rpc_done(rpc, -EINTR);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+srpc_client_rpc_t *
+srpc_create_client_rpc (lnet_process_id_t peer, int service,
+			int nbulkiov, int bulklen,
+			void (*rpc_done)(srpc_client_rpc_t *),
+			void (*rpc_fini)(srpc_client_rpc_t *), void *priv)
+{
+	srpc_client_rpc_t *rpc;
+
+	LIBCFS_ALLOC(rpc, offsetof(srpc_client_rpc_t,
+				   crpc_bulk.bk_iovs[nbulkiov]));
+	if (rpc == NULL)
+		return NULL;
+
+	srpc_init_client_rpc(rpc, peer, service, nbulkiov,
+			     bulklen, rpc_done, rpc_fini, priv);
+	return rpc;
+}
+
+/* called with rpc->crpc_lock held */
+void
+srpc_abort_rpc (srpc_client_rpc_t *rpc, int why)
+{
+	LASSERT (why != 0);
+
+	if (rpc->crpc_aborted || /* already aborted */
+	    rpc->crpc_closed)    /* callback imminent */
+		return;
+
+	CDEBUG (D_NET,
+		"Aborting RPC: service %d, peer %s, state %s, why %d\n",
+		rpc->crpc_service, libcfs_id2str(rpc->crpc_dest),
+		swi_state2str(rpc->crpc_wi.swi_state), why);
+
+	rpc->crpc_aborted = 1;
+	rpc->crpc_status  = why;
+	swi_schedule_workitem(&rpc->crpc_wi);
+	return;
+}
+
+/* called with rpc->crpc_lock held */
+void
+srpc_post_rpc (srpc_client_rpc_t *rpc)
+{
+	LASSERT (!rpc->crpc_aborted);
+	LASSERT (srpc_data.rpc_state == SRPC_STATE_RUNNING);
+
+	CDEBUG (D_NET, "Posting RPC: peer %s, service %d, timeout %d\n",
+		libcfs_id2str(rpc->crpc_dest), rpc->crpc_service,
+		rpc->crpc_timeout);
+
+	srpc_add_client_rpc_timer(rpc);
+	swi_schedule_workitem(&rpc->crpc_wi);
+	return;
+}
+
+
+int
+srpc_send_reply(struct srpc_server_rpc *rpc)
+{
+	srpc_event_t		*ev = &rpc->srpc_ev;
+	struct srpc_msg		*msg = &rpc->srpc_replymsg;
+	struct srpc_buffer	*buffer = rpc->srpc_reqstbuf;
+	struct srpc_service_cd	*scd = rpc->srpc_scd;
+	struct srpc_service	*sv = scd->scd_svc;
+	__u64			rpyid;
+	int			rc;
+
+	LASSERT(buffer != NULL);
+	rpyid = buffer->buf_msg.msg_body.reqst.rpyid;
+
+	spin_lock(&scd->scd_lock);
+
+	if (!sv->sv_shuttingdown && !srpc_serv_is_framework(sv)) {
+		/* Repost buffer before replying since test client
+		 * might send me another RPC once it gets the reply */
+		if (srpc_service_post_buffer(scd, buffer) != 0)
+			CWARN("Failed to repost %s buffer\n", sv->sv_name);
+		rpc->srpc_reqstbuf = NULL;
+	}
+
+	spin_unlock(&scd->scd_lock);
+
+	ev->ev_fired = 0;
+	ev->ev_data  = rpc;
+	ev->ev_type  = SRPC_REPLY_SENT;
+
+	msg->msg_magic   = SRPC_MSG_MAGIC;
+	msg->msg_version = SRPC_MSG_VERSION;
+	msg->msg_type    = srpc_service2reply(sv->sv_id);
+
+	rc = srpc_post_active_rdma(SRPC_RDMA_PORTAL, rpyid, msg,
+				   sizeof(*msg), LNET_MD_OP_PUT,
+				   rpc->srpc_peer, rpc->srpc_self,
+				   &rpc->srpc_replymdh, ev);
+	if (rc != 0)
+		ev->ev_fired = 1;  /* no more event expected */
+	return rc;
+}
+
+/* when in kernel always called with LNET_LOCK() held, and in thread context */
+void
+srpc_lnet_ev_handler(lnet_event_t *ev)
+{
+	struct srpc_service_cd	*scd;
+	srpc_event_t      *rpcev = ev->md.user_ptr;
+	srpc_client_rpc_t *crpc;
+	srpc_server_rpc_t *srpc;
+	srpc_buffer_t     *buffer;
+	srpc_service_t    *sv;
+	srpc_msg_t	*msg;
+	srpc_msg_type_t    type;
+
+	LASSERT (!in_interrupt());
+
+	if (ev->status != 0) {
+		spin_lock(&srpc_data.rpc_glock);
+		srpc_data.rpc_counters.errors++;
+		spin_unlock(&srpc_data.rpc_glock);
+	}
+
+	rpcev->ev_lnet = ev->type;
+
+	switch (rpcev->ev_type) {
+	default:
+		CERROR("Unknown event: status %d, type %d, lnet %d\n",
+		       rpcev->ev_status, rpcev->ev_type, rpcev->ev_lnet);
+		LBUG ();
+	case SRPC_REQUEST_SENT:
+		if (ev->status == 0 && ev->type != LNET_EVENT_UNLINK) {
+			spin_lock(&srpc_data.rpc_glock);
+			srpc_data.rpc_counters.rpcs_sent++;
+			spin_unlock(&srpc_data.rpc_glock);
+		}
+	case SRPC_REPLY_RCVD:
+	case SRPC_BULK_REQ_RCVD:
+		crpc = rpcev->ev_data;
+
+		if (rpcev != &crpc->crpc_reqstev &&
+		    rpcev != &crpc->crpc_replyev &&
+		    rpcev != &crpc->crpc_bulkev) {
+			CERROR("rpcev %p, crpc %p, reqstev %p, replyev %p, bulkev %p\n",
+			       rpcev, crpc, &crpc->crpc_reqstev,
+			       &crpc->crpc_replyev, &crpc->crpc_bulkev);
+			CERROR("Bad event: status %d, type %d, lnet %d\n",
+			       rpcev->ev_status, rpcev->ev_type, rpcev->ev_lnet);
+			LBUG ();
+		}
+
+		spin_lock(&crpc->crpc_lock);
+
+		LASSERT(rpcev->ev_fired == 0);
+		rpcev->ev_fired  = 1;
+		rpcev->ev_status = (ev->type == LNET_EVENT_UNLINK) ?
+						-EINTR : ev->status;
+		swi_schedule_workitem(&crpc->crpc_wi);
+
+		spin_unlock(&crpc->crpc_lock);
+		break;
+
+	case SRPC_REQUEST_RCVD:
+		scd = rpcev->ev_data;
+		sv = scd->scd_svc;
+
+		LASSERT(rpcev == &scd->scd_ev);
+
+		spin_lock(&scd->scd_lock);
+
+		LASSERT (ev->unlinked);
+		LASSERT (ev->type == LNET_EVENT_PUT ||
+			 ev->type == LNET_EVENT_UNLINK);
+		LASSERT (ev->type != LNET_EVENT_UNLINK ||
+			 sv->sv_shuttingdown);
+
+		buffer = container_of(ev->md.start, srpc_buffer_t, buf_msg);
+		buffer->buf_peer = ev->initiator;
+		buffer->buf_self = ev->target.nid;
+
+		LASSERT(scd->scd_buf_nposted > 0);
+		scd->scd_buf_nposted--;
+
+		if (sv->sv_shuttingdown) {
+			/* Leave buffer on scd->scd_buf_nposted since
+			 * srpc_finish_service needs to traverse it. */
+			spin_unlock(&scd->scd_lock);
+			break;
+		}
+
+		if (scd->scd_buf_err_stamp != 0 &&
+		    scd->scd_buf_err_stamp < cfs_time_current_sec()) {
+			/* re-enable adding buffer */
+			scd->scd_buf_err_stamp = 0;
+			scd->scd_buf_err = 0;
+		}
+
+		if (scd->scd_buf_err == 0 && /* adding buffer is enabled */
+		    scd->scd_buf_adjust == 0 &&
+		    scd->scd_buf_nposted < scd->scd_buf_low) {
+			scd->scd_buf_adjust = MAX(scd->scd_buf_total / 2,
+						  SFW_TEST_WI_MIN);
+			swi_schedule_workitem(&scd->scd_buf_wi);
+		}
+
+		list_del(&buffer->buf_list); /* from scd->scd_buf_posted */
+		msg = &buffer->buf_msg;
+		type = srpc_service2request(sv->sv_id);
+
+		if (ev->status != 0 || ev->mlength != sizeof(*msg) ||
+		    (msg->msg_type != type &&
+		     msg->msg_type != __swab32(type)) ||
+		    (msg->msg_magic != SRPC_MSG_MAGIC &&
+		     msg->msg_magic != __swab32(SRPC_MSG_MAGIC))) {
+			CERROR ("Dropping RPC (%s) from %s: "
+				"status %d mlength %d type %u magic %u.\n",
+				sv->sv_name, libcfs_id2str(ev->initiator),
+				ev->status, ev->mlength,
+				msg->msg_type, msg->msg_magic);
+
+			/* NB can't call srpc_service_recycle_buffer here since
+			 * it may call LNetM[DE]Attach. The invalid magic tells
+			 * srpc_handle_rpc to drop this RPC */
+			msg->msg_magic = 0;
+		}
+
+		if (!list_empty(&scd->scd_rpc_free)) {
+			srpc = list_entry(scd->scd_rpc_free.next,
+					      struct srpc_server_rpc,
+					      srpc_list);
+			list_del(&srpc->srpc_list);
+
+			srpc_init_server_rpc(srpc, scd, buffer);
+			list_add_tail(&srpc->srpc_list,
+					  &scd->scd_rpc_active);
+			swi_schedule_workitem(&srpc->srpc_wi);
+		} else {
+			list_add_tail(&buffer->buf_list,
+					  &scd->scd_buf_blocked);
+		}
+
+		spin_unlock(&scd->scd_lock);
+
+		spin_lock(&srpc_data.rpc_glock);
+		srpc_data.rpc_counters.rpcs_rcvd++;
+		spin_unlock(&srpc_data.rpc_glock);
+		break;
+
+	case SRPC_BULK_GET_RPLD:
+		LASSERT (ev->type == LNET_EVENT_SEND ||
+			 ev->type == LNET_EVENT_REPLY ||
+			 ev->type == LNET_EVENT_UNLINK);
+
+		if (!ev->unlinked)
+			break; /* wait for final event */
+
+	case SRPC_BULK_PUT_SENT:
+		if (ev->status == 0 && ev->type != LNET_EVENT_UNLINK) {
+			spin_lock(&srpc_data.rpc_glock);
+
+			if (rpcev->ev_type == SRPC_BULK_GET_RPLD)
+				srpc_data.rpc_counters.bulk_get += ev->mlength;
+			else
+				srpc_data.rpc_counters.bulk_put += ev->mlength;
+
+			spin_unlock(&srpc_data.rpc_glock);
+		}
+	case SRPC_REPLY_SENT:
+		srpc = rpcev->ev_data;
+		scd  = srpc->srpc_scd;
+
+		LASSERT(rpcev == &srpc->srpc_ev);
+
+		spin_lock(&scd->scd_lock);
+
+		rpcev->ev_fired  = 1;
+		rpcev->ev_status = (ev->type == LNET_EVENT_UNLINK) ?
+				   -EINTR : ev->status;
+		swi_schedule_workitem(&srpc->srpc_wi);
+
+		spin_unlock(&scd->scd_lock);
+		break;
+	}
+}
+
+
+int
+srpc_startup (void)
+{
+	int rc;
+
+	memset(&srpc_data, 0, sizeof(struct smoketest_rpc));
+	spin_lock_init(&srpc_data.rpc_glock);
+
+	/* 1 second pause to avoid timestamp reuse */
+	cfs_pause(cfs_time_seconds(1));
+	srpc_data.rpc_matchbits = ((__u64) cfs_time_current_sec()) << 48;
+
+	srpc_data.rpc_state = SRPC_STATE_NONE;
+
+	rc = LNetNIInit(LUSTRE_SRV_LNET_PID);
+	if (rc < 0) {
+		CERROR ("LNetNIInit() has failed: %d\n", rc);
+		return rc;
+	}
+
+	srpc_data.rpc_state = SRPC_STATE_NI_INIT;
+
+	LNetInvalidateHandle(&srpc_data.rpc_lnet_eq);
+	rc = LNetEQAlloc(0, srpc_lnet_ev_handler, &srpc_data.rpc_lnet_eq);
+	if (rc != 0) {
+		CERROR("LNetEQAlloc() has failed: %d\n", rc);
+		goto bail;
+	}
+
+	rc = LNetSetLazyPortal(SRPC_FRAMEWORK_REQUEST_PORTAL);
+	LASSERT(rc == 0);
+	rc = LNetSetLazyPortal(SRPC_REQUEST_PORTAL);
+	LASSERT(rc == 0);
+
+	srpc_data.rpc_state = SRPC_STATE_EQ_INIT;
+
+	rc = stt_startup();
+
+bail:
+	if (rc != 0)
+		srpc_shutdown();
+	else
+		srpc_data.rpc_state = SRPC_STATE_RUNNING;
+
+	return rc;
+}
+
+void
+srpc_shutdown (void)
+{
+	int i;
+	int rc;
+	int state;
+
+	state = srpc_data.rpc_state;
+	srpc_data.rpc_state = SRPC_STATE_STOPPING;
+
+	switch (state) {
+	default:
+		LBUG ();
+	case SRPC_STATE_RUNNING:
+		spin_lock(&srpc_data.rpc_glock);
+
+		for (i = 0; i <= SRPC_SERVICE_MAX_ID; i++) {
+			srpc_service_t *sv = srpc_data.rpc_services[i];
+
+			LASSERTF (sv == NULL,
+				  "service not empty: id %d, name %s\n",
+				  i, sv->sv_name);
+		}
+
+		spin_unlock(&srpc_data.rpc_glock);
+
+		stt_shutdown();
+
+	case SRPC_STATE_EQ_INIT:
+		rc = LNetClearLazyPortal(SRPC_FRAMEWORK_REQUEST_PORTAL);
+		rc = LNetClearLazyPortal(SRPC_REQUEST_PORTAL);
+		LASSERT (rc == 0);
+		rc = LNetEQFree(srpc_data.rpc_lnet_eq);
+		LASSERT (rc == 0); /* the EQ should have no user by now */
+
+	case SRPC_STATE_NI_INIT:
+		LNetNIFini();
+	}
+
+	return;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/rpc.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/rpc.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/rpc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/rpc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,302 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __SELFTEST_RPC_H__
+#define __SELFTEST_RPC_H__
+
+#include <linux/lnet/lnetst.h>
+
+/*
+ * LST wired structures
+ *
+ * XXX: *REPLY == *REQST + 1
+ */
+typedef enum {
+	SRPC_MSG_MKSN_REQST     = 0,
+	SRPC_MSG_MKSN_REPLY     = 1,
+	SRPC_MSG_RMSN_REQST     = 2,
+	SRPC_MSG_RMSN_REPLY     = 3,
+	SRPC_MSG_BATCH_REQST    = 4,
+	SRPC_MSG_BATCH_REPLY    = 5,
+	SRPC_MSG_STAT_REQST     = 6,
+	SRPC_MSG_STAT_REPLY     = 7,
+	SRPC_MSG_TEST_REQST     = 8,
+	SRPC_MSG_TEST_REPLY     = 9,
+	SRPC_MSG_DEBUG_REQST    = 10,
+	SRPC_MSG_DEBUG_REPLY    = 11,
+	SRPC_MSG_BRW_REQST      = 12,
+	SRPC_MSG_BRW_REPLY      = 13,
+	SRPC_MSG_PING_REQST     = 14,
+	SRPC_MSG_PING_REPLY     = 15,
+	SRPC_MSG_JOIN_REQST     = 16,
+	SRPC_MSG_JOIN_REPLY     = 17,
+} srpc_msg_type_t;
+
+
+/* CAVEAT EMPTOR:
+ * All srpc_*_reqst_t's 1st field must be matchbits of reply buffer,
+ * and 2nd field matchbits of bulk buffer if any.
+ *
+ * All srpc_*_reply_t's 1st field must be a __u32 status, and 2nd field
+ * session id if needed.
+ */
+typedef struct {
+	__u64			rpyid;		/* reply buffer matchbits */
+	__u64			bulkid;		/* bulk buffer matchbits */
+} WIRE_ATTR srpc_generic_reqst_t;
+
+typedef struct {
+	__u32		   status;
+	lst_sid_t	       sid;
+} WIRE_ATTR srpc_generic_reply_t;
+
+/* FRAMEWORK RPCs */
+typedef struct {
+	__u64			mksn_rpyid;      /* reply buffer matchbits */
+	lst_sid_t	       mksn_sid;	/* session id */
+	__u32			mksn_force;      /* use brute force */
+	char			mksn_name[LST_NAME_SIZE];
+} WIRE_ATTR srpc_mksn_reqst_t;			/* make session request */
+
+typedef struct {
+	__u32		   mksn_status;      /* session status */
+	lst_sid_t	       mksn_sid;	 /* session id */
+	__u32		   mksn_timeout;     /* session timeout */
+	char			mksn_name[LST_NAME_SIZE];
+} WIRE_ATTR srpc_mksn_reply_t; /* make session reply */
+
+typedef struct {
+	__u64			rmsn_rpyid;      /* reply buffer matchbits */
+	lst_sid_t		rmsn_sid;	/* session id */
+} WIRE_ATTR srpc_rmsn_reqst_t; /* remove session request */
+
+typedef struct {
+	__u32			rmsn_status;
+	lst_sid_t		rmsn_sid;	/* session id */
+} WIRE_ATTR srpc_rmsn_reply_t; /* remove session reply */
+
+typedef struct {
+	__u64			join_rpyid;     /* reply buffer matchbits */
+	lst_sid_t	       join_sid;       /* session id to join */
+	char		    join_group[LST_NAME_SIZE]; /* group name */
+} WIRE_ATTR srpc_join_reqst_t;
+
+typedef struct {
+	__u32		   join_status;    /* returned status */
+	lst_sid_t	       join_sid;       /* session id */
+	__u32			join_timeout;   /* # seconds' inactivity to expire */
+	char		    join_session[LST_NAME_SIZE]; /* session name */
+} WIRE_ATTR srpc_join_reply_t;
+
+typedef struct {
+	__u64		   dbg_rpyid;      /* reply buffer matchbits */
+	lst_sid_t	       dbg_sid;	/* session id */
+	__u32		   dbg_flags;      /* bitmap of debug */
+} WIRE_ATTR srpc_debug_reqst_t;
+
+typedef struct {
+	__u32		   dbg_status;     /* returned code */
+	lst_sid_t	       dbg_sid;	/* session id */
+	__u32		   dbg_timeout;    /* session timeout */
+	__u32		   dbg_nbatch;     /* # of batches in the node */
+	char		    dbg_name[LST_NAME_SIZE]; /* session name */
+} WIRE_ATTR srpc_debug_reply_t;
+
+#define SRPC_BATCH_OPC_RUN      1
+#define SRPC_BATCH_OPC_STOP     2
+#define SRPC_BATCH_OPC_QUERY    3
+
+typedef struct {
+	__u64		   bar_rpyid;      /* reply buffer matchbits */
+	lst_sid_t	       bar_sid;	/* session id */
+	lst_bid_t	       bar_bid;	/* batch id */
+	__u32		   bar_opc;	/* create/start/stop batch */
+	__u32		   bar_testidx;    /* index of test */
+	__u32		   bar_arg;	/* parameters */
+} WIRE_ATTR srpc_batch_reqst_t;
+
+typedef struct {
+	__u32		   bar_status;     /* status of request */
+	lst_sid_t	       bar_sid;	/* session id */
+	__u32		   bar_active;     /* # of active tests in batch/test */
+	__u32		   bar_time;       /* remained time */
+} WIRE_ATTR srpc_batch_reply_t;
+
+typedef struct {
+	__u64		   str_rpyid;      /* reply buffer matchbits */
+	lst_sid_t	       str_sid;	/* session id */
+	__u32		   str_type;       /* type of stat */
+} WIRE_ATTR srpc_stat_reqst_t;
+
+typedef struct {
+	__u32		   str_status;
+	lst_sid_t	       str_sid;
+	sfw_counters_t	  str_fw;
+	srpc_counters_t	 str_rpc;
+	lnet_counters_t	 str_lnet;
+} WIRE_ATTR srpc_stat_reply_t;
+
+typedef struct {
+	__u32		   blk_opc;	/* bulk operation code */
+	__u32		   blk_npg;	/* # of pages */
+	__u32		   blk_flags;      /* reserved flags */
+} WIRE_ATTR test_bulk_req_t;
+
+typedef struct {
+	/** bulk operation code */
+	__u16			blk_opc;
+	/** data check flags */
+	__u16			blk_flags;
+	/** data length */
+	__u32			blk_len;
+	/** reserved: offset */
+	__u32		   blk_offset;
+} WIRE_ATTR test_bulk_req_v1_t;
+
+typedef struct {
+	__u32			png_size;       /* size of ping message */
+	__u32			png_flags;      /* reserved flags */
+} WIRE_ATTR test_ping_req_t;
+
+typedef struct {
+	__u64			tsr_rpyid;      /* reply buffer matchbits */
+	__u64			tsr_bulkid;     /* bulk buffer matchbits */
+	lst_sid_t		tsr_sid;	/* session id */
+	lst_bid_t		tsr_bid;	/* batch id */
+	__u32			tsr_service;    /* test type: bulk|ping|... */
+	/* test client loop count or # server buffers needed */
+	__u32			tsr_loop;
+	__u32			tsr_concur;     /* concurrency of test */
+	__u8			tsr_is_client;  /* is test client or not */
+	__u8			tsr_stop_onerr; /* stop on error */
+	__u32			tsr_ndest;      /* # of dest nodes */
+
+	union {
+		test_ping_req_t		ping;
+		test_bulk_req_t		bulk_v0;
+		test_bulk_req_v1_t	bulk_v1;
+	}		tsr_u;
+} WIRE_ATTR srpc_test_reqst_t;
+
+typedef struct {
+	__u32			tsr_status;     /* returned code */
+	lst_sid_t		tsr_sid;
+} WIRE_ATTR srpc_test_reply_t;
+
+/* TEST RPCs */
+typedef struct {
+	__u64		   pnr_rpyid;
+	__u32		   pnr_magic;
+	__u32		   pnr_seq;
+	__u64		   pnr_time_sec;
+	__u64		   pnr_time_usec;
+} WIRE_ATTR srpc_ping_reqst_t;
+
+typedef struct {
+	__u32		   pnr_status;
+	__u32		   pnr_magic;
+	__u32		   pnr_seq;
+} WIRE_ATTR srpc_ping_reply_t;
+
+typedef struct {
+	__u64		   brw_rpyid;      /* reply buffer matchbits */
+	__u64		   brw_bulkid;     /* bulk buffer matchbits */
+	__u32		   brw_rw;	 /* read or write */
+	__u32		   brw_len;	/* bulk data len */
+	__u32		   brw_flags;      /* bulk data patterns */
+} WIRE_ATTR srpc_brw_reqst_t; /* bulk r/w request */
+
+typedef struct {
+	__u32		   brw_status;
+} WIRE_ATTR srpc_brw_reply_t; /* bulk r/w reply */
+
+#define SRPC_MSG_MAGIC		  0xeeb0f00d
+#define SRPC_MSG_VERSION		1
+
+typedef struct srpc_msg {
+	/** magic number */
+	__u32	msg_magic;
+	/** message version number */
+	__u32	msg_version;
+	/** type of message body: srpc_msg_type_t */
+	__u32	msg_type;
+	__u32	msg_reserved0;
+	__u32	msg_reserved1;
+	/** test session features */
+	__u32	msg_ses_feats;
+	union {
+		srpc_generic_reqst_t reqst;
+		srpc_generic_reply_t reply;
+
+		srpc_mksn_reqst_t    mksn_reqst;
+		srpc_mksn_reply_t    mksn_reply;
+		srpc_rmsn_reqst_t    rmsn_reqst;
+		srpc_rmsn_reply_t    rmsn_reply;
+		srpc_debug_reqst_t   dbg_reqst;
+		srpc_debug_reply_t   dbg_reply;
+		srpc_batch_reqst_t   bat_reqst;
+		srpc_batch_reply_t   bat_reply;
+		srpc_stat_reqst_t    stat_reqst;
+		srpc_stat_reply_t    stat_reply;
+		srpc_test_reqst_t    tes_reqst;
+		srpc_test_reply_t    tes_reply;
+		srpc_join_reqst_t    join_reqst;
+		srpc_join_reply_t    join_reply;
+
+		srpc_ping_reqst_t    ping_reqst;
+		srpc_ping_reply_t    ping_reply;
+		srpc_brw_reqst_t     brw_reqst;
+		srpc_brw_reply_t     brw_reply;
+	}     msg_body;
+} WIRE_ATTR srpc_msg_t;
+
+static inline void
+srpc_unpack_msg_hdr(srpc_msg_t *msg)
+{
+	if (msg->msg_magic == SRPC_MSG_MAGIC)
+		return; /* no flipping needed */
+
+	/* We do not swap the magic number here as it is needed to
+	   determine whether the body needs to be swapped. */
+	/* __swab32s(&msg->msg_magic); */
+	__swab32s(&msg->msg_type);
+	__swab32s(&msg->msg_version);
+	__swab32s(&msg->msg_ses_feats);
+	__swab32s(&msg->msg_reserved0);
+	__swab32s(&msg->msg_reserved1);
+}
+
+#endif /* __SELFTEST_RPC_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/selftest.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/selftest.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/selftest.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/selftest.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,611 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ * copy of GPLv2].
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/selftest.h
+ *
+ * Author: Isaac Huang <isaac@clusterfs.com>
+ */
+#ifndef __SELFTEST_SELFTEST_H__
+#define __SELFTEST_SELFTEST_H__
+
+#define LNET_ONLY
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/lnet.h>
+#include <linux/lnet/lib-lnet.h>
+#include <linux/lnet/lib-types.h>
+#include <linux/lnet/lnetst.h>
+
+#include "rpc.h"
+#include "timer.h"
+
+#ifndef MADE_WITHOUT_COMPROMISE
+#define MADE_WITHOUT_COMPROMISE
+#endif
+
+
+#define SWI_STATE_NEWBORN		  0
+#define SWI_STATE_REPLY_SUBMITTED	  1
+#define SWI_STATE_REPLY_SENT	       2
+#define SWI_STATE_REQUEST_SUBMITTED	3
+#define SWI_STATE_REQUEST_SENT	     4
+#define SWI_STATE_REPLY_RECEIVED	   5
+#define SWI_STATE_BULK_STARTED	     6
+#define SWI_STATE_DONE		     10
+
+/* forward refs */
+struct srpc_service;
+struct srpc_service_cd;
+struct sfw_test_unit;
+struct sfw_test_instance;
+
+/* services below SRPC_FRAMEWORK_SERVICE_MAX_ID are framework
+ * services, e.g. create/modify session.
+ */
+#define SRPC_SERVICE_DEBUG	      0
+#define SRPC_SERVICE_MAKE_SESSION       1
+#define SRPC_SERVICE_REMOVE_SESSION     2
+#define SRPC_SERVICE_BATCH	      3
+#define SRPC_SERVICE_TEST	       4
+#define SRPC_SERVICE_QUERY_STAT	 5
+#define SRPC_SERVICE_JOIN	       6
+#define SRPC_FRAMEWORK_SERVICE_MAX_ID   10
+/* other services start from SRPC_FRAMEWORK_SERVICE_MAX_ID+1 */
+#define SRPC_SERVICE_BRW		11
+#define SRPC_SERVICE_PING	       12
+#define SRPC_SERVICE_MAX_ID	     12
+
+#define SRPC_REQUEST_PORTAL	     50
+/* a lazy portal for framework RPC requests */
+#define SRPC_FRAMEWORK_REQUEST_PORTAL   51
+/* all reply/bulk RDMAs go to this portal */
+#define SRPC_RDMA_PORTAL		52
+
+static inline srpc_msg_type_t
+srpc_service2request (int service)
+{
+	switch (service) {
+	default:
+		LBUG ();
+	case SRPC_SERVICE_DEBUG:
+		return SRPC_MSG_DEBUG_REQST;
+
+	case SRPC_SERVICE_MAKE_SESSION:
+		return SRPC_MSG_MKSN_REQST;
+
+	case SRPC_SERVICE_REMOVE_SESSION:
+		return SRPC_MSG_RMSN_REQST;
+
+	case SRPC_SERVICE_BATCH:
+		return SRPC_MSG_BATCH_REQST;
+
+	case SRPC_SERVICE_TEST:
+		return SRPC_MSG_TEST_REQST;
+
+	case SRPC_SERVICE_QUERY_STAT:
+		return SRPC_MSG_STAT_REQST;
+
+	case SRPC_SERVICE_BRW:
+		return SRPC_MSG_BRW_REQST;
+
+	case SRPC_SERVICE_PING:
+		return SRPC_MSG_PING_REQST;
+
+	case SRPC_SERVICE_JOIN:
+		return SRPC_MSG_JOIN_REQST;
+	}
+}
+
+static inline srpc_msg_type_t
+srpc_service2reply (int service)
+{
+	return srpc_service2request(service) + 1;
+}
+
+typedef enum {
+	SRPC_BULK_REQ_RCVD   = 1, /* passive bulk request(PUT sink/GET source) received */
+	SRPC_BULK_PUT_SENT   = 2, /* active bulk PUT sent (source) */
+	SRPC_BULK_GET_RPLD   = 3, /* active bulk GET replied (sink) */
+	SRPC_REPLY_RCVD      = 4, /* incoming reply received */
+	SRPC_REPLY_SENT      = 5, /* outgoing reply sent */
+	SRPC_REQUEST_RCVD    = 6, /* incoming request received */
+	SRPC_REQUEST_SENT    = 7, /* outgoing request sent */
+} srpc_event_type_t;
+
+/* RPC event */
+typedef struct {
+	srpc_event_type_t ev_type;   /* what's up */
+	lnet_event_kind_t ev_lnet;   /* LNet event type */
+	int	       ev_fired;  /* LNet event fired? */
+	int	       ev_status; /* LNet event status */
+	void	     *ev_data;   /* owning server/client RPC */
+} srpc_event_t;
+
+typedef struct {
+	int	      bk_len;  /* len of bulk data */
+	lnet_handle_md_t bk_mdh;
+	int	      bk_sink; /* sink/source */
+	int	      bk_niov; /* # iov in bk_iovs */
+	lnet_kiov_t      bk_iovs[0];
+} srpc_bulk_t; /* bulk descriptor */
+
+/* message buffer descriptor */
+typedef struct srpc_buffer {
+	struct list_head	   buf_list; /* chain on srpc_service::*_msgq */
+	srpc_msg_t	   buf_msg;
+	lnet_handle_md_t     buf_mdh;
+	lnet_nid_t	   buf_self;
+	lnet_process_id_t    buf_peer;
+} srpc_buffer_t;
+
+struct swi_workitem;
+typedef int (*swi_action_t) (struct swi_workitem *);
+
+typedef struct swi_workitem {
+	struct cfs_wi_sched	*swi_sched;
+	cfs_workitem_t       swi_workitem;
+	swi_action_t	 swi_action;
+	int		  swi_state;
+} swi_workitem_t;
+
+/* server-side state of a RPC */
+typedef struct srpc_server_rpc {
+	/* chain on srpc_service::*_rpcq */
+	struct list_head		srpc_list;
+	struct srpc_service_cd *srpc_scd;
+	swi_workitem_t       srpc_wi;
+	srpc_event_t	 srpc_ev;      /* bulk/reply event */
+	lnet_nid_t	   srpc_self;
+	lnet_process_id_t    srpc_peer;
+	srpc_msg_t	   srpc_replymsg;
+	lnet_handle_md_t     srpc_replymdh;
+	srpc_buffer_t       *srpc_reqstbuf;
+	srpc_bulk_t	 *srpc_bulk;
+
+	unsigned int	 srpc_aborted; /* being given up */
+	int		  srpc_status;
+	void	       (*srpc_done)(struct srpc_server_rpc *);
+} srpc_server_rpc_t;
+
+/* client-side state of a RPC */
+typedef struct srpc_client_rpc {
+	struct list_head		crpc_list;	/* chain on user's lists */
+	spinlock_t		crpc_lock;	/* serialize */
+	int		  crpc_service;
+	atomic_t	 crpc_refcount;
+	int		  crpc_timeout; /* # seconds to wait for reply */
+	stt_timer_t	  crpc_timer;
+	swi_workitem_t       crpc_wi;
+	lnet_process_id_t    crpc_dest;
+
+	void	       (*crpc_done)(struct srpc_client_rpc *);
+	void	       (*crpc_fini)(struct srpc_client_rpc *);
+	int		  crpc_status;    /* completion status */
+	void		*crpc_priv;      /* caller data */
+
+	/* state flags */
+	unsigned int	 crpc_aborted:1; /* being given up */
+	unsigned int	 crpc_closed:1;  /* completed */
+
+	/* RPC events */
+	srpc_event_t	 crpc_bulkev;    /* bulk event */
+	srpc_event_t	 crpc_reqstev;   /* request event */
+	srpc_event_t	 crpc_replyev;   /* reply event */
+
+	/* bulk, request(reqst), and reply exchanged on wire */
+	srpc_msg_t	   crpc_reqstmsg;
+	srpc_msg_t	   crpc_replymsg;
+	lnet_handle_md_t     crpc_reqstmdh;
+	lnet_handle_md_t     crpc_replymdh;
+	srpc_bulk_t	  crpc_bulk;
+} srpc_client_rpc_t;
+
+#define srpc_client_rpc_size(rpc)				       \
+offsetof(srpc_client_rpc_t, crpc_bulk.bk_iovs[(rpc)->crpc_bulk.bk_niov])
+
+#define srpc_client_rpc_addref(rpc)				     \
+do {								    \
+	CDEBUG(D_NET, "RPC[%p] -> %s (%d)++\n",			 \
+	       (rpc), libcfs_id2str((rpc)->crpc_dest),		  \
+	       atomic_read(&(rpc)->crpc_refcount));		 \
+	LASSERT(atomic_read(&(rpc)->crpc_refcount) > 0);	    \
+	atomic_inc(&(rpc)->crpc_refcount);			  \
+} while (0)
+
+#define srpc_client_rpc_decref(rpc)				     \
+do {								    \
+	CDEBUG(D_NET, "RPC[%p] -> %s (%d)--\n",			 \
+	       (rpc), libcfs_id2str((rpc)->crpc_dest),		  \
+	       atomic_read(&(rpc)->crpc_refcount));		 \
+	LASSERT(atomic_read(&(rpc)->crpc_refcount) > 0);	    \
+	if (atomic_dec_and_test(&(rpc)->crpc_refcount))	     \
+		srpc_destroy_client_rpc(rpc);			   \
+} while (0)
+
+#define srpc_event_pending(rpc)   ((rpc)->crpc_bulkev.ev_fired == 0 ||  \
+				   (rpc)->crpc_reqstev.ev_fired == 0 || \
+				   (rpc)->crpc_replyev.ev_fired == 0)
+
+/* CPU partition data of srpc service */
+struct srpc_service_cd {
+	/** serialize */
+	spinlock_t		scd_lock;
+	/** backref to service */
+	struct srpc_service	*scd_svc;
+	/** event buffer */
+	srpc_event_t		scd_ev;
+	/** free RPC descriptors */
+	struct list_head		scd_rpc_free;
+	/** in-flight RPCs */
+	struct list_head		scd_rpc_active;
+	/** workitem for posting buffer */
+	swi_workitem_t		scd_buf_wi;
+	/** CPT id */
+	int			scd_cpt;
+	/** error code for scd_buf_wi */
+	int			scd_buf_err;
+	/** timestamp for scd_buf_err */
+	unsigned long	   scd_buf_err_stamp;
+	/** total # request buffers */
+	int			scd_buf_total;
+	/** # posted request buffers */
+	int			scd_buf_nposted;
+	/** in progress of buffer posting */
+	int			scd_buf_posting;
+	/** allocate more buffers if scd_buf_nposted < scd_buf_low */
+	int			scd_buf_low;
+	/** increase/decrease some buffers */
+	int			scd_buf_adjust;
+	/** posted message buffers */
+	struct list_head		scd_buf_posted;
+	/** blocked for RPC descriptor */
+	struct list_head		scd_buf_blocked;
+};
+
+/* number of server workitems (mini-thread) for testing service */
+#define SFW_TEST_WI_MIN		256
+#define SFW_TEST_WI_MAX		2048
+/* extra buffers for tolerating buggy peers, or unbalanced number
+ * of peers between partitions  */
+#define SFW_TEST_WI_EXTRA	64
+
+/* number of server workitems (mini-thread) for framework service */
+#define SFW_FRWK_WI_MIN		16
+#define SFW_FRWK_WI_MAX		256
+
+typedef struct srpc_service {
+	int			sv_id;		/* service id */
+	const char		*sv_name;	/* human readable name */
+	int			sv_wi_total;	/* total server workitems */
+	int			sv_shuttingdown;
+	int			sv_ncpts;
+	/* percpt data for srpc_service */
+	struct srpc_service_cd	**sv_cpt_data;
+	/* Service callbacks:
+	 * - sv_handler: process incoming RPC request
+	 * - sv_bulk_ready: notify bulk data
+	 */
+	int	      (*sv_handler) (srpc_server_rpc_t *);
+	int	      (*sv_bulk_ready) (srpc_server_rpc_t *, int);
+} srpc_service_t;
+
+typedef struct {
+	struct list_head	sn_list;    /* chain on fw_zombie_sessions */
+	lst_sid_t	 sn_id;      /* unique identifier */
+	unsigned int      sn_timeout; /* # seconds' inactivity to expire */
+	int	       sn_timer_active;
+	unsigned int	  sn_features;
+	stt_timer_t       sn_timer;
+	struct list_head	sn_batches; /* list of batches */
+	char	      sn_name[LST_NAME_SIZE];
+	atomic_t      sn_refcount;
+	atomic_t      sn_brw_errors;
+	atomic_t      sn_ping_errors;
+	cfs_time_t	sn_started;
+} sfw_session_t;
+
+#define sfw_sid_equal(sid0, sid1)     ((sid0).ses_nid == (sid1).ses_nid && \
+				       (sid0).ses_stamp == (sid1).ses_stamp)
+
+typedef struct {
+	struct list_head	bat_list;      /* chain on sn_batches */
+	lst_bid_t	 bat_id;	/* batch id */
+	int	       bat_error;     /* error code of batch */
+	sfw_session_t    *bat_session;   /* batch's session */
+	atomic_t      bat_nactive;   /* # of active tests */
+	struct list_head	bat_tests;     /* test instances */
+} sfw_batch_t;
+
+typedef struct {
+	int  (*tso_init)(struct sfw_test_instance *tsi); /* intialize test client */
+	void (*tso_fini)(struct sfw_test_instance *tsi); /* finalize test client */
+	int  (*tso_prep_rpc)(struct sfw_test_unit *tsu,
+			     lnet_process_id_t dest,
+			     srpc_client_rpc_t **rpc);   /* prep a tests rpc */
+	void (*tso_done_rpc)(struct sfw_test_unit *tsu,
+			     srpc_client_rpc_t *rpc);    /* done a test rpc */
+} sfw_test_client_ops_t;
+
+typedef struct sfw_test_instance {
+	struct list_head	      tsi_list;	 /* chain on batch */
+	int		     tsi_service;      /* test type */
+	sfw_batch_t	    *tsi_batch;	/* batch */
+	sfw_test_client_ops_t  *tsi_ops;	  /* test client operations */
+
+	/* public parameter for all test units */
+	unsigned int		tsi_is_client:1;     /* is test client */
+	unsigned int		tsi_stoptsu_onerr:1; /* stop tsu on error */
+	int		     tsi_concur;	  /* concurrency */
+	int		     tsi_loop;	    /* loop count */
+
+	/* status of test instance */
+	spinlock_t		tsi_lock;	  /* serialize */
+	unsigned int		tsi_stopping:1;   /* test is stopping */
+	atomic_t	    tsi_nactive;      /* # of active test unit */
+	struct list_head	      tsi_units;	/* test units */
+	struct list_head	      tsi_free_rpcs;    /* free rpcs */
+	struct list_head	      tsi_active_rpcs;  /* active rpcs */
+
+	union {
+		test_ping_req_t		ping;	  /* ping parameter */
+		test_bulk_req_t		bulk_v0;  /* bulk parameter */
+		test_bulk_req_v1_t	bulk_v1;  /* bulk v1 parameter */
+	} tsi_u;
+} sfw_test_instance_t;
+
+/* XXX: trailing (PAGE_CACHE_SIZE % sizeof(lnet_process_id_t)) bytes at
+ * the end of pages are not used */
+#define SFW_MAX_CONCUR     LST_MAX_CONCUR
+#define SFW_ID_PER_PAGE    (PAGE_CACHE_SIZE / sizeof(lnet_process_id_packed_t))
+#define SFW_MAX_NDESTS     (LNET_MAX_IOV * SFW_ID_PER_PAGE)
+#define sfw_id_pages(n)    (((n) + SFW_ID_PER_PAGE - 1) / SFW_ID_PER_PAGE)
+
+typedef struct sfw_test_unit {
+	struct list_head	    tsu_list;	 /* chain on lst_test_instance */
+	lnet_process_id_t     tsu_dest;	 /* id of dest node */
+	int		   tsu_loop;	 /* loop count of the test */
+	sfw_test_instance_t  *tsu_instance;     /* pointer to test instance */
+	void		 *tsu_private;      /* private data */
+	swi_workitem_t	tsu_worker;       /* workitem of the test unit */
+} sfw_test_unit_t;
+
+typedef struct sfw_test_case {
+	struct list_head	      tsc_list;	 /* chain on fw_tests */
+	srpc_service_t	 *tsc_srv_service;  /* test service */
+	sfw_test_client_ops_t  *tsc_cli_ops;      /* ops of test client */
+} sfw_test_case_t;
+
+srpc_client_rpc_t *
+sfw_create_rpc(lnet_process_id_t peer, int service,
+	       unsigned features, int nbulkiov, int bulklen,
+	       void (*done) (srpc_client_rpc_t *), void *priv);
+int sfw_create_test_rpc(sfw_test_unit_t *tsu,
+			lnet_process_id_t peer, unsigned features,
+			int nblk, int blklen, srpc_client_rpc_t **rpc);
+void sfw_abort_rpc(srpc_client_rpc_t *rpc);
+void sfw_post_rpc(srpc_client_rpc_t *rpc);
+void sfw_client_rpc_done(srpc_client_rpc_t *rpc);
+void sfw_unpack_message(srpc_msg_t *msg);
+void sfw_free_pages(srpc_server_rpc_t *rpc);
+void sfw_add_bulk_page(srpc_bulk_t *bk, struct page *pg, int i);
+int sfw_alloc_pages(srpc_server_rpc_t *rpc, int cpt, int npages, int len,
+		    int sink);
+int sfw_make_session (srpc_mksn_reqst_t *request, srpc_mksn_reply_t *reply);
+
+srpc_client_rpc_t *
+srpc_create_client_rpc(lnet_process_id_t peer, int service,
+		       int nbulkiov, int bulklen,
+		       void (*rpc_done)(srpc_client_rpc_t *),
+		       void (*rpc_fini)(srpc_client_rpc_t *), void *priv);
+void srpc_post_rpc(srpc_client_rpc_t *rpc);
+void srpc_abort_rpc(srpc_client_rpc_t *rpc, int why);
+void srpc_free_bulk(srpc_bulk_t *bk);
+srpc_bulk_t *srpc_alloc_bulk(int cpt, unsigned bulk_npg, unsigned bulk_len,
+			     int sink);
+int srpc_send_rpc(swi_workitem_t *wi);
+int srpc_send_reply(srpc_server_rpc_t *rpc);
+int srpc_add_service(srpc_service_t *sv);
+int srpc_remove_service(srpc_service_t *sv);
+void srpc_shutdown_service(srpc_service_t *sv);
+void srpc_abort_service(srpc_service_t *sv);
+int srpc_finish_service(srpc_service_t *sv);
+int srpc_service_add_buffers(srpc_service_t *sv, int nbuffer);
+void srpc_service_remove_buffers(srpc_service_t *sv, int nbuffer);
+void srpc_get_counters(srpc_counters_t *cnt);
+void srpc_set_counters(const srpc_counters_t *cnt);
+
+extern struct cfs_wi_sched *lst_sched_serial;
+extern struct cfs_wi_sched **lst_sched_test;
+
+static inline int
+srpc_serv_is_framework(struct srpc_service *svc)
+{
+	return svc->sv_id < SRPC_FRAMEWORK_SERVICE_MAX_ID;
+}
+
+static inline int
+swi_wi_action(cfs_workitem_t *wi)
+{
+	swi_workitem_t *swi = container_of(wi, swi_workitem_t, swi_workitem);
+
+	return swi->swi_action(swi);
+}
+
+static inline void
+swi_init_workitem(swi_workitem_t *swi, void *data,
+		  swi_action_t action, struct cfs_wi_sched *sched)
+{
+	swi->swi_sched  = sched;
+	swi->swi_action = action;
+	swi->swi_state  = SWI_STATE_NEWBORN;
+	cfs_wi_init(&swi->swi_workitem, data, swi_wi_action);
+}
+
+static inline void
+swi_schedule_workitem(swi_workitem_t *wi)
+{
+	cfs_wi_schedule(wi->swi_sched, &wi->swi_workitem);
+}
+
+static inline void
+swi_exit_workitem(swi_workitem_t *swi)
+{
+	cfs_wi_exit(swi->swi_sched, &swi->swi_workitem);
+}
+
+static inline int
+swi_deschedule_workitem(swi_workitem_t *swi)
+{
+	return cfs_wi_deschedule(swi->swi_sched, &swi->swi_workitem);
+}
+
+
+int sfw_startup(void);
+int srpc_startup(void);
+void sfw_shutdown(void);
+void srpc_shutdown(void);
+
+static inline void
+srpc_destroy_client_rpc (srpc_client_rpc_t *rpc)
+{
+	LASSERT (rpc != NULL);
+	LASSERT (!srpc_event_pending(rpc));
+	LASSERT (atomic_read(&rpc->crpc_refcount) == 0);
+
+	if (rpc->crpc_fini == NULL) {
+		LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc));
+	} else {
+		(*rpc->crpc_fini) (rpc);
+	}
+
+	return;
+}
+
+static inline void
+srpc_init_client_rpc (srpc_client_rpc_t *rpc, lnet_process_id_t peer,
+		      int service, int nbulkiov, int bulklen,
+		      void (*rpc_done)(srpc_client_rpc_t *),
+		      void (*rpc_fini)(srpc_client_rpc_t *), void *priv)
+{
+	LASSERT (nbulkiov <= LNET_MAX_IOV);
+
+	memset(rpc, 0, offsetof(srpc_client_rpc_t,
+				crpc_bulk.bk_iovs[nbulkiov]));
+
+	INIT_LIST_HEAD(&rpc->crpc_list);
+	swi_init_workitem(&rpc->crpc_wi, rpc, srpc_send_rpc,
+			  lst_sched_test[lnet_cpt_of_nid(peer.nid)]);
+	spin_lock_init(&rpc->crpc_lock);
+	atomic_set(&rpc->crpc_refcount, 1); /* 1 ref for caller */
+
+	rpc->crpc_dest	 = peer;
+	rpc->crpc_priv	 = priv;
+	rpc->crpc_service      = service;
+	rpc->crpc_bulk.bk_len  = bulklen;
+	rpc->crpc_bulk.bk_niov = nbulkiov;
+	rpc->crpc_done	 = rpc_done;
+	rpc->crpc_fini	 = rpc_fini;
+	LNetInvalidateHandle(&rpc->crpc_reqstmdh);
+	LNetInvalidateHandle(&rpc->crpc_replymdh);
+	LNetInvalidateHandle(&rpc->crpc_bulk.bk_mdh);
+
+	/* no event is expected at this point */
+	rpc->crpc_bulkev.ev_fired  =
+	rpc->crpc_reqstev.ev_fired =
+	rpc->crpc_replyev.ev_fired = 1;
+
+	rpc->crpc_reqstmsg.msg_magic   = SRPC_MSG_MAGIC;
+	rpc->crpc_reqstmsg.msg_version = SRPC_MSG_VERSION;
+	rpc->crpc_reqstmsg.msg_type    = srpc_service2request(service);
+	return;
+}
+
+static inline const char *
+swi_state2str (int state)
+{
+#define STATE2STR(x) case x: return #x
+	switch(state) {
+		default:
+			LBUG();
+		STATE2STR(SWI_STATE_NEWBORN);
+		STATE2STR(SWI_STATE_REPLY_SUBMITTED);
+		STATE2STR(SWI_STATE_REPLY_SENT);
+		STATE2STR(SWI_STATE_REQUEST_SUBMITTED);
+		STATE2STR(SWI_STATE_REQUEST_SENT);
+		STATE2STR(SWI_STATE_REPLY_RECEIVED);
+		STATE2STR(SWI_STATE_BULK_STARTED);
+		STATE2STR(SWI_STATE_DONE);
+	}
+#undef STATE2STR
+}
+
+#define UNUSED(x)       ( (void)(x) )
+
+
+#define selftest_wait_events()	cfs_pause(cfs_time_seconds(1) / 10)
+
+
+#define lst_wait_until(cond, lock, fmt, ...)				\
+do {									\
+	int __I = 2;							\
+	while (!(cond)) {						\
+		CDEBUG(IS_PO2(++__I) ? D_WARNING : D_NET,		\
+		       fmt, ## __VA_ARGS__);				\
+		spin_unlock(&(lock));					\
+									\
+		selftest_wait_events();					\
+									\
+		spin_lock(&(lock));					\
+	}								\
+} while (0)
+
+static inline void
+srpc_wait_service_shutdown(srpc_service_t *sv)
+{
+	int i = 2;
+
+	LASSERT(sv->sv_shuttingdown);
+
+	while (srpc_finish_service(sv) == 0) {
+		i++;
+		CDEBUG (((i & -i) == i) ? D_WARNING : D_NET,
+			"Waiting for %s service to shutdown...\n",
+			sv->sv_name);
+		selftest_wait_events();
+	}
+}
+
+#endif /* __SELFTEST_SELFTEST_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/timer.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/timer.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/timer.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/timer.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,253 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/timer.c
+ *
+ * Author: Isaac Huang <isaac@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include "selftest.h"
+
+
+/*
+ * Timers are implemented as a sorted queue of expiry times. The queue
+ * is slotted, with each slot holding timers which expire in a
+ * 2**STTIMER_MINPOLL (8) second period. The timers in each slot are
+ * sorted by increasing expiry time. The number of slots is 2**7 (128),
+ * to cover a time period of 1024 seconds into the future before wrapping.
+ */
+#define STTIMER_MINPOLL	3   /* log2 min poll interval (8 s) */
+#define STTIMER_SLOTTIME       (1 << STTIMER_MINPOLL)
+#define STTIMER_SLOTTIMEMASK   (~(STTIMER_SLOTTIME - 1))
+#define STTIMER_NSLOTS	       (1 << 7)
+#define STTIMER_SLOT(t)	       (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \
+						    (STTIMER_NSLOTS - 1))])
+
+struct st_timer_data {
+	spinlock_t	 stt_lock;
+	/* start time of the slot processed previously */
+	cfs_time_t       stt_prev_slot;
+	struct list_head       stt_hash[STTIMER_NSLOTS];
+	int	      stt_shuttingdown;
+	wait_queue_head_t      stt_waitq;
+	int	      stt_nthreads;
+} stt_data;
+
+void
+stt_add_timer(stt_timer_t *timer)
+{
+	struct list_head *pos;
+
+	spin_lock(&stt_data.stt_lock);
+
+	LASSERT (stt_data.stt_nthreads > 0);
+	LASSERT (!stt_data.stt_shuttingdown);
+	LASSERT (timer->stt_func != NULL);
+	LASSERT (list_empty(&timer->stt_list));
+	LASSERT (cfs_time_after(timer->stt_expires, cfs_time_current_sec()));
+
+	/* a simple insertion sort */
+	list_for_each_prev (pos, STTIMER_SLOT(timer->stt_expires)) {
+		stt_timer_t *old = list_entry(pos, stt_timer_t, stt_list);
+
+		if (cfs_time_aftereq(timer->stt_expires, old->stt_expires))
+			break;
+	}
+	list_add(&timer->stt_list, pos);
+
+	spin_unlock(&stt_data.stt_lock);
+}
+
+/*
+ * The function returns whether it has deactivated a pending timer or not.
+ * (ie. del_timer() of an inactive timer returns 0, del_timer() of an
+ * active timer returns 1.)
+ *
+ * CAVEAT EMPTOR:
+ * When 0 is returned, it is possible that timer->stt_func _is_ running on
+ * another CPU.
+ */
+int
+stt_del_timer (stt_timer_t *timer)
+{
+	int ret = 0;
+
+	spin_lock(&stt_data.stt_lock);
+
+	LASSERT (stt_data.stt_nthreads > 0);
+	LASSERT (!stt_data.stt_shuttingdown);
+
+	if (!list_empty(&timer->stt_list)) {
+		ret = 1;
+		list_del_init(&timer->stt_list);
+	}
+
+	spin_unlock(&stt_data.stt_lock);
+	return ret;
+}
+
+/* called with stt_data.stt_lock held */
+int
+stt_expire_list (struct list_head *slot, cfs_time_t now)
+{
+	int	  expired = 0;
+	stt_timer_t *timer;
+
+	while (!list_empty(slot)) {
+		timer = list_entry(slot->next, stt_timer_t, stt_list);
+
+		if (cfs_time_after(timer->stt_expires, now))
+			break;
+
+		list_del_init(&timer->stt_list);
+		spin_unlock(&stt_data.stt_lock);
+
+		expired++;
+		(*timer->stt_func) (timer->stt_data);
+
+		spin_lock(&stt_data.stt_lock);
+	}
+
+	return expired;
+}
+
+int
+stt_check_timers (cfs_time_t *last)
+{
+	int	expired = 0;
+	cfs_time_t now;
+	cfs_time_t this_slot;
+
+	now = cfs_time_current_sec();
+	this_slot = now & STTIMER_SLOTTIMEMASK;
+
+	spin_lock(&stt_data.stt_lock);
+
+	while (cfs_time_aftereq(this_slot, *last)) {
+		expired += stt_expire_list(STTIMER_SLOT(this_slot), now);
+		this_slot = cfs_time_sub(this_slot, STTIMER_SLOTTIME);
+	}
+
+	*last = now & STTIMER_SLOTTIMEMASK;
+	spin_unlock(&stt_data.stt_lock);
+	return expired;
+}
+
+
+int
+stt_timer_main (void *arg)
+{
+	int rc = 0;
+	UNUSED(arg);
+
+	SET_BUT_UNUSED(rc);
+
+	cfs_block_allsigs();
+
+	while (!stt_data.stt_shuttingdown) {
+		stt_check_timers(&stt_data.stt_prev_slot);
+
+		rc = wait_event_timeout(stt_data.stt_waitq,
+					stt_data.stt_shuttingdown,
+					cfs_time_seconds(STTIMER_SLOTTIME));
+	}
+
+	spin_lock(&stt_data.stt_lock);
+	stt_data.stt_nthreads--;
+	spin_unlock(&stt_data.stt_lock);
+	return 0;
+}
+
+int
+stt_start_timer_thread (void)
+{
+	task_t *task;
+
+	LASSERT(!stt_data.stt_shuttingdown);
+
+	task = kthread_run(stt_timer_main, NULL, "st_timer");
+	if (IS_ERR(task))
+		return PTR_ERR(task);
+
+	spin_lock(&stt_data.stt_lock);
+	stt_data.stt_nthreads++;
+	spin_unlock(&stt_data.stt_lock);
+	return 0;
+}
+
+
+int
+stt_startup (void)
+{
+	int rc = 0;
+	int i;
+
+	stt_data.stt_shuttingdown = 0;
+	stt_data.stt_prev_slot = cfs_time_current_sec() & STTIMER_SLOTTIMEMASK;
+
+	spin_lock_init(&stt_data.stt_lock);
+	for (i = 0; i < STTIMER_NSLOTS; i++)
+		INIT_LIST_HEAD(&stt_data.stt_hash[i]);
+
+	stt_data.stt_nthreads = 0;
+	init_waitqueue_head(&stt_data.stt_waitq);
+	rc = stt_start_timer_thread();
+	if (rc != 0)
+		CERROR ("Can't spawn timer thread: %d\n", rc);
+
+	return rc;
+}
+
+void
+stt_shutdown (void)
+{
+	int i;
+
+	spin_lock(&stt_data.stt_lock);
+
+	for (i = 0; i < STTIMER_NSLOTS; i++)
+		LASSERT (list_empty(&stt_data.stt_hash[i]));
+
+	stt_data.stt_shuttingdown = 1;
+
+	wake_up(&stt_data.stt_waitq);
+	lst_wait_until(stt_data.stt_nthreads == 0, stt_data.stt_lock,
+		       "waiting for %d threads to terminate\n",
+		       stt_data.stt_nthreads);
+
+	spin_unlock(&stt_data.stt_lock);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/timer.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/timer.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lnet/selftest/timer.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lnet/selftest/timer.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,53 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lnet/selftest/timer.h
+ *
+ * Author: Isaac Huang <isaac@clusterfs.com>
+ */
+#ifndef __SELFTEST_TIMER_H__
+#define __SELFTEST_TIMER_H__
+
+typedef struct {
+	struct list_head	stt_list;
+	cfs_time_t	stt_expires;
+	void	    (*stt_func) (void *);
+	void	     *stt_data;
+} stt_timer_t;
+
+void stt_add_timer (stt_timer_t *timer);
+int stt_del_timer (stt_timer_t *timer);
+int stt_startup (void);
+void stt_shutdown (void);
+
+#endif /* __SELFTEST_TIMER_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_handler.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_handler.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_handler.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_handler.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,661 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fid/fid_handler.c
+ *
+ * Lustre Sequence Manager
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FID
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+
+#include <obd.h>
+#include <obd_class.h>
+#include <dt_object.h>
+#include <md_object.h>
+#include <obd_support.h>
+#include <lustre_req_layout.h>
+#include <lustre_fid.h>
+#include "fid_internal.h"
+
+int client_fid_init(struct obd_device *obd,
+		    struct obd_export *exp, enum lu_cli_type type)
+{
+	struct client_obd *cli = &obd->u.cli;
+	char *prefix;
+	int rc;
+	ENTRY;
+
+	OBD_ALLOC_PTR(cli->cl_seq);
+	if (cli->cl_seq == NULL)
+		RETURN(-ENOMEM);
+
+	OBD_ALLOC(prefix, MAX_OBD_NAME + 5);
+	if (prefix == NULL)
+		GOTO(out_free_seq, rc = -ENOMEM);
+
+	snprintf(prefix, MAX_OBD_NAME + 5, "cli-%s", obd->obd_name);
+
+	/* Init client side sequence-manager */
+	rc = seq_client_init(cli->cl_seq, exp, type, prefix, NULL);
+	OBD_FREE(prefix, MAX_OBD_NAME + 5);
+	if (rc)
+		GOTO(out_free_seq, rc);
+
+	RETURN(rc);
+out_free_seq:
+	OBD_FREE_PTR(cli->cl_seq);
+	cli->cl_seq = NULL;
+	return rc;
+}
+EXPORT_SYMBOL(client_fid_init);
+
+int client_fid_fini(struct obd_device *obd)
+{
+	struct client_obd *cli = &obd->u.cli;
+	ENTRY;
+
+	if (cli->cl_seq != NULL) {
+		seq_client_fini(cli->cl_seq);
+		OBD_FREE_PTR(cli->cl_seq);
+		cli->cl_seq = NULL;
+	}
+
+	RETURN(0);
+}
+EXPORT_SYMBOL(client_fid_fini);
+
+static void seq_server_proc_fini(struct lu_server_seq *seq);
+
+/* Assigns client to sequence controller node. */
+int seq_server_set_cli(struct lu_server_seq *seq,
+		       struct lu_client_seq *cli,
+		       const struct lu_env *env)
+{
+	int rc = 0;
+	ENTRY;
+
+	/*
+	 * Ask client for new range, assign that range to ->seq_space and write
+	 * seq state to backing store should be atomic.
+	 */
+	mutex_lock(&seq->lss_mutex);
+
+	if (cli == NULL) {
+		CDEBUG(D_INFO, "%s: Detached sequence client %s\n",
+		       seq->lss_name, cli->lcs_name);
+		seq->lss_cli = cli;
+		GOTO(out_up, rc = 0);
+	}
+
+	if (seq->lss_cli != NULL) {
+		CDEBUG(D_HA, "%s: Sequence controller is already "
+		       "assigned\n", seq->lss_name);
+		GOTO(out_up, rc = -EEXIST);
+	}
+
+	CDEBUG(D_INFO, "%s: Attached sequence controller %s\n",
+	       seq->lss_name, cli->lcs_name);
+
+	seq->lss_cli = cli;
+	cli->lcs_space.lsr_index = seq->lss_site->ss_node_id;
+	EXIT;
+out_up:
+	mutex_unlock(&seq->lss_mutex);
+	return rc;
+}
+EXPORT_SYMBOL(seq_server_set_cli);
+/*
+ * allocate \a w units of sequence from range \a from.
+ */
+static inline void range_alloc(struct lu_seq_range *to,
+			       struct lu_seq_range *from,
+			       __u64 width)
+{
+	width = min(range_space(from), width);
+	to->lsr_start = from->lsr_start;
+	to->lsr_end = from->lsr_start + width;
+	from->lsr_start += width;
+}
+
+/**
+ * On controller node, allocate new super sequence for regular sequence server.
+ * As this super sequence controller, this node suppose to maintain fld
+ * and update index.
+ * \a out range always has currect mds node number of requester.
+ */
+
+static int __seq_server_alloc_super(struct lu_server_seq *seq,
+				    struct lu_seq_range *out,
+				    const struct lu_env *env)
+{
+	struct lu_seq_range *space = &seq->lss_space;
+	int rc;
+	ENTRY;
+
+	LASSERT(range_is_sane(space));
+
+	if (range_is_exhausted(space)) {
+		CERROR("%s: Sequences space is exhausted\n",
+		       seq->lss_name);
+		RETURN(-ENOSPC);
+	} else {
+		range_alloc(out, space, seq->lss_width);
+	}
+
+	rc = seq_store_update(env, seq, out, 1 /* sync */);
+
+	LCONSOLE_INFO("%s: super-sequence allocation rc = %d " DRANGE"\n",
+		      seq->lss_name, rc, PRANGE(out));
+
+	RETURN(rc);
+}
+
+int seq_server_alloc_super(struct lu_server_seq *seq,
+			   struct lu_seq_range *out,
+			   const struct lu_env *env)
+{
+	int rc;
+	ENTRY;
+
+	mutex_lock(&seq->lss_mutex);
+	rc = __seq_server_alloc_super(seq, out, env);
+	mutex_unlock(&seq->lss_mutex);
+
+	RETURN(rc);
+}
+
+static int __seq_set_init(const struct lu_env *env,
+			    struct lu_server_seq *seq)
+{
+	struct lu_seq_range *space = &seq->lss_space;
+	int rc;
+
+	range_alloc(&seq->lss_lowater_set, space, seq->lss_set_width);
+	range_alloc(&seq->lss_hiwater_set, space, seq->lss_set_width);
+
+	rc = seq_store_update(env, seq, NULL, 1);
+
+	return rc;
+}
+
+/*
+ * This function implements new seq allocation algorithm using async
+ * updates to seq file on disk. ref bug 18857 for details.
+ * there are four variable to keep track of this process
+ *
+ * lss_space; - available lss_space
+ * lss_lowater_set; - lu_seq_range for all seqs before barrier, i.e. safe to use
+ * lss_hiwater_set; - lu_seq_range after barrier, i.e. allocated but may be
+ *		    not yet committed
+ *
+ * when lss_lowater_set reaches the end it is replaced with hiwater one and
+ * a write operation is initiated to allocate new hiwater range.
+ * if last seq write opearion is still not commited, current operation is
+ * flaged as sync write op.
+ */
+static int range_alloc_set(const struct lu_env *env,
+			    struct lu_seq_range *out,
+			    struct lu_server_seq *seq)
+{
+	struct lu_seq_range *space = &seq->lss_space;
+	struct lu_seq_range *loset = &seq->lss_lowater_set;
+	struct lu_seq_range *hiset = &seq->lss_hiwater_set;
+	int rc = 0;
+
+	if (range_is_zero(loset))
+		__seq_set_init(env, seq);
+
+	if (OBD_FAIL_CHECK(OBD_FAIL_SEQ_ALLOC)) /* exhaust set */
+		loset->lsr_start = loset->lsr_end;
+
+	if (range_is_exhausted(loset)) {
+		/* reached high water mark. */
+		struct lu_device *dev = seq->lss_site->ss_lu->ls_top_dev;
+		int obd_num_clients = dev->ld_obd->obd_num_exports;
+		__u64 set_sz;
+
+		/* calculate new seq width based on number of clients */
+		set_sz = max(seq->lss_set_width,
+			     obd_num_clients * seq->lss_width);
+		set_sz = min(range_space(space), set_sz);
+
+		/* Switch to hiwater range now */
+		*loset = *hiset;
+		/* allocate new hiwater range */
+		range_alloc(hiset, space, set_sz);
+
+		/* update ondisk seq with new *space */
+		rc = seq_store_update(env, seq, NULL, seq->lss_need_sync);
+	}
+
+	LASSERTF(!range_is_exhausted(loset) || range_is_sane(loset),
+		 DRANGE"\n", PRANGE(loset));
+
+	if (rc == 0)
+		range_alloc(out, loset, seq->lss_width);
+
+	RETURN(rc);
+}
+
+static int __seq_server_alloc_meta(struct lu_server_seq *seq,
+				   struct lu_seq_range *out,
+				   const struct lu_env *env)
+{
+	struct lu_seq_range *space = &seq->lss_space;
+	int rc = 0;
+
+	ENTRY;
+
+	LASSERT(range_is_sane(space));
+
+	/* Check if available space ends and allocate new super seq */
+	if (range_is_exhausted(space)) {
+		if (!seq->lss_cli) {
+			CERROR("%s: No sequence controller is attached.\n",
+			       seq->lss_name);
+			RETURN(-ENODEV);
+		}
+
+		rc = seq_client_alloc_super(seq->lss_cli, env);
+		if (rc) {
+			CERROR("%s: Can't allocate super-sequence, rc %d\n",
+			       seq->lss_name, rc);
+			RETURN(rc);
+		}
+
+		/* Saving new range to allocation space. */
+		*space = seq->lss_cli->lcs_space;
+		LASSERT(range_is_sane(space));
+	}
+
+	rc = range_alloc_set(env, out, seq);
+	if (rc != 0) {
+		CERROR("%s: Allocated meta-sequence failed: rc = %d\n",
+			seq->lss_name, rc);
+		RETURN(rc);
+	}
+
+	CDEBUG(D_INFO, "%s: Allocated meta-sequence " DRANGE"\n",
+		seq->lss_name, PRANGE(out));
+
+	RETURN(rc);
+}
+
+int seq_server_alloc_meta(struct lu_server_seq *seq,
+			  struct lu_seq_range *out,
+			  const struct lu_env *env)
+{
+	int rc;
+	ENTRY;
+
+	mutex_lock(&seq->lss_mutex);
+	rc = __seq_server_alloc_meta(seq, out, env);
+	mutex_unlock(&seq->lss_mutex);
+
+	RETURN(rc);
+}
+EXPORT_SYMBOL(seq_server_alloc_meta);
+
+static int seq_server_handle(struct lu_site *site,
+			     const struct lu_env *env,
+			     __u32 opc, struct lu_seq_range *out)
+{
+	int rc;
+	struct seq_server_site *ss_site;
+	ENTRY;
+
+	ss_site = lu_site2seq(site);
+
+	switch (opc) {
+	case SEQ_ALLOC_META:
+		if (!ss_site->ss_server_seq) {
+			CERROR("Sequence server is not "
+			       "initialized\n");
+			RETURN(-EINVAL);
+		}
+		rc = seq_server_alloc_meta(ss_site->ss_server_seq, out, env);
+		break;
+	case SEQ_ALLOC_SUPER:
+		if (!ss_site->ss_control_seq) {
+			CERROR("Sequence controller is not "
+			       "initialized\n");
+			RETURN(-EINVAL);
+		}
+		rc = seq_server_alloc_super(ss_site->ss_control_seq, out, env);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	RETURN(rc);
+}
+
+static int seq_req_handle(struct ptlrpc_request *req,
+			  const struct lu_env *env,
+			  struct seq_thread_info *info)
+{
+	struct lu_seq_range *out, *tmp;
+	struct lu_site *site;
+	int rc = -EPROTO;
+	__u32 *opc;
+	ENTRY;
+
+	LASSERT(!(lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY));
+	site = req->rq_export->exp_obd->obd_lu_dev->ld_site;
+	LASSERT(site != NULL);
+
+	rc = req_capsule_server_pack(info->sti_pill);
+	if (rc)
+		RETURN(err_serious(rc));
+
+	opc = req_capsule_client_get(info->sti_pill, &RMF_SEQ_OPC);
+	if (opc != NULL) {
+		out = req_capsule_server_get(info->sti_pill, &RMF_SEQ_RANGE);
+		if (out == NULL)
+			RETURN(err_serious(-EPROTO));
+
+		tmp = req_capsule_client_get(info->sti_pill, &RMF_SEQ_RANGE);
+
+		/* seq client passed mdt id, we need to pass that using out
+		 * range parameter */
+
+		out->lsr_index = tmp->lsr_index;
+		out->lsr_flags = tmp->lsr_flags;
+		rc = seq_server_handle(site, env, *opc, out);
+	} else
+		rc = err_serious(-EPROTO);
+
+	RETURN(rc);
+}
+
+/* context key constructor/destructor: seq_key_init, seq_key_fini */
+LU_KEY_INIT_FINI(seq, struct seq_thread_info);
+
+/* context key: seq_thread_key */
+LU_CONTEXT_KEY_DEFINE(seq, LCT_MD_THREAD | LCT_DT_THREAD);
+
+static void seq_thread_info_init(struct ptlrpc_request *req,
+				 struct seq_thread_info *info)
+{
+	info->sti_pill = &req->rq_pill;
+	/* Init request capsule */
+	req_capsule_init(info->sti_pill, req, RCL_SERVER);
+	req_capsule_set(info->sti_pill, &RQF_SEQ_QUERY);
+}
+
+static void seq_thread_info_fini(struct seq_thread_info *info)
+{
+	req_capsule_fini(info->sti_pill);
+}
+
+int seq_handle(struct ptlrpc_request *req)
+{
+	const struct lu_env *env;
+	struct seq_thread_info *info;
+	int rc;
+
+	env = req->rq_svc_thread->t_env;
+	LASSERT(env != NULL);
+
+	info = lu_context_key_get(&env->le_ctx, &seq_thread_key);
+	LASSERT(info != NULL);
+
+	seq_thread_info_init(req, info);
+	rc = seq_req_handle(req, env, info);
+	/* XXX: we don't need replay but MDT assign transno in any case,
+	 * remove it manually before reply*/
+	lustre_msg_set_transno(req->rq_repmsg, 0);
+	seq_thread_info_fini(info);
+
+	return rc;
+}
+EXPORT_SYMBOL(seq_handle);
+
+/*
+ * Entry point for handling FLD RPCs called from MDT.
+ */
+int seq_query(struct com_thread_info *info)
+{
+	return seq_handle(info->cti_pill->rc_req);
+}
+EXPORT_SYMBOL(seq_query);
+
+
+#ifdef LPROCFS
+static int seq_server_proc_init(struct lu_server_seq *seq)
+{
+	int rc;
+	ENTRY;
+
+	seq->lss_proc_dir = lprocfs_register(seq->lss_name,
+					     seq_type_proc_dir,
+					     NULL, NULL);
+	if (IS_ERR(seq->lss_proc_dir)) {
+		rc = PTR_ERR(seq->lss_proc_dir);
+		RETURN(rc);
+	}
+
+	rc = lprocfs_add_vars(seq->lss_proc_dir,
+			      seq_server_proc_list, seq);
+	if (rc) {
+		CERROR("%s: Can't init sequence manager "
+		       "proc, rc %d\n", seq->lss_name, rc);
+		GOTO(out_cleanup, rc);
+	}
+
+	RETURN(0);
+
+out_cleanup:
+	seq_server_proc_fini(seq);
+	return rc;
+}
+
+static void seq_server_proc_fini(struct lu_server_seq *seq)
+{
+	ENTRY;
+	if (seq->lss_proc_dir != NULL) {
+		if (!IS_ERR(seq->lss_proc_dir))
+			lprocfs_remove(&seq->lss_proc_dir);
+		seq->lss_proc_dir = NULL;
+	}
+	EXIT;
+}
+#else
+static int seq_server_proc_init(struct lu_server_seq *seq)
+{
+	return 0;
+}
+
+static void seq_server_proc_fini(struct lu_server_seq *seq)
+{
+	return;
+}
+#endif
+
+
+int seq_server_init(struct lu_server_seq *seq,
+		    struct dt_device *dev,
+		    const char *prefix,
+		    enum lu_mgr_type type,
+		    struct seq_server_site *ss,
+		    const struct lu_env *env)
+{
+	int rc, is_srv = (type == LUSTRE_SEQ_SERVER);
+	ENTRY;
+
+	LASSERT(dev != NULL);
+	LASSERT(prefix != NULL);
+	LASSERT(ss != NULL);
+	LASSERT(ss->ss_lu != NULL);
+
+	seq->lss_cli = NULL;
+	seq->lss_type = type;
+	seq->lss_site = ss;
+	range_init(&seq->lss_space);
+
+	range_init(&seq->lss_lowater_set);
+	range_init(&seq->lss_hiwater_set);
+	seq->lss_set_width = LUSTRE_SEQ_BATCH_WIDTH;
+
+	mutex_init(&seq->lss_mutex);
+
+	seq->lss_width = is_srv ?
+		LUSTRE_SEQ_META_WIDTH : LUSTRE_SEQ_SUPER_WIDTH;
+
+	snprintf(seq->lss_name, sizeof(seq->lss_name),
+		 "%s-%s", (is_srv ? "srv" : "ctl"), prefix);
+
+	rc = seq_store_init(seq, env, dev);
+	if (rc)
+		GOTO(out, rc);
+	/* Request backing store for saved sequence info. */
+	rc = seq_store_read(seq, env);
+	if (rc == -ENODATA) {
+
+		/* Nothing is read, init by default value. */
+		seq->lss_space = is_srv ?
+			LUSTRE_SEQ_ZERO_RANGE:
+			LUSTRE_SEQ_SPACE_RANGE;
+
+		LASSERT(ss != NULL);
+		seq->lss_space.lsr_index = ss->ss_node_id;
+		LCONSOLE_INFO("%s: No data found "
+			      "on store. Initialize space\n",
+			      seq->lss_name);
+
+		rc = seq_store_update(env, seq, NULL, 0);
+		if (rc) {
+			CERROR("%s: Can't write space data, "
+			       "rc %d\n", seq->lss_name, rc);
+		}
+	} else if (rc) {
+		CERROR("%s: Can't read space data, rc %d\n",
+		       seq->lss_name, rc);
+		GOTO(out, rc);
+	}
+
+	if (is_srv) {
+		LASSERT(range_is_sane(&seq->lss_space));
+	} else {
+		LASSERT(!range_is_zero(&seq->lss_space) &&
+			range_is_sane(&seq->lss_space));
+	}
+
+	rc  = seq_server_proc_init(seq);
+	if (rc)
+		GOTO(out, rc);
+
+	EXIT;
+out:
+	if (rc)
+		seq_server_fini(seq, env);
+	return rc;
+}
+EXPORT_SYMBOL(seq_server_init);
+
+void seq_server_fini(struct lu_server_seq *seq,
+		     const struct lu_env *env)
+{
+	ENTRY;
+
+	seq_server_proc_fini(seq);
+	seq_store_fini(seq, env);
+
+	EXIT;
+}
+EXPORT_SYMBOL(seq_server_fini);
+
+int seq_site_fini(const struct lu_env *env, struct seq_server_site *ss)
+{
+	if (ss == NULL)
+		RETURN(0);
+
+	if (ss->ss_server_seq) {
+		seq_server_fini(ss->ss_server_seq, env);
+		OBD_FREE_PTR(ss->ss_server_seq);
+		ss->ss_server_seq = NULL;
+	}
+
+	if (ss->ss_control_seq) {
+		seq_server_fini(ss->ss_control_seq, env);
+		OBD_FREE_PTR(ss->ss_control_seq);
+		ss->ss_control_seq = NULL;
+	}
+
+	if (ss->ss_client_seq) {
+		seq_client_fini(ss->ss_client_seq);
+		OBD_FREE_PTR(ss->ss_client_seq);
+		ss->ss_client_seq = NULL;
+	}
+
+	RETURN(0);
+}
+EXPORT_SYMBOL(seq_site_fini);
+
+proc_dir_entry_t *seq_type_proc_dir = NULL;
+
+static int __init fid_mod_init(void)
+{
+	seq_type_proc_dir = lprocfs_register(LUSTRE_SEQ_NAME,
+					     proc_lustre_root,
+					     NULL, NULL);
+	if (IS_ERR(seq_type_proc_dir))
+		return PTR_ERR(seq_type_proc_dir);
+
+	LU_CONTEXT_KEY_INIT(&seq_thread_key);
+	lu_context_key_register(&seq_thread_key);
+	return 0;
+}
+
+static void __exit fid_mod_exit(void)
+{
+	lu_context_key_degister(&seq_thread_key);
+	if (seq_type_proc_dir != NULL && !IS_ERR(seq_type_proc_dir)) {
+		lprocfs_remove(&seq_type_proc_dir);
+		seq_type_proc_dir = NULL;
+	}
+}
+
+MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
+MODULE_DESCRIPTION("Lustre FID Module");
+MODULE_LICENSE("GPL");
+
+cfs_module(fid, "0.1.0", fid_mod_init, fid_mod_exit);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_internal.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_internal.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_internal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,84 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fid/fid_internal.h
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+#ifndef __FID_INTERNAL_H
+#define __FID_INTERNAL_H
+
+#include <lustre/lustre_idl.h>
+#include <dt_object.h>
+
+#include <linux/libcfs/libcfs.h>
+
+struct seq_thread_info {
+	struct req_capsule     *sti_pill;
+	struct lu_seq_range     sti_space;
+	struct lu_buf	   sti_buf;
+};
+
+enum {
+	SEQ_TXN_STORE_CREDITS = 20
+};
+
+extern struct lu_context_key seq_thread_key;
+
+int seq_client_alloc_super(struct lu_client_seq *seq,
+			   const struct lu_env *env);
+/* Store API functions. */
+int seq_store_init(struct lu_server_seq *seq,
+		   const struct lu_env *env,
+		   struct dt_device *dt);
+
+void seq_store_fini(struct lu_server_seq *seq,
+		    const struct lu_env *env);
+
+int seq_store_read(struct lu_server_seq *seq,
+		   const struct lu_env *env);
+
+int seq_store_update(const struct lu_env *env, struct lu_server_seq *seq,
+		     struct lu_seq_range *out, int sync);
+
+#ifdef LPROCFS
+extern struct lprocfs_vars seq_server_proc_list[];
+extern struct lprocfs_vars seq_client_proc_list[];
+#endif
+
+
+extern proc_dir_entry_t *seq_type_proc_dir;
+
+#endif /* __FID_INTERNAL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_lib.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_lib.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_lib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_lib.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,97 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fid/fid_lib.c
+ *
+ * Miscellaneous fid functions.
+ *
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FID
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+
+#include <obd.h>
+#include <lu_object.h>
+#include <lustre_fid.h>
+
+/**
+ * A cluster-wide range from which fid-sequences are granted to servers and
+ * then clients.
+ *
+ * Fid namespace:
+ * <pre>
+ * Normal FID:	seq:64 [2^33,2^64-1]      oid:32	  ver:32
+ * IGIF      :	0:32, ino:32	      gen:32	  0:32
+ * IDIF      :	0:31, 1:1, ost-index:16,  objd:48	 0:32
+ * </pre>
+ *
+ * The first 0x400 sequences of normal FID are reserved for special purpose.
+ * FID_SEQ_START + 1 is for local file id generation.
+ * FID_SEQ_START + 2 is for .lustre directory and its objects
+ */
+const struct lu_seq_range LUSTRE_SEQ_SPACE_RANGE = {
+	FID_SEQ_NORMAL,
+	(__u64)~0ULL
+};
+EXPORT_SYMBOL(LUSTRE_SEQ_SPACE_RANGE);
+
+/* Zero range, used for init and other purposes. */
+const struct lu_seq_range LUSTRE_SEQ_ZERO_RANGE = {
+	0,
+	0
+};
+EXPORT_SYMBOL(LUSTRE_SEQ_ZERO_RANGE);
+
+/* Lustre Big Fs Lock fid. */
+const struct lu_fid LUSTRE_BFL_FID = { .f_seq = FID_SEQ_SPECIAL,
+				       .f_oid = FID_OID_SPECIAL_BFL,
+				       .f_ver = 0x0000000000000000 };
+EXPORT_SYMBOL(LUSTRE_BFL_FID);
+
+/** Special fid for ".lustre" directory */
+const struct lu_fid LU_DOT_LUSTRE_FID = { .f_seq = FID_SEQ_DOT_LUSTRE,
+					  .f_oid = FID_OID_DOT_LUSTRE,
+					  .f_ver = 0x0000000000000000 };
+EXPORT_SYMBOL(LU_DOT_LUSTRE_FID);
+
+/** Special fid for "fid" special object in .lustre */
+const struct lu_fid LU_OBF_FID = { .f_seq = FID_SEQ_DOT_LUSTRE,
+				   .f_oid = FID_OID_DOT_LUSTRE_OBF,
+				   .f_ver = 0x0000000000000000 };
+EXPORT_SYMBOL(LU_OBF_FID);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_request.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_request.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_request.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_request.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,522 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fid/fid_request.c
+ *
+ * Lustre Sequence Manager
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FID
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+
+#include <obd.h>
+#include <obd_class.h>
+#include <dt_object.h>
+#include <md_object.h>
+#include <obd_support.h>
+#include <lustre_req_layout.h>
+#include <lustre_fid.h>
+/* mdc RPC locks */
+#include <lustre_mdc.h>
+#include "fid_internal.h"
+
+static int seq_client_rpc(struct lu_client_seq *seq,
+			  struct lu_seq_range *output, __u32 opc,
+			  const char *opcname)
+{
+	struct obd_export     *exp = seq->lcs_exp;
+	struct ptlrpc_request *req;
+	struct lu_seq_range   *out, *in;
+	__u32		 *op;
+	unsigned int	   debug_mask;
+	int		    rc;
+	ENTRY;
+
+	req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), &RQF_SEQ_QUERY,
+					LUSTRE_MDS_VERSION, SEQ_QUERY);
+	if (req == NULL)
+		RETURN(-ENOMEM);
+
+	/* Init operation code */
+	op = req_capsule_client_get(&req->rq_pill, &RMF_SEQ_OPC);
+	*op = opc;
+
+	/* Zero out input range, this is not recovery yet. */
+	in = req_capsule_client_get(&req->rq_pill, &RMF_SEQ_RANGE);
+	range_init(in);
+
+	ptlrpc_request_set_replen(req);
+
+	in->lsr_index = seq->lcs_space.lsr_index;
+	if (seq->lcs_type == LUSTRE_SEQ_METADATA)
+		fld_range_set_mdt(in);
+	else
+		fld_range_set_ost(in);
+
+	if (opc == SEQ_ALLOC_SUPER) {
+		req->rq_request_portal = SEQ_CONTROLLER_PORTAL;
+		req->rq_reply_portal = MDC_REPLY_PORTAL;
+		/* During allocating super sequence for data object,
+		 * the current thread might hold the export of MDT0(MDT0
+		 * precreating objects on this OST), and it will send the
+		 * request to MDT0 here, so we can not keep resending the
+		 * request here, otherwise if MDT0 is failed(umounted),
+		 * it can not release the export of MDT0 */
+		if (seq->lcs_type == LUSTRE_SEQ_DATA)
+			req->rq_no_delay = req->rq_no_resend = 1;
+		debug_mask = D_CONSOLE;
+	} else {
+		if (seq->lcs_type == LUSTRE_SEQ_METADATA)
+			req->rq_request_portal = SEQ_METADATA_PORTAL;
+		else
+			req->rq_request_portal = SEQ_DATA_PORTAL;
+		debug_mask = D_INFO;
+	}
+
+	ptlrpc_at_set_req_timeout(req);
+
+	if (seq->lcs_type == LUSTRE_SEQ_METADATA)
+		mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
+	rc = ptlrpc_queue_wait(req);
+	if (seq->lcs_type == LUSTRE_SEQ_METADATA)
+		mdc_put_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
+	if (rc)
+		GOTO(out_req, rc);
+
+	out = req_capsule_server_get(&req->rq_pill, &RMF_SEQ_RANGE);
+	*output = *out;
+
+	if (!range_is_sane(output)) {
+		CERROR("%s: Invalid range received from server: "
+		       DRANGE"\n", seq->lcs_name, PRANGE(output));
+		GOTO(out_req, rc = -EINVAL);
+	}
+
+	if (range_is_exhausted(output)) {
+		CERROR("%s: Range received from server is exhausted: "
+		       DRANGE"]\n", seq->lcs_name, PRANGE(output));
+		GOTO(out_req, rc = -EINVAL);
+	}
+
+	CDEBUG_LIMIT(debug_mask, "%s: Allocated %s-sequence "DRANGE"]\n",
+		     seq->lcs_name, opcname, PRANGE(output));
+
+	EXIT;
+out_req:
+	ptlrpc_req_finished(req);
+	return rc;
+}
+
+/* Request sequence-controller node to allocate new super-sequence. */
+int seq_client_alloc_super(struct lu_client_seq *seq,
+			   const struct lu_env *env)
+{
+	int rc;
+	ENTRY;
+
+	mutex_lock(&seq->lcs_mutex);
+
+	if (seq->lcs_srv) {
+		LASSERT(env != NULL);
+		rc = seq_server_alloc_super(seq->lcs_srv, &seq->lcs_space,
+					    env);
+	} else {
+		/* Check whether the connection to seq controller has been
+		 * setup (lcs_exp != NULL) */
+		if (seq->lcs_exp == NULL) {
+			mutex_unlock(&seq->lcs_mutex);
+			RETURN(-EINPROGRESS);
+		}
+
+		rc = seq_client_rpc(seq, &seq->lcs_space,
+				    SEQ_ALLOC_SUPER, "super");
+	}
+	mutex_unlock(&seq->lcs_mutex);
+	RETURN(rc);
+}
+
+/* Request sequence-controller node to allocate new meta-sequence. */
+static int seq_client_alloc_meta(const struct lu_env *env,
+				 struct lu_client_seq *seq)
+{
+	int rc;
+	ENTRY;
+
+	if (seq->lcs_srv) {
+		LASSERT(env != NULL);
+		rc = seq_server_alloc_meta(seq->lcs_srv, &seq->lcs_space, env);
+	} else {
+		do {
+			/* If meta server return -EINPROGRESS or EAGAIN,
+			 * it means meta server might not be ready to
+			 * allocate super sequence from sequence controller
+			 * (MDT0)yet */
+			rc = seq_client_rpc(seq, &seq->lcs_space,
+					    SEQ_ALLOC_META, "meta");
+		} while (rc == -EINPROGRESS || rc == -EAGAIN);
+	}
+	RETURN(rc);
+}
+
+/* Allocate new sequence for client. */
+static int seq_client_alloc_seq(const struct lu_env *env,
+				struct lu_client_seq *seq, seqno_t *seqnr)
+{
+	int rc;
+	ENTRY;
+
+	LASSERT(range_is_sane(&seq->lcs_space));
+
+	if (range_is_exhausted(&seq->lcs_space)) {
+		rc = seq_client_alloc_meta(env, seq);
+		if (rc) {
+			CERROR("%s: Can't allocate new meta-sequence,"
+			       "rc %d\n", seq->lcs_name, rc);
+			RETURN(rc);
+		} else {
+			CDEBUG(D_INFO, "%s: New range - "DRANGE"\n",
+			       seq->lcs_name, PRANGE(&seq->lcs_space));
+		}
+	} else {
+		rc = 0;
+	}
+
+	LASSERT(!range_is_exhausted(&seq->lcs_space));
+	*seqnr = seq->lcs_space.lsr_start;
+	seq->lcs_space.lsr_start += 1;
+
+	CDEBUG(D_INFO, "%s: Allocated sequence ["LPX64"]\n", seq->lcs_name,
+	       *seqnr);
+
+	RETURN(rc);
+}
+
+static int seq_fid_alloc_prep(struct lu_client_seq *seq,
+			      wait_queue_t *link)
+{
+	if (seq->lcs_update) {
+		add_wait_queue(&seq->lcs_waitq, link);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		mutex_unlock(&seq->lcs_mutex);
+
+		waitq_wait(link, TASK_UNINTERRUPTIBLE);
+
+		mutex_lock(&seq->lcs_mutex);
+		remove_wait_queue(&seq->lcs_waitq, link);
+		set_current_state(TASK_RUNNING);
+		return -EAGAIN;
+	}
+	++seq->lcs_update;
+	mutex_unlock(&seq->lcs_mutex);
+	return 0;
+}
+
+static void seq_fid_alloc_fini(struct lu_client_seq *seq)
+{
+	LASSERT(seq->lcs_update == 1);
+	mutex_lock(&seq->lcs_mutex);
+	--seq->lcs_update;
+	wake_up(&seq->lcs_waitq);
+}
+
+/**
+ * Allocate the whole seq to the caller.
+ **/
+int seq_client_get_seq(const struct lu_env *env,
+		       struct lu_client_seq *seq, seqno_t *seqnr)
+{
+	wait_queue_t link;
+	int rc;
+
+	LASSERT(seqnr != NULL);
+	mutex_lock(&seq->lcs_mutex);
+	init_waitqueue_entry_current(&link);
+
+	while (1) {
+		rc = seq_fid_alloc_prep(seq, &link);
+		if (rc == 0)
+			break;
+	}
+
+	rc = seq_client_alloc_seq(env, seq, seqnr);
+	if (rc) {
+		CERROR("%s: Can't allocate new sequence, "
+		       "rc %d\n", seq->lcs_name, rc);
+		seq_fid_alloc_fini(seq);
+		mutex_unlock(&seq->lcs_mutex);
+		return rc;
+	}
+
+	CDEBUG(D_INFO, "%s: allocate sequence "
+	       "[0x%16.16"LPF64"x]\n", seq->lcs_name, *seqnr);
+
+	/* Since the caller require the whole seq,
+	 * so marked this seq to be used */
+	if (seq->lcs_type == LUSTRE_SEQ_METADATA)
+		seq->lcs_fid.f_oid = LUSTRE_METADATA_SEQ_MAX_WIDTH;
+	else
+		seq->lcs_fid.f_oid = LUSTRE_DATA_SEQ_MAX_WIDTH;
+
+	seq->lcs_fid.f_seq = *seqnr;
+	seq->lcs_fid.f_ver = 0;
+	/*
+	 * Inform caller that sequence switch is performed to allow it
+	 * to setup FLD for it.
+	 */
+	seq_fid_alloc_fini(seq);
+	mutex_unlock(&seq->lcs_mutex);
+
+	return rc;
+}
+EXPORT_SYMBOL(seq_client_get_seq);
+
+/* Allocate new fid on passed client @seq and save it to @fid. */
+int seq_client_alloc_fid(const struct lu_env *env,
+			 struct lu_client_seq *seq, struct lu_fid *fid)
+{
+	wait_queue_t link;
+	int rc;
+	ENTRY;
+
+	LASSERT(seq != NULL);
+	LASSERT(fid != NULL);
+
+	init_waitqueue_entry_current(&link);
+	mutex_lock(&seq->lcs_mutex);
+
+	if (OBD_FAIL_CHECK(OBD_FAIL_SEQ_EXHAUST))
+		seq->lcs_fid.f_oid = seq->lcs_width;
+
+	while (1) {
+		seqno_t seqnr;
+
+		if (!fid_is_zero(&seq->lcs_fid) &&
+		    fid_oid(&seq->lcs_fid) < seq->lcs_width) {
+			/* Just bump last allocated fid and return to caller. */
+			seq->lcs_fid.f_oid += 1;
+			rc = 0;
+			break;
+		}
+
+		rc = seq_fid_alloc_prep(seq, &link);
+		if (rc)
+			continue;
+
+		rc = seq_client_alloc_seq(env, seq, &seqnr);
+		if (rc) {
+			CERROR("%s: Can't allocate new sequence, "
+			       "rc %d\n", seq->lcs_name, rc);
+			seq_fid_alloc_fini(seq);
+			mutex_unlock(&seq->lcs_mutex);
+			RETURN(rc);
+		}
+
+		CDEBUG(D_INFO, "%s: Switch to sequence "
+		       "[0x%16.16"LPF64"x]\n", seq->lcs_name, seqnr);
+
+		seq->lcs_fid.f_oid = LUSTRE_FID_INIT_OID;
+		seq->lcs_fid.f_seq = seqnr;
+		seq->lcs_fid.f_ver = 0;
+
+		/*
+		 * Inform caller that sequence switch is performed to allow it
+		 * to setup FLD for it.
+		 */
+		rc = 1;
+
+		seq_fid_alloc_fini(seq);
+		break;
+	}
+
+	*fid = seq->lcs_fid;
+	mutex_unlock(&seq->lcs_mutex);
+
+	CDEBUG(D_INFO, "%s: Allocated FID "DFID"\n", seq->lcs_name,  PFID(fid));
+	RETURN(rc);
+}
+EXPORT_SYMBOL(seq_client_alloc_fid);
+
+/*
+ * Finish the current sequence due to disconnect.
+ * See mdc_import_event()
+ */
+void seq_client_flush(struct lu_client_seq *seq)
+{
+	wait_queue_t link;
+
+	LASSERT(seq != NULL);
+	init_waitqueue_entry_current(&link);
+	mutex_lock(&seq->lcs_mutex);
+
+	while (seq->lcs_update) {
+		add_wait_queue(&seq->lcs_waitq, &link);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		mutex_unlock(&seq->lcs_mutex);
+
+		waitq_wait(&link, TASK_UNINTERRUPTIBLE);
+
+		mutex_lock(&seq->lcs_mutex);
+		remove_wait_queue(&seq->lcs_waitq, &link);
+		set_current_state(TASK_RUNNING);
+	}
+
+	fid_zero(&seq->lcs_fid);
+	/**
+	 * this id shld not be used for seq range allocation.
+	 * set to -1 for dgb check.
+	 */
+
+	seq->lcs_space.lsr_index = -1;
+
+	range_init(&seq->lcs_space);
+	mutex_unlock(&seq->lcs_mutex);
+}
+EXPORT_SYMBOL(seq_client_flush);
+
+static void seq_client_proc_fini(struct lu_client_seq *seq);
+
+#ifdef LPROCFS
+static int seq_client_proc_init(struct lu_client_seq *seq)
+{
+	int rc;
+	ENTRY;
+
+	seq->lcs_proc_dir = lprocfs_register(seq->lcs_name,
+					     seq_type_proc_dir,
+					     NULL, NULL);
+
+	if (IS_ERR(seq->lcs_proc_dir)) {
+		CERROR("%s: LProcFS failed in seq-init\n",
+		       seq->lcs_name);
+		rc = PTR_ERR(seq->lcs_proc_dir);
+		RETURN(rc);
+	}
+
+	rc = lprocfs_add_vars(seq->lcs_proc_dir,
+			      seq_client_proc_list, seq);
+	if (rc) {
+		CERROR("%s: Can't init sequence manager "
+		       "proc, rc %d\n", seq->lcs_name, rc);
+		GOTO(out_cleanup, rc);
+	}
+
+	RETURN(0);
+
+out_cleanup:
+	seq_client_proc_fini(seq);
+	return rc;
+}
+
+static void seq_client_proc_fini(struct lu_client_seq *seq)
+{
+	ENTRY;
+	if (seq->lcs_proc_dir) {
+		if (!IS_ERR(seq->lcs_proc_dir))
+			lprocfs_remove(&seq->lcs_proc_dir);
+		seq->lcs_proc_dir = NULL;
+	}
+	EXIT;
+}
+#else
+static int seq_client_proc_init(struct lu_client_seq *seq)
+{
+	return 0;
+}
+
+static void seq_client_proc_fini(struct lu_client_seq *seq)
+{
+	return;
+}
+#endif
+
+int seq_client_init(struct lu_client_seq *seq,
+		    struct obd_export *exp,
+		    enum lu_cli_type type,
+		    const char *prefix,
+		    struct lu_server_seq *srv)
+{
+	int rc;
+	ENTRY;
+
+	LASSERT(seq != NULL);
+	LASSERT(prefix != NULL);
+
+	seq->lcs_srv = srv;
+	seq->lcs_type = type;
+
+	mutex_init(&seq->lcs_mutex);
+	if (type == LUSTRE_SEQ_METADATA)
+		seq->lcs_width = LUSTRE_METADATA_SEQ_MAX_WIDTH;
+	else
+		seq->lcs_width = LUSTRE_DATA_SEQ_MAX_WIDTH;
+
+	init_waitqueue_head(&seq->lcs_waitq);
+	/* Make sure that things are clear before work is started. */
+	seq_client_flush(seq);
+
+	if (exp != NULL)
+		seq->lcs_exp = class_export_get(exp);
+	else if (type == LUSTRE_SEQ_METADATA)
+		LASSERT(seq->lcs_srv != NULL);
+
+	snprintf(seq->lcs_name, sizeof(seq->lcs_name),
+		 "cli-%s", prefix);
+
+	rc = seq_client_proc_init(seq);
+	if (rc)
+		seq_client_fini(seq);
+	RETURN(rc);
+}
+EXPORT_SYMBOL(seq_client_init);
+
+void seq_client_fini(struct lu_client_seq *seq)
+{
+	ENTRY;
+
+	seq_client_proc_fini(seq);
+
+	if (seq->lcs_exp != NULL) {
+		class_export_put(seq->lcs_exp);
+		seq->lcs_exp = NULL;
+	}
+
+	seq->lcs_srv = NULL;
+	EXIT;
+}
+EXPORT_SYMBOL(seq_client_fini);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_store.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_store.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/fid_store.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/fid_store.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,259 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2013, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fid/fid_store.c
+ *
+ * Lustre Sequence Manager
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FID
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+
+#include <obd.h>
+#include <obd_class.h>
+#include <dt_object.h>
+#include <md_object.h>
+#include <obd_support.h>
+#include <lustre_req_layout.h>
+#include <lustre_fid.h>
+#include "fid_internal.h"
+
+
+static struct lu_buf *seq_store_buf(struct seq_thread_info *info)
+{
+	struct lu_buf *buf;
+
+	buf = &info->sti_buf;
+	buf->lb_buf = &info->sti_space;
+	buf->lb_len = sizeof(info->sti_space);
+	return buf;
+}
+
+struct seq_update_callback {
+	struct dt_txn_commit_cb suc_cb;
+	struct lu_server_seq   *suc_seq;
+};
+
+void seq_update_cb(struct lu_env *env, struct thandle *th,
+		   struct dt_txn_commit_cb *cb, int err)
+{
+	struct seq_update_callback *ccb;
+
+	ccb = container_of0(cb, struct seq_update_callback, suc_cb);
+
+	LASSERT(ccb->suc_seq != NULL);
+
+	ccb->suc_seq->lss_need_sync = 0;
+	OBD_FREE_PTR(ccb);
+}
+
+int seq_update_cb_add(struct thandle *th, struct lu_server_seq *seq)
+{
+	struct seq_update_callback *ccb;
+	struct dt_txn_commit_cb	   *dcb;
+	int			   rc;
+
+	OBD_ALLOC_PTR(ccb);
+	if (ccb == NULL)
+		return -ENOMEM;
+
+	ccb->suc_seq	   = seq;
+	seq->lss_need_sync = 1;
+
+	dcb	       = &ccb->suc_cb;
+	dcb->dcb_func  = seq_update_cb;
+	INIT_LIST_HEAD(&dcb->dcb_linkage);
+	strncpy(dcb->dcb_name, "seq_update_cb", MAX_COMMIT_CB_STR_LEN);
+	dcb->dcb_name[MAX_COMMIT_CB_STR_LEN - 1] = '\0';
+
+	rc = dt_trans_cb_add(th, dcb);
+	if (rc)
+		OBD_FREE_PTR(ccb);
+	return rc;
+}
+
+/* This function implies that caller takes care about locking. */
+int seq_store_update(const struct lu_env *env, struct lu_server_seq *seq,
+		     struct lu_seq_range *out, int sync)
+{
+	struct dt_device *dt_dev = lu2dt_dev(seq->lss_obj->do_lu.lo_dev);
+	struct seq_thread_info *info;
+	struct thandle *th;
+	loff_t pos = 0;
+	int rc;
+
+	info = lu_context_key_get(&env->le_ctx, &seq_thread_key);
+	LASSERT(info != NULL);
+
+	th = dt_trans_create(env, dt_dev);
+	if (IS_ERR(th))
+		RETURN(PTR_ERR(th));
+
+	rc = dt_declare_record_write(env, seq->lss_obj,
+				     sizeof(struct lu_seq_range), 0, th);
+	if (rc)
+		GOTO(exit, rc);
+
+	if (out != NULL) {
+		rc = fld_declare_server_create(env,
+					       seq->lss_site->ss_server_fld,
+					       out, th);
+		if (rc)
+			GOTO(exit, rc);
+	}
+
+	rc = dt_trans_start_local(env, dt_dev, th);
+	if (rc)
+		GOTO(exit, rc);
+
+	/* Store ranges in le format. */
+	range_cpu_to_le(&info->sti_space, &seq->lss_space);
+
+	rc = dt_record_write(env, seq->lss_obj, seq_store_buf(info), &pos, th);
+	if (rc) {
+		CERROR("%s: Can't write space data, rc %d\n",
+		       seq->lss_name, rc);
+		GOTO(exit, rc);
+	} else if (out != NULL) {
+		rc = fld_server_create(env, seq->lss_site->ss_server_fld, out,
+				       th);
+		if (rc) {
+			CERROR("%s: Can't Update fld database, rc %d\n",
+				seq->lss_name, rc);
+			GOTO(exit, rc);
+		}
+	}
+	/* next sequence update will need sync until this update is committed
+	 * in case of sync operation this is not needed obviously */
+	if (!sync)
+		/* if callback can't be added then sync always */
+		sync = !!seq_update_cb_add(th, seq);
+
+	th->th_sync |= sync;
+exit:
+	dt_trans_stop(env, dt_dev, th);
+	return rc;
+}
+
+/*
+ * This function implies that caller takes care about locking or locking is not
+ * needed (init time).
+ */
+int seq_store_read(struct lu_server_seq *seq,
+		   const struct lu_env *env)
+{
+	struct seq_thread_info *info;
+	loff_t pos = 0;
+	int rc;
+	ENTRY;
+
+	info = lu_context_key_get(&env->le_ctx, &seq_thread_key);
+	LASSERT(info != NULL);
+
+	rc = seq->lss_obj->do_body_ops->dbo_read(env, seq->lss_obj,
+						 seq_store_buf(info),
+						 &pos, BYPASS_CAPA);
+
+	if (rc == sizeof(info->sti_space)) {
+		range_le_to_cpu(&seq->lss_space, &info->sti_space);
+		CDEBUG(D_INFO, "%s: Space - "DRANGE"\n",
+		       seq->lss_name, PRANGE(&seq->lss_space));
+		rc = 0;
+	} else if (rc == 0) {
+		rc = -ENODATA;
+	} else if (rc > 0) {
+		CERROR("%s: Read only %d bytes of %d\n", seq->lss_name,
+		       rc, (int)sizeof(info->sti_space));
+		rc = -EIO;
+	}
+
+	RETURN(rc);
+}
+
+int seq_store_init(struct lu_server_seq *seq,
+		   const struct lu_env *env,
+		   struct dt_device *dt)
+{
+	struct dt_object *dt_obj;
+	struct lu_fid fid;
+	struct lu_attr attr;
+	struct dt_object_format dof;
+	const char *name;
+	int rc;
+	ENTRY;
+
+	name = seq->lss_type == LUSTRE_SEQ_SERVER ?
+		LUSTRE_SEQ_SRV_NAME : LUSTRE_SEQ_CTL_NAME;
+
+	if (seq->lss_type == LUSTRE_SEQ_SERVER)
+		lu_local_obj_fid(&fid, FID_SEQ_SRV_OID);
+	else
+		lu_local_obj_fid(&fid, FID_SEQ_CTL_OID);
+
+	memset(&attr, 0, sizeof(attr));
+	attr.la_valid = LA_MODE;
+	attr.la_mode = S_IFREG | 0666;
+	dof.dof_type = DFT_REGULAR;
+
+	dt_obj = dt_find_or_create(env, dt, &fid, &dof, &attr);
+	if (!IS_ERR(dt_obj)) {
+		seq->lss_obj = dt_obj;
+		rc = 0;
+	} else {
+		CERROR("%s: Can't find \"%s\" obj %d\n",
+		       seq->lss_name, name, (int)PTR_ERR(dt_obj));
+		rc = PTR_ERR(dt_obj);
+	}
+
+	RETURN(rc);
+}
+
+void seq_store_fini(struct lu_server_seq *seq,
+		    const struct lu_env *env)
+{
+	ENTRY;
+
+	if (seq->lss_obj != NULL) {
+		if (!IS_ERR(seq->lss_obj))
+			lu_object_put(env, &seq->lss_obj->do_lu);
+		seq->lss_obj = NULL;
+	}
+
+	EXIT;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/lproc_fid.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/lproc_fid.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/lproc_fid.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/lproc_fid.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,222 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fid/lproc_fid.c
+ *
+ * Lustre Sequence Manager
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FID
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+
+#include <obd.h>
+#include <obd_class.h>
+#include <dt_object.h>
+#include <md_object.h>
+#include <obd_support.h>
+#include <lustre_req_layout.h>
+#include <lustre_fid.h>
+#include "fid_internal.h"
+
+#ifdef LPROCFS
+/*
+ * Note: this function is only used for testing, it is no safe for production
+ * use.
+ */
+static int
+lprocfs_fid_write_common(const char *buffer, unsigned long count,
+			 struct lu_seq_range *range)
+{
+	struct lu_seq_range tmp;
+	int rc;
+	ENTRY;
+
+	LASSERT(range != NULL);
+
+	rc = sscanf(buffer, "[%llx - %llx]\n",
+		    (long long unsigned *)&tmp.lsr_start,
+		    (long long unsigned *)&tmp.lsr_end);
+	if (rc != 2 || !range_is_sane(&tmp) || range_is_zero(&tmp))
+		RETURN(-EINVAL);
+	*range = tmp;
+	RETURN(0);
+}
+
+/* Client side procfs stuff */
+static ssize_t
+lprocfs_fid_space_seq_write(struct file *file, const char *buffer,
+			    size_t count, loff_t *off)
+{
+	struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
+	int rc;
+	ENTRY;
+
+	LASSERT(seq != NULL);
+
+	mutex_lock(&seq->lcs_mutex);
+	rc = lprocfs_fid_write_common(buffer, count, &seq->lcs_space);
+
+	if (rc == 0) {
+		CDEBUG(D_INFO, "%s: Space: "DRANGE"\n",
+		       seq->lcs_name, PRANGE(&seq->lcs_space));
+	}
+
+	mutex_unlock(&seq->lcs_mutex);
+
+	RETURN(count);
+}
+
+static int
+lprocfs_fid_space_seq_show(struct seq_file *m, void *unused)
+{
+	struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
+	int rc;
+	ENTRY;
+
+	LASSERT(seq != NULL);
+
+	mutex_lock(&seq->lcs_mutex);
+	rc = seq_printf(m, "["LPX64" - "LPX64"]:%x:%s\n", PRANGE(&seq->lcs_space));
+	mutex_unlock(&seq->lcs_mutex);
+
+	RETURN(rc);
+}
+
+static ssize_t
+lprocfs_fid_width_seq_write(struct file *file, const char *buffer,
+			    size_t count, loff_t *off)
+{
+	struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
+	__u64  max;
+	int rc, val;
+	ENTRY;
+
+	LASSERT(seq != NULL);
+
+	rc = lprocfs_write_helper(buffer, count, &val);
+	if (rc)
+		RETURN(rc);
+
+	mutex_lock(&seq->lcs_mutex);
+	if (seq->lcs_type == LUSTRE_SEQ_DATA)
+		max = LUSTRE_DATA_SEQ_MAX_WIDTH;
+	else
+		max = LUSTRE_METADATA_SEQ_MAX_WIDTH;
+
+	if (val <= max && val > 0) {
+		seq->lcs_width = val;
+
+		if (rc == 0) {
+			CDEBUG(D_INFO, "%s: Sequence size: "LPU64"\n",
+			       seq->lcs_name, seq->lcs_width);
+		}
+	}
+
+	mutex_unlock(&seq->lcs_mutex);
+
+	RETURN(count);
+}
+
+static int
+lprocfs_fid_width_seq_show(struct seq_file *m, void *unused)
+{
+	struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
+	int rc;
+	ENTRY;
+
+	LASSERT(seq != NULL);
+
+	mutex_lock(&seq->lcs_mutex);
+	rc = seq_printf(m, LPU64"\n", seq->lcs_width);
+	mutex_unlock(&seq->lcs_mutex);
+
+	RETURN(rc);
+}
+
+static int
+lprocfs_fid_fid_seq_show(struct seq_file *m, void *unused)
+{
+	struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
+	int rc;
+	ENTRY;
+
+	LASSERT(seq != NULL);
+
+	mutex_lock(&seq->lcs_mutex);
+	rc = seq_printf(m, DFID"\n", PFID(&seq->lcs_fid));
+	mutex_unlock(&seq->lcs_mutex);
+
+	RETURN(rc);
+}
+
+static int
+lprocfs_fid_server_seq_show(struct seq_file *m, void *unused)
+{
+	struct lu_client_seq *seq = (struct lu_client_seq *)m->private;
+	struct client_obd *cli;
+	int rc;
+	ENTRY;
+
+	LASSERT(seq != NULL);
+
+	if (seq->lcs_exp != NULL) {
+		cli = &seq->lcs_exp->exp_obd->u.cli;
+		rc = seq_printf(m, "%s\n", cli->cl_target_uuid.uuid);
+	} else {
+		rc = seq_printf(m, "%s\n", seq->lcs_srv->lss_name);
+	}
+	RETURN(rc);
+}
+
+struct lprocfs_vars seq_server_proc_list[] = {
+};
+
+LPROC_SEQ_FOPS(lprocfs_fid_space);
+LPROC_SEQ_FOPS(lprocfs_fid_width);
+LPROC_SEQ_FOPS_RO(lprocfs_fid_server);
+LPROC_SEQ_FOPS_RO(lprocfs_fid_fid);
+
+struct lprocfs_vars seq_client_proc_list[] = {
+	{ "space", &lprocfs_fid_space_fops },
+	{ "width", &lprocfs_fid_width_fops },
+	{ "server", &lprocfs_fid_server_fops },
+	{ "fid", &lprocfs_fid_fid_fops },
+	{ NULL }
+};
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/Makefile
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fid/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fid/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,5 @@
+obj-$(CONFIG_LUSTRE_FS) += fid.o
+fid-y := fid_handler.o fid_store.o fid_request.o lproc_fid.o fid_lib.o
+
+
+ccflags-y := -I$(src)/../include
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_cache.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_cache.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_cache.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_cache.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,566 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, 2013, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fld/fld_cache.c
+ *
+ * FLD (Fids Location Database)
+ *
+ * Author: Pravin Shelar <pravin.shelar@sun.com>
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FLD
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+# include <linux/jbd.h>
+# include <asm/div64.h>
+
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_ver.h>
+#include <obd_support.h>
+#include <lprocfs_status.h>
+
+#include <dt_object.h>
+#include <md_object.h>
+#include <lustre_req_layout.h>
+#include <lustre_fld.h>
+#include "fld_internal.h"
+
+/**
+ * create fld cache.
+ */
+struct fld_cache *fld_cache_init(const char *name,
+				 int cache_size, int cache_threshold)
+{
+	struct fld_cache *cache;
+	ENTRY;
+
+	LASSERT(name != NULL);
+	LASSERT(cache_threshold < cache_size);
+
+	OBD_ALLOC_PTR(cache);
+	if (cache == NULL)
+		RETURN(ERR_PTR(-ENOMEM));
+
+	INIT_LIST_HEAD(&cache->fci_entries_head);
+	INIT_LIST_HEAD(&cache->fci_lru);
+
+	cache->fci_cache_count = 0;
+	rwlock_init(&cache->fci_lock);
+
+	strlcpy(cache->fci_name, name,
+		sizeof(cache->fci_name));
+
+	cache->fci_cache_size = cache_size;
+	cache->fci_threshold = cache_threshold;
+
+	/* Init fld cache info. */
+	memset(&cache->fci_stat, 0, sizeof(cache->fci_stat));
+
+	CDEBUG(D_INFO, "%s: FLD cache - Size: %d, Threshold: %d\n",
+	       cache->fci_name, cache_size, cache_threshold);
+
+	RETURN(cache);
+}
+
+/**
+ * destroy fld cache.
+ */
+void fld_cache_fini(struct fld_cache *cache)
+{
+	__u64 pct;
+	ENTRY;
+
+	LASSERT(cache != NULL);
+	fld_cache_flush(cache);
+
+	if (cache->fci_stat.fst_count > 0) {
+		pct = cache->fci_stat.fst_cache * 100;
+		do_div(pct, cache->fci_stat.fst_count);
+	} else {
+		pct = 0;
+	}
+
+	CDEBUG(D_INFO, "FLD cache statistics (%s):\n", cache->fci_name);
+	CDEBUG(D_INFO, "  Total reqs: "LPU64"\n", cache->fci_stat.fst_count);
+	CDEBUG(D_INFO, "  Cache reqs: "LPU64"\n", cache->fci_stat.fst_cache);
+	CDEBUG(D_INFO, "  Cache hits: "LPU64"%%\n", pct);
+
+	OBD_FREE_PTR(cache);
+
+	EXIT;
+}
+
+/**
+ * delete given node from list.
+ */
+void fld_cache_entry_delete(struct fld_cache *cache,
+			    struct fld_cache_entry *node)
+{
+	list_del(&node->fce_list);
+	list_del(&node->fce_lru);
+	cache->fci_cache_count--;
+	OBD_FREE_PTR(node);
+}
+
+/**
+ * fix list by checking new entry with NEXT entry in order.
+ */
+static void fld_fix_new_list(struct fld_cache *cache)
+{
+	struct fld_cache_entry *f_curr;
+	struct fld_cache_entry *f_next;
+	struct lu_seq_range *c_range;
+	struct lu_seq_range *n_range;
+	struct list_head *head = &cache->fci_entries_head;
+	ENTRY;
+
+restart_fixup:
+
+	list_for_each_entry_safe(f_curr, f_next, head, fce_list) {
+		c_range = &f_curr->fce_range;
+		n_range = &f_next->fce_range;
+
+		LASSERT(range_is_sane(c_range));
+		if (&f_next->fce_list == head)
+			break;
+
+		if (c_range->lsr_flags != n_range->lsr_flags)
+			continue;
+
+		LASSERTF(c_range->lsr_start <= n_range->lsr_start,
+			 "cur lsr_start "DRANGE" next lsr_start "DRANGE"\n",
+			 PRANGE(c_range), PRANGE(n_range));
+
+		/* check merge possibility with next range */
+		if (c_range->lsr_end == n_range->lsr_start) {
+			if (c_range->lsr_index != n_range->lsr_index)
+				continue;
+			n_range->lsr_start = c_range->lsr_start;
+			fld_cache_entry_delete(cache, f_curr);
+			continue;
+		}
+
+		/* check if current range overlaps with next range. */
+		if (n_range->lsr_start < c_range->lsr_end) {
+			if (c_range->lsr_index == n_range->lsr_index) {
+				n_range->lsr_start = c_range->lsr_start;
+				n_range->lsr_end = max(c_range->lsr_end,
+						       n_range->lsr_end);
+				fld_cache_entry_delete(cache, f_curr);
+			} else {
+				if (n_range->lsr_end <= c_range->lsr_end) {
+					*n_range = *c_range;
+					fld_cache_entry_delete(cache, f_curr);
+				} else
+					n_range->lsr_start = c_range->lsr_end;
+			}
+
+			/* we could have overlap over next
+			 * range too. better restart. */
+			goto restart_fixup;
+		}
+
+		/* kill duplicates */
+		if (c_range->lsr_start == n_range->lsr_start &&
+		    c_range->lsr_end == n_range->lsr_end)
+			fld_cache_entry_delete(cache, f_curr);
+	}
+
+	EXIT;
+}
+
+/**
+ * add node to fld cache
+ */
+static inline void fld_cache_entry_add(struct fld_cache *cache,
+				       struct fld_cache_entry *f_new,
+				       struct list_head *pos)
+{
+	list_add(&f_new->fce_list, pos);
+	list_add(&f_new->fce_lru, &cache->fci_lru);
+
+	cache->fci_cache_count++;
+	fld_fix_new_list(cache);
+}
+
+/**
+ * Check if cache needs to be shrunk. If so - do it.
+ * Remove one entry in list and so on until cache is shrunk enough.
+ */
+static int fld_cache_shrink(struct fld_cache *cache)
+{
+	struct fld_cache_entry *flde;
+	struct list_head *curr;
+	int num = 0;
+	ENTRY;
+
+	LASSERT(cache != NULL);
+
+	if (cache->fci_cache_count < cache->fci_cache_size)
+		RETURN(0);
+
+	curr = cache->fci_lru.prev;
+
+	while (cache->fci_cache_count + cache->fci_threshold >
+	       cache->fci_cache_size && curr != &cache->fci_lru) {
+
+		flde = list_entry(curr, struct fld_cache_entry, fce_lru);
+		curr = curr->prev;
+		fld_cache_entry_delete(cache, flde);
+		num++;
+	}
+
+	CDEBUG(D_INFO, "%s: FLD cache - Shrunk by "
+	       "%d entries\n", cache->fci_name, num);
+
+	RETURN(0);
+}
+
+/**
+ * kill all fld cache entries.
+ */
+void fld_cache_flush(struct fld_cache *cache)
+{
+	ENTRY;
+
+	write_lock(&cache->fci_lock);
+	cache->fci_cache_size = 0;
+	fld_cache_shrink(cache);
+	write_unlock(&cache->fci_lock);
+
+	EXIT;
+}
+
+/**
+ * punch hole in existing range. divide this range and add new
+ * entry accordingly.
+ */
+
+void fld_cache_punch_hole(struct fld_cache *cache,
+			  struct fld_cache_entry *f_curr,
+			  struct fld_cache_entry *f_new)
+{
+	const struct lu_seq_range *range = &f_new->fce_range;
+	const seqno_t new_start  = range->lsr_start;
+	const seqno_t new_end  = range->lsr_end;
+	struct fld_cache_entry *fldt;
+
+	ENTRY;
+	OBD_ALLOC_GFP(fldt, sizeof *fldt, GFP_ATOMIC);
+	if (!fldt) {
+		OBD_FREE_PTR(f_new);
+		EXIT;
+		/* overlap is not allowed, so dont mess up list. */
+		return;
+	}
+	/*  break f_curr RANGE into three RANGES:
+	 *	f_curr, f_new , fldt
+	 */
+
+	/* f_new = *range */
+
+	/* fldt */
+	fldt->fce_range.lsr_start = new_end;
+	fldt->fce_range.lsr_end = f_curr->fce_range.lsr_end;
+	fldt->fce_range.lsr_index = f_curr->fce_range.lsr_index;
+
+	/* f_curr */
+	f_curr->fce_range.lsr_end = new_start;
+
+	/* add these two entries to list */
+	fld_cache_entry_add(cache, f_new, &f_curr->fce_list);
+	fld_cache_entry_add(cache, fldt, &f_new->fce_list);
+
+	/* no need to fixup */
+	EXIT;
+}
+
+/**
+ * handle range overlap in fld cache.
+ */
+static void fld_cache_overlap_handle(struct fld_cache *cache,
+				struct fld_cache_entry *f_curr,
+				struct fld_cache_entry *f_new)
+{
+	const struct lu_seq_range *range = &f_new->fce_range;
+	const seqno_t new_start  = range->lsr_start;
+	const seqno_t new_end  = range->lsr_end;
+	const mdsno_t mdt = range->lsr_index;
+
+	/* this is overlap case, these case are checking overlapping with
+	 * prev range only. fixup will handle overlaping with next range. */
+
+	if (f_curr->fce_range.lsr_index == mdt) {
+		f_curr->fce_range.lsr_start = min(f_curr->fce_range.lsr_start,
+						  new_start);
+
+		f_curr->fce_range.lsr_end = max(f_curr->fce_range.lsr_end,
+						new_end);
+
+		OBD_FREE_PTR(f_new);
+		fld_fix_new_list(cache);
+
+	} else if (new_start <= f_curr->fce_range.lsr_start &&
+			f_curr->fce_range.lsr_end <= new_end) {
+		/* case 1: new range completely overshadowed existing range.
+		 *	 e.g. whole range migrated. update fld cache entry */
+
+		f_curr->fce_range = *range;
+		OBD_FREE_PTR(f_new);
+		fld_fix_new_list(cache);
+
+	} else if (f_curr->fce_range.lsr_start < new_start &&
+			new_end < f_curr->fce_range.lsr_end) {
+		/* case 2: new range fit within existing range. */
+
+		fld_cache_punch_hole(cache, f_curr, f_new);
+
+	} else  if (new_end <= f_curr->fce_range.lsr_end) {
+		/* case 3: overlap:
+		 *	 [new_start [c_start  new_end)  c_end)
+		 */
+
+		LASSERT(new_start <= f_curr->fce_range.lsr_start);
+
+		f_curr->fce_range.lsr_start = new_end;
+		fld_cache_entry_add(cache, f_new, f_curr->fce_list.prev);
+
+	} else if (f_curr->fce_range.lsr_start <= new_start) {
+		/* case 4: overlap:
+		 *	 [c_start [new_start c_end) new_end)
+		 */
+
+		LASSERT(f_curr->fce_range.lsr_end <= new_end);
+
+		f_curr->fce_range.lsr_end = new_start;
+		fld_cache_entry_add(cache, f_new, &f_curr->fce_list);
+	} else
+		CERROR("NEW range ="DRANGE" curr = "DRANGE"\n",
+		       PRANGE(range),PRANGE(&f_curr->fce_range));
+}
+
+struct fld_cache_entry
+*fld_cache_entry_create(const struct lu_seq_range *range)
+{
+	struct fld_cache_entry *f_new;
+
+	LASSERT(range_is_sane(range));
+
+	OBD_ALLOC_PTR(f_new);
+	if (!f_new)
+		RETURN(ERR_PTR(-ENOMEM));
+
+	f_new->fce_range = *range;
+	RETURN(f_new);
+}
+
+/**
+ * Insert FLD entry in FLD cache.
+ *
+ * This function handles all cases of merging and breaking up of
+ * ranges.
+ */
+int fld_cache_insert_nolock(struct fld_cache *cache,
+			    struct fld_cache_entry *f_new)
+{
+	struct fld_cache_entry *f_curr;
+	struct fld_cache_entry *n;
+	struct list_head *head;
+	struct list_head *prev = NULL;
+	const seqno_t new_start  = f_new->fce_range.lsr_start;
+	const seqno_t new_end  = f_new->fce_range.lsr_end;
+	__u32 new_flags  = f_new->fce_range.lsr_flags;
+	ENTRY;
+
+	/*
+	 * Duplicate entries are eliminated in insert op.
+	 * So we don't need to search new entry before starting
+	 * insertion loop.
+	 */
+
+	if (!cache->fci_no_shrink)
+		fld_cache_shrink(cache);
+
+	head = &cache->fci_entries_head;
+
+	list_for_each_entry_safe(f_curr, n, head, fce_list) {
+		/* add list if next is end of list */
+		if (new_end < f_curr->fce_range.lsr_start ||
+		   (new_end == f_curr->fce_range.lsr_start &&
+		    new_flags != f_curr->fce_range.lsr_flags))
+			break;
+
+		prev = &f_curr->fce_list;
+		/* check if this range is to left of new range. */
+		if (new_start < f_curr->fce_range.lsr_end &&
+		    new_flags == f_curr->fce_range.lsr_flags) {
+			fld_cache_overlap_handle(cache, f_curr, f_new);
+			goto out;
+		}
+	}
+
+	if (prev == NULL)
+		prev = head;
+
+	CDEBUG(D_INFO, "insert range "DRANGE"\n", PRANGE(&f_new->fce_range));
+	/* Add new entry to cache and lru list. */
+	fld_cache_entry_add(cache, f_new, prev);
+out:
+	RETURN(0);
+}
+
+int fld_cache_insert(struct fld_cache *cache,
+		     const struct lu_seq_range *range)
+{
+	struct fld_cache_entry	*flde;
+	int rc;
+
+	flde = fld_cache_entry_create(range);
+	if (IS_ERR(flde))
+		RETURN(PTR_ERR(flde));
+
+	write_lock(&cache->fci_lock);
+	rc = fld_cache_insert_nolock(cache, flde);
+	write_unlock(&cache->fci_lock);
+	if (rc)
+		OBD_FREE_PTR(flde);
+
+	RETURN(rc);
+}
+
+void fld_cache_delete_nolock(struct fld_cache *cache,
+		      const struct lu_seq_range *range)
+{
+	struct fld_cache_entry *flde;
+	struct fld_cache_entry *tmp;
+	struct list_head *head;
+
+	head = &cache->fci_entries_head;
+	list_for_each_entry_safe(flde, tmp, head, fce_list) {
+		/* add list if next is end of list */
+		if (range->lsr_start == flde->fce_range.lsr_start ||
+		   (range->lsr_end == flde->fce_range.lsr_end &&
+		    range->lsr_flags == flde->fce_range.lsr_flags)) {
+			fld_cache_entry_delete(cache, flde);
+			break;
+		}
+	}
+}
+
+/**
+ * Delete FLD entry in FLD cache.
+ *
+ */
+void fld_cache_delete(struct fld_cache *cache,
+		      const struct lu_seq_range *range)
+{
+	write_lock(&cache->fci_lock);
+	fld_cache_delete_nolock(cache, range);
+	write_unlock(&cache->fci_lock);
+}
+
+struct fld_cache_entry
+*fld_cache_entry_lookup_nolock(struct fld_cache *cache,
+			      struct lu_seq_range *range)
+{
+	struct fld_cache_entry *flde;
+	struct fld_cache_entry *got = NULL;
+	struct list_head *head;
+
+	head = &cache->fci_entries_head;
+	list_for_each_entry(flde, head, fce_list) {
+		if (range->lsr_start == flde->fce_range.lsr_start ||
+		   (range->lsr_end == flde->fce_range.lsr_end &&
+		    range->lsr_flags == flde->fce_range.lsr_flags)) {
+			got = flde;
+			break;
+		}
+	}
+
+	RETURN(got);
+}
+
+/**
+ * lookup \a seq sequence for range in fld cache.
+ */
+struct fld_cache_entry
+*fld_cache_entry_lookup(struct fld_cache *cache, struct lu_seq_range *range)
+{
+	struct fld_cache_entry *got = NULL;
+	ENTRY;
+
+	read_lock(&cache->fci_lock);
+	got = fld_cache_entry_lookup_nolock(cache, range);
+	read_unlock(&cache->fci_lock);
+	RETURN(got);
+}
+
+/**
+ * lookup \a seq sequence for range in fld cache.
+ */
+int fld_cache_lookup(struct fld_cache *cache,
+		     const seqno_t seq, struct lu_seq_range *range)
+{
+	struct fld_cache_entry *flde;
+	struct fld_cache_entry *prev = NULL;
+	struct list_head *head;
+	ENTRY;
+
+	read_lock(&cache->fci_lock);
+	head = &cache->fci_entries_head;
+
+	cache->fci_stat.fst_count++;
+	list_for_each_entry(flde, head, fce_list) {
+		if (flde->fce_range.lsr_start > seq) {
+			if (prev != NULL)
+				*range = prev->fce_range;
+			break;
+		}
+
+		prev = flde;
+		if (range_within(&flde->fce_range, seq)) {
+			*range = flde->fce_range;
+
+			cache->fci_stat.fst_cache++;
+			read_unlock(&cache->fci_lock);
+			RETURN(0);
+		}
+	}
+	read_unlock(&cache->fci_lock);
+	RETURN(-ENOENT);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_handler.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_handler.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_handler.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_handler.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,447 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2013, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fld/fld_handler.c
+ *
+ * FLD (Fids Location Database)
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ * Author: WangDi <wangdi@clusterfs.com>
+ * Author: Pravin Shelar <pravin.shelar@sun.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FLD
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+# include <linux/jbd.h>
+# include <asm/div64.h>
+
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_ver.h>
+#include <obd_support.h>
+#include <lprocfs_status.h>
+
+#include <md_object.h>
+#include <lustre_fid.h>
+#include <lustre_req_layout.h>
+#include "fld_internal.h"
+#include <lustre_fid.h>
+
+
+/* context key constructor/destructor: fld_key_init, fld_key_fini */
+LU_KEY_INIT_FINI(fld, struct fld_thread_info);
+
+/* context key: fld_thread_key */
+LU_CONTEXT_KEY_DEFINE(fld, LCT_MD_THREAD | LCT_DT_THREAD | LCT_MG_THREAD);
+
+proc_dir_entry_t *fld_type_proc_dir = NULL;
+
+static int __init fld_mod_init(void)
+{
+	fld_type_proc_dir = lprocfs_register(LUSTRE_FLD_NAME,
+					     proc_lustre_root,
+					     NULL, NULL);
+	if (IS_ERR(fld_type_proc_dir))
+		return PTR_ERR(fld_type_proc_dir);
+
+	LU_CONTEXT_KEY_INIT(&fld_thread_key);
+	lu_context_key_register(&fld_thread_key);
+	return 0;
+}
+
+static void __exit fld_mod_exit(void)
+{
+	lu_context_key_degister(&fld_thread_key);
+	if (fld_type_proc_dir != NULL && !IS_ERR(fld_type_proc_dir)) {
+		lprocfs_remove(&fld_type_proc_dir);
+		fld_type_proc_dir = NULL;
+	}
+}
+
+int fld_declare_server_create(const struct lu_env *env,
+			      struct lu_server_fld *fld,
+			      struct lu_seq_range *range,
+			      struct thandle *th)
+{
+	int rc;
+
+	rc = fld_declare_index_create(env, fld, range, th);
+	RETURN(rc);
+}
+EXPORT_SYMBOL(fld_declare_server_create);
+
+/**
+ * Insert FLD index entry and update FLD cache.
+ *
+ * This function is called from the sequence allocator when a super-sequence
+ * is granted to a server.
+ */
+int fld_server_create(const struct lu_env *env, struct lu_server_fld *fld,
+		      struct lu_seq_range *range, struct thandle *th)
+{
+	int rc;
+
+	mutex_lock(&fld->lsf_lock);
+	rc = fld_index_create(env, fld, range, th);
+	mutex_unlock(&fld->lsf_lock);
+
+	RETURN(rc);
+}
+EXPORT_SYMBOL(fld_server_create);
+
+/**
+ *  Lookup mds by seq, returns a range for given seq.
+ *
+ *  If that entry is not cached in fld cache, request is sent to super
+ *  sequence controller node (MDT0). All other MDT[1...N] and client
+ *  cache fld entries, but this cache is not persistent.
+ */
+int fld_server_lookup(const struct lu_env *env, struct lu_server_fld *fld,
+		      seqno_t seq, struct lu_seq_range *range)
+{
+	struct lu_seq_range *erange;
+	struct fld_thread_info *info;
+	int rc;
+	ENTRY;
+
+	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
+	LASSERT(info != NULL);
+	erange = &info->fti_lrange;
+
+	/* Lookup it in the cache. */
+	rc = fld_cache_lookup(fld->lsf_cache, seq, erange);
+	if (rc == 0) {
+		if (unlikely(fld_range_type(erange) != fld_range_type(range) &&
+			     !fld_range_is_any(range))) {
+			CERROR("%s: FLD cache range "DRANGE" does not match"
+			       "requested flag %x: rc = %d\n", fld->lsf_name,
+			       PRANGE(erange), range->lsr_flags, -EIO);
+			RETURN(-EIO);
+		}
+		*range = *erange;
+		RETURN(0);
+	}
+
+	if (fld->lsf_obj) {
+		/* On server side, all entries should be in cache.
+		 * If we can not find it in cache, just return error */
+		CERROR("%s: Cannot find sequence "LPX64": rc = %d\n",
+			fld->lsf_name, seq, -EIO);
+		RETURN(-EIO);
+	} else {
+		LASSERT(fld->lsf_control_exp);
+		/* send request to mdt0 i.e. super seq. controller.
+		 * This is temporary solution, long term solution is fld
+		 * replication on all mdt servers.
+		 */
+		range->lsr_start = seq;
+		rc = fld_client_rpc(fld->lsf_control_exp,
+				    range, FLD_LOOKUP);
+		if (rc == 0)
+			fld_cache_insert(fld->lsf_cache, range);
+	}
+	RETURN(rc);
+}
+EXPORT_SYMBOL(fld_server_lookup);
+
+/**
+ * All MDT server handle fld lookup operation. But only MDT0 has fld index.
+ * if entry is not found in cache we need to forward lookup request to MDT0
+ */
+
+static int fld_server_handle(struct lu_server_fld *fld,
+			     const struct lu_env *env,
+			     __u32 opc, struct lu_seq_range *range,
+			     struct fld_thread_info *info)
+{
+	int rc;
+	ENTRY;
+
+	switch (opc) {
+	case FLD_LOOKUP:
+		rc = fld_server_lookup(env, fld, range->lsr_start, range);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	CDEBUG(D_INFO, "%s: FLD req handle: error %d (opc: %d, range: "
+	       DRANGE"\n", fld->lsf_name, rc, opc, PRANGE(range));
+
+	RETURN(rc);
+
+}
+
+static int fld_req_handle(struct ptlrpc_request *req,
+			  struct fld_thread_info *info)
+{
+	struct obd_export *exp = req->rq_export;
+	struct lu_site *site = exp->exp_obd->obd_lu_dev->ld_site;
+	struct lu_seq_range *in;
+	struct lu_seq_range *out;
+	int rc;
+	__u32 *opc;
+	ENTRY;
+
+	rc = req_capsule_server_pack(info->fti_pill);
+	if (rc)
+		RETURN(err_serious(rc));
+
+	opc = req_capsule_client_get(info->fti_pill, &RMF_FLD_OPC);
+	if (opc != NULL) {
+		in = req_capsule_client_get(info->fti_pill, &RMF_FLD_MDFLD);
+		if (in == NULL)
+			RETURN(err_serious(-EPROTO));
+		out = req_capsule_server_get(info->fti_pill, &RMF_FLD_MDFLD);
+		if (out == NULL)
+			RETURN(err_serious(-EPROTO));
+		*out = *in;
+
+		/* For old 2.0 client, the 'lsr_flags' is uninitialized.
+		 * Set it as 'LU_SEQ_RANGE_MDT' by default. */
+		if (!(exp_connect_flags(exp) & OBD_CONNECT_64BITHASH) &&
+		    !(exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS) &&
+		    !(exp_connect_flags(exp) & OBD_CONNECT_LIGHTWEIGHT) &&
+		    !exp->exp_libclient)
+			fld_range_set_mdt(out);
+
+		rc = fld_server_handle(lu_site2seq(site)->ss_server_fld,
+				       req->rq_svc_thread->t_env,
+				       *opc, out, info);
+	} else {
+		rc = err_serious(-EPROTO);
+	}
+
+	RETURN(rc);
+}
+
+static void fld_thread_info_init(struct ptlrpc_request *req,
+				 struct fld_thread_info *info)
+{
+	info->fti_pill = &req->rq_pill;
+	/* Init request capsule. */
+	req_capsule_init(info->fti_pill, req, RCL_SERVER);
+	req_capsule_set(info->fti_pill, &RQF_FLD_QUERY);
+}
+
+static void fld_thread_info_fini(struct fld_thread_info *info)
+{
+	req_capsule_fini(info->fti_pill);
+}
+
+static int fld_handle(struct ptlrpc_request *req)
+{
+	struct fld_thread_info *info;
+	const struct lu_env *env;
+	int rc;
+
+	env = req->rq_svc_thread->t_env;
+	LASSERT(env != NULL);
+
+	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
+	LASSERT(info != NULL);
+
+	fld_thread_info_init(req, info);
+	rc = fld_req_handle(req, info);
+	fld_thread_info_fini(info);
+
+	return rc;
+}
+
+/*
+ * Entry point for handling FLD RPCs called from MDT.
+ */
+int fld_query(struct com_thread_info *info)
+{
+	return fld_handle(info->cti_pill->rc_req);
+}
+EXPORT_SYMBOL(fld_query);
+
+/*
+ * Returns true, if fid is local to this server node.
+ *
+ * WARNING: this function is *not* guaranteed to return false if fid is
+ * remote: it makes an educated conservative guess only.
+ *
+ * fid_is_local() is supposed to be used in assertion checks only.
+ */
+int fid_is_local(const struct lu_env *env,
+		 struct lu_site *site, const struct lu_fid *fid)
+{
+	int result;
+	struct seq_server_site *ss_site;
+	struct lu_seq_range *range;
+	struct fld_thread_info *info;
+	ENTRY;
+
+	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
+	range = &info->fti_lrange;
+
+	result = 1; /* conservatively assume fid is local */
+	ss_site = lu_site2seq(site);
+	if (ss_site->ss_client_fld != NULL) {
+		int rc;
+
+		rc = fld_cache_lookup(ss_site->ss_client_fld->lcf_cache,
+				      fid_seq(fid), range);
+		if (rc == 0)
+			result = (range->lsr_index == ss_site->ss_node_id);
+	}
+	return result;
+}
+EXPORT_SYMBOL(fid_is_local);
+
+static void fld_server_proc_fini(struct lu_server_fld *fld);
+
+#ifdef LPROCFS
+static int fld_server_proc_init(struct lu_server_fld *fld)
+{
+	int rc = 0;
+	ENTRY;
+
+	fld->lsf_proc_dir = lprocfs_register(fld->lsf_name,
+					     fld_type_proc_dir,
+					     fld_server_proc_list, fld);
+	if (IS_ERR(fld->lsf_proc_dir)) {
+		rc = PTR_ERR(fld->lsf_proc_dir);
+		RETURN(rc);
+	}
+
+	rc = lprocfs_seq_create(fld->lsf_proc_dir, "fldb", 0444,
+				&fld_proc_seq_fops, fld);
+	if (rc) {
+		lprocfs_remove(&fld->lsf_proc_dir);
+		fld->lsf_proc_dir = NULL;
+	}
+
+	RETURN(rc);
+}
+
+static void fld_server_proc_fini(struct lu_server_fld *fld)
+{
+	ENTRY;
+	if (fld->lsf_proc_dir != NULL) {
+		if (!IS_ERR(fld->lsf_proc_dir))
+			lprocfs_remove(&fld->lsf_proc_dir);
+		fld->lsf_proc_dir = NULL;
+	}
+	EXIT;
+}
+#else
+static int fld_server_proc_init(struct lu_server_fld *fld)
+{
+	return 0;
+}
+
+static void fld_server_proc_fini(struct lu_server_fld *fld)
+{
+	return;
+}
+#endif
+
+int fld_server_init(const struct lu_env *env, struct lu_server_fld *fld,
+		    struct dt_device *dt, const char *prefix, int mds_node_id,
+		    int type)
+{
+	int cache_size, cache_threshold;
+	int rc;
+	ENTRY;
+
+	snprintf(fld->lsf_name, sizeof(fld->lsf_name),
+		 "srv-%s", prefix);
+
+	cache_size = FLD_SERVER_CACHE_SIZE /
+		sizeof(struct fld_cache_entry);
+
+	cache_threshold = cache_size *
+		FLD_SERVER_CACHE_THRESHOLD / 100;
+
+	mutex_init(&fld->lsf_lock);
+	fld->lsf_cache = fld_cache_init(fld->lsf_name,
+					cache_size, cache_threshold);
+	if (IS_ERR(fld->lsf_cache)) {
+		rc = PTR_ERR(fld->lsf_cache);
+		fld->lsf_cache = NULL;
+		GOTO(out, rc);
+	}
+
+	if (!mds_node_id && type == LU_SEQ_RANGE_MDT) {
+		rc = fld_index_init(env, fld, dt);
+		if (rc)
+			GOTO(out, rc);
+	} else {
+		fld->lsf_obj = NULL;
+	}
+
+	rc = fld_server_proc_init(fld);
+	if (rc)
+		GOTO(out, rc);
+
+	fld->lsf_control_exp = NULL;
+
+	GOTO(out, rc);
+
+out:
+	if (rc)
+		fld_server_fini(env, fld);
+	return rc;
+}
+EXPORT_SYMBOL(fld_server_init);
+
+void fld_server_fini(const struct lu_env *env, struct lu_server_fld *fld)
+{
+	ENTRY;
+
+	fld_server_proc_fini(fld);
+	fld_index_fini(env, fld);
+
+	if (fld->lsf_cache != NULL) {
+		if (!IS_ERR(fld->lsf_cache))
+			fld_cache_fini(fld->lsf_cache);
+		fld->lsf_cache = NULL;
+	}
+
+	EXIT;
+}
+EXPORT_SYMBOL(fld_server_fini);
+
+MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
+MODULE_DESCRIPTION("Lustre FLD");
+MODULE_LICENSE("GPL");
+
+cfs_module(mdd, "0.1.0", fld_mod_init, fld_mod_exit);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_index.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_index.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_index.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_index.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,426 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2013, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fld/fld_index.c
+ *
+ * Author: WangDi <wangdi@clusterfs.com>
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FLD
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+# include <linux/jbd.h>
+
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_ver.h>
+#include <obd_support.h>
+#include <lprocfs_status.h>
+
+#include <dt_object.h>
+#include <md_object.h>
+#include <lustre_mdc.h>
+#include <lustre_fid.h>
+#include <lustre_fld.h>
+#include "fld_internal.h"
+
+const char fld_index_name[] = "fld";
+
+static const struct lu_seq_range IGIF_FLD_RANGE = {
+	.lsr_start = FID_SEQ_IGIF,
+	.lsr_end   = FID_SEQ_IGIF_MAX + 1,
+	.lsr_index = 0,
+	.lsr_flags = LU_SEQ_RANGE_MDT
+};
+
+static const struct lu_seq_range DOT_LUSTRE_FLD_RANGE = {
+	.lsr_start = FID_SEQ_DOT_LUSTRE,
+	.lsr_end   = FID_SEQ_DOT_LUSTRE + 1,
+	.lsr_index = 0,
+	.lsr_flags = LU_SEQ_RANGE_MDT
+};
+
+static const struct lu_seq_range ROOT_FLD_RANGE = {
+	.lsr_start = FID_SEQ_ROOT,
+	.lsr_end   = FID_SEQ_ROOT + 1,
+	.lsr_index = 0,
+	.lsr_flags = LU_SEQ_RANGE_MDT
+};
+
+const struct dt_index_features fld_index_features = {
+	.dif_flags       = DT_IND_UPDATE,
+	.dif_keysize_min = sizeof(seqno_t),
+	.dif_keysize_max = sizeof(seqno_t),
+	.dif_recsize_min = sizeof(struct lu_seq_range),
+	.dif_recsize_max = sizeof(struct lu_seq_range),
+	.dif_ptrsize     = 4
+};
+
+extern struct lu_context_key fld_thread_key;
+
+int fld_declare_index_create(const struct lu_env *env,
+			     struct lu_server_fld *fld,
+			     const struct lu_seq_range *new_range,
+			     struct thandle *th)
+{
+	struct lu_seq_range	*tmp;
+	struct lu_seq_range	*range;
+	struct fld_thread_info	*info;
+	int			rc = 0;
+
+	ENTRY;
+
+	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
+	range = &info->fti_lrange;
+	tmp = &info->fti_irange;
+	memset(range, 0, sizeof(*range));
+
+	rc = fld_index_lookup(env, fld, new_range->lsr_start, range);
+	if (rc == 0) {
+		/* In case of duplicate entry, the location must be same */
+		LASSERT((range_compare_loc(new_range, range) == 0));
+		GOTO(out, rc = -EEXIST);
+	}
+
+	if (rc != -ENOENT) {
+		CERROR("%s: lookup range "DRANGE" error: rc = %d\n",
+			fld->lsf_name, PRANGE(range), rc);
+		GOTO(out, rc);
+	}
+
+	/* Check for merge case, since the fld entry can only be increamental,
+	 * so we will only check whether it can be merged from the left. */
+	if (new_range->lsr_start == range->lsr_end && range->lsr_end != 0 &&
+	    range_compare_loc(new_range, range) == 0) {
+		range_cpu_to_be(tmp, range);
+		rc = dt_declare_delete(env, fld->lsf_obj,
+				       (struct dt_key *)&tmp->lsr_start, th);
+		if (rc) {
+			CERROR("%s: declare record "DRANGE" failed: rc = %d\n",
+			       fld->lsf_name, PRANGE(range), rc);
+			GOTO(out, rc);
+		}
+		memcpy(tmp, new_range, sizeof(*new_range));
+		tmp->lsr_start = range->lsr_start;
+	} else {
+		memcpy(tmp, new_range, sizeof(*new_range));
+	}
+
+	range_cpu_to_be(tmp, tmp);
+	rc = dt_declare_insert(env, fld->lsf_obj, (struct dt_rec *)tmp,
+			       (struct dt_key *)&tmp->lsr_start, th);
+out:
+	RETURN(rc);
+}
+
+/**
+ * insert range in fld store.
+ *
+ *      \param  range  range to be inserted
+ *      \param  th     transaction for this operation as it could compound
+ *		     transaction.
+ *
+ *      \retval  0  success
+ *      \retval  -ve error
+ *
+ * The whole fld index insertion is protected by seq->lss_mutex (see
+ * seq_server_alloc_super), i.e. only one thread will access fldb each
+ * time, so we do not need worry the fld file and cache will being
+ * changed between declare and create.
+ * Because the fld entry can only be increamental, so we will only check
+ * whether it can be merged from the left.
+ **/
+int fld_index_create(const struct lu_env *env, struct lu_server_fld *fld,
+		     const struct lu_seq_range *new_range, struct thandle *th)
+{
+	struct lu_seq_range	*range;
+	struct lu_seq_range	*tmp;
+	struct fld_thread_info	*info;
+	int			rc = 0;
+	int			deleted = 0;
+	struct fld_cache_entry	*flde;
+	ENTRY;
+
+	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
+
+	LASSERT(mutex_is_locked(&fld->lsf_lock));
+
+	range = &info->fti_lrange;
+	memset(range, 0, sizeof(*range));
+	tmp = &info->fti_irange;
+	rc = fld_index_lookup(env, fld, new_range->lsr_start, range);
+	if (rc != -ENOENT) {
+		rc = rc == 0 ? -EEXIST : rc;
+		GOTO(out, rc);
+	}
+
+	if (new_range->lsr_start == range->lsr_end && range->lsr_end != 0 &&
+	    range_compare_loc(new_range, range) == 0) {
+		range_cpu_to_be(tmp, range);
+		rc = dt_delete(env, fld->lsf_obj,
+			       (struct dt_key *)&tmp->lsr_start, th,
+				BYPASS_CAPA);
+		if (rc != 0)
+			GOTO(out, rc);
+		memcpy(tmp, new_range, sizeof(*new_range));
+		tmp->lsr_start = range->lsr_start;
+		deleted = 1;
+	} else {
+		memcpy(tmp, new_range, sizeof(*new_range));
+	}
+
+	range_cpu_to_be(tmp, tmp);
+	rc = dt_insert(env, fld->lsf_obj, (struct dt_rec *)tmp,
+		       (struct dt_key *)&tmp->lsr_start, th, BYPASS_CAPA, 1);
+	if (rc != 0) {
+		CERROR("%s: insert range "DRANGE" failed: rc = %d\n",
+		       fld->lsf_name, PRANGE(new_range), rc);
+		GOTO(out, rc);
+	}
+
+	flde = fld_cache_entry_create(new_range);
+	if (IS_ERR(flde))
+		GOTO(out, rc = PTR_ERR(flde));
+
+	write_lock(&fld->lsf_cache->fci_lock);
+	if (deleted)
+		fld_cache_delete_nolock(fld->lsf_cache, new_range);
+	rc = fld_cache_insert_nolock(fld->lsf_cache, flde);
+	write_unlock(&fld->lsf_cache->fci_lock);
+	if (rc)
+		OBD_FREE_PTR(flde);
+out:
+	RETURN(rc);
+}
+
+/**
+ * lookup range for a seq passed. note here we only care about the start/end,
+ * caller should handle the attached location data (flags, index).
+ *
+ * \param  seq     seq for lookup.
+ * \param  range   result of lookup.
+ *
+ * \retval  0	   found, \a range is the matched range;
+ * \retval -ENOENT      not found, \a range is the left-side range;
+ * \retval  -ve	 other error;
+ */
+int fld_index_lookup(const struct lu_env *env, struct lu_server_fld *fld,
+		     seqno_t seq, struct lu_seq_range *range)
+{
+	struct lu_seq_range     *fld_rec;
+	struct fld_thread_info  *info;
+	int rc;
+
+	ENTRY;
+
+	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
+	fld_rec = &info->fti_rec;
+
+	rc = fld_cache_lookup(fld->lsf_cache, seq, fld_rec);
+	if (rc == 0) {
+		*range = *fld_rec;
+		if (range_within(range, seq))
+			rc = 0;
+		else
+			rc = -ENOENT;
+	}
+
+	CDEBUG(D_INFO, "%s: lookup seq = "LPX64" range : "DRANGE" rc = %d\n",
+	       fld->lsf_name, seq, PRANGE(range), rc);
+
+	RETURN(rc);
+}
+
+int fld_insert_entry(const struct lu_env *env,
+		     struct lu_server_fld *fld,
+		     const struct lu_seq_range *range)
+{
+	struct thandle *th;
+	int rc;
+	ENTRY;
+
+	th = dt_trans_create(env, lu2dt_dev(fld->lsf_obj->do_lu.lo_dev));
+	if (IS_ERR(th))
+		RETURN(PTR_ERR(th));
+
+	rc = fld_declare_index_create(env, fld, range, th);
+	if (rc != 0) {
+		if (rc == -EEXIST)
+			rc = 0;
+		GOTO(out, rc);
+	}
+
+	rc = dt_trans_start_local(env, lu2dt_dev(fld->lsf_obj->do_lu.lo_dev),
+				  th);
+	if (rc)
+		GOTO(out, rc);
+
+	rc = fld_index_create(env, fld, range, th);
+	if (rc == -EEXIST)
+		rc = 0;
+out:
+	dt_trans_stop(env, lu2dt_dev(fld->lsf_obj->do_lu.lo_dev), th);
+	RETURN(rc);
+}
+EXPORT_SYMBOL(fld_insert_entry);
+
+static int fld_insert_special_entries(const struct lu_env *env,
+				      struct lu_server_fld *fld)
+{
+	int rc;
+
+	rc = fld_insert_entry(env, fld, &IGIF_FLD_RANGE);
+	if (rc != 0)
+		RETURN(rc);
+
+	rc = fld_insert_entry(env, fld, &DOT_LUSTRE_FLD_RANGE);
+	if (rc != 0)
+		RETURN(rc);
+
+	rc = fld_insert_entry(env, fld, &ROOT_FLD_RANGE);
+
+	RETURN(rc);
+}
+
+int fld_index_init(const struct lu_env *env, struct lu_server_fld *fld,
+		   struct dt_device *dt)
+{
+	struct dt_object	*dt_obj = NULL;
+	struct lu_fid		fid;
+	struct lu_attr		*attr = NULL;
+	struct lu_seq_range	*range = NULL;
+	struct fld_thread_info	*info;
+	struct dt_object_format	dof;
+	struct dt_it		*it;
+	const struct dt_it_ops	*iops;
+	int			rc;
+	ENTRY;
+
+	info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
+	LASSERT(info != NULL);
+
+	lu_local_obj_fid(&fid, FLD_INDEX_OID);
+	OBD_ALLOC_PTR(attr);
+	if (attr == NULL)
+		RETURN(-ENOMEM);
+
+	memset(attr, 0, sizeof(*attr));
+	attr->la_valid = LA_MODE;
+	attr->la_mode = S_IFREG | 0666;
+	dof.dof_type = DFT_INDEX;
+	dof.u.dof_idx.di_feat = &fld_index_features;
+
+	dt_obj = dt_find_or_create(env, dt, &fid, &dof, attr);
+	if (IS_ERR(dt_obj)) {
+		rc = PTR_ERR(dt_obj);
+		CERROR("%s: Can't find \"%s\" obj %d\n", fld->lsf_name,
+			fld_index_name, rc);
+		dt_obj = NULL;
+		GOTO(out, rc);
+	}
+
+	fld->lsf_obj = dt_obj;
+	rc = dt_obj->do_ops->do_index_try(env, dt_obj, &fld_index_features);
+	if (rc != 0) {
+		CERROR("%s: File \"%s\" is not an index: rc = %d!\n",
+		       fld->lsf_name, fld_index_name, rc);
+		GOTO(out, rc);
+	}
+
+	range = &info->fti_rec;
+	/* Load fld entry to cache */
+	iops = &dt_obj->do_index_ops->dio_it;
+	it = iops->init(env, dt_obj, 0, NULL);
+	if (IS_ERR(it))
+		GOTO(out, rc = PTR_ERR(it));
+
+	rc = iops->load(env, it, 0);
+	if (rc < 0)
+		GOTO(out_it_fini, rc);
+
+	if (rc > 0) {
+		/* Load FLD entry into server cache */
+		do {
+			rc = iops->rec(env, it, (struct dt_rec *)range, 0);
+			if (rc != 0)
+				GOTO(out_it_put, rc);
+			LASSERT(range != NULL);
+			range_be_to_cpu(range, range);
+			rc = fld_cache_insert(fld->lsf_cache, range);
+			if (rc != 0)
+				GOTO(out_it_put, rc);
+			rc = iops->next(env, it);
+		} while (rc == 0);
+	}
+
+	/* Note: fld_insert_entry will detect whether these
+	 * special entries already exist inside FLDB */
+	mutex_lock(&fld->lsf_lock);
+	rc = fld_insert_special_entries(env, fld);
+	mutex_unlock(&fld->lsf_lock);
+	if (rc != 0) {
+		CERROR("%s: insert special entries failed!: rc = %d\n",
+		       fld->lsf_name, rc);
+		GOTO(out_it_put, rc);
+	}
+
+out_it_put:
+	iops->put(env, it);
+out_it_fini:
+	iops->fini(env, it);
+out:
+	if (attr != NULL)
+		OBD_FREE_PTR(attr);
+
+	if (rc != 0) {
+		if (dt_obj != NULL)
+			lu_object_put(env, &dt_obj->do_lu);
+		fld->lsf_obj = NULL;
+	}
+	RETURN(rc);
+}
+
+void fld_index_fini(const struct lu_env *env, struct lu_server_fld *fld)
+{
+	ENTRY;
+	if (fld->lsf_obj != NULL) {
+		if (!IS_ERR(fld->lsf_obj))
+			lu_object_put(env, &fld->lsf_obj->do_lu);
+		fld->lsf_obj = NULL;
+	}
+	EXIT;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_internal.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_internal.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_internal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,223 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, 2013, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fld/fld_internal.h
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ * Author: Tom WangDi <wangdi@clusterfs.com>
+ */
+#ifndef __FLD_INTERNAL_H
+#define __FLD_INTERNAL_H
+
+#include <lustre/lustre_idl.h>
+#include <dt_object.h>
+
+#include <linux/libcfs/libcfs.h>
+#include <lustre_req_layout.h>
+#include <lustre_fld.h>
+
+enum {
+	LUSTRE_FLD_INIT = 1 << 0,
+	LUSTRE_FLD_RUN  = 1 << 1
+};
+
+struct fld_stats {
+	__u64   fst_count;
+	__u64   fst_cache;
+	__u64   fst_inflight;
+};
+
+typedef int (*fld_hash_func_t) (struct lu_client_fld *, __u64);
+
+typedef struct lu_fld_target *
+(*fld_scan_func_t) (struct lu_client_fld *, __u64);
+
+struct lu_fld_hash {
+	const char	      *fh_name;
+	fld_hash_func_t	  fh_hash_func;
+	fld_scan_func_t	  fh_scan_func;
+};
+
+struct fld_cache_entry {
+	struct list_head	       fce_lru;
+	struct list_head	       fce_list;
+	/**
+	 * fld cache entries are sorted on range->lsr_start field. */
+	struct lu_seq_range      fce_range;
+};
+
+struct fld_cache {
+	/**
+	 * Cache guard, protects fci_hash mostly because others immutable after
+	 * init is finished.
+	 */
+	rwlock_t		 fci_lock;
+
+	/**
+	 * Cache shrink threshold */
+	int		      fci_threshold;
+
+	/**
+	 * Prefered number of cached entries */
+	int		      fci_cache_size;
+
+	/**
+	 * Current number of cached entries. Protected by \a fci_lock */
+	int		      fci_cache_count;
+
+	/**
+	 * LRU list fld entries. */
+	struct list_head	       fci_lru;
+
+	/**
+	 * sorted fld entries. */
+	struct list_head	       fci_entries_head;
+
+	/**
+	 * Cache statistics. */
+	struct fld_stats	 fci_stat;
+
+	/**
+	 * Cache name used for debug and messages. */
+	char		     fci_name[80];
+	unsigned int		 fci_no_shrink:1;
+};
+
+enum fld_op {
+	FLD_CREATE = 0,
+	FLD_DELETE = 1,
+	FLD_LOOKUP = 2
+};
+
+enum {
+	/* 4M of FLD cache will not hurt client a lot. */
+	FLD_SERVER_CACHE_SIZE      = (4 * 0x100000),
+
+	/* 1M of FLD cache will not hurt client a lot. */
+	FLD_CLIENT_CACHE_SIZE      = (1 * 0x100000)
+};
+
+enum {
+	/* Cache threshold is 10 percent of size. */
+	FLD_SERVER_CACHE_THRESHOLD = 10,
+
+	/* Cache threshold is 10 percent of size. */
+	FLD_CLIENT_CACHE_THRESHOLD = 10
+};
+
+extern struct lu_fld_hash fld_hash[];
+
+
+struct fld_thread_info {
+	struct req_capsule *fti_pill;
+	__u64	       fti_key;
+	struct lu_seq_range fti_rec;
+	struct lu_seq_range fti_lrange;
+	struct lu_seq_range fti_irange;
+};
+
+extern struct lu_context_key fld_thread_key;
+
+int fld_index_init(const struct lu_env *env, struct lu_server_fld *fld,
+		   struct dt_device *dt);
+
+void fld_index_fini(const struct lu_env *env, struct lu_server_fld *fld);
+
+int fld_declare_index_create(const struct lu_env *env,
+			     struct lu_server_fld *fld,
+			     const struct lu_seq_range *new,
+			     struct thandle *th);
+
+int fld_index_create(const struct lu_env *env, struct lu_server_fld *fld,
+		     const struct lu_seq_range *new, struct thandle *th);
+
+int fld_index_lookup(const struct lu_env *env, struct lu_server_fld *fld,
+		     seqno_t seq, struct lu_seq_range *range);
+
+int fld_client_rpc(struct obd_export *exp,
+		   struct lu_seq_range *range, __u32 fld_op);
+
+#ifdef LPROCFS
+extern struct lprocfs_vars fld_server_proc_list[];
+extern struct lprocfs_vars fld_client_proc_list[];
+#endif
+
+
+struct fld_cache *fld_cache_init(const char *name,
+				 int cache_size, int cache_threshold);
+
+void fld_cache_fini(struct fld_cache *cache);
+
+void fld_cache_flush(struct fld_cache *cache);
+
+int fld_cache_insert(struct fld_cache *cache,
+		     const struct lu_seq_range *range);
+
+struct fld_cache_entry
+*fld_cache_entry_create(const struct lu_seq_range *range);
+
+int fld_cache_insert_nolock(struct fld_cache *cache,
+			    struct fld_cache_entry *f_new);
+void fld_cache_delete(struct fld_cache *cache,
+		      const struct lu_seq_range *range);
+void fld_cache_delete_nolock(struct fld_cache *cache,
+			     const struct lu_seq_range *range);
+int fld_cache_lookup(struct fld_cache *cache,
+		     const seqno_t seq, struct lu_seq_range *range);
+
+struct fld_cache_entry*
+fld_cache_entry_lookup(struct fld_cache *cache, struct lu_seq_range *range);
+void fld_cache_entry_delete(struct fld_cache *cache,
+			    struct fld_cache_entry *node);
+void fld_dump_cache_entries(struct fld_cache *cache);
+
+struct fld_cache_entry
+*fld_cache_entry_lookup_nolock(struct fld_cache *cache,
+			      struct lu_seq_range *range);
+int fld_write_range(const struct lu_env *env, struct dt_object *dt,
+		    const struct lu_seq_range *range, struct thandle *th);
+
+static inline const char *
+fld_target_name(struct lu_fld_target *tar)
+{
+	if (tar->ft_srv != NULL)
+		return tar->ft_srv->lsf_name;
+
+	return (const char *)tar->ft_exp->exp_obd->obd_name;
+}
+
+extern proc_dir_entry_t *fld_type_proc_dir;
+extern struct file_operations fld_proc_seq_fops;
+#endif /* __FLD_INTERNAL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_request.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_request.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/fld_request.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/fld_request.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,519 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2013, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fld/fld_request.c
+ *
+ * FLD (Fids Location Database)
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FLD
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+# include <linux/jbd.h>
+# include <asm/div64.h>
+
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_ver.h>
+#include <obd_support.h>
+#include <lprocfs_status.h>
+
+#include <dt_object.h>
+#include <md_object.h>
+#include <lustre_req_layout.h>
+#include <lustre_fld.h>
+#include <lustre_mdc.h>
+#include "fld_internal.h"
+
+/* TODO: these 3 functions are copies of flow-control code from mdc_lib.c
+ * It should be common thing. The same about mdc RPC lock */
+static int fld_req_avail(struct client_obd *cli, struct mdc_cache_waiter *mcw)
+{
+	int rc;
+	ENTRY;
+	client_obd_list_lock(&cli->cl_loi_list_lock);
+	rc = list_empty(&mcw->mcw_entry);
+	client_obd_list_unlock(&cli->cl_loi_list_lock);
+	RETURN(rc);
+};
+
+static void fld_enter_request(struct client_obd *cli)
+{
+	struct mdc_cache_waiter mcw;
+	struct l_wait_info lwi = { 0 };
+
+	client_obd_list_lock(&cli->cl_loi_list_lock);
+	if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
+		list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters);
+		init_waitqueue_head(&mcw.mcw_waitq);
+		client_obd_list_unlock(&cli->cl_loi_list_lock);
+		l_wait_event(mcw.mcw_waitq, fld_req_avail(cli, &mcw), &lwi);
+	} else {
+		cli->cl_r_in_flight++;
+		client_obd_list_unlock(&cli->cl_loi_list_lock);
+	}
+}
+
+static void fld_exit_request(struct client_obd *cli)
+{
+	struct list_head *l, *tmp;
+	struct mdc_cache_waiter *mcw;
+
+	client_obd_list_lock(&cli->cl_loi_list_lock);
+	cli->cl_r_in_flight--;
+	list_for_each_safe(l, tmp, &cli->cl_cache_waiters) {
+
+		if (cli->cl_r_in_flight >= cli->cl_max_rpcs_in_flight) {
+			/* No free request slots anymore */
+			break;
+		}
+
+		mcw = list_entry(l, struct mdc_cache_waiter, mcw_entry);
+		list_del_init(&mcw->mcw_entry);
+		cli->cl_r_in_flight++;
+		wake_up(&mcw->mcw_waitq);
+	}
+	client_obd_list_unlock(&cli->cl_loi_list_lock);
+}
+
+static int fld_rrb_hash(struct lu_client_fld *fld,
+			seqno_t seq)
+{
+	LASSERT(fld->lcf_count > 0);
+	return do_div(seq, fld->lcf_count);
+}
+
+static struct lu_fld_target *
+fld_rrb_scan(struct lu_client_fld *fld, seqno_t seq)
+{
+	struct lu_fld_target *target;
+	int hash;
+	ENTRY;
+
+	/* Because almost all of special sequence located in MDT0,
+	 * it should go to index 0 directly, instead of calculating
+	 * hash again, and also if other MDTs is not being connected,
+	 * the fld lookup requests(for seq on MDT0) should not be
+	 * blocked because of other MDTs */
+	if (fid_seq_is_norm(seq))
+		hash = fld_rrb_hash(fld, seq);
+	else
+		hash = 0;
+
+	list_for_each_entry(target, &fld->lcf_targets, ft_chain) {
+		if (target->ft_idx == hash)
+			RETURN(target);
+	}
+
+	CERROR("%s: Can't find target by hash %d (seq "LPX64"). "
+	       "Targets (%d):\n", fld->lcf_name, hash, seq,
+	       fld->lcf_count);
+
+	list_for_each_entry(target, &fld->lcf_targets, ft_chain) {
+		const char *srv_name = target->ft_srv != NULL  ?
+			target->ft_srv->lsf_name : "<null>";
+		const char *exp_name = target->ft_exp != NULL ?
+			(char *)target->ft_exp->exp_obd->obd_uuid.uuid :
+			"<null>";
+
+		CERROR("  exp: 0x%p (%s), srv: 0x%p (%s), idx: "LPU64"\n",
+		       target->ft_exp, exp_name, target->ft_srv,
+		       srv_name, target->ft_idx);
+	}
+
+	/*
+	 * If target is not found, there is logical error anyway, so here is
+	 * LBUG() to catch this situation.
+	 */
+	LBUG();
+	RETURN(NULL);
+}
+
+struct lu_fld_hash fld_hash[] = {
+	{
+		.fh_name = "RRB",
+		.fh_hash_func = fld_rrb_hash,
+		.fh_scan_func = fld_rrb_scan
+	},
+	{
+		0,
+	}
+};
+
+static struct lu_fld_target *
+fld_client_get_target(struct lu_client_fld *fld, seqno_t seq)
+{
+	struct lu_fld_target *target;
+	ENTRY;
+
+	LASSERT(fld->lcf_hash != NULL);
+
+	spin_lock(&fld->lcf_lock);
+	target = fld->lcf_hash->fh_scan_func(fld, seq);
+	spin_unlock(&fld->lcf_lock);
+
+	if (target != NULL) {
+		CDEBUG(D_INFO, "%s: Found target (idx "LPU64
+		       ") by seq "LPX64"\n", fld->lcf_name,
+		       target->ft_idx, seq);
+	}
+
+	RETURN(target);
+}
+
+/*
+ * Add export to FLD. This is usually done by CMM and LMV as they are main users
+ * of FLD module.
+ */
+int fld_client_add_target(struct lu_client_fld *fld,
+			  struct lu_fld_target *tar)
+{
+	const char *name;
+	struct lu_fld_target *target, *tmp;
+	ENTRY;
+
+	LASSERT(tar != NULL);
+	name = fld_target_name(tar);
+	LASSERT(name != NULL);
+	LASSERT(tar->ft_srv != NULL || tar->ft_exp != NULL);
+
+	if (fld->lcf_flags != LUSTRE_FLD_INIT) {
+		CERROR("%s: Attempt to add target %s (idx "LPU64") "
+		       "on fly - skip it\n", fld->lcf_name, name,
+		       tar->ft_idx);
+		RETURN(0);
+	} else {
+		CDEBUG(D_INFO, "%s: Adding target %s (idx "
+		       LPU64")\n", fld->lcf_name, name, tar->ft_idx);
+	}
+
+	OBD_ALLOC_PTR(target);
+	if (target == NULL)
+		RETURN(-ENOMEM);
+
+	spin_lock(&fld->lcf_lock);
+	list_for_each_entry(tmp, &fld->lcf_targets, ft_chain) {
+		if (tmp->ft_idx == tar->ft_idx) {
+			spin_unlock(&fld->lcf_lock);
+			OBD_FREE_PTR(target);
+			CERROR("Target %s exists in FLD and known as %s:#"LPU64"\n",
+			       name, fld_target_name(tmp), tmp->ft_idx);
+			RETURN(-EEXIST);
+		}
+	}
+
+	target->ft_exp = tar->ft_exp;
+	if (target->ft_exp != NULL)
+		class_export_get(target->ft_exp);
+	target->ft_srv = tar->ft_srv;
+	target->ft_idx = tar->ft_idx;
+
+	list_add_tail(&target->ft_chain,
+			  &fld->lcf_targets);
+
+	fld->lcf_count++;
+	spin_unlock(&fld->lcf_lock);
+
+	RETURN(0);
+}
+EXPORT_SYMBOL(fld_client_add_target);
+
+/* Remove export from FLD */
+int fld_client_del_target(struct lu_client_fld *fld, __u64 idx)
+{
+	struct lu_fld_target *target, *tmp;
+	ENTRY;
+
+	spin_lock(&fld->lcf_lock);
+	list_for_each_entry_safe(target, tmp,
+				     &fld->lcf_targets, ft_chain) {
+		if (target->ft_idx == idx) {
+			fld->lcf_count--;
+			list_del(&target->ft_chain);
+			spin_unlock(&fld->lcf_lock);
+
+			if (target->ft_exp != NULL)
+				class_export_put(target->ft_exp);
+
+			OBD_FREE_PTR(target);
+			RETURN(0);
+		}
+	}
+	spin_unlock(&fld->lcf_lock);
+	RETURN(-ENOENT);
+}
+EXPORT_SYMBOL(fld_client_del_target);
+
+#ifdef LPROCFS
+static int fld_client_proc_init(struct lu_client_fld *fld)
+{
+	int rc;
+	ENTRY;
+
+	fld->lcf_proc_dir = lprocfs_register(fld->lcf_name,
+					     fld_type_proc_dir,
+					     NULL, NULL);
+
+	if (IS_ERR(fld->lcf_proc_dir)) {
+		CERROR("%s: LProcFS failed in fld-init\n",
+		       fld->lcf_name);
+		rc = PTR_ERR(fld->lcf_proc_dir);
+		RETURN(rc);
+	}
+
+	rc = lprocfs_add_vars(fld->lcf_proc_dir,
+			      fld_client_proc_list, fld);
+	if (rc) {
+		CERROR("%s: Can't init FLD proc, rc %d\n",
+		       fld->lcf_name, rc);
+		GOTO(out_cleanup, rc);
+	}
+
+	RETURN(0);
+
+out_cleanup:
+	fld_client_proc_fini(fld);
+	return rc;
+}
+
+void fld_client_proc_fini(struct lu_client_fld *fld)
+{
+	ENTRY;
+	if (fld->lcf_proc_dir) {
+		if (!IS_ERR(fld->lcf_proc_dir))
+			lprocfs_remove(&fld->lcf_proc_dir);
+		fld->lcf_proc_dir = NULL;
+	}
+	EXIT;
+}
+#else
+static int fld_client_proc_init(struct lu_client_fld *fld)
+{
+	return 0;
+}
+
+void fld_client_proc_fini(struct lu_client_fld *fld)
+{
+	return;
+}
+#endif
+
+EXPORT_SYMBOL(fld_client_proc_fini);
+
+static inline int hash_is_sane(int hash)
+{
+	return (hash >= 0 && hash < ARRAY_SIZE(fld_hash));
+}
+
+int fld_client_init(struct lu_client_fld *fld,
+		    const char *prefix, int hash)
+{
+	int cache_size, cache_threshold;
+	int rc;
+	ENTRY;
+
+	LASSERT(fld != NULL);
+
+	snprintf(fld->lcf_name, sizeof(fld->lcf_name),
+		 "cli-%s", prefix);
+
+	if (!hash_is_sane(hash)) {
+		CERROR("%s: Wrong hash function %#x\n",
+		       fld->lcf_name, hash);
+		RETURN(-EINVAL);
+	}
+
+	fld->lcf_count = 0;
+	spin_lock_init(&fld->lcf_lock);
+	fld->lcf_hash = &fld_hash[hash];
+	fld->lcf_flags = LUSTRE_FLD_INIT;
+	INIT_LIST_HEAD(&fld->lcf_targets);
+
+	cache_size = FLD_CLIENT_CACHE_SIZE /
+		sizeof(struct fld_cache_entry);
+
+	cache_threshold = cache_size *
+		FLD_CLIENT_CACHE_THRESHOLD / 100;
+
+	fld->lcf_cache = fld_cache_init(fld->lcf_name,
+					cache_size, cache_threshold);
+	if (IS_ERR(fld->lcf_cache)) {
+		rc = PTR_ERR(fld->lcf_cache);
+		fld->lcf_cache = NULL;
+		GOTO(out, rc);
+	}
+
+	rc = fld_client_proc_init(fld);
+	if (rc)
+		GOTO(out, rc);
+	EXIT;
+out:
+	if (rc)
+		fld_client_fini(fld);
+	else
+		CDEBUG(D_INFO, "%s: Using \"%s\" hash\n",
+		       fld->lcf_name, fld->lcf_hash->fh_name);
+	return rc;
+}
+EXPORT_SYMBOL(fld_client_init);
+
+void fld_client_fini(struct lu_client_fld *fld)
+{
+	struct lu_fld_target *target, *tmp;
+	ENTRY;
+
+	spin_lock(&fld->lcf_lock);
+	list_for_each_entry_safe(target, tmp,
+				     &fld->lcf_targets, ft_chain) {
+		fld->lcf_count--;
+		list_del(&target->ft_chain);
+		if (target->ft_exp != NULL)
+			class_export_put(target->ft_exp);
+		OBD_FREE_PTR(target);
+	}
+	spin_unlock(&fld->lcf_lock);
+
+	if (fld->lcf_cache != NULL) {
+		if (!IS_ERR(fld->lcf_cache))
+			fld_cache_fini(fld->lcf_cache);
+		fld->lcf_cache = NULL;
+	}
+
+	EXIT;
+}
+EXPORT_SYMBOL(fld_client_fini);
+
+int fld_client_rpc(struct obd_export *exp,
+		   struct lu_seq_range *range, __u32 fld_op)
+{
+	struct ptlrpc_request *req;
+	struct lu_seq_range   *prange;
+	__u32		 *op;
+	int		    rc;
+	struct obd_import     *imp;
+	ENTRY;
+
+	LASSERT(exp != NULL);
+
+	imp = class_exp2cliimp(exp);
+	req = ptlrpc_request_alloc_pack(imp, &RQF_FLD_QUERY, LUSTRE_MDS_VERSION,
+					FLD_QUERY);
+	if (req == NULL)
+		RETURN(-ENOMEM);
+
+	op = req_capsule_client_get(&req->rq_pill, &RMF_FLD_OPC);
+	*op = fld_op;
+
+	prange = req_capsule_client_get(&req->rq_pill, &RMF_FLD_MDFLD);
+	*prange = *range;
+
+	ptlrpc_request_set_replen(req);
+	req->rq_request_portal = FLD_REQUEST_PORTAL;
+	ptlrpc_at_set_req_timeout(req);
+
+	if (fld_op == FLD_LOOKUP &&
+	    imp->imp_connect_flags_orig & OBD_CONNECT_MDS_MDS)
+		req->rq_allow_replay = 1;
+
+	if (fld_op != FLD_LOOKUP)
+		mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
+	fld_enter_request(&exp->exp_obd->u.cli);
+	rc = ptlrpc_queue_wait(req);
+	fld_exit_request(&exp->exp_obd->u.cli);
+	if (fld_op != FLD_LOOKUP)
+		mdc_put_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
+	if (rc)
+		GOTO(out_req, rc);
+
+	prange = req_capsule_server_get(&req->rq_pill, &RMF_FLD_MDFLD);
+	if (prange == NULL)
+		GOTO(out_req, rc = -EFAULT);
+	*range = *prange;
+	EXIT;
+out_req:
+	ptlrpc_req_finished(req);
+	return rc;
+}
+
+int fld_client_lookup(struct lu_client_fld *fld, seqno_t seq, mdsno_t *mds,
+		      __u32 flags, const struct lu_env *env)
+{
+	struct lu_seq_range res = { 0 };
+	struct lu_fld_target *target;
+	int rc;
+	ENTRY;
+
+	fld->lcf_flags |= LUSTRE_FLD_RUN;
+
+	rc = fld_cache_lookup(fld->lcf_cache, seq, &res);
+	if (rc == 0) {
+		*mds = res.lsr_index;
+		RETURN(0);
+	}
+
+	/* Can not find it in the cache */
+	target = fld_client_get_target(fld, seq);
+	LASSERT(target != NULL);
+
+	CDEBUG(D_INFO, "%s: Lookup fld entry (seq: "LPX64") on "
+	       "target %s (idx "LPU64")\n", fld->lcf_name, seq,
+	       fld_target_name(target), target->ft_idx);
+
+	res.lsr_start = seq;
+	fld_range_set_type(&res, flags);
+	if (target->ft_srv != NULL) {
+		LASSERT(env != NULL);
+		rc = fld_server_lookup(env, target->ft_srv, seq, &res);
+	} else {
+		rc = fld_client_rpc(target->ft_exp, &res, FLD_LOOKUP);
+	}
+
+	if (rc == 0) {
+		*mds = res.lsr_index;
+
+		fld_cache_insert(fld->lcf_cache, &res);
+	}
+	RETURN(rc);
+}
+EXPORT_SYMBOL(fld_client_lookup);
+
+void fld_client_flush(struct lu_client_fld *fld)
+{
+	fld_cache_flush(fld->lcf_cache);
+}
+EXPORT_SYMBOL(fld_client_flush);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/lproc_fld.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/lproc_fld.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/lproc_fld.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/lproc_fld.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,373 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, 2013, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/fld/lproc_fld.c
+ *
+ * FLD (FIDs Location Database)
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ *	Di Wang <di.wang@whamcloud.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_FLD
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/module.h>
+
+#include <obd.h>
+#include <obd_class.h>
+#include <dt_object.h>
+#include <md_object.h>
+#include <obd_support.h>
+#include <lustre_req_layout.h>
+#include <lustre_fld.h>
+#include <lustre_fid.h>
+#include "fld_internal.h"
+
+#ifdef LPROCFS
+static int
+fld_proc_targets_seq_show(struct seq_file *m, void *unused)
+{
+	struct lu_client_fld *fld = (struct lu_client_fld *)m->private;
+	struct lu_fld_target *target;
+	ENTRY;
+
+	LASSERT(fld != NULL);
+
+	spin_lock(&fld->lcf_lock);
+	list_for_each_entry(target,
+				&fld->lcf_targets, ft_chain)
+		seq_printf(m, "%s\n", fld_target_name(target));
+	spin_unlock(&fld->lcf_lock);
+
+	RETURN(0);
+}
+
+static int
+fld_proc_hash_seq_show(struct seq_file *m, void *unused)
+{
+	struct lu_client_fld *fld = (struct lu_client_fld *)m->private;
+	ENTRY;
+
+	LASSERT(fld != NULL);
+
+	spin_lock(&fld->lcf_lock);
+	seq_printf(m, "%s\n", fld->lcf_hash->fh_name);
+	spin_unlock(&fld->lcf_lock);
+
+	RETURN(0);
+}
+
+static ssize_t
+fld_proc_hash_seq_write(struct file *file, const char *buffer,
+			size_t count, loff_t *off)
+{
+	struct lu_client_fld *fld = ((struct seq_file *)file->private_data)->private;
+	struct lu_fld_hash *hash = NULL;
+	int i;
+	ENTRY;
+
+	LASSERT(fld != NULL);
+
+	for (i = 0; fld_hash[i].fh_name != NULL; i++) {
+		if (count != strlen(fld_hash[i].fh_name))
+			continue;
+
+		if (!strncmp(fld_hash[i].fh_name, buffer, count)) {
+			hash = &fld_hash[i];
+			break;
+		}
+	}
+
+	if (hash != NULL) {
+		spin_lock(&fld->lcf_lock);
+		fld->lcf_hash = hash;
+		spin_unlock(&fld->lcf_lock);
+
+		CDEBUG(D_INFO, "%s: Changed hash to \"%s\"\n",
+		       fld->lcf_name, hash->fh_name);
+	}
+
+	RETURN(count);
+}
+
+static ssize_t
+fld_proc_cache_flush_write(struct file *file, const char __user *buffer,
+			       size_t count, loff_t *pos)
+{
+	struct lu_client_fld *fld = file->private_data;
+	ENTRY;
+
+	LASSERT(fld != NULL);
+
+	fld_cache_flush(fld->lcf_cache);
+
+	CDEBUG(D_INFO, "%s: Lookup cache is flushed\n", fld->lcf_name);
+
+	RETURN(count);
+}
+
+static int fld_proc_cache_flush_open(struct inode *inode, struct file *file)
+{
+	file->private_data = PDE_DATA(inode);
+	return 0;
+}
+
+static int fld_proc_cache_flush_release(struct inode *inode, struct file *file)
+{
+	file->private_data = NULL;
+	return 0;
+}
+
+struct file_operations fld_proc_cache_flush_fops = {
+	.owner		= THIS_MODULE,
+	.open		= fld_proc_cache_flush_open,
+	.write		= fld_proc_cache_flush_write,
+	.release	= fld_proc_cache_flush_release,
+};
+
+struct fld_seq_param {
+	struct lu_env		fsp_env;
+	struct dt_it		*fsp_it;
+	struct lu_server_fld	*fsp_fld;
+	unsigned int		fsp_stop:1;
+};
+
+static void *fldb_seq_start(struct seq_file *p, loff_t *pos)
+{
+	struct fld_seq_param    *param = p->private;
+	struct lu_server_fld    *fld;
+	struct dt_object	*obj;
+	const struct dt_it_ops  *iops;
+
+	if (param == NULL || param->fsp_stop)
+		return NULL;
+
+	fld = param->fsp_fld;
+	obj = fld->lsf_obj;
+	LASSERT(obj != NULL);
+	iops = &obj->do_index_ops->dio_it;
+
+	iops->load(&param->fsp_env, param->fsp_it, *pos);
+
+	*pos = be64_to_cpu(*(__u64 *)iops->key(&param->fsp_env, param->fsp_it));
+	return param;
+}
+
+static void fldb_seq_stop(struct seq_file *p, void *v)
+{
+	struct fld_seq_param    *param = p->private;
+	const struct dt_it_ops	*iops;
+	struct lu_server_fld	*fld;
+	struct dt_object	*obj;
+
+	if (param == NULL)
+		return;
+
+	fld = param->fsp_fld;
+	obj = fld->lsf_obj;
+	LASSERT(obj != NULL);
+	iops = &obj->do_index_ops->dio_it;
+
+	iops->put(&param->fsp_env, param->fsp_it);
+}
+
+static void *fldb_seq_next(struct seq_file *p, void *v, loff_t *pos)
+{
+	struct fld_seq_param    *param = p->private;
+	struct lu_server_fld	*fld;
+	struct dt_object	*obj;
+	const struct dt_it_ops	*iops;
+	int			rc;
+
+	if (param == NULL || param->fsp_stop)
+		return NULL;
+
+	fld = param->fsp_fld;
+	obj = fld->lsf_obj;
+	LASSERT(obj != NULL);
+	iops = &obj->do_index_ops->dio_it;
+
+	rc = iops->next(&param->fsp_env, param->fsp_it);
+	if (rc > 0) {
+		param->fsp_stop = 1;
+		return NULL;
+	}
+
+	*pos = be64_to_cpu(*(__u64 *)iops->key(&param->fsp_env, param->fsp_it));
+	return param;
+}
+
+static int fldb_seq_show(struct seq_file *p, void *v)
+{
+	struct fld_seq_param    *param = p->private;
+	struct lu_server_fld	*fld;
+	struct dt_object	*obj;
+	const struct dt_it_ops	*iops;
+	struct fld_thread_info	*info;
+	struct lu_seq_range	*fld_rec;
+	int			rc;
+
+	if (param == NULL || param->fsp_stop)
+		return 0;
+
+	fld = param->fsp_fld;
+	obj = fld->lsf_obj;
+	LASSERT(obj != NULL);
+	iops = &obj->do_index_ops->dio_it;
+
+	info = lu_context_key_get(&param->fsp_env.le_ctx,
+				  &fld_thread_key);
+	fld_rec = &info->fti_rec;
+	rc = iops->rec(&param->fsp_env, param->fsp_it,
+		       (struct dt_rec *)fld_rec, 0);
+	if (rc != 0) {
+		CERROR("%s:read record error: rc %d\n",
+		       fld->lsf_name, rc);
+	} else if (fld_rec->lsr_start != 0) {
+		range_be_to_cpu(fld_rec, fld_rec);
+		rc = seq_printf(p, DRANGE"\n", PRANGE(fld_rec));
+	}
+
+	return rc;
+}
+
+struct seq_operations fldb_sops = {
+	.start = fldb_seq_start,
+	.stop = fldb_seq_stop,
+	.next = fldb_seq_next,
+	.show = fldb_seq_show,
+};
+
+static int fldb_seq_open(struct inode *inode, struct file *file)
+{
+	struct seq_file		*seq;
+	struct lu_server_fld    *fld = (struct lu_server_fld *)PDE_DATA(inode);
+	struct dt_object	*obj;
+	const struct dt_it_ops  *iops;
+	struct fld_seq_param    *param = NULL;
+	int			env_init = 0;
+	int			rc;
+
+	rc = seq_open(file, &fldb_sops);
+	if (rc)
+		GOTO(out, rc);
+
+	obj = fld->lsf_obj;
+	if (obj == NULL) {
+		seq = file->private_data;
+		seq->private = NULL;
+		return 0;
+	}
+
+	OBD_ALLOC_PTR(param);
+	if (param == NULL)
+		GOTO(out, rc = -ENOMEM);
+
+	rc = lu_env_init(&param->fsp_env, LCT_MD_THREAD);
+	if (rc != 0)
+		GOTO(out, rc);
+
+	env_init = 1;
+	iops = &obj->do_index_ops->dio_it;
+	param->fsp_it = iops->init(&param->fsp_env, obj, 0, NULL);
+	if (IS_ERR(param->fsp_it))
+		GOTO(out, rc = PTR_ERR(param->fsp_it));
+
+	param->fsp_fld = fld;
+	param->fsp_stop = 0;
+
+	seq = file->private_data;
+	seq->private = param;
+out:
+	if (rc != 0) {
+		if (env_init == 1)
+			lu_env_fini(&param->fsp_env);
+		if (param != NULL)
+			OBD_FREE_PTR(param);
+	}
+	return rc;
+}
+
+static int fldb_seq_release(struct inode *inode, struct file *file)
+{
+	struct seq_file		*seq = file->private_data;
+	struct fld_seq_param	*param;
+	struct lu_server_fld	*fld;
+	struct dt_object	*obj;
+	const struct dt_it_ops	*iops;
+
+	param = seq->private;
+	if (param == NULL) {
+		lprocfs_seq_release(inode, file);
+		return 0;
+	}
+
+	fld = param->fsp_fld;
+	obj = fld->lsf_obj;
+	LASSERT(obj != NULL);
+	iops = &obj->do_index_ops->dio_it;
+
+	LASSERT(iops != NULL);
+	LASSERT(obj != NULL);
+	LASSERT(param->fsp_it != NULL);
+	iops->fini(&param->fsp_env, param->fsp_it);
+	lu_env_fini(&param->fsp_env);
+	OBD_FREE_PTR(param);
+	lprocfs_seq_release(inode, file);
+
+	return 0;
+}
+
+struct lprocfs_vars fld_server_proc_list[] = {
+	{ NULL }};
+
+LPROC_SEQ_FOPS_RO(fld_proc_targets);
+LPROC_SEQ_FOPS(fld_proc_hash);
+
+struct lprocfs_vars fld_client_proc_list[] = {
+	{ "targets", &fld_proc_targets_fops },
+	{ "hash", &fld_proc_hash_fops },
+	{ "cache_flush", &fld_proc_cache_flush_fops },
+	{ NULL }};
+
+struct file_operations fld_proc_seq_fops = {
+	.owner   = THIS_MODULE,
+	.open    = fldb_seq_open,
+	.read    = seq_read,
+	.release = fldb_seq_release,
+};
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/Makefile linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/Makefile
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/fld/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/fld/Makefile	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,5 @@
+obj-$(CONFIG_LUSTRE_FS) += fld.o
+fld-y := fld_handler.o fld_request.o fld_cache.o fld_index.o lproc_fld.o
+
+
+ccflags-y := -I$(src)/../include
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/cl_object.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/cl_object.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/cl_object.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/cl_object.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3279 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+#ifndef _LUSTRE_CL_OBJECT_H
+#define _LUSTRE_CL_OBJECT_H
+
+/** \defgroup clio clio
+ *
+ * Client objects implement io operations and cache pages.
+ *
+ * Examples: lov and osc are implementations of cl interface.
+ *
+ * Big Theory Statement.
+ *
+ * Layered objects.
+ *
+ * Client implementation is based on the following data-types:
+ *
+ *   - cl_object
+ *
+ *   - cl_page
+ *
+ *   - cl_lock     represents an extent lock on an object.
+ *
+ *   - cl_io       represents high-level i/o activity such as whole read/write
+ *		 system call, or write-out of pages from under the lock being
+ *		 canceled. cl_io has sub-ios that can be stopped and resumed
+ *		 independently, thus achieving high degree of transfer
+ *		 parallelism. Single cl_io can be advanced forward by
+ *		 the multiple threads (although in the most usual case of
+ *		 read/write system call it is associated with the single user
+ *		 thread, that issued the system call).
+ *
+ *   - cl_req      represents a collection of pages for a transfer. cl_req is
+ *		 constructed by req-forming engine that tries to saturate
+ *		 transport with large and continuous transfers.
+ *
+ * Terminology
+ *
+ *     - to avoid confusion high-level I/O operation like read or write system
+ *     call is referred to as "an io", whereas low-level I/O operation, like
+ *     RPC, is referred to as "a transfer"
+ *
+ *     - "generic code" means generic (not file system specific) code in the
+ *     hosting environment. "cl-code" means code (mostly in cl_*.c files) that
+ *     is not layer specific.
+ *
+ * Locking.
+ *
+ *  - i_mutex
+ *      - PG_locked
+ *	  - cl_object_header::coh_page_guard
+ *	  - cl_object_header::coh_lock_guard
+ *	  - lu_site::ls_guard
+ *
+ * See the top comment in cl_object.c for the description of overall locking and
+ * reference-counting design.
+ *
+ * See comments below for the description of i/o, page, and dlm-locking
+ * design.
+ *
+ * @{
+ */
+
+/*
+ * super-class definitions.
+ */
+#include <lu_object.h>
+#include <lvfs.h>
+#	include <linux/mutex.h>
+#	include <linux/radix-tree.h>
+
+struct inode;
+
+struct cl_device;
+struct cl_device_operations;
+
+struct cl_object;
+struct cl_object_page_operations;
+struct cl_object_lock_operations;
+
+struct cl_page;
+struct cl_page_slice;
+struct cl_lock;
+struct cl_lock_slice;
+
+struct cl_lock_operations;
+struct cl_page_operations;
+
+struct cl_io;
+struct cl_io_slice;
+
+struct cl_req;
+struct cl_req_slice;
+
+/**
+ * Operations for each data device in the client stack.
+ *
+ * \see vvp_cl_ops, lov_cl_ops, lovsub_cl_ops, osc_cl_ops
+ */
+struct cl_device_operations {
+	/**
+	 * Initialize cl_req. This method is called top-to-bottom on all
+	 * devices in the stack to get them a chance to allocate layer-private
+	 * data, and to attach them to the cl_req by calling
+	 * cl_req_slice_add().
+	 *
+	 * \see osc_req_init(), lov_req_init(), lovsub_req_init()
+	 * \see ccc_req_init()
+	 */
+	int (*cdo_req_init)(const struct lu_env *env, struct cl_device *dev,
+			    struct cl_req *req);
+};
+
+/**
+ * Device in the client stack.
+ *
+ * \see ccc_device, lov_device, lovsub_device, osc_device
+ */
+struct cl_device {
+	/** Super-class. */
+	struct lu_device		   cd_lu_dev;
+	/** Per-layer operation vector. */
+	const struct cl_device_operations *cd_ops;
+};
+
+/** \addtogroup cl_object cl_object
+ * @{ */
+/**
+ * "Data attributes" of cl_object. Data attributes can be updated
+ * independently for a sub-object, and top-object's attributes are calculated
+ * from sub-objects' ones.
+ */
+struct cl_attr {
+	/** Object size, in bytes */
+	loff_t cat_size;
+	/**
+	 * Known minimal size, in bytes.
+	 *
+	 * This is only valid when at least one DLM lock is held.
+	 */
+	loff_t cat_kms;
+	/** Modification time. Measured in seconds since epoch. */
+	time_t cat_mtime;
+	/** Access time. Measured in seconds since epoch. */
+	time_t cat_atime;
+	/** Change time. Measured in seconds since epoch. */
+	time_t cat_ctime;
+	/**
+	 * Blocks allocated to this cl_object on the server file system.
+	 *
+	 * \todo XXX An interface for block size is needed.
+	 */
+	__u64  cat_blocks;
+	/**
+	 * User identifier for quota purposes.
+	 */
+	uid_t  cat_uid;
+	/**
+	 * Group identifier for quota purposes.
+	 */
+	gid_t  cat_gid;
+};
+
+/**
+ * Fields in cl_attr that are being set.
+ */
+enum cl_attr_valid {
+	CAT_SIZE   = 1 << 0,
+	CAT_KMS    = 1 << 1,
+	CAT_MTIME  = 1 << 3,
+	CAT_ATIME  = 1 << 4,
+	CAT_CTIME  = 1 << 5,
+	CAT_BLOCKS = 1 << 6,
+	CAT_UID    = 1 << 7,
+	CAT_GID    = 1 << 8
+};
+
+/**
+ * Sub-class of lu_object with methods common for objects on the client
+ * stacks.
+ *
+ * cl_object: represents a regular file system object, both a file and a
+ *    stripe. cl_object is based on lu_object: it is identified by a fid,
+ *    layered, cached, hashed, and lrued. Important distinction with the server
+ *    side, where md_object and dt_object are used, is that cl_object "fans out"
+ *    at the lov/sns level: depending on the file layout, single file is
+ *    represented as a set of "sub-objects" (stripes). At the implementation
+ *    level, struct lov_object contains an array of cl_objects. Each sub-object
+ *    is a full-fledged cl_object, having its fid, living in the lru and hash
+ *    table.
+ *
+ *    This leads to the next important difference with the server side: on the
+ *    client, it's quite usual to have objects with the different sequence of
+ *    layers. For example, typical top-object is composed of the following
+ *    layers:
+ *
+ *	- vvp
+ *	- lov
+ *
+ *    whereas its sub-objects are composed of
+ *
+ *	- lovsub
+ *	- osc
+ *
+ *    layers. Here "lovsub" is a mostly dummy layer, whose purpose is to keep
+ *    track of the object-subobject relationship.
+ *
+ *    Sub-objects are not cached independently: when top-object is about to
+ *    be discarded from the memory, all its sub-objects are torn-down and
+ *    destroyed too.
+ *
+ * \see ccc_object, lov_object, lovsub_object, osc_object
+ */
+struct cl_object {
+	/** super class */
+	struct lu_object		   co_lu;
+	/** per-object-layer operations */
+	const struct cl_object_operations *co_ops;
+	/** offset of page slice in cl_page buffer */
+	int				   co_slice_off;
+};
+
+/**
+ * Description of the client object configuration. This is used for the
+ * creation of a new client object that is identified by a more state than
+ * fid.
+ */
+struct cl_object_conf {
+	/** Super-class. */
+	struct lu_object_conf     coc_lu;
+	union {
+		/**
+		 * Object layout. This is consumed by lov.
+		 */
+		struct lustre_md *coc_md;
+		/**
+		 * Description of particular stripe location in the
+		 * cluster. This is consumed by osc.
+		 */
+		struct lov_oinfo *coc_oinfo;
+	} u;
+	/**
+	 * VFS inode. This is consumed by vvp.
+	 */
+	struct inode	     *coc_inode;
+	/**
+	 * Layout lock handle.
+	 */
+	struct ldlm_lock	 *coc_lock;
+	/**
+	 * Operation to handle layout, OBJECT_CONF_XYZ.
+	 */
+	int			  coc_opc;
+};
+
+enum {
+	/** configure layout, set up a new stripe, must be called while
+	 * holding layout lock. */
+	OBJECT_CONF_SET = 0,
+	/** invalidate the current stripe configuration due to losing
+	 * layout lock. */
+	OBJECT_CONF_INVALIDATE = 1,
+	/** wait for old layout to go away so that new layout can be
+	 * set up. */
+	OBJECT_CONF_WAIT = 2
+};
+
+/**
+ * Operations implemented for each cl object layer.
+ *
+ * \see vvp_ops, lov_ops, lovsub_ops, osc_ops
+ */
+struct cl_object_operations {
+	/**
+	 * Initialize page slice for this layer. Called top-to-bottom through
+	 * every object layer when a new cl_page is instantiated. Layer
+	 * keeping private per-page data, or requiring its own page operations
+	 * vector should allocate these data here, and attach then to the page
+	 * by calling cl_page_slice_add(). \a vmpage is locked (in the VM
+	 * sense). Optional.
+	 *
+	 * \retval NULL success.
+	 *
+	 * \retval ERR_PTR(errno) failure code.
+	 *
+	 * \retval valid-pointer pointer to already existing referenced page
+	 *	 to be used instead of newly created.
+	 */
+	int  (*coo_page_init)(const struct lu_env *env, struct cl_object *obj,
+				struct cl_page *page, struct page *vmpage);
+	/**
+	 * Initialize lock slice for this layer. Called top-to-bottom through
+	 * every object layer when a new cl_lock is instantiated. Layer
+	 * keeping private per-lock data, or requiring its own lock operations
+	 * vector should allocate these data here, and attach then to the lock
+	 * by calling cl_lock_slice_add(). Mandatory.
+	 */
+	int  (*coo_lock_init)(const struct lu_env *env,
+			      struct cl_object *obj, struct cl_lock *lock,
+			      const struct cl_io *io);
+	/**
+	 * Initialize io state for a given layer.
+	 *
+	 * called top-to-bottom once per io existence to initialize io
+	 * state. If layer wants to keep some state for this type of io, it
+	 * has to embed struct cl_io_slice in lu_env::le_ses, and register
+	 * slice with cl_io_slice_add(). It is guaranteed that all threads
+	 * participating in this io share the same session.
+	 */
+	int  (*coo_io_init)(const struct lu_env *env,
+			    struct cl_object *obj, struct cl_io *io);
+	/**
+	 * Fill portion of \a attr that this layer controls. This method is
+	 * called top-to-bottom through all object layers.
+	 *
+	 * \pre cl_object_header::coh_attr_guard of the top-object is locked.
+	 *
+	 * \return   0: to continue
+	 * \return +ve: to stop iterating through layers (but 0 is returned
+	 * from enclosing cl_object_attr_get())
+	 * \return -ve: to signal error
+	 */
+	int (*coo_attr_get)(const struct lu_env *env, struct cl_object *obj,
+			    struct cl_attr *attr);
+	/**
+	 * Update attributes.
+	 *
+	 * \a valid is a bitmask composed from enum #cl_attr_valid, and
+	 * indicating what attributes are to be set.
+	 *
+	 * \pre cl_object_header::coh_attr_guard of the top-object is locked.
+	 *
+	 * \return the same convention as for
+	 * cl_object_operations::coo_attr_get() is used.
+	 */
+	int (*coo_attr_set)(const struct lu_env *env, struct cl_object *obj,
+			    const struct cl_attr *attr, unsigned valid);
+	/**
+	 * Update object configuration. Called top-to-bottom to modify object
+	 * configuration.
+	 *
+	 * XXX error conditions and handling.
+	 */
+	int (*coo_conf_set)(const struct lu_env *env, struct cl_object *obj,
+			    const struct cl_object_conf *conf);
+	/**
+	 * Glimpse ast. Executed when glimpse ast arrives for a lock on this
+	 * object. Layers are supposed to fill parts of \a lvb that will be
+	 * shipped to the glimpse originator as a glimpse result.
+	 *
+	 * \see ccc_object_glimpse(), lovsub_object_glimpse(),
+	 * \see osc_object_glimpse()
+	 */
+	int (*coo_glimpse)(const struct lu_env *env,
+			   const struct cl_object *obj, struct ost_lvb *lvb);
+};
+
+/**
+ * Extended header for client object.
+ */
+struct cl_object_header {
+	/** Standard lu_object_header. cl_object::co_lu::lo_header points
+	 * here. */
+	struct lu_object_header  coh_lu;
+	/** \name locks
+	 * \todo XXX move locks below to the separate cache-lines, they are
+	 * mostly useless otherwise.
+	 */
+	/** @{ */
+	/** Lock protecting page tree. */
+	spinlock_t		 coh_page_guard;
+	/** Lock protecting lock list. */
+	spinlock_t		 coh_lock_guard;
+	/** @} locks */
+	/** Radix tree of cl_page's, cached for this object. */
+	struct radix_tree_root   coh_tree;
+	/** # of pages in radix tree. */
+	unsigned long	    coh_pages;
+	/** List of cl_lock's granted for this object. */
+	struct list_head	       coh_locks;
+
+	/**
+	 * Parent object. It is assumed that an object has a well-defined
+	 * parent, but not a well-defined child (there may be multiple
+	 * sub-objects, for the same top-object). cl_object_header::coh_parent
+	 * field allows certain code to be written generically, without
+	 * limiting possible cl_object layouts unduly.
+	 */
+	struct cl_object_header *coh_parent;
+	/**
+	 * Protects consistency between cl_attr of parent object and
+	 * attributes of sub-objects, that the former is calculated ("merged")
+	 * from.
+	 *
+	 * \todo XXX this can be read/write lock if needed.
+	 */
+	spinlock_t		 coh_attr_guard;
+	/**
+	 * Size of cl_page + page slices
+	 */
+	unsigned short		 coh_page_bufsize;
+	/**
+	 * Number of objects above this one: 0 for a top-object, 1 for its
+	 * sub-object, etc.
+	 */
+	unsigned char		 coh_nesting;
+};
+
+/**
+ * Helper macro: iterate over all layers of the object \a obj, assigning every
+ * layer top-to-bottom to \a slice.
+ */
+#define cl_object_for_each(slice, obj)				      \
+	list_for_each_entry((slice),				    \
+				&(obj)->co_lu.lo_header->loh_layers,	\
+				co_lu.lo_linkage)
+/**
+ * Helper macro: iterate over all layers of the object \a obj, assigning every
+ * layer bottom-to-top to \a slice.
+ */
+#define cl_object_for_each_reverse(slice, obj)			       \
+	list_for_each_entry_reverse((slice),			     \
+					&(obj)->co_lu.lo_header->loh_layers, \
+					co_lu.lo_linkage)
+/** @} cl_object */
+
+#ifndef pgoff_t
+#define pgoff_t unsigned long
+#endif
+
+#define CL_PAGE_EOF ((pgoff_t)~0ull)
+
+/** \addtogroup cl_page cl_page
+ * @{ */
+
+/** \struct cl_page
+ * Layered client page.
+ *
+ * cl_page: represents a portion of a file, cached in the memory. All pages
+ *    of the given file are of the same size, and are kept in the radix tree
+ *    hanging off the cl_object. cl_page doesn't fan out, but as sub-objects
+ *    of the top-level file object are first class cl_objects, they have their
+ *    own radix trees of pages and hence page is implemented as a sequence of
+ *    struct cl_pages's, linked into double-linked list through
+ *    cl_page::cp_parent and cl_page::cp_child pointers, each residing in the
+ *    corresponding radix tree at the corresponding logical offset.
+ *
+ * cl_page is associated with VM page of the hosting environment (struct
+ *    page in Linux kernel, for example), struct page. It is assumed, that this
+ *    association is implemented by one of cl_page layers (top layer in the
+ *    current design) that
+ *
+ *	- intercepts per-VM-page call-backs made by the environment (e.g.,
+ *	  memory pressure),
+ *
+ *	- translates state (page flag bits) and locking between lustre and
+ *	  environment.
+ *
+ *    The association between cl_page and struct page is immutable and
+ *    established when cl_page is created.
+ *
+ * cl_page can be "owned" by a particular cl_io (see below), guaranteeing
+ *    this io an exclusive access to this page w.r.t. other io attempts and
+ *    various events changing page state (such as transfer completion, or
+ *    eviction of the page from the memory). Note, that in general cl_io
+ *    cannot be identified with a particular thread, and page ownership is not
+ *    exactly equal to the current thread holding a lock on the page. Layer
+ *    implementing association between cl_page and struct page has to implement
+ *    ownership on top of available synchronization mechanisms.
+ *
+ *    While lustre client maintains the notion of an page ownership by io,
+ *    hosting MM/VM usually has its own page concurrency control
+ *    mechanisms. For example, in Linux, page access is synchronized by the
+ *    per-page PG_locked bit-lock, and generic kernel code (generic_file_*())
+ *    takes care to acquire and release such locks as necessary around the
+ *    calls to the file system methods (->readpage(), ->prepare_write(),
+ *    ->commit_write(), etc.). This leads to the situation when there are two
+ *    different ways to own a page in the client:
+ *
+ *	- client code explicitly and voluntary owns the page (cl_page_own());
+ *
+ *	- VM locks a page and then calls the client, that has "to assume"
+ *	  the ownership from the VM (cl_page_assume()).
+ *
+ *    Dual methods to release ownership are cl_page_disown() and
+ *    cl_page_unassume().
+ *
+ * cl_page is reference counted (cl_page::cp_ref). When reference counter
+ *    drops to 0, the page is returned to the cache, unless it is in
+ *    cl_page_state::CPS_FREEING state, in which case it is immediately
+ *    destroyed.
+ *
+ *    The general logic guaranteeing the absence of "existential races" for
+ *    pages is the following:
+ *
+ *	- there are fixed known ways for a thread to obtain a new reference
+ *	  to a page:
+ *
+ *	    - by doing a lookup in the cl_object radix tree, protected by the
+ *	      spin-lock;
+ *
+ *	    - by starting from VM-locked struct page and following some
+ *	      hosting environment method (e.g., following ->private pointer in
+ *	      the case of Linux kernel), see cl_vmpage_page();
+ *
+ *	- when the page enters cl_page_state::CPS_FREEING state, all these
+ *	  ways are severed with the proper synchronization
+ *	  (cl_page_delete());
+ *
+ *	- entry into cl_page_state::CPS_FREEING is serialized by the VM page
+ *	  lock;
+ *
+ *	- no new references to the page in cl_page_state::CPS_FREEING state
+ *	  are allowed (checked in cl_page_get()).
+ *
+ *    Together this guarantees that when last reference to a
+ *    cl_page_state::CPS_FREEING page is released, it is safe to destroy the
+ *    page, as neither references to it can be acquired at that point, nor
+ *    ones exist.
+ *
+ * cl_page is a state machine. States are enumerated in enum
+ *    cl_page_state. Possible state transitions are enumerated in
+ *    cl_page_state_set(). State transition process (i.e., actual changing of
+ *    cl_page::cp_state field) is protected by the lock on the underlying VM
+ *    page.
+ *
+ * Linux Kernel implementation.
+ *
+ *    Binding between cl_page and struct page (which is a typedef for
+ *    struct page) is implemented in the vvp layer. cl_page is attached to the
+ *    ->private pointer of the struct page, together with the setting of
+ *    PG_private bit in page->flags, and acquiring additional reference on the
+ *    struct page (much like struct buffer_head, or any similar file system
+ *    private data structures).
+ *
+ *    PG_locked lock is used to implement both ownership and transfer
+ *    synchronization, that is, page is VM-locked in CPS_{OWNED,PAGE{IN,OUT}}
+ *    states. No additional references are acquired for the duration of the
+ *    transfer.
+ *
+ * \warning *THIS IS NOT* the behavior expected by the Linux kernel, where
+ *	  write-out is "protected" by the special PG_writeback bit.
+ */
+
+/**
+ * States of cl_page. cl_page.c assumes particular order here.
+ *
+ * The page state machine is rather crude, as it doesn't recognize finer page
+ * states like "dirty" or "up to date". This is because such states are not
+ * always well defined for the whole stack (see, for example, the
+ * implementation of the read-ahead, that hides page up-to-dateness to track
+ * cache hits accurately). Such sub-states are maintained by the layers that
+ * are interested in them.
+ */
+enum cl_page_state {
+	/**
+	 * Page is in the cache, un-owned. Page leaves cached state in the
+	 * following cases:
+	 *
+	 *     - [cl_page_state::CPS_OWNED] io comes across the page and
+	 *     owns it;
+	 *
+	 *     - [cl_page_state::CPS_PAGEOUT] page is dirty, the
+	 *     req-formation engine decides that it wants to include this page
+	 *     into an cl_req being constructed, and yanks it from the cache;
+	 *
+	 *     - [cl_page_state::CPS_FREEING] VM callback is executed to
+	 *     evict the page form the memory;
+	 *
+	 * \invariant cl_page::cp_owner == NULL && cl_page::cp_req == NULL
+	 */
+	CPS_CACHED,
+	/**
+	 * Page is exclusively owned by some cl_io. Page may end up in this
+	 * state as a result of
+	 *
+	 *     - io creating new page and immediately owning it;
+	 *
+	 *     - [cl_page_state::CPS_CACHED] io finding existing cached page
+	 *     and owning it;
+	 *
+	 *     - [cl_page_state::CPS_OWNED] io finding existing owned page
+	 *     and waiting for owner to release the page;
+	 *
+	 * Page leaves owned state in the following cases:
+	 *
+	 *     - [cl_page_state::CPS_CACHED] io decides to leave the page in
+	 *     the cache, doing nothing;
+	 *
+	 *     - [cl_page_state::CPS_PAGEIN] io starts read transfer for
+	 *     this page;
+	 *
+	 *     - [cl_page_state::CPS_PAGEOUT] io starts immediate write
+	 *     transfer for this page;
+	 *
+	 *     - [cl_page_state::CPS_FREEING] io decides to destroy this
+	 *     page (e.g., as part of truncate or extent lock cancellation).
+	 *
+	 * \invariant cl_page::cp_owner != NULL && cl_page::cp_req == NULL
+	 */
+	CPS_OWNED,
+	/**
+	 * Page is being written out, as a part of a transfer. This state is
+	 * entered when req-formation logic decided that it wants this page to
+	 * be sent through the wire _now_. Specifically, it means that once
+	 * this state is achieved, transfer completion handler (with either
+	 * success or failure indication) is guaranteed to be executed against
+	 * this page independently of any locks and any scheduling decisions
+	 * made by the hosting environment (that effectively means that the
+	 * page is never put into cl_page_state::CPS_PAGEOUT state "in
+	 * advance". This property is mentioned, because it is important when
+	 * reasoning about possible dead-locks in the system). The page can
+	 * enter this state as a result of
+	 *
+	 *     - [cl_page_state::CPS_OWNED] an io requesting an immediate
+	 *     write-out of this page, or
+	 *
+	 *     - [cl_page_state::CPS_CACHED] req-forming engine deciding
+	 *     that it has enough dirty pages cached to issue a "good"
+	 *     transfer.
+	 *
+	 * The page leaves cl_page_state::CPS_PAGEOUT state when the transfer
+	 * is completed---it is moved into cl_page_state::CPS_CACHED state.
+	 *
+	 * Underlying VM page is locked for the duration of transfer.
+	 *
+	 * \invariant: cl_page::cp_owner == NULL && cl_page::cp_req != NULL
+	 */
+	CPS_PAGEOUT,
+	/**
+	 * Page is being read in, as a part of a transfer. This is quite
+	 * similar to the cl_page_state::CPS_PAGEOUT state, except that
+	 * read-in is always "immediate"---there is no such thing a sudden
+	 * construction of read cl_req from cached, presumably not up to date,
+	 * pages.
+	 *
+	 * Underlying VM page is locked for the duration of transfer.
+	 *
+	 * \invariant: cl_page::cp_owner == NULL && cl_page::cp_req != NULL
+	 */
+	CPS_PAGEIN,
+	/**
+	 * Page is being destroyed. This state is entered when client decides
+	 * that page has to be deleted from its host object, as, e.g., a part
+	 * of truncate.
+	 *
+	 * Once this state is reached, there is no way to escape it.
+	 *
+	 * \invariant: cl_page::cp_owner == NULL && cl_page::cp_req == NULL
+	 */
+	CPS_FREEING,
+	CPS_NR
+};
+
+enum cl_page_type {
+	/** Host page, the page is from the host inode which the cl_page
+	 * belongs to. */
+	CPT_CACHEABLE = 1,
+
+	/** Transient page, the transient cl_page is used to bind a cl_page
+	 *  to vmpage which is not belonging to the same object of cl_page.
+	 *  it is used in DirectIO, lockless IO and liblustre. */
+	CPT_TRANSIENT,
+};
+
+/**
+ * Flags maintained for every cl_page.
+ */
+enum cl_page_flags {
+	/**
+	 * Set when pagein completes. Used for debugging (read completes at
+	 * most once for a page).
+	 */
+	CPF_READ_COMPLETED = 1 << 0
+};
+
+/**
+ * Fields are protected by the lock on struct page, except for atomics and
+ * immutables.
+ *
+ * \invariant Data type invariants are in cl_page_invariant(). Basically:
+ * cl_page::cp_parent and cl_page::cp_child are a well-formed double-linked
+ * list, consistent with the parent/child pointers in the cl_page::cp_obj and
+ * cl_page::cp_owner (when set).
+ */
+struct cl_page {
+	/** Reference counter. */
+	atomic_t	     cp_ref;
+	/** An object this page is a part of. Immutable after creation. */
+	struct cl_object	*cp_obj;
+	/** Logical page index within the object. Immutable after creation. */
+	pgoff_t		  cp_index;
+	/** List of slices. Immutable after creation. */
+	struct list_head	       cp_layers;
+	/** Parent page, NULL for top-level page. Immutable after creation. */
+	struct cl_page	  *cp_parent;
+	/** Lower-layer page. NULL for bottommost page. Immutable after
+	 * creation. */
+	struct cl_page	  *cp_child;
+	/**
+	 * Page state. This field is const to avoid accidental update, it is
+	 * modified only internally within cl_page.c. Protected by a VM lock.
+	 */
+	const enum cl_page_state cp_state;
+	/** Linkage of pages within group. Protected by cl_page::cp_mutex. */
+	struct list_head		cp_batch;
+	/** Mutex serializing membership of a page in a batch. */
+	struct mutex		cp_mutex;
+	/** Linkage of pages within cl_req. */
+	struct list_head	       cp_flight;
+	/** Transfer error. */
+	int		      cp_error;
+
+	/**
+	 * Page type. Only CPT_TRANSIENT is used so far. Immutable after
+	 * creation.
+	 */
+	enum cl_page_type	cp_type;
+
+	/**
+	 * Owning IO in cl_page_state::CPS_OWNED state. Sub-page can be owned
+	 * by sub-io. Protected by a VM lock.
+	 */
+	struct cl_io	    *cp_owner;
+	/**
+	 * Debug information, the task is owning the page.
+	 */
+	task_t	      *cp_task;
+	/**
+	 * Owning IO request in cl_page_state::CPS_PAGEOUT and
+	 * cl_page_state::CPS_PAGEIN states. This field is maintained only in
+	 * the top-level pages. Protected by a VM lock.
+	 */
+	struct cl_req	   *cp_req;
+	/** List of references to this page, for debugging. */
+	struct lu_ref	    cp_reference;
+	/** Link to an object, for debugging. */
+	struct lu_ref_link      *cp_obj_ref;
+	/** Link to a queue, for debugging. */
+	struct lu_ref_link      *cp_queue_ref;
+	/** Per-page flags from enum cl_page_flags. Protected by a VM lock. */
+	unsigned		 cp_flags;
+	/** Assigned if doing a sync_io */
+	struct cl_sync_io       *cp_sync_io;
+};
+
+/**
+ * Per-layer part of cl_page.
+ *
+ * \see ccc_page, lov_page, osc_page
+ */
+struct cl_page_slice {
+	struct cl_page		  *cpl_page;
+	/**
+	 * Object slice corresponding to this page slice. Immutable after
+	 * creation.
+	 */
+	struct cl_object		*cpl_obj;
+	const struct cl_page_operations *cpl_ops;
+	/** Linkage into cl_page::cp_layers. Immutable after creation. */
+	struct list_head		       cpl_linkage;
+};
+
+/**
+ * Lock mode. For the client extent locks.
+ *
+ * \warning: cl_lock_mode_match() assumes particular ordering here.
+ * \ingroup cl_lock
+ */
+enum cl_lock_mode {
+	/**
+	 * Mode of a lock that protects no data, and exists only as a
+	 * placeholder. This is used for `glimpse' requests. A phantom lock
+	 * might get promoted to real lock at some point.
+	 */
+	CLM_PHANTOM,
+	CLM_READ,
+	CLM_WRITE,
+	CLM_GROUP
+};
+
+/**
+ * Requested transfer type.
+ * \ingroup cl_req
+ */
+enum cl_req_type {
+	CRT_READ,
+	CRT_WRITE,
+	CRT_NR
+};
+
+/**
+ * Per-layer page operations.
+ *
+ * Methods taking an \a io argument are for the activity happening in the
+ * context of given \a io. Page is assumed to be owned by that io, except for
+ * the obvious cases (like cl_page_operations::cpo_own()).
+ *
+ * \see vvp_page_ops, lov_page_ops, osc_page_ops
+ */
+struct cl_page_operations {
+	/**
+	 * cl_page<->struct page methods. Only one layer in the stack has to
+	 * implement these. Current code assumes that this functionality is
+	 * provided by the topmost layer, see cl_page_disown0() as an example.
+	 */
+
+	/**
+	 * \return the underlying VM page. Optional.
+	 */
+	struct page *(*cpo_vmpage)(const struct lu_env *env,
+				  const struct cl_page_slice *slice);
+	/**
+	 * Called when \a io acquires this page into the exclusive
+	 * ownership. When this method returns, it is guaranteed that the is
+	 * not owned by other io, and no transfer is going on against
+	 * it. Optional.
+	 *
+	 * \see cl_page_own()
+	 * \see vvp_page_own(), lov_page_own()
+	 */
+	int  (*cpo_own)(const struct lu_env *env,
+			const struct cl_page_slice *slice,
+			struct cl_io *io, int nonblock);
+	/** Called when ownership it yielded. Optional.
+	 *
+	 * \see cl_page_disown()
+	 * \see vvp_page_disown()
+	 */
+	void (*cpo_disown)(const struct lu_env *env,
+			   const struct cl_page_slice *slice, struct cl_io *io);
+	/**
+	 * Called for a page that is already "owned" by \a io from VM point of
+	 * view. Optional.
+	 *
+	 * \see cl_page_assume()
+	 * \see vvp_page_assume(), lov_page_assume()
+	 */
+	void (*cpo_assume)(const struct lu_env *env,
+			   const struct cl_page_slice *slice, struct cl_io *io);
+	/** Dual to cl_page_operations::cpo_assume(). Optional. Called
+	 * bottom-to-top when IO releases a page without actually unlocking
+	 * it.
+	 *
+	 * \see cl_page_unassume()
+	 * \see vvp_page_unassume()
+	 */
+	void (*cpo_unassume)(const struct lu_env *env,
+			     const struct cl_page_slice *slice,
+			     struct cl_io *io);
+	/**
+	 * Announces whether the page contains valid data or not by \a uptodate.
+	 *
+	 * \see cl_page_export()
+	 * \see vvp_page_export()
+	 */
+	void  (*cpo_export)(const struct lu_env *env,
+			    const struct cl_page_slice *slice, int uptodate);
+	/**
+	 * Unmaps page from the user space (if it is mapped).
+	 *
+	 * \see cl_page_unmap()
+	 * \see vvp_page_unmap()
+	 */
+	int (*cpo_unmap)(const struct lu_env *env,
+			 const struct cl_page_slice *slice, struct cl_io *io);
+	/**
+	 * Checks whether underlying VM page is locked (in the suitable
+	 * sense). Used for assertions.
+	 *
+	 * \retval    -EBUSY: page is protected by a lock of a given mode;
+	 * \retval  -ENODATA: page is not protected by a lock;
+	 * \retval	 0: this layer cannot decide. (Should never happen.)
+	 */
+	int (*cpo_is_vmlocked)(const struct lu_env *env,
+			       const struct cl_page_slice *slice);
+	/**
+	 * Page destruction.
+	 */
+
+	/**
+	 * Called when page is truncated from the object. Optional.
+	 *
+	 * \see cl_page_discard()
+	 * \see vvp_page_discard(), osc_page_discard()
+	 */
+	void (*cpo_discard)(const struct lu_env *env,
+			    const struct cl_page_slice *slice,
+			    struct cl_io *io);
+	/**
+	 * Called when page is removed from the cache, and is about to being
+	 * destroyed. Optional.
+	 *
+	 * \see cl_page_delete()
+	 * \see vvp_page_delete(), osc_page_delete()
+	 */
+	void (*cpo_delete)(const struct lu_env *env,
+			   const struct cl_page_slice *slice);
+	/** Destructor. Frees resources and slice itself. */
+	void (*cpo_fini)(const struct lu_env *env,
+			 struct cl_page_slice *slice);
+
+	/**
+	 * Checks whether the page is protected by a cl_lock. This is a
+	 * per-layer method, because certain layers have ways to check for the
+	 * lock much more efficiently than through the generic locks scan, or
+	 * implement locking mechanisms separate from cl_lock, e.g.,
+	 * LL_FILE_GROUP_LOCKED in vvp. If \a pending is true, check for locks
+	 * being canceled, or scheduled for cancellation as soon as the last
+	 * user goes away, too.
+	 *
+	 * \retval    -EBUSY: page is protected by a lock of a given mode;
+	 * \retval  -ENODATA: page is not protected by a lock;
+	 * \retval	 0: this layer cannot decide.
+	 *
+	 * \see cl_page_is_under_lock()
+	 */
+	int (*cpo_is_under_lock)(const struct lu_env *env,
+				 const struct cl_page_slice *slice,
+				 struct cl_io *io);
+
+	/**
+	 * Optional debugging helper. Prints given page slice.
+	 *
+	 * \see cl_page_print()
+	 */
+	int (*cpo_print)(const struct lu_env *env,
+			 const struct cl_page_slice *slice,
+			 void *cookie, lu_printer_t p);
+	/**
+	 * \name transfer
+	 *
+	 * Transfer methods. See comment on cl_req for a description of
+	 * transfer formation and life-cycle.
+	 *
+	 * @{
+	 */
+	/**
+	 * Request type dependent vector of operations.
+	 *
+	 * Transfer operations depend on transfer mode (cl_req_type). To avoid
+	 * passing transfer mode to each and every of these methods, and to
+	 * avoid branching on request type inside of the methods, separate
+	 * methods for cl_req_type:CRT_READ and cl_req_type:CRT_WRITE are
+	 * provided. That is, method invocation usually looks like
+	 *
+	 *	 slice->cp_ops.io[req->crq_type].cpo_method(env, slice, ...);
+	 */
+	struct {
+		/**
+		 * Called when a page is submitted for a transfer as a part of
+		 * cl_page_list.
+		 *
+		 * \return    0	 : page is eligible for submission;
+		 * \return    -EALREADY : skip this page;
+		 * \return    -ve       : error.
+		 *
+		 * \see cl_page_prep()
+		 */
+		int  (*cpo_prep)(const struct lu_env *env,
+				 const struct cl_page_slice *slice,
+				 struct cl_io *io);
+		/**
+		 * Completion handler. This is guaranteed to be eventually
+		 * fired after cl_page_operations::cpo_prep() or
+		 * cl_page_operations::cpo_make_ready() call.
+		 *
+		 * This method can be called in a non-blocking context. It is
+		 * guaranteed however, that the page involved and its object
+		 * are pinned in memory (and, hence, calling cl_page_put() is
+		 * safe).
+		 *
+		 * \see cl_page_completion()
+		 */
+		void (*cpo_completion)(const struct lu_env *env,
+				       const struct cl_page_slice *slice,
+				       int ioret);
+		/**
+		 * Called when cached page is about to be added to the
+		 * cl_req as a part of req formation.
+		 *
+		 * \return    0       : proceed with this page;
+		 * \return    -EAGAIN : skip this page;
+		 * \return    -ve     : error.
+		 *
+		 * \see cl_page_make_ready()
+		 */
+		int  (*cpo_make_ready)(const struct lu_env *env,
+				       const struct cl_page_slice *slice);
+		/**
+		 * Announce that this page is to be written out
+		 * opportunistically, that is, page is dirty, it is not
+		 * necessary to start write-out transfer right now, but
+		 * eventually page has to be written out.
+		 *
+		 * Main caller of this is the write path (see
+		 * vvp_io_commit_write()), using this method to build a
+		 * "transfer cache" from which large transfers are then
+		 * constructed by the req-formation engine.
+		 *
+		 * \todo XXX it would make sense to add page-age tracking
+		 * semantics here, and to oblige the req-formation engine to
+		 * send the page out not later than it is too old.
+		 *
+		 * \see cl_page_cache_add()
+		 */
+		int  (*cpo_cache_add)(const struct lu_env *env,
+				      const struct cl_page_slice *slice,
+				      struct cl_io *io);
+	} io[CRT_NR];
+	/**
+	 * Tell transfer engine that only [to, from] part of a page should be
+	 * transmitted.
+	 *
+	 * This is used for immediate transfers.
+	 *
+	 * \todo XXX this is not very good interface. It would be much better
+	 * if all transfer parameters were supplied as arguments to
+	 * cl_io_operations::cio_submit() call, but it is not clear how to do
+	 * this for page queues.
+	 *
+	 * \see cl_page_clip()
+	 */
+	void (*cpo_clip)(const struct lu_env *env,
+			 const struct cl_page_slice *slice,
+			 int from, int to);
+	/**
+	 * \pre  the page was queued for transferring.
+	 * \post page is removed from client's pending list, or -EBUSY
+	 *       is returned if it has already been in transferring.
+	 *
+	 * This is one of seldom page operation which is:
+	 * 0. called from top level;
+	 * 1. don't have vmpage locked;
+	 * 2. every layer should synchronize execution of its ->cpo_cancel()
+	 *    with completion handlers. Osc uses client obd lock for this
+	 *    purpose. Based on there is no vvp_page_cancel and
+	 *    lov_page_cancel(), cpo_cancel is defacto protected by client lock.
+	 *
+	 * \see osc_page_cancel().
+	 */
+	int (*cpo_cancel)(const struct lu_env *env,
+			  const struct cl_page_slice *slice);
+	/**
+	 * Write out a page by kernel. This is only called by ll_writepage
+	 * right now.
+	 *
+	 * \see cl_page_flush()
+	 */
+	int (*cpo_flush)(const struct lu_env *env,
+			 const struct cl_page_slice *slice,
+			 struct cl_io *io);
+	/** @} transfer */
+};
+
+/**
+ * Helper macro, dumping detailed information about \a page into a log.
+ */
+#define CL_PAGE_DEBUG(mask, env, page, format, ...)		     \
+do {								    \
+	LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL);		\
+									\
+	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {		   \
+		cl_page_print(env, &msgdata, lu_cdebug_printer, page);  \
+		CDEBUG(mask, format , ## __VA_ARGS__);		  \
+	}							       \
+} while (0)
+
+/**
+ * Helper macro, dumping shorter information about \a page into a log.
+ */
+#define CL_PAGE_HEADER(mask, env, page, format, ...)			  \
+do {									  \
+	LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL);		      \
+									      \
+	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {			 \
+		cl_page_header_print(env, &msgdata, lu_cdebug_printer, page); \
+		CDEBUG(mask, format , ## __VA_ARGS__);			\
+	}								     \
+} while (0)
+
+static inline int __page_in_use(const struct cl_page *page, int refc)
+{
+	if (page->cp_type == CPT_CACHEABLE)
+		++refc;
+	LASSERT(atomic_read(&page->cp_ref) > 0);
+	return (atomic_read(&page->cp_ref) > refc);
+}
+#define cl_page_in_use(pg)       __page_in_use(pg, 1)
+#define cl_page_in_use_noref(pg) __page_in_use(pg, 0)
+
+/** @} cl_page */
+
+/** \addtogroup cl_lock cl_lock
+ * @{ */
+/** \struct cl_lock
+ *
+ * Extent locking on the client.
+ *
+ * LAYERING
+ *
+ * The locking model of the new client code is built around
+ *
+ *	struct cl_lock
+ *
+ * data-type representing an extent lock on a regular file. cl_lock is a
+ * layered object (much like cl_object and cl_page), it consists of a header
+ * (struct cl_lock) and a list of layers (struct cl_lock_slice), linked to
+ * cl_lock::cll_layers list through cl_lock_slice::cls_linkage.
+ *
+ * All locks for a given object are linked into cl_object_header::coh_locks
+ * list (protected by cl_object_header::coh_lock_guard spin-lock) through
+ * cl_lock::cll_linkage. Currently this list is not sorted in any way. We can
+ * sort it in starting lock offset, or use altogether different data structure
+ * like a tree.
+ *
+ * Typical cl_lock consists of the two layers:
+ *
+ *     - vvp_lock (vvp specific data), and
+ *     - lov_lock (lov specific data).
+ *
+ * lov_lock contains an array of sub-locks. Each of these sub-locks is a
+ * normal cl_lock: it has a header (struct cl_lock) and a list of layers:
+ *
+ *     - lovsub_lock, and
+ *     - osc_lock
+ *
+ * Each sub-lock is associated with a cl_object (representing stripe
+ * sub-object or the file to which top-level cl_lock is associated to), and is
+ * linked into that cl_object::coh_locks. In this respect cl_lock is similar to
+ * cl_object (that at lov layer also fans out into multiple sub-objects), and
+ * is different from cl_page, that doesn't fan out (there is usually exactly
+ * one osc_page for every vvp_page). We shall call vvp-lov portion of the lock
+ * a "top-lock" and its lovsub-osc portion a "sub-lock".
+ *
+ * LIFE CYCLE
+ *
+ * cl_lock is reference counted. When reference counter drops to 0, lock is
+ * placed in the cache, except when lock is in CLS_FREEING state. CLS_FREEING
+ * lock is destroyed when last reference is released. Referencing between
+ * top-lock and its sub-locks is described in the lov documentation module.
+ *
+ * STATE MACHINE
+ *
+ * Also, cl_lock is a state machine. This requires some clarification. One of
+ * the goals of client IO re-write was to make IO path non-blocking, or at
+ * least to make it easier to make it non-blocking in the future. Here
+ * `non-blocking' means that when a system call (read, write, truncate)
+ * reaches a situation where it has to wait for a communication with the
+ * server, it should --instead of waiting-- remember its current state and
+ * switch to some other work.  E.g,. instead of waiting for a lock enqueue,
+ * client should proceed doing IO on the next stripe, etc. Obviously this is
+ * rather radical redesign, and it is not planned to be fully implemented at
+ * this time, instead we are putting some infrastructure in place, that would
+ * make it easier to do asynchronous non-blocking IO easier in the
+ * future. Specifically, where old locking code goes to sleep (waiting for
+ * enqueue, for example), new code returns cl_lock_transition::CLO_WAIT. When
+ * enqueue reply comes, its completion handler signals that lock state-machine
+ * is ready to transit to the next state. There is some generic code in
+ * cl_lock.c that sleeps, waiting for these signals. As a result, for users of
+ * this cl_lock.c code, it looks like locking is done in normal blocking
+ * fashion, and it the same time it is possible to switch to the non-blocking
+ * locking (simply by returning cl_lock_transition::CLO_WAIT from cl_lock.c
+ * functions).
+ *
+ * For a description of state machine states and transitions see enum
+ * cl_lock_state.
+ *
+ * There are two ways to restrict a set of states which lock might move to:
+ *
+ *     - placing a "hold" on a lock guarantees that lock will not be moved
+ *       into cl_lock_state::CLS_FREEING state until hold is released. Hold
+ *       can be only acquired on a lock that is not in
+ *       cl_lock_state::CLS_FREEING. All holds on a lock are counted in
+ *       cl_lock::cll_holds. Hold protects lock from cancellation and
+ *       destruction. Requests to cancel and destroy a lock on hold will be
+ *       recorded, but only honored when last hold on a lock is released;
+ *
+ *     - placing a "user" on a lock guarantees that lock will not leave
+ *       cl_lock_state::CLS_NEW, cl_lock_state::CLS_QUEUING,
+ *       cl_lock_state::CLS_ENQUEUED and cl_lock_state::CLS_HELD set of
+ *       states, once it enters this set. That is, if a user is added onto a
+ *       lock in a state not from this set, it doesn't immediately enforce
+ *       lock to move to this set, but once lock enters this set it will
+ *       remain there until all users are removed. Lock users are counted in
+ *       cl_lock::cll_users.
+ *
+ *       User is used to assure that lock is not canceled or destroyed while
+ *       it is being enqueued, or actively used by some IO.
+ *
+ *       Currently, a user always comes with a hold (cl_lock_invariant()
+ *       checks that a number of holds is not less than a number of users).
+ *
+ * CONCURRENCY
+ *
+ * This is how lock state-machine operates. struct cl_lock contains a mutex
+ * cl_lock::cll_guard that protects struct fields.
+ *
+ *     - mutex is taken, and cl_lock::cll_state is examined.
+ *
+ *     - for every state there are possible target states where lock can move
+ *       into. They are tried in order. Attempts to move into next state are
+ *       done by _try() functions in cl_lock.c:cl_{enqueue,unlock,wait}_try().
+ *
+ *     - if the transition can be performed immediately, state is changed,
+ *       and mutex is released.
+ *
+ *     - if the transition requires blocking, _try() function returns
+ *       cl_lock_transition::CLO_WAIT. Caller unlocks mutex and goes to
+ *       sleep, waiting for possibility of lock state change. It is woken
+ *       up when some event occurs, that makes lock state change possible
+ *       (e.g., the reception of the reply from the server), and repeats
+ *       the loop.
+ *
+ * Top-lock and sub-lock has separate mutexes and the latter has to be taken
+ * first to avoid dead-lock.
+ *
+ * To see an example of interaction of all these issues, take a look at the
+ * lov_cl.c:lov_lock_enqueue() function. It is called as a part of
+ * cl_enqueue_try(), and tries to advance top-lock to ENQUEUED state, by
+ * advancing state-machines of its sub-locks (lov_lock_enqueue_one()). Note
+ * also, that it uses trylock to grab sub-lock mutex to avoid dead-lock. It
+ * also has to handle CEF_ASYNC enqueue, when sub-locks enqueues have to be
+ * done in parallel, rather than one after another (this is used for glimpse
+ * locks, that cannot dead-lock).
+ *
+ * INTERFACE AND USAGE
+ *
+ * struct cl_lock_operations provide a number of call-backs that are invoked
+ * when events of interest occurs. Layers can intercept and handle glimpse,
+ * blocking, cancel ASTs and a reception of the reply from the server.
+ *
+ * One important difference with the old client locking model is that new
+ * client has a representation for the top-lock, whereas in the old code only
+ * sub-locks existed as real data structures and file-level locks are
+ * represented by "request sets" that are created and destroyed on each and
+ * every lock creation.
+ *
+ * Top-locks are cached, and can be found in the cache by the system calls. It
+ * is possible that top-lock is in cache, but some of its sub-locks were
+ * canceled and destroyed. In that case top-lock has to be enqueued again
+ * before it can be used.
+ *
+ * Overall process of the locking during IO operation is as following:
+ *
+ *     - once parameters for IO are setup in cl_io, cl_io_operations::cio_lock()
+ *       is called on each layer. Responsibility of this method is to add locks,
+ *       needed by a given layer into cl_io.ci_lockset.
+ *
+ *     - once locks for all layers were collected, they are sorted to avoid
+ *       dead-locks (cl_io_locks_sort()), and enqueued.
+ *
+ *     - when all locks are acquired, IO is performed;
+ *
+ *     - locks are released into cache.
+ *
+ * Striping introduces major additional complexity into locking. The
+ * fundamental problem is that it is generally unsafe to actively use (hold)
+ * two locks on the different OST servers at the same time, as this introduces
+ * inter-server dependency and can lead to cascading evictions.
+ *
+ * Basic solution is to sub-divide large read/write IOs into smaller pieces so
+ * that no multi-stripe locks are taken (note that this design abandons POSIX
+ * read/write semantics). Such pieces ideally can be executed concurrently. At
+ * the same time, certain types of IO cannot be sub-divived, without
+ * sacrificing correctness. This includes:
+ *
+ *  - O_APPEND write, where [0, EOF] lock has to be taken, to guarantee
+ *  atomicity;
+ *
+ *  - ftruncate(fd, offset), where [offset, EOF] lock has to be taken.
+ *
+ * Also, in the case of read(fd, buf, count) or write(fd, buf, count), where
+ * buf is a part of memory mapped Lustre file, a lock or locks protecting buf
+ * has to be held together with the usual lock on [offset, offset + count].
+ *
+ * As multi-stripe locks have to be allowed, it makes sense to cache them, so
+ * that, for example, a sequence of O_APPEND writes can proceed quickly
+ * without going down to the individual stripes to do lock matching. On the
+ * other hand, multi-stripe locks shouldn't be used by normal read/write
+ * calls. To achieve this, every layer can implement ->clo_fits_into() method,
+ * that is called by lock matching code (cl_lock_lookup()), and that can be
+ * used to selectively disable matching of certain locks for certain IOs. For
+ * exmaple, lov layer implements lov_lock_fits_into() that allow multi-stripe
+ * locks to be matched only for truncates and O_APPEND writes.
+ *
+ * Interaction with DLM
+ *
+ * In the expected setup, cl_lock is ultimately backed up by a collection of
+ * DLM locks (struct ldlm_lock). Association between cl_lock and DLM lock is
+ * implemented in osc layer, that also matches DLM events (ASTs, cancellation,
+ * etc.) into cl_lock_operation calls. See struct osc_lock for a more detailed
+ * description of interaction with DLM.
+ */
+
+/**
+ * Lock description.
+ */
+struct cl_lock_descr {
+	/** Object this lock is granted for. */
+	struct cl_object *cld_obj;
+	/** Index of the first page protected by this lock. */
+	pgoff_t	   cld_start;
+	/** Index of the last page (inclusive) protected by this lock. */
+	pgoff_t	   cld_end;
+	/** Group ID, for group lock */
+	__u64	     cld_gid;
+	/** Lock mode. */
+	enum cl_lock_mode cld_mode;
+	/**
+	 * flags to enqueue lock. A combination of bit-flags from
+	 * enum cl_enq_flags.
+	 */
+	__u32	     cld_enq_flags;
+};
+
+#define DDESCR "%s(%d):[%lu, %lu]"
+#define PDESCR(descr)						   \
+	cl_lock_mode_name((descr)->cld_mode), (descr)->cld_mode,	\
+	(descr)->cld_start, (descr)->cld_end
+
+const char *cl_lock_mode_name(const enum cl_lock_mode mode);
+
+/**
+ * Lock state-machine states.
+ *
+ * \htmlonly
+ * <pre>
+ *
+ * Possible state transitions:
+ *
+ *	      +------------------>NEW
+ *	      |		    |
+ *	      |		    | cl_enqueue_try()
+ *	      |		    |
+ *	      |    cl_unuse_try()  V
+ *	      |  +--------------QUEUING (*)
+ *	      |  |		 |
+ *	      |  |		 | cl_enqueue_try()
+ *	      |  |		 |
+ *	      |  | cl_unuse_try()  V
+ *    sub-lock  |  +-------------ENQUEUED (*)
+ *    canceled  |  |		 |
+ *	      |  |		 | cl_wait_try()
+ *	      |  |		 |
+ *	      |  |		(R)
+ *	      |  |		 |
+ *	      |  |		 V
+ *	      |  |		HELD<---------+
+ *	      |  |		 |	    |
+ *	      |  |		 |	    | cl_use_try()
+ *	      |  |  cl_unuse_try() |	    |
+ *	      |  |		 |	    |
+ *	      |  |		 V	 ---+
+ *	      |  +------------>INTRANSIT (D) <--+
+ *	      |		    |	    |
+ *	      |     cl_unuse_try() |	    | cached lock found
+ *	      |		    |	    | cl_use_try()
+ *	      |		    |	    |
+ *	      |		    V	    |
+ *	      +------------------CACHED---------+
+ *				   |
+ *				  (C)
+ *				   |
+ *				   V
+ *				FREEING
+ *
+ * Legend:
+ *
+ *	 In states marked with (*) transition to the same state (i.e., a loop
+ *	 in the diagram) is possible.
+ *
+ *	 (R) is the point where Receive call-back is invoked: it allows layers
+ *	 to handle arrival of lock reply.
+ *
+ *	 (C) is the point where Cancellation call-back is invoked.
+ *
+ *	 (D) is the transit state which means the lock is changing.
+ *
+ *	 Transition to FREEING state is possible from any other state in the
+ *	 diagram in case of unrecoverable error.
+ * </pre>
+ * \endhtmlonly
+ *
+ * These states are for individual cl_lock object. Top-lock and its sub-locks
+ * can be in the different states. Another way to say this is that we have
+ * nested state-machines.
+ *
+ * Separate QUEUING and ENQUEUED states are needed to support non-blocking
+ * operation for locks with multiple sub-locks. Imagine lock on a file F, that
+ * intersects 3 stripes S0, S1, and S2. To enqueue F client has to send
+ * enqueue to S0, wait for its completion, then send enqueue for S1, wait for
+ * its completion and at last enqueue lock for S2, and wait for its
+ * completion. In that case, top-lock is in QUEUING state while S0, S1 are
+ * handled, and is in ENQUEUED state after enqueue to S2 has been sent (note
+ * that in this case, sub-locks move from state to state, and top-lock remains
+ * in the same state).
+ */
+enum cl_lock_state {
+	/**
+	 * Lock that wasn't yet enqueued
+	 */
+	CLS_NEW,
+	/**
+	 * Enqueue is in progress, blocking for some intermediate interaction
+	 * with the other side.
+	 */
+	CLS_QUEUING,
+	/**
+	 * Lock is fully enqueued, waiting for server to reply when it is
+	 * granted.
+	 */
+	CLS_ENQUEUED,
+	/**
+	 * Lock granted, actively used by some IO.
+	 */
+	CLS_HELD,
+	/**
+	 * This state is used to mark the lock is being used, or unused.
+	 * We need this state because the lock may have several sublocks,
+	 * so it's impossible to have an atomic way to bring all sublocks
+	 * into CLS_HELD state at use case, or all sublocks to CLS_CACHED
+	 * at unuse case.
+	 * If a thread is referring to a lock, and it sees the lock is in this
+	 * state, it must wait for the lock.
+	 * See state diagram for details.
+	 */
+	CLS_INTRANSIT,
+	/**
+	 * Lock granted, not used.
+	 */
+	CLS_CACHED,
+	/**
+	 * Lock is being destroyed.
+	 */
+	CLS_FREEING,
+	CLS_NR
+};
+
+enum cl_lock_flags {
+	/**
+	 * lock has been cancelled. This flag is never cleared once set (by
+	 * cl_lock_cancel0()).
+	 */
+	CLF_CANCELLED  = 1 << 0,
+	/** cancellation is pending for this lock. */
+	CLF_CANCELPEND = 1 << 1,
+	/** destruction is pending for this lock. */
+	CLF_DOOMED     = 1 << 2,
+	/** from enqueue RPC reply upcall. */
+	CLF_FROM_UPCALL= 1 << 3,
+};
+
+/**
+ * Lock closure.
+ *
+ * Lock closure is a collection of locks (both top-locks and sub-locks) that
+ * might be updated in a result of an operation on a certain lock (which lock
+ * this is a closure of).
+ *
+ * Closures are needed to guarantee dead-lock freedom in the presence of
+ *
+ *     - nested state-machines (top-lock state-machine composed of sub-lock
+ *       state-machines), and
+ *
+ *     - shared sub-locks.
+ *
+ * Specifically, many operations, such as lock enqueue, wait, unlock,
+ * etc. start from a top-lock, and then operate on a sub-locks of this
+ * top-lock, holding a top-lock mutex. When sub-lock state changes as a result
+ * of such operation, this change has to be propagated to all top-locks that
+ * share this sub-lock. Obviously, no natural lock ordering (e.g.,
+ * top-to-bottom or bottom-to-top) captures this scenario, so try-locking has
+ * to be used. Lock closure systematizes this try-and-repeat logic.
+ */
+struct cl_lock_closure {
+	/**
+	 * Lock that is mutexed when closure construction is started. When
+	 * closure in is `wait' mode (cl_lock_closure::clc_wait), mutex on
+	 * origin is released before waiting.
+	 */
+	struct cl_lock   *clc_origin;
+	/**
+	 * List of enclosed locks, so far. Locks are linked here through
+	 * cl_lock::cll_inclosure.
+	 */
+	struct list_head	clc_list;
+	/**
+	 * True iff closure is in a `wait' mode. This determines what
+	 * cl_lock_enclosure() does when a lock L to be added to the closure
+	 * is currently mutexed by some other thread.
+	 *
+	 * If cl_lock_closure::clc_wait is not set, then closure construction
+	 * fails with CLO_REPEAT immediately.
+	 *
+	 * In wait mode, cl_lock_enclosure() waits until next attempt to build
+	 * a closure might succeed. To this end it releases an origin mutex
+	 * (cl_lock_closure::clc_origin), that has to be the only lock mutex
+	 * owned by the current thread, and then waits on L mutex (by grabbing
+	 * it and immediately releasing), before returning CLO_REPEAT to the
+	 * caller.
+	 */
+	int	       clc_wait;
+	/** Number of locks in the closure. */
+	int	       clc_nr;
+};
+
+/**
+ * Layered client lock.
+ */
+struct cl_lock {
+	/** Reference counter. */
+	atomic_t	  cll_ref;
+	/** List of slices. Immutable after creation. */
+	struct list_head	    cll_layers;
+	/**
+	 * Linkage into cl_lock::cll_descr::cld_obj::coh_locks list. Protected
+	 * by cl_lock::cll_descr::cld_obj::coh_lock_guard.
+	 */
+	struct list_head	    cll_linkage;
+	/**
+	 * Parameters of this lock. Protected by
+	 * cl_lock::cll_descr::cld_obj::coh_lock_guard nested within
+	 * cl_lock::cll_guard. Modified only on lock creation and in
+	 * cl_lock_modify().
+	 */
+	struct cl_lock_descr  cll_descr;
+	/** Protected by cl_lock::cll_guard. */
+	enum cl_lock_state    cll_state;
+	/** signals state changes. */
+	wait_queue_head_t	   cll_wq;
+	/**
+	 * Recursive lock, most fields in cl_lock{} are protected by this.
+	 *
+	 * Locking rules: this mutex is never held across network
+	 * communication, except when lock is being canceled.
+	 *
+	 * Lock ordering: a mutex of a sub-lock is taken first, then a mutex
+	 * on a top-lock. Other direction is implemented through a
+	 * try-lock-repeat loop. Mutices of unrelated locks can be taken only
+	 * by try-locking.
+	 *
+	 * \see osc_lock_enqueue_wait(), lov_lock_cancel(), lov_sublock_wait().
+	 */
+	struct mutex		cll_guard;
+	task_t	   *cll_guarder;
+	int		   cll_depth;
+
+	/**
+	 * the owner for INTRANSIT state
+	 */
+	task_t	   *cll_intransit_owner;
+	int		   cll_error;
+	/**
+	 * Number of holds on a lock. A hold prevents a lock from being
+	 * canceled and destroyed. Protected by cl_lock::cll_guard.
+	 *
+	 * \see cl_lock_hold(), cl_lock_unhold(), cl_lock_release()
+	 */
+	int		   cll_holds;
+	 /**
+	  * Number of lock users. Valid in cl_lock_state::CLS_HELD state
+	  * only. Lock user pins lock in CLS_HELD state. Protected by
+	  * cl_lock::cll_guard.
+	  *
+	  * \see cl_wait(), cl_unuse().
+	  */
+	int		   cll_users;
+	/**
+	 * Flag bit-mask. Values from enum cl_lock_flags. Updates are
+	 * protected by cl_lock::cll_guard.
+	 */
+	unsigned long	 cll_flags;
+	/**
+	 * A linkage into a list of locks in a closure.
+	 *
+	 * \see cl_lock_closure
+	 */
+	struct list_head	    cll_inclosure;
+	/**
+	 * Confict lock at queuing time.
+	 */
+	struct cl_lock       *cll_conflict;
+	/**
+	 * A list of references to this lock, for debugging.
+	 */
+	struct lu_ref	 cll_reference;
+	/**
+	 * A list of holds on this lock, for debugging.
+	 */
+	struct lu_ref	 cll_holders;
+	/**
+	 * A reference for cl_lock::cll_descr::cld_obj. For debugging.
+	 */
+	struct lu_ref_link   *cll_obj_ref;
+#ifdef CONFIG_LOCKDEP
+	/* "dep_map" name is assumed by lockdep.h macros. */
+	struct lockdep_map    dep_map;
+#endif
+};
+
+/**
+ * Per-layer part of cl_lock
+ *
+ * \see ccc_lock, lov_lock, lovsub_lock, osc_lock
+ */
+struct cl_lock_slice {
+	struct cl_lock		  *cls_lock;
+	/** Object slice corresponding to this lock slice. Immutable after
+	 * creation. */
+	struct cl_object		*cls_obj;
+	const struct cl_lock_operations *cls_ops;
+	/** Linkage into cl_lock::cll_layers. Immutable after creation. */
+	struct list_head		       cls_linkage;
+};
+
+/**
+ * Possible (non-error) return values of ->clo_{enqueue,wait,unlock}().
+ *
+ * NOTE: lov_subresult() depends on ordering here.
+ */
+enum cl_lock_transition {
+	/** operation cannot be completed immediately. Wait for state change. */
+	CLO_WAIT	= 1,
+	/** operation had to release lock mutex, restart. */
+	CLO_REPEAT      = 2,
+	/** lower layer re-enqueued. */
+	CLO_REENQUEUED  = 3,
+};
+
+/**
+ *
+ * \see vvp_lock_ops, lov_lock_ops, lovsub_lock_ops, osc_lock_ops
+ */
+struct cl_lock_operations {
+	/**
+	 * \name statemachine
+	 *
+	 * State machine transitions. These 3 methods are called to transfer
+	 * lock from one state to another, as described in the commentary
+	 * above enum #cl_lock_state.
+	 *
+	 * \retval 0	  this layer has nothing more to do to before
+	 *		       transition to the target state happens;
+	 *
+	 * \retval CLO_REPEAT method had to release and re-acquire cl_lock
+	 *		    mutex, repeat invocation of transition method
+	 *		    across all layers;
+	 *
+	 * \retval CLO_WAIT   this layer cannot move to the target state
+	 *		    immediately, as it has to wait for certain event
+	 *		    (e.g., the communication with the server). It
+	 *		    is guaranteed, that when the state transfer
+	 *		    becomes possible, cl_lock::cll_wq wait-queue
+	 *		    is signaled. Caller can wait for this event by
+	 *		    calling cl_lock_state_wait();
+	 *
+	 * \retval -ve	failure, abort state transition, move the lock
+	 *		    into cl_lock_state::CLS_FREEING state, and set
+	 *		    cl_lock::cll_error.
+	 *
+	 * Once all layers voted to agree to transition (by returning 0), lock
+	 * is moved into corresponding target state. All state transition
+	 * methods are optional.
+	 */
+	/** @{ */
+	/**
+	 * Attempts to enqueue the lock. Called top-to-bottom.
+	 *
+	 * \see ccc_lock_enqueue(), lov_lock_enqueue(), lovsub_lock_enqueue(),
+	 * \see osc_lock_enqueue()
+	 */
+	int  (*clo_enqueue)(const struct lu_env *env,
+			    const struct cl_lock_slice *slice,
+			    struct cl_io *io, __u32 enqflags);
+	/**
+	 * Attempts to wait for enqueue result. Called top-to-bottom.
+	 *
+	 * \see ccc_lock_wait(), lov_lock_wait(), osc_lock_wait()
+	 */
+	int  (*clo_wait)(const struct lu_env *env,
+			 const struct cl_lock_slice *slice);
+	/**
+	 * Attempts to unlock the lock. Called bottom-to-top. In addition to
+	 * usual return values of lock state-machine methods, this can return
+	 * -ESTALE to indicate that lock cannot be returned to the cache, and
+	 * has to be re-initialized.
+	 * unuse is a one-shot operation, so it must NOT return CLO_WAIT.
+	 *
+	 * \see ccc_lock_unuse(), lov_lock_unuse(), osc_lock_unuse()
+	 */
+	int  (*clo_unuse)(const struct lu_env *env,
+			  const struct cl_lock_slice *slice);
+	/**
+	 * Notifies layer that cached lock is started being used.
+	 *
+	 * \pre lock->cll_state == CLS_CACHED
+	 *
+	 * \see lov_lock_use(), osc_lock_use()
+	 */
+	int  (*clo_use)(const struct lu_env *env,
+			const struct cl_lock_slice *slice);
+	/** @} statemachine */
+	/**
+	 * A method invoked when lock state is changed (as a result of state
+	 * transition). This is used, for example, to track when the state of
+	 * a sub-lock changes, to propagate this change to the corresponding
+	 * top-lock. Optional
+	 *
+	 * \see lovsub_lock_state()
+	 */
+	void (*clo_state)(const struct lu_env *env,
+			  const struct cl_lock_slice *slice,
+			  enum cl_lock_state st);
+	/**
+	 * Returns true, iff given lock is suitable for the given io, idea
+	 * being, that there are certain "unsafe" locks, e.g., ones acquired
+	 * for O_APPEND writes, that we don't want to re-use for a normal
+	 * write, to avoid the danger of cascading evictions. Optional. Runs
+	 * under cl_object_header::coh_lock_guard.
+	 *
+	 * XXX this should take more information about lock needed by
+	 * io. Probably lock description or something similar.
+	 *
+	 * \see lov_fits_into()
+	 */
+	int (*clo_fits_into)(const struct lu_env *env,
+			     const struct cl_lock_slice *slice,
+			     const struct cl_lock_descr *need,
+			     const struct cl_io *io);
+	/**
+	 * \name ast
+	 * Asynchronous System Traps. All of then are optional, all are
+	 * executed bottom-to-top.
+	 */
+	/** @{ */
+
+	/**
+	 * Cancellation callback. Cancel a lock voluntarily, or under
+	 * the request of server.
+	 */
+	void (*clo_cancel)(const struct lu_env *env,
+			   const struct cl_lock_slice *slice);
+	/**
+	 * Lock weighting ast. Executed to estimate how precious this lock
+	 * is. The sum of results across all layers is used to determine
+	 * whether lock worth keeping in cache given present memory usage.
+	 *
+	 * \see osc_lock_weigh(), vvp_lock_weigh(), lovsub_lock_weigh().
+	 */
+	unsigned long (*clo_weigh)(const struct lu_env *env,
+				   const struct cl_lock_slice *slice);
+	/** @} ast */
+
+	/**
+	 * \see lovsub_lock_closure()
+	 */
+	int (*clo_closure)(const struct lu_env *env,
+			   const struct cl_lock_slice *slice,
+			   struct cl_lock_closure *closure);
+	/**
+	 * Executed bottom-to-top when lock description changes (e.g., as a
+	 * result of server granting more generous lock than was requested).
+	 *
+	 * \see lovsub_lock_modify()
+	 */
+	int (*clo_modify)(const struct lu_env *env,
+			  const struct cl_lock_slice *slice,
+			  const struct cl_lock_descr *updated);
+	/**
+	 * Notifies layers (bottom-to-top) that lock is going to be
+	 * destroyed. Responsibility of layers is to prevent new references on
+	 * this lock from being acquired once this method returns.
+	 *
+	 * This can be called multiple times due to the races.
+	 *
+	 * \see cl_lock_delete()
+	 * \see osc_lock_delete(), lovsub_lock_delete()
+	 */
+	void (*clo_delete)(const struct lu_env *env,
+			   const struct cl_lock_slice *slice);
+	/**
+	 * Destructor. Frees resources and the slice.
+	 *
+	 * \see ccc_lock_fini(), lov_lock_fini(), lovsub_lock_fini(),
+	 * \see osc_lock_fini()
+	 */
+	void (*clo_fini)(const struct lu_env *env, struct cl_lock_slice *slice);
+	/**
+	 * Optional debugging helper. Prints given lock slice.
+	 */
+	int (*clo_print)(const struct lu_env *env,
+			 void *cookie, lu_printer_t p,
+			 const struct cl_lock_slice *slice);
+};
+
+#define CL_LOCK_DEBUG(mask, env, lock, format, ...)		     \
+do {								    \
+	LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL);		\
+									\
+	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {		   \
+		cl_lock_print(env, &msgdata, lu_cdebug_printer, lock);  \
+		CDEBUG(mask, format , ## __VA_ARGS__);		  \
+	}							       \
+} while (0)
+
+#define CL_LOCK_ASSERT(expr, env, lock) do {			    \
+	if (likely(expr))					       \
+		break;						  \
+									\
+	CL_LOCK_DEBUG(D_ERROR, env, lock, "failed at %s.\n", #expr);    \
+	LBUG();							 \
+} while (0)
+
+/** @} cl_lock */
+
+/** \addtogroup cl_page_list cl_page_list
+ * Page list used to perform collective operations on a group of pages.
+ *
+ * Pages are added to the list one by one. cl_page_list acquires a reference
+ * for every page in it. Page list is used to perform collective operations on
+ * pages:
+ *
+ *     - submit pages for an immediate transfer,
+ *
+ *     - own pages on behalf of certain io (waiting for each page in turn),
+ *
+ *     - discard pages.
+ *
+ * When list is finalized, it releases references on all pages it still has.
+ *
+ * \todo XXX concurrency control.
+ *
+ * @{
+ */
+struct cl_page_list {
+	unsigned	     pl_nr;
+	struct list_head	   pl_pages;
+	task_t	  *pl_owner;
+};
+
+/**
+ * A 2-queue of pages. A convenience data-type for common use case, 2-queue
+ * contains an incoming page list and an outgoing page list.
+ */
+struct cl_2queue {
+	struct cl_page_list c2_qin;
+	struct cl_page_list c2_qout;
+};
+
+/** @} cl_page_list */
+
+/** \addtogroup cl_io cl_io
+ * @{ */
+/** \struct cl_io
+ * I/O
+ *
+ * cl_io represents a high level I/O activity like
+ * read(2)/write(2)/truncate(2) system call, or cancellation of an extent
+ * lock.
+ *
+ * cl_io is a layered object, much like cl_{object,page,lock} but with one
+ * important distinction. We want to minimize number of calls to the allocator
+ * in the fast path, e.g., in the case of read(2) when everything is cached:
+ * client already owns the lock over region being read, and data are cached
+ * due to read-ahead. To avoid allocation of cl_io layers in such situations,
+ * per-layer io state is stored in the session, associated with the io, see
+ * struct {vvp,lov,osc}_io for example. Sessions allocation is amortized
+ * by using free-lists, see cl_env_get().
+ *
+ * There is a small predefined number of possible io types, enumerated in enum
+ * cl_io_type.
+ *
+ * cl_io is a state machine, that can be advanced concurrently by the multiple
+ * threads. It is up to these threads to control the concurrency and,
+ * specifically, to detect when io is done, and its state can be safely
+ * released.
+ *
+ * For read/write io overall execution plan is as following:
+ *
+ *     (0) initialize io state through all layers;
+ *
+ *     (1) loop: prepare chunk of work to do
+ *
+ *     (2) call all layers to collect locks they need to process current chunk
+ *
+ *     (3) sort all locks to avoid dead-locks, and acquire them
+ *
+ *     (4) process the chunk: call per-page methods
+ *	 (cl_io_operations::cio_read_page() for read,
+ *	 cl_io_operations::cio_prepare_write(),
+ *	 cl_io_operations::cio_commit_write() for write)
+ *
+ *     (5) release locks
+ *
+ *     (6) repeat loop.
+ *
+ * To implement the "parallel IO mode", lov layer creates sub-io's (lazily to
+ * address allocation efficiency issues mentioned above), and returns with the
+ * special error condition from per-page method when current sub-io has to
+ * block. This causes io loop to be repeated, and lov switches to the next
+ * sub-io in its cl_io_operations::cio_iter_init() implementation.
+ */
+
+/** IO types */
+enum cl_io_type {
+	/** read system call */
+	CIT_READ,
+	/** write system call */
+	CIT_WRITE,
+	/** truncate, utime system calls */
+	CIT_SETATTR,
+	/**
+	 * page fault handling
+	 */
+	CIT_FAULT,
+	/**
+	 * fsync system call handling
+	 * To write out a range of file
+	 */
+	CIT_FSYNC,
+	/**
+	 * Miscellaneous io. This is used for occasional io activity that
+	 * doesn't fit into other types. Currently this is used for:
+	 *
+	 *     - cancellation of an extent lock. This io exists as a context
+	 *     to write dirty pages from under the lock being canceled back
+	 *     to the server;
+	 *
+	 *     - VM induced page write-out. An io context for writing page out
+	 *     for memory cleansing;
+	 *
+	 *     - glimpse. An io context to acquire glimpse lock.
+	 *
+	 *     - grouplock. An io context to acquire group lock.
+	 *
+	 * CIT_MISC io is used simply as a context in which locks and pages
+	 * are manipulated. Such io has no internal "process", that is,
+	 * cl_io_loop() is never called for it.
+	 */
+	CIT_MISC,
+	CIT_OP_NR
+};
+
+/**
+ * States of cl_io state machine
+ */
+enum cl_io_state {
+	/** Not initialized. */
+	CIS_ZERO,
+	/** Initialized. */
+	CIS_INIT,
+	/** IO iteration started. */
+	CIS_IT_STARTED,
+	/** Locks taken. */
+	CIS_LOCKED,
+	/** Actual IO is in progress. */
+	CIS_IO_GOING,
+	/** IO for the current iteration finished. */
+	CIS_IO_FINISHED,
+	/** Locks released. */
+	CIS_UNLOCKED,
+	/** Iteration completed. */
+	CIS_IT_ENDED,
+	/** cl_io finalized. */
+	CIS_FINI
+};
+
+/**
+ * IO state private for a layer.
+ *
+ * This is usually embedded into layer session data, rather than allocated
+ * dynamically.
+ *
+ * \see vvp_io, lov_io, osc_io, ccc_io
+ */
+struct cl_io_slice {
+	struct cl_io		  *cis_io;
+	/** corresponding object slice. Immutable after creation. */
+	struct cl_object	      *cis_obj;
+	/** io operations. Immutable after creation. */
+	const struct cl_io_operations *cis_iop;
+	/**
+	 * linkage into a list of all slices for a given cl_io, hanging off
+	 * cl_io::ci_layers. Immutable after creation.
+	 */
+	struct list_head		     cis_linkage;
+};
+
+
+/**
+ * Per-layer io operations.
+ * \see vvp_io_ops, lov_io_ops, lovsub_io_ops, osc_io_ops
+ */
+struct cl_io_operations {
+	/**
+	 * Vector of io state transition methods for every io type.
+	 *
+	 * \see cl_page_operations::io
+	 */
+	struct {
+		/**
+		 * Prepare io iteration at a given layer.
+		 *
+		 * Called top-to-bottom at the beginning of each iteration of
+		 * "io loop" (if it makes sense for this type of io). Here
+		 * layer selects what work it will do during this iteration.
+		 *
+		 * \see cl_io_operations::cio_iter_fini()
+		 */
+		int (*cio_iter_init) (const struct lu_env *env,
+				      const struct cl_io_slice *slice);
+		/**
+		 * Finalize io iteration.
+		 *
+		 * Called bottom-to-top at the end of each iteration of "io
+		 * loop". Here layers can decide whether IO has to be
+		 * continued.
+		 *
+		 * \see cl_io_operations::cio_iter_init()
+		 */
+		void (*cio_iter_fini) (const struct lu_env *env,
+				       const struct cl_io_slice *slice);
+		/**
+		 * Collect locks for the current iteration of io.
+		 *
+		 * Called top-to-bottom to collect all locks necessary for
+		 * this iteration. This methods shouldn't actually enqueue
+		 * anything, instead it should post a lock through
+		 * cl_io_lock_add(). Once all locks are collected, they are
+		 * sorted and enqueued in the proper order.
+		 */
+		int  (*cio_lock) (const struct lu_env *env,
+				  const struct cl_io_slice *slice);
+		/**
+		 * Finalize unlocking.
+		 *
+		 * Called bottom-to-top to finish layer specific unlocking
+		 * functionality, after generic code released all locks
+		 * acquired by cl_io_operations::cio_lock().
+		 */
+		void  (*cio_unlock)(const struct lu_env *env,
+				    const struct cl_io_slice *slice);
+		/**
+		 * Start io iteration.
+		 *
+		 * Once all locks are acquired, called top-to-bottom to
+		 * commence actual IO. In the current implementation,
+		 * top-level vvp_io_{read,write}_start() does all the work
+		 * synchronously by calling generic_file_*(), so other layers
+		 * are called when everything is done.
+		 */
+		int  (*cio_start)(const struct lu_env *env,
+				  const struct cl_io_slice *slice);
+		/**
+		 * Called top-to-bottom at the end of io loop. Here layer
+		 * might wait for an unfinished asynchronous io.
+		 */
+		void (*cio_end)  (const struct lu_env *env,
+				  const struct cl_io_slice *slice);
+		/**
+		 * Called bottom-to-top to notify layers that read/write IO
+		 * iteration finished, with \a nob bytes transferred.
+		 */
+		void (*cio_advance)(const struct lu_env *env,
+				    const struct cl_io_slice *slice,
+				    size_t nob);
+		/**
+		 * Called once per io, bottom-to-top to release io resources.
+		 */
+		void (*cio_fini) (const struct lu_env *env,
+				  const struct cl_io_slice *slice);
+	} op[CIT_OP_NR];
+	struct {
+		/**
+		 * Submit pages from \a queue->c2_qin for IO, and move
+		 * successfully submitted pages into \a queue->c2_qout. Return
+		 * non-zero if failed to submit even the single page. If
+		 * submission failed after some pages were moved into \a
+		 * queue->c2_qout, completion callback with non-zero ioret is
+		 * executed on them.
+		 */
+		int  (*cio_submit)(const struct lu_env *env,
+				   const struct cl_io_slice *slice,
+				   enum cl_req_type crt,
+				   struct cl_2queue *queue);
+	} req_op[CRT_NR];
+	/**
+	 * Read missing page.
+	 *
+	 * Called by a top-level cl_io_operations::op[CIT_READ]::cio_start()
+	 * method, when it hits not-up-to-date page in the range. Optional.
+	 *
+	 * \pre io->ci_type == CIT_READ
+	 */
+	int (*cio_read_page)(const struct lu_env *env,
+			     const struct cl_io_slice *slice,
+			     const struct cl_page_slice *page);
+	/**
+	 * Prepare write of a \a page. Called bottom-to-top by a top-level
+	 * cl_io_operations::op[CIT_WRITE]::cio_start() to prepare page for
+	 * get data from user-level buffer.
+	 *
+	 * \pre io->ci_type == CIT_WRITE
+	 *
+	 * \see vvp_io_prepare_write(), lov_io_prepare_write(),
+	 * osc_io_prepare_write().
+	 */
+	int (*cio_prepare_write)(const struct lu_env *env,
+				 const struct cl_io_slice *slice,
+				 const struct cl_page_slice *page,
+				 unsigned from, unsigned to);
+	/**
+	 *
+	 * \pre io->ci_type == CIT_WRITE
+	 *
+	 * \see vvp_io_commit_write(), lov_io_commit_write(),
+	 * osc_io_commit_write().
+	 */
+	int (*cio_commit_write)(const struct lu_env *env,
+				const struct cl_io_slice *slice,
+				const struct cl_page_slice *page,
+				unsigned from, unsigned to);
+	/**
+	 * Optional debugging helper. Print given io slice.
+	 */
+	int (*cio_print)(const struct lu_env *env, void *cookie,
+			 lu_printer_t p, const struct cl_io_slice *slice);
+};
+
+/**
+ * Flags to lock enqueue procedure.
+ * \ingroup cl_lock
+ */
+enum cl_enq_flags {
+	/**
+	 * instruct server to not block, if conflicting lock is found. Instead
+	 * -EWOULDBLOCK is returned immediately.
+	 */
+	CEF_NONBLOCK     = 0x00000001,
+	/**
+	 * take lock asynchronously (out of order), as it cannot
+	 * deadlock. This is for LDLM_FL_HAS_INTENT locks used for glimpsing.
+	 */
+	CEF_ASYNC	= 0x00000002,
+	/**
+	 * tell the server to instruct (though a flag in the blocking ast) an
+	 * owner of the conflicting lock, that it can drop dirty pages
+	 * protected by this lock, without sending them to the server.
+	 */
+	CEF_DISCARD_DATA = 0x00000004,
+	/**
+	 * tell the sub layers that it must be a `real' lock. This is used for
+	 * mmapped-buffer locks and glimpse locks that must be never converted
+	 * into lockless mode.
+	 *
+	 * \see vvp_mmap_locks(), cl_glimpse_lock().
+	 */
+	CEF_MUST	 = 0x00000008,
+	/**
+	 * tell the sub layers that never request a `real' lock. This flag is
+	 * not used currently.
+	 *
+	 * cl_io::ci_lockreq and CEF_{MUST,NEVER} flags specify lockless
+	 * conversion policy: ci_lockreq describes generic information of lock
+	 * requirement for this IO, especially for locks which belong to the
+	 * object doing IO; however, lock itself may have precise requirements
+	 * that are described by the enqueue flags.
+	 */
+	CEF_NEVER	= 0x00000010,
+	/**
+	 * for async glimpse lock.
+	 */
+	CEF_AGL	  = 0x00000020,
+	/**
+	 * mask of enq_flags.
+	 */
+	CEF_MASK	 = 0x0000003f,
+};
+
+/**
+ * Link between lock and io. Intermediate structure is needed, because the
+ * same lock can be part of multiple io's simultaneously.
+ */
+struct cl_io_lock_link {
+	/** linkage into one of cl_lockset lists. */
+	struct list_head	   cill_linkage;
+	struct cl_lock_descr cill_descr;
+	struct cl_lock      *cill_lock;
+	/** optional destructor */
+	void	       (*cill_fini)(const struct lu_env *env,
+					struct cl_io_lock_link *link);
+};
+
+/**
+ * Lock-set represents a collection of locks, that io needs at a
+ * time. Generally speaking, client tries to avoid holding multiple locks when
+ * possible, because
+ *
+ *      - holding extent locks over multiple ost's introduces the danger of
+ *	"cascading timeouts";
+ *
+ *      - holding multiple locks over the same ost is still dead-lock prone,
+ *	see comment in osc_lock_enqueue(),
+ *
+ * but there are certain situations where this is unavoidable:
+ *
+ *      - O_APPEND writes have to take [0, EOF] lock for correctness;
+ *
+ *      - truncate has to take [new-size, EOF] lock for correctness;
+ *
+ *      - SNS has to take locks across full stripe for correctness;
+ *
+ *      - in the case when user level buffer, supplied to {read,write}(file0),
+ *	is a part of a memory mapped lustre file, client has to take a dlm
+ *	locks on file0, and all files that back up the buffer (or a part of
+ *	the buffer, that is being processed in the current chunk, in any
+ *	case, there are situations where at least 2 locks are necessary).
+ *
+ * In such cases we at least try to take locks in the same consistent
+ * order. To this end, all locks are first collected, then sorted, and then
+ * enqueued.
+ */
+struct cl_lockset {
+	/** locks to be acquired. */
+	struct list_head  cls_todo;
+	/** locks currently being processed. */
+	struct list_head  cls_curr;
+	/** locks acquired. */
+	struct list_head  cls_done;
+};
+
+/**
+ * Lock requirements(demand) for IO. It should be cl_io_lock_req,
+ * but 'req' is always to be thought as 'request' :-)
+ */
+enum cl_io_lock_dmd {
+	/** Always lock data (e.g., O_APPEND). */
+	CILR_MANDATORY = 0,
+	/** Layers are free to decide between local and global locking. */
+	CILR_MAYBE,
+	/** Never lock: there is no cache (e.g., liblustre). */
+	CILR_NEVER
+};
+
+enum cl_fsync_mode {
+	/** start writeback, do not wait for them to finish */
+	CL_FSYNC_NONE  = 0,
+	/** start writeback and wait for them to finish */
+	CL_FSYNC_LOCAL = 1,
+	/** discard all of dirty pages in a specific file range */
+	CL_FSYNC_DISCARD = 2,
+	/** start writeback and make sure they have reached storage before
+	 * return. OST_SYNC RPC must be issued and finished */
+	CL_FSYNC_ALL   = 3
+};
+
+struct cl_io_rw_common {
+	loff_t      crw_pos;
+	size_t      crw_count;
+	int	 crw_nonblock;
+};
+
+
+/**
+ * State for io.
+ *
+ * cl_io is shared by all threads participating in this IO (in current
+ * implementation only one thread advances IO, but parallel IO design and
+ * concurrent copy_*_user() require multiple threads acting on the same IO. It
+ * is up to these threads to serialize their activities, including updates to
+ * mutable cl_io fields.
+ */
+struct cl_io {
+	/** type of this IO. Immutable after creation. */
+	enum cl_io_type		ci_type;
+	/** current state of cl_io state machine. */
+	enum cl_io_state	       ci_state;
+	/** main object this io is against. Immutable after creation. */
+	struct cl_object	      *ci_obj;
+	/**
+	 * Upper layer io, of which this io is a part of. Immutable after
+	 * creation.
+	 */
+	struct cl_io		  *ci_parent;
+	/** List of slices. Immutable after creation. */
+	struct list_head		     ci_layers;
+	/** list of locks (to be) acquired by this io. */
+	struct cl_lockset	      ci_lockset;
+	/** lock requirements, this is just a help info for sublayers. */
+	enum cl_io_lock_dmd	    ci_lockreq;
+	union {
+		struct cl_rd_io {
+			struct cl_io_rw_common rd;
+		} ci_rd;
+		struct cl_wr_io {
+			struct cl_io_rw_common wr;
+			int		    wr_append;
+			int		    wr_sync;
+		} ci_wr;
+		struct cl_io_rw_common ci_rw;
+		struct cl_setattr_io {
+			struct ost_lvb   sa_attr;
+			unsigned int     sa_valid;
+			struct obd_capa *sa_capa;
+		} ci_setattr;
+		struct cl_fault_io {
+			/** page index within file. */
+			pgoff_t	 ft_index;
+			/** bytes valid byte on a faulted page. */
+			int	     ft_nob;
+			/** writable page? for nopage() only */
+			int	     ft_writable;
+			/** page of an executable? */
+			int	     ft_executable;
+			/** page_mkwrite() */
+			int	     ft_mkwrite;
+			/** resulting page */
+			struct cl_page *ft_page;
+		} ci_fault;
+		struct cl_fsync_io {
+			loff_t	     fi_start;
+			loff_t	     fi_end;
+			struct obd_capa   *fi_capa;
+			/** file system level fid */
+			struct lu_fid     *fi_fid;
+			enum cl_fsync_mode fi_mode;
+			/* how many pages were written/discarded */
+			unsigned int       fi_nr_written;
+		} ci_fsync;
+	} u;
+	struct cl_2queue     ci_queue;
+	size_t	       ci_nob;
+	int		  ci_result;
+	unsigned int	 ci_continue:1,
+	/**
+	 * This io has held grouplock, to inform sublayers that
+	 * don't do lockless i/o.
+	 */
+			     ci_no_srvlock:1,
+	/**
+	 * The whole IO need to be restarted because layout has been changed
+	 */
+			     ci_need_restart:1,
+	/**
+	 * to not refresh layout - the IO issuer knows that the layout won't
+	 * change(page operations, layout change causes all page to be
+	 * discarded), or it doesn't matter if it changes(sync).
+	 */
+			     ci_ignore_layout:1,
+	/**
+	 * Check if layout changed after the IO finishes. Mainly for HSM
+	 * requirement. If IO occurs to openning files, it doesn't need to
+	 * verify layout because HSM won't release openning files.
+	 * Right now, only two opertaions need to verify layout: glimpse
+	 * and setattr.
+	 */
+			     ci_verify_layout:1;
+	/**
+	 * Number of pages owned by this IO. For invariant checking.
+	 */
+	unsigned	     ci_owned_nr;
+};
+
+/** @} cl_io */
+
+/** \addtogroup cl_req cl_req
+ * @{ */
+/** \struct cl_req
+ * Transfer.
+ *
+ * There are two possible modes of transfer initiation on the client:
+ *
+ *     - immediate transfer: this is started when a high level io wants a page
+ *       or a collection of pages to be transferred right away. Examples:
+ *       read-ahead, synchronous read in the case of non-page aligned write,
+ *       page write-out as a part of extent lock cancellation, page write-out
+ *       as a part of memory cleansing. Immediate transfer can be both
+ *       cl_req_type::CRT_READ and cl_req_type::CRT_WRITE;
+ *
+ *     - opportunistic transfer (cl_req_type::CRT_WRITE only), that happens
+ *       when io wants to transfer a page to the server some time later, when
+ *       it can be done efficiently. Example: pages dirtied by the write(2)
+ *       path.
+ *
+ * In any case, transfer takes place in the form of a cl_req, which is a
+ * representation for a network RPC.
+ *
+ * Pages queued for an opportunistic transfer are cached until it is decided
+ * that efficient RPC can be composed of them. This decision is made by "a
+ * req-formation engine", currently implemented as a part of osc
+ * layer. Req-formation depends on many factors: the size of the resulting
+ * RPC, whether or not multi-object RPCs are supported by the server,
+ * max-rpc-in-flight limitations, size of the dirty cache, etc.
+ *
+ * For the immediate transfer io submits a cl_page_list, that req-formation
+ * engine slices into cl_req's, possibly adding cached pages to some of
+ * the resulting req's.
+ *
+ * Whenever a page from cl_page_list is added to a newly constructed req, its
+ * cl_page_operations::cpo_prep() layer methods are called. At that moment,
+ * page state is atomically changed from cl_page_state::CPS_OWNED to
+ * cl_page_state::CPS_PAGEOUT or cl_page_state::CPS_PAGEIN, cl_page::cp_owner
+ * is zeroed, and cl_page::cp_req is set to the
+ * req. cl_page_operations::cpo_prep() method at the particular layer might
+ * return -EALREADY to indicate that it does not need to submit this page
+ * at all. This is possible, for example, if page, submitted for read,
+ * became up-to-date in the meantime; and for write, the page don't have
+ * dirty bit marked. \see cl_io_submit_rw()
+ *
+ * Whenever a cached page is added to a newly constructed req, its
+ * cl_page_operations::cpo_make_ready() layer methods are called. At that
+ * moment, page state is atomically changed from cl_page_state::CPS_CACHED to
+ * cl_page_state::CPS_PAGEOUT, and cl_page::cp_req is set to
+ * req. cl_page_operations::cpo_make_ready() method at the particular layer
+ * might return -EAGAIN to indicate that this page is not eligible for the
+ * transfer right now.
+ *
+ * FUTURE
+ *
+ * Plan is to divide transfers into "priority bands" (indicated when
+ * submitting cl_page_list, and queuing a page for the opportunistic transfer)
+ * and allow glueing of cached pages to immediate transfers only within single
+ * band. This would make high priority transfers (like lock cancellation or
+ * memory pressure induced write-out) really high priority.
+ *
+ */
+
+/**
+ * Per-transfer attributes.
+ */
+struct cl_req_attr {
+	/** Generic attributes for the server consumption. */
+	struct obdo	*cra_oa;
+	/** Capability. */
+	struct obd_capa	*cra_capa;
+	/** Jobid */
+	char		 cra_jobid[JOBSTATS_JOBID_SIZE];
+};
+
+/**
+ * Transfer request operations definable at every layer.
+ *
+ * Concurrency: transfer formation engine synchronizes calls to all transfer
+ * methods.
+ */
+struct cl_req_operations {
+	/**
+	 * Invoked top-to-bottom by cl_req_prep() when transfer formation is
+	 * complete (all pages are added).
+	 *
+	 * \see osc_req_prep()
+	 */
+	int  (*cro_prep)(const struct lu_env *env,
+			 const struct cl_req_slice *slice);
+	/**
+	 * Called top-to-bottom to fill in \a oa fields. This is called twice
+	 * with different flags, see bug 10150 and osc_build_req().
+	 *
+	 * \param obj an object from cl_req which attributes are to be set in
+	 *	    \a oa.
+	 *
+	 * \param oa struct obdo where attributes are placed
+	 *
+	 * \param flags \a oa fields to be filled.
+	 */
+	void (*cro_attr_set)(const struct lu_env *env,
+			     const struct cl_req_slice *slice,
+			     const struct cl_object *obj,
+			     struct cl_req_attr *attr, obd_valid flags);
+	/**
+	 * Called top-to-bottom from cl_req_completion() to notify layers that
+	 * transfer completed. Has to free all state allocated by
+	 * cl_device_operations::cdo_req_init().
+	 */
+	void (*cro_completion)(const struct lu_env *env,
+			       const struct cl_req_slice *slice, int ioret);
+};
+
+/**
+ * A per-object state that (potentially multi-object) transfer request keeps.
+ */
+struct cl_req_obj {
+	/** object itself */
+	struct cl_object   *ro_obj;
+	/** reference to cl_req_obj::ro_obj. For debugging. */
+	struct lu_ref_link *ro_obj_ref;
+	/* something else? Number of pages for a given object? */
+};
+
+/**
+ * Transfer request.
+ *
+ * Transfer requests are not reference counted, because IO sub-system owns
+ * them exclusively and knows when to free them.
+ *
+ * Life cycle.
+ *
+ * cl_req is created by cl_req_alloc() that calls
+ * cl_device_operations::cdo_req_init() device methods to allocate per-req
+ * state in every layer.
+ *
+ * Then pages are added (cl_req_page_add()), req keeps track of all objects it
+ * contains pages for.
+ *
+ * Once all pages were collected, cl_page_operations::cpo_prep() method is
+ * called top-to-bottom. At that point layers can modify req, let it pass, or
+ * deny it completely. This is to support things like SNS that have transfer
+ * ordering requirements invisible to the individual req-formation engine.
+ *
+ * On transfer completion (or transfer timeout, or failure to initiate the
+ * transfer of an allocated req), cl_req_operations::cro_completion() method
+ * is called, after execution of cl_page_operations::cpo_completion() of all
+ * req's pages.
+ */
+struct cl_req {
+	enum cl_req_type      crq_type;
+	/** A list of pages being transfered */
+	struct list_head	    crq_pages;
+	/** Number of pages in cl_req::crq_pages */
+	unsigned	      crq_nrpages;
+	/** An array of objects which pages are in ->crq_pages */
+	struct cl_req_obj    *crq_o;
+	/** Number of elements in cl_req::crq_objs[] */
+	unsigned	      crq_nrobjs;
+	struct list_head	    crq_layers;
+};
+
+/**
+ * Per-layer state for request.
+ */
+struct cl_req_slice {
+	struct cl_req    *crs_req;
+	struct cl_device *crs_dev;
+	struct list_head	crs_linkage;
+	const struct cl_req_operations *crs_ops;
+};
+
+/* @} cl_req */
+
+enum cache_stats_item {
+	/** how many cache lookups were performed */
+	CS_lookup = 0,
+	/** how many times cache lookup resulted in a hit */
+	CS_hit,
+	/** how many entities are in the cache right now */
+	CS_total,
+	/** how many entities in the cache are actively used (and cannot be
+	 * evicted) right now */
+	CS_busy,
+	/** how many entities were created at all */
+	CS_create,
+	CS_NR
+};
+
+#define CS_NAMES { "lookup", "hit", "total", "busy", "create" }
+
+/**
+ * Stats for a generic cache (similar to inode, lu_object, etc. caches).
+ */
+struct cache_stats {
+	const char    *cs_name;
+	atomic_t   cs_stats[CS_NR];
+};
+
+/** These are not exported so far */
+void cache_stats_init (struct cache_stats *cs, const char *name);
+
+/**
+ * Client-side site. This represents particular client stack. "Global"
+ * variables should (directly or indirectly) be added here to allow multiple
+ * clients to co-exist in the single address space.
+ */
+struct cl_site {
+	struct lu_site	cs_lu;
+	/**
+	 * Statistical counters. Atomics do not scale, something better like
+	 * per-cpu counters is needed.
+	 *
+	 * These are exported as /proc/fs/lustre/llite/.../site
+	 *
+	 * When interpreting keep in mind that both sub-locks (and sub-pages)
+	 * and top-locks (and top-pages) are accounted here.
+	 */
+	struct cache_stats    cs_pages;
+	struct cache_stats    cs_locks;
+	atomic_t	  cs_pages_state[CPS_NR];
+	atomic_t	  cs_locks_state[CLS_NR];
+};
+
+int  cl_site_init (struct cl_site *s, struct cl_device *top);
+void cl_site_fini (struct cl_site *s);
+void cl_stack_fini(const struct lu_env *env, struct cl_device *cl);
+
+/**
+ * Output client site statistical counters into a buffer. Suitable for
+ * ll_rd_*()-style functions.
+ */
+int cl_site_stats_print(const struct cl_site *site, struct seq_file *m);
+
+/**
+ * \name helpers
+ *
+ * Type conversion and accessory functions.
+ */
+/** @{ */
+
+static inline struct cl_site *lu2cl_site(const struct lu_site *site)
+{
+	return container_of(site, struct cl_site, cs_lu);
+}
+
+static inline int lu_device_is_cl(const struct lu_device *d)
+{
+	return d->ld_type->ldt_tags & LU_DEVICE_CL;
+}
+
+static inline struct cl_device *lu2cl_dev(const struct lu_device *d)
+{
+	LASSERT(d == NULL || IS_ERR(d) || lu_device_is_cl(d));
+	return container_of0(d, struct cl_device, cd_lu_dev);
+}
+
+static inline struct lu_device *cl2lu_dev(struct cl_device *d)
+{
+	return &d->cd_lu_dev;
+}
+
+static inline struct cl_object *lu2cl(const struct lu_object *o)
+{
+	LASSERT(o == NULL || IS_ERR(o) || lu_device_is_cl(o->lo_dev));
+	return container_of0(o, struct cl_object, co_lu);
+}
+
+static inline const struct cl_object_conf *
+lu2cl_conf(const struct lu_object_conf *conf)
+{
+	return container_of0(conf, struct cl_object_conf, coc_lu);
+}
+
+static inline struct cl_object *cl_object_next(const struct cl_object *obj)
+{
+	return obj ? lu2cl(lu_object_next(&obj->co_lu)) : NULL;
+}
+
+static inline struct cl_device *cl_object_device(const struct cl_object *o)
+{
+	LASSERT(o == NULL || IS_ERR(o) || lu_device_is_cl(o->co_lu.lo_dev));
+	return container_of0(o->co_lu.lo_dev, struct cl_device, cd_lu_dev);
+}
+
+static inline struct cl_object_header *luh2coh(const struct lu_object_header *h)
+{
+	return container_of0(h, struct cl_object_header, coh_lu);
+}
+
+static inline struct cl_site *cl_object_site(const struct cl_object *obj)
+{
+	return lu2cl_site(obj->co_lu.lo_dev->ld_site);
+}
+
+static inline
+struct cl_object_header *cl_object_header(const struct cl_object *obj)
+{
+	return luh2coh(obj->co_lu.lo_header);
+}
+
+static inline int cl_device_init(struct cl_device *d, struct lu_device_type *t)
+{
+	return lu_device_init(&d->cd_lu_dev, t);
+}
+
+static inline void cl_device_fini(struct cl_device *d)
+{
+	lu_device_fini(&d->cd_lu_dev);
+}
+
+void cl_page_slice_add(struct cl_page *page, struct cl_page_slice *slice,
+		       struct cl_object *obj,
+		       const struct cl_page_operations *ops);
+void cl_lock_slice_add(struct cl_lock *lock, struct cl_lock_slice *slice,
+		       struct cl_object *obj,
+		       const struct cl_lock_operations *ops);
+void cl_io_slice_add(struct cl_io *io, struct cl_io_slice *slice,
+		     struct cl_object *obj, const struct cl_io_operations *ops);
+void cl_req_slice_add(struct cl_req *req, struct cl_req_slice *slice,
+		      struct cl_device *dev,
+		      const struct cl_req_operations *ops);
+/** @} helpers */
+
+/** \defgroup cl_object cl_object
+ * @{ */
+struct cl_object *cl_object_top (struct cl_object *o);
+struct cl_object *cl_object_find(const struct lu_env *env, struct cl_device *cd,
+				 const struct lu_fid *fid,
+				 const struct cl_object_conf *c);
+
+int  cl_object_header_init(struct cl_object_header *h);
+void cl_object_header_fini(struct cl_object_header *h);
+void cl_object_put	(const struct lu_env *env, struct cl_object *o);
+void cl_object_get	(struct cl_object *o);
+void cl_object_attr_lock  (struct cl_object *o);
+void cl_object_attr_unlock(struct cl_object *o);
+int  cl_object_attr_get   (const struct lu_env *env, struct cl_object *obj,
+			   struct cl_attr *attr);
+int  cl_object_attr_set   (const struct lu_env *env, struct cl_object *obj,
+			   const struct cl_attr *attr, unsigned valid);
+int  cl_object_glimpse    (const struct lu_env *env, struct cl_object *obj,
+			   struct ost_lvb *lvb);
+int  cl_conf_set	  (const struct lu_env *env, struct cl_object *obj,
+			   const struct cl_object_conf *conf);
+void cl_object_prune      (const struct lu_env *env, struct cl_object *obj);
+void cl_object_kill       (const struct lu_env *env, struct cl_object *obj);
+int  cl_object_has_locks  (struct cl_object *obj);
+
+/**
+ * Returns true, iff \a o0 and \a o1 are slices of the same object.
+ */
+static inline int cl_object_same(struct cl_object *o0, struct cl_object *o1)
+{
+	return cl_object_header(o0) == cl_object_header(o1);
+}
+
+static inline void cl_object_page_init(struct cl_object *clob, int size)
+{
+	clob->co_slice_off = cl_object_header(clob)->coh_page_bufsize;
+	cl_object_header(clob)->coh_page_bufsize += ALIGN(size, 8);
+}
+
+static inline void *cl_object_page_slice(struct cl_object *clob,
+					 struct cl_page *page)
+{
+	return (void *)((char *)page + clob->co_slice_off);
+}
+
+/** @} cl_object */
+
+/** \defgroup cl_page cl_page
+ * @{ */
+enum {
+	CLP_GANG_OKAY = 0,
+	CLP_GANG_RESCHED,
+	CLP_GANG_AGAIN,
+	CLP_GANG_ABORT
+};
+
+/* callback of cl_page_gang_lookup() */
+typedef int   (*cl_page_gang_cb_t)  (const struct lu_env *, struct cl_io *,
+				     struct cl_page *, void *);
+int	     cl_page_gang_lookup (const struct lu_env *env,
+				     struct cl_object *obj,
+				     struct cl_io *io,
+				     pgoff_t start, pgoff_t end,
+				     cl_page_gang_cb_t cb, void *cbdata);
+struct cl_page *cl_page_lookup      (struct cl_object_header *hdr,
+				     pgoff_t index);
+struct cl_page *cl_page_find	(const struct lu_env *env,
+				     struct cl_object *obj,
+				     pgoff_t idx, struct page *vmpage,
+				     enum cl_page_type type);
+struct cl_page *cl_page_find_sub    (const struct lu_env *env,
+				     struct cl_object *obj,
+				     pgoff_t idx, struct page *vmpage,
+				     struct cl_page *parent);
+void	    cl_page_get	 (struct cl_page *page);
+void	    cl_page_put	 (const struct lu_env *env,
+				     struct cl_page *page);
+void	    cl_page_print       (const struct lu_env *env, void *cookie,
+				     lu_printer_t printer,
+				     const struct cl_page *pg);
+void	    cl_page_header_print(const struct lu_env *env, void *cookie,
+				     lu_printer_t printer,
+				     const struct cl_page *pg);
+struct page     *cl_page_vmpage      (const struct lu_env *env,
+				     struct cl_page *page);
+struct cl_page *cl_vmpage_page      (struct page *vmpage, struct cl_object *obj);
+struct cl_page *cl_page_top	 (struct cl_page *page);
+
+const struct cl_page_slice *cl_page_at(const struct cl_page *page,
+				       const struct lu_device_type *dtype);
+
+/**
+ * \name ownership
+ *
+ * Functions dealing with the ownership of page by io.
+ */
+/** @{ */
+
+int  cl_page_own	(const struct lu_env *env,
+			 struct cl_io *io, struct cl_page *page);
+int  cl_page_own_try    (const struct lu_env *env,
+			 struct cl_io *io, struct cl_page *page);
+void cl_page_assume     (const struct lu_env *env,
+			 struct cl_io *io, struct cl_page *page);
+void cl_page_unassume   (const struct lu_env *env,
+			 struct cl_io *io, struct cl_page *pg);
+void cl_page_disown     (const struct lu_env *env,
+			 struct cl_io *io, struct cl_page *page);
+int  cl_page_is_owned   (const struct cl_page *pg, const struct cl_io *io);
+
+/** @} ownership */
+
+/**
+ * \name transfer
+ *
+ * Functions dealing with the preparation of a page for a transfer, and
+ * tracking transfer state.
+ */
+/** @{ */
+int  cl_page_prep       (const struct lu_env *env, struct cl_io *io,
+			 struct cl_page *pg, enum cl_req_type crt);
+void cl_page_completion (const struct lu_env *env,
+			 struct cl_page *pg, enum cl_req_type crt, int ioret);
+int  cl_page_make_ready (const struct lu_env *env, struct cl_page *pg,
+			 enum cl_req_type crt);
+int  cl_page_cache_add  (const struct lu_env *env, struct cl_io *io,
+			 struct cl_page *pg, enum cl_req_type crt);
+void cl_page_clip       (const struct lu_env *env, struct cl_page *pg,
+			 int from, int to);
+int  cl_page_cancel     (const struct lu_env *env, struct cl_page *page);
+int  cl_page_flush      (const struct lu_env *env, struct cl_io *io,
+			 struct cl_page *pg);
+
+/** @} transfer */
+
+
+/**
+ * \name helper routines
+ * Functions to discard, delete and export a cl_page.
+ */
+/** @{ */
+void    cl_page_discard      (const struct lu_env *env, struct cl_io *io,
+			      struct cl_page *pg);
+void    cl_page_delete       (const struct lu_env *env, struct cl_page *pg);
+int     cl_page_unmap	(const struct lu_env *env, struct cl_io *io,
+			      struct cl_page *pg);
+int     cl_page_is_vmlocked  (const struct lu_env *env,
+			      const struct cl_page *pg);
+void    cl_page_export       (const struct lu_env *env,
+			      struct cl_page *pg, int uptodate);
+int     cl_page_is_under_lock(const struct lu_env *env, struct cl_io *io,
+			      struct cl_page *page);
+loff_t  cl_offset	    (const struct cl_object *obj, pgoff_t idx);
+pgoff_t cl_index	     (const struct cl_object *obj, loff_t offset);
+int     cl_page_size	 (const struct cl_object *obj);
+int     cl_pages_prune       (const struct lu_env *env, struct cl_object *obj);
+
+void cl_lock_print      (const struct lu_env *env, void *cookie,
+			 lu_printer_t printer, const struct cl_lock *lock);
+void cl_lock_descr_print(const struct lu_env *env, void *cookie,
+			 lu_printer_t printer,
+			 const struct cl_lock_descr *descr);
+/* @} helper */
+
+/** @} cl_page */
+
+/** \defgroup cl_lock cl_lock
+ * @{ */
+
+struct cl_lock *cl_lock_hold(const struct lu_env *env, const struct cl_io *io,
+			     const struct cl_lock_descr *need,
+			     const char *scope, const void *source);
+struct cl_lock *cl_lock_peek(const struct lu_env *env, const struct cl_io *io,
+			     const struct cl_lock_descr *need,
+			     const char *scope, const void *source);
+struct cl_lock *cl_lock_request(const struct lu_env *env, struct cl_io *io,
+				const struct cl_lock_descr *need,
+				const char *scope, const void *source);
+struct cl_lock *cl_lock_at_pgoff(const struct lu_env *env,
+				 struct cl_object *obj, pgoff_t index,
+				 struct cl_lock *except, int pending,
+				 int canceld);
+static inline struct cl_lock *cl_lock_at_page(const struct lu_env *env,
+					      struct cl_object *obj,
+					      struct cl_page *page,
+					      struct cl_lock *except,
+					      int pending, int canceld)
+{
+	LASSERT(cl_object_header(obj) == cl_object_header(page->cp_obj));
+	return cl_lock_at_pgoff(env, obj, page->cp_index, except,
+				pending, canceld);
+}
+
+const struct cl_lock_slice *cl_lock_at(const struct cl_lock *lock,
+				       const struct lu_device_type *dtype);
+
+void  cl_lock_get       (struct cl_lock *lock);
+void  cl_lock_get_trust (struct cl_lock *lock);
+void  cl_lock_put       (const struct lu_env *env, struct cl_lock *lock);
+void  cl_lock_hold_add  (const struct lu_env *env, struct cl_lock *lock,
+			 const char *scope, const void *source);
+void cl_lock_hold_release(const struct lu_env *env, struct cl_lock *lock,
+			  const char *scope, const void *source);
+void  cl_lock_unhold    (const struct lu_env *env, struct cl_lock *lock,
+			 const char *scope, const void *source);
+void  cl_lock_release   (const struct lu_env *env, struct cl_lock *lock,
+			 const char *scope, const void *source);
+void  cl_lock_user_add  (const struct lu_env *env, struct cl_lock *lock);
+void  cl_lock_user_del  (const struct lu_env *env, struct cl_lock *lock);
+
+enum cl_lock_state cl_lock_intransit(const struct lu_env *env,
+				     struct cl_lock *lock);
+void cl_lock_extransit(const struct lu_env *env, struct cl_lock *lock,
+		       enum cl_lock_state state);
+int cl_lock_is_intransit(struct cl_lock *lock);
+
+int cl_lock_enqueue_wait(const struct lu_env *env, struct cl_lock *lock,
+			 int keep_mutex);
+
+/** \name statemachine statemachine
+ * Interface to lock state machine consists of 3 parts:
+ *
+ *     - "try" functions that attempt to effect a state transition. If state
+ *     transition is not possible right now (e.g., if it has to wait for some
+ *     asynchronous event to occur), these functions return
+ *     cl_lock_transition::CLO_WAIT.
+ *
+ *     - "non-try" functions that implement synchronous blocking interface on
+ *     top of non-blocking "try" functions. These functions repeatedly call
+ *     corresponding "try" versions, and if state transition is not possible
+ *     immediately, wait for lock state change.
+ *
+ *     - methods from cl_lock_operations, called by "try" functions. Lock can
+ *     be advanced to the target state only when all layers voted that they
+ *     are ready for this transition. "Try" functions call methods under lock
+ *     mutex. If a layer had to release a mutex, it re-acquires it and returns
+ *     cl_lock_transition::CLO_REPEAT, causing "try" function to call all
+ *     layers again.
+ *
+ * TRY	      NON-TRY      METHOD			    FINAL STATE
+ *
+ * cl_enqueue_try() cl_enqueue() cl_lock_operations::clo_enqueue() CLS_ENQUEUED
+ *
+ * cl_wait_try()    cl_wait()    cl_lock_operations::clo_wait()    CLS_HELD
+ *
+ * cl_unuse_try()   cl_unuse()   cl_lock_operations::clo_unuse()   CLS_CACHED
+ *
+ * cl_use_try()     NONE	 cl_lock_operations::clo_use()     CLS_HELD
+ *
+ * @{ */
+
+int   cl_enqueue    (const struct lu_env *env, struct cl_lock *lock,
+		     struct cl_io *io, __u32 flags);
+int   cl_wait       (const struct lu_env *env, struct cl_lock *lock);
+void  cl_unuse      (const struct lu_env *env, struct cl_lock *lock);
+int   cl_enqueue_try(const struct lu_env *env, struct cl_lock *lock,
+		     struct cl_io *io, __u32 flags);
+int   cl_unuse_try  (const struct lu_env *env, struct cl_lock *lock);
+int   cl_wait_try   (const struct lu_env *env, struct cl_lock *lock);
+int   cl_use_try    (const struct lu_env *env, struct cl_lock *lock, int atomic);
+
+/** @} statemachine */
+
+void cl_lock_signal      (const struct lu_env *env, struct cl_lock *lock);
+int  cl_lock_state_wait  (const struct lu_env *env, struct cl_lock *lock);
+void cl_lock_state_set   (const struct lu_env *env, struct cl_lock *lock,
+			  enum cl_lock_state state);
+int  cl_queue_match      (const struct list_head *queue,
+			  const struct cl_lock_descr *need);
+
+void cl_lock_mutex_get  (const struct lu_env *env, struct cl_lock *lock);
+int  cl_lock_mutex_try  (const struct lu_env *env, struct cl_lock *lock);
+void cl_lock_mutex_put  (const struct lu_env *env, struct cl_lock *lock);
+int  cl_lock_is_mutexed (struct cl_lock *lock);
+int  cl_lock_nr_mutexed (const struct lu_env *env);
+int  cl_lock_discard_pages(const struct lu_env *env, struct cl_lock *lock);
+int  cl_lock_ext_match  (const struct cl_lock_descr *has,
+			 const struct cl_lock_descr *need);
+int  cl_lock_descr_match(const struct cl_lock_descr *has,
+			 const struct cl_lock_descr *need);
+int  cl_lock_mode_match (enum cl_lock_mode has, enum cl_lock_mode need);
+int  cl_lock_modify     (const struct lu_env *env, struct cl_lock *lock,
+			 const struct cl_lock_descr *desc);
+
+void cl_lock_closure_init (const struct lu_env *env,
+			   struct cl_lock_closure *closure,
+			   struct cl_lock *origin, int wait);
+void cl_lock_closure_fini (struct cl_lock_closure *closure);
+int  cl_lock_closure_build(const struct lu_env *env, struct cl_lock *lock,
+			   struct cl_lock_closure *closure);
+void cl_lock_disclosure   (const struct lu_env *env,
+			   struct cl_lock_closure *closure);
+int  cl_lock_enclosure    (const struct lu_env *env, struct cl_lock *lock,
+			   struct cl_lock_closure *closure);
+
+void cl_lock_cancel(const struct lu_env *env, struct cl_lock *lock);
+void cl_lock_delete(const struct lu_env *env, struct cl_lock *lock);
+void cl_lock_error (const struct lu_env *env, struct cl_lock *lock, int error);
+void cl_locks_prune(const struct lu_env *env, struct cl_object *obj, int wait);
+
+unsigned long cl_lock_weigh(const struct lu_env *env, struct cl_lock *lock);
+
+/** @} cl_lock */
+
+/** \defgroup cl_io cl_io
+ * @{ */
+
+int   cl_io_init	 (const struct lu_env *env, struct cl_io *io,
+			  enum cl_io_type iot, struct cl_object *obj);
+int   cl_io_sub_init     (const struct lu_env *env, struct cl_io *io,
+			  enum cl_io_type iot, struct cl_object *obj);
+int   cl_io_rw_init      (const struct lu_env *env, struct cl_io *io,
+			  enum cl_io_type iot, loff_t pos, size_t count);
+int   cl_io_loop	 (const struct lu_env *env, struct cl_io *io);
+
+void  cl_io_fini	 (const struct lu_env *env, struct cl_io *io);
+int   cl_io_iter_init    (const struct lu_env *env, struct cl_io *io);
+void  cl_io_iter_fini    (const struct lu_env *env, struct cl_io *io);
+int   cl_io_lock	 (const struct lu_env *env, struct cl_io *io);
+void  cl_io_unlock       (const struct lu_env *env, struct cl_io *io);
+int   cl_io_start	(const struct lu_env *env, struct cl_io *io);
+void  cl_io_end	  (const struct lu_env *env, struct cl_io *io);
+int   cl_io_lock_add     (const struct lu_env *env, struct cl_io *io,
+			  struct cl_io_lock_link *link);
+int   cl_io_lock_alloc_add(const struct lu_env *env, struct cl_io *io,
+			   struct cl_lock_descr *descr);
+int   cl_io_read_page    (const struct lu_env *env, struct cl_io *io,
+			  struct cl_page *page);
+int   cl_io_prepare_write(const struct lu_env *env, struct cl_io *io,
+			  struct cl_page *page, unsigned from, unsigned to);
+int   cl_io_commit_write (const struct lu_env *env, struct cl_io *io,
+			  struct cl_page *page, unsigned from, unsigned to);
+int   cl_io_submit_rw    (const struct lu_env *env, struct cl_io *io,
+			  enum cl_req_type iot, struct cl_2queue *queue);
+int   cl_io_submit_sync  (const struct lu_env *env, struct cl_io *io,
+			  enum cl_req_type iot, struct cl_2queue *queue,
+			  long timeout);
+void  cl_io_rw_advance   (const struct lu_env *env, struct cl_io *io,
+			  size_t nob);
+int   cl_io_cancel       (const struct lu_env *env, struct cl_io *io,
+			  struct cl_page_list *queue);
+int   cl_io_is_going     (const struct lu_env *env);
+
+/**
+ * True, iff \a io is an O_APPEND write(2).
+ */
+static inline int cl_io_is_append(const struct cl_io *io)
+{
+	return io->ci_type == CIT_WRITE && io->u.ci_wr.wr_append;
+}
+
+static inline int cl_io_is_sync_write(const struct cl_io *io)
+{
+	return io->ci_type == CIT_WRITE && io->u.ci_wr.wr_sync;
+}
+
+static inline int cl_io_is_mkwrite(const struct cl_io *io)
+{
+	return io->ci_type == CIT_FAULT && io->u.ci_fault.ft_mkwrite;
+}
+
+/**
+ * True, iff \a io is a truncate(2).
+ */
+static inline int cl_io_is_trunc(const struct cl_io *io)
+{
+	return io->ci_type == CIT_SETATTR &&
+		(io->u.ci_setattr.sa_valid & ATTR_SIZE);
+}
+
+struct cl_io *cl_io_top(struct cl_io *io);
+
+void cl_io_print(const struct lu_env *env, void *cookie,
+		 lu_printer_t printer, const struct cl_io *io);
+
+#define CL_IO_SLICE_CLEAN(foo_io, base)				 \
+do {								    \
+	typeof(foo_io) __foo_io = (foo_io);			     \
+									\
+	CLASSERT(offsetof(typeof(*__foo_io), base) == 0);	       \
+	memset(&__foo_io->base + 1, 0,				  \
+	       (sizeof *__foo_io) - sizeof __foo_io->base);	     \
+} while (0)
+
+/** @} cl_io */
+
+/** \defgroup cl_page_list cl_page_list
+ * @{ */
+
+/**
+ * Last page in the page list.
+ */
+static inline struct cl_page *cl_page_list_last(struct cl_page_list *plist)
+{
+	LASSERT(plist->pl_nr > 0);
+	return list_entry(plist->pl_pages.prev, struct cl_page, cp_batch);
+}
+
+/**
+ * Iterate over pages in a page list.
+ */
+#define cl_page_list_for_each(page, list)			       \
+	list_for_each_entry((page), &(list)->pl_pages, cp_batch)
+
+/**
+ * Iterate over pages in a page list, taking possible removals into account.
+ */
+#define cl_page_list_for_each_safe(page, temp, list)		    \
+	list_for_each_entry_safe((page), (temp), &(list)->pl_pages, cp_batch)
+
+void cl_page_list_init   (struct cl_page_list *plist);
+void cl_page_list_add    (struct cl_page_list *plist, struct cl_page *page);
+void cl_page_list_move   (struct cl_page_list *dst, struct cl_page_list *src,
+			  struct cl_page *page);
+void cl_page_list_splice (struct cl_page_list *list,
+			  struct cl_page_list *head);
+void cl_page_list_del    (const struct lu_env *env,
+			  struct cl_page_list *plist, struct cl_page *page);
+void cl_page_list_disown (const struct lu_env *env,
+			  struct cl_io *io, struct cl_page_list *plist);
+int  cl_page_list_own    (const struct lu_env *env,
+			  struct cl_io *io, struct cl_page_list *plist);
+void cl_page_list_assume (const struct lu_env *env,
+			  struct cl_io *io, struct cl_page_list *plist);
+void cl_page_list_discard(const struct lu_env *env,
+			  struct cl_io *io, struct cl_page_list *plist);
+int  cl_page_list_unmap  (const struct lu_env *env,
+			  struct cl_io *io, struct cl_page_list *plist);
+void cl_page_list_fini   (const struct lu_env *env, struct cl_page_list *plist);
+
+void cl_2queue_init     (struct cl_2queue *queue);
+void cl_2queue_add      (struct cl_2queue *queue, struct cl_page *page);
+void cl_2queue_disown   (const struct lu_env *env,
+			 struct cl_io *io, struct cl_2queue *queue);
+void cl_2queue_assume   (const struct lu_env *env,
+			 struct cl_io *io, struct cl_2queue *queue);
+void cl_2queue_discard  (const struct lu_env *env,
+			 struct cl_io *io, struct cl_2queue *queue);
+void cl_2queue_fini     (const struct lu_env *env, struct cl_2queue *queue);
+void cl_2queue_init_page(struct cl_2queue *queue, struct cl_page *page);
+
+/** @} cl_page_list */
+
+/** \defgroup cl_req cl_req
+ * @{ */
+struct cl_req *cl_req_alloc(const struct lu_env *env, struct cl_page *page,
+			    enum cl_req_type crt, int nr_objects);
+
+void cl_req_page_add  (const struct lu_env *env, struct cl_req *req,
+		       struct cl_page *page);
+void cl_req_page_done (const struct lu_env *env, struct cl_page *page);
+int  cl_req_prep      (const struct lu_env *env, struct cl_req *req);
+void cl_req_attr_set  (const struct lu_env *env, struct cl_req *req,
+		       struct cl_req_attr *attr, obd_valid flags);
+void cl_req_completion(const struct lu_env *env, struct cl_req *req, int ioret);
+
+/** \defgroup cl_sync_io cl_sync_io
+ * @{ */
+
+/**
+ * Anchor for synchronous transfer. This is allocated on a stack by thread
+ * doing synchronous transfer, and a pointer to this structure is set up in
+ * every page submitted for transfer. Transfer completion routine updates
+ * anchor and wakes up waiting thread when transfer is complete.
+ */
+struct cl_sync_io {
+	/** number of pages yet to be transferred. */
+	atomic_t		csi_sync_nr;
+	/** error code. */
+	int			csi_sync_rc;
+	/** barrier of destroy this structure */
+	atomic_t		csi_barrier;
+	/** completion to be signaled when transfer is complete. */
+	wait_queue_head_t		csi_waitq;
+};
+
+void cl_sync_io_init(struct cl_sync_io *anchor, int nrpages);
+int  cl_sync_io_wait(const struct lu_env *env, struct cl_io *io,
+		     struct cl_page_list *queue, struct cl_sync_io *anchor,
+		     long timeout);
+void cl_sync_io_note(struct cl_sync_io *anchor, int ioret);
+
+/** @} cl_sync_io */
+
+/** @} cl_req */
+
+/** \defgroup cl_env cl_env
+ *
+ * lu_env handling for a client.
+ *
+ * lu_env is an environment within which lustre code executes. Its major part
+ * is lu_context---a fast memory allocation mechanism that is used to conserve
+ * precious kernel stack space. Originally lu_env was designed for a server,
+ * where
+ *
+ *     - there is a (mostly) fixed number of threads, and
+ *
+ *     - call chains have no non-lustre portions inserted between lustre code.
+ *
+ * On a client both these assumtpion fails, because every user thread can
+ * potentially execute lustre code as part of a system call, and lustre calls
+ * into VFS or MM that call back into lustre.
+ *
+ * To deal with that, cl_env wrapper functions implement the following
+ * optimizations:
+ *
+ *     - allocation and destruction of environment is amortized by caching no
+ *     longer used environments instead of destroying them;
+ *
+ *     - there is a notion of "current" environment, attached to the kernel
+ *     data structure representing current thread Top-level lustre code
+ *     allocates an environment and makes it current, then calls into
+ *     non-lustre code, that in turn calls lustre back. Low-level lustre
+ *     code thus called can fetch environment created by the top-level code
+ *     and reuse it, avoiding additional environment allocation.
+ *       Right now, three interfaces can attach the cl_env to running thread:
+ *       - cl_env_get
+ *       - cl_env_implant
+ *       - cl_env_reexit(cl_env_reenter had to be called priorly)
+ *
+ * \see lu_env, lu_context, lu_context_key
+ * @{ */
+
+struct cl_env_nest {
+	int   cen_refcheck;
+	void *cen_cookie;
+};
+
+struct lu_env *cl_env_peek       (int *refcheck);
+struct lu_env *cl_env_get	(int *refcheck);
+struct lu_env *cl_env_alloc      (int *refcheck, __u32 tags);
+struct lu_env *cl_env_nested_get (struct cl_env_nest *nest);
+void	   cl_env_put	(struct lu_env *env, int *refcheck);
+void	   cl_env_nested_put (struct cl_env_nest *nest, struct lu_env *env);
+void	  *cl_env_reenter    (void);
+void	   cl_env_reexit     (void *cookie);
+void	   cl_env_implant    (struct lu_env *env, int *refcheck);
+void	   cl_env_unplant    (struct lu_env *env, int *refcheck);
+
+/** @} cl_env */
+
+/*
+ * Misc
+ */
+void cl_attr2lvb(struct ost_lvb *lvb, const struct cl_attr *attr);
+void cl_lvb2attr(struct cl_attr *attr, const struct ost_lvb *lvb);
+
+struct cl_device *cl_type_setup(const struct lu_env *env, struct lu_site *site,
+				struct lu_device_type *ldt,
+				struct lu_device *next);
+/** @} clio */
+
+int cl_global_init(void);
+void cl_global_fini(void);
+
+#endif /* _LINUX_CL_OBJECT_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/dt_object.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/dt_object.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/dt_object.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/dt_object.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1498 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LUSTRE_DT_OBJECT_H
+#define __LUSTRE_DT_OBJECT_H
+
+/** \defgroup dt dt
+ * Sub-class of lu_object with methods common for "data" objects in OST stack.
+ *
+ * Data objects behave like regular files: you can read/write them, get and
+ * set their attributes. Implementation of dt interface is supposed to
+ * implement some form of garbage collection, normally reference counting
+ * (nlink) based one.
+ *
+ * Examples: osd (lustre/osd) is an implementation of dt interface.
+ * @{
+ */
+
+
+/*
+ * super-class definitions.
+ */
+#include <lu_object.h>
+
+#include <linux/libcfs/libcfs.h>
+
+struct seq_file;
+struct proc_dir_entry;
+struct lustre_cfg;
+
+struct thandle;
+struct dt_device;
+struct dt_object;
+struct dt_index_features;
+struct niobuf_local;
+struct niobuf_remote;
+struct ldlm_enqueue_info;
+
+typedef enum {
+	MNTOPT_USERXATTR	= 0x00000001,
+	MNTOPT_ACL	      = 0x00000002,
+} mntopt_t;
+
+struct dt_device_param {
+	unsigned	   ddp_max_name_len;
+	unsigned	   ddp_max_nlink;
+	unsigned	   ddp_block_shift;
+	mntopt_t	   ddp_mntopts;
+	unsigned	   ddp_max_ea_size;
+	void	      *ddp_mnt; /* XXX: old code can retrieve mnt -bzzz */
+	int		ddp_mount_type;
+	unsigned long long ddp_maxbytes;
+	/* percentage of available space to reserve for grant error margin */
+	int		ddp_grant_reserved;
+	/* per-inode space consumption */
+	short	      ddp_inodespace;
+	/* per-fragment grant overhead to be used by client for grant
+	 * calculation */
+	int		ddp_grant_frag;
+};
+
+/**
+ * Per-transaction commit callback function
+ */
+struct dt_txn_commit_cb;
+typedef void (*dt_cb_t)(struct lu_env *env, struct thandle *th,
+			struct dt_txn_commit_cb *cb, int err);
+/**
+ * Special per-transaction callback for cases when just commit callback
+ * is needed and per-device callback are not convenient to use
+ */
+#define TRANS_COMMIT_CB_MAGIC	0xa0a00a0a
+#define MAX_COMMIT_CB_STR_LEN	32
+
+struct dt_txn_commit_cb {
+	struct list_head	dcb_linkage;
+	dt_cb_t		dcb_func;
+	__u32		dcb_magic;
+	char		dcb_name[MAX_COMMIT_CB_STR_LEN];
+};
+
+/**
+ * Operations on dt device.
+ */
+struct dt_device_operations {
+	/**
+	 * Return device-wide statistics.
+	 */
+	int   (*dt_statfs)(const struct lu_env *env,
+			   struct dt_device *dev, struct obd_statfs *osfs);
+	/**
+	 * Create transaction, described by \a param.
+	 */
+	struct thandle *(*dt_trans_create)(const struct lu_env *env,
+					   struct dt_device *dev);
+	/**
+	 * Start transaction, described by \a param.
+	 */
+	int   (*dt_trans_start)(const struct lu_env *env,
+				struct dt_device *dev, struct thandle *th);
+	/**
+	 * Finish previously started transaction.
+	 */
+	int   (*dt_trans_stop)(const struct lu_env *env,
+			       struct thandle *th);
+	/**
+	 * Add commit callback to the transaction.
+	 */
+	int   (*dt_trans_cb_add)(struct thandle *th,
+				 struct dt_txn_commit_cb *dcb);
+	/**
+	 * Return fid of root index object.
+	 */
+	int   (*dt_root_get)(const struct lu_env *env,
+			     struct dt_device *dev, struct lu_fid *f);
+	/**
+	 * Return device configuration data.
+	 */
+	void  (*dt_conf_get)(const struct lu_env *env,
+			     const struct dt_device *dev,
+			     struct dt_device_param *param);
+	/**
+	 *  handling device state, mostly for tests
+	 */
+	int   (*dt_sync)(const struct lu_env *env, struct dt_device *dev);
+	int   (*dt_ro)(const struct lu_env *env, struct dt_device *dev);
+	/**
+	  * Start a transaction commit asynchronously
+	  *
+	  * \param env environment
+	  * \param dev dt_device to start commit on
+	  *
+	  * \return 0 success, negative value if error
+	  */
+	 int   (*dt_commit_async)(const struct lu_env *env,
+				  struct dt_device *dev);
+	/**
+	 * Initialize capability context.
+	 */
+	int   (*dt_init_capa_ctxt)(const struct lu_env *env,
+				   struct dt_device *dev,
+				   int mode, unsigned long timeout,
+				   __u32 alg, struct lustre_capa_key *keys);
+};
+
+struct dt_index_features {
+	/** required feature flags from enum dt_index_flags */
+	__u32 dif_flags;
+	/** minimal required key size */
+	size_t dif_keysize_min;
+	/** maximal required key size, 0 if no limit */
+	size_t dif_keysize_max;
+	/** minimal required record size */
+	size_t dif_recsize_min;
+	/** maximal required record size, 0 if no limit */
+	size_t dif_recsize_max;
+	/** pointer size for record */
+	size_t dif_ptrsize;
+};
+
+enum dt_index_flags {
+	/** index supports variable sized keys */
+	DT_IND_VARKEY = 1 << 0,
+	/** index supports variable sized records */
+	DT_IND_VARREC = 1 << 1,
+	/** index can be modified */
+	DT_IND_UPDATE = 1 << 2,
+	/** index supports records with non-unique (duplicate) keys */
+	DT_IND_NONUNQ = 1 << 3,
+	/**
+	 * index support fixed-size keys sorted with natural numerical way
+	 * and is able to return left-side value if no exact value found
+	 */
+	DT_IND_RANGE = 1 << 4,
+};
+
+/**
+ * Features, required from index to support file system directories (mapping
+ * names to fids).
+ */
+extern const struct dt_index_features dt_directory_features;
+extern const struct dt_index_features dt_otable_features;
+extern const struct dt_index_features dt_lfsck_features;
+
+/* index features supported by the accounting objects */
+extern const struct dt_index_features dt_acct_features;
+
+/* index features supported by the quota global indexes */
+extern const struct dt_index_features dt_quota_glb_features;
+
+/* index features supported by the quota slave indexes */
+extern const struct dt_index_features dt_quota_slv_features;
+
+/**
+ * This is a general purpose dt allocation hint.
+ * It now contains the parent object.
+ * It can contain any allocation hint in the future.
+ */
+struct dt_allocation_hint {
+	struct dt_object	   *dah_parent;
+	__u32		       dah_mode;
+};
+
+/**
+ * object type specifier.
+ */
+
+enum dt_format_type {
+	DFT_REGULAR,
+	DFT_DIR,
+	/** for mknod */
+	DFT_NODE,
+	/** for special index */
+	DFT_INDEX,
+	/** for symbolic link */
+	DFT_SYM,
+};
+
+/**
+ * object format specifier.
+ */
+struct dt_object_format {
+	/** type for dt object */
+	enum dt_format_type dof_type;
+	union {
+		struct dof_regular {
+			int striped;
+		} dof_reg;
+		struct dof_dir {
+		} dof_dir;
+		struct dof_node {
+		} dof_node;
+		/**
+		 * special index need feature as parameter to create
+		 * special idx
+		 */
+		struct dof_index {
+			const struct dt_index_features *di_feat;
+		} dof_idx;
+	} u;
+};
+
+enum dt_format_type dt_mode_to_dft(__u32 mode);
+
+typedef __u64 dt_obj_version_t;
+
+/**
+ * Per-dt-object operations.
+ */
+struct dt_object_operations {
+	void  (*do_read_lock)(const struct lu_env *env,
+			      struct dt_object *dt, unsigned role);
+	void  (*do_write_lock)(const struct lu_env *env,
+			       struct dt_object *dt, unsigned role);
+	void  (*do_read_unlock)(const struct lu_env *env,
+				struct dt_object *dt);
+	void  (*do_write_unlock)(const struct lu_env *env,
+				 struct dt_object *dt);
+	int  (*do_write_locked)(const struct lu_env *env,
+				struct dt_object *dt);
+	/**
+	 * Note: following ->do_{x,}attr_{set,get}() operations are very
+	 * similar to ->moo_{x,}attr_{set,get}() operations in struct
+	 * md_object_operations (see md_object.h). These operations are not in
+	 * lu_object_operations, because ->do_{x,}attr_set() versions take
+	 * transaction handle as an argument (this transaction is started by
+	 * caller). We might factor ->do_{x,}attr_get() into
+	 * lu_object_operations, but that would break existing symmetry.
+	 */
+
+	/**
+	 * Return standard attributes.
+	 *
+	 * precondition: lu_object_exists(&dt->do_lu);
+	 */
+	int   (*do_attr_get)(const struct lu_env *env,
+			     struct dt_object *dt, struct lu_attr *attr,
+			     struct lustre_capa *capa);
+	/**
+	 * Set standard attributes.
+	 *
+	 * precondition: dt_object_exists(dt);
+	 */
+	int   (*do_declare_attr_set)(const struct lu_env *env,
+				     struct dt_object *dt,
+				     const struct lu_attr *attr,
+				     struct thandle *handle);
+	int   (*do_attr_set)(const struct lu_env *env,
+			     struct dt_object *dt,
+			     const struct lu_attr *attr,
+			     struct thandle *handle,
+			     struct lustre_capa *capa);
+	/**
+	 * Return a value of an extended attribute.
+	 *
+	 * precondition: dt_object_exists(dt);
+	 */
+	int   (*do_xattr_get)(const struct lu_env *env, struct dt_object *dt,
+			      struct lu_buf *buf, const char *name,
+			      struct lustre_capa *capa);
+	/**
+	 * Set value of an extended attribute.
+	 *
+	 * \a fl - flags from enum lu_xattr_flags
+	 *
+	 * precondition: dt_object_exists(dt);
+	 */
+	int   (*do_declare_xattr_set)(const struct lu_env *env,
+				      struct dt_object *dt,
+				      const struct lu_buf *buf,
+				      const char *name, int fl,
+				      struct thandle *handle);
+	int   (*do_xattr_set)(const struct lu_env *env,
+			      struct dt_object *dt, const struct lu_buf *buf,
+			      const char *name, int fl, struct thandle *handle,
+			      struct lustre_capa *capa);
+	/**
+	 * Delete existing extended attribute.
+	 *
+	 * precondition: dt_object_exists(dt);
+	 */
+	int   (*do_declare_xattr_del)(const struct lu_env *env,
+				      struct dt_object *dt,
+				      const char *name, struct thandle *handle);
+	int   (*do_xattr_del)(const struct lu_env *env,
+			      struct dt_object *dt,
+			      const char *name, struct thandle *handle,
+			      struct lustre_capa *capa);
+	/**
+	 * Place list of existing extended attributes into \a buf (which has
+	 * length len).
+	 *
+	 * precondition: dt_object_exists(dt);
+	 */
+	int   (*do_xattr_list)(const struct lu_env *env,
+			       struct dt_object *dt, struct lu_buf *buf,
+			       struct lustre_capa *capa);
+	/**
+	 * Init allocation hint using parent object and child mode.
+	 * (1) The \a parent might be NULL if this is a partial creation for
+	 *     remote object.
+	 * (2) The type of child is in \a child_mode.
+	 * (3) The result hint is stored in \a ah;
+	 */
+	void  (*do_ah_init)(const struct lu_env *env,
+			    struct dt_allocation_hint *ah,
+			    struct dt_object *parent,
+			    struct dt_object *child,
+			    umode_t child_mode);
+	/**
+	 * Create new object on this device.
+	 *
+	 * precondition: !dt_object_exists(dt);
+	 * postcondition: ergo(result == 0, dt_object_exists(dt));
+	 */
+	int   (*do_declare_create)(const struct lu_env *env,
+				   struct dt_object *dt,
+				   struct lu_attr *attr,
+				   struct dt_allocation_hint *hint,
+				   struct dt_object_format *dof,
+				   struct thandle *th);
+	int   (*do_create)(const struct lu_env *env, struct dt_object *dt,
+			   struct lu_attr *attr,
+			   struct dt_allocation_hint *hint,
+			   struct dt_object_format *dof,
+			   struct thandle *th);
+
+	/**
+	  Destroy object on this device
+	 * precondition: !dt_object_exists(dt);
+	 * postcondition: ergo(result == 0, dt_object_exists(dt));
+	 */
+	int   (*do_declare_destroy)(const struct lu_env *env,
+				    struct dt_object *dt,
+				    struct thandle *th);
+	int   (*do_destroy)(const struct lu_env *env, struct dt_object *dt,
+			    struct thandle *th);
+
+	/**
+	 * Announce that this object is going to be used as an index. This
+	 * operation check that object supports indexing operations and
+	 * installs appropriate dt_index_operations vector on success.
+	 *
+	 * Also probes for features. Operation is successful if all required
+	 * features are supported.
+	 */
+	int   (*do_index_try)(const struct lu_env *env,
+			      struct dt_object *dt,
+			      const struct dt_index_features *feat);
+	/**
+	 * Add nlink of the object
+	 * precondition: dt_object_exists(dt);
+	 */
+	int   (*do_declare_ref_add)(const struct lu_env *env,
+				    struct dt_object *dt, struct thandle *th);
+	int   (*do_ref_add)(const struct lu_env *env,
+			    struct dt_object *dt, struct thandle *th);
+	/**
+	 * Del nlink of the object
+	 * precondition: dt_object_exists(dt);
+	 */
+	int   (*do_declare_ref_del)(const struct lu_env *env,
+				    struct dt_object *dt, struct thandle *th);
+	int   (*do_ref_del)(const struct lu_env *env,
+			    struct dt_object *dt, struct thandle *th);
+
+	struct obd_capa *(*do_capa_get)(const struct lu_env *env,
+					struct dt_object *dt,
+					struct lustre_capa *old,
+					__u64 opc);
+	int (*do_object_sync)(const struct lu_env *, struct dt_object *);
+	/**
+	 * Get object info of next level. Currently, only get inode from osd.
+	 * This is only used by quota b=16542
+	 * precondition: dt_object_exists(dt);
+	 */
+	int (*do_data_get)(const struct lu_env *env, struct dt_object *dt,
+			   void **data);
+
+	/**
+	 * Lock object.
+	 */
+	int (*do_object_lock)(const struct lu_env *env, struct dt_object *dt,
+			      struct lustre_handle *lh,
+			      struct ldlm_enqueue_info *einfo,
+			      void *policy);
+};
+
+/**
+ * Per-dt-object operations on "file body".
+ */
+struct dt_body_operations {
+	/**
+	 * precondition: dt_object_exists(dt);
+	 */
+	ssize_t (*dbo_read)(const struct lu_env *env, struct dt_object *dt,
+			    struct lu_buf *buf, loff_t *pos,
+			    struct lustre_capa *capa);
+	/**
+	 * precondition: dt_object_exists(dt);
+	 */
+	ssize_t (*dbo_declare_write)(const struct lu_env *env,
+				     struct dt_object *dt,
+				     const loff_t size, loff_t pos,
+				     struct thandle *handle);
+	ssize_t (*dbo_write)(const struct lu_env *env, struct dt_object *dt,
+			     const struct lu_buf *buf, loff_t *pos,
+			     struct thandle *handle, struct lustre_capa *capa,
+			     int ignore_quota);
+	/*
+	 * methods for zero-copy IO
+	 */
+
+	/*
+	 * precondition: dt_object_exists(dt);
+	 * returns:
+	 * < 0 - error code
+	 * = 0 - illegal
+	 * > 0 - number of local buffers prepared
+	 */
+	int (*dbo_bufs_get)(const struct lu_env *env, struct dt_object *dt,
+			    loff_t pos, ssize_t len, struct niobuf_local *lb,
+			    int rw, struct lustre_capa *capa);
+	/*
+	 * precondition: dt_object_exists(dt);
+	 */
+	int (*dbo_bufs_put)(const struct lu_env *env, struct dt_object *dt,
+			    struct niobuf_local *lb, int nr);
+	/*
+	 * precondition: dt_object_exists(dt);
+	 */
+	int (*dbo_write_prep)(const struct lu_env *env, struct dt_object *dt,
+			      struct niobuf_local *lb, int nr);
+	/*
+	 * precondition: dt_object_exists(dt);
+	 */
+	int (*dbo_declare_write_commit)(const struct lu_env *env,
+					struct dt_object *dt,
+					struct niobuf_local *,
+					int, struct thandle *);
+	/*
+	 * precondition: dt_object_exists(dt);
+	 */
+	int (*dbo_write_commit)(const struct lu_env *env, struct dt_object *dt,
+				struct niobuf_local *, int, struct thandle *);
+	/*
+	 * precondition: dt_object_exists(dt);
+	 */
+	int (*dbo_read_prep)(const struct lu_env *env, struct dt_object *dt,
+			     struct niobuf_local *lnb, int nr);
+	int (*dbo_fiemap_get)(const struct lu_env *env, struct dt_object *dt,
+			      struct ll_user_fiemap *fm);
+	/**
+	 * Punch object's content
+	 * precondition: regular object, not index
+	 */
+	int   (*dbo_declare_punch)(const struct lu_env *, struct dt_object *,
+				  __u64, __u64, struct thandle *th);
+	int   (*dbo_punch)(const struct lu_env *env, struct dt_object *dt,
+			  __u64 start, __u64 end, struct thandle *th,
+			  struct lustre_capa *capa);
+};
+
+/**
+ * Incomplete type of index record.
+ */
+struct dt_rec;
+
+/**
+ * Incomplete type of index key.
+ */
+struct dt_key;
+
+/**
+ * Incomplete type of dt iterator.
+ */
+struct dt_it;
+
+/**
+ * Per-dt-object operations on object as index.
+ */
+struct dt_index_operations {
+	/**
+	 * precondition: dt_object_exists(dt);
+	 */
+	int (*dio_lookup)(const struct lu_env *env, struct dt_object *dt,
+			  struct dt_rec *rec, const struct dt_key *key,
+			  struct lustre_capa *capa);
+	/**
+	 * precondition: dt_object_exists(dt);
+	 */
+	int (*dio_declare_insert)(const struct lu_env *env,
+				  struct dt_object *dt,
+				  const struct dt_rec *rec,
+				  const struct dt_key *key,
+				  struct thandle *handle);
+	int (*dio_insert)(const struct lu_env *env, struct dt_object *dt,
+			  const struct dt_rec *rec, const struct dt_key *key,
+			  struct thandle *handle, struct lustre_capa *capa,
+			  int ignore_quota);
+	/**
+	 * precondition: dt_object_exists(dt);
+	 */
+	int (*dio_declare_delete)(const struct lu_env *env,
+				  struct dt_object *dt,
+				  const struct dt_key *key,
+				  struct thandle *handle);
+	int (*dio_delete)(const struct lu_env *env, struct dt_object *dt,
+			  const struct dt_key *key, struct thandle *handle,
+			  struct lustre_capa *capa);
+	/**
+	 * Iterator interface
+	 */
+	struct dt_it_ops {
+		/**
+		 * Allocate and initialize new iterator.
+		 *
+		 * precondition: dt_object_exists(dt);
+		 */
+		struct dt_it *(*init)(const struct lu_env *env,
+				      struct dt_object *dt,
+				      __u32 attr,
+				      struct lustre_capa *capa);
+		void	  (*fini)(const struct lu_env *env,
+				      struct dt_it *di);
+		int	    (*get)(const struct lu_env *env,
+				      struct dt_it *di,
+				      const struct dt_key *key);
+		void	   (*put)(const struct lu_env *env,
+				      struct dt_it *di);
+		int	   (*next)(const struct lu_env *env,
+				      struct dt_it *di);
+		struct dt_key *(*key)(const struct lu_env *env,
+				      const struct dt_it *di);
+		int       (*key_size)(const struct lu_env *env,
+				      const struct dt_it *di);
+		int	    (*rec)(const struct lu_env *env,
+				      const struct dt_it *di,
+				      struct dt_rec *rec,
+				      __u32 attr);
+		__u64	(*store)(const struct lu_env *env,
+				      const struct dt_it *di);
+		int	   (*load)(const struct lu_env *env,
+				      const struct dt_it *di, __u64 hash);
+		int	(*key_rec)(const struct lu_env *env,
+				      const struct dt_it *di, void* key_rec);
+	} dio_it;
+};
+
+enum dt_otable_it_valid {
+	DOIV_ERROR_HANDLE	= 0x0001,
+};
+
+enum dt_otable_it_flags {
+	/* Exit when fail. */
+	DOIF_FAILOUT	= 0x0001,
+
+	/* Reset iteration position to the device beginning. */
+	DOIF_RESET	= 0x0002,
+
+	/* There is up layer component uses the iteration. */
+	DOIF_OUTUSED	= 0x0004,
+};
+
+/* otable based iteration needs to use the common DT interation APIs.
+ * To initialize the iteration, it needs call dio_it::init() firstly.
+ * Here is how the otable based iteration should prepare arguments to
+ * call dt_it_ops::init().
+ *
+ * For otable based iteration, the 32-bits 'attr' for dt_it_ops::init()
+ * is composed of two parts:
+ * low 16-bits is for valid bits, high 16-bits is for flags bits. */
+#define DT_OTABLE_IT_FLAGS_SHIFT	16
+#define DT_OTABLE_IT_FLAGS_MASK 	0xffff0000
+
+struct dt_device {
+	struct lu_device		   dd_lu_dev;
+	const struct dt_device_operations *dd_ops;
+
+	/**
+	 * List of dt_txn_callback (see below). This is not protected in any
+	 * way, because callbacks are supposed to be added/deleted only during
+	 * single-threaded start-up shut-down procedures.
+	 */
+	struct list_head			 dd_txn_callbacks;
+};
+
+int  dt_device_init(struct dt_device *dev, struct lu_device_type *t);
+void dt_device_fini(struct dt_device *dev);
+
+static inline int lu_device_is_dt(const struct lu_device *d)
+{
+	return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_DT);
+}
+
+static inline struct dt_device * lu2dt_dev(struct lu_device *l)
+{
+	LASSERT(lu_device_is_dt(l));
+	return container_of0(l, struct dt_device, dd_lu_dev);
+}
+
+struct dt_object {
+	struct lu_object		   do_lu;
+	const struct dt_object_operations *do_ops;
+	const struct dt_body_operations   *do_body_ops;
+	const struct dt_index_operations  *do_index_ops;
+};
+
+/*
+ * In-core representation of per-device local object OID storage
+ */
+struct local_oid_storage {
+	/* all initialized llog systems on this node linked by this */
+	struct list_head	  los_list;
+
+	/* how many handle's reference this los has */
+	atomic_t	  los_refcount;
+	struct dt_device *los_dev;
+	struct dt_object *los_obj;
+
+	/* data used to generate new fids */
+	struct mutex	 los_id_lock;
+	__u64		  los_seq;
+	__u32		  los_last_oid;
+};
+
+static inline struct dt_object *lu2dt(struct lu_object *l)
+{
+	LASSERT(l == NULL || IS_ERR(l) || lu_device_is_dt(l->lo_dev));
+	return container_of0(l, struct dt_object, do_lu);
+}
+
+int  dt_object_init(struct dt_object *obj,
+		    struct lu_object_header *h, struct lu_device *d);
+
+void dt_object_fini(struct dt_object *obj);
+
+static inline int dt_object_exists(const struct dt_object *dt)
+{
+	return lu_object_exists(&dt->do_lu);
+}
+
+static inline int dt_object_remote(const struct dt_object *dt)
+{
+	return lu_object_remote(&dt->do_lu);
+}
+
+static inline struct dt_object *lu2dt_obj(struct lu_object *o)
+{
+	LASSERT(ergo(o != NULL, lu_device_is_dt(o->lo_dev)));
+	return container_of0(o, struct dt_object, do_lu);
+}
+
+/**
+ * This is the general purpose transaction handle.
+ * 1. Transaction Life Cycle
+ *      This transaction handle is allocated upon starting a new transaction,
+ *      and deallocated after this transaction is committed.
+ * 2. Transaction Nesting
+ *      We do _NOT_ support nested transaction. So, every thread should only
+ *      have one active transaction, and a transaction only belongs to one
+ *      thread. Due to this, transaction handle need no reference count.
+ * 3. Transaction & dt_object locking
+ *      dt_object locks should be taken inside transaction.
+ * 4. Transaction & RPC
+ *      No RPC request should be issued inside transaction.
+ */
+struct thandle {
+	/** the dt device on which the transactions are executed */
+	struct dt_device *th_dev;
+
+	/** context for this transaction, tag is LCT_TX_HANDLE */
+	struct lu_context th_ctx;
+
+	/** additional tags (layers can add in declare) */
+	__u32	     th_tags;
+
+	/** the last operation result in this transaction.
+	 * this value is used in recovery */
+	__s32	     th_result;
+
+	/** whether we need sync commit */
+	unsigned int		th_sync:1;
+
+	/* local transation, no need to inform other layers */
+	unsigned int		th_local:1;
+
+	/* In DNE, one transaction can be disassemblied into
+	 * updates on several different MDTs, and these updates
+	 * will be attached to th_remote_update_list per target.
+	 * Only single thread will access the list, no need lock
+	 */
+	struct list_head		th_remote_update_list;
+	struct update_request	*th_current_request;
+};
+
+/**
+ * Transaction call-backs.
+ *
+ * These are invoked by osd (or underlying transaction engine) when
+ * transaction changes state.
+ *
+ * Call-backs are used by upper layers to modify transaction parameters and to
+ * perform some actions on for each transaction state transition. Typical
+ * example is mdt registering call-back to write into last-received file
+ * before each transaction commit.
+ */
+struct dt_txn_callback {
+	int (*dtc_txn_start)(const struct lu_env *env,
+			     struct thandle *txn, void *cookie);
+	int (*dtc_txn_stop)(const struct lu_env *env,
+			    struct thandle *txn, void *cookie);
+	void (*dtc_txn_commit)(struct thandle *txn, void *cookie);
+	void		*dtc_cookie;
+	__u32		dtc_tag;
+	struct list_head	   dtc_linkage;
+};
+
+void dt_txn_callback_add(struct dt_device *dev, struct dt_txn_callback *cb);
+void dt_txn_callback_del(struct dt_device *dev, struct dt_txn_callback *cb);
+
+int dt_txn_hook_start(const struct lu_env *env,
+		      struct dt_device *dev, struct thandle *txn);
+int dt_txn_hook_stop(const struct lu_env *env, struct thandle *txn);
+void dt_txn_hook_commit(struct thandle *txn);
+
+int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj);
+
+/**
+ * Callback function used for parsing path.
+ * \see llo_store_resolve
+ */
+typedef int (*dt_entry_func_t)(const struct lu_env *env,
+			    const char *name,
+			    void *pvt);
+
+#define DT_MAX_PATH 1024
+
+int dt_path_parser(const struct lu_env *env,
+		   char *local, dt_entry_func_t entry_func,
+		   void *data);
+
+struct dt_object *
+dt_store_resolve(const struct lu_env *env, struct dt_device *dt,
+		 const char *path, struct lu_fid *fid);
+
+struct dt_object *dt_store_open(const struct lu_env *env,
+				struct dt_device *dt,
+				const char *dirname,
+				const char *filename,
+				struct lu_fid *fid);
+
+struct dt_object *dt_find_or_create(const struct lu_env *env,
+				    struct dt_device *dt,
+				    const struct lu_fid *fid,
+				    struct dt_object_format *dof,
+				    struct lu_attr *attr);
+
+struct dt_object *dt_locate_at(const struct lu_env *env,
+			       struct dt_device *dev,
+			       const struct lu_fid *fid,
+			       struct lu_device *top_dev);
+static inline struct dt_object *
+dt_locate(const struct lu_env *env, struct dt_device *dev,
+	  const struct lu_fid *fid)
+{
+	return dt_locate_at(env, dev, fid, dev->dd_lu_dev.ld_site->ls_top_dev);
+}
+
+
+int local_oid_storage_init(const struct lu_env *env, struct dt_device *dev,
+			   const struct lu_fid *first_fid,
+			   struct local_oid_storage **los);
+void local_oid_storage_fini(const struct lu_env *env,
+			    struct local_oid_storage *los);
+int local_object_fid_generate(const struct lu_env *env,
+			      struct local_oid_storage *los,
+			      struct lu_fid *fid);
+int local_object_declare_create(const struct lu_env *env,
+				struct local_oid_storage *los,
+				struct dt_object *o,
+				struct lu_attr *attr,
+				struct dt_object_format *dof,
+				struct thandle *th);
+int local_object_create(const struct lu_env *env,
+			struct local_oid_storage *los,
+			struct dt_object *o,
+			struct lu_attr *attr, struct dt_object_format *dof,
+			struct thandle *th);
+struct dt_object *local_file_find_or_create(const struct lu_env *env,
+					    struct local_oid_storage *los,
+					    struct dt_object *parent,
+					    const char *name, __u32 mode);
+struct dt_object *local_file_find_or_create_with_fid(const struct lu_env *env,
+						     struct dt_device *dt,
+						     const struct lu_fid *fid,
+						     struct dt_object *parent,
+						     const char *name,
+						     __u32 mode);
+struct dt_object *
+local_index_find_or_create(const struct lu_env *env,
+			   struct local_oid_storage *los,
+			   struct dt_object *parent,
+			   const char *name, __u32 mode,
+			   const struct dt_index_features *ft);
+struct dt_object *
+local_index_find_or_create_with_fid(const struct lu_env *env,
+				    struct dt_device *dt,
+				    const struct lu_fid *fid,
+				    struct dt_object *parent,
+				    const char *name, __u32 mode,
+				    const struct dt_index_features *ft);
+int local_object_unlink(const struct lu_env *env, struct dt_device *dt,
+			struct dt_object *parent, const char *name);
+
+static inline int dt_object_lock(const struct lu_env *env,
+				 struct dt_object *o, struct lustre_handle *lh,
+				 struct ldlm_enqueue_info *einfo,
+				 void *policy)
+{
+	LASSERT(o);
+	LASSERT(o->do_ops);
+	LASSERT(o->do_ops->do_object_lock);
+	return o->do_ops->do_object_lock(env, o, lh, einfo, policy);
+}
+
+int dt_lookup_dir(const struct lu_env *env, struct dt_object *dir,
+		  const char *name, struct lu_fid *fid);
+
+static inline int dt_object_sync(const struct lu_env *env,
+				 struct dt_object *o)
+{
+	LASSERT(o);
+	LASSERT(o->do_ops);
+	LASSERT(o->do_ops->do_object_sync);
+	return o->do_ops->do_object_sync(env, o);
+}
+
+int dt_declare_version_set(const struct lu_env *env, struct dt_object *o,
+			   struct thandle *th);
+void dt_version_set(const struct lu_env *env, struct dt_object *o,
+		    dt_obj_version_t version, struct thandle *th);
+dt_obj_version_t dt_version_get(const struct lu_env *env, struct dt_object *o);
+
+
+int dt_read(const struct lu_env *env, struct dt_object *dt,
+	    struct lu_buf *buf, loff_t *pos);
+int dt_record_read(const struct lu_env *env, struct dt_object *dt,
+		   struct lu_buf *buf, loff_t *pos);
+int dt_record_write(const struct lu_env *env, struct dt_object *dt,
+		    const struct lu_buf *buf, loff_t *pos, struct thandle *th);
+typedef int (*dt_index_page_build_t)(const struct lu_env *env,
+				     union lu_page *lp, int nob,
+				     const struct dt_it_ops *iops,
+				     struct dt_it *it, __u32 attr, void *arg);
+int dt_index_walk(const struct lu_env *env, struct dt_object *obj,
+		  const struct lu_rdpg *rdpg, dt_index_page_build_t filler,
+		  void *arg);
+int dt_index_read(const struct lu_env *env, struct dt_device *dev,
+		  struct idx_info *ii, const struct lu_rdpg *rdpg);
+
+static inline struct thandle *dt_trans_create(const struct lu_env *env,
+					      struct dt_device *d)
+{
+	LASSERT(d->dd_ops->dt_trans_create);
+	return d->dd_ops->dt_trans_create(env, d);
+}
+
+static inline int dt_trans_start(const struct lu_env *env,
+				 struct dt_device *d, struct thandle *th)
+{
+	LASSERT(d->dd_ops->dt_trans_start);
+	return d->dd_ops->dt_trans_start(env, d, th);
+}
+
+/* for this transaction hooks shouldn't be called */
+static inline int dt_trans_start_local(const struct lu_env *env,
+				       struct dt_device *d, struct thandle *th)
+{
+	LASSERT(d->dd_ops->dt_trans_start);
+	th->th_local = 1;
+	return d->dd_ops->dt_trans_start(env, d, th);
+}
+
+static inline int dt_trans_stop(const struct lu_env *env,
+				struct dt_device *d, struct thandle *th)
+{
+	LASSERT(d->dd_ops->dt_trans_stop);
+	return d->dd_ops->dt_trans_stop(env, th);
+}
+
+static inline int dt_trans_cb_add(struct thandle *th,
+				  struct dt_txn_commit_cb *dcb)
+{
+	LASSERT(th->th_dev->dd_ops->dt_trans_cb_add);
+	dcb->dcb_magic = TRANS_COMMIT_CB_MAGIC;
+	return th->th_dev->dd_ops->dt_trans_cb_add(th, dcb);
+}
+/** @} dt */
+
+
+static inline int dt_declare_record_write(const struct lu_env *env,
+					  struct dt_object *dt,
+					  int size, loff_t pos,
+					  struct thandle *th)
+{
+	int rc;
+
+	LASSERTF(dt != NULL, "dt is NULL when we want to write record\n");
+	LASSERT(th != NULL);
+	LASSERT(dt->do_body_ops);
+	LASSERT(dt->do_body_ops->dbo_declare_write);
+	rc = dt->do_body_ops->dbo_declare_write(env, dt, size, pos, th);
+	return rc;
+}
+
+static inline int dt_declare_create(const struct lu_env *env,
+				    struct dt_object *dt,
+				    struct lu_attr *attr,
+				    struct dt_allocation_hint *hint,
+				    struct dt_object_format *dof,
+				    struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_declare_create);
+	return dt->do_ops->do_declare_create(env, dt, attr, hint, dof, th);
+}
+
+static inline int dt_create(const struct lu_env *env,
+				    struct dt_object *dt,
+				    struct lu_attr *attr,
+				    struct dt_allocation_hint *hint,
+				    struct dt_object_format *dof,
+				    struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_create);
+	return dt->do_ops->do_create(env, dt, attr, hint, dof, th);
+}
+
+static inline int dt_declare_destroy(const struct lu_env *env,
+				     struct dt_object *dt,
+				     struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_declare_destroy);
+	return dt->do_ops->do_declare_destroy(env, dt, th);
+}
+
+static inline int dt_destroy(const struct lu_env *env,
+			     struct dt_object *dt,
+			     struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_destroy);
+	return dt->do_ops->do_destroy(env, dt, th);
+}
+
+static inline void dt_read_lock(const struct lu_env *env,
+				struct dt_object *dt,
+				unsigned role)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_read_lock);
+	dt->do_ops->do_read_lock(env, dt, role);
+}
+
+static inline void dt_write_lock(const struct lu_env *env,
+				struct dt_object *dt,
+				unsigned role)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_write_lock);
+	dt->do_ops->do_write_lock(env, dt, role);
+}
+
+static inline void dt_read_unlock(const struct lu_env *env,
+				struct dt_object *dt)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_read_unlock);
+	dt->do_ops->do_read_unlock(env, dt);
+}
+
+static inline void dt_write_unlock(const struct lu_env *env,
+				struct dt_object *dt)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_write_unlock);
+	dt->do_ops->do_write_unlock(env, dt);
+}
+
+static inline int dt_write_locked(const struct lu_env *env,
+				  struct dt_object *dt)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_write_locked);
+	return dt->do_ops->do_write_locked(env, dt);
+}
+
+static inline int dt_attr_get(const struct lu_env *env, struct dt_object *dt,
+			      struct lu_attr *la, void *arg)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_attr_get);
+	return dt->do_ops->do_attr_get(env, dt, la, arg);
+}
+
+static inline int dt_declare_attr_set(const struct lu_env *env,
+				      struct dt_object *dt,
+				      const struct lu_attr *la,
+				      struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_declare_attr_set);
+	return dt->do_ops->do_declare_attr_set(env, dt, la, th);
+}
+
+static inline int dt_attr_set(const struct lu_env *env, struct dt_object *dt,
+			      const struct lu_attr *la, struct thandle *th,
+			      struct lustre_capa *capa)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_attr_set);
+	return dt->do_ops->do_attr_set(env, dt, la, th, capa);
+}
+
+static inline int dt_declare_ref_add(const struct lu_env *env,
+				     struct dt_object *dt, struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_declare_ref_add);
+	return dt->do_ops->do_declare_ref_add(env, dt, th);
+}
+
+static inline int dt_ref_add(const struct lu_env *env,
+			     struct dt_object *dt, struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_ref_add);
+	return dt->do_ops->do_ref_add(env, dt, th);
+}
+
+static inline int dt_declare_ref_del(const struct lu_env *env,
+				     struct dt_object *dt, struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_declare_ref_del);
+	return dt->do_ops->do_declare_ref_del(env, dt, th);
+}
+
+static inline int dt_ref_del(const struct lu_env *env,
+			     struct dt_object *dt, struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_ref_del);
+	return dt->do_ops->do_ref_del(env, dt, th);
+}
+
+static inline struct obd_capa *dt_capa_get(const struct lu_env *env,
+					   struct dt_object *dt,
+					   struct lustre_capa *old, __u64 opc)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_ref_del);
+	return dt->do_ops->do_capa_get(env, dt, old, opc);
+}
+
+static inline int dt_bufs_get(const struct lu_env *env, struct dt_object *d,
+			      struct niobuf_remote *rnb,
+			      struct niobuf_local *lnb, int rw,
+			      struct lustre_capa *capa)
+{
+	LASSERT(d);
+	LASSERT(d->do_body_ops);
+	LASSERT(d->do_body_ops->dbo_bufs_get);
+	return d->do_body_ops->dbo_bufs_get(env, d, rnb->offset,
+					    rnb->len, lnb, rw, capa);
+}
+
+static inline int dt_bufs_put(const struct lu_env *env, struct dt_object *d,
+			      struct niobuf_local *lnb, int n)
+{
+	LASSERT(d);
+	LASSERT(d->do_body_ops);
+	LASSERT(d->do_body_ops->dbo_bufs_put);
+	return d->do_body_ops->dbo_bufs_put(env, d, lnb, n);
+}
+
+static inline int dt_write_prep(const struct lu_env *env, struct dt_object *d,
+				struct niobuf_local *lnb, int n)
+{
+	LASSERT(d);
+	LASSERT(d->do_body_ops);
+	LASSERT(d->do_body_ops->dbo_write_prep);
+	return d->do_body_ops->dbo_write_prep(env, d, lnb, n);
+}
+
+static inline int dt_declare_write_commit(const struct lu_env *env,
+					  struct dt_object *d,
+					  struct niobuf_local *lnb,
+					  int n, struct thandle *th)
+{
+	LASSERTF(d != NULL, "dt is NULL when we want to declare write\n");
+	LASSERT(th != NULL);
+	return d->do_body_ops->dbo_declare_write_commit(env, d, lnb, n, th);
+}
+
+
+static inline int dt_write_commit(const struct lu_env *env,
+				  struct dt_object *d, struct niobuf_local *lnb,
+				  int n, struct thandle *th)
+{
+	LASSERT(d);
+	LASSERT(d->do_body_ops);
+	LASSERT(d->do_body_ops->dbo_write_commit);
+	return d->do_body_ops->dbo_write_commit(env, d, lnb, n, th);
+}
+
+static inline int dt_read_prep(const struct lu_env *env, struct dt_object *d,
+			       struct niobuf_local *lnb, int n)
+{
+	LASSERT(d);
+	LASSERT(d->do_body_ops);
+	LASSERT(d->do_body_ops->dbo_read_prep);
+	return d->do_body_ops->dbo_read_prep(env, d, lnb, n);
+}
+
+static inline int dt_declare_punch(const struct lu_env *env,
+				   struct dt_object *dt, __u64 start,
+				   __u64 end, struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_body_ops);
+	LASSERT(dt->do_body_ops->dbo_declare_punch);
+	return dt->do_body_ops->dbo_declare_punch(env, dt, start, end, th);
+}
+
+static inline int dt_punch(const struct lu_env *env, struct dt_object *dt,
+			   __u64 start, __u64 end, struct thandle *th,
+			   struct lustre_capa *capa)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_body_ops);
+	LASSERT(dt->do_body_ops->dbo_punch);
+	return dt->do_body_ops->dbo_punch(env, dt, start, end, th, capa);
+}
+
+static inline int dt_fiemap_get(const struct lu_env *env, struct dt_object *d,
+				struct ll_user_fiemap *fm)
+{
+	LASSERT(d);
+	if (d->do_body_ops == NULL)
+		return -EPROTO;
+	if (d->do_body_ops->dbo_fiemap_get == NULL)
+		return -EOPNOTSUPP;
+	return d->do_body_ops->dbo_fiemap_get(env, d, fm);
+}
+
+static inline int dt_statfs(const struct lu_env *env, struct dt_device *dev,
+			    struct obd_statfs *osfs)
+{
+	LASSERT(dev);
+	LASSERT(dev->dd_ops);
+	LASSERT(dev->dd_ops->dt_statfs);
+	return dev->dd_ops->dt_statfs(env, dev, osfs);
+}
+
+static inline int dt_root_get(const struct lu_env *env, struct dt_device *dev,
+			      struct lu_fid *f)
+{
+	LASSERT(dev);
+	LASSERT(dev->dd_ops);
+	LASSERT(dev->dd_ops->dt_root_get);
+	return dev->dd_ops->dt_root_get(env, dev, f);
+}
+
+static inline void dt_conf_get(const struct lu_env *env,
+			       const struct dt_device *dev,
+			       struct dt_device_param *param)
+{
+	LASSERT(dev);
+	LASSERT(dev->dd_ops);
+	LASSERT(dev->dd_ops->dt_conf_get);
+	return dev->dd_ops->dt_conf_get(env, dev, param);
+}
+
+static inline int dt_sync(const struct lu_env *env, struct dt_device *dev)
+{
+	LASSERT(dev);
+	LASSERT(dev->dd_ops);
+	LASSERT(dev->dd_ops->dt_sync);
+	return dev->dd_ops->dt_sync(env, dev);
+}
+
+static inline int dt_ro(const struct lu_env *env, struct dt_device *dev)
+{
+	LASSERT(dev);
+	LASSERT(dev->dd_ops);
+	LASSERT(dev->dd_ops->dt_ro);
+	return dev->dd_ops->dt_ro(env, dev);
+}
+
+static inline int dt_declare_insert(const struct lu_env *env,
+				    struct dt_object *dt,
+				    const struct dt_rec *rec,
+				    const struct dt_key *key,
+				    struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_index_ops);
+	LASSERT(dt->do_index_ops->dio_declare_insert);
+	return dt->do_index_ops->dio_declare_insert(env, dt, rec, key, th);
+}
+
+static inline int dt_insert(const struct lu_env *env,
+				    struct dt_object *dt,
+				    const struct dt_rec *rec,
+				    const struct dt_key *key,
+				    struct thandle *th,
+				    struct lustre_capa *capa,
+				    int noquota)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_index_ops);
+	LASSERT(dt->do_index_ops->dio_insert);
+	return dt->do_index_ops->dio_insert(env, dt, rec, key, th,
+					    capa, noquota);
+}
+
+static inline int dt_declare_xattr_del(const struct lu_env *env,
+				       struct dt_object *dt,
+				       const char *name,
+				       struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_declare_xattr_del);
+	return dt->do_ops->do_declare_xattr_del(env, dt, name, th);
+}
+
+static inline int dt_xattr_del(const struct lu_env *env,
+			       struct dt_object *dt, const char *name,
+			       struct thandle *th,
+			       struct lustre_capa *capa)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_xattr_del);
+	return dt->do_ops->do_xattr_del(env, dt, name, th, capa);
+}
+
+static inline int dt_declare_xattr_set(const struct lu_env *env,
+				      struct dt_object *dt,
+				      const struct lu_buf *buf,
+				      const char *name, int fl,
+				      struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_declare_xattr_set);
+	return dt->do_ops->do_declare_xattr_set(env, dt, buf, name, fl, th);
+}
+
+static inline int dt_xattr_set(const struct lu_env *env,
+			      struct dt_object *dt, const struct lu_buf *buf,
+			      const char *name, int fl, struct thandle *th,
+			      struct lustre_capa *capa)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_xattr_set);
+	return dt->do_ops->do_xattr_set(env, dt, buf, name, fl, th, capa);
+}
+
+static inline int dt_xattr_get(const struct lu_env *env,
+			      struct dt_object *dt, struct lu_buf *buf,
+			      const char *name, struct lustre_capa *capa)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_xattr_get);
+	return dt->do_ops->do_xattr_get(env, dt, buf, name, capa);
+}
+
+static inline int dt_xattr_list(const struct lu_env *env,
+			       struct dt_object *dt, struct lu_buf *buf,
+			       struct lustre_capa *capa)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_ops);
+	LASSERT(dt->do_ops->do_xattr_list);
+	return dt->do_ops->do_xattr_list(env, dt, buf, capa);
+}
+
+static inline int dt_declare_delete(const struct lu_env *env,
+				    struct dt_object *dt,
+				    const struct dt_key *key,
+				    struct thandle *th)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_index_ops);
+	LASSERT(dt->do_index_ops->dio_declare_delete);
+	return dt->do_index_ops->dio_declare_delete(env, dt, key, th);
+}
+
+static inline int dt_delete(const struct lu_env *env,
+			    struct dt_object *dt,
+			    const struct dt_key *key,
+			    struct thandle *th,
+			    struct lustre_capa *capa)
+{
+	LASSERT(dt);
+	LASSERT(dt->do_index_ops);
+	LASSERT(dt->do_index_ops->dio_delete);
+	return dt->do_index_ops->dio_delete(env, dt, key, th, capa);
+}
+
+static inline int dt_commit_async(const struct lu_env *env,
+				  struct dt_device *dev)
+{
+	LASSERT(dev);
+	LASSERT(dev->dd_ops);
+	LASSERT(dev->dd_ops->dt_commit_async);
+	return dev->dd_ops->dt_commit_async(env, dev);
+}
+
+static inline int dt_init_capa_ctxt(const struct lu_env *env,
+				    struct dt_device *dev,
+				    int mode, unsigned long timeout,
+				    __u32 alg, struct lustre_capa_key *keys)
+{
+	LASSERT(dev);
+	LASSERT(dev->dd_ops);
+	LASSERT(dev->dd_ops->dt_init_capa_ctxt);
+	return dev->dd_ops->dt_init_capa_ctxt(env, dev, mode,
+					      timeout, alg, keys);
+}
+
+static inline int dt_lookup(const struct lu_env *env,
+			    struct dt_object *dt,
+			    struct dt_rec *rec,
+			    const struct dt_key *key,
+			    struct lustre_capa *capa)
+{
+	int ret;
+
+	LASSERT(dt);
+	LASSERT(dt->do_index_ops);
+	LASSERT(dt->do_index_ops->dio_lookup);
+
+	ret = dt->do_index_ops->dio_lookup(env, dt, rec, key, capa);
+	if (ret > 0)
+		ret = 0;
+	else if (ret == 0)
+		ret = -ENOENT;
+	return ret;
+}
+
+#define LU221_BAD_TIME (0x80000000U + 24 * 3600)
+
+struct dt_find_hint {
+	struct lu_fid	*dfh_fid;
+	struct dt_device     *dfh_dt;
+	struct dt_object     *dfh_o;
+};
+
+struct dt_thread_info {
+	char		     dti_buf[DT_MAX_PATH];
+	struct dt_find_hint      dti_dfh;
+	struct lu_attr	   dti_attr;
+	struct lu_fid	    dti_fid;
+	struct dt_object_format  dti_dof;
+	struct lustre_mdt_attrs  dti_lma;
+	struct lu_buf	    dti_lb;
+	loff_t		   dti_off;
+};
+
+extern struct lu_context_key dt_key;
+
+static inline struct dt_thread_info *dt_info(const struct lu_env *env)
+{
+	struct dt_thread_info *dti;
+
+	dti = lu_context_key_get(&env->le_ctx, &dt_key);
+	LASSERT(dti);
+	return dti;
+}
+
+int dt_global_init(void);
+void dt_global_fini(void);
+
+# ifdef LPROCFS
+int lprocfs_dt_rd_blksize(char *page, char **start, off_t off,
+			  int count, int *eof, void *data);
+int lprocfs_dt_rd_kbytestotal(char *page, char **start, off_t off,
+			      int count, int *eof, void *data);
+int lprocfs_dt_rd_kbytesfree(char *page, char **start, off_t off,
+			     int count, int *eof, void *data);
+int lprocfs_dt_rd_kbytesavail(char *page, char **start, off_t off,
+			      int count, int *eof, void *data);
+int lprocfs_dt_rd_filestotal(char *page, char **start, off_t off,
+			     int count, int *eof, void *data);
+int lprocfs_dt_rd_filesfree(char *page, char **start, off_t off,
+			    int count, int *eof, void *data);
+# endif /* LPROCFS */
+
+#endif /* __LUSTRE_DT_OBJECT_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/interval_tree.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/interval_tree.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/interval_tree.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/interval_tree.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,124 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/interval_tree.h
+ *
+ * Author: Huang Wei <huangwei@clusterfs.com>
+ * Author: Jay Xiong <jinshan.xiong@sun.com>
+ */
+
+#ifndef _INTERVAL_H__
+#define _INTERVAL_H__
+
+#include <linux/libcfs/libcfs.h>   /* LASSERT. */
+
+struct interval_node {
+	struct interval_node   *in_left;
+	struct interval_node   *in_right;
+	struct interval_node   *in_parent;
+	unsigned		in_color:1,
+				in_intree:1, /** set if the node is in tree */
+				in_res1:30;
+	__u8		    in_res2[4];  /** tags, 8-bytes aligned */
+	__u64		   in_max_high;
+	struct interval_node_extent {
+		__u64 start;
+		__u64 end;
+	} in_extent;
+};
+
+enum interval_iter {
+	INTERVAL_ITER_CONT = 1,
+	INTERVAL_ITER_STOP = 2
+};
+
+static inline int interval_is_intree(struct interval_node *node)
+{
+	return node->in_intree == 1;
+}
+
+static inline __u64 interval_low(struct interval_node *node)
+{
+	return node->in_extent.start;
+}
+
+static inline __u64 interval_high(struct interval_node *node)
+{
+	return node->in_extent.end;
+}
+
+static inline void interval_set(struct interval_node *node,
+				__u64 start, __u64 end)
+{
+	LASSERT(start <= end);
+	node->in_extent.start = start;
+	node->in_extent.end = end;
+	node->in_max_high = end;
+}
+
+/* Rules to write an interval callback.
+ *  - the callback returns INTERVAL_ITER_STOP when it thinks the iteration
+ *    should be stopped. It will then cause the iteration function to return
+ *    immediately with return value INTERVAL_ITER_STOP.
+ *  - callbacks for interval_iterate and interval_iterate_reverse: Every
+ *    nodes in the tree will be set to @node before the callback being called
+ *  - callback for interval_search: Only overlapped node will be set to @node
+ *    before the callback being called.
+ */
+typedef enum interval_iter (*interval_callback_t)(struct interval_node *node,
+						  void *args);
+
+struct interval_node *interval_insert(struct interval_node *node,
+				      struct interval_node **root);
+void interval_erase(struct interval_node *node, struct interval_node **root);
+
+/* Search the extents in the tree and call @func for each overlapped
+ * extents. */
+enum interval_iter interval_search(struct interval_node *root,
+				   struct interval_node_extent *ex,
+				   interval_callback_t func, void *data);
+
+/* Iterate every node in the tree - by reverse order or regular order. */
+enum interval_iter interval_iterate(struct interval_node *root,
+				    interval_callback_t func, void *data);
+enum interval_iter interval_iterate_reverse(struct interval_node *root,
+				    interval_callback_t func,void *data);
+
+void interval_expand(struct interval_node *root,
+		     struct interval_node_extent *ext,
+		     struct interval_node_extent *limiter);
+int interval_is_overlapped(struct interval_node *root,
+			   struct interval_node_extent *ex);
+struct interval_node *interval_find(struct interval_node *root,
+				    struct interval_node_extent *ex);
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/ioctl.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/ioctl.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/ioctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/ioctl.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,106 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _IOWR
+
+/* On i386 and x86_64, _ASM_I386_IOCTL_H is defined by the kernel's ioctl.h,
+ * and on newer kernels this header is shared as _ASM_GENERIC_IOCTL_H.
+ *
+ * We can avoid any problems with the kernel header being included again by
+ * defining _ASM_I386_IOCTL_H here so that a later occurence of <asm/ioctl.h>
+ * does not include the kernel's ioctl.h after this one. b=14746 */
+#define _ASM_I386_IOCTL_H
+#define _ASM_GENERIC_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS     8
+#define _IOC_TYPEBITS   8
+#define _IOC_SIZEBITS   14
+#define _IOC_DIRBITS    2
+
+#define _IOC_NRMASK     ((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK   ((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK   ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK    ((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT    0
+#define _IOC_TYPESHIFT  (_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT  (_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT   (_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE       0U
+#define _IOC_WRITE      1U
+#define _IOC_READ       2U
+
+#define _IOC(dir,type,nr,size) (((dir)  << _IOC_DIRSHIFT) | ((type) << _IOC_TYPESHIFT) | ((nr)   << _IOC_NRSHIFT) | ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)	    _IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)      _IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)      _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)     _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)	    (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)	   (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)	     (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)	   (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN	  (_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT	 (_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT       ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK    (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT   (_IOC_SIZESHIFT)
+
+#endif /* _IOWR */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lclient.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lclient.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lclient.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lclient.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,437 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * Definitions shared between vvp and liblustre, and other clients in the
+ * future.
+ *
+ *   Author: Oleg Drokin <oleg.drokin@sun.com>
+ *   Author: Nikita Danilov <nikita.danilov@sun.com>
+ */
+
+#ifndef LCLIENT_H
+#define LCLIENT_H
+
+blkcnt_t dirty_cnt(struct inode *inode);
+
+int cl_glimpse_size0(struct inode *inode, int agl);
+int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io,
+		    struct inode *inode, struct cl_object *clob, int agl);
+
+static inline int cl_glimpse_size(struct inode *inode)
+{
+	return cl_glimpse_size0(inode, 0);
+}
+
+static inline int cl_agl(struct inode *inode)
+{
+	return cl_glimpse_size0(inode, 1);
+}
+
+/**
+ * Locking policy for setattr.
+ */
+enum ccc_setattr_lock_type {
+	/** Locking is done by server */
+	SETATTR_NOLOCK,
+	/** Extent lock is enqueued */
+	SETATTR_EXTENT_LOCK,
+	/** Existing local extent lock is used */
+	SETATTR_MATCH_LOCK
+};
+
+
+/**
+ * IO state private to vvp or slp layers.
+ */
+struct ccc_io {
+	/** super class */
+	struct cl_io_slice     cui_cl;
+	struct cl_io_lock_link cui_link;
+	/**
+	 * I/O vector information to or from which read/write is going.
+	 */
+	struct iovec *cui_iov;
+	unsigned long cui_nrsegs;
+	/**
+	 * Total iov count for left IO.
+	 */
+	unsigned long cui_tot_nrsegs;
+	/**
+	 * Old length for iov that was truncated partially.
+	 */
+	size_t cui_iov_olen;
+	/**
+	 * Total size for the left IO.
+	 */
+	size_t cui_tot_count;
+
+	union {
+		struct {
+			enum ccc_setattr_lock_type cui_local_lock;
+		} setattr;
+	} u;
+	/**
+	 * True iff io is processing glimpse right now.
+	 */
+	int		  cui_glimpse;
+	/**
+	 * Layout version when this IO is initialized
+	 */
+	__u32		cui_layout_gen;
+	/**
+	 * File descriptor against which IO is done.
+	 */
+	struct ll_file_data *cui_fd;
+	struct kiocb *cui_iocb;
+};
+
+/**
+ * True, if \a io is a normal io, False for other (sendfile, splice*).
+ * must be impementated in arch specific code.
+ */
+int cl_is_normalio(const struct lu_env *env, const struct cl_io *io);
+
+extern struct lu_context_key ccc_key;
+extern struct lu_context_key ccc_session_key;
+
+struct ccc_thread_info {
+	struct cl_lock_descr cti_descr;
+	struct cl_io	 cti_io;
+	struct cl_attr       cti_attr;
+};
+
+static inline struct ccc_thread_info *ccc_env_info(const struct lu_env *env)
+{
+	struct ccc_thread_info      *info;
+
+	info = lu_context_key_get(&env->le_ctx, &ccc_key);
+	LASSERT(info != NULL);
+	return info;
+}
+
+static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env)
+{
+	struct cl_attr *attr = &ccc_env_info(env)->cti_attr;
+	memset(attr, 0, sizeof(*attr));
+	return attr;
+}
+
+static inline struct cl_io *ccc_env_thread_io(const struct lu_env *env)
+{
+	struct cl_io *io = &ccc_env_info(env)->cti_io;
+	memset(io, 0, sizeof(*io));
+	return io;
+}
+
+struct ccc_session {
+	struct ccc_io cs_ios;
+};
+
+static inline struct ccc_session *ccc_env_session(const struct lu_env *env)
+{
+	struct ccc_session *ses;
+
+	ses = lu_context_key_get(env->le_ses, &ccc_session_key);
+	LASSERT(ses != NULL);
+	return ses;
+}
+
+static inline struct ccc_io *ccc_env_io(const struct lu_env *env)
+{
+	return &ccc_env_session(env)->cs_ios;
+}
+
+/**
+ * ccc-private object state.
+ */
+struct ccc_object {
+	struct cl_object_header cob_header;
+	struct cl_object	cob_cl;
+	struct inode	   *cob_inode;
+
+	/**
+	 * A list of dirty pages pending IO in the cache. Used by
+	 * SOM. Protected by ll_inode_info::lli_lock.
+	 *
+	 * \see ccc_page::cpg_pending_linkage
+	 */
+	struct list_head	     cob_pending_list;
+
+	/**
+	 * Access this counter is protected by inode->i_sem. Now that
+	 * the lifetime of transient pages must be covered by inode sem,
+	 * we don't need to hold any lock..
+	 */
+	int		     cob_transient_pages;
+	/**
+	 * Number of outstanding mmaps on this file.
+	 *
+	 * \see ll_vm_open(), ll_vm_close().
+	 */
+	atomic_t	    cob_mmap_cnt;
+
+	/**
+	 * various flags
+	 * cob_discard_page_warned
+	 *     if pages belonging to this object are discarded when a client
+	 * is evicted, some debug info will be printed, this flag will be set
+	 * during processing the first discarded page, then avoid flooding
+	 * debug message for lots of discarded pages.
+	 *
+	 * \see ll_dirty_page_discard_warn.
+	 */
+	unsigned int		cob_discard_page_warned:1;
+};
+
+/**
+ * ccc-private page state.
+ */
+struct ccc_page {
+	struct cl_page_slice cpg_cl;
+	int		  cpg_defer_uptodate;
+	int		  cpg_ra_used;
+	int		  cpg_write_queued;
+	/**
+	 * Non-empty iff this page is already counted in
+	 * ccc_object::cob_pending_list. Protected by
+	 * ccc_object::cob_pending_guard. This list is only used as a flag,
+	 * that is, never iterated through, only checked for list_empty(), but
+	 * having a list is useful for debugging.
+	 */
+	struct list_head	   cpg_pending_linkage;
+	/** VM page */
+	struct page	  *cpg_page;
+};
+
+static inline struct ccc_page *cl2ccc_page(const struct cl_page_slice *slice)
+{
+	return container_of(slice, struct ccc_page, cpg_cl);
+}
+
+struct cl_page    *ccc_vmpage_page_transient(struct page *vmpage);
+
+struct ccc_device {
+	struct cl_device    cdv_cl;
+	struct super_block *cdv_sb;
+	struct cl_device   *cdv_next;
+};
+
+struct ccc_lock {
+	struct cl_lock_slice clk_cl;
+};
+
+struct ccc_req {
+	struct cl_req_slice  crq_cl;
+};
+
+void *ccc_key_init	(const struct lu_context *ctx,
+			   struct lu_context_key *key);
+void  ccc_key_fini	(const struct lu_context *ctx,
+			   struct lu_context_key *key, void *data);
+void *ccc_session_key_init(const struct lu_context *ctx,
+			   struct lu_context_key *key);
+void  ccc_session_key_fini(const struct lu_context *ctx,
+			   struct lu_context_key *key, void *data);
+
+int	      ccc_device_init  (const struct lu_env *env,
+				   struct lu_device *d,
+				   const char *name, struct lu_device *next);
+struct lu_device *ccc_device_fini (const struct lu_env *env,
+				   struct lu_device *d);
+struct lu_device *ccc_device_alloc(const struct lu_env *env,
+				   struct lu_device_type *t,
+				   struct lustre_cfg *cfg,
+				   const struct lu_device_operations *luops,
+				   const struct cl_device_operations *clops);
+struct lu_device *ccc_device_free (const struct lu_env *env,
+				   struct lu_device *d);
+struct lu_object *ccc_object_alloc(const struct lu_env *env,
+				   const struct lu_object_header *hdr,
+				   struct lu_device *dev,
+				   const struct cl_object_operations *clops,
+				   const struct lu_object_operations *luops);
+
+int ccc_req_init(const struct lu_env *env, struct cl_device *dev,
+		 struct cl_req *req);
+void ccc_umount(const struct lu_env *env, struct cl_device *dev);
+int ccc_global_init(struct lu_device_type *device_type);
+void ccc_global_fini(struct lu_device_type *device_type);
+int ccc_object_init0(const struct lu_env *env,struct ccc_object *vob,
+		     const struct cl_object_conf *conf);
+int ccc_object_init(const struct lu_env *env, struct lu_object *obj,
+		    const struct lu_object_conf *conf);
+void ccc_object_free(const struct lu_env *env, struct lu_object *obj);
+int ccc_lock_init(const struct lu_env *env, struct cl_object *obj,
+		  struct cl_lock *lock, const struct cl_io *io,
+		  const struct cl_lock_operations *lkops);
+int ccc_attr_set(const struct lu_env *env, struct cl_object *obj,
+		 const struct cl_attr *attr, unsigned valid);
+int ccc_object_glimpse(const struct lu_env *env,
+		       const struct cl_object *obj, struct ost_lvb *lvb);
+int ccc_conf_set(const struct lu_env *env, struct cl_object *obj,
+		 const struct cl_object_conf *conf);
+struct page *ccc_page_vmpage(const struct lu_env *env,
+			    const struct cl_page_slice *slice);
+int ccc_page_is_under_lock(const struct lu_env *env,
+			   const struct cl_page_slice *slice, struct cl_io *io);
+int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice);
+void ccc_transient_page_verify(const struct cl_page *page);
+int  ccc_transient_page_own(const struct lu_env *env,
+			    const struct cl_page_slice *slice,
+			    struct cl_io *io, int nonblock);
+void ccc_transient_page_assume(const struct lu_env *env,
+			       const struct cl_page_slice *slice,
+			       struct cl_io *io);
+void ccc_transient_page_unassume(const struct lu_env *env,
+				 const struct cl_page_slice *slice,
+				 struct cl_io *io);
+void ccc_transient_page_disown(const struct lu_env *env,
+			       const struct cl_page_slice *slice,
+			       struct cl_io *io);
+void ccc_transient_page_discard(const struct lu_env *env,
+				const struct cl_page_slice *slice,
+				struct cl_io *io);
+int ccc_transient_page_prep(const struct lu_env *env,
+			    const struct cl_page_slice *slice,
+			    struct cl_io *io);
+void ccc_lock_delete(const struct lu_env *env,
+		     const struct cl_lock_slice *slice);
+void ccc_lock_fini(const struct lu_env *env,struct cl_lock_slice *slice);
+int ccc_lock_enqueue(const struct lu_env *env,const struct cl_lock_slice *slice,
+		     struct cl_io *io, __u32 enqflags);
+int ccc_lock_unuse(const struct lu_env *env,const struct cl_lock_slice *slice);
+int ccc_lock_wait(const struct lu_env *env,const struct cl_lock_slice *slice);
+int ccc_lock_fits_into(const struct lu_env *env,
+		       const struct cl_lock_slice *slice,
+		       const struct cl_lock_descr *need,
+		       const struct cl_io *io);
+void ccc_lock_state(const struct lu_env *env,
+		    const struct cl_lock_slice *slice,
+		    enum cl_lock_state state);
+
+void ccc_io_fini(const struct lu_env *env, const struct cl_io_slice *ios);
+int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io,
+			  __u32 enqflags, enum cl_lock_mode mode,
+			  pgoff_t start, pgoff_t end);
+int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io,
+		    __u32 enqflags, enum cl_lock_mode mode,
+		    loff_t start, loff_t end);
+void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios);
+void ccc_io_advance(const struct lu_env *env, const struct cl_io_slice *ios,
+		    size_t nob);
+void ccc_io_update_iov(const struct lu_env *env, struct ccc_io *cio,
+		       struct cl_io *io);
+int ccc_prep_size(const struct lu_env *env, struct cl_object *obj,
+		  struct cl_io *io, loff_t start, size_t count, int *exceed);
+void ccc_req_completion(const struct lu_env *env,
+			const struct cl_req_slice *slice, int ioret);
+void ccc_req_attr_set(const struct lu_env *env,const struct cl_req_slice *slice,
+		      const struct cl_object *obj,
+		      struct cl_req_attr *oa, obd_valid flags);
+
+struct lu_device   *ccc2lu_dev      (struct ccc_device *vdv);
+struct lu_object   *ccc2lu	  (struct ccc_object *vob);
+struct ccc_device  *lu2ccc_dev      (const struct lu_device *d);
+struct ccc_device  *cl2ccc_dev      (const struct cl_device *d);
+struct ccc_object  *lu2ccc	  (const struct lu_object *obj);
+struct ccc_object  *cl2ccc	  (const struct cl_object *obj);
+struct ccc_lock    *cl2ccc_lock     (const struct cl_lock_slice *slice);
+struct ccc_io      *cl2ccc_io       (const struct lu_env *env,
+				     const struct cl_io_slice *slice);
+struct ccc_req     *cl2ccc_req      (const struct cl_req_slice *slice);
+struct page	 *cl2vm_page      (const struct cl_page_slice *slice);
+struct inode       *ccc_object_inode(const struct cl_object *obj);
+struct ccc_object  *cl_inode2ccc    (struct inode *inode);
+
+int cl_setattr_ost(struct inode *inode, const struct iattr *attr,
+		   struct obd_capa *capa);
+
+struct cl_page *ccc_vmpage_page_transient(struct page *vmpage);
+int ccc_object_invariant(const struct cl_object *obj);
+int cl_file_inode_init(struct inode *inode, struct lustre_md *md);
+void cl_inode_fini(struct inode *inode);
+int cl_local_size(struct inode *inode);
+
+__u16 ll_dirent_type_get(struct lu_dirent *ent);
+__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32);
+__u32 cl_fid_build_gen(const struct lu_fid *fid);
+
+# define CLOBINVRNT(env, clob, expr)				    \
+	((void)sizeof(env), (void)sizeof(clob), (void)sizeof !!(expr))
+
+int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp);
+int cl_ocd_update(struct obd_device *host,
+		  struct obd_device *watched,
+		  enum obd_notify_event ev, void *owner, void *data);
+
+struct ccc_grouplock {
+	struct lu_env   *cg_env;
+	struct cl_io    *cg_io;
+	struct cl_lock  *cg_lock;
+	unsigned long    cg_gid;
+};
+
+int  cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock,
+		      struct ccc_grouplock *cg);
+void cl_put_grouplock(struct ccc_grouplock *cg);
+
+/**
+ * New interfaces to get and put lov_stripe_md from lov layer. This violates
+ * layering because lov_stripe_md is supposed to be a private data in lov.
+ *
+ * NB: If you find you have to use these interfaces for your new code, please
+ * think about it again. These interfaces may be removed in the future for
+ * better layering. */
+struct lov_stripe_md *lov_lsm_get(struct cl_object *clobj);
+void lov_lsm_put(struct cl_object *clobj, struct lov_stripe_md *lsm);
+int lov_read_and_clear_async_rc(struct cl_object *clob);
+
+struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode);
+void ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm);
+
+/**
+ * Data structure managing a client's cached clean pages. An LRU of
+ * pages is maintained, along with other statistics.
+ */
+struct cl_client_cache {
+	atomic_t	ccc_users;    /* # of users (OSCs) of this data */
+	struct list_head	ccc_lru;      /* LRU list of cached clean pages */
+	spinlock_t	ccc_lru_lock; /* lock for list */
+	atomic_t	ccc_lru_left; /* # of LRU entries available */
+	unsigned long	ccc_lru_max;  /* Max # of LRU entries possible */
+	unsigned int	ccc_lru_shrinkers; /* # of threads reclaiming */
+};
+
+#endif /*LCLIENT_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lprocfs_status.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lprocfs_status.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lprocfs_status.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lprocfs_status.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,58 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/linux/lprocfs_status.h
+ *
+ * Top level header file for LProc SNMP
+ *
+ * Author: Hariharan Thantry thantry@users.sourceforge.net
+ */
+#ifndef _LINUX_LPROCFS_SNMP_H
+#define _LINUX_LPROCFS_SNMP_H
+
+#ifndef _LPROCFS_SNMP_H
+#error Do not #include this file directly. #include <lprocfs_status.h> instead
+#endif
+
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/version.h>
+#include <linux/smp.h>
+#include <linux/rwsem.h>
+#include <linux/libcfs/libcfs.h>
+#include <linux/statfs.h>
+
+
+#endif /* LPROCFS_SNMP_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_acl.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_acl.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_acl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_acl.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/lustre/include/lustre_acl.h
+ *
+ * MDS data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ */
+
+#ifndef _LUSTRE_LINUX_ACL_H
+#define _LUSTRE_LINUX_ACL_H
+
+#ifndef	_LUSTRE_ACL_H
+#error	Shoud not include direectly. use #include <lustre_acl.h> instead
+#endif
+
+# include <linux/fs.h>
+# include <linux/dcache.h>
+# ifdef CONFIG_FS_POSIX_ACL
+#  include <linux/posix_acl_xattr.h>
+#  define LUSTRE_POSIX_ACL_MAX_ENTRIES	32
+#  define LUSTRE_POSIX_ACL_MAX_SIZE					\
+	(sizeof(posix_acl_xattr_header) +				\
+	 LUSTRE_POSIX_ACL_MAX_ENTRIES * sizeof(posix_acl_xattr_entry))
+# endif /* CONFIG_FS_POSIX_ACL */
+# include <linux/lustre_intent.h>
+# include <linux/xattr.h> /* XATTR_{REPLACE,CREATE} */
+
+#ifndef LUSTRE_POSIX_ACL_MAX_SIZE
+# define LUSTRE_POSIX_ACL_MAX_SIZE   0
+#endif
+
+#endif /* _LUSTRE_LINUX_ACL_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_common.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_common.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_common.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,22 @@
+#ifndef LUSTRE_COMMON_H
+#define LUSTRE_COMMON_H
+
+#include <linux/sched.h>
+
+static inline int cfs_cleanup_group_info(void)
+{
+	struct group_info *ginfo;
+
+	ginfo = groups_alloc(0);
+	if (!ginfo)
+		return -ENOMEM;
+
+	set_current_groups(ginfo);
+	put_group_info(ginfo);
+
+	return 0;
+}
+
+#define ll_inode_blksize(a)		(1<<(a)->i_blkbits)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_compat25.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,349 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LINUX_COMPAT25_H
+#define _LINUX_COMPAT25_H
+
+#include <linux/fs_struct.h>
+#include <linux/namei.h>
+#include <linux/libcfs/linux/portals_compat25.h>
+
+#include <linux/lustre_patchless_compat.h>
+
+# define LOCK_FS_STRUCT(fs)	spin_lock(&(fs)->lock)
+# define UNLOCK_FS_STRUCT(fs)	spin_unlock(&(fs)->lock)
+
+static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
+				 struct dentry *dentry)
+{
+	struct path path;
+	struct path old_pwd;
+
+	path.mnt = mnt;
+	path.dentry = dentry;
+	LOCK_FS_STRUCT(fs);
+	old_pwd = fs->pwd;
+	path_get(&path);
+	fs->pwd = path;
+	UNLOCK_FS_STRUCT(fs);
+
+	if (old_pwd.dentry)
+		path_put(&old_pwd);
+}
+
+
+/*
+ * set ATTR_BLOCKS to a high value to avoid any risk of collision with other
+ * ATTR_* attributes (see bug 13828)
+ */
+#define ATTR_BLOCKS    (1 << 27)
+
+#define current_ngroups current_cred()->group_info->ngroups
+#define current_groups current_cred()->group_info->small_block
+
+/*
+ * OBD need working random driver, thus all our
+ * initialization routines must be called after device
+ * driver initialization
+ */
+#ifndef MODULE
+#undef module_init
+#define module_init(a)     late_initcall(a)
+#endif
+
+
+#define LTIME_S(time)		   (time.tv_sec)
+
+#define ll_permission(inode,mask,nd)    inode_permission(inode,mask)
+
+# define ll_generic_permission(inode, mask, flags, check_acl) \
+	 generic_permission(inode, mask)
+
+#define ll_blkdev_put(a, b) blkdev_put(a, b)
+
+#define ll_dentry_open(a,b,c)	dentry_open(a,b,c)
+
+#define ll_vfs_symlink(dir, dentry, mnt, path, mode) \
+		       vfs_symlink(dir, dentry, path)
+
+
+#define ll_generic_file_llseek_size(file, offset, origin, maxbytes, eof) \
+		generic_file_llseek_size(file, offset, origin, maxbytes, eof);
+
+/* inode_dio_wait(i) use as-is for write lock */
+# define inode_dio_write_done(i)	do {} while (0) /* for write unlock */
+# define inode_dio_read(i)		atomic_inc(&(i)->i_dio_count)
+/* inode_dio_done(i) use as-is for read unlock */
+
+#define TREE_READ_LOCK_IRQ(mapping)	spin_lock_irq(&(mapping)->tree_lock)
+#define TREE_READ_UNLOCK_IRQ(mapping)	spin_unlock_irq(&(mapping)->tree_lock)
+
+static inline
+int ll_unregister_blkdev(unsigned int dev, const char *name)
+{
+	unregister_blkdev(dev, name);
+	return 0;
+}
+
+#define ll_invalidate_bdev(a,b)	 invalidate_bdev((a))
+
+#ifndef FS_HAS_FIEMAP
+#define FS_HAS_FIEMAP			(0)
+#endif
+
+
+
+/* add a lustre compatible layer for crypto API */
+#include <linux/crypto.h>
+#define ll_crypto_hash	  crypto_hash
+#define ll_crypto_cipher	crypto_blkcipher
+#define ll_crypto_alloc_hash(name, type, mask)  crypto_alloc_hash(name, type, mask)
+#define ll_crypto_hash_setkey(tfm, key, keylen) crypto_hash_setkey(tfm, key, keylen)
+#define ll_crypto_hash_init(desc)	       crypto_hash_init(desc)
+#define ll_crypto_hash_update(desc, sl, bytes)  crypto_hash_update(desc, sl, bytes)
+#define ll_crypto_hash_final(desc, out)	 crypto_hash_final(desc, out)
+#define ll_crypto_blkcipher_setkey(tfm, key, keylen) \
+		crypto_blkcipher_setkey(tfm, key, keylen)
+#define ll_crypto_blkcipher_set_iv(tfm, src, len) \
+		crypto_blkcipher_set_iv(tfm, src, len)
+#define ll_crypto_blkcipher_get_iv(tfm, dst, len) \
+		crypto_blkcipher_get_iv(tfm, dst, len)
+#define ll_crypto_blkcipher_encrypt(desc, dst, src, bytes) \
+		crypto_blkcipher_encrypt(desc, dst, src, bytes)
+#define ll_crypto_blkcipher_decrypt(desc, dst, src, bytes) \
+		crypto_blkcipher_decrypt(desc, dst, src, bytes)
+#define ll_crypto_blkcipher_encrypt_iv(desc, dst, src, bytes) \
+		crypto_blkcipher_encrypt_iv(desc, dst, src, bytes)
+#define ll_crypto_blkcipher_decrypt_iv(desc, dst, src, bytes) \
+		crypto_blkcipher_decrypt_iv(desc, dst, src, bytes)
+
+static inline
+struct ll_crypto_cipher *ll_crypto_alloc_blkcipher(const char *name,
+						   u32 type, u32 mask)
+{
+	struct ll_crypto_cipher *rtn = crypto_alloc_blkcipher(name, type, mask);
+
+	return (rtn == NULL ? ERR_PTR(-ENOMEM) : rtn);
+}
+
+static inline int ll_crypto_hmac(struct ll_crypto_hash *tfm,
+				 u8 *key, unsigned int *keylen,
+				 struct scatterlist *sg,
+				 unsigned int size, u8 *result)
+{
+	struct hash_desc desc;
+	int	      rv;
+	desc.tfm   = tfm;
+	desc.flags = 0;
+	rv = crypto_hash_setkey(desc.tfm, key, *keylen);
+	if (rv) {
+		CERROR("failed to hash setkey: %d\n", rv);
+		return rv;
+	}
+	return crypto_hash_digest(&desc, sg, size, result);
+}
+static inline
+unsigned int ll_crypto_tfm_alg_max_keysize(struct crypto_blkcipher *tfm)
+{
+	return crypto_blkcipher_tfm(tfm)->__crt_alg->cra_blkcipher.max_keysize;
+}
+static inline
+unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm)
+{
+	return crypto_blkcipher_tfm(tfm)->__crt_alg->cra_blkcipher.min_keysize;
+}
+
+#define ll_crypto_hash_blocksize(tfm)       crypto_hash_blocksize(tfm)
+#define ll_crypto_hash_digestsize(tfm)      crypto_hash_digestsize(tfm)
+#define ll_crypto_blkcipher_ivsize(tfm)     crypto_blkcipher_ivsize(tfm)
+#define ll_crypto_blkcipher_blocksize(tfm)  crypto_blkcipher_blocksize(tfm)
+#define ll_crypto_free_hash(tfm)	    crypto_free_hash(tfm)
+#define ll_crypto_free_blkcipher(tfm)       crypto_free_blkcipher(tfm)
+
+#define ll_vfs_rmdir(dir,entry,mnt)	     vfs_rmdir(dir,entry)
+#define ll_vfs_mkdir(inode,dir,mnt,mode)	vfs_mkdir(inode,dir,mode)
+#define ll_vfs_link(old,mnt,dir,new,mnt1)       vfs_link(old,dir,new)
+#define ll_vfs_unlink(inode,entry,mnt)	  vfs_unlink(inode,entry)
+#define ll_vfs_mknod(dir,entry,mnt,mode,dev)    vfs_mknod(dir,entry,mode,dev)
+#define ll_security_inode_unlink(dir,entry,mnt) security_inode_unlink(dir,entry)
+#define ll_vfs_rename(old,old_dir,mnt,new,new_dir,mnt1) \
+		vfs_rename(old,old_dir,new,new_dir)
+
+#ifdef for_each_possible_cpu
+#define cfs_for_each_possible_cpu(cpu) for_each_possible_cpu(cpu)
+#elif defined(for_each_cpu)
+#define cfs_for_each_possible_cpu(cpu) for_each_cpu(cpu)
+#endif
+
+#define cfs_bio_io_error(a,b)   bio_io_error((a))
+#define cfs_bio_endio(a,b,c)    bio_endio((a),(c))
+
+#define cfs_fs_pwd(fs)       ((fs)->pwd.dentry)
+#define cfs_fs_mnt(fs)       ((fs)->pwd.mnt)
+#define cfs_path_put(nd)     path_put(&(nd)->path)
+
+
+#ifndef SLAB_DESTROY_BY_RCU
+#define SLAB_DESTROY_BY_RCU 0
+#endif
+
+
+
+static inline int
+ll_quota_on(struct super_block *sb, int off, int ver, char *name, int remount)
+{
+	int rc;
+
+	if (sb->s_qcop->quota_on) {
+		struct path path;
+
+		rc = kern_path(name, LOOKUP_FOLLOW, &path);
+		if (!rc)
+			return rc;
+		rc = sb->s_qcop->quota_on(sb, off, ver
+					    , &path
+					   );
+		path_put(&path);
+		return rc;
+	}
+	else
+		return -ENOSYS;
+}
+
+static inline int ll_quota_off(struct super_block *sb, int off, int remount)
+{
+	if (sb->s_qcop->quota_off) {
+		return sb->s_qcop->quota_off(sb, off
+					    );
+	}
+	else
+		return -ENOSYS;
+}
+
+
+# define ll_vfs_dq_init	     dquot_initialize
+# define ll_vfs_dq_drop	     dquot_drop
+# define ll_vfs_dq_transfer	 dquot_transfer
+# define ll_vfs_dq_off(sb, remount) dquot_suspend(sb, -1)
+
+
+
+
+
+#define queue_max_phys_segments(rq)       queue_max_segments(rq)
+#define queue_max_hw_segments(rq)	 queue_max_segments(rq)
+
+#define ll_kmap_atomic(a, b)	kmap_atomic(a)
+#define ll_kunmap_atomic(a, b)	kunmap_atomic(a)
+
+
+#define ll_d_hlist_node hlist_node
+#define ll_d_hlist_empty(list) hlist_empty(list)
+#define ll_d_hlist_entry(ptr, type, name) hlist_entry(ptr.first, type, name)
+#define ll_d_hlist_for_each(tmp, i_dentry) hlist_for_each(tmp, i_dentry)
+#define ll_d_hlist_for_each_entry(dentry, p, i_dentry, alias) \
+	p = NULL; hlist_for_each_entry(dentry, i_dentry, alias)
+
+
+#define bio_hw_segments(q, bio) 0
+
+
+#define ll_pagevec_init(pv, cold)       do {} while (0)
+#define ll_pagevec_add(pv, pg)	  (0)
+#define ll_pagevec_lru_add_file(pv)     do {} while (0)
+
+
+#ifndef QUOTA_OK
+# define QUOTA_OK 0
+#endif
+#ifndef NO_QUOTA
+# define NO_QUOTA (-EDQUOT)
+#endif
+
+#ifndef SEEK_DATA
+#define SEEK_DATA      3       /* seek to the next data */
+#endif
+#ifndef SEEK_HOLE
+#define SEEK_HOLE      4       /* seek to the next hole */
+#endif
+
+#ifndef FMODE_UNSIGNED_OFFSET
+#define FMODE_UNSIGNED_OFFSET	((__force fmode_t)0x2000)
+#endif
+
+#if !defined(_ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_) && !defined(ext2_set_bit)
+# define ext2_set_bit	     __test_and_set_bit_le
+# define ext2_clear_bit	   __test_and_clear_bit_le
+# define ext2_test_bit	    test_bit_le
+# define ext2_find_first_zero_bit find_first_zero_bit_le
+# define ext2_find_next_zero_bit  find_next_zero_bit_le
+#endif
+
+#ifdef ATTR_TIMES_SET
+# define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)
+#else
+# define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET)
+#endif
+
+
+
+/*
+ * After 3.1, kernel's nameidata.intent.open.flags is different
+ * with lustre's lookup_intent.it_flags, as lustre's it_flags'
+ * lower bits equal to FMODE_xxx while kernel doesn't transliterate
+ * lower bits of nameidata.intent.open.flags to FMODE_xxx.
+ * */
+#include <linux/version.h>
+static inline int ll_namei_to_lookup_intent_flag(int flag)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
+	flag = (flag & ~O_ACCMODE) | OPEN_FMODE(flag);
+#endif
+	return flag;
+}
+
+# define ll_mrf_ret void
+# define LL_MRF_RETURN(rc)
+
+#include <linux/fs.h>
+
+# define ll_umode_t	umode_t
+
+#include <linux/dcache.h>
+
+# define ll_dirty_inode(inode, flag)	(inode)->i_sb->s_op->dirty_inode((inode), flag)
+
+#endif /* _COMPAT25_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_debug.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_debug.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_debug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_debug.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,47 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LINUX_LUSTRE_DEBUG_H
+#define _LINUX_LUSTRE_DEBUG_H
+
+#ifndef _LUSTRE_DEBUG_H
+#error Do not #include this file directly. #include <lprocfs_status.h> instead
+#endif
+
+#define LL_CDEBUG_PAGE(mask, page, fmt, arg...)			       \
+	CDEBUG(mask, "page %p map %p index %lu flags %lx count %u priv %0lx: "\
+	       fmt, page, page->mapping, page->index, (long)page->flags,      \
+	       page_count(page), page_private(page), ## arg)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_dlm.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_dlm.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_dlm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_dlm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,46 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LINUX_LUSTRE_DLM_H__
+#define _LINUX_LUSTRE_DLM_H__
+
+#ifndef _LUSTRE_DLM_H__
+#error Do not #include this file directly. #include <lprocfs_status.h> instead
+#endif
+
+# include <linux/proc_fs.h>
+#  include <asm/processor.h>
+#  include <linux/bit_spinlock.h>
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_fsfilt.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_fsfilt.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_fsfilt.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_fsfilt.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,181 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/linux/lustre_fsfilt.h
+ *
+ * Filesystem interface helper.
+ */
+
+#ifndef _LINUX_LUSTRE_FSFILT_H
+#define _LINUX_LUSTRE_FSFILT_H
+
+#ifndef _LUSTRE_FSFILT_H
+#error Do not #include this file directly. #include <lustre_fsfilt.h> instead
+#endif
+
+
+#include <obd.h>
+#include <obd_class.h>
+
+typedef void (*fsfilt_cb_t)(struct obd_device *obd, __u64 last_rcvd,
+			    void *data, int error);
+
+struct fsfilt_operations {
+	struct list_head fs_list;
+	module_t *fs_owner;
+	char   *fs_type;
+	char   *(* fs_getlabel)(struct super_block *sb);
+	void   *(* fs_start)(struct inode *inode, int op, void *desc_private,
+			     int logs);
+	int     (* fs_commit)(struct inode *inode, void *handle,int force_sync);
+	int     (* fs_map_inode_pages)(struct inode *inode, struct page **page,
+				       int pages, unsigned long *blocks,
+				       int create, struct mutex *sem);
+	int     (* fs_write_record)(struct file *, void *, int size, loff_t *,
+				    int force_sync);
+	int     (* fs_read_record)(struct file *, void *, int size, loff_t *);
+	int     (* fs_setup)(struct super_block *sb);
+};
+
+extern int fsfilt_register_ops(struct fsfilt_operations *fs_ops);
+extern void fsfilt_unregister_ops(struct fsfilt_operations *fs_ops);
+extern struct fsfilt_operations *fsfilt_get_ops(const char *type);
+extern void fsfilt_put_ops(struct fsfilt_operations *fs_ops);
+
+static inline char *fsfilt_get_label(struct obd_device *obd,
+				     struct super_block *sb)
+{
+	if (obd->obd_fsops->fs_getlabel == NULL)
+		return NULL;
+	if (obd->obd_fsops->fs_getlabel(sb)[0] == '\0')
+		return NULL;
+
+	return obd->obd_fsops->fs_getlabel(sb);
+}
+
+#define FSFILT_OP_UNLINK		1
+#define FSFILT_OP_CANCEL_UNLINK	 10
+
+#define __fsfilt_check_slow(obd, start, msg)			      \
+do {								      \
+	if (cfs_time_before(jiffies, start + 15 * HZ))		\
+		break;						    \
+	else if (cfs_time_before(jiffies, start + 30 * HZ))	   \
+		CDEBUG(D_VFSTRACE, "%s: slow %s %lus\n", obd->obd_name,   \
+		       msg, (jiffies-start) / HZ);		    \
+	else if (cfs_time_before(jiffies, start + DISK_TIMEOUT * HZ)) \
+		CWARN("%s: slow %s %lus\n", obd->obd_name, msg,	   \
+		      (jiffies - start) / HZ);			\
+	else							      \
+		CERROR("%s: slow %s %lus\n", obd->obd_name, msg,	  \
+		       (jiffies - start) / HZ);		       \
+} while (0)
+
+#define fsfilt_check_slow(obd, start, msg)	      \
+do {						    \
+	__fsfilt_check_slow(obd, start, msg);	   \
+	start = jiffies;				\
+} while (0)
+
+static inline void *fsfilt_start_log(struct obd_device *obd,
+				     struct inode *inode, int op,
+				     struct obd_trans_info *oti, int logs)
+{
+	unsigned long now = jiffies;
+	void *parent_handle = oti ? oti->oti_handle : NULL;
+	void *handle;
+
+	handle = obd->obd_fsops->fs_start(inode, op, parent_handle, logs);
+	CDEBUG(D_INFO, "started handle %p (%p)\n", handle, parent_handle);
+
+	if (oti != NULL) {
+		if (parent_handle == NULL) {
+			oti->oti_handle = handle;
+		} else if (handle != parent_handle) {
+			CERROR("mismatch: parent %p, handle %p, oti %p\n",
+			       parent_handle, handle, oti);
+			LBUG();
+		}
+	}
+	fsfilt_check_slow(obd, now, "journal start");
+	return handle;
+}
+
+static inline int fsfilt_commit(struct obd_device *obd, struct inode *inode,
+				void *handle, int force_sync)
+{
+	unsigned long now = jiffies;
+	int rc = obd->obd_fsops->fs_commit(inode, handle, force_sync);
+	CDEBUG(D_INFO, "committing handle %p\n", handle);
+
+	fsfilt_check_slow(obd, now, "journal start");
+
+	return rc;
+}
+
+static inline int fsfilt_map_inode_pages(struct obd_device *obd,
+					 struct inode *inode,
+					 struct page **page, int pages,
+					 unsigned long *blocks,
+					 int create, struct mutex *mutex)
+{
+	return obd->obd_fsops->fs_map_inode_pages(inode, page, pages, blocks,
+						  create, mutex);
+}
+
+static inline int fsfilt_read_record(struct obd_device *obd, struct file *file,
+				     void *buf, loff_t size, loff_t *offs)
+{
+	return obd->obd_fsops->fs_read_record(file, buf, size, offs);
+}
+
+static inline int fsfilt_write_record(struct obd_device *obd, struct file *file,
+				      void *buf, loff_t size, loff_t *offs,
+				      int force_sync)
+{
+	return obd->obd_fsops->fs_write_record(file, buf, size,offs,force_sync);
+}
+
+static inline int fsfilt_setup(struct obd_device *obd, struct super_block *fs)
+{
+	if (obd->obd_fsops->fs_setup)
+		return obd->obd_fsops->fs_setup(fs);
+	return 0;
+}
+
+
+
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_handles.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_handles.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_handles.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_handles.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,53 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LINUX_LUSTRE_HANDLES_H_
+#define __LINUX_LUSTRE_HANDLES_H_
+
+#ifndef __LUSTRE_HANDLES_H_
+#error Do not #include this file directly. #include <lustre_handles.h> instead
+#endif
+
+#include <asm/types.h>
+#include <asm/atomic.h>
+#include <linux/list.h>
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <linux/rcupdate.h> /* for rcu_head{} */
+typedef struct rcu_head cfs_rcu_head_t;
+
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_intent.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_intent.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_intent.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_intent.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,62 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef LUSTRE_INTENT_H
+#define LUSTRE_INTENT_H
+
+/* intent IT_XXX are defined in lustre/include/obd.h */
+struct lustre_intent_data {
+	int		it_disposition;
+	int		it_status;
+	__u64		it_lock_handle;
+	__u64		it_lock_bits;
+	int		it_lock_mode;
+	int		it_remote_lock_mode;
+	__u64	   it_remote_lock_handle;
+	void	   *it_data;
+	unsigned int    it_lock_set:1;
+};
+
+struct lookup_intent {
+	int     it_op;
+	int     it_flags;
+	int     it_create_mode;
+	union {
+		struct lustre_intent_data lustre;
+	} d;
+};
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_lib.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_lib.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_lib.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_lib.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,87 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/linux/lustre_lib.h
+ *
+ * Basic Lustre library routines.
+ */
+
+#ifndef _LINUX_LUSTRE_LIB_H
+#define _LINUX_LUSTRE_LIB_H
+
+#ifndef _LUSTRE_LIB_H
+#error Do not #include this file directly. #include <lustre_lib.h> instead
+#endif
+
+# include <linux/rwsem.h>
+# include <linux/sched.h>
+# include <linux/signal.h>
+# include <linux/types.h>
+# include <linux/lustre_compat25.h>
+# include <linux/lustre_common.h>
+
+#ifndef LP_POISON
+#if BITS_PER_LONG > 32
+# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
+# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a)
+#else
+# define LI_POISON ((int)0x5a5a5a5a)
+# define LL_POISON ((long)0x5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a)
+#endif
+#endif
+
+/* This macro is only for compatibility reasons with older Linux Lustre user
+ * tools. New ioctls should NOT use this macro as the ioctl "size". Instead
+ * the ioctl should get a "size" argument which is the actual data type used
+ * by the ioctl, to ensure the ioctl interface is versioned correctly. */
+#define OBD_IOC_DATA_TYPE	       long
+
+#define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |		\
+			   sigmask(SIGTERM) | sigmask(SIGQUIT) |	       \
+			   sigmask(SIGALRM))
+
+/* initialize ost_lvb according to inode */
+static inline void inode_init_lvb(struct inode *inode, struct ost_lvb *lvb)
+{
+	lvb->lvb_size = i_size_read(inode);
+	lvb->lvb_blocks = inode->i_blocks;
+	lvb->lvb_mtime = LTIME_S(inode->i_mtime);
+	lvb->lvb_atime = LTIME_S(inode->i_atime);
+	lvb->lvb_ctime = LTIME_S(inode->i_ctime);
+}
+
+#endif /* _LUSTRE_LIB_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_lite.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_lite.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_lite.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_lite.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,100 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LINUX_LL_H
+#define _LINUX_LL_H
+
+#ifndef _LL_H
+#error Do not #include this file directly. #include <lustre_lite.h> instead
+#endif
+
+
+#include <linux/version.h>
+
+#include <asm/statfs.h>
+
+#include <linux/fs.h>
+#include <linux/dcache.h>
+#include <linux/proc_fs.h>
+
+#include <obd_class.h>
+#include <lustre_net.h>
+#include <lustre_ha.h>
+
+#include <linux/rbtree.h>
+#include <linux/lustre_compat25.h>
+#include <linux/lustre_common.h>
+#include <linux/pagemap.h>
+
+/* lprocfs.c */
+enum {
+	 LPROC_LL_DIRTY_HITS = 0,
+	 LPROC_LL_DIRTY_MISSES,
+	 LPROC_LL_READ_BYTES,
+	 LPROC_LL_WRITE_BYTES,
+	 LPROC_LL_BRW_READ,
+	 LPROC_LL_BRW_WRITE,
+	 LPROC_LL_OSC_READ,
+	 LPROC_LL_OSC_WRITE,
+	 LPROC_LL_IOCTL,
+	 LPROC_LL_OPEN,
+	 LPROC_LL_RELEASE,
+	 LPROC_LL_MAP,
+	 LPROC_LL_LLSEEK,
+	 LPROC_LL_FSYNC,
+	 LPROC_LL_READDIR,
+	 LPROC_LL_SETATTR,
+	 LPROC_LL_TRUNC,
+	 LPROC_LL_FLOCK,
+	 LPROC_LL_GETATTR,
+	 LPROC_LL_CREATE,
+	 LPROC_LL_LINK,
+	 LPROC_LL_UNLINK,
+	 LPROC_LL_SYMLINK,
+	 LPROC_LL_MKDIR,
+	 LPROC_LL_RMDIR,
+	 LPROC_LL_MKNOD,
+	 LPROC_LL_RENAME,
+	 LPROC_LL_STAFS,
+	 LPROC_LL_ALLOC_INODE,
+	 LPROC_LL_SETXATTR,
+	 LPROC_LL_GETXATTR,
+	 LPROC_LL_LISTXATTR,
+	 LPROC_LL_REMOVEXATTR,
+	 LPROC_LL_INODE_PERM,
+	 LPROC_LL_FILE_OPCODES
+};
+
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_log.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_log.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_log.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_log.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/linux/lustre_log.h
+ *
+ * Generic infrastructure for managing a collection of logs.
+ * These logs are used for:
+ *  - orphan recovery: OST adds record on create
+ *  - mtime/size consistency: the OST adds a record on first write
+ *  - open/unlinked objects: OST adds a record on destroy
+ *
+ *  - mds unlink log: the MDS adds an entry upon delete
+ *
+ *  - raid1 replication log between OST's
+ *  - MDS replication logs
+ */
+
+#ifndef _LINUX_LUSTRE_LOG_H
+#define _LINUX_LUSTRE_LOG_H
+
+#ifndef _LUSTRE_LOG_H
+#error Do not #include this file directly. #include <lustre_log.h> instead
+#endif
+
+#define LUSTRE_LOG_SERVER
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_net.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_net.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_net.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_net.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,50 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LINUX_LUSTRE_NET_H
+#define _LINUX_LUSTRE_NET_H
+
+#ifndef _LUSTRE_NET_H
+#error Do not #include this file directly. #include <lustre_net.h> instead
+#endif
+
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+/* XXX Liang: should be moved to other header instead of here */
+#ifndef WITH_GROUP_INFO
+#define WITH_GROUP_INFO
+#endif
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_patchless_compat.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_patchless_compat.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_patchless_compat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_patchless_compat.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,83 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef LUSTRE_PATCHLESS_COMPAT_H
+#define LUSTRE_PATCHLESS_COMPAT_H
+
+#include <linux/fs.h>
+
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/hash.h>
+
+
+#define ll_delete_from_page_cache(page) delete_from_page_cache(page)
+
+static inline void
+truncate_complete_page(struct address_space *mapping, struct page *page)
+{
+	if (page->mapping != mapping)
+		return;
+
+	if (PagePrivate(page))
+		page->mapping->a_ops->invalidatepage(page, 0);
+
+	cancel_dirty_page(page, PAGE_SIZE);
+	ClearPageMappedToDisk(page);
+	ll_delete_from_page_cache(page);
+}
+
+#ifdef ATTR_OPEN
+# define ATTR_FROM_OPEN ATTR_OPEN
+#else
+# ifndef ATTR_FROM_OPEN
+#  define ATTR_FROM_OPEN 0
+# endif
+#endif /* ATTR_OPEN */
+
+#ifndef ATTR_RAW
+#define ATTR_RAW 0
+#endif
+
+#ifndef ATTR_CTIME_SET
+/*
+ * set ATTR_CTIME_SET to a high value to avoid any risk of collision with other
+ * ATTR_* attributes (see bug 13828)
+ */
+#define ATTR_CTIME_SET (1 << 28)
+#endif
+
+#endif /* LUSTRE_PATCHLESS_COMPAT_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_quota.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_quota.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_quota.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_quota.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,47 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LINUX_LUSTRE_QUOTA_H
+#define _LINUX_LUSTRE_QUOTA_H
+
+#ifndef _LUSTRE_QUOTA_H
+#error Do not #include this file directly. #include <lustre_quota.h> instead
+#endif
+
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/quota.h>
+#include <linux/quotaops.h>
+
+#endif /* _LUSTRE_QUOTA_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_user.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_user.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lustre_user.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lustre_user.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/linux/lustre_user.h
+ *
+ * Lustre public user-space interface definitions.
+ */
+
+#ifndef _LINUX_LUSTRE_USER_H
+#define _LINUX_LUSTRE_USER_H
+
+# include <linux/version.h>
+# include <linux/quota.h>
+
+/*
+ * asm-x86_64/processor.h on some SLES 9 distros seems to use
+ * kernel-only typedefs.  fortunately skipping it altogether is ok
+ * (for now).
+ */
+#define __ASM_X86_64_PROCESSOR_H
+
+#include <linux/string.h>
+
+#if defined(__x86_64__) || defined(__ia64__) || defined(__ppc64__) || \
+    defined(__craynv) || defined (__mips64__) || defined(__powerpc64__)
+typedef struct stat     lstat_t;
+#define lstat_f	 lstat
+#define HAVE_LOV_USER_MDS_DATA
+#else
+typedef struct stat64   lstat_t;
+#define lstat_f	 lstat64
+#define HAVE_LOV_USER_MDS_DATA
+#endif
+
+#endif /* _LUSTRE_USER_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lvfs.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lvfs.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lvfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lvfs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,134 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/linux/lvfs.h
+ *
+ * lustre VFS/process permission interface
+ */
+
+#ifndef __LINUX_LVFS_H__
+#define __LINUX_LVFS_H__
+
+#ifndef __LVFS_H__
+#error Do not #include this file directly. #include <lvfs.h> instead
+#endif
+
+#include <linux/lustre_compat25.h>
+#include <linux/lustre_common.h>
+#include <linux/lvfs_linux.h>
+
+#define LLOG_LVFS
+
+/* simple.c */
+
+struct lvfs_ucred {
+	__u32		   luc_uid;
+	__u32		   luc_gid;
+	__u32		   luc_fsuid;
+	__u32		   luc_fsgid;
+	kernel_cap_t	luc_cap;
+	__u32		   luc_umask;
+	struct group_info      *luc_ginfo;
+	struct md_identity     *luc_identity;
+};
+
+struct lvfs_callback_ops {
+	struct dentry *(*l_fid2dentry)(__u64 id_ino, __u32 gen, __u64 gr, void *data);
+};
+
+#define OBD_RUN_CTXT_MAGIC      0xC0FFEEAA
+#define OBD_CTXT_DEBUG	  /* development-only debugging */
+struct lvfs_run_ctxt {
+	struct vfsmount	 *pwdmnt;
+	struct dentry	   *pwd;
+	mm_segment_t	     fs;
+	struct lvfs_ucred	luc;
+	int		      ngroups;
+	struct lvfs_callback_ops cb_ops;
+	struct group_info       *group_info;
+	struct dt_device	*dt;
+#ifdef OBD_CTXT_DEBUG
+	__u32		    magic;
+#endif
+};
+
+#ifdef OBD_CTXT_DEBUG
+#define OBD_SET_CTXT_MAGIC(ctxt) (ctxt)->magic = OBD_RUN_CTXT_MAGIC
+#else
+#define OBD_SET_CTXT_MAGIC(ctxt) do {} while(0)
+#endif
+
+
+int lustre_rename(struct dentry *dir, struct vfsmount *mnt, char *oldname,
+		  char *newname);
+
+static inline void l_dput(struct dentry *de)
+{
+	if (!de || IS_ERR(de))
+		return;
+	//shrink_dcache_parent(de);
+	LASSERT(d_count(de) > 0);
+	dput(de);
+}
+
+/* We need to hold the inode semaphore over the dcache lookup itself, or we
+ * run the risk of entering the filesystem lookup path concurrently on SMP
+ * systems, and instantiating two inodes for the same entry.  We still
+ * protect against concurrent addition/removal races with the DLM locking.
+ */
+static inline struct dentry *ll_lookup_one_len(const char *fid_name,
+					       struct dentry *dparent,
+					       int fid_namelen)
+{
+	struct dentry *dchild;
+
+	mutex_lock(&dparent->d_inode->i_mutex);
+	dchild = lookup_one_len(fid_name, dparent, fid_namelen);
+	mutex_unlock(&dparent->d_inode->i_mutex);
+
+	if (IS_ERR(dchild) || dchild->d_inode == NULL)
+		return dchild;
+
+	if (is_bad_inode(dchild->d_inode)) {
+		CERROR("bad inode returned %lu/%u\n",
+		       dchild->d_inode->i_ino, dchild->d_inode->i_generation);
+		dput(dchild);
+		dchild = ERR_PTR(-ENOENT);
+	}
+	return dchild;
+}
+
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lvfs_linux.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lvfs_linux.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/lvfs_linux.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/lvfs_linux.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LVFS_LINUX_H__
+#define __LVFS_LINUX_H__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/namei.h>
+#include <linux/sched.h>
+
+#include <lvfs.h>
+
+#define l_file file
+#define l_dentry dentry
+
+#define l_filp_open filp_open
+
+struct lvfs_run_ctxt;
+struct l_file *l_dentry_open(struct lvfs_run_ctxt *, struct l_dentry *,
+			     int flags);
+
+struct l_linux_dirent {
+	struct list_head      lld_list;
+	ino_t	   lld_ino;
+	unsigned long   lld_off;
+	char	    lld_name[LL_FID_NAMELEN];
+};
+struct l_readdir_callback {
+	struct l_linux_dirent *lrc_dirent;
+	struct list_head	    *lrc_list;
+};
+
+#endif /*  __LVFS_LINUX_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/obd_class.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/obd_class.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/obd_class.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/obd_class.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,58 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LINUX_CLASS_OBD_H
+#define __LINUX_CLASS_OBD_H
+
+#ifndef __CLASS_OBD_H
+#error Do not #include this file directly. #include <obd_class.h> instead
+#endif
+
+#include <asm/uaccess.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+
+/* obdo.c */
+void obdo_from_la(struct obdo *dst, struct lu_attr *la, __u64 valid);
+void la_from_obdo(struct lu_attr *la, struct obdo *dst, obd_flag valid);
+void obdo_refresh_inode(struct inode *dst, struct obdo *src, obd_flag valid);
+void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid);
+#define ll_inode_flags(inode)	 (inode->i_flags)
+
+
+#endif /* __LINUX_OBD_CLASS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/obd.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/obd.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/obd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/obd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,128 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LINUX_OBD_H
+#define __LINUX_OBD_H
+
+#ifndef __OBD_H
+#error Do not #include this file directly. #include <obd.h> instead
+#endif
+
+#include <obd_support.h>
+
+# include <linux/fs.h>
+# include <linux/list.h>
+# include <linux/sched.h>  /* for struct task_struct, for current.h */
+# include <linux/proc_fs.h>
+# include <linux/mount.h>
+# include <linux/lustre_intent.h>
+
+struct ll_iattr {
+	struct iattr	iattr;
+	unsigned int	ia_attr_flags;
+};
+
+#define CLIENT_OBD_LIST_LOCK_DEBUG 1
+
+typedef struct {
+	spinlock_t		lock;
+
+	unsigned long       time;
+	struct task_struct *task;
+	const char	 *func;
+	int		 line;
+} client_obd_lock_t;
+
+static inline void __client_obd_list_lock(client_obd_lock_t *lock,
+					  const char *func, int line)
+{
+	unsigned long cur = jiffies;
+	while (1) {
+		if (spin_trylock(&lock->lock)) {
+			LASSERT(lock->task == NULL);
+			lock->task = current;
+			lock->func = func;
+			lock->line = line;
+			lock->time = jiffies;
+			break;
+		}
+
+		if ((jiffies - cur > 5 * HZ) &&
+		    (jiffies - lock->time > 5 * HZ)) {
+			struct task_struct *task = lock->task;
+
+			if (task == NULL)
+				continue;
+
+			LCONSOLE_WARN("%s:%d: lock %p was acquired"
+				      " by <%s:%d:%s:%d> for %lu seconds.\n",
+				      current->comm, current->pid,
+				      lock, task->comm, task->pid,
+				      lock->func, lock->line,
+				      (jiffies - lock->time) / HZ);
+			LCONSOLE_WARN("====== for process holding the "
+				      "lock =====\n");
+			libcfs_debug_dumpstack(task);
+			LCONSOLE_WARN("====== for current process =====\n");
+			libcfs_debug_dumpstack(NULL);
+			LCONSOLE_WARN("====== end =======\n");
+			cfs_pause(1000 * HZ);
+		}
+		cpu_relax();
+	}
+}
+
+#define client_obd_list_lock(lock) \
+	__client_obd_list_lock(lock, __FUNCTION__, __LINE__)
+
+static inline void client_obd_list_unlock(client_obd_lock_t *lock)
+{
+	LASSERT(lock->task != NULL);
+	lock->task = NULL;
+	lock->time = jiffies;
+	spin_unlock(&lock->lock);
+}
+
+
+static inline void client_obd_list_lock_init(client_obd_lock_t *lock)
+{
+	spin_lock_init(&lock->lock);
+}
+
+static inline void client_obd_list_lock_done(client_obd_lock_t *lock)
+{}
+
+#endif /* __LINUX_OBD_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/obd_support.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/obd_support.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/linux/obd_support.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/linux/obd_support.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,63 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LINUX_OBD_SUPPORT
+#define _LINUX_OBD_SUPPORT
+
+#ifndef _OBD_SUPPORT
+#error Do not #include this file directly. #include <obd_support.h> instead
+#endif
+
+#ifdef CONFIG_X86
+#include <asm/cpufeature.h>
+#endif
+#include <asm/processor.h>
+#include <linux/seq_file.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
+#include <linux/lustre_compat25.h>
+#include <linux/lustre_common.h>
+#include <linux/libcfs/libcfs.h>
+#include <lustre/lustre_idl.h>
+
+
+# include <linux/types.h>
+# include <linux/blkdev.h>
+# include <lvfs.h>
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lprocfs_status.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lprocfs_status.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lprocfs_status.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lprocfs_status.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1043 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lprocfs_status.h
+ *
+ * Top level header file for LProc SNMP
+ *
+ * Author: Hariharan Thantry thantry@users.sourceforge.net
+ */
+#ifndef _LPROCFS_SNMP_H
+#define _LPROCFS_SNMP_H
+
+#include <linux/lprocfs_status.h>
+#include <lustre/lustre_idl.h>
+#include <linux/libcfs/params_tree.h>
+
+struct lprocfs_vars {
+	const char		*name;
+	struct file_operations	*fops;
+	void			*data;
+	/**
+	 * /proc file mode.
+	 */
+	umode_t			proc_mode;
+};
+
+struct lprocfs_static_vars {
+	struct lprocfs_vars *module_vars;
+	struct lprocfs_vars *obd_vars;
+};
+
+/* if we find more consumers this could be generalized */
+#define OBD_HIST_MAX 32
+struct obd_histogram {
+	spinlock_t	oh_lock;
+	unsigned long	oh_buckets[OBD_HIST_MAX];
+};
+
+enum {
+	BRW_R_PAGES = 0,
+	BRW_W_PAGES,
+	BRW_R_RPC_HIST,
+	BRW_W_RPC_HIST,
+	BRW_R_IO_TIME,
+	BRW_W_IO_TIME,
+	BRW_R_DISCONT_PAGES,
+	BRW_W_DISCONT_PAGES,
+	BRW_R_DISCONT_BLOCKS,
+	BRW_W_DISCONT_BLOCKS,
+	BRW_R_DISK_IOSIZE,
+	BRW_W_DISK_IOSIZE,
+	BRW_R_DIO_FRAGS,
+	BRW_W_DIO_FRAGS,
+	BRW_LAST,
+};
+
+struct brw_stats {
+	struct obd_histogram hist[BRW_LAST];
+};
+
+enum {
+	RENAME_SAMEDIR_SIZE = 0,
+	RENAME_CROSSDIR_SRC_SIZE,
+	RENAME_CROSSDIR_TGT_SIZE,
+	RENAME_LAST,
+};
+
+struct rename_stats {
+	struct obd_histogram hist[RENAME_LAST];
+};
+
+/* An lprocfs counter can be configured using the enum bit masks below.
+ *
+ * LPROCFS_CNTR_EXTERNALLOCK indicates that an external lock already
+ * protects this counter from concurrent updates. If not specified,
+ * lprocfs an internal per-counter lock variable. External locks are
+ * not used to protect counter increments, but are used to protect
+ * counter readout and resets.
+ *
+ * LPROCFS_CNTR_AVGMINMAX indicates a multi-valued counter samples,
+ * (i.e. counter can be incremented by more than "1"). When specified,
+ * the counter maintains min, max and sum in addition to a simple
+ * invocation count. This allows averages to be be computed.
+ * If not specified, the counter is an increment-by-1 counter.
+ * min, max, sum, etc. are not maintained.
+ *
+ * LPROCFS_CNTR_STDDEV indicates that the counter should track sum of
+ * squares (for multi-valued counter samples only). This allows
+ * external computation of standard deviation, but involves a 64-bit
+ * multiply per counter increment.
+ */
+
+enum {
+	LPROCFS_CNTR_EXTERNALLOCK = 0x0001,
+	LPROCFS_CNTR_AVGMINMAX    = 0x0002,
+	LPROCFS_CNTR_STDDEV       = 0x0004,
+
+	/* counter data type */
+	LPROCFS_TYPE_REGS	 = 0x0100,
+	LPROCFS_TYPE_BYTES	= 0x0200,
+	LPROCFS_TYPE_PAGES	= 0x0400,
+	LPROCFS_TYPE_CYCLE	= 0x0800,
+};
+
+#define LC_MIN_INIT ((~(__u64)0) >> 1)
+
+struct lprocfs_counter_header {
+	unsigned int		lc_config;
+	const char		*lc_name;   /* must be static */
+	const char		*lc_units;  /* must be static */
+};
+
+struct lprocfs_counter {
+	__s64	lc_count;
+	__s64	lc_min;
+	__s64	lc_max;
+	__s64	lc_sumsquare;
+	/*
+	 * Every counter has lc_array_sum[0], while lc_array_sum[1] is only
+	 * for irq context counter, i.e. stats with
+	 * LPROCFS_STATS_FLAG_IRQ_SAFE flag, its counter need
+	 * lc_array_sum[1]
+	 */
+	__s64	lc_array_sum[1];
+};
+#define lc_sum		lc_array_sum[0]
+#define lc_sum_irq	lc_array_sum[1]
+
+struct lprocfs_percpu {
+#ifndef __GNUC__
+	__s64			pad;
+#endif
+	struct lprocfs_counter lp_cntr[0];
+};
+
+#define LPROCFS_GET_NUM_CPU 0x0001
+#define LPROCFS_GET_SMP_ID  0x0002
+
+enum lprocfs_stats_flags {
+	LPROCFS_STATS_FLAG_NONE     = 0x0000, /* per cpu counter */
+	LPROCFS_STATS_FLAG_NOPERCPU = 0x0001, /* stats have no percpu
+					       * area and need locking */
+	LPROCFS_STATS_FLAG_IRQ_SAFE = 0x0002, /* alloc need irq safe */
+};
+
+enum lprocfs_fields_flags {
+	LPROCFS_FIELDS_FLAGS_CONFIG     = 0x0001,
+	LPROCFS_FIELDS_FLAGS_SUM	= 0x0002,
+	LPROCFS_FIELDS_FLAGS_MIN	= 0x0003,
+	LPROCFS_FIELDS_FLAGS_MAX	= 0x0004,
+	LPROCFS_FIELDS_FLAGS_AVG	= 0x0005,
+	LPROCFS_FIELDS_FLAGS_SUMSQUARE  = 0x0006,
+	LPROCFS_FIELDS_FLAGS_COUNT      = 0x0007,
+};
+
+struct lprocfs_stats {
+	/* # of counters */
+	unsigned short			ls_num;
+	/* 1 + the biggest cpu # whose ls_percpu slot has been allocated */
+	unsigned short			ls_biggest_alloc_num;
+	enum lprocfs_stats_flags	ls_flags;
+	/* Lock used when there are no percpu stats areas; For percpu stats,
+	 * it is used to protect ls_biggest_alloc_num change */
+	spinlock_t			ls_lock;
+
+	/* has ls_num of counter headers */
+	struct lprocfs_counter_header	*ls_cnt_header;
+	struct lprocfs_percpu		*ls_percpu[0];
+};
+
+#define OPC_RANGE(seg) (seg ## _LAST_OPC - seg ## _FIRST_OPC)
+
+/* Pack all opcodes down into a single monotonically increasing index */
+static inline int opcode_offset(__u32 opc) {
+	if (opc < OST_LAST_OPC) {
+		 /* OST opcode */
+		return (opc - OST_FIRST_OPC);
+	} else if (opc < MDS_LAST_OPC) {
+		/* MDS opcode */
+		return (opc - MDS_FIRST_OPC +
+			OPC_RANGE(OST));
+	} else if (opc < LDLM_LAST_OPC) {
+		/* LDLM Opcode */
+		return (opc - LDLM_FIRST_OPC +
+			OPC_RANGE(MDS) +
+			OPC_RANGE(OST));
+	} else if (opc < MGS_LAST_OPC) {
+		/* MGS Opcode */
+		return (opc - MGS_FIRST_OPC +
+			OPC_RANGE(LDLM) +
+			OPC_RANGE(MDS) +
+			OPC_RANGE(OST));
+	} else if (opc < OBD_LAST_OPC) {
+		/* OBD Ping */
+		return (opc - OBD_FIRST_OPC +
+			OPC_RANGE(MGS) +
+			OPC_RANGE(LDLM) +
+			OPC_RANGE(MDS) +
+			OPC_RANGE(OST));
+	} else if (opc < LLOG_LAST_OPC) {
+		/* LLOG Opcode */
+		return (opc - LLOG_FIRST_OPC +
+			OPC_RANGE(OBD) +
+			OPC_RANGE(MGS) +
+			OPC_RANGE(LDLM) +
+			OPC_RANGE(MDS) +
+			OPC_RANGE(OST));
+	} else if (opc < QUOTA_LAST_OPC) {
+		/* LQUOTA Opcode */
+		return (opc - QUOTA_FIRST_OPC +
+			OPC_RANGE(LLOG) +
+			OPC_RANGE(OBD) +
+			OPC_RANGE(MGS) +
+			OPC_RANGE(LDLM) +
+			OPC_RANGE(MDS) +
+			OPC_RANGE(OST));
+	} else if (opc < SEQ_LAST_OPC) {
+		/* SEQ opcode */
+		return (opc - SEQ_FIRST_OPC +
+			OPC_RANGE(QUOTA) +
+			OPC_RANGE(LLOG) +
+			OPC_RANGE(OBD) +
+			OPC_RANGE(MGS) +
+			OPC_RANGE(LDLM) +
+			OPC_RANGE(MDS) +
+			OPC_RANGE(OST));
+	} else if (opc < SEC_LAST_OPC) {
+		/* SEC opcode */
+		return (opc - SEC_FIRST_OPC +
+			OPC_RANGE(SEQ) +
+			OPC_RANGE(QUOTA) +
+			OPC_RANGE(LLOG) +
+			OPC_RANGE(OBD) +
+			OPC_RANGE(MGS) +
+			OPC_RANGE(LDLM) +
+			OPC_RANGE(MDS) +
+			OPC_RANGE(OST));
+	} else if (opc < FLD_LAST_OPC) {
+		/* FLD opcode */
+		 return (opc - FLD_FIRST_OPC +
+			OPC_RANGE(SEC) +
+			OPC_RANGE(SEQ) +
+			OPC_RANGE(QUOTA) +
+			OPC_RANGE(LLOG) +
+			OPC_RANGE(OBD) +
+			OPC_RANGE(MGS) +
+			OPC_RANGE(LDLM) +
+			OPC_RANGE(MDS) +
+			OPC_RANGE(OST));
+	} else if (opc < UPDATE_LAST_OPC) {
+		/* update opcode */
+		return (opc - UPDATE_FIRST_OPC +
+			OPC_RANGE(FLD) +
+			OPC_RANGE(SEC) +
+			OPC_RANGE(SEQ) +
+			OPC_RANGE(QUOTA) +
+			OPC_RANGE(LLOG) +
+			OPC_RANGE(OBD) +
+			OPC_RANGE(MGS) +
+			OPC_RANGE(LDLM) +
+			OPC_RANGE(MDS) +
+			OPC_RANGE(OST));
+	} else {
+		/* Unknown Opcode */
+		return -1;
+	}
+}
+
+
+#define LUSTRE_MAX_OPCODES (OPC_RANGE(OST)  + \
+			    OPC_RANGE(MDS)  + \
+			    OPC_RANGE(LDLM) + \
+			    OPC_RANGE(MGS)  + \
+			    OPC_RANGE(OBD)  + \
+			    OPC_RANGE(LLOG) + \
+			    OPC_RANGE(SEC)  + \
+			    OPC_RANGE(SEQ)  + \
+			    OPC_RANGE(SEC)  + \
+			    OPC_RANGE(FLD)  + \
+			    OPC_RANGE(UPDATE))
+
+#define EXTRA_MAX_OPCODES ((PTLRPC_LAST_CNTR - PTLRPC_FIRST_CNTR)  + \
+			    OPC_RANGE(EXTRA))
+
+enum {
+	PTLRPC_REQWAIT_CNTR = 0,
+	PTLRPC_REQQDEPTH_CNTR,
+	PTLRPC_REQACTIVE_CNTR,
+	PTLRPC_TIMEOUT,
+	PTLRPC_REQBUF_AVAIL_CNTR,
+	PTLRPC_LAST_CNTR
+};
+
+#define PTLRPC_FIRST_CNTR PTLRPC_REQWAIT_CNTR
+
+enum {
+	LDLM_GLIMPSE_ENQUEUE = 0,
+	LDLM_PLAIN_ENQUEUE,
+	LDLM_EXTENT_ENQUEUE,
+	LDLM_FLOCK_ENQUEUE,
+	LDLM_IBITS_ENQUEUE,
+	MDS_REINT_SETATTR,
+	MDS_REINT_CREATE,
+	MDS_REINT_LINK,
+	MDS_REINT_UNLINK,
+	MDS_REINT_RENAME,
+	MDS_REINT_OPEN,
+	MDS_REINT_SETXATTR,
+	BRW_READ_BYTES,
+	BRW_WRITE_BYTES,
+	EXTRA_LAST_OPC
+};
+
+#define EXTRA_FIRST_OPC LDLM_GLIMPSE_ENQUEUE
+/* class_obd.c */
+extern proc_dir_entry_t *proc_lustre_root;
+
+struct obd_device;
+struct obd_histogram;
+
+/* Days / hours / mins / seconds format */
+struct dhms {
+	int d,h,m,s;
+};
+static inline void s2dhms(struct dhms *ts, time_t secs)
+{
+	ts->d = secs / 86400;
+	secs = secs % 86400;
+	ts->h = secs / 3600;
+	secs = secs % 3600;
+	ts->m = secs / 60;
+	ts->s = secs % 60;
+}
+#define DHMS_FMT "%dd%dh%02dm%02ds"
+#define DHMS_VARS(x) (x)->d, (x)->h, (x)->m, (x)->s
+
+#define JOBSTATS_JOBID_VAR_MAX_LEN	20
+#define JOBSTATS_DISABLE		"disable"
+#define JOBSTATS_PROCNAME_UID		"procname_uid"
+
+typedef void (*cntr_init_callback)(struct lprocfs_stats *stats);
+
+struct obd_job_stats {
+	cfs_hash_t	*ojs_hash;
+	struct list_head	 ojs_list;
+	rwlock_t       ojs_lock; /* protect the obj_list */
+	cntr_init_callback ojs_cntr_init_fn;
+	int		ojs_cntr_num;
+	int		ojs_cleanup_interval;
+	time_t		   ojs_last_cleanup;
+};
+
+#ifdef LPROCFS
+
+extern int lprocfs_stats_alloc_one(struct lprocfs_stats *stats,
+				   unsigned int cpuid);
+/*
+ * \return value
+ *      < 0     : on error (only possible for opc as LPROCFS_GET_SMP_ID)
+ */
+static inline int lprocfs_stats_lock(struct lprocfs_stats *stats, int opc,
+				     unsigned long *flags)
+{
+	int		rc = 0;
+
+	switch (opc) {
+	default:
+		LBUG();
+
+	case LPROCFS_GET_SMP_ID:
+		if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+			if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
+				spin_lock_irqsave(&stats->ls_lock, *flags);
+			else
+				spin_lock(&stats->ls_lock);
+			return 0;
+		} else {
+			unsigned int cpuid = get_cpu();
+
+			if (unlikely(stats->ls_percpu[cpuid] == NULL)) {
+				rc = lprocfs_stats_alloc_one(stats, cpuid);
+				if (rc < 0) {
+					put_cpu();
+					return rc;
+				}
+			}
+			return cpuid;
+		}
+
+	case LPROCFS_GET_NUM_CPU:
+		if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+			if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
+				spin_lock_irqsave(&stats->ls_lock, *flags);
+			else
+				spin_lock(&stats->ls_lock);
+			return 1;
+		} else {
+			return stats->ls_biggest_alloc_num;
+		}
+	}
+}
+
+static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats, int opc,
+					unsigned long *flags)
+{
+	switch (opc) {
+	default:
+		LBUG();
+
+	case LPROCFS_GET_SMP_ID:
+		if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+			if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) {
+				spin_unlock_irqrestore(&stats->ls_lock,
+							   *flags);
+			} else {
+				spin_unlock(&stats->ls_lock);
+			}
+		} else {
+			put_cpu();
+		}
+		return;
+
+	case LPROCFS_GET_NUM_CPU:
+		if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
+			if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) {
+				spin_unlock_irqrestore(&stats->ls_lock,
+							   *flags);
+			} else {
+				spin_unlock(&stats->ls_lock);
+			}
+		}
+		return;
+	}
+}
+
+static inline unsigned int
+lprocfs_stats_counter_size(struct lprocfs_stats *stats)
+{
+	unsigned int percpusize;
+
+	percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
+
+	/* irq safe stats need lc_array_sum[1] */
+	if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
+		percpusize += stats->ls_num * sizeof(__s64);
+
+	if ((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0)
+		percpusize = L1_CACHE_ALIGN(percpusize);
+
+	return percpusize;
+}
+
+static inline struct lprocfs_counter *
+lprocfs_stats_counter_get(struct lprocfs_stats *stats, unsigned int cpuid,
+			  int index)
+{
+	struct lprocfs_counter *cntr;
+
+	cntr = &stats->ls_percpu[cpuid]->lp_cntr[index];
+
+	if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
+		cntr = (void *)cntr + index * sizeof(__s64);
+
+	return cntr;
+}
+
+/* Two optimized LPROCFS counter increment functions are provided:
+ *     lprocfs_counter_incr(cntr, value) - optimized for by-one counters
+ *     lprocfs_counter_add(cntr) - use for multi-valued counters
+ * Counter data layout allows config flag, counter lock and the
+ * count itself to reside within a single cache line.
+ */
+
+extern void lprocfs_counter_add(struct lprocfs_stats *stats, int idx,
+				long amount);
+extern void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx,
+				long amount);
+
+#define lprocfs_counter_incr(stats, idx) \
+	lprocfs_counter_add(stats, idx, 1)
+#define lprocfs_counter_decr(stats, idx) \
+	lprocfs_counter_sub(stats, idx, 1)
+
+extern __s64 lprocfs_read_helper(struct lprocfs_counter *lc,
+				 struct lprocfs_counter_header *header,
+				 enum lprocfs_stats_flags flags,
+				 enum lprocfs_fields_flags field);
+static inline __u64 lprocfs_stats_collector(struct lprocfs_stats *stats,
+					    int idx,
+					    enum lprocfs_fields_flags field)
+{
+	int	      i;
+	unsigned int  num_cpu;
+	unsigned long flags	= 0;
+	__u64	      ret	= 0;
+
+	LASSERT(stats != NULL);
+
+	num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
+	for (i = 0; i < num_cpu; i++) {
+		if (stats->ls_percpu[i] == NULL)
+			continue;
+		ret += lprocfs_read_helper(
+				lprocfs_stats_counter_get(stats, i, idx),
+				&stats->ls_cnt_header[idx], stats->ls_flags,
+				field);
+	}
+	lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
+	return ret;
+}
+
+extern struct lprocfs_stats *
+lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags);
+extern void lprocfs_clear_stats(struct lprocfs_stats *stats);
+extern void lprocfs_free_stats(struct lprocfs_stats **stats);
+extern void lprocfs_init_ops_stats(int num_private_stats,
+				   struct lprocfs_stats *stats);
+extern void lprocfs_init_mps_stats(int num_private_stats,
+				   struct lprocfs_stats *stats);
+extern void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats);
+extern int lprocfs_alloc_obd_stats(struct obd_device *obddev,
+				   unsigned int num_private_stats);
+extern int lprocfs_alloc_md_stats(struct obd_device *obddev,
+				  unsigned int num_private_stats);
+extern void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
+				 unsigned conf, const char *name,
+				 const char *units);
+extern void lprocfs_free_obd_stats(struct obd_device *obddev);
+extern void lprocfs_free_md_stats(struct obd_device *obddev);
+struct obd_export;
+struct nid_stat;
+extern int lprocfs_add_clear_entry(struct obd_device * obd,
+				   proc_dir_entry_t *entry);
+extern int lprocfs_exp_setup(struct obd_export *exp,
+			     lnet_nid_t *peer_nid, int *newnid);
+extern int lprocfs_exp_cleanup(struct obd_export *exp);
+extern proc_dir_entry_t *lprocfs_add_simple(struct proc_dir_entry *root,
+						char *name,
+						void *data,
+						struct file_operations *fops);
+extern struct proc_dir_entry *
+lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent,
+		    const char *format, ...);
+extern void lprocfs_free_per_client_stats(struct obd_device *obd);
+extern int
+lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
+			      unsigned long count, void *data);
+extern int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data);
+
+extern int lprocfs_register_stats(proc_dir_entry_t *root, const char *name,
+				  struct lprocfs_stats *stats);
+
+/* lprocfs_status.c */
+extern int lprocfs_add_vars(proc_dir_entry_t *root,
+			    struct lprocfs_vars *var,
+			    void *data);
+
+extern proc_dir_entry_t *lprocfs_register(const char *name,
+					      proc_dir_entry_t *parent,
+					      struct lprocfs_vars *list,
+					      void *data);
+
+extern void lprocfs_remove(proc_dir_entry_t **root);
+extern void lprocfs_remove_proc_entry(const char *name,
+				      struct proc_dir_entry *parent);
+
+extern int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list);
+extern int lprocfs_obd_cleanup(struct obd_device *obd);
+
+extern int lprocfs_seq_create(proc_dir_entry_t *parent, const char *name,
+			      umode_t mode,
+			      const struct file_operations *seq_fops,
+			      void *data);
+extern int lprocfs_obd_seq_create(struct obd_device *dev, const char *name,
+				  umode_t mode,
+				  const struct file_operations *seq_fops,
+				  void *data);
+
+/* Generic callbacks */
+
+extern int lprocfs_rd_u64(struct seq_file *m, void *data);
+extern int lprocfs_rd_atomic(struct seq_file *m, void *data);
+extern int lprocfs_wr_atomic(struct file *file, const char *buffer,
+			     unsigned long count, void *data);
+extern int lprocfs_rd_uint(struct seq_file *m, void *data);
+extern int lprocfs_wr_uint(struct file *file, const char *buffer,
+			   unsigned long count, void *data);
+extern int lprocfs_rd_uuid(struct seq_file *m, void *data);
+extern int lprocfs_rd_name(struct seq_file *m, void *data);
+extern int lprocfs_rd_server_uuid(struct seq_file *m, void *data);
+extern int lprocfs_rd_conn_uuid(struct seq_file *m, void *data);
+extern int lprocfs_rd_import(struct seq_file *m, void *data);
+extern int lprocfs_rd_state(struct seq_file *m, void *data);
+extern int lprocfs_rd_connect_flags(struct seq_file *m, void *data);
+extern int lprocfs_rd_num_exports(struct seq_file *m, void *data);
+extern int lprocfs_rd_numrefs(struct seq_file *m, void *data);
+
+struct adaptive_timeout;
+extern int lprocfs_at_hist_helper(struct seq_file *m,
+				  struct adaptive_timeout *at);
+extern int lprocfs_rd_timeouts(struct seq_file *m, void *data);
+extern int lprocfs_wr_timeouts(struct file *file, const char *buffer,
+			       unsigned long count, void *data);
+extern int lprocfs_wr_evict_client(struct file *file, const char *buffer,
+			    size_t count, loff_t *off);
+extern int lprocfs_wr_ping(struct file *file, const char *buffer,
+			   size_t count, loff_t *off);
+extern int lprocfs_wr_import(struct file *file, const char *buffer,
+		      size_t count, loff_t *off);
+extern int lprocfs_rd_pinger_recov(struct seq_file *m, void *n);
+extern int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
+				   size_t count, loff_t *off);
+
+/* Statfs helpers */
+extern int lprocfs_rd_blksize(struct seq_file *m, void *data);
+extern int lprocfs_rd_kbytestotal(struct seq_file *m, void *data);
+extern int lprocfs_rd_kbytesfree(struct seq_file *m, void *data);
+extern int lprocfs_rd_kbytesavail(struct seq_file *m, void *data);
+extern int lprocfs_rd_filestotal(struct seq_file *m, void *data);
+extern int lprocfs_rd_filesfree(struct seq_file *m, void *data);
+
+extern int lprocfs_write_helper(const char *buffer, unsigned long count,
+				int *val);
+extern int lprocfs_write_frac_helper(const char *buffer, unsigned long count,
+				     int *val, int mult);
+extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult);
+extern int lprocfs_read_frac_helper(char *buffer, unsigned long count,
+				    long val, int mult);
+extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count,
+				    __u64 *val);
+extern int lprocfs_write_frac_u64_helper(const char *buffer,
+					 unsigned long count,
+					 __u64 *val, int mult);
+char *lprocfs_find_named_value(const char *buffer, const char *name,
+				unsigned long *count);
+void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value);
+void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value);
+void lprocfs_oh_clear(struct obd_histogram *oh);
+unsigned long lprocfs_oh_sum(struct obd_histogram *oh);
+
+void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
+			   struct lprocfs_counter *cnt);
+
+extern int lprocfs_single_release(cfs_inode_t *, struct file *);
+extern int lprocfs_seq_release(cfs_inode_t *, struct file *);
+
+/* You must use these macros when you want to refer to
+ * the import in a client obd_device for a lprocfs entry */
+#define LPROCFS_CLIMP_CHECK(obd) do {	   \
+	typecheck(struct obd_device *, obd);    \
+	down_read(&(obd)->u.cli.cl_sem);    \
+	if ((obd)->u.cli.cl_import == NULL) {   \
+	     up_read(&(obd)->u.cli.cl_sem); \
+	     return -ENODEV;		    \
+	}				       \
+} while(0)
+#define LPROCFS_CLIMP_EXIT(obd)		 \
+	up_read(&(obd)->u.cli.cl_sem);
+
+
+/* write the name##_seq_show function, call LPROC_SEQ_FOPS_RO for read-only
+  proc entries; otherwise, you will define name##_seq_write function also for
+  a read-write proc entry, and then call LPROC_SEQ_SEQ instead. Finally,
+  call lprocfs_obd_seq_create(obd, filename, 0444, &name#_fops, data); */
+#define __LPROC_SEQ_FOPS(name, custom_seq_write)			\
+static int name##_single_open(cfs_inode_t *inode, struct file *file)	\
+{									\
+	return single_open(file, name##_seq_show, PDE_DATA(inode));	\
+}									\
+struct file_operations name##_fops = {				     \
+	.owner   = THIS_MODULE,					    \
+	.open    = name##_single_open,				     \
+	.read    = seq_read,					       \
+	.write   = custom_seq_write,				       \
+	.llseek  = seq_lseek,					      \
+	.release = lprocfs_single_release,				 \
+}
+
+#define LPROC_SEQ_FOPS_RO(name)	 __LPROC_SEQ_FOPS(name, NULL)
+#define LPROC_SEQ_FOPS(name)	    __LPROC_SEQ_FOPS(name, name##_seq_write)
+
+#define LPROC_SEQ_FOPS_RO_TYPE(name, type)				\
+	static int name##_##type##_seq_show(struct seq_file *m, void *v)\
+	{								\
+		return lprocfs_rd_##type(m, m->private);		\
+	}								\
+	LPROC_SEQ_FOPS_RO(name##_##type)
+
+#define LPROC_SEQ_FOPS_RW_TYPE(name, type)				\
+	static int name##_##type##_seq_show(struct seq_file *m, void *v)\
+	{								\
+		return lprocfs_rd_##type(m, m->private);		\
+	}								\
+	static ssize_t name##_##type##_seq_write(struct file *file,	\
+			const char *buffer, size_t count, loff_t *off)	\
+	{								\
+		struct seq_file *seq = file->private_data;		\
+		return lprocfs_wr_##type(file, buffer,			\
+					 count, seq->private);		\
+	}								\
+	LPROC_SEQ_FOPS(name##_##type);
+
+#define LPROC_SEQ_FOPS_WR_ONLY(name, type)				\
+	static ssize_t name##_##type##_write(struct file *file,		\
+			const char *buffer, size_t count, loff_t *off)	\
+	{								\
+		return lprocfs_wr_##type(file, buffer, count, off);	\
+	}								\
+	static int name##_##type##_open(cfs_inode_t *inode, struct file *file) \
+	{								\
+		return single_open(file, NULL, PDE_DATA(inode));	\
+	}								\
+	struct file_operations name##_##type##_fops = {			\
+		.open	= name##_##type##_open,				\
+		.write	= name##_##type##_write,			\
+		.release = lprocfs_single_release,			\
+	};
+
+/* lprocfs_jobstats.c */
+int lprocfs_job_stats_log(struct obd_device *obd, char *jobid,
+			  int event, long amount);
+void lprocfs_job_stats_fini(struct obd_device *obd);
+int lprocfs_job_stats_init(struct obd_device *obd, int cntr_num,
+			   cntr_init_callback fn);
+int lprocfs_rd_job_interval(struct seq_file *m, void *data);
+int lprocfs_wr_job_interval(struct file *file, const char *buffer,
+			    unsigned long count, void *data);
+
+/* lproc_ptlrpc.c */
+struct ptlrpc_request;
+extern void target_print_req(void *seq_file, struct ptlrpc_request *req);
+
+/* lproc_status.c */
+int lprocfs_obd_rd_max_pages_per_rpc(struct seq_file *m, void *data);
+int lprocfs_obd_wr_max_pages_per_rpc(struct file *file, const char *buffer,
+				     size_t count, loff_t *off);
+
+/* all quota proc functions */
+extern int lprocfs_quota_rd_bunit(char *page, char **start,
+				  loff_t off, int count,
+				  int *eof, void *data);
+extern int lprocfs_quota_wr_bunit(struct file *file, const char *buffer,
+				  unsigned long count, void *data);
+extern int lprocfs_quota_rd_btune(char *page, char **start,
+				  loff_t off, int count,
+				  int *eof, void *data);
+extern int lprocfs_quota_wr_btune(struct file *file, const char *buffer,
+				  unsigned long count, void *data);
+extern int lprocfs_quota_rd_iunit(char *page, char **start,
+				  loff_t off, int count,
+				  int *eof, void *data);
+extern int lprocfs_quota_wr_iunit(struct file *file, const char *buffer,
+				  unsigned long count, void *data);
+extern int lprocfs_quota_rd_itune(char *page, char **start,
+				  loff_t off, int count,
+				  int *eof, void *data);
+extern int lprocfs_quota_wr_itune(struct file *file, const char *buffer,
+				  unsigned long count, void *data);
+extern int lprocfs_quota_rd_type(char *page, char **start, loff_t off, int count,
+				 int *eof, void *data);
+extern int lprocfs_quota_wr_type(struct file *file, const char *buffer,
+				 unsigned long count, void *data);
+extern int lprocfs_quota_rd_switch_seconds(char *page, char **start, loff_t off,
+					   int count, int *eof, void *data);
+extern int lprocfs_quota_wr_switch_seconds(struct file *file,
+					   const char *buffer,
+					   unsigned long count, void *data);
+extern int lprocfs_quota_rd_sync_blk(char *page, char **start, loff_t off,
+				     int count, int *eof, void *data);
+extern int lprocfs_quota_wr_sync_blk(struct file *file, const char *buffer,
+				     unsigned long count, void *data);
+extern int lprocfs_quota_rd_switch_qs(char *page, char **start, loff_t off,
+				      int count, int *eof, void *data);
+extern int lprocfs_quota_wr_switch_qs(struct file *file,
+				      const char *buffer,
+				      unsigned long count, void *data);
+extern int lprocfs_quota_rd_boundary_factor(char *page, char **start, loff_t off,
+					    int count, int *eof, void *data);
+extern int lprocfs_quota_wr_boundary_factor(struct file *file,
+					    const char *buffer,
+					    unsigned long count, void *data);
+extern int lprocfs_quota_rd_least_bunit(char *page, char **start, loff_t off,
+					int count, int *eof, void *data);
+extern int lprocfs_quota_wr_least_bunit(struct file *file,
+					const char *buffer,
+					unsigned long count, void *data);
+extern int lprocfs_quota_rd_least_iunit(char *page, char **start, loff_t off,
+					int count, int *eof, void *data);
+extern int lprocfs_quota_wr_least_iunit(struct file *file,
+					const char *buffer,
+					unsigned long count, void *data);
+extern int lprocfs_quota_rd_qs_factor(char *page, char **start, loff_t off,
+				      int count, int *eof, void *data);
+extern int lprocfs_quota_wr_qs_factor(struct file *file,
+				      const char *buffer,
+				      unsigned long count, void *data);
+
+
+
+#else
+/* LPROCFS is not defined */
+
+#define proc_lustre_root NULL
+
+static inline void lprocfs_counter_add(struct lprocfs_stats *stats,
+				       int index, long amount)
+{ return; }
+static inline void lprocfs_counter_incr(struct lprocfs_stats *stats,
+					int index)
+{ return; }
+static inline void lprocfs_counter_sub(struct lprocfs_stats *stats,
+				       int index, long amount)
+{ return; }
+static inline void lprocfs_counter_decr(struct lprocfs_stats *stats,
+					int index)
+{ return; }
+static inline void lprocfs_counter_init(struct lprocfs_stats *stats,
+					int index, unsigned conf,
+					const char *name, const char *units)
+{ return; }
+
+static inline __u64 lc_read_helper(struct lprocfs_counter *lc,
+				   enum lprocfs_fields_flags field)
+{ return 0; }
+
+/* NB: we return !NULL to satisfy error checker */
+static inline struct lprocfs_stats *
+lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags)
+{ return (struct lprocfs_stats *)1; }
+static inline void lprocfs_clear_stats(struct lprocfs_stats *stats)
+{ return; }
+static inline void lprocfs_free_stats(struct lprocfs_stats **stats)
+{ return; }
+static inline int lprocfs_register_stats(proc_dir_entry_t *root,
+					 const char *name,
+					 struct lprocfs_stats *stats)
+{ return 0; }
+static inline void lprocfs_init_ops_stats(int num_private_stats,
+					  struct lprocfs_stats *stats)
+{ return; }
+static inline void lprocfs_init_mps_stats(int num_private_stats,
+					  struct lprocfs_stats *stats)
+{ return; }
+static inline void lprocfs_init_ldlm_stats(struct lprocfs_stats *ldlm_stats)
+{ return; }
+static inline int lprocfs_alloc_obd_stats(struct obd_device *obddev,
+					  unsigned int num_private_stats)
+{ return 0; }
+static inline int lprocfs_alloc_md_stats(struct obd_device *obddev,
+					 unsigned int num_private_stats)
+{ return 0; }
+static inline void lprocfs_free_obd_stats(struct obd_device *obddev)
+{ return; }
+static inline void lprocfs_free_md_stats(struct obd_device *obddev)
+{ return; }
+
+struct obd_export;
+static inline int lprocfs_add_clear_entry(struct obd_export *exp)
+{ return 0; }
+static inline int lprocfs_exp_setup(struct obd_export *exp,lnet_nid_t *peer_nid,
+				    int *newnid)
+{ return 0; }
+static inline int lprocfs_exp_cleanup(struct obd_export *exp)
+{ return 0; }
+static inline proc_dir_entry_t *
+lprocfs_add_simple(struct proc_dir_entry *root, char *name,
+		   void *data, struct file_operations *fops)
+{return 0; }
+static inline struct proc_dir_entry *
+lprocfs_add_symlink(const char *name, struct proc_dir_entry *parent,
+		    const char *format, ...)
+{return NULL; }
+static inline void lprocfs_free_per_client_stats(struct obd_device *obd)
+{ return; }
+static inline
+int lprocfs_nid_stats_clear_write(struct file *file, const char *buffer,
+				  unsigned long count, void *data)
+{return count;}
+static inline
+int lprocfs_nid_stats_clear_read(struct seq_file *m, void *data)
+{ return 0; }
+
+static inline proc_dir_entry_t *
+lprocfs_register(const char *name, proc_dir_entry_t *parent,
+		 struct lprocfs_vars *list, void *data)
+{ return NULL; }
+static inline int lprocfs_add_vars(proc_dir_entry_t *root,
+				   struct lprocfs_vars *var,
+				   void *data)
+{ return 0; }
+static inline void lprocfs_remove(proc_dir_entry_t **root)
+{ return; }
+static inline void lprocfs_remove_proc_entry(const char *name,
+					     struct proc_dir_entry *parent)
+{ return; }
+static inline int lprocfs_obd_setup(struct obd_device *dev,
+				    struct lprocfs_vars *list)
+{ return 0; }
+static inline int lprocfs_obd_cleanup(struct obd_device *dev)
+{ return 0; }
+static inline int lprocfs_rd_u64(struct seq_file *m, void *data)
+{ return 0; }
+static inline int lprocfs_rd_uuid(struct seq_file *m, void *data)
+{ return 0; }
+static inline int lprocfs_rd_name(struct seq_file *m, void *data)
+{ return 0; }
+static inline int lprocfs_rd_server_uuid(struct seq_file *m, void *data)
+{ return 0; }
+static inline int lprocfs_rd_conn_uuid(struct seq_file *m, void *data)
+{ return 0; }
+static inline int lprocfs_rd_import(struct seq_file *m, void *data)
+{ return 0; }
+static inline int lprocfs_rd_pinger_recov(struct seq_file *m, void *n)
+{ return 0; }
+static inline int lprocfs_rd_state(struct seq_file *m, void *data)
+{ return 0; }
+static inline int lprocfs_rd_connect_flags(struct seq_file *m, void *data)
+{ return 0; }
+static inline int lprocfs_rd_num_exports(struct seq_file *m, void *data)
+{ return 0; }
+extern inline int lprocfs_rd_numrefs(struct seq_file *m, void *data)
+{ return 0; }
+struct adaptive_timeout;
+static inline int lprocfs_at_hist_helper(struct seq_file *m,
+					 struct adaptive_timeout *at)
+{ return 0; }
+static inline int lprocfs_rd_timeouts(struct seq_file *m, void *data)
+{ return 0; }
+static inline int lprocfs_wr_timeouts(struct file *file,
+				      const char *buffer,
+				      unsigned long count, void *data)
+{ return 0; }
+static inline int lprocfs_wr_evict_client(struct file *file, const char *buffer,
+				    size_t count, loff_t *off)
+{ return 0; }
+static inline int lprocfs_wr_ping(struct file *file, const char *buffer,
+			   size_t count, loff_t *off)
+{ return 0; }
+static inline int lprocfs_wr_import(struct file *file, const char *buffer,
+			      size_t count, loff_t *off)
+{ return 0; }
+static inline int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
+					size_t count, loff_t *off)
+{ return 0; }
+
+/* Statfs helpers */
+static inline
+int lprocfs_rd_blksize(struct seq_file *m, void *data)
+{ return 0; }
+static inline
+int lprocfs_rd_kbytestotal(struct seq_file *m, void *data)
+{ return 0; }
+static inline
+int lprocfs_rd_kbytesfree(struct seq_file *m, void *data)
+{ return 0; }
+static inline
+int lprocfs_rd_kbytesavail(struct seq_file *m, void *data)
+{ return 0; }
+static inline
+int lprocfs_rd_filestotal(struct seq_file *m, void *data)
+{ return 0; }
+static inline
+int lprocfs_rd_filesfree(struct seq_file *m, void *data)
+{ return 0; }
+static inline
+void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
+{ return; }
+static inline
+void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value)
+{ return; }
+static inline
+void lprocfs_oh_clear(struct obd_histogram *oh)
+{ return; }
+static inline
+unsigned long lprocfs_oh_sum(struct obd_histogram *oh)
+{ return 0; }
+static inline
+void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
+			   struct lprocfs_counter *cnt)
+{ return; }
+static inline
+__u64 lprocfs_stats_collector(struct lprocfs_stats *stats, int idx,
+			       enum lprocfs_fields_flags field)
+{ return (__u64)0; }
+
+#define LPROC_SEQ_FOPS_RO(name)
+#define LPROC_SEQ_FOPS(name)
+#define LPROC_SEQ_FOPS_RO_TYPE(name, type)
+#define LPROC_SEQ_FOPS_RW_TYPE(name, type)
+#define LPROC_SEQ_FOPS_WR_ONLY(name, type)
+
+/* lprocfs_jobstats.c */
+static inline
+int lprocfs_job_stats_log(struct obd_device *obd, char *jobid, int event,
+			  long amount)
+{ return 0; }
+static inline
+void lprocfs_job_stats_fini(struct obd_device *obd)
+{ return; }
+static inline
+int lprocfs_job_stats_init(struct obd_device *obd, int cntr_num,
+			   cntr_init_callback fn)
+{ return 0; }
+
+
+/* lproc_ptlrpc.c */
+#define target_print_req NULL
+
+#endif /* LPROCFS */
+
+#endif /* LPROCFS_SNMP_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lu_object.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lu_object.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lu_object.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lu_object.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1346 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LUSTRE_LU_OBJECT_H
+#define __LUSTRE_LU_OBJECT_H
+
+#include <stdarg.h>
+#include <linux/libcfs/libcfs.h>
+#include <lustre/lustre_idl.h>
+#include <lu_ref.h>
+
+struct seq_file;
+struct proc_dir_entry;
+struct lustre_cfg;
+struct lprocfs_stats;
+
+/** \defgroup lu lu
+ * lu_* data-types represent server-side entities shared by data and meta-data
+ * stacks.
+ *
+ * Design goals:
+ *
+ * -# support for layering.
+ *
+ *     Server side object is split into layers, one per device in the
+ *     corresponding device stack. Individual layer is represented by struct
+ *     lu_object. Compound layered object --- by struct lu_object_header. Most
+ *     interface functions take lu_object as an argument and operate on the
+ *     whole compound object. This decision was made due to the following
+ *     reasons:
+ *
+ *	- it's envisaged that lu_object will be used much more often than
+ *	lu_object_header;
+ *
+ *	- we want lower (non-top) layers to be able to initiate operations
+ *	on the whole object.
+ *
+ *     Generic code supports layering more complex than simple stacking, e.g.,
+ *     it is possible that at some layer object "spawns" multiple sub-objects
+ *     on the lower layer.
+ *
+ * -# fid-based identification.
+ *
+ *     Compound object is uniquely identified by its fid. Objects are indexed
+ *     by their fids (hash table is used for index).
+ *
+ * -# caching and life-cycle management.
+ *
+ *     Object's life-time is controlled by reference counting. When reference
+ *     count drops to 0, object is returned to cache. Cached objects still
+ *     retain their identity (i.e., fid), and can be recovered from cache.
+ *
+ *     Objects are kept in the global LRU list, and lu_site_purge() function
+ *     can be used to reclaim given number of unused objects from the tail of
+ *     the LRU.
+ *
+ * -# avoiding recursion.
+ *
+ *     Generic code tries to replace recursion through layers by iterations
+ *     where possible. Additionally to the end of reducing stack consumption,
+ *     data, when practically possible, are allocated through lu_context_key
+ *     interface rather than on stack.
+ * @{
+ */
+
+struct lu_site;
+struct lu_object;
+struct lu_device;
+struct lu_object_header;
+struct lu_context;
+struct lu_env;
+
+/**
+ * Operations common for data and meta-data devices.
+ */
+struct lu_device_operations {
+	/**
+	 * Allocate object for the given device (without lower-layer
+	 * parts). This is called by lu_object_operations::loo_object_init()
+	 * from the parent layer, and should setup at least lu_object::lo_dev
+	 * and lu_object::lo_ops fields of resulting lu_object.
+	 *
+	 * Object creation protocol.
+	 *
+	 * Due to design goal of avoiding recursion, object creation (see
+	 * lu_object_alloc()) is somewhat involved:
+	 *
+	 *  - first, lu_device_operations::ldo_object_alloc() method of the
+	 *  top-level device in the stack is called. It should allocate top
+	 *  level object (including lu_object_header), but without any
+	 *  lower-layer sub-object(s).
+	 *
+	 *  - then lu_object_alloc() sets fid in the header of newly created
+	 *  object.
+	 *
+	 *  - then lu_object_operations::loo_object_init() is called. It has
+	 *  to allocate lower-layer object(s). To do this,
+	 *  lu_object_operations::loo_object_init() calls ldo_object_alloc()
+	 *  of the lower-layer device(s).
+	 *
+	 *  - for all new objects allocated by
+	 *  lu_object_operations::loo_object_init() (and inserted into object
+	 *  stack), lu_object_operations::loo_object_init() is called again
+	 *  repeatedly, until no new objects are created.
+	 *
+	 * \post ergo(!IS_ERR(result), result->lo_dev == d &&
+	 *			     result->lo_ops != NULL);
+	 */
+	struct lu_object *(*ldo_object_alloc)(const struct lu_env *env,
+					      const struct lu_object_header *h,
+					      struct lu_device *d);
+	/**
+	 * process config specific for device.
+	 */
+	int (*ldo_process_config)(const struct lu_env *env,
+				  struct lu_device *, struct lustre_cfg *);
+	int (*ldo_recovery_complete)(const struct lu_env *,
+				     struct lu_device *);
+
+	/**
+	 * initialize local objects for device. this method called after layer has
+	 * been initialized (after LCFG_SETUP stage) and before it starts serving
+	 * user requests.
+	 */
+
+	int (*ldo_prepare)(const struct lu_env *,
+			   struct lu_device *parent,
+			   struct lu_device *dev);
+
+};
+
+/**
+ * For lu_object_conf flags
+ */
+typedef enum {
+	/* This is a new object to be allocated, or the file
+	 * corresponding to the object does not exists. */
+	LOC_F_NEW	= 0x00000001,
+} loc_flags_t;
+
+/**
+ * Object configuration, describing particulars of object being created. On
+ * server this is not used, as server objects are full identified by fid. On
+ * client configuration contains struct lustre_md.
+ */
+struct lu_object_conf {
+	/**
+	 * Some hints for obj find and alloc.
+	 */
+	loc_flags_t     loc_flags;
+};
+
+/**
+ * Type of "printer" function used by lu_object_operations::loo_object_print()
+ * method.
+ *
+ * Printer function is needed to provide some flexibility in (semi-)debugging
+ * output: possible implementations: printk, CDEBUG, sysfs/seq_file
+ */
+typedef int (*lu_printer_t)(const struct lu_env *env,
+			    void *cookie, const char *format, ...)
+	__attribute__ ((format (printf, 3, 4)));
+
+/**
+ * Operations specific for particular lu_object.
+ */
+struct lu_object_operations {
+
+	/**
+	 * Allocate lower-layer parts of the object by calling
+	 * lu_device_operations::ldo_object_alloc() of the corresponding
+	 * underlying device.
+	 *
+	 * This method is called once for each object inserted into object
+	 * stack. It's responsibility of this method to insert lower-layer
+	 * object(s) it create into appropriate places of object stack.
+	 */
+	int (*loo_object_init)(const struct lu_env *env,
+			       struct lu_object *o,
+			       const struct lu_object_conf *conf);
+	/**
+	 * Called (in top-to-bottom order) during object allocation after all
+	 * layers were allocated and initialized. Can be used to perform
+	 * initialization depending on lower layers.
+	 */
+	int (*loo_object_start)(const struct lu_env *env,
+				struct lu_object *o);
+	/**
+	 * Called before lu_object_operations::loo_object_free() to signal
+	 * that object is being destroyed. Dual to
+	 * lu_object_operations::loo_object_init().
+	 */
+	void (*loo_object_delete)(const struct lu_env *env,
+				  struct lu_object *o);
+	/**
+	 * Dual to lu_device_operations::ldo_object_alloc(). Called when
+	 * object is removed from memory.
+	 */
+	void (*loo_object_free)(const struct lu_env *env,
+				struct lu_object *o);
+	/**
+	 * Called when last active reference to the object is released (and
+	 * object returns to the cache). This method is optional.
+	 */
+	void (*loo_object_release)(const struct lu_env *env,
+				   struct lu_object *o);
+	/**
+	 * Optional debugging helper. Print given object.
+	 */
+	int (*loo_object_print)(const struct lu_env *env, void *cookie,
+				lu_printer_t p, const struct lu_object *o);
+	/**
+	 * Optional debugging method. Returns true iff method is internally
+	 * consistent.
+	 */
+	int (*loo_object_invariant)(const struct lu_object *o);
+};
+
+/**
+ * Type of lu_device.
+ */
+struct lu_device_type;
+
+/**
+ * Device: a layer in the server side abstraction stacking.
+ */
+struct lu_device {
+	/**
+	 * reference count. This is incremented, in particular, on each object
+	 * created at this layer.
+	 *
+	 * \todo XXX which means that atomic_t is probably too small.
+	 */
+	atomic_t		       ld_ref;
+	/**
+	 * Pointer to device type. Never modified once set.
+	 */
+	struct lu_device_type       *ld_type;
+	/**
+	 * Operation vector for this device.
+	 */
+	const struct lu_device_operations *ld_ops;
+	/**
+	 * Stack this device belongs to.
+	 */
+	struct lu_site		    *ld_site;
+	struct proc_dir_entry	     *ld_proc_entry;
+
+	/** \todo XXX: temporary back pointer into obd. */
+	struct obd_device		 *ld_obd;
+	/**
+	 * A list of references to this object, for debugging.
+	 */
+	struct lu_ref		      ld_reference;
+	/**
+	 * Link the device to the site.
+	 **/
+	struct list_head			 ld_linkage;
+};
+
+struct lu_device_type_operations;
+
+/**
+ * Tag bits for device type. They are used to distinguish certain groups of
+ * device types.
+ */
+enum lu_device_tag {
+	/** this is meta-data device */
+	LU_DEVICE_MD = (1 << 0),
+	/** this is data device */
+	LU_DEVICE_DT = (1 << 1),
+	/** data device in the client stack */
+	LU_DEVICE_CL = (1 << 2)
+};
+
+/**
+ * Type of device.
+ */
+struct lu_device_type {
+	/**
+	 * Tag bits. Taken from enum lu_device_tag. Never modified once set.
+	 */
+	__u32				   ldt_tags;
+	/**
+	 * Name of this class. Unique system-wide. Never modified once set.
+	 */
+	char				   *ldt_name;
+	/**
+	 * Operations for this type.
+	 */
+	const struct lu_device_type_operations *ldt_ops;
+	/**
+	 * \todo XXX: temporary pointer to associated obd_type.
+	 */
+	struct obd_type			*ldt_obd_type;
+	/**
+	 * \todo XXX: temporary: context tags used by obd_*() calls.
+	 */
+	__u32				   ldt_ctx_tags;
+	/**
+	 * Number of existing device type instances.
+	 */
+	unsigned				ldt_device_nr;
+	/**
+	 * Linkage into a global list of all device types.
+	 *
+	 * \see lu_device_types.
+	 */
+	struct list_head			      ldt_linkage;
+};
+
+/**
+ * Operations on a device type.
+ */
+struct lu_device_type_operations {
+	/**
+	 * Allocate new device.
+	 */
+	struct lu_device *(*ldto_device_alloc)(const struct lu_env *env,
+					       struct lu_device_type *t,
+					       struct lustre_cfg *lcfg);
+	/**
+	 * Free device. Dual to
+	 * lu_device_type_operations::ldto_device_alloc(). Returns pointer to
+	 * the next device in the stack.
+	 */
+	struct lu_device *(*ldto_device_free)(const struct lu_env *,
+					      struct lu_device *);
+
+	/**
+	 * Initialize the devices after allocation
+	 */
+	int  (*ldto_device_init)(const struct lu_env *env,
+				 struct lu_device *, const char *,
+				 struct lu_device *);
+	/**
+	 * Finalize device. Dual to
+	 * lu_device_type_operations::ldto_device_init(). Returns pointer to
+	 * the next device in the stack.
+	 */
+	struct lu_device *(*ldto_device_fini)(const struct lu_env *env,
+					      struct lu_device *);
+	/**
+	 * Initialize device type. This is called on module load.
+	 */
+	int  (*ldto_init)(struct lu_device_type *t);
+	/**
+	 * Finalize device type. Dual to
+	 * lu_device_type_operations::ldto_init(). Called on module unload.
+	 */
+	void (*ldto_fini)(struct lu_device_type *t);
+	/**
+	 * Called when the first device is created.
+	 */
+	void (*ldto_start)(struct lu_device_type *t);
+	/**
+	 * Called when number of devices drops to 0.
+	 */
+	void (*ldto_stop)(struct lu_device_type *t);
+};
+
+static inline int lu_device_is_md(const struct lu_device *d)
+{
+	return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_MD);
+}
+
+/**
+ * Flags for the object layers.
+ */
+enum lu_object_flags {
+	/**
+	 * this flags is set if lu_object_operations::loo_object_init() has
+	 * been called for this layer. Used by lu_object_alloc().
+	 */
+	LU_OBJECT_ALLOCATED = (1 << 0)
+};
+
+/**
+ * Common object attributes.
+ */
+struct lu_attr {
+	/** size in bytes */
+	__u64	  la_size;
+	/** modification time in seconds since Epoch */
+	obd_time       la_mtime;
+	/** access time in seconds since Epoch */
+	obd_time       la_atime;
+	/** change time in seconds since Epoch */
+	obd_time       la_ctime;
+	/** 512-byte blocks allocated to object */
+	__u64	  la_blocks;
+	/** permission bits and file type */
+	__u32	  la_mode;
+	/** owner id */
+	__u32	  la_uid;
+	/** group id */
+	__u32	  la_gid;
+	/** object flags */
+	__u32	  la_flags;
+	/** number of persistent references to this object */
+	__u32	  la_nlink;
+	/** blk bits of the object*/
+	__u32	  la_blkbits;
+	/** blk size of the object*/
+	__u32	  la_blksize;
+	/** real device */
+	__u32	  la_rdev;
+	/**
+	 * valid bits
+	 *
+	 * \see enum la_valid
+	 */
+	__u64	  la_valid;
+};
+
+/** Bit-mask of valid attributes */
+enum la_valid {
+	LA_ATIME = 1 << 0,
+	LA_MTIME = 1 << 1,
+	LA_CTIME = 1 << 2,
+	LA_SIZE  = 1 << 3,
+	LA_MODE  = 1 << 4,
+	LA_UID   = 1 << 5,
+	LA_GID   = 1 << 6,
+	LA_BLOCKS = 1 << 7,
+	LA_TYPE   = 1 << 8,
+	LA_FLAGS  = 1 << 9,
+	LA_NLINK  = 1 << 10,
+	LA_RDEV   = 1 << 11,
+	LA_BLKSIZE = 1 << 12,
+	LA_KILL_SUID = 1 << 13,
+	LA_KILL_SGID = 1 << 14,
+};
+
+/**
+ * Layer in the layered object.
+ */
+struct lu_object {
+	/**
+	 * Header for this object.
+	 */
+	struct lu_object_header	   *lo_header;
+	/**
+	 * Device for this layer.
+	 */
+	struct lu_device		  *lo_dev;
+	/**
+	 * Operations for this object.
+	 */
+	const struct lu_object_operations *lo_ops;
+	/**
+	 * Linkage into list of all layers.
+	 */
+	struct list_head			 lo_linkage;
+	/**
+	 * Depth. Top level layer depth is 0.
+	 */
+	int				lo_depth;
+	/**
+	 * Flags from enum lu_object_flags.
+	 */
+	__u32					lo_flags;
+	/**
+	 * Link to the device, for debugging.
+	 */
+	struct lu_ref_link		*lo_dev_ref;
+};
+
+enum lu_object_header_flags {
+	/**
+	 * Don't keep this object in cache. Object will be destroyed as soon
+	 * as last reference to it is released. This flag cannot be cleared
+	 * once set.
+	 */
+	LU_OBJECT_HEARD_BANSHEE = 0,
+	/**
+	 * Mark this object has already been taken out of cache.
+	 */
+	LU_OBJECT_UNHASHED = 1
+};
+
+enum lu_object_header_attr {
+	LOHA_EXISTS   = 1 << 0,
+	LOHA_REMOTE   = 1 << 1,
+	/**
+	 * UNIX file type is stored in S_IFMT bits.
+	 */
+	LOHA_FT_START = 001 << 12, /**< S_IFIFO */
+	LOHA_FT_END   = 017 << 12, /**< S_IFMT */
+};
+
+/**
+ * "Compound" object, consisting of multiple layers.
+ *
+ * Compound object with given fid is unique with given lu_site.
+ *
+ * Note, that object does *not* necessary correspond to the real object in the
+ * persistent storage: object is an anchor for locking and method calling, so
+ * it is created for things like not-yet-existing child created by mkdir or
+ * create calls. lu_object_operations::loo_exists() can be used to check
+ * whether object is backed by persistent storage entity.
+ */
+struct lu_object_header {
+	/**
+	 * Object flags from enum lu_object_header_flags. Set and checked
+	 * atomically.
+	 */
+	unsigned long	  loh_flags;
+	/**
+	 * Object reference count. Protected by lu_site::ls_guard.
+	 */
+	atomic_t	   loh_ref;
+	/**
+	 * Fid, uniquely identifying this object.
+	 */
+	struct lu_fid	  loh_fid;
+	/**
+	 * Common object attributes, cached for efficiency. From enum
+	 * lu_object_header_attr.
+	 */
+	__u32		  loh_attr;
+	/**
+	 * Linkage into per-site hash table. Protected by lu_site::ls_guard.
+	 */
+	struct hlist_node       loh_hash;
+	/**
+	 * Linkage into per-site LRU list. Protected by lu_site::ls_guard.
+	 */
+	struct list_head	     loh_lru;
+	/**
+	 * Linkage into list of layers. Never modified once set (except lately
+	 * during object destruction). No locking is necessary.
+	 */
+	struct list_head	     loh_layers;
+	/**
+	 * A list of references to this object, for debugging.
+	 */
+	struct lu_ref	  loh_reference;
+};
+
+struct fld;
+
+struct lu_site_bkt_data {
+	/**
+	 * number of busy object on this bucket
+	 */
+	long		      lsb_busy;
+	/**
+	 * LRU list, updated on each access to object. Protected by
+	 * bucket lock of lu_site::ls_obj_hash.
+	 *
+	 * "Cold" end of LRU is lu_site::ls_lru.next. Accessed object are
+	 * moved to the lu_site::ls_lru.prev (this is due to the non-existence
+	 * of list_for_each_entry_safe_reverse()).
+	 */
+	struct list_head		lsb_lru;
+	/**
+	 * Wait-queue signaled when an object in this site is ultimately
+	 * destroyed (lu_object_free()). It is used by lu_object_find() to
+	 * wait before re-trying when object in the process of destruction is
+	 * found in the hash table.
+	 *
+	 * \see htable_lookup().
+	 */
+	wait_queue_head_t	       lsb_marche_funebre;
+};
+
+enum {
+	LU_SS_CREATED	 = 0,
+	LU_SS_CACHE_HIT,
+	LU_SS_CACHE_MISS,
+	LU_SS_CACHE_RACE,
+	LU_SS_CACHE_DEATH_RACE,
+	LU_SS_LRU_PURGED,
+	LU_SS_LAST_STAT
+};
+
+/**
+ * lu_site is a "compartment" within which objects are unique, and LRU
+ * discipline is maintained.
+ *
+ * lu_site exists so that multiple layered stacks can co-exist in the same
+ * address space.
+ *
+ * lu_site has the same relation to lu_device as lu_object_header to
+ * lu_object.
+ */
+struct lu_site {
+	/**
+	 * objects hash table
+	 */
+	cfs_hash_t	       *ls_obj_hash;
+	/**
+	 * index of bucket on hash table while purging
+	 */
+	int		       ls_purge_start;
+	/**
+	 * Top-level device for this stack.
+	 */
+	struct lu_device	 *ls_top_dev;
+	/**
+	 * Bottom-level device for this stack
+	 */
+	struct lu_device	*ls_bottom_dev;
+	/**
+	 * Linkage into global list of sites.
+	 */
+	struct list_head		ls_linkage;
+	/**
+	 * List for lu device for this site, protected
+	 * by ls_ld_lock.
+	 **/
+	struct list_head		ls_ld_linkage;
+	spinlock_t		ls_ld_lock;
+
+	/**
+	 * lu_site stats
+	 */
+	struct lprocfs_stats	*ls_stats;
+	/**
+	 * XXX: a hack! fld has to find md_site via site, remove when possible
+	 */
+	struct seq_server_site	*ld_seq_site;
+};
+
+static inline struct lu_site_bkt_data *
+lu_site_bkt_from_fid(struct lu_site *site, struct lu_fid *fid)
+{
+	cfs_hash_bd_t bd;
+
+	cfs_hash_bd_get(site->ls_obj_hash, fid, &bd);
+	return cfs_hash_bd_extra_get(site->ls_obj_hash, &bd);
+}
+
+/** \name ctors
+ * Constructors/destructors.
+ * @{
+ */
+
+int  lu_site_init	 (struct lu_site *s, struct lu_device *d);
+void lu_site_fini	 (struct lu_site *s);
+int  lu_site_init_finish  (struct lu_site *s);
+void lu_stack_fini	(const struct lu_env *env, struct lu_device *top);
+void lu_device_get	(struct lu_device *d);
+void lu_device_put	(struct lu_device *d);
+int  lu_device_init       (struct lu_device *d, struct lu_device_type *t);
+void lu_device_fini       (struct lu_device *d);
+int  lu_object_header_init(struct lu_object_header *h);
+void lu_object_header_fini(struct lu_object_header *h);
+int  lu_object_init       (struct lu_object *o,
+			   struct lu_object_header *h, struct lu_device *d);
+void lu_object_fini       (struct lu_object *o);
+void lu_object_add_top    (struct lu_object_header *h, struct lu_object *o);
+void lu_object_add	(struct lu_object *before, struct lu_object *o);
+
+void lu_dev_add_linkage(struct lu_site *s, struct lu_device *d);
+void lu_dev_del_linkage(struct lu_site *s, struct lu_device *d);
+
+/**
+ * Helpers to initialize and finalize device types.
+ */
+
+int  lu_device_type_init(struct lu_device_type *ldt);
+void lu_device_type_fini(struct lu_device_type *ldt);
+void lu_types_stop(void);
+
+/** @} ctors */
+
+/** \name caching
+ * Caching and reference counting.
+ * @{
+ */
+
+/**
+ * Acquire additional reference to the given object. This function is used to
+ * attain additional reference. To acquire initial reference use
+ * lu_object_find().
+ */
+static inline void lu_object_get(struct lu_object *o)
+{
+	LASSERT(atomic_read(&o->lo_header->loh_ref) > 0);
+	atomic_inc(&o->lo_header->loh_ref);
+}
+
+/**
+ * Return true of object will not be cached after last reference to it is
+ * released.
+ */
+static inline int lu_object_is_dying(const struct lu_object_header *h)
+{
+	return test_bit(LU_OBJECT_HEARD_BANSHEE, &h->loh_flags);
+}
+
+void lu_object_put(const struct lu_env *env, struct lu_object *o);
+void lu_object_put_nocache(const struct lu_env *env, struct lu_object *o);
+void lu_object_unhash(const struct lu_env *env, struct lu_object *o);
+
+int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr);
+
+void lu_site_print(const struct lu_env *env, struct lu_site *s, void *cookie,
+		   lu_printer_t printer);
+struct lu_object *lu_object_find(const struct lu_env *env,
+				 struct lu_device *dev, const struct lu_fid *f,
+				 const struct lu_object_conf *conf);
+struct lu_object *lu_object_find_at(const struct lu_env *env,
+				    struct lu_device *dev,
+				    const struct lu_fid *f,
+				    const struct lu_object_conf *conf);
+struct lu_object *lu_object_find_slice(const struct lu_env *env,
+				       struct lu_device *dev,
+				       const struct lu_fid *f,
+				       const struct lu_object_conf *conf);
+/** @} caching */
+
+/** \name helpers
+ * Helpers.
+ * @{
+ */
+
+/**
+ * First (topmost) sub-object of given compound object
+ */
+static inline struct lu_object *lu_object_top(struct lu_object_header *h)
+{
+	LASSERT(!list_empty(&h->loh_layers));
+	return container_of0(h->loh_layers.next, struct lu_object, lo_linkage);
+}
+
+/**
+ * Next sub-object in the layering
+ */
+static inline struct lu_object *lu_object_next(const struct lu_object *o)
+{
+	return container_of0(o->lo_linkage.next, struct lu_object, lo_linkage);
+}
+
+/**
+ * Pointer to the fid of this object.
+ */
+static inline const struct lu_fid *lu_object_fid(const struct lu_object *o)
+{
+	return &o->lo_header->loh_fid;
+}
+
+/**
+ * return device operations vector for this object
+ */
+static const inline struct lu_device_operations *
+lu_object_ops(const struct lu_object *o)
+{
+	return o->lo_dev->ld_ops;
+}
+
+/**
+ * Given a compound object, find its slice, corresponding to the device type
+ * \a dtype.
+ */
+struct lu_object *lu_object_locate(struct lu_object_header *h,
+				   const struct lu_device_type *dtype);
+
+/**
+ * Printer function emitting messages through libcfs_debug_msg().
+ */
+int lu_cdebug_printer(const struct lu_env *env,
+		      void *cookie, const char *format, ...);
+
+/**
+ * Print object description followed by a user-supplied message.
+ */
+#define LU_OBJECT_DEBUG(mask, env, object, format, ...)		   \
+do {								      \
+	LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL);		  \
+									  \
+	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {		     \
+		lu_object_print(env, &msgdata, lu_cdebug_printer, object);\
+		CDEBUG(mask, format , ## __VA_ARGS__);		    \
+	}								 \
+} while (0)
+
+/**
+ * Print short object description followed by a user-supplied message.
+ */
+#define LU_OBJECT_HEADER(mask, env, object, format, ...)		\
+do {								    \
+	LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL);		\
+									\
+	if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) {		   \
+		lu_object_header_print(env, &msgdata, lu_cdebug_printer,\
+				       (object)->lo_header);	    \
+		lu_cdebug_printer(env, &msgdata, "\n");		 \
+		CDEBUG(mask, format , ## __VA_ARGS__);		  \
+	}							       \
+} while (0)
+
+void lu_object_print       (const struct lu_env *env, void *cookie,
+			    lu_printer_t printer, const struct lu_object *o);
+void lu_object_header_print(const struct lu_env *env, void *cookie,
+			    lu_printer_t printer,
+			    const struct lu_object_header *hdr);
+
+/**
+ * Check object consistency.
+ */
+int lu_object_invariant(const struct lu_object *o);
+
+
+/**
+ * Check whether object exists, no matter on local or remote storage.
+ * Note: LOHA_EXISTS will be set once some one created the object,
+ * and it does not needs to be committed to storage.
+ */
+#define lu_object_exists(o) ((o)->lo_header->loh_attr & LOHA_EXISTS)
+
+/**
+ * Check whether object on the remote storage.
+ */
+#define lu_object_remote(o) unlikely((o)->lo_header->loh_attr & LOHA_REMOTE)
+
+static inline int lu_object_assert_exists(const struct lu_object *o)
+{
+	return lu_object_exists(o);
+}
+
+static inline int lu_object_assert_not_exists(const struct lu_object *o)
+{
+	return !lu_object_exists(o);
+}
+
+/**
+ * Attr of this object.
+ */
+static inline __u32 lu_object_attr(const struct lu_object *o)
+{
+	LASSERT(lu_object_exists(o) != 0);
+	return o->lo_header->loh_attr;
+}
+
+static inline struct lu_ref_link *lu_object_ref_add(struct lu_object *o,
+						    const char *scope,
+						    const void *source)
+{
+	return lu_ref_add(&o->lo_header->loh_reference, scope, source);
+}
+
+static inline void lu_object_ref_del(struct lu_object *o,
+				     const char *scope, const void *source)
+{
+	lu_ref_del(&o->lo_header->loh_reference, scope, source);
+}
+
+static inline void lu_object_ref_del_at(struct lu_object *o,
+					struct lu_ref_link *link,
+					const char *scope, const void *source)
+{
+	lu_ref_del_at(&o->lo_header->loh_reference, link, scope, source);
+}
+
+/** input params, should be filled out by mdt */
+struct lu_rdpg {
+	/** hash */
+	__u64		   rp_hash;
+	/** count in bytes */
+	unsigned int	    rp_count;
+	/** number of pages */
+	unsigned int	    rp_npages;
+	/** requested attr */
+	__u32		   rp_attrs;
+	/** pointers to pages */
+	struct page	   **rp_pages;
+};
+
+enum lu_xattr_flags {
+	LU_XATTR_REPLACE = (1 << 0),
+	LU_XATTR_CREATE  = (1 << 1)
+};
+
+/** @} helpers */
+
+/** \name lu_context
+ * @{ */
+
+/** For lu_context health-checks */
+enum lu_context_state {
+	LCS_INITIALIZED = 1,
+	LCS_ENTERED,
+	LCS_LEFT,
+	LCS_FINALIZED
+};
+
+/**
+ * lu_context. Execution context for lu_object methods. Currently associated
+ * with thread.
+ *
+ * All lu_object methods, except device and device type methods (called during
+ * system initialization and shutdown) are executed "within" some
+ * lu_context. This means, that pointer to some "current" lu_context is passed
+ * as an argument to all methods.
+ *
+ * All service ptlrpc threads create lu_context as part of their
+ * initialization. It is possible to create "stand-alone" context for other
+ * execution environments (like system calls).
+ *
+ * lu_object methods mainly use lu_context through lu_context_key interface
+ * that allows each layer to associate arbitrary pieces of data with each
+ * context (see pthread_key_create(3) for similar interface).
+ *
+ * On a client, lu_context is bound to a thread, see cl_env_get().
+ *
+ * \see lu_context_key
+ */
+struct lu_context {
+	/**
+	 * lu_context is used on the client side too. Yet we don't want to
+	 * allocate values of server-side keys for the client contexts and
+	 * vice versa.
+	 *
+	 * To achieve this, set of tags in introduced. Contexts and keys are
+	 * marked with tags. Key value are created only for context whose set
+	 * of tags has non-empty intersection with one for key. Tags are taken
+	 * from enum lu_context_tag.
+	 */
+	__u32		  lc_tags;
+	enum lu_context_state  lc_state;
+	/**
+	 * Pointer to the home service thread. NULL for other execution
+	 * contexts.
+	 */
+	struct ptlrpc_thread  *lc_thread;
+	/**
+	 * Pointer to an array with key values. Internal implementation
+	 * detail.
+	 */
+	void		 **lc_value;
+	/**
+	 * Linkage into a list of all remembered contexts. Only
+	 * `non-transient' contexts, i.e., ones created for service threads
+	 * are placed here.
+	 */
+	struct list_head	     lc_remember;
+	/**
+	 * Version counter used to skip calls to lu_context_refill() when no
+	 * keys were registered.
+	 */
+	unsigned	       lc_version;
+	/**
+	 * Debugging cookie.
+	 */
+	unsigned	       lc_cookie;
+};
+
+/**
+ * lu_context_key interface. Similar to pthread_key.
+ */
+
+enum lu_context_tag {
+	/**
+	 * Thread on md server
+	 */
+	LCT_MD_THREAD = 1 << 0,
+	/**
+	 * Thread on dt server
+	 */
+	LCT_DT_THREAD = 1 << 1,
+	/**
+	 * Context for transaction handle
+	 */
+	LCT_TX_HANDLE = 1 << 2,
+	/**
+	 * Thread on client
+	 */
+	LCT_CL_THREAD = 1 << 3,
+	/**
+	 * A per-request session on a server, and a per-system-call session on
+	 * a client.
+	 */
+	LCT_SESSION   = 1 << 4,
+	/**
+	 * A per-request data on OSP device
+	 */
+	LCT_OSP_THREAD = 1 << 5,
+	/**
+	 * MGS device thread
+	 */
+	LCT_MG_THREAD = 1 << 6,
+	/**
+	 * Context for local operations
+	 */
+	LCT_LOCAL = 1 << 7,
+	/**
+	 * Set when at least one of keys, having values in this context has
+	 * non-NULL lu_context_key::lct_exit() method. This is used to
+	 * optimize lu_context_exit() call.
+	 */
+	LCT_HAS_EXIT  = 1 << 28,
+	/**
+	 * Don't add references for modules creating key values in that context.
+	 * This is only for contexts used internally by lu_object framework.
+	 */
+	LCT_NOREF     = 1 << 29,
+	/**
+	 * Key is being prepared for retiring, don't create new values for it.
+	 */
+	LCT_QUIESCENT = 1 << 30,
+	/**
+	 * Context should be remembered.
+	 */
+	LCT_REMEMBER  = 1 << 31,
+	/**
+	 * Contexts usable in cache shrinker thread.
+	 */
+	LCT_SHRINKER  = LCT_MD_THREAD|LCT_DT_THREAD|LCT_CL_THREAD|LCT_NOREF
+};
+
+/**
+ * Key. Represents per-context value slot.
+ *
+ * Keys are usually registered when module owning the key is initialized, and
+ * de-registered when module is unloaded. Once key is registered, all new
+ * contexts with matching tags, will get key value. "Old" contexts, already
+ * initialized at the time of key registration, can be forced to get key value
+ * by calling lu_context_refill().
+ *
+ * Every key value is counted in lu_context_key::lct_used and acquires a
+ * reference on an owning module. This means, that all key values have to be
+ * destroyed before module can be unloaded. This is usually achieved by
+ * stopping threads started by the module, that created contexts in their
+ * entry functions. Situation is complicated by the threads shared by multiple
+ * modules, like ptlrpcd daemon on a client. To work around this problem,
+ * contexts, created in such threads, are `remembered' (see
+ * LCT_REMEMBER)---i.e., added into a global list. When module is preparing
+ * for unloading it does the following:
+ *
+ *     - marks its keys as `quiescent' (lu_context_tag::LCT_QUIESCENT)
+ *       preventing new key values from being allocated in the new contexts,
+ *       and
+ *
+ *     - scans a list of remembered contexts, destroying values of module
+ *       keys, thus releasing references to the module.
+ *
+ * This is done by lu_context_key_quiesce(). If module is re-activated
+ * before key has been de-registered, lu_context_key_revive() call clears
+ * `quiescent' marker.
+ *
+ * lu_context code doesn't provide any internal synchronization for these
+ * activities---it's assumed that startup (including threads start-up) and
+ * shutdown are serialized by some external means.
+ *
+ * \see lu_context
+ */
+struct lu_context_key {
+	/**
+	 * Set of tags for which values of this key are to be instantiated.
+	 */
+	__u32 lct_tags;
+	/**
+	 * Value constructor. This is called when new value is created for a
+	 * context. Returns pointer to new value of error pointer.
+	 */
+	void  *(*lct_init)(const struct lu_context *ctx,
+			   struct lu_context_key *key);
+	/**
+	 * Value destructor. Called when context with previously allocated
+	 * value of this slot is destroyed. \a data is a value that was returned
+	 * by a matching call to lu_context_key::lct_init().
+	 */
+	void   (*lct_fini)(const struct lu_context *ctx,
+			   struct lu_context_key *key, void *data);
+	/**
+	 * Optional method called on lu_context_exit() for all allocated
+	 * keys. Can be used by debugging code checking that locks are
+	 * released, etc.
+	 */
+	void   (*lct_exit)(const struct lu_context *ctx,
+			   struct lu_context_key *key, void *data);
+	/**
+	 * Internal implementation detail: index within lu_context::lc_value[]
+	 * reserved for this key.
+	 */
+	int      lct_index;
+	/**
+	 * Internal implementation detail: number of values created for this
+	 * key.
+	 */
+	atomic_t lct_used;
+	/**
+	 * Internal implementation detail: module for this key.
+	 */
+	module_t *lct_owner;
+	/**
+	 * References to this key. For debugging.
+	 */
+	struct lu_ref  lct_reference;
+};
+
+#define LU_KEY_INIT(mod, type)				    \
+	static void* mod##_key_init(const struct lu_context *ctx, \
+				    struct lu_context_key *key)   \
+	{							 \
+		type *value;				      \
+								  \
+		CLASSERT(PAGE_CACHE_SIZE >= sizeof (*value));       \
+								  \
+		OBD_ALLOC_PTR(value);			     \
+		if (value == NULL)				\
+			value = ERR_PTR(-ENOMEM);		 \
+								  \
+		return value;				     \
+	}							 \
+	struct __##mod##__dummy_init {;} /* semicolon catcher */
+
+#define LU_KEY_FINI(mod, type)					      \
+	static void mod##_key_fini(const struct lu_context *ctx,	    \
+				    struct lu_context_key *key, void* data) \
+	{								   \
+		type *info = data;					  \
+									    \
+		OBD_FREE_PTR(info);					 \
+	}								   \
+	struct __##mod##__dummy_fini {;} /* semicolon catcher */
+
+#define LU_KEY_INIT_FINI(mod, type)   \
+	LU_KEY_INIT(mod,type);	\
+	LU_KEY_FINI(mod,type)
+
+#define LU_CONTEXT_KEY_DEFINE(mod, tags)		\
+	struct lu_context_key mod##_thread_key = {      \
+		.lct_tags = tags,		       \
+		.lct_init = mod##_key_init,	     \
+		.lct_fini = mod##_key_fini	      \
+	}
+
+#define LU_CONTEXT_KEY_INIT(key)			\
+do {						    \
+	(key)->lct_owner = THIS_MODULE;		 \
+} while (0)
+
+int   lu_context_key_register(struct lu_context_key *key);
+void  lu_context_key_degister(struct lu_context_key *key);
+void *lu_context_key_get     (const struct lu_context *ctx,
+			       const struct lu_context_key *key);
+void  lu_context_key_quiesce (struct lu_context_key *key);
+void  lu_context_key_revive  (struct lu_context_key *key);
+
+
+/*
+ * LU_KEY_INIT_GENERIC() has to be a macro to correctly determine an
+ * owning module.
+ */
+
+#define LU_KEY_INIT_GENERIC(mod)					\
+	static void mod##_key_init_generic(struct lu_context_key *k, ...) \
+	{							       \
+		struct lu_context_key *key = k;			 \
+		va_list args;					   \
+									\
+		va_start(args, k);				      \
+		do {						    \
+			LU_CONTEXT_KEY_INIT(key);		       \
+			key = va_arg(args, struct lu_context_key *);    \
+		} while (key != NULL);				  \
+		va_end(args);					   \
+	}
+
+#define LU_TYPE_INIT(mod, ...)					  \
+	LU_KEY_INIT_GENERIC(mod)					\
+	static int mod##_type_init(struct lu_device_type *t)	    \
+	{							       \
+		mod##_key_init_generic(__VA_ARGS__, NULL);	      \
+		return lu_context_key_register_many(__VA_ARGS__, NULL); \
+	}							       \
+	struct __##mod##_dummy_type_init {;}
+
+#define LU_TYPE_FINI(mod, ...)					  \
+	static void mod##_type_fini(struct lu_device_type *t)	   \
+	{							       \
+		lu_context_key_degister_many(__VA_ARGS__, NULL);	\
+	}							       \
+	struct __##mod##_dummy_type_fini {;}
+
+#define LU_TYPE_START(mod, ...)				 \
+	static void mod##_type_start(struct lu_device_type *t)  \
+	{						       \
+		lu_context_key_revive_many(__VA_ARGS__, NULL);  \
+	}						       \
+	struct __##mod##_dummy_type_start {;}
+
+#define LU_TYPE_STOP(mod, ...)				  \
+	static void mod##_type_stop(struct lu_device_type *t)   \
+	{						       \
+		lu_context_key_quiesce_many(__VA_ARGS__, NULL); \
+	}						       \
+	struct __##mod##_dummy_type_stop {;}
+
+
+
+#define LU_TYPE_INIT_FINI(mod, ...)	     \
+	LU_TYPE_INIT(mod, __VA_ARGS__);	 \
+	LU_TYPE_FINI(mod, __VA_ARGS__);	 \
+	LU_TYPE_START(mod, __VA_ARGS__);	\
+	LU_TYPE_STOP(mod, __VA_ARGS__)
+
+int   lu_context_init  (struct lu_context *ctx, __u32 tags);
+void  lu_context_fini  (struct lu_context *ctx);
+void  lu_context_enter (struct lu_context *ctx);
+void  lu_context_exit  (struct lu_context *ctx);
+int   lu_context_refill(struct lu_context *ctx);
+
+/*
+ * Helper functions to operate on multiple keys. These are used by the default
+ * device type operations, defined by LU_TYPE_INIT_FINI().
+ */
+
+int  lu_context_key_register_many(struct lu_context_key *k, ...);
+void lu_context_key_degister_many(struct lu_context_key *k, ...);
+void lu_context_key_revive_many  (struct lu_context_key *k, ...);
+void lu_context_key_quiesce_many (struct lu_context_key *k, ...);
+
+/*
+ * update/clear ctx/ses tags.
+ */
+void lu_context_tags_update(__u32 tags);
+void lu_context_tags_clear(__u32 tags);
+void lu_session_tags_update(__u32 tags);
+void lu_session_tags_clear(__u32 tags);
+
+/**
+ * Environment.
+ */
+struct lu_env {
+	/**
+	 * "Local" context, used to store data instead of stack.
+	 */
+	struct lu_context  le_ctx;
+	/**
+	 * "Session" context for per-request data.
+	 */
+	struct lu_context *le_ses;
+};
+
+int  lu_env_init  (struct lu_env *env, __u32 tags);
+void lu_env_fini  (struct lu_env *env);
+int  lu_env_refill(struct lu_env *env);
+int  lu_env_refill_by_tags(struct lu_env *env, __u32 ctags, __u32 stags);
+
+/** @} lu_context */
+
+/**
+ * Output site statistical counters into a buffer. Suitable for
+ * ll_rd_*()-style functions.
+ */
+int lu_site_stats_print(const struct lu_site *s, struct seq_file *m);
+
+/**
+ * Common name structure to be passed around for various name related methods.
+ */
+struct lu_name {
+	const char    *ln_name;
+	int	    ln_namelen;
+};
+
+/**
+ * Common buffer structure to be passed around for various xattr_{s,g}et()
+ * methods.
+ */
+struct lu_buf {
+	void   *lb_buf;
+	ssize_t lb_len;
+};
+
+#define DLUBUF "(%p %zu)"
+#define PLUBUF(buf) (buf)->lb_buf, (buf)->lb_len
+/**
+ * One-time initializers, called at obdclass module initialization, not
+ * exported.
+ */
+
+/**
+ * Initialization of global lu_* data.
+ */
+int lu_global_init(void);
+
+/**
+ * Dual to lu_global_init().
+ */
+void lu_global_fini(void);
+
+struct lu_kmem_descr {
+	struct kmem_cache **ckd_cache;
+	const char       *ckd_name;
+	const size_t      ckd_size;
+};
+
+int  lu_kmem_init(struct lu_kmem_descr *caches);
+void lu_kmem_fini(struct lu_kmem_descr *caches);
+
+void lu_object_assign_fid(const struct lu_env *env, struct lu_object *o,
+			  const struct lu_fid *fid);
+struct lu_object *lu_object_anon(const struct lu_env *env,
+				 struct lu_device *dev,
+				 const struct lu_object_conf *conf);
+
+/** null buffer */
+extern struct lu_buf LU_BUF_NULL;
+
+void lu_buf_free(struct lu_buf *buf);
+void lu_buf_alloc(struct lu_buf *buf, int size);
+void lu_buf_realloc(struct lu_buf *buf, int size);
+
+int lu_buf_check_and_grow(struct lu_buf *buf, int len);
+struct lu_buf *lu_buf_check_and_alloc(struct lu_buf *buf, int len);
+
+/** @} lu */
+#endif /* __LUSTRE_LU_OBJECT_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lu_ref.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lu_ref.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lu_ref.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lu_ref.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ *
+ *   Author: Nikita Danilov <nikita.danilov@sun.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __LUSTRE_LU_REF_H
+#define __LUSTRE_LU_REF_H
+
+#include <linux/list.h>
+
+/** \defgroup lu_ref lu_ref
+ *
+ * An interface to track references between objects. Mostly for debugging.
+ *
+ * Suppose there is a reference counted data-structure struct foo. To track
+ * who acquired references to instance of struct foo, add lu_ref field to it:
+ *
+ * \code
+ *	 struct foo {
+ *		 atomic_t      foo_refcount;
+ *		 struct lu_ref foo_reference;
+ *		 ...
+ *	 };
+ * \endcode
+ *
+ * foo::foo_reference has to be initialized by calling
+ * lu_ref_init(). Typically there will be functions or macros to increment and
+ * decrement foo::foo_refcount, let's say they are foo_get(struct foo *foo)
+ * and foo_put(struct foo *foo), respectively.
+ *
+ * Whenever foo_get() is called to acquire a reference on a foo, lu_ref_add()
+ * has to be called to insert into foo::foo_reference a record, describing
+ * acquired reference. Dually, lu_ref_del() removes matching record. Typical
+ * usages are:
+ *
+ * \code
+ *	struct bar *bar;
+ *
+ *	// bar owns a reference to foo.
+ *	bar->bar_foo = foo_get(foo);
+ *	lu_ref_add(&foo->foo_reference, "bar", bar);
+ *
+ *	...
+ *
+ *	// reference from bar to foo is released.
+ *	lu_ref_del(&foo->foo_reference, "bar", bar);
+ *	foo_put(bar->bar_foo);
+ *
+ *
+ *	// current thread acquired a temporary reference to foo.
+ *	foo_get(foo);
+ *	lu_ref_add(&foo->reference, __FUNCTION__, current);
+ *
+ *	...
+ *
+ *	// temporary reference is released.
+ *	lu_ref_del(&foo->reference, __FUNCTION__, current);
+ *	foo_put(foo);
+ * \endcode
+ *
+ * \e Et \e cetera. Often it makes sense to include lu_ref_add() and
+ * lu_ref_del() calls into foo_get() and foo_put(). When an instance of struct
+ * foo is destroyed, lu_ref_fini() has to be called that checks that no
+ * pending references remain. lu_ref_print() can be used to dump a list of
+ * pending references, while hunting down a leak.
+ *
+ * For objects to which a large number of references can be acquired,
+ * lu_ref_del() can become cpu consuming, as it has to scan the list of
+ * references. To work around this, remember result of lu_ref_add() (usually
+ * in the same place where pointer to struct foo is stored), and use
+ * lu_ref_del_at():
+ *
+ * \code
+ *	// There is a large number of bar's for a single foo.
+ *	bar->bar_foo     = foo_get(foo);
+ *	bar->bar_foo_ref = lu_ref_add(&foo->foo_reference, "bar", bar);
+ *
+ *	...
+ *
+ *	// reference from bar to foo is released.
+ *	lu_ref_del_at(&foo->foo_reference, bar->bar_foo_ref, "bar", bar);
+ *	foo_put(bar->bar_foo);
+ * \endcode
+ *
+ * lu_ref interface degrades gracefully in case of memory shortages.
+ *
+ * @{
+ */
+
+
+struct lu_ref  {};
+
+static inline void lu_ref_init(struct lu_ref *ref)
+{
+}
+
+static inline void lu_ref_fini(struct lu_ref *ref)
+{
+}
+
+static inline struct lu_ref_link *lu_ref_add(struct lu_ref *ref,
+					     const char *scope,
+					     const void *source)
+{
+	return NULL;
+}
+
+static inline struct lu_ref_link *lu_ref_add_atomic(struct lu_ref *ref,
+						    const char *scope,
+						    const void *source)
+{
+	return NULL;
+}
+
+static inline void lu_ref_del(struct lu_ref *ref, const char *scope,
+			      const void *source)
+{
+}
+
+static inline void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
+				 const char *scope, const void *source0,
+				 const void *source1)
+{
+}
+
+static inline void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
+				 const char *scope, const void *source)
+{
+}
+
+static inline int lu_ref_global_init(void)
+{
+	return 0;
+}
+
+static inline void lu_ref_global_fini(void)
+{
+}
+
+static inline void lu_ref_print(const struct lu_ref *ref)
+{
+}
+
+static inline void lu_ref_print_all(void)
+{
+}
+
+/** @} lu */
+
+#endif /* __LUSTRE_LU_REF_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/libiam.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/libiam.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/libiam.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/libiam.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,145 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre/libiam.h
+ *
+ * iam user level library
+ *
+ * Author: Wang Di <wangdi@clusterfs.com>
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ * Author: Fan Yong <fanyong@clusterfs.com>
+ */
+
+/*
+ *  lustre/libiam.h
+ */
+
+#ifndef __IAM_ULIB_H__
+#define __IAM_ULIB_H__
+
+/** \defgroup libiam libiam
+ *
+ * @{
+ */
+
+
+#define DX_FMT_NAME_LEN 16
+
+enum iam_fmt_t {
+	FMT_LFIX,
+	FMT_LVAR
+};
+
+struct iam_uapi_info {
+	__u16 iui_keysize;
+	__u16 iui_recsize;
+	__u16 iui_ptrsize;
+	__u16 iui_height;
+	char  iui_fmt_name[DX_FMT_NAME_LEN];
+};
+
+/*
+ * Creat an iam file, but do NOT open it.
+ * Return 0 if success, else -1.
+ */
+int iam_creat(char *filename, enum iam_fmt_t fmt,
+	      int blocksize, int keysize, int recsize, int ptrsize);
+
+/*
+ * Open an iam file, but do NOT creat it if the file doesn't exist.
+ * Please use iam_creat for creating the file before use iam_open.
+ * Return file id (fd) if success, else -1.
+ */
+int iam_open(char *filename, struct iam_uapi_info *ua);
+
+/*
+ * Close file opened by iam_open.
+ */
+int iam_close(int fd);
+
+/*
+ * Please use iam_open before use this function.
+ */
+int iam_insert(int fd, struct iam_uapi_info *ua,
+	       int key_need_convert, char *keybuf,
+	       int rec_need_convert, char *recbuf);
+
+/*
+ * Please use iam_open before use this function.
+ */
+int iam_lookup(int fd, struct iam_uapi_info *ua,
+	       int key_need_convert, char *key_buf,
+	       int *keysize, char *save_key,
+	       int rec_need_convert, char *rec_buf,
+	       int *recsize, char *save_rec);
+
+/*
+ * Please use iam_open before use this function.
+ */
+int iam_delete(int fd, struct iam_uapi_info *ua,
+	       int key_need_convert, char *keybuf,
+	       int rec_need_convert, char *recbuf);
+
+/*
+ * Please use iam_open before use this function.
+ */
+int iam_it_start(int fd, struct iam_uapi_info *ua,
+		 int key_need_convert, char *key_buf,
+		 int *keysize, char *save_key,
+		 int rec_need_convert, char *rec_buf,
+		 int *recsize, char *save_rec);
+
+/*
+ * Please use iam_open before use this function.
+ */
+int iam_it_next(int fd, struct iam_uapi_info *ua,
+		int key_need_convert, char *key_buf,
+		int *keysize, char *save_key,
+		int rec_need_convert, char *rec_buf,
+		int *recsize, char *save_rec);
+
+/*
+ * Please use iam_open before use this function.
+ */
+int iam_it_stop(int fd, struct iam_uapi_info *ua,
+		int key_need_convert, char *keybuf,
+		int rec_need_convert, char *recbuf);
+
+/*
+ * Change iam file mode.
+ */
+int iam_polymorph(char *filename, unsigned long mode);
+
+/** @} libiam */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/liblustreapi.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/liblustreapi.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/liblustreapi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/liblustreapi.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+/*
+ * NOTE: This file is DEPRECATED!  Please include lustreapi.h directly
+ * instead of this file.  This file will be removed from a future version
+ * of lustre!
+ */
+
+#ifndef _LIBLUSTREAPI_H_
+#define _LIBLUSTREAPI_H_
+
+#include <lustre/lustreapi.h>
+#warning "Including liblustreapi.h is deprecated. Include lustreapi.h directly."
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/ll_fiemap.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,121 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre/ll_fiemap.h
+ *
+ * FIEMAP data structures and flags. This header file will be used until
+ * fiemap.h is available in the upstream kernel.
+ *
+ * Author: Kalpak Shah <kalpak.shah@sun.com>
+ * Author: Andreas Dilger <adilger@sun.com>
+ */
+
+#ifndef _LUSTRE_FIEMAP_H
+#define _LUSTRE_FIEMAP_H
+
+
+
+struct ll_fiemap_extent {
+	__u64 fe_logical;  /* logical offset in bytes for the start of
+			    * the extent from the beginning of the file */
+	__u64 fe_physical; /* physical offset in bytes for the start
+			    * of the extent from the beginning of the disk */
+	__u64 fe_length;   /* length in bytes for this extent */
+	__u64 fe_reserved64[2];
+	__u32 fe_flags;    /* FIEMAP_EXTENT_* flags for this extent */
+	__u32 fe_device;   /* device number for this extent */
+	__u32 fe_reserved[2];
+};
+
+struct ll_user_fiemap {
+	__u64 fm_start;  /* logical offset (inclusive) at
+			  * which to start mapping (in) */
+	__u64 fm_length; /* logical length of mapping which
+			  * userspace wants (in) */
+	__u32 fm_flags;  /* FIEMAP_FLAG_* flags for request (in/out) */
+	__u32 fm_mapped_extents;/* number of extents that were mapped (out) */
+	__u32 fm_extent_count;  /* size of fm_extents array (in) */
+	__u32 fm_reserved;
+	struct ll_fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
+};
+
+#define FIEMAP_MAX_OFFSET      (~0ULL)
+
+#define FIEMAP_FLAG_SYNC	 0x00000001 /* sync file data before map */
+#define FIEMAP_FLAG_XATTR	0x00000002 /* map extended attribute tree */
+
+#define FIEMAP_EXTENT_LAST	      0x00000001 /* Last extent in file. */
+#define FIEMAP_EXTENT_UNKNOWN	   0x00000002 /* Data location unknown. */
+#define FIEMAP_EXTENT_DELALLOC	  0x00000004 /* Location still pending.
+						    * Sets EXTENT_UNKNOWN. */
+#define FIEMAP_EXTENT_ENCODED	   0x00000008 /* Data can not be read
+						    * while fs is unmounted */
+#define FIEMAP_EXTENT_DATA_ENCRYPTED    0x00000080 /* Data is encrypted by fs.
+						    * Sets EXTENT_NO_DIRECT. */
+#define FIEMAP_EXTENT_NOT_ALIGNED       0x00000100 /* Extent offsets may not be
+						    * block aligned. */
+#define FIEMAP_EXTENT_DATA_INLINE       0x00000200 /* Data mixed with metadata.
+						    * Sets EXTENT_NOT_ALIGNED.*/
+#define FIEMAP_EXTENT_DATA_TAIL	 0x00000400 /* Multiple files in block.
+						    * Sets EXTENT_NOT_ALIGNED.*/
+#define FIEMAP_EXTENT_UNWRITTEN	 0x00000800 /* Space allocated, but
+						    * no data (i.e. zero). */
+#define FIEMAP_EXTENT_MERGED	    0x00001000 /* File does not natively
+						    * support extents. Result
+						    * merged for efficiency. */
+
+
+static inline size_t fiemap_count_to_size(size_t extent_count)
+{
+	return (sizeof(struct ll_user_fiemap) + extent_count *
+					       sizeof(struct ll_fiemap_extent));
+}
+
+static inline unsigned fiemap_size_to_count(size_t array_size)
+{
+	return ((array_size - sizeof(struct ll_user_fiemap)) /
+					       sizeof(struct ll_fiemap_extent));
+}
+
+#define FIEMAP_FLAG_DEVICE_ORDER 0x40000000 /* return device ordered mapping */
+
+#ifdef FIEMAP_FLAGS_COMPAT
+#undef FIEMAP_FLAGS_COMPAT
+#endif
+
+/* Lustre specific flags - use a high bit, don't conflict with upstream flag */
+#define FIEMAP_EXTENT_NO_DIRECT	 0x40000000 /* Data mapping undefined */
+#define FIEMAP_EXTENT_NET	       0x80000000 /* Data stored remotely.
+						    * Sets NO_DIRECT flag */
+
+#endif /* _LUSTRE_FIEMAP_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustreapi.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustreapi.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustreapi.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustreapi.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,310 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LUSTREAPI_H_
+#define _LUSTREAPI_H_
+
+/** \defgroup llapi llapi
+ *
+ * @{
+ */
+
+#include <lustre/lustre_user.h>
+
+typedef void (*llapi_cb_t)(char *obd_type_name, char *obd_name, char *obd_uuid, void *args);
+
+/* lustreapi message severity level */
+enum llapi_message_level {
+	LLAPI_MSG_OFF    = 0,
+	LLAPI_MSG_FATAL  = 1,
+	LLAPI_MSG_ERROR  = 2,
+	LLAPI_MSG_WARN   = 3,
+	LLAPI_MSG_NORMAL = 4,
+	LLAPI_MSG_INFO   = 5,
+	LLAPI_MSG_DEBUG  = 6,
+	LLAPI_MSG_MAX
+};
+
+/* the bottom three bits reserved for llapi_message_level */
+#define LLAPI_MSG_MASK	  0x00000007
+#define LLAPI_MSG_NO_ERRNO      0x00000010
+
+extern void llapi_msg_set_level(int level);
+extern void llapi_error(int level, int rc, char *fmt, ...);
+#define llapi_err_noerrno(level, fmt, a...)			     \
+	llapi_error((level) | LLAPI_MSG_NO_ERRNO, 0, fmt, ## a)
+extern void llapi_printf(int level, char *fmt, ...);
+extern int llapi_file_create(const char *name, unsigned long long stripe_size,
+			     int stripe_offset, int stripe_count,
+			     int stripe_pattern);
+extern int llapi_file_open(const char *name, int flags, int mode,
+			   unsigned long long stripe_size, int stripe_offset,
+			   int stripe_count, int stripe_pattern);
+extern int llapi_file_create_pool(const char *name,
+				  unsigned long long stripe_size,
+				  int stripe_offset, int stripe_count,
+				  int stripe_pattern, char *pool_name);
+extern int llapi_file_open_pool(const char *name, int flags, int mode,
+				unsigned long long stripe_size,
+				int stripe_offset, int stripe_count,
+				int stripe_pattern, char *pool_name);
+extern int llapi_poollist(const char *name);
+extern int llapi_get_poollist(const char *name, char **poollist, int list_size,
+			      char *buffer, int buffer_size);
+extern int llapi_get_poolmembers(const char *poolname, char **members,
+				 int list_size, char *buffer, int buffer_size);
+extern int llapi_file_get_stripe(const char *path, struct lov_user_md *lum);
+#define HAVE_LLAPI_FILE_LOOKUP
+extern int llapi_file_lookup(int dirfd, const char *name);
+
+#define VERBOSE_COUNT      0x1
+#define VERBOSE_SIZE       0x2
+#define VERBOSE_OFFSET     0x4
+#define VERBOSE_POOL       0x8
+#define VERBOSE_DETAIL     0x10
+#define VERBOSE_OBJID      0x20
+#define VERBOSE_GENERATION 0x40
+#define VERBOSE_MDTINDEX   0x80
+#define VERBOSE_ALL	(VERBOSE_COUNT | VERBOSE_SIZE | VERBOSE_OFFSET | \
+			    VERBOSE_POOL | VERBOSE_OBJID | VERBOSE_GENERATION)
+
+struct find_param {
+	unsigned int maxdepth;
+	time_t  atime;
+	time_t  mtime;
+	time_t  ctime;
+	int     asign;  /* cannot be bitfields due to using pointers to */
+	int     csign;  /* access them during argument parsing. */
+	int     msign;
+	int     type;
+	int	     size_sign:2,	/* these need to be signed values */
+			stripesize_sign:2,
+			stripecount_sign:2;
+	unsigned long long size;
+	unsigned long long size_units;
+	uid_t uid;
+	gid_t gid;
+
+	unsigned long   zeroend:1,
+			recursive:1,
+			exclude_pattern:1,
+			exclude_type:1,
+			exclude_obd:1,
+			exclude_mdt:1,
+			exclude_gid:1,
+			exclude_uid:1,
+			check_gid:1,	    /* group ID */
+			check_uid:1,	    /* user ID */
+			check_pool:1,	   /* LOV pool name */
+			check_size:1,	   /* file size */
+			exclude_pool:1,
+			exclude_size:1,
+			exclude_atime:1,
+			exclude_mtime:1,
+			exclude_ctime:1,
+			get_lmv:1,	      /* get MDT list from LMV */
+			raw:1,		  /* do not fill in defaults */
+			check_stripesize:1,     /* LOV stripe size */
+			exclude_stripesize:1,
+			check_stripecount:1,    /* LOV stripe count */
+			exclude_stripecount:1;
+
+	int     verbose;
+	int     quiet;
+
+	/* regular expression */
+	char   *pattern;
+
+	char   *print_fmt;
+
+	struct  obd_uuid       *obduuid;
+	int		     num_obds;
+	int		     num_alloc_obds;
+	int		     obdindex;
+	int		    *obdindexes;
+
+	struct  obd_uuid       *mdtuuid;
+	int		     num_mdts;
+	int		     num_alloc_mdts;
+	int		     mdtindex;
+	int		    *mdtindexes;
+	int		     file_mdtindex;
+
+	int	lumlen;
+	struct  lov_user_mds_data *lmd;
+
+	char poolname[LOV_MAXPOOLNAME + 1];
+
+	int			fp_lmv_count;
+	struct lmv_user_md	*fp_lmv_md;
+
+	unsigned long long stripesize;
+	unsigned long long stripesize_units;
+	unsigned long long stripecount;
+
+	/* In-process parameters. */
+	unsigned long   got_uuids:1,
+			obds_printed:1,
+			have_fileinfo:1;	/* file attrs and LOV xattr */
+	unsigned int    depth;
+	dev_t	   st_dev;
+};
+
+extern int llapi_ostlist(char *path, struct find_param *param);
+extern int llapi_uuid_match(char *real_uuid, char *search_uuid);
+extern int llapi_getstripe(char *path, struct find_param *param);
+extern int llapi_find(char *path, struct find_param *param);
+
+extern int llapi_file_fget_mdtidx(int fd, int *mdtidx);
+extern int llapi_dir_create_pool(const char *name, int flags, int stripe_offset,
+				 int stripe_count, int stripe_pattern,
+				 char *poolname);
+int llapi_direntry_remove(char *dname);
+extern int llapi_obd_statfs(char *path, __u32 type, __u32 index,
+		     struct obd_statfs *stat_buf,
+		     struct obd_uuid *uuid_buf);
+extern int llapi_ping(char *obd_type, char *obd_name);
+extern int llapi_target_check(int num_types, char **obd_types, char *dir);
+extern int llapi_file_get_lov_uuid(const char *path, struct obd_uuid *lov_uuid);
+extern int llapi_file_get_lmv_uuid(const char *path, struct obd_uuid *lmv_uuid);
+extern int llapi_file_fget_lov_uuid(int fd, struct obd_uuid *lov_uuid);
+extern int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count);
+extern int llapi_lmv_get_uuids(int fd, struct obd_uuid *uuidp, int *mdt_count);
+extern int llapi_is_lustre_mnttype(const char *type);
+extern int llapi_search_ost(char *fsname, char *poolname, char *ostname);
+extern int llapi_get_obd_count(char *mnt, int *count, int is_mdt);
+extern int parse_size(char *optarg, unsigned long long *size,
+		      unsigned long long *size_units, int bytes_spec);
+extern int llapi_search_mounts(const char *pathname, int index,
+			       char *mntdir, char *fsname);
+extern int llapi_search_fsname(const char *pathname, char *fsname);
+extern int llapi_getname(const char *path, char *buf, size_t size);
+
+extern void llapi_ping_target(char *obd_type, char *obd_name,
+			      char *obd_uuid, void *args);
+
+extern int llapi_search_rootpath(char *pathname, const char *fsname);
+
+struct mntent;
+#define HAVE_LLAPI_IS_LUSTRE_MNT
+extern int llapi_is_lustre_mnt(struct mntent *mnt);
+extern int llapi_quotachown(char *path, int flag);
+extern int llapi_quotacheck(char *mnt, int check_type);
+extern int llapi_poll_quotacheck(char *mnt, struct if_quotacheck *qchk);
+extern int llapi_quotactl(char *mnt, struct if_quotactl *qctl);
+extern int llapi_target_iterate(int type_num, char **obd_type, void *args,
+				llapi_cb_t cb);
+extern int llapi_get_connect_flags(const char *mnt, __u64 *flags);
+extern int llapi_lsetfacl(int argc, char *argv[]);
+extern int llapi_lgetfacl(int argc, char *argv[]);
+extern int llapi_rsetfacl(int argc, char *argv[]);
+extern int llapi_rgetfacl(int argc, char *argv[]);
+extern int llapi_cp(int argc, char *argv[]);
+extern int llapi_ls(int argc, char *argv[]);
+extern int llapi_fid2path(const char *device, const char *fidstr, char *path,
+			  int pathlen, long long *recno, int *linkno);
+extern int llapi_path2fid(const char *path, lustre_fid *fid);
+extern int llapi_fd2fid(const int fd, lustre_fid *fid);
+
+extern int llapi_get_version(char *buffer, int buffer_size, char **version);
+extern int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags);
+extern int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus);
+extern int llapi_hsm_state_set(const char *path, __u64 setmask, __u64 clearmask,
+			       __u32 archive_id);
+
+extern int llapi_create_volatile_idx(char *directory, int idx, int mode);
+static inline int llapi_create_volatile(char *directory, int mode)
+{
+	return llapi_create_volatile_idx(directory, -1, mode);
+}
+
+
+extern int llapi_fswap_layouts(const int fd1, const int fd2,
+			       __u64 dv1, __u64 dv2, __u64 flags);
+extern int llapi_swap_layouts(const char *path1, const char *path2,
+			      __u64 dv1, __u64 dv2, __u64 flags);
+
+/* Changelog interface.  priv is private state, managed internally
+   by these functions */
+#define CHANGELOG_FLAG_FOLLOW 0x01   /* Not yet implemented */
+#define CHANGELOG_FLAG_BLOCK  0x02   /* Blocking IO makes sense in case of
+   slow user parsing of the records, but it also prevents us from cleaning
+   up if the records are not consumed. */
+
+/* Records received are in extentded format now, though most of them are still
+ * written in disk in changelog_rec format (to save space and time), it's
+ * converted to extented format in the lustre api to ease changelog analysis. */
+#define HAVE_CHANGELOG_EXTEND_REC 1
+
+extern int llapi_changelog_start(void **priv, int flags, const char *mdtname,
+				 long long startrec);
+extern int llapi_changelog_fini(void **priv);
+extern int llapi_changelog_recv(void *priv, struct changelog_ext_rec **rech);
+extern int llapi_changelog_free(struct changelog_ext_rec **rech);
+/* Allow records up to endrec to be destroyed; requires registered id. */
+extern int llapi_changelog_clear(const char *mdtname, const char *idstr,
+				 long long endrec);
+
+/* HSM copytool interface.
+ * priv is private state, managed internally by these functions
+ */
+struct hsm_copytool_private;
+extern int llapi_hsm_copytool_start(struct hsm_copytool_private **priv,
+				    char *fsname, int flags,
+				    int archive_count, int *archives);
+extern int llapi_hsm_copytool_fini(struct hsm_copytool_private **priv);
+extern int llapi_hsm_copytool_recv(struct hsm_copytool_private *priv,
+				   struct hsm_action_list **hal, int *msgsize);
+extern int llapi_hsm_copytool_free(struct hsm_action_list **hal);
+extern int llapi_hsm_copy_start(char *mnt, struct hsm_copy *copy,
+				const struct hsm_action_item *hai);
+extern int llapi_hsm_copy_end(char *mnt, struct hsm_copy *copy,
+			      const struct hsm_progress *hp);
+extern int llapi_hsm_progress(char *mnt, struct hsm_progress *hp);
+extern int llapi_hsm_import(const char *dst, int archive, struct stat *st,
+			    unsigned long long stripe_size, int stripe_offset,
+			    int stripe_count, int stripe_pattern,
+			    char *pool_name, lustre_fid *newfid);
+
+/* HSM user interface */
+extern struct hsm_user_request *llapi_hsm_user_request_alloc(int itemcount,
+							     int data_len);
+extern int llapi_hsm_request(char *mnt, struct hsm_user_request *request);
+extern int llapi_hsm_current_action(const char *path,
+				    struct hsm_current_action *hca);
+/** @} llapi */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_build_version.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_build_version.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_build_version.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_build_version.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2 @@
+#define BUILD_VERSION "v2_3_64_0-g6e62c21-CHANGED-3.9.0"
+#define LUSTRE_RELEASE 3.9.0_g6e62c21
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3653 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre/lustre_idl.h
+ *
+ * Lustre wire protocol definitions.
+ */
+
+/** \defgroup lustreidl lustreidl
+ *
+ * Lustre wire protocol definitions.
+ *
+ * ALL structs passing over the wire should be declared here.  Structs
+ * that are used in interfaces with userspace should go in lustre_user.h.
+ *
+ * All structs being declared here should be built from simple fixed-size
+ * types (__u8, __u16, __u32, __u64) or be built from other types or
+ * structs also declared in this file.  Similarly, all flags and magic
+ * values in those structs should also be declared here.  This ensures
+ * that the Lustre wire protocol is not influenced by external dependencies.
+ *
+ * The only other acceptable items in this file are VERY SIMPLE accessor
+ * functions to avoid callers grubbing inside the structures, and the
+ * prototypes of the swabber functions for each struct.  Nothing that
+ * depends on external functions or definitions should be in here.
+ *
+ * Structs must be properly aligned to put 64-bit values on an 8-byte
+ * boundary.  Any structs being added here must also be added to
+ * utils/wirecheck.c and "make newwiretest" run to regenerate the
+ * utils/wiretest.c sources.  This allows us to verify that wire structs
+ * have the proper alignment/size on all architectures.
+ *
+ * DO NOT CHANGE any of the structs, flags, values declared here and used
+ * in released Lustre versions.  Some structs may have padding fields that
+ * can be used.  Some structs might allow addition at the end (verify this
+ * in the code to ensure that new/old clients that see this larger struct
+ * do not fail, otherwise you need to implement protocol compatibility).
+ *
+ * We assume all nodes are either little-endian or big-endian, and we
+ * always send messages in the sender's native format.  The receiver
+ * detects the message format by checking the 'magic' field of the message
+ * (see lustre_msg_swabbed() below).
+ *
+ * Each wire type has corresponding 'lustre_swab_xxxtypexxx()' routines,
+ * implemented either here, inline (trivial implementations) or in
+ * ptlrpc/pack_generic.c.  These 'swabbers' convert the type from "other"
+ * endian, in-place in the message buffer.
+ *
+ * A swabber takes a single pointer argument.  The caller must already have
+ * verified that the length of the message buffer >= sizeof (type).
+ *
+ * For variable length types, a second 'lustre_swab_v_xxxtypexxx()' routine
+ * may be defined that swabs just the variable part, after the caller has
+ * verified that the message buffer is large enough.
+ *
+ * @{
+ */
+
+#ifndef _LUSTRE_IDL_H_
+#define _LUSTRE_IDL_H_
+
+#if !defined(LASSERT) && !defined(LPU64)
+#include <linux/libcfs/libcfs.h> /* for LASSERT, LPUX64, etc */
+#endif
+
+/* Defn's shared with user-space. */
+#include <lustre/lustre_user.h>
+
+/*
+ *  GENERAL STUFF
+ */
+/* FOO_REQUEST_PORTAL is for incoming requests on the FOO
+ * FOO_REPLY_PORTAL   is for incoming replies on the FOO
+ * FOO_BULK_PORTAL    is for incoming bulk on the FOO
+ */
+
+#define CONNMGR_REQUEST_PORTAL	  1
+#define CONNMGR_REPLY_PORTAL	    2
+//#define OSC_REQUEST_PORTAL	    3
+#define OSC_REPLY_PORTAL		4
+//#define OSC_BULK_PORTAL	       5
+#define OST_IO_PORTAL		   6
+#define OST_CREATE_PORTAL	       7
+#define OST_BULK_PORTAL		 8
+//#define MDC_REQUEST_PORTAL	    9
+#define MDC_REPLY_PORTAL	       10
+//#define MDC_BULK_PORTAL	      11
+#define MDS_REQUEST_PORTAL	     12
+//#define MDS_REPLY_PORTAL	     13
+#define MDS_BULK_PORTAL		14
+#define LDLM_CB_REQUEST_PORTAL	 15
+#define LDLM_CB_REPLY_PORTAL	   16
+#define LDLM_CANCEL_REQUEST_PORTAL     17
+#define LDLM_CANCEL_REPLY_PORTAL       18
+//#define PTLBD_REQUEST_PORTAL	   19
+//#define PTLBD_REPLY_PORTAL	     20
+//#define PTLBD_BULK_PORTAL	      21
+#define MDS_SETATTR_PORTAL	     22
+#define MDS_READPAGE_PORTAL	    23
+#define MDS_MDS_PORTAL		 24
+
+#define MGC_REPLY_PORTAL	       25
+#define MGS_REQUEST_PORTAL	     26
+#define MGS_REPLY_PORTAL	       27
+#define OST_REQUEST_PORTAL	     28
+#define FLD_REQUEST_PORTAL	     29
+#define SEQ_METADATA_PORTAL	    30
+#define SEQ_DATA_PORTAL		31
+#define SEQ_CONTROLLER_PORTAL	  32
+#define MGS_BULK_PORTAL		33
+
+/* Portal 63 is reserved for the Cray Inc DVS - nic@cray.com, roe@cray.com, n8851@cray.com */
+
+/* packet types */
+#define PTL_RPC_MSG_REQUEST 4711
+#define PTL_RPC_MSG_ERR     4712
+#define PTL_RPC_MSG_REPLY   4713
+
+/* DON'T use swabbed values of MAGIC as magic! */
+#define LUSTRE_MSG_MAGIC_V1 0x0BD00BD0
+#define LUSTRE_MSG_MAGIC_V2 0x0BD00BD3
+
+#define LUSTRE_MSG_MAGIC_V1_SWABBED 0xD00BD00B
+#define LUSTRE_MSG_MAGIC_V2_SWABBED 0xD30BD00B
+
+#define LUSTRE_MSG_MAGIC LUSTRE_MSG_MAGIC_V2
+
+#define PTLRPC_MSG_VERSION  0x00000003
+#define LUSTRE_VERSION_MASK 0xffff0000
+#define LUSTRE_OBD_VERSION  0x00010000
+#define LUSTRE_MDS_VERSION  0x00020000
+#define LUSTRE_OST_VERSION  0x00030000
+#define LUSTRE_DLM_VERSION  0x00040000
+#define LUSTRE_LOG_VERSION  0x00050000
+#define LUSTRE_MGS_VERSION  0x00060000
+
+typedef __u32 mdsno_t;
+typedef __u64 seqno_t;
+typedef __u64 obd_id;
+typedef __u64 obd_seq;
+typedef __s64 obd_time;
+typedef __u64 obd_size;
+typedef __u64 obd_off;
+typedef __u64 obd_blocks;
+typedef __u64 obd_valid;
+typedef __u32 obd_blksize;
+typedef __u32 obd_mode;
+typedef __u32 obd_uid;
+typedef __u32 obd_gid;
+typedef __u32 obd_flag;
+typedef __u32 obd_count;
+
+/**
+ * Describes a range of sequence, lsr_start is included but lsr_end is
+ * not in the range.
+ * Same structure is used in fld module where lsr_index field holds mdt id
+ * of the home mdt.
+ */
+struct lu_seq_range {
+	__u64 lsr_start;
+	__u64 lsr_end;
+	__u32 lsr_index;
+	__u32 lsr_flags;
+};
+
+#define LU_SEQ_RANGE_MDT	0x0
+#define LU_SEQ_RANGE_OST	0x1
+#define LU_SEQ_RANGE_ANY	0x3
+
+#define LU_SEQ_RANGE_MASK	0x3
+
+static inline unsigned fld_range_type(const struct lu_seq_range *range)
+{
+	return range->lsr_flags & LU_SEQ_RANGE_MASK;
+}
+
+static inline int fld_range_is_ost(const struct lu_seq_range *range)
+{
+	return fld_range_type(range) == LU_SEQ_RANGE_OST;
+}
+
+static inline int fld_range_is_mdt(const struct lu_seq_range *range)
+{
+	return fld_range_type(range) == LU_SEQ_RANGE_MDT;
+}
+
+/**
+ * This all range is only being used when fld client sends fld query request,
+ * but it does not know whether the seq is MDT or OST, so it will send req
+ * with ALL type, which means either seq type gotten from lookup can be
+ * expected.
+ */
+static inline unsigned fld_range_is_any(const struct lu_seq_range *range)
+{
+	return fld_range_type(range) == LU_SEQ_RANGE_ANY;
+}
+
+static inline void fld_range_set_type(struct lu_seq_range *range,
+				      unsigned flags)
+{
+	LASSERT(!(flags & ~LU_SEQ_RANGE_MASK));
+	range->lsr_flags |= flags;
+}
+
+static inline void fld_range_set_mdt(struct lu_seq_range *range)
+{
+	fld_range_set_type(range, LU_SEQ_RANGE_MDT);
+}
+
+static inline void fld_range_set_ost(struct lu_seq_range *range)
+{
+	fld_range_set_type(range, LU_SEQ_RANGE_OST);
+}
+
+static inline void fld_range_set_any(struct lu_seq_range *range)
+{
+	fld_range_set_type(range, LU_SEQ_RANGE_ANY);
+}
+
+/**
+ * returns  width of given range \a r
+ */
+
+static inline __u64 range_space(const struct lu_seq_range *range)
+{
+	return range->lsr_end - range->lsr_start;
+}
+
+/**
+ * initialize range to zero
+ */
+
+static inline void range_init(struct lu_seq_range *range)
+{
+	range->lsr_start = range->lsr_end = range->lsr_index = 0;
+}
+
+/**
+ * check if given seq id \a s is within given range \a r
+ */
+
+static inline int range_within(const struct lu_seq_range *range,
+			       __u64 s)
+{
+	return s >= range->lsr_start && s < range->lsr_end;
+}
+
+static inline int range_is_sane(const struct lu_seq_range *range)
+{
+	return (range->lsr_end >= range->lsr_start);
+}
+
+static inline int range_is_zero(const struct lu_seq_range *range)
+{
+	return (range->lsr_start == 0 && range->lsr_end == 0);
+}
+
+static inline int range_is_exhausted(const struct lu_seq_range *range)
+
+{
+	return range_space(range) == 0;
+}
+
+/* return 0 if two range have the same location */
+static inline int range_compare_loc(const struct lu_seq_range *r1,
+				    const struct lu_seq_range *r2)
+{
+	return r1->lsr_index != r2->lsr_index ||
+	       r1->lsr_flags != r2->lsr_flags;
+}
+
+#define DRANGE "[%#16.16"LPF64"x-%#16.16"LPF64"x):%x:%s"
+
+#define PRANGE(range)		\
+	(range)->lsr_start,	\
+	(range)->lsr_end,	\
+	(range)->lsr_index,	\
+	fld_range_is_mdt(range) ? "mdt" : "ost"
+
+
+/** \defgroup lu_fid lu_fid
+ * @{ */
+
+/**
+ * Flags for lustre_mdt_attrs::lma_compat and lustre_mdt_attrs::lma_incompat.
+ * Deprecated since HSM and SOM attributes are now stored in separate on-disk
+ * xattr.
+ */
+enum lma_compat {
+	LMAC_HSM = 0x00000001,
+	LMAC_SOM = 0x00000002,
+};
+
+/**
+ * Masks for all features that should be supported by a Lustre version to
+ * access a specific file.
+ * This information is stored in lustre_mdt_attrs::lma_incompat.
+ */
+enum lma_incompat {
+	LMAI_RELEASED = 0x0000001, /* file is released */
+	LMAI_AGENT = 0x00000002, /* agent inode */
+	LMAI_REMOTE_PARENT = 0x00000004, /* the parent of the object
+					    is on the remote MDT */
+};
+#define LMA_INCOMPAT_SUPP	(LMAI_AGENT | LMAI_REMOTE_PARENT)
+
+extern void lustre_lma_swab(struct lustre_mdt_attrs *lma);
+extern void lustre_lma_init(struct lustre_mdt_attrs *lma,
+			    const struct lu_fid *fid, __u32 incompat);
+/**
+ * SOM on-disk attributes stored in a separate xattr.
+ */
+struct som_attrs {
+	/** Bitfield for supported data in this structure. For future use. */
+	__u32	som_compat;
+
+	/** Incompat feature list. The supported feature mask is availabe in
+	 * SOM_INCOMPAT_SUPP */
+	__u32	som_incompat;
+
+	/** IO Epoch SOM attributes belongs to */
+	__u64	som_ioepoch;
+	/** total file size in objects */
+	__u64	som_size;
+	/** total fs blocks in objects */
+	__u64	som_blocks;
+	/** mds mount id the size is valid for */
+	__u64	som_mountid;
+};
+extern void lustre_som_swab(struct som_attrs *attrs);
+
+#define SOM_INCOMPAT_SUPP 0x0
+
+/**
+ * HSM on-disk attributes stored in a separate xattr.
+ */
+struct hsm_attrs {
+	/** Bitfield for supported data in this structure. For future use. */
+	__u32	hsm_compat;
+
+	/** HSM flags, see hsm_flags enum below */
+	__u32	hsm_flags;
+	/** backend archive id associated with the file */
+	__u64	hsm_arch_id;
+	/** version associated with the last archiving, if any */
+	__u64	hsm_arch_ver;
+};
+extern void lustre_hsm_swab(struct hsm_attrs *attrs);
+
+/**
+ * fid constants
+ */
+enum {
+	/** LASTID file has zero OID */
+	LUSTRE_FID_LASTID_OID = 0UL,
+	/** initial fid id value */
+	LUSTRE_FID_INIT_OID  = 1UL
+};
+
+/** returns fid object sequence */
+static inline __u64 fid_seq(const struct lu_fid *fid)
+{
+	return fid->f_seq;
+}
+
+/** returns fid object id */
+static inline __u32 fid_oid(const struct lu_fid *fid)
+{
+	return fid->f_oid;
+}
+
+/** returns fid object version */
+static inline __u32 fid_ver(const struct lu_fid *fid)
+{
+	return fid->f_ver;
+}
+
+static inline void fid_zero(struct lu_fid *fid)
+{
+	memset(fid, 0, sizeof(*fid));
+}
+
+static inline obd_id fid_ver_oid(const struct lu_fid *fid)
+{
+	return ((__u64)fid_ver(fid) << 32 | fid_oid(fid));
+}
+
+/**
+ * Note that reserved SEQ numbers below 12 will conflict with ldiskfs
+ * inodes in the IGIF namespace, so these reserved SEQ numbers can be
+ * used for other purposes and not risk collisions with existing inodes.
+ *
+ * Different FID Format
+ * http://arch.lustre.org/index.php?title=Interoperability_fids_zfs#NEW.0
+ */
+enum fid_seq {
+	FID_SEQ_OST_MDT0	= 0,
+	FID_SEQ_LLOG		= 1, /* unnamed llogs */
+	FID_SEQ_ECHO		= 2,
+	FID_SEQ_OST_MDT1	= 3,
+	FID_SEQ_OST_MAX		= 9, /* Max MDT count before OST_on_FID */
+	FID_SEQ_LLOG_NAME	= 10, /* named llogs */
+	FID_SEQ_RSVD		= 11,
+	FID_SEQ_IGIF		= 12,
+	FID_SEQ_IGIF_MAX	= 0x0ffffffffULL,
+	FID_SEQ_IDIF		= 0x100000000ULL,
+	FID_SEQ_IDIF_MAX	= 0x1ffffffffULL,
+	/* Normal FID sequence starts from this value, i.e. 1<<33 */
+	FID_SEQ_START		= 0x200000000ULL,
+	/* sequence for local pre-defined FIDs listed in local_oid */
+	FID_SEQ_LOCAL_FILE	= 0x200000001ULL,
+	FID_SEQ_DOT_LUSTRE	= 0x200000002ULL,
+	/* sequence is used for local named objects FIDs generated
+	 * by local_object_storage library */
+	FID_SEQ_LOCAL_NAME	= 0x200000003ULL,
+	/* Because current FLD will only cache the fid sequence, instead
+	 * of oid on the client side, if the FID needs to be exposed to
+	 * clients sides, it needs to make sure all of fids under one
+	 * sequence will be located in one MDT. */
+	FID_SEQ_SPECIAL		= 0x200000004ULL,
+	FID_SEQ_QUOTA		= 0x200000005ULL,
+	FID_SEQ_QUOTA_GLB	= 0x200000006ULL,
+	FID_SEQ_ROOT		= 0x200000007ULL,  /* Located on MDT0 */
+	FID_SEQ_NORMAL		= 0x200000400ULL,
+	FID_SEQ_LOV_DEFAULT	= 0xffffffffffffffffULL
+};
+
+#define OBIF_OID_MAX_BITS	   32
+#define OBIF_MAX_OID		(1ULL << OBIF_OID_MAX_BITS)
+#define OBIF_OID_MASK	       ((1ULL << OBIF_OID_MAX_BITS) - 1)
+#define IDIF_OID_MAX_BITS	   48
+#define IDIF_MAX_OID		(1ULL << IDIF_OID_MAX_BITS)
+#define IDIF_OID_MASK	       ((1ULL << IDIF_OID_MAX_BITS) - 1)
+
+/** OID for FID_SEQ_SPECIAL */
+enum special_oid {
+	/* Big Filesystem Lock to serialize rename operations */
+	FID_OID_SPECIAL_BFL     = 1UL,
+};
+
+/** OID for FID_SEQ_DOT_LUSTRE */
+enum dot_lustre_oid {
+	FID_OID_DOT_LUSTRE  = 1UL,
+	FID_OID_DOT_LUSTRE_OBF = 2UL,
+};
+
+static inline int fid_seq_is_mdt0(obd_seq seq)
+{
+	return (seq == FID_SEQ_OST_MDT0);
+}
+
+static inline int fid_seq_is_mdt(const __u64 seq)
+{
+	return seq == FID_SEQ_OST_MDT0 || seq >= FID_SEQ_NORMAL;
+};
+
+static inline int fid_seq_is_echo(obd_seq seq)
+{
+	return (seq == FID_SEQ_ECHO);
+}
+
+static inline int fid_is_echo(const struct lu_fid *fid)
+{
+	return fid_seq_is_echo(fid_seq(fid));
+}
+
+static inline int fid_seq_is_llog(obd_seq seq)
+{
+	return (seq == FID_SEQ_LLOG);
+}
+
+static inline int fid_is_llog(const struct lu_fid *fid)
+{
+	/* file with OID == 0 is not llog but contains last oid */
+	return fid_seq_is_llog(fid_seq(fid)) && fid_oid(fid) > 0;
+}
+
+static inline int fid_seq_is_rsvd(const __u64 seq)
+{
+	return (seq > FID_SEQ_OST_MDT0 && seq <= FID_SEQ_RSVD);
+};
+
+static inline int fid_seq_is_special(const __u64 seq)
+{
+	return seq == FID_SEQ_SPECIAL;
+};
+
+static inline int fid_seq_is_local_file(const __u64 seq)
+{
+	return seq == FID_SEQ_LOCAL_FILE ||
+	       seq == FID_SEQ_LOCAL_NAME;
+};
+
+static inline int fid_seq_is_root(const __u64 seq)
+{
+	return seq == FID_SEQ_ROOT;
+}
+
+static inline int fid_seq_is_dot(const __u64 seq)
+{
+	return seq == FID_SEQ_DOT_LUSTRE;
+}
+
+static inline int fid_seq_is_default(const __u64 seq)
+{
+	return seq == FID_SEQ_LOV_DEFAULT;
+}
+
+static inline int fid_is_mdt0(const struct lu_fid *fid)
+{
+	return fid_seq_is_mdt0(fid_seq(fid));
+}
+
+static inline void lu_root_fid(struct lu_fid *fid)
+{
+	fid->f_seq = FID_SEQ_ROOT;
+	fid->f_oid = 1;
+	fid->f_ver = 0;
+}
+
+/**
+ * Check if a fid is igif or not.
+ * \param fid the fid to be tested.
+ * \return true if the fid is a igif; otherwise false.
+ */
+static inline int fid_seq_is_igif(const __u64 seq)
+{
+	return seq >= FID_SEQ_IGIF && seq <= FID_SEQ_IGIF_MAX;
+}
+
+static inline int fid_is_igif(const struct lu_fid *fid)
+{
+	return fid_seq_is_igif(fid_seq(fid));
+}
+
+/**
+ * Check if a fid is idif or not.
+ * \param fid the fid to be tested.
+ * \return true if the fid is a idif; otherwise false.
+ */
+static inline int fid_seq_is_idif(const __u64 seq)
+{
+	return seq >= FID_SEQ_IDIF && seq <= FID_SEQ_IDIF_MAX;
+}
+
+static inline int fid_is_idif(const struct lu_fid *fid)
+{
+	return fid_seq_is_idif(fid_seq(fid));
+}
+
+static inline int fid_is_local_file(const struct lu_fid *fid)
+{
+	return fid_seq_is_local_file(fid_seq(fid));
+}
+
+static inline int fid_seq_is_norm(const __u64 seq)
+{
+	return (seq >= FID_SEQ_NORMAL);
+}
+
+static inline int fid_is_norm(const struct lu_fid *fid)
+{
+	return fid_seq_is_norm(fid_seq(fid));
+}
+
+/* convert an OST objid into an IDIF FID SEQ number */
+static inline obd_seq fid_idif_seq(obd_id id, __u32 ost_idx)
+{
+	return FID_SEQ_IDIF | (ost_idx << 16) | ((id >> 32) & 0xffff);
+}
+
+/* convert a packed IDIF FID into an OST objid */
+static inline obd_id fid_idif_id(obd_seq seq, __u32 oid, __u32 ver)
+{
+	return ((__u64)ver << 48) | ((seq & 0xffff) << 32) | oid;
+}
+
+/* extract ost index from IDIF FID */
+static inline __u32 fid_idif_ost_idx(const struct lu_fid *fid)
+{
+	LASSERT(fid_is_idif(fid));
+	return (fid_seq(fid) >> 16) & 0xffff;
+}
+
+/* extract OST sequence (group) from a wire ost_id (id/seq) pair */
+static inline obd_seq ostid_seq(const struct ost_id *ostid)
+{
+	if (fid_seq_is_mdt0(ostid->oi.oi_seq))
+		return FID_SEQ_OST_MDT0;
+
+	if (fid_seq_is_default(ostid->oi.oi_seq))
+		return FID_SEQ_LOV_DEFAULT;
+
+	if (fid_is_idif(&ostid->oi_fid))
+		return FID_SEQ_OST_MDT0;
+
+	return fid_seq(&ostid->oi_fid);
+}
+
+/* extract OST objid from a wire ost_id (id/seq) pair */
+static inline obd_id ostid_id(const struct ost_id *ostid)
+{
+	if (fid_seq_is_mdt0(ostid_seq(ostid)))
+		return ostid->oi.oi_id & IDIF_OID_MASK;
+
+	if (fid_is_idif(&ostid->oi_fid))
+		return fid_idif_id(fid_seq(&ostid->oi_fid),
+				   fid_oid(&ostid->oi_fid), 0);
+
+	return fid_oid(&ostid->oi_fid);
+}
+
+static inline void ostid_set_seq(struct ost_id *oi, __u64 seq)
+{
+	if (fid_seq_is_mdt0(seq) || fid_seq_is_default(seq)) {
+		oi->oi.oi_seq = seq;
+	} else {
+		oi->oi_fid.f_seq = seq;
+		/* Note: if f_oid + f_ver is zero, we need init it
+		 * to be 1, otherwise, ostid_seq will treat this
+		 * as old ostid (oi_seq == 0) */
+		if (oi->oi_fid.f_oid == 0 && oi->oi_fid.f_ver == 0)
+			oi->oi_fid.f_oid = LUSTRE_FID_INIT_OID;
+	}
+}
+
+static inline void ostid_set_seq_mdt0(struct ost_id *oi)
+{
+	ostid_set_seq(oi, FID_SEQ_OST_MDT0);
+}
+
+static inline void ostid_set_seq_echo(struct ost_id *oi)
+{
+	ostid_set_seq(oi, FID_SEQ_ECHO);
+}
+
+static inline void ostid_set_seq_llog(struct ost_id *oi)
+{
+	ostid_set_seq(oi, FID_SEQ_LLOG);
+}
+
+/**
+ * Note: we need check oi_seq to decide where to set oi_id,
+ * so oi_seq should always be set ahead of oi_id.
+ */
+static inline void ostid_set_id(struct ost_id *oi, __u64 oid)
+{
+	if (fid_seq_is_mdt0(ostid_seq(oi))) {
+		if (oid >= IDIF_MAX_OID) {
+			CERROR("Bad "LPU64" to set "DOSTID"\n",
+				oid, POSTID(oi));
+			return;
+		}
+		oi->oi.oi_id = oid;
+	} else {
+		if (oid > OBIF_MAX_OID) {
+			CERROR("Bad "LPU64" to set "DOSTID"\n",
+				oid, POSTID(oi));
+			return;
+		}
+		oi->oi_fid.f_oid = oid;
+	}
+}
+
+static inline void ostid_inc_id(struct ost_id *oi)
+{
+	if (fid_seq_is_mdt0(ostid_seq(oi))) {
+		if (unlikely(ostid_id(oi) + 1 > IDIF_MAX_OID)) {
+			CERROR("Bad inc "DOSTID"\n", POSTID(oi));
+			return;
+		}
+		oi->oi.oi_id++;
+	} else {
+		oi->oi_fid.f_oid++;
+	}
+}
+
+static inline void ostid_dec_id(struct ost_id *oi)
+{
+	if (fid_seq_is_mdt0(ostid_seq(oi)))
+		oi->oi.oi_id--;
+	else
+		oi->oi_fid.f_oid--;
+}
+
+/**
+ * Unpack an OST object id/seq (group) into a FID.  This is needed for
+ * converting all obdo, lmm, lsm, etc. 64-bit id/seq pairs into proper
+ * FIDs.  Note that if an id/seq is already in FID/IDIF format it will
+ * be passed through unchanged.  Only legacy OST objects in "group 0"
+ * will be mapped into the IDIF namespace so that they can fit into the
+ * struct lu_fid fields without loss.  For reference see:
+ * http://arch.lustre.org/index.php?title=Interoperability_fids_zfs
+ */
+static inline int ostid_to_fid(struct lu_fid *fid, struct ost_id *ostid,
+			       __u32 ost_idx)
+{
+	if (ost_idx > 0xffff) {
+		CERROR("bad ost_idx, "DOSTID" ost_idx:%u\n", POSTID(ostid),
+		       ost_idx);
+		return -EBADF;
+	}
+
+	if (fid_seq_is_mdt0(ostid_seq(ostid))) {
+		/* This is a "legacy" (old 1.x/2.early) OST object in "group 0"
+		 * that we map into the IDIF namespace.  It allows up to 2^48
+		 * objects per OST, as this is the object namespace that has
+		 * been in production for years.  This can handle create rates
+		 * of 1M objects/s/OST for 9 years, or combinations thereof. */
+		if (ostid_id(ostid) >= IDIF_MAX_OID) {
+			 CERROR("bad MDT0 id, "DOSTID" ost_idx:%u\n",
+				POSTID(ostid), ost_idx);
+			 return -EBADF;
+		}
+		fid->f_seq = fid_idif_seq(ostid_id(ostid), ost_idx);
+		/* truncate to 32 bits by assignment */
+		fid->f_oid = ostid_id(ostid);
+		/* in theory, not currently used */
+		fid->f_ver = ostid_id(ostid) >> 48;
+	} else /* if (fid_seq_is_idif(seq) || fid_seq_is_norm(seq)) */ {
+	       /* This is either an IDIF object, which identifies objects across
+		* all OSTs, or a regular FID.  The IDIF namespace maps legacy
+		* OST objects into the FID namespace.  In both cases, we just
+		* pass the FID through, no conversion needed. */
+		if (ostid->oi_fid.f_ver != 0) {
+			CERROR("bad MDT0 id, "DOSTID" ost_idx:%u\n",
+				POSTID(ostid), ost_idx);
+			return -EBADF;
+		}
+		*fid = ostid->oi_fid;
+	}
+
+	return 0;
+}
+
+/* pack any OST FID into an ostid (id/seq) for the wire/disk */
+static inline int fid_to_ostid(const struct lu_fid *fid, struct ost_id *ostid)
+{
+	if (unlikely(fid_seq_is_igif(fid->f_seq))) {
+		CERROR("bad IGIF, "DFID"\n", PFID(fid));
+		return -EBADF;
+	}
+
+	if (fid_is_idif(fid)) {
+		ostid_set_seq_mdt0(ostid);
+		ostid_set_id(ostid, fid_idif_id(fid_seq(fid), fid_oid(fid),
+						fid_ver(fid)));
+	} else {
+		ostid->oi_fid = *fid;
+	}
+
+	return 0;
+}
+
+/* Check whether the fid is for LAST_ID */
+static inline int fid_is_last_id(const struct lu_fid *fid)
+{
+	return (fid_oid(fid) == 0);
+}
+
+/**
+ * Get inode number from a igif.
+ * \param fid a igif to get inode number from.
+ * \return inode number for the igif.
+ */
+static inline ino_t lu_igif_ino(const struct lu_fid *fid)
+{
+	return fid_seq(fid);
+}
+
+extern void lustre_swab_ost_id(struct ost_id *oid);
+
+/**
+ * Get inode generation from a igif.
+ * \param fid a igif to get inode generation from.
+ * \return inode generation for the igif.
+ */
+static inline __u32 lu_igif_gen(const struct lu_fid *fid)
+{
+	return fid_oid(fid);
+}
+
+/**
+ * Build igif from the inode number/generation.
+ */
+static inline void lu_igif_build(struct lu_fid *fid, __u32 ino, __u32 gen)
+{
+	fid->f_seq = ino;
+	fid->f_oid = gen;
+	fid->f_ver = 0;
+}
+
+/*
+ * Fids are transmitted across network (in the sender byte-ordering),
+ * and stored on disk in big-endian order.
+ */
+static inline void fid_cpu_to_le(struct lu_fid *dst, const struct lu_fid *src)
+{
+	/* check that all fields are converted */
+	CLASSERT(sizeof *src ==
+		 sizeof fid_seq(src) +
+		 sizeof fid_oid(src) + sizeof fid_ver(src));
+	dst->f_seq = cpu_to_le64(fid_seq(src));
+	dst->f_oid = cpu_to_le32(fid_oid(src));
+	dst->f_ver = cpu_to_le32(fid_ver(src));
+}
+
+static inline void fid_le_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
+{
+	/* check that all fields are converted */
+	CLASSERT(sizeof *src ==
+		 sizeof fid_seq(src) +
+		 sizeof fid_oid(src) + sizeof fid_ver(src));
+	dst->f_seq = le64_to_cpu(fid_seq(src));
+	dst->f_oid = le32_to_cpu(fid_oid(src));
+	dst->f_ver = le32_to_cpu(fid_ver(src));
+}
+
+static inline void fid_cpu_to_be(struct lu_fid *dst, const struct lu_fid *src)
+{
+	/* check that all fields are converted */
+	CLASSERT(sizeof *src ==
+		 sizeof fid_seq(src) +
+		 sizeof fid_oid(src) + sizeof fid_ver(src));
+	dst->f_seq = cpu_to_be64(fid_seq(src));
+	dst->f_oid = cpu_to_be32(fid_oid(src));
+	dst->f_ver = cpu_to_be32(fid_ver(src));
+}
+
+static inline void fid_be_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
+{
+	/* check that all fields are converted */
+	CLASSERT(sizeof *src ==
+		 sizeof fid_seq(src) +
+		 sizeof fid_oid(src) + sizeof fid_ver(src));
+	dst->f_seq = be64_to_cpu(fid_seq(src));
+	dst->f_oid = be32_to_cpu(fid_oid(src));
+	dst->f_ver = be32_to_cpu(fid_ver(src));
+}
+
+static inline int fid_is_sane(const struct lu_fid *fid)
+{
+	return fid != NULL &&
+	       ((fid_seq(fid) >= FID_SEQ_START && fid_ver(fid) == 0) ||
+		fid_is_igif(fid) || fid_is_idif(fid) ||
+		fid_seq_is_rsvd(fid_seq(fid)));
+}
+
+static inline int fid_is_zero(const struct lu_fid *fid)
+{
+	return fid_seq(fid) == 0 && fid_oid(fid) == 0;
+}
+
+extern void lustre_swab_lu_fid(struct lu_fid *fid);
+extern void lustre_swab_lu_seq_range(struct lu_seq_range *range);
+
+static inline int lu_fid_eq(const struct lu_fid *f0, const struct lu_fid *f1)
+{
+	/* Check that there is no alignment padding. */
+	CLASSERT(sizeof *f0 ==
+		 sizeof f0->f_seq + sizeof f0->f_oid + sizeof f0->f_ver);
+	return memcmp(f0, f1, sizeof *f0) == 0;
+}
+
+#define __diff_normalize(val0, val1)			    \
+({							      \
+	typeof(val0) __val0 = (val0);			   \
+	typeof(val1) __val1 = (val1);			   \
+								\
+	(__val0 == __val1 ? 0 : __val0 > __val1 ? +1 : -1);     \
+})
+
+static inline int lu_fid_cmp(const struct lu_fid *f0,
+			     const struct lu_fid *f1)
+{
+	return
+		__diff_normalize(fid_seq(f0), fid_seq(f1)) ?:
+		__diff_normalize(fid_oid(f0), fid_oid(f1)) ?:
+		__diff_normalize(fid_ver(f0), fid_ver(f1));
+}
+
+static inline void ostid_cpu_to_le(struct ost_id *src_oi,
+				   struct ost_id *dst_oi)
+{
+	if (fid_seq_is_mdt0(ostid_seq(src_oi))) {
+		dst_oi->oi.oi_id = cpu_to_le64(src_oi->oi.oi_id);
+		dst_oi->oi.oi_seq = cpu_to_le64(src_oi->oi.oi_seq);
+	} else {
+		fid_cpu_to_le(&dst_oi->oi_fid, &src_oi->oi_fid);
+	}
+}
+
+static inline void ostid_le_to_cpu(struct ost_id *src_oi,
+				   struct ost_id *dst_oi)
+{
+	if (fid_seq_is_mdt0(ostid_seq(src_oi))) {
+		dst_oi->oi.oi_id = le64_to_cpu(src_oi->oi.oi_id);
+		dst_oi->oi.oi_seq = le64_to_cpu(src_oi->oi.oi_seq);
+	} else {
+		fid_le_to_cpu(&dst_oi->oi_fid, &src_oi->oi_fid);
+	}
+}
+
+/** @} lu_fid */
+
+/** \defgroup lu_dir lu_dir
+ * @{ */
+
+/**
+ * Enumeration of possible directory entry attributes.
+ *
+ * Attributes follow directory entry header in the order they appear in this
+ * enumeration.
+ */
+enum lu_dirent_attrs {
+	LUDA_FID		= 0x0001,
+	LUDA_TYPE		= 0x0002,
+	LUDA_64BITHASH		= 0x0004,
+
+	/* The following attrs are used for MDT interanl only,
+	 * not visible to client */
+
+	/* Verify the dirent consistency */
+	LUDA_VERIFY		= 0x8000,
+	/* Only check but not repair the dirent inconsistency */
+	LUDA_VERIFY_DRYRUN	= 0x4000,
+	/* The dirent has been repaired, or to be repaired (dryrun). */
+	LUDA_REPAIR		= 0x2000,
+	/* The system is upgraded, has beed or to be repaired (dryrun). */
+	LUDA_UPGRADE		= 0x1000,
+	/* Ignore this record, go to next directly. */
+	LUDA_IGNORE		= 0x0800,
+};
+
+#define LU_DIRENT_ATTRS_MASK	0xf800
+
+/**
+ * Layout of readdir pages, as transmitted on wire.
+ */
+struct lu_dirent {
+	/** valid if LUDA_FID is set. */
+	struct lu_fid lde_fid;
+	/** a unique entry identifier: a hash or an offset. */
+	__u64	 lde_hash;
+	/** total record length, including all attributes. */
+	__u16	 lde_reclen;
+	/** name length */
+	__u16	 lde_namelen;
+	/** optional variable size attributes following this entry.
+	 *  taken from enum lu_dirent_attrs.
+	 */
+	__u32	 lde_attrs;
+	/** name is followed by the attributes indicated in ->ldp_attrs, in
+	 *  their natural order. After the last attribute, padding bytes are
+	 *  added to make ->lde_reclen a multiple of 8.
+	 */
+	char	  lde_name[0];
+};
+
+/*
+ * Definitions of optional directory entry attributes formats.
+ *
+ * Individual attributes do not have their length encoded in a generic way. It
+ * is assumed that consumer of an attribute knows its format. This means that
+ * it is impossible to skip over an unknown attribute, except by skipping over all
+ * remaining attributes (by using ->lde_reclen), which is not too
+ * constraining, because new server versions will append new attributes at
+ * the end of an entry.
+ */
+
+/**
+ * Fid directory attribute: a fid of an object referenced by the entry. This
+ * will be almost always requested by the client and supplied by the server.
+ *
+ * Aligned to 8 bytes.
+ */
+/* To have compatibility with 1.8, lets have fid in lu_dirent struct. */
+
+/**
+ * File type.
+ *
+ * Aligned to 2 bytes.
+ */
+struct luda_type {
+	__u16 lt_type;
+};
+
+struct lu_dirpage {
+	__u64	    ldp_hash_start;
+	__u64	    ldp_hash_end;
+	__u32	    ldp_flags;
+	__u32	    ldp_pad0;
+	struct lu_dirent ldp_entries[0];
+};
+
+enum lu_dirpage_flags {
+	/**
+	 * dirpage contains no entry.
+	 */
+	LDF_EMPTY   = 1 << 0,
+	/**
+	 * last entry's lde_hash equals ldp_hash_end.
+	 */
+	LDF_COLLIDE = 1 << 1
+};
+
+static inline struct lu_dirent *lu_dirent_start(struct lu_dirpage *dp)
+{
+	if (le32_to_cpu(dp->ldp_flags) & LDF_EMPTY)
+		return NULL;
+	else
+		return dp->ldp_entries;
+}
+
+static inline struct lu_dirent *lu_dirent_next(struct lu_dirent *ent)
+{
+	struct lu_dirent *next;
+
+	if (le16_to_cpu(ent->lde_reclen) != 0)
+		next = ((void *)ent) + le16_to_cpu(ent->lde_reclen);
+	else
+		next = NULL;
+
+	return next;
+}
+
+static inline int lu_dirent_calc_size(int namelen, __u16 attr)
+{
+	int size;
+
+	if (attr & LUDA_TYPE) {
+		const unsigned align = sizeof(struct luda_type) - 1;
+		size = (sizeof(struct lu_dirent) + namelen + align) & ~align;
+		size += sizeof(struct luda_type);
+	} else
+		size = sizeof(struct lu_dirent) + namelen;
+
+	return (size + 7) & ~7;
+}
+
+static inline int lu_dirent_size(struct lu_dirent *ent)
+{
+	if (le16_to_cpu(ent->lde_reclen) == 0) {
+		return lu_dirent_calc_size(le16_to_cpu(ent->lde_namelen),
+					   le32_to_cpu(ent->lde_attrs));
+	}
+	return le16_to_cpu(ent->lde_reclen);
+}
+
+#define MDS_DIR_END_OFF 0xfffffffffffffffeULL
+
+/**
+ * MDS_READPAGE page size
+ *
+ * This is the directory page size packed in MDS_READPAGE RPC.
+ * It's different than PAGE_CACHE_SIZE because the client needs to
+ * access the struct lu_dirpage header packed at the beginning of
+ * the "page" and without this there isn't any way to know find the
+ * lu_dirpage header is if client and server PAGE_CACHE_SIZE differ.
+ */
+#define LU_PAGE_SHIFT 12
+#define LU_PAGE_SIZE  (1UL << LU_PAGE_SHIFT)
+#define LU_PAGE_MASK  (~(LU_PAGE_SIZE - 1))
+
+#define LU_PAGE_COUNT (1 << (PAGE_CACHE_SHIFT - LU_PAGE_SHIFT))
+
+/** @} lu_dir */
+
+struct lustre_handle {
+	__u64 cookie;
+};
+#define DEAD_HANDLE_MAGIC 0xdeadbeefcafebabeULL
+
+static inline int lustre_handle_is_used(struct lustre_handle *lh)
+{
+	return lh->cookie != 0ull;
+}
+
+static inline int lustre_handle_equal(const struct lustre_handle *lh1,
+				      const struct lustre_handle *lh2)
+{
+	return lh1->cookie == lh2->cookie;
+}
+
+static inline void lustre_handle_copy(struct lustre_handle *tgt,
+				      struct lustre_handle *src)
+{
+	tgt->cookie = src->cookie;
+}
+
+/* flags for lm_flags */
+#define MSGHDR_AT_SUPPORT	       0x1
+#define MSGHDR_CKSUM_INCOMPAT18	 0x2
+
+#define lustre_msg lustre_msg_v2
+/* we depend on this structure to be 8-byte aligned */
+/* this type is only endian-adjusted in lustre_unpack_msg() */
+struct lustre_msg_v2 {
+	__u32 lm_bufcount;
+	__u32 lm_secflvr;
+	__u32 lm_magic;
+	__u32 lm_repsize;
+	__u32 lm_cksum;
+	__u32 lm_flags;
+	__u32 lm_padding_2;
+	__u32 lm_padding_3;
+	__u32 lm_buflens[0];
+};
+
+/* without gss, ptlrpc_body is put at the first buffer. */
+#define PTLRPC_NUM_VERSIONS     4
+#define JOBSTATS_JOBID_SIZE     32  /* 32 bytes string */
+struct ptlrpc_body_v3 {
+	struct lustre_handle pb_handle;
+	__u32 pb_type;
+	__u32 pb_version;
+	__u32 pb_opc;
+	__u32 pb_status;
+	__u64 pb_last_xid;
+	__u64 pb_last_seen;
+	__u64 pb_last_committed;
+	__u64 pb_transno;
+	__u32 pb_flags;
+	__u32 pb_op_flags;
+	__u32 pb_conn_cnt;
+	__u32 pb_timeout;  /* for req, the deadline, for rep, the service est */
+	__u32 pb_service_time; /* for rep, actual service time */
+	__u32 pb_limit;
+	__u64 pb_slv;
+	/* VBR: pre-versions */
+	__u64 pb_pre_versions[PTLRPC_NUM_VERSIONS];
+	/* padding for future needs */
+	__u64 pb_padding[4];
+	char  pb_jobid[JOBSTATS_JOBID_SIZE];
+};
+#define ptlrpc_body     ptlrpc_body_v3
+
+struct ptlrpc_body_v2 {
+	struct lustre_handle pb_handle;
+	__u32 pb_type;
+	__u32 pb_version;
+	__u32 pb_opc;
+	__u32 pb_status;
+	__u64 pb_last_xid;
+	__u64 pb_last_seen;
+	__u64 pb_last_committed;
+	__u64 pb_transno;
+	__u32 pb_flags;
+	__u32 pb_op_flags;
+	__u32 pb_conn_cnt;
+	__u32 pb_timeout;  /* for req, the deadline, for rep, the service est */
+	__u32 pb_service_time; /* for rep, actual service time, also used for
+				  net_latency of req */
+	__u32 pb_limit;
+	__u64 pb_slv;
+	/* VBR: pre-versions */
+	__u64 pb_pre_versions[PTLRPC_NUM_VERSIONS];
+	/* padding for future needs */
+	__u64 pb_padding[4];
+};
+
+extern void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb);
+
+/* message body offset for lustre_msg_v2 */
+/* ptlrpc body offset in all request/reply messages */
+#define MSG_PTLRPC_BODY_OFF	     0
+
+/* normal request/reply message record offset */
+#define REQ_REC_OFF		     1
+#define REPLY_REC_OFF		   1
+
+/* ldlm request message body offset */
+#define DLM_LOCKREQ_OFF		 1 /* lockreq offset */
+#define DLM_REQ_REC_OFF		 2 /* normal dlm request record offset */
+
+/* ldlm intent lock message body offset */
+#define DLM_INTENT_IT_OFF	       2 /* intent lock it offset */
+#define DLM_INTENT_REC_OFF	      3 /* intent lock record offset */
+
+/* ldlm reply message body offset */
+#define DLM_LOCKREPLY_OFF	       1 /* lockrep offset */
+#define DLM_REPLY_REC_OFF	       2 /* reply record offset */
+
+/** only use in req->rq_{req,rep}_swab_mask */
+#define MSG_PTLRPC_HEADER_OFF	   31
+
+/* Flags that are operation-specific go in the top 16 bits. */
+#define MSG_OP_FLAG_MASK   0xffff0000
+#define MSG_OP_FLAG_SHIFT  16
+
+/* Flags that apply to all requests are in the bottom 16 bits */
+#define MSG_GEN_FLAG_MASK     0x0000ffff
+#define MSG_LAST_REPLAY	   0x0001
+#define MSG_RESENT		0x0002
+#define MSG_REPLAY		0x0004
+/* #define MSG_AT_SUPPORT	 0x0008
+ * This was used in early prototypes of adaptive timeouts, and while there
+ * shouldn't be any users of that code there also isn't a need for using this
+ * bits. Defer usage until at least 1.10 to avoid potential conflict. */
+#define MSG_DELAY_REPLAY	  0x0010
+#define MSG_VERSION_REPLAY	0x0020
+#define MSG_REQ_REPLAY_DONE       0x0040
+#define MSG_LOCK_REPLAY_DONE      0x0080
+
+/*
+ * Flags for all connect opcodes (MDS_CONNECT, OST_CONNECT)
+ */
+
+#define MSG_CONNECT_RECOVERING  0x00000001
+#define MSG_CONNECT_RECONNECT   0x00000002
+#define MSG_CONNECT_REPLAYABLE  0x00000004
+//#define MSG_CONNECT_PEER	0x8
+#define MSG_CONNECT_LIBCLIENT   0x00000010
+#define MSG_CONNECT_INITIAL     0x00000020
+#define MSG_CONNECT_ASYNC       0x00000040
+#define MSG_CONNECT_NEXT_VER    0x00000080 /* use next version of lustre_msg */
+#define MSG_CONNECT_TRANSNO     0x00000100 /* report transno */
+
+/* Connect flags */
+#define OBD_CONNECT_RDONLY		0x1ULL /*client has read-only access*/
+#define OBD_CONNECT_INDEX		 0x2ULL /*connect specific LOV idx */
+#define OBD_CONNECT_MDS		   0x4ULL /*connect from MDT to OST */
+#define OBD_CONNECT_GRANT		 0x8ULL /*OSC gets grant at connect */
+#define OBD_CONNECT_SRVLOCK	      0x10ULL /*server takes locks for cli */
+#define OBD_CONNECT_VERSION	      0x20ULL /*Lustre versions in ocd */
+#define OBD_CONNECT_REQPORTAL	    0x40ULL /*Separate non-IO req portal */
+#define OBD_CONNECT_ACL		  0x80ULL /*access control lists */
+#define OBD_CONNECT_XATTR	       0x100ULL /*client use extended attr */
+#define OBD_CONNECT_CROW		0x200ULL /*MDS+OST create obj on write*/
+#define OBD_CONNECT_TRUNCLOCK	   0x400ULL /*locks on server for punch */
+#define OBD_CONNECT_TRANSNO	     0x800ULL /*replay sends init transno */
+#define OBD_CONNECT_IBITS	      0x1000ULL /*support for inodebits locks*/
+#define OBD_CONNECT_JOIN	       0x2000ULL /*files can be concatenated.
+						  *We do not support JOIN FILE
+						  *anymore, reserve this flags
+						  *just for preventing such bit
+						  *to be reused.*/
+#define OBD_CONNECT_ATTRFID	    0x4000ULL /*Server can GetAttr By Fid*/
+#define OBD_CONNECT_NODEVOH	    0x8000ULL /*No open hndl on specl nodes*/
+#define OBD_CONNECT_RMT_CLIENT	0x10000ULL /*Remote client */
+#define OBD_CONNECT_RMT_CLIENT_FORCE  0x20000ULL /*Remote client by force */
+#define OBD_CONNECT_BRW_SIZE	  0x40000ULL /*Max bytes per rpc */
+#define OBD_CONNECT_QUOTA64	   0x80000ULL /*Not used since 2.4 */
+#define OBD_CONNECT_MDS_CAPA	 0x100000ULL /*MDS capability */
+#define OBD_CONNECT_OSS_CAPA	 0x200000ULL /*OSS capability */
+#define OBD_CONNECT_CANCELSET	0x400000ULL /*Early batched cancels. */
+#define OBD_CONNECT_SOM	      0x800000ULL /*Size on MDS */
+#define OBD_CONNECT_AT	      0x1000000ULL /*client uses AT */
+#define OBD_CONNECT_LRU_RESIZE      0x2000000ULL /*LRU resize feature. */
+#define OBD_CONNECT_MDS_MDS	 0x4000000ULL /*MDS-MDS connection */
+#define OBD_CONNECT_REAL	    0x8000000ULL /*real connection */
+#define OBD_CONNECT_CHANGE_QS      0x10000000ULL /*Not used since 2.4 */
+#define OBD_CONNECT_CKSUM	  0x20000000ULL /*support several cksum algos*/
+#define OBD_CONNECT_FID	    0x40000000ULL /*FID is supported by server */
+#define OBD_CONNECT_VBR	    0x80000000ULL /*version based recovery */
+#define OBD_CONNECT_LOV_V3	0x100000000ULL /*client supports LOV v3 EA */
+#define OBD_CONNECT_GRANT_SHRINK  0x200000000ULL /* support grant shrink */
+#define OBD_CONNECT_SKIP_ORPHAN   0x400000000ULL /* don't reuse orphan objids */
+#define OBD_CONNECT_MAX_EASIZE    0x800000000ULL /* preserved for large EA */
+#define OBD_CONNECT_FULL20       0x1000000000ULL /* it is 2.0 client */
+#define OBD_CONNECT_LAYOUTLOCK   0x2000000000ULL /* client uses layout lock */
+#define OBD_CONNECT_64BITHASH    0x4000000000ULL /* client supports 64-bits
+						  * directory hash */
+#define OBD_CONNECT_MAXBYTES     0x8000000000ULL /* max stripe size */
+#define OBD_CONNECT_IMP_RECOV   0x10000000000ULL /* imp recovery support */
+#define OBD_CONNECT_JOBSTATS    0x20000000000ULL /* jobid in ptlrpc_body */
+#define OBD_CONNECT_UMASK       0x40000000000ULL /* create uses client umask */
+#define OBD_CONNECT_EINPROGRESS 0x80000000000ULL /* client handles -EINPROGRESS
+						  * RPC error properly */
+#define OBD_CONNECT_GRANT_PARAM 0x100000000000ULL/* extra grant params used for
+						  * finer space reservation */
+#define OBD_CONNECT_FLOCK_OWNER 0x200000000000ULL /* for the fixed 1.8
+						   * policy and 2.x server */
+#define OBD_CONNECT_LVB_TYPE	0x400000000000ULL /* variable type of LVB */
+#define OBD_CONNECT_NANOSEC_TIME 0x800000000000ULL /* nanosecond timestamps */
+#define OBD_CONNECT_LIGHTWEIGHT 0x1000000000000ULL/* lightweight connection */
+#define OBD_CONNECT_SHORTIO     0x2000000000000ULL/* short io */
+#define OBD_CONNECT_PINGLESS	0x4000000000000ULL/* pings not required */
+/* XXX README XXX:
+ * Please DO NOT add flag values here before first ensuring that this same
+ * flag value is not in use on some other branch.  Please clear any such
+ * changes with senior engineers before starting to use a new flag.  Then,
+ * submit a small patch against EVERY branch that ONLY adds the new flag,
+ * updates obd_connect_names[] for lprocfs_rd_connect_flags(), adds the
+ * flag to check_obd_connect_data(), and updates wiretests accordingly, so it
+ * can be approved and landed easily to reserve the flag for future use. */
+
+/* The MNE_SWAB flag is overloading the MDS_MDS bit only for the MGS
+ * connection.  It is a temporary bug fix for Imperative Recovery interop
+ * between 2.2 and 2.3 x86/ppc nodes, and can be removed when interop for
+ * 2.2 clients/servers is no longer needed.  LU-1252/LU-1644. */
+#define OBD_CONNECT_MNE_SWAB		 OBD_CONNECT_MDS_MDS
+
+#define OCD_HAS_FLAG(ocd, flg)  \
+	(!!((ocd)->ocd_connect_flags & OBD_CONNECT_##flg))
+
+
+#define LRU_RESIZE_CONNECT_FLAG OBD_CONNECT_LRU_RESIZE
+
+#define MDT_CONNECT_SUPPORTED  (OBD_CONNECT_RDONLY | OBD_CONNECT_VERSION | \
+				OBD_CONNECT_ACL | OBD_CONNECT_XATTR | \
+				OBD_CONNECT_IBITS | \
+				OBD_CONNECT_NODEVOH | OBD_CONNECT_ATTRFID | \
+				OBD_CONNECT_CANCELSET | OBD_CONNECT_AT | \
+				OBD_CONNECT_RMT_CLIENT | \
+				OBD_CONNECT_RMT_CLIENT_FORCE | \
+				OBD_CONNECT_BRW_SIZE | OBD_CONNECT_MDS_CAPA | \
+				OBD_CONNECT_OSS_CAPA | OBD_CONNECT_MDS_MDS | \
+				OBD_CONNECT_FID | LRU_RESIZE_CONNECT_FLAG | \
+				OBD_CONNECT_VBR | OBD_CONNECT_LOV_V3 | \
+				OBD_CONNECT_SOM | OBD_CONNECT_FULL20 | \
+				OBD_CONNECT_64BITHASH | OBD_CONNECT_JOBSTATS | \
+				OBD_CONNECT_EINPROGRESS | \
+				OBD_CONNECT_LIGHTWEIGHT | OBD_CONNECT_UMASK | \
+				OBD_CONNECT_LVB_TYPE | OBD_CONNECT_LAYOUTLOCK |\
+				OBD_CONNECT_PINGLESS)
+#define OST_CONNECT_SUPPORTED  (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \
+				OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \
+				OBD_CONNECT_TRUNCLOCK | OBD_CONNECT_INDEX | \
+				OBD_CONNECT_BRW_SIZE | OBD_CONNECT_OSS_CAPA | \
+				OBD_CONNECT_CANCELSET | OBD_CONNECT_AT | \
+				LRU_RESIZE_CONNECT_FLAG | OBD_CONNECT_CKSUM | \
+				OBD_CONNECT_RMT_CLIENT | \
+				OBD_CONNECT_RMT_CLIENT_FORCE | OBD_CONNECT_VBR | \
+				OBD_CONNECT_MDS | OBD_CONNECT_SKIP_ORPHAN | \
+				OBD_CONNECT_GRANT_SHRINK | OBD_CONNECT_FULL20 | \
+				OBD_CONNECT_64BITHASH | OBD_CONNECT_MAXBYTES | \
+				OBD_CONNECT_MAX_EASIZE | \
+				OBD_CONNECT_EINPROGRESS | \
+				OBD_CONNECT_JOBSTATS | \
+				OBD_CONNECT_LIGHTWEIGHT | OBD_CONNECT_LVB_TYPE|\
+				OBD_CONNECT_LAYOUTLOCK | OBD_CONNECT_FID | \
+				OBD_CONNECT_PINGLESS)
+#define ECHO_CONNECT_SUPPORTED (0)
+#define MGS_CONNECT_SUPPORTED  (OBD_CONNECT_VERSION | OBD_CONNECT_AT | \
+				OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV | \
+				OBD_CONNECT_MNE_SWAB | OBD_CONNECT_PINGLESS)
+
+/* Features required for this version of the client to work with server */
+#define CLIENT_CONNECT_MDT_REQD (OBD_CONNECT_IBITS | OBD_CONNECT_FID | \
+				 OBD_CONNECT_FULL20)
+
+#define OBD_OCD_VERSION(major,minor,patch,fix) (((major)<<24) + ((minor)<<16) +\
+						((patch)<<8) + (fix))
+#define OBD_OCD_VERSION_MAJOR(version) ((int)((version)>>24)&255)
+#define OBD_OCD_VERSION_MINOR(version) ((int)((version)>>16)&255)
+#define OBD_OCD_VERSION_PATCH(version) ((int)((version)>>8)&255)
+#define OBD_OCD_VERSION_FIX(version)   ((int)(version)&255)
+
+/* This structure is used for both request and reply.
+ *
+ * If we eventually have separate connect data for different types, which we
+ * almost certainly will, then perhaps we stick a union in here. */
+struct obd_connect_data_v1 {
+	__u64 ocd_connect_flags; /* OBD_CONNECT_* per above */
+	__u32 ocd_version;	 /* lustre release version number */
+	__u32 ocd_grant;	 /* initial cache grant amount (bytes) */
+	__u32 ocd_index;	 /* LOV index to connect to */
+	__u32 ocd_brw_size;	 /* Maximum BRW size in bytes, must be 2^n */
+	__u64 ocd_ibits_known;   /* inode bits this client understands */
+	__u8  ocd_blocksize;     /* log2 of the backend filesystem blocksize */
+	__u8  ocd_inodespace;    /* log2 of the per-inode space consumption */
+	__u16 ocd_grant_extent;  /* per-extent grant overhead, in 1K blocks */
+	__u32 ocd_unused;	/* also fix lustre_swab_connect */
+	__u64 ocd_transno;       /* first transno from client to be replayed */
+	__u32 ocd_group;	 /* MDS group on OST */
+	__u32 ocd_cksum_types;   /* supported checksum algorithms */
+	__u32 ocd_max_easize;    /* How big LOV EA can be on MDS */
+	__u32 ocd_instance;      /* also fix lustre_swab_connect */
+	__u64 ocd_maxbytes;      /* Maximum stripe size in bytes */
+};
+
+struct obd_connect_data {
+	__u64 ocd_connect_flags; /* OBD_CONNECT_* per above */
+	__u32 ocd_version;	 /* lustre release version number */
+	__u32 ocd_grant;	 /* initial cache grant amount (bytes) */
+	__u32 ocd_index;	 /* LOV index to connect to */
+	__u32 ocd_brw_size;	 /* Maximum BRW size in bytes */
+	__u64 ocd_ibits_known;   /* inode bits this client understands */
+	__u8  ocd_blocksize;     /* log2 of the backend filesystem blocksize */
+	__u8  ocd_inodespace;    /* log2 of the per-inode space consumption */
+	__u16 ocd_grant_extent;  /* per-extent grant overhead, in 1K blocks */
+	__u32 ocd_unused;	/* also fix lustre_swab_connect */
+	__u64 ocd_transno;       /* first transno from client to be replayed */
+	__u32 ocd_group;	 /* MDS group on OST */
+	__u32 ocd_cksum_types;   /* supported checksum algorithms */
+	__u32 ocd_max_easize;    /* How big LOV EA can be on MDS */
+	__u32 ocd_instance;      /* instance # of this target */
+	__u64 ocd_maxbytes;      /* Maximum stripe size in bytes */
+	/* Fields after ocd_maxbytes are only accessible by the receiver
+	 * if the corresponding flag in ocd_connect_flags is set. Accessing
+	 * any field after ocd_maxbytes on the receiver without a valid flag
+	 * may result in out-of-bound memory access and kernel oops. */
+	__u64 padding1;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 padding2;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 padding3;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 padding4;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 padding5;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 padding6;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 padding7;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 padding8;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 padding9;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 paddingA;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 paddingB;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 paddingC;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 paddingD;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 paddingE;	  /* added 2.1.0. also fix lustre_swab_connect */
+	__u64 paddingF;	  /* added 2.1.0. also fix lustre_swab_connect */
+};
+/* XXX README XXX:
+ * Please DO NOT use any fields here before first ensuring that this same
+ * field is not in use on some other branch.  Please clear any such changes
+ * with senior engineers before starting to use a new field.  Then, submit
+ * a small patch against EVERY branch that ONLY adds the new field along with
+ * the matching OBD_CONNECT flag, so that can be approved and landed easily to
+ * reserve the flag for future use. */
+
+
+extern void lustre_swab_connect(struct obd_connect_data *ocd);
+
+/*
+ * Supported checksum algorithms. Up to 32 checksum types are supported.
+ * (32-bit mask stored in obd_connect_data::ocd_cksum_types)
+ * Please update DECLARE_CKSUM_NAME/OBD_CKSUM_ALL in obd.h when adding a new
+ * algorithm and also the OBD_FL_CKSUM* flags.
+ */
+typedef enum {
+	OBD_CKSUM_CRC32 = 0x00000001,
+	OBD_CKSUM_ADLER = 0x00000002,
+	OBD_CKSUM_CRC32C= 0x00000004,
+} cksum_type_t;
+
+/*
+ *   OST requests: OBDO & OBD request records
+ */
+
+/* opcodes */
+typedef enum {
+	OST_REPLY      =  0,       /* reply ? */
+	OST_GETATTR    =  1,
+	OST_SETATTR    =  2,
+	OST_READ       =  3,
+	OST_WRITE      =  4,
+	OST_CREATE     =  5,
+	OST_DESTROY    =  6,
+	OST_GET_INFO   =  7,
+	OST_CONNECT    =  8,
+	OST_DISCONNECT =  9,
+	OST_PUNCH      = 10,
+	OST_OPEN       = 11,
+	OST_CLOSE      = 12,
+	OST_STATFS     = 13,
+	OST_SYNC       = 16,
+	OST_SET_INFO   = 17,
+	OST_QUOTACHECK = 18,
+	OST_QUOTACTL   = 19,
+	OST_QUOTA_ADJUST_QUNIT = 20, /* not used since 2.4 */
+	OST_LAST_OPC
+} ost_cmd_t;
+#define OST_FIRST_OPC  OST_REPLY
+
+enum obdo_flags {
+	OBD_FL_INLINEDATA   = 0x00000001,
+	OBD_FL_OBDMDEXISTS  = 0x00000002,
+	OBD_FL_DELORPHAN    = 0x00000004, /* if set in o_flags delete orphans */
+	OBD_FL_NORPC	= 0x00000008, /* set in o_flags do in OSC not OST */
+	OBD_FL_IDONLY       = 0x00000010, /* set in o_flags only adjust obj id*/
+	OBD_FL_RECREATE_OBJS= 0x00000020, /* recreate missing obj */
+	OBD_FL_DEBUG_CHECK  = 0x00000040, /* echo client/server debug check */
+	OBD_FL_NO_USRQUOTA  = 0x00000100, /* the object's owner is over quota */
+	OBD_FL_NO_GRPQUOTA  = 0x00000200, /* the object's group is over quota */
+	OBD_FL_CREATE_CROW  = 0x00000400, /* object should be create on write */
+	OBD_FL_SRVLOCK      = 0x00000800, /* delegate DLM locking to server */
+	OBD_FL_CKSUM_CRC32  = 0x00001000, /* CRC32 checksum type */
+	OBD_FL_CKSUM_ADLER  = 0x00002000, /* ADLER checksum type */
+	OBD_FL_CKSUM_CRC32C = 0x00004000, /* CRC32C checksum type */
+	OBD_FL_CKSUM_RSVD2  = 0x00008000, /* for future cksum types */
+	OBD_FL_CKSUM_RSVD3  = 0x00010000, /* for future cksum types */
+	OBD_FL_SHRINK_GRANT = 0x00020000, /* object shrink the grant */
+	OBD_FL_MMAP	 = 0x00040000, /* object is mmapped on the client.
+					   * XXX: obsoleted - reserved for old
+					   * clients prior than 2.2 */
+	OBD_FL_RECOV_RESEND = 0x00080000, /* recoverable resent */
+	OBD_FL_NOSPC_BLK    = 0x00100000, /* no more block space on OST */
+
+	/* Note that while these checksum values are currently separate bits,
+	 * in 2.x we can actually allow all values from 1-31 if we wanted. */
+	OBD_FL_CKSUM_ALL    = OBD_FL_CKSUM_CRC32 | OBD_FL_CKSUM_ADLER |
+			      OBD_FL_CKSUM_CRC32C,
+
+	/* mask for local-only flag, which won't be sent over network */
+	OBD_FL_LOCAL_MASK   = 0xF0000000,
+};
+
+#define LOV_MAGIC_V1      0x0BD10BD0
+#define LOV_MAGIC	 LOV_MAGIC_V1
+#define LOV_MAGIC_JOIN_V1 0x0BD20BD0
+#define LOV_MAGIC_V3      0x0BD30BD0
+
+/*
+ * magic for fully defined striping
+ * the idea is that we should have different magics for striping "hints"
+ * (struct lov_user_md_v[13]) and defined ready-to-use striping (struct
+ * lov_mds_md_v[13]). at the moment the magics are used in wire protocol,
+ * we can't just change it w/o long way preparation, but we still need a
+ * mechanism to allow LOD to differentiate hint versus ready striping.
+ * so, at the moment we do a trick: MDT knows what to expect from request
+ * depending on the case (replay uses ready striping, non-replay req uses
+ * hints), so MDT replaces magic with appropriate one and now LOD can
+ * easily understand what's inside -bzzz
+ */
+#define LOV_MAGIC_V1_DEF  0x0CD10BD0
+#define LOV_MAGIC_V3_DEF  0x0CD30BD0
+
+#define LOV_PATTERN_RAID0 0x001   /* stripes are used round-robin */
+#define LOV_PATTERN_RAID1 0x002   /* stripes are mirrors of each other */
+#define LOV_PATTERN_FIRST 0x100   /* first stripe is not in round-robin */
+#define LOV_PATTERN_CMOBD 0x200
+
+#define lov_ost_data lov_ost_data_v1
+struct lov_ost_data_v1 {	  /* per-stripe data structure (little-endian)*/
+	struct ost_id l_ost_oi;	  /* OST object ID */
+	__u32 l_ost_gen;	  /* generation of this l_ost_idx */
+	__u32 l_ost_idx;	  /* OST index in LOV (lov_tgt_desc->tgts) */
+};
+
+#define lov_mds_md lov_mds_md_v1
+struct lov_mds_md_v1 {	    /* LOV EA mds/wire data (little-endian) */
+	__u32 lmm_magic;	  /* magic number = LOV_MAGIC_V1 */
+	__u32 lmm_pattern;	/* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
+	struct ost_id	lmm_oi;	  /* LOV object ID */
+	__u32 lmm_stripe_size;    /* size of stripe in bytes */
+	/* lmm_stripe_count used to be __u32 */
+	__u16 lmm_stripe_count;   /* num stripes in use for this object */
+	__u16 lmm_layout_gen;     /* layout generation number */
+	struct lov_ost_data_v1 lmm_objects[0]; /* per-stripe data */
+};
+
+/**
+ * Sigh, because pre-2.4 uses
+ * struct lov_mds_md_v1 {
+ *	........
+ *	__u64 lmm_object_id;
+ *	__u64 lmm_object_seq;
+ *      ......
+ *      }
+ * to identify the LOV(MDT) object, and lmm_object_seq will
+ * be normal_fid, which make it hard to combine these conversion
+ * to ostid_to FID. so we will do lmm_oi/fid conversion separately
+ *
+ * We can tell the lmm_oi by this way,
+ * 1.8: lmm_object_id = {inode}, lmm_object_gr = 0
+ * 2.1: lmm_object_id = {oid < 128k}, lmm_object_seq = FID_SEQ_NORMAL
+ * 2.4: lmm_oi.f_seq = FID_SEQ_NORMAL, lmm_oi.f_oid = {oid < 128k},
+ *      lmm_oi.f_ver = 0
+ *
+ * But currently lmm_oi/lsm_oi does not have any "real" usages,
+ * except for printing some information, and the user can always
+ * get the real FID from LMA, besides this multiple case check might
+ * make swab more complicate. So we will keep using id/seq for lmm_oi.
+ */
+
+static inline void fid_to_lmm_oi(const struct lu_fid *fid,
+				 struct ost_id *oi)
+{
+	oi->oi.oi_id = fid_oid(fid);
+	oi->oi.oi_seq = fid_seq(fid);
+}
+
+static inline void lmm_oi_set_seq(struct ost_id *oi, __u64 seq)
+{
+	oi->oi.oi_seq = seq;
+}
+
+static inline __u64 lmm_oi_id(struct ost_id *oi)
+{
+	return oi->oi.oi_id;
+}
+
+static inline __u64 lmm_oi_seq(struct ost_id *oi)
+{
+	return oi->oi.oi_seq;
+}
+
+static inline void lmm_oi_le_to_cpu(struct ost_id *dst_oi,
+				    struct ost_id *src_oi)
+{
+	dst_oi->oi.oi_id = le64_to_cpu(src_oi->oi.oi_id);
+	dst_oi->oi.oi_seq = le64_to_cpu(src_oi->oi.oi_seq);
+}
+
+static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
+				    struct ost_id *src_oi)
+{
+	dst_oi->oi.oi_id = cpu_to_le64(src_oi->oi.oi_id);
+	dst_oi->oi.oi_seq = cpu_to_le64(src_oi->oi.oi_seq);
+}
+
+/* extern void lustre_swab_lov_mds_md(struct lov_mds_md *llm); */
+
+#define MAX_MD_SIZE (sizeof(struct lov_mds_md) + 4 * sizeof(struct lov_ost_data))
+#define MIN_MD_SIZE (sizeof(struct lov_mds_md) + 1 * sizeof(struct lov_ost_data))
+
+#define XATTR_NAME_ACL_ACCESS   "system.posix_acl_access"
+#define XATTR_NAME_ACL_DEFAULT  "system.posix_acl_default"
+#define XATTR_USER_PREFIX       "user."
+#define XATTR_TRUSTED_PREFIX    "trusted."
+#define XATTR_SECURITY_PREFIX   "security."
+#define XATTR_LUSTRE_PREFIX     "lustre."
+
+#define XATTR_NAME_LOV	  "trusted.lov"
+#define XATTR_NAME_LMA	  "trusted.lma"
+#define XATTR_NAME_LMV	  "trusted.lmv"
+#define XATTR_NAME_LINK	 "trusted.link"
+#define XATTR_NAME_FID	  "trusted.fid"
+#define XATTR_NAME_VERSION      "trusted.version"
+#define XATTR_NAME_SOM		"trusted.som"
+#define XATTR_NAME_HSM		"trusted.hsm"
+#define XATTR_NAME_LFSCK_NAMESPACE "trusted.lfsck_namespace"
+
+struct lov_mds_md_v3 {	    /* LOV EA mds/wire data (little-endian) */
+	__u32 lmm_magic;	  /* magic number = LOV_MAGIC_V3 */
+	__u32 lmm_pattern;	/* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
+	struct ost_id	lmm_oi;	  /* LOV object ID */
+	__u32 lmm_stripe_size;    /* size of stripe in bytes */
+	/* lmm_stripe_count used to be __u32 */
+	__u16 lmm_stripe_count;   /* num stripes in use for this object */
+	__u16 lmm_layout_gen;     /* layout generation number */
+	char  lmm_pool_name[LOV_MAXPOOLNAME]; /* must be 32bit aligned */
+	struct lov_ost_data_v1 lmm_objects[0]; /* per-stripe data */
+};
+
+#define OBD_MD_FLID	(0x00000001ULL) /* object ID */
+#define OBD_MD_FLATIME     (0x00000002ULL) /* access time */
+#define OBD_MD_FLMTIME     (0x00000004ULL) /* data modification time */
+#define OBD_MD_FLCTIME     (0x00000008ULL) /* change time */
+#define OBD_MD_FLSIZE      (0x00000010ULL) /* size */
+#define OBD_MD_FLBLOCKS    (0x00000020ULL) /* allocated blocks count */
+#define OBD_MD_FLBLKSZ     (0x00000040ULL) /* block size */
+#define OBD_MD_FLMODE      (0x00000080ULL) /* access bits (mode & ~S_IFMT) */
+#define OBD_MD_FLTYPE      (0x00000100ULL) /* object type (mode & S_IFMT) */
+#define OBD_MD_FLUID       (0x00000200ULL) /* user ID */
+#define OBD_MD_FLGID       (0x00000400ULL) /* group ID */
+#define OBD_MD_FLFLAGS     (0x00000800ULL) /* flags word */
+#define OBD_MD_FLNLINK     (0x00002000ULL) /* link count */
+#define OBD_MD_FLGENER     (0x00004000ULL) /* generation number */
+/*#define OBD_MD_FLINLINE    (0x00008000ULL)  inline data. used until 1.6.5 */
+#define OBD_MD_FLRDEV      (0x00010000ULL) /* device number */
+#define OBD_MD_FLEASIZE    (0x00020000ULL) /* extended attribute data */
+#define OBD_MD_LINKNAME    (0x00040000ULL) /* symbolic link target */
+#define OBD_MD_FLHANDLE    (0x00080000ULL) /* file/lock handle */
+#define OBD_MD_FLCKSUM     (0x00100000ULL) /* bulk data checksum */
+#define OBD_MD_FLQOS       (0x00200000ULL) /* quality of service stats */
+/*#define OBD_MD_FLOSCOPQ    (0x00400000ULL) osc opaque data, never used */
+#define OBD_MD_FLCOOKIE    (0x00800000ULL) /* log cancellation cookie */
+#define OBD_MD_FLGROUP     (0x01000000ULL) /* group */
+#define OBD_MD_FLFID       (0x02000000ULL) /* ->ost write inline fid */
+#define OBD_MD_FLEPOCH     (0x04000000ULL) /* ->ost write with ioepoch */
+					   /* ->mds if epoch opens or closes */
+#define OBD_MD_FLGRANT     (0x08000000ULL) /* ost preallocation space grant */
+#define OBD_MD_FLDIREA     (0x10000000ULL) /* dir's extended attribute data */
+#define OBD_MD_FLUSRQUOTA  (0x20000000ULL) /* over quota flags sent from ost */
+#define OBD_MD_FLGRPQUOTA  (0x40000000ULL) /* over quota flags sent from ost */
+#define OBD_MD_FLMODEASIZE (0x80000000ULL) /* EA size will be changed */
+
+#define OBD_MD_MDS	 (0x0000000100000000ULL) /* where an inode lives on */
+#define OBD_MD_REINT       (0x0000000200000000ULL) /* reintegrate oa */
+#define OBD_MD_MEA	 (0x0000000400000000ULL) /* CMD split EA  */
+
+/* OBD_MD_MDTIDX is used to get MDT index, but it is never been used overwire,
+ * and it is already obsolete since 2.3 */
+/* #define OBD_MD_MDTIDX      (0x0000000800000000ULL) */
+
+#define OBD_MD_FLXATTR       (0x0000001000000000ULL) /* xattr */
+#define OBD_MD_FLXATTRLS     (0x0000002000000000ULL) /* xattr list */
+#define OBD_MD_FLXATTRRM     (0x0000004000000000ULL) /* xattr remove */
+#define OBD_MD_FLACL	 (0x0000008000000000ULL) /* ACL */
+#define OBD_MD_FLRMTPERM     (0x0000010000000000ULL) /* remote permission */
+#define OBD_MD_FLMDSCAPA     (0x0000020000000000ULL) /* MDS capability */
+#define OBD_MD_FLOSSCAPA     (0x0000040000000000ULL) /* OSS capability */
+#define OBD_MD_FLCKSPLIT     (0x0000080000000000ULL) /* Check split on server */
+#define OBD_MD_FLCROSSREF    (0x0000100000000000ULL) /* Cross-ref case */
+#define OBD_MD_FLGETATTRLOCK (0x0000200000000000ULL) /* Get IOEpoch attributes
+						      * under lock */
+#define OBD_MD_FLOBJCOUNT    (0x0000400000000000ULL) /* for multiple destroy */
+
+#define OBD_MD_FLRMTLSETFACL (0x0001000000000000ULL) /* lfs lsetfacl case */
+#define OBD_MD_FLRMTLGETFACL (0x0002000000000000ULL) /* lfs lgetfacl case */
+#define OBD_MD_FLRMTRSETFACL (0x0004000000000000ULL) /* lfs rsetfacl case */
+#define OBD_MD_FLRMTRGETFACL (0x0008000000000000ULL) /* lfs rgetfacl case */
+
+#define OBD_MD_FLDATAVERSION (0x0010000000000000ULL) /* iversion sum */
+
+#define OBD_MD_FLGETATTR (OBD_MD_FLID    | OBD_MD_FLATIME | OBD_MD_FLMTIME | \
+			  OBD_MD_FLCTIME | OBD_MD_FLSIZE  | OBD_MD_FLBLKSZ | \
+			  OBD_MD_FLMODE  | OBD_MD_FLTYPE  | OBD_MD_FLUID   | \
+			  OBD_MD_FLGID   | OBD_MD_FLFLAGS | OBD_MD_FLNLINK | \
+			  OBD_MD_FLGENER | OBD_MD_FLRDEV  | OBD_MD_FLGROUP)
+
+/* don't forget obdo_fid which is way down at the bottom so it can
+ * come after the definition of llog_cookie */
+
+enum hss_valid {
+	HSS_SETMASK	= 0x01,
+	HSS_CLEARMASK	= 0x02,
+	HSS_ARCHIVE_ID	= 0x04,
+};
+
+struct hsm_state_set {
+	__u32	hss_valid;
+	__u32	hss_archive_id;
+	__u64	hss_setmask;
+	__u64	hss_clearmask;
+};
+
+extern void lustre_swab_hsm_user_state(struct hsm_user_state *hus);
+extern void lustre_swab_hsm_state_set(struct hsm_state_set *hss);
+
+extern void lustre_swab_obd_statfs (struct obd_statfs *os);
+
+/* ost_body.data values for OST_BRW */
+
+#define OBD_BRW_READ	    0x01
+#define OBD_BRW_WRITE	   0x02
+#define OBD_BRW_RWMASK	  (OBD_BRW_READ | OBD_BRW_WRITE)
+#define OBD_BRW_SYNC	    0x08 /* this page is a part of synchronous
+				      * transfer and is not accounted in
+				      * the grant. */
+#define OBD_BRW_CHECK	   0x10
+#define OBD_BRW_FROM_GRANT      0x20 /* the osc manages this under llite */
+#define OBD_BRW_GRANTED	 0x40 /* the ost manages this */
+#define OBD_BRW_NOCACHE	 0x80 /* this page is a part of non-cached IO */
+#define OBD_BRW_NOQUOTA	0x100
+#define OBD_BRW_SRVLOCK	0x200 /* Client holds no lock over this page */
+#define OBD_BRW_ASYNC	  0x400 /* Server may delay commit to disk */
+#define OBD_BRW_MEMALLOC       0x800 /* Client runs in the "kswapd" context */
+#define OBD_BRW_OVER_USRQUOTA 0x1000 /* Running out of user quota */
+#define OBD_BRW_OVER_GRPQUOTA 0x2000 /* Running out of group quota */
+
+#define OBD_OBJECT_EOF 0xffffffffffffffffULL
+
+#define OST_MIN_PRECREATE 32
+#define OST_MAX_PRECREATE 20000
+
+struct obd_ioobj {
+	struct ost_id	ioo_oid;	/* object ID, if multi-obj BRW */
+	__u32		ioo_max_brw;	/* low 16 bits were o_mode before 2.4,
+					 * now (PTLRPC_BULK_OPS_COUNT - 1) in
+					 * high 16 bits in 2.4 and later */
+	__u32		ioo_bufcnt;	/* number of niobufs for this object */
+};
+
+#define IOOBJ_MAX_BRW_BITS	16
+#define IOOBJ_TYPE_MASK		((1U << IOOBJ_MAX_BRW_BITS) - 1)
+#define ioobj_max_brw_get(ioo)	(((ioo)->ioo_max_brw >> IOOBJ_MAX_BRW_BITS) + 1)
+#define ioobj_max_brw_set(ioo, num)					\
+do { (ioo)->ioo_max_brw = ((num) - 1) << IOOBJ_MAX_BRW_BITS; } while (0)
+
+extern void lustre_swab_obd_ioobj (struct obd_ioobj *ioo);
+
+/* multiple of 8 bytes => can array */
+struct niobuf_remote {
+	__u64 offset;
+	__u32 len;
+	__u32 flags;
+};
+
+extern void lustre_swab_niobuf_remote (struct niobuf_remote *nbr);
+
+/* lock value block communicated between the filter and llite */
+
+/* OST_LVB_ERR_INIT is needed because the return code in rc is
+ * negative, i.e. because ((MASK + rc) & MASK) != MASK. */
+#define OST_LVB_ERR_INIT 0xffbadbad80000000ULL
+#define OST_LVB_ERR_MASK 0xffbadbad00000000ULL
+#define OST_LVB_IS_ERR(blocks)					  \
+	((blocks & OST_LVB_ERR_MASK) == OST_LVB_ERR_MASK)
+#define OST_LVB_SET_ERR(blocks, rc)				     \
+	do { blocks = OST_LVB_ERR_INIT + rc; } while (0)
+#define OST_LVB_GET_ERR(blocks)    (int)(blocks - OST_LVB_ERR_INIT)
+
+struct ost_lvb_v1 {
+	__u64		lvb_size;
+	obd_time	lvb_mtime;
+	obd_time	lvb_atime;
+	obd_time	lvb_ctime;
+	__u64		lvb_blocks;
+};
+
+extern void lustre_swab_ost_lvb_v1(struct ost_lvb_v1 *lvb);
+
+struct ost_lvb {
+	__u64		lvb_size;
+	obd_time	lvb_mtime;
+	obd_time	lvb_atime;
+	obd_time	lvb_ctime;
+	__u64		lvb_blocks;
+	__u32		lvb_mtime_ns;
+	__u32		lvb_atime_ns;
+	__u32		lvb_ctime_ns;
+	__u32		lvb_padding;
+};
+
+extern void lustre_swab_ost_lvb(struct ost_lvb *lvb);
+
+/*
+ *   lquota data structures
+ */
+
+#ifndef QUOTABLOCK_BITS
+#define QUOTABLOCK_BITS 10
+#endif
+
+#ifndef QUOTABLOCK_SIZE
+#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
+#endif
+
+#ifndef toqb
+#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
+#endif
+
+/* The lquota_id structure is an union of all the possible identifier types that
+ * can be used with quota, this includes:
+ * - 64-bit user ID
+ * - 64-bit group ID
+ * - a FID which can be used for per-directory quota in the future */
+union lquota_id {
+	struct lu_fid	qid_fid; /* FID for per-directory quota */
+	__u64		qid_uid; /* user identifier */
+	__u64		qid_gid; /* group identifier */
+};
+
+/* quotactl management */
+struct obd_quotactl {
+	__u32			qc_cmd;
+	__u32			qc_type; /* see Q_* flag below */
+	__u32			qc_id;
+	__u32			qc_stat;
+	struct obd_dqinfo	qc_dqinfo;
+	struct obd_dqblk	qc_dqblk;
+};
+
+extern void lustre_swab_obd_quotactl(struct obd_quotactl *q);
+
+#define Q_QUOTACHECK	0x800100 /* deprecated as of 2.4 */
+#define Q_INITQUOTA	0x800101 /* deprecated as of 2.4  */
+#define Q_GETOINFO	0x800102 /* get obd quota info */
+#define Q_GETOQUOTA	0x800103 /* get obd quotas */
+#define Q_FINVALIDATE	0x800104 /* deprecated as of 2.4 */
+
+#define Q_COPY(out, in, member) (out)->member = (in)->member
+
+#define QCTL_COPY(out, in)		\
+do {					\
+	Q_COPY(out, in, qc_cmd);	\
+	Q_COPY(out, in, qc_type);	\
+	Q_COPY(out, in, qc_id);		\
+	Q_COPY(out, in, qc_stat);	\
+	Q_COPY(out, in, qc_dqinfo);	\
+	Q_COPY(out, in, qc_dqblk);	\
+} while (0)
+
+/* Body of quota request used for quota acquire/release RPCs between quota
+ * master (aka QMT) and slaves (ak QSD). */
+struct quota_body {
+	struct lu_fid	qb_fid;     /* FID of global index packing the pool ID
+				      * and type (data or metadata) as well as
+				      * the quota type (user or group). */
+	union lquota_id	qb_id;      /* uid or gid or directory FID */
+	__u32		qb_flags;   /* see below */
+	__u32		qb_padding;
+	__u64		qb_count;   /* acquire/release count (kbytes/inodes) */
+	__u64		qb_usage;   /* current slave usage (kbytes/inodes) */
+	__u64		qb_slv_ver; /* slave index file version */
+	struct lustre_handle	qb_lockh;     /* per-ID lock handle */
+	struct lustre_handle	qb_glb_lockh; /* global lock handle */
+	__u64		qb_padding1[4];
+};
+
+/* When the quota_body is used in the reply of quota global intent
+ * lock (IT_QUOTA_CONN) reply, qb_fid contains slave index file FID. */
+#define qb_slv_fid	qb_fid
+/* qb_usage is the current qunit (in kbytes/inodes) when quota_body is used in
+ * quota reply */
+#define qb_qunit	qb_usage
+
+#define QUOTA_DQACQ_FL_ACQ	0x1  /* acquire quota */
+#define QUOTA_DQACQ_FL_PREACQ	0x2  /* pre-acquire */
+#define QUOTA_DQACQ_FL_REL	0x4  /* release quota */
+#define QUOTA_DQACQ_FL_REPORT	0x8  /* report usage */
+
+extern void lustre_swab_quota_body(struct quota_body *b);
+
+/* Quota types currently supported */
+enum {
+	LQUOTA_TYPE_USR	= 0x00, /* maps to USRQUOTA */
+	LQUOTA_TYPE_GRP	= 0x01, /* maps to GRPQUOTA */
+	LQUOTA_TYPE_MAX
+};
+
+/* There are 2 different resource types on which a quota limit can be enforced:
+ * - inodes on the MDTs
+ * - blocks on the OSTs */
+enum {
+	LQUOTA_RES_MD		= 0x01, /* skip 0 to avoid null oid in FID */
+	LQUOTA_RES_DT		= 0x02,
+	LQUOTA_LAST_RES,
+	LQUOTA_FIRST_RES	= LQUOTA_RES_MD
+};
+#define LQUOTA_NR_RES (LQUOTA_LAST_RES - LQUOTA_FIRST_RES + 1)
+
+/*
+ * Space accounting support
+ * Format of an accounting record, providing disk usage information for a given
+ * user or group
+ */
+struct lquota_acct_rec { /* 16 bytes */
+	__u64 bspace;  /* current space in use */
+	__u64 ispace;  /* current # inodes in use */
+};
+
+/*
+ * Global quota index support
+ * Format of a global record, providing global quota settings for a given quota
+ * identifier
+ */
+struct lquota_glb_rec { /* 32 bytes */
+	__u64 qbr_hardlimit; /* quota hard limit, in #inodes or kbytes */
+	__u64 qbr_softlimit; /* quota soft limit, in #inodes or kbytes */
+	__u64 qbr_time;      /* grace time, in seconds */
+	__u64 qbr_granted;   /* how much is granted to slaves, in #inodes or
+			      * kbytes */
+};
+
+/*
+ * Slave index support
+ * Format of a slave record, recording how much space is granted to a given
+ * slave
+ */
+struct lquota_slv_rec { /* 8 bytes */
+	__u64 qsr_granted; /* space granted to the slave for the key=ID,
+			    * in #inodes or kbytes */
+};
+
+/* Data structures associated with the quota locks */
+
+/* Glimpse descriptor used for the index & per-ID quota locks */
+struct ldlm_gl_lquota_desc {
+	union lquota_id	gl_id;    /* quota ID subject to the glimpse */
+	__u64		gl_flags; /* see LQUOTA_FL* below */
+	__u64		gl_ver;   /* new index version */
+	__u64		gl_hardlimit; /* new hardlimit or qunit value */
+	__u64		gl_softlimit; /* new softlimit */
+	__u64		gl_time;
+	__u64		gl_pad2;
+};
+#define gl_qunit	gl_hardlimit /* current qunit value used when
+				      * glimpsing per-ID quota locks */
+
+/* quota glimpse flags */
+#define LQUOTA_FL_EDQUOT 0x1 /* user/group out of quota space on QMT */
+
+/* LVB used with quota (global and per-ID) locks */
+struct lquota_lvb {
+	__u64	lvb_flags;	/* see LQUOTA_FL* above */
+	__u64	lvb_id_may_rel; /* space that might be released later */
+	__u64	lvb_id_rel;     /* space released by the slave for this ID */
+	__u64	lvb_id_qunit;   /* current qunit value */
+	__u64	lvb_pad1;
+};
+
+extern void lustre_swab_lquota_lvb(struct lquota_lvb *lvb);
+
+/* LVB used with global quota lock */
+#define lvb_glb_ver  lvb_id_may_rel /* current version of the global index */
+
+/* op codes */
+typedef enum {
+	QUOTA_DQACQ	= 601,
+	QUOTA_DQREL	= 602,
+	QUOTA_LAST_OPC
+} quota_cmd_t;
+#define QUOTA_FIRST_OPC	QUOTA_DQACQ
+
+/*
+ *   MDS REQ RECORDS
+ */
+
+/* opcodes */
+typedef enum {
+	MDS_GETATTR		= 33,
+	MDS_GETATTR_NAME	= 34,
+	MDS_CLOSE		= 35,
+	MDS_REINT		= 36,
+	MDS_READPAGE		= 37,
+	MDS_CONNECT		= 38,
+	MDS_DISCONNECT		= 39,
+	MDS_GETSTATUS		= 40,
+	MDS_STATFS		= 41,
+	MDS_PIN			= 42,
+	MDS_UNPIN		= 43,
+	MDS_SYNC		= 44,
+	MDS_DONE_WRITING	= 45,
+	MDS_SET_INFO		= 46,
+	MDS_QUOTACHECK		= 47,
+	MDS_QUOTACTL		= 48,
+	MDS_GETXATTR		= 49,
+	MDS_SETXATTR		= 50, /* obsolete, now it's MDS_REINT op */
+	MDS_WRITEPAGE		= 51,
+	MDS_IS_SUBDIR		= 52,
+	MDS_GET_INFO		= 53,
+	MDS_HSM_STATE_GET	= 54,
+	MDS_HSM_STATE_SET	= 55,
+	MDS_HSM_ACTION		= 56,
+	MDS_HSM_PROGRESS	= 57,
+	MDS_HSM_REQUEST		= 58,
+	MDS_HSM_CT_REGISTER	= 59,
+	MDS_HSM_CT_UNREGISTER	= 60,
+	MDS_SWAP_LAYOUTS	= 61,
+	MDS_LAST_OPC
+} mds_cmd_t;
+
+#define MDS_FIRST_OPC    MDS_GETATTR
+
+
+/* opcodes for object update */
+typedef enum {
+	UPDATE_OBJ	= 1000,
+	UPDATE_LAST_OPC
+} update_cmd_t;
+
+#define UPDATE_FIRST_OPC    UPDATE_OBJ
+
+/*
+ * Do not exceed 63
+ */
+
+typedef enum {
+	REINT_SETATTR  = 1,
+	REINT_CREATE   = 2,
+	REINT_LINK     = 3,
+	REINT_UNLINK   = 4,
+	REINT_RENAME   = 5,
+	REINT_OPEN     = 6,
+	REINT_SETXATTR = 7,
+	REINT_RMENTRY  = 8,
+//      REINT_WRITE    = 9,
+	REINT_MAX
+} mds_reint_t, mdt_reint_t;
+
+extern void lustre_swab_generic_32s (__u32 *val);
+
+/* the disposition of the intent outlines what was executed */
+#define DISP_IT_EXECD	0x00000001
+#define DISP_LOOKUP_EXECD    0x00000002
+#define DISP_LOOKUP_NEG      0x00000004
+#define DISP_LOOKUP_POS      0x00000008
+#define DISP_OPEN_CREATE     0x00000010
+#define DISP_OPEN_OPEN       0x00000020
+#define DISP_ENQ_COMPLETE    0x00400000
+#define DISP_ENQ_OPEN_REF    0x00800000
+#define DISP_ENQ_CREATE_REF  0x01000000
+#define DISP_OPEN_LOCK       0x02000000
+
+/* INODE LOCK PARTS */
+#define MDS_INODELOCK_LOOKUP 0x000001       /* dentry, mode, owner, group */
+#define MDS_INODELOCK_UPDATE 0x000002       /* size, links, timestamps */
+#define MDS_INODELOCK_OPEN   0x000004       /* For opened files */
+#define MDS_INODELOCK_LAYOUT 0x000008       /* for layout */
+#define MDS_INODELOCK_PERM   0x000010       /* for permission */
+
+#define MDS_INODELOCK_MAXSHIFT 4
+/* This FULL lock is useful to take on unlink sort of operations */
+#define MDS_INODELOCK_FULL ((1<<(MDS_INODELOCK_MAXSHIFT+1))-1)
+
+extern void lustre_swab_ll_fid (struct ll_fid *fid);
+
+/* NOTE: until Lustre 1.8.7/2.1.1 the fid_ver() was packed into name[2],
+ * but was moved into name[1] along with the OID to avoid consuming the
+ * name[2,3] fields that need to be used for the quota id (also a FID). */
+enum {
+	LUSTRE_RES_ID_SEQ_OFF = 0,
+	LUSTRE_RES_ID_VER_OID_OFF = 1,
+	LUSTRE_RES_ID_WAS_VER_OFF = 2, /* see note above */
+	LUSTRE_RES_ID_QUOTA_SEQ_OFF = 2,
+	LUSTRE_RES_ID_QUOTA_VER_OID_OFF = 3,
+	LUSTRE_RES_ID_HSH_OFF = 3
+};
+
+#define MDS_STATUS_CONN 1
+#define MDS_STATUS_LOV 2
+
+/* mdt_thread_info.mti_flags. */
+enum md_op_flags {
+	/* The flag indicates Size-on-MDS attributes are changed. */
+	MF_SOM_CHANGE	   = (1 << 0),
+	/* Flags indicates an epoch opens or closes. */
+	MF_EPOCH_OPEN	   = (1 << 1),
+	MF_EPOCH_CLOSE	  = (1 << 2),
+	MF_MDC_CANCEL_FID1      = (1 << 3),
+	MF_MDC_CANCEL_FID2      = (1 << 4),
+	MF_MDC_CANCEL_FID3      = (1 << 5),
+	MF_MDC_CANCEL_FID4      = (1 << 6),
+	/* There is a pending attribute update. */
+	MF_SOM_AU	       = (1 << 7),
+	/* Cancel OST locks while getattr OST attributes. */
+	MF_GETATTR_LOCK	 = (1 << 8),
+	MF_GET_MDT_IDX	  = (1 << 9),
+};
+
+#define MF_SOM_LOCAL_FLAGS (MF_SOM_CHANGE | MF_EPOCH_OPEN | MF_EPOCH_CLOSE)
+
+#define LUSTRE_BFLAG_UNCOMMITTED_WRITES   0x1
+
+/* these should be identical to their EXT4_*_FL counterparts, they are
+ * redefined here only to avoid dragging in fs/ext4/ext4.h */
+#define LUSTRE_SYNC_FL	 0x00000008 /* Synchronous updates */
+#define LUSTRE_IMMUTABLE_FL    0x00000010 /* Immutable file */
+#define LUSTRE_APPEND_FL       0x00000020 /* writes to file may only append */
+#define LUSTRE_NOATIME_FL      0x00000080 /* do not update atime */
+#define LUSTRE_DIRSYNC_FL      0x00010000 /* dirsync behaviour (dir only) */
+
+/* Convert wire LUSTRE_*_FL to corresponding client local VFS S_* values
+ * for the client inode i_flags.  The LUSTRE_*_FL are the Lustre wire
+ * protocol equivalents of LDISKFS_*_FL values stored on disk, while
+ * the S_* flags are kernel-internal values that change between kernel
+ * versions.  These flags are set/cleared via FSFILT_IOC_{GET,SET}_FLAGS.
+ * See b=16526 for a full history. */
+static inline int ll_ext_to_inode_flags(int flags)
+{
+	return (((flags & LUSTRE_SYNC_FL)      ? S_SYNC      : 0) |
+		((flags & LUSTRE_NOATIME_FL)   ? S_NOATIME   : 0) |
+		((flags & LUSTRE_APPEND_FL)    ? S_APPEND    : 0) |
+#if defined(S_DIRSYNC)
+		((flags & LUSTRE_DIRSYNC_FL)   ? S_DIRSYNC   : 0) |
+#endif
+		((flags & LUSTRE_IMMUTABLE_FL) ? S_IMMUTABLE : 0));
+}
+
+static inline int ll_inode_to_ext_flags(int iflags)
+{
+	return (((iflags & S_SYNC)      ? LUSTRE_SYNC_FL      : 0) |
+		((iflags & S_NOATIME)   ? LUSTRE_NOATIME_FL   : 0) |
+		((iflags & S_APPEND)    ? LUSTRE_APPEND_FL    : 0) |
+#if defined(S_DIRSYNC)
+		((iflags & S_DIRSYNC)   ? LUSTRE_DIRSYNC_FL   : 0) |
+#endif
+		((iflags & S_IMMUTABLE) ? LUSTRE_IMMUTABLE_FL : 0));
+}
+
+struct mdt_body {
+	struct lu_fid  fid1;
+	struct lu_fid  fid2;
+	struct lustre_handle handle;
+	__u64	  valid;
+	__u64	  size;   /* Offset, in the case of MDS_READPAGE */
+       obd_time	mtime;
+       obd_time	atime;
+       obd_time	ctime;
+	__u64	  blocks; /* XID, in the case of MDS_READPAGE */
+	__u64	  ioepoch;
+	__u64	       unused1; /* was "ino" until 2.4.0 */
+	__u32	  fsuid;
+	__u32	  fsgid;
+	__u32	  capability;
+	__u32	  mode;
+	__u32	  uid;
+	__u32	  gid;
+	__u32	  flags; /* from vfs for pin/unpin, LUSTRE_BFLAG close */
+	__u32	  rdev;
+	__u32	  nlink; /* #bytes to read in the case of MDS_READPAGE */
+	__u32	       unused2; /* was "generation" until 2.4.0 */
+	__u32	  suppgid;
+	__u32	  eadatasize;
+	__u32	  aclsize;
+	__u32	  max_mdsize;
+	__u32	  max_cookiesize;
+	__u32	  uid_h; /* high 32-bits of uid, for FUID */
+	__u32	  gid_h; /* high 32-bits of gid, for FUID */
+	__u32	  padding_5; /* also fix lustre_swab_mdt_body */
+	__u64	  padding_6;
+	__u64	  padding_7;
+	__u64	  padding_8;
+	__u64	  padding_9;
+	__u64	  padding_10;
+}; /* 216 */
+
+extern void lustre_swab_mdt_body (struct mdt_body *b);
+
+struct mdt_ioepoch {
+	struct lustre_handle handle;
+	__u64  ioepoch;
+	__u32  flags;
+	__u32  padding;
+};
+
+extern void lustre_swab_mdt_ioepoch (struct mdt_ioepoch *b);
+
+/* permissions for md_perm.mp_perm */
+enum {
+	CFS_SETUID_PERM = 0x01,
+	CFS_SETGID_PERM = 0x02,
+	CFS_SETGRP_PERM = 0x04,
+	CFS_RMTACL_PERM = 0x08,
+	CFS_RMTOWN_PERM = 0x10
+};
+
+/* inode access permission for remote user, the inode info are omitted,
+ * for client knows them. */
+struct mdt_remote_perm {
+	__u32	   rp_uid;
+	__u32	   rp_gid;
+	__u32	   rp_fsuid;
+	__u32	   rp_fsuid_h;
+	__u32	   rp_fsgid;
+	__u32	   rp_fsgid_h;
+	__u32	   rp_access_perm; /* MAY_READ/WRITE/EXEC */
+	__u32	   rp_padding;
+};
+
+extern void lustre_swab_mdt_remote_perm(struct mdt_remote_perm *p);
+
+struct mdt_rec_setattr {
+	__u32	   sa_opcode;
+	__u32	   sa_cap;
+	__u32	   sa_fsuid;
+	__u32	   sa_fsuid_h;
+	__u32	   sa_fsgid;
+	__u32	   sa_fsgid_h;
+	__u32	   sa_suppgid;
+	__u32	   sa_suppgid_h;
+	__u32	   sa_padding_1;
+	__u32	   sa_padding_1_h;
+	struct lu_fid   sa_fid;
+	__u64	   sa_valid;
+	__u32	   sa_uid;
+	__u32	   sa_gid;
+	__u64	   sa_size;
+	__u64	   sa_blocks;
+	obd_time	sa_mtime;
+	obd_time	sa_atime;
+	obd_time	sa_ctime;
+	__u32	   sa_attr_flags;
+	__u32	   sa_mode;
+	__u32	   sa_bias;      /* some operation flags */
+	__u32	   sa_padding_3;
+	__u32	   sa_padding_4;
+	__u32	   sa_padding_5;
+};
+
+extern void lustre_swab_mdt_rec_setattr (struct mdt_rec_setattr *sa);
+
+/*
+ * Attribute flags used in mdt_rec_setattr::sa_valid.
+ * The kernel's #defines for ATTR_* should not be used over the network
+ * since the client and MDS may run different kernels (see bug 13828)
+ * Therefore, we should only use MDS_ATTR_* attributes for sa_valid.
+ */
+#define MDS_ATTR_MODE	  0x1ULL /* = 1 */
+#define MDS_ATTR_UID	   0x2ULL /* = 2 */
+#define MDS_ATTR_GID	   0x4ULL /* = 4 */
+#define MDS_ATTR_SIZE	  0x8ULL /* = 8 */
+#define MDS_ATTR_ATIME	0x10ULL /* = 16 */
+#define MDS_ATTR_MTIME	0x20ULL /* = 32 */
+#define MDS_ATTR_CTIME	0x40ULL /* = 64 */
+#define MDS_ATTR_ATIME_SET    0x80ULL /* = 128 */
+#define MDS_ATTR_MTIME_SET   0x100ULL /* = 256 */
+#define MDS_ATTR_FORCE       0x200ULL /* = 512, Not a change, but a change it */
+#define MDS_ATTR_ATTR_FLAG   0x400ULL /* = 1024 */
+#define MDS_ATTR_KILL_SUID   0x800ULL /* = 2048 */
+#define MDS_ATTR_KILL_SGID  0x1000ULL /* = 4096 */
+#define MDS_ATTR_CTIME_SET  0x2000ULL /* = 8192 */
+#define MDS_ATTR_FROM_OPEN  0x4000ULL /* = 16384, called from open path, ie O_TRUNC */
+#define MDS_ATTR_BLOCKS     0x8000ULL /* = 32768 */
+
+#ifndef FMODE_READ
+#define FMODE_READ	       00000001
+#define FMODE_WRITE	      00000002
+#endif
+
+#define MDS_FMODE_CLOSED	 00000000
+#define MDS_FMODE_EXEC	   00000004
+/* IO Epoch is opened on a closed file. */
+#define MDS_FMODE_EPOCH	  01000000
+/* IO Epoch is opened on a file truncate. */
+#define MDS_FMODE_TRUNC	  02000000
+/* Size-on-MDS Attribute Update is pending. */
+#define MDS_FMODE_SOM	    04000000
+
+#define MDS_OPEN_CREATED	 00000010
+#define MDS_OPEN_CROSS	   00000020
+
+#define MDS_OPEN_CREAT	   00000100
+#define MDS_OPEN_EXCL	    00000200
+#define MDS_OPEN_TRUNC	   00001000
+#define MDS_OPEN_APPEND	  00002000
+#define MDS_OPEN_SYNC	    00010000
+#define MDS_OPEN_DIRECTORY       00200000
+
+#define MDS_OPEN_BY_FID		040000000 /* open_by_fid for known object */
+#define MDS_OPEN_DELAY_CREATE  0100000000 /* delay initial object create */
+#define MDS_OPEN_OWNEROVERRIDE 0200000000 /* NFSD rw-reopen ro file for owner */
+#define MDS_OPEN_JOIN_FILE     0400000000 /* open for join file.
+					   * We do not support JOIN FILE
+					   * anymore, reserve this flags
+					   * just for preventing such bit
+					   * to be reused. */
+
+#define MDS_OPEN_LOCK	 04000000000 /* This open requires open lock */
+#define MDS_OPEN_HAS_EA      010000000000 /* specify object create pattern */
+#define MDS_OPEN_HAS_OBJS    020000000000 /* Just set the EA the obj exist */
+#define MDS_OPEN_NORESTORE  0100000000000ULL /* Do not restore file at open */
+#define MDS_OPEN_NEWSTRIPE  0200000000000ULL /* New stripe needed (restripe or
+					      * hsm restore) */
+#define MDS_OPEN_VOLATILE   0400000000000ULL /* File is volatile = created
+						unlinked */
+
+/* permission for create non-directory file */
+#define MAY_CREATE      (1 << 7)
+/* permission for create directory file */
+#define MAY_LINK	(1 << 8)
+/* permission for delete from the directory */
+#define MAY_UNLINK      (1 << 9)
+/* source's permission for rename */
+#define MAY_RENAME_SRC  (1 << 10)
+/* target's permission for rename */
+#define MAY_RENAME_TAR  (1 << 11)
+/* part (parent's) VTX permission check */
+#define MAY_VTX_PART    (1 << 12)
+/* full VTX permission check */
+#define MAY_VTX_FULL    (1 << 13)
+/* lfs rgetfacl permission check */
+#define MAY_RGETFACL    (1 << 14)
+
+enum {
+	MDS_CHECK_SPLIT		= 1 << 0,
+	MDS_CROSS_REF		= 1 << 1,
+	MDS_VTX_BYPASS		= 1 << 2,
+	MDS_PERM_BYPASS		= 1 << 3,
+	MDS_SOM			= 1 << 4,
+	MDS_QUOTA_IGNORE	= 1 << 5,
+	MDS_CLOSE_CLEANUP	= 1 << 6,
+	MDS_KEEP_ORPHAN		= 1 << 7,
+	MDS_RECOV_OPEN		= 1 << 8,
+	MDS_DATA_MODIFIED	= 1 << 9,
+	MDS_CREATE_VOLATILE	= 1 << 10,
+	MDS_OWNEROVERRIDE	= 1 << 11,
+};
+
+/* instance of mdt_reint_rec */
+struct mdt_rec_create {
+	__u32	   cr_opcode;
+	__u32	   cr_cap;
+	__u32	   cr_fsuid;
+	__u32	   cr_fsuid_h;
+	__u32	   cr_fsgid;
+	__u32	   cr_fsgid_h;
+	__u32	   cr_suppgid1;
+	__u32	   cr_suppgid1_h;
+	__u32	   cr_suppgid2;
+	__u32	   cr_suppgid2_h;
+	struct lu_fid   cr_fid1;
+	struct lu_fid   cr_fid2;
+	struct lustre_handle cr_old_handle; /* handle in case of open replay */
+	obd_time	cr_time;
+	__u64	   cr_rdev;
+	__u64	   cr_ioepoch;
+	__u64	   cr_padding_1;   /* rr_blocks */
+	__u32	   cr_mode;
+	__u32	   cr_bias;
+	/* use of helpers set/get_mrc_cr_flags() is needed to access
+	 * 64 bits cr_flags [cr_flags_l, cr_flags_h], this is done to
+	 * extend cr_flags size without breaking 1.8 compat */
+	__u32	   cr_flags_l;     /* for use with open, low  32 bits  */
+	__u32	   cr_flags_h;     /* for use with open, high 32 bits */
+	__u32	   cr_umask;       /* umask for create */
+	__u32	   cr_padding_4;   /* rr_padding_4 */
+};
+
+static inline void set_mrc_cr_flags(struct mdt_rec_create *mrc, __u64 flags)
+{
+	mrc->cr_flags_l = (__u32)(flags & 0xFFFFFFFFUll);
+	mrc->cr_flags_h = (__u32)(flags >> 32);
+}
+
+static inline __u64 get_mrc_cr_flags(struct mdt_rec_create *mrc)
+{
+	return ((__u64)(mrc->cr_flags_l) | ((__u64)mrc->cr_flags_h << 32));
+}
+
+/* instance of mdt_reint_rec */
+struct mdt_rec_link {
+	__u32	   lk_opcode;
+	__u32	   lk_cap;
+	__u32	   lk_fsuid;
+	__u32	   lk_fsuid_h;
+	__u32	   lk_fsgid;
+	__u32	   lk_fsgid_h;
+	__u32	   lk_suppgid1;
+	__u32	   lk_suppgid1_h;
+	__u32	   lk_suppgid2;
+	__u32	   lk_suppgid2_h;
+	struct lu_fid   lk_fid1;
+	struct lu_fid   lk_fid2;
+	obd_time	lk_time;
+	__u64	   lk_padding_1;   /* rr_atime */
+	__u64	   lk_padding_2;   /* rr_ctime */
+	__u64	   lk_padding_3;   /* rr_size */
+	__u64	   lk_padding_4;   /* rr_blocks */
+	__u32	   lk_bias;
+	__u32	   lk_padding_5;   /* rr_mode */
+	__u32	   lk_padding_6;   /* rr_flags */
+	__u32	   lk_padding_7;   /* rr_padding_2 */
+	__u32	   lk_padding_8;   /* rr_padding_3 */
+	__u32	   lk_padding_9;   /* rr_padding_4 */
+};
+
+/* instance of mdt_reint_rec */
+struct mdt_rec_unlink {
+	__u32	   ul_opcode;
+	__u32	   ul_cap;
+	__u32	   ul_fsuid;
+	__u32	   ul_fsuid_h;
+	__u32	   ul_fsgid;
+	__u32	   ul_fsgid_h;
+	__u32	   ul_suppgid1;
+	__u32	   ul_suppgid1_h;
+	__u32	   ul_suppgid2;
+	__u32	   ul_suppgid2_h;
+	struct lu_fid   ul_fid1;
+	struct lu_fid   ul_fid2;
+	obd_time	ul_time;
+	__u64	   ul_padding_2;   /* rr_atime */
+	__u64	   ul_padding_3;   /* rr_ctime */
+	__u64	   ul_padding_4;   /* rr_size */
+	__u64	   ul_padding_5;   /* rr_blocks */
+	__u32	   ul_bias;
+	__u32	   ul_mode;
+	__u32	   ul_padding_6;   /* rr_flags */
+	__u32	   ul_padding_7;   /* rr_padding_2 */
+	__u32	   ul_padding_8;   /* rr_padding_3 */
+	__u32	   ul_padding_9;   /* rr_padding_4 */
+};
+
+/* instance of mdt_reint_rec */
+struct mdt_rec_rename {
+	__u32	   rn_opcode;
+	__u32	   rn_cap;
+	__u32	   rn_fsuid;
+	__u32	   rn_fsuid_h;
+	__u32	   rn_fsgid;
+	__u32	   rn_fsgid_h;
+	__u32	   rn_suppgid1;
+	__u32	   rn_suppgid1_h;
+	__u32	   rn_suppgid2;
+	__u32	   rn_suppgid2_h;
+	struct lu_fid   rn_fid1;
+	struct lu_fid   rn_fid2;
+	obd_time	rn_time;
+	__u64	   rn_padding_1;   /* rr_atime */
+	__u64	   rn_padding_2;   /* rr_ctime */
+	__u64	   rn_padding_3;   /* rr_size */
+	__u64	   rn_padding_4;   /* rr_blocks */
+	__u32	   rn_bias;	/* some operation flags */
+	__u32	   rn_mode;	/* cross-ref rename has mode */
+	__u32	   rn_padding_5;   /* rr_flags */
+	__u32	   rn_padding_6;   /* rr_padding_2 */
+	__u32	   rn_padding_7;   /* rr_padding_3 */
+	__u32	   rn_padding_8;   /* rr_padding_4 */
+};
+
+/* instance of mdt_reint_rec */
+struct mdt_rec_setxattr {
+	__u32	   sx_opcode;
+	__u32	   sx_cap;
+	__u32	   sx_fsuid;
+	__u32	   sx_fsuid_h;
+	__u32	   sx_fsgid;
+	__u32	   sx_fsgid_h;
+	__u32	   sx_suppgid1;
+	__u32	   sx_suppgid1_h;
+	__u32	   sx_suppgid2;
+	__u32	   sx_suppgid2_h;
+	struct lu_fid   sx_fid;
+	__u64	   sx_padding_1;   /* These three are rr_fid2 */
+	__u32	   sx_padding_2;
+	__u32	   sx_padding_3;
+	__u64	   sx_valid;
+	obd_time	sx_time;
+	__u64	   sx_padding_5;   /* rr_ctime */
+	__u64	   sx_padding_6;   /* rr_size */
+	__u64	   sx_padding_7;   /* rr_blocks */
+	__u32	   sx_size;
+	__u32	   sx_flags;
+	__u32	   sx_padding_8;   /* rr_flags */
+	__u32	   sx_padding_9;   /* rr_padding_2 */
+	__u32	   sx_padding_10;  /* rr_padding_3 */
+	__u32	   sx_padding_11;  /* rr_padding_4 */
+};
+
+/*
+ * mdt_rec_reint is the template for all mdt_reint_xxx structures.
+ * Do NOT change the size of various members, otherwise the value
+ * will be broken in lustre_swab_mdt_rec_reint().
+ *
+ * If you add new members in other mdt_reint_xxx structres and need to use the
+ * rr_padding_x fields, then update lustre_swab_mdt_rec_reint() also.
+ */
+struct mdt_rec_reint {
+	__u32	   rr_opcode;
+	__u32	   rr_cap;
+	__u32	   rr_fsuid;
+	__u32	   rr_fsuid_h;
+	__u32	   rr_fsgid;
+	__u32	   rr_fsgid_h;
+	__u32	   rr_suppgid1;
+	__u32	   rr_suppgid1_h;
+	__u32	   rr_suppgid2;
+	__u32	   rr_suppgid2_h;
+	struct lu_fid   rr_fid1;
+	struct lu_fid   rr_fid2;
+	obd_time	rr_mtime;
+	obd_time	rr_atime;
+	obd_time	rr_ctime;
+	__u64	   rr_size;
+	__u64	   rr_blocks;
+	__u32	   rr_bias;
+	__u32	   rr_mode;
+	__u32	   rr_flags;
+	__u32	   rr_flags_h;
+	__u32	   rr_umask;
+	__u32	   rr_padding_4; /* also fix lustre_swab_mdt_rec_reint */
+};
+
+extern void lustre_swab_mdt_rec_reint(struct mdt_rec_reint *rr);
+
+struct lmv_desc {
+	__u32 ld_tgt_count;		/* how many MDS's */
+	__u32 ld_active_tgt_count;	 /* how many active */
+	__u32 ld_default_stripe_count;     /* how many objects are used */
+	__u32 ld_pattern;		  /* default MEA_MAGIC_* */
+	__u64 ld_default_hash_size;
+	__u64 ld_padding_1;		/* also fix lustre_swab_lmv_desc */
+	__u32 ld_padding_2;		/* also fix lustre_swab_lmv_desc */
+	__u32 ld_qos_maxage;	       /* in second */
+	__u32 ld_padding_3;		/* also fix lustre_swab_lmv_desc */
+	__u32 ld_padding_4;		/* also fix lustre_swab_lmv_desc */
+	struct obd_uuid ld_uuid;
+};
+
+extern void lustre_swab_lmv_desc (struct lmv_desc *ld);
+
+/* TODO: lmv_stripe_md should contain mds capabilities for all slave fids */
+struct lmv_stripe_md {
+	__u32	 mea_magic;
+	__u32	 mea_count;
+	__u32	 mea_master;
+	__u32	 mea_padding;
+	char	  mea_pool_name[LOV_MAXPOOLNAME];
+	struct lu_fid mea_ids[0];
+};
+
+extern void lustre_swab_lmv_stripe_md(struct lmv_stripe_md *mea);
+
+/* lmv structures */
+#define MEA_MAGIC_LAST_CHAR      0xb2221ca1
+#define MEA_MAGIC_ALL_CHARS      0xb222a11c
+#define MEA_MAGIC_HASH_SEGMENT   0xb222a11b
+
+#define MAX_HASH_SIZE_32	 0x7fffffffUL
+#define MAX_HASH_SIZE	    0x7fffffffffffffffULL
+#define MAX_HASH_HIGHEST_BIT     0x1000000000000000ULL
+
+enum fld_rpc_opc {
+	FLD_QUERY		       = 900,
+	FLD_LAST_OPC,
+	FLD_FIRST_OPC		   = FLD_QUERY
+};
+
+enum seq_rpc_opc {
+	SEQ_QUERY		       = 700,
+	SEQ_LAST_OPC,
+	SEQ_FIRST_OPC		   = SEQ_QUERY
+};
+
+enum seq_op {
+	SEQ_ALLOC_SUPER = 0,
+	SEQ_ALLOC_META = 1
+};
+
+/*
+ *  LOV data structures
+ */
+
+#define LOV_MAX_UUID_BUFFER_SIZE  8192
+/* The size of the buffer the lov/mdc reserves for the
+ * array of UUIDs returned by the MDS.  With the current
+ * protocol, this will limit the max number of OSTs per LOV */
+
+#define LOV_DESC_MAGIC 0xB0CCDE5C
+
+/* LOV settings descriptor (should only contain static info) */
+struct lov_desc {
+	__u32 ld_tgt_count;		/* how many OBD's */
+	__u32 ld_active_tgt_count;	 /* how many active */
+	__u32 ld_default_stripe_count;     /* how many objects are used */
+	__u32 ld_pattern;		  /* default PATTERN_RAID0 */
+	__u64 ld_default_stripe_size;      /* in bytes */
+	__u64 ld_default_stripe_offset;    /* in bytes */
+	__u32 ld_padding_0;		/* unused */
+	__u32 ld_qos_maxage;	       /* in second */
+	__u32 ld_padding_1;		/* also fix lustre_swab_lov_desc */
+	__u32 ld_padding_2;		/* also fix lustre_swab_lov_desc */
+	struct obd_uuid ld_uuid;
+};
+
+#define ld_magic ld_active_tgt_count       /* for swabbing from llogs */
+
+extern void lustre_swab_lov_desc (struct lov_desc *ld);
+
+/*
+ *   LDLM requests:
+ */
+/* opcodes -- MUST be distinct from OST/MDS opcodes */
+typedef enum {
+	LDLM_ENQUEUE     = 101,
+	LDLM_CONVERT     = 102,
+	LDLM_CANCEL      = 103,
+	LDLM_BL_CALLBACK = 104,
+	LDLM_CP_CALLBACK = 105,
+	LDLM_GL_CALLBACK = 106,
+	LDLM_SET_INFO    = 107,
+	LDLM_LAST_OPC
+} ldlm_cmd_t;
+#define LDLM_FIRST_OPC LDLM_ENQUEUE
+
+#define RES_NAME_SIZE 4
+struct ldlm_res_id {
+	__u64 name[RES_NAME_SIZE];
+};
+
+extern void lustre_swab_ldlm_res_id (struct ldlm_res_id *id);
+
+static inline int ldlm_res_eq(const struct ldlm_res_id *res0,
+			      const struct ldlm_res_id *res1)
+{
+	return !memcmp(res0, res1, sizeof(*res0));
+}
+
+/* lock types */
+typedef enum {
+	LCK_MINMODE = 0,
+	LCK_EX      = 1,
+	LCK_PW      = 2,
+	LCK_PR      = 4,
+	LCK_CW      = 8,
+	LCK_CR      = 16,
+	LCK_NL      = 32,
+	LCK_GROUP   = 64,
+	LCK_COS     = 128,
+	LCK_MAXMODE
+} ldlm_mode_t;
+
+#define LCK_MODE_NUM    8
+
+typedef enum {
+	LDLM_PLAIN     = 10,
+	LDLM_EXTENT    = 11,
+	LDLM_FLOCK     = 12,
+	LDLM_IBITS     = 13,
+	LDLM_MAX_TYPE
+} ldlm_type_t;
+
+#define LDLM_MIN_TYPE LDLM_PLAIN
+
+struct ldlm_extent {
+	__u64 start;
+	__u64 end;
+	__u64 gid;
+};
+
+static inline int ldlm_extent_overlap(struct ldlm_extent *ex1,
+				      struct ldlm_extent *ex2)
+{
+	return (ex1->start <= ex2->end) && (ex2->start <= ex1->end);
+}
+
+/* check if @ex1 contains @ex2 */
+static inline int ldlm_extent_contain(struct ldlm_extent *ex1,
+				      struct ldlm_extent *ex2)
+{
+	return (ex1->start <= ex2->start) && (ex1->end >= ex2->end);
+}
+
+struct ldlm_inodebits {
+	__u64 bits;
+};
+
+struct ldlm_flock_wire {
+	__u64 lfw_start;
+	__u64 lfw_end;
+	__u64 lfw_owner;
+	__u32 lfw_padding;
+	__u32 lfw_pid;
+};
+
+/* it's important that the fields of the ldlm_extent structure match
+ * the first fields of the ldlm_flock structure because there is only
+ * one ldlm_swab routine to process the ldlm_policy_data_t union. if
+ * this ever changes we will need to swab the union differently based
+ * on the resource type. */
+
+typedef union {
+	struct ldlm_extent l_extent;
+	struct ldlm_flock_wire l_flock;
+	struct ldlm_inodebits l_inodebits;
+} ldlm_wire_policy_data_t;
+
+extern void lustre_swab_ldlm_policy_data (ldlm_wire_policy_data_t *d);
+
+union ldlm_gl_desc {
+	struct ldlm_gl_lquota_desc	lquota_desc;
+};
+
+extern void lustre_swab_gl_desc(union ldlm_gl_desc *);
+
+struct ldlm_intent {
+	__u64 opc;
+};
+
+extern void lustre_swab_ldlm_intent (struct ldlm_intent *i);
+
+struct ldlm_resource_desc {
+	ldlm_type_t lr_type;
+	__u32 lr_padding;       /* also fix lustre_swab_ldlm_resource_desc */
+	struct ldlm_res_id lr_name;
+};
+
+extern void lustre_swab_ldlm_resource_desc (struct ldlm_resource_desc *r);
+
+struct ldlm_lock_desc {
+	struct ldlm_resource_desc l_resource;
+	ldlm_mode_t l_req_mode;
+	ldlm_mode_t l_granted_mode;
+	ldlm_wire_policy_data_t l_policy_data;
+};
+
+extern void lustre_swab_ldlm_lock_desc (struct ldlm_lock_desc *l);
+
+#define LDLM_LOCKREQ_HANDLES 2
+#define LDLM_ENQUEUE_CANCEL_OFF 1
+
+struct ldlm_request {
+	__u32 lock_flags;
+	__u32 lock_count;
+	struct ldlm_lock_desc lock_desc;
+	struct lustre_handle lock_handle[LDLM_LOCKREQ_HANDLES];
+};
+
+extern void lustre_swab_ldlm_request (struct ldlm_request *rq);
+
+/* If LDLM_ENQUEUE, 1 slot is already occupied, 1 is available.
+ * Otherwise, 2 are available. */
+#define ldlm_request_bufsize(count,type)				\
+({								      \
+	int _avail = LDLM_LOCKREQ_HANDLES;			      \
+	_avail -= (type == LDLM_ENQUEUE ? LDLM_ENQUEUE_CANCEL_OFF : 0); \
+	sizeof(struct ldlm_request) +				   \
+	(count > _avail ? count - _avail : 0) *			 \
+	sizeof(struct lustre_handle);				   \
+})
+
+struct ldlm_reply {
+	__u32 lock_flags;
+	__u32 lock_padding;     /* also fix lustre_swab_ldlm_reply */
+	struct ldlm_lock_desc lock_desc;
+	struct lustre_handle lock_handle;
+	__u64  lock_policy_res1;
+	__u64  lock_policy_res2;
+};
+
+extern void lustre_swab_ldlm_reply (struct ldlm_reply *r);
+
+#define ldlm_flags_to_wire(flags)    ((__u32)(flags))
+#define ldlm_flags_from_wire(flags)  ((__u64)(flags))
+
+/*
+ * Opcodes for mountconf (mgs and mgc)
+ */
+typedef enum {
+	MGS_CONNECT = 250,
+	MGS_DISCONNECT,
+	MGS_EXCEPTION,	 /* node died, etc. */
+	MGS_TARGET_REG,	/* whenever target starts up */
+	MGS_TARGET_DEL,
+	MGS_SET_INFO,
+	MGS_CONFIG_READ,
+	MGS_LAST_OPC
+} mgs_cmd_t;
+#define MGS_FIRST_OPC MGS_CONNECT
+
+#define MGS_PARAM_MAXLEN 1024
+#define KEY_SET_INFO "set_info"
+
+struct mgs_send_param {
+	char	     mgs_param[MGS_PARAM_MAXLEN];
+};
+
+/* We pass this info to the MGS so it can write config logs */
+#define MTI_NAME_MAXLEN  64
+#define MTI_PARAM_MAXLEN 4096
+#define MTI_NIDS_MAX     32
+struct mgs_target_info {
+	__u32	    mti_lustre_ver;
+	__u32	    mti_stripe_index;
+	__u32	    mti_config_ver;
+	__u32	    mti_flags;
+	__u32	    mti_nid_count;
+	__u32	    mti_instance; /* Running instance of target */
+	char	     mti_fsname[MTI_NAME_MAXLEN];
+	char	     mti_svname[MTI_NAME_MAXLEN];
+	char	     mti_uuid[sizeof(struct obd_uuid)];
+	__u64	    mti_nids[MTI_NIDS_MAX];     /* host nids (lnet_nid_t)*/
+	char	     mti_params[MTI_PARAM_MAXLEN];
+};
+extern void lustre_swab_mgs_target_info(struct mgs_target_info *oinfo);
+
+struct mgs_nidtbl_entry {
+	__u64	   mne_version;    /* table version of this entry */
+	__u32	   mne_instance;   /* target instance # */
+	__u32	   mne_index;      /* target index */
+	__u32	   mne_length;     /* length of this entry - by bytes */
+	__u8	    mne_type;       /* target type LDD_F_SV_TYPE_OST/MDT */
+	__u8	    mne_nid_type;   /* type of nid(mbz). for ipv6. */
+	__u8	    mne_nid_size;   /* size of each NID, by bytes */
+	__u8	    mne_nid_count;  /* # of NIDs in buffer */
+	union {
+		lnet_nid_t nids[0];     /* variable size buffer for NIDs. */
+	} u;
+};
+extern void lustre_swab_mgs_nidtbl_entry(struct mgs_nidtbl_entry *oinfo);
+
+struct mgs_config_body {
+	char     mcb_name[MTI_NAME_MAXLEN]; /* logname */
+	__u64    mcb_offset;    /* next index of config log to request */
+	__u16    mcb_type;      /* type of log: CONFIG_T_[CONFIG|RECOVER] */
+	__u8     mcb_reserved;
+	__u8     mcb_bits;      /* bits unit size of config log */
+	__u32    mcb_units;     /* # of units for bulk transfer */
+};
+extern void lustre_swab_mgs_config_body(struct mgs_config_body *body);
+
+struct mgs_config_res {
+	__u64    mcr_offset;    /* index of last config log */
+	__u64    mcr_size;      /* size of the log */
+};
+extern void lustre_swab_mgs_config_res(struct mgs_config_res *body);
+
+/* Config marker flags (in config log) */
+#define CM_START       0x01
+#define CM_END	 0x02
+#define CM_SKIP	0x04
+#define CM_UPGRADE146  0x08
+#define CM_EXCLUDE     0x10
+#define CM_START_SKIP (CM_START | CM_SKIP)
+
+struct cfg_marker {
+	__u32	     cm_step;       /* aka config version */
+	__u32	     cm_flags;
+	__u32	     cm_vers;       /* lustre release version number */
+	__u32	     cm_padding;    /* 64 bit align */
+	obd_time	  cm_createtime; /*when this record was first created */
+	obd_time	  cm_canceltime; /*when this record is no longer valid*/
+	char	      cm_tgtname[MTI_NAME_MAXLEN];
+	char	      cm_comment[MTI_NAME_MAXLEN];
+};
+
+extern void lustre_swab_cfg_marker(struct cfg_marker *marker,
+				   int swab, int size);
+
+/*
+ * Opcodes for multiple servers.
+ */
+
+typedef enum {
+	OBD_PING = 400,
+	OBD_LOG_CANCEL,
+	OBD_QC_CALLBACK,
+	OBD_IDX_READ,
+	OBD_LAST_OPC
+} obd_cmd_t;
+#define OBD_FIRST_OPC OBD_PING
+
+/* catalog of log objects */
+
+/** Identifier for a single log object */
+struct llog_logid {
+	struct ost_id		lgl_oi;
+	__u32		   lgl_ogen;
+} __attribute__((packed));
+
+/** Records written to the CATALOGS list */
+#define CATLIST "CATALOGS"
+struct llog_catid {
+	struct llog_logid       lci_logid;
+	__u32		   lci_padding1;
+	__u32		   lci_padding2;
+	__u32		   lci_padding3;
+} __attribute__((packed));
+
+/* Log data record types - there is no specific reason that these need to
+ * be related to the RPC opcodes, but no reason not to (may be handy later?)
+ */
+#define LLOG_OP_MAGIC 0x10600000
+#define LLOG_OP_MASK  0xfff00000
+
+typedef enum {
+	LLOG_PAD_MAGIC		= LLOG_OP_MAGIC | 0x00000,
+	OST_SZ_REC		= LLOG_OP_MAGIC | 0x00f00,
+	/* OST_RAID1_REC	= LLOG_OP_MAGIC | 0x01000, never used */
+	MDS_UNLINK_REC		= LLOG_OP_MAGIC | 0x10000 | (MDS_REINT << 8) |
+				  REINT_UNLINK, /* obsolete after 2.5.0 */
+	MDS_UNLINK64_REC	= LLOG_OP_MAGIC | 0x90000 | (MDS_REINT << 8) |
+				  REINT_UNLINK,
+	/* MDS_SETATTR_REC	= LLOG_OP_MAGIC | 0x12401, obsolete 1.8.0 */
+	MDS_SETATTR64_REC	= LLOG_OP_MAGIC | 0x90000 | (MDS_REINT << 8) |
+				  REINT_SETATTR,
+	OBD_CFG_REC		= LLOG_OP_MAGIC | 0x20000,
+	/* PTL_CFG_REC		= LLOG_OP_MAGIC | 0x30000, obsolete 1.4.0 */
+	LLOG_GEN_REC		= LLOG_OP_MAGIC | 0x40000,
+	/* LLOG_JOIN_REC	= LLOG_OP_MAGIC | 0x50000, obsolete  1.8.0 */
+	CHANGELOG_REC		= LLOG_OP_MAGIC | 0x60000,
+	CHANGELOG_USER_REC	= LLOG_OP_MAGIC | 0x70000,
+	LLOG_HDR_MAGIC		= LLOG_OP_MAGIC | 0x45539,
+	LLOG_LOGID_MAGIC	= LLOG_OP_MAGIC | 0x4553b,
+} llog_op_type;
+
+#define LLOG_REC_HDR_NEEDS_SWABBING(r) \
+	(((r)->lrh_type & __swab32(LLOG_OP_MASK)) == __swab32(LLOG_OP_MAGIC))
+
+/** Log record header - stored in little endian order.
+ * Each record must start with this struct, end with a llog_rec_tail,
+ * and be a multiple of 256 bits in size.
+ */
+struct llog_rec_hdr {
+	__u32	lrh_len;
+	__u32	lrh_index;
+	__u32	lrh_type;
+	__u32	lrh_id;
+};
+
+struct llog_rec_tail {
+	__u32	lrt_len;
+	__u32	lrt_index;
+};
+
+/* Where data follow just after header */
+#define REC_DATA(ptr)						\
+	((void *)((char *)ptr + sizeof(struct llog_rec_hdr)))
+
+#define REC_DATA_LEN(rec)					\
+	(rec->lrh_len - sizeof(struct llog_rec_hdr) -		\
+	 sizeof(struct llog_rec_tail))
+
+struct llog_logid_rec {
+	struct llog_rec_hdr	lid_hdr;
+	struct llog_logid	lid_id;
+	__u32			lid_padding1;
+	__u64			lid_padding2;
+	__u64			lid_padding3;
+	struct llog_rec_tail	lid_tail;
+} __attribute__((packed));
+
+struct llog_unlink_rec {
+	struct llog_rec_hdr	lur_hdr;
+	obd_id			lur_oid;
+	obd_count		lur_oseq;
+	obd_count		lur_count;
+	struct llog_rec_tail	lur_tail;
+} __attribute__((packed));
+
+struct llog_unlink64_rec {
+	struct llog_rec_hdr	lur_hdr;
+	struct lu_fid		lur_fid;
+	obd_count		lur_count; /* to destroy the lost precreated */
+	__u32			lur_padding1;
+	__u64			lur_padding2;
+	__u64			lur_padding3;
+	struct llog_rec_tail    lur_tail;
+} __attribute__((packed));
+
+struct llog_setattr64_rec {
+	struct llog_rec_hdr	lsr_hdr;
+	struct ost_id		lsr_oi;
+	__u32			lsr_uid;
+	__u32			lsr_uid_h;
+	__u32			lsr_gid;
+	__u32			lsr_gid_h;
+	__u64			lsr_padding;
+	struct llog_rec_tail    lsr_tail;
+} __attribute__((packed));
+
+struct llog_size_change_rec {
+	struct llog_rec_hdr	lsc_hdr;
+	struct ll_fid		lsc_fid;
+	__u32			lsc_ioepoch;
+	__u32			lsc_padding1;
+	__u64			lsc_padding2;
+	__u64			lsc_padding3;
+	struct llog_rec_tail	lsc_tail;
+} __attribute__((packed));
+
+#define CHANGELOG_MAGIC 0xca103000
+
+/** \a changelog_rec_type's that can't be masked */
+#define CHANGELOG_MINMASK (1 << CL_MARK)
+/** bits covering all \a changelog_rec_type's */
+#define CHANGELOG_ALLMASK 0XFFFFFFFF
+/** default \a changelog_rec_type mask */
+#define CHANGELOG_DEFMASK CHANGELOG_ALLMASK & ~(1 << CL_ATIME | 1 << CL_CLOSE)
+
+/* changelog llog name, needed by client replicators */
+#define CHANGELOG_CATALOG "changelog_catalog"
+
+struct changelog_setinfo {
+	__u64 cs_recno;
+	__u32 cs_id;
+} __attribute__((packed));
+
+/** changelog record */
+struct llog_changelog_rec {
+	struct llog_rec_hdr  cr_hdr;
+	struct changelog_rec cr;
+	struct llog_rec_tail cr_tail; /**< for_sizezof_only */
+} __attribute__((packed));
+
+struct llog_changelog_ext_rec {
+	struct llog_rec_hdr      cr_hdr;
+	struct changelog_ext_rec cr;
+	struct llog_rec_tail     cr_tail; /**< for_sizezof_only */
+} __attribute__((packed));
+
+#define CHANGELOG_USER_PREFIX "cl"
+
+struct llog_changelog_user_rec {
+	struct llog_rec_hdr   cur_hdr;
+	__u32		 cur_id;
+	__u32		 cur_padding;
+	__u64		 cur_endrec;
+	struct llog_rec_tail  cur_tail;
+} __attribute__((packed));
+
+/* Old llog gen for compatibility */
+struct llog_gen {
+	__u64 mnt_cnt;
+	__u64 conn_cnt;
+} __attribute__((packed));
+
+struct llog_gen_rec {
+	struct llog_rec_hdr	lgr_hdr;
+	struct llog_gen		lgr_gen;
+	__u64			padding1;
+	__u64			padding2;
+	__u64			padding3;
+	struct llog_rec_tail	lgr_tail;
+};
+
+/* On-disk header structure of each log object, stored in little endian order */
+#define LLOG_CHUNK_SIZE	 8192
+#define LLOG_HEADER_SIZE	(96)
+#define LLOG_BITMAP_BYTES       (LLOG_CHUNK_SIZE - LLOG_HEADER_SIZE)
+
+#define LLOG_MIN_REC_SIZE       (24) /* round(llog_rec_hdr + llog_rec_tail) */
+
+/* flags for the logs */
+enum llog_flag {
+	LLOG_F_ZAP_WHEN_EMPTY	= 0x1,
+	LLOG_F_IS_CAT		= 0x2,
+	LLOG_F_IS_PLAIN		= 0x4,
+};
+
+struct llog_log_hdr {
+	struct llog_rec_hdr     llh_hdr;
+	obd_time		llh_timestamp;
+	__u32		   llh_count;
+	__u32		   llh_bitmap_offset;
+	__u32		   llh_size;
+	__u32		   llh_flags;
+	__u32		   llh_cat_idx;
+	/* for a catalog the first plain slot is next to it */
+	struct obd_uuid	 llh_tgtuuid;
+	__u32		   llh_reserved[LLOG_HEADER_SIZE/sizeof(__u32) - 23];
+	__u32		   llh_bitmap[LLOG_BITMAP_BYTES/sizeof(__u32)];
+	struct llog_rec_tail    llh_tail;
+} __attribute__((packed));
+
+#define LLOG_BITMAP_SIZE(llh)  (__u32)((llh->llh_hdr.lrh_len -		\
+					llh->llh_bitmap_offset -	\
+					sizeof(llh->llh_tail)) * 8)
+
+/** log cookies are used to reference a specific log file and a record therein */
+struct llog_cookie {
+	struct llog_logid       lgc_lgl;
+	__u32		   lgc_subsys;
+	__u32		   lgc_index;
+	__u32		   lgc_padding;
+} __attribute__((packed));
+
+/** llog protocol */
+enum llogd_rpc_ops {
+	LLOG_ORIGIN_HANDLE_CREATE       = 501,
+	LLOG_ORIGIN_HANDLE_NEXT_BLOCK   = 502,
+	LLOG_ORIGIN_HANDLE_READ_HEADER  = 503,
+	LLOG_ORIGIN_HANDLE_WRITE_REC    = 504,
+	LLOG_ORIGIN_HANDLE_CLOSE	= 505,
+	LLOG_ORIGIN_CONNECT	     = 506,
+	LLOG_CATINFO			= 507,  /* deprecated */
+	LLOG_ORIGIN_HANDLE_PREV_BLOCK   = 508,
+	LLOG_ORIGIN_HANDLE_DESTROY      = 509,  /* for destroy llog object*/
+	LLOG_LAST_OPC,
+	LLOG_FIRST_OPC		  = LLOG_ORIGIN_HANDLE_CREATE
+};
+
+struct llogd_body {
+	struct llog_logid  lgd_logid;
+	__u32 lgd_ctxt_idx;
+	__u32 lgd_llh_flags;
+	__u32 lgd_index;
+	__u32 lgd_saved_index;
+	__u32 lgd_len;
+	__u64 lgd_cur_offset;
+} __attribute__((packed));
+
+struct llogd_conn_body {
+	struct llog_gen	 lgdc_gen;
+	struct llog_logid       lgdc_logid;
+	__u32		   lgdc_ctxt_idx;
+} __attribute__((packed));
+
+/* Note: 64-bit types are 64-bit aligned in structure */
+struct obdo {
+	obd_valid	       o_valid;	/* hot fields in this obdo */
+	struct ost_id	   o_oi;
+	obd_id		  o_parent_seq;
+	obd_size		o_size;	 /* o_size-o_blocks == ost_lvb */
+	obd_time		o_mtime;
+	obd_time		o_atime;
+	obd_time		o_ctime;
+	obd_blocks	      o_blocks;       /* brw: cli sent cached bytes */
+	obd_size		o_grant;
+
+	/* 32-bit fields start here: keep an even number of them via padding */
+	obd_blksize	     o_blksize;      /* optimal IO blocksize */
+	obd_mode		o_mode;	 /* brw: cli sent cache remain */
+	obd_uid		 o_uid;
+	obd_gid		 o_gid;
+	obd_flag		o_flags;
+	obd_count	       o_nlink;	/* brw: checksum */
+	obd_count	       o_parent_oid;
+	obd_count		o_misc;		/* brw: o_dropped */
+
+	__u64		   o_ioepoch;      /* epoch in ost writes */
+	__u32		   o_stripe_idx;   /* holds stripe idx */
+	__u32		   o_parent_ver;
+	struct lustre_handle    o_handle;       /* brw: lock handle to prolong
+						 * locks */
+	struct llog_cookie      o_lcookie;      /* destroy: unlink cookie from
+						 * MDS */
+	__u32			o_uid_h;
+	__u32			o_gid_h;
+
+	__u64			o_data_version; /* getattr: sum of iversion for
+						 * each stripe.
+						 * brw: grant space consumed on
+						 * the client for the write */
+	__u64			o_padding_4;
+	__u64			o_padding_5;
+	__u64			o_padding_6;
+};
+
+#define o_dirty   o_blocks
+#define o_undirty o_mode
+#define o_dropped o_misc
+#define o_cksum   o_nlink
+#define o_grant_used o_data_version
+
+static inline void lustre_set_wire_obdo(struct obd_connect_data *ocd,
+					struct obdo *wobdo, struct obdo *lobdo)
+{
+	memcpy(wobdo, lobdo, sizeof(*lobdo));
+	wobdo->o_flags &= ~OBD_FL_LOCAL_MASK;
+	if (ocd == NULL)
+		return;
+
+	if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) &&
+	    fid_seq_is_echo(ostid_seq(&lobdo->o_oi))) {
+		/* Currently OBD_FL_OSTID will only be used when 2.4 echo
+		 * client communicate with pre-2.4 server */
+		wobdo->o_oi.oi.oi_id = fid_oid(&lobdo->o_oi.oi_fid);
+		wobdo->o_oi.oi.oi_seq = fid_seq(&lobdo->o_oi.oi_fid);
+	}
+}
+
+static inline void lustre_get_wire_obdo(struct obd_connect_data *ocd,
+					struct obdo *lobdo, struct obdo *wobdo)
+{
+	obd_flag local_flags = 0;
+
+	if (lobdo->o_valid & OBD_MD_FLFLAGS)
+		 local_flags = lobdo->o_flags & OBD_FL_LOCAL_MASK;
+
+	LASSERT(!(wobdo->o_flags & OBD_FL_LOCAL_MASK));
+
+	memcpy(lobdo, wobdo, sizeof(*lobdo));
+	if (local_flags != 0) {
+		lobdo->o_valid |= OBD_MD_FLFLAGS;
+		lobdo->o_flags &= ~OBD_FL_LOCAL_MASK;
+		lobdo->o_flags |= local_flags;
+	}
+	if (ocd == NULL)
+		return;
+
+	if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) &&
+	    fid_seq_is_echo(wobdo->o_oi.oi.oi_seq)) {
+		/* see above */
+		lobdo->o_oi.oi_fid.f_seq = wobdo->o_oi.oi.oi_seq;
+		lobdo->o_oi.oi_fid.f_oid = wobdo->o_oi.oi.oi_id;
+		lobdo->o_oi.oi_fid.f_ver = 0;
+	}
+}
+
+extern void lustre_swab_obdo (struct obdo *o);
+
+/* request structure for OST's */
+struct ost_body {
+	struct  obdo oa;
+};
+
+/* Key for FIEMAP to be used in get_info calls */
+struct ll_fiemap_info_key {
+	char    name[8];
+	struct  obdo oa;
+	struct  ll_user_fiemap fiemap;
+};
+
+extern void lustre_swab_ost_body (struct ost_body *b);
+extern void lustre_swab_ost_last_id(obd_id *id);
+extern void lustre_swab_fiemap(struct ll_user_fiemap *fiemap);
+
+extern void lustre_swab_lov_user_md_v1(struct lov_user_md_v1 *lum);
+extern void lustre_swab_lov_user_md_v3(struct lov_user_md_v3 *lum);
+extern void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod,
+					    int stripe_count);
+extern void lustre_swab_lov_mds_md(struct lov_mds_md *lmm);
+
+/* llog_swab.c */
+extern void lustre_swab_llogd_body (struct llogd_body *d);
+extern void lustre_swab_llog_hdr (struct llog_log_hdr *h);
+extern void lustre_swab_llogd_conn_body (struct llogd_conn_body *d);
+extern void lustre_swab_llog_rec(struct llog_rec_hdr *rec);
+extern void lustre_swab_llog_id(struct llog_logid *lid);
+
+struct lustre_cfg;
+extern void lustre_swab_lustre_cfg(struct lustre_cfg *lcfg);
+
+/* Functions for dumping PTLRPC fields */
+void dump_rniobuf(struct niobuf_remote *rnb);
+void dump_ioo(struct obd_ioobj *nb);
+void dump_obdo(struct obdo *oa);
+void dump_ost_body(struct ost_body *ob);
+void dump_rcs(__u32 *rc);
+
+#define IDX_INFO_MAGIC 0x3D37CC37
+
+/* Index file transfer through the network. The server serializes the index into
+ * a byte stream which is sent to the client via a bulk transfer */
+struct idx_info {
+	__u32		ii_magic;
+
+	/* reply: see idx_info_flags below */
+	__u32		ii_flags;
+
+	/* request & reply: number of lu_idxpage (to be) transferred */
+	__u16		ii_count;
+	__u16		ii_pad0;
+
+	/* request: requested attributes passed down to the iterator API */
+	__u32		ii_attrs;
+
+	/* request & reply: index file identifier (FID) */
+	struct lu_fid	ii_fid;
+
+	/* reply: version of the index file before starting to walk the index.
+	 * Please note that the version can be modified at any time during the
+	 * transfer */
+	__u64		ii_version;
+
+	/* request: hash to start with:
+	 * reply: hash of the first entry of the first lu_idxpage and hash
+	 *	of the entry to read next if any */
+	__u64		ii_hash_start;
+	__u64		ii_hash_end;
+
+	/* reply: size of keys in lu_idxpages, minimal one if II_FL_VARKEY is
+	 * set */
+	__u16		ii_keysize;
+
+	/* reply: size of records in lu_idxpages, minimal one if II_FL_VARREC
+	 * is set */
+	__u16		ii_recsize;
+
+	__u32		ii_pad1;
+	__u64		ii_pad2;
+	__u64		ii_pad3;
+};
+extern void lustre_swab_idx_info(struct idx_info *ii);
+
+#define II_END_OFF	MDS_DIR_END_OFF /* all entries have been read */
+
+/* List of flags used in idx_info::ii_flags */
+enum idx_info_flags {
+	II_FL_NOHASH	= 1 << 0, /* client doesn't care about hash value */
+	II_FL_VARKEY	= 1 << 1, /* keys can be of variable size */
+	II_FL_VARREC	= 1 << 2, /* records can be of variable size */
+	II_FL_NONUNQ	= 1 << 3, /* index supports non-unique keys */
+};
+
+#define LIP_MAGIC 0x8A6D6B6C
+
+/* 4KB (= LU_PAGE_SIZE) container gathering key/record pairs */
+struct lu_idxpage {
+	/* 16-byte header */
+	__u32	lip_magic;
+	__u16	lip_flags;
+	__u16	lip_nr;   /* number of entries in the container */
+	__u64	lip_pad0; /* additional padding for future use */
+
+	/* key/record pairs are stored in the remaining 4080 bytes.
+	 * depending upon the flags in idx_info::ii_flags, each key/record
+	 * pair might be preceded by:
+	 * - a hash value
+	 * - the key size (II_FL_VARKEY is set)
+	 * - the record size (II_FL_VARREC is set)
+	 *
+	 * For the time being, we only support fixed-size key & record. */
+	char	lip_entries[0];
+};
+extern void lustre_swab_lip_header(struct lu_idxpage *lip);
+
+#define LIP_HDR_SIZE (offsetof(struct lu_idxpage, lip_entries))
+
+/* Gather all possible type associated with a 4KB container */
+union lu_page {
+	struct lu_dirpage	lp_dir; /* for MDS_READPAGE */
+	struct lu_idxpage	lp_idx; /* for OBD_IDX_READ */
+	char			lp_array[LU_PAGE_SIZE];
+};
+
+/* security opcodes */
+typedef enum {
+	SEC_CTX_INIT	    = 801,
+	SEC_CTX_INIT_CONT       = 802,
+	SEC_CTX_FINI	    = 803,
+	SEC_LAST_OPC,
+	SEC_FIRST_OPC	   = SEC_CTX_INIT
+} sec_cmd_t;
+
+/*
+ * capa related definitions
+ */
+#define CAPA_HMAC_MAX_LEN       64
+#define CAPA_HMAC_KEY_MAX_LEN   56
+
+/* NB take care when changing the sequence of elements this struct,
+ * because the offset info is used in find_capa() */
+struct lustre_capa {
+	struct lu_fid   lc_fid;	 /** fid */
+	__u64	   lc_opc;	 /** operations allowed */
+	__u64	   lc_uid;	 /** file owner */
+	__u64	   lc_gid;	 /** file group */
+	__u32	   lc_flags;       /** HMAC algorithm & flags */
+	__u32	   lc_keyid;       /** key# used for the capability */
+	__u32	   lc_timeout;     /** capa timeout value (sec) */
+	__u32	   lc_expiry;      /** expiry time (sec) */
+	__u8	    lc_hmac[CAPA_HMAC_MAX_LEN];   /** HMAC */
+} __attribute__((packed));
+
+extern void lustre_swab_lustre_capa(struct lustre_capa *c);
+
+/** lustre_capa::lc_opc */
+enum {
+	CAPA_OPC_BODY_WRITE   = 1<<0,  /**< write object data */
+	CAPA_OPC_BODY_READ    = 1<<1,  /**< read object data */
+	CAPA_OPC_INDEX_LOOKUP = 1<<2,  /**< lookup object fid */
+	CAPA_OPC_INDEX_INSERT = 1<<3,  /**< insert object fid */
+	CAPA_OPC_INDEX_DELETE = 1<<4,  /**< delete object fid */
+	CAPA_OPC_OSS_WRITE    = 1<<5,  /**< write oss object data */
+	CAPA_OPC_OSS_READ     = 1<<6,  /**< read oss object data */
+	CAPA_OPC_OSS_TRUNC    = 1<<7,  /**< truncate oss object */
+	CAPA_OPC_OSS_DESTROY  = 1<<8,  /**< destroy oss object */
+	CAPA_OPC_META_WRITE   = 1<<9,  /**< write object meta data */
+	CAPA_OPC_META_READ    = 1<<10, /**< read object meta data */
+};
+
+#define CAPA_OPC_OSS_RW (CAPA_OPC_OSS_READ | CAPA_OPC_OSS_WRITE)
+#define CAPA_OPC_MDS_ONLY						   \
+	(CAPA_OPC_BODY_WRITE | CAPA_OPC_BODY_READ | CAPA_OPC_INDEX_LOOKUP | \
+	 CAPA_OPC_INDEX_INSERT | CAPA_OPC_INDEX_DELETE)
+#define CAPA_OPC_OSS_ONLY						   \
+	(CAPA_OPC_OSS_WRITE | CAPA_OPC_OSS_READ | CAPA_OPC_OSS_TRUNC |      \
+	 CAPA_OPC_OSS_DESTROY)
+#define CAPA_OPC_MDS_DEFAULT ~CAPA_OPC_OSS_ONLY
+#define CAPA_OPC_OSS_DEFAULT ~(CAPA_OPC_MDS_ONLY | CAPA_OPC_OSS_ONLY)
+
+/* MDS capability covers object capability for operations of body r/w
+ * (dir readpage/sendpage), index lookup/insert/delete and meta data r/w,
+ * while OSS capability only covers object capability for operations of
+ * oss data(file content) r/w/truncate.
+ */
+static inline int capa_for_mds(struct lustre_capa *c)
+{
+	return (c->lc_opc & CAPA_OPC_INDEX_LOOKUP) != 0;
+}
+
+static inline int capa_for_oss(struct lustre_capa *c)
+{
+	return (c->lc_opc & CAPA_OPC_INDEX_LOOKUP) == 0;
+}
+
+/* lustre_capa::lc_hmac_alg */
+enum {
+	CAPA_HMAC_ALG_SHA1 = 1, /**< sha1 algorithm */
+	CAPA_HMAC_ALG_MAX,
+};
+
+#define CAPA_FL_MASK	    0x00ffffff
+#define CAPA_HMAC_ALG_MASK      0xff000000
+
+struct lustre_capa_key {
+	__u64   lk_seq;       /**< mds# */
+	__u32   lk_keyid;     /**< key# */
+	__u32   lk_padding;
+	__u8    lk_key[CAPA_HMAC_KEY_MAX_LEN];    /**< key */
+} __attribute__((packed));
+
+extern void lustre_swab_lustre_capa_key(struct lustre_capa_key *k);
+
+/** The link ea holds 1 \a link_ea_entry for each hardlink */
+#define LINK_EA_MAGIC 0x11EAF1DFUL
+struct link_ea_header {
+	__u32 leh_magic;
+	__u32 leh_reccount;
+	__u64 leh_len;      /* total size */
+	/* future use */
+	__u32 padding1;
+	__u32 padding2;
+};
+
+/** Hardlink data is name and parent fid.
+ * Stored in this crazy struct for maximum packing and endian-neutrality
+ */
+struct link_ea_entry {
+	/** __u16 stored big-endian, unaligned */
+	unsigned char      lee_reclen[2];
+	unsigned char      lee_parent_fid[sizeof(struct lu_fid)];
+	char	       lee_name[0];
+}__attribute__((packed));
+
+/** fid2path request/reply structure */
+struct getinfo_fid2path {
+	struct lu_fid   gf_fid;
+	__u64	   gf_recno;
+	__u32	   gf_linkno;
+	__u32	   gf_pathlen;
+	char	    gf_path[0];
+} __attribute__((packed));
+
+void lustre_swab_fid2path (struct getinfo_fid2path *gf);
+
+enum {
+	LAYOUT_INTENT_ACCESS    = 0,
+	LAYOUT_INTENT_READ      = 1,
+	LAYOUT_INTENT_WRITE     = 2,
+	LAYOUT_INTENT_GLIMPSE   = 3,
+	LAYOUT_INTENT_TRUNC     = 4,
+	LAYOUT_INTENT_RELEASE   = 5,
+	LAYOUT_INTENT_RESTORE   = 6
+};
+
+/* enqueue layout lock with intent */
+struct layout_intent {
+	__u32 li_opc; /* intent operation for enqueue, read, write etc */
+	__u32 li_flags;
+	__u64 li_start;
+	__u64 li_end;
+};
+
+void lustre_swab_layout_intent(struct layout_intent *li);
+
+/**
+ * On the wire version of hsm_progress structure.
+ *
+ * Contains the userspace hsm_progress and some internal fields.
+ */
+struct hsm_progress_kernel {
+	/* Field taken from struct hsm_progress */
+	lustre_fid		hpk_fid;
+	__u64			hpk_cookie;
+	struct hsm_extent	hpk_extent;
+	__u16			hpk_flags;
+	__u16			hpk_errval; /* positive val */
+	__u32			hpk_padding1;
+	/* Additional fields */
+	__u64			hpk_data_version;
+	__u64			hpk_padding2;
+} __attribute__((packed));
+
+extern void lustre_swab_hsm_user_state(struct hsm_user_state *hus);
+extern void lustre_swab_hsm_current_action(struct hsm_current_action *action);
+extern void lustre_swab_hsm_progress_kernel(struct hsm_progress_kernel *hpk);
+extern void lustre_swab_hsm_user_state(struct hsm_user_state *hus);
+extern void lustre_swab_hsm_user_item(struct hsm_user_item *hui);
+extern void lustre_swab_hsm_request(struct hsm_request *hr);
+
+/**
+ * These are object update opcode under UPDATE_OBJ, which is currently
+ * being used by cross-ref operations between MDT.
+ *
+ * During the cross-ref operation, the Master MDT, which the client send the
+ * request to, will disassembly the operation into object updates, then OSP
+ * will send these updates to the remote MDT to be executed.
+ *
+ *   Update request format
+ *   magic:  UPDATE_BUFFER_MAGIC_V1
+ *   Count:  How many updates in the req.
+ *   bufs[0] : following are packets of object.
+ *   update[0]:
+ *		type: object_update_op, the op code of update
+ *		fid: The object fid of the update.
+ *		lens/bufs: other parameters of the update.
+ *   update[1]:
+ *		type: object_update_op, the op code of update
+ *		fid: The object fid of the update.
+ *		lens/bufs: other parameters of the update.
+ *   ..........
+ *   update[7]:	type: object_update_op, the op code of update
+ *		fid: The object fid of the update.
+ *		lens/bufs: other parameters of the update.
+ *   Current 8 maxim updates per object update request.
+ *
+ *******************************************************************
+ *   update reply format:
+ *
+ *   ur_version: UPDATE_REPLY_V1
+ *   ur_count:   The count of the reply, which is usually equal
+ *		 to the number of updates in the request.
+ *   ur_lens:    The reply lengths of each object update.
+ *
+ *   replies:    1st update reply  [4bytes_ret: other body]
+ *		 2nd update reply  [4bytes_ret: other body]
+ *		 .....
+ *		 nth update reply  [4bytes_ret: other body]
+ *
+ *   For each reply of the update, the format would be
+ *	 result(4 bytes):Other stuff
+ */
+
+#define UPDATE_MAX_OPS		10
+#define UPDATE_BUFFER_MAGIC_V1	0xBDDE0001
+#define UPDATE_BUFFER_MAGIC	UPDATE_BUFFER_MAGIC_V1
+#define UPDATE_BUF_COUNT	8
+enum object_update_op {
+	OBJ_CREATE		= 1,
+	OBJ_DESTROY		= 2,
+	OBJ_REF_ADD		= 3,
+	OBJ_REF_DEL		= 4,
+	OBJ_ATTR_SET		= 5,
+	OBJ_ATTR_GET		= 6,
+	OBJ_XATTR_SET		= 7,
+	OBJ_XATTR_GET		= 8,
+	OBJ_INDEX_LOOKUP	= 9,
+	OBJ_INDEX_INSERT	= 10,
+	OBJ_INDEX_DELETE	= 11,
+	OBJ_LAST
+};
+
+struct update {
+	__u32		u_type;
+	__u32		u_batchid;
+	struct lu_fid	u_fid;
+	__u32		u_lens[UPDATE_BUF_COUNT];
+	__u32		u_bufs[0];
+};
+
+struct update_buf {
+	__u32	ub_magic;
+	__u32	ub_count;
+	__u32	ub_bufs[0];
+};
+
+#define UPDATE_REPLY_V1		0x00BD0001
+struct update_reply {
+	__u32	ur_version;
+	__u32	ur_count;
+	__u32	ur_lens[0];
+};
+
+void lustre_swab_update_buf(struct update_buf *ub);
+void lustre_swab_update_reply_buf(struct update_reply *ur);
+
+/** layout swap request structure
+ * fid1 and fid2 are in mdt_body
+ */
+struct mdc_swap_layouts {
+	__u64	   msl_flags;
+} __packed;
+
+void lustre_swab_swap_layouts(struct mdc_swap_layouts *msl);
+
+#endif
+/** @} lustreidl */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_lfsck_user.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_lfsck_user.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_lfsck_user.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_lfsck_user.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License version 2 for more details.  A copy is
+ * included in the COPYING file that accompanied this code.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * lustre/include/lustre/lustre_lfsck_user.h
+ *
+ * Lustre LFSCK userspace interfaces.
+ *
+ * Author: Fan Yong <yong.fan@whamcloud.com>
+ */
+
+#ifndef _LUSTRE_LFSCK_USER_H
+# define _LUSTRE_LFSCK_USER_H
+
+enum lfsck_param_flags {
+	/* Reset LFSCK iterator position to the device beginning. */
+	LPF_RESET       = 0x0001,
+
+	/* Exit when fail. */
+	LPF_FAILOUT     = 0x0002,
+
+	/* Dryrun mode, only check without modification */
+	LPF_DRYRUN      = 0x0004,
+};
+
+enum lfsck_type {
+	/* For MDT-OST consistency check/repair. */
+	LT_LAYOUT	= 0x0001,
+
+	/* For MDT-MDT consistency check/repair. */
+	LT_DNE		= 0x0002,
+
+	/* For FID-in-dirent and linkEA consistency check/repair. */
+	LT_NAMESPACE	= 0x0004,
+};
+
+#define LFSCK_VERSION_V1	1
+#define LFSCK_VERSION_V2	2
+
+#define LFSCK_TYPES_ALL		((__u16)(~0))
+#define LFSCK_TYPES_DEF		((__u16)0)
+#define LFSCK_TYPES_SUPPORTED	LT_NAMESPACE
+
+#define LFSCK_SPEED_NO_LIMIT	0
+#define LFSCK_SPEED_LIMIT_DEF	LFSCK_SPEED_NO_LIMIT
+
+enum lfsck_start_valid {
+	LSV_SPEED_LIMIT		= 0x00000001,
+	LSV_ERROR_HANDLE	= 0x00000002,
+	LSV_DRYRUN		= 0x00000004,
+};
+
+/* Arguments for starting lfsck. */
+struct lfsck_start {
+	/* Which arguments are valid, see 'enum lfsck_start_valid'. */
+	__u32   ls_valid;
+
+	/* How many items can be scanned at most per second. */
+	__u32   ls_speed_limit;
+
+	/* For compatibility between user space tools and kernel service. */
+	__u16   ls_version;
+
+	/* Which LFSCK components to be (have been) started. */
+	__u16   ls_active;
+
+	/* Flags for the LFSCK, see 'enum lfsck_param_flags'. */
+	__u16   ls_flags;
+
+	/* For 64-bits aligned. */
+	__u16   ls_padding;
+};
+
+#endif /* _LUSTRE_LFSCK_USER_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_user.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_user.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_user.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre/lustre_user.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1145 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2010, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre/lustre_user.h
+ *
+ * Lustre public user-space interface definitions.
+ */
+
+#ifndef _LUSTRE_USER_H
+#define _LUSTRE_USER_H
+
+/** \defgroup lustreuser lustreuser
+ *
+ * @{
+ */
+
+#include <lustre/ll_fiemap.h>
+#include <linux/lustre_user.h>
+
+/* for statfs() */
+#define LL_SUPER_MAGIC 0x0BD00BD0
+
+#ifndef FSFILT_IOC_GETFLAGS
+#define FSFILT_IOC_GETFLAGS	       _IOR('f', 1, long)
+#define FSFILT_IOC_SETFLAGS	       _IOW('f', 2, long)
+#define FSFILT_IOC_GETVERSION	     _IOR('f', 3, long)
+#define FSFILT_IOC_SETVERSION	     _IOW('f', 4, long)
+#define FSFILT_IOC_GETVERSION_OLD	 _IOR('v', 1, long)
+#define FSFILT_IOC_SETVERSION_OLD	 _IOW('v', 2, long)
+#define FSFILT_IOC_FIEMAP		 _IOWR('f', 11, struct ll_user_fiemap)
+#endif
+
+/* FIEMAP flags supported by Lustre */
+#define LUSTRE_FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_DEVICE_ORDER)
+
+enum obd_statfs_state {
+	OS_STATE_DEGRADED       = 0x00000001, /**< RAID degraded/rebuilding */
+	OS_STATE_READONLY       = 0x00000002, /**< filesystem is read-only */
+	OS_STATE_RDONLY_1       = 0x00000004, /**< obsolete 1.6, was EROFS=30 */
+	OS_STATE_RDONLY_2       = 0x00000008, /**< obsolete 1.6, was EROFS=30 */
+	OS_STATE_RDONLY_3       = 0x00000010, /**< obsolete 1.6, was EROFS=30 */
+};
+
+struct obd_statfs {
+	__u64	   os_type;
+	__u64	   os_blocks;
+	__u64	   os_bfree;
+	__u64	   os_bavail;
+	__u64	   os_files;
+	__u64	   os_ffree;
+	__u8	    os_fsid[40];
+	__u32	   os_bsize;
+	__u32	   os_namelen;
+	__u64	   os_maxbytes;
+	__u32	   os_state;       /**< obd_statfs_state OS_STATE_* flag */
+	__u32	   os_fprecreated;	/* objs available now to the caller */
+					/* used in QoS code to find preferred
+					 * OSTs */
+	__u32	   os_spare2;
+	__u32	   os_spare3;
+	__u32	   os_spare4;
+	__u32	   os_spare5;
+	__u32	   os_spare6;
+	__u32	   os_spare7;
+	__u32	   os_spare8;
+	__u32	   os_spare9;
+};
+
+/**
+ * File IDentifier.
+ *
+ * FID is a cluster-wide unique identifier of a file or an object (stripe).
+ * FIDs are never reused.
+ **/
+struct lu_fid {
+       /**
+	* FID sequence. Sequence is a unit of migration: all files (objects)
+	* with FIDs from a given sequence are stored on the same server.
+	* Lustre should support 2^64 objects, so even if each sequence
+	* has only a single object we can still enumerate 2^64 objects.
+	**/
+	__u64 f_seq;
+	/* FID number within sequence. */
+	__u32 f_oid;
+	/**
+	 * FID version, used to distinguish different versions (in the sense
+	 * of snapshots, etc.) of the same file system object. Not currently
+	 * used.
+	 **/
+	__u32 f_ver;
+};
+
+struct filter_fid {
+	struct lu_fid	ff_parent;  /* ff_parent.f_ver == file stripe number */
+};
+
+/* keep this one for compatibility */
+struct filter_fid_old {
+	struct lu_fid	ff_parent;
+	__u64		ff_objid;
+	__u64		ff_seq;
+};
+
+/* Userspace should treat lu_fid as opaque, and only use the following methods
+ * to print or parse them.  Other functions (e.g. compare, swab) could be moved
+ * here from lustre_idl.h if needed. */
+typedef struct lu_fid lustre_fid;
+
+/**
+ * Following struct for object attributes, that will be kept inode's EA.
+ * Introduced in 2.0 release (please see b15993, for details)
+ * Added to all objects since Lustre 2.4 as contains self FID
+ */
+struct lustre_mdt_attrs {
+	/**
+	 * Bitfield for supported data in this structure. From enum lma_compat.
+	 * lma_self_fid and lma_flags are always available.
+	 */
+	__u32   lma_compat;
+	/**
+	 * Per-file incompat feature list. Lustre version should support all
+	 * flags set in this field. The supported feature mask is available in
+	 * LMA_INCOMPAT_SUPP.
+	 */
+	__u32   lma_incompat;
+	/** FID of this inode */
+	struct lu_fid  lma_self_fid;
+};
+
+/**
+ * Prior to 2.4, the LMA structure also included SOM attributes which has since
+ * been moved to a dedicated xattr
+ * lma_flags was also removed because of lma_compat/incompat fields.
+ */
+#define LMA_OLD_SIZE (sizeof(struct lustre_mdt_attrs) + 5 * sizeof(__u64))
+
+/**
+ * OST object IDentifier.
+ */
+struct ost_id {
+	union {
+		struct ostid {
+			__u64	oi_id;
+			__u64	oi_seq;
+		} oi;
+		struct lu_fid oi_fid;
+	};
+};
+
+#define DOSTID LPX64":"LPU64
+#define POSTID(oi) ostid_seq(oi), ostid_id(oi)
+
+/*
+ * The ioctl naming rules:
+ * LL_*     - works on the currently opened filehandle instead of parent dir
+ * *_OBD_*  - gets data for both OSC or MDC (LOV, LMV indirectly)
+ * *_MDC_*  - gets/sets data related to MDC
+ * *_LOV_*  - gets/sets data related to OSC/LOV
+ * *FILE*   - called on parent dir and passes in a filename
+ * *STRIPE* - set/get lov_user_md
+ * *INFO    - set/get lov_user_mds_data
+ */
+/* see <lustre_lib.h> for ioctl numberss 101-150 */
+#define LL_IOC_GETFLAGS		 _IOR ('f', 151, long)
+#define LL_IOC_SETFLAGS		 _IOW ('f', 152, long)
+#define LL_IOC_CLRFLAGS		 _IOW ('f', 153, long)
+/* LL_IOC_LOV_SETSTRIPE: See also OBD_IOC_LOV_SETSTRIPE */
+#define LL_IOC_LOV_SETSTRIPE	    _IOW ('f', 154, long)
+/* LL_IOC_LOV_GETSTRIPE: See also OBD_IOC_LOV_GETSTRIPE */
+#define LL_IOC_LOV_GETSTRIPE	    _IOW ('f', 155, long)
+/* LL_IOC_LOV_SETEA: See also OBD_IOC_LOV_SETEA */
+#define LL_IOC_LOV_SETEA		_IOW ('f', 156, long)
+#define LL_IOC_RECREATE_OBJ	     _IOW ('f', 157, long)
+#define LL_IOC_RECREATE_FID	     _IOW ('f', 157, struct lu_fid)
+#define LL_IOC_GROUP_LOCK	       _IOW ('f', 158, long)
+#define LL_IOC_GROUP_UNLOCK	     _IOW ('f', 159, long)
+/* LL_IOC_QUOTACHECK: See also OBD_IOC_QUOTACHECK */
+#define LL_IOC_QUOTACHECK	       _IOW ('f', 160, int)
+/* LL_IOC_POLL_QUOTACHECK: See also OBD_IOC_POLL_QUOTACHECK */
+#define LL_IOC_POLL_QUOTACHECK	  _IOR ('f', 161, struct if_quotacheck *)
+/* LL_IOC_QUOTACTL: See also OBD_IOC_QUOTACTL */
+#define LL_IOC_QUOTACTL		 _IOWR('f', 162, struct if_quotactl)
+#define IOC_OBD_STATFS		  _IOWR('f', 164, struct obd_statfs *)
+#define IOC_LOV_GETINFO		 _IOWR('f', 165, struct lov_user_mds_data *)
+#define LL_IOC_FLUSHCTX		 _IOW ('f', 166, long)
+#define LL_IOC_RMTACL		   _IOW ('f', 167, long)
+#define LL_IOC_GETOBDCOUNT	      _IOR ('f', 168, long)
+#define LL_IOC_LLOOP_ATTACH	     _IOWR('f', 169, long)
+#define LL_IOC_LLOOP_DETACH	     _IOWR('f', 170, long)
+#define LL_IOC_LLOOP_INFO	       _IOWR('f', 171, struct lu_fid)
+#define LL_IOC_LLOOP_DETACH_BYDEV       _IOWR('f', 172, long)
+#define LL_IOC_PATH2FID		 _IOR ('f', 173, long)
+#define LL_IOC_GET_CONNECT_FLAGS	_IOWR('f', 174, __u64 *)
+#define LL_IOC_GET_MDTIDX	       _IOR ('f', 175, int)
+
+/* see <lustre_lib.h> for ioctl numbers 177-210 */
+
+#define LL_IOC_HSM_STATE_GET		_IOR('f', 211, struct hsm_user_state)
+#define LL_IOC_HSM_STATE_SET		_IOW('f', 212, struct hsm_state_set)
+#define LL_IOC_HSM_CT_START		_IOW('f', 213, struct lustre_kernelcomm)
+#define LL_IOC_HSM_COPY_START		_IOW('f', 214, struct hsm_copy *)
+#define LL_IOC_HSM_COPY_END		_IOW('f', 215, struct hsm_copy *)
+#define LL_IOC_HSM_PROGRESS		_IOW('f', 216, struct hsm_user_request)
+#define LL_IOC_HSM_REQUEST		_IOW('f', 217, struct hsm_user_request)
+#define LL_IOC_DATA_VERSION		_IOR('f', 218, struct ioc_data_version)
+#define LL_IOC_LOV_SWAP_LAYOUTS		_IOW('f', 219, \
+						struct lustre_swap_layouts)
+#define LL_IOC_HSM_ACTION		_IOR('f', 220, \
+						struct hsm_current_action)
+/* see <lustre_lib.h> for ioctl numbers 221-232 */
+
+#define LL_IOC_LMV_SETSTRIPE	    _IOWR('f', 240, struct lmv_user_md)
+#define LL_IOC_LMV_GETSTRIPE	    _IOWR('f', 241, struct lmv_user_md)
+#define LL_IOC_REMOVE_ENTRY	    _IOWR('f', 242, __u64)
+
+#define LL_STATFS_LMV	   1
+#define LL_STATFS_LOV	   2
+#define LL_STATFS_NODELAY	4
+
+#define IOC_MDC_TYPE	    'i'
+#define IOC_MDC_LOOKUP	  _IOWR(IOC_MDC_TYPE, 20, struct obd_device *)
+#define IOC_MDC_GETFILESTRIPE   _IOWR(IOC_MDC_TYPE, 21, struct lov_user_md *)
+#define IOC_MDC_GETFILEINFO     _IOWR(IOC_MDC_TYPE, 22, struct lov_user_mds_data *)
+#define LL_IOC_MDC_GETINFO      _IOWR(IOC_MDC_TYPE, 23, struct lov_user_mds_data *)
+
+/* Keep these for backward compartability. */
+#define LL_IOC_OBD_STATFS       IOC_OBD_STATFS
+#define IOC_MDC_GETSTRIPE       IOC_MDC_GETFILESTRIPE
+
+
+#define MAX_OBD_NAME 128 /* If this changes, a NEW ioctl must be added */
+
+/* Hopefully O_LOV_DELAY_CREATE does not conflict with standard O_xxx flags.
+ * Previously it was defined as 0100000000 and conflicts with FMODE_NONOTIFY
+ * which was added since kernel 2.6.36, so we redefine it as 020000000.
+ * To be compatible with old version's statically linked binary, finally we
+ * define it as (020000000 | 0100000000).
+ * */
+#define O_LOV_DELAY_CREATE      0120000000
+
+#define LL_FILE_IGNORE_LOCK     0x00000001
+#define LL_FILE_GROUP_LOCKED    0x00000002
+#define LL_FILE_READAHEA	0x00000004
+#define LL_FILE_LOCKED_DIRECTIO 0x00000008 /* client-side locks with dio */
+#define LL_FILE_LOCKLESS_IO     0x00000010 /* server-side locks with cio */
+#define LL_FILE_RMTACL	  0x00000020
+
+#define LOV_USER_MAGIC_V1 0x0BD10BD0
+#define LOV_USER_MAGIC    LOV_USER_MAGIC_V1
+#define LOV_USER_MAGIC_JOIN_V1 0x0BD20BD0
+#define LOV_USER_MAGIC_V3 0x0BD30BD0
+
+#define LMV_MAGIC_V1      0x0CD10CD0    /*normal stripe lmv magic */
+#define LMV_USER_MAGIC    0x0CD20CD0    /*default lmv magic*/
+
+#define LOV_PATTERN_RAID0 0x001
+#define LOV_PATTERN_RAID1 0x002
+#define LOV_PATTERN_FIRST 0x100
+
+#define LOV_MAXPOOLNAME 16
+#define LOV_POOLNAMEF "%.16s"
+
+#define LOV_MIN_STRIPE_BITS 16   /* maximum PAGE_SIZE (ia64), power of 2 */
+#define LOV_MIN_STRIPE_SIZE (1 << LOV_MIN_STRIPE_BITS)
+#define LOV_MAX_STRIPE_COUNT_OLD 160
+/* This calculation is crafted so that input of 4096 will result in 160
+ * which in turn is equal to old maximal stripe count.
+ * XXX: In fact this is too simpified for now, what it also need is to get
+ * ea_type argument to clearly know how much space each stripe consumes.
+ *
+ * The limit of 12 pages is somewhat arbitrary, but is a reasonably large
+ * allocation that is sufficient for the current generation of systems.
+ *
+ * (max buffer size - lov+rpc header) / sizeof(struct lov_ost_data_v1) */
+#define LOV_MAX_STRIPE_COUNT 2000  /* ((12 * 4096 - 256) / 24) */
+#define LOV_ALL_STRIPES       0xffff /* only valid for directories */
+#define LOV_V1_INSANE_STRIPE_COUNT 65532 /* maximum stripe count bz13933 */
+
+#define lov_user_ost_data lov_user_ost_data_v1
+struct lov_user_ost_data_v1 {     /* per-stripe data structure */
+	struct ost_id l_ost_oi;	  /* OST object ID */
+	__u32 l_ost_gen;	  /* generation of this OST index */
+	__u32 l_ost_idx;	  /* OST index in LOV */
+} __attribute__((packed));
+
+#define lov_user_md lov_user_md_v1
+struct lov_user_md_v1 {	   /* LOV EA user data (host-endian) */
+	__u32 lmm_magic;	  /* magic number = LOV_USER_MAGIC_V1 */
+	__u32 lmm_pattern;	/* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
+	struct ost_id lmm_oi;	  /* LOV object ID */
+	__u32 lmm_stripe_size;    /* size of stripe in bytes */
+	__u16 lmm_stripe_count;   /* num stripes in use for this object */
+	union {
+		__u16 lmm_stripe_offset;  /* starting stripe offset in
+					   * lmm_objects, use when writing */
+		__u16 lmm_layout_gen;     /* layout generation number
+					   * used when reading */
+	};
+	struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */
+} __attribute__((packed,  __may_alias__));
+
+struct lov_user_md_v3 {	   /* LOV EA user data (host-endian) */
+	__u32 lmm_magic;	  /* magic number = LOV_USER_MAGIC_V3 */
+	__u32 lmm_pattern;	/* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
+	struct ost_id lmm_oi;	  /* LOV object ID */
+	__u32 lmm_stripe_size;    /* size of stripe in bytes */
+	__u16 lmm_stripe_count;   /* num stripes in use for this object */
+	union {
+		__u16 lmm_stripe_offset;  /* starting stripe offset in
+					   * lmm_objects, use when writing */
+		__u16 lmm_layout_gen;     /* layout generation number
+					   * used when reading */
+	};
+	char  lmm_pool_name[LOV_MAXPOOLNAME]; /* pool name */
+	struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */
+} __attribute__((packed));
+
+/* Compile with -D_LARGEFILE64_SOURCE or -D_GNU_SOURCE (or #define) to
+ * use this.  It is unsafe to #define those values in this header as it
+ * is possible the application has already #included <sys/stat.h>. */
+#ifdef HAVE_LOV_USER_MDS_DATA
+#define lov_user_mds_data lov_user_mds_data_v1
+struct lov_user_mds_data_v1 {
+	lstat_t lmd_st;		 /* MDS stat struct */
+	struct lov_user_md_v1 lmd_lmm;  /* LOV EA V1 user data */
+} __attribute__((packed));
+
+struct lov_user_mds_data_v3 {
+	lstat_t lmd_st;		 /* MDS stat struct */
+	struct lov_user_md_v3 lmd_lmm;  /* LOV EA V3 user data */
+} __attribute__((packed));
+#endif
+
+/* keep this to be the same size as lov_user_ost_data_v1 */
+struct lmv_user_mds_data {
+	struct lu_fid	lum_fid;
+	__u32		lum_padding;
+	__u32		lum_mds;
+};
+
+/* lum_type */
+enum {
+	LMV_STRIPE_TYPE = 0,
+	LMV_DEFAULT_TYPE = 1,
+};
+
+#define lmv_user_md lmv_user_md_v1
+struct lmv_user_md_v1 {
+	__u32	lum_magic;	 /* must be the first field */
+	__u32	lum_stripe_count;  /* dirstripe count */
+	__u32	lum_stripe_offset; /* MDT idx for default dirstripe */
+	__u32	lum_hash_type;     /* Dir stripe policy */
+	__u32	lum_type;	  /* LMV type: default or normal */
+	__u32	lum_padding1;
+	__u32	lum_padding2;
+	__u32	lum_padding3;
+	char	lum_pool_name[LOV_MAXPOOLNAME];
+	struct	lmv_user_mds_data  lum_objects[0];
+};
+
+static inline int lmv_user_md_size(int stripes, int lmm_magic)
+{
+	return sizeof(struct lmv_user_md) +
+		      stripes * sizeof(struct lmv_user_mds_data);
+}
+
+extern void lustre_swab_lmv_user_md(struct lmv_user_md *lum);
+
+struct ll_recreate_obj {
+	__u64 lrc_id;
+	__u32 lrc_ost_idx;
+};
+
+struct ll_fid {
+	__u64 id;	 /* holds object id */
+	__u32 generation; /* holds object generation */
+	__u32 f_type;     /* holds object type or stripe idx when passing it to
+			   * OST for saving into EA. */
+};
+
+#define UUID_MAX	40
+struct obd_uuid {
+	char uuid[UUID_MAX];
+};
+
+static inline int obd_uuid_equals(const struct obd_uuid *u1,
+				  const struct obd_uuid *u2)
+{
+	return strcmp((char *)u1->uuid, (char *)u2->uuid) == 0;
+}
+
+static inline int obd_uuid_empty(struct obd_uuid *uuid)
+{
+	return uuid->uuid[0] == '\0';
+}
+
+static inline void obd_str2uuid(struct obd_uuid *uuid, const char *tmp)
+{
+	strncpy((char *)uuid->uuid, tmp, sizeof(*uuid));
+	uuid->uuid[sizeof(*uuid) - 1] = '\0';
+}
+
+/* For printf's only, make sure uuid is terminated */
+static inline char *obd_uuid2str(struct obd_uuid *uuid)
+{
+	if (uuid->uuid[sizeof(*uuid) - 1] != '\0') {
+		/* Obviously not safe, but for printfs, no real harm done...
+		   we're always null-terminated, even in a race. */
+		static char temp[sizeof(*uuid)];
+		memcpy(temp, uuid->uuid, sizeof(*uuid) - 1);
+		temp[sizeof(*uuid) - 1] = '\0';
+		return temp;
+	}
+	return (char *)(uuid->uuid);
+}
+
+/* Extract fsname from uuid (or target name) of a target
+   e.g. (myfs-OST0007_UUID -> myfs)
+   see also deuuidify. */
+static inline void obd_uuid2fsname(char *buf, char *uuid, int buflen)
+{
+	char *p;
+
+	strncpy(buf, uuid, buflen - 1);
+	buf[buflen - 1] = '\0';
+	p = strrchr(buf, '-');
+	if (p)
+	   *p = '\0';
+}
+
+/* printf display format
+   e.g. printf("file FID is "DFID"\n", PFID(fid)); */
+#define DFID_NOBRACE LPX64":0x%x:0x%x"
+#define DFID "["DFID_NOBRACE"]"
+#define PFID(fid)     \
+	(fid)->f_seq, \
+	(fid)->f_oid, \
+	(fid)->f_ver
+
+/* scanf input parse format -- strip '[' first.
+   e.g. sscanf(fidstr, SFID, RFID(&fid)); */
+/* #define SFID "0x"LPX64i":0x"LPSZX":0x"LPSZX""
+liblustreapi.c:2893: warning: format '%lx' expects type 'long unsigned int *', but argument 4 has type 'unsigned int *'
+liblustreapi.c:2893: warning: format '%lx' expects type 'long unsigned int *', but argument 5 has type 'unsigned int *'
+*/
+#define SFID "0x"LPX64i":0x%x:0x%x"
+#define RFID(fid)     \
+	&((fid)->f_seq), \
+	&((fid)->f_oid), \
+	&((fid)->f_ver)
+
+
+/********* Quotas **********/
+
+/* these must be explicitly translated into linux Q_* in ll_dir_ioctl */
+#define LUSTRE_Q_QUOTAON    0x800002     /* turn quotas on */
+#define LUSTRE_Q_QUOTAOFF   0x800003     /* turn quotas off */
+#define LUSTRE_Q_GETINFO    0x800005     /* get information about quota files */
+#define LUSTRE_Q_SETINFO    0x800006     /* set information about quota files */
+#define LUSTRE_Q_GETQUOTA   0x800007     /* get user quota structure */
+#define LUSTRE_Q_SETQUOTA   0x800008     /* set user quota structure */
+/* lustre-specific control commands */
+#define LUSTRE_Q_INVALIDATE  0x80000b     /* invalidate quota data */
+#define LUSTRE_Q_FINVALIDATE 0x80000c     /* invalidate filter quota data */
+
+#define UGQUOTA 2       /* set both USRQUOTA and GRPQUOTA */
+
+struct if_quotacheck {
+	char		    obd_type[16];
+	struct obd_uuid	 obd_uuid;
+};
+
+#define IDENTITY_DOWNCALL_MAGIC 0x6d6dd629
+
+/* permission */
+#define N_PERMS_MAX      64
+
+struct perm_downcall_data {
+	__u64 pdd_nid;
+	__u32 pdd_perm;
+	__u32 pdd_padding;
+};
+
+struct identity_downcall_data {
+	__u32			    idd_magic;
+	__u32			    idd_err;
+	__u32			    idd_uid;
+	__u32			    idd_gid;
+	__u32			    idd_nperms;
+	__u32			    idd_ngroups;
+	struct perm_downcall_data idd_perms[N_PERMS_MAX];
+	__u32			    idd_groups[0];
+};
+
+/* for non-mapped uid/gid */
+#define NOBODY_UID      99
+#define NOBODY_GID      99
+
+#define INVALID_ID      (-1)
+
+enum {
+	RMT_LSETFACL    = 1,
+	RMT_LGETFACL    = 2,
+	RMT_RSETFACL    = 3,
+	RMT_RGETFACL    = 4
+};
+
+#ifdef NEED_QUOTA_DEFS
+#ifndef QIF_BLIMITS
+#define QIF_BLIMITS     1
+#define QIF_SPACE       2
+#define QIF_ILIMITS     4
+#define QIF_INODES      8
+#define QIF_BTIME       16
+#define QIF_ITIME       32
+#define QIF_LIMITS      (QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE       (QIF_SPACE | QIF_INODES)
+#define QIF_TIMES       (QIF_BTIME | QIF_ITIME)
+#define QIF_ALL	 (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+#endif
+
+#endif /* !__KERNEL__ */
+
+/* lustre volatile file support
+ * file name header: .^L^S^T^R:volatile"
+ */
+#define LUSTRE_VOLATILE_HDR	".\x0c\x13\x14\x12:VOLATILE"
+#define LUSTRE_VOLATILE_HDR_LEN	14
+/* hdr + MDT index */
+#define LUSTRE_VOLATILE_IDX	LUSTRE_VOLATILE_HDR":%.4X:"
+
+typedef enum lustre_quota_version {
+	LUSTRE_QUOTA_V2 = 1
+} lustre_quota_version_t;
+
+/* XXX: same as if_dqinfo struct in kernel */
+struct obd_dqinfo {
+	__u64 dqi_bgrace;
+	__u64 dqi_igrace;
+	__u32 dqi_flags;
+	__u32 dqi_valid;
+};
+
+/* XXX: same as if_dqblk struct in kernel, plus one padding */
+struct obd_dqblk {
+	__u64 dqb_bhardlimit;
+	__u64 dqb_bsoftlimit;
+	__u64 dqb_curspace;
+	__u64 dqb_ihardlimit;
+	__u64 dqb_isoftlimit;
+	__u64 dqb_curinodes;
+	__u64 dqb_btime;
+	__u64 dqb_itime;
+	__u32 dqb_valid;
+	__u32 dqb_padding;
+};
+
+enum {
+	QC_GENERAL      = 0,
+	QC_MDTIDX       = 1,
+	QC_OSTIDX       = 2,
+	QC_UUID	 = 3
+};
+
+struct if_quotactl {
+	__u32		   qc_cmd;
+	__u32		   qc_type;
+	__u32		   qc_id;
+	__u32		   qc_stat;
+	__u32		   qc_valid;
+	__u32		   qc_idx;
+	struct obd_dqinfo       qc_dqinfo;
+	struct obd_dqblk	qc_dqblk;
+	char		    obd_type[16];
+	struct obd_uuid	 obd_uuid;
+};
+
+/* swap layout flags */
+#define	SWAP_LAYOUTS_CHECK_DV1		(1 << 0)
+#define	SWAP_LAYOUTS_CHECK_DV2		(1 << 1)
+#define	SWAP_LAYOUTS_KEEP_MTIME		(1 << 2)
+#define	SWAP_LAYOUTS_KEEP_ATIME		(1 << 3)
+struct lustre_swap_layouts {
+	__u64	sl_flags;
+	__u32	sl_fd;
+	__u32	sl_gid;
+	__u64	sl_dv1;
+	__u64	sl_dv2;
+};
+
+
+/********* Changelogs **********/
+/** Changelog record types */
+enum changelog_rec_type {
+	CL_MARK     = 0,
+	CL_CREATE   = 1,  /* namespace */
+	CL_MKDIR    = 2,  /* namespace */
+	CL_HARDLINK = 3,  /* namespace */
+	CL_SOFTLINK = 4,  /* namespace */
+	CL_MKNOD    = 5,  /* namespace */
+	CL_UNLINK   = 6,  /* namespace */
+	CL_RMDIR    = 7,  /* namespace */
+	CL_RENAME   = 8,  /* namespace */
+	CL_EXT      = 9,  /* namespace extended record (2nd half of rename) */
+	CL_OPEN     = 10, /* not currently used */
+	CL_CLOSE    = 11, /* may be written to log only with mtime change */
+	CL_LAYOUT   = 12, /* file layout/striping modified */
+	CL_TRUNC    = 13,
+	CL_SETATTR  = 14,
+	CL_XATTR    = 15,
+	CL_HSM      = 16, /* HSM specific events, see flags */
+	CL_MTIME    = 17, /* Precedence: setattr > mtime > ctime > atime */
+	CL_CTIME    = 18,
+	CL_ATIME    = 19,
+	CL_LAST
+};
+
+static inline const char *changelog_type2str(int type) {
+	static const char *changelog_str[] = {
+		"MARK",  "CREAT", "MKDIR", "HLINK", "SLINK", "MKNOD", "UNLNK",
+		"RMDIR", "RENME", "RNMTO", "OPEN",  "CLOSE", "LYOUT", "TRUNC",
+		"SATTR", "XATTR", "HSM",   "MTIME", "CTIME", "ATIME",
+	};
+
+	if (type >= 0 && type < CL_LAST)
+		return changelog_str[type];
+	return NULL;
+}
+
+/* per-record flags */
+#define CLF_VERSION     0x1000
+#define CLF_EXT_VERSION 0x2000
+#define CLF_FLAGSHIFT   12
+#define CLF_FLAGMASK    ((1U << CLF_FLAGSHIFT) - 1)
+#define CLF_VERMASK     (~CLF_FLAGMASK)
+/* Anything under the flagmask may be per-type (if desired) */
+/* Flags for unlink */
+#define CLF_UNLINK_LAST       0x0001 /* Unlink of last hardlink */
+#define CLF_UNLINK_HSM_EXISTS 0x0002 /* File has something in HSM */
+				     /* HSM cleaning needed */
+/* Flags for rename */
+#define CLF_RENAME_LAST       0x0001 /* rename unlink last hardlink of target */
+
+/* Flags for HSM */
+/* 12b used (from high weight to low weight):
+ * 2b for flags
+ * 3b for event
+ * 7b for error code
+ */
+#define CLF_HSM_ERR_L	0 /* HSM return code, 7 bits */
+#define CLF_HSM_ERR_H	6
+#define CLF_HSM_EVENT_L      7 /* HSM event, 3 bits, see enum hsm_event */
+#define CLF_HSM_EVENT_H      9
+#define CLF_HSM_FLAG_L      10 /* HSM flags, 2 bits, 1 used, 1 spare */
+#define CLF_HSM_FLAG_H      11
+#define CLF_HSM_SPARE_L     12 /* 4 spare bits */
+#define CLF_HSM_SPARE_H     15
+#define CLF_HSM_LAST	15
+
+/* Remove bits higher than _h, then extract the value
+ * between _h and _l by shifting lower weigth to bit 0. */
+#define CLF_GET_BITS(_b, _h, _l) (((_b << (CLF_HSM_LAST - _h)) & 0xFFFF) \
+				   >> (CLF_HSM_LAST - _h + _l))
+
+#define CLF_HSM_SUCCESS      0x00
+#define CLF_HSM_MAXERROR     0x7E
+#define CLF_HSM_ERROVERFLOW  0x7F
+
+#define CLF_HSM_DIRTY	1 /* file is dirty after HSM request end */
+
+/* 3 bits field => 8 values allowed */
+enum hsm_event {
+	HE_ARCHIVE      = 0,
+	HE_RESTORE      = 1,
+	HE_CANCEL       = 2,
+	HE_RELEASE      = 3,
+	HE_REMOVE       = 4,
+	HE_STATE	= 5,
+	HE_SPARE1       = 6,
+	HE_SPARE2       = 7,
+};
+
+static inline enum hsm_event hsm_get_cl_event(__u16 flags)
+{
+	return CLF_GET_BITS(flags, CLF_HSM_EVENT_H, CLF_HSM_EVENT_L);
+}
+
+static inline void hsm_set_cl_event(int *flags, enum hsm_event he)
+{
+	*flags |= (he << CLF_HSM_EVENT_L);
+}
+
+static inline __u16 hsm_get_cl_flags(int flags)
+{
+	return CLF_GET_BITS(flags, CLF_HSM_FLAG_H, CLF_HSM_FLAG_L);
+}
+
+static inline void hsm_set_cl_flags(int *flags, int bits)
+{
+	*flags |= (bits << CLF_HSM_FLAG_L);
+}
+
+static inline int hsm_get_cl_error(int flags)
+{
+	return CLF_GET_BITS(flags, CLF_HSM_ERR_H, CLF_HSM_ERR_L);
+}
+
+static inline void hsm_set_cl_error(int *flags, int error)
+{
+	*flags |= (error << CLF_HSM_ERR_L);
+}
+
+#define CR_MAXSIZE cfs_size_round(2*NAME_MAX + 1 + sizeof(struct changelog_rec))
+
+struct changelog_rec {
+	__u16		 cr_namelen;
+	__u16		 cr_flags; /**< (flags&CLF_FLAGMASK)|CLF_VERSION */
+	__u32		 cr_type;  /**< \a changelog_rec_type */
+	__u64		 cr_index; /**< changelog record number */
+	__u64		 cr_prev;  /**< last index for this target fid */
+	__u64		 cr_time;
+	union {
+		lustre_fid    cr_tfid;	/**< target fid */
+		__u32	 cr_markerflags; /**< CL_MARK flags */
+	};
+	lustre_fid	    cr_pfid;	/**< parent fid */
+	char		  cr_name[0];     /**< last element */
+} __attribute__((packed));
+
+/* changelog_ext_rec is 2*sizeof(lu_fid) bigger than changelog_rec, to save
+ * space, only rename uses changelog_ext_rec, while others use changelog_rec to
+ * store records.
+ */
+struct changelog_ext_rec {
+	__u16			cr_namelen;
+	__u16			cr_flags; /**< (flags & CLF_FLAGMASK) |
+						CLF_EXT_VERSION */
+	__u32			cr_type;  /**< \a changelog_rec_type */
+	__u64			cr_index; /**< changelog record number */
+	__u64			cr_prev;  /**< last index for this target fid */
+	__u64			cr_time;
+	union {
+		lustre_fid	cr_tfid;	/**< target fid */
+		__u32		cr_markerflags; /**< CL_MARK flags */
+	};
+	lustre_fid		cr_pfid;	/**< target parent fid */
+	lustre_fid		cr_sfid;	/**< source fid, or zero */
+	lustre_fid		cr_spfid;       /**< source parent fid, or zero */
+	char			cr_name[0];     /**< last element */
+} __attribute__((packed));
+
+#define CHANGELOG_REC_EXTENDED(rec) \
+	(((rec)->cr_flags & CLF_VERMASK) == CLF_EXT_VERSION)
+
+static inline int changelog_rec_size(struct changelog_rec *rec)
+{
+	return CHANGELOG_REC_EXTENDED(rec) ? sizeof(struct changelog_ext_rec):
+					     sizeof(*rec);
+}
+
+static inline char *changelog_rec_name(struct changelog_rec *rec)
+{
+	return CHANGELOG_REC_EXTENDED(rec) ?
+		((struct changelog_ext_rec *)rec)->cr_name: rec->cr_name;
+}
+
+static inline int changelog_rec_snamelen(struct changelog_ext_rec *rec)
+{
+	return rec->cr_namelen - strlen(rec->cr_name) - 1;
+}
+
+static inline char *changelog_rec_sname(struct changelog_ext_rec *rec)
+{
+	return rec->cr_name + strlen(rec->cr_name) + 1;
+}
+
+struct ioc_changelog {
+	__u64 icc_recno;
+	__u32 icc_mdtindex;
+	__u32 icc_id;
+	__u32 icc_flags;
+};
+
+enum changelog_message_type {
+	CL_RECORD = 10, /* message is a changelog_rec */
+	CL_EOF    = 11, /* at end of current changelog */
+};
+
+/********* Misc **********/
+
+struct ioc_data_version {
+	__u64 idv_version;
+	__u64 idv_flags;     /* See LL_DV_xxx */
+};
+#define LL_DV_NOFLUSH 0x01   /* Do not take READ EXTENT LOCK before sampling
+				version. Dirty caches are left unchanged. */
+
+#ifndef offsetof
+# define offsetof(typ,memb)     ((unsigned long)((char *)&(((typ *)0)->memb)))
+#endif
+
+#define dot_lustre_name ".lustre"
+
+
+/********* HSM **********/
+
+/** HSM per-file state
+ * See HSM_FLAGS below.
+ */
+enum hsm_states {
+	HS_EXISTS	= 0x00000001,
+	HS_DIRTY	= 0x00000002,
+	HS_RELEASED	= 0x00000004,
+	HS_ARCHIVED	= 0x00000008,
+	HS_NORELEASE	= 0x00000010,
+	HS_NOARCHIVE	= 0x00000020,
+	HS_LOST		= 0x00000040,
+};
+
+/* HSM user-setable flags. */
+#define HSM_USER_MASK   (HS_NORELEASE | HS_NOARCHIVE | HS_DIRTY)
+
+/* Other HSM flags. */
+#define HSM_STATUS_MASK (HS_EXISTS | HS_LOST | HS_RELEASED | HS_ARCHIVED)
+
+/*
+ * All HSM-related possible flags that could be applied to a file.
+ * This should be kept in sync with hsm_states.
+ */
+#define HSM_FLAGS_MASK  (HSM_USER_MASK | HSM_STATUS_MASK)
+
+/**
+ * HSM request progress state
+ */
+enum hsm_progress_states {
+	HPS_WAITING	= 1,
+	HPS_RUNNING	= 2,
+	HPS_DONE	= 3,
+};
+#define HPS_NONE	0
+
+static inline char *hsm_progress_state2name(enum hsm_progress_states s)
+{
+	switch  (s) {
+	case HPS_WAITING:	return "waiting";
+	case HPS_RUNNING:	return "running";
+	case HPS_DONE:		return "done";
+	default:		return "unknown";
+	}
+}
+
+struct hsm_extent {
+	__u64 offset;
+	__u64 length;
+} __attribute__((packed));
+
+/**
+ * Current HSM states of a Lustre file.
+ *
+ * This structure purpose is to be sent to user-space mainly. It describes the
+ * current HSM flags and in-progress action.
+ */
+struct hsm_user_state {
+	/** Current HSM states, from enum hsm_states. */
+	__u32			hus_states;
+	__u32			hus_archive_id;
+	/**  The current undergoing action, if there is one */
+	__u32			hus_in_progress_state;
+	__u32			hus_in_progress_action;
+	struct hsm_extent	hus_in_progress_location;
+	char			hus_extended_info[];
+};
+
+struct hsm_state_set_ioc {
+	struct lu_fid	hssi_fid;
+	__u64		hssi_setmask;
+	__u64		hssi_clearmask;
+};
+
+/*
+ * This structure describes the current in-progress action for a file.
+ * it is retuned to user space and send over the wire
+ */
+struct hsm_current_action {
+	/**  The current undergoing action, if there is one */
+	/* state is one of hsm_progress_states */
+	__u32			hca_state;
+	/* action is one of hsm_user_action */
+	__u32			hca_action;
+	struct hsm_extent	hca_location;
+};
+
+/***** HSM user requests ******/
+/* User-generated (lfs/ioctl) request types */
+enum hsm_user_action {
+	HUA_NONE    =  1, /* no action (noop) */
+	HUA_ARCHIVE = 10, /* copy to hsm */
+	HUA_RESTORE = 11, /* prestage */
+	HUA_RELEASE = 12, /* drop ost objects */
+	HUA_REMOVE  = 13, /* remove from archive */
+	HUA_CANCEL  = 14  /* cancel a request */
+};
+
+static inline char *hsm_user_action2name(enum hsm_user_action  a)
+{
+	switch  (a) {
+	case HUA_NONE:    return "NOOP";
+	case HUA_ARCHIVE: return "ARCHIVE";
+	case HUA_RESTORE: return "RESTORE";
+	case HUA_RELEASE: return "RELEASE";
+	case HUA_REMOVE:  return "REMOVE";
+	case HUA_CANCEL:  return "CANCEL";
+	default:	  return "UNKNOWN";
+	}
+}
+
+/*
+ * List of hr_flags (bit field)
+ */
+#define HSM_FORCE_ACTION 0x0001
+/* used by CT, connot be set by user */
+#define HSM_GHOST_COPY   0x0002
+
+/**
+ * Contains all the fixed part of struct hsm_user_request.
+ *
+ */
+struct hsm_request {
+	__u32 hr_action;	/* enum hsm_user_action */
+	__u32 hr_archive_id;	/* archive id, used only with HUA_ARCHIVE */
+	__u64 hr_flags;		/* request flags */
+	__u32 hr_itemcount;	/* item count in hur_user_item vector */
+	__u32 hr_data_len;
+};
+
+struct hsm_user_item {
+       lustre_fid	hui_fid;
+       struct hsm_extent hui_extent;
+} __attribute__((packed));
+
+struct hsm_user_request {
+	struct hsm_request	hur_request;
+	struct hsm_user_item	hur_user_item[0];
+	/* extra data blob at end of struct (after all
+	 * hur_user_items), only use helpers to access it
+	 */
+} __attribute__((packed));
+
+/** Return pointer to data field in a hsm user request */
+static inline void *hur_data(struct hsm_user_request *hur)
+{
+	return &(hur->hur_user_item[hur->hur_request.hr_itemcount]);
+}
+
+/** Compute the current length of the provided hsm_user_request. */
+static inline int hur_len(struct hsm_user_request *hur)
+{
+	return offsetof(struct hsm_user_request,
+			hur_user_item[hur->hur_request.hr_itemcount]) +
+		hur->hur_request.hr_data_len;
+}
+
+/****** HSM RPCs to copytool *****/
+/* Message types the copytool may receive */
+enum hsm_message_type {
+	HMT_ACTION_LIST = 100, /* message is a hsm_action_list */
+};
+
+/* Actions the copytool may be instructed to take for a given action_item */
+enum hsm_copytool_action {
+	HSMA_NONE    = 10, /* no action */
+	HSMA_ARCHIVE = 20, /* arbitrary offset */
+	HSMA_RESTORE = 21,
+	HSMA_REMOVE  = 22,
+	HSMA_CANCEL  = 23
+};
+
+static inline char *hsm_copytool_action2name(enum hsm_copytool_action  a)
+{
+	switch  (a) {
+	case HSMA_NONE:    return "NOOP";
+	case HSMA_ARCHIVE: return "ARCHIVE";
+	case HSMA_RESTORE: return "RESTORE";
+	case HSMA_REMOVE:  return "REMOVE";
+	case HSMA_CANCEL:  return "CANCEL";
+	default:	   return "UNKNOWN";
+	}
+}
+
+/* Copytool item action description */
+struct hsm_action_item {
+	__u32      hai_len;     /* valid size of this struct */
+	__u32      hai_action;  /* hsm_copytool_action, but use known size */
+	lustre_fid hai_fid;     /* Lustre FID to operated on */
+	lustre_fid hai_dfid;    /* fid used for data access */
+	struct hsm_extent hai_extent;  /* byte range to operate on */
+	__u64      hai_cookie;  /* action cookie from coordinator */
+	__u64      hai_gid;     /* grouplock id */
+	char       hai_data[0]; /* variable length */
+} __attribute__((packed));
+
+/*
+ * helper function which print in hexa the first bytes of
+ * hai opaque field
+ * \param hai [IN] record to print
+ * \param buffer [OUT] output buffer
+ * \param len [IN] max buffer len
+ * \retval buffer
+ */
+static inline char *hai_dump_data_field(struct hsm_action_item *hai,
+					char *buffer, int len)
+{
+	int i, sz, data_len;
+	char *ptr;
+
+	ptr = buffer;
+	sz = len;
+	data_len = hai->hai_len - sizeof(*hai);
+	for (i = 0 ; (i < data_len) && (sz > 0) ; i++)
+	{
+		int cnt;
+
+		cnt = snprintf(ptr, sz, "%.2X",
+			       (unsigned char)hai->hai_data[i]);
+		ptr += cnt;
+		sz -= cnt;
+	}
+	*ptr = '\0';
+	return buffer;
+}
+
+/* Copytool action list */
+#define HAL_VERSION 1
+#define HAL_MAXSIZE LNET_MTU /* bytes, used in userspace only */
+struct hsm_action_list {
+	__u32 hal_version;
+	__u32 hal_count;       /* number of hai's to follow */
+	__u64 hal_compound_id; /* returned by coordinator */
+	__u64 hal_flags;
+	__u32 hal_archive_id; /* which archive backend */
+	__u32 padding1;
+	char  hal_fsname[0];   /* null-terminated */
+	/* struct hsm_action_item[hal_count] follows, aligned on 8-byte
+	   boundaries. See hai_zero */
+} __attribute__((packed));
+
+#ifndef HAVE_CFS_SIZE_ROUND
+static inline int cfs_size_round (int val)
+{
+	return (val + 7) & (~0x7);
+}
+#define HAVE_CFS_SIZE_ROUND
+#endif
+
+/* Return pointer to first hai in action list */
+static inline struct hsm_action_item * hai_zero(struct hsm_action_list *hal)
+{
+	return (struct hsm_action_item *)(hal->hal_fsname +
+					  cfs_size_round(strlen(hal-> \
+								hal_fsname)));
+}
+/* Return pointer to next hai */
+static inline struct hsm_action_item * hai_next(struct hsm_action_item *hai)
+{
+	return (struct hsm_action_item *)((char *)hai +
+					  cfs_size_round(hai->hai_len));
+}
+
+/* Return size of an hsm_action_list */
+static inline int hal_size(struct hsm_action_list *hal)
+{
+	int i, sz;
+	struct hsm_action_item *hai;
+
+	sz = sizeof(*hal) + cfs_size_round(strlen(hal->hal_fsname));
+	hai = hai_zero(hal);
+	for (i = 0 ; i < hal->hal_count ; i++) {
+		sz += cfs_size_round(hai->hai_len);
+		hai = hai_next(hai);
+	}
+	return(sz);
+}
+
+/* Copytool progress reporting */
+#define HP_FLAG_COMPLETED 0x01
+#define HP_FLAG_RETRY     0x02
+
+struct hsm_progress {
+	lustre_fid		hp_fid;
+	__u64			hp_cookie;
+	struct hsm_extent	hp_extent;
+	__u16			hp_flags;
+	__u16			hp_errval; /* positive val */
+	__u32			padding;
+};
+
+/**
+ * Use by copytool during any hsm request they handled.
+ * This structure is initialized by llapi_hsm_copy_start()
+ * which is an helper over the ioctl() interface
+ * Store Lustre, internal use only, data.
+ */
+struct hsm_copy {
+	__u64			hc_data_version;
+	__u16			hc_flags;
+	__u16			hc_errval; /* positive val */
+	__u32			padding;
+	struct hsm_action_item	hc_hai;
+};
+
+/** @} lustreuser */
+
+#endif /* _LUSTRE_USER_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_acl.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_acl.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_acl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_acl.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_acl.h
+ */
+
+#ifndef _LUSTRE_ACL_H
+#define _LUSTRE_ACL_H
+
+#include <linux/lustre_acl.h>
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_capa.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_capa.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_capa.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_capa.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,305 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_capa.h
+ *
+ * Author: Lai Siyao <lsy@clusterfs.com>
+ */
+
+#ifndef __LINUX_CAPA_H_
+#define __LINUX_CAPA_H_
+
+/** \defgroup capa capa
+ *
+ * @{
+ */
+
+/*
+ * capability
+ */
+#include <linux/crypto.h>
+#include <lustre/lustre_idl.h>
+
+#define CAPA_TIMEOUT 1800		/* sec, == 30 min */
+#define CAPA_KEY_TIMEOUT (24 * 60 * 60)  /* sec, == 1 days */
+
+struct capa_hmac_alg {
+	const char     *ha_name;
+	int	     ha_len;
+	int	     ha_keylen;
+};
+
+#define DEF_CAPA_HMAC_ALG(name, type, len, keylen)      \
+[CAPA_HMAC_ALG_ ## type] = {			    \
+	.ha_name	 = name,			\
+	.ha_len	  = len,			 \
+	.ha_keylen       = keylen,		      \
+}
+
+struct client_capa {
+	struct inode	     *inode;
+	struct list_head		lli_list;     /* link to lli_oss_capas */
+};
+
+struct target_capa {
+	struct hlist_node	  c_hash;       /* link to capa hash */
+};
+
+struct obd_capa {
+	struct list_head		c_list;       /* link to capa_list */
+
+	struct lustre_capa	c_capa;       /* capa */
+	atomic_t	      c_refc;       /* ref count */
+	cfs_time_t		c_expiry;     /* jiffies */
+	spinlock_t		c_lock;	/* protect capa content */
+	int			c_site;
+
+	union {
+		struct client_capa	cli;
+		struct target_capa	tgt;
+	} u;
+};
+
+enum {
+	CAPA_SITE_CLIENT = 0,
+	CAPA_SITE_SERVER,
+	CAPA_SITE_MAX
+};
+
+static inline struct lu_fid *capa_fid(struct lustre_capa *capa)
+{
+	return &capa->lc_fid;
+}
+
+static inline __u64 capa_opc(struct lustre_capa *capa)
+{
+	return capa->lc_opc;
+}
+
+static inline __u64 capa_uid(struct lustre_capa *capa)
+{
+	return capa->lc_uid;
+}
+
+static inline __u64 capa_gid(struct lustre_capa *capa)
+{
+	return capa->lc_gid;
+}
+
+static inline __u32 capa_flags(struct lustre_capa *capa)
+{
+	return capa->lc_flags & 0xffffff;
+}
+
+static inline __u32 capa_alg(struct lustre_capa *capa)
+{
+	return (capa->lc_flags >> 24);
+}
+
+static inline __u32 capa_keyid(struct lustre_capa *capa)
+{
+	return capa->lc_keyid;
+}
+
+static inline __u64 capa_key_seq(struct lustre_capa_key *key)
+{
+	return key->lk_seq;
+}
+
+static inline __u32 capa_key_keyid(struct lustre_capa_key *key)
+{
+	return key->lk_keyid;
+}
+
+static inline __u32 capa_timeout(struct lustre_capa *capa)
+{
+	return capa->lc_timeout;
+}
+
+static inline __u32 capa_expiry(struct lustre_capa *capa)
+{
+	return capa->lc_expiry;
+}
+
+void _debug_capa(struct lustre_capa *, struct libcfs_debug_msg_data *,
+		 const char *fmt, ... );
+#define DEBUG_CAPA(level, capa, fmt, args...)				  \
+do {									   \
+	if (((level) & D_CANTMASK) != 0 ||				     \
+	    ((libcfs_debug & (level)) != 0 &&				  \
+	     (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) {	       \
+		LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, level, NULL);	      \
+		_debug_capa((capa), &msgdata, fmt, ##args);		    \
+	}								      \
+} while (0)
+
+#define DEBUG_CAPA_KEY(level, k, fmt, args...)				 \
+do {									   \
+CDEBUG(level, fmt " capability key@%p seq "LPU64" keyid %u\n",		 \
+       ##args, k, capa_key_seq(k), capa_key_keyid(k));			 \
+} while (0)
+
+typedef int (* renew_capa_cb_t)(struct obd_capa *, struct lustre_capa *);
+
+/* obdclass/capa.c */
+extern struct list_head capa_list[];
+extern spinlock_t capa_lock;
+extern int capa_count[];
+extern struct kmem_cache *capa_cachep;
+
+struct hlist_head *init_capa_hash(void);
+void cleanup_capa_hash(struct hlist_head *hash);
+
+struct obd_capa *capa_add(struct hlist_head *hash,
+			  struct lustre_capa *capa);
+struct obd_capa *capa_lookup(struct hlist_head *hash,
+			     struct lustre_capa *capa, int alive);
+
+int capa_hmac(__u8 *hmac, struct lustre_capa *capa, __u8 *key);
+int capa_encrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen);
+int capa_decrypt_id(__u32 *d, __u32 *s, __u8 *key, int keylen);
+void capa_cpy(void *dst, struct obd_capa *ocapa);
+static inline struct obd_capa *alloc_capa(int site)
+{
+	struct obd_capa *ocapa;
+
+	if (unlikely(site != CAPA_SITE_CLIENT && site != CAPA_SITE_SERVER))
+		return ERR_PTR(-EINVAL);
+
+	OBD_SLAB_ALLOC_PTR(ocapa, capa_cachep);
+	if (unlikely(!ocapa))
+		return ERR_PTR(-ENOMEM);
+
+	INIT_LIST_HEAD(&ocapa->c_list);
+	atomic_set(&ocapa->c_refc, 1);
+	spin_lock_init(&ocapa->c_lock);
+	ocapa->c_site = site;
+	if (ocapa->c_site == CAPA_SITE_CLIENT)
+		INIT_LIST_HEAD(&ocapa->u.cli.lli_list);
+	else
+		INIT_HLIST_NODE(&ocapa->u.tgt.c_hash);
+
+	return ocapa;
+}
+
+static inline struct obd_capa *capa_get(struct obd_capa *ocapa)
+{
+	if (!ocapa)
+		return NULL;
+
+	atomic_inc(&ocapa->c_refc);
+	return ocapa;
+}
+
+static inline void capa_put(struct obd_capa *ocapa)
+{
+	if (!ocapa)
+		return;
+
+	if (atomic_read(&ocapa->c_refc) == 0) {
+		DEBUG_CAPA(D_ERROR, &ocapa->c_capa, "refc is 0 for");
+		LBUG();
+	}
+
+	if (atomic_dec_and_test(&ocapa->c_refc)) {
+		LASSERT(list_empty(&ocapa->c_list));
+		if (ocapa->c_site == CAPA_SITE_CLIENT) {
+			LASSERT(list_empty(&ocapa->u.cli.lli_list));
+		} else {
+			struct hlist_node *hnode;
+
+			hnode = &ocapa->u.tgt.c_hash;
+			LASSERT(!hnode->next && !hnode->pprev);
+		}
+		OBD_SLAB_FREE(ocapa, capa_cachep, sizeof(*ocapa));
+	}
+}
+
+static inline int open_flags_to_accmode(int flags)
+{
+	int mode = flags;
+
+	if ((mode + 1) & O_ACCMODE)
+		mode++;
+	if (mode & O_TRUNC)
+		mode |= 2;
+
+	return mode;
+}
+
+static inline __u64 capa_open_opc(int mode)
+{
+	return mode & FMODE_WRITE ? CAPA_OPC_OSS_WRITE : CAPA_OPC_OSS_READ;
+}
+
+static inline void set_capa_expiry(struct obd_capa *ocapa)
+{
+	cfs_time_t expiry = cfs_time_sub((cfs_time_t)ocapa->c_capa.lc_expiry,
+					 cfs_time_current_sec());
+	ocapa->c_expiry = cfs_time_add(cfs_time_current(),
+				       cfs_time_seconds(expiry));
+}
+
+static inline int capa_is_expired_sec(struct lustre_capa *capa)
+{
+	return (capa->lc_expiry - cfs_time_current_sec() <= 0);
+}
+
+static inline int capa_is_expired(struct obd_capa *ocapa)
+{
+	return cfs_time_beforeq(ocapa->c_expiry, cfs_time_current());
+}
+
+static inline int capa_opc_supported(struct lustre_capa *capa, __u64 opc)
+{
+	return (capa_opc(capa) & opc) == opc;
+}
+
+struct filter_capa_key {
+	struct list_head	      k_list;
+	struct lustre_capa_key  k_key;
+};
+
+enum {
+	LC_ID_NONE      = 0,
+	LC_ID_PLAIN     = 1,
+	LC_ID_CONVERT   = 2
+};
+
+#define BYPASS_CAPA (struct lustre_capa *)ERR_PTR(-ENOENT)
+
+/** @} capa */
+
+#endif /* __LINUX_CAPA_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_cfg.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_cfg.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_cfg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_cfg.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,299 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LUSTRE_CFG_H
+#define _LUSTRE_CFG_H
+
+/** \defgroup cfg cfg
+ *
+ * @{
+ */
+
+/*
+ * 1cf6
+ * lcfG
+ */
+#define LUSTRE_CFG_VERSION 0x1cf60001
+#define LUSTRE_CFG_MAX_BUFCOUNT 8
+
+#define LCFG_HDR_SIZE(count) \
+    cfs_size_round(offsetof (struct lustre_cfg, lcfg_buflens[(count)]))
+
+/** If the LCFG_REQUIRED bit is set in a configuration command,
+ * then the client is required to understand this parameter
+ * in order to mount the filesystem. If it does not understand
+ * a REQUIRED command the client mount will fail. */
+#define LCFG_REQUIRED	 0x0001000
+
+enum lcfg_command_type {
+	LCFG_ATTACH	     = 0x00cf001, /**< create a new obd instance */
+	LCFG_DETACH	     = 0x00cf002, /**< destroy obd instance */
+	LCFG_SETUP	      = 0x00cf003, /**< call type-specific setup */
+	LCFG_CLEANUP	    = 0x00cf004, /**< call type-specific cleanup */
+	LCFG_ADD_UUID	   = 0x00cf005, /**< add a nid to a niduuid */
+	LCFG_DEL_UUID	   = 0x00cf006, /**< remove a nid from a niduuid */
+	LCFG_MOUNTOPT	   = 0x00cf007, /**< create a profile (mdc, osc) */
+	LCFG_DEL_MOUNTOPT       = 0x00cf008, /**< destroy a profile */
+	LCFG_SET_TIMEOUT	= 0x00cf009, /**< set obd_timeout */
+	LCFG_SET_UPCALL	 = 0x00cf00a, /**< deprecated */
+	LCFG_ADD_CONN	   = 0x00cf00b, /**< add a failover niduuid to an obd */
+	LCFG_DEL_CONN	   = 0x00cf00c, /**< remove a failover niduuid */
+	LCFG_LOV_ADD_OBD	= 0x00cf00d, /**< add an osc to a lov */
+	LCFG_LOV_DEL_OBD	= 0x00cf00e, /**< remove an osc from a lov */
+	LCFG_PARAM	      = 0x00cf00f, /**< set a proc parameter */
+	LCFG_MARKER	     = 0x00cf010, /**< metadata about next cfg rec */
+	LCFG_LOG_START	  = 0x00ce011, /**< mgc only, process a cfg log */
+	LCFG_LOG_END	    = 0x00ce012, /**< stop processing updates */
+	LCFG_LOV_ADD_INA	= 0x00ce013, /**< like LOV_ADD_OBD, inactive */
+	LCFG_ADD_MDC	    = 0x00cf014, /**< add an mdc to a lmv */
+	LCFG_DEL_MDC	    = 0x00cf015, /**< remove an mdc from a lmv */
+	LCFG_SPTLRPC_CONF       = 0x00ce016, /**< security */
+	LCFG_POOL_NEW	   = 0x00ce020, /**< create an ost pool name */
+	LCFG_POOL_ADD	   = 0x00ce021, /**< add an ost to a pool */
+	LCFG_POOL_REM	   = 0x00ce022, /**< remove an ost from a pool */
+	LCFG_POOL_DEL	   = 0x00ce023, /**< destroy an ost pool name */
+	LCFG_SET_LDLM_TIMEOUT   = 0x00ce030, /**< set ldlm_timeout */
+	LCFG_PRE_CLEANUP	= 0x00cf031, /**< call type-specific pre
+					      * cleanup cleanup */
+};
+
+struct lustre_cfg_bufs {
+	void    *lcfg_buf[LUSTRE_CFG_MAX_BUFCOUNT];
+	__u32    lcfg_buflen[LUSTRE_CFG_MAX_BUFCOUNT];
+	__u32    lcfg_bufcount;
+};
+
+struct lustre_cfg {
+	__u32 lcfg_version;
+	__u32 lcfg_command;
+
+	__u32 lcfg_num;
+	__u32 lcfg_flags;
+	__u64 lcfg_nid;
+	__u32 lcfg_nal;		/* not used any more */
+
+	__u32 lcfg_bufcount;
+	__u32 lcfg_buflens[0];
+};
+
+enum cfg_record_type {
+	PORTALS_CFG_TYPE = 1,
+	LUSTRE_CFG_TYPE = 123,
+};
+
+#define LUSTRE_CFG_BUFLEN(lcfg, idx)	    \
+	((lcfg)->lcfg_bufcount <= (idx)	 \
+	 ? 0				    \
+	 : (lcfg)->lcfg_buflens[(idx)])
+
+static inline void lustre_cfg_bufs_set(struct lustre_cfg_bufs *bufs,
+				       __u32		   index,
+				       void		   *buf,
+				       __u32		   buflen)
+{
+	if (index >= LUSTRE_CFG_MAX_BUFCOUNT)
+		return;
+	if (bufs == NULL)
+		return;
+
+	if (bufs->lcfg_bufcount <= index)
+		bufs->lcfg_bufcount = index + 1;
+
+	bufs->lcfg_buf[index]    = buf;
+	bufs->lcfg_buflen[index] = buflen;
+}
+
+static inline void lustre_cfg_bufs_set_string(struct lustre_cfg_bufs *bufs,
+					      __u32 index,
+					      char *str)
+{
+	lustre_cfg_bufs_set(bufs, index, str, str ? strlen(str) + 1 : 0);
+}
+
+static inline void lustre_cfg_bufs_reset(struct lustre_cfg_bufs *bufs, char *name)
+{
+	memset((bufs), 0, sizeof(*bufs));
+	if (name)
+		lustre_cfg_bufs_set_string(bufs, 0, name);
+}
+
+static inline void *lustre_cfg_buf(struct lustre_cfg *lcfg, int index)
+{
+	int i;
+	int offset;
+	int bufcount;
+	LASSERT (lcfg != NULL);
+	LASSERT (index >= 0);
+
+	bufcount = lcfg->lcfg_bufcount;
+	if (index >= bufcount)
+		return NULL;
+
+	offset = LCFG_HDR_SIZE(lcfg->lcfg_bufcount);
+	for (i = 0; i < index; i++)
+		offset += cfs_size_round(lcfg->lcfg_buflens[i]);
+	return (char *)lcfg + offset;
+}
+
+static inline void lustre_cfg_bufs_init(struct lustre_cfg_bufs *bufs,
+					struct lustre_cfg *lcfg)
+{
+	int i;
+	bufs->lcfg_bufcount = lcfg->lcfg_bufcount;
+	for (i = 0; i < bufs->lcfg_bufcount; i++) {
+		bufs->lcfg_buflen[i] = lcfg->lcfg_buflens[i];
+		bufs->lcfg_buf[i] = lustre_cfg_buf(lcfg, i);
+	}
+}
+
+static inline char *lustre_cfg_string(struct lustre_cfg *lcfg, int index)
+{
+	char *s;
+
+	if (lcfg->lcfg_buflens[index] == 0)
+		return NULL;
+
+	s = lustre_cfg_buf(lcfg, index);
+	if (s == NULL)
+		return NULL;
+
+	/*
+	 * make sure it's NULL terminated, even if this kills a char
+	 * of data.  Try to use the padding first though.
+	 */
+	if (s[lcfg->lcfg_buflens[index] - 1] != '\0') {
+		int last = min((int)lcfg->lcfg_buflens[index],
+			       cfs_size_round(lcfg->lcfg_buflens[index]) - 1);
+		char lost = s[last];
+		s[last] = '\0';
+		if (lost != '\0') {
+			CWARN("Truncated buf %d to '%s' (lost '%c'...)\n",
+			      index, s, lost);
+		}
+	}
+	return s;
+}
+
+static inline int lustre_cfg_len(__u32 bufcount, __u32 *buflens)
+{
+	int i;
+	int len;
+	ENTRY;
+
+	len = LCFG_HDR_SIZE(bufcount);
+	for (i = 0; i < bufcount; i++)
+		len += cfs_size_round(buflens[i]);
+
+	RETURN(cfs_size_round(len));
+}
+
+
+#include <obd_support.h>
+
+static inline struct lustre_cfg *lustre_cfg_new(int cmd,
+						struct lustre_cfg_bufs *bufs)
+{
+	struct lustre_cfg *lcfg;
+	char *ptr;
+	int i;
+
+	ENTRY;
+
+	OBD_ALLOC(lcfg, lustre_cfg_len(bufs->lcfg_bufcount,
+				       bufs->lcfg_buflen));
+	if (!lcfg)
+		RETURN(ERR_PTR(-ENOMEM));
+
+	lcfg->lcfg_version = LUSTRE_CFG_VERSION;
+	lcfg->lcfg_command = cmd;
+	lcfg->lcfg_bufcount = bufs->lcfg_bufcount;
+
+	ptr = (char *)lcfg + LCFG_HDR_SIZE(lcfg->lcfg_bufcount);
+	for (i = 0; i < lcfg->lcfg_bufcount; i++) {
+		lcfg->lcfg_buflens[i] = bufs->lcfg_buflen[i];
+		LOGL((char *)bufs->lcfg_buf[i], bufs->lcfg_buflen[i], ptr);
+	}
+	RETURN(lcfg);
+}
+
+static inline void lustre_cfg_free(struct lustre_cfg *lcfg)
+{
+	int len;
+
+	len = lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens);
+
+	OBD_FREE(lcfg, len);
+	EXIT;
+	return;
+}
+
+static inline int lustre_cfg_sanity_check(void *buf, int len)
+{
+	struct lustre_cfg *lcfg = (struct lustre_cfg *)buf;
+	ENTRY;
+	if (!lcfg)
+		RETURN(-EINVAL);
+
+	/* check that the first bits of the struct are valid */
+	if (len < LCFG_HDR_SIZE(0))
+		RETURN(-EINVAL);
+
+	if (lcfg->lcfg_version != LUSTRE_CFG_VERSION)
+		RETURN(-EINVAL);
+
+	if (lcfg->lcfg_bufcount >= LUSTRE_CFG_MAX_BUFCOUNT)
+		RETURN(-EINVAL);
+
+	/* check that the buflens are valid */
+	if (len < LCFG_HDR_SIZE(lcfg->lcfg_bufcount))
+		RETURN(-EINVAL);
+
+	/* make sure all the pointers point inside the data */
+	if (len < lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens))
+		RETURN(-EINVAL);
+
+	RETURN(0);
+}
+
+#include <lustre/lustre_user.h>
+
+#ifndef INVALID_UID
+#define INVALID_UID     (-1)
+#endif
+
+/** @} cfg */
+
+#endif // _LUSTRE_CFG_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_debug.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_debug.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_debug.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_debug.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,76 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LUSTRE_DEBUG_H
+#define _LUSTRE_DEBUG_H
+
+/** \defgroup debug debug
+ *
+ * @{
+ */
+
+#include <lustre_net.h>
+#include <obd.h>
+
+#include <linux/lustre_debug.h>
+
+#define ASSERT_MAX_SIZE_MB 60000ULL
+#define ASSERT_PAGE_INDEX(index, OP)				    \
+do { if (index > ASSERT_MAX_SIZE_MB << (20 - PAGE_CACHE_SHIFT)) {	 \
+	CERROR("bad page index %lu > %llu\n", index,		    \
+	       ASSERT_MAX_SIZE_MB << (20 - PAGE_CACHE_SHIFT));	    \
+	libcfs_debug = ~0UL;					    \
+	OP;							     \
+}} while(0)
+
+#define ASSERT_FILE_OFFSET(offset, OP)				  \
+do { if (offset > ASSERT_MAX_SIZE_MB << 20) {			   \
+	CERROR("bad file offset %llu > %llu\n", offset,		 \
+	       ASSERT_MAX_SIZE_MB << 20);			       \
+	libcfs_debug = ~0UL;					    \
+	OP;							     \
+}} while(0)
+
+/* lib/debug.c */
+void dump_lniobuf(struct niobuf_local *lnb);
+int dump_req(struct ptlrpc_request *req);
+void dump_lsm(int level, struct lov_stripe_md *lsm);
+int block_debug_setup(void *addr, int len, __u64 off, __u64 id);
+int block_debug_check(char *who, void *addr, int len, __u64 off, __u64 id);
+
+/** @} debug */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_disk.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_disk.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_disk.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_disk.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,543 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_disk.h
+ *
+ * Lustre disk format definitions.
+ *
+ * Author: Nathan Rutman <nathan@clusterfs.com>
+ */
+
+#ifndef _LUSTRE_DISK_H
+#define _LUSTRE_DISK_H
+
+/** \defgroup disk disk
+ *
+ * @{
+ */
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lnet/types.h>
+
+/****************** on-disk files *********************/
+
+#define MDT_LOGS_DIR      "LOGS"  /* COMPAT_146 */
+#define MOUNT_CONFIGS_DIR "CONFIGS"
+#define CONFIGS_FILE      "mountdata"
+/** Persistent mount data are stored on the disk in this file. */
+#define MOUNT_DATA_FILE    MOUNT_CONFIGS_DIR"/"CONFIGS_FILE
+#define LAST_RCVD	 "last_rcvd"
+#define LOV_OBJID	 "lov_objid"
+#define LOV_OBJSEQ		"lov_objseq"
+#define HEALTH_CHECK      "health_check"
+#define CAPA_KEYS	 "capa_keys"
+#define CHANGELOG_USERS   "changelog_users"
+#define MGS_NIDTBL_DIR    "NIDTBL_VERSIONS"
+#define QMT_DIR	   "quota_master"
+#define QSD_DIR	   "quota_slave"
+
+/****************** persistent mount data *********************/
+
+#define LDD_F_SV_TYPE_MDT   0x0001
+#define LDD_F_SV_TYPE_OST   0x0002
+#define LDD_F_SV_TYPE_MGS   0x0004
+#define LDD_F_SV_TYPE_MASK (LDD_F_SV_TYPE_MDT  | \
+			    LDD_F_SV_TYPE_OST  | \
+			    LDD_F_SV_TYPE_MGS)
+#define LDD_F_SV_ALL	0x0008
+/** need an index assignment */
+#define LDD_F_NEED_INDEX    0x0010
+/** never registered */
+#define LDD_F_VIRGIN	0x0020
+/** update the config logs for this server */
+#define LDD_F_UPDATE	0x0040
+/** rewrite the LDD */
+#define LDD_F_REWRITE_LDD   0x0080
+/** regenerate config logs for this fs or server */
+#define LDD_F_WRITECONF     0x0100
+/** COMPAT_14 */
+#define LDD_F_UPGRADE14     0x0200
+/** process as lctl conf_param */
+#define LDD_F_PARAM	 0x0400
+/** all nodes are specified as service nodes */
+#define LDD_F_NO_PRIMNODE   0x1000
+/** IR enable flag */
+#define LDD_F_IR_CAPABLE    0x2000
+/** the MGS refused to register the target. */
+#define LDD_F_ERROR	 0x4000
+
+/* opc for target register */
+#define LDD_F_OPC_REG   0x10000000
+#define LDD_F_OPC_UNREG 0x20000000
+#define LDD_F_OPC_READY 0x40000000
+#define LDD_F_OPC_MASK  0xf0000000
+
+#define LDD_F_ONDISK_MASK  (LDD_F_SV_TYPE_MASK)
+
+#define LDD_F_MASK	  0xFFFF
+
+enum ldd_mount_type {
+	LDD_MT_EXT3 = 0,
+	LDD_MT_LDISKFS,
+	LDD_MT_SMFS,
+	LDD_MT_REISERFS,
+	LDD_MT_LDISKFS2,
+	LDD_MT_ZFS,
+	LDD_MT_LAST
+};
+
+static inline char *mt_str(enum ldd_mount_type mt)
+{
+	static char *mount_type_string[] = {
+		"ext3",
+		"ldiskfs",
+		"smfs",
+		"reiserfs",
+		"ldiskfs2",
+		"zfs",
+	};
+	return mount_type_string[mt];
+}
+
+static inline char *mt_type(enum ldd_mount_type mt)
+{
+	static char *mount_type_string[] = {
+		"osd-ldiskfs",
+		"osd-ldiskfs",
+		"osd-smfs",
+		"osd-reiserfs",
+		"osd-ldiskfs",
+		"osd-zfs",
+	};
+	return mount_type_string[mt];
+}
+
+#define LDD_INCOMPAT_SUPP 0
+#define LDD_ROCOMPAT_SUPP 0
+
+#define LDD_MAGIC 0x1dd00001
+
+/* On-disk configuration file. In host-endian order. */
+struct lustre_disk_data {
+	__u32      ldd_magic;
+	__u32      ldd_feature_compat;  /* compatible feature flags */
+	__u32      ldd_feature_rocompat;/* read-only compatible feature flags */
+	__u32      ldd_feature_incompat;/* incompatible feature flags */
+
+	__u32      ldd_config_ver;      /* config rewrite count - not used */
+	__u32      ldd_flags;	   /* LDD_SV_TYPE */
+	__u32      ldd_svindex;	 /* server index (0001), must match
+					   svname */
+	__u32      ldd_mount_type;      /* target fs type LDD_MT_* */
+	char       ldd_fsname[64];      /* filesystem this server is part of,
+					   MTI_NAME_MAXLEN */
+	char       ldd_svname[64];      /* this server's name (lustre-mdt0001)*/
+	__u8       ldd_uuid[40];	/* server UUID (COMPAT_146) */
+
+/*200*/ char       ldd_userdata[1024 - 200]; /* arbitrary user string */
+/*1024*/__u8       ldd_padding[4096 - 1024];
+/*4096*/char       ldd_mount_opts[4096]; /* target fs mount opts */
+/*8192*/char       ldd_params[4096];     /* key=value pairs */
+};
+
+
+#define IS_MDT(data)    ((data)->lsi_flags & LDD_F_SV_TYPE_MDT)
+#define IS_OST(data)    ((data)->lsi_flags & LDD_F_SV_TYPE_OST)
+#define IS_MGS(data)    ((data)->lsi_flags & LDD_F_SV_TYPE_MGS)
+#define IS_SERVER(data) ((data)->lsi_flags & (LDD_F_SV_TYPE_MGS | \
+			 LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST))
+#define MT_STR(data)    mt_str((data)->ldd_mount_type)
+
+/* Make the mdt/ost server obd name based on the filesystem name */
+static inline int server_make_name(__u32 flags, __u16 index, char *fs,
+				   char *name)
+{
+	if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
+		if (!(flags & LDD_F_SV_ALL))
+			sprintf(name, "%.8s%c%s%04x", fs,
+				(flags & LDD_F_VIRGIN) ? ':' :
+					((flags & LDD_F_WRITECONF) ? '=' : '-'),
+				(flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
+				index);
+	} else if (flags & LDD_F_SV_TYPE_MGS) {
+		sprintf(name, "MGS");
+	} else {
+		CERROR("unknown server type %#x\n", flags);
+		return 1;
+	}
+	return 0;
+}
+
+/****************** mount command *********************/
+
+/* The lmd is only used internally by Lustre; mount simply passes
+   everything as string options */
+
+#define LMD_MAGIC    0xbdacbd03
+
+/* gleaned from the mount command - no persistent info here */
+struct lustre_mount_data {
+	__u32      lmd_magic;
+	__u32      lmd_flags;	 /* lustre mount flags */
+	int	lmd_mgs_failnodes; /* mgs failover node count */
+	int	lmd_exclude_count;
+	int	lmd_recovery_time_soft;
+	int	lmd_recovery_time_hard;
+	char      *lmd_dev;	   /* device name */
+	char      *lmd_profile;       /* client only */
+	char      *lmd_mgssec;	/* sptlrpc flavor to mgs */
+	char      *lmd_opts;	  /* lustre mount options (as opposed to
+					 _device_ mount options) */
+	char      *lmd_params;	/* lustre params */
+	__u32     *lmd_exclude;       /* array of OSTs to ignore */
+	char	*lmd_mgs;	   /* MGS nid */
+	char	*lmd_osd_type;      /* OSD type */
+};
+
+#define LMD_FLG_SERVER       0x0001  /* Mounting a server */
+#define LMD_FLG_CLIENT       0x0002  /* Mounting a client */
+#define LMD_FLG_ABORT_RECOV  0x0008  /* Abort recovery */
+#define LMD_FLG_NOSVC	0x0010  /* Only start MGS/MGC for servers,
+					no other services */
+#define LMD_FLG_NOMGS	0x0020  /* Only start target for servers, reusing
+					existing MGS services */
+#define LMD_FLG_WRITECONF    0x0040  /* Rewrite config log */
+#define LMD_FLG_NOIR	 0x0080  /* NO imperative recovery */
+#define LMD_FLG_NOSCRUB	     0x0100  /* Do not trigger scrub automatically */
+#define LMD_FLG_MGS	     0x0200  /* Also start MGS along with server */
+#define LMD_FLG_IAM	     0x0400  /* IAM dir */
+#define LMD_FLG_NO_PRIMNODE  0x0800  /* all nodes are service nodes */
+#define LMD_FLG_VIRGIN	     0x1000  /* the service registers first time */
+#define LMD_FLG_UPDATE	     0x2000  /* update parameters */
+
+#define lmd_is_client(x) ((x)->lmd_flags & LMD_FLG_CLIENT)
+
+
+/****************** last_rcvd file *********************/
+
+/** version recovery epoch */
+#define LR_EPOCH_BITS   32
+#define lr_epoch(a) ((a) >> LR_EPOCH_BITS)
+#define LR_EXPIRE_INTERVALS 16 /**< number of intervals to track transno */
+#define ENOENT_VERSION 1 /** 'virtual' version of non-existent object */
+
+#define LR_SERVER_SIZE   512
+#define LR_CLIENT_START 8192
+#define LR_CLIENT_SIZE   128
+#if LR_CLIENT_START < LR_SERVER_SIZE
+#error "Can't have LR_CLIENT_START < LR_SERVER_SIZE"
+#endif
+
+/*
+ * This limit is arbitrary (131072 clients on x86), but it is convenient to use
+ * 2^n * PAGE_CACHE_SIZE * 8 for the number of bits that fit an order-n allocation.
+ * If we need more than 131072 clients (order-2 allocation on x86) then this
+ * should become an array of single-page pointers that are allocated on demand.
+ */
+#if (128 * 1024UL) > (PAGE_CACHE_SIZE * 8)
+#define LR_MAX_CLIENTS (128 * 1024UL)
+#else
+#define LR_MAX_CLIENTS (PAGE_CACHE_SIZE * 8)
+#endif
+
+/** COMPAT_146: this is an OST (temporary) */
+#define OBD_COMPAT_OST	  0x00000002
+/** COMPAT_146: this is an MDT (temporary) */
+#define OBD_COMPAT_MDT	  0x00000004
+/** 2.0 server, interop flag to show server version is changed */
+#define OBD_COMPAT_20	   0x00000008
+
+/** MDS handles LOV_OBJID file */
+#define OBD_ROCOMPAT_LOVOBJID   0x00000001
+
+/** OST handles group subdirs */
+#define OBD_INCOMPAT_GROUPS     0x00000001
+/** this is an OST */
+#define OBD_INCOMPAT_OST	0x00000002
+/** this is an MDT */
+#define OBD_INCOMPAT_MDT	0x00000004
+/** common last_rvcd format */
+#define OBD_INCOMPAT_COMMON_LR  0x00000008
+/** FID is enabled */
+#define OBD_INCOMPAT_FID	0x00000010
+/** Size-on-MDS is enabled */
+#define OBD_INCOMPAT_SOM	0x00000020
+/** filesystem using iam format to store directory entries */
+#define OBD_INCOMPAT_IAM_DIR    0x00000040
+/** LMA attribute contains per-inode incompatible flags */
+#define OBD_INCOMPAT_LMA	0x00000080
+/** lmm_stripe_count has been shrunk from __u32 to __u16 and the remaining 16
+ * bits are now used to store a generation. Once we start changing the layout
+ * and bumping the generation, old versions expecting a 32-bit lmm_stripe_count
+ * will be confused by interpreting stripe_count | gen << 16 as the actual
+ * stripe count */
+#define OBD_INCOMPAT_LMM_VER    0x00000100
+/** multiple OI files for MDT */
+#define OBD_INCOMPAT_MULTI_OI   0x00000200
+
+/* Data stored per server at the head of the last_rcvd file.  In le32 order.
+   This should be common to filter_internal.h, lustre_mds.h */
+struct lr_server_data {
+	__u8  lsd_uuid[40];	/* server UUID */
+	__u64 lsd_last_transno;    /* last completed transaction ID */
+	__u64 lsd_compat14;	/* reserved - compat with old last_rcvd */
+	__u64 lsd_mount_count;     /* incarnation number */
+	__u32 lsd_feature_compat;  /* compatible feature flags */
+	__u32 lsd_feature_rocompat;/* read-only compatible feature flags */
+	__u32 lsd_feature_incompat;/* incompatible feature flags */
+	__u32 lsd_server_size;     /* size of server data area */
+	__u32 lsd_client_start;    /* start of per-client data area */
+	__u16 lsd_client_size;     /* size of per-client data area */
+	__u16 lsd_subdir_count;    /* number of subdirectories for objects */
+	__u64 lsd_catalog_oid;     /* recovery catalog object id */
+	__u32 lsd_catalog_ogen;    /* recovery catalog inode generation */
+	__u8  lsd_peeruuid[40];    /* UUID of MDS associated with this OST */
+	__u32 lsd_osd_index;       /* index number of OST in LOV */
+	__u32 lsd_padding1;	/* was lsd_mdt_index, unused in 2.4.0 */
+	__u32 lsd_start_epoch;     /* VBR: start epoch from last boot */
+	/** transaction values since lsd_trans_table_time */
+	__u64 lsd_trans_table[LR_EXPIRE_INTERVALS];
+	/** start point of transno table below */
+	__u32 lsd_trans_table_time; /* time of first slot in table above */
+	__u32 lsd_expire_intervals; /* LR_EXPIRE_INTERVALS */
+	__u8  lsd_padding[LR_SERVER_SIZE - 288];
+};
+
+/* Data stored per client in the last_rcvd file.  In le32 order. */
+struct lsd_client_data {
+	__u8  lcd_uuid[40];      /* client UUID */
+	__u64 lcd_last_transno; /* last completed transaction ID */
+	__u64 lcd_last_xid;     /* xid for the last transaction */
+	__u32 lcd_last_result;  /* result from last RPC */
+	__u32 lcd_last_data;    /* per-op data (disposition for open &c.) */
+	/* for MDS_CLOSE requests */
+	__u64 lcd_last_close_transno; /* last completed transaction ID */
+	__u64 lcd_last_close_xid;     /* xid for the last transaction */
+	__u32 lcd_last_close_result;  /* result from last RPC */
+	__u32 lcd_last_close_data;    /* per-op data */
+	/* VBR: last versions */
+	__u64 lcd_pre_versions[4];
+	__u32 lcd_last_epoch;
+	/** orphans handling for delayed export rely on that */
+	__u32 lcd_first_epoch;
+	__u8  lcd_padding[LR_CLIENT_SIZE - 128];
+};
+
+/* bug20354: the lcd_uuid for export of clients may be wrong */
+static inline void check_lcd(char *obd_name, int index,
+			     struct lsd_client_data *lcd)
+{
+	int length = sizeof(lcd->lcd_uuid);
+	if (strnlen((char*)lcd->lcd_uuid, length) == length) {
+		lcd->lcd_uuid[length - 1] = '\0';
+
+		LCONSOLE_ERROR("the client UUID (%s) on %s for exports"
+			       "stored in last_rcvd(index = %d) is bad!\n",
+			       lcd->lcd_uuid, obd_name, index);
+	}
+}
+
+/* last_rcvd handling */
+static inline void lsd_le_to_cpu(struct lr_server_data *buf,
+				 struct lr_server_data *lsd)
+{
+	int i;
+	memcpy(lsd->lsd_uuid, buf->lsd_uuid, sizeof(lsd->lsd_uuid));
+	lsd->lsd_last_transno     = le64_to_cpu(buf->lsd_last_transno);
+	lsd->lsd_compat14	 = le64_to_cpu(buf->lsd_compat14);
+	lsd->lsd_mount_count      = le64_to_cpu(buf->lsd_mount_count);
+	lsd->lsd_feature_compat   = le32_to_cpu(buf->lsd_feature_compat);
+	lsd->lsd_feature_rocompat = le32_to_cpu(buf->lsd_feature_rocompat);
+	lsd->lsd_feature_incompat = le32_to_cpu(buf->lsd_feature_incompat);
+	lsd->lsd_server_size      = le32_to_cpu(buf->lsd_server_size);
+	lsd->lsd_client_start     = le32_to_cpu(buf->lsd_client_start);
+	lsd->lsd_client_size      = le16_to_cpu(buf->lsd_client_size);
+	lsd->lsd_subdir_count     = le16_to_cpu(buf->lsd_subdir_count);
+	lsd->lsd_catalog_oid      = le64_to_cpu(buf->lsd_catalog_oid);
+	lsd->lsd_catalog_ogen     = le32_to_cpu(buf->lsd_catalog_ogen);
+	memcpy(lsd->lsd_peeruuid, buf->lsd_peeruuid, sizeof(lsd->lsd_peeruuid));
+	lsd->lsd_osd_index	= le32_to_cpu(buf->lsd_osd_index);
+	lsd->lsd_padding1	= le32_to_cpu(buf->lsd_padding1);
+	lsd->lsd_start_epoch      = le32_to_cpu(buf->lsd_start_epoch);
+	for (i = 0; i < LR_EXPIRE_INTERVALS; i++)
+		lsd->lsd_trans_table[i] = le64_to_cpu(buf->lsd_trans_table[i]);
+	lsd->lsd_trans_table_time = le32_to_cpu(buf->lsd_trans_table_time);
+	lsd->lsd_expire_intervals = le32_to_cpu(buf->lsd_expire_intervals);
+}
+
+static inline void lsd_cpu_to_le(struct lr_server_data *lsd,
+				 struct lr_server_data *buf)
+{
+	int i;
+	memcpy(buf->lsd_uuid, lsd->lsd_uuid, sizeof(buf->lsd_uuid));
+	buf->lsd_last_transno     = cpu_to_le64(lsd->lsd_last_transno);
+	buf->lsd_compat14	 = cpu_to_le64(lsd->lsd_compat14);
+	buf->lsd_mount_count      = cpu_to_le64(lsd->lsd_mount_count);
+	buf->lsd_feature_compat   = cpu_to_le32(lsd->lsd_feature_compat);
+	buf->lsd_feature_rocompat = cpu_to_le32(lsd->lsd_feature_rocompat);
+	buf->lsd_feature_incompat = cpu_to_le32(lsd->lsd_feature_incompat);
+	buf->lsd_server_size      = cpu_to_le32(lsd->lsd_server_size);
+	buf->lsd_client_start     = cpu_to_le32(lsd->lsd_client_start);
+	buf->lsd_client_size      = cpu_to_le16(lsd->lsd_client_size);
+	buf->lsd_subdir_count     = cpu_to_le16(lsd->lsd_subdir_count);
+	buf->lsd_catalog_oid      = cpu_to_le64(lsd->lsd_catalog_oid);
+	buf->lsd_catalog_ogen     = cpu_to_le32(lsd->lsd_catalog_ogen);
+	memcpy(buf->lsd_peeruuid, lsd->lsd_peeruuid, sizeof(buf->lsd_peeruuid));
+	buf->lsd_osd_index	  = cpu_to_le32(lsd->lsd_osd_index);
+	buf->lsd_padding1	  = cpu_to_le32(lsd->lsd_padding1);
+	buf->lsd_start_epoch      = cpu_to_le32(lsd->lsd_start_epoch);
+	for (i = 0; i < LR_EXPIRE_INTERVALS; i++)
+		buf->lsd_trans_table[i] = cpu_to_le64(lsd->lsd_trans_table[i]);
+	buf->lsd_trans_table_time = cpu_to_le32(lsd->lsd_trans_table_time);
+	buf->lsd_expire_intervals = cpu_to_le32(lsd->lsd_expire_intervals);
+}
+
+static inline void lcd_le_to_cpu(struct lsd_client_data *buf,
+				 struct lsd_client_data *lcd)
+{
+	memcpy(lcd->lcd_uuid, buf->lcd_uuid, sizeof (lcd->lcd_uuid));
+	lcd->lcd_last_transno       = le64_to_cpu(buf->lcd_last_transno);
+	lcd->lcd_last_xid	   = le64_to_cpu(buf->lcd_last_xid);
+	lcd->lcd_last_result	= le32_to_cpu(buf->lcd_last_result);
+	lcd->lcd_last_data	  = le32_to_cpu(buf->lcd_last_data);
+	lcd->lcd_last_close_transno = le64_to_cpu(buf->lcd_last_close_transno);
+	lcd->lcd_last_close_xid     = le64_to_cpu(buf->lcd_last_close_xid);
+	lcd->lcd_last_close_result  = le32_to_cpu(buf->lcd_last_close_result);
+	lcd->lcd_last_close_data    = le32_to_cpu(buf->lcd_last_close_data);
+	lcd->lcd_pre_versions[0]    = le64_to_cpu(buf->lcd_pre_versions[0]);
+	lcd->lcd_pre_versions[1]    = le64_to_cpu(buf->lcd_pre_versions[1]);
+	lcd->lcd_pre_versions[2]    = le64_to_cpu(buf->lcd_pre_versions[2]);
+	lcd->lcd_pre_versions[3]    = le64_to_cpu(buf->lcd_pre_versions[3]);
+	lcd->lcd_last_epoch	 = le32_to_cpu(buf->lcd_last_epoch);
+	lcd->lcd_first_epoch	= le32_to_cpu(buf->lcd_first_epoch);
+}
+
+static inline void lcd_cpu_to_le(struct lsd_client_data *lcd,
+				 struct lsd_client_data *buf)
+{
+	memcpy(buf->lcd_uuid, lcd->lcd_uuid, sizeof (lcd->lcd_uuid));
+	buf->lcd_last_transno       = cpu_to_le64(lcd->lcd_last_transno);
+	buf->lcd_last_xid	   = cpu_to_le64(lcd->lcd_last_xid);
+	buf->lcd_last_result	= cpu_to_le32(lcd->lcd_last_result);
+	buf->lcd_last_data	  = cpu_to_le32(lcd->lcd_last_data);
+	buf->lcd_last_close_transno = cpu_to_le64(lcd->lcd_last_close_transno);
+	buf->lcd_last_close_xid     = cpu_to_le64(lcd->lcd_last_close_xid);
+	buf->lcd_last_close_result  = cpu_to_le32(lcd->lcd_last_close_result);
+	buf->lcd_last_close_data    = cpu_to_le32(lcd->lcd_last_close_data);
+	buf->lcd_pre_versions[0]    = cpu_to_le64(lcd->lcd_pre_versions[0]);
+	buf->lcd_pre_versions[1]    = cpu_to_le64(lcd->lcd_pre_versions[1]);
+	buf->lcd_pre_versions[2]    = cpu_to_le64(lcd->lcd_pre_versions[2]);
+	buf->lcd_pre_versions[3]    = cpu_to_le64(lcd->lcd_pre_versions[3]);
+	buf->lcd_last_epoch	 = cpu_to_le32(lcd->lcd_last_epoch);
+	buf->lcd_first_epoch	= cpu_to_le32(lcd->lcd_first_epoch);
+}
+
+static inline __u64 lcd_last_transno(struct lsd_client_data *lcd)
+{
+	return (lcd->lcd_last_transno > lcd->lcd_last_close_transno ?
+		lcd->lcd_last_transno : lcd->lcd_last_close_transno);
+}
+
+static inline __u64 lcd_last_xid(struct lsd_client_data *lcd)
+{
+	return (lcd->lcd_last_xid > lcd->lcd_last_close_xid ?
+		lcd->lcd_last_xid : lcd->lcd_last_close_xid);
+}
+
+/****************** superblock additional info *********************/
+
+struct ll_sb_info;
+
+struct lustre_sb_info {
+	int		       lsi_flags;
+	struct obd_device	*lsi_mgc;     /* mgc obd */
+	struct lustre_mount_data *lsi_lmd;     /* mount command info */
+	struct ll_sb_info	*lsi_llsbi;   /* add'l client sbi info */
+	struct dt_device	 *lsi_dt_dev;  /* dt device to access disk fs*/
+	struct vfsmount	  *lsi_srv_mnt; /* the one server mount */
+	atomic_t	      lsi_mounts;  /* references to the srv_mnt */
+	char			  lsi_svname[MTI_NAME_MAXLEN];
+	char			  lsi_osd_obdname[64];
+	char			  lsi_osd_uuid[64];
+	struct obd_export	 *lsi_osd_exp;
+	char			  lsi_osd_type[16];
+	char			  lsi_fstype[16];
+	struct backing_dev_info   lsi_bdi;     /* each client mountpoint needs
+						  own backing_dev_info */
+};
+
+#define LSI_UMOUNT_FAILOVER	      0x00200000
+#define LSI_BDI_INITIALIZED	      0x00400000
+
+#define     s2lsi(sb)	((struct lustre_sb_info *)((sb)->s_fs_info))
+#define     s2lsi_nocast(sb) ((sb)->s_fs_info)
+
+#define     get_profile_name(sb)   (s2lsi(sb)->lsi_lmd->lmd_profile)
+#define	    get_mount_flags(sb)	   (s2lsi(sb)->lsi_lmd->lmd_flags)
+#define	    get_mntdev_name(sb)	   (s2lsi(sb)->lsi_lmd->lmd_dev)
+
+
+/****************** mount lookup info *********************/
+
+struct lustre_mount_info {
+	char		 *lmi_name;
+	struct super_block   *lmi_sb;
+	struct vfsmount      *lmi_mnt;
+	struct list_head	    lmi_list_chain;
+};
+
+/****************** prototypes *********************/
+
+/* obd_mount.c */
+int server_name2fsname(const char *svname, char *fsname, const char **endptr);
+int server_name2index(const char *svname, __u32 *idx, const char **endptr);
+int server_name2svname(const char *label, char *svname, const char **endptr,
+		       size_t svsize);
+
+int lustre_put_lsi(struct super_block *sb);
+int lustre_start_simple(char *obdname, char *type, char *uuid,
+			char *s1, char *s2, char *s3, char *s4);
+int lustre_start_mgc(struct super_block *sb);
+void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb,
+						  struct vfsmount *mnt));
+void lustre_register_kill_super_cb(void (*cfs)(struct super_block *sb));
+int lustre_common_put_super(struct super_block *sb);
+
+
+int mgc_fsname2resid(char *fsname, struct ldlm_res_id *res_id, int type);
+
+/** @} disk */
+
+#endif // _LUSTRE_DISK_H
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_dlm.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_dlm.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_dlm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_dlm.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1671 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2010, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+/** \defgroup LDLM Lustre Distributed Lock Manager
+ *
+ * Lustre DLM is based on VAX DLM.
+ * Its two main roles are:
+ *   - To provide locking assuring consistency of data on all Lustre nodes.
+ *   - To allow clients to cache state protected by a lock by holding the
+ *     lock until a conflicting lock is requested or it is expired by the LRU.
+ *
+ * @{
+ */
+
+#ifndef _LUSTRE_DLM_H__
+#define _LUSTRE_DLM_H__
+
+#include <linux/lustre_dlm.h>
+
+#include <lustre_lib.h>
+#include <lustre_net.h>
+#include <lustre_import.h>
+#include <lustre_handles.h>
+#include <interval_tree.h> /* for interval_node{}, ldlm_extent */
+#include <lu_ref.h>
+
+struct obd_ops;
+struct obd_device;
+
+#define OBD_LDLM_DEVICENAME  "ldlm"
+
+#define LDLM_DEFAULT_LRU_SIZE (100 * num_online_cpus())
+#define LDLM_DEFAULT_MAX_ALIVE (cfs_time_seconds(36000))
+#define LDLM_CTIME_AGE_LIMIT (10)
+#define LDLM_DEFAULT_PARALLEL_AST_LIMIT 1024
+
+/**
+ * LDLM non-error return states
+ */
+typedef enum {
+	ELDLM_OK = 0,
+
+	ELDLM_LOCK_CHANGED = 300,
+	ELDLM_LOCK_ABORTED = 301,
+	ELDLM_LOCK_REPLACED = 302,
+	ELDLM_NO_LOCK_DATA = 303,
+	ELDLM_LOCK_WOULDBLOCK = 304,
+
+	ELDLM_NAMESPACE_EXISTS = 400,
+	ELDLM_BAD_NAMESPACE    = 401
+} ldlm_error_t;
+
+/**
+ * LDLM namespace type.
+ * The "client" type is actually an indication that this is a narrow local view
+ * into complete namespace on the server. Such namespaces cannot make any
+ * decisions about lack of conflicts or do any autonomous lock granting without
+ * first speaking to a server.
+ */
+typedef enum {
+	LDLM_NAMESPACE_SERVER = 1 << 0,
+	LDLM_NAMESPACE_CLIENT = 1 << 1
+} ldlm_side_t;
+
+/**
+ * Declaration of flags sent through the wire.
+ **/
+#define LDLM_FL_LOCK_CHANGED   0x000001 /* extent, mode, or resource changed */
+
+/**
+ * If the server returns one of these flags, then the lock was put on that list.
+ * If the client sends one of these flags (during recovery ONLY!), it wants the
+ * lock added to the specified list, no questions asked.
+ */
+#define LDLM_FL_BLOCK_GRANTED  0x000002
+#define LDLM_FL_BLOCK_CONV     0x000004
+#define LDLM_FL_BLOCK_WAIT     0x000008
+
+/* Used to be LDLM_FL_CBPENDING 0x000010 moved to non-wire flags */
+
+#define LDLM_FL_AST_SENT       0x000020 /* blocking or cancel packet was
+					 * queued for sending. */
+/* Used to be LDLM_FL_WAIT_NOREPROC 0x000040   moved to non-wire flags */
+/* Used to be LDLM_FL_CANCEL	0x000080   moved to non-wire flags */
+
+/**
+ * Lock is being replayed.  This could probably be implied by the fact that one
+ * of BLOCK_{GRANTED,CONV,WAIT} is set, but that is pretty dangerous.
+ */
+#define LDLM_FL_REPLAY	 0x000100
+
+#define LDLM_FL_INTENT_ONLY    0x000200 /* Don't grant lock, just do intent. */
+
+/* Used to be LDLM_FL_LOCAL_ONLY 0x000400  moved to non-wire flags */
+/* Used to be LDLM_FL_FAILED     0x000800  moved to non-wire flags */
+
+#define LDLM_FL_HAS_INTENT     0x001000 /* lock request has intent */
+
+/* Used to be LDLM_FL_CANCELING  0x002000  moved to non-wire flags */
+/* Used to be LDLM_FL_LOCAL      0x004000  moved to non-wire flags */
+
+#define LDLM_FL_DISCARD_DATA   0x010000 /* discard (no writeback) on cancel */
+
+#define LDLM_FL_NO_TIMEOUT     0x020000 /* Blocked by group lock - wait
+					 * indefinitely */
+
+/** file & record locking */
+#define LDLM_FL_BLOCK_NOWAIT   0x040000 /* Server told not to wait if blocked.
+					 * For AGL, OST will not send glimpse
+					 * callback. */
+#define LDLM_FL_TEST_LOCK      0x080000 // return blocking lock
+
+/* Used to be LDLM_FL_LVB_READY  0x100000 moved to non-wire flags */
+/* Used to be LDLM_FL_KMS_IGNORE 0x200000 moved to non-wire flags */
+/* Used to be LDLM_FL_NO_LRU     0x400000 moved to non-wire flags */
+
+/* Immediatelly cancel such locks when they block some other locks. Send
+ * cancel notification to original lock holder, but expect no reply. This is
+ * for clients (like liblustre) that cannot be expected to reliably response
+ * to blocking AST. */
+#define LDLM_FL_CANCEL_ON_BLOCK 0x800000
+
+/* Flags flags inherited from parent lock when doing intents. */
+#define LDLM_INHERIT_FLAGS     (LDLM_FL_CANCEL_ON_BLOCK)
+
+/* Used to be LDLM_FL_CP_REQD	0x1000000 moved to non-wire flags */
+/* Used to be LDLM_FL_CLEANED	0x2000000 moved to non-wire flags */
+/* Used to be LDLM_FL_ATOMIC_CB      0x4000000 moved to non-wire flags */
+/* Used to be LDLM_FL_BL_AST	 0x10000000 moved to non-wire flags */
+/* Used to be LDLM_FL_BL_DONE	0x20000000 moved to non-wire flags */
+
+/* measure lock contention and return -EUSERS if locking contention is high */
+#define LDLM_FL_DENY_ON_CONTENTION 0x40000000
+
+/* These are flags that are mapped into the flags and ASTs of blocking locks */
+#define LDLM_AST_DISCARD_DATA  0x80000000 /* Add FL_DISCARD to blocking ASTs */
+
+/* Flags sent in AST lock_flags to be mapped into the receiving lock. */
+#define LDLM_AST_FLAGS	 (LDLM_FL_DISCARD_DATA)
+
+/*
+ * --------------------------------------------------------------------------
+ * NOTE! Starting from this point, that is, LDLM_FL_* flags with values above
+ * 0x80000000 will not be sent over the wire.
+ * --------------------------------------------------------------------------
+ */
+
+/**
+ * Declaration of flags not sent through the wire.
+ **/
+
+/**
+ * Used for marking lock as a target for -EINTR while cp_ast sleep
+ * emulation + race with upcoming bl_ast.
+ */
+#define LDLM_FL_FAIL_LOC       0x100000000ULL
+
+/**
+ * Used while processing the unused list to know that we have already
+ * handled this lock and decided to skip it.
+ */
+#define LDLM_FL_SKIPPED	0x200000000ULL
+/* this lock is being destroyed */
+#define LDLM_FL_CBPENDING      0x400000000ULL
+/* not a real flag, not saved in lock */
+#define LDLM_FL_WAIT_NOREPROC  0x800000000ULL
+/* cancellation callback already run */
+#define LDLM_FL_CANCEL	 0x1000000000ULL
+#define LDLM_FL_LOCAL_ONLY     0x2000000000ULL
+/* don't run the cancel callback under ldlm_cli_cancel_unused */
+#define LDLM_FL_FAILED	 0x4000000000ULL
+/* lock cancel has already been sent */
+#define LDLM_FL_CANCELING      0x8000000000ULL
+/* local lock (ie, no srv/cli split) */
+#define LDLM_FL_LOCAL	  0x10000000000ULL
+/* XXX FIXME: This is being added to b_size as a low-risk fix to the fact that
+ * the LVB filling happens _after_ the lock has been granted, so another thread
+ * can match it before the LVB has been updated.  As a dirty hack, we set
+ * LDLM_FL_LVB_READY only after we've done the LVB poop.
+ * this is only needed on LOV/OSC now, where LVB is actually used and callers
+ * must set it in input flags.
+ *
+ * The proper fix is to do the granting inside of the completion AST, which can
+ * be replaced with a LVB-aware wrapping function for OSC locks.  That change is
+ * pretty high-risk, though, and would need a lot more testing. */
+#define LDLM_FL_LVB_READY      0x20000000000ULL
+/* A lock contributes to the known minimum size (KMS) calculation until it has
+ * finished the part of its cancelation that performs write back on its dirty
+ * pages.  It can remain on the granted list during this whole time.  Threads
+ * racing to update the KMS after performing their writeback need to know to
+ * exclude each other's locks from the calculation as they walk the granted
+ * list. */
+#define LDLM_FL_KMS_IGNORE     0x40000000000ULL
+/* completion AST to be executed */
+#define LDLM_FL_CP_REQD	0x80000000000ULL
+/* cleanup_resource has already handled the lock */
+#define LDLM_FL_CLEANED	0x100000000000ULL
+/* optimization hint: LDLM can run blocking callback from current context
+ * w/o involving separate thread. in order to decrease cs rate */
+#define LDLM_FL_ATOMIC_CB      0x200000000000ULL
+
+/* It may happen that a client initiates two operations, e.g. unlink and
+ * mkdir, such that the server sends a blocking AST for conflicting
+ * locks to this client for the first operation, whereas the second
+ * operation has canceled this lock and is waiting for rpc_lock which is
+ * taken by the first operation. LDLM_FL_BL_AST is set by
+ * ldlm_callback_handler() in the lock to prevent the Early Lock Cancel
+ * (ELC) code from cancelling it.
+ *
+ * LDLM_FL_BL_DONE is to be set by ldlm_cancel_callback() when lock
+ * cache is dropped to let ldlm_callback_handler() return EINVAL to the
+ * server. It is used when ELC RPC is already prepared and is waiting
+ * for rpc_lock, too late to send a separate CANCEL RPC. */
+#define LDLM_FL_BL_AST	  0x400000000000ULL
+#define LDLM_FL_BL_DONE	 0x800000000000ULL
+/* Don't put lock into the LRU list, so that it is not canceled due to aging.
+ * Used by MGC locks, they are cancelled only at unmount or by callback. */
+#define LDLM_FL_NO_LRU		0x1000000000000ULL
+
+/**
+ * The blocking callback is overloaded to perform two functions.  These flags
+ * indicate which operation should be performed.
+ */
+#define LDLM_CB_BLOCKING    1
+#define LDLM_CB_CANCELING   2
+
+/**
+ * \name Lock Compatibility Matrix.
+ *
+ * A lock has both a type (extent, flock, inode bits, or plain) and a mode.
+ * Lock types are described in their respective implementation files:
+ * ldlm_{extent,flock,inodebits,plain}.c.
+ *
+ * There are six lock modes along with a compatibility matrix to indicate if
+ * two locks are compatible.
+ *
+ * - EX: Exclusive mode. Before a new file is created, MDS requests EX lock
+ *   on the parent.
+ * - PW: Protective Write (normal write) mode. When a client requests a write
+ *   lock from an OST, a lock with PW mode will be issued.
+ * - PR: Protective Read (normal read) mode. When a client requests a read from
+ *   an OST, a lock with PR mode will be issued. Also, if the client opens a
+ *   file for execution, it is granted a lock with PR mode.
+ * - CW: Concurrent Write mode. The type of lock that the MDS grants if a client
+ *   requests a write lock during a file open operation.
+ * - CR Concurrent Read mode. When a client performs a path lookup, MDS grants
+ *   an inodebit lock with the CR mode on the intermediate path component.
+ * - NL Null mode.
+ *
+ * <PRE>
+ *       NL  CR  CW  PR  PW  EX
+ *  NL    1   1   1   1   1   1
+ *  CR    1   1   1   1   1   0
+ *  CW    1   1   1   0   0   0
+ *  PR    1   1   0   1   0   0
+ *  PW    1   1   0   0   0   0
+ *  EX    1   0   0   0   0   0
+ * </PRE>
+ */
+/** @{ */
+#define LCK_COMPAT_EX  LCK_NL
+#define LCK_COMPAT_PW  (LCK_COMPAT_EX | LCK_CR)
+#define LCK_COMPAT_PR  (LCK_COMPAT_PW | LCK_PR)
+#define LCK_COMPAT_CW  (LCK_COMPAT_PW | LCK_CW)
+#define LCK_COMPAT_CR  (LCK_COMPAT_CW | LCK_PR | LCK_PW)
+#define LCK_COMPAT_NL  (LCK_COMPAT_CR | LCK_EX | LCK_GROUP)
+#define LCK_COMPAT_GROUP  (LCK_GROUP | LCK_NL)
+#define LCK_COMPAT_COS (LCK_COS)
+/** @} Lock Compatibility Matrix */
+
+extern ldlm_mode_t lck_compat_array[];
+
+static inline void lockmode_verify(ldlm_mode_t mode)
+{
+       LASSERT(mode > LCK_MINMODE && mode < LCK_MAXMODE);
+}
+
+static inline int lockmode_compat(ldlm_mode_t exist_mode, ldlm_mode_t new_mode)
+{
+       return (lck_compat_array[exist_mode] & new_mode);
+}
+
+/*
+ *
+ * cluster name spaces
+ *
+ */
+
+#define DLM_OST_NAMESPACE 1
+#define DLM_MDS_NAMESPACE 2
+
+/* XXX
+   - do we just separate this by security domains and use a prefix for
+     multiple namespaces in the same domain?
+   -
+*/
+
+/**
+ * Locking rules for LDLM:
+ *
+ * lr_lock
+ *
+ * lr_lock
+ *     waiting_locks_spinlock
+ *
+ * lr_lock
+ *     led_lock
+ *
+ * lr_lock
+ *     ns_lock
+ *
+ * lr_lvb_mutex
+ *     lr_lock
+ *
+ */
+
+struct ldlm_pool;
+struct ldlm_lock;
+struct ldlm_resource;
+struct ldlm_namespace;
+
+/**
+ * Operations on LDLM pools.
+ * LDLM pool is a pool of locks in the namespace without any implicitly
+ * specified limits.
+ * Locks in the pool are organized in LRU.
+ * Local memory pressure or server instructions (e.g. mempressure on server)
+ * can trigger freeing of locks from the pool
+ */
+struct ldlm_pool_ops {
+	/** Recalculate pool \a pl usage */
+	int (*po_recalc)(struct ldlm_pool *pl);
+	/** Cancel at least \a nr locks from pool \a pl */
+	int (*po_shrink)(struct ldlm_pool *pl, int nr,
+			 unsigned int gfp_mask);
+	int (*po_setup)(struct ldlm_pool *pl, int limit);
+};
+
+/** One second for pools thread check interval. Each pool has own period. */
+#define LDLM_POOLS_THREAD_PERIOD (1)
+
+/** ~6% margin for modest pools. See ldlm_pool.c for details. */
+#define LDLM_POOLS_MODEST_MARGIN_SHIFT (4)
+
+/** Default recalc period for server side pools in sec. */
+#define LDLM_POOL_SRV_DEF_RECALC_PERIOD (1)
+
+/** Default recalc period for client side pools in sec. */
+#define LDLM_POOL_CLI_DEF_RECALC_PERIOD (10)
+
+/**
+ * LDLM pool structure to track granted locks.
+ * For purposes of determining when to release locks on e.g. memory pressure.
+ * This feature is commonly referred to as lru_resize.
+ */
+struct ldlm_pool {
+	/** Pool proc directory. */
+	proc_dir_entry_t	*pl_proc_dir;
+	/** Pool name, must be long enough to hold compound proc entry name. */
+	char			pl_name[100];
+	/** Lock for protecting SLV/CLV updates. */
+	spinlock_t		pl_lock;
+	/** Number of allowed locks in in pool, both, client and server side. */
+	atomic_t		pl_limit;
+	/** Number of granted locks in */
+	atomic_t		pl_granted;
+	/** Grant rate per T. */
+	atomic_t		pl_grant_rate;
+	/** Cancel rate per T. */
+	atomic_t		pl_cancel_rate;
+	/** Server lock volume (SLV). Protected by pl_lock. */
+	__u64			pl_server_lock_volume;
+	/** Current biggest client lock volume. Protected by pl_lock. */
+	__u64			pl_client_lock_volume;
+	/** Lock volume factor. SLV on client is calculated as following:
+	 *  server_slv * lock_volume_factor. */
+	atomic_t		pl_lock_volume_factor;
+	/** Time when last SLV from server was obtained. */
+	time_t			pl_recalc_time;
+	/** Recalculation period for pool. */
+	time_t			pl_recalc_period;
+	/** Recalculation and shrink operations. */
+	struct ldlm_pool_ops	*pl_ops;
+	/** Number of planned locks for next period. */
+	int			pl_grant_plan;
+	/** Pool statistics. */
+	struct lprocfs_stats	*pl_stats;
+};
+
+typedef int (*ldlm_res_policy)(struct ldlm_namespace *, struct ldlm_lock **,
+			       void *req_cookie, ldlm_mode_t mode, __u64 flags,
+			       void *data);
+
+typedef int (*ldlm_cancel_for_recovery)(struct ldlm_lock *lock);
+
+/**
+ * LVB operations.
+ * LVB is Lock Value Block. This is a special opaque (to LDLM) value that could
+ * be associated with an LDLM lock and transferred from client to server and
+ * back.
+ *
+ * Currently LVBs are used by:
+ *  - OSC-OST code to maintain current object size/times
+ *  - layout lock code to return the layout when the layout lock is granted
+ */
+struct ldlm_valblock_ops {
+	int (*lvbo_init)(struct ldlm_resource *res);
+	int (*lvbo_update)(struct ldlm_resource *res,
+			   struct ptlrpc_request *r,
+			   int increase);
+	int (*lvbo_free)(struct ldlm_resource *res);
+	/* Return size of lvb data appropriate RPC size can be reserved */
+	int (*lvbo_size)(struct ldlm_lock *lock);
+	/* Called to fill in lvb data to RPC buffer @buf */
+	int (*lvbo_fill)(struct ldlm_lock *lock, void *buf, int buflen);
+};
+
+/**
+ * LDLM pools related, type of lock pool in the namespace.
+ * Greedy means release cached locks aggressively
+ */
+typedef enum {
+	LDLM_NAMESPACE_GREEDY = 1 << 0,
+	LDLM_NAMESPACE_MODEST = 1 << 1
+} ldlm_appetite_t;
+
+/**
+ * Default values for the "max_nolock_size", "contention_time" and
+ * "contended_locks" namespace tunables.
+ */
+#define NS_DEFAULT_MAX_NOLOCK_BYTES 0
+#define NS_DEFAULT_CONTENTION_SECONDS 2
+#define NS_DEFAULT_CONTENDED_LOCKS 32
+
+struct ldlm_ns_bucket {
+	/** back pointer to namespace */
+	struct ldlm_namespace      *nsb_namespace;
+	/**
+	 * Estimated lock callback time.  Used by adaptive timeout code to
+	 * avoid spurious client evictions due to unresponsiveness when in
+	 * fact the network or overall system load is at fault
+	 */
+	struct adaptive_timeout     nsb_at_estimate;
+};
+
+enum {
+	/** LDLM namespace lock stats */
+	LDLM_NSS_LOCKS	  = 0,
+	LDLM_NSS_LAST
+};
+
+typedef enum {
+	/** invalide type */
+	LDLM_NS_TYPE_UNKNOWN    = 0,
+	/** mdc namespace */
+	LDLM_NS_TYPE_MDC,
+	/** mds namespace */
+	LDLM_NS_TYPE_MDT,
+	/** osc namespace */
+	LDLM_NS_TYPE_OSC,
+	/** ost namespace */
+	LDLM_NS_TYPE_OST,
+	/** mgc namespace */
+	LDLM_NS_TYPE_MGC,
+	/** mgs namespace */
+	LDLM_NS_TYPE_MGT,
+} ldlm_ns_type_t;
+
+/**
+ * LDLM Namespace.
+ *
+ * Namespace serves to contain locks related to a particular service.
+ * There are two kinds of namespaces:
+ * - Server namespace has knowledge of all locks and is therefore authoritative
+ *   to make decisions like what locks could be granted and what conflicts
+ *   exist during new lock enqueue.
+ * - Client namespace only has limited knowledge about locks in the namespace,
+ *   only seeing locks held by the client.
+ *
+ * Every Lustre service has one server namespace present on the server serving
+ * that service. Every client connected to the service has a client namespace
+ * for it.
+ * Every lock obtained by client in that namespace is actually represented by
+ * two in-memory locks. One on the server and one on the client. The locks are
+ * linked by a special cookie by which one node can tell to the other which lock
+ * it actually means during communications. Such locks are called remote locks.
+ * The locks held by server only without any reference to a client are called
+ * local locks.
+ */
+struct ldlm_namespace {
+	/** Backward link to OBD, required for LDLM pool to store new SLV. */
+	struct obd_device	*ns_obd;
+
+	/** Flag indicating if namespace is on client instead of server */
+	ldlm_side_t		ns_client;
+
+	/** Resource hash table for namespace. */
+	cfs_hash_t		*ns_rs_hash;
+
+	/** serialize */
+	spinlock_t		ns_lock;
+
+	/** big refcount (by bucket) */
+	atomic_t		ns_bref;
+
+	/**
+	 * Namespace connect flags supported by server (may be changed via
+	 * /proc, LRU resize may be disabled/enabled).
+	 */
+	__u64			ns_connect_flags;
+
+	/** Client side original connect flags supported by server. */
+	__u64			ns_orig_connect_flags;
+
+	/* namespace proc dir entry */
+	struct proc_dir_entry	*ns_proc_dir_entry;
+
+	/**
+	 * Position in global namespace list linking all namespaces on
+	 * the node.
+	 */
+	struct list_head		ns_list_chain;
+
+	/**
+	 * List of unused locks for this namespace. This list is also called
+	 * LRU lock list.
+	 * Unused locks are locks with zero reader/writer reference counts.
+	 * This list is only used on clients for lock caching purposes.
+	 * When we want to release some locks voluntarily or if server wants
+	 * us to release some locks due to e.g. memory pressure, we take locks
+	 * to release from the head of this list.
+	 * Locks are linked via l_lru field in \see struct ldlm_lock.
+	 */
+	struct list_head		ns_unused_list;
+	/** Number of locks in the LRU list above */
+	int			ns_nr_unused;
+
+	/**
+	 * Maximum number of locks permitted in the LRU. If 0, means locks
+	 * are managed by pools and there is no preset limit, rather it is all
+	 * controlled by available memory on this client and on server.
+	 */
+	unsigned int		ns_max_unused;
+	/** Maximum allowed age (last used time) for locks in the LRU */
+	unsigned int		ns_max_age;
+	/**
+	 * Server only: number of times we evicted clients due to lack of reply
+	 * to ASTs.
+	 */
+	unsigned int		ns_timeouts;
+	/**
+	 * Number of seconds since the file change time after which the
+	 * MDT will return an UPDATE lock along with a LOOKUP lock.
+	 * This allows the client to start caching negative dentries
+	 * for a directory and may save an RPC for a later stat.
+	 */
+	unsigned int		ns_ctime_age_limit;
+
+	/**
+	 * Used to rate-limit ldlm_namespace_dump calls.
+	 * \see ldlm_namespace_dump. Increased by 10 seconds every time
+	 * it is called.
+	 */
+	cfs_time_t		ns_next_dump;
+
+	/** "policy" function that does actual lock conflict determination */
+	ldlm_res_policy		ns_policy;
+
+	/**
+	 * LVB operations for this namespace.
+	 * \see struct ldlm_valblock_ops
+	 */
+	struct ldlm_valblock_ops *ns_lvbo;
+
+	/**
+	 * Used by filter code to store pointer to OBD of the service.
+	 * Should be dropped in favor of \a ns_obd
+	 */
+	void			*ns_lvbp;
+
+	/**
+	 * Wait queue used by __ldlm_namespace_free. Gets woken up every time
+	 * a resource is removed.
+	 */
+	wait_queue_head_t		ns_waitq;
+	/** LDLM pool structure for this namespace */
+	struct ldlm_pool	ns_pool;
+	/** Definition of how eagerly unused locks will be released from LRU */
+	ldlm_appetite_t		ns_appetite;
+
+	/**
+	 * If more than \a ns_contended_locks are found, the resource is
+	 * considered to be contended. Lock enqueues might specify that no
+	 * contended locks should be granted
+	 */
+	unsigned		ns_contended_locks;
+
+	/**
+	 * The resources in this namespace remember contended state during
+	 * \a ns_contention_time, in seconds.
+	 */
+	unsigned		ns_contention_time;
+
+	/**
+	 * Limit size of contended extent locks, in bytes.
+	 * If extended lock is requested for more then this many bytes and
+	 * caller instructs us not to grant contended locks, we would disregard
+	 * such a request.
+	 */
+	unsigned		ns_max_nolock_size;
+
+	/** Limit of parallel AST RPC count. */
+	unsigned		ns_max_parallel_ast;
+
+	/** Callback to cancel locks before replaying it during recovery. */
+	ldlm_cancel_for_recovery ns_cancel_for_recovery;
+
+	/** LDLM lock stats */
+	struct lprocfs_stats	*ns_stats;
+
+	/**
+	 * Flag to indicate namespace is being freed. Used to determine if
+	 * recalculation of LDLM pool statistics should be skipped.
+	 */
+	unsigned		ns_stopping:1;
+};
+
+/**
+ * Returns 1 if namespace \a ns is a client namespace.
+ */
+static inline int ns_is_client(struct ldlm_namespace *ns)
+{
+	LASSERT(ns != NULL);
+	LASSERT(!(ns->ns_client & ~(LDLM_NAMESPACE_CLIENT |
+				    LDLM_NAMESPACE_SERVER)));
+	LASSERT(ns->ns_client == LDLM_NAMESPACE_CLIENT ||
+		ns->ns_client == LDLM_NAMESPACE_SERVER);
+	return ns->ns_client == LDLM_NAMESPACE_CLIENT;
+}
+
+/**
+ * Returns 1 if namespace \a ns is a server namespace.
+ */
+static inline int ns_is_server(struct ldlm_namespace *ns)
+{
+	LASSERT(ns != NULL);
+	LASSERT(!(ns->ns_client & ~(LDLM_NAMESPACE_CLIENT |
+				    LDLM_NAMESPACE_SERVER)));
+	LASSERT(ns->ns_client == LDLM_NAMESPACE_CLIENT ||
+		ns->ns_client == LDLM_NAMESPACE_SERVER);
+	return ns->ns_client == LDLM_NAMESPACE_SERVER;
+}
+
+/**
+ * Returns 1 if namespace \a ns supports early lock cancel (ELC).
+ */
+static inline int ns_connect_cancelset(struct ldlm_namespace *ns)
+{
+	LASSERT(ns != NULL);
+	return !!(ns->ns_connect_flags & OBD_CONNECT_CANCELSET);
+}
+
+/**
+ * Returns 1 if this namespace supports lru_resize.
+ */
+static inline int ns_connect_lru_resize(struct ldlm_namespace *ns)
+{
+	LASSERT(ns != NULL);
+	return !!(ns->ns_connect_flags & OBD_CONNECT_LRU_RESIZE);
+}
+
+static inline void ns_register_cancel(struct ldlm_namespace *ns,
+				      ldlm_cancel_for_recovery arg)
+{
+	LASSERT(ns != NULL);
+	ns->ns_cancel_for_recovery = arg;
+}
+
+struct ldlm_lock;
+
+/** Type for blocking callback function of a lock. */
+typedef int (*ldlm_blocking_callback)(struct ldlm_lock *lock,
+				      struct ldlm_lock_desc *new, void *data,
+				      int flag);
+/** Type for completion callback function of a lock. */
+typedef int (*ldlm_completion_callback)(struct ldlm_lock *lock, __u64 flags,
+					void *data);
+/** Type for glimpse callback function of a lock. */
+typedef int (*ldlm_glimpse_callback)(struct ldlm_lock *lock, void *data);
+/** Type for weight callback function of a lock. */
+typedef unsigned long (*ldlm_weigh_callback)(struct ldlm_lock *lock);
+
+/** Work list for sending GL ASTs to multiple locks. */
+struct ldlm_glimpse_work {
+	struct ldlm_lock	*gl_lock; /* lock to glimpse */
+	struct list_head		 gl_list; /* linkage to other gl work structs */
+	__u32			 gl_flags;/* see LDLM_GL_WORK_* below */
+	union ldlm_gl_desc	*gl_desc; /* glimpse descriptor to be packed in
+					   * glimpse callback request */
+};
+
+/** The ldlm_glimpse_work is allocated on the stack and should not be freed. */
+#define LDLM_GL_WORK_NOFREE 0x1
+
+/** Interval node data for each LDLM_EXTENT lock. */
+struct ldlm_interval {
+	struct interval_node	li_node;  /* node for tree management */
+	struct list_head		li_group; /* the locks which have the same
+					   * policy - group of the policy */
+};
+#define to_ldlm_interval(n) container_of(n, struct ldlm_interval, li_node)
+
+/**
+ * Interval tree for extent locks.
+ * The interval tree must be accessed under the resource lock.
+ * Interval trees are used for granted extent locks to speed up conflicts
+ * lookup. See ldlm/interval_tree.c for more details.
+ */
+struct ldlm_interval_tree {
+	/** Tree size. */
+	int			lit_size;
+	ldlm_mode_t		lit_mode;  /* lock mode */
+	struct interval_node	*lit_root; /* actual ldlm_interval */
+};
+
+/** Whether to track references to exports by LDLM locks. */
+#define LUSTRE_TRACKS_LOCK_EXP_REFS (0)
+
+/** Cancel flags. */
+typedef enum {
+	LCF_ASYNC      = 0x1, /* Cancel locks asynchronously. */
+	LCF_LOCAL      = 0x2, /* Cancel locks locally, not notifing server */
+	LCF_BL_AST     = 0x4, /* Cancel locks marked as LDLM_FL_BL_AST
+			       * in the same RPC */
+} ldlm_cancel_flags_t;
+
+struct ldlm_flock {
+	__u64 start;
+	__u64 end;
+	__u64 owner;
+	__u64 blocking_owner;
+	struct obd_export *blocking_export;
+	/* Protected by the hash lock */
+	__u32 blocking_refs;
+	__u32 pid;
+};
+
+typedef union {
+	struct ldlm_extent l_extent;
+	struct ldlm_flock l_flock;
+	struct ldlm_inodebits l_inodebits;
+} ldlm_policy_data_t;
+
+void ldlm_convert_policy_to_wire(ldlm_type_t type,
+				 const ldlm_policy_data_t *lpolicy,
+				 ldlm_wire_policy_data_t *wpolicy);
+void ldlm_convert_policy_to_local(struct obd_export *exp, ldlm_type_t type,
+				  const ldlm_wire_policy_data_t *wpolicy,
+				  ldlm_policy_data_t *lpolicy);
+
+enum lvb_type {
+	LVB_T_NONE	= 0,
+	LVB_T_OST	= 1,
+	LVB_T_LQUOTA	= 2,
+	LVB_T_LAYOUT	= 3,
+};
+
+/**
+ * LDLM lock structure
+ *
+ * Represents a single LDLM lock and its state in memory. Each lock is
+ * associated with a single ldlm_resource, the object which is being
+ * locked. There may be multiple ldlm_locks on a single resource,
+ * depending on the lock type and whether the locks are conflicting or
+ * not.
+ */
+struct ldlm_lock {
+	/**
+	 * Local lock handle.
+	 * When remote side wants to tell us about a lock, they address
+	 * it by this opaque handle.  The handle does not hold a
+	 * reference on the ldlm_lock, so it can be safely passed to
+	 * other threads or nodes. When the lock needs to be accessed
+	 * from the handle, it is looked up again in the lock table, and
+	 * may no longer exist.
+	 *
+	 * Must be first in the structure.
+	 */
+	struct portals_handle	l_handle;
+	/**
+	 * Lock reference count.
+	 * This is how many users have pointers to actual structure, so that
+	 * we do not accidentally free lock structure that is in use.
+	 */
+	atomic_t		l_refc;
+	/**
+	 * Internal spinlock protects l_resource.  We should hold this lock
+	 * first before taking res_lock.
+	 */
+	spinlock_t		l_lock;
+	/**
+	 * Pointer to actual resource this lock is in.
+	 * ldlm_lock_change_resource() can change this.
+	 */
+	struct ldlm_resource	*l_resource;
+	/**
+	 * List item for client side LRU list.
+	 * Protected by ns_lock in struct ldlm_namespace.
+	 */
+	struct list_head		l_lru;
+	/**
+	 * Linkage to resource's lock queues according to current lock state.
+	 * (could be granted, waiting or converting)
+	 * Protected by lr_lock in struct ldlm_resource.
+	 */
+	struct list_head		l_res_link;
+	/**
+	 * Tree node for ldlm_extent.
+	 */
+	struct ldlm_interval	*l_tree_node;
+	/**
+	 * Per export hash of locks.
+	 * Protected by per-bucket exp->exp_lock_hash locks.
+	 */
+	struct hlist_node	l_exp_hash;
+	/**
+	 * Per export hash of flock locks.
+	 * Protected by per-bucket exp->exp_flock_hash locks.
+	 */
+	struct hlist_node	l_exp_flock_hash;
+	/**
+	 * Requested mode.
+	 * Protected by lr_lock.
+	 */
+	ldlm_mode_t		l_req_mode;
+	/**
+	 * Granted mode, also protected by lr_lock.
+	 */
+	ldlm_mode_t		l_granted_mode;
+	/** Lock completion handler pointer. Called when lock is granted. */
+	ldlm_completion_callback l_completion_ast;
+	/**
+	 * Lock blocking AST handler pointer.
+	 * It plays two roles:
+	 * - as a notification of an attempt to queue a conflicting lock (once)
+	 * - as a notification when the lock is being cancelled.
+	 *
+	 * As such it's typically called twice: once for the initial conflict
+	 * and then once more when the last user went away and the lock is
+	 * cancelled (could happen recursively).
+	 */
+	ldlm_blocking_callback	l_blocking_ast;
+	/**
+	 * Lock glimpse handler.
+	 * Glimpse handler is used to obtain LVB updates from a client by
+	 * server
+	 */
+	ldlm_glimpse_callback	l_glimpse_ast;
+
+	/** XXX apparently unused "weight" handler. To be removed? */
+	ldlm_weigh_callback	l_weigh_ast;
+
+	/**
+	 * Lock export.
+	 * This is a pointer to actual client export for locks that were granted
+	 * to clients. Used server-side.
+	 */
+	struct obd_export	*l_export;
+	/**
+	 * Lock connection export.
+	 * Pointer to server export on a client.
+	 */
+	struct obd_export	*l_conn_export;
+
+	/**
+	 * Remote lock handle.
+	 * If the lock is remote, this is the handle of the other side lock
+	 * (l_handle)
+	 */
+	struct lustre_handle	l_remote_handle;
+
+	/**
+	 * Representation of private data specific for a lock type.
+	 * Examples are: extent range for extent lock or bitmask for ibits locks
+	 */
+	ldlm_policy_data_t	l_policy_data;
+
+	/**
+	 * Lock state flags.
+	 * Like whenever we receive any blocking requests for this lock, etc.
+	 * Protected by lr_lock.
+	 */
+	__u64			l_flags;
+	/**
+	 * Lock r/w usage counters.
+	 * Protected by lr_lock.
+	 */
+	__u32			l_readers;
+	__u32			l_writers;
+	/**
+	 * If the lock is granted, a process sleeps on this waitq to learn when
+	 * it's no longer in use.  If the lock is not granted, a process sleeps
+	 * on this waitq to learn when it becomes granted.
+	 */
+	wait_queue_head_t		l_waitq;
+
+	/**
+	 * Seconds. It will be updated if there is any activity related to
+	 * the lock, e.g. enqueue the lock or send blocking AST.
+	 */
+	cfs_time_t		l_last_activity;
+
+	/**
+	 * Time last used by e.g. being matched by lock match.
+	 * Jiffies. Should be converted to time if needed.
+	 */
+	cfs_time_t		l_last_used;
+
+	/** Originally requested extent for the extent lock. */
+	struct ldlm_extent	l_req_extent;
+
+	unsigned int		l_failed:1,
+	/**
+	 * Set for locks that were removed from class hash table and will be
+	 * destroyed when last reference to them is released. Set by
+	 * ldlm_lock_destroy_internal().
+	 *
+	 * Protected by lock and resource locks.
+	 */
+				l_destroyed:1,
+	/*
+	 * it's set in lock_res_and_lock() and unset in unlock_res_and_lock().
+	 *
+	 * NB: compared with check_res_locked(), checking this bit is cheaper.
+	 * Also, spin_is_locked() is deprecated for kernel code; one reason is
+	 * because it works only for SMP so user needs to add extra macros like
+	 * LASSERT_SPIN_LOCKED for uniprocessor kernels.
+	 */
+				l_res_locked:1,
+	/*
+	 * It's set once we call ldlm_add_waiting_lock_res_locked()
+	 * to start the lock-timeout timer and it will never be reset.
+	 *
+	 * Protected by lock_res_and_lock().
+	 */
+				l_waited:1,
+	/** Flag whether this is a server namespace lock. */
+				l_ns_srv:1;
+
+	/*
+	 * Client-side-only members.
+	 */
+
+	enum lvb_type	      l_lvb_type;
+
+	/**
+	 * Temporary storage for a LVB received during an enqueue operation.
+	 */
+	__u32			l_lvb_len;
+	void			*l_lvb_data;
+
+	/** Private storage for lock user. Opaque to LDLM. */
+	void			*l_ast_data;
+
+	/*
+	 * Server-side-only members.
+	 */
+
+	/**
+	 * Connection cookie for the client originating the operation.
+	 * Used by Commit on Share (COS) code. Currently only used for
+	 * inodebits locks on MDS.
+	 */
+	__u64			l_client_cookie;
+
+	/**
+	 * List item for locks waiting for cancellation from clients.
+	 * The lists this could be linked into are:
+	 * waiting_locks_list (protected by waiting_locks_spinlock),
+	 * then if the lock timed out, it is moved to
+	 * expired_lock_thread.elt_expired_locks for further processing.
+	 * Protected by elt_lock.
+	 */
+	struct list_head		l_pending_chain;
+
+	/**
+	 * Set when lock is sent a blocking AST. Time in seconds when timeout
+	 * is reached and client holding this lock could be evicted.
+	 * This timeout could be further extended by e.g. certain IO activity
+	 * under this lock.
+	 * \see ost_rw_prolong_locks
+	 */
+	cfs_time_t		l_callback_timeout;
+
+	/** Local PID of process which created this lock. */
+	__u32			l_pid;
+
+	/**
+	 * Number of times blocking AST was sent for this lock.
+	 * This is for debugging. Valid values are 0 and 1, if there is an
+	 * attempt to send blocking AST more than once, an assertion would be
+	 * hit. \see ldlm_work_bl_ast_lock
+	 */
+	int			l_bl_ast_run;
+	/** List item ldlm_add_ast_work_item() for case of blocking ASTs. */
+	struct list_head		l_bl_ast;
+	/** List item ldlm_add_ast_work_item() for case of completion ASTs. */
+	struct list_head		l_cp_ast;
+	/** For ldlm_add_ast_work_item() for "revoke" AST used in COS. */
+	struct list_head		l_rk_ast;
+
+	/**
+	 * Pointer to a conflicting lock that caused blocking AST to be sent
+	 * for this lock
+	 */
+	struct ldlm_lock	*l_blocking_lock;
+
+	/**
+	 * Protected by lr_lock, linkages to "skip lists".
+	 * For more explanations of skip lists see ldlm/ldlm_inodebits.c
+	 */
+	struct list_head		l_sl_mode;
+	struct list_head		l_sl_policy;
+
+	/** Reference tracking structure to debug leaked locks. */
+	struct lu_ref		l_reference;
+#if LUSTRE_TRACKS_LOCK_EXP_REFS
+	/* Debugging stuff for bug 20498, for tracking export references. */
+	/** number of export references taken */
+	int			l_exp_refs_nr;
+	/** link all locks referencing one export */
+	struct list_head		l_exp_refs_link;
+	/** referenced export object */
+	struct obd_export	*l_exp_refs_target;
+#endif
+	/**
+	 * export blocking dlm lock list, protected by
+	 * l_export->exp_bl_list_lock.
+	 * Lock order of waiting_lists_spinlock, exp_bl_list_lock and res lock
+	 * is: res lock -> exp_bl_list_lock -> wanting_lists_spinlock.
+	 */
+	struct list_head		l_exp_list;
+};
+
+/**
+ * LDLM resource description.
+ * Basically, resource is a representation for a single object.
+ * Object has a name which is currently 4 64-bit integers. LDLM user is
+ * responsible for creation of a mapping between objects it wants to be
+ * protected and resource names.
+ *
+ * A resource can only hold locks of a single lock type, though there may be
+ * multiple ldlm_locks on a single resource, depending on the lock type and
+ * whether the locks are conflicting or not.
+ */
+struct ldlm_resource {
+	struct ldlm_ns_bucket	*lr_ns_bucket;
+
+	/**
+	 * List item for list in namespace hash.
+	 * protected by ns_lock
+	 */
+	struct hlist_node	lr_hash;
+
+	/** Spinlock to protect locks under this resource. */
+	spinlock_t		lr_lock;
+
+	/**
+	 * protected by lr_lock
+	 * @{ */
+	/** List of locks in granted state */
+	struct list_head		lr_granted;
+	/** List of locks waiting to change their granted mode (converted) */
+	struct list_head		lr_converting;
+	/**
+	 * List of locks that could not be granted due to conflicts and
+	 * that are waiting for conflicts to go away */
+	struct list_head		lr_waiting;
+	/** @} */
+
+	/* XXX No longer needed? Remove ASAP */
+	ldlm_mode_t		lr_most_restr;
+
+	/** Type of locks this resource can hold. Only one type per resource. */
+	ldlm_type_t		lr_type; /* LDLM_{PLAIN,EXTENT,FLOCK,IBITS} */
+
+	/** Resource name */
+	struct ldlm_res_id	lr_name;
+	/** Reference count for this resource */
+	atomic_t		lr_refcount;
+
+	/**
+	 * Interval trees (only for extent locks) for all modes of this resource
+	 */
+	struct ldlm_interval_tree lr_itree[LCK_MODE_NUM];
+
+	/**
+	 * Server-side-only lock value block elements.
+	 * To serialize lvbo_init.
+	 */
+	struct mutex		lr_lvb_mutex;
+	int			lr_lvb_len;
+	/** protected by lr_lock */
+	void			*lr_lvb_data;
+
+	/** When the resource was considered as contended. */
+	cfs_time_t		lr_contention_time;
+	/** List of references to this resource. For debugging. */
+	struct lu_ref		lr_reference;
+
+	struct inode		*lr_lvb_inode;
+};
+
+static inline bool ldlm_has_layout(struct ldlm_lock *lock)
+{
+	return lock->l_resource->lr_type == LDLM_IBITS &&
+		lock->l_policy_data.l_inodebits.bits & MDS_INODELOCK_LAYOUT;
+}
+
+static inline char *
+ldlm_ns_name(struct ldlm_namespace *ns)
+{
+	return ns->ns_rs_hash->hs_name;
+}
+
+static inline struct ldlm_namespace *
+ldlm_res_to_ns(struct ldlm_resource *res)
+{
+	return res->lr_ns_bucket->nsb_namespace;
+}
+
+static inline struct ldlm_namespace *
+ldlm_lock_to_ns(struct ldlm_lock *lock)
+{
+	return ldlm_res_to_ns(lock->l_resource);
+}
+
+static inline char *
+ldlm_lock_to_ns_name(struct ldlm_lock *lock)
+{
+	return ldlm_ns_name(ldlm_lock_to_ns(lock));
+}
+
+static inline struct adaptive_timeout *
+ldlm_lock_to_ns_at(struct ldlm_lock *lock)
+{
+	return &lock->l_resource->lr_ns_bucket->nsb_at_estimate;
+}
+
+static inline int ldlm_lvbo_init(struct ldlm_resource *res)
+{
+	struct ldlm_namespace *ns = ldlm_res_to_ns(res);
+
+	if (ns->ns_lvbo != NULL && ns->ns_lvbo->lvbo_init != NULL)
+		return ns->ns_lvbo->lvbo_init(res);
+
+	return 0;
+}
+
+static inline int ldlm_lvbo_size(struct ldlm_lock *lock)
+{
+	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
+
+	if (ns->ns_lvbo != NULL && ns->ns_lvbo->lvbo_size != NULL)
+		return ns->ns_lvbo->lvbo_size(lock);
+
+	return 0;
+}
+
+static inline int ldlm_lvbo_fill(struct ldlm_lock *lock, void *buf, int len)
+{
+	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
+
+	if (ns->ns_lvbo != NULL) {
+		LASSERT(ns->ns_lvbo->lvbo_fill != NULL);
+		return ns->ns_lvbo->lvbo_fill(lock, buf, len);
+	}
+	return 0;
+}
+
+struct ldlm_ast_work {
+	struct ldlm_lock      *w_lock;
+	int		    w_blocking;
+	struct ldlm_lock_desc  w_desc;
+	struct list_head	     w_list;
+	int		    w_flags;
+	void		  *w_data;
+	int		    w_datalen;
+};
+
+/**
+ * Common ldlm_enqueue parameters
+ */
+struct ldlm_enqueue_info {
+	__u32 ei_type;   /** Type of the lock being enqueued. */
+	__u32 ei_mode;   /** Mode of the lock being enqueued. */
+	void *ei_cb_bl;  /** blocking lock callback */
+	void *ei_cb_cp;  /** lock completion callback */
+	void *ei_cb_gl;  /** lock glimpse callback */
+	void *ei_cb_wg;  /** lock weigh callback */
+	void *ei_cbdata; /** Data to be passed into callbacks. */
+};
+
+extern struct obd_ops ldlm_obd_ops;
+
+extern char *ldlm_lockname[];
+extern char *ldlm_typename[];
+extern char *ldlm_it2str(int it);
+
+/**
+ * Just a fancy CDEBUG call with log level preset to LDLM_DEBUG.
+ * For the cases where we do not have actual lock to print along
+ * with a debugging message that is ldlm-related
+ */
+#define LDLM_DEBUG_NOLOCK(format, a...)			\
+	CDEBUG(D_DLMTRACE, "### " format "\n" , ##a)
+
+/**
+ * Support function for lock information printing into debug logs.
+ * \see LDLM_DEBUG
+ */
+#define ldlm_lock_debug(msgdata, mask, cdls, lock, fmt, a...) do {      \
+	CFS_CHECK_STACK(msgdata, mask, cdls);			   \
+									\
+	if (((mask) & D_CANTMASK) != 0 ||			       \
+	    ((libcfs_debug & (mask)) != 0 &&			    \
+	     (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0))	  \
+		_ldlm_lock_debug(lock, msgdata, fmt, ##a);	      \
+} while(0)
+
+void _ldlm_lock_debug(struct ldlm_lock *lock,
+		      struct libcfs_debug_msg_data *data,
+		      const char *fmt, ...)
+	__attribute__ ((format (printf, 3, 4)));
+
+/**
+ * Rate-limited version of lock printing function.
+ */
+#define LDLM_DEBUG_LIMIT(mask, lock, fmt, a...) do {			 \
+	static cfs_debug_limit_state_t _ldlm_cdls;			   \
+	LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, &_ldlm_cdls);	      \
+	ldlm_lock_debug(&msgdata, mask, &_ldlm_cdls, lock, "### " fmt , ##a);\
+} while (0)
+
+#define LDLM_ERROR(lock, fmt, a...) LDLM_DEBUG_LIMIT(D_ERROR, lock, fmt, ## a)
+#define LDLM_WARN(lock, fmt, a...)  LDLM_DEBUG_LIMIT(D_WARNING, lock, fmt, ## a)
+
+/** Non-rate-limited lock printing function for debugging purposes. */
+#define LDLM_DEBUG(lock, fmt, a...)   do {				  \
+	if (likely(lock != NULL)) {					    \
+		LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_DLMTRACE, NULL);      \
+		ldlm_lock_debug(&msgdata, D_DLMTRACE, NULL, lock,	    \
+				"### " fmt , ##a);			    \
+	} else {							    \
+		LDLM_DEBUG_NOLOCK("no dlm lock: " fmt, ##a);		    \
+	}								    \
+} while (0)
+
+typedef int (*ldlm_processing_policy)(struct ldlm_lock *lock, __u64 *flags,
+				      int first_enq, ldlm_error_t *err,
+				      struct list_head *work_list);
+
+/**
+ * Return values for lock iterators.
+ * Also used during deciding of lock grants and cancellations.
+ */
+#define LDLM_ITER_CONTINUE 1 /* keep iterating */
+#define LDLM_ITER_STOP     2 /* stop iterating */
+
+typedef int (*ldlm_iterator_t)(struct ldlm_lock *, void *);
+typedef int (*ldlm_res_iterator_t)(struct ldlm_resource *, void *);
+
+/** \defgroup ldlm_iterator Lock iterators
+ *
+ * LDLM provides for a way to iterate through every lock on a resource or
+ * namespace or every resource in a namespace.
+ * @{ */
+int ldlm_resource_foreach(struct ldlm_resource *res, ldlm_iterator_t iter,
+			  void *closure);
+void ldlm_namespace_foreach(struct ldlm_namespace *ns, ldlm_iterator_t iter,
+			    void *closure);
+int ldlm_resource_iterate(struct ldlm_namespace *, const struct ldlm_res_id *,
+			  ldlm_iterator_t iter, void *data);
+/** @} ldlm_iterator */
+
+int ldlm_replay_locks(struct obd_import *imp);
+
+/* ldlm_flock.c */
+int ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data);
+
+/* ldlm_extent.c */
+__u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, __u64 old_kms);
+
+struct ldlm_callback_suite {
+	ldlm_completion_callback lcs_completion;
+	ldlm_blocking_callback   lcs_blocking;
+	ldlm_glimpse_callback    lcs_glimpse;
+	ldlm_weigh_callback      lcs_weigh;
+};
+
+/* ldlm_lockd.c */
+int ldlm_del_waiting_lock(struct ldlm_lock *lock);
+int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, int timeout);
+int ldlm_get_ref(void);
+void ldlm_put_ref(void);
+int ldlm_init_export(struct obd_export *exp);
+void ldlm_destroy_export(struct obd_export *exp);
+struct ldlm_lock *ldlm_request_lock(struct ptlrpc_request *req);
+
+/* ldlm_lock.c */
+void ldlm_register_intent(struct ldlm_namespace *ns, ldlm_res_policy arg);
+void ldlm_lock2handle(const struct ldlm_lock *lock,
+		      struct lustre_handle *lockh);
+struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *, __u64 flags);
+void ldlm_cancel_callback(struct ldlm_lock *);
+int ldlm_lock_remove_from_lru(struct ldlm_lock *);
+int ldlm_lock_set_data(struct lustre_handle *, void *);
+
+/**
+ * Obtain a lock reference by its handle.
+ */
+static inline struct ldlm_lock *ldlm_handle2lock(const struct lustre_handle *h)
+{
+	return __ldlm_handle2lock(h, 0);
+}
+
+#define LDLM_LOCK_REF_DEL(lock) \
+	lu_ref_del(&lock->l_reference, "handle", current)
+
+static inline struct ldlm_lock *
+ldlm_handle2lock_long(const struct lustre_handle *h, __u64 flags)
+{
+	struct ldlm_lock *lock;
+
+	lock = __ldlm_handle2lock(h, flags);
+	if (lock != NULL)
+		LDLM_LOCK_REF_DEL(lock);
+	return lock;
+}
+
+/**
+ * Update Lock Value Block Operations (LVBO) on a resource taking into account
+ * data from reqest \a r
+ */
+static inline int ldlm_res_lvbo_update(struct ldlm_resource *res,
+				       struct ptlrpc_request *r, int increase)
+{
+	if (ldlm_res_to_ns(res)->ns_lvbo &&
+	    ldlm_res_to_ns(res)->ns_lvbo->lvbo_update) {
+		return ldlm_res_to_ns(res)->ns_lvbo->lvbo_update(res, r,
+								 increase);
+	}
+	return 0;
+}
+
+int ldlm_error2errno(ldlm_error_t error);
+ldlm_error_t ldlm_errno2error(int err_no); /* don't call it `errno': this
+					    * confuses user-space. */
+#if LUSTRE_TRACKS_LOCK_EXP_REFS
+void ldlm_dump_export_locks(struct obd_export *exp);
+#endif
+
+/**
+ * Release a temporary lock reference obtained by ldlm_handle2lock() or
+ * __ldlm_handle2lock().
+ */
+#define LDLM_LOCK_PUT(lock)		     \
+do {					    \
+	LDLM_LOCK_REF_DEL(lock);		\
+	/*LDLM_DEBUG((lock), "put");*/	  \
+	ldlm_lock_put(lock);		    \
+} while (0)
+
+/**
+ * Release a lock reference obtained by some other means (see
+ * LDLM_LOCK_PUT()).
+ */
+#define LDLM_LOCK_RELEASE(lock)		 \
+do {					    \
+	/*LDLM_DEBUG((lock), "put");*/	  \
+	ldlm_lock_put(lock);		    \
+} while (0)
+
+#define LDLM_LOCK_GET(lock)		     \
+({					      \
+	ldlm_lock_get(lock);		    \
+	/*LDLM_DEBUG((lock), "get");*/	  \
+	lock;				   \
+})
+
+#define ldlm_lock_list_put(head, member, count)		     \
+({								  \
+	struct ldlm_lock *_lock, *_next;			    \
+	int c = count;					      \
+	list_for_each_entry_safe(_lock, _next, head, member) {  \
+		if (c-- == 0)				       \
+			break;				      \
+		list_del_init(&_lock->member);		  \
+		LDLM_LOCK_RELEASE(_lock);			   \
+	}							   \
+	LASSERT(c <= 0);					    \
+})
+
+struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock);
+void ldlm_lock_put(struct ldlm_lock *lock);
+void ldlm_lock_destroy(struct ldlm_lock *lock);
+void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc);
+void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode);
+int  ldlm_lock_addref_try(struct lustre_handle *lockh, __u32 mode);
+void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode);
+void ldlm_lock_decref_and_cancel(struct lustre_handle *lockh, __u32 mode);
+void ldlm_lock_fail_match_locked(struct ldlm_lock *lock);
+void ldlm_lock_fail_match(struct ldlm_lock *lock);
+void ldlm_lock_allow_match(struct ldlm_lock *lock);
+void ldlm_lock_allow_match_locked(struct ldlm_lock *lock);
+ldlm_mode_t ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
+			    const struct ldlm_res_id *, ldlm_type_t type,
+			    ldlm_policy_data_t *, ldlm_mode_t mode,
+			    struct lustre_handle *, int unref);
+ldlm_mode_t ldlm_revalidate_lock_handle(struct lustre_handle *lockh,
+					__u64 *bits);
+struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode,
+					__u32 *flags);
+void ldlm_lock_downgrade(struct ldlm_lock *lock, int new_mode);
+void ldlm_lock_cancel(struct ldlm_lock *lock);
+void ldlm_reprocess_all(struct ldlm_resource *res);
+void ldlm_reprocess_all_ns(struct ldlm_namespace *ns);
+void ldlm_lock_dump_handle(int level, struct lustre_handle *);
+void ldlm_unlink_lock_skiplist(struct ldlm_lock *req);
+
+/* resource.c */
+struct ldlm_namespace *
+ldlm_namespace_new(struct obd_device *obd, char *name,
+		   ldlm_side_t client, ldlm_appetite_t apt,
+		   ldlm_ns_type_t ns_type);
+int ldlm_namespace_cleanup(struct ldlm_namespace *ns, __u64 flags);
+void ldlm_namespace_free(struct ldlm_namespace *ns,
+			 struct obd_import *imp, int force);
+void ldlm_namespace_register(struct ldlm_namespace *ns, ldlm_side_t client);
+void ldlm_namespace_unregister(struct ldlm_namespace *ns, ldlm_side_t client);
+void ldlm_namespace_move_locked(struct ldlm_namespace *ns, ldlm_side_t client);
+struct ldlm_namespace *ldlm_namespace_first_locked(ldlm_side_t client);
+void ldlm_namespace_get(struct ldlm_namespace *ns);
+void ldlm_namespace_put(struct ldlm_namespace *ns);
+int ldlm_proc_setup(void);
+#ifdef LPROCFS
+void ldlm_proc_cleanup(void);
+#else
+static inline void ldlm_proc_cleanup(void) {}
+#endif
+
+/* resource.c - internal */
+struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns,
+					struct ldlm_resource *parent,
+					const struct ldlm_res_id *,
+					ldlm_type_t type, int create);
+struct ldlm_resource *ldlm_resource_getref(struct ldlm_resource *res);
+int ldlm_resource_putref(struct ldlm_resource *res);
+void ldlm_resource_add_lock(struct ldlm_resource *res,
+			    struct list_head *head,
+			    struct ldlm_lock *lock);
+void ldlm_resource_unlink_lock(struct ldlm_lock *lock);
+void ldlm_res2desc(struct ldlm_resource *res, struct ldlm_resource_desc *desc);
+void ldlm_dump_all_namespaces(ldlm_side_t client, int level);
+void ldlm_namespace_dump(int level, struct ldlm_namespace *);
+void ldlm_resource_dump(int level, struct ldlm_resource *);
+int ldlm_lock_change_resource(struct ldlm_namespace *, struct ldlm_lock *,
+			      const struct ldlm_res_id *);
+
+#define LDLM_RESOURCE_ADDREF(res) do {				  \
+	lu_ref_add_atomic(&(res)->lr_reference, __FUNCTION__, current);  \
+} while (0)
+
+#define LDLM_RESOURCE_DELREF(res) do {				  \
+	lu_ref_del(&(res)->lr_reference, __FUNCTION__, current);  \
+} while (0)
+
+/* ldlm_request.c */
+int ldlm_expired_completion_wait(void *data);
+/** \defgroup ldlm_local_ast Default AST handlers for local locks
+ * These AST handlers are typically used for server-side local locks and are
+ * also used by client-side lock handlers to perform minimum level base
+ * processing.
+ * @{ */
+int ldlm_blocking_ast_nocheck(struct ldlm_lock *lock);
+int ldlm_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
+		      void *data, int flag);
+int ldlm_glimpse_ast(struct ldlm_lock *lock, void *reqp);
+int ldlm_completion_ast_async(struct ldlm_lock *lock, __u64 flags, void *data);
+int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data);
+/** @} ldlm_local_ast */
+
+/** \defgroup ldlm_cli_api API to operate on locks from actual LDLM users.
+ * These are typically used by client and server (*_local versions)
+ * to obtain and release locks.
+ * @{ */
+int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp,
+		     struct ldlm_enqueue_info *einfo,
+		     const struct ldlm_res_id *res_id,
+		     ldlm_policy_data_t const *policy, __u64 *flags,
+		     void *lvb, __u32 lvb_len, enum lvb_type lvb_type,
+		     struct lustre_handle *lockh, int async);
+int ldlm_prep_enqueue_req(struct obd_export *exp,
+			  struct ptlrpc_request *req,
+			  struct list_head *cancels,
+			  int count);
+int ldlm_prep_elc_req(struct obd_export *exp,
+		      struct ptlrpc_request *req,
+		      int version, int opc, int canceloff,
+		      struct list_head *cancels, int count);
+
+struct ptlrpc_request *ldlm_enqueue_pack(struct obd_export *exp, int lvb_len);
+int ldlm_handle_enqueue0(struct ldlm_namespace *ns, struct ptlrpc_request *req,
+			 const struct ldlm_request *dlm_req,
+			 const struct ldlm_callback_suite *cbs);
+int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req,
+			  ldlm_type_t type, __u8 with_policy, ldlm_mode_t mode,
+			  __u64 *flags, void *lvb, __u32 lvb_len,
+			  struct lustre_handle *lockh, int rc);
+int ldlm_cli_enqueue_local(struct ldlm_namespace *ns,
+			   const struct ldlm_res_id *res_id,
+			   ldlm_type_t type, ldlm_policy_data_t *policy,
+			   ldlm_mode_t mode, __u64 *flags,
+			   ldlm_blocking_callback blocking,
+			   ldlm_completion_callback completion,
+			   ldlm_glimpse_callback glimpse,
+			   void *data, __u32 lvb_len, enum lvb_type lvb_type,
+			   const __u64 *client_cookie,
+			   struct lustre_handle *lockh);
+int ldlm_server_ast(struct lustre_handle *lockh, struct ldlm_lock_desc *new,
+		    void *data, __u32 data_len);
+int ldlm_cli_convert(struct lustre_handle *, int new_mode, __u32 *flags);
+int ldlm_cli_update_pool(struct ptlrpc_request *req);
+int ldlm_cli_cancel(struct lustre_handle *lockh,
+		    ldlm_cancel_flags_t cancel_flags);
+int ldlm_cli_cancel_unused(struct ldlm_namespace *, const struct ldlm_res_id *,
+			   ldlm_cancel_flags_t flags, void *opaque);
+int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
+				    const struct ldlm_res_id *res_id,
+				    ldlm_policy_data_t *policy,
+				    ldlm_mode_t mode,
+				    ldlm_cancel_flags_t flags,
+				    void *opaque);
+int ldlm_cli_cancel_req(struct obd_export *exp, struct list_head *head,
+			int count, ldlm_cancel_flags_t flags);
+int ldlm_cancel_resource_local(struct ldlm_resource *res,
+			       struct list_head *cancels,
+			       ldlm_policy_data_t *policy,
+			       ldlm_mode_t mode, int lock_flags,
+			       ldlm_cancel_flags_t cancel_flags, void *opaque);
+int ldlm_cli_cancel_list_local(struct list_head *cancels, int count,
+			       ldlm_cancel_flags_t flags);
+int ldlm_cli_cancel_list(struct list_head *head, int count,
+			 struct ptlrpc_request *req, ldlm_cancel_flags_t flags);
+/** @} ldlm_cli_api */
+
+/* mds/handler.c */
+/* This has to be here because recursive inclusion sucks. */
+int intent_disposition(struct ldlm_reply *rep, int flag);
+void intent_set_disposition(struct ldlm_reply *rep, int flag);
+
+
+/* ioctls for trying requests */
+#define IOC_LDLM_TYPE		   'f'
+#define IOC_LDLM_MIN_NR		 40
+
+#define IOC_LDLM_TEST		   _IOWR('f', 40, long)
+#define IOC_LDLM_DUMP		   _IOWR('f', 41, long)
+#define IOC_LDLM_REGRESS_START	  _IOWR('f', 42, long)
+#define IOC_LDLM_REGRESS_STOP	   _IOWR('f', 43, long)
+#define IOC_LDLM_MAX_NR		 43
+
+/**
+ * "Modes" of acquiring lock_res, necessary to tell lockdep that taking more
+ * than one lock_res is dead-lock safe.
+ */
+enum lock_res_type {
+	LRT_NORMAL,
+	LRT_NEW
+};
+
+/** Lock resource. */
+static inline void lock_res(struct ldlm_resource *res)
+{
+	spin_lock(&res->lr_lock);
+}
+
+/** Lock resource with a way to instruct lockdep code about nestedness-safe. */
+static inline void lock_res_nested(struct ldlm_resource *res,
+				   enum lock_res_type mode)
+{
+	spin_lock_nested(&res->lr_lock, mode);
+}
+
+/** Unlock resource. */
+static inline void unlock_res(struct ldlm_resource *res)
+{
+	spin_unlock(&res->lr_lock);
+}
+
+/** Check if resource is already locked, assert if not. */
+static inline void check_res_locked(struct ldlm_resource *res)
+{
+	LASSERT(spin_is_locked(&res->lr_lock));
+}
+
+struct ldlm_resource * lock_res_and_lock(struct ldlm_lock *lock);
+void unlock_res_and_lock(struct ldlm_lock *lock);
+
+/* ldlm_pool.c */
+/** \defgroup ldlm_pools Various LDLM pool related functions
+ * There are not used outside of ldlm.
+ * @{
+ */
+void ldlm_pools_recalc(ldlm_side_t client);
+int ldlm_pools_init(void);
+void ldlm_pools_fini(void);
+
+int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns,
+		   int idx, ldlm_side_t client);
+int ldlm_pool_shrink(struct ldlm_pool *pl, int nr,
+		     unsigned int gfp_mask);
+void ldlm_pool_fini(struct ldlm_pool *pl);
+int ldlm_pool_setup(struct ldlm_pool *pl, int limit);
+int ldlm_pool_recalc(struct ldlm_pool *pl);
+__u32 ldlm_pool_get_lvf(struct ldlm_pool *pl);
+__u64 ldlm_pool_get_slv(struct ldlm_pool *pl);
+__u64 ldlm_pool_get_clv(struct ldlm_pool *pl);
+__u32 ldlm_pool_get_limit(struct ldlm_pool *pl);
+void ldlm_pool_set_slv(struct ldlm_pool *pl, __u64 slv);
+void ldlm_pool_set_clv(struct ldlm_pool *pl, __u64 clv);
+void ldlm_pool_set_limit(struct ldlm_pool *pl, __u32 limit);
+void ldlm_pool_add(struct ldlm_pool *pl, struct ldlm_lock *lock);
+void ldlm_pool_del(struct ldlm_pool *pl, struct ldlm_lock *lock);
+/** @} */
+
+#endif
+/** @} LDLM */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_eacl.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_eacl.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_eacl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_eacl.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/lustre/include/lustre_idmap.h
+ *
+ * MDS data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ */
+
+#ifndef _LUSTRE_EACL_H
+#define _LUSTRE_EACL_H
+
+/** \defgroup eacl eacl
+ *
+ * @{
+ */
+
+#ifdef CONFIG_FS_POSIX_ACL
+
+#include <linux/posix_acl_xattr.h>
+
+typedef struct {
+	__u16		   e_tag;
+	__u16		   e_perm;
+	__u32		   e_id;
+	__u32		   e_stat;
+} ext_acl_xattr_entry;
+
+typedef struct {
+	__u32		   a_count;
+	ext_acl_xattr_entry     a_entries[0];
+} ext_acl_xattr_header;
+
+#define CFS_ACL_XATTR_SIZE(count, prefix) \
+	(sizeof(prefix ## _header) + (count) * sizeof(prefix ## _entry))
+
+#define CFS_ACL_XATTR_COUNT(size, prefix) \
+	(((size) - sizeof(prefix ## _header)) / sizeof(prefix ## _entry))
+
+
+extern ext_acl_xattr_header *
+lustre_posix_acl_xattr_2ext(posix_acl_xattr_header *header, int size);
+extern int
+lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, int size,
+			      posix_acl_xattr_header **out);
+extern void
+lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size);
+extern void
+lustre_ext_acl_xattr_free(ext_acl_xattr_header *header);
+extern int
+lustre_acl_xattr_merge2posix(posix_acl_xattr_header *posix_header, int size,
+			     ext_acl_xattr_header *ext_header,
+			     posix_acl_xattr_header **out);
+extern ext_acl_xattr_header *
+lustre_acl_xattr_merge2ext(posix_acl_xattr_header *posix_header, int size,
+			   ext_acl_xattr_header *ext_header);
+
+#endif /* CONFIG_FS_POSIX_ACL */
+
+/** @} eacl */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_export.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_export.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_export.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_export.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,389 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+/** \defgroup obd_export PortalRPC export definitions
+ *
+ * @{
+ */
+
+#ifndef __EXPORT_H
+#define __EXPORT_H
+
+/** \defgroup export export
+ *
+ * @{
+ */
+
+#include <lprocfs_status.h>
+#include <lustre/lustre_idl.h>
+#include <lustre_dlm.h>
+
+struct mds_client_data;
+struct mdt_client_data;
+struct mds_idmap_table;
+struct mdt_idmap_table;
+
+/**
+ * Target-specific export data
+ */
+struct tg_export_data {
+	/** Protects led_lcd below */
+	struct mutex		ted_lcd_lock;
+	/** Per-client data for each export */
+	struct lsd_client_data	*ted_lcd;
+	/** Offset of record in last_rcvd file */
+	loff_t			ted_lr_off;
+	/** Client index in last_rcvd file */
+	int			ted_lr_idx;
+};
+
+/**
+ * MDT-specific export data
+ */
+struct mdt_export_data {
+	struct tg_export_data	med_ted;
+	/** List of all files opened by client on this MDT */
+	struct list_head		med_open_head;
+	spinlock_t		med_open_lock; /* med_open_head, mfd_list */
+	/** Bitmask of all ibit locks this MDT understands */
+	__u64			med_ibits_known;
+	struct mutex		med_idmap_mutex;
+	struct lustre_idmap_table *med_idmap;
+};
+
+struct ec_export_data { /* echo client */
+	struct list_head eced_locks;
+};
+
+/* In-memory access to client data from OST struct */
+/** Filter (oss-side) specific import data */
+struct filter_export_data {
+	struct tg_export_data	fed_ted;
+	spinlock_t		fed_lock;	/**< protects fed_mod_list */
+	long		       fed_dirty;    /* in bytes */
+	long		       fed_grant;    /* in bytes */
+	struct list_head		 fed_mod_list; /* files being modified */
+	int			fed_mod_count;/* items in fed_writing list */
+	long		       fed_pending;  /* bytes just being written */
+	__u32		      fed_group;
+	__u8		       fed_pagesize; /* log2 of client page size */
+};
+
+struct mgs_export_data {
+	struct list_head		med_clients;	/* mgc fs client via this exp */
+	spinlock_t		med_lock;	/* protect med_clients */
+};
+
+/**
+ * per-NID statistics structure.
+ * It tracks access patterns to this export on a per-client-NID basis
+ */
+struct nid_stat {
+	lnet_nid_t	       nid;
+	struct hlist_node	 nid_hash;
+	struct list_head	       nid_list;
+	struct obd_device       *nid_obd;
+	struct proc_dir_entry   *nid_proc;
+	struct lprocfs_stats    *nid_stats;
+	struct lprocfs_stats    *nid_ldlm_stats;
+	atomic_t	     nid_exp_ref_count; /* for obd_nid_stats_hash
+							   exp_nid_stats */
+};
+
+#define nidstat_getref(nidstat)						\
+do {									   \
+	atomic_inc(&(nidstat)->nid_exp_ref_count);			 \
+} while(0)
+
+#define nidstat_putref(nidstat)						\
+do {									   \
+	atomic_dec(&(nidstat)->nid_exp_ref_count);			 \
+	LASSERTF(atomic_read(&(nidstat)->nid_exp_ref_count) >= 0,	  \
+		 "stat %p nid_exp_ref_count < 0\n", nidstat);		  \
+} while(0)
+
+enum obd_option {
+	OBD_OPT_FORCE =	 0x0001,
+	OBD_OPT_FAILOVER =      0x0002,
+	OBD_OPT_ABORT_RECOV =   0x0004,
+};
+
+/**
+ * Export structure. Represents target-side of connection in portals.
+ * Also used in Lustre to connect between layers on the same node when
+ * there is no network-connection in-between.
+ * For every connected client there is an export structure on the server
+ * attached to the same obd device.
+ */
+struct obd_export {
+	/**
+	 * Export handle, it's id is provided to client on connect
+	 * Subsequent client RPCs contain this handle id to identify
+	 * what export they are talking to.
+	 */
+	struct portals_handle     exp_handle;
+	atomic_t	      exp_refcount;
+	/**
+	 * Set of counters below is to track where export references are
+	 * kept. The exp_rpc_count is used for reconnect handling also,
+	 * the cb_count and locks_count are for debug purposes only for now.
+	 * The sum of them should be less than exp_refcount by 3
+	 */
+	atomic_t	      exp_rpc_count; /* RPC references */
+	atomic_t	      exp_cb_count; /* Commit callback references */
+	/** Number of queued replay requests to be processes */
+	atomic_t		  exp_replay_count;
+	atomic_t	      exp_locks_count; /** Lock references */
+#if LUSTRE_TRACKS_LOCK_EXP_REFS
+	struct list_head		exp_locks_list;
+	spinlock_t		  exp_locks_list_guard;
+#endif
+	/** UUID of client connected to this export */
+	struct obd_uuid	   exp_client_uuid;
+	/** To link all exports on an obd device */
+	struct list_head		exp_obd_chain;
+	struct hlist_node	  exp_uuid_hash; /** uuid-export hash*/
+	struct hlist_node	  exp_nid_hash; /** nid-export hash */
+	/**
+	 * All exports eligible for ping evictor are linked into a list
+	 * through this field in "most time since last request on this export"
+	 * order
+	 * protected by obd_dev_lock
+	 */
+	struct list_head		exp_obd_chain_timed;
+	/** Obd device of this export */
+	struct obd_device	*exp_obd;
+	/**
+	 * "reverse" import to send requests (e.g. from ldlm) back to client
+	 * exp_lock protect its change
+	 */
+	struct obd_import	*exp_imp_reverse;
+	struct nid_stat	  *exp_nid_stats;
+	struct lprocfs_stats     *exp_md_stats;
+	/** Active connetion */
+	struct ptlrpc_connection *exp_connection;
+	/** Connection count value from last succesful reconnect rpc */
+	__u32		     exp_conn_cnt;
+	/** Hash list of all ldlm locks granted on this export */
+	cfs_hash_t	       *exp_lock_hash;
+	/**
+	 * Hash list for Posix lock deadlock detection, added with
+	 * ldlm_lock::l_exp_flock_hash.
+	 */
+	cfs_hash_t	       *exp_flock_hash;
+	struct list_head		exp_outstanding_replies;
+	struct list_head		exp_uncommitted_replies;
+	spinlock_t		  exp_uncommitted_replies_lock;
+	/** Last committed transno for this export */
+	__u64		     exp_last_committed;
+	/** When was last request received */
+	cfs_time_t		exp_last_request_time;
+	/** On replay all requests waiting for replay are linked here */
+	struct list_head		exp_req_replay_queue;
+	/**
+	 * protects exp_flags, exp_outstanding_replies and the change
+	 * of exp_imp_reverse
+	 */
+	spinlock_t		  exp_lock;
+	/** Compatibility flags for this export are embedded into
+	 *  exp_connect_data */
+	struct obd_connect_data   exp_connect_data;
+	enum obd_option	   exp_flags;
+	unsigned long	     exp_failed:1,
+				  exp_in_recovery:1,
+				  exp_disconnected:1,
+				  exp_connecting:1,
+				  /** VBR: export missed recovery */
+				  exp_delayed:1,
+				  /** VBR: failed version checking */
+				  exp_vbr_failed:1,
+				  exp_req_replay_needed:1,
+				  exp_lock_replay_needed:1,
+				  exp_need_sync:1,
+				  exp_flvr_changed:1,
+				  exp_flvr_adapt:1,
+				  exp_libclient:1, /* liblustre client? */
+				  /* client timed out and tried to reconnect,
+				   * but couldn't because of active rpcs */
+				  exp_abort_active_req:1,
+				  /* if to swap nidtbl entries for 2.2 clients.
+				   * Only used by the MGS to fix LU-1644. */
+				  exp_need_mne_swab:1;
+	/* also protected by exp_lock */
+	enum lustre_sec_part      exp_sp_peer;
+	struct sptlrpc_flavor     exp_flvr;	     /* current */
+	struct sptlrpc_flavor     exp_flvr_old[2];      /* about-to-expire */
+	cfs_time_t		exp_flvr_expire[2];   /* seconds */
+
+	/** protects exp_hp_rpcs */
+	spinlock_t		  exp_rpc_lock;
+	struct list_head		  exp_hp_rpcs;	/* (potential) HP RPCs */
+
+	/** blocking dlm lock list, protected by exp_bl_list_lock */
+	struct list_head		exp_bl_list;
+	spinlock_t		  exp_bl_list_lock;
+
+	/** Target specific data */
+	union {
+		struct tg_export_data     eu_target_data;
+		struct mdt_export_data    eu_mdt_data;
+		struct filter_export_data eu_filter_data;
+		struct ec_export_data     eu_ec_data;
+		struct mgs_export_data    eu_mgs_data;
+	} u;
+};
+
+#define exp_target_data u.eu_target_data
+#define exp_mdt_data    u.eu_mdt_data
+#define exp_filter_data u.eu_filter_data
+#define exp_ec_data     u.eu_ec_data
+
+static inline __u64 *exp_connect_flags_ptr(struct obd_export *exp)
+{
+	return &exp->exp_connect_data.ocd_connect_flags;
+}
+
+static inline __u64 exp_connect_flags(struct obd_export *exp)
+{
+	return *exp_connect_flags_ptr(exp);
+}
+
+static inline int exp_max_brw_size(struct obd_export *exp)
+{
+	LASSERT(exp != NULL);
+	if (exp_connect_flags(exp) & OBD_CONNECT_BRW_SIZE)
+		return exp->exp_connect_data.ocd_brw_size;
+
+	return ONE_MB_BRW_SIZE;
+}
+
+static inline int exp_connect_multibulk(struct obd_export *exp)
+{
+	return exp_max_brw_size(exp) > ONE_MB_BRW_SIZE;
+}
+
+static inline int exp_expired(struct obd_export *exp, cfs_duration_t age)
+{
+	LASSERT(exp->exp_delayed);
+	return cfs_time_before(cfs_time_add(exp->exp_last_request_time, age),
+			       cfs_time_current_sec());
+}
+
+static inline int exp_connect_cancelset(struct obd_export *exp)
+{
+	LASSERT(exp != NULL);
+	return !!(exp_connect_flags(exp) & OBD_CONNECT_CANCELSET);
+}
+
+static inline int exp_connect_lru_resize(struct obd_export *exp)
+{
+	LASSERT(exp != NULL);
+	return !!(exp_connect_flags(exp) & OBD_CONNECT_LRU_RESIZE);
+}
+
+static inline int exp_connect_rmtclient(struct obd_export *exp)
+{
+	LASSERT(exp != NULL);
+	return !!(exp_connect_flags(exp) & OBD_CONNECT_RMT_CLIENT);
+}
+
+static inline int client_is_remote(struct obd_export *exp)
+{
+	struct obd_import *imp = class_exp2cliimp(exp);
+
+	return !!(imp->imp_connect_data.ocd_connect_flags &
+		  OBD_CONNECT_RMT_CLIENT);
+}
+
+static inline int exp_connect_vbr(struct obd_export *exp)
+{
+	LASSERT(exp != NULL);
+	LASSERT(exp->exp_connection);
+	return !!(exp_connect_flags(exp) & OBD_CONNECT_VBR);
+}
+
+static inline int exp_connect_som(struct obd_export *exp)
+{
+	LASSERT(exp != NULL);
+	return !!(exp_connect_flags(exp) & OBD_CONNECT_SOM);
+}
+
+static inline int exp_connect_umask(struct obd_export *exp)
+{
+	return !!(exp_connect_flags(exp) & OBD_CONNECT_UMASK);
+}
+
+static inline int imp_connect_lru_resize(struct obd_import *imp)
+{
+	struct obd_connect_data *ocd;
+
+	LASSERT(imp != NULL);
+	ocd = &imp->imp_connect_data;
+	return !!(ocd->ocd_connect_flags & OBD_CONNECT_LRU_RESIZE);
+}
+
+static inline int exp_connect_layout(struct obd_export *exp)
+{
+	return !!(exp_connect_flags(exp) & OBD_CONNECT_LAYOUTLOCK);
+}
+
+static inline bool exp_connect_lvb_type(struct obd_export *exp)
+{
+	LASSERT(exp != NULL);
+	if (exp_connect_flags(exp) & OBD_CONNECT_LVB_TYPE)
+		return true;
+	else
+		return false;
+}
+
+static inline bool imp_connect_lvb_type(struct obd_import *imp)
+{
+	struct obd_connect_data *ocd;
+
+	LASSERT(imp != NULL);
+	ocd = &imp->imp_connect_data;
+	if (ocd->ocd_connect_flags & OBD_CONNECT_LVB_TYPE)
+		return true;
+	else
+		return false;
+}
+
+extern struct obd_export *class_conn2export(struct lustre_handle *conn);
+extern struct obd_device *class_conn2obd(struct lustre_handle *conn);
+
+/** @} export */
+
+#endif /* __EXPORT_H */
+/** @} obd_export */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_fid.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_fid.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_fid.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_fid.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,762 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_fid.h
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+#ifndef __LINUX_FID_H
+#define __LINUX_FID_H
+
+/** \defgroup fid fid
+ *
+ * @{
+ *
+ * http://wiki.lustre.org/index.php/Architecture_-_Interoperability_fids_zfs
+ * describes the FID namespace and interoperability requirements for FIDs.
+ * The important parts of that document are included here for reference.
+ *
+ * FID
+ *   File IDentifier generated by client from range allocated by the SEQuence
+ *   service and stored in struct lu_fid. The FID is composed of three parts:
+ *   SEQuence, ObjectID, and VERsion.  The SEQ component is a filesystem
+ *   unique 64-bit integer, and only one client is ever assigned any SEQ value.
+ *   The first 0x400 FID_SEQ_NORMAL [2^33, 2^33 + 0x400] values are reserved
+ *   for system use.  The OID component is a 32-bit value generated by the
+ *   client on a per-SEQ basis to allow creating many unique FIDs without
+ *   communication with the server.  The VER component is a 32-bit value that
+ *   distinguishes between different FID instantiations, such as snapshots or
+ *   separate subtrees within the filesystem.  FIDs with the same VER field
+ *   are considered part of the same namespace.
+ *
+ * OLD filesystems are those upgraded from Lustre 1.x that predate FIDs, and
+ *   MDTs use 32-bit ldiskfs internal inode/generation numbers (IGIFs), while
+ *   OSTs use 64-bit Lustre object IDs and generation numbers.
+ *
+ * NEW filesystems are those formatted since the introduction of FIDs.
+ *
+ * IGIF
+ *   Inode and Generation In FID, a surrogate FID used to globally identify
+ *   an existing object on OLD formatted MDT file system. This would only be
+ *   used on MDT0 in a DNE filesystem, because there cannot be more than one
+ *   MDT in an OLD formatted filesystem. Belongs to sequence in [12, 2^32 - 1]
+ *   range, where inode number is stored in SEQ, and inode generation is in OID.
+ *   NOTE: This assumes no more than 2^32-1 inodes exist in the MDT filesystem,
+ *   which is the maximum possible for an ldiskfs backend.  It also assumes
+ *   that the reserved ext3/ext4/ldiskfs inode numbers [0-11] are never visible
+ *   to clients, which has always been true.
+ *
+ * IDIF
+ *   object ID In FID, a surrogate FID used to globally identify an existing
+ *   OST object on OLD formatted OST file system. Belongs to a sequence in
+ *   [2^32, 2^33 - 1]. Sequence number is calculated as:
+ *
+ *      1 << 32 | (ost_index << 16) | ((objid >> 32) & 0xffff)
+ *
+ *   that is, SEQ consists of 16-bit OST index, and higher 16 bits of object
+ *   ID. The generation of unique SEQ values per OST allows the IDIF FIDs to
+ *   be identified in the FLD correctly. The OID field is calculated as:
+ *
+ *      objid & 0xffffffff
+ *
+ *   that is, it consists of lower 32 bits of object ID.  For objects within
+ *   the IDIF range, object ID extraction will be:
+ *
+ *      o_id = (fid->f_seq & 0x7fff) << 16 | fid->f_oid;
+ *      o_seq = 0;  // formerly group number
+ *
+ *   NOTE: This assumes that no more than 2^48-1 objects have ever been created
+ *   on any OST, and that no more than 65535 OSTs are in use.  Both are very
+ *   reasonable assumptions, i.e. an IDIF can uniquely map all objects assuming
+ *   a maximum creation rate of 1M objects per second for a maximum of 9 years,
+ *   or combinations thereof.
+ *
+ * OST_MDT0
+ *   Surrogate FID used to identify an existing object on OLD formatted OST
+ *   filesystem. Belongs to the reserved SEQuence 0, and is used prior to
+ *   the introduction of FID-on-OST, at which point IDIF will be used to
+ *   identify objects as residing on a specific OST.
+ *
+ * LLOG
+ *   For Lustre Log objects the object sequence 1 is used. This is compatible
+ *   with both OLD and NEW namespaces, as this SEQ number is in the
+ *   ext3/ldiskfs reserved inode range and does not conflict with IGIF
+ *   sequence numbers.
+ *
+ * ECHO
+ *   For testing OST IO performance the object sequence 2 is used. This is
+ *   compatible with both OLD and NEW namespaces, as this SEQ number is in
+ *   the ext3/ldiskfs reserved inode range and does not conflict with IGIF
+ *   sequence numbers.
+ *
+ * OST_MDT1 .. OST_MAX
+ *   For testing with multiple MDTs the object sequence 3 through 9 is used,
+ *   allowing direct mapping of MDTs 1 through 7 respectively, for a total
+ *   of 8 MDTs including OST_MDT0. This matches the legacy CMD project "group"
+ *   mappings. However, this SEQ range is only for testing prior to any
+ *   production DNE release, as the objects in this range conflict across all
+ *   OSTs, as the OST index is not part of the FID.  For production DNE usage,
+ *   OST objects created by MDT1+ will use FID_SEQ_NORMAL FIDs.
+ *
+ * DLM OST objid to IDIF mapping
+ *   For compatibility with existing OLD OST network protocol structures, the
+ *   FID must map onto the o_id and o_seq in a manner that ensures existing
+ *   objects are identified consistently for IO, as well as onto the LDLM
+ *   namespace to ensure IDIFs there is only a single resource name for any
+ *   object in the DLM.  The OLD OST object DLM resource mapping is:
+ *
+ *      resource[] = {o_id, o_seq, 0, 0}; // o_seq == 0 for production releases
+ *
+ *   The NEW OST object DLM resource mapping is the same for both MDT and OST:
+ *
+ *      resource[] = {SEQ, OID, VER, HASH};
+ *
+ *  NOTE: for mapping IDIF values to DLM resource names the o_id may be
+ *  larger than the 2^33 reserved sequence numbers for IDIF, so it is possible
+ *  for the o_id numbers to overlap FID SEQ numbers in the resource. However,
+ *  in all production releases the OLD o_seq field is always zero, and all
+ *  valid FID OID values are non-zero, so the lock resources will not collide.
+ *  Even so, the MDT and OST resources are also in different LDLM namespaces.
+ */
+
+#include <linux/libcfs/libcfs.h>
+#include <lustre/lustre_idl.h>
+#include <lustre_req_layout.h>
+#include <lustre_mdt.h>
+#include <obd.h>
+
+
+struct lu_site;
+struct lu_context;
+
+/* Whole sequences space range and zero range definitions */
+extern const struct lu_seq_range LUSTRE_SEQ_SPACE_RANGE;
+extern const struct lu_seq_range LUSTRE_SEQ_ZERO_RANGE;
+extern const struct lu_fid LUSTRE_BFL_FID;
+extern const struct lu_fid LU_OBF_FID;
+extern const struct lu_fid LU_DOT_LUSTRE_FID;
+
+enum {
+	/*
+	 * This is how may metadata FIDs may be allocated in one sequence(128k)
+	 */
+	LUSTRE_METADATA_SEQ_MAX_WIDTH = 0x0000000000020000ULL,
+
+	/*
+	 * This is how many data FIDs could be allocated in one sequence(4B - 1)
+	 */
+	LUSTRE_DATA_SEQ_MAX_WIDTH = 0x00000000FFFFFFFFULL,
+
+	/*
+	 * How many sequences to allocate to a client at once.
+	 */
+	LUSTRE_SEQ_META_WIDTH = 0x0000000000000001ULL,
+
+	/*
+	 * seq allocation pool size.
+	 */
+	LUSTRE_SEQ_BATCH_WIDTH = LUSTRE_SEQ_META_WIDTH * 1000,
+
+	/*
+	 * This is how many sequences may be in one super-sequence allocated to
+	 * MDTs.
+	 */
+	LUSTRE_SEQ_SUPER_WIDTH = ((1ULL << 30ULL) * LUSTRE_SEQ_META_WIDTH)
+};
+
+enum {
+	/** 2^6 FIDs for OI containers */
+	OSD_OI_FID_OID_BITS     = 6,
+	/** reserve enough FIDs in case we want more in the future */
+	OSD_OI_FID_OID_BITS_MAX = 10,
+};
+
+/** special OID for local objects */
+enum local_oid {
+	/** \see fld_mod_init */
+	FLD_INDEX_OID		= 3UL,
+	/** \see fid_mod_init */
+	FID_SEQ_CTL_OID		= 4UL,
+	FID_SEQ_SRV_OID		= 5UL,
+	/** \see mdd_mod_init */
+	MDD_ROOT_INDEX_OID	= 6UL, /* deprecated in 2.4 */
+	MDD_ORPHAN_OID		= 7UL, /* deprecated in 2.4 */
+	MDD_LOV_OBJ_OID		= 8UL,
+	MDD_CAPA_KEYS_OID	= 9UL,
+	/** \see mdt_mod_init */
+	LAST_RECV_OID		= 11UL,
+	OSD_FS_ROOT_OID		= 13UL,
+	ACCT_USER_OID		= 15UL,
+	ACCT_GROUP_OID		= 16UL,
+	LFSCK_BOOKMARK_OID	= 17UL,
+	OTABLE_IT_OID		= 18UL,
+	/* These two definitions are obsolete
+	 * OFD_GROUP0_LAST_OID     = 20UL,
+	 * OFD_GROUP4K_LAST_OID    = 20UL+4096,
+	 */
+	OFD_LAST_GROUP_OID	= 4117UL,
+	LLOG_CATALOGS_OID	= 4118UL,
+	MGS_CONFIGS_OID		= 4119UL,
+	OFD_HEALTH_CHECK_OID	= 4120UL,
+	MDD_LOV_OBJ_OSEQ	= 4121UL,
+	LFSCK_NAMESPACE_OID     = 4122UL,
+	REMOTE_PARENT_DIR_OID	= 4123UL,
+};
+
+static inline void lu_local_obj_fid(struct lu_fid *fid, __u32 oid)
+{
+	fid->f_seq = FID_SEQ_LOCAL_FILE;
+	fid->f_oid = oid;
+	fid->f_ver = 0;
+}
+
+static inline void lu_local_name_obj_fid(struct lu_fid *fid, __u32 oid)
+{
+	fid->f_seq = FID_SEQ_LOCAL_NAME;
+	fid->f_oid = oid;
+	fid->f_ver = 0;
+}
+
+/* For new FS (>= 2.4), the root FID will be changed to
+ * [FID_SEQ_ROOT:1:0], for existing FS, (upgraded to 2.4),
+ * the root FID will still be IGIF */
+static inline int fid_is_root(const struct lu_fid *fid)
+{
+	return unlikely((fid_seq(fid) == FID_SEQ_ROOT &&
+			 fid_oid(fid) == 1));
+}
+
+static inline int fid_is_dot_lustre(const struct lu_fid *fid)
+{
+	return unlikely(fid_seq(fid) == FID_SEQ_DOT_LUSTRE &&
+			fid_oid(fid) == FID_OID_DOT_LUSTRE);
+}
+
+static inline int fid_is_obf(const struct lu_fid *fid)
+{
+	return unlikely(fid_seq(fid) == FID_SEQ_DOT_LUSTRE &&
+			fid_oid(fid) == FID_OID_DOT_LUSTRE_OBF);
+}
+
+static inline int fid_is_otable_it(const struct lu_fid *fid)
+{
+	return unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE &&
+			fid_oid(fid) == OTABLE_IT_OID);
+}
+
+static inline int fid_is_acct(const struct lu_fid *fid)
+{
+	return fid_seq(fid) == FID_SEQ_LOCAL_FILE &&
+	       (fid_oid(fid) == ACCT_USER_OID ||
+		fid_oid(fid) == ACCT_GROUP_OID);
+}
+
+static inline int fid_is_quota(const struct lu_fid *fid)
+{
+	return fid_seq(fid) == FID_SEQ_QUOTA ||
+	       fid_seq(fid) == FID_SEQ_QUOTA_GLB;
+}
+
+static inline int fid_is_namespace_visible(const struct lu_fid *fid)
+{
+	const __u64 seq = fid_seq(fid);
+
+	/* Here, we cannot distinguish whether the normal FID is for OST
+	 * object or not. It is caller's duty to check more if needed. */
+	return (!fid_is_last_id(fid) &&
+		(fid_seq_is_norm(seq) || fid_seq_is_igif(seq))) ||
+	       fid_is_root(fid) || fid_is_dot_lustre(fid);
+}
+
+static inline int fid_seq_in_fldb(__u64 seq)
+{
+	return fid_seq_is_igif(seq) || fid_seq_is_norm(seq) ||
+	       fid_seq_is_root(seq) || fid_seq_is_dot(seq);
+}
+
+static inline void lu_last_id_fid(struct lu_fid *fid, __u64 seq)
+{
+	if (fid_seq_is_mdt0(seq)) {
+		fid->f_seq = fid_idif_seq(0, 0);
+	} else {
+		LASSERTF(fid_seq_is_norm(seq) || fid_seq_is_echo(seq) ||
+			 fid_seq_is_idif(seq), LPX64"\n", seq);
+		fid->f_seq = seq;
+	}
+	fid->f_oid = 0;
+	fid->f_ver = 0;
+}
+
+enum lu_mgr_type {
+	LUSTRE_SEQ_SERVER,
+	LUSTRE_SEQ_CONTROLLER
+};
+
+struct lu_server_seq;
+
+/* Client sequence manager interface. */
+struct lu_client_seq {
+	/* Sequence-controller export. */
+	struct obd_export      *lcs_exp;
+	struct mutex		lcs_mutex;
+
+	/*
+	 * Range of allowed for allocation sequeces. When using lu_client_seq on
+	 * clients, this contains meta-sequence range. And for servers this
+	 * contains super-sequence range.
+	 */
+	struct lu_seq_range	 lcs_space;
+
+	/* Seq related proc */
+	proc_dir_entry_t   *lcs_proc_dir;
+
+	/* This holds last allocated fid in last obtained seq */
+	struct lu_fid	   lcs_fid;
+
+	/* LUSTRE_SEQ_METADATA or LUSTRE_SEQ_DATA */
+	enum lu_cli_type	lcs_type;
+
+	/*
+	 * Service uuid, passed from MDT + seq name to form unique seq name to
+	 * use it with procfs.
+	 */
+	char		    lcs_name[80];
+
+	/*
+	 * Sequence width, that is how many objects may be allocated in one
+	 * sequence. Default value for it is LUSTRE_SEQ_MAX_WIDTH.
+	 */
+	__u64		   lcs_width;
+
+	/* Seq-server for direct talking */
+	struct lu_server_seq   *lcs_srv;
+
+	/* wait queue for fid allocation and update indicator */
+	wait_queue_head_t	     lcs_waitq;
+	int		     lcs_update;
+};
+
+/* server sequence manager interface */
+struct lu_server_seq {
+	/* Available sequences space */
+	struct lu_seq_range	 lss_space;
+
+	/* keeps highwater in lsr_end for seq allocation algorithm */
+	struct lu_seq_range	 lss_lowater_set;
+	struct lu_seq_range	 lss_hiwater_set;
+
+	/*
+	 * Device for server side seq manager needs (saving sequences to backing
+	 * store).
+	 */
+	struct dt_device       *lss_dev;
+
+	/* /seq file object device */
+	struct dt_object       *lss_obj;
+
+	/* Seq related proc */
+	proc_dir_entry_t   *lss_proc_dir;
+
+	/* LUSTRE_SEQ_SERVER or LUSTRE_SEQ_CONTROLLER */
+	enum lu_mgr_type       lss_type;
+
+	/* Client interafce to request controller */
+	struct lu_client_seq   *lss_cli;
+
+	/* Mutex for protecting allocation */
+	struct mutex		lss_mutex;
+
+	/*
+	 * Service uuid, passed from MDT + seq name to form unique seq name to
+	 * use it with procfs.
+	 */
+	char		    lss_name[80];
+
+	/*
+	 * Allocation chunks for super and meta sequences. Default values are
+	 * LUSTRE_SEQ_SUPER_WIDTH and LUSTRE_SEQ_META_WIDTH.
+	 */
+	__u64		   lss_width;
+
+	/*
+	 * minimum lss_alloc_set size that should be allocated from
+	 * lss_space
+	 */
+	__u64		   lss_set_width;
+
+	/* sync is needed for update operation */
+	__u32		   lss_need_sync;
+
+	/**
+	 * Pointer to site object, required to access site fld.
+	 */
+	struct seq_server_site  *lss_site;
+};
+
+int seq_query(struct com_thread_info *info);
+int seq_handle(struct ptlrpc_request *req);
+
+/* Server methods */
+int seq_server_init(struct lu_server_seq *seq,
+		    struct dt_device *dev,
+		    const char *prefix,
+		    enum lu_mgr_type type,
+		    struct seq_server_site *ss,
+		    const struct lu_env *env);
+
+void seq_server_fini(struct lu_server_seq *seq,
+		     const struct lu_env *env);
+
+int seq_server_alloc_super(struct lu_server_seq *seq,
+			   struct lu_seq_range *out,
+			   const struct lu_env *env);
+
+int seq_server_alloc_meta(struct lu_server_seq *seq,
+			  struct lu_seq_range *out,
+			  const struct lu_env *env);
+
+int seq_server_set_cli(struct lu_server_seq *seq,
+		       struct lu_client_seq *cli,
+		       const struct lu_env *env);
+
+/* Client methods */
+int seq_client_init(struct lu_client_seq *seq,
+		    struct obd_export *exp,
+		    enum lu_cli_type type,
+		    const char *prefix,
+		    struct lu_server_seq *srv);
+
+void seq_client_fini(struct lu_client_seq *seq);
+
+void seq_client_flush(struct lu_client_seq *seq);
+
+int seq_client_alloc_fid(const struct lu_env *env, struct lu_client_seq *seq,
+			 struct lu_fid *fid);
+int seq_client_get_seq(const struct lu_env *env, struct lu_client_seq *seq,
+		       seqno_t *seqnr);
+int seq_site_fini(const struct lu_env *env, struct seq_server_site *ss);
+/* Fids common stuff */
+int fid_is_local(const struct lu_env *env,
+		 struct lu_site *site, const struct lu_fid *fid);
+
+int client_fid_init(struct obd_device *obd, struct obd_export *exp,
+		    enum lu_cli_type type);
+int client_fid_fini(struct obd_device *obd);
+
+/* fid locking */
+
+struct ldlm_namespace;
+
+/*
+ * Build (DLM) resource name from FID.
+ *
+ * NOTE: until Lustre 1.8.7/2.1.1 the fid_ver() was packed into name[2],
+ * but was moved into name[1] along with the OID to avoid consuming the
+ * renaming name[2,3] fields that need to be used for the quota identifier.
+ */
+static inline struct ldlm_res_id *
+fid_build_reg_res_name(const struct lu_fid *f,
+		       struct ldlm_res_id *name)
+{
+	memset(name, 0, sizeof *name);
+	name->name[LUSTRE_RES_ID_SEQ_OFF] = fid_seq(f);
+	name->name[LUSTRE_RES_ID_VER_OID_OFF] = fid_ver_oid(f);
+	return name;
+}
+
+/*
+ * Build (DLM) resource identifier from global quota FID and quota ID.
+ */
+static inline struct ldlm_res_id *
+fid_build_quota_resid(const struct lu_fid *glb_fid, union lquota_id *qid,
+		      struct ldlm_res_id *res)
+{
+	fid_build_reg_res_name(glb_fid, res);
+	res->name[LUSTRE_RES_ID_QUOTA_SEQ_OFF] = fid_seq(&qid->qid_fid);
+	res->name[LUSTRE_RES_ID_QUOTA_VER_OID_OFF] = fid_ver_oid(&qid->qid_fid);
+	return res;
+}
+
+/*
+ * Extract global FID and quota ID from resource name
+ */
+static inline void fid_extract_quota_resid(struct ldlm_res_id *res,
+					   struct lu_fid *glb_fid,
+					   union lquota_id *qid)
+{
+	glb_fid->f_seq = res->name[LUSTRE_RES_ID_SEQ_OFF];
+	glb_fid->f_oid = (__u32)res->name[LUSTRE_RES_ID_VER_OID_OFF];
+	glb_fid->f_ver = (__u32)(res->name[LUSTRE_RES_ID_VER_OID_OFF] >> 32);
+
+	qid->qid_fid.f_seq = res->name[LUSTRE_RES_ID_QUOTA_SEQ_OFF];
+	qid->qid_fid.f_oid = (__u32)res->name[LUSTRE_RES_ID_QUOTA_VER_OID_OFF];
+	qid->qid_fid.f_ver =
+		(__u32)(res->name[LUSTRE_RES_ID_QUOTA_VER_OID_OFF] >> 32);
+}
+
+/*
+ * Return true if resource is for object identified by fid.
+ */
+static inline int fid_res_name_eq(const struct lu_fid *f,
+				  const struct ldlm_res_id *name)
+{
+	return name->name[LUSTRE_RES_ID_SEQ_OFF] == fid_seq(f) &&
+	       name->name[LUSTRE_RES_ID_VER_OID_OFF] == fid_ver_oid(f);
+}
+
+/* reverse function of fid_build_reg_res_name() */
+static inline void fid_build_from_res_name(struct lu_fid *f,
+					   const struct ldlm_res_id *name)
+{
+	fid_zero(f);
+	f->f_seq = name->name[LUSTRE_RES_ID_SEQ_OFF];
+	f->f_oid = name->name[LUSTRE_RES_ID_VER_OID_OFF] & 0xffffffff;
+	f->f_ver = name->name[LUSTRE_RES_ID_VER_OID_OFF] >> 32;
+	LASSERT(fid_res_name_eq(f, name));
+}
+
+static inline struct ldlm_res_id *
+fid_build_pdo_res_name(const struct lu_fid *f,
+		       unsigned int hash,
+		       struct ldlm_res_id *name)
+{
+	fid_build_reg_res_name(f, name);
+	name->name[LUSTRE_RES_ID_HSH_OFF] = hash;
+	return name;
+}
+
+/**
+ * Build DLM resource name from object id & seq, which will be removed
+ * finally, when we replace ost_id with FID in data stack.
+ *
+ * Currently, resid from the old client, whose res[0] = object_id,
+ * res[1] = object_seq, is just oposite with Metatdata
+ * resid, where, res[0] = fid->f_seq, res[1] = fid->f_oid.
+ * To unifiy the resid identification, we will reverse the data
+ * resid to keep it same with Metadata resid, i.e.
+ *
+ * For resid from the old client,
+ *    res[0] = objid,  res[1] = 0, still keep the original order,
+ *    for compatiblity.
+ *
+ * For new resid
+ *    res will be built from normal FID directly, i.e. res[0] = f_seq,
+ *    res[1] = f_oid + f_ver.
+ */
+static inline void ostid_build_res_name(struct ost_id *oi,
+					struct ldlm_res_id *name)
+{
+	memset(name, 0, sizeof *name);
+	if (fid_seq_is_mdt0(ostid_seq(oi))) {
+		name->name[LUSTRE_RES_ID_SEQ_OFF] = ostid_id(oi);
+		name->name[LUSTRE_RES_ID_VER_OID_OFF] = ostid_seq(oi);
+	} else {
+		fid_build_reg_res_name((struct lu_fid *)oi, name);
+	}
+}
+
+static inline void ostid_res_name_to_id(struct ost_id *oi,
+					struct ldlm_res_id *name)
+{
+	if (fid_seq_is_mdt0(name->name[LUSTRE_RES_ID_SEQ_OFF])) {
+		/* old resid */
+		ostid_set_seq(oi, name->name[LUSTRE_RES_ID_VER_OID_OFF]);
+		ostid_set_id(oi, name->name[LUSTRE_RES_ID_SEQ_OFF]);
+	} else {
+		/* new resid */
+		fid_build_from_res_name((struct lu_fid *)oi, name);
+	}
+}
+
+/**
+ * Return true if the resource is for the object identified by this id & group.
+ */
+static inline int ostid_res_name_eq(struct ost_id *oi,
+				    struct ldlm_res_id *name)
+{
+	/* Note: it is just a trick here to save some effort, probably the
+	 * correct way would be turn them into the FID and compare */
+	if (fid_seq_is_mdt0(ostid_seq(oi))) {
+		return name->name[LUSTRE_RES_ID_SEQ_OFF] == ostid_id(oi) &&
+		       name->name[LUSTRE_RES_ID_VER_OID_OFF] == ostid_seq(oi);
+	} else {
+		return name->name[LUSTRE_RES_ID_SEQ_OFF] == ostid_seq(oi) &&
+		       name->name[LUSTRE_RES_ID_VER_OID_OFF] == ostid_id(oi);
+	}
+}
+
+/* The same as osc_build_res_name() */
+static inline void ost_fid_build_resid(const struct lu_fid *fid,
+				       struct ldlm_res_id *resname)
+{
+	if (fid_is_mdt0(fid) || fid_is_idif(fid)) {
+		struct ost_id oi;
+		oi.oi.oi_id = 0; /* gcc 4.7.2 complains otherwise */
+		if (fid_to_ostid(fid, &oi) != 0)
+			return;
+		ostid_build_res_name(&oi, resname);
+	} else {
+		fid_build_reg_res_name(fid, resname);
+	}
+}
+
+static inline void ost_fid_from_resid(struct lu_fid *fid,
+				      const struct ldlm_res_id *name)
+{
+	if (fid_seq_is_mdt0(name->name[LUSTRE_RES_ID_VER_OID_OFF])) {
+		/* old resid */
+		struct ost_id oi;
+		ostid_set_seq(&oi, name->name[LUSTRE_RES_ID_VER_OID_OFF]);
+		ostid_set_id(&oi, name->name[LUSTRE_RES_ID_SEQ_OFF]);
+		ostid_to_fid(fid, &oi, 0);
+	} else {
+		/* new resid */
+		fid_build_from_res_name(fid, name);
+	}
+}
+
+/**
+ * Flatten 128-bit FID values into a 64-bit value for use as an inode number.
+ * For non-IGIF FIDs this starts just over 2^32, and continues without
+ * conflict until 2^64, at which point we wrap the high 24 bits of the SEQ
+ * into the range where there may not be many OID values in use, to minimize
+ * the risk of conflict.
+ *
+ * Suppose LUSTRE_SEQ_MAX_WIDTH less than (1 << 24) which is currently true,
+ * the time between re-used inode numbers is very long - 2^40 SEQ numbers,
+ * or about 2^40 client mounts, if clients create less than 2^24 files/mount.
+ */
+static inline __u64 fid_flatten(const struct lu_fid *fid)
+{
+	__u64 ino;
+	__u64 seq;
+
+	if (fid_is_igif(fid)) {
+		ino = lu_igif_ino(fid);
+		RETURN(ino);
+	}
+
+	seq = fid_seq(fid);
+
+	ino = (seq << 24) + ((seq >> 24) & 0xffffff0000ULL) + fid_oid(fid);
+
+	RETURN(ino ? ino : fid_oid(fid));
+}
+
+static inline __u32 fid_hash(const struct lu_fid *f, int bits)
+{
+	/* all objects with same id and different versions will belong to same
+	 * collisions list. */
+	return cfs_hash_long(fid_flatten(f), bits);
+}
+
+/**
+ * map fid to 32 bit value for ino on 32bit systems. */
+static inline __u32 fid_flatten32(const struct lu_fid *fid)
+{
+	__u32 ino;
+	__u64 seq;
+
+	if (fid_is_igif(fid)) {
+		ino = lu_igif_ino(fid);
+		RETURN(ino);
+	}
+
+	seq = fid_seq(fid) - FID_SEQ_START;
+
+	/* Map the high bits of the OID into higher bits of the inode number so
+	 * that inodes generated at about the same time have a reduced chance
+	 * of collisions. This will give a period of 2^12 = 1024 unique clients
+	 * (from SEQ) and up to min(LUSTRE_SEQ_MAX_WIDTH, 2^20) = 128k objects
+	 * (from OID), or up to 128M inodes without collisions for new files. */
+	ino = ((seq & 0x000fffffULL) << 12) + ((seq >> 8) & 0xfffff000) +
+	       (seq >> (64 - (40-8)) & 0xffffff00) +
+	       (fid_oid(fid) & 0xff000fff) + ((fid_oid(fid) & 0x00fff000) << 8);
+
+	RETURN(ino ? ino : fid_oid(fid));
+}
+
+static inline int lu_fid_diff(struct lu_fid *fid1, struct lu_fid *fid2)
+{
+	LASSERTF(fid_seq(fid1) == fid_seq(fid2), "fid1:"DFID", fid2:"DFID"\n",
+		 PFID(fid1), PFID(fid2));
+
+	if (fid_is_idif(fid1) && fid_is_idif(fid2))
+		return fid_idif_id(fid1->f_seq, fid1->f_oid, fid1->f_ver) -
+		       fid_idif_id(fid2->f_seq, fid2->f_oid, fid2->f_ver);
+
+	return fid_oid(fid1) - fid_oid(fid2);
+}
+
+#define LUSTRE_SEQ_SRV_NAME "seq_srv"
+#define LUSTRE_SEQ_CTL_NAME "seq_ctl"
+
+/* Range common stuff */
+static inline void range_cpu_to_le(struct lu_seq_range *dst, const struct lu_seq_range *src)
+{
+	dst->lsr_start = cpu_to_le64(src->lsr_start);
+	dst->lsr_end = cpu_to_le64(src->lsr_end);
+	dst->lsr_index = cpu_to_le32(src->lsr_index);
+	dst->lsr_flags = cpu_to_le32(src->lsr_flags);
+}
+
+static inline void range_le_to_cpu(struct lu_seq_range *dst, const struct lu_seq_range *src)
+{
+	dst->lsr_start = le64_to_cpu(src->lsr_start);
+	dst->lsr_end = le64_to_cpu(src->lsr_end);
+	dst->lsr_index = le32_to_cpu(src->lsr_index);
+	dst->lsr_flags = le32_to_cpu(src->lsr_flags);
+}
+
+static inline void range_cpu_to_be(struct lu_seq_range *dst, const struct lu_seq_range *src)
+{
+	dst->lsr_start = cpu_to_be64(src->lsr_start);
+	dst->lsr_end = cpu_to_be64(src->lsr_end);
+	dst->lsr_index = cpu_to_be32(src->lsr_index);
+	dst->lsr_flags = cpu_to_be32(src->lsr_flags);
+}
+
+static inline void range_be_to_cpu(struct lu_seq_range *dst, const struct lu_seq_range *src)
+{
+	dst->lsr_start = be64_to_cpu(src->lsr_start);
+	dst->lsr_end = be64_to_cpu(src->lsr_end);
+	dst->lsr_index = be32_to_cpu(src->lsr_index);
+	dst->lsr_flags = be32_to_cpu(src->lsr_flags);
+}
+
+/** @} fid */
+
+#endif /* __LINUX_FID_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_fld.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_fld.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_fld.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_fld.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,202 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2013, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LINUX_FLD_H
+#define __LINUX_FLD_H
+
+/** \defgroup fld fld
+ *
+ * @{
+ */
+
+#include <lustre/lustre_idl.h>
+#include <lustre_mdt.h>
+#include <dt_object.h>
+
+#include <linux/libcfs/libcfs.h>
+
+struct lu_client_fld;
+struct lu_server_fld;
+struct lu_fld_hash;
+struct fld_cache;
+
+extern const struct dt_index_features fld_index_features;
+extern const char fld_index_name[];
+
+/*
+ * FLD (Fid Location Database) interface.
+ */
+enum {
+	LUSTRE_CLI_FLD_HASH_DHT = 0,
+	LUSTRE_CLI_FLD_HASH_RRB
+};
+
+
+struct lu_fld_target {
+	struct list_head	       ft_chain;
+	struct obd_export       *ft_exp;
+	struct lu_server_fld    *ft_srv;
+	__u64		    ft_idx;
+};
+
+struct lu_server_fld {
+	/**
+	 * Fld dir proc entry. */
+	proc_dir_entry_t    *lsf_proc_dir;
+
+	/**
+	 * /fld file object device */
+	struct dt_object	*lsf_obj;
+
+	/**
+	 * super sequence controller export, needed to forward fld
+	 * lookup  request. */
+	struct obd_export       *lsf_control_exp;
+
+	/**
+	 * Client FLD cache. */
+	struct fld_cache	*lsf_cache;
+
+	/**
+	 * Protect index modifications */
+	struct mutex		lsf_lock;
+
+	/**
+	 * Fld service name in form "fld-srv-lustre-MDTXXX" */
+	char		     lsf_name[80];
+
+};
+
+struct lu_client_fld {
+	/**
+	 * Client side proc entry. */
+	proc_dir_entry_t    *lcf_proc_dir;
+
+	/**
+	 * List of exports client FLD knows about. */
+	struct list_head	       lcf_targets;
+
+	/**
+	 * Current hash to be used to chose an export. */
+	struct lu_fld_hash      *lcf_hash;
+
+	/**
+	 * Exports count. */
+	int		      lcf_count;
+
+	/**
+	 * Lock protecting exports list and fld_hash. */
+	spinlock_t		 lcf_lock;
+
+	/**
+	 * Client FLD cache. */
+	struct fld_cache	*lcf_cache;
+
+	/**
+	 * Client fld proc entry name. */
+	char		     lcf_name[80];
+
+	const struct lu_context *lcf_ctx;
+
+	int		      lcf_flags;
+};
+
+/**
+ * number of blocks to reserve for particular operations. Should be function of
+ * ... something. Stub for now.
+ */
+enum {
+	/* one insert operation can involve two delete and one insert */
+	FLD_TXN_INDEX_INSERT_CREDITS  = 60,
+	FLD_TXN_INDEX_DELETE_CREDITS  = 20,
+};
+
+int fld_query(struct com_thread_info *info);
+
+/* Server methods */
+int fld_server_init(const struct lu_env *env, struct lu_server_fld *fld,
+		    struct dt_device *dt, const char *prefix, int mds_node_id,
+		    int type);
+
+void fld_server_fini(const struct lu_env *env, struct lu_server_fld *fld);
+
+int fld_declare_server_create(const struct lu_env *env,
+			      struct lu_server_fld *fld,
+			      struct lu_seq_range *new,
+			      struct thandle *th);
+
+int fld_server_create(const struct lu_env *env,
+		      struct lu_server_fld *fld,
+		      struct lu_seq_range *add_range,
+		      struct thandle *th);
+
+int fld_insert_entry(const struct lu_env *env,
+		     struct lu_server_fld *fld,
+		     const struct lu_seq_range *range);
+
+int fld_server_lookup(const struct lu_env *env, struct lu_server_fld *fld,
+		      seqno_t seq, struct lu_seq_range *range);
+
+/* Client methods */
+int fld_client_init(struct lu_client_fld *fld,
+		    const char *prefix, int hash);
+
+void fld_client_fini(struct lu_client_fld *fld);
+
+void fld_client_flush(struct lu_client_fld *fld);
+
+int fld_client_lookup(struct lu_client_fld *fld, seqno_t seq, mdsno_t *mds,
+		      __u32 flags, const struct lu_env *env);
+
+int fld_client_create(struct lu_client_fld *fld,
+		      struct lu_seq_range *range,
+		      const struct lu_env *env);
+
+int fld_client_delete(struct lu_client_fld *fld,
+		      seqno_t seq,
+		      const struct lu_env *env);
+
+int fld_client_add_target(struct lu_client_fld *fld,
+			  struct lu_fld_target *tar);
+
+int fld_client_del_target(struct lu_client_fld *fld,
+			  __u64 idx);
+
+void fld_client_proc_fini(struct lu_client_fld *fld);
+
+/** @} fld */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_fsfilt.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_fsfilt.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_fsfilt.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_fsfilt.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_fsfilt.h
+ *
+ * Filesystem interface helper.
+ */
+
+#ifndef _LUSTRE_FSFILT_H
+#define _LUSTRE_FSFILT_H
+
+#include <linux/lustre_fsfilt.h>
+
+#define LU221_BAD_TIME (0x80000000U + 24 * 3600)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_ha.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_ha.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_ha.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_ha.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LUSTRE_HA_H
+#define _LUSTRE_HA_H
+
+/** \defgroup ha ha
+ *
+ * @{
+ */
+
+struct obd_import;
+struct obd_export;
+struct obd_device;
+struct ptlrpc_request;
+
+
+int ptlrpc_replay(struct obd_import *imp);
+int ptlrpc_resend(struct obd_import *imp);
+void ptlrpc_free_committed(struct obd_import *imp);
+void ptlrpc_wake_delayed(struct obd_import *imp);
+int ptlrpc_recover_import(struct obd_import *imp, char *new_uuid, int async);
+int ptlrpc_set_import_active(struct obd_import *imp, int active);
+void ptlrpc_activate_import(struct obd_import *imp);
+void ptlrpc_deactivate_import(struct obd_import *imp);
+void ptlrpc_invalidate_import(struct obd_import *imp);
+void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt);
+int ptlrpc_check_suspend(void);
+void ptlrpc_activate_timeouts(struct obd_import *imp);
+void ptlrpc_deactivate_timeouts(struct obd_import *imp);
+
+/** @} ha */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_handles.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_handles.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_handles.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_handles.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,93 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LUSTRE_HANDLES_H_
+#define __LUSTRE_HANDLES_H_
+
+/** \defgroup handles handles
+ *
+ * @{
+ */
+
+#include <linux/lustre_handles.h>
+
+#include <linux/libcfs/libcfs.h>
+
+
+struct portals_handle_ops {
+	void (*hop_addref)(void *object);
+	void (*hop_free)(void *object, int size);
+};
+
+/* These handles are most easily used by having them appear at the very top of
+ * whatever object that you want to make handles for.  ie:
+ *
+ * struct ldlm_lock {
+ *	 struct portals_handle handle;
+ *	 ...
+ * };
+ *
+ * Now you're able to assign the results of cookie2handle directly to an
+ * ldlm_lock.  If it's not at the top, you'll want to use container_of()
+ * to compute the start of the structure based on the handle field. */
+struct portals_handle {
+	struct list_head			h_link;
+	__u64				h_cookie;
+	struct portals_handle_ops	*h_ops;
+
+	/* newly added fields to handle the RCU issue. -jxiong */
+	cfs_rcu_head_t			h_rcu;
+	spinlock_t			h_lock;
+	unsigned int			h_size:31;
+	unsigned int			h_in:1;
+};
+#define RCU2HANDLE(rcu)    container_of(rcu, struct portals_handle, h_rcu)
+
+/* handles.c */
+
+/* Add a handle to the hash table */
+void class_handle_hash(struct portals_handle *,
+		       struct portals_handle_ops *ops);
+void class_handle_unhash(struct portals_handle *);
+void class_handle_hash_back(struct portals_handle *);
+void *class_handle2object(__u64 cookie);
+void class_handle_free_cb(cfs_rcu_head_t *);
+int class_handle_init(void);
+void class_handle_cleanup(void);
+
+/** @} handles */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_idmap.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_idmap.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_idmap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_idmap.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,104 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/lustre/include/lustre_idmap.h
+ *
+ * MDS data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ */
+
+#ifndef _LUSTRE_IDMAP_H
+#define _LUSTRE_IDMAP_H
+
+/** \defgroup idmap idmap
+ *
+ * @{
+ */
+
+#include <linux/libcfs/libcfs.h>
+
+#define CFS_NGROUPS_PER_BLOCK   ((int)(PAGE_CACHE_SIZE / sizeof(gid_t)))
+
+#define CFS_GROUP_AT(gi, i) \
+	((gi)->blocks[(i) / CFS_NGROUPS_PER_BLOCK][(i) % CFS_NGROUPS_PER_BLOCK])
+
+enum {
+	CFS_IC_NOTHING     = 0,    /* convert nothing */
+	CFS_IC_ALL	 = 1,    /* convert all items */
+	CFS_IC_MAPPED      = 2,    /* convert mapped uid/gid */
+	CFS_IC_UNMAPPED    = 3     /* convert unmapped uid/gid */
+};
+
+#define  CFS_IDMAP_NOTFOUND     (-1)
+
+#define CFS_IDMAP_HASHSIZE      32
+
+enum lustre_idmap_idx {
+	RMT_UIDMAP_IDX,
+	LCL_UIDMAP_IDX,
+	RMT_GIDMAP_IDX,
+	LCL_GIDMAP_IDX,
+	CFS_IDMAP_N_HASHES
+};
+
+struct lustre_idmap_table {
+	spinlock_t	lit_lock;
+	struct list_head	lit_idmaps[CFS_IDMAP_N_HASHES][CFS_IDMAP_HASHSIZE];
+};
+
+struct lu_ucred;
+
+extern void lustre_groups_from_list(group_info_t *ginfo, gid_t *glist);
+extern void lustre_groups_sort(group_info_t *group_info);
+extern int lustre_in_group_p(struct lu_ucred *mu, gid_t grp);
+
+extern int lustre_idmap_add(struct lustre_idmap_table *t,
+			    uid_t ruid, uid_t luid,
+			    gid_t rgid, gid_t lgid);
+extern int lustre_idmap_del(struct lustre_idmap_table *t,
+			    uid_t ruid, uid_t luid,
+			    gid_t rgid, gid_t lgid);
+extern int lustre_idmap_lookup_uid(struct lu_ucred *mu,
+				   struct lustre_idmap_table *t,
+				   int reverse, uid_t uid);
+extern int lustre_idmap_lookup_gid(struct lu_ucred *mu,
+				   struct lustre_idmap_table *t,
+				   int reverse, gid_t gid);
+extern struct lustre_idmap_table *lustre_idmap_init(void);
+extern void lustre_idmap_fini(struct lustre_idmap_table *t);
+
+/** @} idmap */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_import.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_import.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_import.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_import.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,367 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+/** \defgroup obd_import PtlRPC import definitions
+ * Imports are client-side representation of remote obd target.
+ *
+ * @{
+ */
+
+#ifndef __IMPORT_H
+#define __IMPORT_H
+
+/** \defgroup export export
+ *
+ * @{
+ */
+
+#include <lustre_handles.h>
+#include <lustre/lustre_idl.h>
+
+
+/**
+ * Adaptive Timeout stuff
+ *
+ * @{
+ */
+#define D_ADAPTTO D_OTHER
+#define AT_BINS 4		  /* "bin" means "N seconds of history" */
+#define AT_FLG_NOHIST 0x1	  /* use last reported value only */
+
+struct adaptive_timeout {
+	time_t		at_binstart;	 /* bin start time */
+	unsigned int	at_hist[AT_BINS];    /* timeout history bins */
+	unsigned int	at_flags;
+	unsigned int	at_current;	  /* current timeout value */
+	unsigned int	at_worst_ever;       /* worst-ever timeout value */
+	time_t		at_worst_time;       /* worst-ever timeout timestamp */
+	spinlock_t	at_lock;
+};
+
+struct ptlrpc_at_array {
+	struct list_head       *paa_reqs_array; /** array to hold requests */
+	__u32	     paa_size;       /** the size of array */
+	__u32	     paa_count;      /** the total count of reqs */
+	time_t	    paa_deadline;   /** the earliest deadline of reqs */
+	__u32	    *paa_reqs_count; /** the count of reqs in each entry */
+};
+
+#define IMP_AT_MAX_PORTALS 8
+struct imp_at {
+	int		     iat_portal[IMP_AT_MAX_PORTALS];
+	struct adaptive_timeout iat_net_latency;
+	struct adaptive_timeout iat_service_estimate[IMP_AT_MAX_PORTALS];
+};
+
+
+/** @} */
+
+/** Possible import states */
+enum lustre_imp_state {
+	LUSTRE_IMP_CLOSED     = 1,
+	LUSTRE_IMP_NEW	= 2,
+	LUSTRE_IMP_DISCON     = 3,
+	LUSTRE_IMP_CONNECTING = 4,
+	LUSTRE_IMP_REPLAY     = 5,
+	LUSTRE_IMP_REPLAY_LOCKS = 6,
+	LUSTRE_IMP_REPLAY_WAIT  = 7,
+	LUSTRE_IMP_RECOVER    = 8,
+	LUSTRE_IMP_FULL       = 9,
+	LUSTRE_IMP_EVICTED    = 10,
+};
+
+/** Returns test string representation of numeric import state \a state */
+static inline char * ptlrpc_import_state_name(enum lustre_imp_state state)
+{
+	static char* import_state_names[] = {
+		"<UNKNOWN>", "CLOSED",  "NEW", "DISCONN",
+		"CONNECTING", "REPLAY", "REPLAY_LOCKS", "REPLAY_WAIT",
+		"RECOVER", "FULL", "EVICTED",
+	};
+
+	LASSERT (state <= LUSTRE_IMP_EVICTED);
+	return import_state_names[state];
+}
+
+/**
+ * List of import event types
+ */
+enum obd_import_event {
+	IMP_EVENT_DISCON     = 0x808001,
+	IMP_EVENT_INACTIVE   = 0x808002,
+	IMP_EVENT_INVALIDATE = 0x808003,
+	IMP_EVENT_ACTIVE     = 0x808004,
+	IMP_EVENT_OCD	= 0x808005,
+	IMP_EVENT_DEACTIVATE = 0x808006,
+	IMP_EVENT_ACTIVATE   = 0x808007,
+};
+
+/**
+ * Definition of import connection structure
+ */
+struct obd_import_conn {
+	/** Item for linking connections together */
+	struct list_head		oic_item;
+	/** Pointer to actual PortalRPC connection */
+	struct ptlrpc_connection *oic_conn;
+	/** uuid of remote side */
+	struct obd_uuid	   oic_uuid;
+	/**
+	 * Time (64 bit jiffies) of last connection attempt on this connection
+	 */
+	__u64		     oic_last_attempt;
+};
+
+/* state history */
+#define IMP_STATE_HIST_LEN 16
+struct import_state_hist {
+	enum lustre_imp_state ish_state;
+	time_t		ish_time;
+};
+
+/**
+ * Defintion of PortalRPC import structure.
+ * Imports are representing client-side view to remote target.
+ */
+struct obd_import {
+	/** Local handle (== id) for this import. */
+	struct portals_handle     imp_handle;
+	/** Reference counter */
+	atomic_t	      imp_refcount;
+	struct lustre_handle      imp_dlm_handle; /* client's ldlm export */
+	/** Currently active connection */
+	struct ptlrpc_connection *imp_connection;
+	/** PortalRPC client structure for this import */
+	struct ptlrpc_client     *imp_client;
+	/** List element for linking into pinger chain */
+	struct list_head		imp_pinger_chain;
+	/** List element for linking into chain for destruction */
+	struct list_head		imp_zombie_chain;
+
+	/**
+	 * Lists of requests that are retained for replay, waiting for a reply,
+	 * or waiting for recovery to complete, respectively.
+	 * @{
+	 */
+	struct list_head		imp_replay_list;
+	struct list_head		imp_sending_list;
+	struct list_head		imp_delayed_list;
+	/** @} */
+
+	/** obd device for this import */
+	struct obd_device	*imp_obd;
+
+	/**
+	 * some seciruty-related fields
+	 * @{
+	 */
+	struct ptlrpc_sec	*imp_sec;
+	struct mutex		  imp_sec_mutex;
+	cfs_time_t		imp_sec_expire;
+	/** @} */
+
+	/** Wait queue for those who need to wait for recovery completion */
+	wait_queue_head_t	       imp_recovery_waitq;
+
+	/** Number of requests currently in-flight */
+	atomic_t	      imp_inflight;
+	/** Number of requests currently unregistering */
+	atomic_t	      imp_unregistering;
+	/** Number of replay requests inflight */
+	atomic_t	      imp_replay_inflight;
+	/** Number of currently happening import invalidations */
+	atomic_t	      imp_inval_count;
+	/** Numbner of request timeouts */
+	atomic_t	      imp_timeouts;
+	/** Current import state */
+	enum lustre_imp_state     imp_state;
+	/** History of import states */
+	struct import_state_hist  imp_state_hist[IMP_STATE_HIST_LEN];
+	int		       imp_state_hist_idx;
+	/** Current import generation. Incremented on every reconnect */
+	int		       imp_generation;
+	/** Incremented every time we send reconnection request */
+	__u32		     imp_conn_cnt;
+       /**
+	* \see ptlrpc_free_committed remembers imp_generation value here
+	* after a check to save on unnecessary replay list iterations
+	*/
+	int		       imp_last_generation_checked;
+	/** Last tranno we replayed */
+	__u64		     imp_last_replay_transno;
+	/** Last transno committed on remote side */
+	__u64		     imp_peer_committed_transno;
+	/**
+	 * \see ptlrpc_free_committed remembers last_transno since its last
+	 * check here and if last_transno did not change since last run of
+	 * ptlrpc_free_committed and import generation is the same, we can
+	 * skip looking for requests to remove from replay list as optimisation
+	 */
+	__u64		     imp_last_transno_checked;
+	/**
+	 * Remote export handle. This is how remote side knows what export
+	 * we are talking to. Filled from response to connect request
+	 */
+	struct lustre_handle      imp_remote_handle;
+	/** When to perform next ping. time in jiffies. */
+	cfs_time_t		imp_next_ping;
+	/** When we last succesfully connected. time in 64bit jiffies */
+	__u64		     imp_last_success_conn;
+
+	/** List of all possible connection for import. */
+	struct list_head		imp_conn_list;
+	/**
+	 * Current connection. \a imp_connection is imp_conn_current->oic_conn
+	 */
+	struct obd_import_conn   *imp_conn_current;
+
+	/** Protects flags, level, generation, conn_cnt, *_list */
+	spinlock_t		  imp_lock;
+
+	/* flags */
+	unsigned long	     imp_no_timeout:1, /* timeouts are disabled */
+				  imp_invalid:1,    /* evicted */
+				  /* administratively disabled */
+				  imp_deactive:1,
+				  /* try to recover the import */
+				  imp_replayable:1,
+				  /* don't run recovery (timeout instead) */
+				  imp_dlm_fake:1,
+				  /* use 1/2 timeout on MDS' OSCs */
+				  imp_server_timeout:1,
+				  /* VBR: imp in delayed recovery */
+				  imp_delayed_recovery:1,
+				  /* VBR: if gap was found then no lock replays
+				   */
+				  imp_no_lock_replay:1,
+				  /* recovery by versions was failed */
+				  imp_vbr_failed:1,
+				  /* force an immidiate ping */
+				  imp_force_verify:1,
+				  /* force a scheduled ping */
+				  imp_force_next_verify:1,
+				  /* pingable */
+				  imp_pingable:1,
+				  /* resend for replay */
+				  imp_resend_replay:1,
+				  /* disable normal recovery, for test only. */
+				  imp_no_pinger_recover:1,
+				  /* need IR MNE swab */
+				  imp_need_mne_swab:1,
+				  /* import must be reconnected instead of
+				   * chouse new connection */
+				  imp_force_reconnect:1,
+				  /* import has tried to connect with server */
+				  imp_connect_tried:1;
+	__u32		     imp_connect_op;
+	struct obd_connect_data   imp_connect_data;
+	__u64		     imp_connect_flags_orig;
+	int		       imp_connect_error;
+
+	__u32		     imp_msg_magic;
+	__u32		     imp_msghdr_flags;       /* adjusted based on server capability */
+
+	struct ptlrpc_request_pool *imp_rq_pool;	  /* emergency request pool */
+
+	struct imp_at	     imp_at;		 /* adaptive timeout data */
+	time_t		    imp_last_reply_time;    /* for health check */
+};
+
+typedef void (*obd_import_callback)(struct obd_import *imp, void *closure,
+				    int event, void *event_arg, void *cb_data);
+
+/**
+ * Structure for import observer.
+ * It is possible to register "observer" on an import and every time
+ * something happens to an import (like connect/evict/disconnect)
+ * obderver will get its callback called with event type
+ */
+struct obd_import_observer {
+	struct list_head	   oio_chain;
+	obd_import_callback  oio_cb;
+	void		*oio_cb_data;
+};
+
+void class_observe_import(struct obd_import *imp, obd_import_callback cb,
+			  void *cb_data);
+void class_unobserve_import(struct obd_import *imp, obd_import_callback cb,
+			    void *cb_data);
+void class_notify_import_observers(struct obd_import *imp, int event,
+				   void *event_arg);
+
+/* import.c */
+static inline unsigned int at_est2timeout(unsigned int val)
+{
+	/* add an arbitrary minimum: 125% +5 sec */
+	return (val + (val >> 2) + 5);
+}
+
+static inline unsigned int at_timeout2est(unsigned int val)
+{
+	/* restore estimate value from timeout: e=4/5(t-5) */
+	LASSERT(val);
+	return (max((val << 2) / 5, 5U) - 4);
+}
+
+static inline void at_reset(struct adaptive_timeout *at, int val) {
+	at->at_current = val;
+	at->at_worst_ever = val;
+	at->at_worst_time = cfs_time_current_sec();
+}
+static inline void at_init(struct adaptive_timeout *at, int val, int flags) {
+	memset(at, 0, sizeof(*at));
+	spin_lock_init(&at->at_lock);
+	at->at_flags = flags;
+	at_reset(at, val);
+}
+extern unsigned int at_min;
+static inline int at_get(struct adaptive_timeout *at) {
+	return (at->at_current > at_min) ? at->at_current : at_min;
+}
+int at_measured(struct adaptive_timeout *at, unsigned int val);
+int import_at_get_index(struct obd_import *imp, int portal);
+extern unsigned int at_max;
+#define AT_OFF (at_max == 0)
+
+/* genops.c */
+struct obd_export;
+extern struct obd_import *class_exp2cliimp(struct obd_export *);
+extern struct obd_import *class_conn2cliimp(struct lustre_handle *);
+
+/** @} import */
+
+#endif /* __IMPORT_H */
+
+/** @} obd_import */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_lib.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_lib.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_lib.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_lib.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,667 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_lib.h
+ *
+ * Basic Lustre library routines.
+ */
+
+#ifndef _LUSTRE_LIB_H
+#define _LUSTRE_LIB_H
+
+/** \defgroup lib lib
+ *
+ * @{
+ */
+
+#include <linux/libcfs/libcfs.h>
+#include <lustre/lustre_idl.h>
+#include <lustre_ver.h>
+#include <lustre_cfg.h>
+#include <linux/lustre_lib.h>
+
+/* target.c */
+struct ptlrpc_request;
+struct obd_export;
+struct lu_target;
+struct l_wait_info;
+#include <lustre_ha.h>
+#include <lustre_net.h>
+#include <lvfs.h>
+
+
+int target_pack_pool_reply(struct ptlrpc_request *req);
+int do_set_info_async(struct obd_import *imp,
+		      int opcode, int version,
+		      obd_count keylen, void *key,
+		      obd_count vallen, void *val,
+		      struct ptlrpc_request_set *set);
+
+#define OBD_RECOVERY_MAX_TIME (obd_timeout * 18) /* b13079 */
+#define OBD_MAX_IOCTL_BUFFER CONFIG_LUSTRE_OBD_MAX_IOCTL_BUFFER
+
+void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id);
+
+/* client.c */
+
+int client_sanobd_setup(struct obd_device *obddev, struct lustre_cfg* lcfg);
+struct client_obd *client_conn2cli(struct lustre_handle *conn);
+
+struct md_open_data;
+struct obd_client_handle {
+	struct lustre_handle  och_fh;
+	struct lu_fid	 och_fid;
+	struct md_open_data  *och_mod;
+	__u32 och_magic;
+	int och_flags;
+};
+#define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed
+
+/* statfs_pack.c */
+void statfs_pack(struct obd_statfs *osfs, struct kstatfs *sfs);
+void statfs_unpack(struct kstatfs *sfs, struct obd_statfs *osfs);
+
+/* l_lock.c */
+struct lustre_lock {
+	int			l_depth;
+	task_t		*l_owner;
+	struct semaphore	l_sem;
+	spinlock_t		l_spin;
+};
+
+void l_lock_init(struct lustre_lock *);
+void l_lock(struct lustre_lock *);
+void l_unlock(struct lustre_lock *);
+int l_has_lock(struct lustre_lock *);
+
+/*
+ * For md echo client
+ */
+enum md_echo_cmd {
+	ECHO_MD_CREATE       = 1, /* Open/Create file on MDT */
+	ECHO_MD_MKDIR	= 2, /* Mkdir on MDT */
+	ECHO_MD_DESTROY      = 3, /* Unlink file on MDT */
+	ECHO_MD_RMDIR	= 4, /* Rmdir on MDT */
+	ECHO_MD_LOOKUP       = 5, /* Lookup on MDT */
+	ECHO_MD_GETATTR      = 6, /* Getattr on MDT */
+	ECHO_MD_SETATTR      = 7, /* Setattr on MDT */
+	ECHO_MD_ALLOC_FID    = 8, /* Get FIDs from MDT */
+};
+
+/*
+ *   OBD IOCTLS
+ */
+#define OBD_IOCTL_VERSION 0x00010004
+
+struct obd_ioctl_data {
+	__u32 ioc_len;
+	__u32 ioc_version;
+
+	union {
+		__u64 ioc_cookie;
+		__u64 ioc_u64_1;
+	};
+	union {
+		__u32 ioc_conn1;
+		__u32 ioc_u32_1;
+	};
+	union {
+		__u32 ioc_conn2;
+		__u32 ioc_u32_2;
+	};
+
+	struct obdo ioc_obdo1;
+	struct obdo ioc_obdo2;
+
+	obd_size ioc_count;
+	obd_off  ioc_offset;
+	__u32    ioc_dev;
+	__u32    ioc_command;
+
+	__u64 ioc_nid;
+	__u32 ioc_nal;
+	__u32 ioc_type;
+
+	/* buffers the kernel will treat as user pointers */
+	__u32  ioc_plen1;
+	char  *ioc_pbuf1;
+	__u32  ioc_plen2;
+	char  *ioc_pbuf2;
+
+	/* inline buffers for various arguments */
+	__u32  ioc_inllen1;
+	char  *ioc_inlbuf1;
+	__u32  ioc_inllen2;
+	char  *ioc_inlbuf2;
+	__u32  ioc_inllen3;
+	char  *ioc_inlbuf3;
+	__u32  ioc_inllen4;
+	char  *ioc_inlbuf4;
+
+	char    ioc_bulk[0];
+};
+
+struct obd_ioctl_hdr {
+	__u32 ioc_len;
+	__u32 ioc_version;
+};
+
+static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)
+{
+	int len = cfs_size_round(sizeof(struct obd_ioctl_data));
+	len += cfs_size_round(data->ioc_inllen1);
+	len += cfs_size_round(data->ioc_inllen2);
+	len += cfs_size_round(data->ioc_inllen3);
+	len += cfs_size_round(data->ioc_inllen4);
+	return len;
+}
+
+
+static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
+{
+	if (data->ioc_len > (1<<30)) {
+		CERROR("OBD ioctl: ioc_len larger than 1<<30\n");
+		return 1;
+	}
+	if (data->ioc_inllen1 > (1<<30)) {
+		CERROR("OBD ioctl: ioc_inllen1 larger than 1<<30\n");
+		return 1;
+	}
+	if (data->ioc_inllen2 > (1<<30)) {
+		CERROR("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
+		return 1;
+	}
+	if (data->ioc_inllen3 > (1<<30)) {
+		CERROR("OBD ioctl: ioc_inllen3 larger than 1<<30\n");
+		return 1;
+	}
+	if (data->ioc_inllen4 > (1<<30)) {
+		CERROR("OBD ioctl: ioc_inllen4 larger than 1<<30\n");
+		return 1;
+	}
+	if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
+		CERROR("OBD ioctl: inlbuf1 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
+		CERROR("OBD ioctl: inlbuf2 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_inlbuf3 && !data->ioc_inllen3) {
+		CERROR("OBD ioctl: inlbuf3 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_inlbuf4 && !data->ioc_inllen4) {
+		CERROR("OBD ioctl: inlbuf4 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_pbuf1 && !data->ioc_plen1) {
+		CERROR("OBD ioctl: pbuf1 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_pbuf2 && !data->ioc_plen2) {
+		CERROR("OBD ioctl: pbuf2 pointer but 0 length\n");
+		return 1;
+	}
+	if (data->ioc_plen1 && !data->ioc_pbuf1) {
+		CERROR("OBD ioctl: plen1 set but NULL pointer\n");
+		return 1;
+	}
+	if (data->ioc_plen2 && !data->ioc_pbuf2) {
+		CERROR("OBD ioctl: plen2 set but NULL pointer\n");
+		return 1;
+	}
+	if (obd_ioctl_packlen(data) > data->ioc_len) {
+		CERROR("OBD ioctl: packlen exceeds ioc_len (%d > %d)\n",
+		       obd_ioctl_packlen(data), data->ioc_len);
+		return 1;
+	}
+	return 0;
+}
+
+
+#include <obd_support.h>
+
+/* function defined in lustre/obdclass/<platform>/<platform>-module.c */
+int obd_ioctl_getdata(char **buf, int *len, void *arg);
+int obd_ioctl_popdata(void *arg, void *data, int len);
+
+static inline void obd_ioctl_freedata(char *buf, int len)
+{
+	ENTRY;
+
+	OBD_FREE_LARGE(buf, len);
+	EXIT;
+	return;
+}
+
+/*
+ * BSD ioctl description:
+ * #define IOC_V1       _IOR(g, n1, long)
+ * #define IOC_V2       _IOW(g, n2, long)
+ *
+ * ioctl(f, IOC_V1, arg);
+ * arg will be treated as a long value,
+ *
+ * ioctl(f, IOC_V2, arg)
+ * arg will be treated as a pointer, bsd will call
+ * copyin(buf, arg, sizeof(long))
+ *
+ * To make BSD ioctl handles argument correctly and simplely,
+ * we change _IOR to _IOWR so BSD will copyin obd_ioctl_data
+ * for us. Does this change affect Linux?  (XXX Liang)
+ */
+#define OBD_IOC_CREATE		 _IOWR('f', 101, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_DESTROY		_IOW ('f', 104, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_PREALLOCATE	    _IOWR('f', 105, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_SETATTR		_IOW ('f', 107, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_GETATTR		_IOWR ('f', 108, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_READ		   _IOWR('f', 109, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_WRITE		  _IOWR('f', 110, OBD_IOC_DATA_TYPE)
+
+
+#define OBD_IOC_STATFS		 _IOWR('f', 113, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_SYNC		   _IOW ('f', 114, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_READ2		  _IOWR('f', 115, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_FORMAT		 _IOWR('f', 116, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_PARTITION	      _IOWR('f', 117, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_COPY		   _IOWR('f', 120, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_MIGR		   _IOWR('f', 121, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_PUNCH		  _IOWR('f', 122, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_MODULE_DEBUG	   _IOWR('f', 124, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_BRW_READ	       _IOWR('f', 125, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_BRW_WRITE	      _IOWR('f', 126, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_NAME2DEV	       _IOWR('f', 127, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_UUID2DEV	       _IOWR('f', 130, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_GETNAME		_IOWR('f', 131, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_GETMDNAME	      _IOR('f', 131, char[MAX_OBD_NAME])
+#define OBD_IOC_GETDTNAME	       OBD_IOC_GETNAME
+
+#define OBD_IOC_LOV_GET_CONFIG	 _IOWR('f', 132, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_CLIENT_RECOVER	 _IOW ('f', 133, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_PING_TARGET	    _IOW ('f', 136, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_DEC_FS_USE_COUNT       _IO  ('f', 139      )
+#define OBD_IOC_NO_TRANSNO	     _IOW ('f', 140, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_SET_READONLY	   _IOW ('f', 141, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_ABORT_RECOVERY	 _IOR ('f', 142, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_ROOT_SQUASH	    _IOWR('f', 143, OBD_IOC_DATA_TYPE)
+
+#define OBD_GET_VERSION		_IOWR ('f', 144, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_GSS_SUPPORT	    _IOWR('f', 145, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_CLOSE_UUID	     _IOWR ('f', 147, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_CHANGELOG_SEND	 _IOW ('f', 148, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_GETDEVICE	      _IOWR ('f', 149, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_FID2PATH	       _IOWR ('f', 150, OBD_IOC_DATA_TYPE)
+/* see also <lustre/lustre_user.h> for ioctls 151-153 */
+/* OBD_IOC_LOV_SETSTRIPE: See also LL_IOC_LOV_SETSTRIPE */
+#define OBD_IOC_LOV_SETSTRIPE	  _IOW ('f', 154, OBD_IOC_DATA_TYPE)
+/* OBD_IOC_LOV_GETSTRIPE: See also LL_IOC_LOV_GETSTRIPE */
+#define OBD_IOC_LOV_GETSTRIPE	  _IOW ('f', 155, OBD_IOC_DATA_TYPE)
+/* OBD_IOC_LOV_SETEA: See also LL_IOC_LOV_SETEA */
+#define OBD_IOC_LOV_SETEA	      _IOW ('f', 156, OBD_IOC_DATA_TYPE)
+/* see <lustre/lustre_user.h> for ioctls 157-159 */
+/* OBD_IOC_QUOTACHECK: See also LL_IOC_QUOTACHECK */
+#define OBD_IOC_QUOTACHECK	     _IOW ('f', 160, int)
+/* OBD_IOC_POLL_QUOTACHECK: See also LL_IOC_POLL_QUOTACHECK */
+#define OBD_IOC_POLL_QUOTACHECK	_IOR ('f', 161, struct if_quotacheck *)
+/* OBD_IOC_QUOTACTL: See also LL_IOC_QUOTACTL */
+#define OBD_IOC_QUOTACTL	       _IOWR('f', 162, struct if_quotactl)
+/* see  also <lustre/lustre_user.h> for ioctls 163-176 */
+#define OBD_IOC_CHANGELOG_REG	  _IOW ('f', 177, struct obd_ioctl_data)
+#define OBD_IOC_CHANGELOG_DEREG	_IOW ('f', 178, struct obd_ioctl_data)
+#define OBD_IOC_CHANGELOG_CLEAR	_IOW ('f', 179, struct obd_ioctl_data)
+#define OBD_IOC_RECORD		 _IOWR('f', 180, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_ENDRECORD	      _IOWR('f', 181, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_PARSE		  _IOWR('f', 182, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_DORECORD	       _IOWR('f', 183, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_PROCESS_CFG	    _IOWR('f', 184, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_DUMP_LOG	       _IOWR('f', 185, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_CLEAR_LOG	      _IOWR('f', 186, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_PARAM		  _IOW ('f', 187, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_POOL		   _IOWR('f', 188, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_REPLACE_NIDS	   _IOWR('f', 189, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_CATLOGLIST	     _IOWR('f', 190, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_INFO	      _IOWR('f', 191, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_PRINT	     _IOWR('f', 192, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_CANCEL	    _IOWR('f', 193, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_REMOVE	    _IOWR('f', 194, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_LLOG_CHECK	     _IOWR('f', 195, OBD_IOC_DATA_TYPE)
+/* OBD_IOC_LLOG_CATINFO is deprecated */
+#define OBD_IOC_LLOG_CATINFO	   _IOWR('f', 196, OBD_IOC_DATA_TYPE)
+
+#define ECHO_IOC_GET_STRIPE	    _IOWR('f', 200, OBD_IOC_DATA_TYPE)
+#define ECHO_IOC_SET_STRIPE	    _IOWR('f', 201, OBD_IOC_DATA_TYPE)
+#define ECHO_IOC_ENQUEUE	       _IOWR('f', 202, OBD_IOC_DATA_TYPE)
+#define ECHO_IOC_CANCEL		_IOWR('f', 203, OBD_IOC_DATA_TYPE)
+
+#define OBD_IOC_GET_OBJ_VERSION	_IOR('f', 210, OBD_IOC_DATA_TYPE)
+
+/* <lustre/lustre_user.h> defines ioctl number 218-219 */
+#define OBD_IOC_GET_MNTOPT	     _IOW('f', 220, mntopt_t)
+
+#define OBD_IOC_ECHO_MD		_IOR('f', 221, struct obd_ioctl_data)
+#define OBD_IOC_ECHO_ALLOC_SEQ	 _IOWR('f', 222, struct obd_ioctl_data)
+
+#define OBD_IOC_START_LFSCK	       _IOWR('f', 230, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_STOP_LFSCK	       _IOW('f', 231, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_PAUSE_LFSCK	       _IOW('f', 232, OBD_IOC_DATA_TYPE)
+
+/* XXX _IOWR('f', 250, long) has been defined in
+ * libcfs/include/libcfs/libcfs_private.h for debug, don't use it
+ */
+
+/* Until such time as we get_info the per-stripe maximum from the OST,
+ * we define this to be 2T - 4k, which is the ext3 maxbytes. */
+#define LUSTRE_STRIPE_MAXBYTES 0x1fffffff000ULL
+
+/* Special values for remove LOV EA from disk */
+#define LOVEA_DELETE_VALUES(size, count, offset) (size == 0 && count == 0 && \
+						 offset == (typeof(offset))(-1))
+
+/* #define POISON_BULK 0 */
+
+/*
+ * l_wait_event is a flexible sleeping function, permitting simple caller
+ * configuration of interrupt and timeout sensitivity along with actions to
+ * be performed in the event of either exception.
+ *
+ * The first form of usage looks like this:
+ *
+ * struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout, timeout_handler,
+ *					   intr_handler, callback_data);
+ * rc = l_wait_event(waitq, condition, &lwi);
+ *
+ * l_wait_event() makes the current process wait on 'waitq' until 'condition'
+ * is TRUE or a "killable" signal (SIGTERM, SIKGILL, SIGINT) is pending.  It
+ * returns 0 to signify 'condition' is TRUE, but if a signal wakes it before
+ * 'condition' becomes true, it optionally calls the specified 'intr_handler'
+ * if not NULL, and returns -EINTR.
+ *
+ * If a non-zero timeout is specified, signals are ignored until the timeout
+ * has expired.  At this time, if 'timeout_handler' is not NULL it is called.
+ * If it returns FALSE l_wait_event() continues to wait as described above with
+ * signals enabled.  Otherwise it returns -ETIMEDOUT.
+ *
+ * LWI_INTR(intr_handler, callback_data) is shorthand for
+ * LWI_TIMEOUT_INTR(0, NULL, intr_handler, callback_data)
+ *
+ * The second form of usage looks like this:
+ *
+ * struct l_wait_info lwi = LWI_TIMEOUT(timeout, timeout_handler);
+ * rc = l_wait_event(waitq, condition, &lwi);
+ *
+ * This form is the same as the first except that it COMPLETELY IGNORES
+ * SIGNALS.  The caller must therefore beware that if 'timeout' is zero, or if
+ * 'timeout_handler' is not NULL and returns FALSE, then the ONLY thing that
+ * can unblock the current process is 'condition' becoming TRUE.
+ *
+ * Another form of usage is:
+ * struct l_wait_info lwi = LWI_TIMEOUT_INTERVAL(timeout, interval,
+ *					       timeout_handler);
+ * rc = l_wait_event(waitq, condition, &lwi);
+ * This is the same as previous case, but condition is checked once every
+ * 'interval' jiffies (if non-zero).
+ *
+ * Subtle synchronization point: this macro does *not* necessary takes
+ * wait-queue spin-lock before returning, and, hence, following idiom is safe
+ * ONLY when caller provides some external locking:
+ *
+ *	     Thread1			    Thread2
+ *
+ *   l_wait_event(&obj->wq, ....);				       (1)
+ *
+ *				    wake_up(&obj->wq):		 (2)
+ *					 spin_lock(&q->lock);	  (2.1)
+ *					 __wake_up_common(q, ...);     (2.2)
+ *					 spin_unlock(&q->lock, flags); (2.3)
+ *
+ *   OBD_FREE_PTR(obj);						  (3)
+ *
+ * As l_wait_event() may "short-cut" execution and return without taking
+ * wait-queue spin-lock, some additional synchronization is necessary to
+ * guarantee that step (3) can begin only after (2.3) finishes.
+ *
+ * XXX nikita: some ptlrpc daemon threads have races of that sort.
+ *
+ */
+static inline int back_to_sleep(void *arg)
+{
+	return 0;
+}
+
+#define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
+
+struct l_wait_info {
+	cfs_duration_t lwi_timeout;
+	cfs_duration_t lwi_interval;
+	int	    lwi_allow_intr;
+	int  (*lwi_on_timeout)(void *);
+	void (*lwi_on_signal)(void *);
+	void  *lwi_cb_data;
+};
+
+/* NB: LWI_TIMEOUT ignores signals completely */
+#define LWI_TIMEOUT(time, cb, data)	     \
+((struct l_wait_info) {			 \
+	.lwi_timeout    = time,		 \
+	.lwi_on_timeout = cb,		   \
+	.lwi_cb_data    = data,		 \
+	.lwi_interval   = 0,		    \
+	.lwi_allow_intr = 0		     \
+})
+
+#define LWI_TIMEOUT_INTERVAL(time, interval, cb, data)  \
+((struct l_wait_info) {				 \
+	.lwi_timeout    = time,			 \
+	.lwi_on_timeout = cb,			   \
+	.lwi_cb_data    = data,			 \
+	.lwi_interval   = interval,		     \
+	.lwi_allow_intr = 0			     \
+})
+
+#define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data)   \
+((struct l_wait_info) {				 \
+	.lwi_timeout    = time,			 \
+	.lwi_on_timeout = time_cb,		      \
+	.lwi_on_signal  = sig_cb,		       \
+	.lwi_cb_data    = data,			 \
+	.lwi_interval   = 0,			    \
+	.lwi_allow_intr = 0			     \
+})
+
+#define LWI_TIMEOUT_INTR_ALL(time, time_cb, sig_cb, data)       \
+((struct l_wait_info) {					 \
+	.lwi_timeout    = time,				 \
+	.lwi_on_timeout = time_cb,			      \
+	.lwi_on_signal  = sig_cb,			       \
+	.lwi_cb_data    = data,				 \
+	.lwi_interval   = 0,				    \
+	.lwi_allow_intr = 1				     \
+})
+
+#define LWI_INTR(cb, data)  LWI_TIMEOUT_INTR(0, NULL, cb, data)
+
+
+/*
+ * wait for @condition to become true, but no longer than timeout, specified
+ * by @info.
+ */
+#define __l_wait_event(wq, condition, info, ret, l_add_wait)		   \
+do {									   \
+	wait_queue_t __wait;						 \
+	cfs_duration_t __timeout = info->lwi_timeout;			  \
+	sigset_t   __blocked;					      \
+	int   __allow_intr = info->lwi_allow_intr;			     \
+									       \
+	ret = 0;							       \
+	if (condition)							 \
+		break;							 \
+									       \
+	init_waitqueue_entry_current(&__wait);					    \
+	l_add_wait(&wq, &__wait);					      \
+									       \
+	/* Block all signals (just the non-fatal ones if no timeout). */       \
+	if (info->lwi_on_signal != NULL && (__timeout == 0 || __allow_intr))   \
+		__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);	      \
+	else								   \
+		__blocked = cfs_block_sigsinv(0);			      \
+									       \
+	for (;;) {							     \
+		unsigned       __wstate;				       \
+									       \
+		__wstate = info->lwi_on_signal != NULL &&		      \
+			   (__timeout == 0 || __allow_intr) ?		  \
+			TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;	       \
+									       \
+		set_current_state(TASK_INTERRUPTIBLE);		 \
+									       \
+		if (condition)						 \
+			break;						 \
+									       \
+		if (__timeout == 0) {					  \
+			waitq_wait(&__wait, __wstate);		     \
+		} else {						       \
+			cfs_duration_t interval = info->lwi_interval?	  \
+					     min_t(cfs_duration_t,	     \
+						 info->lwi_interval,__timeout):\
+					     __timeout;			\
+			cfs_duration_t remaining = waitq_timedwait(&__wait,\
+						   __wstate,		   \
+						   interval);		  \
+			__timeout = cfs_time_sub(__timeout,		    \
+					    cfs_time_sub(interval, remaining));\
+			if (__timeout == 0) {				  \
+				if (info->lwi_on_timeout == NULL ||	    \
+				    info->lwi_on_timeout(info->lwi_cb_data)) { \
+					ret = -ETIMEDOUT;		      \
+					break;				 \
+				}					      \
+				/* Take signals after the timeout expires. */  \
+				if (info->lwi_on_signal != NULL)	       \
+				    (void)cfs_block_sigsinv(LUSTRE_FATAL_SIGS);\
+			}						      \
+		}							      \
+									       \
+		if (condition)						 \
+			break;						 \
+		if (cfs_signal_pending()) {				    \
+			if (info->lwi_on_signal != NULL &&		     \
+			    (__timeout == 0 || __allow_intr)) {		\
+				if (info->lwi_on_signal != LWI_ON_SIGNAL_NOOP) \
+					info->lwi_on_signal(info->lwi_cb_data);\
+				ret = -EINTR;				  \
+				break;					 \
+			}						      \
+			/* We have to do this here because some signals */     \
+			/* are not blockable - ie from strace(1).       */     \
+			/* In these cases we want to schedule_timeout() */     \
+			/* again, because we don't want that to return  */     \
+			/* -EINTR when the RPC actually succeeded.      */     \
+			/* the recalc_sigpending() below will deliver the */     \
+			/* signal properly.			     */     \
+			cfs_clear_sigpending();				\
+		}							      \
+	}								      \
+									       \
+	cfs_restore_sigs(__blocked);					   \
+									       \
+	set_current_state(TASK_RUNNING);			       \
+	remove_wait_queue(&wq, &__wait);					   \
+} while (0)
+
+
+
+#define l_wait_event(wq, condition, info)		       \
+({							      \
+	int		 __ret;			      \
+	struct l_wait_info *__info = (info);		    \
+								\
+	__l_wait_event(wq, condition, __info,		   \
+		       __ret, add_wait_queue);		   \
+	__ret;						  \
+})
+
+#define l_wait_event_exclusive(wq, condition, info)	     \
+({							      \
+	int		 __ret;			      \
+	struct l_wait_info *__info = (info);		    \
+								\
+	__l_wait_event(wq, condition, __info,		   \
+		       __ret, add_wait_queue_exclusive);	 \
+	__ret;						  \
+})
+
+#define l_wait_event_exclusive_head(wq, condition, info)	\
+({							      \
+	int		 __ret;			      \
+	struct l_wait_info *__info = (info);		    \
+								\
+	__l_wait_event(wq, condition, __info,		   \
+		       __ret, add_wait_queue_exclusive_head);    \
+	__ret;						  \
+})
+
+#define l_wait_condition(wq, condition)			 \
+({							      \
+	struct l_wait_info lwi = { 0 };			 \
+	l_wait_event(wq, condition, &lwi);		      \
+})
+
+#define l_wait_condition_exclusive(wq, condition)	       \
+({							      \
+	struct l_wait_info lwi = { 0 };			 \
+	l_wait_event_exclusive(wq, condition, &lwi);	    \
+})
+
+#define l_wait_condition_exclusive_head(wq, condition)	  \
+({							      \
+	struct l_wait_info lwi = { 0 };			 \
+	l_wait_event_exclusive_head(wq, condition, &lwi);       \
+})
+
+#define LIBLUSTRE_CLIENT (0)
+
+/** @} lib */
+
+#endif /* _LUSTRE_LIB_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_linkea.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_linkea.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_linkea.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_linkea.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2013, Intel Corporation.
+ * Use is subject to license terms.
+ *
+ * Author: di wang <di.wang@intel.com>
+ */
+
+struct linkea_data {
+	/**
+	 * Buffer to keep link EA body.
+	 */
+	struct lu_buf		*ld_buf;
+	/**
+	 * The matched header, entry and its lenght in the EA
+	 */
+	struct link_ea_header	*ld_leh;
+	struct link_ea_entry	*ld_lee;
+	int			ld_reclen;
+};
+
+int linkea_data_new(struct linkea_data *ldata, struct lu_buf *buf);
+int linkea_init(struct linkea_data *ldata);
+void linkea_entry_unpack(const struct link_ea_entry *lee, int *reclen,
+			 struct lu_name *lname, struct lu_fid *pfid);
+int linkea_add_buf(struct linkea_data *ldata, const struct lu_name *lname,
+		   const struct lu_fid *pfid);
+void linkea_del_buf(struct linkea_data *ldata, const struct lu_name *lname);
+int linkea_links_find(struct linkea_data *ldata, const struct lu_name *lname,
+		      const struct lu_fid  *pfid);
+
+#define LINKEA_NEXT_ENTRY(ldata)	\
+	(struct link_ea_entry *)((char *)ldata.ld_lee + ldata.ld_reclen)
+
+#define LINKEA_FIRST_ENTRY(ldata)	\
+	(struct link_ea_entry *)(ldata.ld_leh + 1)
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_lite.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_lite.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_lite.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_lite.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,147 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LL_H
+#define _LL_H
+
+/** \defgroup lite lite
+ *
+ * @{
+ */
+
+#include <linux/lustre_lite.h>
+
+#include <obd_class.h>
+#include <obd_ost.h>
+#include <lustre_net.h>
+#include <lustre_mds.h>
+#include <lustre_ha.h>
+
+/* 4UL * 1024 * 1024 */
+#define LL_MAX_BLKSIZE_BITS     (22)
+#define LL_MAX_BLKSIZE	  (1UL<<LL_MAX_BLKSIZE_BITS)
+
+#include <lustre/lustre_user.h>
+
+
+struct lustre_rw_params {
+	int		lrp_lock_mode;
+	ldlm_policy_data_t lrp_policy;
+	obd_flag	   lrp_brw_flags;
+	int		lrp_ast_flags;
+};
+
+/*
+ * XXX nikita: this function lives in the header because it is used by both
+ * llite kernel module and liblustre library, and there is no (?) better place
+ * to put it in.
+ */
+static inline void lustre_build_lock_params(int cmd, unsigned long open_flags,
+					    __u64 connect_flags,
+					    loff_t pos, ssize_t len,
+					    struct lustre_rw_params *params)
+{
+	params->lrp_lock_mode = (cmd == OBD_BRW_READ) ? LCK_PR : LCK_PW;
+	params->lrp_brw_flags = 0;
+
+	params->lrp_policy.l_extent.start = pos;
+	params->lrp_policy.l_extent.end = pos + len - 1;
+	/*
+	 * for now O_APPEND always takes local locks.
+	 */
+	if (cmd == OBD_BRW_WRITE && (open_flags & O_APPEND)) {
+		params->lrp_policy.l_extent.start = 0;
+		params->lrp_policy.l_extent.end   = OBD_OBJECT_EOF;
+	} else if (LIBLUSTRE_CLIENT && (connect_flags & OBD_CONNECT_SRVLOCK)) {
+		/*
+		 * liblustre: OST-side locking for all non-O_APPEND
+		 * reads/writes.
+		 */
+		params->lrp_lock_mode = LCK_NL;
+		params->lrp_brw_flags = OBD_BRW_SRVLOCK;
+	} else {
+		/*
+		 * nothing special for the kernel. In the future llite may use
+		 * OST-side locks for small writes into highly contended
+		 * files.
+		 */
+	}
+	params->lrp_ast_flags = (open_flags & O_NONBLOCK) ?
+		LDLM_FL_BLOCK_NOWAIT : 0;
+}
+
+/*
+ * This is embedded into liblustre and llite super-blocks to keep track of
+ * connect flags (capabilities) supported by all imports given mount is
+ * connected to.
+ */
+struct lustre_client_ocd {
+	/*
+	 * This is conjunction of connect_flags across all imports (LOVs) this
+	 * mount is connected to. This field is updated by cl_ocd_update()
+	 * under ->lco_lock.
+	 */
+	__u64	      lco_flags;
+	struct mutex	   lco_lock;
+	struct obd_export *lco_md_exp;
+	struct obd_export *lco_dt_exp;
+};
+
+/*
+ * Chain of hash overflow pages.
+ */
+struct ll_dir_chain {
+	/* XXX something. Later */
+};
+
+static inline void ll_dir_chain_init(struct ll_dir_chain *chain)
+{
+}
+
+static inline void ll_dir_chain_fini(struct ll_dir_chain *chain)
+{
+}
+
+static inline unsigned long hash_x_index(__u64 hash, int hash64)
+{
+	if (BITS_PER_LONG == 32 && hash64)
+		hash >>= 32;
+	return ~0UL - hash;
+}
+
+/** @} lite */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_log.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_log.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_log.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_log.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,576 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_log.h
+ *
+ * Generic infrastructure for managing a collection of logs.
+ * These logs are used for:
+ *
+ * - orphan recovery: OST adds record on create
+ * - mtime/size consistency: the OST adds a record on first write
+ * - open/unlinked objects: OST adds a record on destroy
+ *
+ * - mds unlink log: the MDS adds an entry upon delete
+ *
+ * - raid1 replication log between OST's
+ * - MDS replication logs
+ */
+
+#ifndef _LUSTRE_LOG_H
+#define _LUSTRE_LOG_H
+
+/** \defgroup log log
+ *
+ * @{
+ */
+
+#include <linux/lustre_log.h>
+
+#include <obd_class.h>
+#include <obd_ost.h>
+#include <lustre/lustre_idl.h>
+#include <dt_object.h>
+
+#define LOG_NAME_LIMIT(logname, name)		   \
+	snprintf(logname, sizeof(logname), "LOGS/%s", name)
+#define LLOG_EEMPTY 4711
+
+enum llog_open_param {
+	LLOG_OPEN_EXISTS	= 0x0000,
+	LLOG_OPEN_NEW		= 0x0001,
+};
+
+struct plain_handle_data {
+	struct list_head	  phd_entry;
+	struct llog_handle *phd_cat_handle;
+	struct llog_cookie  phd_cookie; /* cookie of this log in its cat */
+};
+
+struct cat_handle_data {
+	struct list_head	      chd_head;
+	struct llog_handle     *chd_current_log; /* currently open log */
+	struct llog_handle	*chd_next_log; /* llog to be used next */
+};
+
+static inline void logid_to_fid(struct llog_logid *id, struct lu_fid *fid)
+{
+	/* For compatibility purposes we identify pre-OSD (~< 2.3.51 MDS)
+	 * logid's by non-zero ogen (inode generation) and convert them
+	 * into IGIF */
+	if (id->lgl_ogen == 0) {
+		fid->f_seq = id->lgl_oi.oi.oi_seq;
+		fid->f_oid = id->lgl_oi.oi.oi_id;
+		fid->f_ver = 0;
+	} else {
+		lu_igif_build(fid, id->lgl_oi.oi.oi_id, id->lgl_ogen);
+	}
+}
+
+static inline void fid_to_logid(struct lu_fid *fid, struct llog_logid *id)
+{
+	id->lgl_oi.oi.oi_seq = fid->f_seq;
+	id->lgl_oi.oi.oi_id = fid->f_oid;
+	id->lgl_ogen = 0;
+}
+
+static inline void logid_set_id(struct llog_logid *log_id, __u64 id)
+{
+	log_id->lgl_oi.oi.oi_id = id;
+}
+
+static inline __u64 logid_id(struct llog_logid *log_id)
+{
+	return log_id->lgl_oi.oi.oi_id;
+}
+
+struct llog_handle;
+
+/* llog.c  -  general API */
+int llog_init_handle(const struct lu_env *env, struct llog_handle *handle,
+		     int flags, struct obd_uuid *uuid);
+int llog_copy_handler(const struct lu_env *env, struct llog_handle *llh,
+		      struct llog_rec_hdr *rec, void *data);
+int llog_process(const struct lu_env *env, struct llog_handle *loghandle,
+		 llog_cb_t cb, void *data, void *catdata);
+int llog_process_or_fork(const struct lu_env *env,
+			 struct llog_handle *loghandle,
+			 llog_cb_t cb, void *data, void *catdata, bool fork);
+int llog_reverse_process(const struct lu_env *env,
+			 struct llog_handle *loghandle, llog_cb_t cb,
+			 void *data, void *catdata);
+int llog_cancel_rec(const struct lu_env *env, struct llog_handle *loghandle,
+		    int index);
+int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt,
+	      struct llog_handle **lgh, struct llog_logid *logid,
+	      char *name, enum llog_open_param open_param);
+int llog_close(const struct lu_env *env, struct llog_handle *cathandle);
+int llog_get_size(struct llog_handle *loghandle);
+
+/* llog_process flags */
+#define LLOG_FLAG_NODEAMON 0x0001
+
+/* llog_cat.c - catalog api */
+struct llog_process_data {
+	/**
+	 * Any useful data needed while processing catalog. This is
+	 * passed later to process callback.
+	 */
+	void		*lpd_data;
+	/**
+	 * Catalog process callback function, called for each record
+	 * in catalog.
+	 */
+	llog_cb_t	    lpd_cb;
+	/**
+	 * Start processing the catalog from startcat/startidx
+	 */
+	int		  lpd_startcat;
+	int		  lpd_startidx;
+};
+
+struct llog_process_cat_data {
+	/**
+	 * Temporary stored first_idx while scanning log.
+	 */
+	int		  lpcd_first_idx;
+	/**
+	 * Temporary stored last_idx while scanning log.
+	 */
+	int		  lpcd_last_idx;
+};
+
+int llog_cat_close(const struct lu_env *env, struct llog_handle *cathandle);
+int llog_cat_add_rec(const struct lu_env *env, struct llog_handle *cathandle,
+		     struct llog_rec_hdr *rec, struct llog_cookie *reccookie,
+		     void *buf, struct thandle *th);
+int llog_cat_declare_add_rec(const struct lu_env *env,
+			     struct llog_handle *cathandle,
+			     struct llog_rec_hdr *rec, struct thandle *th);
+int llog_cat_add(const struct lu_env *env, struct llog_handle *cathandle,
+		 struct llog_rec_hdr *rec, struct llog_cookie *reccookie,
+		 void *buf);
+int llog_cat_cancel_records(const struct lu_env *env,
+			    struct llog_handle *cathandle, int count,
+			    struct llog_cookie *cookies);
+int llog_cat_process_or_fork(const struct lu_env *env,
+			     struct llog_handle *cat_llh, llog_cb_t cb,
+			     void *data, int startcat, int startidx, bool fork);
+int llog_cat_process(const struct lu_env *env, struct llog_handle *cat_llh,
+		     llog_cb_t cb, void *data, int startcat, int startidx);
+int llog_cat_reverse_process(const struct lu_env *env,
+			     struct llog_handle *cat_llh, llog_cb_t cb,
+			     void *data);
+int llog_cat_init_and_process(const struct lu_env *env,
+			      struct llog_handle *llh);
+
+/* llog_obd.c */
+int llog_setup(const struct lu_env *env, struct obd_device *obd,
+	       struct obd_llog_group *olg, int index,
+	       struct obd_device *disk_obd, struct llog_operations *op);
+int __llog_ctxt_put(const struct lu_env *env, struct llog_ctxt *ctxt);
+int llog_cleanup(const struct lu_env *env, struct llog_ctxt *);
+int llog_sync(struct llog_ctxt *ctxt, struct obd_export *exp, int flags);
+int llog_obd_add(const struct lu_env *env, struct llog_ctxt *ctxt,
+		 struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
+		 struct llog_cookie *logcookies, int numcookies);
+int llog_cancel(const struct lu_env *env, struct llog_ctxt *ctxt,
+		struct lov_stripe_md *lsm, int count,
+		struct llog_cookie *cookies, int flags);
+
+int obd_llog_init(struct obd_device *obd, struct obd_llog_group *olg,
+		  struct obd_device *disk_obd, int *idx);
+
+int obd_llog_finish(struct obd_device *obd, int count);
+
+/* llog_ioctl.c */
+int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt, int cmd,
+	       struct obd_ioctl_data *data);
+
+/* llog_net.c */
+int llog_initiator_connect(struct llog_ctxt *ctxt);
+
+struct llog_operations {
+	int (*lop_destroy)(const struct lu_env *env,
+			   struct llog_handle *handle);
+	int (*lop_next_block)(const struct lu_env *env, struct llog_handle *h,
+			      int *curr_idx, int next_idx, __u64 *offset,
+			      void *buf, int len);
+	int (*lop_prev_block)(const struct lu_env *env, struct llog_handle *h,
+			      int prev_idx, void *buf, int len);
+	int (*lop_read_header)(const struct lu_env *env,
+			       struct llog_handle *handle);
+	int (*lop_setup)(const struct lu_env *env, struct obd_device *obd,
+			 struct obd_llog_group *olg, int ctxt_idx,
+			 struct obd_device *disk_obd);
+	int (*lop_sync)(struct llog_ctxt *ctxt, struct obd_export *exp,
+			int flags);
+	int (*lop_cleanup)(const struct lu_env *env, struct llog_ctxt *ctxt);
+	int (*lop_cancel)(const struct lu_env *env, struct llog_ctxt *ctxt,
+			  struct lov_stripe_md *lsm, int count,
+			  struct llog_cookie *cookies, int flags);
+	int (*lop_connect)(struct llog_ctxt *ctxt, struct llog_logid *logid,
+			   struct llog_gen *gen, struct obd_uuid *uuid);
+	/**
+	 * Any llog file must be opened first using llog_open().  Llog can be
+	 * opened by name, logid or without both, in last case the new logid
+	 * will be generated.
+	 */
+	int (*lop_open)(const struct lu_env *env, struct llog_handle *lgh,
+			struct llog_logid *logid, char *name,
+			enum llog_open_param);
+	/**
+	 * Opened llog may not exist and this must be checked where needed using
+	 * the llog_exist() call.
+	 */
+	int (*lop_exist)(struct llog_handle *lgh);
+	/**
+	 * Close llog file and calls llog_free_handle() implicitly.
+	 * Any opened llog must be closed by llog_close() call.
+	 */
+	int (*lop_close)(const struct lu_env *env, struct llog_handle *handle);
+	/**
+	 * Create new llog file. The llog must be opened.
+	 * Must be used only for local llog operations.
+	 */
+	int (*lop_declare_create)(const struct lu_env *env,
+				  struct llog_handle *handle,
+				  struct thandle *th);
+	int (*lop_create)(const struct lu_env *env, struct llog_handle *handle,
+			  struct thandle *th);
+	/**
+	 * write new record in llog. It appends records usually but can edit
+	 * existing records too.
+	 */
+	int (*lop_declare_write_rec)(const struct lu_env *env,
+				     struct llog_handle *lgh,
+				     struct llog_rec_hdr *rec,
+				     int idx, struct thandle *th);
+	int (*lop_write_rec)(const struct lu_env *env,
+			     struct llog_handle *loghandle,
+			     struct llog_rec_hdr *rec,
+			     struct llog_cookie *cookie, int cookiecount,
+			     void *buf, int idx, struct thandle *th);
+	/**
+	 * Add new record in llog catalog. Does the same as llog_write_rec()
+	 * but using llog catalog.
+	 */
+	int (*lop_declare_add)(const struct lu_env *env,
+			       struct llog_handle *lgh,
+			       struct llog_rec_hdr *rec, struct thandle *th);
+	int (*lop_add)(const struct lu_env *env, struct llog_handle *lgh,
+		       struct llog_rec_hdr *rec, struct llog_cookie *cookie,
+		       void *buf, struct thandle *th);
+	/* Old llog_add version, used in MDS-LOV-OSC now and will gone with
+	 * LOD/OSP replacement */
+	int (*lop_obd_add)(const struct lu_env *env, struct llog_ctxt *ctxt,
+			   struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
+			   struct llog_cookie *logcookies, int numcookies);
+};
+
+/* In-memory descriptor for a log object or log catalog */
+struct llog_handle {
+	struct rw_semaphore	 lgh_lock;
+	spinlock_t		 lgh_hdr_lock; /* protect lgh_hdr data */
+	struct llog_logid	 lgh_id; /* id of this log */
+	struct llog_log_hdr	*lgh_hdr;
+	struct file		*lgh_file;
+	struct dt_object	*lgh_obj;
+	int			 lgh_last_idx;
+	int			 lgh_cur_idx; /* used during llog_process */
+	__u64			 lgh_cur_offset; /* used during llog_process */
+	struct llog_ctxt	*lgh_ctxt;
+	union {
+		struct plain_handle_data	 phd;
+		struct cat_handle_data		 chd;
+	} u;
+	char			*lgh_name;
+	void			*private_data;
+	struct llog_operations	*lgh_logops;
+	atomic_t		 lgh_refcount;
+};
+
+/* llog_lvfs.c */
+extern struct llog_operations llog_lvfs_ops;
+
+/* llog_osd.c */
+extern struct llog_operations llog_osd_ops;
+int llog_osd_get_cat_list(const struct lu_env *env, struct dt_device *d,
+			  int idx, int count,
+			  struct llog_catid *idarray);
+int llog_osd_put_cat_list(const struct lu_env *env, struct dt_device *d,
+			  int idx, int count,
+			  struct llog_catid *idarray);
+
+#define LLOG_CTXT_FLAG_UNINITIALIZED     0x00000001
+#define LLOG_CTXT_FLAG_STOP		 0x00000002
+
+struct llog_ctxt {
+	int		      loc_idx; /* my index the obd array of ctxt's */
+	struct obd_device       *loc_obd; /* points back to the containing obd*/
+	struct obd_llog_group   *loc_olg; /* group containing that ctxt */
+	struct obd_export       *loc_exp; /* parent "disk" export (e.g. MDS) */
+	struct obd_import       *loc_imp; /* to use in RPC's: can be backward
+					     pointing import */
+	struct llog_operations  *loc_logops;
+	struct llog_handle      *loc_handle;
+	struct mutex		 loc_mutex; /* protect loc_imp */
+	atomic_t	     loc_refcount;
+	long		     loc_flags; /* flags, see above defines */
+	struct dt_object	*loc_dir;
+};
+
+#define LLOG_PROC_BREAK 0x0001
+#define LLOG_DEL_RECORD 0x0002
+
+static inline int llog_obd2ops(struct llog_ctxt *ctxt,
+			       struct llog_operations **lop)
+{
+	if (ctxt == NULL)
+		return -ENOTCONN;
+
+	*lop = ctxt->loc_logops;
+	if (*lop == NULL)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static inline int llog_handle2ops(struct llog_handle *loghandle,
+				  struct llog_operations **lop)
+{
+	if (loghandle == NULL || loghandle->lgh_logops == NULL)
+		return -EINVAL;
+
+	*lop = loghandle->lgh_logops;
+	return 0;
+}
+
+static inline int llog_data_len(int len)
+{
+	return cfs_size_round(len);
+}
+
+static inline struct llog_ctxt *llog_ctxt_get(struct llog_ctxt *ctxt)
+{
+	atomic_inc(&ctxt->loc_refcount);
+	CDEBUG(D_INFO, "GETting ctxt %p : new refcount %d\n", ctxt,
+	       atomic_read(&ctxt->loc_refcount));
+	return ctxt;
+}
+
+static inline void llog_ctxt_put(struct llog_ctxt *ctxt)
+{
+	if (ctxt == NULL)
+		return;
+	LASSERT_ATOMIC_GT_LT(&ctxt->loc_refcount, 0, LI_POISON);
+	CDEBUG(D_INFO, "PUTting ctxt %p : new refcount %d\n", ctxt,
+	       atomic_read(&ctxt->loc_refcount) - 1);
+	__llog_ctxt_put(NULL, ctxt);
+}
+
+static inline void llog_group_init(struct obd_llog_group *olg, int group)
+{
+	init_waitqueue_head(&olg->olg_waitq);
+	spin_lock_init(&olg->olg_lock);
+	mutex_init(&olg->olg_cat_processing);
+	olg->olg_seq = group;
+}
+
+static inline int llog_group_set_ctxt(struct obd_llog_group *olg,
+				      struct llog_ctxt *ctxt, int index)
+{
+	LASSERT(index >= 0 && index < LLOG_MAX_CTXTS);
+
+	spin_lock(&olg->olg_lock);
+	if (olg->olg_ctxts[index] != NULL) {
+		spin_unlock(&olg->olg_lock);
+		return -EEXIST;
+	}
+	olg->olg_ctxts[index] = ctxt;
+	spin_unlock(&olg->olg_lock);
+	return 0;
+}
+
+static inline struct llog_ctxt *llog_group_get_ctxt(struct obd_llog_group *olg,
+						    int index)
+{
+	struct llog_ctxt *ctxt;
+
+	LASSERT(index >= 0 && index < LLOG_MAX_CTXTS);
+
+	spin_lock(&olg->olg_lock);
+	if (olg->olg_ctxts[index] == NULL)
+		ctxt = NULL;
+	else
+		ctxt = llog_ctxt_get(olg->olg_ctxts[index]);
+	spin_unlock(&olg->olg_lock);
+	return ctxt;
+}
+
+static inline void llog_group_clear_ctxt(struct obd_llog_group *olg, int index)
+{
+	LASSERT(index >= 0 && index < LLOG_MAX_CTXTS);
+	spin_lock(&olg->olg_lock);
+	olg->olg_ctxts[index] = NULL;
+	spin_unlock(&olg->olg_lock);
+}
+
+static inline struct llog_ctxt *llog_get_context(struct obd_device *obd,
+						 int index)
+{
+	return llog_group_get_ctxt(&obd->obd_olg, index);
+}
+
+static inline int llog_group_ctxt_null(struct obd_llog_group *olg, int index)
+{
+	return (olg->olg_ctxts[index] == NULL);
+}
+
+static inline int llog_ctxt_null(struct obd_device *obd, int index)
+{
+	return (llog_group_ctxt_null(&obd->obd_olg, index));
+}
+
+static inline int llog_destroy(const struct lu_env *env,
+			       struct llog_handle *handle)
+{
+	struct llog_operations *lop;
+	int rc;
+
+	ENTRY;
+
+	rc = llog_handle2ops(handle, &lop);
+	if (rc)
+		RETURN(rc);
+	if (lop->lop_destroy == NULL)
+		RETURN(-EOPNOTSUPP);
+
+	rc = lop->lop_destroy(env, handle);
+	RETURN(rc);
+}
+
+static inline int llog_next_block(const struct lu_env *env,
+				  struct llog_handle *loghandle, int *cur_idx,
+				  int next_idx, __u64 *cur_offset, void *buf,
+				  int len)
+{
+	struct llog_operations *lop;
+	int rc;
+
+	ENTRY;
+
+	rc = llog_handle2ops(loghandle, &lop);
+	if (rc)
+		RETURN(rc);
+	if (lop->lop_next_block == NULL)
+		RETURN(-EOPNOTSUPP);
+
+	rc = lop->lop_next_block(env, loghandle, cur_idx, next_idx,
+				 cur_offset, buf, len);
+	RETURN(rc);
+}
+
+static inline int llog_prev_block(const struct lu_env *env,
+				  struct llog_handle *loghandle,
+				  int prev_idx, void *buf, int len)
+{
+	struct llog_operations *lop;
+	int rc;
+
+	ENTRY;
+
+	rc = llog_handle2ops(loghandle, &lop);
+	if (rc)
+		RETURN(rc);
+	if (lop->lop_prev_block == NULL)
+		RETURN(-EOPNOTSUPP);
+
+	rc = lop->lop_prev_block(env, loghandle, prev_idx, buf, len);
+	RETURN(rc);
+}
+
+static inline int llog_connect(struct llog_ctxt *ctxt,
+			       struct llog_logid *logid, struct llog_gen *gen,
+			       struct obd_uuid *uuid)
+{
+	struct llog_operations	*lop;
+	int			 rc;
+
+	ENTRY;
+
+	rc = llog_obd2ops(ctxt, &lop);
+	if (rc)
+		RETURN(rc);
+	if (lop->lop_connect == NULL)
+		RETURN(-EOPNOTSUPP);
+
+	rc = lop->lop_connect(ctxt, logid, gen, uuid);
+	RETURN(rc);
+}
+
+/* llog.c */
+int llog_exist(struct llog_handle *loghandle);
+int llog_declare_create(const struct lu_env *env,
+			struct llog_handle *loghandle, struct thandle *th);
+int llog_create(const struct lu_env *env, struct llog_handle *handle,
+		struct thandle *th);
+int llog_declare_write_rec(const struct lu_env *env,
+			   struct llog_handle *handle,
+			   struct llog_rec_hdr *rec, int idx,
+			   struct thandle *th);
+int llog_write_rec(const struct lu_env *env, struct llog_handle *handle,
+		   struct llog_rec_hdr *rec, struct llog_cookie *logcookies,
+		   int numcookies, void *buf, int idx, struct thandle *th);
+int llog_add(const struct lu_env *env, struct llog_handle *lgh,
+	     struct llog_rec_hdr *rec, struct llog_cookie *logcookies,
+	     void *buf, struct thandle *th);
+int llog_declare_add(const struct lu_env *env, struct llog_handle *lgh,
+		     struct llog_rec_hdr *rec, struct thandle *th);
+int lustre_process_log(struct super_block *sb, char *logname,
+		       struct config_llog_instance *cfg);
+int lustre_end_log(struct super_block *sb, char *logname,
+		   struct config_llog_instance *cfg);
+int llog_open_create(const struct lu_env *env, struct llog_ctxt *ctxt,
+		     struct llog_handle **res, struct llog_logid *logid,
+		     char *name);
+int llog_erase(const struct lu_env *env, struct llog_ctxt *ctxt,
+	       struct llog_logid *logid, char *name);
+int llog_write(const struct lu_env *env, struct llog_handle *loghandle,
+	       struct llog_rec_hdr *rec, struct llog_cookie *reccookie,
+	       int cookiecount, void *buf, int idx);
+
+/** @} log */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_mdc.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_mdc.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_mdc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_mdc.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,176 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_mdc.h
+ *
+ * MDS data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ */
+
+#ifndef _LUSTRE_MDC_H
+#define _LUSTRE_MDC_H
+
+/** \defgroup mdc mdc
+ *
+ * @{
+ */
+
+# include <linux/fs.h>
+# include <linux/dcache.h>
+# ifdef CONFIG_FS_POSIX_ACL
+#  include <linux/posix_acl_xattr.h>
+# endif /* CONFIG_FS_POSIX_ACL */
+# include <linux/lustre_intent.h>
+#include <lustre_handles.h>
+#include <linux/libcfs/libcfs.h>
+#include <obd_class.h>
+#include <lustre/lustre_idl.h>
+#include <lustre_lib.h>
+#include <lustre_dlm.h>
+#include <lustre_export.h>
+
+struct ptlrpc_client;
+struct obd_export;
+struct ptlrpc_request;
+struct obd_device;
+
+struct mdc_rpc_lock {
+	struct mutex		rpcl_mutex;
+	struct lookup_intent	*rpcl_it;
+	int			rpcl_fakes;
+};
+
+#define MDC_FAKE_RPCL_IT ((void *)0x2c0012bfUL)
+
+static inline void mdc_init_rpc_lock(struct mdc_rpc_lock *lck)
+{
+	mutex_init(&lck->rpcl_mutex);
+	lck->rpcl_it = NULL;
+}
+
+static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck,
+				    struct lookup_intent *it)
+{
+	ENTRY;
+
+	if (it != NULL && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP))
+		return;
+
+	/* This would normally block until the existing request finishes.
+	 * If fail_loc is set it will block until the regular request is
+	 * done, then set rpcl_it to MDC_FAKE_RPCL_IT.  Once that is set
+	 * it will only be cleared when all fake requests are finished.
+	 * Only when all fake requests are finished can normal requests
+	 * be sent, to ensure they are recoverable again. */
+ again:
+	mutex_lock(&lck->rpcl_mutex);
+
+	if (CFS_FAIL_CHECK_QUIET(OBD_FAIL_MDC_RPCS_SEM)) {
+		lck->rpcl_it = MDC_FAKE_RPCL_IT;
+		lck->rpcl_fakes++;
+		mutex_unlock(&lck->rpcl_mutex);
+		return;
+	}
+
+	/* This will only happen when the CFS_FAIL_CHECK() was
+	 * just turned off but there are still requests in progress.
+	 * Wait until they finish.  It doesn't need to be efficient
+	 * in this extremely rare case, just have low overhead in
+	 * the common case when it isn't true. */
+	while (unlikely(lck->rpcl_it == MDC_FAKE_RPCL_IT)) {
+		mutex_unlock(&lck->rpcl_mutex);
+		schedule_timeout(cfs_time_seconds(1) / 4);
+		goto again;
+	}
+
+	LASSERT(lck->rpcl_it == NULL);
+	lck->rpcl_it = it;
+}
+
+static inline void mdc_put_rpc_lock(struct mdc_rpc_lock *lck,
+				    struct lookup_intent *it)
+{
+	if (it != NULL && (it->it_op == IT_GETATTR || it->it_op == IT_LOOKUP))
+		goto out;
+
+	if (lck->rpcl_it == MDC_FAKE_RPCL_IT) { /* OBD_FAIL_MDC_RPCS_SEM */
+		mutex_lock(&lck->rpcl_mutex);
+
+		LASSERTF(lck->rpcl_fakes > 0, "%d\n", lck->rpcl_fakes);
+		lck->rpcl_fakes--;
+
+		if (lck->rpcl_fakes == 0)
+			lck->rpcl_it = NULL;
+
+	} else {
+		LASSERTF(it == lck->rpcl_it, "%p != %p\n", it, lck->rpcl_it);
+		lck->rpcl_it = NULL;
+	}
+
+	mutex_unlock(&lck->rpcl_mutex);
+ out:
+	EXIT;
+}
+
+static inline void mdc_update_max_ea_from_body(struct obd_export *exp,
+					       struct mdt_body *body)
+{
+	if (body->valid & OBD_MD_FLMODEASIZE) {
+		if (exp->exp_obd->u.cli.cl_max_mds_easize < body->max_mdsize)
+			exp->exp_obd->u.cli.cl_max_mds_easize =
+						body->max_mdsize;
+		if (exp->exp_obd->u.cli.cl_max_mds_cookiesize <
+						body->max_cookiesize)
+			exp->exp_obd->u.cli.cl_max_mds_cookiesize =
+						body->max_cookiesize;
+	}
+}
+
+
+struct mdc_cache_waiter {
+	struct list_head	      mcw_entry;
+	wait_queue_head_t	     mcw_waitq;
+};
+
+/* mdc/mdc_locks.c */
+int it_disposition(struct lookup_intent *it, int flag);
+void it_clear_disposition(struct lookup_intent *it, int flag);
+void it_set_disposition(struct lookup_intent *it, int flag);
+int it_open_error(int phase, struct lookup_intent *it);
+
+/** @} mdc */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_mds.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_mds.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_mds.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_mds.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,81 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_mds.h
+ *
+ * MDS data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ */
+
+#ifndef _LUSTRE_MDS_H
+#define _LUSTRE_MDS_H
+
+/** \defgroup mds mds
+ *
+ * @{
+ */
+
+#include <lustre_handles.h>
+#include <linux/libcfs/libcfs.h>
+#include <lustre/lustre_idl.h>
+#include <lustre_lib.h>
+#include <lustre_dlm.h>
+#include <lustre_export.h>
+
+struct mds_group_info {
+	struct obd_uuid *uuid;
+	int group;
+};
+
+struct mds_capa_info {
+	struct obd_uuid	*uuid;
+	struct lustre_capa_key *capa;
+};
+
+#define MDD_OBD_NAME     "mdd_obd"
+#define MDD_OBD_UUID     "mdd_obd_uuid"
+
+static inline int md_should_create(__u64 flags)
+{
+       return !(flags & MDS_OPEN_DELAY_CREATE ||
+	       !(flags & FMODE_WRITE));
+}
+
+/* these are local flags, used only on the client, private */
+#define M_CHECK_STALE	   0200000000
+
+/** @} mds */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_mdt.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_mdt.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_mdt.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_mdt.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,84 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __LINUX_MDT_H
+#define __LINUX_MDT_H
+
+/** \defgroup mdt mdt
+ *
+ * @{
+ */
+
+#include <lustre/lustre_idl.h>
+#include <lustre_req_layout.h>
+#include <md_object.h>
+#include <dt_object.h>
+#include <linux/libcfs/libcfs.h>
+
+/*
+ * Common thread info for mdt, seq and fld
+ */
+struct com_thread_info {
+	/*
+	 * for req-layout interface.
+	 */
+	struct req_capsule *cti_pill;
+};
+
+enum {
+	ESERIOUS = 0x0001000
+};
+
+static inline int err_serious(int rc)
+{
+	LASSERT(rc < 0);
+	LASSERT(-rc < ESERIOUS);
+	return -(-rc | ESERIOUS);
+}
+
+static inline int clear_serious(int rc)
+{
+	if (rc < 0)
+		rc = -(-rc & ~ESERIOUS);
+	return rc;
+}
+
+static inline int is_serious(int rc)
+{
+	return (rc < 0 && -rc & ESERIOUS);
+}
+
+/** @} mdt */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_net.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_net.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_net.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_net.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,3451 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2010, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+/** \defgroup PtlRPC Portal RPC and networking module.
+ *
+ * PortalRPC is the layer used by rest of lustre code to achieve network
+ * communications: establish connections with corresponding export and import
+ * states, listen for a service, send and receive RPCs.
+ * PortalRPC also includes base recovery framework: packet resending and
+ * replaying, reconnections, pinger.
+ *
+ * PortalRPC utilizes LNet as its transport layer.
+ *
+ * @{
+ */
+
+
+#ifndef _LUSTRE_NET_H
+#define _LUSTRE_NET_H
+
+/** \defgroup net net
+ *
+ * @{
+ */
+
+#include <linux/lustre_net.h>
+
+#include <linux/libcfs/libcfs.h>
+// #include <obd.h>
+#include <linux/lnet/lnet.h>
+#include <lustre/lustre_idl.h>
+#include <lustre_ha.h>
+#include <lustre_sec.h>
+#include <lustre_import.h>
+#include <lprocfs_status.h>
+#include <lu_object.h>
+#include <lustre_req_layout.h>
+
+#include <obd_support.h>
+#include <lustre_ver.h>
+
+/* MD flags we _always_ use */
+#define PTLRPC_MD_OPTIONS  0
+
+/**
+ * Max # of bulk operations in one request.
+ * In order for the client and server to properly negotiate the maximum
+ * possible transfer size, PTLRPC_BULK_OPS_COUNT must be a power-of-two
+ * value.  The client is free to limit the actual RPC size for any bulk
+ * transfer via cl_max_pages_per_rpc to some non-power-of-two value. */
+#define PTLRPC_BULK_OPS_BITS	2
+#define PTLRPC_BULK_OPS_COUNT	(1U << PTLRPC_BULK_OPS_BITS)
+/**
+ * PTLRPC_BULK_OPS_MASK is for the convenience of the client only, and
+ * should not be used on the server at all.  Otherwise, it imposes a
+ * protocol limitation on the maximum RPC size that can be used by any
+ * RPC sent to that server in the future.  Instead, the server should
+ * use the negotiated per-client ocd_brw_size to determine the bulk
+ * RPC count. */
+#define PTLRPC_BULK_OPS_MASK	(~((__u64)PTLRPC_BULK_OPS_COUNT - 1))
+
+/**
+ * Define maxima for bulk I/O.
+ *
+ * A single PTLRPC BRW request is sent via up to PTLRPC_BULK_OPS_COUNT
+ * of LNET_MTU sized RDMA transfers.  Clients and servers negotiate the
+ * currently supported maximum between peers at connect via ocd_brw_size.
+ */
+#define PTLRPC_MAX_BRW_BITS	(LNET_MTU_BITS + PTLRPC_BULK_OPS_BITS)
+#define PTLRPC_MAX_BRW_SIZE	(1 << PTLRPC_MAX_BRW_BITS)
+#define PTLRPC_MAX_BRW_PAGES	(PTLRPC_MAX_BRW_SIZE >> PAGE_CACHE_SHIFT)
+
+#define ONE_MB_BRW_SIZE		(1 << LNET_MTU_BITS)
+#define MD_MAX_BRW_SIZE		(1 << LNET_MTU_BITS)
+#define MD_MAX_BRW_PAGES	(MD_MAX_BRW_SIZE >> PAGE_CACHE_SHIFT)
+#define DT_MAX_BRW_SIZE		PTLRPC_MAX_BRW_SIZE
+#define DT_MAX_BRW_PAGES	(DT_MAX_BRW_SIZE >> PAGE_CACHE_SHIFT)
+#define OFD_MAX_BRW_SIZE	(1 << LNET_MTU_BITS)
+
+/* When PAGE_SIZE is a constant, we can check our arithmetic here with cpp! */
+# if ((PTLRPC_MAX_BRW_PAGES & (PTLRPC_MAX_BRW_PAGES - 1)) != 0)
+#  error "PTLRPC_MAX_BRW_PAGES isn't a power of two"
+# endif
+# if (PTLRPC_MAX_BRW_SIZE != (PTLRPC_MAX_BRW_PAGES * PAGE_CACHE_SIZE))
+#  error "PTLRPC_MAX_BRW_SIZE isn't PTLRPC_MAX_BRW_PAGES * PAGE_CACHE_SIZE"
+# endif
+# if (PTLRPC_MAX_BRW_SIZE > LNET_MTU * PTLRPC_BULK_OPS_COUNT)
+#  error "PTLRPC_MAX_BRW_SIZE too big"
+# endif
+# if (PTLRPC_MAX_BRW_PAGES > LNET_MAX_IOV * PTLRPC_BULK_OPS_COUNT)
+#  error "PTLRPC_MAX_BRW_PAGES too big"
+# endif
+
+#define PTLRPC_NTHRS_INIT	2
+
+/**
+ * Buffer Constants
+ *
+ * Constants determine how memory is used to buffer incoming service requests.
+ *
+ * ?_NBUFS	      # buffers to allocate when growing the pool
+ * ?_BUFSIZE	    # bytes in a single request buffer
+ * ?_MAXREQSIZE	 # maximum request service will receive
+ *
+ * When fewer than ?_NBUFS/2 buffers are posted for receive, another chunk
+ * of ?_NBUFS is added to the pool.
+ *
+ * Messages larger than ?_MAXREQSIZE are dropped.  Request buffers are
+ * considered full when less than ?_MAXREQSIZE is left in them.
+ */
+/**
+ * Thread Constants
+ *
+ * Constants determine how threads are created for ptlrpc service.
+ *
+ * ?_NTHRS_INIT		# threads to create for each service partition on
+ *			  initializing. If it's non-affinity service and
+ *			  there is only one partition, it's the overall #
+ *			  threads for the service while initializing.
+ * ?_NTHRS_BASE		# threads should be created at least for each
+ *			  ptlrpc partition to keep the service healthy.
+ *			  It's the low-water mark of threads upper-limit
+ *			  for each partition.
+ * ?_THR_FACTOR	 # threads can be added on threads upper-limit for
+ *			  each CPU core. This factor is only for reference,
+ *			  we might decrease value of factor if number of cores
+ *			  per CPT is above a limit.
+ * ?_NTHRS_MAX		# overall threads can be created for a service,
+ *			  it's a soft limit because if service is running
+ *			  on machine with hundreds of cores and tens of
+ *			  CPU partitions, we need to guarantee each partition
+ *			  has ?_NTHRS_BASE threads, which means total threads
+ *			  will be ?_NTHRS_BASE * number_of_cpts which can
+ *			  exceed ?_NTHRS_MAX.
+ *
+ * Examples
+ *
+ * #define MDS_NTHRS_INIT	2
+ * #define MDS_NTHRS_BASE	64
+ * #define MDS_NTHRS_FACTOR	8
+ * #define MDS_NTHRS_MAX	1024
+ *
+ * Example 1):
+ * ---------------------------------------------------------------------
+ * Server(A) has 16 cores, user configured it to 4 partitions so each
+ * partition has 4 cores, then actual number of service threads on each
+ * partition is:
+ *     MDS_NTHRS_BASE(64) + cores(4) * MDS_NTHRS_FACTOR(8) = 96
+ *
+ * Total number of threads for the service is:
+ *     96 * partitions(4) = 384
+ *
+ * Example 2):
+ * ---------------------------------------------------------------------
+ * Server(B) has 32 cores, user configured it to 4 partitions so each
+ * partition has 8 cores, then actual number of service threads on each
+ * partition is:
+ *     MDS_NTHRS_BASE(64) + cores(8) * MDS_NTHRS_FACTOR(8) = 128
+ *
+ * Total number of threads for the service is:
+ *     128 * partitions(4) = 512
+ *
+ * Example 3):
+ * ---------------------------------------------------------------------
+ * Server(B) has 96 cores, user configured it to 8 partitions so each
+ * partition has 12 cores, then actual number of service threads on each
+ * partition is:
+ *     MDS_NTHRS_BASE(64) + cores(12) * MDS_NTHRS_FACTOR(8) = 160
+ *
+ * Total number of threads for the service is:
+ *     160 * partitions(8) = 1280
+ *
+ * However, it's above the soft limit MDS_NTHRS_MAX, so we choose this number
+ * as upper limit of threads number for each partition:
+ *     MDS_NTHRS_MAX(1024) / partitions(8) = 128
+ *
+ * Example 4):
+ * ---------------------------------------------------------------------
+ * Server(C) have a thousand of cores and user configured it to 32 partitions
+ *     MDS_NTHRS_BASE(64) * 32 = 2048
+ *
+ * which is already above soft limit MDS_NTHRS_MAX(1024), but we still need
+ * to guarantee that each partition has at least MDS_NTHRS_BASE(64) threads
+ * to keep service healthy, so total number of threads will just be 2048.
+ *
+ * NB: we don't suggest to choose server with that many cores because backend
+ *     filesystem itself, buffer cache, or underlying network stack might
+ *     have some SMP scalability issues at that large scale.
+ *
+ *     If user already has a fat machine with hundreds or thousands of cores,
+ *     there are two choices for configuration:
+ *     a) create CPU table from subset of all CPUs and run Lustre on
+ *	top of this subset
+ *     b) bind service threads on a few partitions, see modparameters of
+ *	MDS and OSS for details
+*
+ * NB: these calculations (and examples below) are simplified to help
+ *     understanding, the real implementation is a little more complex,
+ *     please see ptlrpc_server_nthreads_check() for details.
+ *
+ */
+
+ /*
+  * LDLM threads constants:
+  *
+  * Given 8 as factor and 24 as base threads number
+  *
+  * example 1)
+  * On 4-core machine we will have 24 + 8 * 4 = 56 threads.
+  *
+  * example 2)
+  * On 8-core machine with 2 partitions we will have 24 + 4 * 8 = 56
+  * threads for each partition and total threads number will be 112.
+  *
+  * example 3)
+  * On 64-core machine with 8 partitions we will need LDLM_NTHRS_BASE(24)
+  * threads for each partition to keep service healthy, so total threads
+  * number should be 24 * 8 = 192.
+  *
+  * So with these constants, threads number will be at the similar level
+  * of old versions, unless target machine has over a hundred cores
+  */
+#define LDLM_THR_FACTOR		8
+#define LDLM_NTHRS_INIT		PTLRPC_NTHRS_INIT
+#define LDLM_NTHRS_BASE		24
+#define LDLM_NTHRS_MAX		(num_online_cpus() == 1 ? 64 : 128)
+
+#define LDLM_BL_THREADS   LDLM_NTHRS_AUTO_INIT
+#define LDLM_CLIENT_NBUFS 1
+#define LDLM_SERVER_NBUFS 64
+#define LDLM_BUFSIZE      (8 * 1024)
+#define LDLM_MAXREQSIZE   (5 * 1024)
+#define LDLM_MAXREPSIZE   (1024)
+
+ /*
+  * MDS threads constants:
+  *
+  * Please see examples in "Thread Constants", MDS threads number will be at
+  * the comparable level of old versions, unless the server has many cores.
+  */
+#ifndef MDS_MAX_THREADS
+#define MDS_MAX_THREADS		1024
+#define MDS_MAX_OTHR_THREADS	256
+
+#else /* MDS_MAX_THREADS */
+#if MDS_MAX_THREADS < PTLRPC_NTHRS_INIT
+#undef MDS_MAX_THREADS
+#define MDS_MAX_THREADS	PTLRPC_NTHRS_INIT
+#endif
+#define MDS_MAX_OTHR_THREADS	max(PTLRPC_NTHRS_INIT, MDS_MAX_THREADS / 2)
+#endif
+
+/* default service */
+#define MDS_THR_FACTOR		8
+#define MDS_NTHRS_INIT		PTLRPC_NTHRS_INIT
+#define MDS_NTHRS_MAX		MDS_MAX_THREADS
+#define MDS_NTHRS_BASE		min(64, MDS_NTHRS_MAX)
+
+/* read-page service */
+#define MDS_RDPG_THR_FACTOR	4
+#define MDS_RDPG_NTHRS_INIT	PTLRPC_NTHRS_INIT
+#define MDS_RDPG_NTHRS_MAX	MDS_MAX_OTHR_THREADS
+#define MDS_RDPG_NTHRS_BASE	min(48, MDS_RDPG_NTHRS_MAX)
+
+/* these should be removed when we remove setattr service in the future */
+#define MDS_SETA_THR_FACTOR	4
+#define MDS_SETA_NTHRS_INIT	PTLRPC_NTHRS_INIT
+#define MDS_SETA_NTHRS_MAX	MDS_MAX_OTHR_THREADS
+#define MDS_SETA_NTHRS_BASE	min(48, MDS_SETA_NTHRS_MAX)
+
+/* non-affinity threads */
+#define MDS_OTHR_NTHRS_INIT	PTLRPC_NTHRS_INIT
+#define MDS_OTHR_NTHRS_MAX	MDS_MAX_OTHR_THREADS
+
+#define MDS_NBUFS		64
+
+/**
+ * Assume file name length = FNAME_MAX = 256 (true for ext3).
+ *	  path name length = PATH_MAX = 4096
+ *	  LOV MD size max  = EA_MAX = 24 * 2000
+ *		(NB: 24 is size of lov_ost_data)
+ *	  LOV LOGCOOKIE size max = 32 * 2000
+ *		(NB: 32 is size of llog_cookie)
+ * symlink:  FNAME_MAX + PATH_MAX  <- largest
+ * link:     FNAME_MAX + PATH_MAX  (mds_rec_link < mds_rec_create)
+ * rename:   FNAME_MAX + FNAME_MAX
+ * open:     FNAME_MAX + EA_MAX
+ *
+ * MDS_MAXREQSIZE ~= 4736 bytes =
+ * lustre_msg + ldlm_request + mdt_body + mds_rec_create + FNAME_MAX + PATH_MAX
+ * MDS_MAXREPSIZE ~= 8300 bytes = lustre_msg + llog_header
+ *
+ * Realistic size is about 512 bytes (20 character name + 128 char symlink),
+ * except in the open case where there are a large number of OSTs in a LOV.
+ */
+#define MDS_MAXREQSIZE		(5 * 1024)	/* >= 4736 */
+#define MDS_MAXREPSIZE		(9 * 1024)	/* >= 8300 */
+
+/**
+ * MDS incoming request with LOV EA
+ * 24 = sizeof(struct lov_ost_data), i.e: replay of opencreate
+ */
+#define MDS_LOV_MAXREQSIZE	max(MDS_MAXREQSIZE, \
+				    362 + LOV_MAX_STRIPE_COUNT * 24)
+/**
+ * MDS outgoing reply with LOV EA
+ *
+ * NB: max reply size Lustre 2.4+ client can get from old MDS is:
+ * LOV_MAX_STRIPE_COUNT * (llog_cookie + lov_ost_data) + extra bytes
+ *
+ * but 2.4 or later MDS will never send reply with llog_cookie to any
+ * version client. This macro is defined for server side reply buffer size.
+ */
+#define MDS_LOV_MAXREPSIZE	MDS_LOV_MAXREQSIZE
+
+/**
+ * This is the size of a maximum REINT_SETXATTR request:
+ *
+ *   lustre_msg		 56 (32 + 4 x 5 + 4)
+ *   ptlrpc_body	184
+ *   mdt_rec_setxattr	136
+ *   lustre_capa	120
+ *   name		256 (XATTR_NAME_MAX)
+ *   value	      65536 (XATTR_SIZE_MAX)
+ */
+#define MDS_EA_MAXREQSIZE	66288
+
+/**
+ * These are the maximum request and reply sizes (rounded up to 1 KB
+ * boundaries) for the "regular" MDS_REQUEST_PORTAL and MDS_REPLY_PORTAL.
+ */
+#define MDS_REG_MAXREQSIZE	(((max(MDS_EA_MAXREQSIZE, \
+				       MDS_LOV_MAXREQSIZE) + 1023) >> 10) << 10)
+#define MDS_REG_MAXREPSIZE	MDS_REG_MAXREQSIZE
+
+/**
+ * The update request includes all of updates from the create, which might
+ * include linkea (4K maxim), together with other updates, we set it to 9K:
+ * lustre_msg + ptlrpc_body + UPDATE_BUF_SIZE (8K)
+ */
+#define MDS_OUT_MAXREQSIZE	(9 * 1024)
+#define MDS_OUT_MAXREPSIZE	MDS_MAXREPSIZE
+
+/** MDS_BUFSIZE = max_reqsize (w/o LOV EA) + max sptlrpc payload size */
+#define MDS_BUFSIZE		max(MDS_MAXREQSIZE + SPTLRPC_MAX_PAYLOAD, \
+				    8 * 1024)
+
+/**
+ * MDS_REG_BUFSIZE should at least be MDS_REG_MAXREQSIZE + SPTLRPC_MAX_PAYLOAD.
+ * However, we need to allocate a much larger buffer for it because LNet
+ * requires each MD(rqbd) has at least MDS_REQ_MAXREQSIZE bytes left to avoid
+ * dropping of maximum-sized incoming request.  So if MDS_REG_BUFSIZE is only a
+ * little larger than MDS_REG_MAXREQSIZE, then it can only fit in one request
+ * even there are about MDS_REG_MAX_REQSIZE bytes left in a rqbd, and memory
+ * utilization is very low.
+ *
+ * In the meanwhile, size of rqbd can't be too large, because rqbd can't be
+ * reused until all requests fit in it have been processed and released,
+ * which means one long blocked request can prevent the rqbd be reused.
+ * Now we set request buffer size to 160 KB, so even each rqbd is unlinked
+ * from LNet with unused 65 KB, buffer utilization will be about 59%.
+ * Please check LU-2432 for details.
+ */
+#define MDS_REG_BUFSIZE		max(MDS_REG_MAXREQSIZE + SPTLRPC_MAX_PAYLOAD, \
+				    160 * 1024)
+
+/**
+ * MDS_OUT_BUFSIZE = max_out_reqsize + max sptlrpc payload (~1K) which is
+ * about 10K, for the same reason as MDS_REG_BUFSIZE, we also give some
+ * extra bytes to each request buffer to improve buffer utilization rate.
+  */
+#define MDS_OUT_BUFSIZE		max(MDS_OUT_MAXREQSIZE + SPTLRPC_MAX_PAYLOAD, \
+				    24 * 1024)
+
+/** FLD_MAXREQSIZE == lustre_msg + __u32 padding + ptlrpc_body + opc */
+#define FLD_MAXREQSIZE  (160)
+
+/** FLD_MAXREPSIZE == lustre_msg + ptlrpc_body */
+#define FLD_MAXREPSIZE  (152)
+#define FLD_BUFSIZE	(1 << 12)
+
+/**
+ * SEQ_MAXREQSIZE == lustre_msg + __u32 padding + ptlrpc_body + opc + lu_range +
+ * __u32 padding */
+#define SEQ_MAXREQSIZE  (160)
+
+/** SEQ_MAXREPSIZE == lustre_msg + ptlrpc_body + lu_range */
+#define SEQ_MAXREPSIZE  (152)
+#define SEQ_BUFSIZE	(1 << 12)
+
+/** MGS threads must be >= 3, see bug 22458 comment #28 */
+#define MGS_NTHRS_INIT	(PTLRPC_NTHRS_INIT + 1)
+#define MGS_NTHRS_MAX	32
+
+#define MGS_NBUFS       64
+#define MGS_BUFSIZE     (8 * 1024)
+#define MGS_MAXREQSIZE  (7 * 1024)
+#define MGS_MAXREPSIZE  (9 * 1024)
+
+ /*
+  * OSS threads constants:
+  *
+  * Given 8 as factor and 64 as base threads number
+  *
+  * example 1):
+  * On 8-core server configured to 2 partitions, we will have
+  * 64 + 8 * 4 = 96 threads for each partition, 192 total threads.
+  *
+  * example 2):
+  * On 32-core machine configured to 4 partitions, we will have
+  * 64 + 8 * 8 = 112 threads for each partition, so total threads number
+  * will be 112 * 4 = 448.
+  *
+  * example 3):
+  * On 64-core machine configured to 4 partitions, we will have
+  * 64 + 16 * 8 = 192 threads for each partition, so total threads number
+  * will be 192 * 4 = 768 which is above limit OSS_NTHRS_MAX(512), so we
+  * cut off the value to OSS_NTHRS_MAX(512) / 4 which is 128 threads
+  * for each partition.
+  *
+  * So we can see that with these constants, threads number wil be at the
+  * similar level of old versions, unless the server has many cores.
+  */
+ /* depress threads factor for VM with small memory size */
+#define OSS_THR_FACTOR		min_t(int, 8, \
+				NUM_CACHEPAGES >> (28 - PAGE_CACHE_SHIFT))
+#define OSS_NTHRS_INIT		(PTLRPC_NTHRS_INIT + 1)
+#define OSS_NTHRS_BASE		64
+#define OSS_NTHRS_MAX		512
+
+/* threads for handling "create" request */
+#define OSS_CR_THR_FACTOR	1
+#define OSS_CR_NTHRS_INIT	PTLRPC_NTHRS_INIT
+#define OSS_CR_NTHRS_BASE	8
+#define OSS_CR_NTHRS_MAX	64
+
+/**
+ * OST_IO_MAXREQSIZE ~=
+ *	lustre_msg + ptlrpc_body + obdo + obd_ioobj +
+ *	DT_MAX_BRW_PAGES * niobuf_remote
+ *
+ * - single object with 16 pages is 512 bytes
+ * - OST_IO_MAXREQSIZE must be at least 1 page of cookies plus some spillover
+ * - Must be a multiple of 1024
+ * - actual size is about 18K
+ */
+#define _OST_MAXREQSIZE_SUM (sizeof(struct lustre_msg) + \
+			     sizeof(struct ptlrpc_body) + \
+			     sizeof(struct obdo) + \
+			     sizeof(struct obd_ioobj) + \
+			     sizeof(struct niobuf_remote) * DT_MAX_BRW_PAGES)
+/**
+ * FIEMAP request can be 4K+ for now
+ */
+#define OST_MAXREQSIZE		(5 * 1024)
+#define OST_IO_MAXREQSIZE	max_t(int, OST_MAXREQSIZE, \
+				(((_OST_MAXREQSIZE_SUM - 1) | (1024 - 1)) + 1))
+
+#define OST_MAXREPSIZE		(9 * 1024)
+#define OST_IO_MAXREPSIZE	OST_MAXREPSIZE
+
+#define OST_NBUFS		64
+/** OST_BUFSIZE = max_reqsize + max sptlrpc payload size */
+#define OST_BUFSIZE		max_t(int, OST_MAXREQSIZE + 1024, 16 * 1024)
+/**
+ * OST_IO_MAXREQSIZE is 18K, giving extra 46K can increase buffer utilization
+ * rate of request buffer, please check comment of MDS_LOV_BUFSIZE for details.
+ */
+#define OST_IO_BUFSIZE		max_t(int, OST_IO_MAXREQSIZE + 1024, 64 * 1024)
+
+/* Macro to hide a typecast. */
+#define ptlrpc_req_async_args(req) ((void *)&req->rq_async_args)
+
+/**
+ * Structure to single define portal connection.
+ */
+struct ptlrpc_connection {
+	/** linkage for connections hash table */
+	struct hlist_node	c_hash;
+	/** Our own lnet nid for this connection */
+	lnet_nid_t	      c_self;
+	/** Remote side nid for this connection */
+	lnet_process_id_t       c_peer;
+	/** UUID of the other side */
+	struct obd_uuid	 c_remote_uuid;
+	/** reference counter for this connection */
+	atomic_t	    c_refcount;
+};
+
+/** Client definition for PortalRPC */
+struct ptlrpc_client {
+	/** What lnet portal does this client send messages to by default */
+	__u32		   cli_request_portal;
+	/** What portal do we expect replies on */
+	__u32		   cli_reply_portal;
+	/** Name of the client */
+	char		   *cli_name;
+};
+
+/** state flags of requests */
+/* XXX only ones left are those used by the bulk descs as well! */
+#define PTL_RPC_FL_INTR      (1 << 0)  /* reply wait was interrupted by user */
+#define PTL_RPC_FL_TIMEOUT   (1 << 7)  /* request timed out waiting for reply */
+
+#define REQ_MAX_ACK_LOCKS 8
+
+union ptlrpc_async_args {
+	/**
+	 * Scratchpad for passing args to completion interpreter. Users
+	 * cast to the struct of their choosing, and CLASSERT that this is
+	 * big enough.  For _tons_ of context, OBD_ALLOC a struct and store
+	 * a pointer to it here.  The pointer_arg ensures this struct is at
+	 * least big enough for that.
+	 */
+	void      *pointer_arg[11];
+	__u64      space[7];
+};
+
+struct ptlrpc_request_set;
+typedef int (*set_interpreter_func)(struct ptlrpc_request_set *, void *, int);
+typedef int (*set_producer_func)(struct ptlrpc_request_set *, void *);
+
+/**
+ * Definition of request set structure.
+ * Request set is a list of requests (not necessary to the same target) that
+ * once populated with RPCs could be sent in parallel.
+ * There are two kinds of request sets. General purpose and with dedicated
+ * serving thread. Example of the latter is ptlrpcd set.
+ * For general purpose sets once request set started sending it is impossible
+ * to add new requests to such set.
+ * Provides a way to call "completion callbacks" when all requests in the set
+ * returned.
+ */
+struct ptlrpc_request_set {
+	atomic_t	  set_refcount;
+	/** number of in queue requests */
+	atomic_t	  set_new_count;
+	/** number of uncompleted requests */
+	atomic_t	  set_remaining;
+	/** wait queue to wait on for request events */
+	wait_queue_head_t	   set_waitq;
+	wait_queue_head_t	  *set_wakeup_ptr;
+	/** List of requests in the set */
+	struct list_head	    set_requests;
+	/**
+	 * List of completion callbacks to be called when the set is completed
+	 * This is only used if \a set_interpret is NULL.
+	 * Links struct ptlrpc_set_cbdata.
+	 */
+	struct list_head	    set_cblist;
+	/** Completion callback, if only one. */
+	set_interpreter_func  set_interpret;
+	/** opaq argument passed to completion \a set_interpret callback. */
+	void		 *set_arg;
+	/**
+	 * Lock for \a set_new_requests manipulations
+	 * locked so that any old caller can communicate requests to
+	 * the set holder who can then fold them into the lock-free set
+	 */
+	spinlock_t		set_new_req_lock;
+	/** List of new yet unsent requests. Only used with ptlrpcd now. */
+	struct list_head	    set_new_requests;
+
+	/** rq_status of requests that have been freed already */
+	int		   set_rc;
+	/** Additional fields used by the flow control extension */
+	/** Maximum number of RPCs in flight */
+	int		   set_max_inflight;
+	/** Callback function used to generate RPCs */
+	set_producer_func     set_producer;
+	/** opaq argument passed to the producer callback */
+	void		 *set_producer_arg;
+};
+
+/**
+ * Description of a single ptrlrpc_set callback
+ */
+struct ptlrpc_set_cbdata {
+	/** List linkage item */
+	struct list_head	      psc_item;
+	/** Pointer to interpreting function */
+	set_interpreter_func    psc_interpret;
+	/** Opaq argument to pass to the callback */
+	void		   *psc_data;
+};
+
+struct ptlrpc_bulk_desc;
+struct ptlrpc_service_part;
+struct ptlrpc_service;
+
+/**
+ * ptlrpc callback & work item stuff
+ */
+struct ptlrpc_cb_id {
+	void   (*cbid_fn)(lnet_event_t *ev);     /* specific callback fn */
+	void    *cbid_arg;		      /* additional arg */
+};
+
+/** Maximum number of locks to fit into reply state */
+#define RS_MAX_LOCKS 8
+#define RS_DEBUG     0
+
+/**
+ * Structure to define reply state on the server
+ * Reply state holds various reply message information. Also for "difficult"
+ * replies (rep-ack case) we store the state after sending reply and wait
+ * for the client to acknowledge the reception. In these cases locks could be
+ * added to the state for replay/failover consistency guarantees.
+ */
+struct ptlrpc_reply_state {
+	/** Callback description */
+	struct ptlrpc_cb_id    rs_cb_id;
+	/** Linkage for list of all reply states in a system */
+	struct list_head	     rs_list;
+	/** Linkage for list of all reply states on same export */
+	struct list_head	     rs_exp_list;
+	/** Linkage for list of all reply states for same obd */
+	struct list_head	     rs_obd_list;
+#if RS_DEBUG
+	struct list_head	     rs_debug_list;
+#endif
+	/** A spinlock to protect the reply state flags */
+	spinlock_t		rs_lock;
+	/** Reply state flags */
+	unsigned long	  rs_difficult:1;     /* ACK/commit stuff */
+	unsigned long	  rs_no_ack:1;    /* no ACK, even for
+						  difficult requests */
+	unsigned long	  rs_scheduled:1;     /* being handled? */
+	unsigned long	  rs_scheduled_ever:1;/* any schedule attempts? */
+	unsigned long	  rs_handled:1;  /* been handled yet? */
+	unsigned long	  rs_on_net:1;   /* reply_out_callback pending? */
+	unsigned long	  rs_prealloc:1; /* rs from prealloc list */
+	unsigned long	  rs_committed:1;/* the transaction was committed
+						 and the rs was dispatched
+						 by ptlrpc_commit_replies */
+	/** Size of the state */
+	int		    rs_size;
+	/** opcode */
+	__u32		  rs_opc;
+	/** Transaction number */
+	__u64		  rs_transno;
+	/** xid */
+	__u64		  rs_xid;
+	struct obd_export     *rs_export;
+	struct ptlrpc_service_part *rs_svcpt;
+	/** Lnet metadata handle for the reply */
+	lnet_handle_md_t       rs_md_h;
+	atomic_t	   rs_refcount;
+
+	/** Context for the sevice thread */
+	struct ptlrpc_svc_ctx *rs_svc_ctx;
+	/** Reply buffer (actually sent to the client), encoded if needed */
+	struct lustre_msg     *rs_repbuf;       /* wrapper */
+	/** Size of the reply buffer */
+	int		    rs_repbuf_len;   /* wrapper buf length */
+	/** Size of the reply message */
+	int		    rs_repdata_len;  /* wrapper msg length */
+	/**
+	 * Actual reply message. Its content is encrupted (if needed) to
+	 * produce reply buffer for actual sending. In simple case
+	 * of no network encryption we jus set \a rs_repbuf to \a rs_msg
+	 */
+	struct lustre_msg     *rs_msg;	  /* reply message */
+
+	/** Number of locks awaiting client ACK */
+	int		    rs_nlocks;
+	/** Handles of locks awaiting client reply ACK */
+	struct lustre_handle   rs_locks[RS_MAX_LOCKS];
+	/** Lock modes of locks in \a rs_locks */
+	ldlm_mode_t	    rs_modes[RS_MAX_LOCKS];
+};
+
+struct ptlrpc_thread;
+
+/** RPC stages */
+enum rq_phase {
+	RQ_PHASE_NEW	    = 0xebc0de00,
+	RQ_PHASE_RPC	    = 0xebc0de01,
+	RQ_PHASE_BULK	   = 0xebc0de02,
+	RQ_PHASE_INTERPRET      = 0xebc0de03,
+	RQ_PHASE_COMPLETE       = 0xebc0de04,
+	RQ_PHASE_UNREGISTERING  = 0xebc0de05,
+	RQ_PHASE_UNDEFINED      = 0xebc0de06
+};
+
+/** Type of request interpreter call-back */
+typedef int (*ptlrpc_interpterer_t)(const struct lu_env *env,
+				    struct ptlrpc_request *req,
+				    void *arg, int rc);
+
+/**
+ * Definition of request pool structure.
+ * The pool is used to store empty preallocated requests for the case
+ * when we would actually need to send something without performing
+ * any allocations (to avoid e.g. OOM).
+ */
+struct ptlrpc_request_pool {
+	/** Locks the list */
+	spinlock_t prp_lock;
+	/** list of ptlrpc_request structs */
+	struct list_head prp_req_list;
+	/** Maximum message size that would fit into a rquest from this pool */
+	int prp_rq_size;
+	/** Function to allocate more requests for this pool */
+	void (*prp_populate)(struct ptlrpc_request_pool *, int);
+};
+
+struct lu_context;
+struct lu_env;
+
+struct ldlm_lock;
+
+/**
+ * \defgroup nrs Network Request Scheduler
+ * @{
+ */
+struct ptlrpc_nrs_policy;
+struct ptlrpc_nrs_resource;
+struct ptlrpc_nrs_request;
+
+/**
+ * NRS control operations.
+ *
+ * These are common for all policies.
+ */
+enum ptlrpc_nrs_ctl {
+	/**
+	 * Not a valid opcode.
+	 */
+	PTLRPC_NRS_CTL_INVALID,
+	/**
+	 * Activate the policy.
+	 */
+	PTLRPC_NRS_CTL_START,
+	/**
+	 * Reserved for multiple primary policies, which may be a possibility
+	 * in the future.
+	 */
+	PTLRPC_NRS_CTL_STOP,
+	/**
+	 * Policies can start using opcodes from this value and onwards for
+	 * their own purposes; the assigned value itself is arbitrary.
+	 */
+	PTLRPC_NRS_CTL_1ST_POL_SPEC = 0x20,
+};
+
+/**
+ * ORR policy operations
+ */
+enum nrs_ctl_orr {
+	NRS_CTL_ORR_RD_QUANTUM = PTLRPC_NRS_CTL_1ST_POL_SPEC,
+	NRS_CTL_ORR_WR_QUANTUM,
+	NRS_CTL_ORR_RD_OFF_TYPE,
+	NRS_CTL_ORR_WR_OFF_TYPE,
+	NRS_CTL_ORR_RD_SUPP_REQ,
+	NRS_CTL_ORR_WR_SUPP_REQ,
+};
+
+/**
+ * NRS policy operations.
+ *
+ * These determine the behaviour of a policy, and are called in response to
+ * NRS core events.
+ */
+struct ptlrpc_nrs_pol_ops {
+	/**
+	 * Called during policy registration; this operation is optional.
+	 *
+	 * \param[in,out] policy The policy being initialized
+	 */
+	int	(*op_policy_init) (struct ptlrpc_nrs_policy *policy);
+	/**
+	 * Called during policy unregistration; this operation is optional.
+	 *
+	 * \param[in,out] policy The policy being unregistered/finalized
+	 */
+	void	(*op_policy_fini) (struct ptlrpc_nrs_policy *policy);
+	/**
+	 * Called when activating a policy via lprocfs; policies allocate and
+	 * initialize their resources here; this operation is optional.
+	 *
+	 * \param[in,out] policy The policy being started
+	 *
+	 * \see nrs_policy_start_locked()
+	 */
+	int	(*op_policy_start) (struct ptlrpc_nrs_policy *policy);
+	/**
+	 * Called when deactivating a policy via lprocfs; policies deallocate
+	 * their resources here; this operation is optional
+	 *
+	 * \param[in,out] policy The policy being stopped
+	 *
+	 * \see nrs_policy_stop0()
+	 */
+	void	(*op_policy_stop) (struct ptlrpc_nrs_policy *policy);
+	/**
+	 * Used for policy-specific operations; i.e. not generic ones like
+	 * \e PTLRPC_NRS_CTL_START and \e PTLRPC_NRS_CTL_GET_INFO; analogous
+	 * to an ioctl; this operation is optional.
+	 *
+	 * \param[in,out]	 policy The policy carrying out operation \a opc
+	 * \param[in]	  opc	 The command operation being carried out
+	 * \param[in,out] arg	 An generic buffer for communication between the
+	 *			 user and the control operation
+	 *
+	 * \retval -ve error
+	 * \retval   0 success
+	 *
+	 * \see ptlrpc_nrs_policy_control()
+	 */
+	int	(*op_policy_ctl) (struct ptlrpc_nrs_policy *policy,
+				  enum ptlrpc_nrs_ctl opc, void *arg);
+
+	/**
+	 * Called when obtaining references to the resources of the resource
+	 * hierarchy for a request that has arrived for handling at the PTLRPC
+	 * service. Policies should return -ve for requests they do not wish
+	 * to handle. This operation is mandatory.
+	 *
+	 * \param[in,out] policy  The policy we're getting resources for.
+	 * \param[in,out] nrq	  The request we are getting resources for.
+	 * \param[in]	  parent  The parent resource of the resource being
+	 *			  requested; set to NULL if none.
+	 * \param[out]	  resp	  The resource is to be returned here; the
+	 *			  fallback policy in an NRS head should
+	 *			  \e always return a non-NULL pointer value.
+	 * \param[in]  moving_req When set, signifies that this is an attempt
+	 *			  to obtain resources for a request being moved
+	 *			  to the high-priority NRS head by
+	 *			  ldlm_lock_reorder_req().
+	 *			  This implies two things:
+	 *			  1. We are under obd_export::exp_rpc_lock and
+	 *			  so should not sleep.
+	 *			  2. We should not perform non-idempotent or can
+	 *			  skip performing idempotent operations that
+	 *			  were carried out when resources were first
+	 *			  taken for the request when it was initialized
+	 *			  in ptlrpc_nrs_req_initialize().
+	 *
+	 * \retval 0, +ve The level of the returned resource in the resource
+	 *		  hierarchy; currently only 0 (for a non-leaf resource)
+	 *		  and 1 (for a leaf resource) are supported by the
+	 *		  framework.
+	 * \retval -ve	  error
+	 *
+	 * \see ptlrpc_nrs_req_initialize()
+	 * \see ptlrpc_nrs_hpreq_add_nolock()
+	 * \see ptlrpc_nrs_req_hp_move()
+	 */
+	int	(*op_res_get) (struct ptlrpc_nrs_policy *policy,
+			       struct ptlrpc_nrs_request *nrq,
+			       const struct ptlrpc_nrs_resource *parent,
+			       struct ptlrpc_nrs_resource **resp,
+			       bool moving_req);
+	/**
+	 * Called when releasing references taken for resources in the resource
+	 * hierarchy for the request; this operation is optional.
+	 *
+	 * \param[in,out] policy The policy the resource belongs to
+	 * \param[in] res	 The resource to be freed
+	 *
+	 * \see ptlrpc_nrs_req_finalize()
+	 * \see ptlrpc_nrs_hpreq_add_nolock()
+	 * \see ptlrpc_nrs_req_hp_move()
+	 */
+	void	(*op_res_put) (struct ptlrpc_nrs_policy *policy,
+			       const struct ptlrpc_nrs_resource *res);
+
+	/**
+	 * Obtains a request for handling from the policy, and optionally
+	 * removes the request from the policy; this operation is mandatory.
+	 *
+	 * \param[in,out] policy The policy to poll
+	 * \param[in]	  peek	 When set, signifies that we just want to
+	 *			 examine the request, and not handle it, so the
+	 *			 request is not removed from the policy.
+	 * \param[in]	  force	 When set, it will force a policy to return a
+	 *			 request if it has one queued.
+	 *
+	 * \retval NULL No request available for handling
+	 * \retval valid-pointer The request polled for handling
+	 *
+	 * \see ptlrpc_nrs_req_get_nolock()
+	 */
+	struct ptlrpc_nrs_request *
+		(*op_req_get) (struct ptlrpc_nrs_policy *policy, bool peek,
+			       bool force);
+	/**
+	 * Called when attempting to add a request to a policy for later
+	 * handling; this operation is mandatory.
+	 *
+	 * \param[in,out] policy  The policy on which to enqueue \a nrq
+	 * \param[in,out] nrq The request to enqueue
+	 *
+	 * \retval 0	success
+	 * \retval != 0	error
+	 *
+	 * \see ptlrpc_nrs_req_add_nolock()
+	 */
+	int	(*op_req_enqueue) (struct ptlrpc_nrs_policy *policy,
+				   struct ptlrpc_nrs_request *nrq);
+	/**
+	 * Removes a request from the policy's set of pending requests. Normally
+	 * called after a request has been polled successfully from the policy
+	 * for handling; this operation is mandatory.
+	 *
+	 * \param[in,out] policy The policy the request \a nrq belongs to
+	 * \param[in,out] nrq    The request to dequeue
+	 *
+	 * \see ptlrpc_nrs_req_del_nolock()
+	 */
+	void	(*op_req_dequeue) (struct ptlrpc_nrs_policy *policy,
+				   struct ptlrpc_nrs_request *nrq);
+	/**
+	 * Called after the request being carried out. Could be used for
+	 * job/resource control; this operation is optional.
+	 *
+	 * \param[in,out] policy The policy which is stopping to handle request
+	 *			 \a nrq
+	 * \param[in,out] nrq	 The request
+	 *
+	 * \pre spin_is_locked(&svcpt->scp_req_lock)
+	 *
+	 * \see ptlrpc_nrs_req_stop_nolock()
+	 */
+	void	(*op_req_stop) (struct ptlrpc_nrs_policy *policy,
+				struct ptlrpc_nrs_request *nrq);
+	/**
+	 * Registers the policy's lprocfs interface with a PTLRPC service.
+	 *
+	 * \param[in] svc The service
+	 *
+	 * \retval 0	success
+	 * \retval != 0	error
+	 */
+	int	(*op_lprocfs_init) (struct ptlrpc_service *svc);
+	/**
+	 * Unegisters the policy's lprocfs interface with a PTLRPC service.
+	 *
+	 * In cases of failed policy registration in
+	 * \e ptlrpc_nrs_policy_register(), this function may be called for a
+	 * service which has not registered the policy successfully, so
+	 * implementations of this method should make sure their operations are
+	 * safe in such cases.
+	 *
+	 * \param[in] svc The service
+	 */
+	void	(*op_lprocfs_fini) (struct ptlrpc_service *svc);
+};
+
+/**
+ * Policy flags
+ */
+enum nrs_policy_flags {
+	/**
+	 * Fallback policy, use this flag only on a single supported policy per
+	 * service. The flag cannot be used on policies that use
+	 * \e PTLRPC_NRS_FL_REG_EXTERN
+	 */
+	PTLRPC_NRS_FL_FALLBACK		= (1 << 0),
+	/**
+	 * Start policy immediately after registering.
+	 */
+	PTLRPC_NRS_FL_REG_START		= (1 << 1),
+	/**
+	 * This is a policy registering from a module different to the one NRS
+	 * core ships in (currently ptlrpc).
+	 */
+	PTLRPC_NRS_FL_REG_EXTERN	= (1 << 2),
+};
+
+/**
+ * NRS queue type.
+ *
+ * Denotes whether an NRS instance is for handling normal or high-priority
+ * RPCs, or whether an operation pertains to one or both of the NRS instances
+ * in a service.
+ */
+enum ptlrpc_nrs_queue_type {
+	PTLRPC_NRS_QUEUE_REG	= (1 << 0),
+	PTLRPC_NRS_QUEUE_HP	= (1 << 1),
+	PTLRPC_NRS_QUEUE_BOTH	= (PTLRPC_NRS_QUEUE_REG | PTLRPC_NRS_QUEUE_HP)
+};
+
+/**
+ * NRS head
+ *
+ * A PTLRPC service has at least one NRS head instance for handling normal
+ * priority RPCs, and may optionally have a second NRS head instance for
+ * handling high-priority RPCs. Each NRS head maintains a list of available
+ * policies, of which one and only one policy is acting as the fallback policy,
+ * and optionally a different policy may be acting as the primary policy. For
+ * all RPCs handled by this NRS head instance, NRS core will first attempt to
+ * enqueue the RPC using the primary policy (if any). The fallback policy is
+ * used in the following cases:
+ * - when there was no primary policy in the
+ *   ptlrpc_nrs_pol_state::NRS_POL_STATE_STARTED state at the time the request
+ *   was initialized.
+ * - when the primary policy that was at the
+ *   ptlrpc_nrs_pol_state::PTLRPC_NRS_POL_STATE_STARTED state at the time the
+ *   RPC was initialized, denoted it did not wish, or for some other reason was
+ *   not able to handle the request, by returning a non-valid NRS resource
+ *   reference.
+ * - when the primary policy that was at the
+ *   ptlrpc_nrs_pol_state::PTLRPC_NRS_POL_STATE_STARTED state at the time the
+ *   RPC was initialized, fails later during the request enqueueing stage.
+ *
+ * \see nrs_resource_get_safe()
+ * \see nrs_request_enqueue()
+ */
+struct ptlrpc_nrs {
+	spinlock_t			nrs_lock;
+	/** XXX Possibly replace svcpt->scp_req_lock with another lock here. */
+	/**
+	 * List of registered policies
+	 */
+	struct list_head			nrs_policy_list;
+	/**
+	 * List of policies with queued requests. Policies that have any
+	 * outstanding requests are queued here, and this list is queried
+	 * in a round-robin manner from NRS core when obtaining a request
+	 * for handling. This ensures that requests from policies that at some
+	 * point transition away from the
+	 * ptlrpc_nrs_pol_state::NRS_POL_STATE_STARTED state are drained.
+	 */
+	struct list_head			nrs_policy_queued;
+	/**
+	 * Service partition for this NRS head
+	 */
+	struct ptlrpc_service_part     *nrs_svcpt;
+	/**
+	 * Primary policy, which is the preferred policy for handling RPCs
+	 */
+	struct ptlrpc_nrs_policy       *nrs_policy_primary;
+	/**
+	 * Fallback policy, which is the backup policy for handling RPCs
+	 */
+	struct ptlrpc_nrs_policy       *nrs_policy_fallback;
+	/**
+	 * This NRS head handles either HP or regular requests
+	 */
+	enum ptlrpc_nrs_queue_type	nrs_queue_type;
+	/**
+	 * # queued requests from all policies in this NRS head
+	 */
+	unsigned long			nrs_req_queued;
+	/**
+	 * # scheduled requests from all policies in this NRS head
+	 */
+	unsigned long			nrs_req_started;
+	/**
+	 * # policies on this NRS
+	 */
+	unsigned			nrs_num_pols;
+	/**
+	 * This NRS head is in progress of starting a policy
+	 */
+	unsigned			nrs_policy_starting:1;
+	/**
+	 * In progress of shutting down the whole NRS head; used during
+	 * unregistration
+	 */
+	unsigned			nrs_stopping:1;
+};
+
+#define NRS_POL_NAME_MAX		16
+
+struct ptlrpc_nrs_pol_desc;
+
+/**
+ * Service compatibility predicate; this determines whether a policy is adequate
+ * for handling RPCs of a particular PTLRPC service.
+ *
+ * XXX:This should give the same result during policy registration and
+ * unregistration, and for all partitions of a service; so the result should not
+ * depend on temporal service or other properties, that may influence the
+ * result.
+ */
+typedef bool (*nrs_pol_desc_compat_t) (const struct ptlrpc_service *svc,
+				       const struct ptlrpc_nrs_pol_desc *desc);
+
+struct ptlrpc_nrs_pol_conf {
+	/**
+	 * Human-readable policy name
+	 */
+	char				   nc_name[NRS_POL_NAME_MAX];
+	/**
+	 * NRS operations for this policy
+	 */
+	const struct ptlrpc_nrs_pol_ops	  *nc_ops;
+	/**
+	 * Service compatibility predicate
+	 */
+	nrs_pol_desc_compat_t		   nc_compat;
+	/**
+	 * Set for policies that support a single ptlrpc service, i.e. ones that
+	 * have \a pd_compat set to nrs_policy_compat_one(). The variable value
+	 * depicts the name of the single service that such policies are
+	 * compatible with.
+	 */
+	const char			  *nc_compat_svc_name;
+	/**
+	 * Owner module for this policy descriptor; policies registering from a
+	 * different module to the one the NRS framework is held within
+	 * (currently ptlrpc), should set this field to THIS_MODULE.
+	 */
+	module_t			  *nc_owner;
+	/**
+	 * Policy registration flags; a bitmast of \e nrs_policy_flags
+	 */
+	unsigned			   nc_flags;
+};
+
+/**
+ * NRS policy registering descriptor
+ *
+ * Is used to hold a description of a policy that can be passed to NRS core in
+ * order to register the policy with NRS heads in different PTLRPC services.
+ */
+struct ptlrpc_nrs_pol_desc {
+	/**
+	 * Human-readable policy name
+	 */
+	char					pd_name[NRS_POL_NAME_MAX];
+	/**
+	 * Link into nrs_core::nrs_policies
+	 */
+	struct list_head				pd_list;
+	/**
+	 * NRS operations for this policy
+	 */
+	const struct ptlrpc_nrs_pol_ops	       *pd_ops;
+	/**
+	 * Service compatibility predicate
+	 */
+	nrs_pol_desc_compat_t			pd_compat;
+	/**
+	 * Set for policies that are compatible with only one PTLRPC service.
+	 *
+	 * \see ptlrpc_nrs_pol_conf::nc_compat_svc_name
+	 */
+	const char			       *pd_compat_svc_name;
+	/**
+	 * Owner module for this policy descriptor.
+	 *
+	 * We need to hold a reference to the module whenever we might make use
+	 * of any of the module's contents, i.e.
+	 * - If one or more instances of the policy are at a state where they
+	 *   might be handling a request, i.e.
+	 *   ptlrpc_nrs_pol_state::NRS_POL_STATE_STARTED or
+	 *   ptlrpc_nrs_pol_state::NRS_POL_STATE_STOPPING as we will have to
+	 *   call into the policy's ptlrpc_nrs_pol_ops() handlers. A reference
+	 *   is taken on the module when
+	 *   \e ptlrpc_nrs_pol_desc::pd_refs becomes 1, and released when it
+	 *   becomes 0, so that we hold only one reference to the module maximum
+	 *   at any time.
+	 *
+	 *   We do not need to hold a reference to the module, even though we
+	 *   might use code and data from the module, in the following cases:
+	 * - During external policy registration, because this should happen in
+	 *   the module's init() function, in which case the module is safe from
+	 *   removal because a reference is being held on the module by the
+	 *   kernel, and iirc kmod (and I guess module-init-tools also) will
+	 *   serialize any racing processes properly anyway.
+	 * - During external policy unregistration, because this should happen
+	 *   in a module's exit() function, and any attempts to start a policy
+	 *   instance would need to take a reference on the module, and this is
+	 *   not possible once we have reached the point where the exit()
+	 *   handler is called.
+	 * - During service registration and unregistration, as service setup
+	 *   and cleanup, and policy registration, unregistration and policy
+	 *   instance starting, are serialized by \e nrs_core::nrs_mutex, so
+	 *   as long as users adhere to the convention of registering policies
+	 *   in init() and unregistering them in module exit() functions, there
+	 *   should not be a race between these operations.
+	 * - During any policy-specific lprocfs operations, because a reference
+	 *   is held by the kernel on a proc entry that has been entered by a
+	 *   syscall, so as long as proc entries are removed during unregistration time,
+	 *   then unregistration and lprocfs operations will be properly
+	 *   serialized.
+	 */
+	module_t			       *pd_owner;
+	/**
+	 * Bitmask of \e nrs_policy_flags
+	 */
+	unsigned				pd_flags;
+	/**
+	 * # of references on this descriptor
+	 */
+	atomic_t				pd_refs;
+};
+
+/**
+ * NRS policy state
+ *
+ * Policies transition from one state to the other during their lifetime
+ */
+enum ptlrpc_nrs_pol_state {
+	/**
+	 * Not a valid policy state.
+	 */
+	NRS_POL_STATE_INVALID,
+	/**
+	 * Policies are at this state either at the start of their life, or
+	 * transition here when the user selects a different policy to act
+	 * as the primary one.
+	 */
+	NRS_POL_STATE_STOPPED,
+	/**
+	 * Policy is progress of stopping
+	 */
+	NRS_POL_STATE_STOPPING,
+	/**
+	 * Policy is in progress of starting
+	 */
+	NRS_POL_STATE_STARTING,
+	/**
+	 * A policy is in this state in two cases:
+	 * - it is the fallback policy, which is always in this state.
+	 * - it has been activated by the user; i.e. it is the primary policy,
+	 */
+	NRS_POL_STATE_STARTED,
+};
+
+/**
+ * NRS policy information
+ *
+ * Used for obtaining information for the status of a policy via lprocfs
+ */
+struct ptlrpc_nrs_pol_info {
+	/**
+	 * Policy name
+	 */
+	char				pi_name[NRS_POL_NAME_MAX];
+	/**
+	 * Current policy state
+	 */
+	enum ptlrpc_nrs_pol_state	pi_state;
+	/**
+	 * # RPCs enqueued for later dispatching by the policy
+	 */
+	long				pi_req_queued;
+	/**
+	 * # RPCs started for dispatch by the policy
+	 */
+	long				pi_req_started;
+	/**
+	 * Is this a fallback policy?
+	 */
+	unsigned			pi_fallback:1;
+};
+
+/**
+ * NRS policy
+ *
+ * There is one instance of this for each policy in each NRS head of each
+ * PTLRPC service partition.
+ */
+struct ptlrpc_nrs_policy {
+	/**
+	 * Linkage into the NRS head's list of policies,
+	 * ptlrpc_nrs:nrs_policy_list
+	 */
+	struct list_head			pol_list;
+	/**
+	 * Linkage into the NRS head's list of policies with enqueued
+	 * requests ptlrpc_nrs:nrs_policy_queued
+	 */
+	struct list_head			pol_list_queued;
+	/**
+	 * Current state of this policy
+	 */
+	enum ptlrpc_nrs_pol_state	pol_state;
+	/**
+	 * Bitmask of nrs_policy_flags
+	 */
+	unsigned			pol_flags;
+	/**
+	 * # RPCs enqueued for later dispatching by the policy
+	 */
+	long				pol_req_queued;
+	/**
+	 * # RPCs started for dispatch by the policy
+	 */
+	long				pol_req_started;
+	/**
+	 * Usage Reference count taken on the policy instance
+	 */
+	long				pol_ref;
+	/**
+	 * The NRS head this policy has been created at
+	 */
+	struct ptlrpc_nrs	       *pol_nrs;
+	/**
+	 * Private policy data; varies by policy type
+	 */
+	void			       *pol_private;
+	/**
+	 * Policy descriptor for this policy instance.
+	 */
+	struct ptlrpc_nrs_pol_desc     *pol_desc;
+};
+
+/**
+ * NRS resource
+ *
+ * Resources are embedded into two types of NRS entities:
+ * - Inside NRS policies, in the policy's private data in
+ *   ptlrpc_nrs_policy::pol_private
+ * - In objects that act as prime-level scheduling entities in different NRS
+ *   policies; e.g. on a policy that performs round robin or similar order
+ *   scheduling across client NIDs, there would be one NRS resource per unique
+ *   client NID. On a policy which performs round robin scheduling across
+ *   backend filesystem objects, there would be one resource associated with
+ *   each of the backend filesystem objects partaking in the scheduling
+ *   performed by the policy.
+ *
+ * NRS resources share a parent-child relationship, in which resources embedded
+ * in policy instances are the parent entities, with all scheduling entities
+ * a policy schedules across being the children, thus forming a simple resource
+ * hierarchy. This hierarchy may be extended with one or more levels in the
+ * future if the ability to have more than one primary policy is added.
+ *
+ * Upon request initialization, references to the then active NRS policies are
+ * taken and used to later handle the dispatching of the request with one of
+ * these policies.
+ *
+ * \see nrs_resource_get_safe()
+ * \see ptlrpc_nrs_req_add()
+ */
+struct ptlrpc_nrs_resource {
+	/**
+	 * This NRS resource's parent; is NULL for resources embedded in NRS
+	 * policy instances; i.e. those are top-level ones.
+	 */
+	struct ptlrpc_nrs_resource     *res_parent;
+	/**
+	 * The policy associated with this resource.
+	 */
+	struct ptlrpc_nrs_policy       *res_policy;
+};
+
+enum {
+	NRS_RES_FALLBACK,
+	NRS_RES_PRIMARY,
+	NRS_RES_MAX
+};
+
+/* \name fifo
+ *
+ * FIFO policy
+ *
+ * This policy is a logical wrapper around previous, non-NRS functionality.
+ * It dispatches RPCs in the same order as they arrive from the network. This
+ * policy is currently used as the fallback policy, and the only enabled policy
+ * on all NRS heads of all PTLRPC service partitions.
+ * @{
+ */
+
+/**
+ * Private data structure for the FIFO policy
+ */
+struct nrs_fifo_head {
+	/**
+	 * Resource object for policy instance.
+	 */
+	struct ptlrpc_nrs_resource	fh_res;
+	/**
+	 * List of queued requests.
+	 */
+	struct list_head			fh_list;
+	/**
+	 * For debugging purposes.
+	 */
+	__u64				fh_sequence;
+};
+
+struct nrs_fifo_req {
+	struct list_head		fr_list;
+	__u64			fr_sequence;
+};
+
+/** @} fifo */
+
+/**
+ * \name CRR-N
+ *
+ * CRR-N, Client Round Robin over NIDs
+ * @{
+ */
+
+/**
+ * private data structure for CRR-N NRS
+ */
+struct nrs_crrn_net {
+	struct ptlrpc_nrs_resource	cn_res;
+	cfs_binheap_t		       *cn_binheap;
+	cfs_hash_t		       *cn_cli_hash;
+	/**
+	 * Used when a new scheduling round commences, in order to synchronize
+	 * all clients with the new round number.
+	 */
+	__u64				cn_round;
+	/**
+	 * Determines the relevant ordering amongst request batches within a
+	 * scheduling round.
+	 */
+	__u64				cn_sequence;
+	/**
+	 * Round Robin quantum; the maximum number of RPCs that each request
+	 * batch for each client can have in a scheduling round.
+	 */
+	__u16				cn_quantum;
+};
+
+/**
+ * Object representing a client in CRR-N, as identified by its NID
+ */
+struct nrs_crrn_client {
+	struct ptlrpc_nrs_resource	cc_res;
+	struct hlist_node		cc_hnode;
+	lnet_nid_t			cc_nid;
+	/**
+	 * The round number against which this client is currently scheduling
+	 * requests.
+	 */
+	__u64				cc_round;
+	/**
+	 * The sequence number used for requests scheduled by this client during
+	 * the current round number.
+	 */
+	__u64				cc_sequence;
+	atomic_t			cc_ref;
+	/**
+	 * Round Robin quantum; the maximum number of RPCs the client is allowed
+	 * to schedule in a single batch of each round.
+	 */
+	__u16				cc_quantum;
+	/**
+	 * # of pending requests for this client, on all existing rounds
+	 */
+	__u16				cc_active;
+};
+
+/**
+ * CRR-N NRS request definition
+ */
+struct nrs_crrn_req {
+	/**
+	 * Round number for this request; shared with all other requests in the
+	 * same batch.
+	 */
+	__u64			cr_round;
+	/**
+	 * Sequence number for this request; shared with all other requests in
+	 * the same batch.
+	 */
+	__u64			cr_sequence;
+};
+
+/**
+ * CRR-N policy operations.
+ */
+enum nrs_ctl_crr {
+	/**
+	 * Read the RR quantum size of a CRR-N policy.
+	 */
+	NRS_CTL_CRRN_RD_QUANTUM = PTLRPC_NRS_CTL_1ST_POL_SPEC,
+	/**
+	 * Write the RR quantum size of a CRR-N policy.
+	 */
+	NRS_CTL_CRRN_WR_QUANTUM,
+};
+
+/** @} CRR-N */
+
+/**
+ * \name ORR/TRR
+ *
+ * ORR/TRR (Object-based Round Robin/Target-based Round Robin) NRS policies
+ * @{
+ */
+
+/**
+ * Lower and upper byte offsets of a brw RPC
+ */
+struct nrs_orr_req_range {
+	__u64		or_start;
+	__u64		or_end;
+};
+
+/**
+ * RPC types supported by the ORR/TRR policies
+ */
+enum nrs_orr_supp {
+	NOS_OST_READ  = (1 << 0),
+	NOS_OST_WRITE = (1 << 1),
+	NOS_OST_RW    = (NOS_OST_READ | NOS_OST_WRITE),
+	/**
+	 * Default value for policies.
+	 */
+	NOS_DFLT      = NOS_OST_READ
+};
+
+/**
+ * As unique keys for grouping RPCs together, we use the object's OST FID for
+ * the ORR policy, and the OST index for the TRR policy.
+ *
+ * XXX: We waste some space for TRR policy instances by using a union, but it
+ *	allows to consolidate some of the code between ORR and TRR, and these
+ *	policies will probably eventually merge into one anyway.
+ */
+struct nrs_orr_key {
+	union {
+		/** object FID for ORR */
+		struct lu_fid	ok_fid;
+		/** OST index for TRR */
+		__u32		ok_idx;
+	};
+};
+
+/**
+ * The largest base string for unique hash/slab object names is
+ * "nrs_orr_reg_", so 13 characters. We add 3 to this to be used for the CPT
+ * id number, so this _should_ be more than enough for the maximum number of
+ * CPTs on any system. If it does happen that this statement is incorrect,
+ * nrs_orr_genobjname() will inevitably yield a non-unique name and cause
+ * kmem_cache_create() to complain (on Linux), so the erroneous situation
+ * will hopefully not go unnoticed.
+ */
+#define NRS_ORR_OBJ_NAME_MAX	(sizeof("nrs_orr_reg_") + 3)
+
+/**
+ * private data structure for ORR and TRR NRS
+ */
+struct nrs_orr_data {
+	struct ptlrpc_nrs_resource	od_res;
+	cfs_binheap_t		       *od_binheap;
+	cfs_hash_t		       *od_obj_hash;
+	struct kmem_cache		       *od_cache;
+	/**
+	 * Used when a new scheduling round commences, in order to synchronize
+	 * all object or OST batches with the new round number.
+	 */
+	__u64				od_round;
+	/**
+	 * Determines the relevant ordering amongst request batches within a
+	 * scheduling round.
+	 */
+	__u64				od_sequence;
+	/**
+	 * RPC types that are currently supported.
+	 */
+	enum nrs_orr_supp		od_supp;
+	/**
+	 * Round Robin quantum; the maxium number of RPCs that each request
+	 * batch for each object or OST can have in a scheduling round.
+	 */
+	__u16				od_quantum;
+	/**
+	 * Whether to use physical disk offsets or logical file offsets.
+	 */
+	bool				od_physical;
+	/**
+	 * XXX: We need to provide a persistently allocated string to hold
+	 * unique object names for this policy, since in currently supported
+	 * versions of Linux by Lustre, kmem_cache_create() just sets a pointer
+	 * to the name string provided. kstrdup() is used in the version of
+	 * kmeme_cache_create() in current Linux mainline, so we may be able to
+	 * remove this in the future.
+	 */
+	char				od_objname[NRS_ORR_OBJ_NAME_MAX];
+};
+
+/**
+ * Represents a backend-fs object or OST in the ORR and TRR policies
+ * respectively
+ */
+struct nrs_orr_object {
+	struct ptlrpc_nrs_resource	oo_res;
+	struct hlist_node		oo_hnode;
+	/**
+	 * The round number against which requests are being scheduled for this
+	 * object or OST
+	 */
+	__u64				oo_round;
+	/**
+	 * The sequence number used for requests scheduled for this object or
+	 * OST during the current round number.
+	 */
+	__u64				oo_sequence;
+	/**
+	 * The key of the object or OST for which this structure instance is
+	 * scheduling RPCs
+	 */
+	struct nrs_orr_key		oo_key;
+	atomic_t			oo_ref;
+	/**
+	 * Round Robin quantum; the maximum number of RPCs that are allowed to
+	 * be scheduled for the object or OST in a single batch of each round.
+	 */
+	__u16				oo_quantum;
+	/**
+	 * # of pending requests for this object or OST, on all existing rounds
+	 */
+	__u16				oo_active;
+};
+
+/**
+ * ORR/TRR NRS request definition
+ */
+struct nrs_orr_req {
+	/**
+	 * The offset range this request covers
+	 */
+	struct nrs_orr_req_range	or_range;
+	/**
+	 * Round number for this request; shared with all other requests in the
+	 * same batch.
+	 */
+	__u64				or_round;
+	/**
+	 * Sequence number for this request; shared with all other requests in
+	 * the same batch.
+	 */
+	__u64				or_sequence;
+	/**
+	 * For debugging purposes.
+	 */
+	struct nrs_orr_key		or_key;
+	/**
+	 * An ORR policy instance has filled in request information while
+	 * enqueueing the request on the service partition's regular NRS head.
+	 */
+	unsigned int			or_orr_set:1;
+	/**
+	 * A TRR policy instance has filled in request information while
+	 * enqueueing the request on the service partition's regular NRS head.
+	 */
+	unsigned int			or_trr_set:1;
+	/**
+	 * Request offset ranges have been filled in with logical offset
+	 * values.
+	 */
+	unsigned int			or_logical_set:1;
+	/**
+	 * Request offset ranges have been filled in with physical offset
+	 * values.
+	 */
+	unsigned int			or_physical_set:1;
+};
+
+/** @} ORR/TRR */
+
+/**
+ * NRS request
+ *
+ * Instances of this object exist embedded within ptlrpc_request; the main
+ * purpose of this object is to hold references to the request's resources
+ * for the lifetime of the request, and to hold properties that policies use
+ * use for determining the request's scheduling priority.
+ * */
+struct ptlrpc_nrs_request {
+	/**
+	 * The request's resource hierarchy.
+	 */
+	struct ptlrpc_nrs_resource     *nr_res_ptrs[NRS_RES_MAX];
+	/**
+	 * Index into ptlrpc_nrs_request::nr_res_ptrs of the resource of the
+	 * policy that was used to enqueue the request.
+	 *
+	 * \see nrs_request_enqueue()
+	 */
+	unsigned			nr_res_idx;
+	unsigned			nr_initialized:1;
+	unsigned			nr_enqueued:1;
+	unsigned			nr_started:1;
+	unsigned			nr_finalized:1;
+	cfs_binheap_node_t		nr_node;
+
+	/**
+	 * Policy-specific fields, used for determining a request's scheduling
+	 * priority, and other supporting functionality.
+	 */
+	union {
+		/**
+		 * Fields for the FIFO policy
+		 */
+		struct nrs_fifo_req	fifo;
+		/**
+		 * CRR-N request defintion
+		 */
+		struct nrs_crrn_req	crr;
+		/** ORR and TRR share the same request definition */
+		struct nrs_orr_req	orr;
+	} nr_u;
+	/**
+	 * Externally-registering policies may want to use this to allocate
+	 * their own request properties.
+	 */
+	void			       *ext;
+};
+
+/** @} nrs */
+
+/**
+ * Basic request prioritization operations structure.
+ * The whole idea is centered around locks and RPCs that might affect locks.
+ * When a lock is contended we try to give priority to RPCs that might lead
+ * to fastest release of that lock.
+ * Currently only implemented for OSTs only in a way that makes all
+ * IO and truncate RPCs that are coming from a locked region where a lock is
+ * contended a priority over other requests.
+ */
+struct ptlrpc_hpreq_ops {
+	/**
+	 * Check if the lock handle of the given lock is the same as
+	 * taken from the request.
+	 */
+	int  (*hpreq_lock_match)(struct ptlrpc_request *, struct ldlm_lock *);
+	/**
+	 * Check if the request is a high priority one.
+	 */
+	int  (*hpreq_check)(struct ptlrpc_request *);
+	/**
+	 * Called after the request has been handled.
+	 */
+	void (*hpreq_fini)(struct ptlrpc_request *);
+};
+
+/**
+ * Represents remote procedure call.
+ *
+ * This is a staple structure used by everybody wanting to send a request
+ * in Lustre.
+ */
+struct ptlrpc_request {
+	/* Request type: one of PTL_RPC_MSG_* */
+	int rq_type;
+	/** Result of request processing */
+	int rq_status;
+	/**
+	 * Linkage item through which this request is included into
+	 * sending/delayed lists on client and into rqbd list on server
+	 */
+	struct list_head rq_list;
+	/**
+	 * Server side list of incoming unserved requests sorted by arrival
+	 * time.  Traversed from time to time to notice about to expire
+	 * requests and sent back "early replies" to clients to let them
+	 * know server is alive and well, just very busy to service their
+	 * requests in time
+	 */
+	struct list_head rq_timed_list;
+	/** server-side history, used for debuging purposes. */
+	struct list_head rq_history_list;
+	/** server-side per-export list */
+	struct list_head rq_exp_list;
+	/** server-side hp handlers */
+	struct ptlrpc_hpreq_ops *rq_ops;
+
+	/** initial thread servicing this request */
+	struct ptlrpc_thread *rq_svc_thread;
+
+	/** history sequence # */
+	__u64 rq_history_seq;
+	/** \addtogroup  nrs
+	 * @{
+	 */
+	/** stub for NRS request */
+	struct ptlrpc_nrs_request rq_nrq;
+	/** @} nrs */
+	/** the index of service's srv_at_array into which request is linked */
+	time_t rq_at_index;
+	/** Lock to protect request flags and some other important bits, like
+	 * rq_list
+	 */
+	spinlock_t rq_lock;
+	/** client-side flags are serialized by rq_lock */
+	unsigned int rq_intr:1, rq_replied:1, rq_err:1,
+		rq_timedout:1, rq_resend:1, rq_restart:1,
+		/**
+		 * when ->rq_replay is set, request is kept by the client even
+		 * after server commits corresponding transaction. This is
+		 * used for operations that require sequence of multiple
+		 * requests to be replayed. The only example currently is file
+		 * open/close. When last request in such a sequence is
+		 * committed, ->rq_replay is cleared on all requests in the
+		 * sequence.
+		 */
+		rq_replay:1,
+		rq_no_resend:1, rq_waiting:1, rq_receiving_reply:1,
+		rq_no_delay:1, rq_net_err:1, rq_wait_ctx:1,
+		rq_early:1, rq_must_unlink:1,
+		rq_memalloc:1,      /* req originated from "kswapd" */
+		/* server-side flags */
+		rq_packed_final:1,  /* packed final reply */
+		rq_hp:1,	    /* high priority RPC */
+		rq_at_linked:1,     /* link into service's srv_at_array */
+		rq_reply_truncate:1,
+		rq_committed:1,
+		/* whether the "rq_set" is a valid one */
+		rq_invalid_rqset:1,
+		rq_generation_set:1,
+		/* do not resend request on -EINPROGRESS */
+		rq_no_retry_einprogress:1,
+		/* allow the req to be sent if the import is in recovery
+		 * status */
+		rq_allow_replay:1;
+
+	unsigned int rq_nr_resend;
+
+	enum rq_phase rq_phase; /* one of RQ_PHASE_* */
+	enum rq_phase rq_next_phase; /* one of RQ_PHASE_* to be used next */
+	atomic_t rq_refcount;/* client-side refcount for SENT race,
+				    server-side refcounf for multiple replies */
+
+	/** Portal to which this request would be sent */
+	short rq_request_portal;  /* XXX FIXME bug 249 */
+	/** Portal where to wait for reply and where reply would be sent */
+	short rq_reply_portal;    /* XXX FIXME bug 249 */
+
+	/**
+	 * client-side:
+	 * !rq_truncate : # reply bytes actually received,
+	 *  rq_truncate : required repbuf_len for resend
+	 */
+	int rq_nob_received;
+	/** Request length */
+	int rq_reqlen;
+	/** Reply length */
+	int rq_replen;
+	/** Request message - what client sent */
+	struct lustre_msg *rq_reqmsg;
+	/** Reply message - server response */
+	struct lustre_msg *rq_repmsg;
+	/** Transaction number */
+	__u64 rq_transno;
+	/** xid */
+	__u64 rq_xid;
+	/**
+	 * List item to for replay list. Not yet commited requests get linked
+	 * there.
+	 * Also see \a rq_replay comment above.
+	 */
+	struct list_head rq_replay_list;
+
+	/**
+	 * security and encryption data
+	 * @{ */
+	struct ptlrpc_cli_ctx   *rq_cli_ctx;     /**< client's half ctx */
+	struct ptlrpc_svc_ctx   *rq_svc_ctx;     /**< server's half ctx */
+	struct list_head	       rq_ctx_chain;   /**< link to waited ctx */
+
+	struct sptlrpc_flavor    rq_flvr;	/**< for client & server */
+	enum lustre_sec_part     rq_sp_from;
+
+	/* client/server security flags */
+	unsigned int
+				 rq_ctx_init:1,      /* context initiation */
+				 rq_ctx_fini:1,      /* context destroy */
+				 rq_bulk_read:1,     /* request bulk read */
+				 rq_bulk_write:1,    /* request bulk write */
+				 /* server authentication flags */
+				 rq_auth_gss:1,      /* authenticated by gss */
+				 rq_auth_remote:1,   /* authed as remote user */
+				 rq_auth_usr_root:1, /* authed as root */
+				 rq_auth_usr_mdt:1,  /* authed as mdt */
+				 rq_auth_usr_ost:1,  /* authed as ost */
+				 /* security tfm flags */
+				 rq_pack_udesc:1,
+				 rq_pack_bulk:1,
+				 /* doesn't expect reply FIXME */
+				 rq_no_reply:1,
+				 rq_pill_init:1;     /* pill initialized */
+
+	uid_t		    rq_auth_uid;	/* authed uid */
+	uid_t		    rq_auth_mapped_uid; /* authed uid mapped to */
+
+	/* (server side), pointed directly into req buffer */
+	struct ptlrpc_user_desc *rq_user_desc;
+
+	/* various buffer pointers */
+	struct lustre_msg       *rq_reqbuf;      /* req wrapper */
+	char		    *rq_repbuf;      /* rep buffer */
+	struct lustre_msg       *rq_repdata;     /* rep wrapper msg */
+	struct lustre_msg       *rq_clrbuf;      /* only in priv mode */
+	int		      rq_reqbuf_len;  /* req wrapper buf len */
+	int		      rq_reqdata_len; /* req wrapper msg len */
+	int		      rq_repbuf_len;  /* rep buffer len */
+	int		      rq_repdata_len; /* rep wrapper msg len */
+	int		      rq_clrbuf_len;  /* only in priv mode */
+	int		      rq_clrdata_len; /* only in priv mode */
+
+	/** early replies go to offset 0, regular replies go after that */
+	unsigned int	     rq_reply_off;
+
+	/** @} */
+
+	/** Fields that help to see if request and reply were swabbed or not */
+	__u32 rq_req_swab_mask;
+	__u32 rq_rep_swab_mask;
+
+	/** What was import generation when this request was sent */
+	int rq_import_generation;
+	enum lustre_imp_state rq_send_state;
+
+	/** how many early replies (for stats) */
+	int rq_early_count;
+
+	/** client+server request */
+	lnet_handle_md_t     rq_req_md_h;
+	struct ptlrpc_cb_id  rq_req_cbid;
+	/** optional time limit for send attempts */
+	cfs_duration_t       rq_delay_limit;
+	/** time request was first queued */
+	cfs_time_t	   rq_queued_time;
+
+	/* server-side... */
+	/** request arrival time */
+	struct timeval       rq_arrival_time;
+	/** separated reply state */
+	struct ptlrpc_reply_state *rq_reply_state;
+	/** incoming request buffer */
+	struct ptlrpc_request_buffer_desc *rq_rqbd;
+
+	/** client-only incoming reply */
+	lnet_handle_md_t     rq_reply_md_h;
+	wait_queue_head_t	  rq_reply_waitq;
+	struct ptlrpc_cb_id  rq_reply_cbid;
+
+	/** our LNet NID */
+	lnet_nid_t	   rq_self;
+	/** Peer description (the other side) */
+	lnet_process_id_t    rq_peer;
+	/** Server-side, export on which request was received */
+	struct obd_export   *rq_export;
+	/** Client side, import where request is being sent */
+	struct obd_import   *rq_import;
+
+	/** Replay callback, called after request is replayed at recovery */
+	void (*rq_replay_cb)(struct ptlrpc_request *);
+	/**
+	 * Commit callback, called when request is committed and about to be
+	 * freed.
+	 */
+	void (*rq_commit_cb)(struct ptlrpc_request *);
+	/** Opaq data for replay and commit callbacks. */
+	void  *rq_cb_data;
+
+	/** For bulk requests on client only: bulk descriptor */
+	struct ptlrpc_bulk_desc *rq_bulk;
+
+	/** client outgoing req */
+	/**
+	 * when request/reply sent (secs), or time when request should be sent
+	 */
+	time_t rq_sent;
+	/** time for request really sent out */
+	time_t rq_real_sent;
+
+	/** when request must finish. volatile
+	 * so that servers' early reply updates to the deadline aren't
+	 * kept in per-cpu cache */
+	volatile time_t rq_deadline;
+	/** when req reply unlink must finish. */
+	time_t rq_reply_deadline;
+	/** when req bulk unlink must finish. */
+	time_t rq_bulk_deadline;
+	/**
+	 * service time estimate (secs)
+	 * If the requestsis not served by this time, it is marked as timed out.
+	 */
+	int    rq_timeout;
+
+	/** Multi-rpc bits */
+	/** Per-request waitq introduced by bug 21938 for recovery waiting */
+	wait_queue_head_t rq_set_waitq;
+	/** Link item for request set lists */
+	struct list_head  rq_set_chain;
+	/** Link back to the request set */
+	struct ptlrpc_request_set *rq_set;
+	/** Async completion handler, called when reply is received */
+	ptlrpc_interpterer_t rq_interpret_reply;
+	/** Async completion context */
+	union ptlrpc_async_args rq_async_args;
+
+	/** Pool if request is from preallocated list */
+	struct ptlrpc_request_pool *rq_pool;
+
+	struct lu_context	   rq_session;
+	struct lu_context	   rq_recov_session;
+
+	/** request format description */
+	struct req_capsule	  rq_pill;
+};
+
+/**
+ * Call completion handler for rpc if any, return it's status or original
+ * rc if there was no handler defined for this request.
+ */
+static inline int ptlrpc_req_interpret(const struct lu_env *env,
+				       struct ptlrpc_request *req, int rc)
+{
+	if (req->rq_interpret_reply != NULL) {
+		req->rq_status = req->rq_interpret_reply(env, req,
+							 &req->rq_async_args,
+							 rc);
+		return req->rq_status;
+	}
+	return rc;
+}
+
+/** \addtogroup  nrs
+ * @{
+ */
+int ptlrpc_nrs_policy_register(struct ptlrpc_nrs_pol_conf *conf);
+int ptlrpc_nrs_policy_unregister(struct ptlrpc_nrs_pol_conf *conf);
+void ptlrpc_nrs_req_hp_move(struct ptlrpc_request *req);
+void nrs_policy_get_info_locked(struct ptlrpc_nrs_policy *policy,
+				struct ptlrpc_nrs_pol_info *info);
+
+/*
+ * Can the request be moved from the regular NRS head to the high-priority NRS
+ * head (of the same PTLRPC service partition), if any?
+ *
+ * For a reliable result, this should be checked under svcpt->scp_req lock.
+ */
+static inline bool ptlrpc_nrs_req_can_move(struct ptlrpc_request *req)
+{
+	struct ptlrpc_nrs_request *nrq = &req->rq_nrq;
+
+	/**
+	 * LU-898: Check ptlrpc_nrs_request::nr_enqueued to make sure the
+	 * request has been enqueued first, and ptlrpc_nrs_request::nr_started
+	 * to make sure it has not been scheduled yet (analogous to previous
+	 * (non-NRS) checking of !list_empty(&ptlrpc_request::rq_list).
+	 */
+	return nrq->nr_enqueued && !nrq->nr_started && !req->rq_hp;
+}
+/** @} nrs */
+
+/**
+ * Returns 1 if request buffer at offset \a index was already swabbed
+ */
+static inline int lustre_req_swabbed(struct ptlrpc_request *req, int index)
+{
+	LASSERT(index < sizeof(req->rq_req_swab_mask) * 8);
+	return req->rq_req_swab_mask & (1 << index);
+}
+
+/**
+ * Returns 1 if request reply buffer at offset \a index was already swabbed
+ */
+static inline int lustre_rep_swabbed(struct ptlrpc_request *req, int index)
+{
+	LASSERT(index < sizeof(req->rq_rep_swab_mask) * 8);
+	return req->rq_rep_swab_mask & (1 << index);
+}
+
+/**
+ * Returns 1 if request needs to be swabbed into local cpu byteorder
+ */
+static inline int ptlrpc_req_need_swab(struct ptlrpc_request *req)
+{
+	return lustre_req_swabbed(req, MSG_PTLRPC_HEADER_OFF);
+}
+
+/**
+ * Returns 1 if request reply needs to be swabbed into local cpu byteorder
+ */
+static inline int ptlrpc_rep_need_swab(struct ptlrpc_request *req)
+{
+	return lustre_rep_swabbed(req, MSG_PTLRPC_HEADER_OFF);
+}
+
+/**
+ * Mark request buffer at offset \a index that it was already swabbed
+ */
+static inline void lustre_set_req_swabbed(struct ptlrpc_request *req, int index)
+{
+	LASSERT(index < sizeof(req->rq_req_swab_mask) * 8);
+	LASSERT((req->rq_req_swab_mask & (1 << index)) == 0);
+	req->rq_req_swab_mask |= 1 << index;
+}
+
+/**
+ * Mark request reply buffer at offset \a index that it was already swabbed
+ */
+static inline void lustre_set_rep_swabbed(struct ptlrpc_request *req, int index)
+{
+	LASSERT(index < sizeof(req->rq_rep_swab_mask) * 8);
+	LASSERT((req->rq_rep_swab_mask & (1 << index)) == 0);
+	req->rq_rep_swab_mask |= 1 << index;
+}
+
+/**
+ * Convert numerical request phase value \a phase into text string description
+ */
+static inline const char *
+ptlrpc_phase2str(enum rq_phase phase)
+{
+	switch (phase) {
+	case RQ_PHASE_NEW:
+		return "New";
+	case RQ_PHASE_RPC:
+		return "Rpc";
+	case RQ_PHASE_BULK:
+		return "Bulk";
+	case RQ_PHASE_INTERPRET:
+		return "Interpret";
+	case RQ_PHASE_COMPLETE:
+		return "Complete";
+	case RQ_PHASE_UNREGISTERING:
+		return "Unregistering";
+	default:
+		return "?Phase?";
+	}
+}
+
+/**
+ * Convert numerical request phase of the request \a req into text stringi
+ * description
+ */
+static inline const char *
+ptlrpc_rqphase2str(struct ptlrpc_request *req)
+{
+	return ptlrpc_phase2str(req->rq_phase);
+}
+
+/**
+ * Debugging functions and helpers to print request structure into debug log
+ * @{
+ */
+/* Spare the preprocessor, spoil the bugs. */
+#define FLAG(field, str) (field ? str : "")
+
+/** Convert bit flags into a string */
+#define DEBUG_REQ_FLAGS(req)						    \
+	ptlrpc_rqphase2str(req),						\
+	FLAG(req->rq_intr, "I"), FLAG(req->rq_replied, "R"),		    \
+	FLAG(req->rq_err, "E"),						 \
+	FLAG(req->rq_timedout, "X") /* eXpired */, FLAG(req->rq_resend, "S"),   \
+	FLAG(req->rq_restart, "T"), FLAG(req->rq_replay, "P"),		  \
+	FLAG(req->rq_no_resend, "N"),					   \
+	FLAG(req->rq_waiting, "W"),					     \
+	FLAG(req->rq_wait_ctx, "C"), FLAG(req->rq_hp, "H"),		     \
+	FLAG(req->rq_committed, "M")
+
+#define REQ_FLAGS_FMT "%s:%s%s%s%s%s%s%s%s%s%s%s%s"
+
+void _debug_req(struct ptlrpc_request *req,
+		struct libcfs_debug_msg_data *data, const char *fmt, ...)
+	__attribute__ ((format (printf, 3, 4)));
+
+/**
+ * Helper that decides if we need to print request accordig to current debug
+ * level settings
+ */
+#define debug_req(msgdata, mask, cdls, req, fmt, a...)			\
+do {									  \
+	CFS_CHECK_STACK(msgdata, mask, cdls);				 \
+									      \
+	if (((mask) & D_CANTMASK) != 0 ||				     \
+	    ((libcfs_debug & (mask)) != 0 &&				  \
+	     (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0))		\
+		_debug_req((req), msgdata, fmt, ##a);			 \
+} while(0)
+
+/**
+ * This is the debug print function you need to use to print request sturucture
+ * content into lustre debug log.
+ * for most callers (level is a constant) this is resolved at compile time */
+#define DEBUG_REQ(level, req, fmt, args...)				   \
+do {									  \
+	if ((level) & (D_ERROR | D_WARNING)) {				\
+		static cfs_debug_limit_state_t cdls;			  \
+		LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, level, &cdls);	    \
+		debug_req(&msgdata, level, &cdls, req, "@@@ "fmt" ", ## args);\
+	} else {							      \
+		LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, level, NULL);	     \
+		debug_req(&msgdata, level, NULL, req, "@@@ "fmt" ", ## args); \
+	}								     \
+} while (0)
+/** @} */
+
+/**
+ * Structure that defines a single page of a bulk transfer
+ */
+struct ptlrpc_bulk_page {
+	/** Linkage to list of pages in a bulk */
+	struct list_head       bp_link;
+	/**
+	 * Number of bytes in a page to transfer starting from \a bp_pageoffset
+	 */
+	int	      bp_buflen;
+	/** offset within a page */
+	int	      bp_pageoffset;
+	/** The page itself */
+	struct page     *bp_page;
+};
+
+#define BULK_GET_SOURCE   0
+#define BULK_PUT_SINK     1
+#define BULK_GET_SINK     2
+#define BULK_PUT_SOURCE   3
+
+/**
+ * Definition of bulk descriptor.
+ * Bulks are special "Two phase" RPCs where initial request message
+ * is sent first and it is followed bt a transfer (o receiving) of a large
+ * amount of data to be settled into pages referenced from the bulk descriptors.
+ * Bulks transfers (the actual data following the small requests) are done
+ * on separate LNet portals.
+ * In lustre we use bulk transfers for READ and WRITE transfers from/to OSTs.
+ *  Another user is readpage for MDT.
+ */
+struct ptlrpc_bulk_desc {
+	/** completed with failure */
+	unsigned long bd_failure:1;
+	/** {put,get}{source,sink} */
+	unsigned long bd_type:2;
+	/** client side */
+	unsigned long bd_registered:1;
+	/** For serialization with callback */
+	spinlock_t bd_lock;
+	/** Import generation when request for this bulk was sent */
+	int bd_import_generation;
+	/** LNet portal for this bulk */
+	__u32 bd_portal;
+	/** Server side - export this bulk created for */
+	struct obd_export *bd_export;
+	/** Client side - import this bulk was sent on */
+	struct obd_import *bd_import;
+	/** Back pointer to the request */
+	struct ptlrpc_request *bd_req;
+	wait_queue_head_t	    bd_waitq;	/* server side only WQ */
+	int		    bd_iov_count;    /* # entries in bd_iov */
+	int		    bd_max_iov;      /* allocated size of bd_iov */
+	int		    bd_nob;	  /* # bytes covered */
+	int		    bd_nob_transferred; /* # bytes GOT/PUT */
+
+	__u64		  bd_last_xid;
+
+	struct ptlrpc_cb_id    bd_cbid;	 /* network callback info */
+	lnet_nid_t	     bd_sender;       /* stash event::sender */
+	int			bd_md_count;	/* # valid entries in bd_mds */
+	int			bd_md_max_brw;	/* max entries in bd_mds */
+	/** array of associated MDs */
+	lnet_handle_md_t	bd_mds[PTLRPC_BULK_OPS_COUNT];
+
+	/*
+	 * encrypt iov, size is either 0 or bd_iov_count.
+	 */
+	lnet_kiov_t	   *bd_enc_iov;
+
+	lnet_kiov_t	    bd_iov[0];
+};
+
+enum {
+	SVC_STOPPED     = 1 << 0,
+	SVC_STOPPING    = 1 << 1,
+	SVC_STARTING    = 1 << 2,
+	SVC_RUNNING     = 1 << 3,
+	SVC_EVENT       = 1 << 4,
+	SVC_SIGNAL      = 1 << 5,
+};
+
+#define PTLRPC_THR_NAME_LEN		32
+/**
+ * Definition of server service thread structure
+ */
+struct ptlrpc_thread {
+	/**
+	 * List of active threads in svc->srv_threads
+	 */
+	struct list_head t_link;
+	/**
+	 * thread-private data (preallocated memory)
+	 */
+	void *t_data;
+	__u32 t_flags;
+	/**
+	 * service thread index, from ptlrpc_start_threads
+	 */
+	unsigned int t_id;
+	/**
+	 * service thread pid
+	 */
+	pid_t t_pid;
+	/**
+	 * put watchdog in the structure per thread b=14840
+	 */
+	struct lc_watchdog *t_watchdog;
+	/**
+	 * the svc this thread belonged to b=18582
+	 */
+	struct ptlrpc_service_part	*t_svcpt;
+	wait_queue_head_t			t_ctl_waitq;
+	struct lu_env			*t_env;
+	char				t_name[PTLRPC_THR_NAME_LEN];
+};
+
+static inline int thread_is_init(struct ptlrpc_thread *thread)
+{
+	return thread->t_flags == 0;
+}
+
+static inline int thread_is_stopped(struct ptlrpc_thread *thread)
+{
+	return !!(thread->t_flags & SVC_STOPPED);
+}
+
+static inline int thread_is_stopping(struct ptlrpc_thread *thread)
+{
+	return !!(thread->t_flags & SVC_STOPPING);
+}
+
+static inline int thread_is_starting(struct ptlrpc_thread *thread)
+{
+	return !!(thread->t_flags & SVC_STARTING);
+}
+
+static inline int thread_is_running(struct ptlrpc_thread *thread)
+{
+	return !!(thread->t_flags & SVC_RUNNING);
+}
+
+static inline int thread_is_event(struct ptlrpc_thread *thread)
+{
+	return !!(thread->t_flags & SVC_EVENT);
+}
+
+static inline int thread_is_signal(struct ptlrpc_thread *thread)
+{
+	return !!(thread->t_flags & SVC_SIGNAL);
+}
+
+static inline void thread_clear_flags(struct ptlrpc_thread *thread, __u32 flags)
+{
+	thread->t_flags &= ~flags;
+}
+
+static inline void thread_set_flags(struct ptlrpc_thread *thread, __u32 flags)
+{
+	thread->t_flags = flags;
+}
+
+static inline void thread_add_flags(struct ptlrpc_thread *thread, __u32 flags)
+{
+	thread->t_flags |= flags;
+}
+
+static inline int thread_test_and_clear_flags(struct ptlrpc_thread *thread,
+					      __u32 flags)
+{
+	if (thread->t_flags & flags) {
+		thread->t_flags &= ~flags;
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * Request buffer descriptor structure.
+ * This is a structure that contains one posted request buffer for service.
+ * Once data land into a buffer, event callback creates actual request and
+ * notifies wakes one of the service threads to process new incoming request.
+ * More than one request can fit into the buffer.
+ */
+struct ptlrpc_request_buffer_desc {
+	/** Link item for rqbds on a service */
+	struct list_head	     rqbd_list;
+	/** History of requests for this buffer */
+	struct list_head	     rqbd_reqs;
+	/** Back pointer to service for which this buffer is registered */
+	struct ptlrpc_service_part *rqbd_svcpt;
+	/** LNet descriptor */
+	lnet_handle_md_t       rqbd_md_h;
+	int		    rqbd_refcount;
+	/** The buffer itself */
+	char		  *rqbd_buffer;
+	struct ptlrpc_cb_id    rqbd_cbid;
+	/**
+	 * This "embedded" request structure is only used for the
+	 * last request to fit into the buffer
+	 */
+	struct ptlrpc_request  rqbd_req;
+};
+
+typedef int  (*svc_handler_t)(struct ptlrpc_request *req);
+
+struct ptlrpc_service_ops {
+	/**
+	 * if non-NULL called during thread creation (ptlrpc_start_thread())
+	 * to initialize service specific per-thread state.
+	 */
+	int		(*so_thr_init)(struct ptlrpc_thread *thr);
+	/**
+	 * if non-NULL called during thread shutdown (ptlrpc_main()) to
+	 * destruct state created by ->srv_init().
+	 */
+	void		(*so_thr_done)(struct ptlrpc_thread *thr);
+	/**
+	 * Handler function for incoming requests for this service
+	 */
+	int		(*so_req_handler)(struct ptlrpc_request *req);
+	/**
+	 * function to determine priority of the request, it's called
+	 * on every new request
+	 */
+	int		(*so_hpreq_handler)(struct ptlrpc_request *);
+	/**
+	 * service-specific print fn
+	 */
+	void		(*so_req_printer)(void *, struct ptlrpc_request *);
+};
+
+#ifndef __cfs_cacheline_aligned
+/* NB: put it here for reducing patche dependence */
+# define __cfs_cacheline_aligned
+#endif
+
+/**
+ * How many high priority requests to serve before serving one normal
+ * priority request
+ */
+#define PTLRPC_SVC_HP_RATIO 10
+
+/**
+ * Definition of PortalRPC service.
+ * The service is listening on a particular portal (like tcp port)
+ * and perform actions for a specific server like IO service for OST
+ * or general metadata service for MDS.
+ */
+struct ptlrpc_service {
+	/** serialize /proc operations */
+	spinlock_t			srv_lock;
+	/** most often accessed fields */
+	/** chain thru all services */
+	struct list_head		      srv_list;
+	/** service operations table */
+	struct ptlrpc_service_ops	srv_ops;
+	/** only statically allocated strings here; we don't clean them */
+	char			   *srv_name;
+	/** only statically allocated strings here; we don't clean them */
+	char			   *srv_thread_name;
+	/** service thread list */
+	struct list_head		      srv_threads;
+	/** threads # should be created for each partition on initializing */
+	int				srv_nthrs_cpt_init;
+	/** limit of threads number for each partition */
+	int				srv_nthrs_cpt_limit;
+	/** Root of /proc dir tree for this service */
+	proc_dir_entry_t	   *srv_procroot;
+	/** Pointer to statistic data for this service */
+	struct lprocfs_stats	   *srv_stats;
+	/** # hp per lp reqs to handle */
+	int			     srv_hpreq_ratio;
+	/** biggest request to receive */
+	int			     srv_max_req_size;
+	/** biggest reply to send */
+	int			     srv_max_reply_size;
+	/** size of individual buffers */
+	int			     srv_buf_size;
+	/** # buffers to allocate in 1 group */
+	int			     srv_nbuf_per_group;
+	/** Local portal on which to receive requests */
+	__u32			   srv_req_portal;
+	/** Portal on the client to send replies to */
+	__u32			   srv_rep_portal;
+	/**
+	 * Tags for lu_context associated with this thread, see struct
+	 * lu_context.
+	 */
+	__u32			   srv_ctx_tags;
+	/** soft watchdog timeout multiplier */
+	int			     srv_watchdog_factor;
+	/** under unregister_service */
+	unsigned			srv_is_stopping:1;
+
+	/** max # request buffers in history per partition */
+	int				srv_hist_nrqbds_cpt_max;
+	/** number of CPTs this service bound on */
+	int				srv_ncpts;
+	/** CPTs array this service bound on */
+	__u32				*srv_cpts;
+	/** 2^srv_cptab_bits >= cfs_cpt_numbert(srv_cptable) */
+	int				srv_cpt_bits;
+	/** CPT table this service is running over */
+	struct cfs_cpt_table		*srv_cptable;
+	/**
+	 * partition data for ptlrpc service
+	 */
+	struct ptlrpc_service_part	*srv_parts[0];
+};
+
+/**
+ * Definition of PortalRPC service partition data.
+ * Although a service only has one instance of it right now, but we
+ * will have multiple instances very soon (instance per CPT).
+ *
+ * it has four locks:
+ * \a scp_lock
+ *    serialize operations on rqbd and requests waiting for preprocess
+ * \a scp_req_lock
+ *    serialize operations active requests sent to this portal
+ * \a scp_at_lock
+ *    serialize adaptive timeout stuff
+ * \a scp_rep_lock
+ *    serialize operations on RS list (reply states)
+ *
+ * We don't have any use-case to take two or more locks at the same time
+ * for now, so there is no lock order issue.
+ */
+struct ptlrpc_service_part {
+	/** back reference to owner */
+	struct ptlrpc_service		*scp_service __cfs_cacheline_aligned;
+	/* CPT id, reserved */
+	int				scp_cpt;
+	/** always increasing number */
+	int				scp_thr_nextid;
+	/** # of starting threads */
+	int				scp_nthrs_starting;
+	/** # of stopping threads, reserved for shrinking threads */
+	int				scp_nthrs_stopping;
+	/** # running threads */
+	int				scp_nthrs_running;
+	/** service threads list */
+	struct list_head			scp_threads;
+
+	/**
+	 * serialize the following fields, used for protecting
+	 * rqbd list and incoming requests waiting for preprocess,
+	 * threads starting & stopping are also protected by this lock.
+	 */
+	spinlock_t			scp_lock  __cfs_cacheline_aligned;
+	/** total # req buffer descs allocated */
+	int				scp_nrqbds_total;
+	/** # posted request buffers for receiving */
+	int				scp_nrqbds_posted;
+	/** in progress of allocating rqbd */
+	int				scp_rqbd_allocating;
+	/** # incoming reqs */
+	int				scp_nreqs_incoming;
+	/** request buffers to be reposted */
+	struct list_head			scp_rqbd_idle;
+	/** req buffers receiving */
+	struct list_head			scp_rqbd_posted;
+	/** incoming reqs */
+	struct list_head			scp_req_incoming;
+	/** timeout before re-posting reqs, in tick */
+	cfs_duration_t			scp_rqbd_timeout;
+	/**
+	 * all threads sleep on this. This wait-queue is signalled when new
+	 * incoming request arrives and when difficult reply has to be handled.
+	 */
+	wait_queue_head_t			scp_waitq;
+
+	/** request history */
+	struct list_head			scp_hist_reqs;
+	/** request buffer history */
+	struct list_head			scp_hist_rqbds;
+	/** # request buffers in history */
+	int				scp_hist_nrqbds;
+	/** sequence number for request */
+	__u64				scp_hist_seq;
+	/** highest seq culled from history */
+	__u64				scp_hist_seq_culled;
+
+	/**
+	 * serialize the following fields, used for processing requests
+	 * sent to this portal
+	 */
+	spinlock_t			scp_req_lock __cfs_cacheline_aligned;
+	/** # reqs in either of the NRS heads below */
+	/** # reqs being served */
+	int				scp_nreqs_active;
+	/** # HPreqs being served */
+	int				scp_nhreqs_active;
+	/** # hp requests handled */
+	int				scp_hreq_count;
+
+	/** NRS head for regular requests */
+	struct ptlrpc_nrs		scp_nrs_reg;
+	/** NRS head for HP requests; this is only valid for services that can
+	 *  handle HP requests */
+	struct ptlrpc_nrs	       *scp_nrs_hp;
+
+	/** AT stuff */
+	/** @{ */
+	/**
+	 * serialize the following fields, used for changes on
+	 * adaptive timeout
+	 */
+	spinlock_t			scp_at_lock __cfs_cacheline_aligned;
+	/** estimated rpc service time */
+	struct adaptive_timeout		scp_at_estimate;
+	/** reqs waiting for replies */
+	struct ptlrpc_at_array		scp_at_array;
+	/** early reply timer */
+	timer_list_t			scp_at_timer;
+	/** debug */
+	cfs_time_t			scp_at_checktime;
+	/** check early replies */
+	unsigned			scp_at_check;
+	/** @} */
+
+	/**
+	 * serialize the following fields, used for processing
+	 * replies for this portal
+	 */
+	spinlock_t			scp_rep_lock __cfs_cacheline_aligned;
+	/** all the active replies */
+	struct list_head			scp_rep_active;
+	/** List of free reply_states */
+	struct list_head			scp_rep_idle;
+	/** waitq to run, when adding stuff to srv_free_rs_list */
+	wait_queue_head_t			scp_rep_waitq;
+	/** # 'difficult' replies */
+	atomic_t			scp_nreps_difficult;
+};
+
+#define ptlrpc_service_for_each_part(part, i, svc)			\
+	for (i = 0;							\
+	     i < (svc)->srv_ncpts &&					\
+	     (svc)->srv_parts != NULL &&				\
+	     ((part) = (svc)->srv_parts[i]) != NULL; i++)
+
+/**
+ * Declaration of ptlrpcd control structure
+ */
+struct ptlrpcd_ctl {
+	/**
+	 * Ptlrpc thread control flags (LIOD_START, LIOD_STOP, LIOD_FORCE)
+	 */
+	unsigned long			pc_flags;
+	/**
+	 * Thread lock protecting structure fields.
+	 */
+	spinlock_t			pc_lock;
+	/**
+	 * Start completion.
+	 */
+	struct completion		pc_starting;
+	/**
+	 * Stop completion.
+	 */
+	struct completion		pc_finishing;
+	/**
+	 * Thread requests set.
+	 */
+	struct ptlrpc_request_set  *pc_set;
+	/**
+	 * Thread name used in cfs_daemonize()
+	 */
+	char			pc_name[16];
+	/**
+	 * Environment for request interpreters to run in.
+	 */
+	struct lu_env	       pc_env;
+	/**
+	 * Index of ptlrpcd thread in the array.
+	 */
+	int			 pc_index;
+	/**
+	 * Number of the ptlrpcd's partners.
+	 */
+	int			 pc_npartners;
+	/**
+	 * Pointer to the array of partners' ptlrpcd_ctl structure.
+	 */
+	struct ptlrpcd_ctl	**pc_partners;
+	/**
+	 * Record the partner index to be processed next.
+	 */
+	int			 pc_cursor;
+};
+
+/* Bits for pc_flags */
+enum ptlrpcd_ctl_flags {
+	/**
+	 * Ptlrpc thread start flag.
+	 */
+	LIOD_START       = 1 << 0,
+	/**
+	 * Ptlrpc thread stop flag.
+	 */
+	LIOD_STOP	= 1 << 1,
+	/**
+	 * Ptlrpc thread force flag (only stop force so far).
+	 * This will cause aborting any inflight rpcs handled
+	 * by thread if LIOD_STOP is specified.
+	 */
+	LIOD_FORCE       = 1 << 2,
+	/**
+	 * This is a recovery ptlrpc thread.
+	 */
+	LIOD_RECOVERY    = 1 << 3,
+	/**
+	 * The ptlrpcd is bound to some CPU core.
+	 */
+	LIOD_BIND	= 1 << 4,
+};
+
+/**
+ * \addtogroup nrs
+ * @{
+ *
+ * Service compatibility function; the policy is compatible with all services.
+ *
+ * \param[in] svc  The service the policy is attempting to register with.
+ * \param[in] desc The policy descriptor
+ *
+ * \retval true The policy is compatible with the service
+ *
+ * \see ptlrpc_nrs_pol_desc::pd_compat()
+ */
+static inline bool nrs_policy_compat_all(const struct ptlrpc_service *svc,
+					 const struct ptlrpc_nrs_pol_desc *desc)
+{
+	return true;
+}
+
+/**
+ * Service compatibility function; the policy is compatible with only a specific
+ * service which is identified by its human-readable name at
+ * ptlrpc_service::srv_name.
+ *
+ * \param[in] svc  The service the policy is attempting to register with.
+ * \param[in] desc The policy descriptor
+ *
+ * \retval false The policy is not compatible with the service
+ * \retval true	 The policy is compatible with the service
+ *
+ * \see ptlrpc_nrs_pol_desc::pd_compat()
+ */
+static inline bool nrs_policy_compat_one(const struct ptlrpc_service *svc,
+					 const struct ptlrpc_nrs_pol_desc *desc)
+{
+	LASSERT(desc->pd_compat_svc_name != NULL);
+	return strcmp(svc->srv_name, desc->pd_compat_svc_name) == 0;
+}
+
+/** @} nrs */
+
+/* ptlrpc/events.c */
+extern lnet_handle_eq_t ptlrpc_eq_h;
+extern int ptlrpc_uuid_to_peer(struct obd_uuid *uuid,
+			       lnet_process_id_t *peer, lnet_nid_t *self);
+/**
+ * These callbacks are invoked by LNet when something happened to
+ * underlying buffer
+ * @{
+ */
+extern void request_out_callback(lnet_event_t *ev);
+extern void reply_in_callback(lnet_event_t *ev);
+extern void client_bulk_callback(lnet_event_t *ev);
+extern void request_in_callback(lnet_event_t *ev);
+extern void reply_out_callback(lnet_event_t *ev);
+/** @} */
+
+/* ptlrpc/connection.c */
+struct ptlrpc_connection *ptlrpc_connection_get(lnet_process_id_t peer,
+						lnet_nid_t self,
+						struct obd_uuid *uuid);
+int ptlrpc_connection_put(struct ptlrpc_connection *c);
+struct ptlrpc_connection *ptlrpc_connection_addref(struct ptlrpc_connection *);
+int ptlrpc_connection_init(void);
+void ptlrpc_connection_fini(void);
+extern lnet_pid_t ptl_get_pid(void);
+
+/* ptlrpc/niobuf.c */
+/**
+ * Actual interfacing with LNet to put/get/register/unregister stuff
+ * @{
+ */
+
+int ptlrpc_register_bulk(struct ptlrpc_request *req);
+int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async);
+
+static inline int ptlrpc_client_bulk_active(struct ptlrpc_request *req)
+{
+	struct ptlrpc_bulk_desc *desc;
+	int		      rc;
+
+	LASSERT(req != NULL);
+	desc = req->rq_bulk;
+
+	if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_BULK_UNLINK) &&
+	    req->rq_bulk_deadline > cfs_time_current_sec())
+		return 1;
+
+	if (!desc)
+		return 0;
+
+	spin_lock(&desc->bd_lock);
+	rc = desc->bd_md_count;
+	spin_unlock(&desc->bd_lock);
+	return rc;
+}
+
+#define PTLRPC_REPLY_MAYBE_DIFFICULT 0x01
+#define PTLRPC_REPLY_EARLY	   0x02
+int ptlrpc_send_reply(struct ptlrpc_request *req, int flags);
+int ptlrpc_reply(struct ptlrpc_request *req);
+int ptlrpc_send_error(struct ptlrpc_request *req, int difficult);
+int ptlrpc_error(struct ptlrpc_request *req);
+void ptlrpc_resend_req(struct ptlrpc_request *request);
+int ptlrpc_at_get_net_latency(struct ptlrpc_request *req);
+int ptl_send_rpc(struct ptlrpc_request *request, int noreply);
+int ptlrpc_register_rqbd(struct ptlrpc_request_buffer_desc *rqbd);
+/** @} */
+
+/* ptlrpc/client.c */
+/**
+ * Client-side portals API. Everything to send requests, receive replies,
+ * request queues, request management, etc.
+ * @{
+ */
+void ptlrpc_init_client(int req_portal, int rep_portal, char *name,
+			struct ptlrpc_client *);
+void ptlrpc_cleanup_client(struct obd_import *imp);
+struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid);
+
+int ptlrpc_queue_wait(struct ptlrpc_request *req);
+int ptlrpc_replay_req(struct ptlrpc_request *req);
+int ptlrpc_unregister_reply(struct ptlrpc_request *req, int async);
+void ptlrpc_restart_req(struct ptlrpc_request *req);
+void ptlrpc_abort_inflight(struct obd_import *imp);
+void ptlrpc_cleanup_imp(struct obd_import *imp);
+void ptlrpc_abort_set(struct ptlrpc_request_set *set);
+
+struct ptlrpc_request_set *ptlrpc_prep_set(void);
+struct ptlrpc_request_set *ptlrpc_prep_fcset(int max, set_producer_func func,
+					     void *arg);
+int ptlrpc_set_add_cb(struct ptlrpc_request_set *set,
+		      set_interpreter_func fn, void *data);
+int ptlrpc_set_next_timeout(struct ptlrpc_request_set *);
+int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set);
+int ptlrpc_set_wait(struct ptlrpc_request_set *);
+int ptlrpc_expired_set(void *data);
+void ptlrpc_interrupted_set(void *data);
+void ptlrpc_mark_interrupted(struct ptlrpc_request *req);
+void ptlrpc_set_destroy(struct ptlrpc_request_set *);
+void ptlrpc_set_add_req(struct ptlrpc_request_set *, struct ptlrpc_request *);
+void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
+			    struct ptlrpc_request *req);
+
+void ptlrpc_free_rq_pool(struct ptlrpc_request_pool *pool);
+void ptlrpc_add_rqs_to_pool(struct ptlrpc_request_pool *pool, int num_rq);
+
+struct ptlrpc_request_pool *
+ptlrpc_init_rq_pool(int, int,
+		    void (*populate_pool)(struct ptlrpc_request_pool *, int));
+
+void ptlrpc_at_set_req_timeout(struct ptlrpc_request *req);
+struct ptlrpc_request *ptlrpc_request_alloc(struct obd_import *imp,
+					    const struct req_format *format);
+struct ptlrpc_request *ptlrpc_request_alloc_pool(struct obd_import *imp,
+					    struct ptlrpc_request_pool *,
+					    const struct req_format *format);
+void ptlrpc_request_free(struct ptlrpc_request *request);
+int ptlrpc_request_pack(struct ptlrpc_request *request,
+			__u32 version, int opcode);
+struct ptlrpc_request *ptlrpc_request_alloc_pack(struct obd_import *imp,
+						const struct req_format *format,
+						__u32 version, int opcode);
+int ptlrpc_request_bufs_pack(struct ptlrpc_request *request,
+			     __u32 version, int opcode, char **bufs,
+			     struct ptlrpc_cli_ctx *ctx);
+struct ptlrpc_request *ptlrpc_prep_req(struct obd_import *imp, __u32 version,
+				       int opcode, int count, __u32 *lengths,
+				       char **bufs);
+struct ptlrpc_request *ptlrpc_prep_req_pool(struct obd_import *imp,
+					     __u32 version, int opcode,
+					    int count, __u32 *lengths, char **bufs,
+					    struct ptlrpc_request_pool *pool);
+void ptlrpc_req_finished(struct ptlrpc_request *request);
+void ptlrpc_req_finished_with_imp_lock(struct ptlrpc_request *request);
+struct ptlrpc_request *ptlrpc_request_addref(struct ptlrpc_request *req);
+struct ptlrpc_bulk_desc *ptlrpc_prep_bulk_imp(struct ptlrpc_request *req,
+					      unsigned npages, unsigned max_brw,
+					      unsigned type, unsigned portal);
+void __ptlrpc_free_bulk(struct ptlrpc_bulk_desc *bulk, int pin);
+static inline void ptlrpc_free_bulk_pin(struct ptlrpc_bulk_desc *bulk)
+{
+	__ptlrpc_free_bulk(bulk, 1);
+}
+static inline void ptlrpc_free_bulk_nopin(struct ptlrpc_bulk_desc *bulk)
+{
+	__ptlrpc_free_bulk(bulk, 0);
+}
+void __ptlrpc_prep_bulk_page(struct ptlrpc_bulk_desc *desc,
+			     struct page *page, int pageoffset, int len, int);
+static inline void ptlrpc_prep_bulk_page_pin(struct ptlrpc_bulk_desc *desc,
+					     struct page *page, int pageoffset,
+					     int len)
+{
+	__ptlrpc_prep_bulk_page(desc, page, pageoffset, len, 1);
+}
+
+static inline void ptlrpc_prep_bulk_page_nopin(struct ptlrpc_bulk_desc *desc,
+					       struct page *page, int pageoffset,
+					       int len)
+{
+	__ptlrpc_prep_bulk_page(desc, page, pageoffset, len, 0);
+}
+
+void ptlrpc_retain_replayable_request(struct ptlrpc_request *req,
+				      struct obd_import *imp);
+__u64 ptlrpc_next_xid(void);
+__u64 ptlrpc_sample_next_xid(void);
+__u64 ptlrpc_req_xid(struct ptlrpc_request *request);
+
+/* Set of routines to run a function in ptlrpcd context */
+void *ptlrpcd_alloc_work(struct obd_import *imp,
+			 int (*cb)(const struct lu_env *, void *), void *data);
+void ptlrpcd_destroy_work(void *handler);
+int ptlrpcd_queue_work(void *handler);
+
+/** @} */
+struct ptlrpc_service_buf_conf {
+	/* nbufs is buffers # to allocate when growing the pool */
+	unsigned int			bc_nbufs;
+	/* buffer size to post */
+	unsigned int			bc_buf_size;
+	/* portal to listed for requests on */
+	unsigned int			bc_req_portal;
+	/* portal of where to send replies to */
+	unsigned int			bc_rep_portal;
+	/* maximum request size to be accepted for this service */
+	unsigned int			bc_req_max_size;
+	/* maximum reply size this service can ever send */
+	unsigned int			bc_rep_max_size;
+};
+
+struct ptlrpc_service_thr_conf {
+	/* threadname should be 8 characters or less - 6 will be added on */
+	char				*tc_thr_name;
+	/* threads increasing factor for each CPU */
+	unsigned int			tc_thr_factor;
+	/* service threads # to start on each partition while initializing */
+	unsigned int			tc_nthrs_init;
+	/*
+	 * low water of threads # upper-limit on each partition while running,
+	 * service availability may be impacted if threads number is lower
+	 * than this value. It can be ZERO if the service doesn't require
+	 * CPU affinity or there is only one partition.
+	 */
+	unsigned int			tc_nthrs_base;
+	/* "soft" limit for total threads number */
+	unsigned int			tc_nthrs_max;
+	/* user specified threads number, it will be validated due to
+	 * other members of this structure. */
+	unsigned int			tc_nthrs_user;
+	/* set NUMA node affinity for service threads */
+	unsigned int			tc_cpu_affinity;
+	/* Tags for lu_context associated with service thread */
+	__u32				tc_ctx_tags;
+};
+
+struct ptlrpc_service_cpt_conf {
+	struct cfs_cpt_table		*cc_cptable;
+	/* string pattern to describe CPTs for a service */
+	char				*cc_pattern;
+};
+
+struct ptlrpc_service_conf {
+	/* service name */
+	char				*psc_name;
+	/* soft watchdog timeout multiplifier to print stuck service traces */
+	unsigned int			psc_watchdog_factor;
+	/* buffer information */
+	struct ptlrpc_service_buf_conf	psc_buf;
+	/* thread information */
+	struct ptlrpc_service_thr_conf	psc_thr;
+	/* CPU partition information */
+	struct ptlrpc_service_cpt_conf	psc_cpt;
+	/* function table */
+	struct ptlrpc_service_ops	psc_ops;
+};
+
+/* ptlrpc/service.c */
+/**
+ * Server-side services API. Register/unregister service, request state
+ * management, service thread management
+ *
+ * @{
+ */
+void ptlrpc_save_lock(struct ptlrpc_request *req,
+		      struct lustre_handle *lock, int mode, int no_ack);
+void ptlrpc_commit_replies(struct obd_export *exp);
+void ptlrpc_dispatch_difficult_reply(struct ptlrpc_reply_state *rs);
+void ptlrpc_schedule_difficult_reply(struct ptlrpc_reply_state *rs);
+int ptlrpc_hpreq_handler(struct ptlrpc_request *req);
+struct ptlrpc_service *ptlrpc_register_service(
+				struct ptlrpc_service_conf *conf,
+				struct proc_dir_entry *proc_entry);
+void ptlrpc_stop_all_threads(struct ptlrpc_service *svc);
+
+int ptlrpc_start_threads(struct ptlrpc_service *svc);
+int ptlrpc_unregister_service(struct ptlrpc_service *service);
+int liblustre_check_services(void *arg);
+void ptlrpc_daemonize(char *name);
+int ptlrpc_service_health_check(struct ptlrpc_service *);
+void ptlrpc_server_drop_request(struct ptlrpc_request *req);
+void ptlrpc_request_change_export(struct ptlrpc_request *req,
+				  struct obd_export *export);
+
+int ptlrpc_hr_init(void);
+void ptlrpc_hr_fini(void);
+
+/** @} */
+
+/* ptlrpc/import.c */
+/**
+ * Import API
+ * @{
+ */
+int ptlrpc_connect_import(struct obd_import *imp);
+int ptlrpc_init_import(struct obd_import *imp);
+int ptlrpc_disconnect_import(struct obd_import *imp, int noclose);
+int ptlrpc_import_recovery_state_machine(struct obd_import *imp);
+void deuuidify(char *uuid, const char *prefix, char **uuid_start,
+	       int *uuid_len);
+
+/* ptlrpc/pack_generic.c */
+int ptlrpc_reconnect_import(struct obd_import *imp);
+/** @} */
+
+/**
+ * ptlrpc msg buffer and swab interface
+ *
+ * @{
+ */
+int ptlrpc_buf_need_swab(struct ptlrpc_request *req, const int inout,
+			 int index);
+void ptlrpc_buf_set_swabbed(struct ptlrpc_request *req, const int inout,
+				int index);
+int ptlrpc_unpack_rep_msg(struct ptlrpc_request *req, int len);
+int ptlrpc_unpack_req_msg(struct ptlrpc_request *req, int len);
+
+int lustre_msg_check_version(struct lustre_msg *msg, __u32 version);
+void lustre_init_msg_v2(struct lustre_msg_v2 *msg, int count, __u32 *lens,
+			char **bufs);
+int lustre_pack_request(struct ptlrpc_request *, __u32 magic, int count,
+			__u32 *lens, char **bufs);
+int lustre_pack_reply(struct ptlrpc_request *, int count, __u32 *lens,
+		      char **bufs);
+int lustre_pack_reply_v2(struct ptlrpc_request *req, int count,
+			 __u32 *lens, char **bufs, int flags);
+#define LPRFL_EARLY_REPLY 1
+int lustre_pack_reply_flags(struct ptlrpc_request *, int count, __u32 *lens,
+			    char **bufs, int flags);
+int lustre_shrink_msg(struct lustre_msg *msg, int segment,
+		      unsigned int newlen, int move_data);
+void lustre_free_reply_state(struct ptlrpc_reply_state *rs);
+int __lustre_unpack_msg(struct lustre_msg *m, int len);
+int lustre_msg_hdr_size(__u32 magic, int count);
+int lustre_msg_size(__u32 magic, int count, __u32 *lengths);
+int lustre_msg_size_v2(int count, __u32 *lengths);
+int lustre_packed_msg_size(struct lustre_msg *msg);
+int lustre_msg_early_size(void);
+void *lustre_msg_buf_v2(struct lustre_msg_v2 *m, int n, int min_size);
+void *lustre_msg_buf(struct lustre_msg *m, int n, int minlen);
+int lustre_msg_buflen(struct lustre_msg *m, int n);
+void lustre_msg_set_buflen(struct lustre_msg *m, int n, int len);
+int lustre_msg_bufcount(struct lustre_msg *m);
+char *lustre_msg_string(struct lustre_msg *m, int n, int max_len);
+__u32 lustre_msghdr_get_flags(struct lustre_msg *msg);
+void lustre_msghdr_set_flags(struct lustre_msg *msg, __u32 flags);
+__u32 lustre_msg_get_flags(struct lustre_msg *msg);
+void lustre_msg_add_flags(struct lustre_msg *msg, int flags);
+void lustre_msg_set_flags(struct lustre_msg *msg, int flags);
+void lustre_msg_clear_flags(struct lustre_msg *msg, int flags);
+__u32 lustre_msg_get_op_flags(struct lustre_msg *msg);
+void lustre_msg_add_op_flags(struct lustre_msg *msg, int flags);
+void lustre_msg_set_op_flags(struct lustre_msg *msg, int flags);
+struct lustre_handle *lustre_msg_get_handle(struct lustre_msg *msg);
+__u32 lustre_msg_get_type(struct lustre_msg *msg);
+__u32 lustre_msg_get_version(struct lustre_msg *msg);
+void lustre_msg_add_version(struct lustre_msg *msg, int version);
+__u32 lustre_msg_get_opc(struct lustre_msg *msg);
+__u64 lustre_msg_get_last_xid(struct lustre_msg *msg);
+__u64 lustre_msg_get_last_committed(struct lustre_msg *msg);
+__u64 *lustre_msg_get_versions(struct lustre_msg *msg);
+__u64 lustre_msg_get_transno(struct lustre_msg *msg);
+__u64 lustre_msg_get_slv(struct lustre_msg *msg);
+__u32 lustre_msg_get_limit(struct lustre_msg *msg);
+void lustre_msg_set_slv(struct lustre_msg *msg, __u64 slv);
+void lustre_msg_set_limit(struct lustre_msg *msg, __u64 limit);
+int lustre_msg_get_status(struct lustre_msg *msg);
+__u32 lustre_msg_get_conn_cnt(struct lustre_msg *msg);
+int lustre_msg_is_v1(struct lustre_msg *msg);
+__u32 lustre_msg_get_magic(struct lustre_msg *msg);
+__u32 lustre_msg_get_timeout(struct lustre_msg *msg);
+__u32 lustre_msg_get_service_time(struct lustre_msg *msg);
+char *lustre_msg_get_jobid(struct lustre_msg *msg);
+__u32 lustre_msg_get_cksum(struct lustre_msg *msg);
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0)
+__u32 lustre_msg_calc_cksum(struct lustre_msg *msg, int compat18);
+#else
+# warning "remove checksum compatibility support for b1_8"
+__u32 lustre_msg_calc_cksum(struct lustre_msg *msg);
+#endif
+void lustre_msg_set_handle(struct lustre_msg *msg,struct lustre_handle *handle);
+void lustre_msg_set_type(struct lustre_msg *msg, __u32 type);
+void lustre_msg_set_opc(struct lustre_msg *msg, __u32 opc);
+void lustre_msg_set_last_xid(struct lustre_msg *msg, __u64 last_xid);
+void lustre_msg_set_last_committed(struct lustre_msg *msg,__u64 last_committed);
+void lustre_msg_set_versions(struct lustre_msg *msg, __u64 *versions);
+void lustre_msg_set_transno(struct lustre_msg *msg, __u64 transno);
+void lustre_msg_set_status(struct lustre_msg *msg, __u32 status);
+void lustre_msg_set_conn_cnt(struct lustre_msg *msg, __u32 conn_cnt);
+void ptlrpc_req_set_repsize(struct ptlrpc_request *req, int count, __u32 *sizes);
+void ptlrpc_request_set_replen(struct ptlrpc_request *req);
+void lustre_msg_set_timeout(struct lustre_msg *msg, __u32 timeout);
+void lustre_msg_set_service_time(struct lustre_msg *msg, __u32 service_time);
+void lustre_msg_set_jobid(struct lustre_msg *msg, char *jobid);
+void lustre_msg_set_cksum(struct lustre_msg *msg, __u32 cksum);
+
+static inline void
+lustre_shrink_reply(struct ptlrpc_request *req, int segment,
+		    unsigned int newlen, int move_data)
+{
+	LASSERT(req->rq_reply_state);
+	LASSERT(req->rq_repmsg);
+	req->rq_replen = lustre_shrink_msg(req->rq_repmsg, segment,
+					   newlen, move_data);
+}
+/** @} */
+
+/** Change request phase of \a req to \a new_phase */
+static inline void
+ptlrpc_rqphase_move(struct ptlrpc_request *req, enum rq_phase new_phase)
+{
+	if (req->rq_phase == new_phase)
+		return;
+
+	if (new_phase == RQ_PHASE_UNREGISTERING) {
+		req->rq_next_phase = req->rq_phase;
+		if (req->rq_import)
+			atomic_inc(&req->rq_import->imp_unregistering);
+	}
+
+	if (req->rq_phase == RQ_PHASE_UNREGISTERING) {
+		if (req->rq_import)
+			atomic_dec(&req->rq_import->imp_unregistering);
+	}
+
+	DEBUG_REQ(D_INFO, req, "move req \"%s\" -> \"%s\"",
+		  ptlrpc_rqphase2str(req), ptlrpc_phase2str(new_phase));
+
+	req->rq_phase = new_phase;
+}
+
+/**
+ * Returns true if request \a req got early reply and hard deadline is not met
+ */
+static inline int
+ptlrpc_client_early(struct ptlrpc_request *req)
+{
+	if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK) &&
+	    req->rq_reply_deadline > cfs_time_current_sec())
+		return 0;
+	return req->rq_early;
+}
+
+/**
+ * Returns true if we got real reply from server for this request
+ */
+static inline int
+ptlrpc_client_replied(struct ptlrpc_request *req)
+{
+	if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK) &&
+	    req->rq_reply_deadline > cfs_time_current_sec())
+		return 0;
+	return req->rq_replied;
+}
+
+/** Returns true if request \a req is in process of receiving server reply */
+static inline int
+ptlrpc_client_recv(struct ptlrpc_request *req)
+{
+	if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK) &&
+	    req->rq_reply_deadline > cfs_time_current_sec())
+		return 1;
+	return req->rq_receiving_reply;
+}
+
+static inline int
+ptlrpc_client_recv_or_unlink(struct ptlrpc_request *req)
+{
+	int rc;
+
+	spin_lock(&req->rq_lock);
+	if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_LONG_REPL_UNLINK) &&
+	    req->rq_reply_deadline > cfs_time_current_sec()) {
+		spin_unlock(&req->rq_lock);
+		return 1;
+	}
+	rc = req->rq_receiving_reply || req->rq_must_unlink;
+	spin_unlock(&req->rq_lock);
+	return rc;
+}
+
+static inline void
+ptlrpc_client_wake_req(struct ptlrpc_request *req)
+{
+	if (req->rq_set == NULL)
+		wake_up(&req->rq_reply_waitq);
+	else
+		wake_up(&req->rq_set->set_waitq);
+}
+
+static inline void
+ptlrpc_rs_addref(struct ptlrpc_reply_state *rs)
+{
+	LASSERT(atomic_read(&rs->rs_refcount) > 0);
+	atomic_inc(&rs->rs_refcount);
+}
+
+static inline void
+ptlrpc_rs_decref(struct ptlrpc_reply_state *rs)
+{
+	LASSERT(atomic_read(&rs->rs_refcount) > 0);
+	if (atomic_dec_and_test(&rs->rs_refcount))
+		lustre_free_reply_state(rs);
+}
+
+/* Should only be called once per req */
+static inline void ptlrpc_req_drop_rs(struct ptlrpc_request *req)
+{
+	if (req->rq_reply_state == NULL)
+		return; /* shouldn't occur */
+	ptlrpc_rs_decref(req->rq_reply_state);
+	req->rq_reply_state = NULL;
+	req->rq_repmsg = NULL;
+}
+
+static inline __u32 lustre_request_magic(struct ptlrpc_request *req)
+{
+	return lustre_msg_get_magic(req->rq_reqmsg);
+}
+
+static inline int ptlrpc_req_get_repsize(struct ptlrpc_request *req)
+{
+	switch (req->rq_reqmsg->lm_magic) {
+	case LUSTRE_MSG_MAGIC_V2:
+		return req->rq_reqmsg->lm_repsize;
+	default:
+		LASSERTF(0, "incorrect message magic: %08x\n",
+			 req->rq_reqmsg->lm_magic);
+		return -EFAULT;
+	}
+}
+
+static inline int ptlrpc_send_limit_expired(struct ptlrpc_request *req)
+{
+	if (req->rq_delay_limit != 0 &&
+	    cfs_time_before(cfs_time_add(req->rq_queued_time,
+					 cfs_time_seconds(req->rq_delay_limit)),
+			    cfs_time_current())) {
+		return 1;
+	}
+	return 0;
+}
+
+static inline int ptlrpc_no_resend(struct ptlrpc_request *req)
+{
+	if (!req->rq_no_resend && ptlrpc_send_limit_expired(req)) {
+		spin_lock(&req->rq_lock);
+		req->rq_no_resend = 1;
+		spin_unlock(&req->rq_lock);
+	}
+	return req->rq_no_resend;
+}
+
+static inline int
+ptlrpc_server_get_timeout(struct ptlrpc_service_part *svcpt)
+{
+	int at = AT_OFF ? 0 : at_get(&svcpt->scp_at_estimate);
+
+	return svcpt->scp_service->srv_watchdog_factor *
+	       max_t(int, at, obd_timeout);
+}
+
+static inline struct ptlrpc_service *
+ptlrpc_req2svc(struct ptlrpc_request *req)
+{
+	LASSERT(req->rq_rqbd != NULL);
+	return req->rq_rqbd->rqbd_svcpt->scp_service;
+}
+
+/* ldlm/ldlm_lib.c */
+/**
+ * Target client logic
+ * @{
+ */
+int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg);
+int client_obd_cleanup(struct obd_device *obddev);
+int client_connect_import(const struct lu_env *env,
+			  struct obd_export **exp, struct obd_device *obd,
+			  struct obd_uuid *cluuid, struct obd_connect_data *,
+			  void *localdata);
+int client_disconnect_export(struct obd_export *exp);
+int client_import_add_conn(struct obd_import *imp, struct obd_uuid *uuid,
+			   int priority);
+int client_import_del_conn(struct obd_import *imp, struct obd_uuid *uuid);
+int client_import_find_conn(struct obd_import *imp, lnet_nid_t peer,
+			    struct obd_uuid *uuid);
+int import_set_conn_priority(struct obd_import *imp, struct obd_uuid *uuid);
+void client_destroy_import(struct obd_import *imp);
+/** @} */
+
+
+/* ptlrpc/pinger.c */
+/**
+ * Pinger API (client side only)
+ * @{
+ */
+enum timeout_event {
+	TIMEOUT_GRANT = 1
+};
+struct timeout_item;
+typedef int (*timeout_cb_t)(struct timeout_item *, void *);
+int ptlrpc_pinger_add_import(struct obd_import *imp);
+int ptlrpc_pinger_del_import(struct obd_import *imp);
+int ptlrpc_add_timeout_client(int time, enum timeout_event event,
+			      timeout_cb_t cb, void *data,
+			      struct list_head *obd_list);
+int ptlrpc_del_timeout_client(struct list_head *obd_list,
+			      enum timeout_event event);
+struct ptlrpc_request * ptlrpc_prep_ping(struct obd_import *imp);
+int ptlrpc_obd_ping(struct obd_device *obd);
+cfs_time_t ptlrpc_suspend_wakeup_time(void);
+void ping_evictor_start(void);
+void ping_evictor_stop(void);
+int ptlrpc_check_and_wait_suspend(struct ptlrpc_request *req);
+void ptlrpc_pinger_ir_up(void);
+void ptlrpc_pinger_ir_down(void);
+/** @} */
+int ptlrpc_pinger_suppress_pings(void);
+
+/* ptlrpc daemon bind policy */
+typedef enum {
+	/* all ptlrpcd threads are free mode */
+	PDB_POLICY_NONE	  = 1,
+	/* all ptlrpcd threads are bound mode */
+	PDB_POLICY_FULL	  = 2,
+	/* <free1 bound1> <free2 bound2> ... <freeN boundN> */
+	PDB_POLICY_PAIR	  = 3,
+	/* <free1 bound1> <bound1 free2> ... <freeN boundN> <boundN free1>,
+	 * means each ptlrpcd[X] has two partners: thread[X-1] and thread[X+1].
+	 * If kernel supports NUMA, pthrpcd threads are binded and
+	 * grouped by NUMA node */
+	PDB_POLICY_NEIGHBOR      = 4,
+} pdb_policy_t;
+
+/* ptlrpc daemon load policy
+ * It is caller's duty to specify how to push the async RPC into some ptlrpcd
+ * queue, but it is not enforced, affected by "ptlrpcd_bind_policy". If it is
+ * "PDB_POLICY_FULL", then the RPC will be processed by the selected ptlrpcd,
+ * Otherwise, the RPC may be processed by the selected ptlrpcd or its partner,
+ * depends on which is scheduled firstly, to accelerate the RPC processing. */
+typedef enum {
+	/* on the same CPU core as the caller */
+	PDL_POLICY_SAME	 = 1,
+	/* within the same CPU partition, but not the same core as the caller */
+	PDL_POLICY_LOCAL	= 2,
+	/* round-robin on all CPU cores, but not the same core as the caller */
+	PDL_POLICY_ROUND	= 3,
+	/* the specified CPU core is preferred, but not enforced */
+	PDL_POLICY_PREFERRED    = 4,
+} pdl_policy_t;
+
+/* ptlrpc/ptlrpcd.c */
+void ptlrpcd_stop(struct ptlrpcd_ctl *pc, int force);
+void ptlrpcd_free(struct ptlrpcd_ctl *pc);
+void ptlrpcd_wake(struct ptlrpc_request *req);
+void ptlrpcd_add_req(struct ptlrpc_request *req, pdl_policy_t policy, int idx);
+void ptlrpcd_add_rqset(struct ptlrpc_request_set *set);
+int ptlrpcd_addref(void);
+void ptlrpcd_decref(void);
+
+/* ptlrpc/lproc_ptlrpc.c */
+/**
+ * procfs output related functions
+ * @{
+ */
+const char* ll_opcode2str(__u32 opcode);
+#ifdef LPROCFS
+void ptlrpc_lprocfs_register_obd(struct obd_device *obd);
+void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd);
+void ptlrpc_lprocfs_brw(struct ptlrpc_request *req, int bytes);
+#else
+static inline void ptlrpc_lprocfs_register_obd(struct obd_device *obd) {}
+static inline void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd) {}
+static inline void ptlrpc_lprocfs_brw(struct ptlrpc_request *req, int bytes) {}
+#endif
+/** @} */
+
+/* ptlrpc/llog_server.c */
+int llog_origin_handle_open(struct ptlrpc_request *req);
+int llog_origin_handle_destroy(struct ptlrpc_request *req);
+int llog_origin_handle_prev_block(struct ptlrpc_request *req);
+int llog_origin_handle_next_block(struct ptlrpc_request *req);
+int llog_origin_handle_read_header(struct ptlrpc_request *req);
+int llog_origin_handle_close(struct ptlrpc_request *req);
+int llog_origin_handle_cancel(struct ptlrpc_request *req);
+
+/* ptlrpc/llog_client.c */
+extern struct llog_operations llog_client_ops;
+
+/** @} net */
+
+#endif
+/** @} PtlRPC */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_param.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_param.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_param.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_param.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,121 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_param.h
+ *
+ * User-settable parameter keys
+ *
+ * Author: Nathan Rutman <nathan@clusterfs.com>
+ */
+
+#ifndef _LUSTRE_PARAM_H
+#define _LUSTRE_PARAM_H
+
+/** \defgroup param param
+ *
+ * @{
+ */
+
+/* For interoperability */
+struct cfg_interop_param {
+	char *old_param;
+	char *new_param;
+};
+
+/* obd_config.c */
+int class_find_param(char *buf, char *key, char **valp);
+struct cfg_interop_param *class_find_old_param(const char *param,
+					       struct cfg_interop_param *ptr);
+int class_get_next_param(char **params, char *copy);
+int class_match_param(char *buf, char *key, char **valp);
+int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh);
+int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh);
+int class_parse_net(char *buf, __u32 *net, char **endh);
+int class_match_nid(char *buf, char *key, lnet_nid_t nid);
+int class_match_net(char *buf, char *key, __u32 net);
+/* obd_mount.c */
+int do_lcfg(char *cfgname, lnet_nid_t nid, int cmd,
+	    char *s1, char *s2, char *s3, char *s4);
+
+
+
+/****************** User-settable parameter keys *********************/
+/* e.g.
+	tunefs.lustre --param="failover.node=192.168.0.13@tcp0" /dev/sda
+	lctl conf_param testfs-OST0000 failover.node=3@elan,192.168.0.3@tcp0
+		    ... testfs-MDT0000.lov.stripesize=4M
+		    ... testfs-OST0000.ost.client_cache_seconds=15
+		    ... testfs.sys.timeout=<secs>
+		    ... testfs.llite.max_read_ahead_mb=16
+*/
+
+/* System global or special params not handled in obd's proc
+ * See mgs_write_log_sys()
+ */
+#define PARAM_TIMEOUT	      "timeout="	  /* global */
+#define PARAM_LDLM_TIMEOUT	 "ldlm_timeout="     /* global */
+#define PARAM_AT_MIN	       "at_min="	   /* global */
+#define PARAM_AT_MAX	       "at_max="	   /* global */
+#define PARAM_AT_EXTRA	     "at_extra="	 /* global */
+#define PARAM_AT_EARLY_MARGIN      "at_early_margin="  /* global */
+#define PARAM_AT_HISTORY	   "at_history="       /* global */
+#define PARAM_JOBID_VAR		   "jobid_var="	       /* global */
+#define PARAM_MGSNODE	      "mgsnode="	  /* only at mounttime */
+#define PARAM_FAILNODE	     "failover.node="    /* add failover nid */
+#define PARAM_FAILMODE	     "failover.mode="    /* initial mount only */
+#define PARAM_ACTIVE	       "active="	   /* activate/deactivate */
+#define PARAM_NETWORK	      "network="	  /* bind on nid */
+#define PARAM_ID_UPCALL		"identity_upcall="  /* identity upcall */
+
+/* Prefixes for parameters handled by obd's proc methods (XXX_process_config) */
+#define PARAM_OST		  "ost."
+#define PARAM_OSC		  "osc."
+#define PARAM_MDT		  "mdt."
+#define PARAM_MDD		  "mdd."
+#define PARAM_MDC		  "mdc."
+#define PARAM_LLITE		"llite."
+#define PARAM_LOV		  "lov."
+#define PARAM_LOD		"lod."
+#define PARAM_OSP		"osp."
+#define PARAM_SYS		  "sys."	      /* global */
+#define PARAM_SRPC		 "srpc."
+#define PARAM_SRPC_FLVR	    "srpc.flavor."
+#define PARAM_SRPC_UDESC	   "srpc.udesc.cli2mdt"
+#define PARAM_SEC		  "security."
+#define PARAM_QUOTA		"quota."	    /* global */
+
+/** @} param */
+
+#endif /* _LUSTRE_PARAM_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_quota.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_quota.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_quota.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_quota.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,239 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LUSTRE_QUOTA_H
+#define _LUSTRE_QUOTA_H
+
+/** \defgroup quota quota
+ *
+ */
+
+#include <linux/lustre_quota.h>
+
+#include <dt_object.h>
+#include <lustre_fid.h>
+#include <lustre_dlm.h>
+
+#ifndef MAX_IQ_TIME
+#define MAX_IQ_TIME  604800     /* (7*24*60*60) 1 week */
+#endif
+
+#ifndef MAX_DQ_TIME
+#define MAX_DQ_TIME  604800     /* (7*24*60*60) 1 week */
+#endif
+
+struct lquota_id_info;
+struct lquota_trans;
+
+/* Gather all quota record type in an union that can be used to read any records
+ * from disk. All fields of these records must be 64-bit aligned, otherwise the
+ * OSD layer may swab them incorrectly. */
+union lquota_rec {
+	struct lquota_glb_rec	lqr_glb_rec;
+	struct lquota_slv_rec	lqr_slv_rec;
+	struct lquota_acct_rec	lqr_acct_rec;
+};
+
+/* Index features supported by the global index objects
+ * Only used for migration purpose and should be removed once on-disk migration
+ * is no longer needed */
+extern struct dt_index_features dt_quota_iusr_features;
+extern struct dt_index_features dt_quota_busr_features;
+extern struct dt_index_features dt_quota_igrp_features;
+extern struct dt_index_features dt_quota_bgrp_features;
+
+/* Name used in the configuration logs to identify the default metadata pool
+ * (composed of all the MDTs, with pool ID 0) and the default data pool (all
+ * the OSTs, with pool ID 0 too). */
+#define QUOTA_METAPOOL_NAME   "mdt="
+#define QUOTA_DATAPOOL_NAME   "ost="
+
+/*
+ * Quota Master Target support
+ */
+
+/* Request handlers for quota master operations.
+ * This is used by the MDT to pass quota/lock requests to the quota master
+ * target. This won't be needed any more once the QMT is a real target and
+ * does not rely any more on the MDT service threads and namespace. */
+struct qmt_handlers {
+	/* Handle quotactl request from client. */
+	int (*qmth_quotactl)(const struct lu_env *, struct lu_device *,
+			     struct obd_quotactl *);
+
+	/* Handle dqacq/dqrel request from slave. */
+	int (*qmth_dqacq)(const struct lu_env *, struct lu_device *,
+			  struct ptlrpc_request *);
+
+	/* LDLM intent policy associated with quota locks */
+	int (*qmth_intent_policy)(const struct lu_env *, struct lu_device *,
+				  struct ptlrpc_request *, struct ldlm_lock **,
+				  int);
+
+	/* Initialize LVB of ldlm resource associated with quota objects */
+	int (*qmth_lvbo_init)(struct lu_device *, struct ldlm_resource *);
+
+	/* Update LVB of ldlm resource associated with quota objects */
+	int (*qmth_lvbo_update)(struct lu_device *, struct ldlm_resource *,
+				struct ptlrpc_request *, int);
+
+	/* Return size of LVB to be packed in ldlm message */
+	int (*qmth_lvbo_size)(struct lu_device *, struct ldlm_lock *);
+
+	/* Fill request buffer with lvb */
+	int (*qmth_lvbo_fill)(struct lu_device *, struct ldlm_lock *, void *,
+			      int);
+
+	/* Free lvb associated with ldlm resource */
+	int (*qmth_lvbo_free)(struct lu_device *, struct ldlm_resource *);
+};
+
+/* actual handlers are defined in lustre/quota/qmt_handler.c */
+extern struct qmt_handlers qmt_hdls;
+
+/*
+ * Quota enforcement support on slaves
+ */
+
+struct qsd_instance;
+
+/* The quota slave feature is implemented under the form of a library.
+ * The API is the following:
+ *
+ * - qsd_init(): the user (mostly the OSD layer) should first allocate a qsd
+ *	       instance via qsd_init(). This creates all required structures
+ *	       to manage quota enforcement for this target and performs all
+ *	       low-level initialization which does not involve any lustre
+ *	       object. qsd_init() should typically be called when the OSD
+ *	       is being set up.
+ *
+ * - qsd_prepare(): This sets up on-disk objects associated with the quota slave
+ *		  feature and initiates the quota reintegration procedure if
+ *		  needed. qsd_prepare() should typically be called when
+ *		  ->ldo_prepare is invoked.
+ *
+ * - qsd_start(): a qsd instance should be started once recovery is completed
+ *		(i.e. when ->ldo_recovery_complete is called). This is used
+ *		to notify the qsd layer that quota should now be enforced
+ *		again via the qsd_op_begin/end functions. The last step of the
+ *		reintegration prodecure (namely usage reconciliation) will be
+ *		completed during start.
+ *
+ * - qsd_fini(): is used to release a qsd_instance structure allocated with
+ *	       qsd_init(). This releases all quota slave objects and frees the
+ *	       structures associated with the qsd_instance.
+ *
+ * - qsd_op_begin(): is used to enforce quota, it must be called in the
+ *		   declaration of each operation. qsd_op_end() should then be
+ *		   invoked later once all operations have been completed in
+ *		   order to release/adjust the quota space.
+ *		   Running qsd_op_begin() before qsd_start() isn't fatal and
+ *		   will return success.
+ *		   Once qsd_start() has been run, qsd_op_begin() will block
+ *		   until the reintegration procedure is completed.
+ *
+ * - qsd_op_end(): performs the post operation quota processing. This must be
+ *		 called after the operation transaction stopped.
+ *		 While qsd_op_begin() must be invoked each time a new
+ *		 operation is declared, qsd_op_end() should be called only
+ *		 once for the whole transaction.
+ *
+ * - qsd_op_adjust(): triggers pre-acquire/release if necessary.
+ *
+ * Below are the function prototypes to be used by OSD layer to manage quota
+ * enforcement. Arguments are documented where each function is defined.  */
+
+struct qsd_instance *qsd_init(const struct lu_env *, char *, struct dt_device *,
+			      proc_dir_entry_t *);
+int qsd_prepare(const struct lu_env *, struct qsd_instance *);
+int qsd_start(const struct lu_env *, struct qsd_instance *);
+void qsd_fini(const struct lu_env *, struct qsd_instance *);
+int qsd_op_begin(const struct lu_env *, struct qsd_instance *,
+		 struct lquota_trans *, struct lquota_id_info *, int *);
+void qsd_op_end(const struct lu_env *, struct qsd_instance *,
+		struct lquota_trans *);
+void qsd_op_adjust(const struct lu_env *, struct qsd_instance *,
+		   union lquota_id *, int);
+/* This is exported for the ldiskfs quota migration only,
+ * see convert_quota_file() */
+int lquota_disk_write_glb(const struct lu_env *, struct dt_object *,
+			  __u64, struct lquota_glb_rec *);
+
+/*
+ * Quota information attached to a transaction
+ */
+
+struct lquota_entry;
+
+struct lquota_id_info {
+	/* quota identifier */
+	union lquota_id		 lqi_id;
+
+	/* USRQUOTA or GRPQUOTA for now, could be expanded for
+	 * directory quota or other types later.  */
+	int			 lqi_type;
+
+	/* inodes or kbytes to be consumed or released, it could
+	 * be negative when releasing space.  */
+	long long		 lqi_space;
+
+	/* quota slave entry structure associated with this ID */
+	struct lquota_entry	*lqi_qentry;
+
+	/* whether we are reporting blocks or inodes */
+	bool			 lqi_is_blk;
+};
+
+/* Since we enforce only inode quota in meta pool (MDTs), and block quota in
+ * data pool (OSTs), there are at most 4 quota ids being enforced in a single
+ * transaction, which is chown transaction:
+ * original uid and gid, new uid and gid.
+ *
+ * This value might need to be revised when directory quota is added.  */
+#define QUOTA_MAX_TRANSIDS    4
+
+/* all qids involved in a single transaction */
+struct lquota_trans {
+	unsigned short		lqt_id_cnt;
+	struct lquota_id_info	lqt_ids[QUOTA_MAX_TRANSIDS];
+};
+
+/* flags for quota local enforcement */
+#define QUOTA_FL_OVER_USRQUOTA  0x01
+#define QUOTA_FL_OVER_GRPQUOTA  0x02
+#define QUOTA_FL_SYNC	   0x04
+
+#define IS_LQUOTA_RES(res)						\
+	(res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA ||	\
+	 res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA_GLB)
+
+/* helper function used by MDT & OFD to retrieve quota accounting information
+ * on slave */
+int lquotactl_slv(const struct lu_env *, struct dt_device *,
+		  struct obd_quotactl *);
+/** @} quota */
+#endif /* _LUSTRE_QUOTA_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_req_layout.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_req_layout.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_req_layout.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_req_layout.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,334 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lustre_req_layout.h
+ *
+ * Lustre Metadata Target (mdt) request handler
+ *
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ */
+
+#ifndef _LUSTRE_REQ_LAYOUT_H__
+#define _LUSTRE_REQ_LAYOUT_H__
+
+/** \defgroup req_layout req_layout
+ *
+ * @{
+ */
+
+struct req_msg_field;
+struct req_format;
+struct req_capsule;
+
+struct ptlrpc_request;
+
+enum req_location {
+	RCL_CLIENT,
+	RCL_SERVER,
+	RCL_NR
+};
+
+/* Maximal number of fields (buffers) in a request message. */
+#define REQ_MAX_FIELD_NR  9
+
+struct req_capsule {
+	struct ptlrpc_request   *rc_req;
+	const struct req_format *rc_fmt;
+	enum req_location	rc_loc;
+	__u32		    rc_area[RCL_NR][REQ_MAX_FIELD_NR];
+};
+
+#if !defined(__REQ_LAYOUT_USER__)
+
+/* struct ptlrpc_request, lustre_msg* */
+#include <lustre_net.h>
+
+void req_capsule_init(struct req_capsule *pill, struct ptlrpc_request *req,
+		      enum req_location location);
+void req_capsule_fini(struct req_capsule *pill);
+
+void req_capsule_set(struct req_capsule *pill, const struct req_format *fmt);
+void req_capsule_client_dump(struct req_capsule *pill);
+void req_capsule_server_dump(struct req_capsule *pill);
+void req_capsule_init_area(struct req_capsule *pill);
+int req_capsule_filled_sizes(struct req_capsule *pill, enum req_location loc);
+int  req_capsule_server_pack(struct req_capsule *pill);
+
+void *req_capsule_client_get(struct req_capsule *pill,
+			     const struct req_msg_field *field);
+void *req_capsule_client_swab_get(struct req_capsule *pill,
+				  const struct req_msg_field *field,
+				  void *swabber);
+void *req_capsule_client_sized_get(struct req_capsule *pill,
+				   const struct req_msg_field *field,
+				   int len);
+void *req_capsule_server_get(struct req_capsule *pill,
+			     const struct req_msg_field *field);
+void *req_capsule_server_sized_get(struct req_capsule *pill,
+				   const struct req_msg_field *field,
+				   int len);
+void *req_capsule_server_swab_get(struct req_capsule *pill,
+				  const struct req_msg_field *field,
+				  void *swabber);
+void *req_capsule_server_sized_swab_get(struct req_capsule *pill,
+					const struct req_msg_field *field,
+					int len, void *swabber);
+const void *req_capsule_other_get(struct req_capsule *pill,
+				  const struct req_msg_field *field);
+
+void req_capsule_set_size(struct req_capsule *pill,
+			  const struct req_msg_field *field,
+			  enum req_location loc, int size);
+int req_capsule_get_size(const struct req_capsule *pill,
+			  const struct req_msg_field *field,
+			  enum req_location loc);
+int req_capsule_msg_size(struct req_capsule *pill, enum req_location loc);
+int req_capsule_fmt_size(__u32 magic, const struct req_format *fmt,
+			 enum req_location loc);
+void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt);
+
+int req_capsule_has_field(const struct req_capsule *pill,
+			  const struct req_msg_field *field,
+			  enum req_location loc);
+int req_capsule_field_present(const struct req_capsule *pill,
+			      const struct req_msg_field *field,
+			      enum req_location loc);
+void req_capsule_shrink(struct req_capsule *pill,
+			const struct req_msg_field *field,
+			unsigned int newlen,
+			enum req_location loc);
+int req_capsule_server_grow(struct req_capsule *pill,
+			    const struct req_msg_field *field,
+			    unsigned int newlen);
+int  req_layout_init(void);
+void req_layout_fini(void);
+
+/* __REQ_LAYOUT_USER__ */
+#endif
+
+extern struct req_format RQF_OBD_PING;
+extern struct req_format RQF_OBD_SET_INFO;
+extern struct req_format RQF_SEC_CTX;
+extern struct req_format RQF_OBD_IDX_READ;
+/* MGS req_format */
+extern struct req_format RQF_MGS_TARGET_REG;
+extern struct req_format RQF_MGS_SET_INFO;
+extern struct req_format RQF_MGS_CONFIG_READ;
+/* fid/fld req_format */
+extern struct req_format RQF_SEQ_QUERY;
+extern struct req_format RQF_FLD_QUERY;
+/* MDS req_format */
+extern struct req_format RQF_MDS_CONNECT;
+extern struct req_format RQF_MDS_DISCONNECT;
+extern struct req_format RQF_MDS_STATFS;
+extern struct req_format RQF_MDS_GETSTATUS;
+extern struct req_format RQF_MDS_SYNC;
+extern struct req_format RQF_MDS_GETXATTR;
+extern struct req_format RQF_MDS_GETATTR;
+extern struct req_format RQF_UPDATE_OBJ;
+
+/*
+ * This is format of direct (non-intent) MDS_GETATTR_NAME request.
+ */
+extern struct req_format RQF_MDS_GETATTR_NAME;
+extern struct req_format RQF_MDS_CLOSE;
+extern struct req_format RQF_MDS_PIN;
+extern struct req_format RQF_MDS_UNPIN;
+extern struct req_format RQF_MDS_CONNECT;
+extern struct req_format RQF_MDS_DISCONNECT;
+extern struct req_format RQF_MDS_GET_INFO;
+extern struct req_format RQF_MDS_READPAGE;
+extern struct req_format RQF_MDS_WRITEPAGE;
+extern struct req_format RQF_MDS_IS_SUBDIR;
+extern struct req_format RQF_MDS_DONE_WRITING;
+extern struct req_format RQF_MDS_REINT;
+extern struct req_format RQF_MDS_REINT_CREATE;
+extern struct req_format RQF_MDS_REINT_CREATE_RMT_ACL;
+extern struct req_format RQF_MDS_REINT_CREATE_SLAVE;
+extern struct req_format RQF_MDS_REINT_CREATE_SYM;
+extern struct req_format RQF_MDS_REINT_OPEN;
+extern struct req_format RQF_MDS_REINT_UNLINK;
+extern struct req_format RQF_MDS_REINT_LINK;
+extern struct req_format RQF_MDS_REINT_RENAME;
+extern struct req_format RQF_MDS_REINT_SETATTR;
+extern struct req_format RQF_MDS_REINT_SETXATTR;
+extern struct req_format RQF_MDS_QUOTACHECK;
+extern struct req_format RQF_MDS_QUOTACTL;
+extern struct req_format RQF_QC_CALLBACK;
+extern struct req_format RQF_QUOTA_DQACQ;
+extern struct req_format RQF_MDS_SWAP_LAYOUTS;
+/* MDS hsm formats */
+extern struct req_format RQF_MDS_HSM_STATE_GET;
+extern struct req_format RQF_MDS_HSM_STATE_SET;
+extern struct req_format RQF_MDS_HSM_ACTION;
+extern struct req_format RQF_MDS_HSM_PROGRESS;
+extern struct req_format RQF_MDS_HSM_CT_REGISTER;
+extern struct req_format RQF_MDS_HSM_CT_UNREGISTER;
+extern struct req_format RQF_MDS_HSM_REQUEST;
+/* OST req_format */
+extern struct req_format RQF_OST_CONNECT;
+extern struct req_format RQF_OST_DISCONNECT;
+extern struct req_format RQF_OST_QUOTACHECK;
+extern struct req_format RQF_OST_QUOTACTL;
+extern struct req_format RQF_OST_GETATTR;
+extern struct req_format RQF_OST_SETATTR;
+extern struct req_format RQF_OST_CREATE;
+extern struct req_format RQF_OST_PUNCH;
+extern struct req_format RQF_OST_SYNC;
+extern struct req_format RQF_OST_DESTROY;
+extern struct req_format RQF_OST_BRW_READ;
+extern struct req_format RQF_OST_BRW_WRITE;
+extern struct req_format RQF_OST_STATFS;
+extern struct req_format RQF_OST_SET_GRANT_INFO;
+extern struct req_format RQF_OST_GET_INFO_GENERIC;
+extern struct req_format RQF_OST_GET_INFO_LAST_ID;
+extern struct req_format RQF_OST_GET_INFO_LAST_FID;
+extern struct req_format RQF_OST_SET_INFO_LAST_FID;
+extern struct req_format RQF_OST_GET_INFO_FIEMAP;
+
+/* LDLM req_format */
+extern struct req_format RQF_LDLM_ENQUEUE;
+extern struct req_format RQF_LDLM_ENQUEUE_LVB;
+extern struct req_format RQF_LDLM_CONVERT;
+extern struct req_format RQF_LDLM_INTENT;
+extern struct req_format RQF_LDLM_INTENT_BASIC;
+extern struct req_format RQF_LDLM_INTENT_LAYOUT;
+extern struct req_format RQF_LDLM_INTENT_GETATTR;
+extern struct req_format RQF_LDLM_INTENT_OPEN;
+extern struct req_format RQF_LDLM_INTENT_CREATE;
+extern struct req_format RQF_LDLM_INTENT_UNLINK;
+extern struct req_format RQF_LDLM_INTENT_QUOTA;
+extern struct req_format RQF_LDLM_CANCEL;
+extern struct req_format RQF_LDLM_CALLBACK;
+extern struct req_format RQF_LDLM_CP_CALLBACK;
+extern struct req_format RQF_LDLM_BL_CALLBACK;
+extern struct req_format RQF_LDLM_GL_CALLBACK;
+extern struct req_format RQF_LDLM_GL_DESC_CALLBACK;
+/* LOG req_format */
+extern struct req_format RQF_LOG_CANCEL;
+extern struct req_format RQF_LLOG_ORIGIN_HANDLE_CREATE;
+extern struct req_format RQF_LLOG_ORIGIN_HANDLE_DESTROY;
+extern struct req_format RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK;
+extern struct req_format RQF_LLOG_ORIGIN_HANDLE_PREV_BLOCK;
+extern struct req_format RQF_LLOG_ORIGIN_HANDLE_READ_HEADER;
+extern struct req_format RQF_LLOG_ORIGIN_CONNECT;
+
+extern struct req_msg_field RMF_GENERIC_DATA;
+extern struct req_msg_field RMF_PTLRPC_BODY;
+extern struct req_msg_field RMF_MDT_BODY;
+extern struct req_msg_field RMF_MDT_EPOCH;
+extern struct req_msg_field RMF_OBD_STATFS;
+extern struct req_msg_field RMF_NAME;
+extern struct req_msg_field RMF_SYMTGT;
+extern struct req_msg_field RMF_TGTUUID;
+extern struct req_msg_field RMF_CLUUID;
+extern struct req_msg_field RMF_SETINFO_VAL;
+extern struct req_msg_field RMF_SETINFO_KEY;
+extern struct req_msg_field RMF_GETINFO_VAL;
+extern struct req_msg_field RMF_GETINFO_VALLEN;
+extern struct req_msg_field RMF_GETINFO_KEY;
+extern struct req_msg_field RMF_IDX_INFO;
+
+/*
+ * connection handle received in MDS_CONNECT request.
+ */
+extern struct req_msg_field RMF_CONN;
+extern struct req_msg_field RMF_CONNECT_DATA;
+extern struct req_msg_field RMF_DLM_REQ;
+extern struct req_msg_field RMF_DLM_REP;
+extern struct req_msg_field RMF_DLM_LVB;
+extern struct req_msg_field RMF_DLM_GL_DESC;
+extern struct req_msg_field RMF_LDLM_INTENT;
+extern struct req_msg_field RMF_LAYOUT_INTENT;
+extern struct req_msg_field RMF_MDT_MD;
+extern struct req_msg_field RMF_REC_REINT;
+extern struct req_msg_field RMF_EADATA;
+extern struct req_msg_field RMF_ACL;
+extern struct req_msg_field RMF_LOGCOOKIES;
+extern struct req_msg_field RMF_CAPA1;
+extern struct req_msg_field RMF_CAPA2;
+extern struct req_msg_field RMF_OBD_QUOTACHECK;
+extern struct req_msg_field RMF_OBD_QUOTACTL;
+extern struct req_msg_field RMF_QUOTA_BODY;
+extern struct req_msg_field RMF_STRING;
+extern struct req_msg_field RMF_SWAP_LAYOUTS;
+extern struct req_msg_field RMF_MDS_HSM_PROGRESS;
+extern struct req_msg_field RMF_MDS_HSM_REQUEST;
+extern struct req_msg_field RMF_MDS_HSM_USER_ITEM;
+extern struct req_msg_field RMF_MDS_HSM_ARCHIVE;
+extern struct req_msg_field RMF_HSM_USER_STATE;
+extern struct req_msg_field RMF_HSM_STATE_SET;
+extern struct req_msg_field RMF_MDS_HSM_CURRENT_ACTION;
+extern struct req_msg_field RMF_MDS_HSM_REQUEST;
+
+/* seq-mgr fields */
+extern struct req_msg_field RMF_SEQ_OPC;
+extern struct req_msg_field RMF_SEQ_RANGE;
+extern struct req_msg_field RMF_FID_SPACE;
+
+/* FLD fields */
+extern struct req_msg_field RMF_FLD_OPC;
+extern struct req_msg_field RMF_FLD_MDFLD;
+
+extern struct req_msg_field RMF_LLOGD_BODY;
+extern struct req_msg_field RMF_LLOG_LOG_HDR;
+extern struct req_msg_field RMF_LLOGD_CONN_BODY;
+
+extern struct req_msg_field RMF_MGS_TARGET_INFO;
+extern struct req_msg_field RMF_MGS_SEND_PARAM;
+
+extern struct req_msg_field RMF_OST_BODY;
+extern struct req_msg_field RMF_OBD_IOOBJ;
+extern struct req_msg_field RMF_OBD_ID;
+extern struct req_msg_field RMF_FID;
+extern struct req_msg_field RMF_NIOBUF_REMOTE;
+extern struct req_msg_field RMF_RCS;
+extern struct req_msg_field RMF_FIEMAP_KEY;
+extern struct req_msg_field RMF_FIEMAP_VAL;
+extern struct req_msg_field RMF_OST_ID;
+
+/* MGS config read message format */
+extern struct req_msg_field RMF_MGS_CONFIG_BODY;
+extern struct req_msg_field RMF_MGS_CONFIG_RES;
+
+/* generic uint32 */
+extern struct req_msg_field RMF_U32;
+
+/* OBJ update format */
+extern struct req_msg_field RMF_UPDATE;
+extern struct req_msg_field RMF_UPDATE_REPLY;
+/** @} req_layout */
+
+#endif /* _LUSTRE_REQ_LAYOUT_H__ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_sec.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_sec.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_sec.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_sec.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1145 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LUSTRE_SEC_H_
+#define _LUSTRE_SEC_H_
+
+/** \defgroup sptlrpc sptlrpc
+ *
+ * @{
+ */
+
+/*
+ * to avoid include
+ */
+struct obd_import;
+struct obd_export;
+struct ptlrpc_request;
+struct ptlrpc_reply_state;
+struct ptlrpc_bulk_desc;
+struct brw_page;
+/* Linux specific */
+struct key;
+struct seq_file;
+
+/*
+ * forward declaration
+ */
+struct ptlrpc_sec_policy;
+struct ptlrpc_sec_cops;
+struct ptlrpc_sec_sops;
+struct ptlrpc_sec;
+struct ptlrpc_svc_ctx;
+struct ptlrpc_cli_ctx;
+struct ptlrpc_ctx_ops;
+
+/**
+ * \addtogroup flavor flavor
+ *
+ * RPC flavor is represented by a 32 bits integer. Currently the high 12 bits
+ * are unused, must be set to 0 for future expansion.
+ * <pre>
+ * ------------------------------------------------------------------------
+ * | 4b (bulk svc) | 4b (bulk type) | 4b (svc) | 4b (mech)  | 4b (policy) |
+ * ------------------------------------------------------------------------
+ * </pre>
+ *
+ * @{
+ */
+
+/*
+ * flavor constants
+ */
+enum sptlrpc_policy {
+	SPTLRPC_POLICY_NULL	     = 0,
+	SPTLRPC_POLICY_PLAIN	    = 1,
+	SPTLRPC_POLICY_GSS	      = 2,
+	SPTLRPC_POLICY_MAX,
+};
+
+enum sptlrpc_mech_null {
+	SPTLRPC_MECH_NULL	       = 0,
+	SPTLRPC_MECH_NULL_MAX,
+};
+
+enum sptlrpc_mech_plain {
+	SPTLRPC_MECH_PLAIN	      = 0,
+	SPTLRPC_MECH_PLAIN_MAX,
+};
+
+enum sptlrpc_mech_gss {
+	SPTLRPC_MECH_GSS_NULL	   = 0,
+	SPTLRPC_MECH_GSS_KRB5	   = 1,
+	SPTLRPC_MECH_GSS_MAX,
+};
+
+enum sptlrpc_service_type {
+	SPTLRPC_SVC_NULL		= 0,    /**< no security */
+	SPTLRPC_SVC_AUTH		= 1,    /**< authentication only */
+	SPTLRPC_SVC_INTG		= 2,    /**< integrity */
+	SPTLRPC_SVC_PRIV		= 3,    /**< privacy */
+	SPTLRPC_SVC_MAX,
+};
+
+enum sptlrpc_bulk_type {
+	SPTLRPC_BULK_DEFAULT	    = 0,    /**< follow rpc flavor */
+	SPTLRPC_BULK_HASH	       = 1,    /**< hash integrity */
+	SPTLRPC_BULK_MAX,
+};
+
+enum sptlrpc_bulk_service {
+	SPTLRPC_BULK_SVC_NULL	   = 0,    /**< no security */
+	SPTLRPC_BULK_SVC_AUTH	   = 1,    /**< authentication only */
+	SPTLRPC_BULK_SVC_INTG	   = 2,    /**< integrity */
+	SPTLRPC_BULK_SVC_PRIV	   = 3,    /**< privacy */
+	SPTLRPC_BULK_SVC_MAX,
+};
+
+/*
+ * compose/extract macros
+ */
+#define FLVR_POLICY_OFFSET	      (0)
+#define FLVR_MECH_OFFSET		(4)
+#define FLVR_SVC_OFFSET		 (8)
+#define FLVR_BULK_TYPE_OFFSET	   (12)
+#define FLVR_BULK_SVC_OFFSET	    (16)
+
+#define MAKE_FLVR(policy, mech, svc, btype, bsvc)		       \
+	(((__u32)(policy) << FLVR_POLICY_OFFSET) |		      \
+	 ((__u32)(mech) << FLVR_MECH_OFFSET) |			  \
+	 ((__u32)(svc) << FLVR_SVC_OFFSET) |			    \
+	 ((__u32)(btype) << FLVR_BULK_TYPE_OFFSET) |		    \
+	 ((__u32)(bsvc) << FLVR_BULK_SVC_OFFSET))
+
+/*
+ * extraction
+ */
+#define SPTLRPC_FLVR_POLICY(flavor)				     \
+	((((__u32)(flavor)) >> FLVR_POLICY_OFFSET) & 0xF)
+#define SPTLRPC_FLVR_MECH(flavor)				       \
+	((((__u32)(flavor)) >> FLVR_MECH_OFFSET) & 0xF)
+#define SPTLRPC_FLVR_SVC(flavor)					\
+	((((__u32)(flavor)) >> FLVR_SVC_OFFSET) & 0xF)
+#define SPTLRPC_FLVR_BULK_TYPE(flavor)				  \
+	((((__u32)(flavor)) >> FLVR_BULK_TYPE_OFFSET) & 0xF)
+#define SPTLRPC_FLVR_BULK_SVC(flavor)				   \
+	((((__u32)(flavor)) >> FLVR_BULK_SVC_OFFSET) & 0xF)
+
+#define SPTLRPC_FLVR_BASE(flavor)				       \
+	((((__u32)(flavor)) >> FLVR_POLICY_OFFSET) & 0xFFF)
+#define SPTLRPC_FLVR_BASE_SUB(flavor)				   \
+	((((__u32)(flavor)) >> FLVR_MECH_OFFSET) & 0xFF)
+
+/*
+ * gss subflavors
+ */
+#define MAKE_BASE_SUBFLVR(mech, svc)				    \
+	((__u32)(mech) |						\
+	 ((__u32)(svc) << (FLVR_SVC_OFFSET - FLVR_MECH_OFFSET)))
+
+#define SPTLRPC_SUBFLVR_KRB5N					   \
+	MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_NULL)
+#define SPTLRPC_SUBFLVR_KRB5A					   \
+	MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_AUTH)
+#define SPTLRPC_SUBFLVR_KRB5I					   \
+	MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_INTG)
+#define SPTLRPC_SUBFLVR_KRB5P					   \
+	MAKE_BASE_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_PRIV)
+
+/*
+ * "end user" flavors
+ */
+#define SPTLRPC_FLVR_NULL			       \
+	MAKE_FLVR(SPTLRPC_POLICY_NULL,		  \
+		  SPTLRPC_MECH_NULL,		    \
+		  SPTLRPC_SVC_NULL,		     \
+		  SPTLRPC_BULK_DEFAULT,		 \
+		  SPTLRPC_BULK_SVC_NULL)
+#define SPTLRPC_FLVR_PLAIN			      \
+	MAKE_FLVR(SPTLRPC_POLICY_PLAIN,		 \
+		  SPTLRPC_MECH_PLAIN,		   \
+		  SPTLRPC_SVC_NULL,		     \
+		  SPTLRPC_BULK_HASH,		    \
+		  SPTLRPC_BULK_SVC_INTG)
+#define SPTLRPC_FLVR_KRB5N			      \
+	MAKE_FLVR(SPTLRPC_POLICY_GSS,		   \
+		  SPTLRPC_MECH_GSS_KRB5,		\
+		  SPTLRPC_SVC_NULL,		     \
+		  SPTLRPC_BULK_DEFAULT,		 \
+		  SPTLRPC_BULK_SVC_NULL)
+#define SPTLRPC_FLVR_KRB5A			      \
+	MAKE_FLVR(SPTLRPC_POLICY_GSS,		   \
+		  SPTLRPC_MECH_GSS_KRB5,		\
+		  SPTLRPC_SVC_AUTH,		     \
+		  SPTLRPC_BULK_DEFAULT,		 \
+		  SPTLRPC_BULK_SVC_NULL)
+#define SPTLRPC_FLVR_KRB5I			      \
+	MAKE_FLVR(SPTLRPC_POLICY_GSS,		   \
+		  SPTLRPC_MECH_GSS_KRB5,		\
+		  SPTLRPC_SVC_INTG,		     \
+		  SPTLRPC_BULK_DEFAULT,		 \
+		  SPTLRPC_BULK_SVC_INTG)
+#define SPTLRPC_FLVR_KRB5P			      \
+	MAKE_FLVR(SPTLRPC_POLICY_GSS,		   \
+		  SPTLRPC_MECH_GSS_KRB5,		\
+		  SPTLRPC_SVC_PRIV,		     \
+		  SPTLRPC_BULK_DEFAULT,		 \
+		  SPTLRPC_BULK_SVC_PRIV)
+
+#define SPTLRPC_FLVR_DEFAULT	    SPTLRPC_FLVR_NULL
+
+#define SPTLRPC_FLVR_INVALID	    ((__u32) 0xFFFFFFFF)
+#define SPTLRPC_FLVR_ANY		((__u32) 0xFFF00000)
+
+/**
+ * extract the useful part from wire flavor
+ */
+#define WIRE_FLVR(wflvr)		(((__u32) (wflvr)) & 0x000FFFFF)
+
+/** @} flavor */
+
+static inline void flvr_set_svc(__u32 *flvr, __u32 svc)
+{
+	LASSERT(svc < SPTLRPC_SVC_MAX);
+	*flvr = MAKE_FLVR(SPTLRPC_FLVR_POLICY(*flvr),
+			  SPTLRPC_FLVR_MECH(*flvr),
+			  svc,
+			  SPTLRPC_FLVR_BULK_TYPE(*flvr),
+			  SPTLRPC_FLVR_BULK_SVC(*flvr));
+}
+
+static inline void flvr_set_bulk_svc(__u32 *flvr, __u32 svc)
+{
+	LASSERT(svc < SPTLRPC_BULK_SVC_MAX);
+	*flvr = MAKE_FLVR(SPTLRPC_FLVR_POLICY(*flvr),
+			  SPTLRPC_FLVR_MECH(*flvr),
+			  SPTLRPC_FLVR_SVC(*flvr),
+			  SPTLRPC_FLVR_BULK_TYPE(*flvr),
+			  svc);
+}
+
+struct bulk_spec_hash {
+	__u8    hash_alg;
+};
+
+/**
+ * Full description of flavors being used on a ptlrpc connection, include
+ * both regular RPC and bulk transfer parts.
+ */
+struct sptlrpc_flavor {
+	/**
+	 * wire flavor, should be renamed to sf_wire.
+	 */
+	__u32   sf_rpc;
+	/**
+	 * general flags of PTLRPC_SEC_FL_*
+	 */
+	__u32   sf_flags;
+	/**
+	 * rpc flavor specification
+	 */
+	union {
+		/* nothing for now */
+	} u_rpc;
+	/**
+	 * bulk flavor specification
+	 */
+	union {
+		struct bulk_spec_hash hash;
+	} u_bulk;
+};
+
+/**
+ * identify the RPC is generated from what part of Lustre. It's encoded into
+ * RPC requests and to be checked by ptlrpc service.
+ */
+enum lustre_sec_part {
+	LUSTRE_SP_CLI	   = 0,
+	LUSTRE_SP_MDT,
+	LUSTRE_SP_OST,
+	LUSTRE_SP_MGC,
+	LUSTRE_SP_MGS,
+	LUSTRE_SP_ANY	   = 0xFF
+};
+
+const char *sptlrpc_part2name(enum lustre_sec_part sp);
+enum lustre_sec_part sptlrpc_target_sec_part(struct obd_device *obd);
+
+/**
+ * A rule specifies a flavor to be used by a ptlrpc connection between
+ * two Lustre parts.
+ */
+struct sptlrpc_rule {
+	__u32		   sr_netid;   /* LNET network ID */
+	__u8		    sr_from;    /* sec_part */
+	__u8		    sr_to;      /* sec_part */
+	__u16		   sr_padding;
+	struct sptlrpc_flavor   sr_flvr;
+};
+
+/**
+ * A set of rules in memory.
+ *
+ * Rules are generated and stored on MGS, and propagated to MDT, OST,
+ * and client when needed.
+ */
+struct sptlrpc_rule_set {
+	int		     srs_nslot;
+	int		     srs_nrule;
+	struct sptlrpc_rule    *srs_rules;
+};
+
+int sptlrpc_parse_flavor(const char *str, struct sptlrpc_flavor *flvr);
+int sptlrpc_flavor_has_bulk(struct sptlrpc_flavor *flvr);
+
+static inline void sptlrpc_rule_set_init(struct sptlrpc_rule_set *set)
+{
+	memset(set, 0, sizeof(*set));
+}
+
+void sptlrpc_rule_set_free(struct sptlrpc_rule_set *set);
+int  sptlrpc_rule_set_expand(struct sptlrpc_rule_set *set);
+int  sptlrpc_rule_set_merge(struct sptlrpc_rule_set *set,
+			    struct sptlrpc_rule *rule);
+int sptlrpc_rule_set_choose(struct sptlrpc_rule_set *rset,
+			    enum lustre_sec_part from,
+			    enum lustre_sec_part to,
+			    lnet_nid_t nid,
+			    struct sptlrpc_flavor *sf);
+void sptlrpc_rule_set_dump(struct sptlrpc_rule_set *set);
+
+int  sptlrpc_process_config(struct lustre_cfg *lcfg);
+void sptlrpc_conf_log_start(const char *logname);
+void sptlrpc_conf_log_stop(const char *logname);
+void sptlrpc_conf_log_update_begin(const char *logname);
+void sptlrpc_conf_log_update_end(const char *logname);
+void sptlrpc_conf_client_adapt(struct obd_device *obd);
+int  sptlrpc_conf_target_get_rules(struct obd_device *obd,
+				   struct sptlrpc_rule_set *rset,
+				   int initial);
+void sptlrpc_target_choose_flavor(struct sptlrpc_rule_set *rset,
+				  enum lustre_sec_part from,
+				  lnet_nid_t nid,
+				  struct sptlrpc_flavor *flavor);
+
+/* The maximum length of security payload. 1024 is enough for Kerberos 5,
+ * and should be enough for other future mechanisms but not sure.
+ * Only used by pre-allocated request/reply pool.
+ */
+#define SPTLRPC_MAX_PAYLOAD     (1024)
+
+
+struct vfs_cred {
+	uint32_t	vc_uid;
+	uint32_t	vc_gid;
+};
+
+struct ptlrpc_ctx_ops {
+	/**
+	 * To determine whether it's suitable to use the \a ctx for \a vcred.
+	 */
+	int     (*match)       (struct ptlrpc_cli_ctx *ctx,
+				struct vfs_cred *vcred);
+
+	/**
+	 * To bring the \a ctx uptodate.
+	 */
+	int     (*refresh)     (struct ptlrpc_cli_ctx *ctx);
+
+	/**
+	 * Validate the \a ctx.
+	 */
+	int     (*validate)    (struct ptlrpc_cli_ctx *ctx);
+
+	/**
+	 * Force the \a ctx to die.
+	 */
+	void    (*die)	 (struct ptlrpc_cli_ctx *ctx,
+				int grace);
+	int     (*display)     (struct ptlrpc_cli_ctx *ctx,
+				char *buf, int bufsize);
+
+	/**
+	 * Sign the request message using \a ctx.
+	 *
+	 * \pre req->rq_reqmsg point to request message.
+	 * \pre req->rq_reqlen is the request message length.
+	 * \post req->rq_reqbuf point to request message with signature.
+	 * \post req->rq_reqdata_len is set to the final request message size.
+	 *
+	 * \see null_ctx_sign(), plain_ctx_sign(), gss_cli_ctx_sign().
+	 */
+	int     (*sign)	(struct ptlrpc_cli_ctx *ctx,
+				struct ptlrpc_request *req);
+
+	/**
+	 * Verify the reply message using \a ctx.
+	 *
+	 * \pre req->rq_repdata point to reply message with signature.
+	 * \pre req->rq_repdata_len is the total reply message length.
+	 * \post req->rq_repmsg point to reply message without signature.
+	 * \post req->rq_replen is the reply message length.
+	 *
+	 * \see null_ctx_verify(), plain_ctx_verify(), gss_cli_ctx_verify().
+	 */
+	int     (*verify)      (struct ptlrpc_cli_ctx *ctx,
+				struct ptlrpc_request *req);
+
+	/**
+	 * Encrypt the request message using \a ctx.
+	 *
+	 * \pre req->rq_reqmsg point to request message in clear text.
+	 * \pre req->rq_reqlen is the request message length.
+	 * \post req->rq_reqbuf point to request message.
+	 * \post req->rq_reqdata_len is set to the final request message size.
+	 *
+	 * \see gss_cli_ctx_seal().
+	 */
+	int     (*seal)	(struct ptlrpc_cli_ctx *ctx,
+				struct ptlrpc_request *req);
+
+	/**
+	 * Decrypt the reply message using \a ctx.
+	 *
+	 * \pre req->rq_repdata point to encrypted reply message.
+	 * \pre req->rq_repdata_len is the total cipher text length.
+	 * \post req->rq_repmsg point to reply message in clear text.
+	 * \post req->rq_replen is the reply message length in clear text.
+	 *
+	 * \see gss_cli_ctx_unseal().
+	 */
+	int     (*unseal)      (struct ptlrpc_cli_ctx *ctx,
+				struct ptlrpc_request *req);
+
+	/**
+	 * Wrap bulk request data. This is called before wrapping RPC
+	 * request message.
+	 *
+	 * \pre bulk buffer is descripted by desc->bd_iov and
+	 * desc->bd_iov_count. note for read it's just buffer, no data
+	 * need to be sent;  for write it contains data in clear text.
+	 * \post when necessary, ptlrpc_bulk_sec_desc was properly prepared
+	 * (usually inside of RPC request message).
+	 * - encryption: cipher text bulk buffer is descripted by
+	 *   desc->bd_enc_iov and desc->bd_iov_count (currently assume iov
+	 *   count remains the same).
+	 * - otherwise: bulk buffer is still desc->bd_iov and
+	 *   desc->bd_iov_count.
+	 *
+	 * \return 0: success.
+	 * \return -ev: error code.
+	 *
+	 * \see plain_cli_wrap_bulk(), gss_cli_ctx_wrap_bulk().
+	 */
+	int     (*wrap_bulk)   (struct ptlrpc_cli_ctx *ctx,
+				struct ptlrpc_request *req,
+				struct ptlrpc_bulk_desc *desc);
+
+	/**
+	 * Unwrap bulk reply data. This is called after wrapping RPC
+	 * reply message.
+	 *
+	 * \pre bulk buffer is descripted by desc->bd_iov/desc->bd_enc_iov and
+	 * desc->bd_iov_count, according to wrap_bulk().
+	 * \post final bulk data in clear text is placed in buffer described
+	 * by desc->bd_iov and desc->bd_iov_count.
+	 * \return +ve nob of actual bulk data in clear text.
+	 * \return -ve error code.
+	 *
+	 * \see plain_cli_unwrap_bulk(), gss_cli_ctx_unwrap_bulk().
+	 */
+	int     (*unwrap_bulk) (struct ptlrpc_cli_ctx *ctx,
+				struct ptlrpc_request *req,
+				struct ptlrpc_bulk_desc *desc);
+};
+
+#define PTLRPC_CTX_NEW_BIT	     (0)  /* newly created */
+#define PTLRPC_CTX_UPTODATE_BIT	(1)  /* uptodate */
+#define PTLRPC_CTX_DEAD_BIT	    (2)  /* mark expired gracefully */
+#define PTLRPC_CTX_ERROR_BIT	   (3)  /* fatal error (refresh, etc.) */
+#define PTLRPC_CTX_CACHED_BIT	  (8)  /* in ctx cache (hash etc.) */
+#define PTLRPC_CTX_ETERNAL_BIT	 (9)  /* always valid */
+
+#define PTLRPC_CTX_NEW		 (1 << PTLRPC_CTX_NEW_BIT)
+#define PTLRPC_CTX_UPTODATE	    (1 << PTLRPC_CTX_UPTODATE_BIT)
+#define PTLRPC_CTX_DEAD		(1 << PTLRPC_CTX_DEAD_BIT)
+#define PTLRPC_CTX_ERROR	       (1 << PTLRPC_CTX_ERROR_BIT)
+#define PTLRPC_CTX_CACHED	      (1 << PTLRPC_CTX_CACHED_BIT)
+#define PTLRPC_CTX_ETERNAL	     (1 << PTLRPC_CTX_ETERNAL_BIT)
+
+#define PTLRPC_CTX_STATUS_MASK	 (PTLRPC_CTX_NEW_BIT    |       \
+					PTLRPC_CTX_UPTODATE   |       \
+					PTLRPC_CTX_DEAD       |       \
+					PTLRPC_CTX_ERROR)
+
+struct ptlrpc_cli_ctx {
+	struct hlist_node	cc_cache;      /* linked into ctx cache */
+	atomic_t	    cc_refcount;
+	struct ptlrpc_sec      *cc_sec;
+	struct ptlrpc_ctx_ops  *cc_ops;
+	cfs_time_t	      cc_expire;     /* in seconds */
+	unsigned int	    cc_early_expire:1;
+	unsigned long	   cc_flags;
+	struct vfs_cred	 cc_vcred;
+	spinlock_t		cc_lock;
+	struct list_head	      cc_req_list;   /* waiting reqs linked here */
+	struct list_head	      cc_gc_chain;   /* linked to gc chain */
+};
+
+/**
+ * client side policy operation vector.
+ */
+struct ptlrpc_sec_cops {
+	/**
+	 * Given an \a imp, create and initialize a ptlrpc_sec structure.
+	 * \param ctx service context:
+	 * - regular import: \a ctx should be NULL;
+	 * - reverse import: \a ctx is obtained from incoming request.
+	 * \param flavor specify what flavor to use.
+	 *
+	 * When necessary, policy module is responsible for taking reference
+	 * on the import.
+	 *
+	 * \see null_create_sec(), plain_create_sec(), gss_sec_create_kr().
+	 */
+	struct ptlrpc_sec *     (*create_sec)  (struct obd_import *imp,
+						struct ptlrpc_svc_ctx *ctx,
+						struct sptlrpc_flavor *flavor);
+
+	/**
+	 * Destructor of ptlrpc_sec. When called, refcount has been dropped
+	 * to 0 and all contexts has been destroyed.
+	 *
+	 * \see null_destroy_sec(), plain_destroy_sec(), gss_sec_destroy_kr().
+	 */
+	void		    (*destroy_sec) (struct ptlrpc_sec *sec);
+
+	/**
+	 * Notify that this ptlrpc_sec is going to die. Optionally, policy
+	 * module is supposed to set sec->ps_dying and whatever necessary
+	 * actions.
+	 *
+	 * \see plain_kill_sec(), gss_sec_kill().
+	 */
+	void		    (*kill_sec)    (struct ptlrpc_sec *sec);
+
+	/**
+	 * Given \a vcred, lookup and/or create its context. The policy module
+	 * is supposed to maintain its own context cache.
+	 * XXX currently \a create and \a remove_dead is always 1, perhaps
+	 * should be removed completely.
+	 *
+	 * \see null_lookup_ctx(), plain_lookup_ctx(), gss_sec_lookup_ctx_kr().
+	 */
+	struct ptlrpc_cli_ctx * (*lookup_ctx)  (struct ptlrpc_sec *sec,
+						struct vfs_cred *vcred,
+						int create,
+						int remove_dead);
+
+	/**
+	 * Called then the reference of \a ctx dropped to 0. The policy module
+	 * is supposed to destroy this context or whatever else according to
+	 * its cache maintainance mechamism.
+	 *
+	 * \param sync if zero, we shouldn't wait for the context being
+	 * destroyed completely.
+	 *
+	 * \see plain_release_ctx(), gss_sec_release_ctx_kr().
+	 */
+	void		    (*release_ctx) (struct ptlrpc_sec *sec,
+						struct ptlrpc_cli_ctx *ctx,
+						int sync);
+
+	/**
+	 * Flush the context cache.
+	 *
+	 * \param uid context of which user, -1 means all contexts.
+	 * \param grace if zero, the PTLRPC_CTX_UPTODATE_BIT of affected
+	 * contexts should be cleared immediately.
+	 * \param force if zero, only idle contexts will be flushed.
+	 *
+	 * \see plain_flush_ctx_cache(), gss_sec_flush_ctx_cache_kr().
+	 */
+	int		     (*flush_ctx_cache)
+					       (struct ptlrpc_sec *sec,
+						uid_t uid,
+						int grace,
+						int force);
+
+	/**
+	 * Called periodically by garbage collector to remove dead contexts
+	 * from cache.
+	 *
+	 * \see gss_sec_gc_ctx_kr().
+	 */
+	void		    (*gc_ctx)      (struct ptlrpc_sec *sec);
+
+	/**
+	 * Given an context \a ctx, install a corresponding reverse service
+	 * context on client side.
+	 * XXX currently it's only used by GSS module, maybe we should remove
+	 * this from general API.
+	 */
+	int		     (*install_rctx)(struct obd_import *imp,
+						struct ptlrpc_sec *sec,
+						struct ptlrpc_cli_ctx *ctx);
+
+	/**
+	 * To allocate request buffer for \a req.
+	 *
+	 * \pre req->rq_reqmsg == NULL.
+	 * \pre req->rq_reqbuf == NULL, otherwise it must be pre-allocated,
+	 * we are not supposed to free it.
+	 * \post if success, req->rq_reqmsg point to a buffer with size
+	 * at least \a lustre_msg_size.
+	 *
+	 * \see null_alloc_reqbuf(), plain_alloc_reqbuf(), gss_alloc_reqbuf().
+	 */
+	int		     (*alloc_reqbuf)(struct ptlrpc_sec *sec,
+						struct ptlrpc_request *req,
+						int lustre_msg_size);
+
+	/**
+	 * To free request buffer for \a req.
+	 *
+	 * \pre req->rq_reqbuf != NULL.
+	 *
+	 * \see null_free_reqbuf(), plain_free_reqbuf(), gss_free_reqbuf().
+	 */
+	void		    (*free_reqbuf) (struct ptlrpc_sec *sec,
+						struct ptlrpc_request *req);
+
+	/**
+	 * To allocate reply buffer for \a req.
+	 *
+	 * \pre req->rq_repbuf == NULL.
+	 * \post if success, req->rq_repbuf point to a buffer with size
+	 * req->rq_repbuf_len, the size should be large enough to receive
+	 * reply which be transformed from \a lustre_msg_size of clear text.
+	 *
+	 * \see null_alloc_repbuf(), plain_alloc_repbuf(), gss_alloc_repbuf().
+	 */
+	int		     (*alloc_repbuf)(struct ptlrpc_sec *sec,
+						struct ptlrpc_request *req,
+						int lustre_msg_size);
+
+	/**
+	 * To free reply buffer for \a req.
+	 *
+	 * \pre req->rq_repbuf != NULL.
+	 * \post req->rq_repbuf == NULL.
+	 * \post req->rq_repbuf_len == 0.
+	 *
+	 * \see null_free_repbuf(), plain_free_repbuf(), gss_free_repbuf().
+	 */
+	void		    (*free_repbuf) (struct ptlrpc_sec *sec,
+						struct ptlrpc_request *req);
+
+	/**
+	 * To expand the request buffer of \a req, thus the \a segment in
+	 * the request message pointed by req->rq_reqmsg can accommodate
+	 * at least \a newsize of data.
+	 *
+	 * \pre req->rq_reqmsg->lm_buflens[segment] < newsize.
+	 *
+	 * \see null_enlarge_reqbuf(), plain_enlarge_reqbuf(),
+	 * gss_enlarge_reqbuf().
+	 */
+	int		     (*enlarge_reqbuf)
+					       (struct ptlrpc_sec *sec,
+						struct ptlrpc_request *req,
+						int segment, int newsize);
+	/*
+	 * misc
+	 */
+	int		     (*display)     (struct ptlrpc_sec *sec,
+						struct seq_file *seq);
+};
+
+/**
+ * server side policy operation vector.
+ */
+struct ptlrpc_sec_sops {
+	/**
+	 * verify an incoming request.
+	 *
+	 * \pre request message is pointed by req->rq_reqbuf, size is
+	 * req->rq_reqdata_len; and the message has been unpacked to
+	 * host byte order.
+	 *
+	 * \retval SECSVC_OK success, req->rq_reqmsg point to request message
+	 * in clear text, size is req->rq_reqlen; req->rq_svc_ctx is set;
+	 * req->rq_sp_from is decoded from request.
+	 * \retval SECSVC_COMPLETE success, the request has been fully
+	 * processed, and reply message has been prepared; req->rq_sp_from is
+	 * decoded from request.
+	 * \retval SECSVC_DROP failed, this request should be dropped.
+	 *
+	 * \see null_accept(), plain_accept(), gss_svc_accept_kr().
+	 */
+	int		     (*accept)      (struct ptlrpc_request *req);
+
+	/**
+	 * Perform security transformation upon reply message.
+	 *
+	 * \pre reply message is pointed by req->rq_reply_state->rs_msg, size
+	 * is req->rq_replen.
+	 * \post req->rs_repdata_len is the final message size.
+	 * \post req->rq_reply_off is set.
+	 *
+	 * \see null_authorize(), plain_authorize(), gss_svc_authorize().
+	 */
+	int		     (*authorize)   (struct ptlrpc_request *req);
+
+	/**
+	 * Invalidate server context \a ctx.
+	 *
+	 * \see gss_svc_invalidate_ctx().
+	 */
+	void		    (*invalidate_ctx)
+					       (struct ptlrpc_svc_ctx *ctx);
+
+	/**
+	 * Allocate a ptlrpc_reply_state.
+	 *
+	 * \param msgsize size of the reply message in clear text.
+	 * \pre if req->rq_reply_state != NULL, then it's pre-allocated, we
+	 * should simply use it; otherwise we'll responsible for allocating
+	 * a new one.
+	 * \post req->rq_reply_state != NULL;
+	 * \post req->rq_reply_state->rs_msg != NULL;
+	 *
+	 * \see null_alloc_rs(), plain_alloc_rs(), gss_svc_alloc_rs().
+	 */
+	int		     (*alloc_rs)    (struct ptlrpc_request *req,
+						int msgsize);
+
+	/**
+	 * Free a ptlrpc_reply_state.
+	 */
+	void		    (*free_rs)     (struct ptlrpc_reply_state *rs);
+
+	/**
+	 * Release the server context \a ctx.
+	 *
+	 * \see gss_svc_free_ctx().
+	 */
+	void		    (*free_ctx)    (struct ptlrpc_svc_ctx *ctx);
+
+	/**
+	 * Install a reverse context based on the server context \a ctx.
+	 *
+	 * \see gss_svc_install_rctx_kr().
+	 */
+	int		     (*install_rctx)(struct obd_import *imp,
+						struct ptlrpc_svc_ctx *ctx);
+
+	/**
+	 * Prepare buffer for incoming bulk write.
+	 *
+	 * \pre desc->bd_iov and desc->bd_iov_count describes the buffer
+	 * intended to receive the write.
+	 *
+	 * \see gss_svc_prep_bulk().
+	 */
+	int		     (*prep_bulk)   (struct ptlrpc_request *req,
+						struct ptlrpc_bulk_desc *desc);
+
+	/**
+	 * Unwrap the bulk write data.
+	 *
+	 * \see plain_svc_unwrap_bulk(), gss_svc_unwrap_bulk().
+	 */
+	int		     (*unwrap_bulk) (struct ptlrpc_request *req,
+						struct ptlrpc_bulk_desc *desc);
+
+	/**
+	 * Wrap the bulk read data.
+	 *
+	 * \see plain_svc_wrap_bulk(), gss_svc_wrap_bulk().
+	 */
+	int		     (*wrap_bulk)   (struct ptlrpc_request *req,
+						struct ptlrpc_bulk_desc *desc);
+};
+
+struct ptlrpc_sec_policy {
+	module_t		   *sp_owner;
+	char			   *sp_name;
+	__u16			   sp_policy; /* policy number */
+	struct ptlrpc_sec_cops	 *sp_cops;   /* client ops */
+	struct ptlrpc_sec_sops	 *sp_sops;   /* server ops */
+};
+
+#define PTLRPC_SEC_FL_REVERSE	   0x0001 /* reverse sec */
+#define PTLRPC_SEC_FL_ROOTONLY	  0x0002 /* treat everyone as root */
+#define PTLRPC_SEC_FL_UDESC	     0x0004 /* ship udesc */
+#define PTLRPC_SEC_FL_BULK	      0x0008 /* intensive bulk i/o expected */
+#define PTLRPC_SEC_FL_PAG	       0x0010 /* PAG mode */
+
+/**
+ * The ptlrpc_sec represents the client side ptlrpc security facilities,
+ * each obd_import (both regular and reverse import) must associate with
+ * a ptlrpc_sec.
+ *
+ * \see sptlrpc_import_sec_adapt().
+ */
+struct ptlrpc_sec {
+	struct ptlrpc_sec_policy       *ps_policy;
+	atomic_t		    ps_refcount;
+	/** statistic only */
+	atomic_t		    ps_nctx;
+	/** unique identifier */
+	int			     ps_id;
+	struct sptlrpc_flavor	   ps_flvr;
+	enum lustre_sec_part	    ps_part;
+	/** after set, no more new context will be created */
+	unsigned int		    ps_dying:1;
+	/** owning import */
+	struct obd_import	      *ps_import;
+	spinlock_t			ps_lock;
+
+	/*
+	 * garbage collection
+	 */
+	struct list_head		      ps_gc_list;
+	cfs_time_t		      ps_gc_interval; /* in seconds */
+	cfs_time_t		      ps_gc_next;     /* in seconds */
+};
+
+static inline int sec_is_reverse(struct ptlrpc_sec *sec)
+{
+	return (sec->ps_flvr.sf_flags & PTLRPC_SEC_FL_REVERSE);
+}
+
+static inline int sec_is_rootonly(struct ptlrpc_sec *sec)
+{
+	return (sec->ps_flvr.sf_flags & PTLRPC_SEC_FL_ROOTONLY);
+}
+
+
+struct ptlrpc_svc_ctx {
+	atomic_t		    sc_refcount;
+	struct ptlrpc_sec_policy       *sc_policy;
+};
+
+/*
+ * user identity descriptor
+ */
+#define LUSTRE_MAX_GROUPS	       (128)
+
+struct ptlrpc_user_desc {
+	__u32	   pud_uid;
+	__u32	   pud_gid;
+	__u32	   pud_fsuid;
+	__u32	   pud_fsgid;
+	__u32	   pud_cap;
+	__u32	   pud_ngroups;
+	__u32	   pud_groups[0];
+};
+
+/*
+ * bulk flavors
+ */
+enum sptlrpc_bulk_hash_alg {
+	BULK_HASH_ALG_NULL      = 0,
+	BULK_HASH_ALG_ADLER32,
+	BULK_HASH_ALG_CRC32,
+	BULK_HASH_ALG_MD5,
+	BULK_HASH_ALG_SHA1,
+	BULK_HASH_ALG_SHA256,
+	BULK_HASH_ALG_SHA384,
+	BULK_HASH_ALG_SHA512,
+	BULK_HASH_ALG_MAX
+};
+
+const char * sptlrpc_get_hash_name(__u8 hash_alg);
+__u8 sptlrpc_get_hash_alg(const char *algname);
+
+enum {
+	BSD_FL_ERR      = 1,
+};
+
+struct ptlrpc_bulk_sec_desc {
+	__u8	    bsd_version;    /* 0 */
+	__u8	    bsd_type;       /* SPTLRPC_BULK_XXX */
+	__u8	    bsd_svc;	/* SPTLRPC_BULK_SVC_XXXX */
+	__u8	    bsd_flags;      /* flags */
+	__u32	   bsd_nob;	/* nob of bulk data */
+	__u8	    bsd_data[0];    /* policy-specific token */
+};
+
+
+/*
+ * lprocfs
+ */
+struct proc_dir_entry;
+extern struct proc_dir_entry *sptlrpc_proc_root;
+
+/*
+ * round size up to next power of 2, for slab allocation.
+ * @size must be sane (can't overflow after round up)
+ */
+static inline int size_roundup_power2(int size)
+{
+	size--;
+	size |= size >> 1;
+	size |= size >> 2;
+	size |= size >> 4;
+	size |= size >> 8;
+	size |= size >> 16;
+	size++;
+	return size;
+}
+
+/*
+ * internal support libraries
+ */
+void _sptlrpc_enlarge_msg_inplace(struct lustre_msg *msg,
+				  int segment, int newsize);
+
+/*
+ * security policies
+ */
+int sptlrpc_register_policy(struct ptlrpc_sec_policy *policy);
+int sptlrpc_unregister_policy(struct ptlrpc_sec_policy *policy);
+
+__u32 sptlrpc_name2flavor_base(const char *name);
+const char *sptlrpc_flavor2name_base(__u32 flvr);
+char *sptlrpc_flavor2name_bulk(struct sptlrpc_flavor *sf,
+			       char *buf, int bufsize);
+char *sptlrpc_flavor2name(struct sptlrpc_flavor *sf, char *buf, int bufsize);
+char *sptlrpc_secflags2str(__u32 flags, char *buf, int bufsize);
+
+static inline
+struct ptlrpc_sec_policy *sptlrpc_policy_get(struct ptlrpc_sec_policy *policy)
+{
+	__module_get(policy->sp_owner);
+	return policy;
+}
+
+static inline
+void sptlrpc_policy_put(struct ptlrpc_sec_policy *policy)
+{
+	module_put(policy->sp_owner);
+}
+
+/*
+ * client credential
+ */
+static inline
+unsigned long cli_ctx_status(struct ptlrpc_cli_ctx *ctx)
+{
+	return (ctx->cc_flags & PTLRPC_CTX_STATUS_MASK);
+}
+
+static inline
+int cli_ctx_is_ready(struct ptlrpc_cli_ctx *ctx)
+{
+	return (cli_ctx_status(ctx) == PTLRPC_CTX_UPTODATE);
+}
+
+static inline
+int cli_ctx_is_refreshed(struct ptlrpc_cli_ctx *ctx)
+{
+	return (cli_ctx_status(ctx) != 0);
+}
+
+static inline
+int cli_ctx_is_uptodate(struct ptlrpc_cli_ctx *ctx)
+{
+	return ((ctx->cc_flags & PTLRPC_CTX_UPTODATE) != 0);
+}
+
+static inline
+int cli_ctx_is_error(struct ptlrpc_cli_ctx *ctx)
+{
+	return ((ctx->cc_flags & PTLRPC_CTX_ERROR) != 0);
+}
+
+static inline
+int cli_ctx_is_dead(struct ptlrpc_cli_ctx *ctx)
+{
+	return ((ctx->cc_flags & (PTLRPC_CTX_DEAD | PTLRPC_CTX_ERROR)) != 0);
+}
+
+static inline
+int cli_ctx_is_eternal(struct ptlrpc_cli_ctx *ctx)
+{
+	return ((ctx->cc_flags & PTLRPC_CTX_ETERNAL) != 0);
+}
+
+/*
+ * sec get/put
+ */
+struct ptlrpc_sec *sptlrpc_sec_get(struct ptlrpc_sec *sec);
+void sptlrpc_sec_put(struct ptlrpc_sec *sec);
+
+/*
+ * internal apis which only used by policy impelentation
+ */
+int  sptlrpc_get_next_secid(void);
+void sptlrpc_sec_destroy(struct ptlrpc_sec *sec);
+
+/*
+ * exported client context api
+ */
+struct ptlrpc_cli_ctx *sptlrpc_cli_ctx_get(struct ptlrpc_cli_ctx *ctx);
+void sptlrpc_cli_ctx_put(struct ptlrpc_cli_ctx *ctx, int sync);
+void sptlrpc_cli_ctx_expire(struct ptlrpc_cli_ctx *ctx);
+void sptlrpc_cli_ctx_wakeup(struct ptlrpc_cli_ctx *ctx);
+int sptlrpc_cli_ctx_display(struct ptlrpc_cli_ctx *ctx, char *buf, int bufsize);
+
+/*
+ * exported client context wrap/buffers
+ */
+int sptlrpc_cli_wrap_request(struct ptlrpc_request *req);
+int sptlrpc_cli_unwrap_reply(struct ptlrpc_request *req);
+int sptlrpc_cli_alloc_reqbuf(struct ptlrpc_request *req, int msgsize);
+void sptlrpc_cli_free_reqbuf(struct ptlrpc_request *req);
+int sptlrpc_cli_alloc_repbuf(struct ptlrpc_request *req, int msgsize);
+void sptlrpc_cli_free_repbuf(struct ptlrpc_request *req);
+int sptlrpc_cli_enlarge_reqbuf(struct ptlrpc_request *req,
+			       int segment, int newsize);
+int  sptlrpc_cli_unwrap_early_reply(struct ptlrpc_request *req,
+				    struct ptlrpc_request **req_ret);
+void sptlrpc_cli_finish_early_reply(struct ptlrpc_request *early_req);
+
+void sptlrpc_request_out_callback(struct ptlrpc_request *req);
+
+/*
+ * exported higher interface of import & request
+ */
+int sptlrpc_import_sec_adapt(struct obd_import *imp,
+			     struct ptlrpc_svc_ctx *ctx,
+			     struct sptlrpc_flavor *flvr);
+struct ptlrpc_sec *sptlrpc_import_sec_ref(struct obd_import *imp);
+void sptlrpc_import_sec_put(struct obd_import *imp);
+
+int  sptlrpc_import_check_ctx(struct obd_import *imp);
+void sptlrpc_import_flush_root_ctx(struct obd_import *imp);
+void sptlrpc_import_flush_my_ctx(struct obd_import *imp);
+void sptlrpc_import_flush_all_ctx(struct obd_import *imp);
+int  sptlrpc_req_get_ctx(struct ptlrpc_request *req);
+void sptlrpc_req_put_ctx(struct ptlrpc_request *req, int sync);
+int  sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout);
+int  sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req);
+void sptlrpc_req_set_flavor(struct ptlrpc_request *req, int opcode);
+
+int sptlrpc_parse_rule(char *param, struct sptlrpc_rule *rule);
+
+/* gc */
+void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec);
+void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec);
+void sptlrpc_gc_add_ctx(struct ptlrpc_cli_ctx *ctx);
+
+/* misc */
+const char * sec2target_str(struct ptlrpc_sec *sec);
+int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev);
+
+/*
+ * server side
+ */
+enum secsvc_accept_res {
+	SECSVC_OK       = 0,
+	SECSVC_COMPLETE,
+	SECSVC_DROP,
+};
+
+int  sptlrpc_svc_unwrap_request(struct ptlrpc_request *req);
+int  sptlrpc_svc_alloc_rs(struct ptlrpc_request *req, int msglen);
+int  sptlrpc_svc_wrap_reply(struct ptlrpc_request *req);
+void sptlrpc_svc_free_rs(struct ptlrpc_reply_state *rs);
+void sptlrpc_svc_ctx_addref(struct ptlrpc_request *req);
+void sptlrpc_svc_ctx_decref(struct ptlrpc_request *req);
+void sptlrpc_svc_ctx_invalidate(struct ptlrpc_request *req);
+
+int  sptlrpc_target_export_check(struct obd_export *exp,
+				 struct ptlrpc_request *req);
+void sptlrpc_target_update_exp_flavor(struct obd_device *obd,
+				      struct sptlrpc_rule_set *rset);
+
+/*
+ * reverse context
+ */
+int sptlrpc_svc_install_rvs_ctx(struct obd_import *imp,
+				struct ptlrpc_svc_ctx *ctx);
+int sptlrpc_cli_install_rvs_ctx(struct obd_import *imp,
+				struct ptlrpc_cli_ctx *ctx);
+
+/* bulk security api */
+int sptlrpc_enc_pool_add_user(void);
+int sptlrpc_enc_pool_del_user(void);
+int  sptlrpc_enc_pool_get_pages(struct ptlrpc_bulk_desc *desc);
+void sptlrpc_enc_pool_put_pages(struct ptlrpc_bulk_desc *desc);
+
+int sptlrpc_cli_wrap_bulk(struct ptlrpc_request *req,
+			  struct ptlrpc_bulk_desc *desc);
+int sptlrpc_cli_unwrap_bulk_read(struct ptlrpc_request *req,
+				 struct ptlrpc_bulk_desc *desc,
+				 int nob);
+int sptlrpc_cli_unwrap_bulk_write(struct ptlrpc_request *req,
+				  struct ptlrpc_bulk_desc *desc);
+
+/* bulk helpers (internal use only by policies) */
+int sptlrpc_get_bulk_checksum(struct ptlrpc_bulk_desc *desc, __u8 alg,
+			      void *buf, int buflen);
+
+int bulk_sec_desc_unpack(struct lustre_msg *msg, int offset, int swabbed);
+
+/* user descriptor helpers */
+static inline int sptlrpc_user_desc_size(int ngroups)
+{
+	return sizeof(struct ptlrpc_user_desc) + ngroups * sizeof(__u32);
+}
+
+int sptlrpc_current_user_desc_size(void);
+int sptlrpc_pack_user_desc(struct lustre_msg *msg, int offset);
+int sptlrpc_unpack_user_desc(struct lustre_msg *req, int offset, int swabbed);
+
+
+#define CFS_CAP_CHOWN_MASK (1 << CFS_CAP_CHOWN)
+#define CFS_CAP_SYS_RESOURCE_MASK (1 << CFS_CAP_SYS_RESOURCE)
+
+enum {
+	LUSTRE_SEC_NONE	 = 0,
+	LUSTRE_SEC_REMOTE       = 1,
+	LUSTRE_SEC_SPECIFY      = 2,
+	LUSTRE_SEC_ALL	  = 3
+};
+
+/** @} sptlrpc */
+
+#endif /* _LUSTRE_SEC_H_ */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_update.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_update.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_update.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_update.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,189 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.htm
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2013, Intel Corporation.
+ */
+/*
+ * lustre/include/lustre_update.h
+ *
+ * Author: Di Wang <di.wang@intel.com>
+ */
+
+#ifndef _LUSTRE_UPDATE_H
+#define _LUSTRE_UPDATE_H
+
+#define UPDATE_BUFFER_SIZE	8192
+struct update_request {
+	struct dt_device	*ur_dt;
+	struct list_head		ur_list;    /* attached itself to thandle */
+	int			ur_flags;
+	int			ur_rc;	    /* request result */
+	int			ur_batchid; /* Current batch(trans) id */
+	struct update_buf	*ur_buf;   /* Holding the update req */
+};
+
+static inline unsigned long update_size(struct update *update)
+{
+	unsigned long size;
+	int	   i;
+
+	size = cfs_size_round(offsetof(struct update, u_bufs[0]));
+	for (i = 0; i < UPDATE_BUF_COUNT; i++)
+		size += cfs_size_round(update->u_lens[i]);
+
+	return size;
+}
+
+static inline void *update_param_buf(struct update *update, int index,
+				     int *size)
+{
+	int	i;
+	void	*ptr;
+
+	if (index >= UPDATE_BUF_COUNT)
+		return NULL;
+
+	ptr = (char *)update + cfs_size_round(offsetof(struct update,
+						       u_bufs[0]));
+	for (i = 0; i < index; i++) {
+		LASSERT(update->u_lens[i] > 0);
+		ptr += cfs_size_round(update->u_lens[i]);
+	}
+
+	if (size != NULL)
+		*size = update->u_lens[index];
+
+	return ptr;
+}
+
+static inline unsigned long update_buf_size(struct update_buf *buf)
+{
+	unsigned long size;
+	int	   i = 0;
+
+	size = cfs_size_round(offsetof(struct update_buf, ub_bufs[0]));
+	for (i = 0; i < buf->ub_count; i++) {
+		struct update *update;
+
+		update = (struct update *)((char *)buf + size);
+		size += update_size(update);
+	}
+	LASSERT(size <= UPDATE_BUFFER_SIZE);
+	return size;
+}
+
+static inline void *update_buf_get(struct update_buf *buf, int index, int *size)
+{
+	int	count = buf->ub_count;
+	void	*ptr;
+	int	i = 0;
+
+	if (index >= count)
+		return NULL;
+
+	ptr = (char *)buf + cfs_size_round(offsetof(struct update_buf,
+						    ub_bufs[0]));
+	for (i = 0; i < index; i++)
+		ptr += update_size((struct update *)ptr);
+
+	if (size != NULL)
+		*size = update_size((struct update *)ptr);
+
+	return ptr;
+}
+
+static inline void update_init_reply_buf(struct update_reply *reply, int count)
+{
+	reply->ur_version = UPDATE_REPLY_V1;
+	reply->ur_count = count;
+}
+
+static inline void *update_get_buf_internal(struct update_reply *reply,
+					    int index, int *size)
+{
+	char *ptr;
+	int count = reply->ur_count;
+	int i;
+
+	if (index >= count)
+		return NULL;
+
+	ptr = (char *)reply + cfs_size_round(offsetof(struct update_reply,
+					     ur_lens[count]));
+	for (i = 0; i < index; i++) {
+		LASSERT(reply->ur_lens[i] > 0);
+		ptr += cfs_size_round(reply->ur_lens[i]);
+	}
+
+	if (size != NULL)
+		*size = reply->ur_lens[index];
+
+	return ptr;
+}
+
+static inline void update_insert_reply(struct update_reply *reply, void *data,
+				       int data_len, int index, int rc)
+{
+	char *ptr;
+
+	ptr = update_get_buf_internal(reply, index, NULL);
+	LASSERT(ptr != NULL);
+
+	*(int *)ptr = cpu_to_le32(rc);
+	ptr += sizeof(int);
+	if (data_len > 0) {
+		LASSERT(data != NULL);
+		memcpy(ptr, data, data_len);
+	}
+	reply->ur_lens[index] = data_len + sizeof(int);
+}
+
+static inline int update_get_reply_buf(struct update_reply *reply, void **buf,
+				       int index)
+{
+	char *ptr;
+	int  size = 0;
+	int  result;
+
+	ptr = update_get_buf_internal(reply, index, &size);
+	result = *(int *)ptr;
+
+	if (result < 0)
+		return result;
+
+	LASSERT((ptr != NULL && size >= sizeof(int)));
+	*buf = ptr + sizeof(int);
+	return size - sizeof(int);
+}
+
+static inline int update_get_reply_result(struct update_reply *reply,
+					  void **buf, int index)
+{
+	void *ptr;
+	int  size;
+
+	ptr = update_get_buf_internal(reply, index, &size);
+	LASSERT(ptr != NULL && size > sizeof(int));
+	return *(int *)ptr;
+}
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_ver.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_ver.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lustre_ver.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lustre_ver.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,24 @@
+#ifndef _LUSTRE_VER_H_
+#define _LUSTRE_VER_H_
+/* This file automatically generated from lustre/include/lustre_ver.h.in,
+ * based on parameters in lustre/autoconf/lustre-version.ac.
+ * Changes made directly to this file will be lost. */
+
+#define LUSTRE_MAJOR 2
+#define LUSTRE_MINOR 3
+#define LUSTRE_PATCH 64
+#define LUSTRE_FIX 0
+#define LUSTRE_VERSION_STRING "2.3.64"
+
+#define LUSTRE_VERSION_CODE OBD_OCD_VERSION(LUSTRE_MAJOR,LUSTRE_MINOR,LUSTRE_PATCH,LUSTRE_FIX)
+
+/* liblustre clients are only allowed to connect if their LUSTRE_FIX mismatches
+ * by this amount (set in lustre/autoconf/lustre-version.ac). */
+#define LUSTRE_VERSION_ALLOWED_OFFSET OBD_OCD_VERSION(0, 0, 1, 32)
+
+/* If lustre version of client and servers it connects to differs by more
+ * than this amount, client would issue a warning.
+ * (set in lustre/autoconf/lustre-version.ac) */
+#define LUSTRE_VERSION_OFFSET_WARN OBD_OCD_VERSION(0, 4, 0, 0)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lu_target.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lu_target.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lu_target.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lu_target.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,91 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _LUSTRE_LU_TARGET_H
+#define _LUSTRE_LU_TARGET_H
+
+#include <dt_object.h>
+#include <lustre_disk.h>
+
+struct lu_target {
+	struct obd_device       *lut_obd;
+	struct dt_device	*lut_bottom;
+	/** last_rcvd file */
+	struct dt_object	*lut_last_rcvd;
+	/* transaction callbacks */
+	struct dt_txn_callback   lut_txn_cb;
+	/** server data in last_rcvd file */
+	struct lr_server_data    lut_lsd;
+	/** Server last transaction number */
+	__u64		    lut_last_transno;
+	/** Lock protecting last transaction number */
+	spinlock_t		 lut_translock;
+	/** Lock protecting client bitmap */
+	spinlock_t		 lut_client_bitmap_lock;
+	/** Bitmap of known clients */
+	unsigned long	   *lut_client_bitmap;
+};
+
+typedef void (*tgt_cb_t)(struct lu_target *lut, __u64 transno,
+			 void *data, int err);
+struct tgt_commit_cb {
+	tgt_cb_t  tgt_cb_func;
+	void     *tgt_cb_data;
+};
+
+void tgt_boot_epoch_update(struct lu_target *lut);
+int tgt_last_commit_cb_add(struct thandle *th, struct lu_target *lut,
+			   struct obd_export *exp, __u64 transno);
+int tgt_new_client_cb_add(struct thandle *th, struct obd_export *exp);
+int tgt_init(const struct lu_env *env, struct lu_target *lut,
+	     struct obd_device *obd, struct dt_device *dt);
+void tgt_fini(const struct lu_env *env, struct lu_target *lut);
+int tgt_client_alloc(struct obd_export *exp);
+void tgt_client_free(struct obd_export *exp);
+int tgt_client_del(const struct lu_env *env, struct obd_export *exp);
+int tgt_client_add(const struct lu_env *env, struct obd_export *exp, int);
+int tgt_client_new(const struct lu_env *env, struct obd_export *exp);
+int tgt_client_data_read(const struct lu_env *env, struct lu_target *tg,
+			 struct lsd_client_data *lcd, loff_t *off, int index);
+int tgt_client_data_write(const struct lu_env *env, struct lu_target *tg,
+			  struct lsd_client_data *lcd, loff_t *off, struct thandle *th);
+int tgt_server_data_read(const struct lu_env *env, struct lu_target *tg);
+int tgt_server_data_write(const struct lu_env *env, struct lu_target *tg,
+			  struct thandle *th);
+int tgt_server_data_update(const struct lu_env *env, struct lu_target *tg, int sync);
+int tgt_truncate_last_rcvd(const struct lu_env *env, struct lu_target *tg, loff_t off);
+
+#endif /* __LUSTRE_LU_TARGET_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lvfs.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lvfs.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/lvfs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/lvfs.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/lvfs.h
+ *
+ * lustre VFS/process permission interface
+ */
+
+#ifndef __LVFS_H__
+#define __LVFS_H__
+
+#define LL_FID_NAMELEN (16 + 1 + 8 + 1)
+
+#include <linux/libcfs/libcfs.h>
+#include <linux/lvfs.h>
+
+#include <linux/libcfs/lucache.h>
+
+
+/* lvfs_common.c */
+struct dentry *lvfs_fid2dentry(struct lvfs_run_ctxt *, __u64, __u32, __u64 ,void *data);
+
+void push_ctxt(struct lvfs_run_ctxt *save, struct lvfs_run_ctxt *new_ctx,
+	       struct lvfs_ucred *cred);
+void pop_ctxt(struct lvfs_run_ctxt *saved, struct lvfs_run_ctxt *new_ctx,
+	      struct lvfs_ucred *cred);
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/md_object.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/md_object.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/md_object.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/md_object.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,908 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/md_object.h
+ *
+ * Extention of lu_object.h for metadata objects
+ */
+
+#ifndef _LUSTRE_MD_OBJECT_H
+#define _LUSTRE_MD_OBJECT_H
+
+/** \defgroup md md
+ * Sub-class of lu_object with methods common for "meta-data" objects in MDT
+ * stack.
+ *
+ * Meta-data objects implement namespace operations: you can link, unlink
+ * them, and treat them as directories.
+ *
+ * Examples: mdt, cmm, and mdt are implementations of md interface.
+ * @{
+ */
+
+
+/*
+ * super-class definitions.
+ */
+#include <dt_object.h>
+
+struct md_device;
+struct md_device_operations;
+struct md_object;
+struct obd_export;
+
+enum {
+	UCRED_INVALID   = -1,
+	UCRED_INIT      = 0,
+	UCRED_OLD       = 1,
+	UCRED_NEW       = 2
+};
+
+enum {
+	MD_CAPAINFO_MAX = 5
+};
+
+/** there are at most 5 fids in one operation, see rename, NOTE the last one
+ * is a temporary one used for is_subdir() */
+struct md_capainfo {
+	__u32		   mc_auth;
+	__u32		   mc_padding;
+	struct lu_fid	   mc_fid[MD_CAPAINFO_MAX];
+	struct lustre_capa     *mc_capa[MD_CAPAINFO_MAX];
+};
+
+struct md_quota {
+	struct obd_export       *mq_exp;
+};
+
+/**
+ * Implemented in mdd/mdd_handler.c.
+ *
+ * XXX should be moved into separate .h/.c together with all md security
+ * related definitions.
+ */
+struct md_capainfo *md_capainfo(const struct lu_env *env);
+struct md_quota *md_quota(const struct lu_env *env);
+
+/** metadata attributes */
+enum ma_valid {
+	MA_INODE     = (1 << 0),
+	MA_LOV       = (1 << 1),
+	MA_COOKIE    = (1 << 2),
+	MA_FLAGS     = (1 << 3),
+	MA_LMV       = (1 << 4),
+	MA_ACL_DEF   = (1 << 5),
+	MA_LOV_DEF   = (1 << 6),
+	MA_LAY_GEN   = (1 << 7),
+	MA_HSM       = (1 << 8),
+	MA_SOM       = (1 << 9),
+	MA_PFID      = (1 << 10)
+};
+
+typedef enum {
+	MDL_MINMODE  = 0,
+	MDL_EX       = 1,
+	MDL_PW       = 2,
+	MDL_PR       = 4,
+	MDL_CW       = 8,
+	MDL_CR       = 16,
+	MDL_NL       = 32,
+	MDL_GROUP    = 64,
+	MDL_MAXMODE
+} mdl_mode_t;
+
+typedef enum {
+	MDT_NUL_LOCK = 0,
+	MDT_REG_LOCK = (1 << 0),
+	MDT_PDO_LOCK = (1 << 1)
+} mdl_type_t;
+
+/* memory structure for hsm attributes
+ * for fields description see the on disk structure hsm_attrs
+ * which is defined in lustre_idl.h
+ */
+struct md_hsm {
+	__u32	mh_compat;
+	__u32	mh_flags;
+	__u64	mh_arch_id;
+	__u64	mh_arch_ver;
+};
+
+#define IOEPOCH_INVAL 0
+
+/* memory structure for som attributes
+ * for fields description see the on disk structure som_attrs
+ * which is defined in lustre_idl.h
+ */
+struct md_som_data {
+	__u32	msd_compat;
+	__u32	msd_incompat;
+	__u64	msd_ioepoch;
+	__u64	msd_size;
+	__u64	msd_blocks;
+	__u64	msd_mountid;
+};
+
+struct md_attr {
+	__u64		   ma_valid;
+	__u64		   ma_need;
+	__u64		   ma_attr_flags;
+	struct lu_attr	  ma_attr;
+	struct lu_fid	   ma_pfid;
+	struct md_hsm	   ma_hsm;
+	struct lov_mds_md      *ma_lmm;
+	struct lmv_stripe_md   *ma_lmv;
+	void		   *ma_acl;
+	struct llog_cookie     *ma_cookie;
+	struct lustre_capa     *ma_capa;
+	struct md_som_data     *ma_som;
+	int		     ma_lmm_size;
+	int		     ma_lmv_size;
+	int		     ma_acl_size;
+	int		     ma_cookie_size;
+	__u16		   ma_layout_gen;
+};
+
+/** Additional parameters for create */
+struct md_op_spec {
+	union {
+		/** symlink target */
+		const char	       *sp_symname;
+		/** parent FID for cross-ref mkdir */
+		const struct lu_fid      *sp_pfid;
+		/** eadata for regular files */
+		struct md_spec_reg {
+			/** lov objs exist already */
+			const struct lu_fid   *fid;
+			const void *eadata;
+			int  eadatalen;
+		} sp_ea;
+	} u;
+
+	/** Create flag from client: such as MDS_OPEN_CREAT, and others. */
+	__u64      sp_cr_flags;
+
+	/** don't create lov objects or llog cookie - this replay */
+	unsigned int no_create:1,
+		     sp_cr_lookup:1, /* do lookup sanity check or not. */
+		     sp_rm_entry:1;  /* only remove name entry */
+
+	/** Current lock mode for parent dir where create is performing. */
+	mdl_mode_t sp_cr_mode;
+
+	/** to create directory */
+	const struct dt_index_features *sp_feat;
+};
+
+/**
+ * Operations implemented for each md object (both directory and leaf).
+ */
+struct md_object_operations {
+	int (*moo_permission)(const struct lu_env *env,
+			      struct md_object *pobj, struct md_object *cobj,
+			      struct md_attr *attr, int mask);
+
+	int (*moo_attr_get)(const struct lu_env *env, struct md_object *obj,
+			    struct md_attr *attr);
+
+	int (*moo_attr_set)(const struct lu_env *env, struct md_object *obj,
+			    const struct md_attr *attr);
+
+	int (*moo_xattr_get)(const struct lu_env *env, struct md_object *obj,
+			     struct lu_buf *buf, const char *name);
+
+	int (*moo_xattr_list)(const struct lu_env *env, struct md_object *obj,
+			      struct lu_buf *buf);
+
+	int (*moo_xattr_set)(const struct lu_env *env, struct md_object *obj,
+			     const struct lu_buf *buf, const char *name,
+			     int fl);
+
+	int (*moo_xattr_del)(const struct lu_env *env, struct md_object *obj,
+			     const char *name);
+
+	/** This method is used to swap the layouts between 2 objects */
+	int (*moo_swap_layouts)(const struct lu_env *env,
+			       struct md_object *obj1, struct md_object *obj2,
+			       __u64 flags);
+
+	/** \retval number of bytes actually read upon success */
+	int (*moo_readpage)(const struct lu_env *env, struct md_object *obj,
+			    const struct lu_rdpg *rdpg);
+
+	int (*moo_readlink)(const struct lu_env *env, struct md_object *obj,
+			    struct lu_buf *buf);
+	int (*moo_changelog)(const struct lu_env *env,
+			     enum changelog_rec_type type, int flags,
+			     struct md_object *obj);
+	/** part of cross-ref operation */
+	int (*moo_object_create)(const struct lu_env *env,
+				 struct md_object *obj,
+				 const struct md_op_spec *spec,
+				 struct md_attr *ma);
+
+	int (*moo_ref_add)(const struct lu_env *env,
+			   struct md_object *obj,
+			   const struct md_attr *ma);
+
+	int (*moo_ref_del)(const struct lu_env *env,
+			   struct md_object *obj,
+			   struct md_attr *ma);
+
+	int (*moo_open)(const struct lu_env *env,
+			struct md_object *obj, int flag);
+
+	int (*moo_close)(const struct lu_env *env, struct md_object *obj,
+			 struct md_attr *ma, int mode);
+
+	int (*moo_capa_get)(const struct lu_env *, struct md_object *,
+			    struct lustre_capa *, int renewal);
+
+	int (*moo_object_sync)(const struct lu_env *, struct md_object *);
+
+	int (*moo_file_lock)(const struct lu_env *env, struct md_object *obj,
+			     struct lov_mds_md *lmm, struct ldlm_extent *extent,
+			     struct lustre_handle *lockh);
+	int (*moo_file_unlock)(const struct lu_env *env, struct md_object *obj,
+			       struct lov_mds_md *lmm,
+			       struct lustre_handle *lockh);
+	int (*moo_object_lock)(const struct lu_env *env, struct md_object *obj,
+			       struct lustre_handle *lh,
+			       struct ldlm_enqueue_info *einfo,
+			       void *policy);
+};
+
+/**
+ * Operations implemented for each directory object.
+ */
+struct md_dir_operations {
+	int (*mdo_is_subdir) (const struct lu_env *env, struct md_object *obj,
+			      const struct lu_fid *fid, struct lu_fid *sfid);
+
+	int (*mdo_lookup)(const struct lu_env *env, struct md_object *obj,
+			  const struct lu_name *lname, struct lu_fid *fid,
+			  struct md_op_spec *spec);
+
+	mdl_mode_t (*mdo_lock_mode)(const struct lu_env *env,
+				    struct md_object *obj,
+				    mdl_mode_t mode);
+
+	int (*mdo_create)(const struct lu_env *env, struct md_object *pobj,
+			  const struct lu_name *lname, struct md_object *child,
+			  struct md_op_spec *spec,
+			  struct md_attr *ma);
+
+	/** This method is used for creating data object for this meta object*/
+	int (*mdo_create_data)(const struct lu_env *env, struct md_object *p,
+			       struct md_object *o,
+			       const struct md_op_spec *spec,
+			       struct md_attr *ma);
+
+	int (*mdo_rename)(const struct lu_env *env, struct md_object *spobj,
+			  struct md_object *tpobj, const struct lu_fid *lf,
+			  const struct lu_name *lsname, struct md_object *tobj,
+			  const struct lu_name *ltname, struct md_attr *ma);
+
+	int (*mdo_link)(const struct lu_env *env, struct md_object *tgt_obj,
+			struct md_object *src_obj, const struct lu_name *lname,
+			struct md_attr *ma);
+
+	int (*mdo_unlink)(const struct lu_env *env, struct md_object *pobj,
+			  struct md_object *cobj, const struct lu_name *lname,
+			  struct md_attr *ma, int no_name);
+
+	/** This method is used to compare a requested layout to an existing
+	 * layout (struct lov_mds_md_v1/3 vs struct lov_mds_md_v1/3) */
+	int (*mdo_lum_lmm_cmp)(const struct lu_env *env,
+			       struct md_object *cobj,
+			       const struct md_op_spec *spec,
+			       struct md_attr *ma);
+
+	/** partial ops for cross-ref case */
+	int (*mdo_name_insert)(const struct lu_env *env,
+			       struct md_object *obj,
+			       const struct lu_name *lname,
+			       const struct lu_fid *fid,
+			       const struct md_attr *ma);
+
+	int (*mdo_name_remove)(const struct lu_env *env,
+			       struct md_object *obj,
+			       const struct lu_name *lname,
+			       const struct md_attr *ma);
+
+	int (*mdo_rename_tgt)(const struct lu_env *env, struct md_object *pobj,
+			      struct md_object *tobj, const struct lu_fid *fid,
+			      const struct lu_name *lname, struct md_attr *ma);
+};
+
+struct md_device_operations {
+	/** meta-data device related handlers. */
+	int (*mdo_root_get)(const struct lu_env *env, struct md_device *m,
+			    struct lu_fid *f);
+
+	int (*mdo_maxsize_get)(const struct lu_env *env, struct md_device *m,
+			       int *md_size, int *cookie_size);
+
+	int (*mdo_statfs)(const struct lu_env *env, struct md_device *m,
+			  struct obd_statfs *sfs);
+
+	int (*mdo_init_capa_ctxt)(const struct lu_env *env, struct md_device *m,
+				  int mode, unsigned long timeout, __u32 alg,
+				  struct lustre_capa_key *keys);
+
+	int (*mdo_update_capa_key)(const struct lu_env *env,
+				   struct md_device *m,
+				   struct lustre_capa_key *key);
+
+	int (*mdo_llog_ctxt_get)(const struct lu_env *env,
+				 struct md_device *m, int idx, void **h);
+
+	int (*mdo_iocontrol)(const struct lu_env *env, struct md_device *m,
+			     unsigned int cmd, int len, void *data);
+};
+
+enum md_upcall_event {
+	/** Sync the md layer*/
+	MD_LOV_SYNC = (1 << 0),
+	/** Just for split, no need trans, for replay */
+	MD_NO_TRANS = (1 << 1),
+	MD_LOV_CONFIG = (1 << 2),
+	/** Trigger quota recovery */
+	MD_LOV_QUOTA = (1 << 3)
+};
+
+struct md_upcall {
+	/** this lock protects upcall using against its removal
+	 * read lock is for usage the upcall, write - for init/fini */
+	struct rw_semaphore	mu_upcall_sem;
+	/** device to call, upper layer normally */
+	struct md_device       *mu_upcall_dev;
+	/** upcall function */
+	int (*mu_upcall)(const struct lu_env *env, struct md_device *md,
+			 enum md_upcall_event ev, void *data);
+};
+
+struct md_device {
+	struct lu_device		   md_lu_dev;
+	const struct md_device_operations *md_ops;
+	struct md_upcall		   md_upcall;
+};
+
+static inline void md_upcall_init(struct md_device *m, void *upcl)
+{
+	init_rwsem(&m->md_upcall.mu_upcall_sem);
+	m->md_upcall.mu_upcall_dev = NULL;
+	m->md_upcall.mu_upcall = upcl;
+}
+
+static inline void md_upcall_dev_set(struct md_device *m, struct md_device *up)
+{
+	down_write(&m->md_upcall.mu_upcall_sem);
+	m->md_upcall.mu_upcall_dev = up;
+	up_write(&m->md_upcall.mu_upcall_sem);
+}
+
+static inline void md_upcall_fini(struct md_device *m)
+{
+	down_write(&m->md_upcall.mu_upcall_sem);
+	m->md_upcall.mu_upcall_dev = NULL;
+	m->md_upcall.mu_upcall = NULL;
+	up_write(&m->md_upcall.mu_upcall_sem);
+}
+
+static inline int md_do_upcall(const struct lu_env *env, struct md_device *m,
+				enum md_upcall_event ev, void *data)
+{
+	int rc = 0;
+	down_read(&m->md_upcall.mu_upcall_sem);
+	if (m->md_upcall.mu_upcall_dev != NULL &&
+	    m->md_upcall.mu_upcall_dev->md_upcall.mu_upcall != NULL) {
+		rc = m->md_upcall.mu_upcall_dev->md_upcall.mu_upcall(env,
+					      m->md_upcall.mu_upcall_dev,
+					      ev, data);
+	}
+	up_read(&m->md_upcall.mu_upcall_sem);
+	return rc;
+}
+
+struct md_object {
+	struct lu_object		   mo_lu;
+	const struct md_object_operations *mo_ops;
+	const struct md_dir_operations    *mo_dir_ops;
+};
+
+/**
+ * seq-server site.
+ */
+struct seq_server_site {
+	struct lu_site	     *ss_lu;
+	/**
+	 * mds number of this site.
+	 */
+	mdsno_t	       ss_node_id;
+	/**
+	 * Fid location database
+	 */
+	struct lu_server_fld *ss_server_fld;
+	struct lu_client_fld *ss_client_fld;
+
+	/**
+	 * Server Seq Manager
+	 */
+	struct lu_server_seq *ss_server_seq;
+
+	/**
+	 * Controller Seq Manager
+	 */
+	struct lu_server_seq *ss_control_seq;
+	struct obd_export    *ss_control_exp;
+
+	/**
+	 * Client Seq Manager
+	 */
+	struct lu_client_seq *ss_client_seq;
+};
+
+static inline struct md_device *lu2md_dev(const struct lu_device *d)
+{
+	LASSERT(IS_ERR(d) || lu_device_is_md(d));
+	return container_of0(d, struct md_device, md_lu_dev);
+}
+
+static inline struct lu_device *md2lu_dev(struct md_device *d)
+{
+	return &d->md_lu_dev;
+}
+
+static inline struct md_object *lu2md(const struct lu_object *o)
+{
+	LASSERT(o == NULL || IS_ERR(o) || lu_device_is_md(o->lo_dev));
+	return container_of0(o, struct md_object, mo_lu);
+}
+
+static inline struct md_object *md_object_next(const struct md_object *obj)
+{
+	return (obj ? lu2md(lu_object_next(&obj->mo_lu)) : NULL);
+}
+
+static inline struct md_device *md_obj2dev(const struct md_object *o)
+{
+	LASSERT(o == NULL || IS_ERR(o) || lu_device_is_md(o->mo_lu.lo_dev));
+	return container_of0(o->mo_lu.lo_dev, struct md_device, md_lu_dev);
+}
+
+static inline struct seq_server_site *lu_site2seq(const struct lu_site *s)
+{
+	return s->ld_seq_site;
+}
+
+static inline int md_device_init(struct md_device *md, struct lu_device_type *t)
+{
+	return lu_device_init(&md->md_lu_dev, t);
+}
+
+static inline void md_device_fini(struct md_device *md)
+{
+	lu_device_fini(&md->md_lu_dev);
+}
+
+static inline struct md_object *md_object_find_slice(const struct lu_env *env,
+						     struct md_device *md,
+						     const struct lu_fid *f)
+{
+	return lu2md(lu_object_find_slice(env, md2lu_dev(md), f, NULL));
+}
+
+
+/** md operations */
+static inline int mo_permission(const struct lu_env *env,
+				struct md_object *p,
+				struct md_object *c,
+				struct md_attr *at,
+				int mask)
+{
+	LASSERT(c->mo_ops->moo_permission);
+	return c->mo_ops->moo_permission(env, p, c, at, mask);
+}
+
+static inline int mo_attr_get(const struct lu_env *env,
+			      struct md_object *m,
+			      struct md_attr *at)
+{
+	LASSERT(m->mo_ops->moo_attr_get);
+	return m->mo_ops->moo_attr_get(env, m, at);
+}
+
+static inline int mo_readlink(const struct lu_env *env,
+			      struct md_object *m,
+			      struct lu_buf *buf)
+{
+	LASSERT(m->mo_ops->moo_readlink);
+	return m->mo_ops->moo_readlink(env, m, buf);
+}
+
+static inline int mo_changelog(const struct lu_env *env,
+			       enum changelog_rec_type type,
+			       int flags, struct md_object *m)
+{
+	LASSERT(m->mo_ops->moo_changelog);
+	return m->mo_ops->moo_changelog(env, type, flags, m);
+}
+
+static inline int mo_attr_set(const struct lu_env *env,
+			      struct md_object *m,
+			      const struct md_attr *at)
+{
+	LASSERT(m->mo_ops->moo_attr_set);
+	return m->mo_ops->moo_attr_set(env, m, at);
+}
+
+static inline int mo_xattr_get(const struct lu_env *env,
+			       struct md_object *m,
+			       struct lu_buf *buf,
+			       const char *name)
+{
+	LASSERT(m->mo_ops->moo_xattr_get);
+	return m->mo_ops->moo_xattr_get(env, m, buf, name);
+}
+
+static inline int mo_xattr_del(const struct lu_env *env,
+			       struct md_object *m,
+			       const char *name)
+{
+	LASSERT(m->mo_ops->moo_xattr_del);
+	return m->mo_ops->moo_xattr_del(env, m, name);
+}
+
+static inline int mo_xattr_set(const struct lu_env *env,
+			       struct md_object *m,
+			       const struct lu_buf *buf,
+			       const char *name,
+			       int flags)
+{
+	LASSERT(m->mo_ops->moo_xattr_set);
+	return m->mo_ops->moo_xattr_set(env, m, buf, name, flags);
+}
+
+static inline int mo_xattr_list(const struct lu_env *env,
+				struct md_object *m,
+				struct lu_buf *buf)
+{
+	LASSERT(m->mo_ops->moo_xattr_list);
+	return m->mo_ops->moo_xattr_list(env, m, buf);
+}
+
+static inline int mo_swap_layouts(const struct lu_env *env,
+				  struct md_object *o1,
+				  struct md_object *o2, __u64 flags)
+{
+	LASSERT(o1->mo_ops->moo_swap_layouts);
+	LASSERT(o2->mo_ops->moo_swap_layouts);
+	if (o1->mo_ops->moo_swap_layouts != o2->mo_ops->moo_swap_layouts)
+		return -EPERM;
+	return o1->mo_ops->moo_swap_layouts(env, o1, o2, flags);
+}
+
+static inline int mo_open(const struct lu_env *env,
+			  struct md_object *m,
+			  int flags)
+{
+	LASSERT(m->mo_ops->moo_open);
+	return m->mo_ops->moo_open(env, m, flags);
+}
+
+static inline int mo_close(const struct lu_env *env,
+			   struct md_object *m,
+			   struct md_attr *ma,
+			   int mode)
+{
+	LASSERT(m->mo_ops->moo_close);
+	return m->mo_ops->moo_close(env, m, ma, mode);
+}
+
+static inline int mo_readpage(const struct lu_env *env,
+			      struct md_object *m,
+			      const struct lu_rdpg *rdpg)
+{
+	LASSERT(m->mo_ops->moo_readpage);
+	return m->mo_ops->moo_readpage(env, m, rdpg);
+}
+
+static inline int mo_object_create(const struct lu_env *env,
+				   struct md_object *m,
+				   const struct md_op_spec *spc,
+				   struct md_attr *at)
+{
+	LASSERT(m->mo_ops->moo_object_create);
+	return m->mo_ops->moo_object_create(env, m, spc, at);
+}
+
+static inline int mo_ref_add(const struct lu_env *env,
+			     struct md_object *m,
+			     const struct md_attr *ma)
+{
+	LASSERT(m->mo_ops->moo_ref_add);
+	return m->mo_ops->moo_ref_add(env, m, ma);
+}
+
+static inline int mo_ref_del(const struct lu_env *env,
+			     struct md_object *m,
+			     struct md_attr *ma)
+{
+	LASSERT(m->mo_ops->moo_ref_del);
+	return m->mo_ops->moo_ref_del(env, m, ma);
+}
+
+static inline int mo_capa_get(const struct lu_env *env,
+			      struct md_object *m,
+			      struct lustre_capa *c,
+			      int renewal)
+{
+	LASSERT(m->mo_ops->moo_capa_get);
+	return m->mo_ops->moo_capa_get(env, m, c, renewal);
+}
+
+static inline int mo_object_sync(const struct lu_env *env, struct md_object *m)
+{
+	LASSERT(m->mo_ops->moo_object_sync);
+	return m->mo_ops->moo_object_sync(env, m);
+}
+
+static inline int mo_file_lock(const struct lu_env *env, struct md_object *m,
+			       struct lov_mds_md *lmm,
+			       struct ldlm_extent *extent,
+			       struct lustre_handle *lockh)
+{
+	LASSERT(m->mo_ops->moo_file_lock);
+	return m->mo_ops->moo_file_lock(env, m, lmm, extent, lockh);
+}
+
+static inline int mo_file_unlock(const struct lu_env *env, struct md_object *m,
+				 struct lov_mds_md *lmm,
+				 struct lustre_handle *lockh)
+{
+	LASSERT(m->mo_ops->moo_file_unlock);
+	return m->mo_ops->moo_file_unlock(env, m, lmm, lockh);
+}
+
+static inline int mo_object_lock(const struct lu_env *env,
+				 struct md_object *m,
+				 struct lustre_handle *lh,
+				 struct ldlm_enqueue_info *einfo,
+				 void *policy)
+{
+	LASSERT(m->mo_ops->moo_object_lock);
+	return m->mo_ops->moo_object_lock(env, m, lh, einfo, policy);
+}
+
+static inline int mdo_lookup(const struct lu_env *env,
+			     struct md_object *p,
+			     const struct lu_name *lname,
+			     struct lu_fid *f,
+			     struct md_op_spec *spec)
+{
+	LASSERT(p->mo_dir_ops->mdo_lookup);
+	return p->mo_dir_ops->mdo_lookup(env, p, lname, f, spec);
+}
+
+static inline mdl_mode_t mdo_lock_mode(const struct lu_env *env,
+				       struct md_object *mo,
+				       mdl_mode_t lm)
+{
+	if (mo->mo_dir_ops->mdo_lock_mode == NULL)
+		return MDL_MINMODE;
+	return mo->mo_dir_ops->mdo_lock_mode(env, mo, lm);
+}
+
+static inline int mdo_create(const struct lu_env *env,
+			     struct md_object *p,
+			     const struct lu_name *lchild_name,
+			     struct md_object *c,
+			     struct md_op_spec *spc,
+			     struct md_attr *at)
+{
+	LASSERT(p->mo_dir_ops->mdo_create);
+	return p->mo_dir_ops->mdo_create(env, p, lchild_name, c, spc, at);
+}
+
+static inline int mdo_create_data(const struct lu_env *env,
+				  struct md_object *p,
+				  struct md_object *c,
+				  const struct md_op_spec *spec,
+				  struct md_attr *ma)
+{
+	LASSERT(c->mo_dir_ops->mdo_create_data);
+	return c->mo_dir_ops->mdo_create_data(env, p, c, spec, ma);
+}
+
+static inline int mdo_rename(const struct lu_env *env,
+			     struct md_object *sp,
+			     struct md_object *tp,
+			     const struct lu_fid *lf,
+			     const struct lu_name *lsname,
+			     struct md_object *t,
+			     const struct lu_name *ltname,
+			     struct md_attr *ma)
+{
+	LASSERT(tp->mo_dir_ops->mdo_rename);
+	return tp->mo_dir_ops->mdo_rename(env, sp, tp, lf, lsname, t, ltname,
+					  ma);
+}
+
+static inline int mdo_is_subdir(const struct lu_env *env,
+				struct md_object *mo,
+				const struct lu_fid *fid,
+				struct lu_fid *sfid)
+{
+	LASSERT(mo->mo_dir_ops->mdo_is_subdir);
+	return mo->mo_dir_ops->mdo_is_subdir(env, mo, fid, sfid);
+}
+
+static inline int mdo_link(const struct lu_env *env,
+			   struct md_object *p,
+			   struct md_object *s,
+			   const struct lu_name *lname,
+			   struct md_attr *ma)
+{
+	LASSERT(s->mo_dir_ops->mdo_link);
+	return s->mo_dir_ops->mdo_link(env, p, s, lname, ma);
+}
+
+static inline int mdo_unlink(const struct lu_env *env,
+			     struct md_object *p,
+			     struct md_object *c,
+			     const struct lu_name *lname,
+			     struct md_attr *ma, int no_name)
+{
+	LASSERT(p->mo_dir_ops->mdo_unlink);
+	return p->mo_dir_ops->mdo_unlink(env, p, c, lname, ma, no_name);
+}
+
+static inline int mdo_lum_lmm_cmp(const struct lu_env *env,
+				  struct md_object *c,
+				  const struct md_op_spec *spec,
+				  struct md_attr *ma)
+{
+	LASSERT(c->mo_dir_ops->mdo_lum_lmm_cmp);
+	return c->mo_dir_ops->mdo_lum_lmm_cmp(env, c, spec, ma);
+}
+
+static inline int mdo_name_insert(const struct lu_env *env,
+				  struct md_object *p,
+				  const struct lu_name *lname,
+				  const struct lu_fid *f,
+				  const struct md_attr *ma)
+{
+	LASSERT(p->mo_dir_ops->mdo_name_insert);
+	return p->mo_dir_ops->mdo_name_insert(env, p, lname, f, ma);
+}
+
+static inline int mdo_name_remove(const struct lu_env *env,
+				  struct md_object *p,
+				  const struct lu_name *lname,
+				  const struct md_attr *ma)
+{
+	LASSERT(p->mo_dir_ops->mdo_name_remove);
+	return p->mo_dir_ops->mdo_name_remove(env, p, lname, ma);
+}
+
+static inline int mdo_rename_tgt(const struct lu_env *env,
+				 struct md_object *p,
+				 struct md_object *t,
+				 const struct lu_fid *lf,
+				 const struct lu_name *lname,
+				 struct md_attr *ma)
+{
+	if (t) {
+		LASSERT(t->mo_dir_ops->mdo_rename_tgt);
+		return t->mo_dir_ops->mdo_rename_tgt(env, p, t, lf, lname, ma);
+	} else {
+		LASSERT(p->mo_dir_ops->mdo_rename_tgt);
+		return p->mo_dir_ops->mdo_rename_tgt(env, p, t, lf, lname, ma);
+	}
+}
+
+/**
+ * Used in MDD/OUT layer for object lock rule
+ **/
+enum mdd_object_role {
+	MOR_SRC_PARENT,
+	MOR_SRC_CHILD,
+	MOR_TGT_PARENT,
+	MOR_TGT_CHILD,
+	MOR_TGT_ORPHAN
+};
+
+struct dt_device;
+/**
+ * Structure to hold object information. This is used to create object
+ * \pre llod_dir exist
+ */
+struct lu_local_obj_desc {
+	const char		      *llod_dir;
+	const char		      *llod_name;
+	__u32			    llod_oid;
+	int			      llod_is_index;
+	const struct dt_index_features  *llod_feat;
+	struct list_head		       llod_linkage;
+};
+
+int lustre_buf2som(void *buf, int rc, struct md_som_data *msd);
+int lustre_buf2hsm(void *buf, int rc, struct md_hsm *mh);
+void lustre_hsm2buf(void *buf, struct md_hsm *mh);
+
+struct lu_ucred {
+	__u32	       uc_valid;
+	__u32	       uc_o_uid;
+	__u32	       uc_o_gid;
+	__u32	       uc_o_fsuid;
+	__u32	       uc_o_fsgid;
+	__u32	       uc_uid;
+	__u32	       uc_gid;
+	__u32	       uc_fsuid;
+	__u32	       uc_fsgid;
+	__u32	       uc_suppgids[2];
+	cfs_cap_t	   uc_cap;
+	__u32	       uc_umask;
+	group_info_t   *uc_ginfo;
+	struct md_identity *uc_identity;
+};
+
+struct lu_ucred *lu_ucred(const struct lu_env *env);
+
+struct lu_ucred *lu_ucred_check(const struct lu_env *env);
+
+struct lu_ucred *lu_ucred_assert(const struct lu_env *env);
+
+int lu_ucred_global_init(void);
+
+void lu_ucred_global_fini(void);
+
+#define md_cap_t(x) (x)
+
+#define MD_CAP_TO_MASK(x) (1 << (x))
+
+#define md_cap_raised(c, flag) (md_cap_t(c) & MD_CAP_TO_MASK(flag))
+
+/* capable() is copied from linux kernel! */
+static inline int md_capable(struct lu_ucred *uc, cfs_cap_t cap)
+{
+	if (md_cap_raised(uc->uc_cap, cap))
+		return 1;
+	return 0;
+}
+
+/** @} md */
+#endif /* _LINUX_MD_OBJECT_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_cache.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_cache.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_cache.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_cache.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _OBD_CACHE_H__
+#define _OBD_CACHE_H__
+
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_cksum.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_cksum.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_cksum.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_cksum.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,176 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __OBD_CKSUM
+#define __OBD_CKSUM
+#include <linux/libcfs/libcfs.h>
+#include <lustre/lustre_idl.h>
+
+static inline unsigned char cksum_obd2cfs(cksum_type_t cksum_type)
+{
+	switch (cksum_type) {
+	case OBD_CKSUM_CRC32:
+		return CFS_HASH_ALG_CRC32;
+	case OBD_CKSUM_ADLER:
+		return CFS_HASH_ALG_ADLER32;
+	case OBD_CKSUM_CRC32C:
+		return CFS_HASH_ALG_CRC32C;
+	default:
+		CERROR("Unknown checksum type (%x)!!!\n", cksum_type);
+		LBUG();
+	}
+	return 0;
+}
+
+/* The OBD_FL_CKSUM_* flags is packed into 5 bits of o_flags, since there can
+ * only be a single checksum type per RPC.
+ *
+ * The OBD_CHECKSUM_* type bits passed in ocd_cksum_types are a 32-bit bitmask
+ * since they need to represent the full range of checksum algorithms that
+ * both the client and server can understand.
+ *
+ * In case of an unsupported types/flags we fall back to ADLER
+ * because that is supported by all clients since 1.8
+ *
+ * In case multiple algorithms are supported the best one is used. */
+static inline obd_flag cksum_type_pack(cksum_type_t cksum_type)
+{
+	unsigned int    performance = 0, tmp;
+	obd_flag	flag = OBD_FL_CKSUM_ADLER;
+
+	if (cksum_type & OBD_CKSUM_CRC32) {
+		tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32));
+		if (tmp > performance) {
+			performance = tmp;
+			flag = OBD_FL_CKSUM_CRC32;
+		}
+	}
+	if (cksum_type & OBD_CKSUM_CRC32C) {
+		tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C));
+		if (tmp > performance) {
+			performance = tmp;
+			flag = OBD_FL_CKSUM_CRC32C;
+		}
+	}
+	if (cksum_type & OBD_CKSUM_ADLER) {
+		tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER));
+		if (tmp > performance) {
+			performance = tmp;
+			flag = OBD_FL_CKSUM_ADLER;
+		}
+	}
+	if (unlikely(cksum_type && !(cksum_type & (OBD_CKSUM_CRC32C |
+						   OBD_CKSUM_CRC32 |
+						   OBD_CKSUM_ADLER))))
+		CWARN("unknown cksum type %x\n", cksum_type);
+
+	return flag;
+}
+
+static inline cksum_type_t cksum_type_unpack(obd_flag o_flags)
+{
+	switch (o_flags & OBD_FL_CKSUM_ALL) {
+	case OBD_FL_CKSUM_CRC32C:
+		return OBD_CKSUM_CRC32C;
+	case OBD_FL_CKSUM_CRC32:
+		return OBD_CKSUM_CRC32;
+	default:
+		break;
+	}
+
+	return OBD_CKSUM_ADLER;
+}
+
+/* Return a bitmask of the checksum types supported on this system.
+ * 1.8 supported ADLER it is base and not depend on hw
+ * Client uses all available local algos
+ */
+static inline cksum_type_t cksum_types_supported_client(void)
+{
+	cksum_type_t ret = OBD_CKSUM_ADLER;
+
+	CDEBUG(D_INFO, "Crypto hash speed: crc %d, crc32c %d, adler %d\n",
+	       cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)),
+	       cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)),
+	       cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER)));
+
+	if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)) > 0)
+		ret |= OBD_CKSUM_CRC32C;
+	if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)) > 0)
+		ret |= OBD_CKSUM_CRC32;
+
+	return ret;
+}
+
+/* Server uses algos that perform at 50% or better of the Adler */
+static inline cksum_type_t cksum_types_supported_server(void)
+{
+	int	     base_speed;
+	cksum_type_t    ret = OBD_CKSUM_ADLER;
+
+	CDEBUG(D_INFO, "Crypto hash speed: crc %d, crc32c %d, adler %d\n",
+	       cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)),
+	       cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)),
+	       cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER)));
+
+	base_speed = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER)) / 2;
+
+	if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)) >=
+	    base_speed)
+		ret |= OBD_CKSUM_CRC32C;
+	if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)) >=
+	    base_speed)
+		ret |= OBD_CKSUM_CRC32;
+
+	return ret;
+}
+
+
+/* Select the best checksum algorithm among those supplied in the cksum_types
+ * input.
+ *
+ * Currently, calling cksum_type_pack() with a mask will return the fastest
+ * checksum type due to its benchmarking at libcfs module load.
+ * Caution is advised, however, since what is fastest on a single client may
+ * not be the fastest or most efficient algorithm on the server.  */
+static inline cksum_type_t cksum_type_select(cksum_type_t cksum_types)
+{
+	return cksum_type_unpack(cksum_type_pack(cksum_types));
+}
+
+/* Checksum algorithm names. Must be defined in the same order as the
+ * OBD_CKSUM_* flags. */
+#define DECLARE_CKSUM_NAME char *cksum_name[] = {"crc32", "adler", "crc32c"}
+
+#endif /* __OBD_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_class.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_class.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_class.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_class.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2281 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+#ifndef __CLASS_OBD_H
+#define __CLASS_OBD_H
+
+
+#include <obd_support.h>
+#include <lustre_import.h>
+#include <lustre_net.h>
+#include <obd.h>
+#include <lustre_lib.h>
+#include <lustre/lustre_idl.h>
+#include <lprocfs_status.h>
+
+#include <linux/obd_class.h>
+
+#define OBD_STATFS_NODELAY      0x0001  /* requests should be send without delay
+					 * and resends for avoid deadlocks */
+#define OBD_STATFS_FROM_CACHE   0x0002  /* the statfs callback should not update
+					 * obd_osfs_age */
+#define OBD_STATFS_PTLRPCD      0x0004  /* requests will be sent via ptlrpcd
+					 * instead of a specific set. This
+					 * means that we cannot rely on the set
+					 * interpret routine to be called.
+					 * lov_statfs_fini() must thus be called
+					 * by the request interpret routine */
+#define OBD_STATFS_FOR_MDT0	0x0008	/* The statfs is only for retrieving
+					 * information from MDT0. */
+#define OBD_FL_PUNCH    0x00000001      /* To indicate it is punch operation */
+
+/* OBD Device Declarations */
+extern struct obd_device *obd_devs[MAX_OBD_DEVICES];
+extern rwlock_t obd_dev_lock;
+
+/* OBD Operations Declarations */
+extern struct obd_device *class_conn2obd(struct lustre_handle *);
+extern struct obd_device *class_exp2obd(struct obd_export *);
+extern int class_handle_ioctl(unsigned int cmd, unsigned long arg);
+extern int lustre_get_jobid(char *jobid);
+
+struct lu_device_type;
+
+/* genops.c */
+struct obd_export *class_conn2export(struct lustre_handle *);
+int class_register_type(struct obd_ops *, struct md_ops *,
+			struct lprocfs_vars *, const char *nm,
+			struct lu_device_type *ldt);
+int class_unregister_type(const char *nm);
+
+struct obd_device *class_newdev(const char *type_name, const char *name);
+void class_release_dev(struct obd_device *obd);
+
+int class_name2dev(const char *name);
+struct obd_device *class_name2obd(const char *name);
+int class_uuid2dev(struct obd_uuid *uuid);
+struct obd_device *class_uuid2obd(struct obd_uuid *uuid);
+void class_obd_list(void);
+struct obd_device * class_find_client_obd(struct obd_uuid *tgt_uuid,
+					  const char * typ_name,
+					  struct obd_uuid *grp_uuid);
+struct obd_device * class_devices_in_group(struct obd_uuid *grp_uuid,
+					   int *next);
+struct obd_device * class_num2obd(int num);
+int get_devices_count(void);
+
+int class_notify_sptlrpc_conf(const char *fsname, int namelen);
+
+char *obd_export_nid2str(struct obd_export *exp);
+
+int obd_export_evict_by_nid(struct obd_device *obd, const char *nid);
+int obd_export_evict_by_uuid(struct obd_device *obd, const char *uuid);
+int obd_connect_flags2str(char *page, int count, __u64 flags, char *sep);
+
+int obd_zombie_impexp_init(void);
+void obd_zombie_impexp_stop(void);
+void obd_zombie_impexp_cull(void);
+void obd_zombie_barrier(void);
+void obd_exports_barrier(struct obd_device *obd);
+int kuc_len(int payload_len);
+struct kuc_hdr * kuc_ptr(void *p);
+int kuc_ispayload(void *p);
+void *kuc_alloc(int payload_len, int transport, int type);
+void kuc_free(void *p, int payload_len);
+
+struct llog_handle;
+struct llog_rec_hdr;
+typedef int (*llog_cb_t)(const struct lu_env *, struct llog_handle *,
+			 struct llog_rec_hdr *, void *);
+/* obd_config.c */
+struct lustre_cfg *lustre_cfg_rename(struct lustre_cfg *cfg,
+				     const char *new_name);
+int class_process_config(struct lustre_cfg *lcfg);
+int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
+			     struct lustre_cfg *lcfg, void *data);
+int class_attach(struct lustre_cfg *lcfg);
+int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg);
+int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg);
+int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg);
+struct obd_device *class_incref(struct obd_device *obd,
+				const char *scope, const void *source);
+void class_decref(struct obd_device *obd,
+		  const char *scope, const void *source);
+void dump_exports(struct obd_device *obd, int locks);
+int class_config_llog_handler(const struct lu_env *env,
+			      struct llog_handle *handle,
+			      struct llog_rec_hdr *rec, void *data);
+int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg);
+int class_add_uuid(const char *uuid, __u64 nid);
+
+/*obdecho*/
+#ifdef LPROCFS
+extern void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars);
+#else
+static inline void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars)
+{
+	memset(lvars, 0, sizeof(*lvars));
+}
+#endif
+
+#define CFG_F_START     0x01   /* Set when we start updating from a log */
+#define CFG_F_MARKER    0x02   /* We are within a maker */
+#define CFG_F_SKIP      0x04   /* We should ignore this cfg command */
+#define CFG_F_COMPAT146 0x08   /* Allow old-style logs */
+#define CFG_F_EXCLUDE   0x10   /* OST exclusion list */
+
+/* Passed as data param to class_config_parse_llog */
+struct config_llog_instance {
+	char	       *cfg_obdname;
+	void	       *cfg_instance;
+	struct super_block *cfg_sb;
+	struct obd_uuid     cfg_uuid;
+	llog_cb_t	    cfg_callback;
+	int		 cfg_last_idx; /* for partial llog processing */
+	int		 cfg_flags;
+};
+int class_config_parse_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
+			    char *name, struct config_llog_instance *cfg);
+int class_config_dump_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
+			   char *name, struct config_llog_instance *cfg);
+
+enum {
+	CONFIG_T_CONFIG  = 0,
+	CONFIG_T_SPTLRPC = 1,
+	CONFIG_T_RECOVER = 2,
+	CONFIG_T_MAX     = 3
+};
+
+/* list of active configuration logs  */
+struct config_llog_data {
+	struct ldlm_res_id	  cld_resid;
+	struct config_llog_instance cld_cfg;
+	struct list_head		  cld_list_chain;
+	atomic_t		cld_refcount;
+	struct config_llog_data    *cld_sptlrpc;/* depended sptlrpc log */
+	struct config_llog_data    *cld_recover;    /* imperative recover log */
+	struct obd_export	  *cld_mgcexp;
+	struct mutex		    cld_lock;
+	int			 cld_type;
+	unsigned int		cld_stopping:1, /* we were told to stop
+						     * watching */
+				    cld_lostlock:1; /* lock not requeued */
+	char			cld_logname[0];
+};
+
+struct lustre_profile {
+	struct list_head       lp_list;
+	char	    *lp_profile;
+	char	    *lp_dt;
+	char	    *lp_md;
+};
+
+struct lustre_profile *class_get_profile(const char * prof);
+void class_del_profile(const char *prof);
+void class_del_profiles(void);
+
+#if LUSTRE_TRACKS_LOCK_EXP_REFS
+
+void __class_export_add_lock_ref(struct obd_export *, struct ldlm_lock *);
+void __class_export_del_lock_ref(struct obd_export *, struct ldlm_lock *);
+extern void (*class_export_dump_hook)(struct obd_export *);
+
+#else
+
+#define __class_export_add_lock_ref(exp, lock)	     do {} while(0)
+#define __class_export_del_lock_ref(exp, lock)	     do {} while(0)
+
+#endif
+
+#define class_export_rpc_inc(exp)				       \
+({								      \
+	atomic_inc(&(exp)->exp_rpc_count);			  \
+	CDEBUG(D_INFO, "RPC GETting export %p : new rpc_count %d\n",    \
+	       (exp), atomic_read(&(exp)->exp_rpc_count));	  \
+})
+
+#define class_export_rpc_dec(exp)				       \
+({								      \
+	LASSERT_ATOMIC_POS(&exp->exp_rpc_count);			\
+	atomic_dec(&(exp)->exp_rpc_count);			  \
+	CDEBUG(D_INFO, "RPC PUTting export %p : new rpc_count %d\n",    \
+	       (exp), atomic_read(&(exp)->exp_rpc_count));	  \
+})
+
+#define class_export_lock_get(exp, lock)				\
+({								      \
+	atomic_inc(&(exp)->exp_locks_count);			\
+	__class_export_add_lock_ref(exp, lock);			 \
+	CDEBUG(D_INFO, "lock GETting export %p : new locks_count %d\n", \
+	       (exp), atomic_read(&(exp)->exp_locks_count));	\
+	class_export_get(exp);					  \
+})
+
+#define class_export_lock_put(exp, lock)				\
+({								      \
+	LASSERT_ATOMIC_POS(&exp->exp_locks_count);		      \
+	atomic_dec(&(exp)->exp_locks_count);			\
+	__class_export_del_lock_ref(exp, lock);			 \
+	CDEBUG(D_INFO, "lock PUTting export %p : new locks_count %d\n", \
+	       (exp), atomic_read(&(exp)->exp_locks_count));	\
+	class_export_put(exp);					  \
+})
+
+#define class_export_cb_get(exp)					\
+({								      \
+	atomic_inc(&(exp)->exp_cb_count);			   \
+	CDEBUG(D_INFO, "callback GETting export %p : new cb_count %d\n",\
+	       (exp), atomic_read(&(exp)->exp_cb_count));	   \
+	class_export_get(exp);					  \
+})
+
+#define class_export_cb_put(exp)					\
+({								      \
+	LASSERT_ATOMIC_POS(&exp->exp_cb_count);			 \
+	atomic_dec(&(exp)->exp_cb_count);			   \
+	CDEBUG(D_INFO, "callback PUTting export %p : new cb_count %d\n",\
+	       (exp), atomic_read(&(exp)->exp_cb_count));	   \
+	class_export_put(exp);					  \
+})
+
+/* genops.c */
+struct obd_export *class_export_get(struct obd_export *exp);
+void class_export_put(struct obd_export *exp);
+struct obd_export *class_new_export(struct obd_device *obddev,
+				    struct obd_uuid *cluuid);
+void class_unlink_export(struct obd_export *exp);
+
+struct obd_import *class_import_get(struct obd_import *);
+void class_import_put(struct obd_import *);
+struct obd_import *class_new_import(struct obd_device *obd);
+void class_destroy_import(struct obd_import *exp);
+
+struct obd_type *class_search_type(const char *name);
+struct obd_type *class_get_type(const char *name);
+void class_put_type(struct obd_type *type);
+int class_connect(struct lustre_handle *conn, struct obd_device *obd,
+		  struct obd_uuid *cluuid);
+int class_disconnect(struct obd_export *exp);
+void class_fail_export(struct obd_export *exp);
+int class_connected_export(struct obd_export *exp);
+void class_disconnect_exports(struct obd_device *obddev);
+int class_manual_cleanup(struct obd_device *obd);
+void class_disconnect_stale_exports(struct obd_device *,
+				    int (*test_export)(struct obd_export *));
+static inline enum obd_option exp_flags_from_obd(struct obd_device *obd)
+{
+	return ((obd->obd_fail ? OBD_OPT_FAILOVER : 0) |
+		(obd->obd_force ? OBD_OPT_FORCE : 0) |
+		(obd->obd_abort_recovery ? OBD_OPT_ABORT_RECOV : 0) |
+		0);
+}
+
+
+void obdo_cpy_md(struct obdo *dst, struct obdo *src, obd_flag valid);
+void obdo_to_ioobj(struct obdo *oa, struct obd_ioobj *ioobj);
+void obdo_from_iattr(struct obdo *oa, struct iattr *attr,
+		     unsigned int ia_valid);
+void iattr_from_obdo(struct iattr *attr, struct obdo *oa, obd_flag valid);
+void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, obd_flag valid);
+void obdo_from_md(struct obdo *oa, struct md_op_data *op_data,
+		  unsigned int valid);
+
+void obdo_cpu_to_le(struct obdo *dobdo, struct obdo *sobdo);
+void obdo_le_to_cpu(struct obdo *dobdo, struct obdo *sobdo);
+
+#define OBT(dev)	(dev)->obd_type
+#define OBP(dev, op)    (dev)->obd_type->typ_dt_ops->o_ ## op
+#define MDP(dev, op)    (dev)->obd_type->typ_md_ops->m_ ## op
+#define CTXTP(ctxt, op) (ctxt)->loc_logops->lop_##op
+
+/* Ensure obd_setup: used for cleanup which must be called
+   while obd is stopping */
+#define OBD_CHECK_DEV(obd)				      \
+do {							    \
+	if (!(obd)) {					   \
+		CERROR("NULL device\n");			\
+		RETURN(-ENODEV);				\
+	}						       \
+} while (0)
+
+/* ensure obd_setup and !obd_stopping */
+#define OBD_CHECK_DEV_ACTIVE(obd)			       \
+do {							    \
+	OBD_CHECK_DEV(obd);				     \
+	if (!(obd)->obd_set_up || (obd)->obd_stopping) {	\
+		CERROR("Device %d not setup\n",		 \
+		       (obd)->obd_minor);		       \
+		RETURN(-ENODEV);				\
+	}						       \
+} while (0)
+
+
+#ifdef LPROCFS
+#define OBD_COUNTER_OFFSET(op)				  \
+	((offsetof(struct obd_ops, o_ ## op) -		  \
+	  offsetof(struct obd_ops, o_iocontrol))		\
+	 / sizeof(((struct obd_ops *)(0))->o_iocontrol))
+
+#define OBD_COUNTER_INCREMENT(obdx, op)			   \
+	if ((obdx)->obd_stats != NULL) {			  \
+		unsigned int coffset;			     \
+		coffset = (unsigned int)((obdx)->obd_cntr_base) + \
+			OBD_COUNTER_OFFSET(op);		   \
+		LASSERT(coffset < (obdx)->obd_stats->ls_num);     \
+		lprocfs_counter_incr((obdx)->obd_stats, coffset); \
+	}
+
+#define EXP_COUNTER_INCREMENT(export, op)				    \
+	if ((export)->exp_obd->obd_stats != NULL) {			  \
+		unsigned int coffset;					\
+		coffset = (unsigned int)((export)->exp_obd->obd_cntr_base) + \
+			OBD_COUNTER_OFFSET(op);			      \
+		LASSERT(coffset < (export)->exp_obd->obd_stats->ls_num);     \
+		lprocfs_counter_incr((export)->exp_obd->obd_stats, coffset); \
+		if ((export)->exp_nid_stats != NULL &&		       \
+		    (export)->exp_nid_stats->nid_stats != NULL)	      \
+			lprocfs_counter_incr(				\
+				(export)->exp_nid_stats->nid_stats, coffset);\
+	}
+
+#define MD_COUNTER_OFFSET(op)				   \
+	((offsetof(struct md_ops, m_ ## op) -		   \
+	  offsetof(struct md_ops, m_getstatus))		 \
+	 / sizeof(((struct md_ops *)(0))->m_getstatus))
+
+#define MD_COUNTER_INCREMENT(obdx, op)			   \
+	if ((obd)->md_stats != NULL) {			   \
+		unsigned int coffset;			    \
+		coffset = (unsigned int)((obdx)->md_cntr_base) + \
+			MD_COUNTER_OFFSET(op);		   \
+		LASSERT(coffset < (obdx)->md_stats->ls_num);     \
+		lprocfs_counter_incr((obdx)->md_stats, coffset); \
+	}
+
+#define EXP_MD_COUNTER_INCREMENT(export, op)				 \
+	if ((export)->exp_obd->obd_stats != NULL) {			  \
+		unsigned int coffset;					\
+		coffset = (unsigned int)((export)->exp_obd->md_cntr_base) +  \
+			MD_COUNTER_OFFSET(op);			       \
+		LASSERT(coffset < (export)->exp_obd->md_stats->ls_num);      \
+		lprocfs_counter_incr((export)->exp_obd->md_stats, coffset);  \
+		if ((export)->exp_md_stats != NULL)			  \
+			lprocfs_counter_incr(				\
+				(export)->exp_md_stats, coffset);	    \
+	}
+
+#else
+#define OBD_COUNTER_OFFSET(op)
+#define OBD_COUNTER_INCREMENT(obd, op)
+#define EXP_COUNTER_INCREMENT(exp, op)
+#define MD_COUNTER_INCREMENT(obd, op)
+#define EXP_MD_COUNTER_INCREMENT(exp, op)
+#endif
+
+static inline int lprocfs_nid_ldlm_stats_init(struct nid_stat* tmp)
+{
+	/* Always add in ldlm_stats */
+	tmp->nid_ldlm_stats = lprocfs_alloc_stats(LDLM_LAST_OPC - LDLM_FIRST_OPC
+						  ,LPROCFS_STATS_FLAG_NOPERCPU);
+	if (tmp->nid_ldlm_stats == NULL)
+		return -ENOMEM;
+
+	lprocfs_init_ldlm_stats(tmp->nid_ldlm_stats);
+
+	return lprocfs_register_stats(tmp->nid_proc, "ldlm_stats",
+				      tmp->nid_ldlm_stats);
+}
+
+#define OBD_CHECK_MD_OP(obd, op, err)			   \
+do {							    \
+	if (!OBT(obd) || !MDP((obd), op)) {		     \
+		if (err)					\
+			CERROR("md_" #op ": dev %s/%d no operation\n", \
+			       obd->obd_name, obd->obd_minor);  \
+		RETURN(err);				    \
+	}						       \
+} while (0)
+
+#define EXP_CHECK_MD_OP(exp, op)				\
+do {							    \
+	if ((exp) == NULL) {				    \
+		CERROR("obd_" #op ": NULL export\n");	   \
+		RETURN(-ENODEV);				\
+	}						       \
+	if ((exp)->exp_obd == NULL || !OBT((exp)->exp_obd)) {   \
+		CERROR("obd_" #op ": cleaned up obd\n");	\
+		RETURN(-EOPNOTSUPP);			    \
+	}						       \
+	if (!OBT((exp)->exp_obd) || !MDP((exp)->exp_obd, op)) { \
+		CERROR("obd_" #op ": dev %s/%d no operation\n", \
+		       (exp)->exp_obd->obd_name,		\
+		       (exp)->exp_obd->obd_minor);	      \
+		RETURN(-EOPNOTSUPP);			    \
+	}						       \
+} while (0)
+
+
+#define OBD_CHECK_DT_OP(obd, op, err)			   \
+do {							    \
+	if (!OBT(obd) || !OBP((obd), op)) {		     \
+		if (err)					\
+			CERROR("obd_" #op ": dev %d no operation\n",    \
+			       obd->obd_minor);		 \
+		RETURN(err);				    \
+	}						       \
+} while (0)
+
+#define EXP_CHECK_DT_OP(exp, op)				\
+do {							    \
+	if ((exp) == NULL) {				    \
+		CERROR("obd_" #op ": NULL export\n");	   \
+		RETURN(-ENODEV);				\
+	}						       \
+	if ((exp)->exp_obd == NULL || !OBT((exp)->exp_obd)) {   \
+		CERROR("obd_" #op ": cleaned up obd\n");	\
+		RETURN(-EOPNOTSUPP);			    \
+	}						       \
+	if (!OBT((exp)->exp_obd) || !OBP((exp)->exp_obd, op)) { \
+		CERROR("obd_" #op ": dev %d no operation\n",    \
+		       (exp)->exp_obd->obd_minor);	      \
+		RETURN(-EOPNOTSUPP);			    \
+	}						       \
+} while (0)
+
+#define CTXT_CHECK_OP(ctxt, op, err)				 \
+do {								 \
+	if (!OBT(ctxt->loc_obd) || !CTXTP((ctxt), op)) {	     \
+		if (err)					     \
+			CERROR("lop_" #op ": dev %d no operation\n", \
+			       ctxt->loc_obd->obd_minor);	    \
+		RETURN(err);					 \
+	}							    \
+} while (0)
+
+static inline int class_devno_max(void)
+{
+	return MAX_OBD_DEVICES;
+}
+
+static inline int obd_get_info(const struct lu_env *env,
+			       struct obd_export *exp, __u32 keylen,
+			       void *key, __u32 *vallen, void *val,
+			       struct lov_stripe_md *lsm)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, get_info);
+	EXP_COUNTER_INCREMENT(exp, get_info);
+
+	rc = OBP(exp->exp_obd, get_info)(env, exp, keylen, key, vallen, val,
+					 lsm);
+	RETURN(rc);
+}
+
+static inline int obd_set_info_async(const struct lu_env *env,
+				     struct obd_export *exp, obd_count keylen,
+				     void *key, obd_count vallen, void *val,
+				     struct ptlrpc_request_set *set)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, set_info_async);
+	EXP_COUNTER_INCREMENT(exp, set_info_async);
+
+	rc = OBP(exp->exp_obd, set_info_async)(env, exp, keylen, key, vallen,
+					       val, set);
+	RETURN(rc);
+}
+
+/*
+ * obd-lu integration.
+ *
+ * Functionality is being moved into new lu_device-based layering, but some
+ * pieces of configuration process are still based on obd devices.
+ *
+ * Specifically, lu_device_type_operations::ldto_device_alloc() methods fully
+ * subsume ->o_setup() methods of obd devices they replace. The same for
+ * lu_device_operations::ldo_process_config() and ->o_process_config(). As a
+ * result, obd_setup() and obd_process_config() branch and call one XOR
+ * another.
+ *
+ * Yet neither lu_device_type_operations::ldto_device_fini() nor
+ * lu_device_type_operations::ldto_device_free() fully implement the
+ * functionality of ->o_precleanup() and ->o_cleanup() they override. Hence,
+ * obd_precleanup() and obd_cleanup() call both lu_device and obd operations.
+ */
+
+#define DECLARE_LU_VARS(ldt, d)		 \
+	struct lu_device_type *ldt;       \
+	struct lu_device *d
+
+static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg)
+{
+	int rc;
+	DECLARE_LU_VARS(ldt, d);
+	ENTRY;
+
+	ldt = obd->obd_type->typ_lu;
+	if (ldt != NULL) {
+		struct lu_context  session_ctx;
+		struct lu_env env;
+		lu_context_init(&session_ctx, LCT_SESSION);
+		session_ctx.lc_thread = NULL;
+		lu_context_enter(&session_ctx);
+
+		rc = lu_env_init(&env, ldt->ldt_ctx_tags);
+		if (rc == 0) {
+			env.le_ses = &session_ctx;
+			d = ldt->ldt_ops->ldto_device_alloc(&env, ldt, cfg);
+			lu_env_fini(&env);
+			if (!IS_ERR(d)) {
+				obd->obd_lu_dev = d;
+				d->ld_obd = obd;
+				rc = 0;
+			} else
+				rc = PTR_ERR(d);
+		}
+		lu_context_exit(&session_ctx);
+		lu_context_fini(&session_ctx);
+
+	} else {
+		OBD_CHECK_DT_OP(obd, setup, -EOPNOTSUPP);
+		OBD_COUNTER_INCREMENT(obd, setup);
+		rc = OBP(obd, setup)(obd, cfg);
+	}
+	RETURN(rc);
+}
+
+static inline int obd_precleanup(struct obd_device *obd,
+				 enum obd_cleanup_stage cleanup_stage)
+{
+	int rc;
+	DECLARE_LU_VARS(ldt, d);
+	ENTRY;
+
+	OBD_CHECK_DEV(obd);
+	ldt = obd->obd_type->typ_lu;
+	d = obd->obd_lu_dev;
+	if (ldt != NULL && d != NULL) {
+		if (cleanup_stage == OBD_CLEANUP_EXPORTS) {
+			struct lu_env env;
+
+			rc = lu_env_init(&env, ldt->ldt_ctx_tags);
+			if (rc == 0) {
+				ldt->ldt_ops->ldto_device_fini(&env, d);
+				lu_env_fini(&env);
+			}
+		}
+	}
+	OBD_CHECK_DT_OP(obd, precleanup, 0);
+	OBD_COUNTER_INCREMENT(obd, precleanup);
+
+	rc = OBP(obd, precleanup)(obd, cleanup_stage);
+	RETURN(rc);
+}
+
+static inline int obd_cleanup(struct obd_device *obd)
+{
+	int rc;
+	DECLARE_LU_VARS(ldt, d);
+	ENTRY;
+
+	OBD_CHECK_DEV(obd);
+
+	ldt = obd->obd_type->typ_lu;
+	d = obd->obd_lu_dev;
+	if (ldt != NULL && d != NULL) {
+		struct lu_env env;
+
+		rc = lu_env_init(&env, ldt->ldt_ctx_tags);
+		if (rc == 0) {
+			ldt->ldt_ops->ldto_device_free(&env, d);
+			lu_env_fini(&env);
+			obd->obd_lu_dev = NULL;
+		}
+	}
+	OBD_CHECK_DT_OP(obd, cleanup, 0);
+	OBD_COUNTER_INCREMENT(obd, cleanup);
+
+	rc = OBP(obd, cleanup)(obd);
+	RETURN(rc);
+}
+
+static inline void obd_cleanup_client_import(struct obd_device *obd)
+{
+	ENTRY;
+
+	/* If we set up but never connected, the
+	   client import will not have been cleaned. */
+	down_write(&obd->u.cli.cl_sem);
+	if (obd->u.cli.cl_import) {
+		struct obd_import *imp;
+		imp = obd->u.cli.cl_import;
+		CDEBUG(D_CONFIG, "%s: client import never connected\n",
+		       obd->obd_name);
+		ptlrpc_invalidate_import(imp);
+		if (imp->imp_rq_pool) {
+			ptlrpc_free_rq_pool(imp->imp_rq_pool);
+			imp->imp_rq_pool = NULL;
+		}
+		client_destroy_import(imp);
+		obd->u.cli.cl_import = NULL;
+	}
+	up_write(&obd->u.cli.cl_sem);
+
+	EXIT;
+}
+
+static inline int
+obd_process_config(struct obd_device *obd, int datalen, void *data)
+{
+	int rc;
+	DECLARE_LU_VARS(ldt, d);
+	ENTRY;
+
+	OBD_CHECK_DEV(obd);
+
+	obd->obd_process_conf = 1;
+	ldt = obd->obd_type->typ_lu;
+	d = obd->obd_lu_dev;
+	if (ldt != NULL && d != NULL) {
+		struct lu_env env;
+
+		rc = lu_env_init(&env, ldt->ldt_ctx_tags);
+		if (rc == 0) {
+			rc = d->ld_ops->ldo_process_config(&env, d, data);
+			lu_env_fini(&env);
+		}
+	} else {
+		OBD_CHECK_DT_OP(obd, process_config, -EOPNOTSUPP);
+		rc = OBP(obd, process_config)(obd, datalen, data);
+	}
+	OBD_COUNTER_INCREMENT(obd, process_config);
+	obd->obd_process_conf = 0;
+
+	RETURN(rc);
+}
+
+/* Pack an in-memory MD struct for storage on disk.
+ * Returns +ve size of packed MD (0 for free), or -ve error.
+ *
+ * If @disk_tgt == NULL, MD size is returned (max size if @mem_src == NULL).
+ * If @*disk_tgt != NULL and @mem_src == NULL, @*disk_tgt will be freed.
+ * If @*disk_tgt == NULL, it will be allocated
+ */
+static inline int obd_packmd(struct obd_export *exp,
+			     struct lov_mds_md **disk_tgt,
+			     struct lov_stripe_md *mem_src)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, packmd);
+	EXP_COUNTER_INCREMENT(exp, packmd);
+
+	rc = OBP(exp->exp_obd, packmd)(exp, disk_tgt, mem_src);
+	RETURN(rc);
+}
+
+static inline int obd_size_diskmd(struct obd_export *exp,
+				  struct lov_stripe_md *mem_src)
+{
+	return obd_packmd(exp, NULL, mem_src);
+}
+
+/* helper functions */
+static inline int obd_alloc_diskmd(struct obd_export *exp,
+				   struct lov_mds_md **disk_tgt)
+{
+	LASSERT(disk_tgt);
+	LASSERT(*disk_tgt == NULL);
+	return obd_packmd(exp, disk_tgt, NULL);
+}
+
+static inline int obd_free_diskmd(struct obd_export *exp,
+				  struct lov_mds_md **disk_tgt)
+{
+	LASSERT(disk_tgt);
+	LASSERT(*disk_tgt);
+	/*
+	 * LU-2590, for caller's convenience, *disk_tgt could be host
+	 * endianness, it needs swab to LE if necessary, while just
+	 * lov_mds_md header needs it for figuring out how much memory
+	 * needs to be freed.
+	 */
+	if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) &&
+	    (((*disk_tgt)->lmm_magic == LOV_MAGIC_V1) ||
+	     ((*disk_tgt)->lmm_magic == LOV_MAGIC_V3)))
+		lustre_swab_lov_mds_md(*disk_tgt);
+	return obd_packmd(exp, disk_tgt, NULL);
+}
+
+/* Unpack an MD struct from disk to in-memory format.
+ * Returns +ve size of unpacked MD (0 for free), or -ve error.
+ *
+ * If @mem_tgt == NULL, MD size is returned (max size if @disk_src == NULL).
+ * If @*mem_tgt != NULL and @disk_src == NULL, @*mem_tgt will be freed.
+ * If @*mem_tgt == NULL, it will be allocated
+ */
+static inline int obd_unpackmd(struct obd_export *exp,
+			       struct lov_stripe_md **mem_tgt,
+			       struct lov_mds_md *disk_src,
+			       int disk_len)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, unpackmd);
+	EXP_COUNTER_INCREMENT(exp, unpackmd);
+
+	rc = OBP(exp->exp_obd, unpackmd)(exp, mem_tgt, disk_src, disk_len);
+	RETURN(rc);
+}
+
+/* helper functions */
+static inline int obd_alloc_memmd(struct obd_export *exp,
+				  struct lov_stripe_md **mem_tgt)
+{
+	LASSERT(mem_tgt);
+	LASSERT(*mem_tgt == NULL);
+	return obd_unpackmd(exp, mem_tgt, NULL, 0);
+}
+
+static inline int obd_free_memmd(struct obd_export *exp,
+				 struct lov_stripe_md **mem_tgt)
+{
+	int rc;
+
+	LASSERT(mem_tgt);
+	LASSERT(*mem_tgt);
+	rc = obd_unpackmd(exp, mem_tgt, NULL, 0);
+	*mem_tgt = NULL;
+	return rc;
+}
+
+static inline int obd_precreate(struct obd_export *exp)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, precreate);
+	OBD_COUNTER_INCREMENT(exp->exp_obd, precreate);
+
+	rc = OBP(exp->exp_obd, precreate)(exp);
+	RETURN(rc);
+}
+
+static inline int obd_create_async(struct obd_export *exp,
+				   struct obd_info *oinfo,
+				   struct lov_stripe_md **ea,
+				   struct obd_trans_info *oti)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, create_async);
+	EXP_COUNTER_INCREMENT(exp, create_async);
+
+	rc = OBP(exp->exp_obd, create_async)(exp, oinfo, ea, oti);
+	RETURN(rc);
+}
+
+static inline int obd_create(const struct lu_env *env, struct obd_export *exp,
+			     struct obdo *obdo, struct lov_stripe_md **ea,
+			     struct obd_trans_info *oti)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, create);
+	EXP_COUNTER_INCREMENT(exp, create);
+
+	rc = OBP(exp->exp_obd, create)(env, exp, obdo, ea, oti);
+	RETURN(rc);
+}
+
+static inline int obd_destroy(const struct lu_env *env, struct obd_export *exp,
+			      struct obdo *obdo, struct lov_stripe_md *ea,
+			      struct obd_trans_info *oti,
+			      struct obd_export *md_exp, void *capa)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, destroy);
+	EXP_COUNTER_INCREMENT(exp, destroy);
+
+	rc = OBP(exp->exp_obd, destroy)(env, exp, obdo, ea, oti, md_exp, capa);
+	RETURN(rc);
+}
+
+static inline int obd_getattr(const struct lu_env *env, struct obd_export *exp,
+			      struct obd_info *oinfo)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, getattr);
+	EXP_COUNTER_INCREMENT(exp, getattr);
+
+	rc = OBP(exp->exp_obd, getattr)(env, exp, oinfo);
+	RETURN(rc);
+}
+
+static inline int obd_getattr_async(struct obd_export *exp,
+				    struct obd_info *oinfo,
+				    struct ptlrpc_request_set *set)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, getattr_async);
+	EXP_COUNTER_INCREMENT(exp, getattr_async);
+
+	rc = OBP(exp->exp_obd, getattr_async)(exp, oinfo, set);
+	RETURN(rc);
+}
+
+static inline int obd_setattr(const struct lu_env *env, struct obd_export *exp,
+			      struct obd_info *oinfo,
+			      struct obd_trans_info *oti)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, setattr);
+	EXP_COUNTER_INCREMENT(exp, setattr);
+
+	rc = OBP(exp->exp_obd, setattr)(env, exp, oinfo, oti);
+	RETURN(rc);
+}
+
+/* This performs all the requests set init/wait/destroy actions. */
+static inline int obd_setattr_rqset(struct obd_export *exp,
+				    struct obd_info *oinfo,
+				    struct obd_trans_info *oti)
+{
+	struct ptlrpc_request_set *set = NULL;
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, setattr_async);
+	EXP_COUNTER_INCREMENT(exp, setattr_async);
+
+	set =  ptlrpc_prep_set();
+	if (set == NULL)
+		RETURN(-ENOMEM);
+
+	rc = OBP(exp->exp_obd, setattr_async)(exp, oinfo, oti, set);
+	if (rc == 0)
+		rc = ptlrpc_set_wait(set);
+	ptlrpc_set_destroy(set);
+	RETURN(rc);
+}
+
+/* This adds all the requests into @set if @set != NULL, otherwise
+   all requests are sent asynchronously without waiting for response. */
+static inline int obd_setattr_async(struct obd_export *exp,
+				    struct obd_info *oinfo,
+				    struct obd_trans_info *oti,
+				    struct ptlrpc_request_set *set)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, setattr_async);
+	EXP_COUNTER_INCREMENT(exp, setattr_async);
+
+	rc = OBP(exp->exp_obd, setattr_async)(exp, oinfo, oti, set);
+	RETURN(rc);
+}
+
+static inline int obd_add_conn(struct obd_import *imp, struct obd_uuid *uuid,
+			       int priority)
+{
+	struct obd_device *obd = imp->imp_obd;
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DEV_ACTIVE(obd);
+	OBD_CHECK_DT_OP(obd, add_conn, -EOPNOTSUPP);
+	OBD_COUNTER_INCREMENT(obd, add_conn);
+
+	rc = OBP(obd, add_conn)(imp, uuid, priority);
+	RETURN(rc);
+}
+
+static inline int obd_del_conn(struct obd_import *imp, struct obd_uuid *uuid)
+{
+	struct obd_device *obd = imp->imp_obd;
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DEV_ACTIVE(obd);
+	OBD_CHECK_DT_OP(obd, del_conn, -EOPNOTSUPP);
+	OBD_COUNTER_INCREMENT(obd, del_conn);
+
+	rc = OBP(obd, del_conn)(imp, uuid);
+	RETURN(rc);
+}
+
+static inline struct obd_uuid *obd_get_uuid(struct obd_export *exp)
+{
+	struct obd_uuid *uuid;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(exp->exp_obd, get_uuid, NULL);
+	EXP_COUNTER_INCREMENT(exp, get_uuid);
+
+	uuid = OBP(exp->exp_obd, get_uuid)(exp);
+	RETURN(uuid);
+}
+
+/** Create a new /a exp on device /a obd for the uuid /a cluuid
+ * @param exp New export handle
+ * @param d Connect data, supported flags are set, flags also understood
+ *    by obd are returned.
+ */
+static inline int obd_connect(const struct lu_env *env,
+			      struct obd_export **exp,struct obd_device *obd,
+			      struct obd_uuid *cluuid,
+			      struct obd_connect_data *data,
+			      void *localdata)
+{
+	int rc;
+	__u64 ocf = data ? data->ocd_connect_flags : 0; /* for post-condition
+						   * check */
+	ENTRY;
+
+	OBD_CHECK_DEV_ACTIVE(obd);
+	OBD_CHECK_DT_OP(obd, connect, -EOPNOTSUPP);
+	OBD_COUNTER_INCREMENT(obd, connect);
+
+	rc = OBP(obd, connect)(env, exp, obd, cluuid, data, localdata);
+	/* check that only subset is granted */
+	LASSERT(ergo(data != NULL, (data->ocd_connect_flags & ocf) ==
+				    data->ocd_connect_flags));
+	RETURN(rc);
+}
+
+static inline int obd_reconnect(const struct lu_env *env,
+				struct obd_export *exp,
+				struct obd_device *obd,
+				struct obd_uuid *cluuid,
+				struct obd_connect_data *d,
+				void *localdata)
+{
+	int rc;
+	__u64 ocf = d ? d->ocd_connect_flags : 0; /* for post-condition
+						   * check */
+
+	ENTRY;
+
+	OBD_CHECK_DEV_ACTIVE(obd);
+	OBD_CHECK_DT_OP(obd, reconnect, 0);
+	OBD_COUNTER_INCREMENT(obd, reconnect);
+
+	rc = OBP(obd, reconnect)(env, exp, obd, cluuid, d, localdata);
+	/* check that only subset is granted */
+	LASSERT(ergo(d != NULL,
+		     (d->ocd_connect_flags & ocf) == d->ocd_connect_flags));
+	RETURN(rc);
+}
+
+static inline int obd_disconnect(struct obd_export *exp)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, disconnect);
+	EXP_COUNTER_INCREMENT(exp, disconnect);
+
+	rc = OBP(exp->exp_obd, disconnect)(exp);
+	RETURN(rc);
+}
+
+static inline int obd_fid_init(struct obd_device *obd, struct obd_export *exp,
+			       enum lu_cli_type type)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(obd, fid_init, 0);
+	OBD_COUNTER_INCREMENT(obd, fid_init);
+
+	rc = OBP(obd, fid_init)(obd, exp, type);
+	RETURN(rc);
+}
+
+static inline int obd_fid_fini(struct obd_device *obd)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(obd, fid_fini, 0);
+	OBD_COUNTER_INCREMENT(obd, fid_fini);
+
+	rc = OBP(obd, fid_fini)(obd);
+	RETURN(rc);
+}
+
+static inline int obd_fid_alloc(struct obd_export *exp,
+				struct lu_fid *fid,
+				struct md_op_data *op_data)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, fid_alloc);
+	EXP_COUNTER_INCREMENT(exp, fid_alloc);
+
+	rc = OBP(exp->exp_obd, fid_alloc)(exp, fid, op_data);
+	RETURN(rc);
+}
+
+static inline int obd_ping(const struct lu_env *env, struct obd_export *exp)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(exp->exp_obd, ping, 0);
+	EXP_COUNTER_INCREMENT(exp, ping);
+
+	rc = OBP(exp->exp_obd, ping)(env, exp);
+	RETURN(rc);
+}
+
+static inline int obd_pool_new(struct obd_device *obd, char *poolname)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(obd, pool_new, -EOPNOTSUPP);
+	OBD_COUNTER_INCREMENT(obd, pool_new);
+
+	rc = OBP(obd, pool_new)(obd, poolname);
+	RETURN(rc);
+}
+
+static inline int obd_pool_del(struct obd_device *obd, char *poolname)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(obd, pool_del, -EOPNOTSUPP);
+	OBD_COUNTER_INCREMENT(obd, pool_del);
+
+	rc = OBP(obd, pool_del)(obd, poolname);
+	RETURN(rc);
+}
+
+static inline int obd_pool_add(struct obd_device *obd, char *poolname, char *ostname)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(obd, pool_add, -EOPNOTSUPP);
+	OBD_COUNTER_INCREMENT(obd, pool_add);
+
+	rc = OBP(obd, pool_add)(obd, poolname, ostname);
+	RETURN(rc);
+}
+
+static inline int obd_pool_rem(struct obd_device *obd, char *poolname, char *ostname)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(obd, pool_rem, -EOPNOTSUPP);
+	OBD_COUNTER_INCREMENT(obd, pool_rem);
+
+	rc = OBP(obd, pool_rem)(obd, poolname, ostname);
+	RETURN(rc);
+}
+
+static inline void obd_getref(struct obd_device *obd)
+{
+	ENTRY;
+	if (OBT(obd) && OBP(obd, getref)) {
+		OBD_COUNTER_INCREMENT(obd, getref);
+		OBP(obd, getref)(obd);
+	}
+	EXIT;
+}
+
+static inline void obd_putref(struct obd_device *obd)
+{
+	ENTRY;
+	if (OBT(obd) && OBP(obd, putref)) {
+		OBD_COUNTER_INCREMENT(obd, putref);
+		OBP(obd, putref)(obd);
+	}
+	EXIT;
+}
+
+static inline int obd_init_export(struct obd_export *exp)
+{
+	int rc = 0;
+
+	ENTRY;
+	if ((exp)->exp_obd != NULL && OBT((exp)->exp_obd) &&
+	    OBP((exp)->exp_obd, init_export))
+		rc = OBP(exp->exp_obd, init_export)(exp);
+	RETURN(rc);
+}
+
+static inline int obd_destroy_export(struct obd_export *exp)
+{
+	ENTRY;
+	if ((exp)->exp_obd != NULL && OBT((exp)->exp_obd) &&
+	    OBP((exp)->exp_obd, destroy_export))
+		OBP(exp->exp_obd, destroy_export)(exp);
+	RETURN(0);
+}
+
+static inline int obd_extent_calc(struct obd_export *exp,
+				  struct lov_stripe_md *md,
+				  int cmd, obd_off *offset)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_DT_OP(exp, extent_calc);
+	rc = OBP(exp->exp_obd, extent_calc)(exp, md, cmd, offset);
+	RETURN(rc);
+}
+
+static inline struct dentry *
+obd_lvfs_fid2dentry(struct obd_export *exp, struct ost_id *oi, __u32 gen)
+{
+	struct lvfs_run_ctxt *ctxt = &exp->exp_obd->obd_lvfs_ctxt;
+	LASSERT(exp->exp_obd);
+
+	return ctxt->cb_ops.l_fid2dentry(ostid_id(oi), gen, ostid_seq(oi),
+					 exp->exp_obd);
+}
+
+/* @max_age is the oldest time in jiffies that we accept using a cached data.
+ * If the cache is older than @max_age we will get a new value from the
+ * target.  Use a value of "cfs_time_current() + HZ" to guarantee freshness. */
+static inline int obd_statfs_async(struct obd_export *exp,
+				   struct obd_info *oinfo,
+				   __u64 max_age,
+				   struct ptlrpc_request_set *rqset)
+{
+	int rc = 0;
+	struct obd_device *obd;
+	ENTRY;
+
+	if (exp == NULL || exp->exp_obd == NULL)
+		RETURN(-EINVAL);
+
+	obd = exp->exp_obd;
+	OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP);
+	OBD_COUNTER_INCREMENT(obd, statfs);
+
+	CDEBUG(D_SUPER, "%s: osfs %p age "LPU64", max_age "LPU64"\n",
+	       obd->obd_name, &obd->obd_osfs, obd->obd_osfs_age, max_age);
+	if (cfs_time_before_64(obd->obd_osfs_age, max_age)) {
+		rc = OBP(obd, statfs_async)(exp, oinfo, max_age, rqset);
+	} else {
+		CDEBUG(D_SUPER,"%s: use %p cache blocks "LPU64"/"LPU64
+		       " objects "LPU64"/"LPU64"\n",
+		       obd->obd_name, &obd->obd_osfs,
+		       obd->obd_osfs.os_bavail, obd->obd_osfs.os_blocks,
+		       obd->obd_osfs.os_ffree, obd->obd_osfs.os_files);
+		spin_lock(&obd->obd_osfs_lock);
+		memcpy(oinfo->oi_osfs, &obd->obd_osfs, sizeof(*oinfo->oi_osfs));
+		spin_unlock(&obd->obd_osfs_lock);
+		oinfo->oi_flags |= OBD_STATFS_FROM_CACHE;
+		if (oinfo->oi_cb_up)
+			oinfo->oi_cb_up(oinfo, 0);
+	}
+	RETURN(rc);
+}
+
+static inline int obd_statfs_rqset(struct obd_export *exp,
+				   struct obd_statfs *osfs, __u64 max_age,
+				   __u32 flags)
+{
+	struct ptlrpc_request_set *set = NULL;
+	struct obd_info oinfo = { { { 0 } } };
+	int rc = 0;
+	ENTRY;
+
+	set =  ptlrpc_prep_set();
+	if (set == NULL)
+		RETURN(-ENOMEM);
+
+	oinfo.oi_osfs = osfs;
+	oinfo.oi_flags = flags;
+	rc = obd_statfs_async(exp, &oinfo, max_age, set);
+	if (rc == 0)
+		rc = ptlrpc_set_wait(set);
+	ptlrpc_set_destroy(set);
+	RETURN(rc);
+}
+
+/* @max_age is the oldest time in jiffies that we accept using a cached data.
+ * If the cache is older than @max_age we will get a new value from the
+ * target.  Use a value of "cfs_time_current() + HZ" to guarantee freshness. */
+static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp,
+			     struct obd_statfs *osfs, __u64 max_age,
+			     __u32 flags)
+{
+	int rc = 0;
+	struct obd_device *obd = exp->exp_obd;
+	ENTRY;
+
+	if (obd == NULL)
+		RETURN(-EINVAL);
+
+	OBD_CHECK_DT_OP(obd, statfs, -EOPNOTSUPP);
+	OBD_COUNTER_INCREMENT(obd, statfs);
+
+	CDEBUG(D_SUPER, "osfs "LPU64", max_age "LPU64"\n",
+	       obd->obd_osfs_age, max_age);
+	if (cfs_time_before_64(obd->obd_osfs_age, max_age)) {
+		rc = OBP(obd, statfs)(env, exp, osfs, max_age, flags);
+		if (rc == 0) {
+			spin_lock(&obd->obd_osfs_lock);
+			memcpy(&obd->obd_osfs, osfs, sizeof(obd->obd_osfs));
+			obd->obd_osfs_age = cfs_time_current_64();
+			spin_unlock(&obd->obd_osfs_lock);
+		}
+	} else {
+		CDEBUG(D_SUPER, "%s: use %p cache blocks "LPU64"/"LPU64
+		       " objects "LPU64"/"LPU64"\n",
+		       obd->obd_name, &obd->obd_osfs,
+		       obd->obd_osfs.os_bavail, obd->obd_osfs.os_blocks,
+		       obd->obd_osfs.os_ffree, obd->obd_osfs.os_files);
+		spin_lock(&obd->obd_osfs_lock);
+		memcpy(osfs, &obd->obd_osfs, sizeof(*osfs));
+		spin_unlock(&obd->obd_osfs_lock);
+	}
+	RETURN(rc);
+}
+
+static inline int obd_sync_rqset(struct obd_export *exp, struct obd_info *oinfo,
+				 obd_size start, obd_size end)
+{
+	struct ptlrpc_request_set *set = NULL;
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(exp->exp_obd, sync, -EOPNOTSUPP);
+	EXP_COUNTER_INCREMENT(exp, sync);
+
+	set =  ptlrpc_prep_set();
+	if (set == NULL)
+		RETURN(-ENOMEM);
+
+	rc = OBP(exp->exp_obd, sync)(NULL, exp, oinfo, start, end, set);
+	if (rc == 0)
+		rc = ptlrpc_set_wait(set);
+	ptlrpc_set_destroy(set);
+	RETURN(rc);
+}
+
+static inline int obd_sync(const struct lu_env *env, struct obd_export *exp,
+			   struct obd_info *oinfo, obd_size start, obd_size end,
+			   struct ptlrpc_request_set *set)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(exp->exp_obd, sync, -EOPNOTSUPP);
+	EXP_COUNTER_INCREMENT(exp, sync);
+
+	rc = OBP(exp->exp_obd, sync)(env, exp, oinfo, start, end, set);
+	RETURN(rc);
+}
+
+static inline int obd_punch_rqset(struct obd_export *exp,
+				  struct obd_info *oinfo,
+				  struct obd_trans_info *oti)
+{
+	struct ptlrpc_request_set *set = NULL;
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, punch);
+	EXP_COUNTER_INCREMENT(exp, punch);
+
+	set =  ptlrpc_prep_set();
+	if (set == NULL)
+		RETURN(-ENOMEM);
+
+	rc = OBP(exp->exp_obd, punch)(NULL, exp, oinfo, oti, set);
+	if (rc == 0)
+		rc = ptlrpc_set_wait(set);
+	ptlrpc_set_destroy(set);
+	RETURN(rc);
+}
+
+static inline int obd_punch(const struct lu_env *env, struct obd_export *exp,
+			    struct obd_info *oinfo, struct obd_trans_info *oti,
+			    struct ptlrpc_request_set *rqset)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, punch);
+	EXP_COUNTER_INCREMENT(exp, punch);
+
+	rc = OBP(exp->exp_obd, punch)(env, exp, oinfo, oti, rqset);
+	RETURN(rc);
+}
+
+static inline int obd_brw(int cmd, struct obd_export *exp,
+			  struct obd_info *oinfo, obd_count oa_bufs,
+			  struct brw_page *pg, struct obd_trans_info *oti)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, brw);
+	EXP_COUNTER_INCREMENT(exp, brw);
+
+	if (!(cmd & (OBD_BRW_RWMASK | OBD_BRW_CHECK))) {
+		CERROR("obd_brw: cmd must be OBD_BRW_READ, OBD_BRW_WRITE, "
+		       "or OBD_BRW_CHECK\n");
+		LBUG();
+	}
+
+	rc = OBP(exp->exp_obd, brw)(cmd, exp, oinfo, oa_bufs, pg, oti);
+	RETURN(rc);
+}
+
+static inline int obd_preprw(const struct lu_env *env, int cmd,
+			     struct obd_export *exp, struct obdo *oa,
+			     int objcount, struct obd_ioobj *obj,
+			     struct niobuf_remote *remote, int *pages,
+			     struct niobuf_local *local,
+			     struct obd_trans_info *oti,
+			     struct lustre_capa *capa)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, preprw);
+	EXP_COUNTER_INCREMENT(exp, preprw);
+
+	rc = OBP(exp->exp_obd, preprw)(env, cmd, exp, oa, objcount, obj, remote,
+				       pages, local, oti, capa);
+	RETURN(rc);
+}
+
+static inline int obd_commitrw(const struct lu_env *env, int cmd,
+			       struct obd_export *exp, struct obdo *oa,
+			       int objcount, struct obd_ioobj *obj,
+			       struct niobuf_remote *rnb, int pages,
+			       struct niobuf_local *local,
+			       struct obd_trans_info *oti, int rc)
+{
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, commitrw);
+	EXP_COUNTER_INCREMENT(exp, commitrw);
+
+	rc = OBP(exp->exp_obd, commitrw)(env, cmd, exp, oa, objcount, obj,
+					 rnb, pages, local, oti, rc);
+	RETURN(rc);
+}
+
+static inline int obd_merge_lvb(struct obd_export *exp,
+				struct lov_stripe_md *lsm,
+				struct ost_lvb *lvb, int kms_only)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, merge_lvb);
+	EXP_COUNTER_INCREMENT(exp, merge_lvb);
+
+	rc = OBP(exp->exp_obd, merge_lvb)(exp, lsm, lvb, kms_only);
+	RETURN(rc);
+}
+
+static inline int obd_adjust_kms(struct obd_export *exp,
+				 struct lov_stripe_md *lsm, obd_off size,
+				 int shrink)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, adjust_kms);
+	EXP_COUNTER_INCREMENT(exp, adjust_kms);
+
+	rc = OBP(exp->exp_obd, adjust_kms)(exp, lsm, size, shrink);
+	RETURN(rc);
+}
+
+static inline int obd_iocontrol(unsigned int cmd, struct obd_export *exp,
+				int len, void *karg, void *uarg)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, iocontrol);
+	EXP_COUNTER_INCREMENT(exp, iocontrol);
+
+	rc = OBP(exp->exp_obd, iocontrol)(cmd, exp, len, karg, uarg);
+	RETURN(rc);
+}
+
+static inline int obd_enqueue_rqset(struct obd_export *exp,
+				    struct obd_info *oinfo,
+				    struct ldlm_enqueue_info *einfo)
+{
+	struct ptlrpc_request_set *set = NULL;
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, enqueue);
+	EXP_COUNTER_INCREMENT(exp, enqueue);
+
+	set =  ptlrpc_prep_set();
+	if (set == NULL)
+		RETURN(-ENOMEM);
+
+	rc = OBP(exp->exp_obd, enqueue)(exp, oinfo, einfo, set);
+	if (rc == 0)
+		rc = ptlrpc_set_wait(set);
+	ptlrpc_set_destroy(set);
+	RETURN(rc);
+}
+
+static inline int obd_enqueue(struct obd_export *exp,
+			      struct obd_info *oinfo,
+			      struct ldlm_enqueue_info *einfo,
+			      struct ptlrpc_request_set *set)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, enqueue);
+	EXP_COUNTER_INCREMENT(exp, enqueue);
+
+	rc = OBP(exp->exp_obd, enqueue)(exp, oinfo, einfo, set);
+	RETURN(rc);
+}
+
+static inline int obd_change_cbdata(struct obd_export *exp,
+				    struct lov_stripe_md *lsm,
+				    ldlm_iterator_t it, void *data)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, change_cbdata);
+	EXP_COUNTER_INCREMENT(exp, change_cbdata);
+
+	rc = OBP(exp->exp_obd, change_cbdata)(exp, lsm, it, data);
+	RETURN(rc);
+}
+
+static inline int obd_find_cbdata(struct obd_export *exp,
+				  struct lov_stripe_md *lsm,
+				  ldlm_iterator_t it, void *data)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, find_cbdata);
+	EXP_COUNTER_INCREMENT(exp, find_cbdata);
+
+	rc = OBP(exp->exp_obd, find_cbdata)(exp, lsm, it, data);
+	RETURN(rc);
+}
+
+static inline int obd_cancel(struct obd_export *exp,
+			     struct lov_stripe_md *ea, __u32 mode,
+			     struct lustre_handle *lockh)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, cancel);
+	EXP_COUNTER_INCREMENT(exp, cancel);
+
+	rc = OBP(exp->exp_obd, cancel)(exp, ea, mode, lockh);
+	RETURN(rc);
+}
+
+static inline int obd_cancel_unused(struct obd_export *exp,
+				    struct lov_stripe_md *ea,
+				    ldlm_cancel_flags_t flags,
+				    void *opaque)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, cancel_unused);
+	EXP_COUNTER_INCREMENT(exp, cancel_unused);
+
+	rc = OBP(exp->exp_obd, cancel_unused)(exp, ea, flags, opaque);
+	RETURN(rc);
+}
+
+static inline int obd_pin(struct obd_export *exp, const struct lu_fid *fid,
+			  struct obd_capa *oc, struct obd_client_handle *handle,
+			  int flag)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, pin);
+	EXP_COUNTER_INCREMENT(exp, pin);
+
+	rc = OBP(exp->exp_obd, pin)(exp, fid, oc, handle, flag);
+	RETURN(rc);
+}
+
+static inline int obd_unpin(struct obd_export *exp,
+			    struct obd_client_handle *handle, int flag)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, unpin);
+	EXP_COUNTER_INCREMENT(exp, unpin);
+
+	rc = OBP(exp->exp_obd, unpin)(exp, handle, flag);
+	RETURN(rc);
+}
+
+
+static inline void obd_import_event(struct obd_device *obd,
+				    struct obd_import *imp,
+				    enum obd_import_event event)
+{
+	ENTRY;
+	if (!obd) {
+		CERROR("NULL device\n");
+		EXIT;
+		return;
+	}
+	if (obd->obd_set_up && OBP(obd, import_event)) {
+		OBD_COUNTER_INCREMENT(obd, import_event);
+		OBP(obd, import_event)(obd, imp, event);
+	}
+	EXIT;
+}
+
+static inline int obd_llog_connect(struct obd_export *exp,
+				   struct llogd_conn_body *body)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(exp->exp_obd, llog_connect, 0);
+	EXP_COUNTER_INCREMENT(exp, llog_connect);
+
+	rc = OBP(exp->exp_obd, llog_connect)(exp, body);
+	RETURN(rc);
+}
+
+
+static inline int obd_notify(struct obd_device *obd,
+			     struct obd_device *watched,
+			     enum obd_notify_event ev,
+			     void *data)
+{
+	int rc;
+	ENTRY;
+	OBD_CHECK_DEV(obd);
+
+	/* the check for async_recov is a complete hack - I'm hereby
+	   overloading the meaning to also mean "this was called from
+	   mds_postsetup".  I know that my mds is able to handle notifies
+	   by this point, and it needs to get them to execute mds_postrecov. */
+	if (!obd->obd_set_up && !obd->obd_async_recov) {
+		CDEBUG(D_HA, "obd %s not set up\n", obd->obd_name);
+		RETURN(-EINVAL);
+	}
+
+	if (!OBP(obd, notify)) {
+		CDEBUG(D_HA, "obd %s has no notify handler\n", obd->obd_name);
+		RETURN(-ENOSYS);
+	}
+
+	OBD_COUNTER_INCREMENT(obd, notify);
+	rc = OBP(obd, notify)(obd, watched, ev, data);
+	RETURN(rc);
+}
+
+static inline int obd_notify_observer(struct obd_device *observer,
+				      struct obd_device *observed,
+				      enum obd_notify_event ev,
+				      void *data)
+{
+	int rc1;
+	int rc2;
+
+	struct obd_notify_upcall *onu;
+
+	if (observer->obd_observer)
+		rc1 = obd_notify(observer->obd_observer, observed, ev, data);
+	else
+		rc1 = 0;
+	/*
+	 * Also, call non-obd listener, if any
+	 */
+	onu = &observer->obd_upcall;
+	if (onu->onu_upcall != NULL)
+		rc2 = onu->onu_upcall(observer, observed, ev,
+				      onu->onu_owner, NULL);
+	else
+		rc2 = 0;
+
+	return rc1 ? rc1 : rc2;
+}
+
+static inline int obd_quotacheck(struct obd_export *exp,
+				 struct obd_quotactl *oqctl)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, quotacheck);
+	EXP_COUNTER_INCREMENT(exp, quotacheck);
+
+	rc = OBP(exp->exp_obd, quotacheck)(exp->exp_obd, exp, oqctl);
+	RETURN(rc);
+}
+
+static inline int obd_quotactl(struct obd_export *exp,
+			       struct obd_quotactl *oqctl)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_DT_OP(exp, quotactl);
+	EXP_COUNTER_INCREMENT(exp, quotactl);
+
+	rc = OBP(exp->exp_obd, quotactl)(exp->exp_obd, exp, oqctl);
+	RETURN(rc);
+}
+
+static inline int obd_health_check(const struct lu_env *env,
+				   struct obd_device *obd)
+{
+	/* returns: 0 on healthy
+	 *	 >0 on unhealthy + reason code/flag
+	 *	    however the only suppored reason == 1 right now
+	 *	    We'll need to define some better reasons
+	 *	    or flags in the future.
+	 *	 <0 on error
+	 */
+	int rc;
+	ENTRY;
+
+	/* don't use EXP_CHECK_DT_OP, because NULL method is normal here */
+	if (obd == NULL || !OBT(obd)) {
+		CERROR("cleaned up obd\n");
+		RETURN(-EOPNOTSUPP);
+	}
+	if (!obd->obd_set_up || obd->obd_stopping)
+		RETURN(0);
+	if (!OBP(obd, health_check))
+		RETURN(0);
+
+	rc = OBP(obd, health_check)(env, obd);
+	RETURN(rc);
+}
+
+static inline int obd_register_observer(struct obd_device *obd,
+					struct obd_device *observer)
+{
+	ENTRY;
+	OBD_CHECK_DEV(obd);
+	down_write(&obd->obd_observer_link_sem);
+	if (obd->obd_observer && observer) {
+		up_write(&obd->obd_observer_link_sem);
+		RETURN(-EALREADY);
+	}
+	obd->obd_observer = observer;
+	up_write(&obd->obd_observer_link_sem);
+	RETURN(0);
+}
+
+static inline int obd_pin_observer(struct obd_device *obd,
+				   struct obd_device **observer)
+{
+	ENTRY;
+	down_read(&obd->obd_observer_link_sem);
+	if (!obd->obd_observer) {
+		*observer = NULL;
+		up_read(&obd->obd_observer_link_sem);
+		RETURN(-ENOENT);
+	}
+	*observer = obd->obd_observer;
+	RETURN(0);
+}
+
+static inline int obd_unpin_observer(struct obd_device *obd)
+{
+	ENTRY;
+	up_read(&obd->obd_observer_link_sem);
+	RETURN(0);
+}
+
+#if 0
+static inline int obd_register_page_removal_cb(struct obd_export *exp,
+					       obd_page_removal_cb_t cb,
+					       obd_pin_extent_cb pin_cb)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(exp->exp_obd, register_page_removal_cb, 0);
+	OBD_COUNTER_INCREMENT(exp->exp_obd, register_page_removal_cb);
+
+	rc = OBP(exp->exp_obd, register_page_removal_cb)(exp, cb, pin_cb);
+	RETURN(rc);
+}
+
+static inline int obd_unregister_page_removal_cb(struct obd_export *exp,
+						 obd_page_removal_cb_t cb)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(exp->exp_obd, unregister_page_removal_cb, 0);
+	OBD_COUNTER_INCREMENT(exp->exp_obd, unregister_page_removal_cb);
+
+	rc = OBP(exp->exp_obd, unregister_page_removal_cb)(exp, cb);
+	RETURN(rc);
+}
+
+static inline int obd_register_lock_cancel_cb(struct obd_export *exp,
+					      obd_lock_cancel_cb cb)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(exp->exp_obd, register_lock_cancel_cb, 0);
+	OBD_COUNTER_INCREMENT(exp->exp_obd, register_lock_cancel_cb);
+
+	rc = OBP(exp->exp_obd, register_lock_cancel_cb)(exp, cb);
+	RETURN(rc);
+}
+
+static inline int obd_unregister_lock_cancel_cb(struct obd_export *exp,
+						 obd_lock_cancel_cb cb)
+{
+	int rc;
+	ENTRY;
+
+	OBD_CHECK_DT_OP(exp->exp_obd, unregister_lock_cancel_cb, 0);
+	OBD_COUNTER_INCREMENT(exp->exp_obd, unregister_lock_cancel_cb);
+
+	rc = OBP(exp->exp_obd, unregister_lock_cancel_cb)(exp, cb);
+	RETURN(rc);
+}
+#endif
+
+/* metadata helpers */
+static inline int md_getstatus(struct obd_export *exp,
+			       struct lu_fid *fid, struct obd_capa **pc)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_MD_OP(exp, getstatus);
+	EXP_MD_COUNTER_INCREMENT(exp, getstatus);
+	rc = MDP(exp->exp_obd, getstatus)(exp, fid, pc);
+	RETURN(rc);
+}
+
+static inline int md_getattr(struct obd_export *exp, struct md_op_data *op_data,
+			     struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, getattr);
+	EXP_MD_COUNTER_INCREMENT(exp, getattr);
+	rc = MDP(exp->exp_obd, getattr)(exp, op_data, request);
+	RETURN(rc);
+}
+
+static inline int md_null_inode(struct obd_export *exp,
+				   const struct lu_fid *fid)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, null_inode);
+	EXP_MD_COUNTER_INCREMENT(exp, null_inode);
+	rc = MDP(exp->exp_obd, null_inode)(exp, fid);
+	RETURN(rc);
+}
+
+static inline int md_find_cbdata(struct obd_export *exp,
+				 const struct lu_fid *fid,
+				 ldlm_iterator_t it, void *data)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, find_cbdata);
+	EXP_MD_COUNTER_INCREMENT(exp, find_cbdata);
+	rc = MDP(exp->exp_obd, find_cbdata)(exp, fid, it, data);
+	RETURN(rc);
+}
+
+static inline int md_close(struct obd_export *exp, struct md_op_data *op_data,
+			   struct md_open_data *mod,
+			   struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, close);
+	EXP_MD_COUNTER_INCREMENT(exp, close);
+	rc = MDP(exp->exp_obd, close)(exp, op_data, mod, request);
+	RETURN(rc);
+}
+
+static inline int md_create(struct obd_export *exp, struct md_op_data *op_data,
+			    const void *data, int datalen, int mode, __u32 uid,
+			    __u32 gid, cfs_cap_t cap_effective, __u64 rdev,
+			    struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, create);
+	EXP_MD_COUNTER_INCREMENT(exp, create);
+	rc = MDP(exp->exp_obd, create)(exp, op_data, data, datalen, mode,
+				       uid, gid, cap_effective, rdev, request);
+	RETURN(rc);
+}
+
+static inline int md_done_writing(struct obd_export *exp,
+				  struct md_op_data *op_data,
+				  struct md_open_data *mod)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, done_writing);
+	EXP_MD_COUNTER_INCREMENT(exp, done_writing);
+	rc = MDP(exp->exp_obd, done_writing)(exp, op_data, mod);
+	RETURN(rc);
+}
+
+static inline int md_enqueue(struct obd_export *exp,
+			     struct ldlm_enqueue_info *einfo,
+			     struct lookup_intent *it,
+			     struct md_op_data *op_data,
+			     struct lustre_handle *lockh,
+			     void *lmm, int lmmsize,
+			     struct ptlrpc_request **req,
+			     int extra_lock_flags)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, enqueue);
+	EXP_MD_COUNTER_INCREMENT(exp, enqueue);
+	rc = MDP(exp->exp_obd, enqueue)(exp, einfo, it, op_data, lockh,
+					lmm, lmmsize, req, extra_lock_flags);
+	RETURN(rc);
+}
+
+static inline int md_getattr_name(struct obd_export *exp,
+				  struct md_op_data *op_data,
+				  struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, getattr_name);
+	EXP_MD_COUNTER_INCREMENT(exp, getattr_name);
+	rc = MDP(exp->exp_obd, getattr_name)(exp, op_data, request);
+	RETURN(rc);
+}
+
+static inline int md_intent_lock(struct obd_export *exp,
+				 struct md_op_data *op_data, void *lmm,
+				 int lmmsize, struct lookup_intent *it,
+				 int lookup_flags, struct ptlrpc_request **reqp,
+				 ldlm_blocking_callback cb_blocking,
+				 __u64 extra_lock_flags)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, intent_lock);
+	EXP_MD_COUNTER_INCREMENT(exp, intent_lock);
+	rc = MDP(exp->exp_obd, intent_lock)(exp, op_data, lmm, lmmsize,
+					    it, lookup_flags, reqp, cb_blocking,
+					    extra_lock_flags);
+	RETURN(rc);
+}
+
+static inline int md_link(struct obd_export *exp, struct md_op_data *op_data,
+			  struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, link);
+	EXP_MD_COUNTER_INCREMENT(exp, link);
+	rc = MDP(exp->exp_obd, link)(exp, op_data, request);
+	RETURN(rc);
+}
+
+static inline int md_rename(struct obd_export *exp, struct md_op_data *op_data,
+			    const char *old, int oldlen, const char *new,
+			    int newlen, struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, rename);
+	EXP_MD_COUNTER_INCREMENT(exp, rename);
+	rc = MDP(exp->exp_obd, rename)(exp, op_data, old, oldlen, new,
+				       newlen, request);
+	RETURN(rc);
+}
+
+static inline int md_is_subdir(struct obd_export *exp,
+			       const struct lu_fid *pfid,
+			       const struct lu_fid *cfid,
+			       struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, is_subdir);
+	EXP_MD_COUNTER_INCREMENT(exp, is_subdir);
+	rc = MDP(exp->exp_obd, is_subdir)(exp, pfid, cfid, request);
+	RETURN(rc);
+}
+
+static inline int md_setattr(struct obd_export *exp, struct md_op_data *op_data,
+			     void *ea, int ealen, void *ea2, int ea2len,
+			     struct ptlrpc_request **request,
+			     struct md_open_data **mod)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, setattr);
+	EXP_MD_COUNTER_INCREMENT(exp, setattr);
+	rc = MDP(exp->exp_obd, setattr)(exp, op_data, ea, ealen,
+					ea2, ea2len, request, mod);
+	RETURN(rc);
+}
+
+static inline int md_sync(struct obd_export *exp, const struct lu_fid *fid,
+			  struct obd_capa *oc, struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, sync);
+	EXP_MD_COUNTER_INCREMENT(exp, sync);
+	rc = MDP(exp->exp_obd, sync)(exp, fid, oc, request);
+	RETURN(rc);
+}
+
+static inline int md_readpage(struct obd_export *exp, struct md_op_data *opdata,
+			      struct page **pages,
+			      struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, readpage);
+	EXP_MD_COUNTER_INCREMENT(exp, readpage);
+	rc = MDP(exp->exp_obd, readpage)(exp, opdata, pages, request);
+	RETURN(rc);
+}
+
+static inline int md_unlink(struct obd_export *exp, struct md_op_data *op_data,
+			    struct ptlrpc_request **request)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, unlink);
+	EXP_MD_COUNTER_INCREMENT(exp, unlink);
+	rc = MDP(exp->exp_obd, unlink)(exp, op_data, request);
+	RETURN(rc);
+}
+
+static inline int md_get_lustre_md(struct obd_export *exp,
+				   struct ptlrpc_request *req,
+				   struct obd_export *dt_exp,
+				   struct obd_export *md_exp,
+				   struct lustre_md *md)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, get_lustre_md);
+	EXP_MD_COUNTER_INCREMENT(exp, get_lustre_md);
+	RETURN(MDP(exp->exp_obd, get_lustre_md)(exp, req, dt_exp, md_exp, md));
+}
+
+static inline int md_free_lustre_md(struct obd_export *exp,
+				    struct lustre_md *md)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, free_lustre_md);
+	EXP_MD_COUNTER_INCREMENT(exp, free_lustre_md);
+	RETURN(MDP(exp->exp_obd, free_lustre_md)(exp, md));
+}
+
+static inline int md_setxattr(struct obd_export *exp,
+			      const struct lu_fid *fid, struct obd_capa *oc,
+			      obd_valid valid, const char *name,
+			      const char *input, int input_size,
+			      int output_size, int flags, __u32 suppgid,
+			      struct ptlrpc_request **request)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, setxattr);
+	EXP_MD_COUNTER_INCREMENT(exp, setxattr);
+	RETURN(MDP(exp->exp_obd, setxattr)(exp, fid, oc, valid, name, input,
+					   input_size, output_size, flags,
+					   suppgid, request));
+}
+
+static inline int md_getxattr(struct obd_export *exp,
+			      const struct lu_fid *fid, struct obd_capa *oc,
+			      obd_valid valid, const char *name,
+			      const char *input, int input_size,
+			      int output_size, int flags,
+			      struct ptlrpc_request **request)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, getxattr);
+	EXP_MD_COUNTER_INCREMENT(exp, getxattr);
+	RETURN(MDP(exp->exp_obd, getxattr)(exp, fid, oc, valid, name, input,
+					   input_size, output_size, flags,
+					   request));
+}
+
+static inline int md_set_open_replay_data(struct obd_export *exp,
+					  struct obd_client_handle *och,
+					  struct ptlrpc_request *open_req)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, set_open_replay_data);
+	EXP_MD_COUNTER_INCREMENT(exp, set_open_replay_data);
+	RETURN(MDP(exp->exp_obd, set_open_replay_data)(exp, och, open_req));
+}
+
+static inline int md_clear_open_replay_data(struct obd_export *exp,
+					    struct obd_client_handle *och)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, clear_open_replay_data);
+	EXP_MD_COUNTER_INCREMENT(exp, clear_open_replay_data);
+	RETURN(MDP(exp->exp_obd, clear_open_replay_data)(exp, och));
+}
+
+static inline int md_set_lock_data(struct obd_export *exp,
+				   __u64 *lockh, void *data, __u64 *bits)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, set_lock_data);
+	EXP_MD_COUNTER_INCREMENT(exp, set_lock_data);
+	RETURN(MDP(exp->exp_obd, set_lock_data)(exp, lockh, data, bits));
+}
+
+static inline int md_cancel_unused(struct obd_export *exp,
+				   const struct lu_fid *fid,
+				   ldlm_policy_data_t *policy,
+				   ldlm_mode_t mode,
+				   ldlm_cancel_flags_t flags,
+				   void *opaque)
+{
+	int rc;
+	ENTRY;
+
+	EXP_CHECK_MD_OP(exp, cancel_unused);
+	EXP_MD_COUNTER_INCREMENT(exp, cancel_unused);
+
+	rc = MDP(exp->exp_obd, cancel_unused)(exp, fid, policy, mode,
+					      flags, opaque);
+	RETURN(rc);
+}
+
+static inline ldlm_mode_t md_lock_match(struct obd_export *exp, __u64 flags,
+					const struct lu_fid *fid,
+					ldlm_type_t type,
+					ldlm_policy_data_t *policy,
+					ldlm_mode_t mode,
+					struct lustre_handle *lockh)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, lock_match);
+	EXP_MD_COUNTER_INCREMENT(exp, lock_match);
+	RETURN(MDP(exp->exp_obd, lock_match)(exp, flags, fid, type,
+					     policy, mode, lockh));
+}
+
+static inline int md_init_ea_size(struct obd_export *exp, int easize,
+				  int def_asize, int cookiesize)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, init_ea_size);
+	EXP_MD_COUNTER_INCREMENT(exp, init_ea_size);
+	RETURN(MDP(exp->exp_obd, init_ea_size)(exp, easize, def_asize,
+					       cookiesize));
+}
+
+static inline int md_get_remote_perm(struct obd_export *exp,
+				     const struct lu_fid *fid,
+				     struct obd_capa *oc, __u32 suppgid,
+				     struct ptlrpc_request **request)
+{
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, get_remote_perm);
+	EXP_MD_COUNTER_INCREMENT(exp, get_remote_perm);
+	RETURN(MDP(exp->exp_obd, get_remote_perm)(exp, fid, oc, suppgid,
+						  request));
+}
+
+static inline int md_renew_capa(struct obd_export *exp, struct obd_capa *ocapa,
+				renew_capa_cb_t cb)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, renew_capa);
+	EXP_MD_COUNTER_INCREMENT(exp, renew_capa);
+	rc = MDP(exp->exp_obd, renew_capa)(exp, ocapa, cb);
+	RETURN(rc);
+}
+
+static inline int md_unpack_capa(struct obd_export *exp,
+				 struct ptlrpc_request *req,
+				 const struct req_msg_field *field,
+				 struct obd_capa **oc)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, unpack_capa);
+	EXP_MD_COUNTER_INCREMENT(exp, unpack_capa);
+	rc = MDP(exp->exp_obd, unpack_capa)(exp, req, field, oc);
+	RETURN(rc);
+}
+
+static inline int md_intent_getattr_async(struct obd_export *exp,
+					  struct md_enqueue_info *minfo,
+					  struct ldlm_enqueue_info *einfo)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, intent_getattr_async);
+	EXP_MD_COUNTER_INCREMENT(exp, intent_getattr_async);
+	rc = MDP(exp->exp_obd, intent_getattr_async)(exp, minfo, einfo);
+	RETURN(rc);
+}
+
+static inline int md_revalidate_lock(struct obd_export *exp,
+				     struct lookup_intent *it,
+				     struct lu_fid *fid, __u64 *bits)
+{
+	int rc;
+	ENTRY;
+	EXP_CHECK_MD_OP(exp, revalidate_lock);
+	EXP_MD_COUNTER_INCREMENT(exp, revalidate_lock);
+	rc = MDP(exp->exp_obd, revalidate_lock)(exp, it, fid, bits);
+	RETURN(rc);
+}
+
+
+/* OBD Metadata Support */
+
+extern int obd_init_caches(void);
+extern void obd_cleanup_caches(void);
+
+/* support routines */
+extern struct kmem_cache *obdo_cachep;
+
+#define OBDO_ALLOC(ptr)						       \
+do {									  \
+	OBD_SLAB_ALLOC_PTR_GFP((ptr), obdo_cachep, __GFP_IO);	     \
+} while(0)
+
+#define OBDO_FREE(ptr)							\
+do {									  \
+	OBD_SLAB_FREE_PTR((ptr), obdo_cachep);				\
+} while(0)
+
+
+static inline void obdo2fid(struct obdo *oa, struct lu_fid *fid)
+{
+	/* something here */
+}
+
+static inline void fid2obdo(struct lu_fid *fid, struct obdo *oa)
+{
+	/* something here */
+}
+
+typedef int (*register_lwp_cb)(void *data);
+
+struct lwp_register_item {
+	struct obd_export **lri_exp;
+	register_lwp_cb	    lri_cb_func;
+	void		   *lri_cb_data;
+	struct list_head	    lri_list;
+	char		    lri_name[MTI_NAME_MAXLEN];
+};
+
+/* I'm as embarrassed about this as you are.
+ *
+ * <shaver> // XXX do not look into _superhack with remaining eye
+ * <shaver> // XXX if this were any uglier, I'd get my own show on MTV */
+extern int (*ptlrpc_put_connection_superhack)(struct ptlrpc_connection *c);
+
+/* obd_mount.c */
+
+/* sysctl.c */
+extern void obd_sysctl_init (void);
+extern void obd_sysctl_clean (void);
+
+/* uuid.c  */
+typedef __u8 class_uuid_t[16];
+void class_uuid_unparse(class_uuid_t in, struct obd_uuid *out);
+
+/* lustre_peer.c    */
+int lustre_uuid_to_peer(const char *uuid, lnet_nid_t *peer_nid, int index);
+int class_add_uuid(const char *uuid, __u64 nid);
+int class_del_uuid (const char *uuid);
+int class_check_uuid(struct obd_uuid *uuid, __u64 nid);
+void class_init_uuidlist(void);
+void class_exit_uuidlist(void);
+
+/* mea.c */
+int mea_name2idx(struct lmv_stripe_md *mea, const char *name, int namelen);
+int raw_name2idx(int hashtype, int count, const char *name, int namelen);
+
+/* prng.c */
+#define ll_generate_random_uuid(uuid_out) cfs_get_random_bytes(uuid_out, sizeof(class_uuid_t))
+
+#endif /* __LINUX_OBD_CLASS_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1677 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef __OBD_H
+#define __OBD_H
+
+#include <linux/obd.h>
+
+#define IOC_OSC_TYPE	 'h'
+#define IOC_OSC_MIN_NR       20
+#define IOC_OSC_SET_ACTIVE   _IOWR(IOC_OSC_TYPE, 21, struct obd_device *)
+#define IOC_OSC_MAX_NR       50
+
+#define IOC_MDC_TYPE	 'i'
+#define IOC_MDC_MIN_NR       20
+#define IOC_MDC_MAX_NR       50
+
+#include <lustre/lustre_idl.h>
+#include <lu_ref.h>
+#include <lustre_lib.h>
+#include <lustre_export.h>
+#include <lustre_fld.h>
+#include <lustre_capa.h>
+
+#include <linux/libcfs/bitmap.h>
+
+
+#define MAX_OBD_DEVICES 8192
+
+struct osc_async_rc {
+	int     ar_rc;
+	int     ar_force_sync;
+	__u64   ar_min_xid;
+};
+
+struct lov_oinfo {		 /* per-stripe data structure */
+	struct ost_id   loi_oi;    /* object ID/Sequence on the target OST */
+	int loi_ost_idx;	   /* OST stripe index in lov_tgt_desc->tgts */
+	int loi_ost_gen;	   /* generation of this loi_ost_idx */
+
+	unsigned long loi_kms_valid:1;
+	__u64 loi_kms;	     /* known minimum size */
+	struct ost_lvb loi_lvb;
+	struct osc_async_rc     loi_ar;
+};
+
+static inline void loi_kms_set(struct lov_oinfo *oinfo, __u64 kms)
+{
+	oinfo->loi_kms = kms;
+	oinfo->loi_kms_valid = 1;
+}
+
+static inline void loi_init(struct lov_oinfo *loi)
+{
+}
+
+struct lov_stripe_md {
+	atomic_t     lsm_refc;
+	spinlock_t	lsm_lock;
+	pid_t	    lsm_lock_owner; /* debugging */
+
+	/* maximum possible file size, might change as OSTs status changes,
+	 * e.g. disconnected, deactivated */
+	__u64	    lsm_maxbytes;
+	struct {
+		/* Public members. */
+		struct ost_id lw_object_oi; /* lov object id/seq */
+
+		/* LOV-private members start here -- only for use in lov/. */
+		__u32 lw_magic;
+		__u32 lw_stripe_size;      /* size of the stripe */
+		__u32 lw_pattern;	  /* striping pattern (RAID0, RAID1) */
+		__u16 lw_stripe_count;  /* number of objects being striped over */
+		__u16 lw_layout_gen;       /* generation of the layout */
+		char  lw_pool_name[LOV_MAXPOOLNAME]; /* pool name */
+	} lsm_wire;
+
+	struct lov_oinfo *lsm_oinfo[0];
+};
+
+#define lsm_oi		 lsm_wire.lw_object_oi
+#define lsm_magic	lsm_wire.lw_magic
+#define lsm_layout_gen   lsm_wire.lw_layout_gen
+#define lsm_stripe_size  lsm_wire.lw_stripe_size
+#define lsm_pattern      lsm_wire.lw_pattern
+#define lsm_stripe_count lsm_wire.lw_stripe_count
+#define lsm_pool_name    lsm_wire.lw_pool_name
+
+struct obd_info;
+
+typedef int (*obd_enqueue_update_f)(void *cookie, int rc);
+
+/* obd info for a particular level (lov, osc). */
+struct obd_info {
+	/* Lock policy. It keeps an extent which is specific for a particular
+	 * OSC. (e.g. lov_prep_enqueue_set initialises extent of the policy,
+	 * and osc_enqueue passes it into ldlm_lock_match & ldlm_cli_enqueue. */
+	ldlm_policy_data_t      oi_policy;
+	/* Flags used for set request specific flags:
+	   - while lock handling, the flags obtained on the enqueue
+	   request are set here.
+	   - while stats, the flags used for control delay/resend.
+	   - while setattr, the flags used for distinguish punch operation
+	 */
+	__u64		   oi_flags;
+	/* Lock handle specific for every OSC lock. */
+	struct lustre_handle   *oi_lockh;
+	/* lsm data specific for every OSC. */
+	struct lov_stripe_md   *oi_md;
+	/* obdo data specific for every OSC, if needed at all. */
+	struct obdo	    *oi_oa;
+	/* statfs data specific for every OSC, if needed at all. */
+	struct obd_statfs      *oi_osfs;
+	/* An update callback which is called to update some data on upper
+	 * level. E.g. it is used for update lsm->lsm_oinfo at every recieved
+	 * request in osc level for enqueue requests. It is also possible to
+	 * update some caller data from LOV layer if needed. */
+	obd_enqueue_update_f    oi_cb_up;
+	/* oss capability, its type is obd_capa in client to avoid copy.
+	 * in contrary its type is lustre_capa in OSS. */
+	void		   *oi_capa;
+	/* transfer jobid from ost_sync() to filter_sync()... */
+	char		   *oi_jobid;
+};
+
+/* compare all relevant fields. */
+static inline int lov_stripe_md_cmp(struct lov_stripe_md *m1,
+				    struct lov_stripe_md *m2)
+{
+	/*
+	 * ->lsm_wire contains padding, but it should be zeroed out during
+	 * allocation.
+	 */
+	return memcmp(&m1->lsm_wire, &m2->lsm_wire, sizeof m1->lsm_wire);
+}
+
+static inline int lov_lum_lsm_cmp(struct lov_user_md *lum,
+				  struct lov_stripe_md  *lsm)
+{
+	if (lsm->lsm_magic != lum->lmm_magic)
+		return 1;
+	if ((lsm->lsm_stripe_count != 0) && (lum->lmm_stripe_count != 0) &&
+	    (lsm->lsm_stripe_count != lum->lmm_stripe_count))
+		return 2;
+	if ((lsm->lsm_stripe_size != 0) && (lum->lmm_stripe_size != 0) &&
+	    (lsm->lsm_stripe_size != lum->lmm_stripe_size))
+		return 3;
+	if ((lsm->lsm_pattern != 0) && (lum->lmm_pattern != 0) &&
+	    (lsm->lsm_pattern != lum->lmm_pattern))
+		return 4;
+	if ((lsm->lsm_magic == LOV_MAGIC_V3) &&
+	    (strncmp(lsm->lsm_pool_name,
+		     ((struct lov_user_md_v3 *)lum)->lmm_pool_name,
+		     LOV_MAXPOOLNAME) != 0))
+		return 5;
+	return 0;
+}
+
+static inline int lov_lum_swab_if_needed(struct lov_user_md_v3 *lumv3,
+					 int *lmm_magic,
+					 struct lov_user_md *lum)
+{
+	if (lum && copy_from_user(lumv3, lum,sizeof(struct lov_user_md_v1)))
+		return -EFAULT;
+
+	*lmm_magic = lumv3->lmm_magic;
+
+	if (*lmm_magic == __swab32(LOV_USER_MAGIC_V1)) {
+		lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lumv3);
+		*lmm_magic = LOV_USER_MAGIC_V1;
+	} else if (*lmm_magic == LOV_USER_MAGIC_V3) {
+		if (lum && copy_from_user(lumv3, lum, sizeof(*lumv3)))
+			return -EFAULT;
+	} else if (*lmm_magic == __swab32(LOV_USER_MAGIC_V3)) {
+		if (lum && copy_from_user(lumv3, lum, sizeof(*lumv3)))
+			return -EFAULT;
+		lustre_swab_lov_user_md_v3(lumv3);
+		*lmm_magic = LOV_USER_MAGIC_V3;
+	} else if (*lmm_magic != LOV_USER_MAGIC_V1) {
+		CDEBUG(D_IOCTL,
+		       "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n",
+		       *lmm_magic, LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3);
+		       return -EINVAL;
+	}
+	return 0;
+}
+
+void lov_stripe_lock(struct lov_stripe_md *md);
+void lov_stripe_unlock(struct lov_stripe_md *md);
+
+struct obd_type {
+	struct list_head typ_chain;
+	struct obd_ops *typ_dt_ops;
+	struct md_ops *typ_md_ops;
+	proc_dir_entry_t *typ_procroot;
+	char *typ_name;
+	int  typ_refcnt;
+	struct lu_device_type *typ_lu;
+	spinlock_t obd_type_lock;
+};
+
+struct brw_page {
+	obd_off  off;
+	struct page *pg;
+	int count;
+	obd_flag flag;
+};
+
+/* Individual type definitions */
+
+struct ost_server_data;
+
+struct osd_properties {
+	size_t osd_max_ea_size;
+};
+
+#define OBT_MAGIC       0xBDDECEAE
+/* hold common fields for "target" device */
+struct obd_device_target {
+	__u32		     obt_magic;
+	__u32		     obt_instance;
+	struct super_block       *obt_sb;
+	/** last_rcvd file */
+	struct file	      *obt_rcvd_filp;
+	__u64		     obt_mount_count;
+	struct rw_semaphore	  obt_rwsem;
+	struct vfsmount	  *obt_vfsmnt;
+	struct file	      *obt_health_check_filp;
+	struct osd_properties     obt_osd_properties;
+	struct obd_job_stats      obt_jobstats;
+};
+
+/* llog contexts */
+enum llog_ctxt_id {
+	LLOG_CONFIG_ORIG_CTXT  =  0,
+	LLOG_CONFIG_REPL_CTXT,
+	LLOG_MDS_OST_ORIG_CTXT,
+	LLOG_MDS_OST_REPL_CTXT,
+	LLOG_SIZE_ORIG_CTXT,
+	LLOG_SIZE_REPL_CTXT,
+	LLOG_RD1_ORIG_CTXT,
+	LLOG_RD1_REPL_CTXT,
+	LLOG_TEST_ORIG_CTXT,
+	LLOG_TEST_REPL_CTXT,
+	LLOG_LOVEA_ORIG_CTXT,
+	LLOG_LOVEA_REPL_CTXT,
+	LLOG_CHANGELOG_ORIG_CTXT,      /**< changelog generation on mdd */
+	LLOG_CHANGELOG_REPL_CTXT,      /**< changelog access on clients */
+	LLOG_CHANGELOG_USER_ORIG_CTXT, /**< for multiple changelog consumers */
+	LLOG_MAX_CTXTS
+};
+
+#define FILTER_SUBDIR_COUNT      32	    /* set to zero for no subdirs */
+
+struct filter_subdirs {
+	struct dentry *dentry[FILTER_SUBDIR_COUNT];
+};
+
+
+struct filter_ext {
+	__u64		fe_start;
+	__u64		fe_end;
+};
+
+struct filter_obd {
+	/* NB this field MUST be first */
+	struct obd_device_target fo_obt;
+	const char		*fo_fstype;
+
+	int			fo_group_count;
+	struct dentry		*fo_dentry_O;
+	struct dentry		**fo_dentry_O_groups;
+	struct filter_subdirs	*fo_dentry_O_sub;
+	struct mutex		fo_init_lock;	/* group initialization lock*/
+	int			fo_committed_group;
+
+	spinlock_t		fo_objidlock;	/* protect fo_lastobjid */
+
+	unsigned long		fo_destroys_in_progress;
+	struct mutex		fo_create_locks[FILTER_SUBDIR_COUNT];
+
+	struct list_head fo_export_list;
+	int		  fo_subdir_count;
+
+	obd_size	     fo_tot_dirty;      /* protected by obd_osfs_lock */
+	obd_size	     fo_tot_granted;    /* all values in bytes */
+	obd_size	     fo_tot_pending;
+	int		  fo_tot_granted_clients;
+
+	obd_size	     fo_readcache_max_filesize;
+	spinlock_t		fo_flags_lock;
+	unsigned int	 fo_read_cache:1,   /**< enable read-only cache */
+			     fo_writethrough_cache:1,/**< read cache writes */
+			     fo_mds_ost_sync:1, /**< MDS-OST orphan recovery*/
+			     fo_raid_degraded:1;/**< RAID device degraded */
+
+	struct obd_import   *fo_mdc_imp;
+	struct obd_uuid      fo_mdc_uuid;
+	struct lustre_handle fo_mdc_conn;
+	struct file	**fo_last_objid_files;
+	__u64	       *fo_last_objids; /* last created objid for groups,
+					      * protected by fo_objidlock */
+
+	struct mutex		fo_alloc_lock;
+
+	atomic_t	 fo_r_in_flight;
+	atomic_t	 fo_w_in_flight;
+
+	/*
+	 * per-filter pool of kiobuf's allocated by filter_common_setup() and
+	 * torn down by filter_cleanup().
+	 *
+	 * This pool contains kiobuf used by
+	 * filter_{prep,commit}rw_{read,write}() and is shared by all OST
+	 * threads.
+	 *
+	 * Locking: protected by internal lock of cfs_hash, pool can be
+	 * found from this hash table by t_id of ptlrpc_thread.
+	 */
+	struct cfs_hash		*fo_iobuf_hash;
+
+	struct brw_stats	 fo_filter_stats;
+
+	int		      fo_fmd_max_num; /* per exp filter_mod_data */
+	int		      fo_fmd_max_age; /* jiffies to fmd expiry */
+	unsigned long	    fo_syncjournal:1, /* sync journal on writes */
+				 fo_sync_lock_cancel:2;/* sync on lock cancel */
+
+
+	/* sptlrpc stuff */
+	rwlock_t		fo_sptlrpc_lock;
+	struct sptlrpc_rule_set  fo_sptlrpc_rset;
+
+	/* capability related */
+	unsigned int	     fo_fl_oss_capa;
+	struct list_head	       fo_capa_keys;
+	struct hlist_head	*fo_capa_hash;
+	int		      fo_sec_level;
+};
+
+struct timeout_item {
+	enum timeout_event ti_event;
+	cfs_time_t	 ti_timeout;
+	timeout_cb_t       ti_cb;
+	void	      *ti_cb_data;
+	struct list_head	 ti_obd_list;
+	struct list_head	 ti_chain;
+};
+
+#define OSC_MAX_RIF_DEFAULT       8
+#define MDS_OSC_MAX_RIF_DEFAULT   50
+#define OSC_MAX_RIF_MAX	 256
+#define OSC_MAX_DIRTY_DEFAULT  (OSC_MAX_RIF_DEFAULT * 4)
+#define OSC_MAX_DIRTY_MB_MAX   2048     /* arbitrary, but < MAX_LONG bytes */
+#define OSC_DEFAULT_RESENDS      10
+
+/* possible values for fo_sync_lock_cancel */
+enum {
+	NEVER_SYNC_ON_CANCEL = 0,
+	BLOCKING_SYNC_ON_CANCEL = 1,
+	ALWAYS_SYNC_ON_CANCEL = 2,
+	NUM_SYNC_ON_CANCEL_STATES
+};
+
+#define MDC_MAX_RIF_DEFAULT       8
+#define MDC_MAX_RIF_MAX	 512
+
+struct mdc_rpc_lock;
+struct obd_import;
+struct client_obd {
+	struct rw_semaphore  cl_sem;
+	struct obd_uuid	  cl_target_uuid;
+	struct obd_import       *cl_import; /* ptlrpc connection state */
+	int		      cl_conn_count;
+	/* max_mds_easize is purely a performance thing so we don't have to
+	 * call obd_size_diskmd() all the time. */
+	int		      cl_default_mds_easize;
+	int		      cl_max_mds_easize;
+	int		      cl_max_mds_cookiesize;
+
+	enum lustre_sec_part     cl_sp_me;
+	enum lustre_sec_part     cl_sp_to;
+	struct sptlrpc_flavor    cl_flvr_mgc;   /* fixed flavor of mgc->mgs */
+
+	/* the grant values are protected by loi_list_lock below */
+	long		     cl_dirty;	 /* all _dirty_ in bytes */
+	long		     cl_dirty_max;     /* allowed w/o rpc */
+	long		     cl_dirty_transit; /* dirty synchronous */
+	long		     cl_avail_grant;   /* bytes of credit for ost */
+	long		     cl_lost_grant;    /* lost credits (trunc) */
+
+	/* since we allocate grant by blocks, we don't know how many grant will
+	 * be used to add a page into cache. As a solution, we reserve maximum
+	 * grant before trying to dirty a page and unreserve the rest.
+	 * See osc_{reserve|unreserve}_grant for details. */
+	long		 cl_reserved_grant;
+	struct list_head	   cl_cache_waiters; /* waiting for cache/grant */
+	cfs_time_t	   cl_next_shrink_grant;   /* jiffies */
+	struct list_head	   cl_grant_shrink_list;  /* Timeout event list */
+	int		  cl_grant_shrink_interval; /* seconds */
+
+	/* A chunk is an optimal size used by osc_extent to determine
+	 * the extent size. A chunk is max(PAGE_CACHE_SIZE, OST block size) */
+	int		  cl_chunkbits;
+	int		  cl_chunk;
+	int		  cl_extent_tax; /* extent overhead, by bytes */
+
+	/* keep track of objects that have lois that contain pages which
+	 * have been queued for async brw.  this lock also protects the
+	 * lists of osc_client_pages that hang off of the loi */
+	/*
+	 * ->cl_loi_list_lock protects consistency of
+	 * ->cl_loi_{ready,read,write}_list. ->ap_make_ready() and
+	 * ->ap_completion() call-backs are executed under this lock. As we
+	 * cannot guarantee that these call-backs never block on all platforms
+	 * (as a matter of fact they do block on Mac OS X), type of
+	 * ->cl_loi_list_lock is platform dependent: it's a spin-lock on Linux
+	 * and blocking mutex on Mac OS X. (Alternative is to make this lock
+	 * blocking everywhere, but we don't want to slow down fast-path of
+	 * our main platform.)
+	 *
+	 * Exact type of ->cl_loi_list_lock is defined in arch/obd.h together
+	 * with client_obd_list_{un,}lock() and
+	 * client_obd_list_lock_{init,done}() functions.
+	 *
+	 * NB by Jinshan: though field names are still _loi_, but actually
+	 * osc_object{}s are in the list.
+	 */
+	client_obd_lock_t	cl_loi_list_lock;
+	struct list_head	       cl_loi_ready_list;
+	struct list_head	       cl_loi_hp_ready_list;
+	struct list_head	       cl_loi_write_list;
+	struct list_head	       cl_loi_read_list;
+	int		      cl_r_in_flight;
+	int		      cl_w_in_flight;
+	/* just a sum of the loi/lop pending numbers to be exported by /proc */
+	atomic_t	     cl_pending_w_pages;
+	atomic_t	     cl_pending_r_pages;
+	__u32			 cl_max_pages_per_rpc;
+	int		      cl_max_rpcs_in_flight;
+	struct obd_histogram     cl_read_rpc_hist;
+	struct obd_histogram     cl_write_rpc_hist;
+	struct obd_histogram     cl_read_page_hist;
+	struct obd_histogram     cl_write_page_hist;
+	struct obd_histogram     cl_read_offset_hist;
+	struct obd_histogram     cl_write_offset_hist;
+
+	/* lru for osc caching pages */
+	struct cl_client_cache	*cl_cache;
+	struct list_head		 cl_lru_osc; /* member of cl_cache->ccc_lru */
+	atomic_t		*cl_lru_left;
+	atomic_t		 cl_lru_busy;
+	atomic_t		 cl_lru_shrinkers;
+	atomic_t		 cl_lru_in_list;
+	struct list_head		 cl_lru_list; /* lru page list */
+	client_obd_lock_t	 cl_lru_list_lock; /* page list protector */
+
+	/* number of in flight destroy rpcs is limited to max_rpcs_in_flight */
+	atomic_t	     cl_destroy_in_flight;
+	wait_queue_head_t	      cl_destroy_waitq;
+
+	struct mdc_rpc_lock     *cl_rpc_lock;
+	struct mdc_rpc_lock     *cl_close_lock;
+
+	/* mgc datastruct */
+	struct semaphore	 cl_mgc_sem;
+	struct vfsmount	 *cl_mgc_vfsmnt;
+	struct dentry	   *cl_mgc_configs_dir;
+	atomic_t	     cl_mgc_refcount;
+	struct obd_export       *cl_mgc_mgsexp;
+
+	/* checksumming for data sent over the network */
+	unsigned int	     cl_checksum:1; /* 0 = disabled, 1 = enabled */
+	/* supported checksum types that are worked out at connect time */
+	__u32		    cl_supp_cksum_types;
+	/* checksum algorithm to be used */
+	cksum_type_t	     cl_cksum_type;
+
+	/* also protected by the poorly named _loi_list_lock lock above */
+	struct osc_async_rc      cl_ar;
+
+	/* used by quotacheck when the servers are older than 2.4 */
+	int		      cl_qchk_stat; /* quotacheck stat of the peer */
+#define CL_NOT_QUOTACHECKED 1   /* client->cl_qchk_stat init value */
+#if LUSTRE_VERSION_CODE >= OBD_OCD_VERSION(2, 7, 50, 0)
+#warning "please consider removing quotacheck compatibility code"
+#endif
+
+	/* sequence manager */
+	struct lu_client_seq    *cl_seq;
+
+	atomic_t	     cl_resends; /* resend count */
+
+	/* ptlrpc work for writeback in ptlrpcd context */
+	void		    *cl_writeback_work;
+	/* hash tables for osc_quota_info */
+	cfs_hash_t	      *cl_quota_hash[MAXQUOTAS];
+};
+#define obd2cli_tgt(obd) ((char *)(obd)->u.cli.cl_target_uuid.uuid)
+
+struct obd_id_info {
+	__u32   idx;
+	obd_id  *data;
+};
+
+/* */
+
+struct echo_obd {
+	struct obd_device_target eo_obt;
+	struct obdo		eo_oa;
+	spinlock_t		 eo_lock;
+	__u64			 eo_lastino;
+	struct lustre_handle	eo_nl_lock;
+	atomic_t		eo_prep;
+};
+
+struct ost_obd {
+	struct ptlrpc_service	*ost_service;
+	struct ptlrpc_service	*ost_create_service;
+	struct ptlrpc_service	*ost_io_service;
+	struct ptlrpc_service	*ost_seq_service;
+	struct mutex		ost_health_mutex;
+};
+
+struct echo_client_obd {
+	struct obd_export	*ec_exp;   /* the local connection to osc/lov */
+	spinlock_t		ec_lock;
+	struct list_head	   ec_objects;
+	struct list_head	   ec_locks;
+	int		  ec_nstripes;
+	__u64		ec_unique;
+};
+
+struct lov_qos_oss {
+	struct obd_uuid     lqo_uuid;       /* ptlrpc's c_remote_uuid */
+	struct list_head	  lqo_oss_list;   /* link to lov_qos */
+	__u64	       lqo_bavail;     /* total bytes avail on OSS */
+	__u64	       lqo_penalty;    /* current penalty */
+	__u64	       lqo_penalty_per_obj;/* penalty decrease every obj*/
+	time_t	      lqo_used;       /* last used time, seconds */
+	__u32	       lqo_ost_count;  /* number of osts on this oss */
+};
+
+struct ltd_qos {
+	struct lov_qos_oss *ltq_oss;	 /* oss info */
+	__u64	       ltq_penalty;     /* current penalty */
+	__u64	       ltq_penalty_per_obj; /* penalty decrease every obj*/
+	__u64	       ltq_weight;      /* net weighting */
+	time_t	      ltq_used;	/* last used time, seconds */
+	unsigned int	ltq_usable:1;    /* usable for striping */
+};
+
+/* Generic subset of OSTs */
+struct ost_pool {
+	__u32	      *op_array;      /* array of index of
+						   lov_obd->lov_tgts */
+	unsigned int	op_count;      /* number of OSTs in the array */
+	unsigned int	op_size;       /* allocated size of lp_array */
+	struct rw_semaphore op_rw_sem;     /* to protect ost_pool use */
+};
+
+/* Round-robin allocator data */
+struct lov_qos_rr {
+	__u32	       lqr_start_idx;   /* start index of new inode */
+	__u32	       lqr_offset_idx;  /* aliasing for start_idx  */
+	int		 lqr_start_count; /* reseed counter */
+	struct ost_pool     lqr_pool;	/* round-robin optimized list */
+	unsigned long       lqr_dirty:1;     /* recalc round-robin list */
+};
+
+/* allow statfs data caching for 1 second */
+#define OBD_STATFS_CACHE_SECONDS 1
+
+struct lov_statfs_data {
+	struct obd_info   lsd_oi;
+	struct obd_statfs lsd_statfs;
+};
+/* Stripe placement optimization */
+struct lov_qos {
+	struct list_head	  lq_oss_list; /* list of OSSs that targets use */
+	struct rw_semaphore lq_rw_sem;
+	__u32	       lq_active_oss_count;
+	unsigned int	lq_prio_free;   /* priority for free space */
+	unsigned int	lq_threshold_rr;/* priority for rr */
+	struct lov_qos_rr   lq_rr;	  /* round robin qos data */
+	unsigned long       lq_dirty:1,     /* recalc qos data */
+			    lq_same_space:1,/* the ost's all have approx.
+					       the same space avail */
+			    lq_reset:1,     /* zero current penalties */
+			    lq_statfs_in_progress:1; /* statfs op in
+							progress */
+	/* qos statfs data */
+	struct lov_statfs_data *lq_statfs_data;
+	wait_queue_head_t	 lq_statfs_waitq; /* waitqueue to notify statfs
+					      * requests completion */
+};
+
+struct lov_tgt_desc {
+	struct list_head	  ltd_kill;
+	struct obd_uuid     ltd_uuid;
+	struct obd_device  *ltd_obd;
+	struct obd_export  *ltd_exp;
+	struct ltd_qos      ltd_qos;     /* qos info per target */
+	__u32	       ltd_gen;
+	__u32	       ltd_index;   /* index in lov_obd->tgts */
+	unsigned long       ltd_active:1,/* is this target up for requests */
+			    ltd_activate:1,/* should  target be activated */
+			    ltd_reap:1;  /* should this target be deleted */
+};
+
+/* Pool metadata */
+#define pool_tgt_size(_p)   _p->pool_obds.op_size
+#define pool_tgt_count(_p)  _p->pool_obds.op_count
+#define pool_tgt_array(_p)  _p->pool_obds.op_array
+#define pool_tgt_rw_sem(_p) _p->pool_obds.op_rw_sem
+
+struct pool_desc {
+	char		  pool_name[LOV_MAXPOOLNAME + 1]; /* name of pool */
+	struct ost_pool       pool_obds;	      /* pool members */
+	atomic_t	  pool_refcount;	  /* pool ref. counter */
+	struct lov_qos_rr     pool_rr;		/* round robin qos */
+	struct hlist_node      pool_hash;	      /* access by poolname */
+	struct list_head	    pool_list;	      /* serial access */
+	proc_dir_entry_t *pool_proc_entry;	/* file in /proc */
+	struct obd_device    *pool_lobd;	      /* obd of the lov/lod to which
+						       * this pool belongs */
+};
+
+struct lov_obd {
+	struct lov_desc	 desc;
+	struct lov_tgt_desc   **lov_tgts;	      /* sparse array */
+	struct ost_pool	 lov_packed;	    /* all OSTs in a packed
+							  array */
+	struct mutex		lov_lock;
+	struct obd_connect_data lov_ocd;
+	atomic_t	    lov_refcount;
+	__u32		   lov_tgt_count;	 /* how many OBD's */
+	__u32		   lov_active_tgt_count;  /* how many active */
+	__u32		   lov_death_row;/* tgts scheduled to be deleted */
+	__u32		   lov_tgt_size;   /* size of tgts array */
+	int		     lov_connects;
+	int		     lov_pool_count;
+	cfs_hash_t	     *lov_pools_hash_body; /* used for key access */
+	struct list_head	      lov_pool_list; /* used for sequential access */
+	proc_dir_entry_t   *lov_pool_proc_entry;
+	enum lustre_sec_part    lov_sp_me;
+
+	/* Cached LRU pages from upper layer */
+	void		       *lov_cache;
+
+	struct rw_semaphore     lov_notify_lock;
+};
+
+struct lmv_tgt_desc {
+	struct obd_uuid		ltd_uuid;
+	struct obd_export	*ltd_exp;
+	int			ltd_idx;
+	struct mutex		ltd_fid_mutex;
+	unsigned long		ltd_active:1; /* target up for requests */
+};
+
+enum placement_policy {
+	PLACEMENT_CHAR_POLICY   = 0,
+	PLACEMENT_NID_POLICY    = 1,
+	PLACEMENT_INVAL_POLICY  = 2,
+	PLACEMENT_MAX_POLICY
+};
+
+typedef enum placement_policy placement_policy_t;
+
+struct lmv_obd {
+	int			refcount;
+	struct lu_client_fld	lmv_fld;
+	spinlock_t		lmv_lock;
+	placement_policy_t	lmv_placement;
+	struct lmv_desc		desc;
+	struct obd_uuid		cluuid;
+	struct obd_export	*exp;
+
+	struct mutex		init_mutex;
+	int			connected;
+	int			max_easize;
+	int			max_def_easize;
+	int			max_cookiesize;
+	int			server_timeout;
+
+	int			tgts_size; /* size of tgts array */
+	struct lmv_tgt_desc	**tgts;
+
+	struct obd_connect_data	conn_data;
+};
+
+struct niobuf_local {
+	__u64		lnb_file_offset;
+	__u32		lnb_page_offset;
+	__u32		len;
+	__u32		flags;
+	struct page	*page;
+	struct dentry	*dentry;
+	int		lnb_grant_used;
+	int		rc;
+};
+
+#define LUSTRE_FLD_NAME	 "fld"
+#define LUSTRE_SEQ_NAME	 "seq"
+
+#define LUSTRE_MDD_NAME	 "mdd"
+#define LUSTRE_OSD_LDISKFS_NAME	"osd-ldiskfs"
+#define LUSTRE_OSD_ZFS_NAME     "osd-zfs"
+#define LUSTRE_VVP_NAME	 "vvp"
+#define LUSTRE_LMV_NAME	 "lmv"
+#define LUSTRE_SLP_NAME	 "slp"
+#define LUSTRE_LOD_NAME		"lod"
+#define LUSTRE_OSP_NAME		"osp"
+#define LUSTRE_LWP_NAME		"lwp"
+
+/* obd device type names */
+ /* FIXME all the references to LUSTRE_MDS_NAME should be swapped with LUSTRE_MDT_NAME */
+#define LUSTRE_MDS_NAME	 "mds"
+#define LUSTRE_MDT_NAME	 "mdt"
+#define LUSTRE_MDC_NAME	 "mdc"
+#define LUSTRE_OSS_NAME	 "ost"       /* FIXME change name to oss */
+#define LUSTRE_OST_NAME	 "obdfilter" /* FIXME change name to ost */
+#define LUSTRE_OSC_NAME	 "osc"
+#define LUSTRE_LOV_NAME	 "lov"
+#define LUSTRE_MGS_NAME	 "mgs"
+#define LUSTRE_MGC_NAME	 "mgc"
+
+#define LUSTRE_ECHO_NAME	"obdecho"
+#define LUSTRE_ECHO_CLIENT_NAME "echo_client"
+#define LUSTRE_QMT_NAME	 "qmt"
+
+/* Constant obd names (post-rename) */
+#define LUSTRE_MDS_OBDNAME "MDS"
+#define LUSTRE_OSS_OBDNAME "OSS"
+#define LUSTRE_MGS_OBDNAME "MGS"
+#define LUSTRE_MGC_OBDNAME "MGC"
+
+static inline int is_osp_on_mdt(char *name)
+{
+	char   *ptr;
+
+	ptr = strrchr(name, '-');
+	if (ptr == NULL) {
+		CERROR("%s is not a obdname\n", name);
+		return 0;
+	}
+
+	/* 1.8 OSC/OSP name on MDT is fsname-OSTxxxx-osc */
+	if (strncmp(ptr + 1, "osc", 3) == 0)
+		return 1;
+
+	if (strncmp(ptr + 1, "MDT", 3) != 0)
+		return 0;
+
+	while (*(--ptr) != '-' && ptr != name);
+
+	if (ptr == name)
+		return 0;
+
+	if (strncmp(ptr + 1, LUSTRE_OSP_NAME, strlen(LUSTRE_OSP_NAME)) != 0 &&
+	    strncmp(ptr + 1, LUSTRE_OSC_NAME, strlen(LUSTRE_OSC_NAME)) != 0)
+		return 0;
+
+	return 1;
+}
+
+/* Don't conflict with on-wire flags OBD_BRW_WRITE, etc */
+#define N_LOCAL_TEMP_PAGE 0x10000000
+
+struct obd_trans_info {
+	__u64		    oti_transno;
+	__u64		    oti_xid;
+	/* Only used on the server side for tracking acks. */
+	struct oti_req_ack_lock {
+		struct lustre_handle lock;
+		__u32		mode;
+	}			oti_ack_locks[4];
+	void		    *oti_handle;
+	struct llog_cookie       oti_onecookie;
+	struct llog_cookie      *oti_logcookies;
+	int		      oti_numcookies;
+	/** synchronous write is needed */
+	unsigned long		 oti_sync_write:1;
+
+	/* initial thread handling transaction */
+	struct ptlrpc_thread *   oti_thread;
+	__u32		    oti_conn_cnt;
+	/** VBR: versions */
+	__u64		    oti_pre_version;
+	/** JobID */
+	char		    *oti_jobid;
+
+	struct obd_uuid	 *oti_ost_uuid;
+};
+
+static inline void oti_init(struct obd_trans_info *oti,
+			    struct ptlrpc_request *req)
+{
+	if (oti == NULL)
+		return;
+	memset(oti, 0, sizeof(*oti));
+
+	if (req == NULL)
+		return;
+
+	oti->oti_xid = req->rq_xid;
+	/** VBR: take versions from request */
+	if (req->rq_reqmsg != NULL &&
+	    lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) {
+		__u64 *pre_version = lustre_msg_get_versions(req->rq_reqmsg);
+		oti->oti_pre_version = pre_version ? pre_version[0] : 0;
+		oti->oti_transno = lustre_msg_get_transno(req->rq_reqmsg);
+	}
+
+	/** called from mds_create_objects */
+	if (req->rq_repmsg != NULL)
+		oti->oti_transno = lustre_msg_get_transno(req->rq_repmsg);
+	oti->oti_thread = req->rq_svc_thread;
+	if (req->rq_reqmsg != NULL)
+		oti->oti_conn_cnt = lustre_msg_get_conn_cnt(req->rq_reqmsg);
+}
+
+static inline void oti_alloc_cookies(struct obd_trans_info *oti,int num_cookies)
+{
+	if (!oti)
+		return;
+
+	if (num_cookies == 1)
+		oti->oti_logcookies = &oti->oti_onecookie;
+	else
+		OBD_ALLOC_LARGE(oti->oti_logcookies,
+				num_cookies * sizeof(oti->oti_onecookie));
+
+	oti->oti_numcookies = num_cookies;
+}
+
+static inline void oti_free_cookies(struct obd_trans_info *oti)
+{
+	if (!oti || !oti->oti_logcookies)
+		return;
+
+	if (oti->oti_logcookies == &oti->oti_onecookie)
+		LASSERT(oti->oti_numcookies == 1);
+	else
+		OBD_FREE_LARGE(oti->oti_logcookies,
+			       oti->oti_numcookies*sizeof(oti->oti_onecookie));
+	oti->oti_logcookies = NULL;
+	oti->oti_numcookies = 0;
+}
+
+/*
+ * Events signalled through obd_notify() upcall-chain.
+ */
+enum obd_notify_event {
+	/* target added */
+	OBD_NOTIFY_CREATE,
+	/* Device connect start */
+	OBD_NOTIFY_CONNECT,
+	/* Device activated */
+	OBD_NOTIFY_ACTIVE,
+	/* Device deactivated */
+	OBD_NOTIFY_INACTIVE,
+	/* Device disconnected */
+	OBD_NOTIFY_DISCON,
+	/* Connect data for import were changed */
+	OBD_NOTIFY_OCD,
+	/* Sync request */
+	OBD_NOTIFY_SYNC_NONBLOCK,
+	OBD_NOTIFY_SYNC,
+	/* Configuration event */
+	OBD_NOTIFY_CONFIG,
+	/* Administratively deactivate/activate event */
+	OBD_NOTIFY_DEACTIVATE,
+	OBD_NOTIFY_ACTIVATE
+};
+
+/*
+ * Data structure used to pass obd_notify()-event to non-obd listeners (llite
+ * and liblustre being main examples).
+ */
+struct obd_notify_upcall {
+	int (*onu_upcall)(struct obd_device *host, struct obd_device *watched,
+			  enum obd_notify_event ev, void *owner, void *data);
+	/* Opaque datum supplied by upper layer listener */
+	void *onu_owner;
+};
+
+struct target_recovery_data {
+	svc_handler_t		trd_recovery_handler;
+	pid_t			trd_processing_task;
+	struct completion	trd_starting;
+	struct completion	trd_finishing;
+};
+
+struct obd_llog_group {
+	int		olg_seq;
+	struct llog_ctxt  *olg_ctxts[LLOG_MAX_CTXTS];
+	wait_queue_head_t	olg_waitq;
+	spinlock_t	   olg_lock;
+	struct mutex	   olg_cat_processing;
+};
+
+/* corresponds to one of the obd's */
+#define OBD_DEVICE_MAGIC	0XAB5CD6EF
+#define OBD_DEV_BY_DEVNAME      0xffffd0de
+
+struct obd_device {
+	struct obd_type	*obd_type;
+	__u32		   obd_magic;
+
+	/* common and UUID name of this device */
+	char		    obd_name[MAX_OBD_NAME];
+	struct obd_uuid	 obd_uuid;
+
+	struct lu_device       *obd_lu_dev;
+
+	int		     obd_minor;
+	/* bitfield modification is protected by obd_dev_lock */
+	unsigned long obd_attached:1,      /* finished attach */
+		      obd_set_up:1,	/* finished setup */
+		      obd_recovering:1,    /* there are recoverable clients */
+		      obd_abort_recovery:1,/* recovery expired */
+		      obd_version_recov:1, /* obd uses version checking */
+		      obd_replayable:1,    /* recovery is enabled; inform clients */
+		      obd_no_transno:1,    /* no committed-transno notification */
+		      obd_no_recov:1,      /* fail instead of retry messages */
+		      obd_stopping:1,      /* started cleanup */
+		      obd_starting:1,      /* started setup */
+		      obd_force:1,	 /* cleanup with > 0 obd refcount */
+		      obd_fail:1,	  /* cleanup with failover */
+		      obd_async_recov:1,   /* allow asynchronous orphan cleanup */
+		      obd_no_conn:1,       /* deny new connections */
+		      obd_inactive:1,      /* device active/inactive
+					   * (for /proc/status only!!) */
+		      obd_no_ir:1,	 /* no imperative recovery. */
+		      obd_process_conf:1;  /* device is processing mgs config */
+	/* use separate field as it is set in interrupt to don't mess with
+	 * protection of other bits using _bh lock */
+	unsigned long obd_recovery_expired:1;
+	/* uuid-export hash body */
+	cfs_hash_t	     *obd_uuid_hash;
+	/* nid-export hash body */
+	cfs_hash_t	     *obd_nid_hash;
+	/* nid stats body */
+	cfs_hash_t	     *obd_nid_stats_hash;
+	struct list_head	      obd_nid_stats;
+	atomic_t	    obd_refcount;
+	wait_queue_head_t	     obd_refcount_waitq;
+	struct list_head	      obd_exports;
+	struct list_head	      obd_unlinked_exports;
+	struct list_head	      obd_delayed_exports;
+	int		     obd_num_exports;
+	spinlock_t		obd_nid_lock;
+	struct ldlm_namespace  *obd_namespace;
+	struct ptlrpc_client	obd_ldlm_client; /* XXX OST/MDS only */
+	/* a spinlock is OK for what we do now, may need a semaphore later */
+	spinlock_t		obd_dev_lock; /* protect OBD bitfield above */
+	struct mutex		obd_dev_mutex;
+	__u64			obd_last_committed;
+	struct fsfilt_operations *obd_fsops;
+	spinlock_t		obd_osfs_lock;
+	struct obd_statfs	obd_osfs;       /* locked by obd_osfs_lock */
+	__u64			obd_osfs_age;
+	struct lvfs_run_ctxt	obd_lvfs_ctxt;
+	struct obd_llog_group	obd_olg;	/* default llog group */
+	struct obd_device	*obd_observer;
+	struct rw_semaphore	obd_observer_link_sem;
+	struct obd_notify_upcall obd_upcall;
+	struct obd_export       *obd_self_export;
+	/* list of exports in LRU order, for ping evictor, with obd_dev_lock */
+	struct list_head	      obd_exports_timed;
+	time_t		  obd_eviction_timer; /* for ping evictor */
+
+	int			      obd_max_recoverable_clients;
+	atomic_t		     obd_connected_clients;
+	int			      obd_stale_clients;
+	int			      obd_delayed_clients;
+	/* this lock protects all recovery list_heads, timer and
+	 * obd_next_recovery_transno value */
+	spinlock_t			 obd_recovery_task_lock;
+	__u64			    obd_next_recovery_transno;
+	int			      obd_replayed_requests;
+	int			      obd_requests_queued_for_recovery;
+	wait_queue_head_t		      obd_next_transno_waitq;
+	/* protected by obd_recovery_task_lock */
+	timer_list_t		      obd_recovery_timer;
+	time_t			   obd_recovery_start; /* seconds */
+	time_t			   obd_recovery_end; /* seconds, for lprocfs_status */
+	int			      obd_recovery_time_hard;
+	int			      obd_recovery_timeout;
+	int			      obd_recovery_ir_factor;
+
+	/* new recovery stuff from CMD2 */
+	struct target_recovery_data      obd_recovery_data;
+	int			      obd_replayed_locks;
+	atomic_t		     obd_req_replay_clients;
+	atomic_t		     obd_lock_replay_clients;
+	/* all lists are protected by obd_recovery_task_lock */
+	struct list_head		       obd_req_replay_queue;
+	struct list_head		       obd_lock_replay_queue;
+	struct list_head		       obd_final_req_queue;
+	int			      obd_recovery_stage;
+
+	union {
+		struct obd_device_target obt;
+		struct filter_obd filter;
+		struct client_obd cli;
+		struct ost_obd ost;
+		struct echo_client_obd echo_client;
+		struct echo_obd echo;
+		struct lov_obd lov;
+		struct lmv_obd lmv;
+	} u;
+	/* Fields used by LProcFS */
+	unsigned int	   obd_cntr_base;
+	struct lprocfs_stats  *obd_stats;
+
+	unsigned int	   md_cntr_base;
+	struct lprocfs_stats  *md_stats;
+
+	proc_dir_entry_t  *obd_proc_entry;
+	void		  *obd_proc_private; /* type private PDEs */
+	proc_dir_entry_t  *obd_proc_exports_entry;
+	proc_dir_entry_t  *obd_svc_procroot;
+	struct lprocfs_stats  *obd_svc_stats;
+	atomic_t	   obd_evict_inprogress;
+	wait_queue_head_t	    obd_evict_inprogress_waitq;
+	struct list_head	     obd_evict_list; /* protected with pet_lock */
+
+	/**
+	 * Ldlm pool part. Save last calculated SLV and Limit.
+	 */
+	rwlock_t		obd_pool_lock;
+	int		    obd_pool_limit;
+	__u64		  obd_pool_slv;
+
+	/**
+	 * A list of outstanding class_incref()'s against this obd. For
+	 * debugging.
+	 */
+	struct lu_ref	  obd_reference;
+
+	int		       obd_conn_inprogress;
+};
+
+#define OBD_LLOG_FL_SENDNOW     0x0001
+#define OBD_LLOG_FL_EXIT	0x0002
+
+enum obd_cleanup_stage {
+/* Special case hack for MDS LOVs */
+	OBD_CLEANUP_EARLY,
+/* can be directly mapped to .ldto_device_fini() */
+	OBD_CLEANUP_EXPORTS,
+};
+
+/* get/set_info keys */
+#define KEY_ASYNC	       "async"
+#define KEY_BLOCKSIZE_BITS      "blocksize_bits"
+#define KEY_BLOCKSIZE	   "blocksize"
+#define KEY_CAPA_KEY	    "capa_key"
+#define KEY_CHANGELOG_CLEAR     "changelog_clear"
+#define KEY_FID2PATH	    "fid2path"
+#define KEY_CHECKSUM	    "checksum"
+#define KEY_CLEAR_FS	    "clear_fs"
+#define KEY_CONN_DATA	   "conn_data"
+#define KEY_EVICT_BY_NID	"evict_by_nid"
+#define KEY_FIEMAP	      "fiemap"
+#define KEY_FLUSH_CTX	   "flush_ctx"
+#define KEY_GRANT_SHRINK	"grant_shrink"
+#define KEY_HSM_COPYTOOL_SEND   "hsm_send"
+#define KEY_INIT_RECOV_BACKUP   "init_recov_bk"
+#define KEY_INIT_RECOV	  "initial_recov"
+#define KEY_INTERMDS	    "inter_mds"
+#define KEY_LAST_ID	     "last_id"
+#define KEY_LAST_FID		"last_fid"
+#define KEY_LOCK_TO_STRIPE      "lock_to_stripe"
+#define KEY_LOVDESC	     "lovdesc"
+#define KEY_LOV_IDX	     "lov_idx"
+#define KEY_MAX_EASIZE	  "max_easize"
+#define KEY_MDS_CONN	    "mds_conn"
+#define KEY_MGSSEC	      "mgssec"
+#define KEY_NEXT_ID	     "next_id"
+#define KEY_READ_ONLY	   "read-only"
+#define KEY_REGISTER_TARGET     "register_target"
+#define KEY_SET_FS	      "set_fs"
+#define KEY_TGT_COUNT	   "tgt_count"
+/*      KEY_SET_INFO in lustre_idl.h */
+#define KEY_SPTLRPC_CONF	"sptlrpc_conf"
+#define KEY_CONNECT_FLAG	"connect_flags"
+#define KEY_SYNC_LOCK_CANCEL    "sync_lock_cancel"
+
+#define KEY_CACHE_SET		"cache_set"
+#define KEY_CACHE_LRU_SHRINK	"cache_lru_shrink"
+#define KEY_CHANGELOG_INDEX	"changelog_index"
+
+struct lu_context;
+
+/* /!\ must be coherent with include/linux/namei.h on patched kernel */
+#define IT_OPEN     (1 << 0)
+#define IT_CREAT    (1 << 1)
+#define IT_READDIR  (1 << 2)
+#define IT_GETATTR  (1 << 3)
+#define IT_LOOKUP   (1 << 4)
+#define IT_UNLINK   (1 << 5)
+#define IT_TRUNC    (1 << 6)
+#define IT_GETXATTR (1 << 7)
+#define IT_EXEC     (1 << 8)
+#define IT_PIN      (1 << 9)
+#define IT_LAYOUT   (1 << 10)
+#define IT_QUOTA_DQACQ (1 << 11)
+#define IT_QUOTA_CONN  (1 << 12)
+
+static inline int it_to_lock_mode(struct lookup_intent *it)
+{
+	/* CREAT needs to be tested before open (both could be set) */
+	if (it->it_op & IT_CREAT)
+		return LCK_CW;
+	else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_LOOKUP |
+			      IT_LAYOUT))
+		return LCK_CR;
+
+	LASSERTF(0, "Invalid it_op: %d\n", it->it_op);
+	return -EINVAL;
+}
+
+struct md_op_data {
+	struct lu_fid	   op_fid1; /* operation fid1 (usualy parent) */
+	struct lu_fid	   op_fid2; /* operation fid2 (usualy child) */
+	struct lu_fid	   op_fid3; /* 2 extra fids to find conflicting */
+	struct lu_fid	   op_fid4; /* to the operation locks. */
+	mdsno_t		 op_mds;  /* what mds server open will go to */
+	struct lustre_handle    op_handle;
+	obd_time		op_mod_time;
+	const char	     *op_name;
+	int		     op_namelen;
+	__u32		   op_mode;
+	struct lmv_stripe_md   *op_mea1;
+	struct lmv_stripe_md   *op_mea2;
+	__u32		   op_suppgids[2];
+	__u32		   op_fsuid;
+	__u32		   op_fsgid;
+	cfs_cap_t	       op_cap;
+	void		   *op_data;
+
+	/* iattr fields and blocks. */
+	struct iattr	    op_attr;
+	unsigned int	    op_attr_flags;
+	__u64		   op_valid;
+	loff_t		  op_attr_blocks;
+
+	/* Size-on-MDS epoch and flags. */
+	__u64		   op_ioepoch;
+	__u32		   op_flags;
+
+	/* Capa fields */
+	struct obd_capa	*op_capa1;
+	struct obd_capa	*op_capa2;
+
+	/* Various operation flags. */
+	__u32		   op_bias;
+
+	/* Operation type */
+	__u32		   op_opc;
+
+	/* Used by readdir */
+	__u64		   op_offset;
+
+	/* Used by readdir */
+	__u32		   op_npages;
+
+	/* used to transfer info between the stacks of MD client
+	 * see enum op_cli_flags */
+	__u32			op_cli_flags;
+};
+
+enum op_cli_flags {
+	CLI_SET_MEA	= 1 << 0,
+	CLI_RM_ENTRY	= 1 << 1,
+};
+
+struct md_enqueue_info;
+/* metadata stat-ahead */
+typedef int (* md_enqueue_cb_t)(struct ptlrpc_request *req,
+				struct md_enqueue_info *minfo,
+				int rc);
+
+/* seq client type */
+enum lu_cli_type {
+	LUSTRE_SEQ_METADATA = 1,
+	LUSTRE_SEQ_DATA
+};
+
+struct md_enqueue_info {
+	struct md_op_data       mi_data;
+	struct lookup_intent    mi_it;
+	struct lustre_handle    mi_lockh;
+	struct inode	   *mi_dir;
+	md_enqueue_cb_t	 mi_cb;
+	__u64		   mi_cbdata;
+	unsigned int	    mi_generation;
+};
+
+struct obd_ops {
+	module_t *o_owner;
+	int (*o_iocontrol)(unsigned int cmd, struct obd_export *exp, int len,
+			   void *karg, void *uarg);
+	int (*o_get_info)(const struct lu_env *env, struct obd_export *,
+			  __u32 keylen, void *key, __u32 *vallen, void *val,
+			  struct lov_stripe_md *lsm);
+	int (*o_set_info_async)(const struct lu_env *, struct obd_export *,
+				__u32 keylen, void *key,
+				__u32 vallen, void *val,
+				struct ptlrpc_request_set *set);
+	int (*o_attach)(struct obd_device *dev, obd_count len, void *data);
+	int (*o_detach)(struct obd_device *dev);
+	int (*o_setup) (struct obd_device *dev, struct lustre_cfg *cfg);
+	int (*o_precleanup)(struct obd_device *dev,
+			    enum obd_cleanup_stage cleanup_stage);
+	int (*o_cleanup)(struct obd_device *dev);
+	int (*o_process_config)(struct obd_device *dev, obd_count len,
+				void *data);
+	int (*o_postrecov)(struct obd_device *dev);
+	int (*o_add_conn)(struct obd_import *imp, struct obd_uuid *uuid,
+			  int priority);
+	int (*o_del_conn)(struct obd_import *imp, struct obd_uuid *uuid);
+	/* connect to the target device with given connection
+	 * data. @ocd->ocd_connect_flags is modified to reflect flags actually
+	 * granted by the target, which are guaranteed to be a subset of flags
+	 * asked for. If @ocd == NULL, use default parameters. */
+	int (*o_connect)(const struct lu_env *env,
+			 struct obd_export **exp, struct obd_device *src,
+			 struct obd_uuid *cluuid, struct obd_connect_data *ocd,
+			 void *localdata);
+	int (*o_reconnect)(const struct lu_env *env,
+			   struct obd_export *exp, struct obd_device *src,
+			   struct obd_uuid *cluuid,
+			   struct obd_connect_data *ocd,
+			   void *localdata);
+	int (*o_disconnect)(struct obd_export *exp);
+
+	/* Initialize/finalize fids infrastructure. */
+	int (*o_fid_init)(struct obd_device *obd,
+			  struct obd_export *exp, enum lu_cli_type type);
+	int (*o_fid_fini)(struct obd_device *obd);
+
+	/* Allocate new fid according to passed @hint. */
+	int (*o_fid_alloc)(struct obd_export *exp, struct lu_fid *fid,
+			   struct md_op_data *op_data);
+
+	/*
+	 * Object with @fid is getting deleted, we may want to do something
+	 * about this.
+	 */
+	int (*o_statfs)(const struct lu_env *, struct obd_export *exp,
+			struct obd_statfs *osfs, __u64 max_age, __u32 flags);
+	int (*o_statfs_async)(struct obd_export *exp, struct obd_info *oinfo,
+			      __u64 max_age, struct ptlrpc_request_set *set);
+	int (*o_packmd)(struct obd_export *exp, struct lov_mds_md **disk_tgt,
+			struct lov_stripe_md *mem_src);
+	int (*o_unpackmd)(struct obd_export *exp,struct lov_stripe_md **mem_tgt,
+			  struct lov_mds_md *disk_src, int disk_len);
+	int (*o_preallocate)(struct lustre_handle *, obd_count *req,
+			     obd_id *ids);
+	/* FIXME: add fid capability support for create & destroy! */
+	int (*o_precreate)(struct obd_export *exp);
+	int (*o_create)(const struct lu_env *env, struct obd_export *exp,
+			struct obdo *oa, struct lov_stripe_md **ea,
+			struct obd_trans_info *oti);
+	int (*o_create_async)(struct obd_export *exp,  struct obd_info *oinfo,
+			      struct lov_stripe_md **ea,
+			      struct obd_trans_info *oti);
+	int (*o_destroy)(const struct lu_env *env, struct obd_export *exp,
+			 struct obdo *oa, struct lov_stripe_md *ea,
+			 struct obd_trans_info *oti, struct obd_export *md_exp,
+			 void *capa);
+	int (*o_setattr)(const struct lu_env *, struct obd_export *exp,
+			 struct obd_info *oinfo, struct obd_trans_info *oti);
+	int (*o_setattr_async)(struct obd_export *exp, struct obd_info *oinfo,
+			       struct obd_trans_info *oti,
+			       struct ptlrpc_request_set *rqset);
+	int (*o_getattr)(const struct lu_env *env, struct obd_export *exp,
+			 struct obd_info *oinfo);
+	int (*o_getattr_async)(struct obd_export *exp, struct obd_info *oinfo,
+			       struct ptlrpc_request_set *set);
+	int (*o_brw)(int rw, struct obd_export *exp, struct obd_info *oinfo,
+		     obd_count oa_bufs, struct brw_page *pgarr,
+		     struct obd_trans_info *oti);
+	int (*o_merge_lvb)(struct obd_export *exp, struct lov_stripe_md *lsm,
+			   struct ost_lvb *lvb, int kms_only);
+	int (*o_adjust_kms)(struct obd_export *exp, struct lov_stripe_md *lsm,
+			    obd_off size, int shrink);
+	int (*o_punch)(const struct lu_env *, struct obd_export *exp,
+		       struct obd_info *oinfo, struct obd_trans_info *oti,
+		       struct ptlrpc_request_set *rqset);
+	int (*o_sync)(const struct lu_env *env, struct obd_export *exp,
+		      struct obd_info *oinfo, obd_size start, obd_size end,
+		      struct ptlrpc_request_set *set);
+	int (*o_migrate)(struct lustre_handle *conn, struct lov_stripe_md *dst,
+			 struct lov_stripe_md *src, obd_size start,
+			 obd_size end, struct obd_trans_info *oti);
+	int (*o_copy)(struct lustre_handle *dstconn, struct lov_stripe_md *dst,
+		      struct lustre_handle *srconn, struct lov_stripe_md *src,
+		      obd_size start, obd_size end, struct obd_trans_info *);
+	int (*o_iterate)(struct lustre_handle *conn,
+			 int (*)(obd_id, obd_seq, void *),
+			 obd_id *startid, obd_seq seq, void *data);
+	int (*o_preprw)(const struct lu_env *env, int cmd,
+			struct obd_export *exp, struct obdo *oa, int objcount,
+			struct obd_ioobj *obj, struct niobuf_remote *remote,
+			int *nr_pages, struct niobuf_local *local,
+			struct obd_trans_info *oti, struct lustre_capa *capa);
+	int (*o_commitrw)(const struct lu_env *env, int cmd,
+			  struct obd_export *exp, struct obdo *oa,
+			  int objcount, struct obd_ioobj *obj,
+			  struct niobuf_remote *remote, int pages,
+			  struct niobuf_local *local,
+			  struct obd_trans_info *oti, int rc);
+	int (*o_enqueue)(struct obd_export *, struct obd_info *oinfo,
+			 struct ldlm_enqueue_info *einfo,
+			 struct ptlrpc_request_set *rqset);
+	int (*o_change_cbdata)(struct obd_export *, struct lov_stripe_md *,
+			       ldlm_iterator_t it, void *data);
+	int (*o_find_cbdata)(struct obd_export *, struct lov_stripe_md *,
+			     ldlm_iterator_t it, void *data);
+	int (*o_cancel)(struct obd_export *, struct lov_stripe_md *md,
+			__u32 mode, struct lustre_handle *);
+	int (*o_cancel_unused)(struct obd_export *, struct lov_stripe_md *,
+			       ldlm_cancel_flags_t flags, void *opaque);
+	int (*o_init_export)(struct obd_export *exp);
+	int (*o_destroy_export)(struct obd_export *exp);
+	int (*o_extent_calc)(struct obd_export *, struct lov_stripe_md *,
+			     int cmd, obd_off *);
+
+	/* llog related obd_methods */
+	int (*o_llog_init)(struct obd_device *obd, struct obd_llog_group *grp,
+			   struct obd_device *disk_obd, int *idx);
+	int (*o_llog_finish)(struct obd_device *obd, int count);
+	int (*o_llog_connect)(struct obd_export *, struct llogd_conn_body *);
+
+	/* metadata-only methods */
+	int (*o_pin)(struct obd_export *, const struct lu_fid *fid,
+		     struct obd_capa *, struct obd_client_handle *, int flag);
+	int (*o_unpin)(struct obd_export *, struct obd_client_handle *, int);
+
+	int (*o_import_event)(struct obd_device *, struct obd_import *,
+			      enum obd_import_event);
+
+	int (*o_notify)(struct obd_device *obd, struct obd_device *watched,
+			enum obd_notify_event ev, void *data);
+
+	int (*o_health_check)(const struct lu_env *env, struct obd_device *);
+	struct obd_uuid *(*o_get_uuid) (struct obd_export *exp);
+
+	/* quota methods */
+	int (*o_quotacheck)(struct obd_device *, struct obd_export *,
+			    struct obd_quotactl *);
+	int (*o_quotactl)(struct obd_device *, struct obd_export *,
+			  struct obd_quotactl *);
+
+	int (*o_ping)(const struct lu_env *, struct obd_export *exp);
+
+	/* pools methods */
+	int (*o_pool_new)(struct obd_device *obd, char *poolname);
+	int (*o_pool_del)(struct obd_device *obd, char *poolname);
+	int (*o_pool_add)(struct obd_device *obd, char *poolname,
+			  char *ostname);
+	int (*o_pool_rem)(struct obd_device *obd, char *poolname,
+			  char *ostname);
+	void (*o_getref)(struct obd_device *obd);
+	void (*o_putref)(struct obd_device *obd);
+	/*
+	 * NOTE: If adding ops, add another LPROCFS_OBD_OP_INIT() line
+	 * to lprocfs_alloc_obd_stats() in obdclass/lprocfs_status.c.
+	 * Also, add a wrapper function in include/linux/obd_class.h. */
+};
+
+enum {
+	LUSTRE_OPC_MKDIR    = (1 << 0),
+	LUSTRE_OPC_SYMLINK  = (1 << 1),
+	LUSTRE_OPC_MKNOD    = (1 << 2),
+	LUSTRE_OPC_CREATE   = (1 << 3),
+	LUSTRE_OPC_ANY      = (1 << 4)
+};
+
+/* lmv structures */
+#define MEA_MAGIC_LAST_CHAR      0xb2221ca1
+#define MEA_MAGIC_ALL_CHARS      0xb222a11c
+#define MEA_MAGIC_HASH_SEGMENT   0xb222a11b
+
+#define MAX_HASH_SIZE_32	 0x7fffffffUL
+#define MAX_HASH_SIZE	    0x7fffffffffffffffULL
+#define MAX_HASH_HIGHEST_BIT     0x1000000000000000ULL
+
+struct lustre_md {
+	struct mdt_body	 *body;
+	struct lov_stripe_md    *lsm;
+	struct lmv_stripe_md    *mea;
+#ifdef CONFIG_FS_POSIX_ACL
+	struct posix_acl	*posix_acl;
+#endif
+	struct mdt_remote_perm  *remote_perm;
+	struct obd_capa	 *mds_capa;
+	struct obd_capa	 *oss_capa;
+};
+
+struct md_open_data {
+	struct obd_client_handle *mod_och;
+	struct ptlrpc_request    *mod_open_req;
+	struct ptlrpc_request    *mod_close_req;
+	atomic_t	      mod_refcount;
+};
+
+struct lookup_intent;
+
+struct md_ops {
+	int (*m_getstatus)(struct obd_export *, struct lu_fid *,
+			   struct obd_capa **);
+	int (*m_null_inode)(struct obd_export *, const struct lu_fid *);
+	int (*m_find_cbdata)(struct obd_export *, const struct lu_fid *,
+			     ldlm_iterator_t, void *);
+	int (*m_close)(struct obd_export *, struct md_op_data *,
+		       struct md_open_data *, struct ptlrpc_request **);
+	int (*m_create)(struct obd_export *, struct md_op_data *,
+			const void *, int, int, __u32, __u32, cfs_cap_t,
+			__u64, struct ptlrpc_request **);
+	int (*m_done_writing)(struct obd_export *, struct md_op_data  *,
+			      struct md_open_data *);
+	int (*m_enqueue)(struct obd_export *, struct ldlm_enqueue_info *,
+			 struct lookup_intent *, struct md_op_data *,
+			 struct lustre_handle *, void *, int,
+			 struct ptlrpc_request **, __u64);
+	int (*m_getattr)(struct obd_export *, struct md_op_data *,
+			 struct ptlrpc_request **);
+	int (*m_getattr_name)(struct obd_export *, struct md_op_data *,
+			      struct ptlrpc_request **);
+	int (*m_intent_lock)(struct obd_export *, struct md_op_data *,
+			     void *, int, struct lookup_intent *, int,
+			     struct ptlrpc_request **,
+			     ldlm_blocking_callback, __u64);
+	int (*m_link)(struct obd_export *, struct md_op_data *,
+		      struct ptlrpc_request **);
+	int (*m_rename)(struct obd_export *, struct md_op_data *,
+			const char *, int, const char *, int,
+			struct ptlrpc_request **);
+	int (*m_is_subdir)(struct obd_export *, const struct lu_fid *,
+			   const struct lu_fid *,
+			   struct ptlrpc_request **);
+	int (*m_setattr)(struct obd_export *, struct md_op_data *, void *,
+			 int , void *, int, struct ptlrpc_request **,
+			 struct md_open_data **mod);
+	int (*m_sync)(struct obd_export *, const struct lu_fid *,
+		      struct obd_capa *, struct ptlrpc_request **);
+	int (*m_readpage)(struct obd_export *, struct md_op_data *,
+			  struct page **, struct ptlrpc_request **);
+
+	int (*m_unlink)(struct obd_export *, struct md_op_data *,
+			struct ptlrpc_request **);
+
+	int (*m_setxattr)(struct obd_export *, const struct lu_fid *,
+			  struct obd_capa *, obd_valid, const char *,
+			  const char *, int, int, int, __u32,
+			  struct ptlrpc_request **);
+
+	int (*m_getxattr)(struct obd_export *, const struct lu_fid *,
+			  struct obd_capa *, obd_valid, const char *,
+			  const char *, int, int, int,
+			  struct ptlrpc_request **);
+
+	int (*m_init_ea_size)(struct obd_export *, int, int, int);
+
+	int (*m_get_lustre_md)(struct obd_export *, struct ptlrpc_request *,
+			       struct obd_export *, struct obd_export *,
+			       struct lustre_md *);
+
+	int (*m_free_lustre_md)(struct obd_export *, struct lustre_md *);
+
+	int (*m_set_open_replay_data)(struct obd_export *,
+				      struct obd_client_handle *,
+				      struct ptlrpc_request *);
+	int (*m_clear_open_replay_data)(struct obd_export *,
+					struct obd_client_handle *);
+	int (*m_set_lock_data)(struct obd_export *, __u64 *, void *, __u64 *);
+
+	ldlm_mode_t (*m_lock_match)(struct obd_export *, __u64,
+				    const struct lu_fid *, ldlm_type_t,
+				    ldlm_policy_data_t *, ldlm_mode_t,
+				    struct lustre_handle *);
+
+	int (*m_cancel_unused)(struct obd_export *, const struct lu_fid *,
+			       ldlm_policy_data_t *, ldlm_mode_t,
+			       ldlm_cancel_flags_t flags, void *opaque);
+	int (*m_renew_capa)(struct obd_export *, struct obd_capa *oc,
+			    renew_capa_cb_t cb);
+	int (*m_unpack_capa)(struct obd_export *, struct ptlrpc_request *,
+			     const struct req_msg_field *, struct obd_capa **);
+
+	int (*m_get_remote_perm)(struct obd_export *, const struct lu_fid *,
+				 struct obd_capa *, __u32,
+				 struct ptlrpc_request **);
+
+	int (*m_intent_getattr_async)(struct obd_export *,
+				      struct md_enqueue_info *,
+				      struct ldlm_enqueue_info *);
+
+	int (*m_revalidate_lock)(struct obd_export *, struct lookup_intent *,
+				 struct lu_fid *, __u64 *bits);
+
+	/*
+	 * NOTE: If adding ops, add another LPROCFS_MD_OP_INIT() line to
+	 * lprocfs_alloc_md_stats() in obdclass/lprocfs_status.c. Also, add a
+	 * wrapper function in include/linux/obd_class.h.
+	 */
+};
+
+struct lsm_operations {
+	void (*lsm_free)(struct lov_stripe_md *);
+	int (*lsm_destroy)(struct lov_stripe_md *, struct obdo *oa,
+			   struct obd_export *md_exp);
+	void (*lsm_stripe_by_index)(struct lov_stripe_md *, int *, obd_off *,
+				    obd_off *);
+	void (*lsm_stripe_by_offset)(struct lov_stripe_md *, int *, obd_off *,
+				     obd_off *);
+	int (*lsm_lmm_verify) (struct lov_mds_md *lmm, int lmm_bytes,
+			       __u16 *stripe_count);
+	int (*lsm_unpackmd) (struct lov_obd *lov, struct lov_stripe_md *lsm,
+			     struct lov_mds_md *lmm);
+};
+
+extern const struct lsm_operations lsm_v1_ops;
+extern const struct lsm_operations lsm_v3_ops;
+static inline const struct lsm_operations *lsm_op_find(int magic)
+{
+	switch(magic) {
+	case LOV_MAGIC_V1:
+	       return &lsm_v1_ops;
+	case LOV_MAGIC_V3:
+	       return &lsm_v3_ops;
+	default:
+	       CERROR("Cannot recognize lsm_magic %08x\n", magic);
+	       return NULL;
+	}
+}
+
+/* Requests for obd_extent_calc() */
+#define OBD_CALC_STRIPE_START   1
+#define OBD_CALC_STRIPE_END     2
+
+static inline struct lustre_capa *oinfo_capa(struct obd_info *oinfo)
+{
+	return oinfo->oi_capa;
+}
+
+static inline struct md_open_data *obd_mod_alloc(void)
+{
+	struct md_open_data *mod;
+	OBD_ALLOC_PTR(mod);
+	if (mod == NULL)
+		return NULL;
+	atomic_set(&mod->mod_refcount, 1);
+	return mod;
+}
+
+#define obd_mod_get(mod) atomic_inc(&(mod)->mod_refcount)
+#define obd_mod_put(mod)					\
+({							      \
+	if (atomic_dec_and_test(&(mod)->mod_refcount)) {	  \
+		if ((mod)->mod_open_req)			  \
+			ptlrpc_req_finished((mod)->mod_open_req);   \
+		OBD_FREE_PTR(mod);			      \
+	}						       \
+})
+
+void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid);
+void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent);
+
+/* return 1 if client should be resend request */
+static inline int client_should_resend(int resend, struct client_obd *cli)
+{
+	return atomic_read(&cli->cl_resends) ?
+	       atomic_read(&cli->cl_resends) > resend : 1;
+}
+
+/**
+ * Return device name for this device
+ *
+ * XXX: lu_device is declared before obd_device, while a pointer pointing
+ * back to obd_device in lu_device, so this helper function defines here
+ * instead of in lu_object.h
+ */
+static inline const char *lu_dev_name(const struct lu_device *lu_dev)
+{
+	return lu_dev->ld_obd->obd_name;
+}
+
+static inline bool filename_is_volatile(const char *name, int namelen, int *idx)
+{
+	const char	*start;
+	char		*end;
+
+	if (strncmp(name, LUSTRE_VOLATILE_HDR, LUSTRE_VOLATILE_HDR_LEN) != 0)
+		return false;
+
+	/* caller does not care of idx */
+	if (idx == NULL)
+		return true;
+
+	/* volatile file, the MDT can be set from name */
+	/* name format is LUSTRE_VOLATILE_HDR:[idx]: */
+	/* if no MDT is specified, use std way */
+	if (namelen < LUSTRE_VOLATILE_HDR_LEN + 2)
+		goto bad_format;
+	/* test for no MDT idx case */
+	if ((*(name + LUSTRE_VOLATILE_HDR_LEN) == ':') &&
+	    (*(name + LUSTRE_VOLATILE_HDR_LEN + 1) == ':')) {
+		*idx = -1;
+		return true;
+	}
+	/* we have an idx, read it */
+	start = name + LUSTRE_VOLATILE_HDR_LEN + 1;
+	*idx = strtoul(start, &end, 0);
+	/* error cases:
+	 * no digit, no trailing :, negative value
+	 */
+	if (((*idx == 0) && (end == start)) ||
+	    (*end != ':') || (*idx < 0))
+		goto bad_format;
+
+	return true;
+bad_format:
+	/* bad format of mdt idx, we cannot return an error
+	 * to caller so we use hash algo */
+	CERROR("Bad volatile file name format: %s\n",
+	       name + LUSTRE_VOLATILE_HDR_LEN);
+	return false;
+}
+
+static inline int cli_brw_size(struct obd_device *obd)
+{
+	LASSERT(obd != NULL);
+	return obd->u.cli.cl_max_pages_per_rpc << PAGE_CACHE_SHIFT;
+}
+
+#endif /* __OBD_H */
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_lov.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_lov.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_lov.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_lov.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,126 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _OBD_LOV_H__
+#define _OBD_LOV_H__
+
+#define LOV_DEFAULT_STRIPE_SIZE (1 << LNET_MTU_BITS)
+
+static inline int lov_stripe_md_size(__u16 stripes)
+{
+	return sizeof(struct lov_stripe_md) + stripes*sizeof(struct lov_oinfo*);
+}
+
+static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic)
+{
+	if (lmm_magic == LOV_MAGIC_V3)
+		return sizeof(struct lov_mds_md_v3) +
+			stripes * sizeof(struct lov_ost_data_v1);
+	else
+		return sizeof(struct lov_mds_md_v1) +
+			stripes * sizeof(struct lov_ost_data_v1);
+}
+
+struct lov_version_size {
+	__u32   lvs_magic;
+	size_t  lvs_lmm_size;
+	size_t  lvs_lod_size;
+};
+
+static inline __u32 lov_mds_md_stripecnt(int ea_size, __u32 lmm_magic)
+{
+	static const struct lov_version_size lmm_ver_size[] = {
+			{ .lvs_magic = LOV_MAGIC_V3,
+			  .lvs_lmm_size = sizeof(struct lov_mds_md_v3),
+			  .lvs_lod_size = sizeof(struct lov_ost_data_v1) },
+			{ .lvs_magic = LOV_MAGIC_V1,
+			  .lvs_lmm_size = sizeof(struct lov_mds_md_v1),
+			  .lvs_lod_size = sizeof(struct lov_ost_data_v1)} };
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(lmm_ver_size); i++) {
+		if (lmm_magic == lmm_ver_size[i].lvs_magic) {
+			if (ea_size <= lmm_ver_size[i].lvs_lmm_size)
+				return 0;
+			return (ea_size - lmm_ver_size[i].lvs_lmm_size) /
+				lmm_ver_size[i].lvs_lod_size;
+		}
+	}
+
+	/* Invalid LOV magic, so no stripes could fit */
+	return 0;
+}
+
+/* lov_do_div64(a, b) returns a % b, and a = a / b.
+ * The 32-bit code is LOV-specific due to knowing about stripe limits in
+ * order to reduce the divisor to a 32-bit number.  If the divisor is
+ * already a 32-bit value the compiler handles this directly. */
+#if BITS_PER_LONG > 32
+# define lov_do_div64(n,base) ({					\
+	uint64_t __base = (base);					\
+	uint64_t __rem;							\
+	__rem = ((uint64_t)(n)) % __base;				\
+	(n) = ((uint64_t)(n)) / __base;					\
+	__rem;								\
+  })
+#else
+# define lov_do_div64(n,base) ({					\
+	uint64_t __rem;							\
+	if ((sizeof(base) > 4) && (((base) & 0xffffffff00000000ULL) != 0)) {  \
+		int __remainder;					      \
+		LASSERTF(!((base) & (LOV_MIN_STRIPE_SIZE - 1)), "64 bit lov " \
+			 "division %llu / %llu\n", (n), (uint64_t)(base));    \
+		__remainder = (n) & (LOV_MIN_STRIPE_SIZE - 1);		\
+		(n) >>= LOV_MIN_STRIPE_BITS;				\
+		__rem = do_div(n, (base) >> LOV_MIN_STRIPE_BITS);	\
+		__rem <<= LOV_MIN_STRIPE_BITS;				\
+		__rem += __remainder;					\
+	} else {							\
+		__rem = do_div(n, base);				\
+	}								\
+	__rem;								\
+  })
+#endif
+
+#define IOC_LOV_TYPE		   'g'
+#define IOC_LOV_MIN_NR		 50
+#define IOC_LOV_SET_OSC_ACTIVE	 _IOWR('g', 50, long)
+#define IOC_LOV_MAX_NR		 50
+
+#define QOS_DEFAULT_THRESHOLD	   10 /* MB */
+#define QOS_DEFAULT_MAXAGE	      5  /* Seconds */
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_ost.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_ost.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_ost.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_ost.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,96 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/include/obd_ost.h
+ *
+ * Data structures for object storage targets and client: OST & OSC's
+ *
+ * See also lustre_idl.h for wire formats of requests.
+ */
+
+#ifndef _LUSTRE_OST_H
+#define _LUSTRE_OST_H
+
+#include <obd_class.h>
+
+struct osc_brw_async_args {
+	struct obdo       *aa_oa;
+	int		aa_requested_nob;
+	int		aa_nio_count;
+	obd_count	  aa_page_count;
+	int		aa_resends;
+	struct brw_page  **aa_ppga;
+	struct client_obd *aa_cli;
+	struct list_head	 aa_oaps;
+	struct list_head	 aa_exts;
+	struct obd_capa   *aa_ocapa;
+	struct cl_req     *aa_clerq;
+};
+
+#define osc_grant_args osc_brw_async_args
+struct osc_async_args {
+	struct obd_info   *aa_oi;
+};
+
+struct osc_setattr_args {
+	struct obdo	 *sa_oa;
+	obd_enqueue_update_f sa_upcall;
+	void		*sa_cookie;
+};
+
+struct osc_fsync_args {
+	struct obd_info     *fa_oi;
+	obd_enqueue_update_f fa_upcall;
+	void		*fa_cookie;
+};
+
+struct osc_enqueue_args {
+	struct obd_export	*oa_exp;
+	__u64		    *oa_flags;
+	obd_enqueue_update_f      oa_upcall;
+	void		     *oa_cookie;
+	struct ost_lvb	   *oa_lvb;
+	struct lustre_handle     *oa_lockh;
+	struct ldlm_enqueue_info *oa_ei;
+	unsigned int	      oa_agl:1;
+};
+
+#if 0
+int osc_extent_blocking_cb(struct ldlm_lock *lock,
+			   struct ldlm_lock_desc *new, void *data,
+			   int flag);
+#endif
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_support.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_support.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/include/obd_support.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/include/obd_support.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,851 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#ifndef _OBD_SUPPORT
+#define _OBD_SUPPORT
+
+#include <linux/libcfs/libcfs.h>
+#include <lvfs.h>
+#include <lprocfs_status.h>
+
+#include <linux/obd_support.h>
+
+/* global variables */
+extern struct lprocfs_stats *obd_memory;
+enum {
+	OBD_MEMORY_STAT = 0,
+	OBD_MEMORY_PAGES_STAT = 1,
+	OBD_STATS_NUM,
+};
+
+extern unsigned int obd_debug_peer_on_timeout;
+extern unsigned int obd_dump_on_timeout;
+extern unsigned int obd_dump_on_eviction;
+/* obd_timeout should only be used for recovery, not for
+   networking / disk / timings affected by load (use Adaptive Timeouts) */
+extern unsigned int obd_timeout;	  /* seconds */
+extern unsigned int ldlm_timeout;	 /* seconds */
+extern unsigned int obd_timeout_set;
+extern unsigned int ldlm_timeout_set;
+extern unsigned int at_min;
+extern unsigned int at_max;
+extern unsigned int at_history;
+extern int at_early_margin;
+extern int at_extra;
+extern unsigned int obd_sync_filter;
+extern unsigned int obd_max_dirty_pages;
+extern atomic_t obd_dirty_pages;
+extern atomic_t obd_dirty_transit_pages;
+extern unsigned int obd_alloc_fail_rate;
+extern char obd_jobid_var[];
+
+/* lvfs.c */
+int obd_alloc_fail(const void *ptr, const char *name, const char *type,
+		   size_t size, const char *file, int line);
+
+/* Some hash init argument constants */
+#define HASH_POOLS_BKT_BITS 3
+#define HASH_POOLS_CUR_BITS 3
+#define HASH_POOLS_MAX_BITS 7
+#define HASH_UUID_BKT_BITS 5
+#define HASH_UUID_CUR_BITS 7
+#define HASH_UUID_MAX_BITS 12
+#define HASH_NID_BKT_BITS 5
+#define HASH_NID_CUR_BITS 7
+#define HASH_NID_MAX_BITS 12
+#define HASH_NID_STATS_BKT_BITS 5
+#define HASH_NID_STATS_CUR_BITS 7
+#define HASH_NID_STATS_MAX_BITS 12
+#define HASH_LQE_BKT_BITS 5
+#define HASH_LQE_CUR_BITS 7
+#define HASH_LQE_MAX_BITS 12
+#define HASH_CONN_BKT_BITS 5
+#define HASH_CONN_CUR_BITS 5
+#define HASH_CONN_MAX_BITS 15
+#define HASH_EXP_LOCK_BKT_BITS  5
+#define HASH_EXP_LOCK_CUR_BITS  7
+#define HASH_EXP_LOCK_MAX_BITS  16
+#define HASH_CL_ENV_BKT_BITS    5
+#define HASH_CL_ENV_BITS	10
+#define HASH_JOB_STATS_BKT_BITS 5
+#define HASH_JOB_STATS_CUR_BITS 7
+#define HASH_JOB_STATS_MAX_BITS 12
+
+/* Timeout definitions */
+#define OBD_TIMEOUT_DEFAULT	     100
+#define LDLM_TIMEOUT_DEFAULT	    20
+#define MDS_LDLM_TIMEOUT_DEFAULT	6
+/* Time to wait for all clients to reconnect during recovery (hard limit) */
+#define OBD_RECOVERY_TIME_HARD	  (obd_timeout * 9)
+/* Time to wait for all clients to reconnect during recovery (soft limit) */
+/* Should be very conservative; must catch the first reconnect after reboot */
+#define OBD_RECOVERY_TIME_SOFT	  (obd_timeout * 3)
+/* Change recovery-small 26b time if you change this */
+#define PING_INTERVAL max(obd_timeout / 4, 1U)
+/* a bit more than maximal journal commit time in seconds */
+#define PING_INTERVAL_SHORT min(PING_INTERVAL, 7U)
+/* Client may skip 1 ping; we must wait at least 2.5. But for multiple
+ * failover targets the client only pings one server at a time, and pings
+ * can be lost on a loaded network. Since eviction has serious consequences,
+ * and there's no urgent need to evict a client just because it's idle, we
+ * should be very conservative here. */
+#define PING_EVICT_TIMEOUT (PING_INTERVAL * 6)
+#define DISK_TIMEOUT 50	  /* Beyond this we warn about disk speed */
+#define CONNECTION_SWITCH_MIN 5U /* Connection switching rate limiter */
+ /* Max connect interval for nonresponsive servers; ~50s to avoid building up
+    connect requests in the LND queues, but within obd_timeout so we don't
+    miss the recovery window */
+#define CONNECTION_SWITCH_MAX min(50U, max(CONNECTION_SWITCH_MIN,obd_timeout))
+#define CONNECTION_SWITCH_INC 5  /* Connection timeout backoff */
+/* In general this should be low to have quick detection of a system
+   running on a backup server. (If it's too low, import_select_connection
+   will increase the timeout anyhow.)  */
+#define INITIAL_CONNECT_TIMEOUT max(CONNECTION_SWITCH_MIN,obd_timeout/20)
+/* The max delay between connects is SWITCH_MAX + SWITCH_INC + INITIAL */
+#define RECONNECT_DELAY_MAX (CONNECTION_SWITCH_MAX + CONNECTION_SWITCH_INC + \
+			     INITIAL_CONNECT_TIMEOUT)
+/* The min time a target should wait for clients to reconnect in recovery */
+#define OBD_RECOVERY_TIME_MIN    (2*RECONNECT_DELAY_MAX)
+#define OBD_IR_FACTOR_MIN	 1
+#define OBD_IR_FACTOR_MAX	 10
+#define OBD_IR_FACTOR_DEFAULT    (OBD_IR_FACTOR_MAX/2)
+/* default timeout for the MGS to become IR_FULL */
+#define OBD_IR_MGS_TIMEOUT       (4*obd_timeout)
+#define LONG_UNLINK 300	  /* Unlink should happen before now */
+
+/**
+ * Time interval of shrink, if the client is "idle" more than this interval,
+ * then the ll_grant thread will return the requested grant space to filter
+ */
+#define GRANT_SHRINK_INTERVAL	    1200/*20 minutes*/
+
+#define OBD_FAIL_MDS		     0x100
+#define OBD_FAIL_MDS_HANDLE_UNPACK       0x101
+#define OBD_FAIL_MDS_GETATTR_NET	 0x102
+#define OBD_FAIL_MDS_GETATTR_PACK	0x103
+#define OBD_FAIL_MDS_READPAGE_NET	0x104
+#define OBD_FAIL_MDS_READPAGE_PACK       0x105
+#define OBD_FAIL_MDS_SENDPAGE	    0x106
+#define OBD_FAIL_MDS_REINT_NET	   0x107
+#define OBD_FAIL_MDS_REINT_UNPACK	0x108
+#define OBD_FAIL_MDS_REINT_SETATTR       0x109
+#define OBD_FAIL_MDS_REINT_SETATTR_WRITE 0x10a
+#define OBD_FAIL_MDS_REINT_CREATE	0x10b
+#define OBD_FAIL_MDS_REINT_CREATE_WRITE  0x10c
+#define OBD_FAIL_MDS_REINT_UNLINK	0x10d
+#define OBD_FAIL_MDS_REINT_UNLINK_WRITE  0x10e
+#define OBD_FAIL_MDS_REINT_LINK	  0x10f
+#define OBD_FAIL_MDS_REINT_LINK_WRITE    0x110
+#define OBD_FAIL_MDS_REINT_RENAME	0x111
+#define OBD_FAIL_MDS_REINT_RENAME_WRITE  0x112
+#define OBD_FAIL_MDS_OPEN_NET	    0x113
+#define OBD_FAIL_MDS_OPEN_PACK	   0x114
+#define OBD_FAIL_MDS_CLOSE_NET	   0x115
+#define OBD_FAIL_MDS_CLOSE_PACK	  0x116
+#define OBD_FAIL_MDS_CONNECT_NET	 0x117
+#define OBD_FAIL_MDS_CONNECT_PACK	0x118
+#define OBD_FAIL_MDS_REINT_NET_REP       0x119
+#define OBD_FAIL_MDS_DISCONNECT_NET      0x11a
+#define OBD_FAIL_MDS_GETSTATUS_NET       0x11b
+#define OBD_FAIL_MDS_GETSTATUS_PACK      0x11c
+#define OBD_FAIL_MDS_STATFS_PACK	 0x11d
+#define OBD_FAIL_MDS_STATFS_NET	  0x11e
+#define OBD_FAIL_MDS_GETATTR_NAME_NET    0x11f
+#define OBD_FAIL_MDS_PIN_NET	     0x120
+#define OBD_FAIL_MDS_UNPIN_NET	   0x121
+#define OBD_FAIL_MDS_ALL_REPLY_NET       0x122
+#define OBD_FAIL_MDS_ALL_REQUEST_NET     0x123
+#define OBD_FAIL_MDS_SYNC_NET	    0x124
+#define OBD_FAIL_MDS_SYNC_PACK	   0x125
+#define OBD_FAIL_MDS_DONE_WRITING_NET    0x126
+#define OBD_FAIL_MDS_DONE_WRITING_PACK   0x127
+#define OBD_FAIL_MDS_ALLOC_OBDO	  0x128
+#define OBD_FAIL_MDS_PAUSE_OPEN	  0x129
+#define OBD_FAIL_MDS_STATFS_LCW_SLEEP    0x12a
+#define OBD_FAIL_MDS_OPEN_CREATE	 0x12b
+#define OBD_FAIL_MDS_OST_SETATTR	 0x12c
+#define OBD_FAIL_MDS_QUOTACHECK_NET      0x12d
+#define OBD_FAIL_MDS_QUOTACTL_NET	0x12e
+#define OBD_FAIL_MDS_CLIENT_ADD	  0x12f
+#define OBD_FAIL_MDS_GETXATTR_NET	0x130
+#define OBD_FAIL_MDS_GETXATTR_PACK       0x131
+#define OBD_FAIL_MDS_SETXATTR_NET	0x132
+#define OBD_FAIL_MDS_SETXATTR	    0x133
+#define OBD_FAIL_MDS_SETXATTR_WRITE      0x134
+#define OBD_FAIL_MDS_FS_SETUP	    0x135
+#define OBD_FAIL_MDS_RESEND	      0x136
+#define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
+#define OBD_FAIL_MDS_LOV_SYNC_RACE       0x138
+#define OBD_FAIL_MDS_OSC_PRECREATE       0x139
+#define OBD_FAIL_MDS_LLOG_SYNC_TIMEOUT   0x13a
+#define OBD_FAIL_MDS_CLOSE_NET_REP       0x13b
+#define OBD_FAIL_MDS_BLOCK_QUOTA_REQ     0x13c
+#define OBD_FAIL_MDS_DROP_QUOTA_REQ      0x13d
+#define OBD_FAIL_MDS_REMOVE_COMMON_EA    0x13e
+#define OBD_FAIL_MDS_ALLOW_COMMON_EA_SETTING   0x13f
+#define OBD_FAIL_MDS_FAIL_LOV_LOG_ADD    0x140
+#define OBD_FAIL_MDS_LOV_PREP_CREATE     0x141
+#define OBD_FAIL_MDS_REINT_DELAY	 0x142
+#define OBD_FAIL_MDS_READLINK_EPROTO     0x143
+#define OBD_FAIL_MDS_OPEN_WAIT_CREATE    0x144
+#define OBD_FAIL_MDS_PDO_LOCK	    0x145
+#define OBD_FAIL_MDS_PDO_LOCK2	   0x146
+#define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
+#define OBD_FAIL_MDS_NEGATIVE_POSITIVE	 0x148
+#define OBD_FAIL_MDS_HSM_STATE_GET_NET		0x149
+#define OBD_FAIL_MDS_HSM_STATE_SET_NET		0x14a
+#define OBD_FAIL_MDS_HSM_PROGRESS_NET		0x14b
+#define OBD_FAIL_MDS_HSM_REQUEST_NET		0x14c
+#define OBD_FAIL_MDS_HSM_CT_REGISTER_NET	0x14d
+#define OBD_FAIL_MDS_HSM_CT_UNREGISTER_NET	0x14e
+#define OBD_FAIL_MDS_SWAP_LAYOUTS_NET		0x14f
+#define OBD_FAIL_MDS_HSM_ACTION_NET		0x150
+#define OBD_FAIL_MDS_CHANGELOG_INIT		0x151
+
+/* layout lock */
+#define OBD_FAIL_MDS_NO_LL_GETATTR	 0x170
+#define OBD_FAIL_MDS_NO_LL_OPEN		 0x171
+#define OBD_FAIL_MDS_LL_BLOCK		 0x172
+
+/* CMD */
+#define OBD_FAIL_MDS_IS_SUBDIR_NET       0x180
+#define OBD_FAIL_MDS_IS_SUBDIR_PACK      0x181
+#define OBD_FAIL_MDS_SET_INFO_NET	0x182
+#define OBD_FAIL_MDS_WRITEPAGE_NET       0x183
+#define OBD_FAIL_MDS_WRITEPAGE_PACK      0x184
+#define OBD_FAIL_MDS_RECOVERY_ACCEPTS_GAPS 0x185
+#define OBD_FAIL_MDS_GET_INFO_NET	0x186
+#define OBD_FAIL_MDS_DQACQ_NET	   0x187
+
+/* OI scrub */
+#define OBD_FAIL_OSD_SCRUB_DELAY			0x190
+#define OBD_FAIL_OSD_SCRUB_CRASH			0x191
+#define OBD_FAIL_OSD_SCRUB_FATAL			0x192
+#define OBD_FAIL_OSD_FID_MAPPING			0x193
+#define OBD_FAIL_OSD_LMA_INCOMPAT			0x194
+
+#define OBD_FAIL_OST		     0x200
+#define OBD_FAIL_OST_CONNECT_NET	 0x201
+#define OBD_FAIL_OST_DISCONNECT_NET      0x202
+#define OBD_FAIL_OST_GET_INFO_NET	0x203
+#define OBD_FAIL_OST_CREATE_NET	  0x204
+#define OBD_FAIL_OST_DESTROY_NET	 0x205
+#define OBD_FAIL_OST_GETATTR_NET	 0x206
+#define OBD_FAIL_OST_SETATTR_NET	 0x207
+#define OBD_FAIL_OST_OPEN_NET	    0x208
+#define OBD_FAIL_OST_CLOSE_NET	   0x209
+#define OBD_FAIL_OST_BRW_NET	     0x20a
+#define OBD_FAIL_OST_PUNCH_NET	   0x20b
+#define OBD_FAIL_OST_STATFS_NET	  0x20c
+#define OBD_FAIL_OST_HANDLE_UNPACK       0x20d
+#define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
+#define OBD_FAIL_OST_BRW_READ_BULK       0x20f
+#define OBD_FAIL_OST_SYNC_NET	    0x210
+#define OBD_FAIL_OST_ALL_REPLY_NET       0x211
+#define OBD_FAIL_OST_ALL_REQUEST_NET     0x212
+#define OBD_FAIL_OST_LDLM_REPLY_NET      0x213
+#define OBD_FAIL_OST_BRW_PAUSE_BULK      0x214
+#define OBD_FAIL_OST_ENOSPC	      0x215
+#define OBD_FAIL_OST_EROFS	       0x216
+#define OBD_FAIL_OST_ENOENT	      0x217
+#define OBD_FAIL_OST_QUOTACHECK_NET      0x218
+#define OBD_FAIL_OST_QUOTACTL_NET	0x219
+#define OBD_FAIL_OST_CHECKSUM_RECEIVE    0x21a
+#define OBD_FAIL_OST_CHECKSUM_SEND       0x21b
+#define OBD_FAIL_OST_BRW_SIZE	    0x21c
+#define OBD_FAIL_OST_DROP_REQ	    0x21d
+#define OBD_FAIL_OST_SETATTR_CREDITS     0x21e
+#define OBD_FAIL_OST_HOLD_WRITE_RPC      0x21f
+#define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
+#define OBD_FAIL_OST_LLOG_RECOVERY_TIMEOUT 0x221
+#define OBD_FAIL_OST_CANCEL_COOKIE_TIMEOUT 0x222
+#define OBD_FAIL_OST_PAUSE_CREATE	0x223
+#define OBD_FAIL_OST_BRW_PAUSE_PACK      0x224
+#define OBD_FAIL_OST_CONNECT_NET2	0x225
+#define OBD_FAIL_OST_NOMEM	       0x226
+#define OBD_FAIL_OST_BRW_PAUSE_BULK2     0x227
+#define OBD_FAIL_OST_MAPBLK_ENOSPC       0x228
+#define OBD_FAIL_OST_ENOINO	      0x229
+#define OBD_FAIL_OST_DQACQ_NET	   0x230
+#define OBD_FAIL_OST_STATFS_EINPROGRESS  0x231
+
+#define OBD_FAIL_LDLM		    0x300
+#define OBD_FAIL_LDLM_NAMESPACE_NEW      0x301
+#define OBD_FAIL_LDLM_ENQUEUE_NET			0x302
+#define OBD_FAIL_LDLM_CONVERT_NET			0x303
+#define OBD_FAIL_LDLM_CANCEL_NET			0x304
+#define OBD_FAIL_LDLM_BL_CALLBACK_NET			0x305
+#define OBD_FAIL_LDLM_CP_CALLBACK_NET			0x306
+#define OBD_FAIL_LDLM_GL_CALLBACK_NET			0x307
+#define OBD_FAIL_LDLM_ENQUEUE_EXTENT_ERR 0x308
+#define OBD_FAIL_LDLM_ENQUEUE_INTENT_ERR 0x309
+#define OBD_FAIL_LDLM_CREATE_RESOURCE    0x30a
+#define OBD_FAIL_LDLM_ENQUEUE_BLOCKED    0x30b
+#define OBD_FAIL_LDLM_REPLY	      0x30c
+#define OBD_FAIL_LDLM_RECOV_CLIENTS      0x30d
+#define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
+#define OBD_FAIL_LDLM_GLIMPSE	    0x30f
+#define OBD_FAIL_LDLM_CANCEL_RACE	0x310
+#define OBD_FAIL_LDLM_CANCEL_EVICT_RACE  0x311
+#define OBD_FAIL_LDLM_PAUSE_CANCEL       0x312
+#define OBD_FAIL_LDLM_CLOSE_THREAD       0x313
+#define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE  0x314
+#define OBD_FAIL_LDLM_CP_CB_WAIT	 0x315
+#define OBD_FAIL_LDLM_OST_FAIL_RACE      0x316
+#define OBD_FAIL_LDLM_INTR_CP_AST	0x317
+#define OBD_FAIL_LDLM_CP_BL_RACE	 0x318
+#define OBD_FAIL_LDLM_NEW_LOCK	   0x319
+#define OBD_FAIL_LDLM_AGL_DELAY	  0x31a
+#define OBD_FAIL_LDLM_AGL_NOLOCK	 0x31b
+#define OBD_FAIL_LDLM_OST_LVB		 0x31c
+
+/* LOCKLESS IO */
+#define OBD_FAIL_LDLM_SET_CONTENTION     0x385
+
+#define OBD_FAIL_OSC		     0x400
+#define OBD_FAIL_OSC_BRW_READ_BULK       0x401
+#define OBD_FAIL_OSC_BRW_WRITE_BULK      0x402
+#define OBD_FAIL_OSC_LOCK_BL_AST	 0x403
+#define OBD_FAIL_OSC_LOCK_CP_AST	 0x404
+#define OBD_FAIL_OSC_MATCH	       0x405
+#define OBD_FAIL_OSC_BRW_PREP_REQ	0x406
+#define OBD_FAIL_OSC_SHUTDOWN	    0x407
+#define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
+#define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
+#define OBD_FAIL_OSC_BRW_PREP_REQ2       0x40a
+#define OBD_FAIL_OSC_CONNECT_CKSUM       0x40b
+#define OBD_FAIL_OSC_CKSUM_ADLER_ONLY    0x40c
+#define OBD_FAIL_OSC_DIO_PAUSE	   0x40d
+#define OBD_FAIL_OSC_OBJECT_CONTENTION   0x40e
+#define OBD_FAIL_OSC_CP_CANCEL_RACE      0x40f
+#define OBD_FAIL_OSC_CP_ENQ_RACE	 0x410
+#define OBD_FAIL_OSC_NO_GRANT	    0x411
+#define OBD_FAIL_OSC_DELAY_SETTIME	 0x412
+
+#define OBD_FAIL_PTLRPC		  0x500
+#define OBD_FAIL_PTLRPC_ACK	      0x501
+#define OBD_FAIL_PTLRPC_RQBD	     0x502
+#define OBD_FAIL_PTLRPC_BULK_GET_NET     0x503
+#define OBD_FAIL_PTLRPC_BULK_PUT_NET     0x504
+#define OBD_FAIL_PTLRPC_DROP_RPC	 0x505
+#define OBD_FAIL_PTLRPC_DELAY_SEND       0x506
+#define OBD_FAIL_PTLRPC_DELAY_RECOV      0x507
+#define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
+#define OBD_FAIL_PTLRPC_PAUSE_REQ	0x50a
+#define OBD_FAIL_PTLRPC_PAUSE_REP	0x50c
+#define OBD_FAIL_PTLRPC_IMP_DEACTIVE     0x50d
+#define OBD_FAIL_PTLRPC_DUMP_LOG	 0x50e
+#define OBD_FAIL_PTLRPC_LONG_REPL_UNLINK 0x50f
+#define OBD_FAIL_PTLRPC_LONG_BULK_UNLINK 0x510
+#define OBD_FAIL_PTLRPC_HPREQ_TIMEOUT    0x511
+#define OBD_FAIL_PTLRPC_HPREQ_NOTIMEOUT  0x512
+#define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
+#define OBD_FAIL_PTLRPC_FINISH_REPLAY    0x514
+#define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2  0x515
+#define OBD_FAIL_PTLRPC_DELAY_IMP_FULL   0x516
+#define OBD_FAIL_PTLRPC_CANCEL_RESEND    0x517
+
+#define OBD_FAIL_OBD_PING_NET	    0x600
+#define OBD_FAIL_OBD_LOG_CANCEL_NET      0x601
+#define OBD_FAIL_OBD_LOGD_NET	    0x602
+#define OBD_FAIL_OBD_QC_CALLBACK_NET     0x603
+#define OBD_FAIL_OBD_DQACQ	       0x604
+#define OBD_FAIL_OBD_LLOG_SETUP	  0x605
+#define OBD_FAIL_OBD_LOG_CANCEL_REP      0x606
+#define OBD_FAIL_OBD_IDX_READ_NET	0x607
+#define OBD_FAIL_OBD_IDX_READ_BREAK	 0x608
+#define OBD_FAIL_OBD_NO_LRU		 0x609
+
+#define OBD_FAIL_TGT_REPLY_NET	   0x700
+#define OBD_FAIL_TGT_CONN_RACE	   0x701
+#define OBD_FAIL_TGT_FORCE_RECONNECT     0x702
+#define OBD_FAIL_TGT_DELAY_CONNECT       0x703
+#define OBD_FAIL_TGT_DELAY_RECONNECT     0x704
+#define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
+#define OBD_FAIL_TGT_TOOMANY_THREADS     0x706
+#define OBD_FAIL_TGT_REPLAY_DROP	 0x707
+#define OBD_FAIL_TGT_FAKE_EXP	    0x708
+#define OBD_FAIL_TGT_REPLAY_DELAY	0x709
+#define OBD_FAIL_TGT_LAST_REPLAY	 0x710
+#define OBD_FAIL_TGT_CLIENT_ADD	  0x711
+#define OBD_FAIL_TGT_RCVG_FLAG	   0x712
+
+#define OBD_FAIL_MDC_REVALIDATE_PAUSE    0x800
+#define OBD_FAIL_MDC_ENQUEUE_PAUSE       0x801
+#define OBD_FAIL_MDC_OLD_EXT_FLAGS       0x802
+#define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
+#define OBD_FAIL_MDC_RPCS_SEM		 0x804
+#define OBD_FAIL_MDC_LIGHTWEIGHT	 0x805
+
+#define OBD_FAIL_MGS		     0x900
+#define OBD_FAIL_MGS_ALL_REQUEST_NET     0x901
+#define OBD_FAIL_MGS_ALL_REPLY_NET       0x902
+#define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
+#define OBD_FAIL_MGS_PAUSE_REQ	   0x904
+#define OBD_FAIL_MGS_PAUSE_TARGET_REG    0x905
+
+#define OBD_FAIL_QUOTA_DQACQ_NET			0xA01
+#define OBD_FAIL_QUOTA_EDQUOT	    0xA02
+#define OBD_FAIL_QUOTA_DELAY_REINT       0xA03
+#define OBD_FAIL_QUOTA_RECOVERABLE_ERR   0xA04
+
+#define OBD_FAIL_LPROC_REMOVE	    0xB00
+
+#define OBD_FAIL_GENERAL_ALLOC	   0xC00
+
+#define OBD_FAIL_SEQ		     0x1000
+#define OBD_FAIL_SEQ_QUERY_NET	   0x1001
+#define OBD_FAIL_SEQ_EXHAUST		 0x1002
+
+#define OBD_FAIL_FLD		     0x1100
+#define OBD_FAIL_FLD_QUERY_NET	   0x1101
+
+#define OBD_FAIL_SEC_CTX		 0x1200
+#define OBD_FAIL_SEC_CTX_INIT_NET	0x1201
+#define OBD_FAIL_SEC_CTX_INIT_CONT_NET   0x1202
+#define OBD_FAIL_SEC_CTX_FINI_NET	0x1203
+#define OBD_FAIL_SEC_CTX_HDL_PAUSE       0x1204
+
+#define OBD_FAIL_LLOG			       0x1300
+#define OBD_FAIL_LLOG_ORIGIN_CONNECT_NET	    0x1301
+#define OBD_FAIL_LLOG_ORIGIN_HANDLE_CREATE_NET      0x1302
+#define OBD_FAIL_LLOG_ORIGIN_HANDLE_DESTROY_NET     0x1303
+#define OBD_FAIL_LLOG_ORIGIN_HANDLE_READ_HEADER_NET 0x1304
+#define OBD_FAIL_LLOG_ORIGIN_HANDLE_NEXT_BLOCK_NET  0x1305
+#define OBD_FAIL_LLOG_ORIGIN_HANDLE_PREV_BLOCK_NET  0x1306
+#define OBD_FAIL_LLOG_ORIGIN_HANDLE_WRITE_REC_NET   0x1307
+#define OBD_FAIL_LLOG_ORIGIN_HANDLE_CLOSE_NET       0x1308
+#define OBD_FAIL_LLOG_CATINFO_NET		   0x1309
+#define OBD_FAIL_MDS_SYNC_CAPA_SL		   0x1310
+#define OBD_FAIL_SEQ_ALLOC			  0x1311
+
+#define OBD_FAIL_LLITE			      0x1400
+#define OBD_FAIL_LLITE_FAULT_TRUNC_RACE	     0x1401
+#define OBD_FAIL_LOCK_STATE_WAIT_INTR	       0x1402
+#define OBD_FAIL_LOV_INIT			    0x1403
+#define OBD_FAIL_GLIMPSE_DELAY			    0x1404
+
+#define OBD_FAIL_FID_INDIR	0x1501
+#define OBD_FAIL_FID_INLMA	0x1502
+#define OBD_FAIL_FID_IGIF	0x1504
+#define OBD_FAIL_FID_LOOKUP	0x1505
+#define OBD_FAIL_FID_NOLMA	0x1506
+
+/* LFSCK */
+#define OBD_FAIL_LFSCK_DELAY1		0x1600
+#define OBD_FAIL_LFSCK_DELAY2		0x1601
+#define OBD_FAIL_LFSCK_DELAY3		0x1602
+#define OBD_FAIL_LFSCK_LINKEA_CRASH	0x1603
+#define OBD_FAIL_LFSCK_LINKEA_MORE	0x1604
+#define OBD_FAIL_LFSCK_FATAL1		0x1608
+#define OBD_FAIL_LFSCK_FATAL2		0x1609
+#define OBD_FAIL_LFSCK_CRASH		0x160a
+#define OBD_FAIL_LFSCK_NO_AUTO		0x160b
+#define OBD_FAIL_LFSCK_NO_DOUBLESCAN	0x160c
+
+/* UPDATE */
+#define OBD_FAIL_UPDATE_OBJ_NET			0x1700
+#define OBD_FAIL_UPDATE_OBJ_NET_REP		0x1701
+
+
+/* Assign references to moved code to reduce code changes */
+#define OBD_FAIL_PRECHECK(id)		   CFS_FAIL_PRECHECK(id)
+#define OBD_FAIL_CHECK(id)		      CFS_FAIL_CHECK(id)
+#define OBD_FAIL_CHECK_VALUE(id, value)	 CFS_FAIL_CHECK_VALUE(id, value)
+#define OBD_FAIL_CHECK_ORSET(id, value)	 CFS_FAIL_CHECK_ORSET(id, value)
+#define OBD_FAIL_CHECK_RESET(id, value)	 CFS_FAIL_CHECK_RESET(id, value)
+#define OBD_FAIL_RETURN(id, ret)		CFS_FAIL_RETURN(id, ret)
+#define OBD_FAIL_TIMEOUT(id, secs)	      CFS_FAIL_TIMEOUT(id, secs)
+#define OBD_FAIL_TIMEOUT_MS(id, ms)	     CFS_FAIL_TIMEOUT_MS(id, ms)
+#define OBD_FAIL_TIMEOUT_ORSET(id, value, secs) CFS_FAIL_TIMEOUT_ORSET(id, value, secs)
+#define OBD_RACE(id)			    CFS_RACE(id)
+#define OBD_FAIL_ONCE			   CFS_FAIL_ONCE
+#define OBD_FAILED			      CFS_FAILED
+
+extern atomic_t libcfs_kmemory;
+
+#ifdef LPROCFS
+#define obd_memory_add(size)						  \
+	lprocfs_counter_add(obd_memory, OBD_MEMORY_STAT, (long)(size))
+#define obd_memory_sub(size)						  \
+	lprocfs_counter_sub(obd_memory, OBD_MEMORY_STAT, (long)(size))
+#define obd_memory_sum()						      \
+	lprocfs_stats_collector(obd_memory, OBD_MEMORY_STAT,		  \
+				LPROCFS_FIELDS_FLAGS_SUM)
+#define obd_pages_add(order)						  \
+	lprocfs_counter_add(obd_memory, OBD_MEMORY_PAGES_STAT,		\
+			    (long)(1 << (order)))
+#define obd_pages_sub(order)						  \
+	lprocfs_counter_sub(obd_memory, OBD_MEMORY_PAGES_STAT,		\
+			    (long)(1 << (order)))
+#define obd_pages_sum()						       \
+	lprocfs_stats_collector(obd_memory, OBD_MEMORY_PAGES_STAT,	    \
+				LPROCFS_FIELDS_FLAGS_SUM)
+
+extern void obd_update_maxusage(void);
+extern __u64 obd_memory_max(void);
+extern __u64 obd_pages_max(void);
+
+#else
+
+extern __u64 obd_alloc;
+extern __u64 obd_pages;
+
+extern __u64 obd_max_alloc;
+extern __u64 obd_max_pages;
+
+static inline void obd_memory_add(long size)
+{
+	obd_alloc += size;
+	if (obd_alloc > obd_max_alloc)
+		obd_max_alloc = obd_alloc;
+}
+
+static inline void obd_memory_sub(long size)
+{
+	obd_alloc -= size;
+}
+
+static inline void obd_pages_add(int order)
+{
+	obd_pages += 1<< order;
+	if (obd_pages > obd_max_pages)
+		obd_max_pages = obd_pages;
+}
+
+static inline void obd_pages_sub(int order)
+{
+	obd_pages -= 1<< order;
+}
+
+#define obd_memory_sum() (obd_alloc)
+#define obd_pages_sum()  (obd_pages)
+
+#define obd_memory_max() (obd_max_alloc)
+#define obd_pages_max() (obd_max_pages)
+
+#endif
+
+#define OBD_DEBUG_MEMUSAGE (1)
+
+#if OBD_DEBUG_MEMUSAGE
+#define OBD_ALLOC_POST(ptr, size, name)				 \
+		obd_memory_add(size);				   \
+		CDEBUG(D_MALLOC, name " '" #ptr "': %d at %p.\n",       \
+		       (int)(size), ptr)
+
+#define OBD_FREE_PRE(ptr, size, name)				   \
+	LASSERT(ptr);						   \
+	obd_memory_sub(size);					   \
+	CDEBUG(D_MALLOC, name " '" #ptr "': %d at %p.\n",	       \
+	       (int)(size), ptr);				       \
+	POISON(ptr, 0x5a, size)
+
+#else /* !OBD_DEBUG_MEMUSAGE */
+
+#define OBD_ALLOC_POST(ptr, size, name) ((void)0)
+#define OBD_FREE_PRE(ptr, size, name)   ((void)0)
+
+#endif /* !OBD_DEBUG_MEMUSAGE */
+
+#define HAS_FAIL_ALLOC_FLAG OBD_FAIL_CHECK(OBD_FAIL_GENERAL_ALLOC)
+
+#define OBD_ALLOC_FAIL_BITS 24
+#define OBD_ALLOC_FAIL_MASK ((1 << OBD_ALLOC_FAIL_BITS) - 1)
+#define OBD_ALLOC_FAIL_MULT (OBD_ALLOC_FAIL_MASK / 100)
+
+#if defined(LUSTRE_UTILS) /* this version is for utils only */
+#define __OBD_MALLOC_VERBOSE(ptr, cptab, cpt, size, flags)		      \
+do {									      \
+	(ptr) = (cptab) == NULL ?					      \
+		kmalloc(size, flags) :				      \
+		kmalloc_node(size, flags, cfs_cpt_spread_node(cptab, cpt));   \
+	if (unlikely((ptr) == NULL)) {					\
+		CERROR("kmalloc of '" #ptr "' (%d bytes) failed at %s:%d\n",  \
+		       (int)(size), __FILE__, __LINE__);		      \
+	} else {							      \
+		memset(ptr, 0, size);					      \
+		CDEBUG(D_MALLOC, "kmalloced '" #ptr "': %d at %p\n",	      \
+		       (int)(size), ptr);				      \
+	}								      \
+} while (0)
+
+#else /* this version is for the kernel and liblustre */
+#define OBD_FREE_RTN0(ptr)						    \
+({									    \
+	kfree(ptr);							\
+	(ptr) = NULL;							 \
+	0;								    \
+})
+
+#define __OBD_MALLOC_VERBOSE(ptr, cptab, cpt, size, flags)		      \
+do {									      \
+	(ptr) = (cptab) == NULL ?					      \
+		kmalloc(size, flags | __GFP_ZERO) :			      \
+		kmalloc_node(size, flags | __GFP_ZERO,			      \
+			     cfs_cpt_spread_node(cptab, cpt));		      \
+	if (likely((ptr) != NULL &&					   \
+		   (!HAS_FAIL_ALLOC_FLAG || obd_alloc_fail_rate == 0 ||       \
+		    !obd_alloc_fail(ptr, #ptr, "km", size,		    \
+				    __FILE__, __LINE__) ||		    \
+		    OBD_FREE_RTN0(ptr)))){				    \
+		OBD_ALLOC_POST(ptr, size, "kmalloced");		       \
+	}								     \
+} while (0)
+#endif
+
+#define OBD_ALLOC_GFP(ptr, size, gfp_mask)				      \
+	__OBD_MALLOC_VERBOSE(ptr, NULL, 0, size, gfp_mask)
+
+#define OBD_ALLOC(ptr, size) OBD_ALLOC_GFP(ptr, size, __GFP_IO)
+#define OBD_ALLOC_WAIT(ptr, size) OBD_ALLOC_GFP(ptr, size, GFP_IOFS)
+#define OBD_ALLOC_PTR(ptr) OBD_ALLOC(ptr, sizeof *(ptr))
+#define OBD_ALLOC_PTR_WAIT(ptr) OBD_ALLOC_WAIT(ptr, sizeof *(ptr))
+
+#define OBD_CPT_ALLOC_GFP(ptr, cptab, cpt, size, gfp_mask)		      \
+	__OBD_MALLOC_VERBOSE(ptr, cptab, cpt, size, gfp_mask)
+
+#define OBD_CPT_ALLOC(ptr, cptab, cpt, size)				      \
+	OBD_CPT_ALLOC_GFP(ptr, cptab, cpt, size, __GFP_IO)
+
+#define OBD_CPT_ALLOC_PTR(ptr, cptab, cpt)				      \
+	OBD_CPT_ALLOC(ptr, cptab, cpt, sizeof *(ptr))
+
+# define __OBD_VMALLOC_VEROBSE(ptr, cptab, cpt, size)			      \
+do {									      \
+	(ptr) = cptab == NULL ?						      \
+		vzalloc(size) :						      \
+		vzalloc_node(size, cfs_cpt_spread_node(cptab, cpt));	      \
+	if (unlikely((ptr) == NULL)) {					\
+		CERROR("vmalloc of '" #ptr "' (%d bytes) failed\n",	   \
+		       (int)(size));					  \
+		CERROR(LPU64" total bytes allocated by Lustre, %d by LNET\n", \
+		       obd_memory_sum(), atomic_read(&libcfs_kmemory));   \
+	} else {							      \
+		OBD_ALLOC_POST(ptr, size, "vmalloced");		       \
+	}								     \
+} while(0)
+
+# define OBD_VMALLOC(ptr, size)						      \
+	 __OBD_VMALLOC_VEROBSE(ptr, NULL, 0, size)
+# define OBD_CPT_VMALLOC(ptr, cptab, cpt, size)				      \
+	 __OBD_VMALLOC_VEROBSE(ptr, cptab, cpt, size)
+
+
+/* Allocations above this size are considered too big and could not be done
+ * atomically.
+ *
+ * Be very careful when changing this value, especially when decreasing it,
+ * since vmalloc in Linux doesn't perform well on multi-cores system, calling
+ * vmalloc in critical path would hurt peformance badly. See LU-66.
+ */
+#define OBD_ALLOC_BIG (4 * PAGE_CACHE_SIZE)
+
+#define OBD_ALLOC_LARGE(ptr, size)					    \
+do {									  \
+	if (size > OBD_ALLOC_BIG)					     \
+		OBD_VMALLOC(ptr, size);				       \
+	else								  \
+		OBD_ALLOC(ptr, size);					 \
+} while (0)
+
+#define OBD_CPT_ALLOC_LARGE(ptr, cptab, cpt, size)			      \
+do {									      \
+	if (size > OBD_ALLOC_BIG)					      \
+		OBD_CPT_VMALLOC(ptr, cptab, cpt, size);			      \
+	else								      \
+		OBD_CPT_ALLOC(ptr, cptab, cpt, size);			      \
+} while (0)
+
+#define OBD_FREE_LARGE(ptr, size)					     \
+do {									  \
+	if (size > OBD_ALLOC_BIG)					     \
+		OBD_VFREE(ptr, size);					 \
+	else								  \
+		OBD_FREE(ptr, size);					  \
+} while (0)
+
+
+#ifdef CONFIG_DEBUG_SLAB
+#define POISON(ptr, c, s) do {} while (0)
+#define POISON_PTR(ptr)  ((void)0)
+#else
+#define POISON(ptr, c, s) memset(ptr, c, s)
+#define POISON_PTR(ptr)  (ptr) = (void *)0xdeadbeef
+#endif
+
+#ifdef POISON_BULK
+#define POISON_PAGE(page, val) do { memset(kmap(page), val, PAGE_CACHE_SIZE);   \
+				    kunmap(page); } while (0)
+#else
+#define POISON_PAGE(page, val) do { } while (0)
+#endif
+
+#define OBD_FREE(ptr, size)						   \
+do {									  \
+	OBD_FREE_PRE(ptr, size, "kfreed");				    \
+	kfree(ptr);							\
+	POISON_PTR(ptr);						      \
+} while(0)
+
+
+#define OBD_FREE_RCU(ptr, size, handle)					      \
+do {									      \
+	struct portals_handle *__h = (handle);				      \
+									      \
+	LASSERT(handle != NULL);					      \
+	__h->h_cookie = (unsigned long)(ptr);				      \
+	__h->h_size = (size);						      \
+	call_rcu(&__h->h_rcu, class_handle_free_cb);			      \
+	POISON_PTR(ptr);						      \
+} while(0)
+
+
+#define OBD_VFREE(ptr, size)				\
+	do {						\
+		OBD_FREE_PRE(ptr, size, "vfreed");	\
+		vfree(ptr);			\
+		POISON_PTR(ptr);			\
+	} while (0)
+
+/* we memset() the slab object to 0 when allocation succeeds, so DO NOT
+ * HAVE A CTOR THAT DOES ANYTHING.  its work will be cleared here.  we'd
+ * love to assert on that, but slab.c keeps kmem_cache_s all to itself. */
+#define OBD_SLAB_FREE_RTN0(ptr, slab)					 \
+({									    \
+	kmem_cache_free((slab), (ptr));				    \
+	(ptr) = NULL;							 \
+	0;								    \
+})
+
+#define __OBD_SLAB_ALLOC_VERBOSE(ptr, slab, cptab, cpt, size, type)	      \
+do {									      \
+	LASSERT(ergo((type) != GFP_ATOMIC, !in_interrupt()));	      \
+	(ptr) = (cptab) == NULL ?					      \
+		kmem_cache_alloc(slab, type | __GFP_ZERO) :		\
+		kmem_cache_alloc_node(slab, type | __GFP_ZERO,		\
+				      cfs_cpt_spread_node(cptab, cpt));	\
+	if (likely((ptr) != NULL &&					   \
+		   (!HAS_FAIL_ALLOC_FLAG || obd_alloc_fail_rate == 0 ||       \
+		    !obd_alloc_fail(ptr, #ptr, "slab-", size,		 \
+				    __FILE__, __LINE__) ||		    \
+		    OBD_SLAB_FREE_RTN0(ptr, slab)))) {			\
+		OBD_ALLOC_POST(ptr, size, "slab-alloced");		    \
+	}								     \
+} while(0)
+
+#define OBD_SLAB_ALLOC_GFP(ptr, slab, size, flags)			      \
+	__OBD_SLAB_ALLOC_VERBOSE(ptr, slab, NULL, 0, size, flags)
+#define OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, size, flags)	      \
+	__OBD_SLAB_ALLOC_VERBOSE(ptr, slab, cptab, cpt, size, flags)
+
+#define OBD_FREE_PTR(ptr) OBD_FREE(ptr, sizeof *(ptr))
+
+#define OBD_SLAB_FREE(ptr, slab, size)					\
+do {									  \
+	OBD_FREE_PRE(ptr, size, "slab-freed");				\
+	kmem_cache_free(slab, ptr);					\
+	POISON_PTR(ptr);						      \
+} while(0)
+
+#define OBD_SLAB_ALLOC(ptr, slab, size)					      \
+	OBD_SLAB_ALLOC_GFP(ptr, slab, size, __GFP_IO)
+
+#define OBD_SLAB_CPT_ALLOC(ptr, slab, cptab, cpt, size)			      \
+	OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, size, __GFP_IO)
+
+#define OBD_SLAB_ALLOC_PTR(ptr, slab)					      \
+	OBD_SLAB_ALLOC(ptr, slab, sizeof *(ptr))
+
+#define OBD_SLAB_CPT_ALLOC_PTR(ptr, slab, cptab, cpt)			      \
+	OBD_SLAB_CPT_ALLOC(ptr, slab, cptab, cpt, sizeof *(ptr))
+
+#define OBD_SLAB_ALLOC_PTR_GFP(ptr, slab, flags)			      \
+	OBD_SLAB_ALLOC_GFP(ptr, slab, sizeof *(ptr), flags)
+
+#define OBD_SLAB_CPT_ALLOC_PTR_GFP(ptr, slab, cptab, cpt, flags)		      \
+	OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, sizeof *(ptr), flags)
+
+#define OBD_SLAB_FREE_PTR(ptr, slab)					      \
+	OBD_SLAB_FREE((ptr), (slab), sizeof *(ptr))
+
+#define KEY_IS(str) \
+	(keylen >= (sizeof(str)-1) && memcmp(key, str, (sizeof(str)-1)) == 0)
+
+/* Wrapper for contiguous page frame allocation */
+#define __OBD_PAGE_ALLOC_VERBOSE(ptr, cptab, cpt, gfp_mask)		      \
+do {									      \
+	(ptr) = (cptab) == NULL ?					      \
+		alloc_page(gfp_mask) :				      \
+		alloc_pages_node(cfs_cpt_spread_node(cptab, cpt), gfp_mask, 0);\
+	if (unlikely((ptr) == NULL)) {					\
+		CERROR("alloc_pages of '" #ptr "' %d page(s) / "LPU64" bytes "\
+		       "failed\n", (int)1,				    \
+		       (__u64)(1 << PAGE_CACHE_SHIFT));			 \
+		CERROR(LPU64" total bytes and "LPU64" total pages "	   \
+		       "("LPU64" bytes) allocated by Lustre, "		\
+		       "%d total bytes by LNET\n",			    \
+		       obd_memory_sum(),				      \
+		       obd_pages_sum() << PAGE_CACHE_SHIFT,		     \
+		       obd_pages_sum(),				       \
+		       atomic_read(&libcfs_kmemory));		     \
+	} else {							      \
+		obd_pages_add(0);					     \
+		CDEBUG(D_MALLOC, "alloc_pages '" #ptr "': %d page(s) / "      \
+		       LPU64" bytes at %p.\n",				\
+		       (int)1,						\
+		       (__u64)(1 << PAGE_CACHE_SHIFT), ptr);		    \
+	}								     \
+} while (0)
+
+#define OBD_PAGE_ALLOC(ptr, gfp_mask)					      \
+	__OBD_PAGE_ALLOC_VERBOSE(ptr, NULL, 0, gfp_mask)
+#define OBD_PAGE_CPT_ALLOC(ptr, cptab, cpt, gfp_mask)			      \
+	__OBD_PAGE_ALLOC_VERBOSE(ptr, cptab, cpt, gfp_mask)
+
+#define OBD_PAGE_FREE(ptr)						    \
+do {									  \
+	LASSERT(ptr);							 \
+	obd_pages_sub(0);						     \
+	CDEBUG(D_MALLOC, "free_pages '" #ptr "': %d page(s) / "LPU64" bytes " \
+	       "at %p.\n",						    \
+	       (int)1, (__u64)(1 << PAGE_CACHE_SHIFT),			  \
+	       ptr);							  \
+	__free_page(ptr);						   \
+	(ptr) = (void *)0xdeadbeef;					   \
+} while (0)
+
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/Kconfig linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/Kconfig
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/Kconfig	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,51 @@
+config LUSTRE_FS
+	tristate "Lustre file system client support"
+	depends on STAGING && INET && BROKEN
+	select LNET
+	select CRYPTO
+	select CRYPTO_CRC32
+	select CRYPTO_CRC32_PCLMUL if X86
+	select CRYPTO_CRC32C
+	select CRYPTO_MD5
+	select CRYPTO_SHA1
+	select CRYPTO_SHA256
+	select CRYPTO_SHA512
+	help
+	  This option enables Lustre file system client support. Choose Y
+	  here if you want to access a Lustre file system cluster. To compile
+	  this file system support as a module, choose M here: the module will
+	  be called lustre.
+
+	  To mount Lustre file systems , you also need to install the user space
+	  mount.lustre and other user space commands which can be found in the
+	  lustre-client package, available from
+	  http://downloads.whamcloud.com/public/lustre/
+
+	  Lustre file system is the most popular cluster file system in high
+	  performance computing. Source code of both kernel space and user space
+	  Lustre components can also be found at
+	  http://git.whamcloud.com/?p=fs/lustre-release.git;a=summary
+
+	  If unsure, say N.
+
+	  See also http://wiki.lustre.org/
+
+config LUSTRE_OBD_MAX_IOCTL_BUFFER
+	int "Lustre obd max ioctl buffer bytes (default 8KB)"
+	depends on LUSTRE_FS
+	default 8192
+	help
+	  This option defines the maximum size of buffer in bytes that user space
+	  applications can pass to Lustre kernel module through ioctl interface.
+
+	  If unsure, use default.
+
+config LUSTRE_DEBUG_EXPENSIVE_CHECK
+	bool "Enable Lustre DEBUG checks"
+	depends on LUSTRE_FS
+	default false
+	help
+	  This option is mainly for debug purpose. It enables Lustre code to do
+	  expensive checks that may have a performance impact.
+
+	  Use with caution. If unsure, say N.
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/lclient/glimpse.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/lclient/glimpse.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/lclient/glimpse.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/lclient/glimpse.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,274 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * glimpse code shared between vvp and liblustre (and other Lustre clients in
+ * the future).
+ *
+ *   Author: Nikita Danilov <nikita.danilov@sun.com>
+ *   Author: Oleg Drokin <oleg.drokin@sun.com>
+ */
+
+#include <linux/libcfs/libcfs.h>
+#include <obd_class.h>
+#include <obd_support.h>
+#include <obd.h>
+
+# include <lustre_dlm.h>
+# include <lustre_lite.h>
+# include <lustre_mdc.h>
+# include <linux/pagemap.h>
+# include <linux/file.h>
+
+#include "cl_object.h"
+#include "lclient.h"
+# include "../llite/llite_internal.h"
+
+static const struct cl_lock_descr whole_file = {
+	.cld_start = 0,
+	.cld_end   = CL_PAGE_EOF,
+	.cld_mode  = CLM_READ
+};
+
+/*
+ * Check whether file has possible unwriten pages.
+ *
+ * \retval 1    file is mmap-ed or has dirty pages
+ *	 0    otherwise
+ */
+blkcnt_t dirty_cnt(struct inode *inode)
+{
+	blkcnt_t cnt = 0;
+	struct ccc_object *vob = cl_inode2ccc(inode);
+	void	      *results[1];
+
+	if (inode->i_mapping != NULL)
+		cnt += radix_tree_gang_lookup_tag(&inode->i_mapping->page_tree,
+						  results, 0, 1,
+						  PAGECACHE_TAG_DIRTY);
+	if (cnt == 0 && atomic_read(&vob->cob_mmap_cnt) > 0)
+		cnt = 1;
+
+	return (cnt > 0) ? 1 : 0;
+}
+
+int cl_glimpse_lock(const struct lu_env *env, struct cl_io *io,
+		    struct inode *inode, struct cl_object *clob, int agl)
+{
+	struct cl_lock_descr *descr = &ccc_env_info(env)->cti_descr;
+	struct cl_inode_info *lli   = cl_i2info(inode);
+	const struct lu_fid  *fid   = lu_object_fid(&clob->co_lu);
+	struct ccc_io	*cio   = ccc_env_io(env);
+	struct cl_lock       *lock;
+	int result;
+
+	ENTRY;
+	result = 0;
+	if (!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)) {
+		CDEBUG(D_DLMTRACE, "Glimpsing inode "DFID"\n", PFID(fid));
+		if (lli->lli_has_smd) {
+			/* NOTE: this looks like DLM lock request, but it may
+			 *       not be one. Due to CEF_ASYNC flag (translated
+			 *       to LDLM_FL_HAS_INTENT by osc), this is
+			 *       glimpse request, that won't revoke any
+			 *       conflicting DLM locks held. Instead,
+			 *       ll_glimpse_callback() will be called on each
+			 *       client holding a DLM lock against this file,
+			 *       and resulting size will be returned for each
+			 *       stripe. DLM lock on [0, EOF] is acquired only
+			 *       if there were no conflicting locks. If there
+			 *       were conflicting locks, enqueuing or waiting
+			 *       fails with -ENAVAIL, but valid inode
+			 *       attributes are returned anyway. */
+			*descr = whole_file;
+			descr->cld_obj   = clob;
+			descr->cld_mode  = CLM_PHANTOM;
+			descr->cld_enq_flags = CEF_ASYNC | CEF_MUST;
+			if (agl)
+				descr->cld_enq_flags |= CEF_AGL;
+			cio->cui_glimpse = 1;
+			/*
+			 * CEF_ASYNC is used because glimpse sub-locks cannot
+			 * deadlock (because they never conflict with other
+			 * locks) and, hence, can be enqueued out-of-order.
+			 *
+			 * CEF_MUST protects glimpse lock from conversion into
+			 * a lockless mode.
+			 */
+			lock = cl_lock_request(env, io, descr, "glimpse",
+					       current);
+			cio->cui_glimpse = 0;
+
+			if (lock == NULL)
+				RETURN(0);
+
+			if (IS_ERR(lock))
+				RETURN(PTR_ERR(lock));
+
+			LASSERT(agl == 0);
+			result = cl_wait(env, lock);
+			if (result == 0) {
+				cl_merge_lvb(env, inode);
+				if (cl_isize_read(inode) > 0 &&
+				    inode->i_blocks == 0) {
+					/*
+					 * LU-417: Add dirty pages block count
+					 * lest i_blocks reports 0, some "cp" or
+					 * "tar" may think it's a completely
+					 * sparse file and skip it.
+					 */
+					inode->i_blocks = dirty_cnt(inode);
+				}
+				cl_unuse(env, lock);
+			}
+			cl_lock_release(env, lock, "glimpse", current);
+		} else {
+			CDEBUG(D_DLMTRACE, "No objects for inode\n");
+			cl_merge_lvb(env, inode);
+		}
+	}
+
+	RETURN(result);
+}
+
+static int cl_io_get(struct inode *inode, struct lu_env **envout,
+		     struct cl_io **ioout, int *refcheck)
+{
+	struct lu_env	  *env;
+	struct cl_io	   *io;
+	struct cl_inode_info   *lli = cl_i2info(inode);
+	struct cl_object       *clob = lli->lli_clob;
+	int result;
+
+	if (S_ISREG(cl_inode_mode(inode))) {
+		env = cl_env_get(refcheck);
+		if (!IS_ERR(env)) {
+			io = ccc_env_thread_io(env);
+			io->ci_obj = clob;
+			*envout = env;
+			*ioout  = io;
+			result = +1;
+		} else
+			result = PTR_ERR(env);
+	} else
+		result = 0;
+	return result;
+}
+
+int cl_glimpse_size0(struct inode *inode, int agl)
+{
+	/*
+	 * We don't need ast_flags argument to cl_glimpse_size(), because
+	 * osc_lock_enqueue() takes care of the possible deadlock that said
+	 * argument was introduced to avoid.
+	 */
+	/*
+	 * XXX but note that ll_file_seek() passes LDLM_FL_BLOCK_NOWAIT to
+	 * cl_glimpse_size(), which doesn't make sense: glimpse locks are not
+	 * blocking anyway.
+	 */
+	struct lu_env	  *env = NULL;
+	struct cl_io	   *io  = NULL;
+	int		     result;
+	int		     refcheck;
+
+	ENTRY;
+
+	result = cl_io_get(inode, &env, &io, &refcheck);
+	if (result > 0) {
+	again:
+		io->ci_verify_layout = 1;
+		result = cl_io_init(env, io, CIT_MISC, io->ci_obj);
+		if (result > 0)
+			/*
+			 * nothing to do for this io. This currently happens
+			 * when stripe sub-object's are not yet created.
+			 */
+			result = io->ci_result;
+		else if (result == 0)
+			result = cl_glimpse_lock(env, io, inode, io->ci_obj,
+						 agl);
+
+		OBD_FAIL_TIMEOUT(OBD_FAIL_GLIMPSE_DELAY, 2);
+		cl_io_fini(env, io);
+		if (unlikely(io->ci_need_restart))
+			goto again;
+		cl_env_put(env, &refcheck);
+	}
+	RETURN(result);
+}
+
+int cl_local_size(struct inode *inode)
+{
+	struct lu_env	   *env = NULL;
+	struct cl_io	    *io  = NULL;
+	struct ccc_thread_info  *cti;
+	struct cl_object	*clob;
+	struct cl_lock_descr    *descr;
+	struct cl_lock	  *lock;
+	int		      result;
+	int		      refcheck;
+
+	ENTRY;
+
+	if (!cl_i2info(inode)->lli_has_smd)
+		RETURN(0);
+
+	result = cl_io_get(inode, &env, &io, &refcheck);
+	if (result <= 0)
+		RETURN(result);
+
+	clob = io->ci_obj;
+	result = cl_io_init(env, io, CIT_MISC, clob);
+	if (result > 0)
+		result = io->ci_result;
+	else if (result == 0) {
+		cti = ccc_env_info(env);
+		descr = &cti->cti_descr;
+
+		*descr = whole_file;
+		descr->cld_obj = clob;
+		lock = cl_lock_peek(env, io, descr, "localsize", current);
+		if (lock != NULL) {
+			cl_merge_lvb(env, inode);
+			cl_unuse(env, lock);
+			cl_lock_release(env, lock, "localsize", current);
+			result = 0;
+		} else
+			result = -ENODATA;
+	}
+	cl_io_fini(env, io);
+	cl_env_put(env, &refcheck);
+	RETURN(result);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/lclient/lcommon_cl.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/lclient/lcommon_cl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/lclient/lcommon_cl.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1325 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * cl code shared between vvp and liblustre (and other Lustre clients in the
+ * future).
+ *
+ *   Author: Nikita Danilov <nikita.danilov@sun.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_LLITE
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/fs.h>
+# include <linux/sched.h>
+# include <linux/mm.h>
+# include <linux/quotaops.h>
+# include <linux/highmem.h>
+# include <linux/pagemap.h>
+# include <linux/rbtree.h>
+
+#include <obd.h>
+#include <obd_support.h>
+#include <lustre_fid.h>
+#include <lustre_lite.h>
+#include <lustre_dlm.h>
+#include <lustre_ver.h>
+#include <lustre_mdc.h>
+#include <cl_object.h>
+
+#include <lclient.h>
+
+#include "../llite/llite_internal.h"
+
+const struct cl_req_operations ccc_req_ops;
+
+/*
+ * ccc_ prefix stands for "Common Client Code".
+ */
+
+static struct kmem_cache *ccc_lock_kmem;
+static struct kmem_cache *ccc_object_kmem;
+static struct kmem_cache *ccc_thread_kmem;
+static struct kmem_cache *ccc_session_kmem;
+static struct kmem_cache *ccc_req_kmem;
+
+static struct lu_kmem_descr ccc_caches[] = {
+	{
+		.ckd_cache = &ccc_lock_kmem,
+		.ckd_name  = "ccc_lock_kmem",
+		.ckd_size  = sizeof (struct ccc_lock)
+	},
+	{
+		.ckd_cache = &ccc_object_kmem,
+		.ckd_name  = "ccc_object_kmem",
+		.ckd_size  = sizeof (struct ccc_object)
+	},
+	{
+		.ckd_cache = &ccc_thread_kmem,
+		.ckd_name  = "ccc_thread_kmem",
+		.ckd_size  = sizeof (struct ccc_thread_info),
+	},
+	{
+		.ckd_cache = &ccc_session_kmem,
+		.ckd_name  = "ccc_session_kmem",
+		.ckd_size  = sizeof (struct ccc_session)
+	},
+	{
+		.ckd_cache = &ccc_req_kmem,
+		.ckd_name  = "ccc_req_kmem",
+		.ckd_size  = sizeof (struct ccc_req)
+	},
+	{
+		.ckd_cache = NULL
+	}
+};
+
+/*****************************************************************************
+ *
+ * Vvp device and device type functions.
+ *
+ */
+
+void *ccc_key_init(const struct lu_context *ctx,
+			  struct lu_context_key *key)
+{
+	struct ccc_thread_info *info;
+
+	OBD_SLAB_ALLOC_PTR_GFP(info, ccc_thread_kmem, __GFP_IO);
+	if (info == NULL)
+		info = ERR_PTR(-ENOMEM);
+	return info;
+}
+
+void ccc_key_fini(const struct lu_context *ctx,
+			 struct lu_context_key *key, void *data)
+{
+	struct ccc_thread_info *info = data;
+	OBD_SLAB_FREE_PTR(info, ccc_thread_kmem);
+}
+
+void *ccc_session_key_init(const struct lu_context *ctx,
+				  struct lu_context_key *key)
+{
+	struct ccc_session *session;
+
+	OBD_SLAB_ALLOC_PTR_GFP(session, ccc_session_kmem, __GFP_IO);
+	if (session == NULL)
+		session = ERR_PTR(-ENOMEM);
+	return session;
+}
+
+void ccc_session_key_fini(const struct lu_context *ctx,
+				 struct lu_context_key *key, void *data)
+{
+	struct ccc_session *session = data;
+	OBD_SLAB_FREE_PTR(session, ccc_session_kmem);
+}
+
+struct lu_context_key ccc_key = {
+	.lct_tags = LCT_CL_THREAD,
+	.lct_init = ccc_key_init,
+	.lct_fini = ccc_key_fini
+};
+
+struct lu_context_key ccc_session_key = {
+	.lct_tags = LCT_SESSION,
+	.lct_init = ccc_session_key_init,
+	.lct_fini = ccc_session_key_fini
+};
+
+
+/* type constructor/destructor: ccc_type_{init,fini,start,stop}(). */
+// LU_TYPE_INIT_FINI(ccc, &ccc_key, &ccc_session_key);
+
+int ccc_device_init(const struct lu_env *env, struct lu_device *d,
+			   const char *name, struct lu_device *next)
+{
+	struct ccc_device  *vdv;
+	int rc;
+	ENTRY;
+
+	vdv = lu2ccc_dev(d);
+	vdv->cdv_next = lu2cl_dev(next);
+
+	LASSERT(d->ld_site != NULL && next->ld_type != NULL);
+	next->ld_site = d->ld_site;
+	rc = next->ld_type->ldt_ops->ldto_device_init(
+			env, next, next->ld_type->ldt_name, NULL);
+	if (rc == 0) {
+		lu_device_get(next);
+		lu_ref_add(&next->ld_reference, "lu-stack", &lu_site_init);
+	}
+	RETURN(rc);
+}
+
+struct lu_device *ccc_device_fini(const struct lu_env *env,
+					 struct lu_device *d)
+{
+	return cl2lu_dev(lu2ccc_dev(d)->cdv_next);
+}
+
+struct lu_device *ccc_device_alloc(const struct lu_env *env,
+				   struct lu_device_type *t,
+				   struct lustre_cfg *cfg,
+				   const struct lu_device_operations *luops,
+				   const struct cl_device_operations *clops)
+{
+	struct ccc_device *vdv;
+	struct lu_device  *lud;
+	struct cl_site    *site;
+	int rc;
+	ENTRY;
+
+	OBD_ALLOC_PTR(vdv);
+	if (vdv == NULL)
+		RETURN(ERR_PTR(-ENOMEM));
+
+	lud = &vdv->cdv_cl.cd_lu_dev;
+	cl_device_init(&vdv->cdv_cl, t);
+	ccc2lu_dev(vdv)->ld_ops = luops;
+	vdv->cdv_cl.cd_ops = clops;
+
+	OBD_ALLOC_PTR(site);
+	if (site != NULL) {
+		rc = cl_site_init(site, &vdv->cdv_cl);
+		if (rc == 0)
+			rc = lu_site_init_finish(&site->cs_lu);
+		else {
+			LASSERT(lud->ld_site == NULL);
+			CERROR("Cannot init lu_site, rc %d.\n", rc);
+			OBD_FREE_PTR(site);
+		}
+	} else
+		rc = -ENOMEM;
+	if (rc != 0) {
+		ccc_device_free(env, lud);
+		lud = ERR_PTR(rc);
+	}
+	RETURN(lud);
+}
+
+struct lu_device *ccc_device_free(const struct lu_env *env,
+					 struct lu_device *d)
+{
+	struct ccc_device *vdv  = lu2ccc_dev(d);
+	struct cl_site    *site = lu2cl_site(d->ld_site);
+	struct lu_device  *next = cl2lu_dev(vdv->cdv_next);
+
+	if (d->ld_site != NULL) {
+		cl_site_fini(site);
+		OBD_FREE_PTR(site);
+	}
+	cl_device_fini(lu2cl_dev(d));
+	OBD_FREE_PTR(vdv);
+	return next;
+}
+
+int ccc_req_init(const struct lu_env *env, struct cl_device *dev,
+			struct cl_req *req)
+{
+	struct ccc_req *vrq;
+	int result;
+
+	OBD_SLAB_ALLOC_PTR_GFP(vrq, ccc_req_kmem, __GFP_IO);
+	if (vrq != NULL) {
+		cl_req_slice_add(req, &vrq->crq_cl, dev, &ccc_req_ops);
+		result = 0;
+	} else
+		result = -ENOMEM;
+	return result;
+}
+
+/**
+ * An `emergency' environment used by ccc_inode_fini() when cl_env_get()
+ * fails. Access to this environment is serialized by ccc_inode_fini_guard
+ * mutex.
+ */
+static struct lu_env *ccc_inode_fini_env = NULL;
+
+/**
+ * A mutex serializing calls to slp_inode_fini() under extreme memory
+ * pressure, when environments cannot be allocated.
+ */
+static DEFINE_MUTEX(ccc_inode_fini_guard);
+static int dummy_refcheck;
+
+int ccc_global_init(struct lu_device_type *device_type)
+{
+	int result;
+
+	result = lu_kmem_init(ccc_caches);
+	if (result)
+		return result;
+
+	result = lu_device_type_init(device_type);
+	if (result)
+		goto out_kmem;
+
+	ccc_inode_fini_env = cl_env_alloc(&dummy_refcheck,
+					  LCT_REMEMBER|LCT_NOREF);
+	if (IS_ERR(ccc_inode_fini_env)) {
+		result = PTR_ERR(ccc_inode_fini_env);
+		goto out_device;
+	}
+
+	ccc_inode_fini_env->le_ctx.lc_cookie = 0x4;
+	return 0;
+out_device:
+	lu_device_type_fini(device_type);
+out_kmem:
+	lu_kmem_fini(ccc_caches);
+	return result;
+}
+
+void ccc_global_fini(struct lu_device_type *device_type)
+{
+	if (ccc_inode_fini_env != NULL) {
+		cl_env_put(ccc_inode_fini_env, &dummy_refcheck);
+		ccc_inode_fini_env = NULL;
+	}
+	lu_device_type_fini(device_type);
+	lu_kmem_fini(ccc_caches);
+}
+
+/*****************************************************************************
+ *
+ * Object operations.
+ *
+ */
+
+struct lu_object *ccc_object_alloc(const struct lu_env *env,
+				   const struct lu_object_header *unused,
+				   struct lu_device *dev,
+				   const struct cl_object_operations *clops,
+				   const struct lu_object_operations *luops)
+{
+	struct ccc_object *vob;
+	struct lu_object  *obj;
+
+	OBD_SLAB_ALLOC_PTR_GFP(vob, ccc_object_kmem, __GFP_IO);
+	if (vob != NULL) {
+		struct cl_object_header *hdr;
+
+		obj = ccc2lu(vob);
+		hdr = &vob->cob_header;
+		cl_object_header_init(hdr);
+		lu_object_init(obj, &hdr->coh_lu, dev);
+		lu_object_add_top(&hdr->coh_lu, obj);
+
+		vob->cob_cl.co_ops = clops;
+		obj->lo_ops = luops;
+	} else
+		obj = NULL;
+	return obj;
+}
+
+int ccc_object_init0(const struct lu_env *env,
+			    struct ccc_object *vob,
+			    const struct cl_object_conf *conf)
+{
+	vob->cob_inode = conf->coc_inode;
+	vob->cob_transient_pages = 0;
+	cl_object_page_init(&vob->cob_cl, sizeof(struct ccc_page));
+	return 0;
+}
+
+int ccc_object_init(const struct lu_env *env, struct lu_object *obj,
+			   const struct lu_object_conf *conf)
+{
+	struct ccc_device *dev = lu2ccc_dev(obj->lo_dev);
+	struct ccc_object *vob = lu2ccc(obj);
+	struct lu_object  *below;
+	struct lu_device  *under;
+	int result;
+
+	under = &dev->cdv_next->cd_lu_dev;
+	below = under->ld_ops->ldo_object_alloc(env, obj->lo_header, under);
+	if (below != NULL) {
+		const struct cl_object_conf *cconf;
+
+		cconf = lu2cl_conf(conf);
+		INIT_LIST_HEAD(&vob->cob_pending_list);
+		lu_object_add(obj, below);
+		result = ccc_object_init0(env, vob, cconf);
+	} else
+		result = -ENOMEM;
+	return result;
+}
+
+void ccc_object_free(const struct lu_env *env, struct lu_object *obj)
+{
+	struct ccc_object *vob = lu2ccc(obj);
+
+	lu_object_fini(obj);
+	lu_object_header_fini(obj->lo_header);
+	OBD_SLAB_FREE_PTR(vob, ccc_object_kmem);
+}
+
+int ccc_lock_init(const struct lu_env *env,
+		  struct cl_object *obj, struct cl_lock *lock,
+		  const struct cl_io *unused,
+		  const struct cl_lock_operations *lkops)
+{
+	struct ccc_lock *clk;
+	int result;
+
+	CLOBINVRNT(env, obj, ccc_object_invariant(obj));
+
+	OBD_SLAB_ALLOC_PTR_GFP(clk, ccc_lock_kmem, __GFP_IO);
+	if (clk != NULL) {
+		cl_lock_slice_add(lock, &clk->clk_cl, obj, lkops);
+		result = 0;
+	} else
+		result = -ENOMEM;
+	return result;
+}
+
+int ccc_attr_set(const struct lu_env *env, struct cl_object *obj,
+		 const struct cl_attr *attr, unsigned valid)
+{
+	return 0;
+}
+
+int ccc_object_glimpse(const struct lu_env *env,
+		       const struct cl_object *obj, struct ost_lvb *lvb)
+{
+	struct inode *inode = ccc_object_inode(obj);
+
+	ENTRY;
+	lvb->lvb_mtime = cl_inode_mtime(inode);
+	lvb->lvb_atime = cl_inode_atime(inode);
+	lvb->lvb_ctime = cl_inode_ctime(inode);
+	/*
+	 * LU-417: Add dirty pages block count lest i_blocks reports 0, some
+	 * "cp" or "tar" on remote node may think it's a completely sparse file
+	 * and skip it.
+	 */
+	if (lvb->lvb_size > 0 && lvb->lvb_blocks == 0)
+		lvb->lvb_blocks = dirty_cnt(inode);
+	RETURN(0);
+}
+
+
+
+int ccc_conf_set(const struct lu_env *env, struct cl_object *obj,
+			const struct cl_object_conf *conf)
+{
+	/* TODO: destroy all pages attached to this object. */
+	return 0;
+}
+
+static void ccc_object_size_lock(struct cl_object *obj)
+{
+	struct inode *inode = ccc_object_inode(obj);
+
+	cl_isize_lock(inode);
+	cl_object_attr_lock(obj);
+}
+
+static void ccc_object_size_unlock(struct cl_object *obj)
+{
+	struct inode *inode = ccc_object_inode(obj);
+
+	cl_object_attr_unlock(obj);
+	cl_isize_unlock(inode);
+}
+
+/*****************************************************************************
+ *
+ * Page operations.
+ *
+ */
+
+struct page *ccc_page_vmpage(const struct lu_env *env,
+			    const struct cl_page_slice *slice)
+{
+	return cl2vm_page(slice);
+}
+
+int ccc_page_is_under_lock(const struct lu_env *env,
+			   const struct cl_page_slice *slice,
+			   struct cl_io *io)
+{
+	struct ccc_io	*cio  = ccc_env_io(env);
+	struct cl_lock_descr *desc = &ccc_env_info(env)->cti_descr;
+	struct cl_page       *page = slice->cpl_page;
+
+	int result;
+
+	ENTRY;
+
+	if (io->ci_type == CIT_READ || io->ci_type == CIT_WRITE ||
+	    io->ci_type == CIT_FAULT) {
+		if (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)
+			result = -EBUSY;
+		else {
+			desc->cld_start = page->cp_index;
+			desc->cld_end   = page->cp_index;
+			desc->cld_obj   = page->cp_obj;
+			desc->cld_mode  = CLM_READ;
+			result = cl_queue_match(&io->ci_lockset.cls_done,
+						desc) ? -EBUSY : 0;
+		}
+	} else
+		result = 0;
+	RETURN(result);
+}
+
+int ccc_fail(const struct lu_env *env, const struct cl_page_slice *slice)
+{
+	/*
+	 * Cached read?
+	 */
+	LBUG();
+	return 0;
+}
+
+void ccc_transient_page_verify(const struct cl_page *page)
+{
+}
+
+int ccc_transient_page_own(const struct lu_env *env,
+				   const struct cl_page_slice *slice,
+				   struct cl_io *unused,
+				   int nonblock)
+{
+	ccc_transient_page_verify(slice->cpl_page);
+	return 0;
+}
+
+void ccc_transient_page_assume(const struct lu_env *env,
+				      const struct cl_page_slice *slice,
+				      struct cl_io *unused)
+{
+	ccc_transient_page_verify(slice->cpl_page);
+}
+
+void ccc_transient_page_unassume(const struct lu_env *env,
+					const struct cl_page_slice *slice,
+					struct cl_io *unused)
+{
+	ccc_transient_page_verify(slice->cpl_page);
+}
+
+void ccc_transient_page_disown(const struct lu_env *env,
+				      const struct cl_page_slice *slice,
+				      struct cl_io *unused)
+{
+	ccc_transient_page_verify(slice->cpl_page);
+}
+
+void ccc_transient_page_discard(const struct lu_env *env,
+				       const struct cl_page_slice *slice,
+				       struct cl_io *unused)
+{
+	struct cl_page *page = slice->cpl_page;
+
+	ccc_transient_page_verify(slice->cpl_page);
+
+	/*
+	 * For transient pages, remove it from the radix tree.
+	 */
+	cl_page_delete(env, page);
+}
+
+int ccc_transient_page_prep(const struct lu_env *env,
+				   const struct cl_page_slice *slice,
+				   struct cl_io *unused)
+{
+	ENTRY;
+	/* transient page should always be sent. */
+	RETURN(0);
+}
+
+/*****************************************************************************
+ *
+ * Lock operations.
+ *
+ */
+
+void ccc_lock_delete(const struct lu_env *env,
+		     const struct cl_lock_slice *slice)
+{
+	CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj));
+}
+
+void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice)
+{
+	struct ccc_lock *clk = cl2ccc_lock(slice);
+	OBD_SLAB_FREE_PTR(clk, ccc_lock_kmem);
+}
+
+int ccc_lock_enqueue(const struct lu_env *env,
+		     const struct cl_lock_slice *slice,
+		     struct cl_io *unused, __u32 enqflags)
+{
+	CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj));
+	return 0;
+}
+
+int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice)
+{
+	CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj));
+	return 0;
+}
+
+int ccc_lock_wait(const struct lu_env *env, const struct cl_lock_slice *slice)
+{
+	CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj));
+	return 0;
+}
+
+/**
+ * Implementation of cl_lock_operations::clo_fits_into() methods for ccc
+ * layer. This function is executed every time io finds an existing lock in
+ * the lock cache while creating new lock. This function has to decide whether
+ * cached lock "fits" into io.
+ *
+ * \param slice lock to be checked
+ * \param io    IO that wants a lock.
+ *
+ * \see lov_lock_fits_into().
+ */
+int ccc_lock_fits_into(const struct lu_env *env,
+		       const struct cl_lock_slice *slice,
+		       const struct cl_lock_descr *need,
+		       const struct cl_io *io)
+{
+	const struct cl_lock       *lock  = slice->cls_lock;
+	const struct cl_lock_descr *descr = &lock->cll_descr;
+	const struct ccc_io	*cio   = ccc_env_io(env);
+	int			 result;
+
+	ENTRY;
+	/*
+	 * Work around DLM peculiarity: it assumes that glimpse
+	 * (LDLM_FL_HAS_INTENT) lock is always LCK_PR, and returns reads lock
+	 * when asked for LCK_PW lock with LDLM_FL_HAS_INTENT flag set. Make
+	 * sure that glimpse doesn't get CLM_WRITE top-lock, so that it
+	 * doesn't enqueue CLM_WRITE sub-locks.
+	 */
+	if (cio->cui_glimpse)
+		result = descr->cld_mode != CLM_WRITE;
+
+	/*
+	 * Also, don't match incomplete write locks for read, otherwise read
+	 * would enqueue missing sub-locks in the write mode.
+	 */
+	else if (need->cld_mode != descr->cld_mode)
+		result = lock->cll_state >= CLS_ENQUEUED;
+	else
+		result = 1;
+	RETURN(result);
+}
+
+/**
+ * Implements cl_lock_operations::clo_state() method for ccc layer, invoked
+ * whenever lock state changes. Transfers object attributes, that might be
+ * updated as a result of lock acquiring into inode.
+ */
+void ccc_lock_state(const struct lu_env *env,
+		    const struct cl_lock_slice *slice,
+		    enum cl_lock_state state)
+{
+	struct cl_lock *lock = slice->cls_lock;
+	ENTRY;
+
+	/*
+	 * Refresh inode attributes when the lock is moving into CLS_HELD
+	 * state, and only when this is a result of real enqueue, rather than
+	 * of finding lock in the cache.
+	 */
+	if (state == CLS_HELD && lock->cll_state < CLS_HELD) {
+		struct cl_object *obj;
+		struct inode     *inode;
+
+		obj   = slice->cls_obj;
+		inode = ccc_object_inode(obj);
+
+		/* vmtruncate() sets the i_size
+		 * under both a DLM lock and the
+		 * ll_inode_size_lock().  If we don't get the
+		 * ll_inode_size_lock() here we can match the DLM lock and
+		 * reset i_size.  generic_file_write can then trust the
+		 * stale i_size when doing appending writes and effectively
+		 * cancel the result of the truncate.  Getting the
+		 * ll_inode_size_lock() after the enqueue maintains the DLM
+		 * -> ll_inode_size_lock() acquiring order. */
+		if (lock->cll_descr.cld_start == 0 &&
+		    lock->cll_descr.cld_end == CL_PAGE_EOF)
+			cl_merge_lvb(env, inode);
+	}
+	EXIT;
+}
+
+/*****************************************************************************
+ *
+ * io operations.
+ *
+ */
+
+void ccc_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
+{
+	struct cl_io *io = ios->cis_io;
+
+	CLOBINVRNT(env, io->ci_obj, ccc_object_invariant(io->ci_obj));
+}
+
+int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io,
+			  __u32 enqflags, enum cl_lock_mode mode,
+			  pgoff_t start, pgoff_t end)
+{
+	struct ccc_io	  *cio   = ccc_env_io(env);
+	struct cl_lock_descr   *descr = &cio->cui_link.cill_descr;
+	struct cl_object       *obj   = io->ci_obj;
+
+	CLOBINVRNT(env, obj, ccc_object_invariant(obj));
+	ENTRY;
+
+	CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end);
+
+	memset(&cio->cui_link, 0, sizeof cio->cui_link);
+
+	if (cio->cui_fd && (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
+		descr->cld_mode = CLM_GROUP;
+		descr->cld_gid  = cio->cui_fd->fd_grouplock.cg_gid;
+	} else {
+		descr->cld_mode  = mode;
+	}
+	descr->cld_obj   = obj;
+	descr->cld_start = start;
+	descr->cld_end   = end;
+	descr->cld_enq_flags = enqflags;
+
+	cl_io_lock_add(env, io, &cio->cui_link);
+	RETURN(0);
+}
+
+void ccc_io_update_iov(const struct lu_env *env,
+		       struct ccc_io *cio, struct cl_io *io)
+{
+	int i;
+	size_t size = io->u.ci_rw.crw_count;
+
+	cio->cui_iov_olen = 0;
+	if (!cl_is_normalio(env, io) || cio->cui_tot_nrsegs == 0)
+		return;
+
+	for (i = 0; i < cio->cui_tot_nrsegs; i++) {
+		struct iovec *iv = &cio->cui_iov[i];
+
+		if (iv->iov_len < size)
+			size -= iv->iov_len;
+		else {
+			if (iv->iov_len > size) {
+				cio->cui_iov_olen = iv->iov_len;
+				iv->iov_len = size;
+			}
+			break;
+		}
+	}
+
+	cio->cui_nrsegs = i + 1;
+	LASSERTF(cio->cui_tot_nrsegs >= cio->cui_nrsegs,
+		 "tot_nrsegs: %lu, nrsegs: %lu\n",
+		 cio->cui_tot_nrsegs, cio->cui_nrsegs);
+}
+
+int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io,
+		    __u32 enqflags, enum cl_lock_mode mode,
+		    loff_t start, loff_t end)
+{
+	struct cl_object *obj = io->ci_obj;
+	return ccc_io_one_lock_index(env, io, enqflags, mode,
+				     cl_index(obj, start), cl_index(obj, end));
+}
+
+void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios)
+{
+	CLOBINVRNT(env, ios->cis_io->ci_obj,
+		   ccc_object_invariant(ios->cis_io->ci_obj));
+}
+
+void ccc_io_advance(const struct lu_env *env,
+		    const struct cl_io_slice *ios,
+		    size_t nob)
+{
+	struct ccc_io    *cio = cl2ccc_io(env, ios);
+	struct cl_io     *io  = ios->cis_io;
+	struct cl_object *obj = ios->cis_io->ci_obj;
+
+	CLOBINVRNT(env, obj, ccc_object_invariant(obj));
+
+	if (!cl_is_normalio(env, io))
+		return;
+
+	LASSERT(cio->cui_tot_nrsegs >= cio->cui_nrsegs);
+	LASSERT(cio->cui_tot_count  >= nob);
+
+	cio->cui_iov	+= cio->cui_nrsegs;
+	cio->cui_tot_nrsegs -= cio->cui_nrsegs;
+	cio->cui_tot_count  -= nob;
+
+	/* update the iov */
+	if (cio->cui_iov_olen > 0) {
+		struct iovec *iv;
+
+		cio->cui_iov--;
+		cio->cui_tot_nrsegs++;
+		iv = &cio->cui_iov[0];
+		if (io->ci_continue) {
+			iv->iov_base += iv->iov_len;
+			LASSERT(cio->cui_iov_olen > iv->iov_len);
+			iv->iov_len = cio->cui_iov_olen - iv->iov_len;
+		} else {
+			/* restore the iov_len, in case of restart io. */
+			iv->iov_len = cio->cui_iov_olen;
+		}
+		cio->cui_iov_olen = 0;
+	}
+}
+
+/**
+ * Helper function that if necessary adjusts file size (inode->i_size), when
+ * position at the offset \a pos is accessed. File size can be arbitrary stale
+ * on a Lustre client, but client at least knows KMS. If accessed area is
+ * inside [0, KMS], set file size to KMS, otherwise glimpse file size.
+ *
+ * Locking: cl_isize_lock is used to serialize changes to inode size and to
+ * protect consistency between inode size and cl_object
+ * attributes. cl_object_size_lock() protects consistency between cl_attr's of
+ * top-object and sub-objects.
+ */
+int ccc_prep_size(const struct lu_env *env, struct cl_object *obj,
+		  struct cl_io *io, loff_t start, size_t count, int *exceed)
+{
+	struct cl_attr *attr  = ccc_env_thread_attr(env);
+	struct inode   *inode = ccc_object_inode(obj);
+	loff_t	  pos   = start + count - 1;
+	loff_t kms;
+	int result;
+
+	/*
+	 * Consistency guarantees: following possibilities exist for the
+	 * relation between region being accessed and real file size at this
+	 * moment:
+	 *
+	 *  (A): the region is completely inside of the file;
+	 *
+	 *  (B-x): x bytes of region are inside of the file, the rest is
+	 *  outside;
+	 *
+	 *  (C): the region is completely outside of the file.
+	 *
+	 * This classification is stable under DLM lock already acquired by
+	 * the caller, because to change the class, other client has to take
+	 * DLM lock conflicting with our lock. Also, any updates to ->i_size
+	 * by other threads on this client are serialized by
+	 * ll_inode_size_lock(). This guarantees that short reads are handled
+	 * correctly in the face of concurrent writes and truncates.
+	 */
+	ccc_object_size_lock(obj);
+	result = cl_object_attr_get(env, obj, attr);
+	if (result == 0) {
+		kms = attr->cat_kms;
+		if (pos > kms) {
+			/*
+			 * A glimpse is necessary to determine whether we
+			 * return a short read (B) or some zeroes at the end
+			 * of the buffer (C)
+			 */
+			ccc_object_size_unlock(obj);
+			result = cl_glimpse_lock(env, io, inode, obj, 0);
+			if (result == 0 && exceed != NULL) {
+				/* If objective page index exceed end-of-file
+				 * page index, return directly. Do not expect
+				 * kernel will check such case correctly.
+				 * linux-2.6.18-128.1.1 miss to do that.
+				 * --bug 17336 */
+				loff_t size = cl_isize_read(inode);
+				unsigned long cur_index = start >> PAGE_CACHE_SHIFT;
+
+				if ((size == 0 && cur_index != 0) ||
+				    (((size - 1) >> PAGE_CACHE_SHIFT) < cur_index))
+				*exceed = 1;
+			}
+			return result;
+		} else {
+			/*
+			 * region is within kms and, hence, within real file
+			 * size (A). We need to increase i_size to cover the
+			 * read region so that generic_file_read() will do its
+			 * job, but that doesn't mean the kms size is
+			 * _correct_, it is only the _minimum_ size. If
+			 * someone does a stat they will get the correct size
+			 * which will always be >= the kms value here.
+			 * b=11081
+			 */
+			if (cl_isize_read(inode) < kms) {
+				cl_isize_write_nolock(inode, kms);
+				CDEBUG(D_VFSTRACE,
+				       DFID" updating i_size "LPU64"\n",
+				       PFID(lu_object_fid(&obj->co_lu)),
+				       (__u64)cl_isize_read(inode));
+
+			}
+		}
+	}
+	ccc_object_size_unlock(obj);
+	return result;
+}
+
+/*****************************************************************************
+ *
+ * Transfer operations.
+ *
+ */
+
+void ccc_req_completion(const struct lu_env *env,
+			const struct cl_req_slice *slice, int ioret)
+{
+	struct ccc_req *vrq;
+
+	if (ioret > 0)
+		cl_stats_tally(slice->crs_dev, slice->crs_req->crq_type, ioret);
+
+	vrq = cl2ccc_req(slice);
+	OBD_SLAB_FREE_PTR(vrq, ccc_req_kmem);
+}
+
+/**
+ * Implementation of struct cl_req_operations::cro_attr_set() for ccc
+ * layer. ccc is responsible for
+ *
+ *    - o_[mac]time
+ *
+ *    - o_mode
+ *
+ *    - o_parent_seq
+ *
+ *    - o_[ug]id
+ *
+ *    - o_parent_oid
+ *
+ *    - o_parent_ver
+ *
+ *    - o_ioepoch,
+ *
+ *  and capability.
+ */
+void ccc_req_attr_set(const struct lu_env *env,
+		      const struct cl_req_slice *slice,
+		      const struct cl_object *obj,
+		      struct cl_req_attr *attr, obd_valid flags)
+{
+	struct inode *inode;
+	struct obdo  *oa;
+	obd_flag      valid_flags;
+
+	oa = attr->cra_oa;
+	inode = ccc_object_inode(obj);
+	valid_flags = OBD_MD_FLTYPE;
+
+	if ((flags & OBD_MD_FLOSSCAPA) != 0) {
+		LASSERT(attr->cra_capa == NULL);
+		attr->cra_capa = cl_capa_lookup(inode,
+						slice->crs_req->crq_type);
+	}
+
+	if (slice->crs_req->crq_type == CRT_WRITE) {
+		if (flags & OBD_MD_FLEPOCH) {
+			oa->o_valid |= OBD_MD_FLEPOCH;
+			oa->o_ioepoch = cl_i2info(inode)->lli_ioepoch;
+			valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME |
+				       OBD_MD_FLUID | OBD_MD_FLGID;
+		}
+	}
+	obdo_from_inode(oa, inode, valid_flags & flags);
+	obdo_set_parent_fid(oa, &cl_i2info(inode)->lli_fid);
+	memcpy(attr->cra_jobid, cl_i2info(inode)->lli_jobid,
+	       JOBSTATS_JOBID_SIZE);
+}
+
+const struct cl_req_operations ccc_req_ops = {
+	.cro_attr_set   = ccc_req_attr_set,
+	.cro_completion = ccc_req_completion
+};
+
+int cl_setattr_ost(struct inode *inode, const struct iattr *attr,
+		   struct obd_capa *capa)
+{
+	struct lu_env *env;
+	struct cl_io  *io;
+	int	    result;
+	int	    refcheck;
+
+	ENTRY;
+
+	env = cl_env_get(&refcheck);
+	if (IS_ERR(env))
+		RETURN(PTR_ERR(env));
+
+	io = ccc_env_thread_io(env);
+	io->ci_obj = cl_i2info(inode)->lli_clob;
+
+	io->u.ci_setattr.sa_attr.lvb_atime = LTIME_S(attr->ia_atime);
+	io->u.ci_setattr.sa_attr.lvb_mtime = LTIME_S(attr->ia_mtime);
+	io->u.ci_setattr.sa_attr.lvb_ctime = LTIME_S(attr->ia_ctime);
+	io->u.ci_setattr.sa_attr.lvb_size = attr->ia_size;
+	io->u.ci_setattr.sa_valid = attr->ia_valid;
+	io->u.ci_setattr.sa_capa = capa;
+
+again:
+	if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) {
+		struct ccc_io *cio = ccc_env_io(env);
+
+		if (attr->ia_valid & ATTR_FILE)
+			/* populate the file descriptor for ftruncate to honor
+			 * group lock - see LU-787 */
+			cio->cui_fd = cl_iattr2fd(inode, attr);
+
+		result = cl_io_loop(env, io);
+	} else {
+		result = io->ci_result;
+	}
+	cl_io_fini(env, io);
+	if (unlikely(io->ci_need_restart))
+		goto again;
+	cl_env_put(env, &refcheck);
+	RETURN(result);
+}
+
+/*****************************************************************************
+ *
+ * Type conversions.
+ *
+ */
+
+struct lu_device *ccc2lu_dev(struct ccc_device *vdv)
+{
+	return &vdv->cdv_cl.cd_lu_dev;
+}
+
+struct ccc_device *lu2ccc_dev(const struct lu_device *d)
+{
+	return container_of0(d, struct ccc_device, cdv_cl.cd_lu_dev);
+}
+
+struct ccc_device *cl2ccc_dev(const struct cl_device *d)
+{
+	return container_of0(d, struct ccc_device, cdv_cl);
+}
+
+struct lu_object *ccc2lu(struct ccc_object *vob)
+{
+	return &vob->cob_cl.co_lu;
+}
+
+struct ccc_object *lu2ccc(const struct lu_object *obj)
+{
+	return container_of0(obj, struct ccc_object, cob_cl.co_lu);
+}
+
+struct ccc_object *cl2ccc(const struct cl_object *obj)
+{
+	return container_of0(obj, struct ccc_object, cob_cl);
+}
+
+struct ccc_lock *cl2ccc_lock(const struct cl_lock_slice *slice)
+{
+	return container_of(slice, struct ccc_lock, clk_cl);
+}
+
+struct ccc_io *cl2ccc_io(const struct lu_env *env,
+			 const struct cl_io_slice *slice)
+{
+	struct ccc_io *cio;
+
+	cio = container_of(slice, struct ccc_io, cui_cl);
+	LASSERT(cio == ccc_env_io(env));
+	return cio;
+}
+
+struct ccc_req *cl2ccc_req(const struct cl_req_slice *slice)
+{
+	return container_of0(slice, struct ccc_req, crq_cl);
+}
+
+struct page *cl2vm_page(const struct cl_page_slice *slice)
+{
+	return cl2ccc_page(slice)->cpg_page;
+}
+
+/*****************************************************************************
+ *
+ * Accessors.
+ *
+ */
+int ccc_object_invariant(const struct cl_object *obj)
+{
+	struct inode	 *inode = ccc_object_inode(obj);
+	struct cl_inode_info *lli   = cl_i2info(inode);
+
+	return (S_ISREG(cl_inode_mode(inode)) ||
+		/* i_mode of unlinked inode is zeroed. */
+		cl_inode_mode(inode) == 0) && lli->lli_clob == obj;
+}
+
+struct inode *ccc_object_inode(const struct cl_object *obj)
+{
+	return cl2ccc(obj)->cob_inode;
+}
+
+/**
+ * Returns a pointer to cl_page associated with \a vmpage, without acquiring
+ * additional reference to the resulting page. This is an unsafe version of
+ * cl_vmpage_page() that can only be used under vmpage lock.
+ */
+struct cl_page *ccc_vmpage_page_transient(struct page *vmpage)
+{
+	KLASSERT(PageLocked(vmpage));
+	return (struct cl_page *)vmpage->private;
+}
+
+/**
+ * Initialize or update CLIO structures for regular files when new
+ * meta-data arrives from the server.
+ *
+ * \param inode regular file inode
+ * \param md    new file metadata from MDS
+ * - allocates cl_object if necessary,
+ * - updated layout, if object was already here.
+ */
+int cl_file_inode_init(struct inode *inode, struct lustre_md *md)
+{
+	struct lu_env	*env;
+	struct cl_inode_info *lli;
+	struct cl_object     *clob;
+	struct lu_site       *site;
+	struct lu_fid	*fid;
+	struct cl_object_conf conf = {
+		.coc_inode = inode,
+		.u = {
+			.coc_md    = md
+		}
+	};
+	int result = 0;
+	int refcheck;
+
+	LASSERT(md->body->valid & OBD_MD_FLID);
+	LASSERT(S_ISREG(cl_inode_mode(inode)));
+
+	env = cl_env_get(&refcheck);
+	if (IS_ERR(env))
+		return PTR_ERR(env);
+
+	site = cl_i2sbi(inode)->ll_site;
+	lli  = cl_i2info(inode);
+	fid  = &lli->lli_fid;
+	LASSERT(fid_is_sane(fid));
+
+	if (lli->lli_clob == NULL) {
+		/* clob is slave of inode, empty lli_clob means for new inode,
+		 * there is no clob in cache with the given fid, so it is
+		 * unnecessary to perform lookup-alloc-lookup-insert, just
+		 * alloc and insert directly. */
+		LASSERT(inode->i_state & I_NEW);
+		conf.coc_lu.loc_flags = LOC_F_NEW;
+		clob = cl_object_find(env, lu2cl_dev(site->ls_top_dev),
+				      fid, &conf);
+		if (!IS_ERR(clob)) {
+			/*
+			 * No locking is necessary, as new inode is
+			 * locked by I_NEW bit.
+			 */
+			lli->lli_clob = clob;
+			lli->lli_has_smd = md->lsm != NULL;
+			lu_object_ref_add(&clob->co_lu, "inode", inode);
+		} else
+			result = PTR_ERR(clob);
+	} else {
+		result = cl_conf_set(env, lli->lli_clob, &conf);
+	}
+
+	cl_env_put(env, &refcheck);
+
+	if (result != 0)
+		CERROR("Failure to initialize cl object "DFID": %d\n",
+		       PFID(fid), result);
+	return result;
+}
+
+/**
+ * Wait for others drop their references of the object at first, then we drop
+ * the last one, which will lead to the object be destroyed immediately.
+ * Must be called after cl_object_kill() against this object.
+ *
+ * The reason we want to do this is: destroying top object will wait for sub
+ * objects being destroyed first, so we can't let bottom layer (e.g. from ASTs)
+ * to initiate top object destroying which may deadlock. See bz22520.
+ */
+static void cl_object_put_last(struct lu_env *env, struct cl_object *obj)
+{
+	struct lu_object_header *header = obj->co_lu.lo_header;
+	wait_queue_t	   waiter;
+
+	if (unlikely(atomic_read(&header->loh_ref) != 1)) {
+		struct lu_site *site = obj->co_lu.lo_dev->ld_site;
+		struct lu_site_bkt_data *bkt;
+
+		bkt = lu_site_bkt_from_fid(site, &header->loh_fid);
+
+		init_waitqueue_entry_current(&waiter);
+		add_wait_queue(&bkt->lsb_marche_funebre, &waiter);
+
+		while (1) {
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			if (atomic_read(&header->loh_ref) == 1)
+				break;
+			waitq_wait(&waiter, TASK_UNINTERRUPTIBLE);
+		}
+
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&bkt->lsb_marche_funebre, &waiter);
+	}
+
+	cl_object_put(env, obj);
+}
+
+void cl_inode_fini(struct inode *inode)
+{
+	struct lu_env	   *env;
+	struct cl_inode_info    *lli  = cl_i2info(inode);
+	struct cl_object	*clob = lli->lli_clob;
+	int refcheck;
+	int emergency;
+
+	if (clob != NULL) {
+		void		    *cookie;
+
+		cookie = cl_env_reenter();
+		env = cl_env_get(&refcheck);
+		emergency = IS_ERR(env);
+		if (emergency) {
+			mutex_lock(&ccc_inode_fini_guard);
+			LASSERT(ccc_inode_fini_env != NULL);
+			cl_env_implant(ccc_inode_fini_env, &refcheck);
+			env = ccc_inode_fini_env;
+		}
+		/*
+		 * cl_object cache is a slave to inode cache (which, in turn
+		 * is a slave to dentry cache), don't keep cl_object in memory
+		 * when its master is evicted.
+		 */
+		cl_object_kill(env, clob);
+		lu_object_ref_del(&clob->co_lu, "inode", inode);
+		cl_object_put_last(env, clob);
+		lli->lli_clob = NULL;
+		if (emergency) {
+			cl_env_unplant(ccc_inode_fini_env, &refcheck);
+			mutex_unlock(&ccc_inode_fini_guard);
+		} else
+			cl_env_put(env, &refcheck);
+		cl_env_reexit(cookie);
+	}
+}
+
+/**
+ * return IF_* type for given lu_dirent entry.
+ * IF_* flag shld be converted to particular OS file type in
+ * platform llite module.
+ */
+__u16 ll_dirent_type_get(struct lu_dirent *ent)
+{
+	__u16 type = 0;
+	struct luda_type *lt;
+	int len = 0;
+
+	if (le32_to_cpu(ent->lde_attrs) & LUDA_TYPE) {
+		const unsigned align = sizeof(struct luda_type) - 1;
+
+		len = le16_to_cpu(ent->lde_namelen);
+		len = (len + align) & ~align;
+		lt = (void *)ent->lde_name + len;
+		type = IFTODT(le16_to_cpu(lt->lt_type));
+	}
+	return type;
+}
+
+/**
+ * build inode number from passed @fid */
+__u64 cl_fid_build_ino(const struct lu_fid *fid, int api32)
+{
+	if (BITS_PER_LONG == 32 || api32)
+		RETURN(fid_flatten32(fid));
+	else
+		RETURN(fid_flatten(fid));
+}
+
+/**
+ * build inode generation from passed @fid.  If our FID overflows the 32-bit
+ * inode number then return a non-zero generation to distinguish them. */
+__u32 cl_fid_build_gen(const struct lu_fid *fid)
+{
+	__u32 gen;
+	ENTRY;
+
+	if (fid_is_igif(fid)) {
+		gen = lu_igif_gen(fid);
+		RETURN(gen);
+	}
+
+	gen = (fid_flatten(fid) >> 32);
+	RETURN(gen);
+}
+
+/* lsm is unreliable after hsm implementation as layout can be changed at
+ * any time. This is only to support old, non-clio-ized interfaces. It will
+ * cause deadlock if clio operations are called with this extra layout refcount
+ * because in case the layout changed during the IO, ll_layout_refresh() will
+ * have to wait for the refcount to become zero to destroy the older layout.
+ *
+ * Notice that the lsm returned by this function may not be valid unless called
+ * inside layout lock - MDS_INODELOCK_LAYOUT. */
+struct lov_stripe_md *ccc_inode_lsm_get(struct inode *inode)
+{
+	return lov_lsm_get(cl_i2info(inode)->lli_clob);
+}
+
+void inline ccc_inode_lsm_put(struct inode *inode, struct lov_stripe_md *lsm)
+{
+	lov_lsm_put(cl_i2info(inode)->lli_clob, lsm);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/lclient/lcommon_misc.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/lclient/lcommon_misc.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/lclient/lcommon_misc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/lclient/lcommon_misc.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,194 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * cl code shared between vvp and liblustre (and other Lustre clients in the
+ * future).
+ *
+ */
+#include <obd_class.h>
+#include <obd_support.h>
+#include <obd.h>
+#include <cl_object.h>
+#include <lclient.h>
+
+#include <lustre_lite.h>
+
+
+/* Initialize the default and maximum LOV EA and cookie sizes.  This allows
+ * us to make MDS RPCs with large enough reply buffers to hold the
+ * maximum-sized (= maximum striped) EA and cookie without having to
+ * calculate this (via a call into the LOV + OSCs) each time we make an RPC. */
+int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp)
+{
+	struct lov_stripe_md lsm = { .lsm_magic = LOV_MAGIC_V3 };
+	__u32 valsize = sizeof(struct lov_desc);
+	int rc, easize, def_easize, cookiesize;
+	struct lov_desc desc;
+	__u16 stripes;
+	ENTRY;
+
+	rc = obd_get_info(NULL, dt_exp, sizeof(KEY_LOVDESC), KEY_LOVDESC,
+			  &valsize, &desc, NULL);
+	if (rc)
+		RETURN(rc);
+
+	stripes = min(desc.ld_tgt_count, (__u32)LOV_MAX_STRIPE_COUNT);
+	lsm.lsm_stripe_count = stripes;
+	easize = obd_size_diskmd(dt_exp, &lsm);
+
+	lsm.lsm_stripe_count = desc.ld_default_stripe_count;
+	def_easize = obd_size_diskmd(dt_exp, &lsm);
+
+	cookiesize = stripes * sizeof(struct llog_cookie);
+
+	CDEBUG(D_HA, "updating max_mdsize/max_cookiesize: %d/%d\n",
+	       easize, cookiesize);
+
+	rc = md_init_ea_size(md_exp, easize, def_easize, cookiesize);
+	RETURN(rc);
+}
+
+/**
+ * This function is used as an upcall-callback hooked by liblustre and llite
+ * clients into obd_notify() listeners chain to handle notifications about
+ * change of import connect_flags. See llu_fsswop_mount() and
+ * lustre_common_fill_super().
+ */
+int cl_ocd_update(struct obd_device *host,
+		  struct obd_device *watched,
+		  enum obd_notify_event ev, void *owner, void *data)
+{
+	struct lustre_client_ocd *lco;
+	struct client_obd	*cli;
+	__u64 flags;
+	int   result;
+
+	ENTRY;
+	if (!strcmp(watched->obd_type->typ_name, LUSTRE_OSC_NAME)) {
+		cli = &watched->u.cli;
+		lco = owner;
+		flags = cli->cl_import->imp_connect_data.ocd_connect_flags;
+		CDEBUG(D_SUPER, "Changing connect_flags: "LPX64" -> "LPX64"\n",
+		       lco->lco_flags, flags);
+		mutex_lock(&lco->lco_lock);
+		lco->lco_flags &= flags;
+		/* for each osc event update ea size */
+		if (lco->lco_dt_exp)
+			cl_init_ea_size(lco->lco_md_exp, lco->lco_dt_exp);
+
+		mutex_unlock(&lco->lco_lock);
+		result = 0;
+	} else {
+		CERROR("unexpected notification from %s %s!\n",
+		       watched->obd_type->typ_name,
+		       watched->obd_name);
+		result = -EINVAL;
+	}
+	RETURN(result);
+}
+
+#define GROUPLOCK_SCOPE "grouplock"
+
+int cl_get_grouplock(struct cl_object *obj, unsigned long gid, int nonblock,
+		     struct ccc_grouplock *cg)
+{
+	struct lu_env	  *env;
+	struct cl_io	   *io;
+	struct cl_lock	 *lock;
+	struct cl_lock_descr   *descr;
+	__u32		   enqflags;
+	int		     refcheck;
+	int		     rc;
+
+	env = cl_env_get(&refcheck);
+	if (IS_ERR(env))
+		return PTR_ERR(env);
+
+	io = ccc_env_thread_io(env);
+	io->ci_obj = obj;
+	io->ci_ignore_layout = 1;
+
+	rc = cl_io_init(env, io, CIT_MISC, io->ci_obj);
+	if (rc) {
+		LASSERT(rc < 0);
+		cl_env_put(env, &refcheck);
+		return rc;
+	}
+
+	descr = &ccc_env_info(env)->cti_descr;
+	descr->cld_obj = obj;
+	descr->cld_start = 0;
+	descr->cld_end = CL_PAGE_EOF;
+	descr->cld_gid = gid;
+	descr->cld_mode = CLM_GROUP;
+
+	enqflags = CEF_MUST | (nonblock ? CEF_NONBLOCK : 0);
+	descr->cld_enq_flags = enqflags;
+
+	lock = cl_lock_request(env, io, descr, GROUPLOCK_SCOPE, current);
+	if (IS_ERR(lock)) {
+		cl_io_fini(env, io);
+		cl_env_put(env, &refcheck);
+		return PTR_ERR(lock);
+	}
+
+	cg->cg_env  = cl_env_get(&refcheck);
+	cg->cg_io   = io;
+	cg->cg_lock = lock;
+	cg->cg_gid  = gid;
+	LASSERT(cg->cg_env == env);
+
+	cl_env_unplant(env, &refcheck);
+	return 0;
+}
+
+void cl_put_grouplock(struct ccc_grouplock *cg)
+{
+	struct lu_env  *env  = cg->cg_env;
+	struct cl_io   *io   = cg->cg_io;
+	struct cl_lock *lock = cg->cg_lock;
+	int	     refcheck;
+
+	LASSERT(cg->cg_env);
+	LASSERT(cg->cg_gid);
+
+	cl_env_implant(env, &refcheck);
+	cl_env_put(env, &refcheck);
+
+	cl_unuse(env, lock);
+	cl_lock_release(env, lock, GROUPLOCK_SCOPE, current);
+	cl_io_fini(env, io);
+	cl_env_put(env, NULL);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/interval_tree.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/interval_tree.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/interval_tree.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/interval_tree.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,764 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/ldlm/interval_tree.c
+ *
+ * Interval tree library used by ldlm extent lock code
+ *
+ * Author: Huang Wei <huangwei@clusterfs.com>
+ * Author: Jay Xiong <jinshan.xiong@sun.com>
+ */
+# include <lustre_dlm.h>
+#include <obd_support.h>
+#include <interval_tree.h>
+
+enum {
+	INTERVAL_RED = 0,
+	INTERVAL_BLACK = 1
+};
+
+static inline int node_is_left_child(struct interval_node *node)
+{
+	LASSERT(node->in_parent != NULL);
+	return node == node->in_parent->in_left;
+}
+
+static inline int node_is_right_child(struct interval_node *node)
+{
+	LASSERT(node->in_parent != NULL);
+	return node == node->in_parent->in_right;
+}
+
+static inline int node_is_red(struct interval_node *node)
+{
+	return node->in_color == INTERVAL_RED;
+}
+
+static inline int node_is_black(struct interval_node *node)
+{
+	return node->in_color == INTERVAL_BLACK;
+}
+
+static inline int extent_compare(struct interval_node_extent *e1,
+				 struct interval_node_extent *e2)
+{
+	int rc;
+	if (e1->start == e2->start) {
+		if (e1->end < e2->end)
+			rc = -1;
+		else if (e1->end > e2->end)
+			rc = 1;
+		else
+			rc = 0;
+	} else {
+		if (e1->start < e2->start)
+			rc = -1;
+		else
+			rc = 1;
+	}
+	return rc;
+}
+
+static inline int extent_equal(struct interval_node_extent *e1,
+			       struct interval_node_extent *e2)
+{
+	return (e1->start == e2->start) && (e1->end == e2->end);
+}
+
+static inline int extent_overlapped(struct interval_node_extent *e1,
+				    struct interval_node_extent *e2)
+{
+	return (e1->start <= e2->end) && (e2->start <= e1->end);
+}
+
+static inline int node_compare(struct interval_node *n1,
+			       struct interval_node *n2)
+{
+	return extent_compare(&n1->in_extent, &n2->in_extent);
+}
+
+static inline int node_equal(struct interval_node *n1,
+			     struct interval_node *n2)
+{
+	return extent_equal(&n1->in_extent, &n2->in_extent);
+}
+
+static inline __u64 max_u64(__u64 x, __u64 y)
+{
+	return x > y ? x : y;
+}
+
+static inline __u64 min_u64(__u64 x, __u64 y)
+{
+	return x < y ? x : y;
+}
+
+#define interval_for_each(node, root)		   \
+for (node = interval_first(root); node != NULL;	 \
+     node = interval_next(node))
+
+#define interval_for_each_reverse(node, root)	   \
+for (node = interval_last(root); node != NULL;	  \
+     node = interval_prev(node))
+
+static struct interval_node *interval_first(struct interval_node *node)
+{
+	ENTRY;
+
+	if (!node)
+		RETURN(NULL);
+	while (node->in_left)
+		node = node->in_left;
+	RETURN(node);
+}
+
+static struct interval_node *interval_last(struct interval_node *node)
+{
+	ENTRY;
+
+	if (!node)
+		RETURN(NULL);
+	while (node->in_right)
+		node = node->in_right;
+	RETURN(node);
+}
+
+static struct interval_node *interval_next(struct interval_node *node)
+{
+	ENTRY;
+
+	if (!node)
+		RETURN(NULL);
+	if (node->in_right)
+		RETURN(interval_first(node->in_right));
+	while (node->in_parent && node_is_right_child(node))
+		node = node->in_parent;
+	RETURN(node->in_parent);
+}
+
+static struct interval_node *interval_prev(struct interval_node *node)
+{
+	ENTRY;
+
+	if (!node)
+		RETURN(NULL);
+
+	if (node->in_left)
+		RETURN(interval_last(node->in_left));
+
+	while (node->in_parent && node_is_left_child(node))
+		node = node->in_parent;
+
+	RETURN(node->in_parent);
+}
+
+enum interval_iter interval_iterate(struct interval_node *root,
+				    interval_callback_t func,
+				    void *data)
+{
+	struct interval_node *node;
+	enum interval_iter rc = INTERVAL_ITER_CONT;
+	ENTRY;
+
+	interval_for_each(node, root) {
+		rc = func(node, data);
+		if (rc == INTERVAL_ITER_STOP)
+			break;
+	}
+
+	RETURN(rc);
+}
+EXPORT_SYMBOL(interval_iterate);
+
+enum interval_iter interval_iterate_reverse(struct interval_node *root,
+					    interval_callback_t func,
+					    void *data)
+{
+	struct interval_node *node;
+	enum interval_iter rc = INTERVAL_ITER_CONT;
+	ENTRY;
+
+	interval_for_each_reverse(node, root) {
+		rc = func(node, data);
+		if (rc == INTERVAL_ITER_STOP)
+			break;
+	}
+
+	RETURN(rc);
+}
+EXPORT_SYMBOL(interval_iterate_reverse);
+
+/* try to find a node with same interval in the tree,
+ * if found, return the pointer to the node, otherwise return NULL*/
+struct interval_node *interval_find(struct interval_node *root,
+				    struct interval_node_extent *ex)
+{
+	struct interval_node *walk = root;
+	int rc;
+	ENTRY;
+
+	while (walk) {
+		rc = extent_compare(ex, &walk->in_extent);
+		if (rc == 0)
+			break;
+		else if (rc < 0)
+			walk = walk->in_left;
+		else
+			walk = walk->in_right;
+	}
+
+	RETURN(walk);
+}
+EXPORT_SYMBOL(interval_find);
+
+static void __rotate_change_maxhigh(struct interval_node *node,
+				    struct interval_node *rotate)
+{
+	__u64 left_max, right_max;
+
+	rotate->in_max_high = node->in_max_high;
+	left_max = node->in_left ? node->in_left->in_max_high : 0;
+	right_max = node->in_right ? node->in_right->in_max_high : 0;
+	node->in_max_high  = max_u64(interval_high(node),
+				     max_u64(left_max,right_max));
+}
+
+/* The left rotation "pivots" around the link from node to node->right, and
+ * - node will be linked to node->right's left child, and
+ * - node->right's left child will be linked to node's right child.  */
+static void __rotate_left(struct interval_node *node,
+			  struct interval_node **root)
+{
+	struct interval_node *right = node->in_right;
+	struct interval_node *parent = node->in_parent;
+
+	node->in_right = right->in_left;
+	if (node->in_right)
+		right->in_left->in_parent = node;
+
+	right->in_left = node;
+	right->in_parent = parent;
+	if (parent) {
+		if (node_is_left_child(node))
+			parent->in_left = right;
+		else
+			parent->in_right = right;
+	} else {
+		*root = right;
+	}
+	node->in_parent = right;
+
+	/* update max_high for node and right */
+	__rotate_change_maxhigh(node, right);
+}
+
+/* The right rotation "pivots" around the link from node to node->left, and
+ * - node will be linked to node->left's right child, and
+ * - node->left's right child will be linked to node's left child.  */
+static void __rotate_right(struct interval_node *node,
+			   struct interval_node **root)
+{
+	struct interval_node *left = node->in_left;
+	struct interval_node *parent = node->in_parent;
+
+	node->in_left = left->in_right;
+	if (node->in_left)
+		left->in_right->in_parent = node;
+	left->in_right = node;
+
+	left->in_parent = parent;
+	if (parent) {
+		if (node_is_right_child(node))
+			parent->in_right = left;
+		else
+			parent->in_left = left;
+	} else {
+		*root = left;
+	}
+	node->in_parent = left;
+
+	/* update max_high for node and left */
+	__rotate_change_maxhigh(node, left);
+}
+
+#define interval_swap(a, b) do {			\
+	struct interval_node *c = a; a = b; b = c;      \
+} while (0)
+
+/*
+ * Operations INSERT and DELETE, when run on a tree with n keys,
+ * take O(logN) time.Because they modify the tree, the result
+ * may violate the red-black properties.To restore these properties,
+ * we must change the colors of some of the nodes in the tree
+ * and also change the pointer structure.
+ */
+static void interval_insert_color(struct interval_node *node,
+				  struct interval_node **root)
+{
+	struct interval_node *parent, *gparent;
+	ENTRY;
+
+	while ((parent = node->in_parent) && node_is_red(parent)) {
+		gparent = parent->in_parent;
+		/* Parent is RED, so gparent must not be NULL */
+		if (node_is_left_child(parent)) {
+			struct interval_node *uncle;
+			uncle = gparent->in_right;
+			if (uncle && node_is_red(uncle)) {
+				uncle->in_color = INTERVAL_BLACK;
+				parent->in_color = INTERVAL_BLACK;
+				gparent->in_color = INTERVAL_RED;
+				node = gparent;
+				continue;
+			}
+
+			if (parent->in_right == node) {
+				__rotate_left(parent, root);
+				interval_swap(node, parent);
+			}
+
+			parent->in_color = INTERVAL_BLACK;
+			gparent->in_color = INTERVAL_RED;
+			__rotate_right(gparent, root);
+		} else {
+			struct interval_node *uncle;
+			uncle = gparent->in_left;
+			if (uncle && node_is_red(uncle)) {
+				uncle->in_color = INTERVAL_BLACK;
+				parent->in_color = INTERVAL_BLACK;
+				gparent->in_color = INTERVAL_RED;
+				node = gparent;
+				continue;
+			}
+
+			if (node_is_left_child(node)) {
+				__rotate_right(parent, root);
+				interval_swap(node, parent);
+			}
+
+			parent->in_color = INTERVAL_BLACK;
+			gparent->in_color = INTERVAL_RED;
+			__rotate_left(gparent, root);
+		}
+	}
+
+	(*root)->in_color = INTERVAL_BLACK;
+	EXIT;
+}
+
+struct interval_node *interval_insert(struct interval_node *node,
+				      struct interval_node **root)
+
+{
+	struct interval_node **p, *parent = NULL;
+	ENTRY;
+
+	LASSERT(!interval_is_intree(node));
+	p = root;
+	while (*p) {
+		parent = *p;
+		if (node_equal(parent, node))
+			RETURN(parent);
+
+		/* max_high field must be updated after each iteration */
+		if (parent->in_max_high < interval_high(node))
+			parent->in_max_high = interval_high(node);
+
+		if (node_compare(node, parent) < 0)
+			p = &parent->in_left;
+		else
+			p = &parent->in_right;
+	}
+
+	/* link node into the tree */
+	node->in_parent = parent;
+	node->in_color = INTERVAL_RED;
+	node->in_left = node->in_right = NULL;
+	*p = node;
+
+	interval_insert_color(node, root);
+	node->in_intree = 1;
+
+	RETURN(NULL);
+}
+EXPORT_SYMBOL(interval_insert);
+
+static inline int node_is_black_or_0(struct interval_node *node)
+{
+	return !node || node_is_black(node);
+}
+
+static void interval_erase_color(struct interval_node *node,
+				 struct interval_node *parent,
+				 struct interval_node **root)
+{
+	struct interval_node *tmp;
+	ENTRY;
+
+	while (node_is_black_or_0(node) && node != *root) {
+		if (parent->in_left == node) {
+			tmp = parent->in_right;
+			if (node_is_red(tmp)) {
+				tmp->in_color = INTERVAL_BLACK;
+				parent->in_color = INTERVAL_RED;
+				__rotate_left(parent, root);
+				tmp = parent->in_right;
+			}
+			if (node_is_black_or_0(tmp->in_left) &&
+			    node_is_black_or_0(tmp->in_right)) {
+				tmp->in_color = INTERVAL_RED;
+				node = parent;
+				parent = node->in_parent;
+			} else {
+				if (node_is_black_or_0(tmp->in_right)) {
+					struct interval_node *o_left;
+					if ((o_left = tmp->in_left))
+					     o_left->in_color = INTERVAL_BLACK;
+					tmp->in_color = INTERVAL_RED;
+					__rotate_right(tmp, root);
+					tmp = parent->in_right;
+				}
+				tmp->in_color = parent->in_color;
+				parent->in_color = INTERVAL_BLACK;
+				if (tmp->in_right)
+				    tmp->in_right->in_color = INTERVAL_BLACK;
+				__rotate_left(parent, root);
+				node = *root;
+				break;
+			}
+		} else {
+			tmp = parent->in_left;
+			if (node_is_red(tmp)) {
+				tmp->in_color = INTERVAL_BLACK;
+				parent->in_color = INTERVAL_RED;
+				__rotate_right(parent, root);
+				tmp = parent->in_left;
+			}
+			if (node_is_black_or_0(tmp->in_left) &&
+			    node_is_black_or_0(tmp->in_right)) {
+				tmp->in_color = INTERVAL_RED;
+				node = parent;
+				parent = node->in_parent;
+			} else {
+				if (node_is_black_or_0(tmp->in_left)) {
+					struct interval_node *o_right;
+					if ((o_right = tmp->in_right))
+					    o_right->in_color = INTERVAL_BLACK;
+					tmp->in_color = INTERVAL_RED;
+					__rotate_left(tmp, root);
+					tmp = parent->in_left;
+				}
+				tmp->in_color = parent->in_color;
+				parent->in_color = INTERVAL_BLACK;
+				if (tmp->in_left)
+					tmp->in_left->in_color = INTERVAL_BLACK;
+				__rotate_right(parent, root);
+				node = *root;
+				break;
+			}
+		}
+	}
+	if (node)
+		node->in_color = INTERVAL_BLACK;
+	EXIT;
+}
+
+/*
+ * if the @max_high value of @node is changed, this function traverse  a path
+ * from node  up to the root to update max_high for the whole tree.
+ */
+static void update_maxhigh(struct interval_node *node,
+			   __u64  old_maxhigh)
+{
+	__u64 left_max, right_max;
+	ENTRY;
+
+	while (node) {
+		left_max = node->in_left ? node->in_left->in_max_high : 0;
+		right_max = node->in_right ? node->in_right->in_max_high : 0;
+		node->in_max_high = max_u64(interval_high(node),
+					    max_u64(left_max, right_max));
+
+		if (node->in_max_high >= old_maxhigh)
+			break;
+		node = node->in_parent;
+	}
+	EXIT;
+}
+
+void interval_erase(struct interval_node *node,
+		    struct interval_node **root)
+{
+	struct interval_node *child, *parent;
+	int color;
+	ENTRY;
+
+	LASSERT(interval_is_intree(node));
+	node->in_intree = 0;
+	if (!node->in_left) {
+		child = node->in_right;
+	} else if (!node->in_right) {
+		child = node->in_left;
+	} else { /* Both left and right child are not NULL */
+		struct interval_node *old = node;
+
+		node = interval_next(node);
+		child = node->in_right;
+		parent = node->in_parent;
+		color = node->in_color;
+
+		if (child)
+			child->in_parent = parent;
+		if (parent == old)
+			parent->in_right = child;
+		else
+			parent->in_left = child;
+
+		node->in_color = old->in_color;
+		node->in_right = old->in_right;
+		node->in_left = old->in_left;
+		node->in_parent = old->in_parent;
+
+		if (old->in_parent) {
+			if (node_is_left_child(old))
+				old->in_parent->in_left = node;
+			else
+				old->in_parent->in_right = node;
+		} else {
+			*root = node;
+		}
+
+		old->in_left->in_parent = node;
+		if (old->in_right)
+			old->in_right->in_parent = node;
+		update_maxhigh(child ? : parent, node->in_max_high);
+		update_maxhigh(node, old->in_max_high);
+		if (parent == old)
+			 parent = node;
+		goto color;
+	}
+	parent = node->in_parent;
+	color = node->in_color;
+
+	if (child)
+		child->in_parent = parent;
+	if (parent) {
+		if (node_is_left_child(node))
+			parent->in_left = child;
+		else
+			parent->in_right = child;
+	} else {
+		*root = child;
+	}
+
+	update_maxhigh(child ? : parent, node->in_max_high);
+
+color:
+	if (color == INTERVAL_BLACK)
+		interval_erase_color(child, parent, root);
+	EXIT;
+}
+EXPORT_SYMBOL(interval_erase);
+
+static inline int interval_may_overlap(struct interval_node *node,
+					  struct interval_node_extent *ext)
+{
+	return (ext->start <= node->in_max_high &&
+		ext->end >= interval_low(node));
+}
+
+/*
+ * This function finds all intervals that overlap interval ext,
+ * and calls func to handle resulted intervals one by one.
+ * in lustre, this function will find all conflicting locks in
+ * the granted queue and add these locks to the ast work list.
+ *
+ * {
+ *       if (node == NULL)
+ *	       return 0;
+ *       if (ext->end < interval_low(node)) {
+ *	       interval_search(node->in_left, ext, func, data);
+ *       } else if (interval_may_overlap(node, ext)) {
+ *	       if (extent_overlapped(ext, &node->in_extent))
+ *		       func(node, data);
+ *	       interval_search(node->in_left, ext, func, data);
+ *	       interval_search(node->in_right, ext, func, data);
+ *       }
+ *       return 0;
+ * }
+ *
+ */
+enum interval_iter interval_search(struct interval_node *node,
+				   struct interval_node_extent *ext,
+				   interval_callback_t func,
+				   void *data)
+{
+	struct interval_node *parent;
+	enum interval_iter rc = INTERVAL_ITER_CONT;
+
+	LASSERT(ext != NULL);
+	LASSERT(func != NULL);
+
+	while (node) {
+		if (ext->end < interval_low(node)) {
+			if (node->in_left) {
+				node = node->in_left;
+				continue;
+			}
+		} else if (interval_may_overlap(node, ext)) {
+			if (extent_overlapped(ext, &node->in_extent)) {
+				rc = func(node, data);
+				if (rc == INTERVAL_ITER_STOP)
+					break;
+			}
+
+			if (node->in_left) {
+				node = node->in_left;
+				continue;
+			}
+			if (node->in_right) {
+				node = node->in_right;
+				continue;
+			}
+		}
+
+		parent = node->in_parent;
+		while (parent) {
+			if (node_is_left_child(node) &&
+			    parent->in_right) {
+				/* If we ever got the left, it means that the
+				 * parent met ext->end<interval_low(parent), or
+				 * may_overlap(parent). If the former is true,
+				 * we needn't go back. So stop early and check
+				 * may_overlap(parent) after this loop.  */
+				node = parent->in_right;
+				break;
+			}
+			node = parent;
+			parent = parent->in_parent;
+		}
+		if (parent == NULL || !interval_may_overlap(parent, ext))
+			break;
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(interval_search);
+
+static enum interval_iter interval_overlap_cb(struct interval_node *n,
+					      void *args)
+{
+	*(int *)args = 1;
+	return INTERVAL_ITER_STOP;
+}
+
+int interval_is_overlapped(struct interval_node *root,
+			   struct interval_node_extent *ext)
+{
+	int has = 0;
+	(void)interval_search(root, ext, interval_overlap_cb, &has);
+	return has;
+}
+EXPORT_SYMBOL(interval_is_overlapped);
+
+/* Don't expand to low. Expanding downwards is expensive, and meaningless to
+ * some extents, because programs seldom do IO backward.
+ *
+ * The recursive algorithm of expanding low:
+ * expand_low {
+ *	struct interval_node *tmp;
+ *	static __u64 res = 0;
+ *
+ *	if (root == NULL)
+ *		return res;
+ *	if (root->in_max_high < low) {
+ *		res = max_u64(root->in_max_high + 1, res);
+ *		return res;
+ *	} else if (low < interval_low(root)) {
+ *		interval_expand_low(root->in_left, low);
+ *		return res;
+ *	}
+ *
+ *	if (interval_high(root) < low)
+ *		res = max_u64(interval_high(root) + 1, res);
+ *	interval_expand_low(root->in_left, low);
+ *	interval_expand_low(root->in_right, low);
+ *
+ *	return res;
+ * }
+ *
+ * It's much easy to eliminate the recursion, see interval_search for
+ * an example. -jay
+ */
+static inline __u64 interval_expand_low(struct interval_node *root, __u64 low)
+{
+	/* we only concern the empty tree right now. */
+	if (root == NULL)
+		return 0;
+	return low;
+}
+
+static inline __u64 interval_expand_high(struct interval_node *node, __u64 high)
+{
+	__u64 result = ~0;
+
+	while (node != NULL) {
+		if (node->in_max_high < high)
+			break;
+
+		if (interval_low(node) > high) {
+			result = interval_low(node) - 1;
+			node = node->in_left;
+		} else {
+			node = node->in_right;
+		}
+	}
+
+	return result;
+}
+
+/* expanding the extent based on @ext. */
+void interval_expand(struct interval_node *root,
+		     struct interval_node_extent *ext,
+		     struct interval_node_extent *limiter)
+{
+	/* The assertion of interval_is_overlapped is expensive because we may
+	 * travel many nodes to find the overlapped node. */
+	LASSERT(interval_is_overlapped(root, ext) == 0);
+	if (!limiter || limiter->start < ext->start)
+		ext->start = interval_expand_low(root, ext->start);
+	if (!limiter || limiter->end > ext->end)
+		ext->end = interval_expand_high(root, ext->end);
+	LASSERT(interval_is_overlapped(root, ext) == 0);
+}
+EXPORT_SYMBOL(interval_expand);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,242 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2010, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/ldlm/ldlm_extent.c
+ *
+ * Author: Peter Braam <braam@clusterfs.com>
+ * Author: Phil Schwan <phil@clusterfs.com>
+ */
+
+/**
+ * This file contains implementation of EXTENT lock type
+ *
+ * EXTENT lock type is for locking a contiguous range of values, represented
+ * by 64-bit starting and ending offsets (inclusive). There are several extent
+ * lock modes, some of which may be mutually incompatible. Extent locks are
+ * considered incompatible if their modes are incompatible and their extents
+ * intersect.  See the lock mode compatibility matrix in lustre_dlm.h.
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+# include <linux/libcfs/libcfs.h>
+
+#include <lustre_dlm.h>
+#include <obd_support.h>
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_lib.h>
+
+#include "ldlm_internal.h"
+
+
+/* When a lock is cancelled by a client, the KMS may undergo change if this
+ * is the "highest lock".  This function returns the new KMS value.
+ * Caller must hold lr_lock already.
+ *
+ * NB: A lock on [x,y] protects a KMS of up to y + 1 bytes! */
+__u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, __u64 old_kms)
+{
+	struct ldlm_resource *res = lock->l_resource;
+	struct list_head *tmp;
+	struct ldlm_lock *lck;
+	__u64 kms = 0;
+	ENTRY;
+
+	/* don't let another thread in ldlm_extent_shift_kms race in
+	 * just after we finish and take our lock into account in its
+	 * calculation of the kms */
+	lock->l_flags |= LDLM_FL_KMS_IGNORE;
+
+	list_for_each(tmp, &res->lr_granted) {
+		lck = list_entry(tmp, struct ldlm_lock, l_res_link);
+
+		if (lck->l_flags & LDLM_FL_KMS_IGNORE)
+			continue;
+
+		if (lck->l_policy_data.l_extent.end >= old_kms)
+			RETURN(old_kms);
+
+		/* This extent _has_ to be smaller than old_kms (checked above)
+		 * so kms can only ever be smaller or the same as old_kms. */
+		if (lck->l_policy_data.l_extent.end + 1 > kms)
+			kms = lck->l_policy_data.l_extent.end + 1;
+	}
+	LASSERTF(kms <= old_kms, "kms "LPU64" old_kms "LPU64"\n", kms, old_kms);
+
+	RETURN(kms);
+}
+EXPORT_SYMBOL(ldlm_extent_shift_kms);
+
+struct kmem_cache *ldlm_interval_slab;
+struct ldlm_interval *ldlm_interval_alloc(struct ldlm_lock *lock)
+{
+	struct ldlm_interval *node;
+	ENTRY;
+
+	LASSERT(lock->l_resource->lr_type == LDLM_EXTENT);
+	OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, __GFP_IO);
+	if (node == NULL)
+		RETURN(NULL);
+
+	INIT_LIST_HEAD(&node->li_group);
+	ldlm_interval_attach(node, lock);
+	RETURN(node);
+}
+
+void ldlm_interval_free(struct ldlm_interval *node)
+{
+	if (node) {
+		LASSERT(list_empty(&node->li_group));
+		LASSERT(!interval_is_intree(&node->li_node));
+		OBD_SLAB_FREE(node, ldlm_interval_slab, sizeof(*node));
+	}
+}
+
+/* interval tree, for LDLM_EXTENT. */
+void ldlm_interval_attach(struct ldlm_interval *n,
+			  struct ldlm_lock *l)
+{
+	LASSERT(l->l_tree_node == NULL);
+	LASSERT(l->l_resource->lr_type == LDLM_EXTENT);
+
+	list_add_tail(&l->l_sl_policy, &n->li_group);
+	l->l_tree_node = n;
+}
+
+struct ldlm_interval *ldlm_interval_detach(struct ldlm_lock *l)
+{
+	struct ldlm_interval *n = l->l_tree_node;
+
+	if (n == NULL)
+		return NULL;
+
+	LASSERT(!list_empty(&n->li_group));
+	l->l_tree_node = NULL;
+	list_del_init(&l->l_sl_policy);
+
+	return (list_empty(&n->li_group) ? n : NULL);
+}
+
+static inline int lock_mode_to_index(ldlm_mode_t mode)
+{
+	int index;
+
+	LASSERT(mode != 0);
+	LASSERT(IS_PO2(mode));
+	for (index = -1; mode; index++, mode >>= 1) ;
+	LASSERT(index < LCK_MODE_NUM);
+	return index;
+}
+
+/** Add newly granted lock into interval tree for the resource. */
+void ldlm_extent_add_lock(struct ldlm_resource *res,
+			  struct ldlm_lock *lock)
+{
+	struct interval_node *found, **root;
+	struct ldlm_interval *node;
+	struct ldlm_extent *extent;
+	int idx;
+
+	LASSERT(lock->l_granted_mode == lock->l_req_mode);
+
+	node = lock->l_tree_node;
+	LASSERT(node != NULL);
+	LASSERT(!interval_is_intree(&node->li_node));
+
+	idx = lock_mode_to_index(lock->l_granted_mode);
+	LASSERT(lock->l_granted_mode == 1 << idx);
+	LASSERT(lock->l_granted_mode == res->lr_itree[idx].lit_mode);
+
+	/* node extent initialize */
+	extent = &lock->l_policy_data.l_extent;
+	interval_set(&node->li_node, extent->start, extent->end);
+
+	root = &res->lr_itree[idx].lit_root;
+	found = interval_insert(&node->li_node, root);
+	if (found) { /* The policy group found. */
+		struct ldlm_interval *tmp = ldlm_interval_detach(lock);
+		LASSERT(tmp != NULL);
+		ldlm_interval_free(tmp);
+		ldlm_interval_attach(to_ldlm_interval(found), lock);
+	}
+	res->lr_itree[idx].lit_size++;
+
+	/* even though we use interval tree to manage the extent lock, we also
+	 * add the locks into grant list, for debug purpose, .. */
+	ldlm_resource_add_lock(res, &res->lr_granted, lock);
+}
+
+/** Remove cancelled lock from resource interval tree. */
+void ldlm_extent_unlink_lock(struct ldlm_lock *lock)
+{
+	struct ldlm_resource *res = lock->l_resource;
+	struct ldlm_interval *node = lock->l_tree_node;
+	struct ldlm_interval_tree *tree;
+	int idx;
+
+	if (!node || !interval_is_intree(&node->li_node)) /* duplicate unlink */
+		return;
+
+	idx = lock_mode_to_index(lock->l_granted_mode);
+	LASSERT(lock->l_granted_mode == 1 << idx);
+	tree = &res->lr_itree[idx];
+
+	LASSERT(tree->lit_root != NULL); /* assure the tree is not null */
+
+	tree->lit_size--;
+	node = ldlm_interval_detach(lock);
+	if (node) {
+		interval_erase(&node->li_node, &tree->lit_root);
+		ldlm_interval_free(node);
+	}
+}
+
+void ldlm_extent_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				     ldlm_policy_data_t *lpolicy)
+{
+	memset(lpolicy, 0, sizeof(*lpolicy));
+	lpolicy->l_extent.start = wpolicy->l_extent.start;
+	lpolicy->l_extent.end = wpolicy->l_extent.end;
+	lpolicy->l_extent.gid = wpolicy->l_extent.gid;
+}
+
+void ldlm_extent_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
+				     ldlm_wire_policy_data_t *wpolicy)
+{
+	memset(wpolicy, 0, sizeof(*wpolicy));
+	wpolicy->l_extent.start = lpolicy->l_extent.start;
+	wpolicy->l_extent.end = lpolicy->l_extent.end;
+	wpolicy->l_extent.gid = lpolicy->l_extent.gid;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,849 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003 Hewlett-Packard Development Company LP.
+ * Developed under the sponsorship of the US Government under
+ * Subcontract No. B514193
+ *
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2010, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+/**
+ * This file implements POSIX lock type for Lustre.
+ * Its policy properties are start and end of extent and PID.
+ *
+ * These locks are only done through MDS due to POSIX semantics requiring
+ * e.g. that locks could be only partially released and as such split into
+ * two parts, and also that two adjacent locks from the same process may be
+ * merged into a single wider lock.
+ *
+ * Lock modes are mapped like this:
+ * PR and PW for READ and WRITE locks
+ * NL to request a releasing of a portion of the lock
+ *
+ * These flock locks never timeout.
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+#include <lustre_dlm.h>
+#include <obd_support.h>
+#include <obd_class.h>
+#include <lustre_lib.h>
+#include <linux/list.h>
+
+#include "ldlm_internal.h"
+
+int ldlm_flock_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
+			    void *data, int flag);
+
+/**
+ * list_for_remaining_safe - iterate over the remaining entries in a list
+ *	      and safeguard against removal of a list entry.
+ * \param pos   the &struct list_head to use as a loop counter. pos MUST
+ *	      have been initialized prior to using it in this macro.
+ * \param n     another &struct list_head to use as temporary storage
+ * \param head  the head for your list.
+ */
+#define list_for_remaining_safe(pos, n, head) \
+	for (n = pos->next; pos != (head); pos = n, n = pos->next)
+
+static inline int
+ldlm_same_flock_owner(struct ldlm_lock *lock, struct ldlm_lock *new)
+{
+	return((new->l_policy_data.l_flock.owner ==
+		lock->l_policy_data.l_flock.owner) &&
+	       (new->l_export == lock->l_export));
+}
+
+static inline int
+ldlm_flocks_overlap(struct ldlm_lock *lock, struct ldlm_lock *new)
+{
+	return((new->l_policy_data.l_flock.start <=
+		lock->l_policy_data.l_flock.end) &&
+	       (new->l_policy_data.l_flock.end >=
+		lock->l_policy_data.l_flock.start));
+}
+
+static inline int ldlm_flock_blocking_link(struct ldlm_lock *req,
+					   struct ldlm_lock *lock)
+{
+	int rc = 0;
+
+	/* For server only */
+	if (req->l_export == NULL)
+		return 0;
+
+	if (unlikely(req->l_export->exp_flock_hash == NULL)) {
+		rc = ldlm_init_flock_export(req->l_export);
+		if (rc)
+			goto error;
+	}
+
+	LASSERT(hlist_unhashed(&req->l_exp_flock_hash));
+
+	req->l_policy_data.l_flock.blocking_owner =
+		lock->l_policy_data.l_flock.owner;
+	req->l_policy_data.l_flock.blocking_export =
+		lock->l_export;
+	req->l_policy_data.l_flock.blocking_refs = 0;
+
+	cfs_hash_add(req->l_export->exp_flock_hash,
+		     &req->l_policy_data.l_flock.owner,
+		     &req->l_exp_flock_hash);
+error:
+	return rc;
+}
+
+static inline void ldlm_flock_blocking_unlink(struct ldlm_lock *req)
+{
+	/* For server only */
+	if (req->l_export == NULL)
+		return;
+
+	check_res_locked(req->l_resource);
+	if (req->l_export->exp_flock_hash != NULL &&
+	    !hlist_unhashed(&req->l_exp_flock_hash))
+		cfs_hash_del(req->l_export->exp_flock_hash,
+			     &req->l_policy_data.l_flock.owner,
+			     &req->l_exp_flock_hash);
+}
+
+static inline void
+ldlm_flock_destroy(struct ldlm_lock *lock, ldlm_mode_t mode, __u64 flags)
+{
+	ENTRY;
+
+	LDLM_DEBUG(lock, "ldlm_flock_destroy(mode: %d, flags: 0x%llx)",
+		   mode, flags);
+
+	/* Safe to not lock here, since it should be empty anyway */
+	LASSERT(hlist_unhashed(&lock->l_exp_flock_hash));
+
+	list_del_init(&lock->l_res_link);
+	if (flags == LDLM_FL_WAIT_NOREPROC &&
+	    !(lock->l_flags & LDLM_FL_FAILED)) {
+		/* client side - set a flag to prevent sending a CANCEL */
+		lock->l_flags |= LDLM_FL_LOCAL_ONLY | LDLM_FL_CBPENDING;
+
+		/* when reaching here, it is under lock_res_and_lock(). Thus,
+		   need call the nolock version of ldlm_lock_decref_internal*/
+		ldlm_lock_decref_internal_nolock(lock, mode);
+	}
+
+	ldlm_lock_destroy_nolock(lock);
+	EXIT;
+}
+
+/**
+ * POSIX locks deadlock detection code.
+ *
+ * Given a new lock \a req and an existing lock \a bl_lock it conflicts
+ * with, we need to iterate through all blocked POSIX locks for this
+ * export and see if there is a deadlock condition arising. (i.e. when
+ * one client holds a lock on something and want a lock on something
+ * else and at the same time another client has the opposite situation).
+ */
+static int
+ldlm_flock_deadlock(struct ldlm_lock *req, struct ldlm_lock *bl_lock)
+{
+	struct obd_export *req_exp = req->l_export;
+	struct obd_export *bl_exp = bl_lock->l_export;
+	__u64 req_owner = req->l_policy_data.l_flock.owner;
+	__u64 bl_owner = bl_lock->l_policy_data.l_flock.owner;
+
+	/* For server only */
+	if (req_exp == NULL)
+		return 0;
+
+	class_export_get(bl_exp);
+	while (1) {
+		struct obd_export *bl_exp_new;
+		struct ldlm_lock *lock = NULL;
+		struct ldlm_flock *flock;
+
+		if (bl_exp->exp_flock_hash != NULL)
+			lock = cfs_hash_lookup(bl_exp->exp_flock_hash,
+					       &bl_owner);
+		if (lock == NULL)
+			break;
+
+		flock = &lock->l_policy_data.l_flock;
+		LASSERT(flock->owner == bl_owner);
+		bl_owner = flock->blocking_owner;
+		bl_exp_new = class_export_get(flock->blocking_export);
+		class_export_put(bl_exp);
+
+		cfs_hash_put(bl_exp->exp_flock_hash, &lock->l_exp_flock_hash);
+		bl_exp = bl_exp_new;
+
+		if (bl_owner == req_owner && bl_exp == req_exp) {
+			class_export_put(bl_exp);
+			return 1;
+		}
+	}
+	class_export_put(bl_exp);
+
+	return 0;
+}
+
+/**
+ * Process a granting attempt for flock lock.
+ * Must be called under ns lock held.
+ *
+ * This function looks for any conflicts for \a lock in the granted or
+ * waiting queues. The lock is granted if no conflicts are found in
+ * either queue.
+ *
+ * It is also responsible for splitting a lock if a portion of the lock
+ * is released.
+ *
+ * If \a first_enq is 0 (ie, called from ldlm_reprocess_queue):
+ *   - blocking ASTs have already been sent
+ *
+ * If \a first_enq is 1 (ie, called from ldlm_lock_enqueue):
+ *   - blocking ASTs have not been sent yet, so list of conflicting locks
+ *     would be collected and ASTs sent.
+ */
+int
+ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags, int first_enq,
+			ldlm_error_t *err, struct list_head *work_list)
+{
+	struct ldlm_resource *res = req->l_resource;
+	struct ldlm_namespace *ns = ldlm_res_to_ns(res);
+	struct list_head *tmp;
+	struct list_head *ownlocks = NULL;
+	struct ldlm_lock *lock = NULL;
+	struct ldlm_lock *new = req;
+	struct ldlm_lock *new2 = NULL;
+	ldlm_mode_t mode = req->l_req_mode;
+	int local = ns_is_client(ns);
+	int added = (mode == LCK_NL);
+	int overlaps = 0;
+	int splitted = 0;
+	const struct ldlm_callback_suite null_cbs = { NULL };
+	int rc;
+	ENTRY;
+
+	CDEBUG(D_DLMTRACE, "flags %#llx owner "LPU64" pid %u mode %u start "
+	       LPU64" end "LPU64"\n", *flags,
+	       new->l_policy_data.l_flock.owner,
+	       new->l_policy_data.l_flock.pid, mode,
+	       req->l_policy_data.l_flock.start,
+	       req->l_policy_data.l_flock.end);
+
+	*err = ELDLM_OK;
+
+	if (local) {
+		/* No blocking ASTs are sent to the clients for
+		 * Posix file & record locks */
+		req->l_blocking_ast = NULL;
+	} else {
+		/* Called on the server for lock cancels. */
+		req->l_blocking_ast = ldlm_flock_blocking_ast;
+	}
+
+reprocess:
+	if ((*flags == LDLM_FL_WAIT_NOREPROC) || (mode == LCK_NL)) {
+		/* This loop determines where this processes locks start
+		 * in the resource lr_granted list. */
+		list_for_each(tmp, &res->lr_granted) {
+			lock = list_entry(tmp, struct ldlm_lock,
+					      l_res_link);
+			if (ldlm_same_flock_owner(lock, req)) {
+				ownlocks = tmp;
+				break;
+			}
+		}
+	} else {
+		lockmode_verify(mode);
+
+		/* This loop determines if there are existing locks
+		 * that conflict with the new lock request. */
+		list_for_each(tmp, &res->lr_granted) {
+			lock = list_entry(tmp, struct ldlm_lock,
+					      l_res_link);
+
+			if (ldlm_same_flock_owner(lock, req)) {
+				if (!ownlocks)
+					ownlocks = tmp;
+				continue;
+			}
+
+			/* locks are compatible, overlap doesn't matter */
+			if (lockmode_compat(lock->l_granted_mode, mode))
+				continue;
+
+			if (!ldlm_flocks_overlap(lock, req))
+				continue;
+
+			if (!first_enq)
+				RETURN(LDLM_ITER_CONTINUE);
+
+			if (*flags & LDLM_FL_BLOCK_NOWAIT) {
+				ldlm_flock_destroy(req, mode, *flags);
+				*err = -EAGAIN;
+				RETURN(LDLM_ITER_STOP);
+			}
+
+			if (*flags & LDLM_FL_TEST_LOCK) {
+				ldlm_flock_destroy(req, mode, *flags);
+				req->l_req_mode = lock->l_granted_mode;
+				req->l_policy_data.l_flock.pid =
+					lock->l_policy_data.l_flock.pid;
+				req->l_policy_data.l_flock.start =
+					lock->l_policy_data.l_flock.start;
+				req->l_policy_data.l_flock.end =
+					lock->l_policy_data.l_flock.end;
+				*flags |= LDLM_FL_LOCK_CHANGED;
+				RETURN(LDLM_ITER_STOP);
+			}
+
+			if (ldlm_flock_deadlock(req, lock)) {
+				ldlm_flock_destroy(req, mode, *flags);
+				*err = -EDEADLK;
+				RETURN(LDLM_ITER_STOP);
+			}
+
+			rc = ldlm_flock_blocking_link(req, lock);
+			if (rc) {
+				ldlm_flock_destroy(req, mode, *flags);
+				*err = rc;
+				RETURN(LDLM_ITER_STOP);
+			}
+			ldlm_resource_add_lock(res, &res->lr_waiting, req);
+			*flags |= LDLM_FL_BLOCK_GRANTED;
+			RETURN(LDLM_ITER_STOP);
+		}
+	}
+
+	if (*flags & LDLM_FL_TEST_LOCK) {
+		ldlm_flock_destroy(req, mode, *flags);
+		req->l_req_mode = LCK_NL;
+		*flags |= LDLM_FL_LOCK_CHANGED;
+		RETURN(LDLM_ITER_STOP);
+	}
+
+	/* In case we had slept on this lock request take it off of the
+	 * deadlock detection hash list. */
+	ldlm_flock_blocking_unlink(req);
+
+	/* Scan the locks owned by this process that overlap this request.
+	 * We may have to merge or split existing locks. */
+
+	if (!ownlocks)
+		ownlocks = &res->lr_granted;
+
+	list_for_remaining_safe(ownlocks, tmp, &res->lr_granted) {
+		lock = list_entry(ownlocks, struct ldlm_lock, l_res_link);
+
+		if (!ldlm_same_flock_owner(lock, new))
+			break;
+
+		if (lock->l_granted_mode == mode) {
+			/* If the modes are the same then we need to process
+			 * locks that overlap OR adjoin the new lock. The extra
+			 * logic condition is necessary to deal with arithmetic
+			 * overflow and underflow. */
+			if ((new->l_policy_data.l_flock.start >
+			     (lock->l_policy_data.l_flock.end + 1))
+			    && (lock->l_policy_data.l_flock.end !=
+				OBD_OBJECT_EOF))
+				continue;
+
+			if ((new->l_policy_data.l_flock.end <
+			     (lock->l_policy_data.l_flock.start - 1))
+			    && (lock->l_policy_data.l_flock.start != 0))
+				break;
+
+			if (new->l_policy_data.l_flock.start <
+			    lock->l_policy_data.l_flock.start) {
+				lock->l_policy_data.l_flock.start =
+					new->l_policy_data.l_flock.start;
+			} else {
+				new->l_policy_data.l_flock.start =
+					lock->l_policy_data.l_flock.start;
+			}
+
+			if (new->l_policy_data.l_flock.end >
+			    lock->l_policy_data.l_flock.end) {
+				lock->l_policy_data.l_flock.end =
+					new->l_policy_data.l_flock.end;
+			} else {
+				new->l_policy_data.l_flock.end =
+					lock->l_policy_data.l_flock.end;
+			}
+
+			if (added) {
+				ldlm_flock_destroy(lock, mode, *flags);
+			} else {
+				new = lock;
+				added = 1;
+			}
+			continue;
+		}
+
+		if (new->l_policy_data.l_flock.start >
+		    lock->l_policy_data.l_flock.end)
+			continue;
+
+		if (new->l_policy_data.l_flock.end <
+		    lock->l_policy_data.l_flock.start)
+			break;
+
+		++overlaps;
+
+		if (new->l_policy_data.l_flock.start <=
+		    lock->l_policy_data.l_flock.start) {
+			if (new->l_policy_data.l_flock.end <
+			    lock->l_policy_data.l_flock.end) {
+				lock->l_policy_data.l_flock.start =
+					new->l_policy_data.l_flock.end + 1;
+				break;
+			}
+			ldlm_flock_destroy(lock, lock->l_req_mode, *flags);
+			continue;
+		}
+		if (new->l_policy_data.l_flock.end >=
+		    lock->l_policy_data.l_flock.end) {
+			lock->l_policy_data.l_flock.end =
+				new->l_policy_data.l_flock.start - 1;
+			continue;
+		}
+
+		/* split the existing lock into two locks */
+
+		/* if this is an F_UNLCK operation then we could avoid
+		 * allocating a new lock and use the req lock passed in
+		 * with the request but this would complicate the reply
+		 * processing since updates to req get reflected in the
+		 * reply. The client side replays the lock request so
+		 * it must see the original lock data in the reply. */
+
+		/* XXX - if ldlm_lock_new() can sleep we should
+		 * release the lr_lock, allocate the new lock,
+		 * and restart processing this lock. */
+		if (!new2) {
+			unlock_res_and_lock(req);
+			new2 = ldlm_lock_create(ns, &res->lr_name, LDLM_FLOCK,
+						lock->l_granted_mode, &null_cbs,
+						NULL, 0, LVB_T_NONE);
+			lock_res_and_lock(req);
+			if (!new2) {
+				ldlm_flock_destroy(req, lock->l_granted_mode,
+						   *flags);
+				*err = -ENOLCK;
+				RETURN(LDLM_ITER_STOP);
+			}
+			goto reprocess;
+		}
+
+		splitted = 1;
+
+		new2->l_granted_mode = lock->l_granted_mode;
+		new2->l_policy_data.l_flock.pid =
+			new->l_policy_data.l_flock.pid;
+		new2->l_policy_data.l_flock.owner =
+			new->l_policy_data.l_flock.owner;
+		new2->l_policy_data.l_flock.start =
+			lock->l_policy_data.l_flock.start;
+		new2->l_policy_data.l_flock.end =
+			new->l_policy_data.l_flock.start - 1;
+		lock->l_policy_data.l_flock.start =
+			new->l_policy_data.l_flock.end + 1;
+		new2->l_conn_export = lock->l_conn_export;
+		if (lock->l_export != NULL) {
+			new2->l_export = class_export_lock_get(lock->l_export, new2);
+			if (new2->l_export->exp_lock_hash &&
+			    hlist_unhashed(&new2->l_exp_hash))
+				cfs_hash_add(new2->l_export->exp_lock_hash,
+					     &new2->l_remote_handle,
+					     &new2->l_exp_hash);
+		}
+		if (*flags == LDLM_FL_WAIT_NOREPROC)
+			ldlm_lock_addref_internal_nolock(new2,
+							 lock->l_granted_mode);
+
+		/* insert new2 at lock */
+		ldlm_resource_add_lock(res, ownlocks, new2);
+		LDLM_LOCK_RELEASE(new2);
+		break;
+	}
+
+	/* if new2 is created but never used, destroy it*/
+	if (splitted == 0 && new2 != NULL)
+		ldlm_lock_destroy_nolock(new2);
+
+	/* At this point we're granting the lock request. */
+	req->l_granted_mode = req->l_req_mode;
+
+	/* Add req to the granted queue before calling ldlm_reprocess_all(). */
+	if (!added) {
+		list_del_init(&req->l_res_link);
+		/* insert new lock before ownlocks in list. */
+		ldlm_resource_add_lock(res, ownlocks, req);
+	}
+
+	if (*flags != LDLM_FL_WAIT_NOREPROC) {
+		/* The only one possible case for client-side calls flock
+		 * policy function is ldlm_flock_completion_ast inside which
+		 * carries LDLM_FL_WAIT_NOREPROC flag. */
+		CERROR("Illegal parameter for client-side-only module.\n");
+		LBUG();
+	}
+
+	/* In case we're reprocessing the requested lock we can't destroy
+	 * it until after calling ldlm_add_ast_work_item() above so that laawi()
+	 * can bump the reference count on \a req. Otherwise \a req
+	 * could be freed before the completion AST can be sent.  */
+	if (added)
+		ldlm_flock_destroy(req, mode, *flags);
+
+	ldlm_resource_dump(D_INFO, res);
+	RETURN(LDLM_ITER_CONTINUE);
+}
+
+struct ldlm_flock_wait_data {
+	struct ldlm_lock *fwd_lock;
+	int	       fwd_generation;
+};
+
+static void
+ldlm_flock_interrupted_wait(void *data)
+{
+	struct ldlm_lock *lock;
+	ENTRY;
+
+	lock = ((struct ldlm_flock_wait_data *)data)->fwd_lock;
+
+	/* take lock off the deadlock detection hash list. */
+	lock_res_and_lock(lock);
+	ldlm_flock_blocking_unlink(lock);
+
+	/* client side - set flag to prevent lock from being put on LRU list */
+	lock->l_flags |= LDLM_FL_CBPENDING;
+	unlock_res_and_lock(lock);
+
+	EXIT;
+}
+
+/**
+ * Flock completion callback function.
+ *
+ * \param lock [in,out]: A lock to be handled
+ * \param flags    [in]: flags
+ * \param *data    [in]: ldlm_work_cp_ast_lock() will use ldlm_cb_set_arg
+ *
+ * \retval 0    : success
+ * \retval <0   : failure
+ */
+int
+ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
+{
+	struct file_lock		*getlk = lock->l_ast_data;
+	struct obd_device	      *obd;
+	struct obd_import	      *imp = NULL;
+	struct ldlm_flock_wait_data     fwd;
+	struct l_wait_info	      lwi;
+	ldlm_error_t		    err;
+	int			     rc = 0;
+	ENTRY;
+
+	CDEBUG(D_DLMTRACE, "flags: 0x%llx data: %p getlk: %p\n",
+	       flags, data, getlk);
+
+	/* Import invalidation. We need to actually release the lock
+	 * references being held, so that it can go away. No point in
+	 * holding the lock even if app still believes it has it, since
+	 * server already dropped it anyway. Only for granted locks too. */
+	if ((lock->l_flags & (LDLM_FL_FAILED|LDLM_FL_LOCAL_ONLY)) ==
+	    (LDLM_FL_FAILED|LDLM_FL_LOCAL_ONLY)) {
+		if (lock->l_req_mode == lock->l_granted_mode &&
+		    lock->l_granted_mode != LCK_NL &&
+		    NULL == data)
+			ldlm_lock_decref_internal(lock, lock->l_req_mode);
+
+		/* Need to wake up the waiter if we were evicted */
+		wake_up(&lock->l_waitq);
+		RETURN(0);
+	}
+
+	LASSERT(flags != LDLM_FL_WAIT_NOREPROC);
+
+	if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
+		       LDLM_FL_BLOCK_CONV))) {
+		if (NULL == data)
+			/* mds granted the lock in the reply */
+			goto granted;
+		/* CP AST RPC: lock get granted, wake it up */
+		wake_up(&lock->l_waitq);
+		RETURN(0);
+	}
+
+	LDLM_DEBUG(lock, "client-side enqueue returned a blocked lock, "
+		   "sleeping");
+	fwd.fwd_lock = lock;
+	obd = class_exp2obd(lock->l_conn_export);
+
+	/* if this is a local lock, there is no import */
+	if (NULL != obd)
+		imp = obd->u.cli.cl_import;
+
+	if (NULL != imp) {
+		spin_lock(&imp->imp_lock);
+		fwd.fwd_generation = imp->imp_generation;
+		spin_unlock(&imp->imp_lock);
+	}
+
+	lwi = LWI_TIMEOUT_INTR(0, NULL, ldlm_flock_interrupted_wait, &fwd);
+
+	/* Go to sleep until the lock is granted. */
+	rc = l_wait_event(lock->l_waitq, is_granted_or_cancelled(lock), &lwi);
+
+	if (rc) {
+		LDLM_DEBUG(lock, "client-side enqueue waking up: failed (%d)",
+			   rc);
+		RETURN(rc);
+	}
+
+granted:
+	OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT, 10);
+
+	if (lock->l_destroyed) {
+		LDLM_DEBUG(lock, "client-side enqueue waking up: destroyed");
+		RETURN(0);
+	}
+
+	if (lock->l_flags & LDLM_FL_FAILED) {
+		LDLM_DEBUG(lock, "client-side enqueue waking up: failed");
+		RETURN(-EIO);
+	}
+
+	if (rc) {
+		LDLM_DEBUG(lock, "client-side enqueue waking up: failed (%d)",
+			   rc);
+		RETURN(rc);
+	}
+
+	LDLM_DEBUG(lock, "client-side enqueue granted");
+
+	lock_res_and_lock(lock);
+
+	/* take lock off the deadlock detection hash list. */
+	ldlm_flock_blocking_unlink(lock);
+
+	/* ldlm_lock_enqueue() has already placed lock on the granted list. */
+	list_del_init(&lock->l_res_link);
+
+	if (flags & LDLM_FL_TEST_LOCK) {
+		/* fcntl(F_GETLK) request */
+		/* The old mode was saved in getlk->fl_type so that if the mode
+		 * in the lock changes we can decref the appropriate refcount.*/
+		ldlm_flock_destroy(lock, flock_type(getlk),
+				   LDLM_FL_WAIT_NOREPROC);
+		switch (lock->l_granted_mode) {
+		case LCK_PR:
+			flock_set_type(getlk, F_RDLCK);
+			break;
+		case LCK_PW:
+			flock_set_type(getlk, F_WRLCK);
+			break;
+		default:
+			flock_set_type(getlk, F_UNLCK);
+		}
+		flock_set_pid(getlk, (pid_t)lock->l_policy_data.l_flock.pid);
+		flock_set_start(getlk,
+				(loff_t)lock->l_policy_data.l_flock.start);
+		flock_set_end(getlk,
+			      (loff_t)lock->l_policy_data.l_flock.end);
+	} else {
+		__u64 noreproc = LDLM_FL_WAIT_NOREPROC;
+
+		/* We need to reprocess the lock to do merges or splits
+		 * with existing locks owned by this process. */
+		ldlm_process_flock_lock(lock, &noreproc, 1, &err, NULL);
+	}
+	unlock_res_and_lock(lock);
+	RETURN(0);
+}
+EXPORT_SYMBOL(ldlm_flock_completion_ast);
+
+int ldlm_flock_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
+			    void *data, int flag)
+{
+	ENTRY;
+
+	LASSERT(lock);
+	LASSERT(flag == LDLM_CB_CANCELING);
+
+	/* take lock off the deadlock detection hash list. */
+	lock_res_and_lock(lock);
+	ldlm_flock_blocking_unlink(lock);
+	unlock_res_and_lock(lock);
+	RETURN(0);
+}
+
+void ldlm_flock_policy_wire18_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				       ldlm_policy_data_t *lpolicy)
+{
+	memset(lpolicy, 0, sizeof(*lpolicy));
+	lpolicy->l_flock.start = wpolicy->l_flock.lfw_start;
+	lpolicy->l_flock.end = wpolicy->l_flock.lfw_end;
+	lpolicy->l_flock.pid = wpolicy->l_flock.lfw_pid;
+	/* Compat code, old clients had no idea about owner field and
+	 * relied solely on pid for ownership. Introduced in LU-104, 2.1,
+	 * April 2011 */
+	lpolicy->l_flock.owner = wpolicy->l_flock.lfw_pid;
+}
+
+
+void ldlm_flock_policy_wire21_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				       ldlm_policy_data_t *lpolicy)
+{
+	memset(lpolicy, 0, sizeof(*lpolicy));
+	lpolicy->l_flock.start = wpolicy->l_flock.lfw_start;
+	lpolicy->l_flock.end = wpolicy->l_flock.lfw_end;
+	lpolicy->l_flock.pid = wpolicy->l_flock.lfw_pid;
+	lpolicy->l_flock.owner = wpolicy->l_flock.lfw_owner;
+}
+
+void ldlm_flock_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
+				     ldlm_wire_policy_data_t *wpolicy)
+{
+	memset(wpolicy, 0, sizeof(*wpolicy));
+	wpolicy->l_flock.lfw_start = lpolicy->l_flock.start;
+	wpolicy->l_flock.lfw_end = lpolicy->l_flock.end;
+	wpolicy->l_flock.lfw_pid = lpolicy->l_flock.pid;
+	wpolicy->l_flock.lfw_owner = lpolicy->l_flock.owner;
+}
+
+/*
+ * Export handle<->flock hash operations.
+ */
+static unsigned
+ldlm_export_flock_hash(cfs_hash_t *hs, const void *key, unsigned mask)
+{
+	return cfs_hash_u64_hash(*(__u64 *)key, mask);
+}
+
+static void *
+ldlm_export_flock_key(struct hlist_node *hnode)
+{
+	struct ldlm_lock *lock;
+
+	lock = hlist_entry(hnode, struct ldlm_lock, l_exp_flock_hash);
+	return &lock->l_policy_data.l_flock.owner;
+}
+
+static int
+ldlm_export_flock_keycmp(const void *key, struct hlist_node *hnode)
+{
+	return !memcmp(ldlm_export_flock_key(hnode), key, sizeof(__u64));
+}
+
+static void *
+ldlm_export_flock_object(struct hlist_node *hnode)
+{
+	return hlist_entry(hnode, struct ldlm_lock, l_exp_flock_hash);
+}
+
+static void
+ldlm_export_flock_get(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	struct ldlm_lock *lock;
+	struct ldlm_flock *flock;
+
+	lock = hlist_entry(hnode, struct ldlm_lock, l_exp_flock_hash);
+	LDLM_LOCK_GET(lock);
+
+	flock = &lock->l_policy_data.l_flock;
+	LASSERT(flock->blocking_export != NULL);
+	class_export_get(flock->blocking_export);
+	flock->blocking_refs++;
+}
+
+static void
+ldlm_export_flock_put(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	struct ldlm_lock *lock;
+	struct ldlm_flock *flock;
+
+	lock = hlist_entry(hnode, struct ldlm_lock, l_exp_flock_hash);
+	LDLM_LOCK_RELEASE(lock);
+
+	flock = &lock->l_policy_data.l_flock;
+	LASSERT(flock->blocking_export != NULL);
+	class_export_put(flock->blocking_export);
+	if (--flock->blocking_refs == 0) {
+		flock->blocking_owner = 0;
+		flock->blocking_export = NULL;
+	}
+}
+
+static cfs_hash_ops_t ldlm_export_flock_ops = {
+	.hs_hash	= ldlm_export_flock_hash,
+	.hs_key	 = ldlm_export_flock_key,
+	.hs_keycmp      = ldlm_export_flock_keycmp,
+	.hs_object      = ldlm_export_flock_object,
+	.hs_get	 = ldlm_export_flock_get,
+	.hs_put	 = ldlm_export_flock_put,
+	.hs_put_locked  = ldlm_export_flock_put,
+};
+
+int ldlm_init_flock_export(struct obd_export *exp)
+{
+	exp->exp_flock_hash =
+		cfs_hash_create(obd_uuid2str(&exp->exp_client_uuid),
+				HASH_EXP_LOCK_CUR_BITS,
+				HASH_EXP_LOCK_MAX_BITS,
+				HASH_EXP_LOCK_BKT_BITS, 0,
+				CFS_HASH_MIN_THETA, CFS_HASH_MAX_THETA,
+				&ldlm_export_flock_ops,
+				CFS_HASH_DEFAULT | CFS_HASH_NBLK_CHANGE);
+	if (!exp->exp_flock_hash)
+		RETURN(-ENOMEM);
+
+	RETURN(0);
+}
+EXPORT_SYMBOL(ldlm_init_flock_export);
+
+void ldlm_destroy_flock_export(struct obd_export *exp)
+{
+	ENTRY;
+	if (exp->exp_flock_hash) {
+		cfs_hash_putref(exp->exp_flock_hash);
+		exp->exp_flock_hash = NULL;
+	}
+	EXIT;
+}
+EXPORT_SYMBOL(ldlm_destroy_flock_export);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_inodebits.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,75 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/ldlm/ldlm_inodebits.c
+ *
+ * Author: Peter Braam <braam@clusterfs.com>
+ * Author: Phil Schwan <phil@clusterfs.com>
+ */
+
+/**
+ * This file contains implementation of IBITS lock type
+ *
+ * IBITS lock type contains a bit mask determining various properties of an
+ * object. The meanings of specific bits are specific to the caller and are
+ * opaque to LDLM code.
+ *
+ * Locks with intersecting bitmasks and conflicting lock modes (e.g.  LCK_PW)
+ * are considered conflicting.  See the lock mode compatibility matrix
+ * in lustre_dlm.h.
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+#include <lustre_dlm.h>
+#include <obd_support.h>
+#include <lustre_lib.h>
+
+#include "ldlm_internal.h"
+
+
+void ldlm_ibits_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				     ldlm_policy_data_t *lpolicy)
+{
+	memset(lpolicy, 0, sizeof(*lpolicy));
+	lpolicy->l_inodebits.bits = wpolicy->l_inodebits.bits;
+}
+
+void ldlm_ibits_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
+				     ldlm_wire_policy_data_t *wpolicy)
+{
+	memset(wpolicy, 0, sizeof(*wpolicy));
+	wpolicy->l_inodebits.bits = lpolicy->l_inodebits.bits;
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,276 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#define MAX_STRING_SIZE 128
+
+extern atomic_t ldlm_srv_namespace_nr;
+extern atomic_t ldlm_cli_namespace_nr;
+extern struct mutex ldlm_srv_namespace_lock;
+extern struct list_head ldlm_srv_namespace_list;
+extern struct mutex ldlm_cli_namespace_lock;
+extern struct list_head ldlm_cli_namespace_list;
+
+static inline atomic_t *ldlm_namespace_nr(ldlm_side_t client)
+{
+	return client == LDLM_NAMESPACE_SERVER ?
+		&ldlm_srv_namespace_nr : &ldlm_cli_namespace_nr;
+}
+
+static inline struct list_head *ldlm_namespace_list(ldlm_side_t client)
+{
+	return client == LDLM_NAMESPACE_SERVER ?
+		&ldlm_srv_namespace_list : &ldlm_cli_namespace_list;
+}
+
+static inline struct mutex *ldlm_namespace_lock(ldlm_side_t client)
+{
+	return client == LDLM_NAMESPACE_SERVER ?
+		&ldlm_srv_namespace_lock : &ldlm_cli_namespace_lock;
+}
+
+/* ldlm_request.c */
+/* Cancel lru flag, it indicates we cancel aged locks. */
+enum {
+	LDLM_CANCEL_AGED   = 1 << 0, /* Cancel aged locks (non lru resize). */
+	LDLM_CANCEL_PASSED = 1 << 1, /* Cancel passed number of locks. */
+	LDLM_CANCEL_SHRINK = 1 << 2, /* Cancel locks from shrinker. */
+	LDLM_CANCEL_LRUR   = 1 << 3, /* Cancel locks from lru resize. */
+	LDLM_CANCEL_NO_WAIT = 1 << 4 /* Cancel locks w/o blocking (neither
+				      * sending nor waiting for any rpcs) */
+};
+
+int ldlm_cancel_lru(struct ldlm_namespace *ns, int nr,
+		    ldlm_cancel_flags_t sync, int flags);
+int ldlm_cancel_lru_local(struct ldlm_namespace *ns,
+			  struct list_head *cancels, int count, int max,
+			  ldlm_cancel_flags_t cancel_flags, int flags);
+extern int ldlm_enqueue_min;
+int ldlm_get_enq_timeout(struct ldlm_lock *lock);
+
+/* ldlm_resource.c */
+int ldlm_resource_putref_locked(struct ldlm_resource *res);
+void ldlm_resource_insert_lock_after(struct ldlm_lock *original,
+				     struct ldlm_lock *new);
+void ldlm_namespace_free_prior(struct ldlm_namespace *ns,
+			       struct obd_import *imp, int force);
+void ldlm_namespace_free_post(struct ldlm_namespace *ns);
+/* ldlm_lock.c */
+
+struct ldlm_cb_set_arg {
+	struct ptlrpc_request_set	*set;
+	int				 type; /* LDLM_{CP,BL,GL}_CALLBACK */
+	atomic_t			 restart;
+	struct list_head			*list;
+	union ldlm_gl_desc		*gl_desc; /* glimpse AST descriptor */
+};
+
+typedef enum {
+	LDLM_WORK_BL_AST,
+	LDLM_WORK_CP_AST,
+	LDLM_WORK_REVOKE_AST,
+	LDLM_WORK_GL_AST
+} ldlm_desc_ast_t;
+
+void ldlm_grant_lock(struct ldlm_lock *lock, struct list_head *work_list);
+int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill,
+		  enum req_location loc, void *data, int size);
+struct ldlm_lock *
+ldlm_lock_create(struct ldlm_namespace *ns, const struct ldlm_res_id *,
+		 ldlm_type_t type, ldlm_mode_t,
+		 const struct ldlm_callback_suite *cbs,
+		 void *data, __u32 lvb_len, enum lvb_type lvb_type);
+ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *, struct ldlm_lock **,
+			       void *cookie, __u64 *flags);
+void ldlm_lock_addref_internal(struct ldlm_lock *, __u32 mode);
+void ldlm_lock_addref_internal_nolock(struct ldlm_lock *, __u32 mode);
+void ldlm_lock_decref_internal(struct ldlm_lock *, __u32 mode);
+void ldlm_lock_decref_internal_nolock(struct ldlm_lock *, __u32 mode);
+void ldlm_add_ast_work_item(struct ldlm_lock *lock, struct ldlm_lock *new,
+			    struct list_head *work_list);
+int ldlm_run_ast_work(struct ldlm_namespace *ns, struct list_head *rpc_list,
+		      ldlm_desc_ast_t ast_type);
+int ldlm_work_gl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq);
+int ldlm_lock_remove_from_lru(struct ldlm_lock *lock);
+int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock);
+void ldlm_lock_add_to_lru_nolock(struct ldlm_lock *lock);
+void ldlm_lock_add_to_lru(struct ldlm_lock *lock);
+void ldlm_lock_touch_in_lru(struct ldlm_lock *lock);
+void ldlm_lock_destroy_nolock(struct ldlm_lock *lock);
+
+void ldlm_cancel_locks_for_export(struct obd_export *export);
+
+/* ldlm_lockd.c */
+int ldlm_bl_to_thread_lock(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld,
+			   struct ldlm_lock *lock);
+int ldlm_bl_to_thread_list(struct ldlm_namespace *ns,
+			   struct ldlm_lock_desc *ld,
+			   struct list_head *cancels, int count,
+			   ldlm_cancel_flags_t cancel_flags);
+
+void ldlm_handle_bl_callback(struct ldlm_namespace *ns,
+			     struct ldlm_lock_desc *ld, struct ldlm_lock *lock);
+
+
+/* ldlm_extent.c */
+void ldlm_extent_add_lock(struct ldlm_resource *res, struct ldlm_lock *lock);
+void ldlm_extent_unlink_lock(struct ldlm_lock *lock);
+
+/* ldlm_flock.c */
+int ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags,
+			    int first_enq, ldlm_error_t *err,
+			    struct list_head *work_list);
+int ldlm_init_flock_export(struct obd_export *exp);
+void ldlm_destroy_flock_export(struct obd_export *exp);
+
+/* l_lock.c */
+void l_check_ns_lock(struct ldlm_namespace *ns);
+void l_check_no_ns_lock(struct ldlm_namespace *ns);
+
+extern proc_dir_entry_t *ldlm_svc_proc_dir;
+extern proc_dir_entry_t *ldlm_type_proc_dir;
+
+struct ldlm_state {
+	struct ptlrpc_service *ldlm_cb_service;
+	struct ptlrpc_service *ldlm_cancel_service;
+	struct ptlrpc_client *ldlm_client;
+	struct ptlrpc_connection *ldlm_server_conn;
+	struct ldlm_bl_pool *ldlm_bl_pool;
+};
+
+/* interval tree, for LDLM_EXTENT. */
+extern struct kmem_cache *ldlm_interval_slab; /* slab cache for ldlm_interval */
+extern void ldlm_interval_attach(struct ldlm_interval *n, struct ldlm_lock *l);
+extern struct ldlm_interval *ldlm_interval_detach(struct ldlm_lock *l);
+extern struct ldlm_interval *ldlm_interval_alloc(struct ldlm_lock *lock);
+extern void ldlm_interval_free(struct ldlm_interval *node);
+/* this function must be called with res lock held */
+static inline struct ldlm_extent *
+ldlm_interval_extent(struct ldlm_interval *node)
+{
+	struct ldlm_lock *lock;
+	LASSERT(!list_empty(&node->li_group));
+
+	lock = list_entry(node->li_group.next, struct ldlm_lock,
+			      l_sl_policy);
+	return &lock->l_policy_data.l_extent;
+}
+
+int ldlm_init(void);
+void ldlm_exit(void);
+
+enum ldlm_policy_res {
+	LDLM_POLICY_CANCEL_LOCK,
+	LDLM_POLICY_KEEP_LOCK,
+	LDLM_POLICY_SKIP_LOCK
+};
+
+typedef enum ldlm_policy_res ldlm_policy_res_t;
+
+#define LDLM_POOL_PROC_READER_SEQ_SHOW(var, type)			    \
+	static int lprocfs_##var##_seq_show(struct seq_file *m, void *v) \
+	{								    \
+		struct ldlm_pool *pl = m->private;			    \
+		type tmp;						    \
+									    \
+		spin_lock(&pl->pl_lock);				    \
+		tmp = pl->pl_##var;					    \
+		spin_unlock(&pl->pl_lock);				    \
+									    \
+		return lprocfs_rd_uint(m, &tmp);			    \
+	}								    \
+	struct __##var##__dummy_read {;} /* semicolon catcher */
+
+#define LDLM_POOL_PROC_WRITER(var, type)				    \
+	int lprocfs_wr_##var(struct file *file, const char *buffer,	    \
+			     unsigned long count, void *data)		    \
+	{								    \
+		struct ldlm_pool *pl = data;				    \
+		type tmp;						    \
+		int rc;							    \
+									    \
+		rc = lprocfs_wr_uint(file, buffer, count, &tmp);	    \
+		if (rc < 0) {						    \
+			CERROR("Can't parse user input, rc = %d\n", rc);    \
+			return rc;					    \
+		}							    \
+									    \
+		spin_lock(&pl->pl_lock);				    \
+		pl->pl_##var = tmp;					    \
+		spin_unlock(&pl->pl_lock);				    \
+									    \
+		return rc;						    \
+	}								    \
+	struct __##var##__dummy_write {;} /* semicolon catcher */
+
+static inline int is_granted_or_cancelled(struct ldlm_lock *lock)
+{
+	int ret = 0;
+
+	lock_res_and_lock(lock);
+	if (((lock->l_req_mode == lock->l_granted_mode) &&
+	     !(lock->l_flags & LDLM_FL_CP_REQD)) ||
+	    (lock->l_flags & (LDLM_FL_FAILED | LDLM_FL_CANCEL)))
+		ret = 1;
+	unlock_res_and_lock(lock);
+
+	return ret;
+}
+
+typedef void (*ldlm_policy_wire_to_local_t)(const ldlm_wire_policy_data_t *,
+					    ldlm_policy_data_t *);
+
+typedef void (*ldlm_policy_local_to_wire_t)(const ldlm_policy_data_t *,
+					    ldlm_wire_policy_data_t *);
+
+void ldlm_plain_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				     ldlm_policy_data_t *lpolicy);
+void ldlm_plain_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
+				     ldlm_wire_policy_data_t *wpolicy);
+void ldlm_ibits_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				     ldlm_policy_data_t *lpolicy);
+void ldlm_ibits_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
+				     ldlm_wire_policy_data_t *wpolicy);
+void ldlm_extent_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				     ldlm_policy_data_t *lpolicy);
+void ldlm_extent_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
+				     ldlm_wire_policy_data_t *wpolicy);
+void ldlm_flock_policy_wire18_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				     ldlm_policy_data_t *lpolicy);
+void ldlm_flock_policy_wire21_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				     ldlm_policy_data_t *lpolicy);
+
+void ldlm_flock_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
+				     ldlm_wire_policy_data_t *wpolicy);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,868 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2010, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+/**
+ * This file deals with various client/target related logic including recovery.
+ *
+ * TODO: This code more logically belongs in the ptlrpc module than in ldlm and
+ * should be moved.
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+# include <linux/libcfs/libcfs.h>
+#include <obd.h>
+#include <obd_class.h>
+#include <lustre_dlm.h>
+#include <lustre_net.h>
+#include <lustre_sec.h>
+#include "ldlm_internal.h"
+
+/* @priority: If non-zero, move the selected connection to the list head.
+ * @create: If zero, only search in existing connections.
+ */
+static int import_set_conn(struct obd_import *imp, struct obd_uuid *uuid,
+			   int priority, int create)
+{
+	struct ptlrpc_connection *ptlrpc_conn;
+	struct obd_import_conn *imp_conn = NULL, *item;
+	int rc = 0;
+	ENTRY;
+
+	if (!create && !priority) {
+		CDEBUG(D_HA, "Nothing to do\n");
+		RETURN(-EINVAL);
+	}
+
+	ptlrpc_conn = ptlrpc_uuid_to_connection(uuid);
+	if (!ptlrpc_conn) {
+		CDEBUG(D_HA, "can't find connection %s\n", uuid->uuid);
+		RETURN (-ENOENT);
+	}
+
+	if (create) {
+		OBD_ALLOC(imp_conn, sizeof(*imp_conn));
+		if (!imp_conn) {
+			GOTO(out_put, rc = -ENOMEM);
+		}
+	}
+
+	spin_lock(&imp->imp_lock);
+	list_for_each_entry(item, &imp->imp_conn_list, oic_item) {
+		if (obd_uuid_equals(uuid, &item->oic_uuid)) {
+			if (priority) {
+				list_del(&item->oic_item);
+				list_add(&item->oic_item,
+					     &imp->imp_conn_list);
+				item->oic_last_attempt = 0;
+			}
+			CDEBUG(D_HA, "imp %p@%s: found existing conn %s%s\n",
+			       imp, imp->imp_obd->obd_name, uuid->uuid,
+			       (priority ? ", moved to head" : ""));
+			spin_unlock(&imp->imp_lock);
+			GOTO(out_free, rc = 0);
+		}
+	}
+	/* No existing import connection found for \a uuid. */
+	if (create) {
+		imp_conn->oic_conn = ptlrpc_conn;
+		imp_conn->oic_uuid = *uuid;
+		imp_conn->oic_last_attempt = 0;
+		if (priority)
+			list_add(&imp_conn->oic_item, &imp->imp_conn_list);
+		else
+			list_add_tail(&imp_conn->oic_item,
+					  &imp->imp_conn_list);
+		CDEBUG(D_HA, "imp %p@%s: add connection %s at %s\n",
+		       imp, imp->imp_obd->obd_name, uuid->uuid,
+		       (priority ? "head" : "tail"));
+	} else {
+		spin_unlock(&imp->imp_lock);
+		GOTO(out_free, rc = -ENOENT);
+	}
+
+	spin_unlock(&imp->imp_lock);
+	RETURN(0);
+out_free:
+	if (imp_conn)
+		OBD_FREE(imp_conn, sizeof(*imp_conn));
+out_put:
+	ptlrpc_connection_put(ptlrpc_conn);
+	RETURN(rc);
+}
+
+int import_set_conn_priority(struct obd_import *imp, struct obd_uuid *uuid)
+{
+	return import_set_conn(imp, uuid, 1, 0);
+}
+
+int client_import_add_conn(struct obd_import *imp, struct obd_uuid *uuid,
+			   int priority)
+{
+	return import_set_conn(imp, uuid, priority, 1);
+}
+EXPORT_SYMBOL(client_import_add_conn);
+
+int client_import_del_conn(struct obd_import *imp, struct obd_uuid *uuid)
+{
+	struct obd_import_conn *imp_conn;
+	struct obd_export *dlmexp;
+	int rc = -ENOENT;
+	ENTRY;
+
+	spin_lock(&imp->imp_lock);
+	if (list_empty(&imp->imp_conn_list)) {
+		LASSERT(!imp->imp_connection);
+		GOTO(out, rc);
+	}
+
+	list_for_each_entry(imp_conn, &imp->imp_conn_list, oic_item) {
+		if (!obd_uuid_equals(uuid, &imp_conn->oic_uuid))
+			continue;
+		LASSERT(imp_conn->oic_conn);
+
+		if (imp_conn == imp->imp_conn_current) {
+			LASSERT(imp_conn->oic_conn == imp->imp_connection);
+
+			if (imp->imp_state != LUSTRE_IMP_CLOSED &&
+			    imp->imp_state != LUSTRE_IMP_DISCON) {
+				CERROR("can't remove current connection\n");
+				GOTO(out, rc = -EBUSY);
+			}
+
+			ptlrpc_connection_put(imp->imp_connection);
+			imp->imp_connection = NULL;
+
+			dlmexp = class_conn2export(&imp->imp_dlm_handle);
+			if (dlmexp && dlmexp->exp_connection) {
+				LASSERT(dlmexp->exp_connection ==
+					imp_conn->oic_conn);
+				ptlrpc_connection_put(dlmexp->exp_connection);
+				dlmexp->exp_connection = NULL;
+			}
+		}
+
+		list_del(&imp_conn->oic_item);
+		ptlrpc_connection_put(imp_conn->oic_conn);
+		OBD_FREE(imp_conn, sizeof(*imp_conn));
+		CDEBUG(D_HA, "imp %p@%s: remove connection %s\n",
+		       imp, imp->imp_obd->obd_name, uuid->uuid);
+		rc = 0;
+		break;
+	}
+out:
+	spin_unlock(&imp->imp_lock);
+	if (rc == -ENOENT)
+		CERROR("connection %s not found\n", uuid->uuid);
+	RETURN(rc);
+}
+EXPORT_SYMBOL(client_import_del_conn);
+
+/**
+ * Find conn UUID by peer NID. \a peer is a server NID. This function is used
+ * to find a conn uuid of \a imp which can reach \a peer.
+ */
+int client_import_find_conn(struct obd_import *imp, lnet_nid_t peer,
+			    struct obd_uuid *uuid)
+{
+	struct obd_import_conn *conn;
+	int rc = -ENOENT;
+	ENTRY;
+
+	spin_lock(&imp->imp_lock);
+	list_for_each_entry(conn, &imp->imp_conn_list, oic_item) {
+		/* Check if conn UUID does have this peer NID. */
+		if (class_check_uuid(&conn->oic_uuid, peer)) {
+			*uuid = conn->oic_uuid;
+			rc = 0;
+			break;
+		}
+	}
+	spin_unlock(&imp->imp_lock);
+	RETURN(rc);
+}
+EXPORT_SYMBOL(client_import_find_conn);
+
+void client_destroy_import(struct obd_import *imp)
+{
+	/* Drop security policy instance after all RPCs have finished/aborted
+	 * to let all busy contexts be released. */
+	class_import_get(imp);
+	class_destroy_import(imp);
+	sptlrpc_import_sec_put(imp);
+	class_import_put(imp);
+}
+EXPORT_SYMBOL(client_destroy_import);
+
+/**
+ * Check whether or not the OSC is on MDT.
+ * In the config log,
+ * osc on MDT
+ *	setup 0:{fsname}-OSTxxxx-osc[-MDTxxxx] 1:lustre-OST0000_UUID 2:NID
+ * osc on client
+ *	setup 0:{fsname}-OSTxxxx-osc 1:lustre-OST0000_UUID 2:NID
+ *
+ **/
+static int osc_on_mdt(char *obdname)
+{
+	char *ptr;
+
+	ptr = strrchr(obdname, '-');
+	if (ptr == NULL)
+		return 0;
+
+	if (strncmp(ptr + 1, "MDT", 3) == 0)
+		return 1;
+
+	return 0;
+}
+
+/* Configure an RPC client OBD device.
+ *
+ * lcfg parameters:
+ * 1 - client UUID
+ * 2 - server UUID
+ * 3 - inactive-on-startup
+ */
+int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
+{
+	struct client_obd *cli = &obddev->u.cli;
+	struct obd_import *imp;
+	struct obd_uuid server_uuid;
+	int rq_portal, rp_portal, connect_op;
+	char *name = obddev->obd_type->typ_name;
+	ldlm_ns_type_t ns_type = LDLM_NS_TYPE_UNKNOWN;
+	int rc;
+	char	*cli_name = lustre_cfg_buf(lcfg, 0);
+	ENTRY;
+
+	/* In a more perfect world, we would hang a ptlrpc_client off of
+	 * obd_type and just use the values from there. */
+	if (!strcmp(name, LUSTRE_OSC_NAME) ||
+	    (!(strcmp(name, LUSTRE_OSP_NAME)) &&
+	     (is_osp_on_mdt(cli_name) &&
+	       strstr(lustre_cfg_buf(lcfg, 1), "OST") != NULL))) {
+		/* OSC or OSP_on_MDT for OSTs */
+		rq_portal = OST_REQUEST_PORTAL;
+		rp_portal = OSC_REPLY_PORTAL;
+		connect_op = OST_CONNECT;
+		cli->cl_sp_me = LUSTRE_SP_CLI;
+		cli->cl_sp_to = LUSTRE_SP_OST;
+		ns_type = LDLM_NS_TYPE_OSC;
+	} else if (!strcmp(name, LUSTRE_MDC_NAME) ||
+		   !strcmp(name, LUSTRE_LWP_NAME) ||
+		   (!strcmp(name, LUSTRE_OSP_NAME) &&
+		    (is_osp_on_mdt(cli_name) &&
+		     strstr(lustre_cfg_buf(lcfg, 1), "OST") == NULL))) {
+		/* MDC or OSP_on_MDT for other MDTs */
+		rq_portal = MDS_REQUEST_PORTAL;
+		rp_portal = MDC_REPLY_PORTAL;
+		connect_op = MDS_CONNECT;
+		cli->cl_sp_me = LUSTRE_SP_CLI;
+		cli->cl_sp_to = LUSTRE_SP_MDT;
+		ns_type = LDLM_NS_TYPE_MDC;
+	} else if (!strcmp(name, LUSTRE_MGC_NAME)) {
+		rq_portal = MGS_REQUEST_PORTAL;
+		rp_portal = MGC_REPLY_PORTAL;
+		connect_op = MGS_CONNECT;
+		cli->cl_sp_me = LUSTRE_SP_MGC;
+		cli->cl_sp_to = LUSTRE_SP_MGS;
+		cli->cl_flvr_mgc.sf_rpc = SPTLRPC_FLVR_INVALID;
+		ns_type = LDLM_NS_TYPE_MGC;
+	} else {
+		CERROR("unknown client OBD type \"%s\", can't setup\n",
+		       name);
+		RETURN(-EINVAL);
+	}
+
+	if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {
+		CERROR("requires a TARGET UUID\n");
+		RETURN(-EINVAL);
+	}
+
+	if (LUSTRE_CFG_BUFLEN(lcfg, 1) > 37) {
+		CERROR("client UUID must be less than 38 characters\n");
+		RETURN(-EINVAL);
+	}
+
+	if (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1) {
+		CERROR("setup requires a SERVER UUID\n");
+		RETURN(-EINVAL);
+	}
+
+	if (LUSTRE_CFG_BUFLEN(lcfg, 2) > 37) {
+		CERROR("target UUID must be less than 38 characters\n");
+		RETURN(-EINVAL);
+	}
+
+	init_rwsem(&cli->cl_sem);
+	sema_init(&cli->cl_mgc_sem, 1);
+	cli->cl_conn_count = 0;
+	memcpy(server_uuid.uuid, lustre_cfg_buf(lcfg, 2),
+	       min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),
+		     sizeof(server_uuid)));
+
+	cli->cl_dirty = 0;
+	cli->cl_avail_grant = 0;
+	/* FIXME: Should limit this for the sum of all cl_dirty_max. */
+	cli->cl_dirty_max = OSC_MAX_DIRTY_DEFAULT * 1024 * 1024;
+	if (cli->cl_dirty_max >> PAGE_CACHE_SHIFT > num_physpages / 8)
+		cli->cl_dirty_max = num_physpages << (PAGE_CACHE_SHIFT - 3);
+	INIT_LIST_HEAD(&cli->cl_cache_waiters);
+	INIT_LIST_HEAD(&cli->cl_loi_ready_list);
+	INIT_LIST_HEAD(&cli->cl_loi_hp_ready_list);
+	INIT_LIST_HEAD(&cli->cl_loi_write_list);
+	INIT_LIST_HEAD(&cli->cl_loi_read_list);
+	client_obd_list_lock_init(&cli->cl_loi_list_lock);
+	atomic_set(&cli->cl_pending_w_pages, 0);
+	atomic_set(&cli->cl_pending_r_pages, 0);
+	cli->cl_r_in_flight = 0;
+	cli->cl_w_in_flight = 0;
+
+	spin_lock_init(&cli->cl_read_rpc_hist.oh_lock);
+	spin_lock_init(&cli->cl_write_rpc_hist.oh_lock);
+	spin_lock_init(&cli->cl_read_page_hist.oh_lock);
+	spin_lock_init(&cli->cl_write_page_hist.oh_lock);
+	spin_lock_init(&cli->cl_read_offset_hist.oh_lock);
+	spin_lock_init(&cli->cl_write_offset_hist.oh_lock);
+
+	/* lru for osc. */
+	INIT_LIST_HEAD(&cli->cl_lru_osc);
+	atomic_set(&cli->cl_lru_shrinkers, 0);
+	atomic_set(&cli->cl_lru_busy, 0);
+	atomic_set(&cli->cl_lru_in_list, 0);
+	INIT_LIST_HEAD(&cli->cl_lru_list);
+	client_obd_list_lock_init(&cli->cl_lru_list_lock);
+
+	init_waitqueue_head(&cli->cl_destroy_waitq);
+	atomic_set(&cli->cl_destroy_in_flight, 0);
+	/* Turn on checksumming by default. */
+	cli->cl_checksum = 1;
+	/*
+	 * The supported checksum types will be worked out at connect time
+	 * Set cl_chksum* to CRC32 for now to avoid returning screwed info
+	 * through procfs.
+	 */
+	cli->cl_cksum_type = cli->cl_supp_cksum_types = OBD_CKSUM_CRC32;
+	atomic_set(&cli->cl_resends, OSC_DEFAULT_RESENDS);
+
+	/* This value may be reduced at connect time in
+	 * ptlrpc_connect_interpret() . We initialize it to only
+	 * 1MB until we know what the performance looks like.
+	 * In the future this should likely be increased. LU-1431 */
+	cli->cl_max_pages_per_rpc = min_t(int, PTLRPC_MAX_BRW_PAGES,
+					  LNET_MTU >> PAGE_CACHE_SHIFT);
+
+	if (!strcmp(name, LUSTRE_MDC_NAME)) {
+		cli->cl_max_rpcs_in_flight = MDC_MAX_RIF_DEFAULT;
+	} else if (num_physpages >> (20 - PAGE_CACHE_SHIFT) <= 128 /* MB */) {
+		cli->cl_max_rpcs_in_flight = 2;
+	} else if (num_physpages >> (20 - PAGE_CACHE_SHIFT) <= 256 /* MB */) {
+		cli->cl_max_rpcs_in_flight = 3;
+	} else if (num_physpages >> (20 - PAGE_CACHE_SHIFT) <= 512 /* MB */) {
+		cli->cl_max_rpcs_in_flight = 4;
+	} else {
+		if (osc_on_mdt(obddev->obd_name))
+			cli->cl_max_rpcs_in_flight = MDS_OSC_MAX_RIF_DEFAULT;
+		else
+			cli->cl_max_rpcs_in_flight = OSC_MAX_RIF_DEFAULT;
+	}
+	rc = ldlm_get_ref();
+	if (rc) {
+		CERROR("ldlm_get_ref failed: %d\n", rc);
+		GOTO(err, rc);
+	}
+
+	ptlrpc_init_client(rq_portal, rp_portal, name,
+			   &obddev->obd_ldlm_client);
+
+	imp = class_new_import(obddev);
+	if (imp == NULL)
+		GOTO(err_ldlm, rc = -ENOENT);
+	imp->imp_client = &obddev->obd_ldlm_client;
+	imp->imp_connect_op = connect_op;
+	memcpy(cli->cl_target_uuid.uuid, lustre_cfg_buf(lcfg, 1),
+	       LUSTRE_CFG_BUFLEN(lcfg, 1));
+	class_import_put(imp);
+
+	rc = client_import_add_conn(imp, &server_uuid, 1);
+	if (rc) {
+		CERROR("can't add initial connection\n");
+		GOTO(err_import, rc);
+	}
+
+	cli->cl_import = imp;
+	/* cli->cl_max_mds_{easize,cookiesize} updated by mdc_init_ea_size() */
+	cli->cl_max_mds_easize = sizeof(struct lov_mds_md_v3);
+	cli->cl_max_mds_cookiesize = sizeof(struct llog_cookie);
+
+	if (LUSTRE_CFG_BUFLEN(lcfg, 3) > 0) {
+		if (!strcmp(lustre_cfg_string(lcfg, 3), "inactive")) {
+			CDEBUG(D_HA, "marking %s %s->%s as inactive\n",
+			       name, obddev->obd_name,
+			       cli->cl_target_uuid.uuid);
+			spin_lock(&imp->imp_lock);
+			imp->imp_deactive = 1;
+			spin_unlock(&imp->imp_lock);
+		}
+	}
+
+	obddev->obd_namespace = ldlm_namespace_new(obddev, obddev->obd_name,
+						   LDLM_NAMESPACE_CLIENT,
+						   LDLM_NAMESPACE_GREEDY,
+						   ns_type);
+	if (obddev->obd_namespace == NULL) {
+		CERROR("Unable to create client namespace - %s\n",
+		       obddev->obd_name);
+		GOTO(err_import, rc = -ENOMEM);
+	}
+
+	cli->cl_qchk_stat = CL_NOT_QUOTACHECKED;
+
+	RETURN(rc);
+
+err_import:
+	class_destroy_import(imp);
+err_ldlm:
+	ldlm_put_ref();
+err:
+	RETURN(rc);
+
+}
+EXPORT_SYMBOL(client_obd_setup);
+
+int client_obd_cleanup(struct obd_device *obddev)
+{
+	ENTRY;
+
+	ldlm_namespace_free_post(obddev->obd_namespace);
+	obddev->obd_namespace = NULL;
+
+	LASSERT(obddev->u.cli.cl_import == NULL);
+
+	ldlm_put_ref();
+	RETURN(0);
+}
+EXPORT_SYMBOL(client_obd_cleanup);
+
+/* ->o_connect() method for client side (OSC and MDC and MGC) */
+int client_connect_import(const struct lu_env *env,
+			  struct obd_export **exp,
+			  struct obd_device *obd, struct obd_uuid *cluuid,
+			  struct obd_connect_data *data, void *localdata)
+{
+	struct client_obd       *cli    = &obd->u.cli;
+	struct obd_import       *imp    = cli->cl_import;
+	struct obd_connect_data *ocd;
+	struct lustre_handle    conn    = { 0 };
+	int		     rc;
+	ENTRY;
+
+	*exp = NULL;
+	down_write(&cli->cl_sem);
+	if (cli->cl_conn_count > 0 )
+		GOTO(out_sem, rc = -EALREADY);
+
+	rc = class_connect(&conn, obd, cluuid);
+	if (rc)
+		GOTO(out_sem, rc);
+
+	cli->cl_conn_count++;
+	*exp = class_conn2export(&conn);
+
+	LASSERT(obd->obd_namespace);
+
+	imp->imp_dlm_handle = conn;
+	rc = ptlrpc_init_import(imp);
+	if (rc != 0)
+		GOTO(out_ldlm, rc);
+
+	ocd = &imp->imp_connect_data;
+	if (data) {
+		*ocd = *data;
+		imp->imp_connect_flags_orig = data->ocd_connect_flags;
+	}
+
+	rc = ptlrpc_connect_import(imp);
+	if (rc != 0) {
+		LASSERT (imp->imp_state == LUSTRE_IMP_DISCON);
+		GOTO(out_ldlm, rc);
+	}
+	LASSERT((*exp)->exp_connection);
+
+	if (data) {
+		LASSERTF((ocd->ocd_connect_flags & data->ocd_connect_flags) ==
+			 ocd->ocd_connect_flags, "old "LPX64", new "LPX64"\n",
+			 data->ocd_connect_flags, ocd->ocd_connect_flags);
+		data->ocd_connect_flags = ocd->ocd_connect_flags;
+	}
+
+	ptlrpc_pinger_add_import(imp);
+
+	EXIT;
+
+	if (rc) {
+out_ldlm:
+		cli->cl_conn_count--;
+		class_disconnect(*exp);
+		*exp = NULL;
+	}
+out_sem:
+	up_write(&cli->cl_sem);
+
+	return rc;
+}
+EXPORT_SYMBOL(client_connect_import);
+
+int client_disconnect_export(struct obd_export *exp)
+{
+	struct obd_device *obd = class_exp2obd(exp);
+	struct client_obd *cli;
+	struct obd_import *imp;
+	int rc = 0, err;
+	ENTRY;
+
+	if (!obd) {
+		CERROR("invalid export for disconnect: exp %p cookie "LPX64"\n",
+		       exp, exp ? exp->exp_handle.h_cookie : -1);
+		RETURN(-EINVAL);
+	}
+
+	cli = &obd->u.cli;
+	imp = cli->cl_import;
+
+	down_write(&cli->cl_sem);
+	CDEBUG(D_INFO, "disconnect %s - %d\n", obd->obd_name,
+	       cli->cl_conn_count);
+
+	if (!cli->cl_conn_count) {
+		CERROR("disconnecting disconnected device (%s)\n",
+		       obd->obd_name);
+		GOTO(out_disconnect, rc = -EINVAL);
+	}
+
+	cli->cl_conn_count--;
+	if (cli->cl_conn_count)
+		GOTO(out_disconnect, rc = 0);
+
+	/* Mark import deactivated now, so we don't try to reconnect if any
+	 * of the cleanup RPCs fails (e.g. LDLM cancel, etc).  We don't
+	 * fully deactivate the import, or that would drop all requests. */
+	spin_lock(&imp->imp_lock);
+	imp->imp_deactive = 1;
+	spin_unlock(&imp->imp_lock);
+
+	/* Some non-replayable imports (MDS's OSCs) are pinged, so just
+	 * delete it regardless.  (It's safe to delete an import that was
+	 * never added.) */
+	(void)ptlrpc_pinger_del_import(imp);
+
+	if (obd->obd_namespace != NULL) {
+		/* obd_force == local only */
+		ldlm_cli_cancel_unused(obd->obd_namespace, NULL,
+				       obd->obd_force ? LCF_LOCAL : 0, NULL);
+		ldlm_namespace_free_prior(obd->obd_namespace, imp, obd->obd_force);
+	}
+
+	/* There's no need to hold sem while disconnecting an import,
+	 * and it may actually cause deadlock in GSS. */
+	up_write(&cli->cl_sem);
+	rc = ptlrpc_disconnect_import(imp, 0);
+	down_write(&cli->cl_sem);
+
+	ptlrpc_invalidate_import(imp);
+
+	EXIT;
+
+out_disconnect:
+	/* Use server style - class_disconnect should be always called for
+	 * o_disconnect. */
+	err = class_disconnect(exp);
+	if (!rc && err)
+		rc = err;
+
+	up_write(&cli->cl_sem);
+
+	RETURN(rc);
+}
+EXPORT_SYMBOL(client_disconnect_export);
+
+
+/**
+ * Packs current SLV and Limit into \a req.
+ */
+int target_pack_pool_reply(struct ptlrpc_request *req)
+{
+	struct obd_device *obd;
+	ENTRY;
+
+	/* Check that we still have all structures alive as this may
+	 * be some late RPC at shutdown time. */
+	if (unlikely(!req->rq_export || !req->rq_export->exp_obd ||
+		     !exp_connect_lru_resize(req->rq_export))) {
+		lustre_msg_set_slv(req->rq_repmsg, 0);
+		lustre_msg_set_limit(req->rq_repmsg, 0);
+		RETURN(0);
+	}
+
+	/* OBD is alive here as export is alive, which we checked above. */
+	obd = req->rq_export->exp_obd;
+
+	read_lock(&obd->obd_pool_lock);
+	lustre_msg_set_slv(req->rq_repmsg, obd->obd_pool_slv);
+	lustre_msg_set_limit(req->rq_repmsg, obd->obd_pool_limit);
+	read_unlock(&obd->obd_pool_lock);
+
+	RETURN(0);
+}
+EXPORT_SYMBOL(target_pack_pool_reply);
+
+int target_send_reply_msg(struct ptlrpc_request *req, int rc, int fail_id)
+{
+	if (OBD_FAIL_CHECK_ORSET(fail_id & ~OBD_FAIL_ONCE, OBD_FAIL_ONCE)) {
+		DEBUG_REQ(D_ERROR, req, "dropping reply");
+		return (-ECOMM);
+	}
+
+	if (unlikely(rc)) {
+		DEBUG_REQ(D_NET, req, "processing error (%d)", rc);
+		req->rq_status = rc;
+		return (ptlrpc_send_error(req, 1));
+	} else {
+		DEBUG_REQ(D_NET, req, "sending reply");
+	}
+
+	return (ptlrpc_send_reply(req, PTLRPC_REPLY_MAYBE_DIFFICULT));
+}
+
+void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
+{
+	struct ptlrpc_service_part *svcpt;
+	int			netrc;
+	struct ptlrpc_reply_state *rs;
+	struct obd_export	 *exp;
+	ENTRY;
+
+	if (req->rq_no_reply) {
+		EXIT;
+		return;
+	}
+
+	svcpt = req->rq_rqbd->rqbd_svcpt;
+	rs = req->rq_reply_state;
+	if (rs == NULL || !rs->rs_difficult) {
+		/* no notifiers */
+		target_send_reply_msg (req, rc, fail_id);
+		EXIT;
+		return;
+	}
+
+	/* must be an export if locks saved */
+	LASSERT (req->rq_export != NULL);
+	/* req/reply consistent */
+	LASSERT(rs->rs_svcpt == svcpt);
+
+	/* "fresh" reply */
+	LASSERT (!rs->rs_scheduled);
+	LASSERT (!rs->rs_scheduled_ever);
+	LASSERT (!rs->rs_handled);
+	LASSERT (!rs->rs_on_net);
+	LASSERT (rs->rs_export == NULL);
+	LASSERT (list_empty(&rs->rs_obd_list));
+	LASSERT (list_empty(&rs->rs_exp_list));
+
+	exp = class_export_get (req->rq_export);
+
+	/* disable reply scheduling while I'm setting up */
+	rs->rs_scheduled = 1;
+	rs->rs_on_net    = 1;
+	rs->rs_xid       = req->rq_xid;
+	rs->rs_transno   = req->rq_transno;
+	rs->rs_export    = exp;
+	rs->rs_opc       = lustre_msg_get_opc(req->rq_reqmsg);
+
+	spin_lock(&exp->exp_uncommitted_replies_lock);
+	CDEBUG(D_NET, "rs transno = "LPU64", last committed = "LPU64"\n",
+	       rs->rs_transno, exp->exp_last_committed);
+	if (rs->rs_transno > exp->exp_last_committed) {
+		/* not committed already */
+		list_add_tail(&rs->rs_obd_list,
+				  &exp->exp_uncommitted_replies);
+	}
+	spin_unlock(&exp->exp_uncommitted_replies_lock);
+
+	spin_lock(&exp->exp_lock);
+	list_add_tail(&rs->rs_exp_list, &exp->exp_outstanding_replies);
+	spin_unlock(&exp->exp_lock);
+
+	netrc = target_send_reply_msg(req, rc, fail_id);
+
+	spin_lock(&svcpt->scp_rep_lock);
+
+	atomic_inc(&svcpt->scp_nreps_difficult);
+
+	if (netrc != 0) {
+		/* error sending: reply is off the net.  Also we need +1
+		 * reply ref until ptlrpc_handle_rs() is done
+		 * with the reply state (if the send was successful, there
+		 * would have been +1 ref for the net, which
+		 * reply_out_callback leaves alone) */
+		rs->rs_on_net = 0;
+		ptlrpc_rs_addref(rs);
+	}
+
+	spin_lock(&rs->rs_lock);
+	if (rs->rs_transno <= exp->exp_last_committed ||
+	    (!rs->rs_on_net && !rs->rs_no_ack) ||
+	    list_empty(&rs->rs_exp_list) ||     /* completed already */
+	    list_empty(&rs->rs_obd_list)) {
+		CDEBUG(D_HA, "Schedule reply immediately\n");
+		ptlrpc_dispatch_difficult_reply(rs);
+	} else {
+		list_add(&rs->rs_list, &svcpt->scp_rep_active);
+		rs->rs_scheduled = 0;	/* allow notifier to schedule */
+	}
+	spin_unlock(&rs->rs_lock);
+	spin_unlock(&svcpt->scp_rep_lock);
+	EXIT;
+}
+EXPORT_SYMBOL(target_send_reply);
+
+ldlm_mode_t lck_compat_array[] = {
+	[LCK_EX] LCK_COMPAT_EX,
+	[LCK_PW] LCK_COMPAT_PW,
+	[LCK_PR] LCK_COMPAT_PR,
+	[LCK_CW] LCK_COMPAT_CW,
+	[LCK_CR] LCK_COMPAT_CR,
+	[LCK_NL] LCK_COMPAT_NL,
+	[LCK_GROUP] LCK_COMPAT_GROUP,
+	[LCK_COS] LCK_COMPAT_COS,
+};
+
+/**
+ * Rather arbitrary mapping from LDLM error codes to errno values. This should
+ * not escape to the user level.
+ */
+int ldlm_error2errno(ldlm_error_t error)
+{
+	int result;
+
+	switch (error) {
+	case ELDLM_OK:
+		result = 0;
+		break;
+	case ELDLM_LOCK_CHANGED:
+		result = -ESTALE;
+		break;
+	case ELDLM_LOCK_ABORTED:
+		result = -ENAVAIL;
+		break;
+	case ELDLM_LOCK_REPLACED:
+		result = -ESRCH;
+		break;
+	case ELDLM_NO_LOCK_DATA:
+		result = -ENOENT;
+		break;
+	case ELDLM_NAMESPACE_EXISTS:
+		result = -EEXIST;
+		break;
+	case ELDLM_BAD_NAMESPACE:
+		result = -EBADF;
+		break;
+	default:
+		if (((int)error) < 0)  /* cast to signed type */
+			result = error; /* as ldlm_error_t can be unsigned */
+		else {
+			CERROR("Invalid DLM result code: %d\n", error);
+			result = -EPROTO;
+		}
+	}
+	return result;
+}
+EXPORT_SYMBOL(ldlm_error2errno);
+
+/**
+ * Dual to ldlm_error2errno(): maps errno values back to ldlm_error_t.
+ */
+ldlm_error_t ldlm_errno2error(int err_no)
+{
+	int error;
+
+	switch (err_no) {
+	case 0:
+		error = ELDLM_OK;
+		break;
+	case -ESTALE:
+		error = ELDLM_LOCK_CHANGED;
+		break;
+	case -ENAVAIL:
+		error = ELDLM_LOCK_ABORTED;
+		break;
+	case -ESRCH:
+		error = ELDLM_LOCK_REPLACED;
+		break;
+	case -ENOENT:
+		error = ELDLM_NO_LOCK_DATA;
+		break;
+	case -EEXIST:
+		error = ELDLM_NAMESPACE_EXISTS;
+		break;
+	case -EBADF:
+		error = ELDLM_BAD_NAMESPACE;
+		break;
+	default:
+		error = err_no;
+	}
+	return error;
+}
+EXPORT_SYMBOL(ldlm_errno2error);
+
+#if LUSTRE_TRACKS_LOCK_EXP_REFS
+void ldlm_dump_export_locks(struct obd_export *exp)
+{
+	spin_lock(&exp->exp_locks_list_guard);
+	if (!list_empty(&exp->exp_locks_list)) {
+		struct ldlm_lock *lock;
+
+		CERROR("dumping locks for export %p,"
+		       "ignore if the unmount doesn't hang\n", exp);
+		list_for_each_entry(lock, &exp->exp_locks_list,
+					l_exp_refs_link)
+			LDLM_ERROR(lock, "lock:");
+	}
+	spin_unlock(&exp->exp_locks_list_guard);
+}
+#endif
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,2429 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2010, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/ldlm/ldlm_lock.c
+ *
+ * Author: Peter Braam <braam@clusterfs.com>
+ * Author: Phil Schwan <phil@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+# include <linux/libcfs/libcfs.h>
+# include <linux/lustre_intent.h>
+
+#include <obd_class.h>
+#include "ldlm_internal.h"
+
+/* lock types */
+char *ldlm_lockname[] = {
+	[0] "--",
+	[LCK_EX] "EX",
+	[LCK_PW] "PW",
+	[LCK_PR] "PR",
+	[LCK_CW] "CW",
+	[LCK_CR] "CR",
+	[LCK_NL] "NL",
+	[LCK_GROUP] "GROUP",
+	[LCK_COS] "COS"
+};
+EXPORT_SYMBOL(ldlm_lockname);
+
+char *ldlm_typename[] = {
+	[LDLM_PLAIN] "PLN",
+	[LDLM_EXTENT] "EXT",
+	[LDLM_FLOCK] "FLK",
+	[LDLM_IBITS] "IBT",
+};
+EXPORT_SYMBOL(ldlm_typename);
+
+static ldlm_policy_wire_to_local_t ldlm_policy_wire18_to_local[] = {
+	[LDLM_PLAIN - LDLM_MIN_TYPE] ldlm_plain_policy_wire_to_local,
+	[LDLM_EXTENT - LDLM_MIN_TYPE] ldlm_extent_policy_wire_to_local,
+	[LDLM_FLOCK - LDLM_MIN_TYPE] ldlm_flock_policy_wire18_to_local,
+	[LDLM_IBITS - LDLM_MIN_TYPE] ldlm_ibits_policy_wire_to_local,
+};
+
+static ldlm_policy_wire_to_local_t ldlm_policy_wire21_to_local[] = {
+	[LDLM_PLAIN - LDLM_MIN_TYPE] ldlm_plain_policy_wire_to_local,
+	[LDLM_EXTENT - LDLM_MIN_TYPE] ldlm_extent_policy_wire_to_local,
+	[LDLM_FLOCK - LDLM_MIN_TYPE] ldlm_flock_policy_wire21_to_local,
+	[LDLM_IBITS - LDLM_MIN_TYPE] ldlm_ibits_policy_wire_to_local,
+};
+
+static ldlm_policy_local_to_wire_t ldlm_policy_local_to_wire[] = {
+	[LDLM_PLAIN - LDLM_MIN_TYPE] ldlm_plain_policy_local_to_wire,
+	[LDLM_EXTENT - LDLM_MIN_TYPE] ldlm_extent_policy_local_to_wire,
+	[LDLM_FLOCK - LDLM_MIN_TYPE] ldlm_flock_policy_local_to_wire,
+	[LDLM_IBITS - LDLM_MIN_TYPE] ldlm_ibits_policy_local_to_wire,
+};
+
+/**
+ * Converts lock policy from local format to on the wire lock_desc format
+ */
+void ldlm_convert_policy_to_wire(ldlm_type_t type,
+				 const ldlm_policy_data_t *lpolicy,
+				 ldlm_wire_policy_data_t *wpolicy)
+{
+	ldlm_policy_local_to_wire_t convert;
+
+	convert = ldlm_policy_local_to_wire[type - LDLM_MIN_TYPE];
+
+	convert(lpolicy, wpolicy);
+}
+
+/**
+ * Converts lock policy from on the wire lock_desc format to local format
+ */
+void ldlm_convert_policy_to_local(struct obd_export *exp, ldlm_type_t type,
+				  const ldlm_wire_policy_data_t *wpolicy,
+				  ldlm_policy_data_t *lpolicy)
+{
+	ldlm_policy_wire_to_local_t convert;
+	int new_client;
+
+	/** some badness for 2.0.0 clients, but 2.0.0 isn't supported */
+	new_client = (exp_connect_flags(exp) & OBD_CONNECT_FULL20) != 0;
+	if (new_client)
+		convert = ldlm_policy_wire21_to_local[type - LDLM_MIN_TYPE];
+	else
+		convert = ldlm_policy_wire18_to_local[type - LDLM_MIN_TYPE];
+
+	convert(wpolicy, lpolicy);
+}
+
+char *ldlm_it2str(int it)
+{
+	switch (it) {
+	case IT_OPEN:
+		return "open";
+	case IT_CREAT:
+		return "creat";
+	case (IT_OPEN | IT_CREAT):
+		return "open|creat";
+	case IT_READDIR:
+		return "readdir";
+	case IT_GETATTR:
+		return "getattr";
+	case IT_LOOKUP:
+		return "lookup";
+	case IT_UNLINK:
+		return "unlink";
+	case IT_GETXATTR:
+		return "getxattr";
+	case IT_LAYOUT:
+		return "layout";
+	default:
+		CERROR("Unknown intent %d\n", it);
+		return "UNKNOWN";
+	}
+}
+EXPORT_SYMBOL(ldlm_it2str);
+
+extern struct kmem_cache *ldlm_lock_slab;
+
+
+void ldlm_register_intent(struct ldlm_namespace *ns, ldlm_res_policy arg)
+{
+	ns->ns_policy = arg;
+}
+EXPORT_SYMBOL(ldlm_register_intent);
+
+/*
+ * REFCOUNTED LOCK OBJECTS
+ */
+
+
+/**
+ * Get a reference on a lock.
+ *
+ * Lock refcounts, during creation:
+ *   - one special one for allocation, dec'd only once in destroy
+ *   - one for being a lock that's in-use
+ *   - one for the addref associated with a new lock
+ */
+struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock)
+{
+	atomic_inc(&lock->l_refc);
+	return lock;
+}
+EXPORT_SYMBOL(ldlm_lock_get);
+
+/**
+ * Release lock reference.
+ *
+ * Also frees the lock if it was last reference.
+ */
+void ldlm_lock_put(struct ldlm_lock *lock)
+{
+	ENTRY;
+
+	LASSERT(lock->l_resource != LP_POISON);
+	LASSERT(atomic_read(&lock->l_refc) > 0);
+	if (atomic_dec_and_test(&lock->l_refc)) {
+		struct ldlm_resource *res;
+
+		LDLM_DEBUG(lock,
+			   "final lock_put on destroyed lock, freeing it.");
+
+		res = lock->l_resource;
+		LASSERT(lock->l_destroyed);
+		LASSERT(list_empty(&lock->l_res_link));
+		LASSERT(list_empty(&lock->l_pending_chain));
+
+		lprocfs_counter_decr(ldlm_res_to_ns(res)->ns_stats,
+				     LDLM_NSS_LOCKS);
+		lu_ref_del(&res->lr_reference, "lock", lock);
+		ldlm_resource_putref(res);
+		lock->l_resource = NULL;
+		if (lock->l_export) {
+			class_export_lock_put(lock->l_export, lock);
+			lock->l_export = NULL;
+		}
+
+		if (lock->l_lvb_data != NULL)
+			OBD_FREE(lock->l_lvb_data, lock->l_lvb_len);
+
+		ldlm_interval_free(ldlm_interval_detach(lock));
+		lu_ref_fini(&lock->l_reference);
+		OBD_FREE_RCU(lock, sizeof(*lock), &lock->l_handle);
+	}
+
+	EXIT;
+}
+EXPORT_SYMBOL(ldlm_lock_put);
+
+/**
+ * Removes LDLM lock \a lock from LRU. Assumes LRU is already locked.
+ */
+int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock)
+{
+	int rc = 0;
+	if (!list_empty(&lock->l_lru)) {
+		struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
+
+		LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
+		list_del_init(&lock->l_lru);
+		if (lock->l_flags & LDLM_FL_SKIPPED)
+			lock->l_flags &= ~LDLM_FL_SKIPPED;
+		LASSERT(ns->ns_nr_unused > 0);
+		ns->ns_nr_unused--;
+		rc = 1;
+	}
+	return rc;
+}
+
+/**
+ * Removes LDLM lock \a lock from LRU. Obtains the LRU lock first.
+ */
+int ldlm_lock_remove_from_lru(struct ldlm_lock *lock)
+{
+	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
+	int rc;
+
+	ENTRY;
+	if (lock->l_ns_srv) {
+		LASSERT(list_empty(&lock->l_lru));
+		RETURN(0);
+	}
+
+	spin_lock(&ns->ns_lock);
+	rc = ldlm_lock_remove_from_lru_nolock(lock);
+	spin_unlock(&ns->ns_lock);
+	EXIT;
+	return rc;
+}
+
+/**
+ * Adds LDLM lock \a lock to namespace LRU. Assumes LRU is already locked.
+ */
+void ldlm_lock_add_to_lru_nolock(struct ldlm_lock *lock)
+{
+	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
+
+	lock->l_last_used = cfs_time_current();
+	LASSERT(list_empty(&lock->l_lru));
+	LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
+	list_add_tail(&lock->l_lru, &ns->ns_unused_list);
+	LASSERT(ns->ns_nr_unused >= 0);
+	ns->ns_nr_unused++;
+}
+
+/**
+ * Adds LDLM lock \a lock to namespace LRU. Obtains necessary LRU locks
+ * first.
+ */
+void ldlm_lock_add_to_lru(struct ldlm_lock *lock)
+{
+	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
+
+	ENTRY;
+	spin_lock(&ns->ns_lock);
+	ldlm_lock_add_to_lru_nolock(lock);
+	spin_unlock(&ns->ns_lock);
+	EXIT;
+}
+
+/**
+ * Moves LDLM lock \a lock that is already in namespace LRU to the tail of
+ * the LRU. Performs necessary LRU locking
+ */
+void ldlm_lock_touch_in_lru(struct ldlm_lock *lock)
+{
+	struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
+
+	ENTRY;
+	if (lock->l_ns_srv) {
+		LASSERT(list_empty(&lock->l_lru));
+		EXIT;
+		return;
+	}
+
+	spin_lock(&ns->ns_lock);
+	if (!list_empty(&lock->l_lru)) {
+		ldlm_lock_remove_from_lru_nolock(lock);
+		ldlm_lock_add_to_lru_nolock(lock);
+	}
+	spin_unlock(&ns->ns_lock);
+	EXIT;
+}
+
+/**
+ * Helper to destroy a locked lock.
+ *
+ * Used by ldlm_lock_destroy and ldlm_lock_destroy_nolock
+ * Must be called with l_lock and lr_lock held.
+ *
+ * Does not actually free the lock data, but rather marks the lock as
+ * destroyed by setting l_destroyed field in the lock to 1.  Destroys a
+ * handle->lock association too, so that the lock can no longer be found
+ * and removes the lock from LRU list.  Actual lock freeing occurs when
+ * last lock reference goes away.
+ *
+ * Original comment (of some historical value):
+ * This used to have a 'strict' flag, which recovery would use to mark an
+ * in-use lock as needing-to-die.  Lest I am ever tempted to put it back, I
+ * shall explain why it's gone: with the new hash table scheme, once you call
+ * ldlm_lock_destroy, you can never drop your final references on this lock.
+ * Because it's not in the hash table anymore.  -phil
+ */
+int ldlm_lock_destroy_internal(struct ldlm_lock *lock)
+{
+	ENTRY;
+
+	if (lock->l_readers || lock->l_writers) {
+		LDLM_ERROR(lock, "lock still has references");
+		LBUG();
+	}
+
+	if (!list_empty(&lock->l_res_link)) {
+		LDLM_ERROR(lock, "lock still on resource");
+		LBUG();
+	}
+
+	if (lock->l_destroyed) {
+		LASSERT(list_empty(&lock->l_lru));
+		EXIT;
+		return 0;
+	}
+	lock->l_destroyed = 1;
+
+	if (lock->l_export && lock->l_export->exp_lock_hash) {
+		/* NB: it's safe to call cfs_hash_del() even lock isn't
+		 * in exp_lock_hash. */
+		/* In the function below, .hs_keycmp resolves to
+		 * ldlm_export_lock_keycmp() */
+		/* coverity[overrun-buffer-val] */
+		cfs_hash_del(lock->l_export->exp_lock_hash,
+			     &lock->l_remote_handle, &lock->l_exp_hash);
+	}
+
+	ldlm_lock_remove_from_lru(lock);
+	class_handle_unhash(&lock->l_handle);
+
+#if 0
+	/* Wake anyone waiting for this lock */
+	/* FIXME: I should probably add yet another flag, instead of using
+	 * l_export to only call this on clients */
+	if (lock->l_export)
+		class_export_put(lock->l_export);
+	lock->l_export = NULL;
+	if (lock->l_export && lock->l_completion_ast)
+		lock->l_completion_ast(lock, 0);
+#endif
+	EXIT;
+	return 1;
+}
+
+/**
+ * Destroys a LDLM lock \a lock. Performs necessary locking first.
+ */
+void ldlm_lock_destroy(struct ldlm_lock *lock)
+{
+	int first;
+	ENTRY;
+	lock_res_and_lock(lock);
+	first = ldlm_lock_destroy_internal(lock);
+	unlock_res_and_lock(lock);
+
+	/* drop reference from hashtable only for first destroy */
+	if (first) {
+		lu_ref_del(&lock->l_reference, "hash", lock);
+		LDLM_LOCK_RELEASE(lock);
+	}
+	EXIT;
+}
+
+/**
+ * Destroys a LDLM lock \a lock that is already locked.
+ */
+void ldlm_lock_destroy_nolock(struct ldlm_lock *lock)
+{
+	int first;
+	ENTRY;
+	first = ldlm_lock_destroy_internal(lock);
+	/* drop reference from hashtable only for first destroy */
+	if (first) {
+		lu_ref_del(&lock->l_reference, "hash", lock);
+		LDLM_LOCK_RELEASE(lock);
+	}
+	EXIT;
+}
+
+/* this is called by portals_handle2object with the handle lock taken */
+static void lock_handle_addref(void *lock)
+{
+	LDLM_LOCK_GET((struct ldlm_lock *)lock);
+}
+
+static void lock_handle_free(void *lock, int size)
+{
+	LASSERT(size == sizeof(struct ldlm_lock));
+	OBD_SLAB_FREE(lock, ldlm_lock_slab, size);
+}
+
+struct portals_handle_ops lock_handle_ops = {
+	.hop_addref = lock_handle_addref,
+	.hop_free   = lock_handle_free,
+};
+
+/**
+ *
+ * Allocate and initialize new lock structure.
+ *
+ * usage: pass in a resource on which you have done ldlm_resource_get
+ *	new lock will take over the refcount.
+ * returns: lock with refcount 2 - one for current caller and one for remote
+ */
+static struct ldlm_lock *ldlm_lock_new(struct ldlm_resource *resource)
+{
+	struct ldlm_lock *lock;
+	ENTRY;
+
+	if (resource == NULL)
+		LBUG();
+
+	OBD_SLAB_ALLOC_PTR_GFP(lock, ldlm_lock_slab, __GFP_IO);
+	if (lock == NULL)
+		RETURN(NULL);
+
+	spin_lock_init(&lock->l_lock);
+	lock->l_resource = resource;
+	lu_ref_add(&resource->lr_reference, "lock", lock);
+
+	atomic_set(&lock->l_refc, 2);
+	INIT_LIST_HEAD(&lock->l_res_link);
+	INIT_LIST_HEAD(&lock->l_lru);
+	INIT_LIST_HEAD(&lock->l_pending_chain);
+	INIT_LIST_HEAD(&lock->l_bl_ast);
+	INIT_LIST_HEAD(&lock->l_cp_ast);
+	INIT_LIST_HEAD(&lock->l_rk_ast);
+	init_waitqueue_head(&lock->l_waitq);
+	lock->l_blocking_lock = NULL;
+	INIT_LIST_HEAD(&lock->l_sl_mode);
+	INIT_LIST_HEAD(&lock->l_sl_policy);
+	INIT_HLIST_NODE(&lock->l_exp_hash);
+	INIT_HLIST_NODE(&lock->l_exp_flock_hash);
+
+	lprocfs_counter_incr(ldlm_res_to_ns(resource)->ns_stats,
+			     LDLM_NSS_LOCKS);
+	INIT_LIST_HEAD(&lock->l_handle.h_link);
+	class_handle_hash(&lock->l_handle, &lock_handle_ops);
+
+	lu_ref_init(&lock->l_reference);
+	lu_ref_add(&lock->l_reference, "hash", lock);
+	lock->l_callback_timeout = 0;
+
+#if LUSTRE_TRACKS_LOCK_EXP_REFS
+	INIT_LIST_HEAD(&lock->l_exp_refs_link);
+	lock->l_exp_refs_nr = 0;
+	lock->l_exp_refs_target = NULL;
+#endif
+	INIT_LIST_HEAD(&lock->l_exp_list);
+
+	RETURN(lock);
+}
+
+/**
+ * Moves LDLM lock \a lock to another resource.
+ * This is used on client when server returns some other lock than requested
+ * (typically as a result of intent operation)
+ */
+int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock,
+			      const struct ldlm_res_id *new_resid)
+{
+	struct ldlm_resource *oldres = lock->l_resource;
+	struct ldlm_resource *newres;
+	int type;
+	ENTRY;
+
+	LASSERT(ns_is_client(ns));
+
+	lock_res_and_lock(lock);
+	if (memcmp(new_resid, &lock->l_resource->lr_name,
+		   sizeof(lock->l_resource->lr_name)) == 0) {
+		/* Nothing to do */
+		unlock_res_and_lock(lock);
+		RETURN(0);
+	}
+
+	LASSERT(new_resid->name[0] != 0);
+
+	/* This function assumes that the lock isn't on any lists */
+	LASSERT(list_empty(&lock->l_res_link));
+
+	type = oldres->lr_type;
+	unlock_res_and_lock(lock);
+
+	newres = ldlm_resource_get(ns, NULL, new_resid, type, 1);
+	if (newres == NULL)
+		RETURN(-ENOMEM);
+
+	lu_ref_add(&newres->lr_reference, "lock", lock);
+	/*
+	 * To flip the lock from the old to the new resource, lock, oldres and
+	 * newres have to be locked. Resource spin-locks are nested within
+	 * lock->l_lock, and are taken in the memory address order to avoid
+	 * dead-locks.
+	 */
+	spin_lock(&lock->l_lock);
+	oldres = lock->l_resource;
+	if (oldres < newres) {
+		lock_res(oldres);
+		lock_res_nested(newres, LRT_NEW);
+	} else {
+		lock_res(newres);
+		lock_res_nested(oldres, LRT_NEW);
+	}
+	LASSERT(memcmp(new_resid, &oldres->lr_name,
+		       sizeof oldres->lr_name) != 0);
+	lock->l_resource = newres;
+	unlock_res(oldres);
+	unlock_res_and_lock(lock);
+
+	/* ...and the flowers are still standing! */
+	lu_ref_del(&oldres->lr_reference, "lock", lock);
+	ldlm_resource_putref(oldres);
+
+	RETURN(0);
+}
+EXPORT_SYMBOL(ldlm_lock_change_resource);
+
+/** \defgroup ldlm_handles LDLM HANDLES
+ * Ways to get hold of locks without any addresses.
+ * @{
+ */
+
+/**
+ * Fills in handle for LDLM lock \a lock into supplied \a lockh
+ * Does not take any references.
+ */
+void ldlm_lock2handle(const struct ldlm_lock *lock, struct lustre_handle *lockh)
+{
+	lockh->cookie = lock->l_handle.h_cookie;
+}
+EXPORT_SYMBOL(ldlm_lock2handle);
+
+/**
+ * Obtain a lock reference by handle.
+ *
+ * if \a flags: atomically get the lock and set the flags.
+ *	      Return NULL if flag already set
+ */
+struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *handle,
+				     __u64 flags)
+{
+	struct ldlm_lock *lock;
+	ENTRY;
+
+	LASSERT(handle);
+
+	lock = class_handle2object(handle->cookie);
+	if (lock == NULL)
+		RETURN(NULL);
+
+	/* It's unlikely but possible that someone marked the lock as
+	 * destroyed after we did handle2object on it */
+	if (flags == 0 && !lock->l_destroyed) {
+		lu_ref_add(&lock->l_reference, "handle", current);
+		RETURN(lock);
+	}
+
+	lock_res_and_lock(lock);
+
+	LASSERT(lock->l_resource != NULL);
+
+	lu_ref_add_atomic(&lock->l_reference, "handle", current);
+	if (unlikely(lock->l_destroyed)) {
+		unlock_res_and_lock(lock);
+		CDEBUG(D_INFO, "lock already destroyed: lock %p\n", lock);
+		LDLM_LOCK_PUT(lock);
+		RETURN(NULL);
+	}
+
+	if (flags && (lock->l_flags & flags)) {
+		unlock_res_and_lock(lock);
+		LDLM_LOCK_PUT(lock);
+		RETURN(NULL);
+	}
+
+	if (flags)
+		lock->l_flags |= flags;
+
+	unlock_res_and_lock(lock);
+	RETURN(lock);
+}
+EXPORT_SYMBOL(__ldlm_handle2lock);
+/** @} ldlm_handles */
+
+/**
+ * Fill in "on the wire" representation for given LDLM lock into supplied
+ * lock descriptor \a desc structure.
+ */
+void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc)
+{
+	struct obd_export *exp = lock->l_export ?: lock->l_conn_export;
+
+	/* INODEBITS_INTEROP: If the other side does not support
+	 * inodebits, reply with a plain lock descriptor. */
+	if ((lock->l_resource->lr_type == LDLM_IBITS) &&
+	    (exp && !(exp_connect_flags(exp) & OBD_CONNECT_IBITS))) {
+		/* Make sure all the right bits are set in this lock we
+		   are going to pass to client */
+		LASSERTF(lock->l_policy_data.l_inodebits.bits ==
+			 (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE |
+			  MDS_INODELOCK_LAYOUT),
+			 "Inappropriate inode lock bits during "
+			 "conversion " LPU64 "\n",
+			 lock->l_policy_data.l_inodebits.bits);
+
+		ldlm_res2desc(lock->l_resource, &desc->l_resource);
+		desc->l_resource.lr_type = LDLM_PLAIN;
+
+		/* Convert "new" lock mode to something old client can
+		   understand */
+		if ((lock->l_req_mode == LCK_CR) ||
+		    (lock->l_req_mode == LCK_CW))
+			desc->l_req_mode = LCK_PR;
+		else
+			desc->l_req_mode = lock->l_req_mode;
+		if ((lock->l_granted_mode == LCK_CR) ||
+		    (lock->l_granted_mode == LCK_CW)) {
+			desc->l_granted_mode = LCK_PR;
+		} else {
+			/* We never grant PW/EX locks to clients */
+			LASSERT((lock->l_granted_mode != LCK_PW) &&
+				(lock->l_granted_mode != LCK_EX));
+			desc->l_granted_mode = lock->l_granted_mode;
+		}
+
+		/* We do not copy policy here, because there is no
+		   policy for plain locks */
+	} else {
+		ldlm_res2desc(lock->l_resource, &desc->l_resource);
+		desc->l_req_mode = lock->l_req_mode;
+		desc->l_granted_mode = lock->l_granted_mode;
+		ldlm_convert_policy_to_wire(lock->l_resource->lr_type,
+					    &lock->l_policy_data,
+					    &desc->l_policy_data);
+	}
+}
+EXPORT_SYMBOL(ldlm_lock2desc);
+
+/**
+ * Add a lock to list of conflicting locks to send AST to.
+ *
+ * Only add if we have not sent a blocking AST to the lock yet.
+ */
+void ldlm_add_bl_work_item(struct ldlm_lock *lock, struct ldlm_lock *new,
+			   struct list_head *work_list)
+{
+	if ((lock->l_flags & LDLM_FL_AST_SENT) == 0) {
+		LDLM_DEBUG(lock, "lock incompatible; sending blocking AST.");
+		lock->l_flags |= LDLM_FL_AST_SENT;
+		/* If the enqueuing client said so, tell the AST recipient to
+		 * discard dirty data, rather than writing back. */
+		if (new->l_flags & LDLM_AST_DISCARD_DATA)
+			lock->l_flags |= LDLM_FL_DISCARD_DATA;
+		LASSERT(list_empty(&lock->l_bl_ast));
+		list_add(&lock->l_bl_ast, work_list);
+		LDLM_LOCK_GET(lock);
+		LASSERT(lock->l_blocking_lock == NULL);
+		lock->l_blocking_lock = LDLM_LOCK_GET(new);
+	}
+}
+
+/**
+ * Add a lock to list of just granted locks to send completion AST to.
+ */
+void ldlm_add_cp_work_item(struct ldlm_lock *lock, struct list_head *work_list)
+{
+	if ((lock->l_flags & LDLM_FL_CP_REQD) == 0) {
+		lock->l_flags |= LDLM_FL_CP_REQD;
+		LDLM_DEBUG(lock, "lock granted; sending completion AST.");
+		LASSERT(list_empty(&lock->l_cp_ast));
+		list_add(&lock->l_cp_ast, work_list);
+		LDLM_LOCK_GET(lock);
+	}
+}
+
+/**
+ * Aggregator function to add AST work items into a list. Determines
+ * what sort of an AST work needs to be done and calls the proper
+ * adding function.
+ * Must be called with lr_lock held.
+ */
+void ldlm_add_ast_work_item(struct ldlm_lock *lock, struct ldlm_lock *new,
+			    struct list_head *work_list)
+{
+	ENTRY;
+	check_res_locked(lock->l_resource);
+	if (new)
+		ldlm_add_bl_work_item(lock, new, work_list);
+	else
+		ldlm_add_cp_work_item(lock, work_list);
+	EXIT;
+}
+
+/**
+ * Add specified reader/writer reference to LDLM lock with handle \a lockh.
+ * r/w reference type is determined by \a mode
+ * Calls ldlm_lock_addref_internal.
+ */
+void ldlm_lock_addref(struct lustre_handle *lockh, __u32 mode)
+{
+	struct ldlm_lock *lock;
+
+	lock = ldlm_handle2lock(lockh);
+	LASSERT(lock != NULL);
+	ldlm_lock_addref_internal(lock, mode);
+	LDLM_LOCK_PUT(lock);
+}
+EXPORT_SYMBOL(ldlm_lock_addref);
+
+/**
+ * Helper function.
+ * Add specified reader/writer reference to LDLM lock \a lock.
+ * r/w reference type is determined by \a mode
+ * Removes lock from LRU if it is there.
+ * Assumes the LDLM lock is already locked.
+ */
+void ldlm_lock_addref_internal_nolock(struct ldlm_lock *lock, __u32 mode)
+{
+	ldlm_lock_remove_from_lru(lock);
+	if (mode & (LCK_NL | LCK_CR | LCK_PR)) {
+		lock->l_readers++;
+		lu_ref_add_atomic(&lock->l_reference, "reader", lock);
+	}
+	if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS)) {
+		lock->l_writers++;
+		lu_ref_add_atomic(&lock->l_reference, "writer", lock);
+	}
+	LDLM_LOCK_GET(lock);
+	lu_ref_add_atomic(&lock->l_reference, "user", lock);
+	LDLM_DEBUG(lock, "ldlm_lock_addref(%s)", ldlm_lockname[mode]);
+}
+
+/**
+ * Attempts to add reader/writer reference to a lock with handle \a lockh, and
+ * fails if lock is already LDLM_FL_CBPENDING or destroyed.
+ *
+ * \retval 0 success, lock was addref-ed
+ *
+ * \retval -EAGAIN lock is being canceled.
+ */
+int ldlm_lock_addref_try(struct lustre_handle *lockh, __u32 mode)
+{
+	struct ldlm_lock *lock;
+	int	       result;
+
+	result = -EAGAIN;
+	lock = ldlm_handle2lock(lockh);
+	if (lock != NULL) {
+		lock_res_and_lock(lock);
+		if (lock->l_readers != 0 || lock->l_writers != 0 ||
+		    !(lock->l_flags & LDLM_FL_CBPENDING)) {
+			ldlm_lock_addref_internal_nolock(lock, mode);
+			result = 0;
+		}
+		unlock_res_and_lock(lock);
+		LDLM_LOCK_PUT(lock);
+	}
+	return result;
+}
+EXPORT_SYMBOL(ldlm_lock_addref_try);
+
+/**
+ * Add specified reader/writer reference to LDLM lock \a lock.
+ * Locks LDLM lock and calls ldlm_lock_addref_internal_nolock to do the work.
+ * Only called for local locks.
+ */
+void ldlm_lock_addref_internal(struct ldlm_lock *lock, __u32 mode)
+{
+	lock_res_and_lock(lock);
+	ldlm_lock_addref_internal_nolock(lock, mode);
+	unlock_res_and_lock(lock);
+}
+
+/**
+ * Removes reader/writer reference for LDLM lock \a lock.
+ * Assumes LDLM lock is already locked.
+ * only called in ldlm_flock_destroy and for local locks.
+ * Does NOT add lock to LRU if no r/w references left to accomodate flock locks
+ * that cannot be placed in LRU.
+ */
+void ldlm_lock_decref_internal_nolock(struct ldlm_lock *lock, __u32 mode)
+{
+	LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]);
+	if (mode & (LCK_NL | LCK_CR | LCK_PR)) {
+		LASSERT(lock->l_readers > 0);
+		lu_ref_del(&lock->l_reference, "reader", lock);
+		lock->l_readers--;
+	}
+	if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS)) {
+		LASSERT(lock->l_writers > 0);
+		lu_ref_del(&lock->l_reference, "writer", lock);
+		lock->l_writers--;
+	}
+
+	lu_ref_del(&lock->l_reference, "user", lock);
+	LDLM_LOCK_RELEASE(lock);    /* matches the LDLM_LOCK_GET() in addref */
+}
+
+/**
+ * Removes reader/writer reference for LDLM lock \a lock.
+ * Locks LDLM lock first.
+ * If the lock is determined to be client lock on a client and r/w refcount
+ * drops to zero and the lock is not blocked, the lock is added to LRU lock
+ * on the namespace.
+ * For blocked LDLM locks if r/w count drops to zero, blocking_ast is called.
+ */
+void ldlm_lock_decref_internal(struct ldlm_lock *lock, __u32 mode)
+{
+	struct ldlm_namespace *ns;
+	ENTRY;
+
+	lock_res_and_lock(lock);
+
+	ns = ldlm_lock_to_ns(lock);
+
+	ldlm_lock_decref_internal_nolock(lock, mode);
+
+	if (lock->l_flags & LDLM_FL_LOCAL &&
+	    !lock->l_readers && !lock->l_writers) {
+		/* If this is a local lock on a server namespace and this was
+		 * the last reference, cancel the lock. */
+		CDEBUG(D_INFO, "forcing cancel of local lock\n");
+		lock->l_flags |= LDLM_FL_CBPENDING;
+	}
+
+	if (!lock->l_readers && !lock->l_writers &&
+	    (lock->l_flags & LDLM_FL_CBPENDING)) {
+		/* If we received a blocked AST and this was the last reference,
+		 * run the callback. */
+		if (lock->l_ns_srv && lock->l_export)
+			CERROR("FL_CBPENDING set on non-local lock--just a "
+			       "warning\n");
+
+		LDLM_DEBUG(lock, "final decref done on cbpending lock");
+
+		LDLM_LOCK_GET(lock); /* dropped by bl thread */
+		ldlm_lock_remove_from_lru(lock);
+		unlock_res_and_lock(lock);
+
+		if (lock->l_flags & LDLM_FL_FAIL_LOC)
+			OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE);
+
+		if ((lock->l_flags & LDLM_FL_ATOMIC_CB) ||
+		    ldlm_bl_to_thread_lock(ns, NULL, lock) != 0)
+			ldlm_handle_bl_callback(ns, NULL, lock);
+	} else if (ns_is_client(ns) &&
+		   !lock->l_readers && !lock->l_writers &&
+		   !(lock->l_flags & LDLM_FL_NO_LRU) &&
+		   !(lock->l_flags & LDLM_FL_BL_AST)) {
+
+		LDLM_DEBUG(lock, "add lock into lru list");
+
+		/* If this is a client-side namespace and this was the last
+		 * reference, put it on the LRU. */
+		ldlm_lock_add_to_lru(lock);
+		unlock_res_and_lock(lock);
+
+		if (lock->l_flags & LDLM_FL_FAIL_LOC)
+			OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE);
+
+		/* Call ldlm_cancel_lru() only if EARLY_CANCEL and LRU RESIZE
+		 * are not supported by the server, otherwise, it is done on
+		 * enqueue. */
+		if (!exp_connect_cancelset(lock->l_conn_export) &&
+		    !ns_connect_lru_resize(ns))
+			ldlm_cancel_lru(ns, 0, LCF_ASYNC, 0);
+	} else {
+		LDLM_DEBUG(lock, "do not add lock into lru list");
+		unlock_res_and_lock(lock);
+	}
+
+	EXIT;
+}
+
+/**
+ * Decrease reader/writer refcount for LDLM lock with handle \a lockh
+ */
+void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode)
+{
+	struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0);
+	LASSERTF(lock != NULL, "Non-existing lock: "LPX64"\n", lockh->cookie);
+	ldlm_lock_decref_internal(lock, mode);
+	LDLM_LOCK_PUT(lock);
+}
+EXPORT_SYMBOL(ldlm_lock_decref);
+
+/**
+ * Decrease reader/writer refcount for LDLM lock with handle
+ * \a lockh and mark it for subsequent cancellation once r/w refcount
+ * drops to zero instead of putting into LRU.
+ *
+ * Typical usage is for GROUP locks which we cannot allow to be cached.
+ */
+void ldlm_lock_decref_and_cancel(struct lustre_handle *lockh, __u32 mode)
+{
+	struct ldlm_lock *lock = __ldlm_handle2lock(lockh, 0);
+	ENTRY;
+
+	LASSERT(lock != NULL);
+
+	LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]);
+	lock_res_and_lock(lock);
+	lock->l_flags |= LDLM_FL_CBPENDING;
+	unlock_res_and_lock(lock);
+	ldlm_lock_decref_internal(lock, mode);
+	LDLM_LOCK_PUT(lock);
+}
+EXPORT_SYMBOL(ldlm_lock_decref_and_cancel);
+
+struct sl_insert_point {
+	struct list_head *res_link;
+	struct list_head *mode_link;
+	struct list_head *policy_link;
+};
+
+/**
+ * Finds a position to insert the new lock into granted lock list.
+ *
+ * Used for locks eligible for skiplist optimization.
+ *
+ * Parameters:
+ *      queue [input]:  the granted list where search acts on;
+ *      req [input]:    the lock whose position to be located;
+ *      prev [output]:  positions within 3 lists to insert @req to
+ * Return Value:
+ *      filled @prev
+ * NOTE: called by
+ *  - ldlm_grant_lock_with_skiplist
+ */
+static void search_granted_lock(struct list_head *queue,
+				struct ldlm_lock *req,
+				struct sl_insert_point *prev)
+{
+	struct list_head *tmp;
+	struct ldlm_lock *lock, *mode_end, *policy_end;
+	ENTRY;
+
+	list_for_each(tmp, queue) {
+		lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+
+		mode_end = list_entry(lock->l_sl_mode.prev,
+					  struct ldlm_lock, l_sl_mode);
+
+		if (lock->l_req_mode != req->l_req_mode) {
+			/* jump to last lock of mode group */
+			tmp = &mode_end->l_res_link;
+			continue;
+		}
+
+		/* suitable mode group is found */
+		if (lock->l_resource->lr_type == LDLM_PLAIN) {
+			/* insert point is last lock of the mode group */
+			prev->res_link = &mode_end->l_res_link;
+			prev->mode_link = &mode_end->l_sl_mode;
+			prev->policy_link = &req->l_sl_policy;
+			EXIT;
+			return;
+		} else if (lock->l_resource->lr_type == LDLM_IBITS) {
+			for (;;) {
+				policy_end =
+					list_entry(lock->l_sl_policy.prev,
+						       struct ldlm_lock,
+						       l_sl_policy);
+
+				if (lock->l_policy_data.l_inodebits.bits ==
+				    req->l_policy_data.l_inodebits.bits) {
+					/* insert point is last lock of
+					 * the policy group */
+					prev->res_link =
+						&policy_end->l_res_link;
+					prev->mode_link =
+						&policy_end->l_sl_mode;
+					prev->policy_link =
+						&policy_end->l_sl_policy;
+					EXIT;
+					return;
+				}
+
+				if (policy_end == mode_end)
+					/* done with mode group */
+					break;
+
+				/* go to next policy group within mode group */
+				tmp = policy_end->l_res_link.next;
+				lock = list_entry(tmp, struct ldlm_lock,
+						      l_res_link);
+			}  /* loop over policy groups within the mode group */
+
+			/* insert point is last lock of the mode group,
+			 * new policy group is started */
+			prev->res_link = &mode_end->l_res_link;
+			prev->mode_link = &mode_end->l_sl_mode;
+			prev->policy_link = &req->l_sl_policy;
+			EXIT;
+			return;
+		} else {
+			LDLM_ERROR(lock,"is not LDLM_PLAIN or LDLM_IBITS lock");
+			LBUG();
+		}
+	}
+
+	/* insert point is last lock on the queue,
+	 * new mode group and new policy group are started */
+	prev->res_link = queue->prev;
+	prev->mode_link = &req->l_sl_mode;
+	prev->policy_link = &req->l_sl_policy;
+	EXIT;
+	return;
+}
+
+/**
+ * Add a lock into resource granted list after a position described by
+ * \a prev.
+ */
+static void ldlm_granted_list_add_lock(struct ldlm_lock *lock,
+				       struct sl_insert_point *prev)
+{
+	struct ldlm_resource *res = lock->l_resource;
+	ENTRY;
+
+	check_res_locked(res);
+
+	ldlm_resource_dump(D_INFO, res);
+	LDLM_DEBUG(lock, "About to add lock:");
+
+	if (lock->l_destroyed) {
+		CDEBUG(D_OTHER, "Lock destroyed, not adding to resource\n");
+		return;
+	}
+
+	LASSERT(list_empty(&lock->l_res_link));
+	LASSERT(list_empty(&lock->l_sl_mode));
+	LASSERT(list_empty(&lock->l_sl_policy));
+
+	/*
+	 * lock->link == prev->link means lock is first starting the group.
+	 * Don't re-add to itself to suppress kernel warnings.
+	 */
+	if (&lock->l_res_link != prev->res_link)
+		list_add(&lock->l_res_link, prev->res_link);
+	if (&lock->l_sl_mode != prev->mode_link)
+		list_add(&lock->l_sl_mode, prev->mode_link);
+	if (&lock->l_sl_policy != prev->policy_link)
+		list_add(&lock->l_sl_policy, prev->policy_link);
+
+	EXIT;
+}
+
+/**
+ * Add a lock to granted list on a resource maintaining skiplist
+ * correctness.
+ */
+static void ldlm_grant_lock_with_skiplist(struct ldlm_lock *lock)
+{
+	struct sl_insert_point prev;
+	ENTRY;
+
+	LASSERT(lock->l_req_mode == lock->l_granted_mode);
+
+	search_granted_lock(&lock->l_resource->lr_granted, lock, &prev);
+	ldlm_granted_list_add_lock(lock, &prev);
+	EXIT;
+}
+
+/**
+ * Perform lock granting bookkeeping.
+ *
+ * Includes putting the lock into granted list and updating lock mode.
+ * NOTE: called by
+ *  - ldlm_lock_enqueue
+ *  - ldlm_reprocess_queue
+ *  - ldlm_lock_convert
+ *
+ * must be called with lr_lock held
+ */
+void ldlm_grant_lock(struct ldlm_lock *lock, struct list_head *work_list)
+{
+	struct ldlm_resource *res = lock->l_resource;
+	ENTRY;
+
+	check_res_locked(res);
+
+	lock->l_granted_mode = lock->l_req_mode;
+	if (res->lr_type == LDLM_PLAIN || res->lr_type == LDLM_IBITS)
+		ldlm_grant_lock_with_skiplist(lock);
+	else if (res->lr_type == LDLM_EXTENT)
+		ldlm_extent_add_lock(res, lock);
+	else
+		ldlm_resource_add_lock(res, &res->lr_granted, lock);
+
+	if (lock->l_granted_mode < res->lr_most_restr)
+		res->lr_most_restr = lock->l_granted_mode;
+
+	if (work_list && lock->l_completion_ast != NULL)
+		ldlm_add_ast_work_item(lock, NULL, work_list);
+
+	ldlm_pool_add(&ldlm_res_to_ns(res)->ns_pool, lock);
+	EXIT;
+}
+
+/**
+ * Search for a lock with given properties in a queue.
+ *
+ * \retval a referenced lock or NULL.  See the flag descriptions below, in the
+ * comment above ldlm_lock_match
+ */
+static struct ldlm_lock *search_queue(struct list_head *queue,
+				      ldlm_mode_t *mode,
+				      ldlm_policy_data_t *policy,
+				      struct ldlm_lock *old_lock,
+				      __u64 flags, int unref)
+{
+	struct ldlm_lock *lock;
+	struct list_head       *tmp;
+
+	list_for_each(tmp, queue) {
+		ldlm_mode_t match;
+
+		lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+
+		if (lock == old_lock)
+			break;
+
+		/* llite sometimes wants to match locks that will be
+		 * canceled when their users drop, but we allow it to match
+		 * if it passes in CBPENDING and the lock still has users.
+		 * this is generally only going to be used by children
+		 * whose parents already hold a lock so forward progress
+		 * can still happen. */
+		if (lock->l_flags & LDLM_FL_CBPENDING &&
+		    !(flags & LDLM_FL_CBPENDING))
+			continue;
+		if (!unref && lock->l_flags & LDLM_FL_CBPENDING &&
+		    lock->l_readers == 0 && lock->l_writers == 0)
+			continue;
+
+		if (!(lock->l_req_mode & *mode))
+			continue;
+		match = lock->l_req_mode;
+
+		if (lock->l_resource->lr_type == LDLM_EXTENT &&
+		    (lock->l_policy_data.l_extent.start >
+		     policy->l_extent.start ||
+		     lock->l_policy_data.l_extent.end < policy->l_extent.end))
+			continue;
+
+		if (unlikely(match == LCK_GROUP) &&
+		    lock->l_resource->lr_type == LDLM_EXTENT &&
+		    lock->l_policy_data.l_extent.gid != policy->l_extent.gid)
+			continue;
+
+		/* We match if we have existing lock with same or wider set
+		   of bits. */
+		if (lock->l_resource->lr_type == LDLM_IBITS &&
+		     ((lock->l_policy_data.l_inodebits.bits &
+		      policy->l_inodebits.bits) !=
+		      policy->l_inodebits.bits))
+			continue;
+
+		if (!unref &&
+		    (lock->l_destroyed || lock->l_flags & LDLM_FL_FAILED ||
+		     lock->l_failed))
+			continue;
+
+		if ((flags & LDLM_FL_LOCAL_ONLY) &&
+		    !(lock->l_flags & LDLM_FL_LOCAL))
+			continue;
+
+		if (flags & LDLM_FL_TEST_LOCK) {
+			LDLM_LOCK_GET(lock);
+			ldlm_lock_touch_in_lru(lock);
+		} else {
+			ldlm_lock_addref_internal_nolock(lock, match);
+		}
+		*mode = match;
+		return lock;
+	}
+
+	return NULL;
+}
+
+void ldlm_lock_fail_match_locked(struct ldlm_lock *lock)
+{
+	if (!lock->l_failed) {
+		lock->l_failed = 1;
+		wake_up_all(&lock->l_waitq);
+	}
+}
+EXPORT_SYMBOL(ldlm_lock_fail_match_locked);
+
+void ldlm_lock_fail_match(struct ldlm_lock *lock)
+{
+	lock_res_and_lock(lock);
+	ldlm_lock_fail_match_locked(lock);
+	unlock_res_and_lock(lock);
+}
+EXPORT_SYMBOL(ldlm_lock_fail_match);
+
+/**
+ * Mark lock as "matchable" by OST.
+ *
+ * Used to prevent certain races in LOV/OSC where the lock is granted, but LVB
+ * is not yet valid.
+ * Assumes LDLM lock is already locked.
+ */
+void ldlm_lock_allow_match_locked(struct ldlm_lock *lock)
+{
+	lock->l_flags |= LDLM_FL_LVB_READY;
+	wake_up_all(&lock->l_waitq);
+}
+EXPORT_SYMBOL(ldlm_lock_allow_match_locked);
+
+/**
+ * Mark lock as "matchable" by OST.
+ * Locks the lock and then \see ldlm_lock_allow_match_locked
+ */
+void ldlm_lock_allow_match(struct ldlm_lock *lock)
+{
+	lock_res_and_lock(lock);
+	ldlm_lock_allow_match_locked(lock);
+	unlock_res_and_lock(lock);
+}
+EXPORT_SYMBOL(ldlm_lock_allow_match);
+
+/**
+ * Attempt to find a lock with specified properties.
+ *
+ * Typically returns a reference to matched lock unless LDLM_FL_TEST_LOCK is
+ * set in \a flags
+ *
+ * Can be called in two ways:
+ *
+ * If 'ns' is NULL, then lockh describes an existing lock that we want to look
+ * for a duplicate of.
+ *
+ * Otherwise, all of the fields must be filled in, to match against.
+ *
+ * If 'flags' contains LDLM_FL_LOCAL_ONLY, then only match local locks on the
+ *     server (ie, connh is NULL)
+ * If 'flags' contains LDLM_FL_BLOCK_GRANTED, then only locks on the granted
+ *     list will be considered
+ * If 'flags' contains LDLM_FL_CBPENDING, then locks that have been marked
+ *     to be canceled can still be matched as long as they still have reader
+ *     or writer refernces
+ * If 'flags' contains LDLM_FL_TEST_LOCK, then don't actually reference a lock,
+ *     just tell us if we would have matched.
+ *
+ * \retval 1 if it finds an already-existing lock that is compatible; in this
+ * case, lockh is filled in with a addref()ed lock
+ *
+ * We also check security context, and if that fails we simply return 0 (to
+ * keep caller code unchanged), the context failure will be discovered by
+ * caller sometime later.
+ */
+ldlm_mode_t ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
+			    const struct ldlm_res_id *res_id, ldlm_type_t type,
+			    ldlm_policy_data_t *policy, ldlm_mode_t mode,
+			    struct lustre_handle *lockh, int unref)
+{
+	struct ldlm_resource *res;
+	struct ldlm_lock *lock, *old_lock = NULL;
+	int rc = 0;
+	ENTRY;
+
+	if (ns == NULL) {
+		old_lock = ldlm_handle2lock(lockh);
+		LASSERT(old_lock);
+
+		ns = ldlm_lock_to_ns(old_lock);
+		res_id = &old_lock->l_resource->lr_name;
+		type = old_lock->l_resource->lr_type;
+		mode = old_lock->l_req_mode;
+	}
+
+	res = ldlm_resource_get(ns, NULL, res_id, type, 0);
+	if (res == NULL) {
+		LASSERT(old_lock == NULL);
+		RETURN(0);
+	}
+
+	LDLM_RESOURCE_ADDREF(res);
+	lock_res(res);
+
+	lock = search_queue(&res->lr_granted, &mode, policy, old_lock,
+			    flags, unref);
+	if (lock != NULL)
+		GOTO(out, rc = 1);
+	if (flags & LDLM_FL_BLOCK_GRANTED)
+		GOTO(out, rc = 0);
+	lock = search_queue(&res->lr_converting, &mode, policy, old_lock,
+			    flags, unref);
+	if (lock != NULL)
+		GOTO(out, rc = 1);
+	lock = search_queue(&res->lr_waiting, &mode, policy, old_lock,
+			    flags, unref);
+	if (lock != NULL)
+		GOTO(out, rc = 1);
+
+	EXIT;
+ out:
+	unlock_res(res);
+	LDLM_RESOURCE_DELREF(res);
+	ldlm_resource_putref(res);
+
+	if (lock) {
+		ldlm_lock2handle(lock, lockh);
+		if ((flags & LDLM_FL_LVB_READY) &&
+		    (!(lock->l_flags & LDLM_FL_LVB_READY))) {
+			struct l_wait_info lwi;
+			if (lock->l_completion_ast) {
+				int err = lock->l_completion_ast(lock,
+							  LDLM_FL_WAIT_NOREPROC,
+								 NULL);
+				if (err) {
+					if (flags & LDLM_FL_TEST_LOCK)
+						LDLM_LOCK_RELEASE(lock);
+					else
+						ldlm_lock_decref_internal(lock,
+									  mode);
+					rc = 0;
+					goto out2;
+				}
+			}
+
+			lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(obd_timeout),
+					       NULL, LWI_ON_SIGNAL_NOOP, NULL);
+
+			/* XXX FIXME see comment on CAN_MATCH in lustre_dlm.h */
+			l_wait_event(lock->l_waitq,
+				     lock->l_flags & LDLM_FL_LVB_READY ||
+				     lock->l_destroyed || lock->l_failed,
+				     &lwi);
+			if (!(lock->l_flags & LDLM_FL_LVB_READY)) {
+				if (flags & LDLM_FL_TEST_LOCK)
+					LDLM_LOCK_RELEASE(lock);
+				else
+					ldlm_lock_decref_internal(lock, mode);
+				rc = 0;
+			}
+		}
+	}
+ out2:
+	if (rc) {
+		LDLM_DEBUG(lock, "matched ("LPU64" "LPU64")",
+			   (type == LDLM_PLAIN || type == LDLM_IBITS) ?
+				res_id->name[2] : policy->l_extent.start,
+			   (type == LDLM_PLAIN || type == LDLM_IBITS) ?
+				res_id->name[3] : policy->l_extent.end);
+
+		/* check user's security context */
+		if (lock->l_conn_export &&
+		    sptlrpc_import_check_ctx(
+				class_exp2cliimp(lock->l_conn_export))) {
+			if (!(flags & LDLM_FL_TEST_LOCK))
+				ldlm_lock_decref_internal(lock, mode);
+			rc = 0;
+		}
+
+		if (flags & LDLM_FL_TEST_LOCK)
+			LDLM_LOCK_RELEASE(lock);
+
+	} else if (!(flags & LDLM_FL_TEST_LOCK)) {/*less verbose for test-only*/
+		LDLM_DEBUG_NOLOCK("not matched ns %p type %u mode %u res "
+				  LPU64"/"LPU64" ("LPU64" "LPU64")", ns,
+				  type, mode, res_id->name[0], res_id->name[1],
+				  (type == LDLM_PLAIN || type == LDLM_IBITS) ?
+					res_id->name[2] :policy->l_extent.start,
+				  (type == LDLM_PLAIN || type == LDLM_IBITS) ?
+					res_id->name[3] : policy->l_extent.end);
+	}
+	if (old_lock)
+		LDLM_LOCK_PUT(old_lock);
+
+	return rc ? mode : 0;
+}
+EXPORT_SYMBOL(ldlm_lock_match);
+
+ldlm_mode_t ldlm_revalidate_lock_handle(struct lustre_handle *lockh,
+					__u64 *bits)
+{
+	struct ldlm_lock *lock;
+	ldlm_mode_t mode = 0;
+	ENTRY;
+
+	lock = ldlm_handle2lock(lockh);
+	if (lock != NULL) {
+		lock_res_and_lock(lock);
+		if (lock->l_destroyed || lock->l_flags & LDLM_FL_FAILED ||
+		    lock->l_failed)
+			GOTO(out, mode);
+
+		if (lock->l_flags & LDLM_FL_CBPENDING &&
+		    lock->l_readers == 0 && lock->l_writers == 0)
+			GOTO(out, mode);
+
+		if (bits)
+			*bits = lock->l_policy_data.l_inodebits.bits;
+		mode = lock->l_granted_mode;
+		ldlm_lock_addref_internal_nolock(lock, mode);
+	}
+
+	EXIT;
+
+out:
+	if (lock != NULL) {
+		unlock_res_and_lock(lock);
+		LDLM_LOCK_PUT(lock);
+	}
+	return mode;
+}
+EXPORT_SYMBOL(ldlm_revalidate_lock_handle);
+
+/** The caller must guarantee that the buffer is large enough. */
+int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill,
+		  enum req_location loc, void *data, int size)
+{
+	void *lvb;
+	ENTRY;
+
+	LASSERT(data != NULL);
+	LASSERT(size >= 0);
+
+	switch (lock->l_lvb_type) {
+	case LVB_T_OST:
+		if (size == sizeof(struct ost_lvb)) {
+			if (loc == RCL_CLIENT)
+				lvb = req_capsule_client_swab_get(pill,
+						&RMF_DLM_LVB,
+						lustre_swab_ost_lvb);
+			else
+				lvb = req_capsule_server_swab_get(pill,
+						&RMF_DLM_LVB,
+						lustre_swab_ost_lvb);
+			if (unlikely(lvb == NULL)) {
+				LDLM_ERROR(lock, "no LVB");
+				RETURN(-EPROTO);
+			}
+
+			memcpy(data, lvb, size);
+		} else if (size == sizeof(struct ost_lvb_v1)) {
+			struct ost_lvb *olvb = data;
+
+			if (loc == RCL_CLIENT)
+				lvb = req_capsule_client_swab_get(pill,
+						&RMF_DLM_LVB,
+						lustre_swab_ost_lvb_v1);
+			else
+				lvb = req_capsule_server_sized_swab_get(pill,
+						&RMF_DLM_LVB, size,
+						lustre_swab_ost_lvb_v1);
+			if (unlikely(lvb == NULL)) {
+				LDLM_ERROR(lock, "no LVB");
+				RETURN(-EPROTO);
+			}
+
+			memcpy(data, lvb, size);
+			olvb->lvb_mtime_ns = 0;
+			olvb->lvb_atime_ns = 0;
+			olvb->lvb_ctime_ns = 0;
+		} else {
+			LDLM_ERROR(lock, "Replied unexpected ost LVB size %d",
+				   size);
+			RETURN(-EINVAL);
+		}
+		break;
+	case LVB_T_LQUOTA:
+		if (size == sizeof(struct lquota_lvb)) {
+			if (loc == RCL_CLIENT)
+				lvb = req_capsule_client_swab_get(pill,
+						&RMF_DLM_LVB,
+						lustre_swab_lquota_lvb);
+			else
+				lvb = req_capsule_server_swab_get(pill,
+						&RMF_DLM_LVB,
+						lustre_swab_lquota_lvb);
+			if (unlikely(lvb == NULL)) {
+				LDLM_ERROR(lock, "no LVB");
+				RETURN(-EPROTO);
+			}
+
+			memcpy(data, lvb, size);
+		} else {
+			LDLM_ERROR(lock, "Replied unexpected lquota LVB size %d",
+				   size);
+			RETURN(-EINVAL);
+		}
+		break;
+	case LVB_T_LAYOUT:
+		if (size == 0)
+			break;
+
+		if (loc == RCL_CLIENT)
+			lvb = req_capsule_client_get(pill, &RMF_DLM_LVB);
+		else
+			lvb = req_capsule_server_get(pill, &RMF_DLM_LVB);
+		if (unlikely(lvb == NULL)) {
+			LDLM_ERROR(lock, "no LVB");
+			RETURN(-EPROTO);
+		}
+
+		memcpy(data, lvb, size);
+		break;
+	default:
+		LDLM_ERROR(lock, "Unknown LVB type: %d\n", lock->l_lvb_type);
+		libcfs_debug_dumpstack(NULL);
+		RETURN(-EINVAL);
+	}
+
+	RETURN(0);
+}
+
+/**
+ * Create and fill in new LDLM lock with specified properties.
+ * Returns a referenced lock
+ */
+struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns,
+				   const struct ldlm_res_id *res_id,
+				   ldlm_type_t type,
+				   ldlm_mode_t mode,
+				   const struct ldlm_callback_suite *cbs,
+				   void *data, __u32 lvb_len,
+				   enum lvb_type lvb_type)
+{
+	struct ldlm_lock *lock;
+	struct ldlm_resource *res;
+	ENTRY;
+
+	res = ldlm_resource_get(ns, NULL, res_id, type, 1);
+	if (res == NULL)
+		RETURN(NULL);
+
+	lock = ldlm_lock_new(res);
+
+	if (lock == NULL)
+		RETURN(NULL);
+
+	lock->l_req_mode = mode;
+	lock->l_ast_data = data;
+	lock->l_pid = current_pid();
+	lock->l_ns_srv = !!ns_is_server(ns);
+	if (cbs) {
+		lock->l_blocking_ast = cbs->lcs_blocking;
+		lock->l_completion_ast = cbs->lcs_completion;
+		lock->l_glimpse_ast = cbs->lcs_glimpse;
+		lock->l_weigh_ast = cbs->lcs_weigh;
+	}
+
+	lock->l_tree_node = NULL;
+	/* if this is the extent lock, allocate the interval tree node */
+	if (type == LDLM_EXTENT) {
+		if (ldlm_interval_alloc(lock) == NULL)
+			GOTO(out, 0);
+	}
+
+	if (lvb_len) {
+		lock->l_lvb_len = lvb_len;
+		OBD_ALLOC(lock->l_lvb_data, lvb_len);
+		if (lock->l_lvb_data == NULL)
+			GOTO(out, 0);
+	}
+
+	lock->l_lvb_type = lvb_type;
+	if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_NEW_LOCK))
+		GOTO(out, 0);
+
+	RETURN(lock);
+
+out:
+	ldlm_lock_destroy(lock);
+	LDLM_LOCK_RELEASE(lock);
+	return NULL;
+}
+
+/**
+ * Enqueue (request) a lock.
+ *
+ * Does not block. As a result of enqueue the lock would be put
+ * into granted or waiting list.
+ *
+ * If namespace has intent policy sent and the lock has LDLM_FL_HAS_INTENT flag
+ * set, skip all the enqueueing and delegate lock processing to intent policy
+ * function.
+ */
+ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns,
+			       struct ldlm_lock **lockp,
+			       void *cookie, __u64 *flags)
+{
+	struct ldlm_lock *lock = *lockp;
+	struct ldlm_resource *res = lock->l_resource;
+	int local = ns_is_client(ldlm_res_to_ns(res));
+	ldlm_error_t rc = ELDLM_OK;
+	struct ldlm_interval *node = NULL;
+	ENTRY;
+
+	lock->l_last_activity = cfs_time_current_sec();
+	/* policies are not executed on the client or during replay */
+	if ((*flags & (LDLM_FL_HAS_INTENT|LDLM_FL_REPLAY)) == LDLM_FL_HAS_INTENT
+	    && !local && ns->ns_policy) {
+		rc = ns->ns_policy(ns, lockp, cookie, lock->l_req_mode, *flags,
+				   NULL);
+		if (rc == ELDLM_LOCK_REPLACED) {
+			/* The lock that was returned has already been granted,
+			 * and placed into lockp.  If it's not the same as the
+			 * one we passed in, then destroy the old one and our
+			 * work here is done. */
+			if (lock != *lockp) {
+				ldlm_lock_destroy(lock);
+				LDLM_LOCK_RELEASE(lock);
+			}
+			*flags |= LDLM_FL_LOCK_CHANGED;
+			RETURN(0);
+		} else if (rc != ELDLM_OK ||
+			   (rc == ELDLM_OK && (*flags & LDLM_FL_INTENT_ONLY))) {
+			ldlm_lock_destroy(lock);
+			RETURN(rc);
+		}
+	}
+
+	/* For a replaying lock, it might be already in granted list. So
+	 * unlinking the lock will cause the interval node to be freed, we
+	 * have to allocate the interval node early otherwise we can't regrant
+	 * this lock in the future. - jay */
+	if (!local && (*flags & LDLM_FL_REPLAY) && res->lr_type == LDLM_EXTENT)
+		OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, __GFP_IO);
+
+	lock_res_and_lock(lock);
+	if (local && lock->l_req_mode == lock->l_granted_mode) {
+		/* The server returned a blocked lock, but it was granted
+		 * before we got a chance to actually enqueue it.  We don't
+		 * need to do anything else. */
+		*flags &= ~(LDLM_FL_BLOCK_GRANTED |
+			    LDLM_FL_BLOCK_CONV | LDLM_FL_BLOCK_WAIT);
+		GOTO(out, ELDLM_OK);
+	}
+
+	ldlm_resource_unlink_lock(lock);
+	if (res->lr_type == LDLM_EXTENT && lock->l_tree_node == NULL) {
+		if (node == NULL) {
+			ldlm_lock_destroy_nolock(lock);
+			GOTO(out, rc = -ENOMEM);
+		}
+
+		INIT_LIST_HEAD(&node->li_group);
+		ldlm_interval_attach(node, lock);
+		node = NULL;
+	}
+
+	/* Some flags from the enqueue want to make it into the AST, via the
+	 * lock's l_flags. */
+	lock->l_flags |= *flags & LDLM_AST_DISCARD_DATA;
+
+	/* This distinction between local lock trees is very important; a client
+	 * namespace only has information about locks taken by that client, and
+	 * thus doesn't have enough information to decide for itself if it can
+	 * be granted (below).  In this case, we do exactly what the server
+	 * tells us to do, as dictated by the 'flags'.
+	 *
+	 * We do exactly the same thing during recovery, when the server is
+	 * more or less trusting the clients not to lie.
+	 *
+	 * FIXME (bug 268): Detect obvious lies by checking compatibility in
+	 * granted/converting queues. */
+	if (local) {
+		if (*flags & LDLM_FL_BLOCK_CONV)
+			ldlm_resource_add_lock(res, &res->lr_converting, lock);
+		else if (*flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED))
+			ldlm_resource_add_lock(res, &res->lr_waiting, lock);
+		else
+			ldlm_grant_lock(lock, NULL);
+		GOTO(out, ELDLM_OK);
+	} else {
+		CERROR("This is client-side-only module, cannot handle "
+		       "LDLM_NAMESPACE_SERVER resource type lock.\n");
+		LBUG();
+	}
+
+out:
+	unlock_res_and_lock(lock);
+	if (node)
+		OBD_SLAB_FREE(node, ldlm_interval_slab, sizeof(*node));
+	return rc;
+}
+
+
+/**
+ * Process a call to blocking AST callback for a lock in ast_work list
+ */
+static int
+ldlm_work_bl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq)
+{
+	struct ldlm_cb_set_arg *arg = opaq;
+	struct ldlm_lock_desc   d;
+	int		     rc;
+	struct ldlm_lock       *lock;
+	ENTRY;
+
+	if (list_empty(arg->list))
+		RETURN(-ENOENT);
+
+	lock = list_entry(arg->list->next, struct ldlm_lock, l_bl_ast);
+
+	/* nobody should touch l_bl_ast */
+	lock_res_and_lock(lock);
+	list_del_init(&lock->l_bl_ast);
+
+	LASSERT(lock->l_flags & LDLM_FL_AST_SENT);
+	LASSERT(lock->l_bl_ast_run == 0);
+	LASSERT(lock->l_blocking_lock);
+	lock->l_bl_ast_run++;
+	unlock_res_and_lock(lock);
+
+	ldlm_lock2desc(lock->l_blocking_lock, &d);
+
+	rc = lock->l_blocking_ast(lock, &d, (void *)arg, LDLM_CB_BLOCKING);
+	LDLM_LOCK_RELEASE(lock->l_blocking_lock);
+	lock->l_blocking_lock = NULL;
+	LDLM_LOCK_RELEASE(lock);
+
+	RETURN(rc);
+}
+
+/**
+ * Process a call to completion AST callback for a lock in ast_work list
+ */
+static int
+ldlm_work_cp_ast_lock(struct ptlrpc_request_set *rqset, void *opaq)
+{
+	struct ldlm_cb_set_arg  *arg = opaq;
+	int		      rc = 0;
+	struct ldlm_lock	*lock;
+	ldlm_completion_callback completion_callback;
+	ENTRY;
+
+	if (list_empty(arg->list))
+		RETURN(-ENOENT);
+
+	lock = list_entry(arg->list->next, struct ldlm_lock, l_cp_ast);
+
+	/* It's possible to receive a completion AST before we've set
+	 * the l_completion_ast pointer: either because the AST arrived
+	 * before the reply, or simply because there's a small race
+	 * window between receiving the reply and finishing the local
+	 * enqueue. (bug 842)
+	 *
+	 * This can't happen with the blocking_ast, however, because we
+	 * will never call the local blocking_ast until we drop our
+	 * reader/writer reference, which we won't do until we get the
+	 * reply and finish enqueueing. */
+
+	/* nobody should touch l_cp_ast */
+	lock_res_and_lock(lock);
+	list_del_init(&lock->l_cp_ast);
+	LASSERT(lock->l_flags & LDLM_FL_CP_REQD);
+	/* save l_completion_ast since it can be changed by
+	 * mds_intent_policy(), see bug 14225 */
+	completion_callback = lock->l_completion_ast;
+	lock->l_flags &= ~LDLM_FL_CP_REQD;
+	unlock_res_and_lock(lock);
+
+	if (completion_callback != NULL)
+		rc = completion_callback(lock, 0, (void *)arg);
+	LDLM_LOCK_RELEASE(lock);
+
+	RETURN(rc);
+}
+
+/**
+ * Process a call to revocation AST callback for a lock in ast_work list
+ */
+static int
+ldlm_work_revoke_ast_lock(struct ptlrpc_request_set *rqset, void *opaq)
+{
+	struct ldlm_cb_set_arg *arg = opaq;
+	struct ldlm_lock_desc   desc;
+	int		     rc;
+	struct ldlm_lock       *lock;
+	ENTRY;
+
+	if (list_empty(arg->list))
+		RETURN(-ENOENT);
+
+	lock = list_entry(arg->list->next, struct ldlm_lock, l_rk_ast);
+	list_del_init(&lock->l_rk_ast);
+
+	/* the desc just pretend to exclusive */
+	ldlm_lock2desc(lock, &desc);
+	desc.l_req_mode = LCK_EX;
+	desc.l_granted_mode = 0;
+
+	rc = lock->l_blocking_ast(lock, &desc, (void*)arg, LDLM_CB_BLOCKING);
+	LDLM_LOCK_RELEASE(lock);
+
+	RETURN(rc);
+}
+
+/**
+ * Process a call to glimpse AST callback for a lock in ast_work list
+ */
+int ldlm_work_gl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq)
+{
+	struct ldlm_cb_set_arg		*arg = opaq;
+	struct ldlm_glimpse_work	*gl_work;
+	struct ldlm_lock		*lock;
+	int				 rc = 0;
+	ENTRY;
+
+	if (list_empty(arg->list))
+		RETURN(-ENOENT);
+
+	gl_work = list_entry(arg->list->next, struct ldlm_glimpse_work,
+				 gl_list);
+	list_del_init(&gl_work->gl_list);
+
+	lock = gl_work->gl_lock;
+
+	/* transfer the glimpse descriptor to ldlm_cb_set_arg */
+	arg->gl_desc = gl_work->gl_desc;
+
+	/* invoke the actual glimpse callback */
+	if (lock->l_glimpse_ast(lock, (void*)arg) == 0)
+		rc = 1;
+
+	LDLM_LOCK_RELEASE(lock);
+
+	if ((gl_work->gl_flags & LDLM_GL_WORK_NOFREE) == 0)
+		OBD_FREE_PTR(gl_work);
+
+	RETURN(rc);
+}
+
+/**
+ * Process list of locks in need of ASTs being sent.
+ *
+ * Used on server to send multiple ASTs together instead of sending one by
+ * one.
+ */
+int ldlm_run_ast_work(struct ldlm_namespace *ns, struct list_head *rpc_list,
+		      ldlm_desc_ast_t ast_type)
+{
+	struct ldlm_cb_set_arg *arg;
+	set_producer_func       work_ast_lock;
+	int		     rc;
+
+	if (list_empty(rpc_list))
+		RETURN(0);
+
+	OBD_ALLOC_PTR(arg);
+	if (arg == NULL)
+		RETURN(-ENOMEM);
+
+	atomic_set(&arg->restart, 0);
+	arg->list = rpc_list;
+
+	switch (ast_type) {
+		case LDLM_WORK_BL_AST:
+			arg->type = LDLM_BL_CALLBACK;
+			work_ast_lock = ldlm_work_bl_ast_lock;
+			break;
+		case LDLM_WORK_CP_AST:
+			arg->type = LDLM_CP_CALLBACK;
+			work_ast_lock = ldlm_work_cp_ast_lock;
+			break;
+		case LDLM_WORK_REVOKE_AST:
+			arg->type = LDLM_BL_CALLBACK;
+			work_ast_lock = ldlm_work_revoke_ast_lock;
+			break;
+		case LDLM_WORK_GL_AST:
+			arg->type = LDLM_GL_CALLBACK;
+			work_ast_lock = ldlm_work_gl_ast_lock;
+			break;
+		default:
+			LBUG();
+	}
+
+	/* We create a ptlrpc request set with flow control extension.
+	 * This request set will use the work_ast_lock function to produce new
+	 * requests and will send a new request each time one completes in order
+	 * to keep the number of requests in flight to ns_max_parallel_ast */
+	arg->set = ptlrpc_prep_fcset(ns->ns_max_parallel_ast ? : UINT_MAX,
+				     work_ast_lock, arg);
+	if (arg->set == NULL)
+		GOTO(out, rc = -ENOMEM);
+
+	ptlrpc_set_wait(arg->set);
+	ptlrpc_set_destroy(arg->set);
+
+	rc = atomic_read(&arg->restart) ? -ERESTART : 0;
+	GOTO(out, rc);
+out:
+	OBD_FREE_PTR(arg);
+	return rc;
+}
+
+static int reprocess_one_queue(struct ldlm_resource *res, void *closure)
+{
+	ldlm_reprocess_all(res);
+	return LDLM_ITER_CONTINUE;
+}
+
+static int ldlm_reprocess_res(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+			      struct hlist_node *hnode, void *arg)
+{
+	struct ldlm_resource *res = cfs_hash_object(hs, hnode);
+	int    rc;
+
+	rc = reprocess_one_queue(res, arg);
+
+	return rc == LDLM_ITER_STOP;
+}
+
+/**
+ * Iterate through all resources on a namespace attempting to grant waiting
+ * locks.
+ */
+void ldlm_reprocess_all_ns(struct ldlm_namespace *ns)
+{
+	ENTRY;
+
+	if (ns != NULL) {
+		cfs_hash_for_each_nolock(ns->ns_rs_hash,
+					 ldlm_reprocess_res, NULL);
+	}
+	EXIT;
+}
+EXPORT_SYMBOL(ldlm_reprocess_all_ns);
+
+/**
+ * Try to grant all waiting locks on a resource.
+ *
+ * Calls ldlm_reprocess_queue on converting and waiting queues.
+ *
+ * Typically called after some resource locks are cancelled to see
+ * if anything could be granted as a result of the cancellation.
+ */
+void ldlm_reprocess_all(struct ldlm_resource *res)
+{
+	LIST_HEAD(rpc_list);
+
+	ENTRY;
+	if (!ns_is_client(ldlm_res_to_ns(res))) {
+		CERROR("This is client-side-only module, cannot handle "
+		       "LDLM_NAMESPACE_SERVER resource type lock.\n");
+		LBUG();
+	}
+	EXIT;
+}
+
+/**
+ * Helper function to call blocking AST for LDLM lock \a lock in a
+ * "cancelling" mode.
+ */
+void ldlm_cancel_callback(struct ldlm_lock *lock)
+{
+	check_res_locked(lock->l_resource);
+	if (!(lock->l_flags & LDLM_FL_CANCEL)) {
+		lock->l_flags |= LDLM_FL_CANCEL;
+		if (lock->l_blocking_ast) {
+			unlock_res_and_lock(lock);
+			lock->l_blocking_ast(lock, NULL, lock->l_ast_data,
+					     LDLM_CB_CANCELING);
+			lock_res_and_lock(lock);
+		} else {
+			LDLM_DEBUG(lock, "no blocking ast");
+		}
+	}
+	lock->l_flags |= LDLM_FL_BL_DONE;
+}
+
+/**
+ * Remove skiplist-enabled LDLM lock \a req from granted list
+ */
+void ldlm_unlink_lock_skiplist(struct ldlm_lock *req)
+{
+	if (req->l_resource->lr_type != LDLM_PLAIN &&
+	    req->l_resource->lr_type != LDLM_IBITS)
+		return;
+
+	list_del_init(&req->l_sl_policy);
+	list_del_init(&req->l_sl_mode);
+}
+
+/**
+ * Attempts to cancel LDLM lock \a lock that has no reader/writer references.
+ */
+void ldlm_lock_cancel(struct ldlm_lock *lock)
+{
+	struct ldlm_resource *res;
+	struct ldlm_namespace *ns;
+	ENTRY;
+
+	lock_res_and_lock(lock);
+
+	res = lock->l_resource;
+	ns  = ldlm_res_to_ns(res);
+
+	/* Please do not, no matter how tempting, remove this LBUG without
+	 * talking to me first. -phik */
+	if (lock->l_readers || lock->l_writers) {
+		LDLM_ERROR(lock, "lock still has references");
+		LBUG();
+	}
+
+	if (lock->l_waited)
+		ldlm_del_waiting_lock(lock);
+
+	/* Releases cancel callback. */
+	ldlm_cancel_callback(lock);
+
+	/* Yes, second time, just in case it was added again while we were
+	   running with no res lock in ldlm_cancel_callback */
+	if (lock->l_waited)
+		ldlm_del_waiting_lock(lock);
+
+	ldlm_resource_unlink_lock(lock);
+	ldlm_lock_destroy_nolock(lock);
+
+	if (lock->l_granted_mode == lock->l_req_mode)
+		ldlm_pool_del(&ns->ns_pool, lock);
+
+	/* Make sure we will not be called again for same lock what is possible
+	 * if not to zero out lock->l_granted_mode */
+	lock->l_granted_mode = LCK_MINMODE;
+	unlock_res_and_lock(lock);
+
+	EXIT;
+}
+EXPORT_SYMBOL(ldlm_lock_cancel);
+
+/**
+ * Set opaque data into the lock that only makes sense to upper layer.
+ */
+int ldlm_lock_set_data(struct lustre_handle *lockh, void *data)
+{
+	struct ldlm_lock *lock = ldlm_handle2lock(lockh);
+	int rc = -EINVAL;
+	ENTRY;
+
+	if (lock) {
+		if (lock->l_ast_data == NULL)
+			lock->l_ast_data = data;
+		if (lock->l_ast_data == data)
+			rc = 0;
+		LDLM_LOCK_PUT(lock);
+	}
+	RETURN(rc);
+}
+EXPORT_SYMBOL(ldlm_lock_set_data);
+
+struct export_cl_data {
+	struct obd_export	*ecl_exp;
+	int			ecl_loop;
+};
+
+/**
+ * Iterator function for ldlm_cancel_locks_for_export.
+ * Cancels passed locks.
+ */
+int ldlm_cancel_locks_for_export_cb(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+				    struct hlist_node *hnode, void *data)
+
+{
+	struct export_cl_data	*ecl = (struct export_cl_data *)data;
+	struct obd_export	*exp  = ecl->ecl_exp;
+	struct ldlm_lock     *lock = cfs_hash_object(hs, hnode);
+	struct ldlm_resource *res;
+
+	res = ldlm_resource_getref(lock->l_resource);
+	LDLM_LOCK_GET(lock);
+
+	LDLM_DEBUG(lock, "export %p", exp);
+	ldlm_res_lvbo_update(res, NULL, 1);
+	ldlm_lock_cancel(lock);
+	ldlm_reprocess_all(res);
+	ldlm_resource_putref(res);
+	LDLM_LOCK_RELEASE(lock);
+
+	ecl->ecl_loop++;
+	if ((ecl->ecl_loop & -ecl->ecl_loop) == ecl->ecl_loop) {
+		CDEBUG(D_INFO,
+		       "Cancel lock %p for export %p (loop %d), still have "
+		       "%d locks left on hash table.\n",
+		       lock, exp, ecl->ecl_loop,
+		       atomic_read(&hs->hs_count));
+	}
+
+	return 0;
+}
+
+/**
+ * Cancel all locks for given export.
+ *
+ * Typically called on client disconnection/eviction
+ */
+void ldlm_cancel_locks_for_export(struct obd_export *exp)
+{
+	struct export_cl_data	ecl = {
+		.ecl_exp	= exp,
+		.ecl_loop	= 0,
+	};
+
+	cfs_hash_for_each_empty(exp->exp_lock_hash,
+				ldlm_cancel_locks_for_export_cb, &ecl);
+}
+
+/**
+ * Downgrade an exclusive lock.
+ *
+ * A fast variant of ldlm_lock_convert for convertion of exclusive
+ * locks. The convertion is always successful.
+ * Used by Commit on Sharing (COS) code.
+ *
+ * \param lock A lock to convert
+ * \param new_mode new lock mode
+ */
+void ldlm_lock_downgrade(struct ldlm_lock *lock, int new_mode)
+{
+	ENTRY;
+
+	LASSERT(lock->l_granted_mode & (LCK_PW | LCK_EX));
+	LASSERT(new_mode == LCK_COS);
+
+	lock_res_and_lock(lock);
+	ldlm_resource_unlink_lock(lock);
+	/*
+	 * Remove the lock from pool as it will be added again in
+	 * ldlm_grant_lock() called below.
+	 */
+	ldlm_pool_del(&ldlm_lock_to_ns(lock)->ns_pool, lock);
+
+	lock->l_req_mode = new_mode;
+	ldlm_grant_lock(lock, NULL);
+	unlock_res_and_lock(lock);
+	ldlm_reprocess_all(lock->l_resource);
+
+	EXIT;
+}
+EXPORT_SYMBOL(ldlm_lock_downgrade);
+
+/**
+ * Attempt to convert already granted lock to a different mode.
+ *
+ * While lock conversion is not currently used, future client-side
+ * optimizations could take advantage of it to avoid discarding cached
+ * pages on a file.
+ */
+struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock, int new_mode,
+					__u32 *flags)
+{
+	LIST_HEAD(rpc_list);
+	struct ldlm_resource *res;
+	struct ldlm_namespace *ns;
+	int granted = 0;
+	struct ldlm_interval *node;
+	ENTRY;
+
+	/* Just return if mode is unchanged. */
+	if (new_mode == lock->l_granted_mode) {
+		*flags |= LDLM_FL_BLOCK_GRANTED;
+		RETURN(lock->l_resource);
+	}
+
+	/* I can't check the type of lock here because the bitlock of lock
+	 * is not held here, so do the allocation blindly. -jay */
+	OBD_SLAB_ALLOC_PTR_GFP(node, ldlm_interval_slab, __GFP_IO);
+	if (node == NULL)  /* Actually, this causes EDEADLOCK to be returned */
+		RETURN(NULL);
+
+	LASSERTF((new_mode == LCK_PW && lock->l_granted_mode == LCK_PR),
+		 "new_mode %u, granted %u\n", new_mode, lock->l_granted_mode);
+
+	lock_res_and_lock(lock);
+
+	res = lock->l_resource;
+	ns  = ldlm_res_to_ns(res);
+
+	lock->l_req_mode = new_mode;
+	if (res->lr_type == LDLM_PLAIN || res->lr_type == LDLM_IBITS) {
+		ldlm_resource_unlink_lock(lock);
+	} else {
+		ldlm_resource_unlink_lock(lock);
+		if (res->lr_type == LDLM_EXTENT) {
+			/* FIXME: ugly code, I have to attach the lock to a
+			 * interval node again since perhaps it will be granted
+			 * soon */
+			INIT_LIST_HEAD(&node->li_group);
+			ldlm_interval_attach(node, lock);
+			node = NULL;
+		}
+	}
+
+	/*
+	 * Remove old lock from the pool before adding the lock with new
+	 * mode below in ->policy()
+	 */
+	ldlm_pool_del(&ns->ns_pool, lock);
+
+	/* If this is a local resource, put it on the appropriate list. */
+	if (ns_is_client(ldlm_res_to_ns(res))) {
+		if (*flags & (LDLM_FL_BLOCK_CONV | LDLM_FL_BLOCK_GRANTED)) {
+			ldlm_resource_add_lock(res, &res->lr_converting, lock);
+		} else {
+			/* This should never happen, because of the way the
+			 * server handles conversions. */
+			LDLM_ERROR(lock, "Erroneous flags %x on local lock\n",
+				   *flags);
+			LBUG();
+
+			ldlm_grant_lock(lock, &rpc_list);
+			granted = 1;
+			/* FIXME: completion handling not with lr_lock held ! */
+			if (lock->l_completion_ast)
+				lock->l_completion_ast(lock, 0, NULL);
+		}
+	} else {
+		CERROR("This is client-side-only module, cannot handle "
+		       "LDLM_NAMESPACE_SERVER resource type lock.\n");
+		LBUG();
+	}
+	unlock_res_and_lock(lock);
+
+	if (granted)
+		ldlm_run_ast_work(ns, &rpc_list, LDLM_WORK_CP_AST);
+	if (node)
+		OBD_SLAB_FREE(node, ldlm_interval_slab, sizeof(*node));
+	RETURN(res);
+}
+EXPORT_SYMBOL(ldlm_lock_convert);
+
+/**
+ * Print lock with lock handle \a lockh description into debug log.
+ *
+ * Used when printing all locks on a resource for debug purposes.
+ */
+void ldlm_lock_dump_handle(int level, struct lustre_handle *lockh)
+{
+	struct ldlm_lock *lock;
+
+	if (!((libcfs_debug | D_ERROR) & level))
+		return;
+
+	lock = ldlm_handle2lock(lockh);
+	if (lock == NULL)
+		return;
+
+	LDLM_DEBUG_LIMIT(level, lock, "###");
+
+	LDLM_LOCK_PUT(lock);
+}
+EXPORT_SYMBOL(ldlm_lock_dump_handle);
+
+/**
+ * Print lock information with custom message into debug log.
+ * Helper function.
+ */
+void _ldlm_lock_debug(struct ldlm_lock *lock,
+		      struct libcfs_debug_msg_data *msgdata,
+		      const char *fmt, ...)
+{
+	va_list args;
+	struct obd_export *exp = lock->l_export;
+	struct ldlm_resource *resource = lock->l_resource;
+	char *nid = "local";
+
+	va_start(args, fmt);
+
+	if (exp && exp->exp_connection) {
+		nid = libcfs_nid2str(exp->exp_connection->c_peer.nid);
+	} else if (exp && exp->exp_obd != NULL) {
+		struct obd_import *imp = exp->exp_obd->u.cli.cl_import;
+		nid = libcfs_nid2str(imp->imp_connection->c_peer.nid);
+	}
+
+	if (resource == NULL) {
+		libcfs_debug_vmsg2(msgdata, fmt, args,
+		       " ns: \?\? lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
+		       "res: \?\? rrc=\?\? type: \?\?\? flags: "LPX64" nid: %s "
+		       "remote: "LPX64" expref: %d pid: %u timeout: %lu "
+		       "lvb_type: %d\n",
+		       lock,
+		       lock->l_handle.h_cookie, atomic_read(&lock->l_refc),
+		       lock->l_readers, lock->l_writers,
+		       ldlm_lockname[lock->l_granted_mode],
+		       ldlm_lockname[lock->l_req_mode],
+		       lock->l_flags, nid, lock->l_remote_handle.cookie,
+		       exp ? atomic_read(&exp->exp_refcount) : -99,
+		       lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type);
+		va_end(args);
+		return;
+	}
+
+	switch (resource->lr_type) {
+	case LDLM_EXTENT:
+		libcfs_debug_vmsg2(msgdata, fmt, args,
+		       " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
+		       "res: "LPU64"/"LPU64" rrc: %d type: %s ["LPU64"->"LPU64
+		       "] (req "LPU64"->"LPU64") flags: "LPX64" nid: %s remote:"
+		       " "LPX64" expref: %d pid: %u timeout: %lu lvb_type: %d\n",
+		       ldlm_lock_to_ns_name(lock), lock,
+		       lock->l_handle.h_cookie, atomic_read(&lock->l_refc),
+		       lock->l_readers, lock->l_writers,
+		       ldlm_lockname[lock->l_granted_mode],
+		       ldlm_lockname[lock->l_req_mode],
+		       resource->lr_name.name[0],
+		       resource->lr_name.name[1],
+		       atomic_read(&resource->lr_refcount),
+		       ldlm_typename[resource->lr_type],
+		       lock->l_policy_data.l_extent.start,
+		       lock->l_policy_data.l_extent.end,
+		       lock->l_req_extent.start, lock->l_req_extent.end,
+		       lock->l_flags, nid, lock->l_remote_handle.cookie,
+		       exp ? atomic_read(&exp->exp_refcount) : -99,
+		       lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type);
+		break;
+
+	case LDLM_FLOCK:
+		libcfs_debug_vmsg2(msgdata, fmt, args,
+		       " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
+		       "res: "LPU64"/"LPU64" rrc: %d type: %s pid: %d "
+		       "["LPU64"->"LPU64"] flags: "LPX64" nid: %s remote: "LPX64
+		       " expref: %d pid: %u timeout: %lu\n",
+		       ldlm_lock_to_ns_name(lock), lock,
+		       lock->l_handle.h_cookie, atomic_read(&lock->l_refc),
+		       lock->l_readers, lock->l_writers,
+		       ldlm_lockname[lock->l_granted_mode],
+		       ldlm_lockname[lock->l_req_mode],
+		       resource->lr_name.name[0],
+		       resource->lr_name.name[1],
+		       atomic_read(&resource->lr_refcount),
+		       ldlm_typename[resource->lr_type],
+		       lock->l_policy_data.l_flock.pid,
+		       lock->l_policy_data.l_flock.start,
+		       lock->l_policy_data.l_flock.end,
+		       lock->l_flags, nid, lock->l_remote_handle.cookie,
+		       exp ? atomic_read(&exp->exp_refcount) : -99,
+		       lock->l_pid, lock->l_callback_timeout);
+		break;
+
+	case LDLM_IBITS:
+		libcfs_debug_vmsg2(msgdata, fmt, args,
+		       " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
+		       "res: "LPU64"/"LPU64" bits "LPX64" rrc: %d type: %s "
+		       "flags: "LPX64" nid: %s remote: "LPX64" expref: %d "
+		       "pid: %u timeout: %lu lvb_type: %d\n",
+		       ldlm_lock_to_ns_name(lock),
+		       lock, lock->l_handle.h_cookie,
+		       atomic_read (&lock->l_refc),
+		       lock->l_readers, lock->l_writers,
+		       ldlm_lockname[lock->l_granted_mode],
+		       ldlm_lockname[lock->l_req_mode],
+		       resource->lr_name.name[0],
+		       resource->lr_name.name[1],
+		       lock->l_policy_data.l_inodebits.bits,
+		       atomic_read(&resource->lr_refcount),
+		       ldlm_typename[resource->lr_type],
+		       lock->l_flags, nid, lock->l_remote_handle.cookie,
+		       exp ? atomic_read(&exp->exp_refcount) : -99,
+		       lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type);
+		break;
+
+	default:
+		libcfs_debug_vmsg2(msgdata, fmt, args,
+		       " ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
+		       "res: "LPU64"/"LPU64" rrc: %d type: %s flags: "LPX64" "
+		       "nid: %s remote: "LPX64" expref: %d pid: %u timeout: %lu"
+		       "lvb_type: %d\n",
+		       ldlm_lock_to_ns_name(lock),
+		       lock, lock->l_handle.h_cookie,
+		       atomic_read (&lock->l_refc),
+		       lock->l_readers, lock->l_writers,
+		       ldlm_lockname[lock->l_granted_mode],
+		       ldlm_lockname[lock->l_req_mode],
+		       resource->lr_name.name[0],
+		       resource->lr_name.name[1],
+		       atomic_read(&resource->lr_refcount),
+		       ldlm_typename[resource->lr_type],
+		       lock->l_flags, nid, lock->l_remote_handle.cookie,
+		       exp ? atomic_read(&exp->exp_refcount) : -99,
+		       lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type);
+		break;
+	}
+	va_end(args);
+}
+EXPORT_SYMBOL(_ldlm_lock_debug);
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1238 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2010, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/ldlm/ldlm_lockd.c
+ *
+ * Author: Peter Braam <braam@clusterfs.com>
+ * Author: Phil Schwan <phil@clusterfs.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+# include <linux/libcfs/libcfs.h>
+
+#include <lustre_dlm.h>
+#include <obd_class.h>
+#include <linux/list.h>
+#include "ldlm_internal.h"
+
+static int ldlm_num_threads;
+CFS_MODULE_PARM(ldlm_num_threads, "i", int, 0444,
+		"number of DLM service threads to start");
+
+static char *ldlm_cpts;
+CFS_MODULE_PARM(ldlm_cpts, "s", charp, 0444,
+		"CPU partitions ldlm threads should run on");
+
+extern struct kmem_cache *ldlm_resource_slab;
+extern struct kmem_cache *ldlm_lock_slab;
+static struct mutex	ldlm_ref_mutex;
+static int ldlm_refcount;
+
+struct ldlm_cb_async_args {
+	struct ldlm_cb_set_arg *ca_set_arg;
+	struct ldlm_lock       *ca_lock;
+};
+
+/* LDLM state */
+
+static struct ldlm_state *ldlm_state;
+
+inline cfs_time_t round_timeout(cfs_time_t timeout)
+{
+	return cfs_time_seconds((int)cfs_duration_sec(cfs_time_sub(timeout, 0)) + 1);
+}
+
+/* timeout for initial callback (AST) reply (bz10399) */
+static inline unsigned int ldlm_get_rq_timeout(void)
+{
+	/* Non-AT value */
+	unsigned int timeout = min(ldlm_timeout, obd_timeout / 3);
+
+	return timeout < 1 ? 1 : timeout;
+}
+
+#define ELT_STOPPED   0
+#define ELT_READY     1
+#define ELT_TERMINATE 2
+
+struct ldlm_bl_pool {
+	spinlock_t		blp_lock;
+
+	/*
+	 * blp_prio_list is used for callbacks that should be handled
+	 * as a priority. It is used for LDLM_FL_DISCARD_DATA requests.
+	 * see bug 13843
+	 */
+	struct list_head	      blp_prio_list;
+
+	/*
+	 * blp_list is used for all other callbacks which are likely
+	 * to take longer to process.
+	 */
+	struct list_head	      blp_list;
+
+	wait_queue_head_t	     blp_waitq;
+	struct completion	blp_comp;
+	atomic_t	    blp_num_threads;
+	atomic_t	    blp_busy_threads;
+	int		     blp_min_threads;
+	int		     blp_max_threads;
+};
+
+struct ldlm_bl_work_item {
+	struct list_head	      blwi_entry;
+	struct ldlm_namespace  *blwi_ns;
+	struct ldlm_lock_desc   blwi_ld;
+	struct ldlm_lock       *blwi_lock;
+	struct list_head	      blwi_head;
+	int		     blwi_count;
+	struct completion	blwi_comp;
+	ldlm_cancel_flags_t     blwi_flags;
+	int		     blwi_mem_pressure;
+};
+
+
+int ldlm_del_waiting_lock(struct ldlm_lock *lock)
+{
+	RETURN(0);
+}
+
+int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, int timeout)
+{
+	RETURN(0);
+}
+
+
+
+/**
+ * Callback handler for receiving incoming blocking ASTs.
+ *
+ * This can only happen on client side.
+ */
+void ldlm_handle_bl_callback(struct ldlm_namespace *ns,
+			     struct ldlm_lock_desc *ld, struct ldlm_lock *lock)
+{
+	int do_ast;
+	ENTRY;
+
+	LDLM_DEBUG(lock, "client blocking AST callback handler");
+
+	lock_res_and_lock(lock);
+	lock->l_flags |= LDLM_FL_CBPENDING;
+
+	if (lock->l_flags & LDLM_FL_CANCEL_ON_BLOCK)
+		lock->l_flags |= LDLM_FL_CANCEL;
+
+	do_ast = (!lock->l_readers && !lock->l_writers);
+	unlock_res_and_lock(lock);
+
+	if (do_ast) {
+		CDEBUG(D_DLMTRACE, "Lock %p already unused, calling callback (%p)\n",
+		       lock, lock->l_blocking_ast);
+		if (lock->l_blocking_ast != NULL)
+			lock->l_blocking_ast(lock, ld, lock->l_ast_data,
+					     LDLM_CB_BLOCKING);
+	} else {
+		CDEBUG(D_DLMTRACE, "Lock %p is referenced, will be cancelled later\n",
+		       lock);
+	}
+
+	LDLM_DEBUG(lock, "client blocking callback handler END");
+	LDLM_LOCK_RELEASE(lock);
+	EXIT;
+}
+
+/**
+ * Callback handler for receiving incoming completion ASTs.
+ *
+ * This only can happen on client side.
+ */
+static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
+				    struct ldlm_namespace *ns,
+				    struct ldlm_request *dlm_req,
+				    struct ldlm_lock *lock)
+{
+	int lvb_len;
+	LIST_HEAD(ast_list);
+	int rc = 0;
+	ENTRY;
+
+	LDLM_DEBUG(lock, "client completion callback handler START");
+
+	if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CANCEL_BL_CB_RACE)) {
+		int to = cfs_time_seconds(1);
+		while (to > 0) {
+			schedule_timeout_and_set_state(
+				TASK_INTERRUPTIBLE, to);
+			if (lock->l_granted_mode == lock->l_req_mode ||
+			    lock->l_destroyed)
+				break;
+		}
+	}
+
+	lvb_len = req_capsule_get_size(&req->rq_pill, &RMF_DLM_LVB, RCL_CLIENT);
+	if (lvb_len < 0) {
+		LDLM_ERROR(lock, "Fail to get lvb_len, rc = %d", lvb_len);
+		GOTO(out, rc = lvb_len);
+	} else if (lvb_len > 0) {
+		if (lock->l_lvb_len > 0) {
+			/* for extent lock, lvb contains ost_lvb{}. */
+			LASSERT(lock->l_lvb_data != NULL);
+
+			if (unlikely(lock->l_lvb_len < lvb_len)) {
+				LDLM_ERROR(lock, "Replied LVB is larger than "
+					   "expectation, expected = %d, "
+					   "replied = %d",
+					   lock->l_lvb_len, lvb_len);
+				GOTO(out, rc = -EINVAL);
+			}
+		} else if (ldlm_has_layout(lock)) { /* for layout lock, lvb has
+						     * variable length */
+			void *lvb_data;
+
+			OBD_ALLOC(lvb_data, lvb_len);
+			if (lvb_data == NULL) {
+				LDLM_ERROR(lock, "No memory: %d.\n", lvb_len);
+				GOTO(out, rc = -ENOMEM);
+			}
+
+			lock_res_and_lock(lock);
+			LASSERT(lock->l_lvb_data == NULL);
+			lock->l_lvb_data = lvb_data;
+			lock->l_lvb_len = lvb_len;
+			unlock_res_and_lock(lock);
+		}
+	}
+
+	lock_res_and_lock(lock);
+	if (lock->l_destroyed ||
+	    lock->l_granted_mode == lock->l_req_mode) {
+		/* bug 11300: the lock has already been granted */
+		unlock_res_and_lock(lock);
+		LDLM_DEBUG(lock, "Double grant race happened");
+		GOTO(out, rc = 0);
+	}
+
+	/* If we receive the completion AST before the actual enqueue returned,
+	 * then we might need to switch lock modes, resources, or extents. */
+	if (dlm_req->lock_desc.l_granted_mode != lock->l_req_mode) {
+		lock->l_req_mode = dlm_req->lock_desc.l_granted_mode;
+		LDLM_DEBUG(lock, "completion AST, new lock mode");
+	}
+
+	if (lock->l_resource->lr_type != LDLM_PLAIN) {
+		ldlm_convert_policy_to_local(req->rq_export,
+					  dlm_req->lock_desc.l_resource.lr_type,
+					  &dlm_req->lock_desc.l_policy_data,
+					  &lock->l_policy_data);
+		LDLM_DEBUG(lock, "completion AST, new policy data");
+	}
+
+	ldlm_resource_unlink_lock(lock);
+	if (memcmp(&dlm_req->lock_desc.l_resource.lr_name,
+		   &lock->l_resource->lr_name,
+		   sizeof(lock->l_resource->lr_name)) != 0) {
+		unlock_res_and_lock(lock);
+		rc = ldlm_lock_change_resource(ns, lock,
+				&dlm_req->lock_desc.l_resource.lr_name);
+		if (rc < 0) {
+			LDLM_ERROR(lock, "Failed to allocate resource");
+			GOTO(out, rc);
+		}
+		LDLM_DEBUG(lock, "completion AST, new resource");
+		CERROR("change resource!\n");
+		lock_res_and_lock(lock);
+	}
+
+	if (dlm_req->lock_flags & LDLM_FL_AST_SENT) {
+		/* BL_AST locks are not needed in LRU.
+		 * Let ldlm_cancel_lru() be fast. */
+		ldlm_lock_remove_from_lru(lock);
+		lock->l_flags |= LDLM_FL_CBPENDING | LDLM_FL_BL_AST;
+		LDLM_DEBUG(lock, "completion AST includes blocking AST");
+	}
+
+	if (lock->l_lvb_len > 0) {
+		rc = ldlm_fill_lvb(lock, &req->rq_pill, RCL_CLIENT,
+				   lock->l_lvb_data, lvb_len);
+		if (rc < 0) {
+			unlock_res_and_lock(lock);
+			GOTO(out, rc);
+		}
+	}
+
+	ldlm_grant_lock(lock, &ast_list);
+	unlock_res_and_lock(lock);
+
+	LDLM_DEBUG(lock, "callback handler finished, about to run_ast_work");
+
+	/* Let Enqueue to call osc_lock_upcall() and initialize
+	 * l_ast_data */
+	OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_CP_ENQ_RACE, 2);
+
+	ldlm_run_ast_work(ns, &ast_list, LDLM_WORK_CP_AST);
+
+	LDLM_DEBUG_NOLOCK("client completion callback handler END (lock %p)",
+			  lock);
+	GOTO(out, rc);
+
+out:
+	if (rc < 0) {
+		lock_res_and_lock(lock);
+		lock->l_flags |= LDLM_FL_FAILED;
+		unlock_res_and_lock(lock);
+		wake_up(&lock->l_waitq);
+	}
+	LDLM_LOCK_RELEASE(lock);
+}
+
+/**
+ * Callback handler for receiving incoming glimpse ASTs.
+ *
+ * This only can happen on client side.  After handling the glimpse AST
+ * we also consider dropping the lock here if it is unused locally for a
+ * long time.
+ */
+static void ldlm_handle_gl_callback(struct ptlrpc_request *req,
+				    struct ldlm_namespace *ns,
+				    struct ldlm_request *dlm_req,
+				    struct ldlm_lock *lock)
+{
+	int rc = -ENOSYS;
+	ENTRY;
+
+	LDLM_DEBUG(lock, "client glimpse AST callback handler");
+
+	if (lock->l_glimpse_ast != NULL)
+		rc = lock->l_glimpse_ast(lock, req);
+
+	if (req->rq_repmsg != NULL) {
+		ptlrpc_reply(req);
+	} else {
+		req->rq_status = rc;
+		ptlrpc_error(req);
+	}
+
+	lock_res_and_lock(lock);
+	if (lock->l_granted_mode == LCK_PW &&
+	    !lock->l_readers && !lock->l_writers &&
+	    cfs_time_after(cfs_time_current(),
+			   cfs_time_add(lock->l_last_used,
+					cfs_time_seconds(10)))) {
+		unlock_res_and_lock(lock);
+		if (ldlm_bl_to_thread_lock(ns, NULL, lock))
+			ldlm_handle_bl_callback(ns, NULL, lock);
+
+		EXIT;
+		return;
+	}
+	unlock_res_and_lock(lock);
+	LDLM_LOCK_RELEASE(lock);
+	EXIT;
+}
+
+static int ldlm_callback_reply(struct ptlrpc_request *req, int rc)
+{
+	if (req->rq_no_reply)
+		return 0;
+
+	req->rq_status = rc;
+	if (!req->rq_packed_final) {
+		rc = lustre_pack_reply(req, 1, NULL, NULL);
+		if (rc)
+			return rc;
+	}
+	return ptlrpc_reply(req);
+}
+
+static int __ldlm_bl_to_thread(struct ldlm_bl_work_item *blwi,
+			       ldlm_cancel_flags_t cancel_flags)
+{
+	struct ldlm_bl_pool *blp = ldlm_state->ldlm_bl_pool;
+	ENTRY;
+
+	spin_lock(&blp->blp_lock);
+	if (blwi->blwi_lock &&
+	    blwi->blwi_lock->l_flags & LDLM_FL_DISCARD_DATA) {
+		/* add LDLM_FL_DISCARD_DATA requests to the priority list */
+		list_add_tail(&blwi->blwi_entry, &blp->blp_prio_list);
+	} else {
+		/* other blocking callbacks are added to the regular list */
+		list_add_tail(&blwi->blwi_entry, &blp->blp_list);
+	}
+	spin_unlock(&blp->blp_lock);
+
+	wake_up(&blp->blp_waitq);
+
+	/* can not check blwi->blwi_flags as blwi could be already freed in
+	   LCF_ASYNC mode */
+	if (!(cancel_flags & LCF_ASYNC))
+		wait_for_completion(&blwi->blwi_comp);
+
+	RETURN(0);
+}
+
+static inline void init_blwi(struct ldlm_bl_work_item *blwi,
+			     struct ldlm_namespace *ns,
+			     struct ldlm_lock_desc *ld,
+			     struct list_head *cancels, int count,
+			     struct ldlm_lock *lock,
+			     ldlm_cancel_flags_t cancel_flags)
+{
+	init_completion(&blwi->blwi_comp);
+	INIT_LIST_HEAD(&blwi->blwi_head);
+
+	if (memory_pressure_get())
+		blwi->blwi_mem_pressure = 1;
+
+	blwi->blwi_ns = ns;
+	blwi->blwi_flags = cancel_flags;
+	if (ld != NULL)
+		blwi->blwi_ld = *ld;
+	if (count) {
+		list_add(&blwi->blwi_head, cancels);
+		list_del_init(cancels);
+		blwi->blwi_count = count;
+	} else {
+		blwi->blwi_lock = lock;
+	}
+}
+
+/**
+ * Queues a list of locks \a cancels containing \a count locks
+ * for later processing by a blocking thread.  If \a count is zero,
+ * then the lock referenced as \a lock is queued instead.
+ *
+ * The blocking thread would then call ->l_blocking_ast callback in the lock.
+ * If list addition fails an error is returned and caller is supposed to
+ * call ->l_blocking_ast itself.
+ */
+static int ldlm_bl_to_thread(struct ldlm_namespace *ns,
+			     struct ldlm_lock_desc *ld,
+			     struct ldlm_lock *lock,
+			     struct list_head *cancels, int count,
+			     ldlm_cancel_flags_t cancel_flags)
+{
+	ENTRY;
+
+	if (cancels && count == 0)
+		RETURN(0);
+
+	if (cancel_flags & LCF_ASYNC) {
+		struct ldlm_bl_work_item *blwi;
+
+		OBD_ALLOC(blwi, sizeof(*blwi));
+		if (blwi == NULL)
+			RETURN(-ENOMEM);
+		init_blwi(blwi, ns, ld, cancels, count, lock, cancel_flags);
+
+		RETURN(__ldlm_bl_to_thread(blwi, cancel_flags));
+	} else {
+		/* if it is synchronous call do minimum mem alloc, as it could
+		 * be triggered from kernel shrinker
+		 */
+		struct ldlm_bl_work_item blwi;
+
+		memset(&blwi, 0, sizeof(blwi));
+		init_blwi(&blwi, ns, ld, cancels, count, lock, cancel_flags);
+		RETURN(__ldlm_bl_to_thread(&blwi, cancel_flags));
+	}
+}
+
+
+int ldlm_bl_to_thread_lock(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld,
+			   struct ldlm_lock *lock)
+{
+	return ldlm_bl_to_thread(ns, ld, lock, NULL, 0, LCF_ASYNC);
+}
+
+int ldlm_bl_to_thread_list(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld,
+			   struct list_head *cancels, int count,
+			   ldlm_cancel_flags_t cancel_flags)
+{
+	return ldlm_bl_to_thread(ns, ld, NULL, cancels, count, cancel_flags);
+}
+
+/* Setinfo coming from Server (eg MDT) to Client (eg MDC)! */
+static int ldlm_handle_setinfo(struct ptlrpc_request *req)
+{
+	struct obd_device *obd = req->rq_export->exp_obd;
+	char *key;
+	void *val;
+	int keylen, vallen;
+	int rc = -ENOSYS;
+	ENTRY;
+
+	DEBUG_REQ(D_HSM, req, "%s: handle setinfo\n", obd->obd_name);
+
+	req_capsule_set(&req->rq_pill, &RQF_OBD_SET_INFO);
+
+	key = req_capsule_client_get(&req->rq_pill, &RMF_SETINFO_KEY);
+	if (key == NULL) {
+		DEBUG_REQ(D_IOCTL, req, "no set_info key");
+		RETURN(-EFAULT);
+	}
+	keylen = req_capsule_get_size(&req->rq_pill, &RMF_SETINFO_KEY,
+				      RCL_CLIENT);
+	val = req_capsule_client_get(&req->rq_pill, &RMF_SETINFO_VAL);
+	if (val == NULL) {
+		DEBUG_REQ(D_IOCTL, req, "no set_info val");
+		RETURN(-EFAULT);
+	}
+	vallen = req_capsule_get_size(&req->rq_pill, &RMF_SETINFO_VAL,
+				      RCL_CLIENT);
+
+	/* We are responsible for swabbing contents of val */
+
+	if (KEY_IS(KEY_HSM_COPYTOOL_SEND))
+		/* Pass it on to mdc (the "export" in this case) */
+		rc = obd_set_info_async(req->rq_svc_thread->t_env,
+					req->rq_export,
+					sizeof(KEY_HSM_COPYTOOL_SEND),
+					KEY_HSM_COPYTOOL_SEND,
+					vallen, val, NULL);
+	else
+		DEBUG_REQ(D_WARNING, req, "ignoring unknown key %s", key);
+
+	return rc;
+}
+
+static inline void ldlm_callback_errmsg(struct ptlrpc_request *req,
+					const char *msg, int rc,
+					struct lustre_handle *handle)
+{
+	DEBUG_REQ((req->rq_no_reply || rc) ? D_WARNING : D_DLMTRACE, req,
+		  "%s: [nid %s] [rc %d] [lock "LPX64"]",
+		  msg, libcfs_id2str(req->rq_peer), rc,
+		  handle ? handle->cookie : 0);
+	if (req->rq_no_reply)
+		CWARN("No reply was sent, maybe cause bug 21636.\n");
+	else if (rc)
+		CWARN("Send reply failed, maybe cause bug 21636.\n");
+}
+
+static int ldlm_handle_qc_callback(struct ptlrpc_request *req)
+{
+	struct obd_quotactl *oqctl;
+	struct client_obd *cli = &req->rq_export->exp_obd->u.cli;
+
+	oqctl = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL);
+	if (oqctl == NULL) {
+		CERROR("Can't unpack obd_quotactl\n");
+		RETURN(-EPROTO);
+	}
+
+	cli->cl_qchk_stat = oqctl->qc_stat;
+	return 0;
+}
+
+/* TODO: handle requests in a similar way as MDT: see mdt_handle_common() */
+static int ldlm_callback_handler(struct ptlrpc_request *req)
+{
+	struct ldlm_namespace *ns;
+	struct ldlm_request *dlm_req;
+	struct ldlm_lock *lock;
+	int rc;
+	ENTRY;
+
+	/* Requests arrive in sender's byte order.  The ptlrpc service
+	 * handler has already checked and, if necessary, byte-swapped the
+	 * incoming request message body, but I am responsible for the
+	 * message buffers. */
+
+	/* do nothing for sec context finalize */
+	if (lustre_msg_get_opc(req->rq_reqmsg) == SEC_CTX_FINI)
+		RETURN(0);
+
+	req_capsule_init(&req->rq_pill, req, RCL_SERVER);
+
+	if (req->rq_export == NULL) {
+		rc = ldlm_callback_reply(req, -ENOTCONN);
+		ldlm_callback_errmsg(req, "Operate on unconnected server",
+				     rc, NULL);
+		RETURN(0);
+	}
+
+	LASSERT(req->rq_export != NULL);
+	LASSERT(req->rq_export->exp_obd != NULL);
+
+	switch (lustre_msg_get_opc(req->rq_reqmsg)) {
+	case LDLM_BL_CALLBACK:
+		if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_BL_CALLBACK_NET))
+			RETURN(0);
+		break;
+	case LDLM_CP_CALLBACK:
+		if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CP_CALLBACK_NET))
+			RETURN(0);
+		break;
+	case LDLM_GL_CALLBACK:
+		if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_GL_CALLBACK_NET))
+			RETURN(0);
+		break;
+	case LDLM_SET_INFO:
+		rc = ldlm_handle_setinfo(req);
+		ldlm_callback_reply(req, rc);
+		RETURN(0);
+	case OBD_LOG_CANCEL: /* remove this eventually - for 1.4.0 compat */
+		CERROR("shouldn't be handling OBD_LOG_CANCEL on DLM thread\n");
+		req_capsule_set(&req->rq_pill, &RQF_LOG_CANCEL);
+		if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOG_CANCEL_NET))
+			RETURN(0);
+		rc = llog_origin_handle_cancel(req);
+		if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOG_CANCEL_REP))
+			RETURN(0);
+		ldlm_callback_reply(req, rc);
+		RETURN(0);
+	case LLOG_ORIGIN_HANDLE_CREATE:
+		req_capsule_set(&req->rq_pill, &RQF_LLOG_ORIGIN_HANDLE_CREATE);
+		if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET))
+			RETURN(0);
+		rc = llog_origin_handle_open(req);
+		ldlm_callback_reply(req, rc);
+		RETURN(0);
+	case LLOG_ORIGIN_HANDLE_NEXT_BLOCK:
+		req_capsule_set(&req->rq_pill,
+				&RQF_LLOG_ORIGIN_HANDLE_NEXT_BLOCK);
+		if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET))
+			RETURN(0);
+		rc = llog_origin_handle_next_block(req);
+		ldlm_callback_reply(req, rc);
+		RETURN(0);
+	case LLOG_ORIGIN_HANDLE_READ_HEADER:
+		req_capsule_set(&req->rq_pill,
+				&RQF_LLOG_ORIGIN_HANDLE_READ_HEADER);
+		if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET))
+			RETURN(0);
+		rc = llog_origin_handle_read_header(req);
+		ldlm_callback_reply(req, rc);
+		RETURN(0);
+	case LLOG_ORIGIN_HANDLE_CLOSE:
+		if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET))
+			RETURN(0);
+		rc = llog_origin_handle_close(req);
+		ldlm_callback_reply(req, rc);
+		RETURN(0);
+	case OBD_QC_CALLBACK:
+		req_capsule_set(&req->rq_pill, &RQF_QC_CALLBACK);
+		if (OBD_FAIL_CHECK(OBD_FAIL_OBD_QC_CALLBACK_NET))
+			RETURN(0);
+		rc = ldlm_handle_qc_callback(req);
+		ldlm_callback_reply(req, rc);
+		RETURN(0);
+	default:
+		CERROR("unknown opcode %u\n",
+		       lustre_msg_get_opc(req->rq_reqmsg));
+		ldlm_callback_reply(req, -EPROTO);
+		RETURN(0);
+	}
+
+	ns = req->rq_export->exp_obd->obd_namespace;
+	LASSERT(ns != NULL);
+
+	req_capsule_set(&req->rq_pill, &RQF_LDLM_CALLBACK);
+
+	dlm_req = req_capsule_client_get(&req->rq_pill, &RMF_DLM_REQ);
+	if (dlm_req == NULL) {
+		rc = ldlm_callback_reply(req, -EPROTO);
+		ldlm_callback_errmsg(req, "Operate without parameter", rc,
+				     NULL);
+		RETURN(0);
+	}
+
+	/* Force a known safe race, send a cancel to the server for a lock
+	 * which the server has already started a blocking callback on. */
+	if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CANCEL_BL_CB_RACE) &&
+	    lustre_msg_get_opc(req->rq_reqmsg) == LDLM_BL_CALLBACK) {
+		rc = ldlm_cli_cancel(&dlm_req->lock_handle[0], 0);
+		if (rc < 0)
+			CERROR("ldlm_cli_cancel: %d\n", rc);
+	}
+
+	lock = ldlm_handle2lock_long(&dlm_req->lock_handle[0], 0);
+	if (!lock) {
+		CDEBUG(D_DLMTRACE, "callback on lock "LPX64" - lock "
+		       "disappeared\n", dlm_req->lock_handle[0].cookie);
+		rc = ldlm_callback_reply(req, -EINVAL);
+		ldlm_callback_errmsg(req, "Operate with invalid parameter", rc,
+				     &dlm_req->lock_handle[0]);
+		RETURN(0);
+	}
+
+	if ((lock->l_flags & LDLM_FL_FAIL_LOC) &&
+	    lustre_msg_get_opc(req->rq_reqmsg) == LDLM_BL_CALLBACK)
+		OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE);
+
+	/* Copy hints/flags (e.g. LDLM_FL_DISCARD_DATA) from AST. */
+	lock_res_and_lock(lock);
+	lock->l_flags |= ldlm_flags_from_wire(dlm_req->lock_flags &
+					      LDLM_AST_FLAGS);
+	if (lustre_msg_get_opc(req->rq_reqmsg) == LDLM_BL_CALLBACK) {
+		/* If somebody cancels lock and cache is already dropped,
+		 * or lock is failed before cp_ast received on client,
+		 * we can tell the server we have no lock. Otherwise, we
+		 * should send cancel after dropping the cache. */
+		if (((lock->l_flags & LDLM_FL_CANCELING) &&
+		    (lock->l_flags & LDLM_FL_BL_DONE)) ||
+		    (lock->l_flags & LDLM_FL_FAILED)) {
+			LDLM_DEBUG(lock, "callback on lock "
+				   LPX64" - lock disappeared\n",
+				   dlm_req->lock_handle[0].cookie);
+			unlock_res_and_lock(lock);
+			LDLM_LOCK_RELEASE(lock);
+			rc = ldlm_callback_reply(req, -EINVAL);
+			ldlm_callback_errmsg(req, "Operate on stale lock", rc,
+					     &dlm_req->lock_handle[0]);
+			RETURN(0);
+		}
+		/* BL_AST locks are not needed in LRU.
+		 * Let ldlm_cancel_lru() be fast. */
+		ldlm_lock_remove_from_lru(lock);
+		lock->l_flags |= LDLM_FL_BL_AST;
+	}
+	unlock_res_and_lock(lock);
+
+	/* We want the ost thread to get this reply so that it can respond
+	 * to ost requests (write cache writeback) that might be triggered
+	 * in the callback.
+	 *
+	 * But we'd also like to be able to indicate in the reply that we're
+	 * cancelling right now, because it's unused, or have an intent result
+	 * in the reply, so we might have to push the responsibility for sending
+	 * the reply down into the AST handlers, alas. */
+
+	switch (lustre_msg_get_opc(req->rq_reqmsg)) {
+	case LDLM_BL_CALLBACK:
+		CDEBUG(D_INODE, "blocking ast\n");
+		req_capsule_extend(&req->rq_pill, &RQF_LDLM_BL_CALLBACK);
+		if (!(lock->l_flags & LDLM_FL_CANCEL_ON_BLOCK)) {
+			rc = ldlm_callback_reply(req, 0);
+			if (req->rq_no_reply || rc)
+				ldlm_callback_errmsg(req, "Normal process", rc,
+						     &dlm_req->lock_handle[0]);
+		}
+		if (ldlm_bl_to_thread_lock(ns, &dlm_req->lock_desc, lock))
+			ldlm_handle_bl_callback(ns, &dlm_req->lock_desc, lock);
+		break;
+	case LDLM_CP_CALLBACK:
+		CDEBUG(D_INODE, "completion ast\n");
+		req_capsule_extend(&req->rq_pill, &RQF_LDLM_CP_CALLBACK);
+		ldlm_callback_reply(req, 0);
+		ldlm_handle_cp_callback(req, ns, dlm_req, lock);
+		break;
+	case LDLM_GL_CALLBACK:
+		CDEBUG(D_INODE, "glimpse ast\n");
+		req_capsule_extend(&req->rq_pill, &RQF_LDLM_GL_CALLBACK);
+		ldlm_handle_gl_callback(req, ns, dlm_req, lock);
+		break;
+	default:
+		LBUG();			 /* checked above */
+	}
+
+	RETURN(0);
+}
+
+
+static struct ldlm_bl_work_item *ldlm_bl_get_work(struct ldlm_bl_pool *blp)
+{
+	struct ldlm_bl_work_item *blwi = NULL;
+	static unsigned int num_bl = 0;
+
+	spin_lock(&blp->blp_lock);
+	/* process a request from the blp_list at least every blp_num_threads */
+	if (!list_empty(&blp->blp_list) &&
+	    (list_empty(&blp->blp_prio_list) || num_bl == 0))
+		blwi = list_entry(blp->blp_list.next,
+				      struct ldlm_bl_work_item, blwi_entry);
+	else
+		if (!list_empty(&blp->blp_prio_list))
+			blwi = list_entry(blp->blp_prio_list.next,
+					      struct ldlm_bl_work_item,
+					      blwi_entry);
+
+	if (blwi) {
+		if (++num_bl >= atomic_read(&blp->blp_num_threads))
+			num_bl = 0;
+		list_del(&blwi->blwi_entry);
+	}
+	spin_unlock(&blp->blp_lock);
+
+	return blwi;
+}
+
+/* This only contains temporary data until the thread starts */
+struct ldlm_bl_thread_data {
+	char			bltd_name[CFS_CURPROC_COMM_MAX];
+	struct ldlm_bl_pool	*bltd_blp;
+	struct completion	bltd_comp;
+	int			bltd_num;
+};
+
+static int ldlm_bl_thread_main(void *arg);
+
+static int ldlm_bl_thread_start(struct ldlm_bl_pool *blp)
+{
+	struct ldlm_bl_thread_data bltd = { .bltd_blp = blp };
+	task_t *task;
+
+	init_completion(&bltd.bltd_comp);
+	bltd.bltd_num = atomic_read(&blp->blp_num_threads);
+	snprintf(bltd.bltd_name, sizeof(bltd.bltd_name) - 1,
+		"ldlm_bl_%02d", bltd.bltd_num);
+	task = kthread_run(ldlm_bl_thread_main, &bltd, bltd.bltd_name);
+	if (IS_ERR(task)) {
+		CERROR("cannot start LDLM thread ldlm_bl_%02d: rc %ld\n",
+		       atomic_read(&blp->blp_num_threads), PTR_ERR(task));
+		return PTR_ERR(task);
+	}
+	wait_for_completion(&bltd.bltd_comp);
+
+	return 0;
+}
+
+/**
+ * Main blocking requests processing thread.
+ *
+ * Callers put locks into its queue by calling ldlm_bl_to_thread.
+ * This thread in the end ends up doing actual call to ->l_blocking_ast
+ * for queued locks.
+ */
+static int ldlm_bl_thread_main(void *arg)
+{
+	struct ldlm_bl_pool *blp;
+	ENTRY;
+
+	{
+		struct ldlm_bl_thread_data *bltd = arg;
+
+		blp = bltd->bltd_blp;
+
+		atomic_inc(&blp->blp_num_threads);
+		atomic_inc(&blp->blp_busy_threads);
+
+		complete(&bltd->bltd_comp);
+		/* cannot use bltd after this, it is only on caller's stack */
+	}
+
+	while (1) {
+		struct l_wait_info lwi = { 0 };
+		struct ldlm_bl_work_item *blwi = NULL;
+		int busy;
+
+		blwi = ldlm_bl_get_work(blp);
+
+		if (blwi == NULL) {
+			atomic_dec(&blp->blp_busy_threads);
+			l_wait_event_exclusive(blp->blp_waitq,
+					 (blwi = ldlm_bl_get_work(blp)) != NULL,
+					 &lwi);
+			busy = atomic_inc_return(&blp->blp_busy_threads);
+		} else {
+			busy = atomic_read(&blp->blp_busy_threads);
+		}
+
+		if (blwi->blwi_ns == NULL)
+			/* added by ldlm_cleanup() */
+			break;
+
+		/* Not fatal if racy and have a few too many threads */
+		if (unlikely(busy < blp->blp_max_threads &&
+			     busy >= atomic_read(&blp->blp_num_threads) &&
+			     !blwi->blwi_mem_pressure))
+			/* discard the return value, we tried */
+			ldlm_bl_thread_start(blp);
+
+		if (blwi->blwi_mem_pressure)
+			memory_pressure_set();
+
+		if (blwi->blwi_count) {
+			int count;
+			/* The special case when we cancel locks in LRU
+			 * asynchronously, we pass the list of locks here.
+			 * Thus locks are marked LDLM_FL_CANCELING, but NOT
+			 * canceled locally yet. */
+			count = ldlm_cli_cancel_list_local(&blwi->blwi_head,
+							   blwi->blwi_count,
+							   LCF_BL_AST);
+			ldlm_cli_cancel_list(&blwi->blwi_head, count, NULL,
+					     blwi->blwi_flags);
+		} else {
+			ldlm_handle_bl_callback(blwi->blwi_ns, &blwi->blwi_ld,
+						blwi->blwi_lock);
+		}
+		if (blwi->blwi_mem_pressure)
+			memory_pressure_clr();
+
+		if (blwi->blwi_flags & LCF_ASYNC)
+			OBD_FREE(blwi, sizeof(*blwi));
+		else
+			complete(&blwi->blwi_comp);
+	}
+
+	atomic_dec(&blp->blp_busy_threads);
+	atomic_dec(&blp->blp_num_threads);
+	complete(&blp->blp_comp);
+	RETURN(0);
+}
+
+
+static int ldlm_setup(void);
+static int ldlm_cleanup(void);
+
+int ldlm_get_ref(void)
+{
+	int rc = 0;
+	ENTRY;
+	mutex_lock(&ldlm_ref_mutex);
+	if (++ldlm_refcount == 1) {
+		rc = ldlm_setup();
+		if (rc)
+			ldlm_refcount--;
+	}
+	mutex_unlock(&ldlm_ref_mutex);
+
+	RETURN(rc);
+}
+EXPORT_SYMBOL(ldlm_get_ref);
+
+void ldlm_put_ref(void)
+{
+	ENTRY;
+	mutex_lock(&ldlm_ref_mutex);
+	if (ldlm_refcount == 1) {
+		int rc = ldlm_cleanup();
+		if (rc)
+			CERROR("ldlm_cleanup failed: %d\n", rc);
+		else
+			ldlm_refcount--;
+	} else {
+		ldlm_refcount--;
+	}
+	mutex_unlock(&ldlm_ref_mutex);
+
+	EXIT;
+}
+EXPORT_SYMBOL(ldlm_put_ref);
+
+/*
+ * Export handle<->lock hash operations.
+ */
+static unsigned
+ldlm_export_lock_hash(cfs_hash_t *hs, const void *key, unsigned mask)
+{
+	return cfs_hash_u64_hash(((struct lustre_handle *)key)->cookie, mask);
+}
+
+static void *
+ldlm_export_lock_key(struct hlist_node *hnode)
+{
+	struct ldlm_lock *lock;
+
+	lock = hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
+	return &lock->l_remote_handle;
+}
+
+static void
+ldlm_export_lock_keycpy(struct hlist_node *hnode, void *key)
+{
+	struct ldlm_lock     *lock;
+
+	lock = hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
+	lock->l_remote_handle = *(struct lustre_handle *)key;
+}
+
+static int
+ldlm_export_lock_keycmp(const void *key, struct hlist_node *hnode)
+{
+	return lustre_handle_equal(ldlm_export_lock_key(hnode), key);
+}
+
+static void *
+ldlm_export_lock_object(struct hlist_node *hnode)
+{
+	return hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
+}
+
+static void
+ldlm_export_lock_get(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	struct ldlm_lock *lock;
+
+	lock = hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
+	LDLM_LOCK_GET(lock);
+}
+
+static void
+ldlm_export_lock_put(cfs_hash_t *hs, struct hlist_node *hnode)
+{
+	struct ldlm_lock *lock;
+
+	lock = hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
+	LDLM_LOCK_RELEASE(lock);
+}
+
+static cfs_hash_ops_t ldlm_export_lock_ops = {
+	.hs_hash	= ldlm_export_lock_hash,
+	.hs_key	 = ldlm_export_lock_key,
+	.hs_keycmp      = ldlm_export_lock_keycmp,
+	.hs_keycpy      = ldlm_export_lock_keycpy,
+	.hs_object      = ldlm_export_lock_object,
+	.hs_get	 = ldlm_export_lock_get,
+	.hs_put	 = ldlm_export_lock_put,
+	.hs_put_locked  = ldlm_export_lock_put,
+};
+
+int ldlm_init_export(struct obd_export *exp)
+{
+	ENTRY;
+
+	exp->exp_lock_hash =
+		cfs_hash_create(obd_uuid2str(&exp->exp_client_uuid),
+				HASH_EXP_LOCK_CUR_BITS,
+				HASH_EXP_LOCK_MAX_BITS,
+				HASH_EXP_LOCK_BKT_BITS, 0,
+				CFS_HASH_MIN_THETA, CFS_HASH_MAX_THETA,
+				&ldlm_export_lock_ops,
+				CFS_HASH_DEFAULT | CFS_HASH_REHASH_KEY |
+				CFS_HASH_NBLK_CHANGE);
+
+	if (!exp->exp_lock_hash)
+		RETURN(-ENOMEM);
+
+	RETURN(0);
+}
+EXPORT_SYMBOL(ldlm_init_export);
+
+void ldlm_destroy_export(struct obd_export *exp)
+{
+	ENTRY;
+	cfs_hash_putref(exp->exp_lock_hash);
+	exp->exp_lock_hash = NULL;
+
+	ldlm_destroy_flock_export(exp);
+	EXIT;
+}
+EXPORT_SYMBOL(ldlm_destroy_export);
+
+static int ldlm_setup(void)
+{
+	static struct ptlrpc_service_conf	conf;
+	struct ldlm_bl_pool			*blp = NULL;
+	int rc = 0;
+	int i;
+	ENTRY;
+
+	if (ldlm_state != NULL)
+		RETURN(-EALREADY);
+
+	OBD_ALLOC(ldlm_state, sizeof(*ldlm_state));
+	if (ldlm_state == NULL)
+		RETURN(-ENOMEM);
+
+#ifdef LPROCFS
+	rc = ldlm_proc_setup();
+	if (rc != 0)
+		GOTO(out, rc);
+#endif
+
+	memset(&conf, 0, sizeof(conf));
+	conf = (typeof(conf)) {
+		.psc_name		= "ldlm_cbd",
+		.psc_watchdog_factor	= 2,
+		.psc_buf		= {
+			.bc_nbufs		= LDLM_CLIENT_NBUFS,
+			.bc_buf_size		= LDLM_BUFSIZE,
+			.bc_req_max_size	= LDLM_MAXREQSIZE,
+			.bc_rep_max_size	= LDLM_MAXREPSIZE,
+			.bc_req_portal		= LDLM_CB_REQUEST_PORTAL,
+			.bc_rep_portal		= LDLM_CB_REPLY_PORTAL,
+		},
+		.psc_thr		= {
+			.tc_thr_name		= "ldlm_cb",
+			.tc_thr_factor		= LDLM_THR_FACTOR,
+			.tc_nthrs_init		= LDLM_NTHRS_INIT,
+			.tc_nthrs_base		= LDLM_NTHRS_BASE,
+			.tc_nthrs_max		= LDLM_NTHRS_MAX,
+			.tc_nthrs_user		= ldlm_num_threads,
+			.tc_cpu_affinity	= 1,
+			.tc_ctx_tags		= LCT_MD_THREAD | LCT_DT_THREAD,
+		},
+		.psc_cpt		= {
+			.cc_pattern		= ldlm_cpts,
+		},
+		.psc_ops		= {
+			.so_req_handler		= ldlm_callback_handler,
+		},
+	};
+	ldlm_state->ldlm_cb_service = \
+			ptlrpc_register_service(&conf, ldlm_svc_proc_dir);
+	if (IS_ERR(ldlm_state->ldlm_cb_service)) {
+		CERROR("failed to start service\n");
+		rc = PTR_ERR(ldlm_state->ldlm_cb_service);
+		ldlm_state->ldlm_cb_service = NULL;
+		GOTO(out, rc);
+	}
+
+
+	OBD_ALLOC(blp, sizeof(*blp));
+	if (blp == NULL)
+		GOTO(out, rc = -ENOMEM);
+	ldlm_state->ldlm_bl_pool = blp;
+
+	spin_lock_init(&blp->blp_lock);
+	INIT_LIST_HEAD(&blp->blp_list);
+	INIT_LIST_HEAD(&blp->blp_prio_list);
+	init_waitqueue_head(&blp->blp_waitq);
+	atomic_set(&blp->blp_num_threads, 0);
+	atomic_set(&blp->blp_busy_threads, 0);
+
+	if (ldlm_num_threads == 0) {
+		blp->blp_min_threads = LDLM_NTHRS_INIT;
+		blp->blp_max_threads = LDLM_NTHRS_MAX;
+	} else {
+		blp->blp_min_threads = blp->blp_max_threads = \
+			min_t(int, LDLM_NTHRS_MAX, max_t(int, LDLM_NTHRS_INIT,
+							 ldlm_num_threads));
+	}
+
+	for (i = 0; i < blp->blp_min_threads; i++) {
+		rc = ldlm_bl_thread_start(blp);
+		if (rc < 0)
+			GOTO(out, rc);
+	}
+
+
+	rc = ldlm_pools_init();
+	if (rc) {
+		CERROR("Failed to initialize LDLM pools: %d\n", rc);
+		GOTO(out, rc);
+	}
+	RETURN(0);
+
+ out:
+	ldlm_cleanup();
+	RETURN(rc);
+}
+
+static int ldlm_cleanup(void)
+{
+	ENTRY;
+
+	if (!list_empty(ldlm_namespace_list(LDLM_NAMESPACE_SERVER)) ||
+	    !list_empty(ldlm_namespace_list(LDLM_NAMESPACE_CLIENT))) {
+		CERROR("ldlm still has namespaces; clean these up first.\n");
+		ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE);
+		ldlm_dump_all_namespaces(LDLM_NAMESPACE_CLIENT, D_DLMTRACE);
+		RETURN(-EBUSY);
+	}
+
+	ldlm_pools_fini();
+
+	if (ldlm_state->ldlm_bl_pool != NULL) {
+		struct ldlm_bl_pool *blp = ldlm_state->ldlm_bl_pool;
+
+		while (atomic_read(&blp->blp_num_threads) > 0) {
+			struct ldlm_bl_work_item blwi = { .blwi_ns = NULL };
+
+			init_completion(&blp->blp_comp);
+
+			spin_lock(&blp->blp_lock);
+			list_add_tail(&blwi.blwi_entry, &blp->blp_list);
+			wake_up(&blp->blp_waitq);
+			spin_unlock(&blp->blp_lock);
+
+			wait_for_completion(&blp->blp_comp);
+		}
+
+		OBD_FREE(blp, sizeof(*blp));
+	}
+
+	if (ldlm_state->ldlm_cb_service != NULL)
+		ptlrpc_unregister_service(ldlm_state->ldlm_cb_service);
+
+	ldlm_proc_cleanup();
+
+
+	OBD_FREE(ldlm_state, sizeof(*ldlm_state));
+	ldlm_state = NULL;
+
+	RETURN(0);
+}
+
+int ldlm_init(void)
+{
+	mutex_init(&ldlm_ref_mutex);
+	mutex_init(ldlm_namespace_lock(LDLM_NAMESPACE_SERVER));
+	mutex_init(ldlm_namespace_lock(LDLM_NAMESPACE_CLIENT));
+	ldlm_resource_slab = kmem_cache_create("ldlm_resources",
+					       sizeof(struct ldlm_resource), 0,
+					       SLAB_HWCACHE_ALIGN, NULL);
+	if (ldlm_resource_slab == NULL)
+		return -ENOMEM;
+
+	ldlm_lock_slab = kmem_cache_create("ldlm_locks",
+			      sizeof(struct ldlm_lock), 0,
+			      SLAB_HWCACHE_ALIGN | SLAB_DESTROY_BY_RCU, NULL);
+	if (ldlm_lock_slab == NULL) {
+		kmem_cache_destroy(ldlm_resource_slab);
+		return -ENOMEM;
+	}
+
+	ldlm_interval_slab = kmem_cache_create("interval_node",
+					sizeof(struct ldlm_interval),
+					0, SLAB_HWCACHE_ALIGN, NULL);
+	if (ldlm_interval_slab == NULL) {
+		kmem_cache_destroy(ldlm_resource_slab);
+		kmem_cache_destroy(ldlm_lock_slab);
+		return -ENOMEM;
+	}
+#if LUSTRE_TRACKS_LOCK_EXP_REFS
+	class_export_dump_hook = ldlm_dump_export_locks;
+#endif
+	return 0;
+}
+
+void ldlm_exit(void)
+{
+	if (ldlm_refcount)
+		CERROR("ldlm_refcount is %d in ldlm_exit!\n", ldlm_refcount);
+	kmem_cache_destroy(ldlm_resource_slab);
+	/* ldlm_lock_put() use RCU to call ldlm_lock_free, so need call
+	 * synchronize_rcu() to wait a grace period elapsed, so that
+	 * ldlm_lock_free() get a chance to be called. */
+	synchronize_rcu();
+	kmem_cache_destroy(ldlm_lock_slab);
+	kmem_cache_destroy(ldlm_interval_slab);
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_plain.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,72 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/ldlm/ldlm_plain.c
+ *
+ * Author: Peter Braam <braam@clusterfs.com>
+ * Author: Phil Schwan <phil@clusterfs.com>
+ */
+
+/**
+ * This file contains implementation of PLAIN lock type.
+ *
+ * PLAIN locks are the simplest form of LDLM locking, and are used when
+ * there only needs to be a single lock on a resource. This avoids some
+ * of the complexity of EXTENT and IBITS lock types, but doesn't allow
+ * different "parts" of a resource to be locked concurrently.  Example
+ * use cases for PLAIN locks include locking of MGS configuration logs
+ * and (as of Lustre 2.4) quota records.
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+#include <lustre_dlm.h>
+#include <obd_support.h>
+#include <lustre_lib.h>
+
+#include "ldlm_internal.h"
+
+
+void ldlm_plain_policy_wire_to_local(const ldlm_wire_policy_data_t *wpolicy,
+				     ldlm_policy_data_t *lpolicy)
+{
+	/* No policy for plain locks */
+}
+
+void ldlm_plain_policy_local_to_wire(const ldlm_policy_data_t *lpolicy,
+				     ldlm_wire_policy_data_t *wpolicy)
+{
+	/* No policy for plain locks */
+}
diff -druNp --no-dereference linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
--- linux-libre-3.10-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-3.11-rc7-gnu/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c	2013-08-25 20:43:22.000000000 -0400
@@ -0,0 +1,1384 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2010, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/ldlm/ldlm_pool.c
+ *
+ * Author: Yury Umanets <umka@clusterfs.com>
+ */
+
+/*
+ * Idea of this code is rather simple. Each second, for each server namespace
+ * we have SLV - server lock volume which is calculated on current number of
+ * granted locks, grant speed for past period, etc - that is, locking load.
+ * This SLV number may be thought as a flow definition for simplicity. It is
+ * sent to clients with each occasion to let them know what is current load
+ * situation on the server. By default, at the beginning, SLV on server is
+ * set max value which is calculated as the following: allow to one client
+ * have all locks of limit ->pl_limit for 10h.
+ *
+ * Next, on clients, number of cached locks is not limited artificially in any
+ * way as it was before. Instead, client calculates CLV, that is, client lock
+ * volume for each lock and compares it with last SLV from the server. CLV is
+ * calculated as the number of locks in LRU * lock live time in seconds. If
+ * CLV > SLV - lock is canceled.
+ *
+ * Client has LVF, that is, lock volume factor which regulates how much sensitive
+ * client should be about last SLV from server. The higher LVF is the more locks
+ * will be canceled on client. Default value for it is 1. Setting LVF to 2 means
+ * that client will cancel locks 2 times faster.
+ *
+ * Locks on a client will be canceled more intensively in these cases:
+ * (1) if SLV is smaller, that is, load is higher on the server;
+ * (2) client has a lot of locks (the more locks are held by client, the bigger
+ *     chances that some of them should be canceled);
+ * (3) client has old locks (taken some time ago);
+ *
+ * Thus, according to flow paradigm that we use for better understanding SLV,
+ * CLV is the volume of particle in flow described by SLV. According to this,
+ * if flow is getting thinner, more and more particles become outside of it and
+ * as particles are locks, they should be canceled.
+ *
+ * General idea of this belongs to Vitaly Fertman (vitaly@clusterfs.com). Andreas
+ * Dilger (adilger@clusterfs.com) proposed few nice ideas like using LVF and many
+ * cleanups. Flow definition to allow more easy understanding of the logic belongs
+ * to Nikita Danilov (nikita@clusterfs.com) as well as many cleanups and fixes.
+ * And design and implementation are done by Yury Umanets (umka@clusterfs.com).
+ *
+ * Glossary for terms used:
+ *
+ * pl_limit - Number of allowed locks in pool. Applies to server and client
+ * side (tunable);
+ *
+ * pl_granted - Number of granted locks (calculated);
+ * pl_grant_rate - Number of granted locks for last T (calculated);
+ * pl_cancel_rate - Number of canceled locks for last T (calculated);
+ * pl_grant_speed - Grant speed (GR - CR) for last T (calculated);
+ * pl_grant_plan - Planned number of granted locks for next T (calculated);
+ * pl_server_lock_volume - Current server lock volume (calculated);
+ *
+ * As it may be seen from list above, we have few possible tunables which may
+ * affect behavior much. They all may be modified via proc. However, they also
+ * give a possibility for constructing few pre-defined behavior policies. If
+ * none of predefines is suitable for a working pattern being used, new one may
+ * be "constructed" via proc tunables.
+ */
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+# include <lustre_dlm.h>
+
+#include <cl_object.h>
+
+#include <obd_class.h>
+#include <obd_support.h>
+#include "ldlm_internal.h"
+
+
+/*
+ * 50 ldlm locks for 1MB of RAM.
+ */
+#define LDLM_POOL_HOST_L ((NUM_CACHEPAGES >> (20 - PAGE_CACHE_SHIFT)) * 50)
+
+/*
+ * Maximal possible grant step plan in %.
+ */
+#define L